From: Florian Fainelli Date: Fri, 24 Apr 2009 14:35:19 +0000 (+0000) Subject: remove 2.6.24, no target is relying on it X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=c2bf14deb99602780a71f9290d0936d143fb1a38;p=openwrt%2Fstaging%2Fansuel.git remove 2.6.24, no target is relying on it SVN-Revision: 15388 --- diff --git a/include/kernel-version.mk b/include/kernel-version.mk index 07c318d942..0f9621ed8a 100644 --- a/include/kernel-version.mk +++ b/include/kernel-version.mk @@ -19,9 +19,6 @@ endif ifeq ($(LINUX_VERSION),2.6.23.17) LINUX_KERNEL_MD5SUM:=a0300a393ac91ce9c64bf31522b45e2e endif -ifeq ($(LINUX_VERSION),2.6.24.7) - LINUX_KERNEL_MD5SUM:=40a73780d51525d28d36dec852c680c4 -endif ifeq ($(LINUX_VERSION),2.6.25.20) LINUX_KERNEL_MD5SUM:=0da698edccf03e2235abc2830a495114 endif diff --git a/target/linux/generic-2.6/config-2.6.24 b/target/linux/generic-2.6/config-2.6.24 deleted file mode 100644 index 13d07a52c1..0000000000 --- a/target/linux/generic-2.6/config-2.6.24 +++ /dev/null @@ -1,1817 +0,0 @@ -# CONFIG_6PACK is not set -# CONFIG_8139CP is not set -# CONFIG_9P_FS is not set -# CONFIG_ACENIC is not set -# CONFIG_ACORN_PARTITION is not set -# CONFIG_ADAPTEC_STARFIRE is not set -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_AFS_FS is not set -# CONFIG_AF_RXRPC is not set -# CONFIG_AIRO is not set -# CONFIG_AIRO_CS is not set -# CONFIG_AMD8111_ETH is not set -# CONFIG_AMIGA_PARTITION is not set -CONFIG_ANON_INODES=y -# CONFIG_APPLICOM is not set -CONFIG_ARCH_FLATMEM_ENABLE=y -# CONFIG_ARCNET is not set -CONFIG_ARPD=y -CONFIG_ASK_IP_FIB_HASH=y -# CONFIG_ATA is not set -# CONFIG_ATALK is not set -# CONFIG_ATARI_PARTITION is not set -# CONFIG_ATA_GENERIC is not set -# CONFIG_ATA_OVER_ETH is not set -# CONFIG_ATL1 is not set -# CONFIG_ATM is not set -# CONFIG_ATMEL is not set -# CONFIG_ATM_AMBASSADOR is not set -# CONFIG_ATM_BR2684 is not set -CONFIG_ATM_BR2684_IPFILTER=y -# CONFIG_ATM_CLIP is not set -CONFIG_ATM_CLIP_NO_ICMP=y -# CONFIG_ATM_DRIVERS is not set -# CONFIG_ATM_DUMMY is not set -# CONFIG_ATM_ENI is not set -# CONFIG_ATM_FIRESTREAM is not set -# CONFIG_ATM_FORE200E_MAYBE is not set -# CONFIG_ATM_HE is not set -# CONFIG_ATM_HORIZON is not set -# CONFIG_ATM_IA is not set -# CONFIG_ATM_IDT77252 is not set -# CONFIG_ATM_LANAI is not set -# CONFIG_ATM_LANE is not set -# CONFIG_ATM_MPOA is not set -# CONFIG_ATM_NICSTAR is not set -# CONFIG_ATM_TCP is not set -# CONFIG_ATM_ZATM is not set -# CONFIG_AUDIT is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_AUTOFS_FS is not set -# CONFIG_AX25 is not set -# CONFIG_AX25_DAMA_SLAVE is not set -# CONFIG_AX88796 is not set -# CONFIG_B44 is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set -CONFIG_BASE_FULL=y -# CONFIG_BASLER_EXCITE is not set -# CONFIG_BAYCOM_EPP is not set -# CONFIG_BAYCOM_PAR is not set -# CONFIG_BAYCOM_SER_FDX is not set -# CONFIG_BAYCOM_SER_HDX is not set -# CONFIG_BCM43XX is not set -CONFIG_BCM43XX_DEBUG=y -CONFIG_BCM43XX_DMA=y -CONFIG_BCM43XX_DMA_AND_PIO_MODE=y -# CONFIG_BCM43XX_DMA_MODE is not set -CONFIG_BCM43XX_PIO=y -# CONFIG_BCM43XX_PIO_MODE is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_MISC is not set -# CONFIG_BLINK is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_BLK_CPQ_DA is not set -CONFIG_BLK_DEV=y -# CONFIG_BLK_DEV_3W_XXXX_RAID 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_BSG is not set -# CONFIG_BLK_DEV_CMD640 is not set -# CONFIG_BLK_DEV_CMD64X is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -# CONFIG_BLK_DEV_CRYPTOLOOP 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_CY82C693 is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_DELKIN is not set -# CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_DEV_GENERIC is not set -# CONFIG_BLK_DEV_HD is not set -# CONFIG_BLK_DEV_HD_IDE is not set -# CONFIG_BLK_DEV_HPT34X is not set -# CONFIG_BLK_DEV_HPT366 is not set -# CONFIG_BLK_DEV_IDECD is not set -# CONFIG_BLK_DEV_IDECS is not set -# CONFIG_BLK_DEV_IDEDMA_FORCED is not set -# CONFIG_BLK_DEV_IDEFLOPPY is not set -# CONFIG_BLK_DEV_IDEPCI is not set -# CONFIG_BLK_DEV_IDEPNP is not set -# CONFIG_BLK_DEV_IDESCSI is not set -# CONFIG_BLK_DEV_IDETAPE is not set -# CONFIG_BLK_DEV_IDE_SATA is not set -# CONFIG_BLK_DEV_IDE_SWARM is not set -CONFIG_BLK_DEV_INITRD=y -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_BLK_DEV_IT8213 is not set -# CONFIG_BLK_DEV_IT821X is not set -# CONFIG_BLK_DEV_JMICRON is not set -# CONFIG_BLK_DEV_LOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_NS87415 is not set -# CONFIG_BLK_DEV_OFFBOARD is not set -# CONFIG_BLK_DEV_OPTI621 is not set -# CONFIG_BLK_DEV_PDC202XX_NEW is not set -# CONFIG_BLK_DEV_PDC202XX_OLD is not set -# CONFIG_BLK_DEV_PLATFORM is not set -# CONFIG_BLK_DEV_PIIX is not set -# CONFIG_BLK_DEV_RAM is not set -# CONFIG_BLK_DEV_RZ1000 is not set -# CONFIG_BLK_DEV_SC1200 is not set -# CONFIG_BLK_DEV_SD is not set -# CONFIG_BLK_DEV_SIIMAGE is not set -# CONFIG_BLK_DEV_SIS5513 is not set -# CONFIG_BLK_DEV_SL82C105 is not set -# CONFIG_BLK_DEV_SLC90E66 is not set -# CONFIG_BLK_DEV_SR is not set -# CONFIG_BLK_DEV_SVWKS is not set -# CONFIG_BLK_DEV_SX8 is not set -# CONFIG_BLK_DEV_TC86C001 is not set -# CONFIG_BLK_DEV_TRIFLEX is not set -# CONFIG_BLK_DEV_TRM290 is not set -# CONFIG_BLK_DEV_UB is not set -# CONFIG_BLK_DEV_UMEM is not set -# CONFIG_BLK_DEV_VIA82CXXX is not set -CONFIG_BLOCK=y -# CONFIG_BNX2 is not set -# CONFIG_BONDING is not set -# CONFIG_BPQETHER is not set -CONFIG_BRIDGE=y -# CONFIG_BRIDGE_EBT_802_3 is not set -# CONFIG_BRIDGE_EBT_AMONG is not set -# CONFIG_BRIDGE_EBT_ARP is not set -# CONFIG_BRIDGE_EBT_ARPREPLY is not set -# CONFIG_BRIDGE_EBT_BROUTE is not set -# CONFIG_BRIDGE_EBT_DNAT is not set -# CONFIG_BRIDGE_EBT_IP is not set -# CONFIG_BRIDGE_EBT_LIMIT is not set -# CONFIG_BRIDGE_EBT_LOG is not set -# CONFIG_BRIDGE_EBT_MARK is not set -# CONFIG_BRIDGE_EBT_MARK_T is not set -# CONFIG_BRIDGE_EBT_NFLOG is not set -# CONFIG_BRIDGE_EBT_PKTTYPE is not set -# CONFIG_BRIDGE_EBT_REDIRECT is not set -# CONFIG_BRIDGE_EBT_SNAT is not set -# CONFIG_BRIDGE_EBT_STP is not set -# CONFIG_BRIDGE_EBT_T_FILTER is not set -# CONFIG_BRIDGE_EBT_T_NAT is not set -# CONFIG_BRIDGE_EBT_ULOG is not set -# CONFIG_BRIDGE_EBT_VLAN is not set -# CONFIG_BRIDGE_NETFILTER is not set -# CONFIG_BRIDGE_NF_EBTABLES is not set -CONFIG_BROKEN_ON_SMP=y -CONFIG_BSD_DISKLABEL=y -CONFIG_BSD_PROCESS_ACCT=y -# CONFIG_BSD_PROCESS_ACCT_V3 is not set -# CONFIG_BT is not set -# CONFIG_BT_BNEP is not set -CONFIG_BT_BNEP_MC_FILTER=y -CONFIG_BT_BNEP_PROTO_FILTER=y -# CONFIG_BT_CMTP is not set -# CONFIG_BT_HCIBCM203X is not set -# CONFIG_BT_HCIBFUSB is not set -# CONFIG_BT_HCIBLUECARD is not set -# CONFIG_BT_HCIBPA10X is not set -# CONFIG_BT_HCIBT3C is not set -# CONFIG_BT_HCIBTSDIO is not set -# CONFIG_BT_HCIBTUART is not set -# CONFIG_BT_HCIDTL1 is not set -# CONFIG_BT_HCIUART is not set -CONFIG_BT_HCIUART_BCSP=y -CONFIG_BT_HCIUART_H4=y -# CONFIG_BT_HCIUART_LL is not set -# CONFIG_BT_HCIUSB is not set -CONFIG_BT_HCIUSB_SCO=y -# CONFIG_BT_HCIVHCI is not set -# CONFIG_BT_HIDP is not set -# CONFIG_BT_L2CAP is not set -# CONFIG_BT_RFCOMM is not set -CONFIG_BT_RFCOMM_TTY=y -# CONFIG_BT_SCO is not set -CONFIG_BUG=y -# CONFIG_CAPI_AVM is not set -# CONFIG_CAPI_EICON is not set -# CONFIG_CAPI_TRACE is not set -CONFIG_CARDBUS=y -# CONFIG_CARDMAN_4000 is not set -# CONFIG_CARDMAN_4040 is not set -# CONFIG_CASSINI is not set -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_CFG80211 is not set -# CONFIG_CGROUPS is not set -# CONFIG_CHELSIO_T1 is not set -# CONFIG_CHELSIO_T3 is not set -# CONFIG_CHR_DEV_OSST is not set -# CONFIG_CHR_DEV_SCH is not set -# CONFIG_CHR_DEV_SG is not set -# CONFIG_CHR_DEV_ST is not set -# CONFIG_CICADA_PHY is not set -# CONFIG_CIFS is not set -# CONFIG_CIFS_DEBUG2 is not set -# CONFIG_CIFS_EXPERIMENTAL is not set -CONFIG_CIFS_POSIX=y -CONFIG_CIFS_STATS=y -# CONFIG_CIFS_STATS2 is not set -# CONFIG_CIFS_WEAK_PW_HASH is not set -# CONFIG_CIFS_XATTR is not set -CONFIG_CLS_U32_MARK=y -CONFIG_CLS_U32_PERF=y -CONFIG_CMDLINE="" -# CONFIG_CODA_FS is not set -CONFIG_CONFIGFS_FS=y -# CONFIG_CONNECTOR is not set -# CONFIG_CRAMFS is not set -# CONFIG_CRC16 is not set -CONFIG_CRC32=y -# CONFIG_CRC7 is not set -# CONFIG_CRC_CCITT is not set -# CONFIG_CRC_ITU_T is not set -CONFIG_CROSSCOMPILE=y -CONFIG_CRYPTO=y -# CONFIG_CRYPTO_AEAD is not set -# CONFIG_CRYPTO_AES is not set -# CONFIG_CRYPTO_ALGAPI is not set -# CONFIG_CRYPTO_ANUBIS is not set -# CONFIG_CRYPTO_ARC4 is not set -# CONFIG_CRYPTO_AUTHENC is not set -# CONFIG_CRYPTO_BLKCIPHER is not set -# CONFIG_CRYPTO_BLOWFISH is not set -# CONFIG_CRYPTO_CAMELLIA is not set -# CONFIG_CRYPTO_CAST5 is not set -# CONFIG_CRYPTO_CAST6 is not set -# CONFIG_CRYPTO_CBC is not set -# CONFIG_CRYPTO_CRC32C is not set -# CONFIG_CRYPTO_CRYPTD is not set -# CONFIG_CRYPTO_DEFLATE is not set -# CONFIG_CRYPTO_DES is not set -# CONFIG_CRYPTO_ECB is not set -# CONFIG_CRYPTO_FCRYPT is not set -# CONFIG_CRYPTO_GF128MUL is not set -# CONFIG_CRYPTO_HASH is not set -# CONFIG_CRYPTO_HMAC is not set -# CONFIG_CRYPTO_HW is not set -# CONFIG_CRYPTO_KHAZAD is not set -# CONFIG_CRYPTO_LRW is not set -# CONFIG_CRYPTO_MANAGER is not set -# CONFIG_CRYPTO_MD4 is not set -# CONFIG_CRYPTO_MD5 is not set -# CONFIG_CRYPTO_MICHAEL_MIC is not set -# CONFIG_CRYPTO_NULL is not set -# CONFIG_CRYPTO_PCBC is not set -# CONFIG_CRYPTO_SEED is not set -# CONFIG_CRYPTO_SERPENT is not set -# CONFIG_CRYPTO_SHA1 is not set -# CONFIG_CRYPTO_SHA256 is not set -# CONFIG_CRYPTO_SHA512 is not set -# CONFIG_CRYPTO_TEA is not set -# CONFIG_CRYPTO_TEST is not set -# CONFIG_CRYPTO_TGR192 is not set -# CONFIG_CRYPTO_TWOFISH is not set -# CONFIG_CRYPTO_TWOFISH_COMMON is not set -# CONFIG_CRYPTO_WP512 is not set -# CONFIG_CRYPTO_XCBC is not set -# CONFIG_CRYPTO_XTS is not set -# CONFIG_DAB is not set -# CONFIG_DAVICOM_PHY is not set -# CONFIG_DEBUG_FS is not set -# CONFIG_DEBUG_KERNEL is not set -# CONFIG_DECNET is not set -# CONFIG_DEFAULT_AS is not set -# CONFIG_DEFAULT_BIC is not set -# CONFIG_DEFAULT_CFQ is not set -# CONFIG_DEFAULT_CUBIC is not set -CONFIG_DEFAULT_DEADLINE=y -# CONFIG_DEFAULT_HTCP is not set -CONFIG_DEFAULT_IOSCHED="deadline" -# CONFIG_DEFAULT_NOOP is not set -# CONFIG_DEFAULT_RENO is not set -CONFIG_DEFAULT_TCP_CONG="vegas" -CONFIG_DEFAULT_VEGAS=y -# CONFIG_DEFAULT_WESTWOOD is not set -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" -# CONFIG_DEVFS_DEBUG is not set -CONFIG_DEVFS_FS=y -CONFIG_DEVFS_MOUNT=y -# CONFIG_DGRS is not set -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_DISPLAY_SUPPORT is not set -# CONFIG_DL2K is not set -# CONFIG_DLM is not set -# CONFIG_DMA_ENGINE is not set -# CONFIG_DNOTIFY is not set -# CONFIG_DRM is not set -# CONFIG_DS1682 is not set -# CONFIG_DTLK is not set -# CONFIG_DUMMY is not set -# CONFIG_DVB is not set -# CONFIG_DVB_CORE is not set -# CONFIG_E100 is not set -# CONFIG_E1000 is not set -# CONFIG_ECONET is not set -# CONFIG_EEPRO100 is not set -# CONFIG_EEPROM_93CX6 is not set -# CONFIG_EFI_PARTITION is not set -# CONFIG_EFS_FS is not set -# CONFIG_ELF_CORE is not set -CONFIG_EMBEDDED=y -# CONFIG_ENABLE_MUST_CHECK is not set -CONFIG_ENABLE_WARN_DEPRECATED=y -# CONFIG_EPIC100 is not set -CONFIG_EPOLL=y -# CONFIG_EQUALIZER is not set -CONFIG_EVENTFD=y -CONFIG_EXPERIMENTAL=y -# CONFIG_EXPORTFS is not set -# CONFIG_EXT2_FS is not set -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XIP is not set -# CONFIG_EXT3_FS is not set -# CONFIG_EXT3_FS_XATTR is not set -# CONFIG_EXT4DEV_FS is not set -# CONFIG_FAIR_GROUP_SCHED is not set -CONFIG_FAT_DEFAULT_CODEPAGE=437 -CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -# CONFIG_FAT_FS is not set -# CONFIG_FB is not set -# CONFIG_FB_IBM_GXT4500 is not set -# CONFIG_FDDI is not set -# CONFIG_FEALNX is not set -CONFIG_FIB_RULES=y -# CONFIG_FIREWIRE is not set -CONFIG_FLATMEM=y -CONFIG_FLATMEM_MANUAL=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_FORCEDETH is not set -# CONFIG_FS_POSIX_ACL is not set -# CONFIG_FTL is not set -# CONFIG_FUSE_FS is not set -# CONFIG_FUSION is not set -# CONFIG_FUSION_FC is not set -# CONFIG_FUSION_SAS is not set -# CONFIG_FUSION_SPI is not set -CONFIG_FUTEX=y -CONFIG_FW_LOADER=y -CONFIG_GACT_PROB=y -# CONFIG_GAMEPORT is not set -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_GENERIC_TIME=y -# CONFIG_GFS2_FS is not set -# CONFIG_GPIO_DEVICE is not set -# CONFIG_HAMACHI is not set -CONFIG_HAMRADIO=y -# CONFIG_HAPPYMEAL is not set -# CONFIG_HEADERS_CHECK is not set -# CONFIG_HERMES is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HID is not set -# CONFIG_HID_DEBUG is not set -# CONFIG_HID_FF is not set -# CONFIG_HID_SUPPORT is not set -# CONFIG_HIDRAW is not set -CONFIG_HIGH_RES_TIMERS=y -# CONFIG_HIPPI is not set -# CONFIG_HOSTAP is not set -# CONFIG_HOSTAP_CS is not set -CONFIG_HOSTAP_FIRMWARE=y -CONFIG_HOSTAP_FIRMWARE_NVRAM=y -# CONFIG_HOSTAP_PCI is not set -# CONFIG_HOSTAP_PLX is not set -CONFIG_HOTPLUG=y -# CONFIG_HOTPLUG_CPU is not set -# CONFIG_HOTPLUG_PCI is not set -# CONFIG_HP100 is not set -# CONFIG_HPFS_FS is not set -# CONFIG_HUGETLB_PAGE is not set -# CONFIG_HWMON is not set -# CONFIG_HWMON_VID is not set -CONFIG_HZ=100 -CONFIG_HZ_100=y -# CONFIG_HZ_1000 is not set -# CONFIG_HZ_1024 is not set -# CONFIG_HZ_128 is not set -# CONFIG_HZ_250 is not set -# CONFIG_HZ_256 is not set -# CONFIG_HZ_300 is not set -# CONFIG_HZ_48 is not set -# CONFIG_I2C_ALGOPCA is not set -# CONFIG_I2C_ALGOPCF is not set -# 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_CHARDEV is not set -# CONFIG_I2C_DEBUG_ALGO is not set -# CONFIG_I2C_DEBUG_BUS is not set -# CONFIG_I2C_DEBUG_CHIP is not set -# CONFIG_I2C_DEBUG_CORE is not set -# CONFIG_I2C_ELEKTOR is not set -# CONFIG_I2C_GPIO is not set -# CONFIG_I2C_I801 is not set -# CONFIG_I2C_I810 is not set -# CONFIG_I2C_IBM_IIC is not set -# CONFIG_I2C_MPC is not set -# CONFIG_I2C_NFORCE2 is not set -# CONFIG_I2C_OCORES is not set -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_PCA_ISA is not set -# CONFIG_I2C_PIIX4 is not set -# CONFIG_I2C_PROSAVAGE is not set -# CONFIG_I2C_SAVAGE4 is not set -# CONFIG_I2C_SIBYTE is not set -# CONFIG_I2C_SIMTEC 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_TAOS_EVM is not set -# CONFIG_I2C_TINY_USB is not set -# CONFIG_I2C_VIA is not set -# CONFIG_I2C_VIAPRO is not set -# CONFIG_I2C_VOODOO3 is not set -# CONFIG_I2O is not set -# CONFIG_I82092 is not set -# CONFIG_ICPLUS_PHY is not set -# CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_IDEDMA_IVB is not set -# CONFIG_IDEDMA_ONLYDISK is not set -# CONFIG_IDEPCI_SHARE_IRQ is not set -CONFIG_IDE_MAX_HWIFS=4 -CONFIG_IDE_PROC_FS=y -# CONFIG_IDE_TASK_IOCTL is not set -# CONFIG_IEEE1394 is not set -# CONFIG_IEEE1394_DV1394 is not set -# CONFIG_IEEE1394_ETH1394 is not set -# CONFIG_IEEE1394_OHCI1394 is not set -# CONFIG_IEEE1394_PCILYNX is not set -# CONFIG_IEEE1394_RAWIO is not set -# CONFIG_IEEE1394_VERBOSEDEBUG is not set -# CONFIG_IEEE1394_VIDEO1394 is not set -# CONFIG_IEEE80211 is not set -# CONFIG_IEEE80211_CRYPT_CCMP is not set -# CONFIG_IEEE80211_CRYPT_TKIP is not set -# CONFIG_IEEE80211_CRYPT_WEP is not set -# CONFIG_IEEE80211_DEBUG is not set -# CONFIG_IEEE80211_SOFTMAC is not set -# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set -# CONFIG_IFB is not set -# CONFIG_IKCONFIG is not set -# CONFIG_IKCONFIG_PROC is not set -# CONFIG_IMQ is not set -# CONFIG_IMQ_BEHAVIOR_AA is not set -# CONFIG_IMQ_BEHAVIOR_AB is not set -CONFIG_IMQ_BEHAVIOR_BA=y -# CONFIG_IMQ_BEHAVIOR_BB is not set -CONFIG_IMQ_NUM_DEVS=2 -CONFIG_INET=y -# 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_INET6_XFRM_MODE_BEET is not set -# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set -# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET6_XFRM_MODE_TUNNEL is not set -# CONFIG_INET6_XFRM_TUNNEL is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_DIAG is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_LRO is not set -# CONFIG_INET_TCP_DIAG is not set -# CONFIG_INET_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET_XFRM_MODE_TUNNEL is not set -# CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INFINIBAND is not set -# CONFIG_INFTL is not set -CONFIG_INIT_ENV_ARG_LIMIT=32 -# CONFIG_INOTIFY is not set -# CONFIG_INOTIFY_USER is not set -# CONFIG_INPUT is not set -# CONFIG_INPUT_ATI_REMOTE is not set -# CONFIG_INPUT_ATI_REMOTE2 is not set -# CONFIG_INPUT_EVBUG is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_FF_MEMLESS is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_KEYSPAN_REMOTE is not set -# CONFIG_INPUT_MISC is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_PCSPKR is not set -# CONFIG_INPUT_POLLDEV is not set -# CONFIG_INPUT_POWERMATE is not set -# CONFIG_INPUT_TABLET is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_TSDEV is not set -# CONFIG_INPUT_UINPUT is not set -# CONFIG_INPUT_WISTRON_BTNS is not set -# CONFIG_INSTRUMENTATION is not set -# CONFIG_IOSCHED_AS is not set -# CONFIG_IOSCHED_CFQ is not set -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_NOOP=y -# CONFIG_IP6_NF_FILTER is not set -# CONFIG_IP6_NF_IPTABLES is not set -# CONFIG_IP6_NF_MANGLE is not set -# CONFIG_IP6_NF_MATCH_AH is not set -# CONFIG_IP6_NF_MATCH_EUI64 is not set -# CONFIG_IP6_NF_MATCH_FRAG is not set -# CONFIG_IP6_NF_MATCH_HL is not set -# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set -# CONFIG_IP6_NF_MATCH_LIMIT is not set -# CONFIG_IP6_NF_MATCH_MH is not set -# CONFIG_IP6_NF_MATCH_OPTS is not set -# CONFIG_IP6_NF_MATCH_OWNER is not set -# CONFIG_IP6_NF_MATCH_RT is not set -# CONFIG_IP6_NF_QUEUE is not set -# CONFIG_IP6_NF_RAW is not set -# CONFIG_IP6_NF_TARGET_HL is not set -# CONFIG_IP6_NF_TARGET_IMQ is not set -# CONFIG_IP6_NF_TARGET_LOG is not set -# CONFIG_IP6_NF_TARGET_REJECT is not set -# CONFIG_IP6_NF_TARGET_ROUTE is not set -# CONFIG_IPC_NS is not set -# CONFIG_IPMI_HANDLER is not set -CONFIG_IPSEC_NAT_TRAVERSAL=y -# CONFIG_IPV6 is not set -# CONFIG_IPV6_MIP6 is not set -# CONFIG_IPV6_MROUTE is not set -# CONFIG_IPV6_MULTIPLE_TABLES is not set -# CONFIG_IPV6_OPTIMISTIC_DAD is not set -# CONFIG_IPV6_PRIVACY is not set -CONFIG_IPV6_ROUTER_PREF=y -# CONFIG_IPV6_ROUTE_INFO is not set -# CONFIG_IPV6_SIT is not set -# CONFIG_IPV6_TUNNEL is not set -# CONFIG_IPW2100 is not set -# CONFIG_IPW2100_DEBUG is not set -CONFIG_IPW2100_MONITOR=y -# CONFIG_IPW2200 is not set -# CONFIG_IPW2200_DEBUG is not set -CONFIG_IPW2200_MONITOR=y -# CONFIG_IPW2200_PROMISCUOUS is not set -# CONFIG_IPW2200_QOS is not set -# CONFIG_IPW2200_RADIOTAP is not set -# CONFIG_IPX is not set -CONFIG_IP_ADVANCED_ROUTER=y -# CONFIG_IP_DCCP is not set -CONFIG_IP_FIB_HASH=y -# CONFIG_IP_FIB_TRIE is not set -# CONFIG_IP_MROUTE is not set -CONFIG_IP_MULTICAST=y -CONFIG_IP_MULTIPLE_TABLES=y -# CONFIG_IP_NF_AMANDA is not set -# CONFIG_IP_NF_ARPFILTER is not set -# CONFIG_IP_NF_ARPTABLES is not set -# CONFIG_IP_NF_ARP_MANGLE is not set -CONFIG_IP_NF_CONNTRACK=y -# CONFIG_IP_NF_CONNTRACK_EVENTS is not set -CONFIG_IP_NF_CONNTRACK_MARK=y -CONFIG_IP_NF_CT_ACCT=y -# CONFIG_IP_NF_CT_PROTO_SCTP is not set -# CONFIG_IP_NF_FILTER is not set -# CONFIG_IP_NF_FTP is not set -# CONFIG_IP_NF_H323 is not set -# CONFIG_IP_NF_IPTABLES is not set -# CONFIG_IP_NF_IRC is not set -# CONFIG_IP_NF_MANGLE is not set -# CONFIG_IP_NF_MATCH_ADDRTYPE is not set -# CONFIG_IP_NF_MATCH_AH is not set -# CONFIG_IP_NF_MATCH_ECN is not set -# CONFIG_IP_NF_MATCH_HASHLIMIT is not set -# CONFIG_IP_NF_MATCH_IPP2P is not set -# CONFIG_IP_NF_MATCH_IPRANGE is not set -# CONFIG_NETFILTER_XT_MATCH_LAYER7 is not set -# CONFIG_NETFILTER_XT_MATCH_LAYER7_DEBUG is not set -# CONFIG_NETFILTER_XT_MATCH_TIME is not set -# CONFIG_IP_NF_MATCH_OWNER is not set -# CONFIG_IP_NF_MATCH_RECENT is not set -# CONFIG_IP_NF_MATCH_SET is not set -# CONFIG_IP_NF_MATCH_TIME is not set -# CONFIG_IP_NF_MATCH_TOS is not set -# CONFIG_IP_NF_MATCH_TTL is not set -CONFIG_IP_NF_NAT=y -# CONFIG_IP_NF_NAT_AMANDA is not set -# CONFIG_IP_NF_NAT_FTP is not set -# CONFIG_IP_NF_NAT_H323 is not set -# CONFIG_IP_NF_NAT_IRC is not set -CONFIG_IP_NF_NAT_NEEDED=y -# CONFIG_IP_NF_NAT_PPTP is not set -# CONFIG_IP_NF_NAT_SIP is not set -# CONFIG_IP_NF_NAT_SNMP_BASIC is not set -# CONFIG_IP_NF_NAT_TFTP is not set -# CONFIG_IP_NF_NETBIOS_NS is not set -# CONFIG_IP_NF_PPTP is not set -# CONFIG_IP_NF_QUEUE is not set -# CONFIG_IP_NF_RAW is not set -# CONFIG_IP_NF_SET is not set -CONFIG_IP_NF_SET_HASHSIZE=1024 -# CONFIG_IP_NF_SET_IPHASH is not set -# CONFIG_IP_NF_SET_IPMAP is not set -# CONFIG_IP_NF_SET_IPPORTHASH is not set -# CONFIG_IP_NF_SET_IPTREE is not set -# CONFIG_IP_NF_SET_IPTREEMAP is not set -# CONFIG_IP_NF_SET_MACIPMAP is not set -CONFIG_IP_NF_SET_MAX=256 -# CONFIG_IP_NF_SET_NETHASH is not set -# CONFIG_IP_NF_SET_PORTMAP is not set -# CONFIG_IP_NF_SIP is not set -# CONFIG_IP_NF_TARGET_CLUSTERIP is not set -# CONFIG_IP_NF_TARGET_ECN is not set -# CONFIG_IP_NF_TARGET_IMQ is not set -# CONFIG_IP_NF_TARGET_LOG is not set -# CONFIG_IP_NF_TARGET_MASQUERADE is not set -# CONFIG_IP_NF_TARGET_NETMAP is not set -# CONFIG_IP_NF_TARGET_REDIRECT is not set -# CONFIG_IP_NF_TARGET_REJECT is not set -# CONFIG_IP_NF_TARGET_ROUTE is not set -# CONFIG_IP_NF_TARGET_SAME is not set -# CONFIG_IP_NF_TARGET_SET is not set -# CONFIG_IP_NF_TARGET_TOS is not set -# CONFIG_IP_NF_TARGET_TTL is not set -# CONFIG_IP_NF_TARGET_ULOG is not set -# CONFIG_IP_NF_TFTP is not set -# CONFIG_IP_PNP is not set -CONFIG_IP_ROUTE_FWMARK=y -CONFIG_IP_ROUTE_MULTIPATH=y -CONFIG_IP_ROUTE_MULTIPATH_CACHED=y -# CONFIG_IP_ROUTE_MULTIPATH_DRR is not set -# CONFIG_IP_ROUTE_MULTIPATH_RANDOM is not set -# CONFIG_IP_ROUTE_MULTIPATH_RR is not set -# CONFIG_IP_ROUTE_MULTIPATH_WRANDOM is not set -CONFIG_IP_ROUTE_VERBOSE=y -# CONFIG_IP_SCTP is not set -# CONFIG_IP_VS is not set -# CONFIG_IRDA is not set -# CONFIG_ISCSI_TCP is not set -# CONFIG_ISDN is not set -# CONFIG_ISDN_CAPI is not set -# CONFIG_ISDN_CAPI_CAPI20 is not set -# CONFIG_ISDN_CAPI_CAPIFS is not set -CONFIG_ISDN_CAPI_CAPIFS_BOOL=y -CONFIG_ISDN_CAPI_MIDDLEWARE=y -# CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON is not set -# CONFIG_ISDN_I4L is not set -# CONFIG_ISO9660_FS is not set -# CONFIG_IXGB is not set -# CONFIG_JBD is not set -# CONFIG_JBD_DEBUG is not set -# CONFIG_JFFS2_CMODE_NONE is not set -# CONFIG_JFFS2_CMODE_FAVOURLZO is not set -CONFIG_JFFS2_CMODE_PRIORITY=y -# CONFIG_JFFS2_CMODE_SIZE is not set -CONFIG_JFFS2_COMPRESSION_OPTIONS=y -CONFIG_JFFS2_FS=y -CONFIG_JFFS2_FS_DEBUG=0 -# CONFIG_JFFS2_FS_WBUF_VERIFY is not set -CONFIG_JFFS2_FS_WRITEBUFFER=y -# CONFIG_JFFS2_FS_XATTR is not set -# CONFIG_JFFS2_LZO is not set -CONFIG_JFFS2_RTIME=y -# CONFIG_JFFS2_RUBIN is not set -CONFIG_JFFS2_SUMMARY=y -CONFIG_JFFS2_ZLIB=y -# CONFIG_JFFS_FS is not set -# CONFIG_JFS_DEBUG is not set -# CONFIG_JFS_FS is not set -# CONFIG_JFS_POSIX_ACL is not set -# CONFIG_JFS_SECURITY is not set -# CONFIG_JFS_STATISTICS is not set -CONFIG_JOLIET=y -# CONFIG_KALLSYMS is not set -# CONFIG_KALLSYMS_EXTRA_PASS is not set -# CONFIG_KARMA_PARTITION is not set -# CONFIG_KEXEC is not set -# CONFIG_KEYS is not set -# CONFIG_KMOD is not set -# CONFIG_LAPB is not set -# CONFIG_LASAT is not set -# CONFIG_LBD is not set -# CONFIG_LDM_PARTITION is not set -# CONFIG_LEDS_ALIX is not set -CONFIG_LEDS_CLASS=y -# CONFIG_LEDS_GPIO is not set -CONFIG_LEDS_TRIGGERS=y -CONFIG_LEDS_TRIGGER_DEFAULT_ON=y -CONFIG_LEDS_TRIGGER_HEARTBEAT=y -# CONFIG_LEDS_TRIGGER_IDE_DISK is not set -# CONFIG_LEDS_TRIGGER_MORSE is not set -CONFIG_LEDS_TRIGGER_TIMER=y -# CONFIG_LEGACY_PTYS is not set -# CONFIG_LIBCRC32C is not set -# CONFIG_LIBERTAS is not set -# CONFIG_LIBERTAS_USB is not set -CONFIG_LLC=y -# CONFIG_LLC2 is not set -CONFIG_LOCALVERSION="" -# CONFIG_LOCALVERSION_AUTO is not set -# CONFIG_LOCKD is not set -CONFIG_LOCKDEP_SUPPORT=y -CONFIG_LOCKD_V4=y -CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_LSF is not set -# CONFIG_LXT_PHY is not set -# CONFIG_MAC80211 is not set -# CONFIG_MAC80211_DEBUG is not set -# CONFIG_MAC80211_LEDS is not set -# CONFIG_MACVLAN is not set -# CONFIG_MAC_EMUMOUSEBTN is not set -CONFIG_MAC_PARTITION=y -# CONFIG_MAGIC_SYSRQ is not set -# CONFIG_MARKEINS is not set -# CONFIG_MARVELL_PHY is not set -# CONFIG_MD is not set -# CONFIG_MEGARAID_LEGACY is not set -# CONFIG_MEGARAID_NEWGEN is not set -# CONFIG_MEGARAID_SAS is not set -# CONFIG_MFD_SM501 is not set -CONFIG_MII=y -# CONFIG_MINIX_FS is not set -# CONFIG_MINIX_SUBPARTITION is not set -CONFIG_MINI_FO=y -CONFIG_MISC_DEVICES=y -# CONFIG_MKISS is not set -# CONFIG_MMC is not set -# CONFIG_MMC_ARMMMCI is not set -CONFIG_MMU=y -CONFIG_MODULES=y -# CONFIG_MODULE_FORCE_UNLOAD is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_MODULE_UNLOAD=y -# CONFIG_MODVERSIONS is not set -# CONFIG_MOUSE_APPLETOUCH is not set -# CONFIG_MOUSE_INPORT is not set -# CONFIG_MOUSE_LOGIBM is not set -# CONFIG_MOUSE_PC110PAD is not set -# CONFIG_MSDOS_FS is not set -CONFIG_MSDOS_PARTITION=y -# CONFIG_MTD_DATAFLASH is not set -# CONFIG_MTD_M25P80 is not set -# CONFIG_MTD_INTEL_VR_NOR is not set -# CONFIG_MTD_NAND is not set -# CONFIG_MTD_OOPS is not set -# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set -CONFIG_MTD_ROOTFS_ROOT_DEV=y -CONFIG_MTD_ROOTFS_SPLIT=y -# CONFIG_MTD_UBI is not set -# CONFIG_MWAVE is not set -# CONFIG_MYRI10GE is not set -# CONFIG_NCP_FS is not set -CONFIG_NET=y -# CONFIG_NET_ACT_NAT is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETDEBUG is not set -CONFIG_NETDEVICES=y -# CONFIG_NETDEVICES_MULTIQUEUE is not set -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_DEBUG is not set -# CONFIG_NETFILTER_NETLINK is not set -# CONFIG_NETFILTER_XTABLES is not set -# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set -# CONFIG_NETFILTER_XT_MATCH_CONNBYTES is not set -# CONFIG_NETFILTER_XT_MATCH_CONNLIMIT is not set -# CONFIG_NETFILTER_XT_MATCH_CONNMARK is not set -# CONFIG_NETFILTER_XT_MATCH_CONNTRACK is not set -# CONFIG_NETFILTER_XT_MATCH_DCCP is not set -# CONFIG_NETFILTER_XT_MATCH_DSCP is not set -# CONFIG_NETFILTER_XT_MATCH_ESP is not set -# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set -# CONFIG_NETFILTER_XT_MATCH_HELPER is not set -# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set -# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set -# CONFIG_NETFILTER_XT_MATCH_MAC is not set -# CONFIG_NETFILTER_XT_MATCH_MARK is not set -# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set -# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set -# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set -# CONFIG_NETFILTER_XT_MATCH_POLICY is not set -# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set -# CONFIG_NETFILTER_XT_MATCH_REALM is not set -# CONFIG_NETFILTER_XT_MATCH_SCTP is not set -# CONFIG_NETFILTER_XT_MATCH_STATE is not set -# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set -# CONFIG_NETFILTER_XT_MATCH_STRING is not set -# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set -# CONFIG_NETFILTER_XT_MATCH_U32 is not set -# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set -# CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set -# CONFIG_NETFILTER_XT_TARGET_DSCP is not set -# CONFIG_NETFILTER_XT_TARGET_MARK is not set -# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set -# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set -# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set -# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set -# CONFIG_NETFILTER_XT_TARGET_TRACE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NETROM is not set -CONFIG_NETWORK_FILESYSTEMS=y -# CONFIG_NETWORK_SECMARK is not set -# CONFIG_NETXEN_NIC is not set -# CONFIG_NET_9P is not set -# CONFIG_NET_ACT_GACT is not set -# CONFIG_NET_ACT_IPT is not set -# CONFIG_NET_ACT_MIRRED is not set -# CONFIG_NET_ACT_PEDIT is not set -CONFIG_NET_ACT_POLICE=y -# CONFIG_NET_ACT_SIMP is not set -CONFIG_NET_CLS=y -CONFIG_NET_CLS_ACT=y -# CONFIG_NET_CLS_BASIC is not set -# CONFIG_NET_CLS_FW is not set -CONFIG_NET_CLS_IND=y -CONFIG_NET_CLS_POLICE=y -CONFIG_NET_CLS_ROUTE=y -# CONFIG_NET_CLS_ROUTE4 is not set -# CONFIG_NET_CLS_RSVP is not set -# CONFIG_NET_CLS_RSVP6 is not set -# CONFIG_NET_CLS_TCINDEX is not set -# CONFIG_NET_CLS_U32 is not set -CONFIG_NET_EMATCH=y -# CONFIG_NET_EMATCH_CMP is not set -# CONFIG_NET_EMATCH_META is not set -# CONFIG_NET_EMATCH_NBYTE is not set -CONFIG_NET_EMATCH_STACK=32 -# CONFIG_NET_EMATCH_TEXT is not set -# CONFIG_NET_EMATCH_U32 is not set -CONFIG_NET_ESTIMATOR=y -CONFIG_NET_ETHERNET=y -# CONFIG_NET_FC is not set -# CONFIG_NET_IPGRE is not set -CONFIG_NET_IPGRE_BROADCAST=y -# CONFIG_NET_IPIP is not set -# CONFIG_NET_ISA is not set -# CONFIG_NET_KEY is not set -# CONFIG_NET_KEY_MIGRATE is not set -CONFIG_NET_PCI=y -# CONFIG_NET_PCMCIA is not set -# CONFIG_NET_PKTGEN is not set -# CONFIG_NET_POLL_CONTROLLER is not set -CONFIG_NET_RADIO=y -# CONFIG_NET_SB1000 is not set -CONFIG_NET_SCHED=y -# CONFIG_NET_SCH_ATM is not set -# CONFIG_NET_SCH_CBQ is not set -# CONFIG_NET_SCH_CLK_CPU is not set -# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set -CONFIG_NET_SCH_CLK_JIFFIES=y -# CONFIG_NET_SCH_DSMARK is not set -# CONFIG_NET_SCH_ESFQ is not set -CONFIG_NET_SCH_ESFQ_NFCT=y -CONFIG_NET_SCH_FIFO=y -# CONFIG_NET_SCH_GRED is not set -# CONFIG_NET_SCH_HFSC is not set -# CONFIG_NET_SCH_HTB is not set -# CONFIG_NET_SCH_INGRESS is not set -# CONFIG_NET_SCH_NETEM is not set -# CONFIG_NET_SCH_PRIO is not set -# CONFIG_NET_SCH_RED is not set -# CONFIG_NET_SCH_RR is not set -# CONFIG_NET_SCH_SFQ is not set -# CONFIG_NET_SCH_TBF is not set -# CONFIG_NET_SCH_TEQL is not set -# CONFIG_NET_TULIP is not set -CONFIG_NET_WIRELESS=y -CONFIG_NET_WIRELESS_RTNETLINK=y -# CONFIG_NEW_GPIO is not set -CONFIG_NEW_LEDS=y -# CONFIG_NFSD is not set -CONFIG_NFSD_TCP=y -# CONFIG_NFSD_V2_ACL is not set -CONFIG_NFSD_V3=y -# CONFIG_NFSD_V3_ACL is not set -CONFIG_NFSD_V4=y -# CONFIG_NFS_ACL_SUPPORT is not set -CONFIG_NFS_COMMON=y -# CONFIG_NFS_DIRECTIO is not set -# CONFIG_NFS_FS is not set -CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set -CONFIG_NFS_V4=y -# CONFIG_NFTL is not set -# CONFIG_NF_CONNTRACK is not set -# CONFIG_NF_CONNTRACK_AMANDA is not set -CONFIG_NF_CONNTRACK_ENABLED=y -# CONFIG_NF_CONNTRACK_EVENTS is not set -# CONFIG_NF_CONNTRACK_FTP is not set -# CONFIG_NF_CONNTRACK_H323 is not set -# CONFIG_NF_CONNTRACK_IPV4 is not set -# CONFIG_NF_CONNTRACK_IPV6 is not set -# CONFIG_NF_CONNTRACK_IRC is not set -CONFIG_NF_CONNTRACK_MARK=y -# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set -# CONFIG_NF_CONNTRACK_PPTP is not set -CONFIG_NF_CONNTRACK_PROC_COMPAT=y -# CONFIG_NF_CONNTRACK_RTSP is not set -# CONFIG_NF_CONNTRACK_SANE is not set -# CONFIG_NF_CONNTRACK_SIP is not set -CONFIG_NF_CONNTRACK_SUPPORT=y -# CONFIG_NF_CONNTRACK_TFTP is not set -CONFIG_NF_CT_ACCT=y -# CONFIG_NF_CT_PROTO_GRE is not set -# CONFIG_NF_CT_PROTO_SCTP is not set -# CONFIG_NF_CT_PROTO_UDPLITE is not set -# CONFIG_NF_NAT is not set -# CONFIG_NF_NAT_AMANDA is not set -# CONFIG_NF_NAT_FTP is not set -# CONFIG_NF_NAT_H323 is not set -# CONFIG_NF_NAT_IRC is not set -CONFIG_NF_NAT_NEEDED=y -# CONFIG_NF_NAT_PPTP is not set -# CONFIG_NF_NAT_PROTO_GRE is not set -# CONFIG_NF_NAT_RTSP is not set -# CONFIG_NF_NAT_SIP is not set -# CONFIG_NF_NAT_SNMP_BASIC is not set -# CONFIG_NF_NAT_TFTP is not set -# CONFIG_NLS is not set -# CONFIG_NLS_ASCII is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -# CONFIG_NLS_CODEPAGE_437 is not set -# 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_874 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -CONFIG_NLS_DEFAULT="iso8859-1" -# CONFIG_NLS_ISO8859_1 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_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_8 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -# CONFIG_NLS_UTF8 is not set -# CONFIG_NORTEL_HERMES is not set -# CONFIG_NO_HZ is not set -# CONFIG_NS83820 is not set -# CONFIG_NTFS_DEBUG is not set -# CONFIG_NTFS_FS is not set -# CONFIG_NTFS_RW is not set -# CONFIG_OCFS2_FS is not set -# CONFIG_OSF_PARTITION is not set -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -# CONFIG_PARPORT is not set -# CONFIG_PARPORT_PC is not set -CONFIG_PARTITION_ADVANCED=y -# CONFIG_PATA_ALI is not set -# CONFIG_PATA_AMD is not set -# CONFIG_PATA_ARTOP is not set -# CONFIG_PATA_ATIIXP is not set -# CONFIG_PATA_CMD640_PCI is not set -# CONFIG_PATA_CMD64X is not set -# CONFIG_PATA_CS5520 is not set -# CONFIG_PATA_CS5530 is not set -# CONFIG_PATA_CS5535 is not set -# CONFIG_PATA_CYPRESS is not set -# CONFIG_PATA_EFAR is not set -# CONFIG_PATA_HPT366 is not set -# CONFIG_PATA_HPT37X is not set -# CONFIG_PATA_HPT3X2N is not set -# CONFIG_PATA_HPT3X3 is not set -# CONFIG_PATA_ISAPNP is not set -# CONFIG_PATA_IT8213 is not set -# CONFIG_PATA_IT821X is not set -# CONFIG_PATA_JMICRON is not set -# CONFIG_PATA_LEGACY is not set -# CONFIG_PATA_MARVELL is not set -# CONFIG_PATA_MPIIX is not set -# CONFIG_PATA_NETCELL is not set -# CONFIG_PATA_NS87410 is not set -# CONFIG_PATA_NS87415 is not set -# CONFIG_PATA_OF_PLATFORM is not set -# CONFIG_PATA_OLDPIIX is not set -# CONFIG_PATA_OPTI is not set -# CONFIG_PATA_OPTIDMA is not set -# CONFIG_PATA_PCMCIA is not set -# CONFIG_PATA_PDC2027X is not set -# CONFIG_PATA_PDC_OLD is not set -# CONFIG_PATA_PLATFORM is not set -# CONFIG_PATA_QDI is not set -# CONFIG_PATA_RADISYS is not set -# CONFIG_PATA_RZ1000 is not set -# CONFIG_PATA_SC1200 is not set -# CONFIG_PATA_SERVERWORKS is not set -# CONFIG_PATA_SIL680 is not set -# CONFIG_PATA_SIS is not set -# CONFIG_PATA_TRIFLEX is not set -# CONFIG_PATA_VIA is not set -# CONFIG_PATA_WINBOND is not set -# CONFIG_PATA_WINBOND_VLB is not set -# CONFIG_PC300TOO is not set -# CONFIG_PCCARD is not set -# CONFIG_PCI is not set -# CONFIG_PCI_ATMEL is not set -# CONFIG_PCI_HERMES is not set -# CONFIG_PCI_LEGACY is not set -# CONFIG_PCI_MSI is not set -# CONFIG_PCMCIA is not set -# CONFIG_PCMCIA_AHA152X is not set -# CONFIG_PCMCIA_ATMEL is not set -# CONFIG_PCMCIA_DEBUG is not set -# CONFIG_PCMCIA_FDOMAIN is not set -# CONFIG_PCMCIA_HERMES is not set -# CONFIG_PCMCIA_IOCTL is not set -# CONFIG_PCMCIA_LOAD_CIS is not set -# CONFIG_PCMCIA_NETWAVE is not set -# CONFIG_PCMCIA_NINJA_SCSI is not set -# CONFIG_PCMCIA_QLOGIC is not set -# CONFIG_PCMCIA_RAYCS is not set -# CONFIG_PCMCIA_SPECTRUM is not set -# CONFIG_PCMCIA_SYM53C500 is not set -# CONFIG_PCMCIA_WAVELAN is not set -# CONFIG_PCMCIA_WL3501 is not set -# CONFIG_PCNET32 is not set -# CONFIG_PD6729 is not set -# CONFIG_PDC_ADMA is not set -# CONFIG_PHANTOM is not set -# CONFIG_PHONE is not set -# CONFIG_PHYLIB is not set -# CONFIG_PID_NS is not set -CONFIG_PLIST=y -# CONFIG_PLX_HERMES is not set -# CONFIG_PM is not set -# CONFIG_POSIX_MQUEUE is not set -# CONFIG_POWER_SUPPLY is not set -# CONFIG_PPP is not set -# CONFIG_PPPOATM is not set -# CONFIG_PPPOE is not set -# CONFIG_PPPOL2TP is not set -# CONFIG_PPP_ASYNC is not set -# CONFIG_PPP_BSDCOMP is not set -# CONFIG_PPP_DEFLATE is not set -CONFIG_PPP_FILTER=y -# CONFIG_PPP_MPPE is not set -CONFIG_PPP_MULTILINK=y -# CONFIG_PPP_SYNC_TTY is not set -# CONFIG_PREEMPT is not set -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set -CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_PRINTK=y -# CONFIG_PRINTK_TIME is not set -# CONFIG_PRISM54 is not set -CONFIG_PROC_FS=y -CONFIG_PROC_KCORE=y -CONFIG_PROC_SYSCTL=y -# CONFIG_PROFILING is not set -# CONFIG_QEMU is not set -# CONFIG_QLA3XXX is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_QUOTA is not set -# CONFIG_R3964 is not set -# CONFIG_R8169 is not set -# CONFIG_RADIO_ADAPTERS is not set -# CONFIG_RADIO_AZTECH is not set -# CONFIG_RADIO_CADET is not set -# CONFIG_RADIO_GEMTEK is not set -# CONFIG_RADIO_GEMTEK_PCI is not set -# CONFIG_RADIO_MAESTRO is not set -# CONFIG_RADIO_MAXIRADIO is not set -# CONFIG_RADIO_RTRACK is not set -# CONFIG_RADIO_RTRACK2 is not set -# CONFIG_RADIO_SF16FMI is not set -# CONFIG_RADIO_SF16FMR2 is not set -# CONFIG_RADIO_TERRATEC is not set -# CONFIG_RADIO_TRUST is not set -# CONFIG_RADIO_TYPHOON is not set -# CONFIG_RADIO_ZOLTRIX is not set -# CONFIG_RAID_ATTRS is not set -CONFIG_RAMFS=y -# CONFIG_RAW_DRIVER is not set -# CONFIG_REISERFS_CHECK is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_REISERFS_FS_XATTR is not set -# CONFIG_REISERFS_PROC_INFO is not set -# CONFIG_RELAY is not set -# CONFIG_RESOURCES_64BIT is not set -# CONFIG_RFD_FTL is not set -# CONFIG_RFKILL is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_ROSE is not set -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set -# CONFIG_RTC_CLASS is not set -CONFIG_RTC_DRV_CMOS=y -# CONFIG_RTC_DRV_MAX6900 is not set -# CONFIG_RTC_DRV_MAX6902 is not set -# CONFIG_RTC_DRV_RS5C348 is not set -# CONFIG_RTL8187 is not set -CONFIG_RT_MUTEXES=y -# CONFIG_S2IO is not set -# CONFIG_SAMPLES is not set -# CONFIG_SATA_AHCI is not set -# CONFIG_SATA_INIC162X is not set -# CONFIG_SATA_MV is not set -# CONFIG_SATA_NV is not set -# CONFIG_SATA_PROMISE is not set -# CONFIG_SATA_QSTOR is not set -# CONFIG_SATA_SIL is not set -# CONFIG_SATA_SIL24 is not set -# CONFIG_SATA_SIS is not set -# CONFIG_SATA_SVW is not set -# CONFIG_SATA_SX4 is not set -# CONFIG_SATA_ULI is not set -# CONFIG_SATA_VIA is not set -# CONFIG_SATA_VITESSE is not set -# CONFIG_SC92031 is not set -# CONFIG_SCSI is not set -# CONFIG_SCSI_3W_9XXX is not set -# CONFIG_SCSI_7000FASST is not set -# CONFIG_SCSI_AACRAID is not set -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_ADVANSYS is not set -# CONFIG_SCSI_AHA152X is not set -# CONFIG_SCSI_AHA1542 is not set -# CONFIG_SCSI_AIC79XX is not set -# CONFIG_SCSI_AIC7XXX is not set -# CONFIG_SCSI_AIC7XXX_OLD is not set -# CONFIG_SCSI_AIC94XX is not set -# CONFIG_SCSI_ARCMSR is not set -# CONFIG_SCSI_BUSLOGIC is not set -# CONFIG_SCSI_CONSTANTS is not set -# CONFIG_SCSI_DC390T is not set -# CONFIG_SCSI_DC395x is not set -# CONFIG_SCSI_DEBUG is not set -CONFIG_SCSI_DMA=y -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_DPT_I2O is not set -# CONFIG_SCSI_DTC3280 is not set -# CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_ESP_CORE is not set -# CONFIG_SCSI_FC_ATTRS 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_GENERIC_NCR5380_MMIO is not set -# CONFIG_SCSI_HPTIOP is not set -# CONFIG_SCSI_IN2000 is not set -# CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_IPR is not set -# CONFIG_SCSI_IPS is not set -# CONFIG_SCSI_ISCSI_ATTRS is not set -# CONFIG_SCSI_LOGGING is not set -CONFIG_SCSI_LOWLEVEL=y -# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set -# CONFIG_SCSI_LPFC is not set -CONFIG_SCSI_MULTI_LUN=y -# CONFIG_SCSI_NCR53C406A is not set -# CONFIG_SCSI_NETLINK is not set -# CONFIG_SCSI_NSP32 is not set -# CONFIG_SCSI_PAS16 is not set -CONFIG_SCSI_PROC_FS=y -# CONFIG_SCSI_PSI240I is not set -# CONFIG_SCSI_QLA_FC is not set -# CONFIG_SCSI_QLA_ISCSI is not set -# CONFIG_SCSI_QLOGIC_1280 is not set -# CONFIG_SCSI_QLOGIC_FAS is not set -# CONFIG_SCSI_SAS_ATTRS is not set -# CONFIG_SCSI_SAS_LIBSAS is not set -# CONFIG_SCSI_SCAN_ASYNC is not set -# CONFIG_SCSI_SEAGATE is not set -# CONFIG_SCSI_SPI_ATTRS is not set -# CONFIG_SCSI_SRP is not set -# CONFIG_SCSI_SRP_ATTRS is not set -# CONFIG_SCSI_STEX is not set -# CONFIG_SCSI_SYM53C416 is not set -# CONFIG_SCSI_SYM53C8XX_2 is not set -# CONFIG_SCSI_T128 is not set -# CONFIG_SCSI_TGT is not set -# CONFIG_SCSI_U14_34F is not set -# CONFIG_SCSI_ULTRASTOR is not set -# CONFIG_SECCOMP is not set -# CONFIG_SECURITY is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set -CONFIG_SELECT_MEMORY_MODEL=y -# CONFIG_SENSORS_ABITUGURU is not set -# CONFIG_SENSORS_ABITUGURU3 is not set -# CONFIG_SENSORS_AD7418 is not set -# CONFIG_SENSORS_ADM1021 is not set -# CONFIG_SENSORS_ADM1025 is not set -# CONFIG_SENSORS_ADM1026 is not set -# CONFIG_SENSORS_ADM1029 is not set -# CONFIG_SENSORS_ADM1031 is not set -# CONFIG_SENSORS_ADM9240 is not set -# CONFIG_SENSORS_ADT7470 is not set -# CONFIG_SENSORS_APPLESMC is not set -# CONFIG_SENSORS_ASB100 is not set -# CONFIG_SENSORS_ATXP1 is not set -# CONFIG_SENSORS_CORETEMP is not set -# CONFIG_SENSORS_DME1737 is not set -# CONFIG_SENSORS_DS1337 is not set -# CONFIG_SENSORS_DS1374 is not set -# CONFIG_SENSORS_DS1621 is not set -# CONFIG_SENSORS_EEPROM is not set -# CONFIG_SENSORS_F71805F is not set -# CONFIG_SENSORS_F71882FG is not set -# CONFIG_SENSORS_F75375S is not set -# CONFIG_SENSORS_FSCHER is not set -# CONFIG_SENSORS_FSCHMD is not set -# CONFIG_SENSORS_FSCPOS is not set -# CONFIG_SENSORS_GL518SM is not set -# CONFIG_SENSORS_GL520SM is not set -# CONFIG_SENSORS_HDAPS is not set -# CONFIG_SENSORS_I5K_AMB is not set -# CONFIG_SENSORS_IT87 is not set -# CONFIG_SENSORS_K8TEMP is not set -# CONFIG_SENSORS_LM63 is not set -# CONFIG_SENSORS_LM70 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_LM93 is not set -# CONFIG_SENSORS_M41T00 is not set -# CONFIG_SENSORS_MAX1619 is not set -# CONFIG_SENSORS_MAX6650 is not set -# CONFIG_SENSORS_MAX6875 is not set -# CONFIG_SENSORS_PC87427 is not set -# CONFIG_SENSORS_PCA9539 is not set -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_SIS5595 is not set -# CONFIG_SENSORS_SMSC47B397 is not set -# CONFIG_SENSORS_SMSC47M1 is not set -# CONFIG_SENSORS_SMSC47M192 is not set -# CONFIG_SENSORS_THMC50 is not set -# CONFIG_SENSORS_TSL2550 is not set -# CONFIG_SENSORS_VIA686A is not set -# CONFIG_SENSORS_VT1211 is not set -# CONFIG_SENSORS_VT8231 is not set -# CONFIG_SENSORS_W83627EHF is not set -# CONFIG_SENSORS_W83627HF is not set -# CONFIG_SENSORS_W83781D is not set -# CONFIG_SENSORS_W83791D is not set -# CONFIG_SENSORS_W83792D is not set -# CONFIG_SENSORS_W83793 is not set -# CONFIG_SENSORS_W83L785TS is not set -CONFIG_SERIAL_8250=y -CONFIG_SERIAL_8250_CONSOLE=y -# CONFIG_SERIAL_8250_CS is not set -CONFIG_SERIAL_8250_NR_UARTS=2 -# CONFIG_SERIAL_8250_PCI is not set -CONFIG_SERIAL_8250_RUNTIME_UARTS=2 -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_JSM is not set -# CONFIG_SERIAL_NONSTANDARD is not set -# CONFIG_SERIAL_UARTLITE is not set -# CONFIG_SERIO is not set -# CONFIG_SGI_IOC4 is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_SHAPER is not set -CONFIG_SHMEM=y -CONFIG_SIGNALFD=y -# CONFIG_SIS190 is not set -# CONFIG_SIS900 is not set -# CONFIG_SK98LIN is not set -# CONFIG_SKGE is not set -# CONFIG_SKY2 is not set -CONFIG_SLAB=y -# CONFIG_SLHC is not set -# CONFIG_SLIP is not set -# CONFIG_SLOB is not set -# CONFIG_SLUB is not set -# CONFIG_SMB_FS is not set -# CONFIG_SMB_NLS_DEFAULT is not set -# CONFIG_SND is not set -# CONFIG_SND_AC97_POWER_SAVE is not set -# CONFIG_SND_AD1816A is not set -# CONFIG_SND_AD1848 is not set -# CONFIG_SND_AD1889 is not set -# CONFIG_SND_ADLIB is not set -# CONFIG_SND_ALI5451 is not set -# CONFIG_SND_ALS100 is not set -# CONFIG_SND_ALS300 is not set -# CONFIG_SND_ALS4000 is not set -# CONFIG_SND_ATIIXP is not set -# CONFIG_SND_ATIIXP_MODEM is not set -# CONFIG_SND_AU8810 is not set -# CONFIG_SND_AU8820 is not set -# CONFIG_SND_AU8830 is not set -# CONFIG_SND_AZT2320 is not set -# CONFIG_SND_AZT3328 is not set -# CONFIG_SND_BT87X is not set -# CONFIG_SND_CA0106 is not set -# CONFIG_SND_CMI8330 is not set -# CONFIG_SND_CMIPCI is not set -# CONFIG_SND_CS4231 is not set -# CONFIG_SND_CS4232 is not set -# CONFIG_SND_CS4236 is not set -# CONFIG_SND_CS4281 is not set -# CONFIG_SND_CS46XX is not set -# CONFIG_SND_CS5530 is not set -# CONFIG_SND_CS5535AUDIO is not set -# CONFIG_SND_DARLA20 is not set -# CONFIG_SND_DARLA24 is not set -# CONFIG_SND_DEBUG is not set -# CONFIG_SND_DT019X is not set -# CONFIG_SND_DUMMY is not set -# CONFIG_SND_DYNAMIC_MINORS is not set -# CONFIG_SND_ECHO3G is not set -# CONFIG_SND_EMU10K1 is not set -# CONFIG_SND_EMU10K1X is not set -# CONFIG_SND_ENS1370 is not set -# CONFIG_SND_ENS1371 is not set -# CONFIG_SND_ES1688 is not set -# CONFIG_SND_ES18XX is not set -# CONFIG_SND_ES1938 is not set -# CONFIG_SND_ES1968 is not set -# CONFIG_SND_ES968 is not set -# CONFIG_SND_FM801 is not set -# CONFIG_SND_GINA20 is not set -# CONFIG_SND_GINA24 is not set -# CONFIG_SND_GUSCLASSIC is not set -# CONFIG_SND_GUSEXTREME is not set -# CONFIG_SND_GUSMAX is not set -# CONFIG_SND_HDA_INTEL is not set -# CONFIG_SND_HDSP is not set -# CONFIG_SND_HDSPM is not set -# CONFIG_SND_HWDEP is not set -# CONFIG_SND_ICE1712 is not set -# CONFIG_SND_ICE1724 is not set -# CONFIG_SND_INDIGO is not set -# CONFIG_SND_INDIGODJ is not set -# CONFIG_SND_INDIGOIO is not set -# CONFIG_SND_INTEL8X0 is not set -# CONFIG_SND_INTEL8X0M is not set -# CONFIG_SND_INTERWAVE is not set -# CONFIG_SND_INTERWAVE_STB is not set -# CONFIG_SND_KORG1212 is not set -# CONFIG_SND_LAYLA20 is not set -# CONFIG_SND_LAYLA24 is not set -# CONFIG_SND_MAESTRO3 is not set -# CONFIG_SND_MIA is not set -# CONFIG_SND_MIRO is not set -# CONFIG_SND_MIXART is not set -# CONFIG_SND_MIXER_OSS is not set -# CONFIG_SND_MONA is not set -# CONFIG_SND_MPU401 is not set -# CONFIG_SND_MTPAV is not set -# CONFIG_SND_NM256 is not set -# CONFIG_SND_OPL3SA2 is not set -# CONFIG_SND_OPTI92X_AD1848 is not set -# CONFIG_SND_OPTI92X_CS4231 is not set -# CONFIG_SND_OPTI93X is not set -CONFIG_SND_OSSEMUL=y -# CONFIG_SND_PCM is not set -# CONFIG_SND_PCM_OSS is not set -CONFIG_SND_PCM_OSS_PLUGINS=y -# CONFIG_SND_PCXHR is not set -# CONFIG_SND_PDAUDIOCF is not set -# CONFIG_SND_RAWMIDI is not set -# CONFIG_SND_RIPTIDE is not set -# CONFIG_SND_RME32 is not set -# CONFIG_SND_RME96 is not set -# CONFIG_SND_RME9652 is not set -# CONFIG_SND_RTCTIMER is not set -# CONFIG_SND_SB16 is not set -# CONFIG_SND_SB8 is not set -# CONFIG_SND_SBAWE is not set -# CONFIG_SND_SEQUENCER is not set -# CONFIG_SND_SERIAL_U16550 is not set -# CONFIG_SND_SGALAXY is not set -# CONFIG_SND_SOC is not set -# CONFIG_SND_SONICVIBES is not set -# CONFIG_SND_SSCAPE is not set -# CONFIG_SND_SUPPORT_OLD_API is not set -# CONFIG_SND_TIMER is not set -# CONFIG_SND_TRIDENT is not set -# CONFIG_SND_USB_AUDIO is not set -# CONFIG_SND_USB_CAIAQ is not set -# CONFIG_SND_USB_USX2Y is not set -# CONFIG_SND_VERBOSE_PRINTK is not set -CONFIG_SND_VERBOSE_PROCFS=y -# CONFIG_SND_VIA82XX is not set -# CONFIG_SND_VIA82XX_MODEM is not set -# CONFIG_SND_VX222 is not set -# CONFIG_SND_VXPOCKET is not set -# CONFIG_SND_WAVEFRONT is not set -# CONFIG_SND_YMFPCI is not set -# CONFIG_SNI_RM is not set -# CONFIG_SOLARIS_X86_PARTITION is not set -# CONFIG_SOUND is not set -# CONFIG_SOUND_PRIME is not set -# CONFIG_SPARSEMEM_MANUAL is not set -# CONFIG_SPI is not set -# CONFIG_SPI_DEBUG is not set -# CONFIG_SPI_MASTER is not set -# CONFIG_SPI_AT25 is not set -# CONFIG_SPI_TLE62X0 is not set -CONFIG_SPLIT_PTLOCK_CPUS=4 -CONFIG_SQUASHFS=y -# CONFIG_SQUASHFS_EMBEDDED is not set -CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 -# CONFIG_SQUASHFS_VMALLOC is not set -# CONFIG_SSB is not set -# CONFIG_SSB_DEBUG is not set -# CONFIG_SSB_DRIVER_MIPS is not set -# CONFIG_SSB_PCMCIAHOST is not set -# CONFIG_SSB_SILENT is not set -# CONFIG_SSFDC is not set -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_STANDALONE=y -# CONFIG_STRIP is not set -# CONFIG_SUNDANCE is not set -# CONFIG_SUNGEM is not set -# CONFIG_SUNRPC is not set -# CONFIG_SUNRPC_BIND34 is not set -# CONFIG_SUNRPC_GSS is not set -# CONFIG_SUN_PARTITION is not set -CONFIG_SUSPEND_UP_POSSIBLE=y -CONFIG_SWAP=y -# CONFIG_SYNCLINK_CS is not set -CONFIG_SYN_COOKIES=y -CONFIG_SYSCTL=y -CONFIG_SYSCTL_SYSCALL=y -CONFIG_SYSFS=y -# CONFIG_SYSFS_DEPRECATED is not set -# CONFIG_SYSV68_PARTITION is not set -CONFIG_SYSVIPC=y -# CONFIG_SYSV_FS is not set -# CONFIG_SYS_HYPERVISOR is not set -# CONFIG_TASKSTATS is not set -# CONFIG_TCG_TPM is not set -CONFIG_TCP_CONG_ADVANCED=y -# CONFIG_TCP_CONG_BIC is not set -# CONFIG_TCP_CONG_CUBIC is not set -# CONFIG_TCP_CONG_HSTCP is not set -# CONFIG_TCP_CONG_HTCP is not set -# CONFIG_TCP_CONG_HYBLA is not set -# CONFIG_TCP_CONG_ILLINOIS is not set -# CONFIG_TCP_CONG_LP is not set -# CONFIG_TCP_CONG_SCALABLE is not set -CONFIG_TCP_CONG_VEGAS=y -# CONFIG_TCP_CONG_VENO is not set -# CONFIG_TCP_CONG_WESTWOOD is not set -# CONFIG_TCP_CONG_YEAH is not set -# CONFIG_TCP_MD5SIG is not set -CONFIG_TEXTSEARCH=y -# CONFIG_TEXTSEARCH_BM is not set -# CONFIG_TEXTSEARCH_FSM is not set -# CONFIG_TEXTSEARCH_KMP is not set -# CONFIG_TIFM_CORE is not set -# CONFIG_TIGON3 is not set -CONFIG_TIMERFD=y -# CONFIG_TINY_SHMEM is not set -# CONFIG_TIPC is not set -# CONFIG_TLAN is not set -# CONFIG_TMD_HERMES is not set -CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set -# CONFIG_TR is not set -CONFIG_TRACE_IRQFLAGS_SUPPORT=y -# CONFIG_TUN is not set -# CONFIG_TUNER_3036 is not set -# CONFIG_TUNER_TEA5761 is not set -# CONFIG_UDF_FS is not set -CONFIG_UDF_NLS=y -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -# CONFIG_UFS_FS is not set -# CONFIG_UIO is not set -# CONFIG_ULTRIX_PARTITION is not set -CONFIG_UNIX=y -CONFIG_UNIX98_PTYS=y -# CONFIG_UNIXWARE_DISKLABEL is not set -# CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_USB is not set -# CONFIG_USBPCWATCHDOG is not set -# CONFIG_USB_ACECAD is not set -# CONFIG_USB_ACM is not set -# CONFIG_USB_ADUTUX is not set -# CONFIG_USB_AIPTEK is not set -CONFIG_USB_ALI_M5632=y -CONFIG_USB_AN2720=y -# CONFIG_USB_APPLEDISPLAY is not set -# CONFIG_USB_APPLETOUCH is not set -CONFIG_USB_ARCH_HAS_EHCI=y -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y -CONFIG_USB_ARMLINUX=y -# CONFIG_USB_ATI_REMOTE is not set -# CONFIG_USB_ATI_REMOTE2 is not set -# CONFIG_USB_ATM is not set -# CONFIG_USB_AUERSWALD is not set -# CONFIG_USB_BANDWIDTH is not set -CONFIG_USB_BELKIN=y -# CONFIG_USB_BERRY_CHARGE is not set -# CONFIG_USB_CATC is not set -# CONFIG_USB_CXACRU is not set -# CONFIG_USB_CYPRESS_CY7C63 is not set -# CONFIG_USB_CYTHERM is not set -# CONFIG_USB_DABUSB is not set -# CONFIG_USB_DEBUG is not set -CONFIG_USB_DEVICEFS=y -# CONFIG_USB_DEVICE_CLASS is not set -# CONFIG_USB_DSBR is not set -# CONFIG_USB_DYNAMIC_MINORS is not set -# CONFIG_USB_EHCI_ROOT_HUB_TT is not set -# CONFIG_USB_EHCI_SPLIT_ISO is not set -# CONFIG_USB_EHCI_TT_NEWSCHED is not set -# CONFIG_USB_EMI26 is not set -# CONFIG_USB_EMI62 is not set -# CONFIG_USB_EPSON2888 is not set -# CONFIG_USB_ET61X251 is not set -CONFIG_USB_EZUSB=y -# CONFIG_USB_FTDI_ELAN is not set -# CONFIG_USB_GADGET is not set -# CONFIG_USB_HID is not set -# CONFIG_USB_HIDDEV is not set -CONFIG_USB_HIDINPUT=y -# CONFIG_USB_HIDINPUT_POWERBOOK is not set -# CONFIG_USB_IBMCAM is not set -# CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_IOWARRIOR is not set -# CONFIG_USB_ISP116X_HCD is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_KBD is not set -# CONFIG_USB_KBTAB is not set -# CONFIG_USB_KC2190 is not set -# CONFIG_USB_KEYSPAN_REMOTE is not set -# CONFIG_USB_KONICAWC is not set -# CONFIG_USB_LCD is not set -# CONFIG_USB_LD is not set -# CONFIG_USB_LED is not set -# CONFIG_USB_LEGOTOWER is not set -# CONFIG_USB_LIBUSUAL is not set -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_MICROTEK is not set -# CONFIG_USB_MON is not set -# CONFIG_USB_MOUSE is not set -# CONFIG_USB_NET_AX8817X is not set -# CONFIG_USB_NET_CDCETHER is not set -# CONFIG_USB_NET_CDC_SUBSET is not set -# CONFIG_USB_NET_DM9601 is not set -# CONFIG_USB_NET_GL620A is not set -# CONFIG_USB_NET_MCS7830 is not set -# CONFIG_USB_NET_NET1080 is not set -# CONFIG_USB_NET_PLUSB is not set -# CONFIG_USB_NET_RNDIS_HOST is not set -# CONFIG_USB_NET_ZAURUS is not set -# CONFIG_USB_OHCI_BIG_ENDIAN is not set -# CONFIG_USB_OHCI_HCD is not set -# CONFIG_USB_OHCI_HCD_SSB is not set -CONFIG_USB_OHCI_LITTLE_ENDIAN=y -# CONFIG_USB_OTG is not set -# CONFIG_USB_OV511 is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_PHIDGET is not set -# CONFIG_USB_POWERMATE is not set -# CONFIG_USB_PRINTER is not set -# CONFIG_USB_QUICKCAM_MESSENGER is not set -# CONFIG_USB_R8A66597_HCD is not set -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_RTL8150 is not set -# CONFIG_USB_SE401 is not set -# CONFIG_USB_SERIAL is not set -# CONFIG_USB_SERIAL_AIRCABLE is not set -# CONFIG_USB_SERIAL_AIRPRIME is not set -# CONFIG_USB_SERIAL_ARK3116 is not set -# CONFIG_USB_SERIAL_BELKIN is not set -# CONFIG_USB_SERIAL_CH341 is not set -# CONFIG_USB_SERIAL_CP2101 is not set -# CONFIG_USB_SERIAL_CYBERJACK is not set -# CONFIG_USB_SERIAL_CYPRESS_M8 is not set -# CONFIG_USB_SERIAL_DEBUG is not set -# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set -# CONFIG_USB_SERIAL_EDGEPORT is not set -# CONFIG_USB_SERIAL_EDGEPORT_TI is not set -# CONFIG_USB_SERIAL_EMPEG is not set -# CONFIG_USB_SERIAL_FTDI_SIO is not set -# CONFIG_USB_SERIAL_FUNSOFT is not set -# CONFIG_USB_SERIAL_GARMIN is not set -CONFIG_USB_SERIAL_GENERIC=y -# CONFIG_USB_SERIAL_HP4X is not set -# CONFIG_USB_SERIAL_IPAQ is not set -# CONFIG_USB_SERIAL_IPW is not set -# CONFIG_USB_SERIAL_IR is not set -# CONFIG_USB_SERIAL_KEYSPAN is not set -CONFIG_USB_SERIAL_KEYSPAN_MPR=y -# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set -CONFIG_USB_SERIAL_KEYSPAN_USA18X=y -CONFIG_USB_SERIAL_KEYSPAN_USA19=y -CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y -CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y -CONFIG_USB_SERIAL_KEYSPAN_USA19W=y -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_USA49W=y -CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y -# CONFIG_USB_SERIAL_KLSI is not set -# CONFIG_USB_SERIAL_KOBIL_SCT is not set -# CONFIG_USB_SERIAL_MCT_U232 is not set -# CONFIG_USB_SERIAL_MOS7720 is not set -# CONFIG_USB_SERIAL_MOS7840 is not set -# CONFIG_USB_SERIAL_NAVMAN is not set -# CONFIG_USB_SERIAL_OMNINET is not set -# CONFIG_USB_SERIAL_OPTION is not set -# CONFIG_USB_SERIAL_OTI6858 is not set -# CONFIG_USB_SERIAL_PL2303 is not set -# CONFIG_USB_SERIAL_SAFE is not set -CONFIG_USB_SERIAL_SAFE_PADDED=y -# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set -# CONFIG_USB_SERIAL_TI is not set -# CONFIG_USB_SERIAL_VISOR is not set -# CONFIG_USB_SERIAL_WHITEHEAT is not set -# CONFIG_USB_SERIAL_XIRCOM is not set -# CONFIG_USB_SISUSBVGA is not set -# CONFIG_USB_SL811_HCD is not set -# CONFIG_USB_SN9C102 is not set -# CONFIG_USB_SPEEDTOUCH is not set -# CONFIG_USB_STORAGE is not set -CONFIG_USB_STORAGE_ALAUDA=y -CONFIG_USB_STORAGE_DATAFAB=y -# CONFIG_USB_STORAGE_DEBUG is not set -CONFIG_USB_STORAGE_DPCM=y -CONFIG_USB_STORAGE_FREECOM=y -# CONFIG_USB_STORAGE_ISD200 is not set -CONFIG_USB_STORAGE_JUMPSHOT=y -CONFIG_USB_STORAGE_KARMA=y -# CONFIG_USB_STORAGE_ONETOUCH is not set -CONFIG_USB_STORAGE_SDDR09=y -CONFIG_USB_STORAGE_SDDR55=y -CONFIG_USB_STORAGE_USBAT=y -# CONFIG_USB_STV680 is not set -CONFIG_USB_SUPPORT=y -# CONFIG_USB_TEST is not set -# CONFIG_USB_TOUCHSCREEN is not set -# CONFIG_USB_TRANCEVIBRATOR is not set -# CONFIG_USB_UEAGLEATM is not set -# CONFIG_USB_USBNET is not set -# CONFIG_USB_USBNET_MII is not set -# CONFIG_USB_VICAM is not set -# CONFIG_USB_W9968CF is not set -# CONFIG_USB_WACOM is not set -# CONFIG_USB_XPAD is not set -# CONFIG_USB_XUSBATM is not set -# CONFIG_USB_YEALINK is not set -# CONFIG_USB_ZC0301 is not set -# CONFIG_USB_ZD1201 is not set -# CONFIG_USB_ZR364XX is not set -# CONFIG_UTS_NS is not set -# CONFIG_VETH is not set -# CONFIG_VFAT_FS is not set -# CONFIG_VIA_VELOCITY is not set -# CONFIG_VIDEO_ADV7170 is not set -# CONFIG_VIDEO_ADV7175 is not set -# CONFIG_VIDEO_ADV_DEBUG is not set -# CONFIG_VIDEO_BT819 is not set -# CONFIG_VIDEO_BT848 is not set -# CONFIG_VIDEO_BT856 is not set -# CONFIG_VIDEO_BT866 is not set -# CONFIG_VIDEO_CAFE_CCIC is not set -# CONFIG_VIDEO_CAPTURE_DRIVERS is not set -# CONFIG_VIDEO_CPIA is not set -# CONFIG_VIDEO_CS53L32A is not set -# CONFIG_VIDEO_CX2341X is not set -# CONFIG_VIDEO_CX25840 is not set -# CONFIG_VIDEO_CX88 is not set -# CONFIG_VIDEO_DEV is not set -# CONFIG_VIDEO_DPC is not set -# CONFIG_VIDEO_EM28XX is not set -# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set -# CONFIG_VIDEO_HEXIUM_GEMINI is not set -# CONFIG_VIDEO_HEXIUM_ORION is not set -# CONFIG_VIDEO_IVTV is not set -# CONFIG_VIDEO_KS0127 is not set -# CONFIG_VIDEO_MSP3400 is not set -# CONFIG_VIDEO_MXB is not set -# CONFIG_VIDEO_OUTPUT_CONTROL is not set -# CONFIG_VIDEO_OV7670 is not set -# CONFIG_VIDEO_OVCAMCHIP is not set -# CONFIG_VIDEO_PMS is not set -# CONFIG_VIDEO_PVRUSB2 is not set -# CONFIG_VIDEO_SAA5246A is not set -# CONFIG_VIDEO_SAA5249 is not set -# CONFIG_VIDEO_SAA7110 is not set -# CONFIG_VIDEO_SAA7111 is not set -# CONFIG_VIDEO_SAA7114 is not set -# CONFIG_VIDEO_SAA711X is not set -# CONFIG_VIDEO_SAA7127 is not set -# CONFIG_VIDEO_SAA7134 is not set -# CONFIG_VIDEO_SAA7185 is not set -# CONFIG_VIDEO_SAA7191 is not set -# CONFIG_VIDEO_STRADIS is not set -# CONFIG_VIDEO_TCM825X is not set -# CONFIG_VIDEO_TDA7432 is not set -# CONFIG_VIDEO_TDA9840 is not set -# CONFIG_VIDEO_TDA9875 is not set -# CONFIG_VIDEO_TEA6415C is not set -# CONFIG_VIDEO_TEA6420 is not set -# CONFIG_VIDEO_TLV320AIC23B is not set -# CONFIG_VIDEO_TVAUDIO is not set -# CONFIG_VIDEO_TVP5150 is not set -# CONFIG_VIDEO_UPD64031A is not set -# CONFIG_VIDEO_UPD64083 is not set -# CONFIG_VIDEO_USBVISION is not set -# CONFIG_VIDEO_V4L1 is not set -CONFIG_VIDEO_V4L1_COMPAT=y -CONFIG_VIDEO_V4L2=y -# CONFIG_VIDEO_VIVI is not set -# CONFIG_VIDEO_VP27SMPX is not set -# CONFIG_VIDEO_VPX3220 is not set -# CONFIG_VIDEO_WM8739 is not set -# CONFIG_VIDEO_WM8775 is not set -# CONFIG_VIDEO_ZORAN is not set -CONFIG_VIRT_TO_BUS=y -# CONFIG_VITESSE_PHY is not set -CONFIG_VLAN_8021Q=y -# CONFIG_VM_EVENT_COUNTERS is not set -# CONFIG_VT is not set -# CONFIG_VXFS_FS is not set -# CONFIG_W1 is not set -# CONFIG_W1_MASTER_DS1WM is not set -# CONFIG_W1_MASTER_DS2482 is not set -# CONFIG_W1_MASTER_DS2490 is not set -# CONFIG_W1_MASTER_GPIO is not set -# CONFIG_W1_MASTER_MATROX is not set -# CONFIG_W1_SLAVE_DS2433 is not set -# CONFIG_W1_SLAVE_DS2760 is not set -# CONFIG_W1_SLAVE_SMEM is not set -# CONFIG_W1_SLAVE_THERM is not set -# CONFIG_W83627HF_WDT is not set -# CONFIG_W83697HF_WDT is not set -# CONFIG_W83877F_WDT is not set -# CONFIG_W83977F_WDT is not set -# CONFIG_WAN is not set -# CONFIG_WAN_ROUTER is not set -CONFIG_WATCHDOG=y -# CONFIG_WATCHDOG_NOWAYOUT is not set -# CONFIG_WDTPCI is not set -CONFIG_WIRELESS_EXT=y -CONFIG_WLAN_80211=y -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WR_PPMC is not set -# CONFIG_X25 is not set -CONFIG_XFRM=y -# CONFIG_XFRM_MIGRATE is not set -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_USER is not set -# CONFIG_XFS_FS is not set -# CONFIG_XFS_POSIX_ACL is not set -# CONFIG_XFS_QUOTA is not set -# CONFIG_XFS_RT is not set -# CONFIG_XFS_SECURITY is not set -# CONFIG_YAFFS_FS is not set -# CONFIG_YAM is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_YENTA is not set -# CONFIG_YENTA_O2 is not set -# CONFIG_YENTA_RICOH is not set -# CONFIG_YENTA_TI is not set -# CONFIG_YENTA_TOSHIBA is not set -# CONFIG_ZD1211RW is not set -# CONFIG_ZD1211RW_DEBUG is not set -CONFIG_ZISOFS=y -# CONFIG_ZISOFS_FS is not set -CONFIG_ZLIB_DEFLATE=y -CONFIG_ZLIB_INFLATE=y -CONFIG_ZONE_DMA=y -CONFIG_ZONE_DMA_FLAG=1 diff --git a/target/linux/generic-2.6/patches-2.6.24/001-squashfs.patch b/target/linux/generic-2.6/patches-2.6.24/001-squashfs.patch deleted file mode 100644 index 1db40917cd..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/001-squashfs.patch +++ /dev/null @@ -1,4170 +0,0 @@ ---- a/fs/Kconfig -+++ b/fs/Kconfig -@@ -1405,6 +1405,71 @@ config CRAMFS - - If unsure, say N. - -+config SQUASHFS -+ tristate "SquashFS 3.0 - Squashed file system support" -+ select ZLIB_INFLATE -+ help -+ Saying Y here includes support for SquashFS 3.0 (a Compressed Read-Only File -+ System). Squashfs is a highly compressed read-only filesystem for Linux. -+ It uses zlib compression to compress both files, inodes and directories. -+ Inodes in the system are very small and all blocks are packed to minimise -+ data overhead. Block sizes greater than 4K are supported up to a maximum of 64K. -+ SquashFS 3.0 supports 64 bit filesystems and files (larger than 4GB), full -+ uid/gid information, hard links and timestamps. -+ -+ Squashfs is intended for general read-only filesystem use, for archival -+ use (i.e. in cases where a .tar.gz file may be used), and in embedded -+ systems where low overhead is needed. Further information and filesystem tools -+ are available from http://squashfs.sourceforge.net. -+ -+ If you want to compile this as a module ( = code which can be -+ inserted in and removed from the running kernel whenever you want), -+ say M here and read . The module -+ will be called squashfs. Note that the root file system (the one -+ containing the directory /) cannot be compiled as a module. -+ -+ If unsure, say N. -+ -+config SQUASHFS_EMBEDDED -+ -+ bool "Additional options for memory-constrained systems" -+ depends on SQUASHFS -+ default n -+ help -+ Saying Y here allows you to specify cache sizes and how Squashfs -+ allocates memory. This is only intended for memory constrained -+ systems. -+ -+ If unsure, say N. -+ -+config SQUASHFS_FRAGMENT_CACHE_SIZE -+ int "Number of fragments cached" if SQUASHFS_EMBEDDED -+ depends on SQUASHFS -+ default "3" -+ help -+ By default SquashFS caches the last 3 fragments read from -+ the filesystem. Increasing this amount may mean SquashFS -+ has to re-read fragments less often from disk, at the expense -+ of extra system memory. Decreasing this amount will mean -+ SquashFS uses less memory at the expense of extra reads from disk. -+ -+ Note there must be at least one cached fragment. Anything -+ much more than three will probably not make much difference. -+ -+config SQUASHFS_VMALLOC -+ bool "Use Vmalloc rather than Kmalloc" if SQUASHFS_EMBEDDED -+ depends on SQUASHFS -+ default n -+ help -+ By default SquashFS uses kmalloc to obtain fragment cache memory. -+ Kmalloc memory is the standard kernel allocator, but it can fail -+ on memory constrained systems. Because of the way Vmalloc works, -+ Vmalloc can succeed when kmalloc fails. Specifying this option -+ will make SquashFS always use Vmalloc to allocate the -+ fragment cache memory. -+ -+ If unsure, say N. -+ - config VXFS_FS - tristate "FreeVxFS file system support (VERITAS VxFS(TM) compatible)" - depends on BLOCK ---- a/fs/Makefile -+++ b/fs/Makefile -@@ -72,6 +72,7 @@ obj-$(CONFIG_JBD) += jbd/ - obj-$(CONFIG_JBD2) += jbd2/ - obj-$(CONFIG_EXT2_FS) += ext2/ - obj-$(CONFIG_CRAMFS) += cramfs/ -+obj-$(CONFIG_SQUASHFS) += squashfs/ - obj-y += ramfs/ - obj-$(CONFIG_HUGETLBFS) += hugetlbfs/ - obj-$(CONFIG_CODA_FS) += coda/ ---- /dev/null -+++ b/fs/squashfs/inode.c -@@ -0,0 +1,2122 @@ -+/* -+ * Squashfs - a compressed read only filesystem for Linux -+ * -+ * Copyright (c) 2002, 2003, 2004, 2005, 2006 -+ * Phillip Lougher -+ * -+ * 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, -+ * 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ * -+ * inode.c -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "squashfs.h" -+ -+static void squashfs_put_super(struct super_block *); -+static int squashfs_statfs(struct dentry *, struct kstatfs *); -+static int squashfs_symlink_readpage(struct file *file, struct page *page); -+static int squashfs_readpage(struct file *file, struct page *page); -+static int squashfs_readpage4K(struct file *file, struct page *page); -+static int squashfs_readdir(struct file *, void *, filldir_t); -+static struct inode *squashfs_alloc_inode(struct super_block *sb); -+static void squashfs_destroy_inode(struct inode *inode); -+static int init_inodecache(void); -+static void destroy_inodecache(void); -+static struct dentry *squashfs_lookup(struct inode *, struct dentry *, -+ struct nameidata *); -+static struct inode *squashfs_iget(struct super_block *s, squashfs_inode_t inode); -+static long long read_blocklist(struct inode *inode, int index, -+ int readahead_blks, char *block_list, -+ unsigned short **block_p, unsigned int *bsize); -+static int squashfs_get_sb(struct file_system_type *, int, -+ const char *, void *, struct vfsmount *); -+ -+ -+static z_stream stream; -+ -+static struct file_system_type squashfs_fs_type = { -+ .owner = THIS_MODULE, -+ .name = "squashfs", -+ .get_sb = squashfs_get_sb, -+ .kill_sb = kill_block_super, -+ .fs_flags = FS_REQUIRES_DEV -+}; -+ -+static unsigned char squashfs_filetype_table[] = { -+ DT_UNKNOWN, DT_DIR, DT_REG, DT_LNK, DT_BLK, DT_CHR, DT_FIFO, DT_SOCK -+}; -+ -+static struct super_operations squashfs_ops = { -+ .alloc_inode = squashfs_alloc_inode, -+ .destroy_inode = squashfs_destroy_inode, -+ .statfs = squashfs_statfs, -+ .put_super = squashfs_put_super, -+}; -+ -+SQSH_EXTERN struct address_space_operations squashfs_symlink_aops = { -+ .readpage = squashfs_symlink_readpage -+}; -+ -+SQSH_EXTERN struct address_space_operations squashfs_aops = { -+ .readpage = squashfs_readpage -+}; -+ -+SQSH_EXTERN struct address_space_operations squashfs_aops_4K = { -+ .readpage = squashfs_readpage4K -+}; -+ -+static struct file_operations squashfs_dir_ops = { -+ .read = generic_read_dir, -+ .readdir = squashfs_readdir -+}; -+ -+SQSH_EXTERN struct inode_operations squashfs_dir_inode_ops = { -+ .lookup = squashfs_lookup -+}; -+ -+ -+static struct buffer_head *get_block_length(struct super_block *s, -+ int *cur_index, int *offset, int *c_byte) -+{ -+ struct squashfs_sb_info *msblk = s->s_fs_info; -+ unsigned short temp; -+ struct buffer_head *bh; -+ -+ if (!(bh = sb_bread(s, *cur_index))) -+ goto out; -+ -+ if (msblk->devblksize - *offset == 1) { -+ if (msblk->swap) -+ ((unsigned char *) &temp)[1] = *((unsigned char *) -+ (bh->b_data + *offset)); -+ else -+ ((unsigned char *) &temp)[0] = *((unsigned char *) -+ (bh->b_data + *offset)); -+ brelse(bh); -+ if (!(bh = sb_bread(s, ++(*cur_index)))) -+ goto out; -+ if (msblk->swap) -+ ((unsigned char *) &temp)[0] = *((unsigned char *) -+ bh->b_data); -+ else -+ ((unsigned char *) &temp)[1] = *((unsigned char *) -+ bh->b_data); -+ *c_byte = temp; -+ *offset = 1; -+ } else { -+ if (msblk->swap) { -+ ((unsigned char *) &temp)[1] = *((unsigned char *) -+ (bh->b_data + *offset)); -+ ((unsigned char *) &temp)[0] = *((unsigned char *) -+ (bh->b_data + *offset + 1)); -+ } else { -+ ((unsigned char *) &temp)[0] = *((unsigned char *) -+ (bh->b_data + *offset)); -+ ((unsigned char *) &temp)[1] = *((unsigned char *) -+ (bh->b_data + *offset + 1)); -+ } -+ *c_byte = temp; -+ *offset += 2; -+ } -+ -+ if (SQUASHFS_CHECK_DATA(msblk->sblk.flags)) { -+ if (*offset == msblk->devblksize) { -+ brelse(bh); -+ if (!(bh = sb_bread(s, ++(*cur_index)))) -+ goto out; -+ *offset = 0; -+ } -+ if (*((unsigned char *) (bh->b_data + *offset)) != -+ SQUASHFS_MARKER_BYTE) { -+ ERROR("Metadata block marker corrupt @ %x\n", -+ *cur_index); -+ brelse(bh); -+ goto out; -+ } -+ (*offset)++; -+ } -+ return bh; -+ -+out: -+ return NULL; -+} -+ -+ -+SQSH_EXTERN unsigned int squashfs_read_data(struct super_block *s, char *buffer, -+ long long index, unsigned int length, -+ long long *next_index) -+{ -+ struct squashfs_sb_info *msblk = s->s_fs_info; -+ struct buffer_head *bh[((SQUASHFS_FILE_MAX_SIZE - 1) >> -+ msblk->devblksize_log2) + 2]; -+ unsigned int offset = index & ((1 << msblk->devblksize_log2) - 1); -+ unsigned int cur_index = index >> msblk->devblksize_log2; -+ int bytes, avail_bytes, b = 0, k; -+ char *c_buffer; -+ unsigned int compressed; -+ unsigned int c_byte = length; -+ -+ if (c_byte) { -+ bytes = msblk->devblksize - offset; -+ compressed = SQUASHFS_COMPRESSED_BLOCK(c_byte); -+ c_buffer = compressed ? msblk->read_data : buffer; -+ c_byte = SQUASHFS_COMPRESSED_SIZE_BLOCK(c_byte); -+ -+ TRACE("Block @ 0x%llx, %scompressed size %d\n", index, compressed -+ ? "" : "un", (unsigned int) c_byte); -+ -+ if (!(bh[0] = sb_getblk(s, cur_index))) -+ goto block_release; -+ -+ for (b = 1; bytes < c_byte; b++) { -+ if (!(bh[b] = sb_getblk(s, ++cur_index))) -+ goto block_release; -+ bytes += msblk->devblksize; -+ } -+ ll_rw_block(READ, b, bh); -+ } else { -+ if (!(bh[0] = get_block_length(s, &cur_index, &offset, -+ &c_byte))) -+ goto read_failure; -+ -+ bytes = msblk->devblksize - offset; -+ compressed = SQUASHFS_COMPRESSED(c_byte); -+ c_buffer = compressed ? msblk->read_data : buffer; -+ c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte); -+ -+ TRACE("Block @ 0x%llx, %scompressed size %d\n", index, compressed -+ ? "" : "un", (unsigned int) c_byte); -+ -+ for (b = 1; bytes < c_byte; b++) { -+ if (!(bh[b] = sb_getblk(s, ++cur_index))) -+ goto block_release; -+ bytes += msblk->devblksize; -+ } -+ ll_rw_block(READ, b - 1, bh + 1); -+ } -+ -+ if (compressed) -+ down(&msblk->read_data_mutex); -+ -+ for (bytes = 0, k = 0; k < b; k++) { -+ avail_bytes = (c_byte - bytes) > (msblk->devblksize - offset) ? -+ msblk->devblksize - offset : -+ c_byte - bytes; -+ wait_on_buffer(bh[k]); -+ if (!buffer_uptodate(bh[k])) -+ goto block_release; -+ memcpy(c_buffer + bytes, bh[k]->b_data + offset, avail_bytes); -+ bytes += avail_bytes; -+ offset = 0; -+ brelse(bh[k]); -+ } -+ -+ /* -+ * uncompress block -+ */ -+ if (compressed) { -+ int zlib_err; -+ -+ stream.next_in = c_buffer; -+ stream.avail_in = c_byte; -+ stream.next_out = buffer; -+ stream.avail_out = msblk->read_size; -+ -+ if (((zlib_err = zlib_inflateInit(&stream)) != Z_OK) || -+ ((zlib_err = zlib_inflate(&stream, Z_FINISH)) -+ != Z_STREAM_END) || ((zlib_err = -+ zlib_inflateEnd(&stream)) != Z_OK)) { -+ ERROR("zlib_fs returned unexpected result 0x%x\n", -+ zlib_err); -+ bytes = 0; -+ } else -+ bytes = stream.total_out; -+ -+ up(&msblk->read_data_mutex); -+ } -+ -+ if (next_index) -+ *next_index = index + c_byte + (length ? 0 : -+ (SQUASHFS_CHECK_DATA(msblk->sblk.flags) -+ ? 3 : 2)); -+ return bytes; -+ -+block_release: -+ while (--b >= 0) -+ brelse(bh[b]); -+ -+read_failure: -+ ERROR("sb_bread failed reading block 0x%x\n", cur_index); -+ return 0; -+} -+ -+ -+SQSH_EXTERN int squashfs_get_cached_block(struct super_block *s, char *buffer, -+ long long block, unsigned int offset, -+ int length, long long *next_block, -+ unsigned int *next_offset) -+{ -+ struct squashfs_sb_info *msblk = s->s_fs_info; -+ int n, i, bytes, return_length = length; -+ long long next_index; -+ -+ TRACE("Entered squashfs_get_cached_block [%llx:%x]\n", block, offset); -+ -+ while ( 1 ) { -+ for (i = 0; i < SQUASHFS_CACHED_BLKS; i++) -+ if (msblk->block_cache[i].block == block) -+ break; -+ -+ down(&msblk->block_cache_mutex); -+ -+ if (i == SQUASHFS_CACHED_BLKS) { -+ /* read inode header block */ -+ for (i = msblk->next_cache, n = SQUASHFS_CACHED_BLKS; -+ n ; n --, i = (i + 1) % -+ SQUASHFS_CACHED_BLKS) -+ if (msblk->block_cache[i].block != -+ SQUASHFS_USED_BLK) -+ break; -+ -+ if (n == 0) { -+ wait_queue_t wait; -+ -+ init_waitqueue_entry(&wait, current); -+ add_wait_queue(&msblk->waitq, &wait); -+ set_current_state(TASK_UNINTERRUPTIBLE); -+ up(&msblk->block_cache_mutex); -+ schedule(); -+ set_current_state(TASK_RUNNING); -+ remove_wait_queue(&msblk->waitq, &wait); -+ continue; -+ } -+ msblk->next_cache = (i + 1) % SQUASHFS_CACHED_BLKS; -+ -+ if (msblk->block_cache[i].block == -+ SQUASHFS_INVALID_BLK) { -+ if (!(msblk->block_cache[i].data = -+ kmalloc(SQUASHFS_METADATA_SIZE, -+ GFP_KERNEL))) { -+ ERROR("Failed to allocate cache" -+ "block\n"); -+ up(&msblk->block_cache_mutex); -+ goto out; -+ } -+ } -+ -+ msblk->block_cache[i].block = SQUASHFS_USED_BLK; -+ up(&msblk->block_cache_mutex); -+ -+ if (!(msblk->block_cache[i].length = -+ squashfs_read_data(s, -+ msblk->block_cache[i].data, -+ block, 0, &next_index))) { -+ ERROR("Unable to read cache block [%llx:%x]\n", -+ block, offset); -+ goto out; -+ } -+ -+ down(&msblk->block_cache_mutex); -+ wake_up(&msblk->waitq); -+ msblk->block_cache[i].block = block; -+ msblk->block_cache[i].next_index = next_index; -+ TRACE("Read cache block [%llx:%x]\n", block, offset); -+ } -+ -+ if (msblk->block_cache[i].block != block) { -+ up(&msblk->block_cache_mutex); -+ continue; -+ } -+ -+ if ((bytes = msblk->block_cache[i].length - offset) >= length) { -+ if (buffer) -+ memcpy(buffer, msblk->block_cache[i].data + -+ offset, length); -+ if (msblk->block_cache[i].length - offset == length) { -+ *next_block = msblk->block_cache[i].next_index; -+ *next_offset = 0; -+ } else { -+ *next_block = block; -+ *next_offset = offset + length; -+ } -+ up(&msblk->block_cache_mutex); -+ goto finish; -+ } else { -+ if (buffer) { -+ memcpy(buffer, msblk->block_cache[i].data + -+ offset, bytes); -+ buffer += bytes; -+ } -+ block = msblk->block_cache[i].next_index; -+ up(&msblk->block_cache_mutex); -+ length -= bytes; -+ offset = 0; -+ } -+ } -+ -+finish: -+ return return_length; -+out: -+ return 0; -+} -+ -+ -+static int get_fragment_location(struct super_block *s, unsigned int fragment, -+ long long *fragment_start_block, -+ unsigned int *fragment_size) -+{ -+ struct squashfs_sb_info *msblk = s->s_fs_info; -+ long long start_block = -+ msblk->fragment_index[SQUASHFS_FRAGMENT_INDEX(fragment)]; -+ int offset = SQUASHFS_FRAGMENT_INDEX_OFFSET(fragment); -+ struct squashfs_fragment_entry fragment_entry; -+ -+ if (msblk->swap) { -+ struct squashfs_fragment_entry sfragment_entry; -+ -+ if (!squashfs_get_cached_block(s, (char *) &sfragment_entry, -+ start_block, offset, -+ sizeof(sfragment_entry), &start_block, -+ &offset)) -+ goto out; -+ SQUASHFS_SWAP_FRAGMENT_ENTRY(&fragment_entry, &sfragment_entry); -+ } else -+ if (!squashfs_get_cached_block(s, (char *) &fragment_entry, -+ start_block, offset, -+ sizeof(fragment_entry), &start_block, -+ &offset)) -+ goto out; -+ -+ *fragment_start_block = fragment_entry.start_block; -+ *fragment_size = fragment_entry.size; -+ -+ return 1; -+ -+out: -+ return 0; -+} -+ -+ -+SQSH_EXTERN void release_cached_fragment(struct squashfs_sb_info *msblk, struct -+ squashfs_fragment_cache *fragment) -+{ -+ down(&msblk->fragment_mutex); -+ fragment->locked --; -+ wake_up(&msblk->fragment_wait_queue); -+ up(&msblk->fragment_mutex); -+} -+ -+ -+SQSH_EXTERN struct squashfs_fragment_cache *get_cached_fragment(struct super_block -+ *s, long long start_block, -+ int length) -+{ -+ int i, n; -+ struct squashfs_sb_info *msblk = s->s_fs_info; -+ -+ while ( 1 ) { -+ down(&msblk->fragment_mutex); -+ -+ for (i = 0; i < SQUASHFS_CACHED_FRAGMENTS && -+ msblk->fragment[i].block != start_block; i++); -+ -+ if (i == SQUASHFS_CACHED_FRAGMENTS) { -+ for (i = msblk->next_fragment, n = -+ SQUASHFS_CACHED_FRAGMENTS; n && -+ msblk->fragment[i].locked; n--, i = (i + 1) % -+ SQUASHFS_CACHED_FRAGMENTS); -+ -+ if (n == 0) { -+ wait_queue_t wait; -+ -+ init_waitqueue_entry(&wait, current); -+ add_wait_queue(&msblk->fragment_wait_queue, -+ &wait); -+ set_current_state(TASK_UNINTERRUPTIBLE); -+ up(&msblk->fragment_mutex); -+ schedule(); -+ set_current_state(TASK_RUNNING); -+ remove_wait_queue(&msblk->fragment_wait_queue, -+ &wait); -+ continue; -+ } -+ msblk->next_fragment = (msblk->next_fragment + 1) % -+ SQUASHFS_CACHED_FRAGMENTS; -+ -+ if (msblk->fragment[i].data == NULL) -+ if (!(msblk->fragment[i].data = SQUASHFS_ALLOC -+ (SQUASHFS_FILE_MAX_SIZE))) { -+ ERROR("Failed to allocate fragment " -+ "cache block\n"); -+ up(&msblk->fragment_mutex); -+ goto out; -+ } -+ -+ msblk->fragment[i].block = SQUASHFS_INVALID_BLK; -+ msblk->fragment[i].locked = 1; -+ up(&msblk->fragment_mutex); -+ -+ if (!(msblk->fragment[i].length = squashfs_read_data(s, -+ msblk->fragment[i].data, -+ start_block, length, NULL))) { -+ ERROR("Unable to read fragment cache block " -+ "[%llx]\n", start_block); -+ msblk->fragment[i].locked = 0; -+ goto out; -+ } -+ -+ msblk->fragment[i].block = start_block; -+ TRACE("New fragment %d, start block %lld, locked %d\n", -+ i, msblk->fragment[i].block, -+ msblk->fragment[i].locked); -+ break; -+ } -+ -+ msblk->fragment[i].locked++; -+ up(&msblk->fragment_mutex); -+ TRACE("Got fragment %d, start block %lld, locked %d\n", i, -+ msblk->fragment[i].block, -+ msblk->fragment[i].locked); -+ break; -+ } -+ -+ return &msblk->fragment[i]; -+ -+out: -+ return NULL; -+} -+ -+ -+static struct inode *squashfs_new_inode(struct super_block *s, -+ struct squashfs_base_inode_header *inodeb) -+{ -+ struct squashfs_sb_info *msblk = s->s_fs_info; -+ struct inode *i = new_inode(s); -+ -+ if (i) { -+ i->i_ino = inodeb->inode_number; -+ i->i_mtime.tv_sec = inodeb->mtime; -+ i->i_atime.tv_sec = inodeb->mtime; -+ i->i_ctime.tv_sec = inodeb->mtime; -+ i->i_uid = msblk->uid[inodeb->uid]; -+ i->i_mode = inodeb->mode; -+ i->i_size = 0; -+ if (inodeb->guid == SQUASHFS_GUIDS) -+ i->i_gid = i->i_uid; -+ else -+ i->i_gid = msblk->guid[inodeb->guid]; -+ } -+ -+ return i; -+} -+ -+ -+static struct inode *squashfs_iget(struct super_block *s, squashfs_inode_t inode) -+{ -+ struct inode *i; -+ struct squashfs_sb_info *msblk = s->s_fs_info; -+ struct squashfs_super_block *sblk = &msblk->sblk; -+ long long block = SQUASHFS_INODE_BLK(inode) + -+ sblk->inode_table_start; -+ unsigned int offset = SQUASHFS_INODE_OFFSET(inode); -+ long long next_block; -+ unsigned int next_offset; -+ union squashfs_inode_header id, sid; -+ struct squashfs_base_inode_header *inodeb = &id.base, -+ *sinodeb = &sid.base; -+ -+ TRACE("Entered squashfs_iget\n"); -+ -+ if (msblk->swap) { -+ if (!squashfs_get_cached_block(s, (char *) sinodeb, block, -+ offset, sizeof(*sinodeb), &next_block, -+ &next_offset)) -+ goto failed_read; -+ SQUASHFS_SWAP_BASE_INODE_HEADER(inodeb, sinodeb, -+ sizeof(*sinodeb)); -+ } else -+ if (!squashfs_get_cached_block(s, (char *) inodeb, block, -+ offset, sizeof(*inodeb), &next_block, -+ &next_offset)) -+ goto failed_read; -+ -+ switch(inodeb->inode_type) { -+ case SQUASHFS_FILE_TYPE: { -+ unsigned int frag_size; -+ long long frag_blk; -+ struct squashfs_reg_inode_header *inodep = &id.reg; -+ struct squashfs_reg_inode_header *sinodep = &sid.reg; -+ -+ if (msblk->swap) { -+ if (!squashfs_get_cached_block(s, (char *) -+ sinodep, block, offset, -+ sizeof(*sinodep), &next_block, -+ &next_offset)) -+ goto failed_read; -+ SQUASHFS_SWAP_REG_INODE_HEADER(inodep, sinodep); -+ } else -+ if (!squashfs_get_cached_block(s, (char *) -+ inodep, block, offset, -+ sizeof(*inodep), &next_block, -+ &next_offset)) -+ goto failed_read; -+ -+ frag_blk = SQUASHFS_INVALID_BLK; -+ if (inodep->fragment != SQUASHFS_INVALID_FRAG && -+ !get_fragment_location(s, -+ inodep->fragment, &frag_blk, &frag_size)) -+ goto failed_read; -+ -+ if((i = squashfs_new_inode(s, inodeb)) == NULL) -+ goto failed_read1; -+ -+ i->i_nlink = 1; -+ i->i_size = inodep->file_size; -+ i->i_fop = &generic_ro_fops; -+ i->i_mode |= S_IFREG; -+ i->i_blocks = ((i->i_size - 1) >> 9) + 1; -+ SQUASHFS_I(i)->u.s1.fragment_start_block = frag_blk; -+ SQUASHFS_I(i)->u.s1.fragment_size = frag_size; -+ SQUASHFS_I(i)->u.s1.fragment_offset = inodep->offset; -+ SQUASHFS_I(i)->start_block = inodep->start_block; -+ SQUASHFS_I(i)->u.s1.block_list_start = next_block; -+ SQUASHFS_I(i)->offset = next_offset; -+ if (sblk->block_size > 4096) -+ i->i_data.a_ops = &squashfs_aops; -+ else -+ i->i_data.a_ops = &squashfs_aops_4K; -+ -+ TRACE("File inode %x:%x, start_block %llx, " -+ "block_list_start %llx, offset %x\n", -+ SQUASHFS_INODE_BLK(inode), offset, -+ inodep->start_block, next_block, -+ next_offset); -+ break; -+ } -+ case SQUASHFS_LREG_TYPE: { -+ unsigned int frag_size; -+ long long frag_blk; -+ struct squashfs_lreg_inode_header *inodep = &id.lreg; -+ struct squashfs_lreg_inode_header *sinodep = &sid.lreg; -+ -+ if (msblk->swap) { -+ if (!squashfs_get_cached_block(s, (char *) -+ sinodep, block, offset, -+ sizeof(*sinodep), &next_block, -+ &next_offset)) -+ goto failed_read; -+ SQUASHFS_SWAP_LREG_INODE_HEADER(inodep, sinodep); -+ } else -+ if (!squashfs_get_cached_block(s, (char *) -+ inodep, block, offset, -+ sizeof(*inodep), &next_block, -+ &next_offset)) -+ goto failed_read; -+ -+ frag_blk = SQUASHFS_INVALID_BLK; -+ if (inodep->fragment != SQUASHFS_INVALID_FRAG && -+ !get_fragment_location(s, -+ inodep->fragment, &frag_blk, &frag_size)) -+ goto failed_read; -+ -+ if((i = squashfs_new_inode(s, inodeb)) == NULL) -+ goto failed_read1; -+ -+ i->i_nlink = inodep->nlink; -+ i->i_size = inodep->file_size; -+ i->i_fop = &generic_ro_fops; -+ i->i_mode |= S_IFREG; -+ i->i_blocks = ((i->i_size - 1) >> 9) + 1; -+ SQUASHFS_I(i)->u.s1.fragment_start_block = frag_blk; -+ SQUASHFS_I(i)->u.s1.fragment_size = frag_size; -+ SQUASHFS_I(i)->u.s1.fragment_offset = inodep->offset; -+ SQUASHFS_I(i)->start_block = inodep->start_block; -+ SQUASHFS_I(i)->u.s1.block_list_start = next_block; -+ SQUASHFS_I(i)->offset = next_offset; -+ if (sblk->block_size > 4096) -+ i->i_data.a_ops = &squashfs_aops; -+ else -+ i->i_data.a_ops = &squashfs_aops_4K; -+ -+ TRACE("File inode %x:%x, start_block %llx, " -+ "block_list_start %llx, offset %x\n", -+ SQUASHFS_INODE_BLK(inode), offset, -+ inodep->start_block, next_block, -+ next_offset); -+ break; -+ } -+ case SQUASHFS_DIR_TYPE: { -+ struct squashfs_dir_inode_header *inodep = &id.dir; -+ struct squashfs_dir_inode_header *sinodep = &sid.dir; -+ -+ if (msblk->swap) { -+ if (!squashfs_get_cached_block(s, (char *) -+ sinodep, block, offset, -+ sizeof(*sinodep), &next_block, -+ &next_offset)) -+ goto failed_read; -+ SQUASHFS_SWAP_DIR_INODE_HEADER(inodep, sinodep); -+ } else -+ if (!squashfs_get_cached_block(s, (char *) -+ inodep, block, offset, -+ sizeof(*inodep), &next_block, -+ &next_offset)) -+ goto failed_read; -+ -+ if((i = squashfs_new_inode(s, inodeb)) == NULL) -+ goto failed_read1; -+ -+ i->i_nlink = inodep->nlink; -+ i->i_size = inodep->file_size; -+ i->i_op = &squashfs_dir_inode_ops; -+ i->i_fop = &squashfs_dir_ops; -+ i->i_mode |= S_IFDIR; -+ SQUASHFS_I(i)->start_block = inodep->start_block; -+ SQUASHFS_I(i)->offset = inodep->offset; -+ SQUASHFS_I(i)->u.s2.directory_index_count = 0; -+ SQUASHFS_I(i)->u.s2.parent_inode = inodep->parent_inode; -+ -+ TRACE("Directory inode %x:%x, start_block %x, offset " -+ "%x\n", SQUASHFS_INODE_BLK(inode), -+ offset, inodep->start_block, -+ inodep->offset); -+ break; -+ } -+ case SQUASHFS_LDIR_TYPE: { -+ struct squashfs_ldir_inode_header *inodep = &id.ldir; -+ struct squashfs_ldir_inode_header *sinodep = &sid.ldir; -+ -+ if (msblk->swap) { -+ if (!squashfs_get_cached_block(s, (char *) -+ sinodep, block, offset, -+ sizeof(*sinodep), &next_block, -+ &next_offset)) -+ goto failed_read; -+ SQUASHFS_SWAP_LDIR_INODE_HEADER(inodep, -+ sinodep); -+ } else -+ if (!squashfs_get_cached_block(s, (char *) -+ inodep, block, offset, -+ sizeof(*inodep), &next_block, -+ &next_offset)) -+ goto failed_read; -+ -+ if((i = squashfs_new_inode(s, inodeb)) == NULL) -+ goto failed_read1; -+ -+ i->i_nlink = inodep->nlink; -+ i->i_size = inodep->file_size; -+ i->i_op = &squashfs_dir_inode_ops; -+ i->i_fop = &squashfs_dir_ops; -+ i->i_mode |= S_IFDIR; -+ SQUASHFS_I(i)->start_block = inodep->start_block; -+ SQUASHFS_I(i)->offset = inodep->offset; -+ SQUASHFS_I(i)->u.s2.directory_index_start = next_block; -+ SQUASHFS_I(i)->u.s2.directory_index_offset = -+ next_offset; -+ SQUASHFS_I(i)->u.s2.directory_index_count = -+ inodep->i_count; -+ SQUASHFS_I(i)->u.s2.parent_inode = inodep->parent_inode; -+ -+ TRACE("Long directory inode %x:%x, start_block %x, " -+ "offset %x\n", -+ SQUASHFS_INODE_BLK(inode), offset, -+ inodep->start_block, inodep->offset); -+ break; -+ } -+ case SQUASHFS_SYMLINK_TYPE: { -+ struct squashfs_symlink_inode_header *inodep = -+ &id.symlink; -+ struct squashfs_symlink_inode_header *sinodep = -+ &sid.symlink; -+ -+ if (msblk->swap) { -+ if (!squashfs_get_cached_block(s, (char *) -+ sinodep, block, offset, -+ sizeof(*sinodep), &next_block, -+ &next_offset)) -+ goto failed_read; -+ SQUASHFS_SWAP_SYMLINK_INODE_HEADER(inodep, -+ sinodep); -+ } else -+ if (!squashfs_get_cached_block(s, (char *) -+ inodep, block, offset, -+ sizeof(*inodep), &next_block, -+ &next_offset)) -+ goto failed_read; -+ -+ if((i = squashfs_new_inode(s, inodeb)) == NULL) -+ goto failed_read1; -+ -+ i->i_nlink = inodep->nlink; -+ i->i_size = inodep->symlink_size; -+ i->i_op = &page_symlink_inode_operations; -+ i->i_data.a_ops = &squashfs_symlink_aops; -+ i->i_mode |= S_IFLNK; -+ SQUASHFS_I(i)->start_block = next_block; -+ SQUASHFS_I(i)->offset = next_offset; -+ -+ TRACE("Symbolic link inode %x:%x, start_block %llx, " -+ "offset %x\n", -+ SQUASHFS_INODE_BLK(inode), offset, -+ next_block, next_offset); -+ break; -+ } -+ case SQUASHFS_BLKDEV_TYPE: -+ case SQUASHFS_CHRDEV_TYPE: { -+ struct squashfs_dev_inode_header *inodep = &id.dev; -+ struct squashfs_dev_inode_header *sinodep = &sid.dev; -+ -+ if (msblk->swap) { -+ if (!squashfs_get_cached_block(s, (char *) -+ sinodep, block, offset, -+ sizeof(*sinodep), &next_block, -+ &next_offset)) -+ goto failed_read; -+ SQUASHFS_SWAP_DEV_INODE_HEADER(inodep, sinodep); -+ } else -+ if (!squashfs_get_cached_block(s, (char *) -+ inodep, block, offset, -+ sizeof(*inodep), &next_block, -+ &next_offset)) -+ goto failed_read; -+ -+ if ((i = squashfs_new_inode(s, inodeb)) == NULL) -+ goto failed_read1; -+ -+ i->i_nlink = inodep->nlink; -+ i->i_mode |= (inodeb->inode_type == -+ SQUASHFS_CHRDEV_TYPE) ? S_IFCHR : -+ S_IFBLK; -+ init_special_inode(i, i->i_mode, -+ old_decode_dev(inodep->rdev)); -+ -+ TRACE("Device inode %x:%x, rdev %x\n", -+ SQUASHFS_INODE_BLK(inode), offset, -+ inodep->rdev); -+ break; -+ } -+ case SQUASHFS_FIFO_TYPE: -+ case SQUASHFS_SOCKET_TYPE: { -+ struct squashfs_ipc_inode_header *inodep = &id.ipc; -+ struct squashfs_ipc_inode_header *sinodep = &sid.ipc; -+ -+ if (msblk->swap) { -+ if (!squashfs_get_cached_block(s, (char *) -+ sinodep, block, offset, -+ sizeof(*sinodep), &next_block, -+ &next_offset)) -+ goto failed_read; -+ SQUASHFS_SWAP_IPC_INODE_HEADER(inodep, sinodep); -+ } else -+ if (!squashfs_get_cached_block(s, (char *) -+ inodep, block, offset, -+ sizeof(*inodep), &next_block, -+ &next_offset)) -+ goto failed_read; -+ -+ if ((i = squashfs_new_inode(s, inodeb)) == NULL) -+ goto failed_read1; -+ -+ i->i_nlink = inodep->nlink; -+ i->i_mode |= (inodeb->inode_type == SQUASHFS_FIFO_TYPE) -+ ? S_IFIFO : S_IFSOCK; -+ init_special_inode(i, i->i_mode, 0); -+ break; -+ } -+ default: -+ ERROR("Unknown inode type %d in squashfs_iget!\n", -+ inodeb->inode_type); -+ goto failed_read1; -+ } -+ -+ insert_inode_hash(i); -+ return i; -+ -+failed_read: -+ ERROR("Unable to read inode [%llx:%x]\n", block, offset); -+ -+failed_read1: -+ return NULL; -+} -+ -+ -+static int read_fragment_index_table(struct super_block *s) -+{ -+ struct squashfs_sb_info *msblk = s->s_fs_info; -+ struct squashfs_super_block *sblk = &msblk->sblk; -+ -+ /* Allocate fragment index table */ -+ if (!(msblk->fragment_index = kmalloc(SQUASHFS_FRAGMENT_INDEX_BYTES -+ (sblk->fragments), GFP_KERNEL))) { -+ ERROR("Failed to allocate uid/gid table\n"); -+ return 0; -+ } -+ -+ if (SQUASHFS_FRAGMENT_INDEX_BYTES(sblk->fragments) && -+ !squashfs_read_data(s, (char *) -+ msblk->fragment_index, -+ sblk->fragment_table_start, -+ SQUASHFS_FRAGMENT_INDEX_BYTES -+ (sblk->fragments) | -+ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL)) { -+ ERROR("unable to read fragment index table\n"); -+ return 0; -+ } -+ -+ if (msblk->swap) { -+ int i; -+ long long fragment; -+ -+ for (i = 0; i < SQUASHFS_FRAGMENT_INDEXES(sblk->fragments); -+ i++) { -+ SQUASHFS_SWAP_FRAGMENT_INDEXES((&fragment), -+ &msblk->fragment_index[i], 1); -+ msblk->fragment_index[i] = fragment; -+ } -+ } -+ -+ return 1; -+} -+ -+ -+static int supported_squashfs_filesystem(struct squashfs_sb_info *msblk, int silent) -+{ -+ struct squashfs_super_block *sblk = &msblk->sblk; -+ -+ msblk->iget = squashfs_iget; -+ msblk->read_blocklist = read_blocklist; -+ msblk->read_fragment_index_table = read_fragment_index_table; -+ -+ if (sblk->s_major == 1) { -+ if (!squashfs_1_0_supported(msblk)) { -+ SERROR("Major/Minor mismatch, Squashfs 1.0 filesystems " -+ "are unsupported\n"); -+ SERROR("Please recompile with " -+ "Squashfs 1.0 support enabled\n"); -+ return 0; -+ } -+ } else if (sblk->s_major == 2) { -+ if (!squashfs_2_0_supported(msblk)) { -+ SERROR("Major/Minor mismatch, Squashfs 2.0 filesystems " -+ "are unsupported\n"); -+ SERROR("Please recompile with " -+ "Squashfs 2.0 support enabled\n"); -+ return 0; -+ } -+ } else if(sblk->s_major != SQUASHFS_MAJOR || sblk->s_minor > -+ SQUASHFS_MINOR) { -+ SERROR("Major/Minor mismatch, trying to mount newer %d.%d " -+ "filesystem\n", sblk->s_major, sblk->s_minor); -+ SERROR("Please update your kernel\n"); -+ return 0; -+ } -+ -+ return 1; -+} -+ -+ -+static int squashfs_fill_super(struct super_block *s, void *data, int silent) -+{ -+ struct squashfs_sb_info *msblk; -+ struct squashfs_super_block *sblk; -+ int i; -+ char b[BDEVNAME_SIZE]; -+ struct inode *root; -+ -+ TRACE("Entered squashfs_read_superblock\n"); -+ -+ if (!(s->s_fs_info = kmalloc(sizeof(struct squashfs_sb_info), -+ GFP_KERNEL))) { -+ ERROR("Failed to allocate superblock\n"); -+ goto failure; -+ } -+ memset(s->s_fs_info, 0, sizeof(struct squashfs_sb_info)); -+ msblk = s->s_fs_info; -+ sblk = &msblk->sblk; -+ -+ msblk->devblksize = sb_min_blocksize(s, BLOCK_SIZE); -+ msblk->devblksize_log2 = ffz(~msblk->devblksize); -+ -+ init_MUTEX(&msblk->read_data_mutex); -+ init_MUTEX(&msblk->read_page_mutex); -+ init_MUTEX(&msblk->block_cache_mutex); -+ init_MUTEX(&msblk->fragment_mutex); -+ init_MUTEX(&msblk->meta_index_mutex); -+ -+ init_waitqueue_head(&msblk->waitq); -+ init_waitqueue_head(&msblk->fragment_wait_queue); -+ -+ if (!squashfs_read_data(s, (char *) sblk, SQUASHFS_START, -+ sizeof(struct squashfs_super_block) | -+ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL)) { -+ SERROR("unable to read superblock\n"); -+ goto failed_mount; -+ } -+ -+ /* Check it is a SQUASHFS superblock */ -+ msblk->swap = 0; -+ if ((s->s_magic = sblk->s_magic) != SQUASHFS_MAGIC) { -+ if (sblk->s_magic == SQUASHFS_MAGIC_SWAP) { -+ struct squashfs_super_block ssblk; -+ -+ WARNING("Mounting a different endian SQUASHFS " -+ "filesystem on %s\n", bdevname(s->s_bdev, b)); -+ -+ SQUASHFS_SWAP_SUPER_BLOCK(&ssblk, sblk); -+ memcpy(sblk, &ssblk, sizeof(struct squashfs_super_block)); -+ msblk->swap = 1; -+ } else { -+ SERROR("Can't find a SQUASHFS superblock on %s\n", -+ bdevname(s->s_bdev, b)); -+ goto failed_mount; -+ } -+ } -+ -+ /* Check the MAJOR & MINOR versions */ -+ if(!supported_squashfs_filesystem(msblk, silent)) -+ goto failed_mount; -+ -+ TRACE("Found valid superblock on %s\n", bdevname(s->s_bdev, b)); -+ TRACE("Inodes are %scompressed\n", -+ SQUASHFS_UNCOMPRESSED_INODES -+ (sblk->flags) ? "un" : ""); -+ TRACE("Data is %scompressed\n", -+ SQUASHFS_UNCOMPRESSED_DATA(sblk->flags) -+ ? "un" : ""); -+ TRACE("Check data is %s present in the filesystem\n", -+ SQUASHFS_CHECK_DATA(sblk->flags) ? -+ "" : "not"); -+ TRACE("Filesystem size %lld bytes\n", sblk->bytes_used); -+ TRACE("Block size %d\n", sblk->block_size); -+ TRACE("Number of inodes %d\n", sblk->inodes); -+ if (sblk->s_major > 1) -+ TRACE("Number of fragments %d\n", sblk->fragments); -+ TRACE("Number of uids %d\n", sblk->no_uids); -+ TRACE("Number of gids %d\n", sblk->no_guids); -+ TRACE("sblk->inode_table_start %llx\n", sblk->inode_table_start); -+ TRACE("sblk->directory_table_start %llx\n", sblk->directory_table_start); -+ if (sblk->s_major > 1) -+ TRACE("sblk->fragment_table_start %llx\n", -+ sblk->fragment_table_start); -+ TRACE("sblk->uid_start %llx\n", sblk->uid_start); -+ -+ s->s_flags |= MS_RDONLY; -+ s->s_op = &squashfs_ops; -+ -+ /* Init inode_table block pointer array */ -+ if (!(msblk->block_cache = kmalloc(sizeof(struct squashfs_cache) * -+ SQUASHFS_CACHED_BLKS, GFP_KERNEL))) { -+ ERROR("Failed to allocate block cache\n"); -+ goto failed_mount; -+ } -+ -+ for (i = 0; i < SQUASHFS_CACHED_BLKS; i++) -+ msblk->block_cache[i].block = SQUASHFS_INVALID_BLK; -+ -+ msblk->next_cache = 0; -+ -+ /* Allocate read_data block */ -+ msblk->read_size = (sblk->block_size < SQUASHFS_METADATA_SIZE) ? -+ SQUASHFS_METADATA_SIZE : -+ sblk->block_size; -+ -+ if (!(msblk->read_data = kmalloc(msblk->read_size, GFP_KERNEL))) { -+ ERROR("Failed to allocate read_data block\n"); -+ goto failed_mount; -+ } -+ -+ /* Allocate read_page block */ -+ if (!(msblk->read_page = kmalloc(sblk->block_size, GFP_KERNEL))) { -+ ERROR("Failed to allocate read_page block\n"); -+ goto failed_mount; -+ } -+ -+ /* Allocate uid and gid tables */ -+ if (!(msblk->uid = kmalloc((sblk->no_uids + sblk->no_guids) * -+ sizeof(unsigned int), GFP_KERNEL))) { -+ ERROR("Failed to allocate uid/gid table\n"); -+ goto failed_mount; -+ } -+ msblk->guid = msblk->uid + sblk->no_uids; -+ -+ if (msblk->swap) { -+ unsigned int suid[sblk->no_uids + sblk->no_guids]; -+ -+ if (!squashfs_read_data(s, (char *) &suid, sblk->uid_start, -+ ((sblk->no_uids + sblk->no_guids) * -+ sizeof(unsigned int)) | -+ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL)) { -+ ERROR("unable to read uid/gid table\n"); -+ goto failed_mount; -+ } -+ -+ SQUASHFS_SWAP_DATA(msblk->uid, suid, (sblk->no_uids + -+ sblk->no_guids), (sizeof(unsigned int) * 8)); -+ } else -+ if (!squashfs_read_data(s, (char *) msblk->uid, sblk->uid_start, -+ ((sblk->no_uids + sblk->no_guids) * -+ sizeof(unsigned int)) | -+ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL)) { -+ ERROR("unable to read uid/gid table\n"); -+ goto failed_mount; -+ } -+ -+ -+ if (sblk->s_major == 1 && squashfs_1_0_supported(msblk)) -+ goto allocate_root; -+ -+ if (!(msblk->fragment = kmalloc(sizeof(struct squashfs_fragment_cache) * -+ SQUASHFS_CACHED_FRAGMENTS, GFP_KERNEL))) { -+ ERROR("Failed to allocate fragment block cache\n"); -+ goto failed_mount; -+ } -+ -+ for (i = 0; i < SQUASHFS_CACHED_FRAGMENTS; i++) { -+ msblk->fragment[i].locked = 0; -+ msblk->fragment[i].block = SQUASHFS_INVALID_BLK; -+ msblk->fragment[i].data = NULL; -+ } -+ -+ msblk->next_fragment = 0; -+ -+ /* Allocate fragment index table */ -+ if (msblk->read_fragment_index_table(s) == 0) -+ goto failed_mount; -+ -+allocate_root: -+ if ((root = (msblk->iget)(s, sblk->root_inode)) == NULL) -+ goto failed_mount; -+ -+ if ((s->s_root = d_alloc_root(root)) == NULL) { -+ ERROR("Root inode create failed\n"); -+ iput(root); -+ goto failed_mount; -+ } -+ -+ TRACE("Leaving squashfs_read_super\n"); -+ return 0; -+ -+failed_mount: -+ kfree(msblk->fragment_index); -+ kfree(msblk->fragment); -+ kfree(msblk->uid); -+ kfree(msblk->read_page); -+ kfree(msblk->read_data); -+ kfree(msblk->block_cache); -+ kfree(msblk->fragment_index_2); -+ kfree(s->s_fs_info); -+ s->s_fs_info = NULL; -+ return -EINVAL; -+ -+failure: -+ return -ENOMEM; -+} -+ -+ -+static int squashfs_statfs(struct dentry *dentry, struct kstatfs *buf) -+{ -+ struct squashfs_sb_info *msblk = dentry->d_inode->i_sb->s_fs_info; -+ struct squashfs_super_block *sblk = &msblk->sblk; -+ -+ TRACE("Entered squashfs_statfs\n"); -+ -+ buf->f_type = SQUASHFS_MAGIC; -+ buf->f_bsize = sblk->block_size; -+ buf->f_blocks = ((sblk->bytes_used - 1) >> sblk->block_log) + 1; -+ buf->f_bfree = buf->f_bavail = 0; -+ buf->f_files = sblk->inodes; -+ buf->f_ffree = 0; -+ buf->f_namelen = SQUASHFS_NAME_LEN; -+ -+ return 0; -+} -+ -+ -+static int squashfs_symlink_readpage(struct file *file, struct page *page) -+{ -+ struct inode *inode = page->mapping->host; -+ int index = page->index << PAGE_CACHE_SHIFT, length, bytes; -+ long long block = SQUASHFS_I(inode)->start_block; -+ int offset = SQUASHFS_I(inode)->offset; -+ void *pageaddr = kmap(page); -+ -+ TRACE("Entered squashfs_symlink_readpage, page index %ld, start block " -+ "%llx, offset %x\n", page->index, -+ SQUASHFS_I(inode)->start_block, -+ SQUASHFS_I(inode)->offset); -+ -+ for (length = 0; length < index; length += bytes) { -+ if (!(bytes = squashfs_get_cached_block(inode->i_sb, NULL, -+ block, offset, PAGE_CACHE_SIZE, &block, -+ &offset))) { -+ ERROR("Unable to read symbolic link [%llx:%x]\n", block, -+ offset); -+ goto skip_read; -+ } -+ } -+ -+ if (length != index) { -+ ERROR("(squashfs_symlink_readpage) length != index\n"); -+ bytes = 0; -+ goto skip_read; -+ } -+ -+ bytes = (i_size_read(inode) - length) > PAGE_CACHE_SIZE ? PAGE_CACHE_SIZE : -+ i_size_read(inode) - length; -+ -+ if (!(bytes = squashfs_get_cached_block(inode->i_sb, pageaddr, block, -+ offset, bytes, &block, &offset))) -+ ERROR("Unable to read symbolic link [%llx:%x]\n", block, offset); -+ -+skip_read: -+ memset(pageaddr + bytes, 0, PAGE_CACHE_SIZE - bytes); -+ kunmap(page); -+ SetPageUptodate(page); -+ unlock_page(page); -+ -+ return 0; -+} -+ -+ -+struct meta_index *locate_meta_index(struct inode *inode, int index, int offset) -+{ -+ struct meta_index *meta = NULL; -+ struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info; -+ int i; -+ -+ down(&msblk->meta_index_mutex); -+ -+ TRACE("locate_meta_index: index %d, offset %d\n", index, offset); -+ -+ if(msblk->meta_index == NULL) -+ goto not_allocated; -+ -+ for (i = 0; i < SQUASHFS_META_NUMBER; i ++) -+ if (msblk->meta_index[i].inode_number == inode->i_ino && -+ msblk->meta_index[i].offset >= offset && -+ msblk->meta_index[i].offset <= index && -+ msblk->meta_index[i].locked == 0) { -+ TRACE("locate_meta_index: entry %d, offset %d\n", i, -+ msblk->meta_index[i].offset); -+ meta = &msblk->meta_index[i]; -+ offset = meta->offset; -+ } -+ -+ if (meta) -+ meta->locked = 1; -+ -+not_allocated: -+ up(&msblk->meta_index_mutex); -+ -+ return meta; -+} -+ -+ -+struct meta_index *empty_meta_index(struct inode *inode, int offset, int skip) -+{ -+ struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info; -+ struct meta_index *meta = NULL; -+ int i; -+ -+ down(&msblk->meta_index_mutex); -+ -+ TRACE("empty_meta_index: offset %d, skip %d\n", offset, skip); -+ -+ if(msblk->meta_index == NULL) { -+ if (!(msblk->meta_index = kmalloc(sizeof(struct meta_index) * -+ SQUASHFS_META_NUMBER, GFP_KERNEL))) { -+ ERROR("Failed to allocate meta_index\n"); -+ goto failed; -+ } -+ for(i = 0; i < SQUASHFS_META_NUMBER; i++) { -+ msblk->meta_index[i].inode_number = 0; -+ msblk->meta_index[i].locked = 0; -+ } -+ msblk->next_meta_index = 0; -+ } -+ -+ for(i = SQUASHFS_META_NUMBER; i && -+ msblk->meta_index[msblk->next_meta_index].locked; i --) -+ msblk->next_meta_index = (msblk->next_meta_index + 1) % -+ SQUASHFS_META_NUMBER; -+ -+ if(i == 0) { -+ TRACE("empty_meta_index: failed!\n"); -+ goto failed; -+ } -+ -+ TRACE("empty_meta_index: returned meta entry %d, %p\n", -+ msblk->next_meta_index, -+ &msblk->meta_index[msblk->next_meta_index]); -+ -+ meta = &msblk->meta_index[msblk->next_meta_index]; -+ msblk->next_meta_index = (msblk->next_meta_index + 1) % -+ SQUASHFS_META_NUMBER; -+ -+ meta->inode_number = inode->i_ino; -+ meta->offset = offset; -+ meta->skip = skip; -+ meta->entries = 0; -+ meta->locked = 1; -+ -+failed: -+ up(&msblk->meta_index_mutex); -+ return meta; -+} -+ -+ -+void release_meta_index(struct inode *inode, struct meta_index *meta) -+{ -+ meta->locked = 0; -+} -+ -+ -+static int read_block_index(struct super_block *s, int blocks, char *block_list, -+ long long *start_block, int *offset) -+{ -+ struct squashfs_sb_info *msblk = s->s_fs_info; -+ unsigned int *block_listp; -+ int block = 0; -+ -+ if (msblk->swap) { -+ char sblock_list[blocks << 2]; -+ -+ if (!squashfs_get_cached_block(s, sblock_list, *start_block, -+ *offset, blocks << 2, start_block, offset)) { -+ ERROR("Unable to read block list [%llx:%x]\n", -+ *start_block, *offset); -+ goto failure; -+ } -+ SQUASHFS_SWAP_INTS(((unsigned int *)block_list), -+ ((unsigned int *)sblock_list), blocks); -+ } else -+ if (!squashfs_get_cached_block(s, block_list, *start_block, -+ *offset, blocks << 2, start_block, offset)) { -+ ERROR("Unable to read block list [%llx:%x]\n", -+ *start_block, *offset); -+ goto failure; -+ } -+ -+ for (block_listp = (unsigned int *) block_list; blocks; -+ block_listp++, blocks --) -+ block += SQUASHFS_COMPRESSED_SIZE_BLOCK(*block_listp); -+ -+ return block; -+ -+failure: -+ return -1; -+} -+ -+ -+#define SIZE 256 -+ -+static inline int calculate_skip(int blocks) { -+ int skip = (blocks - 1) / ((SQUASHFS_SLOTS * SQUASHFS_META_ENTRIES + 1) * SQUASHFS_META_INDEXES); -+ return skip >= 7 ? 7 : skip + 1; -+} -+ -+ -+static int get_meta_index(struct inode *inode, int index, -+ long long *index_block, int *index_offset, -+ long long *data_block, char *block_list) -+{ -+ struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info; -+ struct squashfs_super_block *sblk = &msblk->sblk; -+ int skip = calculate_skip(i_size_read(inode) >> sblk->block_log); -+ int offset = 0; -+ struct meta_index *meta; -+ struct meta_entry *meta_entry; -+ long long cur_index_block = SQUASHFS_I(inode)->u.s1.block_list_start; -+ int cur_offset = SQUASHFS_I(inode)->offset; -+ long long cur_data_block = SQUASHFS_I(inode)->start_block; -+ int i; -+ -+ index /= SQUASHFS_META_INDEXES * skip; -+ -+ while ( offset < index ) { -+ meta = locate_meta_index(inode, index, offset + 1); -+ -+ if (meta == NULL) { -+ if ((meta = empty_meta_index(inode, offset + 1, -+ skip)) == NULL) -+ goto all_done; -+ } else { -+ offset = index < meta->offset + meta->entries ? index : -+ meta->offset + meta->entries - 1; -+ meta_entry = &meta->meta_entry[offset - meta->offset]; -+ cur_index_block = meta_entry->index_block + sblk->inode_table_start; -+ cur_offset = meta_entry->offset; -+ cur_data_block = meta_entry->data_block; -+ TRACE("get_meta_index: offset %d, meta->offset %d, " -+ "meta->entries %d\n", offset, meta->offset, -+ meta->entries); -+ TRACE("get_meta_index: index_block 0x%llx, offset 0x%x" -+ " data_block 0x%llx\n", cur_index_block, -+ cur_offset, cur_data_block); -+ } -+ -+ for (i = meta->offset + meta->entries; i <= index && -+ i < meta->offset + SQUASHFS_META_ENTRIES; i++) { -+ int blocks = skip * SQUASHFS_META_INDEXES; -+ -+ while (blocks) { -+ int block = blocks > (SIZE >> 2) ? (SIZE >> 2) : -+ blocks; -+ int res = read_block_index(inode->i_sb, block, -+ block_list, &cur_index_block, -+ &cur_offset); -+ -+ if (res == -1) -+ goto failed; -+ -+ cur_data_block += res; -+ blocks -= block; -+ } -+ -+ meta_entry = &meta->meta_entry[i - meta->offset]; -+ meta_entry->index_block = cur_index_block - sblk->inode_table_start; -+ meta_entry->offset = cur_offset; -+ meta_entry->data_block = cur_data_block; -+ meta->entries ++; -+ offset ++; -+ } -+ -+ TRACE("get_meta_index: meta->offset %d, meta->entries %d\n", -+ meta->offset, meta->entries); -+ -+ release_meta_index(inode, meta); -+ } -+ -+all_done: -+ *index_block = cur_index_block; -+ *index_offset = cur_offset; -+ *data_block = cur_data_block; -+ -+ return offset * SQUASHFS_META_INDEXES * skip; -+ -+failed: -+ release_meta_index(inode, meta); -+ return -1; -+} -+ -+ -+static long long read_blocklist(struct inode *inode, int index, -+ int readahead_blks, char *block_list, -+ unsigned short **block_p, unsigned int *bsize) -+{ -+ long long block_ptr; -+ int offset; -+ long long block; -+ int res = get_meta_index(inode, index, &block_ptr, &offset, &block, -+ block_list); -+ -+ TRACE("read_blocklist: res %d, index %d, block_ptr 0x%llx, offset" -+ " 0x%x, block 0x%llx\n", res, index, block_ptr, offset, -+ block); -+ -+ if(res == -1) -+ goto failure; -+ -+ index -= res; -+ -+ while ( index ) { -+ int blocks = index > (SIZE >> 2) ? (SIZE >> 2) : index; -+ int res = read_block_index(inode->i_sb, blocks, block_list, -+ &block_ptr, &offset); -+ if (res == -1) -+ goto failure; -+ block += res; -+ index -= blocks; -+ } -+ -+ if (read_block_index(inode->i_sb, 1, block_list, -+ &block_ptr, &offset) == -1) -+ goto failure; -+ *bsize = *((unsigned int *) block_list); -+ -+ return block; -+ -+failure: -+ return 0; -+} -+ -+ -+static int squashfs_readpage(struct file *file, struct page *page) -+{ -+ struct inode *inode = page->mapping->host; -+ struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info; -+ struct squashfs_super_block *sblk = &msblk->sblk; -+ unsigned char block_list[SIZE]; -+ long long block; -+ unsigned int bsize, i = 0, bytes = 0, byte_offset = 0; -+ int index = page->index >> (sblk->block_log - PAGE_CACHE_SHIFT); -+ void *pageaddr; -+ struct squashfs_fragment_cache *fragment = NULL; -+ char *data_ptr = msblk->read_page; -+ -+ int mask = (1 << (sblk->block_log - PAGE_CACHE_SHIFT)) - 1; -+ int start_index = page->index & ~mask; -+ int end_index = start_index | mask; -+ -+ TRACE("Entered squashfs_readpage, page index %lx, start block %llx\n", -+ page->index, -+ SQUASHFS_I(inode)->start_block); -+ -+ if (page->index >= ((i_size_read(inode) + PAGE_CACHE_SIZE - 1) >> -+ PAGE_CACHE_SHIFT)) -+ goto skip_read; -+ -+ if (SQUASHFS_I(inode)->u.s1.fragment_start_block == SQUASHFS_INVALID_BLK -+ || index < (i_size_read(inode) >> -+ sblk->block_log)) { -+ if ((block = (msblk->read_blocklist)(inode, index, 1, -+ block_list, NULL, &bsize)) == 0) -+ goto skip_read; -+ -+ down(&msblk->read_page_mutex); -+ -+ if (!(bytes = squashfs_read_data(inode->i_sb, msblk->read_page, -+ block, bsize, NULL))) { -+ ERROR("Unable to read page, block %llx, size %x\n", block, -+ bsize); -+ up(&msblk->read_page_mutex); -+ goto skip_read; -+ } -+ } else { -+ if ((fragment = get_cached_fragment(inode->i_sb, -+ SQUASHFS_I(inode)-> -+ u.s1.fragment_start_block, -+ SQUASHFS_I(inode)->u.s1.fragment_size)) -+ == NULL) { -+ ERROR("Unable to read page, block %llx, size %x\n", -+ SQUASHFS_I(inode)-> -+ u.s1.fragment_start_block, -+ (int) SQUASHFS_I(inode)-> -+ u.s1.fragment_size); -+ goto skip_read; -+ } -+ bytes = SQUASHFS_I(inode)->u.s1.fragment_offset + -+ (i_size_read(inode) & (sblk->block_size -+ - 1)); -+ byte_offset = SQUASHFS_I(inode)->u.s1.fragment_offset; -+ data_ptr = fragment->data; -+ } -+ -+ for (i = start_index; i <= end_index && byte_offset < bytes; -+ i++, byte_offset += PAGE_CACHE_SIZE) { -+ struct page *push_page; -+ int available_bytes = (bytes - byte_offset) > PAGE_CACHE_SIZE ? -+ PAGE_CACHE_SIZE : bytes - byte_offset; -+ -+ TRACE("bytes %d, i %d, byte_offset %d, available_bytes %d\n", -+ bytes, i, byte_offset, available_bytes); -+ -+ if (i == page->index) { -+ pageaddr = kmap_atomic(page, KM_USER0); -+ memcpy(pageaddr, data_ptr + byte_offset, -+ available_bytes); -+ memset(pageaddr + available_bytes, 0, -+ PAGE_CACHE_SIZE - available_bytes); -+ kunmap_atomic(pageaddr, KM_USER0); -+ flush_dcache_page(page); -+ SetPageUptodate(page); -+ unlock_page(page); -+ } else if ((push_page = -+ grab_cache_page_nowait(page->mapping, i))) { -+ pageaddr = kmap_atomic(push_page, KM_USER0); -+ -+ memcpy(pageaddr, data_ptr + byte_offset, -+ available_bytes); -+ memset(pageaddr + available_bytes, 0, -+ PAGE_CACHE_SIZE - available_bytes); -+ kunmap_atomic(pageaddr, KM_USER0); -+ flush_dcache_page(push_page); -+ SetPageUptodate(push_page); -+ unlock_page(push_page); -+ page_cache_release(push_page); -+ } -+ } -+ -+ if (SQUASHFS_I(inode)->u.s1.fragment_start_block == SQUASHFS_INVALID_BLK -+ || index < (i_size_read(inode) >> -+ sblk->block_log)) -+ up(&msblk->read_page_mutex); -+ else -+ release_cached_fragment(msblk, fragment); -+ -+ return 0; -+ -+skip_read: -+ pageaddr = kmap_atomic(page, KM_USER0); -+ memset(pageaddr + bytes, 0, PAGE_CACHE_SIZE - bytes); -+ kunmap_atomic(pageaddr, KM_USER0); -+ flush_dcache_page(page); -+ SetPageUptodate(page); -+ unlock_page(page); -+ -+ return 0; -+} -+ -+ -+static int squashfs_readpage4K(struct file *file, struct page *page) -+{ -+ struct inode *inode = page->mapping->host; -+ struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info; -+ struct squashfs_super_block *sblk = &msblk->sblk; -+ unsigned char block_list[SIZE]; -+ long long block; -+ unsigned int bsize, bytes = 0; -+ void *pageaddr; -+ -+ TRACE("Entered squashfs_readpage4K, page index %lx, start block %llx\n", -+ page->index, -+ SQUASHFS_I(inode)->start_block); -+ -+ if (page->index >= ((i_size_read(inode) + PAGE_CACHE_SIZE - 1) >> -+ PAGE_CACHE_SHIFT)) { -+ pageaddr = kmap_atomic(page, KM_USER0); -+ goto skip_read; -+ } -+ -+ if (SQUASHFS_I(inode)->u.s1.fragment_start_block == SQUASHFS_INVALID_BLK -+ || page->index < (i_size_read(inode) >> -+ sblk->block_log)) { -+ block = (msblk->read_blocklist)(inode, page->index, 1, -+ block_list, NULL, &bsize); -+ -+ down(&msblk->read_page_mutex); -+ bytes = squashfs_read_data(inode->i_sb, msblk->read_page, block, -+ bsize, NULL); -+ pageaddr = kmap_atomic(page, KM_USER0); -+ if (bytes) -+ memcpy(pageaddr, msblk->read_page, bytes); -+ else -+ ERROR("Unable to read page, block %llx, size %x\n", -+ block, bsize); -+ up(&msblk->read_page_mutex); -+ } else { -+ struct squashfs_fragment_cache *fragment = -+ get_cached_fragment(inode->i_sb, -+ SQUASHFS_I(inode)-> -+ u.s1.fragment_start_block, -+ SQUASHFS_I(inode)-> u.s1.fragment_size); -+ pageaddr = kmap_atomic(page, KM_USER0); -+ if (fragment) { -+ bytes = i_size_read(inode) & (sblk->block_size - 1); -+ memcpy(pageaddr, fragment->data + SQUASHFS_I(inode)-> -+ u.s1.fragment_offset, bytes); -+ release_cached_fragment(msblk, fragment); -+ } else -+ ERROR("Unable to read page, block %llx, size %x\n", -+ SQUASHFS_I(inode)-> -+ u.s1.fragment_start_block, (int) -+ SQUASHFS_I(inode)-> u.s1.fragment_size); -+ } -+ -+skip_read: -+ memset(pageaddr + bytes, 0, PAGE_CACHE_SIZE - bytes); -+ kunmap_atomic(pageaddr, KM_USER0); -+ flush_dcache_page(page); -+ SetPageUptodate(page); -+ unlock_page(page); -+ -+ return 0; -+} -+ -+ -+static int get_dir_index_using_offset(struct super_block *s, long long -+ *next_block, unsigned int *next_offset, -+ long long index_start, -+ unsigned int index_offset, int i_count, -+ long long f_pos) -+{ -+ struct squashfs_sb_info *msblk = s->s_fs_info; -+ struct squashfs_super_block *sblk = &msblk->sblk; -+ int i, length = 0; -+ struct squashfs_dir_index index; -+ -+ TRACE("Entered get_dir_index_using_offset, i_count %d, f_pos %d\n", -+ i_count, (unsigned int) f_pos); -+ -+ f_pos =- 3; -+ if (f_pos == 0) -+ goto finish; -+ -+ for (i = 0; i < i_count; i++) { -+ if (msblk->swap) { -+ struct squashfs_dir_index sindex; -+ squashfs_get_cached_block(s, (char *) &sindex, -+ index_start, index_offset, -+ sizeof(sindex), &index_start, -+ &index_offset); -+ SQUASHFS_SWAP_DIR_INDEX(&index, &sindex); -+ } else -+ squashfs_get_cached_block(s, (char *) &index, -+ index_start, index_offset, -+ sizeof(index), &index_start, -+ &index_offset); -+ -+ if (index.index > f_pos) -+ break; -+ -+ squashfs_get_cached_block(s, NULL, index_start, index_offset, -+ index.size + 1, &index_start, -+ &index_offset); -+ -+ length = index.index; -+ *next_block = index.start_block + sblk->directory_table_start; -+ } -+ -+ *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE; -+ -+finish: -+ return length + 3; -+} -+ -+ -+static int get_dir_index_using_name(struct super_block *s, long long -+ *next_block, unsigned int *next_offset, -+ long long index_start, -+ unsigned int index_offset, int i_count, -+ const char *name, int size) -+{ -+ struct squashfs_sb_info *msblk = s->s_fs_info; -+ struct squashfs_super_block *sblk = &msblk->sblk; -+ int i, length = 0; -+ char buffer[sizeof(struct squashfs_dir_index) + SQUASHFS_NAME_LEN + 1]; -+ struct squashfs_dir_index *index = (struct squashfs_dir_index *) buffer; -+ char str[SQUASHFS_NAME_LEN + 1]; -+ -+ TRACE("Entered get_dir_index_using_name, i_count %d\n", i_count); -+ -+ strncpy(str, name, size); -+ str[size] = '\0'; -+ -+ for (i = 0; i < i_count; i++) { -+ if (msblk->swap) { -+ struct squashfs_dir_index sindex; -+ squashfs_get_cached_block(s, (char *) &sindex, -+ index_start, index_offset, -+ sizeof(sindex), &index_start, -+ &index_offset); -+ SQUASHFS_SWAP_DIR_INDEX(index, &sindex); -+ } else -+ squashfs_get_cached_block(s, (char *) index, -+ index_start, index_offset, -+ sizeof(struct squashfs_dir_index), -+ &index_start, &index_offset); -+ -+ squashfs_get_cached_block(s, index->name, index_start, -+ index_offset, index->size + 1, -+ &index_start, &index_offset); -+ -+ index->name[index->size + 1] = '\0'; -+ -+ if (strcmp(index->name, str) > 0) -+ break; -+ -+ length = index->index; -+ *next_block = index->start_block + sblk->directory_table_start; -+ } -+ -+ *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE; -+ return length + 3; -+} -+ -+ -+static int squashfs_readdir(struct file *file, void *dirent, filldir_t filldir) -+{ -+ struct inode *i = file->f_dentry->d_inode; -+ struct squashfs_sb_info *msblk = i->i_sb->s_fs_info; -+ struct squashfs_super_block *sblk = &msblk->sblk; -+ long long next_block = SQUASHFS_I(i)->start_block + -+ sblk->directory_table_start; -+ int next_offset = SQUASHFS_I(i)->offset, length = 0, dirs_read = 0, -+ dir_count; -+ struct squashfs_dir_header dirh; -+ char buffer[sizeof(struct squashfs_dir_entry) + SQUASHFS_NAME_LEN + 1]; -+ struct squashfs_dir_entry *dire = (struct squashfs_dir_entry *) buffer; -+ -+ TRACE("Entered squashfs_readdir [%llx:%x]\n", next_block, next_offset); -+ -+ while(file->f_pos < 3) { -+ char *name; -+ int size, i_ino; -+ -+ if(file->f_pos == 0) { -+ name = "."; -+ size = 1; -+ i_ino = i->i_ino; -+ } else { -+ name = ".."; -+ size = 2; -+ i_ino = SQUASHFS_I(i)->u.s2.parent_inode; -+ } -+ TRACE("Calling filldir(%x, %s, %d, %d, %d, %d)\n", -+ (unsigned int) dirent, name, size, (int) -+ file->f_pos, i_ino, -+ squashfs_filetype_table[1]); -+ -+ if (filldir(dirent, name, size, -+ file->f_pos, i_ino, -+ squashfs_filetype_table[1]) < 0) { -+ TRACE("Filldir returned less than 0\n"); -+ goto finish; -+ } -+ file->f_pos += size; -+ dirs_read++; -+ } -+ -+ length = get_dir_index_using_offset(i->i_sb, &next_block, &next_offset, -+ SQUASHFS_I(i)->u.s2.directory_index_start, -+ SQUASHFS_I(i)->u.s2.directory_index_offset, -+ SQUASHFS_I(i)->u.s2.directory_index_count, -+ file->f_pos); -+ -+ while (length < i_size_read(i)) { -+ /* read directory header */ -+ if (msblk->swap) { -+ struct squashfs_dir_header sdirh; -+ -+ if (!squashfs_get_cached_block(i->i_sb, (char *) &sdirh, -+ next_block, next_offset, sizeof(sdirh), -+ &next_block, &next_offset)) -+ goto failed_read; -+ -+ length += sizeof(sdirh); -+ SQUASHFS_SWAP_DIR_HEADER(&dirh, &sdirh); -+ } else { -+ if (!squashfs_get_cached_block(i->i_sb, (char *) &dirh, -+ next_block, next_offset, sizeof(dirh), -+ &next_block, &next_offset)) -+ goto failed_read; -+ -+ length += sizeof(dirh); -+ } -+ -+ dir_count = dirh.count + 1; -+ while (dir_count--) { -+ if (msblk->swap) { -+ struct squashfs_dir_entry sdire; -+ if (!squashfs_get_cached_block(i->i_sb, (char *) -+ &sdire, next_block, next_offset, -+ sizeof(sdire), &next_block, -+ &next_offset)) -+ goto failed_read; -+ -+ length += sizeof(sdire); -+ SQUASHFS_SWAP_DIR_ENTRY(dire, &sdire); -+ } else { -+ if (!squashfs_get_cached_block(i->i_sb, (char *) -+ dire, next_block, next_offset, -+ sizeof(*dire), &next_block, -+ &next_offset)) -+ goto failed_read; -+ -+ length += sizeof(*dire); -+ } -+ -+ if (!squashfs_get_cached_block(i->i_sb, dire->name, -+ next_block, next_offset, -+ dire->size + 1, &next_block, -+ &next_offset)) -+ goto failed_read; -+ -+ length += dire->size + 1; -+ -+ if (file->f_pos >= length) -+ continue; -+ -+ dire->name[dire->size + 1] = '\0'; -+ -+ TRACE("Calling filldir(%x, %s, %d, %d, %x:%x, %d, %d)\n", -+ (unsigned int) dirent, dire->name, -+ dire->size + 1, (int) file->f_pos, -+ dirh.start_block, dire->offset, -+ dirh.inode_number + dire->inode_number, -+ squashfs_filetype_table[dire->type]); -+ -+ if (filldir(dirent, dire->name, dire->size + 1, -+ file->f_pos, -+ dirh.inode_number + dire->inode_number, -+ squashfs_filetype_table[dire->type]) -+ < 0) { -+ TRACE("Filldir returned less than 0\n"); -+ goto finish; -+ } -+ file->f_pos = length; -+ dirs_read++; -+ } -+ } -+ -+finish: -+ return dirs_read; -+ -+failed_read: -+ ERROR("Unable to read directory block [%llx:%x]\n", next_block, -+ next_offset); -+ return 0; -+} -+ -+ -+static struct dentry *squashfs_lookup(struct inode *i, struct dentry *dentry, -+ struct nameidata *nd) -+{ -+ const unsigned char *name = dentry->d_name.name; -+ int len = dentry->d_name.len; -+ struct inode *inode = NULL; -+ struct squashfs_sb_info *msblk = i->i_sb->s_fs_info; -+ struct squashfs_super_block *sblk = &msblk->sblk; -+ long long next_block = SQUASHFS_I(i)->start_block + -+ sblk->directory_table_start; -+ int next_offset = SQUASHFS_I(i)->offset, length = 0, -+ dir_count; -+ struct squashfs_dir_header dirh; -+ char buffer[sizeof(struct squashfs_dir_entry) + SQUASHFS_NAME_LEN]; -+ struct squashfs_dir_entry *dire = (struct squashfs_dir_entry *) buffer; -+ -+ TRACE("Entered squashfs_lookup [%llx:%x]\n", next_block, next_offset); -+ -+ if (len > SQUASHFS_NAME_LEN) -+ goto exit_loop; -+ -+ length = get_dir_index_using_name(i->i_sb, &next_block, &next_offset, -+ SQUASHFS_I(i)->u.s2.directory_index_start, -+ SQUASHFS_I(i)->u.s2.directory_index_offset, -+ SQUASHFS_I(i)->u.s2.directory_index_count, name, -+ len); -+ -+ while (length < i_size_read(i)) { -+ /* read directory header */ -+ if (msblk->swap) { -+ struct squashfs_dir_header sdirh; -+ if (!squashfs_get_cached_block(i->i_sb, (char *) &sdirh, -+ next_block, next_offset, sizeof(sdirh), -+ &next_block, &next_offset)) -+ goto failed_read; -+ -+ length += sizeof(sdirh); -+ SQUASHFS_SWAP_DIR_HEADER(&dirh, &sdirh); -+ } else { -+ if (!squashfs_get_cached_block(i->i_sb, (char *) &dirh, -+ next_block, next_offset, sizeof(dirh), -+ &next_block, &next_offset)) -+ goto failed_read; -+ -+ length += sizeof(dirh); -+ } -+ -+ dir_count = dirh.count + 1; -+ while (dir_count--) { -+ if (msblk->swap) { -+ struct squashfs_dir_entry sdire; -+ if (!squashfs_get_cached_block(i->i_sb, (char *) -+ &sdire, next_block,next_offset, -+ sizeof(sdire), &next_block, -+ &next_offset)) -+ goto failed_read; -+ -+ length += sizeof(sdire); -+ SQUASHFS_SWAP_DIR_ENTRY(dire, &sdire); -+ } else { -+ if (!squashfs_get_cached_block(i->i_sb, (char *) -+ dire, next_block,next_offset, -+ sizeof(*dire), &next_block, -+ &next_offset)) -+ goto failed_read; -+ -+ length += sizeof(*dire); -+ } -+ -+ if (!squashfs_get_cached_block(i->i_sb, dire->name, -+ next_block, next_offset, dire->size + 1, -+ &next_block, &next_offset)) -+ goto failed_read; -+ -+ length += dire->size + 1; -+ -+ if (name[0] < dire->name[0]) -+ goto exit_loop; -+ -+ if ((len == dire->size + 1) && !strncmp(name, -+ dire->name, len)) { -+ squashfs_inode_t ino = -+ SQUASHFS_MKINODE(dirh.start_block, -+ dire->offset); -+ -+ TRACE("calling squashfs_iget for directory " -+ "entry %s, inode %x:%x, %d\n", name, -+ dirh.start_block, dire->offset, -+ dirh.inode_number + dire->inode_number); -+ -+ inode = (msblk->iget)(i->i_sb, ino); -+ -+ goto exit_loop; -+ } -+ } -+ } -+ -+exit_loop: -+ d_add(dentry, inode); -+ return ERR_PTR(0); -+ -+failed_read: -+ ERROR("Unable to read directory block [%llx:%x]\n", next_block, -+ next_offset); -+ goto exit_loop; -+} -+ -+ -+static void squashfs_put_super(struct super_block *s) -+{ -+ int i; -+ -+ if (s->s_fs_info) { -+ struct squashfs_sb_info *sbi = s->s_fs_info; -+ if (sbi->block_cache) -+ for (i = 0; i < SQUASHFS_CACHED_BLKS; i++) -+ if (sbi->block_cache[i].block != -+ SQUASHFS_INVALID_BLK) -+ kfree(sbi->block_cache[i].data); -+ if (sbi->fragment) -+ for (i = 0; i < SQUASHFS_CACHED_FRAGMENTS; i++) -+ SQUASHFS_FREE(sbi->fragment[i].data); -+ kfree(sbi->fragment); -+ kfree(sbi->block_cache); -+ kfree(sbi->read_data); -+ kfree(sbi->read_page); -+ kfree(sbi->uid); -+ kfree(sbi->fragment_index); -+ kfree(sbi->fragment_index_2); -+ kfree(sbi->meta_index); -+ kfree(s->s_fs_info); -+ s->s_fs_info = NULL; -+ } -+} -+ -+ -+static int squashfs_get_sb(struct file_system_type *fs_type, -+ int flags, const char *dev_name, void *data, -+ struct vfsmount *mnt) -+{ -+ return get_sb_bdev(fs_type, flags, dev_name, data, squashfs_fill_super, mnt); -+} -+ -+ -+static int __init init_squashfs_fs(void) -+{ -+ int err = init_inodecache(); -+ if (err) -+ goto out; -+ -+ printk(KERN_INFO "squashfs: version 3.0 (2006/03/15) " -+ "Phillip Lougher\n"); -+ -+ if (!(stream.workspace = vmalloc(zlib_inflate_workspacesize()))) { -+ ERROR("Failed to allocate zlib workspace\n"); -+ destroy_inodecache(); -+ err = -ENOMEM; -+ goto out; -+ } -+ -+ if ((err = register_filesystem(&squashfs_fs_type))) { -+ vfree(stream.workspace); -+ destroy_inodecache(); -+ } -+ -+out: -+ return err; -+} -+ -+ -+static void __exit exit_squashfs_fs(void) -+{ -+ vfree(stream.workspace); -+ unregister_filesystem(&squashfs_fs_type); -+ destroy_inodecache(); -+} -+ -+ -+static struct kmem_cache * squashfs_inode_cachep; -+ -+ -+static struct inode *squashfs_alloc_inode(struct super_block *sb) -+{ -+ struct squashfs_inode_info *ei; -+ ei = kmem_cache_alloc(squashfs_inode_cachep, GFP_KERNEL); -+ if (!ei) -+ return NULL; -+ return &ei->vfs_inode; -+} -+ -+ -+static void squashfs_destroy_inode(struct inode *inode) -+{ -+ kmem_cache_free(squashfs_inode_cachep, SQUASHFS_I(inode)); -+} -+ -+ -+static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) -+{ -+ struct squashfs_inode_info *ei = foo; -+ -+ inode_init_once(&ei->vfs_inode); -+} -+ -+ -+static int __init init_inodecache(void) -+{ -+ squashfs_inode_cachep = kmem_cache_create("squashfs_inode_cache", -+ sizeof(struct squashfs_inode_info), -+ 0, SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT, -+ init_once); -+ if (squashfs_inode_cachep == NULL) -+ return -ENOMEM; -+ return 0; -+} -+ -+ -+static void destroy_inodecache(void) -+{ -+ kmem_cache_destroy(squashfs_inode_cachep); -+} -+ -+ -+module_init(init_squashfs_fs); -+module_exit(exit_squashfs_fs); -+MODULE_DESCRIPTION("squashfs, a compressed read-only filesystem"); -+MODULE_AUTHOR("Phillip Lougher "); -+MODULE_LICENSE("GPL"); ---- /dev/null -+++ b/fs/squashfs/Makefile -@@ -0,0 +1,7 @@ -+# -+# Makefile for the linux squashfs routines. -+# -+ -+obj-$(CONFIG_SQUASHFS) += squashfs.o -+squashfs-y += inode.o -+squashfs-y += squashfs2_0.o ---- /dev/null -+++ b/fs/squashfs/squashfs2_0.c -@@ -0,0 +1,758 @@ -+/* -+ * Squashfs - a compressed read only filesystem for Linux -+ * -+ * Copyright (c) 2002, 2003, 2004, 2005, 2006 -+ * Phillip Lougher -+ * -+ * 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, -+ * 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ * -+ * squashfs2_0.c -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "squashfs.h" -+static int squashfs_readdir_2(struct file *file, void *dirent, filldir_t filldir); -+static struct dentry *squashfs_lookup_2(struct inode *, struct dentry *, -+ struct nameidata *); -+ -+static struct file_operations squashfs_dir_ops_2 = { -+ .read = generic_read_dir, -+ .readdir = squashfs_readdir_2 -+}; -+ -+static struct inode_operations squashfs_dir_inode_ops_2 = { -+ .lookup = squashfs_lookup_2 -+}; -+ -+static unsigned char squashfs_filetype_table[] = { -+ DT_UNKNOWN, DT_DIR, DT_REG, DT_LNK, DT_BLK, DT_CHR, DT_FIFO, DT_SOCK -+}; -+ -+static int read_fragment_index_table_2(struct super_block *s) -+{ -+ struct squashfs_sb_info *msblk = s->s_fs_info; -+ struct squashfs_super_block *sblk = &msblk->sblk; -+ -+ if (!(msblk->fragment_index_2 = kmalloc(SQUASHFS_FRAGMENT_INDEX_BYTES_2 -+ (sblk->fragments), GFP_KERNEL))) { -+ ERROR("Failed to allocate uid/gid table\n"); -+ return 0; -+ } -+ -+ if (SQUASHFS_FRAGMENT_INDEX_BYTES_2(sblk->fragments) && -+ !squashfs_read_data(s, (char *) -+ msblk->fragment_index_2, -+ sblk->fragment_table_start, -+ SQUASHFS_FRAGMENT_INDEX_BYTES_2 -+ (sblk->fragments) | -+ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL)) { -+ ERROR("unable to read fragment index table\n"); -+ return 0; -+ } -+ -+ if (msblk->swap) { -+ int i; -+ unsigned int fragment; -+ -+ for (i = 0; i < SQUASHFS_FRAGMENT_INDEXES_2(sblk->fragments); -+ i++) { -+ SQUASHFS_SWAP_FRAGMENT_INDEXES_2((&fragment), -+ &msblk->fragment_index_2[i], 1); -+ msblk->fragment_index_2[i] = fragment; -+ } -+ } -+ -+ return 1; -+} -+ -+ -+static int get_fragment_location_2(struct super_block *s, unsigned int fragment, -+ long long *fragment_start_block, -+ unsigned int *fragment_size) -+{ -+ struct squashfs_sb_info *msblk = s->s_fs_info; -+ long long start_block = -+ msblk->fragment_index_2[SQUASHFS_FRAGMENT_INDEX_2(fragment)]; -+ int offset = SQUASHFS_FRAGMENT_INDEX_OFFSET_2(fragment); -+ struct squashfs_fragment_entry_2 fragment_entry; -+ -+ if (msblk->swap) { -+ struct squashfs_fragment_entry_2 sfragment_entry; -+ -+ if (!squashfs_get_cached_block(s, (char *) &sfragment_entry, -+ start_block, offset, -+ sizeof(sfragment_entry), &start_block, -+ &offset)) -+ goto out; -+ SQUASHFS_SWAP_FRAGMENT_ENTRY_2(&fragment_entry, &sfragment_entry); -+ } else -+ if (!squashfs_get_cached_block(s, (char *) &fragment_entry, -+ start_block, offset, -+ sizeof(fragment_entry), &start_block, -+ &offset)) -+ goto out; -+ -+ *fragment_start_block = fragment_entry.start_block; -+ *fragment_size = fragment_entry.size; -+ -+ return 1; -+ -+out: -+ return 0; -+} -+ -+ -+static struct inode *squashfs_new_inode(struct super_block *s, -+ struct squashfs_base_inode_header_2 *inodeb, unsigned int ino) -+{ -+ struct squashfs_sb_info *msblk = s->s_fs_info; -+ struct squashfs_super_block *sblk = &msblk->sblk; -+ struct inode *i = new_inode(s); -+ -+ if (i) { -+ i->i_ino = ino; -+ i->i_mtime.tv_sec = sblk->mkfs_time; -+ i->i_atime.tv_sec = sblk->mkfs_time; -+ i->i_ctime.tv_sec = sblk->mkfs_time; -+ i->i_uid = msblk->uid[inodeb->uid]; -+ i->i_mode = inodeb->mode; -+ i->i_nlink = 1; -+ i->i_size = 0; -+ if (inodeb->guid == SQUASHFS_GUIDS) -+ i->i_gid = i->i_uid; -+ else -+ i->i_gid = msblk->guid[inodeb->guid]; -+ } -+ -+ return i; -+} -+ -+ -+static struct inode *squashfs_iget_2(struct super_block *s, squashfs_inode_t inode) -+{ -+ struct inode *i; -+ struct squashfs_sb_info *msblk = s->s_fs_info; -+ struct squashfs_super_block *sblk = &msblk->sblk; -+ unsigned int block = SQUASHFS_INODE_BLK(inode) + -+ sblk->inode_table_start; -+ unsigned int offset = SQUASHFS_INODE_OFFSET(inode); -+ unsigned int ino = SQUASHFS_MK_VFS_INODE(block -+ - sblk->inode_table_start, offset); -+ long long next_block; -+ unsigned int next_offset; -+ union squashfs_inode_header_2 id, sid; -+ struct squashfs_base_inode_header_2 *inodeb = &id.base, -+ *sinodeb = &sid.base; -+ -+ TRACE("Entered squashfs_iget\n"); -+ -+ if (msblk->swap) { -+ if (!squashfs_get_cached_block(s, (char *) sinodeb, block, -+ offset, sizeof(*sinodeb), &next_block, -+ &next_offset)) -+ goto failed_read; -+ SQUASHFS_SWAP_BASE_INODE_HEADER_2(inodeb, sinodeb, -+ sizeof(*sinodeb)); -+ } else -+ if (!squashfs_get_cached_block(s, (char *) inodeb, block, -+ offset, sizeof(*inodeb), &next_block, -+ &next_offset)) -+ goto failed_read; -+ -+ switch(inodeb->inode_type) { -+ case SQUASHFS_FILE_TYPE: { -+ struct squashfs_reg_inode_header_2 *inodep = &id.reg; -+ struct squashfs_reg_inode_header_2 *sinodep = &sid.reg; -+ long long frag_blk; -+ unsigned int frag_size; -+ -+ if (msblk->swap) { -+ if (!squashfs_get_cached_block(s, (char *) -+ sinodep, block, offset, -+ sizeof(*sinodep), &next_block, -+ &next_offset)) -+ goto failed_read; -+ SQUASHFS_SWAP_REG_INODE_HEADER_2(inodep, sinodep); -+ } else -+ if (!squashfs_get_cached_block(s, (char *) -+ inodep, block, offset, -+ sizeof(*inodep), &next_block, -+ &next_offset)) -+ goto failed_read; -+ -+ frag_blk = SQUASHFS_INVALID_BLK; -+ if (inodep->fragment != SQUASHFS_INVALID_FRAG && -+ !get_fragment_location_2(s, -+ inodep->fragment, &frag_blk, &frag_size)) -+ goto failed_read; -+ -+ if((i = squashfs_new_inode(s, inodeb, ino)) == NULL) -+ goto failed_read1; -+ -+ i->i_size = inodep->file_size; -+ i->i_fop = &generic_ro_fops; -+ i->i_mode |= S_IFREG; -+ i->i_mtime.tv_sec = inodep->mtime; -+ i->i_atime.tv_sec = inodep->mtime; -+ i->i_ctime.tv_sec = inodep->mtime; -+ i->i_blocks = ((i->i_size - 1) >> 9) + 1; -+ i->i_blksize = PAGE_CACHE_SIZE; -+ SQUASHFS_I(i)->u.s1.fragment_start_block = frag_blk; -+ SQUASHFS_I(i)->u.s1.fragment_size = frag_size; -+ SQUASHFS_I(i)->u.s1.fragment_offset = inodep->offset; -+ SQUASHFS_I(i)->start_block = inodep->start_block; -+ SQUASHFS_I(i)->u.s1.block_list_start = next_block; -+ SQUASHFS_I(i)->offset = next_offset; -+ if (sblk->block_size > 4096) -+ i->i_data.a_ops = &squashfs_aops; -+ else -+ i->i_data.a_ops = &squashfs_aops_4K; -+ -+ TRACE("File inode %x:%x, start_block %x, " -+ "block_list_start %llx, offset %x\n", -+ SQUASHFS_INODE_BLK(inode), offset, -+ inodep->start_block, next_block, -+ next_offset); -+ break; -+ } -+ case SQUASHFS_DIR_TYPE: { -+ struct squashfs_dir_inode_header_2 *inodep = &id.dir; -+ struct squashfs_dir_inode_header_2 *sinodep = &sid.dir; -+ -+ if (msblk->swap) { -+ if (!squashfs_get_cached_block(s, (char *) -+ sinodep, block, offset, -+ sizeof(*sinodep), &next_block, -+ &next_offset)) -+ goto failed_read; -+ SQUASHFS_SWAP_DIR_INODE_HEADER_2(inodep, sinodep); -+ } else -+ if (!squashfs_get_cached_block(s, (char *) -+ inodep, block, offset, -+ sizeof(*inodep), &next_block, -+ &next_offset)) -+ goto failed_read; -+ -+ if((i = squashfs_new_inode(s, inodeb, ino)) == NULL) -+ goto failed_read1; -+ -+ i->i_size = inodep->file_size; -+ i->i_op = &squashfs_dir_inode_ops_2; -+ i->i_fop = &squashfs_dir_ops_2; -+ i->i_mode |= S_IFDIR; -+ i->i_mtime.tv_sec = inodep->mtime; -+ i->i_atime.tv_sec = inodep->mtime; -+ i->i_ctime.tv_sec = inodep->mtime; -+ SQUASHFS_I(i)->start_block = inodep->start_block; -+ SQUASHFS_I(i)->offset = inodep->offset; -+ SQUASHFS_I(i)->u.s2.directory_index_count = 0; -+ SQUASHFS_I(i)->u.s2.parent_inode = 0; -+ -+ TRACE("Directory inode %x:%x, start_block %x, offset " -+ "%x\n", SQUASHFS_INODE_BLK(inode), -+ offset, inodep->start_block, -+ inodep->offset); -+ break; -+ } -+ case SQUASHFS_LDIR_TYPE: { -+ struct squashfs_ldir_inode_header_2 *inodep = &id.ldir; -+ struct squashfs_ldir_inode_header_2 *sinodep = &sid.ldir; -+ -+ if (msblk->swap) { -+ if (!squashfs_get_cached_block(s, (char *) -+ sinodep, block, offset, -+ sizeof(*sinodep), &next_block, -+ &next_offset)) -+ goto failed_read; -+ SQUASHFS_SWAP_LDIR_INODE_HEADER_2(inodep, -+ sinodep); -+ } else -+ if (!squashfs_get_cached_block(s, (char *) -+ inodep, block, offset, -+ sizeof(*inodep), &next_block, -+ &next_offset)) -+ goto failed_read; -+ -+ if((i = squashfs_new_inode(s, inodeb, ino)) == NULL) -+ goto failed_read1; -+ -+ i->i_size = inodep->file_size; -+ i->i_op = &squashfs_dir_inode_ops_2; -+ i->i_fop = &squashfs_dir_ops_2; -+ i->i_mode |= S_IFDIR; -+ i->i_mtime.tv_sec = inodep->mtime; -+ i->i_atime.tv_sec = inodep->mtime; -+ i->i_ctime.tv_sec = inodep->mtime; -+ SQUASHFS_I(i)->start_block = inodep->start_block; -+ SQUASHFS_I(i)->offset = inodep->offset; -+ SQUASHFS_I(i)->u.s2.directory_index_start = next_block; -+ SQUASHFS_I(i)->u.s2.directory_index_offset = -+ next_offset; -+ SQUASHFS_I(i)->u.s2.directory_index_count = -+ inodep->i_count; -+ SQUASHFS_I(i)->u.s2.parent_inode = 0; -+ -+ TRACE("Long directory inode %x:%x, start_block %x, " -+ "offset %x\n", -+ SQUASHFS_INODE_BLK(inode), offset, -+ inodep->start_block, inodep->offset); -+ break; -+ } -+ case SQUASHFS_SYMLINK_TYPE: { -+ struct squashfs_symlink_inode_header_2 *inodep = -+ &id.symlink; -+ struct squashfs_symlink_inode_header_2 *sinodep = -+ &sid.symlink; -+ -+ if (msblk->swap) { -+ if (!squashfs_get_cached_block(s, (char *) -+ sinodep, block, offset, -+ sizeof(*sinodep), &next_block, -+ &next_offset)) -+ goto failed_read; -+ SQUASHFS_SWAP_SYMLINK_INODE_HEADER_2(inodep, -+ sinodep); -+ } else -+ if (!squashfs_get_cached_block(s, (char *) -+ inodep, block, offset, -+ sizeof(*inodep), &next_block, -+ &next_offset)) -+ goto failed_read; -+ -+ if((i = squashfs_new_inode(s, inodeb, ino)) == NULL) -+ goto failed_read1; -+ -+ i->i_size = inodep->symlink_size; -+ i->i_op = &page_symlink_inode_operations; -+ i->i_data.a_ops = &squashfs_symlink_aops; -+ i->i_mode |= S_IFLNK; -+ SQUASHFS_I(i)->start_block = next_block; -+ SQUASHFS_I(i)->offset = next_offset; -+ -+ TRACE("Symbolic link inode %x:%x, start_block %llx, " -+ "offset %x\n", -+ SQUASHFS_INODE_BLK(inode), offset, -+ next_block, next_offset); -+ break; -+ } -+ case SQUASHFS_BLKDEV_TYPE: -+ case SQUASHFS_CHRDEV_TYPE: { -+ struct squashfs_dev_inode_header_2 *inodep = &id.dev; -+ struct squashfs_dev_inode_header_2 *sinodep = &sid.dev; -+ -+ if (msblk->swap) { -+ if (!squashfs_get_cached_block(s, (char *) -+ sinodep, block, offset, -+ sizeof(*sinodep), &next_block, -+ &next_offset)) -+ goto failed_read; -+ SQUASHFS_SWAP_DEV_INODE_HEADER_2(inodep, sinodep); -+ } else -+ if (!squashfs_get_cached_block(s, (char *) -+ inodep, block, offset, -+ sizeof(*inodep), &next_block, -+ &next_offset)) -+ goto failed_read; -+ -+ if ((i = squashfs_new_inode(s, inodeb, ino)) == NULL) -+ goto failed_read1; -+ -+ i->i_mode |= (inodeb->inode_type == -+ SQUASHFS_CHRDEV_TYPE) ? S_IFCHR : -+ S_IFBLK; -+ init_special_inode(i, i->i_mode, -+ old_decode_dev(inodep->rdev)); -+ -+ TRACE("Device inode %x:%x, rdev %x\n", -+ SQUASHFS_INODE_BLK(inode), offset, -+ inodep->rdev); -+ break; -+ } -+ case SQUASHFS_FIFO_TYPE: -+ case SQUASHFS_SOCKET_TYPE: { -+ if ((i = squashfs_new_inode(s, inodeb, ino)) == NULL) -+ goto failed_read1; -+ -+ i->i_mode |= (inodeb->inode_type == SQUASHFS_FIFO_TYPE) -+ ? S_IFIFO : S_IFSOCK; -+ init_special_inode(i, i->i_mode, 0); -+ break; -+ } -+ default: -+ ERROR("Unknown inode type %d in squashfs_iget!\n", -+ inodeb->inode_type); -+ goto failed_read1; -+ } -+ -+ insert_inode_hash(i); -+ return i; -+ -+failed_read: -+ ERROR("Unable to read inode [%x:%x]\n", block, offset); -+ -+failed_read1: -+ return NULL; -+} -+ -+ -+static int get_dir_index_using_offset(struct super_block *s, long long -+ *next_block, unsigned int *next_offset, -+ long long index_start, -+ unsigned int index_offset, int i_count, -+ long long f_pos) -+{ -+ struct squashfs_sb_info *msblk = s->s_fs_info; -+ struct squashfs_super_block *sblk = &msblk->sblk; -+ int i, length = 0; -+ struct squashfs_dir_index_2 index; -+ -+ TRACE("Entered get_dir_index_using_offset, i_count %d, f_pos %d\n", -+ i_count, (unsigned int) f_pos); -+ -+ if (f_pos == 0) -+ goto finish; -+ -+ for (i = 0; i < i_count; i++) { -+ if (msblk->swap) { -+ struct squashfs_dir_index_2 sindex; -+ squashfs_get_cached_block(s, (char *) &sindex, -+ index_start, index_offset, -+ sizeof(sindex), &index_start, -+ &index_offset); -+ SQUASHFS_SWAP_DIR_INDEX_2(&index, &sindex); -+ } else -+ squashfs_get_cached_block(s, (char *) &index, -+ index_start, index_offset, -+ sizeof(index), &index_start, -+ &index_offset); -+ -+ if (index.index > f_pos) -+ break; -+ -+ squashfs_get_cached_block(s, NULL, index_start, index_offset, -+ index.size + 1, &index_start, -+ &index_offset); -+ -+ length = index.index; -+ *next_block = index.start_block + sblk->directory_table_start; -+ } -+ -+ *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE; -+ -+finish: -+ return length; -+} -+ -+ -+static int get_dir_index_using_name(struct super_block *s, long long -+ *next_block, unsigned int *next_offset, -+ long long index_start, -+ unsigned int index_offset, int i_count, -+ const char *name, int size) -+{ -+ struct squashfs_sb_info *msblk = s->s_fs_info; -+ struct squashfs_super_block *sblk = &msblk->sblk; -+ int i, length = 0; -+ char buffer[sizeof(struct squashfs_dir_index_2) + SQUASHFS_NAME_LEN + 1]; -+ struct squashfs_dir_index_2 *index = (struct squashfs_dir_index_2 *) buffer; -+ char str[SQUASHFS_NAME_LEN + 1]; -+ -+ TRACE("Entered get_dir_index_using_name, i_count %d\n", i_count); -+ -+ strncpy(str, name, size); -+ str[size] = '\0'; -+ -+ for (i = 0; i < i_count; i++) { -+ if (msblk->swap) { -+ struct squashfs_dir_index_2 sindex; -+ squashfs_get_cached_block(s, (char *) &sindex, -+ index_start, index_offset, -+ sizeof(sindex), &index_start, -+ &index_offset); -+ SQUASHFS_SWAP_DIR_INDEX_2(index, &sindex); -+ } else -+ squashfs_get_cached_block(s, (char *) index, -+ index_start, index_offset, -+ sizeof(struct squashfs_dir_index_2), -+ &index_start, &index_offset); -+ -+ squashfs_get_cached_block(s, index->name, index_start, -+ index_offset, index->size + 1, -+ &index_start, &index_offset); -+ -+ index->name[index->size + 1] = '\0'; -+ -+ if (strcmp(index->name, str) > 0) -+ break; -+ -+ length = index->index; -+ *next_block = index->start_block + sblk->directory_table_start; -+ } -+ -+ *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE; -+ return length; -+} -+ -+ -+static int squashfs_readdir_2(struct file *file, void *dirent, filldir_t filldir) -+{ -+ struct inode *i = file->f_dentry->d_inode; -+ struct squashfs_sb_info *msblk = i->i_sb->s_fs_info; -+ struct squashfs_super_block *sblk = &msblk->sblk; -+ long long next_block = SQUASHFS_I(i)->start_block + -+ sblk->directory_table_start; -+ int next_offset = SQUASHFS_I(i)->offset, length = 0, dirs_read = 0, -+ dir_count; -+ struct squashfs_dir_header_2 dirh; -+ char buffer[sizeof(struct squashfs_dir_entry_2) + SQUASHFS_NAME_LEN + 1]; -+ struct squashfs_dir_entry_2 *dire = (struct squashfs_dir_entry_2 *) buffer; -+ -+ TRACE("Entered squashfs_readdir_2 [%llx:%x]\n", next_block, next_offset); -+ -+ length = get_dir_index_using_offset(i->i_sb, &next_block, &next_offset, -+ SQUASHFS_I(i)->u.s2.directory_index_start, -+ SQUASHFS_I(i)->u.s2.directory_index_offset, -+ SQUASHFS_I(i)->u.s2.directory_index_count, -+ file->f_pos); -+ -+ while (length < i_size_read(i)) { -+ /* read directory header */ -+ if (msblk->swap) { -+ struct squashfs_dir_header_2 sdirh; -+ -+ if (!squashfs_get_cached_block(i->i_sb, (char *) &sdirh, -+ next_block, next_offset, sizeof(sdirh), -+ &next_block, &next_offset)) -+ goto failed_read; -+ -+ length += sizeof(sdirh); -+ SQUASHFS_SWAP_DIR_HEADER_2(&dirh, &sdirh); -+ } else { -+ if (!squashfs_get_cached_block(i->i_sb, (char *) &dirh, -+ next_block, next_offset, sizeof(dirh), -+ &next_block, &next_offset)) -+ goto failed_read; -+ -+ length += sizeof(dirh); -+ } -+ -+ dir_count = dirh.count + 1; -+ while (dir_count--) { -+ if (msblk->swap) { -+ struct squashfs_dir_entry_2 sdire; -+ if (!squashfs_get_cached_block(i->i_sb, (char *) -+ &sdire, next_block, next_offset, -+ sizeof(sdire), &next_block, -+ &next_offset)) -+ goto failed_read; -+ -+ length += sizeof(sdire); -+ SQUASHFS_SWAP_DIR_ENTRY_2(dire, &sdire); -+ } else { -+ if (!squashfs_get_cached_block(i->i_sb, (char *) -+ dire, next_block, next_offset, -+ sizeof(*dire), &next_block, -+ &next_offset)) -+ goto failed_read; -+ -+ length += sizeof(*dire); -+ } -+ -+ if (!squashfs_get_cached_block(i->i_sb, dire->name, -+ next_block, next_offset, -+ dire->size + 1, &next_block, -+ &next_offset)) -+ goto failed_read; -+ -+ length += dire->size + 1; -+ -+ if (file->f_pos >= length) -+ continue; -+ -+ dire->name[dire->size + 1] = '\0'; -+ -+ TRACE("Calling filldir(%x, %s, %d, %d, %x:%x, %d)\n", -+ (unsigned int) dirent, dire->name, -+ dire->size + 1, (int) file->f_pos, -+ dirh.start_block, dire->offset, -+ squashfs_filetype_table[dire->type]); -+ -+ if (filldir(dirent, dire->name, dire->size + 1, -+ file->f_pos, SQUASHFS_MK_VFS_INODE( -+ dirh.start_block, dire->offset), -+ squashfs_filetype_table[dire->type]) -+ < 0) { -+ TRACE("Filldir returned less than 0\n"); -+ goto finish; -+ } -+ file->f_pos = length; -+ dirs_read++; -+ } -+ } -+ -+finish: -+ return dirs_read; -+ -+failed_read: -+ ERROR("Unable to read directory block [%llx:%x]\n", next_block, -+ next_offset); -+ return 0; -+} -+ -+ -+static struct dentry *squashfs_lookup_2(struct inode *i, struct dentry *dentry, -+ struct nameidata *nd) -+{ -+ const unsigned char *name = dentry->d_name.name; -+ int len = dentry->d_name.len; -+ struct inode *inode = NULL; -+ struct squashfs_sb_info *msblk = i->i_sb->s_fs_info; -+ struct squashfs_super_block *sblk = &msblk->sblk; -+ long long next_block = SQUASHFS_I(i)->start_block + -+ sblk->directory_table_start; -+ int next_offset = SQUASHFS_I(i)->offset, length = 0, -+ dir_count; -+ struct squashfs_dir_header_2 dirh; -+ char buffer[sizeof(struct squashfs_dir_entry_2) + SQUASHFS_NAME_LEN]; -+ struct squashfs_dir_entry_2 *dire = (struct squashfs_dir_entry_2 *) buffer; -+ int sorted = sblk->s_major == 2 && sblk->s_minor >= 1; -+ -+ TRACE("Entered squashfs_lookup [%llx:%x]\n", next_block, next_offset); -+ -+ if (len > SQUASHFS_NAME_LEN) -+ goto exit_loop; -+ -+ length = get_dir_index_using_name(i->i_sb, &next_block, &next_offset, -+ SQUASHFS_I(i)->u.s2.directory_index_start, -+ SQUASHFS_I(i)->u.s2.directory_index_offset, -+ SQUASHFS_I(i)->u.s2.directory_index_count, name, -+ len); -+ -+ while (length < i_size_read(i)) { -+ /* read directory header */ -+ if (msblk->swap) { -+ struct squashfs_dir_header_2 sdirh; -+ if (!squashfs_get_cached_block(i->i_sb, (char *) &sdirh, -+ next_block, next_offset, sizeof(sdirh), -+ &next_block, &next_offset)) -+ goto failed_read; -+ -+ length += sizeof(sdirh); -+ SQUASHFS_SWAP_DIR_HEADER_2(&dirh, &sdirh); -+ } else { -+ if (!squashfs_get_cached_block(i->i_sb, (char *) &dirh, -+ next_block, next_offset, sizeof(dirh), -+ &next_block, &next_offset)) -+ goto failed_read; -+ -+ length += sizeof(dirh); -+ } -+ -+ dir_count = dirh.count + 1; -+ while (dir_count--) { -+ if (msblk->swap) { -+ struct squashfs_dir_entry_2 sdire; -+ if (!squashfs_get_cached_block(i->i_sb, (char *) -+ &sdire, next_block,next_offset, -+ sizeof(sdire), &next_block, -+ &next_offset)) -+ goto failed_read; -+ -+ length += sizeof(sdire); -+ SQUASHFS_SWAP_DIR_ENTRY_2(dire, &sdire); -+ } else { -+ if (!squashfs_get_cached_block(i->i_sb, (char *) -+ dire, next_block,next_offset, -+ sizeof(*dire), &next_block, -+ &next_offset)) -+ goto failed_read; -+ -+ length += sizeof(*dire); -+ } -+ -+ if (!squashfs_get_cached_block(i->i_sb, dire->name, -+ next_block, next_offset, dire->size + 1, -+ &next_block, &next_offset)) -+ goto failed_read; -+ -+ length += dire->size + 1; -+ -+ if (sorted && name[0] < dire->name[0]) -+ goto exit_loop; -+ -+ if ((len == dire->size + 1) && !strncmp(name, -+ dire->name, len)) { -+ squashfs_inode_t ino = -+ SQUASHFS_MKINODE(dirh.start_block, -+ dire->offset); -+ -+ TRACE("calling squashfs_iget for directory " -+ "entry %s, inode %x:%x, %lld\n", name, -+ dirh.start_block, dire->offset, ino); -+ -+ inode = (msblk->iget)(i->i_sb, ino); -+ -+ goto exit_loop; -+ } -+ } -+ } -+ -+exit_loop: -+ d_add(dentry, inode); -+ return ERR_PTR(0); -+ -+failed_read: -+ ERROR("Unable to read directory block [%llx:%x]\n", next_block, -+ next_offset); -+ goto exit_loop; -+} -+ -+ -+int squashfs_2_0_supported(struct squashfs_sb_info *msblk) -+{ -+ struct squashfs_super_block *sblk = &msblk->sblk; -+ -+ msblk->iget = squashfs_iget_2; -+ msblk->read_fragment_index_table = read_fragment_index_table_2; -+ -+ sblk->bytes_used = sblk->bytes_used_2; -+ sblk->uid_start = sblk->uid_start_2; -+ sblk->guid_start = sblk->guid_start_2; -+ sblk->inode_table_start = sblk->inode_table_start_2; -+ sblk->directory_table_start = sblk->directory_table_start_2; -+ sblk->fragment_table_start = sblk->fragment_table_start_2; -+ -+ return 1; -+} ---- /dev/null -+++ b/fs/squashfs/squashfs.h -@@ -0,0 +1,86 @@ -+/* -+ * Squashfs - a compressed read only filesystem for Linux -+ * -+ * Copyright (c) 2002, 2003, 2004, 2005, 2006 -+ * Phillip Lougher -+ * -+ * 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, -+ * 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ * -+ * squashfs.h -+ */ -+ -+#ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY -+#undef CONFIG_SQUASHFS_1_0_COMPATIBILITY -+#endif -+ -+#ifdef SQUASHFS_TRACE -+#define TRACE(s, args...) printk(KERN_NOTICE "SQUASHFS: "s, ## args) -+#else -+#define TRACE(s, args...) {} -+#endif -+ -+#define ERROR(s, args...) printk(KERN_ERR "SQUASHFS error: "s, ## args) -+ -+#define SERROR(s, args...) do { \ -+ if (!silent) \ -+ printk(KERN_ERR "SQUASHFS error: "s, ## args);\ -+ } while(0) -+ -+#define WARNING(s, args...) printk(KERN_WARNING "SQUASHFS: "s, ## args) -+ -+static inline struct squashfs_inode_info *SQUASHFS_I(struct inode *inode) -+{ -+ return list_entry(inode, struct squashfs_inode_info, vfs_inode); -+} -+ -+#if defined(CONFIG_SQUASHFS_1_0_COMPATIBILITY ) || defined(CONFIG_SQUASHFS_2_0_COMPATIBILITY) -+#define SQSH_EXTERN -+extern unsigned int squashfs_read_data(struct super_block *s, char *buffer, -+ long long index, unsigned int length, -+ long long *next_index); -+extern int squashfs_get_cached_block(struct super_block *s, char *buffer, -+ long long block, unsigned int offset, -+ int length, long long *next_block, -+ unsigned int *next_offset); -+extern void release_cached_fragment(struct squashfs_sb_info *msblk, struct -+ squashfs_fragment_cache *fragment); -+extern struct squashfs_fragment_cache *get_cached_fragment(struct super_block -+ *s, long long start_block, -+ int length); -+extern struct address_space_operations squashfs_symlink_aops; -+extern struct address_space_operations squashfs_aops; -+extern struct address_space_operations squashfs_aops_4K; -+extern struct inode_operations squashfs_dir_inode_ops; -+#else -+#define SQSH_EXTERN static -+#endif -+ -+#ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY -+extern int squashfs_1_0_supported(struct squashfs_sb_info *msblk); -+#else -+static inline int squashfs_1_0_supported(struct squashfs_sb_info *msblk) -+{ -+ return 0; -+} -+#endif -+ -+#ifdef CONFIG_SQUASHFS_2_0_COMPATIBILITY -+extern int squashfs_2_0_supported(struct squashfs_sb_info *msblk); -+#else -+static inline int squashfs_2_0_supported(struct squashfs_sb_info *msblk) -+{ -+ return 0; -+} -+#endif ---- a/include/linux/magic.h -+++ b/include/linux/magic.h -@@ -35,6 +35,9 @@ - #define REISER2FS_SUPER_MAGIC_STRING "ReIsEr2Fs" - #define REISER2FS_JR_SUPER_MAGIC_STRING "ReIsEr3Fs" - -+#define SQUASHFS_MAGIC 0x73717368 -+#define SQUASHFS_MAGIC_SWAP 0x68737173 -+ - #define SMB_SUPER_MAGIC 0x517B - #define USBDEVICE_SUPER_MAGIC 0x9fa2 - #define CGROUP_SUPER_MAGIC 0x27e0eb ---- /dev/null -+++ b/include/linux/squashfs_fs.h -@@ -0,0 +1,911 @@ -+#ifndef SQUASHFS_FS -+#define SQUASHFS_FS -+ -+/* -+ * Squashfs -+ * -+ * Copyright (c) 2002, 2003, 2004, 2005, 2006 -+ * Phillip Lougher -+ * -+ * 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, -+ * 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ * -+ * squashfs_fs.h -+ */ -+ -+#ifndef CONFIG_SQUASHFS_2_0_COMPATIBILITY -+#define CONFIG_SQUASHFS_2_0_COMPATIBILITY -+#endif -+ -+#ifdef CONFIG_SQUASHFS_VMALLOC -+#define SQUASHFS_ALLOC(a) vmalloc(a) -+#define SQUASHFS_FREE(a) vfree(a) -+#else -+#define SQUASHFS_ALLOC(a) kmalloc(a, GFP_KERNEL) -+#define SQUASHFS_FREE(a) kfree(a) -+#endif -+#define SQUASHFS_CACHED_FRAGMENTS CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE -+#define SQUASHFS_MAJOR 3 -+#define SQUASHFS_MINOR 0 -+#define SQUASHFS_START 0 -+ -+/* size of metadata (inode and directory) blocks */ -+#define SQUASHFS_METADATA_SIZE 8192 -+#define SQUASHFS_METADATA_LOG 13 -+ -+/* default size of data blocks */ -+#define SQUASHFS_FILE_SIZE 65536 -+#define SQUASHFS_FILE_LOG 16 -+ -+#define SQUASHFS_FILE_MAX_SIZE 65536 -+ -+/* Max number of uids and gids */ -+#define SQUASHFS_UIDS 256 -+#define SQUASHFS_GUIDS 255 -+ -+/* Max length of filename (not 255) */ -+#define SQUASHFS_NAME_LEN 256 -+ -+#define SQUASHFS_INVALID ((long long) 0xffffffffffff) -+#define SQUASHFS_INVALID_FRAG ((unsigned int) 0xffffffff) -+#define SQUASHFS_INVALID_BLK ((long long) -1) -+#define SQUASHFS_USED_BLK ((long long) -2) -+ -+/* Filesystem flags */ -+#define SQUASHFS_NOI 0 -+#define SQUASHFS_NOD 1 -+#define SQUASHFS_CHECK 2 -+#define SQUASHFS_NOF 3 -+#define SQUASHFS_NO_FRAG 4 -+#define SQUASHFS_ALWAYS_FRAG 5 -+#define SQUASHFS_DUPLICATE 6 -+ -+#define SQUASHFS_BIT(flag, bit) ((flag >> bit) & 1) -+ -+#define SQUASHFS_UNCOMPRESSED_INODES(flags) SQUASHFS_BIT(flags, \ -+ SQUASHFS_NOI) -+ -+#define SQUASHFS_UNCOMPRESSED_DATA(flags) SQUASHFS_BIT(flags, \ -+ SQUASHFS_NOD) -+ -+#define SQUASHFS_UNCOMPRESSED_FRAGMENTS(flags) SQUASHFS_BIT(flags, \ -+ SQUASHFS_NOF) -+ -+#define SQUASHFS_NO_FRAGMENTS(flags) SQUASHFS_BIT(flags, \ -+ SQUASHFS_NO_FRAG) -+ -+#define SQUASHFS_ALWAYS_FRAGMENTS(flags) SQUASHFS_BIT(flags, \ -+ SQUASHFS_ALWAYS_FRAG) -+ -+#define SQUASHFS_DUPLICATES(flags) SQUASHFS_BIT(flags, \ -+ SQUASHFS_DUPLICATE) -+ -+#define SQUASHFS_CHECK_DATA(flags) SQUASHFS_BIT(flags, \ -+ SQUASHFS_CHECK) -+ -+#define SQUASHFS_MKFLAGS(noi, nod, check_data, nof, no_frag, always_frag, \ -+ duplicate_checking) (noi | (nod << 1) | (check_data << 2) \ -+ | (nof << 3) | (no_frag << 4) | (always_frag << 5) | \ -+ (duplicate_checking << 6)) -+ -+/* Max number of types and file types */ -+#define SQUASHFS_DIR_TYPE 1 -+#define SQUASHFS_FILE_TYPE 2 -+#define SQUASHFS_SYMLINK_TYPE 3 -+#define SQUASHFS_BLKDEV_TYPE 4 -+#define SQUASHFS_CHRDEV_TYPE 5 -+#define SQUASHFS_FIFO_TYPE 6 -+#define SQUASHFS_SOCKET_TYPE 7 -+#define SQUASHFS_LDIR_TYPE 8 -+#define SQUASHFS_LREG_TYPE 9 -+ -+/* 1.0 filesystem type definitions */ -+#define SQUASHFS_TYPES 5 -+#define SQUASHFS_IPC_TYPE 0 -+ -+/* Flag whether block is compressed or uncompressed, bit is set if block is -+ * uncompressed */ -+#define SQUASHFS_COMPRESSED_BIT (1 << 15) -+ -+#define SQUASHFS_COMPRESSED_SIZE(B) (((B) & ~SQUASHFS_COMPRESSED_BIT) ? \ -+ (B) & ~SQUASHFS_COMPRESSED_BIT : SQUASHFS_COMPRESSED_BIT) -+ -+#define SQUASHFS_COMPRESSED(B) (!((B) & SQUASHFS_COMPRESSED_BIT)) -+ -+#define SQUASHFS_COMPRESSED_BIT_BLOCK (1 << 24) -+ -+#define SQUASHFS_COMPRESSED_SIZE_BLOCK(B) (((B) & \ -+ ~SQUASHFS_COMPRESSED_BIT_BLOCK) ? (B) & \ -+ ~SQUASHFS_COMPRESSED_BIT_BLOCK : SQUASHFS_COMPRESSED_BIT_BLOCK) -+ -+#define SQUASHFS_COMPRESSED_BLOCK(B) (!((B) & SQUASHFS_COMPRESSED_BIT_BLOCK)) -+ -+/* -+ * Inode number ops. Inodes consist of a compressed block number, and an -+ * uncompressed offset within that block -+ */ -+#define SQUASHFS_INODE_BLK(a) ((unsigned int) ((a) >> 16)) -+ -+#define SQUASHFS_INODE_OFFSET(a) ((unsigned int) ((a) & 0xffff)) -+ -+#define SQUASHFS_MKINODE(A, B) ((squashfs_inode_t)(((squashfs_inode_t) (A)\ -+ << 16) + (B))) -+ -+/* Compute 32 bit VFS inode number from squashfs inode number */ -+#define SQUASHFS_MK_VFS_INODE(a, b) ((unsigned int) (((a) << 8) + \ -+ ((b) >> 2) + 1)) -+/* XXX */ -+ -+/* Translate between VFS mode and squashfs mode */ -+#define SQUASHFS_MODE(a) ((a) & 0xfff) -+ -+/* fragment and fragment table defines */ -+#define SQUASHFS_FRAGMENT_BYTES(A) (A * sizeof(struct squashfs_fragment_entry)) -+ -+#define SQUASHFS_FRAGMENT_INDEX(A) (SQUASHFS_FRAGMENT_BYTES(A) / \ -+ SQUASHFS_METADATA_SIZE) -+ -+#define SQUASHFS_FRAGMENT_INDEX_OFFSET(A) (SQUASHFS_FRAGMENT_BYTES(A) % \ -+ SQUASHFS_METADATA_SIZE) -+ -+#define SQUASHFS_FRAGMENT_INDEXES(A) ((SQUASHFS_FRAGMENT_BYTES(A) + \ -+ SQUASHFS_METADATA_SIZE - 1) / \ -+ SQUASHFS_METADATA_SIZE) -+ -+#define SQUASHFS_FRAGMENT_INDEX_BYTES(A) (SQUASHFS_FRAGMENT_INDEXES(A) *\ -+ sizeof(long long)) -+ -+/* cached data constants for filesystem */ -+#define SQUASHFS_CACHED_BLKS 8 -+ -+#define SQUASHFS_MAX_FILE_SIZE_LOG 64 -+ -+#define SQUASHFS_MAX_FILE_SIZE ((long long) 1 << \ -+ (SQUASHFS_MAX_FILE_SIZE_LOG - 2)) -+ -+#define SQUASHFS_MARKER_BYTE 0xff -+ -+/* meta index cache */ -+#define SQUASHFS_META_INDEXES (SQUASHFS_METADATA_SIZE / sizeof(unsigned int)) -+#define SQUASHFS_META_ENTRIES 31 -+#define SQUASHFS_META_NUMBER 8 -+#define SQUASHFS_SLOTS 4 -+ -+#include -+ -+struct meta_entry { -+ long long data_block; -+ unsigned int index_block; -+ unsigned short offset; -+ unsigned short pad; -+}; -+ -+struct meta_index { -+ unsigned int inode_number; -+ unsigned int offset; -+ unsigned short entries; -+ unsigned short skip; -+ unsigned short locked; -+ unsigned short pad; -+ struct meta_entry meta_entry[SQUASHFS_META_ENTRIES]; -+}; -+ -+ -+/* -+ * definitions for structures on disk -+ */ -+ -+typedef long long squashfs_block_t; -+typedef long long squashfs_inode_t; -+ -+struct squashfs_super_block { -+ unsigned int s_magic; -+ unsigned int inodes; -+ unsigned int bytes_used_2; -+ unsigned int uid_start_2; -+ unsigned int guid_start_2; -+ unsigned int inode_table_start_2; -+ unsigned int directory_table_start_2; -+ unsigned int s_major:16; -+ unsigned int s_minor:16; -+ unsigned int block_size_1:16; -+ unsigned int block_log:16; -+ unsigned int flags:8; -+ unsigned int no_uids:8; -+ unsigned int no_guids:8; -+ unsigned int mkfs_time /* time of filesystem creation */; -+ squashfs_inode_t root_inode; -+ unsigned int block_size; -+ unsigned int fragments; -+ unsigned int fragment_table_start_2; -+ long long bytes_used; -+ long long uid_start; -+ long long guid_start; -+ long long inode_table_start; -+ long long directory_table_start; -+ long long fragment_table_start; -+ long long unused; -+} __attribute__ ((packed)); -+ -+struct squashfs_dir_index { -+ unsigned int index; -+ unsigned int start_block; -+ unsigned char size; -+ unsigned char name[0]; -+} __attribute__ ((packed)); -+ -+#define SQUASHFS_BASE_INODE_HEADER \ -+ unsigned int inode_type:4; \ -+ unsigned int mode:12; \ -+ unsigned int uid:8; \ -+ unsigned int guid:8; \ -+ unsigned int mtime; \ -+ unsigned int inode_number; -+ -+struct squashfs_base_inode_header { -+ SQUASHFS_BASE_INODE_HEADER; -+} __attribute__ ((packed)); -+ -+struct squashfs_ipc_inode_header { -+ SQUASHFS_BASE_INODE_HEADER; -+ unsigned int nlink; -+} __attribute__ ((packed)); -+ -+struct squashfs_dev_inode_header { -+ SQUASHFS_BASE_INODE_HEADER; -+ unsigned int nlink; -+ unsigned short rdev; -+} __attribute__ ((packed)); -+ -+struct squashfs_symlink_inode_header { -+ SQUASHFS_BASE_INODE_HEADER; -+ unsigned int nlink; -+ unsigned short symlink_size; -+ char symlink[0]; -+} __attribute__ ((packed)); -+ -+struct squashfs_reg_inode_header { -+ SQUASHFS_BASE_INODE_HEADER; -+ squashfs_block_t start_block; -+ unsigned int fragment; -+ unsigned int offset; -+ unsigned int file_size; -+ unsigned short block_list[0]; -+} __attribute__ ((packed)); -+ -+struct squashfs_lreg_inode_header { -+ SQUASHFS_BASE_INODE_HEADER; -+ unsigned int nlink; -+ squashfs_block_t start_block; -+ unsigned int fragment; -+ unsigned int offset; -+ long long file_size; -+ unsigned short block_list[0]; -+} __attribute__ ((packed)); -+ -+struct squashfs_dir_inode_header { -+ SQUASHFS_BASE_INODE_HEADER; -+ unsigned int nlink; -+ unsigned int file_size:19; -+ unsigned int offset:13; -+ unsigned int start_block; -+ unsigned int parent_inode; -+} __attribute__ ((packed)); -+ -+struct squashfs_ldir_inode_header { -+ SQUASHFS_BASE_INODE_HEADER; -+ unsigned int nlink; -+ unsigned int file_size:27; -+ unsigned int offset:13; -+ unsigned int start_block; -+ unsigned int i_count:16; -+ unsigned int parent_inode; -+ struct squashfs_dir_index index[0]; -+} __attribute__ ((packed)); -+ -+union squashfs_inode_header { -+ struct squashfs_base_inode_header base; -+ struct squashfs_dev_inode_header dev; -+ struct squashfs_symlink_inode_header symlink; -+ struct squashfs_reg_inode_header reg; -+ struct squashfs_lreg_inode_header lreg; -+ struct squashfs_dir_inode_header dir; -+ struct squashfs_ldir_inode_header ldir; -+ struct squashfs_ipc_inode_header ipc; -+}; -+ -+struct squashfs_dir_entry { -+ unsigned int offset:13; -+ unsigned int type:3; -+ unsigned int size:8; -+ int inode_number:16; -+ char name[0]; -+} __attribute__ ((packed)); -+ -+struct squashfs_dir_header { -+ unsigned int count:8; -+ unsigned int start_block; -+ unsigned int inode_number; -+} __attribute__ ((packed)); -+ -+struct squashfs_fragment_entry { -+ long long start_block; -+ unsigned int size; -+ unsigned int unused; -+} __attribute__ ((packed)); -+ -+extern int squashfs_uncompress_block(void *d, int dstlen, void *s, int srclen); -+extern int squashfs_uncompress_init(void); -+extern int squashfs_uncompress_exit(void); -+ -+/* -+ * macros to convert each packed bitfield structure from little endian to big -+ * endian and vice versa. These are needed when creating or using a filesystem -+ * on a machine with different byte ordering to the target architecture. -+ * -+ */ -+ -+#define SQUASHFS_SWAP_START \ -+ int bits;\ -+ int b_pos;\ -+ unsigned long long val;\ -+ unsigned char *s;\ -+ unsigned char *d; -+ -+#define SQUASHFS_SWAP_SUPER_BLOCK(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_super_block));\ -+ SQUASHFS_SWAP((s)->s_magic, d, 0, 32);\ -+ SQUASHFS_SWAP((s)->inodes, d, 32, 32);\ -+ SQUASHFS_SWAP((s)->bytes_used_2, d, 64, 32);\ -+ SQUASHFS_SWAP((s)->uid_start_2, d, 96, 32);\ -+ SQUASHFS_SWAP((s)->guid_start_2, d, 128, 32);\ -+ SQUASHFS_SWAP((s)->inode_table_start_2, d, 160, 32);\ -+ SQUASHFS_SWAP((s)->directory_table_start_2, d, 192, 32);\ -+ SQUASHFS_SWAP((s)->s_major, d, 224, 16);\ -+ SQUASHFS_SWAP((s)->s_minor, d, 240, 16);\ -+ SQUASHFS_SWAP((s)->block_size_1, d, 256, 16);\ -+ SQUASHFS_SWAP((s)->block_log, d, 272, 16);\ -+ SQUASHFS_SWAP((s)->flags, d, 288, 8);\ -+ SQUASHFS_SWAP((s)->no_uids, d, 296, 8);\ -+ SQUASHFS_SWAP((s)->no_guids, d, 304, 8);\ -+ SQUASHFS_SWAP((s)->mkfs_time, d, 312, 32);\ -+ SQUASHFS_SWAP((s)->root_inode, d, 344, 64);\ -+ SQUASHFS_SWAP((s)->block_size, d, 408, 32);\ -+ SQUASHFS_SWAP((s)->fragments, d, 440, 32);\ -+ SQUASHFS_SWAP((s)->fragment_table_start_2, d, 472, 32);\ -+ SQUASHFS_SWAP((s)->bytes_used, d, 504, 64);\ -+ SQUASHFS_SWAP((s)->uid_start, d, 568, 64);\ -+ SQUASHFS_SWAP((s)->guid_start, d, 632, 64);\ -+ SQUASHFS_SWAP((s)->inode_table_start, d, 696, 64);\ -+ SQUASHFS_SWAP((s)->directory_table_start, d, 760, 64);\ -+ SQUASHFS_SWAP((s)->fragment_table_start, d, 824, 64);\ -+ SQUASHFS_SWAP((s)->unused, d, 888, 64);\ -+} -+ -+#define SQUASHFS_SWAP_BASE_INODE_CORE(s, d, n)\ -+ SQUASHFS_MEMSET(s, d, n);\ -+ SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\ -+ SQUASHFS_SWAP((s)->mode, d, 4, 12);\ -+ SQUASHFS_SWAP((s)->uid, d, 16, 8);\ -+ SQUASHFS_SWAP((s)->guid, d, 24, 8);\ -+ SQUASHFS_SWAP((s)->mtime, d, 32, 32);\ -+ SQUASHFS_SWAP((s)->inode_number, d, 64, 32); -+ -+#define SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, n) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, n)\ -+} -+ -+#define SQUASHFS_SWAP_IPC_INODE_HEADER(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \ -+ sizeof(struct squashfs_ipc_inode_header))\ -+ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\ -+} -+ -+#define SQUASHFS_SWAP_DEV_INODE_HEADER(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \ -+ sizeof(struct squashfs_dev_inode_header)); \ -+ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\ -+ SQUASHFS_SWAP((s)->rdev, d, 128, 16);\ -+} -+ -+#define SQUASHFS_SWAP_SYMLINK_INODE_HEADER(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \ -+ sizeof(struct squashfs_symlink_inode_header));\ -+ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\ -+ SQUASHFS_SWAP((s)->symlink_size, d, 128, 16);\ -+} -+ -+#define SQUASHFS_SWAP_REG_INODE_HEADER(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \ -+ sizeof(struct squashfs_reg_inode_header));\ -+ SQUASHFS_SWAP((s)->start_block, d, 96, 64);\ -+ SQUASHFS_SWAP((s)->fragment, d, 160, 32);\ -+ SQUASHFS_SWAP((s)->offset, d, 192, 32);\ -+ SQUASHFS_SWAP((s)->file_size, d, 224, 32);\ -+} -+ -+#define SQUASHFS_SWAP_LREG_INODE_HEADER(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \ -+ sizeof(struct squashfs_lreg_inode_header));\ -+ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\ -+ SQUASHFS_SWAP((s)->start_block, d, 128, 64);\ -+ SQUASHFS_SWAP((s)->fragment, d, 192, 32);\ -+ SQUASHFS_SWAP((s)->offset, d, 224, 32);\ -+ SQUASHFS_SWAP((s)->file_size, d, 256, 64);\ -+} -+ -+#define SQUASHFS_SWAP_DIR_INODE_HEADER(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \ -+ sizeof(struct squashfs_dir_inode_header));\ -+ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\ -+ SQUASHFS_SWAP((s)->file_size, d, 128, 19);\ -+ SQUASHFS_SWAP((s)->offset, d, 147, 13);\ -+ SQUASHFS_SWAP((s)->start_block, d, 160, 32);\ -+ SQUASHFS_SWAP((s)->parent_inode, d, 192, 32);\ -+} -+ -+#define SQUASHFS_SWAP_LDIR_INODE_HEADER(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \ -+ sizeof(struct squashfs_ldir_inode_header));\ -+ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\ -+ SQUASHFS_SWAP((s)->file_size, d, 128, 27);\ -+ SQUASHFS_SWAP((s)->offset, d, 155, 13);\ -+ SQUASHFS_SWAP((s)->start_block, d, 168, 32);\ -+ SQUASHFS_SWAP((s)->i_count, d, 200, 16);\ -+ SQUASHFS_SWAP((s)->parent_inode, d, 216, 32);\ -+} -+ -+#define SQUASHFS_SWAP_DIR_INDEX(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_index));\ -+ SQUASHFS_SWAP((s)->index, d, 0, 32);\ -+ SQUASHFS_SWAP((s)->start_block, d, 32, 32);\ -+ SQUASHFS_SWAP((s)->size, d, 64, 8);\ -+} -+ -+#define SQUASHFS_SWAP_DIR_HEADER(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_header));\ -+ SQUASHFS_SWAP((s)->count, d, 0, 8);\ -+ SQUASHFS_SWAP((s)->start_block, d, 8, 32);\ -+ SQUASHFS_SWAP((s)->inode_number, d, 40, 32);\ -+} -+ -+#define SQUASHFS_SWAP_DIR_ENTRY(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_entry));\ -+ SQUASHFS_SWAP((s)->offset, d, 0, 13);\ -+ SQUASHFS_SWAP((s)->type, d, 13, 3);\ -+ SQUASHFS_SWAP((s)->size, d, 16, 8);\ -+ SQUASHFS_SWAP((s)->inode_number, d, 24, 16);\ -+} -+ -+#define SQUASHFS_SWAP_FRAGMENT_ENTRY(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_fragment_entry));\ -+ SQUASHFS_SWAP((s)->start_block, d, 0, 64);\ -+ SQUASHFS_SWAP((s)->size, d, 64, 32);\ -+} -+ -+#define SQUASHFS_SWAP_SHORTS(s, d, n) {\ -+ int entry;\ -+ int bit_position;\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_MEMSET(s, d, n * 2);\ -+ for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \ -+ 16)\ -+ SQUASHFS_SWAP(s[entry], d, bit_position, 16);\ -+} -+ -+#define SQUASHFS_SWAP_INTS(s, d, n) {\ -+ int entry;\ -+ int bit_position;\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_MEMSET(s, d, n * 4);\ -+ for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \ -+ 32)\ -+ SQUASHFS_SWAP(s[entry], d, bit_position, 32);\ -+} -+ -+#define SQUASHFS_SWAP_LONG_LONGS(s, d, n) {\ -+ int entry;\ -+ int bit_position;\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_MEMSET(s, d, n * 8);\ -+ for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \ -+ 64)\ -+ SQUASHFS_SWAP(s[entry], d, bit_position, 64);\ -+} -+ -+#define SQUASHFS_SWAP_DATA(s, d, n, bits) {\ -+ int entry;\ -+ int bit_position;\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_MEMSET(s, d, n * bits / 8);\ -+ for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \ -+ bits)\ -+ SQUASHFS_SWAP(s[entry], d, bit_position, bits);\ -+} -+ -+#define SQUASHFS_SWAP_FRAGMENT_INDEXES(s, d, n) SQUASHFS_SWAP_LONG_LONGS(s, d, n) -+ -+#ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY -+ -+struct squashfs_base_inode_header_1 { -+ unsigned int inode_type:4; -+ unsigned int mode:12; /* protection */ -+ unsigned int uid:4; /* index into uid table */ -+ unsigned int guid:4; /* index into guid table */ -+} __attribute__ ((packed)); -+ -+struct squashfs_ipc_inode_header_1 { -+ unsigned int inode_type:4; -+ unsigned int mode:12; /* protection */ -+ unsigned int uid:4; /* index into uid table */ -+ unsigned int guid:4; /* index into guid table */ -+ unsigned int type:4; -+ unsigned int offset:4; -+} __attribute__ ((packed)); -+ -+struct squashfs_dev_inode_header_1 { -+ unsigned int inode_type:4; -+ unsigned int mode:12; /* protection */ -+ unsigned int uid:4; /* index into uid table */ -+ unsigned int guid:4; /* index into guid table */ -+ unsigned short rdev; -+} __attribute__ ((packed)); -+ -+struct squashfs_symlink_inode_header_1 { -+ unsigned int inode_type:4; -+ unsigned int mode:12; /* protection */ -+ unsigned int uid:4; /* index into uid table */ -+ unsigned int guid:4; /* index into guid table */ -+ unsigned short symlink_size; -+ char symlink[0]; -+} __attribute__ ((packed)); -+ -+struct squashfs_reg_inode_header_1 { -+ unsigned int inode_type:4; -+ unsigned int mode:12; /* protection */ -+ unsigned int uid:4; /* index into uid table */ -+ unsigned int guid:4; /* index into guid table */ -+ unsigned int mtime; -+ unsigned int start_block; -+ unsigned int file_size:32; -+ unsigned short block_list[0]; -+} __attribute__ ((packed)); -+ -+struct squashfs_dir_inode_header_1 { -+ unsigned int inode_type:4; -+ unsigned int mode:12; /* protection */ -+ unsigned int uid:4; /* index into uid table */ -+ unsigned int guid:4; /* index into guid table */ -+ unsigned int file_size:19; -+ unsigned int offset:13; -+ unsigned int mtime; -+ unsigned int start_block:24; -+} __attribute__ ((packed)); -+ -+#define SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, n) \ -+ SQUASHFS_MEMSET(s, d, n);\ -+ SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\ -+ SQUASHFS_SWAP((s)->mode, d, 4, 12);\ -+ SQUASHFS_SWAP((s)->uid, d, 16, 4);\ -+ SQUASHFS_SWAP((s)->guid, d, 20, 4); -+ -+#define SQUASHFS_SWAP_BASE_INODE_HEADER_1(s, d, n) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, n)\ -+} -+ -+#define SQUASHFS_SWAP_IPC_INODE_HEADER_1(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \ -+ sizeof(struct squashfs_ipc_inode_header_1));\ -+ SQUASHFS_SWAP((s)->type, d, 24, 4);\ -+ SQUASHFS_SWAP((s)->offset, d, 28, 4);\ -+} -+ -+#define SQUASHFS_SWAP_DEV_INODE_HEADER_1(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \ -+ sizeof(struct squashfs_dev_inode_header_1));\ -+ SQUASHFS_SWAP((s)->rdev, d, 24, 16);\ -+} -+ -+#define SQUASHFS_SWAP_SYMLINK_INODE_HEADER_1(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \ -+ sizeof(struct squashfs_symlink_inode_header_1));\ -+ SQUASHFS_SWAP((s)->symlink_size, d, 24, 16);\ -+} -+ -+#define SQUASHFS_SWAP_REG_INODE_HEADER_1(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \ -+ sizeof(struct squashfs_reg_inode_header_1));\ -+ SQUASHFS_SWAP((s)->mtime, d, 24, 32);\ -+ SQUASHFS_SWAP((s)->start_block, d, 56, 32);\ -+ SQUASHFS_SWAP((s)->file_size, d, 88, 32);\ -+} -+ -+#define SQUASHFS_SWAP_DIR_INODE_HEADER_1(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \ -+ sizeof(struct squashfs_dir_inode_header_1));\ -+ SQUASHFS_SWAP((s)->file_size, d, 24, 19);\ -+ SQUASHFS_SWAP((s)->offset, d, 43, 13);\ -+ SQUASHFS_SWAP((s)->mtime, d, 56, 32);\ -+ SQUASHFS_SWAP((s)->start_block, d, 88, 24);\ -+} -+ -+#endif -+ -+#ifdef CONFIG_SQUASHFS_2_0_COMPATIBILITY -+ -+struct squashfs_dir_index_2 { -+ unsigned int index:27; -+ unsigned int start_block:29; -+ unsigned char size; -+ unsigned char name[0]; -+} __attribute__ ((packed)); -+ -+struct squashfs_base_inode_header_2 { -+ unsigned int inode_type:4; -+ unsigned int mode:12; /* protection */ -+ unsigned int uid:8; /* index into uid table */ -+ unsigned int guid:8; /* index into guid table */ -+} __attribute__ ((packed)); -+ -+struct squashfs_ipc_inode_header_2 { -+ unsigned int inode_type:4; -+ unsigned int mode:12; /* protection */ -+ unsigned int uid:8; /* index into uid table */ -+ unsigned int guid:8; /* index into guid table */ -+} __attribute__ ((packed)); -+ -+struct squashfs_dev_inode_header_2 { -+ unsigned int inode_type:4; -+ unsigned int mode:12; /* protection */ -+ unsigned int uid:8; /* index into uid table */ -+ unsigned int guid:8; /* index into guid table */ -+ unsigned short rdev; -+} __attribute__ ((packed)); -+ -+struct squashfs_symlink_inode_header_2 { -+ unsigned int inode_type:4; -+ unsigned int mode:12; /* protection */ -+ unsigned int uid:8; /* index into uid table */ -+ unsigned int guid:8; /* index into guid table */ -+ unsigned short symlink_size; -+ char symlink[0]; -+} __attribute__ ((packed)); -+ -+struct squashfs_reg_inode_header_2 { -+ unsigned int inode_type:4; -+ unsigned int mode:12; /* protection */ -+ unsigned int uid:8; /* index into uid table */ -+ unsigned int guid:8; /* index into guid table */ -+ unsigned int mtime; -+ unsigned int start_block; -+ unsigned int fragment; -+ unsigned int offset; -+ unsigned int file_size:32; -+ unsigned short block_list[0]; -+} __attribute__ ((packed)); -+ -+struct squashfs_dir_inode_header_2 { -+ unsigned int inode_type:4; -+ unsigned int mode:12; /* protection */ -+ unsigned int uid:8; /* index into uid table */ -+ unsigned int guid:8; /* index into guid table */ -+ unsigned int file_size:19; -+ unsigned int offset:13; -+ unsigned int mtime; -+ unsigned int start_block:24; -+} __attribute__ ((packed)); -+ -+struct squashfs_ldir_inode_header_2 { -+ unsigned int inode_type:4; -+ unsigned int mode:12; /* protection */ -+ unsigned int uid:8; /* index into uid table */ -+ unsigned int guid:8; /* index into guid table */ -+ unsigned int file_size:27; -+ unsigned int offset:13; -+ unsigned int mtime; -+ unsigned int start_block:24; -+ unsigned int i_count:16; -+ struct squashfs_dir_index_2 index[0]; -+} __attribute__ ((packed)); -+ -+union squashfs_inode_header_2 { -+ struct squashfs_base_inode_header_2 base; -+ struct squashfs_dev_inode_header_2 dev; -+ struct squashfs_symlink_inode_header_2 symlink; -+ struct squashfs_reg_inode_header_2 reg; -+ struct squashfs_dir_inode_header_2 dir; -+ struct squashfs_ldir_inode_header_2 ldir; -+ struct squashfs_ipc_inode_header_2 ipc; -+}; -+ -+struct squashfs_dir_header_2 { -+ unsigned int count:8; -+ unsigned int start_block:24; -+} __attribute__ ((packed)); -+ -+struct squashfs_dir_entry_2 { -+ unsigned int offset:13; -+ unsigned int type:3; -+ unsigned int size:8; -+ char name[0]; -+} __attribute__ ((packed)); -+ -+struct squashfs_fragment_entry_2 { -+ unsigned int start_block; -+ unsigned int size; -+} __attribute__ ((packed)); -+ -+#define SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, n)\ -+ SQUASHFS_MEMSET(s, d, n);\ -+ SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\ -+ SQUASHFS_SWAP((s)->mode, d, 4, 12);\ -+ SQUASHFS_SWAP((s)->uid, d, 16, 8);\ -+ SQUASHFS_SWAP((s)->guid, d, 24, 8);\ -+ -+#define SQUASHFS_SWAP_BASE_INODE_HEADER_2(s, d, n) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, n)\ -+} -+ -+#define SQUASHFS_SWAP_IPC_INODE_HEADER_2(s, d) \ -+ SQUASHFS_SWAP_BASE_INODE_HEADER_2(s, d, sizeof(struct squashfs_ipc_inode_header_2)) -+ -+#define SQUASHFS_SWAP_DEV_INODE_HEADER_2(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \ -+ sizeof(struct squashfs_dev_inode_header_2)); \ -+ SQUASHFS_SWAP((s)->rdev, d, 32, 16);\ -+} -+ -+#define SQUASHFS_SWAP_SYMLINK_INODE_HEADER_2(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \ -+ sizeof(struct squashfs_symlink_inode_header_2));\ -+ SQUASHFS_SWAP((s)->symlink_size, d, 32, 16);\ -+} -+ -+#define SQUASHFS_SWAP_REG_INODE_HEADER_2(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \ -+ sizeof(struct squashfs_reg_inode_header_2));\ -+ SQUASHFS_SWAP((s)->mtime, d, 32, 32);\ -+ SQUASHFS_SWAP((s)->start_block, d, 64, 32);\ -+ SQUASHFS_SWAP((s)->fragment, d, 96, 32);\ -+ SQUASHFS_SWAP((s)->offset, d, 128, 32);\ -+ SQUASHFS_SWAP((s)->file_size, d, 160, 32);\ -+} -+ -+#define SQUASHFS_SWAP_DIR_INODE_HEADER_2(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \ -+ sizeof(struct squashfs_dir_inode_header_2));\ -+ SQUASHFS_SWAP((s)->file_size, d, 32, 19);\ -+ SQUASHFS_SWAP((s)->offset, d, 51, 13);\ -+ SQUASHFS_SWAP((s)->mtime, d, 64, 32);\ -+ SQUASHFS_SWAP((s)->start_block, d, 96, 24);\ -+} -+ -+#define SQUASHFS_SWAP_LDIR_INODE_HEADER_2(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \ -+ sizeof(struct squashfs_ldir_inode_header_2));\ -+ SQUASHFS_SWAP((s)->file_size, d, 32, 27);\ -+ SQUASHFS_SWAP((s)->offset, d, 59, 13);\ -+ SQUASHFS_SWAP((s)->mtime, d, 72, 32);\ -+ SQUASHFS_SWAP((s)->start_block, d, 104, 24);\ -+ SQUASHFS_SWAP((s)->i_count, d, 128, 16);\ -+} -+ -+#define SQUASHFS_SWAP_DIR_INDEX_2(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_index_2));\ -+ SQUASHFS_SWAP((s)->index, d, 0, 27);\ -+ SQUASHFS_SWAP((s)->start_block, d, 27, 29);\ -+ SQUASHFS_SWAP((s)->size, d, 56, 8);\ -+} -+#define SQUASHFS_SWAP_DIR_HEADER_2(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_header_2));\ -+ SQUASHFS_SWAP((s)->count, d, 0, 8);\ -+ SQUASHFS_SWAP((s)->start_block, d, 8, 24);\ -+} -+ -+#define SQUASHFS_SWAP_DIR_ENTRY_2(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_entry_2));\ -+ SQUASHFS_SWAP((s)->offset, d, 0, 13);\ -+ SQUASHFS_SWAP((s)->type, d, 13, 3);\ -+ SQUASHFS_SWAP((s)->size, d, 16, 8);\ -+} -+ -+#define SQUASHFS_SWAP_FRAGMENT_ENTRY_2(s, d) {\ -+ SQUASHFS_SWAP_START\ -+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_fragment_entry_2));\ -+ SQUASHFS_SWAP((s)->start_block, d, 0, 32);\ -+ SQUASHFS_SWAP((s)->size, d, 32, 32);\ -+} -+ -+#define SQUASHFS_SWAP_FRAGMENT_INDEXES_2(s, d, n) SQUASHFS_SWAP_INTS(s, d, n) -+ -+/* fragment and fragment table defines */ -+#define SQUASHFS_FRAGMENT_BYTES_2(A) (A * sizeof(struct squashfs_fragment_entry_2)) -+ -+#define SQUASHFS_FRAGMENT_INDEX_2(A) (SQUASHFS_FRAGMENT_BYTES_2(A) / \ -+ SQUASHFS_METADATA_SIZE) -+ -+#define SQUASHFS_FRAGMENT_INDEX_OFFSET_2(A) (SQUASHFS_FRAGMENT_BYTES_2(A) % \ -+ SQUASHFS_METADATA_SIZE) -+ -+#define SQUASHFS_FRAGMENT_INDEXES_2(A) ((SQUASHFS_FRAGMENT_BYTES_2(A) + \ -+ SQUASHFS_METADATA_SIZE - 1) / \ -+ SQUASHFS_METADATA_SIZE) -+ -+#define SQUASHFS_FRAGMENT_INDEX_BYTES_2(A) (SQUASHFS_FRAGMENT_INDEXES_2(A) *\ -+ sizeof(int)) -+ -+#endif -+ -+#ifdef __KERNEL__ -+ -+/* -+ * macros used to swap each structure entry, taking into account -+ * bitfields and different bitfield placing conventions on differing -+ * architectures -+ */ -+ -+#include -+ -+#ifdef __BIG_ENDIAN -+ /* convert from little endian to big endian */ -+#define SQUASHFS_SWAP(value, p, pos, tbits) _SQUASHFS_SWAP(value, p, pos, \ -+ tbits, b_pos) -+#else -+ /* convert from big endian to little endian */ -+#define SQUASHFS_SWAP(value, p, pos, tbits) _SQUASHFS_SWAP(value, p, pos, \ -+ tbits, 64 - tbits - b_pos) -+#endif -+ -+#define _SQUASHFS_SWAP(value, p, pos, tbits, SHIFT) {\ -+ b_pos = pos % 8;\ -+ val = 0;\ -+ s = (unsigned char *)p + (pos / 8);\ -+ d = ((unsigned char *) &val) + 7;\ -+ for(bits = 0; bits < (tbits + b_pos); bits += 8) \ -+ *d-- = *s++;\ -+ value = (val >> (SHIFT))/* & ((1 << tbits) - 1)*/;\ -+} -+ -+#define SQUASHFS_MEMSET(s, d, n) memset(s, 0, n); -+ -+#endif -+#endif ---- /dev/null -+++ b/include/linux/squashfs_fs_i.h -@@ -0,0 +1,45 @@ -+#ifndef SQUASHFS_FS_I -+#define SQUASHFS_FS_I -+/* -+ * Squashfs -+ * -+ * Copyright (c) 2002, 2003, 2004, 2005, 2006 -+ * Phillip Lougher -+ * -+ * 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, -+ * 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ * -+ * squashfs_fs_i.h -+ */ -+ -+struct squashfs_inode_info { -+ long long start_block; -+ unsigned int offset; -+ union { -+ struct { -+ long long fragment_start_block; -+ unsigned int fragment_size; -+ unsigned int fragment_offset; -+ long long block_list_start; -+ } s1; -+ struct { -+ long long directory_index_start; -+ unsigned int directory_index_offset; -+ unsigned int directory_index_count; -+ unsigned int parent_inode; -+ } s2; -+ } u; -+ struct inode vfs_inode; -+}; -+#endif ---- /dev/null -+++ b/include/linux/squashfs_fs_sb.h -@@ -0,0 +1,74 @@ -+#ifndef SQUASHFS_FS_SB -+#define SQUASHFS_FS_SB -+/* -+ * Squashfs -+ * -+ * Copyright (c) 2002, 2003, 2004, 2005, 2006 -+ * Phillip Lougher -+ * -+ * 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, -+ * 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ * -+ * squashfs_fs_sb.h -+ */ -+ -+#include -+ -+struct squashfs_cache { -+ long long block; -+ int length; -+ long long next_index; -+ char *data; -+}; -+ -+struct squashfs_fragment_cache { -+ long long block; -+ int length; -+ unsigned int locked; -+ char *data; -+}; -+ -+struct squashfs_sb_info { -+ struct squashfs_super_block sblk; -+ int devblksize; -+ int devblksize_log2; -+ int swap; -+ struct squashfs_cache *block_cache; -+ struct squashfs_fragment_cache *fragment; -+ int next_cache; -+ int next_fragment; -+ int next_meta_index; -+ unsigned int *uid; -+ unsigned int *guid; -+ long long *fragment_index; -+ unsigned int *fragment_index_2; -+ unsigned int read_size; -+ char *read_data; -+ char *read_page; -+ struct semaphore read_data_mutex; -+ struct semaphore read_page_mutex; -+ struct semaphore block_cache_mutex; -+ struct semaphore fragment_mutex; -+ struct semaphore meta_index_mutex; -+ wait_queue_head_t waitq; -+ wait_queue_head_t fragment_wait_queue; -+ struct meta_index *meta_index; -+ struct inode *(*iget)(struct super_block *s, squashfs_inode_t \ -+ inode); -+ long long (*read_blocklist)(struct inode *inode, int \ -+ index, int readahead_blks, char *block_list, \ -+ unsigned short **block_p, unsigned int *bsize); -+ int (*read_fragment_index_table)(struct super_block *s); -+}; -+#endif ---- a/init/do_mounts_rd.c -+++ b/init/do_mounts_rd.c -@@ -5,6 +5,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -39,6 +40,7 @@ static int __init crd_load(int in_fd, in - * numbers could not be found. - * - * We currently check for the following magic numbers: -+ * squashfs - * minix - * ext2 - * romfs -@@ -53,6 +55,7 @@ identify_ramdisk_image(int fd, int start - struct ext2_super_block *ext2sb; - struct romfs_super_block *romfsb; - struct cramfs_super *cramfsb; -+ struct squashfs_super_block *squashfsb; - int nblocks = -1; - unsigned char *buf; - -@@ -64,6 +67,7 @@ identify_ramdisk_image(int fd, int start - ext2sb = (struct ext2_super_block *) buf; - romfsb = (struct romfs_super_block *) buf; - cramfsb = (struct cramfs_super *) buf; -+ squashfsb = (struct squashfs_super_block *) buf; - memset(buf, 0xe5, size); - - /* -@@ -101,6 +105,15 @@ identify_ramdisk_image(int fd, int start - goto done; - } - -+ /* squashfs is at block zero too */ -+ if (squashfsb->s_magic == SQUASHFS_MAGIC) { -+ printk(KERN_NOTICE -+ "RAMDISK: squashfs filesystem found at block %d\n", -+ start_block); -+ nblocks = (squashfsb->bytes_used+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS; -+ goto done; -+ } -+ - /* - * Read block 1 to test for minix and ext2 superblock - */ diff --git a/target/linux/generic-2.6/patches-2.6.24/002-lzma_decompress.patch b/target/linux/generic-2.6/patches-2.6.24/002-lzma_decompress.patch deleted file mode 100644 index 4a4e266de9..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/002-lzma_decompress.patch +++ /dev/null @@ -1,788 +0,0 @@ ---- /dev/null -+++ b/include/linux/LzmaDecode.h -@@ -0,0 +1,100 @@ -+/* -+ LzmaDecode.h -+ LZMA Decoder interface -+ -+ LZMA SDK 4.05 Copyright (c) 1999-2004 Igor Pavlov (2004-08-25) -+ http://www.7-zip.org/ -+ -+ LZMA SDK is licensed under two licenses: -+ 1) GNU Lesser General Public License (GNU LGPL) -+ 2) Common Public License (CPL) -+ It means that you can select one of these two licenses and -+ follow rules of that license. -+ -+ SPECIAL EXCEPTION: -+ Igor Pavlov, as the author of this code, expressly permits you to -+ statically or dynamically link your code (or bind by name) to the -+ interfaces of this file without subjecting your linked code to the -+ terms of the CPL or GNU LGPL. Any modifications or additions -+ to this file, however, are subject to the LGPL or CPL terms. -+*/ -+ -+#ifndef __LZMADECODE_H -+#define __LZMADECODE_H -+ -+/* #define _LZMA_IN_CB */ -+/* Use callback for input data */ -+ -+/* #define _LZMA_OUT_READ */ -+/* Use read function for output data */ -+ -+/* #define _LZMA_PROB32 */ -+/* It can increase speed on some 32-bit CPUs, -+ but memory usage will be doubled in that case */ -+ -+/* #define _LZMA_LOC_OPT */ -+/* Enable local speed optimizations inside code */ -+ -+#ifndef UInt32 -+#ifdef _LZMA_UINT32_IS_ULONG -+#define UInt32 unsigned long -+#else -+#define UInt32 unsigned int -+#endif -+#endif -+ -+#ifdef _LZMA_PROB32 -+#define CProb UInt32 -+#else -+#define CProb unsigned short -+#endif -+ -+#define LZMA_RESULT_OK 0 -+#define LZMA_RESULT_DATA_ERROR 1 -+#define LZMA_RESULT_NOT_ENOUGH_MEM 2 -+ -+#ifdef _LZMA_IN_CB -+typedef struct _ILzmaInCallback -+{ -+ int (*Read)(void *object, unsigned char **buffer, UInt32 *bufferSize); -+} ILzmaInCallback; -+#endif -+ -+#define LZMA_BASE_SIZE 1846 -+#define LZMA_LIT_SIZE 768 -+ -+/* -+bufferSize = (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp)))* sizeof(CProb) -+bufferSize += 100 in case of _LZMA_OUT_READ -+by default CProb is unsigned short, -+but if specify _LZMA_PROB_32, CProb will be UInt32(unsigned int) -+*/ -+ -+#ifdef _LZMA_OUT_READ -+int LzmaDecoderInit( -+ unsigned char *buffer, UInt32 bufferSize, -+ int lc, int lp, int pb, -+ unsigned char *dictionary, UInt32 dictionarySize, -+ #ifdef _LZMA_IN_CB -+ ILzmaInCallback *inCallback -+ #else -+ unsigned char *inStream, UInt32 inSize -+ #endif -+); -+#endif -+ -+int LzmaDecode( -+ unsigned char *buffer, -+ #ifndef _LZMA_OUT_READ -+ UInt32 bufferSize, -+ int lc, int lp, int pb, -+ #ifdef _LZMA_IN_CB -+ ILzmaInCallback *inCallback, -+ #else -+ unsigned char *inStream, UInt32 inSize, -+ #endif -+ #endif -+ unsigned char *outStream, UInt32 outSize, -+ UInt32 *outSizeProcessed); -+ -+#endif ---- /dev/null -+++ b/lib/LzmaDecode.c -@@ -0,0 +1,663 @@ -+/* -+ LzmaDecode.c -+ LZMA Decoder -+ -+ LZMA SDK 4.05 Copyright (c) 1999-2004 Igor Pavlov (2004-08-25) -+ http://www.7-zip.org/ -+ -+ LZMA SDK is licensed under two licenses: -+ 1) GNU Lesser General Public License (GNU LGPL) -+ 2) Common Public License (CPL) -+ It means that you can select one of these two licenses and -+ follow rules of that license. -+ -+ SPECIAL EXCEPTION: -+ Igor Pavlov, as the author of this code, expressly permits you to -+ statically or dynamically link your code (or bind by name) to the -+ interfaces of this file without subjecting your linked code to the -+ terms of the CPL or GNU LGPL. Any modifications or additions -+ to this file, however, are subject to the LGPL or CPL terms. -+*/ -+ -+#include -+ -+#ifndef Byte -+#define Byte unsigned char -+#endif -+ -+#define kNumTopBits 24 -+#define kTopValue ((UInt32)1 << kNumTopBits) -+ -+#define kNumBitModelTotalBits 11 -+#define kBitModelTotal (1 << kNumBitModelTotalBits) -+#define kNumMoveBits 5 -+ -+typedef struct _CRangeDecoder -+{ -+ Byte *Buffer; -+ Byte *BufferLim; -+ UInt32 Range; -+ UInt32 Code; -+ #ifdef _LZMA_IN_CB -+ ILzmaInCallback *InCallback; -+ int Result; -+ #endif -+ int ExtraBytes; -+} CRangeDecoder; -+ -+Byte RangeDecoderReadByte(CRangeDecoder *rd) -+{ -+ if (rd->Buffer == rd->BufferLim) -+ { -+ #ifdef _LZMA_IN_CB -+ UInt32 size; -+ rd->Result = rd->InCallback->Read(rd->InCallback, &rd->Buffer, &size); -+ rd->BufferLim = rd->Buffer + size; -+ if (size == 0) -+ #endif -+ { -+ rd->ExtraBytes = 1; -+ return 0xFF; -+ } -+ } -+ return (*rd->Buffer++); -+} -+ -+/* #define ReadByte (*rd->Buffer++) */ -+#define ReadByte (RangeDecoderReadByte(rd)) -+ -+void RangeDecoderInit(CRangeDecoder *rd, -+ #ifdef _LZMA_IN_CB -+ ILzmaInCallback *inCallback -+ #else -+ Byte *stream, UInt32 bufferSize -+ #endif -+ ) -+{ -+ int i; -+ #ifdef _LZMA_IN_CB -+ rd->InCallback = inCallback; -+ rd->Buffer = rd->BufferLim = 0; -+ #else -+ rd->Buffer = stream; -+ rd->BufferLim = stream + bufferSize; -+ #endif -+ rd->ExtraBytes = 0; -+ rd->Code = 0; -+ rd->Range = (0xFFFFFFFF); -+ for(i = 0; i < 5; i++) -+ rd->Code = (rd->Code << 8) | ReadByte; -+} -+ -+#define RC_INIT_VAR UInt32 range = rd->Range; UInt32 code = rd->Code; -+#define RC_FLUSH_VAR rd->Range = range; rd->Code = code; -+#define RC_NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | ReadByte; } -+ -+UInt32 RangeDecoderDecodeDirectBits(CRangeDecoder *rd, int numTotalBits) -+{ -+ RC_INIT_VAR -+ UInt32 result = 0; -+ int i; -+ for (i = numTotalBits; i > 0; i--) -+ { -+ /* UInt32 t; */ -+ range >>= 1; -+ -+ result <<= 1; -+ if (code >= range) -+ { -+ code -= range; -+ result |= 1; -+ } -+ /* -+ t = (code - range) >> 31; -+ t &= 1; -+ code -= range & (t - 1); -+ result = (result + result) | (1 - t); -+ */ -+ RC_NORMALIZE -+ } -+ RC_FLUSH_VAR -+ return result; -+} -+ -+int RangeDecoderBitDecode(CProb *prob, CRangeDecoder *rd) -+{ -+ UInt32 bound = (rd->Range >> kNumBitModelTotalBits) * *prob; -+ if (rd->Code < bound) -+ { -+ rd->Range = bound; -+ *prob += (kBitModelTotal - *prob) >> kNumMoveBits; -+ if (rd->Range < kTopValue) -+ { -+ rd->Code = (rd->Code << 8) | ReadByte; -+ rd->Range <<= 8; -+ } -+ return 0; -+ } -+ else -+ { -+ rd->Range -= bound; -+ rd->Code -= bound; -+ *prob -= (*prob) >> kNumMoveBits; -+ if (rd->Range < kTopValue) -+ { -+ rd->Code = (rd->Code << 8) | ReadByte; -+ rd->Range <<= 8; -+ } -+ return 1; -+ } -+} -+ -+#define RC_GET_BIT2(prob, mi, A0, A1) \ -+ UInt32 bound = (range >> kNumBitModelTotalBits) * *prob; \ -+ if (code < bound) \ -+ { A0; range = bound; *prob += (kBitModelTotal - *prob) >> kNumMoveBits; mi <<= 1; } \ -+ else \ -+ { A1; range -= bound; code -= bound; *prob -= (*prob) >> kNumMoveBits; mi = (mi + mi) + 1; } \ -+ RC_NORMALIZE -+ -+#define RC_GET_BIT(prob, mi) RC_GET_BIT2(prob, mi, ; , ;) -+ -+int RangeDecoderBitTreeDecode(CProb *probs, int numLevels, CRangeDecoder *rd) -+{ -+ int mi = 1; -+ int i; -+ #ifdef _LZMA_LOC_OPT -+ RC_INIT_VAR -+ #endif -+ for(i = numLevels; i > 0; i--) -+ { -+ #ifdef _LZMA_LOC_OPT -+ CProb *prob = probs + mi; -+ RC_GET_BIT(prob, mi) -+ #else -+ mi = (mi + mi) + RangeDecoderBitDecode(probs + mi, rd); -+ #endif -+ } -+ #ifdef _LZMA_LOC_OPT -+ RC_FLUSH_VAR -+ #endif -+ return mi - (1 << numLevels); -+} -+ -+int RangeDecoderReverseBitTreeDecode(CProb *probs, int numLevels, CRangeDecoder *rd) -+{ -+ int mi = 1; -+ int i; -+ int symbol = 0; -+ #ifdef _LZMA_LOC_OPT -+ RC_INIT_VAR -+ #endif -+ for(i = 0; i < numLevels; i++) -+ { -+ #ifdef _LZMA_LOC_OPT -+ CProb *prob = probs + mi; -+ RC_GET_BIT2(prob, mi, ; , symbol |= (1 << i)) -+ #else -+ int bit = RangeDecoderBitDecode(probs + mi, rd); -+ mi = mi + mi + bit; -+ symbol |= (bit << i); -+ #endif -+ } -+ #ifdef _LZMA_LOC_OPT -+ RC_FLUSH_VAR -+ #endif -+ return symbol; -+} -+ -+Byte LzmaLiteralDecode(CProb *probs, CRangeDecoder *rd) -+{ -+ int symbol = 1; -+ #ifdef _LZMA_LOC_OPT -+ RC_INIT_VAR -+ #endif -+ do -+ { -+ #ifdef _LZMA_LOC_OPT -+ CProb *prob = probs + symbol; -+ RC_GET_BIT(prob, symbol) -+ #else -+ symbol = (symbol + symbol) | RangeDecoderBitDecode(probs + symbol, rd); -+ #endif -+ } -+ while (symbol < 0x100); -+ #ifdef _LZMA_LOC_OPT -+ RC_FLUSH_VAR -+ #endif -+ return symbol; -+} -+ -+Byte LzmaLiteralDecodeMatch(CProb *probs, CRangeDecoder *rd, Byte matchByte) -+{ -+ int symbol = 1; -+ #ifdef _LZMA_LOC_OPT -+ RC_INIT_VAR -+ #endif -+ do -+ { -+ int bit; -+ int matchBit = (matchByte >> 7) & 1; -+ matchByte <<= 1; -+ #ifdef _LZMA_LOC_OPT -+ { -+ CProb *prob = probs + ((1 + matchBit) << 8) + symbol; -+ RC_GET_BIT2(prob, symbol, bit = 0, bit = 1) -+ } -+ #else -+ bit = RangeDecoderBitDecode(probs + ((1 + matchBit) << 8) + symbol, rd); -+ symbol = (symbol << 1) | bit; -+ #endif -+ if (matchBit != bit) -+ { -+ while (symbol < 0x100) -+ { -+ #ifdef _LZMA_LOC_OPT -+ CProb *prob = probs + symbol; -+ RC_GET_BIT(prob, symbol) -+ #else -+ symbol = (symbol + symbol) | RangeDecoderBitDecode(probs + symbol, rd); -+ #endif -+ } -+ break; -+ } -+ } -+ while (symbol < 0x100); -+ #ifdef _LZMA_LOC_OPT -+ RC_FLUSH_VAR -+ #endif -+ return symbol; -+} -+ -+#define kNumPosBitsMax 4 -+#define kNumPosStatesMax (1 << kNumPosBitsMax) -+ -+#define kLenNumLowBits 3 -+#define kLenNumLowSymbols (1 << kLenNumLowBits) -+#define kLenNumMidBits 3 -+#define kLenNumMidSymbols (1 << kLenNumMidBits) -+#define kLenNumHighBits 8 -+#define kLenNumHighSymbols (1 << kLenNumHighBits) -+ -+#define LenChoice 0 -+#define LenChoice2 (LenChoice + 1) -+#define LenLow (LenChoice2 + 1) -+#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) -+#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) -+#define kNumLenProbs (LenHigh + kLenNumHighSymbols) -+ -+int LzmaLenDecode(CProb *p, CRangeDecoder *rd, int posState) -+{ -+ if(RangeDecoderBitDecode(p + LenChoice, rd) == 0) -+ return RangeDecoderBitTreeDecode(p + LenLow + -+ (posState << kLenNumLowBits), kLenNumLowBits, rd); -+ if(RangeDecoderBitDecode(p + LenChoice2, rd) == 0) -+ return kLenNumLowSymbols + RangeDecoderBitTreeDecode(p + LenMid + -+ (posState << kLenNumMidBits), kLenNumMidBits, rd); -+ return kLenNumLowSymbols + kLenNumMidSymbols + -+ RangeDecoderBitTreeDecode(p + LenHigh, kLenNumHighBits, rd); -+} -+ -+#define kNumStates 12 -+ -+#define kStartPosModelIndex 4 -+#define kEndPosModelIndex 14 -+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) -+ -+#define kNumPosSlotBits 6 -+#define kNumLenToPosStates 4 -+ -+#define kNumAlignBits 4 -+#define kAlignTableSize (1 << kNumAlignBits) -+ -+#define kMatchMinLen 2 -+ -+#define IsMatch 0 -+#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) -+#define IsRepG0 (IsRep + kNumStates) -+#define IsRepG1 (IsRepG0 + kNumStates) -+#define IsRepG2 (IsRepG1 + kNumStates) -+#define IsRep0Long (IsRepG2 + kNumStates) -+#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) -+#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) -+#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) -+#define LenCoder (Align + kAlignTableSize) -+#define RepLenCoder (LenCoder + kNumLenProbs) -+#define Literal (RepLenCoder + kNumLenProbs) -+ -+#if Literal != LZMA_BASE_SIZE -+StopCompilingDueBUG -+#endif -+ -+#ifdef _LZMA_OUT_READ -+ -+typedef struct _LzmaVarState -+{ -+ CRangeDecoder RangeDecoder; -+ Byte *Dictionary; -+ UInt32 DictionarySize; -+ UInt32 DictionaryPos; -+ UInt32 GlobalPos; -+ UInt32 Reps[4]; -+ int lc; -+ int lp; -+ int pb; -+ int State; -+ int PreviousIsMatch; -+ int RemainLen; -+} LzmaVarState; -+ -+int LzmaDecoderInit( -+ unsigned char *buffer, UInt32 bufferSize, -+ int lc, int lp, int pb, -+ unsigned char *dictionary, UInt32 dictionarySize, -+ #ifdef _LZMA_IN_CB -+ ILzmaInCallback *inCallback -+ #else -+ unsigned char *inStream, UInt32 inSize -+ #endif -+ ) -+{ -+ LzmaVarState *vs = (LzmaVarState *)buffer; -+ CProb *p = (CProb *)(buffer + sizeof(LzmaVarState)); -+ UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + lp)); -+ UInt32 i; -+ if (bufferSize < numProbs * sizeof(CProb) + sizeof(LzmaVarState)) -+ return LZMA_RESULT_NOT_ENOUGH_MEM; -+ vs->Dictionary = dictionary; -+ vs->DictionarySize = dictionarySize; -+ vs->DictionaryPos = 0; -+ vs->GlobalPos = 0; -+ vs->Reps[0] = vs->Reps[1] = vs->Reps[2] = vs->Reps[3] = 1; -+ vs->lc = lc; -+ vs->lp = lp; -+ vs->pb = pb; -+ vs->State = 0; -+ vs->PreviousIsMatch = 0; -+ vs->RemainLen = 0; -+ dictionary[dictionarySize - 1] = 0; -+ for (i = 0; i < numProbs; i++) -+ p[i] = kBitModelTotal >> 1; -+ RangeDecoderInit(&vs->RangeDecoder, -+ #ifdef _LZMA_IN_CB -+ inCallback -+ #else -+ inStream, inSize -+ #endif -+ ); -+ return LZMA_RESULT_OK; -+} -+ -+int LzmaDecode(unsigned char *buffer, -+ unsigned char *outStream, UInt32 outSize, -+ UInt32 *outSizeProcessed) -+{ -+ LzmaVarState *vs = (LzmaVarState *)buffer; -+ CProb *p = (CProb *)(buffer + sizeof(LzmaVarState)); -+ CRangeDecoder rd = vs->RangeDecoder; -+ int state = vs->State; -+ int previousIsMatch = vs->PreviousIsMatch; -+ Byte previousByte; -+ UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3]; -+ UInt32 nowPos = 0; -+ UInt32 posStateMask = (1 << (vs->pb)) - 1; -+ UInt32 literalPosMask = (1 << (vs->lp)) - 1; -+ int lc = vs->lc; -+ int len = vs->RemainLen; -+ UInt32 globalPos = vs->GlobalPos; -+ -+ Byte *dictionary = vs->Dictionary; -+ UInt32 dictionarySize = vs->DictionarySize; -+ UInt32 dictionaryPos = vs->DictionaryPos; -+ -+ if (len == -1) -+ { -+ *outSizeProcessed = 0; -+ return LZMA_RESULT_OK; -+ } -+ -+ while(len > 0 && nowPos < outSize) -+ { -+ UInt32 pos = dictionaryPos - rep0; -+ if (pos >= dictionarySize) -+ pos += dictionarySize; -+ outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos]; -+ if (++dictionaryPos == dictionarySize) -+ dictionaryPos = 0; -+ len--; -+ } -+ if (dictionaryPos == 0) -+ previousByte = dictionary[dictionarySize - 1]; -+ else -+ previousByte = dictionary[dictionaryPos - 1]; -+#else -+ -+int LzmaDecode( -+ Byte *buffer, UInt32 bufferSize, -+ int lc, int lp, int pb, -+ #ifdef _LZMA_IN_CB -+ ILzmaInCallback *inCallback, -+ #else -+ unsigned char *inStream, UInt32 inSize, -+ #endif -+ unsigned char *outStream, UInt32 outSize, -+ UInt32 *outSizeProcessed) -+{ -+ UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + lp)); -+ CProb *p = (CProb *)buffer; -+ CRangeDecoder rd; -+ UInt32 i; -+ int state = 0; -+ int previousIsMatch = 0; -+ Byte previousByte = 0; -+ UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1; -+ UInt32 nowPos = 0; -+ UInt32 posStateMask = (1 << pb) - 1; -+ UInt32 literalPosMask = (1 << lp) - 1; -+ int len = 0; -+ if (bufferSize < numProbs * sizeof(CProb)) -+ return LZMA_RESULT_NOT_ENOUGH_MEM; -+ for (i = 0; i < numProbs; i++) -+ p[i] = kBitModelTotal >> 1; -+ RangeDecoderInit(&rd, -+ #ifdef _LZMA_IN_CB -+ inCallback -+ #else -+ inStream, inSize -+ #endif -+ ); -+#endif -+ -+ *outSizeProcessed = 0; -+ while(nowPos < outSize) -+ { -+ int posState = (int)( -+ (nowPos -+ #ifdef _LZMA_OUT_READ -+ + globalPos -+ #endif -+ ) -+ & posStateMask); -+ #ifdef _LZMA_IN_CB -+ if (rd.Result != LZMA_RESULT_OK) -+ return rd.Result; -+ #endif -+ if (rd.ExtraBytes != 0) -+ return LZMA_RESULT_DATA_ERROR; -+ if (RangeDecoderBitDecode(p + IsMatch + (state << kNumPosBitsMax) + posState, &rd) == 0) -+ { -+ CProb *probs = p + Literal + (LZMA_LIT_SIZE * -+ ((( -+ (nowPos -+ #ifdef _LZMA_OUT_READ -+ + globalPos -+ #endif -+ ) -+ & literalPosMask) << lc) + (previousByte >> (8 - lc)))); -+ -+ if (state < 4) state = 0; -+ else if (state < 10) state -= 3; -+ else state -= 6; -+ if (previousIsMatch) -+ { -+ Byte matchByte; -+ #ifdef _LZMA_OUT_READ -+ UInt32 pos = dictionaryPos - rep0; -+ if (pos >= dictionarySize) -+ pos += dictionarySize; -+ matchByte = dictionary[pos]; -+ #else -+ matchByte = outStream[nowPos - rep0]; -+ #endif -+ previousByte = LzmaLiteralDecodeMatch(probs, &rd, matchByte); -+ previousIsMatch = 0; -+ } -+ else -+ previousByte = LzmaLiteralDecode(probs, &rd); -+ outStream[nowPos++] = previousByte; -+ #ifdef _LZMA_OUT_READ -+ dictionary[dictionaryPos] = previousByte; -+ if (++dictionaryPos == dictionarySize) -+ dictionaryPos = 0; -+ #endif -+ } -+ else -+ { -+ previousIsMatch = 1; -+ if (RangeDecoderBitDecode(p + IsRep + state, &rd) == 1) -+ { -+ if (RangeDecoderBitDecode(p + IsRepG0 + state, &rd) == 0) -+ { -+ if (RangeDecoderBitDecode(p + IsRep0Long + (state << kNumPosBitsMax) + posState, &rd) == 0) -+ { -+ #ifdef _LZMA_OUT_READ -+ UInt32 pos; -+ #endif -+ if ( -+ (nowPos -+ #ifdef _LZMA_OUT_READ -+ + globalPos -+ #endif -+ ) -+ == 0) -+ return LZMA_RESULT_DATA_ERROR; -+ state = state < 7 ? 9 : 11; -+ #ifdef _LZMA_OUT_READ -+ pos = dictionaryPos - rep0; -+ if (pos >= dictionarySize) -+ pos += dictionarySize; -+ previousByte = dictionary[pos]; -+ dictionary[dictionaryPos] = previousByte; -+ if (++dictionaryPos == dictionarySize) -+ dictionaryPos = 0; -+ #else -+ previousByte = outStream[nowPos - rep0]; -+ #endif -+ outStream[nowPos++] = previousByte; -+ continue; -+ } -+ } -+ else -+ { -+ UInt32 distance; -+ if(RangeDecoderBitDecode(p + IsRepG1 + state, &rd) == 0) -+ distance = rep1; -+ else -+ { -+ if(RangeDecoderBitDecode(p + IsRepG2 + state, &rd) == 0) -+ distance = rep2; -+ else -+ { -+ distance = rep3; -+ rep3 = rep2; -+ } -+ rep2 = rep1; -+ } -+ rep1 = rep0; -+ rep0 = distance; -+ } -+ len = LzmaLenDecode(p + RepLenCoder, &rd, posState); -+ state = state < 7 ? 8 : 11; -+ } -+ else -+ { -+ int posSlot; -+ rep3 = rep2; -+ rep2 = rep1; -+ rep1 = rep0; -+ state = state < 7 ? 7 : 10; -+ len = LzmaLenDecode(p + LenCoder, &rd, posState); -+ posSlot = RangeDecoderBitTreeDecode(p + PosSlot + -+ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << -+ kNumPosSlotBits), kNumPosSlotBits, &rd); -+ if (posSlot >= kStartPosModelIndex) -+ { -+ int numDirectBits = ((posSlot >> 1) - 1); -+ rep0 = ((2 | ((UInt32)posSlot & 1)) << numDirectBits); -+ if (posSlot < kEndPosModelIndex) -+ { -+ rep0 += RangeDecoderReverseBitTreeDecode( -+ p + SpecPos + rep0 - posSlot - 1, numDirectBits, &rd); -+ } -+ else -+ { -+ rep0 += RangeDecoderDecodeDirectBits(&rd, -+ numDirectBits - kNumAlignBits) << kNumAlignBits; -+ rep0 += RangeDecoderReverseBitTreeDecode(p + Align, kNumAlignBits, &rd); -+ } -+ } -+ else -+ rep0 = posSlot; -+ rep0++; -+ } -+ if (rep0 == (UInt32)(0)) -+ { -+ /* it's for stream version */ -+ len = -1; -+ break; -+ } -+ if (rep0 > nowPos -+ #ifdef _LZMA_OUT_READ -+ + globalPos -+ #endif -+ ) -+ { -+ return LZMA_RESULT_DATA_ERROR; -+ } -+ len += kMatchMinLen; -+ do -+ { -+ #ifdef _LZMA_OUT_READ -+ UInt32 pos = dictionaryPos - rep0; -+ if (pos >= dictionarySize) -+ pos += dictionarySize; -+ previousByte = dictionary[pos]; -+ dictionary[dictionaryPos] = previousByte; -+ if (++dictionaryPos == dictionarySize) -+ dictionaryPos = 0; -+ #else -+ previousByte = outStream[nowPos - rep0]; -+ #endif -+ outStream[nowPos++] = previousByte; -+ len--; -+ } -+ while(len > 0 && nowPos < outSize); -+ } -+ } -+ -+ #ifdef _LZMA_OUT_READ -+ vs->RangeDecoder = rd; -+ vs->DictionaryPos = dictionaryPos; -+ vs->GlobalPos = globalPos + nowPos; -+ vs->Reps[0] = rep0; -+ vs->Reps[1] = rep1; -+ vs->Reps[2] = rep2; -+ vs->Reps[3] = rep3; -+ vs->State = state; -+ vs->PreviousIsMatch = previousIsMatch; -+ vs->RemainLen = len; -+ #endif -+ -+ *outSizeProcessed = nowPos; -+ return LZMA_RESULT_OK; -+} ---- a/lib/Makefile -+++ b/lib/Makefile -@@ -14,7 +14,7 @@ lib-$(CONFIG_SMP) += cpumask.o - lib-y += kobject.o kref.o klist.o - - obj-y += div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \ -- bust_spinlocks.o hexdump.o kasprintf.o bitmap.o -+ bust_spinlocks.o hexdump.o kasprintf.o bitmap.o LzmaDecode.o - - ifeq ($(CONFIG_DEBUG_KOBJECT),y) - CFLAGS_kobject.o += -DDEBUG -@@ -64,6 +64,7 @@ obj-$(CONFIG_SMP) += percpu_counter.o - obj-$(CONFIG_AUDIT_GENERIC) += audit.o - - obj-$(CONFIG_SWIOTLB) += swiotlb.o -+ - obj-$(CONFIG_FAULT_INJECTION) += fault-inject.o - - lib-$(CONFIG_GENERIC_BUG) += bug.o diff --git a/target/linux/generic-2.6/patches-2.6.24/003-squashfs_lzma.patch b/target/linux/generic-2.6/patches-2.6.24/003-squashfs_lzma.patch deleted file mode 100644 index 9050e370ca..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/003-squashfs_lzma.patch +++ /dev/null @@ -1,107 +0,0 @@ ---- a/fs/squashfs/inode.c -+++ b/fs/squashfs/inode.c -@@ -4,6 +4,9 @@ - * Copyright (c) 2002, 2003, 2004, 2005, 2006 - * Phillip Lougher - * -+ * LZMA decompressor support added by Oleg I. Vdovikin -+ * Copyright (c) 2005 Oleg I.Vdovikin -+ * - * 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, -@@ -21,6 +24,7 @@ - * inode.c - */ - -+#define SQUASHFS_LZMA - #include - #include - #include -@@ -44,6 +48,19 @@ - - #include "squashfs.h" - -+#ifdef SQUASHFS_LZMA -+#include -+ -+/* default LZMA settings, should be in sync with mksquashfs */ -+#define LZMA_LC 3 -+#define LZMA_LP 0 -+#define LZMA_PB 2 -+ -+#define LZMA_WORKSPACE_SIZE ((LZMA_BASE_SIZE + \ -+ (LZMA_LIT_SIZE << (LZMA_LC + LZMA_LP))) * sizeof(CProb)) -+ -+#endif -+ - static void squashfs_put_super(struct super_block *); - static int squashfs_statfs(struct dentry *, struct kstatfs *); - static int squashfs_symlink_readpage(struct file *file, struct page *page); -@@ -64,7 +81,11 @@ static int squashfs_get_sb(struct file_s - const char *, void *, struct vfsmount *); - - -+#ifdef SQUASHFS_LZMA -+static unsigned char lzma_workspace[LZMA_WORKSPACE_SIZE]; -+#else - static z_stream stream; -+#endif - - static struct file_system_type squashfs_fs_type = { - .owner = THIS_MODULE, -@@ -249,6 +270,15 @@ SQSH_EXTERN unsigned int squashfs_read_d - if (compressed) { - int zlib_err; - -+#ifdef SQUASHFS_LZMA -+ if ((zlib_err = LzmaDecode(lzma_workspace, -+ LZMA_WORKSPACE_SIZE, LZMA_LC, LZMA_LP, LZMA_PB, -+ c_buffer, c_byte, buffer, msblk->read_size, &bytes)) != LZMA_RESULT_OK) -+ { -+ ERROR("lzma returned unexpected result 0x%x\n", zlib_err); -+ bytes = 0; -+ } -+#else - stream.next_in = c_buffer; - stream.avail_in = c_byte; - stream.next_out = buffer; -@@ -263,7 +293,7 @@ SQSH_EXTERN unsigned int squashfs_read_d - bytes = 0; - } else - bytes = stream.total_out; -- -+#endif - up(&msblk->read_data_mutex); - } - -@@ -2045,15 +2075,19 @@ static int __init init_squashfs_fs(void) - printk(KERN_INFO "squashfs: version 3.0 (2006/03/15) " - "Phillip Lougher\n"); - -+#ifndef SQUASHFS_LZMA - if (!(stream.workspace = vmalloc(zlib_inflate_workspacesize()))) { - ERROR("Failed to allocate zlib workspace\n"); - destroy_inodecache(); - err = -ENOMEM; - goto out; - } -+#endif - - if ((err = register_filesystem(&squashfs_fs_type))) { -+#ifndef SQUASHFS_LZMA - vfree(stream.workspace); -+#endif - destroy_inodecache(); - } - -@@ -2064,7 +2098,9 @@ out: - - static void __exit exit_squashfs_fs(void) - { -+#ifndef SQUASHFS_LZMA - vfree(stream.workspace); -+#endif - unregister_filesystem(&squashfs_fs_type); - destroy_inodecache(); - } diff --git a/target/linux/generic-2.6/patches-2.6.24/004-extra_optimization.patch b/target/linux/generic-2.6/patches-2.6.24/004-extra_optimization.patch deleted file mode 100644 index 9167a7bcc3..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/004-extra_optimization.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- a/Makefile -+++ b/Makefile -@@ -527,6 +527,9 @@ KBUILD_CFLAGS += $(call cc-optio - NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include) - CHECKFLAGS += $(NOSTDINC_FLAGS) - -+# improve gcc optimization -+CFLAGS += $(call cc-option,-funit-at-a-time,) -+ - # warn about C99 declaration after statement - KBUILD_CFLAGS += $(call cc-option,-Wdeclaration-after-statement,) - diff --git a/target/linux/generic-2.6/patches-2.6.24/005-squashfs_fix.patch b/target/linux/generic-2.6/patches-2.6.24/005-squashfs_fix.patch deleted file mode 100644 index 56b7fc2c40..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/005-squashfs_fix.patch +++ /dev/null @@ -1,19 +0,0 @@ ---- a/fs/squashfs/inode.c -+++ b/fs/squashfs/inode.c -@@ -33,6 +33,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -2125,7 +2126,7 @@ static void squashfs_destroy_inode(struc - } - - --static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags) -+static void init_once(struct kmem_cache * cachep, void *foo) - { - struct squashfs_inode_info *ei = foo; - diff --git a/target/linux/generic-2.6/patches-2.6.24/006-gcc4_inline_fix.patch b/target/linux/generic-2.6/patches-2.6.24/006-gcc4_inline_fix.patch deleted file mode 100644 index cd62e9c250..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/006-gcc4_inline_fix.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/include/asm-mips/system.h -+++ b/include/asm-mips/system.h -@@ -185,7 +185,7 @@ extern __u64 __xchg_u64_unsupported_on_3 - if something tries to do an invalid xchg(). */ - extern void __xchg_called_with_bad_pointer(void); - --static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size) -+static __always_inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size) - { - switch (size) { - case 4: diff --git a/target/linux/generic-2.6/patches-2.6.24/007-samsung_flash.patch b/target/linux/generic-2.6/patches-2.6.24/007-samsung_flash.patch deleted file mode 100644 index 1d679e0095..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/007-samsung_flash.patch +++ /dev/null @@ -1,36 +0,0 @@ ---- a/drivers/mtd/chips/cfi_cmdset_0002.c -+++ b/drivers/mtd/chips/cfi_cmdset_0002.c -@@ -51,6 +51,7 @@ - #define SST49LF040B 0x0050 - #define SST49LF008A 0x005a - #define AT49BV6416 0x00d6 -+#define MANUFACTURER_SAMSUNG 0x00ec - - static int cfi_amdstd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *); - static int cfi_amdstd_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); -@@ -294,12 +295,19 @@ struct mtd_info *cfi_cmdset_0002(struct - - if (extp->MajorVersion != '1' || - (extp->MinorVersion < '0' || extp->MinorVersion > '4')) { -- printk(KERN_ERR " Unknown Amd/Fujitsu Extended Query " -- "version %c.%c.\n", extp->MajorVersion, -- extp->MinorVersion); -- kfree(extp); -- kfree(mtd); -- return NULL; -+ if (cfi->mfr == MANUFACTURER_SAMSUNG && -+ (extp->MajorVersion == '3' && extp->MinorVersion == '3')) { -+ printk(KERN_NOTICE " Newer Samsung flash detected, " -+ "should be compatibile with Amd/Fujitsu.\n"); -+ } -+ else { -+ printk(KERN_ERR " Unknown Amd/Fujitsu Extended Query " -+ "version %c.%c.\n", extp->MajorVersion, -+ extp->MinorVersion); -+ kfree(extp); -+ kfree(mtd); -+ return NULL; -+ } - } - - /* Install our own private info structure */ diff --git a/target/linux/generic-2.6/patches-2.6.24/009-revert_intel_flash_breakage.patch b/target/linux/generic-2.6/patches-2.6.24/009-revert_intel_flash_breakage.patch deleted file mode 100644 index 0237dca55f..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/009-revert_intel_flash_breakage.patch +++ /dev/null @@ -1,169 +0,0 @@ ---- a/drivers/mtd/chips/cfi_cmdset_0001.c -+++ b/drivers/mtd/chips/cfi_cmdset_0001.c -@@ -944,7 +944,7 @@ static void __xipram xip_enable(struct m - - static int __xipram xip_wait_for_operation( - struct map_info *map, struct flchip *chip, -- unsigned long adr, unsigned int chip_op_time ) -+ unsigned long adr, int *chip_op_time ) - { - struct cfi_private *cfi = map->fldrv_priv; - struct cfi_pri_intelext *cfip = cfi->cmdset_priv; -@@ -953,7 +953,7 @@ static int __xipram xip_wait_for_operati - flstate_t oldstate, newstate; - - start = xip_currtime(); -- usec = chip_op_time * 8; -+ usec = *chip_op_time * 8; - if (usec == 0) - usec = 500000; - done = 0; -@@ -1063,8 +1063,8 @@ static int __xipram xip_wait_for_operati - #define XIP_INVAL_CACHED_RANGE(map, from, size) \ - INVALIDATE_CACHED_RANGE(map, from, size) - --#define INVAL_CACHE_AND_WAIT(map, chip, cmd_adr, inval_adr, inval_len, usec) \ -- xip_wait_for_operation(map, chip, cmd_adr, usec) -+#define INVAL_CACHE_AND_WAIT(map, chip, cmd_adr, inval_adr, inval_len, p_usec) \ -+ xip_wait_for_operation(map, chip, cmd_adr, p_usec) - - #else - -@@ -1076,65 +1076,65 @@ static int __xipram xip_wait_for_operati - static int inval_cache_and_wait_for_operation( - struct map_info *map, struct flchip *chip, - unsigned long cmd_adr, unsigned long inval_adr, int inval_len, -- unsigned int chip_op_time) -+ int *chip_op_time ) - { - struct cfi_private *cfi = map->fldrv_priv; - map_word status, status_OK = CMD(0x80); -- int chip_state = chip->state; -- unsigned int timeo, sleep_time; -+ int z, chip_state = chip->state; -+ unsigned long timeo; - - spin_unlock(chip->mutex); - if (inval_len) - INVALIDATE_CACHED_RANGE(map, inval_adr, inval_len); -+ if (*chip_op_time) -+ cfi_udelay(*chip_op_time); - spin_lock(chip->mutex); - -- /* set our timeout to 8 times the expected delay */ -- timeo = chip_op_time * 8; -- if (!timeo) -- timeo = 500000; -- sleep_time = chip_op_time / 2; -+ timeo = *chip_op_time * 8 * HZ / 1000000; -+ if (timeo < HZ/2) -+ timeo = HZ/2; -+ timeo += jiffies; - -+ z = 0; - for (;;) { -+ if (chip->state != chip_state) { -+ /* Someone's suspended the operation: sleep */ -+ DECLARE_WAITQUEUE(wait, current); -+ -+ 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 / 2); /* FIXME */ -+ spin_lock(chip->mutex); -+ continue; -+ } -+ - status = map_read(map, cmd_adr); - if (map_word_andequal(map, status, status_OK, status_OK)) - break; - -- if (!timeo) { -+ /* OK Still waiting */ -+ if (time_after(jiffies, timeo)) { - map_write(map, CMD(0x70), cmd_adr); - chip->state = FL_STATUS; - return -ETIME; - } - -- /* OK Still waiting. Drop the lock, wait a while and retry. */ -+ /* Latency issues. Drop the lock, wait a while and retry */ -+ z++; - spin_unlock(chip->mutex); -- if (sleep_time >= 1000000/HZ) { -- /* -- * Half of the normal delay still remaining -- * can be performed with a sleeping delay instead -- * of busy waiting. -- */ -- msleep(sleep_time/1000); -- timeo -= sleep_time; -- sleep_time = 1000000/HZ; -- } else { -- udelay(1); -- cond_resched(); -- timeo--; -- } -+ cfi_udelay(1); - spin_lock(chip->mutex); -- -- while (chip->state != chip_state) { -- /* Someone's suspended the operation: sleep */ -- DECLARE_WAITQUEUE(wait, current); -- set_current_state(TASK_UNINTERRUPTIBLE); -- add_wait_queue(&chip->wq, &wait); -- spin_unlock(chip->mutex); -- schedule(); -- remove_wait_queue(&chip->wq, &wait); -- spin_lock(chip->mutex); -- } - } - -+ if (!z) { -+ if (!--(*chip_op_time)) -+ *chip_op_time = 1; -+ } else if (z > 1) -+ ++(*chip_op_time); -+ - /* Done and happy. */ - chip->state = FL_STATUS; - return 0; -@@ -1143,7 +1143,8 @@ static int inval_cache_and_wait_for_oper - #endif - - #define WAIT_TIMEOUT(map, chip, adr, udelay) \ -- INVAL_CACHE_AND_WAIT(map, chip, adr, 0, 0, udelay); -+ ({ int __udelay = (udelay); \ -+ INVAL_CACHE_AND_WAIT(map, chip, adr, 0, 0, &__udelay); }) - - - static int do_point_onechip (struct map_info *map, struct flchip *chip, loff_t adr, size_t len) -@@ -1374,7 +1375,7 @@ static int __xipram do_write_oneword(str - - ret = INVAL_CACHE_AND_WAIT(map, chip, adr, - adr, map_bankwidth(map), -- chip->word_write_time); -+ &chip->word_write_time); - if (ret) { - xip_enable(map, chip, adr); - printk(KERN_ERR "%s: word write error (status timeout)\n", map->name); -@@ -1614,7 +1615,7 @@ static int __xipram do_write_buffer(stru - - ret = INVAL_CACHE_AND_WAIT(map, chip, cmd_adr, - initial_adr, initial_len, -- chip->buffer_write_time); -+ &chip->buffer_write_time); - if (ret) { - map_write(map, CMD(0x70), cmd_adr); - chip->state = FL_STATUS; -@@ -1749,7 +1750,7 @@ static int __xipram do_erase_oneblock(st - - ret = INVAL_CACHE_AND_WAIT(map, chip, adr, - adr, len, -- chip->erase_time); -+ &chip->erase_time); - if (ret) { - map_write(map, CMD(0x70), adr); - chip->state = FL_STATUS; diff --git a/target/linux/generic-2.6/patches-2.6.24/010-disable_old_squashfs_compatibility.patch b/target/linux/generic-2.6/patches-2.6.24/010-disable_old_squashfs_compatibility.patch deleted file mode 100644 index 01e27573bc..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/010-disable_old_squashfs_compatibility.patch +++ /dev/null @@ -1,19 +0,0 @@ ---- a/fs/squashfs/Makefile -+++ b/fs/squashfs/Makefile -@@ -4,4 +4,3 @@ - - obj-$(CONFIG_SQUASHFS) += squashfs.o - squashfs-y += inode.o --squashfs-y += squashfs2_0.o ---- a/fs/squashfs/squashfs.h -+++ b/fs/squashfs/squashfs.h -@@ -24,6 +24,9 @@ - #ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY - #undef CONFIG_SQUASHFS_1_0_COMPATIBILITY - #endif -+#ifdef CONFIG_SQUASHFS_2_0_COMPATIBILITY -+#undef CONFIG_SQUASHFS_2_0_COMPATIBILITY -+#endif - - #ifdef SQUASHFS_TRACE - #define TRACE(s, args...) printk(KERN_NOTICE "SQUASHFS: "s, ## args) diff --git a/target/linux/generic-2.6/patches-2.6.24/011-mips_boot.patch b/target/linux/generic-2.6/patches-2.6.24/011-mips_boot.patch deleted file mode 100644 index 4eba9095cf..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/011-mips_boot.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/arch/mips/kernel/head.S -+++ b/arch/mips/kernel/head.S -@@ -120,6 +120,8 @@ - #endif - .endm - -+ j kernel_entry -+ nop - #ifndef CONFIG_NO_EXCEPT_FILL - /* - * Reserved space for exception handlers. diff --git a/target/linux/generic-2.6/patches-2.6.24/012-mips_cpu_tlb.patch b/target/linux/generic-2.6/patches-2.6.24/012-mips_cpu_tlb.patch deleted file mode 100644 index 0b07c30690..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/012-mips_cpu_tlb.patch +++ /dev/null @@ -1,18 +0,0 @@ ---- a/arch/mips/mm/tlbex.c -+++ b/arch/mips/mm/tlbex.c -@@ -902,7 +902,6 @@ static __init void build_tlb_write_entry - case CPU_R10000: - case CPU_R12000: - case CPU_R14000: -- case CPU_4KC: - case CPU_SB1: - case CPU_SB1A: - case CPU_4KSC: -@@ -935,6 +934,7 @@ static __init void build_tlb_write_entry - tlbw(p); - break; - -+ case CPU_4KC: - case CPU_4KEC: - case CPU_24K: - case CPU_34K: diff --git a/target/linux/generic-2.6/patches-2.6.24/013-mips_gdb_stub.patch b/target/linux/generic-2.6/patches-2.6.24/013-mips_gdb_stub.patch deleted file mode 100644 index 877fe9bd35..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/013-mips_gdb_stub.patch +++ /dev/null @@ -1,18 +0,0 @@ ---- a/arch/mips/kernel/gdb-stub.c -+++ b/arch/mips/kernel/gdb-stub.c -@@ -656,6 +656,7 @@ void set_async_breakpoint(unsigned long - *epc = (unsigned long)async_breakpoint; - } - -+#ifdef CONFIG_SMP - static void kgdb_wait(void *arg) - { - unsigned flags; -@@ -668,6 +669,7 @@ static void kgdb_wait(void *arg) - - local_irq_restore(flags); - } -+#endif - - /* - * GDB stub needs to call kgdb_wait on all processor with interrupts diff --git a/target/linux/generic-2.6/patches-2.6.24/060-block2mtd_init.patch b/target/linux/generic-2.6/patches-2.6.24/060-block2mtd_init.patch deleted file mode 100644 index f5d9b0ca8a..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/060-block2mtd_init.patch +++ /dev/null @@ -1,112 +0,0 @@ ---- a/drivers/mtd/devices/block2mtd.c -+++ b/drivers/mtd/devices/block2mtd.c -@@ -16,6 +16,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -237,10 +238,11 @@ static void block2mtd_free_device(struct - - - /* FIXME: ensure that mtd->size % erase_size == 0 */ --static struct block2mtd_dev *add_device(char *devname, int erase_size) -+static struct block2mtd_dev *add_device(char *devname, int erase_size, char *mtdname) - { - struct block_device *bdev; - struct block2mtd_dev *dev; -+ struct mtd_partition *part; - - if (!devname) - return NULL; -@@ -279,14 +281,18 @@ static struct block2mtd_dev *add_device( - - /* Setup the MTD structure */ - /* make the name contain the block device in */ -- dev->mtd.name = kmalloc(sizeof("block2mtd: ") + strlen(devname), -- GFP_KERNEL); -+ -+ if (!mtdname) -+ mtdname = devname; -+ -+ dev->mtd.name = kmalloc(strlen(mtdname) + 1, GFP_KERNEL); -+ - if (!dev->mtd.name) - goto devinit_err; -+ -+ strcpy(dev->mtd.name, mtdname); - -- sprintf(dev->mtd.name, "block2mtd: %s", devname); -- -- dev->mtd.size = dev->blkdev->bd_inode->i_size & PAGE_MASK; -+ dev->mtd.size = dev->blkdev->bd_inode->i_size & PAGE_MASK & ~(erase_size - 1); - dev->mtd.erasesize = erase_size; - dev->mtd.writesize = 1; - dev->mtd.type = MTD_RAM; -@@ -298,15 +304,18 @@ static struct block2mtd_dev *add_device( - dev->mtd.read = block2mtd_read; - dev->mtd.priv = dev; - dev->mtd.owner = THIS_MODULE; -- -- if (add_mtd_device(&dev->mtd)) { -+ -+ part = kzalloc(sizeof(struct mtd_partition), GFP_KERNEL); -+ part->name = dev->mtd.name; -+ part->offset = 0; -+ part->size = dev->mtd.size; -+ if (add_mtd_partitions(&dev->mtd, part, 1)) { - /* Device didnt get added, so free the entry */ - goto devinit_err; - } - list_add(&dev->list, &blkmtd_device_list); - INFO("mtd%d: [%s] erase_size = %dKiB [%d]", dev->mtd.index, -- dev->mtd.name + strlen("blkmtd: "), -- dev->mtd.erasesize >> 10, dev->mtd.erasesize); -+ mtdname, dev->mtd.erasesize >> 10, dev->mtd.erasesize); - return dev; - - devinit_err: -@@ -379,9 +388,9 @@ static char block2mtd_paramline[80 + 12] - - static int block2mtd_setup2(const char *val) - { -- char buf[80 + 12]; /* 80 for device, 12 for erase size */ -+ char buf[80 + 12 + 80]; /* 80 for device, 12 for erase size, 80 for name */ - char *str = buf; -- char *token[2]; -+ char *token[3]; - char *name; - size_t erase_size = PAGE_SIZE; - int i, ret; -@@ -392,7 +401,7 @@ static int block2mtd_setup2(const char * - strcpy(str, val); - kill_final_newline(str); - -- for (i = 0; i < 2; i++) -+ for (i = 0; i < 3; i++) - token[i] = strsep(&str, ","); - - if (str) -@@ -411,8 +420,10 @@ static int block2mtd_setup2(const char * - parse_err("illegal erase size"); - } - } -+ if (token[2] && (strlen(token[2]) + 1 > 80)) -+ parse_err("mtd device name too long"); - -- add_device(name, erase_size); -+ add_device(name, erase_size, token[2]); - - return 0; - } -@@ -446,7 +457,7 @@ static int block2mtd_setup(const char *v - - - module_param_call(block2mtd, block2mtd_setup, NULL, NULL, 0200); --MODULE_PARM_DESC(block2mtd, "Device to use. \"block2mtd=[,]\""); -+MODULE_PARM_DESC(block2mtd, "Device to use. \"block2mtd=[,[,]]\""); - - static int __init block2mtd_init(void) - { diff --git a/target/linux/generic-2.6/patches-2.6.24/065-rootfs_split.patch b/target/linux/generic-2.6/patches-2.6.24/065-rootfs_split.patch deleted file mode 100644 index 6916e063cf..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/065-rootfs_split.patch +++ /dev/null @@ -1,944 +0,0 @@ ---- a/drivers/mtd/Kconfig -+++ b/drivers/mtd/Kconfig -@@ -47,6 +47,16 @@ config MTD_PARTITIONS - devices. Partitioning on NFTL 'devices' is a different - that's the - 'normal' form of partitioning used on a block device. - -+config MTD_ROOTFS_ROOT_DEV -+ bool "Automatically set 'rootfs' partition to be root filesystem" -+ depends on MTD_PARTITIONS -+ default y -+ -+config MTD_ROOTFS_SPLIT -+ bool "Automatically split 'rootfs' partition for squashfs" -+ depends on MTD_PARTITIONS -+ default y -+ - config MTD_REDBOOT_PARTS - tristate "RedBoot partition table parsing" - depends on MTD_PARTITIONS ---- a/drivers/mtd/mtdpart.c -+++ b/drivers/mtd/mtdpart.c -@@ -20,6 +20,8 @@ - #include - #include - #include -+#include -+#include - - /* Our partition linked list */ - static LIST_HEAD(mtd_partitions); -@@ -39,7 +41,7 @@ struct mtd_part { - * the pointer to that structure with this macro. - */ - #define PART(x) ((struct mtd_part *)(x)) -- -+#define IS_PART(mtd) (mtd->read == part_read) - - /* - * MTD methods which simply translate the effective address and pass through -@@ -308,6 +310,312 @@ int del_mtd_partitions(struct mtd_info * - return 0; - } - -+static u_int32_t cur_offset = 0; -+static int add_one_partition(struct mtd_info *master, const struct mtd_partition *part, -+ int i, struct mtd_part **slp) -+{ -+ struct mtd_part *slave; -+ -+ /* allocate the partition structure */ -+ slave = kzalloc (sizeof(*slave), GFP_KERNEL); -+ if (!slave) { -+ printk ("memory allocation error while creating partitions for \"%s\"\n", -+ master->name); -+ del_mtd_partitions(master); -+ return -ENOMEM; -+ } -+ list_add(&slave->list, &mtd_partitions); -+ -+ /* set up the MTD object for this partition */ -+ slave->mtd.type = master->type; -+ slave->mtd.flags = master->flags & ~part->mask_flags; -+ slave->mtd.size = part->size; -+ slave->mtd.writesize = master->writesize; -+ slave->mtd.oobsize = master->oobsize; -+ slave->mtd.oobavail = master->oobavail; -+ slave->mtd.subpage_sft = master->subpage_sft; -+ -+ slave->mtd.name = part->name; -+ slave->mtd.owner = master->owner; -+ -+ slave->mtd.read = part_read; -+ slave->mtd.write = part_write; -+ slave->mtd.refresh_device = part->refresh_partition; -+ -+ if(master->point && master->unpoint){ -+ slave->mtd.point = part_point; -+ slave->mtd.unpoint = part_unpoint; -+ } -+ -+ if (master->read_oob) -+ slave->mtd.read_oob = part_read_oob; -+ if (master->write_oob) -+ slave->mtd.write_oob = part_write_oob; -+ if(master->read_user_prot_reg) -+ slave->mtd.read_user_prot_reg = part_read_user_prot_reg; -+ if(master->read_fact_prot_reg) -+ slave->mtd.read_fact_prot_reg = part_read_fact_prot_reg; -+ if(master->write_user_prot_reg) -+ slave->mtd.write_user_prot_reg = part_write_user_prot_reg; -+ if(master->lock_user_prot_reg) -+ slave->mtd.lock_user_prot_reg = part_lock_user_prot_reg; -+ if(master->get_user_prot_info) -+ slave->mtd.get_user_prot_info = part_get_user_prot_info; -+ if(master->get_fact_prot_info) -+ slave->mtd.get_fact_prot_info = part_get_fact_prot_info; -+ if (master->sync) -+ slave->mtd.sync = part_sync; -+ if (!i && master->suspend && master->resume) { -+ slave->mtd.suspend = part_suspend; -+ slave->mtd.resume = part_resume; -+ } -+ if (master->writev) -+ slave->mtd.writev = part_writev; -+ if (master->lock) -+ slave->mtd.lock = part_lock; -+ if (master->unlock) -+ slave->mtd.unlock = part_unlock; -+ if (master->block_isbad) -+ slave->mtd.block_isbad = part_block_isbad; -+ if (master->block_markbad) -+ slave->mtd.block_markbad = part_block_markbad; -+ slave->mtd.erase = part_erase; -+ slave->master = master; -+ slave->offset = part->offset; -+ slave->index = i; -+ -+ if (slave->offset == MTDPART_OFS_APPEND) -+ slave->offset = cur_offset; -+ if (slave->offset == MTDPART_OFS_NXTBLK) { -+ slave->offset = cur_offset; -+ if ((cur_offset % master->erasesize) != 0) { -+ /* Round up to next erasesize */ -+ slave->offset = ((cur_offset / master->erasesize) + 1) * master->erasesize; -+ printk(KERN_NOTICE "Moving partition %d: " -+ "0x%08x -> 0x%08x\n", i, -+ cur_offset, slave->offset); -+ } -+ } -+ if (slave->mtd.size == MTDPART_SIZ_FULL) -+ slave->mtd.size = master->size - slave->offset; -+ cur_offset = slave->offset + slave->mtd.size; -+ -+ printk (KERN_NOTICE "0x%08x-0x%08x : \"%s\"\n", slave->offset, -+ slave->offset + slave->mtd.size, slave->mtd.name); -+ -+ /* let's do some sanity checks */ -+ if (slave->offset >= master->size) { -+ /* let's register it anyway to preserve ordering */ -+ slave->offset = 0; -+ slave->mtd.size = 0; -+ printk ("mtd: partition \"%s\" is out of reach -- disabled\n", -+ part->name); -+ } -+ if (slave->offset + slave->mtd.size > master->size) { -+ slave->mtd.size = master->size - slave->offset; -+ printk ("mtd: partition \"%s\" extends beyond the end of device \"%s\" -- size truncated to %#x\n", -+ part->name, master->name, slave->mtd.size); -+ } -+ if (master->numeraseregions>1) { -+ /* Deal with variable erase size stuff */ -+ int i; -+ struct mtd_erase_region_info *regions = master->eraseregions; -+ -+ /* Find the first erase regions which is part of this partition. */ -+ for (i=0; i < master->numeraseregions && slave->offset >= regions[i].offset; i++) -+ ; -+ -+ for (i--; i < master->numeraseregions && slave->offset + slave->mtd.size > regions[i].offset; i++) { -+ if (slave->mtd.erasesize < regions[i].erasesize) { -+ slave->mtd.erasesize = regions[i].erasesize; -+ } -+ } -+ } else { -+ /* Single erase size */ -+ slave->mtd.erasesize = master->erasesize; -+ } -+ -+ if ((slave->mtd.flags & MTD_WRITEABLE) && -+ (slave->offset % slave->mtd.erasesize)) { -+ /* Doesn't start on a boundary of major erase size */ -+ /* FIXME: Let it be writable if it is on a boundary of _minor_ erase size though */ -+ slave->mtd.flags &= ~MTD_WRITEABLE; -+ printk ("mtd: partition \"%s\" doesn't start on an erase block boundary -- force read-only\n", -+ part->name); -+ } -+ if ((slave->mtd.flags & MTD_WRITEABLE) && -+ (slave->mtd.size % slave->mtd.erasesize)) { -+ slave->mtd.flags &= ~MTD_WRITEABLE; -+ printk ("mtd: partition \"%s\" doesn't end on an erase block -- force read-only\n", -+ part->name); -+ } -+ -+ slave->mtd.ecclayout = master->ecclayout; -+ if (master->block_isbad) { -+ uint32_t offs = 0; -+ -+ while(offs < slave->mtd.size) { -+ if (master->block_isbad(master, -+ offs + slave->offset)) -+ slave->mtd.ecc_stats.badblocks++; -+ offs += slave->mtd.erasesize; -+ } -+ } -+ -+ if(part->mtdp) -+ { /* store the object pointer (caller may or may not register it */ -+ *part->mtdp = &slave->mtd; -+ slave->registered = 0; -+ } -+ else -+ { -+ /* register our partition */ -+ add_mtd_device(&slave->mtd); -+ slave->registered = 1; -+ } -+ -+ if (slp) -+ *slp = slave; -+ -+ return 0; -+} -+ -+#ifdef CONFIG_MTD_ROOTFS_SPLIT -+#define ROOTFS_SPLIT_NAME "rootfs_data" -+#define ROOTFS_REMOVED_NAME "" -+static int split_squashfs(struct mtd_info *master, int offset, int *split_offset) -+{ -+ char buf[512]; -+ struct squashfs_super_block *sb = (struct squashfs_super_block *) buf; -+ int len, ret; -+ -+ ret = master->read(master, offset, sizeof(*sb), &len, buf); -+ if (ret || (len != sizeof(*sb))) { -+ printk(KERN_ALERT "split_squashfs: error occured while reading " -+ "from \"%s\"\n", master->name); -+ return -EINVAL; -+ } -+ -+ if (*((u32 *) buf) != SQUASHFS_MAGIC) { -+ printk(KERN_ALERT "split_squashfs: no squashfs found in \"%s\"\n", -+ master->name); -+ *split_offset = 0; -+ return 0; -+ } -+ -+ if (sb->bytes_used <= 0) { -+ printk(KERN_ALERT "split_squashfs: squashfs is empty in \"%s\"\n", -+ master->name); -+ *split_offset = 0; -+ return 0; -+ } -+ -+ len = (u32) sb->bytes_used; -+ len += (offset & 0x000fffff); -+ len += (master->erasesize - 1); -+ len &= ~(master->erasesize - 1); -+ len -= (offset & 0x000fffff); -+ *split_offset = offset + len; -+ -+ return 0; -+} -+ -+static int split_rootfs_data(struct mtd_info *master, struct mtd_info *rpart, struct mtd_partition *part, -+ int index) -+{ -+ struct mtd_partition *dpart; -+ struct mtd_part *slave = NULL; -+ int split_offset = 0; -+ int ret; -+ -+ ret = split_squashfs(master, part->offset, &split_offset); -+ if (ret) -+ return ret; -+ -+ if (split_offset <= 0) -+ return 0; -+ -+ dpart = kmalloc(sizeof(*part)+sizeof(ROOTFS_SPLIT_NAME)+1, GFP_KERNEL); -+ if (dpart == NULL) { -+ printk(KERN_INFO "split_squashfs: no memory for partition \"%s\"\n", -+ ROOTFS_SPLIT_NAME); -+ return -ENOMEM; -+ } -+ -+ memcpy(dpart, part, sizeof(*part)); -+ dpart->name = (unsigned char *)&dpart[1]; -+ strcpy(dpart->name, ROOTFS_SPLIT_NAME); -+ -+ dpart->size -= split_offset - dpart->offset; -+ dpart->offset = split_offset; -+ -+ if (dpart == NULL) -+ return 1; -+ -+ printk(KERN_INFO "mtd: partition \"%s\" created automatically, ofs=%X, len=%X \n", -+ ROOTFS_SPLIT_NAME, dpart->offset, dpart->size); -+ -+ ret = add_one_partition(master, dpart, index, &slave); -+ if (ret) -+ kfree(dpart); -+ else if (slave) -+ rpart->split = &slave->mtd; -+ -+ return ret; -+} -+ -+static int refresh_rootfs_split(struct mtd_info *mtd) -+{ -+ struct mtd_partition tpart; -+ struct mtd_part *part; -+ int index = 0; -+ int offset, size; -+ int ret; -+ -+ part = PART(mtd); -+ -+ /* check for the new squashfs offset first */ -+ ret = split_squashfs(part->master, part->offset, &offset); -+ if (ret) -+ return ret; -+ -+ if ((offset > 0) && !mtd->split) { -+ printk(KERN_INFO "%s: creating new split partition for \"%s\"\n", __func__, mtd->name); -+ /* if we don't have a rootfs split partition, create a new one */ -+ tpart.name = mtd->name; -+ tpart.size = mtd->size; -+ tpart.offset = part->offset; -+ -+ /* find the index of the last partition */ -+ if (!list_empty(&mtd_partitions)) -+ index = list_first_entry(&mtd_partitions, struct mtd_part, list)->index + 1; -+ -+ return split_rootfs_data(part->master, &part->mtd, &tpart, index); -+ } else if ((offset > 0) && mtd->split) { -+ /* update the offsets of the existing partition */ -+ size = mtd->size + part->offset - offset; -+ -+ part = PART(mtd->split); -+ part->offset = offset; -+ part->mtd.size = size; -+ printk(KERN_INFO "%s: %s partition \"" ROOTFS_SPLIT_NAME "\", offset: 0x%06x (0x%06x)\n", -+ __func__, (!strcmp(part->mtd.name, ROOTFS_SPLIT_NAME) ? "updating" : "creating"), -+ part->offset, part->mtd.size); -+ strcpy(part->mtd.name, ROOTFS_SPLIT_NAME); -+ } else if ((offset <= 0) && mtd->split) { -+ printk(KERN_INFO "%s: removing partition \"%s\"\n", __func__, mtd->split->name); -+ -+ /* mark existing partition as removed */ -+ part = PART(mtd->split); -+ strcpy(part->mtd.name, ROOTFS_REMOVED_NAME); -+ part->offset = 0; -+ part->mtd.size = 0; -+ } -+ -+ return 0; -+} -+#endif /* CONFIG_MTD_ROOTFS_SPLIT */ -+ - /* - * This function, given a master MTD object and a partition table, creates - * and registers slave MTD objects which are bound to the master according to -@@ -320,168 +628,31 @@ int add_mtd_partitions(struct mtd_info * - int nbparts) - { - struct mtd_part *slave; -- u_int32_t cur_offset = 0; -- int i; -+ struct mtd_partition *part; -+ int i, j, ret = 0; - - printk (KERN_NOTICE "Creating %d MTD partitions on \"%s\":\n", nbparts, master->name); - -- for (i = 0; i < nbparts; i++) { -- -- /* allocate the partition structure */ -- slave = kzalloc (sizeof(*slave), GFP_KERNEL); -- if (!slave) { -- printk ("memory allocation error while creating partitions for \"%s\"\n", -- master->name); -- del_mtd_partitions(master); -- return -ENOMEM; -- } -- list_add(&slave->list, &mtd_partitions); -- -- /* set up the MTD object for this partition */ -- slave->mtd.type = master->type; -- slave->mtd.flags = master->flags & ~parts[i].mask_flags; -- slave->mtd.size = parts[i].size; -- slave->mtd.writesize = master->writesize; -- slave->mtd.oobsize = master->oobsize; -- slave->mtd.oobavail = master->oobavail; -- slave->mtd.subpage_sft = master->subpage_sft; -- -- slave->mtd.name = parts[i].name; -- slave->mtd.owner = master->owner; -- -- slave->mtd.read = part_read; -- slave->mtd.write = part_write; -- -- if(master->point && master->unpoint){ -- slave->mtd.point = part_point; -- slave->mtd.unpoint = part_unpoint; -- } -- -- if (master->read_oob) -- slave->mtd.read_oob = part_read_oob; -- if (master->write_oob) -- slave->mtd.write_oob = part_write_oob; -- if(master->read_user_prot_reg) -- slave->mtd.read_user_prot_reg = part_read_user_prot_reg; -- if(master->read_fact_prot_reg) -- slave->mtd.read_fact_prot_reg = part_read_fact_prot_reg; -- if(master->write_user_prot_reg) -- slave->mtd.write_user_prot_reg = part_write_user_prot_reg; -- if(master->lock_user_prot_reg) -- slave->mtd.lock_user_prot_reg = part_lock_user_prot_reg; -- if(master->get_user_prot_info) -- slave->mtd.get_user_prot_info = part_get_user_prot_info; -- if(master->get_fact_prot_info) -- slave->mtd.get_fact_prot_info = part_get_fact_prot_info; -- if (master->sync) -- slave->mtd.sync = part_sync; -- if (!i && master->suspend && master->resume) { -- slave->mtd.suspend = part_suspend; -- slave->mtd.resume = part_resume; -- } -- if (master->writev) -- slave->mtd.writev = part_writev; -- if (master->lock) -- slave->mtd.lock = part_lock; -- if (master->unlock) -- slave->mtd.unlock = part_unlock; -- if (master->block_isbad) -- slave->mtd.block_isbad = part_block_isbad; -- if (master->block_markbad) -- slave->mtd.block_markbad = part_block_markbad; -- slave->mtd.erase = part_erase; -- slave->master = master; -- slave->offset = parts[i].offset; -- slave->index = i; -- -- if (slave->offset == MTDPART_OFS_APPEND) -- slave->offset = cur_offset; -- if (slave->offset == MTDPART_OFS_NXTBLK) { -- slave->offset = cur_offset; -- if ((cur_offset % master->erasesize) != 0) { -- /* Round up to next erasesize */ -- slave->offset = ((cur_offset / master->erasesize) + 1) * master->erasesize; -- printk(KERN_NOTICE "Moving partition %d: " -- "0x%08x -> 0x%08x\n", i, -- cur_offset, slave->offset); -- } -- } -- if (slave->mtd.size == MTDPART_SIZ_FULL) -- slave->mtd.size = master->size - slave->offset; -- cur_offset = slave->offset + slave->mtd.size; -- -- printk (KERN_NOTICE "0x%08x-0x%08x : \"%s\"\n", slave->offset, -- slave->offset + slave->mtd.size, slave->mtd.name); -- -- /* let's do some sanity checks */ -- if (slave->offset >= master->size) { -- /* let's register it anyway to preserve ordering */ -- slave->offset = 0; -- slave->mtd.size = 0; -- printk ("mtd: partition \"%s\" is out of reach -- disabled\n", -- parts[i].name); -- } -- if (slave->offset + slave->mtd.size > master->size) { -- slave->mtd.size = master->size - slave->offset; -- printk ("mtd: partition \"%s\" extends beyond the end of device \"%s\" -- size truncated to %#x\n", -- parts[i].name, master->name, slave->mtd.size); -- } -- if (master->numeraseregions>1) { -- /* Deal with variable erase size stuff */ -- int i; -- struct mtd_erase_region_info *regions = master->eraseregions; -- -- /* Find the first erase regions which is part of this partition. */ -- for (i=0; i < master->numeraseregions && slave->offset >= regions[i].offset; i++) -- ; -- -- for (i--; i < master->numeraseregions && slave->offset + slave->mtd.size > regions[i].offset; i++) { -- if (slave->mtd.erasesize < regions[i].erasesize) { -- slave->mtd.erasesize = regions[i].erasesize; -- } -+ for (i = 0, j = 0; i < nbparts; i++) { -+ part = (struct mtd_partition *) &parts[i]; -+ ret = add_one_partition(master, part, j, &slave); -+ if (ret) -+ return ret; -+ j++; -+ -+ if (strcmp(part->name, "rootfs") == 0 && slave->registered) { -+#ifdef CONFIG_MTD_ROOTFS_ROOT_DEV -+ if (ROOT_DEV == 0) { -+ printk(KERN_NOTICE "mtd: partition \"rootfs\" " -+ "set to be root filesystem\n"); -+ ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, slave->mtd.index); - } -- } else { -- /* Single erase size */ -- slave->mtd.erasesize = master->erasesize; -- } -- -- if ((slave->mtd.flags & MTD_WRITEABLE) && -- (slave->offset % slave->mtd.erasesize)) { -- /* Doesn't start on a boundary of major erase size */ -- /* FIXME: Let it be writable if it is on a boundary of _minor_ erase size though */ -- slave->mtd.flags &= ~MTD_WRITEABLE; -- printk ("mtd: partition \"%s\" doesn't start on an erase block boundary -- force read-only\n", -- parts[i].name); -- } -- if ((slave->mtd.flags & MTD_WRITEABLE) && -- (slave->mtd.size % slave->mtd.erasesize)) { -- slave->mtd.flags &= ~MTD_WRITEABLE; -- printk ("mtd: partition \"%s\" doesn't end on an erase block -- force read-only\n", -- parts[i].name); -- } -- -- slave->mtd.ecclayout = master->ecclayout; -- if (master->block_isbad) { -- uint32_t offs = 0; -- -- while(offs < slave->mtd.size) { -- if (master->block_isbad(master, -- offs + slave->offset)) -- slave->mtd.ecc_stats.badblocks++; -- offs += slave->mtd.erasesize; -- } -- } -- -- if(parts[i].mtdp) -- { /* store the object pointer (caller may or may not register it */ -- *parts[i].mtdp = &slave->mtd; -- slave->registered = 0; -- } -- else -- { -- /* register our partition */ -- add_mtd_device(&slave->mtd); -- slave->registered = 1; -+#endif -+#ifdef CONFIG_MTD_ROOTFS_SPLIT -+ ret = split_rootfs_data(master, &slave->mtd, part, j); -+ if (ret == 0) -+ j++; -+#endif - } - } - -@@ -557,6 +728,32 @@ int parse_mtd_partitions(struct mtd_info - return ret; - } - -+int refresh_mtd_partitions(struct mtd_info *mtd) -+{ -+ int ret = 0; -+ -+ if (IS_PART(mtd)) { -+ struct mtd_part *part; -+ struct mtd_info *master; -+ -+ part = PART(mtd); -+ master = part->master; -+ if (master->refresh_device) -+ ret = master->refresh_device(master); -+ } -+ -+ if (!ret && mtd->refresh_device) -+ ret = mtd->refresh_device(mtd); -+ -+#ifdef CONFIG_MTD_ROOTFS_SPLIT -+ if (!ret && IS_PART(mtd) && !strcmp(mtd->name, "rootfs")) -+ refresh_rootfs_split(mtd); -+#endif -+ -+ return 0; -+} -+ - EXPORT_SYMBOL_GPL(parse_mtd_partitions); -+EXPORT_SYMBOL_GPL(refresh_mtd_partitions); - EXPORT_SYMBOL_GPL(register_mtd_parser); - EXPORT_SYMBOL_GPL(deregister_mtd_parser); ---- a/drivers/mtd/devices/block2mtd.c -+++ b/drivers/mtd/devices/block2mtd.c -@@ -34,6 +34,8 @@ struct block2mtd_dev { - struct block_device *blkdev; - struct mtd_info mtd; - struct mutex write_mutex; -+ rwlock_t bdev_mutex; -+ char devname[0]; - }; - - -@@ -86,6 +88,12 @@ static int block2mtd_erase(struct mtd_in - size_t len = instr->len; - int err; - -+ read_lock(&dev->bdev_mutex); -+ if (!dev->blkdev) { -+ err = -EINVAL; -+ goto done; -+ } -+ - instr->state = MTD_ERASING; - mutex_lock(&dev->write_mutex); - err = _block2mtd_erase(dev, from, len); -@@ -98,6 +106,10 @@ static int block2mtd_erase(struct mtd_in - - instr->state = MTD_ERASE_DONE; - mtd_erase_callback(instr); -+ -+done: -+ read_unlock(&dev->bdev_mutex); -+ - return err; - } - -@@ -109,10 +121,14 @@ static int block2mtd_read(struct mtd_inf - struct page *page; - int index = from >> PAGE_SHIFT; - int offset = from & (PAGE_SIZE-1); -- int cpylen; -+ int cpylen, err = 0; -+ -+ read_lock(&dev->bdev_mutex); -+ if (!dev->blkdev || (from > mtd->size)) { -+ err = -EINVAL; -+ goto done; -+ } - -- if (from > mtd->size) -- return -EINVAL; - if (from + len > mtd->size) - len = mtd->size - from; - -@@ -127,10 +143,14 @@ static int block2mtd_read(struct mtd_inf - len = len - cpylen; - - page = page_read(dev->blkdev->bd_inode->i_mapping, index); -- if (!page) -- return -ENOMEM; -- if (IS_ERR(page)) -- return PTR_ERR(page); -+ if (!page) { -+ err = -ENOMEM; -+ goto done; -+ } -+ if (IS_ERR(page)) { -+ err = PTR_ERR(page); -+ goto done; -+ } - - memcpy(buf, page_address(page) + offset, cpylen); - page_cache_release(page); -@@ -141,7 +161,10 @@ static int block2mtd_read(struct mtd_inf - offset = 0; - index++; - } -- return 0; -+ -+done: -+ read_unlock(&dev->bdev_mutex); -+ return err; - } - - -@@ -193,12 +216,22 @@ static int block2mtd_write(struct mtd_in - size_t *retlen, const u_char *buf) - { - struct block2mtd_dev *dev = mtd->priv; -- int err; -+ int err = 0; -+ -+ read_lock(&dev->bdev_mutex); -+ if (!dev->blkdev) { -+ err = -EINVAL; -+ goto done; -+ } - - if (!len) -- return 0; -- if (to >= mtd->size) -- return -ENOSPC; -+ goto done; -+ -+ if (to >= mtd->size) { -+ err = -ENOSPC; -+ goto done; -+ } -+ - if (to + len > mtd->size) - len = mtd->size - to; - -@@ -207,6 +240,9 @@ static int block2mtd_write(struct mtd_in - mutex_unlock(&dev->write_mutex); - if (err > 0) - err = 0; -+ -+done: -+ read_unlock(&dev->bdev_mutex); - return err; - } - -@@ -215,51 +251,29 @@ static int block2mtd_write(struct mtd_in - static void block2mtd_sync(struct mtd_info *mtd) - { - struct block2mtd_dev *dev = mtd->priv; -- sync_blockdev(dev->blkdev); -- return; --} -- -- --static void block2mtd_free_device(struct block2mtd_dev *dev) --{ -- if (!dev) -- return; -- -- kfree(dev->mtd.name); - -- if (dev->blkdev) { -- invalidate_mapping_pages(dev->blkdev->bd_inode->i_mapping, -- 0, -1); -- close_bdev_excl(dev->blkdev); -- } -+ read_lock(&dev->bdev_mutex); -+ if (dev->blkdev) -+ sync_blockdev(dev->blkdev); -+ read_unlock(&dev->bdev_mutex); - -- kfree(dev); -+ return; - } - - --/* FIXME: ensure that mtd->size % erase_size == 0 */ --static struct block2mtd_dev *add_device(char *devname, int erase_size, char *mtdname) -+static int _open_bdev(struct block2mtd_dev *dev) - { - struct block_device *bdev; -- struct block2mtd_dev *dev; -- struct mtd_partition *part; -- -- if (!devname) -- return NULL; -- -- dev = kzalloc(sizeof(struct block2mtd_dev), GFP_KERNEL); -- if (!dev) -- return NULL; - - /* Get a handle on the device */ -- bdev = open_bdev_excl(devname, O_RDWR, NULL); -+ bdev = open_bdev_excl(dev->devname, O_RDWR, NULL); - #ifndef MODULE - if (IS_ERR(bdev)) { - - /* We might not have rootfs mounted at this point. Try - to resolve the device name by other means. */ - -- dev_t devt = name_to_dev_t(devname); -+ dev_t devt = name_to_dev_t(dev->devname); - if (devt) { - bdev = open_by_devnum(devt, FMODE_WRITE | FMODE_READ); - } -@@ -267,17 +281,96 @@ static struct block2mtd_dev *add_device( - #endif - - if (IS_ERR(bdev)) { -- ERROR("error: cannot open device %s", devname); -- goto devinit_err; -+ ERROR("error: cannot open device %s", dev->devname); -+ return 1; - } - dev->blkdev = bdev; - - if (MAJOR(bdev->bd_dev) == MTD_BLOCK_MAJOR) { - ERROR("attempting to use an MTD device as a block device"); -- goto devinit_err; -+ return 1; - } - -+ return 0; -+} -+ -+static void _close_bdev(struct block2mtd_dev *dev) -+{ -+ struct block_device *bdev; -+ -+ if (!dev->blkdev) -+ return; -+ -+ bdev = dev->blkdev; -+ invalidate_mapping_pages(dev->blkdev->bd_inode->i_mapping, 0, -1); -+ close_bdev_excl(dev->blkdev); -+ dev->blkdev = NULL; -+} -+ -+static void block2mtd_free_device(struct block2mtd_dev *dev) -+{ -+ if (!dev) -+ return; -+ -+ kfree(dev->mtd.name); -+ _close_bdev(dev); -+ kfree(dev); -+} -+ -+ -+static int block2mtd_refresh(struct mtd_info *mtd) -+{ -+ struct block2mtd_dev *dev = mtd->priv; -+ struct block_device *bdev; -+ dev_t devt; -+ int err = 0; -+ -+ /* no other mtd function can run at this point */ -+ write_lock(&dev->bdev_mutex); -+ -+ /* get the device number for the whole disk */ -+ devt = MKDEV(MAJOR(dev->blkdev->bd_dev), 0); -+ -+ /* close the old block device */ -+ _close_bdev(dev); -+ -+ /* open the whole disk, issue a partition rescan, then */ -+ bdev = open_by_devnum(devt, FMODE_WRITE | FMODE_READ); -+ if (!bdev || !bdev->bd_disk) -+ err = -EINVAL; -+ else { -+ err = rescan_partitions(bdev->bd_disk, bdev); -+ } -+ if (bdev) -+ close_bdev_excl(bdev); -+ -+ /* try to open the partition block device again */ -+ _open_bdev(dev); -+ write_unlock(&dev->bdev_mutex); -+ -+ return err; -+} -+ -+/* FIXME: ensure that mtd->size % erase_size == 0 */ -+static struct block2mtd_dev *add_device(char *devname, int erase_size, char *mtdname) -+{ -+ struct block2mtd_dev *dev; -+ struct mtd_partition *part; -+ -+ if (!devname) -+ return NULL; -+ -+ dev = kzalloc(sizeof(struct block2mtd_dev) + strlen(devname) + 1, GFP_KERNEL); -+ if (!dev) -+ return NULL; -+ -+ strcpy(dev->devname, devname); -+ -+ if (_open_bdev(dev)) -+ goto devinit_err; -+ - mutex_init(&dev->write_mutex); -+ rwlock_init(&dev->bdev_mutex); - - /* Setup the MTD structure */ - /* make the name contain the block device in */ -@@ -304,6 +397,7 @@ static struct block2mtd_dev *add_device( - dev->mtd.read = block2mtd_read; - dev->mtd.priv = dev; - dev->mtd.owner = THIS_MODULE; -+ dev->mtd.refresh_device = block2mtd_refresh; - - part = kzalloc(sizeof(struct mtd_partition), GFP_KERNEL); - part->name = dev->mtd.name; ---- a/drivers/mtd/mtdchar.c -+++ b/drivers/mtd/mtdchar.c -@@ -17,6 +17,7 @@ - - #include - #include -+#include - - #include - -@@ -754,6 +755,13 @@ static int mtd_ioctl(struct inode *inode - file->f_pos = 0; - break; - } -+#ifdef CONFIG_MTD_PARTITIONS -+ case MTDREFRESH: -+ { -+ ret = refresh_mtd_partitions(mtd); -+ break; -+ } -+#endif - - default: - ret = -ENOTTY; ---- a/include/linux/mtd/mtd.h -+++ b/include/linux/mtd/mtd.h -@@ -98,6 +98,7 @@ struct mtd_oob_ops { - uint8_t *oobbuf; - }; - -+struct mtd_info; - struct mtd_info { - u_char type; - u_int32_t flags; -@@ -202,6 +203,9 @@ struct mtd_info { - struct module *owner; - int usecount; - -+ int (*refresh_device)(struct mtd_info *mtd); -+ struct mtd_info *split; -+ - /* If the driver is something smart, like UBI, it may need to maintain - * its own reference counting. The below functions are only for driver. - * The driver may register its callbacks. These callbacks are not ---- a/include/linux/mtd/partitions.h -+++ b/include/linux/mtd/partitions.h -@@ -36,6 +36,7 @@ - * erasesize aligned (e.g. use MTDPART_OFS_NEXTBLK). - */ - -+struct mtd_partition; - struct mtd_partition { - char *name; /* identifier string */ - u_int32_t size; /* partition size */ -@@ -43,6 +44,7 @@ struct mtd_partition { - u_int32_t mask_flags; /* master MTD flags to mask out for this partition */ - struct nand_ecclayout *ecclayout; /* out of band layout for this partition (NAND only)*/ - struct mtd_info **mtdp; /* pointer to store the MTD object */ -+ int (*refresh_partition)(struct mtd_info *); - }; - - #define MTDPART_OFS_NXTBLK (-2) -@@ -52,6 +54,7 @@ struct mtd_partition { - - int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, int); - int del_mtd_partitions(struct mtd_info *); -+int refresh_mtd_partitions(struct mtd_info *); - - /* - * Functions dealing with the various ways of partitioning the space ---- a/include/mtd/mtd-abi.h -+++ b/include/mtd/mtd-abi.h -@@ -95,6 +95,7 @@ struct otp_info { - #define ECCGETLAYOUT _IOR('M', 17, struct nand_ecclayout) - #define ECCGETSTATS _IOR('M', 18, struct mtd_ecc_stats) - #define MTDFILEMODE _IO('M', 19) -+#define MTDREFRESH _IO('M', 23) - - /* - * Obsolete legacy interface. Keep it in order not to break userspace diff --git a/target/linux/generic-2.6/patches-2.6.24/070-redboot_space.patch b/target/linux/generic-2.6/patches-2.6.24/070-redboot_space.patch deleted file mode 100644 index 940536dff9..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/070-redboot_space.patch +++ /dev/null @@ -1,30 +0,0 @@ ---- a/drivers/mtd/redboot.c -+++ b/drivers/mtd/redboot.c -@@ -236,14 +236,21 @@ static int parse_redboot_partitions(stru - #endif - names += strlen(names)+1; - --#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED - 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 = nullname; -- } -+ if (!strcmp(parts[i].name, "rootfs")) { -+ parts[i].size = fl->next->img->flash_base; -+ parts[i].size &= ~(master->erasesize - 1); -+ parts[i].size -= parts[i].offset; -+#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED -+ nrparts--; -+ } else { -+ 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 = nullname; - #endif -+ } -+ } - tmp_fl = fl; - fl = fl->next; - kfree(tmp_fl); diff --git a/target/linux/generic-2.6/patches-2.6.24/080-mtd_plat_nand_chip_fixup.patch b/target/linux/generic-2.6/patches-2.6.24/080-mtd_plat_nand_chip_fixup.patch deleted file mode 100644 index 61f2806bda..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/080-mtd_plat_nand_chip_fixup.patch +++ /dev/null @@ -1,32 +0,0 @@ ---- a/include/linux/mtd/nand.h -+++ b/include/linux/mtd/nand.h -@@ -573,6 +573,7 @@ struct platform_nand_chip { - int chip_delay; - unsigned int options; - const char **part_probe_types; -+ int (*chip_fixup)(struct mtd_info *mtd); - void *priv; - }; - ---- a/drivers/mtd/nand/plat_nand.c -+++ b/drivers/mtd/nand/plat_nand.c -@@ -70,7 +70,18 @@ static int __init plat_nand_probe(struct - platform_set_drvdata(pdev, data); - - /* Scan to find existance of the device */ -- if (nand_scan(&data->mtd, 1)) { -+ if (nand_scan_ident(&data->mtd, 1)) { -+ res = -ENXIO; -+ goto out; -+ } -+ -+ if (pdata->chip.chip_fixup) { -+ res = pdata->chip.chip_fixup(&data->mtd); -+ if (res) -+ goto out; -+ } -+ -+ if (nand_scan_tail(&data->mtd)) { - res = -ENXIO; - goto out; - } diff --git a/target/linux/generic-2.6/patches-2.6.24/100-netfilter_layer7_2.17.patch b/target/linux/generic-2.6/patches-2.6.24/100-netfilter_layer7_2.17.patch deleted file mode 100644 index 9315486308..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/100-netfilter_layer7_2.17.patch +++ /dev/null @@ -1,2101 +0,0 @@ ---- a/net/netfilter/Kconfig -+++ b/net/netfilter/Kconfig -@@ -633,6 +633,27 @@ config NETFILTER_XT_MATCH_STATE - - To compile it as a module, choose M here. If unsure, say N. - -+config NETFILTER_XT_MATCH_LAYER7 -+ tristate '"layer7" match support' -+ depends on NETFILTER_XTABLES -+ depends on EXPERIMENTAL && (IP_NF_CONNTRACK || NF_CONNTRACK) -+ depends on NF_CT_ACCT -+ help -+ Say Y if you want to be able to classify connections (and their -+ packets) based on regular expression matching of their application -+ layer data. This is one way to classify applications such as -+ peer-to-peer filesharing systems that do not always use the same -+ port. -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config NETFILTER_XT_MATCH_LAYER7_DEBUG -+ bool 'Layer 7 debugging output' -+ depends on NETFILTER_XT_MATCH_LAYER7 -+ help -+ Say Y to get lots of debugging output. -+ -+ - config NETFILTER_XT_MATCH_STATISTIC - tristate '"statistic" match support' - depends on NETFILTER_XTABLES ---- a/net/netfilter/Makefile -+++ b/net/netfilter/Makefile -@@ -73,6 +73,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_QUOTA) + - obj-$(CONFIG_NETFILTER_XT_MATCH_REALM) += xt_realm.o - obj-$(CONFIG_NETFILTER_XT_MATCH_SCTP) += xt_sctp.o - obj-$(CONFIG_NETFILTER_XT_MATCH_STATE) += xt_state.o -+obj-$(CONFIG_NETFILTER_XT_MATCH_LAYER7) += xt_layer7.o - obj-$(CONFIG_NETFILTER_XT_MATCH_STATISTIC) += xt_statistic.o - obj-$(CONFIG_NETFILTER_XT_MATCH_STRING) += xt_string.o - obj-$(CONFIG_NETFILTER_XT_MATCH_TCPMSS) += xt_tcpmss.o ---- /dev/null -+++ b/net/netfilter/xt_layer7.c -@@ -0,0 +1,634 @@ -+/* -+ Kernel module to match application layer (OSI layer 7) data in connections. -+ -+ http://l7-filter.sf.net -+ -+ (C) 2003, 2004, 2005, 2006, 2007 Matthew Strait and Ethan Sommer. -+ -+ 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. -+ http://www.gnu.org/licenses/gpl.txt -+ -+ Based on ipt_string.c (C) 2000 Emmanuel Roger , -+ xt_helper.c (C) 2002 Harald Welte and cls_layer7.c (C) 2003 Matthew Strait, -+ Ethan Sommer, Justin Levandoski. -+*/ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "regexp/regexp.c" -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Matthew Strait , Ethan Sommer "); -+MODULE_DESCRIPTION("iptables application layer match module"); -+MODULE_ALIAS("ipt_layer7"); -+MODULE_VERSION("2.17"); -+ -+static int maxdatalen = 2048; // this is the default -+module_param(maxdatalen, int, 0444); -+MODULE_PARM_DESC(maxdatalen, "maximum bytes of data looked at by l7-filter"); -+#ifdef CONFIG_NETFILTER_XT_MATCH_LAYER7_DEBUG -+ #define DPRINTK(format,args...) printk(format,##args) -+#else -+ #define DPRINTK(format,args...) -+#endif -+ -+#define TOTAL_PACKETS master_conntrack->counters[IP_CT_DIR_ORIGINAL].packets + \ -+ master_conntrack->counters[IP_CT_DIR_REPLY].packets -+ -+/* Number of packets whose data we look at. -+This can be modified through /proc/net/layer7_numpackets */ -+static int num_packets = 10; -+ -+static struct pattern_cache { -+ char * regex_string; -+ regexp * pattern; -+ struct pattern_cache * next; -+} * first_pattern_cache = NULL; -+ -+DEFINE_SPINLOCK(l7_lock); -+ -+#ifdef CONFIG_IP_NF_MATCH_LAYER7_DEBUG -+/* Converts an unfriendly string into a friendly one by -+replacing unprintables with periods and all whitespace with " ". */ -+static char * friendly_print(unsigned char * s) -+{ -+ char * f = kmalloc(strlen(s) + 1, GFP_ATOMIC); -+ int i; -+ -+ if(!f) { -+ if (net_ratelimit()) -+ printk(KERN_ERR "layer7: out of memory in " -+ "friendly_print, bailing.\n"); -+ return NULL; -+ } -+ -+ for(i = 0; i < strlen(s); i++){ -+ if(isprint(s[i]) && s[i] < 128) f[i] = s[i]; -+ else if(isspace(s[i])) f[i] = ' '; -+ else f[i] = '.'; -+ } -+ f[i] = '\0'; -+ return f; -+} -+ -+static char dec2hex(int i) -+{ -+ switch (i) { -+ case 0 ... 9: -+ return (i + '0'); -+ break; -+ case 10 ... 15: -+ return (i - 10 + 'a'); -+ break; -+ default: -+ if (net_ratelimit()) -+ printk("layer7: Problem in dec2hex\n"); -+ return '\0'; -+ } -+} -+ -+static char * hex_print(unsigned char * s) -+{ -+ char * g = kmalloc(strlen(s)*3 + 1, GFP_ATOMIC); -+ int i; -+ -+ if(!g) { -+ if (net_ratelimit()) -+ printk(KERN_ERR "layer7: out of memory in hex_print, " -+ "bailing.\n"); -+ return NULL; -+ } -+ -+ for(i = 0; i < strlen(s); i++) { -+ g[i*3 ] = dec2hex(s[i]/16); -+ g[i*3 + 1] = dec2hex(s[i]%16); -+ g[i*3 + 2] = ' '; -+ } -+ g[i*3] = '\0'; -+ -+ return g; -+} -+#endif // DEBUG -+ -+/* Use instead of regcomp. As we expect to be seeing the same regexps over and -+over again, it make sense to cache the results. */ -+static regexp * compile_and_cache(const char * regex_string, -+ const char * protocol) -+{ -+ struct pattern_cache * node = first_pattern_cache; -+ struct pattern_cache * last_pattern_cache = first_pattern_cache; -+ struct pattern_cache * tmp; -+ unsigned int len; -+ -+ while (node != NULL) { -+ if (!strcmp(node->regex_string, regex_string)) -+ return node->pattern; -+ -+ last_pattern_cache = node;/* points at the last non-NULL node */ -+ node = node->next; -+ } -+ -+ /* If we reach the end of the list, then we have not yet cached -+ the pattern for this regex. Let's do that now. -+ Be paranoid about running out of memory to avoid list corruption. */ -+ tmp = kmalloc(sizeof(struct pattern_cache), GFP_ATOMIC); -+ -+ if(!tmp) { -+ if (net_ratelimit()) -+ printk(KERN_ERR "layer7: out of memory in " -+ "compile_and_cache, bailing.\n"); -+ return NULL; -+ } -+ -+ tmp->regex_string = kmalloc(strlen(regex_string) + 1, GFP_ATOMIC); -+ tmp->pattern = kmalloc(sizeof(struct regexp), GFP_ATOMIC); -+ tmp->next = NULL; -+ -+ if(!tmp->regex_string || !tmp->pattern) { -+ if (net_ratelimit()) -+ printk(KERN_ERR "layer7: out of memory in " -+ "compile_and_cache, bailing.\n"); -+ kfree(tmp->regex_string); -+ kfree(tmp->pattern); -+ kfree(tmp); -+ return NULL; -+ } -+ -+ /* Ok. The new node is all ready now. */ -+ node = tmp; -+ -+ if(first_pattern_cache == NULL) /* list is empty */ -+ first_pattern_cache = node; /* make node the beginning */ -+ else -+ last_pattern_cache->next = node; /* attach node to the end */ -+ -+ /* copy the string and compile the regex */ -+ len = strlen(regex_string); -+ DPRINTK("About to compile this: \"%s\"\n", regex_string); -+ node->pattern = regcomp((char *)regex_string, &len); -+ if ( !node->pattern ) { -+ if (net_ratelimit()) -+ printk(KERN_ERR "layer7: Error compiling regexp " -+ "\"%s\" (%s)\n", -+ regex_string, protocol); -+ /* pattern is now cached as NULL, so we won't try again. */ -+ } -+ -+ strcpy(node->regex_string, regex_string); -+ return node->pattern; -+} -+ -+static int can_handle(const struct sk_buff *skb) -+{ -+ if(!ip_hdr(skb)) /* not IP */ -+ return 0; -+ if(ip_hdr(skb)->protocol != IPPROTO_TCP && -+ ip_hdr(skb)->protocol != IPPROTO_UDP && -+ ip_hdr(skb)->protocol != IPPROTO_ICMP) -+ return 0; -+ return 1; -+} -+ -+/* Returns offset the into the skb->data that the application data starts */ -+static int app_data_offset(const struct sk_buff *skb) -+{ -+ /* In case we are ported somewhere (ebtables?) where ip_hdr(skb) -+ isn't set, this can be gotten from 4*(skb->data[0] & 0x0f) as well. */ -+ int ip_hl = 4*ip_hdr(skb)->ihl; -+ -+ if( ip_hdr(skb)->protocol == IPPROTO_TCP ) { -+ /* 12 == offset into TCP header for the header length field. -+ Can't get this with skb->h.th->doff because the tcphdr -+ struct doesn't get set when routing (this is confirmed to be -+ true in Netfilter as well as QoS.) */ -+ int tcp_hl = 4*(skb->data[ip_hl + 12] >> 4); -+ -+ return ip_hl + tcp_hl; -+ } else if( ip_hdr(skb)->protocol == IPPROTO_UDP ) { -+ return ip_hl + 8; /* UDP header is always 8 bytes */ -+ } else if( ip_hdr(skb)->protocol == IPPROTO_ICMP ) { -+ return ip_hl + 8; /* ICMP header is 8 bytes */ -+ } else { -+ if (net_ratelimit()) -+ printk(KERN_ERR "layer7: tried to handle unknown " -+ "protocol!\n"); -+ return ip_hl + 8; /* something reasonable */ -+ } -+} -+ -+/* handles whether there's a match when we aren't appending data anymore */ -+static int match_no_append(struct nf_conn * conntrack, -+ struct nf_conn * master_conntrack, -+ enum ip_conntrack_info ctinfo, -+ enum ip_conntrack_info master_ctinfo, -+ const struct xt_layer7_info * info) -+{ -+ /* If we're in here, throw the app data away */ -+ if(master_conntrack->layer7.app_data != NULL) { -+ -+ #ifdef CONFIG_IP_NF_MATCH_LAYER7_DEBUG -+ if(!master_conntrack->layer7.app_proto) { -+ char * f = -+ friendly_print(master_conntrack->layer7.app_data); -+ char * g = -+ hex_print(master_conntrack->layer7.app_data); -+ DPRINTK("\nl7-filter gave up after %d bytes " -+ "(%d packets):\n%s\n", -+ strlen(f), TOTAL_PACKETS, f); -+ kfree(f); -+ DPRINTK("In hex: %s\n", g); -+ kfree(g); -+ } -+ #endif -+ -+ kfree(master_conntrack->layer7.app_data); -+ master_conntrack->layer7.app_data = NULL; /* don't free again */ -+ } -+ -+ if(master_conntrack->layer7.app_proto){ -+ /* Here child connections set their .app_proto (for /proc) */ -+ if(!conntrack->layer7.app_proto) { -+ conntrack->layer7.app_proto = -+ kmalloc(strlen(master_conntrack->layer7.app_proto)+1, -+ GFP_ATOMIC); -+ if(!conntrack->layer7.app_proto){ -+ if (net_ratelimit()) -+ printk(KERN_ERR "layer7: out of memory " -+ "in match_no_append, " -+ "bailing.\n"); -+ return 1; -+ } -+ strcpy(conntrack->layer7.app_proto, -+ master_conntrack->layer7.app_proto); -+ } -+ -+ return (!strcmp(master_conntrack->layer7.app_proto, -+ info->protocol)); -+ } -+ else { -+ /* If not classified, set to "unknown" to distinguish from -+ connections that are still being tested. */ -+ master_conntrack->layer7.app_proto = -+ kmalloc(strlen("unknown")+1, GFP_ATOMIC); -+ if(!master_conntrack->layer7.app_proto){ -+ if (net_ratelimit()) -+ printk(KERN_ERR "layer7: out of memory in " -+ "match_no_append, bailing.\n"); -+ return 1; -+ } -+ strcpy(master_conntrack->layer7.app_proto, "unknown"); -+ return 0; -+ } -+} -+ -+/* add the new app data to the conntrack. Return number of bytes added. */ -+static int add_data(struct nf_conn * master_conntrack, -+ char * app_data, int appdatalen) -+{ -+ int length = 0, i; -+ int oldlength = master_conntrack->layer7.app_data_len; -+ -+ /* This is a fix for a race condition by Deti Fliegl. However, I'm not -+ clear on whether the race condition exists or whether this really -+ fixes it. I might just be being dense... Anyway, if it's not really -+ a fix, all it does is waste a very small amount of time. */ -+ if(!master_conntrack->layer7.app_data) return 0; -+ -+ /* Strip nulls. Make everything lower case (our regex lib doesn't -+ do case insensitivity). Add it to the end of the current data. */ -+ for(i = 0; i < maxdatalen-oldlength-1 && -+ i < appdatalen; i++) { -+ if(app_data[i] != '\0') { -+ /* the kernel version of tolower mungs 'upper ascii' */ -+ master_conntrack->layer7.app_data[length+oldlength] = -+ isascii(app_data[i])? -+ tolower(app_data[i]) : app_data[i]; -+ length++; -+ } -+ } -+ -+ master_conntrack->layer7.app_data[length+oldlength] = '\0'; -+ master_conntrack->layer7.app_data_len = length + oldlength; -+ -+ return length; -+} -+ -+/* taken from drivers/video/modedb.c */ -+static int my_atoi(const char *s) -+{ -+ int val = 0; -+ -+ for (;; s++) { -+ switch (*s) { -+ case '0'...'9': -+ val = 10*val+(*s-'0'); -+ break; -+ default: -+ return val; -+ } -+ } -+} -+ -+/* write out num_packets to userland. */ -+static int layer7_read_proc(char* page, char ** start, off_t off, int count, -+ int* eof, void * data) -+{ -+ if(num_packets > 99 && net_ratelimit()) -+ printk(KERN_ERR "layer7: NOT REACHED. num_packets too big\n"); -+ -+ page[0] = num_packets/10 + '0'; -+ page[1] = num_packets%10 + '0'; -+ page[2] = '\n'; -+ page[3] = '\0'; -+ -+ *eof=1; -+ -+ return 3; -+} -+ -+/* Read in num_packets from userland */ -+static int layer7_write_proc(struct file* file, const char* buffer, -+ unsigned long count, void *data) -+{ -+ char * foo = kmalloc(count, GFP_ATOMIC); -+ -+ if(!foo){ -+ if (net_ratelimit()) -+ printk(KERN_ERR "layer7: out of memory, bailing. " -+ "num_packets unchanged.\n"); -+ return count; -+ } -+ -+ if(copy_from_user(foo, buffer, count)) { -+ return -EFAULT; -+ } -+ -+ -+ num_packets = my_atoi(foo); -+ kfree (foo); -+ -+ /* This has an arbitrary limit to make the math easier. I'm lazy. -+ But anyway, 99 is a LOT! If you want more, you're doing it wrong! */ -+ if(num_packets > 99) { -+ printk(KERN_WARNING "layer7: num_packets can't be > 99.\n"); -+ num_packets = 99; -+ } else if(num_packets < 1) { -+ printk(KERN_WARNING "layer7: num_packets can't be < 1.\n"); -+ num_packets = 1; -+ } -+ -+ return count; -+} -+ -+static bool -+match(const struct sk_buff *skbin, -+ const struct net_device *in, -+ const struct net_device *out, -+ const struct xt_match *match, -+ const void *matchinfo, -+ int offset, -+ unsigned int protoff, -+ bool *hotdrop) -+{ -+ /* sidestep const without getting a compiler warning... */ -+ struct sk_buff * skb = (struct sk_buff *)skbin; -+ -+ const struct xt_layer7_info * info = matchinfo; -+ enum ip_conntrack_info master_ctinfo, ctinfo; -+ struct nf_conn *master_conntrack, *conntrack; -+ unsigned char * app_data; -+ unsigned int pattern_result, appdatalen; -+ regexp * comppattern; -+ -+ /* Be paranoid/incompetent - lock the entire match function. */ -+ spin_lock_bh(&l7_lock); -+ -+ if(!can_handle(skb)){ -+ DPRINTK("layer7: This is some protocol I can't handle.\n"); -+ spin_unlock_bh(&l7_lock); -+ return info->invert; -+ } -+ -+ /* Treat parent & all its children together as one connection, except -+ for the purpose of setting conntrack->layer7.app_proto in the actual -+ connection. This makes /proc/net/ip_conntrack more satisfying. */ -+ if(!(conntrack = nf_ct_get(skb, &ctinfo)) || -+ !(master_conntrack=nf_ct_get(skb,&master_ctinfo))){ -+ DPRINTK("layer7: couldn't get conntrack.\n"); -+ spin_unlock_bh(&l7_lock); -+ return info->invert; -+ } -+ -+ /* Try to get a master conntrack (and its master etc) for FTP, etc. */ -+ while (master_ct(master_conntrack) != NULL) -+ master_conntrack = master_ct(master_conntrack); -+ -+ /* if we've classified it or seen too many packets */ -+ if(TOTAL_PACKETS > num_packets || -+ master_conntrack->layer7.app_proto) { -+ -+ pattern_result = match_no_append(conntrack, master_conntrack, -+ ctinfo, master_ctinfo, info); -+ -+ /* skb->cb[0] == seen. Don't do things twice if there are -+ multiple l7 rules. I'm not sure that using cb for this purpose -+ is correct, even though it says "put your private variables -+ there". But it doesn't look like it is being used for anything -+ else in the skbs that make it here. */ -+ skb->cb[0] = 1; /* marking it seen here's probably irrelevant */ -+ -+ spin_unlock_bh(&l7_lock); -+ return (pattern_result ^ info->invert); -+ } -+ -+ if(skb_is_nonlinear(skb)){ -+ if(skb_linearize(skb) != 0){ -+ if (net_ratelimit()) -+ printk(KERN_ERR "layer7: failed to linearize " -+ "packet, bailing.\n"); -+ spin_unlock_bh(&l7_lock); -+ return info->invert; -+ } -+ } -+ -+ /* now that the skb is linearized, it's safe to set these. */ -+ app_data = skb->data + app_data_offset(skb); -+ appdatalen = skb_tail_pointer(skb) - app_data; -+ -+ /* the return value gets checked later, when we're ready to use it */ -+ comppattern = compile_and_cache(info->pattern, info->protocol); -+ -+ /* On the first packet of a connection, allocate space for app data */ -+ if(TOTAL_PACKETS == 1 && !skb->cb[0] && -+ !master_conntrack->layer7.app_data){ -+ master_conntrack->layer7.app_data = -+ kmalloc(maxdatalen, GFP_ATOMIC); -+ if(!master_conntrack->layer7.app_data){ -+ if (net_ratelimit()) -+ printk(KERN_ERR "layer7: out of memory in " -+ "match, bailing.\n"); -+ spin_unlock_bh(&l7_lock); -+ return info->invert; -+ } -+ -+ master_conntrack->layer7.app_data[0] = '\0'; -+ } -+ -+ /* Can be here, but unallocated, if numpackets is increased near -+ the beginning of a connection */ -+ if(master_conntrack->layer7.app_data == NULL){ -+ spin_unlock_bh(&l7_lock); -+ return (info->invert); /* unmatched */ -+ } -+ -+ if(!skb->cb[0]){ -+ int newbytes; -+ newbytes = add_data(master_conntrack, app_data, appdatalen); -+ -+ if(newbytes == 0) { /* didn't add any data */ -+ skb->cb[0] = 1; -+ /* Didn't match before, not going to match now */ -+ spin_unlock_bh(&l7_lock); -+ return info->invert; -+ } -+ } -+ -+ /* If looking for "unknown", then never match. "Unknown" means that -+ we've given up; we're still trying with these packets. */ -+ if(!strcmp(info->protocol, "unknown")) { -+ pattern_result = 0; -+ /* If looking for "unset", then always match. "Unset" means that we -+ haven't yet classified the connection. */ -+ } else if(!strcmp(info->protocol, "unset")) { -+ pattern_result = 2; -+ DPRINTK("layer7: matched unset: not yet classified " -+ "(%d/%d packets)\n", TOTAL_PACKETS, num_packets); -+ /* If the regexp failed to compile, don't bother running it */ -+ } else if(comppattern && -+ regexec(comppattern, master_conntrack->layer7.app_data)){ -+ DPRINTK("layer7: matched %s\n", info->protocol); -+ pattern_result = 1; -+ } else pattern_result = 0; -+ -+ if(pattern_result == 1) { -+ master_conntrack->layer7.app_proto = -+ kmalloc(strlen(info->protocol)+1, GFP_ATOMIC); -+ if(!master_conntrack->layer7.app_proto){ -+ if (net_ratelimit()) -+ printk(KERN_ERR "layer7: out of memory in " -+ "match, bailing.\n"); -+ spin_unlock_bh(&l7_lock); -+ return (pattern_result ^ info->invert); -+ } -+ strcpy(master_conntrack->layer7.app_proto, info->protocol); -+ } else if(pattern_result > 1) { /* cleanup from "unset" */ -+ pattern_result = 1; -+ } -+ -+ /* mark the packet seen */ -+ skb->cb[0] = 1; -+ -+ spin_unlock_bh(&l7_lock); -+ return (pattern_result ^ info->invert); -+} -+ -+static bool check(const char *tablename, -+ const void *inf, -+ const struct xt_match *match, -+ void *matchinfo, -+ unsigned int hook_mask) -+ -+{ -+ // load nf_conntrack_ipv4 -+ if (nf_ct_l3proto_try_module_get(match->family) < 0) { -+ printk(KERN_WARNING "can't load conntrack support for " -+ "proto=%d\n", match->family); -+ return false; -+ } -+ return true; -+} -+ -+static void -+destroy(const struct xt_match *match, void *matchinfo) -+{ -+ nf_ct_l3proto_module_put(match->family); -+} -+ -+static struct xt_match xt_layer7_match[] = { -+{ -+ .name = "layer7", -+ .family = AF_INET, -+ .checkentry = check, -+ .match = match, -+ .destroy = destroy, -+ .matchsize = sizeof(struct xt_layer7_info), -+ .me = THIS_MODULE -+} -+}; -+ -+static void layer7_cleanup_proc(void) -+{ -+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,23) -+ remove_proc_entry("layer7_numpackets", proc_net); -+#else -+ remove_proc_entry("layer7_numpackets", init_net.proc_net); -+#endif -+} -+ -+/* register the proc file */ -+static void layer7_init_proc(void) -+{ -+ struct proc_dir_entry* entry; -+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,23) -+ entry = create_proc_entry("layer7_numpackets", 0644, proc_net); -+#else -+ entry = create_proc_entry("layer7_numpackets", 0644, init_net.proc_net); -+#endif -+ entry->read_proc = layer7_read_proc; -+ entry->write_proc = layer7_write_proc; -+} -+ -+static int __init xt_layer7_init(void) -+{ -+ need_conntrack(); -+ -+ layer7_init_proc(); -+ if(maxdatalen < 1) { -+ printk(KERN_WARNING "layer7: maxdatalen can't be < 1, " -+ "using 1\n"); -+ maxdatalen = 1; -+ } -+ /* This is not a hard limit. It's just here to prevent people from -+ bringing their slow machines to a grinding halt. */ -+ else if(maxdatalen > 65536) { -+ printk(KERN_WARNING "layer7: maxdatalen can't be > 65536, " -+ "using 65536\n"); -+ maxdatalen = 65536; -+ } -+ return xt_register_matches(xt_layer7_match, -+ ARRAY_SIZE(xt_layer7_match)); -+} -+ -+static void __exit xt_layer7_fini(void) -+{ -+ layer7_cleanup_proc(); -+ xt_unregister_matches(xt_layer7_match, ARRAY_SIZE(xt_layer7_match)); -+} -+ -+module_init(xt_layer7_init); -+module_exit(xt_layer7_fini); ---- /dev/null -+++ b/net/netfilter/regexp/regexp.c -@@ -0,0 +1,1197 @@ -+/* -+ * regcomp and regexec -- regsub and regerror are elsewhere -+ * @(#)regexp.c 1.3 of 18 April 87 -+ * -+ * Copyright (c) 1986 by University of Toronto. -+ * Written by Henry Spencer. Not derived from licensed software. -+ * -+ * Permission is granted to anyone to use this software for any -+ * purpose on any computer system, and to redistribute it freely, -+ * subject to the following restrictions: -+ * -+ * 1. The author is not responsible for the consequences of use of -+ * this software, no matter how awful, even if they arise -+ * from defects in it. -+ * -+ * 2. The origin of this software must not be misrepresented, either -+ * by explicit claim or by omission. -+ * -+ * 3. Altered versions must be plainly marked as such, and must not -+ * be misrepresented as being the original software. -+ * -+ * Beware that some of this code is subtly aware of the way operator -+ * precedence is structured in regular expressions. Serious changes in -+ * regular-expression syntax might require a total rethink. -+ * -+ * This code was modified by Ethan Sommer to work within the kernel -+ * (it now uses kmalloc etc..) -+ * -+ * Modified slightly by Matthew Strait to use more modern C. -+ */ -+ -+#include "regexp.h" -+#include "regmagic.h" -+ -+/* added by ethan and matt. Lets it work in both kernel and user space. -+(So iptables can use it, for instance.) Yea, it goes both ways... */ -+#if __KERNEL__ -+ #define malloc(foo) kmalloc(foo,GFP_ATOMIC) -+#else -+ #define printk(format,args...) printf(format,##args) -+#endif -+ -+void regerror(char * s) -+{ -+ printk("<3>Regexp: %s\n", s); -+ /* NOTREACHED */ -+} -+ -+/* -+ * The "internal use only" fields in regexp.h are present to pass info from -+ * compile to execute that permits the execute phase to run lots faster on -+ * simple cases. They are: -+ * -+ * regstart char that must begin a match; '\0' if none obvious -+ * reganch is the match anchored (at beginning-of-line only)? -+ * regmust string (pointer into program) that match must include, or NULL -+ * regmlen length of regmust string -+ * -+ * Regstart and reganch permit very fast decisions on suitable starting points -+ * for a match, cutting down the work a lot. Regmust permits fast rejection -+ * of lines that cannot possibly match. The regmust tests are costly enough -+ * that regcomp() supplies a regmust only if the r.e. contains something -+ * potentially expensive (at present, the only such thing detected is * or + -+ * at the start of the r.e., which can involve a lot of backup). Regmlen is -+ * supplied because the test in regexec() needs it and regcomp() is computing -+ * it anyway. -+ */ -+ -+/* -+ * Structure for regexp "program". This is essentially a linear encoding -+ * of a nondeterministic finite-state machine (aka syntax charts or -+ * "railroad normal form" in parsing technology). Each node is an opcode -+ * plus a "next" pointer, possibly plus an operand. "Next" pointers of -+ * all nodes except BRANCH implement concatenation; a "next" pointer with -+ * a BRANCH on both ends of it is connecting two alternatives. (Here we -+ * have one of the subtle syntax dependencies: an individual BRANCH (as -+ * opposed to a collection of them) is never concatenated with anything -+ * because of operator precedence.) The operand of some types of node is -+ * a literal string; for others, it is a node leading into a sub-FSM. In -+ * particular, the operand of a BRANCH node is the first node of the branch. -+ * (NB this is *not* a tree structure: the tail of the branch connects -+ * to the thing following the set of BRANCHes.) The opcodes are: -+ */ -+ -+/* definition number opnd? meaning */ -+#define END 0 /* no End of program. */ -+#define BOL 1 /* no Match "" at beginning of line. */ -+#define EOL 2 /* no Match "" at end of line. */ -+#define ANY 3 /* no Match any one character. */ -+#define ANYOF 4 /* str Match any character in this string. */ -+#define ANYBUT 5 /* str Match any character not in this string. */ -+#define BRANCH 6 /* node Match this alternative, or the next... */ -+#define BACK 7 /* no Match "", "next" ptr points backward. */ -+#define EXACTLY 8 /* str Match this string. */ -+#define NOTHING 9 /* no Match empty string. */ -+#define STAR 10 /* node Match this (simple) thing 0 or more times. */ -+#define PLUS 11 /* node Match this (simple) thing 1 or more times. */ -+#define OPEN 20 /* no Mark this point in input as start of #n. */ -+ /* OPEN+1 is number 1, etc. */ -+#define CLOSE 30 /* no Analogous to OPEN. */ -+ -+/* -+ * Opcode notes: -+ * -+ * BRANCH The set of branches constituting a single choice are hooked -+ * together with their "next" pointers, since precedence prevents -+ * anything being concatenated to any individual branch. The -+ * "next" pointer of the last BRANCH in a choice points to the -+ * thing following the whole choice. This is also where the -+ * final "next" pointer of each individual branch points; each -+ * branch starts with the operand node of a BRANCH node. -+ * -+ * BACK Normal "next" pointers all implicitly point forward; BACK -+ * exists to make loop structures possible. -+ * -+ * STAR,PLUS '?', and complex '*' and '+', are implemented as circular -+ * BRANCH structures using BACK. Simple cases (one character -+ * per match) are implemented with STAR and PLUS for speed -+ * and to minimize recursive plunges. -+ * -+ * OPEN,CLOSE ...are numbered at compile time. -+ */ -+ -+/* -+ * A node is one char of opcode followed by two chars of "next" pointer. -+ * "Next" pointers are stored as two 8-bit pieces, high order first. The -+ * value is a positive offset from the opcode of the node containing it. -+ * An operand, if any, simply follows the node. (Note that much of the -+ * code generation knows about this implicit relationship.) -+ * -+ * Using two bytes for the "next" pointer is vast overkill for most things, -+ * but allows patterns to get big without disasters. -+ */ -+#define OP(p) (*(p)) -+#define NEXT(p) (((*((p)+1)&0377)<<8) + (*((p)+2)&0377)) -+#define OPERAND(p) ((p) + 3) -+ -+/* -+ * See regmagic.h for one further detail of program structure. -+ */ -+ -+ -+/* -+ * Utility definitions. -+ */ -+#ifndef CHARBITS -+#define UCHARAT(p) ((int)*(unsigned char *)(p)) -+#else -+#define UCHARAT(p) ((int)*(p)&CHARBITS) -+#endif -+ -+#define FAIL(m) { regerror(m); return(NULL); } -+#define ISMULT(c) ((c) == '*' || (c) == '+' || (c) == '?') -+#define META "^$.[()|?+*\\" -+ -+/* -+ * Flags to be passed up and down. -+ */ -+#define HASWIDTH 01 /* Known never to match null string. */ -+#define SIMPLE 02 /* Simple enough to be STAR/PLUS operand. */ -+#define SPSTART 04 /* Starts with * or +. */ -+#define WORST 0 /* Worst case. */ -+ -+/* -+ * Global work variables for regcomp(). -+ */ -+struct match_globals { -+char *reginput; /* String-input pointer. */ -+char *regbol; /* Beginning of input, for ^ check. */ -+char **regstartp; /* Pointer to startp array. */ -+char **regendp; /* Ditto for endp. */ -+char *regparse; /* Input-scan pointer. */ -+int regnpar; /* () count. */ -+char regdummy; -+char *regcode; /* Code-emit pointer; ®dummy = don't. */ -+long regsize; /* Code size. */ -+}; -+ -+/* -+ * Forward declarations for regcomp()'s friends. -+ */ -+#ifndef STATIC -+#define STATIC static -+#endif -+STATIC char *reg(struct match_globals *g, int paren,int *flagp); -+STATIC char *regbranch(struct match_globals *g, int *flagp); -+STATIC char *regpiece(struct match_globals *g, int *flagp); -+STATIC char *regatom(struct match_globals *g, int *flagp); -+STATIC char *regnode(struct match_globals *g, char op); -+STATIC char *regnext(struct match_globals *g, char *p); -+STATIC void regc(struct match_globals *g, char b); -+STATIC void reginsert(struct match_globals *g, char op, char *opnd); -+STATIC void regtail(struct match_globals *g, char *p, char *val); -+STATIC void regoptail(struct match_globals *g, char *p, char *val); -+ -+ -+__kernel_size_t my_strcspn(const char *s1,const char *s2) -+{ -+ char *scan1; -+ char *scan2; -+ int count; -+ -+ count = 0; -+ for (scan1 = (char *)s1; *scan1 != '\0'; scan1++) { -+ for (scan2 = (char *)s2; *scan2 != '\0';) /* ++ moved down. */ -+ if (*scan1 == *scan2++) -+ return(count); -+ count++; -+ } -+ return(count); -+} -+ -+/* -+ - regcomp - compile a regular expression into internal code -+ * -+ * We can't allocate space until we know how big the compiled form will be, -+ * but we can't compile it (and thus know how big it is) until we've got a -+ * place to put the code. So we cheat: we compile it twice, once with code -+ * generation turned off and size counting turned on, and once "for real". -+ * This also means that we don't allocate space until we are sure that the -+ * thing really will compile successfully, and we never have to move the -+ * code and thus invalidate pointers into it. (Note that it has to be in -+ * one piece because free() must be able to free it all.) -+ * -+ * Beware that the optimization-preparation code in here knows about some -+ * of the structure of the compiled regexp. -+ */ -+regexp * -+regcomp(char *exp,int *patternsize) -+{ -+ register regexp *r; -+ register char *scan; -+ register char *longest; -+ register int len; -+ int flags; -+ struct match_globals g; -+ -+ /* commented out by ethan -+ extern char *malloc(); -+ */ -+ -+ if (exp == NULL) -+ FAIL("NULL argument"); -+ -+ /* First pass: determine size, legality. */ -+ g.regparse = exp; -+ g.regnpar = 1; -+ g.regsize = 0L; -+ g.regcode = &g.regdummy; -+ regc(&g, MAGIC); -+ if (reg(&g, 0, &flags) == NULL) -+ return(NULL); -+ -+ /* Small enough for pointer-storage convention? */ -+ if (g.regsize >= 32767L) /* Probably could be 65535L. */ -+ FAIL("regexp too big"); -+ -+ /* Allocate space. */ -+ *patternsize=sizeof(regexp) + (unsigned)g.regsize; -+ r = (regexp *)malloc(sizeof(regexp) + (unsigned)g.regsize); -+ if (r == NULL) -+ FAIL("out of space"); -+ -+ /* Second pass: emit code. */ -+ g.regparse = exp; -+ g.regnpar = 1; -+ g.regcode = r->program; -+ regc(&g, MAGIC); -+ if (reg(&g, 0, &flags) == NULL) -+ return(NULL); -+ -+ /* Dig out information for optimizations. */ -+ r->regstart = '\0'; /* Worst-case defaults. */ -+ r->reganch = 0; -+ r->regmust = NULL; -+ r->regmlen = 0; -+ scan = r->program+1; /* First BRANCH. */ -+ if (OP(regnext(&g, scan)) == END) { /* Only one top-level choice. */ -+ scan = OPERAND(scan); -+ -+ /* Starting-point info. */ -+ if (OP(scan) == EXACTLY) -+ r->regstart = *OPERAND(scan); -+ else if (OP(scan) == BOL) -+ r->reganch++; -+ -+ /* -+ * If there's something expensive in the r.e., find the -+ * longest literal string that must appear and make it the -+ * regmust. Resolve ties in favor of later strings, since -+ * the regstart check works with the beginning of the r.e. -+ * and avoiding duplication strengthens checking. Not a -+ * strong reason, but sufficient in the absence of others. -+ */ -+ if (flags&SPSTART) { -+ longest = NULL; -+ len = 0; -+ for (; scan != NULL; scan = regnext(&g, scan)) -+ if (OP(scan) == EXACTLY && strlen(OPERAND(scan)) >= len) { -+ longest = OPERAND(scan); -+ len = strlen(OPERAND(scan)); -+ } -+ r->regmust = longest; -+ r->regmlen = len; -+ } -+ } -+ -+ return(r); -+} -+ -+/* -+ - reg - regular expression, i.e. main body or parenthesized thing -+ * -+ * Caller must absorb opening parenthesis. -+ * -+ * Combining parenthesis handling with the base level of regular expression -+ * is a trifle forced, but the need to tie the tails of the branches to what -+ * follows makes it hard to avoid. -+ */ -+static char * -+reg(struct match_globals *g, int paren, int *flagp /* Parenthesized? */ ) -+{ -+ register char *ret; -+ register char *br; -+ register char *ender; -+ register int parno = 0; /* 0 makes gcc happy */ -+ int flags; -+ -+ *flagp = HASWIDTH; /* Tentatively. */ -+ -+ /* Make an OPEN node, if parenthesized. */ -+ if (paren) { -+ if (g->regnpar >= NSUBEXP) -+ FAIL("too many ()"); -+ parno = g->regnpar; -+ g->regnpar++; -+ ret = regnode(g, OPEN+parno); -+ } else -+ ret = NULL; -+ -+ /* Pick up the branches, linking them together. */ -+ br = regbranch(g, &flags); -+ if (br == NULL) -+ return(NULL); -+ if (ret != NULL) -+ regtail(g, ret, br); /* OPEN -> first. */ -+ else -+ ret = br; -+ if (!(flags&HASWIDTH)) -+ *flagp &= ~HASWIDTH; -+ *flagp |= flags&SPSTART; -+ while (*g->regparse == '|') { -+ g->regparse++; -+ br = regbranch(g, &flags); -+ if (br == NULL) -+ return(NULL); -+ regtail(g, ret, br); /* BRANCH -> BRANCH. */ -+ if (!(flags&HASWIDTH)) -+ *flagp &= ~HASWIDTH; -+ *flagp |= flags&SPSTART; -+ } -+ -+ /* Make a closing node, and hook it on the end. */ -+ ender = regnode(g, (paren) ? CLOSE+parno : END); -+ regtail(g, ret, ender); -+ -+ /* Hook the tails of the branches to the closing node. */ -+ for (br = ret; br != NULL; br = regnext(g, br)) -+ regoptail(g, br, ender); -+ -+ /* Check for proper termination. */ -+ if (paren && *g->regparse++ != ')') { -+ FAIL("unmatched ()"); -+ } else if (!paren && *g->regparse != '\0') { -+ if (*g->regparse == ')') { -+ FAIL("unmatched ()"); -+ } else -+ FAIL("junk on end"); /* "Can't happen". */ -+ /* NOTREACHED */ -+ } -+ -+ return(ret); -+} -+ -+/* -+ - regbranch - one alternative of an | operator -+ * -+ * Implements the concatenation operator. -+ */ -+static char * -+regbranch(struct match_globals *g, int *flagp) -+{ -+ register char *ret; -+ register char *chain; -+ register char *latest; -+ int flags; -+ -+ *flagp = WORST; /* Tentatively. */ -+ -+ ret = regnode(g, BRANCH); -+ chain = NULL; -+ while (*g->regparse != '\0' && *g->regparse != '|' && *g->regparse != ')') { -+ latest = regpiece(g, &flags); -+ if (latest == NULL) -+ return(NULL); -+ *flagp |= flags&HASWIDTH; -+ if (chain == NULL) /* First piece. */ -+ *flagp |= flags&SPSTART; -+ else -+ regtail(g, chain, latest); -+ chain = latest; -+ } -+ if (chain == NULL) /* Loop ran zero times. */ -+ (void) regnode(g, NOTHING); -+ -+ return(ret); -+} -+ -+/* -+ - regpiece - something followed by possible [*+?] -+ * -+ * Note that the branching code sequences used for ? and the general cases -+ * of * and + are somewhat optimized: they use the same NOTHING node as -+ * both the endmarker for their branch list and the body of the last branch. -+ * It might seem that this node could be dispensed with entirely, but the -+ * endmarker role is not redundant. -+ */ -+static char * -+regpiece(struct match_globals *g, int *flagp) -+{ -+ register char *ret; -+ register char op; -+ register char *next; -+ int flags; -+ -+ ret = regatom(g, &flags); -+ if (ret == NULL) -+ return(NULL); -+ -+ op = *g->regparse; -+ if (!ISMULT(op)) { -+ *flagp = flags; -+ return(ret); -+ } -+ -+ if (!(flags&HASWIDTH) && op != '?') -+ FAIL("*+ operand could be empty"); -+ *flagp = (op != '+') ? (WORST|SPSTART) : (WORST|HASWIDTH); -+ -+ if (op == '*' && (flags&SIMPLE)) -+ reginsert(g, STAR, ret); -+ else if (op == '*') { -+ /* Emit x* as (x&|), where & means "self". */ -+ reginsert(g, BRANCH, ret); /* Either x */ -+ regoptail(g, ret, regnode(g, BACK)); /* and loop */ -+ regoptail(g, ret, ret); /* back */ -+ regtail(g, ret, regnode(g, BRANCH)); /* or */ -+ regtail(g, ret, regnode(g, NOTHING)); /* null. */ -+ } else if (op == '+' && (flags&SIMPLE)) -+ reginsert(g, PLUS, ret); -+ else if (op == '+') { -+ /* Emit x+ as x(&|), where & means "self". */ -+ next = regnode(g, BRANCH); /* Either */ -+ regtail(g, ret, next); -+ regtail(g, regnode(g, BACK), ret); /* loop back */ -+ regtail(g, next, regnode(g, BRANCH)); /* or */ -+ regtail(g, ret, regnode(g, NOTHING)); /* null. */ -+ } else if (op == '?') { -+ /* Emit x? as (x|) */ -+ reginsert(g, BRANCH, ret); /* Either x */ -+ regtail(g, ret, regnode(g, BRANCH)); /* or */ -+ next = regnode(g, NOTHING); /* null. */ -+ regtail(g, ret, next); -+ regoptail(g, ret, next); -+ } -+ g->regparse++; -+ if (ISMULT(*g->regparse)) -+ FAIL("nested *?+"); -+ -+ return(ret); -+} -+ -+/* -+ - regatom - the lowest level -+ * -+ * Optimization: gobbles an entire sequence of ordinary characters so that -+ * it can turn them into a single node, which is smaller to store and -+ * faster to run. Backslashed characters are exceptions, each becoming a -+ * separate node; the code is simpler that way and it's not worth fixing. -+ */ -+static char * -+regatom(struct match_globals *g, int *flagp) -+{ -+ register char *ret; -+ int flags; -+ -+ *flagp = WORST; /* Tentatively. */ -+ -+ switch (*g->regparse++) { -+ case '^': -+ ret = regnode(g, BOL); -+ break; -+ case '$': -+ ret = regnode(g, EOL); -+ break; -+ case '.': -+ ret = regnode(g, ANY); -+ *flagp |= HASWIDTH|SIMPLE; -+ break; -+ case '[': { -+ register int class; -+ register int classend; -+ -+ if (*g->regparse == '^') { /* Complement of range. */ -+ ret = regnode(g, ANYBUT); -+ g->regparse++; -+ } else -+ ret = regnode(g, ANYOF); -+ if (*g->regparse == ']' || *g->regparse == '-') -+ regc(g, *g->regparse++); -+ while (*g->regparse != '\0' && *g->regparse != ']') { -+ if (*g->regparse == '-') { -+ g->regparse++; -+ if (*g->regparse == ']' || *g->regparse == '\0') -+ regc(g, '-'); -+ else { -+ class = UCHARAT(g->regparse-2)+1; -+ classend = UCHARAT(g->regparse); -+ if (class > classend+1) -+ FAIL("invalid [] range"); -+ for (; class <= classend; class++) -+ regc(g, class); -+ g->regparse++; -+ } -+ } else -+ regc(g, *g->regparse++); -+ } -+ regc(g, '\0'); -+ if (*g->regparse != ']') -+ FAIL("unmatched []"); -+ g->regparse++; -+ *flagp |= HASWIDTH|SIMPLE; -+ } -+ break; -+ case '(': -+ ret = reg(g, 1, &flags); -+ if (ret == NULL) -+ return(NULL); -+ *flagp |= flags&(HASWIDTH|SPSTART); -+ break; -+ case '\0': -+ case '|': -+ case ')': -+ FAIL("internal urp"); /* Supposed to be caught earlier. */ -+ break; -+ case '?': -+ case '+': -+ case '*': -+ FAIL("?+* follows nothing"); -+ break; -+ case '\\': -+ if (*g->regparse == '\0') -+ FAIL("trailing \\"); -+ ret = regnode(g, EXACTLY); -+ regc(g, *g->regparse++); -+ regc(g, '\0'); -+ *flagp |= HASWIDTH|SIMPLE; -+ break; -+ default: { -+ register int len; -+ register char ender; -+ -+ g->regparse--; -+ len = my_strcspn((const char *)g->regparse, (const char *)META); -+ if (len <= 0) -+ FAIL("internal disaster"); -+ ender = *(g->regparse+len); -+ if (len > 1 && ISMULT(ender)) -+ len--; /* Back off clear of ?+* operand. */ -+ *flagp |= HASWIDTH; -+ if (len == 1) -+ *flagp |= SIMPLE; -+ ret = regnode(g, EXACTLY); -+ while (len > 0) { -+ regc(g, *g->regparse++); -+ len--; -+ } -+ regc(g, '\0'); -+ } -+ break; -+ } -+ -+ return(ret); -+} -+ -+/* -+ - regnode - emit a node -+ */ -+static char * /* Location. */ -+regnode(struct match_globals *g, char op) -+{ -+ register char *ret; -+ register char *ptr; -+ -+ ret = g->regcode; -+ if (ret == &g->regdummy) { -+ g->regsize += 3; -+ return(ret); -+ } -+ -+ ptr = ret; -+ *ptr++ = op; -+ *ptr++ = '\0'; /* Null "next" pointer. */ -+ *ptr++ = '\0'; -+ g->regcode = ptr; -+ -+ return(ret); -+} -+ -+/* -+ - regc - emit (if appropriate) a byte of code -+ */ -+static void -+regc(struct match_globals *g, char b) -+{ -+ if (g->regcode != &g->regdummy) -+ *g->regcode++ = b; -+ else -+ g->regsize++; -+} -+ -+/* -+ - reginsert - insert an operator in front of already-emitted operand -+ * -+ * Means relocating the operand. -+ */ -+static void -+reginsert(struct match_globals *g, char op, char* opnd) -+{ -+ register char *src; -+ register char *dst; -+ register char *place; -+ -+ if (g->regcode == &g->regdummy) { -+ g->regsize += 3; -+ return; -+ } -+ -+ src = g->regcode; -+ g->regcode += 3; -+ dst = g->regcode; -+ while (src > opnd) -+ *--dst = *--src; -+ -+ place = opnd; /* Op node, where operand used to be. */ -+ *place++ = op; -+ *place++ = '\0'; -+ *place++ = '\0'; -+} -+ -+/* -+ - regtail - set the next-pointer at the end of a node chain -+ */ -+static void -+regtail(struct match_globals *g, char *p, char *val) -+{ -+ register char *scan; -+ register char *temp; -+ register int offset; -+ -+ if (p == &g->regdummy) -+ return; -+ -+ /* Find last node. */ -+ scan = p; -+ for (;;) { -+ temp = regnext(g, scan); -+ if (temp == NULL) -+ break; -+ scan = temp; -+ } -+ -+ if (OP(scan) == BACK) -+ offset = scan - val; -+ else -+ offset = val - scan; -+ *(scan+1) = (offset>>8)&0377; -+ *(scan+2) = offset&0377; -+} -+ -+/* -+ - regoptail - regtail on operand of first argument; nop if operandless -+ */ -+static void -+regoptail(struct match_globals *g, char *p, char *val) -+{ -+ /* "Operandless" and "op != BRANCH" are synonymous in practice. */ -+ if (p == NULL || p == &g->regdummy || OP(p) != BRANCH) -+ return; -+ regtail(g, OPERAND(p), val); -+} -+ -+/* -+ * regexec and friends -+ */ -+ -+ -+/* -+ * Forwards. -+ */ -+STATIC int regtry(struct match_globals *g, regexp *prog, char *string); -+STATIC int regmatch(struct match_globals *g, char *prog); -+STATIC int regrepeat(struct match_globals *g, char *p); -+ -+#ifdef DEBUG -+int regnarrate = 0; -+void regdump(); -+STATIC char *regprop(char *op); -+#endif -+ -+/* -+ - regexec - match a regexp against a string -+ */ -+int -+regexec(regexp *prog, char *string) -+{ -+ register char *s; -+ struct match_globals g; -+ -+ /* Be paranoid... */ -+ if (prog == NULL || string == NULL) { -+ printk("<3>Regexp: NULL parameter\n"); -+ return(0); -+ } -+ -+ /* Check validity of program. */ -+ if (UCHARAT(prog->program) != MAGIC) { -+ printk("<3>Regexp: corrupted program\n"); -+ return(0); -+ } -+ -+ /* If there is a "must appear" string, look for it. */ -+ if (prog->regmust != NULL) { -+ s = string; -+ while ((s = strchr(s, prog->regmust[0])) != NULL) { -+ if (strncmp(s, prog->regmust, prog->regmlen) == 0) -+ break; /* Found it. */ -+ s++; -+ } -+ if (s == NULL) /* Not present. */ -+ return(0); -+ } -+ -+ /* Mark beginning of line for ^ . */ -+ g.regbol = string; -+ -+ /* Simplest case: anchored match need be tried only once. */ -+ if (prog->reganch) -+ return(regtry(&g, prog, string)); -+ -+ /* Messy cases: unanchored match. */ -+ s = string; -+ if (prog->regstart != '\0') -+ /* We know what char it must start with. */ -+ while ((s = strchr(s, prog->regstart)) != NULL) { -+ if (regtry(&g, prog, s)) -+ return(1); -+ s++; -+ } -+ else -+ /* We don't -- general case. */ -+ do { -+ if (regtry(&g, prog, s)) -+ return(1); -+ } while (*s++ != '\0'); -+ -+ /* Failure. */ -+ return(0); -+} -+ -+/* -+ - regtry - try match at specific point -+ */ -+static int /* 0 failure, 1 success */ -+regtry(struct match_globals *g, regexp *prog, char *string) -+{ -+ register int i; -+ register char **sp; -+ register char **ep; -+ -+ g->reginput = string; -+ g->regstartp = prog->startp; -+ g->regendp = prog->endp; -+ -+ sp = prog->startp; -+ ep = prog->endp; -+ for (i = NSUBEXP; i > 0; i--) { -+ *sp++ = NULL; -+ *ep++ = NULL; -+ } -+ if (regmatch(g, prog->program + 1)) { -+ prog->startp[0] = string; -+ prog->endp[0] = g->reginput; -+ return(1); -+ } else -+ return(0); -+} -+ -+/* -+ - regmatch - main matching routine -+ * -+ * Conceptually the strategy is simple: check to see whether the current -+ * node matches, call self recursively to see whether the rest matches, -+ * and then act accordingly. In practice we make some effort to avoid -+ * recursion, in particular by going through "ordinary" nodes (that don't -+ * need to know whether the rest of the match failed) by a loop instead of -+ * by recursion. -+ */ -+static int /* 0 failure, 1 success */ -+regmatch(struct match_globals *g, char *prog) -+{ -+ register char *scan = prog; /* Current node. */ -+ char *next; /* Next node. */ -+ -+#ifdef DEBUG -+ if (scan != NULL && regnarrate) -+ fprintf(stderr, "%s(\n", regprop(scan)); -+#endif -+ while (scan != NULL) { -+#ifdef DEBUG -+ if (regnarrate) -+ fprintf(stderr, "%s...\n", regprop(scan)); -+#endif -+ next = regnext(g, scan); -+ -+ switch (OP(scan)) { -+ case BOL: -+ if (g->reginput != g->regbol) -+ return(0); -+ break; -+ case EOL: -+ if (*g->reginput != '\0') -+ return(0); -+ break; -+ case ANY: -+ if (*g->reginput == '\0') -+ return(0); -+ g->reginput++; -+ break; -+ case EXACTLY: { -+ register int len; -+ register char *opnd; -+ -+ opnd = OPERAND(scan); -+ /* Inline the first character, for speed. */ -+ if (*opnd != *g->reginput) -+ return(0); -+ len = strlen(opnd); -+ if (len > 1 && strncmp(opnd, g->reginput, len) != 0) -+ return(0); -+ g->reginput += len; -+ } -+ break; -+ case ANYOF: -+ if (*g->reginput == '\0' || strchr(OPERAND(scan), *g->reginput) == NULL) -+ return(0); -+ g->reginput++; -+ break; -+ case ANYBUT: -+ if (*g->reginput == '\0' || strchr(OPERAND(scan), *g->reginput) != NULL) -+ return(0); -+ g->reginput++; -+ break; -+ case NOTHING: -+ case BACK: -+ break; -+ case OPEN+1: -+ case OPEN+2: -+ case OPEN+3: -+ case OPEN+4: -+ case OPEN+5: -+ case OPEN+6: -+ case OPEN+7: -+ case OPEN+8: -+ case OPEN+9: { -+ register int no; -+ register char *save; -+ -+ no = OP(scan) - OPEN; -+ save = g->reginput; -+ -+ if (regmatch(g, next)) { -+ /* -+ * Don't set startp if some later -+ * invocation of the same parentheses -+ * already has. -+ */ -+ if (g->regstartp[no] == NULL) -+ g->regstartp[no] = save; -+ return(1); -+ } else -+ return(0); -+ } -+ break; -+ case CLOSE+1: -+ case CLOSE+2: -+ case CLOSE+3: -+ case CLOSE+4: -+ case CLOSE+5: -+ case CLOSE+6: -+ case CLOSE+7: -+ case CLOSE+8: -+ case CLOSE+9: -+ { -+ register int no; -+ register char *save; -+ -+ no = OP(scan) - CLOSE; -+ save = g->reginput; -+ -+ if (regmatch(g, next)) { -+ /* -+ * Don't set endp if some later -+ * invocation of the same parentheses -+ * already has. -+ */ -+ if (g->regendp[no] == NULL) -+ g->regendp[no] = save; -+ return(1); -+ } else -+ return(0); -+ } -+ break; -+ case BRANCH: { -+ register char *save; -+ -+ if (OP(next) != BRANCH) /* No choice. */ -+ next = OPERAND(scan); /* Avoid recursion. */ -+ else { -+ do { -+ save = g->reginput; -+ if (regmatch(g, OPERAND(scan))) -+ return(1); -+ g->reginput = save; -+ scan = regnext(g, scan); -+ } while (scan != NULL && OP(scan) == BRANCH); -+ return(0); -+ /* NOTREACHED */ -+ } -+ } -+ break; -+ case STAR: -+ case PLUS: { -+ register char nextch; -+ register int no; -+ register char *save; -+ register int min; -+ -+ /* -+ * Lookahead to avoid useless match attempts -+ * when we know what character comes next. -+ */ -+ nextch = '\0'; -+ if (OP(next) == EXACTLY) -+ nextch = *OPERAND(next); -+ min = (OP(scan) == STAR) ? 0 : 1; -+ save = g->reginput; -+ no = regrepeat(g, OPERAND(scan)); -+ while (no >= min) { -+ /* If it could work, try it. */ -+ if (nextch == '\0' || *g->reginput == nextch) -+ if (regmatch(g, next)) -+ return(1); -+ /* Couldn't or didn't -- back up. */ -+ no--; -+ g->reginput = save + no; -+ } -+ return(0); -+ } -+ break; -+ case END: -+ return(1); /* Success! */ -+ break; -+ default: -+ printk("<3>Regexp: memory corruption\n"); -+ return(0); -+ break; -+ } -+ -+ scan = next; -+ } -+ -+ /* -+ * We get here only if there's trouble -- normally "case END" is -+ * the terminating point. -+ */ -+ printk("<3>Regexp: corrupted pointers\n"); -+ return(0); -+} -+ -+/* -+ - regrepeat - repeatedly match something simple, report how many -+ */ -+static int -+regrepeat(struct match_globals *g, char *p) -+{ -+ register int count = 0; -+ register char *scan; -+ register char *opnd; -+ -+ scan = g->reginput; -+ opnd = OPERAND(p); -+ switch (OP(p)) { -+ case ANY: -+ count = strlen(scan); -+ scan += count; -+ break; -+ case EXACTLY: -+ while (*opnd == *scan) { -+ count++; -+ scan++; -+ } -+ break; -+ case ANYOF: -+ while (*scan != '\0' && strchr(opnd, *scan) != NULL) { -+ count++; -+ scan++; -+ } -+ break; -+ case ANYBUT: -+ while (*scan != '\0' && strchr(opnd, *scan) == NULL) { -+ count++; -+ scan++; -+ } -+ break; -+ default: /* Oh dear. Called inappropriately. */ -+ printk("<3>Regexp: internal foulup\n"); -+ count = 0; /* Best compromise. */ -+ break; -+ } -+ g->reginput = scan; -+ -+ return(count); -+} -+ -+/* -+ - regnext - dig the "next" pointer out of a node -+ */ -+static char* -+regnext(struct match_globals *g, char *p) -+{ -+ register int offset; -+ -+ if (p == &g->regdummy) -+ return(NULL); -+ -+ offset = NEXT(p); -+ if (offset == 0) -+ return(NULL); -+ -+ if (OP(p) == BACK) -+ return(p-offset); -+ else -+ return(p+offset); -+} -+ -+#ifdef DEBUG -+ -+STATIC char *regprop(); -+ -+/* -+ - regdump - dump a regexp onto stdout in vaguely comprehensible form -+ */ -+void -+regdump(regexp *r) -+{ -+ register char *s; -+ register char op = EXACTLY; /* Arbitrary non-END op. */ -+ register char *next; -+ /* extern char *strchr(); */ -+ -+ -+ s = r->program + 1; -+ while (op != END) { /* While that wasn't END last time... */ -+ op = OP(s); -+ printf("%2d%s", s-r->program, regprop(s)); /* Where, what. */ -+ next = regnext(s); -+ if (next == NULL) /* Next ptr. */ -+ printf("(0)"); -+ else -+ printf("(%d)", (s-r->program)+(next-s)); -+ s += 3; -+ if (op == ANYOF || op == ANYBUT || op == EXACTLY) { -+ /* Literal string, where present. */ -+ while (*s != '\0') { -+ putchar(*s); -+ s++; -+ } -+ s++; -+ } -+ putchar('\n'); -+ } -+ -+ /* Header fields of interest. */ -+ if (r->regstart != '\0') -+ printf("start `%c' ", r->regstart); -+ if (r->reganch) -+ printf("anchored "); -+ if (r->regmust != NULL) -+ printf("must have \"%s\"", r->regmust); -+ printf("\n"); -+} -+ -+/* -+ - regprop - printable representation of opcode -+ */ -+static char * -+regprop(char *op) -+{ -+#define BUFLEN 50 -+ register char *p; -+ static char buf[BUFLEN]; -+ -+ strcpy(buf, ":"); -+ -+ switch (OP(op)) { -+ case BOL: -+ p = "BOL"; -+ break; -+ case EOL: -+ p = "EOL"; -+ break; -+ case ANY: -+ p = "ANY"; -+ break; -+ case ANYOF: -+ p = "ANYOF"; -+ break; -+ case ANYBUT: -+ p = "ANYBUT"; -+ break; -+ case BRANCH: -+ p = "BRANCH"; -+ break; -+ case EXACTLY: -+ p = "EXACTLY"; -+ break; -+ case NOTHING: -+ p = "NOTHING"; -+ break; -+ case BACK: -+ p = "BACK"; -+ break; -+ case END: -+ p = "END"; -+ break; -+ case OPEN+1: -+ case OPEN+2: -+ case OPEN+3: -+ case OPEN+4: -+ case OPEN+5: -+ case OPEN+6: -+ case OPEN+7: -+ case OPEN+8: -+ case OPEN+9: -+ snprintf(buf+strlen(buf),BUFLEN-strlen(buf), "OPEN%d", OP(op)-OPEN); -+ p = NULL; -+ break; -+ case CLOSE+1: -+ case CLOSE+2: -+ case CLOSE+3: -+ case CLOSE+4: -+ case CLOSE+5: -+ case CLOSE+6: -+ case CLOSE+7: -+ case CLOSE+8: -+ case CLOSE+9: -+ snprintf(buf+strlen(buf),BUFLEN-strlen(buf), "CLOSE%d", OP(op)-CLOSE); -+ p = NULL; -+ break; -+ case STAR: -+ p = "STAR"; -+ break; -+ case PLUS: -+ p = "PLUS"; -+ break; -+ default: -+ printk("<3>Regexp: corrupted opcode\n"); -+ break; -+ } -+ if (p != NULL) -+ strncat(buf, p, BUFLEN-strlen(buf)); -+ return(buf); -+} -+#endif -+ -+ ---- /dev/null -+++ b/net/netfilter/regexp/regexp.h -@@ -0,0 +1,41 @@ -+/* -+ * Definitions etc. for regexp(3) routines. -+ * -+ * Caveat: this is V8 regexp(3) [actually, a reimplementation thereof], -+ * not the System V one. -+ */ -+ -+#ifndef REGEXP_H -+#define REGEXP_H -+ -+ -+/* -+http://www.opensource.apple.com/darwinsource/10.3/expect-1/expect/expect.h , -+which contains a version of this library, says: -+ -+ * -+ * NSUBEXP must be at least 10, and no greater than 117 or the parser -+ * will not work properly. -+ * -+ -+However, it looks rather like this library is limited to 10. If you think -+otherwise, let us know. -+*/ -+ -+#define NSUBEXP 10 -+typedef struct regexp { -+ char *startp[NSUBEXP]; -+ char *endp[NSUBEXP]; -+ char regstart; /* Internal use only. */ -+ char reganch; /* Internal use only. */ -+ char *regmust; /* Internal use only. */ -+ int regmlen; /* Internal use only. */ -+ char program[1]; /* Unwarranted chumminess with compiler. */ -+} regexp; -+ -+regexp * regcomp(char *exp, int *patternsize); -+int regexec(regexp *prog, char *string); -+void regsub(regexp *prog, char *source, char *dest); -+void regerror(char *s); -+ -+#endif ---- /dev/null -+++ b/net/netfilter/regexp/regmagic.h -@@ -0,0 +1,5 @@ -+/* -+ * The first byte of the regexp internal "program" is actually this magic -+ * number; the start node begins in the second byte. -+ */ -+#define MAGIC 0234 ---- /dev/null -+++ b/net/netfilter/regexp/regsub.c -@@ -0,0 +1,95 @@ -+/* -+ * regsub -+ * @(#)regsub.c 1.3 of 2 April 86 -+ * -+ * Copyright (c) 1986 by University of Toronto. -+ * Written by Henry Spencer. Not derived from licensed software. -+ * -+ * Permission is granted to anyone to use this software for any -+ * purpose on any computer system, and to redistribute it freely, -+ * subject to the following restrictions: -+ * -+ * 1. The author is not responsible for the consequences of use of -+ * this software, no matter how awful, even if they arise -+ * from defects in it. -+ * -+ * 2. The origin of this software must not be misrepresented, either -+ * by explicit claim or by omission. -+ * -+ * 3. Altered versions must be plainly marked as such, and must not -+ * be misrepresented as being the original software. -+ * -+ * -+ * This code was modified by Ethan Sommer to work within the kernel -+ * (it now uses kmalloc etc..) -+ * -+ */ -+#include "regexp.h" -+#include "regmagic.h" -+#include -+ -+ -+#ifndef CHARBITS -+#define UCHARAT(p) ((int)*(unsigned char *)(p)) -+#else -+#define UCHARAT(p) ((int)*(p)&CHARBITS) -+#endif -+ -+#if 0 -+//void regerror(char * s) -+//{ -+// printk("regexp(3): %s", s); -+// /* NOTREACHED */ -+//} -+#endif -+ -+/* -+ - regsub - perform substitutions after a regexp match -+ */ -+void -+regsub(regexp * prog, char * source, char * dest) -+{ -+ register char *src; -+ register char *dst; -+ register char c; -+ register int no; -+ register int len; -+ -+ /* Not necessary and gcc doesn't like it -MLS */ -+ /*extern char *strncpy();*/ -+ -+ if (prog == NULL || source == NULL || dest == NULL) { -+ regerror("NULL parm to regsub"); -+ return; -+ } -+ if (UCHARAT(prog->program) != MAGIC) { -+ regerror("damaged regexp fed to regsub"); -+ return; -+ } -+ -+ src = source; -+ dst = dest; -+ while ((c = *src++) != '\0') { -+ if (c == '&') -+ no = 0; -+ else if (c == '\\' && '0' <= *src && *src <= '9') -+ no = *src++ - '0'; -+ else -+ no = -1; -+ -+ if (no < 0) { /* Ordinary character. */ -+ if (c == '\\' && (*src == '\\' || *src == '&')) -+ c = *src++; -+ *dst++ = c; -+ } else if (prog->startp[no] != NULL && prog->endp[no] != NULL) { -+ len = prog->endp[no] - prog->startp[no]; -+ (void) strncpy(dst, prog->startp[no], len); -+ dst += len; -+ if (len != 0 && *(dst-1) == '\0') { /* strncpy hit NUL. */ -+ regerror("damaged match string"); -+ return; -+ } -+ } -+ } -+ *dst++ = '\0'; -+} ---- a/net/netfilter/nf_conntrack_core.c -+++ b/net/netfilter/nf_conntrack_core.c -@@ -206,6 +206,14 @@ destroy_conntrack(struct nf_conntrack *n - * too. */ - nf_ct_remove_expectations(ct); - -+ #if defined(CONFIG_NETFILTER_XT_MATCH_LAYER7) || defined(CONFIG_NETFILTER_XT_MATCH_LAYER7_MODULE) -+ if(ct->layer7.app_proto) -+ kfree(ct->layer7.app_proto); -+ if(ct->layer7.app_data) -+ kfree(ct->layer7.app_data); -+ #endif -+ -+ - /* We overload first tuple to link into unconfirmed list. */ - if (!nf_ct_is_confirmed(ct)) { - BUG_ON(hlist_unhashed(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode)); ---- a/net/netfilter/nf_conntrack_standalone.c -+++ b/net/netfilter/nf_conntrack_standalone.c -@@ -180,7 +180,12 @@ static int ct_seq_show(struct seq_file * - return -ENOSPC; - #endif - -- if (seq_printf(s, "use=%u\n", atomic_read(&conntrack->ct_general.use))) -+#if defined(CONFIG_NETFILTER_XT_MATCH_LAYER7) || defined(CONFIG_NETFILTER_XT_MATCH_LAYER7_MODULE) -+ if(conntrack->layer7.app_proto) -+ if(seq_printf(s, "l7proto=%s ", conntrack->layer7.app_proto)) -+ return -ENOSPC; -+#endif -+ if (seq_printf(s, "asdfuse=%u\n", atomic_read(&conntrack->ct_general.use))) - return -ENOSPC; - - return 0; ---- a/include/net/netfilter/nf_conntrack.h -+++ b/include/net/netfilter/nf_conntrack.h -@@ -124,6 +124,22 @@ struct nf_conn - u_int32_t secmark; - #endif - -+#if defined(CONFIG_NETFILTER_XT_MATCH_LAYER7) || \ -+ defined(CONFIG_NETFILTER_XT_MATCH_LAYER7_MODULE) -+ struct { -+ /* -+ * e.g. "http". NULL before decision. "unknown" after decision -+ * if no match. -+ */ -+ char *app_proto; -+ /* -+ * application layer data so far. NULL after match decision. -+ */ -+ char *app_data; -+ unsigned int app_data_len; -+ } layer7; -+#endif -+ - /* Storage reserved for other modules: */ - union nf_conntrack_proto proto; - ---- /dev/null -+++ b/include/linux/netfilter/xt_layer7.h -@@ -0,0 +1,13 @@ -+#ifndef _XT_LAYER7_H -+#define _XT_LAYER7_H -+ -+#define MAX_PATTERN_LEN 8192 -+#define MAX_PROTOCOL_LEN 256 -+ -+struct xt_layer7_info { -+ char protocol[MAX_PROTOCOL_LEN]; -+ char pattern[MAX_PATTERN_LEN]; -+ u_int8_t invert; -+}; -+ -+#endif /* _XT_LAYER7_H */ diff --git a/target/linux/generic-2.6/patches-2.6.24/101-netfilter_layer7_pktmatch.patch b/target/linux/generic-2.6/patches-2.6.24/101-netfilter_layer7_pktmatch.patch deleted file mode 100644 index be2dff8e16..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/101-netfilter_layer7_pktmatch.patch +++ /dev/null @@ -1,109 +0,0 @@ ---- a/include/linux/netfilter/xt_layer7.h -+++ b/include/linux/netfilter/xt_layer7.h -@@ -8,6 +8,7 @@ struct xt_layer7_info { - char protocol[MAX_PROTOCOL_LEN]; - char pattern[MAX_PATTERN_LEN]; - u_int8_t invert; -+ u_int8_t pkt; - }; - - #endif /* _XT_LAYER7_H */ ---- a/net/netfilter/xt_layer7.c -+++ b/net/netfilter/xt_layer7.c -@@ -297,34 +297,36 @@ static int match_no_append(struct nf_con - } - - /* add the new app data to the conntrack. Return number of bytes added. */ --static int add_data(struct nf_conn * master_conntrack, -- char * app_data, int appdatalen) -+static int add_datastr(char *target, int offset, char *app_data, int len) - { - int length = 0, i; -- int oldlength = master_conntrack->layer7.app_data_len; -- -- /* This is a fix for a race condition by Deti Fliegl. However, I'm not -- clear on whether the race condition exists or whether this really -- fixes it. I might just be being dense... Anyway, if it's not really -- a fix, all it does is waste a very small amount of time. */ -- if(!master_conntrack->layer7.app_data) return 0; -+ -+ if (!target) return 0; - - /* Strip nulls. Make everything lower case (our regex lib doesn't - do case insensitivity). Add it to the end of the current data. */ -- for(i = 0; i < maxdatalen-oldlength-1 && -- i < appdatalen; i++) { -+ for(i = 0; i < maxdatalen-offset-1 && i < len; i++) { - if(app_data[i] != '\0') { - /* the kernel version of tolower mungs 'upper ascii' */ -- master_conntrack->layer7.app_data[length+oldlength] = -+ target[length+offset] = - isascii(app_data[i])? - tolower(app_data[i]) : app_data[i]; - length++; - } - } -+ target[length+offset] = '\0'; -+ -+ return length; -+} - -- master_conntrack->layer7.app_data[length+oldlength] = '\0'; -- master_conntrack->layer7.app_data_len = length + oldlength; -+/* add the new app data to the conntrack. Return number of bytes added. */ -+static int add_data(struct nf_conn * master_conntrack, -+ char * app_data, int appdatalen) -+{ -+ int length; - -+ length = add_datastr(master_conntrack->layer7.app_data, master_conntrack->layer7.app_data_len, app_data, appdatalen); -+ master_conntrack->layer7.app_data_len += length; - return length; - } - -@@ -411,7 +413,7 @@ match(const struct sk_buff *skbin, - const struct xt_layer7_info * info = matchinfo; - enum ip_conntrack_info master_ctinfo, ctinfo; - struct nf_conn *master_conntrack, *conntrack; -- unsigned char * app_data; -+ unsigned char *app_data, *tmp_data; - unsigned int pattern_result, appdatalen; - regexp * comppattern; - -@@ -439,8 +441,8 @@ match(const struct sk_buff *skbin, - master_conntrack = master_ct(master_conntrack); - - /* if we've classified it or seen too many packets */ -- if(TOTAL_PACKETS > num_packets || -- master_conntrack->layer7.app_proto) { -+ if(!info->pkt && (TOTAL_PACKETS > num_packets || -+ master_conntrack->layer7.app_proto)) { - - pattern_result = match_no_append(conntrack, master_conntrack, - ctinfo, master_ctinfo, info); -@@ -473,6 +475,25 @@ match(const struct sk_buff *skbin, - /* the return value gets checked later, when we're ready to use it */ - comppattern = compile_and_cache(info->pattern, info->protocol); - -+ if (info->pkt) { -+ tmp_data = kmalloc(maxdatalen, GFP_ATOMIC); -+ if(!tmp_data){ -+ if (net_ratelimit()) -+ printk(KERN_ERR "layer7: out of memory in match, bailing.\n"); -+ return info->invert; -+ } -+ -+ tmp_data[0] = '\0'; -+ add_datastr(tmp_data, 0, app_data, appdatalen); -+ pattern_result = ((comppattern && regexec(comppattern, tmp_data)) ? 1 : 0); -+ -+ kfree(tmp_data); -+ tmp_data = NULL; -+ spin_unlock_bh(&l7_lock); -+ -+ return (pattern_result ^ info->invert); -+ } -+ - /* On the first packet of a connection, allocate space for app data */ - if(TOTAL_PACKETS == 1 && !skb->cb[0] && - !master_conntrack->layer7.app_data){ diff --git a/target/linux/generic-2.6/patches-2.6.24/130-netfilter_ipset.patch b/target/linux/generic-2.6/patches-2.6.24/130-netfilter_ipset.patch deleted file mode 100644 index 641d8b441b..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/130-netfilter_ipset.patch +++ /dev/null @@ -1,7688 +0,0 @@ ---- a/include/linux/netfilter_ipv4/Kbuild -+++ b/include/linux/netfilter_ipv4/Kbuild -@@ -45,3 +45,14 @@ header-y += ipt_ttl.h - - unifdef-y += ip_queue.h - unifdef-y += ip_tables.h -+ -+unifdef-y += ip_set.h -+header-y += ip_set_iphash.h -+header-y += ip_set_ipmap.h -+header-y += ip_set_ipporthash.h -+unifdef-y += ip_set_iptree.h -+unifdef-y += ip_set_iptreemap.h -+header-y += ip_set_jhash.h -+header-y += ip_set_macipmap.h -+unifdef-y += ip_set_nethash.h -+header-y += ip_set_portmap.h ---- /dev/null -+++ b/include/linux/netfilter_ipv4/ip_set.h -@@ -0,0 +1,498 @@ -+#ifndef _IP_SET_H -+#define _IP_SET_H -+ -+/* Copyright (C) 2000-2002 Joakim Axelsson -+ * Patrick Schaaf -+ * Martin Josefsson -+ * Copyright (C) 2003-2004 Jozsef Kadlecsik -+ * -+ * 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. -+ */ -+ -+#if 0 -+#define IP_SET_DEBUG -+#endif -+ -+/* -+ * A sockopt of such quality has hardly ever been seen before on the open -+ * market! This little beauty, hardly ever used: above 64, so it's -+ * traditionally used for firewalling, not touched (even once!) by the -+ * 2.0, 2.2 and 2.4 kernels! -+ * -+ * Comes with its own certificate of authenticity, valid anywhere in the -+ * Free world! -+ * -+ * Rusty, 19.4.2000 -+ */ -+#define SO_IP_SET 83 -+ -+/* -+ * Heavily modify by Joakim Axelsson 08.03.2002 -+ * - Made it more modulebased -+ * -+ * Additional heavy modifications by Jozsef Kadlecsik 22.02.2004 -+ * - bindings added -+ * - in order to "deal with" backward compatibility, renamed to ipset -+ */ -+ -+/* -+ * Used so that the kernel module and ipset-binary can match their versions -+ */ -+#define IP_SET_PROTOCOL_VERSION 2 -+ -+#define IP_SET_MAXNAMELEN 32 /* set names and set typenames */ -+ -+/* Lets work with our own typedef for representing an IP address. -+ * We hope to make the code more portable, possibly to IPv6... -+ * -+ * The representation works in HOST byte order, because most set types -+ * will perform arithmetic operations and compare operations. -+ * -+ * For now the type is an uint32_t. -+ * -+ * Make sure to ONLY use the functions when translating and parsing -+ * in order to keep the host byte order and make it more portable: -+ * parse_ip() -+ * parse_mask() -+ * parse_ipandmask() -+ * ip_tostring() -+ * (Joakim: where are they???) -+ */ -+ -+typedef uint32_t ip_set_ip_t; -+ -+/* Sets are identified by an id in kernel space. Tweak with ip_set_id_t -+ * and IP_SET_INVALID_ID if you want to increase the max number of sets. -+ */ -+typedef uint16_t ip_set_id_t; -+ -+#define IP_SET_INVALID_ID 65535 -+ -+/* How deep we follow bindings */ -+#define IP_SET_MAX_BINDINGS 6 -+ -+/* -+ * Option flags for kernel operations (ipt_set_info) -+ */ -+#define IPSET_SRC 0x01 /* Source match/add */ -+#define IPSET_DST 0x02 /* Destination match/add */ -+#define IPSET_MATCH_INV 0x04 /* Inverse matching */ -+ -+/* -+ * Set features -+ */ -+#define IPSET_TYPE_IP 0x01 /* IP address type of set */ -+#define IPSET_TYPE_PORT 0x02 /* Port type of set */ -+#define IPSET_DATA_SINGLE 0x04 /* Single data storage */ -+#define IPSET_DATA_DOUBLE 0x08 /* Double data storage */ -+ -+/* Reserved keywords */ -+#define IPSET_TOKEN_DEFAULT ":default:" -+#define IPSET_TOKEN_ALL ":all:" -+ -+/* SO_IP_SET operation constants, and their request struct types. -+ * -+ * Operation ids: -+ * 0-99: commands with version checking -+ * 100-199: add/del/test/bind/unbind -+ * 200-299: list, save, restore -+ */ -+ -+/* Single shot operations: -+ * version, create, destroy, flush, rename and swap -+ * -+ * Sets are identified by name. -+ */ -+ -+#define IP_SET_REQ_STD \ -+ unsigned op; \ -+ unsigned version; \ -+ char name[IP_SET_MAXNAMELEN] -+ -+#define IP_SET_OP_CREATE 0x00000001 /* Create a new (empty) set */ -+struct ip_set_req_create { -+ IP_SET_REQ_STD; -+ char typename[IP_SET_MAXNAMELEN]; -+}; -+ -+#define IP_SET_OP_DESTROY 0x00000002 /* Remove a (empty) set */ -+struct ip_set_req_std { -+ IP_SET_REQ_STD; -+}; -+ -+#define IP_SET_OP_FLUSH 0x00000003 /* Remove all IPs in a set */ -+/* Uses ip_set_req_std */ -+ -+#define IP_SET_OP_RENAME 0x00000004 /* Rename a set */ -+/* Uses ip_set_req_create */ -+ -+#define IP_SET_OP_SWAP 0x00000005 /* Swap two sets */ -+/* Uses ip_set_req_create */ -+ -+union ip_set_name_index { -+ char name[IP_SET_MAXNAMELEN]; -+ ip_set_id_t index; -+}; -+ -+#define IP_SET_OP_GET_BYNAME 0x00000006 /* Get set index by name */ -+struct ip_set_req_get_set { -+ unsigned op; -+ unsigned version; -+ union ip_set_name_index set; -+}; -+ -+#define IP_SET_OP_GET_BYINDEX 0x00000007 /* Get set name by index */ -+/* Uses ip_set_req_get_set */ -+ -+#define IP_SET_OP_VERSION 0x00000100 /* Ask kernel version */ -+struct ip_set_req_version { -+ unsigned op; -+ unsigned version; -+}; -+ -+/* Double shots operations: -+ * add, del, test, bind and unbind. -+ * -+ * First we query the kernel to get the index and type of the target set, -+ * then issue the command. Validity of IP is checked in kernel in order -+ * to minimalize sockopt operations. -+ */ -+ -+/* Get minimal set data for add/del/test/bind/unbind IP */ -+#define IP_SET_OP_ADT_GET 0x00000010 /* Get set and type */ -+struct ip_set_req_adt_get { -+ unsigned op; -+ unsigned version; -+ union ip_set_name_index set; -+ char typename[IP_SET_MAXNAMELEN]; -+}; -+ -+#define IP_SET_REQ_BYINDEX \ -+ unsigned op; \ -+ ip_set_id_t index; -+ -+struct ip_set_req_adt { -+ IP_SET_REQ_BYINDEX; -+}; -+ -+#define IP_SET_OP_ADD_IP 0x00000101 /* Add an IP to a set */ -+/* Uses ip_set_req_adt, with type specific addage */ -+ -+#define IP_SET_OP_DEL_IP 0x00000102 /* Remove an IP from a set */ -+/* Uses ip_set_req_adt, with type specific addage */ -+ -+#define IP_SET_OP_TEST_IP 0x00000103 /* Test an IP in a set */ -+/* Uses ip_set_req_adt, with type specific addage */ -+ -+#define IP_SET_OP_BIND_SET 0x00000104 /* Bind an IP to a set */ -+/* Uses ip_set_req_bind, with type specific addage */ -+struct ip_set_req_bind { -+ IP_SET_REQ_BYINDEX; -+ char binding[IP_SET_MAXNAMELEN]; -+}; -+ -+#define IP_SET_OP_UNBIND_SET 0x00000105 /* Unbind an IP from a set */ -+/* Uses ip_set_req_bind, with type speficic addage -+ * index = 0 means unbinding for all sets */ -+ -+#define IP_SET_OP_TEST_BIND_SET 0x00000106 /* Test binding an IP to a set */ -+/* Uses ip_set_req_bind, with type specific addage */ -+ -+/* Multiple shots operations: list, save, restore. -+ * -+ * - check kernel version and query the max number of sets -+ * - get the basic information on all sets -+ * and size required for the next step -+ * - get actual set data: header, data, bindings -+ */ -+ -+/* Get max_sets and the index of a queried set -+ */ -+#define IP_SET_OP_MAX_SETS 0x00000020 -+struct ip_set_req_max_sets { -+ unsigned op; -+ unsigned version; -+ ip_set_id_t max_sets; /* max_sets */ -+ ip_set_id_t sets; /* real number of sets */ -+ union ip_set_name_index set; /* index of set if name used */ -+}; -+ -+/* Get the id and name of the sets plus size for next step */ -+#define IP_SET_OP_LIST_SIZE 0x00000201 -+#define IP_SET_OP_SAVE_SIZE 0x00000202 -+struct ip_set_req_setnames { -+ unsigned op; -+ ip_set_id_t index; /* set to list/save */ -+ size_t size; /* size to get setdata/bindings */ -+ /* followed by sets number of struct ip_set_name_list */ -+}; -+ -+struct ip_set_name_list { -+ char name[IP_SET_MAXNAMELEN]; -+ char typename[IP_SET_MAXNAMELEN]; -+ ip_set_id_t index; -+ ip_set_id_t id; -+}; -+ -+/* The actual list operation */ -+#define IP_SET_OP_LIST 0x00000203 -+struct ip_set_req_list { -+ IP_SET_REQ_BYINDEX; -+ /* sets number of struct ip_set_list in reply */ -+}; -+ -+struct ip_set_list { -+ ip_set_id_t index; -+ ip_set_id_t binding; -+ u_int32_t ref; -+ size_t header_size; /* Set header data of header_size */ -+ size_t members_size; /* Set members data of members_size */ -+ size_t bindings_size; /* Set bindings data of bindings_size */ -+}; -+ -+struct ip_set_hash_list { -+ ip_set_ip_t ip; -+ ip_set_id_t binding; -+}; -+ -+/* The save operation */ -+#define IP_SET_OP_SAVE 0x00000204 -+/* Uses ip_set_req_list, in the reply replaced by -+ * sets number of struct ip_set_save plus a marker -+ * ip_set_save followed by ip_set_hash_save structures. -+ */ -+struct ip_set_save { -+ ip_set_id_t index; -+ ip_set_id_t binding; -+ size_t header_size; /* Set header data of header_size */ -+ size_t members_size; /* Set members data of members_size */ -+}; -+ -+/* At restoring, ip == 0 means default binding for the given set: */ -+struct ip_set_hash_save { -+ ip_set_ip_t ip; -+ ip_set_id_t id; -+ ip_set_id_t binding; -+}; -+ -+/* The restore operation */ -+#define IP_SET_OP_RESTORE 0x00000205 -+/* Uses ip_set_req_setnames followed by ip_set_restore structures -+ * plus a marker ip_set_restore, followed by ip_set_hash_save -+ * structures. -+ */ -+struct ip_set_restore { -+ char name[IP_SET_MAXNAMELEN]; -+ char typename[IP_SET_MAXNAMELEN]; -+ ip_set_id_t index; -+ size_t header_size; /* Create data of header_size */ -+ size_t members_size; /* Set members data of members_size */ -+}; -+ -+static inline int bitmap_bytes(ip_set_ip_t a, ip_set_ip_t b) -+{ -+ return 4 * ((((b - a + 8) / 8) + 3) / 4); -+} -+ -+#ifdef __KERNEL__ -+ -+#define ip_set_printk(format, args...) \ -+ do { \ -+ printk("%s: %s: ", __FILE__, __FUNCTION__); \ -+ printk(format "\n" , ## args); \ -+ } while (0) -+ -+#if defined(IP_SET_DEBUG) -+#define DP(format, args...) \ -+ do { \ -+ printk("%s: %s (DBG): ", __FILE__, __FUNCTION__);\ -+ printk(format "\n" , ## args); \ -+ } while (0) -+#define IP_SET_ASSERT(x) \ -+ do { \ -+ if (!(x)) \ -+ printk("IP_SET_ASSERT: %s:%i(%s)\n", \ -+ __FILE__, __LINE__, __FUNCTION__); \ -+ } while (0) -+#else -+#define DP(format, args...) -+#define IP_SET_ASSERT(x) -+#endif -+ -+struct ip_set; -+ -+/* -+ * The ip_set_type definition - one per set type, e.g. "ipmap". -+ * -+ * Each individual set has a pointer, set->type, going to one -+ * of these structures. Function pointers inside the structure implement -+ * the real behaviour of the sets. -+ * -+ * If not mentioned differently, the implementation behind the function -+ * pointers of a set_type, is expected to return 0 if ok, and a negative -+ * errno (e.g. -EINVAL) on error. -+ */ -+struct ip_set_type { -+ struct list_head list; /* next in list of set types */ -+ -+ /* test for IP in set (kernel: iptables -m set src|dst) -+ * return 0 if not in set, 1 if in set. -+ */ -+ int (*testip_kernel) (struct ip_set *set, -+ const struct sk_buff * skb, -+ ip_set_ip_t *ip, -+ const u_int32_t *flags, -+ unsigned char index); -+ -+ /* test for IP in set (userspace: ipset -T set IP) -+ * return 0 if not in set, 1 if in set. -+ */ -+ int (*testip) (struct ip_set *set, -+ const void *data, size_t size, -+ ip_set_ip_t *ip); -+ -+ /* -+ * Size of the data structure passed by when -+ * adding/deletin/testing an entry. -+ */ -+ size_t reqsize; -+ -+ /* Add IP into set (userspace: ipset -A set IP) -+ * Return -EEXIST if the address is already in the set, -+ * and -ERANGE if the address lies outside the set bounds. -+ * If the address was not already in the set, 0 is returned. -+ */ -+ int (*addip) (struct ip_set *set, -+ const void *data, size_t size, -+ ip_set_ip_t *ip); -+ -+ /* Add IP into set (kernel: iptables ... -j SET set src|dst) -+ * Return -EEXIST if the address is already in the set, -+ * and -ERANGE if the address lies outside the set bounds. -+ * If the address was not already in the set, 0 is returned. -+ */ -+ int (*addip_kernel) (struct ip_set *set, -+ const struct sk_buff * skb, -+ ip_set_ip_t *ip, -+ const u_int32_t *flags, -+ unsigned char index); -+ -+ /* remove IP from set (userspace: ipset -D set --entry x) -+ * Return -EEXIST if the address is NOT in the set, -+ * and -ERANGE if the address lies outside the set bounds. -+ * If the address really was in the set, 0 is returned. -+ */ -+ int (*delip) (struct ip_set *set, -+ const void *data, size_t size, -+ ip_set_ip_t *ip); -+ -+ /* remove IP from set (kernel: iptables ... -j SET --entry x) -+ * Return -EEXIST if the address is NOT in the set, -+ * and -ERANGE if the address lies outside the set bounds. -+ * If the address really was in the set, 0 is returned. -+ */ -+ int (*delip_kernel) (struct ip_set *set, -+ const struct sk_buff * skb, -+ ip_set_ip_t *ip, -+ const u_int32_t *flags, -+ unsigned char index); -+ -+ /* new set creation - allocated type specific items -+ */ -+ int (*create) (struct ip_set *set, -+ const void *data, size_t size); -+ -+ /* retry the operation after successfully tweaking the set -+ */ -+ int (*retry) (struct ip_set *set); -+ -+ /* set destruction - free type specific items -+ * There is no return value. -+ * Can be called only when child sets are destroyed. -+ */ -+ void (*destroy) (struct ip_set *set); -+ -+ /* set flushing - reset all bits in the set, or something similar. -+ * There is no return value. -+ */ -+ void (*flush) (struct ip_set *set); -+ -+ /* Listing: size needed for header -+ */ -+ size_t header_size; -+ -+ /* Listing: Get the header -+ * -+ * Fill in the information in "data". -+ * This function is always run after list_header_size() under a -+ * writelock on the set. Therefor is the length of "data" always -+ * correct. -+ */ -+ void (*list_header) (const struct ip_set *set, -+ void *data); -+ -+ /* Listing: Get the size for the set members -+ */ -+ int (*list_members_size) (const struct ip_set *set); -+ -+ /* Listing: Get the set members -+ * -+ * Fill in the information in "data". -+ * This function is always run after list_member_size() under a -+ * writelock on the set. Therefor is the length of "data" always -+ * correct. -+ */ -+ void (*list_members) (const struct ip_set *set, -+ void *data); -+ -+ char typename[IP_SET_MAXNAMELEN]; -+ unsigned char features; -+ int protocol_version; -+ -+ /* Set this to THIS_MODULE if you are a module, otherwise NULL */ -+ struct module *me; -+}; -+ -+extern int ip_set_register_set_type(struct ip_set_type *set_type); -+extern void ip_set_unregister_set_type(struct ip_set_type *set_type); -+ -+/* A generic ipset */ -+struct ip_set { -+ char name[IP_SET_MAXNAMELEN]; /* the name of the set */ -+ rwlock_t lock; /* lock for concurrency control */ -+ ip_set_id_t id; /* set id for swapping */ -+ ip_set_id_t binding; /* default binding for the set */ -+ atomic_t ref; /* in kernel and in hash references */ -+ struct ip_set_type *type; /* the set types */ -+ void *data; /* pooltype specific data */ -+}; -+ -+/* Structure to bind set elements to sets */ -+struct ip_set_hash { -+ struct list_head list; /* list of clashing entries in hash */ -+ ip_set_ip_t ip; /* ip from set */ -+ ip_set_id_t id; /* set id */ -+ ip_set_id_t binding; /* set we bind the element to */ -+}; -+ -+/* register and unregister set references */ -+extern ip_set_id_t ip_set_get_byname(const char name[IP_SET_MAXNAMELEN]); -+extern ip_set_id_t ip_set_get_byindex(ip_set_id_t id); -+extern void ip_set_put(ip_set_id_t id); -+ -+/* API for iptables set match, and SET target */ -+extern void ip_set_addip_kernel(ip_set_id_t id, -+ const struct sk_buff *skb, -+ const u_int32_t *flags); -+extern void ip_set_delip_kernel(ip_set_id_t id, -+ const struct sk_buff *skb, -+ const u_int32_t *flags); -+extern int ip_set_testip_kernel(ip_set_id_t id, -+ const struct sk_buff *skb, -+ const u_int32_t *flags); -+ -+#endif /* __KERNEL__ */ -+ -+#endif /*_IP_SET_H*/ ---- /dev/null -+++ b/include/linux/netfilter_ipv4/ip_set_iphash.h -@@ -0,0 +1,30 @@ -+#ifndef __IP_SET_IPHASH_H -+#define __IP_SET_IPHASH_H -+ -+#include -+ -+#define SETTYPE_NAME "iphash" -+#define MAX_RANGE 0x0000FFFF -+ -+struct ip_set_iphash { -+ ip_set_ip_t *members; /* the iphash proper */ -+ uint32_t elements; /* number of elements */ -+ uint32_t hashsize; /* hash size */ -+ uint16_t probes; /* max number of probes */ -+ uint16_t resize; /* resize factor in percent */ -+ ip_set_ip_t netmask; /* netmask */ -+ void *initval[0]; /* initvals for jhash_1word */ -+}; -+ -+struct ip_set_req_iphash_create { -+ uint32_t hashsize; -+ uint16_t probes; -+ uint16_t resize; -+ ip_set_ip_t netmask; -+}; -+ -+struct ip_set_req_iphash { -+ ip_set_ip_t ip; -+}; -+ -+#endif /* __IP_SET_IPHASH_H */ ---- /dev/null -+++ b/include/linux/netfilter_ipv4/ip_set_ipmap.h -@@ -0,0 +1,56 @@ -+#ifndef __IP_SET_IPMAP_H -+#define __IP_SET_IPMAP_H -+ -+#include -+ -+#define SETTYPE_NAME "ipmap" -+#define MAX_RANGE 0x0000FFFF -+ -+struct ip_set_ipmap { -+ void *members; /* the ipmap proper */ -+ ip_set_ip_t first_ip; /* host byte order, included in range */ -+ ip_set_ip_t last_ip; /* host byte order, included in range */ -+ ip_set_ip_t netmask; /* subnet netmask */ -+ ip_set_ip_t sizeid; /* size of set in IPs */ -+ ip_set_ip_t hosts; /* number of hosts in a subnet */ -+}; -+ -+struct ip_set_req_ipmap_create { -+ ip_set_ip_t from; -+ ip_set_ip_t to; -+ ip_set_ip_t netmask; -+}; -+ -+struct ip_set_req_ipmap { -+ ip_set_ip_t ip; -+}; -+ -+unsigned int -+mask_to_bits(ip_set_ip_t mask) -+{ -+ unsigned int bits = 32; -+ ip_set_ip_t maskaddr; -+ -+ if (mask == 0xFFFFFFFF) -+ return bits; -+ -+ maskaddr = 0xFFFFFFFE; -+ while (--bits >= 0 && maskaddr != mask) -+ maskaddr <<= 1; -+ -+ return bits; -+} -+ -+ip_set_ip_t -+range_to_mask(ip_set_ip_t from, ip_set_ip_t to, unsigned int *bits) -+{ -+ ip_set_ip_t mask = 0xFFFFFFFE; -+ -+ *bits = 32; -+ while (--(*bits) >= 0 && mask && (to & mask) != from) -+ mask <<= 1; -+ -+ return mask; -+} -+ -+#endif /* __IP_SET_IPMAP_H */ ---- /dev/null -+++ b/include/linux/netfilter_ipv4/ip_set_ipporthash.h -@@ -0,0 +1,34 @@ -+#ifndef __IP_SET_IPPORTHASH_H -+#define __IP_SET_IPPORTHASH_H -+ -+#include -+ -+#define SETTYPE_NAME "ipporthash" -+#define MAX_RANGE 0x0000FFFF -+#define INVALID_PORT (MAX_RANGE + 1) -+ -+struct ip_set_ipporthash { -+ ip_set_ip_t *members; /* the ipporthash proper */ -+ uint32_t elements; /* number of elements */ -+ uint32_t hashsize; /* hash size */ -+ uint16_t probes; /* max number of probes */ -+ uint16_t resize; /* resize factor in percent */ -+ ip_set_ip_t first_ip; /* host byte order, included in range */ -+ ip_set_ip_t last_ip; /* host byte order, included in range */ -+ void *initval[0]; /* initvals for jhash_1word */ -+}; -+ -+struct ip_set_req_ipporthash_create { -+ uint32_t hashsize; -+ uint16_t probes; -+ uint16_t resize; -+ ip_set_ip_t from; -+ ip_set_ip_t to; -+}; -+ -+struct ip_set_req_ipporthash { -+ ip_set_ip_t ip; -+ ip_set_ip_t port; -+}; -+ -+#endif /* __IP_SET_IPPORTHASH_H */ ---- /dev/null -+++ b/include/linux/netfilter_ipv4/ip_set_iptree.h -@@ -0,0 +1,40 @@ -+#ifndef __IP_SET_IPTREE_H -+#define __IP_SET_IPTREE_H -+ -+#include -+ -+#define SETTYPE_NAME "iptree" -+#define MAX_RANGE 0x0000FFFF -+ -+struct ip_set_iptreed { -+ unsigned long expires[256]; /* x.x.x.ADDR */ -+}; -+ -+struct ip_set_iptreec { -+ struct ip_set_iptreed *tree[256]; /* x.x.ADDR.* */ -+}; -+ -+struct ip_set_iptreeb { -+ struct ip_set_iptreec *tree[256]; /* x.ADDR.*.* */ -+}; -+ -+struct ip_set_iptree { -+ unsigned int timeout; -+ unsigned int gc_interval; -+#ifdef __KERNEL__ -+ uint32_t elements; /* number of elements */ -+ struct timer_list gc; -+ struct ip_set_iptreeb *tree[256]; /* ADDR.*.*.* */ -+#endif -+}; -+ -+struct ip_set_req_iptree_create { -+ unsigned int timeout; -+}; -+ -+struct ip_set_req_iptree { -+ ip_set_ip_t ip; -+ unsigned int timeout; -+}; -+ -+#endif /* __IP_SET_IPTREE_H */ ---- /dev/null -+++ b/include/linux/netfilter_ipv4/ip_set_iptreemap.h -@@ -0,0 +1,40 @@ -+#ifndef __IP_SET_IPTREEMAP_H -+#define __IP_SET_IPTREEMAP_H -+ -+#include -+ -+#define SETTYPE_NAME "iptreemap" -+ -+#ifdef __KERNEL__ -+struct ip_set_iptreemap_d { -+ unsigned char bitmap[32]; /* x.x.x.y */ -+}; -+ -+struct ip_set_iptreemap_c { -+ struct ip_set_iptreemap_d *tree[256]; /* x.x.y.x */ -+}; -+ -+struct ip_set_iptreemap_b { -+ struct ip_set_iptreemap_c *tree[256]; /* x.y.x.x */ -+ unsigned char dirty[32]; -+}; -+#endif -+ -+struct ip_set_iptreemap { -+ unsigned int gc_interval; -+#ifdef __KERNEL__ -+ struct timer_list gc; -+ struct ip_set_iptreemap_b *tree[256]; /* y.x.x.x */ -+#endif -+}; -+ -+struct ip_set_req_iptreemap_create { -+ unsigned int gc_interval; -+}; -+ -+struct ip_set_req_iptreemap { -+ ip_set_ip_t start; -+ ip_set_ip_t end; -+}; -+ -+#endif /* __IP_SET_IPTREEMAP_H */ ---- /dev/null -+++ b/include/linux/netfilter_ipv4/ip_set_jhash.h -@@ -0,0 +1,148 @@ -+#ifndef _LINUX_IPSET_JHASH_H -+#define _LINUX_IPSET_JHASH_H -+ -+/* This is a copy of linux/jhash.h but the types u32/u8 are changed -+ * to __u32/__u8 so that the header file can be included into -+ * userspace code as well. Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) -+ */ -+ -+/* jhash.h: Jenkins hash support. -+ * -+ * Copyright (C) 1996 Bob Jenkins (bob_jenkins@burtleburtle.net) -+ * -+ * http://burtleburtle.net/bob/hash/ -+ * -+ * These are the credits from Bob's sources: -+ * -+ * lookup2.c, by Bob Jenkins, December 1996, Public Domain. -+ * hash(), hash2(), hash3, and mix() are externally useful functions. -+ * Routines to test the hash are included if SELF_TEST is defined. -+ * You can use this free for any purpose. It has no warranty. -+ * -+ * Copyright (C) 2003 David S. Miller (davem@redhat.com) -+ * -+ * I've modified Bob's hash to be useful in the Linux kernel, and -+ * any bugs present are surely my fault. -DaveM -+ */ -+ -+/* NOTE: Arguments are modified. */ -+#define __jhash_mix(a, b, c) \ -+{ \ -+ a -= b; a -= c; a ^= (c>>13); \ -+ b -= c; b -= a; b ^= (a<<8); \ -+ c -= a; c -= b; c ^= (b>>13); \ -+ a -= b; a -= c; a ^= (c>>12); \ -+ b -= c; b -= a; b ^= (a<<16); \ -+ c -= a; c -= b; c ^= (b>>5); \ -+ a -= b; a -= c; a ^= (c>>3); \ -+ b -= c; b -= a; b ^= (a<<10); \ -+ c -= a; c -= b; c ^= (b>>15); \ -+} -+ -+/* The golden ration: an arbitrary value */ -+#define JHASH_GOLDEN_RATIO 0x9e3779b9 -+ -+/* The most generic version, hashes an arbitrary sequence -+ * of bytes. No alignment or length assumptions are made about -+ * the input key. -+ */ -+static inline __u32 jhash(void *key, __u32 length, __u32 initval) -+{ -+ __u32 a, b, c, len; -+ __u8 *k = key; -+ -+ len = length; -+ a = b = JHASH_GOLDEN_RATIO; -+ c = initval; -+ -+ while (len >= 12) { -+ a += (k[0] +((__u32)k[1]<<8) +((__u32)k[2]<<16) +((__u32)k[3]<<24)); -+ b += (k[4] +((__u32)k[5]<<8) +((__u32)k[6]<<16) +((__u32)k[7]<<24)); -+ c += (k[8] +((__u32)k[9]<<8) +((__u32)k[10]<<16)+((__u32)k[11]<<24)); -+ -+ __jhash_mix(a,b,c); -+ -+ k += 12; -+ len -= 12; -+ } -+ -+ c += length; -+ switch (len) { -+ case 11: c += ((__u32)k[10]<<24); -+ case 10: c += ((__u32)k[9]<<16); -+ case 9 : c += ((__u32)k[8]<<8); -+ case 8 : b += ((__u32)k[7]<<24); -+ case 7 : b += ((__u32)k[6]<<16); -+ case 6 : b += ((__u32)k[5]<<8); -+ case 5 : b += k[4]; -+ case 4 : a += ((__u32)k[3]<<24); -+ case 3 : a += ((__u32)k[2]<<16); -+ case 2 : a += ((__u32)k[1]<<8); -+ case 1 : a += k[0]; -+ }; -+ -+ __jhash_mix(a,b,c); -+ -+ return c; -+} -+ -+/* A special optimized version that handles 1 or more of __u32s. -+ * The length parameter here is the number of __u32s in the key. -+ */ -+static inline __u32 jhash2(__u32 *k, __u32 length, __u32 initval) -+{ -+ __u32 a, b, c, len; -+ -+ a = b = JHASH_GOLDEN_RATIO; -+ c = initval; -+ len = length; -+ -+ while (len >= 3) { -+ a += k[0]; -+ b += k[1]; -+ c += k[2]; -+ __jhash_mix(a, b, c); -+ k += 3; len -= 3; -+ } -+ -+ c += length * 4; -+ -+ switch (len) { -+ case 2 : b += k[1]; -+ case 1 : a += k[0]; -+ }; -+ -+ __jhash_mix(a,b,c); -+ -+ return c; -+} -+ -+ -+/* A special ultra-optimized versions that knows they are hashing exactly -+ * 3, 2 or 1 word(s). -+ * -+ * NOTE: In partilar the "c += length; __jhash_mix(a,b,c);" normally -+ * done at the end is not done here. -+ */ -+static inline __u32 jhash_3words(__u32 a, __u32 b, __u32 c, __u32 initval) -+{ -+ a += JHASH_GOLDEN_RATIO; -+ b += JHASH_GOLDEN_RATIO; -+ c += initval; -+ -+ __jhash_mix(a, b, c); -+ -+ return c; -+} -+ -+static inline __u32 jhash_2words(__u32 a, __u32 b, __u32 initval) -+{ -+ return jhash_3words(a, b, 0, initval); -+} -+ -+static inline __u32 jhash_1word(__u32 a, __u32 initval) -+{ -+ return jhash_3words(a, 0, 0, initval); -+} -+ -+#endif /* _LINUX_IPSET_JHASH_H */ ---- /dev/null -+++ b/include/linux/netfilter_ipv4/ip_set_macipmap.h -@@ -0,0 +1,38 @@ -+#ifndef __IP_SET_MACIPMAP_H -+#define __IP_SET_MACIPMAP_H -+ -+#include -+ -+#define SETTYPE_NAME "macipmap" -+#define MAX_RANGE 0x0000FFFF -+ -+/* general flags */ -+#define IPSET_MACIP_MATCHUNSET 1 -+ -+/* per ip flags */ -+#define IPSET_MACIP_ISSET 1 -+ -+struct ip_set_macipmap { -+ void *members; /* the macipmap proper */ -+ ip_set_ip_t first_ip; /* host byte order, included in range */ -+ ip_set_ip_t last_ip; /* host byte order, included in range */ -+ u_int32_t flags; -+}; -+ -+struct ip_set_req_macipmap_create { -+ ip_set_ip_t from; -+ ip_set_ip_t to; -+ u_int32_t flags; -+}; -+ -+struct ip_set_req_macipmap { -+ ip_set_ip_t ip; -+ unsigned char ethernet[ETH_ALEN]; -+}; -+ -+struct ip_set_macip { -+ unsigned short flags; -+ unsigned char ethernet[ETH_ALEN]; -+}; -+ -+#endif /* __IP_SET_MACIPMAP_H */ ---- /dev/null -+++ b/include/linux/netfilter_ipv4/ip_set_malloc.h -@@ -0,0 +1,116 @@ -+#ifndef _IP_SET_MALLOC_H -+#define _IP_SET_MALLOC_H -+ -+#ifdef __KERNEL__ -+ -+/* Memory allocation and deallocation */ -+static size_t max_malloc_size = 0; -+ -+static inline void init_max_malloc_size(void) -+{ -+#define CACHE(x) max_malloc_size = x; -+#include -+#undef CACHE -+} -+ -+static inline void * ip_set_malloc(size_t bytes) -+{ -+ if (bytes > max_malloc_size) -+ return vmalloc(bytes); -+ else -+ return kmalloc(bytes, GFP_KERNEL); -+} -+ -+static inline void ip_set_free(void * data, size_t bytes) -+{ -+ if (bytes > max_malloc_size) -+ vfree(data); -+ else -+ kfree(data); -+} -+ -+struct harray { -+ size_t max_elements; -+ void *arrays[0]; -+}; -+ -+static inline void * -+harray_malloc(size_t hashsize, size_t typesize, int flags) -+{ -+ struct harray *harray; -+ size_t max_elements, size, i, j; -+ -+ if (!max_malloc_size) -+ init_max_malloc_size(); -+ -+ if (typesize > max_malloc_size) -+ return NULL; -+ -+ max_elements = max_malloc_size/typesize; -+ size = hashsize/max_elements; -+ if (hashsize % max_elements) -+ size++; -+ -+ /* Last pointer signals end of arrays */ -+ harray = kmalloc(sizeof(struct harray) + (size + 1) * sizeof(void *), -+ flags); -+ -+ if (!harray) -+ return NULL; -+ -+ for (i = 0; i < size - 1; i++) { -+ harray->arrays[i] = kmalloc(max_elements * typesize, flags); -+ if (!harray->arrays[i]) -+ goto undo; -+ memset(harray->arrays[i], 0, max_elements * typesize); -+ } -+ harray->arrays[i] = kmalloc((hashsize - i * max_elements) * typesize, -+ flags); -+ if (!harray->arrays[i]) -+ goto undo; -+ memset(harray->arrays[i], 0, (hashsize - i * max_elements) * typesize); -+ -+ harray->max_elements = max_elements; -+ harray->arrays[size] = NULL; -+ -+ return (void *)harray; -+ -+ undo: -+ for (j = 0; j < i; j++) { -+ kfree(harray->arrays[j]); -+ } -+ kfree(harray); -+ return NULL; -+} -+ -+static inline void harray_free(void *h) -+{ -+ struct harray *harray = (struct harray *) h; -+ size_t i; -+ -+ for (i = 0; harray->arrays[i] != NULL; i++) -+ kfree(harray->arrays[i]); -+ kfree(harray); -+} -+ -+static inline void harray_flush(void *h, size_t hashsize, size_t typesize) -+{ -+ struct harray *harray = (struct harray *) h; -+ size_t i; -+ -+ for (i = 0; harray->arrays[i+1] != NULL; i++) -+ memset(harray->arrays[i], 0, harray->max_elements * typesize); -+ memset(harray->arrays[i], 0, -+ (hashsize - i * harray->max_elements) * typesize); -+} -+ -+#define HARRAY_ELEM(h, type, which) \ -+({ \ -+ struct harray *__h = (struct harray *)(h); \ -+ ((type)((__h)->arrays[(which)/(__h)->max_elements]) \ -+ + (which)%(__h)->max_elements); \ -+}) -+ -+#endif /* __KERNEL__ */ -+ -+#endif /*_IP_SET_MALLOC_H*/ ---- /dev/null -+++ b/include/linux/netfilter_ipv4/ip_set_nethash.h -@@ -0,0 +1,55 @@ -+#ifndef __IP_SET_NETHASH_H -+#define __IP_SET_NETHASH_H -+ -+#include -+ -+#define SETTYPE_NAME "nethash" -+#define MAX_RANGE 0x0000FFFF -+ -+struct ip_set_nethash { -+ ip_set_ip_t *members; /* the nethash proper */ -+ uint32_t elements; /* number of elements */ -+ uint32_t hashsize; /* hash size */ -+ uint16_t probes; /* max number of probes */ -+ uint16_t resize; /* resize factor in percent */ -+ unsigned char cidr[30]; /* CIDR sizes */ -+ void *initval[0]; /* initvals for jhash_1word */ -+}; -+ -+struct ip_set_req_nethash_create { -+ uint32_t hashsize; -+ uint16_t probes; -+ uint16_t resize; -+}; -+ -+struct ip_set_req_nethash { -+ ip_set_ip_t ip; -+ unsigned char cidr; -+}; -+ -+static unsigned char shifts[] = {255, 253, 249, 241, 225, 193, 129, 1}; -+ -+static inline ip_set_ip_t -+pack(ip_set_ip_t ip, unsigned char cidr) -+{ -+ ip_set_ip_t addr, *paddr = &addr; -+ unsigned char n, t, *a; -+ -+ addr = htonl(ip & (0xFFFFFFFF << (32 - (cidr)))); -+#ifdef __KERNEL__ -+ DP("ip:%u.%u.%u.%u/%u", NIPQUAD(addr), cidr); -+#endif -+ n = cidr / 8; -+ t = cidr % 8; -+ a = &((unsigned char *)paddr)[n]; -+ *a = *a /(1 << (8 - t)) + shifts[t]; -+#ifdef __KERNEL__ -+ DP("n: %u, t: %u, a: %u", n, t, *a); -+ DP("ip:%u.%u.%u.%u/%u, %u.%u.%u.%u", -+ HIPQUAD(ip), cidr, NIPQUAD(addr)); -+#endif -+ -+ return ntohl(addr); -+} -+ -+#endif /* __IP_SET_NETHASH_H */ ---- /dev/null -+++ b/include/linux/netfilter_ipv4/ip_set_portmap.h -@@ -0,0 +1,25 @@ -+#ifndef __IP_SET_PORTMAP_H -+#define __IP_SET_PORTMAP_H -+ -+#include -+ -+#define SETTYPE_NAME "portmap" -+#define MAX_RANGE 0x0000FFFF -+#define INVALID_PORT (MAX_RANGE + 1) -+ -+struct ip_set_portmap { -+ void *members; /* the portmap proper */ -+ ip_set_ip_t first_port; /* host byte order, included in range */ -+ ip_set_ip_t last_port; /* host byte order, included in range */ -+}; -+ -+struct ip_set_req_portmap_create { -+ ip_set_ip_t from; -+ ip_set_ip_t to; -+}; -+ -+struct ip_set_req_portmap { -+ ip_set_ip_t port; -+}; -+ -+#endif /* __IP_SET_PORTMAP_H */ ---- /dev/null -+++ b/include/linux/netfilter_ipv4/ipt_set.h -@@ -0,0 +1,21 @@ -+#ifndef _IPT_SET_H -+#define _IPT_SET_H -+ -+#include -+ -+struct ipt_set_info { -+ ip_set_id_t index; -+ u_int32_t flags[IP_SET_MAX_BINDINGS + 1]; -+}; -+ -+/* match info */ -+struct ipt_set_info_match { -+ struct ipt_set_info match_set; -+}; -+ -+struct ipt_set_info_target { -+ struct ipt_set_info add_set; -+ struct ipt_set_info del_set; -+}; -+ -+#endif /*_IPT_SET_H*/ ---- /dev/null -+++ b/net/ipv4/netfilter/ip_set.c -@@ -0,0 +1,2003 @@ -+/* Copyright (C) 2000-2002 Joakim Axelsson -+ * Patrick Schaaf -+ * Copyright (C) 2003-2004 Jozsef Kadlecsik -+ * -+ * 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. -+ */ -+ -+/* Kernel module for IP set management */ -+ -+#include -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) -+#include -+#endif -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define ASSERT_READ_LOCK(x) -+#define ASSERT_WRITE_LOCK(x) -+#include -+ -+static struct list_head set_type_list; /* all registered sets */ -+static struct ip_set **ip_set_list; /* all individual sets */ -+static DEFINE_RWLOCK(ip_set_lock); /* protects the lists and the hash */ -+static DECLARE_MUTEX(ip_set_app_mutex); /* serializes user access */ -+static ip_set_id_t ip_set_max = CONFIG_IP_NF_SET_MAX; -+static ip_set_id_t ip_set_bindings_hash_size = CONFIG_IP_NF_SET_HASHSIZE; -+static struct list_head *ip_set_hash; /* hash of bindings */ -+static unsigned int ip_set_hash_random; /* random seed */ -+ -+/* -+ * Sets are identified either by the index in ip_set_list or by id. -+ * The id never changes and is used to find a key in the hash. -+ * The index may change by swapping and used at all other places -+ * (set/SET netfilter modules, binding value, etc.) -+ * -+ * Userspace requests are serialized by ip_set_mutex and sets can -+ * be deleted only from userspace. Therefore ip_set_list locking -+ * must obey the following rules: -+ * -+ * - kernel requests: read and write locking mandatory -+ * - user requests: read locking optional, write locking mandatory -+ */ -+ -+static inline void -+__ip_set_get(ip_set_id_t index) -+{ -+ atomic_inc(&ip_set_list[index]->ref); -+} -+ -+static inline void -+__ip_set_put(ip_set_id_t index) -+{ -+ atomic_dec(&ip_set_list[index]->ref); -+} -+ -+/* -+ * Binding routines -+ */ -+ -+static inline struct ip_set_hash * -+__ip_set_find(u_int32_t key, ip_set_id_t id, ip_set_ip_t ip) -+{ -+ struct ip_set_hash *set_hash; -+ -+ list_for_each_entry(set_hash, &ip_set_hash[key], list) -+ if (set_hash->id == id && set_hash->ip == ip) -+ return set_hash; -+ -+ return NULL; -+} -+ -+static ip_set_id_t -+ip_set_find_in_hash(ip_set_id_t id, ip_set_ip_t ip) -+{ -+ u_int32_t key = jhash_2words(id, ip, ip_set_hash_random) -+ % ip_set_bindings_hash_size; -+ struct ip_set_hash *set_hash; -+ -+ ASSERT_READ_LOCK(&ip_set_lock); -+ IP_SET_ASSERT(ip_set_list[id]); -+ DP("set: %s, ip: %u.%u.%u.%u", ip_set_list[id]->name, HIPQUAD(ip)); -+ -+ set_hash = __ip_set_find(key, id, ip); -+ -+ DP("set: %s, ip: %u.%u.%u.%u, binding: %s", ip_set_list[id]->name, -+ HIPQUAD(ip), -+ set_hash != NULL ? ip_set_list[set_hash->binding]->name : ""); -+ -+ return (set_hash != NULL ? set_hash->binding : IP_SET_INVALID_ID); -+} -+ -+static inline void -+__set_hash_del(struct ip_set_hash *set_hash) -+{ -+ ASSERT_WRITE_LOCK(&ip_set_lock); -+ IP_SET_ASSERT(ip_set_list[set_hash->binding]); -+ -+ __ip_set_put(set_hash->binding); -+ list_del(&set_hash->list); -+ kfree(set_hash); -+} -+ -+static int -+ip_set_hash_del(ip_set_id_t id, ip_set_ip_t ip) -+{ -+ u_int32_t key = jhash_2words(id, ip, ip_set_hash_random) -+ % ip_set_bindings_hash_size; -+ struct ip_set_hash *set_hash; -+ -+ IP_SET_ASSERT(ip_set_list[id]); -+ DP("set: %s, ip: %u.%u.%u.%u", ip_set_list[id]->name, HIPQUAD(ip)); -+ write_lock_bh(&ip_set_lock); -+ set_hash = __ip_set_find(key, id, ip); -+ DP("set: %s, ip: %u.%u.%u.%u, binding: %s", ip_set_list[id]->name, -+ HIPQUAD(ip), -+ set_hash != NULL ? ip_set_list[set_hash->binding]->name : ""); -+ -+ if (set_hash != NULL) -+ __set_hash_del(set_hash); -+ write_unlock_bh(&ip_set_lock); -+ return 0; -+} -+ -+static int -+ip_set_hash_add(ip_set_id_t id, ip_set_ip_t ip, ip_set_id_t binding) -+{ -+ u_int32_t key = jhash_2words(id, ip, ip_set_hash_random) -+ % ip_set_bindings_hash_size; -+ struct ip_set_hash *set_hash; -+ int ret = 0; -+ -+ IP_SET_ASSERT(ip_set_list[id]); -+ IP_SET_ASSERT(ip_set_list[binding]); -+ DP("set: %s, ip: %u.%u.%u.%u, binding: %s", ip_set_list[id]->name, -+ HIPQUAD(ip), ip_set_list[binding]->name); -+ write_lock_bh(&ip_set_lock); -+ set_hash = __ip_set_find(key, id, ip); -+ if (!set_hash) { -+ set_hash = kmalloc(sizeof(struct ip_set_hash), GFP_ATOMIC); -+ if (!set_hash) { -+ ret = -ENOMEM; -+ goto unlock; -+ } -+ INIT_LIST_HEAD(&set_hash->list); -+ set_hash->id = id; -+ set_hash->ip = ip; -+ list_add(&set_hash->list, &ip_set_hash[key]); -+ } else { -+ IP_SET_ASSERT(ip_set_list[set_hash->binding]); -+ DP("overwrite binding: %s", -+ ip_set_list[set_hash->binding]->name); -+ __ip_set_put(set_hash->binding); -+ } -+ set_hash->binding = binding; -+ __ip_set_get(set_hash->binding); -+ DP("stored: key %u, id %u (%s), ip %u.%u.%u.%u, binding %u (%s)", -+ key, id, ip_set_list[id]->name, -+ HIPQUAD(ip), binding, ip_set_list[binding]->name); -+ unlock: -+ write_unlock_bh(&ip_set_lock); -+ return ret; -+} -+ -+#define FOREACH_HASH_DO(fn, args...) \ -+({ \ -+ ip_set_id_t __key; \ -+ struct ip_set_hash *__set_hash; \ -+ \ -+ for (__key = 0; __key < ip_set_bindings_hash_size; __key++) { \ -+ list_for_each_entry(__set_hash, &ip_set_hash[__key], list) \ -+ fn(__set_hash , ## args); \ -+ } \ -+}) -+ -+#define FOREACH_HASH_RW_DO(fn, args...) \ -+({ \ -+ ip_set_id_t __key; \ -+ struct ip_set_hash *__set_hash, *__n; \ -+ \ -+ ASSERT_WRITE_LOCK(&ip_set_lock); \ -+ for (__key = 0; __key < ip_set_bindings_hash_size; __key++) { \ -+ list_for_each_entry_safe(__set_hash, __n, &ip_set_hash[__key], list)\ -+ fn(__set_hash , ## args); \ -+ } \ -+}) -+ -+/* Add, del and test set entries from kernel */ -+ -+#define follow_bindings(index, set, ip) \ -+((index = ip_set_find_in_hash((set)->id, ip)) != IP_SET_INVALID_ID \ -+ || (index = (set)->binding) != IP_SET_INVALID_ID) -+ -+int -+ip_set_testip_kernel(ip_set_id_t index, -+ const struct sk_buff *skb, -+ const u_int32_t *flags) -+{ -+ struct ip_set *set; -+ ip_set_ip_t ip; -+ int res; -+ unsigned char i = 0; -+ -+ IP_SET_ASSERT(flags[i]); -+ read_lock_bh(&ip_set_lock); -+ do { -+ set = ip_set_list[index]; -+ IP_SET_ASSERT(set); -+ DP("set %s, index %u", set->name, index); -+ read_lock_bh(&set->lock); -+ res = set->type->testip_kernel(set, skb, &ip, flags, i++); -+ read_unlock_bh(&set->lock); -+ i += !!(set->type->features & IPSET_DATA_DOUBLE); -+ } while (res > 0 -+ && flags[i] -+ && follow_bindings(index, set, ip)); -+ read_unlock_bh(&ip_set_lock); -+ -+ return res; -+} -+ -+void -+ip_set_addip_kernel(ip_set_id_t index, -+ const struct sk_buff *skb, -+ const u_int32_t *flags) -+{ -+ struct ip_set *set; -+ ip_set_ip_t ip; -+ int res; -+ unsigned char i = 0; -+ -+ IP_SET_ASSERT(flags[i]); -+ retry: -+ read_lock_bh(&ip_set_lock); -+ do { -+ set = ip_set_list[index]; -+ IP_SET_ASSERT(set); -+ DP("set %s, index %u", set->name, index); -+ write_lock_bh(&set->lock); -+ res = set->type->addip_kernel(set, skb, &ip, flags, i++); -+ write_unlock_bh(&set->lock); -+ i += !!(set->type->features & IPSET_DATA_DOUBLE); -+ } while ((res == 0 || res == -EEXIST) -+ && flags[i] -+ && follow_bindings(index, set, ip)); -+ read_unlock_bh(&ip_set_lock); -+ -+ if (res == -EAGAIN -+ && set->type->retry -+ && (res = set->type->retry(set)) == 0) -+ goto retry; -+} -+ -+void -+ip_set_delip_kernel(ip_set_id_t index, -+ const struct sk_buff *skb, -+ const u_int32_t *flags) -+{ -+ struct ip_set *set; -+ ip_set_ip_t ip; -+ int res; -+ unsigned char i = 0; -+ -+ IP_SET_ASSERT(flags[i]); -+ read_lock_bh(&ip_set_lock); -+ do { -+ set = ip_set_list[index]; -+ IP_SET_ASSERT(set); -+ DP("set %s, index %u", set->name, index); -+ write_lock_bh(&set->lock); -+ res = set->type->delip_kernel(set, skb, &ip, flags, i++); -+ write_unlock_bh(&set->lock); -+ i += !!(set->type->features & IPSET_DATA_DOUBLE); -+ } while ((res == 0 || res == -EEXIST) -+ && flags[i] -+ && follow_bindings(index, set, ip)); -+ read_unlock_bh(&ip_set_lock); -+} -+ -+/* Register and deregister settype */ -+ -+static inline struct ip_set_type * -+find_set_type(const char *name) -+{ -+ struct ip_set_type *set_type; -+ -+ list_for_each_entry(set_type, &set_type_list, list) -+ if (!strncmp(set_type->typename, name, IP_SET_MAXNAMELEN - 1)) -+ return set_type; -+ return NULL; -+} -+ -+int -+ip_set_register_set_type(struct ip_set_type *set_type) -+{ -+ int ret = 0; -+ -+ if (set_type->protocol_version != IP_SET_PROTOCOL_VERSION) { -+ ip_set_printk("'%s' uses wrong protocol version %u (want %u)", -+ set_type->typename, -+ set_type->protocol_version, -+ IP_SET_PROTOCOL_VERSION); -+ return -EINVAL; -+ } -+ -+ write_lock_bh(&ip_set_lock); -+ if (find_set_type(set_type->typename)) { -+ /* Duplicate! */ -+ ip_set_printk("'%s' already registered!", -+ set_type->typename); -+ ret = -EINVAL; -+ goto unlock; -+ } -+ if (!try_module_get(THIS_MODULE)) { -+ ret = -EFAULT; -+ goto unlock; -+ } -+ list_add(&set_type->list, &set_type_list); -+ DP("'%s' registered.", set_type->typename); -+ unlock: -+ write_unlock_bh(&ip_set_lock); -+ return ret; -+} -+ -+void -+ip_set_unregister_set_type(struct ip_set_type *set_type) -+{ -+ write_lock_bh(&ip_set_lock); -+ if (!find_set_type(set_type->typename)) { -+ ip_set_printk("'%s' not registered?", -+ set_type->typename); -+ goto unlock; -+ } -+ list_del(&set_type->list); -+ module_put(THIS_MODULE); -+ DP("'%s' unregistered.", set_type->typename); -+ unlock: -+ write_unlock_bh(&ip_set_lock); -+ -+} -+ -+/* -+ * Userspace routines -+ */ -+ -+/* -+ * Find set by name, reference it once. The reference makes sure the -+ * thing pointed to, does not go away under our feet. Drop the reference -+ * later, using ip_set_put(). -+ */ -+ip_set_id_t -+ip_set_get_byname(const char *name) -+{ -+ ip_set_id_t i, index = IP_SET_INVALID_ID; -+ -+ down(&ip_set_app_mutex); -+ for (i = 0; i < ip_set_max; i++) { -+ if (ip_set_list[i] != NULL -+ && strcmp(ip_set_list[i]->name, name) == 0) { -+ __ip_set_get(i); -+ index = i; -+ break; -+ } -+ } -+ up(&ip_set_app_mutex); -+ return index; -+} -+ -+/* -+ * Find set by index, reference it once. The reference makes sure the -+ * thing pointed to, does not go away under our feet. Drop the reference -+ * later, using ip_set_put(). -+ */ -+ip_set_id_t -+ip_set_get_byindex(ip_set_id_t index) -+{ -+ down(&ip_set_app_mutex); -+ -+ if (index >= ip_set_max) -+ return IP_SET_INVALID_ID; -+ -+ if (ip_set_list[index]) -+ __ip_set_get(index); -+ else -+ index = IP_SET_INVALID_ID; -+ -+ up(&ip_set_app_mutex); -+ return index; -+} -+ -+/* -+ * If the given set pointer points to a valid set, decrement -+ * reference count by 1. The caller shall not assume the index -+ * to be valid, after calling this function. -+ */ -+void ip_set_put(ip_set_id_t index) -+{ -+ down(&ip_set_app_mutex); -+ if (ip_set_list[index]) -+ __ip_set_put(index); -+ up(&ip_set_app_mutex); -+} -+ -+/* Find a set by name or index */ -+static ip_set_id_t -+ip_set_find_byname(const char *name) -+{ -+ ip_set_id_t i, index = IP_SET_INVALID_ID; -+ -+ for (i = 0; i < ip_set_max; i++) { -+ if (ip_set_list[i] != NULL -+ && strcmp(ip_set_list[i]->name, name) == 0) { -+ index = i; -+ break; -+ } -+ } -+ return index; -+} -+ -+static ip_set_id_t -+ip_set_find_byindex(ip_set_id_t index) -+{ -+ if (index >= ip_set_max || ip_set_list[index] == NULL) -+ index = IP_SET_INVALID_ID; -+ -+ return index; -+} -+ -+/* -+ * Add, del, test, bind and unbind -+ */ -+ -+static inline int -+__ip_set_testip(struct ip_set *set, -+ const void *data, -+ size_t size, -+ ip_set_ip_t *ip) -+{ -+ int res; -+ -+ read_lock_bh(&set->lock); -+ res = set->type->testip(set, data, size, ip); -+ read_unlock_bh(&set->lock); -+ -+ return res; -+} -+ -+static int -+__ip_set_addip(ip_set_id_t index, -+ const void *data, -+ size_t size) -+{ -+ struct ip_set *set = ip_set_list[index]; -+ ip_set_ip_t ip; -+ int res; -+ -+ IP_SET_ASSERT(set); -+ do { -+ write_lock_bh(&set->lock); -+ res = set->type->addip(set, data, size, &ip); -+ write_unlock_bh(&set->lock); -+ } while (res == -EAGAIN -+ && set->type->retry -+ && (res = set->type->retry(set)) == 0); -+ -+ return res; -+} -+ -+static int -+ip_set_addip(ip_set_id_t index, -+ const void *data, -+ size_t size) -+{ -+ -+ return __ip_set_addip(index, -+ data + sizeof(struct ip_set_req_adt), -+ size - sizeof(struct ip_set_req_adt)); -+} -+ -+static int -+ip_set_delip(ip_set_id_t index, -+ const void *data, -+ size_t size) -+{ -+ struct ip_set *set = ip_set_list[index]; -+ ip_set_ip_t ip; -+ int res; -+ -+ IP_SET_ASSERT(set); -+ write_lock_bh(&set->lock); -+ res = set->type->delip(set, -+ data + sizeof(struct ip_set_req_adt), -+ size - sizeof(struct ip_set_req_adt), -+ &ip); -+ write_unlock_bh(&set->lock); -+ -+ return res; -+} -+ -+static int -+ip_set_testip(ip_set_id_t index, -+ const void *data, -+ size_t size) -+{ -+ struct ip_set *set = ip_set_list[index]; -+ ip_set_ip_t ip; -+ int res; -+ -+ IP_SET_ASSERT(set); -+ res = __ip_set_testip(set, -+ data + sizeof(struct ip_set_req_adt), -+ size - sizeof(struct ip_set_req_adt), -+ &ip); -+ -+ return (res > 0 ? -EEXIST : res); -+} -+ -+static int -+ip_set_bindip(ip_set_id_t index, -+ const void *data, -+ size_t size) -+{ -+ struct ip_set *set = ip_set_list[index]; -+ struct ip_set_req_bind *req_bind; -+ ip_set_id_t binding; -+ ip_set_ip_t ip; -+ int res; -+ -+ IP_SET_ASSERT(set); -+ if (size < sizeof(struct ip_set_req_bind)) -+ return -EINVAL; -+ -+ req_bind = (struct ip_set_req_bind *) data; -+ req_bind->binding[IP_SET_MAXNAMELEN - 1] = '\0'; -+ -+ if (strcmp(req_bind->binding, IPSET_TOKEN_DEFAULT) == 0) { -+ /* Default binding of a set */ -+ char *binding_name; -+ -+ if (size != sizeof(struct ip_set_req_bind) + IP_SET_MAXNAMELEN) -+ return -EINVAL; -+ -+ binding_name = (char *)(data + sizeof(struct ip_set_req_bind)); -+ binding_name[IP_SET_MAXNAMELEN - 1] = '\0'; -+ -+ binding = ip_set_find_byname(binding_name); -+ if (binding == IP_SET_INVALID_ID) -+ return -ENOENT; -+ -+ write_lock_bh(&ip_set_lock); -+ /* Sets as binding values are referenced */ -+ if (set->binding != IP_SET_INVALID_ID) -+ __ip_set_put(set->binding); -+ set->binding = binding; -+ __ip_set_get(set->binding); -+ write_unlock_bh(&ip_set_lock); -+ -+ return 0; -+ } -+ binding = ip_set_find_byname(req_bind->binding); -+ if (binding == IP_SET_INVALID_ID) -+ return -ENOENT; -+ -+ res = __ip_set_testip(set, -+ data + sizeof(struct ip_set_req_bind), -+ size - sizeof(struct ip_set_req_bind), -+ &ip); -+ DP("set %s, ip: %u.%u.%u.%u, binding %s", -+ set->name, HIPQUAD(ip), ip_set_list[binding]->name); -+ -+ if (res >= 0) -+ res = ip_set_hash_add(set->id, ip, binding); -+ -+ return res; -+} -+ -+#define FOREACH_SET_DO(fn, args...) \ -+({ \ -+ ip_set_id_t __i; \ -+ struct ip_set *__set; \ -+ \ -+ for (__i = 0; __i < ip_set_max; __i++) { \ -+ __set = ip_set_list[__i]; \ -+ if (__set != NULL) \ -+ fn(__set , ##args); \ -+ } \ -+}) -+ -+static inline void -+__set_hash_del_byid(struct ip_set_hash *set_hash, ip_set_id_t id) -+{ -+ if (set_hash->id == id) -+ __set_hash_del(set_hash); -+} -+ -+static inline void -+__unbind_default(struct ip_set *set) -+{ -+ if (set->binding != IP_SET_INVALID_ID) { -+ /* Sets as binding values are referenced */ -+ __ip_set_put(set->binding); -+ set->binding = IP_SET_INVALID_ID; -+ } -+} -+ -+static int -+ip_set_unbindip(ip_set_id_t index, -+ const void *data, -+ size_t size) -+{ -+ struct ip_set *set; -+ struct ip_set_req_bind *req_bind; -+ ip_set_ip_t ip; -+ int res; -+ -+ DP(""); -+ if (size < sizeof(struct ip_set_req_bind)) -+ return -EINVAL; -+ -+ req_bind = (struct ip_set_req_bind *) data; -+ req_bind->binding[IP_SET_MAXNAMELEN - 1] = '\0'; -+ -+ DP("%u %s", index, req_bind->binding); -+ if (index == IP_SET_INVALID_ID) { -+ /* unbind :all: */ -+ if (strcmp(req_bind->binding, IPSET_TOKEN_DEFAULT) == 0) { -+ /* Default binding of sets */ -+ write_lock_bh(&ip_set_lock); -+ FOREACH_SET_DO(__unbind_default); -+ write_unlock_bh(&ip_set_lock); -+ return 0; -+ } else if (strcmp(req_bind->binding, IPSET_TOKEN_ALL) == 0) { -+ /* Flush all bindings of all sets*/ -+ write_lock_bh(&ip_set_lock); -+ FOREACH_HASH_RW_DO(__set_hash_del); -+ write_unlock_bh(&ip_set_lock); -+ return 0; -+ } -+ DP("unreachable reached!"); -+ return -EINVAL; -+ } -+ -+ set = ip_set_list[index]; -+ IP_SET_ASSERT(set); -+ if (strcmp(req_bind->binding, IPSET_TOKEN_DEFAULT) == 0) { -+ /* Default binding of set */ -+ ip_set_id_t binding = ip_set_find_byindex(set->binding); -+ -+ if (binding == IP_SET_INVALID_ID) -+ return -ENOENT; -+ -+ write_lock_bh(&ip_set_lock); -+ /* Sets in hash values are referenced */ -+ __ip_set_put(set->binding); -+ set->binding = IP_SET_INVALID_ID; -+ write_unlock_bh(&ip_set_lock); -+ -+ return 0; -+ } else if (strcmp(req_bind->binding, IPSET_TOKEN_ALL) == 0) { -+ /* Flush all bindings */ -+ -+ write_lock_bh(&ip_set_lock); -+ FOREACH_HASH_RW_DO(__set_hash_del_byid, set->id); -+ write_unlock_bh(&ip_set_lock); -+ return 0; -+ } -+ -+ res = __ip_set_testip(set, -+ data + sizeof(struct ip_set_req_bind), -+ size - sizeof(struct ip_set_req_bind), -+ &ip); -+ -+ DP("set %s, ip: %u.%u.%u.%u", set->name, HIPQUAD(ip)); -+ if (res >= 0) -+ res = ip_set_hash_del(set->id, ip); -+ -+ return res; -+} -+ -+static int -+ip_set_testbind(ip_set_id_t index, -+ const void *data, -+ size_t size) -+{ -+ struct ip_set *set = ip_set_list[index]; -+ struct ip_set_req_bind *req_bind; -+ ip_set_id_t binding; -+ ip_set_ip_t ip; -+ int res; -+ -+ IP_SET_ASSERT(set); -+ if (size < sizeof(struct ip_set_req_bind)) -+ return -EINVAL; -+ -+ req_bind = (struct ip_set_req_bind *) data; -+ req_bind->binding[IP_SET_MAXNAMELEN - 1] = '\0'; -+ -+ if (strcmp(req_bind->binding, IPSET_TOKEN_DEFAULT) == 0) { -+ /* Default binding of set */ -+ char *binding_name; -+ -+ if (size != sizeof(struct ip_set_req_bind) + IP_SET_MAXNAMELEN) -+ return -EINVAL; -+ -+ binding_name = (char *)(data + sizeof(struct ip_set_req_bind)); -+ binding_name[IP_SET_MAXNAMELEN - 1] = '\0'; -+ -+ binding = ip_set_find_byname(binding_name); -+ if (binding == IP_SET_INVALID_ID) -+ return -ENOENT; -+ -+ res = (set->binding == binding) ? -EEXIST : 0; -+ -+ return res; -+ } -+ binding = ip_set_find_byname(req_bind->binding); -+ if (binding == IP_SET_INVALID_ID) -+ return -ENOENT; -+ -+ -+ res = __ip_set_testip(set, -+ data + sizeof(struct ip_set_req_bind), -+ size - sizeof(struct ip_set_req_bind), -+ &ip); -+ DP("set %s, ip: %u.%u.%u.%u, binding %s", -+ set->name, HIPQUAD(ip), ip_set_list[binding]->name); -+ -+ if (res >= 0) -+ res = (ip_set_find_in_hash(set->id, ip) == binding) -+ ? -EEXIST : 0; -+ -+ return res; -+} -+ -+static struct ip_set_type * -+find_set_type_rlock(const char *typename) -+{ -+ struct ip_set_type *type; -+ -+ read_lock_bh(&ip_set_lock); -+ type = find_set_type(typename); -+ if (type == NULL) -+ read_unlock_bh(&ip_set_lock); -+ -+ return type; -+} -+ -+static int -+find_free_id(const char *name, -+ ip_set_id_t *index, -+ ip_set_id_t *id) -+{ -+ ip_set_id_t i; -+ -+ *id = IP_SET_INVALID_ID; -+ for (i = 0; i < ip_set_max; i++) { -+ if (ip_set_list[i] == NULL) { -+ if (*id == IP_SET_INVALID_ID) -+ *id = *index = i; -+ } else if (strcmp(name, ip_set_list[i]->name) == 0) -+ /* Name clash */ -+ return -EEXIST; -+ } -+ if (*id == IP_SET_INVALID_ID) -+ /* No free slot remained */ -+ return -ERANGE; -+ /* Check that index is usable as id (swapping) */ -+ check: -+ for (i = 0; i < ip_set_max; i++) { -+ if (ip_set_list[i] != NULL -+ && ip_set_list[i]->id == *id) { -+ *id = i; -+ goto check; -+ } -+ } -+ return 0; -+} -+ -+/* -+ * Create a set -+ */ -+static int -+ip_set_create(const char *name, -+ const char *typename, -+ ip_set_id_t restore, -+ const void *data, -+ size_t size) -+{ -+ struct ip_set *set; -+ ip_set_id_t index = 0, id; -+ int res = 0; -+ -+ DP("setname: %s, typename: %s, id: %u", name, typename, restore); -+ /* -+ * First, and without any locks, allocate and initialize -+ * a normal base set structure. -+ */ -+ set = kmalloc(sizeof(struct ip_set), GFP_KERNEL); -+ if (!set) -+ return -ENOMEM; -+ set->lock = RW_LOCK_UNLOCKED; -+ strncpy(set->name, name, IP_SET_MAXNAMELEN); -+ set->binding = IP_SET_INVALID_ID; -+ atomic_set(&set->ref, 0); -+ -+ /* -+ * Next, take the &ip_set_lock, check that we know the type, -+ * and take a reference on the type, to make sure it -+ * stays available while constructing our new set. -+ * -+ * After referencing the type, we drop the &ip_set_lock, -+ * and let the new set construction run without locks. -+ */ -+ set->type = find_set_type_rlock(typename); -+ if (set->type == NULL) { -+ /* Try loading the module */ -+ char modulename[IP_SET_MAXNAMELEN + strlen("ip_set_") + 1]; -+ strcpy(modulename, "ip_set_"); -+ strcat(modulename, typename); -+ DP("try to load %s", modulename); -+ request_module(modulename); -+ set->type = find_set_type_rlock(typename); -+ } -+ if (set->type == NULL) { -+ ip_set_printk("no set type '%s', set '%s' not created", -+ typename, name); -+ res = -ENOENT; -+ goto out; -+ } -+ if (!try_module_get(set->type->me)) { -+ read_unlock_bh(&ip_set_lock); -+ res = -EFAULT; -+ goto out; -+ } -+ read_unlock_bh(&ip_set_lock); -+ -+ /* -+ * Without holding any locks, create private part. -+ */ -+ res = set->type->create(set, data, size); -+ if (res != 0) -+ goto put_out; -+ -+ /* BTW, res==0 here. */ -+ -+ /* -+ * Here, we have a valid, constructed set. &ip_set_lock again, -+ * find free id/index and check that it is not already in -+ * ip_set_list. -+ */ -+ write_lock_bh(&ip_set_lock); -+ if ((res = find_free_id(set->name, &index, &id)) != 0) { -+ DP("no free id!"); -+ goto cleanup; -+ } -+ -+ /* Make sure restore gets the same index */ -+ if (restore != IP_SET_INVALID_ID && index != restore) { -+ DP("Can't restore, sets are screwed up"); -+ res = -ERANGE; -+ goto cleanup; -+ } -+ -+ /* -+ * Finally! Add our shiny new set to the list, and be done. -+ */ -+ DP("create: '%s' created with index %u, id %u!", set->name, index, id); -+ set->id = id; -+ ip_set_list[index] = set; -+ write_unlock_bh(&ip_set_lock); -+ return res; -+ -+ cleanup: -+ write_unlock_bh(&ip_set_lock); -+ set->type->destroy(set); -+ put_out: -+ module_put(set->type->me); -+ out: -+ kfree(set); -+ return res; -+} -+ -+/* -+ * Destroy a given existing set -+ */ -+static void -+ip_set_destroy_set(ip_set_id_t index) -+{ -+ struct ip_set *set = ip_set_list[index]; -+ -+ IP_SET_ASSERT(set); -+ DP("set: %s", set->name); -+ write_lock_bh(&ip_set_lock); -+ FOREACH_HASH_RW_DO(__set_hash_del_byid, set->id); -+ if (set->binding != IP_SET_INVALID_ID) -+ __ip_set_put(set->binding); -+ ip_set_list[index] = NULL; -+ write_unlock_bh(&ip_set_lock); -+ -+ /* Must call it without holding any lock */ -+ set->type->destroy(set); -+ module_put(set->type->me); -+ kfree(set); -+} -+ -+/* -+ * Destroy a set - or all sets -+ * Sets must not be referenced/used. -+ */ -+static int -+ip_set_destroy(ip_set_id_t index) -+{ -+ ip_set_id_t i; -+ -+ /* ref modification always protected by the mutex */ -+ if (index != IP_SET_INVALID_ID) { -+ if (atomic_read(&ip_set_list[index]->ref)) -+ return -EBUSY; -+ ip_set_destroy_set(index); -+ } else { -+ for (i = 0; i < ip_set_max; i++) { -+ if (ip_set_list[i] != NULL -+ && (atomic_read(&ip_set_list[i]->ref))) -+ return -EBUSY; -+ } -+ -+ for (i = 0; i < ip_set_max; i++) { -+ if (ip_set_list[i] != NULL) -+ ip_set_destroy_set(i); -+ } -+ } -+ return 0; -+} -+ -+static void -+ip_set_flush_set(struct ip_set *set) -+{ -+ DP("set: %s %u", set->name, set->id); -+ -+ write_lock_bh(&set->lock); -+ set->type->flush(set); -+ write_unlock_bh(&set->lock); -+} -+ -+/* -+ * Flush data in a set - or in all sets -+ */ -+static int -+ip_set_flush(ip_set_id_t index) -+{ -+ if (index != IP_SET_INVALID_ID) { -+ IP_SET_ASSERT(ip_set_list[index]); -+ ip_set_flush_set(ip_set_list[index]); -+ } else -+ FOREACH_SET_DO(ip_set_flush_set); -+ -+ return 0; -+} -+ -+/* Rename a set */ -+static int -+ip_set_rename(ip_set_id_t index, const char *name) -+{ -+ struct ip_set *set = ip_set_list[index]; -+ ip_set_id_t i; -+ int res = 0; -+ -+ DP("set: %s to %s", set->name, name); -+ write_lock_bh(&ip_set_lock); -+ for (i = 0; i < ip_set_max; i++) { -+ if (ip_set_list[i] != NULL -+ && strncmp(ip_set_list[i]->name, -+ name, -+ IP_SET_MAXNAMELEN - 1) == 0) { -+ res = -EEXIST; -+ goto unlock; -+ } -+ } -+ strncpy(set->name, name, IP_SET_MAXNAMELEN); -+ unlock: -+ write_unlock_bh(&ip_set_lock); -+ return res; -+} -+ -+/* -+ * Swap two sets so that name/index points to the other. -+ * References are also swapped. -+ */ -+static int -+ip_set_swap(ip_set_id_t from_index, ip_set_id_t to_index) -+{ -+ struct ip_set *from = ip_set_list[from_index]; -+ struct ip_set *to = ip_set_list[to_index]; -+ char from_name[IP_SET_MAXNAMELEN]; -+ u_int32_t from_ref; -+ -+ DP("set: %s to %s", from->name, to->name); -+ /* Features must not change. Artifical restriction. */ -+ if (from->type->features != to->type->features) -+ return -ENOEXEC; -+ -+ /* No magic here: ref munging protected by the mutex */ -+ write_lock_bh(&ip_set_lock); -+ strncpy(from_name, from->name, IP_SET_MAXNAMELEN); -+ from_ref = atomic_read(&from->ref); -+ -+ strncpy(from->name, to->name, IP_SET_MAXNAMELEN); -+ atomic_set(&from->ref, atomic_read(&to->ref)); -+ strncpy(to->name, from_name, IP_SET_MAXNAMELEN); -+ atomic_set(&to->ref, from_ref); -+ -+ ip_set_list[from_index] = to; -+ ip_set_list[to_index] = from; -+ -+ write_unlock_bh(&ip_set_lock); -+ return 0; -+} -+ -+/* -+ * List set data -+ */ -+ -+static inline void -+__set_hash_bindings_size_list(struct ip_set_hash *set_hash, -+ ip_set_id_t id, size_t *size) -+{ -+ if (set_hash->id == id) -+ *size += sizeof(struct ip_set_hash_list); -+} -+ -+static inline void -+__set_hash_bindings_size_save(struct ip_set_hash *set_hash, -+ ip_set_id_t id, size_t *size) -+{ -+ if (set_hash->id == id) -+ *size += sizeof(struct ip_set_hash_save); -+} -+ -+static inline void -+__set_hash_bindings(struct ip_set_hash *set_hash, -+ ip_set_id_t id, void *data, int *used) -+{ -+ if (set_hash->id == id) { -+ struct ip_set_hash_list *hash_list = -+ (struct ip_set_hash_list *)(data + *used); -+ -+ hash_list->ip = set_hash->ip; -+ hash_list->binding = set_hash->binding; -+ *used += sizeof(struct ip_set_hash_list); -+ } -+} -+ -+static int ip_set_list_set(ip_set_id_t index, -+ void *data, -+ int *used, -+ int len) -+{ -+ struct ip_set *set = ip_set_list[index]; -+ struct ip_set_list *set_list; -+ -+ /* Pointer to our header */ -+ set_list = (struct ip_set_list *) (data + *used); -+ -+ DP("set: %s, used: %d %p %p", set->name, *used, data, data + *used); -+ -+ /* Get and ensure header size */ -+ if (*used + sizeof(struct ip_set_list) > len) -+ goto not_enough_mem; -+ *used += sizeof(struct ip_set_list); -+ -+ read_lock_bh(&set->lock); -+ /* Get and ensure set specific header size */ -+ set_list->header_size = set->type->header_size; -+ if (*used + set_list->header_size > len) -+ goto unlock_set; -+ -+ /* Fill in the header */ -+ set_list->index = index; -+ set_list->binding = set->binding; -+ set_list->ref = atomic_read(&set->ref); -+ -+ /* Fill in set spefific header data */ -+ set->type->list_header(set, data + *used); -+ *used += set_list->header_size; -+ -+ /* Get and ensure set specific members size */ -+ set_list->members_size = set->type->list_members_size(set); -+ if (*used + set_list->members_size > len) -+ goto unlock_set; -+ -+ /* Fill in set spefific members data */ -+ set->type->list_members(set, data + *used); -+ *used += set_list->members_size; -+ read_unlock_bh(&set->lock); -+ -+ /* Bindings */ -+ -+ /* Get and ensure set specific bindings size */ -+ set_list->bindings_size = 0; -+ FOREACH_HASH_DO(__set_hash_bindings_size_list, -+ set->id, &set_list->bindings_size); -+ if (*used + set_list->bindings_size > len) -+ goto not_enough_mem; -+ -+ /* Fill in set spefific bindings data */ -+ FOREACH_HASH_DO(__set_hash_bindings, set->id, data, used); -+ -+ return 0; -+ -+ unlock_set: -+ read_unlock_bh(&set->lock); -+ not_enough_mem: -+ DP("not enough mem, try again"); -+ return -EAGAIN; -+} -+ -+/* -+ * Save sets -+ */ -+static int ip_set_save_set(ip_set_id_t index, -+ void *data, -+ int *used, -+ int len) -+{ -+ struct ip_set *set; -+ struct ip_set_save *set_save; -+ -+ /* Pointer to our header */ -+ set_save = (struct ip_set_save *) (data + *used); -+ -+ /* Get and ensure header size */ -+ if (*used + sizeof(struct ip_set_save) > len) -+ goto not_enough_mem; -+ *used += sizeof(struct ip_set_save); -+ -+ set = ip_set_list[index]; -+ DP("set: %s, used: %u(%u) %p %p", set->name, *used, len, -+ data, data + *used); -+ -+ read_lock_bh(&set->lock); -+ /* Get and ensure set specific header size */ -+ set_save->header_size = set->type->header_size; -+ if (*used + set_save->header_size > len) -+ goto unlock_set; -+ -+ /* Fill in the header */ -+ set_save->index = index; -+ set_save->binding = set->binding; -+ -+ /* Fill in set spefific header data */ -+ set->type->list_header(set, data + *used); -+ *used += set_save->header_size; -+ -+ DP("set header filled: %s, used: %u(%u) %p %p", set->name, *used, -+ set_save->header_size, data, data + *used); -+ /* Get and ensure set specific members size */ -+ set_save->members_size = set->type->list_members_size(set); -+ if (*used + set_save->members_size > len) -+ goto unlock_set; -+ -+ /* Fill in set spefific members data */ -+ set->type->list_members(set, data + *used); -+ *used += set_save->members_size; -+ read_unlock_bh(&set->lock); -+ DP("set members filled: %s, used: %u(%u) %p %p", set->name, *used, -+ set_save->members_size, data, data + *used); -+ return 0; -+ -+ unlock_set: -+ read_unlock_bh(&set->lock); -+ not_enough_mem: -+ DP("not enough mem, try again"); -+ return -EAGAIN; -+} -+ -+static inline void -+__set_hash_save_bindings(struct ip_set_hash *set_hash, -+ ip_set_id_t id, -+ void *data, -+ int *used, -+ int len, -+ int *res) -+{ -+ if (*res == 0 -+ && (id == IP_SET_INVALID_ID || set_hash->id == id)) { -+ struct ip_set_hash_save *hash_save = -+ (struct ip_set_hash_save *)(data + *used); -+ /* Ensure bindings size */ -+ if (*used + sizeof(struct ip_set_hash_save) > len) { -+ *res = -ENOMEM; -+ return; -+ } -+ hash_save->id = set_hash->id; -+ hash_save->ip = set_hash->ip; -+ hash_save->binding = set_hash->binding; -+ *used += sizeof(struct ip_set_hash_save); -+ } -+} -+ -+static int ip_set_save_bindings(ip_set_id_t index, -+ void *data, -+ int *used, -+ int len) -+{ -+ int res = 0; -+ struct ip_set_save *set_save; -+ -+ DP("used %u, len %u", *used, len); -+ /* Get and ensure header size */ -+ if (*used + sizeof(struct ip_set_save) > len) -+ return -ENOMEM; -+ -+ /* Marker */ -+ set_save = (struct ip_set_save *) (data + *used); -+ set_save->index = IP_SET_INVALID_ID; -+ set_save->header_size = 0; -+ set_save->members_size = 0; -+ *used += sizeof(struct ip_set_save); -+ -+ DP("marker added used %u, len %u", *used, len); -+ /* Fill in bindings data */ -+ if (index != IP_SET_INVALID_ID) -+ /* Sets are identified by id in hash */ -+ index = ip_set_list[index]->id; -+ FOREACH_HASH_DO(__set_hash_save_bindings, index, data, used, len, &res); -+ -+ return res; -+} -+ -+/* -+ * Restore sets -+ */ -+static int ip_set_restore(void *data, -+ int len) -+{ -+ int res = 0; -+ int line = 0, used = 0, members_size; -+ struct ip_set *set; -+ struct ip_set_hash_save *hash_save; -+ struct ip_set_restore *set_restore; -+ ip_set_id_t index; -+ -+ /* Loop to restore sets */ -+ while (1) { -+ line++; -+ -+ DP("%u %u %u", used, sizeof(struct ip_set_restore), len); -+ /* Get and ensure header size */ -+ if (used + sizeof(struct ip_set_restore) > len) -+ return line; -+ set_restore = (struct ip_set_restore *) (data + used); -+ used += sizeof(struct ip_set_restore); -+ -+ /* Ensure data size */ -+ if (used -+ + set_restore->header_size -+ + set_restore->members_size > len) -+ return line; -+ -+ /* Check marker */ -+ if (set_restore->index == IP_SET_INVALID_ID) { -+ line--; -+ goto bindings; -+ } -+ -+ /* Try to create the set */ -+ DP("restore %s %s", set_restore->name, set_restore->typename); -+ res = ip_set_create(set_restore->name, -+ set_restore->typename, -+ set_restore->index, -+ data + used, -+ set_restore->header_size); -+ -+ if (res != 0) -+ return line; -+ used += set_restore->header_size; -+ -+ index = ip_set_find_byindex(set_restore->index); -+ DP("index %u, restore_index %u", index, set_restore->index); -+ if (index != set_restore->index) -+ return line; -+ /* Try to restore members data */ -+ set = ip_set_list[index]; -+ members_size = 0; -+ DP("members_size %u reqsize %u", -+ set_restore->members_size, set->type->reqsize); -+ while (members_size + set->type->reqsize <= -+ set_restore->members_size) { -+ line++; -+ DP("members: %u, line %u", members_size, line); -+ res = __ip_set_addip(index, -+ data + used + members_size, -+ set->type->reqsize); -+ if (!(res == 0 || res == -EEXIST)) -+ return line; -+ members_size += set->type->reqsize; -+ } -+ -+ DP("members_size %u %u", -+ set_restore->members_size, members_size); -+ if (members_size != set_restore->members_size) -+ return line++; -+ used += set_restore->members_size; -+ } -+ -+ bindings: -+ /* Loop to restore bindings */ -+ while (used < len) { -+ line++; -+ -+ DP("restore binding, line %u", line); -+ /* Get and ensure size */ -+ if (used + sizeof(struct ip_set_hash_save) > len) -+ return line; -+ hash_save = (struct ip_set_hash_save *) (data + used); -+ used += sizeof(struct ip_set_hash_save); -+ -+ /* hash_save->id is used to store the index */ -+ index = ip_set_find_byindex(hash_save->id); -+ DP("restore binding index %u, id %u, %u -> %u", -+ index, hash_save->id, hash_save->ip, hash_save->binding); -+ if (index != hash_save->id) -+ return line; -+ if (ip_set_find_byindex(hash_save->binding) == IP_SET_INVALID_ID) { -+ DP("corrupt binding set index %u", hash_save->binding); -+ return line; -+ } -+ set = ip_set_list[hash_save->id]; -+ /* Null valued IP means default binding */ -+ if (hash_save->ip) -+ res = ip_set_hash_add(set->id, -+ hash_save->ip, -+ hash_save->binding); -+ else { -+ IP_SET_ASSERT(set->binding == IP_SET_INVALID_ID); -+ write_lock_bh(&ip_set_lock); -+ set->binding = hash_save->binding; -+ __ip_set_get(set->binding); -+ write_unlock_bh(&ip_set_lock); -+ DP("default binding: %u", set->binding); -+ } -+ if (res != 0) -+ return line; -+ } -+ if (used != len) -+ return line; -+ -+ return 0; -+} -+ -+static int -+ip_set_sockfn_set(struct sock *sk, int optval, void *user, unsigned int len) -+{ -+ void *data; -+ int res = 0; /* Assume OK */ -+ unsigned *op; -+ struct ip_set_req_adt *req_adt; -+ ip_set_id_t index = IP_SET_INVALID_ID; -+ int (*adtfn)(ip_set_id_t index, -+ const void *data, size_t size); -+ struct fn_table { -+ int (*fn)(ip_set_id_t index, -+ const void *data, size_t size); -+ } adtfn_table[] = -+ { { ip_set_addip }, { ip_set_delip }, { ip_set_testip}, -+ { ip_set_bindip}, { ip_set_unbindip }, { ip_set_testbind }, -+ }; -+ -+ DP("optval=%d, user=%p, len=%d", optval, user, len); -+ if (!capable(CAP_NET_ADMIN)) -+ return -EPERM; -+ if (optval != SO_IP_SET) -+ return -EBADF; -+ if (len <= sizeof(unsigned)) { -+ ip_set_printk("short userdata (want >%zu, got %u)", -+ sizeof(unsigned), len); -+ return -EINVAL; -+ } -+ data = vmalloc(len); -+ if (!data) { -+ DP("out of mem for %u bytes", len); -+ return -ENOMEM; -+ } -+ if (copy_from_user(data, user, len) != 0) { -+ res = -EFAULT; -+ goto done; -+ } -+ if (down_interruptible(&ip_set_app_mutex)) { -+ res = -EINTR; -+ goto done; -+ } -+ -+ op = (unsigned *)data; -+ DP("op=%x", *op); -+ -+ if (*op < IP_SET_OP_VERSION) { -+ /* Check the version at the beginning of operations */ -+ struct ip_set_req_version *req_version = -+ (struct ip_set_req_version *) data; -+ if (req_version->version != IP_SET_PROTOCOL_VERSION) { -+ res = -EPROTO; -+ goto done; -+ } -+ } -+ -+ switch (*op) { -+ case IP_SET_OP_CREATE:{ -+ struct ip_set_req_create *req_create -+ = (struct ip_set_req_create *) data; -+ -+ if (len < sizeof(struct ip_set_req_create)) { -+ ip_set_printk("short CREATE data (want >=%zu, got %u)", -+ sizeof(struct ip_set_req_create), len); -+ res = -EINVAL; -+ goto done; -+ } -+ req_create->name[IP_SET_MAXNAMELEN - 1] = '\0'; -+ req_create->typename[IP_SET_MAXNAMELEN - 1] = '\0'; -+ res = ip_set_create(req_create->name, -+ req_create->typename, -+ IP_SET_INVALID_ID, -+ data + sizeof(struct ip_set_req_create), -+ len - sizeof(struct ip_set_req_create)); -+ goto done; -+ } -+ case IP_SET_OP_DESTROY:{ -+ struct ip_set_req_std *req_destroy -+ = (struct ip_set_req_std *) data; -+ -+ if (len != sizeof(struct ip_set_req_std)) { -+ ip_set_printk("invalid DESTROY data (want %zu, got %u)", -+ sizeof(struct ip_set_req_std), len); -+ res = -EINVAL; -+ goto done; -+ } -+ if (strcmp(req_destroy->name, IPSET_TOKEN_ALL) == 0) { -+ /* Destroy all sets */ -+ index = IP_SET_INVALID_ID; -+ } else { -+ req_destroy->name[IP_SET_MAXNAMELEN - 1] = '\0'; -+ index = ip_set_find_byname(req_destroy->name); -+ -+ if (index == IP_SET_INVALID_ID) { -+ res = -ENOENT; -+ goto done; -+ } -+ } -+ -+ res = ip_set_destroy(index); -+ goto done; -+ } -+ case IP_SET_OP_FLUSH:{ -+ struct ip_set_req_std *req_flush = -+ (struct ip_set_req_std *) data; -+ -+ if (len != sizeof(struct ip_set_req_std)) { -+ ip_set_printk("invalid FLUSH data (want %zu, got %u)", -+ sizeof(struct ip_set_req_std), len); -+ res = -EINVAL; -+ goto done; -+ } -+ if (strcmp(req_flush->name, IPSET_TOKEN_ALL) == 0) { -+ /* Flush all sets */ -+ index = IP_SET_INVALID_ID; -+ } else { -+ req_flush->name[IP_SET_MAXNAMELEN - 1] = '\0'; -+ index = ip_set_find_byname(req_flush->name); -+ -+ if (index == IP_SET_INVALID_ID) { -+ res = -ENOENT; -+ goto done; -+ } -+ } -+ res = ip_set_flush(index); -+ goto done; -+ } -+ case IP_SET_OP_RENAME:{ -+ struct ip_set_req_create *req_rename -+ = (struct ip_set_req_create *) data; -+ -+ if (len != sizeof(struct ip_set_req_create)) { -+ ip_set_printk("invalid RENAME data (want %zu, got %u)", -+ sizeof(struct ip_set_req_create), len); -+ res = -EINVAL; -+ goto done; -+ } -+ -+ req_rename->name[IP_SET_MAXNAMELEN - 1] = '\0'; -+ req_rename->typename[IP_SET_MAXNAMELEN - 1] = '\0'; -+ -+ index = ip_set_find_byname(req_rename->name); -+ if (index == IP_SET_INVALID_ID) { -+ res = -ENOENT; -+ goto done; -+ } -+ res = ip_set_rename(index, req_rename->typename); -+ goto done; -+ } -+ case IP_SET_OP_SWAP:{ -+ struct ip_set_req_create *req_swap -+ = (struct ip_set_req_create *) data; -+ ip_set_id_t to_index; -+ -+ if (len != sizeof(struct ip_set_req_create)) { -+ ip_set_printk("invalid SWAP data (want %zu, got %u)", -+ sizeof(struct ip_set_req_create), len); -+ res = -EINVAL; -+ goto done; -+ } -+ -+ req_swap->name[IP_SET_MAXNAMELEN - 1] = '\0'; -+ req_swap->typename[IP_SET_MAXNAMELEN - 1] = '\0'; -+ -+ index = ip_set_find_byname(req_swap->name); -+ if (index == IP_SET_INVALID_ID) { -+ res = -ENOENT; -+ goto done; -+ } -+ to_index = ip_set_find_byname(req_swap->typename); -+ if (to_index == IP_SET_INVALID_ID) { -+ res = -ENOENT; -+ goto done; -+ } -+ res = ip_set_swap(index, to_index); -+ goto done; -+ } -+ default: -+ break; /* Set identified by id */ -+ } -+ -+ /* There we may have add/del/test/bind/unbind/test_bind operations */ -+ if (*op < IP_SET_OP_ADD_IP || *op > IP_SET_OP_TEST_BIND_SET) { -+ res = -EBADMSG; -+ goto done; -+ } -+ adtfn = adtfn_table[*op - IP_SET_OP_ADD_IP].fn; -+ -+ if (len < sizeof(struct ip_set_req_adt)) { -+ ip_set_printk("short data in adt request (want >=%zu, got %u)", -+ sizeof(struct ip_set_req_adt), len); -+ res = -EINVAL; -+ goto done; -+ } -+ req_adt = (struct ip_set_req_adt *) data; -+ -+ /* -U :all: :all:|:default: uses IP_SET_INVALID_ID */ -+ if (!(*op == IP_SET_OP_UNBIND_SET -+ && req_adt->index == IP_SET_INVALID_ID)) { -+ index = ip_set_find_byindex(req_adt->index); -+ if (index == IP_SET_INVALID_ID) { -+ res = -ENOENT; -+ goto done; -+ } -+ } -+ res = adtfn(index, data, len); -+ -+ done: -+ up(&ip_set_app_mutex); -+ vfree(data); -+ if (res > 0) -+ res = 0; -+ DP("final result %d", res); -+ return res; -+} -+ -+static int -+ip_set_sockfn_get(struct sock *sk, int optval, void *user, int *len) -+{ -+ int res = 0; -+ unsigned *op; -+ ip_set_id_t index = IP_SET_INVALID_ID; -+ void *data; -+ int copylen = *len; -+ -+ DP("optval=%d, user=%p, len=%d", optval, user, *len); -+ if (!capable(CAP_NET_ADMIN)) -+ return -EPERM; -+ if (optval != SO_IP_SET) -+ return -EBADF; -+ if (*len < sizeof(unsigned)) { -+ ip_set_printk("short userdata (want >=%zu, got %d)", -+ sizeof(unsigned), *len); -+ return -EINVAL; -+ } -+ data = vmalloc(*len); -+ if (!data) { -+ DP("out of mem for %d bytes", *len); -+ return -ENOMEM; -+ } -+ if (copy_from_user(data, user, *len) != 0) { -+ res = -EFAULT; -+ goto done; -+ } -+ if (down_interruptible(&ip_set_app_mutex)) { -+ res = -EINTR; -+ goto done; -+ } -+ -+ op = (unsigned *) data; -+ DP("op=%x", *op); -+ -+ if (*op < IP_SET_OP_VERSION) { -+ /* Check the version at the beginning of operations */ -+ struct ip_set_req_version *req_version = -+ (struct ip_set_req_version *) data; -+ if (req_version->version != IP_SET_PROTOCOL_VERSION) { -+ res = -EPROTO; -+ goto done; -+ } -+ } -+ -+ switch (*op) { -+ case IP_SET_OP_VERSION: { -+ struct ip_set_req_version *req_version = -+ (struct ip_set_req_version *) data; -+ -+ if (*len != sizeof(struct ip_set_req_version)) { -+ ip_set_printk("invalid VERSION (want %zu, got %d)", -+ sizeof(struct ip_set_req_version), -+ *len); -+ res = -EINVAL; -+ goto done; -+ } -+ -+ req_version->version = IP_SET_PROTOCOL_VERSION; -+ res = copy_to_user(user, req_version, -+ sizeof(struct ip_set_req_version)); -+ goto done; -+ } -+ case IP_SET_OP_GET_BYNAME: { -+ struct ip_set_req_get_set *req_get -+ = (struct ip_set_req_get_set *) data; -+ -+ if (*len != sizeof(struct ip_set_req_get_set)) { -+ ip_set_printk("invalid GET_BYNAME (want %zu, got %d)", -+ sizeof(struct ip_set_req_get_set), *len); -+ res = -EINVAL; -+ goto done; -+ } -+ req_get->set.name[IP_SET_MAXNAMELEN - 1] = '\0'; -+ index = ip_set_find_byname(req_get->set.name); -+ req_get->set.index = index; -+ goto copy; -+ } -+ case IP_SET_OP_GET_BYINDEX: { -+ struct ip_set_req_get_set *req_get -+ = (struct ip_set_req_get_set *) data; -+ -+ if (*len != sizeof(struct ip_set_req_get_set)) { -+ ip_set_printk("invalid GET_BYINDEX (want %zu, got %d)", -+ sizeof(struct ip_set_req_get_set), *len); -+ res = -EINVAL; -+ goto done; -+ } -+ req_get->set.name[IP_SET_MAXNAMELEN - 1] = '\0'; -+ index = ip_set_find_byindex(req_get->set.index); -+ strncpy(req_get->set.name, -+ index == IP_SET_INVALID_ID ? "" -+ : ip_set_list[index]->name, IP_SET_MAXNAMELEN); -+ goto copy; -+ } -+ case IP_SET_OP_ADT_GET: { -+ struct ip_set_req_adt_get *req_get -+ = (struct ip_set_req_adt_get *) data; -+ -+ if (*len != sizeof(struct ip_set_req_adt_get)) { -+ ip_set_printk("invalid ADT_GET (want %zu, got %d)", -+ sizeof(struct ip_set_req_adt_get), *len); -+ res = -EINVAL; -+ goto done; -+ } -+ req_get->set.name[IP_SET_MAXNAMELEN - 1] = '\0'; -+ index = ip_set_find_byname(req_get->set.name); -+ if (index != IP_SET_INVALID_ID) { -+ req_get->set.index = index; -+ strncpy(req_get->typename, -+ ip_set_list[index]->type->typename, -+ IP_SET_MAXNAMELEN - 1); -+ } else { -+ res = -ENOENT; -+ goto done; -+ } -+ goto copy; -+ } -+ case IP_SET_OP_MAX_SETS: { -+ struct ip_set_req_max_sets *req_max_sets -+ = (struct ip_set_req_max_sets *) data; -+ ip_set_id_t i; -+ -+ if (*len != sizeof(struct ip_set_req_max_sets)) { -+ ip_set_printk("invalid MAX_SETS (want %zu, got %d)", -+ sizeof(struct ip_set_req_max_sets), *len); -+ res = -EINVAL; -+ goto done; -+ } -+ -+ if (strcmp(req_max_sets->set.name, IPSET_TOKEN_ALL) == 0) { -+ req_max_sets->set.index = IP_SET_INVALID_ID; -+ } else { -+ req_max_sets->set.name[IP_SET_MAXNAMELEN - 1] = '\0'; -+ req_max_sets->set.index = -+ ip_set_find_byname(req_max_sets->set.name); -+ if (req_max_sets->set.index == IP_SET_INVALID_ID) { -+ res = -ENOENT; -+ goto done; -+ } -+ } -+ req_max_sets->max_sets = ip_set_max; -+ req_max_sets->sets = 0; -+ for (i = 0; i < ip_set_max; i++) { -+ if (ip_set_list[i] != NULL) -+ req_max_sets->sets++; -+ } -+ goto copy; -+ } -+ case IP_SET_OP_LIST_SIZE: -+ case IP_SET_OP_SAVE_SIZE: { -+ struct ip_set_req_setnames *req_setnames -+ = (struct ip_set_req_setnames *) data; -+ struct ip_set_name_list *name_list; -+ struct ip_set *set; -+ ip_set_id_t i; -+ int used; -+ -+ if (*len < sizeof(struct ip_set_req_setnames)) { -+ ip_set_printk("short LIST_SIZE (want >=%zu, got %d)", -+ sizeof(struct ip_set_req_setnames), *len); -+ res = -EINVAL; -+ goto done; -+ } -+ -+ req_setnames->size = 0; -+ used = sizeof(struct ip_set_req_setnames); -+ for (i = 0; i < ip_set_max; i++) { -+ if (ip_set_list[i] == NULL) -+ continue; -+ name_list = (struct ip_set_name_list *) -+ (data + used); -+ used += sizeof(struct ip_set_name_list); -+ if (used > copylen) { -+ res = -EAGAIN; -+ goto done; -+ } -+ set = ip_set_list[i]; -+ /* Fill in index, name, etc. */ -+ name_list->index = i; -+ name_list->id = set->id; -+ strncpy(name_list->name, -+ set->name, -+ IP_SET_MAXNAMELEN - 1); -+ strncpy(name_list->typename, -+ set->type->typename, -+ IP_SET_MAXNAMELEN - 1); -+ DP("filled %s of type %s, index %u\n", -+ name_list->name, name_list->typename, -+ name_list->index); -+ if (!(req_setnames->index == IP_SET_INVALID_ID -+ || req_setnames->index == i)) -+ continue; -+ /* Update size */ -+ switch (*op) { -+ case IP_SET_OP_LIST_SIZE: { -+ req_setnames->size += sizeof(struct ip_set_list) -+ + set->type->header_size -+ + set->type->list_members_size(set); -+ /* Sets are identified by id in the hash */ -+ FOREACH_HASH_DO(__set_hash_bindings_size_list, -+ set->id, &req_setnames->size); -+ break; -+ } -+ case IP_SET_OP_SAVE_SIZE: { -+ req_setnames->size += sizeof(struct ip_set_save) -+ + set->type->header_size -+ + set->type->list_members_size(set); -+ FOREACH_HASH_DO(__set_hash_bindings_size_save, -+ set->id, &req_setnames->size); -+ break; -+ } -+ default: -+ break; -+ } -+ } -+ if (copylen != used) { -+ res = -EAGAIN; -+ goto done; -+ } -+ goto copy; -+ } -+ case IP_SET_OP_LIST: { -+ struct ip_set_req_list *req_list -+ = (struct ip_set_req_list *) data; -+ ip_set_id_t i; -+ int used; -+ -+ if (*len < sizeof(struct ip_set_req_list)) { -+ ip_set_printk("short LIST (want >=%zu, got %d)", -+ sizeof(struct ip_set_req_list), *len); -+ res = -EINVAL; -+ goto done; -+ } -+ index = req_list->index; -+ if (index != IP_SET_INVALID_ID -+ && ip_set_find_byindex(index) != index) { -+ res = -ENOENT; -+ goto done; -+ } -+ used = 0; -+ if (index == IP_SET_INVALID_ID) { -+ /* List all sets */ -+ for (i = 0; i < ip_set_max && res == 0; i++) { -+ if (ip_set_list[i] != NULL) -+ res = ip_set_list_set(i, data, &used, *len); -+ } -+ } else { -+ /* List an individual set */ -+ res = ip_set_list_set(index, data, &used, *len); -+ } -+ if (res != 0) -+ goto done; -+ else if (copylen != used) { -+ res = -EAGAIN; -+ goto done; -+ } -+ goto copy; -+ } -+ case IP_SET_OP_SAVE: { -+ struct ip_set_req_list *req_save -+ = (struct ip_set_req_list *) data; -+ ip_set_id_t i; -+ int used; -+ -+ if (*len < sizeof(struct ip_set_req_list)) { -+ ip_set_printk("short SAVE (want >=%zu, got %d)", -+ sizeof(struct ip_set_req_list), *len); -+ res = -EINVAL; -+ goto done; -+ } -+ index = req_save->index; -+ if (index != IP_SET_INVALID_ID -+ && ip_set_find_byindex(index) != index) { -+ res = -ENOENT; -+ goto done; -+ } -+ used = 0; -+ if (index == IP_SET_INVALID_ID) { -+ /* Save all sets */ -+ for (i = 0; i < ip_set_max && res == 0; i++) { -+ if (ip_set_list[i] != NULL) -+ res = ip_set_save_set(i, data, &used, *len); -+ } -+ } else { -+ /* Save an individual set */ -+ res = ip_set_save_set(index, data, &used, *len); -+ } -+ if (res == 0) -+ res = ip_set_save_bindings(index, data, &used, *len); -+ -+ if (res != 0) -+ goto done; -+ else if (copylen != used) { -+ res = -EAGAIN; -+ goto done; -+ } -+ goto copy; -+ } -+ case IP_SET_OP_RESTORE: { -+ struct ip_set_req_setnames *req_restore -+ = (struct ip_set_req_setnames *) data; -+ int line; -+ -+ if (*len < sizeof(struct ip_set_req_setnames) -+ || *len != req_restore->size) { -+ ip_set_printk("invalid RESTORE (want =%zu, got %d)", -+ req_restore->size, *len); -+ res = -EINVAL; -+ goto done; -+ } -+ line = ip_set_restore(data + sizeof(struct ip_set_req_setnames), -+ req_restore->size - sizeof(struct ip_set_req_setnames)); -+ DP("ip_set_restore: %u", line); -+ if (line != 0) { -+ res = -EAGAIN; -+ req_restore->size = line; -+ copylen = sizeof(struct ip_set_req_setnames); -+ goto copy; -+ } -+ goto done; -+ } -+ default: -+ res = -EBADMSG; -+ goto done; -+ } /* end of switch(op) */ -+ -+ copy: -+ DP("set %s, copylen %u", index != IP_SET_INVALID_ID -+ && ip_set_list[index] -+ ? ip_set_list[index]->name -+ : ":all:", copylen); -+ res = copy_to_user(user, data, copylen); -+ -+ done: -+ up(&ip_set_app_mutex); -+ vfree(data); -+ if (res > 0) -+ res = 0; -+ DP("final result %d", res); -+ return res; -+} -+ -+static struct nf_sockopt_ops so_set = { -+ .pf = PF_INET, -+ .set_optmin = SO_IP_SET, -+ .set_optmax = SO_IP_SET + 1, -+ .set = &ip_set_sockfn_set, -+ .get_optmin = SO_IP_SET, -+ .get_optmax = SO_IP_SET + 1, -+ .get = &ip_set_sockfn_get, -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) -+ .owner = THIS_MODULE, -+#endif -+}; -+ -+static int max_sets, hash_size; -+module_param(max_sets, int, 0600); -+MODULE_PARM_DESC(max_sets, "maximal number of sets"); -+module_param(hash_size, int, 0600); -+MODULE_PARM_DESC(hash_size, "hash size for bindings"); -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Jozsef Kadlecsik "); -+MODULE_DESCRIPTION("module implementing core IP set support"); -+ -+static int __init ip_set_init(void) -+{ -+ int res; -+ ip_set_id_t i; -+ -+ get_random_bytes(&ip_set_hash_random, 4); -+ if (max_sets) -+ ip_set_max = max_sets; -+ ip_set_list = vmalloc(sizeof(struct ip_set *) * ip_set_max); -+ if (!ip_set_list) { -+ printk(KERN_ERR "Unable to create ip_set_list\n"); -+ return -ENOMEM; -+ } -+ memset(ip_set_list, 0, sizeof(struct ip_set *) * ip_set_max); -+ if (hash_size) -+ ip_set_bindings_hash_size = hash_size; -+ ip_set_hash = vmalloc(sizeof(struct list_head) * ip_set_bindings_hash_size); -+ if (!ip_set_hash) { -+ printk(KERN_ERR "Unable to create ip_set_hash\n"); -+ vfree(ip_set_list); -+ return -ENOMEM; -+ } -+ for (i = 0; i < ip_set_bindings_hash_size; i++) -+ INIT_LIST_HEAD(&ip_set_hash[i]); -+ -+ INIT_LIST_HEAD(&set_type_list); -+ -+ res = nf_register_sockopt(&so_set); -+ if (res != 0) { -+ ip_set_printk("SO_SET registry failed: %d", res); -+ vfree(ip_set_list); -+ vfree(ip_set_hash); -+ return res; -+ } -+ return 0; -+} -+ -+static void __exit ip_set_fini(void) -+{ -+ /* There can't be any existing set or binding */ -+ nf_unregister_sockopt(&so_set); -+ vfree(ip_set_list); -+ vfree(ip_set_hash); -+ DP("these are the famous last words"); -+} -+ -+EXPORT_SYMBOL(ip_set_register_set_type); -+EXPORT_SYMBOL(ip_set_unregister_set_type); -+ -+EXPORT_SYMBOL(ip_set_get_byname); -+EXPORT_SYMBOL(ip_set_get_byindex); -+EXPORT_SYMBOL(ip_set_put); -+ -+EXPORT_SYMBOL(ip_set_addip_kernel); -+EXPORT_SYMBOL(ip_set_delip_kernel); -+EXPORT_SYMBOL(ip_set_testip_kernel); -+ -+module_init(ip_set_init); -+module_exit(ip_set_fini); ---- /dev/null -+++ b/net/ipv4/netfilter/ip_set_iphash.c -@@ -0,0 +1,429 @@ -+/* Copyright (C) 2003-2004 Jozsef Kadlecsik -+ * -+ * 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. -+ */ -+ -+/* Kernel module implementing an ip hash set */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include -+#include -+ -+static int limit = MAX_RANGE; -+ -+static inline __u32 -+jhash_ip(const struct ip_set_iphash *map, uint16_t i, ip_set_ip_t ip) -+{ -+ return jhash_1word(ip, *(((uint32_t *) map->initval) + i)); -+} -+ -+static inline __u32 -+hash_id(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip) -+{ -+ struct ip_set_iphash *map = (struct ip_set_iphash *) set->data; -+ __u32 id; -+ u_int16_t i; -+ ip_set_ip_t *elem; -+ -+ *hash_ip = ip & map->netmask; -+ DP("set: %s, ip:%u.%u.%u.%u, %u.%u.%u.%u, %u.%u.%u.%u", -+ set->name, HIPQUAD(ip), HIPQUAD(*hash_ip), HIPQUAD(map->netmask)); -+ -+ for (i = 0; i < map->probes; i++) { -+ id = jhash_ip(map, i, *hash_ip) % map->hashsize; -+ DP("hash key: %u", id); -+ elem = HARRAY_ELEM(map->members, ip_set_ip_t *, id); -+ if (*elem == *hash_ip) -+ return id; -+ /* No shortcut at testing - there can be deleted -+ * entries. */ -+ } -+ return UINT_MAX; -+} -+ -+static inline int -+__testip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip) -+{ -+ return (ip && hash_id(set, ip, hash_ip) != UINT_MAX); -+} -+ -+static int -+testip(struct ip_set *set, const void *data, size_t size, -+ ip_set_ip_t *hash_ip) -+{ -+ struct ip_set_req_iphash *req = -+ (struct ip_set_req_iphash *) data; -+ -+ if (size != sizeof(struct ip_set_req_iphash)) { -+ ip_set_printk("data length wrong (want %zu, have %zu)", -+ sizeof(struct ip_set_req_iphash), -+ size); -+ return -EINVAL; -+ } -+ return __testip(set, req->ip, hash_ip); -+} -+ -+static int -+testip_kernel(struct ip_set *set, -+ const struct sk_buff *skb, -+ ip_set_ip_t *hash_ip, -+ const u_int32_t *flags, -+ unsigned char index) -+{ -+ return __testip(set, -+ ntohl(flags[index] & IPSET_SRC -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) -+ ? ip_hdr(skb)->saddr -+ : ip_hdr(skb)->daddr), -+#else -+ ? skb->nh.iph->saddr -+ : skb->nh.iph->daddr), -+#endif -+ hash_ip); -+} -+ -+static inline int -+__addip(struct ip_set_iphash *map, ip_set_ip_t ip, ip_set_ip_t *hash_ip) -+{ -+ __u32 probe; -+ u_int16_t i; -+ ip_set_ip_t *elem; -+ -+ if (!ip || map->elements >= limit) -+ return -ERANGE; -+ -+ *hash_ip = ip & map->netmask; -+ -+ for (i = 0; i < map->probes; i++) { -+ probe = jhash_ip(map, i, *hash_ip) % map->hashsize; -+ elem = HARRAY_ELEM(map->members, ip_set_ip_t *, probe); -+ if (*elem == *hash_ip) -+ return -EEXIST; -+ if (!*elem) { -+ *elem = *hash_ip; -+ map->elements++; -+ return 0; -+ } -+ } -+ /* Trigger rehashing */ -+ return -EAGAIN; -+} -+ -+static int -+addip(struct ip_set *set, const void *data, size_t size, -+ ip_set_ip_t *hash_ip) -+{ -+ struct ip_set_req_iphash *req = -+ (struct ip_set_req_iphash *) data; -+ -+ if (size != sizeof(struct ip_set_req_iphash)) { -+ ip_set_printk("data length wrong (want %zu, have %zu)", -+ sizeof(struct ip_set_req_iphash), -+ size); -+ return -EINVAL; -+ } -+ return __addip((struct ip_set_iphash *) set->data, req->ip, hash_ip); -+} -+ -+static int -+addip_kernel(struct ip_set *set, -+ const struct sk_buff *skb, -+ ip_set_ip_t *hash_ip, -+ const u_int32_t *flags, -+ unsigned char index) -+{ -+ return __addip((struct ip_set_iphash *) set->data, -+ ntohl(flags[index] & IPSET_SRC -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) -+ ? ip_hdr(skb)->saddr -+ : ip_hdr(skb)->daddr), -+#else -+ ? skb->nh.iph->saddr -+ : skb->nh.iph->daddr), -+#endif -+ hash_ip); -+} -+ -+static int retry(struct ip_set *set) -+{ -+ struct ip_set_iphash *map = (struct ip_set_iphash *) set->data; -+ ip_set_ip_t hash_ip, *elem; -+ void *members; -+ u_int32_t i, hashsize = map->hashsize; -+ int res; -+ struct ip_set_iphash *tmp; -+ -+ if (map->resize == 0) -+ return -ERANGE; -+ -+ again: -+ res = 0; -+ -+ /* Calculate new hash size */ -+ hashsize += (hashsize * map->resize)/100; -+ if (hashsize == map->hashsize) -+ hashsize++; -+ -+ ip_set_printk("rehashing of set %s triggered: " -+ "hashsize grows from %u to %u", -+ set->name, map->hashsize, hashsize); -+ -+ tmp = kmalloc(sizeof(struct ip_set_iphash) -+ + map->probes * sizeof(uint32_t), GFP_ATOMIC); -+ if (!tmp) { -+ DP("out of memory for %d bytes", -+ sizeof(struct ip_set_iphash) -+ + map->probes * sizeof(uint32_t)); -+ return -ENOMEM; -+ } -+ tmp->members = harray_malloc(hashsize, sizeof(ip_set_ip_t), GFP_ATOMIC); -+ if (!tmp->members) { -+ DP("out of memory for %d bytes", hashsize * sizeof(ip_set_ip_t)); -+ kfree(tmp); -+ return -ENOMEM; -+ } -+ tmp->hashsize = hashsize; -+ tmp->elements = 0; -+ tmp->probes = map->probes; -+ tmp->resize = map->resize; -+ tmp->netmask = map->netmask; -+ memcpy(tmp->initval, map->initval, map->probes * sizeof(uint32_t)); -+ -+ write_lock_bh(&set->lock); -+ map = (struct ip_set_iphash *) set->data; /* Play safe */ -+ for (i = 0; i < map->hashsize && res == 0; i++) { -+ elem = HARRAY_ELEM(map->members, ip_set_ip_t *, i); -+ if (*elem) -+ res = __addip(tmp, *elem, &hash_ip); -+ } -+ if (res) { -+ /* Failure, try again */ -+ write_unlock_bh(&set->lock); -+ harray_free(tmp->members); -+ kfree(tmp); -+ goto again; -+ } -+ -+ /* Success at resizing! */ -+ members = map->members; -+ -+ map->hashsize = tmp->hashsize; -+ map->members = tmp->members; -+ write_unlock_bh(&set->lock); -+ -+ harray_free(members); -+ kfree(tmp); -+ -+ return 0; -+} -+ -+static inline int -+__delip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip) -+{ -+ struct ip_set_iphash *map = (struct ip_set_iphash *) set->data; -+ ip_set_ip_t id, *elem; -+ -+ if (!ip) -+ return -ERANGE; -+ -+ id = hash_id(set, ip, hash_ip); -+ if (id == UINT_MAX) -+ return -EEXIST; -+ -+ elem = HARRAY_ELEM(map->members, ip_set_ip_t *, id); -+ *elem = 0; -+ map->elements--; -+ -+ return 0; -+} -+ -+static int -+delip(struct ip_set *set, const void *data, size_t size, -+ ip_set_ip_t *hash_ip) -+{ -+ struct ip_set_req_iphash *req = -+ (struct ip_set_req_iphash *) data; -+ -+ if (size != sizeof(struct ip_set_req_iphash)) { -+ ip_set_printk("data length wrong (want %zu, have %zu)", -+ sizeof(struct ip_set_req_iphash), -+ size); -+ return -EINVAL; -+ } -+ return __delip(set, req->ip, hash_ip); -+} -+ -+static int -+delip_kernel(struct ip_set *set, -+ const struct sk_buff *skb, -+ ip_set_ip_t *hash_ip, -+ const u_int32_t *flags, -+ unsigned char index) -+{ -+ return __delip(set, -+ ntohl(flags[index] & IPSET_SRC -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) -+ ? ip_hdr(skb)->saddr -+ : ip_hdr(skb)->daddr), -+#else -+ ? skb->nh.iph->saddr -+ : skb->nh.iph->daddr), -+#endif -+ hash_ip); -+} -+ -+static int create(struct ip_set *set, const void *data, size_t size) -+{ -+ struct ip_set_req_iphash_create *req = -+ (struct ip_set_req_iphash_create *) data; -+ struct ip_set_iphash *map; -+ uint16_t i; -+ -+ if (size != sizeof(struct ip_set_req_iphash_create)) { -+ ip_set_printk("data length wrong (want %zu, have %zu)", -+ sizeof(struct ip_set_req_iphash_create), -+ size); -+ return -EINVAL; -+ } -+ -+ if (req->hashsize < 1) { -+ ip_set_printk("hashsize too small"); -+ return -ENOEXEC; -+ } -+ -+ if (req->probes < 1) { -+ ip_set_printk("probes too small"); -+ return -ENOEXEC; -+ } -+ -+ map = kmalloc(sizeof(struct ip_set_iphash) -+ + req->probes * sizeof(uint32_t), GFP_KERNEL); -+ if (!map) { -+ DP("out of memory for %d bytes", -+ sizeof(struct ip_set_iphash) -+ + req->probes * sizeof(uint32_t)); -+ return -ENOMEM; -+ } -+ for (i = 0; i < req->probes; i++) -+ get_random_bytes(((uint32_t *) map->initval)+i, 4); -+ map->elements = 0; -+ map->hashsize = req->hashsize; -+ map->probes = req->probes; -+ map->resize = req->resize; -+ map->netmask = req->netmask; -+ map->members = harray_malloc(map->hashsize, sizeof(ip_set_ip_t), GFP_KERNEL); -+ if (!map->members) { -+ DP("out of memory for %d bytes", map->hashsize * sizeof(ip_set_ip_t)); -+ kfree(map); -+ return -ENOMEM; -+ } -+ -+ set->data = map; -+ return 0; -+} -+ -+static void destroy(struct ip_set *set) -+{ -+ struct ip_set_iphash *map = (struct ip_set_iphash *) set->data; -+ -+ harray_free(map->members); -+ kfree(map); -+ -+ set->data = NULL; -+} -+ -+static void flush(struct ip_set *set) -+{ -+ struct ip_set_iphash *map = (struct ip_set_iphash *) set->data; -+ harray_flush(map->members, map->hashsize, sizeof(ip_set_ip_t)); -+ map->elements = 0; -+} -+ -+static void list_header(const struct ip_set *set, void *data) -+{ -+ struct ip_set_iphash *map = (struct ip_set_iphash *) set->data; -+ struct ip_set_req_iphash_create *header = -+ (struct ip_set_req_iphash_create *) data; -+ -+ header->hashsize = map->hashsize; -+ header->probes = map->probes; -+ header->resize = map->resize; -+ header->netmask = map->netmask; -+} -+ -+static int list_members_size(const struct ip_set *set) -+{ -+ struct ip_set_iphash *map = (struct ip_set_iphash *) set->data; -+ -+ return (map->hashsize * sizeof(ip_set_ip_t)); -+} -+ -+static void list_members(const struct ip_set *set, void *data) -+{ -+ struct ip_set_iphash *map = (struct ip_set_iphash *) set->data; -+ ip_set_ip_t i, *elem; -+ -+ for (i = 0; i < map->hashsize; i++) { -+ elem = HARRAY_ELEM(map->members, ip_set_ip_t *, i); -+ ((ip_set_ip_t *)data)[i] = *elem; -+ } -+} -+ -+static struct ip_set_type ip_set_iphash = { -+ .typename = SETTYPE_NAME, -+ .features = IPSET_TYPE_IP | IPSET_DATA_SINGLE, -+ .protocol_version = IP_SET_PROTOCOL_VERSION, -+ .create = &create, -+ .destroy = &destroy, -+ .flush = &flush, -+ .reqsize = sizeof(struct ip_set_req_iphash), -+ .addip = &addip, -+ .addip_kernel = &addip_kernel, -+ .retry = &retry, -+ .delip = &delip, -+ .delip_kernel = &delip_kernel, -+ .testip = &testip, -+ .testip_kernel = &testip_kernel, -+ .header_size = sizeof(struct ip_set_req_iphash_create), -+ .list_header = &list_header, -+ .list_members_size = &list_members_size, -+ .list_members = &list_members, -+ .me = THIS_MODULE, -+}; -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Jozsef Kadlecsik "); -+MODULE_DESCRIPTION("iphash type of IP sets"); -+module_param(limit, int, 0600); -+MODULE_PARM_DESC(limit, "maximal number of elements stored in the sets"); -+ -+static int __init ip_set_iphash_init(void) -+{ -+ return ip_set_register_set_type(&ip_set_iphash); -+} -+ -+static void __exit ip_set_iphash_fini(void) -+{ -+ /* FIXME: possible race with ip_set_create() */ -+ ip_set_unregister_set_type(&ip_set_iphash); -+} -+ -+module_init(ip_set_iphash_init); -+module_exit(ip_set_iphash_fini); ---- /dev/null -+++ b/net/ipv4/netfilter/ip_set_ipmap.c -@@ -0,0 +1,336 @@ -+/* Copyright (C) 2000-2002 Joakim Axelsson -+ * Patrick Schaaf -+ * Copyright (C) 2003-2004 Jozsef Kadlecsik -+ * -+ * 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. -+ */ -+ -+/* Kernel module implementing an IP set type: the single bitmap type */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+static inline ip_set_ip_t -+ip_to_id(const struct ip_set_ipmap *map, ip_set_ip_t ip) -+{ -+ return (ip - map->first_ip)/map->hosts; -+} -+ -+static inline int -+__testip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip) -+{ -+ struct ip_set_ipmap *map = (struct ip_set_ipmap *) set->data; -+ -+ if (ip < map->first_ip || ip > map->last_ip) -+ return -ERANGE; -+ -+ *hash_ip = ip & map->netmask; -+ DP("set: %s, ip:%u.%u.%u.%u, %u.%u.%u.%u", -+ set->name, HIPQUAD(ip), HIPQUAD(*hash_ip)); -+ return !!test_bit(ip_to_id(map, *hash_ip), map->members); -+} -+ -+static int -+testip(struct ip_set *set, const void *data, size_t size, -+ ip_set_ip_t *hash_ip) -+{ -+ struct ip_set_req_ipmap *req = -+ (struct ip_set_req_ipmap *) data; -+ -+ if (size != sizeof(struct ip_set_req_ipmap)) { -+ ip_set_printk("data length wrong (want %zu, have %zu)", -+ sizeof(struct ip_set_req_ipmap), -+ size); -+ return -EINVAL; -+ } -+ return __testip(set, req->ip, hash_ip); -+} -+ -+static int -+testip_kernel(struct ip_set *set, -+ const struct sk_buff *skb, -+ ip_set_ip_t *hash_ip, -+ const u_int32_t *flags, -+ unsigned char index) -+{ -+ int res = __testip(set, -+ ntohl(flags[index] & IPSET_SRC -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) -+ ? ip_hdr(skb)->saddr -+ : ip_hdr(skb)->daddr), -+#else -+ ? skb->nh.iph->saddr -+ : skb->nh.iph->daddr), -+#endif -+ hash_ip); -+ return (res < 0 ? 0 : res); -+} -+ -+static inline int -+__addip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip) -+{ -+ struct ip_set_ipmap *map = (struct ip_set_ipmap *) set->data; -+ -+ if (ip < map->first_ip || ip > map->last_ip) -+ return -ERANGE; -+ -+ *hash_ip = ip & map->netmask; -+ DP("%u.%u.%u.%u, %u.%u.%u.%u", HIPQUAD(ip), HIPQUAD(*hash_ip)); -+ if (test_and_set_bit(ip_to_id(map, *hash_ip), map->members)) -+ return -EEXIST; -+ -+ return 0; -+} -+ -+static int -+addip(struct ip_set *set, const void *data, size_t size, -+ ip_set_ip_t *hash_ip) -+{ -+ struct ip_set_req_ipmap *req = -+ (struct ip_set_req_ipmap *) data; -+ -+ if (size != sizeof(struct ip_set_req_ipmap)) { -+ ip_set_printk("data length wrong (want %zu, have %zu)", -+ sizeof(struct ip_set_req_ipmap), -+ size); -+ return -EINVAL; -+ } -+ DP("%u.%u.%u.%u", HIPQUAD(req->ip)); -+ return __addip(set, req->ip, hash_ip); -+} -+ -+static int -+addip_kernel(struct ip_set *set, -+ const struct sk_buff *skb, -+ ip_set_ip_t *hash_ip, -+ const u_int32_t *flags, -+ unsigned char index) -+{ -+ return __addip(set, -+ ntohl(flags[index] & IPSET_SRC -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) -+ ? ip_hdr(skb)->saddr -+ : ip_hdr(skb)->daddr), -+#else -+ ? skb->nh.iph->saddr -+ : skb->nh.iph->daddr), -+#endif -+ hash_ip); -+} -+ -+static inline int -+__delip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip) -+{ -+ struct ip_set_ipmap *map = (struct ip_set_ipmap *) set->data; -+ -+ if (ip < map->first_ip || ip > map->last_ip) -+ return -ERANGE; -+ -+ *hash_ip = ip & map->netmask; -+ DP("%u.%u.%u.%u, %u.%u.%u.%u", HIPQUAD(ip), HIPQUAD(*hash_ip)); -+ if (!test_and_clear_bit(ip_to_id(map, *hash_ip), map->members)) -+ return -EEXIST; -+ -+ return 0; -+} -+ -+static int -+delip(struct ip_set *set, const void *data, size_t size, -+ ip_set_ip_t *hash_ip) -+{ -+ struct ip_set_req_ipmap *req = -+ (struct ip_set_req_ipmap *) data; -+ -+ if (size != sizeof(struct ip_set_req_ipmap)) { -+ ip_set_printk("data length wrong (want %zu, have %zu)", -+ sizeof(struct ip_set_req_ipmap), -+ size); -+ return -EINVAL; -+ } -+ return __delip(set, req->ip, hash_ip); -+} -+ -+static int -+delip_kernel(struct ip_set *set, -+ const struct sk_buff *skb, -+ ip_set_ip_t *hash_ip, -+ const u_int32_t *flags, -+ unsigned char index) -+{ -+ return __delip(set, -+ ntohl(flags[index] & IPSET_SRC -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) -+ ? ip_hdr(skb)->saddr -+ : ip_hdr(skb)->daddr), -+#else -+ ? skb->nh.iph->saddr -+ : skb->nh.iph->daddr), -+#endif -+ hash_ip); -+} -+ -+static int create(struct ip_set *set, const void *data, size_t size) -+{ -+ int newbytes; -+ struct ip_set_req_ipmap_create *req = -+ (struct ip_set_req_ipmap_create *) data; -+ struct ip_set_ipmap *map; -+ -+ if (size != sizeof(struct ip_set_req_ipmap_create)) { -+ ip_set_printk("data length wrong (want %zu, have %zu)", -+ sizeof(struct ip_set_req_ipmap_create), -+ size); -+ return -EINVAL; -+ } -+ -+ DP("from %u.%u.%u.%u to %u.%u.%u.%u", -+ HIPQUAD(req->from), HIPQUAD(req->to)); -+ -+ if (req->from > req->to) { -+ DP("bad ip range"); -+ return -ENOEXEC; -+ } -+ -+ map = kmalloc(sizeof(struct ip_set_ipmap), GFP_KERNEL); -+ if (!map) { -+ DP("out of memory for %d bytes", -+ sizeof(struct ip_set_ipmap)); -+ return -ENOMEM; -+ } -+ map->first_ip = req->from; -+ map->last_ip = req->to; -+ map->netmask = req->netmask; -+ -+ if (req->netmask == 0xFFFFFFFF) { -+ map->hosts = 1; -+ map->sizeid = map->last_ip - map->first_ip + 1; -+ } else { -+ unsigned int mask_bits, netmask_bits; -+ ip_set_ip_t mask; -+ -+ map->first_ip &= map->netmask; /* Should we better bark? */ -+ -+ mask = range_to_mask(map->first_ip, map->last_ip, &mask_bits); -+ netmask_bits = mask_to_bits(map->netmask); -+ -+ if ((!mask && (map->first_ip || map->last_ip != 0xFFFFFFFF)) -+ || netmask_bits <= mask_bits) -+ return -ENOEXEC; -+ -+ DP("mask_bits %u, netmask_bits %u", -+ mask_bits, netmask_bits); -+ map->hosts = 2 << (32 - netmask_bits - 1); -+ map->sizeid = 2 << (netmask_bits - mask_bits - 1); -+ } -+ if (map->sizeid > MAX_RANGE + 1) { -+ ip_set_printk("range too big (max %d addresses)", -+ MAX_RANGE+1); -+ kfree(map); -+ return -ENOEXEC; -+ } -+ DP("hosts %u, sizeid %u", map->hosts, map->sizeid); -+ newbytes = bitmap_bytes(0, map->sizeid - 1); -+ map->members = kmalloc(newbytes, GFP_KERNEL); -+ if (!map->members) { -+ DP("out of memory for %d bytes", newbytes); -+ kfree(map); -+ return -ENOMEM; -+ } -+ memset(map->members, 0, newbytes); -+ -+ set->data = map; -+ return 0; -+} -+ -+static void destroy(struct ip_set *set) -+{ -+ struct ip_set_ipmap *map = (struct ip_set_ipmap *) set->data; -+ -+ kfree(map->members); -+ kfree(map); -+ -+ set->data = NULL; -+} -+ -+static void flush(struct ip_set *set) -+{ -+ struct ip_set_ipmap *map = (struct ip_set_ipmap *) set->data; -+ memset(map->members, 0, bitmap_bytes(0, map->sizeid - 1)); -+} -+ -+static void list_header(const struct ip_set *set, void *data) -+{ -+ struct ip_set_ipmap *map = (struct ip_set_ipmap *) set->data; -+ struct ip_set_req_ipmap_create *header = -+ (struct ip_set_req_ipmap_create *) data; -+ -+ header->from = map->first_ip; -+ header->to = map->last_ip; -+ header->netmask = map->netmask; -+} -+ -+static int list_members_size(const struct ip_set *set) -+{ -+ struct ip_set_ipmap *map = (struct ip_set_ipmap *) set->data; -+ -+ return bitmap_bytes(0, map->sizeid - 1); -+} -+ -+static void list_members(const struct ip_set *set, void *data) -+{ -+ struct ip_set_ipmap *map = (struct ip_set_ipmap *) set->data; -+ int bytes = bitmap_bytes(0, map->sizeid - 1); -+ -+ memcpy(data, map->members, bytes); -+} -+ -+static struct ip_set_type ip_set_ipmap = { -+ .typename = SETTYPE_NAME, -+ .features = IPSET_TYPE_IP | IPSET_DATA_SINGLE, -+ .protocol_version = IP_SET_PROTOCOL_VERSION, -+ .create = &create, -+ .destroy = &destroy, -+ .flush = &flush, -+ .reqsize = sizeof(struct ip_set_req_ipmap), -+ .addip = &addip, -+ .addip_kernel = &addip_kernel, -+ .delip = &delip, -+ .delip_kernel = &delip_kernel, -+ .testip = &testip, -+ .testip_kernel = &testip_kernel, -+ .header_size = sizeof(struct ip_set_req_ipmap_create), -+ .list_header = &list_header, -+ .list_members_size = &list_members_size, -+ .list_members = &list_members, -+ .me = THIS_MODULE, -+}; -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Jozsef Kadlecsik "); -+MODULE_DESCRIPTION("ipmap type of IP sets"); -+ -+static int __init ip_set_ipmap_init(void) -+{ -+ return ip_set_register_set_type(&ip_set_ipmap); -+} -+ -+static void __exit ip_set_ipmap_fini(void) -+{ -+ /* FIXME: possible race with ip_set_create() */ -+ ip_set_unregister_set_type(&ip_set_ipmap); -+} -+ -+module_init(ip_set_ipmap_init); -+module_exit(ip_set_ipmap_fini); ---- /dev/null -+++ b/net/ipv4/netfilter/ip_set_ipporthash.c -@@ -0,0 +1,581 @@ -+/* Copyright (C) 2003-2004 Jozsef Kadlecsik -+ * -+ * 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. -+ */ -+ -+/* Kernel module implementing an ip+port hash set */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include -+#include -+ -+static int limit = MAX_RANGE; -+ -+/* We must handle non-linear skbs */ -+static inline ip_set_ip_t -+get_port(const struct sk_buff *skb, u_int32_t flags) -+{ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) -+ struct iphdr *iph = ip_hdr(skb); -+#else -+ struct iphdr *iph = skb->nh.iph; -+#endif -+ u_int16_t offset = ntohs(iph->frag_off) & IP_OFFSET; -+ -+ switch (iph->protocol) { -+ case IPPROTO_TCP: { -+ struct tcphdr tcph; -+ -+ /* See comments at tcp_match in ip_tables.c */ -+ if (offset) -+ return INVALID_PORT; -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) -+ if (skb_copy_bits(skb, ip_hdr(skb)->ihl*4, &tcph, sizeof(tcph)) < 0) -+#else -+ if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &tcph, sizeof(tcph)) < 0) -+#endif -+ /* No choice either */ -+ return INVALID_PORT; -+ -+ return ntohs(flags & IPSET_SRC ? -+ tcph.source : tcph.dest); -+ } -+ case IPPROTO_UDP: { -+ struct udphdr udph; -+ -+ if (offset) -+ return INVALID_PORT; -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) -+ if (skb_copy_bits(skb, ip_hdr(skb)->ihl*4, &udph, sizeof(udph)) < 0) -+#else -+ if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &udph, sizeof(udph)) < 0) -+#endif -+ /* No choice either */ -+ return INVALID_PORT; -+ -+ return ntohs(flags & IPSET_SRC ? -+ udph.source : udph.dest); -+ } -+ default: -+ return INVALID_PORT; -+ } -+} -+ -+static inline __u32 -+jhash_ip(const struct ip_set_ipporthash *map, uint16_t i, ip_set_ip_t ip) -+{ -+ return jhash_1word(ip, *(((uint32_t *) map->initval) + i)); -+} -+ -+#define HASH_IP(map, ip, port) (port + ((ip - ((map)->first_ip)) << 16)) -+ -+static inline __u32 -+hash_id(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t port, -+ ip_set_ip_t *hash_ip) -+{ -+ struct ip_set_ipporthash *map = -+ (struct ip_set_ipporthash *) set->data; -+ __u32 id; -+ u_int16_t i; -+ ip_set_ip_t *elem; -+ -+ *hash_ip = HASH_IP(map, ip, port); -+ DP("set: %s, ipport:%u.%u.%u.%u:%u, %u.%u.%u.%u", -+ set->name, HIPQUAD(ip), port, HIPQUAD(*hash_ip)); -+ -+ for (i = 0; i < map->probes; i++) { -+ id = jhash_ip(map, i, *hash_ip) % map->hashsize; -+ DP("hash key: %u", id); -+ elem = HARRAY_ELEM(map->members, ip_set_ip_t *, id); -+ if (*elem == *hash_ip) -+ return id; -+ /* No shortcut at testing - there can be deleted -+ * entries. */ -+ } -+ return UINT_MAX; -+} -+ -+static inline int -+__testip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t port, -+ ip_set_ip_t *hash_ip) -+{ -+ struct ip_set_ipporthash *map = (struct ip_set_ipporthash *) set->data; -+ -+ if (ip < map->first_ip || ip > map->last_ip) -+ return -ERANGE; -+ -+ return (hash_id(set, ip, port, hash_ip) != UINT_MAX); -+} -+ -+static int -+testip(struct ip_set *set, const void *data, size_t size, -+ ip_set_ip_t *hash_ip) -+{ -+ struct ip_set_req_ipporthash *req = -+ (struct ip_set_req_ipporthash *) data; -+ -+ if (size != sizeof(struct ip_set_req_ipporthash)) { -+ ip_set_printk("data length wrong (want %zu, have %zu)", -+ sizeof(struct ip_set_req_ipporthash), -+ size); -+ return -EINVAL; -+ } -+ return __testip(set, req->ip, req->port, hash_ip); -+} -+ -+static int -+testip_kernel(struct ip_set *set, -+ const struct sk_buff *skb, -+ ip_set_ip_t *hash_ip, -+ const u_int32_t *flags, -+ unsigned char index) -+{ -+ ip_set_ip_t port; -+ int res; -+ -+ if (flags[index+1] == 0) -+ return 0; -+ -+ port = get_port(skb, flags[index+1]); -+ -+ DP("flag: %s src: %u.%u.%u.%u dst: %u.%u.%u.%u", -+ flags[index] & IPSET_SRC ? "SRC" : "DST", -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) -+ NIPQUAD(ip_hdr(skb)->saddr), -+ NIPQUAD(ip_hdr(skb)->daddr)); -+#else -+ NIPQUAD(skb->nh.iph->saddr), -+ NIPQUAD(skb->nh.iph->daddr)); -+#endif -+ DP("flag %s port %u", -+ flags[index+1] & IPSET_SRC ? "SRC" : "DST", -+ port); -+ if (port == INVALID_PORT) -+ return 0; -+ -+ res = __testip(set, -+ ntohl(flags[index] & IPSET_SRC -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) -+ ? ip_hdr(skb)->saddr -+ : ip_hdr(skb)->daddr), -+#else -+ ? skb->nh.iph->saddr -+ : skb->nh.iph->daddr), -+#endif -+ port, -+ hash_ip); -+ return (res < 0 ? 0 : res); -+ -+} -+ -+static inline int -+__add_haship(struct ip_set_ipporthash *map, ip_set_ip_t hash_ip) -+{ -+ __u32 probe; -+ u_int16_t i; -+ ip_set_ip_t *elem; -+ -+ for (i = 0; i < map->probes; i++) { -+ probe = jhash_ip(map, i, hash_ip) % map->hashsize; -+ elem = HARRAY_ELEM(map->members, ip_set_ip_t *, probe); -+ if (*elem == hash_ip) -+ return -EEXIST; -+ if (!*elem) { -+ *elem = hash_ip; -+ map->elements++; -+ return 0; -+ } -+ } -+ /* Trigger rehashing */ -+ return -EAGAIN; -+} -+ -+static inline int -+__addip(struct ip_set_ipporthash *map, ip_set_ip_t ip, ip_set_ip_t port, -+ ip_set_ip_t *hash_ip) -+{ -+ if (map->elements > limit) -+ return -ERANGE; -+ if (ip < map->first_ip || ip > map->last_ip) -+ return -ERANGE; -+ -+ *hash_ip = HASH_IP(map, ip, port); -+ -+ return __add_haship(map, *hash_ip); -+} -+ -+static int -+addip(struct ip_set *set, const void *data, size_t size, -+ ip_set_ip_t *hash_ip) -+{ -+ struct ip_set_req_ipporthash *req = -+ (struct ip_set_req_ipporthash *) data; -+ -+ if (size != sizeof(struct ip_set_req_ipporthash)) { -+ ip_set_printk("data length wrong (want %zu, have %zu)", -+ sizeof(struct ip_set_req_ipporthash), -+ size); -+ return -EINVAL; -+ } -+ return __addip((struct ip_set_ipporthash *) set->data, -+ req->ip, req->port, hash_ip); -+} -+ -+static int -+addip_kernel(struct ip_set *set, -+ const struct sk_buff *skb, -+ ip_set_ip_t *hash_ip, -+ const u_int32_t *flags, -+ unsigned char index) -+{ -+ ip_set_ip_t port; -+ -+ if (flags[index+1] == 0) -+ return -EINVAL; -+ -+ port = get_port(skb, flags[index+1]); -+ -+ DP("flag: %s src: %u.%u.%u.%u dst: %u.%u.%u.%u", -+ flags[index] & IPSET_SRC ? "SRC" : "DST", -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) -+ NIPQUAD(ip_hdr(skb)->saddr), -+ NIPQUAD(ip_hdr(skb)->daddr)); -+#else -+ NIPQUAD(skb->nh.iph->saddr), -+ NIPQUAD(skb->nh.iph->daddr)); -+#endif -+ DP("flag %s port %u", -+ flags[index+1] & IPSET_SRC ? "SRC" : "DST", -+ port); -+ if (port == INVALID_PORT) -+ return -EINVAL; -+ -+ return __addip((struct ip_set_ipporthash *) set->data, -+ ntohl(flags[index] & IPSET_SRC -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) -+ ? ip_hdr(skb)->saddr -+ : ip_hdr(skb)->daddr), -+#else -+ ? skb->nh.iph->saddr -+ : skb->nh.iph->daddr), -+#endif -+ port, -+ hash_ip); -+} -+ -+static int retry(struct ip_set *set) -+{ -+ struct ip_set_ipporthash *map = (struct ip_set_ipporthash *) set->data; -+ ip_set_ip_t *elem; -+ void *members; -+ u_int32_t i, hashsize = map->hashsize; -+ int res; -+ struct ip_set_ipporthash *tmp; -+ -+ if (map->resize == 0) -+ return -ERANGE; -+ -+ again: -+ res = 0; -+ -+ /* Calculate new hash size */ -+ hashsize += (hashsize * map->resize)/100; -+ if (hashsize == map->hashsize) -+ hashsize++; -+ -+ ip_set_printk("rehashing of set %s triggered: " -+ "hashsize grows from %u to %u", -+ set->name, map->hashsize, hashsize); -+ -+ tmp = kmalloc(sizeof(struct ip_set_ipporthash) -+ + map->probes * sizeof(uint32_t), GFP_ATOMIC); -+ if (!tmp) { -+ DP("out of memory for %d bytes", -+ sizeof(struct ip_set_ipporthash) -+ + map->probes * sizeof(uint32_t)); -+ return -ENOMEM; -+ } -+ tmp->members = harray_malloc(hashsize, sizeof(ip_set_ip_t), GFP_ATOMIC); -+ if (!tmp->members) { -+ DP("out of memory for %d bytes", hashsize * sizeof(ip_set_ip_t)); -+ kfree(tmp); -+ return -ENOMEM; -+ } -+ tmp->hashsize = hashsize; -+ tmp->elements = 0; -+ tmp->probes = map->probes; -+ tmp->resize = map->resize; -+ tmp->first_ip = map->first_ip; -+ tmp->last_ip = map->last_ip; -+ memcpy(tmp->initval, map->initval, map->probes * sizeof(uint32_t)); -+ -+ write_lock_bh(&set->lock); -+ map = (struct ip_set_ipporthash *) set->data; /* Play safe */ -+ for (i = 0; i < map->hashsize && res == 0; i++) { -+ elem = HARRAY_ELEM(map->members, ip_set_ip_t *, i); -+ if (*elem) -+ res = __add_haship(tmp, *elem); -+ } -+ if (res) { -+ /* Failure, try again */ -+ write_unlock_bh(&set->lock); -+ harray_free(tmp->members); -+ kfree(tmp); -+ goto again; -+ } -+ -+ /* Success at resizing! */ -+ members = map->members; -+ -+ map->hashsize = tmp->hashsize; -+ map->members = tmp->members; -+ write_unlock_bh(&set->lock); -+ -+ harray_free(members); -+ kfree(tmp); -+ -+ return 0; -+} -+ -+static inline int -+__delip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t port, -+ ip_set_ip_t *hash_ip) -+{ -+ struct ip_set_ipporthash *map = (struct ip_set_ipporthash *) set->data; -+ ip_set_ip_t id; -+ ip_set_ip_t *elem; -+ -+ if (ip < map->first_ip || ip > map->last_ip) -+ return -ERANGE; -+ -+ id = hash_id(set, ip, port, hash_ip); -+ -+ if (id == UINT_MAX) -+ return -EEXIST; -+ -+ elem = HARRAY_ELEM(map->members, ip_set_ip_t *, id); -+ *elem = 0; -+ map->elements--; -+ -+ return 0; -+} -+ -+static int -+delip(struct ip_set *set, const void *data, size_t size, -+ ip_set_ip_t *hash_ip) -+{ -+ struct ip_set_req_ipporthash *req = -+ (struct ip_set_req_ipporthash *) data; -+ -+ if (size != sizeof(struct ip_set_req_ipporthash)) { -+ ip_set_printk("data length wrong (want %zu, have %zu)", -+ sizeof(struct ip_set_req_ipporthash), -+ size); -+ return -EINVAL; -+ } -+ return __delip(set, req->ip, req->port, hash_ip); -+} -+ -+static int -+delip_kernel(struct ip_set *set, -+ const struct sk_buff *skb, -+ ip_set_ip_t *hash_ip, -+ const u_int32_t *flags, -+ unsigned char index) -+{ -+ ip_set_ip_t port; -+ -+ if (flags[index+1] == 0) -+ return -EINVAL; -+ -+ port = get_port(skb, flags[index+1]); -+ -+ DP("flag: %s src: %u.%u.%u.%u dst: %u.%u.%u.%u", -+ flags[index] & IPSET_SRC ? "SRC" : "DST", -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) -+ NIPQUAD(ip_hdr(skb)->saddr), -+ NIPQUAD(ip_hdr(skb)->daddr)); -+#else -+ NIPQUAD(skb->nh.iph->saddr), -+ NIPQUAD(skb->nh.iph->daddr)); -+#endif -+ DP("flag %s port %u", -+ flags[index+1] & IPSET_SRC ? "SRC" : "DST", -+ port); -+ if (port == INVALID_PORT) -+ return -EINVAL; -+ -+ return __delip(set, -+ ntohl(flags[index] & IPSET_SRC -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) -+ ? ip_hdr(skb)->saddr -+ : ip_hdr(skb)->daddr), -+#else -+ ? skb->nh.iph->saddr -+ : skb->nh.iph->daddr), -+#endif -+ port, -+ hash_ip); -+} -+ -+static int create(struct ip_set *set, const void *data, size_t size) -+{ -+ struct ip_set_req_ipporthash_create *req = -+ (struct ip_set_req_ipporthash_create *) data; -+ struct ip_set_ipporthash *map; -+ uint16_t i; -+ -+ if (size != sizeof(struct ip_set_req_ipporthash_create)) { -+ ip_set_printk("data length wrong (want %zu, have %zu)", -+ sizeof(struct ip_set_req_ipporthash_create), -+ size); -+ return -EINVAL; -+ } -+ -+ if (req->hashsize < 1) { -+ ip_set_printk("hashsize too small"); -+ return -ENOEXEC; -+ } -+ -+ if (req->probes < 1) { -+ ip_set_printk("probes too small"); -+ return -ENOEXEC; -+ } -+ -+ map = kmalloc(sizeof(struct ip_set_ipporthash) -+ + req->probes * sizeof(uint32_t), GFP_KERNEL); -+ if (!map) { -+ DP("out of memory for %d bytes", -+ sizeof(struct ip_set_ipporthash) -+ + req->probes * sizeof(uint32_t)); -+ return -ENOMEM; -+ } -+ for (i = 0; i < req->probes; i++) -+ get_random_bytes(((uint32_t *) map->initval)+i, 4); -+ map->elements = 0; -+ map->hashsize = req->hashsize; -+ map->probes = req->probes; -+ map->resize = req->resize; -+ map->first_ip = req->from; -+ map->last_ip = req->to; -+ map->members = harray_malloc(map->hashsize, sizeof(ip_set_ip_t), GFP_KERNEL); -+ if (!map->members) { -+ DP("out of memory for %d bytes", map->hashsize * sizeof(ip_set_ip_t)); -+ kfree(map); -+ return -ENOMEM; -+ } -+ -+ set->data = map; -+ return 0; -+} -+ -+static void destroy(struct ip_set *set) -+{ -+ struct ip_set_ipporthash *map = (struct ip_set_ipporthash *) set->data; -+ -+ harray_free(map->members); -+ kfree(map); -+ -+ set->data = NULL; -+} -+ -+static void flush(struct ip_set *set) -+{ -+ struct ip_set_ipporthash *map = (struct ip_set_ipporthash *) set->data; -+ harray_flush(map->members, map->hashsize, sizeof(ip_set_ip_t)); -+ map->elements = 0; -+} -+ -+static void list_header(const struct ip_set *set, void *data) -+{ -+ struct ip_set_ipporthash *map = (struct ip_set_ipporthash *) set->data; -+ struct ip_set_req_ipporthash_create *header = -+ (struct ip_set_req_ipporthash_create *) data; -+ -+ header->hashsize = map->hashsize; -+ header->probes = map->probes; -+ header->resize = map->resize; -+ header->from = map->first_ip; -+ header->to = map->last_ip; -+} -+ -+static int list_members_size(const struct ip_set *set) -+{ -+ struct ip_set_ipporthash *map = (struct ip_set_ipporthash *) set->data; -+ -+ return (map->hashsize * sizeof(ip_set_ip_t)); -+} -+ -+static void list_members(const struct ip_set *set, void *data) -+{ -+ struct ip_set_ipporthash *map = (struct ip_set_ipporthash *) set->data; -+ ip_set_ip_t i, *elem; -+ -+ for (i = 0; i < map->hashsize; i++) { -+ elem = HARRAY_ELEM(map->members, ip_set_ip_t *, i); -+ ((ip_set_ip_t *)data)[i] = *elem; -+ } -+} -+ -+static struct ip_set_type ip_set_ipporthash = { -+ .typename = SETTYPE_NAME, -+ .features = IPSET_TYPE_IP | IPSET_TYPE_PORT | IPSET_DATA_DOUBLE, -+ .protocol_version = IP_SET_PROTOCOL_VERSION, -+ .create = &create, -+ .destroy = &destroy, -+ .flush = &flush, -+ .reqsize = sizeof(struct ip_set_req_ipporthash), -+ .addip = &addip, -+ .addip_kernel = &addip_kernel, -+ .retry = &retry, -+ .delip = &delip, -+ .delip_kernel = &delip_kernel, -+ .testip = &testip, -+ .testip_kernel = &testip_kernel, -+ .header_size = sizeof(struct ip_set_req_ipporthash_create), -+ .list_header = &list_header, -+ .list_members_size = &list_members_size, -+ .list_members = &list_members, -+ .me = THIS_MODULE, -+}; -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Jozsef Kadlecsik "); -+MODULE_DESCRIPTION("ipporthash type of IP sets"); -+module_param(limit, int, 0600); -+MODULE_PARM_DESC(limit, "maximal number of elements stored in the sets"); -+ -+static int __init ip_set_ipporthash_init(void) -+{ -+ return ip_set_register_set_type(&ip_set_ipporthash); -+} -+ -+static void __exit ip_set_ipporthash_fini(void) -+{ -+ /* FIXME: possible race with ip_set_create() */ -+ ip_set_unregister_set_type(&ip_set_ipporthash); -+} -+ -+module_init(ip_set_ipporthash_init); -+module_exit(ip_set_ipporthash_fini); ---- /dev/null -+++ b/net/ipv4/netfilter/ip_set_iptree.c -@@ -0,0 +1,612 @@ -+/* Copyright (C) 2005 Jozsef Kadlecsik -+ * -+ * 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. -+ */ -+ -+/* Kernel module implementing an IP set type: the iptree type */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* Backward compatibility */ -+#ifndef __nocast -+#define __nocast -+#endif -+ -+#include -+ -+static int limit = MAX_RANGE; -+ -+/* Garbage collection interval in seconds: */ -+#define IPTREE_GC_TIME 5*60 -+/* Sleep so many milliseconds before trying again -+ * to delete the gc timer at destroying/flushing a set */ -+#define IPTREE_DESTROY_SLEEP 100 -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21) -+static struct kmem_cache *branch_cachep; -+static struct kmem_cache *leaf_cachep; -+#else -+static kmem_cache_t *branch_cachep; -+static kmem_cache_t *leaf_cachep; -+#endif -+ -+#if defined(__LITTLE_ENDIAN) -+#define ABCD(a,b,c,d,addrp) do { \ -+ a = ((unsigned char *)addrp)[3]; \ -+ b = ((unsigned char *)addrp)[2]; \ -+ c = ((unsigned char *)addrp)[1]; \ -+ d = ((unsigned char *)addrp)[0]; \ -+} while (0) -+#elif defined(__BIG_ENDIAN) -+#define ABCD(a,b,c,d,addrp) do { \ -+ a = ((unsigned char *)addrp)[0]; \ -+ b = ((unsigned char *)addrp)[1]; \ -+ c = ((unsigned char *)addrp)[2]; \ -+ d = ((unsigned char *)addrp)[3]; \ -+} while (0) -+#else -+#error "Please fix asm/byteorder.h" -+#endif /* __LITTLE_ENDIAN */ -+ -+#define TESTIP_WALK(map, elem, branch) do { \ -+ if ((map)->tree[elem]) { \ -+ branch = (map)->tree[elem]; \ -+ } else \ -+ return 0; \ -+} while (0) -+ -+static inline int -+__testip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip) -+{ -+ struct ip_set_iptree *map = (struct ip_set_iptree *) set->data; -+ struct ip_set_iptreeb *btree; -+ struct ip_set_iptreec *ctree; -+ struct ip_set_iptreed *dtree; -+ unsigned char a,b,c,d; -+ -+ if (!ip) -+ return -ERANGE; -+ -+ *hash_ip = ip; -+ ABCD(a, b, c, d, hash_ip); -+ DP("%u %u %u %u timeout %u", a, b, c, d, map->timeout); -+ TESTIP_WALK(map, a, btree); -+ TESTIP_WALK(btree, b, ctree); -+ TESTIP_WALK(ctree, c, dtree); -+ DP("%lu %lu", dtree->expires[d], jiffies); -+ return dtree->expires[d] -+ && (!map->timeout -+ || time_after(dtree->expires[d], jiffies)); -+} -+ -+static int -+testip(struct ip_set *set, const void *data, size_t size, -+ ip_set_ip_t *hash_ip) -+{ -+ struct ip_set_req_iptree *req = -+ (struct ip_set_req_iptree *) data; -+ -+ if (size != sizeof(struct ip_set_req_iptree)) { -+ ip_set_printk("data length wrong (want %zu, have %zu)", -+ sizeof(struct ip_set_req_iptree), -+ size); -+ return -EINVAL; -+ } -+ return __testip(set, req->ip, hash_ip); -+} -+ -+static int -+testip_kernel(struct ip_set *set, -+ const struct sk_buff *skb, -+ ip_set_ip_t *hash_ip, -+ const u_int32_t *flags, -+ unsigned char index) -+{ -+ int res; -+ -+ DP("flag: %s src: %u.%u.%u.%u dst: %u.%u.%u.%u", -+ flags[index] & IPSET_SRC ? "SRC" : "DST", -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) -+ NIPQUAD(ip_hdr(skb)->saddr), -+ NIPQUAD(ip_hdr(skb)->daddr)); -+#else -+ NIPQUAD(skb->nh.iph->saddr), -+ NIPQUAD(skb->nh.iph->daddr)); -+#endif -+ -+ res = __testip(set, -+ ntohl(flags[index] & IPSET_SRC -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) -+ ? ip_hdr(skb)->saddr -+ : ip_hdr(skb)->daddr), -+#else -+ ? skb->nh.iph->saddr -+ : skb->nh.iph->daddr), -+#endif -+ hash_ip); -+ return (res < 0 ? 0 : res); -+} -+ -+#define ADDIP_WALK(map, elem, branch, type, cachep) do { \ -+ if ((map)->tree[elem]) { \ -+ DP("found %u", elem); \ -+ branch = (map)->tree[elem]; \ -+ } else { \ -+ branch = (type *) \ -+ kmem_cache_alloc(cachep, GFP_ATOMIC); \ -+ if (branch == NULL) \ -+ return -ENOMEM; \ -+ memset(branch, 0, sizeof(*branch)); \ -+ (map)->tree[elem] = branch; \ -+ DP("alloc %u", elem); \ -+ } \ -+} while (0) -+ -+static inline int -+__addip(struct ip_set *set, ip_set_ip_t ip, unsigned int timeout, -+ ip_set_ip_t *hash_ip) -+{ -+ struct ip_set_iptree *map = (struct ip_set_iptree *) set->data; -+ struct ip_set_iptreeb *btree; -+ struct ip_set_iptreec *ctree; -+ struct ip_set_iptreed *dtree; -+ unsigned char a,b,c,d; -+ int ret = 0; -+ -+ if (!ip || map->elements >= limit) -+ /* We could call the garbage collector -+ * but it's probably overkill */ -+ return -ERANGE; -+ -+ *hash_ip = ip; -+ ABCD(a, b, c, d, hash_ip); -+ DP("%u %u %u %u timeout %u", a, b, c, d, timeout); -+ ADDIP_WALK(map, a, btree, struct ip_set_iptreeb, branch_cachep); -+ ADDIP_WALK(btree, b, ctree, struct ip_set_iptreec, branch_cachep); -+ ADDIP_WALK(ctree, c, dtree, struct ip_set_iptreed, leaf_cachep); -+ if (dtree->expires[d] -+ && (!map->timeout || time_after(dtree->expires[d], jiffies))) -+ ret = -EEXIST; -+ dtree->expires[d] = map->timeout ? (timeout * HZ + jiffies) : 1; -+ /* Lottery: I won! */ -+ if (dtree->expires[d] == 0) -+ dtree->expires[d] = 1; -+ DP("%u %lu", d, dtree->expires[d]); -+ if (ret == 0) -+ map->elements++; -+ return ret; -+} -+ -+static int -+addip(struct ip_set *set, const void *data, size_t size, -+ ip_set_ip_t *hash_ip) -+{ -+ struct ip_set_iptree *map = (struct ip_set_iptree *) set->data; -+ struct ip_set_req_iptree *req = -+ (struct ip_set_req_iptree *) data; -+ -+ if (size != sizeof(struct ip_set_req_iptree)) { -+ ip_set_printk("data length wrong (want %zu, have %zu)", -+ sizeof(struct ip_set_req_iptree), -+ size); -+ return -EINVAL; -+ } -+ DP("%u.%u.%u.%u %u", HIPQUAD(req->ip), req->timeout); -+ return __addip(set, req->ip, -+ req->timeout ? req->timeout : map->timeout, -+ hash_ip); -+} -+ -+static int -+addip_kernel(struct ip_set *set, -+ const struct sk_buff *skb, -+ ip_set_ip_t *hash_ip, -+ const u_int32_t *flags, -+ unsigned char index) -+{ -+ struct ip_set_iptree *map = (struct ip_set_iptree *) set->data; -+ -+ return __addip(set, -+ ntohl(flags[index] & IPSET_SRC -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) -+ ? ip_hdr(skb)->saddr -+ : ip_hdr(skb)->daddr), -+#else -+ ? skb->nh.iph->saddr -+ : skb->nh.iph->daddr), -+#endif -+ map->timeout, -+ hash_ip); -+} -+ -+#define DELIP_WALK(map, elem, branch) do { \ -+ if ((map)->tree[elem]) { \ -+ branch = (map)->tree[elem]; \ -+ } else \ -+ return -EEXIST; \ -+} while (0) -+ -+static inline int -+__delip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip) -+{ -+ struct ip_set_iptree *map = (struct ip_set_iptree *) set->data; -+ struct ip_set_iptreeb *btree; -+ struct ip_set_iptreec *ctree; -+ struct ip_set_iptreed *dtree; -+ unsigned char a,b,c,d; -+ -+ if (!ip) -+ return -ERANGE; -+ -+ *hash_ip = ip; -+ ABCD(a, b, c, d, hash_ip); -+ DELIP_WALK(map, a, btree); -+ DELIP_WALK(btree, b, ctree); -+ DELIP_WALK(ctree, c, dtree); -+ -+ if (dtree->expires[d]) { -+ dtree->expires[d] = 0; -+ map->elements--; -+ return 0; -+ } -+ return -EEXIST; -+} -+ -+static int -+delip(struct ip_set *set, const void *data, size_t size, -+ ip_set_ip_t *hash_ip) -+{ -+ struct ip_set_req_iptree *req = -+ (struct ip_set_req_iptree *) data; -+ -+ if (size != sizeof(struct ip_set_req_iptree)) { -+ ip_set_printk("data length wrong (want %zu, have %zu)", -+ sizeof(struct ip_set_req_iptree), -+ size); -+ return -EINVAL; -+ } -+ return __delip(set, req->ip, hash_ip); -+} -+ -+static int -+delip_kernel(struct ip_set *set, -+ const struct sk_buff *skb, -+ ip_set_ip_t *hash_ip, -+ const u_int32_t *flags, -+ unsigned char index) -+{ -+ return __delip(set, -+ ntohl(flags[index] & IPSET_SRC -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) -+ ? ip_hdr(skb)->saddr -+ : ip_hdr(skb)->daddr), -+#else -+ ? skb->nh.iph->saddr -+ : skb->nh.iph->daddr), -+#endif -+ hash_ip); -+} -+ -+#define LOOP_WALK_BEGIN(map, i, branch) \ -+ for (i = 0; i < 256; i++) { \ -+ if (!(map)->tree[i]) \ -+ continue; \ -+ branch = (map)->tree[i] -+ -+#define LOOP_WALK_END } -+ -+static void ip_tree_gc(unsigned long ul_set) -+{ -+ struct ip_set *set = (void *) ul_set; -+ struct ip_set_iptree *map = (struct ip_set_iptree *) set->data; -+ struct ip_set_iptreeb *btree; -+ struct ip_set_iptreec *ctree; -+ struct ip_set_iptreed *dtree; -+ unsigned int a,b,c,d; -+ unsigned char i,j,k; -+ -+ i = j = k = 0; -+ DP("gc: %s", set->name); -+ write_lock_bh(&set->lock); -+ LOOP_WALK_BEGIN(map, a, btree); -+ LOOP_WALK_BEGIN(btree, b, ctree); -+ LOOP_WALK_BEGIN(ctree, c, dtree); -+ for (d = 0; d < 256; d++) { -+ if (dtree->expires[d]) { -+ DP("gc: %u %u %u %u: expires %lu jiffies %lu", -+ a, b, c, d, -+ dtree->expires[d], jiffies); -+ if (map->timeout -+ && time_before(dtree->expires[d], jiffies)) { -+ dtree->expires[d] = 0; -+ map->elements--; -+ } else -+ k = 1; -+ } -+ } -+ if (k == 0) { -+ DP("gc: %s: leaf %u %u %u empty", -+ set->name, a, b, c); -+ kmem_cache_free(leaf_cachep, dtree); -+ ctree->tree[c] = NULL; -+ } else { -+ DP("gc: %s: leaf %u %u %u not empty", -+ set->name, a, b, c); -+ j = 1; -+ k = 0; -+ } -+ LOOP_WALK_END; -+ if (j == 0) { -+ DP("gc: %s: branch %u %u empty", -+ set->name, a, b); -+ kmem_cache_free(branch_cachep, ctree); -+ btree->tree[b] = NULL; -+ } else { -+ DP("gc: %s: branch %u %u not empty", -+ set->name, a, b); -+ i = 1; -+ j = k = 0; -+ } -+ LOOP_WALK_END; -+ if (i == 0) { -+ DP("gc: %s: branch %u empty", -+ set->name, a); -+ kmem_cache_free(branch_cachep, btree); -+ map->tree[a] = NULL; -+ } else { -+ DP("gc: %s: branch %u not empty", -+ set->name, a); -+ i = j = k = 0; -+ } -+ LOOP_WALK_END; -+ write_unlock_bh(&set->lock); -+ -+ map->gc.expires = jiffies + map->gc_interval * HZ; -+ add_timer(&map->gc); -+} -+ -+static inline void init_gc_timer(struct ip_set *set) -+{ -+ struct ip_set_iptree *map = (struct ip_set_iptree *) set->data; -+ -+ /* Even if there is no timeout for the entries, -+ * we still have to call gc because delete -+ * do not clean up empty branches */ -+ map->gc_interval = IPTREE_GC_TIME; -+ init_timer(&map->gc); -+ map->gc.data = (unsigned long) set; -+ map->gc.function = ip_tree_gc; -+ map->gc.expires = jiffies + map->gc_interval * HZ; -+ add_timer(&map->gc); -+} -+ -+static int create(struct ip_set *set, const void *data, size_t size) -+{ -+ struct ip_set_req_iptree_create *req = -+ (struct ip_set_req_iptree_create *) data; -+ struct ip_set_iptree *map; -+ -+ if (size != sizeof(struct ip_set_req_iptree_create)) { -+ ip_set_printk("data length wrong (want %zu, have %zu)", -+ sizeof(struct ip_set_req_iptree_create), -+ size); -+ return -EINVAL; -+ } -+ -+ map = kmalloc(sizeof(struct ip_set_iptree), GFP_KERNEL); -+ if (!map) { -+ DP("out of memory for %d bytes", -+ sizeof(struct ip_set_iptree)); -+ return -ENOMEM; -+ } -+ memset(map, 0, sizeof(*map)); -+ map->timeout = req->timeout; -+ map->elements = 0; -+ set->data = map; -+ -+ init_gc_timer(set); -+ -+ return 0; -+} -+ -+static void __flush(struct ip_set_iptree *map) -+{ -+ struct ip_set_iptreeb *btree; -+ struct ip_set_iptreec *ctree; -+ struct ip_set_iptreed *dtree; -+ unsigned int a,b,c; -+ -+ LOOP_WALK_BEGIN(map, a, btree); -+ LOOP_WALK_BEGIN(btree, b, ctree); -+ LOOP_WALK_BEGIN(ctree, c, dtree); -+ kmem_cache_free(leaf_cachep, dtree); -+ LOOP_WALK_END; -+ kmem_cache_free(branch_cachep, ctree); -+ LOOP_WALK_END; -+ kmem_cache_free(branch_cachep, btree); -+ LOOP_WALK_END; -+ map->elements = 0; -+} -+ -+static void destroy(struct ip_set *set) -+{ -+ struct ip_set_iptree *map = (struct ip_set_iptree *) set->data; -+ -+ /* gc might be running */ -+ while (!del_timer(&map->gc)) -+ msleep(IPTREE_DESTROY_SLEEP); -+ __flush(map); -+ kfree(map); -+ set->data = NULL; -+} -+ -+static void flush(struct ip_set *set) -+{ -+ struct ip_set_iptree *map = (struct ip_set_iptree *) set->data; -+ unsigned int timeout = map->timeout; -+ -+ /* gc might be running */ -+ while (!del_timer(&map->gc)) -+ msleep(IPTREE_DESTROY_SLEEP); -+ __flush(map); -+ memset(map, 0, sizeof(*map)); -+ map->timeout = timeout; -+ -+ init_gc_timer(set); -+} -+ -+static void list_header(const struct ip_set *set, void *data) -+{ -+ struct ip_set_iptree *map = (struct ip_set_iptree *) set->data; -+ struct ip_set_req_iptree_create *header = -+ (struct ip_set_req_iptree_create *) data; -+ -+ header->timeout = map->timeout; -+} -+ -+static int list_members_size(const struct ip_set *set) -+{ -+ struct ip_set_iptree *map = (struct ip_set_iptree *) set->data; -+ struct ip_set_iptreeb *btree; -+ struct ip_set_iptreec *ctree; -+ struct ip_set_iptreed *dtree; -+ unsigned int a,b,c,d; -+ unsigned int count = 0; -+ -+ LOOP_WALK_BEGIN(map, a, btree); -+ LOOP_WALK_BEGIN(btree, b, ctree); -+ LOOP_WALK_BEGIN(ctree, c, dtree); -+ for (d = 0; d < 256; d++) { -+ if (dtree->expires[d] -+ && (!map->timeout || time_after(dtree->expires[d], jiffies))) -+ count++; -+ } -+ LOOP_WALK_END; -+ LOOP_WALK_END; -+ LOOP_WALK_END; -+ -+ DP("members %u", count); -+ return (count * sizeof(struct ip_set_req_iptree)); -+} -+ -+static void list_members(const struct ip_set *set, void *data) -+{ -+ struct ip_set_iptree *map = (struct ip_set_iptree *) set->data; -+ struct ip_set_iptreeb *btree; -+ struct ip_set_iptreec *ctree; -+ struct ip_set_iptreed *dtree; -+ unsigned int a,b,c,d; -+ size_t offset = 0; -+ struct ip_set_req_iptree *entry; -+ -+ LOOP_WALK_BEGIN(map, a, btree); -+ LOOP_WALK_BEGIN(btree, b, ctree); -+ LOOP_WALK_BEGIN(ctree, c, dtree); -+ for (d = 0; d < 256; d++) { -+ if (dtree->expires[d] -+ && (!map->timeout || time_after(dtree->expires[d], jiffies))) { -+ entry = (struct ip_set_req_iptree *)(data + offset); -+ entry->ip = ((a << 24) | (b << 16) | (c << 8) | d); -+ entry->timeout = !map->timeout ? 0 -+ : (dtree->expires[d] - jiffies)/HZ; -+ offset += sizeof(struct ip_set_req_iptree); -+ } -+ } -+ LOOP_WALK_END; -+ LOOP_WALK_END; -+ LOOP_WALK_END; -+} -+ -+static struct ip_set_type ip_set_iptree = { -+ .typename = SETTYPE_NAME, -+ .features = IPSET_TYPE_IP | IPSET_DATA_SINGLE, -+ .protocol_version = IP_SET_PROTOCOL_VERSION, -+ .create = &create, -+ .destroy = &destroy, -+ .flush = &flush, -+ .reqsize = sizeof(struct ip_set_req_iptree), -+ .addip = &addip, -+ .addip_kernel = &addip_kernel, -+ .delip = &delip, -+ .delip_kernel = &delip_kernel, -+ .testip = &testip, -+ .testip_kernel = &testip_kernel, -+ .header_size = sizeof(struct ip_set_req_iptree_create), -+ .list_header = &list_header, -+ .list_members_size = &list_members_size, -+ .list_members = &list_members, -+ .me = THIS_MODULE, -+}; -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Jozsef Kadlecsik "); -+MODULE_DESCRIPTION("iptree type of IP sets"); -+module_param(limit, int, 0600); -+MODULE_PARM_DESC(limit, "maximal number of elements stored in the sets"); -+ -+static int __init ip_set_iptree_init(void) -+{ -+ int ret; -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) -+ branch_cachep = kmem_cache_create("ip_set_iptreeb", -+ sizeof(struct ip_set_iptreeb), -+ 0, 0, NULL); -+#else -+ branch_cachep = kmem_cache_create("ip_set_iptreeb", -+ sizeof(struct ip_set_iptreeb), -+ 0, 0, NULL, NULL); -+#endif -+ if (!branch_cachep) { -+ printk(KERN_ERR "Unable to create ip_set_iptreeb slab cache\n"); -+ ret = -ENOMEM; -+ goto out; -+ } -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) -+ leaf_cachep = kmem_cache_create("ip_set_iptreed", -+ sizeof(struct ip_set_iptreed), -+ 0, 0, NULL); -+#else -+ leaf_cachep = kmem_cache_create("ip_set_iptreed", -+ sizeof(struct ip_set_iptreed), -+ 0, 0, NULL, NULL); -+#endif -+ if (!leaf_cachep) { -+ printk(KERN_ERR "Unable to create ip_set_iptreed slab cache\n"); -+ ret = -ENOMEM; -+ goto free_branch; -+ } -+ ret = ip_set_register_set_type(&ip_set_iptree); -+ if (ret == 0) -+ goto out; -+ -+ kmem_cache_destroy(leaf_cachep); -+ free_branch: -+ kmem_cache_destroy(branch_cachep); -+ out: -+ return ret; -+} -+ -+static void __exit ip_set_iptree_fini(void) -+{ -+ /* FIXME: possible race with ip_set_create() */ -+ ip_set_unregister_set_type(&ip_set_iptree); -+ kmem_cache_destroy(leaf_cachep); -+ kmem_cache_destroy(branch_cachep); -+} -+ -+module_init(ip_set_iptree_init); -+module_exit(ip_set_iptree_fini); ---- /dev/null -+++ b/net/ipv4/netfilter/ip_set_iptreemap.c -@@ -0,0 +1,829 @@ -+/* Copyright (C) 2007 Sven Wegener -+ * -+ * 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. -+ */ -+ -+/* This modules implements the iptreemap ipset type. It uses bitmaps to -+ * represent every single IPv4 address as a single bit. The bitmaps are managed -+ * in a tree structure, where the first three octets of an addresses are used -+ * as an index to find the bitmap and the last octet is used as the bit number. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#define IPTREEMAP_DEFAULT_GC_TIME (5 * 60) -+#define IPTREEMAP_DESTROY_SLEEP (100) -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21) -+static struct kmem_cache *cachep_b; -+static struct kmem_cache *cachep_c; -+static struct kmem_cache *cachep_d; -+#else -+static kmem_cache_t *cachep_b; -+static kmem_cache_t *cachep_c; -+static kmem_cache_t *cachep_d; -+#endif -+ -+static struct ip_set_iptreemap_d *fullbitmap_d; -+static struct ip_set_iptreemap_c *fullbitmap_c; -+static struct ip_set_iptreemap_b *fullbitmap_b; -+ -+#if defined(__LITTLE_ENDIAN) -+#define ABCD(a, b, c, d, addr) \ -+ do { \ -+ a = ((unsigned char *)addr)[3]; \ -+ b = ((unsigned char *)addr)[2]; \ -+ c = ((unsigned char *)addr)[1]; \ -+ d = ((unsigned char *)addr)[0]; \ -+ } while (0) -+#elif defined(__BIG_ENDIAN) -+#define ABCD(a,b,c,d,addrp) do { \ -+ a = ((unsigned char *)addrp)[0]; \ -+ b = ((unsigned char *)addrp)[1]; \ -+ c = ((unsigned char *)addrp)[2]; \ -+ d = ((unsigned char *)addrp)[3]; \ -+} while (0) -+#else -+#error "Please fix asm/byteorder.h" -+#endif /* __LITTLE_ENDIAN */ -+ -+#define TESTIP_WALK(map, elem, branch, full) \ -+ do { \ -+ branch = (map)->tree[elem]; \ -+ if (!branch) \ -+ return 0; \ -+ else if (branch == full) \ -+ return 1; \ -+ } while (0) -+ -+#define ADDIP_WALK(map, elem, branch, type, cachep, full) \ -+ do { \ -+ branch = (map)->tree[elem]; \ -+ if (!branch) { \ -+ branch = (type *) kmem_cache_alloc(cachep, GFP_ATOMIC); \ -+ if (!branch) \ -+ return -ENOMEM; \ -+ memset(branch, 0, sizeof(*branch)); \ -+ (map)->tree[elem] = branch; \ -+ } else if (branch == full) { \ -+ return -EEXIST; \ -+ } \ -+ } while (0) -+ -+#define ADDIP_RANGE_LOOP(map, a, a1, a2, hint, branch, full, cachep, free) \ -+ for (a = a1; a <= a2; a++) { \ -+ branch = (map)->tree[a]; \ -+ if (branch != full) { \ -+ if ((a > a1 && a < a2) || (hint)) { \ -+ if (branch) \ -+ free(branch); \ -+ (map)->tree[a] = full; \ -+ continue; \ -+ } else if (!branch) { \ -+ branch = kmem_cache_alloc(cachep, GFP_ATOMIC); \ -+ if (!branch) \ -+ return -ENOMEM; \ -+ memset(branch, 0, sizeof(*branch)); \ -+ (map)->tree[a] = branch; \ -+ } -+ -+#define ADDIP_RANGE_LOOP_END() \ -+ } \ -+ } -+ -+#define DELIP_WALK(map, elem, branch, cachep, full, flags) \ -+ do { \ -+ branch = (map)->tree[elem]; \ -+ if (!branch) { \ -+ return -EEXIST; \ -+ } else if (branch == full) { \ -+ branch = kmem_cache_alloc(cachep, flags); \ -+ if (!branch) \ -+ return -ENOMEM; \ -+ memcpy(branch, full, sizeof(*full)); \ -+ (map)->tree[elem] = branch; \ -+ } \ -+ } while (0) -+ -+#define DELIP_RANGE_LOOP(map, a, a1, a2, hint, branch, full, cachep, free, flags) \ -+ for (a = a1; a <= a2; a++) { \ -+ branch = (map)->tree[a]; \ -+ if (branch) { \ -+ if ((a > a1 && a < a2) || (hint)) { \ -+ if (branch != full) \ -+ free(branch); \ -+ (map)->tree[a] = NULL; \ -+ continue; \ -+ } else if (branch == full) { \ -+ branch = kmem_cache_alloc(cachep, flags); \ -+ if (!branch) \ -+ return -ENOMEM; \ -+ memcpy(branch, full, sizeof(*branch)); \ -+ (map)->tree[a] = branch; \ -+ } -+ -+#define DELIP_RANGE_LOOP_END() \ -+ } \ -+ } -+ -+#define LOOP_WALK_BEGIN(map, i, branch) \ -+ for (i = 0; i < 256; i++) { \ -+ branch = (map)->tree[i]; \ -+ if (likely(!branch)) \ -+ continue; -+ -+#define LOOP_WALK_END() \ -+ } -+ -+#define LOOP_WALK_BEGIN_GC(map, i, branch, full, cachep, count) \ -+ count = -256; \ -+ for (i = 0; i < 256; i++) { \ -+ branch = (map)->tree[i]; \ -+ if (likely(!branch)) \ -+ continue; \ -+ count++; \ -+ if (branch == full) { \ -+ count++; \ -+ continue; \ -+ } -+ -+#define LOOP_WALK_END_GC(map, i, branch, full, cachep, count) \ -+ if (-256 == count) { \ -+ kmem_cache_free(cachep, branch); \ -+ (map)->tree[i] = NULL; \ -+ } else if (256 == count) { \ -+ kmem_cache_free(cachep, branch); \ -+ (map)->tree[i] = full; \ -+ } \ -+ } -+ -+#define LOOP_WALK_BEGIN_COUNT(map, i, branch, inrange, count) \ -+ for (i = 0; i < 256; i++) { \ -+ if (!(map)->tree[i]) { \ -+ if (inrange) { \ -+ count++; \ -+ inrange = 0; \ -+ } \ -+ continue; \ -+ } \ -+ branch = (map)->tree[i]; -+ -+#define LOOP_WALK_END_COUNT() \ -+ } -+ -+#define MIN(a, b) (a < b ? a : b) -+#define MAX(a, b) (a > b ? a : b) -+ -+#define GETVALUE1(a, a1, b1, r) \ -+ (a == a1 ? b1 : r) -+ -+#define GETVALUE2(a, b, a1, b1, c1, r) \ -+ (a == a1 && b == b1 ? c1 : r) -+ -+#define GETVALUE3(a, b, c, a1, b1, c1, d1, r) \ -+ (a == a1 && b == b1 && c == c1 ? d1 : r) -+ -+#define CHECK1(a, a1, a2, b1, b2, c1, c2, d1, d2) \ -+ ( \ -+ GETVALUE1(a, a1, b1, 0) == 0 \ -+ && GETVALUE1(a, a2, b2, 255) == 255 \ -+ && c1 == 0 \ -+ && c2 == 255 \ -+ && d1 == 0 \ -+ && d2 == 255 \ -+ ) -+ -+#define CHECK2(a, b, a1, a2, b1, b2, c1, c2, d1, d2) \ -+ ( \ -+ GETVALUE2(a, b, a1, b1, c1, 0) == 0 \ -+ && GETVALUE2(a, b, a2, b2, c2, 255) == 255 \ -+ && d1 == 0 \ -+ && d2 == 255 \ -+ ) -+ -+#define CHECK3(a, b, c, a1, a2, b1, b2, c1, c2, d1, d2) \ -+ ( \ -+ GETVALUE3(a, b, c, a1, b1, c1, d1, 0) == 0 \ -+ && GETVALUE3(a, b, c, a2, b2, c2, d2, 255) == 255 \ -+ ) -+ -+ -+static inline void -+free_d(struct ip_set_iptreemap_d *map) -+{ -+ kmem_cache_free(cachep_d, map); -+} -+ -+static inline void -+free_c(struct ip_set_iptreemap_c *map) -+{ -+ struct ip_set_iptreemap_d *dtree; -+ unsigned int i; -+ -+ LOOP_WALK_BEGIN(map, i, dtree) { -+ if (dtree != fullbitmap_d) -+ free_d(dtree); -+ } LOOP_WALK_END(); -+ -+ kmem_cache_free(cachep_c, map); -+} -+ -+static inline void -+free_b(struct ip_set_iptreemap_b *map) -+{ -+ struct ip_set_iptreemap_c *ctree; -+ unsigned int i; -+ -+ LOOP_WALK_BEGIN(map, i, ctree) { -+ if (ctree != fullbitmap_c) -+ free_c(ctree); -+ } LOOP_WALK_END(); -+ -+ kmem_cache_free(cachep_b, map); -+} -+ -+static inline int -+__testip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip) -+{ -+ struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data; -+ struct ip_set_iptreemap_b *btree; -+ struct ip_set_iptreemap_c *ctree; -+ struct ip_set_iptreemap_d *dtree; -+ unsigned char a, b, c, d; -+ -+ *hash_ip = ip; -+ -+ ABCD(a, b, c, d, hash_ip); -+ -+ TESTIP_WALK(map, a, btree, fullbitmap_b); -+ TESTIP_WALK(btree, b, ctree, fullbitmap_c); -+ TESTIP_WALK(ctree, c, dtree, fullbitmap_d); -+ -+ return !!test_bit(d, (void *) dtree->bitmap); -+} -+ -+static int -+testip(struct ip_set *set, const void *data, size_t size, ip_set_ip_t *hash_ip) -+{ -+ struct ip_set_req_iptreemap *req = (struct ip_set_req_iptreemap *) data; -+ -+ if (size != sizeof(struct ip_set_req_iptreemap)) { -+ ip_set_printk("data length wrong (want %zu, have %zu)", sizeof(struct ip_set_req_iptreemap), size); -+ return -EINVAL; -+ } -+ -+ return __testip(set, req->start, hash_ip); -+} -+ -+static int -+testip_kernel(struct ip_set *set, const struct sk_buff *skb, ip_set_ip_t *hash_ip, const u_int32_t *flags, unsigned char index) -+{ -+ int res; -+ -+ res = __testip(set, -+ ntohl(flags[index] & IPSET_SRC -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) -+ ? ip_hdr(skb)->saddr -+ : ip_hdr(skb)->daddr), -+#else -+ ? skb->nh.iph->saddr -+ : skb->nh.iph->daddr), -+#endif -+ hash_ip); -+ -+ return (res < 0 ? 0 : res); -+} -+ -+static inline int -+__addip_single(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip) -+{ -+ struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data; -+ struct ip_set_iptreemap_b *btree; -+ struct ip_set_iptreemap_c *ctree; -+ struct ip_set_iptreemap_d *dtree; -+ unsigned char a, b, c, d; -+ -+ *hash_ip = ip; -+ -+ ABCD(a, b, c, d, hash_ip); -+ -+ ADDIP_WALK(map, a, btree, struct ip_set_iptreemap_b, cachep_b, fullbitmap_b); -+ ADDIP_WALK(btree, b, ctree, struct ip_set_iptreemap_c, cachep_c, fullbitmap_c); -+ ADDIP_WALK(ctree, c, dtree, struct ip_set_iptreemap_d, cachep_d, fullbitmap_d); -+ -+ if (test_and_set_bit(d, (void *) dtree->bitmap)) -+ return -EEXIST; -+ -+ set_bit(b, (void *) btree->dirty); -+ -+ return 0; -+} -+ -+static inline int -+__addip_range(struct ip_set *set, ip_set_ip_t start, ip_set_ip_t end, ip_set_ip_t *hash_ip) -+{ -+ struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data; -+ struct ip_set_iptreemap_b *btree; -+ struct ip_set_iptreemap_c *ctree; -+ struct ip_set_iptreemap_d *dtree; -+ unsigned int a, b, c, d; -+ unsigned char a1, b1, c1, d1; -+ unsigned char a2, b2, c2, d2; -+ -+ if (start == end) -+ return __addip_single(set, start, hash_ip); -+ -+ *hash_ip = start; -+ -+ ABCD(a1, b1, c1, d1, &start); -+ ABCD(a2, b2, c2, d2, &end); -+ -+ /* This is sooo ugly... */ -+ ADDIP_RANGE_LOOP(map, a, a1, a2, CHECK1(a, a1, a2, b1, b2, c1, c2, d1, d2), btree, fullbitmap_b, cachep_b, free_b) { -+ ADDIP_RANGE_LOOP(btree, b, GETVALUE1(a, a1, b1, 0), GETVALUE1(a, a2, b2, 255), CHECK2(a, b, a1, a2, b1, b2, c1, c2, d1, d2), ctree, fullbitmap_c, cachep_c, free_c) { -+ ADDIP_RANGE_LOOP(ctree, c, GETVALUE2(a, b, a1, b1, c1, 0), GETVALUE2(a, b, a2, b2, c2, 255), CHECK3(a, b, c, a1, a2, b1, b2, c1, c2, d1, d2), dtree, fullbitmap_d, cachep_d, free_d) { -+ for (d = GETVALUE3(a, b, c, a1, b1, c1, d1, 0); d <= GETVALUE3(a, b, c, a2, b2, c2, d2, 255); d++) -+ set_bit(d, (void *) dtree->bitmap); -+ set_bit(b, (void *) btree->dirty); -+ } ADDIP_RANGE_LOOP_END(); -+ } ADDIP_RANGE_LOOP_END(); -+ } ADDIP_RANGE_LOOP_END(); -+ -+ return 0; -+} -+ -+static int -+addip(struct ip_set *set, const void *data, size_t size, ip_set_ip_t *hash_ip) -+{ -+ struct ip_set_req_iptreemap *req = (struct ip_set_req_iptreemap *) data; -+ -+ if (size != sizeof(struct ip_set_req_iptreemap)) { -+ ip_set_printk("data length wrong (want %zu, have %zu)", sizeof(struct ip_set_req_iptreemap), size); -+ return -EINVAL; -+ } -+ -+ return __addip_range(set, MIN(req->start, req->end), MAX(req->start, req->end), hash_ip); -+} -+ -+static int -+addip_kernel(struct ip_set *set, const struct sk_buff *skb, ip_set_ip_t *hash_ip, const u_int32_t *flags, unsigned char index) -+{ -+ -+ return __addip_single(set, -+ ntohl(flags[index] & IPSET_SRC -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) -+ ? ip_hdr(skb)->saddr -+ : ip_hdr(skb)->daddr), -+#else -+ ? skb->nh.iph->saddr -+ : skb->nh.iph->daddr), -+#endif -+ hash_ip); -+} -+ -+static inline int -+__delip_single(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip, unsigned int __nocast flags) -+{ -+ struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data; -+ struct ip_set_iptreemap_b *btree; -+ struct ip_set_iptreemap_c *ctree; -+ struct ip_set_iptreemap_d *dtree; -+ unsigned char a,b,c,d; -+ -+ *hash_ip = ip; -+ -+ ABCD(a, b, c, d, hash_ip); -+ -+ DELIP_WALK(map, a, btree, cachep_b, fullbitmap_b, flags); -+ DELIP_WALK(btree, b, ctree, cachep_c, fullbitmap_c, flags); -+ DELIP_WALK(ctree, c, dtree, cachep_d, fullbitmap_d, flags); -+ -+ if (!test_and_clear_bit(d, (void *) dtree->bitmap)) -+ return -EEXIST; -+ -+ set_bit(b, (void *) btree->dirty); -+ -+ return 0; -+} -+ -+static inline int -+__delip_range(struct ip_set *set, ip_set_ip_t start, ip_set_ip_t end, ip_set_ip_t *hash_ip, unsigned int __nocast flags) -+{ -+ struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data; -+ struct ip_set_iptreemap_b *btree; -+ struct ip_set_iptreemap_c *ctree; -+ struct ip_set_iptreemap_d *dtree; -+ unsigned int a, b, c, d; -+ unsigned char a1, b1, c1, d1; -+ unsigned char a2, b2, c2, d2; -+ -+ if (start == end) -+ return __delip_single(set, start, hash_ip, flags); -+ -+ *hash_ip = start; -+ -+ ABCD(a1, b1, c1, d1, &start); -+ ABCD(a2, b2, c2, d2, &end); -+ -+ /* This is sooo ugly... */ -+ DELIP_RANGE_LOOP(map, a, a1, a2, CHECK1(a, a1, a2, b1, b2, c1, c2, d1, d2), btree, fullbitmap_b, cachep_b, free_b, flags) { -+ DELIP_RANGE_LOOP(btree, b, GETVALUE1(a, a1, b1, 0), GETVALUE1(a, a2, b2, 255), CHECK2(a, b, a1, a2, b1, b2, c1, c2, d1, d2), ctree, fullbitmap_c, cachep_c, free_c, flags) { -+ DELIP_RANGE_LOOP(ctree, c, GETVALUE2(a, b, a1, b1, c1, 0), GETVALUE2(a, b, a2, b2, c2, 255), CHECK3(a, b, c, a1, a2, b1, b2, c1, c2, d1, d2), dtree, fullbitmap_d, cachep_d, free_d, flags) { -+ for (d = GETVALUE3(a, b, c, a1, b1, c1, d1, 0); d <= GETVALUE3(a, b, c, a2, b2, c2, d2, 255); d++) -+ clear_bit(d, (void *) dtree->bitmap); -+ set_bit(b, (void *) btree->dirty); -+ } DELIP_RANGE_LOOP_END(); -+ } DELIP_RANGE_LOOP_END(); -+ } DELIP_RANGE_LOOP_END(); -+ -+ return 0; -+} -+ -+static int -+delip(struct ip_set *set, const void *data, size_t size, ip_set_ip_t *hash_ip) -+{ -+ struct ip_set_req_iptreemap *req = (struct ip_set_req_iptreemap *) data; -+ -+ if (size != sizeof(struct ip_set_req_iptreemap)) { -+ ip_set_printk("data length wrong (want %zu, have %zu)", sizeof(struct ip_set_req_iptreemap), size); -+ return -EINVAL; -+ } -+ -+ return __delip_range(set, MIN(req->start, req->end), MAX(req->start, req->end), hash_ip, GFP_KERNEL); -+} -+ -+static int -+delip_kernel(struct ip_set *set, const struct sk_buff *skb, ip_set_ip_t *hash_ip, const u_int32_t *flags, unsigned char index) -+{ -+ return __delip_single(set, -+ ntohl(flags[index] & IPSET_SRC -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) -+ ? ip_hdr(skb)->saddr -+ : ip_hdr(skb)->daddr), -+#else -+ ? skb->nh.iph->saddr -+ : skb->nh.iph->daddr), -+#endif -+ hash_ip, -+ GFP_ATOMIC); -+} -+ -+/* Check the status of the bitmap -+ * -1 == all bits cleared -+ * 1 == all bits set -+ * 0 == anything else -+ */ -+static inline int -+bitmap_status(struct ip_set_iptreemap_d *dtree) -+{ -+ unsigned char first = dtree->bitmap[0]; -+ int a; -+ -+ for (a = 1; a < 32; a++) -+ if (dtree->bitmap[a] != first) -+ return 0; -+ -+ return (first == 0 ? -1 : (first == 255 ? 1 : 0)); -+} -+ -+static void -+gc(unsigned long addr) -+{ -+ struct ip_set *set = (struct ip_set *) addr; -+ struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data; -+ struct ip_set_iptreemap_b *btree; -+ struct ip_set_iptreemap_c *ctree; -+ struct ip_set_iptreemap_d *dtree; -+ unsigned int a, b, c; -+ int i, j, k; -+ -+ write_lock_bh(&set->lock); -+ -+ LOOP_WALK_BEGIN_GC(map, a, btree, fullbitmap_b, cachep_b, i) { -+ LOOP_WALK_BEGIN_GC(btree, b, ctree, fullbitmap_c, cachep_c, j) { -+ if (!test_and_clear_bit(b, (void *) btree->dirty)) -+ continue; -+ LOOP_WALK_BEGIN_GC(ctree, c, dtree, fullbitmap_d, cachep_d, k) { -+ switch (bitmap_status(dtree)) { -+ case -1: -+ kmem_cache_free(cachep_d, dtree); -+ ctree->tree[c] = NULL; -+ k--; -+ break; -+ case 1: -+ kmem_cache_free(cachep_d, dtree); -+ ctree->tree[c] = fullbitmap_d; -+ k++; -+ break; -+ } -+ } LOOP_WALK_END(); -+ } LOOP_WALK_END_GC(btree, b, ctree, fullbitmap_c, cachep_c, k); -+ } LOOP_WALK_END_GC(map, a, btree, fullbitmap_b, cachep_b, j); -+ -+ write_unlock_bh(&set->lock); -+ -+ map->gc.expires = jiffies + map->gc_interval * HZ; -+ add_timer(&map->gc); -+} -+ -+static inline void -+init_gc_timer(struct ip_set *set) -+{ -+ struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data; -+ -+ init_timer(&map->gc); -+ map->gc.data = (unsigned long) set; -+ map->gc.function = gc; -+ map->gc.expires = jiffies + map->gc_interval * HZ; -+ add_timer(&map->gc); -+} -+ -+static int create(struct ip_set *set, const void *data, size_t size) -+{ -+ struct ip_set_req_iptreemap_create *req = (struct ip_set_req_iptreemap_create *) data; -+ struct ip_set_iptreemap *map; -+ -+ if (size != sizeof(struct ip_set_req_iptreemap_create)) { -+ ip_set_printk("data length wrong (want %zu, have %zu)", sizeof(struct ip_set_req_iptreemap_create), size); -+ return -EINVAL; -+ } -+ -+ map = kzalloc(sizeof(*map), GFP_KERNEL); -+ if (!map) -+ return -ENOMEM; -+ -+ map->gc_interval = req->gc_interval ? req->gc_interval : IPTREEMAP_DEFAULT_GC_TIME; -+ set->data = map; -+ -+ init_gc_timer(set); -+ -+ return 0; -+} -+ -+static inline void __flush(struct ip_set_iptreemap *map) -+{ -+ struct ip_set_iptreemap_b *btree; -+ unsigned int a; -+ -+ LOOP_WALK_BEGIN(map, a, btree); -+ if (btree != fullbitmap_b) -+ free_b(btree); -+ LOOP_WALK_END(); -+} -+ -+static void destroy(struct ip_set *set) -+{ -+ struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data; -+ -+ while (!del_timer(&map->gc)) -+ msleep(IPTREEMAP_DESTROY_SLEEP); -+ -+ __flush(map); -+ kfree(map); -+ -+ set->data = NULL; -+} -+ -+static void flush(struct ip_set *set) -+{ -+ struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data; -+ -+ while (!del_timer(&map->gc)) -+ msleep(IPTREEMAP_DESTROY_SLEEP); -+ -+ __flush(map); -+ -+ memset(map, 0, sizeof(*map)); -+ -+ init_gc_timer(set); -+} -+ -+static void list_header(const struct ip_set *set, void *data) -+{ -+ struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data; -+ struct ip_set_req_iptreemap_create *header = (struct ip_set_req_iptreemap_create *) data; -+ -+ header->gc_interval = map->gc_interval; -+} -+ -+static int list_members_size(const struct ip_set *set) -+{ -+ struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data; -+ struct ip_set_iptreemap_b *btree; -+ struct ip_set_iptreemap_c *ctree; -+ struct ip_set_iptreemap_d *dtree; -+ unsigned int a, b, c, d, inrange = 0, count = 0; -+ -+ LOOP_WALK_BEGIN_COUNT(map, a, btree, inrange, count) { -+ LOOP_WALK_BEGIN_COUNT(btree, b, ctree, inrange, count) { -+ LOOP_WALK_BEGIN_COUNT(ctree, c, dtree, inrange, count) { -+ for (d = 0; d < 256; d++) { -+ if (test_bit(d, (void *) dtree->bitmap)) { -+ inrange = 1; -+ } else if (inrange) { -+ count++; -+ inrange = 0; -+ } -+ } -+ } LOOP_WALK_END_COUNT(); -+ } LOOP_WALK_END_COUNT(); -+ } LOOP_WALK_END_COUNT(); -+ -+ if (inrange) -+ count++; -+ -+ return (count * sizeof(struct ip_set_req_iptreemap)); -+} -+ -+static inline size_t add_member(void *data, size_t offset, ip_set_ip_t start, ip_set_ip_t end) -+{ -+ struct ip_set_req_iptreemap *entry = (struct ip_set_req_iptreemap *) (data + offset); -+ -+ entry->start = start; -+ entry->end = end; -+ -+ return sizeof(*entry); -+} -+ -+static void list_members(const struct ip_set *set, void *data) -+{ -+ struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data; -+ struct ip_set_iptreemap_b *btree; -+ struct ip_set_iptreemap_c *ctree; -+ struct ip_set_iptreemap_d *dtree; -+ unsigned int a, b, c, d, inrange = 0; -+ size_t offset = 0; -+ ip_set_ip_t start = 0, end = 0, ip; -+ -+ LOOP_WALK_BEGIN(map, a, btree) { -+ LOOP_WALK_BEGIN(btree, b, ctree) { -+ LOOP_WALK_BEGIN(ctree, c, dtree) { -+ for (d = 0; d < 256; d++) { -+ if (test_bit(d, (void *) dtree->bitmap)) { -+ ip = ((a << 24) | (b << 16) | (c << 8) | d); -+ if (!inrange) { -+ inrange = 1; -+ start = ip; -+ } else if (end < ip - 1) { -+ offset += add_member(data, offset, start, end); -+ start = ip; -+ } -+ end = ip; -+ } else if (inrange) { -+ offset += add_member(data, offset, start, end); -+ inrange = 0; -+ } -+ } -+ } LOOP_WALK_END(); -+ } LOOP_WALK_END(); -+ } LOOP_WALK_END(); -+ -+ if (inrange) -+ add_member(data, offset, start, end); -+} -+ -+static struct ip_set_type ip_set_iptreemap = { -+ .typename = SETTYPE_NAME, -+ .features = IPSET_TYPE_IP | IPSET_DATA_SINGLE, -+ .protocol_version = IP_SET_PROTOCOL_VERSION, -+ .create = create, -+ .destroy = destroy, -+ .flush = flush, -+ .reqsize = sizeof(struct ip_set_req_iptreemap), -+ .addip = addip, -+ .addip_kernel = addip_kernel, -+ .delip = delip, -+ .delip_kernel = delip_kernel, -+ .testip = testip, -+ .testip_kernel = testip_kernel, -+ .header_size = sizeof(struct ip_set_req_iptreemap_create), -+ .list_header = list_header, -+ .list_members_size = list_members_size, -+ .list_members = list_members, -+ .me = THIS_MODULE, -+}; -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Sven Wegener "); -+MODULE_DESCRIPTION("iptreemap type of IP sets"); -+ -+static int __init ip_set_iptreemap_init(void) -+{ -+ int ret = -ENOMEM; -+ int a; -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) -+ cachep_b = kmem_cache_create("ip_set_iptreemap_b", -+ sizeof(struct ip_set_iptreemap_b), -+ 0, 0, NULL); -+#else -+ cachep_b = kmem_cache_create("ip_set_iptreemap_b", -+ sizeof(struct ip_set_iptreemap_b), -+ 0, 0, NULL, NULL); -+#endif -+ if (!cachep_b) { -+ ip_set_printk("Unable to create ip_set_iptreemap_b slab cache"); -+ goto out; -+ } -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) -+ cachep_c = kmem_cache_create("ip_set_iptreemap_c", -+ sizeof(struct ip_set_iptreemap_c), -+ 0, 0, NULL); -+#else -+ cachep_c = kmem_cache_create("ip_set_iptreemap_c", -+ sizeof(struct ip_set_iptreemap_c), -+ 0, 0, NULL, NULL); -+#endif -+ if (!cachep_c) { -+ ip_set_printk("Unable to create ip_set_iptreemap_c slab cache"); -+ goto outb; -+ } -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) -+ cachep_d = kmem_cache_create("ip_set_iptreemap_d", -+ sizeof(struct ip_set_iptreemap_d), -+ 0, 0, NULL); -+#else -+ cachep_d = kmem_cache_create("ip_set_iptreemap_d", -+ sizeof(struct ip_set_iptreemap_d), -+ 0, 0, NULL, NULL); -+#endif -+ if (!cachep_d) { -+ ip_set_printk("Unable to create ip_set_iptreemap_d slab cache"); -+ goto outc; -+ } -+ -+ fullbitmap_d = kmem_cache_alloc(cachep_d, GFP_KERNEL); -+ if (!fullbitmap_d) -+ goto outd; -+ -+ fullbitmap_c = kmem_cache_alloc(cachep_c, GFP_KERNEL); -+ if (!fullbitmap_c) -+ goto outbitmapd; -+ -+ fullbitmap_b = kmem_cache_alloc(cachep_b, GFP_KERNEL); -+ if (!fullbitmap_b) -+ goto outbitmapc; -+ -+ ret = ip_set_register_set_type(&ip_set_iptreemap); -+ if (0 > ret) -+ goto outbitmapb; -+ -+ /* Now init our global bitmaps */ -+ memset(fullbitmap_d->bitmap, 0xff, sizeof(fullbitmap_d->bitmap)); -+ -+ for (a = 0; a < 256; a++) -+ fullbitmap_c->tree[a] = fullbitmap_d; -+ -+ for (a = 0; a < 256; a++) -+ fullbitmap_b->tree[a] = fullbitmap_c; -+ memset(fullbitmap_b->dirty, 0, sizeof(fullbitmap_b->dirty)); -+ -+ return 0; -+ -+outbitmapb: -+ kmem_cache_free(cachep_b, fullbitmap_b); -+outbitmapc: -+ kmem_cache_free(cachep_c, fullbitmap_c); -+outbitmapd: -+ kmem_cache_free(cachep_d, fullbitmap_d); -+outd: -+ kmem_cache_destroy(cachep_d); -+outc: -+ kmem_cache_destroy(cachep_c); -+outb: -+ kmem_cache_destroy(cachep_b); -+out: -+ -+ return ret; -+} -+ -+static void __exit ip_set_iptreemap_fini(void) -+{ -+ ip_set_unregister_set_type(&ip_set_iptreemap); -+ kmem_cache_free(cachep_d, fullbitmap_d); -+ kmem_cache_free(cachep_c, fullbitmap_c); -+ kmem_cache_free(cachep_b, fullbitmap_b); -+ kmem_cache_destroy(cachep_d); -+ kmem_cache_destroy(cachep_c); -+ kmem_cache_destroy(cachep_b); -+} -+ -+module_init(ip_set_iptreemap_init); -+module_exit(ip_set_iptreemap_fini); ---- /dev/null -+++ b/net/ipv4/netfilter/ip_set_macipmap.c -@@ -0,0 +1,375 @@ -+/* Copyright (C) 2000-2002 Joakim Axelsson -+ * Patrick Schaaf -+ * Martin Josefsson -+ * Copyright (C) 2003-2004 Jozsef Kadlecsik -+ * -+ * 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. -+ */ -+ -+/* Kernel module implementing an IP set type: the macipmap type */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+static int -+testip(struct ip_set *set, const void *data, size_t size, ip_set_ip_t *hash_ip) -+{ -+ struct ip_set_macipmap *map = (struct ip_set_macipmap *) set->data; -+ struct ip_set_macip *table = (struct ip_set_macip *) map->members; -+ struct ip_set_req_macipmap *req = (struct ip_set_req_macipmap *) data; -+ -+ if (size != sizeof(struct ip_set_req_macipmap)) { -+ ip_set_printk("data length wrong (want %zu, have %zu)", -+ sizeof(struct ip_set_req_macipmap), -+ size); -+ return -EINVAL; -+ } -+ -+ if (req->ip < map->first_ip || req->ip > map->last_ip) -+ return -ERANGE; -+ -+ *hash_ip = req->ip; -+ DP("set: %s, ip:%u.%u.%u.%u, %u.%u.%u.%u", -+ set->name, HIPQUAD(req->ip), HIPQUAD(*hash_ip)); -+ if (test_bit(IPSET_MACIP_ISSET, -+ (void *) &table[req->ip - map->first_ip].flags)) { -+ return (memcmp(req->ethernet, -+ &table[req->ip - map->first_ip].ethernet, -+ ETH_ALEN) == 0); -+ } else { -+ return (map->flags & IPSET_MACIP_MATCHUNSET ? 1 : 0); -+ } -+} -+ -+static int -+testip_kernel(struct ip_set *set, -+ const struct sk_buff *skb, -+ ip_set_ip_t *hash_ip, -+ const u_int32_t *flags, -+ unsigned char index) -+{ -+ struct ip_set_macipmap *map = -+ (struct ip_set_macipmap *) set->data; -+ struct ip_set_macip *table = -+ (struct ip_set_macip *) map->members; -+ ip_set_ip_t ip; -+ -+ ip = ntohl(flags[index] & IPSET_SRC -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) -+ ? ip_hdr(skb)->saddr -+ : ip_hdr(skb)->daddr); -+#else -+ ? skb->nh.iph->saddr -+ : skb->nh.iph->daddr); -+#endif -+ -+ if (ip < map->first_ip || ip > map->last_ip) -+ return 0; -+ -+ *hash_ip = ip; -+ DP("set: %s, ip:%u.%u.%u.%u, %u.%u.%u.%u", -+ set->name, HIPQUAD(ip), HIPQUAD(*hash_ip)); -+ if (test_bit(IPSET_MACIP_ISSET, -+ (void *) &table[ip - map->first_ip].flags)) { -+ /* Is mac pointer valid? -+ * If so, compare... */ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) -+ return (skb_mac_header(skb) >= skb->head -+ && (skb_mac_header(skb) + ETH_HLEN) <= skb->data -+#else -+ return (skb->mac.raw >= skb->head -+ && (skb->mac.raw + ETH_HLEN) <= skb->data -+#endif -+ && (memcmp(eth_hdr(skb)->h_source, -+ &table[ip - map->first_ip].ethernet, -+ ETH_ALEN) == 0)); -+ } else { -+ return (map->flags & IPSET_MACIP_MATCHUNSET ? 1 : 0); -+ } -+} -+ -+/* returns 0 on success */ -+static inline int -+__addip(struct ip_set *set, -+ ip_set_ip_t ip, unsigned char *ethernet, ip_set_ip_t *hash_ip) -+{ -+ struct ip_set_macipmap *map = -+ (struct ip_set_macipmap *) set->data; -+ struct ip_set_macip *table = -+ (struct ip_set_macip *) map->members; -+ -+ if (ip < map->first_ip || ip > map->last_ip) -+ return -ERANGE; -+ if (test_and_set_bit(IPSET_MACIP_ISSET, -+ (void *) &table[ip - map->first_ip].flags)) -+ return -EEXIST; -+ -+ *hash_ip = ip; -+ DP("%u.%u.%u.%u, %u.%u.%u.%u", HIPQUAD(ip), HIPQUAD(*hash_ip)); -+ memcpy(&table[ip - map->first_ip].ethernet, ethernet, ETH_ALEN); -+ return 0; -+} -+ -+static int -+addip(struct ip_set *set, const void *data, size_t size, -+ ip_set_ip_t *hash_ip) -+{ -+ struct ip_set_req_macipmap *req = -+ (struct ip_set_req_macipmap *) data; -+ -+ if (size != sizeof(struct ip_set_req_macipmap)) { -+ ip_set_printk("data length wrong (want %zu, have %zu)", -+ sizeof(struct ip_set_req_macipmap), -+ size); -+ return -EINVAL; -+ } -+ return __addip(set, req->ip, req->ethernet, hash_ip); -+} -+ -+static int -+addip_kernel(struct ip_set *set, -+ const struct sk_buff *skb, -+ ip_set_ip_t *hash_ip, -+ const u_int32_t *flags, -+ unsigned char index) -+{ -+ ip_set_ip_t ip; -+ -+ ip = ntohl(flags[index] & IPSET_SRC -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) -+ ? ip_hdr(skb)->saddr -+ : ip_hdr(skb)->daddr); -+#else -+ ? skb->nh.iph->saddr -+ : skb->nh.iph->daddr); -+#endif -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) -+ if (!(skb_mac_header(skb) >= skb->head -+ && (skb_mac_header(skb) + ETH_HLEN) <= skb->data)) -+#else -+ if (!(skb->mac.raw >= skb->head -+ && (skb->mac.raw + ETH_HLEN) <= skb->data)) -+#endif -+ return -EINVAL; -+ -+ return __addip(set, ip, eth_hdr(skb)->h_source, hash_ip); -+} -+ -+static inline int -+__delip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip) -+{ -+ struct ip_set_macipmap *map = -+ (struct ip_set_macipmap *) set->data; -+ struct ip_set_macip *table = -+ (struct ip_set_macip *) map->members; -+ -+ if (ip < map->first_ip || ip > map->last_ip) -+ return -ERANGE; -+ if (!test_and_clear_bit(IPSET_MACIP_ISSET, -+ (void *)&table[ip - map->first_ip].flags)) -+ return -EEXIST; -+ -+ *hash_ip = ip; -+ DP("%u.%u.%u.%u, %u.%u.%u.%u", HIPQUAD(ip), HIPQUAD(*hash_ip)); -+ return 0; -+} -+ -+static int -+delip(struct ip_set *set, const void *data, size_t size, -+ ip_set_ip_t *hash_ip) -+{ -+ struct ip_set_req_macipmap *req = -+ (struct ip_set_req_macipmap *) data; -+ -+ if (size != sizeof(struct ip_set_req_macipmap)) { -+ ip_set_printk("data length wrong (want %zu, have %zu)", -+ sizeof(struct ip_set_req_macipmap), -+ size); -+ return -EINVAL; -+ } -+ return __delip(set, req->ip, hash_ip); -+} -+ -+static int -+delip_kernel(struct ip_set *set, -+ const struct sk_buff *skb, -+ ip_set_ip_t *hash_ip, -+ const u_int32_t *flags, -+ unsigned char index) -+{ -+ return __delip(set, -+ ntohl(flags[index] & IPSET_SRC -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) -+ ? ip_hdr(skb)->saddr -+ : ip_hdr(skb)->daddr), -+#else -+ ? skb->nh.iph->saddr -+ : skb->nh.iph->daddr), -+#endif -+ hash_ip); -+} -+ -+static inline size_t members_size(ip_set_id_t from, ip_set_id_t to) -+{ -+ return (size_t)((to - from + 1) * sizeof(struct ip_set_macip)); -+} -+ -+static int create(struct ip_set *set, const void *data, size_t size) -+{ -+ int newbytes; -+ struct ip_set_req_macipmap_create *req = -+ (struct ip_set_req_macipmap_create *) data; -+ struct ip_set_macipmap *map; -+ -+ if (size != sizeof(struct ip_set_req_macipmap_create)) { -+ ip_set_printk("data length wrong (want %zu, have %zu)", -+ sizeof(struct ip_set_req_macipmap_create), -+ size); -+ return -EINVAL; -+ } -+ -+ DP("from %u.%u.%u.%u to %u.%u.%u.%u", -+ HIPQUAD(req->from), HIPQUAD(req->to)); -+ -+ if (req->from > req->to) { -+ DP("bad ip range"); -+ return -ENOEXEC; -+ } -+ -+ if (req->to - req->from > MAX_RANGE) { -+ ip_set_printk("range too big (max %d addresses)", -+ MAX_RANGE+1); -+ return -ENOEXEC; -+ } -+ -+ map = kmalloc(sizeof(struct ip_set_macipmap), GFP_KERNEL); -+ if (!map) { -+ DP("out of memory for %d bytes", -+ sizeof(struct ip_set_macipmap)); -+ return -ENOMEM; -+ } -+ map->flags = req->flags; -+ map->first_ip = req->from; -+ map->last_ip = req->to; -+ newbytes = members_size(map->first_ip, map->last_ip); -+ map->members = ip_set_malloc(newbytes); -+ DP("members: %u %p", newbytes, map->members); -+ if (!map->members) { -+ DP("out of memory for %d bytes", newbytes); -+ kfree(map); -+ return -ENOMEM; -+ } -+ memset(map->members, 0, newbytes); -+ -+ set->data = map; -+ return 0; -+} -+ -+static void destroy(struct ip_set *set) -+{ -+ struct ip_set_macipmap *map = -+ (struct ip_set_macipmap *) set->data; -+ -+ ip_set_free(map->members, members_size(map->first_ip, map->last_ip)); -+ kfree(map); -+ -+ set->data = NULL; -+} -+ -+static void flush(struct ip_set *set) -+{ -+ struct ip_set_macipmap *map = -+ (struct ip_set_macipmap *) set->data; -+ memset(map->members, 0, members_size(map->first_ip, map->last_ip)); -+} -+ -+static void list_header(const struct ip_set *set, void *data) -+{ -+ struct ip_set_macipmap *map = -+ (struct ip_set_macipmap *) set->data; -+ struct ip_set_req_macipmap_create *header = -+ (struct ip_set_req_macipmap_create *) data; -+ -+ DP("list_header %x %x %u", map->first_ip, map->last_ip, -+ map->flags); -+ -+ header->from = map->first_ip; -+ header->to = map->last_ip; -+ header->flags = map->flags; -+} -+ -+static int list_members_size(const struct ip_set *set) -+{ -+ struct ip_set_macipmap *map = -+ (struct ip_set_macipmap *) set->data; -+ -+ DP("%u", members_size(map->first_ip, map->last_ip)); -+ return members_size(map->first_ip, map->last_ip); -+} -+ -+static void list_members(const struct ip_set *set, void *data) -+{ -+ struct ip_set_macipmap *map = -+ (struct ip_set_macipmap *) set->data; -+ -+ int bytes = members_size(map->first_ip, map->last_ip); -+ -+ DP("members: %u %p", bytes, map->members); -+ memcpy(data, map->members, bytes); -+} -+ -+static struct ip_set_type ip_set_macipmap = { -+ .typename = SETTYPE_NAME, -+ .features = IPSET_TYPE_IP | IPSET_DATA_SINGLE, -+ .protocol_version = IP_SET_PROTOCOL_VERSION, -+ .create = &create, -+ .destroy = &destroy, -+ .flush = &flush, -+ .reqsize = sizeof(struct ip_set_req_macipmap), -+ .addip = &addip, -+ .addip_kernel = &addip_kernel, -+ .delip = &delip, -+ .delip_kernel = &delip_kernel, -+ .testip = &testip, -+ .testip_kernel = &testip_kernel, -+ .header_size = sizeof(struct ip_set_req_macipmap_create), -+ .list_header = &list_header, -+ .list_members_size = &list_members_size, -+ .list_members = &list_members, -+ .me = THIS_MODULE, -+}; -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Jozsef Kadlecsik "); -+MODULE_DESCRIPTION("macipmap type of IP sets"); -+ -+static int __init ip_set_macipmap_init(void) -+{ -+ init_max_malloc_size(); -+ return ip_set_register_set_type(&ip_set_macipmap); -+} -+ -+static void __exit ip_set_macipmap_fini(void) -+{ -+ /* FIXME: possible race with ip_set_create() */ -+ ip_set_unregister_set_type(&ip_set_macipmap); -+} -+ -+module_init(ip_set_macipmap_init); -+module_exit(ip_set_macipmap_fini); ---- /dev/null -+++ b/net/ipv4/netfilter/ip_set_nethash.c -@@ -0,0 +1,497 @@ -+/* Copyright (C) 2003-2004 Jozsef Kadlecsik -+ * -+ * 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. -+ */ -+ -+/* Kernel module implementing a cidr nethash set */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include -+#include -+ -+static int limit = MAX_RANGE; -+ -+static inline __u32 -+jhash_ip(const struct ip_set_nethash *map, uint16_t i, ip_set_ip_t ip) -+{ -+ return jhash_1word(ip, *(((uint32_t *) map->initval) + i)); -+} -+ -+static inline __u32 -+hash_id_cidr(struct ip_set_nethash *map, -+ ip_set_ip_t ip, -+ unsigned char cidr, -+ ip_set_ip_t *hash_ip) -+{ -+ __u32 id; -+ u_int16_t i; -+ ip_set_ip_t *elem; -+ -+ *hash_ip = pack(ip, cidr); -+ -+ for (i = 0; i < map->probes; i++) { -+ id = jhash_ip(map, i, *hash_ip) % map->hashsize; -+ DP("hash key: %u", id); -+ elem = HARRAY_ELEM(map->members, ip_set_ip_t *, id); -+ if (*elem == *hash_ip) -+ return id; -+ } -+ return UINT_MAX; -+} -+ -+static inline __u32 -+hash_id(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip) -+{ -+ struct ip_set_nethash *map = (struct ip_set_nethash *) set->data; -+ __u32 id = UINT_MAX; -+ int i; -+ -+ for (i = 0; i < 30 && map->cidr[i]; i++) { -+ id = hash_id_cidr(map, ip, map->cidr[i], hash_ip); -+ if (id != UINT_MAX) -+ break; -+ } -+ return id; -+} -+ -+static inline int -+__testip_cidr(struct ip_set *set, ip_set_ip_t ip, unsigned char cidr, -+ ip_set_ip_t *hash_ip) -+{ -+ struct ip_set_nethash *map = (struct ip_set_nethash *) set->data; -+ -+ return (ip && hash_id_cidr(map, ip, cidr, hash_ip) != UINT_MAX); -+} -+ -+static inline int -+__testip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip) -+{ -+ return (ip && hash_id(set, ip, hash_ip) != UINT_MAX); -+} -+ -+static int -+testip(struct ip_set *set, const void *data, size_t size, -+ ip_set_ip_t *hash_ip) -+{ -+ struct ip_set_req_nethash *req = -+ (struct ip_set_req_nethash *) data; -+ -+ if (size != sizeof(struct ip_set_req_nethash)) { -+ ip_set_printk("data length wrong (want %zu, have %zu)", -+ sizeof(struct ip_set_req_nethash), -+ size); -+ return -EINVAL; -+ } -+ return (req->cidr == 32 ? __testip(set, req->ip, hash_ip) -+ : __testip_cidr(set, req->ip, req->cidr, hash_ip)); -+} -+ -+static int -+testip_kernel(struct ip_set *set, -+ const struct sk_buff *skb, -+ ip_set_ip_t *hash_ip, -+ const u_int32_t *flags, -+ unsigned char index) -+{ -+ return __testip(set, -+ ntohl(flags[index] & IPSET_SRC -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) -+ ? ip_hdr(skb)->saddr -+ : ip_hdr(skb)->daddr), -+#else -+ ? skb->nh.iph->saddr -+ : skb->nh.iph->daddr), -+#endif -+ hash_ip); -+} -+ -+static inline int -+__addip_base(struct ip_set_nethash *map, ip_set_ip_t ip) -+{ -+ __u32 probe; -+ u_int16_t i; -+ ip_set_ip_t *elem; -+ -+ for (i = 0; i < map->probes; i++) { -+ probe = jhash_ip(map, i, ip) % map->hashsize; -+ elem = HARRAY_ELEM(map->members, ip_set_ip_t *, probe); -+ if (*elem == ip) -+ return -EEXIST; -+ if (!*elem) { -+ *elem = ip; -+ map->elements++; -+ return 0; -+ } -+ } -+ /* Trigger rehashing */ -+ return -EAGAIN; -+} -+ -+static inline int -+__addip(struct ip_set_nethash *map, ip_set_ip_t ip, unsigned char cidr, -+ ip_set_ip_t *hash_ip) -+{ -+ if (!ip || map->elements >= limit) -+ return -ERANGE; -+ -+ *hash_ip = pack(ip, cidr); -+ DP("%u.%u.%u.%u/%u, %u.%u.%u.%u", HIPQUAD(ip), cidr, HIPQUAD(*hash_ip)); -+ -+ return __addip_base(map, *hash_ip); -+} -+ -+static void -+update_cidr_sizes(struct ip_set_nethash *map, unsigned char cidr) -+{ -+ unsigned char next; -+ int i; -+ -+ for (i = 0; i < 30 && map->cidr[i]; i++) { -+ if (map->cidr[i] == cidr) { -+ return; -+ } else if (map->cidr[i] < cidr) { -+ next = map->cidr[i]; -+ map->cidr[i] = cidr; -+ cidr = next; -+ } -+ } -+ if (i < 30) -+ map->cidr[i] = cidr; -+} -+ -+static int -+addip(struct ip_set *set, const void *data, size_t size, -+ ip_set_ip_t *hash_ip) -+{ -+ struct ip_set_req_nethash *req = -+ (struct ip_set_req_nethash *) data; -+ int ret; -+ -+ if (size != sizeof(struct ip_set_req_nethash)) { -+ ip_set_printk("data length wrong (want %zu, have %zu)", -+ sizeof(struct ip_set_req_nethash), -+ size); -+ return -EINVAL; -+ } -+ ret = __addip((struct ip_set_nethash *) set->data, -+ req->ip, req->cidr, hash_ip); -+ -+ if (ret == 0) -+ update_cidr_sizes((struct ip_set_nethash *) set->data, -+ req->cidr); -+ -+ return ret; -+} -+ -+static int -+addip_kernel(struct ip_set *set, -+ const struct sk_buff *skb, -+ ip_set_ip_t *hash_ip, -+ const u_int32_t *flags, -+ unsigned char index) -+{ -+ struct ip_set_nethash *map = (struct ip_set_nethash *) set->data; -+ int ret = -ERANGE; -+ ip_set_ip_t ip = ntohl(flags[index] & IPSET_SRC -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) -+ ? ip_hdr(skb)->saddr -+ : ip_hdr(skb)->daddr); -+#else -+ ? skb->nh.iph->saddr -+ : skb->nh.iph->daddr); -+#endif -+ -+ if (map->cidr[0]) -+ ret = __addip(map, ip, map->cidr[0], hash_ip); -+ -+ return ret; -+} -+ -+static int retry(struct ip_set *set) -+{ -+ struct ip_set_nethash *map = (struct ip_set_nethash *) set->data; -+ ip_set_ip_t *elem; -+ void *members; -+ u_int32_t i, hashsize = map->hashsize; -+ int res; -+ struct ip_set_nethash *tmp; -+ -+ if (map->resize == 0) -+ return -ERANGE; -+ -+ again: -+ res = 0; -+ -+ /* Calculate new parameters */ -+ hashsize += (hashsize * map->resize)/100; -+ if (hashsize == map->hashsize) -+ hashsize++; -+ -+ ip_set_printk("rehashing of set %s triggered: " -+ "hashsize grows from %u to %u", -+ set->name, map->hashsize, hashsize); -+ -+ tmp = kmalloc(sizeof(struct ip_set_nethash) -+ + map->probes * sizeof(uint32_t), GFP_ATOMIC); -+ if (!tmp) { -+ DP("out of memory for %d bytes", -+ sizeof(struct ip_set_nethash) -+ + map->probes * sizeof(uint32_t)); -+ return -ENOMEM; -+ } -+ tmp->members = harray_malloc(hashsize, sizeof(ip_set_ip_t), GFP_ATOMIC); -+ if (!tmp->members) { -+ DP("out of memory for %d bytes", hashsize * sizeof(ip_set_ip_t)); -+ kfree(tmp); -+ return -ENOMEM; -+ } -+ tmp->hashsize = hashsize; -+ tmp->elements = 0; -+ tmp->probes = map->probes; -+ tmp->resize = map->resize; -+ memcpy(tmp->initval, map->initval, map->probes * sizeof(uint32_t)); -+ memcpy(tmp->cidr, map->cidr, 30 * sizeof(unsigned char)); -+ -+ write_lock_bh(&set->lock); -+ map = (struct ip_set_nethash *) set->data; /* Play safe */ -+ for (i = 0; i < map->hashsize && res == 0; i++) { -+ elem = HARRAY_ELEM(map->members, ip_set_ip_t *, i); -+ if (*elem) -+ res = __addip_base(tmp, *elem); -+ } -+ if (res) { -+ /* Failure, try again */ -+ write_unlock_bh(&set->lock); -+ harray_free(tmp->members); -+ kfree(tmp); -+ goto again; -+ } -+ -+ /* Success at resizing! */ -+ members = map->members; -+ -+ map->hashsize = tmp->hashsize; -+ map->members = tmp->members; -+ write_unlock_bh(&set->lock); -+ -+ harray_free(members); -+ kfree(tmp); -+ -+ return 0; -+} -+ -+static inline int -+__delip(struct ip_set_nethash *map, ip_set_ip_t ip, unsigned char cidr, -+ ip_set_ip_t *hash_ip) -+{ -+ ip_set_ip_t id, *elem; -+ -+ if (!ip) -+ return -ERANGE; -+ -+ id = hash_id_cidr(map, ip, cidr, hash_ip); -+ if (id == UINT_MAX) -+ return -EEXIST; -+ -+ elem = HARRAY_ELEM(map->members, ip_set_ip_t *, id); -+ *elem = 0; -+ map->elements--; -+ return 0; -+} -+ -+static int -+delip(struct ip_set *set, const void *data, size_t size, -+ ip_set_ip_t *hash_ip) -+{ -+ struct ip_set_req_nethash *req = -+ (struct ip_set_req_nethash *) data; -+ -+ if (size != sizeof(struct ip_set_req_nethash)) { -+ ip_set_printk("data length wrong (want %zu, have %zu)", -+ sizeof(struct ip_set_req_nethash), -+ size); -+ return -EINVAL; -+ } -+ /* TODO: no garbage collection in map->cidr */ -+ return __delip((struct ip_set_nethash *) set->data, -+ req->ip, req->cidr, hash_ip); -+} -+ -+static int -+delip_kernel(struct ip_set *set, -+ const struct sk_buff *skb, -+ ip_set_ip_t *hash_ip, -+ const u_int32_t *flags, -+ unsigned char index) -+{ -+ struct ip_set_nethash *map = (struct ip_set_nethash *) set->data; -+ int ret = -ERANGE; -+ ip_set_ip_t ip = ntohl(flags[index] & IPSET_SRC -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) -+ ? ip_hdr(skb)->saddr -+ : ip_hdr(skb)->daddr); -+#else -+ ? skb->nh.iph->saddr -+ : skb->nh.iph->daddr); -+#endif -+ -+ if (map->cidr[0]) -+ ret = __delip(map, ip, map->cidr[0], hash_ip); -+ -+ return ret; -+} -+ -+static int create(struct ip_set *set, const void *data, size_t size) -+{ -+ struct ip_set_req_nethash_create *req = -+ (struct ip_set_req_nethash_create *) data; -+ struct ip_set_nethash *map; -+ uint16_t i; -+ -+ if (size != sizeof(struct ip_set_req_nethash_create)) { -+ ip_set_printk("data length wrong (want %zu, have %zu)", -+ sizeof(struct ip_set_req_nethash_create), -+ size); -+ return -EINVAL; -+ } -+ -+ if (req->hashsize < 1) { -+ ip_set_printk("hashsize too small"); -+ return -ENOEXEC; -+ } -+ if (req->probes < 1) { -+ ip_set_printk("probes too small"); -+ return -ENOEXEC; -+ } -+ -+ map = kmalloc(sizeof(struct ip_set_nethash) -+ + req->probes * sizeof(uint32_t), GFP_KERNEL); -+ if (!map) { -+ DP("out of memory for %d bytes", -+ sizeof(struct ip_set_nethash) -+ + req->probes * sizeof(uint32_t)); -+ return -ENOMEM; -+ } -+ for (i = 0; i < req->probes; i++) -+ get_random_bytes(((uint32_t *) map->initval)+i, 4); -+ map->elements = 0; -+ map->hashsize = req->hashsize; -+ map->probes = req->probes; -+ map->resize = req->resize; -+ memset(map->cidr, 0, 30 * sizeof(unsigned char)); -+ map->members = harray_malloc(map->hashsize, sizeof(ip_set_ip_t), GFP_KERNEL); -+ if (!map->members) { -+ DP("out of memory for %d bytes", map->hashsize * sizeof(ip_set_ip_t)); -+ kfree(map); -+ return -ENOMEM; -+ } -+ -+ set->data = map; -+ return 0; -+} -+ -+static void destroy(struct ip_set *set) -+{ -+ struct ip_set_nethash *map = (struct ip_set_nethash *) set->data; -+ -+ harray_free(map->members); -+ kfree(map); -+ -+ set->data = NULL; -+} -+ -+static void flush(struct ip_set *set) -+{ -+ struct ip_set_nethash *map = (struct ip_set_nethash *) set->data; -+ harray_flush(map->members, map->hashsize, sizeof(ip_set_ip_t)); -+ memset(map->cidr, 0, 30 * sizeof(unsigned char)); -+ map->elements = 0; -+} -+ -+static void list_header(const struct ip_set *set, void *data) -+{ -+ struct ip_set_nethash *map = (struct ip_set_nethash *) set->data; -+ struct ip_set_req_nethash_create *header = -+ (struct ip_set_req_nethash_create *) data; -+ -+ header->hashsize = map->hashsize; -+ header->probes = map->probes; -+ header->resize = map->resize; -+} -+ -+static int list_members_size(const struct ip_set *set) -+{ -+ struct ip_set_nethash *map = (struct ip_set_nethash *) set->data; -+ -+ return (map->hashsize * sizeof(ip_set_ip_t)); -+} -+ -+static void list_members(const struct ip_set *set, void *data) -+{ -+ struct ip_set_nethash *map = (struct ip_set_nethash *) set->data; -+ ip_set_ip_t i, *elem; -+ -+ for (i = 0; i < map->hashsize; i++) { -+ elem = HARRAY_ELEM(map->members, ip_set_ip_t *, i); -+ ((ip_set_ip_t *)data)[i] = *elem; -+ } -+} -+ -+static struct ip_set_type ip_set_nethash = { -+ .typename = SETTYPE_NAME, -+ .features = IPSET_TYPE_IP | IPSET_DATA_SINGLE, -+ .protocol_version = IP_SET_PROTOCOL_VERSION, -+ .create = &create, -+ .destroy = &destroy, -+ .flush = &flush, -+ .reqsize = sizeof(struct ip_set_req_nethash), -+ .addip = &addip, -+ .addip_kernel = &addip_kernel, -+ .retry = &retry, -+ .delip = &delip, -+ .delip_kernel = &delip_kernel, -+ .testip = &testip, -+ .testip_kernel = &testip_kernel, -+ .header_size = sizeof(struct ip_set_req_nethash_create), -+ .list_header = &list_header, -+ .list_members_size = &list_members_size, -+ .list_members = &list_members, -+ .me = THIS_MODULE, -+}; -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Jozsef Kadlecsik "); -+MODULE_DESCRIPTION("nethash type of IP sets"); -+module_param(limit, int, 0600); -+MODULE_PARM_DESC(limit, "maximal number of elements stored in the sets"); -+ -+static int __init ip_set_nethash_init(void) -+{ -+ return ip_set_register_set_type(&ip_set_nethash); -+} -+ -+static void __exit ip_set_nethash_fini(void) -+{ -+ /* FIXME: possible race with ip_set_create() */ -+ ip_set_unregister_set_type(&ip_set_nethash); -+} -+ -+module_init(ip_set_nethash_init); -+module_exit(ip_set_nethash_fini); ---- /dev/null -+++ b/net/ipv4/netfilter/ip_set_portmap.c -@@ -0,0 +1,346 @@ -+/* Copyright (C) 2003-2004 Jozsef Kadlecsik -+ * -+ * 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. -+ */ -+ -+/* Kernel module implementing a port set type as a bitmap */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include -+ -+/* We must handle non-linear skbs */ -+static inline ip_set_ip_t -+get_port(const struct sk_buff *skb, u_int32_t flags) -+{ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) -+ struct iphdr *iph = ip_hdr(skb); -+#else -+ struct iphdr *iph = skb->nh.iph; -+#endif -+ u_int16_t offset = ntohs(iph->frag_off) & IP_OFFSET; -+ switch (iph->protocol) { -+ case IPPROTO_TCP: { -+ struct tcphdr tcph; -+ -+ /* See comments at tcp_match in ip_tables.c */ -+ if (offset) -+ return INVALID_PORT; -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) -+ if (skb_copy_bits(skb, ip_hdr(skb)->ihl*4, &tcph, sizeof(tcph)) < 0) -+#else -+ if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &tcph, sizeof(tcph)) < 0) -+#endif -+ /* No choice either */ -+ return INVALID_PORT; -+ -+ return ntohs(flags & IPSET_SRC ? -+ tcph.source : tcph.dest); -+ } -+ case IPPROTO_UDP: { -+ struct udphdr udph; -+ -+ if (offset) -+ return INVALID_PORT; -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) -+ if (skb_copy_bits(skb, ip_hdr(skb)->ihl*4, &udph, sizeof(udph)) < 0) -+#else -+ if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &udph, sizeof(udph)) < 0) -+#endif -+ /* No choice either */ -+ return INVALID_PORT; -+ -+ return ntohs(flags & IPSET_SRC ? -+ udph.source : udph.dest); -+ } -+ default: -+ return INVALID_PORT; -+ } -+} -+ -+static inline int -+__testport(struct ip_set *set, ip_set_ip_t port, ip_set_ip_t *hash_port) -+{ -+ struct ip_set_portmap *map = (struct ip_set_portmap *) set->data; -+ -+ if (port < map->first_port || port > map->last_port) -+ return -ERANGE; -+ -+ *hash_port = port; -+ DP("set: %s, port:%u, %u", set->name, port, *hash_port); -+ return !!test_bit(port - map->first_port, map->members); -+} -+ -+static int -+testport(struct ip_set *set, const void *data, size_t size, -+ ip_set_ip_t *hash_port) -+{ -+ struct ip_set_req_portmap *req = -+ (struct ip_set_req_portmap *) data; -+ -+ if (size != sizeof(struct ip_set_req_portmap)) { -+ ip_set_printk("data length wrong (want %zu, have %zu)", -+ sizeof(struct ip_set_req_portmap), -+ size); -+ return -EINVAL; -+ } -+ return __testport(set, req->port, hash_port); -+} -+ -+static int -+testport_kernel(struct ip_set *set, -+ const struct sk_buff *skb, -+ ip_set_ip_t *hash_port, -+ const u_int32_t *flags, -+ unsigned char index) -+{ -+ int res; -+ ip_set_ip_t port = get_port(skb, flags[index]); -+ -+ DP("flag %s port %u", flags[index] & IPSET_SRC ? "SRC" : "DST", port); -+ if (port == INVALID_PORT) -+ return 0; -+ -+ res = __testport(set, port, hash_port); -+ -+ return (res < 0 ? 0 : res); -+} -+ -+static inline int -+__addport(struct ip_set *set, ip_set_ip_t port, ip_set_ip_t *hash_port) -+{ -+ struct ip_set_portmap *map = (struct ip_set_portmap *) set->data; -+ -+ if (port < map->first_port || port > map->last_port) -+ return -ERANGE; -+ if (test_and_set_bit(port - map->first_port, map->members)) -+ return -EEXIST; -+ -+ *hash_port = port; -+ DP("port %u", port); -+ return 0; -+} -+ -+static int -+addport(struct ip_set *set, const void *data, size_t size, -+ ip_set_ip_t *hash_port) -+{ -+ struct ip_set_req_portmap *req = -+ (struct ip_set_req_portmap *) data; -+ -+ if (size != sizeof(struct ip_set_req_portmap)) { -+ ip_set_printk("data length wrong (want %zu, have %zu)", -+ sizeof(struct ip_set_req_portmap), -+ size); -+ return -EINVAL; -+ } -+ return __addport(set, req->port, hash_port); -+} -+ -+static int -+addport_kernel(struct ip_set *set, -+ const struct sk_buff *skb, -+ ip_set_ip_t *hash_port, -+ const u_int32_t *flags, -+ unsigned char index) -+{ -+ ip_set_ip_t port = get_port(skb, flags[index]); -+ -+ if (port == INVALID_PORT) -+ return -EINVAL; -+ -+ return __addport(set, port, hash_port); -+} -+ -+static inline int -+__delport(struct ip_set *set, ip_set_ip_t port, ip_set_ip_t *hash_port) -+{ -+ struct ip_set_portmap *map = (struct ip_set_portmap *) set->data; -+ -+ if (port < map->first_port || port > map->last_port) -+ return -ERANGE; -+ if (!test_and_clear_bit(port - map->first_port, map->members)) -+ return -EEXIST; -+ -+ *hash_port = port; -+ DP("port %u", port); -+ return 0; -+} -+ -+static int -+delport(struct ip_set *set, const void *data, size_t size, -+ ip_set_ip_t *hash_port) -+{ -+ struct ip_set_req_portmap *req = -+ (struct ip_set_req_portmap *) data; -+ -+ if (size != sizeof(struct ip_set_req_portmap)) { -+ ip_set_printk("data length wrong (want %zu, have %zu)", -+ sizeof(struct ip_set_req_portmap), -+ size); -+ return -EINVAL; -+ } -+ return __delport(set, req->port, hash_port); -+} -+ -+static int -+delport_kernel(struct ip_set *set, -+ const struct sk_buff *skb, -+ ip_set_ip_t *hash_port, -+ const u_int32_t *flags, -+ unsigned char index) -+{ -+ ip_set_ip_t port = get_port(skb, flags[index]); -+ -+ if (port == INVALID_PORT) -+ return -EINVAL; -+ -+ return __delport(set, port, hash_port); -+} -+ -+static int create(struct ip_set *set, const void *data, size_t size) -+{ -+ int newbytes; -+ struct ip_set_req_portmap_create *req = -+ (struct ip_set_req_portmap_create *) data; -+ struct ip_set_portmap *map; -+ -+ if (size != sizeof(struct ip_set_req_portmap_create)) { -+ ip_set_printk("data length wrong (want %zu, have %zu)", -+ sizeof(struct ip_set_req_portmap_create), -+ size); -+ return -EINVAL; -+ } -+ -+ DP("from %u to %u", req->from, req->to); -+ -+ if (req->from > req->to) { -+ DP("bad port range"); -+ return -ENOEXEC; -+ } -+ -+ if (req->to - req->from > MAX_RANGE) { -+ ip_set_printk("range too big (max %d ports)", -+ MAX_RANGE+1); -+ return -ENOEXEC; -+ } -+ -+ map = kmalloc(sizeof(struct ip_set_portmap), GFP_KERNEL); -+ if (!map) { -+ DP("out of memory for %d bytes", -+ sizeof(struct ip_set_portmap)); -+ return -ENOMEM; -+ } -+ map->first_port = req->from; -+ map->last_port = req->to; -+ newbytes = bitmap_bytes(req->from, req->to); -+ map->members = kmalloc(newbytes, GFP_KERNEL); -+ if (!map->members) { -+ DP("out of memory for %d bytes", newbytes); -+ kfree(map); -+ return -ENOMEM; -+ } -+ memset(map->members, 0, newbytes); -+ -+ set->data = map; -+ return 0; -+} -+ -+static void destroy(struct ip_set *set) -+{ -+ struct ip_set_portmap *map = (struct ip_set_portmap *) set->data; -+ -+ kfree(map->members); -+ kfree(map); -+ -+ set->data = NULL; -+} -+ -+static void flush(struct ip_set *set) -+{ -+ struct ip_set_portmap *map = (struct ip_set_portmap *) set->data; -+ memset(map->members, 0, bitmap_bytes(map->first_port, map->last_port)); -+} -+ -+static void list_header(const struct ip_set *set, void *data) -+{ -+ struct ip_set_portmap *map = (struct ip_set_portmap *) set->data; -+ struct ip_set_req_portmap_create *header = -+ (struct ip_set_req_portmap_create *) data; -+ -+ DP("list_header %u %u", map->first_port, map->last_port); -+ -+ header->from = map->first_port; -+ header->to = map->last_port; -+} -+ -+static int list_members_size(const struct ip_set *set) -+{ -+ struct ip_set_portmap *map = (struct ip_set_portmap *) set->data; -+ -+ return bitmap_bytes(map->first_port, map->last_port); -+} -+ -+static void list_members(const struct ip_set *set, void *data) -+{ -+ struct ip_set_portmap *map = (struct ip_set_portmap *) set->data; -+ int bytes = bitmap_bytes(map->first_port, map->last_port); -+ -+ memcpy(data, map->members, bytes); -+} -+ -+static struct ip_set_type ip_set_portmap = { -+ .typename = SETTYPE_NAME, -+ .features = IPSET_TYPE_PORT | IPSET_DATA_SINGLE, -+ .protocol_version = IP_SET_PROTOCOL_VERSION, -+ .create = &create, -+ .destroy = &destroy, -+ .flush = &flush, -+ .reqsize = sizeof(struct ip_set_req_portmap), -+ .addip = &addport, -+ .addip_kernel = &addport_kernel, -+ .delip = &delport, -+ .delip_kernel = &delport_kernel, -+ .testip = &testport, -+ .testip_kernel = &testport_kernel, -+ .header_size = sizeof(struct ip_set_req_portmap_create), -+ .list_header = &list_header, -+ .list_members_size = &list_members_size, -+ .list_members = &list_members, -+ .me = THIS_MODULE, -+}; -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Jozsef Kadlecsik "); -+MODULE_DESCRIPTION("portmap type of IP sets"); -+ -+static int __init ip_set_portmap_init(void) -+{ -+ return ip_set_register_set_type(&ip_set_portmap); -+} -+ -+static void __exit ip_set_portmap_fini(void) -+{ -+ /* FIXME: possible race with ip_set_create() */ -+ ip_set_unregister_set_type(&ip_set_portmap); -+} -+ -+module_init(ip_set_portmap_init); -+module_exit(ip_set_portmap_fini); ---- /dev/null -+++ b/net/ipv4/netfilter/ipt_set.c -@@ -0,0 +1,160 @@ -+/* Copyright (C) 2000-2002 Joakim Axelsson -+ * Patrick Schaaf -+ * Martin Josefsson -+ * Copyright (C) 2003-2004 Jozsef Kadlecsik -+ * -+ * 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. -+ */ -+ -+/* Kernel module to match an IP set. */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+static inline int -+match_set(const struct ipt_set_info *info, -+ const struct sk_buff *skb, -+ int inv) -+{ -+ if (ip_set_testip_kernel(info->index, skb, info->flags)) -+ inv = !inv; -+ return inv; -+} -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) -+static bool -+#else -+static int -+#endif -+match(const struct sk_buff *skb, -+ const struct net_device *in, -+ const struct net_device *out, -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17) -+ const struct xt_match *match, -+#endif -+ const void *matchinfo, -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) -+ int offset, unsigned int protoff, bool *hotdrop) -+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) -+ int offset, unsigned int protoff, int *hotdrop) -+#else -+ int offset, int *hotdrop) -+#endif -+{ -+ const struct ipt_set_info_match *info = matchinfo; -+ -+ return match_set(&info->match_set, -+ skb, -+ info->match_set.flags[0] & IPSET_MATCH_INV); -+} -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) -+bool -+#else -+static int -+#endif -+checkentry(const char *tablename, -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) -+ const void *inf, -+#else -+ const struct ipt_ip *ip, -+#endif -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17) -+ const struct xt_match *match, -+#endif -+ void *matchinfo, -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) -+ unsigned int matchsize, -+#endif -+ unsigned int hook_mask) -+{ -+ struct ipt_set_info_match *info = -+ (struct ipt_set_info_match *) matchinfo; -+ ip_set_id_t index; -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) -+ if (matchsize != IPT_ALIGN(sizeof(struct ipt_set_info_match))) { -+ ip_set_printk("invalid matchsize %d", matchsize); -+ return 0; -+ } -+#endif -+ -+ index = ip_set_get_byindex(info->match_set.index); -+ -+ if (index == IP_SET_INVALID_ID) { -+ ip_set_printk("Cannot find set indentified by id %u to match", -+ info->match_set.index); -+ return 0; /* error */ -+ } -+ if (info->match_set.flags[IP_SET_MAX_BINDINGS] != 0) { -+ ip_set_printk("That's nasty!"); -+ return 0; /* error */ -+ } -+ -+ return 1; -+} -+ -+static void destroy( -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17) -+ const struct xt_match *match, -+#endif -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) -+ void *matchinfo, unsigned int matchsize) -+#else -+ void *matchinfo) -+#endif -+{ -+ struct ipt_set_info_match *info = matchinfo; -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) -+ if (matchsize != IPT_ALIGN(sizeof(struct ipt_set_info_match))) { -+ ip_set_printk("invalid matchsize %d", matchsize); -+ return; -+ } -+#endif -+ ip_set_put(info->match_set.index); -+} -+ -+static struct ipt_match set_match = { -+ .name = "set", -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21) -+ .family = AF_INET, -+#endif -+ .match = &match, -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17) -+ .matchsize = sizeof(struct ipt_set_info_match), -+#endif -+ .checkentry = &checkentry, -+ .destroy = &destroy, -+ .me = THIS_MODULE -+}; -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Jozsef Kadlecsik "); -+MODULE_DESCRIPTION("iptables IP set match module"); -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21) -+#define ipt_register_match xt_register_match -+#define ipt_unregister_match xt_unregister_match -+#endif -+ -+static int __init ipt_ipset_init(void) -+{ -+ return ipt_register_match(&set_match); -+} -+ -+static void __exit ipt_ipset_fini(void) -+{ -+ ipt_unregister_match(&set_match); -+} -+ -+module_init(ipt_ipset_init); -+module_exit(ipt_ipset_fini); ---- /dev/null -+++ b/net/ipv4/netfilter/ipt_SET.c -@@ -0,0 +1,179 @@ -+/* Copyright (C) 2000-2002 Joakim Axelsson -+ * Patrick Schaaf -+ * Martin Josefsson -+ * Copyright (C) 2003-2004 Jozsef Kadlecsik -+ * -+ * 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. -+ */ -+ -+/* ipt_SET.c - netfilter target to manipulate IP sets */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static unsigned int -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) -+target(struct sk_buff *skb, -+#else -+target(struct sk_buff **pskb, -+#endif -+ const struct net_device *in, -+ const struct net_device *out, -+ unsigned int hooknum, -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17) -+ const struct xt_target *target, -+#endif -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) -+ const void *targinfo, -+ void *userinfo) -+#else -+ const void *targinfo) -+#endif -+{ -+ const struct ipt_set_info_target *info = targinfo; -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) -+ struct sk_buff *skb = *pskb; -+#endif -+ -+ if (info->add_set.index != IP_SET_INVALID_ID) -+ ip_set_addip_kernel(info->add_set.index, -+ skb, -+ info->add_set.flags); -+ if (info->del_set.index != IP_SET_INVALID_ID) -+ ip_set_delip_kernel(info->del_set.index, -+ skb, -+ info->del_set.flags); -+ -+ return IPT_CONTINUE; -+} -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) -+static bool -+#else -+static int -+#endif -+checkentry(const char *tablename, -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) -+ const void *e, -+#else -+ const struct ipt_entry *e, -+#endif -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17) -+ const struct xt_target *target, -+#endif -+ void *targinfo, -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) -+ unsigned int targinfosize, -+#endif -+ unsigned int hook_mask) -+{ -+ struct ipt_set_info_target *info = -+ (struct ipt_set_info_target *) targinfo; -+ ip_set_id_t index; -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) -+ if (targinfosize != IPT_ALIGN(sizeof(*info))) { -+ DP("bad target info size %u", targinfosize); -+ return 0; -+ } -+#endif -+ -+ if (info->add_set.index != IP_SET_INVALID_ID) { -+ index = ip_set_get_byindex(info->add_set.index); -+ if (index == IP_SET_INVALID_ID) { -+ ip_set_printk("cannot find add_set index %u as target", -+ info->add_set.index); -+ return 0; /* error */ -+ } -+ } -+ -+ if (info->del_set.index != IP_SET_INVALID_ID) { -+ index = ip_set_get_byindex(info->del_set.index); -+ if (index == IP_SET_INVALID_ID) { -+ ip_set_printk("cannot find del_set index %u as target", -+ info->del_set.index); -+ return 0; /* error */ -+ } -+ } -+ if (info->add_set.flags[IP_SET_MAX_BINDINGS] != 0 -+ || info->del_set.flags[IP_SET_MAX_BINDINGS] != 0) { -+ ip_set_printk("That's nasty!"); -+ return 0; /* error */ -+ } -+ -+ return 1; -+} -+ -+static void destroy( -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17) -+ const struct xt_target *target, -+#endif -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) -+ void *targetinfo, unsigned int targetsize) -+#else -+ void *targetinfo) -+#endif -+{ -+ struct ipt_set_info_target *info = targetinfo; -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) -+ if (targetsize != IPT_ALIGN(sizeof(struct ipt_set_info_target))) { -+ ip_set_printk("invalid targetsize %d", targetsize); -+ return; -+ } -+#endif -+ if (info->add_set.index != IP_SET_INVALID_ID) -+ ip_set_put(info->add_set.index); -+ if (info->del_set.index != IP_SET_INVALID_ID) -+ ip_set_put(info->del_set.index); -+} -+ -+static struct ipt_target SET_target = { -+ .name = "SET", -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21) -+ .family = AF_INET, -+#endif -+ .target = target, -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17) -+ .targetsize = sizeof(struct ipt_set_info_target), -+#endif -+ .checkentry = checkentry, -+ .destroy = destroy, -+ .me = THIS_MODULE -+}; -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Jozsef Kadlecsik "); -+MODULE_DESCRIPTION("iptables IP set target module"); -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21) -+#define ipt_register_target xt_register_target -+#define ipt_unregister_target xt_unregister_target -+#endif -+ -+static int __init ipt_SET_init(void) -+{ -+ return ipt_register_target(&SET_target); -+} -+ -+static void __exit ipt_SET_fini(void) -+{ -+ ipt_unregister_target(&SET_target); -+} -+ -+module_init(ipt_SET_init); -+module_exit(ipt_SET_fini); ---- a/net/ipv4/netfilter/Kconfig -+++ b/net/ipv4/netfilter/Kconfig -@@ -402,5 +402,122 @@ config IP_NF_ARP_MANGLE - Allows altering the ARP packet payload: source and destination - hardware and network addresses. - -+config IP_NF_SET -+ tristate "IP set support" -+ depends on INET && NETFILTER -+ help -+ This option adds IP set support to the kernel. -+ In order to define and use sets, you need the userspace utility -+ ipset(8). -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config IP_NF_SET_MAX -+ int "Maximum number of IP sets" -+ default 256 -+ range 2 65534 -+ depends on IP_NF_SET -+ help -+ You can define here default value of the maximum number -+ of IP sets for the kernel. -+ -+ The value can be overriden by the 'max_sets' module -+ parameter of the 'ip_set' module. -+ -+config IP_NF_SET_HASHSIZE -+ int "Hash size for bindings of IP sets" -+ default 1024 -+ depends on IP_NF_SET -+ help -+ You can define here default value of the hash size for -+ bindings of IP sets. -+ -+ The value can be overriden by the 'hash_size' module -+ parameter of the 'ip_set' module. -+ -+config IP_NF_SET_IPMAP -+ tristate "ipmap set support" -+ depends on IP_NF_SET -+ help -+ This option adds the ipmap set type support. -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config IP_NF_SET_MACIPMAP -+ tristate "macipmap set support" -+ depends on IP_NF_SET -+ help -+ This option adds the macipmap set type support. -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config IP_NF_SET_PORTMAP -+ tristate "portmap set support" -+ depends on IP_NF_SET -+ help -+ This option adds the portmap set type support. -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config IP_NF_SET_IPHASH -+ tristate "iphash set support" -+ depends on IP_NF_SET -+ help -+ This option adds the iphash set type support. -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config IP_NF_SET_NETHASH -+ tristate "nethash set support" -+ depends on IP_NF_SET -+ help -+ This option adds the nethash set type support. -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config IP_NF_SET_IPPORTHASH -+ tristate "ipporthash set support" -+ depends on IP_NF_SET -+ help -+ This option adds the ipporthash set type support. -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config IP_NF_SET_IPTREE -+ tristate "iptree set support" -+ depends on IP_NF_SET -+ help -+ This option adds the iptree set type support. -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config IP_NF_SET_IPTREEMAP -+ tristate "iptreemap set support" -+ depends on IP_NF_SET -+ help -+ This option adds the iptreemap set type support. -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config IP_NF_MATCH_SET -+ tristate "set match support" -+ depends on IP_NF_SET -+ help -+ Set matching matches against given IP sets. -+ You need the ipset utility to create and set up the sets. -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+config IP_NF_TARGET_SET -+ tristate "SET target support" -+ depends on IP_NF_SET -+ help -+ The SET target makes possible to add/delete entries -+ in IP sets. -+ You need the ipset utility to create and set up the sets. -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ -+ - endmenu - ---- a/net/ipv4/netfilter/Makefile -+++ b/net/ipv4/netfilter/Makefile -@@ -49,6 +49,7 @@ obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_o - obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.o - obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o - obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o -+obj-$(CONFIG_IP_NF_MATCH_SET) += ipt_set.o - - # targets - obj-$(CONFIG_IP_NF_TARGET_CLUSTERIP) += ipt_CLUSTERIP.o -@@ -62,6 +63,18 @@ obj-$(CONFIG_IP_NF_TARGET_SAME) += ipt_S - obj-$(CONFIG_IP_NF_TARGET_TOS) += ipt_TOS.o - obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o - obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o -+obj-$(CONFIG_IP_NF_TARGET_SET) += ipt_SET.o -+ -+# sets -+obj-$(CONFIG_IP_NF_SET) += ip_set.o -+obj-$(CONFIG_IP_NF_SET_IPMAP) += ip_set_ipmap.o -+obj-$(CONFIG_IP_NF_SET_PORTMAP) += ip_set_portmap.o -+obj-$(CONFIG_IP_NF_SET_MACIPMAP) += ip_set_macipmap.o -+obj-$(CONFIG_IP_NF_SET_IPHASH) += ip_set_iphash.o -+obj-$(CONFIG_IP_NF_SET_NETHASH) += ip_set_nethash.o -+obj-$(CONFIG_IP_NF_SET_IPPORTHASH) += ip_set_ipporthash.o -+obj-$(CONFIG_IP_NF_SET_IPTREE) += ip_set_iptree.o -+obj-$(CONFIG_IP_NF_SET_IPTREEMAP) += ip_set_iptreemap.o - - # generic ARP tables - obj-$(CONFIG_IP_NF_ARPTABLES) += arp_tables.o diff --git a/target/linux/generic-2.6/patches-2.6.24/140-netfilter_time.patch b/target/linux/generic-2.6/patches-2.6.24/140-netfilter_time.patch deleted file mode 100644 index 7430de0f81..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/140-netfilter_time.patch +++ /dev/null @@ -1,239 +0,0 @@ ---- /dev/null -+++ b/include/linux/netfilter_ipv4/ipt_time.h -@@ -0,0 +1,18 @@ -+#ifndef __ipt_time_h_included__ -+#define __ipt_time_h_included__ -+ -+ -+struct ipt_time_info { -+ u_int8_t days_match; /* 1 bit per day. -SMTWTFS */ -+ u_int16_t time_start; /* 0 < time_start < 23*60+59 = 1439 */ -+ u_int16_t time_stop; /* 0:0 < time_stat < 23:59 */ -+ -+ /* FIXME: Keep this one for userspace iptables binary compability: */ -+ u_int8_t kerneltime; /* ignore skb time (and use kerneltime) or not. */ -+ -+ time_t date_start; -+ time_t date_stop; -+}; -+ -+ -+#endif /* __ipt_time_h_included__ */ ---- /dev/null -+++ b/net/ipv4/netfilter/ipt_time.c -@@ -0,0 +1,180 @@ -+/* -+ This is a module which is used for time matching -+ It is using some modified code from dietlibc (localtime() function) -+ that you can find at http://www.fefe.de/dietlibc/ -+ This file is distributed under the terms of the GNU General Public -+ License (GPL). Copies of the GPL can be obtained from: ftp://prep.ai.mit.edu/pub/gnu/GPL -+ 2001-05-04 Fabrice MARIE : initial development. -+ 2001-21-05 Fabrice MARIE : bug fix in the match code, -+ thanks to "Zeng Yu" for bug report. -+ 2001-26-09 Fabrice MARIE : force the match to be in LOCAL_IN or PRE_ROUTING only. -+ 2001-30-11 Fabrice : added the possibility to use the match in FORWARD/OUTPUT with a little hack, -+ added Nguyen Dang Phuoc Dong patch to support timezones. -+ 2004-05-02 Fabrice : added support for date matching, from an idea of Fabien COELHO. -+*/ -+ -+#include -+#include -+#include -+#include -+#include -+ -+MODULE_AUTHOR("Fabrice MARIE "); -+MODULE_DESCRIPTION("Match arrival timestamp/date"); -+MODULE_LICENSE("GPL"); -+ -+struct tm -+{ -+ int tm_sec; /* Seconds. [0-60] (1 leap second) */ -+ int tm_min; /* Minutes. [0-59] */ -+ int tm_hour; /* Hours. [0-23] */ -+ int tm_mday; /* Day. [1-31] */ -+ int tm_mon; /* Month. [0-11] */ -+ int tm_year; /* Year - 1900. */ -+ int tm_wday; /* Day of week. [0-6] */ -+ int tm_yday; /* Days in year.[0-365] */ -+ int tm_isdst; /* DST. [-1/0/1]*/ -+ -+ long int tm_gmtoff; /* we don't care, we count from GMT */ -+ const char *tm_zone; /* we don't care, we count from GMT */ -+}; -+ -+void -+localtime(const u32 time, struct tm *r); -+ -+static bool -+match(const struct sk_buff *skb, -+ const struct net_device *in, -+ const struct net_device *out, -+ const struct xt_match *match, -+ const void *matchinfo, -+ int offset, -+ unsigned int protoff, -+ bool *hotdrop) -+{ -+ const struct ipt_time_info *info = matchinfo; /* match info for rule */ -+ struct timeval tv; -+ struct tm currenttime; /* time human readable */ -+ u_int8_t days_of_week[7] = {64, 32, 16, 8, 4, 2, 1}; -+ u_int16_t packet_time; -+ -+ /* We might not have a timestamp, get one */ -+ if (skb->tstamp.tv64 == 0) -+ __net_timestamp((struct sk_buff *)skb); -+ -+ skb_get_timestamp(skb, &tv); -+ /* First we make sure we are in the date start-stop boundaries */ -+ if ((tv.tv_sec < info->date_start) || (tv.tv_sec > info->date_stop)) -+ return 0; /* We are outside the date boundaries */ -+ -+ /* Transform the timestamp of the packet, in a human readable form */ -+ localtime(tv.tv_sec, ¤ttime); -+ -+ /* check if we match this timestamp, we start by the days... */ -+ if ((days_of_week[currenttime.tm_wday] & info->days_match) != days_of_week[currenttime.tm_wday]) -+ return 0; /* the day doesn't match */ -+ -+ /* ... check the time now */ -+ packet_time = (currenttime.tm_hour * 60) + currenttime.tm_min; -+ if ((packet_time < info->time_start) || (packet_time > info->time_stop)) -+ return 0; -+ -+ /* here we match ! */ -+ return 1; -+} -+ -+static bool -+checkentry(const char *tablename, -+ const void *ip, -+ const struct xt_match *match, -+ void *matchinfo, -+ unsigned int hook_mask) -+{ -+ struct ipt_time_info *info = matchinfo; /* match info for rule */ -+ -+ /* First, check that we are in the correct hooks */ -+ if (hook_mask -+ & ~((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD) | (1 << NF_IP_LOCAL_OUT))) -+ { -+ printk("ipt_time: error, only valid for PRE_ROUTING, LOCAL_IN, FORWARD and OUTPUT)\n"); -+ return 0; -+ } -+ -+ /* Now check the coherence of the data ... */ -+ if ((info->time_start > 1439) || /* 23*60+59 = 1439*/ -+ (info->time_stop > 1439)) -+ { -+ printk(KERN_WARNING "ipt_time: invalid argument\n"); -+ return 0; -+ } -+ -+ return 1; -+} -+ -+static struct ipt_match time_match = { -+ .name = "time", -+ .match = &match, -+ .matchsize = sizeof(struct ipt_time_info), -+ .checkentry = &checkentry, -+ .me = THIS_MODULE -+}; -+ -+static int __init init(void) -+{ -+ printk("ipt_time loading\n"); -+ return xt_register_match(&time_match); -+} -+ -+static void __exit fini(void) -+{ -+ xt_unregister_match(&time_match); -+ printk("ipt_time unloaded\n"); -+} -+ -+module_init(init); -+module_exit(fini); -+ -+ -+/* The part below is borowed and modified from dietlibc */ -+ -+/* seconds per day */ -+#define SPD 24*60*60 -+ -+void -+localtime(const u32 time, struct tm *r) { -+ u32 i, timep; -+ extern struct timezone sys_tz; -+ const unsigned int __spm[12] = -+ { 0, -+ (31), -+ (31+28), -+ (31+28+31), -+ (31+28+31+30), -+ (31+28+31+30+31), -+ (31+28+31+30+31+30), -+ (31+28+31+30+31+30+31), -+ (31+28+31+30+31+30+31+31), -+ (31+28+31+30+31+30+31+31+30), -+ (31+28+31+30+31+30+31+31+30+31), -+ (31+28+31+30+31+30+31+31+30+31+30), -+ }; -+ register u32 work; -+ -+ timep = time - (sys_tz.tz_minuteswest * 60); -+ work=timep%(SPD); -+ r->tm_sec=work%60; work/=60; -+ r->tm_min=work%60; r->tm_hour=work/60; -+ work=timep/(SPD); -+ r->tm_wday=(4+work)%7; -+ for (i=1970; ; ++i) { -+ register time_t k= (!(i%4) && ((i%100) || !(i%400)))?366:365; -+ if (work>k) -+ work-=k; -+ else -+ break; -+ } -+ r->tm_year=i-1900; -+ for (i=11; i && __spm[i]>work; --i) ; -+ r->tm_mon=i; -+ r->tm_mday=work-__spm[i]+1; -+} ---- a/net/ipv4/netfilter/Kconfig -+++ b/net/ipv4/netfilter/Kconfig -@@ -72,6 +72,22 @@ config IP_NF_MATCH_TOS - - To compile it as a module, choose M here. If unsure, say N. - -+ -+config IP_NF_MATCH_TIME -+ tristate 'TIME match support' -+ depends on IP_NF_IPTABLES -+ help -+ This option adds a `time' match, which allows you -+ to match based on the packet arrival time/date -+ (arrival time/date at the machine which netfilter is running on) or -+ departure time/date (for locally generated packets). -+ -+ If you say Y here, try iptables -m time --help for more information. -+ If you want to compile it as a module, say M here and read -+ -+ Documentation/modules.txt. If unsure, say `N'. -+ -+ - config IP_NF_MATCH_RECENT - tristate "recent match support" - depends on IP_NF_IPTABLES ---- a/net/ipv4/netfilter/Makefile -+++ b/net/ipv4/netfilter/Makefile -@@ -50,6 +50,7 @@ obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_ - obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o - obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o - obj-$(CONFIG_IP_NF_MATCH_SET) += ipt_set.o -+obj-$(CONFIG_IP_NF_MATCH_TIME) += ipt_time.o - - # targets - obj-$(CONFIG_IP_NF_TARGET_CLUSTERIP) += ipt_CLUSTERIP.o diff --git a/target/linux/generic-2.6/patches-2.6.24/150-netfilter_imq.patch b/target/linux/generic-2.6/patches-2.6.24/150-netfilter_imq.patch deleted file mode 100644 index 15d6f497b4..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/150-netfilter_imq.patch +++ /dev/null @@ -1,858 +0,0 @@ ---- /dev/null -+++ b/drivers/net/imq.c -@@ -0,0 +1,409 @@ -+/* -+ * Pseudo-driver for the intermediate queue device. -+ * -+ * 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. -+ * -+ * Authors: Patrick McHardy, -+ * -+ * The first version was written by Martin Devera, -+ * -+ * Credits: Jan Rafaj -+ * - Update patch to 2.4.21 -+ * Sebastian Strollo -+ * - Fix "Dead-loop on netdevice imq"-issue -+ * Marcel Sebek -+ * - Update to 2.6.2-rc1 -+ * -+ * After some time of inactivity there is a group taking care -+ * of IMQ again: http://www.linuximq.net -+ * -+ * -+ * 2004/06/30 - New version of IMQ patch to kernels <=2.6.7 including -+ * the following changes: -+ * -+ * - Correction of ipv6 support "+"s issue (Hasso Tepper) -+ * - Correction of imq_init_devs() issue that resulted in -+ * kernel OOPS unloading IMQ as module (Norbert Buchmuller) -+ * - Addition of functionality to choose number of IMQ devices -+ * during kernel config (Andre Correa) -+ * - Addition of functionality to choose how IMQ hooks on -+ * PRE and POSTROUTING (after or before NAT) (Andre Correa) -+ * - Cosmetic corrections (Norbert Buchmuller) (Andre Correa) -+ * -+ * -+ * 2005/12/16 - IMQ versions between 2.6.7 and 2.6.13 were -+ * released with almost no problems. 2.6.14-x was released -+ * with some important changes: nfcache was removed; After -+ * some weeks of trouble we figured out that some IMQ fields -+ * in skb were missing in skbuff.c - skb_clone and copy_skb_header. -+ * These functions are correctly patched by this new patch version. -+ * -+ * Thanks for all who helped to figure out all the problems with -+ * 2.6.14.x: Patrick McHardy, Rune Kock, VeNoMouS, Max CtRiX, -+ * Kevin Shanahan, Richard Lucassen, Valery Dachev (hopefully -+ * I didn't forget anybody). I apologize again for my lack of time. -+ * -+ * More info at: http://www.linuximq.net/ (Andre Correa) -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) -+ #include -+#endif -+#include -+#include -+ -+extern int qdisc_restart1(struct net_device *dev); -+ -+static nf_hookfn imq_nf_hook; -+ -+static struct nf_hook_ops imq_ingress_ipv4 = { -+ .hook = imq_nf_hook, -+ .owner = THIS_MODULE, -+ .pf = PF_INET, -+ .hooknum = NF_IP_PRE_ROUTING, -+#if defined(CONFIG_IMQ_BEHAVIOR_BA) || defined(CONFIG_IMQ_BEHAVIOR_BB) -+ .priority = NF_IP_PRI_MANGLE + 1 -+#else -+ .priority = NF_IP_PRI_NAT_DST + 1 -+#endif -+}; -+ -+static struct nf_hook_ops imq_egress_ipv4 = { -+ .hook = imq_nf_hook, -+ .owner = THIS_MODULE, -+ .pf = PF_INET, -+ .hooknum = NF_IP_POST_ROUTING, -+#if defined(CONFIG_IMQ_BEHAVIOR_AA) || defined(CONFIG_IMQ_BEHAVIOR_BA) -+ .priority = NF_IP_PRI_LAST -+#else -+ .priority = NF_IP_PRI_NAT_SRC - 1 -+#endif -+}; -+ -+#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) -+static struct nf_hook_ops imq_ingress_ipv6 = { -+ .hook = imq_nf_hook, -+ .owner = THIS_MODULE, -+ .pf = PF_INET6, -+ .hooknum = NF_IP6_PRE_ROUTING, -+#if defined(CONFIG_IMQ_BEHAVIOR_BA) || defined(CONFIG_IMQ_BEHAVIOR_BB) -+ .priority = NF_IP6_PRI_MANGLE + 1 -+#else -+ .priority = NF_IP6_PRI_NAT_DST + 1 -+#endif -+}; -+ -+static struct nf_hook_ops imq_egress_ipv6 = { -+ .hook = imq_nf_hook, -+ .owner = THIS_MODULE, -+ .pf = PF_INET6, -+ .hooknum = NF_IP6_POST_ROUTING, -+#if defined(CONFIG_IMQ_BEHAVIOR_AA) || defined(CONFIG_IMQ_BEHAVIOR_BA) -+ .priority = NF_IP6_PRI_LAST -+#else -+ .priority = NF_IP6_PRI_NAT_SRC - 1 -+#endif -+}; -+#endif -+ -+#if defined(CONFIG_IMQ_NUM_DEVS) -+static unsigned int numdevs = CONFIG_IMQ_NUM_DEVS; -+#else -+static unsigned int numdevs = 16; -+#endif -+ -+static struct net_device *imq_devs; -+ -+static struct net_device_stats *imq_get_stats(struct net_device *dev) -+{ -+ return (struct net_device_stats *)dev->priv; -+} -+ -+/* called for packets kfree'd in qdiscs at places other than enqueue */ -+static void imq_skb_destructor(struct sk_buff *skb) -+{ -+ struct nf_info *info = skb->nf_info; -+ -+ if (info) { -+ if (info->indev) -+ dev_put(info->indev); -+ if (info->outdev) -+ dev_put(info->outdev); -+ kfree(info); -+ } -+} -+ -+static int imq_dev_xmit(struct sk_buff *skb, struct net_device *dev) -+{ -+ struct net_device_stats *stats = (struct net_device_stats*) dev->priv; -+ -+ stats->tx_bytes += skb->len; -+ stats->tx_packets++; -+ -+ skb->imq_flags = 0; -+ skb->destructor = NULL; -+ -+ dev->trans_start = jiffies; -+ nf_reinject(skb, skb->nf_info, NF_ACCEPT); -+ return 0; -+} -+ -+static int imq_nf_queue(struct sk_buff *skb, struct nf_info *info, unsigned queue_num, void *data) -+{ -+ struct net_device *dev; -+ struct net_device_stats *stats; -+ struct sk_buff *skb2 = NULL; -+ struct Qdisc *q; -+ unsigned int index = skb->imq_flags&IMQ_F_IFMASK; -+ int ret = -1; -+ -+ if (index > numdevs) -+ return -1; -+ -+ dev = imq_devs + index; -+ if (!(dev->flags & IFF_UP)) { -+ skb->imq_flags = 0; -+ nf_reinject(skb, info, NF_ACCEPT); -+ return 0; -+ } -+ dev->last_rx = jiffies; -+ -+ if (skb->destructor) { -+ skb2 = skb; -+ skb = skb_clone(skb, GFP_ATOMIC); -+ if (!skb) -+ return -1; -+ } -+ skb->nf_info = info; -+ -+ stats = (struct net_device_stats *)dev->priv; -+ stats->rx_bytes+= skb->len; -+ stats->rx_packets++; -+ -+ spin_lock_bh(&dev->queue_lock); -+ q = dev->qdisc; -+ if (q->enqueue) { -+ q->enqueue(skb_get(skb), q); -+ if (skb_shared(skb)) { -+ skb->destructor = imq_skb_destructor; -+ kfree_skb(skb); -+ ret = 0; -+ } -+ } -+ if (spin_is_locked(&dev->_xmit_lock)) -+ netif_schedule(dev); -+ else -+ while (!netif_queue_stopped(dev) && qdisc_restart1(dev) < 0) -+ /* NOTHING */; -+ -+ spin_unlock_bh(&dev->queue_lock); -+ -+ if (skb2) -+ kfree_skb(ret ? skb : skb2); -+ -+ return ret; -+} -+ -+static struct nf_queue_handler nfqh = { -+ .name = "imq", -+ .outfn = imq_nf_queue, -+}; -+ -+static unsigned int imq_nf_hook(unsigned int hook, struct sk_buff *pskb, -+ const struct net_device *indev, -+ const struct net_device *outdev, -+ int (*okfn)(struct sk_buff *)) -+{ -+ if (pskb->imq_flags & IMQ_F_ENQUEUE) -+ return NF_QUEUE; -+ -+ return NF_ACCEPT; -+} -+ -+ -+static int __init imq_init_hooks(void) -+{ -+ int err; -+ -+ err = nf_register_queue_handler(PF_INET, &nfqh); -+ if (err > 0) -+ goto err1; -+ if ((err = nf_register_hook(&imq_ingress_ipv4))) -+ goto err2; -+ if ((err = nf_register_hook(&imq_egress_ipv4))) -+ goto err3; -+#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) -+ if ((err = nf_register_queue_handler(PF_INET6, &nfqh))) -+ goto err4; -+ if ((err = nf_register_hook(&imq_ingress_ipv6))) -+ goto err5; -+ if ((err = nf_register_hook(&imq_egress_ipv6))) -+ goto err6; -+#endif -+ -+ return 0; -+ -+#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) -+err6: -+ nf_unregister_hook(&imq_ingress_ipv6); -+err5: -+ nf_unregister_queue_handler(PF_INET6, &nfqh); -+err4: -+ nf_unregister_hook(&imq_egress_ipv4); -+#endif -+err3: -+ nf_unregister_hook(&imq_ingress_ipv4); -+err2: -+ nf_unregister_queue_handler(PF_INET, &nfqh); -+err1: -+ return err; -+} -+ -+static void __exit imq_unhook(void) -+{ -+#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) -+ nf_unregister_hook(&imq_ingress_ipv6); -+ nf_unregister_hook(&imq_egress_ipv6); -+ nf_unregister_queue_handler(PF_INET6, &nfqh); -+#endif -+ nf_unregister_hook(&imq_ingress_ipv4); -+ nf_unregister_hook(&imq_egress_ipv4); -+ nf_unregister_queue_handler(PF_INET, &nfqh); -+} -+ -+static int __init imq_dev_init(struct net_device *dev) -+{ -+ dev->hard_start_xmit = imq_dev_xmit; -+ dev->type = ARPHRD_VOID; -+ dev->mtu = 16000; -+ dev->tx_queue_len = 11000; -+ dev->flags = IFF_NOARP; -+ dev->priv = kzalloc(sizeof(struct net_device_stats), GFP_KERNEL); -+ if (dev->priv == NULL) -+ return -ENOMEM; -+ dev->get_stats = imq_get_stats; -+ -+ return 0; -+} -+ -+static void imq_dev_uninit(struct net_device *dev) -+{ -+ kfree(dev->priv); -+} -+ -+static int __init imq_init_devs(struct net *net) -+{ -+ struct net_device *dev; -+ int i,j; -+ j = numdevs; -+ -+ if (!numdevs || numdevs > IMQ_MAX_DEVS) { -+ printk(KERN_ERR "IMQ: numdevs has to be betweed 1 and %u\n", -+ IMQ_MAX_DEVS); -+ return -EINVAL; -+ } -+ -+ imq_devs = kzalloc(sizeof(struct net_device) * numdevs, GFP_KERNEL); -+ if (!imq_devs) -+ return -ENOMEM; -+ -+ /* we start counting at zero */ -+ numdevs--; -+ -+ for (i = 0, dev = imq_devs; i <= numdevs; i++, dev++) { -+ strcpy(dev->name, "imq%d"); -+ dev->init = imq_dev_init; -+ dev->uninit = imq_dev_uninit; -+ dev->nd_net = net; -+ -+ if (register_netdev(dev) < 0) -+ goto err_register; -+ } -+ printk(KERN_INFO "IMQ starting with %u devices...\n", j); -+ return 0; -+ -+err_register: -+ for (; i; i--) -+ unregister_netdev(--dev); -+ kfree(imq_devs); -+ return -EIO; -+} -+ -+static void imq_cleanup_devs(void) -+{ -+ int i; -+ struct net_device *dev = imq_devs; -+ -+ for (i = 0; i <= numdevs; i++) -+ unregister_netdev(dev++); -+ -+ kfree(imq_devs); -+} -+ -+static __net_init int imq_init_module(struct net *net) -+{ -+ int err; -+ -+ if ((err = imq_init_devs(net))) { -+ printk(KERN_ERR "IMQ: Error trying imq_init_devs(net)\n"); -+ return err; -+ } -+ if ((err = imq_init_hooks())) { -+ printk(KERN_ERR "IMQ: Error trying imq_init_hooks()\n"); -+ imq_cleanup_devs(); -+ return err; -+ } -+ -+ printk(KERN_INFO "IMQ driver loaded successfully.\n"); -+ -+#if defined(CONFIG_IMQ_BEHAVIOR_BA) || defined(CONFIG_IMQ_BEHAVIOR_BB) -+ printk(KERN_INFO "\tHooking IMQ before NAT on PREROUTING.\n"); -+#else -+ printk(KERN_INFO "\tHooking IMQ after NAT on PREROUTING.\n"); -+#endif -+#if defined(CONFIG_IMQ_BEHAVIOR_AB) || defined(CONFIG_IMQ_BEHAVIOR_BB) -+ printk(KERN_INFO "\tHooking IMQ before NAT on POSTROUTING.\n"); -+#else -+ printk(KERN_INFO "\tHooking IMQ after NAT on POSTROUTING.\n"); -+#endif -+ -+ return 0; -+} -+ -+static __net_exit void imq_exit_module(struct net *net) -+{ -+ imq_unhook(); -+ imq_cleanup_devs(); -+ printk(KERN_INFO "IMQ driver unloaded successfully.\n"); -+} -+ -+static struct pernet_operations __net_initdata imq_net_ops = { -+ .init = imq_init_module, -+ .exit = imq_exit_module, -+}; -+ -+static int __init imq_init(void) -+{ -+ return register_pernet_device(&imq_net_ops); -+} -+ -+module_init(imq_init); -+//module_exit(imq_cleanup_module); -+ -+module_param(numdevs, int, 0); -+MODULE_PARM_DESC(numdevs, "number of IMQ devices (how many imq* devices will be created)"); -+MODULE_AUTHOR("http://www.linuximq.net"); -+MODULE_DESCRIPTION("Pseudo-driver for the intermediate queue device. See http://www.linuximq.net/ for more information."); -+MODULE_LICENSE("GPL"); ---- a/drivers/net/Kconfig -+++ b/drivers/net/Kconfig -@@ -112,6 +112,129 @@ config EQUALIZER - To compile this driver as a module, choose M here: the module - will be called eql. If unsure, say N. - -+config IMQ -+ tristate "IMQ (intermediate queueing device) support" -+ depends on NETDEVICES && NETFILTER -+ ---help--- -+ The IMQ device(s) is used as placeholder for QoS queueing -+ disciplines. Every packet entering/leaving the IP stack can be -+ directed through the IMQ device where it's enqueued/dequeued to the -+ attached qdisc. This allows you to treat network devices as classes -+ and distribute bandwidth among them. Iptables is used to specify -+ through which IMQ device, if any, packets travel. -+ -+ More information at: http://www.linuximq.net/ -+ -+ To compile this driver as a module, choose M here: the module -+ will be called imq. If unsure, say N. -+ -+choice -+ prompt "IMQ behavior (PRE/POSTROUTING)" -+ depends on IMQ -+ default IMQ_BEHAVIOR_BB -+ help -+ -+ This settings defines how IMQ behaves in respect to its -+ hooking in PREROUTING and POSTROUTING. -+ -+ IMQ can work in any of the following ways: -+ -+ PREROUTING | POSTROUTING -+ -----------------|------------------- -+ #1 After NAT | After NAT -+ #2 After NAT | Before NAT -+ #3 Before NAT | After NAT -+ #4 Before NAT | Before NAT -+ -+ The default behavior is to hook before NAT on PREROUTING -+ and after NAT on POSTROUTING (#3). -+ -+ This settings are specially usefull when trying to use IMQ -+ to shape NATed clients. -+ -+ More information can be found at: www.linuximq.net -+ -+ If not sure leave the default settings alone. -+ -+config IMQ_BEHAVIOR_AA -+ bool "IMQ AA" -+ help -+ This settings defines how IMQ behaves in respect to its -+ hooking in PREROUTING and POSTROUTING. -+ -+ Choosing this option will make IMQ hook like this: -+ -+ PREROUTING: After NAT -+ POSTROUTING: After NAT -+ -+ More information can be found at: www.linuximq.net -+ -+ If not sure leave the default settings alone. -+ -+config IMQ_BEHAVIOR_AB -+ bool "IMQ AB" -+ help -+ This settings defines how IMQ behaves in respect to its -+ hooking in PREROUTING and POSTROUTING. -+ -+ Choosing this option will make IMQ hook like this: -+ -+ PREROUTING: After NAT -+ POSTROUTING: Before NAT -+ -+ More information can be found at: www.linuximq.net -+ -+ If not sure leave the default settings alone. -+ -+config IMQ_BEHAVIOR_BA -+ bool "IMQ BA" -+ help -+ This settings defines how IMQ behaves in respect to its -+ hooking in PREROUTING and POSTROUTING. -+ -+ Choosing this option will make IMQ hook like this: -+ -+ PREROUTING: Before NAT -+ POSTROUTING: After NAT -+ -+ More information can be found at: www.linuximq.net -+ -+ If not sure leave the default settings alone. -+ -+config IMQ_BEHAVIOR_BB -+ bool "IMQ BB" -+ help -+ This settings defines how IMQ behaves in respect to its -+ hooking in PREROUTING and POSTROUTING. -+ -+ Choosing this option will make IMQ hook like this: -+ -+ PREROUTING: Before NAT -+ POSTROUTING: Before NAT -+ -+ More information can be found at: www.linuximq.net -+ -+ If not sure leave the default settings alone. -+ -+endchoice -+ -+config IMQ_NUM_DEVS -+ -+ int "Number of IMQ devices" -+ range 2 16 -+ depends on IMQ -+ default "16" -+ help -+ -+ This settings defines how many IMQ devices will be -+ created. -+ -+ The default value is 16. -+ -+ More information can be found at: www.linuximq.net -+ -+ If not sure leave the default settings alone. -+ - config TUN - tristate "Universal TUN/TAP device driver support" - select CRC32 ---- a/drivers/net/Makefile -+++ b/drivers/net/Makefile -@@ -139,6 +139,7 @@ obj-$(CONFIG_SLHC) += slhc.o - obj-$(CONFIG_XEN_NETDEV_FRONTEND) += xen-netfront.o - - obj-$(CONFIG_DUMMY) += dummy.o -+obj-$(CONFIG_IMQ) += imq.o - obj-$(CONFIG_IFB) += ifb.o - obj-$(CONFIG_MACVLAN) += macvlan.o - obj-$(CONFIG_DE600) += de600.o ---- /dev/null -+++ b/include/linux/imq.h -@@ -0,0 +1,9 @@ -+#ifndef _IMQ_H -+#define _IMQ_H -+ -+#define IMQ_MAX_DEVS 16 -+ -+#define IMQ_F_IFMASK 0x7f -+#define IMQ_F_ENQUEUE 0x80 -+ -+#endif /* _IMQ_H */ ---- /dev/null -+++ b/include/linux/netfilter_ipv4/ipt_IMQ.h -@@ -0,0 +1,8 @@ -+#ifndef _IPT_IMQ_H -+#define _IPT_IMQ_H -+ -+struct ipt_imq_info { -+ unsigned int todev; /* target imq device */ -+}; -+ -+#endif /* _IPT_IMQ_H */ ---- /dev/null -+++ b/include/linux/netfilter_ipv6/ip6t_IMQ.h -@@ -0,0 +1,8 @@ -+#ifndef _IP6T_IMQ_H -+#define _IP6T_IMQ_H -+ -+struct ip6t_imq_info { -+ unsigned int todev; /* target imq device */ -+}; -+ -+#endif /* _IP6T_IMQ_H */ ---- a/include/linux/skbuff.h -+++ b/include/linux/skbuff.h -@@ -295,6 +295,10 @@ struct sk_buff { - struct nf_conntrack *nfct; - struct sk_buff *nfct_reasm; - #endif -+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) -+ unsigned char imq_flags; -+ struct nf_info *nf_info; -+#endif - #ifdef CONFIG_BRIDGE_NETFILTER - struct nf_bridge_info *nf_bridge; - #endif -@@ -1728,6 +1732,10 @@ static inline void __nf_copy(struct sk_b - dst->nfct_reasm = src->nfct_reasm; - nf_conntrack_get_reasm(src->nfct_reasm); - #endif -+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) -+ dst->imq_flags = src->imq_flags; -+ dst->nf_info = src->nf_info; -+#endif - #ifdef CONFIG_BRIDGE_NETFILTER - dst->nf_bridge = src->nf_bridge; - nf_bridge_get(src->nf_bridge); ---- a/net/core/dev.c -+++ b/net/core/dev.c -@@ -95,6 +95,9 @@ - #include - #include - #include -+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) -+#include -+#endif - #include - #include - #include -@@ -1533,7 +1536,11 @@ static int dev_gso_segment(struct sk_buf - int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) - { - if (likely(!skb->next)) { -- if (!list_empty(&ptype_all)) -+ if (!list_empty(&ptype_all) -+#if defined(CONFIG_IMQ) || defined(CONFIG_IMQ_MODULE) -+ && !(skb->imq_flags & IMQ_F_ENQUEUE) -+#endif -+ ) - dev_queue_xmit_nit(skb, dev); - - if (netif_needs_gso(dev, skb)) { ---- /dev/null -+++ b/net/ipv4/netfilter/ipt_IMQ.c -@@ -0,0 +1,69 @@ -+/* -+ * This target marks packets to be enqueued to an imq device -+ */ -+#include -+#include -+#include -+#include -+#include -+ -+static unsigned int imq_target(struct sk_buff *pskb, -+ const struct net_device *in, -+ const struct net_device *out, -+ unsigned int hooknum, -+ const struct xt_target *target, -+ const void *targinfo) -+{ -+ struct ipt_imq_info *mr = (struct ipt_imq_info*)targinfo; -+ -+ pskb->imq_flags = mr->todev | IMQ_F_ENQUEUE; -+ -+ return XT_CONTINUE; -+} -+ -+static bool imq_checkentry(const char *tablename, -+ const void *e, -+ const struct xt_target *target, -+ void *targinfo, -+ unsigned int hook_mask) -+{ -+ struct ipt_imq_info *mr; -+ -+ mr = (struct ipt_imq_info*)targinfo; -+ -+ if (mr->todev > IMQ_MAX_DEVS) { -+ printk(KERN_WARNING -+ "IMQ: invalid device specified, highest is %u\n", -+ IMQ_MAX_DEVS); -+ return 0; -+ } -+ -+ return 1; -+} -+ -+static struct xt_target ipt_imq_reg = { -+ .name = "IMQ", -+ .family = AF_INET, -+ .target = imq_target, -+ .targetsize = sizeof(struct ipt_imq_info), -+ .checkentry = imq_checkentry, -+ .me = THIS_MODULE, -+ .table = "mangle" -+}; -+ -+static int __init init(void) -+{ -+ return xt_register_target(&ipt_imq_reg); -+} -+ -+static void __exit fini(void) -+{ -+ xt_unregister_target(&ipt_imq_reg); -+} -+ -+module_init(init); -+module_exit(fini); -+ -+MODULE_AUTHOR("http://www.linuximq.net"); -+MODULE_DESCRIPTION("Pseudo-driver for the intermediate queue device. See http://www.linuximq.net/ for more information."); -+MODULE_LICENSE("GPL"); ---- a/net/ipv4/netfilter/Kconfig -+++ b/net/ipv4/netfilter/Kconfig -@@ -327,6 +327,17 @@ config IP_NF_MANGLE - - To compile it as a module, choose M here. If unsure, say N. - -+config IP_NF_TARGET_IMQ -+ tristate "IMQ target support" -+ depends on IP_NF_MANGLE -+ help -+ This option adds a `IMQ' target which is used to specify if and -+ to which IMQ device packets should get enqueued/dequeued. -+ -+ For more information visit: http://www.linuximq.net/ -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ - config IP_NF_TARGET_TOS - tristate "TOS target support" - depends on IP_NF_MANGLE ---- a/net/ipv4/netfilter/Makefile -+++ b/net/ipv4/netfilter/Makefile -@@ -56,6 +56,7 @@ obj-$(CONFIG_IP_NF_MATCH_TIME) += ipt_ti - obj-$(CONFIG_IP_NF_TARGET_CLUSTERIP) += ipt_CLUSTERIP.o - obj-$(CONFIG_IP_NF_TARGET_ECN) += ipt_ECN.o - obj-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG.o -+obj-$(CONFIG_IP_NF_TARGET_IMQ) += ipt_IMQ.o - obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o - obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o - obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o ---- /dev/null -+++ b/net/ipv6/netfilter/ip6t_IMQ.c -@@ -0,0 +1,69 @@ -+/* -+ * This target marks packets to be enqueued to an imq device -+ */ -+#include -+#include -+#include -+#include -+#include -+ -+static unsigned int imq_target(struct sk_buff *pskb, -+ const struct net_device *in, -+ const struct net_device *out, -+ unsigned int hooknum, -+ const struct xt_target *target, -+ const void *targinfo) -+{ -+ struct ip6t_imq_info *mr = (struct ip6t_imq_info*)targinfo; -+ -+ pskb->imq_flags = mr->todev | IMQ_F_ENQUEUE; -+ -+ return XT_CONTINUE; -+} -+ -+static bool imq_checkentry(const char *tablename, -+ const void *entry, -+ const struct xt_target *target, -+ void *targinfo, -+ unsigned int hook_mask) -+{ -+ struct ip6t_imq_info *mr; -+ -+ mr = (struct ip6t_imq_info*)targinfo; -+ -+ if (mr->todev > IMQ_MAX_DEVS) { -+ printk(KERN_WARNING -+ "IMQ: invalid device specified, highest is %u\n", -+ IMQ_MAX_DEVS); -+ return 0; -+ } -+ -+ return 1; -+} -+ -+static struct xt_target ip6t_imq_reg = { -+ .name = "IMQ", -+ .family = AF_INET6, -+ .target = imq_target, -+ .targetsize = sizeof(struct ip6t_imq_info), -+ .table = "mangle", -+ .checkentry = imq_checkentry, -+ .me = THIS_MODULE -+}; -+ -+static int __init init(void) -+{ -+ return xt_register_target(&ip6t_imq_reg); -+} -+ -+static void __exit fini(void) -+{ -+ xt_unregister_target(&ip6t_imq_reg); -+} -+ -+module_init(init); -+module_exit(fini); -+ -+MODULE_AUTHOR("http://www.linuximq.net"); -+MODULE_DESCRIPTION("Pseudo-driver for the intermediate queue device. See http://www.linuximq.net/ for more information."); -+MODULE_LICENSE("GPL"); ---- a/net/ipv6/netfilter/Kconfig -+++ b/net/ipv6/netfilter/Kconfig -@@ -173,6 +173,15 @@ config IP6_NF_MANGLE - - To compile it as a module, choose M here. If unsure, say N. - -+config IP6_NF_TARGET_IMQ -+ tristate "IMQ target support" -+ depends on IP6_NF_MANGLE -+ help -+ This option adds a `IMQ' target which is used to specify if and -+ to which imq device packets should get enqueued/dequeued. -+ -+ To compile it as a module, choose M here. If unsure, say N. -+ - config IP6_NF_TARGET_HL - tristate 'HL (hoplimit) target support' - depends on IP6_NF_MANGLE ---- a/net/ipv6/netfilter/Makefile -+++ b/net/ipv6/netfilter/Makefile -@@ -6,6 +6,7 @@ - obj-$(CONFIG_IP6_NF_IPTABLES) += ip6_tables.o - obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o - obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o -+obj-$(CONFIG_IP6_NF_TARGET_IMQ) += ip6t_IMQ.o - obj-$(CONFIG_IP6_NF_QUEUE) += ip6_queue.o - obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o - ---- a/net/sched/sch_generic.c -+++ b/net/sched/sch_generic.c -@@ -176,6 +176,11 @@ static inline int qdisc_restart(struct n - return ret; - } - -+int qdisc_restart1(struct net_device *dev) -+{ -+ return qdisc_restart(dev); -+} -+ - void __qdisc_run(struct net_device *dev) - { - unsigned long start_time = jiffies; -@@ -650,3 +655,4 @@ EXPORT_SYMBOL(qdisc_destroy); - EXPORT_SYMBOL(qdisc_reset); - EXPORT_SYMBOL(qdisc_lock_tree); - EXPORT_SYMBOL(qdisc_unlock_tree); -+EXPORT_SYMBOL(qdisc_restart1); diff --git a/target/linux/generic-2.6/patches-2.6.24/180-netfilter_depends.patch b/target/linux/generic-2.6/patches-2.6.24/180-netfilter_depends.patch deleted file mode 100644 index dee5eb7664..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/180-netfilter_depends.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- a/net/netfilter/Kconfig -+++ b/net/netfilter/Kconfig -@@ -143,7 +143,7 @@ config NF_CONNTRACK_FTP - - config NF_CONNTRACK_H323 - tristate "H.323 protocol support (EXPERIMENTAL)" -- depends on EXPERIMENTAL && NF_CONNTRACK && (IPV6 || IPV6=n) -+ depends on EXPERIMENTAL && NF_CONNTRACK - help - H.323 is a VoIP signalling protocol from ITU-T. As one of the most - important VoIP protocols, it is widely used by voice hardware and -@@ -387,7 +387,7 @@ config NETFILTER_XT_TARGET_CONNSECMARK - - config NETFILTER_XT_TARGET_TCPMSS - tristate '"TCPMSS" target support' -- depends on NETFILTER_XTABLES && (IPV6 || IPV6=n) -+ depends on NETFILTER_XTABLES - ---help--- - This option adds a `TCPMSS' target, which allows you to alter the - MSS value of TCP SYN packets, to control the maximum size for that diff --git a/target/linux/generic-2.6/patches-2.6.24/190-netfilter_rtsp.patch b/target/linux/generic-2.6/patches-2.6.24/190-netfilter_rtsp.patch deleted file mode 100644 index 182d0d6548..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/190-netfilter_rtsp.patch +++ /dev/null @@ -1,1362 +0,0 @@ ---- /dev/null -+++ b/include/linux/netfilter/nf_conntrack_rtsp.h -@@ -0,0 +1,63 @@ -+/* -+ * RTSP extension for IP connection tracking. -+ * (C) 2003 by Tom Marshall -+ * based on ip_conntrack_irc.h -+ * -+ * 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 _IP_CONNTRACK_RTSP_H -+#define _IP_CONNTRACK_RTSP_H -+ -+//#define IP_NF_RTSP_DEBUG 1 -+#define IP_NF_RTSP_VERSION "0.6.21" -+ -+#ifdef __KERNEL__ -+/* port block types */ -+typedef enum { -+ pb_single, /* client_port=x */ -+ pb_range, /* client_port=x-y */ -+ pb_discon /* client_port=x/y (rtspbis) */ -+} portblock_t; -+ -+/* We record seq number and length of rtsp headers here, all in host order. */ -+ -+/* -+ * This structure is per expected connection. It is a member of struct -+ * ip_conntrack_expect. The TCP SEQ for the conntrack expect is stored -+ * there and we are expected to only store the length of the data which -+ * needs replaced. If a packet contains multiple RTSP messages, we create -+ * one expected connection per message. -+ * -+ * We use these variables to mark the entire header block. This may seem -+ * like overkill, but the nature of RTSP requires it. A header may appear -+ * multiple times in a message. We must treat two Transport headers the -+ * same as one Transport header with two entries. -+ */ -+struct ip_ct_rtsp_expect -+{ -+ u_int32_t len; /* length of header block */ -+ portblock_t pbtype; /* Type of port block that was requested */ -+ u_int16_t loport; /* Port that was requested, low or first */ -+ u_int16_t hiport; /* Port that was requested, high or second */ -+#if 0 -+ uint method; /* RTSP method */ -+ uint cseq; /* CSeq from request */ -+#endif -+}; -+ -+extern unsigned int (*nf_nat_rtsp_hook)(struct sk_buff *skb, -+ enum ip_conntrack_info ctinfo, -+ unsigned int matchoff, unsigned int matchlen, -+ struct ip_ct_rtsp_expect *prtspexp, -+ struct nf_conntrack_expect *exp); -+ -+extern void (*nf_nat_rtsp_hook_expectfn)(struct nf_conn *ct, struct nf_conntrack_expect *exp); -+ -+#define RTSP_PORT 554 -+ -+#endif /* __KERNEL__ */ -+ -+#endif /* _IP_CONNTRACK_RTSP_H */ ---- /dev/null -+++ b/include/linux/netfilter_helpers.h -@@ -0,0 +1,133 @@ -+/* -+ * Helpers for netfiler modules. This file provides implementations for basic -+ * functions such as strncasecmp(), etc. -+ * -+ * gcc will warn for defined but unused functions, so we only include the -+ * functions requested. The following macros are used: -+ * NF_NEED_STRNCASECMP nf_strncasecmp() -+ * NF_NEED_STRTOU16 nf_strtou16() -+ * NF_NEED_STRTOU32 nf_strtou32() -+ */ -+#ifndef _NETFILTER_HELPERS_H -+#define _NETFILTER_HELPERS_H -+ -+/* Only include these functions for kernel code. */ -+#ifdef __KERNEL__ -+ -+#include -+#define iseol(c) ( (c) == '\r' || (c) == '\n' ) -+ -+/* -+ * The standard strncasecmp() -+ */ -+#ifdef NF_NEED_STRNCASECMP -+static int -+nf_strncasecmp(const char* s1, const char* s2, u_int32_t len) -+{ -+ if (s1 == NULL || s2 == NULL) -+ { -+ if (s1 == NULL && s2 == NULL) -+ { -+ return 0; -+ } -+ return (s1 == NULL) ? -1 : 1; -+ } -+ while (len > 0 && tolower(*s1) == tolower(*s2)) -+ { -+ len--; -+ s1++; -+ s2++; -+ } -+ return ( (len == 0) ? 0 : (tolower(*s1) - tolower(*s2)) ); -+} -+#endif /* NF_NEED_STRNCASECMP */ -+ -+/* -+ * Parse a string containing a 16-bit unsigned integer. -+ * Returns the number of chars used, or zero if no number is found. -+ */ -+#ifdef NF_NEED_STRTOU16 -+static int -+nf_strtou16(const char* pbuf, u_int16_t* pval) -+{ -+ int n = 0; -+ -+ *pval = 0; -+ while (isdigit(pbuf[n])) -+ { -+ *pval = (*pval * 10) + (pbuf[n] - '0'); -+ n++; -+ } -+ -+ return n; -+} -+#endif /* NF_NEED_STRTOU16 */ -+ -+/* -+ * Parse a string containing a 32-bit unsigned integer. -+ * Returns the number of chars used, or zero if no number is found. -+ */ -+#ifdef NF_NEED_STRTOU32 -+static int -+nf_strtou32(const char* pbuf, u_int32_t* pval) -+{ -+ int n = 0; -+ -+ *pval = 0; -+ while (pbuf[n] >= '0' && pbuf[n] <= '9') -+ { -+ *pval = (*pval * 10) + (pbuf[n] - '0'); -+ n++; -+ } -+ -+ return n; -+} -+#endif /* NF_NEED_STRTOU32 */ -+ -+/* -+ * Given a buffer and length, advance to the next line and mark the current -+ * line. -+ */ -+#ifdef NF_NEED_NEXTLINE -+static int -+nf_nextline(char* p, uint len, uint* poff, uint* plineoff, uint* plinelen) -+{ -+ uint off = *poff; -+ uint physlen = 0; -+ -+ if (off >= len) -+ { -+ return 0; -+ } -+ -+ while (p[off] != '\n') -+ { -+ if (len-off <= 1) -+ { -+ return 0; -+ } -+ -+ physlen++; -+ off++; -+ } -+ -+ /* if we saw a crlf, physlen needs adjusted */ -+ if (physlen > 0 && p[off] == '\n' && p[off-1] == '\r') -+ { -+ physlen--; -+ } -+ -+ /* advance past the newline */ -+ off++; -+ -+ *plineoff = *poff; -+ *plinelen = physlen; -+ *poff = off; -+ -+ return 1; -+} -+#endif /* NF_NEED_NEXTLINE */ -+ -+#endif /* __KERNEL__ */ -+ -+#endif /* _NETFILTER_HELPERS_H */ ---- /dev/null -+++ b/include/linux/netfilter_mime.h -@@ -0,0 +1,89 @@ -+/* -+ * MIME functions for netfilter modules. This file provides implementations -+ * for basic MIME parsing. MIME headers are used in many protocols, such as -+ * HTTP, RTSP, SIP, etc. -+ * -+ * gcc will warn for defined but unused functions, so we only include the -+ * functions requested. The following macros are used: -+ * NF_NEED_MIME_NEXTLINE nf_mime_nextline() -+ */ -+#ifndef _NETFILTER_MIME_H -+#define _NETFILTER_MIME_H -+ -+/* Only include these functions for kernel code. */ -+#ifdef __KERNEL__ -+ -+#include -+ -+/* -+ * Given a buffer and length, advance to the next line and mark the current -+ * line. If the current line is empty, *plinelen will be set to zero. If -+ * not, it will be set to the actual line length (including CRLF). -+ * -+ * 'line' in this context means logical line (includes LWS continuations). -+ * Returns 1 on success, 0 on failure. -+ */ -+#ifdef NF_NEED_MIME_NEXTLINE -+static int -+nf_mime_nextline(char* p, uint len, uint* poff, uint* plineoff, uint* plinelen) -+{ -+ uint off = *poff; -+ uint physlen = 0; -+ int is_first_line = 1; -+ -+ if (off >= len) -+ { -+ return 0; -+ } -+ -+ do -+ { -+ while (p[off] != '\n') -+ { -+ if (len-off <= 1) -+ { -+ return 0; -+ } -+ -+ physlen++; -+ off++; -+ } -+ -+ /* if we saw a crlf, physlen needs adjusted */ -+ if (physlen > 0 && p[off] == '\n' && p[off-1] == '\r') -+ { -+ physlen--; -+ } -+ -+ /* advance past the newline */ -+ off++; -+ -+ /* check for an empty line */ -+ if (physlen == 0) -+ { -+ break; -+ } -+ -+ /* check for colon on the first physical line */ -+ if (is_first_line) -+ { -+ is_first_line = 0; -+ if (memchr(p+(*poff), ':', physlen) == NULL) -+ { -+ return 0; -+ } -+ } -+ } -+ while (p[off] == ' ' || p[off] == '\t'); -+ -+ *plineoff = *poff; -+ *plinelen = (physlen == 0) ? 0 : (off - *poff); -+ *poff = off; -+ -+ return 1; -+} -+#endif /* NF_NEED_MIME_NEXTLINE */ -+ -+#endif /* __KERNEL__ */ -+ -+#endif /* _NETFILTER_MIME_H */ ---- a/net/ipv4/netfilter/Makefile -+++ b/net/ipv4/netfilter/Makefile -@@ -23,6 +23,7 @@ obj-$(CONFIG_NF_NAT_AMANDA) += nf_nat_am - obj-$(CONFIG_NF_NAT_FTP) += nf_nat_ftp.o - obj-$(CONFIG_NF_NAT_H323) += nf_nat_h323.o - obj-$(CONFIG_NF_NAT_IRC) += nf_nat_irc.o -+obj-$(CONFIG_NF_NAT_RTSP) += nf_nat_rtsp.o - obj-$(CONFIG_NF_NAT_PPTP) += nf_nat_pptp.o - obj-$(CONFIG_NF_NAT_SIP) += nf_nat_sip.o - obj-$(CONFIG_NF_NAT_SNMP_BASIC) += nf_nat_snmp_basic.o ---- a/net/netfilter/Kconfig -+++ b/net/netfilter/Kconfig -@@ -249,6 +249,16 @@ config NF_CONNTRACK_TFTP - - To compile it as a module, choose M here. If unsure, say N. - -+config NF_CONNTRACK_RTSP -+ tristate "RTSP protocol support" -+ depends on NF_CONNTRACK -+ help -+ Support the RTSP protocol. This allows UDP transports to be setup -+ properly, including RTP and RDT. -+ -+ If you want to compile it as a module, say 'M' here and read -+ Documentation/modules.txt. If unsure, say 'Y'. -+ - config NF_CT_NETLINK - tristate 'Connection tracking netlink interface (EXPERIMENTAL)' - depends on EXPERIMENTAL && NF_CONNTRACK && NETFILTER_NETLINK ---- a/net/netfilter/Makefile -+++ b/net/netfilter/Makefile -@@ -33,6 +33,7 @@ obj-$(CONFIG_NF_CONNTRACK_PPTP) += nf_co - obj-$(CONFIG_NF_CONNTRACK_SANE) += nf_conntrack_sane.o - obj-$(CONFIG_NF_CONNTRACK_SIP) += nf_conntrack_sip.o - obj-$(CONFIG_NF_CONNTRACK_TFTP) += nf_conntrack_tftp.o -+obj-$(CONFIG_NF_CONNTRACK_RTSP) += nf_conntrack_rtsp.o - - # generic X tables - obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o ---- a/net/ipv4/netfilter/Kconfig -+++ b/net/ipv4/netfilter/Kconfig -@@ -290,6 +290,11 @@ config NF_NAT_IRC - depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT - default NF_NAT && NF_CONNTRACK_IRC - -+config NF_NAT_RTSP -+ tristate -+ depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT -+ default NF_NAT && NF_CONNTRACK_RTSP -+ - config NF_NAT_TFTP - tristate - depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT ---- /dev/null -+++ b/net/netfilter/nf_conntrack_rtsp.c -@@ -0,0 +1,513 @@ -+/* -+ * RTSP extension for IP connection tracking -+ * (C) 2003 by Tom Marshall -+ * based on ip_conntrack_irc.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. -+ * -+ * Module load syntax: -+ * insmod nf_conntrack_rtsp.o ports=port1,port2,...port -+ * max_outstanding=n setup_timeout=secs -+ * -+ * If no ports are specified, the default will be port 554. -+ * -+ * With max_outstanding you can define the maximum number of not yet -+ * answered SETUP requests per RTSP session (default 8). -+ * With setup_timeout you can specify how long the system waits for -+ * an expected data channel (default 300 seconds). -+ * -+ * 2005-02-13: Harald Welte -+ * - port to 2.6 -+ * - update to recent post-2.6.11 api changes -+ * 2006-09-14: Steven Van Acker -+ * - removed calls to NAT code from conntrack helper: NAT no longer needed to use rtsp-conntrack -+ * 2007-04-18: Michael Guntsche -+ * - Port to new NF API -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#define NF_NEED_STRNCASECMP -+#define NF_NEED_STRTOU16 -+#define NF_NEED_STRTOU32 -+#define NF_NEED_NEXTLINE -+#include -+#define NF_NEED_MIME_NEXTLINE -+#include -+ -+#include -+#define MAX_SIMUL_SETUP 8 /* XXX: use max_outstanding */ -+#define INFOP(fmt, args...) printk(KERN_INFO "%s: %s: " fmt, __FILE__, __FUNCTION__ , ## args) -+#if 0 -+#define DEBUGP(fmt, args...) printk(KERN_DEBUG "%s: %s: " fmt, __FILE__, __FUNCTION__ , ## args) -+#else -+#define DEBUGP(fmt, args...) -+#endif -+ -+#define MAX_PORTS 8 -+static int ports[MAX_PORTS]; -+static int num_ports = 0; -+static int max_outstanding = 8; -+static unsigned int setup_timeout = 300; -+ -+MODULE_AUTHOR("Tom Marshall "); -+MODULE_DESCRIPTION("RTSP connection tracking module"); -+MODULE_LICENSE("GPL"); -+module_param_array(ports, int, &num_ports, 0400); -+MODULE_PARM_DESC(ports, "port numbers of RTSP servers"); -+module_param(max_outstanding, int, 0400); -+MODULE_PARM_DESC(max_outstanding, "max number of outstanding SETUP requests per RTSP session"); -+module_param(setup_timeout, int, 0400); -+MODULE_PARM_DESC(setup_timeout, "timeout on for unestablished data channels"); -+ -+static char *rtsp_buffer; -+static DEFINE_SPINLOCK(rtsp_buffer_lock); -+ -+unsigned int (*nf_nat_rtsp_hook)(struct sk_buff *skb, -+ enum ip_conntrack_info ctinfo, -+ unsigned int matchoff, unsigned int matchlen,struct ip_ct_rtsp_expect* prtspexp, -+ struct nf_conntrack_expect *exp); -+void (*nf_nat_rtsp_hook_expectfn)(struct nf_conn *ct, struct nf_conntrack_expect *exp); -+ -+EXPORT_SYMBOL_GPL(nf_nat_rtsp_hook); -+ -+/* -+ * Max mappings we will allow for one RTSP connection (for RTP, the number -+ * of allocated ports is twice this value). Note that SMIL burns a lot of -+ * ports so keep this reasonably high. If this is too low, you will see a -+ * lot of "no free client map entries" messages. -+ */ -+#define MAX_PORT_MAPS 16 -+ -+/*** default port list was here in the masq code: 554, 3030, 4040 ***/ -+ -+#define SKIP_WSPACE(ptr,len,off) while(off < len && isspace(*(ptr+off))) { off++; } -+ -+/* -+ * Parse an RTSP packet. -+ * -+ * Returns zero if parsing failed. -+ * -+ * Parameters: -+ * IN ptcp tcp data pointer -+ * IN tcplen tcp data len -+ * IN/OUT ptcpoff points to current tcp offset -+ * OUT phdrsoff set to offset of rtsp headers -+ * OUT phdrslen set to length of rtsp headers -+ * OUT pcseqoff set to offset of CSeq header -+ * OUT pcseqlen set to length of CSeq header -+ */ -+static int -+rtsp_parse_message(char* ptcp, uint tcplen, uint* ptcpoff, -+ uint* phdrsoff, uint* phdrslen, -+ uint* pcseqoff, uint* pcseqlen, -+ uint* transoff, uint* translen) -+{ -+ uint entitylen = 0; -+ uint lineoff; -+ uint linelen; -+ -+ if (!nf_nextline(ptcp, tcplen, ptcpoff, &lineoff, &linelen)) -+ return 0; -+ -+ *phdrsoff = *ptcpoff; -+ while (nf_mime_nextline(ptcp, tcplen, ptcpoff, &lineoff, &linelen)) { -+ if (linelen == 0) { -+ if (entitylen > 0) -+ *ptcpoff += min(entitylen, tcplen - *ptcpoff); -+ break; -+ } -+ if (lineoff+linelen > tcplen) { -+ INFOP("!! overrun !!\n"); -+ break; -+ } -+ -+ if (nf_strncasecmp(ptcp+lineoff, "CSeq:", 5) == 0) { -+ *pcseqoff = lineoff; -+ *pcseqlen = linelen; -+ } -+ -+ if (nf_strncasecmp(ptcp+lineoff, "Transport:", 10) == 0) { -+ *transoff = lineoff; -+ *translen = linelen; -+ } -+ -+ if (nf_strncasecmp(ptcp+lineoff, "Content-Length:", 15) == 0) { -+ uint off = lineoff+15; -+ SKIP_WSPACE(ptcp+lineoff, linelen, off); -+ nf_strtou32(ptcp+off, &entitylen); -+ } -+ } -+ *phdrslen = (*ptcpoff) - (*phdrsoff); -+ -+ return 1; -+} -+ -+/* -+ * Find lo/hi client ports (if any) in transport header -+ * In: -+ * ptcp, tcplen = packet -+ * tranoff, tranlen = buffer to search -+ * -+ * Out: -+ * pport_lo, pport_hi = lo/hi ports (host endian) -+ * -+ * Returns nonzero if any client ports found -+ * -+ * Note: it is valid (and expected) for the client to request multiple -+ * transports, so we need to parse the entire line. -+ */ -+static int -+rtsp_parse_transport(char* ptran, uint tranlen, -+ struct ip_ct_rtsp_expect* prtspexp) -+{ -+ int rc = 0; -+ uint off = 0; -+ -+ if (tranlen < 10 || !iseol(ptran[tranlen-1]) || -+ nf_strncasecmp(ptran, "Transport:", 10) != 0) { -+ INFOP("sanity check failed\n"); -+ return 0; -+ } -+ -+ DEBUGP("tran='%.*s'\n", (int)tranlen, ptran); -+ off += 10; -+ SKIP_WSPACE(ptran, tranlen, off); -+ -+ /* Transport: tran;field;field=val,tran;field;field=val,... */ -+ while (off < tranlen) { -+ const char* pparamend; -+ uint nextparamoff; -+ -+ pparamend = memchr(ptran+off, ',', tranlen-off); -+ pparamend = (pparamend == NULL) ? ptran+tranlen : pparamend+1; -+ nextparamoff = pparamend-ptran; -+ -+ while (off < nextparamoff) { -+ const char* pfieldend; -+ uint nextfieldoff; -+ -+ pfieldend = memchr(ptran+off, ';', nextparamoff-off); -+ nextfieldoff = (pfieldend == NULL) ? nextparamoff : pfieldend-ptran+1; -+ -+ if (strncmp(ptran+off, "client_port=", 12) == 0) { -+ u_int16_t port; -+ uint numlen; -+ -+ off += 12; -+ numlen = nf_strtou16(ptran+off, &port); -+ off += numlen; -+ if (prtspexp->loport != 0 && prtspexp->loport != port) -+ DEBUGP("multiple ports found, port %hu ignored\n", port); -+ else { -+ DEBUGP("lo port found : %hu\n", port); -+ prtspexp->loport = prtspexp->hiport = port; -+ if (ptran[off] == '-') { -+ off++; -+ numlen = nf_strtou16(ptran+off, &port); -+ off += numlen; -+ prtspexp->pbtype = pb_range; -+ prtspexp->hiport = port; -+ -+ // If we have a range, assume rtp: -+ // loport must be even, hiport must be loport+1 -+ if ((prtspexp->loport & 0x0001) != 0 || -+ prtspexp->hiport != prtspexp->loport+1) { -+ DEBUGP("incorrect range: %hu-%hu, correcting\n", -+ prtspexp->loport, prtspexp->hiport); -+ prtspexp->loport &= 0xfffe; -+ prtspexp->hiport = prtspexp->loport+1; -+ } -+ } else if (ptran[off] == '/') { -+ off++; -+ numlen = nf_strtou16(ptran+off, &port); -+ off += numlen; -+ prtspexp->pbtype = pb_discon; -+ prtspexp->hiport = port; -+ } -+ rc = 1; -+ } -+ } -+ -+ /* -+ * Note we don't look for the destination parameter here. -+ * If we are using NAT, the NAT module will handle it. If not, -+ * and the client is sending packets elsewhere, the expectation -+ * will quietly time out. -+ */ -+ -+ off = nextfieldoff; -+ } -+ -+ off = nextparamoff; -+ } -+ -+ return rc; -+} -+ -+void expected(struct nf_conn *ct, struct nf_conntrack_expect *exp) -+{ -+ if(nf_nat_rtsp_hook_expectfn) { -+ nf_nat_rtsp_hook_expectfn(ct,exp); -+ } -+} -+ -+/*** conntrack functions ***/ -+ -+/* outbound packet: client->server */ -+ -+static inline int -+help_out(struct sk_buff *skb, unsigned char *rb_ptr, unsigned int datalen, -+ struct nf_conn *ct, enum ip_conntrack_info ctinfo) -+{ -+ struct ip_ct_rtsp_expect expinfo; -+ -+ int dir = CTINFO2DIR(ctinfo); /* = IP_CT_DIR_ORIGINAL */ -+ //struct tcphdr* tcph = (void*)iph + iph->ihl * 4; -+ //uint tcplen = pktlen - iph->ihl * 4; -+ char* pdata = rb_ptr; -+ //uint datalen = tcplen - tcph->doff * 4; -+ uint dataoff = 0; -+ int ret = NF_ACCEPT; -+ -+ struct nf_conntrack_expect *exp; -+ -+ __be16 be_loport; -+ -+ memset(&expinfo, 0, sizeof(expinfo)); -+ -+ while (dataoff < datalen) { -+ uint cmdoff = dataoff; -+ uint hdrsoff = 0; -+ uint hdrslen = 0; -+ uint cseqoff = 0; -+ uint cseqlen = 0; -+ uint transoff = 0; -+ uint translen = 0; -+ uint off; -+ -+ if (!rtsp_parse_message(pdata, datalen, &dataoff, -+ &hdrsoff, &hdrslen, -+ &cseqoff, &cseqlen, -+ &transoff, &translen)) -+ break; /* not a valid message */ -+ -+ if (strncmp(pdata+cmdoff, "SETUP ", 6) != 0) -+ continue; /* not a SETUP message */ -+ DEBUGP("found a setup message\n"); -+ -+ off = 0; -+ if(translen) { -+ rtsp_parse_transport(pdata+transoff, translen, &expinfo); -+ } -+ -+ if (expinfo.loport == 0) { -+ DEBUGP("no udp transports found\n"); -+ continue; /* no udp transports found */ -+ } -+ -+ DEBUGP("udp transport found, ports=(%d,%hu,%hu)\n", -+ (int)expinfo.pbtype, expinfo.loport, expinfo.hiport); -+ -+ exp = nf_ct_expect_alloc(ct); -+ if (!exp) { -+ ret = NF_DROP; -+ goto out; -+ } -+ -+ be_loport = htons(expinfo.loport); -+ -+ nf_ct_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num, -+ &ct->tuplehash[!dir].tuple.src.u3, &ct->tuplehash[!dir].tuple.dst.u3, -+ IPPROTO_UDP, NULL, &be_loport); -+ -+ exp->master = ct; -+ -+ exp->expectfn = expected; -+ exp->flags = 0; -+ -+ if (expinfo.pbtype == pb_range) { -+ DEBUGP("Changing expectation mask to handle multiple ports\n"); -+ exp->mask.src.u.udp.port = 0xfffe; -+ } -+ -+ DEBUGP("expect_related %u.%u.%u.%u:%u-%u.%u.%u.%u:%u\n", -+ NIPQUAD(exp->tuple.src.u3.ip), -+ ntohs(exp->tuple.src.u.udp.port), -+ NIPQUAD(exp->tuple.dst.u3.ip), -+ ntohs(exp->tuple.dst.u.udp.port)); -+ -+ if (nf_nat_rtsp_hook) -+ /* pass the request off to the nat helper */ -+ ret = nf_nat_rtsp_hook(skb, ctinfo, hdrsoff, hdrslen, &expinfo, exp); -+ else if (nf_ct_expect_related(exp) != 0) { -+ INFOP("nf_ct_expect_related failed\n"); -+ ret = NF_DROP; -+ } -+ nf_ct_expect_put(exp); -+ goto out; -+ } -+out: -+ -+ return ret; -+} -+ -+ -+static inline int -+help_in(struct sk_buff *skb, size_t pktlen, -+ struct nf_conn* ct, enum ip_conntrack_info ctinfo) -+{ -+ return NF_ACCEPT; -+} -+ -+static int help(struct sk_buff *skb, unsigned int protoff, -+ struct nf_conn *ct, enum ip_conntrack_info ctinfo) -+{ -+ struct tcphdr _tcph, *th; -+ unsigned int dataoff, datalen; -+ char *rb_ptr; -+ int ret = NF_DROP; -+ -+ /* Until there's been traffic both ways, don't look in packets. */ -+ if (ctinfo != IP_CT_ESTABLISHED && -+ ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) { -+ DEBUGP("conntrackinfo = %u\n", ctinfo); -+ return NF_ACCEPT; -+ } -+ -+ /* Not whole TCP header? */ -+ th = skb_header_pointer(skb, protoff, sizeof(_tcph), &_tcph); -+ -+ if (!th) -+ return NF_ACCEPT; -+ -+ /* No data ? */ -+ dataoff = protoff + th->doff*4; -+ datalen = skb->len - dataoff; -+ if (dataoff >= skb->len) -+ return NF_ACCEPT; -+ -+ spin_lock_bh(&rtsp_buffer_lock); -+ rb_ptr = skb_header_pointer(skb, dataoff, -+ skb->len - dataoff, rtsp_buffer); -+ BUG_ON(rb_ptr == NULL); -+ -+#if 0 -+ /* Checksum invalid? Ignore. */ -+ /* FIXME: Source route IP option packets --RR */ -+ if (tcp_v4_check(tcph, tcplen, iph->saddr, iph->daddr, -+ csum_partial((char*)tcph, tcplen, 0))) -+ { -+ DEBUGP("bad csum: %p %u %u.%u.%u.%u %u.%u.%u.%u\n", -+ tcph, tcplen, NIPQUAD(iph->saddr), NIPQUAD(iph->daddr)); -+ return NF_ACCEPT; -+ } -+#endif -+ -+ switch (CTINFO2DIR(ctinfo)) { -+ case IP_CT_DIR_ORIGINAL: -+ ret = help_out(skb, rb_ptr, datalen, ct, ctinfo); -+ break; -+ case IP_CT_DIR_REPLY: -+ DEBUGP("IP_CT_DIR_REPLY\n"); -+ /* inbound packet: server->client */ -+ ret = NF_ACCEPT; -+ break; -+ } -+ -+ spin_unlock_bh(&rtsp_buffer_lock); -+ -+ return ret; -+} -+ -+static struct nf_conntrack_helper rtsp_helpers[MAX_PORTS]; -+static char rtsp_names[MAX_PORTS][10]; -+ -+/* This function is intentionally _NOT_ defined as __exit */ -+static void -+fini(void) -+{ -+ int i; -+ for (i = 0; i < num_ports; i++) { -+ DEBUGP("unregistering port %d\n", ports[i]); -+ nf_conntrack_helper_unregister(&rtsp_helpers[i]); -+ } -+ kfree(rtsp_buffer); -+} -+ -+static int __init -+init(void) -+{ -+ int i, ret; -+ struct nf_conntrack_helper *hlpr; -+ char *tmpname; -+ -+ printk("nf_conntrack_rtsp v" IP_NF_RTSP_VERSION " loading\n"); -+ -+ if (max_outstanding < 1) { -+ printk("nf_conntrack_rtsp: max_outstanding must be a positive integer\n"); -+ return -EBUSY; -+ } -+ if (setup_timeout < 0) { -+ printk("nf_conntrack_rtsp: setup_timeout must be a positive integer\n"); -+ return -EBUSY; -+ } -+ -+ rtsp_buffer = kmalloc(65536, GFP_KERNEL); -+ if (!rtsp_buffer) -+ return -ENOMEM; -+ -+ /* If no port given, default to standard rtsp port */ -+ if (ports[0] == 0) { -+ ports[0] = RTSP_PORT; -+ } -+ -+ for (i = 0; (i < MAX_PORTS) && ports[i]; i++) { -+ hlpr = &rtsp_helpers[i]; -+ memset(hlpr, 0, sizeof(struct nf_conntrack_helper)); -+ hlpr->tuple.src.u.tcp.port = htons(ports[i]); -+ hlpr->tuple.dst.protonum = IPPROTO_TCP; -+ hlpr->max_expected = max_outstanding; -+ hlpr->timeout = setup_timeout; -+ hlpr->me = THIS_MODULE; -+ hlpr->help = help; -+ -+ tmpname = &rtsp_names[i][0]; -+ if (ports[i] == RTSP_PORT) { -+ sprintf(tmpname, "rtsp"); -+ } else { -+ sprintf(tmpname, "rtsp-%d", i); -+ } -+ hlpr->name = tmpname; -+ -+ DEBUGP("port #%d: %d\n", i, ports[i]); -+ -+ ret = nf_conntrack_helper_register(hlpr); -+ -+ if (ret) { -+ printk("nf_conntrack_rtsp: ERROR registering port %d\n", ports[i]); -+ fini(); -+ return -EBUSY; -+ } -+ num_ports++; -+ } -+ return 0; -+} -+ -+module_init(init); -+module_exit(fini); -+ -+EXPORT_SYMBOL(nf_nat_rtsp_hook_expectfn); -+ ---- /dev/null -+++ b/net/ipv4/netfilter/nf_nat_rtsp.c -@@ -0,0 +1,496 @@ -+/* -+ * RTSP extension for TCP NAT alteration -+ * (C) 2003 by Tom Marshall -+ * based on ip_nat_irc.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. -+ * -+ * Module load syntax: -+ * insmod nf_nat_rtsp.o ports=port1,port2,...port -+ * stunaddr=
-+ * destaction=[auto|strip|none] -+ * -+ * If no ports are specified, the default will be port 554 only. -+ * -+ * stunaddr specifies the address used to detect that a client is using STUN. -+ * If this address is seen in the destination parameter, it is assumed that -+ * the client has already punched a UDP hole in the firewall, so we don't -+ * mangle the client_port. If none is specified, it is autodetected. It -+ * only needs to be set if you have multiple levels of NAT. It should be -+ * set to the external address that the STUN clients detect. Note that in -+ * this case, it will not be possible for clients to use UDP with servers -+ * between the NATs. -+ * -+ * If no destaction is specified, auto is used. -+ * destaction=auto: strip destination parameter if it is not stunaddr. -+ * destaction=strip: always strip destination parameter (not recommended). -+ * destaction=none: do not touch destination parameter (not recommended). -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#define NF_NEED_STRNCASECMP -+#define NF_NEED_STRTOU16 -+#include -+#define NF_NEED_MIME_NEXTLINE -+#include -+ -+#define INFOP(fmt, args...) printk(KERN_INFO "%s: %s: " fmt, __FILE__, __FUNCTION__ , ## args) -+#if 0 -+#define DEBUGP(fmt, args...) printk(KERN_DEBUG "%s: %s: " fmt, __FILE__, __FUNCTION__ , ## args) -+#else -+#define DEBUGP(fmt, args...) -+#endif -+ -+#define MAX_PORTS 8 -+#define DSTACT_AUTO 0 -+#define DSTACT_STRIP 1 -+#define DSTACT_NONE 2 -+ -+static char* stunaddr = NULL; -+static char* destaction = NULL; -+ -+static u_int32_t extip = 0; -+static int dstact = 0; -+ -+MODULE_AUTHOR("Tom Marshall "); -+MODULE_DESCRIPTION("RTSP network address translation module"); -+MODULE_LICENSE("GPL"); -+module_param(stunaddr, charp, 0644); -+MODULE_PARM_DESC(stunaddr, "Address for detecting STUN"); -+module_param(destaction, charp, 0644); -+MODULE_PARM_DESC(destaction, "Action for destination parameter (auto/strip/none)"); -+ -+#define SKIP_WSPACE(ptr,len,off) while(off < len && isspace(*(ptr+off))) { off++; } -+ -+/*** helper functions ***/ -+ -+static void -+get_skb_tcpdata(struct sk_buff* skb, char** pptcpdata, uint* ptcpdatalen) -+{ -+ struct iphdr* iph = ip_hdr(skb); -+ struct tcphdr* tcph = (void *)iph + ip_hdrlen(skb); -+ -+ *pptcpdata = (char*)tcph + tcph->doff*4; -+ *ptcpdatalen = ((char*)skb_transport_header(skb) + skb->len) - *pptcpdata; -+} -+ -+/*** nat functions ***/ -+ -+/* -+ * Mangle the "Transport:" header: -+ * - Replace all occurences of "client_port=" -+ * - Handle destination parameter -+ * -+ * In: -+ * ct, ctinfo = conntrack context -+ * skb = packet -+ * tranoff = Transport header offset from TCP data -+ * tranlen = Transport header length (incl. CRLF) -+ * rport_lo = replacement low port (host endian) -+ * rport_hi = replacement high port (host endian) -+ * -+ * Returns packet size difference. -+ * -+ * Assumes that a complete transport header is present, ending with CR or LF -+ */ -+static int -+rtsp_mangle_tran(enum ip_conntrack_info ctinfo, -+ struct nf_conntrack_expect* exp, -+ struct ip_ct_rtsp_expect* prtspexp, -+ struct sk_buff* skb, uint tranoff, uint tranlen) -+{ -+ char* ptcp; -+ uint tcplen; -+ char* ptran; -+ char rbuf1[16]; /* Replacement buffer (one port) */ -+ uint rbuf1len; /* Replacement len (one port) */ -+ char rbufa[16]; /* Replacement buffer (all ports) */ -+ uint rbufalen; /* Replacement len (all ports) */ -+ u_int32_t newip; -+ u_int16_t loport, hiport; -+ uint off = 0; -+ uint diff; /* Number of bytes we removed */ -+ -+ struct nf_conn *ct = exp->master; -+ struct nf_conntrack_tuple *t; -+ -+ char szextaddr[15+1]; -+ uint extaddrlen; -+ int is_stun; -+ -+ get_skb_tcpdata(skb, &ptcp, &tcplen); -+ ptran = ptcp+tranoff; -+ -+ if (tranoff+tranlen > tcplen || tcplen-tranoff < tranlen || -+ tranlen < 10 || !iseol(ptran[tranlen-1]) || -+ nf_strncasecmp(ptran, "Transport:", 10) != 0) -+ { -+ INFOP("sanity check failed\n"); -+ return 0; -+ } -+ off += 10; -+ SKIP_WSPACE(ptcp+tranoff, tranlen, off); -+ -+ newip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip; -+ t = &exp->tuple; -+ t->dst.u3.ip = newip; -+ -+ extaddrlen = extip ? sprintf(szextaddr, "%u.%u.%u.%u", NIPQUAD(extip)) -+ : sprintf(szextaddr, "%u.%u.%u.%u", NIPQUAD(newip)); -+ DEBUGP("stunaddr=%s (%s)\n", szextaddr, (extip?"forced":"auto")); -+ -+ rbuf1len = rbufalen = 0; -+ switch (prtspexp->pbtype) -+ { -+ case pb_single: -+ for (loport = prtspexp->loport; loport != 0; loport++) /* XXX: improper wrap? */ -+ { -+ t->dst.u.udp.port = htons(loport); -+ if (nf_ct_expect_related(exp) == 0) -+ { -+ DEBUGP("using port %hu\n", loport); -+ break; -+ } -+ } -+ if (loport != 0) -+ { -+ rbuf1len = sprintf(rbuf1, "%hu", loport); -+ rbufalen = sprintf(rbufa, "%hu", loport); -+ } -+ break; -+ case pb_range: -+ for (loport = prtspexp->loport; loport != 0; loport += 2) /* XXX: improper wrap? */ -+ { -+ t->dst.u.udp.port = htons(loport); -+ if (nf_ct_expect_related(exp) == 0) -+ { -+ hiport = loport + ~exp->mask.src.u.udp.port; -+ DEBUGP("using ports %hu-%hu\n", loport, hiport); -+ break; -+ } -+ } -+ if (loport != 0) -+ { -+ rbuf1len = sprintf(rbuf1, "%hu", loport); -+ rbufalen = sprintf(rbufa, "%hu-%hu", loport, loport+1); -+ } -+ break; -+ case pb_discon: -+ for (loport = prtspexp->loport; loport != 0; loport++) /* XXX: improper wrap? */ -+ { -+ t->dst.u.udp.port = htons(loport); -+ if (nf_ct_expect_related(exp) == 0) -+ { -+ DEBUGP("using port %hu (1 of 2)\n", loport); -+ break; -+ } -+ } -+ for (hiport = prtspexp->hiport; hiport != 0; hiport++) /* XXX: improper wrap? */ -+ { -+ t->dst.u.udp.port = htons(hiport); -+ if (nf_ct_expect_related(exp) == 0) -+ { -+ DEBUGP("using port %hu (2 of 2)\n", hiport); -+ break; -+ } -+ } -+ if (loport != 0 && hiport != 0) -+ { -+ rbuf1len = sprintf(rbuf1, "%hu", loport); -+ if (hiport == loport+1) -+ { -+ rbufalen = sprintf(rbufa, "%hu-%hu", loport, hiport); -+ } -+ else -+ { -+ rbufalen = sprintf(rbufa, "%hu/%hu", loport, hiport); -+ } -+ } -+ break; -+ } -+ -+ if (rbuf1len == 0) -+ { -+ return 0; /* cannot get replacement port(s) */ -+ } -+ -+ /* Transport: tran;field;field=val,tran;field;field=val,... */ -+ while (off < tranlen) -+ { -+ uint saveoff; -+ const char* pparamend; -+ uint nextparamoff; -+ -+ pparamend = memchr(ptran+off, ',', tranlen-off); -+ pparamend = (pparamend == NULL) ? ptran+tranlen : pparamend+1; -+ nextparamoff = pparamend-ptcp; -+ -+ /* -+ * We pass over each param twice. On the first pass, we look for a -+ * destination= field. It is handled by the security policy. If it -+ * is present, allowed, and equal to our external address, we assume -+ * that STUN is being used and we leave the client_port= field alone. -+ */ -+ is_stun = 0; -+ saveoff = off; -+ while (off < nextparamoff) -+ { -+ const char* pfieldend; -+ uint nextfieldoff; -+ -+ pfieldend = memchr(ptran+off, ';', nextparamoff-off); -+ nextfieldoff = (pfieldend == NULL) ? nextparamoff : pfieldend-ptran+1; -+ -+ if (dstact != DSTACT_NONE && strncmp(ptran+off, "destination=", 12) == 0) -+ { -+ if (strncmp(ptran+off+12, szextaddr, extaddrlen) == 0) -+ { -+ is_stun = 1; -+ } -+ if (dstact == DSTACT_STRIP || (dstact == DSTACT_AUTO && !is_stun)) -+ { -+ diff = nextfieldoff-off; -+ if (!nf_nat_mangle_tcp_packet(skb, ct, ctinfo, -+ off, diff, NULL, 0)) -+ { -+ /* mangle failed, all we can do is bail */ -+ nf_ct_unexpect_related(exp); -+ return 0; -+ } -+ get_skb_tcpdata(skb, &ptcp, &tcplen); -+ ptran = ptcp+tranoff; -+ tranlen -= diff; -+ nextparamoff -= diff; -+ nextfieldoff -= diff; -+ } -+ } -+ -+ off = nextfieldoff; -+ } -+ if (is_stun) -+ { -+ continue; -+ } -+ off = saveoff; -+ while (off < nextparamoff) -+ { -+ const char* pfieldend; -+ uint nextfieldoff; -+ -+ pfieldend = memchr(ptran+off, ';', nextparamoff-off); -+ nextfieldoff = (pfieldend == NULL) ? nextparamoff : pfieldend-ptran+1; -+ -+ if (strncmp(ptran+off, "client_port=", 12) == 0) -+ { -+ u_int16_t port; -+ uint numlen; -+ uint origoff; -+ uint origlen; -+ char* rbuf = rbuf1; -+ uint rbuflen = rbuf1len; -+ -+ off += 12; -+ origoff = (ptran-ptcp)+off; -+ origlen = 0; -+ numlen = nf_strtou16(ptran+off, &port); -+ off += numlen; -+ origlen += numlen; -+ if (port != prtspexp->loport) -+ { -+ DEBUGP("multiple ports found, port %hu ignored\n", port); -+ } -+ else -+ { -+ if (ptran[off] == '-' || ptran[off] == '/') -+ { -+ off++; -+ origlen++; -+ numlen = nf_strtou16(ptran+off, &port); -+ off += numlen; -+ origlen += numlen; -+ rbuf = rbufa; -+ rbuflen = rbufalen; -+ } -+ -+ /* -+ * note we cannot just memcpy() if the sizes are the same. -+ * the mangle function does skb resizing, checks for a -+ * cloned skb, and updates the checksums. -+ * -+ * parameter 4 below is offset from start of tcp data. -+ */ -+ diff = origlen-rbuflen; -+ if (!nf_nat_mangle_tcp_packet(skb, ct, ctinfo, -+ origoff, origlen, rbuf, rbuflen)) -+ { -+ /* mangle failed, all we can do is bail */ -+ nf_ct_unexpect_related(exp); -+ return 0; -+ } -+ get_skb_tcpdata(skb, &ptcp, &tcplen); -+ ptran = ptcp+tranoff; -+ tranlen -= diff; -+ nextparamoff -= diff; -+ nextfieldoff -= diff; -+ } -+ } -+ -+ off = nextfieldoff; -+ } -+ -+ off = nextparamoff; -+ } -+ -+ return 1; -+} -+ -+static uint -+help_out(struct sk_buff *skb, enum ip_conntrack_info ctinfo, -+ unsigned int matchoff, unsigned int matchlen, struct ip_ct_rtsp_expect* prtspexp, -+ struct nf_conntrack_expect* exp) -+{ -+ char* ptcp; -+ uint tcplen; -+ uint hdrsoff; -+ uint hdrslen; -+ uint lineoff; -+ uint linelen; -+ uint off; -+ -+ //struct iphdr* iph = (struct iphdr*)skb->nh.iph; -+ //struct tcphdr* tcph = (struct tcphdr*)((void*)iph + iph->ihl*4); -+ -+ get_skb_tcpdata(skb, &ptcp, &tcplen); -+ hdrsoff = matchoff;//exp->seq - ntohl(tcph->seq); -+ hdrslen = matchlen; -+ off = hdrsoff; -+ DEBUGP("NAT rtsp help_out\n"); -+ -+ while (nf_mime_nextline(ptcp, hdrsoff+hdrslen, &off, &lineoff, &linelen)) -+ { -+ if (linelen == 0) -+ { -+ break; -+ } -+ if (off > hdrsoff+hdrslen) -+ { -+ INFOP("!! overrun !!"); -+ break; -+ } -+ DEBUGP("hdr: len=%u, %.*s", linelen, (int)linelen, ptcp+lineoff); -+ -+ if (nf_strncasecmp(ptcp+lineoff, "Transport:", 10) == 0) -+ { -+ uint oldtcplen = tcplen; -+ DEBUGP("hdr: Transport\n"); -+ if (!rtsp_mangle_tran(ctinfo, exp, prtspexp, skb, lineoff, linelen)) -+ { -+ DEBUGP("hdr: Transport mangle failed"); -+ break; -+ } -+ get_skb_tcpdata(skb, &ptcp, &tcplen); -+ hdrslen -= (oldtcplen-tcplen); -+ off -= (oldtcplen-tcplen); -+ lineoff -= (oldtcplen-tcplen); -+ linelen -= (oldtcplen-tcplen); -+ DEBUGP("rep: len=%u, %.*s", linelen, (int)linelen, ptcp+lineoff); -+ } -+ } -+ -+ return NF_ACCEPT; -+} -+ -+static unsigned int -+help(struct sk_buff *skb, enum ip_conntrack_info ctinfo, -+ unsigned int matchoff, unsigned int matchlen, struct ip_ct_rtsp_expect* prtspexp, -+ struct nf_conntrack_expect* exp) -+{ -+ int dir = CTINFO2DIR(ctinfo); -+ int rc = NF_ACCEPT; -+ -+ switch (dir) -+ { -+ case IP_CT_DIR_ORIGINAL: -+ rc = help_out(skb, ctinfo, matchoff, matchlen, prtspexp, exp); -+ break; -+ case IP_CT_DIR_REPLY: -+ DEBUGP("unmangle ! %u\n", ctinfo); -+ /* XXX: unmangle */ -+ rc = NF_ACCEPT; -+ break; -+ } -+ //UNLOCK_BH(&ip_rtsp_lock); -+ -+ return rc; -+} -+ -+static void expected(struct nf_conn* ct, struct nf_conntrack_expect *exp) -+{ -+ struct nf_nat_multi_range_compat mr; -+ u_int32_t newdstip, newsrcip, newip; -+ -+ struct nf_conn *master = ct->master; -+ -+ newdstip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip; -+ newsrcip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip; -+ //FIXME (how to port that ?) -+ //code from 2.4 : newip = (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC) ? newsrcip : newdstip; -+ newip = newdstip; -+ -+ DEBUGP("newsrcip=%u.%u.%u.%u, newdstip=%u.%u.%u.%u, newip=%u.%u.%u.%u\n", -+ NIPQUAD(newsrcip), NIPQUAD(newdstip), NIPQUAD(newip)); -+ -+ mr.rangesize = 1; -+ // We don't want to manip the per-protocol, just the IPs. -+ mr.range[0].flags = IP_NAT_RANGE_MAP_IPS; -+ mr.range[0].min_ip = mr.range[0].max_ip = newip; -+ -+ nf_nat_setup_info(ct, &mr.range[0], NF_IP_PRE_ROUTING); -+} -+ -+ -+static void __exit fini(void) -+{ -+ nf_nat_rtsp_hook = NULL; -+ nf_nat_rtsp_hook_expectfn = NULL; -+ synchronize_net(); -+} -+ -+static int __init init(void) -+{ -+ printk("nf_nat_rtsp v" IP_NF_RTSP_VERSION " loading\n"); -+ -+ BUG_ON(nf_nat_rtsp_hook); -+ nf_nat_rtsp_hook = help; -+ nf_nat_rtsp_hook_expectfn = &expected; -+ -+ if (stunaddr != NULL) -+ extip = in_aton(stunaddr); -+ -+ if (destaction != NULL) { -+ if (strcmp(destaction, "auto") == 0) -+ dstact = DSTACT_AUTO; -+ -+ if (strcmp(destaction, "strip") == 0) -+ dstact = DSTACT_STRIP; -+ -+ if (strcmp(destaction, "none") == 0) -+ dstact = DSTACT_NONE; -+ } -+ -+ return 0; -+} -+ -+module_init(init); -+module_exit(fini); diff --git a/target/linux/generic-2.6/patches-2.6.24/200-sched_esfq.patch b/target/linux/generic-2.6/patches-2.6.24/200-sched_esfq.patch deleted file mode 100644 index 05965399b1..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/200-sched_esfq.patch +++ /dev/null @@ -1,795 +0,0 @@ ---- a/include/linux/pkt_sched.h -+++ b/include/linux/pkt_sched.h -@@ -155,8 +155,37 @@ struct tc_sfq_qopt - * - * The only reason for this is efficiency, it is possible - * to change these parameters in compile time. -+ * -+ * If you need to play with these values, use esfq instead. - */ - -+/* ESFQ section */ -+ -+enum -+{ -+ /* traditional */ -+ TCA_SFQ_HASH_CLASSIC, -+ TCA_SFQ_HASH_DST, -+ TCA_SFQ_HASH_SRC, -+ TCA_SFQ_HASH_FWMARK, -+ /* conntrack */ -+ TCA_SFQ_HASH_CTORIGDST, -+ TCA_SFQ_HASH_CTORIGSRC, -+ TCA_SFQ_HASH_CTREPLDST, -+ TCA_SFQ_HASH_CTREPLSRC, -+ TCA_SFQ_HASH_CTNATCHG, -+}; -+ -+struct tc_esfq_qopt -+{ -+ unsigned quantum; /* Bytes per round allocated to flow */ -+ int perturb_period; /* Period of hash perturbation */ -+ __u32 limit; /* Maximal packets in queue */ -+ unsigned divisor; /* Hash divisor */ -+ unsigned flows; /* Maximal number of flows */ -+ unsigned hash_kind; /* Hash function to use for flow identification */ -+}; -+ - /* RED section */ - - enum ---- a/net/sched/Kconfig -+++ b/net/sched/Kconfig -@@ -139,6 +139,37 @@ config NET_SCH_SFQ - To compile this code as a module, choose M here: the - module will be called sch_sfq. - -+config NET_SCH_ESFQ -+ tristate "Enhanced Stochastic Fairness Queueing (ESFQ)" -+ ---help--- -+ Say Y here if you want to use the Enhanced Stochastic Fairness -+ Queueing (ESFQ) packet scheduling algorithm for some of your network -+ devices or as a leaf discipline for a classful qdisc such as HTB or -+ CBQ (see the top of for details and -+ references to the SFQ algorithm). -+ -+ This is an enchanced SFQ version which allows you to control some -+ hardcoded values in the SFQ scheduler. -+ -+ ESFQ also adds control of the hash function used to identify packet -+ flows. The original SFQ discipline hashes by connection; ESFQ add -+ several other hashing methods, such as by src IP or by dst IP, which -+ can be more fair to users in some networking situations. -+ -+ To compile this code as a module, choose M here: the -+ module will be called sch_esfq. -+ -+config NET_SCH_ESFQ_NFCT -+ bool "Connection Tracking Hash Types" -+ depends on NET_SCH_ESFQ && NF_CONNTRACK -+ ---help--- -+ Say Y here to enable support for hashing based on netfilter connection -+ tracking information. This is useful for a router that is also using -+ NAT to connect privately-addressed hosts to the Internet. If you want -+ to provide fair distribution of upstream bandwidth, ESFQ must use -+ connection tracking information, since all outgoing packets will share -+ the same source address. -+ - config NET_SCH_TEQL - tristate "True Link Equalizer (TEQL)" - ---help--- ---- a/net/sched/Makefile -+++ b/net/sched/Makefile -@@ -23,6 +23,7 @@ obj-$(CONFIG_NET_SCH_GRED) += sch_gred.o - obj-$(CONFIG_NET_SCH_INGRESS) += sch_ingress.o - obj-$(CONFIG_NET_SCH_DSMARK) += sch_dsmark.o - obj-$(CONFIG_NET_SCH_SFQ) += sch_sfq.o -+obj-$(CONFIG_NET_SCH_ESFQ) += sch_esfq.o - obj-$(CONFIG_NET_SCH_TBF) += sch_tbf.o - obj-$(CONFIG_NET_SCH_TEQL) += sch_teql.o - obj-$(CONFIG_NET_SCH_PRIO) += sch_prio.o ---- /dev/null -+++ b/net/sched/sch_esfq.c -@@ -0,0 +1,702 @@ -+/* -+ * net/sched/sch_esfq.c Extended Stochastic Fairness Queueing discipline. -+ * -+ * 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. -+ * -+ * Authors: Alexey Kuznetsov, -+ * -+ * Changes: Alexander Atanasov, -+ * Added dynamic depth,limit,divisor,hash_kind options. -+ * Added dst and src hashes. -+ * -+ * Alexander Clouter, -+ * Ported ESFQ to Linux 2.6. -+ * -+ * Corey Hickey, -+ * Maintenance of the Linux 2.6 port. -+ * Added fwmark hash (thanks to Robert Kurjata). -+ * Added usage of jhash. -+ * Added conntrack support. -+ * Added ctnatchg hash (thanks to Ben Pfountz). -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* Stochastic Fairness Queuing algorithm. -+ For more comments look at sch_sfq.c. -+ The difference is that you can change limit, depth, -+ hash table size and choose alternate hash types. -+ -+ classic: same as in sch_sfq.c -+ dst: destination IP address -+ src: source IP address -+ fwmark: netfilter mark value -+ ctorigdst: original destination IP address -+ ctorigsrc: original source IP address -+ ctrepldst: reply destination IP address -+ ctreplsrc: reply source IP -+ -+*/ -+ -+#define ESFQ_HEAD 0 -+#define ESFQ_TAIL 1 -+ -+/* This type should contain at least SFQ_DEPTH*2 values */ -+typedef unsigned int esfq_index; -+ -+struct esfq_head -+{ -+ esfq_index next; -+ esfq_index prev; -+}; -+ -+struct esfq_sched_data -+{ -+/* Parameters */ -+ int perturb_period; -+ unsigned quantum; /* Allotment per round: MUST BE >= MTU */ -+ int limit; -+ unsigned depth; -+ unsigned hash_divisor; -+ unsigned hash_kind; -+/* Variables */ -+ struct timer_list perturb_timer; -+ int perturbation; -+ esfq_index tail; /* Index of current slot in round */ -+ esfq_index max_depth; /* Maximal depth */ -+ -+ esfq_index *ht; /* Hash table */ -+ esfq_index *next; /* Active slots link */ -+ short *allot; /* Current allotment per slot */ -+ unsigned short *hash; /* Hash value indexed by slots */ -+ struct sk_buff_head *qs; /* Slot queue */ -+ struct esfq_head *dep; /* Linked list of slots, indexed by depth */ -+}; -+ -+/* This contains the info we will hash. */ -+struct esfq_packet_info -+{ -+ u32 proto; /* protocol or port */ -+ u32 src; /* source from packet header */ -+ u32 dst; /* destination from packet header */ -+ u32 ctorigsrc; /* original source from conntrack */ -+ u32 ctorigdst; /* original destination from conntrack */ -+ u32 ctreplsrc; /* reply source from conntrack */ -+ u32 ctrepldst; /* reply destination from conntrack */ -+ u32 mark; /* netfilter mark (fwmark) */ -+}; -+ -+static __inline__ unsigned esfq_jhash_1word(struct esfq_sched_data *q,u32 a) -+{ -+ return jhash_1word(a, q->perturbation) & (q->hash_divisor-1); -+} -+ -+static __inline__ unsigned esfq_jhash_2words(struct esfq_sched_data *q, u32 a, u32 b) -+{ -+ return jhash_2words(a, b, q->perturbation) & (q->hash_divisor-1); -+} -+ -+static __inline__ unsigned esfq_jhash_3words(struct esfq_sched_data *q, u32 a, u32 b, u32 c) -+{ -+ return jhash_3words(a, b, c, q->perturbation) & (q->hash_divisor-1); -+} -+ -+static unsigned esfq_hash(struct esfq_sched_data *q, struct sk_buff *skb) -+{ -+ struct esfq_packet_info info; -+#ifdef CONFIG_NET_SCH_ESFQ_NFCT -+ enum ip_conntrack_info ctinfo; -+ struct nf_conn *ct = nf_ct_get(skb, &ctinfo); -+#endif -+ -+ switch (skb->protocol) { -+ case __constant_htons(ETH_P_IP): -+ { -+ struct iphdr *iph = ip_hdr(skb); -+ info.dst = iph->daddr; -+ info.src = iph->saddr; -+ if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) && -+ (iph->protocol == IPPROTO_TCP || -+ iph->protocol == IPPROTO_UDP || -+ iph->protocol == IPPROTO_SCTP || -+ iph->protocol == IPPROTO_DCCP || -+ iph->protocol == IPPROTO_ESP)) -+ info.proto = *(((u32*)iph) + iph->ihl); -+ else -+ info.proto = iph->protocol; -+ break; -+ } -+ case __constant_htons(ETH_P_IPV6): -+ { -+ struct ipv6hdr *iph = ipv6_hdr(skb); -+ /* Hash ipv6 addresses into a u32. This isn't ideal, -+ * but the code is simple. */ -+ info.dst = jhash2(iph->daddr.s6_addr32, 4, q->perturbation); -+ info.src = jhash2(iph->saddr.s6_addr32, 4, q->perturbation); -+ if (iph->nexthdr == IPPROTO_TCP || -+ iph->nexthdr == IPPROTO_UDP || -+ iph->nexthdr == IPPROTO_SCTP || -+ iph->nexthdr == IPPROTO_DCCP || -+ iph->nexthdr == IPPROTO_ESP) -+ info.proto = *(u32*)&iph[1]; -+ else -+ info.proto = iph->nexthdr; -+ break; -+ } -+ default: -+ info.dst = (u32)(unsigned long)skb->dst; -+ info.src = (u32)(unsigned long)skb->sk; -+ info.proto = skb->protocol; -+ } -+ -+ info.mark = skb->mark; -+ -+#ifdef CONFIG_NET_SCH_ESFQ_NFCT -+ /* defaults if there is no conntrack info */ -+ info.ctorigsrc = info.src; -+ info.ctorigdst = info.dst; -+ info.ctreplsrc = info.dst; -+ info.ctrepldst = info.src; -+ /* collect conntrack info */ -+ if (ct && ct != &nf_conntrack_untracked) { -+ if (skb->protocol == __constant_htons(ETH_P_IP)) { -+ info.ctorigsrc = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip; -+ info.ctorigdst = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.ip; -+ info.ctreplsrc = ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip; -+ info.ctrepldst = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip; -+ } -+ else if (skb->protocol == __constant_htons(ETH_P_IPV6)) { -+ /* Again, hash ipv6 addresses into a single u32. */ -+ info.ctorigsrc = jhash2(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip6, 4, q->perturbation); -+ info.ctorigdst = jhash2(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.ip6, 4, q->perturbation); -+ info.ctreplsrc = jhash2(ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip6, 4, q->perturbation); -+ info.ctrepldst = jhash2(ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip6, 4, q->perturbation); -+ } -+ -+ } -+#endif -+ -+ switch(q->hash_kind) { -+ case TCA_SFQ_HASH_CLASSIC: -+ return esfq_jhash_3words(q, info.dst, info.src, info.proto); -+ case TCA_SFQ_HASH_DST: -+ return esfq_jhash_1word(q, info.dst); -+ case TCA_SFQ_HASH_SRC: -+ return esfq_jhash_1word(q, info.src); -+ case TCA_SFQ_HASH_FWMARK: -+ return esfq_jhash_1word(q, info.mark); -+#ifdef CONFIG_NET_SCH_ESFQ_NFCT -+ case TCA_SFQ_HASH_CTORIGDST: -+ return esfq_jhash_1word(q, info.ctorigdst); -+ case TCA_SFQ_HASH_CTORIGSRC: -+ return esfq_jhash_1word(q, info.ctorigsrc); -+ case TCA_SFQ_HASH_CTREPLDST: -+ return esfq_jhash_1word(q, info.ctrepldst); -+ case TCA_SFQ_HASH_CTREPLSRC: -+ return esfq_jhash_1word(q, info.ctreplsrc); -+ case TCA_SFQ_HASH_CTNATCHG: -+ { -+ if (info.ctorigdst == info.ctreplsrc) -+ return esfq_jhash_1word(q, info.ctorigsrc); -+ return esfq_jhash_1word(q, info.ctreplsrc); -+ } -+#endif -+ default: -+ if (net_ratelimit()) -+ printk(KERN_WARNING "ESFQ: Unknown hash method. Falling back to classic.\n"); -+ } -+ return esfq_jhash_3words(q, info.dst, info.src, info.proto); -+} -+ -+static inline void esfq_link(struct esfq_sched_data *q, esfq_index x) -+{ -+ esfq_index p, n; -+ int d = q->qs[x].qlen + q->depth; -+ -+ p = d; -+ n = q->dep[d].next; -+ q->dep[x].next = n; -+ q->dep[x].prev = p; -+ q->dep[p].next = q->dep[n].prev = x; -+} -+ -+static inline void esfq_dec(struct esfq_sched_data *q, esfq_index x) -+{ -+ esfq_index p, n; -+ -+ n = q->dep[x].next; -+ p = q->dep[x].prev; -+ q->dep[p].next = n; -+ q->dep[n].prev = p; -+ -+ if (n == p && q->max_depth == q->qs[x].qlen + 1) -+ q->max_depth--; -+ -+ esfq_link(q, x); -+} -+ -+static inline void esfq_inc(struct esfq_sched_data *q, esfq_index x) -+{ -+ esfq_index p, n; -+ int d; -+ -+ n = q->dep[x].next; -+ p = q->dep[x].prev; -+ q->dep[p].next = n; -+ q->dep[n].prev = p; -+ d = q->qs[x].qlen; -+ if (q->max_depth < d) -+ q->max_depth = d; -+ -+ esfq_link(q, x); -+} -+ -+static unsigned int esfq_drop(struct Qdisc *sch) -+{ -+ struct esfq_sched_data *q = qdisc_priv(sch); -+ esfq_index d = q->max_depth; -+ struct sk_buff *skb; -+ unsigned int len; -+ -+ /* Queue is full! Find the longest slot and -+ drop a packet from it */ -+ -+ if (d > 1) { -+ esfq_index x = q->dep[d+q->depth].next; -+ skb = q->qs[x].prev; -+ len = skb->len; -+ __skb_unlink(skb, &q->qs[x]); -+ kfree_skb(skb); -+ esfq_dec(q, x); -+ sch->q.qlen--; -+ sch->qstats.drops++; -+ sch->qstats.backlog -= len; -+ return len; -+ } -+ -+ if (d == 1) { -+ /* It is difficult to believe, but ALL THE SLOTS HAVE LENGTH 1. */ -+ d = q->next[q->tail]; -+ q->next[q->tail] = q->next[d]; -+ q->allot[q->next[d]] += q->quantum; -+ skb = q->qs[d].prev; -+ len = skb->len; -+ __skb_unlink(skb, &q->qs[d]); -+ kfree_skb(skb); -+ esfq_dec(q, d); -+ sch->q.qlen--; -+ q->ht[q->hash[d]] = q->depth; -+ sch->qstats.drops++; -+ sch->qstats.backlog -= len; -+ return len; -+ } -+ -+ return 0; -+} -+ -+static void esfq_q_enqueue(struct sk_buff *skb, struct esfq_sched_data *q, unsigned int end) -+{ -+ unsigned hash = esfq_hash(q, skb); -+ unsigned depth = q->depth; -+ esfq_index x; -+ -+ x = q->ht[hash]; -+ if (x == depth) { -+ q->ht[hash] = x = q->dep[depth].next; -+ q->hash[x] = hash; -+ } -+ -+ if (end == ESFQ_TAIL) -+ __skb_queue_tail(&q->qs[x], skb); -+ else -+ __skb_queue_head(&q->qs[x], skb); -+ -+ esfq_inc(q, x); -+ if (q->qs[x].qlen == 1) { /* The flow is new */ -+ if (q->tail == depth) { /* It is the first flow */ -+ q->tail = x; -+ q->next[x] = x; -+ q->allot[x] = q->quantum; -+ } else { -+ q->next[x] = q->next[q->tail]; -+ q->next[q->tail] = x; -+ q->tail = x; -+ } -+ } -+} -+ -+static int esfq_enqueue(struct sk_buff *skb, struct Qdisc* sch) -+{ -+ struct esfq_sched_data *q = qdisc_priv(sch); -+ esfq_q_enqueue(skb, q, ESFQ_TAIL); -+ sch->qstats.backlog += skb->len; -+ if (++sch->q.qlen < q->limit-1) { -+ sch->bstats.bytes += skb->len; -+ sch->bstats.packets++; -+ return 0; -+ } -+ -+ sch->qstats.drops++; -+ esfq_drop(sch); -+ return NET_XMIT_CN; -+} -+ -+ -+static int esfq_requeue(struct sk_buff *skb, struct Qdisc* sch) -+{ -+ struct esfq_sched_data *q = qdisc_priv(sch); -+ esfq_q_enqueue(skb, q, ESFQ_HEAD); -+ sch->qstats.backlog += skb->len; -+ if (++sch->q.qlen < q->limit - 1) { -+ sch->qstats.requeues++; -+ return 0; -+ } -+ -+ sch->qstats.drops++; -+ esfq_drop(sch); -+ return NET_XMIT_CN; -+} -+ -+static struct sk_buff *esfq_q_dequeue(struct esfq_sched_data *q) -+{ -+ struct sk_buff *skb; -+ unsigned depth = q->depth; -+ esfq_index a, old_a; -+ -+ /* No active slots */ -+ if (q->tail == depth) -+ return NULL; -+ -+ a = old_a = q->next[q->tail]; -+ -+ /* Grab packet */ -+ skb = __skb_dequeue(&q->qs[a]); -+ esfq_dec(q, a); -+ -+ /* Is the slot empty? */ -+ if (q->qs[a].qlen == 0) { -+ q->ht[q->hash[a]] = depth; -+ a = q->next[a]; -+ if (a == old_a) { -+ q->tail = depth; -+ return skb; -+ } -+ q->next[q->tail] = a; -+ q->allot[a] += q->quantum; -+ } else if ((q->allot[a] -= skb->len) <= 0) { -+ q->tail = a; -+ a = q->next[a]; -+ q->allot[a] += q->quantum; -+ } -+ -+ return skb; -+} -+ -+static struct sk_buff *esfq_dequeue(struct Qdisc* sch) -+{ -+ struct esfq_sched_data *q = qdisc_priv(sch); -+ struct sk_buff *skb; -+ -+ skb = esfq_q_dequeue(q); -+ if (skb == NULL) -+ return NULL; -+ sch->q.qlen--; -+ sch->qstats.backlog -= skb->len; -+ return skb; -+} -+ -+static void esfq_q_destroy(struct esfq_sched_data *q) -+{ -+ del_timer(&q->perturb_timer); -+ if(q->ht) -+ kfree(q->ht); -+ if(q->dep) -+ kfree(q->dep); -+ if(q->next) -+ kfree(q->next); -+ if(q->allot) -+ kfree(q->allot); -+ if(q->hash) -+ kfree(q->hash); -+ if(q->qs) -+ kfree(q->qs); -+} -+ -+static void esfq_destroy(struct Qdisc *sch) -+{ -+ struct esfq_sched_data *q = qdisc_priv(sch); -+ esfq_q_destroy(q); -+} -+ -+ -+static void esfq_reset(struct Qdisc* sch) -+{ -+ struct sk_buff *skb; -+ -+ while ((skb = esfq_dequeue(sch)) != NULL) -+ kfree_skb(skb); -+} -+ -+static void esfq_perturbation(unsigned long arg) -+{ -+ struct Qdisc *sch = (struct Qdisc*)arg; -+ struct esfq_sched_data *q = qdisc_priv(sch); -+ -+ q->perturbation = net_random()&0x1F; -+ -+ if (q->perturb_period) { -+ q->perturb_timer.expires = jiffies + q->perturb_period; -+ add_timer(&q->perturb_timer); -+ } -+} -+ -+static unsigned int esfq_check_hash(unsigned int kind) -+{ -+ switch (kind) { -+ case TCA_SFQ_HASH_CTORIGDST: -+ case TCA_SFQ_HASH_CTORIGSRC: -+ case TCA_SFQ_HASH_CTREPLDST: -+ case TCA_SFQ_HASH_CTREPLSRC: -+ case TCA_SFQ_HASH_CTNATCHG: -+#ifndef CONFIG_NET_SCH_ESFQ_NFCT -+ { -+ if (net_ratelimit()) -+ printk(KERN_WARNING "ESFQ: Conntrack hash types disabled in kernel config. Falling back to classic.\n"); -+ return TCA_SFQ_HASH_CLASSIC; -+ } -+#endif -+ case TCA_SFQ_HASH_CLASSIC: -+ case TCA_SFQ_HASH_DST: -+ case TCA_SFQ_HASH_SRC: -+ case TCA_SFQ_HASH_FWMARK: -+ return kind; -+ default: -+ { -+ if (net_ratelimit()) -+ printk(KERN_WARNING "ESFQ: Unknown hash type. Falling back to classic.\n"); -+ return TCA_SFQ_HASH_CLASSIC; -+ } -+ } -+} -+ -+static int esfq_q_init(struct esfq_sched_data *q, struct rtattr *opt) -+{ -+ struct tc_esfq_qopt *ctl = RTA_DATA(opt); -+ esfq_index p = ~0U/2; -+ int i; -+ -+ if (opt && opt->rta_len < RTA_LENGTH(sizeof(*ctl))) -+ return -EINVAL; -+ -+ q->perturbation = 0; -+ q->hash_kind = TCA_SFQ_HASH_CLASSIC; -+ q->max_depth = 0; -+ if (opt == NULL) { -+ q->perturb_period = 0; -+ q->hash_divisor = 1024; -+ q->tail = q->limit = q->depth = 128; -+ -+ } else { -+ struct tc_esfq_qopt *ctl = RTA_DATA(opt); -+ if (ctl->quantum) -+ q->quantum = ctl->quantum; -+ q->perturb_period = ctl->perturb_period*HZ; -+ q->hash_divisor = ctl->divisor ? : 1024; -+ q->tail = q->limit = q->depth = ctl->flows ? : 128; -+ -+ if ( q->depth > p - 1 ) -+ return -EINVAL; -+ -+ if (ctl->limit) -+ q->limit = min_t(u32, ctl->limit, q->depth); -+ -+ if (ctl->hash_kind) { -+ q->hash_kind = esfq_check_hash(ctl->hash_kind); -+ } -+ } -+ -+ q->ht = kmalloc(q->hash_divisor*sizeof(esfq_index), GFP_KERNEL); -+ if (!q->ht) -+ goto err_case; -+ q->dep = kmalloc((1+q->depth*2)*sizeof(struct esfq_head), GFP_KERNEL); -+ if (!q->dep) -+ goto err_case; -+ q->next = kmalloc(q->depth*sizeof(esfq_index), GFP_KERNEL); -+ if (!q->next) -+ goto err_case; -+ q->allot = kmalloc(q->depth*sizeof(short), GFP_KERNEL); -+ if (!q->allot) -+ goto err_case; -+ q->hash = kmalloc(q->depth*sizeof(unsigned short), GFP_KERNEL); -+ if (!q->hash) -+ goto err_case; -+ q->qs = kmalloc(q->depth*sizeof(struct sk_buff_head), GFP_KERNEL); -+ if (!q->qs) -+ goto err_case; -+ -+ for (i=0; i< q->hash_divisor; i++) -+ q->ht[i] = q->depth; -+ for (i=0; idepth; i++) { -+ skb_queue_head_init(&q->qs[i]); -+ q->dep[i+q->depth].next = i+q->depth; -+ q->dep[i+q->depth].prev = i+q->depth; -+ } -+ -+ for (i=0; idepth; i++) -+ esfq_link(q, i); -+ return 0; -+err_case: -+ esfq_q_destroy(q); -+ return -ENOBUFS; -+} -+ -+static int esfq_init(struct Qdisc *sch, struct rtattr *opt) -+{ -+ struct esfq_sched_data *q = qdisc_priv(sch); -+ int err; -+ -+ q->quantum = psched_mtu(sch->dev); /* default */ -+ if ((err = esfq_q_init(q, opt))) -+ return err; -+ -+ init_timer(&q->perturb_timer); -+ q->perturb_timer.data = (unsigned long)sch; -+ q->perturb_timer.function = esfq_perturbation; -+ if (q->perturb_period) { -+ q->perturb_timer.expires = jiffies + q->perturb_period; -+ add_timer(&q->perturb_timer); -+ } -+ -+ return 0; -+} -+ -+static int esfq_change(struct Qdisc *sch, struct rtattr *opt) -+{ -+ struct esfq_sched_data *q = qdisc_priv(sch); -+ struct esfq_sched_data new; -+ struct sk_buff *skb; -+ int err; -+ -+ /* set up new queue */ -+ memset(&new, 0, sizeof(struct esfq_sched_data)); -+ new.quantum = psched_mtu(sch->dev); /* default */ -+ if ((err = esfq_q_init(&new, opt))) -+ return err; -+ -+ /* copy all packets from the old queue to the new queue */ -+ sch_tree_lock(sch); -+ while ((skb = esfq_q_dequeue(q)) != NULL) -+ esfq_q_enqueue(skb, &new, ESFQ_TAIL); -+ -+ /* clean up the old queue */ -+ esfq_q_destroy(q); -+ -+ /* copy elements of the new queue into the old queue */ -+ q->perturb_period = new.perturb_period; -+ q->quantum = new.quantum; -+ q->limit = new.limit; -+ q->depth = new.depth; -+ q->hash_divisor = new.hash_divisor; -+ q->hash_kind = new.hash_kind; -+ q->tail = new.tail; -+ q->max_depth = new.max_depth; -+ q->ht = new.ht; -+ q->dep = new.dep; -+ q->next = new.next; -+ q->allot = new.allot; -+ q->hash = new.hash; -+ q->qs = new.qs; -+ -+ /* finish up */ -+ if (q->perturb_period) { -+ q->perturb_timer.expires = jiffies + q->perturb_period; -+ add_timer(&q->perturb_timer); -+ } else { -+ q->perturbation = 0; -+ } -+ sch_tree_unlock(sch); -+ return 0; -+} -+ -+static int esfq_dump(struct Qdisc *sch, struct sk_buff *skb) -+{ -+ struct esfq_sched_data *q = qdisc_priv(sch); -+ unsigned char *b = skb->tail; -+ struct tc_esfq_qopt opt; -+ -+ opt.quantum = q->quantum; -+ opt.perturb_period = q->perturb_period/HZ; -+ -+ opt.limit = q->limit; -+ opt.divisor = q->hash_divisor; -+ opt.flows = q->depth; -+ opt.hash_kind = q->hash_kind; -+ -+ RTA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt); -+ -+ return skb->len; -+ -+rtattr_failure: -+ skb_trim(skb, b - skb->data); -+ return -1; -+} -+ -+static struct Qdisc_ops esfq_qdisc_ops = -+{ -+ .next = NULL, -+ .cl_ops = NULL, -+ .id = "esfq", -+ .priv_size = sizeof(struct esfq_sched_data), -+ .enqueue = esfq_enqueue, -+ .dequeue = esfq_dequeue, -+ .requeue = esfq_requeue, -+ .drop = esfq_drop, -+ .init = esfq_init, -+ .reset = esfq_reset, -+ .destroy = esfq_destroy, -+ .change = esfq_change, -+ .dump = esfq_dump, -+ .owner = THIS_MODULE, -+}; -+ -+static int __init esfq_module_init(void) -+{ -+ return register_qdisc(&esfq_qdisc_ops); -+} -+static void __exit esfq_module_exit(void) -+{ -+ unregister_qdisc(&esfq_qdisc_ops); -+} -+module_init(esfq_module_init) -+module_exit(esfq_module_exit) -+MODULE_LICENSE("GPL"); diff --git a/target/linux/generic-2.6/patches-2.6.24/202-mips-freestanding.patch b/target/linux/generic-2.6/patches-2.6.24/202-mips-freestanding.patch deleted file mode 100644 index e8da7e745f..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/202-mips-freestanding.patch +++ /dev/null @@ -1,12 +0,0 @@ ---- a/arch/mips/Makefile -+++ b/arch/mips/Makefile -@@ -576,6 +576,9 @@ core-$(CONFIG_TOSHIBA_RBTX4938) += arch/ - cflags-$(CONFIG_TOSHIBA_RBTX4938) += -Iinclude/asm-mips/mach-tx49xx - load-$(CONFIG_TOSHIBA_RBTX4938) += 0xffffffff80100000 - -+# temporary until string.h is fixed -+cflags-y += -ffreestanding -+ - cflags-y += -Iinclude/asm-mips/mach-generic - drivers-$(CONFIG_PCI) += arch/mips/pci/ - diff --git a/target/linux/generic-2.6/patches-2.6.24/204-jffs2_eofdetect.patch b/target/linux/generic-2.6/patches-2.6.24/204-jffs2_eofdetect.patch deleted file mode 100644 index eccdbe2f92..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/204-jffs2_eofdetect.patch +++ /dev/null @@ -1,56 +0,0 @@ ---- a/fs/jffs2/build.c -+++ b/fs/jffs2/build.c -@@ -105,6 +105,17 @@ static int jffs2_build_filesystem(struct - dbg_fsbuild("scanned flash completely\n"); - jffs2_dbg_dump_block_lists_nolock(c); - -+ if (c->flags & (1 << 7)) { -+ printk("%s(): unlocking the mtd device... ", __func__); -+ if (c->mtd->unlock) -+ c->mtd->unlock(c->mtd, 0, c->mtd->size); -+ printk("done.\n"); -+ -+ printk("%s(): erasing all blocks after the end marker... ", __func__); -+ jffs2_erase_pending_blocks(c, -1); -+ printk("done.\n"); -+ } -+ - dbg_fsbuild("pass 1 starting\n"); - c->flags |= JFFS2_SB_FLAG_BUILDING; - /* Now scan the directory tree, increasing nlink according to every dirent found. */ ---- a/fs/jffs2/scan.c -+++ b/fs/jffs2/scan.c -@@ -142,9 +142,12 @@ int jffs2_scan_medium(struct jffs2_sb_in - - /* reset summary info for next eraseblock scan */ - jffs2_sum_reset_collected(s); -- -- ret = jffs2_scan_eraseblock(c, jeb, buf_size?flashbuf:(flashbuf+jeb->offset), -- buf_size, s); -+ -+ if (c->flags & (1 << 7)) -+ ret = BLK_STATE_ALLFF; -+ else -+ ret = jffs2_scan_eraseblock(c, jeb, buf_size?flashbuf:(flashbuf+jeb->offset), -+ buf_size, s); - - if (ret < 0) - goto out; -@@ -545,6 +548,17 @@ static int jffs2_scan_eraseblock (struct - return err; - } - -+ if ((buf[0] == 0xde) && -+ (buf[1] == 0xad) && -+ (buf[2] == 0xc0) && -+ (buf[3] == 0xde)) { -+ /* end of filesystem. erase everything after this point */ -+ printk("%s(): End of filesystem marker found at 0x%x\n", __func__, jeb->offset); -+ c->flags |= (1 << 7); -+ -+ return BLK_STATE_ALLFF; -+ } -+ - /* We temporarily use 'ofs' as a pointer into the buffer/jeb */ - ofs = 0; - diff --git a/target/linux/generic-2.6/patches-2.6.24/207-powerpc_asm_segment_h.patch b/target/linux/generic-2.6/patches-2.6.24/207-powerpc_asm_segment_h.patch deleted file mode 100644 index 1272e82c75..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/207-powerpc_asm_segment_h.patch +++ /dev/null @@ -1,9 +0,0 @@ ---- /dev/null -+++ b/include/asm-powerpc/segment.h -@@ -0,0 +1,6 @@ -+#ifndef _ASM_SEGMENT_H -+#define _ASM_SEGMENT_H -+ -+/* Only here because we have some old header files that expect it.. */ -+ -+#endif /* _ASM_SEGMENT_H */ diff --git a/target/linux/generic-2.6/patches-2.6.24/208-rtl8110sb_fix.patch b/target/linux/generic-2.6/patches-2.6.24/208-rtl8110sb_fix.patch deleted file mode 100644 index 8f99a0e5c2..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/208-rtl8110sb_fix.patch +++ /dev/null @@ -1,42 +0,0 @@ ---- a/drivers/net/r8169.c -+++ b/drivers/net/r8169.c -@@ -1537,7 +1537,7 @@ static const struct rtl_cfg_info { - .hw_start = rtl_hw_start_8169, - .region = 1, - .align = 0, -- .intr_event = SYSErr | LinkChg | RxOverflow | -+ .intr_event = LinkChg | RxOverflow | - RxFIFOOver | TxErr | TxOK | RxOK | RxErr, - .napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow, - .msi = 0 -@@ -1546,7 +1546,7 @@ static const struct rtl_cfg_info { - .hw_start = rtl_hw_start_8168, - .region = 2, - .align = 8, -- .intr_event = SYSErr | LinkChg | RxOverflow | -+ .intr_event = LinkChg | RxOverflow | - TxErr | TxOK | RxOK | RxErr, - .napi_event = TxErr | TxOK | RxOK | RxOverflow, - .msi = RTL_FEATURE_MSI -@@ -1555,7 +1555,7 @@ static const struct rtl_cfg_info { - .hw_start = rtl_hw_start_8101, - .region = 2, - .align = 8, -- .intr_event = SYSErr | LinkChg | RxOverflow | PCSTimeout | -+ .intr_event = LinkChg | RxOverflow | PCSTimeout | - RxFIFOOver | TxErr | TxOK | RxOK | RxErr, - .napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow, - .msi = RTL_FEATURE_MSI -@@ -2903,10 +2903,12 @@ static irqreturn_t rtl8169_interrupt(int - break; - } - -+#if 0 - if (unlikely(status & SYSErr)) { - rtl8169_pcierr_interrupt(dev); - break; - } -+#endif - - if (status & LinkChg) - rtl8169_check_link_status(dev, tp, ioaddr); diff --git a/target/linux/generic-2.6/patches-2.6.24/209-mini_fo.patch b/target/linux/generic-2.6/patches-2.6.24/209-mini_fo.patch deleted file mode 100644 index 511f203755..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/209-mini_fo.patch +++ /dev/null @@ -1,7776 +0,0 @@ ---- a/fs/Kconfig -+++ b/fs/Kconfig -@@ -468,6 +468,9 @@ config OCFS2_DEBUG_FS - this option for debugging only as it is likely to decrease - performance of the filesystem. - -+config MINI_FO -+ tristate "Mini fanout overlay filesystem" -+ - config MINIX_FS - tristate "Minix fs support" - help ---- a/fs/Makefile -+++ b/fs/Makefile -@@ -76,6 +76,7 @@ obj-$(CONFIG_SQUASHFS) += squashfs/ - obj-y += ramfs/ - obj-$(CONFIG_HUGETLBFS) += hugetlbfs/ - obj-$(CONFIG_CODA_FS) += coda/ -+obj-$(CONFIG_MINI_FO) += mini_fo/ - obj-$(CONFIG_MINIX_FS) += minix/ - obj-$(CONFIG_FAT_FS) += fat/ - obj-$(CONFIG_MSDOS_FS) += msdos/ ---- /dev/null -+++ b/fs/mini_fo/aux.c -@@ -0,0 +1,577 @@ -+/* -+ * Copyright (c) 1997-2003 Erez Zadok -+ * Copyright (c) 2001-2003 Stony Brook University -+ * -+ * For specific licensing information, see the COPYING file distributed with -+ * this package, or get one from ftp://ftp.filesystems.org/pub/fist/COPYING. -+ * -+ * This Copyright notice must be kept intact and distributed with all -+ * fistgen sources INCLUDING sources generated by fistgen. -+ */ -+/* -+ * Copyright (C) 2004, 2005 Markus Klotzbuecher -+ * -+ * 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. -+ */ -+/* -+ * $Id$ -+ */ -+ -+#ifdef HAVE_CONFIG_H -+# include -+#endif -+ -+#include "fist.h" -+#include "mini_fo.h" -+ -+/* check if file exists in storage */ -+int exists_in_storage(dentry_t *dentry) -+{ -+ check_mini_fo_dentry(dentry); -+ if(dtost(dentry) == MODIFIED || dtost(dentry) == CREATED || dtost(dentry) == DEL_REWRITTEN) -+ return 1; -+ return 0; -+} -+ -+/* check if dentry is in an existing state */ -+int is_mini_fo_existant(dentry_t *dentry) -+{ -+ check_mini_fo_dentry(dentry); -+ -+ if(dtost(dentry) == DELETED || dtost(dentry) == NON_EXISTANT) -+ return 0; -+ else -+ return 1; -+} -+ -+/* -+ * This function will create a negative storage dentry for -+ * dentry, what is required for many create like options. -+ * It will create the storage structure if necessary. -+ */ -+int get_neg_sto_dentry(dentry_t *dentry) -+{ -+ int err = 0; -+ unsigned int len; -+ const unsigned char *name; -+ -+ if(!dentry || -+ !dtopd(dentry) || -+ !(dtost(dentry) == UNMODIFIED || -+ dtost(dentry) == NON_EXISTANT || -+ dtost(dentry) == DELETED)) { -+ printk(KERN_CRIT "mini_fo: get_neg_sto_dentry: invalid dentry passed.\n"); -+ err = -1; -+ goto out; -+ } -+ /* Have we got a neg. dentry already? */ -+ if(dtohd2(dentry)) { -+ err = 0; -+ goto out; -+ } -+ if(dtost(dentry->d_parent) == UNMODIFIED) { -+ /* build sto struct */ -+ err = build_sto_structure(dentry->d_parent->d_parent, dentry->d_parent); -+ if(err || -+ dtost(dentry->d_parent) != MODIFIED) { -+ printk(KERN_CRIT "mini_fo: get_neg_sto_dentry: ERROR building sto structure.\n"); -+ err = -1; -+ goto out; -+ } -+ } -+ -+ len = dentry->d_name.len; -+ name = dentry->d_name.name; -+ -+ dtohd2(dentry) = -+ lookup_one_len(name, dtohd2(dentry->d_parent), len); -+ -+ out: -+ return err; -+} -+ -+int check_mini_fo_dentry(dentry_t *dentry) -+{ -+ ASSERT(dentry != NULL); -+ ASSERT(dtopd(dentry) != NULL); -+ ASSERT((dtohd(dentry) != NULL) || (dtohd2(dentry) != NULL)); -+ -+/* if(dtost(dentry) == MODIFIED) { */ -+/* ASSERT(dentry->d_inode != NULL); */ -+/* ASSERT(dtohd(dentry) != NULL); */ -+/* ASSERT(dtohd(dentry)->d_inode != NULL); */ -+/* ASSERT(dtohd2(dentry) != NULL); */ -+/* ASSERT(dtohd2(dentry)->d_inode != NULL); */ -+/* } */ -+/* else if(dtost(dentry) == UNMODIFIED) { */ -+/* ASSERT(dentry->d_inode != NULL); */ -+/* ASSERT( */ -+/* } */ -+ return 0; -+} -+ -+int check_mini_fo_file(file_t *file) -+{ -+ ASSERT(file != NULL); -+ ASSERT(ftopd(file) != NULL); -+ ASSERT(file->f_dentry != NULL); -+ -+ /* violent checking, check depending of state and type -+ * if(S_ISDIR(file->f_dentry->d_inode->i_mode)) {} -+ */ -+ ASSERT((ftohf(file) != NULL) || (ftohf2(file) != NULL)); -+ return 0; -+} -+ -+int check_mini_fo_inode(inode_t *inode) -+{ -+ ASSERT(inode != NULL); -+ ASSERT(itopd(inode) != NULL); -+ ASSERT((itohi(inode) != NULL) || (itohi2(inode) != NULL)); -+ return 0; -+} -+ -+/* -+ * will walk a base path as provided by get_mini_fo_bpath and return -+ * the (hopefully ;-) ) positive dentry of the renamed base dir. -+ * -+ * This does some work of path_init. -+ */ -+dentry_t *bpath_walk(super_block_t *sb, char *bpath) -+{ -+ int err; -+ struct vfsmount *mnt; -+ struct nameidata nd; -+ -+ /* be paranoid */ -+ if(!bpath || bpath[0] != '/') { -+ printk(KERN_CRIT "mini_fo: bpath_walk: Invalid string.\n"); -+ return NULL; -+ } -+ if(!sb || !stopd(sb)) { -+ printk(KERN_CRIT "mini_fo: bpath_walk: Invalid sb.\n"); -+ return NULL; -+ } -+ -+ /* fix this: how do I reach this lock? -+ * read_lock(¤t->fs->lock); */ -+ mnt = mntget(stopd(sb)->hidden_mnt); -+ /* read_unlock(¤t->fs->lock); */ -+ -+ err = vfs_path_lookup(mnt->mnt_root, mnt, bpath+1, 0, &nd); -+ -+ /* validate */ -+ if (err || !nd.dentry || !nd.dentry->d_inode) { -+ printk(KERN_CRIT "mini_fo: bpath_walk: path_walk failed.\n"); -+ return NULL; -+ } -+ return nd.dentry; -+} -+ -+ -+/* returns the full path of the basefile incl. its name */ -+int get_mini_fo_bpath(dentry_t *dentry, char **bpath, int *bpath_len) -+{ -+ char *buf_walker; -+ int len = 0; -+ dentry_t *sky_walker; -+ -+ if(!dentry || !dtohd(dentry)) { -+ printk(KERN_CRIT "mini_fo: get_mini_fo_bpath: invalid dentry passed.\n"); -+ return -1; -+ } -+ sky_walker = dtohd(dentry); -+ -+ do { -+ len += sky_walker->d_name.len + 1 ; /* 1 for '/' */ -+ sky_walker = sky_walker->d_parent; -+ } while(sky_walker != stopd(dentry->d_inode->i_sb)->base_dir_dentry); -+ -+ /* 1 to oil the loop */ -+ *bpath = (char*) kmalloc(len + 1, GFP_KERNEL); -+ if(!*bpath) { -+ printk(KERN_CRIT "mini_fo: get_mini_fo_bpath: out of mem.\n"); -+ return -1; -+ } -+ buf_walker = *bpath+len; /* put it on last char */ -+ *buf_walker = '\n'; -+ sky_walker = dtohd(dentry); -+ -+ do { -+ buf_walker -= sky_walker->d_name.len; -+ strncpy(buf_walker, -+ sky_walker->d_name.name, -+ sky_walker->d_name.len); -+ *(--buf_walker) = '/'; -+ sky_walker = sky_walker->d_parent; -+ } while(sky_walker != stopd(dentry->d_inode->i_sb)->base_dir_dentry); -+ -+ /* bpath_len doesn't count newline! */ -+ *bpath_len = len; -+ return 0; -+} -+ -+int mini_fo_cp_cont(dentry_t *tgt_dentry, struct vfsmount *tgt_mnt, -+ dentry_t *src_dentry, struct vfsmount *src_mnt) -+{ -+ void *buf; -+ mm_segment_t old_fs; -+ file_t *tgt_file; -+ file_t *src_file; -+ int bytes, len, tmp, err; -+ err = 0; -+ -+ if(!(tgt_dentry->d_inode && src_dentry->d_inode)) { -+ printk(KERN_CRIT "mini_fo_cp_cont: ERROR, neg. dentry passed.\n"); -+ err = -EINVAL; -+ goto out; -+ } -+ -+ dget(tgt_dentry); -+ dget(src_dentry); -+ mntget(tgt_mnt); -+ mntget(src_mnt); -+ -+ /* open file write only */ -+ tgt_file = dentry_open(tgt_dentry, tgt_mnt, 0x1); -+ if(!tgt_file || IS_ERR(tgt_file)) { -+ printk(KERN_CRIT "mini_fo_cp_cont: ERROR opening target file.\n"); -+ err = PTR_ERR(tgt_file); -+ goto out_err; -+ } -+ -+ /* open file read only */ -+ src_file = dentry_open(src_dentry, src_mnt, 0x0); -+ if(!src_file || IS_ERR(src_file)) { -+ printk(KERN_CRIT "mini_fo_cp_cont: ERROR opening source file.\n"); -+ err = PTR_ERR(src_file); -+ -+ /* close target file */ -+ fput(tgt_file); -+ goto out_err; -+ } -+ -+ /* check if the filesystem(s) support read respective write */ -+ if(!src_file->f_op->read || !tgt_file->f_op->write) { -+ printk(KERN_CRIT "mini_fo_cp_cont: ERROR, no fs read or write support.\n"); -+ err = -EPERM; -+ goto out_close; -+ } -+ -+ /* allocate a page for transfering the data */ -+ buf = (void *) __get_free_page(GFP_KERNEL); -+ if(!buf) { -+ printk(KERN_CRIT "mini_fo_cp_cont: ERROR, out of kernel mem.\n"); -+ goto out_err; -+ } -+ -+ tgt_file->f_pos = 0; -+ src_file->f_pos = 0; -+ -+ old_fs = get_fs(); -+ set_fs(KERNEL_DS); -+ -+ /* Doing this I assume that a read operation will return a full -+ * buffer while there is still data to read, and a less than -+ * full buffer when all data has been read. -+ */ -+ bytes = len = PAGE_SIZE; -+ while(bytes == len) { -+ bytes = src_file->f_op->read(src_file, buf, len, -+ &src_file->f_pos); -+ tmp = tgt_file->f_op->write(tgt_file, buf, bytes, -+ &tgt_file->f_pos); -+ if(tmp != bytes) { -+ printk(KERN_CRIT "mini_fo_cp_cont: ERROR writing.\n"); -+ goto out_close_unset; -+ } -+ } -+ -+ free_page((unsigned long) buf); -+ set_fs(old_fs); -+ fput(tgt_file); -+ fput(src_file); -+ goto out; -+ -+ out_close_unset: -+ free_page((unsigned long) buf); -+ set_fs(old_fs); -+ -+ out_close: -+ fput(tgt_file); -+ fput(src_file); -+ -+ out_err: -+ dput(tgt_dentry); -+ dput(src_dentry); -+ -+ /* mk: not sure if this need to be done */ -+ mntput(tgt_mnt); -+ mntput(src_mnt); -+ -+ out: -+ return err; -+} -+ -+/* mk: -+ * ndl (no-duplicate list) stuff -+ * This is used in mini_fo_readdir, to save the storage directory contents -+ * and later when reading base, match them against the list in order -+ * to avoid duplicates. -+ */ -+ -+/* add a file specified by name and len to the ndl -+ * Return values: 0 on success, <0 on failure. -+ */ -+int ndl_add_entry(struct readdir_data *rd, const char *name, int len) -+{ -+ struct ndl_entry *tmp_entry; -+ -+ tmp_entry = (struct ndl_entry *) -+ kmalloc(sizeof(struct ndl_entry), GFP_KERNEL); -+ if(!tmp_entry) { -+ printk(KERN_CRIT "mini_fo: ndl_add_entry: out of mem.\n"); -+ return -ENOMEM; -+ } -+ tmp_entry->name = (char*) kmalloc(len, GFP_KERNEL); -+ if(!tmp_entry->name) { -+ printk(KERN_CRIT "mini_fo: ndl_add_entry: out of mem.\n"); -+ return -ENOMEM; -+ } -+ strncpy(tmp_entry->name, name, len); -+ tmp_entry->len = len; -+ -+ list_add(&tmp_entry->list, &rd->ndl_list); -+ rd->ndl_size++; -+ return 0; -+} -+ -+/* delete all list entries and free memory */ -+void ndl_put_list(struct readdir_data *rd) -+{ -+ struct list_head *tmp; -+ struct ndl_entry *tmp_entry; -+ -+ if(rd->ndl_size <= 0) -+ return; -+ while(!list_empty(&rd->ndl_list)) { -+ tmp = rd->ndl_list.next; -+ list_del(tmp); -+ tmp_entry = list_entry(tmp, struct ndl_entry, list); -+ kfree(tmp_entry->name); -+ kfree(tmp_entry); -+ } -+ rd->ndl_size = 0; -+} -+ -+/* Check if a file specified by name and len is in the ndl -+ * Return value: 0 if not in list, 1 if file is found in ndl. -+ */ -+int ndl_check_entry(struct readdir_data *rd, const char *name, int len) -+{ -+ struct list_head *tmp; -+ struct ndl_entry *tmp_entry; -+ -+ if(rd->ndl_size <= 0) -+ return 0; -+ -+ list_for_each(tmp, &rd->ndl_list) { -+ tmp_entry = list_entry(tmp, struct ndl_entry, list); -+ if(tmp_entry->len != len) -+ continue; -+ if(!strncmp(tmp_entry->name, name, len)) -+ return 1; -+ } -+ return 0; -+} -+ -+/* mk: -+ * Recursive function to create corresponding directorys in the storage fs. -+ * The function will build the storage directorys up to dentry. -+ */ -+int build_sto_structure(dentry_t *dir, dentry_t *dentry) -+{ -+ int err; -+ dentry_t *hidden_sto_dentry; -+ dentry_t *hidden_sto_dir_dentry; -+ -+ if(dentry->d_parent != dir) { -+ printk(KERN_CRIT "mini_fo: build_sto_structure: invalid parameter or meta data corruption [1].\n"); -+ return 1; -+ } -+ -+ if(dtost(dir) != MODIFIED) { -+ err = build_sto_structure(dir->d_parent, dentry->d_parent); -+ if(err) -+ return err; -+ } -+ -+ /* ok, coming back again. */ -+ check_mini_fo_dentry(dentry); -+ hidden_sto_dentry = dtohd2(dentry); -+ -+ if(!hidden_sto_dentry) { -+ /* -+ * This is the case after creating the first -+ * hidden_sto_dentry. -+ * After one negative storage_dentry, all pointers to -+ * hidden_storage dentries are set to NULL. We need to -+ * create the negative dentry before we create the storage -+ * file. -+ */ -+ unsigned int len; -+ const unsigned char *name; -+ len = dtohd(dentry)->d_name.len; -+ name = dtohd(dentry)->d_name.name; -+ hidden_sto_dentry = lookup_one_len(name, dtohd2(dir), len); -+ dtohd2(dentry) = hidden_sto_dentry; -+ } -+ -+ /* was: hidden_sto_dir_dentry = lock_parent(hidden_sto_dentry); */ -+ hidden_sto_dir_dentry = dget(hidden_sto_dentry->d_parent); -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) -+ mutex_lock(&hidden_sto_dir_dentry->d_inode->i_mutex); -+#else -+ down(&hidden_sto_dir_dentry->d_inode->i_sem); -+#endif -+ /* lets be safe */ -+ if(dtohd2(dir) != hidden_sto_dir_dentry) { -+ printk(KERN_CRIT "mini_fo: build_sto_structure: invalid parameter or meta data corruption [2].\n"); -+ return 1; -+ } -+ -+ /* check for errors in lock_parent */ -+ err = PTR_ERR(hidden_sto_dir_dentry); -+ if(IS_ERR(hidden_sto_dir_dentry)) { -+ printk(KERN_CRIT "mini_fo: build_sto_structure: lock_parent failed.\n"); -+ return err; -+ } -+ -+ err = vfs_mkdir(hidden_sto_dir_dentry->d_inode, -+ hidden_sto_dentry, -+ dir->d_inode->i_mode); -+ -+ if(err) { -+ printk(KERN_CRIT "mini_fo: build_sto_structure: failed to create storage dir [1].\n"); -+ /* was: unlock_dir(dir); */ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) -+ mutex_unlock(&dir->d_inode->i_mutex); -+#else -+ up(&dir->d_inode->i_sem); -+#endif -+ dput(dir); -+ return err; -+ } -+ -+ /* everything ok! */ -+ if(!dtohd2(dentry)->d_inode) { -+ printk(KERN_CRIT "mini_fo: build_sto_structure: failed to create storage dir [2].\n"); -+ /* was: unlock_dir(dir); */ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) -+ mutex_unlock(&dir->d_inode->i_mutex); -+#else -+ up(&dir->d_inode->i_sem); -+#endif -+ dput(dir); -+ return 1; -+ } -+ -+ /* interpose the new inode and set new state */ -+ itohi2(dentry->d_inode) = igrab(dtohd2(dentry)->d_inode); -+ dtopd(dentry)->state = MODIFIED; -+ -+ /* initalize the wol list */ -+ itopd(dentry->d_inode)->deleted_list_size = -1; -+ itopd(dentry->d_inode)->renamed_list_size = -1; -+ meta_build_lists(dentry); -+ -+ fist_copy_attr_all(dentry->d_inode, itohi2(dentry->d_inode)); -+ fist_copy_attr_timesizes(dir->d_inode, -+ hidden_sto_dir_dentry->d_inode); -+ dir->d_inode->i_nlink++; -+ /* was: unlock_dir(hidden_sto_dir_dentry); */ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) -+ mutex_unlock(&hidden_sto_dir_dentry->d_inode->i_mutex); -+#else -+ up(&hidden_sto_dir_dentry->d_inode->i_sem); -+#endif -+ dput(hidden_sto_dir_dentry); -+ return 0; -+} -+ -+ -+#if 0 /* unused */ -+ -+/* -+ * Read "len" bytes from "filename" into "buf". -+ * "buf" is in kernel space. -+ */ -+int -+mini_fo_read_file(const char *filename, void *buf, int len) -+{ -+ file_t *filp; -+ mm_segment_t oldfs; -+ int bytes; -+ /* Chroot? Maybe NULL isn't right here */ -+ filp = filp_open(filename, O_RDONLY, 0); -+ if (!filp || IS_ERR(filp)) { -+ printk("mini_fo_read_file err %d\n", (int) PTR_ERR(filp)); -+ return -1; /* or do something else */ -+ } -+ -+ if (!filp->f_op->read) -+ return -2; /* file(system) doesn't allow reads */ -+ -+ /* now read len bytes from offset 0 */ -+ filp->f_pos = 0; /* start offset */ -+ oldfs = get_fs(); -+ set_fs(KERNEL_DS); -+ bytes = filp->f_op->read(filp, buf, len, &filp->f_pos); -+ set_fs(oldfs); -+ -+ /* close the file */ -+ fput(filp); -+ -+ return bytes; -+} -+ -+ -+ -+/* -+ * Write "len" bytes from "buf" to "filename" -+ * "buf" is in kernel space. -+ */ -+int -+mini_fo_write_file(const char *filename, void *buf, int len) -+{ -+ file_t *filp; -+ mm_segment_t oldfs; -+ int bytes; -+ /* Chroot? Maybe NULL isn't right here */ -+ filp = filp_open(filename, O_RDWR|O_CREAT, 0640); -+ if (!filp || IS_ERR(filp)) { -+ printk("mini_fo_write_file err %d\n", (int) PTR_ERR(filp)); -+ return -1; /* or do something else */ -+ } -+ -+ if (!filp->f_op->write) -+ return -2; /* file(system) doesn't allow writes */ -+ -+ /* now write len bytes from offset 0 */ -+ filp->f_pos = 0; /* start offset */ -+ oldfs = get_fs(); -+ set_fs(KERNEL_DS); -+ bytes = filp->f_op->write(filp, buf, len, &filp->f_pos); -+ set_fs(oldfs); -+ -+ /* close the file */ -+ fput(filp); -+ -+ return bytes; -+} -+ -+#endif /* unused */ -+ ---- /dev/null -+++ b/fs/mini_fo/ChangeLog -@@ -0,0 +1,281 @@ -+2006-01-24 Markus Klotzbuecher -+ -+ * Add tons of ugly ifdefs to Ed L. Cashin's mutex patch to -+ retain backwards compatibility. -+ -+2006-01-24 Ed L. Cashin -+ -+ * Support for the new mutex infrastructure -+ (7892f2f48d165a34b0b8130c8a195dfd807b8cb6) -+ -+2005-10-15 Markus Klotzbuecher -+ -+ * Bugfix for a serious memory leak in mini_fo_follow_link. -+ -+2005-09-21 Markus Klotzbuecher -+ -+ * new release 0.6.1 -+ -+ * fix of a compiler warning due to changes in 2.6.13 -+ -+2005-09-21 Klaus Wenninger -+ -+ * file.c: readdir: fix for a bug that caused directory entries -+ to show up twice when using storage filesystems such as -+ minixfs or pramfs. -+ -+2005-06-30 Eric Lammerts -+ -+ * fix for an oops when overwriting a binary thats beeing -+ executed. -+ -+2005-06-09 -+ -+ * Renamed overlay to mini_fo-overlay. -+ -+ * Added mini_fo-merge script to allow merging of storage and base -+ after making modifications. -+ -+2005-05-22 root -+ -+ * Added overlay script that allows to easily mount mini_fo ontop -+ of a given base directory -+ -+2005-05-10 -+ -+ * inode.c: xattr functions return -EOPNOSUPP instead of -+ -ENOSUPP, what confuses "ls -l" -+ -+ * Changed license from LGPL to GPL. -+ -+2005-05-08 root -+ -+ * Makefile: clean it up and added make install and make -+ uninstall. -+ -+2005-05-06 -+ -+ * merged devel branch back to main. [v0-6-0-pre3] -+ -+ * removed unused files print.c and fist_ioctl. [devel-0-0-18] -+ -+ * ioctl: removed fist_ioctl stuff, that is not needed for -+ now. -+ -+2005-05-03 -+ -+ * file.c: simplified mini_fo_open and mini_fo_setattr using -+ new state changing functions. [devel-0-0-17] -+ -+ * inode.c: Fixed getattr state bug (see below) in 2.4 function -+ mini_fo_inode revalidate. -+ -+ * inode.c: found an other bug in mini_fo_getattr. States are not -+ reliable in this function, as a file can be opened, unlinked and -+ the getattr function called. This results in a deleted dentry -+ with an inode. Fix is to ignore states and simply use the inode -+ available. -+ -+2005-04-29 -+ -+ * file.c: Bugfix and cleanup in fasync and fsync. [devel-0-0-16] -+ -+ * file.c: do not use mini_fo_lock so the generic version is -+ used (I guess). -+ -+ * inode.c: getattr, never call getattr on lower files, as this -+ will cause the inum to change. -+ -+ * inode.c: rename_reg_file renamed to rename_nondir, as it -+ doesn't matter as long it't not a dir. Removed all -+ rename_dev_file etc. -+ -+ * tagged as devel-0-0-15 -+ -+ * inode.c: added support for chosing support for extended -+ attrs at compile time by XATTR define in mini_fo.h . -+ -+ * inode.c: fixed mini_fo_getattr to use mini_fo inode and not -+ lower again, what avoids inode number changes that confused -+ rm again. This is the proper solution. -+ -+2005-04-24 -+ -+ * all files: updated Copyright notive to 2005. [devel-0-0-14] -+ -+ * inode.c: fixed mini_fo_getattr to not change the inode -+ number, even if lower files change. -+ -+ * super.c: fixed a bug that caused deleted base file to show -+ up suddenly after some time, or after creating a special -+ file. The problem was that after some time or after special -+ file creating sync_sb_inodes is called by the vfs, that -+ called our mini_fo_put_inode. There was (wrongly) called -+ __meta_put_lists, that nuked the lists, although the inode -+ was going to continue its life. Moving __meta_put_lists to -+ mini_fo_clear_inode, where an inode is really destroyed, -+ solved the problem. -+ -+ -+2005-04-23 -+ -+ * state.c, aux.c: more cleaning up and -+ simplifications. [devel-0-0-13] -+ -+ * inode.c: implemented mini_fo_getattr, that was required for -+ 2.6 because inode_revalidate has been remove there, and the -+ old "du" bug returned. -+ -+ -+2005-04-20 -+ -+ * aux.c: get_neg_sto_dentry(): allow to be called for dentries -+ in state UNMODIFIED, NON_EXISTANT _and_ DELETED. -+ -+2005-04-19 -+ -+ * Fixed a bug under 2.6 that caused files deleted via mini_fo -+ not to be deleted properly and therefore the fs filled up -+ untill no memory was left. [devel-0-0-12] -+ -+ * Added basic hard link support. This means that creating -+ hardlinks will work, but existing ones will be treated as -+ individual files. [devel-0-0-11] -+ -+2005-04-17 -+ -+ * Bugfixes -+ -+2005-04-13 root -+ -+ * Added file state.c for the state transition -+ functions. Doesn't work very well yet, though... -+ -+2005-04-12 -+ -+ * Porting to 2.6 started, which is easier than expected, also -+ due to Olivier previous work. -+ -+2005-04-08 -+ -+ * Fixed the bug that caused du to return invalid sizes of -+ directory trees. The problem was that -+ mini_fo_inode_revalidate didn't always copy the attributes -+ from the base inode properly. -+ -+2005-04-01 Markus Klotzbuecher -+ -+ * Merged devel branch back to main trunk and updated the -+ RELEASE notes. This will be 0-6-0-pre1. -+ -+2005-03-31 Markus Klotzbuecher -+ -+ * Fixed some bugs in rename_reg_file, that only showed up in -+ the kernel compile test. Kernel compiles cleanly ontop of -+ mini_fo, now also make mrproper etc. work. Seems pretty stable. -+ -+2005-03-28 Markus Klotzbuecher -+ -+ * Many, many directory renaming bugfixes and a lot of other -+ cleanup. Dir renaming seems to work relatively stable. -+ -+2005-03-22 Markus Klotzbuecher -+ -+ * Finished implementing lightweight directory renaming. Some -+ basic testing indicates it works fine. -+ Next is to implement testcases for the testsuite and confirm -+ everything is really working ok. -+ -+2005-03-18 Markus Klotzbuecher -+ -+ * Finished implementing meta.c stuff required for directory -+ renaming. -+ -+2005-03-17 Markus Klotzbuecher -+ -+ * Fixed all compile warnings + an extremly old bug that -+ somehow crept in while reworking the wol stuff to the META -+ system. Turning on -Werror again... :-) -+ -+ * Fixed some bugs in the new rename_reg_file function. -+ -+ * Rewrote mini_fo rename and split it into several -+ subfunctions, that handle the different types -+ seperately. Rewrote the regular file function aswell, as it -+ was implemented somewhat inefficient. -+ -+2005-03-16 Markus Klotzbuecher -+ -+ * Implemented new META subsystem, removed old WOL stuff in favor -+ if it. -+ -+ * After some basic testing everything seems ok... -+ -+2005-03-11 Markus Klotzbuecher -+ -+ * Renaming a non regular file caused trouble because I always -+ tried to copy the contents. Now I only do this for regular -+ files. mini_fo_rename still isn't implemented properly, renaming -+ of device files, symlinks etc. results in a empty regular file -+ instead of the proper type. -+ -+ * Directory renaming suddenly works! What a surprise! I guess -+ this is because renaming is implemented as making a copy and -+ removing the original. Still this might not work -+ everywhere... -+ -+2005-03-09 Markus Klotzbuecher -+ -+ * Bugfix, when a mini_fo directory that exists in storage -+ (state: MODIFIED, CREATED and DEL_REWRITTEN) is deleted, a -+ possibly existing WOL file contained in it needs to be -+ deleted too. -+ -+ * Starting cleanup: defined state names in order to get rid of -+ the state numbers. -+ -+2005-03-08 Markus Klotzbuecher -+ -+ * Makefile fix, fist_ioctl was built against wrong sources if ARCH=um -+ -+ * Fixed a bug in dentry.c, mini_fo_d_hash. In state 4 = -+ DEL_REWRITTEN the hash was calculated from the base dentry, -+ which was wrong and and caused assertions in -+ __mini_fo_hidden_dentry to fail. -+ -+2005-02-21 -+ -+ * Implemented directory deleting (inode.c) -+ -+ * main.c: made mini_fo_parse_options a little more robust. -+ -+2004-12-22 -+ -+ * Makefile cleanup and uml stuff, removed unneccessary files -+ -+ * Created a new and hopefully more informative README -+ -+ * CHANGELOG: created a new CHANGELOG and added old entries reversely -+ -+ -+2004-10-24 Gleb Natapov -+ -+ * Fix: owner and group where not correctly copied from base to -+ storage. -+ -+ -+2004-10-05 Gleb Natapov -+ -+ * Implementation of fsync, fasync and lock mini_fo functions. -+ -+ -+2004-09-29 Bob Lee -+ -+ * Fix of a serious pointer bug -+ -+ -+2004-09-28 Gleb Natapov -+ -+ * Implementation of mini_fo_mknod and mini_fo_rename, support -+ for device files. -+ ---- /dev/null -+++ b/fs/mini_fo/dentry.c -@@ -0,0 +1,244 @@ -+/* -+ * Copyright (c) 1997-2003 Erez Zadok -+ * Copyright (c) 2001-2003 Stony Brook University -+ * -+ * For specific licensing information, see the COPYING file distributed with -+ * this package, or get one from ftp://ftp.filesystems.org/pub/fist/COPYING. -+ * -+ * This Copyright notice must be kept intact and distributed with all -+ * fistgen sources INCLUDING sources generated by fistgen. -+ */ -+/* -+ * Copyright (C) 2004, 2005 Markus Klotzbuecher -+ * -+ * 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. -+ */ -+ -+/* -+ * $Id$ -+ */ -+ -+#ifdef HAVE_CONFIG_H -+# include -+#endif -+ -+#include "fist.h" -+#include "mini_fo.h" -+ -+/* -+ * THIS IS A BOOLEAN FUNCTION: returns 1 if valid, 0 otherwise. -+ */ -+STATIC int -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -+mini_fo_d_revalidate(dentry_t *dentry, struct nameidata *nd) -+#else -+mini_fo_d_revalidate(dentry_t *dentry, int flags) -+#endif -+{ -+ int err1 = 1; /* valid = 1, invalid = 0 */ -+ int err2 = 1; -+ dentry_t *hidden_dentry; -+ dentry_t *hidden_sto_dentry; -+ -+ -+ check_mini_fo_dentry(dentry); -+ -+ hidden_dentry = dtohd(dentry); -+ hidden_sto_dentry = dtohd2(dentry); -+ -+ if(hidden_dentry && -+ hidden_dentry->d_op && -+ hidden_dentry->d_op->d_revalidate) { -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -+ err1 = hidden_dentry->d_op->d_revalidate(hidden_dentry, nd); -+#else -+ err1 = hidden_dentry->d_op->d_revalidate(hidden_dentry, flags); -+#endif -+ } -+ if(hidden_sto_dentry && -+ hidden_sto_dentry->d_op && -+ hidden_sto_dentry->d_op->d_revalidate) { -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -+ err2 = hidden_sto_dentry->d_op->d_revalidate(hidden_sto_dentry, -+ nd); -+#else -+ err2 = hidden_sto_dentry->d_op->d_revalidate(hidden_sto_dentry, -+ flags); -+#endif -+ } -+ -+ /* mk: if one of the lower level dentries are valid, -+ * the mini_fo dentry is too. -+ */ -+ return (err1 || err2); -+} -+ -+ -+STATIC int -+mini_fo_d_hash(dentry_t *dentry, qstr_t *name) -+{ -+ int err = 0; -+ dentry_t *hidden_dentry; -+ dentry_t *hidden_sto_dentry; -+ -+ /* hidden_dentry = mini_fo_hidden_dentry(dentry); -+ * hidden_sto_dentry = mini_fo_hidden_sto_dentry(dentry); */ -+ -+ /* state 1, 3, 4, 5: build the hash for the storage dentry */ -+ if((dtopd(dentry)->state == MODIFIED) || -+ (dtopd(dentry)->state == CREATED) || -+ (dtopd(dentry)->state == DEL_REWRITTEN) || -+ (dtopd(dentry)->state == DELETED)) { -+ hidden_sto_dentry = dtohd2(dentry); -+ if(hidden_sto_dentry && -+ hidden_sto_dentry->d_op && -+ hidden_sto_dentry->d_op->d_hash) { -+ err = hidden_sto_dentry->d_op->d_hash(hidden_sto_dentry, name); -+ } -+ goto out; -+ } -+ /* state 2: build the hash for the base dentry */ -+ if(dtopd(dentry)->state == UNMODIFIED) { -+ hidden_dentry = dtohd(dentry); -+ if(hidden_dentry && -+ hidden_dentry->d_op && -+ hidden_dentry->d_op->d_hash) { -+ err = hidden_dentry->d_op->d_hash(hidden_dentry, name); -+ } -+ goto out; -+ } -+ /* state 6: build hash for the dentry that exists */ -+ if(dtopd(dentry)->state == NON_EXISTANT) { -+ hidden_sto_dentry = dtohd2(dentry); -+ if(hidden_sto_dentry && -+ hidden_sto_dentry->d_op && -+ hidden_sto_dentry->d_op->d_hash) { -+ err = hidden_sto_dentry->d_op->d_hash(hidden_sto_dentry, name); -+ goto out; -+ } -+ hidden_dentry = dtohd(dentry); -+ if(hidden_dentry && -+ hidden_dentry->d_op && -+ hidden_dentry->d_op->d_hash) { -+ err = hidden_dentry->d_op->d_hash(hidden_dentry, name); -+ goto out; -+ } -+ } -+ -+ printk(KERN_CRIT "mini_fo: d_hash: invalid state detected.\n"); -+ -+ out: -+ return err; -+} -+ -+ -+STATIC int -+mini_fo_d_compare(dentry_t *dentry, qstr_t *a, qstr_t *b) -+{ -+ int err; -+ dentry_t *hidden_dentry=NULL; -+ -+ /* hidden_dentry = mini_fo_hidden_dentry(dentry); */ -+ if(dtohd2(dentry)) -+ hidden_dentry = dtohd2(dentry); -+ else if(dtohd(dentry)) -+ hidden_dentry = dtohd(dentry); -+ -+ if (hidden_dentry && hidden_dentry->d_op && hidden_dentry->d_op->d_compare) { -+ err = hidden_dentry->d_op->d_compare(hidden_dentry, a, b); -+ } else { -+ err = ((a->len != b->len) || memcmp(a->name, b->name, b->len)); -+ } -+ -+ return err; -+} -+ -+ -+int -+mini_fo_d_delete(dentry_t *dentry) -+{ -+ dentry_t *hidden_dentry; -+ dentry_t *hidden_sto_dentry; -+ int err = 0; -+ -+ /* this could be a negative dentry, so check first */ -+ if (!dtopd(dentry)) { -+ printk(KERN_CRIT "mini_fo_d_delete: negative dentry passed.\n"); -+ goto out; -+ } -+ hidden_dentry = dtohd(dentry); -+ hidden_sto_dentry = dtohd2(dentry); -+ -+ if(hidden_dentry) { -+ if(hidden_dentry->d_op && -+ hidden_dentry->d_op->d_delete) { -+ err = hidden_dentry->d_op->d_delete(hidden_dentry); -+ } -+ } -+ if(hidden_sto_dentry) { -+ if(hidden_sto_dentry->d_op && -+ hidden_sto_dentry->d_op->d_delete) { -+ err = hidden_sto_dentry->d_op->d_delete(hidden_sto_dentry); -+ } -+ } -+ -+ out: -+ return err; -+} -+ -+ -+void -+mini_fo_d_release(dentry_t *dentry) -+{ -+ dentry_t *hidden_dentry; -+ dentry_t *hidden_sto_dentry; -+ -+ -+ /* this could be a negative dentry, so check first */ -+ if (!dtopd(dentry)) { -+ printk(KERN_CRIT "mini_fo_d_release: no private data.\n"); -+ goto out; -+ } -+ hidden_dentry = dtohd(dentry); -+ hidden_sto_dentry = dtohd2(dentry); -+ -+ if(hidden_dentry) { -+ /* decrement hidden dentry's counter and free its inode */ -+ dput(hidden_dentry); -+ } -+ if(hidden_sto_dentry) { -+ /* decrement hidden dentry's counter and free its inode */ -+ dput(hidden_sto_dentry); -+ } -+ -+ /* free private data (mini_fo_dentry_info) here */ -+ kfree(dtopd(dentry)); -+ __dtopd(dentry) = NULL; /* just to be safe */ -+ out: -+ return; -+} -+ -+ -+/* -+ * we don't really need mini_fo_d_iput, because dentry_iput will call iput() if -+ * mini_fo_d_iput is not defined. We left this implemented for ease of -+ * tracing/debugging. -+ */ -+void -+mini_fo_d_iput(dentry_t *dentry, inode_t *inode) -+{ -+ iput(inode); -+} -+ -+ -+struct dentry_operations mini_fo_dops = { -+ d_revalidate: mini_fo_d_revalidate, -+ d_hash: mini_fo_d_hash, -+ d_compare: mini_fo_d_compare, -+ d_release: mini_fo_d_release, -+ d_delete: mini_fo_d_delete, -+ d_iput: mini_fo_d_iput, -+}; ---- /dev/null -+++ b/fs/mini_fo/file.c -@@ -0,0 +1,713 @@ -+/* -+ * Copyright (c) 1997-2003 Erez Zadok -+ * Copyright (c) 2001-2003 Stony Brook University -+ * -+ * For specific licensing information, see the COPYING file distributed with -+ * this package, or get one from ftp://ftp.filesystems.org/pub/fist/COPYING. -+ * -+ * This Copyright notice must be kept intact and distributed with all -+ * fistgen sources INCLUDING sources generated by fistgen. -+ */ -+/* -+ * Copyright (C) 2004, 2005 Markus Klotzbuecher -+ * -+ * 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. -+ */ -+ -+/* -+ * $Id$ -+ */ -+ -+#ifdef HAVE_CONFIG_H -+# include -+#endif -+ -+#include "fist.h" -+#include "mini_fo.h" -+#define ROUND_UP(x) (((x)+sizeof(long)-1) & ~(sizeof(long)-1)) -+ -+/******************* -+ * File Operations * -+ *******************/ -+ -+STATIC loff_t -+mini_fo_llseek(file_t *file, loff_t offset, int origin) -+{ -+ loff_t err; -+ file_t *hidden_file = NULL; -+ -+ if(S_ISDIR(file->f_dentry->d_inode->i_mode)) { -+ /* Check if trying to llseek from a directory */ -+ err = -EISDIR; -+ goto out; -+ } -+ if (ftopd(file) != NULL) { -+ if(ftohf2(file)) { -+ hidden_file = ftohf2(file); -+ } else { -+ hidden_file = ftohf(file); -+ } -+ } -+ -+ /* always set hidden position to this one */ -+ hidden_file->f_pos = file->f_pos; -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -+ memcpy(&(hidden_file->f_ra), -+ &(file->f_ra), -+ sizeof(struct file_ra_state)); -+#else -+ if (file->f_reada) { /* update readahead information if needed */ -+ hidden_file->f_reada = file->f_reada; -+ hidden_file->f_ramax = file->f_ramax; -+ hidden_file->f_raend = file->f_raend; -+ hidden_file->f_ralen = file->f_ralen; -+ hidden_file->f_rawin = file->f_rawin; -+ } -+#endif -+ if (hidden_file->f_op && hidden_file->f_op->llseek) -+ err = hidden_file->f_op->llseek(hidden_file, offset, origin); -+ else -+ err = generic_file_llseek(hidden_file, offset, origin); -+ -+ if (err < 0) -+ goto out; -+ -+ if (err != file->f_pos) { -+ file->f_pos = err; -+ // ION maybe this? -+ // file->f_pos = hidden_file->f_pos; -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) -+ file->f_reada = 0; -+#endif -+ file->f_version++; -+ } -+ -+ out: -+ return err; -+} -+ -+ -+/* mk: fanout capable */ -+STATIC ssize_t -+mini_fo_read(file_t *file, char *buf, size_t count, loff_t *ppos) -+{ -+ int err = -EINVAL; -+ file_t *hidden_file = NULL; -+ loff_t pos = *ppos; -+ -+ if(S_ISDIR(file->f_dentry->d_inode->i_mode)) { -+ /* Check if trying to read from a directory */ -+ /* printk(KERN_CRIT "mini_fo_read: ERROR: trying to read data from a directory.\n"); */ -+ err = -EISDIR; -+ goto out; -+ } -+ -+ if (ftopd(file) != NULL) { -+ if(ftohf2(file)) { -+ hidden_file = ftohf2(file); -+ } else { -+ hidden_file = ftohf(file); -+ } -+ } -+ -+ if (!hidden_file->f_op || !hidden_file->f_op->read) -+ goto out; -+ -+ err = hidden_file->f_op->read(hidden_file, buf, count, &pos); -+ *ppos = pos; -+ -+ if (err >= 0) { -+ /* atime should also be updated for reads of size zero or more */ -+ fist_copy_attr_atime(file->f_dentry->d_inode, -+ hidden_file->f_dentry->d_inode); -+ } -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) -+ /* -+ * MAJOR HACK -+ * because pread() does not have any way to tell us that it is -+ * our caller, then we don't know for sure if we have to update -+ * the file positions. This hack relies on read() having passed us -+ * the "real" pointer of its struct file's f_pos field. -+ */ -+ if (ppos == &file->f_pos) -+ hidden_file->f_pos = *ppos = pos; -+ if (hidden_file->f_reada) { /* update readahead information if needed */ -+ file->f_reada = hidden_file->f_reada; -+ file->f_ramax = hidden_file->f_ramax; -+ file->f_raend = hidden_file->f_raend; -+ file->f_ralen = hidden_file->f_ralen; -+ file->f_rawin = hidden_file->f_rawin; -+ } -+#else -+ memcpy(&(file->f_ra),&(hidden_file->f_ra),sizeof(struct file_ra_state)); -+#endif -+ -+ out: -+ return err; -+} -+ -+ -+/* this mini_fo_write() does not modify data pages! */ -+STATIC ssize_t -+mini_fo_write(file_t *file, const char *buf, size_t count, loff_t *ppos) -+{ -+ int err = -EINVAL; -+ file_t *hidden_file = NULL; -+ inode_t *inode; -+ inode_t *hidden_inode; -+ loff_t pos = *ppos; -+ -+ /* mk: fan out: */ -+ if (ftopd(file) != NULL) { -+ if(ftohf2(file)) { -+ hidden_file = ftohf2(file); -+ } else { -+ /* This is bad! We have no storage file to write to. This -+ * should never happen because if a file is opened for -+ * writing, a copy should have been made earlier. -+ */ -+ printk(KERN_CRIT "mini_fo: write : ERROR, no storage file to write.\n"); -+ err = -EINVAL; -+ goto out; -+ } -+ } -+ -+ inode = file->f_dentry->d_inode; -+ hidden_inode = itohi2(inode); -+ if(!hidden_inode) { -+ printk(KERN_CRIT "mini_fo: write: no sto inode found, not good.\n"); -+ goto out; -+ } -+ -+ if (!hidden_file->f_op || !hidden_file->f_op->write) -+ goto out; -+ -+ /* adjust for append -- seek to the end of the file */ -+ if (file->f_flags & O_APPEND) -+ pos = inode->i_size; -+ -+ err = hidden_file->f_op->write(hidden_file, buf, count, &pos); -+ -+ /* -+ * copy ctime and mtime from lower layer attributes -+ * atime is unchanged for both layers -+ */ -+ if (err >= 0) -+ fist_copy_attr_times(inode, hidden_inode); -+ -+ *ppos = pos; -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) -+ /* -+ * XXX: MAJOR HACK -+ * -+ * because pwrite() does not have any way to tell us that it is -+ * our caller, then we don't know for sure if we have to update -+ * the file positions. This hack relies on write() having passed us -+ * the "real" pointer of its struct file's f_pos field. -+ */ -+ if (ppos == &file->f_pos) -+ hidden_file->f_pos = *ppos = pos; -+#endif -+ /* update this inode's size */ -+ if (pos > inode->i_size) -+ inode->i_size = pos; -+ -+ out: -+ return err; -+} -+ -+/* Global variable to hold a file_t pointer. -+ * This serves to allow mini_fo_filldir function to know which file is -+ * beeing read, which is required for two reasons: -+ * -+ * - be able to call wol functions in order to avoid listing deleted -+ * base files. -+ * - if we're reading a directory which is in state 1, we need to -+ * maintain a list (in mini_fo_filldir) of which files allready -+ * have been copied to userspace,to detect files existing in base -+ * and storage and not list them twice. -+ */ -+filldir_t mini_fo_filldir_orig; -+file_t *mini_fo_filldir_file; -+ -+/* mainly copied from fs/readdir.c */ -+STATIC int -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) -+mini_fo_filldir(void * __buf, const char * name, int namlen, loff_t offset, -+ u64 ino, unsigned int d_type) -+#else -+mini_fo_filldir(void * __buf, const char * name, int namlen, loff_t offset, -+ ino_t ino, unsigned int d_type) -+#endif -+{ -+ struct getdents_callback * buf = (struct getdents_callback *) __buf; -+ file_t* file = mini_fo_filldir_file; -+ -+ /* In theses states we filter meta files in storage (WOL) */ -+ if(file && (dtopd(file->f_dentry)->state == MODIFIED || -+ dtopd(file->f_dentry)->state == CREATED || -+ dtopd(file->f_dentry)->state == DEL_REWRITTEN)) { -+ -+ int tmp = strlen(META_FILENAME); -+ if(tmp == namlen) { -+ if(!strncmp(name, META_FILENAME, namlen)) -+ return 0; -+ } -+ } -+ -+ /* check if we are merging the contents of storage and base */ -+ if(file && dtopd(file->f_dentry)->state == MODIFIED) { -+ /* check if we are still reading storage contents, if -+ * yes, we just save the name of the file for duplicate -+ * checking later. */ -+ -+ if(!ftopd(file)->rd.sto_done) { -+ /* put file into ndl list */ -+ if(ndl_add_entry(&ftopd(file)->rd, name, namlen)) -+ printk(KERN_CRIT "mini_fo_filldir: Error adding to ndl.\n"); -+ } else { -+ /* check if file has been deleted */ -+ if(meta_check_d_entry(file->f_dentry, name, namlen)) -+ return 0; -+ -+ /* do duplicate checking */ -+ if(ndl_check_entry(&ftopd(file)->rd, name, namlen)) -+ return 0; -+ } -+ } -+ -+ return mini_fo_filldir_orig(buf, name, namlen, offset, ino, d_type); -+} -+ -+ -+STATIC int -+mini_fo_readdir(file_t *file, void *dirent, filldir_t filldir) -+{ -+ int err = 0;/* mk: ??? -ENOTDIR; */ -+ file_t *hidden_file = NULL; -+ file_t *hidden_sto_file = NULL; -+ inode_t *inode; -+ struct getdents_callback *buf; -+ int oldcount; -+ -+#if defined(FIST_FILTER_NAME) || defined(FIST_FILTER_SCA) -+ struct mini_fo_getdents_callback buf; -+#endif /* FIST_FILTER_NAME || FIST_FILTER_SCA */ -+ -+ buf = (struct getdents_callback *) dirent; -+ oldcount = buf->count; -+ inode = file->f_dentry->d_inode; -+ mini_fo_filldir_file = file; -+ mini_fo_filldir_orig = filldir; -+ -+ ftopd(file)->rd.sto_done = 0; -+ do { -+ if (ftopd(file) != NULL) { -+ if(ftohf2(file)) { -+ hidden_sto_file = ftohf2(file); -+ err = vfs_readdir(hidden_sto_file, mini_fo_filldir, dirent); -+ file->f_pos = hidden_sto_file->f_pos; -+ if (err > 0) -+ fist_copy_attr_atime(inode, hidden_sto_file->f_dentry->d_inode); -+ /* not finshed yet, we'll be called again */ -+ if (buf->count != oldcount) -+ break; -+ } -+ -+ ftopd(file)->rd.sto_done = 1; -+ -+ if(ftohf(file)) { -+ hidden_file = ftohf(file); -+ err = vfs_readdir(hidden_file, mini_fo_filldir, dirent); -+ file->f_pos = hidden_file->f_pos; -+ if (err > 0) -+ fist_copy_attr_atime(inode, hidden_file->f_dentry->d_inode); -+ } -+ -+ } -+ } while (0); -+ -+ /* mk: -+ * we need to check if all the directory data has been copied to userspace, -+ * or if we will be called again by userspace to complete the operation. -+ */ -+ if(buf->count == oldcount) { -+ ndl_put_list(&ftopd(file)->rd); -+ } -+ -+ /* unset this, safe */ -+ mini_fo_filldir_file = NULL; -+ return err; -+} -+ -+ -+STATIC unsigned int -+mini_fo_poll(file_t *file, poll_table *wait) -+{ -+ unsigned int mask = DEFAULT_POLLMASK; -+ file_t *hidden_file = NULL; -+ -+ if (ftopd(file) != NULL) { -+ if(ftohf2(file)) { -+ hidden_file = ftohf2(file); -+ } else { -+ hidden_file = ftohf(file); -+ } -+ } -+ -+ if (!hidden_file->f_op || !hidden_file->f_op->poll) -+ goto out; -+ -+ mask = hidden_file->f_op->poll(hidden_file, wait); -+ -+ out: -+ return mask; -+} -+ -+/* FIST-LITE special version of mmap */ -+STATIC int -+mini_fo_mmap(file_t *file, vm_area_t *vma) -+{ -+ int err = 0; -+ file_t *hidden_file = NULL; -+ -+ /* fanout capability */ -+ if (ftopd(file) != NULL) { -+ if(ftohf2(file)) { -+ hidden_file = ftohf2(file); -+ } else { -+ hidden_file = ftohf(file); -+ } -+ } -+ -+ ASSERT(hidden_file != NULL); -+ ASSERT(hidden_file->f_op != NULL); -+ ASSERT(hidden_file->f_op->mmap != NULL); -+ -+ vma->vm_file = hidden_file; -+ err = hidden_file->f_op->mmap(hidden_file, vma); -+ get_file(hidden_file); /* make sure it doesn't get freed on us */ -+ fput(file); /* no need to keep extra ref on ours */ -+ -+ return err; -+} -+ -+ -+ -+STATIC int -+mini_fo_open(inode_t *inode, file_t *file) -+{ -+ int err = 0; -+ int hidden_flags; -+ file_t *hidden_file = NULL; -+ dentry_t *hidden_dentry = NULL; -+ -+ /* fanout stuff */ -+ file_t *hidden_sto_file = NULL; -+ dentry_t *hidden_sto_dentry = NULL; -+ -+ __ftopd(file) = -+ kmalloc(sizeof(struct mini_fo_file_info), GFP_KERNEL); -+ if (!ftopd(file)) { -+ err = -ENOMEM; -+ goto out; -+ } -+ -+ /* init the readdir_helper structure */ -+ INIT_LIST_HEAD(&ftopd(file)->rd.ndl_list); -+ ftopd(file)->rd.ndl_size = 0; -+ -+ /* In certain paths this could stay uninitalized and cause trouble */ -+ ftohf(file) = NULL; -+ ftohf2(file) = NULL; -+ hidden_flags = file->f_flags; -+ -+ /* create storage files? */ -+ if(dtost(file->f_dentry) == UNMODIFIED) { -+ if(!IS_WRITE_FLAG(file->f_flags)) { -+ hidden_dentry = dtohd(file->f_dentry); -+ dget(hidden_dentry); -+ /* dentry_open will decrement mnt refcnt if err. -+ * otherwise fput() will do an mntput() for us upon file close. */ -+ mntget(stopd(inode->i_sb)->hidden_mnt); -+ hidden_file = dentry_open(hidden_dentry, -+ stopd(inode->i_sb)->hidden_mnt, -+ hidden_flags); -+ if (IS_ERR(hidden_file)) { -+ err = PTR_ERR(hidden_file); -+ dput(hidden_dentry); -+ goto out; -+ } -+ ftohf(file) = hidden_file; /* link two files */ -+ goto out; -+ } -+ else { -+ if(S_ISDIR(file->f_dentry->d_inode->i_mode)) { -+ err = dir_unmod_to_mod(file->f_dentry); -+ } else -+ err = nondir_unmod_to_mod(file->f_dentry, 1); -+ -+ if (err) { -+ printk("mini_fo_open: ERROR creating storage file.\n"); -+ goto out; -+ } -+ } -+ } -+ hidden_sto_dentry = dtohd2(file->f_dentry); -+ dget(hidden_sto_dentry); -+ -+ if(dtopd(file->f_dentry)->state == MODIFIED) { -+ /* Directorys are special, interpose on both lower level files */ -+ if(S_ISDIR(itohi(inode)->i_mode)) { -+ /* check for invalid file types of lower level files */ -+ if(!(S_ISDIR(itohi(inode)->i_mode) && S_ISDIR(itohi2(inode)->i_mode))) { -+ printk(KERN_CRIT "mini_fo_open: meta data corruption detected.\n"); -+ dput(hidden_sto_dentry); -+ err = -EINVAL; -+ goto out; -+ } -+ -+ /* lower level directorys are ok, open the base file */ -+ hidden_dentry = dtohd(file->f_dentry); -+ dget(hidden_dentry); -+ -+ mntget(stopd(inode->i_sb)->hidden_mnt); -+ hidden_file = dentry_open(hidden_dentry, -+ stopd(inode->i_sb)->hidden_mnt, -+ hidden_flags); -+ if (IS_ERR(hidden_file)) { -+ err = PTR_ERR(hidden_file); -+ dput(hidden_dentry); -+ dput(hidden_sto_dentry); -+ goto out; -+ } -+ ftohf(file) = hidden_file; /* link the two files */ -+ } -+ } -+ -+ if(!exists_in_storage(file->f_dentry)) { -+ printk(KERN_CRIT "mini_fo_open: invalid file state detected.\n"); -+ err = -EINVAL; -+ dput(hidden_sto_dentry); -+ -+ /* If the base file has been opened, we need to close it here */ -+ if(ftohf(file)) { -+ if (hidden_file->f_op && hidden_file->f_op->flush) -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) -+ hidden_file->f_op->flush(hidden_file, NULL); -+#else -+ hidden_file->f_op->flush(hidden_file); -+#endif -+ dput(hidden_dentry); -+ } -+ goto out; -+ } -+ -+ /* ok, now we can safely open the storage file */ -+ mntget(stopd(inode->i_sb)->hidden_mnt2); -+ hidden_sto_file = dentry_open(hidden_sto_dentry, -+ stopd(inode->i_sb)->hidden_mnt2, -+ hidden_flags); -+ -+ /* dentry_open dputs the dentry if it fails */ -+ if (IS_ERR(hidden_sto_file)) { -+ err = PTR_ERR(hidden_sto_file); -+ /* close base file if open */ -+ if(ftohf(file)) { -+ if (hidden_file->f_op && hidden_file->f_op->flush) -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) -+ hidden_file->f_op->flush(hidden_file, NULL); -+#else -+ hidden_file->f_op->flush(hidden_file); -+#endif -+ dput(hidden_dentry); -+ } -+ goto out; -+ } -+ ftohf2(file) = hidden_sto_file; /* link storage file */ -+ -+ out: -+ if (err < 0 && ftopd(file)) { -+ kfree(ftopd(file)); -+ } -+ return err; -+} -+ -+STATIC int -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) -+mini_fo_flush(file_t *file, fl_owner_t id) -+#else -+mini_fo_flush(file_t *file) -+#endif -+{ -+ int err1 = 0; /* assume ok (see open.c:close_fp) */ -+ int err2 = 0; -+ file_t *hidden_file = NULL; -+ -+ check_mini_fo_file(file); -+ -+ /* mk: we don't do any state checking here, as its not worth the time. -+ * Just flush the lower level files if they exist. -+ */ -+ if(ftopd(file) != NULL) { -+ if(ftohf(file) != NULL) { -+ hidden_file = ftohf(file); -+ if (hidden_file->f_op && hidden_file->f_op->flush) -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) -+ err1 = hidden_file->f_op->flush(hidden_file, id); -+#else -+ err1 = hidden_file->f_op->flush(hidden_file); -+#endif -+ } -+ if(ftohf2(file) != NULL) { -+ hidden_file = ftohf2(file); -+ if (hidden_file->f_op && hidden_file->f_op->flush) -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) -+ err2 = hidden_file->f_op->flush(hidden_file, id); -+#else -+ err2 = hidden_file->f_op->flush(hidden_file); -+#endif -+ } -+ } -+ return (err1 | err2); -+} -+ -+ -+STATIC int -+mini_fo_release(inode_t *inode, file_t *file) -+{ -+ int err = 0; -+ file_t *hidden_file = NULL; -+ -+ if (ftopd(file) != NULL) { -+ if(ftohf(file)) { -+ hidden_file = ftohf(file); -+ fput(hidden_file); -+ } -+ if(ftohf2(file)) { -+ hidden_file = ftohf2(file); -+ fput(hidden_file); -+ } -+ kfree(ftopd(file)); -+ } -+ return err; -+} -+ -+STATIC int -+mini_fo_fsync(file_t *file, dentry_t *dentry, int datasync) -+{ -+ int err1 = 0; -+ int err2 = 0; -+ file_t *hidden_file = NULL; -+ dentry_t *hidden_dentry; -+ -+ check_mini_fo_file(file); -+ -+ if ((hidden_file = ftohf(file)) != NULL) { -+ hidden_dentry = dtohd(dentry); -+ if (hidden_file->f_op && hidden_file->f_op->fsync) { -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) -+ mutex_lock(&hidden_dentry->d_inode->i_mutex); -+#else -+ down(&hidden_dentry->d_inode->i_sem); -+#endif -+ err1 = hidden_file->f_op->fsync(hidden_file, hidden_dentry, datasync); -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) -+ mutex_unlock(&hidden_dentry->d_inode->i_mutex); -+#else -+ up(&hidden_dentry->d_inode->i_sem); -+#endif -+ } -+ } -+ -+ if ((hidden_file = ftohf2(file)) != NULL) { -+ hidden_dentry = dtohd2(dentry); -+ if (hidden_file->f_op && hidden_file->f_op->fsync) { -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) -+ mutex_lock(&hidden_dentry->d_inode->i_mutex); -+#else -+ down(&hidden_dentry->d_inode->i_sem); -+#endif -+ err2 = hidden_file->f_op->fsync(hidden_file, hidden_dentry, datasync); -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) -+ mutex_unlock(&hidden_dentry->d_inode->i_mutex); -+#else -+ up(&hidden_dentry->d_inode->i_sem); -+#endif -+ } -+ } -+ else -+ goto err; -+ -+err: -+ return (err1 || err2); -+} -+ -+ -+STATIC int -+mini_fo_fasync(int fd, file_t *file, int flag) -+{ -+ int err1 = 0; -+ int err2 = 0; -+ -+ file_t *hidden_file = NULL; -+ -+ check_mini_fo_file(file); -+ -+ if((hidden_file = ftohf(file)) != NULL) { -+ err1 = hidden_file->f_op->fasync(fd, hidden_file, flag); -+ } -+ if((hidden_file = ftohf2(file)) != NULL) { -+ err2 = hidden_file->f_op->fasync(fd, hidden_file, flag); -+ } -+ -+ return (err1 || err2); -+} -+ -+ -+ -+struct file_operations mini_fo_dir_fops = -+ { -+ read: generic_read_dir, -+ write: mini_fo_write, -+ readdir: mini_fo_readdir, -+ poll: mini_fo_poll, -+ /* ioctl: mini_fo_ioctl, */ -+ mmap: mini_fo_mmap, -+ open: mini_fo_open, -+ flush: mini_fo_flush, -+ release: mini_fo_release, -+ fsync: mini_fo_fsync, -+ fasync: mini_fo_fasync, -+ /* not needed lock: mini_fo_lock, */ -+ /* not needed: readv */ -+ /* not needed: writev */ -+ /* not implemented: sendpage */ -+ /* not implemented: get_unmapped_area */ -+ }; -+ -+struct file_operations mini_fo_main_fops = -+ { -+ llseek: mini_fo_llseek, -+ read: mini_fo_read, -+ write: mini_fo_write, -+ readdir: mini_fo_readdir, -+ poll: mini_fo_poll, -+ /* ioctl: mini_fo_ioctl, */ -+ mmap: mini_fo_mmap, -+ open: mini_fo_open, -+ flush: mini_fo_flush, -+ release: mini_fo_release, -+ fsync: mini_fo_fsync, -+ fasync: mini_fo_fasync, -+ /* not needed: lock: mini_fo_lock, */ -+ /* not needed: readv */ -+ /* not needed: writev */ -+ /* not implemented: sendpage */ -+ /* not implemented: get_unmapped_area */ -+ }; ---- /dev/null -+++ b/fs/mini_fo/fist.h -@@ -0,0 +1,252 @@ -+/* -+ * Copyright (c) 1997-2003 Erez Zadok -+ * Copyright (c) 2001-2003 Stony Brook University -+ * -+ * For specific licensing information, see the COPYING file distributed with -+ * this package, or get one from ftp://ftp.filesystems.org/pub/fist/COPYING. -+ * -+ * This Copyright notice must be kept intact and distributed with all -+ * fistgen sources INCLUDING sources generated by fistgen. -+ */ -+/* -+ * Copyright (C) 2004, 2005 Markus Klotzbuecher -+ * -+ * 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. -+ */ -+ -+ -+/* -+ * $Id$ -+ */ -+ -+#ifndef __FIST_H_ -+#define __FIST_H_ -+ -+/* -+ * KERNEL ONLY CODE: -+ */ -+#ifdef __KERNEL__ -+#include -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19) -+#include -+#else -+#include -+#endif -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) -+#ifdef CONFIG_MODVERSIONS -+# define MODVERSIONS -+# include -+#endif /* CONFIG_MODVERSIONS */ -+#endif /* KERNEL_VERSION < 2.6.0 */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) -+#include -+#else -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#endif -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20) -+#include -+#endif -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -+#include -+#endif -+ -+#include -+ -+#include -+/* #include */ -+#include -+#include -+ -+/* -+ * MACROS: -+ */ -+ -+/* those mapped to ATTR_* were copied from linux/fs.h */ -+#define FA_MODE ATTR_MODE -+#define FA_UID ATTR_UID -+#define FA_GID ATTR_GID -+#define FA_SIZE ATTR_SIZE -+#define FA_ATIME ATTR_ATIME -+#define FA_MTIME ATTR_MTIME -+#define FA_CTIME ATTR_CTIME -+#define FA_ATIME_SET ATTR_ATIME_SET -+#define FA_MTIME_SET ATTR_MTIME_SET -+#define FA_FORCE ATTR_FORCE -+#define FA_ATTR_FLAGS ATTR_ATTR_FLAG -+ -+/* must be greater than all other ATTR_* flags! */ -+#define FA_NLINK 2048 -+#define FA_BLKSIZE 4096 -+#define FA_BLOCKS 8192 -+#define FA_TIMES (FA_ATIME|FA_MTIME|FA_CTIME) -+#define FA_ALL 0 -+ -+/* macros to manage changes between kernels */ -+#define INODE_DATA(i) (&(i)->i_data) -+ -+#define MIN(x,y) ((x < y) ? (x) : (y)) -+#define MAX(x,y) ((x > y) ? (x) : (y)) -+#define MAXPATHLEN PATH_MAX -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,5) -+# define lookup_one_len(a,b,c) lookup_one(a,b) -+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,4,5) */ -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,8) -+# define generic_file_llseek default_llseek -+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,4,8) */ -+ -+#ifndef SEEK_SET -+# define SEEK_SET 0 -+#endif /* not SEEK_SET */ -+ -+#ifndef SEEK_CUR -+# define SEEK_CUR 1 -+#endif /* not SEEK_CUR */ -+ -+#ifndef SEEK_END -+# define SEEK_END 2 -+#endif /* not SEEK_END */ -+ -+#ifndef DEFAULT_POLLMASK -+# define DEFAULT_POLLMASK (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM) -+#endif /* not DEFAULT_POLLMASK */ -+ -+/* XXX: fix this so fistgen generates kfree() code directly */ -+#define kfree_s(a,b) kfree(a) -+ -+/* -+ * TYPEDEFS: -+ */ -+typedef struct dentry dentry_t; -+typedef struct file file_t; -+typedef struct inode inode_t; -+typedef inode_t vnode_t; -+typedef struct page page_t; -+typedef struct qstr qstr_t; -+typedef struct super_block super_block_t; -+typedef super_block_t vfs_t; -+typedef struct vm_area_struct vm_area_t; -+ -+ -+/* -+ * EXTERNALS: -+ */ -+ -+#define FPPF(str,page) printk("PPF %s 0x%x/%d: Lck:%d Err:%d Ref:%d Upd:%d Other::%d:%d:%d:%d:\n", \ -+ str, \ -+ (int) page, \ -+ (int) page->index, \ -+ (PageLocked(page) ? 1 : 0), \ -+ (PageError(page) ? 1 : 0), \ -+ (PageReferenced(page) ? 1 : 0), \ -+ (Page_Uptodate(page) ? 1 : 0), \ -+ (PageDecrAfter(page) ? 1 : 0), \ -+ (PageSlab(page) ? 1 : 0), \ -+ (PageSwapCache(page) ? 1 : 0), \ -+ (PageReserved(page) ? 1 : 0) \ -+ ) -+#define EZKDBG printk("EZK %s:%d:%s\n",__FILE__,__LINE__,__FUNCTION__) -+#if 0 -+# define EZKDBG1 printk("EZK %s:%d\n",__FILE__,__LINE__) -+#else -+# define EZKDBG1 -+#endif -+ -+extern int fist_get_debug_value(void); -+extern int fist_set_debug_value(int val); -+#if 0 /* mini_fo doesn't need these */ -+extern void fist_dprint_internal(int level, char *str,...); -+extern void fist_print_dentry(char *str, const dentry_t *dentry); -+extern void fist_print_inode(char *str, const inode_t *inode); -+extern void fist_print_file(char *str, const file_t *file); -+extern void fist_print_buffer_flags(char *str, struct buffer_head *buffer); -+extern void fist_print_page_flags(char *str, page_t *page); -+extern void fist_print_page_bytes(char *str, page_t *page); -+extern void fist_print_pte_flags(char *str, const page_t *page); -+extern void fist_checkinode(inode_t *inode, char *msg); -+extern void fist_print_sb(char *str, const super_block_t *sb); -+ -+/* §$% by mk: special debug functions */ -+extern void fist_mk_print_dentry(char *str, const dentry_t *dentry); -+extern void fist_mk_print_inode(char *str, const inode_t *inode); -+ -+extern char *add_indent(void); -+extern char *del_indent(void); -+#endif/* mini_fo doesn't need these */ -+ -+ -+#define STATIC -+#define ASSERT(EX) \ -+do { \ -+ if (!(EX)) { \ -+ printk(KERN_CRIT "ASSERTION FAILED: %s at %s:%d (%s)\n", #EX, \ -+ __FILE__, __LINE__, __FUNCTION__); \ -+ (*((char *)0))=0; \ -+ } \ -+} while (0) -+/* same ASSERT, but tell me who was the caller of the function */ -+#define ASSERT2(EX) \ -+do { \ -+ if (!(EX)) { \ -+ printk(KERN_CRIT "ASSERTION FAILED (caller): %s at %s:%d (%s)\n", #EX, \ -+ file, line, func); \ -+ (*((char *)0))=0; \ -+ } \ -+} while (0) -+ -+#if 0 /* mini_fo doesn't need these */ -+#define dprintk(format, args...) printk(KERN_DEBUG format, ##args) -+#define fist_dprint(level, str, args...) fist_dprint_internal(level, KERN_DEBUG str, ## args) -+#define print_entry_location() fist_dprint(4, "%sIN: %s %s:%d\n", add_indent(), __FUNCTION__, __FILE__, __LINE__) -+#define print_exit_location() fist_dprint(4, "%s OUT: %s %s:%d\n", del_indent(), __FUNCTION__, __FILE__, __LINE__) -+#define print_exit_status(status) fist_dprint(4, "%s OUT: %s %s:%d, STATUS: %d\n", del_indent(), __FUNCTION__, __FILE__, __LINE__, status) -+#define print_exit_pointer(status) \ -+do { \ -+ if (IS_ERR(status)) \ -+ fist_dprint(4, "%s OUT: %s %s:%d, RESULT: %ld\n", del_indent(), __FUNCTION__, __FILE__, __LINE__, PTR_ERR(status)); \ -+ else \ -+ fist_dprint(4, "%s OUT: %s %s:%d, RESULT: 0x%x\n", del_indent(), __FUNCTION__, __FILE__, __LINE__, PTR_ERR(status)); \ -+} while (0) -+#endif/* mini_fo doesn't need these */ -+ -+#endif /* __KERNEL__ */ -+ -+ -+/* -+ * DEFINITIONS FOR USER AND KERNEL CODE: -+ * (Note: ioctl numbers 1--9 are reserved for fistgen, the rest -+ * are auto-generated automatically based on the user's .fist file.) -+ */ -+# define FIST_IOCTL_GET_DEBUG_VALUE _IOR(0x15, 1, int) -+# define FIST_IOCTL_SET_DEBUG_VALUE _IOW(0x15, 2, int) -+ -+#endif /* not __FIST_H_ */ ---- /dev/null -+++ b/fs/mini_fo/inode.c -@@ -0,0 +1,1564 @@ -+/* -+ * Copyright (c) 1997-2003 Erez Zadok -+ * Copyright (c) 2001-2003 Stony Brook University -+ * -+ * For specific licensing information, see the COPYING file distributed with -+ * this package, or get one from ftp://ftp.filesystems.org/pub/fist/COPYING. -+ * -+ * This Copyright notice must be kept intact and distributed with all -+ * fistgen sources INCLUDING sources generated by fistgen. -+ */ -+/* -+ * Copyright (C) 2004, 2005 Markus Klotzbuecher -+ * -+ * 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. -+ */ -+ -+/* -+ * $Id$ -+ */ -+ -+#ifdef HAVE_CONFIG_H -+# include -+#endif -+ -+#include "fist.h" -+#include "mini_fo.h" -+ -+STATIC int -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -+mini_fo_create(inode_t *dir, dentry_t *dentry, int mode, struct nameidata *nd) -+#else -+mini_fo_create(inode_t *dir, dentry_t *dentry, int mode) -+#endif -+{ -+ int err = 0; -+ -+ check_mini_fo_dentry(dentry); -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -+ err = create_sto_reg_file(dentry, mode, nd); -+#else -+ err = create_sto_reg_file(dentry, mode); -+#endif -+ check_mini_fo_dentry(dentry); -+ return err; -+} -+ -+ -+STATIC dentry_t * -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -+mini_fo_lookup(inode_t *dir, dentry_t *dentry, struct nameidata* nd) -+#else -+mini_fo_lookup(inode_t *dir, dentry_t *dentry) -+#endif -+{ -+ int err = 0; -+ dentry_t *hidden_dir_dentry; -+ dentry_t *hidden_dentry = NULL; -+ -+ dentry_t *hidden_sto_dir_dentry; -+ dentry_t *hidden_sto_dentry = NULL; -+ -+ /* whiteout flag */ -+ int del_flag = 0; -+ char *bpath = NULL; -+ -+ const char *name; -+ unsigned int namelen; -+ -+ /* Don't allow lookups of META-files */ -+ namelen = strlen(META_FILENAME); -+ if(namelen == dentry->d_name.len) { -+ if(!strncmp(dentry->d_name.name, META_FILENAME, namelen)) { -+ err = -ENOENT; -+ goto out; -+ } -+ } -+ -+ hidden_dir_dentry = dtohd(dentry->d_parent); -+ hidden_sto_dir_dentry = dtohd2(dentry->d_parent); -+ -+ name = dentry->d_name.name; -+ namelen = dentry->d_name.len; -+ -+ /* must initialize dentry operations */ -+ dentry->d_op = &mini_fo_dops; -+ -+ /* setup the del_flag */ -+ del_flag = __meta_check_d_entry(dir, name, namelen); -+ bpath = __meta_check_r_entry(dir, name, namelen); -+ -+ /* perform the lookups of base and storage files: -+ * -+ * This caused some serious trouble, as a lookup_one_len passing -+ * a negative dentry oopses. Solution is to only do the lookup -+ * if the dentry is positive, else we set it to NULL -+ * More trouble, who said a *_dir_dentry can't be NULL? -+ */ -+ if(bpath) { -+ /* Cross-Interposing (C), yeah! */ -+ hidden_dentry = bpath_walk(dir->i_sb, bpath); -+ if(!hidden_dentry || !hidden_dentry->d_inode) { -+ printk(KERN_CRIT "mini_fo_lookup: bpath_walk failed.\n"); -+ err= -EINVAL; -+ goto out; -+ } -+ -+ /* this can be set up safely without fear of spaghetti -+ * interposing as it is only used for copying times */ -+ hidden_dir_dentry = hidden_dentry->d_parent; -+ kfree(bpath); -+ } -+ else if(hidden_dir_dentry && hidden_dir_dentry->d_inode) -+ hidden_dentry = -+ lookup_one_len(name, hidden_dir_dentry, namelen); -+ else -+ hidden_dentry = NULL; -+ -+ if(hidden_sto_dir_dentry && hidden_sto_dir_dentry->d_inode) -+ hidden_sto_dentry = -+ lookup_one_len(name, hidden_sto_dir_dentry, namelen); -+ else -+ hidden_sto_dentry = NULL; -+ -+ /* catch error in lookup */ -+ if (IS_ERR(hidden_dentry) || IS_ERR(hidden_sto_dentry)) { -+ /* mk: we need to call dput on the dentry, whose -+ * lookup_one_len operation failed, in order to avoid -+ * unmount trouble. -+ */ -+ if(IS_ERR(hidden_dentry)) { -+ printk(KERN_CRIT "mini_fo_lookup: ERR from base dentry, lookup failed.\n"); -+ err = PTR_ERR(hidden_dentry); -+ } else { -+ dput(hidden_dentry); -+ } -+ if(IS_ERR(hidden_sto_dentry)) { -+ printk(KERN_CRIT "mini_fo_lookup: ERR from storage dentry, lookup failed.\n"); -+ err = PTR_ERR(hidden_sto_dentry); -+ } else { -+ dput(hidden_sto_dentry); -+ } -+ goto out; -+ } -+ -+ /* allocate dentry private data */ -+ __dtopd(dentry) = (struct mini_fo_dentry_info *) -+ kmalloc(sizeof(struct mini_fo_dentry_info), GFP_KERNEL); -+ -+ if (!dtopd(dentry)) { -+ err = -ENOMEM; -+ goto out_dput; -+ } -+ -+ /* check for different states of the mini_fo file to be looked up. */ -+ -+ /* state 1, file has been modified */ -+ if(hidden_dentry && hidden_sto_dentry && -+ hidden_dentry->d_inode && hidden_sto_dentry->d_inode && !del_flag) { -+ -+ /* update parent directory's atime */ -+ fist_copy_attr_atime(dir, hidden_sto_dir_dentry->d_inode); -+ -+ dtopd(dentry)->state = MODIFIED; -+ dtohd(dentry) = hidden_dentry; -+ dtohd2(dentry) = hidden_sto_dentry; -+ -+ err = mini_fo_tri_interpose(hidden_dentry, -+ hidden_sto_dentry, -+ dentry, dir->i_sb, 1); -+ if (err) { -+ printk(KERN_CRIT "mini_fo_lookup: error interposing (state1).\n"); -+ goto out_free; -+ } -+ goto out; -+ } -+ /* state 2, file is unmodified */ -+ if(hidden_dentry && hidden_dentry->d_inode && !del_flag) { -+ -+ fist_copy_attr_atime(dir, hidden_dir_dentry->d_inode); -+ -+ dtopd(dentry)->state = UNMODIFIED; -+ dtohd(dentry) = hidden_dentry; -+ dtohd2(dentry) = hidden_sto_dentry; /* could be negative */ -+ -+ err = mini_fo_tri_interpose(hidden_dentry, -+ hidden_sto_dentry, -+ dentry, dir->i_sb, 1); -+ if (err) { -+ printk(KERN_CRIT "mini_fo_lookup: error interposing (state2).\n"); -+ goto out_free; -+ } -+ goto out; -+ } -+ /* state 3, file has been newly created */ -+ if(hidden_sto_dentry && hidden_sto_dentry->d_inode && !del_flag) { -+ -+ fist_copy_attr_atime(dir, hidden_sto_dir_dentry->d_inode); -+ dtopd(dentry)->state = CREATED; -+ dtohd(dentry) = hidden_dentry; /* could be negative */ -+ dtohd2(dentry) = hidden_sto_dentry; -+ -+ err = mini_fo_tri_interpose(hidden_dentry, -+ hidden_sto_dentry, -+ dentry, dir->i_sb, 1); -+ if (err) { -+ printk(KERN_CRIT "mini_fo_lookup: error interposing (state3).\n"); -+ goto out_free; -+ } -+ goto out; -+ } -+ -+ /* state 4, file has deleted and created again. */ -+ if(hidden_dentry && hidden_sto_dentry && -+ hidden_dentry->d_inode && -+ hidden_sto_dentry->d_inode && del_flag) { -+ -+ fist_copy_attr_atime(dir, hidden_sto_dir_dentry->d_inode); -+ dtopd(dentry)->state = DEL_REWRITTEN; -+ dtohd(dentry) = NULL; -+ dtohd2(dentry) = hidden_sto_dentry; -+ -+ err = mini_fo_tri_interpose(NULL, -+ hidden_sto_dentry, -+ dentry, dir->i_sb, 1); -+ if (err) { -+ printk(KERN_CRIT "mini_fo_lookup: error interposing (state4).\n"); -+ goto out_free; -+ } -+ /* We will never need this dentry again, as the file has been -+ * deleted from base */ -+ dput(hidden_dentry); -+ goto out; -+ } -+ /* state 5, file has been deleted in base */ -+ if(hidden_dentry && hidden_sto_dentry && -+ hidden_dentry->d_inode && -+ !hidden_sto_dentry->d_inode && del_flag) { -+ -+ /* check which parents atime we need for updating */ -+ if(hidden_sto_dir_dentry->d_inode) -+ fist_copy_attr_atime(dir, -+ hidden_sto_dir_dentry->d_inode); -+ else -+ fist_copy_attr_atime(dir, -+ hidden_dir_dentry->d_inode); -+ -+ dtopd(dentry)->state = DELETED; -+ dtohd(dentry) = NULL; -+ dtohd2(dentry) = hidden_sto_dentry; -+ -+ /* add negative dentry to dcache to speed up lookups */ -+ d_add(dentry, NULL); -+ dput(hidden_dentry); -+ goto out; -+ } -+ /* state 6, file does not exist */ -+ if(((hidden_dentry && !hidden_dentry->d_inode) || -+ (hidden_sto_dentry && !hidden_sto_dentry->d_inode)) && !del_flag) -+ { -+ /* check which parents atime we need for updating */ -+ if(hidden_sto_dir_dentry && hidden_sto_dir_dentry->d_inode) -+ fist_copy_attr_atime(dir, hidden_sto_dir_dentry->d_inode); -+ else -+ fist_copy_attr_atime(dir, hidden_dir_dentry->d_inode); -+ -+ dtopd(dentry)->state = NON_EXISTANT; -+ dtohd(dentry) = hidden_dentry; -+ dtohd2(dentry) = hidden_sto_dentry; -+ d_add(dentry, NULL); -+ goto out; -+ } -+ -+ /* if we get to here, were in an invalid state. bad. */ -+ printk(KERN_CRIT "mini_fo_lookup: ERROR, meta data corruption detected.\n"); -+ -+ /* end state checking */ -+ out_free: -+ d_drop(dentry); /* so that our bad dentry will get destroyed */ -+ kfree(dtopd(dentry)); -+ __dtopd(dentry) = NULL; /* be safe */ -+ -+ out_dput: -+ if(hidden_dentry) -+ dput(hidden_dentry); -+ if(hidden_sto_dentry) -+ dput(hidden_sto_dentry); /* drops usage count and marks for release */ -+ -+ out: -+ /* initalize wol if file exists and is directory */ -+ if(dentry->d_inode) { -+ if(S_ISDIR(dentry->d_inode->i_mode)) { -+ itopd(dentry->d_inode)->deleted_list_size = -1; -+ itopd(dentry->d_inode)->renamed_list_size = -1; -+ meta_build_lists(dentry); -+ } -+ } -+ return ERR_PTR(err); -+} -+ -+ -+STATIC int -+mini_fo_link(dentry_t *old_dentry, inode_t *dir, dentry_t *new_dentry) -+{ -+ int err; -+ dentry_t *hidden_old_dentry; -+ dentry_t *hidden_new_dentry; -+ dentry_t *hidden_dir_dentry; -+ -+ -+ check_mini_fo_dentry(old_dentry); -+ check_mini_fo_dentry(new_dentry); -+ check_mini_fo_inode(dir); -+ -+ /* no links to directorys and existing targets target allowed */ -+ if(S_ISDIR(old_dentry->d_inode->i_mode) || -+ is_mini_fo_existant(new_dentry)) { -+ err = -EPERM; -+ goto out; -+ } -+ -+ /* bring it directly from unmod to del_rew */ -+ if(dtost(old_dentry) == UNMODIFIED) { -+ err = nondir_unmod_to_mod(old_dentry, 1); -+ if(err) { -+ err = -EINVAL; -+ goto out; -+ } -+ err = meta_add_d_entry(old_dentry->d_parent, -+ old_dentry->d_name.name, -+ old_dentry->d_name.len); -+ if(err) { -+ err = -EINVAL; -+ goto out; -+ } -+ dput(dtohd(old_dentry)); -+ dtohd(old_dentry) = NULL; -+ dtost(old_dentry) = DEL_REWRITTEN; -+ } -+ -+ err = get_neg_sto_dentry(new_dentry); -+ if(err) { -+ err = -EINVAL; -+ goto out; -+ } -+ -+ hidden_old_dentry = dtohd2(old_dentry); -+ hidden_new_dentry = dtohd2(new_dentry); -+ -+ dget(hidden_old_dentry); -+ dget(hidden_new_dentry); -+ -+ /* was: hidden_dir_dentry = lock_parent(hidden_new_dentry); */ -+ hidden_dir_dentry = dget(hidden_new_dentry->d_parent); -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) -+ mutex_lock(&hidden_dir_dentry->d_inode->i_mutex); -+#else -+ down(&hidden_dir_dentry->d_inode->i_sem); -+#endif -+ -+ err = vfs_link(hidden_old_dentry, -+ hidden_dir_dentry->d_inode, -+ hidden_new_dentry); -+ if (err || !hidden_new_dentry->d_inode) -+ goto out_lock; -+ -+ dtost(new_dentry) = CREATED; -+ err = mini_fo_tri_interpose(NULL, hidden_new_dentry, new_dentry, dir->i_sb, 0); -+ if (err) -+ goto out_lock; -+ -+ fist_copy_attr_timesizes(dir, hidden_new_dentry->d_inode); -+ /* propagate number of hard-links */ -+ old_dentry->d_inode->i_nlink = itohi2(old_dentry->d_inode)->i_nlink; -+ -+ out_lock: -+ /* was: unlock_dir(hidden_dir_dentry); */ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) -+ mutex_unlock(&hidden_dir_dentry->d_inode->i_mutex); -+#else -+ up(&hidden_dir_dentry->d_inode->i_sem); -+#endif -+ dput(hidden_dir_dentry); -+ -+ dput(hidden_new_dentry); -+ dput(hidden_old_dentry); -+ if (!new_dentry->d_inode) -+ d_drop(new_dentry); -+ -+ out: -+ return err; -+} -+ -+ -+STATIC int -+mini_fo_unlink(inode_t *dir, dentry_t *dentry) -+{ -+ int err = 0; -+ -+ dget(dentry); -+ if(dtopd(dentry)->state == MODIFIED) { -+ err = nondir_mod_to_del(dentry); -+ goto out; -+ } -+ else if(dtopd(dentry)->state == UNMODIFIED) { -+ err = nondir_unmod_to_del(dentry); -+ goto out; -+ } -+ else if(dtopd(dentry)->state == CREATED) { -+ err = nondir_creat_to_del(dentry); -+ goto out; -+ } -+ else if(dtopd(dentry)->state == DEL_REWRITTEN) { -+ err = nondir_del_rew_to_del(dentry); -+ goto out; -+ } -+ -+ printk(KERN_CRIT "mini_fo_unlink: ERROR, invalid state detected.\n"); -+ -+ out: -+ fist_copy_attr_times(dir, itohi2(dentry->d_parent->d_inode)); -+ -+ if(!err) { -+ /* is this causing my pain? d_delete(dentry); */ -+ d_drop(dentry); -+ } -+ -+ dput(dentry); -+ return err; -+} -+ -+ -+STATIC int -+mini_fo_symlink(inode_t *dir, dentry_t *dentry, const char *symname) -+{ -+ int err=0; -+ dentry_t *hidden_sto_dentry; -+ dentry_t *hidden_sto_dir_dentry; -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -+ umode_t mode; -+#endif -+ -+ /* Fail if the symlink file exists */ -+ if(!(dtost(dentry) == DELETED || -+ dtost(dentry) == NON_EXISTANT)) { -+ err = -EEXIST; -+ goto out; -+ } -+ -+ err = get_neg_sto_dentry(dentry); -+ if(err) { -+ err = -EINVAL; -+ goto out; -+ } -+ hidden_sto_dentry = dtohd2(dentry); -+ -+ dget(hidden_sto_dentry); -+ /* was: hidden_sto_dir_dentry = lock_parent(hidden_sto_dentry); */ -+ hidden_sto_dir_dentry = dget(hidden_sto_dentry->d_parent); -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) -+ mutex_lock(&hidden_sto_dir_dentry->d_inode->i_mutex); -+#else -+ down(&hidden_sto_dir_dentry->d_inode->i_sem); -+#endif -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -+ mode = S_IALLUGO; -+ err = vfs_symlink(hidden_sto_dir_dentry->d_inode, -+ hidden_sto_dentry, symname, mode); -+#else -+ err = vfs_symlink(hidden_sto_dir_dentry->d_inode, -+ hidden_sto_dentry, -+ symname); -+#endif -+ if (err || !hidden_sto_dentry->d_inode) -+ goto out_lock; -+ -+ if(dtost(dentry) == DELETED) { -+ dtost(dentry) = DEL_REWRITTEN; -+ err = mini_fo_tri_interpose(NULL, hidden_sto_dentry, dentry, dir->i_sb, 0); -+ if(err) -+ goto out_lock; -+ } else if(dtost(dentry) == NON_EXISTANT) { -+ dtost(dentry) = CREATED; -+ err = mini_fo_tri_interpose(dtohd(dentry), hidden_sto_dentry, dentry, dir->i_sb, 0); -+ if(err) -+ goto out_lock; -+ } -+ fist_copy_attr_timesizes(dir, hidden_sto_dir_dentry->d_inode); -+ -+ out_lock: -+ /* was: unlock_dir(hidden_sto_dir_dentry); */ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) -+ mutex_unlock(&hidden_sto_dir_dentry->d_inode->i_mutex); -+#else -+ up(&hidden_sto_dir_dentry->d_inode->i_sem); -+#endif -+ dput(hidden_sto_dir_dentry); -+ -+ dput(hidden_sto_dentry); -+ if (!dentry->d_inode) -+ d_drop(dentry); -+ out: -+ return err; -+} -+ -+STATIC int -+mini_fo_mkdir(inode_t *dir, dentry_t *dentry, int mode) -+{ -+ int err; -+ -+ err = create_sto_dir(dentry, mode); -+ -+ check_mini_fo_dentry(dentry); -+ -+ return err; -+} -+ -+ -+STATIC int -+mini_fo_rmdir(inode_t *dir, dentry_t *dentry) -+{ -+ int err = 0; -+ -+ dentry_t *hidden_sto_dentry; -+ dentry_t *hidden_sto_dir_dentry; -+ dentry_t *meta_dentry; -+ inode_t *hidden_sto_dir = NULL; -+ -+ check_mini_fo_dentry(dentry); -+ check_mini_fo_inode(dir); -+ -+ dget(dentry); -+ if(dtopd(dentry)->state == MODIFIED) { -+ /* XXX: disabled, because it does not bother to check files on -+ * the original filesystem - just a hack, but better than simply -+ * removing it without testing */ -+ err = -EINVAL; -+ goto out; -+ -+ hidden_sto_dir = itohi2(dir); -+ hidden_sto_dentry = dtohd2(dentry); -+ -+ /* was:hidden_sto_dir_dentry = lock_parent(hidden_sto_dentry); */ -+ hidden_sto_dir_dentry = dget(hidden_sto_dentry->d_parent); -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) -+ mutex_lock(&hidden_sto_dir_dentry->d_inode->i_mutex); -+#else -+ down(&hidden_sto_dir_dentry->d_inode->i_sem); -+#endif -+ -+ /* Delete an old WOL file contained in the storage dir */ -+ meta_dentry = lookup_one_len(META_FILENAME, -+ hidden_sto_dentry, -+ strlen(META_FILENAME)); -+ if(meta_dentry->d_inode) { -+ err = vfs_unlink(hidden_sto_dentry->d_inode, meta_dentry); -+ dput(meta_dentry); -+ if(!err) -+ d_delete(meta_dentry); -+ } -+ -+ err = vfs_rmdir(hidden_sto_dir, hidden_sto_dentry); -+ dput(hidden_sto_dentry); -+ if(!err) -+ d_delete(hidden_sto_dentry); -+ -+ /* propagate number of hard-links */ -+ dentry->d_inode->i_nlink = itohi2(dentry->d_inode)->i_nlink; -+ -+ dput(dtohd(dentry)); -+ -+ dtohd(dentry) = NULL; -+ dtopd(dentry)->state = DELETED; -+ -+ /* carefull with R files */ -+ if( __meta_is_r_entry(dir, -+ dentry->d_name.name, -+ dentry->d_name.len) == 1) { -+ err = meta_remove_r_entry(dentry->d_parent, -+ dentry->d_name.name, -+ dentry->d_name.len); -+ if(err) { -+ printk(KERN_CRIT "mini_fo: rmdir: meta_remove_r_entry failed.\n"); -+ goto out; -+ } -+ } -+ else { -+ /* ok, add deleted file to META */ -+ meta_add_d_entry(dentry->d_parent, -+ dentry->d_name.name, -+ dentry->d_name.len); -+ } -+ /* was: unlock_dir(hidden_sto_dir_dentry); */ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) -+ mutex_unlock(&hidden_sto_dir_dentry->d_inode->i_mutex); -+#else -+ up(&hidden_sto_dir_dentry->d_inode->i_sem); -+#endif -+ dput(hidden_sto_dir_dentry); -+ goto out; -+ } -+ else if(dtopd(dentry)->state == UNMODIFIED) { -+ /* XXX: simply adding it to the delete list here is fscking dangerous! -+ * as a temporary hack, i will disable rmdir on unmodified directories -+ * for now. -+ */ -+ err = -EINVAL; -+ goto out; -+ -+ err = get_neg_sto_dentry(dentry); -+ if(err) { -+ err = -EINVAL; -+ goto out; -+ } -+ -+ /* dput base dentry, this will relase the inode and free the -+ * dentry, as we will never need it again. */ -+ dput(dtohd(dentry)); -+ dtohd(dentry) = NULL; -+ dtopd(dentry)->state = DELETED; -+ -+ /* add deleted file to META-file */ -+ meta_add_d_entry(dentry->d_parent, -+ dentry->d_name.name, -+ dentry->d_name.len); -+ goto out; -+ } -+ else if(dtopd(dentry)->state == CREATED) { -+ hidden_sto_dir = itohi2(dir); -+ hidden_sto_dentry = dtohd2(dentry); -+ -+ /* was: hidden_sto_dir_dentry = lock_parent(hidden_sto_dentry);*/ -+ hidden_sto_dir_dentry = dget(hidden_sto_dentry->d_parent); -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) -+ mutex_lock(&hidden_sto_dir_dentry->d_inode->i_mutex); -+#else -+ down(&hidden_sto_dir_dentry->d_inode->i_sem); -+#endif -+ -+ /* Delete an old WOL file contained in the storage dir */ -+ meta_dentry = lookup_one_len(META_FILENAME, -+ hidden_sto_dentry, -+ strlen(META_FILENAME)); -+ if(meta_dentry->d_inode) { -+ /* is this necessary? dget(meta_dentry); */ -+ err = vfs_unlink(hidden_sto_dentry->d_inode, -+ meta_dentry); -+ dput(meta_dentry); -+ if(!err) -+ d_delete(meta_dentry); -+ } -+ -+ err = vfs_rmdir(hidden_sto_dir, hidden_sto_dentry); -+ dput(hidden_sto_dentry); -+ if(!err) -+ d_delete(hidden_sto_dentry); -+ -+ /* propagate number of hard-links */ -+ dentry->d_inode->i_nlink = itohi2(dentry->d_inode)->i_nlink; -+ dtopd(dentry)->state = NON_EXISTANT; -+ -+ /* was: unlock_dir(hidden_sto_dir_dentry); */ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) -+ mutex_unlock(&hidden_sto_dir_dentry->d_inode->i_mutex); -+#else -+ up(&hidden_sto_dir_dentry->d_inode->i_sem); -+#endif -+ dput(hidden_sto_dir_dentry); -+ -+ goto out; -+ } -+ else if(dtopd(dentry)->state == DEL_REWRITTEN) { -+ hidden_sto_dir = itohi2(dir); -+ hidden_sto_dentry = dtohd2(dentry); -+ -+ /* was: hidden_sto_dir_dentry = lock_parent(hidden_sto_dentry);*/ -+ hidden_sto_dir_dentry = dget(hidden_sto_dentry->d_parent); -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) -+ mutex_lock(&hidden_sto_dir_dentry->d_inode->i_mutex); -+#else -+ down(&hidden_sto_dir_dentry->d_inode->i_sem); -+#endif -+ -+ /* Delete an old WOL file contained in the storage dir */ -+ meta_dentry = lookup_one_len(META_FILENAME, -+ hidden_sto_dentry, -+ strlen(META_FILENAME)); -+ if(meta_dentry->d_inode) { -+ /* is this necessary? dget(meta_dentry); */ -+ err = vfs_unlink(hidden_sto_dentry->d_inode, -+ meta_dentry); -+ dput(meta_dentry); -+ if(!err) -+ d_delete(meta_dentry); -+ } -+ -+ err = vfs_rmdir(hidden_sto_dir, hidden_sto_dentry); -+ dput(hidden_sto_dentry); -+ if(!err) -+ d_delete(hidden_sto_dentry); -+ -+ /* propagate number of hard-links */ -+ dentry->d_inode->i_nlink = itohi2(dentry->d_inode)->i_nlink; -+ dtopd(dentry)->state = DELETED; -+ /* was: unlock_dir(hidden_sto_dir_dentry); */ -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) -+ mutex_unlock(&hidden_sto_dir_dentry->d_inode->i_mutex); -+#else -+ up(&hidden_sto_dir_dentry->d_inode->i_sem); -+#endif -+ dput(hidden_sto_dir_dentry); -+ goto out; -+ } -+ -+ printk(KERN_CRIT "mini_fo_rmdir: ERROR, invalid state detected.\n"); -+ -+ out: -+ if(!err) { -+ d_drop(dentry); -+ } -+ -+ fist_copy_attr_times(dir, itohi2(dentry->d_parent->d_inode)); -+ dput(dentry); -+ -+ return err; -+} -+ -+ -+STATIC int -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -+mini_fo_mknod(inode_t *dir, dentry_t *dentry, int mode, dev_t dev) -+#else -+mini_fo_mknod(inode_t *dir, dentry_t *dentry, int mode, int dev) -+#endif -+{ -+ int err = 0; -+ -+ check_mini_fo_dentry(dentry); -+ -+ err = create_sto_nod(dentry, mode, dev); -+ if(err) { -+ printk(KERN_CRIT "mini_fo_mknod: creating sto nod failed.\n"); -+ err = -EINVAL; -+ } -+ -+ check_mini_fo_dentry(dentry); -+ return err; -+} -+ -+ -+STATIC int -+mini_fo_rename(inode_t *old_dir, dentry_t *old_dentry, -+ inode_t *new_dir, dentry_t *new_dentry) -+{ -+ /* dispatch */ -+ if(S_ISDIR(old_dentry->d_inode->i_mode)) -+ return rename_directory(old_dir, old_dentry, new_dir, new_dentry); -+ return rename_nondir(old_dir, old_dentry, new_dir, new_dentry); -+ -+} -+ -+int rename_directory(inode_t *old_dir, dentry_t *old_dentry, -+ inode_t *new_dir, dentry_t *new_dentry) -+{ -+ int err, bpath_len; -+ char *bpath; -+ -+ dentry_t *hidden_old_dentry; -+ dentry_t *hidden_new_dentry; -+ dentry_t *hidden_old_dir_dentry; -+ dentry_t *hidden_new_dir_dentry; -+ -+ err = 0; -+ bpath = NULL; -+ bpath_len = 0; -+ -+ /* this is a test, chuck out if it works */ -+ if(!(dtopd(new_dentry)->state == DELETED || -+ dtopd(new_dentry)->state == NON_EXISTANT)) { -+ printk(KERN_CRIT "mini_fo: rename_directory: \ -+ uh, ah, new_dentry not negative.\n"); -+ /* return -1; */ -+ } -+ -+ /* state = UNMODIFIED */ -+ if(dtopd(old_dentry)->state == UNMODIFIED) { -+ err = dir_unmod_to_mod(old_dentry); -+ if (err) -+ goto out; -+ } -+ -+ /* state = MODIFIED */ -+ if(dtopd(old_dentry)->state == MODIFIED) { -+ bpath = meta_check_r_entry(old_dentry->d_parent, -+ old_dentry->d_name.name, -+ old_dentry->d_name.len); -+ if(bpath) { -+ err = meta_remove_r_entry(old_dentry->d_parent, -+ old_dentry->d_name.name, -+ old_dentry->d_name.len); -+ if(err) { -+ printk(KERN_CRIT "mini_fo: rename_directory:\ -+ meta_remove_r_entry \ -+ failed.\n"); -+ goto out; -+ } -+ err = meta_add_r_entry(new_dentry->d_parent, -+ bpath, -+ strlen(bpath), -+ new_dentry->d_name.name, -+ new_dentry->d_name.len); -+ kfree(bpath); -+ } -+ else {/* wol it */ -+ err = meta_add_d_entry(old_dentry->d_parent, -+ old_dentry->d_name.name, -+ old_dentry->d_name.len); -+ if (err) -+ goto out; -+ /* put it on rename list */ -+ err = get_mini_fo_bpath(old_dentry, -+ &bpath, -+ &bpath_len); -+ if (err) -+ goto out; -+ err = meta_add_r_entry(new_dentry->d_parent, -+ bpath, bpath_len, -+ new_dentry->d_name.name, -+ new_dentry->d_name.len); -+ if (err) -+ goto out; -+ } -+ /* no state change, MODIFIED stays MODIFIED */ -+ } -+ /* state = CREATED */ -+ if(dtopd(old_dentry)->state == CREATED || -+ dtopd(old_dentry)->state == DEL_REWRITTEN) { -+ if(dtohd(old_dentry)) -+ dput(dtohd(old_dentry)); -+ -+ if(dtopd(new_dentry)->state == DELETED) { -+ dtopd(old_dentry)->state = DEL_REWRITTEN; -+ dtohd(old_dentry) = NULL; -+ } -+ else if(dtopd(new_dentry)->state == NON_EXISTANT) { -+ dtopd(old_dentry)->state = CREATED; -+ /* steal new dentry's neg. base dentry */ -+ dtohd(old_dentry) = dtohd(new_dentry); -+ dtohd(new_dentry) = NULL; -+ } -+ } -+ if(dtopd(new_dentry)->state == UNMODIFIED || -+ dtopd(new_dentry)->state == NON_EXISTANT) { -+ err = get_neg_sto_dentry(new_dentry); -+ if(err) -+ goto out; -+ } -+ -+ /* now move sto file */ -+ hidden_old_dentry = dtohd2(old_dentry); -+ hidden_new_dentry = dtohd2(new_dentry); -+ -+ dget(hidden_old_dentry); -+ dget(hidden_new_dentry); -+ -+ hidden_old_dir_dentry = dget(hidden_old_dentry->d_parent); -+ hidden_new_dir_dentry = dget(hidden_new_dentry->d_parent); -+ double_lock(hidden_old_dir_dentry, hidden_new_dir_dentry); -+ -+ err = vfs_rename(hidden_old_dir_dentry->d_inode, hidden_old_dentry, -+ hidden_new_dir_dentry->d_inode, hidden_new_dentry); -+ if(err) -+ goto out_lock; -+ -+ fist_copy_attr_all(new_dir, hidden_new_dir_dentry->d_inode); -+ if (new_dir != old_dir) -+ fist_copy_attr_all(old_dir, -+ hidden_old_dir_dentry->d_inode); -+ -+ out_lock: -+ /* double_unlock will dput the new/old parent dentries -+ * whose refcnts were incremented via get_parent above. */ -+ double_unlock(hidden_old_dir_dentry, hidden_new_dir_dentry); -+ dput(hidden_new_dentry); -+ dput(hidden_old_dentry); -+ -+ out: -+ return err; -+} -+ -+int rename_nondir(inode_t *old_dir, dentry_t *old_dentry, -+ inode_t *new_dir, dentry_t *new_dentry) -+{ -+ int err=0; -+ -+ check_mini_fo_dentry(old_dentry); -+ check_mini_fo_dentry(new_dentry); -+ check_mini_fo_inode(old_dir); -+ check_mini_fo_inode(new_dir); -+ -+ /* state: UNMODIFIED */ -+ if(dtost(old_dentry) == UNMODIFIED) { -+ err = nondir_unmod_to_mod(old_dentry, 1); -+ if(err) { -+ err = -EINVAL; -+ goto out; -+ } -+ } -+ -+ /* the easy states */ -+ if(exists_in_storage(old_dentry)) { -+ -+ dentry_t *hidden_old_dentry; -+ dentry_t *hidden_new_dentry; -+ dentry_t *hidden_old_dir_dentry; -+ dentry_t *hidden_new_dir_dentry; -+ -+ /* if old file is MODIFIED, add it to the deleted_list */ -+ if(dtopd(old_dentry)->state == MODIFIED) { -+ meta_add_d_entry(old_dentry->d_parent, -+ old_dentry->d_name.name, -+ old_dentry->d_name.len); -+ -+ dput(dtohd(old_dentry)); -+ } -+ /* if old file is CREATED, we only release the base dentry */ -+ if(dtopd(old_dentry)->state == CREATED) { -+ if(dtohd(old_dentry)) -+ dput(dtohd(old_dentry)); -+ } -+ -+ /* now setup the new states (depends on new_dentry state) */ -+ /* new dentry state = MODIFIED */ -+ if(dtopd(new_dentry)->state == MODIFIED) { -+ meta_add_d_entry(new_dentry->d_parent, -+ new_dentry->d_name.name, -+ new_dentry->d_name.len); -+ -+ /* new dentry will be d_put'ed later by the vfs -+ * so don't do it here -+ * dput(dtohd(new_dentry)); -+ */ -+ dtohd(old_dentry) = NULL; -+ dtopd(old_dentry)->state = DEL_REWRITTEN; -+ } -+ /* new dentry state = UNMODIFIED */ -+ else if(dtopd(new_dentry)->state == UNMODIFIED) { -+ if(get_neg_sto_dentry(new_dentry)) -+ return -EINVAL; -+ -+ meta_add_d_entry(new_dentry->d_parent, -+ new_dentry->d_name.name, -+ new_dentry->d_name.len); -+ -+ /* is this right??? */ -+ /*dput(dtohd(new_dentry));*/ -+ dtohd(old_dentry) = NULL; -+ dtopd(old_dentry)->state = DEL_REWRITTEN; -+ } -+ /* new dentry state = CREATED */ -+ else if(dtopd(new_dentry)->state == CREATED) { -+ /* we keep the neg. base dentry (if exists) */ -+ dtohd(old_dentry) = dtohd(new_dentry); -+ /* ...and set it to Null, or we'll get -+ * dcache.c:345 if it gets dput twice... */ -+ dtohd(new_dentry) = NULL; -+ dtopd(old_dentry)->state = CREATED; -+ } -+ /* new dentry state = NON_EXISTANT */ -+ else if(dtopd(new_dentry)->state == NON_EXISTANT) { -+ if(get_neg_sto_dentry(new_dentry)) -+ return -EINVAL; -+ -+ /* we keep the neg. base dentry (if exists) */ -+ dtohd(old_dentry) = dtohd(new_dentry); -+ /* ...and set it to Null, or we'll get -+ * Dr. dcache.c:345 if it gets dput twice... */ -+ dtohd(new_dentry) = NULL; -+ dtopd(old_dentry)->state = CREATED; -+ } -+ /* new dentry state = DEL_REWRITTEN or DELETED */ -+ else if(dtopd(new_dentry)->state == DEL_REWRITTEN || -+ dtopd(new_dentry)->state == DELETED) { -+ dtohd(old_dentry) = NULL; -+ dtopd(old_dentry)->state = DEL_REWRITTEN; -+ } -+ else { /* not possible, uhh, ahh */ -+ printk(KERN_CRIT -+ "mini_fo: rename_reg_file: invalid state detected [1].\n"); -+ return -1; -+ } -+ -+ /* now we definitely have a sto file */ -+ hidden_old_dentry = dtohd2(old_dentry); -+ hidden_new_dentry = dtohd2(new_dentry); -+ -+ dget(hidden_old_dentry); -+ dget(hidden_new_dentry); -+ -+ hidden_old_dir_dentry = dget(hidden_old_dentry->d_parent); -+ hidden_new_dir_dentry = dget(hidden_new_dentry->d_parent); -+ double_lock(hidden_old_dir_dentry, hidden_new_dir_dentry); -+ -+ err = vfs_rename(hidden_old_dir_dentry->d_inode, -+ hidden_old_dentry, -+ hidden_new_dir_dentry->d_inode, -+ hidden_new_dentry); -+ if(err) -+ goto out_lock; -+ -+ fist_copy_attr_all(new_dir, hidden_new_dir_dentry->d_inode); -+ if (new_dir != old_dir) -+ fist_copy_attr_all(old_dir, hidden_old_dir_dentry->d_inode); -+ -+ out_lock: -+ /* double_unlock will dput the new/old parent dentries -+ * whose refcnts were incremented via get_parent above. -+ */ -+ double_unlock(hidden_old_dir_dentry, hidden_new_dir_dentry); -+ dput(hidden_new_dentry); -+ dput(hidden_old_dentry); -+ out: -+ return err; -+ } -+ else { /* invalid state */ -+ printk(KERN_CRIT "mini_fo: rename_reg_file: ERROR: invalid state detected [2].\n"); -+ return -1; -+ } -+} -+ -+ -+STATIC int -+mini_fo_readlink(dentry_t *dentry, char *buf, int bufsiz) -+{ -+ int err=0; -+ dentry_t *hidden_dentry = NULL; -+ -+ if(dtohd2(dentry) && dtohd2(dentry)->d_inode) { -+ hidden_dentry = dtohd2(dentry); -+ } else if(dtohd(dentry) && dtohd(dentry)->d_inode) { -+ hidden_dentry = dtohd(dentry); -+ } else { -+ goto out; -+ } -+ -+ if (!hidden_dentry->d_inode->i_op || -+ !hidden_dentry->d_inode->i_op->readlink) { -+ err = -EINVAL; goto out; -+ } -+ -+ err = hidden_dentry->d_inode->i_op->readlink(hidden_dentry, -+ buf, -+ bufsiz); -+ if (err > 0) -+ fist_copy_attr_atime(dentry->d_inode, hidden_dentry->d_inode); -+ -+ out: -+ return err; -+} -+ -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) -+static int mini_fo_follow_link(dentry_t *dentry, struct nameidata *nd) -+#else -+static void* mini_fo_follow_link(dentry_t *dentry, struct nameidata *nd) -+#endif -+{ -+ char *buf; -+ int len = PAGE_SIZE, err; -+ mm_segment_t old_fs; -+ -+ /* in 2.6 this is freed by mini_fo_put_link called by __do_follow_link */ -+ buf = kmalloc(len, GFP_KERNEL); -+ if (!buf) { -+ err = -ENOMEM; -+ goto out; -+ } -+ -+ /* read the symlink, and then we will follow it */ -+ old_fs = get_fs(); -+ set_fs(KERNEL_DS); -+ err = dentry->d_inode->i_op->readlink(dentry, buf, len); -+ set_fs(old_fs); -+ if (err < 0) { -+ kfree(buf); -+ buf = NULL; -+ goto out; -+ } -+ buf[err] = 0; -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -+ nd_set_link(nd, buf); -+ err = 0; -+#else -+ err = vfs_follow_link(nd, buf); -+#endif -+ -+ out: -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) -+ kfree(buf); -+#endif -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) -+ return err; -+#else -+ return ERR_PTR(err); -+#endif -+} -+ -+STATIC -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) -+void mini_fo_put_link(struct dentry *dentry, struct nameidata *nd) -+#else -+void mini_fo_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie) -+#endif -+{ -+ char *link; -+ link = nd_get_link(nd); -+ kfree(link); -+} -+#endif -+ -+STATIC int -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -+mini_fo_permission(inode_t *inode, int mask, struct nameidata *nd) -+#else -+mini_fo_permission(inode_t *inode, int mask) -+#endif -+{ -+ inode_t *hidden_inode; -+ int mode; -+ int err; -+ -+ if(itohi2(inode)) { -+ hidden_inode = itohi2(inode); -+ } else { -+ hidden_inode = itohi(inode); -+ } -+ mode = inode->i_mode; -+ -+ /* not really needed, as permission handles everything: -+ * err = vfs_permission(inode, mask); -+ * if (err) -+ * goto out; -+ */ -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -+ err = permission(hidden_inode, mask, nd); -+#else -+ err = permission(hidden_inode, mask); -+#endif -+ -+ /* out: */ -+ return err; -+} -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) -+STATIC int -+mini_fo_inode_revalidate(dentry_t *dentry) -+{ -+ int err = 0; -+ dentry_t *hidden_dentry; -+ inode_t *hidden_inode; -+ -+ ASSERT(dentry->d_inode); -+ ASSERT(itopd(dentry->d_inode)); -+ -+ if(itohi2(dentry->d_inode)) { -+ hidden_dentry = dtohd2(dentry); -+ hidden_inode = hidden_dentry->d_inode; -+ } else if(itohi(dentry->d_inode)) { -+ hidden_dentry = dtohd(dentry); -+ hidden_inode = hidden_dentry->d_inode; -+ } else { -+ printk(KERN_CRIT "mini_fo_inode_revalidate: ERROR, invalid state detected.\n"); -+ err = -ENOENT; -+ goto out; -+ } -+ if (hidden_inode && hidden_inode->i_op && hidden_inode->i_op->revalidate){ -+ err = hidden_inode->i_op->revalidate(hidden_dentry); -+ if (err) -+ goto out; -+ } -+ fist_copy_attr_all(dentry->d_inode, hidden_inode); -+ out: -+ return err; -+} -+#endif -+ -+STATIC int -+mini_fo_setattr(dentry_t *dentry, struct iattr *ia) -+{ -+ int err = 0; -+ -+ check_mini_fo_dentry(dentry); -+ -+ if(!is_mini_fo_existant(dentry)) { -+ printk(KERN_CRIT "mini_fo_setattr: ERROR, invalid state detected [1].\n"); -+ goto out; -+ } -+ -+ if(dtost(dentry) == UNMODIFIED) { -+ if(!IS_COPY_FLAG(ia->ia_valid)) -+ goto out; /* we ignore these changes to base */ -+ -+ if(S_ISDIR(dentry->d_inode->i_mode)) { -+ err = dir_unmod_to_mod(dentry); -+ } else { -+ /* we copy contents if file is not beeing truncated */ -+ if(S_ISREG(dentry->d_inode->i_mode) && -+ !(ia->ia_size == 0 && (ia->ia_valid & ATTR_SIZE))) { -+ err = nondir_unmod_to_mod(dentry, 1); -+ } else -+ err = nondir_unmod_to_mod(dentry, 0); -+ } -+ if(err) { -+ err = -EINVAL; -+ printk(KERN_CRIT "mini_fo_setattr: ERROR changing states.\n"); -+ goto out; -+ } -+ } -+ if(!exists_in_storage(dentry)) { -+ printk(KERN_CRIT "mini_fo_setattr: ERROR, invalid state detected [2].\n"); -+ err = -EINVAL; -+ goto out; -+ } -+ ASSERT(dentry->d_inode); -+ ASSERT(dtohd2(dentry)); -+ ASSERT(itopd(dentry->d_inode)); -+ ASSERT(itohi2(dentry->d_inode)); -+ -+ err = notify_change(dtohd2(dentry), ia); -+ fist_copy_attr_all(dentry->d_inode, itohi2(dentry->d_inode)); -+ out: -+ return err; -+} -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -+STATIC int -+mini_fo_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) -+{ -+ int err = 0; -+ dentry_t *hidden_dentry; -+ -+ ASSERT(dentry->d_inode); -+ ASSERT(itopd(dentry->d_inode)); -+ -+ if(itohi2(dentry->d_inode)) { -+ hidden_dentry = dtohd2(dentry); -+ } else if(itohi(dentry->d_inode)) { -+ hidden_dentry = dtohd(dentry); -+ } else { -+ printk(KERN_CRIT "mini_fo_getattr: ERROR, invalid state detected.\n"); -+ err = -ENOENT; -+ goto out; -+ } -+ fist_copy_attr_all(dentry->d_inode, hidden_dentry->d_inode); -+ -+ ASSERT(hidden_dentry); -+ ASSERT(hidden_dentry->d_inode); -+ ASSERT(hidden_dentry->d_inode->i_op); -+ -+ generic_fillattr(dentry->d_inode, stat); -+ if (!stat->blksize) { -+ struct super_block *s = hidden_dentry->d_inode->i_sb; -+ unsigned blocks; -+ blocks = (stat->size+s->s_blocksize-1) >> s->s_blocksize_bits; -+ stat->blocks = (s->s_blocksize / 512) * blocks; -+ stat->blksize = s->s_blocksize; -+ } -+ out: -+ return err; -+} -+#endif -+ -+#if defined(XATTR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20)) -+#if 0 /* no xattr_alloc() and xattr_free() */ -+/* This is lifted from fs/xattr.c */ -+static void * -+xattr_alloc(size_t size, size_t limit) -+{ -+ void *ptr; -+ -+ if (size > limit) -+ return ERR_PTR(-E2BIG); -+ -+ if (!size) /* size request, no buffer is needed */ -+ return NULL; -+ else if (size <= PAGE_SIZE) -+ ptr = kmalloc((unsigned long) size, GFP_KERNEL); -+ else -+ ptr = vmalloc((unsigned long) size); -+ if (!ptr) -+ return ERR_PTR(-ENOMEM); -+ return ptr; -+} -+ -+static void -+xattr_free(void *ptr, size_t size) -+{ -+ if (!size) /* size request, no buffer was needed */ -+ return; -+ else if (size <= PAGE_SIZE) -+ kfree(ptr); -+ else -+ vfree(ptr); -+} -+#endif /* no xattr_alloc() and xattr_free() */ -+ -+/* BKL held by caller. -+ * dentry->d_inode->i_sem down -+ */ -+STATIC int -+mini_fo_getxattr(struct dentry *dentry, const char *name, void *value, size_t size) { -+ struct dentry *hidden_dentry = NULL; -+ int err = -EOPNOTSUPP; -+ /* Define these anyway so we don't need as much ifdef'ed code. */ -+ char *encoded_name = NULL; -+ char *encoded_value = NULL; -+ -+ check_mini_fo_dentry(dentry); -+ -+ if(exists_in_storage(dentry)) -+ hidden_dentry = dtohd2(dentry); -+ else -+ hidden_dentry = dtohd(dentry); -+ -+ ASSERT(hidden_dentry); -+ ASSERT(hidden_dentry->d_inode); -+ ASSERT(hidden_dentry->d_inode->i_op); -+ -+ if (hidden_dentry->d_inode->i_op->getxattr) { -+ encoded_name = (char *)name; -+ encoded_value = (char *)value; -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) -+ mutex_lock(&hidden_dentry->d_inode->i_mutex); -+#else -+ down(&hidden_dentry->d_inode->i_sem); -+#endif -+ /* lock_kernel() already done by caller. */ -+ err = hidden_dentry->d_inode->i_op->getxattr(hidden_dentry, encoded_name, encoded_value, size); -+ /* unlock_kernel() will be done by caller. */ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) -+ mutex_lock(&hidden_dentry->d_inode->i_mutex); -+#else -+ up(&hidden_dentry->d_inode->i_sem); -+#endif -+ } -+ return err; -+} -+ -+/* BKL held by caller. -+ * dentry->d_inode->i_sem down -+ */ -+STATIC int -+#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,21) \ -+ && LINUX_VERSION_CODE <= KERNEL_VERSION(2,4,23)) \ -+ || LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) -+mini_fo_setxattr(struct dentry *dentry, const char *name, -+ const void *value, size_t size, int flags) -+#else -+mini_fo_setxattr(struct dentry *dentry, const char *name, -+ void *value, size_t size, int flags) -+#endif -+ -+{ -+ struct dentry *hidden_dentry = NULL; -+ int err = -EOPNOTSUPP; -+ -+ /* Define these anyway, so we don't have as much ifdef'ed code. */ -+ char *encoded_value = NULL; -+ char *encoded_name = NULL; -+ -+ check_mini_fo_dentry(dentry); -+ -+ if(exists_in_storage(dentry)) -+ hidden_dentry = dtohd2(dentry); -+ else -+ hidden_dentry = dtohd(dentry); -+ -+ ASSERT(hidden_dentry); -+ ASSERT(hidden_dentry->d_inode); -+ ASSERT(hidden_dentry->d_inode->i_op); -+ -+ if (hidden_dentry->d_inode->i_op->setxattr) { -+ encoded_name = (char *)name; -+ encoded_value = (char *)value; -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) -+ mutex_lock(&hidden_dentry->d_inode->i_mutex); -+#else -+ down(&hidden_dentry->d_inode->i_sem); -+#endif -+ /* lock_kernel() already done by caller. */ -+ err = hidden_dentry->d_inode->i_op->setxattr(hidden_dentry, encoded_name, encoded_value, size, flags); -+ /* unlock_kernel() will be done by caller. */ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) -+ mutex_unlock(&hidden_dentry->d_inode->i_mutex); -+#else -+ up(&hidden_dentry->d_inode->i_sem); -+#endif -+ } -+ return err; -+} -+ -+/* BKL held by caller. -+ * dentry->d_inode->i_sem down -+ */ -+STATIC int -+mini_fo_removexattr(struct dentry *dentry, const char *name) { -+ struct dentry *hidden_dentry = NULL; -+ int err = -EOPNOTSUPP; -+ char *encoded_name; -+ -+ check_mini_fo_dentry(dentry); -+ -+ if(exists_in_storage(dentry)) -+ hidden_dentry = dtohd2(dentry); -+ else -+ hidden_dentry = dtohd(dentry); -+ -+ ASSERT(hidden_dentry); -+ ASSERT(hidden_dentry->d_inode); -+ ASSERT(hidden_dentry->d_inode->i_op); -+ -+ if (hidden_dentry->d_inode->i_op->removexattr) { -+ encoded_name = (char *)name; -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) -+ mutex_lock(&hidden_dentry->d_inode->i_mutex); -+#else -+ down(&hidden_dentry->d_inode->i_sem); -+#endif -+ /* lock_kernel() already done by caller. */ -+ err = hidden_dentry->d_inode->i_op->removexattr(hidden_dentry, encoded_name); -+ /* unlock_kernel() will be done by caller. */ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) -+ mutex_unlock(&hidden_dentry->d_inode->i_mutex); -+#else -+ up(&hidden_dentry->d_inode->i_sem); -+#endif -+ } -+ return err; -+} -+ -+/* BKL held by caller. -+ * dentry->d_inode->i_sem down -+ */ -+STATIC int -+mini_fo_listxattr(struct dentry *dentry, char *list, size_t size) { -+ struct dentry *hidden_dentry = NULL; -+ int err = -EOPNOTSUPP; -+ char *encoded_list = NULL; -+ -+ check_mini_fo_dentry(dentry); -+ -+ if(exists_in_storage(dentry)) -+ hidden_dentry = dtohd2(dentry); -+ else -+ hidden_dentry = dtohd(dentry); -+ -+ ASSERT(hidden_dentry); -+ ASSERT(hidden_dentry->d_inode); -+ ASSERT(hidden_dentry->d_inode->i_op); -+ -+ if (hidden_dentry->d_inode->i_op->listxattr) { -+ encoded_list = list; -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) -+ mutex_lock(&hidden_dentry->d_inode->i_mutex); -+#else -+ down(&hidden_dentry->d_inode->i_sem); -+#endif -+ /* lock_kernel() already done by caller. */ -+ err = hidden_dentry->d_inode->i_op->listxattr(hidden_dentry, encoded_list, size); -+ /* unlock_kernel() will be done by caller. */ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) -+ mutex_unlock(&hidden_dentry->d_inode->i_mutex); -+#else -+ up(&hidden_dentry->d_inode->i_sem); -+#endif -+ } -+ return err; -+} -+# endif /* defined(XATTR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20)) */ -+ -+struct inode_operations mini_fo_symlink_iops = -+ { -+ readlink: mini_fo_readlink, -+ follow_link: mini_fo_follow_link, -+ /* mk: permission: mini_fo_permission, */ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) -+ revalidate: mini_fo_inode_revalidate, -+#endif -+ setattr: mini_fo_setattr, -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -+ getattr: mini_fo_getattr, -+ put_link: mini_fo_put_link, -+#endif -+ -+#if defined(XATTR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20)) -+ setxattr: mini_fo_setxattr, -+ getxattr: mini_fo_getxattr, -+ listxattr: mini_fo_listxattr, -+ removexattr: mini_fo_removexattr -+# endif /* defined(XATTR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20)) */ -+ }; -+ -+struct inode_operations mini_fo_dir_iops = -+ { -+ create: mini_fo_create, -+ lookup: mini_fo_lookup, -+ link: mini_fo_link, -+ unlink: mini_fo_unlink, -+ symlink: mini_fo_symlink, -+ mkdir: mini_fo_mkdir, -+ rmdir: mini_fo_rmdir, -+ mknod: mini_fo_mknod, -+ rename: mini_fo_rename, -+ /* no readlink/follow_link for non-symlinks */ -+ // off because we have setattr -+ // truncate: mini_fo_truncate, -+ /* mk:permission: mini_fo_permission, */ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) -+ revalidate: mini_fo_inode_revalidate, -+#endif -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -+ getattr: mini_fo_getattr, -+#endif -+ setattr: mini_fo_setattr, -+#if defined(XATTR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20)) -+ setxattr: mini_fo_setxattr, -+ getxattr: mini_fo_getxattr, -+ listxattr: mini_fo_listxattr, -+ removexattr: mini_fo_removexattr -+# endif /* XATTR && LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20) */ -+ }; -+ -+struct inode_operations mini_fo_main_iops = -+ { -+ /* permission: mini_fo_permission, */ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) -+ revalidate: mini_fo_inode_revalidate, -+#endif -+ setattr: mini_fo_setattr, -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -+ getattr: mini_fo_getattr, -+#endif -+#if defined(XATTR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20)) -+ setxattr: mini_fo_setxattr, -+ getxattr: mini_fo_getxattr, -+ listxattr: mini_fo_listxattr, -+ removexattr: mini_fo_removexattr -+# endif /* XATTR && LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20) */ -+ }; ---- /dev/null -+++ b/fs/mini_fo/main.c -@@ -0,0 +1,423 @@ -+/* -+ * Copyright (c) 1997-2003 Erez Zadok -+ * Copyright (c) 2001-2003 Stony Brook University -+ * -+ * For specific licensing information, see the COPYING file distributed with -+ * this package, or get one from ftp://ftp.filesystems.org/pub/fist/COPYING. -+ * -+ * This Copyright notice must be kept intact and distributed with all -+ * fistgen sources INCLUDING sources generated by fistgen. -+ */ -+/* -+ * Copyright (C) 2004, 2005 Markus Klotzbuecher -+ * -+ * 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. -+ */ -+ -+/* -+ * $Id$ -+ */ -+ -+#ifdef HAVE_CONFIG_H -+# include -+#endif -+ -+#include "fist.h" -+#include "mini_fo.h" -+#include -+ -+/* This definition must only appear after we include */ -+#ifndef MODULE_LICENSE -+# define MODULE_LICENSE(bison) -+#endif /* not MODULE_LICENSE */ -+ -+/* -+ * This is the mini_fo tri interpose function, which extends the -+ * functionality of the regular interpose by interposing a higher -+ * level inode on top of two lower level ones: the base filesystem -+ * inode and the storage filesystem inode. -+ * -+ * sb we pass is mini_fo's super_block -+ */ -+int -+mini_fo_tri_interpose(dentry_t *hidden_dentry, -+ dentry_t *hidden_sto_dentry, -+ dentry_t *dentry, super_block_t *sb, int flag) -+{ -+ inode_t *hidden_inode = NULL; -+ inode_t *hidden_sto_inode = NULL; /* store corresponding storage inode */ -+ int err = 0; -+ inode_t *inode; -+ -+ /* Pointer to hidden_sto_inode if exists, else to hidden_inode. -+ * This is used to copy the attributes of the correct inode. */ -+ inode_t *master_inode; -+ -+ if(hidden_dentry) -+ hidden_inode = hidden_dentry->d_inode; -+ if(hidden_sto_dentry) -+ hidden_sto_inode = hidden_sto_dentry->d_inode; -+ -+ ASSERT(dentry->d_inode == NULL); -+ -+ /* mk: One of the inodes associated with the dentrys is likely to -+ * be NULL, so carefull: -+ */ -+ ASSERT((hidden_inode != NULL) || (hidden_sto_inode != NULL)); -+ -+ if(hidden_sto_inode) -+ master_inode = hidden_sto_inode; -+ else -+ master_inode = hidden_inode; -+ -+ /* -+ * We allocate our new inode below, by calling iget. -+ * iget will call our read_inode which will initialize some -+ * of the new inode's fields -+ */ -+ -+ /* -+ * original: inode = iget(sb, hidden_inode->i_ino); -+ */ -+ inode = iget(sb, iunique(sb, 25)); -+ if (!inode) { -+ err = -EACCES; /* should be impossible??? */ -+ goto out; -+ } -+ -+ /* -+ * interpose the inode if not already interposed -+ * this is possible if the inode is being reused -+ * XXX: what happens if we get_empty_inode() but there's another already? -+ * for now, ASSERT() that this can't happen; fix later. -+ */ -+ if (itohi(inode) != NULL) { -+ printk(KERN_CRIT "mini_fo_tri_interpose: itohi(inode) != NULL.\n"); -+ } -+ if (itohi2(inode) != NULL) { -+ printk(KERN_CRIT "mini_fo_tri_interpose: itohi2(inode) != NULL.\n"); -+ } -+ -+ /* mk: Carefull, igrab can't handle NULL inodes (ok, why should it?), so -+ * we need to check here: -+ */ -+ if(hidden_inode) -+ itohi(inode) = igrab(hidden_inode); -+ else -+ itohi(inode) = NULL; -+ -+ if(hidden_sto_inode) -+ itohi2(inode) = igrab(hidden_sto_inode); -+ else -+ itohi2(inode) = NULL; -+ -+ -+ /* Use different set of inode ops for symlinks & directories*/ -+ if (S_ISLNK(master_inode->i_mode)) -+ inode->i_op = &mini_fo_symlink_iops; -+ else if (S_ISDIR(master_inode->i_mode)) -+ inode->i_op = &mini_fo_dir_iops; -+ -+ /* Use different set of file ops for directories */ -+ if (S_ISDIR(master_inode->i_mode)) -+ inode->i_fop = &mini_fo_dir_fops; -+ -+ /* properly initialize special inodes */ -+ if (S_ISBLK(master_inode->i_mode) || S_ISCHR(master_inode->i_mode) || -+ S_ISFIFO(master_inode->i_mode) || S_ISSOCK(master_inode->i_mode)) { -+ init_special_inode(inode, master_inode->i_mode, master_inode->i_rdev); -+ } -+ -+ /* Fix our inode's address operations to that of the lower inode */ -+ if (inode->i_mapping->a_ops != master_inode->i_mapping->a_ops) { -+ inode->i_mapping->a_ops = master_inode->i_mapping->a_ops; -+ } -+ -+ /* only (our) lookup wants to do a d_add */ -+ if (flag) -+ d_add(dentry, inode); -+ else -+ d_instantiate(dentry, inode); -+ -+ ASSERT(dtopd(dentry) != NULL); -+ -+ /* all well, copy inode attributes */ -+ fist_copy_attr_all(inode, master_inode); -+ -+ out: -+ return err; -+} -+ -+/* parse mount options "base=" and "sto=" */ -+dentry_t * -+mini_fo_parse_options(super_block_t *sb, char *options) -+{ -+ dentry_t *hidden_root = ERR_PTR(-EINVAL); -+ dentry_t *hidden_root2 = ERR_PTR(-EINVAL); -+ struct nameidata nd, nd2; -+ char *name, *tmp, *end; -+ int err = 0; -+ -+ /* We don't want to go off the end of our arguments later on. */ -+ for (end = options; *end; end++); -+ -+ while (options < end) { -+ tmp = options; -+ while (*tmp && *tmp != ',') -+ tmp++; -+ *tmp = '\0'; -+ if (!strncmp("base=", options, 5)) { -+ name = options + 5; -+ printk(KERN_INFO "mini_fo: using base directory: %s\n", name); -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) -+ if (path_init(name, LOOKUP_FOLLOW, &nd)) -+ err = path_walk(name, &nd); -+#else -+ err = path_lookup(name, LOOKUP_FOLLOW, &nd); -+#endif -+ if (err) { -+ printk(KERN_CRIT "mini_fo: error accessing hidden directory '%s'\n", name); -+ hidden_root = ERR_PTR(err); -+ goto out; -+ } -+ hidden_root = nd.dentry; -+ stopd(sb)->base_dir_dentry = nd.dentry; -+ stopd(sb)->hidden_mnt = nd.mnt; -+ -+ } else if(!strncmp("sto=", options, 4)) { -+ /* parse the storage dir */ -+ name = options + 4; -+ printk(KERN_INFO "mini_fo: using storage directory: %s\n", name); -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) -+ if(path_init(name, LOOKUP_FOLLOW, &nd2)) -+ err = path_walk(name, &nd2); -+#else -+ err = path_lookup(name, LOOKUP_FOLLOW, &nd2); -+#endif -+ if(err) { -+ printk(KERN_CRIT "mini_fo: error accessing hidden storage directory '%s'\n", name); -+ -+ hidden_root2 = ERR_PTR(err); -+ goto out; -+ } -+ hidden_root2 = nd2.dentry; -+ stopd(sb)->storage_dir_dentry = nd2.dentry; -+ stopd(sb)->hidden_mnt2 = nd2.mnt; -+ stohs2(sb) = hidden_root2->d_sb; -+ -+ /* validate storage dir, this is done in -+ * mini_fo_read_super for the base directory. -+ */ -+ if (IS_ERR(hidden_root2)) { -+ printk(KERN_WARNING "mini_fo_parse_options: storage dentry lookup failed (err = %ld)\n", PTR_ERR(hidden_root2)); -+ goto out; -+ } -+ if (!hidden_root2->d_inode) { -+ printk(KERN_WARNING "mini_fo_parse_options: no storage dir to interpose on.\n"); -+ goto out; -+ } -+ stohs2(sb) = hidden_root2->d_sb; -+ } else { -+ printk(KERN_WARNING "mini_fo: unrecognized option '%s'\n", options); -+ hidden_root = ERR_PTR(-EINVAL); -+ goto out; -+ } -+ options = tmp + 1; -+ } -+ -+ out: -+ if(IS_ERR(hidden_root2)) -+ return hidden_root2; -+ return hidden_root; -+} -+ -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -+static int -+#else -+super_block_t * -+#endif -+mini_fo_read_super(super_block_t *sb, void *raw_data, int silent) -+{ -+ dentry_t *hidden_root; -+ int err = 0; -+ -+ if (!raw_data) { -+ printk(KERN_WARNING "mini_fo_read_super: missing argument\n"); -+ err = -EINVAL; -+ goto out; -+ } -+ /* -+ * Allocate superblock private data -+ */ -+ __stopd(sb) = kmalloc(sizeof(struct mini_fo_sb_info), GFP_KERNEL); -+ if (!stopd(sb)) { -+ printk(KERN_WARNING "%s: out of memory\n", __FUNCTION__); -+ err = -ENOMEM; -+ goto out; -+ } -+ stohs(sb) = NULL; -+ -+ hidden_root = mini_fo_parse_options(sb, raw_data); -+ if (IS_ERR(hidden_root)) { -+ printk(KERN_WARNING "mini_fo_read_super: lookup_dentry failed (err = %ld)\n", PTR_ERR(hidden_root)); -+ err = PTR_ERR(hidden_root); -+ goto out_free; -+ } -+ if (!hidden_root->d_inode) { -+ printk(KERN_WARNING "mini_fo_read_super: no directory to interpose on\n"); -+ goto out_free; -+ } -+ stohs(sb) = hidden_root->d_sb; -+ -+ /* -+ * Linux 2.4.2-ac3 and beyond has code in -+ * mm/filemap.c:generic_file_write() that requires sb->s_maxbytes -+ * to be populated. If not set, all write()s under that sb will -+ * return 0. -+ * -+ * Linux 2.4.4+ automatically sets s_maxbytes to MAX_NON_LFS; -+ * the filesystem should override it only if it supports LFS. -+ */ -+ /* non-SCA code is good to go with LFS */ -+ sb->s_maxbytes = hidden_root->d_sb->s_maxbytes; -+ -+ sb->s_op = &mini_fo_sops; -+ /* -+ * we can't use d_alloc_root if we want to use -+ * our own interpose function unchanged, -+ * so we simply replicate *most* of the code in d_alloc_root here -+ */ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) -+ sb->s_root = d_alloc(NULL, &(const struct qstr) { "/", 1, 0 }); -+#else -+ sb->s_root = d_alloc(NULL, &(const struct qstr){hash: 0, name: "/", len : 1}); -+#endif -+ if (IS_ERR(sb->s_root)) { -+ printk(KERN_WARNING "mini_fo_read_super: d_alloc failed\n"); -+ err = -ENOMEM; -+ goto out_dput; -+ } -+ -+ sb->s_root->d_op = &mini_fo_dops; -+ sb->s_root->d_sb = sb; -+ sb->s_root->d_parent = sb->s_root; -+ -+ /* link the upper and lower dentries */ -+ __dtopd(sb->s_root) = (struct mini_fo_dentry_info *) -+ kmalloc(sizeof(struct mini_fo_dentry_info), GFP_KERNEL); -+ if (!dtopd(sb->s_root)) { -+ err = -ENOMEM; -+ goto out_dput2; -+ } -+ dtopd(sb->s_root)->state = MODIFIED; -+ dtohd(sb->s_root) = hidden_root; -+ -+ /* fanout relevant, interpose on storage root dentry too */ -+ dtohd2(sb->s_root) = stopd(sb)->storage_dir_dentry; -+ -+ /* ...and call tri-interpose to interpose root dir inodes -+ * if (mini_fo_interpose(hidden_root, sb->s_root, sb, 0)) -+ */ -+ if(mini_fo_tri_interpose(hidden_root, dtohd2(sb->s_root), sb->s_root, sb, 0)) -+ goto out_dput2; -+ -+ /* initalize the wol list */ -+ itopd(sb->s_root->d_inode)->deleted_list_size = -1; -+ itopd(sb->s_root->d_inode)->renamed_list_size = -1; -+ meta_build_lists(sb->s_root); -+ -+ goto out; -+ -+ out_dput2: -+ dput(sb->s_root); -+ out_dput: -+ dput(hidden_root); -+ dput(dtohd2(sb->s_root)); /* release the hidden_sto_dentry too */ -+ out_free: -+ kfree(stopd(sb)); -+ __stopd(sb) = NULL; -+ out: -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -+ return err; -+#else -+ if (err) { -+ return ERR_PTR(err); -+ } else { -+ return sb; -+ } -+#endif -+} -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) -+static int mini_fo_get_sb(struct file_system_type *fs_type, -+ int flags, const char *dev_name, -+ void *raw_data, struct vfsmount *mnt) -+{ -+ return get_sb_nodev(fs_type, flags, raw_data, mini_fo_read_super, mnt); -+} -+#else -+static struct super_block *mini_fo_get_sb(struct file_system_type *fs_type, -+ int flags, const char *dev_name, -+ void *raw_data) -+{ -+ return get_sb_nodev(fs_type, flags, raw_data, mini_fo_read_super); -+} -+#endif -+ -+void mini_fo_kill_block_super(struct super_block *sb) -+{ -+ generic_shutdown_super(sb); -+ /* -+ * XXX: BUG: Halcrow: Things get unstable sometime after this point: -+ * lib/rwsem-spinlock.c:127: spin_is_locked on uninitialized -+ * fs/fs-writeback.c:402: spin_lock(fs/super.c:a0381828) already -+ * locked by fs/fs-writeback.c/402 -+ * -+ * Apparently, someone's not releasing a lock on sb_lock... -+ */ -+} -+ -+static struct file_system_type mini_fo_fs_type = { -+ .owner = THIS_MODULE, -+ .name = "mini_fo", -+ .get_sb = mini_fo_get_sb, -+ .kill_sb = mini_fo_kill_block_super, -+ .fs_flags = 0, -+}; -+ -+ -+#else -+static DECLARE_FSTYPE(mini_fo_fs_type, "mini_fo", mini_fo_read_super, 0); -+#endif -+ -+static int __init init_mini_fo_fs(void) -+{ -+ printk("Registering mini_fo version $Id$\n"); -+ return register_filesystem(&mini_fo_fs_type); -+} -+static void __exit exit_mini_fo_fs(void) -+{ -+ printk("Unregistering mini_fo version $Id$\n"); -+ unregister_filesystem(&mini_fo_fs_type); -+} -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) -+EXPORT_NO_SYMBOLS; -+#endif -+ -+MODULE_AUTHOR("Erez Zadok "); -+MODULE_DESCRIPTION("FiST-generated mini_fo filesystem"); -+MODULE_LICENSE("GPL"); -+ -+/* MODULE_PARM(fist_debug_var, "i"); */ -+/* MODULE_PARM_DESC(fist_debug_var, "Debug level"); */ -+ -+module_init(init_mini_fo_fs) -+module_exit(exit_mini_fo_fs) ---- /dev/null -+++ b/fs/mini_fo/Makefile -@@ -0,0 +1,17 @@ -+# -+# Makefile for mini_fo 2.4 and 2.6 Linux kernels -+# -+# Copyright (C) 2004, 2005 Markus Klotzbuecher -+# -+# 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. -+# -+ -+obj-$(CONFIG_MINI_FO) := mini_fo.o -+mini_fo-objs := meta.o dentry.o file.o inode.o main.o super.o state.o aux.o -+ -+# dependencies -+${mini_fo-objs}: mini_fo.h fist.h -+ ---- /dev/null -+++ b/fs/mini_fo/meta.c -@@ -0,0 +1,1000 @@ -+/* -+ * Copyright (C) 2004, 2005 Markus Klotzbuecher -+ * -+ * 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. -+ */ -+ -+#ifdef HAVE_CONFIG_H -+# include -+#endif /* HAVE_CONFIG_H */ -+#include "fist.h" -+#include "mini_fo.h" -+ -+int meta_build_lists(dentry_t *dentry) -+{ -+ struct mini_fo_inode_info *inode_info; -+ -+ dentry_t *meta_dentry = 0; -+ file_t *meta_file = 0; -+ mm_segment_t old_fs; -+ void *buf; -+ -+ int bytes, len; -+ struct vfsmount *meta_mnt; -+ char *entry; -+ -+ inode_info = itopd(dentry->d_inode); -+ if(!(inode_info->deleted_list_size == -1 && -+ inode_info->renamed_list_size == -1)) { -+ printk(KERN_CRIT "mini_fo: meta_build_lists: \ -+ Error, list(s) not virgin.\n"); -+ return -1; -+ } -+ -+ /* init our meta lists */ -+ INIT_LIST_HEAD(&inode_info->deleted_list); -+ inode_info->deleted_list_size = 0; -+ -+ INIT_LIST_HEAD(&inode_info->renamed_list); -+ inode_info->renamed_list_size = 0; -+ -+ /* might there be a META-file? */ -+ if(dtohd2(dentry) && dtohd2(dentry)->d_inode) { -+ meta_dentry = lookup_one_len(META_FILENAME, -+ dtohd2(dentry), -+ strlen(META_FILENAME)); -+ if(!meta_dentry->d_inode) { -+ dput(meta_dentry); -+ goto out_ok; -+ } -+ /* $%& err, is this correct? */ -+ meta_mnt = stopd(dentry->d_inode->i_sb)->hidden_mnt2; -+ mntget(meta_mnt); -+ -+ -+ /* open META-file for reading */ -+ meta_file = dentry_open(meta_dentry, meta_mnt, 0x0); -+ if(!meta_file || IS_ERR(meta_file)) { -+ printk(KERN_CRIT "mini_fo: meta_build_lists: \ -+ ERROR opening META file.\n"); -+ goto out_err; -+ } -+ -+ /* check if fs supports reading */ -+ if(!meta_file->f_op->read) { -+ printk(KERN_CRIT "mini_fo: meta_build_lists: \ -+ ERROR, fs does not support reading.\n"); -+ goto out_err_close; -+ } -+ -+ /* allocate a page for transfering the data */ -+ buf = (void *) __get_free_page(GFP_KERNEL); -+ if(!buf) { -+ printk(KERN_CRIT "mini_fo: meta_build_lists: \ -+ ERROR, out of mem.\n"); -+ goto out_err_close; -+ } -+ meta_file->f_pos = 0; -+ old_fs = get_fs(); -+ set_fs(KERNEL_DS); -+ do { -+ char *c; -+ bytes = meta_file->f_op->read(meta_file, buf, PAGE_SIZE, &meta_file->f_pos); -+ if(bytes == PAGE_SIZE) { -+ /* trim a cut off filename and adjust f_pos to get it next time */ -+ for(c = (char*) buf+PAGE_SIZE; -+ *c != '\n'; -+ c--, bytes--, meta_file->f_pos--); -+ } -+ entry = (char *) buf; -+ while(entry < (char *) buf+bytes) { -+ -+ char *old_path; -+ char *dir_name; -+ int old_len, new_len; -+ -+ /* len without '\n'*/ -+ len = (int) (strchr(entry, '\n') - entry); -+ switch (*entry) { -+ case 'D': -+ /* format: "D filename" */ -+ meta_list_add_d_entry(dentry, -+ entry+2, -+ len-2); -+ break; -+ case 'R': -+ /* format: "R path/xy/dir newDir" */ -+ old_path = entry+2; -+ dir_name = strchr(old_path, ' ') + 1; -+ old_len = dir_name - old_path - 1; -+ new_len = ((int) entry) + len - ((int ) dir_name); -+ meta_list_add_r_entry(dentry, -+ old_path, -+ old_len, -+ dir_name, -+ new_len); -+ break; -+ default: -+ /* unknown entry type detected */ -+ break; -+ } -+ entry += len+1; -+ } -+ -+ } while(meta_file->f_pos < meta_dentry->d_inode->i_size); -+ -+ free_page((unsigned long) buf); -+ set_fs(old_fs); -+ fput(meta_file); -+ } -+ goto out_ok; -+ -+ out_err_close: -+ fput(meta_file); -+ out_err: -+ mntput(meta_mnt); -+ dput(meta_dentry); -+ return -1; -+ out_ok: -+ return 1; /* check this!!! inode_info->wol_size; */ -+} -+ -+/* cleanups up all lists and free's the mem by dentry */ -+int meta_put_lists(dentry_t *dentry) -+{ -+ if(!dentry || !dentry->d_inode) { -+ printk("mini_fo: meta_put_lists: invalid dentry passed.\n"); -+ return -1; -+ } -+ return __meta_put_lists(dentry->d_inode); -+} -+ -+/* cleanups up all lists and free's the mem by inode */ -+int __meta_put_lists(inode_t *inode) -+{ -+ int err = 0; -+ if(!inode || !itopd(inode)) { -+ printk("mini_fo: __meta_put_lists: invalid inode passed.\n"); -+ return -1; -+ } -+ err = __meta_put_d_list(inode); -+ err |= __meta_put_r_list(inode); -+ return err; -+} -+ -+int meta_sync_lists(dentry_t *dentry) -+{ -+ int err = 0; -+ if(!dentry || !dentry->d_inode) { -+ printk("mini_fo: meta_sync_lists: \ -+ invalid dentry passed.\n"); -+ return -1; -+ } -+ err = meta_sync_d_list(dentry, 0); -+ err |= meta_sync_r_list(dentry, 1); -+ return err; -+} -+ -+ -+/* remove all D entries from the renamed list and free the mem */ -+int __meta_put_d_list(inode_t *inode) -+{ -+ struct list_head *tmp; -+ struct deleted_entry *del_entry; -+ struct mini_fo_inode_info *inode_info; -+ -+ if(!inode || !itopd(inode)) { -+ printk(KERN_CRIT "mini_fo: __meta_put_d_list: \ -+ invalid inode passed.\n"); -+ return -1; -+ } -+ inode_info = itopd(inode); -+ -+ /* nuke the DELETED-list */ -+ if(inode_info->deleted_list_size <= 0) -+ return 0; -+ -+ while(!list_empty(&inode_info->deleted_list)) { -+ tmp = inode_info->deleted_list.next; -+ list_del(tmp); -+ del_entry = list_entry(tmp, struct deleted_entry, list); -+ kfree(del_entry->name); -+ kfree(del_entry); -+ } -+ inode_info->deleted_list_size = 0; -+ -+ return 0; -+} -+ -+/* remove all R entries from the renamed list and free the mem */ -+int __meta_put_r_list(inode_t *inode) -+{ -+ struct list_head *tmp; -+ struct renamed_entry *ren_entry; -+ struct mini_fo_inode_info *inode_info; -+ -+ if(!inode || !itopd(inode)) { -+ printk(KERN_CRIT "mini_fo: meta_put_r_list: invalid inode.\n"); -+ return -1; -+ } -+ inode_info = itopd(inode); -+ -+ /* nuke the RENAMED-list */ -+ if(inode_info->renamed_list_size <= 0) -+ return 0; -+ -+ while(!list_empty(&inode_info->renamed_list)) { -+ tmp = inode_info->renamed_list.next; -+ list_del(tmp); -+ ren_entry = list_entry(tmp, struct renamed_entry, list); -+ kfree(ren_entry->new_name); -+ kfree(ren_entry->old_name); -+ kfree(ren_entry); -+ } -+ inode_info->renamed_list_size = 0; -+ -+ return 0; -+} -+ -+int meta_add_d_entry(dentry_t *dentry, const char *name, int len) -+{ -+ int err = 0; -+ err = meta_list_add_d_entry(dentry, name, len); -+ err |= meta_write_d_entry(dentry,name,len); -+ return err; -+} -+ -+/* add a D entry to the deleted list */ -+int meta_list_add_d_entry(dentry_t *dentry, const char *name, int len) -+{ -+ struct deleted_entry *del_entry; -+ struct mini_fo_inode_info *inode_info; -+ -+ if(!dentry || !dentry->d_inode) { -+ printk(KERN_CRIT "mini_fo: meta_list_add_d_entry: \ -+ invalid dentry passed.\n"); -+ return -1; -+ } -+ inode_info = itopd(dentry->d_inode); -+ -+ if(inode_info->deleted_list_size < 0) -+ return -1; -+ -+ del_entry = (struct deleted_entry *) -+ kmalloc(sizeof(struct deleted_entry), GFP_KERNEL); -+ del_entry->name = (char*) kmalloc(len, GFP_KERNEL); -+ if(!del_entry || !del_entry->name) { -+ printk(KERN_CRIT "mini_fo: meta_list_add_d_entry: \ -+ out of mem.\n"); -+ kfree(del_entry->name); -+ kfree(del_entry); -+ return -ENOMEM; -+ } -+ -+ strncpy(del_entry->name, name, len); -+ del_entry->len = len; -+ -+ list_add(&del_entry->list, &inode_info->deleted_list); -+ inode_info->deleted_list_size++; -+ return 0; -+} -+ -+int meta_add_r_entry(dentry_t *dentry, -+ const char *old_name, int old_len, -+ const char *new_name, int new_len) -+{ -+ int err = 0; -+ err = meta_list_add_r_entry(dentry, -+ old_name, old_len, -+ new_name, new_len); -+ err |= meta_write_r_entry(dentry, -+ old_name, old_len, -+ new_name, new_len); -+ return err; -+} -+ -+/* add a R entry to the renamed list */ -+int meta_list_add_r_entry(dentry_t *dentry, -+ const char *old_name, int old_len, -+ const char *new_name, int new_len) -+{ -+ struct renamed_entry *ren_entry; -+ struct mini_fo_inode_info *inode_info; -+ -+ if(!dentry || !dentry->d_inode) { -+ printk(KERN_CRIT "mini_fo: meta_list_add_r_entry: \ -+ invalid dentry passed.\n"); -+ return -1; -+ } -+ inode_info = itopd(dentry->d_inode); -+ -+ if(inode_info->renamed_list_size < 0) -+ return -1; -+ -+ ren_entry = (struct renamed_entry *) -+ kmalloc(sizeof(struct renamed_entry), GFP_KERNEL); -+ ren_entry->old_name = (char*) kmalloc(old_len, GFP_KERNEL); -+ ren_entry->new_name = (char*) kmalloc(new_len, GFP_KERNEL); -+ -+ if(!ren_entry || !ren_entry->old_name || !ren_entry->new_name) { -+ printk(KERN_CRIT "mini_fo: meta_list_add_r_entry: \ -+ out of mem.\n"); -+ kfree(ren_entry->new_name); -+ kfree(ren_entry->old_name); -+ kfree(ren_entry); -+ return -ENOMEM; -+ } -+ -+ strncpy(ren_entry->old_name, old_name, old_len); -+ ren_entry->old_len = old_len; -+ strncpy(ren_entry->new_name, new_name, new_len); -+ ren_entry->new_len = new_len; -+ -+ list_add(&ren_entry->list, &inode_info->renamed_list); -+ inode_info->renamed_list_size++; -+ return 0; -+} -+ -+ -+int meta_remove_r_entry(dentry_t *dentry, const char *name, int len) -+{ -+ int err = 0; -+ if(!dentry || !dentry->d_inode) { -+ printk(KERN_CRIT -+ "mini_fo: meta_remove_r_entry: \ -+ invalid dentry passed.\n"); -+ return -1; -+ } -+ -+ err = meta_list_remove_r_entry(dentry, name, len); -+ err |= meta_sync_lists(dentry); -+ return err; -+} -+ -+int meta_list_remove_r_entry(dentry_t *dentry, const char *name, int len) -+{ -+ if(!dentry || !dentry->d_inode) { -+ printk(KERN_CRIT -+ "mini_fo: meta_list_remove_r_entry: \ -+ invalid dentry passed.\n"); -+ return -1; -+ } -+ return __meta_list_remove_r_entry(dentry->d_inode, name, len); -+} -+ -+int __meta_list_remove_r_entry(inode_t *inode, const char *name, int len) -+{ -+ struct list_head *tmp; -+ struct renamed_entry *ren_entry; -+ struct mini_fo_inode_info *inode_info; -+ -+ if(!inode || !itopd(inode)) -+ printk(KERN_CRIT -+ "mini_fo: __meta_list_remove_r_entry: \ -+ invalid inode passed.\n"); -+ inode_info = itopd(inode); -+ -+ if(inode_info->renamed_list_size < 0) -+ return -1; -+ if(inode_info->renamed_list_size == 0) -+ return 1; -+ -+ list_for_each(tmp, &inode_info->renamed_list) { -+ ren_entry = list_entry(tmp, struct renamed_entry, list); -+ if(ren_entry->new_len != len) -+ continue; -+ -+ if(!strncmp(ren_entry->new_name, name, len)) { -+ list_del(tmp); -+ kfree(ren_entry->new_name); -+ kfree(ren_entry->old_name); -+ kfree(ren_entry); -+ inode_info->renamed_list_size--; -+ return 0; -+ } -+ } -+ return 1; -+} -+ -+ -+/* append a single D entry to the meta file */ -+int meta_write_d_entry(dentry_t *dentry, const char *name, int len) -+{ -+ dentry_t *meta_dentry = 0; -+ file_t *meta_file = 0; -+ mm_segment_t old_fs; -+ -+ int bytes, err; -+ struct vfsmount *meta_mnt = 0; -+ char *buf; -+ -+ err = 0; -+ -+ if(itopd(dentry->d_inode)->deleted_list_size < 0) { -+ err = -1; -+ goto out; -+ } -+ -+ if(dtopd(dentry)->state == UNMODIFIED) { -+ err = build_sto_structure(dentry->d_parent, dentry); -+ if(err) { -+ printk(KERN_CRIT "mini_fo: meta_write_d_entry: \ -+ build_sto_structure failed.\n"); -+ goto out; -+ } -+ } -+ meta_dentry = lookup_one_len(META_FILENAME, -+ dtohd2(dentry), strlen (META_FILENAME)); -+ -+ /* We need to create a META-file */ -+ if(!meta_dentry->d_inode) { -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -+ vfs_create(dtohd2(dentry)->d_inode, -+ meta_dentry, -+ S_IRUSR | S_IWUSR, -+ NULL); -+#else -+ vfs_create(dtohd2(dentry)->d_inode, -+ meta_dentry, -+ S_IRUSR | S_IWUSR); -+#endif -+ } -+ /* open META-file for writing */ -+ meta_file = dentry_open(meta_dentry, meta_mnt, 0x1); -+ if(!meta_file || IS_ERR(meta_file)) { -+ printk(KERN_CRIT "mini_fo: meta_write_d_entry: \ -+ ERROR opening meta file.\n"); -+ mntput(meta_mnt); /* $%& is this necessary? */ -+ dput(meta_dentry); -+ err = -1; -+ goto out; -+ } -+ -+ /* check if fs supports writing */ -+ if(!meta_file->f_op->write) { -+ printk(KERN_CRIT "mini_fo: meta_write_d_entry: \ -+ ERROR, fs does not support writing.\n"); -+ goto out_err_close; -+ } -+ -+ meta_file->f_pos = meta_dentry->d_inode->i_size; /* append */ -+ old_fs = get_fs(); -+ set_fs(KERNEL_DS); -+ -+ /* size: len for name, 1 for \n and 2 for "D " */ -+ buf = (char *) kmalloc(len+3, GFP_KERNEL); -+ if (!buf) { -+ printk(KERN_CRIT "mini_fo: meta_write_d_entry: \ -+ out of mem.\n"); -+ return -ENOMEM; -+ } -+ -+ buf[0] = 'D'; -+ buf[1] = ' '; -+ strncpy(buf+2, name, len); -+ buf[len+2] = '\n'; -+ bytes = meta_file->f_op->write(meta_file, buf, len+3, -+ &meta_file->f_pos); -+ if(bytes != len+3) { -+ printk(KERN_CRIT "mini_fo: meta_write_d_entry: \ -+ ERROR writing.\n"); -+ err = -1; -+ } -+ kfree(buf); -+ set_fs(old_fs); -+ -+ out_err_close: -+ fput(meta_file); -+ out: -+ return err; -+} -+ -+/* append a single R entry to the meta file */ -+int meta_write_r_entry(dentry_t *dentry, -+ const char *old_name, int old_len, -+ const char *new_name, int new_len) -+{ -+ dentry_t *meta_dentry = 0; -+ file_t *meta_file = 0; -+ mm_segment_t old_fs; -+ -+ int bytes, err, buf_len; -+ struct vfsmount *meta_mnt = 0; -+ char *buf; -+ -+ -+ err = 0; -+ -+ if(itopd(dentry->d_inode)->renamed_list_size < 0) { -+ err = -1; -+ goto out; -+ } -+ -+ /* build the storage structure? */ -+ if(dtopd(dentry)->state == UNMODIFIED) { -+ err = build_sto_structure(dentry->d_parent, dentry); -+ if(err) { -+ printk(KERN_CRIT "mini_fo: meta_write_r_entry: \ -+ build_sto_structure failed.\n"); -+ goto out; -+ } -+ } -+ meta_dentry = lookup_one_len(META_FILENAME, -+ dtohd2(dentry), -+ strlen (META_FILENAME)); -+ if(!meta_dentry->d_inode) { -+ /* We need to create a META-file */ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -+ vfs_create(dtohd2(dentry)->d_inode, -+ meta_dentry, S_IRUSR | S_IWUSR, NULL); -+#else -+ vfs_create(dtohd2(dentry)->d_inode, -+ meta_dentry, S_IRUSR | S_IWUSR); -+#endif -+ } -+ /* open META-file for writing */ -+ meta_file = dentry_open(meta_dentry, meta_mnt, 0x1); -+ if(!meta_file || IS_ERR(meta_file)) { -+ printk(KERN_CRIT "mini_fo: meta_write_r_entry: \ -+ ERROR opening meta file.\n"); -+ mntput(meta_mnt); -+ dput(meta_dentry); -+ err = -1; -+ goto out; -+ } -+ -+ /* check if fs supports writing */ -+ if(!meta_file->f_op->write) { -+ printk(KERN_CRIT "mini_fo: meta_write_r_entry: \ -+ ERROR, fs does not support writing.\n"); -+ goto out_err_close; -+ } -+ -+ meta_file->f_pos = meta_dentry->d_inode->i_size; /* append */ -+ old_fs = get_fs(); -+ set_fs(KERNEL_DS); -+ -+ /* size: 2 for "R ", old_len+new_len for names, 1 blank+1 \n */ -+ buf_len = old_len + new_len + 4; -+ buf = (char *) kmalloc(buf_len, GFP_KERNEL); -+ if (!buf) { -+ printk(KERN_CRIT "mini_fo: meta_write_r_entry: out of mem.\n"); -+ return -ENOMEM; -+ } -+ -+ buf[0] = 'R'; -+ buf[1] = ' '; -+ strncpy(buf + 2, old_name, old_len); -+ buf[old_len + 2] = ' '; -+ strncpy(buf + old_len + 3, new_name, new_len); -+ buf[buf_len -1] = '\n'; -+ bytes = meta_file->f_op->write(meta_file, buf, buf_len, &meta_file->f_pos); -+ if(bytes != buf_len) { -+ printk(KERN_CRIT "mini_fo: meta_write_r_entry: ERROR writing.\n"); -+ err = -1; -+ } -+ -+ kfree(buf); -+ set_fs(old_fs); -+ -+ out_err_close: -+ fput(meta_file); -+ out: -+ return err; -+} -+ -+/* sync D list to disk, append data if app_flag is 1 */ -+/* check the meta_mnt, which seems not to be used (properly) */ -+ -+int meta_sync_d_list(dentry_t *dentry, int app_flag) -+{ -+ dentry_t *meta_dentry; -+ file_t *meta_file; -+ mm_segment_t old_fs; -+ -+ int bytes, err; -+ struct vfsmount *meta_mnt; -+ char *buf; -+ -+ struct list_head *tmp; -+ struct deleted_entry *del_entry; -+ struct mini_fo_inode_info *inode_info; -+ -+ err = 0; -+ meta_file=0; -+ meta_mnt=0; -+ -+ if(!dentry || !dentry->d_inode) { -+ printk(KERN_CRIT "mini_fo: meta_sync_d_list: \ -+ invalid inode passed.\n"); -+ err = -1; -+ goto out; -+ } -+ inode_info = itopd(dentry->d_inode); -+ -+ if(inode_info->deleted_list_size < 0) { -+ err = -1; -+ goto out; -+ } -+ -+ /* ok, there is something to sync */ -+ -+ /* build the storage structure? */ -+ if(!dtohd2(dentry) && !itohi2(dentry->d_inode)) { -+ err = build_sto_structure(dentry->d_parent, dentry); -+ if(err) { -+ printk(KERN_CRIT "mini_fo: meta_sync_d_list: \ -+ build_sto_structure failed.\n"); -+ goto out; -+ } -+ } -+ meta_dentry = lookup_one_len(META_FILENAME, -+ dtohd2(dentry), -+ strlen(META_FILENAME)); -+ if(!meta_dentry->d_inode) { -+ /* We need to create a META-file */ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -+ vfs_create(dtohd2(dentry)->d_inode, -+ meta_dentry, S_IRUSR | S_IWUSR, NULL); -+#else -+ vfs_create(dtohd2(dentry)->d_inode, -+ meta_dentry, S_IRUSR | S_IWUSR); -+#endif -+ app_flag = 0; -+ } -+ /* need we truncate the meta file? */ -+ if(!app_flag) { -+ struct iattr newattrs; -+ newattrs.ia_size = 0; -+ newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME; -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) -+ mutex_lock(&meta_dentry->d_inode->i_mutex); -+#else -+ down(&meta_dentry->d_inode->i_sem); -+#endif -+ err = notify_change(meta_dentry, &newattrs); -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) -+ mutex_unlock(&meta_dentry->d_inode->i_mutex); -+#else -+ up(&meta_dentry->d_inode->i_sem); -+#endif -+ -+ if(err || meta_dentry->d_inode->i_size != 0) { -+ printk(KERN_CRIT "mini_fo: meta_sync_d_list: \ -+ ERROR truncating meta file.\n"); -+ goto out_err_close; -+ } -+ } -+ -+ /* open META-file for writing */ -+ meta_file = dentry_open(meta_dentry, meta_mnt, 0x1); -+ if(!meta_file || IS_ERR(meta_file)) { -+ printk(KERN_CRIT "mini_fo: meta_sync_d_list: \ -+ ERROR opening meta file.\n"); -+ /* we don't mntget so we dont't mntput (for now) -+ * mntput(meta_mnt); -+ */ -+ dput(meta_dentry); -+ err = -1; -+ goto out; -+ } -+ -+ /* check if fs supports writing */ -+ if(!meta_file->f_op->write) { -+ printk(KERN_CRIT "mini_fo: meta_sync_d_list: \ -+ ERROR, fs does not support writing.\n"); -+ goto out_err_close; -+ } -+ -+ meta_file->f_pos = meta_dentry->d_inode->i_size; /* append */ -+ old_fs = get_fs(); -+ set_fs(KERNEL_DS); -+ -+ /* here we go... */ -+ list_for_each(tmp, &inode_info->deleted_list) { -+ del_entry = list_entry(tmp, struct deleted_entry, list); -+ -+ /* size: len for name, 1 for \n and 2 for "D " */ -+ buf = (char *) kmalloc(del_entry->len+3, GFP_KERNEL); -+ if (!buf) { -+ printk(KERN_CRIT "mini_fo: meta_sync_d_list: \ -+ out of mem.\n"); -+ return -ENOMEM; -+ } -+ -+ buf[0] = 'D'; -+ buf[1] = ' '; -+ strncpy(buf+2, del_entry->name, del_entry->len); -+ buf[del_entry->len+2] = '\n'; -+ bytes = meta_file->f_op->write(meta_file, buf, -+ del_entry->len+3, -+ &meta_file->f_pos); -+ if(bytes != del_entry->len+3) { -+ printk(KERN_CRIT "mini_fo: meta_sync_d_list: \ -+ ERROR writing.\n"); -+ err |= -1; -+ } -+ kfree(buf); -+ } -+ set_fs(old_fs); -+ -+ out_err_close: -+ fput(meta_file); -+ out: -+ return err; -+ -+} -+ -+int meta_sync_r_list(dentry_t *dentry, int app_flag) -+{ -+ dentry_t *meta_dentry; -+ file_t *meta_file; -+ mm_segment_t old_fs; -+ -+ int bytes, err, buf_len; -+ struct vfsmount *meta_mnt; -+ char *buf; -+ -+ struct list_head *tmp; -+ struct renamed_entry *ren_entry; -+ struct mini_fo_inode_info *inode_info; -+ -+ err = 0; -+ meta_file=0; -+ meta_mnt=0; -+ -+ if(!dentry || !dentry->d_inode) { -+ printk(KERN_CRIT "mini_fo: meta_sync_r_list: \ -+ invalid dentry passed.\n"); -+ err = -1; -+ goto out; -+ } -+ inode_info = itopd(dentry->d_inode); -+ -+ if(inode_info->deleted_list_size < 0) { -+ err = -1; -+ goto out; -+ } -+ -+ /* ok, there is something to sync */ -+ -+ /* build the storage structure? */ -+ if(!dtohd2(dentry) && !itohi2(dentry->d_inode)) { -+ err = build_sto_structure(dentry->d_parent, dentry); -+ if(err) { -+ printk(KERN_CRIT "mini_fo: meta_sync_r_list: \ -+ build_sto_structure failed.\n"); -+ goto out; -+ } -+ } -+ meta_dentry = lookup_one_len(META_FILENAME, -+ dtohd2(dentry), -+ strlen(META_FILENAME)); -+ if(!meta_dentry->d_inode) { -+ /* We need to create a META-file */ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -+ vfs_create(dtohd2(dentry)->d_inode, -+ meta_dentry, S_IRUSR | S_IWUSR, NULL); -+#else -+ vfs_create(dtohd2(dentry)->d_inode, -+ meta_dentry, S_IRUSR | S_IWUSR); -+#endif -+ app_flag = 0; -+ } -+ /* need we truncate the meta file? */ -+ if(!app_flag) { -+ struct iattr newattrs; -+ newattrs.ia_size = 0; -+ newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME; -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) -+ mutex_lock(&meta_dentry->d_inode->i_mutex); -+#else -+ down(&meta_dentry->d_inode->i_sem); -+#endif -+ err = notify_change(meta_dentry, &newattrs); -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) -+ mutex_unlock(&meta_dentry->d_inode->i_mutex); -+#else -+ up(&meta_dentry->d_inode->i_sem); -+#endif -+ if(err || meta_dentry->d_inode->i_size != 0) { -+ printk(KERN_CRIT "mini_fo: meta_sync_r_list: \ -+ ERROR truncating meta file.\n"); -+ goto out_err_close; -+ } -+ } -+ -+ /* open META-file for writing */ -+ meta_file = dentry_open(meta_dentry, meta_mnt, 0x1); -+ if(!meta_file || IS_ERR(meta_file)) { -+ printk(KERN_CRIT "mini_fo: meta_sync_r_list: \ -+ ERROR opening meta file.\n"); -+ /* we don't mntget so we dont't mntput (for now) -+ * mntput(meta_mnt); -+ */ -+ dput(meta_dentry); -+ err = -1; -+ goto out; -+ } -+ -+ /* check if fs supports writing */ -+ if(!meta_file->f_op->write) { -+ printk(KERN_CRIT "mini_fo: meta_sync_r_list: \ -+ ERROR, fs does not support writing.\n"); -+ goto out_err_close; -+ } -+ -+ meta_file->f_pos = meta_dentry->d_inode->i_size; /* append */ -+ old_fs = get_fs(); -+ set_fs(KERNEL_DS); -+ -+ /* here we go... */ -+ list_for_each(tmp, &inode_info->renamed_list) { -+ ren_entry = list_entry(tmp, struct renamed_entry, list); -+ /* size: -+ * 2 for "R ", old_len+new_len for names, 1 blank+1 \n */ -+ buf_len = ren_entry->old_len + ren_entry->new_len + 4; -+ buf = (char *) kmalloc(buf_len, GFP_KERNEL); -+ if (!buf) { -+ printk(KERN_CRIT "mini_fo: meta_sync_r_list: \ -+ out of mem.\n"); -+ return -ENOMEM; -+ } -+ buf[0] = 'R'; -+ buf[1] = ' '; -+ strncpy(buf + 2, ren_entry->old_name, ren_entry->old_len); -+ buf[ren_entry->old_len + 2] = ' '; -+ strncpy(buf + ren_entry->old_len + 3, -+ ren_entry->new_name, ren_entry->new_len); -+ buf[buf_len - 1] = '\n'; -+ bytes = meta_file->f_op->write(meta_file, buf, -+ buf_len, &meta_file->f_pos); -+ if(bytes != buf_len) { -+ printk(KERN_CRIT "mini_fo: meta_sync_r_list: \ -+ ERROR writing.\n"); -+ err |= -1; -+ } -+ kfree(buf); -+ } -+ set_fs(old_fs); -+ -+ out_err_close: -+ fput(meta_file); -+ out: -+ return err; -+} -+ -+int meta_check_d_entry(dentry_t *dentry, const char *name, int len) -+{ -+ if(!dentry || !dentry->d_inode) -+ printk(KERN_CRIT "mini_fo: meta_check_d_dentry: \ -+ invalid dentry passed.\n"); -+ return __meta_check_d_entry(dentry->d_inode, name, len); -+} -+ -+int __meta_check_d_entry(inode_t *inode, const char *name, int len) -+{ -+ struct list_head *tmp; -+ struct deleted_entry *del_entry; -+ struct mini_fo_inode_info *inode_info; -+ -+ if(!inode || !itopd(inode)) -+ printk(KERN_CRIT "mini_fo: __meta_check_d_dentry: \ -+ invalid inode passed.\n"); -+ -+ inode_info = itopd(inode); -+ -+ if(inode_info->deleted_list_size <= 0) -+ return 0; -+ -+ list_for_each(tmp, &inode_info->deleted_list) { -+ del_entry = list_entry(tmp, struct deleted_entry, list); -+ if(del_entry->len != len) -+ continue; -+ -+ if(!strncmp(del_entry->name, name, len)) -+ return 1; -+ } -+ return 0; -+} -+ -+/* -+ * check if file has been renamed and return path to orig. base dir. -+ * Implements no error return values so far, what of course sucks. -+ * String is null terminated.' -+ */ -+char* meta_check_r_entry(dentry_t *dentry, const char *name, int len) -+{ -+ if(!dentry || !dentry->d_inode) { -+ printk(KERN_CRIT "mini_fo: meta_check_r_dentry: \ -+ invalid dentry passed.\n"); -+ return NULL; -+ } -+ return __meta_check_r_entry(dentry->d_inode, name, len); -+} -+ -+char* __meta_check_r_entry(inode_t *inode, const char *name, int len) -+{ -+ struct list_head *tmp; -+ struct renamed_entry *ren_entry; -+ struct mini_fo_inode_info *inode_info; -+ char *old_path; -+ -+ if(!inode || !itopd(inode)) { -+ printk(KERN_CRIT "mini_fo: meta_check_r_dentry: \ -+ invalid inode passed.\n"); -+ return NULL; -+ } -+ inode_info = itopd(inode); -+ -+ if(inode_info->renamed_list_size <= 0) -+ return NULL; -+ -+ list_for_each(tmp, &inode_info->renamed_list) { -+ ren_entry = list_entry(tmp, struct renamed_entry, list); -+ if(ren_entry->new_len != len) -+ continue; -+ -+ if(!strncmp(ren_entry->new_name, name, len)) { -+ old_path = (char *) -+ kmalloc(ren_entry->old_len+1, GFP_KERNEL); -+ strncpy(old_path, -+ ren_entry->old_name, -+ ren_entry->old_len); -+ old_path[ren_entry->old_len]='\0'; -+ return old_path; -+ } -+ } -+ return NULL; -+} -+ -+/* -+ * This version only checks if entry exists and return: -+ * 1 if exists, -+ * 0 if not, -+ * -1 if error. -+ */ -+int meta_is_r_entry(dentry_t *dentry, const char *name, int len) -+{ -+ if(!dentry || !dentry->d_inode) { -+ printk(KERN_CRIT "mini_fo: meta_check_r_dentry [2]: \ -+ invalid dentry passed.\n"); -+ return -1; -+ } -+ return __meta_is_r_entry(dentry->d_inode, name, len); -+} -+ -+int __meta_is_r_entry(inode_t *inode, const char *name, int len) -+{ -+ struct list_head *tmp; -+ struct renamed_entry *ren_entry; -+ struct mini_fo_inode_info *inode_info; -+ -+ if(!inode || !itopd(inode)) { -+ printk(KERN_CRIT "mini_fo: meta_check_r_dentry [2]: \ -+ invalid inode passed.\n"); -+ return -1; -+ } -+ inode_info = itopd(inode); -+ -+ if(inode_info->renamed_list_size <= 0) -+ return -1; -+ -+ list_for_each(tmp, &inode_info->renamed_list) { -+ ren_entry = list_entry(tmp, struct renamed_entry, list); -+ if(ren_entry->new_len != len) -+ continue; -+ -+ if(!strncmp(ren_entry->new_name, name, len)) -+ return 1; -+ } -+ return 0; -+} -+ ---- /dev/null -+++ b/fs/mini_fo/mini_fo.h -@@ -0,0 +1,510 @@ -+/* -+ * Copyright (c) 1997-2003 Erez Zadok -+ * Copyright (c) 2001-2003 Stony Brook University -+ * -+ * For specific licensing information, see the COPYING file distributed with -+ * this package, or get one from ftp://ftp.filesystems.org/pub/fist/COPYING. -+ * -+ * This Copyright notice must be kept intact and distributed with all -+ * fistgen sources INCLUDING sources generated by fistgen. -+ */ -+/* -+ * Copyright (C) 2004, 2005 Markus Klotzbuecher -+ * -+ * 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. -+ */ -+ -+/* -+ * $Id$ -+ */ -+ -+#ifndef __MINI_FO_H_ -+#define __MINI_FO_H_ -+ -+#ifdef __KERNEL__ -+ -+/* META stuff */ -+#define META_FILENAME "META_dAfFgHE39ktF3HD2sr" -+ -+/* use xattrs? */ -+#define XATTR -+ -+/* File attributes that when changed, result in a file beeing copied to storage */ -+#define COPY_FLAGS ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_SIZE -+ -+/* -+ * mini_fo filestates -+ */ -+#define MODIFIED 1 -+#define UNMODIFIED 2 -+#define CREATED 3 -+#define DEL_REWRITTEN 4 -+#define DELETED 5 -+#define NON_EXISTANT 6 -+ -+/* fist file systems superblock magic */ -+# define MINI_FO_SUPER_MAGIC 0xf15f -+ -+/* -+ * STRUCTURES: -+ */ -+ -+/* mini_fo inode data in memory */ -+struct mini_fo_inode_info { -+ inode_t *wii_inode; -+ inode_t *wii_inode2; /* pointer to storage inode */ -+ -+ /* META-data lists */ -+ /* deleted list, ex wol */ -+ struct list_head deleted_list; -+ int deleted_list_size; -+ -+ /* renamed list */ -+ struct list_head renamed_list; -+ int renamed_list_size; -+ -+ /* add other lists here ... */ -+}; -+ -+/* mini_fo dentry data in memory */ -+struct mini_fo_dentry_info { -+ dentry_t *wdi_dentry; -+ dentry_t *wdi_dentry2; /* pointer to storage dentry */ -+ unsigned int state; /* state of the mini_fo dentry */ -+}; -+ -+ -+/* mini_fo super-block data in memory */ -+struct mini_fo_sb_info { -+ super_block_t *wsi_sb, *wsi_sb2; /* mk: might point to the same sb */ -+ struct vfsmount *hidden_mnt, *hidden_mnt2; -+ dentry_t *base_dir_dentry; -+ dentry_t *storage_dir_dentry; -+ ; -+}; -+ -+/* readdir_data, readdir helper struct */ -+struct readdir_data { -+ struct list_head ndl_list; /* linked list head ptr */ -+ int ndl_size; /* list size */ -+ int sto_done; /* flag to show that the storage dir entries have -+ * all been read an now follow base entries */ -+}; -+ -+/* file private data. */ -+struct mini_fo_file_info { -+ struct file *wfi_file; -+ struct file *wfi_file2; /* pointer to storage file */ -+ struct readdir_data rd; -+}; -+ -+/* struct ndl_entry */ -+struct ndl_entry { -+ struct list_head list; -+ char *name; -+ int len; -+}; -+ -+/******************************** -+ * META-data structures -+ ********************************/ -+ -+/* deleted entry */ -+struct deleted_entry { -+ struct list_head list; -+ char *name; -+ int len; -+}; -+ -+/* renamed entry */ -+struct renamed_entry { -+ struct list_head list; -+ char *old_name; /* old directory with full path */ -+ int old_len; /* length of above string */ -+ char *new_name; /* new directory name */ -+ int new_len; /* length of above string */ -+}; -+ -+/* attr_change entry */ -+struct attr_change_entry { -+ struct list_head list; -+ char *name; -+ int len; -+}; -+ -+/* link entry */ -+struct link_entry { -+ struct list_head list; -+ int links_moved; -+ int inum_base; -+ int inum_sto; -+ char *weird_name; -+ int weird_name_len; -+}; -+ -+ -+/* Some other stuff required for mini_fo_filldir64, copied from -+ * fs/readdir.c -+ */ -+ -+#define ROUND_UP64(x) (((x)+sizeof(u64)-1) & ~(sizeof(u64)-1)) -+#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de))) -+ -+ -+struct linux_dirent64 { -+ u64 d_ino; -+ s64 d_off; -+ unsigned short d_reclen; -+ unsigned char d_type; -+ char d_name[0]; -+}; -+ -+ -+struct getdents_callback64 { -+ struct linux_dirent64 * current_dir; -+ struct linux_dirent64 * previous; -+ int count; -+ int error; -+}; -+ -+struct linux_dirent { -+ unsigned long d_ino; -+ unsigned long d_off; -+ unsigned short d_reclen; -+ char d_name[1]; -+}; -+ -+struct getdents_callback { -+ struct linux_dirent * current_dir; -+ struct linux_dirent * previous; -+ int count; -+ int error; -+}; -+ -+ -+/* -+ * MACROS: -+ */ -+ -+/* file TO private_data */ -+# define ftopd(file) ((struct mini_fo_file_info *)((file)->private_data)) -+# define __ftopd(file) ((file)->private_data) -+/* file TO hidden_file */ -+# define ftohf(file) ((ftopd(file))->wfi_file) -+# define ftohf2(file) ((ftopd(file))->wfi_file2) -+ -+/* inode TO private_data */ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) -+# define itopd(ino) ((struct mini_fo_inode_info *)(ino)->i_private) -+# define __itopd(ino) ((ino)->i_private) -+#else -+# define itopd(ino) ((struct mini_fo_inode_info *)(ino)->u.generic_ip) -+# define __itopd(ino) ((ino)->u.generic_ip) -+#endif -+/* inode TO hidden_inode */ -+# define itohi(ino) (itopd(ino)->wii_inode) -+# define itohi2(ino) (itopd(ino)->wii_inode2) -+ -+/* superblock TO private_data */ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -+# define stopd(super) ((struct mini_fo_sb_info *)(super)->s_fs_info) -+# define __stopd(super) ((super)->s_fs_info) -+#else -+# define stopd(super) ((struct mini_fo_sb_info *)(super)->u.generic_sbp) -+# define __stopd(super) ((super)->u.generic_sbp) -+#endif -+ -+/* unused? # define vfs2priv stopd */ -+/* superblock TO hidden_superblock */ -+ -+# define stohs(super) (stopd(super)->wsi_sb) -+# define stohs2(super) (stopd(super)->wsi_sb2) -+ -+/* dentry TO private_data */ -+# define dtopd(dentry) ((struct mini_fo_dentry_info *)(dentry)->d_fsdata) -+# define __dtopd(dentry) ((dentry)->d_fsdata) -+/* dentry TO hidden_dentry */ -+# define dtohd(dent) (dtopd(dent)->wdi_dentry) -+# define dtohd2(dent) (dtopd(dent)->wdi_dentry2) -+ -+/* dentry to state */ -+# define dtost(dent) (dtopd(dent)->state) -+# define sbt(sb) ((sb)->s_type->name) -+ -+#define IS_WRITE_FLAG(flag) (flag & (O_RDWR | O_WRONLY | O_APPEND)) -+#define IS_COPY_FLAG(flag) (flag & (COPY_FLAGS)) -+ -+/* macros to simplify non-SCA code */ -+# define MALLOC_PAGE_POINTERS(hidden_pages, num_hidden_pages) -+# define MALLOC_PAGEDATA_POINTERS(hidden_pages_data, num_hidden_pages) -+# define FREE_PAGE_POINTERS(hidden_pages, num) -+# define FREE_PAGEDATA_POINTERS(hidden_pages_data, num) -+# define FOR_EACH_PAGE -+# define CURRENT_HIDDEN_PAGE hidden_page -+# define CURRENT_HIDDEN_PAGEDATA hidden_page_data -+# define CURRENT_HIDDEN_PAGEINDEX page->index -+ -+/* -+ * EXTERNALS: -+ */ -+extern struct file_operations mini_fo_main_fops; -+extern struct file_operations mini_fo_dir_fops; -+extern struct inode_operations mini_fo_main_iops; -+extern struct inode_operations mini_fo_dir_iops; -+extern struct inode_operations mini_fo_symlink_iops; -+extern struct super_operations mini_fo_sops; -+extern struct dentry_operations mini_fo_dops; -+extern struct vm_operations_struct mini_fo_shared_vmops; -+extern struct vm_operations_struct mini_fo_private_vmops; -+extern struct address_space_operations mini_fo_aops; -+ -+#if 0 /* unused by mini_fo */ -+extern int mini_fo_interpose(dentry_t *hidden_dentry, dentry_t *this_dentry, super_block_t *sb, int flag); -+#if defined(FIST_FILTER_DATA) || defined(FIST_FILTER_SCA) -+extern page_t *mini_fo_get1page(file_t *file, int index); -+extern int mini_fo_fill_zeros(file_t *file, page_t *page, unsigned from); -+# endif /* FIST_FILTER_DATA || FIST_FILTER_SCA */ -+ -+ -+# define mini_fo_hidden_dentry(d) __mini_fo_hidden_dentry(__FILE__,__FUNCTION__,__LINE__,(d)) -+# define mini_fo_hidden_sto_dentry(d) __mini_fo_hidden_sto_dentry(__FILE__,__FUNCTION__,__LINE__,(d)) -+ -+extern dentry_t *__mini_fo_hidden_dentry(char *file, char *func, int line, dentry_t *this_dentry); -+extern dentry_t *__mini_fo_hidden_sto_dentry(char *file, char *func, int line, dentry_t *this_dentry); -+ -+extern int mini_fo_read_file(const char *filename, void *buf, int len); -+extern int mini_fo_write_file(const char *filename, void *buf, int len); -+extern dentry_t *fist_lookup(dentry_t *dir, const char *name, vnode_t **out, uid_t uid, gid_t gid); -+#endif /* unused by mini_fo */ -+ -+/* state transition functions */ -+extern int nondir_unmod_to_mod(dentry_t *dentry, int cp_flag); -+extern int nondir_del_rew_to_del(dentry_t *dentry); -+extern int nondir_creat_to_del(dentry_t *dentry); -+extern int nondir_mod_to_del(dentry_t *dentry); -+extern int nondir_unmod_to_del(dentry_t *dentry); -+ -+extern int dir_unmod_to_mod(dentry_t *dentry); -+ -+/* rename specials */ -+extern int rename_directory(inode_t *old_dir, dentry_t *old_dentry, inode_t *new_dir, dentry_t *new_dentry); -+extern int rename_nondir(inode_t *old_dir, dentry_t *old_dentry, inode_t *new_dir, dentry_t *new_dentry); -+ -+/* misc stuff */ -+extern int mini_fo_tri_interpose(dentry_t *hidden_dentry, -+ dentry_t *hidden_sto_dentry, -+ dentry_t *dentry, -+ super_block_t *sb, int flag); -+ -+extern int mini_fo_cp_cont(dentry_t *tgt_dentry, struct vfsmount *tgt_mnt, -+ dentry_t *src_dentry, struct vfsmount *src_mnt); -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -+extern int mini_fo_create(inode_t *dir, dentry_t *dentry, int mode, struct nameidata *nd); -+ -+extern int create_sto_nod(dentry_t *dentry, int mode, dev_t dev); -+extern int create_sto_reg_file(dentry_t *dentry, int mode, struct nameidata *nd); -+#else -+extern int mini_fo_create(inode_t *dir, dentry_t *dentry, int mode); -+ -+extern int create_sto_nod(dentry_t *dentry, int mode, int dev); -+extern int create_sto_reg_file(dentry_t *dentry, int mode); -+#endif -+ -+extern int create_sto_dir(dentry_t *dentry, int mode); -+ -+extern int exists_in_storage(dentry_t *dentry); -+extern int is_mini_fo_existant(dentry_t *dentry); -+extern int get_neg_sto_dentry(dentry_t *dentry); -+extern int build_sto_structure(dentry_t *dir, dentry_t *dentry); -+extern int get_mini_fo_bpath(dentry_t *dentry, char **bpath, int *bpath_len); -+extern dentry_t *bpath_walk(super_block_t *sb, char *bpath); -+extern int bpath_put(dentry_t *dentry); -+ -+/* check_mini_fo types functions */ -+extern int check_mini_fo_dentry(dentry_t *dentry); -+extern int check_mini_fo_file(file_t *file); -+extern int check_mini_fo_inode(inode_t *inode); -+ -+/* General meta functions, can be called from outside of meta.c */ -+extern int meta_build_lists(dentry_t *dentry); -+extern int meta_put_lists(dentry_t *dentry); -+extern int __meta_put_lists(inode_t *inode); -+ -+extern int meta_add_d_entry(dentry_t *dentry, const char *name, int len); -+extern int meta_add_r_entry(dentry_t *dentry, -+ const char *old_name, int old_len, -+ const char *new_name, int new_len); -+ -+extern int meta_remove_r_entry(dentry_t *dentry, const char *name, int len); -+ -+extern int meta_check_d_entry(dentry_t *dentry, const char *name, int len); -+extern int __meta_check_d_entry(inode_t *inode, const char *name, int len); -+ -+extern char* meta_check_r_entry(dentry_t *dentry, const char *name, int len); -+extern char* __meta_check_r_entry(inode_t *inode, const char *name, int len); -+extern int meta_is_r_entry(dentry_t *dentry, const char *name, int len); -+extern int __meta_is_r_entry(inode_t *inode, const char *name, int len); -+ -+/* Specific meta functions, should be called only inside meta.c */ -+extern int __meta_put_d_list(inode_t *inode); -+extern int __meta_put_r_list(inode_t *inode); -+ -+extern int meta_list_add_d_entry(dentry_t *dentry, -+ const char *name, int len); -+extern int meta_list_add_r_entry(dentry_t *dentry, -+ const char *old_name, int old_len, -+ const char *new_name, int new_len); -+ -+extern int meta_list_remove_r_entry(dentry_t *dentry, -+ const char *name, int len); -+ -+extern int __meta_list_remove_r_entry(inode_t *inode, -+ const char *name, int len); -+ -+extern int meta_write_d_entry(dentry_t *dentry, const char *name, int len); -+extern int meta_write_r_entry(dentry_t *dentry, -+ const char *old_name, int old_len, -+ const char *new_name, int new_len); -+ -+extern int meta_sync_lists(dentry_t *dentry); -+extern int meta_sync_d_list(dentry_t *dentry, int app_flag); -+extern int meta_sync_r_list(dentry_t *dentry, int app_flag); -+ -+/* ndl stuff */ -+extern int ndl_add_entry(struct readdir_data *rd, const char *name, int len); -+extern void ndl_put_list(struct readdir_data *rd); -+extern int ndl_check_entry(struct readdir_data *rd, -+ const char *name, int len); -+ -+ -+# define copy_inode_size(dst, src) \ -+ dst->i_size = src->i_size; \ -+ dst->i_blocks = src->i_blocks; -+ -+static inline void -+fist_copy_attr_atime(inode_t *dest, const inode_t *src) -+{ -+ ASSERT(dest != NULL); -+ ASSERT(src != NULL); -+ dest->i_atime = src->i_atime; -+} -+static inline void -+fist_copy_attr_times(inode_t *dest, const inode_t *src) -+{ -+ ASSERT(dest != NULL); -+ ASSERT(src != NULL); -+ dest->i_atime = src->i_atime; -+ dest->i_mtime = src->i_mtime; -+ dest->i_ctime = src->i_ctime; -+} -+static inline void -+fist_copy_attr_timesizes(inode_t *dest, const inode_t *src) -+{ -+ ASSERT(dest != NULL); -+ ASSERT(src != NULL); -+ dest->i_atime = src->i_atime; -+ dest->i_mtime = src->i_mtime; -+ dest->i_ctime = src->i_ctime; -+ copy_inode_size(dest, src); -+} -+static inline void -+fist_copy_attr_all(inode_t *dest, const inode_t *src) -+{ -+ ASSERT(dest != NULL); -+ ASSERT(src != NULL); -+ dest->i_mode = src->i_mode; -+ dest->i_nlink = src->i_nlink; -+ dest->i_uid = src->i_uid; -+ dest->i_gid = src->i_gid; -+ dest->i_rdev = src->i_rdev; -+ dest->i_atime = src->i_atime; -+ dest->i_mtime = src->i_mtime; -+ dest->i_ctime = src->i_ctime; -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) -+ dest->i_blksize = src->i_blksize; -+#endif -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,12) -+ dest->i_blkbits = src->i_blkbits; -+# endif /* linux 2.4.12 and newer */ -+ copy_inode_size(dest, src); -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) -+ dest->i_attr_flags = src->i_attr_flags; -+#else -+ dest->i_flags = src->i_flags; -+#endif -+} -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -+/* copied from linux/fs.h */ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) -+static inline void double_lock(struct dentry *d1, struct dentry *d2) -+{ -+ struct mutex *m1 = &d1->d_inode->i_mutex; -+ struct mutex *m2 = &d2->d_inode->i_mutex; -+ if (m1 != m2) { -+ if ((unsigned long) m1 < (unsigned long) m2) { -+ struct mutex *tmp = m2; -+ m2 = m1; m1 = tmp; -+ } -+ mutex_lock(m1); -+ } -+ mutex_lock(m2); -+} -+ -+static inline void double_unlock(struct dentry *d1, struct dentry *d2) -+{ -+ struct mutex *m1 = &d1->d_inode->i_mutex; -+ struct mutex *m2 = &d2->d_inode->i_mutex; -+ mutex_unlock(m1); -+ if (m1 != m2) -+ mutex_unlock(m2); -+ dput(d1); -+ dput(d2); -+} -+ -+#else -+static inline void double_down(struct semaphore *s1, struct semaphore *s2) -+{ -+ if (s1 != s2) { -+ if ((unsigned long) s1 < (unsigned long) s2) { -+ struct semaphore *tmp = s2; -+ s2 = s1; s1 = tmp; -+ } -+ down(s1); -+ } -+ down(s2); -+} -+ -+static inline void double_up(struct semaphore *s1, struct semaphore *s2) -+{ -+ up(s1); -+ if (s1 != s2) -+ up(s2); -+} -+ -+static inline void double_lock(struct dentry *d1, struct dentry *d2) -+{ -+ double_down(&d1->d_inode->i_sem, &d2->d_inode->i_sem); -+} -+ -+static inline void double_unlock(struct dentry *d1, struct dentry *d2) -+{ -+ double_up(&d1->d_inode->i_sem,&d2->d_inode->i_sem); -+ dput(d1); -+ dput(d2); -+} -+#endif /* if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) */ -+#endif /* if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) */ -+#endif /* __KERNEL__ */ -+ -+/* -+ * Definitions for user and kernel code -+ */ -+ -+/* ioctls */ -+ -+#endif /* not __MINI_FO_H_ */ ---- /dev/null -+++ b/fs/mini_fo/mini_fo-merge -@@ -0,0 +1,180 @@ -+#!/bin/bash -+# -+# Copyright (C) 2005 Markus Klotzbuecher -+# 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. -+# -+ -+BASE= -+STO= -+HELP= -+DRYRUN= -+VERBOSE= -+TMP="/tmp/" -+META_NAME="META_dAfFgHE39ktF3HD2sr" -+SKIP_DEL_LIST="skip-delete-list.mini_fo-merge" -+ -+COMMAND= -+exec_command() -+{ -+ if [ x$DRYRUN == "xset" ]; then -+ echo " would run: $COMMAND" -+ elif ! [ x$DRYRUN == "xset" ]; then -+ if [ x$VERBOSE == "xset" ]; then -+ echo " running: $COMMAND" -+ fi -+ eval $COMMAND -+ fi -+} -+ -+usage() -+{ -+cat < -s -+Version 0.1 -+ -+This script merges the contents of a mini_fo storage file system back -+to the base file system. -+ -+!!! Warning: This will modify the base filesystem and can destroy data -+ if used wrongly. -+ -+Options: -+ -b -+ the directory of the base file system. -+ -+ -s -+ the directory of the storage file system. -+ -+ -d dry run, will not change anything and print the commands that -+ would be executed. -+ -+ -t tmp dir for storing temporary file. default: $TMP -+ -+ -v show what operations are performed. -+ -+ -h displays this message. -+ -+EOF -+} -+ -+# parse parameters -+while getopts hdvt:b:s: OPTS -+ do -+ case $OPTS in -+ h) HELP="set";; -+ d) DRYRUN="set";; -+ v) VERBOSE="set";; -+ b) BASE="$OPTARG";; -+ s) STO="$OPTARG";; -+ t) TMP="$OPTARG";; -+ ?) usage -+ exit 1;; -+ esac -+done -+ -+if [ "x$HELP" == "xset" ]; then -+ usage -+ exit -1 -+fi -+ -+if ! [ -d "$BASE" ] || ! [ -d "$STO" ]; then -+ echo -e "$0:\n Error, -s and/or -b argument missing. type $0 -h for help." -+ exit -1; -+fi -+ -+# get full paths -+pushd $STO; STO=`pwd`; popd -+pushd $BASE; BASE=`pwd`; popd -+TMP=${TMP%/} -+ -+ -+cat< /dev/null -+find . -name $META_NAME -type f -print0 | xargs -0 -e grep -e '^R ' | tr -s ':R' ' ' | while read ENTRY; do -+ echo "entry: $ENTRY" -+ META_FILE=`echo $ENTRY | cut -d ' ' -f 1` -+ OLD_B_DIR=`echo $ENTRY | cut -d ' ' -f 2 | sed -e 's/\///'` -+ NEW_NAME=`echo $ENTRY | cut -d ' ' -f 3` -+ NEW_B_DIR=`echo $META_FILE | sed -e "s/$META_NAME/$NEW_NAME/" | sed -e 's/^\.\///'` -+ echo "META_FILE: $META_FILE" -+ echo "OLD_B_DIR: $OLD_B_DIR" -+ echo "NEW_NAME: $NEW_NAME" -+ echo "NEW_B_DIR: $NEW_B_DIR" -+ -+ pushd $BASE &> /dev/null -+ # remove an existing dir in storage -+ COMMAND="rm -rf $NEW_B_DIR"; exec_command -+ COMMAND="cp -R $OLD_B_DIR $NEW_B_DIR"; exec_command -+ echo "" -+ popd &> /dev/null -+ -+ # remember this dir to exclude it from deleting later -+ echo $NEW_B_DIR >> $TMP/$SKIP_DEL_LIST -+done -+ -+# delete all whiteouted files from base -+echo -e "\nDeleting whiteout'ed files from base file system..." -+find . -name $META_NAME -type f -print0 | xargs -0 -e grep -e '^D ' | sed -e 's/:D//' | while read ENTRY; do -+ META_FILE=`echo $ENTRY | cut -d ' ' -f 1` -+ DEL_NAME=`echo $ENTRY | cut -d ' ' -f 2` -+ DEL_FILE=`echo $META_FILE | sed -e "s/$META_NAME/$DEL_NAME/" | sed -e 's/^\.\///'` -+ grep -x $DEL_FILE $TMP/$SKIP_DEL_LIST &> /dev/null -+ if [ $? -ne 0 ]; then -+ pushd $BASE &> /dev/null -+ COMMAND="rm -rf $DEL_FILE"; exec_command -+ popd &> /dev/null -+ else -+ echo " excluding: $DEL_FILE as in skip-del-list." -+ fi -+done -+ -+# create all dirs and update permissions -+echo -e "\nSetting up directory structures in base file system..." -+find . -type d | sed -e 's/^\.\///' | while read DIR; do -+ PERMS=`stat -c %a $DIR` -+ DIR_UID=`stat -c %u $DIR` -+ DIR_GID=`stat -c %g $DIR` -+ pushd $BASE &> /dev/null -+ if ! [ -d $DIR ]; then -+ COMMAND="mkdir -p $DIR"; exec_command -+ fi -+ COMMAND="chmod $PERMS $DIR"; exec_command -+ COMMAND="chown $DIR_UID:$DIR_GID $DIR"; exec_command -+ popd &> /dev/null -+done -+ -+# merge all non-directory files -+echo -e "\nMerging all non-directory files...." -+for i in b c p f l s; do -+ find . -type $i | sed -e 's/^\.\///' | grep -v "$META_NAME" | while read FILE; do -+ pushd $BASE #&> /dev/null -+ COMMAND="cp -df $STO/$FILE $BASE/$FILE"; exec_command -+ popd &> /dev/null -+ done -+done -+popd &> /dev/null -+ -+#rm $TMP/$SKIP_DEL_LIST -+ -+echo "Done!" ---- /dev/null -+++ b/fs/mini_fo/mini_fo-overlay -@@ -0,0 +1,130 @@ -+#!/bin/bash -+# -+# Copyright (C) 2005 Markus Klotzbuecher -+# 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. -+# -+ -+HELP= -+SUFF= -+MNTP= -+MNT_DIR="/mnt" -+STO= -+STO_DIR="/tmp" -+BASE= -+ -+usage() -+{ -+cat <" in $STO_DIR, -+and mount point "mini_fo-" in $MNT_DIR. -+ -+Options: -+ -s -+ add given suffix to storage directory and the mount -+ point. This is usefull for overlaying one base directory -+ several times and avoiding conflicts with storage directory -+ names and mount points. -+ -+ -d -+ change the directory in which the storage directory will be -+ created (default is currently "$STO_DIR". -+ -+ -m -+ use an alternative directory to create the mini_fo -+ mountpoint (default is currently "$MNT_DIR". -+ -+ -h displays this message. -+ -+EOF -+exit 1; -+} -+ -+while getopts hm:s:d: OPTS -+ do -+ case $OPTS in -+ s) SUFF="$OPTARG";; -+ d) STO_DIR="$OPTARG";; -+ m) MNT_DIR="$OPTARG";; -+ h) HELP="set";; -+ ?) usage -+ exit 1;; -+ esac -+done -+shift $(($OPTIND - 1)) -+ -+BASE="$1" -+ -+if [ "x$HELP" == "xset" ]; then -+ usage -+ exit -1 -+fi -+ -+# fix suffix -+if [ "x$SUFF" != "x" ]; then -+ SUFF="-$SUFF" -+fi -+ -+# kill trailing slashes -+MNT_DIR=${MNT_DIR%/} -+STO_DIR=${STO_DIR%/} -+BASE=${BASE%/} -+ -+ -+if ! [ -d "$BASE" ]; then -+ echo "invalid base dir $BASE, run $0 -h for help." -+ exit -1 -+fi -+ -+# check opts -+if ! [ -d "$MNT_DIR" ]; then -+ echo "invalid mount dir $MNT_DIR, run $0 -h for help." -+ exit -1 -+fi -+ -+if ! [ -d "$STO_DIR" ]; then -+ echo "invalid sto_dir_dir $STO_DIR, run $0 -h for help." -+ exit -1 -+fi -+ -+MNTP="$MNT_DIR/mini_fo-`basename $BASE`$SUFF" -+STO="$STO_DIR/sto-`basename $BASE`$SUFF" -+ -+# create the mount point if it doesn't exist -+mkdir -p $MNTP -+if [ $? -ne 0 ]; then -+ echo "Error, failed to create mount point $MNTP" -+fi -+ -+mkdir -p $STO -+if [ $? -ne 0 ]; then -+ echo "Error, failed to create storage dir $STO" -+fi -+ -+# check if fs is already mounted -+mount | grep mini_fo | grep $MNTP &> /dev/null -+if [ $? -eq 0 ]; then -+ echo "Error, existing mini_fo mount at $MNTP." -+ exit -1 -+fi -+ -+mount | grep mini_fo | grep $STO &> /dev/null -+if [ $? -eq 0 ]; then -+ echo "Error, $STO seems to be used already." -+ exit -1 -+fi -+ -+# mount -+mount -t mini_fo -o base=$BASE,sto=$STO $BASE $MNTP -+ -+if [ $? -ne 0 ]; then -+ echo "Error, mounting failed, maybe no permisson to mount?" -+fi ---- /dev/null -+++ b/fs/mini_fo/mmap.c -@@ -0,0 +1,637 @@ -+/* -+ * Copyright (c) 1997-2003 Erez Zadok -+ * Copyright (c) 2001-2003 Stony Brook University -+ * -+ * For specific licensing information, see the COPYING file distributed with -+ * this package, or get one from ftp://ftp.filesystems.org/pub/fist/COPYING. -+ * -+ * This Copyright notice must be kept intact and distributed with all -+ * fistgen sources INCLUDING sources generated by fistgen. -+ */ -+/* -+ * Copyright (C) 2004, 2005 Markus Klotzbuecher -+ * -+ * 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. -+ */ -+ -+/* -+ * $Id$ -+ */ -+ -+#ifdef HAVE_CONFIG_H -+# include -+#endif /* HAVE_CONFIG_H */ -+ -+#include "fist.h" -+#include "mini_fo.h" -+ -+ -+#ifdef FIST_COUNT_WRITES -+/* for counting writes in the middle vs. regular writes */ -+unsigned long count_writes = 0, count_writes_middle = 0; -+#endif /* FIST_COUNT_WRITES */ -+ -+/* forward declaration of commit write and prepare write */ -+STATIC int mini_fo_commit_write(file_t *file, page_t *page, unsigned from, unsigned to); -+STATIC int mini_fo_prepare_write(file_t *file, page_t *page, unsigned from, unsigned to); -+ -+ -+/* -+ * Function for handling creation of holes when lseek-ing past the -+ * end of the file and then writing some data. -+ */ -+int -+mini_fo_fill_zeros(file_t* file, page_t *page, unsigned from) -+{ -+ int err = 0; -+ dentry_t *dentry = file->f_dentry; -+ inode_t *inode = dentry->d_inode; -+ page_t *tmp_page; -+ int index; -+ -+ print_entry_location(); -+ -+ for (index = inode->i_size >> PAGE_CACHE_SHIFT; index < page->index; index++) { -+ tmp_page = mini_fo_get1page(file, index); -+ if (IS_ERR(tmp_page)) { -+ err = PTR_ERR(tmp_page); -+ goto out; -+ } -+ -+ /* -+ * zero out rest of the contents of the page between the appropriate -+ * offsets. -+ */ -+ memset((char*)page_address(tmp_page) + (inode->i_size & ~PAGE_CACHE_MASK), 0, PAGE_CACHE_SIZE - (inode->i_size & ~PAGE_CACHE_MASK)); -+ -+ if (! (err = mini_fo_prepare_write(file, tmp_page, 0, PAGE_CACHE_SIZE))) -+ err = mini_fo_commit_write(file, tmp_page, 0, PAGE_CACHE_SIZE); -+ -+ page_cache_release(tmp_page); -+ if (err < 0) -+ goto out; -+ if (current->need_resched) -+ schedule(); -+ } -+ -+ /* zero out appropriate parts of last page */ -+ -+ /* -+ * if the encoding type is block, then adjust the 'from' (where the -+ * zeroing will start) offset appropriately -+ */ -+ from = from & (~(FIST_ENCODING_BLOCKSIZE - 1)); -+ -+ if ((from - (inode->i_size & ~PAGE_CACHE_MASK)) > 0) { -+ -+ memset((char*)page_address(page) + (inode->i_size & ~PAGE_CACHE_MASK), 0, from - (inode->i_size & ~PAGE_CACHE_MASK)); -+ if (! (err = mini_fo_prepare_write(file, page, 0, PAGE_CACHE_SIZE))) -+ err = mini_fo_commit_write(file, page, 0, PAGE_CACHE_SIZE); -+ -+ if (err < 0) -+ goto out; -+ if (current->need_resched) -+ schedule(); -+ } -+ -+ out: -+ print_exit_status(err); -+ return err; -+} -+ -+ -+ -+STATIC int -+mini_fo_writepage(page_t *page) -+{ -+ int err = -EIO; -+ inode_t *inode; -+ inode_t *hidden_inode; -+ page_t *hidden_page; -+ char *kaddr, *hidden_kaddr; -+ -+ print_entry_location(); -+ -+ inode = page->mapping->host; -+ hidden_inode = itohi(inode); -+ -+ /* -+ * writepage is called when shared mmap'ed files need to write -+ * their pages, while prepare/commit_write are called from the -+ * non-paged write() interface. (However, in 2.3 the two interfaces -+ * share the same cache, while in 2.2 they didn't.) -+ * -+ * So we pretty much have to duplicate much of what commit_write does. -+ */ -+ -+ /* find lower page (returns a locked page) */ -+ hidden_page = grab_cache_page(hidden_inode->i_mapping, page->index); -+ if (!hidden_page) -+ goto out; -+ -+ /* get page address, and encode it */ -+ kaddr = (char *) kmap(page); -+ hidden_kaddr = (char*) kmap(hidden_page); -+ mini_fo_encode_block(kaddr, hidden_kaddr, PAGE_CACHE_SIZE, inode, inode->i_sb, page->index); -+ /* if encode_block could fail, then return error */ -+ kunmap(page); -+ kunmap(hidden_page); -+ -+ /* call lower writepage (expects locked page) */ -+ err = hidden_inode->i_mapping->a_ops->writepage(hidden_page); -+ -+ /* -+ * update mtime and ctime of lower level file system -+ * mini_fo' mtime and ctime are updated by generic_file_write -+ */ -+ hidden_inode->i_mtime = hidden_inode->i_ctime = CURRENT_TIME; -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,1) -+ UnlockPage(hidden_page); /* b/c grab_cache_page locked it */ -+# endif /* kernel older than 2.4.1 */ -+ page_cache_release(hidden_page); /* b/c grab_cache_page increased refcnt */ -+ -+ if (err) -+ ClearPageUptodate(page); -+ else -+ SetPageUptodate(page); -+ out: -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,1) -+ UnlockPage(page); -+# endif /* kernel 2.4.1 and newer */ -+ print_exit_status(err); -+ return err; -+} -+ -+ -+/* -+ * get one page from cache or lower f/s, return error otherwise. -+ * returns unlocked, up-to-date page (if ok), with increased refcnt. -+ */ -+page_t * -+mini_fo_get1page(file_t *file, int index) -+{ -+ page_t *page; -+ dentry_t *dentry; -+ inode_t *inode; -+ struct address_space *mapping; -+ int err; -+ -+ print_entry_location(); -+ -+ dentry = file->f_dentry; /* CPW: Moved below print_entry_location */ -+ inode = dentry->d_inode; -+ mapping = inode->i_mapping; -+ -+ fist_dprint(8, "%s: read page index %d pid %d\n", __FUNCTION__, index, current->pid); -+ if (index < 0) { -+ printk("%s BUG: index=%d\n", __FUNCTION__, index); -+ page = ERR_PTR(-EIO); -+ goto out; -+ } -+ page = read_cache_page(mapping, -+ index, -+ (filler_t *) mapping->a_ops->readpage, -+ (void *) file); -+ if (IS_ERR(page)) -+ goto out; -+ wait_on_page(page); -+ if (!Page_Uptodate(page)) { -+ lock_page(page); -+ err = mapping->a_ops->readpage(file, page); -+ if (err) { -+ page = ERR_PTR(err); -+ goto out; -+ } -+ wait_on_page(page); -+ if (!Page_Uptodate(page)) { -+ page = ERR_PTR(-EIO); -+ goto out; -+ } -+ } -+ -+ out: -+ print_exit_pointer(page); -+ return page; -+} -+ -+ -+/* -+ * get one page from cache or lower f/s, return error otherwise. -+ * similar to get1page, but doesn't guarantee that it will return -+ * an unlocked page. -+ */ -+page_t * -+mini_fo_get1page_cached(file_t *file, int index) -+{ -+ page_t *page; -+ dentry_t *dentry; -+ inode_t *inode; -+ struct address_space *mapping; -+ int err; -+ -+ print_entry_location(); -+ -+ dentry = file->f_dentry; /* CPW: Moved below print_entry_location */ -+ inode = dentry->d_inode; -+ mapping = inode->i_mapping; -+ -+ fist_dprint(8, "%s: read page index %d pid %d\n", __FUNCTION__, index, current->pid); -+ if (index < 0) { -+ printk("%s BUG: index=%d\n", __FUNCTION__, index); -+ page = ERR_PTR(-EIO); -+ goto out; -+ } -+ page = read_cache_page(mapping, -+ index, -+ (filler_t *) mapping->a_ops->readpage, -+ (void *) file); -+ if (IS_ERR(page)) -+ goto out; -+ -+ out: -+ print_exit_pointer(page); -+ return page; -+} -+ -+ -+/* -+ * readpage is called from generic_page_read and the fault handler. -+ * If your file system uses generic_page_read for the read op, it -+ * must implement readpage. -+ * -+ * Readpage expects a locked page, and must unlock it. -+ */ -+STATIC int -+mini_fo_do_readpage(file_t *file, page_t *page) -+{ -+ int err = -EIO; -+ dentry_t *dentry; -+ file_t *hidden_file = NULL; -+ dentry_t *hidden_dentry; -+ inode_t *inode; -+ inode_t *hidden_inode; -+ char *page_data; -+ page_t *hidden_page; -+ char *hidden_page_data; -+ int real_size; -+ -+ print_entry_location(); -+ -+ dentry = file->f_dentry; /* CPW: Moved below print_entry_location */ -+ if (ftopd(file) != NULL) -+ hidden_file = ftohf(file); -+ hidden_dentry = dtohd(dentry); -+ inode = dentry->d_inode; -+ hidden_inode = itohi(inode); -+ -+ fist_dprint(7, "%s: requesting page %d from file %s\n", __FUNCTION__, page->index, dentry->d_name.name); -+ -+ MALLOC_PAGE_POINTERS(hidden_pages, num_hidden_pages); -+ MALLOC_PAGEDATA_POINTERS(hidden_pages_data, num_hidden_pages); -+ FOR_EACH_PAGE -+ CURRENT_HIDDEN_PAGE = NULL; -+ -+ /* find lower page (returns a locked page) */ -+ FOR_EACH_PAGE { -+ fist_dprint(8, "%s: Current page index = %d\n", __FUNCTION__, CURRENT_HIDDEN_PAGEINDEX); -+ CURRENT_HIDDEN_PAGE = read_cache_page(hidden_inode->i_mapping, -+ CURRENT_HIDDEN_PAGEINDEX, -+ (filler_t *) hidden_inode->i_mapping->a_ops->readpage, -+ (void *) hidden_file); -+ if (IS_ERR(CURRENT_HIDDEN_PAGE)) { -+ err = PTR_ERR(CURRENT_HIDDEN_PAGE); -+ CURRENT_HIDDEN_PAGE = NULL; -+ goto out_release; -+ } -+ } -+ -+ /* -+ * wait for the page data to show up -+ * (signaled by readpage as unlocking the page) -+ */ -+ FOR_EACH_PAGE { -+ wait_on_page(CURRENT_HIDDEN_PAGE); -+ if (!Page_Uptodate(CURRENT_HIDDEN_PAGE)) { -+ /* -+ * call readpage() again if we returned from wait_on_page with a -+ * page that's not up-to-date; that can happen when a partial -+ * page has a few buffers which are ok, but not the whole -+ * page. -+ */ -+ lock_page(CURRENT_HIDDEN_PAGE); -+ err = hidden_inode->i_mapping->a_ops->readpage(hidden_file, -+ CURRENT_HIDDEN_PAGE); -+ if (err) { -+ CURRENT_HIDDEN_PAGE = NULL; -+ goto out_release; -+ } -+ wait_on_page(CURRENT_HIDDEN_PAGE); -+ if (!Page_Uptodate(CURRENT_HIDDEN_PAGE)) { -+ err = -EIO; -+ goto out_release; -+ } -+ } -+ } -+ -+ /* map pages, get their addresses */ -+ page_data = (char *) kmap(page); -+ FOR_EACH_PAGE -+ CURRENT_HIDDEN_PAGEDATA = (char *) kmap(CURRENT_HIDDEN_PAGE); -+ -+ /* if decode_block could fail, then return error */ -+ err = 0; -+ real_size = hidden_inode->i_size - (page->index << PAGE_CACHE_SHIFT); -+ if (real_size <= 0) -+ memset(page_data, 0, PAGE_CACHE_SIZE); -+ else if (real_size < PAGE_CACHE_SIZE) { -+ mini_fo_decode_block(hidden_page_data, page_data, real_size, inode, inode->i_sb, page->index); -+ memset(page_data + real_size, 0, PAGE_CACHE_SIZE - real_size); -+ } else -+ mini_fo_decode_block(hidden_page_data, page_data, PAGE_CACHE_SIZE, inode, inode->i_sb, page->index); -+ -+ FOR_EACH_PAGE -+ kunmap(CURRENT_HIDDEN_PAGE); -+ kunmap(page); -+ -+ out_release: -+ FOR_EACH_PAGE -+ if (CURRENT_HIDDEN_PAGE) -+ page_cache_release(CURRENT_HIDDEN_PAGE); /* undo read_cache_page */ -+ -+ FREE_PAGE_POINTERS(hidden_pages, num_hidden_pages); -+ FREE_PAGEDATA_POINTERS(hidden_pages_data, num_hidden_pages); -+ -+ out: -+ if (err == 0) -+ SetPageUptodate(page); -+ else -+ ClearPageUptodate(page); -+ -+ print_exit_status(err); -+ return err; -+} -+ -+ -+STATIC int -+mini_fo_readpage(file_t *file, page_t *page) -+{ -+ int err; -+ print_entry_location(); -+ -+ err = mini_fo_do_readpage(file, page); -+ -+ /* -+ * we have to unlock our page, b/c we _might_ have gotten a locked page. -+ * but we no longer have to wakeup on our page here, b/c UnlockPage does -+ * it -+ */ -+ UnlockPage(page); -+ -+ print_exit_status(err); -+ return err; -+} -+ -+ -+STATIC int -+mini_fo_prepare_write(file_t *file, page_t *page, unsigned from, unsigned to) -+{ -+ int err = 0; -+ -+ print_entry_location(); -+ -+ /* -+ * we call kmap(page) only here, and do the kunmap -+ * and the actual downcalls, including unlockpage and uncache -+ * in commit_write. -+ */ -+ kmap(page); -+ -+ /* fast path for whole page writes */ -+ if (from == 0 && to == PAGE_CACHE_SIZE) -+ goto out; -+ /* read the page to "revalidate" our data */ -+ /* call the helper function which doesn't unlock the page */ -+ if (!Page_Uptodate(page)) -+ err = mini_fo_do_readpage(file, page); -+ -+ out: -+ print_exit_status(err); -+ return err; -+} -+ -+ -+ -+STATIC int -+mini_fo_commit_write(file_t *file, page_t *page, unsigned from, unsigned to) -+{ -+ int err = -ENOMEM; -+ inode_t *inode; -+ inode_t *hidden_inode; -+ page_t *hidden_page; -+ file_t *hidden_file = NULL; -+ loff_t pos; -+ unsigned bytes = to - from; -+ unsigned hidden_from, hidden_to, hidden_bytes; -+ -+ print_entry_location(); -+ -+ inode = page->mapping->host; /* CPW: Moved below print_entry_location */ -+ hidden_inode = itohi(inode); -+ -+ ASSERT(file != NULL); -+ /* -+ * here we have a kmapped page, with data from the user copied -+ * into it. we need to encode_block it, and then call the lower -+ * commit_write. We also need to simulate same behavior of -+ * generic_file_write, and call prepare_write on the lower f/s first. -+ */ -+#ifdef FIST_COUNT_WRITES -+ count_writes++; -+# endif /* FIST_COUNT_WRITES */ -+ -+ /* this is append and/or extend -- we can't have holes so fill them in */ -+ if (page->index > (hidden_inode->i_size >> PAGE_CACHE_SHIFT)) { -+ page_t *tmp_page; -+ int index; -+ for (index = hidden_inode->i_size >> PAGE_CACHE_SHIFT; index < page->index; index++) { -+ tmp_page = mini_fo_get1page(file, index); -+ if (IS_ERR(tmp_page)) { -+ err = PTR_ERR(tmp_page); -+ goto out; -+ } -+ /* zero out the contents of the page at the appropriate offsets */ -+ memset((char*)page_address(tmp_page) + (inode->i_size & ~PAGE_CACHE_MASK), 0, PAGE_CACHE_SIZE - (inode->i_size & ~PAGE_CACHE_MASK)); -+ if (!(err = mini_fo_prepare_write(file, tmp_page, 0, PAGE_CACHE_SIZE))) -+ err = mini_fo_commit_write(file, tmp_page, 0, PAGE_CACHE_SIZE); -+ page_cache_release(tmp_page); -+ if (err < 0) -+ goto out; -+ if (current->need_resched) -+ schedule(); -+ } -+ } -+ -+ if (ftopd(file) != NULL) -+ hidden_file = ftohf(file); -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) -+ mutex_lock(&hidden_inode->i_mutex); -+#else -+ down(&hidden_inode->i_sem); -+#endif -+ /* find lower page (returns a locked page) */ -+ hidden_page = grab_cache_page(hidden_inode->i_mapping, page->index); -+ if (!hidden_page) -+ goto out; -+ -+#if FIST_ENCODING_BLOCKSIZE > 1 -+# error encoding_blocksize greater than 1 is not yet supported -+# endif /* FIST_ENCODING_BLOCKSIZE > 1 */ -+ -+ hidden_from = from & (~(FIST_ENCODING_BLOCKSIZE - 1)); -+ hidden_to = ((to + FIST_ENCODING_BLOCKSIZE - 1) & (~(FIST_ENCODING_BLOCKSIZE - 1))); -+ if ((page->index << PAGE_CACHE_SHIFT) + to > hidden_inode->i_size) { -+ -+ /* -+ * if this call to commit_write had introduced holes and the code -+ * for handling holes was invoked, then the beginning of this page -+ * must be zeroed out -+ * zero out bytes from 'size_of_file%pagesize' to 'from'. -+ */ -+ if ((hidden_from - (inode->i_size & ~PAGE_CACHE_MASK)) > 0) -+ memset((char*)page_address(page) + (inode->i_size & ~PAGE_CACHE_MASK), 0, hidden_from - (inode->i_size & ~PAGE_CACHE_MASK)); -+ -+ } -+ hidden_bytes = hidden_to - hidden_from; -+ -+ /* call lower prepare_write */ -+ err = -EINVAL; -+ if (hidden_inode->i_mapping && -+ hidden_inode->i_mapping->a_ops && -+ hidden_inode->i_mapping->a_ops->prepare_write) -+ err = hidden_inode->i_mapping->a_ops->prepare_write(hidden_file, -+ hidden_page, -+ hidden_from, -+ hidden_to); -+ if (err) -+ /* don't leave locked pages behind, esp. on an ENOSPC */ -+ goto out_unlock; -+ -+ fist_dprint(8, "%s: encoding %d bytes\n", __FUNCTION__, hidden_bytes); -+ mini_fo_encode_block((char *) page_address(page) + hidden_from, (char*) page_address(hidden_page) + hidden_from, hidden_bytes, inode, inode->i_sb, page->index); -+ /* if encode_block could fail, then goto unlock and return error */ -+ -+ /* call lower commit_write */ -+ err = hidden_inode->i_mapping->a_ops->commit_write(hidden_file, -+ hidden_page, -+ hidden_from, -+ hidden_to); -+ -+ if (err < 0) -+ goto out_unlock; -+ -+ err = bytes; /* convert error to no. of bytes */ -+ -+ inode->i_blocks = hidden_inode->i_blocks; -+ /* we may have to update i_size */ -+ pos = (page->index << PAGE_CACHE_SHIFT) + to; -+ if (pos > inode->i_size) -+ inode->i_size = pos; -+ -+ /* -+ * update mtime and ctime of lower level file system -+ * mini_fo' mtime and ctime are updated by generic_file_write -+ */ -+ hidden_inode->i_mtime = hidden_inode->i_ctime = CURRENT_TIME; -+ -+ mark_inode_dirty_sync(inode); -+ -+ out_unlock: -+ UnlockPage(hidden_page); -+ page_cache_release(hidden_page); -+ kunmap(page); /* kmap was done in prepare_write */ -+ out: -+ /* we must set our page as up-to-date */ -+ if (err < 0) -+ ClearPageUptodate(page); -+ else -+ SetPageUptodate(page); -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) -+ mutex_unlock(&hidden_inode->i_mutex); -+#else -+ up(&hidden_inode->i_sem); -+#endif -+ print_exit_status(err); -+ return err; /* assume all is ok */ -+} -+ -+ -+STATIC int -+mini_fo_bmap(struct address_space *mapping, long block) -+{ -+ int err = 0; -+ inode_t *inode; -+ inode_t *hidden_inode; -+ -+ print_entry_location(); -+ -+ inode = (inode_t *) mapping->host; -+ hidden_inode = itohi(inode); -+ -+ if (hidden_inode->i_mapping->a_ops->bmap) -+ err = hidden_inode->i_mapping->a_ops->bmap(hidden_inode->i_mapping, block); -+ print_exit_location(); -+ return err; -+} -+ -+ -+/* -+ * This function is copied verbatim from mm/filemap.c. -+ * XXX: It should be simply moved to some header file instead -- bug Al about it! -+ */ -+static inline int sync_page(struct page *page) -+{ -+ struct address_space *mapping = page->mapping; -+ -+ if (mapping && mapping->a_ops && mapping->a_ops->sync_page) -+ return mapping->a_ops->sync_page(page); -+ return 0; -+} -+ -+ -+/* -+ * XXX: we may not need this function if not FIST_FILTER_DATA. -+ * FIXME: for FIST_FILTER_SCA, get all lower pages and sync them each. -+ */ -+STATIC int -+mini_fo_sync_page(page_t *page) -+{ -+ int err = 0; -+ inode_t *inode; -+ inode_t *hidden_inode; -+ page_t *hidden_page; -+ -+ print_entry_location(); -+ -+ inode = page->mapping->host; /* CPW: Moved below print_entry_location */ -+ hidden_inode = itohi(inode); -+ -+ /* find lower page (returns a locked page) */ -+ hidden_page = grab_cache_page(hidden_inode->i_mapping, page->index); -+ if (!hidden_page) -+ goto out; -+ -+ err = sync_page(hidden_page); -+ -+ UnlockPage(hidden_page); /* b/c grab_cache_page locked it */ -+ page_cache_release(hidden_page); /* b/c grab_cache_page increased refcnt */ -+ -+ out: -+ print_exit_status(err); -+ return err; -+} ---- /dev/null -+++ b/fs/mini_fo/README -@@ -0,0 +1,163 @@ -+README for the mini_fo overlay file system -+========================================= -+ -+ -+WHAT IS MINI_FO? -+---------------- -+ -+mini_fo is a virtual kernel file system that can make read-only -+file systems writable. This is done by redirecting modifying operations -+to a writeable location called "storage directory", and leaving the -+original data in the "base directory" untouched. When reading, the -+file system merges the modifed and original data so that only the -+newest versions will appear. This occurs transparently to the user, -+who can access the data like on any other read-write file system. -+ -+Base and storage directories may be located on the same or on -+different partitions and may be of different file system types. While -+the storage directory obviously needs to be writable, the base may or -+may not be writable, what doesn't matter as it will no be modified -+anyway. -+ -+ -+WHAT IS GOOD FOR? -+----------------- -+ -+The primary purpose of the mini_fo file system is to allow easy -+software updates to embedded systems, that often store their root -+file system in a read-only flash file system, but there are many -+more as for example sandboxing, or for allowing live-cds to -+permanently store information. -+ -+ -+BUILDING -+-------- -+This should be simple. Adjust the Makefile to point to the correct -+kernel headers you want to build the module for. Then: -+ -+ # make -+ -+should build "mini_fo.o" for a 2.4 kernel or "mini_fo.ko" for a 2.6 -+kernel. -+ -+If you are building the module for you current kernel, you can install -+the module (as root): -+ -+ # make install -+ -+or uninstall with -+ -+ # make uninstall -+ -+ -+USING THE FILE SYSTEM -+-------------------- -+ -+the general mount syntax is: -+ -+ mount -t mini_fo -o base=,sto=\ -+ -+ -+Example: -+ -+You have mounted a cdrom to /mnt/cdrom and want to modifiy some files -+on it: -+ -+load the module (as root) -+ -+ # insmod mini_fo.o for a 2.4 kernel or -+ -+ # insmod mini_fo.ko for a 2.6 kernel -+ -+ -+create a storage dir in tmp and a mountpoint for mini_fo: -+ -+ # mkdir /tmp/sto -+ # mkdir /mnt/mini_fo -+ -+and mount the mini_fo file system: -+ -+ # mount -t mini_fo -o base=/mnt/cdrom,sto=/tmp/sto /mnt/cdrom /mnt/mini_fo -+ -+ -+Now the data stored on the cd can be accessed via the mini_fo -+mountpoint just like any read-write file system, files can be modified -+and deleted, new ones can be created and so on. When done unmount the -+file system: -+ -+ # unmount /mnt/mini_fo -+ -+Note that if the file system is mounted again using the same storage -+file system, of course it will appear in the modified state again. If -+you remount it using an new empty storage directory, it will be -+unmodified. Therefore by executing: -+ -+ # cd /tmp/sto -+ # rm -rf * -+ -+you can nuke all the changes you made to the original file system. But -+ remember NEVER do this while the mini_fo file system is mounted! -+ -+ -+Alternatively you can use the mini_fo-overlay bash script, that -+simplifies managing mini_fo mounts. See TOOLS Section. -+ -+ -+TOOLS -+----- -+ -+mini_fo-merge (experimental): -+ -+This is a bash script that will merge changes contained in the storage -+directory back to the base directory. This allows mini_fo to function -+as a cache file system by overlaying a slow (network, ...) file system -+and using a fast (ramdisk, ...) as storage. When done, changes can be -+merged back to the (slow) base with mini_fo-merge. See "mini_fo-merge -+-h" for details. -+ -+It can be usefull for merging changes back after a successfull test -+(patches, software updates...) -+ -+ -+mini_fo-overlay: -+ -+This bash script simplifies managing one or more mini_fo mounts. For -+overlaying a directory called "basedir1", you can just call: -+ -+ # mini_fo-overlay basedir1 -+ -+This will mount mini_fo with "basedir1" as base, "/tmp/sto-basedir1/" -+as storage to "/mnt/mini_fo-basedir1/". It has more options though, -+type "mini_fo-overlay -h" for details. -+ -+ -+DOCUMENTATION, REPORTING BUGS, GETTING HELP -+------------------------------------------- -+ -+Please visit the mini_fo project page at: -+ -+http://www.denx.de/twiki/bin/view/Know/MiniFOHome -+ -+ -+WARNINGS -+-------- -+ -+Never modify the base or the storage directorys while the mini_fo -+file system is mounted, or you might crash you system. Simply accessing -+and reading should not cause any trouble. -+ -+Exporting a mini_fo mount point via NFS has not been tested, and may -+or may not work. -+ -+Check the RELEASE_NOTES for details on bugs and features. -+ -+ -+ -+Copyright (C) 2004, 2005 Markus Klotzbuecher -+ -+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. -+ -+ ---- /dev/null -+++ b/fs/mini_fo/RELEASE_NOTES -@@ -0,0 +1,111 @@ -+Release: mini_fo-0.6.1 (v0-6-1) -+Date: 21.09.2005 -+ -+ -+Changes: -+-------- -+v0-6-1: -+ -+- bugfixes (see ChangeLog) -+ -+- two helper scripts "mini_fo_merge" and "mini_fo_overlay" (see -+ README for details). -+ -+v0-6-0: -+ -+- Support for 2.4 and 2.6 (see Makefile) -+ -+- Partial hard link support (creating works as expected, but already -+ existing links in the base file system will be treated as if they -+ were individual files). -+ -+- Various bugfixes and cleanups. -+ -+ -+v0-6-0-pre1: -+ -+- This is mini_fo-0-6-0-pre1! This release is a complete rewrite of -+ many vital mini_fo parts such as the old whiteout list code which -+ has been replaced by the new META subsystem. -+ -+- Light weight directory renaming implemented. This means if a -+ directory is renamed via the mini_fo filesystem this will no longer -+ result in a complete copy in storage, instead only one empty -+ directory will be created. All base filed contained in the original -+ directory stay there until modified. -+ -+- Special files (creating, renaming, deleting etc.) now working. -+ -+- Many bugfixes and cleanup, mini_fo is now a lot more stable. -+ -+ -+v0-5-10: -+ -+- Final release of the 0-5-* versions. Next will be a complete rewrite -+ of many features. This release contains several bugfixes related to -+ directory renaming. -+ -+ -+v0-5-10-pre6: -+ -+- Lots of cleanup and several bugfixes related to directory deleting -+ -+- Directory renaming suddenly works, what is most likely due to the -+ fact tha that "mv" is smart: if the classic rename doesn't work it -+ will assume that source and target file are on different fs and will -+ copy the directory and try to remove the source directory. Until -+ directory removing wasn't implemented, it would fail to do this and -+ rollback. -+ So, directory renaming works for now, but it doesn't yet do what you -+ would expect from a overlay fs, so use with care. -+ -+ -+v0-5-10-pre5: -+ -+- implemented directory deleting -+- made parsing of mount options more stable -+- New format of mount options! (See README) -+- I can't reproduce the unknown panic with 2.4.25 anymore, so I'll -+ happily assume it never existed! -+ -+ -+Implemented features: -+--------------------- -+ -+- creating hard links (see BUGS on already existing hard links) -+- lightweight directory renaming -+- renaming device files, pipes, sockets, etc. -+- creating, renaming, deleting of special files -+- deleting directorys -+- general directory reading (simple "ls" ) -+- creating files in existing directorys -+- creating directorys -+- renaming files. -+- reading and writing files (involves opening) -+- appending to files (creates copy in storage) -+- deleting files -+- llseek works too, what allows editors to work -+- persistency (a deleted file stay deleted over remounts) -+- use of symbolic links -+- creating of device files -+ -+ -+Not (yet) implemented features: -+------------------------------- -+ -+- full hard link support. -+ -+ -+ -+BUGS: -+----- -+ -+Hard links in the base file system will be treated as individual -+files, not as links to one inode. -+ -+The main problem with hard links isn't allowing to create them, but -+their pure existence. If you modify a base hard link, the changes made -+will only show up on this link, the other link will remain in the -+original state. I hope to fix this someday. Please note that this does -+not effect the special hard links '.' and '..', that are handled -+seperately by the lower fs. ---- /dev/null -+++ b/fs/mini_fo/state.c -@@ -0,0 +1,620 @@ -+/* -+ * Copyright (C) 2005 Markus Klotzbuecher -+ * -+ * 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. -+ */ -+ -+#ifdef HAVE_CONFIG_H -+# include -+#endif /* HAVE_CONFIG_H */ -+ -+#include "fist.h" -+#include "mini_fo.h" -+ -+ -+/* create the storage file, setup new states */ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -+int create_sto_reg_file(dentry_t *dentry, int mode, struct nameidata *nd) -+#else -+int create_sto_reg_file(dentry_t *dentry, int mode) -+#endif -+{ -+ int err = 0; -+ inode_t *dir; -+ dentry_t *hidden_sto_dentry; -+ dentry_t *hidden_sto_dir_dentry; -+ -+ if(exists_in_storage(dentry)) { -+ printk(KERN_CRIT "mini_fo: create_sto_file: wrong type or state.\n"); -+ err = -EINVAL; -+ goto out; -+ } -+ err = get_neg_sto_dentry(dentry); -+ -+ if (err) { -+ printk(KERN_CRIT "mini_fo: create_sto_file: ERROR getting neg. sto dentry.\n"); -+ goto out; -+ } -+ -+ dir = dentry->d_parent->d_inode; -+ hidden_sto_dentry = dtohd2(dentry); -+ -+ /* lock parent */ -+ hidden_sto_dir_dentry = dget(hidden_sto_dentry->d_parent); -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) -+ mutex_lock(&hidden_sto_dir_dentry->d_inode->i_mutex); -+#else -+ down(&hidden_sto_dir_dentry->d_inode->i_sem); -+#endif -+ -+ err = PTR_ERR(hidden_sto_dir_dentry); -+ if (IS_ERR(hidden_sto_dir_dentry)) -+ goto out; -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -+ err = vfs_create(hidden_sto_dir_dentry->d_inode, -+ hidden_sto_dentry, -+ mode, nd); -+#else -+ err = vfs_create(hidden_sto_dir_dentry->d_inode, -+ hidden_sto_dentry, -+ mode); -+#endif -+ if(err) { -+ printk(KERN_CRIT "mini_fo: create_sto_file: ERROR creating sto file.\n"); -+ goto out_lock; -+ } -+ -+ if(!dtohd2(dentry)->d_inode) { -+ printk(KERN_CRIT "mini_fo: create_sto_file: ERROR creating sto file [2].\n"); -+ err = -EINVAL; -+ goto out_lock; -+ } -+ -+ /* interpose the new inode */ -+ if(dtost(dentry) == DELETED) { -+ dtost(dentry) = DEL_REWRITTEN; -+ err = mini_fo_tri_interpose(NULL, hidden_sto_dentry, dentry, dir->i_sb, 0); -+ if(err) -+ goto out_lock; -+ } -+ else if(dtost(dentry) == NON_EXISTANT) { -+ dtost(dentry) = CREATED; -+ err = mini_fo_tri_interpose(dtohd(dentry), hidden_sto_dentry, dentry, dir->i_sb, 0); -+ if(err) -+ goto out_lock; -+ } -+ else if(dtost(dentry) == UNMODIFIED) { -+ dtost(dentry) = MODIFIED; -+ /* interpose on new inode */ -+ if(itohi2(dentry->d_inode) != NULL) { -+ printk(KERN_CRIT "mini_fo: create_sto_file: invalid inode detected.\n"); -+ err = -EINVAL; -+ goto out_lock; -+ } -+ itohi2(dentry->d_inode) = igrab(dtohd2(dentry)->d_inode); -+ } -+ fist_copy_attr_timesizes(dentry->d_parent->d_inode, -+ hidden_sto_dir_dentry->d_inode); -+ -+ out_lock: -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) -+ mutex_unlock(&hidden_sto_dir_dentry->d_inode->i_mutex); -+#else -+ up(&hidden_sto_dir_dentry->d_inode->i_sem); -+#endif -+ dput(hidden_sto_dir_dentry); -+ out: -+ return err; -+} -+ -+/* create the sto dir, setup states */ -+int create_sto_dir(dentry_t *dentry, int mode) -+{ -+ int err = 0; -+ inode_t *dir; -+ dentry_t *hidden_sto_dentry; -+ dentry_t *hidden_sto_dir_dentry; -+ -+ /* had to take the "!S_ISDIR(mode))" check out, because it failed */ -+ if(exists_in_storage(dentry)) { -+ printk(KERN_CRIT "mini_fo: create_sto_dir: wrong type or state.\\ -+n"); -+ err = -EINVAL; -+ goto out; -+ } -+ -+ err = get_neg_sto_dentry(dentry); -+ if(err) { -+ err = -EINVAL; -+ goto out; -+ } -+ -+ dir = dentry->d_parent->d_inode; -+ hidden_sto_dentry = dtohd2(dentry); -+ -+ /* was: hidden_sto_dir_dentry = lock_parent(hidden_sto_dentry); */ -+ hidden_sto_dir_dentry = dget(hidden_sto_dentry->d_parent); -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) -+ mutex_lock(&hidden_sto_dir_dentry->d_inode->i_mutex); -+#else -+ down(&hidden_sto_dir_dentry->d_inode->i_sem); -+#endif -+ -+ err = PTR_ERR(hidden_sto_dir_dentry); -+ if (IS_ERR(hidden_sto_dir_dentry)) -+ goto out; -+ -+ err = vfs_mkdir(hidden_sto_dir_dentry->d_inode, -+ hidden_sto_dentry, -+ mode); -+ if(err) { -+ printk(KERN_CRIT "mini_fo: create_sto_dir: ERROR creating sto dir.\n"); -+ goto out_lock; -+ } -+ -+ if(!dtohd2(dentry)->d_inode) { -+ printk(KERN_CRIT "mini_fo: create_sto_dir: ERROR creating sto dir [2].\n"); -+ err = -EINVAL; -+ goto out_lock; -+ } -+ -+ /* interpose the new inode */ -+ if(dtost(dentry) == DELETED) { -+ dtost(dentry) = DEL_REWRITTEN; -+ err = mini_fo_tri_interpose(NULL, hidden_sto_dentry, dentry, dir->i_sb, 0); -+ if(err) -+ goto out_lock; -+ } -+ else if(dtopd(dentry)->state == NON_EXISTANT) { -+ dtopd(dentry)->state = CREATED; -+ err = mini_fo_tri_interpose(dtohd(dentry), hidden_sto_dentry, dentry, dir->i_sb, 0); -+ if(err) -+ goto out_lock; -+ } -+ else if(dtopd(dentry)->state == UNMODIFIED) { -+ dtopd(dentry)->state = MODIFIED; -+ /* interpose on new inode */ -+ if(itohi2(dentry->d_inode) != NULL) { -+ printk(KERN_CRIT "mini_fo: create_sto_dir: ERROR, invalid inode detected.\n"); -+ err = -EINVAL; -+ goto out_lock; -+ } -+ itohi2(dentry->d_inode) = igrab(dtohd2(dentry)->d_inode); -+ } -+ -+ fist_copy_attr_timesizes(dir, hidden_sto_dir_dentry->d_inode); -+ -+ /* initalize the wol list */ -+ itopd(dentry->d_inode)->deleted_list_size = -1; -+ itopd(dentry->d_inode)->renamed_list_size = -1; -+ meta_build_lists(dentry); -+ -+ -+ out_lock: -+ /* was: unlock_dir(hidden_sto_dir_dentry); */ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) -+ mutex_unlock(&hidden_sto_dir_dentry->d_inode->i_mutex); -+#else -+ up(&hidden_sto_dir_dentry->d_inode->i_sem); -+#endif -+ dput(hidden_sto_dir_dentry); -+ out: -+ return err; -+} -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -+int create_sto_nod(dentry_t *dentry, int mode, dev_t dev) -+#else -+int create_sto_nod(dentry_t *dentry, int mode, int dev) -+#endif -+{ -+ int err = 0; -+ inode_t *dir; -+ dentry_t *hidden_sto_dentry; -+ dentry_t *hidden_sto_dir_dentry; -+ -+ if(exists_in_storage(dentry)) { -+ err = -EEXIST; -+ goto out; -+ } -+ err = get_neg_sto_dentry(dentry); -+ -+ if (err) { -+ printk(KERN_CRIT "mini_fo: create_sto_nod: ERROR getting neg. sto dentry.\n"); -+ goto out; -+ } -+ -+ dir = dentry->d_parent->d_inode; -+ hidden_sto_dentry = dtohd2(dentry); -+ -+ /* lock parent */ -+ hidden_sto_dir_dentry = dget(hidden_sto_dentry->d_parent); -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) -+ mutex_lock(&hidden_sto_dir_dentry->d_inode->i_mutex); -+#else -+ down(&hidden_sto_dir_dentry->d_inode->i_sem); -+#endif -+ -+ err = PTR_ERR(hidden_sto_dir_dentry); -+ if (IS_ERR(hidden_sto_dir_dentry)) -+ goto out; -+ -+ err = vfs_mknod(hidden_sto_dir_dentry->d_inode, hidden_sto_dentry, mode, dev); -+ if(err) -+ goto out_lock; -+ -+ if(!dtohd2(dentry)->d_inode) { -+ printk(KERN_CRIT "mini_fo: create_sto_nod: creating storage inode failed [1].\n"); -+ err = -EINVAL; /* return something indicating failure */ -+ goto out_lock; -+ } -+ -+ /* interpose the new inode */ -+ if(dtost(dentry) == DELETED) { -+ dtost(dentry) = DEL_REWRITTEN; -+ err = mini_fo_tri_interpose(NULL, hidden_sto_dentry, dentry, dir->i_sb, 0); -+ if(err) -+ goto out_lock; -+ } -+ else if(dtost(dentry) == NON_EXISTANT) { -+ dtost(dentry) = CREATED; -+ err = mini_fo_tri_interpose(dtohd(dentry), hidden_sto_dentry, dentry, dir->i_sb, 0); -+ if(err) -+ goto out_lock; -+ } -+ else if(dtost(dentry) == UNMODIFIED) { -+ dtost(dentry) = MODIFIED; -+ /* interpose on new inode */ -+ if(itohi2(dentry->d_inode) != NULL) { -+ printk(KERN_CRIT "mini_fo: create_sto_nod: error, invalid inode detected.\n"); -+ err = -EINVAL; -+ goto out_lock; -+ } -+ itohi2(dentry->d_inode) = igrab(dtohd2(dentry)->d_inode); -+ } -+ -+ fist_copy_attr_timesizes(dir, hidden_sto_dir_dentry->d_inode); -+ -+ out_lock: -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) -+ mutex_unlock(&hidden_sto_dir_dentry->d_inode->i_mutex); -+#else -+ up(&hidden_sto_dir_dentry->d_inode->i_sem); -+#endif -+ dput(hidden_sto_dir_dentry); -+ out: -+ return err; -+} -+ -+ -+/* unimplemented (and possibly not usefull): -+ -+ nondir-del_to_del_rew -+ nondir-non_exist_to_creat -+ -+ dir-unmod_to_del -+ dir-mod_to_del -+ dir-creat_to_del -+ dir-del_rew_to_del -+ dir-del_to_del_rew -+ dir-non_exist_to_creat -+*/ -+ -+ -+/* bring a file of any type from state UNMODIFIED to MODIFIED */ -+int nondir_unmod_to_mod(dentry_t *dentry, int cp_flag) -+{ -+ int err = 0; -+ struct vfsmount *tgt_mnt; -+ struct vfsmount *src_mnt; -+ dentry_t *tgt_dentry; -+ dentry_t *src_dentry; -+ dentry_t *hidden_sto_dentry; -+ dentry_t *hidden_sto_dir_dentry; -+ -+ check_mini_fo_dentry(dentry); -+ -+ if((dtost(dentry) != UNMODIFIED) || -+ S_ISDIR(dentry->d_inode->i_mode)) { -+ printk(KERN_CRIT "mini_fo: nondir_unmod_to_mod: \ -+ wrong type or state.\n"); -+ err = -1; -+ goto out; -+ } -+ err = get_neg_sto_dentry(dentry); -+ -+ if (err) { -+ printk(KERN_CRIT "mini_fo: nondir_unmod_to_mod: \ -+ ERROR getting neg. sto dentry.\n"); -+ goto out; -+ } -+ -+ /* create sto file */ -+ hidden_sto_dentry = dtohd2(dentry); -+ -+ /* lock parent */ -+ hidden_sto_dir_dentry = dget(hidden_sto_dentry->d_parent); -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) -+ mutex_lock(&hidden_sto_dir_dentry->d_inode->i_mutex); -+#else -+ down(&hidden_sto_dir_dentry->d_inode->i_sem); -+#endif -+ -+ err = PTR_ERR(hidden_sto_dir_dentry); -+ if (IS_ERR(hidden_sto_dir_dentry)) -+ goto out; -+ -+ /* handle different types of nondirs */ -+ if(S_ISCHR(dentry->d_inode->i_mode) || -+ S_ISBLK(dentry->d_inode->i_mode)) { -+ err = vfs_mknod(hidden_sto_dir_dentry->d_inode, -+ hidden_sto_dentry, -+ dtohd(dentry)->d_inode->i_mode, -+ dtohd(dentry)->d_inode->i_rdev); -+ } -+ -+ else if(S_ISREG(dentry->d_inode->i_mode)) { -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -+ err = vfs_create(hidden_sto_dir_dentry->d_inode, -+ hidden_sto_dentry, -+ dtohd(dentry)->d_inode->i_mode, NULL); -+#else -+ err = vfs_create(hidden_sto_dir_dentry->d_inode, -+ hidden_sto_dentry, -+ dtohd(dentry)->d_inode->i_mode); -+#endif -+ } -+ if(err) { -+ printk(KERN_CRIT "mini_fo: nondir_unmod_to_mod: \ -+ ERROR creating sto file.\n"); -+ goto out_lock; -+ } -+ -+ /* interpose on new inode */ -+ if(itohi2(dentry->d_inode) != NULL) { -+ printk(KERN_CRIT "mini_fo: nondir_unmod_to_mod: \ -+ ERROR, invalid inode detected.\n"); -+ err = -EINVAL; -+ goto out_lock; -+ } -+ -+ itohi2(dentry->d_inode) = igrab(dtohd2(dentry)->d_inode); -+ -+ fist_copy_attr_timesizes(dentry->d_parent->d_inode, -+ hidden_sto_dir_dentry->d_inode); -+ dtost(dentry) = MODIFIED; -+ -+ /* copy contents if regular file and cp_flag = 1 */ -+ if((cp_flag == 1) && S_ISREG(dentry->d_inode->i_mode)) { -+ -+ /* unlock first */ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) -+ mutex_unlock(&hidden_sto_dir_dentry->d_inode->i_mutex); -+#else -+ up(&hidden_sto_dir_dentry->d_inode->i_sem); -+#endif -+ -+ dput(hidden_sto_dir_dentry); -+ -+ tgt_dentry = dtohd2(dentry); -+ tgt_mnt = stopd(dentry->d_inode->i_sb)->hidden_mnt2; -+ src_dentry = dtohd(dentry); -+ src_mnt = stopd(dentry->d_inode->i_sb)->hidden_mnt; -+ -+ err = mini_fo_cp_cont(tgt_dentry, tgt_mnt, -+ src_dentry, src_mnt); -+ if(err) { -+ printk(KERN_CRIT "mini_fo: nondir_unmod_to_mod: \ -+ ERROR copying contents.\n"); -+ } -+ goto out; -+ } -+ -+ out_lock: -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) -+ mutex_unlock(&hidden_sto_dir_dentry->d_inode->i_mutex); -+#else -+ up(&hidden_sto_dir_dentry->d_inode->i_sem); -+#endif -+ dput(hidden_sto_dir_dentry); -+ out: -+ return err; -+} -+ -+/* this function is currently identical to nondir_creat_to_del */ -+int nondir_del_rew_to_del(dentry_t *dentry) -+{ -+ return nondir_creat_to_del(dentry); -+} -+ -+int nondir_creat_to_del(dentry_t *dentry) -+{ -+ int err = 0; -+ -+ inode_t *hidden_sto_dir_inode; -+ dentry_t *hidden_sto_dir_dentry; -+ dentry_t *hidden_sto_dentry; -+ -+ check_mini_fo_dentry(dentry); -+ -+ /* for now this function serves for both state DEL_REWRITTEN and -+ * CREATED */ -+ if(!(dtost(dentry) == CREATED || (dtost(dentry) == DEL_REWRITTEN)) || -+ S_ISDIR(dentry->d_inode->i_mode)) { -+ printk(KERN_CRIT "mini_fo: nondir_mod_to_del/del_rew_to_del: \ -+ wrong type or state.\n"); -+ err = -1; -+ goto out; -+ } -+ -+ hidden_sto_dir_inode = itohi2(dentry->d_parent->d_inode); -+ hidden_sto_dentry = dtohd2(dentry); -+ -+ /* was: hidden_sto_dir_dentry = lock_parent(hidden_sto_dentry);*/ -+ hidden_sto_dir_dentry = dget(hidden_sto_dentry->d_parent); -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) -+ mutex_lock(&hidden_sto_dir_dentry->d_inode->i_mutex); -+#else -+ down(&hidden_sto_dir_dentry->d_inode->i_sem); -+#endif -+ -+ /* avoid destroying the hidden inode if the file is in use */ -+ dget(hidden_sto_dentry); -+ err = vfs_unlink(hidden_sto_dir_inode, hidden_sto_dentry); -+ dput(hidden_sto_dentry); -+ if(!err) -+ d_delete(hidden_sto_dentry); -+ -+ /* propagate number of hard-links */ -+ dentry->d_inode->i_nlink = itohi2(dentry->d_inode)->i_nlink; -+ -+ dtost(dentry) = NON_EXISTANT; -+ -+ /* was: unlock_dir(hidden_sto_dir_dentry); */ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) -+ mutex_unlock(&hidden_sto_dir_dentry->d_inode->i_mutex); -+#else -+ up(&hidden_sto_dir_dentry->d_inode->i_sem); -+#endif -+ dput(hidden_sto_dir_dentry); -+ -+ out: -+ return err; -+} -+ -+int nondir_mod_to_del(dentry_t *dentry) -+{ -+ int err; -+ dentry_t *hidden_sto_dentry; -+ inode_t *hidden_sto_dir_inode; -+ dentry_t *hidden_sto_dir_dentry; -+ -+ check_mini_fo_dentry(dentry); -+ -+ if(dtost(dentry) != MODIFIED || -+ S_ISDIR(dentry->d_inode->i_mode)) { -+ printk(KERN_CRIT "mini_fo: nondir_mod_to_del: \ -+ wrong type or state.\n"); -+ err = -1; -+ goto out; -+ } -+ -+ hidden_sto_dir_inode = itohi2(dentry->d_parent->d_inode); -+ hidden_sto_dentry = dtohd2(dentry); -+ -+ /* was hidden_sto_dir_dentry = lock_parent(hidden_sto_dentry); */ -+ hidden_sto_dir_dentry = dget(hidden_sto_dentry->d_parent); -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) -+ mutex_lock(&hidden_sto_dir_dentry->d_inode->i_mutex); -+#else -+ down(&hidden_sto_dir_dentry->d_inode->i_sem); -+#endif -+ -+ /* avoid destroying the hidden inode if the file is in use */ -+ dget(hidden_sto_dentry); -+ err = vfs_unlink(hidden_sto_dir_inode, hidden_sto_dentry); -+ dput(hidden_sto_dentry); -+ if(!err) -+ d_delete(hidden_sto_dentry); -+ -+ /* propagate number of hard-links */ -+ dentry->d_inode->i_nlink = itohi2(dentry->d_inode)->i_nlink; -+ -+ /* dput base dentry, this will relase the inode and free the -+ * dentry, as we will never need it again. */ -+ dput(dtohd(dentry)); -+ dtohd(dentry) = NULL; -+ dtost(dentry) = DELETED; -+ -+ /* add deleted file to META-file */ -+ meta_add_d_entry(dentry->d_parent, -+ dentry->d_name.name, -+ dentry->d_name.len); -+ -+ /* was: unlock_dir(hidden_sto_dir_dentry); */ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) -+ mutex_unlock(&hidden_sto_dir_dentry->d_inode->i_mutex); -+#else -+ up(&hidden_sto_dir_dentry->d_inode->i_sem); -+#endif -+ dput(hidden_sto_dir_dentry); -+ -+ out: -+ return err; -+} -+ -+int nondir_unmod_to_del(dentry_t *dentry) -+{ -+ int err = 0; -+ -+ check_mini_fo_dentry(dentry); -+ -+ if(dtost(dentry) != UNMODIFIED || -+ S_ISDIR(dentry->d_inode->i_mode)) { -+ printk(KERN_CRIT "mini_fo: nondir_unmod_to_del: \ -+ wrong type or state.\n"); -+ err = -1; -+ goto out; -+ } -+ -+ /* next we have to get a negative dentry for the storage file */ -+ err = get_neg_sto_dentry(dentry); -+ -+ if(err) -+ goto out; -+ -+ /* add deleted file to META lists */ -+ err = meta_add_d_entry(dentry->d_parent, -+ dentry->d_name.name, -+ dentry->d_name.len); -+ -+ if(err) -+ goto out; -+ -+ /* dput base dentry, this will relase the inode and free the -+ * dentry, as we will never need it again. */ -+ dput(dtohd(dentry)); -+ dtohd(dentry) = NULL; -+ dtost(dentry) = DELETED; -+ -+ out: -+ return err; -+} -+ -+/* bring a dir from state UNMODIFIED to MODIFIED */ -+int dir_unmod_to_mod(dentry_t *dentry) -+{ -+ int err; -+ -+ check_mini_fo_dentry(dentry); -+ -+ if(dtost(dentry) != UNMODIFIED || -+ !S_ISDIR(dentry->d_inode->i_mode)) { -+ printk(KERN_CRIT "mini_fo: dir_unmod_to_mod: \ -+ wrong type or state.\n"); -+ err = -1; -+ goto out; -+ } -+ -+ /* this creates our dir incl. sto. structure */ -+ err = build_sto_structure(dentry->d_parent, dentry); -+ if(err) { -+ printk(KERN_CRIT "mini_fo: dir_unmod_to_mod: \ -+ build_sto_structure failed.\n"); -+ goto out; -+ } -+ out: -+ return err; -+} -+ ---- /dev/null -+++ b/fs/mini_fo/super.c -@@ -0,0 +1,281 @@ -+/* -+ * Copyright (c) 1997-2003 Erez Zadok -+ * Copyright (c) 2001-2003 Stony Brook University -+ * -+ * For specific licensing information, see the COPYING file distributed with -+ * this package, or get one from ftp://ftp.filesystems.org/pub/fist/COPYING. -+ * -+ * This Copyright notice must be kept intact and distributed with all -+ * fistgen sources INCLUDING sources generated by fistgen. -+ */ -+/* -+ * Copyright (C) 2004, 2005 Markus Klotzbuecher -+ * -+ * 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. -+ */ -+ -+/* -+ * $Id$ -+ */ -+ -+#ifdef HAVE_CONFIG_H -+# include -+#endif -+ -+#include "fist.h" -+#include "mini_fo.h" -+ -+ -+STATIC void -+mini_fo_read_inode(inode_t *inode) -+{ -+ static struct address_space_operations mini_fo_empty_aops; -+ -+ __itopd(inode) = kmalloc(sizeof(struct mini_fo_inode_info), GFP_KERNEL); -+ if (!itopd(inode)) { -+ printk("<0>%s:%s:%d: No kernel memory!\n", __FILE__, __FUNCTION__, __LINE__); -+ ASSERT(NULL); -+ } -+ itohi(inode) = NULL; -+ itohi2(inode) = NULL; -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -+ inode->i_version++; -+#else -+ inode->i_version = ++event; /* increment inode version */ -+#endif -+ inode->i_op = &mini_fo_main_iops; -+ inode->i_fop = &mini_fo_main_fops; -+#if 0 -+ /* -+ * XXX: To export a file system via NFS, it has to have the -+ * FS_REQUIRES_DEV flag, so turn it on. But should we inherit it from -+ * the lower file system, or can we allow our file system to be exported -+ * even if the lower one cannot be natively exported. -+ */ -+ inode->i_sb->s_type->fs_flags |= FS_REQUIRES_DEV; -+ /* -+ * OK, the above was a hack, which is now turned off because it may -+ * cause a panic/oops on some systems. The correct way to export a -+ * "nodev" filesystem is via using nfs-utils > 1.0 and the "fsid=" export -+ * parameter, which requires 2.4.20 or later. -+ */ -+#endif -+ /* I don't think ->a_ops is ever allowed to be NULL */ -+ inode->i_mapping->a_ops = &mini_fo_empty_aops; -+} -+ -+ -+#if defined(FIST_DEBUG) || defined(FIST_FILTER_SCA) -+/* -+ * No need to call write_inode() on the lower inode, as it -+ * will have been marked 'dirty' anyway. But we might need -+ * to write some of our own stuff to disk. -+ */ -+STATIC void -+mini_fo_write_inode(inode_t *inode, int sync) -+{ -+ print_entry_location(); -+ print_exit_location(); -+} -+#endif /* defined(FIST_DEBUG) || defined(FIST_FILTER_SCA) */ -+ -+ -+STATIC void -+mini_fo_put_inode(inode_t *inode) -+{ -+ /* -+ * This is really funky stuff: -+ * Basically, if i_count == 1, iput will then decrement it and this inode will be destroyed. -+ * It is currently holding a reference to the hidden inode. -+ * Therefore, it needs to release that reference by calling iput on the hidden inode. -+ * iput() _will_ do it for us (by calling our clear_inode), but _only_ if i_nlink == 0. -+ * The problem is, NFS keeps i_nlink == 1 for silly_rename'd files. -+ * So we must for our i_nlink to 0 here to trick iput() into calling our clear_inode. -+ */ -+ if (atomic_read(&inode->i_count) == 1) -+ inode->i_nlink = 0; -+} -+ -+ -+#if defined(FIST_DEBUG) || defined(FIST_FILTER_SCA) -+/* -+ * we now define delete_inode, because there are two VFS paths that may -+ * destroy an inode: one of them calls clear inode before doing everything -+ * else that's needed, and the other is fine. This way we truncate the inode -+ * size (and its pages) and then clear our own inode, which will do an iput -+ * on our and the lower inode. -+ */ -+STATIC void -+mini_fo_delete_inode(inode_t *inode) -+{ -+ print_entry_location(); -+ -+ fist_checkinode(inode, "mini_fo_delete_inode IN"); -+ inode->i_size = 0; /* every f/s seems to do that */ -+ clear_inode(inode); -+ -+ print_exit_location(); -+} -+#endif /* defined(FIST_DEBUG) || defined(FIST_FILTER_SCA) */ -+ -+ -+/* final actions when unmounting a file system */ -+STATIC void -+mini_fo_put_super(super_block_t *sb) -+{ -+ if (stopd(sb)) { -+ mntput(stopd(sb)->hidden_mnt); -+ mntput(stopd(sb)->hidden_mnt2); -+ -+ /* mk: no! dput(stopd(sb)->base_dir_dentry); -+ dput(stopd(sb)->storage_dir_dentry); */ -+ -+ kfree(stopd(sb)); -+ __stopd(sb) = NULL; -+ } -+} -+ -+ -+#ifdef NOT_NEEDED -+/* -+ * This is called in do_umount before put_super. -+ * The superblock lock is not held yet. -+ * We probably do not need to define this or call write_super -+ * on the hidden_sb, because sync_supers() will get to hidden_sb -+ * sooner or later. But it is also called from file_fsync()... -+ */ -+STATIC void -+mini_fo_write_super(super_block_t *sb) -+{ -+ return; -+} -+#endif /* NOT_NEEDED */ -+ -+ -+STATIC int -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) -+mini_fo_statfs(struct dentry *d, struct kstatfs *buf) -+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) -+mini_fo_statfs(super_block_t *sb, struct kstatfs *buf) -+#else -+mini_fo_statfs(super_block_t *sb, struct statfs *buf) -+#endif -+{ -+ int err = 0; -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) -+ struct dentry *hidden_d; -+ -+ hidden_d = dtohd(d); -+ err = vfs_statfs(hidden_d, buf); -+#else -+ super_block_t *hidden_sb; -+ -+ hidden_sb = stohs(sb); -+ err = vfs_statfs(hidden_sb, buf); -+#endif -+ -+ return err; -+} -+ -+ -+/* -+ * XXX: not implemented. This is not allowed yet. -+ * Should we call this on the hidden_sb? Probably not. -+ */ -+STATIC int -+mini_fo_remount_fs(super_block_t *sb, int *flags, char *data) -+{ -+ //printk(KERN_CRIT "mini_fo_remount_fs: WARNING, this function is umimplemented.\n"); -+ return -ENOSYS; -+} -+ -+ -+/* -+ * Called by iput() when the inode reference count reached zero -+ * and the inode is not hashed anywhere. Used to clear anything -+ * that needs to be, before the inode is completely destroyed and put -+ * on the inode free list. -+ */ -+STATIC void -+mini_fo_clear_inode(inode_t *inode) -+{ -+ /* -+ * Decrement a reference to a hidden_inode, which was incremented -+ * by our read_inode when it was created initially. -+ */ -+ -+ /* release the wol_list */ -+ if(S_ISDIR(inode->i_mode)) { -+ __meta_put_lists(inode); -+ } -+ -+ /* mk: fan out fun */ -+ if(itohi(inode)) -+ iput(itohi(inode)); -+ if(itohi2(inode)) -+ iput(itohi2(inode)); -+ -+ // XXX: why this assertion fails? -+ // because it doesn't like us -+ // ASSERT((inode->i_state & I_DIRTY) == 0); -+ kfree(itopd(inode)); -+ __itopd(inode) = NULL; -+} -+ -+ -+/* -+ * Called in do_umount() if the MNT_FORCE flag was used and this -+ * function is defined. See comment in linux/fs/super.c:do_umount(). -+ * Used only in nfs, to kill any pending RPC tasks, so that subsequent -+ * code can actually succeed and won't leave tasks that need handling. -+ * -+ * PS. I wonder if this is somehow useful to undo damage that was -+ * left in the kernel after a user level file server (such as amd) -+ * dies. -+ */ -+STATIC void -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) -+mini_fo_umount_begin(struct vfsmount *mnt, int flags) -+{ -+ struct vfsmount *hidden_mnt; -+ -+ hidden_mnt = stopd(mnt->mnt_sb)->hidden_mnt; -+ -+ if (hidden_mnt->mnt_sb->s_op->umount_begin) -+ hidden_mnt->mnt_sb->s_op->umount_begin(hidden_mnt, flags); -+ -+} -+#else -+mini_fo_umount_begin(super_block_t *sb) -+{ -+ super_block_t *hidden_sb; -+ -+ hidden_sb = stohs(sb); -+ -+ if (hidden_sb->s_op->umount_begin) -+ hidden_sb->s_op->umount_begin(hidden_sb); -+ -+} -+#endif -+ -+ -+struct super_operations mini_fo_sops = -+{ -+ read_inode: mini_fo_read_inode, -+#if defined(FIST_DEBUG) || defined(FIST_FILTER_SCA) -+ write_inode: mini_fo_write_inode, -+#endif /* defined(FIST_DEBUG) || defined(FIST_FILTER_SCA) */ -+ put_inode: mini_fo_put_inode, -+#if defined(FIST_DEBUG) || defined(FIST_FILTER_SCA) -+ delete_inode: mini_fo_delete_inode, -+#endif /* defined(FIST_DEBUG) || defined(FIST_FILTER_SCA) */ -+ put_super: mini_fo_put_super, -+ statfs: mini_fo_statfs, -+ remount_fs: mini_fo_remount_fs, -+ clear_inode: mini_fo_clear_inode, -+ umount_begin: mini_fo_umount_begin, -+}; diff --git a/target/linux/generic-2.6/patches-2.6.24/213-kobject_uevent.patch b/target/linux/generic-2.6/patches-2.6.24/213-kobject_uevent.patch deleted file mode 100644 index 7d4b232423..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/213-kobject_uevent.patch +++ /dev/null @@ -1,42 +0,0 @@ ---- a/lib/kobject_uevent.c -+++ b/lib/kobject_uevent.c -@@ -27,7 +27,8 @@ u64 uevent_seqnum; - char uevent_helper[UEVENT_HELPER_PATH_LEN] = CONFIG_UEVENT_HELPER_PATH; - static DEFINE_SPINLOCK(sequence_lock); - #if defined(CONFIG_NET) --static struct sock *uevent_sock; -+struct sock *uevent_sock = NULL; -+EXPORT_SYMBOL_GPL(uevent_sock); - #endif - - /* the strings here must match the enum in include/linux/kobject.h */ -@@ -40,6 +41,18 @@ static const char *kobject_actions[] = { - [KOBJ_OFFLINE] = "offline", - }; - -+u64 uevent_next_seqnum(void) -+{ -+ u64 seq; -+ -+ spin_lock(&sequence_lock); -+ seq = ++uevent_seqnum; -+ spin_unlock(&sequence_lock); -+ -+ return seq; -+} -+EXPORT_SYMBOL_GPL(uevent_next_seqnum); -+ - /** - * kobject_action_type - translate action string to numeric type - * -@@ -173,9 +186,7 @@ int kobject_uevent_env(struct kobject *k - } - - /* we will send an event, so request a new sequence number */ -- spin_lock(&sequence_lock); -- seq = ++uevent_seqnum; -- spin_unlock(&sequence_lock); -+ seq = uevent_next_seqnum(); - retval = add_uevent_var(env, "SEQNUM=%llu", (unsigned long long)seq); - if (retval) - goto exit; diff --git a/target/linux/generic-2.6/patches-2.6.24/220-sound_kconfig.patch b/target/linux/generic-2.6/patches-2.6.24/220-sound_kconfig.patch deleted file mode 100644 index d215d12077..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/220-sound_kconfig.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/sound/core/Kconfig -+++ b/sound/core/Kconfig -@@ -9,7 +9,7 @@ config SND_PCM - depends on SND - - config SND_HWDEP -- tristate -+ tristate "Sound hardware support" - depends on SND - - config SND_RAWMIDI diff --git a/target/linux/generic-2.6/patches-2.6.24/400-ledtrig_morse.patch b/target/linux/generic-2.6/patches-2.6.24/400-ledtrig_morse.patch deleted file mode 100644 index 6db1472209..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/400-ledtrig_morse.patch +++ /dev/null @@ -1,18 +0,0 @@ ---- a/drivers/leds/Kconfig -+++ b/drivers/leds/Kconfig -@@ -146,4 +146,8 @@ config LEDS_TRIGGER_HEARTBEAT - load average. - If unsure, say Y. - -+config LEDS_TRIGGER_MORSE -+ tristate "LED Morse Trigger" -+ depends on LEDS_TRIGGERS -+ - endif # NEW_LEDS ---- a/drivers/leds/Makefile -+++ b/drivers/leds/Makefile -@@ -24,3 +24,4 @@ obj-$(CONFIG_LEDS_CM_X270) - obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o - obj-$(CONFIG_LEDS_TRIGGER_IDE_DISK) += ledtrig-ide-disk.o - obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT) += ledtrig-heartbeat.o -+obj-$(CONFIG_LEDS_TRIGGER_MORSE) += ledtrig-morse.o diff --git a/target/linux/generic-2.6/patches-2.6.24/401-led_alix.patch b/target/linux/generic-2.6/patches-2.6.24/401-led_alix.patch deleted file mode 100644 index 81afd81a6a..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/401-led_alix.patch +++ /dev/null @@ -1,25 +0,0 @@ ---- a/drivers/leds/Kconfig -+++ b/drivers/leds/Kconfig -@@ -81,6 +81,12 @@ config LEDS_WRAP - help - This option enables support for the PCEngines WRAP programmable LEDs. - -+config LEDS_ALIX -+ tristate "LED Support for the ALIX 2/3 boards" -+ depends on LEDS_CLASS -+ help -+ This option enables support for the three LEDs on the PCEngines ALIX 2/3 boards. -+ - config LEDS_H1940 - tristate "LED Support for iPAQ H1940 device" - depends on LEDS_CLASS && ARCH_H1940 ---- a/drivers/leds/Makefile -+++ b/drivers/leds/Makefile -@@ -14,6 +14,7 @@ obj-$(CONFIG_LEDS_S3C24XX) += leds-s3c2 - obj-$(CONFIG_LEDS_AMS_DELTA) += leds-ams-delta.o - obj-$(CONFIG_LEDS_NET48XX) += leds-net48xx.o - obj-$(CONFIG_LEDS_WRAP) += leds-wrap.o -+obj-$(CONFIG_LEDS_ALIX) += leds-alix.o - obj-$(CONFIG_LEDS_H1940) += leds-h1940.o - obj-$(CONFIG_LEDS_COBALT_QUBE) += leds-cobalt-qube.o - obj-$(CONFIG_LEDS_COBALT_RAQ) += leds-cobalt-raq.o diff --git a/target/linux/generic-2.6/patches-2.6.24/402-ledtrig_default_on.patch b/target/linux/generic-2.6/patches-2.6.24/402-ledtrig_default_on.patch deleted file mode 100644 index 0e1164cf4b..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/402-ledtrig_default_on.patch +++ /dev/null @@ -1,21 +0,0 @@ ---- a/drivers/leds/Kconfig -+++ b/drivers/leds/Kconfig -@@ -156,4 +156,11 @@ config LEDS_TRIGGER_MORSE - tristate "LED Morse Trigger" - depends on LEDS_TRIGGERS - -+config LEDS_TRIGGER_DEFAULT_ON -+ tristate "LED Default ON Trigger" -+ depends on LEDS_TRIGGERS -+ help -+ This allows LEDs to be initialised in the ON state. -+ If unsure, say Y. -+ - endif # NEW_LEDS ---- a/drivers/leds/Makefile -+++ b/drivers/leds/Makefile -@@ -26,3 +26,4 @@ obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledt - obj-$(CONFIG_LEDS_TRIGGER_IDE_DISK) += ledtrig-ide-disk.o - obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT) += ledtrig-heartbeat.o - obj-$(CONFIG_LEDS_TRIGGER_MORSE) += ledtrig-morse.o -+obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON) += ledtrig-default-on.o diff --git a/target/linux/generic-2.6/patches-2.6.24/403-ds1672_detect.patch b/target/linux/generic-2.6/patches-2.6.24/403-ds1672_detect.patch deleted file mode 100644 index 9c2a2f98ea..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/403-ds1672_detect.patch +++ /dev/null @@ -1,16 +0,0 @@ ---- a/drivers/rtc/rtc-ds1672.c -+++ b/drivers/rtc/rtc-ds1672.c -@@ -13,10 +13,10 @@ - #include - #include - --#define DRV_VERSION "0.3" -+#define DRV_VERSION "0.4" - --/* Addresses to scan: none. This chip cannot be detected. */ --static unsigned short normal_i2c[] = { I2C_CLIENT_END }; -+/* Addresses to scan: 0x68 */ -+static unsigned short normal_i2c[] = { 0x68, I2C_CLIENT_END }; - - /* Insmod parameters */ - I2C_CLIENT_INSMOD; diff --git a/target/linux/generic-2.6/patches-2.6.24/410-gpio_buttons.patch b/target/linux/generic-2.6/patches-2.6.24/410-gpio_buttons.patch deleted file mode 100644 index 31d40c9449..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/410-gpio_buttons.patch +++ /dev/null @@ -1,30 +0,0 @@ ---- a/drivers/input/misc/Kconfig -+++ b/drivers/input/misc/Kconfig -@@ -183,4 +183,20 @@ config HP_SDC_RTC - Say Y here if you want to support the built-in real time clock - of the HP SDC controller. - -+config INPUT_GPIO_BUTTONS -+ tristate "Polled GPIO buttons interface" -+ depends on GENERIC_GPIO -+ select INPUT_POLLDEV -+ help -+ This driver implements support for buttons connected -+ to GPIO pins of various CPUs (and some other chips). -+ -+ Say Y here if your device has buttons connected -+ directly to such GPIO pins. Your board-specific -+ setup logic must also provide a platform device, -+ with configuration data saying which GPIOs are used. -+ -+ To compile this driver as a module, choose M here: the -+ module will be called gpio-buttons. -+ - endif ---- a/drivers/input/misc/Makefile -+++ b/drivers/input/misc/Makefile -@@ -18,3 +18,4 @@ obj-$(CONFIG_INPUT_POWERMATE) += powerm - obj-$(CONFIG_INPUT_YEALINK) += yealink.o - obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o - obj-$(CONFIG_INPUT_UINPUT) += uinput.o -+obj-$(CONFIG_INPUT_GPIO_BUTTONS) += gpio_buttons.o diff --git a/target/linux/generic-2.6/patches-2.6.24/420-gpiodev.patch b/target/linux/generic-2.6/patches-2.6.24/420-gpiodev.patch deleted file mode 100644 index 0b184a0b2a..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/420-gpiodev.patch +++ /dev/null @@ -1,26 +0,0 @@ ---- a/drivers/char/Kconfig -+++ b/drivers/char/Kconfig -@@ -946,6 +946,13 @@ config CS5535_GPIO - - If compiled as a module, it will be called cs5535_gpio. - -+config GPIO_DEVICE -+ tristate "GPIO device support" -+ depends on GENERIC_GPIO -+ help -+ Say Y to enable Linux GPIO device support. This allows control of -+ GPIO pins using a character device -+ - config GPIO_VR41XX - tristate "NEC VR4100 series General-purpose I/O Unit support" - depends on CPU_VR41XX ---- a/drivers/char/Makefile -+++ b/drivers/char/Makefile -@@ -93,6 +93,7 @@ obj-$(CONFIG_SCx200_GPIO) += scx200_gpio - obj-$(CONFIG_PC8736x_GPIO) += pc8736x_gpio.o - obj-$(CONFIG_NSC_GPIO) += nsc_gpio.o - obj-$(CONFIG_CS5535_GPIO) += cs5535_gpio.o -+obj-$(CONFIG_GPIO_DEVICE) += gpio_dev.o - obj-$(CONFIG_GPIO_VR41XX) += vr41xx_giu.o - obj-$(CONFIG_GPIO_TB0219) += tb0219.o - obj-$(CONFIG_TELCLOCK) += tlclk.o diff --git a/target/linux/generic-2.6/patches-2.6.24/510-yaffs_support.patch b/target/linux/generic-2.6/patches-2.6.24/510-yaffs_support.patch deleted file mode 100644 index 4553236b00..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/510-yaffs_support.patch +++ /dev/null @@ -1,17 +0,0 @@ ---- a/fs/Kconfig -+++ b/fs/Kconfig -@@ -420,6 +420,7 @@ config FS_POSIX_ACL - - source "fs/xfs/Kconfig" - source "fs/gfs2/Kconfig" -+source "fs/yaffs2/Kconfig" - - config OCFS2_FS - tristate "OCFS2 file system support" ---- a/fs/Makefile -+++ b/fs/Makefile -@@ -120,3 +120,4 @@ obj-$(CONFIG_HPPFS) += hppfs/ - obj-$(CONFIG_DEBUG_FS) += debugfs/ - obj-$(CONFIG_OCFS2_FS) += ocfs2/ - obj-$(CONFIG_GFS2_FS) += gfs2/ -+obj-$(CONFIG_YAFFS_FS) += yaffs2/ diff --git a/target/linux/generic-2.6/patches-2.6.24/600-phy_extension.patch b/target/linux/generic-2.6/patches-2.6.24/600-phy_extension.patch deleted file mode 100644 index ed37e1a9b8..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/600-phy_extension.patch +++ /dev/null @@ -1,63 +0,0 @@ ---- a/drivers/net/phy/phy.c -+++ b/drivers/net/phy/phy.c -@@ -345,6 +345,50 @@ int phy_ethtool_gset(struct phy_device * - } - EXPORT_SYMBOL(phy_ethtool_gset); - -+int phy_ethtool_ioctl(struct phy_device *phydev, void *useraddr) -+{ -+ u32 cmd; -+ int tmp; -+ struct ethtool_cmd ecmd = { ETHTOOL_GSET }; -+ struct ethtool_value edata = { ETHTOOL_GLINK }; -+ -+ if (get_user(cmd, (u32 *) useraddr)) -+ return -EFAULT; -+ -+ switch (cmd) { -+ case ETHTOOL_GSET: -+ phy_ethtool_gset(phydev, &ecmd); -+ if (copy_to_user(useraddr, &ecmd, sizeof(ecmd))) -+ return -EFAULT; -+ return 0; -+ -+ case ETHTOOL_SSET: -+ if (copy_from_user(&ecmd, useraddr, sizeof(ecmd))) -+ return -EFAULT; -+ return phy_ethtool_sset(phydev, &ecmd); -+ -+ case ETHTOOL_NWAY_RST: -+ /* if autoneg is off, it's an error */ -+ tmp = phy_read(phydev, MII_BMCR); -+ if (tmp & BMCR_ANENABLE) { -+ tmp |= (BMCR_ANRESTART); -+ phy_write(phydev, MII_BMCR, tmp); -+ return 0; -+ } -+ return -EINVAL; -+ -+ case ETHTOOL_GLINK: -+ edata.data = (phy_read(phydev, -+ MII_BMSR) & BMSR_LSTATUS) ? 1 : 0; -+ if (copy_to_user(useraddr, &edata, sizeof(edata))) -+ return -EFAULT; -+ return 0; -+ } -+ -+ return -EOPNOTSUPP; -+} -+EXPORT_SYMBOL(phy_ethtool_ioctl); -+ - /** - * phy_mii_ioctl - generic PHY MII ioctl interface - * @phydev: the phy_device struct ---- a/include/linux/phy.h -+++ b/include/linux/phy.h -@@ -398,6 +398,7 @@ void phy_start_machine(struct phy_device - void phy_stop_machine(struct phy_device *phydev); - int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd); - int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd); -+int phy_ethtool_ioctl(struct phy_device *phydev, void *useraddr); - int phy_mii_ioctl(struct phy_device *phydev, - struct mii_ioctl_data *mii_data, int cmd); - int phy_start_interrupts(struct phy_device *phydev); diff --git a/target/linux/generic-2.6/patches-2.6.24/601-br2684-routed-support.patch b/target/linux/generic-2.6/patches-2.6.24/601-br2684-routed-support.patch deleted file mode 100644 index 3bc2e2642d..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/601-br2684-routed-support.patch +++ /dev/null @@ -1,728 +0,0 @@ ---- a/include/linux/atmbr2684.h -+++ b/include/linux/atmbr2684.h -@@ -14,6 +14,9 @@ - #define BR2684_MEDIA_FDDI (3) - #define BR2684_MEDIA_802_6 (4) /* 802.6 */ - -+ /* used only at device creation: */ -+#define BR2684_FLAG_ROUTED (1<<16) /* payload is routed, not bridged */ -+ - /* - * Is there FCS inbound on this VC? This currently isn't supported. - */ -@@ -36,15 +39,22 @@ - #define BR2684_ENCAPS_AUTODETECT (2) /* Unsuported */ - - /* -+ * Is this VC bridged or routed? -+ */ -+ -+#define BR2684_PAYLOAD_ROUTED (0) -+#define BR2684_PAYLOAD_BRIDGED (1) -+ -+/* - * This is for the ATM_NEWBACKENDIF call - these are like socket families: - * the first element of the structure is the backend number and the rest - * is per-backend specific - */ - struct atm_newif_br2684 { -- atm_backend_t backend_num; /* ATM_BACKEND_BR2684 */ -- int media; /* BR2684_MEDIA_* */ -- char ifname[IFNAMSIZ]; -- int mtu; -+ atm_backend_t backend_num; /* ATM_BACKEND_BR2684 */ -+ int media; /* BR2684_MEDIA_*, flags in upper bits */ -+ char ifname[IFNAMSIZ]; -+ int mtu; - }; - - /* -@@ -55,10 +65,10 @@ struct atm_newif_br2684 { - #define BR2684_FIND_BYNUM (1) - #define BR2684_FIND_BYIFNAME (2) - struct br2684_if_spec { -- int method; /* BR2684_FIND_* */ -+ int method; /* BR2684_FIND_* */ - union { -- char ifname[IFNAMSIZ]; -- int devnum; -+ char ifname[IFNAMSIZ]; -+ int devnum; - } spec; - }; - -@@ -68,16 +78,16 @@ struct br2684_if_spec { - * is per-backend specific - */ - struct atm_backend_br2684 { -- atm_backend_t backend_num; /* ATM_BACKEND_BR2684 */ -+ atm_backend_t backend_num; /* ATM_BACKEND_BR2684 */ - struct br2684_if_spec ifspec; -- int fcs_in; /* BR2684_FCSIN_* */ -- int fcs_out; /* BR2684_FCSOUT_* */ -- int fcs_auto; /* 1: fcs_{in,out} disabled if no FCS rx'ed */ -- int encaps; /* BR2684_ENCAPS_* */ -- int has_vpiid; /* 1: use vpn_id - Unsupported */ -- __u8 vpn_id[7]; -- int send_padding; /* unsupported */ -- int min_size; /* we will pad smaller packets than this */ -+ int fcs_in; /* BR2684_FCSIN_* */ -+ int fcs_out; /* BR2684_FCSOUT_* */ -+ int fcs_auto; /* 1: fcs_{in,out} disabled if no FCS rx'ed */ -+ int encaps; /* BR2684_ENCAPS_* */ -+ int has_vpiid; /* 1: use vpn_id - Unsupported */ -+ __u8 vpn_id[7]; -+ int send_padding; /* unsupported */ -+ int min_size; /* we will pad smaller packets than this */ - }; - - /* -@@ -86,8 +96,8 @@ struct atm_backend_br2684 { - * efficient per-if in/out filters, this support will be removed - */ - struct br2684_filter { -- __be32 prefix; /* network byte order */ -- __be32 netmask; /* 0 = disable filter */ -+ __be32 prefix; /* network byte order */ -+ __be32 netmask; /* 0 = disable filter */ - }; - - struct br2684_filter_set { -@@ -95,7 +105,13 @@ struct br2684_filter_set { - struct br2684_filter filter; - }; - -+enum br2684_payload { -+ p_routed = BR2684_PAYLOAD_ROUTED, -+ p_bridged = BR2684_PAYLOAD_BRIDGED, -+}; -+ - #define BR2684_SETFILT _IOW( 'a', ATMIOC_BACKEND + 0, \ - struct br2684_filter_set) - - #endif /* _LINUX_ATMBR2684_H */ -+ ---- a/net/atm/br2684.c -+++ b/net/atm/br2684.c -@@ -1,8 +1,10 @@ - /* --Experimental ethernet netdevice using ATM AAL5 as underlying carrier --(RFC1483 obsoleted by RFC2684) for Linux 2.4 --Author: Marcell GAL, 2000, XDSL Ltd, Hungary --*/ -+ * Ethernet netdevice using ATM AAL5 as underlying carrier -+ * (RFC1483 obsoleted by RFC2684) for Linux -+ * -+ * Authors: Marcell GAL, 2000, XDSL Ltd, Hungary -+ * Eric Kinzie, 2006-2007, US Naval Research Laboratory -+ */ - - #include - #include -@@ -39,21 +41,35 @@ static void skb_debug(const struct sk_bu - #define skb_debug(skb) do {} while (0) - #endif - -+#define BR2684_ETHERTYPE_LEN 2 -+#define BR2684_PAD_LEN 2 -+ -+#define LLC 0xaa, 0xaa, 0x03 -+#define SNAP_BRIDGED 0x00, 0x80, 0xc2 -+#define SNAP_ROUTED 0x00, 0x00, 0x00 -+#define PID_ETHERNET 0x00, 0x07 -+#define ETHERTYPE_IPV4 0x08, 0x00 -+#define ETHERTYPE_IPV6 0x86, 0xdd -+#define PAD_BRIDGED 0x00, 0x00 -+ -+static unsigned char ethertype_ipv4[] = { ETHERTYPE_IPV4 }; -+static unsigned char ethertype_ipv6[] = { ETHERTYPE_IPV6 }; - static unsigned char llc_oui_pid_pad[] = -- { 0xAA, 0xAA, 0x03, 0x00, 0x80, 0xC2, 0x00, 0x07, 0x00, 0x00 }; --#define PADLEN (2) -+ { LLC, SNAP_BRIDGED, PID_ETHERNET, PAD_BRIDGED }; -+static unsigned char llc_oui_ipv4[] = { LLC, SNAP_ROUTED, ETHERTYPE_IPV4 }; -+static unsigned char llc_oui_ipv6[] = { LLC, SNAP_ROUTED, ETHERTYPE_IPV6 }; - - enum br2684_encaps { -- e_vc = BR2684_ENCAPS_VC, -+ e_vc = BR2684_ENCAPS_VC, - e_llc = BR2684_ENCAPS_LLC, - }; - - struct br2684_vcc { -- struct atm_vcc *atmvcc; -+ struct atm_vcc *atmvcc; - struct net_device *device; -- /* keep old push,pop functions for chaining */ -- void (*old_push)(struct atm_vcc *vcc,struct sk_buff *skb); -- /* void (*old_pop)(struct atm_vcc *vcc,struct sk_buff *skb); */ -+ /* keep old push, pop functions for chaining */ -+ void (*old_push) (struct atm_vcc * vcc, struct sk_buff * skb); -+ /* void (*old_pop)(struct atm_vcc *vcc, struct sk_buff *skb); */ - enum br2684_encaps encaps; - struct list_head brvccs; - #ifdef CONFIG_ATM_BR2684_IPFILTER -@@ -66,9 +82,10 @@ struct br2684_dev { - struct net_device *net_dev; - struct list_head br2684_devs; - int number; -- struct list_head brvccs; /* one device <=> one vcc (before xmas) */ -+ struct list_head brvccs; /* one device <=> one vcc (before xmas) */ - struct net_device_stats stats; - int mac_was_set; -+ enum br2684_payload payload; - }; - - /* -@@ -84,7 +101,7 @@ static LIST_HEAD(br2684_devs); - - static inline struct br2684_dev *BRPRIV(const struct net_device *net_dev) - { -- return (struct br2684_dev *) net_dev->priv; -+ return (struct br2684_dev *)net_dev->priv; - } - - static inline struct net_device *list_entry_brdev(const struct list_head *le) -@@ -94,7 +111,7 @@ static inline struct net_device *list_en - - static inline struct br2684_vcc *BR2684_VCC(const struct atm_vcc *atmvcc) - { -- return (struct br2684_vcc *) (atmvcc->user_back); -+ return (struct br2684_vcc *)(atmvcc->user_back); - } - - static inline struct br2684_vcc *list_entry_brvcc(const struct list_head *le) -@@ -132,10 +149,11 @@ static struct net_device *br2684_find_de - * otherwise false - */ - static int br2684_xmit_vcc(struct sk_buff *skb, struct br2684_dev *brdev, -- struct br2684_vcc *brvcc) -+ struct br2684_vcc *brvcc) - { - struct atm_vcc *atmvcc; - int minheadroom = (brvcc->encaps == e_llc) ? 10 : 2; -+ - if (skb_headroom(skb) < minheadroom) { - struct sk_buff *skb2 = skb_realloc_headroom(skb, minheadroom); - brvcc->copies_needed++; -@@ -146,23 +164,48 @@ static int br2684_xmit_vcc(struct sk_buf - } - skb = skb2; - } -- skb_push(skb, minheadroom); -- if (brvcc->encaps == e_llc) -- skb_copy_to_linear_data(skb, llc_oui_pid_pad, 10); -- else -- memset(skb->data, 0, 2); -+ -+ if (brvcc->encaps == e_llc) { -+ if (brdev->payload == p_bridged) { -+ skb_push(skb, sizeof(llc_oui_pid_pad)); -+ skb_copy_to_linear_data(skb, llc_oui_pid_pad, -+ sizeof(llc_oui_pid_pad)); -+ } else if (brdev->payload == p_routed) { -+ unsigned short prot = ntohs(skb->protocol); -+ -+ skb_push(skb, sizeof(llc_oui_ipv4)); -+ switch (prot) { -+ case ETH_P_IP: -+ skb_copy_to_linear_data(skb, llc_oui_ipv4, -+ sizeof(llc_oui_ipv4)); -+ break; -+ case ETH_P_IPV6: -+ skb_copy_to_linear_data(skb, llc_oui_ipv6, -+ sizeof(llc_oui_ipv6)); -+ break; -+ default: -+ dev_kfree_skb(skb); -+ return 0; -+ } -+ } -+ } else { -+ skb_push(skb, 2); -+ if (brdev->payload == p_bridged) -+ memset(skb->data, 0, 2); -+ } - skb_debug(skb); - - ATM_SKB(skb)->vcc = atmvcc = brvcc->atmvcc; - pr_debug("atm_skb(%p)->vcc(%p)->dev(%p)\n", skb, atmvcc, atmvcc->dev); - if (!atm_may_send(atmvcc, skb->truesize)) { -- /* we free this here for now, because we cannot know in a higher -- layer whether the skb point it supplied wasn't freed yet. -- now, it always is. -- */ -+ /* -+ * We free this here for now, because we cannot know in a higher -+ * layer whether the skb pointer it supplied wasn't freed yet. -+ * Now, it always is. -+ */ - dev_kfree_skb(skb); - return 0; -- } -+ } - atomic_add(skb->truesize, &sk_atm(atmvcc)->sk_wmem_alloc); - ATM_SKB(skb)->atm_options = atmvcc->atm_options; - brdev->stats.tx_packets++; -@@ -172,10 +215,9 @@ static int br2684_xmit_vcc(struct sk_buf - } - - static inline struct br2684_vcc *pick_outgoing_vcc(struct sk_buff *skb, -- struct br2684_dev *brdev) -+ struct br2684_dev *brdev) - { -- return list_empty(&brdev->brvccs) ? NULL : -- list_entry_brvcc(brdev->brvccs.next); /* 1 vcc/dev right now */ -+ return list_empty(&brdev->brvccs) ? NULL : list_entry_brvcc(brdev->brvccs.next); /* 1 vcc/dev right now */ - } - - static int br2684_start_xmit(struct sk_buff *skb, struct net_device *dev) -@@ -199,11 +241,10 @@ static int br2684_start_xmit(struct sk_b - /* - * We should probably use netif_*_queue() here, but that - * involves added complication. We need to walk before -- * we can run -+ * we can run. -+ * -+ * Don't free here! this pointer might be no longer valid! - */ -- /* don't free here! this pointer might be no longer valid! -- dev_kfree_skb(skb); -- */ - brdev->stats.tx_errors++; - brdev->stats.tx_fifo_errors++; - } -@@ -217,12 +258,11 @@ static struct net_device_stats *br2684_g - return &BRPRIV(dev)->stats; - } - -- - /* - * We remember when the MAC gets set, so we don't override it later with - * the ESI of the ATM card of the first VC - */ --static int (*my_eth_mac_addr)(struct net_device *, void *); -+static int (*my_eth_mac_addr) (struct net_device *, void *); - static int br2684_mac_addr(struct net_device *dev, void *p) - { - int err = my_eth_mac_addr(dev, p); -@@ -233,7 +273,7 @@ static int br2684_mac_addr(struct net_de - - #ifdef CONFIG_ATM_BR2684_IPFILTER - /* this IOCTL is experimental. */ --static int br2684_setfilt(struct atm_vcc *atmvcc, void __user *arg) -+static int br2684_setfilt(struct atm_vcc *atmvcc, void __user * arg) - { - struct br2684_vcc *brvcc; - struct br2684_filter_set fs; -@@ -243,13 +283,12 @@ static int br2684_setfilt(struct atm_vcc - if (fs.ifspec.method != BR2684_FIND_BYNOTHING) { - /* - * This is really a per-vcc thing, but we can also search -- * by device -+ * by device. - */ - struct br2684_dev *brdev; - read_lock(&devs_lock); - brdev = BRPRIV(br2684_find_dev(&fs.ifspec)); -- if (brdev == NULL || list_empty(&brdev->brvccs) || -- brdev->brvccs.next != brdev->brvccs.prev) /* >1 VCC */ -+ if (brdev == NULL || list_empty(&brdev->brvccs) || brdev->brvccs.next != brdev->brvccs.prev) /* >1 VCC */ - brvcc = NULL; - else - brvcc = list_entry_brvcc(brdev->brvccs.next); -@@ -267,15 +306,16 @@ static inline int - packet_fails_filter(__be16 type, struct br2684_vcc *brvcc, struct sk_buff *skb) - { - if (brvcc->filter.netmask == 0) -- return 0; /* no filter in place */ -+ return 0; /* no filter in place */ - if (type == htons(ETH_P_IP) && -- (((struct iphdr *) (skb->data))->daddr & brvcc->filter. -+ (((struct iphdr *)(skb->data))->daddr & brvcc->filter. - netmask) == brvcc->filter.prefix) - return 0; - if (type == htons(ETH_P_ARP)) - return 0; -- /* TODO: we should probably filter ARPs too.. don't want to have -- * them returning values that don't make sense, or is that ok? -+ /* -+ * TODO: we should probably filter ARPs too.. don't want to have -+ * them returning values that don't make sense, or is that ok? - */ - return 1; /* drop */ - } -@@ -299,7 +339,6 @@ static void br2684_push(struct atm_vcc * - struct br2684_vcc *brvcc = BR2684_VCC(atmvcc); - struct net_device *net_dev = brvcc->device; - struct br2684_dev *brdev = BRPRIV(net_dev); -- int plen = sizeof(llc_oui_pid_pad) + ETH_HLEN; - - pr_debug("br2684_push\n"); - -@@ -320,35 +359,58 @@ static void br2684_push(struct atm_vcc * - atm_return(atmvcc, skb->truesize); - pr_debug("skb from brdev %p\n", brdev); - if (brvcc->encaps == e_llc) { -- /* let us waste some time for checking the encapsulation. -- Note, that only 7 char is checked so frames with a valid FCS -- are also accepted (but FCS is not checked of course) */ -- if (memcmp(skb->data, llc_oui_pid_pad, 7)) { -+ -+ if (skb->len > 7 && skb->data[7] == 0x01) -+ __skb_trim(skb, skb->len - 4); -+ -+ /* accept packets that have "ipv[46]" in the snap header */ -+ if ((skb->len >= (sizeof(llc_oui_ipv4))) -+ && -+ (memcmp -+ (skb->data, llc_oui_ipv4, -+ sizeof(llc_oui_ipv4) - BR2684_ETHERTYPE_LEN) == 0)) { -+ if (memcmp -+ (skb->data + 6, ethertype_ipv6, -+ sizeof(ethertype_ipv6)) == 0) -+ skb->protocol = __constant_htons(ETH_P_IPV6); -+ else if (memcmp -+ (skb->data + 6, ethertype_ipv4, -+ sizeof(ethertype_ipv4)) == 0) -+ skb->protocol = __constant_htons(ETH_P_IP); -+ else { -+ brdev->stats.rx_errors++; -+ dev_kfree_skb(skb); -+ return; -+ } -+ skb_pull(skb, sizeof(llc_oui_ipv4)); -+ skb_reset_network_header(skb); -+ skb->pkt_type = PACKET_HOST; -+ /* -+ * Let us waste some time for checking the encapsulation. -+ * Note, that only 7 char is checked so frames with a valid FCS -+ * are also accepted (but FCS is not checked of course). -+ */ -+ } else if ((skb->len >= sizeof(llc_oui_pid_pad)) && -+ (memcmp(skb->data, llc_oui_pid_pad, 7) == 0)) { -+ skb_pull(skb, sizeof(llc_oui_pid_pad)); -+ skb->protocol = eth_type_trans(skb, net_dev); -+ } else { - brdev->stats.rx_errors++; - dev_kfree_skb(skb); - return; - } - -- /* Strip FCS if present */ -- if (skb->len > 7 && skb->data[7] == 0x01) -- __skb_trim(skb, skb->len - 4); - } else { -- plen = PADLEN + ETH_HLEN; /* pad, dstmac,srcmac, ethtype */ - /* first 2 chars should be 0 */ - if (*((u16 *) (skb->data)) != 0) { - brdev->stats.rx_errors++; - dev_kfree_skb(skb); - return; - } -- } -- if (skb->len < plen) { -- brdev->stats.rx_errors++; -- dev_kfree_skb(skb); /* dev_ not needed? */ -- return; -+ skb_pull(skb, BR2684_PAD_LEN + ETH_HLEN); /* pad, dstmac, srcmac, ethtype */ -+ skb->protocol = eth_type_trans(skb, net_dev); - } - -- skb_pull(skb, plen - ETH_HLEN); -- skb->protocol = eth_type_trans(skb, net_dev); - #ifdef CONFIG_ATM_BR2684_IPFILTER - if (unlikely(packet_fails_filter(skb->protocol, brvcc, skb))) { - brdev->stats.rx_dropped++; -@@ -372,11 +434,12 @@ static void br2684_push(struct atm_vcc * - netif_rx(skb); - } - --static int br2684_regvcc(struct atm_vcc *atmvcc, void __user *arg) -+/* -+ * Assign a vcc to a dev -+ * Note: we do not have explicit unassign, but look at _push() -+ */ -+static int br2684_regvcc(struct atm_vcc *atmvcc, void __user * arg) - { --/* assign a vcc to a dev --Note: we do not have explicit unassign, but look at _push() --*/ - int err; - struct br2684_vcc *brvcc; - struct sk_buff *skb; -@@ -395,7 +458,7 @@ Note: we do not have explicit unassign, - net_dev = br2684_find_dev(&be.ifspec); - if (net_dev == NULL) { - printk(KERN_ERR -- "br2684: tried to attach to non-existant device\n"); -+ "br2684: tried to attach to non-existant device\n"); - err = -ENXIO; - goto error; - } -@@ -411,13 +474,15 @@ Note: we do not have explicit unassign, - } - if (be.fcs_in != BR2684_FCSIN_NO || be.fcs_out != BR2684_FCSOUT_NO || - be.fcs_auto || be.has_vpiid || be.send_padding || (be.encaps != -- BR2684_ENCAPS_VC && be.encaps != BR2684_ENCAPS_LLC) || -- be.min_size != 0) { -+ BR2684_ENCAPS_VC -+ && be.encaps != -+ BR2684_ENCAPS_LLC) -+ || be.min_size != 0) { - err = -EINVAL; - goto error; - } -- pr_debug("br2684_regvcc vcc=%p, encaps=%d, brvcc=%p\n", atmvcc, be.encaps, -- brvcc); -+ pr_debug("br2684_regvcc vcc=%p, encaps=%d, brvcc=%p\n", atmvcc, -+ be.encaps, brvcc); - if (list_empty(&brdev->brvccs) && !brdev->mac_was_set) { - unsigned char *esi = atmvcc->dev->esi; - if (esi[0] | esi[1] | esi[2] | esi[3] | esi[4] | esi[5]) -@@ -430,7 +495,7 @@ Note: we do not have explicit unassign, - brvcc->device = net_dev; - brvcc->atmvcc = atmvcc; - atmvcc->user_back = brvcc; -- brvcc->encaps = (enum br2684_encaps) be.encaps; -+ brvcc->encaps = (enum br2684_encaps)be.encaps; - brvcc->old_push = atmvcc->push; - barrier(); - atmvcc->push = br2684_push; -@@ -461,7 +526,7 @@ Note: we do not have explicit unassign, - } - __module_get(THIS_MODULE); - return 0; -- error: -+ error: - write_unlock_irq(&devs_lock); - kfree(brvcc); - return err; -@@ -482,25 +547,52 @@ static void br2684_setup(struct net_devi - INIT_LIST_HEAD(&brdev->brvccs); - } - --static int br2684_create(void __user *arg) -+static void br2684_setup_routed(struct net_device *netdev) -+{ -+ struct br2684_dev *brdev = BRPRIV(netdev); -+ brdev->net_dev = netdev; -+ -+ netdev->hard_header_len = 0; -+ my_eth_mac_addr = netdev->set_mac_address; -+ netdev->set_mac_address = br2684_mac_addr; -+ netdev->hard_start_xmit = br2684_start_xmit; -+ netdev->get_stats = br2684_get_stats; -+ netdev->addr_len = 0; -+ netdev->mtu = 1500; -+ netdev->type = ARPHRD_PPP; -+ netdev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST; -+ netdev->tx_queue_len = 100; -+ INIT_LIST_HEAD(&brdev->brvccs); -+} -+ -+static int br2684_create(void __user * arg) - { - int err; - struct net_device *netdev; - struct br2684_dev *brdev; - struct atm_newif_br2684 ni; -+ enum br2684_payload payload; - - pr_debug("br2684_create\n"); - - if (copy_from_user(&ni, arg, sizeof ni)) { - return -EFAULT; - } -+ -+ if (ni.media & BR2684_FLAG_ROUTED) -+ payload = p_routed; -+ else -+ payload = p_bridged; -+ ni.media &= 0xffff; /* strip flags */ -+ - if (ni.media != BR2684_MEDIA_ETHERNET || ni.mtu != 1500) { - return -EINVAL; - } - - netdev = alloc_netdev(sizeof(struct br2684_dev), - ni.ifname[0] ? ni.ifname : "nas%d", -- br2684_setup); -+ (payload == p_routed) ? -+ br2684_setup_routed : br2684_setup); - if (!netdev) - return -ENOMEM; - -@@ -516,6 +608,7 @@ static int br2684_create(void __user *ar - } - - write_lock_irq(&devs_lock); -+ brdev->payload = payload; - brdev->number = list_empty(&br2684_devs) ? 1 : - BRPRIV(list_entry_brdev(br2684_devs.prev))->number + 1; - list_add_tail(&brdev->br2684_devs, &br2684_devs); -@@ -528,16 +621,16 @@ static int br2684_create(void __user *ar - * -ENOIOCTLCMD for any unrecognized ioctl - */ - static int br2684_ioctl(struct socket *sock, unsigned int cmd, -- unsigned long arg) -+ unsigned long arg) - { - struct atm_vcc *atmvcc = ATM_SD(sock); - void __user *argp = (void __user *)arg; -+ atm_backend_t b; - - int err; -- switch(cmd) { -+ switch (cmd) { - case ATM_SETBACKEND: -- case ATM_NEWBACKENDIF: { -- atm_backend_t b; -+ case ATM_NEWBACKENDIF: - err = get_user(b, (atm_backend_t __user *) argp); - if (err) - return -EFAULT; -@@ -549,7 +642,6 @@ static int br2684_ioctl(struct socket *s - return br2684_regvcc(atmvcc, argp); - else - return br2684_create(argp); -- } - #ifdef CONFIG_ATM_BR2684_IPFILTER - case BR2684_SETFILT: - if (atmvcc->push != br2684_push) -@@ -557,6 +649,7 @@ static int br2684_ioctl(struct socket *s - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - err = br2684_setfilt(atmvcc, argp); -+ - return err; - #endif /* CONFIG_ATM_BR2684_IPFILTER */ - } -@@ -564,24 +657,25 @@ static int br2684_ioctl(struct socket *s - } - - static struct atm_ioctl br2684_ioctl_ops = { -- .owner = THIS_MODULE, -- .ioctl = br2684_ioctl, -+ .owner = THIS_MODULE, -+ .ioctl = br2684_ioctl, - }; - -- - #ifdef CONFIG_PROC_FS --static void *br2684_seq_start(struct seq_file *seq, loff_t *pos) -+static void *br2684_seq_start(struct seq_file *seq, loff_t * pos) -+ __acquires(devs_lock) - { - read_lock(&devs_lock); - return seq_list_start(&br2684_devs, *pos); - } - --static void *br2684_seq_next(struct seq_file *seq, void *v, loff_t *pos) -+static void *br2684_seq_next(struct seq_file *seq, void *v, loff_t * pos) - { - return seq_list_next(v, &br2684_devs, pos); - } - - static void br2684_seq_stop(struct seq_file *seq, void *v) -+ __releases(devs_lock) - { - read_unlock(&devs_lock); - } -@@ -589,7 +683,7 @@ static void br2684_seq_stop(struct seq_f - static int br2684_seq_show(struct seq_file *seq, void *v) - { - const struct br2684_dev *brdev = list_entry(v, struct br2684_dev, -- br2684_devs); -+ br2684_devs); - const struct net_device *net_dev = brdev->net_dev; - const struct br2684_vcc *brvcc; - DECLARE_MAC_BUF(mac); -@@ -601,21 +695,19 @@ static int br2684_seq_show(struct seq_fi - brdev->mac_was_set ? "set" : "auto"); - - list_for_each_entry(brvcc, &brdev->brvccs, brvccs) { -- seq_printf(seq, " vcc %d.%d.%d: encaps=%s" -- ", failed copies %u/%u" -- "\n", brvcc->atmvcc->dev->number, -- brvcc->atmvcc->vpi, brvcc->atmvcc->vci, -- (brvcc->encaps == e_llc) ? "LLC" : "VC" -- , brvcc->copies_failed -- , brvcc->copies_needed -- ); -+ seq_printf(seq, " vcc %d.%d.%d: encaps=%s payload=%s" -+ ", failed copies %u/%u" -+ "\n", brvcc->atmvcc->dev->number, -+ brvcc->atmvcc->vpi, brvcc->atmvcc->vci, -+ (brvcc->encaps == e_llc) ? "LLC" : "VC", -+ (brdev->payload == p_bridged) ? "bridged" : "routed", -+ brvcc->copies_failed, brvcc->copies_needed); - #ifdef CONFIG_ATM_BR2684_IPFILTER - #define b1(var, byte) ((u8 *) &brvcc->filter.var)[byte] - #define bs(var) b1(var, 0), b1(var, 1), b1(var, 2), b1(var, 3) -- if (brvcc->filter.netmask != 0) -- seq_printf(seq, " filter=%d.%d.%d.%d/" -- "%d.%d.%d.%d\n", -- bs(prefix), bs(netmask)); -+ if (brvcc->filter.netmask != 0) -+ seq_printf(seq, " filter=%d.%d.%d.%d/" -+ "%d.%d.%d.%d\n", bs(prefix), bs(netmask)); - #undef bs - #undef b1 - #endif /* CONFIG_ATM_BR2684_IPFILTER */ -@@ -625,9 +717,9 @@ static int br2684_seq_show(struct seq_fi - - static const struct seq_operations br2684_seq_ops = { - .start = br2684_seq_start, -- .next = br2684_seq_next, -- .stop = br2684_seq_stop, -- .show = br2684_seq_show, -+ .next = br2684_seq_next, -+ .stop = br2684_seq_stop, -+ .show = br2684_seq_show, - }; - - static int br2684_proc_open(struct inode *inode, struct file *file) -@@ -636,26 +728,28 @@ static int br2684_proc_open(struct inode - } - - static const struct file_operations br2684_proc_ops = { -- .owner = THIS_MODULE, -- .open = br2684_proc_open, -- .read = seq_read, -- .llseek = seq_lseek, -+ .owner = THIS_MODULE, -+ .open = br2684_proc_open, -+ .read = seq_read, -+ .llseek = seq_lseek, - .release = seq_release, - }; - - extern struct proc_dir_entry *atm_proc_root; /* from proc.c */ --#endif -+#endif /* CONFIG_PROC_FS */ - - static int __init br2684_init(void) - { - #ifdef CONFIG_PROC_FS - struct proc_dir_entry *p; -+ - if ((p = create_proc_entry("br2684", 0, atm_proc_root)) == NULL) -- return -ENOMEM; -- p->proc_fops = &br2684_proc_ops; -+ return -ENOMEM; -+ p->proc_fops = &br2684_proc_ops; - #endif -- register_atm_ioctl(&br2684_ioctl_ops); -- return 0; -+ register_atm_ioctl(&br2684_ioctl_ops); -+ return 0; -+ - } - - static void __exit br2684_exit(void) -@@ -689,3 +783,4 @@ module_exit(br2684_exit); - MODULE_AUTHOR("Marcell GAL"); - MODULE_DESCRIPTION("RFC2684 bridged protocols over ATM/AAL5"); - MODULE_LICENSE("GPL"); -+ diff --git a/target/linux/generic-2.6/patches-2.6.24/700-powerpc_git.patch b/target/linux/generic-2.6/patches-2.6.24/700-powerpc_git.patch deleted file mode 100644 index 7524eb3192..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/700-powerpc_git.patch +++ /dev/null @@ -1,71017 +0,0 @@ ---- a/Documentation/kernel-parameters.txt -+++ b/Documentation/kernel-parameters.txt -@@ -686,6 +686,7 @@ and is between 256 and 4096 characters. - See Documentation/isdn/README.HiSax. - - hugepages= [HW,X86-32,IA-64] Maximal number of HugeTLB pages. -+ hugepagesz= [HW,IA-64,PPC] The size of the HugeTLB pages. - - i8042.direct [HW] Put keyboard port into non-translated mode - i8042.dumbkbd [HW] Pretend that controller can only read data from ---- a/Documentation/powerpc/00-INDEX -+++ b/Documentation/powerpc/00-INDEX -@@ -28,3 +28,6 @@ sound.txt - - info on sound support under Linux/PPC - zImage_layout.txt - - info on the kernel images for Linux/PPC -+qe_firmware.txt -+ - describes the layout of firmware binaries for the Freescale QUICC -+ Engine and the code that parses and uploads the microcode therein. ---- a/Documentation/powerpc/booting-without-of.txt -+++ b/Documentation/powerpc/booting-without-of.txt -@@ -52,7 +52,11 @@ Table of Contents - i) Freescale QUICC Engine module (QE) - j) CFI or JEDEC memory-mapped NOR flash - k) Global Utilities Block -- l) Xilinx IP cores -+ l) Freescale Communications Processor Module -+ m) Chipselect/Local Bus -+ n) 4xx/Axon EMAC ethernet nodes -+ o) Xilinx IP cores -+ p) Freescale Synchronous Serial Interface - - VII - Specifying interrupt information for devices - 1) interrupts property -@@ -671,10 +675,10 @@ device or bus to be described by the dev - - In general, the format of an address for a device is defined by the - parent bus type, based on the #address-cells and #size-cells --property. In the absence of such a property, the parent's parent --values are used, etc... The kernel requires the root node to have --those properties defining addresses format for devices directly mapped --on the processor bus. -+properties. Note that the parent's parent definitions of #address-cells -+and #size-cells are not inhereted so every node with children must specify -+them. The kernel requires the root node to have those properties defining -+addresses format for devices directly mapped on the processor bus. - - Those 2 properties define 'cells' for representing an address and a - size. A "cell" is a 32-bit number. For example, if both contain 2 -@@ -711,13 +715,14 @@ define a bus type with a more complex ad - like address space bits, you'll have to add a bus translator to the - prom_parse.c file of the recent kernels for your bus type. - --The "reg" property only defines addresses and sizes (if #size-cells --is non-0) within a given bus. In order to translate addresses upward -+The "reg" property only defines addresses and sizes (if #size-cells is -+non-0) within a given bus. In order to translate addresses upward - (that is into parent bus addresses, and possibly into CPU physical - addresses), all busses must contain a "ranges" property. If the - "ranges" property is missing at a given level, it's assumed that --translation isn't possible. The format of the "ranges" property for a --bus is a list of: -+translation isn't possible, i.e., the registers are not visible on the -+parent bus. The format of the "ranges" property for a bus is a list -+of: - - bus address, parent bus address, size - -@@ -735,6 +740,10 @@ fit in a single 32-bit word. New 32-bi - 1/1 format, unless the processor supports physical addresses greater - than 32-bits, in which case a 2/1 format is recommended. - -+Alternatively, the "ranges" property may be empty, indicating that the -+registers are visible on the parent bus using an identity mapping -+translation. In other words, the parent bus address space is the same -+as the child bus address space. - - 2) Note about "compatible" properties - ------------------------------------- -@@ -1218,16 +1227,14 @@ platforms are moved over to use the flat - - Required properties: - - reg : Offset and length of the register set for the device -- - device_type : Should be "mdio" - - compatible : Should define the compatible device type for the -- mdio. Currently, this is most likely to be "gianfar" -+ mdio. Currently, this is most likely to be "fsl,gianfar-mdio" - - Example: - - mdio@24520 { - reg = <24520 20>; -- device_type = "mdio"; -- compatible = "gianfar"; -+ compatible = "fsl,gianfar-mdio"; - - ethernet-phy@0 { - ...... -@@ -1254,6 +1261,10 @@ platforms are moved over to use the flat - services interrupts for this device. - - phy-handle : The phandle for the PHY connected to this ethernet - controller. -+ - fixed-link : where a is emulated phy id - choose any, -+ but unique to the all specified fixed-links, b is duplex - 0 half, -+ 1 full, c is link speed - d#10/d#100/d#1000, d is pause - 0 no -+ pause, 1 pause, e is asym_pause - 0 no asym_pause, 1 asym_pause. - - Recommended properties: - -@@ -1408,7 +1419,6 @@ platforms are moved over to use the flat - - Example multi port host USB controller device node : - usb@22000 { -- device_type = "usb"; - compatible = "fsl-usb2-mph"; - reg = <22000 1000>; - #address-cells = <1>; -@@ -1422,7 +1432,6 @@ platforms are moved over to use the flat - - Example dual role USB controller device node : - usb@23000 { -- device_type = "usb"; - compatible = "fsl-usb2-dr"; - reg = <23000 1000>; - #address-cells = <1>; -@@ -1586,7 +1595,6 @@ platforms are moved over to use the flat - iii) USB (Universal Serial Bus Controller) - - Required properties: -- - device_type : should be "usb". - - compatible : could be "qe_udc" or "fhci-hcd". - - mode : the could be "host" or "slave". - - reg : Offset and length of the register set for the device -@@ -1600,7 +1608,6 @@ platforms are moved over to use the flat - - Example(slave): - usb@6c0 { -- device_type = "usb"; - compatible = "qe_udc"; - reg = <6c0 40>; - interrupts = <8b 0>; -@@ -1613,7 +1620,7 @@ platforms are moved over to use the flat - - Required properties: - - device_type : should be "network", "hldc", "uart", "transparent" -- "bisync" or "atm". -+ "bisync", "atm", or "serial". - - compatible : could be "ucc_geth" or "fsl_atm" and so on. - - model : should be "UCC". - - device-id : the ucc number(1-8), corresponding to UCCx in UM. -@@ -1626,6 +1633,26 @@ platforms are moved over to use the flat - - interrupt-parent : the phandle for the interrupt controller that - services interrupts for this device. - - pio-handle : The phandle for the Parallel I/O port configuration. -+ - port-number : for UART drivers, the port number to use, between 0 and 3. -+ This usually corresponds to the /dev/ttyQE device, e.g. <0> = /dev/ttyQE0. -+ The port number is added to the minor number of the device. Unlike the -+ CPM UART driver, the port-number is required for the QE UART driver. -+ - soft-uart : for UART drivers, if specified this means the QE UART device -+ driver should use "Soft-UART" mode, which is needed on some SOCs that have -+ broken UART hardware. Soft-UART is provided via a microcode upload. -+ - rx-clock-name: the UCC receive clock source -+ "none": clock source is disabled -+ "brg1" through "brg16": clock source is BRG1-BRG16, respectively -+ "clk1" through "clk24": clock source is CLK1-CLK24, respectively -+ - tx-clock-name: the UCC transmit clock source -+ "none": clock source is disabled -+ "brg1" through "brg16": clock source is BRG1-BRG16, respectively -+ "clk1" through "clk24": clock source is CLK1-CLK24, respectively -+ The following two properties are deprecated. rx-clock has been replaced -+ with rx-clock-name, and tx-clock has been replaced with tx-clock-name. -+ Drivers that currently use the deprecated properties should continue to -+ do so, in order to support older device trees, but they should be updated -+ to check for the new properties first. - - rx-clock : represents the UCC receive clock source. - 0x00 : clock source is disabled; - 0x1~0x10 : clock source is BRG1~BRG16 respectively; -@@ -1772,6 +1799,32 @@ platforms are moved over to use the flat - }; - }; - -+ viii) Uploaded QE firmware -+ -+ If a new firwmare has been uploaded to the QE (usually by the -+ boot loader), then a 'firmware' child node should be added to the QE -+ node. This node provides information on the uploaded firmware that -+ device drivers may need. -+ -+ Required properties: -+ - id: The string name of the firmware. This is taken from the 'id' -+ member of the qe_firmware structure of the uploaded firmware. -+ Device drivers can search this string to determine if the -+ firmware they want is already present. -+ - extended-modes: The Extended Modes bitfield, taken from the -+ firmware binary. It is a 64-bit number represented -+ as an array of two 32-bit numbers. -+ - virtual-traps: The virtual traps, taken from the firmware binary. -+ It is an array of 8 32-bit numbers. -+ -+ Example: -+ -+ firmware { -+ id = "Soft-UART"; -+ extended-modes = <0 0>; -+ virtual-traps = <0 0 0 0 0 0 0 0>; -+ } -+ - j) CFI or JEDEC memory-mapped NOR flash - - Flash chips (Memory Technology Devices) are often used for solid state -@@ -2075,8 +2128,7 @@ platforms are moved over to use the flat - - Example: - localbus@f0010100 { -- compatible = "fsl,mpc8272ads-localbus", -- "fsl,mpc8272-localbus", -+ compatible = "fsl,mpc8272-localbus", - "fsl,pq2-localbus"; - #address-cells = <2>; - #size-cells = <1>; -@@ -2254,7 +2306,7 @@ platforms are moved over to use the flat - available. - For Axon: 0x0000012a - -- l) Xilinx IP cores -+ o) Xilinx IP cores - - The Xilinx EDK toolchain ships with a set of IP cores (devices) for use - in Xilinx Spartan and Virtex FPGAs. The devices cover the whole range -@@ -2276,7 +2328,7 @@ platforms are moved over to use the flat - properties of the device node. In general, device nodes for IP-cores - will take the following form: - -- (name)@(base-address) { -+ (name): (generic-name)@(base-address) { - compatible = "xlnx,(ip-core-name)-(HW_VER)" - [, (list of compatible devices), ...]; - reg = <(baseaddr) (size)>; -@@ -2286,6 +2338,9 @@ platforms are moved over to use the flat - xlnx,(parameter2) = <(int-value)>; - }; - -+ (generic-name): an open firmware-style name that describes the -+ generic class of device. Preferably, this is one word, such -+ as 'serial' or 'ethernet'. - (ip-core-name): the name of the ip block (given after the BEGIN - directive in system.mhs). Should be in lowercase - and all underscores '_' converted to dashes '-'. -@@ -2294,9 +2349,9 @@ platforms are moved over to use the flat - dropped from the parameter name, the name is converted - to lowercase and all underscore '_' characters are - converted to dashes '-'. -- (baseaddr): the C_BASEADDR parameter. -+ (baseaddr): the baseaddr parameter value (often named C_BASEADDR). - (HW_VER): from the HW_VER parameter. -- (size): equals C_HIGHADDR - C_BASEADDR + 1 -+ (size): the address range size (often C_HIGHADDR - C_BASEADDR + 1). - - Typically, the compatible list will include the exact IP core version - followed by an older IP core version which implements the same -@@ -2326,11 +2381,11 @@ platforms are moved over to use the flat - - becomes the following device tree node: - -- opb-uartlite-0@ec100000 { -+ opb_uartlite_0: serial@ec100000 { - device_type = "serial"; - compatible = "xlnx,opb-uartlite-1.00.b"; - reg = ; -- interrupt-parent = <&opb-intc>; -+ interrupt-parent = <&opb_intc_0>; - interrupts = <1 0>; // got this from the opb_intc parameters - current-speed = ; // standard serial device prop - clock-frequency = ; // standard serial device prop -@@ -2339,16 +2394,19 @@ platforms are moved over to use the flat - xlnx,use-parity = <0>; - }; - -- Some IP cores actually implement 2 or more logical devices. In this case, -- the device should still describe the whole IP core with a single node -- and add a child node for each logical device. The ranges property can -- be used to translate from parent IP-core to the registers of each device. -- (Note: this makes the assumption that both logical devices have the same -- bus binding. If this is not true, then separate nodes should be used for -- each logical device). The 'cell-index' property can be used to enumerate -- logical devices within an IP core. For example, the following is the -- system.mhs entry for the dual ps2 controller found on the ml403 reference -- design. -+ Some IP cores actually implement 2 or more logical devices. In -+ this case, the device should still describe the whole IP core with -+ a single node and add a child node for each logical device. The -+ ranges property can be used to translate from parent IP-core to the -+ registers of each device. In addition, the parent node should be -+ compatible with the bus type 'xlnx,compound', and should contain -+ #address-cells and #size-cells, as with any other bus. (Note: this -+ makes the assumption that both logical devices have the same bus -+ binding. If this is not true, then separate nodes should be used -+ for each logical device). The 'cell-index' property can be used to -+ enumerate logical devices within an IP core. For example, the -+ following is the system.mhs entry for the dual ps2 controller found -+ on the ml403 reference design. - - BEGIN opb_ps2_dual_ref - PARAMETER INSTANCE = opb_ps2_dual_ref_0 -@@ -2370,21 +2428,24 @@ platforms are moved over to use the flat - - It would result in the following device tree nodes: - -- opb_ps2_dual_ref_0@a9000000 { -+ opb_ps2_dual_ref_0: opb-ps2-dual-ref@a9000000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "xlnx,compound"; - ranges = <0 a9000000 2000>; - // If this device had extra parameters, then they would - // go here. - ps2@0 { - compatible = "xlnx,opb-ps2-dual-ref-1.00.a"; - reg = <0 40>; -- interrupt-parent = <&opb-intc>; -+ interrupt-parent = <&opb_intc_0>; - interrupts = <3 0>; - cell-index = <0>; - }; - ps2@1000 { - compatible = "xlnx,opb-ps2-dual-ref-1.00.a"; - reg = <1000 40>; -- interrupt-parent = <&opb-intc>; -+ interrupt-parent = <&opb_intc_0>; - interrupts = <3 0>; - cell-index = <0>; - }; -@@ -2447,17 +2508,18 @@ platforms are moved over to use the flat - - Gives this device tree (some properties removed for clarity): - -- plb-v34-0 { -+ plb@0 { - #address-cells = <1>; - #size-cells = <1>; -+ compatible = "xlnx,plb-v34-1.02.a"; - device_type = "ibm,plb"; - ranges; // 1:1 translation - -- plb-bram-if-cntrl-0@ffff0000 { -+ plb_bram_if_cntrl_0: bram@ffff0000 { - reg = ; - } - -- opb-v20-0 { -+ opb@20000000 { - #address-cells = <1>; - #size-cells = <1>; - ranges = <20000000 20000000 20000000 -@@ -2465,11 +2527,11 @@ platforms are moved over to use the flat - 80000000 80000000 40000000 - c0000000 c0000000 20000000>; - -- opb-uart16550-0@a0000000 { -+ opb_uart16550_0: serial@a0000000 { - reg = ; - }; - -- opb-intc-0@d1000fc0 { -+ opb_intc_0: interrupt-controller@d1000fc0 { - reg = ; - }; - }; -@@ -2514,6 +2576,46 @@ platforms are moved over to use the flat - Requred properties: - - current-speed : Baud rate of uartlite - -+ p) Freescale Synchronous Serial Interface -+ -+ The SSI is a serial device that communicates with audio codecs. It can -+ be programmed in AC97, I2S, left-justified, or right-justified modes. -+ -+ Required properties: -+ - compatible : compatible list, containing "fsl,ssi" -+ - cell-index : the SSI, <0> = SSI1, <1> = SSI2, and so on -+ - reg : offset and length of the register set for the device -+ - interrupts : where a is the interrupt number and b is a -+ field that represents an encoding of the sense and -+ level information for the interrupt. This should be -+ encoded based on the information in section 2) -+ depending on the type of interrupt controller you -+ have. -+ - interrupt-parent : the phandle for the interrupt controller that -+ services interrupts for this device. -+ - fsl,mode : the operating mode for the SSI interface -+ "i2s-slave" - I2S mode, SSI is clock slave -+ "i2s-master" - I2S mode, SSI is clock master -+ "lj-slave" - left-justified mode, SSI is clock slave -+ "lj-master" - l.j. mode, SSI is clock master -+ "rj-slave" - right-justified mode, SSI is clock slave -+ "rj-master" - r.j., SSI is clock master -+ "ac97-slave" - AC97 mode, SSI is clock slave -+ "ac97-master" - AC97 mode, SSI is clock master -+ -+ Optional properties: -+ - codec-handle : phandle to a 'codec' node that defines an audio -+ codec connected to this SSI. This node is typically -+ a child of an I2C or other control node. -+ -+ Child 'codec' node required properties: -+ - compatible : compatible list, contains the name of the codec -+ -+ Child 'codec' node optional properties: -+ - clock-frequency : The frequency of the input clock, which typically -+ comes from an on-board dedicated oscillator. -+ -+ - More devices will be defined as this spec matures. - - VII - Specifying interrupt information for devices ---- /dev/null -+++ b/Documentation/powerpc/qe_firmware.txt -@@ -0,0 +1,295 @@ -+ Freescale QUICC Engine Firmware Uploading -+ ----------------------------------------- -+ -+(c) 2007 Timur Tabi , -+ Freescale Semiconductor -+ -+Table of Contents -+================= -+ -+ I - Software License for Firmware -+ -+ II - Microcode Availability -+ -+ III - Description and Terminology -+ -+ IV - Microcode Programming Details -+ -+ V - Firmware Structure Layout -+ -+ VI - Sample Code for Creating Firmware Files -+ -+Revision Information -+==================== -+ -+November 30, 2007: Rev 1.0 - Initial version -+ -+I - Software License for Firmware -+================================= -+ -+Each firmware file comes with its own software license. For information on -+the particular license, please see the license text that is distributed with -+the firmware. -+ -+II - Microcode Availability -+=========================== -+ -+Firmware files are distributed through various channels. Some are available on -+http://opensource.freescale.com. For other firmware files, please contact -+your Freescale representative or your operating system vendor. -+ -+III - Description and Terminology -+================================ -+ -+In this document, the term 'microcode' refers to the sequence of 32-bit -+integers that compose the actual QE microcode. -+ -+The term 'firmware' refers to a binary blob that contains the microcode as -+well as other data that -+ -+ 1) describes the microcode's purpose -+ 2) describes how and where to upload the microcode -+ 3) specifies the values of various registers -+ 4) includes additional data for use by specific device drivers -+ -+Firmware files are binary files that contain only a firmware. -+ -+IV - Microcode Programming Details -+=================================== -+ -+The QE architecture allows for only one microcode present in I-RAM for each -+RISC processor. To replace any current microcode, a full QE reset (which -+disables the microcode) must be performed first. -+ -+QE microcode is uploaded using the following procedure: -+ -+1) The microcode is placed into I-RAM at a specific location, using the -+ IRAM.IADD and IRAM.IDATA registers. -+ -+2) The CERCR.CIR bit is set to 0 or 1, depending on whether the firmware -+ needs split I-RAM. Split I-RAM is only meaningful for SOCs that have -+ QEs with multiple RISC processors, such as the 8360. Splitting the I-RAM -+ allows each processor to run a different microcode, effectively creating an -+ asymmetric multiprocessing (AMP) system. -+ -+3) The TIBCR trap registers are loaded with the addresses of the trap handlers -+ in the microcode. -+ -+4) The RSP.ECCR register is programmed with the value provided. -+ -+5) If necessary, device drivers that need the virtual traps and extended mode -+ data will use them. -+ -+Virtual Microcode Traps -+ -+These virtual traps are conditional branches in the microcode. These are -+"soft" provisional introduced in the ROMcode in order to enable higher -+flexibility and save h/w traps If new features are activated or an issue is -+being fixed in the RAM package utilizing they should be activated. This data -+structure signals the microcode which of these virtual traps is active. -+ -+This structure contains 6 words that the application should copy to some -+specific been defined. This table describes the structure. -+ -+ --------------------------------------------------------------- -+ | Offset in | | Destination Offset | Size of | -+ | array | Protocol | within PRAM | Operand | -+ --------------------------------------------------------------| -+ | 0 | Ethernet | 0xF8 | 4 bytes | -+ | | interworking | | | -+ --------------------------------------------------------------- -+ | 4 | ATM | 0xF8 | 4 bytes | -+ | | interworking | | | -+ --------------------------------------------------------------- -+ | 8 | PPP | 0xF8 | 4 bytes | -+ | | interworking | | | -+ --------------------------------------------------------------- -+ | 12 | Ethernet RX | 0x22 | 1 byte | -+ | | Distributor Page | | | -+ --------------------------------------------------------------- -+ | 16 | ATM Globtal | 0x28 | 1 byte | -+ | | Params Table | | | -+ --------------------------------------------------------------- -+ | 20 | Insert Frame | 0xF8 | 4 bytes | -+ --------------------------------------------------------------- -+ -+ -+Extended Modes -+ -+This is a double word bit array (64 bits) that defines special functionality -+which has an impact on the softwarew drivers. Each bit has its own impact -+and has special instructions for the s/w associated with it. This structure is -+described in this table: -+ -+ ----------------------------------------------------------------------- -+ | Bit # | Name | Description | -+ ----------------------------------------------------------------------- -+ | 0 | General | Indicates that prior to each host command | -+ | | push command | given by the application, the software must | -+ | | | assert a special host command (push command)| -+ | | | CECDR = 0x00800000. | -+ | | | CECR = 0x01c1000f. | -+ ----------------------------------------------------------------------- -+ | 1 | UCC ATM | Indicates that after issuing ATM RX INIT | -+ | | RX INIT | command, the host must issue another special| -+ | | push command | command (push command) and immediately | -+ | | | following that re-issue the ATM RX INIT | -+ | | | command. (This makes the sequence of | -+ | | | initializing the ATM receiver a sequence of | -+ | | | three host commands) | -+ | | | CECDR = 0x00800000. | -+ | | | CECR = 0x01c1000f. | -+ ----------------------------------------------------------------------- -+ | 2 | Add/remove | Indicates that following the specific host | -+ | | command | command: "Add/Remove entry in Hash Lookup | -+ | | validation | Table" used in Interworking setup, the user | -+ | | | must issue another command. | -+ | | | CECDR = 0xce000003. | -+ | | | CECR = 0x01c10f58. | -+ ----------------------------------------------------------------------- -+ | 3 | General push | Indicates that the s/w has to initialize | -+ | | command | some pointers in the Ethernet thread pages | -+ | | | which are used when Header Compression is | -+ | | | activated. The full details of these | -+ | | | pointers is located in the software drivers.| -+ ----------------------------------------------------------------------- -+ | 4 | General push | Indicates that after issuing Ethernet TX | -+ | | command | INIT command, user must issue this command | -+ | | | for each SNUM of Ethernet TX thread. | -+ | | | CECDR = 0x00800003. | -+ | | | CECR = 0x7'b{0}, 8'b{Enet TX thread SNUM}, | -+ | | | 1'b{1}, 12'b{0}, 4'b{1} | -+ ----------------------------------------------------------------------- -+ | 5 - 31 | N/A | Reserved, set to zero. | -+ ----------------------------------------------------------------------- -+ -+V - Firmware Structure Layout -+============================== -+ -+QE microcode from Freescale is typically provided as a header file. This -+header file contains macros that define the microcode binary itself as well as -+some other data used in uploading that microcode. The format of these files -+do not lend themselves to simple inclusion into other code. Hence, -+the need for a more portable format. This section defines that format. -+ -+Instead of distributing a header file, the microcode and related data are -+embedded into a binary blob. This blob is passed to the qe_upload_firmware() -+function, which parses the blob and performs everything necessary to upload -+the microcode. -+ -+All integers are big-endian. See the comments for function -+qe_upload_firmware() for up-to-date implementation information. -+ -+This structure supports versioning, where the version of the structure is -+embedded into the structure itself. To ensure forward and backwards -+compatibility, all versions of the structure must use the same 'qe_header' -+structure at the beginning. -+ -+'header' (type: struct qe_header): -+ The 'length' field is the size, in bytes, of the entire structure, -+ including all the microcode embedded in it, as well as the CRC (if -+ present). -+ -+ The 'magic' field is an array of three bytes that contains the letters -+ 'Q', 'E', and 'F'. This is an identifier that indicates that this -+ structure is a QE Firmware structure. -+ -+ The 'version' field is a single byte that indicates the version of this -+ structure. If the layout of the structure should ever need to be -+ changed to add support for additional types of microcode, then the -+ version number should also be changed. -+ -+The 'id' field is a null-terminated string(suitable for printing) that -+identifies the firmware. -+ -+The 'count' field indicates the number of 'microcode' structures. There -+must be one and only one 'microcode' structure for each RISC processor. -+Therefore, this field also represents the number of RISC processors for this -+SOC. -+ -+The 'soc' structure contains the SOC numbers and revisions used to match -+the microcode to the SOC itself. Normally, the microcode loader should -+check the data in this structure with the SOC number and revisions, and -+only upload the microcode if there's a match. However, this check is not -+made on all platforms. -+ -+Although it is not recommended, you can specify '0' in the soc.model -+field to skip matching SOCs altogether. -+ -+The 'model' field is a 16-bit number that matches the actual SOC. The -+'major' and 'minor' fields are the major and minor revision numbrs, -+respectively, of the SOC. -+ -+For example, to match the 8323, revision 1.0: -+ soc.model = 8323 -+ soc.major = 1 -+ soc.minor = 0 -+ -+'padding' is neccessary for structure alignment. This field ensures that the -+'extended_modes' field is aligned on a 64-bit boundary. -+ -+'extended_modes' is a bitfield that defines special functionality which has an -+impact on the device drivers. Each bit has its own impact and has special -+instructions for the driver associated with it. This field is stored in -+the QE library and available to any driver that calles qe_get_firmware_info(). -+ -+'vtraps' is an array of 8 words that contain virtual trap values for each -+virtual traps. As with 'extended_modes', this field is stored in the QE -+library and available to any driver that calles qe_get_firmware_info(). -+ -+'microcode' (type: struct qe_microcode): -+ For each RISC processor there is one 'microcode' structure. The first -+ 'microcode' structure is for the first RISC, and so on. -+ -+ The 'id' field is a null-terminated string suitable for printing that -+ identifies this particular microcode. -+ -+ 'traps' is an array of 16 words that contain hardware trap values -+ for each of the 16 traps. If trap[i] is 0, then this particular -+ trap is to be ignored (i.e. not written to TIBCR[i]). The entire value -+ is written as-is to the TIBCR[i] register, so be sure to set the EN -+ and T_IBP bits if necessary. -+ -+ 'eccr' is the value to program into the ECCR register. -+ -+ 'iram_offset' is the offset into IRAM to start writing the -+ microcode. -+ -+ 'count' is the number of 32-bit words in the microcode. -+ -+ 'code_offset' is the offset, in bytes, from the beginning of this -+ structure where the microcode itself can be found. The first -+ microcode binary should be located immediately after the 'microcode' -+ array. -+ -+ 'major', 'minor', and 'revision' are the major, minor, and revision -+ version numbers, respectively, of the microcode. If all values are 0, -+ then these fields are ignored. -+ -+ 'reserved' is necessary for structure alignment. Since 'microcode' -+ is an array, the 64-bit 'extended_modes' field needs to be aligned -+ on a 64-bit boundary, and this can only happen if the size of -+ 'microcode' is a multiple of 8 bytes. To ensure that, we add -+ 'reserved'. -+ -+After the last microcode is a 32-bit CRC. It can be calculated using -+this algorithm: -+ -+u32 crc32(const u8 *p, unsigned int len) -+{ -+ unsigned int i; -+ u32 crc = 0; -+ -+ while (len--) { -+ crc ^= *p++; -+ for (i = 0; i < 8; i++) -+ crc = (crc >> 1) ^ ((crc & 1) ? 0xedb88320 : 0); -+ } -+ return crc; -+} -+ -+VI - Sample Code for Creating Firmware Files -+============================================ -+ -+A Python program that creates firmware binaries from the header files normally -+distributed by Freescale can be found on http://opensource.freescale.com. ---- a/arch/powerpc/Kconfig -+++ b/arch/powerpc/Kconfig -@@ -140,6 +140,9 @@ config DEFAULT_UIMAGE - Used to allow a board to specify it wants a uImage built by default - default n - -+config REDBOOT -+ bool -+ - config PPC64_SWSUSP - bool - depends on PPC64 && (BROKEN || (PPC_PMAC64 && EXPERIMENTAL)) -@@ -160,11 +163,13 @@ config PPC_DCR - - config PPC_OF_PLATFORM_PCI - bool -+ depends on PCI - depends on PPC64 # not supported on 32 bits yet - default n - - source "init/Kconfig" - -+source "arch/powerpc/sysdev/Kconfig" - source "arch/powerpc/platforms/Kconfig" - - menu "Kernel options" -@@ -417,7 +422,7 @@ endmenu - - config ISA_DMA_API - bool -- default y -+ default !PPC_ISERIES || PCI - - menu "Bus options" - -@@ -467,7 +472,7 @@ config MCA - config PCI - bool "PCI support" if 40x || CPM2 || PPC_83xx || PPC_85xx || PPC_86xx \ - || PPC_MPC52xx || (EMBEDDED && (PPC_PSERIES || PPC_ISERIES)) \ -- || PPC_PS3 -+ || PPC_PS3 || 44x - default y if !40x && !CPM2 && !8xx && !PPC_83xx \ - && !PPC_85xx && !PPC_86xx - default PCI_PERMEDIA if !4xx && !CPM2 && !8xx ---- a/arch/powerpc/Kconfig.debug -+++ b/arch/powerpc/Kconfig.debug -@@ -151,6 +151,13 @@ config BOOTX_TEXT - - config PPC_EARLY_DEBUG - bool "Early debugging (dangerous)" -+ help -+ Say Y to enable some early debugging facilities that may be available -+ for your processor/board combination. Those facilities are hacks -+ intended to debug problems early during boot, this should not be -+ enabled in a production kernel. -+ Note that enabling this will also cause the kernel default log level -+ to be pushed to max automatically very early during boot - - choice - prompt "Early debugging console" -@@ -218,7 +225,16 @@ config PPC_EARLY_DEBUG_44x - depends on 44x - help - Select this to enable early debugging for IBM 44x chips via the -- inbuilt serial port. -+ inbuilt serial port. If you enable this, ensure you set -+ PPC_EARLY_DEBUG_44x_PHYSLOW below to suit your target board. -+ -+config PPC_EARLY_DEBUG_40x -+ bool "Early serial debugging for IBM/AMCC 40x CPUs" -+ depends on 40x -+ help -+ Select this to enable early debugging for IBM 40x chips via the -+ inbuilt serial port. This works on chips with a 16550 compatible -+ UART. Xilinx chips with uartlite cannot use this option. - - config PPC_EARLY_DEBUG_CPM - bool "Early serial debugging for Freescale CPM-based serial ports" -@@ -235,12 +251,20 @@ config PPC_EARLY_DEBUG_44x_PHYSLOW - hex "Low 32 bits of early debug UART physical address" - depends on PPC_EARLY_DEBUG_44x - default "0x40000200" -+ help -+ You probably want 0x40000200 for ebony boards and -+ 0x40000300 for taishan - - config PPC_EARLY_DEBUG_44x_PHYSHIGH - hex "EPRN of early debug UART physical address" - depends on PPC_EARLY_DEBUG_44x - default "0x1" - -+config PPC_EARLY_DEBUG_40x_PHYSADDR -+ hex "Early debug UART physical address" -+ depends on PPC_EARLY_DEBUG_40x -+ default "0xef600300" -+ - config PPC_EARLY_DEBUG_CPM_ADDR - hex "CPM UART early debug transmit descriptor address" - depends on PPC_EARLY_DEBUG_CPM ---- a/arch/powerpc/Makefile -+++ b/arch/powerpc/Makefile -@@ -167,6 +167,9 @@ boot := arch/$(ARCH)/boot - $(BOOT_TARGETS): vmlinux - $(Q)$(MAKE) ARCH=ppc64 $(build)=$(boot) $(patsubst %,$(boot)/%,$@) - -+bootwrapper_install: -+ $(Q)$(MAKE) ARCH=ppc64 $(build)=$(boot) $(patsubst %,$(boot)/%,$@) -+ - define archhelp - @echo '* zImage - Compressed kernel image (arch/$(ARCH)/boot/zImage.*)' - @echo ' install - Install kernel using' ---- a/arch/powerpc/boot/4xx.c -+++ b/arch/powerpc/boot/4xx.c -@@ -22,16 +22,14 @@ - #include "dcr.h" - - /* Read the 4xx SDRAM controller to get size of system memory. */ --void ibm4xx_fixup_memsize(void) -+void ibm4xx_sdram_fixup_memsize(void) - { - int i; - unsigned long memsize, bank_config; - - memsize = 0; - for (i = 0; i < ARRAY_SIZE(sdram_bxcr); i++) { -- mtdcr(DCRN_SDRAM0_CFGADDR, sdram_bxcr[i]); -- bank_config = mfdcr(DCRN_SDRAM0_CFGDATA); -- -+ bank_config = SDRAM0_READ(sdram_bxcr[i]); - if (bank_config & SDRAM_CONFIG_BANK_ENABLE) - memsize += SDRAM_CONFIG_BANK_SIZE(bank_config); - } -@@ -39,6 +37,69 @@ void ibm4xx_fixup_memsize(void) - dt_fixup_memory(0, memsize); - } - -+/* Read the 440SPe MQ controller to get size of system memory. */ -+#define DCRN_MQ0_B0BAS 0x40 -+#define DCRN_MQ0_B1BAS 0x41 -+#define DCRN_MQ0_B2BAS 0x42 -+#define DCRN_MQ0_B3BAS 0x43 -+ -+static u64 ibm440spe_decode_bas(u32 bas) -+{ -+ u64 base = ((u64)(bas & 0xFFE00000u)) << 2; -+ -+ /* open coded because I'm paranoid about invalid values */ -+ switch ((bas >> 4) & 0xFFF) { -+ case 0: -+ return 0; -+ case 0xffc: -+ return base + 0x000800000ull; -+ case 0xff8: -+ return base + 0x001000000ull; -+ case 0xff0: -+ return base + 0x002000000ull; -+ case 0xfe0: -+ return base + 0x004000000ull; -+ case 0xfc0: -+ return base + 0x008000000ull; -+ case 0xf80: -+ return base + 0x010000000ull; -+ case 0xf00: -+ return base + 0x020000000ull; -+ case 0xe00: -+ return base + 0x040000000ull; -+ case 0xc00: -+ return base + 0x080000000ull; -+ case 0x800: -+ return base + 0x100000000ull; -+ } -+ printf("Memory BAS value 0x%08x unsupported !\n", bas); -+ return 0; -+} -+ -+void ibm440spe_fixup_memsize(void) -+{ -+ u64 banktop, memsize = 0; -+ -+ /* Ultimately, we should directly construct the memory node -+ * so we are able to handle holes in the memory address space -+ */ -+ banktop = ibm440spe_decode_bas(mfdcr(DCRN_MQ0_B0BAS)); -+ if (banktop > memsize) -+ memsize = banktop; -+ banktop = ibm440spe_decode_bas(mfdcr(DCRN_MQ0_B1BAS)); -+ if (banktop > memsize) -+ memsize = banktop; -+ banktop = ibm440spe_decode_bas(mfdcr(DCRN_MQ0_B2BAS)); -+ if (banktop > memsize) -+ memsize = banktop; -+ banktop = ibm440spe_decode_bas(mfdcr(DCRN_MQ0_B3BAS)); -+ if (banktop > memsize) -+ memsize = banktop; -+ -+ dt_fixup_memory(0, memsize); -+} -+ -+ - /* 4xx DDR1/2 Denali memory controller support */ - /* DDR0 registers */ - #define DDR0_02 2 -@@ -77,19 +138,13 @@ void ibm4xx_fixup_memsize(void) - - #define DDR_GET_VAL(val, mask, shift) (((val) >> (shift)) & (mask)) - --static inline u32 mfdcr_sdram0(u32 reg) --{ -- mtdcr(DCRN_SDRAM0_CFGADDR, reg); -- return mfdcr(DCRN_SDRAM0_CFGDATA); --} -- - void ibm4xx_denali_fixup_memsize(void) - { - u32 val, max_cs, max_col, max_row; - u32 cs, col, row, bank, dpath; - unsigned long memsize; - -- val = mfdcr_sdram0(DDR0_02); -+ val = SDRAM0_READ(DDR0_02); - if (!DDR_GET_VAL(val, DDR_START, DDR_START_SHIFT)) - fatal("DDR controller is not initialized\n"); - -@@ -99,12 +154,12 @@ void ibm4xx_denali_fixup_memsize(void) - max_row = DDR_GET_VAL(val, DDR_MAX_ROW_REG, DDR_MAX_ROW_REG_SHIFT); - - /* get CS value */ -- val = mfdcr_sdram0(DDR0_10); -+ val = SDRAM0_READ(DDR0_10); - - val = DDR_GET_VAL(val, DDR_CS_MAP, DDR_CS_MAP_SHIFT); - cs = 0; - while (val) { -- if (val && 0x1) -+ if (val & 0x1) - cs++; - val = val >> 1; - } -@@ -115,15 +170,15 @@ void ibm4xx_denali_fixup_memsize(void) - fatal("DDR wrong CS configuration\n"); - - /* get data path bytes */ -- val = mfdcr_sdram0(DDR0_14); -+ val = SDRAM0_READ(DDR0_14); - - if (DDR_GET_VAL(val, DDR_REDUC, DDR_REDUC_SHIFT)) - dpath = 8; /* 64 bits */ - else - dpath = 4; /* 32 bits */ - -- /* get adress pins (rows) */ -- val = mfdcr_sdram0(DDR0_42); -+ /* get address pins (rows) */ -+ val = SDRAM0_READ(DDR0_42); - - row = DDR_GET_VAL(val, DDR_APIN, DDR_APIN_SHIFT); - if (row > max_row) -@@ -131,7 +186,7 @@ void ibm4xx_denali_fixup_memsize(void) - row = max_row - row; - - /* get collomn size and banks */ -- val = mfdcr_sdram0(DDR0_43); -+ val = SDRAM0_READ(DDR0_43); - - col = DDR_GET_VAL(val, DDR_COL_SZ, DDR_COL_SZ_SHIFT); - if (col > max_col) -@@ -179,13 +234,17 @@ void ibm40x_dbcr_reset(void) - #define EMAC_RESET 0x20000000 - void ibm4xx_quiesce_eth(u32 *emac0, u32 *emac1) - { -- /* Quiesce the MAL and EMAC(s) since PIBS/OpenBIOS don't do this for us */ -+ /* Quiesce the MAL and EMAC(s) since PIBS/OpenBIOS don't -+ * do this for us -+ */ - if (emac0) - *emac0 = EMAC_RESET; - if (emac1) - *emac1 = EMAC_RESET; - - mtdcr(DCRN_MAL0_CFG, MAL_RESET); -+ while (mfdcr(DCRN_MAL0_CFG) & MAL_RESET) -+ ; /* loop until reset takes effect */ - } - - /* Read 4xx EBC bus bridge registers to get mappings of the peripheral -@@ -217,84 +276,335 @@ void ibm4xx_fixup_ebc_ranges(const char - setprop(devp, "ranges", ranges, (p - ranges) * sizeof(u32)); - } - --#define SPRN_CCR1 0x378 --void ibm440ep_fixup_clocks(unsigned int sysclk, unsigned int ser_clk) -+/* Calculate 440GP clocks */ -+void ibm440gp_fixup_clocks(unsigned int sys_clk, unsigned int ser_clk) - { -- u32 cpu, plb, opb, ebc, tb, uart0, m, vco; -- u32 reg; -- u32 fwdva, fwdvb, fbdv, lfbdv, opbdv0, perdv0, spcid0, prbdv0, tmp; -- -- mtdcr(DCRN_CPR0_ADDR, CPR0_PLLD0); -- reg = mfdcr(DCRN_CPR0_DATA); -- tmp = (reg & 0x000F0000) >> 16; -- fwdva = tmp ? tmp : 16; -- tmp = (reg & 0x00000700) >> 8; -- fwdvb = tmp ? tmp : 8; -- tmp = (reg & 0x1F000000) >> 24; -- fbdv = tmp ? tmp : 32; -- lfbdv = (reg & 0x0000007F); -- -- mtdcr(DCRN_CPR0_ADDR, CPR0_OPBD0); -- reg = mfdcr(DCRN_CPR0_DATA); -- tmp = (reg & 0x03000000) >> 24; -- opbdv0 = tmp ? tmp : 4; -- -- mtdcr(DCRN_CPR0_ADDR, CPR0_PERD0); -- reg = mfdcr(DCRN_CPR0_DATA); -- tmp = (reg & 0x07000000) >> 24; -- perdv0 = tmp ? tmp : 8; -- -- mtdcr(DCRN_CPR0_ADDR, CPR0_PRIMBD0); -- reg = mfdcr(DCRN_CPR0_DATA); -- tmp = (reg & 0x07000000) >> 24; -- prbdv0 = tmp ? tmp : 8; -- -- mtdcr(DCRN_CPR0_ADDR, CPR0_SCPID); -- reg = mfdcr(DCRN_CPR0_DATA); -- tmp = (reg & 0x03000000) >> 24; -- spcid0 = tmp ? tmp : 4; -- -- /* Calculate M */ -- mtdcr(DCRN_CPR0_ADDR, CPR0_PLLC0); -- reg = mfdcr(DCRN_CPR0_DATA); -- tmp = (reg & 0x03000000) >> 24; -- if (tmp == 0) { /* PLL output */ -- tmp = (reg & 0x20000000) >> 29; -- if (!tmp) /* PLLOUTA */ -- m = fbdv * lfbdv * fwdva; -+ u32 sys0 = mfdcr(DCRN_CPC0_SYS0); -+ u32 cr0 = mfdcr(DCRN_CPC0_CR0); -+ u32 cpu, plb, opb, ebc, tb, uart0, uart1, m; -+ u32 opdv = CPC0_SYS0_OPDV(sys0); -+ u32 epdv = CPC0_SYS0_EPDV(sys0); -+ -+ if (sys0 & CPC0_SYS0_BYPASS) { -+ /* Bypass system PLL */ -+ cpu = plb = sys_clk; -+ } else { -+ if (sys0 & CPC0_SYS0_EXTSL) -+ /* PerClk */ -+ m = CPC0_SYS0_FWDVB(sys0) * opdv * epdv; - else -- m = fbdv * lfbdv * fwdvb; -+ /* CPU clock */ -+ m = CPC0_SYS0_FBDV(sys0) * CPC0_SYS0_FWDVA(sys0); -+ cpu = sys_clk * m / CPC0_SYS0_FWDVA(sys0); -+ plb = sys_clk * m / CPC0_SYS0_FWDVB(sys0); - } -- else if (tmp == 1) /* CPU output */ -- m = fbdv * fwdva; -+ -+ opb = plb / opdv; -+ ebc = opb / epdv; -+ -+ /* FIXME: Check if this is for all 440GP, or just Ebony */ -+ if ((mfpvr() & 0xf0000fff) == 0x40000440) -+ /* Rev. B 440GP, use external system clock */ -+ tb = sys_clk; - else -- m = perdv0 * opbdv0 * fwdvb; -+ /* Rev. C 440GP, errata force us to use internal clock */ -+ tb = cpu; - -- vco = (m * sysclk) + (m >> 1); -- cpu = vco / fwdva; -- plb = vco / fwdvb / prbdv0; -- opb = plb / opbdv0; -- ebc = plb / perdv0; -+ if (cr0 & CPC0_CR0_U0EC) -+ /* External UART clock */ -+ uart0 = ser_clk; -+ else -+ /* Internal UART clock */ -+ uart0 = plb / CPC0_CR0_UDIV(cr0); - -- /* FIXME */ -- uart0 = ser_clk; -+ if (cr0 & CPC0_CR0_U1EC) -+ /* External UART clock */ -+ uart1 = ser_clk; -+ else -+ /* Internal UART clock */ -+ uart1 = plb / CPC0_CR0_UDIV(cr0); -+ -+ printf("PPC440GP: SysClk = %dMHz (%x)\n\r", -+ (sys_clk + 500000) / 1000000, sys_clk); -+ -+ dt_fixup_cpu_clocks(cpu, tb, 0); -+ -+ dt_fixup_clock("/plb", plb); -+ dt_fixup_clock("/plb/opb", opb); -+ dt_fixup_clock("/plb/opb/ebc", ebc); -+ dt_fixup_clock("/plb/opb/serial@40000200", uart0); -+ dt_fixup_clock("/plb/opb/serial@40000300", uart1); -+} -+ -+#define SPRN_CCR1 0x378 -+ -+static inline u32 __fix_zero(u32 v, u32 def) -+{ -+ return v ? v : def; -+} -+ -+static unsigned int __ibm440eplike_fixup_clocks(unsigned int sys_clk, -+ unsigned int tmr_clk, -+ int per_clk_from_opb) -+{ -+ /* PLL config */ -+ u32 pllc = CPR0_READ(DCRN_CPR0_PLLC); -+ u32 plld = CPR0_READ(DCRN_CPR0_PLLD); -+ -+ /* Dividers */ -+ u32 fbdv = __fix_zero((plld >> 24) & 0x1f, 32); -+ u32 fwdva = __fix_zero((plld >> 16) & 0xf, 16); -+ u32 fwdvb = __fix_zero((plld >> 8) & 7, 8); -+ u32 lfbdv = __fix_zero(plld & 0x3f, 64); -+ u32 pradv0 = __fix_zero((CPR0_READ(DCRN_CPR0_PRIMAD) >> 24) & 7, 8); -+ u32 prbdv0 = __fix_zero((CPR0_READ(DCRN_CPR0_PRIMBD) >> 24) & 7, 8); -+ u32 opbdv0 = __fix_zero((CPR0_READ(DCRN_CPR0_OPBD) >> 24) & 3, 4); -+ u32 perdv0 = __fix_zero((CPR0_READ(DCRN_CPR0_PERD) >> 24) & 3, 4); -+ -+ /* Input clocks for primary dividers */ -+ u32 clk_a, clk_b; -+ -+ /* Resulting clocks */ -+ u32 cpu, plb, opb, ebc, vco; -+ -+ /* Timebase */ -+ u32 ccr1, tb = tmr_clk; -+ -+ if (pllc & 0x40000000) { -+ u32 m; -+ -+ /* Feedback path */ -+ switch ((pllc >> 24) & 7) { -+ case 0: -+ /* PLLOUTx */ -+ m = ((pllc & 0x20000000) ? fwdvb : fwdva) * lfbdv; -+ break; -+ case 1: -+ /* CPU */ -+ m = fwdva * pradv0; -+ break; -+ case 5: -+ /* PERClk */ -+ m = fwdvb * prbdv0 * opbdv0 * perdv0; -+ break; -+ default: -+ printf("WARNING ! Invalid PLL feedback source !\n"); -+ goto bypass; -+ } -+ m *= fbdv; -+ vco = sys_clk * m; -+ clk_a = vco / fwdva; -+ clk_b = vco / fwdvb; -+ } else { -+bypass: -+ /* Bypass system PLL */ -+ vco = 0; -+ clk_a = clk_b = sys_clk; -+ } -+ -+ cpu = clk_a / pradv0; -+ plb = clk_b / prbdv0; -+ opb = plb / opbdv0; -+ ebc = (per_clk_from_opb ? opb : plb) / perdv0; - - /* Figure out timebase. Either CPU or default TmrClk */ -- asm volatile ( -- "mfspr %0,%1\n" -- : -- "=&r"(reg) : "i"(SPRN_CCR1)); -- if (reg & 0x0080) -- tb = 25000000; /* TmrClk is 25MHz */ -- else -+ ccr1 = mfspr(SPRN_CCR1); -+ -+ /* If passed a 0 tmr_clk, force CPU clock */ -+ if (tb == 0) { -+ ccr1 &= ~0x80u; -+ mtspr(SPRN_CCR1, ccr1); -+ } -+ if ((ccr1 & 0x0080) == 0) - tb = cpu; - - dt_fixup_cpu_clocks(cpu, tb, 0); - dt_fixup_clock("/plb", plb); - dt_fixup_clock("/plb/opb", opb); - dt_fixup_clock("/plb/opb/ebc", ebc); -+ -+ return plb; -+} -+ -+static void eplike_fixup_uart_clk(int index, const char *path, -+ unsigned int ser_clk, -+ unsigned int plb_clk) -+{ -+ unsigned int sdr; -+ unsigned int clock; -+ -+ switch (index) { -+ case 0: -+ sdr = SDR0_READ(DCRN_SDR0_UART0); -+ break; -+ case 1: -+ sdr = SDR0_READ(DCRN_SDR0_UART1); -+ break; -+ case 2: -+ sdr = SDR0_READ(DCRN_SDR0_UART2); -+ break; -+ case 3: -+ sdr = SDR0_READ(DCRN_SDR0_UART3); -+ break; -+ default: -+ return; -+ } -+ -+ if (sdr & 0x00800000u) -+ clock = ser_clk; -+ else -+ clock = plb_clk / __fix_zero(sdr & 0xff, 256); -+ -+ dt_fixup_clock(path, clock); -+} -+ -+void ibm440ep_fixup_clocks(unsigned int sys_clk, -+ unsigned int ser_clk, -+ unsigned int tmr_clk) -+{ -+ unsigned int plb_clk = __ibm440eplike_fixup_clocks(sys_clk, tmr_clk, 0); -+ -+ /* serial clocks beed fixup based on int/ext */ -+ eplike_fixup_uart_clk(0, "/plb/opb/serial@ef600300", ser_clk, plb_clk); -+ eplike_fixup_uart_clk(1, "/plb/opb/serial@ef600400", ser_clk, plb_clk); -+ eplike_fixup_uart_clk(2, "/plb/opb/serial@ef600500", ser_clk, plb_clk); -+ eplike_fixup_uart_clk(3, "/plb/opb/serial@ef600600", ser_clk, plb_clk); -+} -+ -+void ibm440gx_fixup_clocks(unsigned int sys_clk, -+ unsigned int ser_clk, -+ unsigned int tmr_clk) -+{ -+ unsigned int plb_clk = __ibm440eplike_fixup_clocks(sys_clk, tmr_clk, 1); -+ -+ /* serial clocks beed fixup based on int/ext */ -+ eplike_fixup_uart_clk(0, "/plb/opb/serial@40000200", ser_clk, plb_clk); -+ eplike_fixup_uart_clk(1, "/plb/opb/serial@40000300", ser_clk, plb_clk); -+} -+ -+void ibm440spe_fixup_clocks(unsigned int sys_clk, -+ unsigned int ser_clk, -+ unsigned int tmr_clk) -+{ -+ unsigned int plb_clk = __ibm440eplike_fixup_clocks(sys_clk, tmr_clk, 1); -+ -+ /* serial clocks beed fixup based on int/ext */ -+ eplike_fixup_uart_clk(0, "/plb/opb/serial@10000200", ser_clk, plb_clk); -+ eplike_fixup_uart_clk(1, "/plb/opb/serial@10000300", ser_clk, plb_clk); -+ eplike_fixup_uart_clk(2, "/plb/opb/serial@10000600", ser_clk, plb_clk); -+} -+ -+void ibm405gp_fixup_clocks(unsigned int sys_clk, unsigned int ser_clk) -+{ -+ u32 pllmr = mfdcr(DCRN_CPC0_PLLMR); -+ u32 cpc0_cr0 = mfdcr(DCRN_405_CPC0_CR0); -+ u32 cpc0_cr1 = mfdcr(DCRN_405_CPC0_CR1); -+ u32 psr = mfdcr(DCRN_405_CPC0_PSR); -+ u32 cpu, plb, opb, ebc, tb, uart0, uart1, m; -+ u32 fwdv, fwdvb, fbdv, cbdv, opdv, epdv, ppdv, udiv; -+ -+ fwdv = (8 - ((pllmr & 0xe0000000) >> 29)); -+ fbdv = (pllmr & 0x1e000000) >> 25; -+ if (fbdv == 0) -+ fbdv = 16; -+ cbdv = ((pllmr & 0x00060000) >> 17) + 1; /* CPU:PLB */ -+ opdv = ((pllmr & 0x00018000) >> 15) + 1; /* PLB:OPB */ -+ ppdv = ((pllmr & 0x00001800) >> 13) + 1; /* PLB:PCI */ -+ epdv = ((pllmr & 0x00001800) >> 11) + 2; /* PLB:EBC */ -+ udiv = ((cpc0_cr0 & 0x3e) >> 1) + 1; -+ -+ /* check for 405GPr */ -+ if ((mfpvr() & 0xfffffff0) == (0x50910951 & 0xfffffff0)) { -+ fwdvb = 8 - (pllmr & 0x00000007); -+ if (!(psr & 0x00001000)) /* PCI async mode enable == 0 */ -+ if (psr & 0x00000020) /* New mode enable */ -+ m = fwdvb * 2 * ppdv; -+ else -+ m = fwdvb * cbdv * ppdv; -+ else if (psr & 0x00000020) /* New mode enable */ -+ if (psr & 0x00000800) /* PerClk synch mode */ -+ m = fwdvb * 2 * epdv; -+ else -+ m = fbdv * fwdv; -+ else if (epdv == fbdv) -+ m = fbdv * cbdv * epdv; -+ else -+ m = fbdv * fwdvb * cbdv; -+ -+ cpu = sys_clk * m / fwdv; -+ plb = sys_clk * m / (fwdvb * cbdv); -+ } else { -+ m = fwdv * fbdv * cbdv; -+ cpu = sys_clk * m / fwdv; -+ plb = cpu / cbdv; -+ } -+ opb = plb / opdv; -+ ebc = plb / epdv; -+ -+ if (cpc0_cr0 & 0x80) -+ /* uart0 uses the external clock */ -+ uart0 = ser_clk; -+ else -+ uart0 = cpu / udiv; -+ -+ if (cpc0_cr0 & 0x40) -+ /* uart1 uses the external clock */ -+ uart1 = ser_clk; -+ else -+ uart1 = cpu / udiv; -+ -+ /* setup the timebase clock to tick at the cpu frequency */ -+ cpc0_cr1 = cpc0_cr1 & ~0x00800000; -+ mtdcr(DCRN_405_CPC0_CR1, cpc0_cr1); -+ tb = cpu; -+ -+ dt_fixup_cpu_clocks(cpu, tb, 0); -+ dt_fixup_clock("/plb", plb); -+ dt_fixup_clock("/plb/opb", opb); -+ dt_fixup_clock("/plb/ebc", ebc); -+ dt_fixup_clock("/plb/opb/serial@ef600300", uart0); -+ dt_fixup_clock("/plb/opb/serial@ef600400", uart1); -+} -+ -+ -+void ibm405ep_fixup_clocks(unsigned int sys_clk) -+{ -+ u32 pllmr0 = mfdcr(DCRN_CPC0_PLLMR0); -+ u32 pllmr1 = mfdcr(DCRN_CPC0_PLLMR1); -+ u32 cpc0_ucr = mfdcr(DCRN_CPC0_UCR); -+ u32 cpu, plb, opb, ebc, uart0, uart1; -+ u32 fwdva, fwdvb, fbdv, cbdv, opdv, epdv; -+ u32 pllmr0_ccdv, tb, m; -+ -+ fwdva = 8 - ((pllmr1 & 0x00070000) >> 16); -+ fwdvb = 8 - ((pllmr1 & 0x00007000) >> 12); -+ fbdv = (pllmr1 & 0x00f00000) >> 20; -+ if (fbdv == 0) -+ fbdv = 16; -+ -+ cbdv = ((pllmr0 & 0x00030000) >> 16) + 1; /* CPU:PLB */ -+ epdv = ((pllmr0 & 0x00000300) >> 8) + 2; /* PLB:EBC */ -+ opdv = ((pllmr0 & 0x00003000) >> 12) + 1; /* PLB:OPB */ -+ -+ m = fbdv * fwdvb; -+ -+ pllmr0_ccdv = ((pllmr0 & 0x00300000) >> 20) + 1; -+ if (pllmr1 & 0x80000000) -+ cpu = sys_clk * m / (fwdva * pllmr0_ccdv); -+ else -+ cpu = sys_clk / pllmr0_ccdv; -+ -+ plb = cpu / cbdv; -+ opb = plb / opdv; -+ ebc = plb / epdv; -+ tb = cpu; -+ uart0 = cpu / (cpc0_ucr & 0x0000007f); -+ uart1 = cpu / ((cpc0_ucr & 0x00007f00) >> 8); -+ -+ dt_fixup_cpu_clocks(cpu, tb, 0); -+ dt_fixup_clock("/plb", plb); -+ dt_fixup_clock("/plb/opb", opb); -+ dt_fixup_clock("/plb/ebc", ebc); - dt_fixup_clock("/plb/opb/serial@ef600300", uart0); -- dt_fixup_clock("/plb/opb/serial@ef600400", uart0); -- dt_fixup_clock("/plb/opb/serial@ef600500", uart0); -- dt_fixup_clock("/plb/opb/serial@ef600600", uart0); -+ dt_fixup_clock("/plb/opb/serial@ef600400", uart1); - } ---- a/arch/powerpc/boot/4xx.h -+++ b/arch/powerpc/boot/4xx.h -@@ -11,12 +11,22 @@ - #ifndef _POWERPC_BOOT_4XX_H_ - #define _POWERPC_BOOT_4XX_H_ - --void ibm4xx_fixup_memsize(void); -+void ibm4xx_sdram_fixup_memsize(void); -+void ibm440spe_fixup_memsize(void); - void ibm4xx_denali_fixup_memsize(void); - void ibm44x_dbcr_reset(void); - void ibm40x_dbcr_reset(void); - void ibm4xx_quiesce_eth(u32 *emac0, u32 *emac1); - void ibm4xx_fixup_ebc_ranges(const char *ebc); --void ibm440ep_fixup_clocks(unsigned int sysclk, unsigned int ser_clk); -+ -+void ibm405gp_fixup_clocks(unsigned int sys_clk, unsigned int ser_clk); -+void ibm405ep_fixup_clocks(unsigned int sys_clk); -+void ibm440gp_fixup_clocks(unsigned int sys_clk, unsigned int ser_clk); -+void ibm440ep_fixup_clocks(unsigned int sys_clk, unsigned int ser_clk, -+ unsigned int tmr_clk); -+void ibm440gx_fixup_clocks(unsigned int sys_clk, unsigned int ser_clk, -+ unsigned int tmr_clk); -+void ibm440spe_fixup_clocks(unsigned int sys_clk, unsigned int ser_clk, -+ unsigned int tmr_clk); - - #endif /* _POWERPC_BOOT_4XX_H_ */ ---- a/arch/powerpc/boot/Makefile -+++ b/arch/powerpc/boot/Makefile -@@ -33,12 +33,15 @@ ifeq ($(call cc-option-yn, -fstack-prote - BOOTCFLAGS += -fno-stack-protector - endif - --BOOTCFLAGS += -I$(obj) -I$(srctree)/$(obj) -+BOOTCFLAGS += -I$(obj) -I$(srctree)/$(obj) -I$(srctree)/$(src)/libfdt - - $(obj)/4xx.o: BOOTCFLAGS += -mcpu=440 - $(obj)/ebony.o: BOOTCFLAGS += -mcpu=440 -+$(obj)/cuboot-taishan.o: BOOTCFLAGS += -mcpu=440 -+$(obj)/cuboot-katmai.o: BOOTCFLAGS += -mcpu=440 - $(obj)/treeboot-walnut.o: BOOTCFLAGS += -mcpu=405 - -+ - zlib := inffast.c inflate.c inftrees.c - zlibheader := inffast.h inffixed.h inflate.h inftrees.h infutil.h - zliblinuxheader := zlib.h zconf.h zutil.h -@@ -46,17 +49,21 @@ zliblinuxheader := zlib.h zconf.h zutil. - $(addprefix $(obj)/,$(zlib) gunzip_util.o main.o): \ - $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader)) - --src-wlib := string.S crt0.S stdio.c main.c flatdevtree.c flatdevtree_misc.c \ -+src-libfdt := fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c -+src-wlib := string.S crt0.S stdio.c main.c \ -+ $(addprefix libfdt/,$(src-libfdt)) libfdt-wrapper.c \ - ns16550.c serial.c simple_alloc.c div64.S util.S \ - gunzip_util.c elf_util.c $(zlib) devtree.c oflib.c ofconsole.c \ - 4xx.c ebony.c mv64x60.c mpsc.c mv64x60_i2c.c cuboot.c bamboo.c \ - cpm-serial.c stdlib.c mpc52xx-psc.c planetcore.c uartlite.c \ - fsl-soc.c mpc8xx.c pq2.c --src-plat := of.c cuboot-52xx.c cuboot-83xx.c cuboot-85xx.c holly.c \ -+src-plat := of.c cuboot-52xx.c cuboot-824x.c cuboot-83xx.c cuboot-85xx.c holly.c \ - cuboot-ebony.c treeboot-ebony.c prpmc2800.c \ - ps3-head.S ps3-hvcall.S ps3.c treeboot-bamboo.c cuboot-8xx.c \ - cuboot-pq2.c cuboot-sequoia.c treeboot-walnut.c cuboot-bamboo.c \ -- fixed-head.S ep88xc.c cuboot-hpc2.c -+ fixed-head.S ep88xc.c cuboot-hpc2.c ep405.c cuboot-taishan.c \ -+ cuboot-katmai.c cuboot-rainier.c redboot-8xx.c ep8248e.c \ -+ cuboot-warp.c - src-boot := $(src-wlib) $(src-plat) empty.c - - src-boot := $(addprefix $(obj)/, $(src-boot)) -@@ -101,24 +108,61 @@ quiet_cmd_bootar = BOOTAR $@ - cmd_bootar = $(CROSS32AR) -cr $@.$$$$ $(filter-out FORCE,$^); mv $@.$$$$ $@ - - $(patsubst %.c,%.o, $(filter %.c, $(src-boot))): %.o: %.c FORCE -+ $(Q)mkdir -p $(dir $@) - $(call if_changed_dep,bootcc) - $(patsubst %.S,%.o, $(filter %.S, $(src-boot))): %.o: %.S FORCE -+ $(Q)mkdir -p $(dir $@) - $(call if_changed_dep,bootas) - - $(obj)/wrapper.a: $(obj-wlib) FORCE - $(call if_changed,bootar) - --hostprogs-y := addnote addRamDisk hack-coff mktree -+hostprogs-y := addnote addRamDisk hack-coff mktree dtc - - targets += $(patsubst $(obj)/%,%,$(obj-boot) wrapper.a) - extra-y := $(obj)/wrapper.a $(obj-plat) $(obj)/empty.o \ - $(obj)/zImage.lds $(obj)/zImage.coff.lds $(obj)/zImage.ps3.lds - - wrapper :=$(srctree)/$(src)/wrapper --wrapperbits := $(extra-y) $(addprefix $(obj)/,addnote hack-coff mktree) \ -+wrapperbits := $(extra-y) $(addprefix $(obj)/,addnote hack-coff mktree dtc) \ - $(wrapper) FORCE - - ############# -+# Bits for building dtc -+# DTC_GENPARSER := 1 # Uncomment to rebuild flex/bison output -+ -+dtc-objs := dtc.o flattree.o fstree.o data.o livetree.o treesource.o srcpos.o checks.o -+dtc-objs += dtc-lexer.lex.o dtc-parser.tab.o -+dtc-objs := $(addprefix dtc-src/, $(dtc-objs)) -+ -+# prerequisites on generated files needs to be explicit -+$(obj)/dtc-src/dtc-parser.tab.o: $(obj)/dtc-src/dtc-parser.tab.c $(obj)/dtc-src/dtc-parser.tab.h -+$(obj)/dtc-src/dtc-lexer.lex.o: $(obj)/dtc-src/dtc-lexer.lex.c $(obj)/dtc-src/dtc-parser.tab.h -+ -+HOSTCFLAGS += -I$(src)/dtc-src/ -I$(src)/libfdt/ -+ -+targets += dtc-src/dtc-parser.tab.c -+targets += dtc-src/dtc-lexer.lex.c -+ -+ifdef DTC_GENPARSER -+BISON = bison -+FLEX = flex -+ -+quiet_cmd_bison = BISON $@ -+ cmd_bison = $(BISON) -o$@ -d $<; cp $@ $@_shipped -+quiet_cmd_flex = FLEX $@ -+ cmd_flex = $(FLEX) -o$@ $<; cp $@ $@_shipped -+ -+$(obj)/dtc-src/dtc-parser.tab.c: $(src)/dtc-src/dtc-parser.y FORCE -+ $(call if_changed,bison) -+ -+$(obj)/dtc-src/dtc-parser.tab.h: $(obj)/dtc-src/dtc-parser.tab.c -+ -+$(obj)/dtc-src/dtc-lexer.lex.c: $(src)/dtc-src/dtc-lexer.l FORCE -+ $(call if_changed,flex) -+endif -+ -+############# - # Bits for building various flavours of zImage - - ifneq ($(CROSS32_COMPILE),) -@@ -150,15 +194,26 @@ image-$(CONFIG_DEFAULT_UIMAGE) += uImag - ifneq ($(CONFIG_DEVICE_TREE),"") - image-$(CONFIG_PPC_8xx) += cuImage.8xx - image-$(CONFIG_PPC_EP88XC) += zImage.ep88xc -+image-$(CONFIG_EP405) += zImage.ep405 - image-$(CONFIG_8260) += cuImage.pq2 -+image-$(CONFIG_EP8248E) += zImage.ep8248e - image-$(CONFIG_PPC_MPC52xx) += cuImage.52xx -+image-$(CONFIG_STORCENTER) += cuImage.824x - image-$(CONFIG_PPC_83xx) += cuImage.83xx - image-$(CONFIG_PPC_85xx) += cuImage.85xx - image-$(CONFIG_MPC7448HPC2) += cuImage.hpc2 - image-$(CONFIG_EBONY) += treeImage.ebony cuImage.ebony - image-$(CONFIG_BAMBOO) += treeImage.bamboo cuImage.bamboo - image-$(CONFIG_SEQUOIA) += cuImage.sequoia -+image-$(CONFIG_RAINIER) += cuImage.rainier - image-$(CONFIG_WALNUT) += treeImage.walnut -+image-$(CONFIG_TAISHAN) += cuImage.taishan -+image-$(CONFIG_KATMAI) += cuImage.katmai -+image-$(CONFIG_WARP) += cuImage.warp -+endif -+ -+ifneq ($(CONFIG_REDBOOT),"") -+image-$(CONFIG_PPC_8xx) += zImage.redboot-8xx - endif - - # For 32-bit powermacs, build the COFF and miboot images -@@ -243,3 +298,51 @@ clean-kernel := vmlinux.strip vmlinux.bi - clean-kernel += $(addsuffix .gz,$(clean-kernel)) - # If not absolute clean-files are relative to $(obj). - clean-files += $(addprefix $(objtree)/, $(clean-kernel)) -+ -+WRAPPER_OBJDIR := /usr/lib/kernel-wrapper -+WRAPPER_DTSDIR := /usr/lib/kernel-wrapper/dts -+WRAPPER_BINDIR := /usr/sbin -+INSTALL := install -+ -+extra-installed := $(patsubst $(obj)/%, $(DESTDIR)$(WRAPPER_OBJDIR)/%, $(extra-y)) -+hostprogs-installed := $(patsubst %, $(DESTDIR)$(WRAPPER_BINDIR)/%, $(hostprogs-y)) -+wrapper-installed := $(DESTDIR)$(WRAPPER_BINDIR)/wrapper -+dts-installed := $(patsubst $(obj)/dts/%, $(DESTDIR)$(WRAPPER_DTSDIR)/%, $(wildcard $(obj)/dts/*.dts)) -+ -+all-installed := $(extra-installed) $(hostprogs-installed) $(wrapper-installed) $(dts-installed) -+ -+quiet_cmd_mkdir = MKDIR $(patsubst $(INSTALL_HDR_PATH)/%,%,$@) -+ cmd_mkdir = mkdir -p $@ -+ -+quiet_cmd_install = INSTALL $(patsubst $(DESTDIR)$(WRAPPER_OBJDIR)/%,%,$@) -+ cmd_install = $(INSTALL) -m0644 $(patsubst $(DESTDIR)$(WRAPPER_OBJDIR)/%,$(obj)/%,$@) $@ -+ -+quiet_cmd_install_dts = INSTALL $(patsubst $(DESTDIR)$(WRAPPER_DTSDIR)/%,dts/%,$@) -+ cmd_install_dts = $(INSTALL) -m0644 $(patsubst $(DESTDIR)$(WRAPPER_DTSDIR)/%,$(srctree)/$(obj)/dts/%,$@) $@ -+ -+quiet_cmd_install_exe = INSTALL $(patsubst $(DESTDIR)$(WRAPPER_BINDIR)/%,%,$@) -+ cmd_install_exe = $(INSTALL) -m0755 $(patsubst $(DESTDIR)$(WRAPPER_BINDIR)/%,$(obj)/%,$@) $@ -+ -+quiet_cmd_install_wrapper = INSTALL $(patsubst $(DESTDIR)$(WRAPPER_BINDIR)/%,%,$@) -+ cmd_install_wrapper = $(INSTALL) -m0755 $(patsubst $(DESTDIR)$(WRAPPER_BINDIR)/%,$(srctree)/$(obj)/%,$@) $@ ;\ -+ sed -i $@ -e 's%^object=.*%object=$(WRAPPER_OBJDIR)%' \ -+ -e 's%^objbin=.*%objbin=$(WRAPPER_BINDIR)%' \ -+ -+ -+$(DESTDIR)$(WRAPPER_OBJDIR) $(DESTDIR)$(WRAPPER_DTSDIR) $(DESTDIR)$(WRAPPER_BINDIR): -+ $(call cmd,mkdir) -+ -+$(extra-installed) : $(DESTDIR)$(WRAPPER_OBJDIR)/% : $(obj)/% | $(DESTDIR)$(WRAPPER_OBJDIR) -+ $(call cmd,install) -+ -+$(hostprogs-installed) : $(DESTDIR)$(WRAPPER_BINDIR)/% : $(obj)/% | $(DESTDIR)$(WRAPPER_BINDIR) -+ $(call cmd,install_exe) -+ -+$(dts-installed) : $(DESTDIR)$(WRAPPER_DTSDIR)/% : $(srctree)/$(obj)/dts/% | $(DESTDIR)$(WRAPPER_DTSDIR) -+ $(call cmd,install_dts) -+ -+$(wrapper-installed): $(DESTDIR)$(WRAPPER_BINDIR) $(srctree)/$(obj)/wrapper | $(DESTDIR)$(WRAPPER_BINDIR) -+ $(call cmd,install_wrapper) -+ -+$(obj)/bootwrapper_install: $(all-installed) -+ ---- a/arch/powerpc/boot/bamboo.c -+++ b/arch/powerpc/boot/bamboo.c -@@ -30,8 +30,8 @@ static void bamboo_fixups(void) - { - unsigned long sysclk = 33333333; - -- ibm440ep_fixup_clocks(sysclk, 11059200); -- ibm4xx_fixup_memsize(); -+ ibm440ep_fixup_clocks(sysclk, 11059200, 25000000); -+ ibm4xx_sdram_fixup_memsize(); - ibm4xx_quiesce_eth((u32 *)0xef600e00, (u32 *)0xef600f00); - dt_fixup_mac_addresses(bamboo_mac0, bamboo_mac1); - } -@@ -42,6 +42,6 @@ void bamboo_init(void *mac0, void *mac1) - platform_ops.exit = ibm44x_dbcr_reset; - bamboo_mac0 = mac0; - bamboo_mac1 = mac1; -- ft_init(_dtb_start, 0, 32); -+ fdt_init(_dtb_start); - serial_console_init(); - } ---- a/arch/powerpc/boot/cuboot-52xx.c -+++ b/arch/powerpc/boot/cuboot-52xx.c -@@ -53,7 +53,7 @@ void platform_init(unsigned long r3, uns - unsigned long r6, unsigned long r7) - { - CUBOOT_INIT(); -- ft_init(_dtb_start, _dtb_end - _dtb_start, 32); -+ fdt_init(_dtb_start); - serial_console_init(); - platform_ops.fixups = platform_fixups; - } ---- /dev/null -+++ b/arch/powerpc/boot/cuboot-824x.c -@@ -0,0 +1,53 @@ -+/* -+ * Old U-boot compatibility for 824x -+ * -+ * Copyright (c) 2007 Freescale Semiconductor, Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include "ops.h" -+#include "stdio.h" -+#include "cuboot.h" -+ -+#define TARGET_824x -+#include "ppcboot.h" -+ -+static bd_t bd; -+ -+ -+static void platform_fixups(void) -+{ -+ void *soc; -+ -+ dt_fixup_memory(bd.bi_memstart, bd.bi_memsize); -+ dt_fixup_mac_addresses(bd.bi_enetaddr); -+ dt_fixup_cpu_clocks(bd.bi_intfreq, bd.bi_busfreq / 4, bd.bi_busfreq); -+ -+ soc = find_node_by_devtype(NULL, "soc"); -+ if (soc) { -+ void *serial = NULL; -+ -+ setprop(soc, "bus-frequency", &bd.bi_busfreq, -+ sizeof(bd.bi_busfreq)); -+ -+ while ((serial = find_node_by_devtype(serial, "serial"))) { -+ if (get_parent(serial) != soc) -+ continue; -+ -+ setprop(serial, "clock-frequency", &bd.bi_busfreq, -+ sizeof(bd.bi_busfreq)); -+ } -+ } -+} -+ -+void platform_init(unsigned long r3, unsigned long r4, unsigned long r5, -+ unsigned long r6, unsigned long r7) -+{ -+ CUBOOT_INIT(); -+ fdt_init(_dtb_start); -+ serial_console_init(); -+ platform_ops.fixups = platform_fixups; -+} ---- a/arch/powerpc/boot/cuboot-83xx.c -+++ b/arch/powerpc/boot/cuboot-83xx.c -@@ -24,7 +24,8 @@ static void platform_fixups(void) - void *soc; - - dt_fixup_memory(bd.bi_memstart, bd.bi_memsize); -- dt_fixup_mac_addresses(bd.bi_enetaddr, bd.bi_enet1addr); -+ dt_fixup_mac_address_by_alias("ethernet0", bd.bi_enetaddr); -+ dt_fixup_mac_address_by_alias("ethernet1", bd.bi_enet1addr); - dt_fixup_cpu_clocks(bd.bi_intfreq, bd.bi_busfreq / 4, bd.bi_busfreq); - - /* Unfortunately, the specific model number is encoded in the -@@ -52,7 +53,7 @@ void platform_init(unsigned long r3, uns - unsigned long r6, unsigned long r7) - { - CUBOOT_INIT(); -- ft_init(_dtb_start, _dtb_end - _dtb_start, 32); -+ fdt_init(_dtb_start); - serial_console_init(); - platform_ops.fixups = platform_fixups; - } ---- a/arch/powerpc/boot/cuboot-85xx.c -+++ b/arch/powerpc/boot/cuboot-85xx.c -@@ -24,8 +24,9 @@ static void platform_fixups(void) - void *soc; - - dt_fixup_memory(bd.bi_memstart, bd.bi_memsize); -- dt_fixup_mac_addresses(bd.bi_enetaddr, bd.bi_enet1addr, -- bd.bi_enet2addr); -+ dt_fixup_mac_address_by_alias("ethernet0", bd.bi_enetaddr); -+ dt_fixup_mac_address_by_alias("ethernet1", bd.bi_enet1addr); -+ dt_fixup_mac_address_by_alias("ethernet2", bd.bi_enet2addr); - dt_fixup_cpu_clocks(bd.bi_intfreq, bd.bi_busfreq / 8, bd.bi_busfreq); - - /* Unfortunately, the specific model number is encoded in the -@@ -53,7 +54,7 @@ void platform_init(unsigned long r3, uns - unsigned long r6, unsigned long r7) - { - CUBOOT_INIT(); -- ft_init(_dtb_start, _dtb_end - _dtb_start, 32); -+ fdt_init(_dtb_start); - serial_console_init(); - platform_ops.fixups = platform_fixups; - } ---- a/arch/powerpc/boot/cuboot-8xx.c -+++ b/arch/powerpc/boot/cuboot-8xx.c -@@ -41,7 +41,7 @@ void platform_init(unsigned long r3, uns - unsigned long r6, unsigned long r7) - { - CUBOOT_INIT(); -- ft_init(_dtb_start, _dtb_end - _dtb_start, 32); -+ fdt_init(_dtb_start); - serial_console_init(); - platform_ops.fixups = platform_fixups; - } ---- a/arch/powerpc/boot/cuboot-hpc2.c -+++ b/arch/powerpc/boot/cuboot-hpc2.c -@@ -42,7 +42,7 @@ void platform_init(unsigned long r3, uns - unsigned long r6, unsigned long r7) - { - CUBOOT_INIT(); -- ft_init(_dtb_start, _dtb_end - _dtb_start, 32); -+ fdt_init(_dtb_start); - serial_console_init(); - platform_ops.fixups = platform_fixups; - } ---- /dev/null -+++ b/arch/powerpc/boot/cuboot-katmai.c -@@ -0,0 +1,56 @@ -+/* -+ * Old U-boot compatibility for Katmai -+ * -+ * Author: Hugh Blemings -+ * -+ * Copyright 2007 Hugh Blemings, IBM Corporation. -+ * Based on cuboot-ebony.c which is: -+ * Copyright 2007 David Gibson, IBM Corporation. -+ * Based on cuboot-83xx.c, which is: -+ * Copyright (c) 2007 Freescale Semiconductor, Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include "ops.h" -+#include "stdio.h" -+#include "reg.h" -+#include "dcr.h" -+#include "4xx.h" -+#include "44x.h" -+#include "cuboot.h" -+ -+#define TARGET_44x -+#include "ppcboot.h" -+ -+static bd_t bd; -+ -+BSS_STACK(4096); -+ -+static void katmai_fixups(void) -+{ -+ unsigned long sysclk = 33333000; -+ -+ /* 440SP Clock logic is all but identical to 440GX -+ * so we just use that code for now at least -+ */ -+ ibm440spe_fixup_clocks(sysclk, 6 * 1843200, 0); -+ -+ ibm440spe_fixup_memsize(); -+ -+ dt_fixup_mac_address(0, bd.bi_enetaddr); -+ -+ ibm4xx_fixup_ebc_ranges("/plb/opb/ebc"); -+} -+ -+void platform_init(unsigned long r3, unsigned long r4, unsigned long r5, -+ unsigned long r6, unsigned long r7) -+{ -+ CUBOOT_INIT(); -+ -+ platform_ops.fixups = katmai_fixups; -+ fdt_init(_dtb_start); -+ serial_console_init(); -+} ---- a/arch/powerpc/boot/cuboot-pq2.c -+++ b/arch/powerpc/boot/cuboot-pq2.c -@@ -255,7 +255,7 @@ void platform_init(unsigned long r3, uns - unsigned long r6, unsigned long r7) - { - CUBOOT_INIT(); -- ft_init(_dtb_start, _dtb_end - _dtb_start, 32); -+ fdt_init(_dtb_start); - serial_console_init(); - platform_ops.fixups = pq2_platform_fixups; - } ---- /dev/null -+++ b/arch/powerpc/boot/cuboot-rainier.c -@@ -0,0 +1,56 @@ -+/* -+ * Old U-boot compatibility for Rainier -+ * -+ * Valentine Barshak -+ * Copyright 2007 MontaVista Software, Inc -+ * -+ * Based on Ebony code by David Gibson -+ * Copyright IBM Corporation, 2007 -+ * -+ * Based on Bamboo code by Josh Boyer -+ * Copyright IBM Corporation, 2007 -+ * -+ * 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 of the License -+ */ -+ -+#include -+#include -+#include "types.h" -+#include "elf.h" -+#include "string.h" -+#include "stdio.h" -+#include "page.h" -+#include "ops.h" -+#include "dcr.h" -+#include "4xx.h" -+#include "44x.h" -+#include "cuboot.h" -+ -+#define TARGET_4xx -+#define TARGET_44x -+#include "ppcboot.h" -+ -+static bd_t bd; -+ -+ -+static void rainier_fixups(void) -+{ -+ unsigned long sysclk = 33333333; -+ -+ ibm440ep_fixup_clocks(sysclk, 11059200, 50000000); -+ ibm4xx_fixup_ebc_ranges("/plb/opb/ebc"); -+ ibm4xx_denali_fixup_memsize(); -+ dt_fixup_mac_addresses(&bd.bi_enetaddr, &bd.bi_enet1addr); -+} -+ -+void platform_init(unsigned long r3, unsigned long r4, unsigned long r5, -+ unsigned long r6, unsigned long r7) -+{ -+ CUBOOT_INIT(); -+ platform_ops.fixups = rainier_fixups; -+ platform_ops.exit = ibm44x_dbcr_reset; -+ fdt_init(_dtb_start); -+ serial_console_init(); -+} ---- a/arch/powerpc/boot/cuboot-sequoia.c -+++ b/arch/powerpc/boot/cuboot-sequoia.c -@@ -39,7 +39,7 @@ static void sequoia_fixups(void) - { - unsigned long sysclk = 33333333; - -- ibm440ep_fixup_clocks(sysclk, 11059200); -+ ibm440ep_fixup_clocks(sysclk, 11059200, 50000000); - ibm4xx_fixup_ebc_ranges("/plb/opb/ebc"); - ibm4xx_denali_fixup_memsize(); - dt_fixup_mac_addresses(&bd.bi_enetaddr, &bd.bi_enet1addr); -@@ -51,6 +51,6 @@ void platform_init(unsigned long r3, uns - CUBOOT_INIT(); - platform_ops.fixups = sequoia_fixups; - platform_ops.exit = ibm44x_dbcr_reset; -- ft_init(_dtb_start, 0, 32); -+ fdt_init(_dtb_start); - serial_console_init(); - } ---- /dev/null -+++ b/arch/powerpc/boot/cuboot-taishan.c -@@ -0,0 +1,54 @@ -+/* -+ * Old U-boot compatibility for Taishan -+ * -+ * Author: Hugh Blemings -+ * -+ * Copyright 2007 Hugh Blemings, IBM Corporation. -+ * Based on cuboot-ebony.c which is: -+ * Copyright 2007 David Gibson, IBM Corporation. -+ * Based on cuboot-83xx.c, which is: -+ * Copyright (c) 2007 Freescale Semiconductor, Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include "ops.h" -+#include "stdio.h" -+#include "cuboot.h" -+#include "reg.h" -+#include "dcr.h" -+#include "4xx.h" -+ -+#define TARGET_44x -+#include "ppcboot.h" -+ -+static bd_t bd; -+ -+BSS_STACK(4096); -+ -+static void taishan_fixups(void) -+{ -+ /* FIXME: sysclk should be derived by reading the FPGA -+ registers */ -+ unsigned long sysclk = 33000000; -+ -+ ibm440gx_fixup_clocks(sysclk, 6 * 1843200, 25000000); -+ -+ ibm4xx_sdram_fixup_memsize(); -+ -+ dt_fixup_mac_addresses(bd.bi_enetaddr, bd.bi_enet1addr); -+ -+ ibm4xx_fixup_ebc_ranges("/plb/opb/ebc"); -+} -+ -+void platform_init(unsigned long r3, unsigned long r4, unsigned long r5, -+ unsigned long r6, unsigned long r7) -+{ -+ CUBOOT_INIT(); -+ -+ platform_ops.fixups = taishan_fixups; -+ fdt_init(_dtb_start); -+ serial_console_init(); -+} ---- /dev/null -+++ b/arch/powerpc/boot/cuboot-warp.c -@@ -0,0 +1,39 @@ -+/* -+ * Copyright (c) 2008 PIKA Technologies -+ * Sean MacLennan -+ * -+ * 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 "ops.h" -+#include "4xx.h" -+#include "cuboot.h" -+ -+#define TARGET_44x -+#include "ppcboot.h" -+ -+static bd_t bd; -+ -+static void warp_fixups(void) -+{ -+ unsigned long sysclk = 66000000; -+ -+ ibm440ep_fixup_clocks(sysclk, 11059200, 50000000); -+ ibm4xx_sdram_fixup_memsize(); -+ ibm4xx_fixup_ebc_ranges("/plb/opb/ebc"); -+ dt_fixup_mac_addresses(&bd.bi_enetaddr); -+} -+ -+ -+void platform_init(unsigned long r3, unsigned long r4, unsigned long r5, -+ unsigned long r6, unsigned long r7) -+{ -+ CUBOOT_INIT(); -+ -+ platform_ops.fixups = warp_fixups; -+ platform_ops.exit = ibm44x_dbcr_reset; -+ fdt_init(_dtb_start); -+ serial_console_init(); -+} ---- a/arch/powerpc/boot/dcr.h -+++ b/arch/powerpc/boot/dcr.h -@@ -14,12 +14,20 @@ - #define DCRN_SDRAM0_CFGADDR 0x010 - #define DCRN_SDRAM0_CFGDATA 0x011 - -+#define SDRAM0_READ(offset) ({\ -+ mtdcr(DCRN_SDRAM0_CFGADDR, offset); \ -+ mfdcr(DCRN_SDRAM0_CFGDATA); }) -+#define SDRAM0_WRITE(offset, data) ({\ -+ mtdcr(DCRN_SDRAM0_CFGADDR, offset); \ -+ mtdcr(DCRN_SDRAM0_CFGDATA, data); }) -+ - #define SDRAM0_B0CR 0x40 - #define SDRAM0_B1CR 0x44 - #define SDRAM0_B2CR 0x48 - #define SDRAM0_B3CR 0x4c - --static const unsigned long sdram_bxcr[] = { SDRAM0_B0CR, SDRAM0_B1CR, SDRAM0_B2CR, SDRAM0_B3CR }; -+static const unsigned long sdram_bxcr[] = { SDRAM0_B0CR, SDRAM0_B1CR, -+ SDRAM0_B2CR, SDRAM0_B3CR }; - - #define SDRAM_CONFIG_BANK_ENABLE 0x00000001 - #define SDRAM_CONFIG_SIZE_MASK 0x000e0000 -@@ -138,5 +146,54 @@ static const unsigned long sdram_bxcr[] - #define DCRN_CPC0_PLLMR 0xb0 - #define DCRN_405_CPC0_CR0 0xb1 - #define DCRN_405_CPC0_CR1 0xb2 -+#define DCRN_405_CPC0_PSR 0xb4 -+ -+/* 405EP Clocking/Power Management/Chip Control regs */ -+#define DCRN_CPC0_PLLMR0 0xf0 -+#define DCRN_CPC0_PLLMR1 0xf4 -+#define DCRN_CPC0_UCR 0xf5 -+ -+/* 440GX Clock control etc */ -+ -+ -+#define DCRN_CPR0_CLKUPD 0x020 -+#define DCRN_CPR0_PLLC 0x040 -+#define DCRN_CPR0_PLLD 0x060 -+#define DCRN_CPR0_PRIMAD 0x080 -+#define DCRN_CPR0_PRIMBD 0x0a0 -+#define DCRN_CPR0_OPBD 0x0c0 -+#define DCRN_CPR0_PERD 0x0e0 -+#define DCRN_CPR0_MALD 0x100 -+ -+#define DCRN_SDR0_CONFIG_ADDR 0xe -+#define DCRN_SDR0_CONFIG_DATA 0xf -+ -+/* SDR read/write helper macros */ -+#define SDR0_READ(offset) ({\ -+ mtdcr(DCRN_SDR0_CONFIG_ADDR, offset); \ -+ mfdcr(DCRN_SDR0_CONFIG_DATA); }) -+#define SDR0_WRITE(offset, data) ({\ -+ mtdcr(DCRN_SDR0_CONFIG_ADDR, offset); \ -+ mtdcr(DCRN_SDR0_CONFIG_DATA, data); }) -+ -+#define DCRN_SDR0_UART0 0x0120 -+#define DCRN_SDR0_UART1 0x0121 -+#define DCRN_SDR0_UART2 0x0122 -+#define DCRN_SDR0_UART3 0x0123 -+ -+ -+/* CPRs read/write helper macros - based off include/asm-ppc/ibm44x.h */ -+ -+#define DCRN_CPR0_CFGADDR 0xc -+#define DCRN_CPR0_CFGDATA 0xd -+ -+#define CPR0_READ(offset) ({\ -+ mtdcr(DCRN_CPR0_CFGADDR, offset); \ -+ mfdcr(DCRN_CPR0_CFGDATA); }) -+#define CPR0_WRITE(offset, data) ({\ -+ mtdcr(DCRN_CPR0_CFGADDR, offset); \ -+ mtdcr(DCRN_CPR0_CFGDATA, data); }) -+ -+ - - #endif /* _PPC_BOOT_DCR_H_ */ ---- a/arch/powerpc/boot/devtree.c -+++ b/arch/powerpc/boot/devtree.c -@@ -88,6 +88,20 @@ void dt_fixup_clock(const char *path, u3 - } - } - -+void dt_fixup_mac_address_by_alias(const char *alias, const u8 *addr) -+{ -+ void *devp = find_node_by_alias(alias); -+ -+ if (devp) { -+ printf("%s: local-mac-address <-" -+ " %02x:%02x:%02x:%02x:%02x:%02x\n\r", alias, -+ addr[0], addr[1], addr[2], -+ addr[3], addr[4], addr[5]); -+ -+ setprop(devp, "local-mac-address", addr, 6); -+ } -+} -+ - void dt_fixup_mac_address(u32 index, const u8 *addr) - { - void *devp = find_node_by_prop_value(NULL, "linux,network-index", ---- /dev/null -+++ b/arch/powerpc/boot/dtc-src/Makefile.dtc -@@ -0,0 +1,25 @@ -+# Makefile.dtc -+# -+# This is not a complete Makefile of itself. Instead, it is designed to -+# be easily embeddable into other systems of Makefiles. -+# -+DTC_SRCS = dtc.c flattree.c fstree.c data.c livetree.c treesource.c srcpos.c \ -+ checks.c -+DTC_EXTRA = dtc.h srcpos.h -+DTC_LEXFILES = dtc-lexer.l -+DTC_BISONFILES = dtc-parser.y -+ -+DTC_LEX_SRCS = $(DTC_LEXFILES:%.l=%.lex.c) -+DTC_BISON_SRCS = $(DTC_BISONFILES:%.y=%.tab.c) -+DTC_BISON_INCLUDES = $(DTC_BISONFILES:%.y=%.tab.h) -+ -+DTC_GEN_SRCS = $(DTC_LEX_SRCS) $(DTC_BISON_SRCS) -+DTC_GEN_ALL = $(DTC_GEN_SRCS) $(DTC_BISON_INCLUDES) -+DTC_OBJS = $(DTC_SRCS:%.c=%.o) $(DTC_GEN_SRCS:%.c=%.o) -+ -+DTC_CLEANFILES = $(DTC_GEN_ALL) -+ -+# We assume the containing Makefile system can do auto-dependencies for most -+# things, but we supply the dependencies on generated header files explicitly -+ -+$(addprefix $(DTC_objdir)/,$(DTC_GEN_SRCS:%.c=%.o)): $(addprefix $(DTC_objdir)/,$(DTC_BISON_INCLUDES)) ---- /dev/null -+++ b/arch/powerpc/boot/dtc-src/checks.c -@@ -0,0 +1,750 @@ -+/* -+ * (C) Copyright David Gibson , IBM Corporation. 2007. -+ * -+ * -+ * 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 "dtc.h" -+ -+#ifdef TRACE_CHECKS -+#define TRACE(c, ...) \ -+ do { \ -+ fprintf(stderr, "=== %s: ", (c)->name); \ -+ fprintf(stderr, __VA_ARGS__); \ -+ fprintf(stderr, "\n"); \ -+ } while (0) -+#else -+#define TRACE(c, fmt, ...) do { } while (0) -+#endif -+ -+enum checklevel { -+ IGNORE = 0, -+ WARN = 1, -+ ERROR = 2, -+}; -+ -+enum checkstatus { -+ UNCHECKED = 0, -+ PREREQ, -+ PASSED, -+ FAILED, -+}; -+ -+struct check; -+ -+typedef void (*tree_check_fn)(struct check *c, struct node *dt); -+typedef void (*node_check_fn)(struct check *c, struct node *dt, struct node *node); -+typedef void (*prop_check_fn)(struct check *c, struct node *dt, -+ struct node *node, struct property *prop); -+ -+struct check { -+ const char *name; -+ tree_check_fn tree_fn; -+ node_check_fn node_fn; -+ prop_check_fn prop_fn; -+ void *data; -+ enum checklevel level; -+ enum checkstatus status; -+ int inprogress; -+ int num_prereqs; -+ struct check **prereq; -+}; -+ -+#define CHECK(nm, tfn, nfn, pfn, d, lvl, ...) \ -+ static struct check *nm##_prereqs[] = { __VA_ARGS__ }; \ -+ static struct check nm = { \ -+ .name = #nm, \ -+ .tree_fn = (tfn), \ -+ .node_fn = (nfn), \ -+ .prop_fn = (pfn), \ -+ .data = (d), \ -+ .level = (lvl), \ -+ .status = UNCHECKED, \ -+ .num_prereqs = ARRAY_SIZE(nm##_prereqs), \ -+ .prereq = nm##_prereqs, \ -+ }; -+ -+#define TREE_CHECK(nm, d, lvl, ...) \ -+ CHECK(nm, check_##nm, NULL, NULL, d, lvl, __VA_ARGS__) -+#define NODE_CHECK(nm, d, lvl, ...) \ -+ CHECK(nm, NULL, check_##nm, NULL, d, lvl, __VA_ARGS__) -+#define PROP_CHECK(nm, d, lvl, ...) \ -+ CHECK(nm, NULL, NULL, check_##nm, d, lvl, __VA_ARGS__) -+#define BATCH_CHECK(nm, lvl, ...) \ -+ CHECK(nm, NULL, NULL, NULL, NULL, lvl, __VA_ARGS__) -+ -+#ifdef __GNUC__ -+static inline void check_msg(struct check *c, const char *fmt, ...) __attribute__((format (printf, 2, 3))); -+#endif -+static inline void check_msg(struct check *c, const char *fmt, ...) -+{ -+ va_list ap; -+ va_start(ap, fmt); -+ -+ if ((c->level < WARN) || (c->level <= quiet)) -+ return; /* Suppress message */ -+ -+ fprintf(stderr, "%s (%s): ", -+ (c->level == ERROR) ? "ERROR" : "Warning", c->name); -+ vfprintf(stderr, fmt, ap); -+ fprintf(stderr, "\n"); -+} -+ -+#define FAIL(c, ...) \ -+ do { \ -+ TRACE((c), "\t\tFAILED at %s:%d", __FILE__, __LINE__); \ -+ (c)->status = FAILED; \ -+ check_msg((c), __VA_ARGS__); \ -+ } while (0) -+ -+static void check_nodes_props(struct check *c, struct node *dt, struct node *node) -+{ -+ struct node *child; -+ struct property *prop; -+ -+ TRACE(c, "%s", node->fullpath); -+ if (c->node_fn) -+ c->node_fn(c, dt, node); -+ -+ if (c->prop_fn) -+ for_each_property(node, prop) { -+ TRACE(c, "%s\t'%s'", node->fullpath, prop->name); -+ c->prop_fn(c, dt, node, prop); -+ } -+ -+ for_each_child(node, child) -+ check_nodes_props(c, dt, child); -+} -+ -+static int run_check(struct check *c, struct node *dt) -+{ -+ int error = 0; -+ int i; -+ -+ assert(!c->inprogress); -+ -+ if (c->status != UNCHECKED) -+ goto out; -+ -+ c->inprogress = 1; -+ -+ for (i = 0; i < c->num_prereqs; i++) { -+ struct check *prq = c->prereq[i]; -+ error |= run_check(prq, dt); -+ if (prq->status != PASSED) { -+ c->status = PREREQ; -+ check_msg(c, "Failed prerequisite '%s'", -+ c->prereq[i]->name); -+ } -+ } -+ -+ if (c->status != UNCHECKED) -+ goto out; -+ -+ if (c->node_fn || c->prop_fn) -+ check_nodes_props(c, dt, dt); -+ -+ if (c->tree_fn) -+ c->tree_fn(c, dt); -+ if (c->status == UNCHECKED) -+ c->status = PASSED; -+ -+ TRACE(c, "\tCompleted, status %d", c->status); -+ -+out: -+ c->inprogress = 0; -+ if ((c->status != PASSED) && (c->level == ERROR)) -+ error = 1; -+ return error; -+} -+ -+/* -+ * Utility check functions -+ */ -+ -+static void check_is_string(struct check *c, struct node *root, -+ struct node *node) -+{ -+ struct property *prop; -+ char *propname = c->data; -+ -+ prop = get_property(node, propname); -+ if (!prop) -+ return; /* Not present, assumed ok */ -+ -+ if (!data_is_one_string(prop->val)) -+ FAIL(c, "\"%s\" property in %s is not a string", -+ propname, node->fullpath); -+} -+#define CHECK_IS_STRING(nm, propname, lvl) \ -+ CHECK(nm, NULL, check_is_string, NULL, (propname), (lvl)) -+ -+static void check_is_cell(struct check *c, struct node *root, -+ struct node *node) -+{ -+ struct property *prop; -+ char *propname = c->data; -+ -+ prop = get_property(node, propname); -+ if (!prop) -+ return; /* Not present, assumed ok */ -+ -+ if (prop->val.len != sizeof(cell_t)) -+ FAIL(c, "\"%s\" property in %s is not a single cell", -+ propname, node->fullpath); -+} -+#define CHECK_IS_CELL(nm, propname, lvl) \ -+ CHECK(nm, NULL, check_is_cell, NULL, (propname), (lvl)) -+ -+/* -+ * Structural check functions -+ */ -+ -+static void check_duplicate_node_names(struct check *c, struct node *dt, -+ struct node *node) -+{ -+ struct node *child, *child2; -+ -+ for_each_child(node, child) -+ for (child2 = child->next_sibling; -+ child2; -+ child2 = child2->next_sibling) -+ if (streq(child->name, child2->name)) -+ FAIL(c, "Duplicate node name %s", -+ child->fullpath); -+} -+NODE_CHECK(duplicate_node_names, NULL, ERROR); -+ -+static void check_duplicate_property_names(struct check *c, struct node *dt, -+ struct node *node) -+{ -+ struct property *prop, *prop2; -+ -+ for_each_property(node, prop) -+ for (prop2 = prop->next; prop2; prop2 = prop2->next) -+ if (streq(prop->name, prop2->name)) -+ FAIL(c, "Duplicate property name %s in %s", -+ prop->name, node->fullpath); -+} -+NODE_CHECK(duplicate_property_names, NULL, ERROR); -+ -+static void check_explicit_phandles(struct check *c, struct node *root, -+ struct node *node) -+{ -+ struct property *prop; -+ struct node *other; -+ cell_t phandle; -+ -+ prop = get_property(node, "linux,phandle"); -+ if (! prop) -+ return; /* No phandle, that's fine */ -+ -+ if (prop->val.len != sizeof(cell_t)) { -+ FAIL(c, "%s has bad length (%d) linux,phandle property", -+ node->fullpath, prop->val.len); -+ return; -+ } -+ -+ phandle = propval_cell(prop); -+ if ((phandle == 0) || (phandle == -1)) { -+ FAIL(c, "%s has invalid linux,phandle value 0x%x", -+ node->fullpath, phandle); -+ return; -+ } -+ -+ other = get_node_by_phandle(root, phandle); -+ if (other) { -+ FAIL(c, "%s has duplicated phandle 0x%x (seen before at %s)", -+ node->fullpath, phandle, other->fullpath); -+ return; -+ } -+ -+ node->phandle = phandle; -+} -+NODE_CHECK(explicit_phandles, NULL, ERROR); -+ -+static void check_name_properties(struct check *c, struct node *root, -+ struct node *node) -+{ -+ struct property *prop; -+ -+ prop = get_property(node, "name"); -+ if (!prop) -+ return; /* No name property, that's fine */ -+ -+ if ((prop->val.len != node->basenamelen+1) -+ || (memcmp(prop->val.val, node->name, node->basenamelen) != 0)) -+ FAIL(c, "\"name\" property in %s is incorrect (\"%s\" instead" -+ " of base node name)", node->fullpath, prop->val.val); -+} -+CHECK_IS_STRING(name_is_string, "name", ERROR); -+NODE_CHECK(name_properties, NULL, ERROR, &name_is_string); -+ -+/* -+ * Reference fixup functions -+ */ -+ -+static void fixup_phandle_references(struct check *c, struct node *dt, -+ struct node *node, struct property *prop) -+{ -+ struct marker *m = prop->val.markers; -+ struct node *refnode; -+ cell_t phandle; -+ -+ for_each_marker_of_type(m, REF_PHANDLE) { -+ assert(m->offset + sizeof(cell_t) <= prop->val.len); -+ -+ refnode = get_node_by_ref(dt, m->ref); -+ if (! refnode) { -+ FAIL(c, "Reference to non-existent node or label \"%s\"\n", -+ m->ref); -+ continue; -+ } -+ -+ phandle = get_node_phandle(dt, refnode); -+ *((cell_t *)(prop->val.val + m->offset)) = cpu_to_be32(phandle); -+ } -+} -+CHECK(phandle_references, NULL, NULL, fixup_phandle_references, NULL, ERROR, -+ &duplicate_node_names, &explicit_phandles); -+ -+static void fixup_path_references(struct check *c, struct node *dt, -+ struct node *node, struct property *prop) -+{ -+ struct marker *m = prop->val.markers; -+ struct node *refnode; -+ char *path; -+ -+ for_each_marker_of_type(m, REF_PATH) { -+ assert(m->offset <= prop->val.len); -+ -+ refnode = get_node_by_ref(dt, m->ref); -+ if (!refnode) { -+ FAIL(c, "Reference to non-existent node or label \"%s\"\n", -+ m->ref); -+ continue; -+ } -+ -+ path = refnode->fullpath; -+ prop->val = data_insert_at_marker(prop->val, m, path, -+ strlen(path) + 1); -+ } -+} -+CHECK(path_references, NULL, NULL, fixup_path_references, NULL, ERROR, -+ &duplicate_node_names); -+ -+/* -+ * Semantic checks -+ */ -+CHECK_IS_CELL(address_cells_is_cell, "#address-cells", WARN); -+CHECK_IS_CELL(size_cells_is_cell, "#size-cells", WARN); -+CHECK_IS_CELL(interrupt_cells_is_cell, "#interrupt-cells", WARN); -+ -+CHECK_IS_STRING(device_type_is_string, "device_type", WARN); -+CHECK_IS_STRING(model_is_string, "model", WARN); -+CHECK_IS_STRING(status_is_string, "status", WARN); -+ -+static void fixup_addr_size_cells(struct check *c, struct node *dt, -+ struct node *node) -+{ -+ struct property *prop; -+ -+ node->addr_cells = -1; -+ node->size_cells = -1; -+ -+ prop = get_property(node, "#address-cells"); -+ if (prop) -+ node->addr_cells = propval_cell(prop); -+ -+ prop = get_property(node, "#size-cells"); -+ if (prop) -+ node->size_cells = propval_cell(prop); -+} -+CHECK(addr_size_cells, NULL, fixup_addr_size_cells, NULL, NULL, WARN, -+ &address_cells_is_cell, &size_cells_is_cell); -+ -+#define node_addr_cells(n) \ -+ (((n)->addr_cells == -1) ? 2 : (n)->addr_cells) -+#define node_size_cells(n) \ -+ (((n)->size_cells == -1) ? 1 : (n)->size_cells) -+ -+static void check_reg_format(struct check *c, struct node *dt, -+ struct node *node) -+{ -+ struct property *prop; -+ int addr_cells, size_cells, entrylen; -+ -+ prop = get_property(node, "reg"); -+ if (!prop) -+ return; /* No "reg", that's fine */ -+ -+ if (!node->parent) { -+ FAIL(c, "Root node has a \"reg\" property"); -+ return; -+ } -+ -+ if (prop->val.len == 0) -+ FAIL(c, "\"reg\" property in %s is empty", node->fullpath); -+ -+ addr_cells = node_addr_cells(node->parent); -+ size_cells = node_size_cells(node->parent); -+ entrylen = (addr_cells + size_cells) * sizeof(cell_t); -+ -+ if ((prop->val.len % entrylen) != 0) -+ FAIL(c, "\"reg\" property in %s has invalid length (%d bytes) " -+ "(#address-cells == %d, #size-cells == %d)", -+ node->fullpath, prop->val.len, addr_cells, size_cells); -+} -+NODE_CHECK(reg_format, NULL, WARN, &addr_size_cells); -+ -+static void check_ranges_format(struct check *c, struct node *dt, -+ struct node *node) -+{ -+ struct property *prop; -+ int c_addr_cells, p_addr_cells, c_size_cells, p_size_cells, entrylen; -+ -+ prop = get_property(node, "ranges"); -+ if (!prop) -+ return; -+ -+ if (!node->parent) { -+ FAIL(c, "Root node has a \"ranges\" property"); -+ return; -+ } -+ -+ p_addr_cells = node_addr_cells(node->parent); -+ p_size_cells = node_size_cells(node->parent); -+ c_addr_cells = node_addr_cells(node); -+ c_size_cells = node_size_cells(node); -+ entrylen = (p_addr_cells + c_addr_cells + c_size_cells) * sizeof(cell_t); -+ -+ if (prop->val.len == 0) { -+ if (p_addr_cells != c_addr_cells) -+ FAIL(c, "%s has empty \"ranges\" property but its " -+ "#address-cells (%d) differs from %s (%d)", -+ node->fullpath, c_addr_cells, node->parent->fullpath, -+ p_addr_cells); -+ if (p_size_cells != c_size_cells) -+ FAIL(c, "%s has empty \"ranges\" property but its " -+ "#size-cells (%d) differs from %s (%d)", -+ node->fullpath, c_size_cells, node->parent->fullpath, -+ p_size_cells); -+ } else if ((prop->val.len % entrylen) != 0) { -+ FAIL(c, "\"ranges\" property in %s has invalid length (%d bytes) " -+ "(parent #address-cells == %d, child #address-cells == %d, " -+ "#size-cells == %d)", node->fullpath, prop->val.len, -+ p_addr_cells, c_addr_cells, c_size_cells); -+ } -+} -+NODE_CHECK(ranges_format, NULL, WARN, &addr_size_cells); -+ -+/* -+ * Style checks -+ */ -+static void check_avoid_default_addr_size(struct check *c, struct node *dt, -+ struct node *node) -+{ -+ struct property *reg, *ranges; -+ -+ if (!node->parent) -+ return; /* Ignore root node */ -+ -+ reg = get_property(node, "reg"); -+ ranges = get_property(node, "ranges"); -+ -+ if (!reg && !ranges) -+ return; -+ -+ if ((node->parent->addr_cells == -1)) -+ FAIL(c, "Relying on default #address-cells value for %s", -+ node->fullpath); -+ -+ if ((node->parent->size_cells == -1)) -+ FAIL(c, "Relying on default #size-cells value for %s", -+ node->fullpath); -+} -+NODE_CHECK(avoid_default_addr_size, NULL, WARN, &addr_size_cells); -+ -+static void check_obsolete_chosen_interrupt_controller(struct check *c, -+ struct node *dt) -+{ -+ struct node *chosen; -+ struct property *prop; -+ -+ chosen = get_node_by_path(dt, "/chosen"); -+ if (!chosen) -+ return; -+ -+ prop = get_property(chosen, "interrupt-controller"); -+ if (prop) -+ FAIL(c, "/chosen has obsolete \"interrupt-controller\" " -+ "property"); -+} -+TREE_CHECK(obsolete_chosen_interrupt_controller, NULL, WARN); -+ -+static struct check *check_table[] = { -+ &duplicate_node_names, &duplicate_property_names, -+ &name_is_string, &name_properties, -+ &explicit_phandles, -+ &phandle_references, &path_references, -+ -+ &address_cells_is_cell, &size_cells_is_cell, &interrupt_cells_is_cell, -+ &device_type_is_string, &model_is_string, &status_is_string, -+ -+ &addr_size_cells, ®_format, &ranges_format, -+ -+ &avoid_default_addr_size, -+ &obsolete_chosen_interrupt_controller, -+}; -+ -+int check_semantics(struct node *dt, int outversion, int boot_cpuid_phys); -+ -+void process_checks(int force, struct boot_info *bi, -+ int checkflag, int outversion, int boot_cpuid_phys) -+{ -+ struct node *dt = bi->dt; -+ int i; -+ int error = 0; -+ -+ for (i = 0; i < ARRAY_SIZE(check_table); i++) { -+ struct check *c = check_table[i]; -+ -+ if (c->level != IGNORE) -+ error = error || run_check(c, dt); -+ } -+ -+ if (error) { -+ if (!force) { -+ fprintf(stderr, "ERROR: Input tree has errors, aborting " -+ "(use -f to force output)\n"); -+ exit(2); -+ } else if (quiet < 3) { -+ fprintf(stderr, "Warning: Input tree has errors, " -+ "output forced\n"); -+ } -+ } -+ -+ if (checkflag) { -+ if (error) { -+ fprintf(stderr, "Warning: Skipping semantic checks due to structural errors\n"); -+ } else { -+ if (!check_semantics(bi->dt, outversion, -+ boot_cpuid_phys)) -+ fprintf(stderr, "Warning: Input tree has semantic errors\n"); -+ } -+ } -+} -+ -+/* -+ * Semantic check functions -+ */ -+ -+#define ERRMSG(...) if (quiet < 2) fprintf(stderr, "ERROR: " __VA_ARGS__) -+#define WARNMSG(...) if (quiet < 1) fprintf(stderr, "Warning: " __VA_ARGS__) -+ -+#define DO_ERR(...) do {ERRMSG(__VA_ARGS__); ok = 0; } while (0) -+ -+#define CHECK_HAVE(node, propname) \ -+ do { \ -+ if (! (prop = get_property((node), (propname)))) \ -+ DO_ERR("Missing \"%s\" property in %s\n", (propname), \ -+ (node)->fullpath); \ -+ } while (0); -+ -+#define CHECK_HAVE_WARN(node, propname) \ -+ do { \ -+ if (! (prop = get_property((node), (propname)))) \ -+ WARNMSG("%s has no \"%s\" property\n", \ -+ (node)->fullpath, (propname)); \ -+ } while (0) -+ -+#define CHECK_HAVE_STRING(node, propname) \ -+ do { \ -+ CHECK_HAVE((node), (propname)); \ -+ if (prop && !data_is_one_string(prop->val)) \ -+ DO_ERR("\"%s\" property in %s is not a string\n", \ -+ (propname), (node)->fullpath); \ -+ } while (0) -+ -+#define CHECK_HAVE_STREQ(node, propname, value) \ -+ do { \ -+ CHECK_HAVE_STRING((node), (propname)); \ -+ if (prop && !streq(prop->val.val, (value))) \ -+ DO_ERR("%s has wrong %s, %s (should be %s\n", \ -+ (node)->fullpath, (propname), \ -+ prop->val.val, (value)); \ -+ } while (0) -+ -+#define CHECK_HAVE_ONECELL(node, propname) \ -+ do { \ -+ CHECK_HAVE((node), (propname)); \ -+ if (prop && (prop->val.len != sizeof(cell_t))) \ -+ DO_ERR("\"%s\" property in %s has wrong size %d (should be 1 cell)\n", (propname), (node)->fullpath, prop->val.len); \ -+ } while (0) -+ -+#define CHECK_HAVE_WARN_ONECELL(node, propname) \ -+ do { \ -+ CHECK_HAVE_WARN((node), (propname)); \ -+ if (prop && (prop->val.len != sizeof(cell_t))) \ -+ DO_ERR("\"%s\" property in %s has wrong size %d (should be 1 cell)\n", (propname), (node)->fullpath, prop->val.len); \ -+ } while (0) -+ -+#define CHECK_HAVE_WARN_PHANDLE(xnode, propname, root) \ -+ do { \ -+ struct node *ref; \ -+ CHECK_HAVE_WARN_ONECELL((xnode), (propname)); \ -+ if (prop) {\ -+ cell_t phandle = propval_cell(prop); \ -+ if ((phandle == 0) || (phandle == -1)) { \ -+ DO_ERR("\"%s\" property in %s contains an invalid phandle %x\n", (propname), (xnode)->fullpath, phandle); \ -+ } else { \ -+ ref = get_node_by_phandle((root), propval_cell(prop)); \ -+ if (! ref) \ -+ DO_ERR("\"%s\" property in %s refers to non-existant phandle %x\n", (propname), (xnode)->fullpath, propval_cell(prop)); \ -+ } \ -+ } \ -+ } while (0) -+ -+#define CHECK_HAVE_WARN_STRING(node, propname) \ -+ do { \ -+ CHECK_HAVE_WARN((node), (propname)); \ -+ if (prop && !data_is_one_string(prop->val)) \ -+ DO_ERR("\"%s\" property in %s is not a string\n", \ -+ (propname), (node)->fullpath); \ -+ } while (0) -+ -+static int check_root(struct node *root) -+{ -+ struct property *prop; -+ int ok = 1; -+ -+ CHECK_HAVE_STRING(root, "model"); -+ CHECK_HAVE_WARN(root, "compatible"); -+ -+ return ok; -+} -+ -+static int check_cpus(struct node *root, int outversion, int boot_cpuid_phys) -+{ -+ struct node *cpus, *cpu; -+ struct property *prop; -+ struct node *bootcpu = NULL; -+ int ok = 1; -+ -+ cpus = get_subnode(root, "cpus"); -+ if (! cpus) { -+ ERRMSG("Missing /cpus node\n"); -+ return 0; -+ } -+ -+ if (cpus->addr_cells != 1) -+ DO_ERR("%s has bad #address-cells value %d (should be 1)\n", -+ cpus->fullpath, cpus->addr_cells); -+ if (cpus->size_cells != 0) -+ DO_ERR("%s has bad #size-cells value %d (should be 0)\n", -+ cpus->fullpath, cpus->size_cells); -+ -+ for_each_child(cpus, cpu) { -+ CHECK_HAVE_STREQ(cpu, "device_type", "cpu"); -+ -+ CHECK_HAVE_ONECELL(cpu, "reg"); -+ if (prop) { -+ cell_t unitnum; -+ char *eptr; -+ -+ unitnum = strtol(get_unitname(cpu), &eptr, 16); -+ if (*eptr) { -+ WARNMSG("%s has bad format unit name %s (should be CPU number\n", -+ cpu->fullpath, get_unitname(cpu)); -+ } else if (unitnum != propval_cell(prop)) { -+ WARNMSG("%s unit name \"%s\" does not match \"reg\" property <%x>\n", -+ cpu->fullpath, get_unitname(cpu), -+ propval_cell(prop)); -+ } -+ } -+ -+/* CHECK_HAVE_ONECELL(cpu, "d-cache-line-size"); */ -+/* CHECK_HAVE_ONECELL(cpu, "i-cache-line-size"); */ -+ CHECK_HAVE_ONECELL(cpu, "d-cache-size"); -+ CHECK_HAVE_ONECELL(cpu, "i-cache-size"); -+ -+ CHECK_HAVE_WARN_ONECELL(cpu, "clock-frequency"); -+ CHECK_HAVE_WARN_ONECELL(cpu, "timebase-frequency"); -+ -+ prop = get_property(cpu, "linux,boot-cpu"); -+ if (prop) { -+ if (prop->val.len) -+ WARNMSG("\"linux,boot-cpu\" property in %s is non-empty\n", -+ cpu->fullpath); -+ if (bootcpu) -+ DO_ERR("Multiple boot cpus (%s and %s)\n", -+ bootcpu->fullpath, cpu->fullpath); -+ else -+ bootcpu = cpu; -+ } -+ } -+ -+ if (outversion < 2) { -+ if (! bootcpu) -+ WARNMSG("No cpu has \"linux,boot-cpu\" property\n"); -+ } else { -+ if (bootcpu) -+ WARNMSG("\"linux,boot-cpu\" property is deprecated in blob version 2 or higher\n"); -+ if (boot_cpuid_phys == 0xfeedbeef) -+ WARNMSG("physical boot CPU not set. Use -b option to set\n"); -+ } -+ -+ return ok; -+} -+ -+static int check_memory(struct node *root) -+{ -+ struct node *mem; -+ struct property *prop; -+ int nnodes = 0; -+ int ok = 1; -+ -+ for_each_child(root, mem) { -+ if (! strneq(mem->name, "memory", mem->basenamelen)) -+ continue; -+ -+ nnodes++; -+ -+ CHECK_HAVE_STREQ(mem, "device_type", "memory"); -+ CHECK_HAVE(mem, "reg"); -+ } -+ -+ if (nnodes == 0) { -+ ERRMSG("No memory nodes\n"); -+ return 0; -+ } -+ -+ return ok; -+} -+ -+int check_semantics(struct node *dt, int outversion, int boot_cpuid_phys) -+{ -+ int ok = 1; -+ -+ ok = ok && check_root(dt); -+ ok = ok && check_cpus(dt, outversion, boot_cpuid_phys); -+ ok = ok && check_memory(dt); -+ if (! ok) -+ return 0; -+ -+ return 1; -+} ---- /dev/null -+++ b/arch/powerpc/boot/dtc-src/data.c -@@ -0,0 +1,321 @@ -+/* -+ * (C) Copyright David Gibson , IBM Corporation. 2005. -+ * -+ * -+ * 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 "dtc.h" -+ -+void data_free(struct data d) -+{ -+ struct marker *m, *nm; -+ -+ m = d.markers; -+ while (m) { -+ nm = m->next; -+ free(m->ref); -+ free(m); -+ m = nm; -+ } -+ -+ assert(!d.val || d.asize); -+ -+ if (d.val) -+ free(d.val); -+} -+ -+struct data data_grow_for(struct data d, int xlen) -+{ -+ struct data nd; -+ int newsize; -+ -+ /* we must start with an allocated datum */ -+ assert(!d.val || d.asize); -+ -+ if (xlen == 0) -+ return d; -+ -+ nd = d; -+ -+ newsize = xlen; -+ -+ while ((d.len + xlen) > newsize) -+ newsize *= 2; -+ -+ nd.asize = newsize; -+ nd.val = xrealloc(d.val, newsize); -+ -+ assert(nd.asize >= (d.len + xlen)); -+ -+ return nd; -+} -+ -+struct data data_copy_mem(const char *mem, int len) -+{ -+ struct data d; -+ -+ d = data_grow_for(empty_data, len); -+ -+ d.len = len; -+ memcpy(d.val, mem, len); -+ -+ return d; -+} -+ -+static char get_oct_char(const char *s, int *i) -+{ -+ char x[4]; -+ char *endx; -+ long val; -+ -+ x[3] = '\0'; -+ x[0] = s[(*i)]; -+ if (x[0]) { -+ x[1] = s[(*i)+1]; -+ if (x[1]) -+ x[2] = s[(*i)+2]; -+ } -+ -+ val = strtol(x, &endx, 8); -+ if ((endx - x) == 0) -+ fprintf(stderr, "Empty \\nnn escape\n"); -+ -+ (*i) += endx - x; -+ return val; -+} -+ -+static char get_hex_char(const char *s, int *i) -+{ -+ char x[3]; -+ char *endx; -+ long val; -+ -+ x[2] = '\0'; -+ x[0] = s[(*i)]; -+ if (x[0]) -+ x[1] = s[(*i)+1]; -+ -+ val = strtol(x, &endx, 16); -+ if ((endx - x) == 0) -+ fprintf(stderr, "Empty \\x escape\n"); -+ -+ (*i) += endx - x; -+ return val; -+} -+ -+struct data data_copy_escape_string(const char *s, int len) -+{ -+ int i = 0; -+ struct data d; -+ char *q; -+ -+ d = data_grow_for(empty_data, strlen(s)+1); -+ -+ q = d.val; -+ while (i < len) { -+ char c = s[i++]; -+ -+ if (c != '\\') { -+ q[d.len++] = c; -+ continue; -+ } -+ -+ c = s[i++]; -+ assert(c); -+ switch (c) { -+ case 'a': -+ q[d.len++] = '\a'; -+ break; -+ case 'b': -+ q[d.len++] = '\b'; -+ break; -+ case 't': -+ q[d.len++] = '\t'; -+ break; -+ case 'n': -+ q[d.len++] = '\n'; -+ break; -+ case 'v': -+ q[d.len++] = '\v'; -+ break; -+ case 'f': -+ q[d.len++] = '\f'; -+ break; -+ case 'r': -+ q[d.len++] = '\r'; -+ break; -+ case '0': -+ case '1': -+ case '2': -+ case '3': -+ case '4': -+ case '5': -+ case '6': -+ case '7': -+ i--; /* need to re-read the first digit as -+ * part of the octal value */ -+ q[d.len++] = get_oct_char(s, &i); -+ break; -+ case 'x': -+ q[d.len++] = get_hex_char(s, &i); -+ break; -+ default: -+ q[d.len++] = c; -+ } -+ } -+ -+ q[d.len++] = '\0'; -+ return d; -+} -+ -+struct data data_copy_file(FILE *f, size_t len) -+{ -+ struct data d; -+ -+ d = data_grow_for(empty_data, len); -+ -+ d.len = len; -+ fread(d.val, len, 1, f); -+ -+ return d; -+} -+ -+struct data data_append_data(struct data d, const void *p, int len) -+{ -+ d = data_grow_for(d, len); -+ memcpy(d.val + d.len, p, len); -+ d.len += len; -+ return d; -+} -+ -+struct data data_insert_at_marker(struct data d, struct marker *m, -+ const void *p, int len) -+{ -+ d = data_grow_for(d, len); -+ memmove(d.val + m->offset + len, d.val + m->offset, d.len - m->offset); -+ memcpy(d.val + m->offset, p, len); -+ d.len += len; -+ -+ /* Adjust all markers after the one we're inserting at */ -+ m = m->next; -+ for_each_marker(m) -+ m->offset += len; -+ return d; -+} -+ -+struct data data_append_markers(struct data d, struct marker *m) -+{ -+ struct marker **mp = &d.markers; -+ -+ /* Find the end of the markerlist */ -+ while (*mp) -+ mp = &((*mp)->next); -+ *mp = m; -+ return d; -+} -+ -+struct data data_merge(struct data d1, struct data d2) -+{ -+ struct data d; -+ struct marker *m2 = d2.markers; -+ -+ d = data_append_markers(data_append_data(d1, d2.val, d2.len), m2); -+ -+ /* Adjust for the length of d1 */ -+ for_each_marker(m2) -+ m2->offset += d1.len; -+ -+ d2.markers = NULL; /* So data_free() doesn't clobber them */ -+ data_free(d2); -+ -+ return d; -+} -+ -+struct data data_append_cell(struct data d, cell_t word) -+{ -+ cell_t beword = cpu_to_be32(word); -+ -+ return data_append_data(d, &beword, sizeof(beword)); -+} -+ -+struct data data_append_re(struct data d, const struct fdt_reserve_entry *re) -+{ -+ struct fdt_reserve_entry bere; -+ -+ bere.address = cpu_to_be64(re->address); -+ bere.size = cpu_to_be64(re->size); -+ -+ return data_append_data(d, &bere, sizeof(bere)); -+} -+ -+struct data data_append_addr(struct data d, u64 addr) -+{ -+ u64 beaddr = cpu_to_be64(addr); -+ -+ return data_append_data(d, &beaddr, sizeof(beaddr)); -+} -+ -+struct data data_append_byte(struct data d, uint8_t byte) -+{ -+ return data_append_data(d, &byte, 1); -+} -+ -+struct data data_append_zeroes(struct data d, int len) -+{ -+ d = data_grow_for(d, len); -+ -+ memset(d.val + d.len, 0, len); -+ d.len += len; -+ return d; -+} -+ -+struct data data_append_align(struct data d, int align) -+{ -+ int newlen = ALIGN(d.len, align); -+ return data_append_zeroes(d, newlen - d.len); -+} -+ -+struct data data_add_marker(struct data d, enum markertype type, char *ref) -+{ -+ struct marker *m; -+ -+ m = xmalloc(sizeof(*m)); -+ m->offset = d.len; -+ m->type = type; -+ m->ref = ref; -+ m->next = NULL; -+ -+ return data_append_markers(d, m); -+} -+ -+int data_is_one_string(struct data d) -+{ -+ int i; -+ int len = d.len; -+ -+ if (len == 0) -+ return 0; -+ -+ for (i = 0; i < len-1; i++) -+ if (d.val[i] == '\0') -+ return 0; -+ -+ if (d.val[len-1] != '\0') -+ return 0; -+ -+ return 1; -+} ---- /dev/null -+++ b/arch/powerpc/boot/dtc-src/dtc-lexer.l -@@ -0,0 +1,328 @@ -+/* -+ * (C) Copyright David Gibson , IBM Corporation. 2005. -+ * -+ * -+ * 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 -+ */ -+ -+%option noyywrap nounput yylineno -+ -+%x INCLUDE -+%x BYTESTRING -+%x PROPNODENAME -+%s V1 -+ -+PROPNODECHAR [a-zA-Z0-9,._+*#?@-] -+PATHCHAR ({PROPNODECHAR}|[/]) -+LABEL [a-zA-Z_][a-zA-Z0-9_]* -+ -+%{ -+#include "dtc.h" -+#include "srcpos.h" -+#include "dtc-parser.tab.h" -+ -+ -+/*#define LEXDEBUG 1*/ -+ -+#ifdef LEXDEBUG -+#define DPRINT(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__) -+#else -+#define DPRINT(fmt, ...) do { } while (0) -+#endif -+ -+static int dts_version; /* = 0 */ -+ -+#define BEGIN_DEFAULT() if (dts_version == 0) { \ -+ DPRINT("\n"); \ -+ BEGIN(INITIAL); \ -+ } else { \ -+ DPRINT("\n"); \ -+ BEGIN(V1); \ -+ } -+%} -+ -+%% -+<*>"/include/" BEGIN(INCLUDE); -+ -+\"[^"\n]*\" { -+ yytext[strlen(yytext) - 1] = 0; -+ if (!push_input_file(yytext + 1)) { -+ /* Some unrecoverable error.*/ -+ exit(1); -+ } -+ BEGIN_DEFAULT(); -+ } -+ -+ -+<*><> { -+ if (!pop_input_file()) { -+ yyterminate(); -+ } -+ } -+ -+<*>\"([^\\"]|\\.)*\" { -+ yylloc.filenum = srcpos_filenum; -+ yylloc.first_line = yylineno; -+ DPRINT("String: %s\n", yytext); -+ yylval.data = data_copy_escape_string(yytext+1, -+ yyleng-2); -+ yylloc.first_line = yylineno; -+ return DT_STRING; -+ } -+ -+<*>"/dts-v1/" { -+ yylloc.filenum = srcpos_filenum; -+ yylloc.first_line = yylineno; -+ DPRINT("Keyword: /dts-v1/\n"); -+ dts_version = 1; -+ BEGIN_DEFAULT(); -+ return DT_V1; -+ } -+ -+<*>"/memreserve/" { -+ yylloc.filenum = srcpos_filenum; -+ yylloc.first_line = yylineno; -+ DPRINT("Keyword: /memreserve/\n"); -+ BEGIN_DEFAULT(); -+ return DT_MEMRESERVE; -+ } -+ -+<*>{LABEL}: { -+ yylloc.filenum = srcpos_filenum; -+ yylloc.first_line = yylineno; -+ DPRINT("Label: %s\n", yytext); -+ yylval.labelref = strdup(yytext); -+ yylval.labelref[yyleng-1] = '\0'; -+ return DT_LABEL; -+ } -+ -+[bodh]# { -+ yylloc.filenum = srcpos_filenum; -+ yylloc.first_line = yylineno; -+ if (*yytext == 'b') -+ yylval.cbase = 2; -+ else if (*yytext == 'o') -+ yylval.cbase = 8; -+ else if (*yytext == 'd') -+ yylval.cbase = 10; -+ else -+ yylval.cbase = 16; -+ DPRINT("Base: %d\n", yylval.cbase); -+ return DT_BASE; -+ } -+ -+[0-9a-fA-F]+ { -+ yylloc.filenum = srcpos_filenum; -+ yylloc.first_line = yylineno; -+ yylval.literal = strdup(yytext); -+ DPRINT("Literal: '%s'\n", yylval.literal); -+ return DT_LEGACYLITERAL; -+ } -+ -+[0-9]+|0[xX][0-9a-fA-F]+ { -+ yylloc.filenum = srcpos_filenum; -+ yylloc.first_line = yylineno; -+ yylval.literal = strdup(yytext); -+ DPRINT("Literal: '%s'\n", yylval.literal); -+ return DT_LITERAL; -+ } -+ -+\&{LABEL} { /* label reference */ -+ yylloc.filenum = srcpos_filenum; -+ yylloc.first_line = yylineno; -+ DPRINT("Ref: %s\n", yytext+1); -+ yylval.labelref = strdup(yytext+1); -+ return DT_REF; -+ } -+ -+"&{/"{PATHCHAR}+\} { /* new-style path reference */ -+ yylloc.filenum = srcpos_filenum; -+ yylloc.first_line = yylineno; -+ yytext[yyleng-1] = '\0'; -+ DPRINT("Ref: %s\n", yytext+2); -+ yylval.labelref = strdup(yytext+2); -+ return DT_REF; -+ } -+ -+"&/"{PATHCHAR}+ { /* old-style path reference */ -+ yylloc.filenum = srcpos_filenum; -+ yylloc.first_line = yylineno; -+ DPRINT("Ref: %s\n", yytext+1); -+ yylval.labelref = strdup(yytext+1); -+ return DT_REF; -+ } -+ -+[0-9a-fA-F]{2} { -+ yylloc.filenum = srcpos_filenum; -+ yylloc.first_line = yylineno; -+ yylval.byte = strtol(yytext, NULL, 16); -+ DPRINT("Byte: %02x\n", (int)yylval.byte); -+ return DT_BYTE; -+ } -+ -+"]" { -+ yylloc.filenum = srcpos_filenum; -+ yylloc.first_line = yylineno; -+ DPRINT("/BYTESTRING\n"); -+ BEGIN_DEFAULT(); -+ return ']'; -+ } -+ -+{PROPNODECHAR}+ { -+ yylloc.filenum = srcpos_filenum; -+ yylloc.first_line = yylineno; -+ DPRINT("PropNodeName: %s\n", yytext); -+ yylval.propnodename = strdup(yytext); -+ BEGIN_DEFAULT(); -+ return DT_PROPNODENAME; -+ } -+ -+ -+<*>[[:space:]]+ /* eat whitespace */ -+ -+<*>"/*"([^*]|\*+[^*/])*\*+"/" { -+ yylloc.filenum = srcpos_filenum; -+ yylloc.first_line = yylineno; -+ DPRINT("Comment: %s\n", yytext); -+ /* eat comments */ -+ } -+ -+<*>"//".*\n /* eat line comments */ -+ -+<*>. { -+ yylloc.filenum = srcpos_filenum; -+ yylloc.first_line = yylineno; -+ DPRINT("Char: %c (\\x%02x)\n", yytext[0], -+ (unsigned)yytext[0]); -+ if (yytext[0] == '[') { -+ DPRINT("\n"); -+ BEGIN(BYTESTRING); -+ } -+ if ((yytext[0] == '{') -+ || (yytext[0] == ';')) { -+ DPRINT("\n"); -+ BEGIN(PROPNODENAME); -+ } -+ return yytext[0]; -+ } -+ -+%% -+ -+ -+/* -+ * Stack of nested include file contexts. -+ */ -+ -+struct incl_file { -+ int filenum; -+ FILE *file; -+ YY_BUFFER_STATE yy_prev_buf; -+ int yy_prev_lineno; -+ struct incl_file *prev; -+}; -+ -+struct incl_file *incl_file_stack; -+ -+ -+/* -+ * Detect infinite include recursion. -+ */ -+#define MAX_INCLUDE_DEPTH (100) -+ -+static int incl_depth = 0; -+ -+ -+int push_input_file(const char *filename) -+{ -+ FILE *f; -+ struct incl_file *incl_file; -+ -+ if (!filename) { -+ yyerror("No include file name given."); -+ return 0; -+ } -+ -+ if (incl_depth++ >= MAX_INCLUDE_DEPTH) { -+ yyerror("Includes nested too deeply"); -+ return 0; -+ } -+ -+ f = dtc_open_file(filename); -+ -+ incl_file = malloc(sizeof(struct incl_file)); -+ if (!incl_file) { -+ yyerror("Can not allocate include file space."); -+ return 0; -+ } -+ -+ /* -+ * Save current context. -+ */ -+ incl_file->yy_prev_buf = YY_CURRENT_BUFFER; -+ incl_file->yy_prev_lineno = yylineno; -+ incl_file->filenum = srcpos_filenum; -+ incl_file->file = yyin; -+ incl_file->prev = incl_file_stack; -+ -+ incl_file_stack = incl_file; -+ -+ /* -+ * Establish new context. -+ */ -+ srcpos_filenum = lookup_file_name(filename, 0); -+ yylineno = 1; -+ yyin = f; -+ yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); -+ -+ return 1; -+} -+ -+ -+int pop_input_file(void) -+{ -+ struct incl_file *incl_file; -+ -+ if (incl_file_stack == 0) -+ return 0; -+ -+ fclose(yyin); -+ -+ /* -+ * Pop. -+ */ -+ --incl_depth; -+ incl_file = incl_file_stack; -+ incl_file_stack = incl_file->prev; -+ -+ /* -+ * Recover old context. -+ */ -+ yy_delete_buffer(YY_CURRENT_BUFFER); -+ yy_switch_to_buffer(incl_file->yy_prev_buf); -+ yylineno = incl_file->yy_prev_lineno; -+ srcpos_filenum = incl_file->filenum; -+ yyin = incl_file->file; -+ -+ /* -+ * Free old state. -+ */ -+ free(incl_file); -+ -+ if (YY_CURRENT_BUFFER == 0) -+ return 0; -+ -+ return 1; -+} ---- /dev/null -+++ b/arch/powerpc/boot/dtc-src/dtc-lexer.lex.c_shipped -@@ -0,0 +1,2174 @@ -+#line 2 "dtc-lexer.lex.c" -+ -+#line 4 "dtc-lexer.lex.c" -+ -+#define YY_INT_ALIGNED short int -+ -+/* A lexical scanner generated by flex */ -+ -+#define FLEX_SCANNER -+#define YY_FLEX_MAJOR_VERSION 2 -+#define YY_FLEX_MINOR_VERSION 5 -+#define YY_FLEX_SUBMINOR_VERSION 33 -+#if YY_FLEX_SUBMINOR_VERSION > 0 -+#define FLEX_BETA -+#endif -+ -+/* First, we deal with platform-specific or compiler-specific issues. */ -+ -+/* begin standard C headers. */ -+#include -+#include -+#include -+#include -+ -+/* end standard C headers. */ -+ -+/* flex integer type definitions */ -+ -+#ifndef FLEXINT_H -+#define FLEXINT_H -+ -+/* C99 systems have . Non-C99 systems may or may not. */ -+ -+#if __STDC_VERSION__ >= 199901L -+ -+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, -+ * if you want the limit (max/min) macros for int types. -+ */ -+#ifndef __STDC_LIMIT_MACROS -+#define __STDC_LIMIT_MACROS 1 -+#endif -+ -+#include -+typedef int8_t flex_int8_t; -+typedef uint8_t flex_uint8_t; -+typedef int16_t flex_int16_t; -+typedef uint16_t flex_uint16_t; -+typedef int32_t flex_int32_t; -+typedef uint32_t flex_uint32_t; -+#else -+typedef signed char flex_int8_t; -+typedef short int flex_int16_t; -+typedef int flex_int32_t; -+typedef unsigned char flex_uint8_t; -+typedef unsigned short int flex_uint16_t; -+typedef unsigned int flex_uint32_t; -+#endif /* ! C99 */ -+ -+/* Limits of integral types. */ -+#ifndef INT8_MIN -+#define INT8_MIN (-128) -+#endif -+#ifndef INT16_MIN -+#define INT16_MIN (-32767-1) -+#endif -+#ifndef INT32_MIN -+#define INT32_MIN (-2147483647-1) -+#endif -+#ifndef INT8_MAX -+#define INT8_MAX (127) -+#endif -+#ifndef INT16_MAX -+#define INT16_MAX (32767) -+#endif -+#ifndef INT32_MAX -+#define INT32_MAX (2147483647) -+#endif -+#ifndef UINT8_MAX -+#define UINT8_MAX (255U) -+#endif -+#ifndef UINT16_MAX -+#define UINT16_MAX (65535U) -+#endif -+#ifndef UINT32_MAX -+#define UINT32_MAX (4294967295U) -+#endif -+ -+#endif /* ! FLEXINT_H */ -+ -+#ifdef __cplusplus -+ -+/* The "const" storage-class-modifier is valid. */ -+#define YY_USE_CONST -+ -+#else /* ! __cplusplus */ -+ -+#if __STDC__ -+ -+#define YY_USE_CONST -+ -+#endif /* __STDC__ */ -+#endif /* ! __cplusplus */ -+ -+#ifdef YY_USE_CONST -+#define yyconst const -+#else -+#define yyconst -+#endif -+ -+/* Returned upon end-of-file. */ -+#define YY_NULL 0 -+ -+/* Promotes a possibly negative, possibly signed char to an unsigned -+ * integer for use as an array index. If the signed char is negative, -+ * we want to instead treat it as an 8-bit unsigned char, hence the -+ * double cast. -+ */ -+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) -+ -+/* Enter a start condition. This macro really ought to take a parameter, -+ * but we do it the disgusting crufty way forced on us by the ()-less -+ * definition of BEGIN. -+ */ -+#define BEGIN (yy_start) = 1 + 2 * -+ -+/* Translate the current start state into a value that can be later handed -+ * to BEGIN to return to the state. The YYSTATE alias is for lex -+ * compatibility. -+ */ -+#define YY_START (((yy_start) - 1) / 2) -+#define YYSTATE YY_START -+ -+/* Action number for EOF rule of a given start state. */ -+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) -+ -+/* Special action meaning "start processing a new file". */ -+#define YY_NEW_FILE yyrestart(yyin ) -+ -+#define YY_END_OF_BUFFER_CHAR 0 -+ -+/* Size of default input buffer. */ -+#ifndef YY_BUF_SIZE -+#define YY_BUF_SIZE 16384 -+#endif -+ -+/* The state buf must be large enough to hold one state per character in the main buffer. -+ */ -+#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) -+ -+#ifndef YY_TYPEDEF_YY_BUFFER_STATE -+#define YY_TYPEDEF_YY_BUFFER_STATE -+typedef struct yy_buffer_state *YY_BUFFER_STATE; -+#endif -+ -+extern int yyleng; -+ -+extern FILE *yyin, *yyout; -+ -+#define EOB_ACT_CONTINUE_SCAN 0 -+#define EOB_ACT_END_OF_FILE 1 -+#define EOB_ACT_LAST_MATCH 2 -+ -+ /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires -+ * access to the local variable yy_act. Since yyless() is a macro, it would break -+ * existing scanners that call yyless() from OUTSIDE yylex. -+ * One obvious solution it to make yy_act a global. I tried that, and saw -+ * a 5% performance hit in a non-yylineno scanner, because yy_act is -+ * normally declared as a register variable-- so it is not worth it. -+ */ -+ #define YY_LESS_LINENO(n) \ -+ do { \ -+ int yyl;\ -+ for ( yyl = n; yyl < yyleng; ++yyl )\ -+ if ( yytext[yyl] == '\n' )\ -+ --yylineno;\ -+ }while(0) -+ -+/* Return all but the first "n" matched characters back to the input stream. */ -+#define yyless(n) \ -+ do \ -+ { \ -+ /* Undo effects of setting up yytext. */ \ -+ int yyless_macro_arg = (n); \ -+ YY_LESS_LINENO(yyless_macro_arg);\ -+ *yy_cp = (yy_hold_char); \ -+ YY_RESTORE_YY_MORE_OFFSET \ -+ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ -+ YY_DO_BEFORE_ACTION; /* set up yytext again */ \ -+ } \ -+ while ( 0 ) -+ -+#define unput(c) yyunput( c, (yytext_ptr) ) -+ -+/* The following is because we cannot portably get our hands on size_t -+ * (without autoconf's help, which isn't available because we want -+ * flex-generated scanners to compile on their own). -+ */ -+ -+#ifndef YY_TYPEDEF_YY_SIZE_T -+#define YY_TYPEDEF_YY_SIZE_T -+typedef unsigned int yy_size_t; -+#endif -+ -+#ifndef YY_STRUCT_YY_BUFFER_STATE -+#define YY_STRUCT_YY_BUFFER_STATE -+struct yy_buffer_state -+ { -+ FILE *yy_input_file; -+ -+ char *yy_ch_buf; /* input buffer */ -+ char *yy_buf_pos; /* current position in input buffer */ -+ -+ /* Size of input buffer in bytes, not including room for EOB -+ * characters. -+ */ -+ yy_size_t yy_buf_size; -+ -+ /* Number of characters read into yy_ch_buf, not including EOB -+ * characters. -+ */ -+ int yy_n_chars; -+ -+ /* Whether we "own" the buffer - i.e., we know we created it, -+ * and can realloc() it to grow it, and should free() it to -+ * delete it. -+ */ -+ int yy_is_our_buffer; -+ -+ /* Whether this is an "interactive" input source; if so, and -+ * if we're using stdio for input, then we want to use getc() -+ * instead of fread(), to make sure we stop fetching input after -+ * each newline. -+ */ -+ int yy_is_interactive; -+ -+ /* Whether we're considered to be at the beginning of a line. -+ * If so, '^' rules will be active on the next match, otherwise -+ * not. -+ */ -+ int yy_at_bol; -+ -+ int yy_bs_lineno; /**< The line count. */ -+ int yy_bs_column; /**< The column count. */ -+ -+ /* Whether to try to fill the input buffer when we reach the -+ * end of it. -+ */ -+ int yy_fill_buffer; -+ -+ int yy_buffer_status; -+ -+#define YY_BUFFER_NEW 0 -+#define YY_BUFFER_NORMAL 1 -+ /* When an EOF's been seen but there's still some text to process -+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we -+ * shouldn't try reading from the input source any more. We might -+ * still have a bunch of tokens to match, though, because of -+ * possible backing-up. -+ * -+ * When we actually see the EOF, we change the status to "new" -+ * (via yyrestart()), so that the user can continue scanning by -+ * just pointing yyin at a new input file. -+ */ -+#define YY_BUFFER_EOF_PENDING 2 -+ -+ }; -+#endif /* !YY_STRUCT_YY_BUFFER_STATE */ -+ -+/* Stack of input buffers. */ -+static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ -+static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ -+static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ -+ -+/* We provide macros for accessing buffer states in case in the -+ * future we want to put the buffer states in a more general -+ * "scanner state". -+ * -+ * Returns the top of the stack, or NULL. -+ */ -+#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ -+ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ -+ : NULL) -+ -+/* Same as previous macro, but useful when we know that the buffer stack is not -+ * NULL or when we need an lvalue. For internal use only. -+ */ -+#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] -+ -+/* yy_hold_char holds the character lost when yytext is formed. */ -+static char yy_hold_char; -+static int yy_n_chars; /* number of characters read into yy_ch_buf */ -+int yyleng; -+ -+/* Points to current character in buffer. */ -+static char *yy_c_buf_p = (char *) 0; -+static int yy_init = 0; /* whether we need to initialize */ -+static int yy_start = 0; /* start state number */ -+ -+/* Flag which is used to allow yywrap()'s to do buffer switches -+ * instead of setting up a fresh yyin. A bit of a hack ... -+ */ -+static int yy_did_buffer_switch_on_eof; -+ -+void yyrestart (FILE *input_file ); -+void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ); -+YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ); -+void yy_delete_buffer (YY_BUFFER_STATE b ); -+void yy_flush_buffer (YY_BUFFER_STATE b ); -+void yypush_buffer_state (YY_BUFFER_STATE new_buffer ); -+void yypop_buffer_state (void ); -+ -+static void yyensure_buffer_stack (void ); -+static void yy_load_buffer_state (void ); -+static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); -+ -+#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ) -+ -+YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); -+YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); -+YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len ); -+ -+void *yyalloc (yy_size_t ); -+void *yyrealloc (void *,yy_size_t ); -+void yyfree (void * ); -+ -+#define yy_new_buffer yy_create_buffer -+ -+#define yy_set_interactive(is_interactive) \ -+ { \ -+ if ( ! YY_CURRENT_BUFFER ){ \ -+ yyensure_buffer_stack (); \ -+ YY_CURRENT_BUFFER_LVALUE = \ -+ yy_create_buffer(yyin,YY_BUF_SIZE ); \ -+ } \ -+ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ -+ } -+ -+#define yy_set_bol(at_bol) \ -+ { \ -+ if ( ! YY_CURRENT_BUFFER ){\ -+ yyensure_buffer_stack (); \ -+ YY_CURRENT_BUFFER_LVALUE = \ -+ yy_create_buffer(yyin,YY_BUF_SIZE ); \ -+ } \ -+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ -+ } -+ -+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) -+ -+/* Begin user sect3 */ -+ -+#define yywrap() 1 -+#define YY_SKIP_YYWRAP -+ -+typedef unsigned char YY_CHAR; -+ -+FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; -+ -+typedef int yy_state_type; -+ -+extern int yylineno; -+ -+int yylineno = 1; -+ -+extern char *yytext; -+#define yytext_ptr yytext -+ -+static yy_state_type yy_get_previous_state (void ); -+static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); -+static int yy_get_next_buffer (void ); -+static void yy_fatal_error (yyconst char msg[] ); -+ -+/* Done after the current pattern has been matched and before the -+ * corresponding action - sets up yytext. -+ */ -+#define YY_DO_BEFORE_ACTION \ -+ (yytext_ptr) = yy_bp; \ -+ yyleng = (size_t) (yy_cp - yy_bp); \ -+ (yy_hold_char) = *yy_cp; \ -+ *yy_cp = '\0'; \ -+ (yy_c_buf_p) = yy_cp; -+ -+#define YY_NUM_RULES 20 -+#define YY_END_OF_BUFFER 21 -+/* This struct is not used in this scanner, -+ but its presence is necessary. */ -+struct yy_trans_info -+ { -+ flex_int32_t yy_verify; -+ flex_int32_t yy_nxt; -+ }; -+static yyconst flex_int16_t yy_accept[94] = -+ { 0, -+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -+ 21, 19, 16, 16, 19, 19, 19, 8, 8, 19, -+ 8, 19, 19, 19, 19, 14, 15, 15, 19, 9, -+ 9, 16, 0, 3, 0, 0, 10, 0, 0, 0, -+ 0, 0, 0, 8, 8, 6, 0, 7, 0, 2, -+ 0, 13, 13, 15, 15, 9, 0, 12, 10, 0, -+ 0, 0, 0, 18, 0, 0, 0, 2, 9, 0, -+ 17, 0, 0, 0, 11, 0, 0, 0, 0, 0, -+ 0, 0, 0, 0, 4, 0, 0, 1, 0, 0, -+ 0, 5, 0 -+ -+ } ; -+ -+static yyconst flex_int32_t yy_ec[256] = -+ { 0, -+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, -+ 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -+ 1, 2, 1, 4, 5, 1, 1, 6, 1, 1, -+ 1, 7, 8, 8, 9, 8, 10, 11, 12, 13, -+ 13, 13, 13, 13, 13, 13, 13, 14, 1, 1, -+ 1, 1, 8, 8, 15, 15, 15, 15, 15, 15, -+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, -+ 16, 16, 16, 16, 16, 16, 16, 17, 16, 16, -+ 1, 18, 19, 1, 16, 1, 15, 20, 21, 22, -+ -+ 23, 15, 16, 24, 25, 16, 16, 26, 27, 28, -+ 24, 16, 16, 29, 30, 31, 32, 33, 16, 17, -+ 16, 16, 34, 1, 35, 1, 1, 1, 1, 1, -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -+ -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -+ 1, 1, 1, 1, 1 -+ } ; -+ -+static yyconst flex_int32_t yy_meta[36] = -+ { 0, -+ 1, 1, 1, 1, 2, 1, 2, 2, 2, 3, -+ 4, 4, 4, 5, 6, 7, 7, 1, 1, 6, -+ 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, -+ 7, 7, 7, 8, 1 -+ } ; -+ -+static yyconst flex_int16_t yy_base[107] = -+ { 0, -+ 0, 0, 32, 0, 53, 0, 76, 0, 108, 111, -+ 280, 288, 37, 39, 33, 36, 106, 0, 123, 146, -+ 255, 251, 45, 0, 159, 288, 0, 53, 108, 172, -+ 114, 127, 158, 288, 245, 0, 0, 234, 235, 236, -+ 197, 195, 199, 0, 0, 288, 0, 288, 160, 288, -+ 183, 288, 0, 0, 183, 182, 0, 0, 0, 0, -+ 204, 189, 207, 288, 179, 187, 180, 194, 0, 171, -+ 288, 196, 178, 174, 288, 169, 169, 177, 165, 153, -+ 143, 155, 137, 118, 288, 122, 42, 288, 36, 36, -+ 40, 288, 288, 212, 218, 223, 229, 234, 239, 245, -+ -+ 251, 255, 262, 270, 275, 280 -+ } ; -+ -+static yyconst flex_int16_t yy_def[107] = -+ { 0, -+ 93, 1, 1, 3, 3, 5, 93, 7, 3, 3, -+ 93, 93, 93, 93, 94, 95, 93, 96, 93, 19, -+ 19, 20, 97, 98, 20, 93, 99, 100, 95, 93, -+ 93, 93, 94, 93, 94, 101, 102, 93, 103, 104, -+ 93, 93, 93, 96, 19, 93, 20, 93, 97, 93, -+ 97, 93, 20, 99, 100, 93, 105, 101, 102, 106, -+ 103, 103, 104, 93, 93, 93, 93, 94, 105, 106, -+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, -+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, -+ 93, 93, 0, 93, 93, 93, 93, 93, 93, 93, -+ -+ 93, 93, 93, 93, 93, 93 -+ } ; -+ -+static yyconst flex_int16_t yy_nxt[324] = -+ { 0, -+ 12, 13, 14, 15, 12, 16, 12, 12, 12, 17, -+ 18, 18, 18, 12, 19, 20, 20, 12, 12, 21, -+ 19, 21, 19, 22, 20, 20, 20, 20, 20, 20, -+ 20, 20, 20, 12, 12, 23, 34, 12, 32, 32, -+ 32, 32, 12, 12, 12, 36, 20, 33, 50, 92, -+ 35, 20, 20, 20, 20, 20, 15, 54, 91, 54, -+ 54, 54, 51, 24, 24, 24, 46, 25, 90, 38, -+ 89, 26, 25, 25, 25, 25, 12, 13, 14, 15, -+ 27, 12, 27, 27, 27, 17, 27, 27, 27, 12, -+ 28, 28, 28, 12, 12, 28, 28, 28, 28, 28, -+ -+ 28, 28, 28, 28, 28, 28, 28, 28, 28, 12, -+ 12, 15, 39, 29, 15, 40, 29, 93, 30, 31, -+ 31, 30, 31, 31, 56, 56, 56, 41, 32, 32, -+ 42, 88, 43, 45, 45, 45, 46, 45, 47, 47, -+ 87, 38, 45, 45, 45, 45, 47, 47, 47, 47, -+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 86, -+ 47, 34, 33, 50, 85, 47, 47, 47, 47, 53, -+ 53, 53, 84, 53, 83, 35, 82, 51, 53, 53, -+ 53, 53, 56, 56, 56, 93, 68, 54, 57, 54, -+ 54, 54, 56, 56, 56, 62, 46, 34, 71, 81, -+ -+ 80, 79, 78, 77, 76, 75, 74, 73, 72, 64, -+ 62, 35, 33, 33, 33, 33, 33, 33, 33, 33, -+ 37, 67, 66, 37, 37, 37, 44, 65, 44, 49, -+ 49, 49, 49, 49, 49, 49, 49, 52, 64, 52, -+ 54, 62, 54, 60, 54, 54, 55, 93, 55, 55, -+ 55, 55, 58, 58, 58, 48, 58, 58, 59, 48, -+ 59, 59, 61, 61, 61, 61, 61, 61, 61, 61, -+ 63, 63, 63, 63, 63, 63, 63, 63, 69, 93, -+ 69, 70, 70, 70, 93, 70, 70, 11, 93, 93, -+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, -+ -+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, -+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, -+ 93, 93, 93 -+ } ; -+ -+static yyconst flex_int16_t yy_chk[324] = -+ { 0, -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -+ 1, 1, 1, 1, 1, 3, 15, 3, 13, 13, -+ 14, 14, 3, 3, 3, 16, 3, 23, 23, 91, -+ 15, 3, 3, 3, 3, 3, 5, 28, 90, 28, -+ 28, 28, 23, 5, 5, 5, 28, 5, 89, 16, -+ 87, 5, 5, 5, 5, 5, 7, 7, 7, 7, -+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -+ -+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -+ 7, 9, 17, 9, 10, 17, 10, 29, 9, 9, -+ 9, 10, 10, 10, 31, 31, 31, 17, 32, 32, -+ 17, 86, 17, 19, 19, 19, 19, 19, 19, 19, -+ 84, 29, 19, 19, 19, 19, 19, 19, 19, 19, -+ 19, 19, 19, 19, 19, 19, 20, 20, 20, 83, -+ 20, 33, 49, 49, 82, 20, 20, 20, 20, 25, -+ 25, 25, 81, 25, 80, 33, 79, 49, 25, 25, -+ 25, 25, 30, 30, 30, 51, 51, 55, 30, 55, -+ 55, 55, 56, 56, 56, 62, 55, 68, 62, 78, -+ -+ 77, 76, 74, 73, 72, 70, 67, 66, 65, 63, -+ 61, 68, 94, 94, 94, 94, 94, 94, 94, 94, -+ 95, 43, 42, 95, 95, 95, 96, 41, 96, 97, -+ 97, 97, 97, 97, 97, 97, 97, 98, 40, 98, -+ 99, 39, 99, 38, 99, 99, 100, 35, 100, 100, -+ 100, 100, 101, 101, 101, 22, 101, 101, 102, 21, -+ 102, 102, 103, 103, 103, 103, 103, 103, 103, 103, -+ 104, 104, 104, 104, 104, 104, 104, 104, 105, 11, -+ 105, 106, 106, 106, 0, 106, 106, 93, 93, 93, -+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, -+ -+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, -+ 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, -+ 93, 93, 93 -+ } ; -+ -+/* Table of booleans, true if rule could match eol. */ -+static yyconst flex_int32_t yy_rule_can_match_eol[21] = -+ { 0, -+0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, -+ 0, }; -+ -+static yy_state_type yy_last_accepting_state; -+static char *yy_last_accepting_cpos; -+ -+extern int yy_flex_debug; -+int yy_flex_debug = 0; -+ -+/* The intent behind this definition is that it'll catch -+ * any uses of REJECT which flex missed. -+ */ -+#define REJECT reject_used_but_not_detected -+#define yymore() yymore_used_but_not_detected -+#define YY_MORE_ADJ 0 -+#define YY_RESTORE_YY_MORE_OFFSET -+char *yytext; -+#line 1 "dtc-lexer.l" -+/* -+ * (C) Copyright David Gibson , IBM Corporation. 2005. -+ * -+ * -+ * 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 -+ */ -+ -+ -+ -+ -+#line 33 "dtc-lexer.l" -+#include "dtc.h" -+#include "srcpos.h" -+#include "dtc-parser.tab.h" -+ -+ -+/*#define LEXDEBUG 1*/ -+ -+#ifdef LEXDEBUG -+#define DPRINT(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__) -+#else -+#define DPRINT(fmt, ...) do { } while (0) -+#endif -+ -+static int dts_version; /* = 0 */ -+ -+#define BEGIN_DEFAULT() if (dts_version == 0) { \ -+ DPRINT("\n"); \ -+ BEGIN(INITIAL); \ -+ } else { \ -+ DPRINT("\n"); \ -+ BEGIN(V1); \ -+ } -+#line 627 "dtc-lexer.lex.c" -+ -+#define INITIAL 0 -+#define INCLUDE 1 -+#define BYTESTRING 2 -+#define PROPNODENAME 3 -+#define V1 4 -+ -+#ifndef YY_NO_UNISTD_H -+/* Special case for "unistd.h", since it is non-ANSI. We include it way -+ * down here because we want the user's section 1 to have been scanned first. -+ * The user has a chance to override it with an option. -+ */ -+#include -+#endif -+ -+#ifndef YY_EXTRA_TYPE -+#define YY_EXTRA_TYPE void * -+#endif -+ -+static int yy_init_globals (void ); -+ -+/* Macros after this point can all be overridden by user definitions in -+ * section 1. -+ */ -+ -+#ifndef YY_SKIP_YYWRAP -+#ifdef __cplusplus -+extern "C" int yywrap (void ); -+#else -+extern int yywrap (void ); -+#endif -+#endif -+ -+#ifndef yytext_ptr -+static void yy_flex_strncpy (char *,yyconst char *,int ); -+#endif -+ -+#ifdef YY_NEED_STRLEN -+static int yy_flex_strlen (yyconst char * ); -+#endif -+ -+#ifndef YY_NO_INPUT -+ -+#ifdef __cplusplus -+static int yyinput (void ); -+#else -+static int input (void ); -+#endif -+ -+#endif -+ -+/* Amount of stuff to slurp up with each read. */ -+#ifndef YY_READ_BUF_SIZE -+#define YY_READ_BUF_SIZE 8192 -+#endif -+ -+/* Copy whatever the last rule matched to the standard output. */ -+#ifndef ECHO -+/* This used to be an fputs(), but since the string might contain NUL's, -+ * we now use fwrite(). -+ */ -+#define ECHO (void) fwrite( yytext, yyleng, 1, yyout ) -+#endif -+ -+/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, -+ * is returned in "result". -+ */ -+#ifndef YY_INPUT -+#define YY_INPUT(buf,result,max_size) \ -+ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ -+ { \ -+ int c = '*'; \ -+ size_t n; \ -+ for ( n = 0; n < max_size && \ -+ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ -+ buf[n] = (char) c; \ -+ if ( c == '\n' ) \ -+ buf[n++] = (char) c; \ -+ if ( c == EOF && ferror( yyin ) ) \ -+ YY_FATAL_ERROR( "input in flex scanner failed" ); \ -+ result = n; \ -+ } \ -+ else \ -+ { \ -+ errno=0; \ -+ while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ -+ { \ -+ if( errno != EINTR) \ -+ { \ -+ YY_FATAL_ERROR( "input in flex scanner failed" ); \ -+ break; \ -+ } \ -+ errno=0; \ -+ clearerr(yyin); \ -+ } \ -+ }\ -+\ -+ -+#endif -+ -+/* No semi-colon after return; correct usage is to write "yyterminate();" - -+ * we don't want an extra ';' after the "return" because that will cause -+ * some compilers to complain about unreachable statements. -+ */ -+#ifndef yyterminate -+#define yyterminate() return YY_NULL -+#endif -+ -+/* Number of entries by which start-condition stack grows. */ -+#ifndef YY_START_STACK_INCR -+#define YY_START_STACK_INCR 25 -+#endif -+ -+/* Report a fatal error. */ -+#ifndef YY_FATAL_ERROR -+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) -+#endif -+ -+/* end tables serialization structures and prototypes */ -+ -+/* Default declaration of generated scanner - a define so the user can -+ * easily add parameters. -+ */ -+#ifndef YY_DECL -+#define YY_DECL_IS_OURS 1 -+ -+extern int yylex (void); -+ -+#define YY_DECL int yylex (void) -+#endif /* !YY_DECL */ -+ -+/* Code executed at the beginning of each rule, after yytext and yyleng -+ * have been set up. -+ */ -+#ifndef YY_USER_ACTION -+#define YY_USER_ACTION -+#endif -+ -+/* Code executed at the end of each rule. */ -+#ifndef YY_BREAK -+#define YY_BREAK break; -+#endif -+ -+#define YY_RULE_SETUP \ -+ YY_USER_ACTION -+ -+/** The main scanner function which does all the work. -+ */ -+YY_DECL -+{ -+ register yy_state_type yy_current_state; -+ register char *yy_cp, *yy_bp; -+ register int yy_act; -+ -+#line 57 "dtc-lexer.l" -+ -+#line 784 "dtc-lexer.lex.c" -+ -+ if ( !(yy_init) ) -+ { -+ (yy_init) = 1; -+ -+#ifdef YY_USER_INIT -+ YY_USER_INIT; -+#endif -+ -+ if ( ! (yy_start) ) -+ (yy_start) = 1; /* first start state */ -+ -+ if ( ! yyin ) -+ yyin = stdin; -+ -+ if ( ! yyout ) -+ yyout = stdout; -+ -+ if ( ! YY_CURRENT_BUFFER ) { -+ yyensure_buffer_stack (); -+ YY_CURRENT_BUFFER_LVALUE = -+ yy_create_buffer(yyin,YY_BUF_SIZE ); -+ } -+ -+ yy_load_buffer_state( ); -+ } -+ -+ while ( 1 ) /* loops until end-of-file is reached */ -+ { -+ yy_cp = (yy_c_buf_p); -+ -+ /* Support of yytext. */ -+ *yy_cp = (yy_hold_char); -+ -+ /* yy_bp points to the position in yy_ch_buf of the start of -+ * the current run. -+ */ -+ yy_bp = yy_cp; -+ -+ yy_current_state = (yy_start); -+yy_match: -+ do -+ { -+ register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; -+ if ( yy_accept[yy_current_state] ) -+ { -+ (yy_last_accepting_state) = yy_current_state; -+ (yy_last_accepting_cpos) = yy_cp; -+ } -+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) -+ { -+ yy_current_state = (int) yy_def[yy_current_state]; -+ if ( yy_current_state >= 94 ) -+ yy_c = yy_meta[(unsigned int) yy_c]; -+ } -+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; -+ ++yy_cp; -+ } -+ while ( yy_base[yy_current_state] != 288 ); -+ -+yy_find_action: -+ yy_act = yy_accept[yy_current_state]; -+ if ( yy_act == 0 ) -+ { /* have to back up */ -+ yy_cp = (yy_last_accepting_cpos); -+ yy_current_state = (yy_last_accepting_state); -+ yy_act = yy_accept[yy_current_state]; -+ } -+ -+ YY_DO_BEFORE_ACTION; -+ -+ if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] ) -+ { -+ int yyl; -+ for ( yyl = 0; yyl < yyleng; ++yyl ) -+ if ( yytext[yyl] == '\n' ) -+ -+ yylineno++; -+; -+ } -+ -+do_action: /* This label is used only to access EOF actions. */ -+ -+ switch ( yy_act ) -+ { /* beginning of action switch */ -+ case 0: /* must back up */ -+ /* undo the effects of YY_DO_BEFORE_ACTION */ -+ *yy_cp = (yy_hold_char); -+ yy_cp = (yy_last_accepting_cpos); -+ yy_current_state = (yy_last_accepting_state); -+ goto yy_find_action; -+ -+case 1: -+YY_RULE_SETUP -+#line 58 "dtc-lexer.l" -+BEGIN(INCLUDE); -+ YY_BREAK -+case 2: -+YY_RULE_SETUP -+#line 60 "dtc-lexer.l" -+{ -+ yytext[strlen(yytext) - 1] = 0; -+ if (!push_input_file(yytext + 1)) { -+ /* Some unrecoverable error.*/ -+ exit(1); -+ } -+ BEGIN_DEFAULT(); -+ } -+ YY_BREAK -+case YY_STATE_EOF(INITIAL): -+case YY_STATE_EOF(INCLUDE): -+case YY_STATE_EOF(BYTESTRING): -+case YY_STATE_EOF(PROPNODENAME): -+case YY_STATE_EOF(V1): -+#line 70 "dtc-lexer.l" -+{ -+ if (!pop_input_file()) { -+ yyterminate(); -+ } -+ } -+ YY_BREAK -+case 3: -+/* rule 3 can match eol */ -+YY_RULE_SETUP -+#line 76 "dtc-lexer.l" -+{ -+ yylloc.filenum = srcpos_filenum; -+ yylloc.first_line = yylineno; -+ DPRINT("String: %s\n", yytext); -+ yylval.data = data_copy_escape_string(yytext+1, -+ yyleng-2); -+ yylloc.first_line = yylineno; -+ return DT_STRING; -+ } -+ YY_BREAK -+case 4: -+YY_RULE_SETUP -+#line 86 "dtc-lexer.l" -+{ -+ yylloc.filenum = srcpos_filenum; -+ yylloc.first_line = yylineno; -+ DPRINT("Keyword: /dts-v1/\n"); -+ dts_version = 1; -+ BEGIN_DEFAULT(); -+ return DT_V1; -+ } -+ YY_BREAK -+case 5: -+YY_RULE_SETUP -+#line 95 "dtc-lexer.l" -+{ -+ yylloc.filenum = srcpos_filenum; -+ yylloc.first_line = yylineno; -+ DPRINT("Keyword: /memreserve/\n"); -+ BEGIN_DEFAULT(); -+ return DT_MEMRESERVE; -+ } -+ YY_BREAK -+case 6: -+YY_RULE_SETUP -+#line 103 "dtc-lexer.l" -+{ -+ yylloc.filenum = srcpos_filenum; -+ yylloc.first_line = yylineno; -+ DPRINT("Label: %s\n", yytext); -+ yylval.labelref = strdup(yytext); -+ yylval.labelref[yyleng-1] = '\0'; -+ return DT_LABEL; -+ } -+ YY_BREAK -+case 7: -+YY_RULE_SETUP -+#line 112 "dtc-lexer.l" -+{ -+ yylloc.filenum = srcpos_filenum; -+ yylloc.first_line = yylineno; -+ if (*yytext == 'b') -+ yylval.cbase = 2; -+ else if (*yytext == 'o') -+ yylval.cbase = 8; -+ else if (*yytext == 'd') -+ yylval.cbase = 10; -+ else -+ yylval.cbase = 16; -+ DPRINT("Base: %d\n", yylval.cbase); -+ return DT_BASE; -+ } -+ YY_BREAK -+case 8: -+YY_RULE_SETUP -+#line 127 "dtc-lexer.l" -+{ -+ yylloc.filenum = srcpos_filenum; -+ yylloc.first_line = yylineno; -+ yylval.literal = strdup(yytext); -+ DPRINT("Literal: '%s'\n", yylval.literal); -+ return DT_LEGACYLITERAL; -+ } -+ YY_BREAK -+case 9: -+YY_RULE_SETUP -+#line 135 "dtc-lexer.l" -+{ -+ yylloc.filenum = srcpos_filenum; -+ yylloc.first_line = yylineno; -+ yylval.literal = strdup(yytext); -+ DPRINT("Literal: '%s'\n", yylval.literal); -+ return DT_LITERAL; -+ } -+ YY_BREAK -+case 10: -+YY_RULE_SETUP -+#line 143 "dtc-lexer.l" -+{ /* label reference */ -+ yylloc.filenum = srcpos_filenum; -+ yylloc.first_line = yylineno; -+ DPRINT("Ref: %s\n", yytext+1); -+ yylval.labelref = strdup(yytext+1); -+ return DT_REF; -+ } -+ YY_BREAK -+case 11: -+YY_RULE_SETUP -+#line 151 "dtc-lexer.l" -+{ /* new-style path reference */ -+ yylloc.filenum = srcpos_filenum; -+ yylloc.first_line = yylineno; -+ yytext[yyleng-1] = '\0'; -+ DPRINT("Ref: %s\n", yytext+2); -+ yylval.labelref = strdup(yytext+2); -+ return DT_REF; -+ } -+ YY_BREAK -+case 12: -+YY_RULE_SETUP -+#line 160 "dtc-lexer.l" -+{ /* old-style path reference */ -+ yylloc.filenum = srcpos_filenum; -+ yylloc.first_line = yylineno; -+ DPRINT("Ref: %s\n", yytext+1); -+ yylval.labelref = strdup(yytext+1); -+ return DT_REF; -+ } -+ YY_BREAK -+case 13: -+YY_RULE_SETUP -+#line 168 "dtc-lexer.l" -+{ -+ yylloc.filenum = srcpos_filenum; -+ yylloc.first_line = yylineno; -+ yylval.byte = strtol(yytext, NULL, 16); -+ DPRINT("Byte: %02x\n", (int)yylval.byte); -+ return DT_BYTE; -+ } -+ YY_BREAK -+case 14: -+YY_RULE_SETUP -+#line 176 "dtc-lexer.l" -+{ -+ yylloc.filenum = srcpos_filenum; -+ yylloc.first_line = yylineno; -+ DPRINT("/BYTESTRING\n"); -+ BEGIN_DEFAULT(); -+ return ']'; -+ } -+ YY_BREAK -+case 15: -+YY_RULE_SETUP -+#line 184 "dtc-lexer.l" -+{ -+ yylloc.filenum = srcpos_filenum; -+ yylloc.first_line = yylineno; -+ DPRINT("PropNodeName: %s\n", yytext); -+ yylval.propnodename = strdup(yytext); -+ BEGIN_DEFAULT(); -+ return DT_PROPNODENAME; -+ } -+ YY_BREAK -+case 16: -+/* rule 16 can match eol */ -+YY_RULE_SETUP -+#line 194 "dtc-lexer.l" -+/* eat whitespace */ -+ YY_BREAK -+case 17: -+/* rule 17 can match eol */ -+YY_RULE_SETUP -+#line 196 "dtc-lexer.l" -+{ -+ yylloc.filenum = srcpos_filenum; -+ yylloc.first_line = yylineno; -+ DPRINT("Comment: %s\n", yytext); -+ /* eat comments */ -+ } -+ YY_BREAK -+case 18: -+/* rule 18 can match eol */ -+YY_RULE_SETUP -+#line 203 "dtc-lexer.l" -+/* eat line comments */ -+ YY_BREAK -+case 19: -+YY_RULE_SETUP -+#line 205 "dtc-lexer.l" -+{ -+ yylloc.filenum = srcpos_filenum; -+ yylloc.first_line = yylineno; -+ DPRINT("Char: %c (\\x%02x)\n", yytext[0], -+ (unsigned)yytext[0]); -+ if (yytext[0] == '[') { -+ DPRINT("\n"); -+ BEGIN(BYTESTRING); -+ } -+ if ((yytext[0] == '{') -+ || (yytext[0] == ';')) { -+ DPRINT("\n"); -+ BEGIN(PROPNODENAME); -+ } -+ return yytext[0]; -+ } -+ YY_BREAK -+case 20: -+YY_RULE_SETUP -+#line 222 "dtc-lexer.l" -+ECHO; -+ YY_BREAK -+#line 1111 "dtc-lexer.lex.c" -+ -+ case YY_END_OF_BUFFER: -+ { -+ /* Amount of text matched not including the EOB char. */ -+ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; -+ -+ /* Undo the effects of YY_DO_BEFORE_ACTION. */ -+ *yy_cp = (yy_hold_char); -+ YY_RESTORE_YY_MORE_OFFSET -+ -+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) -+ { -+ /* We're scanning a new file or input source. It's -+ * possible that this happened because the user -+ * just pointed yyin at a new source and called -+ * yylex(). If so, then we have to assure -+ * consistency between YY_CURRENT_BUFFER and our -+ * globals. Here is the right place to do so, because -+ * this is the first action (other than possibly a -+ * back-up) that will match for the new input source. -+ */ -+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; -+ YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; -+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; -+ } -+ -+ /* Note that here we test for yy_c_buf_p "<=" to the position -+ * of the first EOB in the buffer, since yy_c_buf_p will -+ * already have been incremented past the NUL character -+ * (since all states make transitions on EOB to the -+ * end-of-buffer state). Contrast this with the test -+ * in input(). -+ */ -+ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) -+ { /* This was really a NUL. */ -+ yy_state_type yy_next_state; -+ -+ (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; -+ -+ yy_current_state = yy_get_previous_state( ); -+ -+ /* Okay, we're now positioned to make the NUL -+ * transition. We couldn't have -+ * yy_get_previous_state() go ahead and do it -+ * for us because it doesn't know how to deal -+ * with the possibility of jamming (and we don't -+ * want to build jamming into it because then it -+ * will run more slowly). -+ */ -+ -+ yy_next_state = yy_try_NUL_trans( yy_current_state ); -+ -+ yy_bp = (yytext_ptr) + YY_MORE_ADJ; -+ -+ if ( yy_next_state ) -+ { -+ /* Consume the NUL. */ -+ yy_cp = ++(yy_c_buf_p); -+ yy_current_state = yy_next_state; -+ goto yy_match; -+ } -+ -+ else -+ { -+ yy_cp = (yy_c_buf_p); -+ goto yy_find_action; -+ } -+ } -+ -+ else switch ( yy_get_next_buffer( ) ) -+ { -+ case EOB_ACT_END_OF_FILE: -+ { -+ (yy_did_buffer_switch_on_eof) = 0; -+ -+ if ( yywrap( ) ) -+ { -+ /* Note: because we've taken care in -+ * yy_get_next_buffer() to have set up -+ * yytext, we can now set up -+ * yy_c_buf_p so that if some total -+ * hoser (like flex itself) wants to -+ * call the scanner after we return the -+ * YY_NULL, it'll still work - another -+ * YY_NULL will get returned. -+ */ -+ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; -+ -+ yy_act = YY_STATE_EOF(YY_START); -+ goto do_action; -+ } -+ -+ else -+ { -+ if ( ! (yy_did_buffer_switch_on_eof) ) -+ YY_NEW_FILE; -+ } -+ break; -+ } -+ -+ case EOB_ACT_CONTINUE_SCAN: -+ (yy_c_buf_p) = -+ (yytext_ptr) + yy_amount_of_matched_text; -+ -+ yy_current_state = yy_get_previous_state( ); -+ -+ yy_cp = (yy_c_buf_p); -+ yy_bp = (yytext_ptr) + YY_MORE_ADJ; -+ goto yy_match; -+ -+ case EOB_ACT_LAST_MATCH: -+ (yy_c_buf_p) = -+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; -+ -+ yy_current_state = yy_get_previous_state( ); -+ -+ yy_cp = (yy_c_buf_p); -+ yy_bp = (yytext_ptr) + YY_MORE_ADJ; -+ goto yy_find_action; -+ } -+ break; -+ } -+ -+ default: -+ YY_FATAL_ERROR( -+ "fatal flex scanner internal error--no action found" ); -+ } /* end of action switch */ -+ } /* end of scanning one token */ -+} /* end of yylex */ -+ -+/* yy_get_next_buffer - try to read in a new buffer -+ * -+ * Returns a code representing an action: -+ * EOB_ACT_LAST_MATCH - -+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position -+ * EOB_ACT_END_OF_FILE - end of file -+ */ -+static int yy_get_next_buffer (void) -+{ -+ register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; -+ register char *source = (yytext_ptr); -+ register int number_to_move, i; -+ int ret_val; -+ -+ if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) -+ YY_FATAL_ERROR( -+ "fatal flex scanner internal error--end of buffer missed" ); -+ -+ if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) -+ { /* Don't try to fill the buffer, so this is an EOF. */ -+ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) -+ { -+ /* We matched a single character, the EOB, so -+ * treat this as a final EOF. -+ */ -+ return EOB_ACT_END_OF_FILE; -+ } -+ -+ else -+ { -+ /* We matched some text prior to the EOB, first -+ * process it. -+ */ -+ return EOB_ACT_LAST_MATCH; -+ } -+ } -+ -+ /* Try to read more data. */ -+ -+ /* First move last chars to start of buffer. */ -+ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; -+ -+ for ( i = 0; i < number_to_move; ++i ) -+ *(dest++) = *(source++); -+ -+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) -+ /* don't do the read, it's not guaranteed to return an EOF, -+ * just force an EOF -+ */ -+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; -+ -+ else -+ { -+ int num_to_read = -+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; -+ -+ while ( num_to_read <= 0 ) -+ { /* Not enough room in the buffer - grow it. */ -+ -+ /* just a shorter name for the current buffer */ -+ YY_BUFFER_STATE b = YY_CURRENT_BUFFER; -+ -+ int yy_c_buf_p_offset = -+ (int) ((yy_c_buf_p) - b->yy_ch_buf); -+ -+ if ( b->yy_is_our_buffer ) -+ { -+ int new_size = b->yy_buf_size * 2; -+ -+ if ( new_size <= 0 ) -+ b->yy_buf_size += b->yy_buf_size / 8; -+ else -+ b->yy_buf_size *= 2; -+ -+ b->yy_ch_buf = (char *) -+ /* Include room in for 2 EOB chars. */ -+ yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); -+ } -+ else -+ /* Can't grow it, we don't own it. */ -+ b->yy_ch_buf = 0; -+ -+ if ( ! b->yy_ch_buf ) -+ YY_FATAL_ERROR( -+ "fatal error - scanner input buffer overflow" ); -+ -+ (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; -+ -+ num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - -+ number_to_move - 1; -+ -+ } -+ -+ if ( num_to_read > YY_READ_BUF_SIZE ) -+ num_to_read = YY_READ_BUF_SIZE; -+ -+ /* Read in more data. */ -+ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), -+ (yy_n_chars), (size_t) num_to_read ); -+ -+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); -+ } -+ -+ if ( (yy_n_chars) == 0 ) -+ { -+ if ( number_to_move == YY_MORE_ADJ ) -+ { -+ ret_val = EOB_ACT_END_OF_FILE; -+ yyrestart(yyin ); -+ } -+ -+ else -+ { -+ ret_val = EOB_ACT_LAST_MATCH; -+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = -+ YY_BUFFER_EOF_PENDING; -+ } -+ } -+ -+ else -+ ret_val = EOB_ACT_CONTINUE_SCAN; -+ -+ (yy_n_chars) += number_to_move; -+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; -+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; -+ -+ (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; -+ -+ return ret_val; -+} -+ -+/* yy_get_previous_state - get the state just before the EOB char was reached */ -+ -+ static yy_state_type yy_get_previous_state (void) -+{ -+ register yy_state_type yy_current_state; -+ register char *yy_cp; -+ -+ yy_current_state = (yy_start); -+ -+ for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) -+ { -+ register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); -+ if ( yy_accept[yy_current_state] ) -+ { -+ (yy_last_accepting_state) = yy_current_state; -+ (yy_last_accepting_cpos) = yy_cp; -+ } -+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) -+ { -+ yy_current_state = (int) yy_def[yy_current_state]; -+ if ( yy_current_state >= 94 ) -+ yy_c = yy_meta[(unsigned int) yy_c]; -+ } -+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; -+ } -+ -+ return yy_current_state; -+} -+ -+/* yy_try_NUL_trans - try to make a transition on the NUL character -+ * -+ * synopsis -+ * next_state = yy_try_NUL_trans( current_state ); -+ */ -+ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) -+{ -+ register int yy_is_jam; -+ register char *yy_cp = (yy_c_buf_p); -+ -+ register YY_CHAR yy_c = 1; -+ if ( yy_accept[yy_current_state] ) -+ { -+ (yy_last_accepting_state) = yy_current_state; -+ (yy_last_accepting_cpos) = yy_cp; -+ } -+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) -+ { -+ yy_current_state = (int) yy_def[yy_current_state]; -+ if ( yy_current_state >= 94 ) -+ yy_c = yy_meta[(unsigned int) yy_c]; -+ } -+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; -+ yy_is_jam = (yy_current_state == 93); -+ -+ return yy_is_jam ? 0 : yy_current_state; -+} -+ -+#ifndef YY_NO_INPUT -+#ifdef __cplusplus -+ static int yyinput (void) -+#else -+ static int input (void) -+#endif -+ -+{ -+ int c; -+ -+ *(yy_c_buf_p) = (yy_hold_char); -+ -+ if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) -+ { -+ /* yy_c_buf_p now points to the character we want to return. -+ * If this occurs *before* the EOB characters, then it's a -+ * valid NUL; if not, then we've hit the end of the buffer. -+ */ -+ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) -+ /* This was really a NUL. */ -+ *(yy_c_buf_p) = '\0'; -+ -+ else -+ { /* need more input */ -+ int offset = (yy_c_buf_p) - (yytext_ptr); -+ ++(yy_c_buf_p); -+ -+ switch ( yy_get_next_buffer( ) ) -+ { -+ case EOB_ACT_LAST_MATCH: -+ /* This happens because yy_g_n_b() -+ * sees that we've accumulated a -+ * token and flags that we need to -+ * try matching the token before -+ * proceeding. But for input(), -+ * there's no matching to consider. -+ * So convert the EOB_ACT_LAST_MATCH -+ * to EOB_ACT_END_OF_FILE. -+ */ -+ -+ /* Reset buffer status. */ -+ yyrestart(yyin ); -+ -+ /*FALLTHROUGH*/ -+ -+ case EOB_ACT_END_OF_FILE: -+ { -+ if ( yywrap( ) ) -+ return EOF; -+ -+ if ( ! (yy_did_buffer_switch_on_eof) ) -+ YY_NEW_FILE; -+#ifdef __cplusplus -+ return yyinput(); -+#else -+ return input(); -+#endif -+ } -+ -+ case EOB_ACT_CONTINUE_SCAN: -+ (yy_c_buf_p) = (yytext_ptr) + offset; -+ break; -+ } -+ } -+ } -+ -+ c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ -+ *(yy_c_buf_p) = '\0'; /* preserve yytext */ -+ (yy_hold_char) = *++(yy_c_buf_p); -+ -+ if ( c == '\n' ) -+ -+ yylineno++; -+; -+ -+ return c; -+} -+#endif /* ifndef YY_NO_INPUT */ -+ -+/** Immediately switch to a different input stream. -+ * @param input_file A readable stream. -+ * -+ * @note This function does not reset the start condition to @c INITIAL . -+ */ -+ void yyrestart (FILE * input_file ) -+{ -+ -+ if ( ! YY_CURRENT_BUFFER ){ -+ yyensure_buffer_stack (); -+ YY_CURRENT_BUFFER_LVALUE = -+ yy_create_buffer(yyin,YY_BUF_SIZE ); -+ } -+ -+ yy_init_buffer(YY_CURRENT_BUFFER,input_file ); -+ yy_load_buffer_state( ); -+} -+ -+/** Switch to a different input buffer. -+ * @param new_buffer The new input buffer. -+ * -+ */ -+ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) -+{ -+ -+ /* TODO. We should be able to replace this entire function body -+ * with -+ * yypop_buffer_state(); -+ * yypush_buffer_state(new_buffer); -+ */ -+ yyensure_buffer_stack (); -+ if ( YY_CURRENT_BUFFER == new_buffer ) -+ return; -+ -+ if ( YY_CURRENT_BUFFER ) -+ { -+ /* Flush out information for old buffer. */ -+ *(yy_c_buf_p) = (yy_hold_char); -+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); -+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); -+ } -+ -+ YY_CURRENT_BUFFER_LVALUE = new_buffer; -+ yy_load_buffer_state( ); -+ -+ /* We don't actually know whether we did this switch during -+ * EOF (yywrap()) processing, but the only time this flag -+ * is looked at is after yywrap() is called, so it's safe -+ * to go ahead and always set it. -+ */ -+ (yy_did_buffer_switch_on_eof) = 1; -+} -+ -+static void yy_load_buffer_state (void) -+{ -+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; -+ (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; -+ yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; -+ (yy_hold_char) = *(yy_c_buf_p); -+} -+ -+/** Allocate and initialize an input buffer state. -+ * @param file A readable stream. -+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. -+ * -+ * @return the allocated buffer state. -+ */ -+ YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) -+{ -+ YY_BUFFER_STATE b; -+ -+ b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); -+ if ( ! b ) -+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); -+ -+ b->yy_buf_size = size; -+ -+ /* yy_ch_buf has to be 2 characters longer than the size given because -+ * we need to put in 2 end-of-buffer characters. -+ */ -+ b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ); -+ if ( ! b->yy_ch_buf ) -+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); -+ -+ b->yy_is_our_buffer = 1; -+ -+ yy_init_buffer(b,file ); -+ -+ return b; -+} -+ -+/** Destroy the buffer. -+ * @param b a buffer created with yy_create_buffer() -+ * -+ */ -+ void yy_delete_buffer (YY_BUFFER_STATE b ) -+{ -+ -+ if ( ! b ) -+ return; -+ -+ if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ -+ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; -+ -+ if ( b->yy_is_our_buffer ) -+ yyfree((void *) b->yy_ch_buf ); -+ -+ yyfree((void *) b ); -+} -+ -+#ifndef __cplusplus -+extern int isatty (int ); -+#endif /* __cplusplus */ -+ -+/* Initializes or reinitializes a buffer. -+ * This function is sometimes called more than once on the same buffer, -+ * such as during a yyrestart() or at EOF. -+ */ -+ static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) -+ -+{ -+ int oerrno = errno; -+ -+ yy_flush_buffer(b ); -+ -+ b->yy_input_file = file; -+ b->yy_fill_buffer = 1; -+ -+ /* If b is the current buffer, then yy_init_buffer was _probably_ -+ * called from yyrestart() or through yy_get_next_buffer. -+ * In that case, we don't want to reset the lineno or column. -+ */ -+ if (b != YY_CURRENT_BUFFER){ -+ b->yy_bs_lineno = 1; -+ b->yy_bs_column = 0; -+ } -+ -+ b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; -+ -+ errno = oerrno; -+} -+ -+/** Discard all buffered characters. On the next scan, YY_INPUT will be called. -+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. -+ * -+ */ -+ void yy_flush_buffer (YY_BUFFER_STATE b ) -+{ -+ if ( ! b ) -+ return; -+ -+ b->yy_n_chars = 0; -+ -+ /* We always need two end-of-buffer characters. The first causes -+ * a transition to the end-of-buffer state. The second causes -+ * a jam in that state. -+ */ -+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; -+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; -+ -+ b->yy_buf_pos = &b->yy_ch_buf[0]; -+ -+ b->yy_at_bol = 1; -+ b->yy_buffer_status = YY_BUFFER_NEW; -+ -+ if ( b == YY_CURRENT_BUFFER ) -+ yy_load_buffer_state( ); -+} -+ -+/** Pushes the new state onto the stack. The new state becomes -+ * the current state. This function will allocate the stack -+ * if necessary. -+ * @param new_buffer The new state. -+ * -+ */ -+void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) -+{ -+ if (new_buffer == NULL) -+ return; -+ -+ yyensure_buffer_stack(); -+ -+ /* This block is copied from yy_switch_to_buffer. */ -+ if ( YY_CURRENT_BUFFER ) -+ { -+ /* Flush out information for old buffer. */ -+ *(yy_c_buf_p) = (yy_hold_char); -+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); -+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); -+ } -+ -+ /* Only push if top exists. Otherwise, replace top. */ -+ if (YY_CURRENT_BUFFER) -+ (yy_buffer_stack_top)++; -+ YY_CURRENT_BUFFER_LVALUE = new_buffer; -+ -+ /* copied from yy_switch_to_buffer. */ -+ yy_load_buffer_state( ); -+ (yy_did_buffer_switch_on_eof) = 1; -+} -+ -+/** Removes and deletes the top of the stack, if present. -+ * The next element becomes the new top. -+ * -+ */ -+void yypop_buffer_state (void) -+{ -+ if (!YY_CURRENT_BUFFER) -+ return; -+ -+ yy_delete_buffer(YY_CURRENT_BUFFER ); -+ YY_CURRENT_BUFFER_LVALUE = NULL; -+ if ((yy_buffer_stack_top) > 0) -+ --(yy_buffer_stack_top); -+ -+ if (YY_CURRENT_BUFFER) { -+ yy_load_buffer_state( ); -+ (yy_did_buffer_switch_on_eof) = 1; -+ } -+} -+ -+/* Allocates the stack if it does not exist. -+ * Guarantees space for at least one push. -+ */ -+static void yyensure_buffer_stack (void) -+{ -+ int num_to_alloc; -+ -+ if (!(yy_buffer_stack)) { -+ -+ /* First allocation is just for 2 elements, since we don't know if this -+ * scanner will even need a stack. We use 2 instead of 1 to avoid an -+ * immediate realloc on the next call. -+ */ -+ num_to_alloc = 1; -+ (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc -+ (num_to_alloc * sizeof(struct yy_buffer_state*) -+ ); -+ -+ memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); -+ -+ (yy_buffer_stack_max) = num_to_alloc; -+ (yy_buffer_stack_top) = 0; -+ return; -+ } -+ -+ if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ -+ -+ /* Increase the buffer to prepare for a possible push. */ -+ int grow_size = 8 /* arbitrary grow size */; -+ -+ num_to_alloc = (yy_buffer_stack_max) + grow_size; -+ (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc -+ ((yy_buffer_stack), -+ num_to_alloc * sizeof(struct yy_buffer_state*) -+ ); -+ -+ /* zero only the new slots.*/ -+ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); -+ (yy_buffer_stack_max) = num_to_alloc; -+ } -+} -+ -+/** Setup the input buffer state to scan directly from a user-specified character buffer. -+ * @param base the character buffer -+ * @param size the size in bytes of the character buffer -+ * -+ * @return the newly allocated buffer state object. -+ */ -+YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) -+{ -+ YY_BUFFER_STATE b; -+ -+ if ( size < 2 || -+ base[size-2] != YY_END_OF_BUFFER_CHAR || -+ base[size-1] != YY_END_OF_BUFFER_CHAR ) -+ /* They forgot to leave room for the EOB's. */ -+ return 0; -+ -+ b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); -+ if ( ! b ) -+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); -+ -+ b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ -+ b->yy_buf_pos = b->yy_ch_buf = base; -+ b->yy_is_our_buffer = 0; -+ b->yy_input_file = 0; -+ b->yy_n_chars = b->yy_buf_size; -+ b->yy_is_interactive = 0; -+ b->yy_at_bol = 1; -+ b->yy_fill_buffer = 0; -+ b->yy_buffer_status = YY_BUFFER_NEW; -+ -+ yy_switch_to_buffer(b ); -+ -+ return b; -+} -+ -+/** Setup the input buffer state to scan a string. The next call to yylex() will -+ * scan from a @e copy of @a str. -+ * @param yystr a NUL-terminated string to scan -+ * -+ * @return the newly allocated buffer state object. -+ * @note If you want to scan bytes that may contain NUL values, then use -+ * yy_scan_bytes() instead. -+ */ -+YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) -+{ -+ -+ return yy_scan_bytes(yystr,strlen(yystr) ); -+} -+ -+/** Setup the input buffer state to scan the given bytes. The next call to yylex() will -+ * scan from a @e copy of @a bytes. -+ * @param bytes the byte buffer to scan -+ * @param len the number of bytes in the buffer pointed to by @a bytes. -+ * -+ * @return the newly allocated buffer state object. -+ */ -+YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len ) -+{ -+ YY_BUFFER_STATE b; -+ char *buf; -+ yy_size_t n; -+ int i; -+ -+ /* Get memory for full buffer, including space for trailing EOB's. */ -+ n = _yybytes_len + 2; -+ buf = (char *) yyalloc(n ); -+ if ( ! buf ) -+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); -+ -+ for ( i = 0; i < _yybytes_len; ++i ) -+ buf[i] = yybytes[i]; -+ -+ buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; -+ -+ b = yy_scan_buffer(buf,n ); -+ if ( ! b ) -+ YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); -+ -+ /* It's okay to grow etc. this buffer, and we should throw it -+ * away when we're done. -+ */ -+ b->yy_is_our_buffer = 1; -+ -+ return b; -+} -+ -+#ifndef YY_EXIT_FAILURE -+#define YY_EXIT_FAILURE 2 -+#endif -+ -+static void yy_fatal_error (yyconst char* msg ) -+{ -+ (void) fprintf( stderr, "%s\n", msg ); -+ exit( YY_EXIT_FAILURE ); -+} -+ -+/* Redefine yyless() so it works in section 3 code. */ -+ -+#undef yyless -+#define yyless(n) \ -+ do \ -+ { \ -+ /* Undo effects of setting up yytext. */ \ -+ int yyless_macro_arg = (n); \ -+ YY_LESS_LINENO(yyless_macro_arg);\ -+ yytext[yyleng] = (yy_hold_char); \ -+ (yy_c_buf_p) = yytext + yyless_macro_arg; \ -+ (yy_hold_char) = *(yy_c_buf_p); \ -+ *(yy_c_buf_p) = '\0'; \ -+ yyleng = yyless_macro_arg; \ -+ } \ -+ while ( 0 ) -+ -+/* Accessor methods (get/set functions) to struct members. */ -+ -+/** Get the current line number. -+ * -+ */ -+int yyget_lineno (void) -+{ -+ -+ return yylineno; -+} -+ -+/** Get the input stream. -+ * -+ */ -+FILE *yyget_in (void) -+{ -+ return yyin; -+} -+ -+/** Get the output stream. -+ * -+ */ -+FILE *yyget_out (void) -+{ -+ return yyout; -+} -+ -+/** Get the length of the current token. -+ * -+ */ -+int yyget_leng (void) -+{ -+ return yyleng; -+} -+ -+/** Get the current token. -+ * -+ */ -+ -+char *yyget_text (void) -+{ -+ return yytext; -+} -+ -+/** Set the current line number. -+ * @param line_number -+ * -+ */ -+void yyset_lineno (int line_number ) -+{ -+ -+ yylineno = line_number; -+} -+ -+/** Set the input stream. This does not discard the current -+ * input buffer. -+ * @param in_str A readable stream. -+ * -+ * @see yy_switch_to_buffer -+ */ -+void yyset_in (FILE * in_str ) -+{ -+ yyin = in_str ; -+} -+ -+void yyset_out (FILE * out_str ) -+{ -+ yyout = out_str ; -+} -+ -+int yyget_debug (void) -+{ -+ return yy_flex_debug; -+} -+ -+void yyset_debug (int bdebug ) -+{ -+ yy_flex_debug = bdebug ; -+} -+ -+static int yy_init_globals (void) -+{ -+ /* Initialization is the same as for the non-reentrant scanner. -+ * This function is called from yylex_destroy(), so don't allocate here. -+ */ -+ -+ /* We do not touch yylineno unless the option is enabled. */ -+ yylineno = 1; -+ -+ (yy_buffer_stack) = 0; -+ (yy_buffer_stack_top) = 0; -+ (yy_buffer_stack_max) = 0; -+ (yy_c_buf_p) = (char *) 0; -+ (yy_init) = 0; -+ (yy_start) = 0; -+ -+/* Defined in main.c */ -+#ifdef YY_STDINIT -+ yyin = stdin; -+ yyout = stdout; -+#else -+ yyin = (FILE *) 0; -+ yyout = (FILE *) 0; -+#endif -+ -+ /* For future reference: Set errno on error, since we are called by -+ * yylex_init() -+ */ -+ return 0; -+} -+ -+/* yylex_destroy is for both reentrant and non-reentrant scanners. */ -+int yylex_destroy (void) -+{ -+ -+ /* Pop the buffer stack, destroying each element. */ -+ while(YY_CURRENT_BUFFER){ -+ yy_delete_buffer(YY_CURRENT_BUFFER ); -+ YY_CURRENT_BUFFER_LVALUE = NULL; -+ yypop_buffer_state(); -+ } -+ -+ /* Destroy the stack itself. */ -+ yyfree((yy_buffer_stack) ); -+ (yy_buffer_stack) = NULL; -+ -+ /* Reset the globals. This is important in a non-reentrant scanner so the next time -+ * yylex() is called, initialization will occur. */ -+ yy_init_globals( ); -+ -+ return 0; -+} -+ -+/* -+ * Internal utility routines. -+ */ -+ -+#ifndef yytext_ptr -+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) -+{ -+ register int i; -+ for ( i = 0; i < n; ++i ) -+ s1[i] = s2[i]; -+} -+#endif -+ -+#ifdef YY_NEED_STRLEN -+static int yy_flex_strlen (yyconst char * s ) -+{ -+ register int n; -+ for ( n = 0; s[n]; ++n ) -+ ; -+ -+ return n; -+} -+#endif -+ -+void *yyalloc (yy_size_t size ) -+{ -+ return (void *) malloc( size ); -+} -+ -+void *yyrealloc (void * ptr, yy_size_t size ) -+{ -+ /* The cast to (char *) in the following accommodates both -+ * implementations that use char* generic pointers, and those -+ * that use void* generic pointers. It works with the latter -+ * because both ANSI C and C++ allow castless assignment from -+ * any pointer type to void*, and deal with argument conversions -+ * as though doing an assignment. -+ */ -+ return (void *) realloc( (char *) ptr, size ); -+} -+ -+void yyfree (void * ptr ) -+{ -+ free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ -+} -+ -+#define YYTABLES_NAME "yytables" -+ -+#line 222 "dtc-lexer.l" -+ -+ -+ -+ -+/* -+ * Stack of nested include file contexts. -+ */ -+ -+struct incl_file { -+ int filenum; -+ FILE *file; -+ YY_BUFFER_STATE yy_prev_buf; -+ int yy_prev_lineno; -+ struct incl_file *prev; -+}; -+ -+struct incl_file *incl_file_stack; -+ -+ -+/* -+ * Detect infinite include recursion. -+ */ -+#define MAX_INCLUDE_DEPTH (100) -+ -+static int incl_depth = 0; -+ -+ -+int push_input_file(const char *filename) -+{ -+ FILE *f; -+ struct incl_file *incl_file; -+ -+ if (!filename) { -+ yyerror("No include file name given."); -+ return 0; -+ } -+ -+ if (incl_depth++ >= MAX_INCLUDE_DEPTH) { -+ yyerror("Includes nested too deeply"); -+ return 0; -+ } -+ -+ f = dtc_open_file(filename); -+ -+ incl_file = malloc(sizeof(struct incl_file)); -+ if (!incl_file) { -+ yyerror("Can not allocate include file space."); -+ return 0; -+ } -+ -+ /* -+ * Save current context. -+ */ -+ incl_file->yy_prev_buf = YY_CURRENT_BUFFER; -+ incl_file->yy_prev_lineno = yylineno; -+ incl_file->filenum = srcpos_filenum; -+ incl_file->file = yyin; -+ incl_file->prev = incl_file_stack; -+ -+ incl_file_stack = incl_file; -+ -+ /* -+ * Establish new context. -+ */ -+ srcpos_filenum = lookup_file_name(filename, 0); -+ yylineno = 1; -+ yyin = f; -+ yy_switch_to_buffer(yy_create_buffer(yyin,YY_BUF_SIZE)); -+ -+ return 1; -+} -+ -+ -+int pop_input_file(void) -+{ -+ struct incl_file *incl_file; -+ -+ if (incl_file_stack == 0) -+ return 0; -+ -+ fclose(yyin); -+ -+ /* -+ * Pop. -+ */ -+ --incl_depth; -+ incl_file = incl_file_stack; -+ incl_file_stack = incl_file->prev; -+ -+ /* -+ * Recover old context. -+ */ -+ yy_delete_buffer(YY_CURRENT_BUFFER); -+ yy_switch_to_buffer(incl_file->yy_prev_buf); -+ yylineno = incl_file->yy_prev_lineno; -+ srcpos_filenum = incl_file->filenum; -+ yyin = incl_file->file; -+ -+ /* -+ * Free old state. -+ */ -+ free(incl_file); -+ -+ if (YY_CURRENT_BUFFER == 0) -+ return 0; -+ -+ return 1; -+} -+ ---- /dev/null -+++ b/arch/powerpc/boot/dtc-src/dtc-parser.tab.c_shipped -@@ -0,0 +1,1983 @@ -+/* A Bison parser, made by GNU Bison 2.3. */ -+ -+/* Skeleton implementation for Bison's Yacc-like parsers in C -+ -+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 -+ Free Software Foundation, Inc. -+ -+ This program is free software; you can redistribute it and/or modify -+ it under the terms of the GNU General Public License as published by -+ the Free Software Foundation; either version 2, 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 Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. */ -+ -+/* As a special exception, you may create a larger work that contains -+ part or all of the Bison parser skeleton and distribute that work -+ under terms of your choice, so long as that work isn't itself a -+ parser generator using the skeleton or a modified version thereof -+ as a parser skeleton. Alternatively, if you modify or redistribute -+ the parser skeleton itself, you may (at your option) remove this -+ special exception, which will cause the skeleton and the resulting -+ Bison output files to be licensed under the GNU General Public -+ License without this special exception. -+ -+ This special exception was added by the Free Software Foundation in -+ version 2.2 of Bison. */ -+ -+/* C LALR(1) parser skeleton written by Richard Stallman, by -+ simplifying the original so-called "semantic" parser. */ -+ -+/* All symbols defined below should begin with yy or YY, to avoid -+ infringing on user name space. This should be done even for local -+ variables, as they might otherwise be expanded by user macros. -+ There are some unavoidable exceptions within include files to -+ define necessary library symbols; they are noted "INFRINGES ON -+ USER NAME SPACE" below. */ -+ -+/* Identify Bison output. */ -+#define YYBISON 1 -+ -+/* Bison version. */ -+#define YYBISON_VERSION "2.3" -+ -+/* Skeleton name. */ -+#define YYSKELETON_NAME "yacc.c" -+ -+/* Pure parsers. */ -+#define YYPURE 0 -+ -+/* Using locations. */ -+#define YYLSP_NEEDED 1 -+ -+ -+ -+/* Tokens. */ -+#ifndef YYTOKENTYPE -+# define YYTOKENTYPE -+ /* Put the tokens into the symbol table, so that GDB and other debuggers -+ know about them. */ -+ enum yytokentype { -+ DT_V1 = 258, -+ DT_MEMRESERVE = 259, -+ DT_PROPNODENAME = 260, -+ DT_LITERAL = 261, -+ DT_LEGACYLITERAL = 262, -+ DT_BASE = 263, -+ DT_BYTE = 264, -+ DT_STRING = 265, -+ DT_LABEL = 266, -+ DT_REF = 267 -+ }; -+#endif -+/* Tokens. */ -+#define DT_V1 258 -+#define DT_MEMRESERVE 259 -+#define DT_PROPNODENAME 260 -+#define DT_LITERAL 261 -+#define DT_LEGACYLITERAL 262 -+#define DT_BASE 263 -+#define DT_BYTE 264 -+#define DT_STRING 265 -+#define DT_LABEL 266 -+#define DT_REF 267 -+ -+ -+ -+ -+/* Copy the first part of user declarations. */ -+#line 23 "dtc-parser.y" -+ -+#include "dtc.h" -+#include "srcpos.h" -+ -+int yylex(void); -+unsigned long long eval_literal(const char *s, int base, int bits); -+ -+extern struct boot_info *the_boot_info; -+ -+ -+ -+/* Enabling traces. */ -+#ifndef YYDEBUG -+# define YYDEBUG 0 -+#endif -+ -+/* Enabling verbose error messages. */ -+#ifdef YYERROR_VERBOSE -+# undef YYERROR_VERBOSE -+# define YYERROR_VERBOSE 1 -+#else -+# define YYERROR_VERBOSE 0 -+#endif -+ -+/* Enabling the token table. */ -+#ifndef YYTOKEN_TABLE -+# define YYTOKEN_TABLE 0 -+#endif -+ -+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -+typedef union YYSTYPE -+#line 34 "dtc-parser.y" -+{ -+ char *propnodename; -+ char *literal; -+ char *labelref; -+ unsigned int cbase; -+ u8 byte; -+ struct data data; -+ -+ u64 addr; -+ cell_t cell; -+ struct property *prop; -+ struct property *proplist; -+ struct node *node; -+ struct node *nodelist; -+ struct reserve_info *re; -+} -+/* Line 187 of yacc.c. */ -+#line 148 "dtc-parser.tab.c" -+ YYSTYPE; -+# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -+# define YYSTYPE_IS_DECLARED 1 -+# define YYSTYPE_IS_TRIVIAL 1 -+#endif -+ -+#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED -+typedef struct YYLTYPE -+{ -+ int first_line; -+ int first_column; -+ int last_line; -+ int last_column; -+} YYLTYPE; -+# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ -+# define YYLTYPE_IS_DECLARED 1 -+# define YYLTYPE_IS_TRIVIAL 1 -+#endif -+ -+ -+/* Copy the second part of user declarations. */ -+ -+ -+/* Line 216 of yacc.c. */ -+#line 173 "dtc-parser.tab.c" -+ -+#ifdef short -+# undef short -+#endif -+ -+#ifdef YYTYPE_UINT8 -+typedef YYTYPE_UINT8 yytype_uint8; -+#else -+typedef unsigned char yytype_uint8; -+#endif -+ -+#ifdef YYTYPE_INT8 -+typedef YYTYPE_INT8 yytype_int8; -+#elif (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) -+typedef signed char yytype_int8; -+#else -+typedef short int yytype_int8; -+#endif -+ -+#ifdef YYTYPE_UINT16 -+typedef YYTYPE_UINT16 yytype_uint16; -+#else -+typedef unsigned short int yytype_uint16; -+#endif -+ -+#ifdef YYTYPE_INT16 -+typedef YYTYPE_INT16 yytype_int16; -+#else -+typedef short int yytype_int16; -+#endif -+ -+#ifndef YYSIZE_T -+# ifdef __SIZE_TYPE__ -+# define YYSIZE_T __SIZE_TYPE__ -+# elif defined size_t -+# define YYSIZE_T size_t -+# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) -+# include /* INFRINGES ON USER NAME SPACE */ -+# define YYSIZE_T size_t -+# else -+# define YYSIZE_T unsigned int -+# endif -+#endif -+ -+#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) -+ -+#ifndef YY_ -+# if YYENABLE_NLS -+# if ENABLE_NLS -+# include /* INFRINGES ON USER NAME SPACE */ -+# define YY_(msgid) dgettext ("bison-runtime", msgid) -+# endif -+# endif -+# ifndef YY_ -+# define YY_(msgid) msgid -+# endif -+#endif -+ -+/* Suppress unused-variable warnings by "using" E. */ -+#if ! defined lint || defined __GNUC__ -+# define YYUSE(e) ((void) (e)) -+#else -+# define YYUSE(e) /* empty */ -+#endif -+ -+/* Identity function, used to suppress warnings about constant conditions. */ -+#ifndef lint -+# define YYID(n) (n) -+#else -+#if (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) -+static int -+YYID (int i) -+#else -+static int -+YYID (i) -+ int i; -+#endif -+{ -+ return i; -+} -+#endif -+ -+#if ! defined yyoverflow || YYERROR_VERBOSE -+ -+/* The parser invokes alloca or malloc; define the necessary symbols. */ -+ -+# ifdef YYSTACK_USE_ALLOCA -+# if YYSTACK_USE_ALLOCA -+# ifdef __GNUC__ -+# define YYSTACK_ALLOC __builtin_alloca -+# elif defined __BUILTIN_VA_ARG_INCR -+# include /* INFRINGES ON USER NAME SPACE */ -+# elif defined _AIX -+# define YYSTACK_ALLOC __alloca -+# elif defined _MSC_VER -+# include /* INFRINGES ON USER NAME SPACE */ -+# define alloca _alloca -+# else -+# define YYSTACK_ALLOC alloca -+# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) -+# include /* INFRINGES ON USER NAME SPACE */ -+# ifndef _STDLIB_H -+# define _STDLIB_H 1 -+# endif -+# endif -+# endif -+# endif -+# endif -+ -+# ifdef YYSTACK_ALLOC -+ /* Pacify GCC's `empty if-body' warning. */ -+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) -+# ifndef YYSTACK_ALLOC_MAXIMUM -+ /* The OS might guarantee only one guard page at the bottom of the stack, -+ and a page size can be as small as 4096 bytes. So we cannot safely -+ invoke alloca (N) if N exceeds 4096. Use a slightly smaller number -+ to allow for a few compiler-allocated temporary stack slots. */ -+# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ -+# endif -+# else -+# define YYSTACK_ALLOC YYMALLOC -+# define YYSTACK_FREE YYFREE -+# ifndef YYSTACK_ALLOC_MAXIMUM -+# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM -+# endif -+# if (defined __cplusplus && ! defined _STDLIB_H \ -+ && ! ((defined YYMALLOC || defined malloc) \ -+ && (defined YYFREE || defined free))) -+# include /* INFRINGES ON USER NAME SPACE */ -+# ifndef _STDLIB_H -+# define _STDLIB_H 1 -+# endif -+# endif -+# ifndef YYMALLOC -+# define YYMALLOC malloc -+# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) -+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ -+# endif -+# endif -+# ifndef YYFREE -+# define YYFREE free -+# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) -+void free (void *); /* INFRINGES ON USER NAME SPACE */ -+# endif -+# endif -+# endif -+#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ -+ -+ -+#if (! defined yyoverflow \ -+ && (! defined __cplusplus \ -+ || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ -+ && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) -+ -+/* A type that is properly aligned for any stack member. */ -+union yyalloc -+{ -+ yytype_int16 yyss; -+ YYSTYPE yyvs; -+ YYLTYPE yyls; -+}; -+ -+/* The size of the maximum gap between one aligned stack and the next. */ -+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) -+ -+/* The size of an array large to enough to hold all stacks, each with -+ N elements. */ -+# define YYSTACK_BYTES(N) \ -+ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \ -+ + 2 * YYSTACK_GAP_MAXIMUM) -+ -+/* Copy COUNT objects from FROM to TO. The source and destination do -+ not overlap. */ -+# ifndef YYCOPY -+# if defined __GNUC__ && 1 < __GNUC__ -+# define YYCOPY(To, From, Count) \ -+ __builtin_memcpy (To, From, (Count) * sizeof (*(From))) -+# else -+# define YYCOPY(To, From, Count) \ -+ do \ -+ { \ -+ YYSIZE_T yyi; \ -+ for (yyi = 0; yyi < (Count); yyi++) \ -+ (To)[yyi] = (From)[yyi]; \ -+ } \ -+ while (YYID (0)) -+# endif -+# endif -+ -+/* Relocate STACK from its old location to the new one. The -+ local variables YYSIZE and YYSTACKSIZE give the old and new number of -+ elements in the stack, and YYPTR gives the new location of the -+ stack. Advance YYPTR to a properly aligned location for the next -+ stack. */ -+# define YYSTACK_RELOCATE(Stack) \ -+ do \ -+ { \ -+ YYSIZE_T yynewbytes; \ -+ YYCOPY (&yyptr->Stack, Stack, yysize); \ -+ Stack = &yyptr->Stack; \ -+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ -+ yyptr += yynewbytes / sizeof (*yyptr); \ -+ } \ -+ while (YYID (0)) -+ -+#endif -+ -+/* YYFINAL -- State number of the termination state. */ -+#define YYFINAL 9 -+/* YYLAST -- Last index in YYTABLE. */ -+#define YYLAST 60 -+ -+/* YYNTOKENS -- Number of terminals. */ -+#define YYNTOKENS 24 -+/* YYNNTS -- Number of nonterminals. */ -+#define YYNNTS 20 -+/* YYNRULES -- Number of rules. */ -+#define YYNRULES 43 -+/* YYNRULES -- Number of states. */ -+#define YYNSTATES 67 -+ -+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ -+#define YYUNDEFTOK 2 -+#define YYMAXUTOK 267 -+ -+#define YYTRANSLATE(YYX) \ -+ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) -+ -+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ -+static const yytype_uint8 yytranslate[] = -+{ -+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 23, 14, 2, 15, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 13, -+ 19, 18, 20, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 21, 2, 22, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 16, 2, 17, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -+ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, -+ 5, 6, 7, 8, 9, 10, 11, 12 -+}; -+ -+#if YYDEBUG -+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in -+ YYRHS. */ -+static const yytype_uint8 yyprhs[] = -+{ -+ 0, 0, 3, 8, 11, 12, 15, 21, 22, 25, -+ 27, 34, 36, 38, 41, 47, 48, 51, 57, 61, -+ 64, 69, 74, 77, 80, 81, 84, 87, 88, 91, -+ 94, 97, 98, 100, 102, 105, 106, 109, 112, 113, -+ 116, 119, 123, 124 -+}; -+ -+/* YYRHS -- A `-1'-separated list of the rules' RHS. */ -+static const yytype_int8 yyrhs[] = -+{ -+ 25, 0, -1, 3, 13, 26, 31, -1, 28, 31, -+ -1, -1, 27, 26, -1, 43, 4, 30, 30, 13, -+ -1, -1, 29, 28, -1, 27, -1, 43, 4, 30, -+ 14, 30, 13, -1, 6, -1, 7, -1, 15, 32, -+ -1, 16, 33, 41, 17, 13, -1, -1, 33, 34, -+ -1, 43, 5, 18, 35, 13, -1, 43, 5, 13, -+ -1, 36, 10, -1, 36, 19, 37, 20, -1, 36, -+ 21, 40, 22, -1, 36, 12, -1, 35, 11, -1, -+ -1, 35, 23, -1, 36, 11, -1, -1, 37, 39, -+ -1, 37, 12, -1, 37, 11, -1, -1, 8, -1, -+ 6, -1, 38, 7, -1, -1, 40, 9, -1, 40, -+ 11, -1, -1, 42, 41, -1, 42, 34, -1, 43, -+ 5, 32, -1, -1, 11, -1 -+}; -+ -+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -+static const yytype_uint16 yyrline[] = -+{ -+ 0, 85, 85, 89, 97, 100, 107, 115, 118, 125, -+ 129, 136, 140, 147, 154, 162, 165, 172, 176, 183, -+ 187, 191, 195, 199, 207, 210, 214, 222, 225, 229, -+ 234, 242, 245, 249, 253, 261, 264, 268, 276, 279, -+ 283, 291, 299, 302 -+}; -+#endif -+ -+#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE -+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. -+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -+static const char *const yytname[] = -+{ -+ "$end", "error", "$undefined", "DT_V1", "DT_MEMRESERVE", -+ "DT_PROPNODENAME", "DT_LITERAL", "DT_LEGACYLITERAL", "DT_BASE", -+ "DT_BYTE", "DT_STRING", "DT_LABEL", "DT_REF", "';'", "'-'", "'/'", "'{'", -+ "'}'", "'='", "'<'", "'>'", "'['", "']'", "','", "$accept", "sourcefile", -+ "memreserves", "memreserve", "v0_memreserves", "v0_memreserve", "addr", -+ "devicetree", "nodedef", "proplist", "propdef", "propdata", -+ "propdataprefix", "celllist", "cellbase", "cellval", "bytestring", -+ "subnodes", "subnode", "label", 0 -+}; -+#endif -+ -+# ifdef YYPRINT -+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to -+ token YYLEX-NUM. */ -+static const yytype_uint16 yytoknum[] = -+{ -+ 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, -+ 265, 266, 267, 59, 45, 47, 123, 125, 61, 60, -+ 62, 91, 93, 44 -+}; -+# endif -+ -+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -+static const yytype_uint8 yyr1[] = -+{ -+ 0, 24, 25, 25, 26, 26, 27, 28, 28, 29, -+ 29, 30, 30, 31, 32, 33, 33, 34, 34, 35, -+ 35, 35, 35, 35, 36, 36, 36, 37, 37, 37, -+ 37, 38, 38, 39, 39, 40, 40, 40, 41, 41, -+ 41, 42, 43, 43 -+}; -+ -+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -+static const yytype_uint8 yyr2[] = -+{ -+ 0, 2, 4, 2, 0, 2, 5, 0, 2, 1, -+ 6, 1, 1, 2, 5, 0, 2, 5, 3, 2, -+ 4, 4, 2, 2, 0, 2, 2, 0, 2, 2, -+ 2, 0, 1, 1, 2, 0, 2, 2, 0, 2, -+ 2, 3, 0, 1 -+}; -+ -+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state -+ STATE-NUM when YYTABLE doesn't specify something else to do. Zero -+ means the default is an error. */ -+static const yytype_uint8 yydefact[] = -+{ -+ 7, 0, 43, 0, 9, 0, 7, 0, 4, 1, -+ 0, 3, 8, 0, 0, 4, 0, 15, 13, 11, -+ 12, 0, 2, 5, 0, 38, 0, 0, 0, 16, -+ 0, 38, 0, 0, 6, 0, 40, 39, 0, 10, -+ 14, 18, 24, 41, 0, 0, 23, 17, 25, 19, -+ 26, 22, 27, 35, 31, 0, 33, 32, 30, 29, -+ 20, 0, 28, 36, 37, 21, 34 -+}; -+ -+/* YYDEFGOTO[NTERM-NUM]. */ -+static const yytype_int8 yydefgoto[] = -+{ -+ -1, 3, 14, 4, 5, 6, 27, 11, 18, 25, -+ 29, 44, 45, 54, 61, 62, 55, 30, 31, 7 -+}; -+ -+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing -+ STATE-NUM. */ -+#define YYPACT_NINF -13 -+static const yytype_int8 yypact[] = -+{ -+ 23, 11, -13, 37, -13, -4, 18, 39, 18, -13, -+ 28, -13, -13, 34, -4, 18, 41, -13, -13, -13, -+ -13, 25, -13, -13, 34, -3, 34, 33, 34, -13, -+ 30, -3, 43, 36, -13, 38, -13, -13, 20, -13, -+ -13, -13, -13, -13, 2, 9, -13, -13, -13, -13, -+ -13, -13, -13, -13, -2, -6, -13, -13, -13, -13, -+ -13, 45, -13, -13, -13, -13, -13 -+}; -+ -+/* YYPGOTO[NTERM-NUM]. */ -+static const yytype_int8 yypgoto[] = -+{ -+ -13, -13, 35, 27, 47, -13, -12, 40, 17, -13, -+ 26, -13, -13, -13, -13, -13, -13, 29, -13, -8 -+}; -+ -+/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If -+ positive, shift that token. If negative, reduce the rule which -+ number is the opposite. If zero, do what YYDEFACT says. -+ If YYTABLE_NINF, syntax error. */ -+#define YYTABLE_NINF -43 -+static const yytype_int8 yytable[] = -+{ -+ 16, 21, -42, 63, 56, 64, 57, 16, 2, 58, -+ 59, 10, 28, 46, 33, 47, 65, 32, 60, 49, -+ 50, 51, -42, 32, 8, 48, 1, -42, 52, 2, -+ 53, 19, 20, 41, 2, 15, 17, 9, 42, 26, -+ 19, 20, 15, 13, 17, 24, 34, 35, 38, 39, -+ 23, 40, 66, 12, 22, 43, 0, 36, 0, 0, -+ 37 -+}; -+ -+static const yytype_int8 yycheck[] = -+{ -+ 8, 13, 5, 9, 6, 11, 8, 15, 11, 11, -+ 12, 15, 24, 11, 26, 13, 22, 25, 20, 10, -+ 11, 12, 4, 31, 13, 23, 3, 4, 19, 11, -+ 21, 6, 7, 13, 11, 8, 16, 0, 18, 14, -+ 6, 7, 15, 4, 16, 4, 13, 17, 5, 13, -+ 15, 13, 7, 6, 14, 38, -1, 31, -1, -1, -+ 31 -+}; -+ -+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing -+ symbol of state STATE-NUM. */ -+static const yytype_uint8 yystos[] = -+{ -+ 0, 3, 11, 25, 27, 28, 29, 43, 13, 0, -+ 15, 31, 28, 4, 26, 27, 43, 16, 32, 6, -+ 7, 30, 31, 26, 4, 33, 14, 30, 30, 34, -+ 41, 42, 43, 30, 13, 17, 34, 41, 5, 13, -+ 13, 13, 18, 32, 35, 36, 11, 13, 23, 10, -+ 11, 12, 19, 21, 37, 40, 6, 8, 11, 12, -+ 20, 38, 39, 9, 11, 22, 7 -+}; -+ -+#define yyerrok (yyerrstatus = 0) -+#define yyclearin (yychar = YYEMPTY) -+#define YYEMPTY (-2) -+#define YYEOF 0 -+ -+#define YYACCEPT goto yyacceptlab -+#define YYABORT goto yyabortlab -+#define YYERROR goto yyerrorlab -+ -+ -+/* Like YYERROR except do call yyerror. This remains here temporarily -+ to ease the transition to the new meaning of YYERROR, for GCC. -+ Once GCC version 2 has supplanted version 1, this can go. */ -+ -+#define YYFAIL goto yyerrlab -+ -+#define YYRECOVERING() (!!yyerrstatus) -+ -+#define YYBACKUP(Token, Value) \ -+do \ -+ if (yychar == YYEMPTY && yylen == 1) \ -+ { \ -+ yychar = (Token); \ -+ yylval = (Value); \ -+ yytoken = YYTRANSLATE (yychar); \ -+ YYPOPSTACK (1); \ -+ goto yybackup; \ -+ } \ -+ else \ -+ { \ -+ yyerror (YY_("syntax error: cannot back up")); \ -+ YYERROR; \ -+ } \ -+while (YYID (0)) -+ -+ -+#define YYTERROR 1 -+#define YYERRCODE 256 -+ -+ -+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. -+ If N is 0, then set CURRENT to the empty location which ends -+ the previous symbol: RHS[0] (always defined). */ -+ -+#define YYRHSLOC(Rhs, K) ((Rhs)[K]) -+#ifndef YYLLOC_DEFAULT -+# define YYLLOC_DEFAULT(Current, Rhs, N) \ -+ do \ -+ if (YYID (N)) \ -+ { \ -+ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ -+ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ -+ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ -+ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ -+ } \ -+ else \ -+ { \ -+ (Current).first_line = (Current).last_line = \ -+ YYRHSLOC (Rhs, 0).last_line; \ -+ (Current).first_column = (Current).last_column = \ -+ YYRHSLOC (Rhs, 0).last_column; \ -+ } \ -+ while (YYID (0)) -+#endif -+ -+ -+/* YY_LOCATION_PRINT -- Print the location on the stream. -+ This macro was not mandated originally: define only if we know -+ we won't break user code: when these are the locations we know. */ -+ -+#ifndef YY_LOCATION_PRINT -+# if YYLTYPE_IS_TRIVIAL -+# define YY_LOCATION_PRINT(File, Loc) \ -+ fprintf (File, "%d.%d-%d.%d", \ -+ (Loc).first_line, (Loc).first_column, \ -+ (Loc).last_line, (Loc).last_column) -+# else -+# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -+# endif -+#endif -+ -+ -+/* YYLEX -- calling `yylex' with the right arguments. */ -+ -+#ifdef YYLEX_PARAM -+# define YYLEX yylex (YYLEX_PARAM) -+#else -+# define YYLEX yylex () -+#endif -+ -+/* Enable debugging if requested. */ -+#if YYDEBUG -+ -+# ifndef YYFPRINTF -+# include /* INFRINGES ON USER NAME SPACE */ -+# define YYFPRINTF fprintf -+# endif -+ -+# define YYDPRINTF(Args) \ -+do { \ -+ if (yydebug) \ -+ YYFPRINTF Args; \ -+} while (YYID (0)) -+ -+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -+do { \ -+ if (yydebug) \ -+ { \ -+ YYFPRINTF (stderr, "%s ", Title); \ -+ yy_symbol_print (stderr, \ -+ Type, Value, Location); \ -+ YYFPRINTF (stderr, "\n"); \ -+ } \ -+} while (YYID (0)) -+ -+ -+/*--------------------------------. -+| Print this symbol on YYOUTPUT. | -+`--------------------------------*/ -+ -+/*ARGSUSED*/ -+#if (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) -+static void -+yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp) -+#else -+static void -+yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp) -+ FILE *yyoutput; -+ int yytype; -+ YYSTYPE const * const yyvaluep; -+ YYLTYPE const * const yylocationp; -+#endif -+{ -+ if (!yyvaluep) -+ return; -+ YYUSE (yylocationp); -+# ifdef YYPRINT -+ if (yytype < YYNTOKENS) -+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -+# else -+ YYUSE (yyoutput); -+# endif -+ switch (yytype) -+ { -+ default: -+ break; -+ } -+} -+ -+ -+/*--------------------------------. -+| Print this symbol on YYOUTPUT. | -+`--------------------------------*/ -+ -+#if (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) -+static void -+yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp) -+#else -+static void -+yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp) -+ FILE *yyoutput; -+ int yytype; -+ YYSTYPE const * const yyvaluep; -+ YYLTYPE const * const yylocationp; -+#endif -+{ -+ if (yytype < YYNTOKENS) -+ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); -+ else -+ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); -+ -+ YY_LOCATION_PRINT (yyoutput, *yylocationp); -+ YYFPRINTF (yyoutput, ": "); -+ yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp); -+ YYFPRINTF (yyoutput, ")"); -+} -+ -+/*------------------------------------------------------------------. -+| yy_stack_print -- Print the state stack from its BOTTOM up to its | -+| TOP (included). | -+`------------------------------------------------------------------*/ -+ -+#if (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) -+static void -+yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) -+#else -+static void -+yy_stack_print (bottom, top) -+ yytype_int16 *bottom; -+ yytype_int16 *top; -+#endif -+{ -+ YYFPRINTF (stderr, "Stack now"); -+ for (; bottom <= top; ++bottom) -+ YYFPRINTF (stderr, " %d", *bottom); -+ YYFPRINTF (stderr, "\n"); -+} -+ -+# define YY_STACK_PRINT(Bottom, Top) \ -+do { \ -+ if (yydebug) \ -+ yy_stack_print ((Bottom), (Top)); \ -+} while (YYID (0)) -+ -+ -+/*------------------------------------------------. -+| Report that the YYRULE is going to be reduced. | -+`------------------------------------------------*/ -+ -+#if (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) -+static void -+yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule) -+#else -+static void -+yy_reduce_print (yyvsp, yylsp, yyrule) -+ YYSTYPE *yyvsp; -+ YYLTYPE *yylsp; -+ int yyrule; -+#endif -+{ -+ int yynrhs = yyr2[yyrule]; -+ int yyi; -+ unsigned long int yylno = yyrline[yyrule]; -+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", -+ yyrule - 1, yylno); -+ /* The symbols being reduced. */ -+ for (yyi = 0; yyi < yynrhs; yyi++) -+ { -+ fprintf (stderr, " $%d = ", yyi + 1); -+ yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], -+ &(yyvsp[(yyi + 1) - (yynrhs)]) -+ , &(yylsp[(yyi + 1) - (yynrhs)]) ); -+ fprintf (stderr, "\n"); -+ } -+} -+ -+# define YY_REDUCE_PRINT(Rule) \ -+do { \ -+ if (yydebug) \ -+ yy_reduce_print (yyvsp, yylsp, Rule); \ -+} while (YYID (0)) -+ -+/* Nonzero means print parse trace. It is left uninitialized so that -+ multiple parsers can coexist. */ -+int yydebug; -+#else /* !YYDEBUG */ -+# define YYDPRINTF(Args) -+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) -+# define YY_STACK_PRINT(Bottom, Top) -+# define YY_REDUCE_PRINT(Rule) -+#endif /* !YYDEBUG */ -+ -+ -+/* YYINITDEPTH -- initial size of the parser's stacks. */ -+#ifndef YYINITDEPTH -+# define YYINITDEPTH 200 -+#endif -+ -+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only -+ if the built-in stack extension method is used). -+ -+ Do not make this value too large; the results are undefined if -+ YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) -+ evaluated with infinite-precision integer arithmetic. */ -+ -+#ifndef YYMAXDEPTH -+# define YYMAXDEPTH 10000 -+#endif -+ -+ -+ -+#if YYERROR_VERBOSE -+ -+# ifndef yystrlen -+# if defined __GLIBC__ && defined _STRING_H -+# define yystrlen strlen -+# else -+/* Return the length of YYSTR. */ -+#if (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) -+static YYSIZE_T -+yystrlen (const char *yystr) -+#else -+static YYSIZE_T -+yystrlen (yystr) -+ const char *yystr; -+#endif -+{ -+ YYSIZE_T yylen; -+ for (yylen = 0; yystr[yylen]; yylen++) -+ continue; -+ return yylen; -+} -+# endif -+# endif -+ -+# ifndef yystpcpy -+# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE -+# define yystpcpy stpcpy -+# else -+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in -+ YYDEST. */ -+#if (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) -+static char * -+yystpcpy (char *yydest, const char *yysrc) -+#else -+static char * -+yystpcpy (yydest, yysrc) -+ char *yydest; -+ const char *yysrc; -+#endif -+{ -+ char *yyd = yydest; -+ const char *yys = yysrc; -+ -+ while ((*yyd++ = *yys++) != '\0') -+ continue; -+ -+ return yyd - 1; -+} -+# endif -+# endif -+ -+# ifndef yytnamerr -+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary -+ quotes and backslashes, so that it's suitable for yyerror. The -+ heuristic is that double-quoting is unnecessary unless the string -+ contains an apostrophe, a comma, or backslash (other than -+ backslash-backslash). YYSTR is taken from yytname. If YYRES is -+ null, do not copy; instead, return the length of what the result -+ would have been. */ -+static YYSIZE_T -+yytnamerr (char *yyres, const char *yystr) -+{ -+ if (*yystr == '"') -+ { -+ YYSIZE_T yyn = 0; -+ char const *yyp = yystr; -+ -+ for (;;) -+ switch (*++yyp) -+ { -+ case '\'': -+ case ',': -+ goto do_not_strip_quotes; -+ -+ case '\\': -+ if (*++yyp != '\\') -+ goto do_not_strip_quotes; -+ /* Fall through. */ -+ default: -+ if (yyres) -+ yyres[yyn] = *yyp; -+ yyn++; -+ break; -+ -+ case '"': -+ if (yyres) -+ yyres[yyn] = '\0'; -+ return yyn; -+ } -+ do_not_strip_quotes: ; -+ } -+ -+ if (! yyres) -+ return yystrlen (yystr); -+ -+ return yystpcpy (yyres, yystr) - yyres; -+} -+# endif -+ -+/* Copy into YYRESULT an error message about the unexpected token -+ YYCHAR while in state YYSTATE. Return the number of bytes copied, -+ including the terminating null byte. If YYRESULT is null, do not -+ copy anything; just return the number of bytes that would be -+ copied. As a special case, return 0 if an ordinary "syntax error" -+ message will do. Return YYSIZE_MAXIMUM if overflow occurs during -+ size calculation. */ -+static YYSIZE_T -+yysyntax_error (char *yyresult, int yystate, int yychar) -+{ -+ int yyn = yypact[yystate]; -+ -+ if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) -+ return 0; -+ else -+ { -+ int yytype = YYTRANSLATE (yychar); -+ YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); -+ YYSIZE_T yysize = yysize0; -+ YYSIZE_T yysize1; -+ int yysize_overflow = 0; -+ enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; -+ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; -+ int yyx; -+ -+# if 0 -+ /* This is so xgettext sees the translatable formats that are -+ constructed on the fly. */ -+ YY_("syntax error, unexpected %s"); -+ YY_("syntax error, unexpected %s, expecting %s"); -+ YY_("syntax error, unexpected %s, expecting %s or %s"); -+ YY_("syntax error, unexpected %s, expecting %s or %s or %s"); -+ YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); -+# endif -+ char *yyfmt; -+ char const *yyf; -+ static char const yyunexpected[] = "syntax error, unexpected %s"; -+ static char const yyexpecting[] = ", expecting %s"; -+ static char const yyor[] = " or %s"; -+ char yyformat[sizeof yyunexpected -+ + sizeof yyexpecting - 1 -+ + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) -+ * (sizeof yyor - 1))]; -+ char const *yyprefix = yyexpecting; -+ -+ /* Start YYX at -YYN if negative to avoid negative indexes in -+ YYCHECK. */ -+ int yyxbegin = yyn < 0 ? -yyn : 0; -+ -+ /* Stay within bounds of both yycheck and yytname. */ -+ int yychecklim = YYLAST - yyn + 1; -+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; -+ int yycount = 1; -+ -+ yyarg[0] = yytname[yytype]; -+ yyfmt = yystpcpy (yyformat, yyunexpected); -+ -+ for (yyx = yyxbegin; yyx < yyxend; ++yyx) -+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) -+ { -+ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) -+ { -+ yycount = 1; -+ yysize = yysize0; -+ yyformat[sizeof yyunexpected - 1] = '\0'; -+ break; -+ } -+ yyarg[yycount++] = yytname[yyx]; -+ yysize1 = yysize + yytnamerr (0, yytname[yyx]); -+ yysize_overflow |= (yysize1 < yysize); -+ yysize = yysize1; -+ yyfmt = yystpcpy (yyfmt, yyprefix); -+ yyprefix = yyor; -+ } -+ -+ yyf = YY_(yyformat); -+ yysize1 = yysize + yystrlen (yyf); -+ yysize_overflow |= (yysize1 < yysize); -+ yysize = yysize1; -+ -+ if (yysize_overflow) -+ return YYSIZE_MAXIMUM; -+ -+ if (yyresult) -+ { -+ /* Avoid sprintf, as that infringes on the user's name space. -+ Don't have undefined behavior even if the translation -+ produced a string with the wrong number of "%s"s. */ -+ char *yyp = yyresult; -+ int yyi = 0; -+ while ((*yyp = *yyf) != '\0') -+ { -+ if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) -+ { -+ yyp += yytnamerr (yyp, yyarg[yyi++]); -+ yyf += 2; -+ } -+ else -+ { -+ yyp++; -+ yyf++; -+ } -+ } -+ } -+ return yysize; -+ } -+} -+#endif /* YYERROR_VERBOSE */ -+ -+ -+/*-----------------------------------------------. -+| Release the memory associated to this symbol. | -+`-----------------------------------------------*/ -+ -+/*ARGSUSED*/ -+#if (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) -+static void -+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp) -+#else -+static void -+yydestruct (yymsg, yytype, yyvaluep, yylocationp) -+ const char *yymsg; -+ int yytype; -+ YYSTYPE *yyvaluep; -+ YYLTYPE *yylocationp; -+#endif -+{ -+ YYUSE (yyvaluep); -+ YYUSE (yylocationp); -+ -+ if (!yymsg) -+ yymsg = "Deleting"; -+ YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); -+ -+ switch (yytype) -+ { -+ -+ default: -+ break; -+ } -+} -+ -+ -+/* Prevent warnings from -Wmissing-prototypes. */ -+ -+#ifdef YYPARSE_PARAM -+#if defined __STDC__ || defined __cplusplus -+int yyparse (void *YYPARSE_PARAM); -+#else -+int yyparse (); -+#endif -+#else /* ! YYPARSE_PARAM */ -+#if defined __STDC__ || defined __cplusplus -+int yyparse (void); -+#else -+int yyparse (); -+#endif -+#endif /* ! YYPARSE_PARAM */ -+ -+ -+ -+/* The look-ahead symbol. */ -+int yychar; -+ -+/* The semantic value of the look-ahead symbol. */ -+YYSTYPE yylval; -+ -+/* Number of syntax errors so far. */ -+int yynerrs; -+/* Location data for the look-ahead symbol. */ -+YYLTYPE yylloc; -+ -+ -+ -+/*----------. -+| yyparse. | -+`----------*/ -+ -+#ifdef YYPARSE_PARAM -+#if (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) -+int -+yyparse (void *YYPARSE_PARAM) -+#else -+int -+yyparse (YYPARSE_PARAM) -+ void *YYPARSE_PARAM; -+#endif -+#else /* ! YYPARSE_PARAM */ -+#if (defined __STDC__ || defined __C99__FUNC__ \ -+ || defined __cplusplus || defined _MSC_VER) -+int -+yyparse (void) -+#else -+int -+yyparse () -+ -+#endif -+#endif -+{ -+ -+ int yystate; -+ int yyn; -+ int yyresult; -+ /* Number of tokens to shift before error messages enabled. */ -+ int yyerrstatus; -+ /* Look-ahead token as an internal (translated) token number. */ -+ int yytoken = 0; -+#if YYERROR_VERBOSE -+ /* Buffer for error messages, and its allocated size. */ -+ char yymsgbuf[128]; -+ char *yymsg = yymsgbuf; -+ YYSIZE_T yymsg_alloc = sizeof yymsgbuf; -+#endif -+ -+ /* Three stacks and their tools: -+ `yyss': related to states, -+ `yyvs': related to semantic values, -+ `yyls': related to locations. -+ -+ Refer to the stacks thru separate pointers, to allow yyoverflow -+ to reallocate them elsewhere. */ -+ -+ /* The state stack. */ -+ yytype_int16 yyssa[YYINITDEPTH]; -+ yytype_int16 *yyss = yyssa; -+ yytype_int16 *yyssp; -+ -+ /* The semantic value stack. */ -+ YYSTYPE yyvsa[YYINITDEPTH]; -+ YYSTYPE *yyvs = yyvsa; -+ YYSTYPE *yyvsp; -+ -+ /* The location stack. */ -+ YYLTYPE yylsa[YYINITDEPTH]; -+ YYLTYPE *yyls = yylsa; -+ YYLTYPE *yylsp; -+ /* The locations where the error started and ended. */ -+ YYLTYPE yyerror_range[2]; -+ -+#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N)) -+ -+ YYSIZE_T yystacksize = YYINITDEPTH; -+ -+ /* The variables used to return semantic value and location from the -+ action routines. */ -+ YYSTYPE yyval; -+ YYLTYPE yyloc; -+ -+ /* The number of symbols on the RHS of the reduced rule. -+ Keep to zero when no symbol should be popped. */ -+ int yylen = 0; -+ -+ YYDPRINTF ((stderr, "Starting parse\n")); -+ -+ yystate = 0; -+ yyerrstatus = 0; -+ yynerrs = 0; -+ yychar = YYEMPTY; /* Cause a token to be read. */ -+ -+ /* Initialize stack pointers. -+ Waste one element of value and location stack -+ so that they stay on the same level as the state stack. -+ The wasted elements are never initialized. */ -+ -+ yyssp = yyss; -+ yyvsp = yyvs; -+ yylsp = yyls; -+#if YYLTYPE_IS_TRIVIAL -+ /* Initialize the default location before parsing starts. */ -+ yylloc.first_line = yylloc.last_line = 1; -+ yylloc.first_column = yylloc.last_column = 0; -+#endif -+ -+ goto yysetstate; -+ -+/*------------------------------------------------------------. -+| yynewstate -- Push a new state, which is found in yystate. | -+`------------------------------------------------------------*/ -+ yynewstate: -+ /* In all cases, when you get here, the value and location stacks -+ have just been pushed. So pushing a state here evens the stacks. */ -+ yyssp++; -+ -+ yysetstate: -+ *yyssp = yystate; -+ -+ if (yyss + yystacksize - 1 <= yyssp) -+ { -+ /* Get the current used size of the three stacks, in elements. */ -+ YYSIZE_T yysize = yyssp - yyss + 1; -+ -+#ifdef yyoverflow -+ { -+ /* Give user a chance to reallocate the stack. Use copies of -+ these so that the &'s don't force the real ones into -+ memory. */ -+ YYSTYPE *yyvs1 = yyvs; -+ yytype_int16 *yyss1 = yyss; -+ YYLTYPE *yyls1 = yyls; -+ -+ /* Each stack pointer address is followed by the size of the -+ data in use in that stack, in bytes. This used to be a -+ conditional around just the two extra args, but that might -+ be undefined if yyoverflow is a macro. */ -+ yyoverflow (YY_("memory exhausted"), -+ &yyss1, yysize * sizeof (*yyssp), -+ &yyvs1, yysize * sizeof (*yyvsp), -+ &yyls1, yysize * sizeof (*yylsp), -+ &yystacksize); -+ yyls = yyls1; -+ yyss = yyss1; -+ yyvs = yyvs1; -+ } -+#else /* no yyoverflow */ -+# ifndef YYSTACK_RELOCATE -+ goto yyexhaustedlab; -+# else -+ /* Extend the stack our own way. */ -+ if (YYMAXDEPTH <= yystacksize) -+ goto yyexhaustedlab; -+ yystacksize *= 2; -+ if (YYMAXDEPTH < yystacksize) -+ yystacksize = YYMAXDEPTH; -+ -+ { -+ yytype_int16 *yyss1 = yyss; -+ union yyalloc *yyptr = -+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); -+ if (! yyptr) -+ goto yyexhaustedlab; -+ YYSTACK_RELOCATE (yyss); -+ YYSTACK_RELOCATE (yyvs); -+ YYSTACK_RELOCATE (yyls); -+# undef YYSTACK_RELOCATE -+ if (yyss1 != yyssa) -+ YYSTACK_FREE (yyss1); -+ } -+# endif -+#endif /* no yyoverflow */ -+ -+ yyssp = yyss + yysize - 1; -+ yyvsp = yyvs + yysize - 1; -+ yylsp = yyls + yysize - 1; -+ -+ YYDPRINTF ((stderr, "Stack size increased to %lu\n", -+ (unsigned long int) yystacksize)); -+ -+ if (yyss + yystacksize - 1 <= yyssp) -+ YYABORT; -+ } -+ -+ YYDPRINTF ((stderr, "Entering state %d\n", yystate)); -+ -+ goto yybackup; -+ -+/*-----------. -+| yybackup. | -+`-----------*/ -+yybackup: -+ -+ /* Do appropriate processing given the current state. Read a -+ look-ahead token if we need one and don't already have one. */ -+ -+ /* First try to decide what to do without reference to look-ahead token. */ -+ yyn = yypact[yystate]; -+ if (yyn == YYPACT_NINF) -+ goto yydefault; -+ -+ /* Not known => get a look-ahead token if don't already have one. */ -+ -+ /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ -+ if (yychar == YYEMPTY) -+ { -+ YYDPRINTF ((stderr, "Reading a token: ")); -+ yychar = YYLEX; -+ } -+ -+ if (yychar <= YYEOF) -+ { -+ yychar = yytoken = YYEOF; -+ YYDPRINTF ((stderr, "Now at end of input.\n")); -+ } -+ else -+ { -+ yytoken = YYTRANSLATE (yychar); -+ YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); -+ } -+ -+ /* If the proper action on seeing token YYTOKEN is to reduce or to -+ detect an error, take that action. */ -+ yyn += yytoken; -+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) -+ goto yydefault; -+ yyn = yytable[yyn]; -+ if (yyn <= 0) -+ { -+ if (yyn == 0 || yyn == YYTABLE_NINF) -+ goto yyerrlab; -+ yyn = -yyn; -+ goto yyreduce; -+ } -+ -+ if (yyn == YYFINAL) -+ YYACCEPT; -+ -+ /* Count tokens shifted since error; after three, turn off error -+ status. */ -+ if (yyerrstatus) -+ yyerrstatus--; -+ -+ /* Shift the look-ahead token. */ -+ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); -+ -+ /* Discard the shifted token unless it is eof. */ -+ if (yychar != YYEOF) -+ yychar = YYEMPTY; -+ -+ yystate = yyn; -+ *++yyvsp = yylval; -+ *++yylsp = yylloc; -+ goto yynewstate; -+ -+ -+/*-----------------------------------------------------------. -+| yydefault -- do the default action for the current state. | -+`-----------------------------------------------------------*/ -+yydefault: -+ yyn = yydefact[yystate]; -+ if (yyn == 0) -+ goto yyerrlab; -+ goto yyreduce; -+ -+ -+/*-----------------------------. -+| yyreduce -- Do a reduction. | -+`-----------------------------*/ -+yyreduce: -+ /* yyn is the number of a rule to reduce with. */ -+ yylen = yyr2[yyn]; -+ -+ /* If YYLEN is nonzero, implement the default value of the action: -+ `$$ = $1'. -+ -+ Otherwise, the following line sets YYVAL to garbage. -+ This behavior is undocumented and Bison -+ users should not rely upon it. Assigning to YYVAL -+ unconditionally makes the parser a bit smaller, and it avoids a -+ GCC warning that YYVAL may be used uninitialized. */ -+ yyval = yyvsp[1-yylen]; -+ -+ /* Default location. */ -+ YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen); -+ YY_REDUCE_PRINT (yyn); -+ switch (yyn) -+ { -+ case 2: -+#line 86 "dtc-parser.y" -+ { -+ the_boot_info = build_boot_info((yyvsp[(3) - (4)].re), (yyvsp[(4) - (4)].node)); -+ ;} -+ break; -+ -+ case 3: -+#line 90 "dtc-parser.y" -+ { -+ the_boot_info = build_boot_info((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].node)); -+ ;} -+ break; -+ -+ case 4: -+#line 97 "dtc-parser.y" -+ { -+ (yyval.re) = NULL; -+ ;} -+ break; -+ -+ case 5: -+#line 101 "dtc-parser.y" -+ { -+ (yyval.re) = chain_reserve_entry((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].re)); -+ ;} -+ break; -+ -+ case 6: -+#line 108 "dtc-parser.y" -+ { -+ (yyval.re) = build_reserve_entry((yyvsp[(3) - (5)].addr), (yyvsp[(4) - (5)].addr), (yyvsp[(1) - (5)].labelref)); -+ ;} -+ break; -+ -+ case 7: -+#line 115 "dtc-parser.y" -+ { -+ (yyval.re) = NULL; -+ ;} -+ break; -+ -+ case 8: -+#line 119 "dtc-parser.y" -+ { -+ (yyval.re) = chain_reserve_entry((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].re)); -+ ;} -+ break; -+ -+ case 9: -+#line 126 "dtc-parser.y" -+ { -+ (yyval.re) = (yyvsp[(1) - (1)].re); -+ ;} -+ break; -+ -+ case 10: -+#line 130 "dtc-parser.y" -+ { -+ (yyval.re) = build_reserve_entry((yyvsp[(3) - (6)].addr), (yyvsp[(5) - (6)].addr) - (yyvsp[(3) - (6)].addr) + 1, (yyvsp[(1) - (6)].labelref)); -+ ;} -+ break; -+ -+ case 11: -+#line 137 "dtc-parser.y" -+ { -+ (yyval.addr) = eval_literal((yyvsp[(1) - (1)].literal), 0, 64); -+ ;} -+ break; -+ -+ case 12: -+#line 141 "dtc-parser.y" -+ { -+ (yyval.addr) = eval_literal((yyvsp[(1) - (1)].literal), 16, 64); -+ ;} -+ break; -+ -+ case 13: -+#line 148 "dtc-parser.y" -+ { -+ (yyval.node) = name_node((yyvsp[(2) - (2)].node), "", NULL); -+ ;} -+ break; -+ -+ case 14: -+#line 155 "dtc-parser.y" -+ { -+ (yyval.node) = build_node((yyvsp[(2) - (5)].proplist), (yyvsp[(3) - (5)].nodelist)); -+ ;} -+ break; -+ -+ case 15: -+#line 162 "dtc-parser.y" -+ { -+ (yyval.proplist) = NULL; -+ ;} -+ break; -+ -+ case 16: -+#line 166 "dtc-parser.y" -+ { -+ (yyval.proplist) = chain_property((yyvsp[(2) - (2)].prop), (yyvsp[(1) - (2)].proplist)); -+ ;} -+ break; -+ -+ case 17: -+#line 173 "dtc-parser.y" -+ { -+ (yyval.prop) = build_property((yyvsp[(2) - (5)].propnodename), (yyvsp[(4) - (5)].data), (yyvsp[(1) - (5)].labelref)); -+ ;} -+ break; -+ -+ case 18: -+#line 177 "dtc-parser.y" -+ { -+ (yyval.prop) = build_property((yyvsp[(2) - (3)].propnodename), empty_data, (yyvsp[(1) - (3)].labelref)); -+ ;} -+ break; -+ -+ case 19: -+#line 184 "dtc-parser.y" -+ { -+ (yyval.data) = data_merge((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].data)); -+ ;} -+ break; -+ -+ case 20: -+#line 188 "dtc-parser.y" -+ { -+ (yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data)); -+ ;} -+ break; -+ -+ case 21: -+#line 192 "dtc-parser.y" -+ { -+ (yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data)); -+ ;} -+ break; -+ -+ case 22: -+#line 196 "dtc-parser.y" -+ { -+ (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), REF_PATH, (yyvsp[(2) - (2)].labelref)); -+ ;} -+ break; -+ -+ case 23: -+#line 200 "dtc-parser.y" -+ { -+ (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); -+ ;} -+ break; -+ -+ case 24: -+#line 207 "dtc-parser.y" -+ { -+ (yyval.data) = empty_data; -+ ;} -+ break; -+ -+ case 25: -+#line 211 "dtc-parser.y" -+ { -+ (yyval.data) = (yyvsp[(1) - (2)].data); -+ ;} -+ break; -+ -+ case 26: -+#line 215 "dtc-parser.y" -+ { -+ (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); -+ ;} -+ break; -+ -+ case 27: -+#line 222 "dtc-parser.y" -+ { -+ (yyval.data) = empty_data; -+ ;} -+ break; -+ -+ case 28: -+#line 226 "dtc-parser.y" -+ { -+ (yyval.data) = data_append_cell((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].cell)); -+ ;} -+ break; -+ -+ case 29: -+#line 230 "dtc-parser.y" -+ { -+ (yyval.data) = data_append_cell(data_add_marker((yyvsp[(1) - (2)].data), REF_PHANDLE, -+ (yyvsp[(2) - (2)].labelref)), -1); -+ ;} -+ break; -+ -+ case 30: -+#line 235 "dtc-parser.y" -+ { -+ (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); -+ ;} -+ break; -+ -+ case 31: -+#line 242 "dtc-parser.y" -+ { -+ (yyval.cbase) = 16; -+ ;} -+ break; -+ -+ case 33: -+#line 250 "dtc-parser.y" -+ { -+ (yyval.cell) = eval_literal((yyvsp[(1) - (1)].literal), 0, 32); -+ ;} -+ break; -+ -+ case 34: -+#line 254 "dtc-parser.y" -+ { -+ (yyval.cell) = eval_literal((yyvsp[(2) - (2)].literal), (yyvsp[(1) - (2)].cbase), 32); -+ ;} -+ break; -+ -+ case 35: -+#line 261 "dtc-parser.y" -+ { -+ (yyval.data) = empty_data; -+ ;} -+ break; -+ -+ case 36: -+#line 265 "dtc-parser.y" -+ { -+ (yyval.data) = data_append_byte((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].byte)); -+ ;} -+ break; -+ -+ case 37: -+#line 269 "dtc-parser.y" -+ { -+ (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref)); -+ ;} -+ break; -+ -+ case 38: -+#line 276 "dtc-parser.y" -+ { -+ (yyval.nodelist) = NULL; -+ ;} -+ break; -+ -+ case 39: -+#line 280 "dtc-parser.y" -+ { -+ (yyval.nodelist) = chain_node((yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].nodelist)); -+ ;} -+ break; -+ -+ case 40: -+#line 284 "dtc-parser.y" -+ { -+ yyerror("syntax error: properties must precede subnodes\n"); -+ YYERROR; -+ ;} -+ break; -+ -+ case 41: -+#line 292 "dtc-parser.y" -+ { -+ (yyval.node) = name_node((yyvsp[(3) - (3)].node), (yyvsp[(2) - (3)].propnodename), (yyvsp[(1) - (3)].labelref)); -+ ;} -+ break; -+ -+ case 42: -+#line 299 "dtc-parser.y" -+ { -+ (yyval.labelref) = NULL; -+ ;} -+ break; -+ -+ case 43: -+#line 303 "dtc-parser.y" -+ { -+ (yyval.labelref) = (yyvsp[(1) - (1)].labelref); -+ ;} -+ break; -+ -+ -+/* Line 1267 of yacc.c. */ -+#line 1734 "dtc-parser.tab.c" -+ default: break; -+ } -+ YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); -+ -+ YYPOPSTACK (yylen); -+ yylen = 0; -+ YY_STACK_PRINT (yyss, yyssp); -+ -+ *++yyvsp = yyval; -+ *++yylsp = yyloc; -+ -+ /* Now `shift' the result of the reduction. Determine what state -+ that goes to, based on the state we popped back to and the rule -+ number reduced by. */ -+ -+ yyn = yyr1[yyn]; -+ -+ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; -+ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) -+ yystate = yytable[yystate]; -+ else -+ yystate = yydefgoto[yyn - YYNTOKENS]; -+ -+ goto yynewstate; -+ -+ -+/*------------------------------------. -+| yyerrlab -- here on detecting error | -+`------------------------------------*/ -+yyerrlab: -+ /* If not already recovering from an error, report this error. */ -+ if (!yyerrstatus) -+ { -+ ++yynerrs; -+#if ! YYERROR_VERBOSE -+ yyerror (YY_("syntax error")); -+#else -+ { -+ YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); -+ if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) -+ { -+ YYSIZE_T yyalloc = 2 * yysize; -+ if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) -+ yyalloc = YYSTACK_ALLOC_MAXIMUM; -+ if (yymsg != yymsgbuf) -+ YYSTACK_FREE (yymsg); -+ yymsg = (char *) YYSTACK_ALLOC (yyalloc); -+ if (yymsg) -+ yymsg_alloc = yyalloc; -+ else -+ { -+ yymsg = yymsgbuf; -+ yymsg_alloc = sizeof yymsgbuf; -+ } -+ } -+ -+ if (0 < yysize && yysize <= yymsg_alloc) -+ { -+ (void) yysyntax_error (yymsg, yystate, yychar); -+ yyerror (yymsg); -+ } -+ else -+ { -+ yyerror (YY_("syntax error")); -+ if (yysize != 0) -+ goto yyexhaustedlab; -+ } -+ } -+#endif -+ } -+ -+ yyerror_range[0] = yylloc; -+ -+ if (yyerrstatus == 3) -+ { -+ /* If just tried and failed to reuse look-ahead token after an -+ error, discard it. */ -+ -+ if (yychar <= YYEOF) -+ { -+ /* Return failure if at end of input. */ -+ if (yychar == YYEOF) -+ YYABORT; -+ } -+ else -+ { -+ yydestruct ("Error: discarding", -+ yytoken, &yylval, &yylloc); -+ yychar = YYEMPTY; -+ } -+ } -+ -+ /* Else will try to reuse look-ahead token after shifting the error -+ token. */ -+ goto yyerrlab1; -+ -+ -+/*---------------------------------------------------. -+| yyerrorlab -- error raised explicitly by YYERROR. | -+`---------------------------------------------------*/ -+yyerrorlab: -+ -+ /* Pacify compilers like GCC when the user code never invokes -+ YYERROR and the label yyerrorlab therefore never appears in user -+ code. */ -+ if (/*CONSTCOND*/ 0) -+ goto yyerrorlab; -+ -+ yyerror_range[0] = yylsp[1-yylen]; -+ /* Do not reclaim the symbols of the rule which action triggered -+ this YYERROR. */ -+ YYPOPSTACK (yylen); -+ yylen = 0; -+ YY_STACK_PRINT (yyss, yyssp); -+ yystate = *yyssp; -+ goto yyerrlab1; -+ -+ -+/*-------------------------------------------------------------. -+| yyerrlab1 -- common code for both syntax error and YYERROR. | -+`-------------------------------------------------------------*/ -+yyerrlab1: -+ yyerrstatus = 3; /* Each real token shifted decrements this. */ -+ -+ for (;;) -+ { -+ yyn = yypact[yystate]; -+ if (yyn != YYPACT_NINF) -+ { -+ yyn += YYTERROR; -+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) -+ { -+ yyn = yytable[yyn]; -+ if (0 < yyn) -+ break; -+ } -+ } -+ -+ /* Pop the current state because it cannot handle the error token. */ -+ if (yyssp == yyss) -+ YYABORT; -+ -+ yyerror_range[0] = *yylsp; -+ yydestruct ("Error: popping", -+ yystos[yystate], yyvsp, yylsp); -+ YYPOPSTACK (1); -+ yystate = *yyssp; -+ YY_STACK_PRINT (yyss, yyssp); -+ } -+ -+ if (yyn == YYFINAL) -+ YYACCEPT; -+ -+ *++yyvsp = yylval; -+ -+ yyerror_range[1] = yylloc; -+ /* Using YYLLOC is tempting, but would change the location of -+ the look-ahead. YYLOC is available though. */ -+ YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2); -+ *++yylsp = yyloc; -+ -+ /* Shift the error token. */ -+ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); -+ -+ yystate = yyn; -+ goto yynewstate; -+ -+ -+/*-------------------------------------. -+| yyacceptlab -- YYACCEPT comes here. | -+`-------------------------------------*/ -+yyacceptlab: -+ yyresult = 0; -+ goto yyreturn; -+ -+/*-----------------------------------. -+| yyabortlab -- YYABORT comes here. | -+`-----------------------------------*/ -+yyabortlab: -+ yyresult = 1; -+ goto yyreturn; -+ -+#ifndef yyoverflow -+/*-------------------------------------------------. -+| yyexhaustedlab -- memory exhaustion comes here. | -+`-------------------------------------------------*/ -+yyexhaustedlab: -+ yyerror (YY_("memory exhausted")); -+ yyresult = 2; -+ /* Fall through. */ -+#endif -+ -+yyreturn: -+ if (yychar != YYEOF && yychar != YYEMPTY) -+ yydestruct ("Cleanup: discarding lookahead", -+ yytoken, &yylval, &yylloc); -+ /* Do not reclaim the symbols of the rule which action triggered -+ this YYABORT or YYACCEPT. */ -+ YYPOPSTACK (yylen); -+ YY_STACK_PRINT (yyss, yyssp); -+ while (yyssp != yyss) -+ { -+ yydestruct ("Cleanup: popping", -+ yystos[*yyssp], yyvsp, yylsp); -+ YYPOPSTACK (1); -+ } -+#ifndef yyoverflow -+ if (yyss != yyssa) -+ YYSTACK_FREE (yyss); -+#endif -+#if YYERROR_VERBOSE -+ if (yymsg != yymsgbuf) -+ YYSTACK_FREE (yymsg); -+#endif -+ /* Make sure YYID is used. */ -+ return YYID (yyresult); -+} -+ -+ -+#line 308 "dtc-parser.y" -+ -+ -+void yyerror (char const *s) -+{ -+ const char *fname = srcpos_filename_for_num(yylloc.filenum); -+ -+ if (strcmp(fname, "-") == 0) -+ fname = "stdin"; -+ -+ fprintf(stderr, "%s:%d %s\n", -+ fname, yylloc.first_line, s); -+} -+ -+unsigned long long eval_literal(const char *s, int base, int bits) -+{ -+ unsigned long long val; -+ char *e; -+ -+ errno = 0; -+ val = strtoull(s, &e, base); -+ if (*e) -+ yyerror("bad characters in literal"); -+ else if ((errno == ERANGE) -+ || ((bits < 64) && (val >= (1ULL << bits)))) -+ yyerror("literal out of range"); -+ else if (errno != 0) -+ yyerror("bad literal"); -+ return val; -+} -+ ---- /dev/null -+++ b/arch/powerpc/boot/dtc-src/dtc-parser.tab.h_shipped -@@ -0,0 +1,111 @@ -+/* A Bison parser, made by GNU Bison 2.3. */ -+ -+/* Skeleton interface for Bison's Yacc-like parsers in C -+ -+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 -+ Free Software Foundation, Inc. -+ -+ This program is free software; you can redistribute it and/or modify -+ it under the terms of the GNU General Public License as published by -+ the Free Software Foundation; either version 2, 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 Street, Fifth Floor, -+ Boston, MA 02110-1301, USA. */ -+ -+/* As a special exception, you may create a larger work that contains -+ part or all of the Bison parser skeleton and distribute that work -+ under terms of your choice, so long as that work isn't itself a -+ parser generator using the skeleton or a modified version thereof -+ as a parser skeleton. Alternatively, if you modify or redistribute -+ the parser skeleton itself, you may (at your option) remove this -+ special exception, which will cause the skeleton and the resulting -+ Bison output files to be licensed under the GNU General Public -+ License without this special exception. -+ -+ This special exception was added by the Free Software Foundation in -+ version 2.2 of Bison. */ -+ -+/* Tokens. */ -+#ifndef YYTOKENTYPE -+# define YYTOKENTYPE -+ /* Put the tokens into the symbol table, so that GDB and other debuggers -+ know about them. */ -+ enum yytokentype { -+ DT_V1 = 258, -+ DT_MEMRESERVE = 259, -+ DT_PROPNODENAME = 260, -+ DT_LITERAL = 261, -+ DT_LEGACYLITERAL = 262, -+ DT_BASE = 263, -+ DT_BYTE = 264, -+ DT_STRING = 265, -+ DT_LABEL = 266, -+ DT_REF = 267 -+ }; -+#endif -+/* Tokens. */ -+#define DT_V1 258 -+#define DT_MEMRESERVE 259 -+#define DT_PROPNODENAME 260 -+#define DT_LITERAL 261 -+#define DT_LEGACYLITERAL 262 -+#define DT_BASE 263 -+#define DT_BYTE 264 -+#define DT_STRING 265 -+#define DT_LABEL 266 -+#define DT_REF 267 -+ -+ -+ -+ -+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -+typedef union YYSTYPE -+#line 34 "dtc-parser.y" -+{ -+ char *propnodename; -+ char *literal; -+ char *labelref; -+ unsigned int cbase; -+ u8 byte; -+ struct data data; -+ -+ u64 addr; -+ cell_t cell; -+ struct property *prop; -+ struct property *proplist; -+ struct node *node; -+ struct node *nodelist; -+ struct reserve_info *re; -+} -+/* Line 1489 of yacc.c. */ -+#line 90 "dtc-parser.tab.h" -+ YYSTYPE; -+# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -+# define YYSTYPE_IS_DECLARED 1 -+# define YYSTYPE_IS_TRIVIAL 1 -+#endif -+ -+extern YYSTYPE yylval; -+ -+#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED -+typedef struct YYLTYPE -+{ -+ int first_line; -+ int first_column; -+ int last_line; -+ int last_column; -+} YYLTYPE; -+# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ -+# define YYLTYPE_IS_DECLARED 1 -+# define YYLTYPE_IS_TRIVIAL 1 -+#endif -+ -+extern YYLTYPE yylloc; ---- /dev/null -+++ b/arch/powerpc/boot/dtc-src/dtc-parser.y -@@ -0,0 +1,336 @@ -+/* -+ * (C) Copyright David Gibson , IBM Corporation. 2005. -+ * -+ * -+ * 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 -+ */ -+ -+%locations -+ -+%{ -+#include "dtc.h" -+#include "srcpos.h" -+ -+int yylex(void); -+unsigned long long eval_literal(const char *s, int base, int bits); -+ -+extern struct boot_info *the_boot_info; -+ -+%} -+ -+%union { -+ char *propnodename; -+ char *literal; -+ char *labelref; -+ unsigned int cbase; -+ u8 byte; -+ struct data data; -+ -+ u64 addr; -+ cell_t cell; -+ struct property *prop; -+ struct property *proplist; -+ struct node *node; -+ struct node *nodelist; -+ struct reserve_info *re; -+} -+ -+%token DT_V1 -+%token DT_MEMRESERVE -+%token DT_PROPNODENAME -+%token DT_LITERAL -+%token DT_LEGACYLITERAL -+%token DT_BASE -+%token DT_BYTE -+%token DT_STRING -+%token DT_LABEL -+%token DT_REF -+ -+%type propdata -+%type propdataprefix -+%type memreserve -+%type memreserves -+%type v0_memreserve -+%type v0_memreserves -+%type addr -+%type celllist -+%type cellbase -+%type cellval -+%type bytestring -+%type propdef -+%type proplist -+ -+%type devicetree -+%type nodedef -+%type subnode -+%type subnodes -+%type label -+ -+%% -+ -+sourcefile: -+ DT_V1 ';' memreserves devicetree -+ { -+ the_boot_info = build_boot_info($3, $4); -+ } -+ | v0_memreserves devicetree -+ { -+ the_boot_info = build_boot_info($1, $2); -+ } -+ ; -+ -+memreserves: -+ /* empty */ -+ { -+ $$ = NULL; -+ } -+ | memreserve memreserves -+ { -+ $$ = chain_reserve_entry($1, $2); -+ } -+ ; -+ -+memreserve: -+ label DT_MEMRESERVE addr addr ';' -+ { -+ $$ = build_reserve_entry($3, $4, $1); -+ } -+ ; -+ -+v0_memreserves: -+ /* empty */ -+ { -+ $$ = NULL; -+ } -+ | v0_memreserve v0_memreserves -+ { -+ $$ = chain_reserve_entry($1, $2); -+ }; -+ ; -+ -+v0_memreserve: -+ memreserve -+ { -+ $$ = $1; -+ } -+ | label DT_MEMRESERVE addr '-' addr ';' -+ { -+ $$ = build_reserve_entry($3, $5 - $3 + 1, $1); -+ } -+ ; -+ -+addr: -+ DT_LITERAL -+ { -+ $$ = eval_literal($1, 0, 64); -+ } -+ | DT_LEGACYLITERAL -+ { -+ $$ = eval_literal($1, 16, 64); -+ } -+ ; -+ -+devicetree: -+ '/' nodedef -+ { -+ $$ = name_node($2, "", NULL); -+ } -+ ; -+ -+nodedef: -+ '{' proplist subnodes '}' ';' -+ { -+ $$ = build_node($2, $3); -+ } -+ ; -+ -+proplist: -+ /* empty */ -+ { -+ $$ = NULL; -+ } -+ | proplist propdef -+ { -+ $$ = chain_property($2, $1); -+ } -+ ; -+ -+propdef: -+ label DT_PROPNODENAME '=' propdata ';' -+ { -+ $$ = build_property($2, $4, $1); -+ } -+ | label DT_PROPNODENAME ';' -+ { -+ $$ = build_property($2, empty_data, $1); -+ } -+ ; -+ -+propdata: -+ propdataprefix DT_STRING -+ { -+ $$ = data_merge($1, $2); -+ } -+ | propdataprefix '<' celllist '>' -+ { -+ $$ = data_merge($1, $3); -+ } -+ | propdataprefix '[' bytestring ']' -+ { -+ $$ = data_merge($1, $3); -+ } -+ | propdataprefix DT_REF -+ { -+ $$ = data_add_marker($1, REF_PATH, $2); -+ } -+ | propdata DT_LABEL -+ { -+ $$ = data_add_marker($1, LABEL, $2); -+ } -+ ; -+ -+propdataprefix: -+ /* empty */ -+ { -+ $$ = empty_data; -+ } -+ | propdata ',' -+ { -+ $$ = $1; -+ } -+ | propdataprefix DT_LABEL -+ { -+ $$ = data_add_marker($1, LABEL, $2); -+ } -+ ; -+ -+celllist: -+ /* empty */ -+ { -+ $$ = empty_data; -+ } -+ | celllist cellval -+ { -+ $$ = data_append_cell($1, $2); -+ } -+ | celllist DT_REF -+ { -+ $$ = data_append_cell(data_add_marker($1, REF_PHANDLE, -+ $2), -1); -+ } -+ | celllist DT_LABEL -+ { -+ $$ = data_add_marker($1, LABEL, $2); -+ } -+ ; -+ -+cellbase: -+ /* empty */ -+ { -+ $$ = 16; -+ } -+ | DT_BASE -+ ; -+ -+cellval: -+ DT_LITERAL -+ { -+ $$ = eval_literal($1, 0, 32); -+ } -+ | cellbase DT_LEGACYLITERAL -+ { -+ $$ = eval_literal($2, $1, 32); -+ } -+ ; -+ -+bytestring: -+ /* empty */ -+ { -+ $$ = empty_data; -+ } -+ | bytestring DT_BYTE -+ { -+ $$ = data_append_byte($1, $2); -+ } -+ | bytestring DT_LABEL -+ { -+ $$ = data_add_marker($1, LABEL, $2); -+ } -+ ; -+ -+subnodes: -+ /* empty */ -+ { -+ $$ = NULL; -+ } -+ | subnode subnodes -+ { -+ $$ = chain_node($1, $2); -+ } -+ | subnode propdef -+ { -+ yyerror("syntax error: properties must precede subnodes\n"); -+ YYERROR; -+ } -+ ; -+ -+subnode: -+ label DT_PROPNODENAME nodedef -+ { -+ $$ = name_node($3, $2, $1); -+ } -+ ; -+ -+label: -+ /* empty */ -+ { -+ $$ = NULL; -+ } -+ | DT_LABEL -+ { -+ $$ = $1; -+ } -+ ; -+ -+%% -+ -+void yyerror (char const *s) -+{ -+ const char *fname = srcpos_filename_for_num(yylloc.filenum); -+ -+ if (strcmp(fname, "-") == 0) -+ fname = "stdin"; -+ -+ fprintf(stderr, "%s:%d %s\n", -+ fname, yylloc.first_line, s); -+} -+ -+unsigned long long eval_literal(const char *s, int base, int bits) -+{ -+ unsigned long long val; -+ char *e; -+ -+ errno = 0; -+ val = strtoull(s, &e, base); -+ if (*e) -+ yyerror("bad characters in literal"); -+ else if ((errno == ERANGE) -+ || ((bits < 64) && (val >= (1ULL << bits)))) -+ yyerror("literal out of range"); -+ else if (errno != 0) -+ yyerror("bad literal"); -+ return val; -+} ---- /dev/null -+++ b/arch/powerpc/boot/dtc-src/dtc.c -@@ -0,0 +1,231 @@ -+/* -+ * (C) Copyright David Gibson , IBM Corporation. 2005. -+ * -+ * -+ * 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 "dtc.h" -+#include "srcpos.h" -+ -+#include "version_gen.h" -+ -+/* -+ * Command line options -+ */ -+int quiet; /* Level of quietness */ -+int reservenum; /* Number of memory reservation slots */ -+int minsize; /* Minimum blob size */ -+int padsize; /* Additional padding to blob */ -+ -+char *join_path(const char *path, const char *name) -+{ -+ int lenp = strlen(path); -+ int lenn = strlen(name); -+ int len; -+ int needslash = 1; -+ char *str; -+ -+ len = lenp + lenn + 2; -+ if ((lenp > 0) && (path[lenp-1] == '/')) { -+ needslash = 0; -+ len--; -+ } -+ -+ str = xmalloc(len); -+ memcpy(str, path, lenp); -+ if (needslash) { -+ str[lenp] = '/'; -+ lenp++; -+ } -+ memcpy(str+lenp, name, lenn+1); -+ return str; -+} -+ -+void fill_fullpaths(struct node *tree, const char *prefix) -+{ -+ struct node *child; -+ const char *unit; -+ -+ tree->fullpath = join_path(prefix, tree->name); -+ -+ unit = strchr(tree->name, '@'); -+ if (unit) -+ tree->basenamelen = unit - tree->name; -+ else -+ tree->basenamelen = strlen(tree->name); -+ -+ for_each_child(tree, child) -+ fill_fullpaths(child, tree->fullpath); -+} -+ -+static void __attribute__ ((noreturn)) usage(void) -+{ -+ fprintf(stderr, "Usage:\n"); -+ fprintf(stderr, "\tdtc [options] \n"); -+ fprintf(stderr, "\nOptions:\n"); -+ fprintf(stderr, "\t-h\n"); -+ fprintf(stderr, "\t\tThis help text\n"); -+ fprintf(stderr, "\t-q\n"); -+ fprintf(stderr, "\t\tQuiet: -q suppress warnings, -qq errors, -qqq all\n"); -+ fprintf(stderr, "\t-I \n"); -+ fprintf(stderr, "\t\tInput formats are:\n"); -+ fprintf(stderr, "\t\t\tdts - device tree source text\n"); -+ fprintf(stderr, "\t\t\tdtb - device tree blob\n"); -+ fprintf(stderr, "\t\t\tfs - /proc/device-tree style directory\n"); -+ fprintf(stderr, "\t-o \n"); -+ fprintf(stderr, "\t-O \n"); -+ fprintf(stderr, "\t\tOutput formats are:\n"); -+ fprintf(stderr, "\t\t\tdts - device tree source text\n"); -+ fprintf(stderr, "\t\t\tdtb - device tree blob\n"); -+ fprintf(stderr, "\t\t\tasm - assembler source\n"); -+ fprintf(stderr, "\t-V \n"); -+ fprintf(stderr, "\t\tBlob version to produce, defaults to %d (relevant for dtb\n\t\tand asm output only)\n", DEFAULT_FDT_VERSION); -+ fprintf(stderr, "\t-R \n"); -+ fprintf(stderr, "\t\tMake space for reserve map entries (relevant for \n\t\tdtb and asm output only)\n"); -+ fprintf(stderr, "\t-S \n"); -+ fprintf(stderr, "\t\tMake the blob at least long (extra space)\n"); -+ fprintf(stderr, "\t-p \n"); -+ fprintf(stderr, "\t\tAdd padding to the blob of long (extra space)\n"); -+ fprintf(stderr, "\t-b \n"); -+ fprintf(stderr, "\t\tSet the physical boot cpu\n"); -+ fprintf(stderr, "\t-f\n"); -+ fprintf(stderr, "\t\tForce - try to produce output even if the input tree has errors\n"); -+ fprintf(stderr, "\t-v\n"); -+ fprintf(stderr, "\t\tPrint DTC version and exit\n"); -+ exit(2); -+} -+ -+int main(int argc, char *argv[]) -+{ -+ struct boot_info *bi; -+ const char *inform = "dts"; -+ const char *outform = "dts"; -+ const char *outname = "-"; -+ int force = 0, check = 0; -+ const char *arg; -+ int opt; -+ FILE *inf = NULL; -+ FILE *outf = NULL; -+ int outversion = DEFAULT_FDT_VERSION; -+ int boot_cpuid_phys = 0xfeedbeef; -+ -+ quiet = 0; -+ reservenum = 0; -+ minsize = 0; -+ padsize = 0; -+ -+ while ((opt = getopt(argc, argv, "hI:O:o:V:R:S:p:fcqb:v")) != EOF) { -+ switch (opt) { -+ case 'I': -+ inform = optarg; -+ break; -+ case 'O': -+ outform = optarg; -+ break; -+ case 'o': -+ outname = optarg; -+ break; -+ case 'V': -+ outversion = strtol(optarg, NULL, 0); -+ break; -+ case 'R': -+ reservenum = strtol(optarg, NULL, 0); -+ break; -+ case 'S': -+ minsize = strtol(optarg, NULL, 0); -+ break; -+ case 'p': -+ padsize = strtol(optarg, NULL, 0); -+ break; -+ case 'f': -+ force = 1; -+ break; -+ case 'c': -+ check = 1; -+ break; -+ case 'q': -+ quiet++; -+ break; -+ case 'b': -+ boot_cpuid_phys = strtol(optarg, NULL, 0); -+ break; -+ case 'v': -+ printf("Version: %s\n", DTC_VERSION); -+ exit(0); -+ case 'h': -+ default: -+ usage(); -+ } -+ } -+ -+ if (argc > (optind+1)) -+ usage(); -+ else if (argc < (optind+1)) -+ arg = "-"; -+ else -+ arg = argv[optind]; -+ -+ /* minsize and padsize are mutually exclusive */ -+ if ((minsize) && (padsize)) { -+ die("Can't set both -p and -S\n"); -+ } -+ -+ fprintf(stderr, "DTC: %s->%s on file \"%s\"\n", -+ inform, outform, arg); -+ -+ if (streq(inform, "dts")) { -+ bi = dt_from_source(arg); -+ } else if (streq(inform, "fs")) { -+ bi = dt_from_fs(arg); -+ } else if(streq(inform, "dtb")) { -+ inf = dtc_open_file(arg); -+ bi = dt_from_blob(inf); -+ } else { -+ die("Unknown input format \"%s\"\n", inform); -+ } -+ -+ if (inf && (inf != stdin)) -+ fclose(inf); -+ -+ if (! bi || ! bi->dt) -+ die("Couldn't read input tree\n"); -+ -+ process_checks(force, bi, check, outversion, boot_cpuid_phys); -+ -+ if (streq(outname, "-")) { -+ outf = stdout; -+ } else { -+ outf = fopen(outname, "w"); -+ if (! outf) -+ die("Couldn't open output file %s: %s\n", -+ outname, strerror(errno)); -+ } -+ -+ if (streq(outform, "dts")) { -+ dt_to_source(outf, bi); -+ } else if (streq(outform, "dtb")) { -+ dt_to_blob(outf, bi, outversion, boot_cpuid_phys); -+ } else if (streq(outform, "asm")) { -+ dt_to_asm(outf, bi, outversion, boot_cpuid_phys); -+ } else if (streq(outform, "null")) { -+ /* do nothing */ -+ } else { -+ die("Unknown output format \"%s\"\n", outform); -+ } -+ -+ exit(0); -+} ---- /dev/null -+++ b/arch/powerpc/boot/dtc-src/dtc.h -@@ -0,0 +1,269 @@ -+#ifndef _DTC_H -+#define _DTC_H -+ -+/* -+ * (C) Copyright David Gibson , IBM Corporation. 2005. -+ * -+ * -+ * 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 -+ -+#define DEFAULT_FDT_VERSION 17 -+/* -+ * Command line options -+ */ -+extern int quiet; /* Level of quietness */ -+extern int reservenum; /* Number of memory reservation slots */ -+extern int minsize; /* Minimum blob size */ -+extern int padsize; /* Additional padding to blob */ -+ -+static inline void __attribute__((noreturn)) die(char * str, ...) -+{ -+ va_list ap; -+ -+ va_start(ap, str); -+ fprintf(stderr, "FATAL ERROR: "); -+ vfprintf(stderr, str, ap); -+ exit(1); -+} -+ -+static inline void *xmalloc(size_t len) -+{ -+ void *new = malloc(len); -+ -+ if (! new) -+ die("malloc() failed\n"); -+ -+ return new; -+} -+ -+static inline void *xrealloc(void *p, size_t len) -+{ -+ void *new = realloc(p, len); -+ -+ if (! new) -+ die("realloc() failed (len=%d)\n", len); -+ -+ return new; -+} -+ -+typedef uint8_t u8; -+typedef uint16_t u16; -+typedef uint32_t u32; -+typedef uint64_t u64; -+typedef u32 cell_t; -+ -+#define cpu_to_be16(x) htons(x) -+#define be16_to_cpu(x) ntohs(x) -+ -+#define cpu_to_be32(x) htonl(x) -+#define be32_to_cpu(x) ntohl(x) -+ -+#if __BYTE_ORDER == __BIG_ENDIAN -+#define cpu_to_be64(x) (x) -+#define be64_to_cpu(x) (x) -+#else -+#define cpu_to_be64(x) bswap_64(x) -+#define be64_to_cpu(x) bswap_64(x) -+#endif -+ -+#define streq(a, b) (strcmp((a), (b)) == 0) -+#define strneq(a, b, n) (strncmp((a), (b), (n)) == 0) -+ -+#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) -+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) -+ -+/* Data blobs */ -+enum markertype { -+ REF_PHANDLE, -+ REF_PATH, -+ LABEL, -+}; -+ -+struct marker { -+ enum markertype type; -+ int offset; -+ char *ref; -+ struct marker *next; -+}; -+ -+struct data { -+ int len; -+ char *val; -+ int asize; -+ struct marker *markers; -+}; -+ -+ -+#define empty_data ((struct data){ /* all .members = 0 or NULL */ }) -+ -+#define for_each_marker(m) \ -+ for (; (m); (m) = (m)->next) -+#define for_each_marker_of_type(m, t) \ -+ for_each_marker(m) \ -+ if ((m)->type == (t)) -+ -+void data_free(struct data d); -+ -+struct data data_grow_for(struct data d, int xlen); -+ -+struct data data_copy_mem(const char *mem, int len); -+struct data data_copy_escape_string(const char *s, int len); -+struct data data_copy_file(FILE *f, size_t len); -+ -+struct data data_append_data(struct data d, const void *p, int len); -+struct data data_insert_at_marker(struct data d, struct marker *m, -+ const void *p, int len); -+struct data data_merge(struct data d1, struct data d2); -+struct data data_append_cell(struct data d, cell_t word); -+struct data data_append_re(struct data d, const struct fdt_reserve_entry *re); -+struct data data_append_addr(struct data d, u64 addr); -+struct data data_append_byte(struct data d, uint8_t byte); -+struct data data_append_zeroes(struct data d, int len); -+struct data data_append_align(struct data d, int align); -+ -+struct data data_add_marker(struct data d, enum markertype type, char *ref); -+ -+int data_is_one_string(struct data d); -+ -+/* DT constraints */ -+ -+#define MAX_PROPNAME_LEN 31 -+#define MAX_NODENAME_LEN 31 -+ -+/* Live trees */ -+struct property { -+ char *name; -+ struct data val; -+ -+ struct property *next; -+ -+ char *label; -+}; -+ -+struct node { -+ char *name; -+ struct property *proplist; -+ struct node *children; -+ -+ struct node *parent; -+ struct node *next_sibling; -+ -+ char *fullpath; -+ int basenamelen; -+ -+ cell_t phandle; -+ int addr_cells, size_cells; -+ -+ char *label; -+}; -+ -+#define for_each_property(n, p) \ -+ for ((p) = (n)->proplist; (p); (p) = (p)->next) -+ -+#define for_each_child(n, c) \ -+ for ((c) = (n)->children; (c); (c) = (c)->next_sibling) -+ -+struct property *build_property(char *name, struct data val, char *label); -+struct property *chain_property(struct property *first, struct property *list); -+struct property *reverse_properties(struct property *first); -+ -+struct node *build_node(struct property *proplist, struct node *children); -+struct node *name_node(struct node *node, char *name, char *label); -+struct node *chain_node(struct node *first, struct node *list); -+ -+void add_property(struct node *node, struct property *prop); -+void add_child(struct node *parent, struct node *child); -+ -+const char *get_unitname(struct node *node); -+struct property *get_property(struct node *node, const char *propname); -+cell_t propval_cell(struct property *prop); -+struct node *get_subnode(struct node *node, const char *nodename); -+struct node *get_node_by_path(struct node *tree, const char *path); -+struct node *get_node_by_label(struct node *tree, const char *label); -+struct node *get_node_by_phandle(struct node *tree, cell_t phandle); -+struct node *get_node_by_ref(struct node *tree, const char *ref); -+cell_t get_node_phandle(struct node *root, struct node *node); -+ -+/* Boot info (tree plus memreserve information */ -+ -+struct reserve_info { -+ struct fdt_reserve_entry re; -+ -+ struct reserve_info *next; -+ -+ char *label; -+}; -+ -+struct reserve_info *build_reserve_entry(u64 start, u64 len, char *label); -+struct reserve_info *chain_reserve_entry(struct reserve_info *first, -+ struct reserve_info *list); -+struct reserve_info *add_reserve_entry(struct reserve_info *list, -+ struct reserve_info *new); -+ -+ -+struct boot_info { -+ struct reserve_info *reservelist; -+ struct node *dt; /* the device tree */ -+}; -+ -+struct boot_info *build_boot_info(struct reserve_info *reservelist, -+ struct node *tree); -+ -+/* Checks */ -+ -+void process_checks(int force, struct boot_info *bi, -+ int checkflag, int outversion, int boot_cpuid_phys); -+ -+/* Flattened trees */ -+ -+void dt_to_blob(FILE *f, struct boot_info *bi, int version, -+ int boot_cpuid_phys); -+void dt_to_asm(FILE *f, struct boot_info *bi, int version, -+ int boot_cpuid_phys); -+ -+struct boot_info *dt_from_blob(FILE *f); -+ -+/* Tree source */ -+ -+void dt_to_source(FILE *f, struct boot_info *bi); -+struct boot_info *dt_from_source(const char *f); -+ -+/* FS trees */ -+ -+struct boot_info *dt_from_fs(const char *dirname); -+ -+/* misc */ -+ -+char *join_path(const char *path, const char *name); -+void fill_fullpaths(struct node *tree, const char *prefix); -+ -+#endif /* _DTC_H */ ---- /dev/null -+++ b/arch/powerpc/boot/dtc-src/flattree.c -@@ -0,0 +1,968 @@ -+/* -+ * (C) Copyright David Gibson , IBM Corporation. 2005. -+ * -+ * -+ * 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 "dtc.h" -+ -+#define FTF_FULLPATH 0x1 -+#define FTF_VARALIGN 0x2 -+#define FTF_NAMEPROPS 0x4 -+#define FTF_BOOTCPUID 0x8 -+#define FTF_STRTABSIZE 0x10 -+#define FTF_STRUCTSIZE 0x20 -+#define FTF_NOPS 0x40 -+ -+static struct version_info { -+ int version; -+ int last_comp_version; -+ int hdr_size; -+ int flags; -+} version_table[] = { -+ {1, 1, FDT_V1_SIZE, -+ FTF_FULLPATH|FTF_VARALIGN|FTF_NAMEPROPS}, -+ {2, 1, FDT_V2_SIZE, -+ FTF_FULLPATH|FTF_VARALIGN|FTF_NAMEPROPS|FTF_BOOTCPUID}, -+ {3, 1, FDT_V3_SIZE, -+ FTF_FULLPATH|FTF_VARALIGN|FTF_NAMEPROPS|FTF_BOOTCPUID|FTF_STRTABSIZE}, -+ {16, 16, FDT_V3_SIZE, -+ FTF_BOOTCPUID|FTF_STRTABSIZE|FTF_NOPS}, -+ {17, 16, FDT_V17_SIZE, -+ FTF_BOOTCPUID|FTF_STRTABSIZE|FTF_STRUCTSIZE|FTF_NOPS}, -+}; -+ -+struct emitter { -+ void (*cell)(void *, cell_t); -+ void (*string)(void *, char *, int); -+ void (*align)(void *, int); -+ void (*data)(void *, struct data); -+ void (*beginnode)(void *, const char *); -+ void (*endnode)(void *, const char *); -+ void (*property)(void *, const char *); -+}; -+ -+static void bin_emit_cell(void *e, cell_t val) -+{ -+ struct data *dtbuf = e; -+ -+ *dtbuf = data_append_cell(*dtbuf, val); -+} -+ -+static void bin_emit_string(void *e, char *str, int len) -+{ -+ struct data *dtbuf = e; -+ -+ if (len == 0) -+ len = strlen(str); -+ -+ *dtbuf = data_append_data(*dtbuf, str, len); -+ *dtbuf = data_append_byte(*dtbuf, '\0'); -+} -+ -+static void bin_emit_align(void *e, int a) -+{ -+ struct data *dtbuf = e; -+ -+ *dtbuf = data_append_align(*dtbuf, a); -+} -+ -+static void bin_emit_data(void *e, struct data d) -+{ -+ struct data *dtbuf = e; -+ -+ *dtbuf = data_append_data(*dtbuf, d.val, d.len); -+} -+ -+static void bin_emit_beginnode(void *e, const char *label) -+{ -+ bin_emit_cell(e, FDT_BEGIN_NODE); -+} -+ -+static void bin_emit_endnode(void *e, const char *label) -+{ -+ bin_emit_cell(e, FDT_END_NODE); -+} -+ -+static void bin_emit_property(void *e, const char *label) -+{ -+ bin_emit_cell(e, FDT_PROP); -+} -+ -+static struct emitter bin_emitter = { -+ .cell = bin_emit_cell, -+ .string = bin_emit_string, -+ .align = bin_emit_align, -+ .data = bin_emit_data, -+ .beginnode = bin_emit_beginnode, -+ .endnode = bin_emit_endnode, -+ .property = bin_emit_property, -+}; -+ -+static void emit_label(FILE *f, const char *prefix, const char *label) -+{ -+ fprintf(f, "\t.globl\t%s_%s\n", prefix, label); -+ fprintf(f, "%s_%s:\n", prefix, label); -+ fprintf(f, "_%s_%s:\n", prefix, label); -+} -+ -+static void emit_offset_label(FILE *f, const char *label, int offset) -+{ -+ fprintf(f, "\t.globl\t%s\n", label); -+ fprintf(f, "%s\t= . + %d\n", label, offset); -+} -+ -+static void asm_emit_cell(void *e, cell_t val) -+{ -+ FILE *f = e; -+ -+ fprintf(f, "\t.long\t0x%x\n", val); -+} -+ -+static void asm_emit_string(void *e, char *str, int len) -+{ -+ FILE *f = e; -+ char c = 0; -+ -+ if (len != 0) { -+ /* XXX: ewww */ -+ c = str[len]; -+ str[len] = '\0'; -+ } -+ -+ fprintf(f, "\t.string\t\"%s\"\n", str); -+ -+ if (len != 0) { -+ str[len] = c; -+ } -+} -+ -+static void asm_emit_align(void *e, int a) -+{ -+ FILE *f = e; -+ -+ fprintf(f, "\t.balign\t%d\n", a); -+} -+ -+static void asm_emit_data(void *e, struct data d) -+{ -+ FILE *f = e; -+ int off = 0; -+ struct marker *m; -+ -+ m = d.markers; -+ while (m) { -+ if (m->type == LABEL) -+ emit_offset_label(f, m->ref, m->offset); -+ m = m->next; -+ } -+ -+ while ((d.len - off) >= sizeof(u32)) { -+ fprintf(f, "\t.long\t0x%x\n", -+ be32_to_cpu(*((u32 *)(d.val+off)))); -+ off += sizeof(u32); -+ } -+ -+ if ((d.len - off) >= sizeof(u16)) { -+ fprintf(f, "\t.short\t0x%hx\n", -+ be16_to_cpu(*((u16 *)(d.val+off)))); -+ off += sizeof(u16); -+ } -+ -+ if ((d.len - off) >= 1) { -+ fprintf(f, "\t.byte\t0x%hhx\n", d.val[off]); -+ off += 1; -+ } -+ -+ assert(off == d.len); -+} -+ -+static void asm_emit_beginnode(void *e, const char *label) -+{ -+ FILE *f = e; -+ -+ if (label) { -+ fprintf(f, "\t.globl\t%s\n", label); -+ fprintf(f, "%s:\n", label); -+ } -+ fprintf(f, "\t.long\tFDT_BEGIN_NODE\n"); -+} -+ -+static void asm_emit_endnode(void *e, const char *label) -+{ -+ FILE *f = e; -+ -+ fprintf(f, "\t.long\tFDT_END_NODE\n"); -+ if (label) { -+ fprintf(f, "\t.globl\t%s_end\n", label); -+ fprintf(f, "%s_end:\n", label); -+ } -+} -+ -+static void asm_emit_property(void *e, const char *label) -+{ -+ FILE *f = e; -+ -+ if (label) { -+ fprintf(f, "\t.globl\t%s\n", label); -+ fprintf(f, "%s:\n", label); -+ } -+ fprintf(f, "\t.long\tFDT_PROP\n"); -+} -+ -+static struct emitter asm_emitter = { -+ .cell = asm_emit_cell, -+ .string = asm_emit_string, -+ .align = asm_emit_align, -+ .data = asm_emit_data, -+ .beginnode = asm_emit_beginnode, -+ .endnode = asm_emit_endnode, -+ .property = asm_emit_property, -+}; -+ -+static int stringtable_insert(struct data *d, const char *str) -+{ -+ int i; -+ -+ /* FIXME: do this more efficiently? */ -+ -+ for (i = 0; i < d->len; i++) { -+ if (streq(str, d->val + i)) -+ return i; -+ } -+ -+ *d = data_append_data(*d, str, strlen(str)+1); -+ return i; -+} -+ -+static void flatten_tree(struct node *tree, struct emitter *emit, -+ void *etarget, struct data *strbuf, -+ struct version_info *vi) -+{ -+ struct property *prop; -+ struct node *child; -+ int seen_name_prop = 0; -+ -+ emit->beginnode(etarget, tree->label); -+ -+ if (vi->flags & FTF_FULLPATH) -+ emit->string(etarget, tree->fullpath, 0); -+ else -+ emit->string(etarget, tree->name, 0); -+ -+ emit->align(etarget, sizeof(cell_t)); -+ -+ for_each_property(tree, prop) { -+ int nameoff; -+ -+ if (streq(prop->name, "name")) -+ seen_name_prop = 1; -+ -+ nameoff = stringtable_insert(strbuf, prop->name); -+ -+ emit->property(etarget, prop->label); -+ emit->cell(etarget, prop->val.len); -+ emit->cell(etarget, nameoff); -+ -+ if ((vi->flags & FTF_VARALIGN) && (prop->val.len >= 8)) -+ emit->align(etarget, 8); -+ -+ emit->data(etarget, prop->val); -+ emit->align(etarget, sizeof(cell_t)); -+ } -+ -+ if ((vi->flags & FTF_NAMEPROPS) && !seen_name_prop) { -+ emit->property(etarget, NULL); -+ emit->cell(etarget, tree->basenamelen+1); -+ emit->cell(etarget, stringtable_insert(strbuf, "name")); -+ -+ if ((vi->flags & FTF_VARALIGN) && ((tree->basenamelen+1) >= 8)) -+ emit->align(etarget, 8); -+ -+ emit->string(etarget, tree->name, tree->basenamelen); -+ emit->align(etarget, sizeof(cell_t)); -+ } -+ -+ for_each_child(tree, child) { -+ flatten_tree(child, emit, etarget, strbuf, vi); -+ } -+ -+ emit->endnode(etarget, tree->label); -+} -+ -+static struct data flatten_reserve_list(struct reserve_info *reservelist, -+ struct version_info *vi) -+{ -+ struct reserve_info *re; -+ struct data d = empty_data; -+ static struct fdt_reserve_entry null_re = {0,0}; -+ int j; -+ -+ for (re = reservelist; re; re = re->next) { -+ d = data_append_re(d, &re->re); -+ } -+ /* -+ * Add additional reserved slots if the user asked for them. -+ */ -+ for (j = 0; j < reservenum; j++) { -+ d = data_append_re(d, &null_re); -+ } -+ -+ return d; -+} -+ -+static void make_fdt_header(struct fdt_header *fdt, -+ struct version_info *vi, -+ int reservesize, int dtsize, int strsize, -+ int boot_cpuid_phys) -+{ -+ int reserve_off; -+ -+ reservesize += sizeof(struct fdt_reserve_entry); -+ -+ memset(fdt, 0xff, sizeof(*fdt)); -+ -+ fdt->magic = cpu_to_be32(FDT_MAGIC); -+ fdt->version = cpu_to_be32(vi->version); -+ fdt->last_comp_version = cpu_to_be32(vi->last_comp_version); -+ -+ /* Reserve map should be doubleword aligned */ -+ reserve_off = ALIGN(vi->hdr_size, 8); -+ -+ fdt->off_mem_rsvmap = cpu_to_be32(reserve_off); -+ fdt->off_dt_struct = cpu_to_be32(reserve_off + reservesize); -+ fdt->off_dt_strings = cpu_to_be32(reserve_off + reservesize -+ + dtsize); -+ fdt->totalsize = cpu_to_be32(reserve_off + reservesize + dtsize + strsize); -+ -+ if (vi->flags & FTF_BOOTCPUID) -+ fdt->boot_cpuid_phys = cpu_to_be32(boot_cpuid_phys); -+ if (vi->flags & FTF_STRTABSIZE) -+ fdt->size_dt_strings = cpu_to_be32(strsize); -+ if (vi->flags & FTF_STRUCTSIZE) -+ fdt->size_dt_struct = cpu_to_be32(dtsize); -+} -+ -+void dt_to_blob(FILE *f, struct boot_info *bi, int version, -+ int boot_cpuid_phys) -+{ -+ struct version_info *vi = NULL; -+ int i; -+ struct data blob = empty_data; -+ struct data reservebuf = empty_data; -+ struct data dtbuf = empty_data; -+ struct data strbuf = empty_data; -+ struct fdt_header fdt; -+ int padlen = 0; -+ -+ for (i = 0; i < ARRAY_SIZE(version_table); i++) { -+ if (version_table[i].version == version) -+ vi = &version_table[i]; -+ } -+ if (!vi) -+ die("Unknown device tree blob version %d\n", version); -+ -+ flatten_tree(bi->dt, &bin_emitter, &dtbuf, &strbuf, vi); -+ bin_emit_cell(&dtbuf, FDT_END); -+ -+ reservebuf = flatten_reserve_list(bi->reservelist, vi); -+ -+ /* Make header */ -+ make_fdt_header(&fdt, vi, reservebuf.len, dtbuf.len, strbuf.len, -+ boot_cpuid_phys); -+ -+ /* -+ * If the user asked for more space than is used, adjust the totalsize. -+ */ -+ if (minsize > 0) { -+ padlen = minsize - be32_to_cpu(fdt.totalsize); -+ if ((padlen < 0) && (quiet < 1)) -+ fprintf(stderr, -+ "Warning: blob size %d >= minimum size %d\n", -+ be32_to_cpu(fdt.totalsize), minsize); -+ } -+ -+ if (padsize > 0) -+ padlen = padsize; -+ -+ if (padlen > 0) { -+ int tsize = be32_to_cpu(fdt.totalsize); -+ tsize += padlen; -+ fdt.totalsize = cpu_to_be32(tsize); -+ } -+ -+ /* -+ * Assemble the blob: start with the header, add with alignment -+ * the reserve buffer, add the reserve map terminating zeroes, -+ * the device tree itself, and finally the strings. -+ */ -+ blob = data_append_data(blob, &fdt, sizeof(fdt)); -+ blob = data_append_align(blob, 8); -+ blob = data_merge(blob, reservebuf); -+ blob = data_append_zeroes(blob, sizeof(struct fdt_reserve_entry)); -+ blob = data_merge(blob, dtbuf); -+ blob = data_merge(blob, strbuf); -+ -+ /* -+ * If the user asked for more space than is used, pad out the blob. -+ */ -+ if (padlen > 0) -+ blob = data_append_zeroes(blob, padlen); -+ -+ fwrite(blob.val, blob.len, 1, f); -+ -+ if (ferror(f)) -+ die("Error writing device tree blob: %s\n", strerror(errno)); -+ -+ /* -+ * data_merge() frees the right-hand element so only the blob -+ * remains to be freed. -+ */ -+ data_free(blob); -+} -+ -+static void dump_stringtable_asm(FILE *f, struct data strbuf) -+{ -+ const char *p; -+ int len; -+ -+ p = strbuf.val; -+ -+ while (p < (strbuf.val + strbuf.len)) { -+ len = strlen(p); -+ fprintf(f, "\t.string \"%s\"\n", p); -+ p += len+1; -+ } -+} -+ -+void dt_to_asm(FILE *f, struct boot_info *bi, int version, int boot_cpuid_phys) -+{ -+ struct version_info *vi = NULL; -+ int i; -+ struct data strbuf = empty_data; -+ struct reserve_info *re; -+ const char *symprefix = "dt"; -+ -+ for (i = 0; i < ARRAY_SIZE(version_table); i++) { -+ if (version_table[i].version == version) -+ vi = &version_table[i]; -+ } -+ if (!vi) -+ die("Unknown device tree blob version %d\n", version); -+ -+ fprintf(f, "/* autogenerated by dtc, do not edit */\n\n"); -+ fprintf(f, "#define FDT_MAGIC 0x%x\n", FDT_MAGIC); -+ fprintf(f, "#define FDT_BEGIN_NODE 0x%x\n", FDT_BEGIN_NODE); -+ fprintf(f, "#define FDT_END_NODE 0x%x\n", FDT_END_NODE); -+ fprintf(f, "#define FDT_PROP 0x%x\n", FDT_PROP); -+ fprintf(f, "#define FDT_END 0x%x\n", FDT_END); -+ fprintf(f, "\n"); -+ -+ emit_label(f, symprefix, "blob_start"); -+ emit_label(f, symprefix, "header"); -+ fprintf(f, "\t.long\tFDT_MAGIC\t\t\t\t/* magic */\n"); -+ fprintf(f, "\t.long\t_%s_blob_abs_end - _%s_blob_start\t/* totalsize */\n", -+ symprefix, symprefix); -+ fprintf(f, "\t.long\t_%s_struct_start - _%s_blob_start\t/* off_dt_struct */\n", -+ symprefix, symprefix); -+ fprintf(f, "\t.long\t_%s_strings_start - _%s_blob_start\t/* off_dt_strings */\n", -+ symprefix, symprefix); -+ fprintf(f, "\t.long\t_%s_reserve_map - _%s_blob_start\t/* off_dt_strings */\n", -+ symprefix, symprefix); -+ fprintf(f, "\t.long\t%d\t\t\t\t\t/* version */\n", vi->version); -+ fprintf(f, "\t.long\t%d\t\t\t\t\t/* last_comp_version */\n", -+ vi->last_comp_version); -+ -+ if (vi->flags & FTF_BOOTCPUID) -+ fprintf(f, "\t.long\t%i\t\t\t\t\t/* boot_cpuid_phys */\n", -+ boot_cpuid_phys); -+ -+ if (vi->flags & FTF_STRTABSIZE) -+ fprintf(f, "\t.long\t_%s_strings_end - _%s_strings_start\t/* size_dt_strings */\n", -+ symprefix, symprefix); -+ -+ if (vi->flags & FTF_STRUCTSIZE) -+ fprintf(f, "\t.long\t_%s_struct_end - _%s_struct_start\t/* size_dt_struct */\n", -+ symprefix, symprefix); -+ -+ /* -+ * Reserve map entries. -+ * Align the reserve map to a doubleword boundary. -+ * Each entry is an (address, size) pair of u64 values. -+ * Always supply a zero-sized temination entry. -+ */ -+ asm_emit_align(f, 8); -+ emit_label(f, symprefix, "reserve_map"); -+ -+ fprintf(f, "/* Memory reserve map from source file */\n"); -+ -+ /* -+ * Use .long on high and low halfs of u64s to avoid .quad -+ * as it appears .quad isn't available in some assemblers. -+ */ -+ for (re = bi->reservelist; re; re = re->next) { -+ if (re->label) { -+ fprintf(f, "\t.globl\t%s\n", re->label); -+ fprintf(f, "%s:\n", re->label); -+ } -+ fprintf(f, "\t.long\t0x%08x, 0x%08x\n", -+ (unsigned int)(re->re.address >> 32), -+ (unsigned int)(re->re.address & 0xffffffff)); -+ fprintf(f, "\t.long\t0x%08x, 0x%08x\n", -+ (unsigned int)(re->re.size >> 32), -+ (unsigned int)(re->re.size & 0xffffffff)); -+ } -+ for (i = 0; i < reservenum; i++) { -+ fprintf(f, "\t.long\t0, 0\n\t.long\t0, 0\n"); -+ } -+ -+ fprintf(f, "\t.long\t0, 0\n\t.long\t0, 0\n"); -+ -+ emit_label(f, symprefix, "struct_start"); -+ flatten_tree(bi->dt, &asm_emitter, f, &strbuf, vi); -+ fprintf(f, "\t.long\tFDT_END\n"); -+ emit_label(f, symprefix, "struct_end"); -+ -+ emit_label(f, symprefix, "strings_start"); -+ dump_stringtable_asm(f, strbuf); -+ emit_label(f, symprefix, "strings_end"); -+ -+ emit_label(f, symprefix, "blob_end"); -+ -+ /* -+ * If the user asked for more space than is used, pad it out. -+ */ -+ if (minsize > 0) { -+ fprintf(f, "\t.space\t%d - (_%s_blob_end - _%s_blob_start), 0\n", -+ minsize, symprefix, symprefix); -+ } -+ if (padsize > 0) { -+ fprintf(f, "\t.space\t%d, 0\n", padsize); -+ } -+ emit_label(f, symprefix, "blob_abs_end"); -+ -+ data_free(strbuf); -+} -+ -+struct inbuf { -+ char *base, *limit, *ptr; -+}; -+ -+static void inbuf_init(struct inbuf *inb, void *base, void *limit) -+{ -+ inb->base = base; -+ inb->limit = limit; -+ inb->ptr = inb->base; -+} -+ -+static void flat_read_chunk(struct inbuf *inb, void *p, int len) -+{ -+ if ((inb->ptr + len) > inb->limit) -+ die("Premature end of data parsing flat device tree\n"); -+ -+ memcpy(p, inb->ptr, len); -+ -+ inb->ptr += len; -+} -+ -+static u32 flat_read_word(struct inbuf *inb) -+{ -+ u32 val; -+ -+ assert(((inb->ptr - inb->base) % sizeof(val)) == 0); -+ -+ flat_read_chunk(inb, &val, sizeof(val)); -+ -+ return be32_to_cpu(val); -+} -+ -+static void flat_realign(struct inbuf *inb, int align) -+{ -+ int off = inb->ptr - inb->base; -+ -+ inb->ptr = inb->base + ALIGN(off, align); -+ if (inb->ptr > inb->limit) -+ die("Premature end of data parsing flat device tree\n"); -+} -+ -+static char *flat_read_string(struct inbuf *inb) -+{ -+ int len = 0; -+ const char *p = inb->ptr; -+ char *str; -+ -+ do { -+ if (p >= inb->limit) -+ die("Premature end of data parsing flat device tree\n"); -+ len++; -+ } while ((*p++) != '\0'); -+ -+ str = strdup(inb->ptr); -+ -+ inb->ptr += len; -+ -+ flat_realign(inb, sizeof(u32)); -+ -+ return str; -+} -+ -+static struct data flat_read_data(struct inbuf *inb, int len) -+{ -+ struct data d = empty_data; -+ -+ if (len == 0) -+ return empty_data; -+ -+ d = data_grow_for(d, len); -+ d.len = len; -+ -+ flat_read_chunk(inb, d.val, len); -+ -+ flat_realign(inb, sizeof(u32)); -+ -+ return d; -+} -+ -+static char *flat_read_stringtable(struct inbuf *inb, int offset) -+{ -+ const char *p; -+ -+ p = inb->base + offset; -+ while (1) { -+ if (p >= inb->limit || p < inb->base) -+ die("String offset %d overruns string table\n", -+ offset); -+ -+ if (*p == '\0') -+ break; -+ -+ p++; -+ } -+ -+ return strdup(inb->base + offset); -+} -+ -+static struct property *flat_read_property(struct inbuf *dtbuf, -+ struct inbuf *strbuf, int flags) -+{ -+ u32 proplen, stroff; -+ char *name; -+ struct data val; -+ -+ proplen = flat_read_word(dtbuf); -+ stroff = flat_read_word(dtbuf); -+ -+ name = flat_read_stringtable(strbuf, stroff); -+ -+ if ((flags & FTF_VARALIGN) && (proplen >= 8)) -+ flat_realign(dtbuf, 8); -+ -+ val = flat_read_data(dtbuf, proplen); -+ -+ return build_property(name, val, NULL); -+} -+ -+ -+static struct reserve_info *flat_read_mem_reserve(struct inbuf *inb) -+{ -+ struct reserve_info *reservelist = NULL; -+ struct reserve_info *new; -+ const char *p; -+ struct fdt_reserve_entry re; -+ -+ /* -+ * Each entry is a pair of u64 (addr, size) values for 4 cell_t's. -+ * List terminates at an entry with size equal to zero. -+ * -+ * First pass, count entries. -+ */ -+ p = inb->ptr; -+ while (1) { -+ flat_read_chunk(inb, &re, sizeof(re)); -+ re.address = be64_to_cpu(re.address); -+ re.size = be64_to_cpu(re.size); -+ if (re.size == 0) -+ break; -+ -+ new = build_reserve_entry(re.address, re.size, NULL); -+ reservelist = add_reserve_entry(reservelist, new); -+ } -+ -+ return reservelist; -+} -+ -+ -+static char *nodename_from_path(const char *ppath, const char *cpath) -+{ -+ const char *lslash; -+ int plen; -+ -+ lslash = strrchr(cpath, '/'); -+ if (! lslash) -+ return NULL; -+ -+ plen = lslash - cpath; -+ -+ if (streq(cpath, "/") && streq(ppath, "")) -+ return ""; -+ -+ if ((plen == 0) && streq(ppath, "/")) -+ return strdup(lslash+1); -+ -+ if (! strneq(ppath, cpath, plen)) -+ return NULL; -+ -+ return strdup(lslash+1); -+} -+ -+static const char PROPCHAR[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789,._+*#?-"; -+static const char UNITCHAR[] = "0123456789abcdef,"; -+ -+static int check_node_name(const char *name) -+{ -+ const char *atpos; -+ int basenamelen; -+ -+ atpos = strrchr(name, '@'); -+ -+ if (atpos) -+ basenamelen = atpos - name; -+ else -+ basenamelen = strlen(name); -+ -+ if (strspn(name, PROPCHAR) < basenamelen) -+ return -1; -+ -+ if (atpos -+ && ((basenamelen + 1 + strspn(atpos+1, UNITCHAR)) < strlen(name))) -+ return -1; -+ -+ return basenamelen; -+} -+ -+static struct node *unflatten_tree(struct inbuf *dtbuf, -+ struct inbuf *strbuf, -+ const char *parent_path, int flags) -+{ -+ struct node *node; -+ u32 val; -+ -+ node = build_node(NULL, NULL); -+ -+ if (flags & FTF_FULLPATH) { -+ node->fullpath = flat_read_string(dtbuf); -+ node->name = nodename_from_path(parent_path, node->fullpath); -+ -+ if (! node->name) -+ die("Path \"%s\" is not valid as a child of \"%s\"\n", -+ node->fullpath, parent_path); -+ } else { -+ node->name = flat_read_string(dtbuf); -+ node->fullpath = join_path(parent_path, node->name); -+ } -+ -+ node->basenamelen = check_node_name(node->name); -+ if (node->basenamelen < 0) { -+ fprintf(stderr, "Warning \"%s\" has incorrect format\n", node->name); -+ } -+ -+ do { -+ struct property *prop; -+ struct node *child; -+ -+ val = flat_read_word(dtbuf); -+ switch (val) { -+ case FDT_PROP: -+ if (node->children) -+ fprintf(stderr, "Warning: Flat tree input has " -+ "subnodes preceding a property.\n"); -+ prop = flat_read_property(dtbuf, strbuf, flags); -+ add_property(node, prop); -+ break; -+ -+ case FDT_BEGIN_NODE: -+ child = unflatten_tree(dtbuf,strbuf, node->fullpath, -+ flags); -+ add_child(node, child); -+ break; -+ -+ case FDT_END_NODE: -+ break; -+ -+ case FDT_END: -+ die("Premature FDT_END in device tree blob\n"); -+ break; -+ -+ case FDT_NOP: -+ if (!(flags & FTF_NOPS)) -+ fprintf(stderr, "Warning: NOP tag found in flat tree" -+ " version <16\n"); -+ -+ /* Ignore */ -+ break; -+ -+ default: -+ die("Invalid opcode word %08x in device tree blob\n", -+ val); -+ } -+ } while (val != FDT_END_NODE); -+ -+ return node; -+} -+ -+ -+struct boot_info *dt_from_blob(FILE *f) -+{ -+ u32 magic, totalsize, version, size_str, size_dt; -+ u32 off_dt, off_str, off_mem_rsvmap; -+ int rc; -+ char *blob; -+ struct fdt_header *fdt; -+ char *p; -+ struct inbuf dtbuf, strbuf; -+ struct inbuf memresvbuf; -+ int sizeleft; -+ struct reserve_info *reservelist; -+ struct node *tree; -+ u32 val; -+ int flags = 0; -+ -+ rc = fread(&magic, sizeof(magic), 1, f); -+ if (ferror(f)) -+ die("Error reading DT blob magic number: %s\n", -+ strerror(errno)); -+ if (rc < 1) { -+ if (feof(f)) -+ die("EOF reading DT blob magic number\n"); -+ else -+ die("Mysterious short read reading magic number\n"); -+ } -+ -+ magic = be32_to_cpu(magic); -+ if (magic != FDT_MAGIC) -+ die("Blob has incorrect magic number\n"); -+ -+ rc = fread(&totalsize, sizeof(totalsize), 1, f); -+ if (ferror(f)) -+ die("Error reading DT blob size: %s\n", strerror(errno)); -+ if (rc < 1) { -+ if (feof(f)) -+ die("EOF reading DT blob size\n"); -+ else -+ die("Mysterious short read reading blob size\n"); -+ } -+ -+ totalsize = be32_to_cpu(totalsize); -+ if (totalsize < FDT_V1_SIZE) -+ die("DT blob size (%d) is too small\n", totalsize); -+ -+ blob = xmalloc(totalsize); -+ -+ fdt = (struct fdt_header *)blob; -+ fdt->magic = cpu_to_be32(magic); -+ fdt->totalsize = cpu_to_be32(totalsize); -+ -+ sizeleft = totalsize - sizeof(magic) - sizeof(totalsize); -+ p = blob + sizeof(magic) + sizeof(totalsize); -+ -+ while (sizeleft) { -+ if (feof(f)) -+ die("EOF before reading %d bytes of DT blob\n", -+ totalsize); -+ -+ rc = fread(p, 1, sizeleft, f); -+ if (ferror(f)) -+ die("Error reading DT blob: %s\n", -+ strerror(errno)); -+ -+ sizeleft -= rc; -+ p += rc; -+ } -+ -+ off_dt = be32_to_cpu(fdt->off_dt_struct); -+ off_str = be32_to_cpu(fdt->off_dt_strings); -+ off_mem_rsvmap = be32_to_cpu(fdt->off_mem_rsvmap); -+ version = be32_to_cpu(fdt->version); -+ -+ fprintf(stderr, "\tmagic:\t\t\t0x%x\n", magic); -+ fprintf(stderr, "\ttotalsize:\t\t%d\n", totalsize); -+ fprintf(stderr, "\toff_dt_struct:\t\t0x%x\n", off_dt); -+ fprintf(stderr, "\toff_dt_strings:\t\t0x%x\n", off_str); -+ fprintf(stderr, "\toff_mem_rsvmap:\t\t0x%x\n", off_mem_rsvmap); -+ fprintf(stderr, "\tversion:\t\t0x%x\n", version ); -+ fprintf(stderr, "\tlast_comp_version:\t0x%x\n", -+ be32_to_cpu(fdt->last_comp_version)); -+ -+ if (off_mem_rsvmap >= totalsize) -+ die("Mem Reserve structure offset exceeds total size\n"); -+ -+ if (off_dt >= totalsize) -+ die("DT structure offset exceeds total size\n"); -+ -+ if (off_str > totalsize) -+ die("String table offset exceeds total size\n"); -+ -+ if (version >= 2) -+ fprintf(stderr, "\tboot_cpuid_phys:\t0x%x\n", -+ be32_to_cpu(fdt->boot_cpuid_phys)); -+ -+ size_str = -1; -+ if (version >= 3) { -+ size_str = be32_to_cpu(fdt->size_dt_strings); -+ fprintf(stderr, "\tsize_dt_strings:\t%d\n", size_str); -+ if (off_str+size_str > totalsize) -+ die("String table extends past total size\n"); -+ } -+ -+ if (version >= 17) { -+ size_dt = be32_to_cpu(fdt->size_dt_struct); -+ fprintf(stderr, "\tsize_dt_struct:\t\t%d\n", size_dt); -+ if (off_dt+size_dt > totalsize) -+ die("Structure block extends past total size\n"); -+ } -+ -+ if (version < 16) { -+ flags |= FTF_FULLPATH | FTF_NAMEPROPS | FTF_VARALIGN; -+ } else { -+ flags |= FTF_NOPS; -+ } -+ -+ inbuf_init(&memresvbuf, -+ blob + off_mem_rsvmap, blob + totalsize); -+ inbuf_init(&dtbuf, blob + off_dt, blob + totalsize); -+ if (size_str >= 0) -+ inbuf_init(&strbuf, blob + off_str, blob + off_str + size_str); -+ else -+ inbuf_init(&strbuf, blob + off_str, blob + totalsize); -+ -+ reservelist = flat_read_mem_reserve(&memresvbuf); -+ -+ val = flat_read_word(&dtbuf); -+ -+ if (val != FDT_BEGIN_NODE) -+ die("Device tree blob doesn't begin with FDT_BEGIN_NODE (begins with 0x%08x)\n", val); -+ -+ tree = unflatten_tree(&dtbuf, &strbuf, "", flags); -+ -+ val = flat_read_word(&dtbuf); -+ if (val != FDT_END) -+ die("Device tree blob doesn't end with FDT_END\n"); -+ -+ free(blob); -+ -+ return build_boot_info(reservelist, tree); -+} ---- /dev/null -+++ b/arch/powerpc/boot/dtc-src/fstree.c -@@ -0,0 +1,94 @@ -+/* -+ * (C) Copyright David Gibson , IBM Corporation. 2005. -+ * -+ * -+ * 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 "dtc.h" -+ -+#include -+#include -+ -+static struct node *read_fstree(const char *dirname) -+{ -+ DIR *d; -+ struct dirent *de; -+ struct stat st; -+ struct node *tree; -+ -+ d = opendir(dirname); -+ if (! d) -+ die("opendir(): %s\n", strerror(errno)); -+ -+ tree = build_node(NULL, NULL); -+ -+ while ((de = readdir(d)) != NULL) { -+ char *tmpnam; -+ -+ if (streq(de->d_name, ".") -+ || streq(de->d_name, "..")) -+ continue; -+ -+ tmpnam = join_path(dirname, de->d_name); -+ -+ if (lstat(tmpnam, &st) < 0) -+ die("stat(%s): %s\n", tmpnam, strerror(errno)); -+ -+ if (S_ISREG(st.st_mode)) { -+ struct property *prop; -+ FILE *pfile; -+ -+ pfile = fopen(tmpnam, "r"); -+ if (! pfile) { -+ fprintf(stderr, -+ "WARNING: Cannot open %s: %s\n", -+ tmpnam, strerror(errno)); -+ } else { -+ prop = build_property(strdup(de->d_name), -+ data_copy_file(pfile, -+ st.st_size), -+ NULL); -+ add_property(tree, prop); -+ fclose(pfile); -+ } -+ } else if (S_ISDIR(st.st_mode)) { -+ struct node *newchild; -+ -+ newchild = read_fstree(tmpnam); -+ newchild = name_node(newchild, strdup(de->d_name), -+ NULL); -+ add_child(tree, newchild); -+ } -+ -+ free(tmpnam); -+ } -+ -+ return tree; -+} -+ -+struct boot_info *dt_from_fs(const char *dirname) -+{ -+ struct node *tree; -+ -+ tree = read_fstree(dirname); -+ tree = name_node(tree, "", NULL); -+ -+ fill_fullpaths(tree, ""); -+ -+ return build_boot_info(NULL, tree); -+} -+ ---- /dev/null -+++ b/arch/powerpc/boot/dtc-src/livetree.c -@@ -0,0 +1,305 @@ -+/* -+ * (C) Copyright David Gibson , IBM Corporation. 2005. -+ * -+ * -+ * 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 "dtc.h" -+ -+/* -+ * Tree building functions -+ */ -+ -+struct property *build_property(char *name, struct data val, char *label) -+{ -+ struct property *new = xmalloc(sizeof(*new)); -+ -+ new->name = name; -+ new->val = val; -+ -+ new->next = NULL; -+ -+ new->label = label; -+ -+ return new; -+} -+ -+struct property *chain_property(struct property *first, struct property *list) -+{ -+ assert(first->next == NULL); -+ -+ first->next = list; -+ return first; -+} -+ -+struct property *reverse_properties(struct property *first) -+{ -+ struct property *p = first; -+ struct property *head = NULL; -+ struct property *next; -+ -+ while (p) { -+ next = p->next; -+ p->next = head; -+ head = p; -+ p = next; -+ } -+ return head; -+} -+ -+struct node *build_node(struct property *proplist, struct node *children) -+{ -+ struct node *new = xmalloc(sizeof(*new)); -+ struct node *child; -+ -+ memset(new, 0, sizeof(*new)); -+ -+ new->proplist = reverse_properties(proplist); -+ new->children = children; -+ -+ for_each_child(new, child) { -+ child->parent = new; -+ } -+ -+ return new; -+} -+ -+struct node *name_node(struct node *node, char *name, char * label) -+{ -+ assert(node->name == NULL); -+ -+ node->name = name; -+ -+ node->label = label; -+ -+ return node; -+} -+ -+struct node *chain_node(struct node *first, struct node *list) -+{ -+ assert(first->next_sibling == NULL); -+ -+ first->next_sibling = list; -+ return first; -+} -+ -+void add_property(struct node *node, struct property *prop) -+{ -+ struct property **p; -+ -+ prop->next = NULL; -+ -+ p = &node->proplist; -+ while (*p) -+ p = &((*p)->next); -+ -+ *p = prop; -+} -+ -+void add_child(struct node *parent, struct node *child) -+{ -+ struct node **p; -+ -+ child->next_sibling = NULL; -+ -+ p = &parent->children; -+ while (*p) -+ p = &((*p)->next_sibling); -+ -+ *p = child; -+} -+ -+struct reserve_info *build_reserve_entry(u64 address, u64 size, char *label) -+{ -+ struct reserve_info *new = xmalloc(sizeof(*new)); -+ -+ new->re.address = address; -+ new->re.size = size; -+ -+ new->next = NULL; -+ -+ new->label = label; -+ -+ return new; -+} -+ -+struct reserve_info *chain_reserve_entry(struct reserve_info *first, -+ struct reserve_info *list) -+{ -+ assert(first->next == NULL); -+ -+ first->next = list; -+ return first; -+} -+ -+struct reserve_info *add_reserve_entry(struct reserve_info *list, -+ struct reserve_info *new) -+{ -+ struct reserve_info *last; -+ -+ new->next = NULL; -+ -+ if (! list) -+ return new; -+ -+ for (last = list; last->next; last = last->next) -+ ; -+ -+ last->next = new; -+ -+ return list; -+} -+ -+struct boot_info *build_boot_info(struct reserve_info *reservelist, -+ struct node *tree) -+{ -+ struct boot_info *bi; -+ -+ bi = xmalloc(sizeof(*bi)); -+ bi->reservelist = reservelist; -+ bi->dt = tree; -+ -+ return bi; -+} -+ -+/* -+ * Tree accessor functions -+ */ -+ -+const char *get_unitname(struct node *node) -+{ -+ if (node->name[node->basenamelen] == '\0') -+ return ""; -+ else -+ return node->name + node->basenamelen + 1; -+} -+ -+struct property *get_property(struct node *node, const char *propname) -+{ -+ struct property *prop; -+ -+ for_each_property(node, prop) -+ if (streq(prop->name, propname)) -+ return prop; -+ -+ return NULL; -+} -+ -+cell_t propval_cell(struct property *prop) -+{ -+ assert(prop->val.len == sizeof(cell_t)); -+ return be32_to_cpu(*((cell_t *)prop->val.val)); -+} -+ -+struct node *get_subnode(struct node *node, const char *nodename) -+{ -+ struct node *child; -+ -+ for_each_child(node, child) -+ if (streq(child->name, nodename)) -+ return child; -+ -+ return NULL; -+} -+ -+struct node *get_node_by_path(struct node *tree, const char *path) -+{ -+ const char *p; -+ struct node *child; -+ -+ if (!path || ! (*path)) -+ return tree; -+ -+ while (path[0] == '/') -+ path++; -+ -+ p = strchr(path, '/'); -+ -+ for_each_child(tree, child) { -+ if (p && strneq(path, child->name, p-path)) -+ return get_node_by_path(child, p+1); -+ else if (!p && streq(path, child->name)) -+ return child; -+ } -+ -+ return NULL; -+} -+ -+struct node *get_node_by_label(struct node *tree, const char *label) -+{ -+ struct node *child, *node; -+ -+ assert(label && (strlen(label) > 0)); -+ -+ if (tree->label && streq(tree->label, label)) -+ return tree; -+ -+ for_each_child(tree, child) { -+ node = get_node_by_label(child, label); -+ if (node) -+ return node; -+ } -+ -+ return NULL; -+} -+ -+struct node *get_node_by_phandle(struct node *tree, cell_t phandle) -+{ -+ struct node *child, *node; -+ -+ assert((phandle != 0) && (phandle != -1)); -+ -+ if (tree->phandle == phandle) -+ return tree; -+ -+ for_each_child(tree, child) { -+ node = get_node_by_phandle(child, phandle); -+ if (node) -+ return node; -+ } -+ -+ return NULL; -+} -+ -+struct node *get_node_by_ref(struct node *tree, const char *ref) -+{ -+ if (ref[0] == '/') -+ return get_node_by_path(tree, ref); -+ else -+ return get_node_by_label(tree, ref); -+} -+ -+cell_t get_node_phandle(struct node *root, struct node *node) -+{ -+ static cell_t phandle = 1; /* FIXME: ick, static local */ -+ -+ if ((node->phandle != 0) && (node->phandle != -1)) -+ return node->phandle; -+ -+ assert(! get_property(node, "linux,phandle")); -+ -+ while (get_node_by_phandle(root, phandle)) -+ phandle++; -+ -+ node->phandle = phandle; -+ add_property(node, -+ build_property("linux,phandle", -+ data_append_cell(empty_data, phandle), -+ NULL)); -+ -+ return node->phandle; -+} ---- /dev/null -+++ b/arch/powerpc/boot/dtc-src/srcpos.c -@@ -0,0 +1,105 @@ -+/* -+ * Copyright 2007 Jon Loeliger, Freescale Semiconductor, Inc. -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation; either version 2 of the -+ * License, or (at your option) any later version. -+ * -+ * This 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 "dtc.h" -+#include "srcpos.h" -+ -+ -+/* -+ * Record the complete unique set of opened file names. -+ * Primarily used to cache source position file names. -+ */ -+#define MAX_N_FILE_NAMES (100) -+ -+const char *file_names[MAX_N_FILE_NAMES]; -+static int n_file_names = 0; -+ -+/* -+ * Like yylineno, this is the current open file pos. -+ */ -+ -+int srcpos_filenum = -1; -+ -+ -+ -+FILE *dtc_open_file(const char *fname) -+{ -+ FILE *f; -+ -+ if (lookup_file_name(fname, 1) < 0) -+ die("Too many files opened\n"); -+ -+ if (streq(fname, "-")) -+ f = stdin; -+ else -+ f = fopen(fname, "r"); -+ -+ if (! f) -+ die("Couldn't open \"%s\": %s\n", fname, strerror(errno)); -+ -+ return f; -+} -+ -+ -+ -+/* -+ * Locate and optionally add filename fname in the file_names[] array. -+ * -+ * If the filename is currently not in the array and the boolean -+ * add_it is non-zero, an attempt to add the filename will be made. -+ * -+ * Returns; -+ * Index [0..MAX_N_FILE_NAMES) where the filename is kept -+ * -1 if the name can not be recorded -+ */ -+ -+int lookup_file_name(const char *fname, int add_it) -+{ -+ int i; -+ -+ for (i = 0; i < n_file_names; i++) { -+ if (strcmp(file_names[i], fname) == 0) -+ return i; -+ } -+ -+ if (add_it) { -+ if (n_file_names < MAX_N_FILE_NAMES) { -+ file_names[n_file_names] = strdup(fname); -+ return n_file_names++; -+ } -+ } -+ -+ return -1; -+} -+ -+ -+const char *srcpos_filename_for_num(int filenum) -+{ -+ if (0 <= filenum && filenum < n_file_names) { -+ return file_names[filenum]; -+ } -+ -+ return 0; -+} -+ -+ -+const char *srcpos_get_filename(void) -+{ -+ return srcpos_filename_for_num(srcpos_filenum); -+} ---- /dev/null -+++ b/arch/powerpc/boot/dtc-src/srcpos.h -@@ -0,0 +1,75 @@ -+/* -+ * Copyright 2007 Jon Loeliger, Freescale Semiconductor, Inc. -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation; either version 2 of the -+ * License, or (at your option) any later version. -+ * -+ * This 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 -+ */ -+ -+/* -+ * Augment the standard YYLTYPE with a filenum index into an -+ * array of all opened filenames. -+ */ -+ -+#if ! defined(YYLTYPE) && ! defined(YYLTYPE_IS_DECLARED) -+typedef struct YYLTYPE { -+ int first_line; -+ int first_column; -+ int last_line; -+ int last_column; -+ int filenum; -+} YYLTYPE; -+ -+#define YYLTYPE_IS_DECLARED 1 -+#define YYLTYPE_IS_TRIVIAL 1 -+#endif -+ -+/* Cater to old parser templates. */ -+#ifndef YYID -+#define YYID(n) (n) -+#endif -+ -+#define YYLLOC_DEFAULT(Current, Rhs, N) \ -+ do \ -+ if (YYID (N)) \ -+ { \ -+ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ -+ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ -+ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ -+ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ -+ (Current).filenum = YYRHSLOC (Rhs, N).filenum; \ -+ } \ -+ else \ -+ { \ -+ (Current).first_line = (Current).last_line = \ -+ YYRHSLOC (Rhs, 0).last_line; \ -+ (Current).first_column = (Current).last_column = \ -+ YYRHSLOC (Rhs, 0).last_column; \ -+ (Current).filenum = YYRHSLOC (Rhs, 0).filenum; \ -+ } \ -+ while (YYID (0)) -+ -+ -+ -+extern void yyerror(char const *); -+ -+extern int srcpos_filenum; -+ -+extern int push_input_file(const char *filename); -+extern int pop_input_file(void); -+ -+extern FILE *dtc_open_file(const char *fname); -+extern int lookup_file_name(const char *fname, int add_it); -+extern const char *srcpos_filename_for_num(int filenum); -+const char *srcpos_get_filename(void); ---- /dev/null -+++ b/arch/powerpc/boot/dtc-src/treesource.c -@@ -0,0 +1,275 @@ -+/* -+ * (C) Copyright David Gibson , IBM Corporation. 2005. -+ * -+ * -+ * 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 "dtc.h" -+#include "srcpos.h" -+ -+extern FILE *yyin; -+extern int yyparse(void); -+extern void yyerror(char const *); -+ -+struct boot_info *the_boot_info; -+ -+struct boot_info *dt_from_source(const char *fname) -+{ -+ the_boot_info = NULL; -+ -+ push_input_file(fname); -+ -+ if (yyparse() != 0) -+ return NULL; -+ -+ fill_fullpaths(the_boot_info->dt, ""); -+ -+ return the_boot_info; -+} -+ -+static void write_prefix(FILE *f, int level) -+{ -+ int i; -+ -+ for (i = 0; i < level; i++) -+ fputc('\t', f); -+} -+ -+int isstring(char c) -+{ -+ return (isprint(c) -+ || (c == '\0') -+ || strchr("\a\b\t\n\v\f\r", c)); -+} -+ -+static void write_propval_string(FILE *f, struct data val) -+{ -+ const char *str = val.val; -+ int i; -+ int newchunk = 1; -+ struct marker *m = val.markers; -+ -+ assert(str[val.len-1] == '\0'); -+ -+ for (i = 0; i < (val.len-1); i++) { -+ char c = str[i]; -+ -+ if (newchunk) { -+ while (m && (m->offset <= i)) { -+ if (m->type == LABEL) { -+ assert(m->offset == i); -+ fprintf(f, "%s: ", m->ref); -+ } -+ m = m->next; -+ } -+ fprintf(f, "\""); -+ newchunk = 0; -+ } -+ -+ switch (c) { -+ case '\a': -+ fprintf(f, "\\a"); -+ break; -+ case '\b': -+ fprintf(f, "\\b"); -+ break; -+ case '\t': -+ fprintf(f, "\\t"); -+ break; -+ case '\n': -+ fprintf(f, "\\n"); -+ break; -+ case '\v': -+ fprintf(f, "\\v"); -+ break; -+ case '\f': -+ fprintf(f, "\\f"); -+ break; -+ case '\r': -+ fprintf(f, "\\r"); -+ break; -+ case '\\': -+ fprintf(f, "\\\\"); -+ break; -+ case '\"': -+ fprintf(f, "\\\""); -+ break; -+ case '\0': -+ fprintf(f, "\", "); -+ newchunk = 1; -+ break; -+ default: -+ if (isprint(c)) -+ fprintf(f, "%c", c); -+ else -+ fprintf(f, "\\x%02hhx", c); -+ } -+ } -+ fprintf(f, "\""); -+ -+ /* Wrap up any labels at the end of the value */ -+ for_each_marker_of_type(m, LABEL) { -+ assert (m->offset == val.len); -+ fprintf(f, " %s:", m->ref); -+ } -+} -+ -+static void write_propval_cells(FILE *f, struct data val) -+{ -+ void *propend = val.val + val.len; -+ cell_t *cp = (cell_t *)val.val; -+ struct marker *m = val.markers; -+ -+ fprintf(f, "<"); -+ for (;;) { -+ while (m && (m->offset <= ((char *)cp - val.val))) { -+ if (m->type == LABEL) { -+ assert(m->offset == ((char *)cp - val.val)); -+ fprintf(f, "%s: ", m->ref); -+ } -+ m = m->next; -+ } -+ -+ fprintf(f, "0x%x", be32_to_cpu(*cp++)); -+ if ((void *)cp >= propend) -+ break; -+ fprintf(f, " "); -+ } -+ -+ /* Wrap up any labels at the end of the value */ -+ for_each_marker_of_type(m, LABEL) { -+ assert (m->offset == val.len); -+ fprintf(f, " %s:", m->ref); -+ } -+ fprintf(f, ">"); -+} -+ -+static void write_propval_bytes(FILE *f, struct data val) -+{ -+ void *propend = val.val + val.len; -+ const char *bp = val.val; -+ struct marker *m = val.markers; -+ -+ fprintf(f, "["); -+ for (;;) { -+ while (m && (m->offset == (bp-val.val))) { -+ if (m->type == LABEL) -+ fprintf(f, "%s: ", m->ref); -+ m = m->next; -+ } -+ -+ fprintf(f, "%02hhx", *bp++); -+ if ((void *)bp >= propend) -+ break; -+ fprintf(f, " "); -+ } -+ -+ /* Wrap up any labels at the end of the value */ -+ for_each_marker_of_type(m, LABEL) { -+ assert (m->offset == val.len); -+ fprintf(f, " %s:", m->ref); -+ } -+ fprintf(f, "]"); -+} -+ -+static void write_propval(FILE *f, struct property *prop) -+{ -+ int len = prop->val.len; -+ const char *p = prop->val.val; -+ struct marker *m = prop->val.markers; -+ int nnotstring = 0, nnul = 0; -+ int nnotstringlbl = 0, nnotcelllbl = 0; -+ int i; -+ -+ if (len == 0) { -+ fprintf(f, ";\n"); -+ return; -+ } -+ -+ for (i = 0; i < len; i++) { -+ if (! isstring(p[i])) -+ nnotstring++; -+ if (p[i] == '\0') -+ nnul++; -+ } -+ -+ for_each_marker_of_type(m, LABEL) { -+ if ((m->offset > 0) && (prop->val.val[m->offset - 1] != '\0')) -+ nnotstringlbl++; -+ if ((m->offset % sizeof(cell_t)) != 0) -+ nnotcelllbl++; -+ } -+ -+ fprintf(f, " = "); -+ if ((p[len-1] == '\0') && (nnotstring == 0) && (nnul < (len-nnul)) -+ && (nnotstringlbl == 0)) { -+ write_propval_string(f, prop->val); -+ } else if (((len % sizeof(cell_t)) == 0) && (nnotcelllbl == 0)) { -+ write_propval_cells(f, prop->val); -+ } else { -+ write_propval_bytes(f, prop->val); -+ } -+ -+ fprintf(f, ";\n"); -+} -+ -+static void write_tree_source_node(FILE *f, struct node *tree, int level) -+{ -+ struct property *prop; -+ struct node *child; -+ -+ write_prefix(f, level); -+ if (tree->label) -+ fprintf(f, "%s: ", tree->label); -+ if (tree->name && (*tree->name)) -+ fprintf(f, "%s {\n", tree->name); -+ else -+ fprintf(f, "/ {\n"); -+ -+ for_each_property(tree, prop) { -+ write_prefix(f, level+1); -+ if (prop->label) -+ fprintf(f, "%s: ", prop->label); -+ fprintf(f, "%s", prop->name); -+ write_propval(f, prop); -+ } -+ for_each_child(tree, child) { -+ fprintf(f, "\n"); -+ write_tree_source_node(f, child, level+1); -+ } -+ write_prefix(f, level); -+ fprintf(f, "};\n"); -+} -+ -+ -+void dt_to_source(FILE *f, struct boot_info *bi) -+{ -+ struct reserve_info *re; -+ -+ fprintf(f, "/dts-v1/;\n\n"); -+ -+ for (re = bi->reservelist; re; re = re->next) { -+ if (re->label) -+ fprintf(f, "%s: ", re->label); -+ fprintf(f, "/memreserve/\t0x%016llx 0x%016llx;\n", -+ (unsigned long long)re->re.address, -+ (unsigned long long)re->re.size); -+ } -+ -+ write_tree_source_node(f, bi->dt, 0); -+} -+ ---- /dev/null -+++ b/arch/powerpc/boot/dtc-src/version_gen.h -@@ -0,0 +1 @@ -+#define DTC_VERSION "DTC 1.0.0-gd6f9b62f" ---- /dev/null -+++ b/arch/powerpc/boot/dts/adder875-redboot.dts -@@ -0,0 +1,184 @@ -+/* -+ * Device Tree Source for MPC885 ADS running RedBoot -+ * -+ * Copyright 2006 MontaVista Software, Inc. -+ * Copyright 2007 Freescale Semiconductor, Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. -+ */ -+ -+/dts-v1/; -+/ { -+ model = "Analogue & Micro Adder MPC875"; -+ compatible = "analogue-and-micro,adder875"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ aliases { -+ console = &console; -+ ethernet0 = ð0; -+ ethernet1 = ð1; -+ }; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ PowerPC,875@0 { -+ device_type = "cpu"; -+ reg = <0>; -+ d-cache-line-size = <16>; -+ i-cache-line-size = <16>; -+ d-cache-size = <8192>; -+ i-cache-size = <8192>; -+ timebase-frequency = <0>; -+ bus-frequency = <0>; -+ clock-frequency = <0>; -+ interrupts = <15 2>; // decrementer interrupt -+ interrupt-parent = <&PIC>; -+ }; -+ }; -+ -+ memory { -+ device_type = "memory"; -+ reg = <0 0x01000000>; -+ }; -+ -+ localbus@fa200100 { -+ compatible = "fsl,mpc885-localbus", "fsl,pq1-localbus", -+ "simple-bus"; -+ #address-cells = <2>; -+ #size-cells = <1>; -+ reg = <0xfa200100 0x40>; -+ -+ ranges = < -+ 0 0 0xfe000000 0x00800000 -+ 2 0 0xfa100000 0x00008000 -+ >; -+ -+ flash@0,0 { -+ compatible = "cfi-flash"; -+ reg = <0 0 0x800000>; -+ bank-width = <2>; -+ device-width = <2>; -+ }; -+ }; -+ -+ soc@fa200000 { -+ compatible = "fsl,mpc875-immr", "fsl,pq1-soc", "simple-bus"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges = <0 0xfa200000 0x00004000>; -+ -+ // Temporary until code stops depending on it. -+ device_type = "soc"; -+ -+ // Temporary until get_immrbase() is fixed. -+ reg = <0xfa200000 0x4000>; -+ -+ mdio@e00 { -+ compatible = "fsl,mpc875-fec-mdio", "fsl,pq1-fec-mdio"; -+ reg = <0xe00 0x188>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ PHY0: ethernet-phy@0 { -+ reg = <0>; -+ device_type = "ethernet-phy"; -+ }; -+ -+ PHY1: ethernet-phy@1 { -+ reg = <1>; -+ device_type = "ethernet-phy"; -+ }; -+ }; -+ -+ eth0: ethernet@e00 { -+ device_type = "network"; -+ compatible = "fsl,mpc875-fec-enet", -+ "fsl,pq1-fec-enet"; -+ reg = <0xe00 0x188>; -+ local-mac-address = [ 00 00 00 00 00 00 ]; -+ interrupts = <3 1>; -+ interrupt-parent = <&PIC>; -+ phy-handle = <&PHY0>; -+ linux,network-index = <0>; -+ }; -+ -+ eth1: ethernet@1e00 { -+ device_type = "network"; -+ compatible = "fsl,mpc875-fec-enet", -+ "fsl,pq1-fec-enet"; -+ reg = <0x1e00 0x188>; -+ local-mac-address = [ 00 00 00 00 00 00 ]; -+ interrupts = <7 1>; -+ interrupt-parent = <&PIC>; -+ phy-handle = <&PHY1>; -+ linux,network-index = <1>; -+ }; -+ -+ PIC: interrupt-controller@0 { -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ reg = <0 0x24>; -+ compatible = "fsl,mpc875-pic", "fsl,pq1-pic"; -+ }; -+ -+ cpm@9c0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "fsl,mpc875-cpm", "fsl,cpm1", "simple-bus"; -+ interrupts = <0>; // cpm error interrupt -+ interrupt-parent = <&CPM_PIC>; -+ reg = <0x9c0 0x40>; -+ ranges; -+ -+ muram { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges = <0 0x2000 0x2000>; -+ -+ data@0 { -+ compatible = "fsl,cpm-muram-data"; -+ reg = <0 0x1c00>; -+ }; -+ }; -+ -+ brg@9f0 { -+ compatible = "fsl,mpc875-brg", -+ "fsl,cpm1-brg", -+ "fsl,cpm-brg"; -+ reg = <0x9f0 0x10>; -+ }; -+ -+ CPM_PIC: interrupt-controller@930 { -+ interrupt-controller; -+ #interrupt-cells = <1>; -+ interrupts = <5 2 0 2>; -+ interrupt-parent = <&PIC>; -+ reg = <0x930 0x20>; -+ compatible = "fsl,mpc875-cpm-pic", -+ "fsl,cpm1-pic"; -+ }; -+ -+ console: serial@a80 { -+ device_type = "serial"; -+ compatible = "fsl,mpc875-smc-uart", -+ "fsl,cpm1-smc-uart"; -+ reg = <0xa80 0x10 0x3e80 0x40>; -+ interrupts = <4>; -+ interrupt-parent = <&CPM_PIC>; -+ fsl,cpm-brg = <1>; -+ fsl,cpm-command = <0x0090>; -+ current-speed = <115200>; -+ }; -+ }; -+ }; -+ -+ chosen { -+ linux,stdout-path = &console; -+ }; -+}; ---- /dev/null -+++ b/arch/powerpc/boot/dts/adder875-uboot.dts -@@ -0,0 +1,183 @@ -+/* -+ * Device Tree Source for MPC885 ADS running U-Boot -+ * -+ * Copyright 2006 MontaVista Software, Inc. -+ * Copyright 2007 Freescale Semiconductor, Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. -+ */ -+ -+/dts-v1/; -+/ { -+ model = "Analogue & Micro Adder MPC875"; -+ compatible = "analogue-and-micro,adder875"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ aliases { -+ console = &console; -+ ethernet0 = ð0; -+ ethernet1 = ð1; -+ }; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ PowerPC,875@0 { -+ device_type = "cpu"; -+ reg = <0>; -+ d-cache-line-size = <16>; -+ i-cache-line-size = <16>; -+ d-cache-size = <8192>; -+ i-cache-size = <8192>; -+ timebase-frequency = <0>; -+ bus-frequency = <0>; -+ clock-frequency = <0>; -+ interrupts = <15 2>; // decrementer interrupt -+ interrupt-parent = <&PIC>; -+ }; -+ }; -+ -+ memory { -+ device_type = "memory"; -+ reg = <0 0x01000000>; -+ }; -+ -+ localbus@ff000100 { -+ compatible = "fsl,mpc885-localbus", "fsl,pq1-localbus", -+ "simple-bus"; -+ #address-cells = <2>; -+ #size-cells = <1>; -+ reg = <0xff000100 0x40>; -+ -+ ranges = < -+ 0 0 0xfe000000 0x01000000 -+ >; -+ -+ flash@0,0 { -+ compatible = "cfi-flash"; -+ reg = <0 0 0x800000>; -+ bank-width = <2>; -+ device-width = <2>; -+ }; -+ }; -+ -+ soc@ff000000 { -+ compatible = "fsl,mpc875-immr", "fsl,pq1-soc", "simple-bus"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges = <0 0xff000000 0x00004000>; -+ -+ // Temporary until code stops depending on it. -+ device_type = "soc"; -+ -+ // Temporary until get_immrbase() is fixed. -+ reg = <0xff000000 0x4000>; -+ -+ mdio@e00 { -+ compatible = "fsl,mpc875-fec-mdio", "fsl,pq1-fec-mdio"; -+ reg = <0xe00 0x188>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ PHY0: ethernet-phy@0 { -+ reg = <0>; -+ device_type = "ethernet-phy"; -+ }; -+ -+ PHY1: ethernet-phy@1 { -+ reg = <1>; -+ device_type = "ethernet-phy"; -+ }; -+ }; -+ -+ eth0: ethernet@e00 { -+ device_type = "network"; -+ compatible = "fsl,mpc875-fec-enet", -+ "fsl,pq1-fec-enet"; -+ reg = <0xe00 0x188>; -+ local-mac-address = [ 00 00 00 00 00 00 ]; -+ interrupts = <3 1>; -+ interrupt-parent = <&PIC>; -+ phy-handle = <&PHY0>; -+ linux,network-index = <0>; -+ }; -+ -+ eth1: ethernet@1e00 { -+ device_type = "network"; -+ compatible = "fsl,mpc875-fec-enet", -+ "fsl,pq1-fec-enet"; -+ reg = <0x1e00 0x188>; -+ local-mac-address = [ 00 00 00 00 00 00 ]; -+ interrupts = <7 1>; -+ interrupt-parent = <&PIC>; -+ phy-handle = <&PHY1>; -+ linux,network-index = <1>; -+ }; -+ -+ PIC: interrupt-controller@0 { -+ interrupt-controller; -+ #interrupt-cells = <2>; -+ reg = <0 0x24>; -+ compatible = "fsl,mpc875-pic", "fsl,pq1-pic"; -+ }; -+ -+ cpm@9c0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "fsl,mpc875-cpm", "fsl,cpm1", "simple-bus"; -+ interrupts = <0>; // cpm error interrupt -+ interrupt-parent = <&CPM_PIC>; -+ reg = <0x9c0 0x40>; -+ ranges; -+ -+ muram { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges = <0 0x2000 0x2000>; -+ -+ data@0 { -+ compatible = "fsl,cpm-muram-data"; -+ reg = <0 0x1c00>; -+ }; -+ }; -+ -+ brg@9f0 { -+ compatible = "fsl,mpc875-brg", -+ "fsl,cpm1-brg", -+ "fsl,cpm-brg"; -+ reg = <0x9f0 0x10>; -+ }; -+ -+ CPM_PIC: interrupt-controller@930 { -+ interrupt-controller; -+ #interrupt-cells = <1>; -+ interrupts = <5 2 0 2>; -+ interrupt-parent = <&PIC>; -+ reg = <0x930 0x20>; -+ compatible = "fsl,mpc875-cpm-pic", -+ "fsl,cpm1-pic"; -+ }; -+ -+ console: serial@a80 { -+ device_type = "serial"; -+ compatible = "fsl,mpc875-smc-uart", -+ "fsl,cpm1-smc-uart"; -+ reg = <0xa80 0x10 0x3e80 0x40>; -+ interrupts = <4>; -+ interrupt-parent = <&CPM_PIC>; -+ fsl,cpm-brg = <1>; -+ fsl,cpm-command = <0x0090>; -+ current-speed = <115200>; -+ }; -+ }; -+ }; -+ -+ chosen { -+ linux,stdout-path = &console; -+ }; -+}; ---- a/arch/powerpc/boot/dts/bamboo.dts -+++ b/arch/powerpc/boot/dts/bamboo.dts -@@ -16,14 +16,24 @@ - #size-cells = <1>; - model = "amcc,bamboo"; - compatible = "amcc,bamboo"; -- dcr-parent = <&/cpus/PowerPC,440EP@0>; -+ dcr-parent = <&/cpus/cpu@0>; -+ -+ aliases { -+ ethernet0 = &EMAC0; -+ ethernet1 = &EMAC1; -+ serial0 = &UART0; -+ serial1 = &UART1; -+ serial2 = &UART2; -+ serial3 = &UART3; -+ }; - - cpus { - #address-cells = <1>; - #size-cells = <0>; - -- PowerPC,440EP@0 { -+ cpu@0 { - device_type = "cpu"; -+ model = "PowerPC,440EP"; - reg = <0>; - clock-frequency = <0>; /* Filled in by zImage */ - timebase-frequency = <0>; /* Filled in by zImage */ -@@ -126,7 +136,6 @@ - #address-cells = <2>; - #size-cells = <1>; - clock-frequency = <0>; /* Filled in by zImage */ -- ranges; - interrupts = <5 1>; - interrupt-parent = <&UIC1>; - }; -@@ -238,11 +247,56 @@ - zmii-device = <&ZMII0>; - zmii-channel = <1>; - }; -+ -+ usb@ef601000 { -+ compatible = "ohci-be"; -+ reg = ; -+ interrupts = <8 1 9 1>; -+ interrupt-parent = < &UIC1 >; -+ }; -+ }; -+ -+ PCI0: pci@ec000000 { -+ device_type = "pci"; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ compatible = "ibm,plb440ep-pci", "ibm,plb-pci"; -+ primary; -+ reg = <0 eec00000 8 /* Config space access */ -+ 0 eed00000 4 /* IACK */ -+ 0 eed00000 4 /* Special cycle */ -+ 0 ef400000 40>; /* Internal registers */ -+ -+ /* Outbound ranges, one memory and one IO, -+ * later cannot be changed. Chip supports a second -+ * IO range but we don't use it for now -+ */ -+ ranges = <02000000 0 a0000000 0 a0000000 0 20000000 -+ 01000000 0 00000000 0 e8000000 0 00010000>; -+ -+ /* Inbound 2GB range starting at 0 */ -+ dma-ranges = <42000000 0 0 0 0 0 80000000>; -+ -+ /* Bamboo has all 4 IRQ pins tied together per slot */ -+ interrupt-map-mask = ; -+ interrupt-map = < -+ /* IDSEL 1 */ -+ 0800 0 0 0 &UIC0 1c 8 -+ -+ /* IDSEL 2 */ -+ 1000 0 0 0 &UIC0 1b 8 -+ -+ /* IDSEL 3 */ -+ 1800 0 0 0 &UIC0 1a 8 -+ -+ /* IDSEL 4 */ -+ 2000 0 0 0 &UIC0 19 8 -+ >; - }; - }; - - chosen { - linux,stdout-path = "/plb/opb/serial@ef600300"; -- bootargs = "console=ttyS0,115200"; - }; - }; ---- /dev/null -+++ b/arch/powerpc/boot/dts/cm5200.dts -@@ -0,0 +1,236 @@ -+/* -+ * CM5200 board Device Tree Source -+ * -+ * Copyright (C) 2007 Semihalf -+ * Marian Balakowicz -+ * -+ * 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. -+ */ -+ -+/* -+ * WARNING: Do not depend on this tree layout remaining static just yet. -+ * The MPC5200 device tree conventions are still in flux -+ * Keep an eye on the linuxppc-dev mailing list for more details -+ */ -+ -+/ { -+ model = "schindler,cm5200"; -+ compatible = "schindler,cm5200"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ PowerPC,5200@0 { -+ device_type = "cpu"; -+ reg = <0>; -+ d-cache-line-size = <20>; -+ i-cache-line-size = <20>; -+ d-cache-size = <4000>; // L1, 16K -+ i-cache-size = <4000>; // L1, 16K -+ timebase-frequency = <0>; // from bootloader -+ bus-frequency = <0>; // from bootloader -+ clock-frequency = <0>; // from bootloader -+ }; -+ }; -+ -+ memory { -+ device_type = "memory"; -+ reg = <00000000 04000000>; // 64MB -+ }; -+ -+ soc5200@f0000000 { -+ model = "fsl,mpc5200b"; -+ compatible = "fsl,mpc5200b"; -+ revision = ""; // from bootloader -+ device_type = "soc"; -+ ranges = <0 f0000000 0000c000>; -+ reg = ; -+ bus-frequency = <0>; // from bootloader -+ system-frequency = <0>; // from bootloader -+ -+ cdm@200 { -+ compatible = "mpc5200b-cdm","mpc5200-cdm"; -+ reg = <200 38>; -+ }; -+ -+ mpc5200_pic: pic@500 { -+ // 5200 interrupts are encoded into two levels; -+ interrupt-controller; -+ #interrupt-cells = <3>; -+ compatible = "mpc5200b-pic","mpc5200-pic"; -+ reg = <500 80>; -+ }; -+ -+ gpt@600 { // General Purpose Timer -+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; -+ reg = <600 10>; -+ interrupts = <1 9 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ fsl,has-wdt; -+ }; -+ -+ gpt@610 { // General Purpose Timer -+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; -+ reg = <610 10>; -+ interrupts = <1 a 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ }; -+ -+ gpt@620 { // General Purpose Timer -+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; -+ reg = <620 10>; -+ interrupts = <1 b 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ }; -+ -+ gpt@630 { // General Purpose Timer -+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; -+ reg = <630 10>; -+ interrupts = <1 c 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ }; -+ -+ gpt@640 { // General Purpose Timer -+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; -+ reg = <640 10>; -+ interrupts = <1 d 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ }; -+ -+ gpt@650 { // General Purpose Timer -+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; -+ reg = <650 10>; -+ interrupts = <1 e 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ }; -+ -+ gpt@660 { // General Purpose Timer -+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; -+ reg = <660 10>; -+ interrupts = <1 f 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ }; -+ -+ gpt@670 { // General Purpose Timer -+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; -+ reg = <670 10>; -+ interrupts = <1 10 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ }; -+ -+ rtc@800 { // Real time clock -+ compatible = "mpc5200b-rtc","mpc5200-rtc"; -+ reg = <800 100>; -+ interrupts = <1 5 0 1 6 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ }; -+ -+ gpio@b00 { -+ compatible = "mpc5200b-gpio","mpc5200-gpio"; -+ reg = ; -+ interrupts = <1 7 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ }; -+ -+ gpio-wkup@c00 { -+ compatible = "mpc5200b-gpio-wkup","mpc5200-gpio-wkup"; -+ reg = ; -+ interrupts = <1 8 0 0 3 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ }; -+ -+ spi@f00 { -+ compatible = "mpc5200b-spi","mpc5200-spi"; -+ reg = ; -+ interrupts = <2 d 0 2 e 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ }; -+ -+ usb@1000 { -+ device_type = "usb-ohci-be"; -+ compatible = "mpc5200b-ohci","mpc5200-ohci","ohci-be"; -+ reg = <1000 ff>; -+ interrupts = <2 6 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ }; -+ -+ dma-controller@1200 { -+ compatible = "mpc5200b-bestcomm","mpc5200-bestcomm"; -+ reg = <1200 80>; -+ interrupts = <3 0 0 3 1 0 3 2 0 3 3 0 -+ 3 4 0 3 5 0 3 6 0 3 7 0 -+ 3 8 0 3 9 0 3 a 0 3 b 0 -+ 3 c 0 3 d 0 3 e 0 3 f 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ }; -+ -+ xlb@1f00 { -+ compatible = "mpc5200b-xlb","mpc5200-xlb"; -+ reg = <1f00 100>; -+ }; -+ -+ serial@2000 { // PSC1 -+ device_type = "serial"; -+ compatible = "mpc5200b-psc-uart","mpc5200-psc-uart"; -+ port-number = <0>; // Logical port assignment -+ reg = <2000 100>; -+ interrupts = <2 1 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ }; -+ -+ serial@2200 { // PSC2 -+ device_type = "serial"; -+ compatible = "mpc5200-psc-uart"; -+ port-number = <1>; // Logical port assignment -+ reg = <2200 100>; -+ interrupts = <2 2 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ }; -+ -+ serial@2400 { // PSC3 -+ device_type = "serial"; -+ compatible = "mpc5200-psc-uart"; -+ port-number = <2>; // Logical port assignment -+ reg = <2400 100>; -+ interrupts = <2 3 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ }; -+ -+ serial@2c00 { // PSC6 -+ device_type = "serial"; -+ compatible = "mpc5200b-psc-uart","mpc5200-psc-uart"; -+ port-number = <5>; // Logical port assignment -+ reg = <2c00 100>; -+ interrupts = <2 4 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ }; -+ -+ ethernet@3000 { -+ device_type = "network"; -+ compatible = "mpc5200b-fec","mpc5200-fec"; -+ reg = <3000 800>; -+ local-mac-address = [ 00 00 00 00 00 00 ]; /* Filled in by U-Boot */ -+ interrupts = <2 5 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ }; -+ -+ i2c@3d40 { -+ compatible = "mpc5200b-i2c","mpc5200-i2c","fsl-i2c"; -+ reg = <3d40 40>; -+ interrupts = <2 10 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ fsl5200-clocking; -+ }; -+ -+ sram@8000 { -+ compatible = "mpc5200b-sram","mpc5200-sram"; -+ reg = <8000 4000>; -+ }; -+ }; -+}; ---- a/arch/powerpc/boot/dts/ebony.dts -+++ b/arch/powerpc/boot/dts/ebony.dts -@@ -16,14 +16,22 @@ - #size-cells = <1>; - model = "ibm,ebony"; - compatible = "ibm,ebony"; -- dcr-parent = <&/cpus/PowerPC,440GP@0>; -+ dcr-parent = <&/cpus/cpu@0>; -+ -+ aliases { -+ ethernet0 = &EMAC0; -+ ethernet1 = &EMAC1; -+ serial0 = &UART0; -+ serial1 = &UART1; -+ }; - - cpus { - #address-cells = <1>; - #size-cells = <0>; - -- PowerPC,440GP@0 { -+ cpu@0 { - device_type = "cpu"; -+ model = "PowerPC,440GP"; - reg = <0>; - clock-frequency = <0>; // Filled in by zImage - timebase-frequency = <0>; // Filled in by zImage -@@ -150,9 +158,10 @@ - }; - }; - -- ds1743@1,0 { -+ nvram@1,0 { - /* NVRAM & RTC */ -- compatible = "ds1743"; -+ compatible = "ds1743-nvram"; -+ #bytes = <2000>; - reg = <1 0 2000>; - }; - -@@ -284,12 +293,43 @@ - - }; - -- PCIX0: pci@1234 { -+ PCIX0: pci@20ec00000 { - device_type = "pci"; -- /* FIXME */ -- reg = <2 0ec00000 8 -- 2 0ec80000 f0 -- 2 0ec80100 fc>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ compatible = "ibm,plb440gp-pcix", "ibm,plb-pcix"; -+ primary; -+ reg = <2 0ec00000 8 /* Config space access */ -+ 0 0 0 /* no IACK cycles */ -+ 2 0ed00000 4 /* Special cycles */ -+ 2 0ec80000 f0 /* Internal registers */ -+ 2 0ec80100 fc>; /* Internal messaging registers */ -+ -+ /* Outbound ranges, one memory and one IO, -+ * later cannot be changed -+ */ -+ ranges = <02000000 0 80000000 00000003 80000000 0 80000000 -+ 01000000 0 00000000 00000002 08000000 0 00010000>; -+ -+ /* Inbound 2GB range starting at 0 */ -+ dma-ranges = <42000000 0 0 0 0 0 80000000>; -+ -+ /* Ebony has all 4 IRQ pins tied together per slot */ -+ interrupt-map-mask = ; -+ interrupt-map = < -+ /* IDSEL 1 */ -+ 0800 0 0 0 &UIC0 17 8 -+ -+ /* IDSEL 2 */ -+ 1000 0 0 0 &UIC0 18 8 -+ -+ /* IDSEL 3 */ -+ 1800 0 0 0 &UIC0 19 8 -+ -+ /* IDSEL 4 */ -+ 2000 0 0 0 &UIC0 1a 8 -+ >; - }; - }; - ---- /dev/null -+++ b/arch/powerpc/boot/dts/ep405.dts -@@ -0,0 +1,228 @@ -+/* -+ * Device Tree Source for EP405 -+ * -+ * Copyright 2007 IBM Corp. -+ * Benjamin Herrenschmidt -+ * -+ * 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. -+ */ -+ -+/ { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ model = "ep405"; -+ compatible = "ep405"; -+ dcr-parent = <&/cpus/cpu@0>; -+ -+ aliases { -+ ethernet0 = &EMAC; -+ serial0 = &UART0; -+ serial1 = &UART1; -+ }; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ cpu@0 { -+ device_type = "cpu"; -+ model = "PowerPC,405GP"; -+ reg = <0>; -+ clock-frequency = ; /* Filled in by zImage */ -+ timebase-frequency = <0>; /* Filled in by zImage */ -+ i-cache-line-size = <20>; -+ d-cache-line-size = <20>; -+ i-cache-size = <4000>; -+ d-cache-size = <4000>; -+ dcr-controller; -+ dcr-access-method = "native"; -+ }; -+ }; -+ -+ memory { -+ device_type = "memory"; -+ reg = <0 0>; /* Filled in by zImage */ -+ }; -+ -+ UIC0: interrupt-controller { -+ compatible = "ibm,uic"; -+ interrupt-controller; -+ cell-index = <0>; -+ dcr-reg = <0c0 9>; -+ #address-cells = <0>; -+ #size-cells = <0>; -+ #interrupt-cells = <2>; -+ }; -+ -+ plb { -+ compatible = "ibm,plb3"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges; -+ clock-frequency = <0>; /* Filled in by zImage */ -+ -+ SDRAM0: memory-controller { -+ compatible = "ibm,sdram-405gp"; -+ dcr-reg = <010 2>; -+ }; -+ -+ MAL: mcmal { -+ compatible = "ibm,mcmal-405gp", "ibm,mcmal"; -+ dcr-reg = <180 62>; -+ num-tx-chans = <1>; -+ num-rx-chans = <1>; -+ interrupt-parent = <&UIC0>; -+ interrupts = < -+ b 4 /* TXEOB */ -+ c 4 /* RXEOB */ -+ a 4 /* SERR */ -+ d 4 /* TXDE */ -+ e 4 /* RXDE */>; -+ }; -+ -+ POB0: opb { -+ compatible = "ibm,opb-405gp", "ibm,opb"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges = ; -+ dcr-reg = <0a0 5>; -+ clock-frequency = <0>; /* Filled in by zImage */ -+ -+ UART0: serial@ef600300 { -+ device_type = "serial"; -+ compatible = "ns16550"; -+ reg = ; -+ virtual-reg = ; -+ clock-frequency = <0>; /* Filled in by zImage */ -+ current-speed = <2580>; -+ interrupt-parent = <&UIC0>; -+ interrupts = <0 4>; -+ }; -+ -+ UART1: serial@ef600400 { -+ device_type = "serial"; -+ compatible = "ns16550"; -+ reg = ; -+ virtual-reg = ; -+ clock-frequency = <0>; /* Filled in by zImage */ -+ current-speed = <2580>; -+ interrupt-parent = <&UIC0>; -+ interrupts = <1 4>; -+ }; -+ -+ IIC: i2c@ef600500 { -+ compatible = "ibm,iic-405gp", "ibm,iic"; -+ reg = ; -+ interrupt-parent = <&UIC0>; -+ interrupts = <2 4>; -+ }; -+ -+ GPIO: gpio@ef600700 { -+ compatible = "ibm,gpio-405gp"; -+ reg = ; -+ }; -+ -+ EMAC: ethernet@ef600800 { -+ linux,network-index = <0>; -+ device_type = "network"; -+ compatible = "ibm,emac-405gp", "ibm,emac"; -+ interrupt-parent = <&UIC0>; -+ interrupts = < -+ f 4 /* Ethernet */ -+ 9 4 /* Ethernet Wake Up */>; -+ local-mac-address = [000000000000]; /* Filled in by zImage */ -+ reg = ; -+ mal-device = <&MAL>; -+ mal-tx-channel = <0>; -+ mal-rx-channel = <0>; -+ cell-index = <0>; -+ max-frame-size = <5dc>; -+ rx-fifo-size = <1000>; -+ tx-fifo-size = <800>; -+ phy-mode = "rmii"; -+ phy-map = <00000000>; -+ }; -+ -+ }; -+ -+ EBC0: ebc { -+ compatible = "ibm,ebc-405gp", "ibm,ebc"; -+ dcr-reg = <012 2>; -+ #address-cells = <2>; -+ #size-cells = <1>; -+ -+ -+ /* The ranges property is supplied by the bootwrapper -+ * and is based on the firmware's configuration of the -+ * EBC bridge -+ */ -+ clock-frequency = <0>; /* Filled in by zImage */ -+ -+ /* NVRAM and RTC */ -+ nvrtc@4,200000 { -+ compatible = "ds1742"; -+ reg = <4 200000 0>; /* size fixed up by zImage */ -+ }; -+ -+ /* "BCSR" CPLD contains a PCI irq controller */ -+ bcsr@4,0 { -+ compatible = "ep405-bcsr"; -+ reg = <4 0 10>; -+ interrupt-controller; -+ /* Routing table */ -+ irq-routing = [ 00 /* SYSERR */ -+ 01 /* STTM */ -+ 01 /* RTC */ -+ 01 /* FENET */ -+ 02 /* NB PCIIRQ mux ? */ -+ 03 /* SB Winbond 8259 ? */ -+ 04 /* Serial Ring */ -+ 05 /* USB (ep405pc) */ -+ 06 /* XIRQ 0 */ -+ 06 /* XIRQ 1 */ -+ 06 /* XIRQ 2 */ -+ 06 /* XIRQ 3 */ -+ 06 /* XIRQ 4 */ -+ 06 /* XIRQ 5 */ -+ 06 /* XIRQ 6 */ -+ 07]; /* Reserved */ -+ }; -+ }; -+ -+ PCI0: pci@ec000000 { -+ device_type = "pci"; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ compatible = "ibm,plb405gp-pci", "ibm,plb-pci"; -+ primary; -+ reg = ; /* Internal registers */ -+ -+ /* Outbound ranges, one memory and one IO, -+ * later cannot be changed. Chip supports a second -+ * IO range but we don't use it for now -+ */ -+ ranges = <02000000 0 80000000 80000000 0 20000000 -+ 01000000 0 00000000 e8000000 0 00010000>; -+ -+ /* Inbound 2GB range starting at 0 */ -+ dma-ranges = <42000000 0 0 0 0 80000000>; -+ -+ /* That's all I know about IRQs on that thing ... */ -+ interrupt-map-mask = ; -+ interrupt-map = < -+ /* USB */ -+ 7000 0 0 0 &UIC0 1e 8 /* IRQ5 */ -+ >; -+ }; -+ }; -+ -+ chosen { -+ linux,stdout-path = "/plb/opb/serial@ef600300"; -+ }; -+}; ---- /dev/null -+++ b/arch/powerpc/boot/dts/ep8248e.dts -@@ -0,0 +1,207 @@ -+/* -+ * Device Tree for the Embedded Planet EP8248E board running PlanetCore. -+ * -+ * Copyright 2007 Freescale Semiconductor Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. -+ */ -+ -+/dts-v1/; -+/ { -+ model = "EP8248E"; -+ compatible = "fsl,ep8248e"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ aliases { -+ planetcore-SMC1 = &smc1; -+ planetcore-SCC1 = &scc1; -+ ethernet0 = ð0; -+ ethernet1 = ð1; -+ serial0 = &smc1; -+ serial1 = &scc1; -+ }; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ PowerPC,8248@0 { -+ device_type = "cpu"; -+ reg = <0>; -+ d-cache-line-size = <32>; -+ i-cache-line-size = <32>; -+ d-cache-size = <16384>; -+ i-cache-size = <16384>; -+ timebase-frequency = <0>; -+ clock-frequency = <0>; -+ }; -+ }; -+ -+ localbus@f0010100 { -+ compatible = "fsl,mpc8248-localbus", -+ "fsl,pq2-localbus", -+ "simple-bus"; -+ #address-cells = <2>; -+ #size-cells = <1>; -+ reg = <0xf0010100 0x40>; -+ -+ ranges = <0 0 0xfc000000 0x04000000 -+ 1 0 0xfa000000 0x00008000>; -+ -+ flash@0,3800000 { -+ compatible = "cfi-flash"; -+ reg = <0 0x3800000 0x800000>; -+ bank-width = <4>; -+ device-width = <2>; -+ }; -+ -+ bcsr@1,0 { -+ #address-cells = <2>; -+ #size-cells = <1>; -+ reg = <1 0 0x10>; -+ compatible = "fsl,ep8248e-bcsr"; -+ ranges; -+ -+ mdio { -+ device_type = "mdio"; -+ compatible = "fsl,ep8248e-mdio-bitbang"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ reg = <1 8 1>; -+ -+ PHY0: ethernet-phy@0 { -+ interrupt-parent = <&PIC>; -+ reg = <0>; -+ device_type = "ethernet-phy"; -+ }; -+ -+ PHY1: ethernet-phy@1 { -+ interrupt-parent = <&PIC>; -+ reg = <1>; -+ device_type = "ethernet-phy"; -+ }; -+ }; -+ }; -+ }; -+ -+ memory { -+ device_type = "memory"; -+ reg = <0 0>; -+ }; -+ -+ soc@f0000000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "fsl,mpc8248-immr", "fsl,pq2-soc", "simple-bus"; -+ ranges = <0x00000000 0xf0000000 0x00053000>; -+ -+ // Temporary until code stops depending on it. -+ device_type = "soc"; -+ -+ // Temporary -- will go away once kernel uses ranges for get_immrbase(). -+ reg = <0xf0000000 0x00053000>; -+ -+ cpm@119c0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ #interrupt-cells = <2>; -+ compatible = "fsl,mpc8248-cpm", "fsl,cpm2", -+ "simple-bus"; -+ reg = <0x119c0 0x30>; -+ ranges; -+ -+ muram { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges = <0 0 0x10000>; -+ -+ data@0 { -+ compatible = "fsl,cpm-muram-data"; -+ reg = <0 0x1100 0x1140 -+ 0xec0 0x9800 0x800>; -+ }; -+ }; -+ -+ brg@119f0 { -+ compatible = "fsl,mpc8248-brg", -+ "fsl,cpm2-brg", -+ "fsl,cpm-brg"; -+ reg = <0x119f0 0x10 0x115f0 0x10>; -+ }; -+ -+ /* Monitor port/SMC1 */ -+ smc1: serial@11a80 { -+ device_type = "serial"; -+ compatible = "fsl,mpc8248-smc-uart", -+ "fsl,cpm2-smc-uart"; -+ reg = <0x11a80 0x20 0x1100 0x40>; -+ interrupts = <4 8>; -+ interrupt-parent = <&PIC>; -+ fsl,cpm-brg = <7>; -+ fsl,cpm-command = <0x1d000000>; -+ linux,planetcore-label = "SMC1"; -+ }; -+ -+ /* "Serial" port/SCC1 */ -+ scc1: serial@11a00 { -+ device_type = "serial"; -+ compatible = "fsl,mpc8248-scc-uart", -+ "fsl,cpm2-scc-uart"; -+ reg = <0x11a00 0x20 0x8000 0x100>; -+ interrupts = <40 8>; -+ interrupt-parent = <&PIC>; -+ fsl,cpm-brg = <1>; -+ fsl,cpm-command = <0x00800000>; -+ linux,planetcore-label = "SCC1"; -+ }; -+ -+ eth0: ethernet@11300 { -+ device_type = "network"; -+ compatible = "fsl,mpc8248-fcc-enet", -+ "fsl,cpm2-fcc-enet"; -+ reg = <0x11300 0x20 0x8400 0x100 0x11390 1>; -+ local-mac-address = [ 00 00 00 00 00 00 ]; -+ interrupts = <32 8>; -+ interrupt-parent = <&PIC>; -+ phy-handle = <&PHY0>; -+ linux,network-index = <0>; -+ fsl,cpm-command = <0x12000300>; -+ }; -+ -+ eth1: ethernet@11320 { -+ device_type = "network"; -+ compatible = "fsl,mpc8248-fcc-enet", -+ "fsl,cpm2-fcc-enet"; -+ reg = <0x11320 0x20 0x8500 0x100 0x113b0 1>; -+ local-mac-address = [ 00 00 00 00 00 00 ]; -+ interrupts = <33 8>; -+ interrupt-parent = <&PIC>; -+ phy-handle = <&PHY1>; -+ linux,network-index = <1>; -+ fsl,cpm-command = <0x16200300>; -+ }; -+ -+ usb@11b60 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,mpc8248-usb", -+ "fsl,cpm2-usb"; -+ reg = <0x11b60 0x18 0x8b00 0x100>; -+ interrupt-parent = <&PIC>; -+ interrupts = <11 8>; -+ fsl,cpm-command = <0x2e600000>; -+ }; -+ }; -+ -+ PIC: interrupt-controller@10c00 { -+ #interrupt-cells = <2>; -+ interrupt-controller; -+ reg = <0x10c00 0x80>; -+ compatible = "fsl,mpc8248-pic", "fsl,pq2-pic"; -+ }; -+ }; -+}; ---- /dev/null -+++ b/arch/powerpc/boot/dts/haleakala.dts -@@ -0,0 +1,274 @@ -+/* -+ * Device Tree Source for AMCC Haleakala (405EXr) -+ * -+ * Copyright 2008 DENX Software Engineering, Stefan Roese -+ * -+ * 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. -+ */ -+ -+/ { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ model = "amcc,haleakala"; -+ compatible = "amcc,kilauea"; -+ dcr-parent = <&/cpus/cpu@0>; -+ -+ aliases { -+ ethernet0 = &EMAC0; -+ serial0 = &UART0; -+ serial1 = &UART1; -+ }; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ cpu@0 { -+ device_type = "cpu"; -+ model = "PowerPC,405EXr"; -+ reg = <0>; -+ clock-frequency = <0>; /* Filled in by U-Boot */ -+ timebase-frequency = <0>; /* Filled in by U-Boot */ -+ i-cache-line-size = <20>; -+ d-cache-line-size = <20>; -+ i-cache-size = <4000>; /* 16 kB */ -+ d-cache-size = <4000>; /* 16 kB */ -+ dcr-controller; -+ dcr-access-method = "native"; -+ }; -+ }; -+ -+ memory { -+ device_type = "memory"; -+ reg = <0 0>; /* Filled in by U-Boot */ -+ }; -+ -+ UIC0: interrupt-controller { -+ compatible = "ibm,uic-405exr", "ibm,uic"; -+ interrupt-controller; -+ cell-index = <0>; -+ dcr-reg = <0c0 009>; -+ #address-cells = <0>; -+ #size-cells = <0>; -+ #interrupt-cells = <2>; -+ }; -+ -+ UIC1: interrupt-controller1 { -+ compatible = "ibm,uic-405exr","ibm,uic"; -+ interrupt-controller; -+ cell-index = <1>; -+ dcr-reg = <0d0 009>; -+ #address-cells = <0>; -+ #size-cells = <0>; -+ #interrupt-cells = <2>; -+ interrupts = <1e 4 1f 4>; /* cascade */ -+ interrupt-parent = <&UIC0>; -+ }; -+ -+ UIC2: interrupt-controller2 { -+ compatible = "ibm,uic-405exr","ibm,uic"; -+ interrupt-controller; -+ cell-index = <2>; -+ dcr-reg = <0e0 009>; -+ #address-cells = <0>; -+ #size-cells = <0>; -+ #interrupt-cells = <2>; -+ interrupts = <1c 4 1d 4>; /* cascade */ -+ interrupt-parent = <&UIC0>; -+ }; -+ -+ plb { -+ compatible = "ibm,plb-405exr", "ibm,plb4"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges; -+ clock-frequency = <0>; /* Filled in by U-Boot */ -+ -+ SDRAM0: memory-controller { -+ compatible = "ibm,sdram-405exr"; -+ dcr-reg = <010 2>; -+ }; -+ -+ MAL0: mcmal { -+ compatible = "ibm,mcmal-405exr", "ibm,mcmal2"; -+ dcr-reg = <180 62>; -+ num-tx-chans = <2>; -+ num-rx-chans = <2>; -+ interrupt-parent = <&MAL0>; -+ interrupts = <0 1 2 3 4>; -+ #interrupt-cells = <1>; -+ #address-cells = <0>; -+ #size-cells = <0>; -+ interrupt-map = ; -+ interrupt-map-mask = ; -+ }; -+ -+ POB0: opb { -+ compatible = "ibm,opb-405exr", "ibm,opb"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges = <80000000 80000000 10000000 -+ ef600000 ef600000 a00000 -+ f0000000 f0000000 10000000>; -+ dcr-reg = <0a0 5>; -+ clock-frequency = <0>; /* Filled in by U-Boot */ -+ -+ EBC0: ebc { -+ compatible = "ibm,ebc-405exr", "ibm,ebc"; -+ dcr-reg = <012 2>; -+ #address-cells = <2>; -+ #size-cells = <1>; -+ clock-frequency = <0>; /* Filled in by U-Boot */ -+ /* ranges property is supplied by U-Boot */ -+ interrupts = <5 1>; -+ interrupt-parent = <&UIC1>; -+ -+ nor_flash@0,0 { -+ compatible = "amd,s29gl512n", "cfi-flash"; -+ bank-width = <2>; -+ reg = <0 000000 4000000>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ partition@0 { -+ label = "kernel"; -+ reg = <0 200000>; -+ }; -+ partition@200000 { -+ label = "root"; -+ reg = <200000 200000>; -+ }; -+ partition@400000 { -+ label = "user"; -+ reg = <400000 3b60000>; -+ }; -+ partition@3f60000 { -+ label = "env"; -+ reg = <3f60000 40000>; -+ }; -+ partition@3fa0000 { -+ label = "u-boot"; -+ reg = <3fa0000 60000>; -+ }; -+ }; -+ }; -+ -+ UART0: serial@ef600200 { -+ device_type = "serial"; -+ compatible = "ns16550"; -+ reg = ; -+ virtual-reg = ; -+ clock-frequency = <0>; /* Filled in by U-Boot */ -+ current-speed = <0>; -+ interrupt-parent = <&UIC0>; -+ interrupts = <1a 4>; -+ }; -+ -+ UART1: serial@ef600300 { -+ device_type = "serial"; -+ compatible = "ns16550"; -+ reg = ; -+ virtual-reg = ; -+ clock-frequency = <0>; /* Filled in by U-Boot */ -+ current-speed = <0>; -+ interrupt-parent = <&UIC0>; -+ interrupts = <1 4>; -+ }; -+ -+ IIC0: i2c@ef600400 { -+ compatible = "ibm,iic-405exr", "ibm,iic"; -+ reg = ; -+ interrupt-parent = <&UIC0>; -+ interrupts = <2 4>; -+ }; -+ -+ IIC1: i2c@ef600500 { -+ compatible = "ibm,iic-405exr", "ibm,iic"; -+ reg = ; -+ interrupt-parent = <&UIC0>; -+ interrupts = <7 4>; -+ }; -+ -+ -+ RGMII0: emac-rgmii@ef600b00 { -+ compatible = "ibm,rgmii-405exr", "ibm,rgmii"; -+ reg = ; -+ has-mdio; -+ }; -+ -+ EMAC0: ethernet@ef600900 { -+ linux,network-index = <0>; -+ device_type = "network"; -+ compatible = "ibm,emac-405exr", "ibm,emac4"; -+ interrupt-parent = <&EMAC0>; -+ interrupts = <0 1>; -+ #interrupt-cells = <1>; -+ #address-cells = <0>; -+ #size-cells = <0>; -+ interrupt-map = ; -+ reg = ; -+ local-mac-address = [000000000000]; /* Filled in by U-Boot */ -+ mal-device = <&MAL0>; -+ mal-tx-channel = <0>; -+ mal-rx-channel = <0>; -+ cell-index = <0>; -+ max-frame-size = <5dc>; -+ rx-fifo-size = <1000>; -+ tx-fifo-size = <800>; -+ phy-mode = "rgmii"; -+ phy-map = <00000000>; -+ rgmii-device = <&RGMII0>; -+ rgmii-channel = <0>; -+ has-inverted-stacr-oc; -+ has-new-stacr-staopc; -+ }; -+ }; -+ -+ PCIE0: pciex@0a0000000 { -+ device_type = "pci"; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ compatible = "ibm,plb-pciex-405exr", "ibm,plb-pciex"; -+ primary; -+ port = <0>; /* port number */ -+ reg = ; /* Registers */ -+ dcr-reg = <040 020>; -+ sdr-base = <400>; -+ -+ /* Outbound ranges, one memory and one IO, -+ * later cannot be changed -+ */ -+ ranges = <02000000 0 80000000 90000000 0 08000000 -+ 01000000 0 00000000 e0000000 0 00010000>; -+ -+ /* Inbound 2GB range starting at 0 */ -+ dma-ranges = <42000000 0 0 0 0 80000000>; -+ -+ /* This drives busses 0x00 to 0x3f */ -+ bus-range = <00 3f>; -+ -+ /* Legacy interrupts (note the weird polarity, the bridge seems -+ * to invert PCIe legacy interrupts). -+ * We are de-swizzling here because the numbers are actually for -+ * port of the root complex virtual P2P bridge. But I want -+ * to avoid putting a node for it in the tree, so the numbers -+ * below are basically de-swizzled numbers. -+ * The real slot is on idsel 0, so the swizzling is 1:1 -+ */ -+ interrupt-map-mask = <0000 0 0 7>; -+ interrupt-map = < -+ 0000 0 0 1 &UIC2 0 4 /* swizzled int A */ -+ 0000 0 0 2 &UIC2 1 4 /* swizzled int B */ -+ 0000 0 0 3 &UIC2 2 4 /* swizzled int C */ -+ 0000 0 0 4 &UIC2 3 4 /* swizzled int D */>; -+ }; -+ }; -+}; ---- /dev/null -+++ b/arch/powerpc/boot/dts/katmai.dts -@@ -0,0 +1,400 @@ -+/* -+ * Device Tree Source for AMCC Katmai eval board -+ * -+ * Copyright (c) 2006, 2007 IBM Corp. -+ * Benjamin Herrenschmidt -+ * -+ * Copyright (c) 2006, 2007 IBM Corp. -+ * Josh Boyer -+ * -+ * 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. -+ */ -+ -+/ { -+ #address-cells = <2>; -+ #size-cells = <1>; -+ model = "amcc,katmai"; -+ compatible = "amcc,katmai"; -+ dcr-parent = <&/cpus/cpu@0>; -+ -+ aliases { -+ ethernet0 = &EMAC0; -+ serial0 = &UART0; -+ serial1 = &UART1; -+ serial2 = &UART2; -+ }; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ cpu@0 { -+ device_type = "cpu"; -+ model = "PowerPC,440SPe"; -+ reg = <0>; -+ clock-frequency = <0>; /* Filled in by zImage */ -+ timebase-frequency = <0>; /* Filled in by zImage */ -+ i-cache-line-size = <20>; -+ d-cache-line-size = <20>; -+ i-cache-size = <20000>; -+ d-cache-size = <20000>; -+ dcr-controller; -+ dcr-access-method = "native"; -+ }; -+ }; -+ -+ memory { -+ device_type = "memory"; -+ reg = <0 0 0>; /* Filled in by zImage */ -+ }; -+ -+ UIC0: interrupt-controller0 { -+ compatible = "ibm,uic-440spe","ibm,uic"; -+ interrupt-controller; -+ cell-index = <0>; -+ dcr-reg = <0c0 009>; -+ #address-cells = <0>; -+ #size-cells = <0>; -+ #interrupt-cells = <2>; -+ }; -+ -+ UIC1: interrupt-controller1 { -+ compatible = "ibm,uic-440spe","ibm,uic"; -+ interrupt-controller; -+ cell-index = <1>; -+ dcr-reg = <0d0 009>; -+ #address-cells = <0>; -+ #size-cells = <0>; -+ #interrupt-cells = <2>; -+ interrupts = <1e 4 1f 4>; /* cascade */ -+ interrupt-parent = <&UIC0>; -+ }; -+ -+ UIC2: interrupt-controller2 { -+ compatible = "ibm,uic-440spe","ibm,uic"; -+ interrupt-controller; -+ cell-index = <2>; -+ dcr-reg = <0e0 009>; -+ #address-cells = <0>; -+ #size-cells = <0>; -+ #interrupt-cells = <2>; -+ interrupts = ; /* cascade */ -+ interrupt-parent = <&UIC0>; -+ }; -+ -+ UIC3: interrupt-controller3 { -+ compatible = "ibm,uic-440spe","ibm,uic"; -+ interrupt-controller; -+ cell-index = <3>; -+ dcr-reg = <0f0 009>; -+ #address-cells = <0>; -+ #size-cells = <0>; -+ #interrupt-cells = <2>; -+ interrupts = <10 4 11 4>; /* cascade */ -+ interrupt-parent = <&UIC0>; -+ }; -+ -+ SDR0: sdr { -+ compatible = "ibm,sdr-440spe"; -+ dcr-reg = <00e 002>; -+ }; -+ -+ CPR0: cpr { -+ compatible = "ibm,cpr-440spe"; -+ dcr-reg = <00c 002>; -+ }; -+ -+ plb { -+ compatible = "ibm,plb-440spe", "ibm,plb-440gp", "ibm,plb4"; -+ #address-cells = <2>; -+ #size-cells = <1>; -+ ranges; -+ clock-frequency = <0>; /* Filled in by zImage */ -+ -+ SDRAM0: sdram { -+ compatible = "ibm,sdram-440spe", "ibm,sdram-405gp"; -+ dcr-reg = <010 2>; -+ }; -+ -+ MAL0: mcmal { -+ compatible = "ibm,mcmal-440spe", "ibm,mcmal2"; -+ dcr-reg = <180 62>; -+ num-tx-chans = <2>; -+ num-rx-chans = <1>; -+ interrupt-parent = <&MAL0>; -+ interrupts = <0 1 2 3 4>; -+ #interrupt-cells = <1>; -+ #address-cells = <0>; -+ #size-cells = <0>; -+ interrupt-map = ; -+ }; -+ -+ POB0: opb { -+ compatible = "ibm,opb-440spe", "ibm,opb-440gp", "ibm,opb"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges = <00000000 4 e0000000 20000000>; -+ clock-frequency = <0>; /* Filled in by zImage */ -+ -+ EBC0: ebc { -+ compatible = "ibm,ebc-440spe", "ibm,ebc-440gp", "ibm,ebc"; -+ dcr-reg = <012 2>; -+ #address-cells = <2>; -+ #size-cells = <1>; -+ clock-frequency = <0>; /* Filled in by zImage */ -+ interrupts = <5 1>; -+ interrupt-parent = <&UIC1>; -+ }; -+ -+ UART0: serial@10000200 { -+ device_type = "serial"; -+ compatible = "ns16550"; -+ reg = <10000200 8>; -+ virtual-reg = ; -+ clock-frequency = <0>; /* Filled in by zImage */ -+ current-speed = <1c200>; -+ interrupt-parent = <&UIC0>; -+ interrupts = <0 4>; -+ }; -+ -+ UART1: serial@10000300 { -+ device_type = "serial"; -+ compatible = "ns16550"; -+ reg = <10000300 8>; -+ virtual-reg = ; -+ clock-frequency = <0>; -+ current-speed = <0>; -+ interrupt-parent = <&UIC0>; -+ interrupts = <1 4>; -+ }; -+ -+ -+ UART2: serial@10000600 { -+ device_type = "serial"; -+ compatible = "ns16550"; -+ reg = <10000600 8>; -+ virtual-reg = ; -+ clock-frequency = <0>; -+ current-speed = <0>; -+ interrupt-parent = <&UIC1>; -+ interrupts = <5 4>; -+ }; -+ -+ IIC0: i2c@10000400 { -+ device_type = "i2c"; -+ compatible = "ibm,iic-440spe", "ibm,iic-440gp", "ibm,iic"; -+ reg = <10000400 14>; -+ interrupt-parent = <&UIC0>; -+ interrupts = <2 4>; -+ }; -+ -+ IIC1: i2c@10000500 { -+ device_type = "i2c"; -+ compatible = "ibm,iic-440spe", "ibm,iic-440gp", "ibm,iic"; -+ reg = <10000500 14>; -+ interrupt-parent = <&UIC0>; -+ interrupts = <3 4>; -+ }; -+ -+ EMAC0: ethernet@10000800 { -+ linux,network-index = <0>; -+ device_type = "network"; -+ compatible = "ibm,emac-440spe", "ibm,emac4"; -+ interrupt-parent = <&UIC1>; -+ interrupts = <1c 4 1d 4>; -+ reg = <10000800 70>; -+ local-mac-address = [000000000000]; -+ mal-device = <&MAL0>; -+ mal-tx-channel = <0>; -+ mal-rx-channel = <0>; -+ cell-index = <0>; -+ max-frame-size = <5dc>; -+ rx-fifo-size = <1000>; -+ tx-fifo-size = <800>; -+ phy-mode = "gmii"; -+ phy-map = <00000000>; -+ has-inverted-stacr-oc; -+ has-new-stacr-staopc; -+ }; -+ }; -+ -+ PCIX0: pci@c0ec00000 { -+ device_type = "pci"; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ compatible = "ibm,plb-pcix-440spe", "ibm,plb-pcix"; -+ primary; -+ large-inbound-windows; -+ enable-msi-hole; -+ reg = ; /* Internal messaging registers */ -+ -+ /* Outbound ranges, one memory and one IO, -+ * later cannot be changed -+ */ -+ ranges = <02000000 0 80000000 0000000d 80000000 0 80000000 -+ 01000000 0 00000000 0000000c 08000000 0 00010000>; -+ -+ /* Inbound 2GB range starting at 0 */ -+ dma-ranges = <42000000 0 0 0 0 0 80000000>; -+ -+ /* This drives busses 0 to 0xf */ -+ bus-range = <0 f>; -+ -+ /* -+ * On Katmai, the following PCI-X interrupts signals -+ * have to be enabled via jumpers (only INTA is -+ * enabled per default): -+ * -+ * INTB: J3: 1-2 -+ * INTC: J2: 1-2 -+ * INTD: J1: 1-2 -+ */ -+ interrupt-map-mask = ; -+ interrupt-map = < -+ /* IDSEL 1 */ -+ 0800 0 0 1 &UIC1 14 8 -+ 0800 0 0 2 &UIC1 13 8 -+ 0800 0 0 3 &UIC1 12 8 -+ 0800 0 0 4 &UIC1 11 8 -+ >; -+ }; -+ -+ PCIE0: pciex@d00000000 { -+ device_type = "pci"; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ compatible = "ibm,plb-pciex-440spe", "ibm,plb-pciex"; -+ primary; -+ port = <0>; /* port number */ -+ reg = ; /* Registers */ -+ dcr-reg = <100 020>; -+ sdr-base = <300>; -+ -+ /* Outbound ranges, one memory and one IO, -+ * later cannot be changed -+ */ -+ ranges = <02000000 0 80000000 0000000e 00000000 0 80000000 -+ 01000000 0 00000000 0000000f 80000000 0 00010000>; -+ -+ /* Inbound 2GB range starting at 0 */ -+ dma-ranges = <42000000 0 0 0 0 0 80000000>; -+ -+ /* This drives busses 10 to 0x1f */ -+ bus-range = <10 1f>; -+ -+ /* Legacy interrupts (note the weird polarity, the bridge seems -+ * to invert PCIe legacy interrupts). -+ * We are de-swizzling here because the numbers are actually for -+ * port of the root complex virtual P2P bridge. But I want -+ * to avoid putting a node for it in the tree, so the numbers -+ * below are basically de-swizzled numbers. -+ * The real slot is on idsel 0, so the swizzling is 1:1 -+ */ -+ interrupt-map-mask = <0000 0 0 7>; -+ interrupt-map = < -+ 0000 0 0 1 &UIC3 0 4 /* swizzled int A */ -+ 0000 0 0 2 &UIC3 1 4 /* swizzled int B */ -+ 0000 0 0 3 &UIC3 2 4 /* swizzled int C */ -+ 0000 0 0 4 &UIC3 3 4 /* swizzled int D */>; -+ }; -+ -+ PCIE1: pciex@d20000000 { -+ device_type = "pci"; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ compatible = "ibm,plb-pciex-440spe", "ibm,plb-pciex"; -+ primary; -+ port = <1>; /* port number */ -+ reg = ; /* Registers */ -+ dcr-reg = <120 020>; -+ sdr-base = <340>; -+ -+ /* Outbound ranges, one memory and one IO, -+ * later cannot be changed -+ */ -+ ranges = <02000000 0 80000000 0000000e 80000000 0 80000000 -+ 01000000 0 00000000 0000000f 80010000 0 00010000>; -+ -+ /* Inbound 2GB range starting at 0 */ -+ dma-ranges = <42000000 0 0 0 0 0 80000000>; -+ -+ /* This drives busses 10 to 0x1f */ -+ bus-range = <20 2f>; -+ -+ /* Legacy interrupts (note the weird polarity, the bridge seems -+ * to invert PCIe legacy interrupts). -+ * We are de-swizzling here because the numbers are actually for -+ * port of the root complex virtual P2P bridge. But I want -+ * to avoid putting a node for it in the tree, so the numbers -+ * below are basically de-swizzled numbers. -+ * The real slot is on idsel 0, so the swizzling is 1:1 -+ */ -+ interrupt-map-mask = <0000 0 0 7>; -+ interrupt-map = < -+ 0000 0 0 1 &UIC3 4 4 /* swizzled int A */ -+ 0000 0 0 2 &UIC3 5 4 /* swizzled int B */ -+ 0000 0 0 3 &UIC3 6 4 /* swizzled int C */ -+ 0000 0 0 4 &UIC3 7 4 /* swizzled int D */>; -+ }; -+ -+ PCIE2: pciex@d40000000 { -+ device_type = "pci"; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ compatible = "ibm,plb-pciex-440spe", "ibm,plb-pciex"; -+ primary; -+ port = <2>; /* port number */ -+ reg = ; /* Registers */ -+ dcr-reg = <140 020>; -+ sdr-base = <370>; -+ -+ /* Outbound ranges, one memory and one IO, -+ * later cannot be changed -+ */ -+ ranges = <02000000 0 80000000 0000000f 00000000 0 80000000 -+ 01000000 0 00000000 0000000f 80020000 0 00010000>; -+ -+ /* Inbound 2GB range starting at 0 */ -+ dma-ranges = <42000000 0 0 0 0 0 80000000>; -+ -+ /* This drives busses 10 to 0x1f */ -+ bus-range = <30 3f>; -+ -+ /* Legacy interrupts (note the weird polarity, the bridge seems -+ * to invert PCIe legacy interrupts). -+ * We are de-swizzling here because the numbers are actually for -+ * port of the root complex virtual P2P bridge. But I want -+ * to avoid putting a node for it in the tree, so the numbers -+ * below are basically de-swizzled numbers. -+ * The real slot is on idsel 0, so the swizzling is 1:1 -+ */ -+ interrupt-map-mask = <0000 0 0 7>; -+ interrupt-map = < -+ 0000 0 0 1 &UIC3 8 4 /* swizzled int A */ -+ 0000 0 0 2 &UIC3 9 4 /* swizzled int B */ -+ 0000 0 0 3 &UIC3 a 4 /* swizzled int C */ -+ 0000 0 0 4 &UIC3 b 4 /* swizzled int D */>; -+ }; -+ }; -+ -+ chosen { -+ linux,stdout-path = "/plb/opb/serial@10000200"; -+ }; -+}; ---- a/arch/powerpc/boot/dts/kilauea.dts -+++ b/arch/powerpc/boot/dts/kilauea.dts -@@ -13,14 +13,22 @@ - #size-cells = <1>; - model = "amcc,kilauea"; - compatible = "amcc,kilauea"; -- dcr-parent = <&/cpus/PowerPC,405EX@0>; -+ dcr-parent = <&/cpus/cpu@0>; -+ -+ aliases { -+ ethernet0 = &EMAC0; -+ ethernet1 = &EMAC1; -+ serial0 = &UART0; -+ serial1 = &UART1; -+ }; - - cpus { - #address-cells = <1>; - #size-cells = <0>; - -- PowerPC,405EX@0 { -+ cpu@0 { - device_type = "cpu"; -+ model = "PowerPC,405EX"; - reg = <0>; - clock-frequency = <0>; /* Filled in by U-Boot */ - timebase-frequency = <0>; /* Filled in by U-Boot */ -@@ -194,6 +202,7 @@ - device_type = "rgmii-interface"; - compatible = "ibm,rgmii-405ex", "ibm,rgmii"; - reg = ; -+ has-mdio; - }; - - EMAC0: ethernet@ef600900 { -@@ -220,6 +229,8 @@ - phy-map = <00000000>; - rgmii-device = <&RGMII0>; - rgmii-channel = <0>; -+ has-inverted-stacr-oc; -+ has-new-stacr-staopc; - }; - - EMAC1: ethernet@ef600a00 { -@@ -246,7 +257,91 @@ - phy-map = <00000000>; - rgmii-device = <&RGMII0>; - rgmii-channel = <1>; -+ has-inverted-stacr-oc; -+ has-new-stacr-staopc; - }; - }; -+ -+ PCIE0: pciex@0a0000000 { -+ device_type = "pci"; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ compatible = "ibm,plb-pciex-405ex", "ibm,plb-pciex"; -+ primary; -+ port = <0>; /* port number */ -+ reg = ; /* Registers */ -+ dcr-reg = <040 020>; -+ sdr-base = <400>; -+ -+ /* Outbound ranges, one memory and one IO, -+ * later cannot be changed -+ */ -+ ranges = <02000000 0 80000000 90000000 0 08000000 -+ 01000000 0 00000000 e0000000 0 00010000>; -+ -+ /* Inbound 2GB range starting at 0 */ -+ dma-ranges = <42000000 0 0 0 0 80000000>; -+ -+ /* This drives busses 0x00 to 0x3f */ -+ bus-range = <00 3f>; -+ -+ /* Legacy interrupts (note the weird polarity, the bridge seems -+ * to invert PCIe legacy interrupts). -+ * We are de-swizzling here because the numbers are actually for -+ * port of the root complex virtual P2P bridge. But I want -+ * to avoid putting a node for it in the tree, so the numbers -+ * below are basically de-swizzled numbers. -+ * The real slot is on idsel 0, so the swizzling is 1:1 -+ */ -+ interrupt-map-mask = <0000 0 0 7>; -+ interrupt-map = < -+ 0000 0 0 1 &UIC2 0 4 /* swizzled int A */ -+ 0000 0 0 2 &UIC2 1 4 /* swizzled int B */ -+ 0000 0 0 3 &UIC2 2 4 /* swizzled int C */ -+ 0000 0 0 4 &UIC2 3 4 /* swizzled int D */>; -+ }; -+ -+ PCIE1: pciex@0c0000000 { -+ device_type = "pci"; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ compatible = "ibm,plb-pciex-405ex", "ibm,plb-pciex"; -+ primary; -+ port = <1>; /* port number */ -+ reg = ; /* Registers */ -+ dcr-reg = <060 020>; -+ sdr-base = <440>; -+ -+ /* Outbound ranges, one memory and one IO, -+ * later cannot be changed -+ */ -+ ranges = <02000000 0 80000000 98000000 0 08000000 -+ 01000000 0 00000000 e0010000 0 00010000>; -+ -+ /* Inbound 2GB range starting at 0 */ -+ dma-ranges = <42000000 0 0 0 0 80000000>; -+ -+ /* This drives busses 0x40 to 0x7f */ -+ bus-range = <40 7f>; -+ -+ /* Legacy interrupts (note the weird polarity, the bridge seems -+ * to invert PCIe legacy interrupts). -+ * We are de-swizzling here because the numbers are actually for -+ * port of the root complex virtual P2P bridge. But I want -+ * to avoid putting a node for it in the tree, so the numbers -+ * below are basically de-swizzled numbers. -+ * The real slot is on idsel 0, so the swizzling is 1:1 -+ */ -+ interrupt-map-mask = <0000 0 0 7>; -+ interrupt-map = < -+ 0000 0 0 1 &UIC2 b 4 /* swizzled int A */ -+ 0000 0 0 2 &UIC2 c 4 /* swizzled int B */ -+ 0000 0 0 3 &UIC2 d 4 /* swizzled int C */ -+ 0000 0 0 4 &UIC2 e 4 /* swizzled int D */>; -+ }; - }; - }; ---- a/arch/powerpc/boot/dts/kuroboxHD.dts -+++ b/arch/powerpc/boot/dts/kuroboxHD.dts -@@ -23,6 +23,12 @@ XXXX add flash parts, rtc, ?? - #address-cells = <1>; - #size-cells = <1>; - -+ aliases { -+ serial0 = &serial0; -+ serial1 = &serial1; -+ pci0 = &pci0; -+ }; -+ - cpus { - #address-cells = <1>; - #size-cells = <0>; -@@ -60,7 +66,7 @@ XXXX add flash parts, rtc, ?? - i2c@80003000 { - #address-cells = <1>; - #size-cells = <0>; -- device_type = "i2c"; -+ cell-index = <0>; - compatible = "fsl-i2c"; - reg = <80003000 1000>; - interrupts = <5 2>; -@@ -73,7 +79,8 @@ XXXX add flash parts, rtc, ?? - }; - }; - -- serial@80004500 { -+ serial0: serial@80004500 { -+ cell-index = <0>; - device_type = "serial"; - compatible = "ns16550"; - reg = <80004500 8>; -@@ -83,7 +90,8 @@ XXXX add flash parts, rtc, ?? - interrupt-parent = <&mpic>; - }; - -- serial@80004600 { -+ serial1: serial@80004600 { -+ cell-index = <1>; - device_type = "serial"; - compatible = "ns16550"; - reg = <80004600 8>; -@@ -102,7 +110,7 @@ XXXX add flash parts, rtc, ?? - reg = <80040000 40000>; - }; - -- pci@fec00000 { -+ pci0: pci@fec00000 { - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; ---- a/arch/powerpc/boot/dts/kuroboxHG.dts -+++ b/arch/powerpc/boot/dts/kuroboxHG.dts -@@ -23,6 +23,12 @@ XXXX add flash parts, rtc, ?? - #address-cells = <1>; - #size-cells = <1>; - -+ aliases { -+ serial0 = &serial0; -+ serial1 = &serial1; -+ pci0 = &pci0; -+ }; -+ - cpus { - #address-cells = <1>; - #size-cells = <0>; -@@ -60,7 +66,7 @@ XXXX add flash parts, rtc, ?? - i2c@80003000 { - #address-cells = <1>; - #size-cells = <0>; -- device_type = "i2c"; -+ cell-index = <0>; - compatible = "fsl-i2c"; - reg = <80003000 1000>; - interrupts = <5 2>; -@@ -73,7 +79,8 @@ XXXX add flash parts, rtc, ?? - }; - }; - -- serial@80004500 { -+ serial0: serial@80004500 { -+ cell-index = <0>; - device_type = "serial"; - compatible = "ns16550"; - reg = <80004500 8>; -@@ -83,7 +90,8 @@ XXXX add flash parts, rtc, ?? - interrupt-parent = <&mpic>; - }; - -- serial@80004600 { -+ serial1: serial@80004600 { -+ cell-index = <1>; - device_type = "serial"; - compatible = "ns16550"; - reg = <80004600 8>; -@@ -102,7 +110,7 @@ XXXX add flash parts, rtc, ?? - reg = <80040000 40000>; - }; - -- pci@fec00000 { -+ pci0: pci@fec00000 { - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; ---- a/arch/powerpc/boot/dts/lite5200.dts -+++ b/arch/powerpc/boot/dts/lite5200.dts -@@ -19,7 +19,7 @@ - / { - model = "fsl,lite5200"; - // revision = "1.0"; -- compatible = "fsl,lite5200","generic-mpc5200"; -+ compatible = "fsl,lite5200"; - #address-cells = <1>; - #size-cells = <1>; - -@@ -284,7 +284,8 @@ - }; - - i2c@3d00 { -- device_type = "i2c"; -+ #address-cells = <1>; -+ #size-cells = <0>; - compatible = "mpc5200-i2c","fsl-i2c"; - cell-index = <0>; - reg = <3d00 40>; -@@ -294,7 +295,8 @@ - }; - - i2c@3d40 { -- device_type = "i2c"; -+ #address-cells = <1>; -+ #size-cells = <0>; - compatible = "mpc5200-i2c","fsl-i2c"; - cell-index = <1>; - reg = <3d40 40>; ---- a/arch/powerpc/boot/dts/lite5200b.dts -+++ b/arch/powerpc/boot/dts/lite5200b.dts -@@ -19,7 +19,7 @@ - / { - model = "fsl,lite5200b"; - // revision = "1.0"; -- compatible = "fsl,lite5200b","generic-mpc5200"; -+ compatible = "fsl,lite5200b"; - #address-cells = <1>; - #size-cells = <1>; - -@@ -300,7 +300,8 @@ - }; - - i2c@3d00 { -- device_type = "i2c"; -+ #address-cells = <1>; -+ #size-cells = <0>; - compatible = "mpc5200b-i2c","mpc5200-i2c","fsl-i2c"; - cell-index = <0>; - reg = <3d00 40>; -@@ -310,7 +311,8 @@ - }; - - i2c@3d40 { -- device_type = "i2c"; -+ #address-cells = <1>; -+ #size-cells = <0>; - compatible = "mpc5200b-i2c","mpc5200-i2c","fsl-i2c"; - cell-index = <1>; - reg = <3d40 40>; ---- /dev/null -+++ b/arch/powerpc/boot/dts/makalu.dts -@@ -0,0 +1,347 @@ -+/* -+ * Device Tree Source for AMCC Makalu (405EX) -+ * -+ * Copyright 2007 DENX Software Engineering, Stefan Roese -+ * -+ * 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. -+ */ -+ -+/ { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ model = "amcc,makalu"; -+ compatible = "amcc,makalu"; -+ dcr-parent = <&/cpus/cpu@0>; -+ -+ aliases { -+ ethernet0 = &EMAC0; -+ ethernet1 = &EMAC1; -+ serial0 = &UART0; -+ serial1 = &UART1; -+ }; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ cpu@0 { -+ device_type = "cpu"; -+ model = "PowerPC,405EX"; -+ reg = <0>; -+ clock-frequency = <0>; /* Filled in by U-Boot */ -+ timebase-frequency = <0>; /* Filled in by U-Boot */ -+ i-cache-line-size = <20>; -+ d-cache-line-size = <20>; -+ i-cache-size = <4000>; /* 16 kB */ -+ d-cache-size = <4000>; /* 16 kB */ -+ dcr-controller; -+ dcr-access-method = "native"; -+ }; -+ }; -+ -+ memory { -+ device_type = "memory"; -+ reg = <0 0>; /* Filled in by U-Boot */ -+ }; -+ -+ UIC0: interrupt-controller { -+ compatible = "ibm,uic-405ex", "ibm,uic"; -+ interrupt-controller; -+ cell-index = <0>; -+ dcr-reg = <0c0 009>; -+ #address-cells = <0>; -+ #size-cells = <0>; -+ #interrupt-cells = <2>; -+ }; -+ -+ UIC1: interrupt-controller1 { -+ compatible = "ibm,uic-405ex","ibm,uic"; -+ interrupt-controller; -+ cell-index = <1>; -+ dcr-reg = <0d0 009>; -+ #address-cells = <0>; -+ #size-cells = <0>; -+ #interrupt-cells = <2>; -+ interrupts = <1e 4 1f 4>; /* cascade */ -+ interrupt-parent = <&UIC0>; -+ }; -+ -+ UIC2: interrupt-controller2 { -+ compatible = "ibm,uic-405ex","ibm,uic"; -+ interrupt-controller; -+ cell-index = <2>; -+ dcr-reg = <0e0 009>; -+ #address-cells = <0>; -+ #size-cells = <0>; -+ #interrupt-cells = <2>; -+ interrupts = <1c 4 1d 4>; /* cascade */ -+ interrupt-parent = <&UIC0>; -+ }; -+ -+ plb { -+ compatible = "ibm,plb-405ex", "ibm,plb4"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges; -+ clock-frequency = <0>; /* Filled in by U-Boot */ -+ -+ SDRAM0: memory-controller { -+ compatible = "ibm,sdram-405ex"; -+ dcr-reg = <010 2>; -+ }; -+ -+ MAL0: mcmal { -+ compatible = "ibm,mcmal-405ex", "ibm,mcmal2"; -+ dcr-reg = <180 62>; -+ num-tx-chans = <2>; -+ num-rx-chans = <2>; -+ interrupt-parent = <&MAL0>; -+ interrupts = <0 1 2 3 4>; -+ #interrupt-cells = <1>; -+ #address-cells = <0>; -+ #size-cells = <0>; -+ interrupt-map = ; -+ interrupt-map-mask = ; -+ }; -+ -+ POB0: opb { -+ compatible = "ibm,opb-405ex", "ibm,opb"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges = <80000000 80000000 10000000 -+ ef600000 ef600000 a00000 -+ f0000000 f0000000 10000000>; -+ dcr-reg = <0a0 5>; -+ clock-frequency = <0>; /* Filled in by U-Boot */ -+ -+ EBC0: ebc { -+ compatible = "ibm,ebc-405ex", "ibm,ebc"; -+ dcr-reg = <012 2>; -+ #address-cells = <2>; -+ #size-cells = <1>; -+ clock-frequency = <0>; /* Filled in by U-Boot */ -+ /* ranges property is supplied by U-Boot */ -+ interrupts = <5 1>; -+ interrupt-parent = <&UIC1>; -+ -+ nor_flash@0,0 { -+ compatible = "amd,s29gl512n", "cfi-flash"; -+ bank-width = <2>; -+ reg = <0 000000 4000000>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ partition@0 { -+ label = "kernel"; -+ reg = <0 200000>; -+ }; -+ partition@200000 { -+ label = "root"; -+ reg = <200000 200000>; -+ }; -+ partition@400000 { -+ label = "user"; -+ reg = <400000 3b60000>; -+ }; -+ partition@3f60000 { -+ label = "env"; -+ reg = <3f60000 40000>; -+ }; -+ partition@3fa0000 { -+ label = "u-boot"; -+ reg = <3fa0000 60000>; -+ }; -+ }; -+ }; -+ -+ UART0: serial@ef600200 { -+ device_type = "serial"; -+ compatible = "ns16550"; -+ reg = ; -+ virtual-reg = ; -+ clock-frequency = <0>; /* Filled in by U-Boot */ -+ current-speed = <0>; -+ interrupt-parent = <&UIC0>; -+ interrupts = <1a 4>; -+ }; -+ -+ UART1: serial@ef600300 { -+ device_type = "serial"; -+ compatible = "ns16550"; -+ reg = ; -+ virtual-reg = ; -+ clock-frequency = <0>; /* Filled in by U-Boot */ -+ current-speed = <0>; -+ interrupt-parent = <&UIC0>; -+ interrupts = <1 4>; -+ }; -+ -+ IIC0: i2c@ef600400 { -+ device_type = "i2c"; -+ compatible = "ibm,iic-405ex", "ibm,iic"; -+ reg = ; -+ interrupt-parent = <&UIC0>; -+ interrupts = <2 4>; -+ }; -+ -+ IIC1: i2c@ef600500 { -+ device_type = "i2c"; -+ compatible = "ibm,iic-405ex", "ibm,iic"; -+ reg = ; -+ interrupt-parent = <&UIC0>; -+ interrupts = <7 4>; -+ }; -+ -+ -+ RGMII0: emac-rgmii@ef600b00 { -+ device_type = "rgmii-interface"; -+ compatible = "ibm,rgmii-405ex", "ibm,rgmii"; -+ reg = ; -+ has-mdio; -+ }; -+ -+ EMAC0: ethernet@ef600900 { -+ linux,network-index = <0>; -+ device_type = "network"; -+ compatible = "ibm,emac-405ex", "ibm,emac4"; -+ interrupt-parent = <&EMAC0>; -+ interrupts = <0 1>; -+ #interrupt-cells = <1>; -+ #address-cells = <0>; -+ #size-cells = <0>; -+ interrupt-map = ; -+ reg = ; -+ local-mac-address = [000000000000]; /* Filled in by U-Boot */ -+ mal-device = <&MAL0>; -+ mal-tx-channel = <0>; -+ mal-rx-channel = <0>; -+ cell-index = <0>; -+ max-frame-size = <5dc>; -+ rx-fifo-size = <1000>; -+ tx-fifo-size = <800>; -+ phy-mode = "rgmii"; -+ phy-map = <0000003f>; /* Start at 6 */ -+ rgmii-device = <&RGMII0>; -+ rgmii-channel = <0>; -+ has-inverted-stacr-oc; -+ has-new-stacr-staopc; -+ }; -+ -+ EMAC1: ethernet@ef600a00 { -+ linux,network-index = <1>; -+ device_type = "network"; -+ compatible = "ibm,emac-405ex", "ibm,emac4"; -+ interrupt-parent = <&EMAC1>; -+ interrupts = <0 1>; -+ #interrupt-cells = <1>; -+ #address-cells = <0>; -+ #size-cells = <0>; -+ interrupt-map = ; -+ reg = ; -+ local-mac-address = [000000000000]; /* Filled in by U-Boot */ -+ mal-device = <&MAL0>; -+ mal-tx-channel = <1>; -+ mal-rx-channel = <1>; -+ cell-index = <1>; -+ max-frame-size = <5dc>; -+ rx-fifo-size = <1000>; -+ tx-fifo-size = <800>; -+ phy-mode = "rgmii"; -+ phy-map = <00000000>; -+ rgmii-device = <&RGMII0>; -+ rgmii-channel = <1>; -+ has-inverted-stacr-oc; -+ has-new-stacr-staopc; -+ }; -+ }; -+ -+ PCIE0: pciex@0a0000000 { -+ device_type = "pci"; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ compatible = "ibm,plb-pciex-405ex", "ibm,plb-pciex"; -+ primary; -+ port = <0>; /* port number */ -+ reg = ; /* Registers */ -+ dcr-reg = <040 020>; -+ sdr-base = <400>; -+ -+ /* Outbound ranges, one memory and one IO, -+ * later cannot be changed -+ */ -+ ranges = <02000000 0 80000000 90000000 0 08000000 -+ 01000000 0 00000000 e0000000 0 00010000>; -+ -+ /* Inbound 2GB range starting at 0 */ -+ dma-ranges = <42000000 0 0 0 0 80000000>; -+ -+ /* This drives busses 0x00 to 0x3f */ -+ bus-range = <00 3f>; -+ -+ /* Legacy interrupts (note the weird polarity, the bridge seems -+ * to invert PCIe legacy interrupts). -+ * We are de-swizzling here because the numbers are actually for -+ * port of the root complex virtual P2P bridge. But I want -+ * to avoid putting a node for it in the tree, so the numbers -+ * below are basically de-swizzled numbers. -+ * The real slot is on idsel 0, so the swizzling is 1:1 -+ */ -+ interrupt-map-mask = <0000 0 0 7>; -+ interrupt-map = < -+ 0000 0 0 1 &UIC2 0 4 /* swizzled int A */ -+ 0000 0 0 2 &UIC2 1 4 /* swizzled int B */ -+ 0000 0 0 3 &UIC2 2 4 /* swizzled int C */ -+ 0000 0 0 4 &UIC2 3 4 /* swizzled int D */>; -+ }; -+ -+ PCIE1: pciex@0c0000000 { -+ device_type = "pci"; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ compatible = "ibm,plb-pciex-405ex", "ibm,plb-pciex"; -+ primary; -+ port = <1>; /* port number */ -+ reg = ; /* Registers */ -+ dcr-reg = <060 020>; -+ sdr-base = <440>; -+ -+ /* Outbound ranges, one memory and one IO, -+ * later cannot be changed -+ */ -+ ranges = <02000000 0 80000000 98000000 0 08000000 -+ 01000000 0 00000000 e0010000 0 00010000>; -+ -+ /* Inbound 2GB range starting at 0 */ -+ dma-ranges = <42000000 0 0 0 0 80000000>; -+ -+ /* This drives busses 0x40 to 0x7f */ -+ bus-range = <40 7f>; -+ -+ /* Legacy interrupts (note the weird polarity, the bridge seems -+ * to invert PCIe legacy interrupts). -+ * We are de-swizzling here because the numbers are actually for -+ * port of the root complex virtual P2P bridge. But I want -+ * to avoid putting a node for it in the tree, so the numbers -+ * below are basically de-swizzled numbers. -+ * The real slot is on idsel 0, so the swizzling is 1:1 -+ */ -+ interrupt-map-mask = <0000 0 0 7>; -+ interrupt-map = < -+ 0000 0 0 1 &UIC2 b 4 /* swizzled int A */ -+ 0000 0 0 2 &UIC2 c 4 /* swizzled int B */ -+ 0000 0 0 3 &UIC2 d 4 /* swizzled int C */ -+ 0000 0 0 4 &UIC2 e 4 /* swizzled int D */>; -+ }; -+ }; -+}; ---- /dev/null -+++ b/arch/powerpc/boot/dts/motionpro.dts -@@ -0,0 +1,309 @@ -+/* -+ * Motion-PRO board Device Tree Source -+ * -+ * Copyright (C) 2007 Semihalf -+ * Marian Balakowicz -+ * -+ * 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. -+ */ -+ -+/* -+ * WARNING: Do not depend on this tree layout remaining static just yet. -+ * The MPC5200 device tree conventions are still in flux -+ * Keep an eye on the linuxppc-dev mailing list for more details -+ */ -+ -+/ { -+ model = "promess,motionpro"; -+ compatible = "promess,motionpro"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ PowerPC,5200@0 { -+ device_type = "cpu"; -+ reg = <0>; -+ d-cache-line-size = <20>; -+ i-cache-line-size = <20>; -+ d-cache-size = <4000>; // L1, 16K -+ i-cache-size = <4000>; // L1, 16K -+ timebase-frequency = <0>; // from bootloader -+ bus-frequency = <0>; // from bootloader -+ clock-frequency = <0>; // from bootloader -+ }; -+ }; -+ -+ memory { -+ device_type = "memory"; -+ reg = <00000000 04000000>; // 64MB -+ }; -+ -+ soc5200@f0000000 { -+ model = "fsl,mpc5200b"; -+ compatible = "fsl,mpc5200b"; -+ revision = ""; // from bootloader -+ device_type = "soc"; -+ ranges = <0 f0000000 0000c000>; -+ reg = ; -+ bus-frequency = <0>; // from bootloader -+ system-frequency = <0>; // from bootloader -+ -+ cdm@200 { -+ compatible = "mpc5200b-cdm","mpc5200-cdm"; -+ reg = <200 38>; -+ }; -+ -+ mpc5200_pic: pic@500 { -+ // 5200 interrupts are encoded into two levels; -+ interrupt-controller; -+ #interrupt-cells = <3>; -+ compatible = "mpc5200b-pic","mpc5200-pic"; -+ reg = <500 80>; -+ }; -+ -+ gpt@600 { // General Purpose Timer -+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; -+ reg = <600 10>; -+ interrupts = <1 9 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ fsl,has-wdt; -+ }; -+ -+ gpt@610 { // General Purpose Timer -+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; -+ reg = <610 10>; -+ interrupts = <1 a 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ }; -+ -+ gpt@620 { // General Purpose Timer -+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; -+ reg = <620 10>; -+ interrupts = <1 b 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ }; -+ -+ gpt@630 { // General Purpose Timer -+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; -+ reg = <630 10>; -+ interrupts = <1 c 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ }; -+ -+ gpt@640 { // General Purpose Timer -+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; -+ reg = <640 10>; -+ interrupts = <1 d 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ }; -+ -+ gpt@650 { // General Purpose Timer -+ compatible = "fsl,mpc5200b-gpt","fsl,mpc5200-gpt"; -+ reg = <650 10>; -+ interrupts = <1 e 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ }; -+ -+ motionpro-led@660 { // Motion-PRO status LED -+ compatible = "promess,motionpro-led"; -+ label = "motionpro-statusled"; -+ reg = <660 10>; -+ interrupts = <1 f 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ blink-delay = <64>; // 100 msec -+ }; -+ -+ motionpro-led@670 { // Motion-PRO ready LED -+ compatible = "promess,motionpro-led"; -+ label = "motionpro-readyled"; -+ reg = <670 10>; -+ interrupts = <1 10 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ }; -+ -+ rtc@800 { // Real time clock -+ compatible = "mpc5200b-rtc","mpc5200-rtc"; -+ reg = <800 100>; -+ interrupts = <1 5 0 1 6 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ }; -+ -+ mscan@980 { -+ compatible = "mpc5200b-mscan","mpc5200-mscan"; -+ interrupts = <2 12 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ reg = <980 80>; -+ }; -+ -+ gpio@b00 { -+ compatible = "mpc5200b-gpio","mpc5200-gpio"; -+ reg = ; -+ interrupts = <1 7 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ }; -+ -+ gpio-wkup@c00 { -+ compatible = "mpc5200b-gpio-wkup","mpc5200-gpio-wkup"; -+ reg = ; -+ interrupts = <1 8 0 0 3 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ }; -+ -+ -+ spi@f00 { -+ compatible = "mpc5200b-spi","mpc5200-spi"; -+ reg = ; -+ interrupts = <2 d 0 2 e 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ }; -+ -+ usb@1000 { -+ compatible = "mpc5200b-ohci","mpc5200-ohci","ohci-be"; -+ reg = <1000 ff>; -+ interrupts = <2 6 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ }; -+ -+ dma-controller@1200 { -+ compatible = "mpc5200b-bestcomm","mpc5200-bestcomm"; -+ reg = <1200 80>; -+ interrupts = <3 0 0 3 1 0 3 2 0 3 3 0 -+ 3 4 0 3 5 0 3 6 0 3 7 0 -+ 3 8 0 3 9 0 3 a 0 3 b 0 -+ 3 c 0 3 d 0 3 e 0 3 f 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ }; -+ -+ xlb@1f00 { -+ compatible = "mpc5200b-xlb","mpc5200-xlb"; -+ reg = <1f00 100>; -+ }; -+ -+ serial@2000 { // PSC1 -+ device_type = "serial"; -+ compatible = "mpc5200b-psc-uart","mpc5200-psc-uart"; -+ port-number = <0>; // Logical port assignment -+ reg = <2000 100>; -+ interrupts = <2 1 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ }; -+ -+ // PSC2 in spi master mode -+ spi@2200 { // PSC2 -+ compatible = "mpc5200b-psc-spi","mpc5200-psc-spi"; -+ cell-index = <1>; -+ reg = <2200 100>; -+ interrupts = <2 2 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ }; -+ -+ // PSC5 in uart mode -+ serial@2800 { // PSC5 -+ device_type = "serial"; -+ compatible = "mpc5200b-psc-uart","mpc5200-psc-uart"; -+ port-number = <4>; // Logical port assignment -+ reg = <2800 100>; -+ interrupts = <2 c 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ }; -+ -+ ethernet@3000 { -+ device_type = "network"; -+ compatible = "mpc5200b-fec","mpc5200-fec"; -+ reg = <3000 800>; -+ local-mac-address = [ 00 00 00 00 00 00 ]; /* Filled in by U-Boot */ -+ interrupts = <2 5 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ }; -+ -+ ata@3a00 { -+ compatible = "mpc5200b-ata","mpc5200-ata"; -+ reg = <3a00 100>; -+ interrupts = <2 7 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ }; -+ -+ i2c@3d40 { -+ compatible = "mpc5200b-i2c","mpc5200-i2c","fsl-i2c"; -+ reg = <3d40 40>; -+ interrupts = <2 10 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ fsl5200-clocking; -+ }; -+ -+ sram@8000 { -+ compatible = "mpc5200b-sram","mpc5200-sram"; -+ reg = <8000 4000>; -+ }; -+ }; -+ -+ lpb { -+ model = "fsl,lpb"; -+ compatible = "fsl,lpb"; -+ #address-cells = <2>; -+ #size-cells = <1>; -+ ranges = <1 0 50000000 00010000 -+ 2 0 50010000 00010000 -+ 3 0 50020000 00010000>; -+ -+ // 8-bit DualPort SRAM on LocalPlus Bus CS1 -+ kollmorgen@1,0 { -+ compatible = "promess,motionpro-kollmorgen"; -+ reg = <1 0 10000>; -+ interrupts = <1 1 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ }; -+ -+ // 8-bit board CPLD on LocalPlus Bus CS2 -+ cpld@2,0 { -+ compatible = "promess,motionpro-cpld"; -+ reg = <2 0 10000>; -+ }; -+ -+ // 8-bit custom Anybus Module on LocalPlus Bus CS3 -+ anybus@3,0 { -+ compatible = "promess,motionpro-anybus"; -+ reg = <3 0 10000>; -+ }; -+ pro_module_general@3,0 { -+ compatible = "promess,pro_module_general"; -+ reg = <3 0 3>; -+ }; -+ pro_module_dio@3,800 { -+ compatible = "promess,pro_module_dio"; -+ reg = <3 800 2>; -+ }; -+ }; -+ -+ pci@f0000d00 { -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ compatible = "mpc5200b-pci","mpc5200-pci"; -+ reg = ; -+ interrupt-map-mask = ; -+ interrupt-map = ; -+ clock-frequency = <0>; // From boot loader -+ interrupts = <2 8 0 2 9 0 2 a 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ bus-range = <0 0>; -+ ranges = <42000000 0 80000000 80000000 0 20000000 -+ 02000000 0 a0000000 a0000000 0 10000000 -+ 01000000 0 00000000 b0000000 0 01000000>; -+ }; -+}; ---- a/arch/powerpc/boot/dts/mpc8313erdb.dts -+++ b/arch/powerpc/boot/dts/mpc8313erdb.dts -@@ -15,6 +15,14 @@ - #address-cells = <1>; - #size-cells = <1>; - -+ aliases { -+ ethernet0 = &enet0; -+ ethernet1 = &enet1; -+ serial0 = &serial0; -+ serial1 = &serial1; -+ pci0 = &pci0; -+ }; -+ - cpus { - #address-cells = <1>; - #size-cells = <0>; -@@ -37,10 +45,58 @@ - reg = <00000000 08000000>; // 128MB at 0 - }; - -+ localbus@e0005000 { -+ #address-cells = <2>; -+ #size-cells = <1>; -+ compatible = "fsl,mpc8313-elbc", "fsl,elbc", "simple-bus"; -+ reg = ; -+ interrupts = ; -+ interrupt-parent = <&ipic>; -+ -+ // CS0 and CS1 are swapped when -+ // booting from nand, but the -+ // addresses are the same. -+ ranges = <0 0 fe000000 00800000 -+ 1 0 e2800000 00008000 -+ 2 0 f0000000 00020000 -+ 3 0 fa000000 00008000>; -+ -+ flash@0,0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "cfi-flash"; -+ reg = <0 0 800000>; -+ bank-width = <2>; -+ device-width = <1>; -+ }; -+ -+ nand@1,0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "fsl,mpc8313-fcm-nand", -+ "fsl,elbc-fcm-nand"; -+ reg = <1 0 2000>; -+ -+ u-boot@0 { -+ reg = <0 100000>; -+ read-only; -+ }; -+ -+ kernel@100000 { -+ reg = <100000 300000>; -+ }; -+ -+ fs@400000 { -+ reg = <400000 1c00000>; -+ }; -+ }; -+ }; -+ - soc8313@e0000000 { - #address-cells = <1>; - #size-cells = <1>; - device_type = "soc"; -+ compatible = "simple-bus"; - ranges = <0 e0000000 00100000>; - reg = ; - bus-frequency = <0>; -@@ -52,7 +108,9 @@ - }; - - i2c@3000 { -- device_type = "i2c"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <0>; - compatible = "fsl-i2c"; - reg = <3000 100>; - interrupts = ; -@@ -61,7 +119,9 @@ - }; - - i2c@3100 { -- device_type = "i2c"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <1>; - compatible = "fsl-i2c"; - reg = <3100 100>; - interrupts = ; -@@ -80,7 +140,6 @@ - - /* phy type (ULPI, UTMI, UTMI_WIDE, SERIAL) */ - usb@23000 { -- device_type = "usb"; - compatible = "fsl-usb2-dr"; - reg = <23000 1000>; - #address-cells = <1>; -@@ -91,11 +150,10 @@ - }; - - mdio@24520 { -- device_type = "mdio"; -- compatible = "gianfar"; -- reg = <24520 20>; - #address-cells = <1>; - #size-cells = <0>; -+ compatible = "fsl,gianfar-mdio"; -+ reg = <24520 20>; - phy1: ethernet-phy@1 { - interrupt-parent = < &ipic >; - interrupts = <13 8>; -@@ -110,7 +168,8 @@ - }; - }; - -- ethernet@24000 { -+ enet0: ethernet@24000 { -+ cell-index = <0>; - device_type = "network"; - model = "eTSEC"; - compatible = "gianfar"; -@@ -121,7 +180,8 @@ - phy-handle = < &phy1 >; - }; - -- ethernet@25000 { -+ enet1: ethernet@25000 { -+ cell-index = <1>; - device_type = "network"; - model = "eTSEC"; - compatible = "gianfar"; -@@ -132,7 +192,8 @@ - phy-handle = < &phy4 >; - }; - -- serial@4500 { -+ serial0: serial@4500 { -+ cell-index = <0>; - device_type = "serial"; - compatible = "ns16550"; - reg = <4500 100>; -@@ -141,7 +202,8 @@ - interrupt-parent = < &ipic >; - }; - -- serial@4600 { -+ serial1: serial@4600 { -+ cell-index = <1>; - device_type = "serial"; - compatible = "ns16550"; - reg = <4600 100>; -@@ -179,7 +241,8 @@ - }; - }; - -- pci@e0008500 { -+ pci0: pci@e0008500 { -+ cell-index = <1>; - interrupt-map-mask = ; - interrupt-map = < - ---- a/arch/powerpc/boot/dts/mpc832x_mds.dts -+++ b/arch/powerpc/boot/dts/mpc832x_mds.dts -@@ -7,6 +7,18 @@ - * 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. -+ -+ * To enable external serial I/O on a Freescale MPC 8323 SYS/MDS board, do -+ * this: -+ * -+ * 1) On chip U61, lift (disconnect) pins 21 (TXD) and 22 (RXD) from the board. -+ * 2) Solder a wire from U61-21 to P19A-23. P19 is a grid of pins on the board -+ * next to the serial ports. -+ * 3) Solder a wire from U61-22 to P19K-22. -+ * -+ * Note that there's a typo in the schematic. The board labels the last column -+ * of pins "P19K", but in the schematic, that column is called "P19J". So if -+ * you're going by the schematic, the pin is called "P19J-K22". - */ - - / { -@@ -15,6 +27,14 @@ - #address-cells = <1>; - #size-cells = <1>; - -+ aliases { -+ ethernet0 = &enet0; -+ ethernet1 = &enet1; -+ serial0 = &serial0; -+ serial1 = &serial1; -+ pci0 = &pci0; -+ }; -+ - cpus { - #address-cells = <1>; - #size-cells = <0>; -@@ -59,7 +79,7 @@ - i2c@3000 { - #address-cells = <1>; - #size-cells = <0>; -- device_type = "i2c"; -+ cell-index = <0>; - compatible = "fsl-i2c"; - reg = <3000 100>; - interrupts = ; -@@ -72,7 +92,8 @@ - }; - }; - -- serial@4500 { -+ serial0: serial@4500 { -+ cell-index = <0>; - device_type = "serial"; - compatible = "ns16550"; - reg = <4500 100>; -@@ -81,7 +102,8 @@ - interrupt-parent = < &ipic >; - }; - -- serial@4600 { -+ serial1: serial@4600 { -+ cell-index = <1>; - device_type = "serial"; - compatible = "ns16550"; - reg = <4600 100>; -@@ -159,6 +181,23 @@ - 1 1e 1 0 1 0 /* TX_EN */ - 1 1f 2 0 1 0>;/* CRS */ - }; -+ pio5: ucc_pin@05 { -+ pio-map = < -+ /* -+ * open has -+ * port pin dir drain sel irq -+ */ -+ 2 0 1 0 2 0 /* TxD5 */ -+ 2 8 2 0 2 0 /* RxD5 */ -+ -+ 2 1d 2 0 0 0 /* CTS5 */ -+ 2 1f 1 0 2 0 /* RTS5 */ -+ -+ 2 18 2 0 0 0 /* CD */ -+ -+ >; -+ }; -+ - }; - }; - -@@ -166,6 +205,7 @@ - #address-cells = <1>; - #size-cells = <1>; - device_type = "qe"; -+ compatible = "fsl,qe"; - model = "QE"; - ranges = <0 e0100000 00100000>; - reg = ; -@@ -200,7 +240,6 @@ - }; - - usb@6c0 { -- device_type = "usb"; - compatible = "qe_udc"; - reg = <6c0 40 8B00 100>; - interrupts = ; -@@ -208,48 +247,58 @@ - mode = "slave"; - }; - -- ucc@2200 { -+ enet0: ucc@2200 { - device_type = "network"; - compatible = "ucc_geth"; - model = "UCC"; -+ cell-index = <3>; - device-id = <3>; - reg = <2200 200>; - interrupts = <22>; - interrupt-parent = < &qeic >; -- /* -- * mac-address is deprecated and will be removed -- * in 2.6.25. Only recent versions of -- * U-Boot support local-mac-address, however. -- */ -- mac-address = [ 00 00 00 00 00 00 ]; - local-mac-address = [ 00 00 00 00 00 00 ]; -- rx-clock = <19>; -- tx-clock = <1a>; -+ rx-clock-name = "clk9"; -+ tx-clock-name = "clk10"; - phy-handle = < &phy3 >; - pio-handle = < &pio3 >; - }; - -- ucc@3200 { -+ enet1: ucc@3200 { - device_type = "network"; - compatible = "ucc_geth"; - model = "UCC"; -+ cell-index = <4>; - device-id = <4>; - reg = <3200 200>; - interrupts = <23>; - interrupt-parent = < &qeic >; -- /* -- * mac-address is deprecated and will be removed -- * in 2.6.25. Only recent versions of -- * U-Boot support local-mac-address, however. -- */ -- mac-address = [ 00 00 00 00 00 00 ]; - local-mac-address = [ 00 00 00 00 00 00 ]; -- rx-clock = <17>; -- tx-clock = <18>; -+ rx-clock-name = "clk7"; -+ tx-clock-name = "clk8"; - phy-handle = < &phy4 >; - pio-handle = < &pio4 >; - }; - -+ ucc@2400 { -+ device_type = "serial"; -+ compatible = "ucc_uart"; -+ model = "UCC"; -+ device-id = <5>; /* The UCC number, 1-7*/ -+ port-number = <0>; /* Which ttyQEx device */ -+ soft-uart; /* We need Soft-UART */ -+ reg = <2400 200>; -+ interrupts = <28>; /* From Table 18-12 */ -+ interrupt-parent = < &qeic >; -+ /* -+ * For Soft-UART, we need to set TX to 1X, which -+ * means specifying separate clock sources. -+ */ -+ rx-clock-name = "brg5"; -+ tx-clock-name = "brg6"; -+ pio-handle = < &pio5 >; -+ }; -+ -+ - mdio@2320 { - #address-cells = <1>; - #size-cells = <0>; -@@ -283,7 +332,8 @@ - }; - }; - -- pci@e0008500 { -+ pci0: pci@e0008500 { -+ cell-index = <1>; - interrupt-map-mask = ; - interrupt-map = < - /* IDSEL 0x11 AD17 */ ---- a/arch/powerpc/boot/dts/mpc832x_rdb.dts -+++ b/arch/powerpc/boot/dts/mpc832x_rdb.dts -@@ -15,6 +15,14 @@ - #address-cells = <1>; - #size-cells = <1>; - -+ aliases { -+ ethernet0 = &enet0; -+ ethernet1 = &enet1; -+ serial0 = &serial0; -+ serial1 = &serial1; -+ pci0 = &pci0; -+ }; -+ - cpus { - #address-cells = <1>; - #size-cells = <0>; -@@ -52,7 +60,9 @@ - }; - - i2c@3000 { -- device_type = "i2c"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <0>; - compatible = "fsl-i2c"; - reg = <3000 100>; - interrupts = ; -@@ -60,7 +70,8 @@ - dfsrr; - }; - -- serial@4500 { -+ serial0: serial@4500 { -+ cell-index = <0>; - device_type = "serial"; - compatible = "ns16550"; - reg = <4500 100>; -@@ -69,7 +80,8 @@ - interrupt-parent = <&pic>; - }; - -- serial@4600 { -+ serial1: serial@4600 { -+ cell-index = <1>; - device_type = "serial"; - compatible = "ns16550"; - reg = <4600 100>; -@@ -187,44 +199,34 @@ - mode = "cpu"; - }; - -- ucc@3000 { -+ enet0: ucc@3000 { - device_type = "network"; - compatible = "ucc_geth"; - model = "UCC"; -+ cell-index = <2>; - device-id = <2>; - reg = <3000 200>; - interrupts = <21>; - interrupt-parent = <&qeic>; -- /* -- * mac-address is deprecated and will be removed -- * in 2.6.25. Only recent versions of -- * U-Boot support local-mac-address, however. -- */ -- mac-address = [ 00 00 00 00 00 00 ]; - local-mac-address = [ 00 00 00 00 00 00 ]; -- rx-clock = <20>; -- tx-clock = <13>; -+ rx-clock-name = "clk16"; -+ tx-clock-name = "clk3"; - phy-handle = <&phy00>; - pio-handle = <&ucc2pio>; - }; - -- ucc@2200 { -+ enet1: ucc@2200 { - device_type = "network"; - compatible = "ucc_geth"; - model = "UCC"; -+ cell-index = <3>; - device-id = <3>; - reg = <2200 200>; - interrupts = <22>; - interrupt-parent = <&qeic>; -- /* -- * mac-address is deprecated and will be removed -- * in 2.6.25. Only recent versions of -- * U-Boot support local-mac-address, however. -- */ -- mac-address = [ 00 00 00 00 00 00 ]; - local-mac-address = [ 00 00 00 00 00 00 ]; -- rx-clock = <19>; -- tx-clock = <1a>; -+ rx-clock-name = "clk9"; -+ tx-clock-name = "clk10"; - phy-handle = <&phy04>; - pio-handle = <&ucc3pio>; - }; -@@ -262,7 +264,8 @@ - }; - }; - -- pci@e0008500 { -+ pci0: pci@e0008500 { -+ cell-index = <1>; - interrupt-map-mask = ; - interrupt-map = < - /* IDSEL 0x10 AD16 (USB) */ ---- a/arch/powerpc/boot/dts/mpc8349emitx.dts -+++ b/arch/powerpc/boot/dts/mpc8349emitx.dts -@@ -14,6 +14,15 @@ - #address-cells = <1>; - #size-cells = <1>; - -+ aliases { -+ ethernet0 = &enet0; -+ ethernet1 = &enet1; -+ serial0 = &serial0; -+ serial1 = &serial1; -+ pci0 = &pci0; -+ pci1 = &pci1; -+ }; -+ - cpus { - #address-cells = <1>; - #size-cells = <0>; -@@ -51,7 +60,9 @@ - }; - - i2c@3000 { -- device_type = "i2c"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <0>; - compatible = "fsl-i2c"; - reg = <3000 100>; - interrupts = ; -@@ -60,7 +71,9 @@ - }; - - i2c@3100 { -- device_type = "i2c"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <1>; - compatible = "fsl-i2c"; - reg = <3100 100>; - interrupts = ; -@@ -78,7 +91,6 @@ - }; - - usb@22000 { -- device_type = "usb"; - compatible = "fsl-usb2-mph"; - reg = <22000 1000>; - #address-cells = <1>; -@@ -90,7 +102,6 @@ - }; - - usb@23000 { -- device_type = "usb"; - compatible = "fsl-usb2-dr"; - reg = <23000 1000>; - #address-cells = <1>; -@@ -102,11 +113,10 @@ - }; - - mdio@24520 { -- device_type = "mdio"; -- compatible = "gianfar"; -- reg = <24520 20>; - #address-cells = <1>; - #size-cells = <0>; -+ compatible = "fsl,gianfar-mdio"; -+ reg = <24520 20>; - - /* Vitesse 8201 */ - phy1c: ethernet-phy@1c { -@@ -115,27 +125,14 @@ - reg = <1c>; - device_type = "ethernet-phy"; - }; -- -- /* Vitesse 7385 */ -- phy1f: ethernet-phy@1f { -- interrupt-parent = < &ipic >; -- interrupts = <12 8>; -- reg = <1f>; -- device_type = "ethernet-phy"; -- }; - }; - -- ethernet@24000 { -+ enet0: ethernet@24000 { -+ cell-index = <0>; - device_type = "network"; - model = "TSEC"; - compatible = "gianfar"; - reg = <24000 1000>; -- /* -- * address is deprecated and will be removed -- * in 2.6.25. Only recent versions of -- * U-Boot support local-mac-address, however. -- */ -- address = [ 00 00 00 00 00 00 ]; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <20 8 21 8 22 8>; - interrupt-parent = < &ipic >; -@@ -143,27 +140,22 @@ - linux,network-index = <0>; - }; - -- ethernet@25000 { -- #address-cells = <1>; -- #size-cells = <0>; -+ enet1: ethernet@25000 { -+ cell-index = <1>; - device_type = "network"; - model = "TSEC"; - compatible = "gianfar"; - reg = <25000 1000>; -- /* -- * address is deprecated and will be removed -- * in 2.6.25. Only recent versions of -- * U-Boot support local-mac-address, however. -- */ -- address = [ 00 00 00 00 00 00 ]; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <23 8 24 8 25 8>; - interrupt-parent = < &ipic >; -- phy-handle = < &phy1f >; -+ /* Vitesse 7385 isn't on the MDIO bus */ -+ fixed-link = <1 1 d#1000 0 0>; - linux,network-index = <1>; - }; - -- serial@4500 { -+ serial0: serial@4500 { -+ cell-index = <0>; - device_type = "serial"; - compatible = "ns16550"; - reg = <4500 100>; -@@ -172,7 +164,8 @@ - interrupt-parent = < &ipic >; - }; - -- serial@4600 { -+ serial1: serial@4600 { -+ cell-index = <1>; - device_type = "serial"; - compatible = "ns16550"; - reg = <4600 100>; -@@ -203,7 +196,8 @@ - }; - }; - -- pci@e0008500 { -+ pci0: pci@e0008500 { -+ cell-index = <1>; - interrupt-map-mask = ; - interrupt-map = < - /* IDSEL 0x10 - SATA */ -@@ -224,7 +218,8 @@ - device_type = "pci"; - }; - -- pci@e0008600 { -+ pci1: pci@e0008600 { -+ cell-index = <2>; - interrupt-map-mask = ; - interrupt-map = < - /* IDSEL 0x0E - MiniPCI Slot */ -@@ -249,6 +244,21 @@ - device_type = "pci"; - }; - -- -- -+ localbus@e0005000 { -+ #address-cells = <2>; -+ #size-cells = <1>; -+ compatible = "fsl,mpc8349e-localbus", -+ "fsl,pq2pro-localbus"; -+ reg = ; -+ ranges = <3 0 f0000000 210>; -+ -+ pata@3,0 { -+ compatible = "fsl,mpc8349emitx-pata", "ata-generic"; -+ reg = <3 0 10 3 20c 4>; -+ reg-shift = <1>; -+ pio-mode = <6>; -+ interrupts = <17 8>; -+ interrupt-parent = <&ipic>; -+ }; -+ }; - }; ---- a/arch/powerpc/boot/dts/mpc8349emitxgp.dts -+++ b/arch/powerpc/boot/dts/mpc8349emitxgp.dts -@@ -14,6 +14,13 @@ - #address-cells = <1>; - #size-cells = <1>; - -+ aliases { -+ ethernet0 = &enet0; -+ serial0 = &serial0; -+ serial1 = &serial1; -+ pci0 = &pci0; -+ }; -+ - cpus { - #address-cells = <1>; - #size-cells = <0>; -@@ -51,7 +58,9 @@ - }; - - i2c@3000 { -- device_type = "i2c"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <0>; - compatible = "fsl-i2c"; - reg = <3000 100>; - interrupts = ; -@@ -60,7 +69,9 @@ - }; - - i2c@3100 { -- device_type = "i2c"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <1>; - compatible = "fsl-i2c"; - reg = <3100 100>; - interrupts = ; -@@ -78,7 +89,6 @@ - }; - - usb@23000 { -- device_type = "usb"; - compatible = "fsl-usb2-dr"; - reg = <23000 1000>; - #address-cells = <1>; -@@ -90,11 +100,10 @@ - }; - - mdio@24520 { -- device_type = "mdio"; -- compatible = "gianfar"; -- reg = <24520 20>; - #address-cells = <1>; - #size-cells = <0>; -+ compatible = "fsl,gianfar-mdio"; -+ reg = <24520 20>; - - /* Vitesse 8201 */ - phy1c: ethernet-phy@1c { -@@ -105,7 +114,8 @@ - }; - }; - -- ethernet@24000 { -+ enet0: ethernet@24000 { -+ cell-index = <0>; - device_type = "network"; - model = "TSEC"; - compatible = "gianfar"; -@@ -117,7 +127,8 @@ - linux,network-index = <0>; - }; - -- serial@4500 { -+ serial0: serial@4500 { -+ cell-index = <0>; - device_type = "serial"; - compatible = "ns16550"; - reg = <4500 100>; -@@ -126,7 +137,8 @@ - interrupt-parent = < &ipic >; - }; - -- serial@4600 { -+ serial1: serial@4600 { -+ cell-index = <1>; - device_type = "serial"; - compatible = "ns16550"; - reg = <4600 100>; -@@ -157,7 +169,8 @@ - }; - }; - -- pci@e0008600 { -+ pci0: pci@e0008600 { -+ cell-index = <2>; - interrupt-map-mask = ; - interrupt-map = < - /* IDSEL 0x0F - PCI Slot */ ---- a/arch/powerpc/boot/dts/mpc834x_mds.dts -+++ b/arch/powerpc/boot/dts/mpc834x_mds.dts -@@ -15,6 +15,15 @@ - #address-cells = <1>; - #size-cells = <1>; - -+ aliases { -+ ethernet0 = &enet0; -+ ethernet1 = &enet1; -+ serial0 = &serial0; -+ serial1 = &serial1; -+ pci0 = &pci0; -+ pci1 = &pci1; -+ }; -+ - cpus { - #address-cells = <1>; - #size-cells = <0>; -@@ -59,7 +68,7 @@ - i2c@3000 { - #address-cells = <1>; - #size-cells = <0>; -- device_type = "i2c"; -+ cell-index = <0>; - compatible = "fsl-i2c"; - reg = <3000 100>; - interrupts = ; -@@ -75,7 +84,7 @@ - i2c@3100 { - #address-cells = <1>; - #size-cells = <0>; -- device_type = "i2c"; -+ cell-index = <1>; - compatible = "fsl-i2c"; - reg = <3100 100>; - interrupts = ; -@@ -95,7 +104,6 @@ - /* phy type (ULPI or SERIAL) are only types supportted for MPH */ - /* port = 0 or 1 */ - usb@22000 { -- device_type = "usb"; - compatible = "fsl-usb2-mph"; - reg = <22000 1000>; - #address-cells = <1>; -@@ -107,7 +115,6 @@ - }; - /* phy type (ULPI, UTMI, UTMI_WIDE, SERIAL) */ - usb@23000 { -- device_type = "usb"; - compatible = "fsl-usb2-dr"; - reg = <23000 1000>; - #address-cells = <1>; -@@ -119,11 +126,11 @@ - }; - - mdio@24520 { -- device_type = "mdio"; -- compatible = "gianfar"; -- reg = <24520 20>; - #address-cells = <1>; - #size-cells = <0>; -+ compatible = "fsl,gianfar-mdio"; -+ reg = <24520 20>; -+ - phy0: ethernet-phy@0 { - interrupt-parent = < &ipic >; - interrupts = <11 8>; -@@ -138,17 +145,12 @@ - }; - }; - -- ethernet@24000 { -+ enet0: ethernet@24000 { -+ cell-index = <0>; - device_type = "network"; - model = "TSEC"; - compatible = "gianfar"; - reg = <24000 1000>; -- /* -- * address is deprecated and will be removed -- * in 2.6.25. Only recent versions of -- * U-Boot support local-mac-address, however. -- */ -- address = [ 00 00 00 00 00 00 ]; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <20 8 21 8 22 8>; - interrupt-parent = < &ipic >; -@@ -156,19 +158,12 @@ - linux,network-index = <0>; - }; - -- ethernet@25000 { -- #address-cells = <1>; -- #size-cells = <0>; -+ enet1: ethernet@25000 { -+ cell-index = <1>; - device_type = "network"; - model = "TSEC"; - compatible = "gianfar"; - reg = <25000 1000>; -- /* -- * address is deprecated and will be removed -- * in 2.6.25. Only recent versions of -- * U-Boot support local-mac-address, however. -- */ -- address = [ 00 00 00 00 00 00 ]; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <23 8 24 8 25 8>; - interrupt-parent = < &ipic >; -@@ -176,7 +171,8 @@ - linux,network-index = <1>; - }; - -- serial@4500 { -+ serial0: serial@4500 { -+ cell-index = <0>; - device_type = "serial"; - compatible = "ns16550"; - reg = <4500 100>; -@@ -185,7 +181,8 @@ - interrupt-parent = < &ipic >; - }; - -- serial@4600 { -+ serial1: serial@4600 { -+ cell-index = <1>; - device_type = "serial"; - compatible = "ns16550"; - reg = <4600 100>; -@@ -225,7 +222,8 @@ - }; - }; - -- pci@e0008500 { -+ pci0: pci@e0008500 { -+ cell-index = <1>; - interrupt-map-mask = ; - interrupt-map = < - -@@ -285,7 +283,8 @@ - device_type = "pci"; - }; - -- pci@e0008600 { -+ pci1: pci@e0008600 { -+ cell-index = <2>; - interrupt-map-mask = ; - interrupt-map = < - ---- a/arch/powerpc/boot/dts/mpc836x_mds.dts -+++ b/arch/powerpc/boot/dts/mpc836x_mds.dts -@@ -20,6 +20,14 @@ - #address-cells = <1>; - #size-cells = <1>; - -+ aliases { -+ ethernet0 = &enet0; -+ ethernet1 = &enet1; -+ serial0 = &serial0; -+ serial1 = &serial1; -+ pci0 = &pci0; -+ }; -+ - cpus { - #address-cells = <1>; - #size-cells = <0>; -@@ -64,7 +72,7 @@ - i2c@3000 { - #address-cells = <1>; - #size-cells = <0>; -- device_type = "i2c"; -+ cell-index = <0>; - compatible = "fsl-i2c"; - reg = <3000 100>; - interrupts = ; -@@ -80,7 +88,7 @@ - i2c@3100 { - #address-cells = <1>; - #size-cells = <0>; -- device_type = "i2c"; -+ cell-index = <1>; - compatible = "fsl-i2c"; - reg = <3100 100>; - interrupts = ; -@@ -88,7 +96,8 @@ - dfsrr; - }; - -- serial@4500 { -+ serial0: serial@4500 { -+ cell-index = <0>; - device_type = "serial"; - compatible = "ns16550"; - reg = <4500 100>; -@@ -97,7 +106,8 @@ - interrupt-parent = < &ipic >; - }; - -- serial@4600 { -+ serial1: serial@4600 { -+ cell-index = <1>; - device_type = "serial"; - compatible = "ns16550"; - reg = <4600 100>; -@@ -231,7 +241,6 @@ - }; - - usb@6c0 { -- device_type = "usb"; - compatible = "qe_udc"; - reg = <6c0 40 8B00 100>; - interrupts = ; -@@ -239,45 +248,35 @@ - mode = "slave"; - }; - -- ucc@2000 { -+ enet0: ucc@2000 { - device_type = "network"; - compatible = "ucc_geth"; - model = "UCC"; -+ cell-index = <1>; - device-id = <1>; - reg = <2000 200>; - interrupts = <20>; - interrupt-parent = < &qeic >; -- /* -- * mac-address is deprecated and will be removed -- * in 2.6.25. Only recent versions of -- * U-Boot support local-mac-address, however. -- */ -- mac-address = [ 00 00 00 00 00 00 ]; - local-mac-address = [ 00 00 00 00 00 00 ]; -- rx-clock = <0>; -- tx-clock = <19>; -+ rx-clock-name = "none"; -+ tx-clock-name = "clk9"; - phy-handle = < &phy0 >; - phy-connection-type = "rgmii-id"; - pio-handle = < &pio1 >; - }; - -- ucc@3000 { -+ enet1: ucc@3000 { - device_type = "network"; - compatible = "ucc_geth"; - model = "UCC"; -+ cell-index = <2>; - device-id = <2>; - reg = <3000 200>; - interrupts = <21>; - interrupt-parent = < &qeic >; -- /* -- * mac-address is deprecated and will be removed -- * in 2.6.25. Only recent versions of -- * U-Boot support local-mac-address, however. -- */ -- mac-address = [ 00 00 00 00 00 00 ]; - local-mac-address = [ 00 00 00 00 00 00 ]; -- rx-clock = <0>; -- tx-clock = <14>; -+ rx-clock-name = "none"; -+ tx-clock-name = "clk4"; - phy-handle = < &phy1 >; - phy-connection-type = "rgmii-id"; - pio-handle = < &pio2 >; -@@ -316,7 +315,8 @@ - }; - }; - -- pci@e0008500 { -+ pci0: pci@e0008500 { -+ cell-index = <1>; - interrupt-map-mask = ; - interrupt-map = < - ---- /dev/null -+++ b/arch/powerpc/boot/dts/mpc8377_mds.dts -@@ -0,0 +1,279 @@ -+/* -+ * MPC8377E MDS Device Tree Source -+ * -+ * Copyright 2007 Freescale Semiconductor Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. -+ */ -+ -+/dts-v1/; -+ -+/ { -+ model = "fsl,mpc8377emds"; -+ compatible = "fsl,mpc8377emds","fsl,mpc837xmds"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ aliases { -+ ethernet0 = &enet0; -+ ethernet1 = &enet1; -+ serial0 = &serial0; -+ serial1 = &serial1; -+ pci0 = &pci0; -+ }; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ PowerPC,8377@0 { -+ device_type = "cpu"; -+ reg = <0>; -+ d-cache-line-size = <0x20>; -+ i-cache-line-size = <0x20>; -+ d-cache-size = <0x8000>; // L1, 32K -+ i-cache-size = <0x8000>; // L1, 32K -+ timebase-frequency = <0>; -+ bus-frequency = <0>; -+ clock-frequency = <0>; -+ }; -+ }; -+ -+ memory { -+ device_type = "memory"; -+ reg = <0x00000000 0x20000000>; // 512MB at 0 -+ }; -+ -+ soc@e0000000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ device_type = "soc"; -+ ranges = <0x0 0xe0000000 0x00100000>; -+ reg = <0xe0000000 0x00000200>; -+ bus-frequency = <0>; -+ -+ wdt@200 { -+ compatible = "mpc83xx_wdt"; -+ reg = <0x200 0x100>; -+ }; -+ -+ i2c@3000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <0>; -+ compatible = "fsl-i2c"; -+ reg = <0x3000 0x100>; -+ interrupts = <0xe 0x8>; -+ interrupt-parent = < &ipic >; -+ dfsrr; -+ }; -+ -+ i2c@3100 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <1>; -+ compatible = "fsl-i2c"; -+ reg = <0x3100 0x100>; -+ interrupts = <0xf 0x8>; -+ interrupt-parent = < &ipic >; -+ dfsrr; -+ }; -+ -+ spi@7000 { -+ compatible = "fsl_spi"; -+ reg = <0x7000 0x1000>; -+ interrupts = <0x10 0x8>; -+ interrupt-parent = < &ipic >; -+ mode = "cpu"; -+ }; -+ -+ /* phy type (ULPI, UTMI, UTMI_WIDE, SERIAL) */ -+ usb@23000 { -+ compatible = "fsl-usb2-dr"; -+ reg = <0x23000 0x1000>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ interrupt-parent = < &ipic >; -+ interrupts = <0x26 0x8>; -+ phy_type = "utmi_wide"; -+ }; -+ -+ mdio@24520 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,gianfar-mdio"; -+ reg = <0x24520 0x20>; -+ phy2: ethernet-phy@2 { -+ interrupt-parent = < &ipic >; -+ interrupts = <0x11 0x8>; -+ reg = <2>; -+ device_type = "ethernet-phy"; -+ }; -+ phy3: ethernet-phy@3 { -+ interrupt-parent = < &ipic >; -+ interrupts = <0x12 0x8>; -+ reg = <3>; -+ device_type = "ethernet-phy"; -+ }; -+ }; -+ -+ enet0: ethernet@24000 { -+ cell-index = <0>; -+ device_type = "network"; -+ model = "eTSEC"; -+ compatible = "gianfar"; -+ reg = <0x24000 0x1000>; -+ local-mac-address = [ 00 00 00 00 00 00 ]; -+ interrupts = <0x20 0x8 0x21 0x8 0x22 0x8>; -+ phy-connection-type = "mii"; -+ interrupt-parent = < &ipic >; -+ phy-handle = < &phy2 >; -+ }; -+ -+ enet1: ethernet@25000 { -+ cell-index = <1>; -+ device_type = "network"; -+ model = "eTSEC"; -+ compatible = "gianfar"; -+ reg = <0x25000 0x1000>; -+ local-mac-address = [ 00 00 00 00 00 00 ]; -+ interrupts = <0x23 0x8 0x24 0x8 0x25 0x8>; -+ phy-connection-type = "mii"; -+ interrupt-parent = < &ipic >; -+ phy-handle = < &phy3 >; -+ }; -+ -+ serial0: serial@4500 { -+ cell-index = <0>; -+ device_type = "serial"; -+ compatible = "ns16550"; -+ reg = <0x4500 0x100>; -+ clock-frequency = <0>; -+ interrupts = <0x9 0x8>; -+ interrupt-parent = < &ipic >; -+ }; -+ -+ serial1: serial@4600 { -+ cell-index = <1>; -+ device_type = "serial"; -+ compatible = "ns16550"; -+ reg = <0x4600 0x100>; -+ clock-frequency = <0>; -+ interrupts = <0xa 0x8>; -+ interrupt-parent = < &ipic >; -+ }; -+ -+ crypto@30000 { -+ model = "SEC3"; -+ compatible = "talitos"; -+ reg = <0x30000 0x10000>; -+ interrupts = <0xb 0x8>; -+ interrupt-parent = < &ipic >; -+ /* Rev. 3.0 geometry */ -+ num-channels = <4>; -+ channel-fifo-len = <0x18>; -+ exec-units-mask = <0x000001fe>; -+ descriptor-types-mask = <0x03ab0ebf>; -+ }; -+ -+ sdhc@2e000 { -+ model = "eSDHC"; -+ compatible = "fsl,esdhc"; -+ reg = <0x2e000 0x1000>; -+ interrupts = <0x2a 0x8>; -+ interrupt-parent = < &ipic >; -+ }; -+ -+ sata@18000 { -+ compatible = "fsl,mpc8379-sata"; -+ reg = <0x18000 0x1000>; -+ interrupts = <0x2c 0x8>; -+ interrupt-parent = < &ipic >; -+ }; -+ -+ sata@19000 { -+ compatible = "fsl,mpc8379-sata"; -+ reg = <0x19000 0x1000>; -+ interrupts = <0x2d 0x8>; -+ interrupt-parent = < &ipic >; -+ }; -+ -+ /* IPIC -+ * interrupts cell = -+ * sense values match linux IORESOURCE_IRQ_* defines: -+ * sense == 8: Level, low assertion -+ * sense == 2: Edge, high-to-low change -+ */ -+ ipic: pic@700 { -+ compatible = "fsl,ipic"; -+ interrupt-controller; -+ #address-cells = <0>; -+ #interrupt-cells = <2>; -+ reg = <0x700 0x100>; -+ }; -+ }; -+ -+ pci0: pci@e0008500 { -+ cell-index = <0>; -+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>; -+ interrupt-map = < -+ -+ /* IDSEL 0x11 */ -+ 0x8800 0x0 0x0 0x1 &ipic 0x14 0x8 -+ 0x8800 0x0 0x0 0x2 &ipic 0x15 0x8 -+ 0x8800 0x0 0x0 0x3 &ipic 0x16 0x8 -+ 0x8800 0x0 0x0 0x4 &ipic 0x17 0x8 -+ -+ /* IDSEL 0x12 */ -+ 0x9000 0x0 0x0 0x1 &ipic 0x16 0x8 -+ 0x9000 0x0 0x0 0x2 &ipic 0x17 0x8 -+ 0x9000 0x0 0x0 0x3 &ipic 0x14 0x8 -+ 0x9000 0x0 0x0 0x4 &ipic 0x15 0x8 -+ -+ /* IDSEL 0x13 */ -+ 0x9800 0x0 0x0 0x1 &ipic 0x17 0x8 -+ 0x9800 0x0 0x0 0x2 &ipic 0x14 0x8 -+ 0x9800 0x0 0x0 0x3 &ipic 0x15 0x8 -+ 0x9800 0x0 0x0 0x4 &ipic 0x16 0x8 -+ -+ /* IDSEL 0x15 */ -+ 0xa800 0x0 0x0 0x1 &ipic 0x14 0x8 -+ 0xa800 0x0 0x0 0x2 &ipic 0x15 0x8 -+ 0xa800 0x0 0x0 0x3 &ipic 0x16 0x8 -+ 0xa800 0x0 0x0 0x4 &ipic 0x17 0x8 -+ -+ /* IDSEL 0x16 */ -+ 0xb000 0x0 0x0 0x1 &ipic 0x17 0x8 -+ 0xb000 0x0 0x0 0x2 &ipic 0x14 0x8 -+ 0xb000 0x0 0x0 0x3 &ipic 0x15 0x8 -+ 0xb000 0x0 0x0 0x4 &ipic 0x16 0x8 -+ -+ /* IDSEL 0x17 */ -+ 0xb800 0x0 0x0 0x1 &ipic 0x16 0x8 -+ 0xb800 0x0 0x0 0x2 &ipic 0x17 0x8 -+ 0xb800 0x0 0x0 0x3 &ipic 0x14 0x8 -+ 0xb800 0x0 0x0 0x4 &ipic 0x15 0x8 -+ -+ /* IDSEL 0x18 */ -+ 0xc000 0x0 0x0 0x1 &ipic 0x15 0x8 -+ 0xc000 0x0 0x0 0x2 &ipic 0x16 0x8 -+ 0xc000 0x0 0x0 0x3 &ipic 0x17 0x8 -+ 0xc000 0x0 0x0 0x4 &ipic 0x14 0x8>; -+ interrupt-parent = < &ipic >; -+ interrupts = <0x42 0x8>; -+ bus-range = <0 0>; -+ ranges = <0x02000000 0x0 0x90000000 0x90000000 0x0 0x10000000 -+ 0x42000000 0x0 0x80000000 0x80000000 0x0 0x10000000 -+ 0x01000000 0x0 0x00000000 0xe0300000 0x0 0x00100000>; -+ clock-frequency = <0>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ reg = <0xe0008500 0x100>; -+ compatible = "fsl,mpc8349-pci"; -+ device_type = "pci"; -+ }; -+}; ---- /dev/null -+++ b/arch/powerpc/boot/dts/mpc8378_mds.dts -@@ -0,0 +1,265 @@ -+/* -+ * MPC8378E MDS Device Tree Source -+ * -+ * Copyright 2007 Freescale Semiconductor Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. -+ */ -+ -+/dts-v1/; -+ -+/ { -+ model = "fsl,mpc8378emds"; -+ compatible = "fsl,mpc8378emds","fsl,mpc837xmds"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ aliases { -+ ethernet0 = &enet0; -+ ethernet1 = &enet1; -+ serial0 = &serial0; -+ serial1 = &serial1; -+ pci0 = &pci0; -+ }; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ PowerPC,8378@0 { -+ device_type = "cpu"; -+ reg = <0>; -+ d-cache-line-size = <0x20>; -+ i-cache-line-size = <0x20>; -+ d-cache-size = <0x8000>; // L1, 32K -+ i-cache-size = <0x8000>; // L1, 32K -+ timebase-frequency = <0>; -+ bus-frequency = <0>; -+ clock-frequency = <0>; -+ }; -+ }; -+ -+ memory { -+ device_type = "memory"; -+ reg = <0x00000000 0x20000000>; // 512MB at 0 -+ }; -+ -+ soc@e0000000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ device_type = "soc"; -+ ranges = <0x0 0xe0000000 0x00100000>; -+ reg = <0xe0000000 0x00000200>; -+ bus-frequency = <0>; -+ -+ wdt@200 { -+ compatible = "mpc83xx_wdt"; -+ reg = <0x200 0x100>; -+ }; -+ -+ i2c@3000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <0>; -+ compatible = "fsl-i2c"; -+ reg = <0x3000 0x100>; -+ interrupts = <0xe 0x8>; -+ interrupt-parent = < &ipic >; -+ dfsrr; -+ }; -+ -+ i2c@3100 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <1>; -+ compatible = "fsl-i2c"; -+ reg = <0x3100 0x100>; -+ interrupts = <0xf 0x8>; -+ interrupt-parent = < &ipic >; -+ dfsrr; -+ }; -+ -+ spi@7000 { -+ compatible = "fsl_spi"; -+ reg = <0x7000 0x1000>; -+ interrupts = <0x10 0x8>; -+ interrupt-parent = < &ipic >; -+ mode = "cpu"; -+ }; -+ -+ /* phy type (ULPI, UTMI, UTMI_WIDE, SERIAL) */ -+ usb@23000 { -+ compatible = "fsl-usb2-dr"; -+ reg = <0x23000 0x1000>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ interrupt-parent = < &ipic >; -+ interrupts = <0x26 0x8>; -+ phy_type = "utmi_wide"; -+ }; -+ -+ mdio@24520 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,gianfar-mdio"; -+ reg = <0x24520 0x20>; -+ phy2: ethernet-phy@2 { -+ interrupt-parent = < &ipic >; -+ interrupts = <0x11 0x8>; -+ reg = <2>; -+ device_type = "ethernet-phy"; -+ }; -+ phy3: ethernet-phy@3 { -+ interrupt-parent = < &ipic >; -+ interrupts = <0x12 0x8>; -+ reg = <3>; -+ device_type = "ethernet-phy"; -+ }; -+ }; -+ -+ enet0: ethernet@24000 { -+ cell-index = <0>; -+ device_type = "network"; -+ model = "eTSEC"; -+ compatible = "gianfar"; -+ reg = <0x24000 0x1000>; -+ local-mac-address = [ 00 00 00 00 00 00 ]; -+ interrupts = <0x20 0x8 0x21 0x8 0x22 0x8>; -+ phy-connection-type = "mii"; -+ interrupt-parent = < &ipic >; -+ phy-handle = < &phy2 >; -+ }; -+ -+ enet1: ethernet@25000 { -+ cell-index = <1>; -+ device_type = "network"; -+ model = "eTSEC"; -+ compatible = "gianfar"; -+ reg = <0x25000 0x1000>; -+ local-mac-address = [ 00 00 00 00 00 00 ]; -+ interrupts = <0x23 0x8 0x24 0x8 0x25 0x8>; -+ phy-connection-type = "mii"; -+ interrupt-parent = < &ipic >; -+ phy-handle = < &phy3 >; -+ }; -+ -+ serial0: serial@4500 { -+ cell-index = <0>; -+ device_type = "serial"; -+ compatible = "ns16550"; -+ reg = <0x4500 0x100>; -+ clock-frequency = <0>; -+ interrupts = <0x9 0x8>; -+ interrupt-parent = < &ipic >; -+ }; -+ -+ serial1: serial@4600 { -+ cell-index = <1>; -+ device_type = "serial"; -+ compatible = "ns16550"; -+ reg = <0x4600 0x100>; -+ clock-frequency = <0>; -+ interrupts = <0xa 0x8>; -+ interrupt-parent = < &ipic >; -+ }; -+ -+ crypto@30000 { -+ model = "SEC3"; -+ compatible = "talitos"; -+ reg = <0x30000 0x10000>; -+ interrupts = <0xb 0x8>; -+ interrupt-parent = < &ipic >; -+ /* Rev. 3.0 geometry */ -+ num-channels = <4>; -+ channel-fifo-len = <0x18>; -+ exec-units-mask = <0x000001fe>; -+ descriptor-types-mask = <0x03ab0ebf>; -+ }; -+ -+ sdhc@2e000 { -+ model = "eSDHC"; -+ compatible = "fsl,esdhc"; -+ reg = <0x2e000 0x1000>; -+ interrupts = <0x2a 0x8>; -+ interrupt-parent = < &ipic >; -+ }; -+ -+ /* IPIC -+ * interrupts cell = -+ * sense values match linux IORESOURCE_IRQ_* defines: -+ * sense == 8: Level, low assertion -+ * sense == 2: Edge, high-to-low change -+ */ -+ ipic: pic@700 { -+ compatible = "fsl,ipic"; -+ interrupt-controller; -+ #address-cells = <0>; -+ #interrupt-cells = <2>; -+ reg = <0x700 0x100>; -+ }; -+ }; -+ -+ pci0: pci@e0008500 { -+ cell-index = <0>; -+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>; -+ interrupt-map = < -+ -+ /* IDSEL 0x11 */ -+ 0x8800 0x0 0x0 0x1 &ipic 0x14 0x8 -+ 0x8800 0x0 0x0 0x2 &ipic 0x15 0x8 -+ 0x8800 0x0 0x0 0x3 &ipic 0x16 0x8 -+ 0x8800 0x0 0x0 0x4 &ipic 0x17 0x8 -+ -+ /* IDSEL 0x12 */ -+ 0x9000 0x0 0x0 0x1 &ipic 0x16 0x8 -+ 0x9000 0x0 0x0 0x2 &ipic 0x17 0x8 -+ 0x9000 0x0 0x0 0x3 &ipic 0x14 0x8 -+ 0x9000 0x0 0x0 0x4 &ipic 0x15 0x8 -+ -+ /* IDSEL 0x13 */ -+ 0x9800 0x0 0x0 0x1 &ipic 0x17 0x8 -+ 0x9800 0x0 0x0 0x2 &ipic 0x14 0x8 -+ 0x9800 0x0 0x0 0x3 &ipic 0x15 0x8 -+ 0x9800 0x0 0x0 0x4 &ipic 0x16 0x8 -+ -+ /* IDSEL 0x15 */ -+ 0xa800 0x0 0x0 0x1 &ipic 0x14 0x8 -+ 0xa800 0x0 0x0 0x2 &ipic 0x15 0x8 -+ 0xa800 0x0 0x0 0x3 &ipic 0x16 0x8 -+ 0xa800 0x0 0x0 0x4 &ipic 0x17 0x8 -+ -+ /* IDSEL 0x16 */ -+ 0xb000 0x0 0x0 0x1 &ipic 0x17 0x8 -+ 0xb000 0x0 0x0 0x2 &ipic 0x14 0x8 -+ 0xb000 0x0 0x0 0x3 &ipic 0x15 0x8 -+ 0xb000 0x0 0x0 0x4 &ipic 0x16 0x8 -+ -+ /* IDSEL 0x17 */ -+ 0xb800 0x0 0x0 0x1 &ipic 0x16 0x8 -+ 0xb800 0x0 0x0 0x2 &ipic 0x17 0x8 -+ 0xb800 0x0 0x0 0x3 &ipic 0x14 0x8 -+ 0xb800 0x0 0x0 0x4 &ipic 0x15 0x8 -+ -+ /* IDSEL 0x18 */ -+ 0xc000 0x0 0x0 0x1 &ipic 0x15 0x8 -+ 0xc000 0x0 0x0 0x2 &ipic 0x16 0x8 -+ 0xc000 0x0 0x0 0x3 &ipic 0x17 0x8 -+ 0xc000 0x0 0x0 0x4 &ipic 0x14 0x8>; -+ interrupt-parent = < &ipic >; -+ interrupts = <0x42 0x8>; -+ bus-range = <0 0>; -+ ranges = <0x02000000 0x0 0x90000000 0x90000000 0x0 0x10000000 -+ 0x42000000 0x0 0x80000000 0x80000000 0x0 0x10000000 -+ 0x01000000 0x0 0x00000000 0xe0300000 0x0 0x00100000>; -+ clock-frequency = <0>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ reg = <0xe0008500 0x100>; -+ compatible = "fsl,mpc8349-pci"; -+ device_type = "pci"; -+ }; -+}; ---- /dev/null -+++ b/arch/powerpc/boot/dts/mpc8379_mds.dts -@@ -0,0 +1,293 @@ -+/* -+ * MPC8379E MDS Device Tree Source -+ * -+ * Copyright 2007 Freescale Semiconductor Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. -+ */ -+ -+/dts-v1/; -+ -+/ { -+ model = "fsl,mpc8379emds"; -+ compatible = "fsl,mpc8379emds","fsl,mpc837xmds"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ aliases { -+ ethernet0 = &enet0; -+ ethernet1 = &enet1; -+ serial0 = &serial0; -+ serial1 = &serial1; -+ pci0 = &pci0; -+ }; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ PowerPC,8379@0 { -+ device_type = "cpu"; -+ reg = <0>; -+ d-cache-line-size = <0x20>; -+ i-cache-line-size = <0x20>; -+ d-cache-size = <0x8000>; // L1, 32K -+ i-cache-size = <0x8000>; // L1, 32K -+ timebase-frequency = <0>; -+ bus-frequency = <0>; -+ clock-frequency = <0>; -+ }; -+ }; -+ -+ memory { -+ device_type = "memory"; -+ reg = <0x00000000 0x20000000>; // 512MB at 0 -+ }; -+ -+ soc@e0000000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ device_type = "soc"; -+ ranges = <0x0 0xe0000000 0x00100000>; -+ reg = <0xe0000000 0x00000200>; -+ bus-frequency = <0>; -+ -+ wdt@200 { -+ compatible = "mpc83xx_wdt"; -+ reg = <0x200 0x100>; -+ }; -+ -+ i2c@3000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <0>; -+ compatible = "fsl-i2c"; -+ reg = <0x3000 0x100>; -+ interrupts = <0xe 0x8>; -+ interrupt-parent = < &ipic >; -+ dfsrr; -+ }; -+ -+ i2c@3100 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <1>; -+ compatible = "fsl-i2c"; -+ reg = <0x3100 0x100>; -+ interrupts = <0xf 0x8>; -+ interrupt-parent = < &ipic >; -+ dfsrr; -+ }; -+ -+ spi@7000 { -+ compatible = "fsl_spi"; -+ reg = <0x7000 0x1000>; -+ interrupts = <0x10 0x8>; -+ interrupt-parent = < &ipic >; -+ mode = "cpu"; -+ }; -+ -+ /* phy type (ULPI, UTMI, UTMI_WIDE, SERIAL) */ -+ usb@23000 { -+ compatible = "fsl-usb2-dr"; -+ reg = <0x23000 0x1000>; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ interrupt-parent = < &ipic >; -+ interrupts = <0x26 0x8>; -+ phy_type = "utmi_wide"; -+ }; -+ -+ mdio@24520 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl,gianfar-mdio"; -+ reg = <0x24520 0x20>; -+ phy2: ethernet-phy@2 { -+ interrupt-parent = < &ipic >; -+ interrupts = <0x11 0x8>; -+ reg = <2>; -+ device_type = "ethernet-phy"; -+ }; -+ phy3: ethernet-phy@3 { -+ interrupt-parent = < &ipic >; -+ interrupts = <0x12 0x8>; -+ reg = <3>; -+ device_type = "ethernet-phy"; -+ }; -+ }; -+ -+ enet0: ethernet@24000 { -+ cell-index = <0>; -+ device_type = "network"; -+ model = "eTSEC"; -+ compatible = "gianfar"; -+ reg = <0x24000 0x1000>; -+ local-mac-address = [ 00 00 00 00 00 00 ]; -+ interrupts = <0x20 0x8 0x21 0x8 0x22 0x8>; -+ phy-connection-type = "mii"; -+ interrupt-parent = < &ipic >; -+ phy-handle = < &phy2 >; -+ }; -+ -+ enet1: ethernet@25000 { -+ cell-index = <1>; -+ device_type = "network"; -+ model = "eTSEC"; -+ compatible = "gianfar"; -+ reg = <0x25000 0x1000>; -+ local-mac-address = [ 00 00 00 00 00 00 ]; -+ interrupts = <0x23 0x8 0x24 0x8 0x25 0x8>; -+ phy-connection-type = "mii"; -+ interrupt-parent = < &ipic >; -+ phy-handle = < &phy3 >; -+ }; -+ -+ serial0: serial@4500 { -+ cell-index = <0>; -+ device_type = "serial"; -+ compatible = "ns16550"; -+ reg = <0x4500 0x100>; -+ clock-frequency = <0>; -+ interrupts = <0x9 0x8>; -+ interrupt-parent = < &ipic >; -+ }; -+ -+ serial1: serial@4600 { -+ cell-index = <1>; -+ device_type = "serial"; -+ compatible = "ns16550"; -+ reg = <0x4600 0x100>; -+ clock-frequency = <0>; -+ interrupts = <0xa 0x8>; -+ interrupt-parent = < &ipic >; -+ }; -+ -+ crypto@30000 { -+ model = "SEC3"; -+ compatible = "talitos"; -+ reg = <0x30000 0x10000>; -+ interrupts = <0xb 0x8>; -+ interrupt-parent = < &ipic >; -+ /* Rev. 3.0 geometry */ -+ num-channels = <4>; -+ channel-fifo-len = <0x18>; -+ exec-units-mask = <0x000001fe>; -+ descriptor-types-mask = <0x03ab0ebf>; -+ }; -+ -+ sdhc@2e000 { -+ model = "eSDHC"; -+ compatible = "fsl,esdhc"; -+ reg = <0x2e000 0x1000>; -+ interrupts = <0x2a 0x8>; -+ interrupt-parent = < &ipic >; -+ }; -+ -+ sata@18000 { -+ compatible = "fsl,mpc8379-sata"; -+ reg = <0x18000 0x1000>; -+ interrupts = <0x2c 0x8>; -+ interrupt-parent = < &ipic >; -+ }; -+ -+ sata@19000 { -+ compatible = "fsl,mpc8379-sata"; -+ reg = <0x19000 0x1000>; -+ interrupts = <0x2d 0x8>; -+ interrupt-parent = < &ipic >; -+ }; -+ -+ sata@1a000 { -+ compatible = "fsl,mpc8379-sata"; -+ reg = <0x1a000 0x1000>; -+ interrupts = <0x2e 0x8>; -+ interrupt-parent = < &ipic >; -+ }; -+ -+ sata@1b000 { -+ compatible = "fsl,mpc8379-sata"; -+ reg = <0x1b000 0x1000>; -+ interrupts = <0x2f 0x8>; -+ interrupt-parent = < &ipic >; -+ }; -+ -+ /* IPIC -+ * interrupts cell = -+ * sense values match linux IORESOURCE_IRQ_* defines: -+ * sense == 8: Level, low assertion -+ * sense == 2: Edge, high-to-low change -+ */ -+ ipic: pic@700 { -+ compatible = "fsl,ipic"; -+ interrupt-controller; -+ #address-cells = <0>; -+ #interrupt-cells = <2>; -+ reg = <0x700 0x100>; -+ }; -+ }; -+ -+ pci0: pci@e0008500 { -+ cell-index = <0>; -+ interrupt-map-mask = <0xf800 0x0 0x0 0x7>; -+ interrupt-map = < -+ -+ /* IDSEL 0x11 */ -+ 0x8800 0x0 0x0 0x1 &ipic 0x14 0x8 -+ 0x8800 0x0 0x0 0x2 &ipic 0x15 0x8 -+ 0x8800 0x0 0x0 0x3 &ipic 0x16 0x8 -+ 0x8800 0x0 0x0 0x4 &ipic 0x17 0x8 -+ -+ /* IDSEL 0x12 */ -+ 0x9000 0x0 0x0 0x1 &ipic 0x16 0x8 -+ 0x9000 0x0 0x0 0x2 &ipic 0x17 0x8 -+ 0x9000 0x0 0x0 0x3 &ipic 0x14 0x8 -+ 0x9000 0x0 0x0 0x4 &ipic 0x15 0x8 -+ -+ /* IDSEL 0x13 */ -+ 0x9800 0x0 0x0 0x1 &ipic 0x17 0x8 -+ 0x9800 0x0 0x0 0x2 &ipic 0x14 0x8 -+ 0x9800 0x0 0x0 0x3 &ipic 0x15 0x8 -+ 0x9800 0x0 0x0 0x4 &ipic 0x16 0x8 -+ -+ /* IDSEL 0x15 */ -+ 0xa800 0x0 0x0 0x1 &ipic 0x14 0x8 -+ 0xa800 0x0 0x0 0x2 &ipic 0x15 0x8 -+ 0xa800 0x0 0x0 0x3 &ipic 0x16 0x8 -+ 0xa800 0x0 0x0 0x4 &ipic 0x17 0x8 -+ -+ /* IDSEL 0x16 */ -+ 0xb000 0x0 0x0 0x1 &ipic 0x17 0x8 -+ 0xb000 0x0 0x0 0x2 &ipic 0x14 0x8 -+ 0xb000 0x0 0x0 0x3 &ipic 0x15 0x8 -+ 0xb000 0x0 0x0 0x4 &ipic 0x16 0x8 -+ -+ /* IDSEL 0x17 */ -+ 0xb800 0x0 0x0 0x1 &ipic 0x16 0x8 -+ 0xb800 0x0 0x0 0x2 &ipic 0x17 0x8 -+ 0xb800 0x0 0x0 0x3 &ipic 0x14 0x8 -+ 0xb800 0x0 0x0 0x4 &ipic 0x15 0x8 -+ -+ /* IDSEL 0x18 */ -+ 0xc000 0x0 0x0 0x1 &ipic 0x15 0x8 -+ 0xc000 0x0 0x0 0x2 &ipic 0x16 0x8 -+ 0xc000 0x0 0x0 0x3 &ipic 0x17 0x8 -+ 0xc000 0x0 0x0 0x4 &ipic 0x14 0x8>; -+ interrupt-parent = < &ipic >; -+ interrupts = <0x42 0x8>; -+ bus-range = <0 0>; -+ ranges = <0x02000000 0x0 0x90000000 0x90000000 0x0 0x10000000 -+ 0x42000000 0x0 0x80000000 0x80000000 0x0 0x10000000 -+ 0x01000000 0x0 0x00000000 0xe0300000 0x0 0x00100000>; -+ clock-frequency = <0>; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ reg = <0xe0008500 0x100>; -+ compatible = "fsl,mpc8349-pci"; -+ device_type = "pci"; -+ }; -+}; ---- a/arch/powerpc/boot/dts/mpc8540ads.dts -+++ b/arch/powerpc/boot/dts/mpc8540ads.dts -@@ -16,6 +16,15 @@ - #address-cells = <1>; - #size-cells = <1>; - -+ aliases { -+ ethernet0 = &enet0; -+ ethernet1 = &enet1; -+ ethernet2 = &enet2; -+ serial0 = &serial0; -+ serial1 = &serial1; -+ pci0 = &pci0; -+ }; -+ - cpus { - #address-cells = <1>; - #size-cells = <0>; -@@ -63,7 +72,9 @@ - }; - - i2c@3000 { -- device_type = "i2c"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <0>; - compatible = "fsl-i2c"; - reg = <3000 100>; - interrupts = <2b 2>; -@@ -74,9 +85,9 @@ - mdio@24520 { - #address-cells = <1>; - #size-cells = <0>; -- device_type = "mdio"; -- compatible = "gianfar"; -+ compatible = "fsl,gianfar-mdio"; - reg = <24520 20>; -+ - phy0: ethernet-phy@0 { - interrupt-parent = <&mpic>; - interrupts = <5 1>; -@@ -97,64 +108,44 @@ - }; - }; - -- ethernet@24000 { -- #address-cells = <1>; -- #size-cells = <0>; -+ enet0: ethernet@24000 { -+ cell-index = <0>; - device_type = "network"; - model = "TSEC"; - compatible = "gianfar"; - reg = <24000 1000>; -- /* -- * address is deprecated and will be removed -- * in 2.6.25. Only recent versions of -- * U-Boot support local-mac-address, however. -- */ -- address = [ 00 00 00 00 00 00 ]; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <1d 2 1e 2 22 2>; - interrupt-parent = <&mpic>; - phy-handle = <&phy0>; - }; - -- ethernet@25000 { -- #address-cells = <1>; -- #size-cells = <0>; -+ enet1: ethernet@25000 { -+ cell-index = <1>; - device_type = "network"; - model = "TSEC"; - compatible = "gianfar"; - reg = <25000 1000>; -- /* -- * address is deprecated and will be removed -- * in 2.6.25. Only recent versions of -- * U-Boot support local-mac-address, however. -- */ -- address = [ 00 00 00 00 00 00 ]; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <23 2 24 2 28 2>; - interrupt-parent = <&mpic>; - phy-handle = <&phy1>; - }; - -- ethernet@26000 { -- #address-cells = <1>; -- #size-cells = <0>; -+ enet2: ethernet@26000 { -+ cell-index = <2>; - device_type = "network"; - model = "FEC"; - compatible = "gianfar"; - reg = <26000 1000>; -- /* -- * address is deprecated and will be removed -- * in 2.6.25. Only recent versions of -- * U-Boot support local-mac-address, however. -- */ -- address = [ 00 00 00 00 00 00 ]; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <29 2>; - interrupt-parent = <&mpic>; - phy-handle = <&phy3>; - }; - -- serial@4500 { -+ serial0: serial@4500 { -+ cell-index = <0>; - device_type = "serial"; - compatible = "ns16550"; - reg = <4500 100>; // reg base, size -@@ -163,7 +154,8 @@ - interrupt-parent = <&mpic>; - }; - -- serial@4600 { -+ serial1: serial@4600 { -+ cell-index = <1>; - device_type = "serial"; - compatible = "ns16550"; - reg = <4600 100>; // reg base, size -@@ -183,7 +175,8 @@ - }; - }; - -- pci@e0008000 { -+ pci0: pci@e0008000 { -+ cell-index = <0>; - interrupt-map-mask = ; - interrupt-map = < - ---- a/arch/powerpc/boot/dts/mpc8541cds.dts -+++ b/arch/powerpc/boot/dts/mpc8541cds.dts -@@ -16,6 +16,15 @@ - #address-cells = <1>; - #size-cells = <1>; - -+ aliases { -+ ethernet0 = &enet0; -+ ethernet1 = &enet1; -+ serial0 = &serial0; -+ serial1 = &serial1; -+ pci0 = &pci0; -+ pci1 = &pci1; -+ }; -+ - cpus { - #address-cells = <1>; - #size-cells = <0>; -@@ -63,7 +72,9 @@ - }; - - i2c@3000 { -- device_type = "i2c"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <0>; - compatible = "fsl-i2c"; - reg = <3000 100>; - interrupts = <2b 2>; -@@ -74,9 +85,9 @@ - mdio@24520 { - #address-cells = <1>; - #size-cells = <0>; -- device_type = "mdio"; -- compatible = "gianfar"; -+ compatible = "fsl,gianfar-mdio"; - reg = <24520 20>; -+ - phy0: ethernet-phy@0 { - interrupt-parent = <&mpic>; - interrupts = <5 1>; -@@ -91,9 +102,8 @@ - }; - }; - -- ethernet@24000 { -- #address-cells = <1>; -- #size-cells = <0>; -+ enet0: ethernet@24000 { -+ cell-index = <0>; - device_type = "network"; - model = "TSEC"; - compatible = "gianfar"; -@@ -104,9 +114,8 @@ - phy-handle = <&phy0>; - }; - -- ethernet@25000 { -- #address-cells = <1>; -- #size-cells = <0>; -+ enet1: ethernet@25000 { -+ cell-index = <1>; - device_type = "network"; - model = "TSEC"; - compatible = "gianfar"; -@@ -117,7 +126,8 @@ - phy-handle = <&phy1>; - }; - -- serial@4500 { -+ serial0: serial@4500 { -+ cell-index = <0>; - device_type = "serial"; - compatible = "ns16550"; - reg = <4500 100>; // reg base, size -@@ -126,7 +136,8 @@ - interrupt-parent = <&mpic>; - }; - -- serial@4600 { -+ serial1: serial@4600 { -+ cell-index = <1>; - device_type = "serial"; - compatible = "ns16550"; - reg = <4600 100>; // reg base, size -@@ -183,7 +194,8 @@ - }; - }; - -- pci1: pci@e0008000 { -+ pci0: pci@e0008000 { -+ cell-index = <0>; - interrupt-map-mask = <1f800 0 0 7>; - interrupt-map = < - -@@ -250,11 +262,12 @@ - #interrupt-cells = <2>; - compatible = "chrp,iic"; - interrupts = <1>; -- interrupt-parent = <&pci1>; -+ interrupt-parent = <&pci0>; - }; - }; - -- pci@e0009000 { -+ pci1: pci@e0009000 { -+ cell-index = <1>; - interrupt-map-mask = ; - interrupt-map = < - ---- a/arch/powerpc/boot/dts/mpc8544ds.dts -+++ b/arch/powerpc/boot/dts/mpc8544ds.dts -@@ -15,6 +15,17 @@ - #address-cells = <1>; - #size-cells = <1>; - -+ aliases { -+ ethernet0 = &enet0; -+ ethernet1 = &enet1; -+ serial0 = &serial0; -+ serial1 = &serial1; -+ pci0 = &pci0; -+ pci1 = &pci1; -+ pci2 = &pci2; -+ pci3 = &pci3; -+ }; -+ - cpus { - #cpus = <1>; - #address-cells = <1>; -@@ -64,7 +75,9 @@ - }; - - i2c@3000 { -- device_type = "i2c"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <0>; - compatible = "fsl-i2c"; - reg = <3000 100>; - interrupts = <2b 2>; -@@ -72,12 +85,23 @@ - dfsrr; - }; - -+ i2c@3100 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <1>; -+ compatible = "fsl-i2c"; -+ reg = <3100 100>; -+ interrupts = <2b 2>; -+ interrupt-parent = <&mpic>; -+ dfsrr; -+ }; -+ - mdio@24520 { - #address-cells = <1>; - #size-cells = <0>; -- device_type = "mdio"; -- compatible = "gianfar"; -+ compatible = "fsl,gianfar-mdio"; - reg = <24520 20>; -+ - phy0: ethernet-phy@0 { - interrupt-parent = <&mpic>; - interrupts = ; -@@ -92,9 +116,8 @@ - }; - }; - -- ethernet@24000 { -- #address-cells = <1>; -- #size-cells = <0>; -+ enet0: ethernet@24000 { -+ cell-index = <0>; - device_type = "network"; - model = "TSEC"; - compatible = "gianfar"; -@@ -106,9 +129,8 @@ - phy-connection-type = "rgmii-id"; - }; - -- ethernet@26000 { -- #address-cells = <1>; -- #size-cells = <0>; -+ enet1: ethernet@26000 { -+ cell-index = <1>; - device_type = "network"; - model = "TSEC"; - compatible = "gianfar"; -@@ -120,7 +142,8 @@ - phy-connection-type = "rgmii-id"; - }; - -- serial@4500 { -+ serial0: serial@4500 { -+ cell-index = <0>; - device_type = "serial"; - compatible = "ns16550"; - reg = <4500 100>; -@@ -129,7 +152,8 @@ - interrupt-parent = <&mpic>; - }; - -- serial@4600 { -+ serial1: serial@4600 { -+ cell-index = <1>; - device_type = "serial"; - compatible = "ns16550"; - reg = <4600 100>; -@@ -156,7 +180,8 @@ - }; - }; - -- pci@e0008000 { -+ pci0: pci@e0008000 { -+ cell-index = <0>; - compatible = "fsl,mpc8540-pci"; - device_type = "pci"; - interrupt-map-mask = ; -@@ -187,7 +212,8 @@ - reg = ; - }; - -- pcie@e0009000 { -+ pci1: pcie@e0009000 { -+ cell-index = <1>; - compatible = "fsl,mpc8548-pcie"; - device_type = "pci"; - #interrupt-cells = <1>; -@@ -223,7 +249,8 @@ - }; - }; - -- pcie@e000a000 { -+ pci2: pcie@e000a000 { -+ cell-index = <2>; - compatible = "fsl,mpc8548-pcie"; - device_type = "pci"; - #interrupt-cells = <1>; -@@ -259,7 +286,8 @@ - }; - }; - -- pcie@e000b000 { -+ pci3: pcie@e000b000 { -+ cell-index = <3>; - compatible = "fsl,mpc8548-pcie"; - device_type = "pci"; - #interrupt-cells = <1>; -@@ -276,9 +304,9 @@ - interrupt-map = < - // IDSEL 0x1c USB - e000 0 0 1 &i8259 c 2 -- e100 0 0 1 &i8259 9 2 -- e200 0 0 1 &i8259 a 2 -- e300 0 0 1 &i8259 b 2 -+ e100 0 0 2 &i8259 9 2 -+ e200 0 0 3 &i8259 a 2 -+ e300 0 0 4 &i8259 b 2 - - // IDSEL 0x1d Audio - e800 0 0 1 &i8259 6 2 -@@ -369,6 +397,5 @@ - }; - }; - }; -- - }; - }; ---- a/arch/powerpc/boot/dts/mpc8548cds.dts -+++ b/arch/powerpc/boot/dts/mpc8548cds.dts -@@ -16,6 +16,20 @@ - #address-cells = <1>; - #size-cells = <1>; - -+ aliases { -+ ethernet0 = &enet0; -+ ethernet1 = &enet1; -+/* -+ ethernet2 = &enet2; -+ ethernet3 = &enet3; -+*/ -+ serial0 = &serial0; -+ serial1 = &serial1; -+ pci0 = &pci0; -+ pci1 = &pci1; -+ pci2 = &pci2; -+ }; -+ - cpus { - #address-cells = <1>; - #size-cells = <0>; -@@ -63,7 +77,9 @@ - }; - - i2c@3000 { -- device_type = "i2c"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <0>; - compatible = "fsl-i2c"; - reg = <3000 100>; - interrupts = <2b 2>; -@@ -71,12 +87,23 @@ - dfsrr; - }; - -+ i2c@3100 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <1>; -+ compatible = "fsl-i2c"; -+ reg = <3100 100>; -+ interrupts = <2b 2>; -+ interrupt-parent = <&mpic>; -+ dfsrr; -+ }; -+ - mdio@24520 { - #address-cells = <1>; - #size-cells = <0>; -- device_type = "mdio"; -- compatible = "gianfar"; -+ compatible = "fsl,gianfar-mdio"; - reg = <24520 20>; -+ - phy0: ethernet-phy@0 { - interrupt-parent = <&mpic>; - interrupts = <5 1>; -@@ -103,9 +130,8 @@ - }; - }; - -- ethernet@24000 { -- #address-cells = <1>; -- #size-cells = <0>; -+ enet0: ethernet@24000 { -+ cell-index = <0>; - device_type = "network"; - model = "eTSEC"; - compatible = "gianfar"; -@@ -116,9 +142,8 @@ - phy-handle = <&phy0>; - }; - -- ethernet@25000 { -- #address-cells = <1>; -- #size-cells = <0>; -+ enet1: ethernet@25000 { -+ cell-index = <1>; - device_type = "network"; - model = "eTSEC"; - compatible = "gianfar"; -@@ -130,9 +155,8 @@ - }; - - /* eTSEC 3/4 are currently broken -- ethernet@26000 { -- #address-cells = <1>; -- #size-cells = <0>; -+ enet2: ethernet@26000 { -+ cell-index = <2>; - device_type = "network"; - model = "eTSEC"; - compatible = "gianfar"; -@@ -143,9 +167,8 @@ - phy-handle = <&phy2>; - }; - -- ethernet@27000 { -- #address-cells = <1>; -- #size-cells = <0>; -+ enet3: ethernet@27000 { -+ cell-index = <3>; - device_type = "network"; - model = "eTSEC"; - compatible = "gianfar"; -@@ -157,7 +180,8 @@ - }; - */ - -- serial@4500 { -+ serial0: serial@4500 { -+ cell-index = <0>; - device_type = "serial"; - compatible = "ns16550"; - reg = <4500 100>; // reg base, size -@@ -166,7 +190,8 @@ - interrupt-parent = <&mpic>; - }; - -- serial@4600 { -+ serial1: serial@4600 { -+ cell-index = <1>; - device_type = "serial"; - compatible = "ns16550"; - reg = <4600 100>; // reg base, size -@@ -193,7 +218,8 @@ - }; - }; - -- pci@e0008000 { -+ pci0: pci@e0008000 { -+ cell-index = <0>; - interrupt-map-mask = ; - interrupt-map = < - /* IDSEL 0x4 (PCIX Slot 2) */ -@@ -342,7 +368,8 @@ - }; - }; - -- pci@e0009000 { -+ pci1: pci@e0009000 { -+ cell-index = <1>; - interrupt-map-mask = ; - interrupt-map = < - -@@ -366,7 +393,8 @@ - device_type = "pci"; - }; - -- pcie@e000a000 { -+ pci2: pcie@e000a000 { -+ cell-index = <2>; - interrupt-map-mask = ; - interrupt-map = < - ---- a/arch/powerpc/boot/dts/mpc8555cds.dts -+++ b/arch/powerpc/boot/dts/mpc8555cds.dts -@@ -16,6 +16,15 @@ - #address-cells = <1>; - #size-cells = <1>; - -+ aliases { -+ ethernet0 = &enet0; -+ ethernet1 = &enet1; -+ serial0 = &serial0; -+ serial1 = &serial1; -+ pci0 = &pci0; -+ pci1 = &pci1; -+ }; -+ - cpus { - #address-cells = <1>; - #size-cells = <0>; -@@ -63,7 +72,9 @@ - }; - - i2c@3000 { -- device_type = "i2c"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <0>; - compatible = "fsl-i2c"; - reg = <3000 100>; - interrupts = <2b 2>; -@@ -74,9 +85,9 @@ - mdio@24520 { - #address-cells = <1>; - #size-cells = <0>; -- device_type = "mdio"; -- compatible = "gianfar"; -+ compatible = "fsl,gianfar-mdio"; - reg = <24520 20>; -+ - phy0: ethernet-phy@0 { - interrupt-parent = <&mpic>; - interrupts = <5 1>; -@@ -91,9 +102,8 @@ - }; - }; - -- ethernet@24000 { -- #address-cells = <1>; -- #size-cells = <0>; -+ enet0: ethernet@24000 { -+ cell-index = <0>; - device_type = "network"; - model = "TSEC"; - compatible = "gianfar"; -@@ -104,9 +114,8 @@ - phy-handle = <&phy0>; - }; - -- ethernet@25000 { -- #address-cells = <1>; -- #size-cells = <0>; -+ enet1: ethernet@25000 { -+ cell-index = <1>; - device_type = "network"; - model = "TSEC"; - compatible = "gianfar"; -@@ -117,7 +126,8 @@ - phy-handle = <&phy1>; - }; - -- serial@4500 { -+ serial0: serial@4500 { -+ cell-index = <0>; - device_type = "serial"; - compatible = "ns16550"; - reg = <4500 100>; // reg base, size -@@ -126,7 +136,8 @@ - interrupt-parent = <&mpic>; - }; - -- serial@4600 { -+ serial1: serial@4600 { -+ cell-index = <1>; - device_type = "serial"; - compatible = "ns16550"; - reg = <4600 100>; // reg base, size -@@ -183,7 +194,8 @@ - }; - }; - -- pci1: pci@e0008000 { -+ pci0: pci@e0008000 { -+ cell-index = <0>; - interrupt-map-mask = <1f800 0 0 7>; - interrupt-map = < - -@@ -250,11 +262,12 @@ - #interrupt-cells = <2>; - compatible = "chrp,iic"; - interrupts = <1>; -- interrupt-parent = <&pci1>; -+ interrupt-parent = <&pci0>; - }; - }; - -- pci@e0009000 { -+ pci1: pci@e0009000 { -+ cell-index = <1>; - interrupt-map-mask = ; - interrupt-map = < - ---- a/arch/powerpc/boot/dts/mpc8560ads.dts -+++ b/arch/powerpc/boot/dts/mpc8560ads.dts -@@ -16,6 +16,16 @@ - #address-cells = <1>; - #size-cells = <1>; - -+ aliases { -+ ethernet0 = &enet0; -+ ethernet1 = &enet1; -+ ethernet2 = &enet2; -+ ethernet3 = &enet3; -+ serial0 = &serial0; -+ serial1 = &serial1; -+ pci0 = &pci0; -+ }; -+ - cpus { - #address-cells = <1>; - #size-cells = <0>; -@@ -63,11 +73,11 @@ - }; - - mdio@24520 { -- device_type = "mdio"; -- compatible = "gianfar"; -- reg = <24520 20>; - #address-cells = <1>; - #size-cells = <0>; -+ compatible = "fsl,gianfar-mdio"; -+ reg = <24520 20>; -+ - phy0: ethernet-phy@0 { - interrupt-parent = <&mpic>; - interrupts = <5 1>; -@@ -94,36 +104,24 @@ - }; - }; - -- ethernet@24000 { -+ enet0: ethernet@24000 { -+ cell-index = <0>; - device_type = "network"; - model = "TSEC"; - compatible = "gianfar"; - reg = <24000 1000>; -- /* -- * address is deprecated and will be removed -- * in 2.6.25. Only recent versions of -- * U-Boot support local-mac-address, however. -- */ -- address = [ 00 00 00 00 00 00 ]; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <1d 2 1e 2 22 2>; - interrupt-parent = <&mpic>; - phy-handle = <&phy0>; - }; - -- ethernet@25000 { -- #address-cells = <1>; -- #size-cells = <0>; -+ enet1: ethernet@25000 { -+ cell-index = <1>; - device_type = "network"; - model = "TSEC"; - compatible = "gianfar"; - reg = <25000 1000>; -- /* -- * address is deprecated and will be removed -- * in 2.6.25. Only recent versions of -- * U-Boot support local-mac-address, however. -- */ -- address = [ 00 00 00 00 00 00 ]; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <23 2 24 2 28 2>; - interrupt-parent = <&mpic>; -@@ -174,7 +172,7 @@ - compatible = "fsl,mpc8560-cpm-pic", "fsl,cpm2-pic"; - }; - -- serial@91a00 { -+ serial0: serial@91a00 { - device_type = "serial"; - compatible = "fsl,mpc8560-scc-uart", - "fsl,cpm2-scc-uart"; -@@ -186,7 +184,7 @@ - interrupt-parent = <&cpmpic>; - }; - -- serial@91a20 { -+ serial1: serial@91a20 { - device_type = "serial"; - compatible = "fsl,mpc8560-scc-uart", - "fsl,cpm2-scc-uart"; -@@ -198,17 +196,11 @@ - interrupt-parent = <&cpmpic>; - }; - -- ethernet@91320 { -+ enet2: ethernet@91320 { - device_type = "network"; - compatible = "fsl,mpc8560-fcc-enet", - "fsl,cpm2-fcc-enet"; - reg = <91320 20 88500 100 913b0 1>; -- /* -- * mac-address is deprecated and will be removed -- * in 2.6.25. Only recent versions of -- * U-Boot support local-mac-address, however. -- */ -- mac-address = [ 00 00 00 00 00 00 ]; - local-mac-address = [ 00 00 00 00 00 00 ]; - fsl,cpm-command = <16200300>; - interrupts = <21 8>; -@@ -216,17 +208,11 @@ - phy-handle = <&phy2>; - }; - -- ethernet@91340 { -+ enet3: ethernet@91340 { - device_type = "network"; - compatible = "fsl,mpc8560-fcc-enet", - "fsl,cpm2-fcc-enet"; - reg = <91340 20 88600 100 913d0 1>; -- /* -- * mac-address is deprecated and will be removed -- * in 2.6.25. Only recent versions of -- * U-Boot support local-mac-address, however. -- */ -- mac-address = [ 00 00 00 00 00 00 ]; - local-mac-address = [ 00 00 00 00 00 00 ]; - fsl,cpm-command = <1a400300>; - interrupts = <22 8>; -@@ -236,7 +222,8 @@ - }; - }; - -- pci@e0008000 { -+ pci0: pci@e0008000 { -+ cell-index = <0>; - #interrupt-cells = <1>; - #size-cells = <2>; - #address-cells = <3>; ---- a/arch/powerpc/boot/dts/mpc8568mds.dts -+++ b/arch/powerpc/boot/dts/mpc8568mds.dts -@@ -20,6 +20,17 @@ - #address-cells = <1>; - #size-cells = <1>; - -+ aliases { -+ ethernet0 = &enet0; -+ ethernet1 = &enet1; -+ ethernet2 = &enet2; -+ ethernet3 = &enet3; -+ serial0 = &serial0; -+ serial1 = &serial1; -+ pci0 = &pci0; -+ pci1 = &pci1; -+ }; -+ - cpus { - #address-cells = <1>; - #size-cells = <0>; -@@ -74,7 +85,7 @@ - i2c@3000 { - #address-cells = <1>; - #size-cells = <0>; -- device_type = "i2c"; -+ cell-index = <0>; - compatible = "fsl-i2c"; - reg = <3000 100>; - interrupts = <2b 2>; -@@ -90,7 +101,7 @@ - i2c@3100 { - #address-cells = <1>; - #size-cells = <0>; -- device_type = "i2c"; -+ cell-index = <1>; - compatible = "fsl-i2c"; - reg = <3100 100>; - interrupts = <2b 2>; -@@ -101,9 +112,9 @@ - mdio@24520 { - #address-cells = <1>; - #size-cells = <0>; -- device_type = "mdio"; -- compatible = "gianfar"; -+ compatible = "fsl,gianfar-mdio"; - reg = <24520 20>; -+ - phy0: ethernet-phy@7 { - interrupt-parent = <&mpic>; - interrupts = <1 1>; -@@ -130,45 +141,32 @@ - }; - }; - -- ethernet@24000 { -- #address-cells = <1>; -- #size-cells = <0>; -+ enet0: ethernet@24000 { -+ cell-index = <0>; - device_type = "network"; - model = "eTSEC"; - compatible = "gianfar"; - reg = <24000 1000>; -- /* -- * mac-address is deprecated and will be removed -- * in 2.6.25. Only recent versions of -- * U-Boot support local-mac-address, however. -- */ -- mac-address = [ 00 00 00 00 00 00 ]; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <1d 2 1e 2 22 2>; - interrupt-parent = <&mpic>; - phy-handle = <&phy2>; - }; - -- ethernet@25000 { -- #address-cells = <1>; -- #size-cells = <0>; -+ enet1: ethernet@25000 { -+ cell-index = <1>; - device_type = "network"; - model = "eTSEC"; - compatible = "gianfar"; - reg = <25000 1000>; -- /* -- * mac-address is deprecated and will be removed -- * in 2.6.25. Only recent versions of -- * U-Boot support local-mac-address, however. -- */ -- mac-address = [ 00 00 00 00 00 00 ]; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <23 2 24 2 28 2>; - interrupt-parent = <&mpic>; - phy-handle = <&phy3>; - }; - -- serial@4500 { -+ serial0: serial@4500 { -+ cell-index = <0>; - device_type = "serial"; - compatible = "ns16550"; - reg = <4500 100>; -@@ -183,7 +181,8 @@ - fsl,has-rstcr; - }; - -- serial@4600 { -+ serial1: serial@4600 { -+ cell-index = <1>; - device_type = "serial"; - compatible = "ns16550"; - reg = <4600 100>; -@@ -318,45 +317,35 @@ - mode = "cpu"; - }; - -- ucc@2000 { -+ enet2: ucc@2000 { - device_type = "network"; - compatible = "ucc_geth"; - model = "UCC"; -+ cell-index = <1>; - device-id = <1>; - reg = <2000 200>; - interrupts = <20>; - interrupt-parent = <&qeic>; -- /* -- * mac-address is deprecated and will be removed -- * in 2.6.25. Only recent versions of -- * U-Boot support local-mac-address, however. -- */ -- mac-address = [ 00 00 00 00 00 00 ]; - local-mac-address = [ 00 00 00 00 00 00 ]; -- rx-clock = <0>; -- tx-clock = <20>; -+ rx-clock-name = "none"; -+ tx-clock-name = "clk16"; - pio-handle = <&pio1>; - phy-handle = <&phy0>; - phy-connection-type = "rgmii-id"; - }; - -- ucc@3000 { -+ enet3: ucc@3000 { - device_type = "network"; - compatible = "ucc_geth"; - model = "UCC"; -+ cell-index = <2>; - device-id = <2>; - reg = <3000 200>; - interrupts = <21>; - interrupt-parent = <&qeic>; -- /* -- * mac-address is deprecated and will be removed -- * in 2.6.25. Only recent versions of -- * U-Boot support local-mac-address, however. -- */ -- mac-address = [ 00 00 00 00 00 00 ]; - local-mac-address = [ 00 00 00 00 00 00 ]; -- rx-clock = <0>; -- tx-clock = <20>; -+ rx-clock-name = "none"; -+ tx-clock-name = "clk16"; - pio-handle = <&pio2>; - phy-handle = <&phy1>; - phy-connection-type = "rgmii-id"; -@@ -366,7 +355,6 @@ - #address-cells = <1>; - #size-cells = <0>; - reg = <2120 18>; -- device_type = "mdio"; - compatible = "ucc_geth_phy"; - - /* These are the same PHYs as on -@@ -410,7 +398,8 @@ - - }; - -- pci@e0008000 { -+ pci0: pci@e0008000 { -+ cell-index = <0>; - interrupt-map-mask = ; - interrupt-map = < - /* IDSEL 0x12 AD18 */ -@@ -440,7 +429,8 @@ - }; - - /* PCI Express */ -- pcie@e000a000 { -+ pci1: pcie@e000a000 { -+ cell-index = <2>; - interrupt-map-mask = ; - interrupt-map = < - ---- a/arch/powerpc/boot/dts/mpc8572ds.dts -+++ b/arch/powerpc/boot/dts/mpc8572ds.dts -@@ -15,6 +15,18 @@ - #address-cells = <1>; - #size-cells = <1>; - -+ aliases { -+ ethernet0 = &enet0; -+ ethernet1 = &enet1; -+ ethernet2 = &enet2; -+ ethernet3 = &enet3; -+ serial0 = &serial0; -+ serial1 = &serial1; -+ pci0 = &pci0; -+ pci1 = &pci1; -+ pci2 = &pci2; -+ }; -+ - cpus { - #address-cells = <1>; - #size-cells = <0>; -@@ -69,7 +81,9 @@ - }; - - i2c@3000 { -- device_type = "i2c"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <0>; - compatible = "fsl-i2c"; - reg = <3000 100>; - interrupts = <2b 2>; -@@ -78,7 +92,9 @@ - }; - - i2c@3100 { -- device_type = "i2c"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <1>; - compatible = "fsl-i2c"; - reg = <3100 100>; - interrupts = <2b 2>; -@@ -89,9 +105,9 @@ - mdio@24520 { - #address-cells = <1>; - #size-cells = <0>; -- device_type = "mdio"; -- compatible = "gianfar"; -+ compatible = "fsl,gianfar-mdio"; - reg = <24520 20>; -+ - phy0: ethernet-phy@0 { - interrupt-parent = <&mpic>; - interrupts = ; -@@ -114,9 +130,8 @@ - }; - }; - -- ethernet@24000 { -- #address-cells = <1>; -- #size-cells = <0>; -+ enet0: ethernet@24000 { -+ cell-index = <0>; - device_type = "network"; - model = "eTSEC"; - compatible = "gianfar"; -@@ -128,9 +143,8 @@ - phy-connection-type = "rgmii-id"; - }; - -- ethernet@25000 { -- #address-cells = <1>; -- #size-cells = <0>; -+ enet1: ethernet@25000 { -+ cell-index = <1>; - device_type = "network"; - model = "eTSEC"; - compatible = "gianfar"; -@@ -142,9 +156,8 @@ - phy-connection-type = "rgmii-id"; - }; - -- ethernet@26000 { -- #address-cells = <1>; -- #size-cells = <0>; -+ enet2: ethernet@26000 { -+ cell-index = <2>; - device_type = "network"; - model = "eTSEC"; - compatible = "gianfar"; -@@ -156,9 +169,8 @@ - phy-connection-type = "rgmii-id"; - }; - -- ethernet@27000 { -- #address-cells = <1>; -- #size-cells = <0>; -+ enet3: ethernet@27000 { -+ cell-index = <3>; - device_type = "network"; - model = "eTSEC"; - compatible = "gianfar"; -@@ -170,7 +182,8 @@ - phy-connection-type = "rgmii-id"; - }; - -- serial@4500 { -+ serial0: serial@4500 { -+ cell-index = <0>; - device_type = "serial"; - compatible = "ns16550"; - reg = <4500 100>; -@@ -179,7 +192,8 @@ - interrupt-parent = <&mpic>; - }; - -- serial@4600 { -+ serial1: serial@4600 { -+ cell-index = <1>; - device_type = "serial"; - compatible = "ns16550"; - reg = <4600 100>; -@@ -206,7 +220,8 @@ - }; - }; - -- pcie@ffe08000 { -+ pci0: pcie@ffe08000 { -+ cell-index = <0>; - compatible = "fsl,mpc8548-pcie"; - device_type = "pci"; - #interrupt-cells = <1>; -@@ -319,9 +334,9 @@ - - // IDSEL 0x1c USB - e000 0 0 1 &i8259 c 2 -- e100 0 0 1 &i8259 9 2 -- e200 0 0 1 &i8259 a 2 -- e300 0 0 1 &i8259 b 2 -+ e100 0 0 2 &i8259 9 2 -+ e200 0 0 3 &i8259 a 2 -+ e300 0 0 4 &i8259 b 2 - - // IDSEL 0x1d Audio - e800 0 0 1 &i8259 6 2 -@@ -415,7 +430,8 @@ - - }; - -- pcie@ffe09000 { -+ pci1: pcie@ffe09000 { -+ cell-index = <1>; - compatible = "fsl,mpc8548-pcie"; - device_type = "pci"; - #interrupt-cells = <1>; -@@ -451,7 +467,8 @@ - }; - }; - -- pcie@ffe0a000 { -+ pci2: pcie@ffe0a000 { -+ cell-index = <2>; - compatible = "fsl,mpc8548-pcie"; - device_type = "pci"; - #interrupt-cells = <1>; -@@ -464,6 +481,7 @@ - clock-frequency = <1fca055>; - interrupt-parent = <&mpic>; - interrupts = <1b 2>; -+ interrupt-map-mask = ; - interrupt-map = < - /* IDSEL 0x0 */ - 0000 0 0 1 &mpic 0 1 ---- a/arch/powerpc/boot/dts/mpc8610_hpcd.dts -+++ b/arch/powerpc/boot/dts/mpc8610_hpcd.dts -@@ -1,7 +1,7 @@ - /* - * MPC8610 HPCD Device Tree Source - * -- * Copyright 2007 Freescale Semiconductor Inc. -+ * Copyright 2007-2008 Freescale Semiconductor Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License Version 2 as published -@@ -15,6 +15,13 @@ - #address-cells = <1>; - #size-cells = <1>; - -+ aliases { -+ serial0 = &serial0; -+ serial1 = &serial1; -+ pci0 = &pci0; -+ pci1 = &pci1; -+ }; -+ - cpus { - #address-cells = <1>; - #size-cells = <0>; -@@ -42,33 +49,42 @@ - #size-cells = <1>; - #interrupt-cells = <2>; - device_type = "soc"; -+ compatible = "fsl,mpc8610-immr", "simple-bus"; - ranges = <0 e0000000 00100000>; - reg = ; - bus-frequency = <0>; - - i2c@3000 { -- device_type = "i2c"; -- compatible = "fsl-i2c"; - #address-cells = <1>; - #size-cells = <0>; -+ cell-index = <0>; -+ compatible = "fsl-i2c"; - reg = <3000 100>; - interrupts = <2b 2>; - interrupt-parent = <&mpic>; - dfsrr; -+ -+ cs4270:codec@4f { -+ compatible = "cirrus,cs4270"; -+ reg = <4f>; -+ /* MCLK source is a stand-alone oscillator */ -+ clock-frequency = ; -+ }; - }; - - i2c@3100 { -- device_type = "i2c"; -- compatible = "fsl-i2c"; - #address-cells = <1>; - #size-cells = <0>; -+ cell-index = <1>; -+ compatible = "fsl-i2c"; - reg = <3100 100>; - interrupts = <2b 2>; - interrupt-parent = <&mpic>; - dfsrr; - }; - -- serial@4500 { -+ serial0: serial@4500 { -+ cell-index = <0>; - device_type = "serial"; - compatible = "ns16550"; - reg = <4500 100>; -@@ -77,7 +93,8 @@ - interrupt-parent = <&mpic>; - }; - -- serial@4600 { -+ serial1: serial@4600 { -+ cell-index = <1>; - device_type = "serial"; - compatible = "ns16550"; - reg = <4600 100>; -@@ -86,7 +103,6 @@ - interrupt-parent = <&mpic>; - }; - -- - mpic: interrupt-controller@40000 { - clock-frequency = <0>; - interrupt-controller; -@@ -103,9 +119,113 @@ - reg = ; - fsl,has-rstcr; - }; -+ -+ i2s@16000 { -+ compatible = "fsl,mpc8610-ssi"; -+ cell-index = <0>; -+ reg = <16000 100>; -+ interrupt-parent = <&mpic>; -+ interrupts = <3e 2>; -+ fsl,mode = "i2s-slave"; -+ codec-handle = <&cs4270>; -+ }; -+ -+ ssi@16100 { -+ compatible = "fsl,mpc8610-ssi"; -+ cell-index = <1>; -+ reg = <16100 100>; -+ interrupt-parent = <&mpic>; -+ interrupts = <3f 2>; -+ }; -+ -+ dma@21300 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "fsl,mpc8610-dma", "fsl,eloplus-dma"; -+ cell-index = <0>; -+ reg = <21300 4>; /* DMA general status register */ -+ ranges = <0 21100 200>; -+ -+ dma-channel@0 { -+ compatible = "fsl,mpc8610-dma-channel", -+ "fsl,eloplus-dma-channel"; -+ cell-index = <0>; -+ reg = <0 80>; -+ interrupt-parent = <&mpic>; -+ interrupts = <14 2>; -+ }; -+ dma-channel@1 { -+ compatible = "fsl,mpc8610-dma-channel", -+ "fsl,eloplus-dma-channel"; -+ cell-index = <1>; -+ reg = <80 80>; -+ interrupt-parent = <&mpic>; -+ interrupts = <15 2>; -+ }; -+ dma-channel@2 { -+ compatible = "fsl,mpc8610-dma-channel", -+ "fsl,eloplus-dma-channel"; -+ cell-index = <2>; -+ reg = <100 80>; -+ interrupt-parent = <&mpic>; -+ interrupts = <16 2>; -+ }; -+ dma-channel@3 { -+ compatible = "fsl,mpc8610-dma-channel", -+ "fsl,eloplus-dma-channel"; -+ cell-index = <3>; -+ reg = <180 80>; -+ interrupt-parent = <&mpic>; -+ interrupts = <17 2>; -+ }; -+ }; -+ -+ dma@c300 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "fsl,mpc8610-dma", "fsl,mpc8540-dma"; -+ cell-index = <1>; -+ reg = ; /* DMA general status register */ -+ ranges = <0 c100 200>; -+ -+ dma-channel@0 { -+ compatible = "fsl,mpc8610-dma-channel", -+ "fsl,mpc8540-dma-channel"; -+ cell-index = <0>; -+ reg = <0 80>; -+ interrupt-parent = <&mpic>; -+ interrupts = <3c 2>; -+ }; -+ dma-channel@1 { -+ compatible = "fsl,mpc8610-dma-channel", -+ "fsl,mpc8540-dma-channel"; -+ cell-index = <1>; -+ reg = <80 80>; -+ interrupt-parent = <&mpic>; -+ interrupts = <3d 2>; -+ }; -+ dma-channel@2 { -+ compatible = "fsl,mpc8610-dma-channel", -+ "fsl,mpc8540-dma-channel"; -+ cell-index = <2>; -+ reg = <100 80>; -+ interrupt-parent = <&mpic>; -+ interrupts = <3e 2>; -+ }; -+ dma-channel@3 { -+ compatible = "fsl,mpc8610-dma-channel", -+ "fsl,mpc8540-dma-channel"; -+ cell-index = <3>; -+ reg = <180 80>; -+ interrupt-parent = <&mpic>; -+ interrupts = <3f 2>; -+ }; -+ }; -+ - }; - -- pci@e0008000 { -+ pci0: pci@e0008000 { -+ cell-index = <0>; - compatible = "fsl,mpc8610-pci"; - device_type = "pci"; - #interrupt-cells = <1>; -@@ -134,7 +254,8 @@ - >; - }; - -- pcie@e000a000 { -+ pci1: pcie@e000a000 { -+ cell-index = <1>; - compatible = "fsl,mpc8641-pcie"; - device_type = "pci"; - #interrupt-cells = <1>; ---- a/arch/powerpc/boot/dts/mpc8641_hpcn.dts -+++ b/arch/powerpc/boot/dts/mpc8641_hpcn.dts -@@ -16,6 +16,17 @@ - #address-cells = <1>; - #size-cells = <1>; - -+ aliases { -+ ethernet0 = &enet0; -+ ethernet1 = &enet1; -+ ethernet2 = &enet2; -+ ethernet3 = &enet3; -+ serial0 = &serial0; -+ serial1 = &serial1; -+ pci0 = &pci0; -+ pci1 = &pci1; -+ }; -+ - cpus { - #address-cells = <1>; - #size-cells = <0>; -@@ -49,16 +60,60 @@ - reg = <00000000 40000000>; // 1G at 0x0 - }; - -+ localbus@f8005000 { -+ #address-cells = <2>; -+ #size-cells = <1>; -+ compatible = "fsl,mpc8641-localbus", "simple-bus"; -+ reg = ; -+ interrupts = <13 2>; -+ interrupt-parent = <&mpic>; -+ -+ ranges = <0 0 ff800000 00800000 -+ 1 0 fe000000 01000000 -+ 2 0 f8200000 00100000 -+ 3 0 f8100000 00100000>; -+ -+ flash@0,0 { -+ compatible = "cfi-flash"; -+ reg = <0 0 00800000>; -+ bank-width = <2>; -+ device-width = <2>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ partition@0 { -+ label = "kernel"; -+ reg = <00000000 00300000>; -+ }; -+ partition@300000 { -+ label = "firmware b"; -+ reg = <00300000 00100000>; -+ read-only; -+ }; -+ partition@400000 { -+ label = "fs"; -+ reg = <00400000 00300000>; -+ }; -+ partition@700000 { -+ label = "firmware a"; -+ reg = <00700000 00100000>; -+ read-only; -+ }; -+ }; -+ }; -+ - soc8641@f8000000 { - #address-cells = <1>; - #size-cells = <1>; - device_type = "soc"; -+ compatible = "simple-bus"; - ranges = <00000000 f8000000 00100000>; - reg = ; // CCSRBAR - bus-frequency = <0>; - - i2c@3000 { -- device_type = "i2c"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <0>; - compatible = "fsl-i2c"; - reg = <3000 100>; - interrupts = <2b 2>; -@@ -67,7 +122,9 @@ - }; - - i2c@3100 { -- device_type = "i2c"; -+ #address-cells = <1>; -+ #size-cells = <0>; -+ cell-index = <1>; - compatible = "fsl-i2c"; - reg = <3100 100>; - interrupts = <2b 2>; -@@ -78,9 +135,9 @@ - mdio@24520 { - #address-cells = <1>; - #size-cells = <0>; -- device_type = "mdio"; -- compatible = "gianfar"; -+ compatible = "fsl,gianfar-mdio"; - reg = <24520 20>; -+ - phy0: ethernet-phy@0 { - interrupt-parent = <&mpic>; - interrupts = ; -@@ -107,19 +164,12 @@ - }; - }; - -- ethernet@24000 { -- #address-cells = <1>; -- #size-cells = <0>; -+ enet0: ethernet@24000 { -+ cell-index = <0>; - device_type = "network"; - model = "TSEC"; - compatible = "gianfar"; - reg = <24000 1000>; -- /* -- * mac-address is deprecated and will be removed -- * in 2.6.25. Only recent versions of -- * U-Boot support local-mac-address, however. -- */ -- mac-address = [ 00 00 00 00 00 00 ]; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <1d 2 1e 2 22 2>; - interrupt-parent = <&mpic>; -@@ -127,19 +177,12 @@ - phy-connection-type = "rgmii-id"; - }; - -- ethernet@25000 { -- #address-cells = <1>; -- #size-cells = <0>; -+ enet1: ethernet@25000 { -+ cell-index = <1>; - device_type = "network"; - model = "TSEC"; - compatible = "gianfar"; - reg = <25000 1000>; -- /* -- * mac-address is deprecated and will be removed -- * in 2.6.25. Only recent versions of -- * U-Boot support local-mac-address, however. -- */ -- mac-address = [ 00 00 00 00 00 00 ]; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <23 2 24 2 28 2>; - interrupt-parent = <&mpic>; -@@ -147,19 +190,12 @@ - phy-connection-type = "rgmii-id"; - }; - -- ethernet@26000 { -- #address-cells = <1>; -- #size-cells = <0>; -+ enet2: ethernet@26000 { -+ cell-index = <2>; - device_type = "network"; - model = "TSEC"; - compatible = "gianfar"; - reg = <26000 1000>; -- /* -- * mac-address is deprecated and will be removed -- * in 2.6.25. Only recent versions of -- * U-Boot support local-mac-address, however. -- */ -- mac-address = [ 00 00 00 00 00 00 ]; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <1F 2 20 2 21 2>; - interrupt-parent = <&mpic>; -@@ -167,26 +203,21 @@ - phy-connection-type = "rgmii-id"; - }; - -- ethernet@27000 { -- #address-cells = <1>; -- #size-cells = <0>; -+ enet3: ethernet@27000 { -+ cell-index = <3>; - device_type = "network"; - model = "TSEC"; - compatible = "gianfar"; - reg = <27000 1000>; -- /* -- * mac-address is deprecated and will be removed -- * in 2.6.25. Only recent versions of -- * U-Boot support local-mac-address, however. -- */ -- mac-address = [ 00 00 00 00 00 00 ]; - local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <25 2 26 2 27 2>; - interrupt-parent = <&mpic>; - phy-handle = <&phy3>; - phy-connection-type = "rgmii-id"; - }; -- serial@4500 { -+ -+ serial0: serial@4500 { -+ cell-index = <0>; - device_type = "serial"; - compatible = "ns16550"; - reg = <4500 100>; -@@ -195,7 +226,8 @@ - interrupt-parent = <&mpic>; - }; - -- serial@4600 { -+ serial1: serial@4600 { -+ cell-index = <1>; - device_type = "serial"; - compatible = "ns16550"; - reg = <4600 100>; -@@ -222,7 +254,8 @@ - }; - }; - -- pcie@f8008000 { -+ pci0: pcie@f8008000 { -+ cell-index = <0>; - compatible = "fsl,mpc8641-pcie"; - device_type = "pci"; - #interrupt-cells = <1>; -@@ -335,9 +368,9 @@ - - // IDSEL 0x1c USB - e000 0 0 1 &i8259 c 2 -- e100 0 0 1 &i8259 9 2 -- e200 0 0 1 &i8259 a 2 -- e300 0 0 1 &i8259 b 2 -+ e100 0 0 2 &i8259 9 2 -+ e200 0 0 3 &i8259 a 2 -+ e300 0 0 4 &i8259 b 2 - - // IDSEL 0x1d Audio - e800 0 0 1 &i8259 6 2 -@@ -430,7 +463,8 @@ - - }; - -- pcie@f8009000 { -+ pci1: pcie@f8009000 { -+ cell-index = <1>; - compatible = "fsl,mpc8641-pcie"; - device_type = "pci"; - #interrupt-cells = <1>; ---- a/arch/powerpc/boot/dts/mpc866ads.dts -+++ b/arch/powerpc/boot/dts/mpc866ads.dts -@@ -12,7 +12,7 @@ - - / { - model = "MPC866ADS"; -- compatible = "mpc8xx"; -+ compatible = "fsl,mpc866ads"; - #address-cells = <1>; - #size-cells = <1>; - -@@ -23,15 +23,15 @@ - PowerPC,866@0 { - device_type = "cpu"; - reg = <0>; -- d-cache-line-size = <20>; // 32 bytes -- i-cache-line-size = <20>; // 32 bytes -+ d-cache-line-size = <10>; // 16 bytes -+ i-cache-line-size = <10>; // 16 bytes - d-cache-size = <2000>; // L1, 8K - i-cache-size = <4000>; // L1, 16K - timebase-frequency = <0>; - bus-frequency = <0>; - clock-frequency = <0>; - interrupts = ; // decrementer interrupt -- interrupt-parent = <&Mpc8xx_pic>; -+ interrupt-parent = <&PIC>; - }; - }; - -@@ -40,107 +40,139 @@ - reg = <00000000 800000>; - }; - -- soc866@ff000000 { -+ localbus@ff000100 { -+ compatible = "fsl,mpc866-localbus", "fsl,pq1-localbus"; -+ #address-cells = <2>; -+ #size-cells = <1>; -+ reg = ; -+ -+ ranges = < -+ 1 0 ff080000 00008000 -+ 5 0 ff0a0000 00008000 -+ >; -+ -+ board-control@1,0 { -+ reg = <1 0 20 5 300 4>; -+ compatible = "fsl,mpc866ads-bcsr"; -+ }; -+ }; -+ -+ soc@ff000000 { - #address-cells = <1>; - #size-cells = <1>; - device_type = "soc"; - ranges = <0 ff000000 00100000>; - reg = ; - bus-frequency = <0>; -- mdio@e80 { -- device_type = "mdio"; -- compatible = "fs_enet"; -- reg = ; -+ -+ mdio@e00 { -+ compatible = "fsl,mpc866-fec-mdio", "fsl,pq1-fec-mdio"; -+ reg = ; - #address-cells = <1>; - #size-cells = <0>; -- phy: ethernet-phy@f { -+ PHY: ethernet-phy@f { - reg = ; - device_type = "ethernet-phy"; - }; - }; - -- fec@e00 { -+ ethernet@e00 { - device_type = "network"; -- compatible = "fs_enet"; -- model = "FEC"; -- device-id = <1>; -+ compatible = "fsl,mpc866-fec-enet", -+ "fsl,pq1-fec-enet"; - reg = ; -- mac-address = [ 00 00 0C 00 01 FD ]; -+ local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <3 1>; -- interrupt-parent = <&Mpc8xx_pic>; -- phy-handle = <&Phy>; -+ interrupt-parent = <&PIC>; -+ phy-handle = <&PHY>; -+ linux,network-index = <0>; - }; - -- mpc8xx_pic: pic@ff000000 { -+ PIC: pic@0 { - interrupt-controller; -- #address-cells = <0>; - #interrupt-cells = <2>; - reg = <0 24>; -- device_type = "mpc8xx-pic"; -- compatible = "CPM"; -+ compatible = "fsl,mpc866-pic", "fsl,pq1-pic"; - }; - -- cpm@ff000000 { -+ cpm@9c0 { - #address-cells = <1>; - #size-cells = <1>; -- device_type = "cpm"; -- model = "CPM"; -- ranges = <0 0 4000>; -- reg = <860 f0>; -- command-proc = <9c0>; -+ compatible = "fsl,mpc866-cpm", "fsl,cpm1"; -+ ranges; -+ reg = <9c0 40>; - brg-frequency = <0>; - interrupts = <0 2>; // cpm error interrupt -- interrupt-parent = <&Cpm_pic>; -+ interrupt-parent = <&CPM_PIC>; - -- cpm_pic: pic@930 { -+ muram@2000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges = <0 2000 2000>; -+ -+ data@0 { -+ compatible = "fsl,cpm-muram-data"; -+ reg = <0 1c00>; -+ }; -+ }; -+ -+ brg@9f0 { -+ compatible = "fsl,mpc866-brg", -+ "fsl,cpm1-brg", -+ "fsl,cpm-brg"; -+ reg = <9f0 10>; -+ clock-frequency = <0>; -+ }; -+ -+ CPM_PIC: pic@930 { - interrupt-controller; - #address-cells = <0>; -- #interrupt-cells = <2>; -+ #interrupt-cells = <1>; - interrupts = <5 2 0 2>; -- interrupt-parent = <&Mpc8xx_pic>; -+ interrupt-parent = <&PIC>; - reg = <930 20>; -- device_type = "cpm-pic"; -- compatible = "CPM"; -+ compatible = "fsl,mpc866-cpm-pic", -+ "fsl,cpm1-pic"; - }; - -- smc@a80 { -+ -+ serial@a80 { - device_type = "serial"; -- compatible = "cpm_uart"; -- model = "SMC"; -- device-id = <1>; -+ compatible = "fsl,mpc866-smc-uart", -+ "fsl,cpm1-smc-uart"; - reg = ; -- clock-setup = <00ffffff 0>; -- rx-clock = <1>; -- tx-clock = <1>; -- current-speed = <0>; -- interrupts = <4 3>; -- interrupt-parent = <&Cpm_pic>; -+ interrupts = <4>; -+ interrupt-parent = <&CPM_PIC>; -+ fsl,cpm-brg = <1>; -+ fsl,cpm-command = <0090>; - }; - -- smc@a90 { -+ serial@a90 { - device_type = "serial"; -- compatible = "cpm_uart"; -- model = "SMC"; -- device-id = <2>; -- reg = ; -- clock-setup = ; -- rx-clock = <2>; -- tx-clock = <2>; -- current-speed = <0>; -- interrupts = <3 3>; -- interrupt-parent = <&Cpm_pic>; -+ compatible = "fsl,mpc866-smc-uart", -+ "fsl,cpm1-smc-uart"; -+ reg = ; -+ interrupts = <3>; -+ interrupt-parent = <&CPM_PIC>; -+ fsl,cpm-brg = <2>; -+ fsl,cpm-command = <00d0>; - }; - -- scc@a00 { -+ ethernet@a00 { - device_type = "network"; -- compatible = "fs_enet"; -- model = "SCC"; -- device-id = <1>; -- reg = ; -- mac-address = [ 00 00 0C 00 03 FD ]; -- interrupts = <1e 3>; -- interrupt-parent = <&Cpm_pic>; -+ compatible = "fsl,mpc866-scc-enet", -+ "fsl,cpm1-scc-enet"; -+ reg = ; -+ local-mac-address = [ 00 00 00 00 00 00 ]; -+ interrupts = <1e>; -+ interrupt-parent = <&CPM_PIC>; -+ fsl,cpm-command = <0000>; -+ linux,network-index = <1>; - }; - }; - }; -+ -+ chosen { -+ linux,stdout-path = "/soc/cpm/serial@a80"; -+ }; - }; ---- /dev/null -+++ b/arch/powerpc/boot/dts/rainier.dts -@@ -0,0 +1,353 @@ -+/* -+ * Device Tree Source for AMCC Rainier -+ * -+ * Based on Sequoia code -+ * Copyright (c) 2007 MontaVista Software, Inc. -+ * -+ * FIXME: Draft only! -+ * -+ * 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. -+ * -+ */ -+ -+/ { -+ #address-cells = <2>; -+ #size-cells = <1>; -+ model = "amcc,rainier"; -+ compatible = "amcc,rainier"; -+ dcr-parent = <&/cpus/cpu@0>; -+ -+ aliases { -+ ethernet0 = &EMAC0; -+ ethernet1 = &EMAC1; -+ serial0 = &UART0; -+ serial1 = &UART1; -+ serial2 = &UART2; -+ serial3 = &UART3; -+ }; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ cpu@0 { -+ device_type = "cpu"; -+ model = "PowerPC,440GRx"; -+ reg = <0>; -+ clock-frequency = <0>; /* Filled in by zImage */ -+ timebase-frequency = <0>; /* Filled in by zImage */ -+ i-cache-line-size = <20>; -+ d-cache-line-size = <20>; -+ i-cache-size = <8000>; -+ d-cache-size = <8000>; -+ dcr-controller; -+ dcr-access-method = "native"; -+ }; -+ }; -+ -+ memory { -+ device_type = "memory"; -+ reg = <0 0 0>; /* Filled in by zImage */ -+ }; -+ -+ UIC0: interrupt-controller0 { -+ compatible = "ibm,uic-440grx","ibm,uic"; -+ interrupt-controller; -+ cell-index = <0>; -+ dcr-reg = <0c0 009>; -+ #address-cells = <0>; -+ #size-cells = <0>; -+ #interrupt-cells = <2>; -+ }; -+ -+ UIC1: interrupt-controller1 { -+ compatible = "ibm,uic-440grx","ibm,uic"; -+ interrupt-controller; -+ cell-index = <1>; -+ dcr-reg = <0d0 009>; -+ #address-cells = <0>; -+ #size-cells = <0>; -+ #interrupt-cells = <2>; -+ interrupts = <1e 4 1f 4>; /* cascade */ -+ interrupt-parent = <&UIC0>; -+ }; -+ -+ UIC2: interrupt-controller2 { -+ compatible = "ibm,uic-440grx","ibm,uic"; -+ interrupt-controller; -+ cell-index = <2>; -+ dcr-reg = <0e0 009>; -+ #address-cells = <0>; -+ #size-cells = <0>; -+ #interrupt-cells = <2>; -+ interrupts = <1c 4 1d 4>; /* cascade */ -+ interrupt-parent = <&UIC0>; -+ }; -+ -+ SDR0: sdr { -+ compatible = "ibm,sdr-440grx", "ibm,sdr-440ep"; -+ dcr-reg = <00e 002>; -+ }; -+ -+ CPR0: cpr { -+ compatible = "ibm,cpr-440grx", "ibm,cpr-440ep"; -+ dcr-reg = <00c 002>; -+ }; -+ -+ plb { -+ compatible = "ibm,plb-440grx", "ibm,plb4"; -+ #address-cells = <2>; -+ #size-cells = <1>; -+ ranges; -+ clock-frequency = <0>; /* Filled in by zImage */ -+ -+ SDRAM0: sdram { -+ compatible = "ibm,sdram-440grx", "ibm,sdram-44x-ddr2denali"; -+ dcr-reg = <010 2>; -+ }; -+ -+ DMA0: dma { -+ compatible = "ibm,dma-440grx", "ibm,dma-4xx"; -+ dcr-reg = <100 027>; -+ }; -+ -+ MAL0: mcmal { -+ compatible = "ibm,mcmal-440grx", "ibm,mcmal2"; -+ dcr-reg = <180 62>; -+ num-tx-chans = <2>; -+ num-rx-chans = <2>; -+ interrupt-parent = <&MAL0>; -+ interrupts = <0 1 2 3 4>; -+ #interrupt-cells = <1>; -+ #address-cells = <0>; -+ #size-cells = <0>; -+ interrupt-map = ; -+ interrupt-map-mask = ; -+ }; -+ -+ POB0: opb { -+ compatible = "ibm,opb-440grx", "ibm,opb"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges = <00000000 1 00000000 80000000 -+ 80000000 1 80000000 80000000>; -+ interrupt-parent = <&UIC1>; -+ interrupts = <7 4>; -+ clock-frequency = <0>; /* Filled in by zImage */ -+ -+ EBC0: ebc { -+ compatible = "ibm,ebc-440grx", "ibm,ebc"; -+ dcr-reg = <012 2>; -+ #address-cells = <2>; -+ #size-cells = <1>; -+ clock-frequency = <0>; /* Filled in by zImage */ -+ interrupts = <5 1>; -+ interrupt-parent = <&UIC1>; -+ -+ nor_flash@0,0 { -+ compatible = "amd,s29gl256n", "cfi-flash"; -+ bank-width = <2>; -+ reg = <0 000000 4000000>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ partition@0 { -+ label = "Kernel"; -+ reg = <0 180000>; -+ }; -+ partition@180000 { -+ label = "ramdisk"; -+ reg = <180000 200000>; -+ }; -+ partition@380000 { -+ label = "file system"; -+ reg = <380000 3aa0000>; -+ }; -+ partition@3e20000 { -+ label = "kozio"; -+ reg = <3e20000 140000>; -+ }; -+ partition@3f60000 { -+ label = "env"; -+ reg = <3f60000 40000>; -+ }; -+ partition@3fa0000 { -+ label = "u-boot"; -+ reg = <3fa0000 60000>; -+ }; -+ }; -+ -+ }; -+ -+ UART0: serial@ef600300 { -+ device_type = "serial"; -+ compatible = "ns16550"; -+ reg = ; -+ virtual-reg = ; -+ clock-frequency = <0>; /* Filled in by zImage */ -+ current-speed = <1c200>; -+ interrupt-parent = <&UIC0>; -+ interrupts = <0 4>; -+ }; -+ -+ UART1: serial@ef600400 { -+ device_type = "serial"; -+ compatible = "ns16550"; -+ reg = ; -+ virtual-reg = ; -+ clock-frequency = <0>; -+ current-speed = <0>; -+ interrupt-parent = <&UIC0>; -+ interrupts = <1 4>; -+ }; -+ -+ UART2: serial@ef600500 { -+ device_type = "serial"; -+ compatible = "ns16550"; -+ reg = ; -+ virtual-reg = ; -+ clock-frequency = <0>; -+ current-speed = <0>; -+ interrupt-parent = <&UIC1>; -+ interrupts = <3 4>; -+ }; -+ -+ UART3: serial@ef600600 { -+ device_type = "serial"; -+ compatible = "ns16550"; -+ reg = ; -+ virtual-reg = ; -+ clock-frequency = <0>; -+ current-speed = <0>; -+ interrupt-parent = <&UIC1>; -+ interrupts = <4 4>; -+ }; -+ -+ IIC0: i2c@ef600700 { -+ device_type = "i2c"; -+ compatible = "ibm,iic-440grx", "ibm,iic"; -+ reg = ; -+ interrupt-parent = <&UIC0>; -+ interrupts = <2 4>; -+ }; -+ -+ IIC1: i2c@ef600800 { -+ device_type = "i2c"; -+ compatible = "ibm,iic-440grx", "ibm,iic"; -+ reg = ; -+ interrupt-parent = <&UIC0>; -+ interrupts = <7 4>; -+ }; -+ -+ ZMII0: emac-zmii@ef600d00 { -+ device_type = "zmii-interface"; -+ compatible = "ibm,zmii-440grx", "ibm,zmii"; -+ reg = ; -+ }; -+ -+ RGMII0: emac-rgmii@ef601000 { -+ device_type = "rgmii-interface"; -+ compatible = "ibm,rgmii-440grx", "ibm,rgmii"; -+ reg = ; -+ has-mdio; -+ }; -+ -+ EMAC0: ethernet@ef600e00 { -+ linux,network-index = <0>; -+ device_type = "network"; -+ compatible = "ibm,emac-440grx", "ibm,emac-440epx", "ibm,emac4"; -+ interrupt-parent = <&EMAC0>; -+ interrupts = <0 1>; -+ #interrupt-cells = <1>; -+ #address-cells = <0>; -+ #size-cells = <0>; -+ interrupt-map = ; -+ reg = ; -+ local-mac-address = [000000000000]; -+ mal-device = <&MAL0>; -+ mal-tx-channel = <0>; -+ mal-rx-channel = <0>; -+ cell-index = <0>; -+ max-frame-size = <5dc>; -+ rx-fifo-size = <1000>; -+ tx-fifo-size = <800>; -+ phy-mode = "rgmii"; -+ phy-map = <00000000>; -+ zmii-device = <&ZMII0>; -+ zmii-channel = <0>; -+ rgmii-device = <&RGMII0>; -+ rgmii-channel = <0>; -+ has-inverted-stacr-oc; -+ has-new-stacr-staopc; -+ }; -+ -+ EMAC1: ethernet@ef600f00 { -+ linux,network-index = <1>; -+ device_type = "network"; -+ compatible = "ibm,emac-440grx", "ibm,emac-440epx", "ibm,emac4"; -+ interrupt-parent = <&EMAC1>; -+ interrupts = <0 1>; -+ #interrupt-cells = <1>; -+ #address-cells = <0>; -+ #size-cells = <0>; -+ interrupt-map = ; -+ reg = ; -+ local-mac-address = [000000000000]; -+ mal-device = <&MAL0>; -+ mal-tx-channel = <1>; -+ mal-rx-channel = <1>; -+ cell-index = <1>; -+ max-frame-size = <5dc>; -+ rx-fifo-size = <1000>; -+ tx-fifo-size = <800>; -+ phy-mode = "rgmii"; -+ phy-map = <00000000>; -+ zmii-device = <&ZMII0>; -+ zmii-channel = <1>; -+ rgmii-device = <&RGMII0>; -+ rgmii-channel = <1>; -+ has-inverted-stacr-oc; -+ has-new-stacr-staopc; -+ }; -+ }; -+ -+ PCI0: pci@1ec000000 { -+ device_type = "pci"; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ compatible = "ibm,plb440grx-pci", "ibm,plb-pci"; -+ primary; -+ reg = <1 eec00000 8 /* Config space access */ -+ 1 eed00000 4 /* IACK */ -+ 1 eed00000 4 /* Special cycle */ -+ 1 ef400000 40>; /* Internal registers */ -+ -+ /* Outbound ranges, one memory and one IO, -+ * later cannot be changed. Chip supports a second -+ * IO range but we don't use it for now -+ */ -+ ranges = <02000000 0 80000000 1 80000000 0 10000000 -+ 01000000 0 00000000 1 e8000000 0 00100000>; -+ -+ /* Inbound 2GB range starting at 0 */ -+ dma-ranges = <42000000 0 0 0 0 0 80000000>; -+ -+ /* All PCI interrupts are routed to IRQ 67 */ -+ interrupt-map-mask = <0000 0 0 0>; -+ interrupt-map = < 0000 0 0 0 &UIC2 3 8 >; -+ }; -+ }; -+ -+ chosen { -+ linux,stdout-path = "/plb/opb/serial@ef600300"; -+ bootargs = "console=ttyS0,115200"; -+ }; -+}; ---- a/arch/powerpc/boot/dts/sequoia.dts -+++ b/arch/powerpc/boot/dts/sequoia.dts -@@ -17,14 +17,24 @@ - #size-cells = <1>; - model = "amcc,sequoia"; - compatible = "amcc,sequoia"; -- dcr-parent = <&/cpus/PowerPC,440EPx@0>; -+ dcr-parent = <&/cpus/cpu@0>; -+ -+ aliases { -+ ethernet0 = &EMAC0; -+ ethernet1 = &EMAC1; -+ serial0 = &UART0; -+ serial1 = &UART1; -+ serial2 = &UART2; -+ serial3 = &UART3; -+ }; - - cpus { - #address-cells = <1>; - #size-cells = <0>; - -- PowerPC,440EPx@0 { -+ cpu@0 { - device_type = "cpu"; -+ model = "PowerPC,440EPx"; - reg = <0>; - clock-frequency = <0>; /* Filled in by zImage */ - timebase-frequency = <0>; /* Filled in by zImage */ -@@ -94,7 +104,6 @@ - clock-frequency = <0>; /* Filled in by zImage */ - - SDRAM0: sdram { -- device_type = "memory-controller"; - compatible = "ibm,sdram-440epx", "ibm,sdram-44x-ddr2denali"; - dcr-reg = <010 2>; - }; -@@ -122,6 +131,13 @@ - interrupt-map-mask = ; - }; - -+ USB1: usb@e0000400 { -+ compatible = "ohci-be"; -+ reg = <0 e0000400 60>; -+ interrupt-parent = <&UIC0>; -+ interrupts = <15 8>; -+ }; -+ - POB0: opb { - compatible = "ibm,opb-440epx", "ibm,opb"; - #address-cells = <1>; -@@ -308,6 +324,33 @@ - has-new-stacr-staopc; - }; - }; -+ -+ PCI0: pci@1ec000000 { -+ device_type = "pci"; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ compatible = "ibm,plb440epx-pci", "ibm,plb-pci"; -+ primary; -+ reg = <1 eec00000 8 /* Config space access */ -+ 1 eed00000 4 /* IACK */ -+ 1 eed00000 4 /* Special cycle */ -+ 1 ef400000 40>; /* Internal registers */ -+ -+ /* Outbound ranges, one memory and one IO, -+ * later cannot be changed. Chip supports a second -+ * IO range but we don't use it for now -+ */ -+ ranges = <02000000 0 80000000 1 80000000 0 10000000 -+ 01000000 0 00000000 1 e8000000 0 00100000>; -+ -+ /* Inbound 2GB range starting at 0 */ -+ dma-ranges = <42000000 0 0 0 0 0 80000000>; -+ -+ /* All PCI interrupts are routed to IRQ 67 */ -+ interrupt-map-mask = <0000 0 0 0>; -+ interrupt-map = < 0000 0 0 0 &UIC2 3 8 >; -+ }; - }; - - chosen { ---- /dev/null -+++ b/arch/powerpc/boot/dts/storcenter.dts -@@ -0,0 +1,138 @@ -+/* -+ * Device Tree Source for IOMEGA StorCenter -+ * -+ * Copyright 2007 Oyvind Repvik -+ * Copyright 2007 Jon Loeliger -+ * -+ * Based on the Kurobox DTS by G. Liakhovetski -+ * -+ * 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. -+ */ -+ -+/ { -+ model = "StorCenter"; -+ compatible = "storcenter"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ aliases { -+ serial0 = &serial0; -+ serial1 = &serial1; -+ pci0 = &pci0; -+ }; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ PowerPC,8241@0 { -+ device_type = "cpu"; -+ reg = <0>; -+ clock-frequency = ; /* Hz */ -+ timebase-frequency = ; /* Hz */ -+ bus-frequency = <0>; /* from bootwrapper */ -+ i-cache-line-size = ; /* bytes */ -+ d-cache-line-size = ; /* bytes */ -+ i-cache-size = <4000>; -+ d-cache-size = <4000>; -+ }; -+ }; -+ -+ memory { -+ device_type = "memory"; -+ reg = <00000000 04000000>; /* 64MB @ 0x0 */ -+ }; -+ -+ soc@fc000000 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ device_type = "soc"; -+ compatible = "fsl,mpc8241", "mpc10x"; -+ store-gathering = <0>; /* 0 == off, !0 == on */ -+ ranges = <0 fc000000 100000>; -+ reg = ; /* EUMB */ -+ bus-frequency = <0>; /* fixed by loader */ -+ -+ i2c@3000 { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ compatible = "fsl-i2c"; -+ reg = <3000 100>; -+ interrupts = <5 2>; -+ interrupt-parent = <&mpic>; -+ -+ rtc@68 { -+ compatible = "dallas,ds1337"; -+ reg = <68>; -+ }; -+ }; -+ -+ serial0: serial@4500 { -+ cell-index = <0>; -+ device_type = "serial"; -+ compatible = "ns16550"; -+ reg = <4500 20>; -+ clock-frequency = ; /* Hz */ -+ current-speed = ; -+ interrupts = <9 2>; -+ interrupt-parent = <&mpic>; -+ }; -+ -+ serial1: serial@4600 { -+ cell-index = <1>; -+ device_type = "serial"; -+ compatible = "ns16550"; -+ reg = <4600 20>; -+ clock-frequency = ; /* Hz */ -+ current-speed = ; -+ interrupts = ; -+ interrupt-parent = <&mpic>; -+ }; -+ -+ mpic: interrupt-controller@40000 { -+ #interrupt-cells = <2>; -+ device_type = "open-pic"; -+ compatible = "chrp,open-pic"; -+ interrupt-controller; -+ reg = <40000 40000>; -+ }; -+ -+ }; -+ -+ pci0: pci@fe800000 { -+ #address-cells = <3>; -+ #size-cells = <2>; -+ #interrupt-cells = <1>; -+ device_type = "pci"; -+ compatible = "mpc10x-pci"; -+ reg = ; -+ ranges = <01000000 0 0 fe000000 0 00c00000 -+ 02000000 0 80000000 80000000 0 70000000>; -+ bus-range = <0 ff>; -+ clock-frequency = ; /* Hz */ -+ interrupt-parent = <&mpic>; -+ interrupt-map-mask = ; -+ interrupt-map = < -+ /* IDSEL 13 - IDE */ -+ 6800 0 0 1 &mpic 0 1 -+ 6800 0 0 2 &mpic 0 1 -+ 6800 0 0 3 &mpic 0 1 -+ /* IDSEL 14 - USB */ -+ 7000 0 0 1 &mpic 0 1 -+ 7000 0 0 2 &mpic 0 1 -+ 7000 0 0 3 &mpic 0 1 -+ 7000 0 0 4 &mpic 0 1 -+ /* IDSEL 15 - ETH */ -+ 7800 0 0 1 &mpic 0 1 -+ 7800 0 0 2 &mpic 0 1 -+ 7800 0 0 3 &mpic 0 1 -+ 7800 0 0 4 &mpic 0 1 -+ >; -+ }; -+ -+ chosen { -+ linux,stdout-path = "/soc/serial@4500"; -+ }; -+}; ---- /dev/null -+++ b/arch/powerpc/boot/dts/taishan.dts -@@ -0,0 +1,383 @@ -+/* -+ * Device Tree Source for IBM/AMCC Taishan -+ * -+ * Copyright 2007 IBM Corp. -+ * Hugh Blemings based off code by -+ * Josh Boyer , David Gibson -+ * -+ * 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. -+ */ -+ -+/ { -+ #address-cells = <2>; -+ #size-cells = <1>; -+ model = "amcc,taishan"; -+ compatible = "amcc,taishan"; -+ dcr-parent = <&/cpus/cpu@0>; -+ -+ aliases { -+ ethernet0 = &EMAC2; -+ ethernet1 = &EMAC3; -+ serial0 = &UART0; -+ serial1 = &UART1; -+ }; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ cpu@0 { -+ device_type = "cpu"; -+ model = "PowerPC,440GX"; -+ reg = <0>; -+ clock-frequency = <2FAF0800>; // 800MHz -+ timebase-frequency = <0>; // Filled in by zImage -+ i-cache-line-size = <32>; -+ d-cache-line-size = <32>; -+ i-cache-size = <8000>; /* 32 kB */ -+ d-cache-size = <8000>; /* 32 kB */ -+ dcr-controller; -+ dcr-access-method = "native"; -+ }; -+ }; -+ -+ memory { -+ device_type = "memory"; -+ reg = <0 0 0>; // Filled in by zImage -+ }; -+ -+ -+ UICB0: interrupt-controller-base { -+ compatible = "ibm,uic-440gx", "ibm,uic"; -+ interrupt-controller; -+ cell-index = <3>; -+ dcr-reg = <200 009>; -+ #address-cells = <0>; -+ #size-cells = <0>; -+ #interrupt-cells = <2>; -+ }; -+ -+ -+ UIC0: interrupt-controller0 { -+ compatible = "ibm,uic-440gx", "ibm,uic"; -+ interrupt-controller; -+ cell-index = <0>; -+ dcr-reg = <0c0 009>; -+ #address-cells = <0>; -+ #size-cells = <0>; -+ #interrupt-cells = <2>; -+ interrupts = <01 4 00 4>; /* cascade - first non-critical */ -+ interrupt-parent = <&UICB0>; -+ -+ }; -+ -+ UIC1: interrupt-controller1 { -+ compatible = "ibm,uic-440gx", "ibm,uic"; -+ interrupt-controller; -+ cell-index = <1>; -+ dcr-reg = <0d0 009>; -+ #address-cells = <0>; -+ #size-cells = <0>; -+ #interrupt-cells = <2>; -+ interrupts = <03 4 02 4>; /* cascade */ -+ interrupt-parent = <&UICB0>; -+ }; -+ -+ UIC2: interrupt-controller2 { -+ compatible = "ibm,uic-440gx", "ibm,uic"; -+ interrupt-controller; -+ cell-index = <2>; /* was 1 */ -+ dcr-reg = <210 009>; -+ #address-cells = <0>; -+ #size-cells = <0>; -+ #interrupt-cells = <2>; -+ interrupts = <05 4 04 4>; /* cascade */ -+ interrupt-parent = <&UICB0>; -+ }; -+ -+ -+ CPC0: cpc { -+ compatible = "ibm,cpc-440gp"; -+ dcr-reg = <0b0 003 0e0 010>; -+ // FIXME: anything else? -+ }; -+ -+ plb { -+ compatible = "ibm,plb-440gx", "ibm,plb4"; -+ #address-cells = <2>; -+ #size-cells = <1>; -+ ranges; -+ clock-frequency = <9896800>; // 160MHz -+ -+ SDRAM0: memory-controller { -+ compatible = "ibm,sdram-440gp"; -+ dcr-reg = <010 2>; -+ // FIXME: anything else? -+ }; -+ -+ SRAM0: sram { -+ compatible = "ibm,sram-440gp"; -+ dcr-reg = <020 8 00a 1>; -+ }; -+ -+ DMA0: dma { -+ // FIXME: ??? -+ compatible = "ibm,dma-440gp"; -+ dcr-reg = <100 027>; -+ }; -+ -+ MAL0: mcmal { -+ compatible = "ibm,mcmal-440gx", "ibm,mcmal2"; -+ dcr-reg = <180 62>; -+ num-tx-chans = <4>; -+ num-rx-chans = <4>; -+ interrupt-parent = <&MAL0>; -+ interrupts = <0 1 2 3 4>; -+ #interrupt-cells = <1>; -+ #address-cells = <0>; -+ #size-cells = <0>; -+ interrupt-map = ; -+ interrupt-map-mask = ; -+ }; -+ -+ POB0: opb { -+ compatible = "ibm,opb-440gx", "ibm,opb"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ /* Wish there was a nicer way of specifying a full 32-bit -+ range */ -+ ranges = <00000000 1 00000000 80000000 -+ 80000000 1 80000000 80000000>; -+ dcr-reg = <090 00b>; -+ interrupt-parent = <&UIC1>; -+ interrupts = <7 4>; -+ clock-frequency = <4C4B400>; // 80MHz -+ -+ -+ EBC0: ebc { -+ compatible = "ibm,ebc-440gx", "ibm,ebc"; -+ dcr-reg = <012 2>; -+ #address-cells = <2>; -+ #size-cells = <1>; -+ clock-frequency = <4C4B400>; // 80MHz -+ -+ /* ranges property is supplied by zImage -+ * based on firmware's configuration of the -+ * EBC bridge */ -+ -+ interrupts = <5 4>; -+ interrupt-parent = <&UIC1>; -+ -+ /* TODO: Add other EBC devices */ -+ }; -+ -+ -+ -+ UART0: serial@40000200 { -+ device_type = "serial"; -+ compatible = "ns16550"; -+ reg = <40000200 8>; -+ virtual-reg = ; -+ clock-frequency = ; -+ current-speed = <1C200>; /* 115200 */ -+ interrupt-parent = <&UIC0>; -+ interrupts = <0 4>; -+ }; -+ -+ UART1: serial@40000300 { -+ device_type = "serial"; -+ compatible = "ns16550"; -+ reg = <40000300 8>; -+ virtual-reg = ; -+ clock-frequency = ; -+ current-speed = <1C200>; /* 115200 */ -+ interrupt-parent = <&UIC0>; -+ interrupts = <1 4>; -+ }; -+ -+ IIC0: i2c@40000400 { -+ /* FIXME */ -+ device_type = "i2c"; -+ compatible = "ibm,iic-440gp", "ibm,iic"; -+ reg = <40000400 14>; -+ interrupt-parent = <&UIC0>; -+ interrupts = <2 4>; -+ }; -+ IIC1: i2c@40000500 { -+ /* FIXME */ -+ device_type = "i2c"; -+ compatible = "ibm,iic-440gp", "ibm,iic"; -+ reg = <40000500 14>; -+ interrupt-parent = <&UIC0>; -+ interrupts = <3 4>; -+ }; -+ -+ GPIO0: gpio@40000700 { -+ /* FIXME */ -+ compatible = "ibm,gpio-440gp"; -+ reg = <40000700 20>; -+ }; -+ -+ ZMII0: emac-zmii@40000780 { -+ device_type = "zgmii-interface"; -+ compatible = "ibm,zmii-440gx", "ibm,zmii"; -+ reg = <40000780 c>; -+ }; -+ -+ RGMII0: emac-rgmii@40000790 { -+ device_type = "rgmii-interface"; -+ compatible = "ibm,rgmii"; -+ reg = <40000790 8>; -+ }; -+ -+ -+ EMAC0: ethernet@40000800 { -+ unused = <1>; -+ linux,network-index = <2>; -+ device_type = "network"; -+ compatible = "ibm,emac-440gx", "ibm,emac4"; -+ interrupt-parent = <&UIC1>; -+ interrupts = <1c 4 1d 4>; -+ reg = <40000800 70>; -+ local-mac-address = [000000000000]; // Filled in by zImage -+ mal-device = <&MAL0>; -+ mal-tx-channel = <0>; -+ mal-rx-channel = <0>; -+ cell-index = <0>; -+ max-frame-size = <5dc>; -+ rx-fifo-size = <1000>; -+ tx-fifo-size = <800>; -+ phy-mode = "rmii"; -+ phy-map = <00000001>; -+ zmii-device = <&ZMII0>; -+ zmii-channel = <0>; -+ }; -+ EMAC1: ethernet@40000900 { -+ unused = <1>; -+ linux,network-index = <3>; -+ device_type = "network"; -+ compatible = "ibm,emac-440gx", "ibm,emac4"; -+ interrupt-parent = <&UIC1>; -+ interrupts = <1e 4 1f 4>; -+ reg = <40000900 70>; -+ local-mac-address = [000000000000]; // Filled in by zImage -+ mal-device = <&MAL0>; -+ mal-tx-channel = <1>; -+ mal-rx-channel = <1>; -+ cell-index = <1>; -+ max-frame-size = <5dc>; -+ rx-fifo-size = <1000>; -+ tx-fifo-size = <800>; -+ phy-mode = "rmii"; -+ phy-map = <00000001>; -+ zmii-device = <&ZMII0>; -+ zmii-channel = <1>; -+ }; -+ -+ EMAC2: ethernet@40000c00 { -+ linux,network-index = <0>; -+ device_type = "network"; -+ compatible = "ibm,emac-440gx", "ibm,emac4"; -+ interrupt-parent = <&UIC2>; -+ interrupts = <0 4 1 4>; -+ reg = <40000c00 70>; -+ local-mac-address = [000000000000]; // Filled in by zImage -+ mal-device = <&MAL0>; -+ mal-tx-channel = <2>; -+ mal-rx-channel = <2>; -+ cell-index = <2>; -+ max-frame-size = <5dc>; -+ rx-fifo-size = <1000>; -+ tx-fifo-size = <800>; -+ phy-mode = "rgmii"; -+ phy-map = <00000001>; -+ rgmii-device = <&RGMII0>; -+ rgmii-channel = <0>; -+ zmii-device = <&ZMII0>; -+ zmii-channel = <2>; -+ }; -+ -+ EMAC3: ethernet@40000e00 { -+ linux,network-index = <1>; -+ device_type = "network"; -+ compatible = "ibm,emac-440gx", "ibm,emac4"; -+ interrupt-parent = <&UIC2>; -+ interrupts = <2 4 3 4>; -+ reg = <40000e00 70>; -+ local-mac-address = [000000000000]; // Filled in by zImage -+ mal-device = <&MAL0>; -+ mal-tx-channel = <3>; -+ mal-rx-channel = <3>; -+ cell-index = <3>; -+ max-frame-size = <5dc>; -+ rx-fifo-size = <1000>; -+ tx-fifo-size = <800>; -+ phy-mode = "rgmii"; -+ phy-map = <00000003>; -+ rgmii-device = <&RGMII0>; -+ rgmii-channel = <1>; -+ zmii-device = <&ZMII0>; -+ zmii-channel = <3>; -+ }; -+ -+ -+ GPT0: gpt@40000a00 { -+ /* FIXME */ -+ reg = <40000a00 d4>; -+ interrupt-parent = <&UIC0>; -+ interrupts = <12 4 13 4 14 4 15 4 16 4>; -+ }; -+ -+ }; -+ -+ PCIX0: pci@20ec00000 { -+ device_type = "pci"; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ compatible = "ibm,plb440gp-pcix", "ibm,plb-pcix"; -+ primary; -+ large-inbound-windows; -+ enable-msi-hole; -+ reg = <2 0ec00000 8 /* Config space access */ -+ 0 0 0 /* no IACK cycles */ -+ 2 0ed00000 4 /* Special cycles */ -+ 2 0ec80000 100 /* Internal registers */ -+ 2 0ec80100 fc>; /* Internal messaging registers */ -+ -+ /* Outbound ranges, one memory and one IO, -+ * later cannot be changed -+ */ -+ ranges = <02000000 0 80000000 00000003 80000000 0 80000000 -+ 01000000 0 00000000 00000002 08000000 0 00010000>; -+ -+ /* Inbound 2GB range starting at 0 */ -+ dma-ranges = <42000000 0 0 0 0 0 80000000>; -+ -+ interrupt-map-mask = ; -+ interrupt-map = < -+ /* IDSEL 1 */ -+ 0800 0 0 1 &UIC0 17 8 -+ 0800 0 0 2 &UIC0 18 8 -+ 0800 0 0 3 &UIC0 19 8 -+ 0800 0 0 4 &UIC0 1a 8 -+ -+ /* IDSEL 2 */ -+ 1000 0 0 1 &UIC0 18 8 -+ 1000 0 0 2 &UIC0 19 8 -+ 1000 0 0 3 &UIC0 1a 8 -+ 1000 0 0 4 &UIC0 17 8 -+ >; -+ }; -+ }; -+ -+ chosen { -+ linux,stdout-path = "/plb/opb/serial@40000300"; -+ }; -+}; ---- /dev/null -+++ b/arch/powerpc/boot/dts/tqm5200.dts -@@ -0,0 +1,184 @@ -+/* -+ * TQM5200 board Device Tree Source -+ * -+ * Copyright (C) 2007 Semihalf -+ * Marian Balakowicz -+ * -+ * 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. -+ */ -+ -+/* -+ * WARNING: Do not depend on this tree layout remaining static just yet. -+ * The MPC5200 device tree conventions are still in flux -+ * Keep an eye on the linuxppc-dev mailing list for more details -+ */ -+ -+/ { -+ model = "tqc,tqm5200"; -+ compatible = "tqc,tqm5200"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ PowerPC,5200@0 { -+ device_type = "cpu"; -+ reg = <0>; -+ d-cache-line-size = <20>; -+ i-cache-line-size = <20>; -+ d-cache-size = <4000>; // L1, 16K -+ i-cache-size = <4000>; // L1, 16K -+ timebase-frequency = <0>; // from bootloader -+ bus-frequency = <0>; // from bootloader -+ clock-frequency = <0>; // from bootloader -+ }; -+ }; -+ -+ memory { -+ device_type = "memory"; -+ reg = <00000000 04000000>; // 64MB -+ }; -+ -+ soc5200@f0000000 { -+ model = "fsl,mpc5200"; -+ compatible = "fsl,mpc5200"; -+ revision = ""; // from bootloader -+ device_type = "soc"; -+ ranges = <0 f0000000 0000c000>; -+ reg = ; -+ bus-frequency = <0>; // from bootloader -+ system-frequency = <0>; // from bootloader -+ -+ cdm@200 { -+ compatible = "mpc5200-cdm"; -+ reg = <200 38>; -+ }; -+ -+ mpc5200_pic: pic@500 { -+ // 5200 interrupts are encoded into two levels; -+ interrupt-controller; -+ #interrupt-cells = <3>; -+ compatible = "mpc5200-pic"; -+ reg = <500 80>; -+ }; -+ -+ gpt@600 { // General Purpose Timer -+ compatible = "fsl,mpc5200-gpt"; -+ reg = <600 10>; -+ interrupts = <1 9 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ fsl,has-wdt; -+ }; -+ -+ gpio@b00 { -+ compatible = "mpc5200-gpio"; -+ reg = ; -+ interrupts = <1 7 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ }; -+ -+ usb@1000 { -+ compatible = "mpc5200-ohci","ohci-be"; -+ reg = <1000 ff>; -+ interrupts = <2 6 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ }; -+ -+ dma-controller@1200 { -+ compatible = "mpc5200-bestcomm"; -+ reg = <1200 80>; -+ interrupts = <3 0 0 3 1 0 3 2 0 3 3 0 -+ 3 4 0 3 5 0 3 6 0 3 7 0 -+ 3 8 0 3 9 0 3 a 0 3 b 0 -+ 3 c 0 3 d 0 3 e 0 3 f 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ }; -+ -+ xlb@1f00 { -+ compatible = "mpc5200-xlb"; -+ reg = <1f00 100>; -+ }; -+ -+ serial@2000 { // PSC1 -+ device_type = "serial"; -+ compatible = "mpc5200-psc-uart"; -+ port-number = <0>; // Logical port assignment -+ reg = <2000 100>; -+ interrupts = <2 1 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ }; -+ -+ serial@2200 { // PSC2 -+ device_type = "serial"; -+ compatible = "mpc5200-psc-uart"; -+ port-number = <1>; // Logical port assignment -+ reg = <2200 100>; -+ interrupts = <2 2 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ }; -+ -+ serial@2400 { // PSC3 -+ device_type = "serial"; -+ compatible = "mpc5200-psc-uart"; -+ port-number = <2>; // Logical port assignment -+ reg = <2400 100>; -+ interrupts = <2 3 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ }; -+ -+ ethernet@3000 { -+ device_type = "network"; -+ compatible = "mpc5200-fec"; -+ reg = <3000 800>; -+ local-mac-address = [ 00 00 00 00 00 00 ]; /* Filled in by U-Boot */ -+ interrupts = <2 5 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ }; -+ -+ ata@3a00 { -+ compatible = "mpc5200-ata"; -+ reg = <3a00 100>; -+ interrupts = <2 7 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ }; -+ -+ i2c@3d40 { -+ compatible = "mpc5200-i2c","fsl-i2c"; -+ reg = <3d40 40>; -+ interrupts = <2 10 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ fsl5200-clocking; -+ }; -+ -+ sram@8000 { -+ compatible = "mpc5200-sram"; -+ reg = <8000 4000>; -+ }; -+ }; -+ -+ pci@f0000d00 { -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ device_type = "pci"; -+ compatible = "fsl,mpc5200-pci"; -+ reg = ; -+ interrupt-map-mask = ; -+ interrupt-map = ; -+ clock-frequency = <0>; // From boot loader -+ interrupts = <2 8 0 2 9 0 2 a 0>; -+ interrupt-parent = <&mpc5200_pic>; -+ bus-range = <0 0>; -+ ranges = <42000000 0 80000000 80000000 0 10000000 -+ 02000000 0 90000000 90000000 0 10000000 -+ 01000000 0 00000000 a0000000 0 01000000>; -+ }; -+}; ---- a/arch/powerpc/boot/dts/walnut.dts -+++ b/arch/powerpc/boot/dts/walnut.dts -@@ -14,14 +14,21 @@ - #size-cells = <1>; - model = "ibm,walnut"; - compatible = "ibm,walnut"; -- dcr-parent = <&/cpus/PowerPC,405GP@0>; -+ dcr-parent = <&/cpus/cpu@0>; -+ -+ aliases { -+ ethernet0 = &EMAC; -+ serial0 = &UART0; -+ serial1 = &UART1; -+ }; - - cpus { - #address-cells = <1>; - #size-cells = <0>; - -- PowerPC,405GP@0 { -+ cpu@0 { - device_type = "cpu"; -+ model = "PowerPC,405GP"; - reg = <0>; - clock-frequency = ; /* Filled in by zImage */ - timebase-frequency = <0>; /* Filled in by zImage */ -@@ -168,9 +175,10 @@ - }; - }; - -- ds1743@1,0 { -+ nvram@1,0 { - /* NVRAM and RTC */ -- compatible = "ds1743"; -+ compatible = "ds1743-nvram"; -+ #bytes = <2000>; - reg = <1 0 2000>; - }; - -@@ -190,6 +198,45 @@ - virtual-reg = ; - }; - }; -+ -+ PCI0: pci@ec000000 { -+ device_type = "pci"; -+ #interrupt-cells = <1>; -+ #size-cells = <2>; -+ #address-cells = <3>; -+ compatible = "ibm,plb405gp-pci", "ibm,plb-pci"; -+ primary; -+ reg = ; /* Internal registers */ -+ -+ /* Outbound ranges, one memory and one IO, -+ * later cannot be changed. Chip supports a second -+ * IO range but we don't use it for now -+ */ -+ ranges = <02000000 0 80000000 80000000 0 20000000 -+ 01000000 0 00000000 e8000000 0 00010000>; -+ -+ /* Inbound 2GB range starting at 0 */ -+ dma-ranges = <42000000 0 0 0 0 80000000>; -+ -+ /* Walnut has all 4 IRQ pins tied together per slot */ -+ interrupt-map-mask = ; -+ interrupt-map = < -+ /* IDSEL 1 */ -+ 0800 0 0 0 &UIC0 1c 8 -+ -+ /* IDSEL 2 */ -+ 1000 0 0 0 &UIC0 1d 8 -+ -+ /* IDSEL 3 */ -+ 1800 0 0 0 &UIC0 1e 8 -+ -+ /* IDSEL 4 */ -+ 2000 0 0 0 &UIC0 1f 8 -+ >; -+ }; - }; - - chosen { ---- /dev/null -+++ b/arch/powerpc/boot/dts/warp.dts -@@ -0,0 +1,239 @@ -+/* -+ * Device Tree Source for PIKA Warp -+ * -+ * Copyright (c) 2008 PIKA Technologies -+ * Sean MacLennan -+ * -+ * 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. -+ */ -+ -+/ { -+ #address-cells = <2>; -+ #size-cells = <1>; -+ model = "pika,warp"; -+ compatible = "pika,warp"; -+ dcr-parent = <&/cpus/cpu@0>; -+ -+ aliases { -+ ethernet0 = &EMAC0; -+ serial0 = &UART0; -+ }; -+ -+ cpus { -+ #address-cells = <1>; -+ #size-cells = <0>; -+ -+ cpu@0 { -+ device_type = "cpu"; -+ model = "PowerPC,440EP"; -+ reg = <0>; -+ clock-frequency = <0>; /* Filled in by zImage */ -+ timebase-frequency = <0>; /* Filled in by zImage */ -+ i-cache-line-size = <20>; -+ d-cache-line-size = <20>; -+ i-cache-size = <8000>; -+ d-cache-size = <8000>; -+ dcr-controller; -+ dcr-access-method = "native"; -+ }; -+ }; -+ -+ memory { -+ device_type = "memory"; -+ reg = <0 0 0>; /* Filled in by zImage */ -+ }; -+ -+ UIC0: interrupt-controller0 { -+ compatible = "ibm,uic-440ep","ibm,uic"; -+ interrupt-controller; -+ cell-index = <0>; -+ dcr-reg = <0c0 009>; -+ #address-cells = <0>; -+ #size-cells = <0>; -+ #interrupt-cells = <2>; -+ }; -+ -+ UIC1: interrupt-controller1 { -+ compatible = "ibm,uic-440ep","ibm,uic"; -+ interrupt-controller; -+ cell-index = <1>; -+ dcr-reg = <0d0 009>; -+ #address-cells = <0>; -+ #size-cells = <0>; -+ #interrupt-cells = <2>; -+ interrupts = <1e 4 1f 4>; /* cascade */ -+ interrupt-parent = <&UIC0>; -+ }; -+ -+ SDR0: sdr { -+ compatible = "ibm,sdr-440ep"; -+ dcr-reg = <00e 002>; -+ }; -+ -+ CPR0: cpr { -+ compatible = "ibm,cpr-440ep"; -+ dcr-reg = <00c 002>; -+ }; -+ -+ plb { -+ compatible = "ibm,plb-440ep", "ibm,plb-440gp", "ibm,plb4"; -+ #address-cells = <2>; -+ #size-cells = <1>; -+ ranges; -+ clock-frequency = <0>; /* Filled in by zImage */ -+ -+ SDRAM0: sdram { -+ compatible = "ibm,sdram-440ep", "ibm,sdram-405gp"; -+ dcr-reg = <010 2>; -+ }; -+ -+ DMA0: dma { -+ compatible = "ibm,dma-440ep", "ibm,dma-440gp"; -+ dcr-reg = <100 027>; -+ }; -+ -+ MAL0: mcmal { -+ compatible = "ibm,mcmal-440ep", "ibm,mcmal-440gp", "ibm,mcmal"; -+ dcr-reg = <180 62>; -+ num-tx-chans = <4>; -+ num-rx-chans = <2>; -+ interrupt-parent = <&MAL0>; -+ interrupts = <0 1 2 3 4>; -+ #interrupt-cells = <1>; -+ #address-cells = <0>; -+ #size-cells = <0>; -+ interrupt-map = ; -+ }; -+ -+ POB0: opb { -+ compatible = "ibm,opb-440ep", "ibm,opb-440gp", "ibm,opb"; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ ranges = <00000000 0 00000000 80000000 -+ 80000000 0 80000000 80000000>; -+ interrupt-parent = <&UIC1>; -+ interrupts = <7 4>; -+ clock-frequency = <0>; /* Filled in by zImage */ -+ -+ EBC0: ebc { -+ compatible = "ibm,ebc-440ep", "ibm,ebc-440gp", "ibm,ebc"; -+ dcr-reg = <012 2>; -+ #address-cells = <2>; -+ #size-cells = <1>; -+ clock-frequency = <0>; /* Filled in by zImage */ -+ interrupts = <5 1>; -+ interrupt-parent = <&UIC1>; -+ -+ fpga@2,0 { -+ compatible = "pika,fpga"; -+ reg = <2 0 2200>; -+ interrupts = <18 8>; -+ interrupt-parent = <&UIC0>; -+ }; -+ -+ nor_flash@0,0 { -+ compatible = "amd,s29gl512n", "cfi-flash"; -+ bank-width = <2>; -+ reg = <0 0 4000000>; -+ #address-cells = <1>; -+ #size-cells = <1>; -+ partition@0 { -+ label = "kernel"; -+ reg = <0 180000>; -+ }; -+ partition@180000 { -+ label = "root"; -+ reg = <180000 3480000>; -+ }; -+ partition@3600000 { -+ label = "user"; -+ reg = <3600000 900000>; -+ }; -+ partition@3f00000 { -+ label = "fpga"; -+ reg = <3f00000 40000>; -+ }; -+ partition@3f40000 { -+ label = "env"; -+ reg = <3f40000 40000>; -+ }; -+ partition@3f80000 { -+ label = "u-boot"; -+ reg = <3f80000 80000>; -+ }; -+ }; -+ }; -+ -+ UART0: serial@ef600300 { -+ device_type = "serial"; -+ compatible = "ns16550"; -+ reg = ; -+ virtual-reg = ; -+ clock-frequency = <0>; /* Filled in by zImage */ -+ current-speed = <1c200>; -+ interrupt-parent = <&UIC0>; -+ interrupts = <0 4>; -+ }; -+ -+ IIC0: i2c@ef600700 { -+ compatible = "ibm,iic-440ep", "ibm,iic-440gp", "ibm,iic"; -+ reg = ; -+ interrupt-parent = <&UIC0>; -+ interrupts = <2 4>; -+ }; -+ -+ GPIO0: gpio@ef600b00 { -+ compatible = "ibm,gpio-440ep"; -+ reg = ; -+ }; -+ -+ GPIO1: gpio@ef600c00 { -+ compatible = "ibm,gpio-440ep"; -+ reg = ; -+ }; -+ -+ ZMII0: emac-zmii@ef600d00 { -+ compatible = "ibm,zmii-440ep", "ibm,zmii-440gp", "ibm,zmii"; -+ reg = ; -+ }; -+ -+ EMAC0: ethernet@ef600e00 { -+ linux,network-index = <0>; -+ device_type = "network"; -+ compatible = "ibm,emac-440ep", "ibm,emac-440gp", "ibm,emac"; -+ interrupt-parent = <&UIC1>; -+ interrupts = <1c 4 1d 4>; -+ reg = ; -+ local-mac-address = [000000000000]; -+ mal-device = <&MAL0>; -+ mal-tx-channel = <0 1>; -+ mal-rx-channel = <0>; -+ cell-index = <0>; -+ max-frame-size = <5dc>; -+ rx-fifo-size = <1000>; -+ tx-fifo-size = <800>; -+ phy-mode = "rmii"; -+ phy-map = <00000000>; -+ zmii-device = <&ZMII0>; -+ zmii-channel = <0>; -+ }; -+ -+ usb@ef601000 { -+ compatible = "ohci-be"; -+ reg = ; -+ interrupts = <8 1 9 1>; -+ interrupt-parent = < &UIC1 >; -+ }; -+ }; -+ }; -+ -+ chosen { -+ linux,stdout-path = "/plb/opb/serial@ef600300"; -+ }; -+}; ---- a/arch/powerpc/boot/ebony.c -+++ b/arch/powerpc/boot/ebony.c -@@ -31,66 +31,6 @@ - - static u8 *ebony_mac0, *ebony_mac1; - --/* Calculate 440GP clocks */ --void ibm440gp_fixup_clocks(unsigned int sysclk, unsigned int ser_clk) --{ -- u32 sys0 = mfdcr(DCRN_CPC0_SYS0); -- u32 cr0 = mfdcr(DCRN_CPC0_CR0); -- u32 cpu, plb, opb, ebc, tb, uart0, uart1, m; -- u32 opdv = CPC0_SYS0_OPDV(sys0); -- u32 epdv = CPC0_SYS0_EPDV(sys0); -- -- if (sys0 & CPC0_SYS0_BYPASS) { -- /* Bypass system PLL */ -- cpu = plb = sysclk; -- } else { -- if (sys0 & CPC0_SYS0_EXTSL) -- /* PerClk */ -- m = CPC0_SYS0_FWDVB(sys0) * opdv * epdv; -- else -- /* CPU clock */ -- m = CPC0_SYS0_FBDV(sys0) * CPC0_SYS0_FWDVA(sys0); -- cpu = sysclk * m / CPC0_SYS0_FWDVA(sys0); -- plb = sysclk * m / CPC0_SYS0_FWDVB(sys0); -- } -- -- opb = plb / opdv; -- ebc = opb / epdv; -- -- /* FIXME: Check if this is for all 440GP, or just Ebony */ -- if ((mfpvr() & 0xf0000fff) == 0x40000440) -- /* Rev. B 440GP, use external system clock */ -- tb = sysclk; -- else -- /* Rev. C 440GP, errata force us to use internal clock */ -- tb = cpu; -- -- if (cr0 & CPC0_CR0_U0EC) -- /* External UART clock */ -- uart0 = ser_clk; -- else -- /* Internal UART clock */ -- uart0 = plb / CPC0_CR0_UDIV(cr0); -- -- if (cr0 & CPC0_CR0_U1EC) -- /* External UART clock */ -- uart1 = ser_clk; -- else -- /* Internal UART clock */ -- uart1 = plb / CPC0_CR0_UDIV(cr0); -- -- printf("PPC440GP: SysClk = %dMHz (%x)\n\r", -- (sysclk + 500000) / 1000000, sysclk); -- -- dt_fixup_cpu_clocks(cpu, tb, 0); -- -- dt_fixup_clock("/plb", plb); -- dt_fixup_clock("/plb/opb", opb); -- dt_fixup_clock("/plb/opb/ebc", ebc); -- dt_fixup_clock("/plb/opb/serial@40000200", uart0); -- dt_fixup_clock("/plb/opb/serial@40000300", uart1); --} -- - #define EBONY_FPGA_PATH "/plb/opb/ebc/fpga" - #define EBONY_FPGA_FLASH_SEL 0x01 - #define EBONY_SMALL_FLASH_PATH "/plb/opb/ebc/small-flash" -@@ -134,7 +74,7 @@ static void ebony_fixups(void) - unsigned long sysclk = 33000000; - - ibm440gp_fixup_clocks(sysclk, 6 * 1843200); -- ibm4xx_fixup_memsize(); -+ ibm4xx_sdram_fixup_memsize(); - dt_fixup_mac_addresses(ebony_mac0, ebony_mac1); - ibm4xx_fixup_ebc_ranges("/plb/opb/ebc"); - ebony_flashsel_fixup(); -@@ -146,6 +86,6 @@ void ebony_init(void *mac0, void *mac1) - platform_ops.exit = ibm44x_dbcr_reset; - ebony_mac0 = mac0; - ebony_mac1 = mac1; -- ft_init(_dtb_start, _dtb_end - _dtb_start, 32); -+ fdt_init(_dtb_start); - serial_console_init(); - } ---- /dev/null -+++ b/arch/powerpc/boot/ep405.c -@@ -0,0 +1,74 @@ -+/* -+ * Embedded Planet EP405 with PlanetCore firmware -+ * -+ * (c) Benjamin Herrenschmidt , IBM Corp,\ -+ * -+ * Based on ep88xc.c by -+ * -+ * Scott Wood -+ * -+ * Copyright (c) 2007 Freescale Semiconductor, Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include "ops.h" -+#include "stdio.h" -+#include "planetcore.h" -+#include "dcr.h" -+#include "4xx.h" -+#include "io.h" -+ -+static char *table; -+static u64 mem_size; -+ -+static void platform_fixups(void) -+{ -+ u64 val; -+ void *nvrtc; -+ -+ dt_fixup_memory(0, mem_size); -+ planetcore_set_mac_addrs(table); -+ -+ if (!planetcore_get_decimal(table, PLANETCORE_KEY_CRYSTAL_HZ, &val)) { -+ printf("No PlanetCore crystal frequency key.\r\n"); -+ return; -+ } -+ ibm405gp_fixup_clocks(val, 0xa8c000); -+ ibm4xx_quiesce_eth((u32 *)0xef600800, NULL); -+ ibm4xx_fixup_ebc_ranges("/plb/ebc"); -+ -+ if (!planetcore_get_decimal(table, PLANETCORE_KEY_KB_NVRAM, &val)) { -+ printf("No PlanetCore NVRAM size key.\r\n"); -+ return; -+ } -+ nvrtc = finddevice("/plb/ebc/nvrtc@4,200000"); -+ if (nvrtc != NULL) { -+ u32 reg[3] = { 4, 0x200000, 0}; -+ getprop(nvrtc, "reg", reg, 3); -+ reg[2] = (val << 10) & 0xffffffff; -+ setprop(nvrtc, "reg", reg, 3); -+ } -+} -+ -+void platform_init(unsigned long r3, unsigned long r4, unsigned long r5, -+ unsigned long r6, unsigned long r7) -+{ -+ table = (char *)r3; -+ planetcore_prepare_table(table); -+ -+ if (!planetcore_get_decimal(table, PLANETCORE_KEY_MB_RAM, &mem_size)) -+ return; -+ -+ mem_size *= 1024 * 1024; -+ simple_alloc_init(_end, mem_size - (unsigned long)_end, 32, 64); -+ -+ fdt_init(_dtb_start); -+ -+ planetcore_set_stdout_path(table); -+ -+ serial_console_init(); -+ platform_ops.fixups = platform_fixups; -+} ---- /dev/null -+++ b/arch/powerpc/boot/ep8248e.c -@@ -0,0 +1,55 @@ -+/* -+ * Embedded Planet EP8248E with PlanetCore firmware -+ * -+ * Author: Scott Wood -+ * -+ * Copyright (c) 2007 Freescale Semiconductor, Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include "ops.h" -+#include "stdio.h" -+#include "planetcore.h" -+#include "pq2.h" -+ -+static char *table; -+static u64 mem_size; -+ -+#include -+ -+static void platform_fixups(void) -+{ -+ u64 val; -+ -+ dt_fixup_memory(0, mem_size); -+ planetcore_set_mac_addrs(table); -+ -+ if (!planetcore_get_decimal(table, PLANETCORE_KEY_CRYSTAL_HZ, &val)) { -+ printf("No PlanetCore crystal frequency key.\r\n"); -+ return; -+ } -+ -+ pq2_fixup_clocks(val); -+} -+ -+void platform_init(unsigned long r3, unsigned long r4, unsigned long r5, -+ unsigned long r6, unsigned long r7) -+{ -+ table = (char *)r3; -+ planetcore_prepare_table(table); -+ -+ if (!planetcore_get_decimal(table, PLANETCORE_KEY_MB_RAM, &mem_size)) -+ return; -+ -+ mem_size *= 1024 * 1024; -+ simple_alloc_init(_end, mem_size - (unsigned long)_end, 32, 64); -+ -+ fdt_init(_dtb_start); -+ -+ planetcore_set_stdout_path(table); -+ serial_console_init(); -+ platform_ops.fixups = platform_fixups; -+} ---- a/arch/powerpc/boot/ep88xc.c -+++ b/arch/powerpc/boot/ep88xc.c -@@ -45,7 +45,7 @@ void platform_init(unsigned long r3, uns - mem_size *= 1024 * 1024; - simple_alloc_init(_end, mem_size - (unsigned long)_end, 32, 64); - -- ft_init(_dtb_start, _dtb_end - _dtb_start, 32); -+ fdt_init(_dtb_start); - - planetcore_set_stdout_path(table); - ---- a/arch/powerpc/boot/flatdevtree.c -+++ /dev/null -@@ -1,1036 +0,0 @@ --/* -- * 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -- * -- * Copyright Pantelis Antoniou 2006 -- * Copyright (C) IBM Corporation 2006 -- * -- * Authors: Pantelis Antoniou -- * Hollis Blanchard -- * Mark A. Greer -- * Paul Mackerras -- */ -- --#include --#include --#include "flatdevtree.h" --#include "flatdevtree_env.h" -- --#define _ALIGN(x, al) (((x) + (al) - 1) & ~((al) - 1)) -- --static char *ft_root_node(struct ft_cxt *cxt) --{ -- return cxt->rgn[FT_STRUCT].start; --} -- --/* Routines for keeping node ptrs returned by ft_find_device current */ --/* First entry not used b/c it would return 0 and be taken as NULL/error */ --static void *ft_get_phandle(struct ft_cxt *cxt, char *node) --{ -- unsigned int i; -- -- if (!node) -- return NULL; -- -- for (i = 1; i < cxt->nodes_used; i++) /* already there? */ -- if (cxt->node_tbl[i] == node) -- return (void *)i; -- -- if (cxt->nodes_used < cxt->node_max) { -- cxt->node_tbl[cxt->nodes_used] = node; -- return (void *)cxt->nodes_used++; -- } -- -- return NULL; --} -- --static char *ft_node_ph2node(struct ft_cxt *cxt, const void *phandle) --{ -- unsigned int i = (unsigned int)phandle; -- -- if (i < cxt->nodes_used) -- return cxt->node_tbl[i]; -- return NULL; --} -- --static void ft_node_update_before(struct ft_cxt *cxt, char *addr, int shift) --{ -- unsigned int i; -- -- if (shift == 0) -- return; -- -- for (i = 1; i < cxt->nodes_used; i++) -- if (cxt->node_tbl[i] < addr) -- cxt->node_tbl[i] += shift; --} -- --static void ft_node_update_after(struct ft_cxt *cxt, char *addr, int shift) --{ -- unsigned int i; -- -- if (shift == 0) -- return; -- -- for (i = 1; i < cxt->nodes_used; i++) -- if (cxt->node_tbl[i] >= addr) -- cxt->node_tbl[i] += shift; --} -- --/* Struct used to return info from ft_next() */ --struct ft_atom { -- u32 tag; -- const char *name; -- void *data; -- u32 size; --}; -- --/* Set ptrs to current one's info; return addr of next one */ --static char *ft_next(struct ft_cxt *cxt, char *p, struct ft_atom *ret) --{ -- u32 sz; -- -- if (p >= cxt->rgn[FT_STRUCT].start + cxt->rgn[FT_STRUCT].size) -- return NULL; -- -- ret->tag = be32_to_cpu(*(u32 *) p); -- p += 4; -- -- switch (ret->tag) { /* Tag */ -- case OF_DT_BEGIN_NODE: -- ret->name = p; -- ret->data = (void *)(p - 4); /* start of node */ -- p += _ALIGN(strlen(p) + 1, 4); -- break; -- case OF_DT_PROP: -- ret->size = sz = be32_to_cpu(*(u32 *) p); -- ret->name = cxt->str_anchor + be32_to_cpu(*(u32 *) (p + 4)); -- ret->data = (void *)(p + 8); -- p += 8 + _ALIGN(sz, 4); -- break; -- case OF_DT_END_NODE: -- case OF_DT_NOP: -- break; -- case OF_DT_END: -- default: -- p = NULL; -- break; -- } -- -- return p; --} -- --#define HDR_SIZE _ALIGN(sizeof(struct boot_param_header), 8) --#define EXPAND_INCR 1024 /* alloc this much extra when expanding */ -- --/* Copy the tree to a newly-allocated region and put things in order */ --static int ft_reorder(struct ft_cxt *cxt, int nextra) --{ -- unsigned long tot; -- enum ft_rgn_id r; -- char *p, *pend; -- int stroff; -- -- tot = HDR_SIZE + EXPAND_INCR; -- for (r = FT_RSVMAP; r <= FT_STRINGS; ++r) -- tot += cxt->rgn[r].size; -- if (nextra > 0) -- tot += nextra; -- tot = _ALIGN(tot, 8); -- -- if (!cxt->realloc) -- return 0; -- p = cxt->realloc(NULL, tot); -- if (!p) -- return 0; -- -- memcpy(p, cxt->bph, sizeof(struct boot_param_header)); -- /* offsets get fixed up later */ -- -- cxt->bph = (struct boot_param_header *)p; -- cxt->max_size = tot; -- pend = p + tot; -- p += HDR_SIZE; -- -- memcpy(p, cxt->rgn[FT_RSVMAP].start, cxt->rgn[FT_RSVMAP].size); -- cxt->rgn[FT_RSVMAP].start = p; -- p += cxt->rgn[FT_RSVMAP].size; -- -- memcpy(p, cxt->rgn[FT_STRUCT].start, cxt->rgn[FT_STRUCT].size); -- ft_node_update_after(cxt, cxt->rgn[FT_STRUCT].start, -- p - cxt->rgn[FT_STRUCT].start); -- cxt->p += p - cxt->rgn[FT_STRUCT].start; -- cxt->rgn[FT_STRUCT].start = p; -- -- p = pend - cxt->rgn[FT_STRINGS].size; -- memcpy(p, cxt->rgn[FT_STRINGS].start, cxt->rgn[FT_STRINGS].size); -- stroff = cxt->str_anchor - cxt->rgn[FT_STRINGS].start; -- cxt->rgn[FT_STRINGS].start = p; -- cxt->str_anchor = p + stroff; -- -- cxt->isordered = 1; -- return 1; --} -- --static inline char *prev_end(struct ft_cxt *cxt, enum ft_rgn_id r) --{ -- if (r > FT_RSVMAP) -- return cxt->rgn[r - 1].start + cxt->rgn[r - 1].size; -- return (char *)cxt->bph + HDR_SIZE; --} -- --static inline char *next_start(struct ft_cxt *cxt, enum ft_rgn_id r) --{ -- if (r < FT_STRINGS) -- return cxt->rgn[r + 1].start; -- return (char *)cxt->bph + cxt->max_size; --} -- --/* -- * See if we can expand region rgn by nextra bytes by using up -- * free space after or before the region. -- */ --static int ft_shuffle(struct ft_cxt *cxt, char **pp, enum ft_rgn_id rgn, -- int nextra) --{ -- char *p = *pp; -- char *rgn_start, *rgn_end; -- -- rgn_start = cxt->rgn[rgn].start; -- rgn_end = rgn_start + cxt->rgn[rgn].size; -- if (nextra <= 0 || rgn_end + nextra <= next_start(cxt, rgn)) { -- /* move following stuff */ -- if (p < rgn_end) { -- if (nextra < 0) -- memmove(p, p - nextra, rgn_end - p + nextra); -- else -- memmove(p + nextra, p, rgn_end - p); -- if (rgn == FT_STRUCT) -- ft_node_update_after(cxt, p, nextra); -- } -- cxt->rgn[rgn].size += nextra; -- if (rgn == FT_STRINGS) -- /* assumes strings only added at beginning */ -- cxt->str_anchor += nextra; -- return 1; -- } -- if (prev_end(cxt, rgn) <= rgn_start - nextra) { -- /* move preceding stuff */ -- if (p > rgn_start) { -- memmove(rgn_start - nextra, rgn_start, p - rgn_start); -- if (rgn == FT_STRUCT) -- ft_node_update_before(cxt, p, -nextra); -- } -- *pp -= nextra; -- cxt->rgn[rgn].start -= nextra; -- cxt->rgn[rgn].size += nextra; -- return 1; -- } -- return 0; --} -- --static int ft_make_space(struct ft_cxt *cxt, char **pp, enum ft_rgn_id rgn, -- int nextra) --{ -- unsigned long size, ssize, tot; -- char *str, *next; -- enum ft_rgn_id r; -- -- if (!cxt->isordered) { -- unsigned long rgn_off = *pp - cxt->rgn[rgn].start; -- -- if (!ft_reorder(cxt, nextra)) -- return 0; -- -- *pp = cxt->rgn[rgn].start + rgn_off; -- } -- if (ft_shuffle(cxt, pp, rgn, nextra)) -- return 1; -- -- /* See if there is space after the strings section */ -- ssize = cxt->rgn[FT_STRINGS].size; -- if (cxt->rgn[FT_STRINGS].start + ssize -- < (char *)cxt->bph + cxt->max_size) { -- /* move strings up as far as possible */ -- str = (char *)cxt->bph + cxt->max_size - ssize; -- cxt->str_anchor += str - cxt->rgn[FT_STRINGS].start; -- memmove(str, cxt->rgn[FT_STRINGS].start, ssize); -- cxt->rgn[FT_STRINGS].start = str; -- /* enough space now? */ -- if (rgn >= FT_STRUCT && ft_shuffle(cxt, pp, rgn, nextra)) -- return 1; -- } -- -- /* how much total free space is there following this region? */ -- tot = 0; -- for (r = rgn; r < FT_STRINGS; ++r) { -- char *r_end = cxt->rgn[r].start + cxt->rgn[r].size; -- tot += next_start(cxt, rgn) - r_end; -- } -- -- /* cast is to shut gcc up; we know nextra >= 0 */ -- if (tot < (unsigned int)nextra) { -- /* have to reallocate */ -- char *newp, *new_start; -- int shift; -- -- if (!cxt->realloc) -- return 0; -- size = _ALIGN(cxt->max_size + (nextra - tot) + EXPAND_INCR, 8); -- newp = cxt->realloc(cxt->bph, size); -- if (!newp) -- return 0; -- cxt->max_size = size; -- shift = newp - (char *)cxt->bph; -- -- if (shift) { /* realloc can return same addr */ -- cxt->bph = (struct boot_param_header *)newp; -- ft_node_update_after(cxt, cxt->rgn[FT_STRUCT].start, -- shift); -- for (r = FT_RSVMAP; r <= FT_STRINGS; ++r) { -- new_start = cxt->rgn[r].start + shift; -- cxt->rgn[r].start = new_start; -- } -- *pp += shift; -- cxt->str_anchor += shift; -- } -- -- /* move strings up to the end */ -- str = newp + size - ssize; -- cxt->str_anchor += str - cxt->rgn[FT_STRINGS].start; -- memmove(str, cxt->rgn[FT_STRINGS].start, ssize); -- cxt->rgn[FT_STRINGS].start = str; -- -- if (ft_shuffle(cxt, pp, rgn, nextra)) -- return 1; -- } -- -- /* must be FT_RSVMAP and we need to move FT_STRUCT up */ -- if (rgn == FT_RSVMAP) { -- next = cxt->rgn[FT_RSVMAP].start + cxt->rgn[FT_RSVMAP].size -- + nextra; -- ssize = cxt->rgn[FT_STRUCT].size; -- if (next + ssize >= cxt->rgn[FT_STRINGS].start) -- return 0; /* "can't happen" */ -- memmove(next, cxt->rgn[FT_STRUCT].start, ssize); -- ft_node_update_after(cxt, cxt->rgn[FT_STRUCT].start, nextra); -- cxt->rgn[FT_STRUCT].start = next; -- -- if (ft_shuffle(cxt, pp, rgn, nextra)) -- return 1; -- } -- -- return 0; /* "can't happen" */ --} -- --static void ft_put_word(struct ft_cxt *cxt, u32 v) --{ -- *(u32 *) cxt->p = cpu_to_be32(v); -- cxt->p += 4; --} -- --static void ft_put_bin(struct ft_cxt *cxt, const void *data, unsigned int sz) --{ -- unsigned long sza = _ALIGN(sz, 4); -- -- /* zero out the alignment gap if necessary */ -- if (sz < sza) -- *(u32 *) (cxt->p + sza - 4) = 0; -- -- /* copy in the data */ -- memcpy(cxt->p, data, sz); -- -- cxt->p += sza; --} -- --char *ft_begin_node(struct ft_cxt *cxt, const char *name) --{ -- unsigned long nlen = strlen(name) + 1; -- unsigned long len = 8 + _ALIGN(nlen, 4); -- char *ret; -- -- if (!ft_make_space(cxt, &cxt->p, FT_STRUCT, len)) -- return NULL; -- -- ret = cxt->p; -- -- ft_put_word(cxt, OF_DT_BEGIN_NODE); -- ft_put_bin(cxt, name, strlen(name) + 1); -- -- return ret; --} -- --void ft_end_node(struct ft_cxt *cxt) --{ -- ft_put_word(cxt, OF_DT_END_NODE); --} -- --void ft_nop(struct ft_cxt *cxt) --{ -- if (ft_make_space(cxt, &cxt->p, FT_STRUCT, 4)) -- ft_put_word(cxt, OF_DT_NOP); --} -- --#define NO_STRING 0x7fffffff -- --static int lookup_string(struct ft_cxt *cxt, const char *name) --{ -- char *p, *end; -- -- p = cxt->rgn[FT_STRINGS].start; -- end = p + cxt->rgn[FT_STRINGS].size; -- while (p < end) { -- if (strcmp(p, (char *)name) == 0) -- return p - cxt->str_anchor; -- p += strlen(p) + 1; -- } -- -- return NO_STRING; --} -- --/* lookup string and insert if not found */ --static int map_string(struct ft_cxt *cxt, const char *name) --{ -- int off; -- char *p; -- -- off = lookup_string(cxt, name); -- if (off != NO_STRING) -- return off; -- p = cxt->rgn[FT_STRINGS].start; -- if (!ft_make_space(cxt, &p, FT_STRINGS, strlen(name) + 1)) -- return NO_STRING; -- strcpy(p, name); -- return p - cxt->str_anchor; --} -- --int ft_prop(struct ft_cxt *cxt, const char *name, const void *data, -- unsigned int sz) --{ -- int off, len; -- -- off = map_string(cxt, name); -- if (off == NO_STRING) -- return -1; -- -- len = 12 + _ALIGN(sz, 4); -- if (!ft_make_space(cxt, &cxt->p, FT_STRUCT, len)) -- return -1; -- -- ft_put_word(cxt, OF_DT_PROP); -- ft_put_word(cxt, sz); -- ft_put_word(cxt, off); -- ft_put_bin(cxt, data, sz); -- return 0; --} -- --int ft_prop_str(struct ft_cxt *cxt, const char *name, const char *str) --{ -- return ft_prop(cxt, name, str, strlen(str) + 1); --} -- --int ft_prop_int(struct ft_cxt *cxt, const char *name, unsigned int val) --{ -- u32 v = cpu_to_be32((u32) val); -- -- return ft_prop(cxt, name, &v, 4); --} -- --/* Calculate the size of the reserved map */ --static unsigned long rsvmap_size(struct ft_cxt *cxt) --{ -- struct ft_reserve *res; -- -- res = (struct ft_reserve *)cxt->rgn[FT_RSVMAP].start; -- while (res->start || res->len) -- ++res; -- return (char *)(res + 1) - cxt->rgn[FT_RSVMAP].start; --} -- --/* Calculate the size of the struct region by stepping through it */ --static unsigned long struct_size(struct ft_cxt *cxt) --{ -- char *p = cxt->rgn[FT_STRUCT].start; -- char *next; -- struct ft_atom atom; -- -- /* make check in ft_next happy */ -- if (cxt->rgn[FT_STRUCT].size == 0) -- cxt->rgn[FT_STRUCT].size = 0xfffffffful - (unsigned long)p; -- -- while ((next = ft_next(cxt, p, &atom)) != NULL) -- p = next; -- return p + 4 - cxt->rgn[FT_STRUCT].start; --} -- --/* add `adj' on to all string offset values in the struct area */ --static void adjust_string_offsets(struct ft_cxt *cxt, int adj) --{ -- char *p = cxt->rgn[FT_STRUCT].start; -- char *next; -- struct ft_atom atom; -- int off; -- -- while ((next = ft_next(cxt, p, &atom)) != NULL) { -- if (atom.tag == OF_DT_PROP) { -- off = be32_to_cpu(*(u32 *) (p + 8)); -- *(u32 *) (p + 8) = cpu_to_be32(off + adj); -- } -- p = next; -- } --} -- --/* start construction of the flat OF tree from scratch */ --void ft_begin(struct ft_cxt *cxt, void *blob, unsigned int max_size, -- void *(*realloc_fn) (void *, unsigned long)) --{ -- struct boot_param_header *bph = blob; -- char *p; -- struct ft_reserve *pres; -- -- /* clear the cxt */ -- memset(cxt, 0, sizeof(*cxt)); -- -- cxt->bph = bph; -- cxt->max_size = max_size; -- cxt->realloc = realloc_fn; -- cxt->isordered = 1; -- -- /* zero everything in the header area */ -- memset(bph, 0, sizeof(*bph)); -- -- bph->magic = cpu_to_be32(OF_DT_HEADER); -- bph->version = cpu_to_be32(0x10); -- bph->last_comp_version = cpu_to_be32(0x10); -- -- /* start pointers */ -- cxt->rgn[FT_RSVMAP].start = p = blob + HDR_SIZE; -- cxt->rgn[FT_RSVMAP].size = sizeof(struct ft_reserve); -- pres = (struct ft_reserve *)p; -- cxt->rgn[FT_STRUCT].start = p += sizeof(struct ft_reserve); -- cxt->rgn[FT_STRUCT].size = 4; -- cxt->rgn[FT_STRINGS].start = blob + max_size; -- cxt->rgn[FT_STRINGS].size = 0; -- -- /* init rsvmap and struct */ -- pres->start = 0; -- pres->len = 0; -- *(u32 *) p = cpu_to_be32(OF_DT_END); -- -- cxt->str_anchor = blob; --} -- --/* open up an existing blob to be examined or modified */ --int ft_open(struct ft_cxt *cxt, void *blob, unsigned int max_size, -- unsigned int max_find_device, -- void *(*realloc_fn) (void *, unsigned long)) --{ -- struct boot_param_header *bph = blob; -- -- /* can't cope with version < 16 */ -- if (be32_to_cpu(bph->version) < 16) -- return -1; -- -- /* clear the cxt */ -- memset(cxt, 0, sizeof(*cxt)); -- -- /* alloc node_tbl to track node ptrs returned by ft_find_device */ -- ++max_find_device; -- cxt->node_tbl = realloc_fn(NULL, max_find_device * sizeof(char *)); -- if (!cxt->node_tbl) -- return -1; -- memset(cxt->node_tbl, 0, max_find_device * sizeof(char *)); -- cxt->node_max = max_find_device; -- cxt->nodes_used = 1; /* don't use idx 0 b/c looks like NULL */ -- -- cxt->bph = bph; -- cxt->max_size = max_size; -- cxt->realloc = realloc_fn; -- -- cxt->rgn[FT_RSVMAP].start = blob + be32_to_cpu(bph->off_mem_rsvmap); -- cxt->rgn[FT_RSVMAP].size = rsvmap_size(cxt); -- cxt->rgn[FT_STRUCT].start = blob + be32_to_cpu(bph->off_dt_struct); -- cxt->rgn[FT_STRUCT].size = struct_size(cxt); -- cxt->rgn[FT_STRINGS].start = blob + be32_to_cpu(bph->off_dt_strings); -- cxt->rgn[FT_STRINGS].size = be32_to_cpu(bph->dt_strings_size); -- -- cxt->p = cxt->rgn[FT_STRUCT].start; -- cxt->str_anchor = cxt->rgn[FT_STRINGS].start; -- -- return 0; --} -- --/* add a reserver physical area to the rsvmap */ --int ft_add_rsvmap(struct ft_cxt *cxt, u64 physaddr, u64 size) --{ -- char *p; -- struct ft_reserve *pres; -- -- p = cxt->rgn[FT_RSVMAP].start + cxt->rgn[FT_RSVMAP].size -- - sizeof(struct ft_reserve); -- if (!ft_make_space(cxt, &p, FT_RSVMAP, sizeof(struct ft_reserve))) -- return -1; -- -- pres = (struct ft_reserve *)p; -- pres->start = cpu_to_be64(physaddr); -- pres->len = cpu_to_be64(size); -- -- return 0; --} -- --void ft_begin_tree(struct ft_cxt *cxt) --{ -- cxt->p = ft_root_node(cxt); --} -- --void ft_end_tree(struct ft_cxt *cxt) --{ -- struct boot_param_header *bph = cxt->bph; -- char *p, *oldstr, *str, *endp; -- unsigned long ssize; -- int adj; -- -- if (!cxt->isordered) -- return; /* we haven't touched anything */ -- -- /* adjust string offsets */ -- oldstr = cxt->rgn[FT_STRINGS].start; -- adj = cxt->str_anchor - oldstr; -- if (adj) -- adjust_string_offsets(cxt, adj); -- -- /* make strings end on 8-byte boundary */ -- ssize = cxt->rgn[FT_STRINGS].size; -- endp = (char *)_ALIGN((unsigned long)cxt->rgn[FT_STRUCT].start -- + cxt->rgn[FT_STRUCT].size + ssize, 8); -- str = endp - ssize; -- -- /* move strings down to end of structs */ -- memmove(str, oldstr, ssize); -- cxt->str_anchor = str; -- cxt->rgn[FT_STRINGS].start = str; -- -- /* fill in header fields */ -- p = (char *)bph; -- bph->totalsize = cpu_to_be32(endp - p); -- bph->off_mem_rsvmap = cpu_to_be32(cxt->rgn[FT_RSVMAP].start - p); -- bph->off_dt_struct = cpu_to_be32(cxt->rgn[FT_STRUCT].start - p); -- bph->off_dt_strings = cpu_to_be32(cxt->rgn[FT_STRINGS].start - p); -- bph->dt_strings_size = cpu_to_be32(ssize); --} -- --void *ft_find_device(struct ft_cxt *cxt, const void *top, const char *srch_path) --{ -- char *node; -- -- if (top) { -- node = ft_node_ph2node(cxt, top); -- if (node == NULL) -- return NULL; -- } else { -- node = ft_root_node(cxt); -- } -- -- node = ft_find_descendent(cxt, node, srch_path); -- return ft_get_phandle(cxt, node); --} -- --void *ft_find_descendent(struct ft_cxt *cxt, void *top, const char *srch_path) --{ -- struct ft_atom atom; -- char *p; -- const char *cp, *q; -- int cl; -- int depth = -1; -- int dmatch = 0; -- const char *path_comp[FT_MAX_DEPTH]; -- -- cp = srch_path; -- cl = 0; -- p = top; -- -- while ((p = ft_next(cxt, p, &atom)) != NULL) { -- switch (atom.tag) { -- case OF_DT_BEGIN_NODE: -- ++depth; -- if (depth != dmatch) -- break; -- cxt->genealogy[depth] = atom.data; -- cxt->genealogy[depth + 1] = NULL; -- if (depth && !(strncmp(atom.name, cp, cl) == 0 -- && (atom.name[cl] == '/' -- || atom.name[cl] == '\0' -- || atom.name[cl] == '@'))) -- break; -- path_comp[dmatch] = cp; -- /* it matches so far, advance to next path component */ -- cp += cl; -- /* skip slashes */ -- while (*cp == '/') -- ++cp; -- /* we're done if this is the end of the string */ -- if (*cp == 0) -- return atom.data; -- /* look for end of this component */ -- q = strchr(cp, '/'); -- if (q) -- cl = q - cp; -- else -- cl = strlen(cp); -- ++dmatch; -- break; -- case OF_DT_END_NODE: -- if (depth == 0) -- return NULL; -- if (dmatch > depth) { -- --dmatch; -- cl = cp - path_comp[dmatch] - 1; -- cp = path_comp[dmatch]; -- while (cl > 0 && cp[cl - 1] == '/') -- --cl; -- } -- --depth; -- break; -- } -- } -- return NULL; --} -- --void *__ft_get_parent(struct ft_cxt *cxt, void *node) --{ -- int d; -- struct ft_atom atom; -- char *p; -- -- for (d = 0; cxt->genealogy[d] != NULL; ++d) -- if (cxt->genealogy[d] == node) -- return d > 0 ? cxt->genealogy[d - 1] : NULL; -- -- /* have to do it the hard way... */ -- p = ft_root_node(cxt); -- d = 0; -- while ((p = ft_next(cxt, p, &atom)) != NULL) { -- switch (atom.tag) { -- case OF_DT_BEGIN_NODE: -- cxt->genealogy[d] = atom.data; -- if (node == atom.data) { -- /* found it */ -- cxt->genealogy[d + 1] = NULL; -- return d > 0 ? cxt->genealogy[d - 1] : NULL; -- } -- ++d; -- break; -- case OF_DT_END_NODE: -- --d; -- break; -- } -- } -- return NULL; --} -- --void *ft_get_parent(struct ft_cxt *cxt, const void *phandle) --{ -- void *node = ft_node_ph2node(cxt, phandle); -- if (node == NULL) -- return NULL; -- -- node = __ft_get_parent(cxt, node); -- return ft_get_phandle(cxt, node); --} -- --static const void *__ft_get_prop(struct ft_cxt *cxt, void *node, -- const char *propname, unsigned int *len) --{ -- struct ft_atom atom; -- int depth = 0; -- -- while ((node = ft_next(cxt, node, &atom)) != NULL) { -- switch (atom.tag) { -- case OF_DT_BEGIN_NODE: -- ++depth; -- break; -- -- case OF_DT_PROP: -- if (depth != 1 || strcmp(atom.name, propname)) -- break; -- -- if (len) -- *len = atom.size; -- -- return atom.data; -- -- case OF_DT_END_NODE: -- if (--depth <= 0) -- return NULL; -- } -- } -- -- return NULL; --} -- --int ft_get_prop(struct ft_cxt *cxt, const void *phandle, const char *propname, -- void *buf, const unsigned int buflen) --{ -- const void *data; -- unsigned int size; -- -- void *node = ft_node_ph2node(cxt, phandle); -- if (!node) -- return -1; -- -- data = __ft_get_prop(cxt, node, propname, &size); -- if (data) { -- unsigned int clipped_size = min(size, buflen); -- memcpy(buf, data, clipped_size); -- return size; -- } -- -- return -1; --} -- --void *__ft_find_node_by_prop_value(struct ft_cxt *cxt, void *prev, -- const char *propname, const char *propval, -- unsigned int proplen) --{ -- struct ft_atom atom; -- char *p = ft_root_node(cxt); -- char *next; -- int past_prev = prev ? 0 : 1; -- int depth = -1; -- -- while ((next = ft_next(cxt, p, &atom)) != NULL) { -- const void *data; -- unsigned int size; -- -- switch (atom.tag) { -- case OF_DT_BEGIN_NODE: -- depth++; -- -- if (prev == p) { -- past_prev = 1; -- break; -- } -- -- if (!past_prev || depth < 1) -- break; -- -- data = __ft_get_prop(cxt, p, propname, &size); -- if (!data || size != proplen) -- break; -- if (memcmp(data, propval, size)) -- break; -- -- return p; -- -- case OF_DT_END_NODE: -- if (depth-- == 0) -- return NULL; -- -- break; -- } -- -- p = next; -- } -- -- return NULL; --} -- --void *ft_find_node_by_prop_value(struct ft_cxt *cxt, const void *prev, -- const char *propname, const char *propval, -- int proplen) --{ -- void *node = NULL; -- -- if (prev) { -- node = ft_node_ph2node(cxt, prev); -- -- if (!node) -- return NULL; -- } -- -- node = __ft_find_node_by_prop_value(cxt, node, propname, -- propval, proplen); -- return ft_get_phandle(cxt, node); --} -- --int ft_set_prop(struct ft_cxt *cxt, const void *phandle, const char *propname, -- const void *buf, const unsigned int buflen) --{ -- struct ft_atom atom; -- void *node; -- char *p, *next; -- int nextra; -- -- node = ft_node_ph2node(cxt, phandle); -- if (node == NULL) -- return -1; -- -- next = ft_next(cxt, node, &atom); -- if (atom.tag != OF_DT_BEGIN_NODE) -- /* phandle didn't point to a node */ -- return -1; -- p = next; -- -- while ((next = ft_next(cxt, p, &atom)) != NULL) { -- switch (atom.tag) { -- case OF_DT_BEGIN_NODE: /* properties must go before subnodes */ -- case OF_DT_END_NODE: -- /* haven't found the property, insert here */ -- cxt->p = p; -- return ft_prop(cxt, propname, buf, buflen); -- case OF_DT_PROP: -- if (strcmp(atom.name, propname)) -- break; -- /* found an existing property, overwrite it */ -- nextra = _ALIGN(buflen, 4) - _ALIGN(atom.size, 4); -- cxt->p = atom.data; -- if (nextra && !ft_make_space(cxt, &cxt->p, FT_STRUCT, -- nextra)) -- return -1; -- *(u32 *) (cxt->p - 8) = cpu_to_be32(buflen); -- ft_put_bin(cxt, buf, buflen); -- return 0; -- } -- p = next; -- } -- return -1; --} -- --int ft_del_prop(struct ft_cxt *cxt, const void *phandle, const char *propname) --{ -- struct ft_atom atom; -- void *node; -- char *p, *next; -- int size; -- -- node = ft_node_ph2node(cxt, phandle); -- if (node == NULL) -- return -1; -- -- p = node; -- while ((next = ft_next(cxt, p, &atom)) != NULL) { -- switch (atom.tag) { -- case OF_DT_BEGIN_NODE: -- case OF_DT_END_NODE: -- return -1; -- case OF_DT_PROP: -- if (strcmp(atom.name, propname)) -- break; -- /* found the property, remove it */ -- size = 12 + -_ALIGN(atom.size, 4); -- cxt->p = p; -- if (!ft_make_space(cxt, &cxt->p, FT_STRUCT, -size)) -- return -1; -- return 0; -- } -- p = next; -- } -- return -1; --} -- --void *ft_create_node(struct ft_cxt *cxt, const void *parent, const char *name) --{ -- struct ft_atom atom; -- char *p, *next, *ret; -- int depth = 0; -- -- if (parent) { -- p = ft_node_ph2node(cxt, parent); -- if (!p) -- return NULL; -- } else { -- p = ft_root_node(cxt); -- } -- -- while ((next = ft_next(cxt, p, &atom)) != NULL) { -- switch (atom.tag) { -- case OF_DT_BEGIN_NODE: -- ++depth; -- if (depth == 1 && strcmp(atom.name, name) == 0) -- /* duplicate node name, return error */ -- return NULL; -- break; -- case OF_DT_END_NODE: -- --depth; -- if (depth > 0) -- break; -- /* end of node, insert here */ -- cxt->p = p; -- ret = ft_begin_node(cxt, name); -- ft_end_node(cxt); -- return ft_get_phandle(cxt, ret); -- } -- p = next; -- } -- return NULL; --} -- --/* Returns the start of the path within the provided buffer, or NULL on -- * error. -- */ --char *ft_get_path(struct ft_cxt *cxt, const void *phandle, -- char *buf, int len) --{ -- const char *path_comp[FT_MAX_DEPTH]; -- struct ft_atom atom; -- char *p, *next, *pos; -- int depth = 0, i; -- void *node; -- -- node = ft_node_ph2node(cxt, phandle); -- if (node == NULL) -- return NULL; -- -- p = ft_root_node(cxt); -- -- while ((next = ft_next(cxt, p, &atom)) != NULL) { -- switch (atom.tag) { -- case OF_DT_BEGIN_NODE: -- path_comp[depth++] = atom.name; -- if (p == node) -- goto found; -- -- break; -- -- case OF_DT_END_NODE: -- if (--depth == 0) -- return NULL; -- } -- -- p = next; -- } -- --found: -- pos = buf; -- for (i = 1; i < depth; i++) { -- int this_len; -- -- if (len <= 1) -- return NULL; -- -- *pos++ = '/'; -- len--; -- -- strncpy(pos, path_comp[i], len); -- -- if (pos[len - 1] != 0) -- return NULL; -- -- this_len = strlen(pos); -- len -= this_len; -- pos += this_len; -- } -- -- return buf; --} ---- a/arch/powerpc/boot/flatdevtree.h -+++ /dev/null -@@ -1,113 +0,0 @@ --/* -- * 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -- */ -- --#ifndef FLATDEVTREE_H --#define FLATDEVTREE_H -- --#include "flatdevtree_env.h" -- --/* Definitions used by the flattened device tree */ --#define OF_DT_HEADER 0xd00dfeed /* marker */ --#define OF_DT_BEGIN_NODE 0x1 /* Start of node, full name */ --#define OF_DT_END_NODE 0x2 /* End node */ --#define OF_DT_PROP 0x3 /* Property: name off, size, content */ --#define OF_DT_NOP 0x4 /* nop */ --#define OF_DT_END 0x9 -- --#define OF_DT_VERSION 0x10 -- --struct boot_param_header { -- u32 magic; /* magic word OF_DT_HEADER */ -- u32 totalsize; /* total size of DT block */ -- u32 off_dt_struct; /* offset to structure */ -- u32 off_dt_strings; /* offset to strings */ -- u32 off_mem_rsvmap; /* offset to memory reserve map */ -- u32 version; /* format version */ -- u32 last_comp_version; /* last compatible version */ -- /* version 2 fields below */ -- u32 boot_cpuid_phys; /* Physical CPU id we're booting on */ -- /* version 3 fields below */ -- u32 dt_strings_size; /* size of the DT strings block */ --}; -- --struct ft_reserve { -- u64 start; -- u64 len; --}; -- --struct ft_region { -- char *start; -- unsigned long size; --}; -- --enum ft_rgn_id { -- FT_RSVMAP, -- FT_STRUCT, -- FT_STRINGS, -- FT_N_REGION --}; -- --#define FT_MAX_DEPTH 50 -- --struct ft_cxt { -- struct boot_param_header *bph; -- int max_size; /* maximum size of tree */ -- int isordered; /* everything in standard order */ -- void *(*realloc)(void *, unsigned long); -- char *str_anchor; -- char *p; /* current insertion point in structs */ -- struct ft_region rgn[FT_N_REGION]; -- void *genealogy[FT_MAX_DEPTH+1]; -- char **node_tbl; -- unsigned int node_max; -- unsigned int nodes_used; --}; -- --char *ft_begin_node(struct ft_cxt *cxt, const char *name); --void ft_end_node(struct ft_cxt *cxt); -- --void ft_begin_tree(struct ft_cxt *cxt); --void ft_end_tree(struct ft_cxt *cxt); -- --void ft_nop(struct ft_cxt *cxt); --int ft_prop(struct ft_cxt *cxt, const char *name, -- const void *data, unsigned int sz); --int ft_prop_str(struct ft_cxt *cxt, const char *name, const char *str); --int ft_prop_int(struct ft_cxt *cxt, const char *name, unsigned int val); --void ft_begin(struct ft_cxt *cxt, void *blob, unsigned int max_size, -- void *(*realloc_fn)(void *, unsigned long)); --int ft_open(struct ft_cxt *cxt, void *blob, unsigned int max_size, -- unsigned int max_find_device, -- void *(*realloc_fn)(void *, unsigned long)); --int ft_add_rsvmap(struct ft_cxt *cxt, u64 physaddr, u64 size); -- --void ft_dump_blob(const void *bphp); --void ft_merge_blob(struct ft_cxt *cxt, void *blob); --void *ft_find_device(struct ft_cxt *cxt, const void *top, -- const char *srch_path); --void *ft_find_descendent(struct ft_cxt *cxt, void *top, const char *srch_path); --int ft_get_prop(struct ft_cxt *cxt, const void *phandle, const char *propname, -- void *buf, const unsigned int buflen); --int ft_set_prop(struct ft_cxt *cxt, const void *phandle, const char *propname, -- const void *buf, const unsigned int buflen); --void *ft_get_parent(struct ft_cxt *cxt, const void *phandle); --void *ft_find_node_by_prop_value(struct ft_cxt *cxt, const void *prev, -- const char *propname, const char *propval, -- int proplen); --void *ft_create_node(struct ft_cxt *cxt, const void *parent, const char *name); --char *ft_get_path(struct ft_cxt *cxt, const void *phandle, char *buf, int len); -- --#endif /* FLATDEVTREE_H */ ---- a/arch/powerpc/boot/flatdevtree_misc.c -+++ /dev/null -@@ -1,79 +0,0 @@ --/* -- * This file does the necessary interface mapping between the bootwrapper -- * device tree operations and the interface provided by shared source -- * files flatdevicetree.[ch]. -- * -- * Author: Mark A. Greer -- * -- * 2006 (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 "flatdevtree.h" --#include "ops.h" -- --static struct ft_cxt cxt; -- --static void *fdtm_finddevice(const char *name) --{ -- return ft_find_device(&cxt, NULL, name); --} -- --static int fdtm_getprop(const void *phandle, const char *propname, -- void *buf, const int buflen) --{ -- return ft_get_prop(&cxt, phandle, propname, buf, buflen); --} -- --static int fdtm_setprop(const void *phandle, const char *propname, -- const void *buf, const int buflen) --{ -- return ft_set_prop(&cxt, phandle, propname, buf, buflen); --} -- --static void *fdtm_get_parent(const void *phandle) --{ -- return ft_get_parent(&cxt, phandle); --} -- --static void *fdtm_create_node(const void *phandle, const char *name) --{ -- return ft_create_node(&cxt, phandle, name); --} -- --static void *fdtm_find_node_by_prop_value(const void *prev, -- const char *propname, -- const char *propval, -- int proplen) --{ -- return ft_find_node_by_prop_value(&cxt, prev, propname, -- propval, proplen); --} -- --static unsigned long fdtm_finalize(void) --{ -- ft_end_tree(&cxt); -- return (unsigned long)cxt.bph; --} -- --static char *fdtm_get_path(const void *phandle, char *buf, int len) --{ -- return ft_get_path(&cxt, phandle, buf, len); --} -- --int ft_init(void *dt_blob, unsigned int max_size, unsigned int max_find_device) --{ -- dt_ops.finddevice = fdtm_finddevice; -- dt_ops.getprop = fdtm_getprop; -- dt_ops.setprop = fdtm_setprop; -- dt_ops.get_parent = fdtm_get_parent; -- dt_ops.create_node = fdtm_create_node; -- dt_ops.find_node_by_prop_value = fdtm_find_node_by_prop_value; -- dt_ops.finalize = fdtm_finalize; -- dt_ops.get_path = fdtm_get_path; -- -- return ft_open(&cxt, dt_blob, max_size, max_find_device, -- platform_ops.realloc); --} ---- a/arch/powerpc/boot/holly.c -+++ b/arch/powerpc/boot/holly.c -@@ -28,6 +28,6 @@ void platform_init(unsigned long r3, uns - u32 heapsize = 0x8000000 - (u32)_end; /* 128M */ - - simple_alloc_init(_end, heapsize, 32, 64); -- ft_init(_dtb_start, 0, 4); -+ fdt_init(_dtb_start); - serial_console_init(); - } ---- /dev/null -+++ b/arch/powerpc/boot/libfdt/Makefile.libfdt -@@ -0,0 +1,14 @@ -+# Makefile.libfdt -+# -+# This is not a complete Makefile of itself. Instead, it is designed to -+# be easily embeddable into other systems of Makefiles. -+# -+LIBFDT_SRCS = fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c -+LIBFDT_INCLUDES = fdt.h libfdt.h -+LIBFDT_EXTRA = libfdt_internal.h -+LIBFDT_LIB = libfdt/libfdt.a -+ -+LIBFDT_OBJS = $(LIBFDT_SRCS:%.c=%.o) -+ -+$(LIBFDT_objdir)/$(LIBFDT_LIB): $(addprefix $(LIBFDT_objdir)/,$(LIBFDT_OBJS)) -+ ---- /dev/null -+++ b/arch/powerpc/boot/libfdt/fdt.c -@@ -0,0 +1,156 @@ -+/* -+ * libfdt - Flat Device Tree manipulation -+ * Copyright (C) 2006 David Gibson, IBM Corporation. -+ * -+ * libfdt is dual licensed: you can use it either under the terms of -+ * the GPL, or the BSD license, at your option. -+ * -+ * a) This library 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 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 General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public -+ * License along with this library; if not, write to the Free -+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, -+ * MA 02110-1301 USA -+ * -+ * Alternatively, -+ * -+ * b) 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. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. -+ */ -+#include "libfdt_env.h" -+ -+#include -+#include -+ -+#include "libfdt_internal.h" -+ -+int fdt_check_header(const void *fdt) -+{ -+ if (fdt_magic(fdt) == FDT_MAGIC) { -+ /* Complete tree */ -+ if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION) -+ return -FDT_ERR_BADVERSION; -+ if (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION) -+ return -FDT_ERR_BADVERSION; -+ } else if (fdt_magic(fdt) == SW_MAGIC) { -+ /* Unfinished sequential-write blob */ -+ if (fdt_size_dt_struct(fdt) == 0) -+ return -FDT_ERR_BADSTATE; -+ } else { -+ return -FDT_ERR_BADMAGIC; -+ } -+ -+ return 0; -+} -+ -+const void *fdt_offset_ptr(const void *fdt, int offset, int len) -+{ -+ const void *p; -+ -+ if (fdt_version(fdt) >= 0x11) -+ if (((offset + len) < offset) -+ || ((offset + len) > fdt_size_dt_struct(fdt))) -+ return NULL; -+ -+ p = _fdt_offset_ptr(fdt, offset); -+ -+ if (p + len < p) -+ return NULL; -+ return p; -+} -+ -+uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset) -+{ -+ const uint32_t *tagp, *lenp; -+ uint32_t tag; -+ const char *p; -+ -+ if (offset % FDT_TAGSIZE) -+ return -1; -+ -+ tagp = fdt_offset_ptr(fdt, offset, FDT_TAGSIZE); -+ if (! tagp) -+ return FDT_END; /* premature end */ -+ tag = fdt32_to_cpu(*tagp); -+ offset += FDT_TAGSIZE; -+ -+ switch (tag) { -+ case FDT_BEGIN_NODE: -+ /* skip name */ -+ do { -+ p = fdt_offset_ptr(fdt, offset++, 1); -+ } while (p && (*p != '\0')); -+ if (! p) -+ return FDT_END; -+ break; -+ case FDT_PROP: -+ lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp)); -+ if (! lenp) -+ return FDT_END; -+ /* skip name offset, length and value */ -+ offset += 2*FDT_TAGSIZE + fdt32_to_cpu(*lenp); -+ break; -+ } -+ -+ if (nextoffset) -+ *nextoffset = ALIGN(offset, FDT_TAGSIZE); -+ -+ return tag; -+} -+ -+const char *_fdt_find_string(const char *strtab, int tabsize, const char *s) -+{ -+ int len = strlen(s) + 1; -+ const char *last = strtab + tabsize - len; -+ const char *p; -+ -+ for (p = strtab; p <= last; p++) -+ if (memeq(p, s, len)) -+ return p; -+ return NULL; -+} -+ -+int fdt_move(const void *fdt, void *buf, int bufsize) -+{ -+ int err = fdt_check_header(fdt); -+ -+ if (err) -+ return err; -+ -+ if (fdt_totalsize(fdt) > bufsize) -+ return -FDT_ERR_NOSPACE; -+ -+ memmove(buf, fdt, fdt_totalsize(fdt)); -+ return 0; -+} ---- /dev/null -+++ b/arch/powerpc/boot/libfdt/fdt.h -@@ -0,0 +1,60 @@ -+#ifndef _FDT_H -+#define _FDT_H -+ -+#ifndef __ASSEMBLY__ -+ -+struct fdt_header { -+ uint32_t magic; /* magic word FDT_MAGIC */ -+ uint32_t totalsize; /* total size of DT block */ -+ uint32_t off_dt_struct; /* offset to structure */ -+ uint32_t off_dt_strings; /* offset to strings */ -+ uint32_t off_mem_rsvmap; /* offset to memory reserve map */ -+ uint32_t version; /* format version */ -+ uint32_t last_comp_version; /* last compatible version */ -+ -+ /* version 2 fields below */ -+ uint32_t boot_cpuid_phys; /* Which physical CPU id we're -+ booting on */ -+ /* version 3 fields below */ -+ uint32_t size_dt_strings; /* size of the strings block */ -+ -+ /* version 17 fields below */ -+ uint32_t size_dt_struct; /* size of the structure block */ -+}; -+ -+struct fdt_reserve_entry { -+ uint64_t address; -+ uint64_t size; -+}; -+ -+struct fdt_node_header { -+ uint32_t tag; -+ char name[0]; -+}; -+ -+struct fdt_property { -+ uint32_t tag; -+ uint32_t len; -+ uint32_t nameoff; -+ char data[0]; -+}; -+ -+#endif /* !__ASSEMBLY */ -+ -+#define FDT_MAGIC 0xd00dfeed /* 4: version, 4: total size */ -+#define FDT_TAGSIZE sizeof(uint32_t) -+ -+#define FDT_BEGIN_NODE 0x1 /* Start node: full name */ -+#define FDT_END_NODE 0x2 /* End node */ -+#define FDT_PROP 0x3 /* Property: name off, -+ size, content */ -+#define FDT_NOP 0x4 /* nop */ -+#define FDT_END 0x9 -+ -+#define FDT_V1_SIZE (7*sizeof(uint32_t)) -+#define FDT_V2_SIZE (FDT_V1_SIZE + sizeof(uint32_t)) -+#define FDT_V3_SIZE (FDT_V2_SIZE + sizeof(uint32_t)) -+#define FDT_V16_SIZE FDT_V3_SIZE -+#define FDT_V17_SIZE (FDT_V16_SIZE + sizeof(uint32_t)) -+ -+#endif /* _FDT_H */ ---- /dev/null -+++ b/arch/powerpc/boot/libfdt/fdt_ro.c -@@ -0,0 +1,583 @@ -+/* -+ * libfdt - Flat Device Tree manipulation -+ * Copyright (C) 2006 David Gibson, IBM Corporation. -+ * -+ * libfdt is dual licensed: you can use it either under the terms of -+ * the GPL, or the BSD license, at your option. -+ * -+ * a) This library 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 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 General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public -+ * License along with this library; if not, write to the Free -+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, -+ * MA 02110-1301 USA -+ * -+ * Alternatively, -+ * -+ * b) 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. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. -+ */ -+#include "libfdt_env.h" -+ -+#include -+#include -+ -+#include "libfdt_internal.h" -+ -+#define CHECK_HEADER(fdt) \ -+ { \ -+ int err; \ -+ if ((err = fdt_check_header(fdt)) != 0) \ -+ return err; \ -+ } -+ -+static int nodename_eq(const void *fdt, int offset, -+ const char *s, int len) -+{ -+ const char *p = fdt_offset_ptr(fdt, offset, len+1); -+ -+ if (! p) -+ /* short match */ -+ return 0; -+ -+ if (memcmp(p, s, len) != 0) -+ return 0; -+ -+ if (p[len] == '\0') -+ return 1; -+ else if (!memchr(s, '@', len) && (p[len] == '@')) -+ return 1; -+ else -+ return 0; -+} -+ -+const char *fdt_string(const void *fdt, int stroffset) -+{ -+ return (char *)fdt + fdt_off_dt_strings(fdt) + stroffset; -+} -+ -+int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size) -+{ -+ CHECK_HEADER(fdt); -+ *address = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->address); -+ *size = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->size); -+ return 0; -+} -+ -+int fdt_num_mem_rsv(const void *fdt) -+{ -+ int i = 0; -+ -+ while (fdt64_to_cpu(_fdt_mem_rsv(fdt, i)->size) != 0) -+ i++; -+ return i; -+} -+ -+int fdt_subnode_offset_namelen(const void *fdt, int parentoffset, -+ const char *name, int namelen) -+{ -+ int level = 0; -+ uint32_t tag; -+ int offset, nextoffset; -+ -+ CHECK_HEADER(fdt); -+ -+ tag = fdt_next_tag(fdt, parentoffset, &nextoffset); -+ if (tag != FDT_BEGIN_NODE) -+ return -FDT_ERR_BADOFFSET; -+ -+ do { -+ offset = nextoffset; -+ tag = fdt_next_tag(fdt, offset, &nextoffset); -+ -+ switch (tag) { -+ case FDT_END: -+ return -FDT_ERR_TRUNCATED; -+ -+ case FDT_BEGIN_NODE: -+ level++; -+ if (level != 1) -+ continue; -+ if (nodename_eq(fdt, offset+FDT_TAGSIZE, name, namelen)) -+ /* Found it! */ -+ return offset; -+ break; -+ -+ case FDT_END_NODE: -+ level--; -+ break; -+ -+ case FDT_PROP: -+ case FDT_NOP: -+ break; -+ -+ default: -+ return -FDT_ERR_BADSTRUCTURE; -+ } -+ } while (level >= 0); -+ -+ return -FDT_ERR_NOTFOUND; -+} -+ -+int fdt_subnode_offset(const void *fdt, int parentoffset, -+ const char *name) -+{ -+ return fdt_subnode_offset_namelen(fdt, parentoffset, name, strlen(name)); -+} -+ -+int fdt_path_offset(const void *fdt, const char *path) -+{ -+ const char *end = path + strlen(path); -+ const char *p = path; -+ int offset = 0; -+ -+ CHECK_HEADER(fdt); -+ -+ if (*path != '/') -+ return -FDT_ERR_BADPATH; -+ -+ while (*p) { -+ const char *q; -+ -+ while (*p == '/') -+ p++; -+ if (! *p) -+ return offset; -+ q = strchr(p, '/'); -+ if (! q) -+ q = end; -+ -+ offset = fdt_subnode_offset_namelen(fdt, offset, p, q-p); -+ if (offset < 0) -+ return offset; -+ -+ p = q; -+ } -+ -+ return offset; -+} -+ -+const char *fdt_get_name(const void *fdt, int nodeoffset, int *len) -+{ -+ const struct fdt_node_header *nh; -+ int err; -+ -+ if ((err = fdt_check_header(fdt)) != 0) -+ goto fail; -+ -+ err = -FDT_ERR_BADOFFSET; -+ nh = fdt_offset_ptr(fdt, nodeoffset, sizeof(*nh)); -+ if (!nh || (fdt32_to_cpu(nh->tag) != FDT_BEGIN_NODE)) -+ goto fail; -+ -+ if (len) -+ *len = strlen(nh->name); -+ -+ return nh->name; -+ -+ fail: -+ if (len) -+ *len = err; -+ return NULL; -+} -+ -+const struct fdt_property *fdt_get_property(const void *fdt, -+ int nodeoffset, -+ const char *name, int *lenp) -+{ -+ uint32_t tag; -+ const struct fdt_property *prop; -+ int namestroff; -+ int offset, nextoffset; -+ int err; -+ -+ if ((err = fdt_check_header(fdt)) != 0) -+ goto fail; -+ -+ err = -FDT_ERR_BADOFFSET; -+ if (nodeoffset % FDT_TAGSIZE) -+ goto fail; -+ -+ tag = fdt_next_tag(fdt, nodeoffset, &nextoffset); -+ if (tag != FDT_BEGIN_NODE) -+ goto fail; -+ -+ do { -+ offset = nextoffset; -+ -+ tag = fdt_next_tag(fdt, offset, &nextoffset); -+ switch (tag) { -+ case FDT_END: -+ err = -FDT_ERR_TRUNCATED; -+ goto fail; -+ -+ case FDT_BEGIN_NODE: -+ case FDT_END_NODE: -+ case FDT_NOP: -+ break; -+ -+ case FDT_PROP: -+ err = -FDT_ERR_BADSTRUCTURE; -+ prop = fdt_offset_ptr(fdt, offset, sizeof(*prop)); -+ if (! prop) -+ goto fail; -+ namestroff = fdt32_to_cpu(prop->nameoff); -+ if (streq(fdt_string(fdt, namestroff), name)) { -+ /* Found it! */ -+ int len = fdt32_to_cpu(prop->len); -+ prop = fdt_offset_ptr(fdt, offset, -+ sizeof(*prop)+len); -+ if (! prop) -+ goto fail; -+ -+ if (lenp) -+ *lenp = len; -+ -+ return prop; -+ } -+ break; -+ -+ default: -+ err = -FDT_ERR_BADSTRUCTURE; -+ goto fail; -+ } -+ } while ((tag != FDT_BEGIN_NODE) && (tag != FDT_END_NODE)); -+ -+ err = -FDT_ERR_NOTFOUND; -+ fail: -+ if (lenp) -+ *lenp = err; -+ return NULL; -+} -+ -+const void *fdt_getprop(const void *fdt, int nodeoffset, -+ const char *name, int *lenp) -+{ -+ const struct fdt_property *prop; -+ -+ prop = fdt_get_property(fdt, nodeoffset, name, lenp); -+ if (! prop) -+ return NULL; -+ -+ return prop->data; -+} -+ -+uint32_t fdt_get_phandle(const void *fdt, int nodeoffset) -+{ -+ const uint32_t *php; -+ int len; -+ -+ php = fdt_getprop(fdt, nodeoffset, "linux,phandle", &len); -+ if (!php || (len != sizeof(*php))) -+ return 0; -+ -+ return fdt32_to_cpu(*php); -+} -+ -+int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen) -+{ -+ uint32_t tag; -+ int p = 0, overflow = 0; -+ int offset, nextoffset, namelen; -+ const char *name; -+ -+ CHECK_HEADER(fdt); -+ -+ tag = fdt_next_tag(fdt, 0, &nextoffset); -+ if (tag != FDT_BEGIN_NODE) -+ return -FDT_ERR_BADSTRUCTURE; -+ -+ if (buflen < 2) -+ return -FDT_ERR_NOSPACE; -+ buf[0] = '/'; -+ p = 1; -+ -+ while (nextoffset <= nodeoffset) { -+ offset = nextoffset; -+ tag = fdt_next_tag(fdt, offset, &nextoffset); -+ switch (tag) { -+ case FDT_END: -+ return -FDT_ERR_BADOFFSET; -+ -+ case FDT_BEGIN_NODE: -+ name = fdt_get_name(fdt, offset, &namelen); -+ if (!name) -+ return namelen; -+ if (overflow || ((p + namelen + 1) > buflen)) { -+ overflow++; -+ break; -+ } -+ memcpy(buf + p, name, namelen); -+ p += namelen; -+ buf[p++] = '/'; -+ break; -+ -+ case FDT_END_NODE: -+ if (overflow) { -+ overflow--; -+ break; -+ } -+ do { -+ p--; -+ } while (buf[p-1] != '/'); -+ break; -+ -+ case FDT_PROP: -+ case FDT_NOP: -+ break; -+ -+ default: -+ return -FDT_ERR_BADSTRUCTURE; -+ } -+ } -+ -+ if (overflow) -+ return -FDT_ERR_NOSPACE; -+ -+ if (p > 1) /* special case so that root path is "/", not "" */ -+ p--; -+ buf[p] = '\0'; -+ return p; -+} -+ -+int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset, -+ int supernodedepth, int *nodedepth) -+{ -+ int level = -1; -+ uint32_t tag; -+ int offset, nextoffset = 0; -+ int supernodeoffset = -FDT_ERR_INTERNAL; -+ -+ CHECK_HEADER(fdt); -+ -+ if (supernodedepth < 0) -+ return -FDT_ERR_NOTFOUND; -+ -+ do { -+ offset = nextoffset; -+ tag = fdt_next_tag(fdt, offset, &nextoffset); -+ switch (tag) { -+ case FDT_END: -+ return -FDT_ERR_BADOFFSET; -+ -+ case FDT_BEGIN_NODE: -+ level++; -+ if (level == supernodedepth) -+ supernodeoffset = offset; -+ break; -+ -+ case FDT_END_NODE: -+ level--; -+ break; -+ -+ case FDT_PROP: -+ case FDT_NOP: -+ break; -+ -+ default: -+ return -FDT_ERR_BADSTRUCTURE; -+ } -+ } while (offset < nodeoffset); -+ -+ if (nodedepth) -+ *nodedepth = level; -+ -+ if (supernodedepth > level) -+ return -FDT_ERR_NOTFOUND; -+ return supernodeoffset; -+} -+ -+int fdt_node_depth(const void *fdt, int nodeoffset) -+{ -+ int nodedepth; -+ int err; -+ -+ err = fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, &nodedepth); -+ if (err) -+ return (err < 0) ? err : -FDT_ERR_INTERNAL; -+ return nodedepth; -+} -+ -+int fdt_parent_offset(const void *fdt, int nodeoffset) -+{ -+ int nodedepth = fdt_node_depth(fdt, nodeoffset); -+ -+ if (nodedepth < 0) -+ return nodedepth; -+ return fdt_supernode_atdepth_offset(fdt, nodeoffset, -+ nodedepth - 1, NULL); -+} -+ -+int fdt_node_offset_by_prop_value(const void *fdt, int startoffset, -+ const char *propname, -+ const void *propval, int proplen) -+{ -+ uint32_t tag; -+ int offset, nextoffset; -+ const void *val; -+ int len; -+ -+ CHECK_HEADER(fdt); -+ -+ if (startoffset >= 0) { -+ tag = fdt_next_tag(fdt, startoffset, &nextoffset); -+ if (tag != FDT_BEGIN_NODE) -+ return -FDT_ERR_BADOFFSET; -+ } else { -+ nextoffset = 0; -+ } -+ -+ /* FIXME: The algorithm here is pretty horrible: we scan each -+ * property of a node in fdt_getprop(), then if that didn't -+ * find what we want, we scan over them again making our way -+ * to the next node. Still it's the easiest to implement -+ * approach; performance can come later. */ -+ do { -+ offset = nextoffset; -+ tag = fdt_next_tag(fdt, offset, &nextoffset); -+ -+ switch (tag) { -+ case FDT_BEGIN_NODE: -+ val = fdt_getprop(fdt, offset, propname, &len); -+ if (val -+ && (len == proplen) -+ && (memcmp(val, propval, len) == 0)) -+ return offset; -+ break; -+ -+ case FDT_PROP: -+ case FDT_END: -+ case FDT_END_NODE: -+ case FDT_NOP: -+ break; -+ -+ default: -+ return -FDT_ERR_BADSTRUCTURE; -+ } -+ } while (tag != FDT_END); -+ -+ return -FDT_ERR_NOTFOUND; -+} -+ -+int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle) -+{ -+ if ((phandle == 0) || (phandle == -1)) -+ return -FDT_ERR_BADPHANDLE; -+ phandle = cpu_to_fdt32(phandle); -+ return fdt_node_offset_by_prop_value(fdt, -1, "linux,phandle", -+ &phandle, sizeof(phandle)); -+} -+ -+int _stringlist_contains(const void *strlist, int listlen, const char *str) -+{ -+ int len = strlen(str); -+ const void *p; -+ -+ while (listlen >= len) { -+ if (memcmp(str, strlist, len+1) == 0) -+ return 1; -+ p = memchr(strlist, '\0', listlen); -+ if (!p) -+ return 0; /* malformed strlist.. */ -+ listlen -= (p-strlist) + 1; -+ strlist = p + 1; -+ } -+ return 0; -+} -+ -+int fdt_node_check_compatible(const void *fdt, int nodeoffset, -+ const char *compatible) -+{ -+ const void *prop; -+ int len; -+ -+ prop = fdt_getprop(fdt, nodeoffset, "compatible", &len); -+ if (!prop) -+ return len; -+ if (_stringlist_contains(prop, len, compatible)) -+ return 0; -+ else -+ return 1; -+} -+ -+int fdt_node_offset_by_compatible(const void *fdt, int startoffset, -+ const char *compatible) -+{ -+ uint32_t tag; -+ int offset, nextoffset; -+ int err; -+ -+ CHECK_HEADER(fdt); -+ -+ if (startoffset >= 0) { -+ tag = fdt_next_tag(fdt, startoffset, &nextoffset); -+ if (tag != FDT_BEGIN_NODE) -+ return -FDT_ERR_BADOFFSET; -+ } else { -+ nextoffset = 0; -+ } -+ -+ /* FIXME: The algorithm here is pretty horrible: we scan each -+ * property of a node in fdt_node_check_compatible(), then if -+ * that didn't find what we want, we scan over them again -+ * making our way to the next node. Still it's the easiest to -+ * implement approach; performance can come later. */ -+ do { -+ offset = nextoffset; -+ tag = fdt_next_tag(fdt, offset, &nextoffset); -+ -+ switch (tag) { -+ case FDT_BEGIN_NODE: -+ err = fdt_node_check_compatible(fdt, offset, -+ compatible); -+ if ((err < 0) -+ && (err != -FDT_ERR_NOTFOUND)) -+ return err; -+ else if (err == 0) -+ return offset; -+ break; -+ -+ case FDT_PROP: -+ case FDT_END: -+ case FDT_END_NODE: -+ case FDT_NOP: -+ break; -+ -+ default: -+ return -FDT_ERR_BADSTRUCTURE; -+ } -+ } while (tag != FDT_END); -+ -+ return -FDT_ERR_NOTFOUND; -+} ---- /dev/null -+++ b/arch/powerpc/boot/libfdt/fdt_rw.c -@@ -0,0 +1,447 @@ -+/* -+ * libfdt - Flat Device Tree manipulation -+ * Copyright (C) 2006 David Gibson, IBM Corporation. -+ * -+ * libfdt is dual licensed: you can use it either under the terms of -+ * the GPL, or the BSD license, at your option. -+ * -+ * a) This library 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 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 General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public -+ * License along with this library; if not, write to the Free -+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, -+ * MA 02110-1301 USA -+ * -+ * Alternatively, -+ * -+ * b) 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. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. -+ */ -+#include "libfdt_env.h" -+ -+#include -+#include -+ -+#include "libfdt_internal.h" -+ -+static int _blocks_misordered(const void *fdt, -+ int mem_rsv_size, int struct_size) -+{ -+ return (fdt_off_mem_rsvmap(fdt) < ALIGN(sizeof(struct fdt_header), 8)) -+ || (fdt_off_dt_struct(fdt) < -+ (fdt_off_mem_rsvmap(fdt) + mem_rsv_size)) -+ || (fdt_off_dt_strings(fdt) < -+ (fdt_off_dt_struct(fdt) + struct_size)) -+ || (fdt_totalsize(fdt) < -+ (fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt))); -+} -+ -+static int rw_check_header(void *fdt) -+{ -+ int err; -+ -+ if ((err = fdt_check_header(fdt))) -+ return err; -+ if (fdt_version(fdt) < 17) -+ return -FDT_ERR_BADVERSION; -+ if (_blocks_misordered(fdt, sizeof(struct fdt_reserve_entry), -+ fdt_size_dt_struct(fdt))) -+ return -FDT_ERR_BADLAYOUT; -+ if (fdt_version(fdt) > 17) -+ fdt_set_version(fdt, 17); -+ -+ return 0; -+} -+ -+#define RW_CHECK_HEADER(fdt) \ -+ { \ -+ int err; \ -+ if ((err = rw_check_header(fdt)) != 0) \ -+ return err; \ -+ } -+ -+static inline int _blob_data_size(void *fdt) -+{ -+ return fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt); -+} -+ -+static int _blob_splice(void *fdt, void *p, int oldlen, int newlen) -+{ -+ void *end = fdt + _blob_data_size(fdt); -+ -+ if (((p + oldlen) < p) || ((p + oldlen) > end)) -+ return -FDT_ERR_BADOFFSET; -+ if ((end - oldlen + newlen) > (fdt + fdt_totalsize(fdt))) -+ return -FDT_ERR_NOSPACE; -+ memmove(p + newlen, p + oldlen, end - p - oldlen); -+ return 0; -+} -+ -+static int _blob_splice_mem_rsv(void *fdt, struct fdt_reserve_entry *p, -+ int oldn, int newn) -+{ -+ int delta = (newn - oldn) * sizeof(*p); -+ int err; -+ err = _blob_splice(fdt, p, oldn * sizeof(*p), newn * sizeof(*p)); -+ if (err) -+ return err; -+ fdt_set_off_dt_struct(fdt, fdt_off_dt_struct(fdt) + delta); -+ fdt_set_off_dt_strings(fdt, fdt_off_dt_strings(fdt) + delta); -+ return 0; -+} -+ -+static int _blob_splice_struct(void *fdt, void *p, -+ int oldlen, int newlen) -+{ -+ int delta = newlen - oldlen; -+ int err; -+ -+ if ((err = _blob_splice(fdt, p, oldlen, newlen))) -+ return err; -+ -+ fdt_set_size_dt_struct(fdt, fdt_size_dt_struct(fdt) + delta); -+ fdt_set_off_dt_strings(fdt, fdt_off_dt_strings(fdt) + delta); -+ return 0; -+} -+ -+static int _blob_splice_string(void *fdt, int newlen) -+{ -+ void *p = fdt + fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt); -+ int err; -+ -+ if ((err = _blob_splice(fdt, p, 0, newlen))) -+ return err; -+ -+ fdt_set_size_dt_strings(fdt, fdt_size_dt_strings(fdt) + newlen); -+ return 0; -+} -+ -+static int _find_add_string(void *fdt, const char *s) -+{ -+ char *strtab = (char *)fdt + fdt_off_dt_strings(fdt); -+ const char *p; -+ char *new; -+ int len = strlen(s) + 1; -+ int err; -+ -+ p = _fdt_find_string(strtab, fdt_size_dt_strings(fdt), s); -+ if (p) -+ /* found it */ -+ return (p - strtab); -+ -+ new = strtab + fdt_size_dt_strings(fdt); -+ err = _blob_splice_string(fdt, len); -+ if (err) -+ return err; -+ -+ memcpy(new, s, len); -+ return (new - strtab); -+} -+ -+int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size) -+{ -+ struct fdt_reserve_entry *re; -+ int err; -+ -+ if ((err = rw_check_header(fdt))) -+ return err; -+ -+ re = _fdt_mem_rsv_w(fdt, fdt_num_mem_rsv(fdt)); -+ err = _blob_splice_mem_rsv(fdt, re, 0, 1); -+ if (err) -+ return err; -+ -+ re->address = cpu_to_fdt64(address); -+ re->size = cpu_to_fdt64(size); -+ return 0; -+} -+ -+int fdt_del_mem_rsv(void *fdt, int n) -+{ -+ struct fdt_reserve_entry *re = _fdt_mem_rsv_w(fdt, n); -+ int err; -+ -+ if ((err = rw_check_header(fdt))) -+ return err; -+ if (n >= fdt_num_mem_rsv(fdt)) -+ return -FDT_ERR_NOTFOUND; -+ -+ err = _blob_splice_mem_rsv(fdt, re, 1, 0); -+ if (err) -+ return err; -+ return 0; -+} -+ -+static int _resize_property(void *fdt, int nodeoffset, const char *name, int len, -+ struct fdt_property **prop) -+{ -+ int oldlen; -+ int err; -+ -+ *prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen); -+ if (! (*prop)) -+ return oldlen; -+ -+ if ((err = _blob_splice_struct(fdt, (*prop)->data, -+ ALIGN(oldlen, FDT_TAGSIZE), -+ ALIGN(len, FDT_TAGSIZE)))) -+ return err; -+ -+ (*prop)->len = cpu_to_fdt32(len); -+ return 0; -+} -+ -+static int _add_property(void *fdt, int nodeoffset, const char *name, int len, -+ struct fdt_property **prop) -+{ -+ uint32_t tag; -+ int proplen; -+ int nextoffset; -+ int namestroff; -+ int err; -+ -+ tag = fdt_next_tag(fdt, nodeoffset, &nextoffset); -+ if (tag != FDT_BEGIN_NODE) -+ return -FDT_ERR_BADOFFSET; -+ -+ namestroff = _find_add_string(fdt, name); -+ if (namestroff < 0) -+ return namestroff; -+ -+ *prop = _fdt_offset_ptr_w(fdt, nextoffset); -+ proplen = sizeof(**prop) + ALIGN(len, FDT_TAGSIZE); -+ -+ err = _blob_splice_struct(fdt, *prop, 0, proplen); -+ if (err) -+ return err; -+ -+ (*prop)->tag = cpu_to_fdt32(FDT_PROP); -+ (*prop)->nameoff = cpu_to_fdt32(namestroff); -+ (*prop)->len = cpu_to_fdt32(len); -+ return 0; -+} -+ -+int fdt_setprop(void *fdt, int nodeoffset, const char *name, -+ const void *val, int len) -+{ -+ struct fdt_property *prop; -+ int err; -+ -+ if ((err = rw_check_header(fdt))) -+ return err; -+ -+ err = _resize_property(fdt, nodeoffset, name, len, &prop); -+ if (err == -FDT_ERR_NOTFOUND) -+ err = _add_property(fdt, nodeoffset, name, len, &prop); -+ if (err) -+ return err; -+ -+ memcpy(prop->data, val, len); -+ return 0; -+} -+ -+int fdt_delprop(void *fdt, int nodeoffset, const char *name) -+{ -+ struct fdt_property *prop; -+ int len, proplen; -+ -+ RW_CHECK_HEADER(fdt); -+ -+ prop = fdt_get_property_w(fdt, nodeoffset, name, &len); -+ if (! prop) -+ return len; -+ -+ proplen = sizeof(*prop) + ALIGN(len, FDT_TAGSIZE); -+ return _blob_splice_struct(fdt, prop, proplen, 0); -+} -+ -+int fdt_add_subnode_namelen(void *fdt, int parentoffset, -+ const char *name, int namelen) -+{ -+ struct fdt_node_header *nh; -+ int offset, nextoffset; -+ int nodelen; -+ int err; -+ uint32_t tag; -+ uint32_t *endtag; -+ -+ RW_CHECK_HEADER(fdt); -+ -+ offset = fdt_subnode_offset_namelen(fdt, parentoffset, name, namelen); -+ if (offset >= 0) -+ return -FDT_ERR_EXISTS; -+ else if (offset != -FDT_ERR_NOTFOUND) -+ return offset; -+ -+ /* Try to place the new node after the parent's properties */ -+ fdt_next_tag(fdt, parentoffset, &nextoffset); /* skip the BEGIN_NODE */ -+ do { -+ offset = nextoffset; -+ tag = fdt_next_tag(fdt, offset, &nextoffset); -+ } while (tag == FDT_PROP); -+ -+ nh = _fdt_offset_ptr_w(fdt, offset); -+ nodelen = sizeof(*nh) + ALIGN(namelen+1, FDT_TAGSIZE) + FDT_TAGSIZE; -+ -+ err = _blob_splice_struct(fdt, nh, 0, nodelen); -+ if (err) -+ return err; -+ -+ nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE); -+ memset(nh->name, 0, ALIGN(namelen+1, FDT_TAGSIZE)); -+ memcpy(nh->name, name, namelen); -+ endtag = (uint32_t *)((void *)nh + nodelen - FDT_TAGSIZE); -+ *endtag = cpu_to_fdt32(FDT_END_NODE); -+ -+ return offset; -+} -+ -+int fdt_add_subnode(void *fdt, int parentoffset, const char *name) -+{ -+ return fdt_add_subnode_namelen(fdt, parentoffset, name, strlen(name)); -+} -+ -+int fdt_del_node(void *fdt, int nodeoffset) -+{ -+ int endoffset; -+ -+ RW_CHECK_HEADER(fdt); -+ -+ endoffset = _fdt_node_end_offset(fdt, nodeoffset); -+ if (endoffset < 0) -+ return endoffset; -+ -+ return _blob_splice_struct(fdt, _fdt_offset_ptr_w(fdt, nodeoffset), -+ endoffset - nodeoffset, 0); -+} -+ -+static void _packblocks(const void *fdt, void *buf, -+ int mem_rsv_size, int struct_size) -+{ -+ int mem_rsv_off, struct_off, strings_off; -+ -+ mem_rsv_off = ALIGN(sizeof(struct fdt_header), 8); -+ struct_off = mem_rsv_off + mem_rsv_size; -+ strings_off = struct_off + struct_size; -+ -+ memmove(buf + mem_rsv_off, fdt + fdt_off_mem_rsvmap(fdt), mem_rsv_size); -+ fdt_set_off_mem_rsvmap(buf, mem_rsv_off); -+ -+ memmove(buf + struct_off, fdt + fdt_off_dt_struct(fdt), struct_size); -+ fdt_set_off_dt_struct(buf, struct_off); -+ fdt_set_size_dt_struct(buf, struct_size); -+ -+ memmove(buf + strings_off, fdt + fdt_off_dt_strings(fdt), -+ fdt_size_dt_strings(fdt)); -+ fdt_set_off_dt_strings(buf, strings_off); -+ fdt_set_size_dt_strings(buf, fdt_size_dt_strings(fdt)); -+} -+ -+int fdt_open_into(const void *fdt, void *buf, int bufsize) -+{ -+ int err; -+ int mem_rsv_size, struct_size; -+ int newsize; -+ void *tmp; -+ -+ err = fdt_check_header(fdt); -+ if (err) -+ return err; -+ -+ mem_rsv_size = (fdt_num_mem_rsv(fdt)+1) -+ * sizeof(struct fdt_reserve_entry); -+ -+ if (fdt_version(fdt) >= 17) { -+ struct_size = fdt_size_dt_struct(fdt); -+ } else { -+ struct_size = 0; -+ while (fdt_next_tag(fdt, struct_size, &struct_size) != FDT_END) -+ ; -+ } -+ -+ if (!_blocks_misordered(fdt, mem_rsv_size, struct_size)) { -+ /* no further work necessary */ -+ err = fdt_move(fdt, buf, bufsize); -+ if (err) -+ return err; -+ fdt_set_version(buf, 17); -+ fdt_set_size_dt_struct(buf, struct_size); -+ fdt_set_totalsize(buf, bufsize); -+ return 0; -+ } -+ -+ /* Need to reorder */ -+ newsize = ALIGN(sizeof(struct fdt_header), 8) + mem_rsv_size -+ + struct_size + fdt_size_dt_strings(fdt); -+ -+ if (bufsize < newsize) -+ return -FDT_ERR_NOSPACE; -+ -+ if (((buf + newsize) <= fdt) -+ || (buf >= (fdt + fdt_totalsize(fdt)))) { -+ tmp = buf; -+ } else { -+ tmp = (void *)fdt + fdt_totalsize(fdt); -+ if ((tmp + newsize) > (buf + bufsize)) -+ return -FDT_ERR_NOSPACE; -+ } -+ -+ _packblocks(fdt, tmp, mem_rsv_size, struct_size); -+ memmove(buf, tmp, newsize); -+ -+ fdt_set_magic(buf, FDT_MAGIC); -+ fdt_set_totalsize(buf, bufsize); -+ fdt_set_version(buf, 17); -+ fdt_set_last_comp_version(buf, 16); -+ fdt_set_boot_cpuid_phys(buf, fdt_boot_cpuid_phys(fdt)); -+ -+ return 0; -+} -+ -+int fdt_pack(void *fdt) -+{ -+ int mem_rsv_size; -+ int err; -+ -+ err = rw_check_header(fdt); -+ if (err) -+ return err; -+ -+ mem_rsv_size = (fdt_num_mem_rsv(fdt)+1) -+ * sizeof(struct fdt_reserve_entry); -+ _packblocks(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt)); -+ fdt_set_totalsize(fdt, _blob_data_size(fdt)); -+ -+ return 0; -+} ---- /dev/null -+++ b/arch/powerpc/boot/libfdt/fdt_strerror.c -@@ -0,0 +1,96 @@ -+/* -+ * libfdt - Flat Device Tree manipulation -+ * Copyright (C) 2006 David Gibson, IBM Corporation. -+ * -+ * libfdt is dual licensed: you can use it either under the terms of -+ * the GPL, or the BSD license, at your option. -+ * -+ * a) This library 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 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 General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public -+ * License along with this library; if not, write to the Free -+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, -+ * MA 02110-1301 USA -+ * -+ * Alternatively, -+ * -+ * b) 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. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. -+ */ -+#include "libfdt_env.h" -+ -+#include -+#include -+ -+#include "libfdt_internal.h" -+ -+struct errtabent { -+ const char *str; -+}; -+ -+#define ERRTABENT(val) \ -+ [(val)] = { .str = #val, } -+ -+static struct errtabent errtable[] = { -+ ERRTABENT(FDT_ERR_NOTFOUND), -+ ERRTABENT(FDT_ERR_EXISTS), -+ ERRTABENT(FDT_ERR_NOSPACE), -+ -+ ERRTABENT(FDT_ERR_BADOFFSET), -+ ERRTABENT(FDT_ERR_BADPATH), -+ ERRTABENT(FDT_ERR_BADSTATE), -+ -+ ERRTABENT(FDT_ERR_TRUNCATED), -+ ERRTABENT(FDT_ERR_BADMAGIC), -+ ERRTABENT(FDT_ERR_BADVERSION), -+ ERRTABENT(FDT_ERR_BADSTRUCTURE), -+ ERRTABENT(FDT_ERR_BADLAYOUT), -+}; -+#define ERRTABSIZE (sizeof(errtable) / sizeof(errtable[0])) -+ -+const char *fdt_strerror(int errval) -+{ -+ if (errval > 0) -+ return ""; -+ else if (errval == 0) -+ return ""; -+ else if (errval > -ERRTABSIZE) { -+ const char *s = errtable[-errval].str; -+ -+ if (s) -+ return s; -+ } -+ -+ return ""; -+} ---- /dev/null -+++ b/arch/powerpc/boot/libfdt/fdt_sw.c -@@ -0,0 +1,258 @@ -+/* -+ * libfdt - Flat Device Tree manipulation -+ * Copyright (C) 2006 David Gibson, IBM Corporation. -+ * -+ * libfdt is dual licensed: you can use it either under the terms of -+ * the GPL, or the BSD license, at your option. -+ * -+ * a) This library 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 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 General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public -+ * License along with this library; if not, write to the Free -+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, -+ * MA 02110-1301 USA -+ * -+ * Alternatively, -+ * -+ * b) 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. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. -+ */ -+#include "libfdt_env.h" -+ -+#include -+#include -+ -+#include "libfdt_internal.h" -+ -+static int check_header_sw(void *fdt) -+{ -+ if (fdt_magic(fdt) != SW_MAGIC) -+ return -FDT_ERR_BADMAGIC; -+ return 0; -+} -+ -+static void *grab_space(void *fdt, int len) -+{ -+ int offset = fdt_size_dt_struct(fdt); -+ int spaceleft; -+ -+ spaceleft = fdt_totalsize(fdt) - fdt_off_dt_struct(fdt) -+ - fdt_size_dt_strings(fdt); -+ -+ if ((offset + len < offset) || (offset + len > spaceleft)) -+ return NULL; -+ -+ fdt_set_size_dt_struct(fdt, offset + len); -+ return fdt_offset_ptr_w(fdt, offset, len); -+} -+ -+int fdt_create(void *buf, int bufsize) -+{ -+ void *fdt = buf; -+ -+ if (bufsize < sizeof(struct fdt_header)) -+ return -FDT_ERR_NOSPACE; -+ -+ memset(buf, 0, bufsize); -+ -+ fdt_set_magic(fdt, SW_MAGIC); -+ fdt_set_version(fdt, FDT_LAST_SUPPORTED_VERSION); -+ fdt_set_last_comp_version(fdt, FDT_FIRST_SUPPORTED_VERSION); -+ fdt_set_totalsize(fdt, bufsize); -+ -+ fdt_set_off_mem_rsvmap(fdt, ALIGN(sizeof(struct fdt_header), -+ sizeof(struct fdt_reserve_entry))); -+ fdt_set_off_dt_struct(fdt, fdt_off_mem_rsvmap(fdt)); -+ fdt_set_off_dt_strings(fdt, bufsize); -+ -+ return 0; -+} -+ -+int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size) -+{ -+ struct fdt_reserve_entry *re; -+ int err = check_header_sw(fdt); -+ int offset; -+ -+ if (err) -+ return err; -+ if (fdt_size_dt_struct(fdt)) -+ return -FDT_ERR_BADSTATE; -+ -+ offset = fdt_off_dt_struct(fdt); -+ if ((offset + sizeof(*re)) > fdt_totalsize(fdt)) -+ return -FDT_ERR_NOSPACE; -+ -+ re = (struct fdt_reserve_entry *)(fdt + offset); -+ re->address = cpu_to_fdt64(addr); -+ re->size = cpu_to_fdt64(size); -+ -+ fdt_set_off_dt_struct(fdt, offset + sizeof(*re)); -+ -+ return 0; -+} -+ -+int fdt_finish_reservemap(void *fdt) -+{ -+ return fdt_add_reservemap_entry(fdt, 0, 0); -+} -+ -+int fdt_begin_node(void *fdt, const char *name) -+{ -+ struct fdt_node_header *nh; -+ int err = check_header_sw(fdt); -+ int namelen = strlen(name) + 1; -+ -+ if (err) -+ return err; -+ -+ nh = grab_space(fdt, sizeof(*nh) + ALIGN(namelen, FDT_TAGSIZE)); -+ if (! nh) -+ return -FDT_ERR_NOSPACE; -+ -+ nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE); -+ memcpy(nh->name, name, namelen); -+ return 0; -+} -+ -+int fdt_end_node(void *fdt) -+{ -+ uint32_t *en; -+ int err = check_header_sw(fdt); -+ -+ if (err) -+ return err; -+ -+ en = grab_space(fdt, FDT_TAGSIZE); -+ if (! en) -+ return -FDT_ERR_NOSPACE; -+ -+ *en = cpu_to_fdt32(FDT_END_NODE); -+ return 0; -+} -+ -+static int find_add_string(void *fdt, const char *s) -+{ -+ char *strtab = (char *)fdt + fdt_totalsize(fdt); -+ const char *p; -+ int strtabsize = fdt_size_dt_strings(fdt); -+ int len = strlen(s) + 1; -+ int struct_top, offset; -+ -+ p = _fdt_find_string(strtab - strtabsize, strtabsize, s); -+ if (p) -+ return p - strtab; -+ -+ /* Add it */ -+ offset = -strtabsize - len; -+ struct_top = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt); -+ if (fdt_totalsize(fdt) + offset < struct_top) -+ return 0; /* no more room :( */ -+ -+ memcpy(strtab + offset, s, len); -+ fdt_set_size_dt_strings(fdt, strtabsize + len); -+ return offset; -+} -+ -+int fdt_property(void *fdt, const char *name, const void *val, int len) -+{ -+ struct fdt_property *prop; -+ int err = check_header_sw(fdt); -+ int nameoff; -+ -+ if (err) -+ return err; -+ -+ nameoff = find_add_string(fdt, name); -+ if (nameoff == 0) -+ return -FDT_ERR_NOSPACE; -+ -+ prop = grab_space(fdt, sizeof(*prop) + ALIGN(len, FDT_TAGSIZE)); -+ if (! prop) -+ return -FDT_ERR_NOSPACE; -+ -+ prop->tag = cpu_to_fdt32(FDT_PROP); -+ prop->nameoff = cpu_to_fdt32(nameoff); -+ prop->len = cpu_to_fdt32(len); -+ memcpy(prop->data, val, len); -+ return 0; -+} -+ -+int fdt_finish(void *fdt) -+{ -+ int err = check_header_sw(fdt); -+ char *p = (char *)fdt; -+ uint32_t *end; -+ int oldstroffset, newstroffset; -+ uint32_t tag; -+ int offset, nextoffset; -+ -+ if (err) -+ return err; -+ -+ /* Add terminator */ -+ end = grab_space(fdt, sizeof(*end)); -+ if (! end) -+ return -FDT_ERR_NOSPACE; -+ *end = cpu_to_fdt32(FDT_END); -+ -+ /* Relocate the string table */ -+ oldstroffset = fdt_totalsize(fdt) - fdt_size_dt_strings(fdt); -+ newstroffset = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt); -+ memmove(p + newstroffset, p + oldstroffset, fdt_size_dt_strings(fdt)); -+ fdt_set_off_dt_strings(fdt, newstroffset); -+ -+ /* Walk the structure, correcting string offsets */ -+ offset = 0; -+ while ((tag = fdt_next_tag(fdt, offset, &nextoffset)) != FDT_END) { -+ if (tag == FDT_PROP) { -+ struct fdt_property *prop = -+ fdt_offset_ptr_w(fdt, offset, sizeof(*prop)); -+ int nameoff; -+ -+ if (! prop) -+ return -FDT_ERR_BADSTRUCTURE; -+ -+ nameoff = fdt32_to_cpu(prop->nameoff); -+ nameoff += fdt_size_dt_strings(fdt); -+ prop->nameoff = cpu_to_fdt32(nameoff); -+ } -+ offset = nextoffset; -+ } -+ -+ /* Finally, adjust the header */ -+ fdt_set_totalsize(fdt, newstroffset + fdt_size_dt_strings(fdt)); -+ fdt_set_magic(fdt, FDT_MAGIC); -+ return 0; -+} ---- /dev/null -+++ b/arch/powerpc/boot/libfdt/fdt_wip.c -@@ -0,0 +1,144 @@ -+/* -+ * libfdt - Flat Device Tree manipulation -+ * Copyright (C) 2006 David Gibson, IBM Corporation. -+ * -+ * libfdt is dual licensed: you can use it either under the terms of -+ * the GPL, or the BSD license, at your option. -+ * -+ * a) This library 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 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 General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public -+ * License along with this library; if not, write to the Free -+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, -+ * MA 02110-1301 USA -+ * -+ * Alternatively, -+ * -+ * b) 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. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. -+ */ -+#include "libfdt_env.h" -+ -+#include -+#include -+ -+#include "libfdt_internal.h" -+ -+int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name, -+ const void *val, int len) -+{ -+ void *propval; -+ int proplen; -+ -+ propval = fdt_getprop_w(fdt, nodeoffset, name, &proplen); -+ if (! propval) -+ return proplen; -+ -+ if (proplen != len) -+ return -FDT_ERR_NOSPACE; -+ -+ memcpy(propval, val, len); -+ return 0; -+} -+ -+static void nop_region(void *start, int len) -+{ -+ uint32_t *p; -+ -+ for (p = start; (void *)p < (start + len); p++) -+ *p = cpu_to_fdt32(FDT_NOP); -+} -+ -+int fdt_nop_property(void *fdt, int nodeoffset, const char *name) -+{ -+ struct fdt_property *prop; -+ int len; -+ -+ prop = fdt_get_property_w(fdt, nodeoffset, name, &len); -+ if (! prop) -+ return len; -+ -+ nop_region(prop, len + sizeof(*prop)); -+ -+ return 0; -+} -+ -+int _fdt_node_end_offset(void *fdt, int nodeoffset) -+{ -+ int level = 0; -+ uint32_t tag; -+ int offset, nextoffset; -+ -+ tag = fdt_next_tag(fdt, nodeoffset, &nextoffset); -+ if (tag != FDT_BEGIN_NODE) -+ return -FDT_ERR_BADOFFSET; -+ do { -+ offset = nextoffset; -+ tag = fdt_next_tag(fdt, offset, &nextoffset); -+ -+ switch (tag) { -+ case FDT_END: -+ return offset; -+ -+ case FDT_BEGIN_NODE: -+ level++; -+ break; -+ -+ case FDT_END_NODE: -+ level--; -+ break; -+ -+ case FDT_PROP: -+ case FDT_NOP: -+ break; -+ -+ default: -+ return -FDT_ERR_BADSTRUCTURE; -+ } -+ } while (level >= 0); -+ -+ return nextoffset; -+} -+ -+int fdt_nop_node(void *fdt, int nodeoffset) -+{ -+ int endoffset; -+ -+ endoffset = _fdt_node_end_offset(fdt, nodeoffset); -+ if (endoffset < 0) -+ return endoffset; -+ -+ nop_region(fdt_offset_ptr_w(fdt, nodeoffset, 0), endoffset - nodeoffset); -+ return 0; -+} ---- /dev/null -+++ b/arch/powerpc/boot/libfdt/libfdt.h -@@ -0,0 +1,721 @@ -+#ifndef _LIBFDT_H -+#define _LIBFDT_H -+/* -+ * libfdt - Flat Device Tree manipulation -+ * Copyright (C) 2006 David Gibson, IBM Corporation. -+ * -+ * libfdt is dual licensed: you can use it either under the terms of -+ * the GPL, or the BSD license, at your option. -+ * -+ * a) This library 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 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 General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public -+ * License along with this library; if not, write to the Free -+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, -+ * MA 02110-1301 USA -+ * -+ * Alternatively, -+ * -+ * b) 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. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. -+ */ -+ -+#include -+#include -+ -+#define FDT_FIRST_SUPPORTED_VERSION 0x10 -+#define FDT_LAST_SUPPORTED_VERSION 0x11 -+ -+/* Error codes: informative error codes */ -+#define FDT_ERR_NOTFOUND 1 -+ /* FDT_ERR_NOTFOUND: The requested node or property does not exist */ -+#define FDT_ERR_EXISTS 2 -+ /* FDT_ERR_EXISTS: Attemped to create a node or property which -+ * already exists */ -+#define FDT_ERR_NOSPACE 3 -+ /* FDT_ERR_NOSPACE: Operation needed to expand the device -+ * tree, but its buffer did not have sufficient space to -+ * contain the expanded tree. Use fdt_open_into() to move the -+ * device tree to a buffer with more space. */ -+ -+/* Error codes: codes for bad parameters */ -+#define FDT_ERR_BADOFFSET 4 -+ /* FDT_ERR_BADOFFSET: Function was passed a structure block -+ * offset which is out-of-bounds, or which points to an -+ * unsuitable part of the structure for the operation. */ -+#define FDT_ERR_BADPATH 5 -+ /* FDT_ERR_BADPATH: Function was passed a badly formatted path -+ * (e.g. missing a leading / for a function which requires an -+ * absolute path) */ -+#define FDT_ERR_BADPHANDLE 6 -+ /* FDT_ERR_BADPHANDLE: Function was passed an invalid phandle -+ * value. phandle values of 0 and -1 are not permitted. */ -+#define FDT_ERR_BADSTATE 7 -+ /* FDT_ERR_BADSTATE: Function was passed an incomplete device -+ * tree created by the sequential-write functions, which is -+ * not sufficiently complete for the requested operation. */ -+ -+/* Error codes: codes for bad device tree blobs */ -+#define FDT_ERR_TRUNCATED 8 -+ /* FDT_ERR_TRUNCATED: Structure block of the given device tree -+ * ends without an FDT_END tag. */ -+#define FDT_ERR_BADMAGIC 9 -+ /* FDT_ERR_BADMAGIC: Given "device tree" appears not to be a -+ * device tree at all - it is missing the flattened device -+ * tree magic number. */ -+#define FDT_ERR_BADVERSION 10 -+ /* FDT_ERR_BADVERSION: Given device tree has a version which -+ * can't be handled by the requested operation. For -+ * read-write functions, this may mean that fdt_open_into() is -+ * required to convert the tree to the expected version. */ -+#define FDT_ERR_BADSTRUCTURE 11 -+ /* FDT_ERR_BADSTRUCTURE: Given device tree has a corrupt -+ * structure block or other serious error (e.g. misnested -+ * nodes, or subnodes preceding properties). */ -+#define FDT_ERR_BADLAYOUT 12 -+ /* FDT_ERR_BADLAYOUT: For read-write functions, the given -+ * device tree has it's sub-blocks in an order that the -+ * function can't handle (memory reserve map, then structure, -+ * then strings). Use fdt_open_into() to reorganize the tree -+ * into a form suitable for the read-write operations. */ -+ -+/* "Can't happen" error indicating a bug in libfdt */ -+#define FDT_ERR_INTERNAL 13 -+ /* FDT_ERR_INTERNAL: libfdt has failed an internal assertion. -+ * Should never be returned, if it is, it indicates a bug in -+ * libfdt itself. */ -+ -+#define FDT_ERR_MAX 13 -+ -+/**********************************************************************/ -+/* Low-level functions (you probably don't need these) */ -+/**********************************************************************/ -+ -+const void *fdt_offset_ptr(const void *fdt, int offset, int checklen); -+static inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen) -+{ -+ return (void *)fdt_offset_ptr(fdt, offset, checklen); -+} -+ -+uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset); -+ -+/**********************************************************************/ -+/* General functions */ -+/**********************************************************************/ -+ -+#define fdt_get_header(fdt, field) \ -+ (fdt32_to_cpu(((const struct fdt_header *)(fdt))->field)) -+#define fdt_magic(fdt) (fdt_get_header(fdt, magic)) -+#define fdt_totalsize(fdt) (fdt_get_header(fdt, totalsize)) -+#define fdt_off_dt_struct(fdt) (fdt_get_header(fdt, off_dt_struct)) -+#define fdt_off_dt_strings(fdt) (fdt_get_header(fdt, off_dt_strings)) -+#define fdt_off_mem_rsvmap(fdt) (fdt_get_header(fdt, off_mem_rsvmap)) -+#define fdt_version(fdt) (fdt_get_header(fdt, version)) -+#define fdt_last_comp_version(fdt) (fdt_get_header(fdt, last_comp_version)) -+#define fdt_boot_cpuid_phys(fdt) (fdt_get_header(fdt, boot_cpuid_phys)) -+#define fdt_size_dt_strings(fdt) (fdt_get_header(fdt, size_dt_strings)) -+#define fdt_size_dt_struct(fdt) (fdt_get_header(fdt, size_dt_struct)) -+ -+#define __fdt_set_hdr(name) \ -+ static inline void fdt_set_##name(void *fdt, uint32_t val) \ -+ { \ -+ struct fdt_header *fdth = fdt; \ -+ fdth->name = cpu_to_fdt32(val); \ -+ } -+__fdt_set_hdr(magic); -+__fdt_set_hdr(totalsize); -+__fdt_set_hdr(off_dt_struct); -+__fdt_set_hdr(off_dt_strings); -+__fdt_set_hdr(off_mem_rsvmap); -+__fdt_set_hdr(version); -+__fdt_set_hdr(last_comp_version); -+__fdt_set_hdr(boot_cpuid_phys); -+__fdt_set_hdr(size_dt_strings); -+__fdt_set_hdr(size_dt_struct); -+#undef __fdt_set_hdr -+ -+/** -+ * fdt_check_header - sanity check a device tree or possible device tree -+ * @fdt: pointer to data which might be a flattened device tree -+ * -+ * fdt_check_header() checks that the given buffer contains what -+ * appears to be a flattened device tree with sane information in its -+ * header. -+ * -+ * returns: -+ * 0, if the buffer appears to contain a valid device tree -+ * -FDT_ERR_BADMAGIC, -+ * -FDT_ERR_BADVERSION, -+ * -FDT_ERR_BADSTATE, standard meanings, as above -+ */ -+int fdt_check_header(const void *fdt); -+ -+/** -+ * fdt_move - move a device tree around in memory -+ * @fdt: pointer to the device tree to move -+ * @buf: pointer to memory where the device is to be moved -+ * @bufsize: size of the memory space at buf -+ * -+ * fdt_move() relocates, if possible, the device tree blob located at -+ * fdt to the buffer at buf of size bufsize. The buffer may overlap -+ * with the existing device tree blob at fdt. Therefore, -+ * fdt_move(fdt, fdt, fdt_totalsize(fdt)) -+ * should always succeed. -+ * -+ * returns: -+ * 0, on success -+ * -FDT_ERR_NOSPACE, bufsize is insufficient to contain the device tree -+ * -FDT_ERR_BADMAGIC, -+ * -FDT_ERR_BADVERSION, -+ * -FDT_ERR_BADSTATE, standard meanings -+ */ -+int fdt_move(const void *fdt, void *buf, int bufsize); -+ -+/**********************************************************************/ -+/* Read-only functions */ -+/**********************************************************************/ -+ -+/** -+ * fdt_string - retreive a string from the strings block of a device tree -+ * @fdt: pointer to the device tree blob -+ * @stroffset: offset of the string within the strings block (native endian) -+ * -+ * fdt_string() retrieves a pointer to a single string from the -+ * strings block of the device tree blob at fdt. -+ * -+ * returns: -+ * a pointer to the string, on success -+ * NULL, if stroffset is out of bounds -+ */ -+const char *fdt_string(const void *fdt, int stroffset); -+ -+/** -+ * fdt_num_mem_rsv - retreive the number of memory reserve map entries -+ * @fdt: pointer to the device tree blob -+ * -+ * Returns the number of entries in the device tree blob's memory -+ * reservation map. This does not include the terminating 0,0 entry -+ * or any other (0,0) entries reserved for expansion. -+ * -+ * returns: -+ * the number of entries -+ */ -+int fdt_num_mem_rsv(const void *fdt); -+ -+/** -+ * fdt_get_mem_rsv - retreive one memory reserve map entry -+ * @fdt: pointer to the device tree blob -+ * @address, @size: pointers to 64-bit variables -+ * -+ * On success, *address and *size will contain the address and size of -+ * the n-th reserve map entry from the device tree blob, in -+ * native-endian format. -+ * -+ * returns: -+ * 0, on success -+ * -FDT_ERR_BADMAGIC, -+ * -FDT_ERR_BADVERSION, -+ * -FDT_ERR_BADSTATE, standard meanings -+ */ -+int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size); -+ -+/** -+ * fdt_subnode_offset_namelen - find a subnode based on substring -+ * @fdt: pointer to the device tree blob -+ * @parentoffset: structure block offset of a node -+ * @name: name of the subnode to locate -+ * @namelen: number of characters of name to consider -+ * -+ * Identical to fdt_subnode_offset(), but only examine the first -+ * namelen characters of name for matching the subnode name. This is -+ * useful for finding subnodes based on a portion of a larger string, -+ * such as a full path. -+ */ -+int fdt_subnode_offset_namelen(const void *fdt, int parentoffset, -+ const char *name, int namelen); -+/** -+ * fdt_subnode_offset - find a subnode of a given node -+ * @fdt: pointer to the device tree blob -+ * @parentoffset: structure block offset of a node -+ * @name: name of the subnode to locate -+ * -+ * fdt_subnode_offset() finds a subnode of the node at structure block -+ * offset parentoffset with the given name. name may include a unit -+ * address, in which case fdt_subnode_offset() will find the subnode -+ * with that unit address, or the unit address may be omitted, in -+ * which case fdt_subnode_offset() will find an arbitrary subnode -+ * whose name excluding unit address matches the given name. -+ * -+ * returns: -+ * structure block offset of the requested subnode (>=0), on success -+ * -FDT_ERR_NOTFOUND, if the requested subnode does not exist -+ * -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE tag -+ * -FDT_ERR_BADMAGIC, -+ * -FDT_ERR_BADVERSION, -+ * -FDT_ERR_BADSTATE, -+ * -FDT_ERR_BADSTRUCTURE, -+ * -FDT_ERR_TRUNCATED, standard meanings. -+ */ -+int fdt_subnode_offset(const void *fdt, int parentoffset, const char *name); -+ -+/** -+ * fdt_path_offset - find a tree node by its full path -+ * @fdt: pointer to the device tree blob -+ * @path: full path of the node to locate -+ * -+ * fdt_path_offset() finds a node of a given path in the device tree. -+ * Each path component may omit the unit address portion, but the -+ * results of this are undefined if any such path component is -+ * ambiguous (that is if there are multiple nodes at the relevant -+ * level matching the given component, differentiated only by unit -+ * address). -+ * -+ * returns: -+ * structure block offset of the node with the requested path (>=0), on success -+ * -FDT_ERR_BADPATH, given path does not begin with '/' or is invalid -+ * -FDT_ERR_NOTFOUND, if the requested node does not exist -+ * -FDT_ERR_BADMAGIC, -+ * -FDT_ERR_BADVERSION, -+ * -FDT_ERR_BADSTATE, -+ * -FDT_ERR_BADSTRUCTURE, -+ * -FDT_ERR_TRUNCATED, standard meanings. -+ */ -+int fdt_path_offset(const void *fdt, const char *path); -+ -+/** -+ * fdt_get_name - retreive the name of a given node -+ * @fdt: pointer to the device tree blob -+ * @nodeoffset: structure block offset of the starting node -+ * @lenp: pointer to an integer variable (will be overwritten) or NULL -+ * -+ * fdt_get_name() retrieves the name (including unit address) of the -+ * device tree node at structure block offset nodeoffset. If lenp is -+ * non-NULL, the length of this name is also returned, in the integer -+ * pointed to by lenp. -+ * -+ * returns: -+ * pointer to the node's name, on success -+ * If lenp is non-NULL, *lenp contains the length of that name (>=0) -+ * NULL, on error -+ * if lenp is non-NULL *lenp contains an error code (<0): -+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag -+ * -FDT_ERR_BADMAGIC, -+ * -FDT_ERR_BADVERSION, -+ * -FDT_ERR_BADSTATE, standard meanings -+ */ -+const char *fdt_get_name(const void *fdt, int nodeoffset, int *lenp); -+ -+/** -+ * fdt_get_property - find a given property in a given node -+ * @fdt: pointer to the device tree blob -+ * @nodeoffset: offset of the node whose property to find -+ * @name: name of the property to find -+ * @lenp: pointer to an integer variable (will be overwritten) or NULL -+ * -+ * fdt_get_property() retrieves a pointer to the fdt_property -+ * structure within the device tree blob corresponding to the property -+ * named 'name' of the node at offset nodeoffset. If lenp is -+ * non-NULL, the length of the property value also returned, in the -+ * integer pointed to by lenp. -+ * -+ * returns: -+ * pointer to the structure representing the property -+ * if lenp is non-NULL, *lenp contains the length of the property -+ * value (>=0) -+ * NULL, on error -+ * if lenp is non-NULL, *lenp contains an error code (<0): -+ * -FDT_ERR_NOTFOUND, node does not have named property -+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag -+ * -FDT_ERR_BADMAGIC, -+ * -FDT_ERR_BADVERSION, -+ * -FDT_ERR_BADSTATE, -+ * -FDT_ERR_BADSTRUCTURE, -+ * -FDT_ERR_TRUNCATED, standard meanings -+ */ -+const struct fdt_property *fdt_get_property(const void *fdt, int nodeoffset, -+ const char *name, int *lenp); -+static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset, -+ const char *name, -+ int *lenp) -+{ -+ return (struct fdt_property *)fdt_get_property(fdt, nodeoffset, -+ name, lenp); -+} -+ -+/** -+ * fdt_getprop - retrieve the value of a given property -+ * @fdt: pointer to the device tree blob -+ * @nodeoffset: offset of the node whose property to find -+ * @name: name of the property to find -+ * @lenp: pointer to an integer variable (will be overwritten) or NULL -+ * -+ * fdt_getprop() retrieves a pointer to the value of the property -+ * named 'name' of the node at offset nodeoffset (this will be a -+ * pointer to within the device blob itself, not a copy of the value). -+ * If lenp is non-NULL, the length of the property value also -+ * returned, in the integer pointed to by lenp. -+ * -+ * returns: -+ * pointer to the property's value -+ * if lenp is non-NULL, *lenp contains the length of the property -+ * value (>=0) -+ * NULL, on error -+ * if lenp is non-NULL, *lenp contains an error code (<0): -+ * -FDT_ERR_NOTFOUND, node does not have named property -+ * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag -+ * -FDT_ERR_BADMAGIC, -+ * -FDT_ERR_BADVERSION, -+ * -FDT_ERR_BADSTATE, -+ * -FDT_ERR_BADSTRUCTURE, -+ * -FDT_ERR_TRUNCATED, standard meanings -+ */ -+const void *fdt_getprop(const void *fdt, int nodeoffset, -+ const char *name, int *lenp); -+static inline void *fdt_getprop_w(void *fdt, int nodeoffset, -+ const char *name, int *lenp) -+{ -+ return (void *)fdt_getprop(fdt, nodeoffset, name, lenp); -+} -+ -+/** -+ * fdt_get_phandle - retreive the phandle of a given node -+ * @fdt: pointer to the device tree blob -+ * @nodeoffset: structure block offset of the node -+ * -+ * fdt_get_phandle() retrieves the phandle of the device tree node at -+ * structure block offset nodeoffset. -+ * -+ * returns: -+ * the phandle of the node at nodeoffset, on succes (!= 0, != -1) -+ * 0, if the node has no phandle, or another error occurs -+ */ -+uint32_t fdt_get_phandle(const void *fdt, int nodeoffset); -+ -+/** -+ * fdt_get_path - determine the full path of a node -+ * @fdt: pointer to the device tree blob -+ * @nodeoffset: offset of the node whose path to find -+ * @buf: character buffer to contain the returned path (will be overwritten) -+ * @buflen: size of the character buffer at buf -+ * -+ * fdt_get_path() computes the full path of the node at offset -+ * nodeoffset, and records that path in the buffer at buf. -+ * -+ * NOTE: This function is expensive, as it must scan the device tree -+ * structure from the start to nodeoffset. -+ * -+ * returns: -+ * 0, on success -+ * buf contains the absolute path of the node at -+ * nodeoffset, as a NUL-terminated string. -+ * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag -+ * -FDT_ERR_NOSPACE, the path of the given node is longer than (bufsize-1) -+ * characters and will not fit in the given buffer. -+ * -FDT_ERR_BADMAGIC, -+ * -FDT_ERR_BADVERSION, -+ * -FDT_ERR_BADSTATE, -+ * -FDT_ERR_BADSTRUCTURE, standard meanings -+ */ -+int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen); -+ -+/** -+ * fdt_supernode_atdepth_offset - find a specific ancestor of a node -+ * @fdt: pointer to the device tree blob -+ * @nodeoffset: offset of the node whose parent to find -+ * @supernodedepth: depth of the ancestor to find -+ * @nodedepth: pointer to an integer variable (will be overwritten) or NULL -+ * -+ * fdt_supernode_atdepth_offset() finds an ancestor of the given node -+ * at a specific depth from the root (where the root itself has depth -+ * 0, its immediate subnodes depth 1 and so forth). So -+ * fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, NULL); -+ * will always return 0, the offset of the root node. If the node at -+ * nodeoffset has depth D, then: -+ * fdt_supernode_atdepth_offset(fdt, nodeoffset, D, NULL); -+ * will return nodeoffset itself. -+ * -+ * NOTE: This function is expensive, as it must scan the device tree -+ * structure from the start to nodeoffset. -+ * -+ * returns: -+ -+ * structure block offset of the node at node offset's ancestor -+ * of depth supernodedepth (>=0), on success -+ * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag -+* -FDT_ERR_NOTFOUND, supernodedepth was greater than the depth of nodeoffset -+ * -FDT_ERR_BADMAGIC, -+ * -FDT_ERR_BADVERSION, -+ * -FDT_ERR_BADSTATE, -+ * -FDT_ERR_BADSTRUCTURE, standard meanings -+ */ -+int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset, -+ int supernodedepth, int *nodedepth); -+ -+/** -+ * fdt_node_depth - find the depth of a given node -+ * @fdt: pointer to the device tree blob -+ * @nodeoffset: offset of the node whose parent to find -+ * -+ * fdt_node_depth() finds the depth of a given node. The root node -+ * has depth 0, its immediate subnodes depth 1 and so forth. -+ * -+ * NOTE: This function is expensive, as it must scan the device tree -+ * structure from the start to nodeoffset. -+ * -+ * returns: -+ * depth of the node at nodeoffset (>=0), on success -+ * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag -+ * -FDT_ERR_BADMAGIC, -+ * -FDT_ERR_BADVERSION, -+ * -FDT_ERR_BADSTATE, -+ * -FDT_ERR_BADSTRUCTURE, standard meanings -+ */ -+int fdt_node_depth(const void *fdt, int nodeoffset); -+ -+/** -+ * fdt_parent_offset - find the parent of a given node -+ * @fdt: pointer to the device tree blob -+ * @nodeoffset: offset of the node whose parent to find -+ * -+ * fdt_parent_offset() locates the parent node of a given node (that -+ * is, it finds the offset of the node which contains the node at -+ * nodeoffset as a subnode). -+ * -+ * NOTE: This function is expensive, as it must scan the device tree -+ * structure from the start to nodeoffset, *twice*. -+ * -+ * returns: -+ * stucture block offset of the parent of the node at nodeoffset -+ * (>=0), on success -+ * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag -+ * -FDT_ERR_BADMAGIC, -+ * -FDT_ERR_BADVERSION, -+ * -FDT_ERR_BADSTATE, -+ * -FDT_ERR_BADSTRUCTURE, standard meanings -+ */ -+int fdt_parent_offset(const void *fdt, int nodeoffset); -+ -+/** -+ * fdt_node_offset_by_prop_value - find nodes with a given property value -+ * @fdt: pointer to the device tree blob -+ * @startoffset: only find nodes after this offset -+ * @propname: property name to check -+ * @propval: property value to search for -+ * @proplen: length of the value in propval -+ * -+ * fdt_node_offset_by_prop_value() returns the offset of the first -+ * node after startoffset, which has a property named propname whose -+ * value is of length proplen and has value equal to propval; or if -+ * startoffset is -1, the very first such node in the tree. -+ * -+ * To iterate through all nodes matching the criterion, the following -+ * idiom can be used: -+ * offset = fdt_node_offset_by_prop_value(fdt, -1, propname, -+ * propval, proplen); -+ * while (offset != -FDT_ERR_NOTFOUND) { -+ * // other code here -+ * offset = fdt_node_offset_by_prop_value(fdt, offset, propname, -+ * propval, proplen); -+ * } -+ * -+ * Note the -1 in the first call to the function, if 0 is used here -+ * instead, the function will never locate the root node, even if it -+ * matches the criterion. -+ * -+ * returns: -+ * structure block offset of the located node (>= 0, >startoffset), -+ * on success -+ * -FDT_ERR_NOTFOUND, no node matching the criterion exists in the -+ * tree after startoffset -+ * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag -+ * -FDT_ERR_BADMAGIC, -+ * -FDT_ERR_BADVERSION, -+ * -FDT_ERR_BADSTATE, -+ * -FDT_ERR_BADSTRUCTURE, standard meanings -+ */ -+int fdt_node_offset_by_prop_value(const void *fdt, int startoffset, -+ const char *propname, -+ const void *propval, int proplen); -+ -+/** -+ * fdt_node_offset_by_phandle - find the node with a given phandle -+ * @fdt: pointer to the device tree blob -+ * @phandle: phandle value -+ * -+ * fdt_node_offset_by_prop_value() returns the offset of the node -+ * which has the given phandle value. If there is more than one node -+ * in the tree with the given phandle (an invalid tree), results are -+ * undefined. -+ * -+ * returns: -+ * structure block offset of the located node (>= 0), on success -+ * -FDT_ERR_NOTFOUND, no node with that phandle exists -+ * -FDT_ERR_BADPHANDLE, given phandle value was invalid (0 or -1) -+ * -FDT_ERR_BADMAGIC, -+ * -FDT_ERR_BADVERSION, -+ * -FDT_ERR_BADSTATE, -+ * -FDT_ERR_BADSTRUCTURE, standard meanings -+ */ -+int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle); -+ -+/** -+ * fdt_node_check_compatible: check a node's compatible property -+ * @fdt: pointer to the device tree blob -+ * @nodeoffset: offset of a tree node -+ * @compatible: string to match against -+ * -+ * -+ * fdt_node_check_compatible() returns 0 if the given node contains a -+ * 'compatible' property with the given string as one of its elements, -+ * it returns non-zero otherwise, or on error. -+ * -+ * returns: -+ * 0, if the node has a 'compatible' property listing the given string -+ * 1, if the node has a 'compatible' property, but it does not list -+ * the given string -+ * -FDT_ERR_NOTFOUND, if the given node has no 'compatible' property -+ * -FDT_ERR_BADOFFSET, if nodeoffset does not refer to a BEGIN_NODE tag -+ * -FDT_ERR_BADMAGIC, -+ * -FDT_ERR_BADVERSION, -+ * -FDT_ERR_BADSTATE, -+ * -FDT_ERR_BADSTRUCTURE, standard meanings -+ */ -+int fdt_node_check_compatible(const void *fdt, int nodeoffset, -+ const char *compatible); -+ -+/** -+ * fdt_node_offset_by_compatible - find nodes with a given 'compatible' value -+ * @fdt: pointer to the device tree blob -+ * @startoffset: only find nodes after this offset -+ * @compatible: 'compatible' string to match against -+ * -+ * fdt_node_offset_by_compatible() returns the offset of the first -+ * node after startoffset, which has a 'compatible' property which -+ * lists the given compatible string; or if startoffset is -1, the -+ * very first such node in the tree. -+ * -+ * To iterate through all nodes matching the criterion, the following -+ * idiom can be used: -+ * offset = fdt_node_offset_by_compatible(fdt, -1, compatible); -+ * while (offset != -FDT_ERR_NOTFOUND) { -+ * // other code here -+ * offset = fdt_node_offset_by_compatible(fdt, offset, compatible); -+ * } -+ * -+ * Note the -1 in the first call to the function, if 0 is used here -+ * instead, the function will never locate the root node, even if it -+ * matches the criterion. -+ * -+ * returns: -+ * structure block offset of the located node (>= 0, >startoffset), -+ * on success -+ * -FDT_ERR_NOTFOUND, no node matching the criterion exists in the -+ * tree after startoffset -+ * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag -+ * -FDT_ERR_BADMAGIC, -+ * -FDT_ERR_BADVERSION, -+ * -FDT_ERR_BADSTATE, -+ * -FDT_ERR_BADSTRUCTURE, standard meanings -+ */ -+int fdt_node_offset_by_compatible(const void *fdt, int startoffset, -+ const char *compatible); -+ -+/**********************************************************************/ -+/* Write-in-place functions */ -+/**********************************************************************/ -+ -+int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name, -+ const void *val, int len); -+static inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset, -+ const char *name, uint32_t val) -+{ -+ val = cpu_to_fdt32(val); -+ return fdt_setprop_inplace(fdt, nodeoffset, name, &val, sizeof(val)); -+} -+ -+int fdt_nop_property(void *fdt, int nodeoffset, const char *name); -+int fdt_nop_node(void *fdt, int nodeoffset); -+ -+/**********************************************************************/ -+/* Sequential write functions */ -+/**********************************************************************/ -+ -+int fdt_create(void *buf, int bufsize); -+int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size); -+int fdt_finish_reservemap(void *fdt); -+int fdt_begin_node(void *fdt, const char *name); -+int fdt_property(void *fdt, const char *name, const void *val, int len); -+static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val) -+{ -+ val = cpu_to_fdt32(val); -+ return fdt_property(fdt, name, &val, sizeof(val)); -+} -+#define fdt_property_string(fdt, name, str) \ -+ fdt_property(fdt, name, str, strlen(str)+1) -+int fdt_end_node(void *fdt); -+int fdt_finish(void *fdt); -+ -+/**********************************************************************/ -+/* Read-write functions */ -+/**********************************************************************/ -+ -+int fdt_open_into(const void *fdt, void *buf, int bufsize); -+int fdt_pack(void *fdt); -+ -+int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size); -+int fdt_del_mem_rsv(void *fdt, int n); -+ -+int fdt_setprop(void *fdt, int nodeoffset, const char *name, -+ const void *val, int len); -+static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name, -+ uint32_t val) -+{ -+ val = cpu_to_fdt32(val); -+ return fdt_setprop(fdt, nodeoffset, name, &val, sizeof(val)); -+} -+#define fdt_setprop_string(fdt, nodeoffset, name, str) \ -+ fdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1) -+int fdt_delprop(void *fdt, int nodeoffset, const char *name); -+int fdt_add_subnode_namelen(void *fdt, int parentoffset, -+ const char *name, int namelen); -+int fdt_add_subnode(void *fdt, int parentoffset, const char *name); -+int fdt_del_node(void *fdt, int nodeoffset); -+ -+/**********************************************************************/ -+/* Debugging / informational functions */ -+/**********************************************************************/ -+ -+const char *fdt_strerror(int errval); -+ -+#endif /* _LIBFDT_H */ ---- /dev/null -+++ b/arch/powerpc/boot/libfdt/libfdt_internal.h -@@ -0,0 +1,89 @@ -+#ifndef _LIBFDT_INTERNAL_H -+#define _LIBFDT_INTERNAL_H -+/* -+ * libfdt - Flat Device Tree manipulation -+ * Copyright (C) 2006 David Gibson, IBM Corporation. -+ * -+ * libfdt is dual licensed: you can use it either under the terms of -+ * the GPL, or the BSD license, at your option. -+ * -+ * a) This library 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 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 General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public -+ * License along with this library; if not, write to the Free -+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, -+ * MA 02110-1301 USA -+ * -+ * Alternatively, -+ * -+ * b) 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. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. -+ */ -+#include -+ -+#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) -+#define PALIGN(p, a) ((void *)ALIGN((unsigned long)(p), (a))) -+ -+#define memeq(p, q, n) (memcmp((p), (q), (n)) == 0) -+#define streq(p, q) (strcmp((p), (q)) == 0) -+ -+uint32_t _fdt_next_tag(const void *fdt, int startoffset, int *nextoffset); -+const char *_fdt_find_string(const char *strtab, int tabsize, const char *s); -+int _fdt_node_end_offset(void *fdt, int nodeoffset); -+ -+static inline const void *_fdt_offset_ptr(const void *fdt, int offset) -+{ -+ return fdt + fdt_off_dt_struct(fdt) + offset; -+} -+ -+static inline void *_fdt_offset_ptr_w(void *fdt, int offset) -+{ -+ return (void *)_fdt_offset_ptr(fdt, offset); -+} -+ -+static inline const struct fdt_reserve_entry *_fdt_mem_rsv(const void *fdt, int n) -+{ -+ const struct fdt_reserve_entry *rsv_table = -+ fdt + fdt_off_mem_rsvmap(fdt); -+ -+ return rsv_table + n; -+} -+static inline struct fdt_reserve_entry *_fdt_mem_rsv_w(void *fdt, int n) -+{ -+ return (void *)_fdt_mem_rsv(fdt, n); -+} -+ -+#define SW_MAGIC (~FDT_MAGIC) -+ -+#endif /* _LIBFDT_INTERNAL_H */ ---- /dev/null -+++ b/arch/powerpc/boot/libfdt-wrapper.c -@@ -0,0 +1,184 @@ -+/* -+ * This file does the necessary interface mapping between the bootwrapper -+ * device tree operations and the interface provided by shared source -+ * files flatdevicetree.[ch]. -+ * -+ * Copyright 2007 David Gibson, IBM Corporation. -+ * -+ * This library 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 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 -+ * General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA -+ * 02110-1301 USA -+ */ -+ -+#include -+#include -+#include -+#include -+#include "ops.h" -+ -+#define DEBUG 0 -+#define BAD_ERROR(err) (((err) < 0) \ -+ && ((err) != -FDT_ERR_NOTFOUND) \ -+ && ((err) != -FDT_ERR_EXISTS)) -+ -+#define check_err(err) \ -+ ({ \ -+ if (BAD_ERROR(err) || ((err < 0) && DEBUG)) \ -+ printf("%s():%d %s\n\r", __FUNCTION__, __LINE__, \ -+ fdt_strerror(err)); \ -+ if (BAD_ERROR(err)) \ -+ exit(); \ -+ (err < 0) ? -1 : 0; \ -+ }) -+ -+#define offset_devp(off) \ -+ ({ \ -+ int _offset = (off); \ -+ check_err(_offset) ? NULL : (void *)(_offset+1); \ -+ }) -+ -+#define devp_offset_find(devp) (((int)(devp))-1) -+#define devp_offset(devp) (devp ? ((int)(devp))-1 : 0) -+ -+static void *fdt; -+static void *buf; /* = NULL */ -+ -+#define EXPAND_GRANULARITY 1024 -+ -+static void expand_buf(int minexpand) -+{ -+ int size = fdt_totalsize(fdt); -+ int rc; -+ -+ size = _ALIGN(size + minexpand, EXPAND_GRANULARITY); -+ buf = platform_ops.realloc(buf, size); -+ if (!buf) -+ fatal("Couldn't find %d bytes to expand device tree\n\r", size); -+ rc = fdt_open_into(fdt, buf, size); -+ if (rc != 0) -+ fatal("Couldn't expand fdt into new buffer: %s\n\r", -+ fdt_strerror(rc)); -+ -+ fdt = buf; -+} -+ -+static void *fdt_wrapper_finddevice(const char *path) -+{ -+ return offset_devp(fdt_path_offset(fdt, path)); -+} -+ -+static int fdt_wrapper_getprop(const void *devp, const char *name, -+ void *buf, const int buflen) -+{ -+ const void *p; -+ int len; -+ -+ p = fdt_getprop(fdt, devp_offset(devp), name, &len); -+ if (!p) -+ return check_err(len); -+ memcpy(buf, p, min(len, buflen)); -+ return len; -+} -+ -+static int fdt_wrapper_setprop(const void *devp, const char *name, -+ const void *buf, const int len) -+{ -+ int rc; -+ -+ rc = fdt_setprop(fdt, devp_offset(devp), name, buf, len); -+ if (rc == -FDT_ERR_NOSPACE) { -+ expand_buf(len + 16); -+ rc = fdt_setprop(fdt, devp_offset(devp), name, buf, len); -+ } -+ -+ return check_err(rc); -+} -+ -+static void *fdt_wrapper_get_parent(const void *devp) -+{ -+ return offset_devp(fdt_parent_offset(fdt, devp_offset(devp))); -+} -+ -+static void *fdt_wrapper_create_node(const void *devp, const char *name) -+{ -+ int offset; -+ -+ offset = fdt_add_subnode(fdt, devp_offset(devp), name); -+ if (offset == -FDT_ERR_NOSPACE) { -+ expand_buf(strlen(name) + 16); -+ offset = fdt_add_subnode(fdt, devp_offset(devp), name); -+ } -+ -+ return offset_devp(offset); -+} -+ -+static void *fdt_wrapper_find_node_by_prop_value(const void *prev, -+ const char *name, -+ const char *val, -+ int len) -+{ -+ int offset = fdt_node_offset_by_prop_value(fdt, devp_offset_find(prev), -+ name, val, len); -+ return offset_devp(offset); -+} -+ -+static char *fdt_wrapper_get_path(const void *devp, char *buf, int len) -+{ -+ int rc; -+ -+ rc = fdt_get_path(fdt, devp_offset(devp), buf, len); -+ if (check_err(rc)) -+ return NULL; -+ return buf; -+} -+ -+static unsigned long fdt_wrapper_finalize(void) -+{ -+ int rc; -+ -+ rc = fdt_pack(fdt); -+ if (rc != 0) -+ fatal("Couldn't pack flat tree: %s\n\r", -+ fdt_strerror(rc)); -+ return (unsigned long)fdt; -+} -+ -+void fdt_init(void *blob) -+{ -+ int err; -+ -+ dt_ops.finddevice = fdt_wrapper_finddevice; -+ dt_ops.getprop = fdt_wrapper_getprop; -+ dt_ops.setprop = fdt_wrapper_setprop; -+ dt_ops.get_parent = fdt_wrapper_get_parent; -+ dt_ops.create_node = fdt_wrapper_create_node; -+ dt_ops.find_node_by_prop_value = fdt_wrapper_find_node_by_prop_value; -+ dt_ops.get_path = fdt_wrapper_get_path; -+ dt_ops.finalize = fdt_wrapper_finalize; -+ -+ /* Make sure the dt blob is the right version and so forth */ -+ fdt = blob; -+ err = fdt_open_into(fdt, fdt, fdt_totalsize(blob)); -+ if (err == -FDT_ERR_NOSPACE) { -+ int bufsize = fdt_totalsize(fdt) + 4; -+ buf = malloc(bufsize); -+ err = fdt_open_into(fdt, buf, bufsize); -+ } -+ -+ if (err != 0) -+ fatal("fdt_init(): %s\n\r", fdt_strerror(err)); -+ -+ if (buf) -+ fdt = buf; -+} ---- /dev/null -+++ b/arch/powerpc/boot/libfdt_env.h -@@ -0,0 +1,17 @@ -+#ifndef _ARCH_POWERPC_BOOT_LIBFDT_ENV_H -+#define _ARCH_POWERPC_BOOT_LIBFDT_ENV_H -+ -+#include -+#include -+ -+typedef u32 uint32_t; -+typedef u64 uint64_t; -+ -+#define fdt16_to_cpu(x) (x) -+#define cpu_to_fdt16(x) (x) -+#define fdt32_to_cpu(x) (x) -+#define cpu_to_fdt32(x) (x) -+#define fdt64_to_cpu(x) (x) -+#define cpu_to_fdt64(x) (x) -+ -+#endif /* _ARCH_POWERPC_BOOT_LIBFDT_ENV_H */ ---- a/arch/powerpc/boot/main.c -+++ b/arch/powerpc/boot/main.c -@@ -16,7 +16,6 @@ - #include "stdio.h" - #include "ops.h" - #include "gunzip_util.h" --#include "flatdevtree.h" - #include "reg.h" - - static struct gunzip_state gzstate; ---- a/arch/powerpc/boot/ops.h -+++ b/arch/powerpc/boot/ops.h -@@ -79,7 +79,7 @@ struct loader_info { - extern struct loader_info loader_info; - - void start(void); --int ft_init(void *dt_blob, unsigned int max_size, unsigned int max_find_device); -+void fdt_init(void *blob); - int serial_console_init(void); - int ns16550_console_init(void *devp, struct serial_console_data *scdp); - int mpsc_console_init(void *devp, struct serial_console_data *scdp); -@@ -159,9 +159,23 @@ static inline void *find_node_by_devtype - return find_node_by_prop_value_str(prev, "device_type", type); - } - -+static inline void *find_node_by_alias(const char *alias) -+{ -+ void *devp = finddevice("/aliases"); -+ -+ if (devp) { -+ char path[MAX_PATH_LEN]; -+ if (getprop(devp, alias, path, MAX_PATH_LEN) > 0) -+ return finddevice(path); -+ } -+ -+ return NULL; -+} -+ - void dt_fixup_memory(u64 start, u64 size); - void dt_fixup_cpu_clocks(u32 cpufreq, u32 tbfreq, u32 busfreq); - void dt_fixup_clock(const char *path, u32 freq); -+void dt_fixup_mac_address_by_alias(const char *alias, const u8 *addr); - void dt_fixup_mac_address(u32 index, const u8 *addr); - void __dt_fixup_mac_addresses(u32 startindex, ...); - #define dt_fixup_mac_addresses(...) \ ---- a/arch/powerpc/boot/prpmc2800.c -+++ b/arch/powerpc/boot/prpmc2800.c -@@ -547,8 +547,7 @@ void platform_init(unsigned long r3, uns - if (!dtb) - exit(); - memmove(dtb, _dtb_start, dt_size); -- if (ft_init(dtb, dt_size, 16)) -- exit(); -+ fdt_init(dtb); - - bridge_base = mv64x60_get_bridge_base(); - ---- a/arch/powerpc/boot/ps3.c -+++ b/arch/powerpc/boot/ps3.c -@@ -131,7 +131,7 @@ void platform_init(void) - printf("\n-- PS3 bootwrapper --\n"); - - simple_alloc_init(_end, heapsize, 32, 64); -- ft_init(_dtb_start, 0, 4); -+ fdt_init(_dtb_start); - - chosen = finddevice("/chosen"); - ---- /dev/null -+++ b/arch/powerpc/boot/redboot-8xx.c -@@ -0,0 +1,58 @@ -+/* -+ * RedBoot firmware support -+ * -+ * Author: Scott Wood -+ * -+ * Copyright (c) 2007 Freescale Semiconductor, Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include "ops.h" -+#include "stdio.h" -+#include "redboot.h" -+#include "fsl-soc.h" -+#include "io.h" -+ -+static bd_t bd; -+BSS_STACK(4096); -+ -+#define MHZ(x) ((x + 500000) / 1000000) -+ -+static void platform_fixups(void) -+{ -+ void *node; -+ -+ dt_fixup_memory(bd.bi_memstart, bd.bi_memsize); -+ dt_fixup_mac_addresses(bd.bi_enetaddr); -+ dt_fixup_cpu_clocks(bd.bi_intfreq, bd.bi_busfreq / 16, bd.bi_busfreq); -+ -+ node = finddevice("/soc/cpm/brg"); -+ if (node) { -+ printf("BRG clock-frequency <- 0x%x (%dMHz)\r\n", -+ bd.bi_busfreq, MHZ(bd.bi_busfreq)); -+ setprop(node, "clock-frequency", &bd.bi_busfreq, 4); -+ } -+} -+ -+void platform_init(unsigned long r3, unsigned long r4, unsigned long r5, -+ unsigned long r6, unsigned long r7) -+{ -+ memcpy(&bd, (char *)r3, sizeof(bd)); -+ -+ if (bd.bi_tag != 0x42444944) -+ return; -+ -+ simple_alloc_init(_end, -+ bd.bi_memstart + bd.bi_memsize - (unsigned long)_end, -+ 32, 64); -+ -+ fdt_init(_dtb_start); -+ serial_console_init(); -+ platform_ops.fixups = platform_fixups; -+ -+ loader_info.cmdline = (char *)bd.bi_cmdline; -+ loader_info.cmdline_len = strlen((char *)bd.bi_cmdline); -+} ---- /dev/null -+++ b/arch/powerpc/boot/redboot.h -@@ -0,0 +1,56 @@ -+#ifndef _PPC_REDBOOT_H -+#define _PPC_REDBOOT_H -+ -+//========================================================================= -+// include/asm-ppc/redboot.h -+// Copyright (c) 2002, 2003 Gary Thomas ( -+// Copyright (c) 1997 Dan Malek (dmalek@jlc.net) -+ -+// -+// Board specific details, as provided by RedBoot -+// -+ -+/* A Board Information structure that is given to a program when -+ * RedBoot starts it up. Note: not all fields make sense for all -+ * architectures and it's up to the platform specific code to fill -+ * in the details. -+ */ -+typedef struct bd_info { -+ unsigned int bi_tag; /* Should be 0x42444944 "BDID" */ -+ unsigned int bi_size; /* Size of this structure */ -+ unsigned int bi_revision; /* revision of this structure */ -+ unsigned int bi_bdate; /* bootstrap date, i.e. 0x19971106 */ -+ unsigned int bi_memstart; /* Memory start address */ -+ unsigned int bi_memsize; /* Memory (end) size in bytes */ -+ unsigned int bi_intfreq; /* Internal Freq, in Hz */ -+ unsigned int bi_busfreq; /* Bus Freq, in Hz */ -+ unsigned int bi_cpmfreq; /* CPM Freq, in Hz */ -+ unsigned int bi_brgfreq; /* BRG Freq, in Hz */ -+ unsigned int bi_vco; /* VCO Out from PLL */ -+ unsigned int bi_pci_freq; /* PCI Freq, in Hz */ -+ unsigned int bi_baudrate; /* Default console baud rate */ -+ unsigned int bi_immr; /* IMMR when called from boot rom */ -+ unsigned char bi_enetaddr[6]; -+ unsigned int bi_flashbase; /* Physical address of FLASH memory */ -+ unsigned int bi_flashsize; /* Length of FLASH memory */ -+ int bi_flashwidth; /* Width (8,16,32,64) */ -+ unsigned char *bi_cmdline; /* Pointer to command line */ -+ unsigned char bi_esa[3][6]; /* Ethernet station addresses */ -+ unsigned int bi_ramdisk_begin, bi_ramdisk_end; -+ struct { /* Information about [main] video screen */ -+ short x_res; /* Horizontal resolution in pixels */ -+ short y_res; /* Vertical resolution in pixels */ -+ short bpp; /* Bits/pixel */ -+ short mode; /* Type of pixels (packed, indexed) */ -+ unsigned long fb; /* Pointer to frame buffer (pixel) memory */ -+ } bi_video; -+ void (*bi_cputc)(char); /* Write a character to the RedBoot console */ -+ char (*bi_cgetc)(void); /* Read a character from the RedBoot console */ -+ int (*bi_ctstc)(void); /* Test for input on the RedBoot console */ -+} bd_t; -+ -+#define BI_REV 0x0102 /* Version 1.02 */ -+ -+#define bi_pci_busfreq bi_pci_freq -+#define bi_immr_base bi_immr -+#endif ---- a/arch/powerpc/boot/reg.h -+++ b/arch/powerpc/boot/reg.h -@@ -16,6 +16,14 @@ static inline u32 mfpvr(void) - return pvr; - } - -+#define __stringify_1(x) #x -+#define __stringify(x) __stringify_1(x) -+ -+#define mfspr(rn) ({unsigned long rval; \ -+ asm volatile("mfspr %0," __stringify(rn) \ -+ : "=r" (rval)); rval; }) -+#define mtspr(rn, v) asm volatile("mtspr " __stringify(rn) ",%0" : : "r" (v)) -+ - register void *__stack_pointer asm("r1"); - #define get_sp() (__stack_pointer) - ---- a/arch/powerpc/boot/serial.c -+++ b/arch/powerpc/boot/serial.c -@@ -128,7 +128,8 @@ int serial_console_init(void) - rc = cpm_console_init(devp, &serial_cd); - else if (dt_is_compatible(devp, "mpc5200-psc-uart")) - rc = mpc5200_psc_console_init(devp, &serial_cd); -- else if (dt_is_compatible(devp, "xilinx,uartlite")) -+ else if (dt_is_compatible(devp, "xlnx,opb-uartlite-1.00.b") || -+ dt_is_compatible(devp, "xlnx,xps-uartlite-1.00.a")) - rc = uartlite_console_init(devp, &serial_cd); - - /* Add other serial console driver calls here */ ---- a/arch/powerpc/boot/treeboot-walnut.c -+++ b/arch/powerpc/boot/treeboot-walnut.c -@@ -20,55 +20,6 @@ - - BSS_STACK(4096); - --void ibm405gp_fixup_clocks(unsigned int sysclk, unsigned int ser_clk) --{ -- u32 pllmr = mfdcr(DCRN_CPC0_PLLMR); -- u32 cpc0_cr0 = mfdcr(DCRN_405_CPC0_CR0); -- u32 cpc0_cr1 = mfdcr(DCRN_405_CPC0_CR1); -- u32 cpu, plb, opb, ebc, tb, uart0, uart1, m; -- u32 fwdv, fbdv, cbdv, opdv, epdv, udiv; -- -- fwdv = (8 - ((pllmr & 0xe0000000) >> 29)); -- fbdv = (pllmr & 0x1e000000) >> 25; -- cbdv = ((pllmr & 0x00060000) >> 17) + 1; -- opdv = ((pllmr & 0x00018000) >> 15) + 1; -- epdv = ((pllmr & 0x00001800) >> 13) + 2; -- udiv = ((cpc0_cr0 & 0x3e) >> 1) + 1; -- -- m = fwdv * fbdv * cbdv; -- -- cpu = sysclk * m / fwdv; -- plb = cpu / cbdv; -- opb = plb / opdv; -- ebc = plb / epdv; -- -- if (cpc0_cr0 & 0x80) { -- /* uart0 uses the external clock */ -- uart0 = ser_clk; -- } else { -- uart0 = cpu / udiv; -- } -- -- if (cpc0_cr0 & 0x40) { -- /* uart1 uses the external clock */ -- uart1 = ser_clk; -- } else { -- uart1 = cpu / udiv; -- } -- -- /* setup the timebase clock to tick at the cpu frequency */ -- cpc0_cr1 = cpc0_cr1 & ~0x00800000; -- mtdcr(DCRN_405_CPC0_CR1, cpc0_cr1); -- tb = cpu; -- -- dt_fixup_cpu_clocks(cpu, tb, 0); -- dt_fixup_clock("/plb", plb); -- dt_fixup_clock("/plb/opb", opb); -- dt_fixup_clock("/plb/ebc", ebc); -- dt_fixup_clock("/plb/opb/serial@ef600300", uart0); -- dt_fixup_clock("/plb/opb/serial@ef600400", uart1); --} -- - static void walnut_flashsel_fixup(void) - { - void *devp, *sram; -@@ -112,7 +63,7 @@ static void walnut_flashsel_fixup(void) - #define WALNUT_OPENBIOS_MAC_OFF 0xfffffe0b - static void walnut_fixups(void) - { -- ibm4xx_fixup_memsize(); -+ ibm4xx_sdram_fixup_memsize(); - ibm405gp_fixup_clocks(33330000, 0xa8c000); - ibm4xx_quiesce_eth((u32 *)0xef600800, NULL); - ibm4xx_fixup_ebc_ranges("/plb/ebc"); -@@ -128,6 +79,6 @@ void platform_init(void) - simple_alloc_init(_end, avail_ram, 32, 32); - platform_ops.fixups = walnut_fixups; - platform_ops.exit = ibm40x_dbcr_reset; -- ft_init(_dtb_start, _dtb_end - _dtb_start, 32); -+ fdt_init(_dtb_start); - serial_console_init(); - } ---- a/arch/powerpc/boot/wrapper -+++ b/arch/powerpc/boot/wrapper -@@ -45,6 +45,7 @@ CROSS= - - # directory for object and other files used by this script - object=arch/powerpc/boot -+objbin=$object - - # directory for working files - tmpdir=. -@@ -95,6 +96,7 @@ while [ "$#" -gt 0 ]; do - shift - [ "$#" -gt 0 ] || usage - object="$1" -+ objbin="$1" - ;; - -W) - shift -@@ -116,10 +118,13 @@ while [ "$#" -gt 0 ]; do - done - - if [ -n "$dts" ]; then -+ if [ ! -r "$dts" -a -r "$object/dts/$dts" ]; then -+ dts="$object/dts/$dts" -+ fi - if [ -z "$dtb" ]; then - dtb="$platform.dtb" - fi -- dtc -O dtb -o "$dtb" -b 0 -V 16 "$dts" -+ $object/dtc -O dtb -o "$dtb" -b 0 "$dts" - fi - - if [ -z "$kernel" ]; then -@@ -163,7 +168,7 @@ ps3) - ksection=.kernel:vmlinux.bin - isection=.kernel:initrd - ;; --ep88xc) -+ep88xc|ep405|redboot*|ep8248e) - platformo="$object/fixed-head.o $object/$platform.o" - binary=y - ;; -@@ -246,11 +251,11 @@ fi - # post-processing needed for some platforms - case "$platform" in - pseries|chrp) -- $object/addnote "$ofile" -+ $objbin/addnote "$ofile" - ;; - coff) - ${CROSS}objcopy -O aixcoff-rs6000 --set-start "$entry" "$ofile" -- $object/hack-coff "$ofile" -+ $objbin/hack-coff "$ofile" - ;; - cuboot*) - gzip -f -9 "$ofile" -@@ -259,7 +264,7 @@ cuboot*) - ;; - treeboot*) - mv "$ofile" "$ofile.elf" -- $object/mktree "$ofile.elf" "$ofile" "$base" "$entry" -+ $objbin/mktree "$ofile.elf" "$ofile" "$base" "$entry" - if [ -z "$cacheit" ]; then - rm -f "$ofile.elf" - fi -@@ -287,8 +292,6 @@ ps3) - overlay_dest="256" - overlay_size="256" - -- rm -f "$object/otheros.bld" -- - ${CROSS}objcopy -O binary "$ofile" "$ofile.bin" - - dd if="$ofile.bin" of="$ofile.bin" conv=notrunc \ -@@ -299,6 +302,8 @@ ps3) - skip=$system_reset_overlay seek=$overlay_dest \ - count=$overlay_size bs=1 - -- gzip --force -9 --stdout "$ofile.bin" > "$object/otheros.bld" -+ odir="$(dirname "$ofile.bin")" -+ rm -f "$odir/otheros.bld" -+ gzip --force -9 --stdout "$ofile.bin" > "$odir/otheros.bld" - ;; - esac ---- /dev/null -+++ b/arch/powerpc/configs/adder875-redboot_defconfig -@@ -0,0 +1,798 @@ -+# -+# Automatically generated make config: don't edit -+# Linux kernel version: 2.6.24-rc6 -+# Thu Jan 17 16:17:38 2008 -+# -+# CONFIG_PPC64 is not set -+ -+# -+# Processor support -+# -+# CONFIG_6xx is not set -+# CONFIG_PPC_85xx is not set -+CONFIG_PPC_8xx=y -+# CONFIG_40x is not set -+# CONFIG_44x is not set -+# CONFIG_E200 is not set -+CONFIG_8xx=y -+# CONFIG_PPC_MM_SLICES is not set -+CONFIG_NOT_COHERENT_CACHE=y -+CONFIG_PPC32=y -+CONFIG_WORD_SIZE=32 -+CONFIG_PPC_MERGE=y -+CONFIG_MMU=y -+CONFIG_GENERIC_CMOS_UPDATE=y -+CONFIG_GENERIC_TIME=y -+CONFIG_GENERIC_TIME_VSYSCALL=y -+CONFIG_GENERIC_CLOCKEVENTS=y -+CONFIG_GENERIC_HARDIRQS=y -+CONFIG_IRQ_PER_CPU=y -+CONFIG_RWSEM_XCHGADD_ALGORITHM=y -+CONFIG_ARCH_HAS_ILOG2_U32=y -+CONFIG_GENERIC_HWEIGHT=y -+CONFIG_GENERIC_CALIBRATE_DELAY=y -+CONFIG_GENERIC_FIND_NEXT_BIT=y -+# CONFIG_ARCH_NO_VIRT_TO_BUS is not set -+CONFIG_PPC=y -+CONFIG_EARLY_PRINTK=y -+CONFIG_GENERIC_NVRAM=y -+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -+CONFIG_ARCH_MAY_HAVE_PC_FDC=y -+CONFIG_PPC_OF=y -+CONFIG_OF=y -+# CONFIG_PPC_UDBG_16550 is not set -+# CONFIG_GENERIC_TBSYNC is not set -+CONFIG_AUDIT_ARCH=y -+CONFIG_GENERIC_BUG=y -+# CONFIG_DEFAULT_UIMAGE is not set -+CONFIG_REDBOOT=y -+# CONFIG_PPC_DCR_NATIVE is not set -+# CONFIG_PPC_DCR_MMIO is not set -+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" -+ -+# -+# General setup -+# -+CONFIG_EXPERIMENTAL=y -+CONFIG_BROKEN_ON_SMP=y -+CONFIG_INIT_ENV_ARG_LIMIT=32 -+CONFIG_LOCALVERSION="" -+CONFIG_LOCALVERSION_AUTO=y -+# CONFIG_SWAP is not set -+CONFIG_SYSVIPC=y -+CONFIG_SYSVIPC_SYSCTL=y -+# CONFIG_POSIX_MQUEUE is not set -+# CONFIG_BSD_PROCESS_ACCT is not set -+# CONFIG_TASKSTATS is not set -+# CONFIG_USER_NS is not set -+# CONFIG_PID_NS is not set -+# CONFIG_AUDIT is not set -+# CONFIG_IKCONFIG is not set -+CONFIG_LOG_BUF_SHIFT=14 -+# CONFIG_CGROUPS is not set -+CONFIG_FAIR_GROUP_SCHED=y -+CONFIG_FAIR_USER_SCHED=y -+# CONFIG_FAIR_CGROUP_SCHED is not set -+CONFIG_SYSFS_DEPRECATED=y -+# CONFIG_RELAY is not set -+# CONFIG_BLK_DEV_INITRD is not set -+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -+CONFIG_SYSCTL=y -+CONFIG_EMBEDDED=y -+# CONFIG_SYSCTL_SYSCALL is not set -+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 is not set -+# CONFIG_BASE_FULL is not set -+# CONFIG_FUTEX is not set -+CONFIG_ANON_INODES=y -+CONFIG_EPOLL=y -+CONFIG_SIGNALFD=y -+CONFIG_EVENTFD=y -+CONFIG_SHMEM=y -+# CONFIG_VM_EVENT_COUNTERS is not set -+CONFIG_SLUB_DEBUG=y -+# CONFIG_SLAB is not set -+CONFIG_SLUB=y -+# CONFIG_SLOB is not set -+# CONFIG_TINY_SHMEM is not set -+CONFIG_BASE_SMALL=1 -+# CONFIG_MODULES is not set -+CONFIG_BLOCK=y -+# CONFIG_LBD is not set -+# CONFIG_BLK_DEV_IO_TRACE is not set -+# CONFIG_LSF is not set -+# CONFIG_BLK_DEV_BSG is not set -+ -+# -+# IO Schedulers -+# -+CONFIG_IOSCHED_NOOP=y -+# CONFIG_IOSCHED_AS is not set -+CONFIG_IOSCHED_DEADLINE=y -+# CONFIG_IOSCHED_CFQ is not set -+# CONFIG_DEFAULT_AS is not set -+CONFIG_DEFAULT_DEADLINE=y -+# CONFIG_DEFAULT_CFQ is not set -+# CONFIG_DEFAULT_NOOP is not set -+CONFIG_DEFAULT_IOSCHED="deadline" -+ -+# -+# Platform support -+# -+# CONFIG_PPC_MPC52xx is not set -+# CONFIG_PPC_MPC5200 is not set -+# CONFIG_PPC_CELL is not set -+# CONFIG_PPC_CELL_NATIVE is not set -+CONFIG_CPM1=y -+# CONFIG_MPC8XXFADS is not set -+# CONFIG_MPC86XADS is not set -+# CONFIG_MPC885ADS is not set -+# CONFIG_PPC_EP88XC is not set -+CONFIG_PPC_ADDER875=y -+ -+# -+# MPC8xx CPM Options -+# -+ -+# -+# Generic MPC8xx Options -+# -+CONFIG_8xx_COPYBACK=y -+# CONFIG_8xx_CPU6 is not set -+CONFIG_8xx_CPU15=y -+CONFIG_NO_UCODE_PATCH=y -+# CONFIG_USB_SOF_UCODE_PATCH is not set -+# CONFIG_I2C_SPI_UCODE_PATCH is not set -+# CONFIG_I2C_SPI_SMC1_UCODE_PATCH is not set -+# CONFIG_PQ2ADS is not set -+# CONFIG_MPIC is not set -+# CONFIG_MPIC_WEIRD is not set -+# CONFIG_PPC_I8259 is not set -+# CONFIG_PPC_RTAS is not set -+# CONFIG_MMIO_NVRAM is not set -+# CONFIG_PPC_MPC106 is not set -+# CONFIG_PPC_970_NAP is not set -+# CONFIG_PPC_INDIRECT_IO is not set -+# CONFIG_GENERIC_IOMAP is not set -+# CONFIG_CPU_FREQ is not set -+# CONFIG_CPM2 is not set -+CONFIG_PPC_CPM_NEW_BINDING=y -+# CONFIG_FSL_ULI1575 is not set -+CONFIG_CPM=y -+ -+# -+# Kernel options -+# -+# CONFIG_HIGHMEM is not set -+# CONFIG_TICK_ONESHOT is not set -+# CONFIG_NO_HZ is not set -+# CONFIG_HIGH_RES_TIMERS is not set -+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y -+# CONFIG_HZ_100 is not set -+# CONFIG_HZ_250 is not set -+# CONFIG_HZ_300 is not set -+CONFIG_HZ_1000=y -+CONFIG_HZ=1000 -+CONFIG_PREEMPT_NONE=y -+# CONFIG_PREEMPT_VOLUNTARY is not set -+# CONFIG_PREEMPT is not set -+CONFIG_BINFMT_ELF=y -+# CONFIG_BINFMT_MISC is not set -+# CONFIG_MATH_EMULATION is not set -+# CONFIG_8XX_MINIMAL_FPEMU is not set -+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y -+CONFIG_ARCH_FLATMEM_ENABLE=y -+CONFIG_ARCH_POPULATES_NODE_MAP=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 is not set -+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set -+CONFIG_SPLIT_PTLOCK_CPUS=4 -+# CONFIG_RESOURCES_64BIT is not set -+CONFIG_ZONE_DMA_FLAG=1 -+CONFIG_BOUNCE=y -+CONFIG_VIRT_TO_BUS=y -+# CONFIG_PROC_DEVICETREE is not set -+# CONFIG_CMDLINE_BOOL is not set -+# CONFIG_PM is not set -+CONFIG_SUSPEND_UP_POSSIBLE=y -+CONFIG_HIBERNATION_UP_POSSIBLE=y -+# CONFIG_SECCOMP is not set -+CONFIG_WANT_DEVICE_TREE=y -+CONFIG_DEVICE_TREE="adder875-redboot.dts" -+CONFIG_ISA_DMA_API=y -+ -+# -+# Bus options -+# -+CONFIG_ZONE_DMA=y -+CONFIG_FSL_SOC=y -+# CONFIG_PCI is not set -+# CONFIG_PCI_DOMAINS is not set -+# CONFIG_PCI_SYSCALL is not set -+# CONFIG_PCI_QSPAN is not set -+# CONFIG_ARCH_SUPPORTS_MSI is not set -+# CONFIG_PCCARD is not set -+ -+# -+# Advanced setup -+# -+# CONFIG_ADVANCED_OPTIONS is not set -+ -+# -+# Default settings for advanced configuration options are used -+# -+CONFIG_HIGHMEM_START=0xfe000000 -+CONFIG_LOWMEM_SIZE=0x30000000 -+CONFIG_KERNEL_START=0xc0000000 -+CONFIG_TASK_SIZE=0x80000000 -+CONFIG_CONSISTENT_START=0xfd000000 -+CONFIG_CONSISTENT_SIZE=0x00200000 -+CONFIG_BOOT_LOAD=0x00400000 -+ -+# -+# Networking -+# -+CONFIG_NET=y -+ -+# -+# Networking options -+# -+CONFIG_PACKET=y -+# CONFIG_PACKET_MMAP is not set -+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=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_XFRM_MODE_TRANSPORT is not set -+# CONFIG_INET_XFRM_MODE_TUNNEL is not set -+# CONFIG_INET_XFRM_MODE_BEET is not set -+# CONFIG_INET_LRO is not set -+CONFIG_INET_DIAG=y -+CONFIG_INET_TCP_DIAG=y -+# CONFIG_TCP_CONG_ADVANCED is not set -+CONFIG_TCP_CONG_CUBIC=y -+CONFIG_DEFAULT_TCP_CONG="cubic" -+# CONFIG_TCP_MD5SIG is not set -+# 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 -+# CONFIG_IP_DCCP is not set -+# CONFIG_IP_SCTP is not set -+# 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_ECONET is not set -+# CONFIG_WAN_ROUTER is not set -+# 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_AF_RXRPC is not set -+ -+# -+# Wireless -+# -+# CONFIG_CFG80211 is not set -+# CONFIG_WIRELESS_EXT is not set -+# CONFIG_MAC80211 is not set -+# CONFIG_IEEE80211 is not set -+# CONFIG_RFKILL is not set -+# CONFIG_NET_9P is not set -+ -+# -+# Device Drivers -+# -+ -+# -+# Generic Driver Options -+# -+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -+CONFIG_STANDALONE=y -+CONFIG_PREVENT_FIRMWARE_BUILD=y -+# CONFIG_FW_LOADER is not set -+# CONFIG_DEBUG_DRIVER is not set -+# CONFIG_DEBUG_DEVRES is not set -+# CONFIG_SYS_HYPERVISOR is not set -+# CONFIG_CONNECTOR is not set -+CONFIG_MTD=y -+# CONFIG_MTD_DEBUG is not set -+# CONFIG_MTD_CONCAT is not set -+# CONFIG_MTD_PARTITIONS is not set -+ -+# -+# User Modules And Translation Layers -+# -+CONFIG_MTD_CHAR=y -+CONFIG_MTD_BLKDEVS=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 -+# CONFIG_SSFDC is not set -+# CONFIG_MTD_OOPS 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 is not set -+CONFIG_MTD_CFI_AMDSTD=y -+# 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 -+ -+# -+# Mapping drivers for chip access -+# -+# CONFIG_MTD_COMPLEX_MAPPINGS is not set -+# CONFIG_MTD_PHYSMAP is not set -+CONFIG_MTD_PHYSMAP_OF=y -+# CONFIG_MTD_CFI_FLAGADM is not set -+# 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 -+# CONFIG_MTD_NAND is not set -+# CONFIG_MTD_ONENAND is not set -+ -+# -+# UBI - Unsorted block images -+# -+# CONFIG_MTD_UBI is not set -+CONFIG_OF_DEVICE=y -+# CONFIG_PARPORT is not set -+# CONFIG_BLK_DEV is not set -+# CONFIG_MISC_DEVICES is not set -+# CONFIG_IDE is not set -+ -+# -+# SCSI device support -+# -+# CONFIG_RAID_ATTRS is not set -+# CONFIG_SCSI is not set -+# CONFIG_SCSI_DMA is not set -+# CONFIG_SCSI_NETLINK is not set -+# CONFIG_ATA is not set -+# CONFIG_MD is not set -+# CONFIG_MACINTOSH_DRIVERS is not set -+CONFIG_NETDEVICES=y -+# CONFIG_NETDEVICES_MULTIQUEUE is not set -+# CONFIG_DUMMY is not set -+# CONFIG_BONDING is not set -+# CONFIG_MACVLAN is not set -+# CONFIG_EQUALIZER is not set -+# CONFIG_TUN is not set -+# CONFIG_VETH is not set -+CONFIG_PHYLIB=y -+ -+# -+# MII PHY device drivers -+# -+# CONFIG_MARVELL_PHY is not set -+CONFIG_DAVICOM_PHY=y -+# CONFIG_QSEMI_PHY is not set -+# CONFIG_LXT_PHY is not set -+# CONFIG_CICADA_PHY is not set -+# CONFIG_VITESSE_PHY is not set -+# CONFIG_SMSC_PHY is not set -+# CONFIG_BROADCOM_PHY is not set -+# CONFIG_ICPLUS_PHY is not set -+# CONFIG_FIXED_PHY is not set -+# CONFIG_MDIO_BITBANG is not set -+CONFIG_NET_ETHERNET=y -+CONFIG_MII=y -+# CONFIG_IBM_NEW_EMAC_ZMII is not set -+# CONFIG_IBM_NEW_EMAC_RGMII is not set -+# CONFIG_IBM_NEW_EMAC_TAH is not set -+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set -+# CONFIG_B44 is not set -+CONFIG_FS_ENET=y -+# CONFIG_FS_ENET_HAS_SCC is not set -+CONFIG_FS_ENET_HAS_FEC=y -+CONFIG_FS_ENET_MDIO_FEC=y -+# CONFIG_NETDEV_1000 is not set -+# CONFIG_NETDEV_10000 is not set -+ -+# -+# Wireless LAN -+# -+# CONFIG_WLAN_PRE80211 is not set -+# CONFIG_WLAN_80211 is not set -+# 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 -+# CONFIG_ISDN is not set -+# CONFIG_PHONE is not set -+ -+# -+# Input device support -+# -+CONFIG_INPUT=y -+# CONFIG_INPUT_FF_MEMLESS is not set -+# CONFIG_INPUT_POLLDEV is not set -+ -+# -+# Userland interfaces -+# -+CONFIG_INPUT_MOUSEDEV=y -+CONFIG_INPUT_MOUSEDEV_PSAUX=y -+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -+# CONFIG_INPUT_JOYDEV 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_KEYBOARD_STOWAWAY is not set -+CONFIG_INPUT_MOUSE=y -+CONFIG_MOUSE_PS2=y -+CONFIG_MOUSE_PS2_ALPS=y -+CONFIG_MOUSE_PS2_LOGIPS2PP=y -+CONFIG_MOUSE_PS2_SYNAPTICS=y -+CONFIG_MOUSE_PS2_LIFEBOOK=y -+CONFIG_MOUSE_PS2_TRACKPOINT=y -+# CONFIG_MOUSE_PS2_TOUCHKIT is not set -+# CONFIG_MOUSE_SERIAL is not set -+# CONFIG_MOUSE_VSXXXAA is not set -+# CONFIG_INPUT_JOYSTICK is not set -+# CONFIG_INPUT_TABLET 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=y -+CONFIG_SERIO_LIBPS2=y -+# CONFIG_SERIO_RAW is not set -+# CONFIG_GAMEPORT is not set -+ -+# -+# Character devices -+# -+# CONFIG_VT is not set -+# CONFIG_SERIAL_NONSTANDARD is not set -+ -+# -+# Serial drivers -+# -+# CONFIG_SERIAL_8250 is not set -+ -+# -+# Non-8250 serial port support -+# -+# CONFIG_SERIAL_UARTLITE is not set -+CONFIG_SERIAL_CORE=y -+CONFIG_SERIAL_CORE_CONSOLE=y -+CONFIG_SERIAL_CPM=y -+CONFIG_SERIAL_CPM_CONSOLE=y -+# CONFIG_SERIAL_CPM_SCC1 is not set -+# CONFIG_SERIAL_CPM_SCC2 is not set -+# CONFIG_SERIAL_CPM_SCC3 is not set -+# CONFIG_SERIAL_CPM_SCC4 is not set -+CONFIG_SERIAL_CPM_SMC1=y -+CONFIG_SERIAL_CPM_SMC2=y -+CONFIG_UNIX98_PTYS=y -+# CONFIG_LEGACY_PTYS is not set -+# CONFIG_IPMI_HANDLER is not set -+CONFIG_HW_RANDOM=y -+# CONFIG_NVRAM is not set -+CONFIG_GEN_RTC=y -+# CONFIG_GEN_RTC_X is not set -+# CONFIG_R3964 is not set -+# CONFIG_RAW_DRIVER is not set -+# CONFIG_TCG_TPM is not set -+# CONFIG_I2C is not set -+ -+# -+# SPI support -+# -+# CONFIG_SPI is not set -+# CONFIG_SPI_MASTER is not set -+# CONFIG_W1 is not set -+# CONFIG_POWER_SUPPLY is not set -+# CONFIG_HWMON is not set -+# CONFIG_WATCHDOG is not set -+ -+# -+# Sonics Silicon Backplane -+# -+CONFIG_SSB_POSSIBLE=y -+# CONFIG_SSB is not set -+ -+# -+# Multifunction device drivers -+# -+# CONFIG_MFD_SM501 is not set -+ -+# -+# Multimedia devices -+# -+# CONFIG_VIDEO_DEV is not set -+# CONFIG_DVB_CORE is not set -+CONFIG_DAB=y -+ -+# -+# Graphics support -+# -+# CONFIG_VGASTATE is not set -+CONFIG_VIDEO_OUTPUT_CONTROL=y -+# CONFIG_FB is not set -+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set -+ -+# -+# Display device support -+# -+# CONFIG_DISPLAY_SUPPORT is not set -+ -+# -+# Sound -+# -+# CONFIG_SOUND is not set -+# CONFIG_HID_SUPPORT is not set -+# CONFIG_USB_SUPPORT is not set -+# CONFIG_MMC is not set -+# CONFIG_NEW_LEDS is not set -+# CONFIG_EDAC is not set -+# CONFIG_RTC_CLASS is not set -+ -+# -+# Userspace I/O -+# -+# CONFIG_UIO is not set -+ -+# -+# File systems -+# -+# CONFIG_EXT2_FS is not set -+# CONFIG_EXT3_FS is not set -+# CONFIG_EXT4DEV_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_GFS2_FS is not set -+# CONFIG_OCFS2_FS is not set -+# CONFIG_MINIX_FS is not set -+# CONFIG_ROMFS_FS is not set -+# CONFIG_INOTIFY is not set -+# CONFIG_QUOTA is not set -+# CONFIG_DNOTIFY is not set -+# 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_MSDOS_FS is not set -+# CONFIG_VFAT_FS is not set -+# CONFIG_NTFS_FS is not set -+ -+# -+# Pseudo filesystems -+# -+CONFIG_PROC_FS=y -+# CONFIG_PROC_KCORE is not set -+CONFIG_PROC_SYSCTL=y -+CONFIG_SYSFS=y -+CONFIG_TMPFS=y -+# CONFIG_TMPFS_POSIX_ACL is not set -+# CONFIG_HUGETLB_PAGE 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_JFFS2_FS is not set -+CONFIG_CRAMFS=y -+# 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 -+CONFIG_NETWORK_FILESYSTEMS=y -+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_SUNRPC_BIND34 is not set -+# 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 -+ -+# -+# Partition Types -+# -+CONFIG_PARTITION_ADVANCED=y -+# CONFIG_ACORN_PARTITION is not set -+# CONFIG_OSF_PARTITION is not set -+# CONFIG_AMIGA_PARTITION is not set -+# CONFIG_ATARI_PARTITION is not set -+# CONFIG_MAC_PARTITION is not set -+CONFIG_MSDOS_PARTITION=y -+# CONFIG_BSD_DISKLABEL is not set -+# CONFIG_MINIX_SUBPARTITION is not set -+# CONFIG_SOLARIS_X86_PARTITION is not set -+# CONFIG_UNIXWARE_DISKLABEL is not set -+# CONFIG_LDM_PARTITION is not set -+# CONFIG_SGI_PARTITION is not set -+# CONFIG_ULTRIX_PARTITION is not set -+# CONFIG_SUN_PARTITION is not set -+# CONFIG_KARMA_PARTITION is not set -+# CONFIG_EFI_PARTITION is not set -+# CONFIG_SYSV68_PARTITION is not set -+# CONFIG_NLS is not set -+# CONFIG_DLM is not set -+# CONFIG_UCC_SLOW is not set -+ -+# -+# Library routines -+# -+# CONFIG_CRC_CCITT is not set -+# CONFIG_CRC16 is not set -+# CONFIG_CRC_ITU_T is not set -+# CONFIG_CRC32 is not set -+# CONFIG_CRC7 is not set -+# CONFIG_LIBCRC32C is not set -+CONFIG_ZLIB_INFLATE=y -+CONFIG_HAS_IOMEM=y -+CONFIG_HAS_IOPORT=y -+CONFIG_HAS_DMA=y -+CONFIG_INSTRUMENTATION=y -+# CONFIG_PROFILING is not set -+# CONFIG_MARKERS is not set -+ -+# -+# Kernel hacking -+# -+# CONFIG_PRINTK_TIME is not set -+CONFIG_ENABLE_WARN_DEPRECATED=y -+CONFIG_ENABLE_MUST_CHECK=y -+CONFIG_MAGIC_SYSRQ=y -+# CONFIG_UNUSED_SYMBOLS is not set -+# CONFIG_DEBUG_FS is not set -+# CONFIG_HEADERS_CHECK is not set -+CONFIG_DEBUG_KERNEL=y -+# CONFIG_DEBUG_SHIRQ is not set -+CONFIG_DETECT_SOFTLOCKUP=y -+CONFIG_SCHED_DEBUG=y -+# CONFIG_SCHEDSTATS is not set -+# CONFIG_TIMER_STATS is not set -+# CONFIG_SLUB_DEBUG_ON is not set -+# CONFIG_DEBUG_SPINLOCK is not set -+# CONFIG_DEBUG_MUTEXES is not set -+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -+# CONFIG_DEBUG_KOBJECT is not set -+CONFIG_DEBUG_BUGVERBOSE=y -+CONFIG_DEBUG_INFO=y -+# CONFIG_DEBUG_VM is not set -+# CONFIG_DEBUG_LIST is not set -+# CONFIG_DEBUG_SG is not set -+CONFIG_FORCED_INLINING=y -+# CONFIG_BOOT_PRINTK_DELAY is not set -+# CONFIG_FAULT_INJECTION is not set -+# CONFIG_SAMPLES is not set -+# CONFIG_DEBUG_STACKOVERFLOW is not set -+# CONFIG_DEBUG_STACK_USAGE is not set -+# CONFIG_DEBUG_PAGEALLOC is not set -+# CONFIG_DEBUGGER is not set -+# CONFIG_BDI_SWITCH is not set -+# CONFIG_PPC_EARLY_DEBUG is not set -+ -+# -+# Security options -+# -+# CONFIG_KEYS is not set -+# CONFIG_SECURITY is not set -+# CONFIG_SECURITY_FILE_CAPABILITIES is not set -+# CONFIG_CRYPTO is not set -+# CONFIG_PPC_CLOCK is not set -+CONFIG_PPC_LIB_RHEAP=y ---- /dev/null -+++ b/arch/powerpc/configs/adder875-uboot_defconfig -@@ -0,0 +1,798 @@ -+# -+# Automatically generated make config: don't edit -+# Linux kernel version: 2.6.24-rc6 -+# Thu Jan 17 16:17:18 2008 -+# -+# CONFIG_PPC64 is not set -+ -+# -+# Processor support -+# -+# CONFIG_6xx is not set -+# CONFIG_PPC_85xx is not set -+CONFIG_PPC_8xx=y -+# CONFIG_40x is not set -+# CONFIG_44x is not set -+# CONFIG_E200 is not set -+CONFIG_8xx=y -+# CONFIG_PPC_MM_SLICES is not set -+CONFIG_NOT_COHERENT_CACHE=y -+CONFIG_PPC32=y -+CONFIG_WORD_SIZE=32 -+CONFIG_PPC_MERGE=y -+CONFIG_MMU=y -+CONFIG_GENERIC_CMOS_UPDATE=y -+CONFIG_GENERIC_TIME=y -+CONFIG_GENERIC_TIME_VSYSCALL=y -+CONFIG_GENERIC_CLOCKEVENTS=y -+CONFIG_GENERIC_HARDIRQS=y -+CONFIG_IRQ_PER_CPU=y -+CONFIG_RWSEM_XCHGADD_ALGORITHM=y -+CONFIG_ARCH_HAS_ILOG2_U32=y -+CONFIG_GENERIC_HWEIGHT=y -+CONFIG_GENERIC_CALIBRATE_DELAY=y -+CONFIG_GENERIC_FIND_NEXT_BIT=y -+# CONFIG_ARCH_NO_VIRT_TO_BUS is not set -+CONFIG_PPC=y -+CONFIG_EARLY_PRINTK=y -+CONFIG_GENERIC_NVRAM=y -+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -+CONFIG_ARCH_MAY_HAVE_PC_FDC=y -+CONFIG_PPC_OF=y -+CONFIG_OF=y -+# CONFIG_PPC_UDBG_16550 is not set -+# CONFIG_GENERIC_TBSYNC is not set -+CONFIG_AUDIT_ARCH=y -+CONFIG_GENERIC_BUG=y -+# CONFIG_DEFAULT_UIMAGE is not set -+CONFIG_REDBOOT=y -+# CONFIG_PPC_DCR_NATIVE is not set -+# CONFIG_PPC_DCR_MMIO is not set -+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" -+ -+# -+# General setup -+# -+CONFIG_EXPERIMENTAL=y -+CONFIG_BROKEN_ON_SMP=y -+CONFIG_INIT_ENV_ARG_LIMIT=32 -+CONFIG_LOCALVERSION="" -+CONFIG_LOCALVERSION_AUTO=y -+# CONFIG_SWAP is not set -+CONFIG_SYSVIPC=y -+CONFIG_SYSVIPC_SYSCTL=y -+# CONFIG_POSIX_MQUEUE is not set -+# CONFIG_BSD_PROCESS_ACCT is not set -+# CONFIG_TASKSTATS is not set -+# CONFIG_USER_NS is not set -+# CONFIG_PID_NS is not set -+# CONFIG_AUDIT is not set -+# CONFIG_IKCONFIG is not set -+CONFIG_LOG_BUF_SHIFT=14 -+# CONFIG_CGROUPS is not set -+CONFIG_FAIR_GROUP_SCHED=y -+CONFIG_FAIR_USER_SCHED=y -+# CONFIG_FAIR_CGROUP_SCHED is not set -+CONFIG_SYSFS_DEPRECATED=y -+# CONFIG_RELAY is not set -+# CONFIG_BLK_DEV_INITRD is not set -+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -+CONFIG_SYSCTL=y -+CONFIG_EMBEDDED=y -+# CONFIG_SYSCTL_SYSCALL is not set -+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 is not set -+# CONFIG_BASE_FULL is not set -+# CONFIG_FUTEX is not set -+CONFIG_ANON_INODES=y -+CONFIG_EPOLL=y -+CONFIG_SIGNALFD=y -+CONFIG_EVENTFD=y -+CONFIG_SHMEM=y -+# CONFIG_VM_EVENT_COUNTERS is not set -+CONFIG_SLUB_DEBUG=y -+# CONFIG_SLAB is not set -+CONFIG_SLUB=y -+# CONFIG_SLOB is not set -+# CONFIG_TINY_SHMEM is not set -+CONFIG_BASE_SMALL=1 -+# CONFIG_MODULES is not set -+CONFIG_BLOCK=y -+# CONFIG_LBD is not set -+# CONFIG_BLK_DEV_IO_TRACE is not set -+# CONFIG_LSF is not set -+# CONFIG_BLK_DEV_BSG is not set -+ -+# -+# IO Schedulers -+# -+CONFIG_IOSCHED_NOOP=y -+# CONFIG_IOSCHED_AS is not set -+CONFIG_IOSCHED_DEADLINE=y -+# CONFIG_IOSCHED_CFQ is not set -+# CONFIG_DEFAULT_AS is not set -+CONFIG_DEFAULT_DEADLINE=y -+# CONFIG_DEFAULT_CFQ is not set -+# CONFIG_DEFAULT_NOOP is not set -+CONFIG_DEFAULT_IOSCHED="deadline" -+ -+# -+# Platform support -+# -+# CONFIG_PPC_MPC52xx is not set -+# CONFIG_PPC_MPC5200 is not set -+# CONFIG_PPC_CELL is not set -+# CONFIG_PPC_CELL_NATIVE is not set -+CONFIG_CPM1=y -+# CONFIG_MPC8XXFADS is not set -+# CONFIG_MPC86XADS is not set -+# CONFIG_MPC885ADS is not set -+# CONFIG_PPC_EP88XC is not set -+CONFIG_PPC_ADDER875=y -+ -+# -+# MPC8xx CPM Options -+# -+ -+# -+# Generic MPC8xx Options -+# -+CONFIG_8xx_COPYBACK=y -+# CONFIG_8xx_CPU6 is not set -+CONFIG_8xx_CPU15=y -+CONFIG_NO_UCODE_PATCH=y -+# CONFIG_USB_SOF_UCODE_PATCH is not set -+# CONFIG_I2C_SPI_UCODE_PATCH is not set -+# CONFIG_I2C_SPI_SMC1_UCODE_PATCH is not set -+# CONFIG_PQ2ADS is not set -+# CONFIG_MPIC is not set -+# CONFIG_MPIC_WEIRD is not set -+# CONFIG_PPC_I8259 is not set -+# CONFIG_PPC_RTAS is not set -+# CONFIG_MMIO_NVRAM is not set -+# CONFIG_PPC_MPC106 is not set -+# CONFIG_PPC_970_NAP is not set -+# CONFIG_PPC_INDIRECT_IO is not set -+# CONFIG_GENERIC_IOMAP is not set -+# CONFIG_CPU_FREQ is not set -+# CONFIG_CPM2 is not set -+CONFIG_PPC_CPM_NEW_BINDING=y -+# CONFIG_FSL_ULI1575 is not set -+CONFIG_CPM=y -+ -+# -+# Kernel options -+# -+# CONFIG_HIGHMEM is not set -+# CONFIG_TICK_ONESHOT is not set -+# CONFIG_NO_HZ is not set -+# CONFIG_HIGH_RES_TIMERS is not set -+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y -+# CONFIG_HZ_100 is not set -+# CONFIG_HZ_250 is not set -+# CONFIG_HZ_300 is not set -+CONFIG_HZ_1000=y -+CONFIG_HZ=1000 -+CONFIG_PREEMPT_NONE=y -+# CONFIG_PREEMPT_VOLUNTARY is not set -+# CONFIG_PREEMPT is not set -+CONFIG_BINFMT_ELF=y -+# CONFIG_BINFMT_MISC is not set -+# CONFIG_MATH_EMULATION is not set -+# CONFIG_8XX_MINIMAL_FPEMU is not set -+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y -+CONFIG_ARCH_FLATMEM_ENABLE=y -+CONFIG_ARCH_POPULATES_NODE_MAP=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 is not set -+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set -+CONFIG_SPLIT_PTLOCK_CPUS=4 -+# CONFIG_RESOURCES_64BIT is not set -+CONFIG_ZONE_DMA_FLAG=1 -+CONFIG_BOUNCE=y -+CONFIG_VIRT_TO_BUS=y -+# CONFIG_PROC_DEVICETREE is not set -+# CONFIG_CMDLINE_BOOL is not set -+# CONFIG_PM is not set -+CONFIG_SUSPEND_UP_POSSIBLE=y -+CONFIG_HIBERNATION_UP_POSSIBLE=y -+# CONFIG_SECCOMP is not set -+CONFIG_WANT_DEVICE_TREE=y -+CONFIG_DEVICE_TREE="adder875-uboot.dts" -+CONFIG_ISA_DMA_API=y -+ -+# -+# Bus options -+# -+CONFIG_ZONE_DMA=y -+CONFIG_FSL_SOC=y -+# CONFIG_PCI is not set -+# CONFIG_PCI_DOMAINS is not set -+# CONFIG_PCI_SYSCALL is not set -+# CONFIG_PCI_QSPAN is not set -+# CONFIG_ARCH_SUPPORTS_MSI is not set -+# CONFIG_PCCARD is not set -+ -+# -+# Advanced setup -+# -+# CONFIG_ADVANCED_OPTIONS is not set -+ -+# -+# Default settings for advanced configuration options are used -+# -+CONFIG_HIGHMEM_START=0xfe000000 -+CONFIG_LOWMEM_SIZE=0x30000000 -+CONFIG_KERNEL_START=0xc0000000 -+CONFIG_TASK_SIZE=0x80000000 -+CONFIG_CONSISTENT_START=0xfd000000 -+CONFIG_CONSISTENT_SIZE=0x00200000 -+CONFIG_BOOT_LOAD=0x00400000 -+ -+# -+# Networking -+# -+CONFIG_NET=y -+ -+# -+# Networking options -+# -+CONFIG_PACKET=y -+# CONFIG_PACKET_MMAP is not set -+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=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_XFRM_MODE_TRANSPORT is not set -+# CONFIG_INET_XFRM_MODE_TUNNEL is not set -+# CONFIG_INET_XFRM_MODE_BEET is not set -+# CONFIG_INET_LRO is not set -+CONFIG_INET_DIAG=y -+CONFIG_INET_TCP_DIAG=y -+# CONFIG_TCP_CONG_ADVANCED is not set -+CONFIG_TCP_CONG_CUBIC=y -+CONFIG_DEFAULT_TCP_CONG="cubic" -+# CONFIG_TCP_MD5SIG is not set -+# 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 -+# CONFIG_IP_DCCP is not set -+# CONFIG_IP_SCTP is not set -+# 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_ECONET is not set -+# CONFIG_WAN_ROUTER is not set -+# 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_AF_RXRPC is not set -+ -+# -+# Wireless -+# -+# CONFIG_CFG80211 is not set -+# CONFIG_WIRELESS_EXT is not set -+# CONFIG_MAC80211 is not set -+# CONFIG_IEEE80211 is not set -+# CONFIG_RFKILL is not set -+# CONFIG_NET_9P is not set -+ -+# -+# Device Drivers -+# -+ -+# -+# Generic Driver Options -+# -+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -+CONFIG_STANDALONE=y -+CONFIG_PREVENT_FIRMWARE_BUILD=y -+# CONFIG_FW_LOADER is not set -+# CONFIG_DEBUG_DRIVER is not set -+# CONFIG_DEBUG_DEVRES is not set -+# CONFIG_SYS_HYPERVISOR is not set -+# CONFIG_CONNECTOR is not set -+CONFIG_MTD=y -+# CONFIG_MTD_DEBUG is not set -+# CONFIG_MTD_CONCAT is not set -+# CONFIG_MTD_PARTITIONS is not set -+ -+# -+# User Modules And Translation Layers -+# -+CONFIG_MTD_CHAR=y -+CONFIG_MTD_BLKDEVS=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 -+# CONFIG_SSFDC is not set -+# CONFIG_MTD_OOPS 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 is not set -+CONFIG_MTD_CFI_AMDSTD=y -+# 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 -+ -+# -+# Mapping drivers for chip access -+# -+# CONFIG_MTD_COMPLEX_MAPPINGS is not set -+# CONFIG_MTD_PHYSMAP is not set -+CONFIG_MTD_PHYSMAP_OF=y -+# CONFIG_MTD_CFI_FLAGADM is not set -+# 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 -+# CONFIG_MTD_NAND is not set -+# CONFIG_MTD_ONENAND is not set -+ -+# -+# UBI - Unsorted block images -+# -+# CONFIG_MTD_UBI is not set -+CONFIG_OF_DEVICE=y -+# CONFIG_PARPORT is not set -+# CONFIG_BLK_DEV is not set -+# CONFIG_MISC_DEVICES is not set -+# CONFIG_IDE is not set -+ -+# -+# SCSI device support -+# -+# CONFIG_RAID_ATTRS is not set -+# CONFIG_SCSI is not set -+# CONFIG_SCSI_DMA is not set -+# CONFIG_SCSI_NETLINK is not set -+# CONFIG_ATA is not set -+# CONFIG_MD is not set -+# CONFIG_MACINTOSH_DRIVERS is not set -+CONFIG_NETDEVICES=y -+# CONFIG_NETDEVICES_MULTIQUEUE is not set -+# CONFIG_DUMMY is not set -+# CONFIG_BONDING is not set -+# CONFIG_MACVLAN is not set -+# CONFIG_EQUALIZER is not set -+# CONFIG_TUN is not set -+# CONFIG_VETH is not set -+CONFIG_PHYLIB=y -+ -+# -+# MII PHY device drivers -+# -+# CONFIG_MARVELL_PHY is not set -+CONFIG_DAVICOM_PHY=y -+# CONFIG_QSEMI_PHY is not set -+# CONFIG_LXT_PHY is not set -+# CONFIG_CICADA_PHY is not set -+# CONFIG_VITESSE_PHY is not set -+# CONFIG_SMSC_PHY is not set -+# CONFIG_BROADCOM_PHY is not set -+# CONFIG_ICPLUS_PHY is not set -+# CONFIG_FIXED_PHY is not set -+# CONFIG_MDIO_BITBANG is not set -+CONFIG_NET_ETHERNET=y -+CONFIG_MII=y -+# CONFIG_IBM_NEW_EMAC_ZMII is not set -+# CONFIG_IBM_NEW_EMAC_RGMII is not set -+# CONFIG_IBM_NEW_EMAC_TAH is not set -+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set -+# CONFIG_B44 is not set -+CONFIG_FS_ENET=y -+# CONFIG_FS_ENET_HAS_SCC is not set -+CONFIG_FS_ENET_HAS_FEC=y -+CONFIG_FS_ENET_MDIO_FEC=y -+# CONFIG_NETDEV_1000 is not set -+# CONFIG_NETDEV_10000 is not set -+ -+# -+# Wireless LAN -+# -+# CONFIG_WLAN_PRE80211 is not set -+# CONFIG_WLAN_80211 is not set -+# 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 -+# CONFIG_ISDN is not set -+# CONFIG_PHONE is not set -+ -+# -+# Input device support -+# -+CONFIG_INPUT=y -+# CONFIG_INPUT_FF_MEMLESS is not set -+# CONFIG_INPUT_POLLDEV is not set -+ -+# -+# Userland interfaces -+# -+CONFIG_INPUT_MOUSEDEV=y -+CONFIG_INPUT_MOUSEDEV_PSAUX=y -+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -+# CONFIG_INPUT_JOYDEV 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_KEYBOARD_STOWAWAY is not set -+CONFIG_INPUT_MOUSE=y -+CONFIG_MOUSE_PS2=y -+CONFIG_MOUSE_PS2_ALPS=y -+CONFIG_MOUSE_PS2_LOGIPS2PP=y -+CONFIG_MOUSE_PS2_SYNAPTICS=y -+CONFIG_MOUSE_PS2_LIFEBOOK=y -+CONFIG_MOUSE_PS2_TRACKPOINT=y -+# CONFIG_MOUSE_PS2_TOUCHKIT is not set -+# CONFIG_MOUSE_SERIAL is not set -+# CONFIG_MOUSE_VSXXXAA is not set -+# CONFIG_INPUT_JOYSTICK is not set -+# CONFIG_INPUT_TABLET 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=y -+CONFIG_SERIO_LIBPS2=y -+# CONFIG_SERIO_RAW is not set -+# CONFIG_GAMEPORT is not set -+ -+# -+# Character devices -+# -+# CONFIG_VT is not set -+# CONFIG_SERIAL_NONSTANDARD is not set -+ -+# -+# Serial drivers -+# -+# CONFIG_SERIAL_8250 is not set -+ -+# -+# Non-8250 serial port support -+# -+# CONFIG_SERIAL_UARTLITE is not set -+CONFIG_SERIAL_CORE=y -+CONFIG_SERIAL_CORE_CONSOLE=y -+CONFIG_SERIAL_CPM=y -+CONFIG_SERIAL_CPM_CONSOLE=y -+# CONFIG_SERIAL_CPM_SCC1 is not set -+# CONFIG_SERIAL_CPM_SCC2 is not set -+# CONFIG_SERIAL_CPM_SCC3 is not set -+# CONFIG_SERIAL_CPM_SCC4 is not set -+CONFIG_SERIAL_CPM_SMC1=y -+CONFIG_SERIAL_CPM_SMC2=y -+CONFIG_UNIX98_PTYS=y -+# CONFIG_LEGACY_PTYS is not set -+# CONFIG_IPMI_HANDLER is not set -+CONFIG_HW_RANDOM=y -+# CONFIG_NVRAM is not set -+CONFIG_GEN_RTC=y -+# CONFIG_GEN_RTC_X is not set -+# CONFIG_R3964 is not set -+# CONFIG_RAW_DRIVER is not set -+# CONFIG_TCG_TPM is not set -+# CONFIG_I2C is not set -+ -+# -+# SPI support -+# -+# CONFIG_SPI is not set -+# CONFIG_SPI_MASTER is not set -+# CONFIG_W1 is not set -+# CONFIG_POWER_SUPPLY is not set -+# CONFIG_HWMON is not set -+# CONFIG_WATCHDOG is not set -+ -+# -+# Sonics Silicon Backplane -+# -+CONFIG_SSB_POSSIBLE=y -+# CONFIG_SSB is not set -+ -+# -+# Multifunction device drivers -+# -+# CONFIG_MFD_SM501 is not set -+ -+# -+# Multimedia devices -+# -+# CONFIG_VIDEO_DEV is not set -+# CONFIG_DVB_CORE is not set -+CONFIG_DAB=y -+ -+# -+# Graphics support -+# -+# CONFIG_VGASTATE is not set -+CONFIG_VIDEO_OUTPUT_CONTROL=y -+# CONFIG_FB is not set -+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set -+ -+# -+# Display device support -+# -+# CONFIG_DISPLAY_SUPPORT is not set -+ -+# -+# Sound -+# -+# CONFIG_SOUND is not set -+# CONFIG_HID_SUPPORT is not set -+# CONFIG_USB_SUPPORT is not set -+# CONFIG_MMC is not set -+# CONFIG_NEW_LEDS is not set -+# CONFIG_EDAC is not set -+# CONFIG_RTC_CLASS is not set -+ -+# -+# Userspace I/O -+# -+# CONFIG_UIO is not set -+ -+# -+# File systems -+# -+# CONFIG_EXT2_FS is not set -+# CONFIG_EXT3_FS is not set -+# CONFIG_EXT4DEV_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_GFS2_FS is not set -+# CONFIG_OCFS2_FS is not set -+# CONFIG_MINIX_FS is not set -+# CONFIG_ROMFS_FS is not set -+# CONFIG_INOTIFY is not set -+# CONFIG_QUOTA is not set -+# CONFIG_DNOTIFY is not set -+# 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_MSDOS_FS is not set -+# CONFIG_VFAT_FS is not set -+# CONFIG_NTFS_FS is not set -+ -+# -+# Pseudo filesystems -+# -+CONFIG_PROC_FS=y -+# CONFIG_PROC_KCORE is not set -+CONFIG_PROC_SYSCTL=y -+CONFIG_SYSFS=y -+CONFIG_TMPFS=y -+# CONFIG_TMPFS_POSIX_ACL is not set -+# CONFIG_HUGETLB_PAGE 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_JFFS2_FS is not set -+CONFIG_CRAMFS=y -+# 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 -+CONFIG_NETWORK_FILESYSTEMS=y -+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_SUNRPC_BIND34 is not set -+# 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 -+ -+# -+# Partition Types -+# -+CONFIG_PARTITION_ADVANCED=y -+# CONFIG_ACORN_PARTITION is not set -+# CONFIG_OSF_PARTITION is not set -+# CONFIG_AMIGA_PARTITION is not set -+# CONFIG_ATARI_PARTITION is not set -+# CONFIG_MAC_PARTITION is not set -+CONFIG_MSDOS_PARTITION=y -+# CONFIG_BSD_DISKLABEL is not set -+# CONFIG_MINIX_SUBPARTITION is not set -+# CONFIG_SOLARIS_X86_PARTITION is not set -+# CONFIG_UNIXWARE_DISKLABEL is not set -+# CONFIG_LDM_PARTITION is not set -+# CONFIG_SGI_PARTITION is not set -+# CONFIG_ULTRIX_PARTITION is not set -+# CONFIG_SUN_PARTITION is not set -+# CONFIG_KARMA_PARTITION is not set -+# CONFIG_EFI_PARTITION is not set -+# CONFIG_SYSV68_PARTITION is not set -+# CONFIG_NLS is not set -+# CONFIG_DLM is not set -+# CONFIG_UCC_SLOW is not set -+ -+# -+# Library routines -+# -+# CONFIG_CRC_CCITT is not set -+# CONFIG_CRC16 is not set -+# CONFIG_CRC_ITU_T is not set -+# CONFIG_CRC32 is not set -+# CONFIG_CRC7 is not set -+# CONFIG_LIBCRC32C is not set -+CONFIG_ZLIB_INFLATE=y -+CONFIG_HAS_IOMEM=y -+CONFIG_HAS_IOPORT=y -+CONFIG_HAS_DMA=y -+CONFIG_INSTRUMENTATION=y -+# CONFIG_PROFILING is not set -+# CONFIG_MARKERS is not set -+ -+# -+# Kernel hacking -+# -+# CONFIG_PRINTK_TIME is not set -+CONFIG_ENABLE_WARN_DEPRECATED=y -+CONFIG_ENABLE_MUST_CHECK=y -+CONFIG_MAGIC_SYSRQ=y -+# CONFIG_UNUSED_SYMBOLS is not set -+# CONFIG_DEBUG_FS is not set -+# CONFIG_HEADERS_CHECK is not set -+CONFIG_DEBUG_KERNEL=y -+# CONFIG_DEBUG_SHIRQ is not set -+CONFIG_DETECT_SOFTLOCKUP=y -+CONFIG_SCHED_DEBUG=y -+# CONFIG_SCHEDSTATS is not set -+# CONFIG_TIMER_STATS is not set -+# CONFIG_SLUB_DEBUG_ON is not set -+# CONFIG_DEBUG_SPINLOCK is not set -+# CONFIG_DEBUG_MUTEXES is not set -+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -+# CONFIG_DEBUG_KOBJECT is not set -+CONFIG_DEBUG_BUGVERBOSE=y -+CONFIG_DEBUG_INFO=y -+# CONFIG_DEBUG_VM is not set -+# CONFIG_DEBUG_LIST is not set -+# CONFIG_DEBUG_SG is not set -+CONFIG_FORCED_INLINING=y -+# CONFIG_BOOT_PRINTK_DELAY is not set -+# CONFIG_FAULT_INJECTION is not set -+# CONFIG_SAMPLES is not set -+# CONFIG_DEBUG_STACKOVERFLOW is not set -+# CONFIG_DEBUG_STACK_USAGE is not set -+# CONFIG_DEBUG_PAGEALLOC is not set -+# CONFIG_DEBUGGER is not set -+# CONFIG_BDI_SWITCH is not set -+# CONFIG_PPC_EARLY_DEBUG is not set -+ -+# -+# Security options -+# -+# CONFIG_KEYS is not set -+# CONFIG_SECURITY is not set -+# CONFIG_SECURITY_FILE_CAPABILITIES is not set -+# CONFIG_CRYPTO is not set -+# CONFIG_PPC_CLOCK is not set -+CONFIG_PPC_LIB_RHEAP=y ---- a/arch/powerpc/configs/bamboo_defconfig -+++ b/arch/powerpc/configs/bamboo_defconfig -@@ -1,7 +1,7 @@ - # - # Automatically generated make config: don't edit --# Linux kernel version: 2.6.24-rc4 --# Thu Dec 6 16:48:04 2007 -+# Linux kernel version: 2.6.24-rc6 -+# Mon Dec 24 10:49:50 2007 - # - # CONFIG_PPC64 is not set - -@@ -131,6 +131,7 @@ CONFIG_DEFAULT_AS=y - # CONFIG_DEFAULT_CFQ is not set - # CONFIG_DEFAULT_NOOP is not set - CONFIG_DEFAULT_IOSCHED="anticipatory" -+# CONFIG_PPC4xx_PCI_EXPRESS is not set - - # - # Platform support -@@ -143,6 +144,9 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" - CONFIG_BAMBOO=y - # CONFIG_EBONY is not set - # CONFIG_SEQUOIA is not set -+# CONFIG_TAISHAN is not set -+# CONFIG_KATMAI is not set -+# CONFIG_RAINIER is not set - CONFIG_440EP=y - CONFIG_IBM440EP_ERR42=y - # CONFIG_MPIC is not set -@@ -372,9 +376,7 @@ CONFIG_MISC_DEVICES=y - # CONFIG_FIREWIRE is not set - # CONFIG_IEEE1394 is not set - # CONFIG_I2O is not set --CONFIG_MACINTOSH_DRIVERS=y --# CONFIG_MAC_EMUMOUSEBTN is not set --# CONFIG_WINDFARM is not set -+# CONFIG_MACINTOSH_DRIVERS is not set - CONFIG_NETDEVICES=y - # CONFIG_NETDEVICES_MULTIQUEUE is not set - # CONFIG_DUMMY is not set -@@ -736,19 +738,7 @@ CONFIG_DEBUGGER=y - # CONFIG_KGDB is not set - # CONFIG_XMON is not set - # CONFIG_BDI_SWITCH is not set --CONFIG_PPC_EARLY_DEBUG=y --# CONFIG_PPC_EARLY_DEBUG_LPAR is not set --# CONFIG_PPC_EARLY_DEBUG_G5 is not set --# CONFIG_PPC_EARLY_DEBUG_RTAS_PANEL is not set --# CONFIG_PPC_EARLY_DEBUG_RTAS_CONSOLE is not set --# CONFIG_PPC_EARLY_DEBUG_MAPLE is not set --# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set --# CONFIG_PPC_EARLY_DEBUG_PAS_REALMODE is not set --# CONFIG_PPC_EARLY_DEBUG_BEAT is not set --CONFIG_PPC_EARLY_DEBUG_44x=y --# CONFIG_PPC_EARLY_DEBUG_CPM is not set --CONFIG_PPC_EARLY_DEBUG_44x_PHYSLOW=0xef600300 --CONFIG_PPC_EARLY_DEBUG_44x_PHYSHIGH=0x0 -+# CONFIG_PPC_EARLY_DEBUG is not set - - # - # Security options ---- a/arch/powerpc/configs/celleb_defconfig -+++ b/arch/powerpc/configs/celleb_defconfig -@@ -50,7 +50,8 @@ CONFIG_AUDIT_ARCH=y - CONFIG_GENERIC_BUG=y - # CONFIG_DEFAULT_UIMAGE is not set - # CONFIG_PPC_DCR_NATIVE is not set --# CONFIG_PPC_DCR_MMIO is not set -+CONFIG_PPC_DCR_MMIO=y -+CONFIG_PPC_DCR=y - CONFIG_PPC_OF_PLATFORM_PCI=y - CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" - -@@ -148,7 +149,7 @@ CONFIG_PPC_MULTIPLATFORM=y - CONFIG_PPC_CELLEB=y - # CONFIG_PPC_PS3 is not set - CONFIG_PPC_CELL=y --# CONFIG_PPC_CELL_NATIVE is not set -+CONFIG_PPC_CELL_NATIVE=y - # CONFIG_PPC_IBM_CELL_BLADE is not set - - # -@@ -157,13 +158,19 @@ CONFIG_PPC_CELL=y - CONFIG_SPU_FS=y - CONFIG_SPU_FS_64K_LS=y - CONFIG_SPU_BASE=y -+CONFIG_CBE_RAS=y -+# CONFIG_CBE_THERM is not set - # CONFIG_PQ2ADS is not set -+CONFIG_PPC_NATIVE=y -+CONFIG_UDBG_RTAS_CONSOLE=y - CONFIG_PPC_UDBG_BEAT=y --# CONFIG_MPIC is not set -+CONFIG_MPIC=y - # CONFIG_MPIC_WEIRD is not set - # CONFIG_PPC_I8259 is not set - # CONFIG_U3_DART is not set --# CONFIG_PPC_RTAS is not set -+CONFIG_PPC_RTAS=y -+# CONFIG_RTAS_ERROR_LOGGING is not set -+# CONFIG_RTAS_PROC is not set - # CONFIG_MMIO_NVRAM is not set - # CONFIG_PPC_MPC106 is not set - # CONFIG_PPC_970_NAP is not set -@@ -593,10 +600,11 @@ CONFIG_MII=y - # CONFIG_NET_VENDOR_3COM is not set - # CONFIG_NET_TULIP is not set - # CONFIG_HP100 is not set --# CONFIG_IBM_NEW_EMAC_ZMII is not set --# CONFIG_IBM_NEW_EMAC_RGMII is not set --# CONFIG_IBM_NEW_EMAC_TAH is not set --# CONFIG_IBM_NEW_EMAC_EMAC4 is not set -+# CONFIG_IBM_NEW_EMAC is not set -+CONFIG_IBM_NEW_EMAC_ZMII=y -+CONFIG_IBM_NEW_EMAC_RGMII=y -+CONFIG_IBM_NEW_EMAC_TAH=y -+CONFIG_IBM_NEW_EMAC_EMAC4=y - # CONFIG_NET_PCI is not set - # CONFIG_B44 is not set - CONFIG_NETDEV_1000=y -@@ -741,6 +749,7 @@ CONFIG_SERIAL_TXX9_CONSOLE=y - CONFIG_UNIX98_PTYS=y - # CONFIG_LEGACY_PTYS is not set - CONFIG_HVC_DRIVER=y -+CONFIG_HVC_RTAS=y - CONFIG_HVC_BEAT=y - # CONFIG_IPMI_HANDLER is not set - # CONFIG_HW_RANDOM is not set -@@ -822,6 +831,7 @@ CONFIG_WATCHDOG=y - # Watchdog Device Drivers - # - # CONFIG_SOFT_WATCHDOG is not set -+# CONFIG_WATCHDOG_RTAS is not set - - # - # PCI-based Watchdog Cards -@@ -1245,17 +1255,7 @@ CONFIG_XMON_DISASSEMBLY=y - CONFIG_IRQSTACKS=y - # CONFIG_VIRQ_DEBUG is not set - # CONFIG_BOOTX_TEXT is not set --CONFIG_PPC_EARLY_DEBUG=y --# CONFIG_PPC_EARLY_DEBUG_LPAR is not set --# CONFIG_PPC_EARLY_DEBUG_G5 is not set --# CONFIG_PPC_EARLY_DEBUG_RTAS_PANEL is not set --# CONFIG_PPC_EARLY_DEBUG_RTAS_CONSOLE is not set --# CONFIG_PPC_EARLY_DEBUG_MAPLE is not set --# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set --# CONFIG_PPC_EARLY_DEBUG_PAS_REALMODE is not set --CONFIG_PPC_EARLY_DEBUG_BEAT=y --# CONFIG_PPC_EARLY_DEBUG_44x is not set --# CONFIG_PPC_EARLY_DEBUG_CPM is not set -+# CONFIG_PPC_EARLY_DEBUG is not set - - # - # Security options ---- a/arch/powerpc/configs/ebony_defconfig -+++ b/arch/powerpc/configs/ebony_defconfig -@@ -1,7 +1,7 @@ - # - # Automatically generated make config: don't edit --# Linux kernel version: 2.6.24-rc4 --# Thu Dec 6 16:48:11 2007 -+# Linux kernel version: 2.6.24-rc6 -+# Mon Dec 24 11:16:26 2007 - # - # CONFIG_PPC64 is not set - -@@ -130,6 +130,7 @@ CONFIG_DEFAULT_AS=y - # CONFIG_DEFAULT_CFQ is not set - # CONFIG_DEFAULT_NOOP is not set - CONFIG_DEFAULT_IOSCHED="anticipatory" -+# CONFIG_PPC4xx_PCI_EXPRESS is not set - - # - # Platform support -@@ -142,6 +143,9 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" - # CONFIG_BAMBOO is not set - CONFIG_EBONY=y - # CONFIG_SEQUOIA is not set -+# CONFIG_TAISHAN is not set -+# CONFIG_KATMAI is not set -+# CONFIG_RAINIER is not set - CONFIG_440GP=y - # CONFIG_MPIC is not set - # CONFIG_MPIC_WEIRD is not set ---- /dev/null -+++ b/arch/powerpc/configs/ep405_defconfig -@@ -0,0 +1,952 @@ -+# -+# Automatically generated make config: don't edit -+# Linux kernel version: 2.6.24-rc6 -+# Mon Dec 24 11:17:13 2007 -+# -+# CONFIG_PPC64 is not set -+ -+# -+# Processor support -+# -+# CONFIG_6xx is not set -+# CONFIG_PPC_85xx is not set -+# CONFIG_PPC_8xx is not set -+CONFIG_40x=y -+# CONFIG_44x is not set -+# CONFIG_E200 is not set -+CONFIG_4xx=y -+# CONFIG_PPC_MM_SLICES is not set -+CONFIG_NOT_COHERENT_CACHE=y -+CONFIG_PPC32=y -+CONFIG_WORD_SIZE=32 -+CONFIG_PPC_MERGE=y -+CONFIG_MMU=y -+CONFIG_GENERIC_CMOS_UPDATE=y -+CONFIG_GENERIC_TIME=y -+CONFIG_GENERIC_TIME_VSYSCALL=y -+CONFIG_GENERIC_CLOCKEVENTS=y -+CONFIG_GENERIC_HARDIRQS=y -+CONFIG_IRQ_PER_CPU=y -+CONFIG_RWSEM_XCHGADD_ALGORITHM=y -+CONFIG_ARCH_HAS_ILOG2_U32=y -+CONFIG_GENERIC_HWEIGHT=y -+CONFIG_GENERIC_CALIBRATE_DELAY=y -+CONFIG_GENERIC_FIND_NEXT_BIT=y -+# CONFIG_ARCH_NO_VIRT_TO_BUS is not set -+CONFIG_PPC=y -+CONFIG_EARLY_PRINTK=y -+CONFIG_GENERIC_NVRAM=y -+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -+CONFIG_ARCH_MAY_HAVE_PC_FDC=y -+CONFIG_PPC_OF=y -+CONFIG_OF=y -+CONFIG_PPC_UDBG_16550=y -+# CONFIG_GENERIC_TBSYNC is not set -+CONFIG_AUDIT_ARCH=y -+CONFIG_GENERIC_BUG=y -+# CONFIG_DEFAULT_UIMAGE is not set -+CONFIG_PPC_DCR_NATIVE=y -+# CONFIG_PPC_DCR_MMIO is not set -+CONFIG_PPC_DCR=y -+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" -+ -+# -+# General setup -+# -+CONFIG_EXPERIMENTAL=y -+CONFIG_BROKEN_ON_SMP=y -+CONFIG_INIT_ENV_ARG_LIMIT=32 -+CONFIG_LOCALVERSION="" -+CONFIG_LOCALVERSION_AUTO=y -+CONFIG_SWAP=y -+CONFIG_SYSVIPC=y -+CONFIG_SYSVIPC_SYSCTL=y -+CONFIG_POSIX_MQUEUE=y -+# CONFIG_BSD_PROCESS_ACCT is not set -+# CONFIG_TASKSTATS is not set -+# CONFIG_USER_NS is not set -+# CONFIG_PID_NS is not set -+# CONFIG_AUDIT is not set -+# CONFIG_IKCONFIG is not set -+CONFIG_LOG_BUF_SHIFT=14 -+# CONFIG_CGROUPS is not set -+CONFIG_FAIR_GROUP_SCHED=y -+CONFIG_FAIR_USER_SCHED=y -+# CONFIG_FAIR_CGROUP_SCHED is not set -+CONFIG_SYSFS_DEPRECATED=y -+# CONFIG_RELAY is not set -+CONFIG_BLK_DEV_INITRD=y -+CONFIG_INITRAMFS_SOURCE="" -+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -+CONFIG_SYSCTL=y -+CONFIG_EMBEDDED=y -+CONFIG_SYSCTL_SYSCALL=y -+CONFIG_KALLSYMS=y -+CONFIG_KALLSYMS_ALL=y -+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_ANON_INODES=y -+CONFIG_EPOLL=y -+CONFIG_SIGNALFD=y -+CONFIG_EVENTFD=y -+CONFIG_SHMEM=y -+CONFIG_VM_EVENT_COUNTERS=y -+CONFIG_SLUB_DEBUG=y -+# CONFIG_SLAB is not set -+CONFIG_SLUB=y -+# CONFIG_SLOB is not set -+CONFIG_RT_MUTEXES=y -+# CONFIG_TINY_SHMEM is not set -+CONFIG_BASE_SMALL=0 -+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 -+CONFIG_BLOCK=y -+CONFIG_LBD=y -+# CONFIG_BLK_DEV_IO_TRACE is not set -+# CONFIG_LSF is not set -+# CONFIG_BLK_DEV_BSG is not set -+ -+# -+# IO Schedulers -+# -+CONFIG_IOSCHED_NOOP=y -+CONFIG_IOSCHED_AS=y -+CONFIG_IOSCHED_DEADLINE=y -+CONFIG_IOSCHED_CFQ=y -+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" -+# CONFIG_PPC4xx_PCI_EXPRESS is not set -+ -+# -+# Platform support -+# -+# CONFIG_PPC_MPC52xx is not set -+# CONFIG_PPC_MPC5200 is not set -+# CONFIG_PPC_CELL is not set -+# CONFIG_PPC_CELL_NATIVE is not set -+# CONFIG_PQ2ADS is not set -+CONFIG_EP405=y -+# CONFIG_KILAUEA is not set -+# CONFIG_MAKALU is not set -+# CONFIG_WALNUT is not set -+# CONFIG_XILINX_VIRTEX_GENERIC_BOARD is not set -+CONFIG_405GP=y -+CONFIG_IBM405_ERR77=y -+CONFIG_IBM405_ERR51=y -+# CONFIG_MPIC is not set -+# CONFIG_MPIC_WEIRD is not set -+# CONFIG_PPC_I8259 is not set -+# CONFIG_PPC_RTAS is not set -+# CONFIG_MMIO_NVRAM is not set -+# CONFIG_PPC_MPC106 is not set -+# CONFIG_PPC_970_NAP is not set -+# CONFIG_PPC_INDIRECT_IO is not set -+# CONFIG_GENERIC_IOMAP is not set -+# CONFIG_CPU_FREQ is not set -+# CONFIG_CPM2 is not set -+# CONFIG_FSL_ULI1575 is not set -+ -+# -+# Kernel options -+# -+# CONFIG_HIGHMEM is not set -+# CONFIG_TICK_ONESHOT is not set -+# CONFIG_NO_HZ is not set -+# CONFIG_HIGH_RES_TIMERS is not set -+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y -+# CONFIG_HZ_100 is not set -+CONFIG_HZ_250=y -+# CONFIG_HZ_300 is not set -+# CONFIG_HZ_1000 is not set -+CONFIG_HZ=250 -+CONFIG_PREEMPT_NONE=y -+# CONFIG_PREEMPT_VOLUNTARY is not set -+# CONFIG_PREEMPT is not set -+CONFIG_BINFMT_ELF=y -+# CONFIG_BINFMT_MISC is not set -+# CONFIG_MATH_EMULATION is not set -+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y -+CONFIG_ARCH_FLATMEM_ENABLE=y -+CONFIG_ARCH_POPULATES_NODE_MAP=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 is not set -+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set -+CONFIG_SPLIT_PTLOCK_CPUS=4 -+# CONFIG_RESOURCES_64BIT is not set -+CONFIG_ZONE_DMA_FLAG=1 -+CONFIG_BOUNCE=y -+CONFIG_VIRT_TO_BUS=y -+CONFIG_PROC_DEVICETREE=y -+# CONFIG_CMDLINE_BOOL is not set -+# CONFIG_PM is not set -+CONFIG_SUSPEND_UP_POSSIBLE=y -+CONFIG_HIBERNATION_UP_POSSIBLE=y -+CONFIG_SECCOMP=y -+CONFIG_WANT_DEVICE_TREE=y -+CONFIG_DEVICE_TREE="ep405.dts" -+CONFIG_ISA_DMA_API=y -+ -+# -+# Bus options -+# -+CONFIG_ZONE_DMA=y -+CONFIG_PPC_INDIRECT_PCI=y -+CONFIG_PCI=y -+CONFIG_PCI_DOMAINS=y -+CONFIG_PCI_SYSCALL=y -+# CONFIG_PCIEPORTBUS is not set -+CONFIG_ARCH_SUPPORTS_MSI=y -+# CONFIG_PCI_MSI is not set -+CONFIG_PCI_LEGACY=y -+# CONFIG_PCI_DEBUG is not set -+# CONFIG_PCCARD is not set -+# CONFIG_HOTPLUG_PCI is not set -+ -+# -+# Advanced setup -+# -+# CONFIG_ADVANCED_OPTIONS is not set -+ -+# -+# Default settings for advanced configuration options are used -+# -+CONFIG_HIGHMEM_START=0xfe000000 -+CONFIG_LOWMEM_SIZE=0x30000000 -+CONFIG_KERNEL_START=0xc0000000 -+CONFIG_TASK_SIZE=0xc0000000 -+CONFIG_CONSISTENT_START=0xff100000 -+CONFIG_CONSISTENT_SIZE=0x00200000 -+CONFIG_BOOT_LOAD=0x00400000 -+ -+# -+# Networking -+# -+CONFIG_NET=y -+ -+# -+# Networking options -+# -+CONFIG_PACKET=y -+# CONFIG_PACKET_MMAP is not set -+CONFIG_UNIX=y -+# CONFIG_NET_KEY is not set -+CONFIG_INET=y -+# CONFIG_IP_MULTICAST is not set -+# 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_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 is not set -+# CONFIG_INET_XFRM_MODE_TUNNEL is not set -+# CONFIG_INET_XFRM_MODE_BEET is not set -+# CONFIG_INET_LRO is not set -+CONFIG_INET_DIAG=y -+CONFIG_INET_TCP_DIAG=y -+# CONFIG_TCP_CONG_ADVANCED is not set -+CONFIG_TCP_CONG_CUBIC=y -+CONFIG_DEFAULT_TCP_CONG="cubic" -+# CONFIG_TCP_MD5SIG is not set -+# 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 -+# CONFIG_IP_DCCP is not set -+# CONFIG_IP_SCTP is not set -+# 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_ECONET is not set -+# CONFIG_WAN_ROUTER is not set -+# 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_AF_RXRPC is not set -+ -+# -+# Wireless -+# -+# CONFIG_CFG80211 is not set -+# CONFIG_WIRELESS_EXT is not set -+# CONFIG_MAC80211 is not set -+# CONFIG_IEEE80211 is not set -+# CONFIG_RFKILL is not set -+# CONFIG_NET_9P is not set -+ -+# -+# Device Drivers -+# -+ -+# -+# Generic Driver Options -+# -+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -+CONFIG_STANDALONE=y -+CONFIG_PREVENT_FIRMWARE_BUILD=y -+CONFIG_FW_LOADER=y -+# CONFIG_DEBUG_DRIVER is not set -+# CONFIG_DEBUG_DEVRES is not set -+# CONFIG_SYS_HYPERVISOR is not set -+CONFIG_CONNECTOR=y -+CONFIG_PROC_EVENTS=y -+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 -+ -+# -+# User Modules And Translation Layers -+# -+CONFIG_MTD_CHAR=y -+CONFIG_MTD_BLKDEVS=m -+CONFIG_MTD_BLOCK=m -+# 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 -+# CONFIG_SSFDC is not set -+# CONFIG_MTD_OOPS is not set -+ -+# -+# RAM/ROM/Flash chip drivers -+# -+CONFIG_MTD_CFI=y -+CONFIG_MTD_JEDECPROBE=y -+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 is not set -+CONFIG_MTD_CFI_AMDSTD=y -+# 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 -+ -+# -+# Mapping drivers for chip access -+# -+# CONFIG_MTD_COMPLEX_MAPPINGS is not set -+# CONFIG_MTD_PHYSMAP is not set -+CONFIG_MTD_PHYSMAP_OF=y -+# CONFIG_MTD_INTEL_VR_NOR is not set -+# CONFIG_MTD_PLATRAM is not set -+ -+# -+# Self-contained MTD device drivers -+# -+# CONFIG_MTD_PMC551 is not set -+# 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 -+# CONFIG_MTD_NAND is not set -+# CONFIG_MTD_ONENAND is not set -+ -+# -+# UBI - Unsorted block images -+# -+# CONFIG_MTD_UBI is not set -+CONFIG_OF_DEVICE=y -+# CONFIG_PARPORT is not set -+CONFIG_BLK_DEV=y -+# 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 is not set -+# CONFIG_BLK_DEV_NBD is not set -+# CONFIG_BLK_DEV_SX8 is not set -+# CONFIG_BLK_DEV_UB is not set -+CONFIG_BLK_DEV_RAM=y -+CONFIG_BLK_DEV_RAM_COUNT=16 -+CONFIG_BLK_DEV_RAM_SIZE=35000 -+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 -+# CONFIG_CDROM_PKTCDVD is not set -+# CONFIG_ATA_OVER_ETH is not set -+# CONFIG_XILINX_SYSACE is not set -+CONFIG_MISC_DEVICES=y -+# CONFIG_PHANTOM is not set -+# CONFIG_EEPROM_93CX6 is not set -+# CONFIG_SGI_IOC4 is not set -+# CONFIG_TIFM_CORE is not set -+# CONFIG_IDE is not set -+ -+# -+# SCSI device support -+# -+# CONFIG_RAID_ATTRS is not set -+# CONFIG_SCSI is not set -+# CONFIG_SCSI_DMA is not set -+# CONFIG_SCSI_NETLINK is not set -+# CONFIG_ATA is not set -+# CONFIG_MD is not set -+# CONFIG_FUSION is not set -+ -+# -+# IEEE 1394 (FireWire) support -+# -+# CONFIG_FIREWIRE is not set -+# CONFIG_IEEE1394 is not set -+# CONFIG_I2O is not set -+# CONFIG_MACINTOSH_DRIVERS is not set -+CONFIG_NETDEVICES=y -+# CONFIG_NETDEVICES_MULTIQUEUE is not set -+# CONFIG_DUMMY is not set -+# CONFIG_BONDING is not set -+# CONFIG_MACVLAN is not set -+# CONFIG_EQUALIZER is not set -+# CONFIG_TUN is not set -+# CONFIG_VETH is not set -+# CONFIG_IP1000 is not set -+# CONFIG_ARCNET is not set -+# CONFIG_PHYLIB is not set -+CONFIG_NET_ETHERNET=y -+# CONFIG_MII is not set -+# CONFIG_HAPPYMEAL is not set -+# CONFIG_SUNGEM is not set -+# CONFIG_CASSINI is not set -+# CONFIG_NET_VENDOR_3COM is not set -+# CONFIG_NET_TULIP is not set -+# CONFIG_HP100 is not set -+CONFIG_IBM_NEW_EMAC=y -+CONFIG_IBM_NEW_EMAC_RXB=128 -+CONFIG_IBM_NEW_EMAC_TXB=64 -+CONFIG_IBM_NEW_EMAC_POLL_WEIGHT=32 -+CONFIG_IBM_NEW_EMAC_RX_COPY_THRESHOLD=256 -+CONFIG_IBM_NEW_EMAC_RX_SKB_HEADROOM=0 -+# CONFIG_IBM_NEW_EMAC_DEBUG is not set -+CONFIG_IBM_NEW_EMAC_ZMII=y -+# CONFIG_IBM_NEW_EMAC_RGMII is not set -+# CONFIG_IBM_NEW_EMAC_TAH is not set -+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set -+# CONFIG_NET_PCI is not set -+# CONFIG_B44 is not set -+CONFIG_NETDEV_1000=y -+# CONFIG_ACENIC is not set -+# CONFIG_DL2K is not set -+# CONFIG_E1000 is not set -+# CONFIG_E1000E 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 -+# CONFIG_QLA3XXX is not set -+# CONFIG_ATL1 is not set -+CONFIG_NETDEV_10000=y -+# CONFIG_CHELSIO_T1 is not set -+# CONFIG_CHELSIO_T3 is not set -+# CONFIG_IXGBE is not set -+# CONFIG_IXGB is not set -+# CONFIG_S2IO is not set -+# CONFIG_MYRI10GE is not set -+# CONFIG_NETXEN_NIC is not set -+# CONFIG_NIU is not set -+# CONFIG_MLX4_CORE is not set -+# CONFIG_TEHUTI is not set -+# CONFIG_TR is not set -+ -+# -+# Wireless LAN -+# -+# CONFIG_WLAN_PRE80211 is not set -+# CONFIG_WLAN_80211 is not set -+ -+# -+# USB Network Adapters -+# -+# CONFIG_USB_CATC is not set -+# CONFIG_USB_KAWETH is not set -+# CONFIG_USB_PEGASUS is not set -+# CONFIG_USB_RTL8150 is not set -+# CONFIG_USB_USBNET is not set -+# CONFIG_WAN is not set -+# CONFIG_FDDI is not set -+# CONFIG_HIPPI 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 -+# CONFIG_ISDN is not set -+# CONFIG_PHONE is not set -+ -+# -+# Input device support -+# -+# CONFIG_INPUT is not set -+ -+# -+# Hardware I/O ports -+# -+# CONFIG_SERIO is not set -+# CONFIG_GAMEPORT is not set -+ -+# -+# Character devices -+# -+# CONFIG_VT is not set -+# 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 is not set -+CONFIG_SERIAL_8250_SHARE_IRQ=y -+# CONFIG_SERIAL_8250_DETECT_IRQ is not set -+# CONFIG_SERIAL_8250_RSA is not set -+ -+# -+# Non-8250 serial port support -+# -+# CONFIG_SERIAL_UARTLITE is not set -+CONFIG_SERIAL_CORE=y -+CONFIG_SERIAL_CORE_CONSOLE=y -+# CONFIG_SERIAL_JSM is not set -+CONFIG_SERIAL_OF_PLATFORM=y -+CONFIG_UNIX98_PTYS=y -+CONFIG_LEGACY_PTYS=y -+CONFIG_LEGACY_PTY_COUNT=256 -+# CONFIG_IPMI_HANDLER is not set -+# CONFIG_HW_RANDOM is not set -+# CONFIG_NVRAM is not set -+# CONFIG_GEN_RTC is not set -+# CONFIG_R3964 is not set -+# CONFIG_APPLICOM is not set -+# CONFIG_RAW_DRIVER is not set -+# CONFIG_TCG_TPM is not set -+CONFIG_DEVPORT=y -+# CONFIG_I2C is not set -+ -+# -+# SPI support -+# -+# CONFIG_SPI is not set -+# CONFIG_SPI_MASTER is not set -+# CONFIG_W1 is not set -+# CONFIG_POWER_SUPPLY is not set -+# CONFIG_HWMON is not set -+# CONFIG_WATCHDOG is not set -+ -+# -+# Sonics Silicon Backplane -+# -+CONFIG_SSB_POSSIBLE=y -+# CONFIG_SSB is not set -+ -+# -+# Multifunction device drivers -+# -+# CONFIG_MFD_SM501 is not set -+ -+# -+# Multimedia devices -+# -+# CONFIG_VIDEO_DEV is not set -+# CONFIG_DVB_CORE is not set -+# CONFIG_DAB is not set -+ -+# -+# Graphics support -+# -+# CONFIG_AGP is not set -+# CONFIG_DRM is not set -+# CONFIG_VGASTATE is not set -+CONFIG_VIDEO_OUTPUT_CONTROL=m -+# CONFIG_FB is not set -+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set -+ -+# -+# Display device support -+# -+# CONFIG_DISPLAY_SUPPORT is not set -+ -+# -+# Sound -+# -+# CONFIG_SOUND is not set -+CONFIG_USB_SUPPORT=y -+CONFIG_USB_ARCH_HAS_HCD=y -+CONFIG_USB_ARCH_HAS_OHCI=y -+CONFIG_USB_ARCH_HAS_EHCI=y -+CONFIG_USB=y -+# CONFIG_USB_DEBUG is not set -+ -+# -+# Miscellaneous USB options -+# -+CONFIG_USB_DEVICEFS=y -+CONFIG_USB_DEVICE_CLASS=y -+# CONFIG_USB_DYNAMIC_MINORS is not set -+# CONFIG_USB_OTG is not set -+ -+# -+# USB Host Controller Drivers -+# -+# CONFIG_USB_EHCI_HCD is not set -+# CONFIG_USB_ISP116X_HCD is not set -+CONFIG_USB_OHCI_HCD=y -+CONFIG_USB_OHCI_HCD_PPC_OF=y -+CONFIG_USB_OHCI_HCD_PPC_OF_BE=y -+CONFIG_USB_OHCI_HCD_PPC_OF_LE=y -+CONFIG_USB_OHCI_HCD_PCI=y -+CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y -+CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y -+CONFIG_USB_OHCI_LITTLE_ENDIAN=y -+# CONFIG_USB_UHCI_HCD is not set -+# CONFIG_USB_SL811_HCD is not set -+# CONFIG_USB_R8A66597_HCD is not set -+ -+# -+# USB Device Class drivers -+# -+# CONFIG_USB_ACM is not set -+# CONFIG_USB_PRINTER is not set -+ -+# -+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -+# -+ -+# -+# may also be needed; see USB_STORAGE Help for more information -+# -+# CONFIG_USB_LIBUSUAL is not set -+ -+# -+# USB Imaging devices -+# -+# CONFIG_USB_MDC800 is not set -+CONFIG_USB_MON=y -+ -+# -+# USB port drivers -+# -+ -+# -+# USB Serial Converter support -+# -+# CONFIG_USB_SERIAL is not set -+ -+# -+# USB Miscellaneous drivers -+# -+# CONFIG_USB_EMI62 is not set -+# CONFIG_USB_EMI26 is not set -+# CONFIG_USB_ADUTUX is not set -+# CONFIG_USB_AUERSWALD is not set -+# CONFIG_USB_RIO500 is not set -+# CONFIG_USB_LEGOTOWER is not set -+# CONFIG_USB_LCD is not set -+# CONFIG_USB_BERRY_CHARGE is not set -+# CONFIG_USB_LED is not set -+# CONFIG_USB_CYPRESS_CY7C63 is not set -+# CONFIG_USB_CYTHERM is not set -+# CONFIG_USB_PHIDGET is not set -+# CONFIG_USB_IDMOUSE is not set -+# CONFIG_USB_FTDI_ELAN is not set -+# CONFIG_USB_APPLEDISPLAY is not set -+# CONFIG_USB_LD is not set -+# CONFIG_USB_TRANCEVIBRATOR is not set -+# CONFIG_USB_IOWARRIOR is not set -+# CONFIG_USB_TEST is not set -+ -+# -+# USB DSL modem support -+# -+ -+# -+# USB Gadget Support -+# -+# CONFIG_USB_GADGET is not set -+# CONFIG_MMC is not set -+# CONFIG_NEW_LEDS is not set -+# CONFIG_INFINIBAND is not set -+# CONFIG_EDAC is not set -+# CONFIG_RTC_CLASS is not set -+ -+# -+# Userspace I/O -+# -+# CONFIG_UIO 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_EXT4DEV_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_GFS2_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 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_MSDOS_FS is not set -+# CONFIG_VFAT_FS is not set -+# CONFIG_NTFS_FS is not set -+ -+# -+# Pseudo filesystems -+# -+CONFIG_PROC_FS=y -+CONFIG_PROC_KCORE=y -+CONFIG_PROC_SYSCTL=y -+CONFIG_SYSFS=y -+CONFIG_TMPFS=y -+# CONFIG_TMPFS_POSIX_ACL is not set -+# CONFIG_HUGETLB_PAGE 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_JFFS2_FS is not set -+CONFIG_CRAMFS=y -+# 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 -+CONFIG_NETWORK_FILESYSTEMS=y -+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_SUNRPC_BIND34 is not set -+# 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 -+ -+# -+# Partition Types -+# -+# CONFIG_PARTITION_ADVANCED is not set -+CONFIG_MSDOS_PARTITION=y -+# CONFIG_NLS is not set -+# CONFIG_DLM is not set -+# CONFIG_UCC_SLOW is not set -+ -+# -+# Library routines -+# -+CONFIG_BITREVERSE=y -+# CONFIG_CRC_CCITT is not set -+# CONFIG_CRC16 is not set -+# CONFIG_CRC_ITU_T is not set -+CONFIG_CRC32=y -+# CONFIG_CRC7 is not set -+# CONFIG_LIBCRC32C is not set -+CONFIG_ZLIB_INFLATE=y -+CONFIG_PLIST=y -+CONFIG_HAS_IOMEM=y -+CONFIG_HAS_IOPORT=y -+CONFIG_HAS_DMA=y -+CONFIG_INSTRUMENTATION=y -+# CONFIG_PROFILING is not set -+# CONFIG_KPROBES is not set -+# CONFIG_MARKERS is not set -+ -+# -+# Kernel hacking -+# -+# CONFIG_PRINTK_TIME is not set -+CONFIG_ENABLE_WARN_DEPRECATED=y -+CONFIG_ENABLE_MUST_CHECK=y -+CONFIG_MAGIC_SYSRQ=y -+# CONFIG_UNUSED_SYMBOLS is not set -+# CONFIG_DEBUG_FS is not set -+# CONFIG_HEADERS_CHECK is not set -+CONFIG_DEBUG_KERNEL=y -+# CONFIG_DEBUG_SHIRQ is not set -+CONFIG_DETECT_SOFTLOCKUP=y -+CONFIG_SCHED_DEBUG=y -+# CONFIG_SCHEDSTATS is not set -+# CONFIG_TIMER_STATS is not set -+# CONFIG_SLUB_DEBUG_ON is not set -+# CONFIG_DEBUG_RT_MUTEXES is not set -+# CONFIG_RT_MUTEX_TESTER is not set -+# CONFIG_DEBUG_SPINLOCK is not set -+# CONFIG_DEBUG_MUTEXES is not set -+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -+# CONFIG_DEBUG_KOBJECT is not set -+CONFIG_DEBUG_BUGVERBOSE=y -+# CONFIG_DEBUG_INFO is not set -+# CONFIG_DEBUG_VM is not set -+# CONFIG_DEBUG_LIST is not set -+# CONFIG_DEBUG_SG is not set -+CONFIG_FORCED_INLINING=y -+# CONFIG_BOOT_PRINTK_DELAY is not set -+# CONFIG_RCU_TORTURE_TEST is not set -+# CONFIG_FAULT_INJECTION is not set -+# CONFIG_SAMPLES is not set -+# CONFIG_DEBUG_STACKOVERFLOW is not set -+# CONFIG_DEBUG_STACK_USAGE is not set -+# CONFIG_DEBUG_PAGEALLOC is not set -+# CONFIG_DEBUGGER is not set -+# CONFIG_BDI_SWITCH is not set -+# CONFIG_PPC_EARLY_DEBUG is not set -+ -+# -+# Security options -+# -+# CONFIG_KEYS is not set -+# CONFIG_SECURITY is not set -+# CONFIG_SECURITY_FILE_CAPABILITIES is not set -+CONFIG_CRYPTO=y -+CONFIG_CRYPTO_ALGAPI=y -+CONFIG_CRYPTO_BLKCIPHER=y -+CONFIG_CRYPTO_MANAGER=y -+# CONFIG_CRYPTO_HMAC is not set -+# CONFIG_CRYPTO_XCBC is not set -+# CONFIG_CRYPTO_NULL is not set -+# CONFIG_CRYPTO_MD4 is not set -+CONFIG_CRYPTO_MD5=y -+# CONFIG_CRYPTO_SHA1 is not set -+# 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_GF128MUL is not set -+CONFIG_CRYPTO_ECB=y -+CONFIG_CRYPTO_CBC=y -+CONFIG_CRYPTO_PCBC=y -+# CONFIG_CRYPTO_LRW is not set -+# CONFIG_CRYPTO_XTS is not set -+# CONFIG_CRYPTO_CRYPTD is not set -+CONFIG_CRYPTO_DES=y -+# CONFIG_CRYPTO_FCRYPT is not set -+# 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_SEED is not set -+# CONFIG_CRYPTO_DEFLATE is not set -+# CONFIG_CRYPTO_MICHAEL_MIC is not set -+# CONFIG_CRYPTO_CRC32C is not set -+# CONFIG_CRYPTO_CAMELLIA is not set -+# CONFIG_CRYPTO_TEST is not set -+# CONFIG_CRYPTO_AUTHENC is not set -+CONFIG_CRYPTO_HW=y -+# CONFIG_PPC_CLOCK is not set ---- /dev/null -+++ b/arch/powerpc/configs/ep8248e_defconfig -@@ -0,0 +1,821 @@ -+# -+# Automatically generated make config: don't edit -+# Linux kernel version: 2.6.24-rc6 -+# Fri Jan 11 14:02:06 2008 -+# -+# CONFIG_PPC64 is not set -+ -+# -+# Processor support -+# -+CONFIG_6xx=y -+# CONFIG_PPC_85xx is not set -+# CONFIG_PPC_8xx is not set -+# CONFIG_40x is not set -+# CONFIG_44x is not set -+# CONFIG_E200 is not set -+CONFIG_PPC_FPU=y -+CONFIG_PPC_STD_MMU=y -+CONFIG_PPC_STD_MMU_32=y -+# CONFIG_PPC_MM_SLICES is not set -+# CONFIG_SMP is not set -+CONFIG_PPC32=y -+CONFIG_WORD_SIZE=32 -+CONFIG_PPC_MERGE=y -+CONFIG_MMU=y -+CONFIG_GENERIC_CMOS_UPDATE=y -+CONFIG_GENERIC_TIME=y -+CONFIG_GENERIC_TIME_VSYSCALL=y -+CONFIG_GENERIC_CLOCKEVENTS=y -+CONFIG_GENERIC_HARDIRQS=y -+CONFIG_IRQ_PER_CPU=y -+CONFIG_RWSEM_XCHGADD_ALGORITHM=y -+CONFIG_ARCH_HAS_ILOG2_U32=y -+CONFIG_GENERIC_HWEIGHT=y -+CONFIG_GENERIC_CALIBRATE_DELAY=y -+CONFIG_GENERIC_FIND_NEXT_BIT=y -+# CONFIG_ARCH_NO_VIRT_TO_BUS is not set -+CONFIG_PPC=y -+CONFIG_EARLY_PRINTK=y -+CONFIG_GENERIC_NVRAM=y -+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -+CONFIG_ARCH_MAY_HAVE_PC_FDC=y -+CONFIG_PPC_OF=y -+CONFIG_OF=y -+# CONFIG_PPC_UDBG_16550 is not set -+# CONFIG_GENERIC_TBSYNC is not set -+CONFIG_AUDIT_ARCH=y -+CONFIG_GENERIC_BUG=y -+# CONFIG_DEFAULT_UIMAGE is not set -+# CONFIG_PPC_DCR_NATIVE is not set -+# CONFIG_PPC_DCR_MMIO is not set -+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" -+ -+# -+# General setup -+# -+# CONFIG_EXPERIMENTAL is not set -+CONFIG_BROKEN_ON_SMP=y -+CONFIG_INIT_ENV_ARG_LIMIT=32 -+CONFIG_LOCALVERSION="" -+CONFIG_LOCALVERSION_AUTO=y -+CONFIG_SWAP=y -+CONFIG_SYSVIPC=y -+CONFIG_SYSVIPC_SYSCTL=y -+# CONFIG_BSD_PROCESS_ACCT is not set -+# CONFIG_TASKSTATS is not set -+# CONFIG_AUDIT is not set -+CONFIG_IKCONFIG=y -+CONFIG_IKCONFIG_PROC=y -+CONFIG_LOG_BUF_SHIFT=14 -+# CONFIG_CGROUPS is not set -+CONFIG_FAIR_GROUP_SCHED=y -+CONFIG_FAIR_USER_SCHED=y -+# CONFIG_FAIR_CGROUP_SCHED is not set -+CONFIG_SYSFS_DEPRECATED=y -+# CONFIG_RELAY is not set -+# CONFIG_BLK_DEV_INITRD is not set -+CONFIG_SYSCTL=y -+CONFIG_EMBEDDED=y -+CONFIG_SYSCTL_SYSCALL=y -+CONFIG_KALLSYMS=y -+CONFIG_KALLSYMS_ALL=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_FUTEX=y -+CONFIG_ANON_INODES=y -+CONFIG_EPOLL=y -+CONFIG_SIGNALFD=y -+CONFIG_EVENTFD=y -+CONFIG_SHMEM=y -+CONFIG_VM_EVENT_COUNTERS=y -+CONFIG_SLAB=y -+# CONFIG_SLUB is not set -+# CONFIG_SLOB is not set -+CONFIG_RT_MUTEXES=y -+# CONFIG_TINY_SHMEM is not set -+CONFIG_BASE_SMALL=0 -+# CONFIG_MODULES is not set -+CONFIG_BLOCK=y -+# 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 is not set -+CONFIG_IOSCHED_DEADLINE=y -+# CONFIG_IOSCHED_CFQ is not set -+# CONFIG_DEFAULT_AS is not set -+CONFIG_DEFAULT_DEADLINE=y -+# CONFIG_DEFAULT_CFQ is not set -+# CONFIG_DEFAULT_NOOP is not set -+CONFIG_DEFAULT_IOSCHED="deadline" -+ -+# -+# Platform support -+# -+# CONFIG_PPC_MULTIPLATFORM is not set -+CONFIG_PPC_82xx=y -+# CONFIG_PPC_83xx is not set -+# CONFIG_PPC_86xx is not set -+# CONFIG_PPC_MPC52xx is not set -+# CONFIG_PPC_MPC5200 is not set -+# CONFIG_PPC_CELL is not set -+# CONFIG_PPC_CELL_NATIVE is not set -+# CONFIG_MPC8272_ADS is not set -+# CONFIG_PQ2FADS is not set -+CONFIG_EP8248E=y -+# CONFIG_PQ2ADS is not set -+CONFIG_8260=y -+CONFIG_8272=y -+# CONFIG_MPIC is not set -+# CONFIG_MPIC_WEIRD is not set -+# CONFIG_PPC_I8259 is not set -+# CONFIG_PPC_RTAS is not set -+# CONFIG_MMIO_NVRAM is not set -+# CONFIG_PPC_MPC106 is not set -+# CONFIG_PPC_970_NAP is not set -+# CONFIG_PPC_INDIRECT_IO is not set -+# CONFIG_GENERIC_IOMAP is not set -+# CONFIG_CPU_FREQ is not set -+CONFIG_CPM2=y -+CONFIG_PPC_CPM_NEW_BINDING=y -+# CONFIG_FSL_ULI1575 is not set -+CONFIG_CPM=y -+ -+# -+# Kernel options -+# -+# CONFIG_HIGHMEM is not set -+# CONFIG_TICK_ONESHOT is not set -+# CONFIG_NO_HZ is not set -+# CONFIG_HIGH_RES_TIMERS is not set -+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y -+# CONFIG_HZ_100 is not set -+CONFIG_HZ_250=y -+# CONFIG_HZ_300 is not set -+# CONFIG_HZ_1000 is not set -+CONFIG_HZ=250 -+CONFIG_PREEMPT_NONE=y -+# CONFIG_PREEMPT_VOLUNTARY is not set -+# CONFIG_PREEMPT is not set -+CONFIG_BINFMT_ELF=y -+CONFIG_BINFMT_MISC=y -+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y -+CONFIG_ARCH_FLATMEM_ENABLE=y -+CONFIG_ARCH_POPULATES_NODE_MAP=y -+CONFIG_FLATMEM=y -+CONFIG_FLAT_NODE_MEM_MAP=y -+# CONFIG_SPARSEMEM_STATIC is not set -+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set -+CONFIG_SPLIT_PTLOCK_CPUS=4 -+# CONFIG_RESOURCES_64BIT is not set -+CONFIG_ZONE_DMA_FLAG=1 -+CONFIG_BOUNCE=y -+CONFIG_VIRT_TO_BUS=y -+CONFIG_PROC_DEVICETREE=y -+# CONFIG_CMDLINE_BOOL is not set -+# CONFIG_PM is not set -+CONFIG_SUSPEND_UP_POSSIBLE=y -+CONFIG_HIBERNATION_UP_POSSIBLE=y -+# CONFIG_SECCOMP is not set -+CONFIG_WANT_DEVICE_TREE=y -+CONFIG_DEVICE_TREE="ep8248e.dts" -+CONFIG_ISA_DMA_API=y -+ -+# -+# Bus options -+# -+CONFIG_ZONE_DMA=y -+CONFIG_FSL_SOC=y -+# CONFIG_PCI is not set -+# CONFIG_PCI_DOMAINS is not set -+# CONFIG_PCI_SYSCALL is not set -+# CONFIG_ARCH_SUPPORTS_MSI is not set -+# CONFIG_PCCARD is not set -+ -+# -+# Advanced setup -+# -+# CONFIG_ADVANCED_OPTIONS is not set -+ -+# -+# Default settings for advanced configuration options are used -+# -+CONFIG_HIGHMEM_START=0xfe000000 -+CONFIG_LOWMEM_SIZE=0x30000000 -+CONFIG_KERNEL_START=0xc0000000 -+CONFIG_TASK_SIZE=0xc0000000 -+CONFIG_BOOT_LOAD=0x00400000 -+ -+# -+# Networking -+# -+CONFIG_NET=y -+ -+# -+# Networking options -+# -+CONFIG_PACKET=y -+# 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_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=y -+CONFIG_INET_XFRM_MODE_TRANSPORT=y -+CONFIG_INET_XFRM_MODE_TUNNEL=y -+CONFIG_INET_XFRM_MODE_BEET=y -+# CONFIG_INET_LRO is not set -+CONFIG_INET_DIAG=y -+CONFIG_INET_TCP_DIAG=y -+# CONFIG_TCP_CONG_ADVANCED is not set -+CONFIG_TCP_CONG_CUBIC=y -+CONFIG_DEFAULT_TCP_CONG="cubic" -+# CONFIG_IP_VS is not set -+CONFIG_IPV6=y -+# CONFIG_IPV6_PRIVACY is not set -+# CONFIG_IPV6_ROUTER_PREF is not set -+# CONFIG_INET6_AH is not set -+# CONFIG_INET6_ESP is not set -+# CONFIG_INET6_IPCOMP is not set -+# CONFIG_INET6_XFRM_TUNNEL is not set -+# CONFIG_INET6_TUNNEL is not set -+CONFIG_INET6_XFRM_MODE_TRANSPORT=y -+CONFIG_INET6_XFRM_MODE_TUNNEL=y -+CONFIG_INET6_XFRM_MODE_BEET=y -+CONFIG_IPV6_SIT=y -+# CONFIG_IPV6_TUNNEL is not set -+# CONFIG_NETWORK_SECMARK is not set -+CONFIG_NETFILTER=y -+# CONFIG_NETFILTER_DEBUG is not set -+ -+# -+# Core Netfilter Configuration -+# -+# CONFIG_NETFILTER_NETLINK is not set -+# CONFIG_NF_CONNTRACK_ENABLED is not set -+# CONFIG_NF_CONNTRACK is not set -+# CONFIG_NETFILTER_XTABLES is not set -+ -+# -+# IP: Netfilter Configuration -+# -+# CONFIG_IP_NF_QUEUE is not set -+# CONFIG_IP_NF_IPTABLES is not set -+# CONFIG_IP_NF_ARPTABLES 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_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 -+ -+# -+# Wireless -+# -+# CONFIG_CFG80211 is not set -+# CONFIG_WIRELESS_EXT is not set -+# CONFIG_IEEE80211 is not set -+# CONFIG_RFKILL is not set -+ -+# -+# Device Drivers -+# -+ -+# -+# Generic Driver Options -+# -+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -+CONFIG_STANDALONE=y -+CONFIG_PREVENT_FIRMWARE_BUILD=y -+# CONFIG_FW_LOADER is not set -+# CONFIG_DEBUG_DRIVER is not set -+# CONFIG_DEBUG_DEVRES is not set -+# CONFIG_SYS_HYPERVISOR is not set -+# CONFIG_CONNECTOR is not set -+CONFIG_MTD=y -+# CONFIG_MTD_DEBUG is not set -+# CONFIG_MTD_CONCAT is not set -+# CONFIG_MTD_PARTITIONS is not set -+ -+# -+# User Modules And Translation Layers -+# -+CONFIG_MTD_CHAR=y -+CONFIG_MTD_BLKDEVS=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 -+# CONFIG_SSFDC is not set -+# CONFIG_MTD_OOPS 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 is not set -+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 is not set -+CONFIG_MTD_CFI_I2=y -+# CONFIG_MTD_CFI_I4 is not set -+# CONFIG_MTD_CFI_I8 is not set -+# CONFIG_MTD_OTP is not set -+# CONFIG_MTD_CFI_INTELEXT is not set -+CONFIG_MTD_CFI_AMDSTD=y -+# 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 -+ -+# -+# Mapping drivers for chip access -+# -+# CONFIG_MTD_COMPLEX_MAPPINGS is not set -+# CONFIG_MTD_PHYSMAP is not set -+CONFIG_MTD_PHYSMAP_OF=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 -+# CONFIG_MTD_NAND is not set -+# CONFIG_MTD_ONENAND is not set -+ -+# -+# UBI - Unsorted block images -+# -+# CONFIG_MTD_UBI is not set -+CONFIG_OF_DEVICE=y -+# CONFIG_PARPORT is not set -+CONFIG_BLK_DEV=y -+# CONFIG_BLK_DEV_FD is not set -+# 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 is not set -+# CONFIG_CDROM_PKTCDVD is not set -+# CONFIG_ATA_OVER_ETH is not set -+# CONFIG_MISC_DEVICES is not set -+# CONFIG_IDE is not set -+ -+# -+# SCSI device support -+# -+# CONFIG_RAID_ATTRS is not set -+# CONFIG_SCSI is not set -+# CONFIG_SCSI_DMA is not set -+# CONFIG_SCSI_NETLINK is not set -+# CONFIG_ATA is not set -+# CONFIG_MD is not set -+# CONFIG_MACINTOSH_DRIVERS is not set -+CONFIG_NETDEVICES=y -+# CONFIG_NETDEVICES_MULTIQUEUE is not set -+# CONFIG_DUMMY is not set -+# CONFIG_BONDING is not set -+# CONFIG_EQUALIZER is not set -+# CONFIG_TUN is not set -+# CONFIG_VETH is not set -+CONFIG_PHYLIB=y -+ -+# -+# MII PHY device drivers -+# -+# CONFIG_MARVELL_PHY is not set -+CONFIG_DAVICOM_PHY=y -+# CONFIG_QSEMI_PHY is not set -+# CONFIG_LXT_PHY is not set -+# CONFIG_CICADA_PHY is not set -+# CONFIG_VITESSE_PHY is not set -+# CONFIG_SMSC_PHY is not set -+# CONFIG_BROADCOM_PHY is not set -+# CONFIG_ICPLUS_PHY is not set -+# CONFIG_FIXED_PHY is not set -+CONFIG_MDIO_BITBANG=y -+CONFIG_NET_ETHERNET=y -+CONFIG_MII=y -+# CONFIG_IBM_NEW_EMAC_ZMII is not set -+# CONFIG_IBM_NEW_EMAC_RGMII is not set -+# CONFIG_IBM_NEW_EMAC_TAH is not set -+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set -+# CONFIG_B44 is not set -+CONFIG_FS_ENET=y -+# CONFIG_FS_ENET_HAS_SCC is not set -+CONFIG_FS_ENET_HAS_FCC=y -+# CONFIG_FS_ENET_MDIO_FCC is not set -+CONFIG_NETDEV_1000=y -+CONFIG_NETDEV_10000=y -+ -+# -+# Wireless LAN -+# -+# CONFIG_WLAN_PRE80211 is not set -+# CONFIG_WLAN_80211 is not set -+# CONFIG_WAN is not set -+# CONFIG_PPP is not set -+# CONFIG_SLIP is not set -+# CONFIG_NETPOLL is not set -+# CONFIG_NET_POLL_CONTROLLER is not set -+# CONFIG_ISDN is not set -+# CONFIG_PHONE is not set -+ -+# -+# Input device support -+# -+# CONFIG_INPUT is not set -+ -+# -+# Hardware I/O ports -+# -+# CONFIG_SERIO is not set -+# CONFIG_GAMEPORT is not set -+ -+# -+# Character devices -+# -+# CONFIG_VT is not set -+# CONFIG_SERIAL_NONSTANDARD is not set -+ -+# -+# Serial drivers -+# -+# CONFIG_SERIAL_8250 is not set -+ -+# -+# Non-8250 serial port support -+# -+# CONFIG_SERIAL_UARTLITE is not set -+CONFIG_SERIAL_CORE=y -+CONFIG_SERIAL_CORE_CONSOLE=y -+CONFIG_SERIAL_CPM=y -+CONFIG_SERIAL_CPM_CONSOLE=y -+CONFIG_SERIAL_CPM_SCC1=y -+# CONFIG_SERIAL_CPM_SCC2 is not set -+# CONFIG_SERIAL_CPM_SCC3 is not set -+CONFIG_SERIAL_CPM_SCC4=y -+# CONFIG_SERIAL_CPM_SMC1 is not set -+# CONFIG_SERIAL_CPM_SMC2 is not set -+CONFIG_UNIX98_PTYS=y -+CONFIG_LEGACY_PTYS=y -+CONFIG_LEGACY_PTY_COUNT=256 -+# CONFIG_IPMI_HANDLER is not set -+CONFIG_HW_RANDOM=y -+# CONFIG_NVRAM is not set -+# CONFIG_GEN_RTC is not set -+# CONFIG_R3964 is not set -+# CONFIG_RAW_DRIVER is not set -+# CONFIG_I2C is not set -+ -+# -+# SPI support -+# -+# CONFIG_SPI is not set -+# CONFIG_SPI_MASTER is not set -+# CONFIG_W1 is not set -+# CONFIG_POWER_SUPPLY is not set -+# CONFIG_HWMON is not set -+# CONFIG_WATCHDOG is not set -+ -+# -+# Sonics Silicon Backplane -+# -+CONFIG_SSB_POSSIBLE=y -+# CONFIG_SSB is not set -+ -+# -+# Multifunction device drivers -+# -+# CONFIG_MFD_SM501 is not set -+ -+# -+# Multimedia devices -+# -+# CONFIG_VIDEO_DEV is not set -+# CONFIG_DVB_CORE is not set -+CONFIG_DAB=y -+ -+# -+# Graphics support -+# -+# CONFIG_VGASTATE is not set -+# CONFIG_VIDEO_OUTPUT_CONTROL is not set -+# CONFIG_FB is not set -+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set -+ -+# -+# Display device support -+# -+# CONFIG_DISPLAY_SUPPORT is not set -+ -+# -+# Sound -+# -+# CONFIG_SOUND is not set -+# CONFIG_USB_SUPPORT is not set -+# CONFIG_MMC is not set -+# CONFIG_NEW_LEDS is not set -+# CONFIG_RTC_CLASS is not set -+ -+# -+# Userspace I/O -+# -+# CONFIG_UIO 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=y -+# CONFIG_EXT3_FS_XATTR is not set -+CONFIG_JBD=y -+# 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 is not set -+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_MSDOS_FS is not set -+# CONFIG_VFAT_FS is not set -+# CONFIG_NTFS_FS is not set -+ -+# -+# Pseudo filesystems -+# -+CONFIG_PROC_FS=y -+CONFIG_PROC_KCORE=y -+CONFIG_PROC_SYSCTL=y -+CONFIG_SYSFS=y -+CONFIG_TMPFS=y -+# CONFIG_TMPFS_POSIX_ACL is not set -+# CONFIG_HUGETLB_PAGE is not set -+ -+# -+# Miscellaneous filesystems -+# -+# CONFIG_HFSPLUS_FS is not set -+# CONFIG_JFFS2_FS is not set -+CONFIG_CRAMFS=y -+# 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 -+CONFIG_NETWORK_FILESYSTEMS=y -+CONFIG_NFS_FS=y -+CONFIG_NFS_V3=y -+# CONFIG_NFS_V3_ACL 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_SMB_FS is not set -+# CONFIG_CIFS is not set -+# CONFIG_NCP_FS is not set -+# CONFIG_CODA_FS is not set -+ -+# -+# Partition Types -+# -+CONFIG_PARTITION_ADVANCED=y -+# CONFIG_ACORN_PARTITION is not set -+# CONFIG_OSF_PARTITION is not set -+# CONFIG_AMIGA_PARTITION is not set -+# CONFIG_ATARI_PARTITION is not set -+# CONFIG_MAC_PARTITION is not set -+CONFIG_MSDOS_PARTITION=y -+# CONFIG_BSD_DISKLABEL is not set -+# CONFIG_MINIX_SUBPARTITION is not set -+# CONFIG_SOLARIS_X86_PARTITION is not set -+# CONFIG_UNIXWARE_DISKLABEL is not set -+# CONFIG_LDM_PARTITION is not set -+# CONFIG_SGI_PARTITION is not set -+# CONFIG_ULTRIX_PARTITION is not set -+# CONFIG_SUN_PARTITION is not set -+# CONFIG_KARMA_PARTITION is not set -+# CONFIG_EFI_PARTITION is not set -+# CONFIG_SYSV68_PARTITION is not set -+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 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=y -+CONFIG_NLS_ISO8859_1=y -+# 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=y -+# CONFIG_UCC_SLOW is not set -+ -+# -+# Library routines -+# -+# CONFIG_CRC_CCITT is not set -+# CONFIG_CRC16 is not set -+# CONFIG_CRC_ITU_T is not set -+# CONFIG_CRC32 is not set -+# CONFIG_CRC7 is not set -+# CONFIG_LIBCRC32C is not set -+CONFIG_ZLIB_INFLATE=y -+CONFIG_PLIST=y -+CONFIG_HAS_IOMEM=y -+CONFIG_HAS_IOPORT=y -+CONFIG_HAS_DMA=y -+CONFIG_INSTRUMENTATION=y -+# CONFIG_PROFILING is not set -+# CONFIG_MARKERS is not set -+ -+# -+# Kernel hacking -+# -+# CONFIG_PRINTK_TIME is not set -+CONFIG_ENABLE_WARN_DEPRECATED=y -+CONFIG_ENABLE_MUST_CHECK=y -+CONFIG_MAGIC_SYSRQ=y -+# CONFIG_UNUSED_SYMBOLS is not set -+# CONFIG_DEBUG_FS is not set -+# CONFIG_HEADERS_CHECK is not set -+CONFIG_DEBUG_KERNEL=y -+# CONFIG_DEBUG_SHIRQ is not set -+# CONFIG_DETECT_SOFTLOCKUP is not set -+# CONFIG_SCHED_DEBUG is not set -+# CONFIG_SCHEDSTATS is not set -+# CONFIG_TIMER_STATS is not set -+# CONFIG_DEBUG_SLAB is not set -+# CONFIG_DEBUG_RT_MUTEXES is not set -+# CONFIG_RT_MUTEX_TESTER is not set -+# CONFIG_DEBUG_SPINLOCK is not set -+# CONFIG_DEBUG_MUTEXES is not set -+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -+# CONFIG_DEBUG_KOBJECT is not set -+CONFIG_DEBUG_BUGVERBOSE=y -+CONFIG_DEBUG_INFO=y -+# CONFIG_DEBUG_VM is not set -+# CONFIG_DEBUG_LIST is not set -+# CONFIG_DEBUG_SG is not set -+CONFIG_FORCED_INLINING=y -+# CONFIG_BOOT_PRINTK_DELAY is not set -+# CONFIG_FAULT_INJECTION is not set -+# CONFIG_SAMPLES is not set -+# CONFIG_DEBUG_STACKOVERFLOW is not set -+# CONFIG_DEBUG_STACK_USAGE is not set -+# CONFIG_DEBUG_PAGEALLOC is not set -+# CONFIG_DEBUGGER is not set -+# CONFIG_KGDB_CONSOLE is not set -+CONFIG_BDI_SWITCH=y -+# CONFIG_PPC_EARLY_DEBUG is not set -+ -+# -+# Security options -+# -+# CONFIG_KEYS is not set -+# CONFIG_SECURITY is not set -+CONFIG_CRYPTO=y -+CONFIG_CRYPTO_ALGAPI=y -+CONFIG_CRYPTO_BLKCIPHER=y -+CONFIG_CRYPTO_MANAGER=y -+# CONFIG_CRYPTO_HMAC is not set -+# CONFIG_CRYPTO_NULL is not set -+# CONFIG_CRYPTO_MD4 is not set -+CONFIG_CRYPTO_MD5=y -+# CONFIG_CRYPTO_SHA1 is not set -+# 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_ECB=y -+CONFIG_CRYPTO_CBC=y -+CONFIG_CRYPTO_PCBC=y -+# CONFIG_CRYPTO_CRYPTD is not set -+CONFIG_CRYPTO_DES=y -+# CONFIG_CRYPTO_FCRYPT is not set -+# 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_SEED is not set -+# CONFIG_CRYPTO_DEFLATE is not set -+# CONFIG_CRYPTO_MICHAEL_MIC is not set -+# CONFIG_CRYPTO_CRC32C is not set -+# CONFIG_CRYPTO_CAMELLIA is not set -+# CONFIG_CRYPTO_AUTHENC is not set -+# CONFIG_CRYPTO_HW is not set -+# CONFIG_PPC_CLOCK is not set -+CONFIG_PPC_LIB_RHEAP=y ---- /dev/null -+++ b/arch/powerpc/configs/katmai_defconfig -@@ -0,0 +1,790 @@ -+# -+# Automatically generated make config: don't edit -+# Linux kernel version: 2.6.24-rc6 -+# Mon Dec 24 11:17:43 2007 -+# -+# CONFIG_PPC64 is not set -+ -+# -+# Processor support -+# -+# CONFIG_6xx is not set -+# CONFIG_PPC_85xx is not set -+# CONFIG_PPC_8xx is not set -+# CONFIG_40x is not set -+CONFIG_44x=y -+# CONFIG_E200 is not set -+CONFIG_4xx=y -+CONFIG_BOOKE=y -+CONFIG_PTE_64BIT=y -+CONFIG_PHYS_64BIT=y -+# CONFIG_PPC_MM_SLICES is not set -+CONFIG_NOT_COHERENT_CACHE=y -+CONFIG_PPC32=y -+CONFIG_WORD_SIZE=32 -+CONFIG_PPC_MERGE=y -+CONFIG_MMU=y -+CONFIG_GENERIC_CMOS_UPDATE=y -+CONFIG_GENERIC_TIME=y -+CONFIG_GENERIC_TIME_VSYSCALL=y -+CONFIG_GENERIC_CLOCKEVENTS=y -+CONFIG_GENERIC_HARDIRQS=y -+CONFIG_IRQ_PER_CPU=y -+CONFIG_RWSEM_XCHGADD_ALGORITHM=y -+CONFIG_ARCH_HAS_ILOG2_U32=y -+CONFIG_GENERIC_HWEIGHT=y -+CONFIG_GENERIC_CALIBRATE_DELAY=y -+CONFIG_GENERIC_FIND_NEXT_BIT=y -+# CONFIG_ARCH_NO_VIRT_TO_BUS is not set -+CONFIG_PPC=y -+CONFIG_EARLY_PRINTK=y -+CONFIG_GENERIC_NVRAM=y -+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -+CONFIG_ARCH_MAY_HAVE_PC_FDC=y -+CONFIG_PPC_OF=y -+CONFIG_OF=y -+CONFIG_PPC_UDBG_16550=y -+# CONFIG_GENERIC_TBSYNC is not set -+CONFIG_AUDIT_ARCH=y -+CONFIG_GENERIC_BUG=y -+# CONFIG_DEFAULT_UIMAGE is not set -+CONFIG_PPC_DCR_NATIVE=y -+# CONFIG_PPC_DCR_MMIO is not set -+CONFIG_PPC_DCR=y -+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" -+ -+# -+# General setup -+# -+CONFIG_EXPERIMENTAL=y -+CONFIG_BROKEN_ON_SMP=y -+CONFIG_INIT_ENV_ARG_LIMIT=32 -+CONFIG_LOCALVERSION="" -+CONFIG_LOCALVERSION_AUTO=y -+CONFIG_SWAP=y -+CONFIG_SYSVIPC=y -+CONFIG_SYSVIPC_SYSCTL=y -+CONFIG_POSIX_MQUEUE=y -+# CONFIG_BSD_PROCESS_ACCT is not set -+# CONFIG_TASKSTATS is not set -+# CONFIG_USER_NS is not set -+# CONFIG_PID_NS is not set -+# CONFIG_AUDIT is not set -+# CONFIG_IKCONFIG is not set -+CONFIG_LOG_BUF_SHIFT=14 -+# CONFIG_CGROUPS is not set -+CONFIG_FAIR_GROUP_SCHED=y -+CONFIG_FAIR_USER_SCHED=y -+# CONFIG_FAIR_CGROUP_SCHED is not set -+CONFIG_SYSFS_DEPRECATED=y -+# CONFIG_RELAY is not set -+CONFIG_BLK_DEV_INITRD=y -+CONFIG_INITRAMFS_SOURCE="" -+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -+CONFIG_SYSCTL=y -+CONFIG_EMBEDDED=y -+CONFIG_SYSCTL_SYSCALL=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_ANON_INODES=y -+CONFIG_EPOLL=y -+CONFIG_SIGNALFD=y -+CONFIG_EVENTFD=y -+CONFIG_SHMEM=y -+CONFIG_VM_EVENT_COUNTERS=y -+CONFIG_SLUB_DEBUG=y -+# CONFIG_SLAB is not set -+CONFIG_SLUB=y -+# CONFIG_SLOB is not set -+CONFIG_RT_MUTEXES=y -+# CONFIG_TINY_SHMEM is not set -+CONFIG_BASE_SMALL=0 -+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 -+CONFIG_BLOCK=y -+CONFIG_LBD=y -+# CONFIG_BLK_DEV_IO_TRACE is not set -+# CONFIG_LSF is not set -+# CONFIG_BLK_DEV_BSG is not set -+ -+# -+# IO Schedulers -+# -+CONFIG_IOSCHED_NOOP=y -+CONFIG_IOSCHED_AS=y -+CONFIG_IOSCHED_DEADLINE=y -+CONFIG_IOSCHED_CFQ=y -+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" -+CONFIG_PPC4xx_PCI_EXPRESS=y -+ -+# -+# Platform support -+# -+# CONFIG_PPC_MPC52xx is not set -+# CONFIG_PPC_MPC5200 is not set -+# CONFIG_PPC_CELL is not set -+# CONFIG_PPC_CELL_NATIVE is not set -+# CONFIG_PQ2ADS is not set -+# CONFIG_BAMBOO is not set -+# CONFIG_EBONY is not set -+# CONFIG_SEQUOIA is not set -+# CONFIG_TAISHAN is not set -+CONFIG_KATMAI=y -+# CONFIG_RAINIER is not set -+CONFIG_440SPe=y -+# CONFIG_MPIC is not set -+# CONFIG_MPIC_WEIRD is not set -+# CONFIG_PPC_I8259 is not set -+# CONFIG_PPC_RTAS is not set -+# CONFIG_MMIO_NVRAM is not set -+# CONFIG_PPC_MPC106 is not set -+# CONFIG_PPC_970_NAP is not set -+# CONFIG_PPC_INDIRECT_IO is not set -+# CONFIG_GENERIC_IOMAP is not set -+# CONFIG_CPU_FREQ is not set -+# CONFIG_CPM2 is not set -+# CONFIG_FSL_ULI1575 is not set -+ -+# -+# Kernel options -+# -+# CONFIG_HIGHMEM is not set -+# CONFIG_TICK_ONESHOT is not set -+# CONFIG_NO_HZ is not set -+# CONFIG_HIGH_RES_TIMERS is not set -+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y -+# CONFIG_HZ_100 is not set -+CONFIG_HZ_250=y -+# CONFIG_HZ_300 is not set -+# CONFIG_HZ_1000 is not set -+CONFIG_HZ=250 -+CONFIG_PREEMPT_NONE=y -+# CONFIG_PREEMPT_VOLUNTARY is not set -+# CONFIG_PREEMPT is not set -+CONFIG_BINFMT_ELF=y -+# CONFIG_BINFMT_MISC is not set -+# CONFIG_MATH_EMULATION is not set -+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y -+CONFIG_ARCH_FLATMEM_ENABLE=y -+CONFIG_ARCH_POPULATES_NODE_MAP=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 is not set -+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set -+CONFIG_SPLIT_PTLOCK_CPUS=4 -+CONFIG_RESOURCES_64BIT=y -+CONFIG_ZONE_DMA_FLAG=1 -+CONFIG_BOUNCE=y -+CONFIG_VIRT_TO_BUS=y -+CONFIG_PROC_DEVICETREE=y -+CONFIG_CMDLINE_BOOL=y -+CONFIG_CMDLINE="" -+CONFIG_SECCOMP=y -+CONFIG_WANT_DEVICE_TREE=y -+CONFIG_DEVICE_TREE="katmai.dts" -+CONFIG_ISA_DMA_API=y -+ -+# -+# Bus options -+# -+CONFIG_ZONE_DMA=y -+CONFIG_PPC_INDIRECT_PCI=y -+CONFIG_PCI=y -+CONFIG_PCI_DOMAINS=y -+CONFIG_PCI_SYSCALL=y -+# CONFIG_PCIEPORTBUS is not set -+CONFIG_ARCH_SUPPORTS_MSI=y -+# CONFIG_PCI_MSI is not set -+CONFIG_PCI_LEGACY=y -+# CONFIG_PCI_DEBUG is not set -+# CONFIG_PCCARD is not set -+# CONFIG_HOTPLUG_PCI is not set -+ -+# -+# Advanced setup -+# -+# CONFIG_ADVANCED_OPTIONS is not set -+ -+# -+# Default settings for advanced configuration options are used -+# -+CONFIG_HIGHMEM_START=0xfe000000 -+CONFIG_LOWMEM_SIZE=0x30000000 -+CONFIG_KERNEL_START=0xc0000000 -+CONFIG_TASK_SIZE=0xc0000000 -+CONFIG_CONSISTENT_START=0xff100000 -+CONFIG_CONSISTENT_SIZE=0x00200000 -+CONFIG_BOOT_LOAD=0x01000000 -+ -+# -+# Networking -+# -+CONFIG_NET=y -+ -+# -+# Networking options -+# -+CONFIG_PACKET=y -+# CONFIG_PACKET_MMAP is not set -+CONFIG_UNIX=y -+# CONFIG_NET_KEY is not set -+CONFIG_INET=y -+# CONFIG_IP_MULTICAST is not set -+# 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_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 is not set -+# CONFIG_INET_XFRM_MODE_TUNNEL is not set -+# CONFIG_INET_XFRM_MODE_BEET is not set -+# CONFIG_INET_LRO is not set -+CONFIG_INET_DIAG=y -+CONFIG_INET_TCP_DIAG=y -+# CONFIG_TCP_CONG_ADVANCED is not set -+CONFIG_TCP_CONG_CUBIC=y -+CONFIG_DEFAULT_TCP_CONG="cubic" -+# CONFIG_TCP_MD5SIG is not set -+# 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 -+# CONFIG_IP_DCCP is not set -+# CONFIG_IP_SCTP is not set -+# 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_ECONET is not set -+# CONFIG_WAN_ROUTER is not set -+# 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_AF_RXRPC is not set -+ -+# -+# Wireless -+# -+# CONFIG_CFG80211 is not set -+# CONFIG_WIRELESS_EXT is not set -+# CONFIG_MAC80211 is not set -+# CONFIG_IEEE80211 is not set -+# CONFIG_RFKILL is not set -+# CONFIG_NET_9P is not set -+ -+# -+# Device Drivers -+# -+ -+# -+# Generic Driver Options -+# -+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -+CONFIG_STANDALONE=y -+CONFIG_PREVENT_FIRMWARE_BUILD=y -+CONFIG_FW_LOADER=y -+# CONFIG_DEBUG_DRIVER is not set -+# CONFIG_DEBUG_DEVRES is not set -+# CONFIG_SYS_HYPERVISOR is not set -+CONFIG_CONNECTOR=y -+CONFIG_PROC_EVENTS=y -+# CONFIG_MTD is not set -+CONFIG_OF_DEVICE=y -+# CONFIG_PARPORT is not set -+CONFIG_BLK_DEV=y -+# 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 is not set -+# CONFIG_BLK_DEV_NBD is not set -+# CONFIG_BLK_DEV_SX8 is not set -+CONFIG_BLK_DEV_RAM=y -+CONFIG_BLK_DEV_RAM_COUNT=16 -+CONFIG_BLK_DEV_RAM_SIZE=35000 -+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 -+# CONFIG_CDROM_PKTCDVD is not set -+# CONFIG_ATA_OVER_ETH is not set -+# CONFIG_XILINX_SYSACE is not set -+CONFIG_MISC_DEVICES=y -+# CONFIG_PHANTOM is not set -+# CONFIG_EEPROM_93CX6 is not set -+# CONFIG_SGI_IOC4 is not set -+# CONFIG_TIFM_CORE is not set -+# CONFIG_IDE is not set -+ -+# -+# SCSI device support -+# -+# CONFIG_RAID_ATTRS is not set -+# CONFIG_SCSI is not set -+# CONFIG_SCSI_DMA is not set -+# CONFIG_SCSI_NETLINK is not set -+# CONFIG_ATA is not set -+# CONFIG_MD is not set -+# CONFIG_FUSION is not set -+ -+# -+# IEEE 1394 (FireWire) support -+# -+# CONFIG_FIREWIRE is not set -+# CONFIG_IEEE1394 is not set -+# CONFIG_I2O is not set -+CONFIG_MACINTOSH_DRIVERS=y -+# CONFIG_MAC_EMUMOUSEBTN is not set -+# CONFIG_WINDFARM is not set -+CONFIG_NETDEVICES=y -+# CONFIG_NETDEVICES_MULTIQUEUE is not set -+# CONFIG_DUMMY is not set -+# CONFIG_BONDING is not set -+# CONFIG_MACVLAN is not set -+# CONFIG_EQUALIZER is not set -+# CONFIG_TUN is not set -+# CONFIG_VETH is not set -+# CONFIG_IP1000 is not set -+# CONFIG_ARCNET is not set -+# CONFIG_PHYLIB is not set -+CONFIG_NET_ETHERNET=y -+# CONFIG_MII is not set -+# CONFIG_HAPPYMEAL is not set -+# CONFIG_SUNGEM is not set -+# CONFIG_CASSINI is not set -+# CONFIG_NET_VENDOR_3COM is not set -+# CONFIG_NET_TULIP is not set -+# CONFIG_HP100 is not set -+CONFIG_IBM_NEW_EMAC=y -+CONFIG_IBM_NEW_EMAC_RXB=128 -+CONFIG_IBM_NEW_EMAC_TXB=64 -+CONFIG_IBM_NEW_EMAC_POLL_WEIGHT=32 -+CONFIG_IBM_NEW_EMAC_RX_COPY_THRESHOLD=256 -+CONFIG_IBM_NEW_EMAC_RX_SKB_HEADROOM=0 -+# CONFIG_IBM_NEW_EMAC_DEBUG is not set -+# CONFIG_IBM_NEW_EMAC_ZMII is not set -+# CONFIG_IBM_NEW_EMAC_RGMII is not set -+# CONFIG_IBM_NEW_EMAC_TAH is not set -+CONFIG_IBM_NEW_EMAC_EMAC4=y -+# CONFIG_NET_PCI is not set -+# CONFIG_B44 is not set -+CONFIG_NETDEV_1000=y -+# CONFIG_ACENIC is not set -+# CONFIG_DL2K is not set -+# CONFIG_E1000 is not set -+# CONFIG_E1000E 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 -+# CONFIG_QLA3XXX is not set -+# CONFIG_ATL1 is not set -+CONFIG_NETDEV_10000=y -+# CONFIG_CHELSIO_T1 is not set -+# CONFIG_CHELSIO_T3 is not set -+# CONFIG_IXGBE is not set -+# CONFIG_IXGB is not set -+# CONFIG_S2IO is not set -+# CONFIG_MYRI10GE is not set -+# CONFIG_NETXEN_NIC is not set -+# CONFIG_NIU is not set -+# CONFIG_MLX4_CORE is not set -+# CONFIG_TEHUTI is not set -+# CONFIG_TR is not set -+ -+# -+# Wireless LAN -+# -+# CONFIG_WLAN_PRE80211 is not set -+# CONFIG_WLAN_80211 is not set -+# CONFIG_WAN is not set -+# CONFIG_FDDI is not set -+# CONFIG_HIPPI 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 -+# CONFIG_ISDN is not set -+# CONFIG_PHONE is not set -+ -+# -+# Input device support -+# -+# CONFIG_INPUT is not set -+ -+# -+# Hardware I/O ports -+# -+# CONFIG_SERIO is not set -+# CONFIG_GAMEPORT is not set -+ -+# -+# Character devices -+# -+# CONFIG_VT is not set -+# CONFIG_SERIAL_NONSTANDARD is not set -+ -+# -+# Serial drivers -+# -+CONFIG_SERIAL_8250=y -+CONFIG_SERIAL_8250_CONSOLE=y -+# CONFIG_SERIAL_8250_PCI is not set -+CONFIG_SERIAL_8250_NR_UARTS=4 -+CONFIG_SERIAL_8250_RUNTIME_UARTS=4 -+CONFIG_SERIAL_8250_EXTENDED=y -+# CONFIG_SERIAL_8250_MANY_PORTS is not set -+CONFIG_SERIAL_8250_SHARE_IRQ=y -+# CONFIG_SERIAL_8250_DETECT_IRQ is not set -+# CONFIG_SERIAL_8250_RSA is not set -+ -+# -+# Non-8250 serial port support -+# -+# CONFIG_SERIAL_UARTLITE is not set -+CONFIG_SERIAL_CORE=y -+CONFIG_SERIAL_CORE_CONSOLE=y -+# CONFIG_SERIAL_JSM is not set -+CONFIG_SERIAL_OF_PLATFORM=y -+CONFIG_UNIX98_PTYS=y -+CONFIG_LEGACY_PTYS=y -+CONFIG_LEGACY_PTY_COUNT=256 -+# CONFIG_IPMI_HANDLER is not set -+# CONFIG_HW_RANDOM is not set -+# CONFIG_NVRAM is not set -+# CONFIG_GEN_RTC is not set -+# CONFIG_R3964 is not set -+# CONFIG_APPLICOM is not set -+# CONFIG_RAW_DRIVER is not set -+# CONFIG_TCG_TPM is not set -+CONFIG_DEVPORT=y -+# CONFIG_I2C is not set -+ -+# -+# SPI support -+# -+# CONFIG_SPI is not set -+# CONFIG_SPI_MASTER is not set -+# CONFIG_W1 is not set -+# CONFIG_POWER_SUPPLY is not set -+# CONFIG_HWMON is not set -+# CONFIG_WATCHDOG is not set -+ -+# -+# Sonics Silicon Backplane -+# -+CONFIG_SSB_POSSIBLE=y -+# CONFIG_SSB is not set -+ -+# -+# Multifunction device drivers -+# -+# CONFIG_MFD_SM501 is not set -+ -+# -+# Multimedia devices -+# -+# CONFIG_VIDEO_DEV is not set -+# CONFIG_DVB_CORE is not set -+CONFIG_DAB=y -+ -+# -+# Graphics support -+# -+# CONFIG_AGP is not set -+# CONFIG_DRM is not set -+# CONFIG_VGASTATE is not set -+CONFIG_VIDEO_OUTPUT_CONTROL=m -+# CONFIG_FB is not set -+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set -+ -+# -+# Display device support -+# -+# CONFIG_DISPLAY_SUPPORT is not set -+ -+# -+# Sound -+# -+# CONFIG_SOUND is not set -+CONFIG_USB_SUPPORT=y -+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 -+# CONFIG_MMC is not set -+# CONFIG_NEW_LEDS is not set -+# CONFIG_INFINIBAND is not set -+# CONFIG_EDAC is not set -+# CONFIG_RTC_CLASS is not set -+ -+# -+# Userspace I/O -+# -+# CONFIG_UIO 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_EXT4DEV_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_GFS2_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 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_MSDOS_FS is not set -+# CONFIG_VFAT_FS is not set -+# CONFIG_NTFS_FS is not set -+ -+# -+# Pseudo filesystems -+# -+CONFIG_PROC_FS=y -+CONFIG_PROC_KCORE=y -+CONFIG_PROC_SYSCTL=y -+CONFIG_SYSFS=y -+CONFIG_TMPFS=y -+# CONFIG_TMPFS_POSIX_ACL is not set -+# CONFIG_HUGETLB_PAGE 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_CRAMFS=y -+# 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 -+CONFIG_NETWORK_FILESYSTEMS=y -+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_SUNRPC_BIND34 is not set -+# 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 -+ -+# -+# Partition Types -+# -+# CONFIG_PARTITION_ADVANCED is not set -+CONFIG_MSDOS_PARTITION=y -+# CONFIG_NLS is not set -+# CONFIG_DLM is not set -+# CONFIG_UCC_SLOW is not set -+ -+# -+# Library routines -+# -+CONFIG_BITREVERSE=y -+# CONFIG_CRC_CCITT is not set -+# CONFIG_CRC16 is not set -+# CONFIG_CRC_ITU_T is not set -+CONFIG_CRC32=y -+# CONFIG_CRC7 is not set -+# CONFIG_LIBCRC32C is not set -+CONFIG_ZLIB_INFLATE=y -+CONFIG_PLIST=y -+CONFIG_HAS_IOMEM=y -+CONFIG_HAS_IOPORT=y -+CONFIG_HAS_DMA=y -+CONFIG_INSTRUMENTATION=y -+# CONFIG_PROFILING is not set -+# CONFIG_KPROBES is not set -+# CONFIG_MARKERS is not set -+ -+# -+# Kernel hacking -+# -+# CONFIG_PRINTK_TIME is not set -+CONFIG_ENABLE_WARN_DEPRECATED=y -+CONFIG_ENABLE_MUST_CHECK=y -+CONFIG_MAGIC_SYSRQ=y -+# CONFIG_UNUSED_SYMBOLS is not set -+# CONFIG_DEBUG_FS is not set -+# CONFIG_HEADERS_CHECK is not set -+CONFIG_DEBUG_KERNEL=y -+# CONFIG_DEBUG_SHIRQ is not set -+CONFIG_DETECT_SOFTLOCKUP=y -+CONFIG_SCHED_DEBUG=y -+# CONFIG_SCHEDSTATS is not set -+# CONFIG_TIMER_STATS is not set -+# CONFIG_SLUB_DEBUG_ON is not set -+# CONFIG_DEBUG_RT_MUTEXES is not set -+# CONFIG_RT_MUTEX_TESTER is not set -+# CONFIG_DEBUG_SPINLOCK is not set -+# CONFIG_DEBUG_MUTEXES is not set -+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -+# CONFIG_DEBUG_KOBJECT is not set -+# CONFIG_DEBUG_BUGVERBOSE is not set -+# CONFIG_DEBUG_INFO is not set -+# CONFIG_DEBUG_VM is not set -+# CONFIG_DEBUG_LIST is not set -+# CONFIG_DEBUG_SG is not set -+CONFIG_FORCED_INLINING=y -+# CONFIG_BOOT_PRINTK_DELAY is not set -+# CONFIG_RCU_TORTURE_TEST is not set -+# CONFIG_FAULT_INJECTION is not set -+# CONFIG_SAMPLES is not set -+# CONFIG_DEBUG_STACKOVERFLOW is not set -+# CONFIG_DEBUG_STACK_USAGE is not set -+# CONFIG_DEBUG_PAGEALLOC is not set -+CONFIG_DEBUGGER=y -+# CONFIG_KGDB is not set -+# CONFIG_XMON is not set -+# CONFIG_BDI_SWITCH is not set -+# CONFIG_PPC_EARLY_DEBUG is not set -+ -+# -+# Security options -+# -+# CONFIG_KEYS is not set -+# CONFIG_SECURITY is not set -+# CONFIG_SECURITY_FILE_CAPABILITIES is not set -+CONFIG_CRYPTO=y -+CONFIG_CRYPTO_ALGAPI=y -+CONFIG_CRYPTO_BLKCIPHER=y -+CONFIG_CRYPTO_MANAGER=y -+# CONFIG_CRYPTO_HMAC is not set -+# CONFIG_CRYPTO_XCBC is not set -+# CONFIG_CRYPTO_NULL is not set -+# CONFIG_CRYPTO_MD4 is not set -+CONFIG_CRYPTO_MD5=y -+# CONFIG_CRYPTO_SHA1 is not set -+# 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_GF128MUL is not set -+CONFIG_CRYPTO_ECB=y -+CONFIG_CRYPTO_CBC=y -+CONFIG_CRYPTO_PCBC=y -+# CONFIG_CRYPTO_LRW is not set -+# CONFIG_CRYPTO_XTS is not set -+# CONFIG_CRYPTO_CRYPTD is not set -+CONFIG_CRYPTO_DES=y -+# CONFIG_CRYPTO_FCRYPT is not set -+# 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_SEED is not set -+# CONFIG_CRYPTO_DEFLATE is not set -+# CONFIG_CRYPTO_MICHAEL_MIC is not set -+# CONFIG_CRYPTO_CRC32C is not set -+# CONFIG_CRYPTO_CAMELLIA is not set -+# CONFIG_CRYPTO_TEST is not set -+# CONFIG_CRYPTO_AUTHENC is not set -+CONFIG_CRYPTO_HW=y -+# CONFIG_PPC_CLOCK is not set ---- a/arch/powerpc/configs/kilauea_defconfig -+++ b/arch/powerpc/configs/kilauea_defconfig -@@ -1,7 +1,7 @@ - # - # Automatically generated make config: don't edit --# Linux kernel version: 2.6.24-rc4 --# Thu Dec 6 16:48:20 2007 -+# Linux kernel version: 2.6.24-rc6 -+# Thu Jan 3 14:21:31 2008 - # - # CONFIG_PPC64 is not set - -@@ -40,7 +40,7 @@ CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y - CONFIG_ARCH_MAY_HAVE_PC_FDC=y - CONFIG_PPC_OF=y - CONFIG_OF=y --# CONFIG_PPC_UDBG_16550 is not set -+CONFIG_PPC_UDBG_16550=y - # CONFIG_GENERIC_TBSYNC is not set - CONFIG_AUDIT_ARCH=y - CONFIG_GENERIC_BUG=y -@@ -125,6 +125,7 @@ CONFIG_DEFAULT_AS=y - # CONFIG_DEFAULT_CFQ is not set - # CONFIG_DEFAULT_NOOP is not set - CONFIG_DEFAULT_IOSCHED="anticipatory" -+CONFIG_PPC4xx_PCI_EXPRESS=y - - # - # Platform support -@@ -134,9 +135,12 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" - # CONFIG_PPC_CELL is not set - # CONFIG_PPC_CELL_NATIVE is not set - # CONFIG_PQ2ADS is not set -+# CONFIG_EP405 is not set - CONFIG_KILAUEA=y -+# CONFIG_MAKALU is not set - # CONFIG_WALNUT is not set - # CONFIG_XILINX_VIRTEX_GENERIC_BOARD is not set -+CONFIG_405EX=y - # CONFIG_MPIC is not set - # CONFIG_MPIC_WEIRD is not set - # CONFIG_PPC_I8259 is not set -@@ -199,11 +203,17 @@ CONFIG_ISA_DMA_API=y - # Bus options - # - CONFIG_ZONE_DMA=y --# CONFIG_PCI is not set --# CONFIG_PCI_DOMAINS is not set --# CONFIG_PCI_SYSCALL is not set --# CONFIG_ARCH_SUPPORTS_MSI is not set -+CONFIG_PPC_INDIRECT_PCI=y -+CONFIG_PCI=y -+CONFIG_PCI_DOMAINS=y -+CONFIG_PCI_SYSCALL=y -+# CONFIG_PCIEPORTBUS is not set -+CONFIG_ARCH_SUPPORTS_MSI=y -+# CONFIG_PCI_MSI is not set -+CONFIG_PCI_LEGACY=y -+# CONFIG_PCI_DEBUG is not set - # CONFIG_PCCARD is not set -+# CONFIG_HOTPLUG_PCI is not set - - # - # Advanced setup -@@ -368,11 +378,13 @@ CONFIG_MTD_CFI_UTIL=y - # CONFIG_MTD_COMPLEX_MAPPINGS is not set - # CONFIG_MTD_PHYSMAP is not set - CONFIG_MTD_PHYSMAP_OF=y -+# CONFIG_MTD_INTEL_VR_NOR is not set - # CONFIG_MTD_PLATRAM is not set - - # - # Self-contained MTD device drivers - # -+# CONFIG_MTD_PMC551 is not set - # CONFIG_MTD_SLRAM is not set - # CONFIG_MTD_PHRAM is not set - # CONFIG_MTD_MTDRAM is not set -@@ -395,9 +407,14 @@ CONFIG_OF_DEVICE=y - # CONFIG_PARPORT is not set - CONFIG_BLK_DEV=y - # 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 is not set - # CONFIG_BLK_DEV_NBD is not set -+# CONFIG_BLK_DEV_SX8 is not set - CONFIG_BLK_DEV_RAM=y - CONFIG_BLK_DEV_RAM_COUNT=16 - CONFIG_BLK_DEV_RAM_SIZE=35000 -@@ -417,6 +434,14 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 - # CONFIG_SCSI_NETLINK is not set - # CONFIG_ATA is not set - # CONFIG_MD is not set -+# CONFIG_FUSION is not set -+ -+# -+# IEEE 1394 (FireWire) support -+# -+# CONFIG_FIREWIRE is not set -+# CONFIG_IEEE1394 is not set -+# CONFIG_I2O is not set - # CONFIG_MACINTOSH_DRIVERS is not set - CONFIG_NETDEVICES=y - # CONFIG_NETDEVICES_MULTIQUEUE is not set -@@ -426,9 +451,33 @@ CONFIG_NETDEVICES=y - # CONFIG_EQUALIZER is not set - # CONFIG_TUN is not set - # CONFIG_VETH is not set --# CONFIG_NET_ETHERNET is not set -+# CONFIG_IP1000 is not set -+# CONFIG_ARCNET is not set -+# CONFIG_PHYLIB is not set -+CONFIG_NET_ETHERNET=y -+# CONFIG_MII is not set -+# CONFIG_HAPPYMEAL is not set -+# CONFIG_SUNGEM is not set -+# CONFIG_CASSINI is not set -+# CONFIG_NET_VENDOR_3COM is not set -+# CONFIG_NET_TULIP is not set -+# CONFIG_HP100 is not set -+CONFIG_IBM_NEW_EMAC=y -+CONFIG_IBM_NEW_EMAC_RXB=256 -+CONFIG_IBM_NEW_EMAC_TXB=256 -+CONFIG_IBM_NEW_EMAC_POLL_WEIGHT=32 -+CONFIG_IBM_NEW_EMAC_RX_COPY_THRESHOLD=256 -+CONFIG_IBM_NEW_EMAC_RX_SKB_HEADROOM=0 -+# CONFIG_IBM_NEW_EMAC_DEBUG is not set -+# CONFIG_IBM_NEW_EMAC_ZMII is not set -+CONFIG_IBM_NEW_EMAC_RGMII=y -+# CONFIG_IBM_NEW_EMAC_TAH is not set -+CONFIG_IBM_NEW_EMAC_EMAC4=y -+# CONFIG_NET_PCI is not set -+# CONFIG_B44 is not set - # CONFIG_NETDEV_1000 is not set - # CONFIG_NETDEV_10000 is not set -+# CONFIG_TR is not set - - # - # Wireless LAN -@@ -436,6 +485,8 @@ CONFIG_NETDEVICES=y - # CONFIG_WLAN_PRE80211 is not set - # CONFIG_WLAN_80211 is not set - # CONFIG_WAN is not set -+# CONFIG_FDDI is not set -+# CONFIG_HIPPI is not set - # CONFIG_PPP is not set - # CONFIG_SLIP is not set - # CONFIG_SHAPER is not set -@@ -467,6 +518,7 @@ CONFIG_NETDEVICES=y - # - 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 -@@ -481,6 +533,7 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y - # CONFIG_SERIAL_UARTLITE is not set - CONFIG_SERIAL_CORE=y - CONFIG_SERIAL_CORE_CONSOLE=y -+# CONFIG_SERIAL_JSM is not set - CONFIG_SERIAL_OF_PLATFORM=y - CONFIG_UNIX98_PTYS=y - CONFIG_LEGACY_PTYS=y -@@ -490,8 +543,10 @@ CONFIG_LEGACY_PTY_COUNT=256 - # CONFIG_NVRAM is not set - # CONFIG_GEN_RTC is not set - # CONFIG_R3964 is not set -+# CONFIG_APPLICOM is not set - # CONFIG_RAW_DRIVER is not set - # CONFIG_TCG_TPM is not set -+CONFIG_DEVPORT=y - # CONFIG_I2C is not set - - # -@@ -525,6 +580,8 @@ CONFIG_SSB_POSSIBLE=y - # - # Graphics support - # -+# CONFIG_AGP is not set -+# CONFIG_DRM is not set - # CONFIG_VGASTATE is not set - # CONFIG_VIDEO_OUTPUT_CONTROL is not set - # CONFIG_FB is not set -@@ -542,6 +599,7 @@ CONFIG_SSB_POSSIBLE=y - # CONFIG_USB_SUPPORT is not set - # CONFIG_MMC is not set - # CONFIG_NEW_LEDS is not set -+# CONFIG_INFINIBAND is not set - # CONFIG_EDAC is not set - # CONFIG_RTC_CLASS is not set - ---- a/arch/powerpc/configs/lite5200_defconfig -+++ /dev/null -@@ -1,847 +0,0 @@ --# --# Automatically generated make config: don't edit --# Linux kernel version: 2.6.24-rc4 --# Thu Dec 6 16:48:24 2007 --# --# CONFIG_PPC64 is not set -- --# --# Processor support --# --CONFIG_6xx=y --# CONFIG_PPC_85xx is not set --# CONFIG_PPC_8xx is not set --# CONFIG_40x is not set --# CONFIG_44x is not set --# CONFIG_E200 is not set --CONFIG_PPC_FPU=y --# CONFIG_ALTIVEC is not set --CONFIG_PPC_STD_MMU=y --CONFIG_PPC_STD_MMU_32=y --# CONFIG_PPC_MM_SLICES is not set --# CONFIG_SMP is not set --CONFIG_PPC32=y --CONFIG_WORD_SIZE=32 --CONFIG_PPC_MERGE=y --CONFIG_MMU=y --CONFIG_GENERIC_CMOS_UPDATE=y --CONFIG_GENERIC_TIME=y --CONFIG_GENERIC_TIME_VSYSCALL=y --CONFIG_GENERIC_CLOCKEVENTS=y --CONFIG_GENERIC_HARDIRQS=y --CONFIG_IRQ_PER_CPU=y --CONFIG_RWSEM_XCHGADD_ALGORITHM=y --CONFIG_ARCH_HAS_ILOG2_U32=y --CONFIG_GENERIC_HWEIGHT=y --CONFIG_GENERIC_CALIBRATE_DELAY=y --CONFIG_GENERIC_FIND_NEXT_BIT=y --# CONFIG_ARCH_NO_VIRT_TO_BUS is not set --CONFIG_PPC=y --CONFIG_EARLY_PRINTK=y --CONFIG_GENERIC_NVRAM=y --CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y --CONFIG_ARCH_MAY_HAVE_PC_FDC=y --CONFIG_PPC_OF=y --CONFIG_OF=y --# CONFIG_PPC_UDBG_16550 is not set --# CONFIG_GENERIC_TBSYNC is not set --CONFIG_AUDIT_ARCH=y --CONFIG_GENERIC_BUG=y --# CONFIG_DEFAULT_UIMAGE is not set --# CONFIG_PPC_DCR_NATIVE is not set --# CONFIG_PPC_DCR_MMIO is not set --CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" -- --# --# General setup --# --CONFIG_EXPERIMENTAL=y --CONFIG_BROKEN_ON_SMP=y --CONFIG_INIT_ENV_ARG_LIMIT=32 --CONFIG_LOCALVERSION="" --CONFIG_LOCALVERSION_AUTO=y --CONFIG_SWAP=y --CONFIG_SYSVIPC=y --CONFIG_SYSVIPC_SYSCTL=y --# CONFIG_POSIX_MQUEUE is not set --# CONFIG_BSD_PROCESS_ACCT is not set --# CONFIG_TASKSTATS is not set --# CONFIG_USER_NS is not set --# CONFIG_PID_NS is not set --# CONFIG_AUDIT is not set --# CONFIG_IKCONFIG is not set --CONFIG_LOG_BUF_SHIFT=14 --# CONFIG_CGROUPS is not set --# CONFIG_FAIR_GROUP_SCHED is not set --CONFIG_SYSFS_DEPRECATED=y --# CONFIG_RELAY is not set --CONFIG_BLK_DEV_INITRD=y --CONFIG_INITRAMFS_SOURCE="" --# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set --CONFIG_SYSCTL=y --CONFIG_EMBEDDED=y --# CONFIG_SYSCTL_SYSCALL is not set --# CONFIG_KALLSYMS is not set --CONFIG_HOTPLUG=y --CONFIG_PRINTK=y --CONFIG_BUG=y --CONFIG_ELF_CORE=y --CONFIG_BASE_FULL=y --CONFIG_FUTEX=y --CONFIG_ANON_INODES=y --# CONFIG_EPOLL is not set --CONFIG_SIGNALFD=y --CONFIG_EVENTFD=y --CONFIG_SHMEM=y --CONFIG_VM_EVENT_COUNTERS=y --CONFIG_SLUB_DEBUG=y --# CONFIG_SLAB is not set --CONFIG_SLUB=y --# CONFIG_SLOB is not set --CONFIG_RT_MUTEXES=y --# CONFIG_TINY_SHMEM is not set --CONFIG_BASE_SMALL=0 --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 is not set --CONFIG_BLOCK=y --# CONFIG_LBD is not set --# CONFIG_BLK_DEV_IO_TRACE is not set --# CONFIG_LSF is not set --# CONFIG_BLK_DEV_BSG is not set -- --# --# IO Schedulers --# --CONFIG_IOSCHED_NOOP=y --CONFIG_IOSCHED_AS=y --CONFIG_IOSCHED_DEADLINE=y --CONFIG_IOSCHED_CFQ=y --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" -- --# --# Platform support --# --CONFIG_PPC_MULTIPLATFORM=y --# CONFIG_PPC_82xx is not set --# CONFIG_PPC_83xx is not set --# CONFIG_PPC_86xx is not set --CONFIG_CLASSIC32=y --# CONFIG_PPC_CHRP is not set --CONFIG_PPC_MPC52xx=y --CONFIG_PPC_MPC5200=y --CONFIG_PPC_MPC5200_BUGFIX=y --# CONFIG_PPC_EFIKA is not set --CONFIG_PPC_LITE5200=y --# CONFIG_PPC_PMAC is not set --# CONFIG_PPC_CELL is not set --# CONFIG_PPC_CELL_NATIVE is not set --# CONFIG_PQ2ADS is not set --# CONFIG_EMBEDDED6xx is not set --# CONFIG_MPIC is not set --# CONFIG_MPIC_WEIRD is not set --# CONFIG_PPC_I8259 is not set --# CONFIG_PPC_RTAS is not set --# CONFIG_MMIO_NVRAM is not set --# CONFIG_PPC_MPC106 is not set --# CONFIG_PPC_970_NAP is not set --# CONFIG_PPC_INDIRECT_IO is not set --# CONFIG_GENERIC_IOMAP is not set --# CONFIG_CPU_FREQ is not set --# CONFIG_TAU is not set --# CONFIG_CPM2 is not set --# CONFIG_FSL_ULI1575 is not set --CONFIG_PPC_BESTCOMM=y --CONFIG_PPC_BESTCOMM_ATA=y --CONFIG_PPC_BESTCOMM_FEC=y --CONFIG_PPC_BESTCOMM_GEN_BD=y -- --# --# Kernel options --# --# CONFIG_HIGHMEM is not set --CONFIG_TICK_ONESHOT=y --CONFIG_NO_HZ=y --CONFIG_HIGH_RES_TIMERS=y --CONFIG_GENERIC_CLOCKEVENTS_BUILD=y --# CONFIG_HZ_100 is not set --CONFIG_HZ_250=y --# CONFIG_HZ_300 is not set --# CONFIG_HZ_1000 is not set --CONFIG_HZ=250 --CONFIG_PREEMPT_NONE=y --# CONFIG_PREEMPT_VOLUNTARY is not set --# CONFIG_PREEMPT is not set --CONFIG_BINFMT_ELF=y --# CONFIG_BINFMT_MISC is not set --CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y --# CONFIG_KEXEC is not set --CONFIG_ARCH_FLATMEM_ENABLE=y --CONFIG_ARCH_POPULATES_NODE_MAP=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 is not set --# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set --CONFIG_SPLIT_PTLOCK_CPUS=4 --# CONFIG_RESOURCES_64BIT is not set --CONFIG_ZONE_DMA_FLAG=1 --CONFIG_BOUNCE=y --CONFIG_VIRT_TO_BUS=y --CONFIG_PROC_DEVICETREE=y --# CONFIG_CMDLINE_BOOL is not set --CONFIG_PM=y --# CONFIG_PM_LEGACY is not set --# CONFIG_PM_DEBUG is not set --CONFIG_PM_SLEEP=y --CONFIG_SUSPEND_UP_POSSIBLE=y --CONFIG_SUSPEND=y --CONFIG_HIBERNATION_UP_POSSIBLE=y --# CONFIG_HIBERNATION is not set --CONFIG_SECCOMP=y --CONFIG_WANT_DEVICE_TREE=y --CONFIG_DEVICE_TREE="" --CONFIG_ISA_DMA_API=y -- --# --# Bus options --# --CONFIG_ZONE_DMA=y --CONFIG_GENERIC_ISA_DMA=y --# CONFIG_PPC_INDIRECT_PCI is not set --CONFIG_FSL_SOC=y --CONFIG_PCI=y --CONFIG_PCI_DOMAINS=y --CONFIG_PCI_SYSCALL=y --# CONFIG_PCIEPORTBUS is not set --CONFIG_ARCH_SUPPORTS_MSI=y --# CONFIG_PCI_MSI is not set --CONFIG_PCI_LEGACY=y --# CONFIG_PCI_DEBUG is not set --# CONFIG_PCCARD is not set --# CONFIG_HOTPLUG_PCI is not set -- --# --# Advanced setup --# --# CONFIG_ADVANCED_OPTIONS is not set -- --# --# Default settings for advanced configuration options are used --# --CONFIG_HIGHMEM_START=0xfe000000 --CONFIG_LOWMEM_SIZE=0x30000000 --CONFIG_KERNEL_START=0xc0000000 --CONFIG_TASK_SIZE=0xc0000000 --CONFIG_BOOT_LOAD=0x00800000 -- --# --# Networking --# --CONFIG_NET=y -- --# --# Networking options --# --CONFIG_PACKET=y --# CONFIG_PACKET_MMAP is not set --CONFIG_UNIX=y --CONFIG_XFRM=y --CONFIG_XFRM_USER=m --# CONFIG_XFRM_SUB_POLICY is not set --# CONFIG_XFRM_MIGRATE 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=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_XFRM_MODE_TRANSPORT=y --CONFIG_INET_XFRM_MODE_TUNNEL=y --CONFIG_INET_XFRM_MODE_BEET=y --# CONFIG_INET_LRO is not set --CONFIG_INET_DIAG=y --CONFIG_INET_TCP_DIAG=y --# CONFIG_TCP_CONG_ADVANCED is not set --CONFIG_TCP_CONG_CUBIC=y --CONFIG_DEFAULT_TCP_CONG="cubic" --# CONFIG_TCP_MD5SIG is not set --# 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 --# CONFIG_IP_DCCP is not set --# CONFIG_IP_SCTP is not set --# 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_ECONET is not set --# CONFIG_WAN_ROUTER is not set --# 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_AF_RXRPC is not set -- --# --# Wireless --# --# CONFIG_CFG80211 is not set --# CONFIG_WIRELESS_EXT is not set --# CONFIG_MAC80211 is not set --# CONFIG_IEEE80211 is not set --# CONFIG_RFKILL is not set --# CONFIG_NET_9P is not set -- --# --# Device Drivers --# -- --# --# Generic Driver Options --# --CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" --CONFIG_STANDALONE=y --CONFIG_PREVENT_FIRMWARE_BUILD=y --# CONFIG_FW_LOADER is not set --# CONFIG_DEBUG_DRIVER is not set --# CONFIG_DEBUG_DEVRES is not set --# CONFIG_SYS_HYPERVISOR is not set --# CONFIG_CONNECTOR is not set --# CONFIG_MTD is not set --CONFIG_OF_DEVICE=y --# CONFIG_PARPORT is not set --CONFIG_BLK_DEV=y --# 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=y --# CONFIG_BLK_DEV_CRYPTOLOOP is not set --# CONFIG_BLK_DEV_NBD is not set --# CONFIG_BLK_DEV_SX8 is not set --CONFIG_BLK_DEV_RAM=y --CONFIG_BLK_DEV_RAM_COUNT=16 --CONFIG_BLK_DEV_RAM_SIZE=32768 --CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 --# CONFIG_CDROM_PKTCDVD is not set --# CONFIG_ATA_OVER_ETH is not set --CONFIG_MISC_DEVICES=y --# CONFIG_PHANTOM is not set --# CONFIG_EEPROM_93CX6 is not set --# CONFIG_SGI_IOC4 is not set --# CONFIG_TIFM_CORE is not set --# CONFIG_IDE is not set -- --# --# SCSI device support --# --# CONFIG_RAID_ATTRS is not set --CONFIG_SCSI=y --CONFIG_SCSI_DMA=y --# CONFIG_SCSI_TGT is not set --# CONFIG_SCSI_NETLINK is not set --# CONFIG_SCSI_PROC_FS is not set -- --# --# SCSI support type (disk, tape, CD-ROM) --# --# CONFIG_BLK_DEV_SD is not set --# CONFIG_CHR_DEV_ST is not set --# CONFIG_CHR_DEV_OSST is not set --# CONFIG_BLK_DEV_SR is not set --# CONFIG_CHR_DEV_SG is not set --# CONFIG_CHR_DEV_SCH is not set -- --# --# Some SCSI devices (e.g. CD jukebox) support multiple LUNs --# --# CONFIG_SCSI_MULTI_LUN is not set --# CONFIG_SCSI_CONSTANTS is not set --# CONFIG_SCSI_LOGGING is not set --# CONFIG_SCSI_SCAN_ASYNC is not set --CONFIG_SCSI_WAIT_SCAN=m -- --# --# SCSI Transports --# --# CONFIG_SCSI_SPI_ATTRS is not set --# CONFIG_SCSI_FC_ATTRS is not set --# CONFIG_SCSI_ISCSI_ATTRS is not set --# CONFIG_SCSI_SAS_LIBSAS is not set --# CONFIG_SCSI_SRP_ATTRS is not set --CONFIG_SCSI_LOWLEVEL=y --# CONFIG_ISCSI_TCP is not set --# CONFIG_BLK_DEV_3W_XXXX_RAID is not set --# CONFIG_SCSI_3W_9XXX is not set --# CONFIG_SCSI_ACARD is not set --# CONFIG_SCSI_AACRAID is not set --# CONFIG_SCSI_AIC7XXX is not set --# CONFIG_SCSI_AIC7XXX_OLD is not set --# CONFIG_SCSI_AIC79XX is not set --# CONFIG_SCSI_AIC94XX is not set --# CONFIG_SCSI_DPT_I2O is not set --# CONFIG_SCSI_ADVANSYS is not set --# CONFIG_SCSI_ARCMSR is not set --# CONFIG_MEGARAID_NEWGEN is not set --# CONFIG_MEGARAID_LEGACY is not set --# CONFIG_MEGARAID_SAS is not set --# CONFIG_SCSI_HPTIOP is not set --# CONFIG_SCSI_BUSLOGIC is not set --# CONFIG_SCSI_DMX3191D is not set --# CONFIG_SCSI_EATA is not set --# CONFIG_SCSI_FUTURE_DOMAIN is not set --# CONFIG_SCSI_GDTH is not set --# CONFIG_SCSI_IPS is not set --# CONFIG_SCSI_INITIO is not set --# CONFIG_SCSI_INIA100 is not set --# CONFIG_SCSI_STEX is not set --# CONFIG_SCSI_SYM53C8XX_2 is not set --# CONFIG_SCSI_IPR is not set --# CONFIG_SCSI_QLOGIC_1280 is not set --# CONFIG_SCSI_QLA_FC is not set --# CONFIG_SCSI_QLA_ISCSI is not set --# CONFIG_SCSI_LPFC is not set --# CONFIG_SCSI_DC395x is not set --# CONFIG_SCSI_DC390T is not set --# CONFIG_SCSI_NSP32 is not set --# CONFIG_SCSI_DEBUG is not set --# CONFIG_SCSI_SRP is not set --CONFIG_ATA=y --# CONFIG_ATA_NONSTANDARD is not set --# CONFIG_SATA_AHCI is not set --# CONFIG_SATA_SVW is not set --# CONFIG_ATA_PIIX is not set --# CONFIG_SATA_MV is not set --# CONFIG_SATA_NV is not set --# CONFIG_PDC_ADMA is not set --# CONFIG_SATA_QSTOR is not set --# CONFIG_SATA_PROMISE is not set --# CONFIG_SATA_SX4 is not set --# CONFIG_SATA_SIL is not set --# CONFIG_SATA_SIL24 is not set --# CONFIG_SATA_SIS is not set --# CONFIG_SATA_ULI is not set --# CONFIG_SATA_VIA is not set --# CONFIG_SATA_VITESSE is not set --# CONFIG_SATA_INIC162X is not set --# CONFIG_PATA_ALI is not set --# CONFIG_PATA_AMD is not set --# CONFIG_PATA_ARTOP is not set --# CONFIG_PATA_ATIIXP is not set --# CONFIG_PATA_CMD640_PCI is not set --# CONFIG_PATA_CMD64X is not set --# CONFIG_PATA_CS5520 is not set --# CONFIG_PATA_CS5530 is not set --# CONFIG_PATA_CYPRESS is not set --# CONFIG_PATA_EFAR is not set --# CONFIG_ATA_GENERIC is not set --# CONFIG_PATA_HPT366 is not set --# CONFIG_PATA_HPT37X is not set --# CONFIG_PATA_HPT3X2N is not set --# CONFIG_PATA_HPT3X3 is not set --# CONFIG_PATA_IT821X is not set --# CONFIG_PATA_IT8213 is not set --# CONFIG_PATA_JMICRON is not set --# CONFIG_PATA_TRIFLEX is not set --# CONFIG_PATA_MARVELL is not set --CONFIG_PATA_MPC52xx=y --# CONFIG_PATA_MPIIX is not set --# CONFIG_PATA_OLDPIIX is not set --# CONFIG_PATA_NETCELL is not set --# CONFIG_PATA_NS87410 is not set --# CONFIG_PATA_NS87415 is not set --# CONFIG_PATA_OPTI is not set --# CONFIG_PATA_OPTIDMA is not set --# CONFIG_PATA_PDC_OLD is not set --# CONFIG_PATA_RADISYS is not set --# CONFIG_PATA_RZ1000 is not set --# CONFIG_PATA_SC1200 is not set --# CONFIG_PATA_SERVERWORKS is not set --# CONFIG_PATA_PDC2027X is not set --# CONFIG_PATA_SIL680 is not set --# CONFIG_PATA_SIS is not set --# CONFIG_PATA_VIA is not set --# CONFIG_PATA_WINBOND is not set --# CONFIG_PATA_PLATFORM is not set --# CONFIG_MD is not set --# CONFIG_FUSION is not set -- --# --# IEEE 1394 (FireWire) support --# --# CONFIG_FIREWIRE is not set --# CONFIG_IEEE1394 is not set --# CONFIG_I2O is not set --# CONFIG_MACINTOSH_DRIVERS is not set --CONFIG_NETDEVICES=y --# CONFIG_NETDEVICES_MULTIQUEUE is not set --# CONFIG_DUMMY is not set --# CONFIG_BONDING is not set --# CONFIG_MACVLAN is not set --# CONFIG_EQUALIZER is not set --# CONFIG_TUN is not set --# CONFIG_VETH is not set --# CONFIG_IP1000 is not set --# CONFIG_ARCNET is not set --# CONFIG_NET_ETHERNET is not set --CONFIG_NETDEV_1000=y --# CONFIG_ACENIC is not set --# CONFIG_DL2K is not set --# CONFIG_E1000 is not set --# CONFIG_E1000E 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 --# CONFIG_MV643XX_ETH is not set --# CONFIG_QLA3XXX is not set --# CONFIG_ATL1 is not set --CONFIG_NETDEV_10000=y --# CONFIG_CHELSIO_T1 is not set --# CONFIG_CHELSIO_T3 is not set --# CONFIG_IXGBE is not set --# CONFIG_IXGB is not set --# CONFIG_S2IO is not set --# CONFIG_MYRI10GE is not set --# CONFIG_NETXEN_NIC is not set --# CONFIG_NIU is not set --# CONFIG_MLX4_CORE is not set --# CONFIG_TEHUTI is not set --# CONFIG_TR is not set -- --# --# Wireless LAN --# --# CONFIG_WLAN_PRE80211 is not set --# CONFIG_WLAN_80211 is not set --# CONFIG_WAN is not set --# CONFIG_FDDI is not set --# CONFIG_HIPPI is not set --# CONFIG_PPP is not set --# CONFIG_SLIP is not set --# CONFIG_NET_FC 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 --# CONFIG_ISDN is not set --# CONFIG_PHONE is not set -- --# --# Input device support --# --# CONFIG_INPUT is not set -- --# --# Hardware I/O ports --# --# CONFIG_SERIO is not set --# CONFIG_GAMEPORT is not set -- --# --# Character devices --# --# CONFIG_VT is not set --# CONFIG_SERIAL_NONSTANDARD is not set -- --# --# Serial drivers --# --# CONFIG_SERIAL_8250 is not set -- --# --# Non-8250 serial port support --# --# CONFIG_SERIAL_UARTLITE is not set --CONFIG_SERIAL_CORE=y --CONFIG_SERIAL_CORE_CONSOLE=y --CONFIG_SERIAL_MPC52xx=y --CONFIG_SERIAL_MPC52xx_CONSOLE=y --CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=9600 --# CONFIG_SERIAL_JSM is not set --CONFIG_UNIX98_PTYS=y --CONFIG_LEGACY_PTYS=y --CONFIG_LEGACY_PTY_COUNT=256 --# CONFIG_IPMI_HANDLER is not set --# CONFIG_HW_RANDOM is not set --# CONFIG_NVRAM is not set --# CONFIG_GEN_RTC is not set --# CONFIG_R3964 is not set --# CONFIG_APPLICOM is not set --# CONFIG_RAW_DRIVER is not set --# CONFIG_TCG_TPM is not set --CONFIG_DEVPORT=y --# CONFIG_I2C is not set -- --# --# SPI support --# --# CONFIG_SPI is not set --# CONFIG_SPI_MASTER is not set --# CONFIG_W1 is not set --# CONFIG_POWER_SUPPLY is not set --# CONFIG_HWMON is not set --# CONFIG_WATCHDOG is not set -- --# --# Sonics Silicon Backplane --# --CONFIG_SSB_POSSIBLE=y --# CONFIG_SSB is not set -- --# --# Multifunction device drivers --# --# CONFIG_MFD_SM501 is not set -- --# --# Multimedia devices --# --# CONFIG_VIDEO_DEV is not set --# CONFIG_DVB_CORE is not set --# CONFIG_DAB is not set -- --# --# Graphics support --# --# CONFIG_AGP is not set --# CONFIG_DRM is not set --# CONFIG_VGASTATE is not set --CONFIG_VIDEO_OUTPUT_CONTROL=m --# CONFIG_FB is not set --# CONFIG_BACKLIGHT_LCD_SUPPORT is not set -- --# --# Display device support --# --# CONFIG_DISPLAY_SUPPORT is not set -- --# --# Sound --# --# CONFIG_SOUND is not set --CONFIG_USB_SUPPORT=y --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 --# CONFIG_MMC is not set --# CONFIG_NEW_LEDS is not set --# CONFIG_INFINIBAND is not set --# CONFIG_EDAC is not set --# CONFIG_RTC_CLASS is not set -- --# --# Userspace I/O --# --# CONFIG_UIO 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=y --CONFIG_EXT3_FS_XATTR=y --# CONFIG_EXT3_FS_POSIX_ACL is not set --# CONFIG_EXT3_FS_SECURITY is not set --# CONFIG_EXT4DEV_FS is not set --CONFIG_JBD=y --CONFIG_FS_MBCACHE=y --# 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_GFS2_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 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_MSDOS_FS is not set --# CONFIG_VFAT_FS is not set --# CONFIG_NTFS_FS is not set -- --# --# Pseudo filesystems --# --CONFIG_PROC_FS=y --CONFIG_PROC_KCORE=y --CONFIG_PROC_SYSCTL=y --CONFIG_SYSFS=y --CONFIG_TMPFS=y --# CONFIG_TMPFS_POSIX_ACL is not set --# CONFIG_HUGETLB_PAGE 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_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 --CONFIG_NETWORK_FILESYSTEMS=y --# CONFIG_NFS_FS is not set --# CONFIG_NFSD 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 -- --# --# Partition Types --# --# CONFIG_PARTITION_ADVANCED is not set --CONFIG_MSDOS_PARTITION=y --# CONFIG_NLS is not set --# CONFIG_DLM is not set --# CONFIG_UCC_SLOW is not set -- --# --# Library routines --# --# CONFIG_CRC_CCITT is not set --# CONFIG_CRC16 is not set --# CONFIG_CRC_ITU_T is not set --# CONFIG_CRC32 is not set --# CONFIG_CRC7 is not set --# CONFIG_LIBCRC32C is not set --CONFIG_PLIST=y --CONFIG_HAS_IOMEM=y --CONFIG_HAS_IOPORT=y --CONFIG_HAS_DMA=y --# CONFIG_INSTRUMENTATION is not set -- --# --# Kernel hacking --# --CONFIG_PRINTK_TIME=y --CONFIG_ENABLE_WARN_DEPRECATED=y --CONFIG_ENABLE_MUST_CHECK=y --# CONFIG_MAGIC_SYSRQ is not set --# CONFIG_UNUSED_SYMBOLS is not set --# CONFIG_DEBUG_FS is not set --# CONFIG_HEADERS_CHECK is not set --CONFIG_DEBUG_KERNEL=y --# CONFIG_DEBUG_SHIRQ is not set --CONFIG_DETECT_SOFTLOCKUP=y --CONFIG_SCHED_DEBUG=y --# CONFIG_SCHEDSTATS is not set --# CONFIG_TIMER_STATS is not set --# CONFIG_SLUB_DEBUG_ON is not set --# CONFIG_DEBUG_RT_MUTEXES is not set --# CONFIG_RT_MUTEX_TESTER is not set --# CONFIG_DEBUG_SPINLOCK is not set --# CONFIG_DEBUG_MUTEXES is not set --# CONFIG_DEBUG_SPINLOCK_SLEEP is not set --# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set --# CONFIG_DEBUG_KOBJECT is not set --# CONFIG_DEBUG_BUGVERBOSE is not set --CONFIG_DEBUG_INFO=y --# CONFIG_DEBUG_VM is not set --# CONFIG_DEBUG_LIST is not set --# CONFIG_DEBUG_SG is not set --CONFIG_FORCED_INLINING=y --# CONFIG_BOOT_PRINTK_DELAY is not set --# CONFIG_RCU_TORTURE_TEST is not set --# CONFIG_FAULT_INJECTION is not set --# CONFIG_SAMPLES is not set --# CONFIG_DEBUG_STACKOVERFLOW is not set --# CONFIG_DEBUG_STACK_USAGE is not set --# CONFIG_DEBUG_PAGEALLOC is not set --# CONFIG_DEBUGGER is not set --# CONFIG_BDI_SWITCH is not set --# CONFIG_BOOTX_TEXT is not set --# CONFIG_PPC_EARLY_DEBUG is not set -- --# --# Security options --# --# CONFIG_KEYS is not set --# CONFIG_SECURITY is not set --# CONFIG_SECURITY_FILE_CAPABILITIES is not set --# CONFIG_CRYPTO is not set --CONFIG_PPC_CLOCK=y --CONFIG_PPC_LIB_RHEAP=y ---- /dev/null -+++ b/arch/powerpc/configs/makalu_defconfig -@@ -0,0 +1,812 @@ -+# -+# Automatically generated make config: don't edit -+# Linux kernel version: 2.6.24-rc6 -+# Mon Dec 24 11:18:32 2007 -+# -+# CONFIG_PPC64 is not set -+ -+# -+# Processor support -+# -+# CONFIG_6xx is not set -+# CONFIG_PPC_85xx is not set -+# CONFIG_PPC_8xx is not set -+CONFIG_40x=y -+# CONFIG_44x is not set -+# CONFIG_E200 is not set -+CONFIG_4xx=y -+# CONFIG_PPC_MM_SLICES is not set -+CONFIG_NOT_COHERENT_CACHE=y -+CONFIG_PPC32=y -+CONFIG_WORD_SIZE=32 -+CONFIG_PPC_MERGE=y -+CONFIG_MMU=y -+CONFIG_GENERIC_CMOS_UPDATE=y -+CONFIG_GENERIC_TIME=y -+CONFIG_GENERIC_TIME_VSYSCALL=y -+CONFIG_GENERIC_CLOCKEVENTS=y -+CONFIG_GENERIC_HARDIRQS=y -+CONFIG_IRQ_PER_CPU=y -+CONFIG_RWSEM_XCHGADD_ALGORITHM=y -+CONFIG_ARCH_HAS_ILOG2_U32=y -+CONFIG_GENERIC_HWEIGHT=y -+CONFIG_GENERIC_CALIBRATE_DELAY=y -+CONFIG_GENERIC_FIND_NEXT_BIT=y -+# CONFIG_ARCH_NO_VIRT_TO_BUS is not set -+CONFIG_PPC=y -+CONFIG_EARLY_PRINTK=y -+CONFIG_GENERIC_NVRAM=y -+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -+CONFIG_ARCH_MAY_HAVE_PC_FDC=y -+CONFIG_PPC_OF=y -+CONFIG_OF=y -+CONFIG_PPC_UDBG_16550=y -+# CONFIG_GENERIC_TBSYNC is not set -+CONFIG_AUDIT_ARCH=y -+CONFIG_GENERIC_BUG=y -+# CONFIG_DEFAULT_UIMAGE is not set -+CONFIG_PPC_DCR_NATIVE=y -+# CONFIG_PPC_DCR_MMIO is not set -+CONFIG_PPC_DCR=y -+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" -+ -+# -+# General setup -+# -+CONFIG_EXPERIMENTAL=y -+CONFIG_BROKEN_ON_SMP=y -+CONFIG_INIT_ENV_ARG_LIMIT=32 -+CONFIG_LOCALVERSION="" -+CONFIG_LOCALVERSION_AUTO=y -+CONFIG_SWAP=y -+CONFIG_SYSVIPC=y -+CONFIG_SYSVIPC_SYSCTL=y -+CONFIG_POSIX_MQUEUE=y -+# CONFIG_BSD_PROCESS_ACCT is not set -+# CONFIG_TASKSTATS is not set -+# CONFIG_USER_NS is not set -+# CONFIG_PID_NS is not set -+# CONFIG_AUDIT is not set -+# CONFIG_IKCONFIG is not set -+CONFIG_LOG_BUF_SHIFT=14 -+# CONFIG_CGROUPS is not set -+# CONFIG_FAIR_GROUP_SCHED is not set -+CONFIG_SYSFS_DEPRECATED=y -+# CONFIG_RELAY is not set -+CONFIG_BLK_DEV_INITRD=y -+CONFIG_INITRAMFS_SOURCE="" -+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -+CONFIG_SYSCTL=y -+CONFIG_EMBEDDED=y -+CONFIG_SYSCTL_SYSCALL=y -+CONFIG_KALLSYMS=y -+CONFIG_KALLSYMS_ALL=y -+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_ANON_INODES=y -+CONFIG_EPOLL=y -+CONFIG_SIGNALFD=y -+CONFIG_EVENTFD=y -+CONFIG_SHMEM=y -+CONFIG_VM_EVENT_COUNTERS=y -+CONFIG_SLUB_DEBUG=y -+# CONFIG_SLAB is not set -+CONFIG_SLUB=y -+# CONFIG_SLOB is not set -+CONFIG_RT_MUTEXES=y -+# CONFIG_TINY_SHMEM is not set -+CONFIG_BASE_SMALL=0 -+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 -+CONFIG_BLOCK=y -+CONFIG_LBD=y -+# CONFIG_BLK_DEV_IO_TRACE is not set -+# CONFIG_LSF is not set -+# CONFIG_BLK_DEV_BSG is not set -+ -+# -+# IO Schedulers -+# -+CONFIG_IOSCHED_NOOP=y -+CONFIG_IOSCHED_AS=y -+CONFIG_IOSCHED_DEADLINE=y -+CONFIG_IOSCHED_CFQ=y -+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" -+CONFIG_PPC4xx_PCI_EXPRESS=y -+ -+# -+# Platform support -+# -+# CONFIG_PPC_MPC52xx is not set -+# CONFIG_PPC_MPC5200 is not set -+# CONFIG_PPC_CELL is not set -+# CONFIG_PPC_CELL_NATIVE is not set -+# CONFIG_PQ2ADS is not set -+# CONFIG_EP405 is not set -+# CONFIG_KILAUEA is not set -+CONFIG_MAKALU=y -+# CONFIG_WALNUT is not set -+# CONFIG_XILINX_VIRTEX_GENERIC_BOARD is not set -+CONFIG_405EX=y -+# CONFIG_MPIC is not set -+# CONFIG_MPIC_WEIRD is not set -+# CONFIG_PPC_I8259 is not set -+# CONFIG_PPC_RTAS is not set -+# CONFIG_MMIO_NVRAM is not set -+# CONFIG_PPC_MPC106 is not set -+# CONFIG_PPC_970_NAP is not set -+# CONFIG_PPC_INDIRECT_IO is not set -+# CONFIG_GENERIC_IOMAP is not set -+# CONFIG_CPU_FREQ is not set -+# CONFIG_CPM2 is not set -+# CONFIG_FSL_ULI1575 is not set -+ -+# -+# Kernel options -+# -+# CONFIG_HIGHMEM is not set -+# CONFIG_TICK_ONESHOT is not set -+# CONFIG_NO_HZ is not set -+# CONFIG_HIGH_RES_TIMERS is not set -+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y -+# CONFIG_HZ_100 is not set -+CONFIG_HZ_250=y -+# CONFIG_HZ_300 is not set -+# CONFIG_HZ_1000 is not set -+CONFIG_HZ=250 -+CONFIG_PREEMPT_NONE=y -+# CONFIG_PREEMPT_VOLUNTARY is not set -+# CONFIG_PREEMPT is not set -+CONFIG_BINFMT_ELF=y -+# CONFIG_BINFMT_MISC is not set -+# CONFIG_MATH_EMULATION is not set -+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y -+CONFIG_ARCH_FLATMEM_ENABLE=y -+CONFIG_ARCH_POPULATES_NODE_MAP=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 is not set -+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set -+CONFIG_SPLIT_PTLOCK_CPUS=4 -+# CONFIG_RESOURCES_64BIT is not set -+CONFIG_ZONE_DMA_FLAG=1 -+CONFIG_BOUNCE=y -+CONFIG_VIRT_TO_BUS=y -+CONFIG_PROC_DEVICETREE=y -+# CONFIG_CMDLINE_BOOL is not set -+# CONFIG_PM is not set -+CONFIG_SUSPEND_UP_POSSIBLE=y -+CONFIG_HIBERNATION_UP_POSSIBLE=y -+CONFIG_SECCOMP=y -+CONFIG_WANT_DEVICE_TREE=y -+CONFIG_DEVICE_TREE="kilauea.dts" -+CONFIG_ISA_DMA_API=y -+ -+# -+# Bus options -+# -+CONFIG_ZONE_DMA=y -+CONFIG_PPC_INDIRECT_PCI=y -+CONFIG_PCI=y -+CONFIG_PCI_DOMAINS=y -+CONFIG_PCI_SYSCALL=y -+# CONFIG_PCIEPORTBUS is not set -+CONFIG_ARCH_SUPPORTS_MSI=y -+# CONFIG_PCI_MSI is not set -+CONFIG_PCI_LEGACY=y -+# CONFIG_PCI_DEBUG is not set -+# CONFIG_PCCARD is not set -+# CONFIG_HOTPLUG_PCI is not set -+ -+# -+# Advanced setup -+# -+# CONFIG_ADVANCED_OPTIONS is not set -+ -+# -+# Default settings for advanced configuration options are used -+# -+CONFIG_HIGHMEM_START=0xfe000000 -+CONFIG_LOWMEM_SIZE=0x30000000 -+CONFIG_KERNEL_START=0xc0000000 -+CONFIG_TASK_SIZE=0xc0000000 -+CONFIG_CONSISTENT_START=0xff100000 -+CONFIG_CONSISTENT_SIZE=0x00200000 -+CONFIG_BOOT_LOAD=0x00400000 -+ -+# -+# Networking -+# -+CONFIG_NET=y -+ -+# -+# Networking options -+# -+CONFIG_PACKET=y -+# CONFIG_PACKET_MMAP is not set -+CONFIG_UNIX=y -+# CONFIG_NET_KEY is not set -+CONFIG_INET=y -+# CONFIG_IP_MULTICAST is not set -+# 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_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 is not set -+# CONFIG_INET_XFRM_MODE_TUNNEL is not set -+# CONFIG_INET_XFRM_MODE_BEET is not set -+# CONFIG_INET_LRO is not set -+CONFIG_INET_DIAG=y -+CONFIG_INET_TCP_DIAG=y -+# CONFIG_TCP_CONG_ADVANCED is not set -+CONFIG_TCP_CONG_CUBIC=y -+CONFIG_DEFAULT_TCP_CONG="cubic" -+# CONFIG_TCP_MD5SIG is not set -+# 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 -+# CONFIG_IP_DCCP is not set -+# CONFIG_IP_SCTP is not set -+# 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_ECONET is not set -+# CONFIG_WAN_ROUTER is not set -+# 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_AF_RXRPC is not set -+ -+# -+# Wireless -+# -+# CONFIG_CFG80211 is not set -+# CONFIG_WIRELESS_EXT is not set -+# CONFIG_MAC80211 is not set -+# CONFIG_IEEE80211 is not set -+# CONFIG_RFKILL is not set -+# CONFIG_NET_9P is not set -+ -+# -+# Device Drivers -+# -+ -+# -+# Generic Driver Options -+# -+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -+CONFIG_STANDALONE=y -+CONFIG_PREVENT_FIRMWARE_BUILD=y -+CONFIG_FW_LOADER=y -+# CONFIG_DEBUG_DRIVER is not set -+# CONFIG_DEBUG_DEVRES is not set -+# CONFIG_SYS_HYPERVISOR is not set -+CONFIG_CONNECTOR=y -+CONFIG_PROC_EVENTS=y -+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 -+ -+# -+# User Modules And Translation Layers -+# -+CONFIG_MTD_CHAR=y -+CONFIG_MTD_BLKDEVS=m -+CONFIG_MTD_BLOCK=m -+# 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 -+# CONFIG_SSFDC is not set -+# CONFIG_MTD_OOPS is not set -+ -+# -+# RAM/ROM/Flash chip drivers -+# -+CONFIG_MTD_CFI=y -+CONFIG_MTD_JEDECPROBE=y -+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 is not set -+CONFIG_MTD_CFI_AMDSTD=y -+# 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 -+ -+# -+# Mapping drivers for chip access -+# -+# CONFIG_MTD_COMPLEX_MAPPINGS is not set -+# CONFIG_MTD_PHYSMAP is not set -+CONFIG_MTD_PHYSMAP_OF=y -+# CONFIG_MTD_INTEL_VR_NOR is not set -+# CONFIG_MTD_PLATRAM is not set -+ -+# -+# Self-contained MTD device drivers -+# -+# CONFIG_MTD_PMC551 is not set -+# 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 -+# CONFIG_MTD_NAND is not set -+# CONFIG_MTD_ONENAND is not set -+ -+# -+# UBI - Unsorted block images -+# -+# CONFIG_MTD_UBI is not set -+CONFIG_OF_DEVICE=y -+# CONFIG_PARPORT is not set -+CONFIG_BLK_DEV=y -+# 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 is not set -+# CONFIG_BLK_DEV_NBD is not set -+# CONFIG_BLK_DEV_SX8 is not set -+CONFIG_BLK_DEV_RAM=y -+CONFIG_BLK_DEV_RAM_COUNT=16 -+CONFIG_BLK_DEV_RAM_SIZE=35000 -+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 -+# CONFIG_CDROM_PKTCDVD is not set -+# CONFIG_ATA_OVER_ETH is not set -+# CONFIG_XILINX_SYSACE is not set -+# CONFIG_MISC_DEVICES is not set -+# CONFIG_IDE is not set -+ -+# -+# SCSI device support -+# -+# CONFIG_RAID_ATTRS is not set -+# CONFIG_SCSI is not set -+# CONFIG_SCSI_DMA is not set -+# CONFIG_SCSI_NETLINK is not set -+# CONFIG_ATA is not set -+# CONFIG_MD is not set -+# CONFIG_FUSION is not set -+ -+# -+# IEEE 1394 (FireWire) support -+# -+# CONFIG_FIREWIRE is not set -+# CONFIG_IEEE1394 is not set -+# CONFIG_I2O is not set -+# CONFIG_MACINTOSH_DRIVERS is not set -+CONFIG_NETDEVICES=y -+# CONFIG_NETDEVICES_MULTIQUEUE is not set -+# CONFIG_DUMMY is not set -+# CONFIG_BONDING is not set -+# CONFIG_MACVLAN is not set -+# CONFIG_EQUALIZER is not set -+# CONFIG_TUN is not set -+# CONFIG_VETH is not set -+# CONFIG_IP1000 is not set -+# CONFIG_ARCNET is not set -+# CONFIG_PHYLIB is not set -+CONFIG_NET_ETHERNET=y -+# CONFIG_MII is not set -+# CONFIG_HAPPYMEAL is not set -+# CONFIG_SUNGEM is not set -+# CONFIG_CASSINI is not set -+# CONFIG_NET_VENDOR_3COM is not set -+# CONFIG_NET_TULIP is not set -+# CONFIG_HP100 is not set -+CONFIG_IBM_NEW_EMAC=y -+CONFIG_IBM_NEW_EMAC_RXB=256 -+CONFIG_IBM_NEW_EMAC_TXB=256 -+CONFIG_IBM_NEW_EMAC_POLL_WEIGHT=32 -+CONFIG_IBM_NEW_EMAC_RX_COPY_THRESHOLD=256 -+CONFIG_IBM_NEW_EMAC_RX_SKB_HEADROOM=0 -+# CONFIG_IBM_NEW_EMAC_DEBUG is not set -+# CONFIG_IBM_NEW_EMAC_ZMII is not set -+CONFIG_IBM_NEW_EMAC_RGMII=y -+# CONFIG_IBM_NEW_EMAC_TAH is not set -+CONFIG_IBM_NEW_EMAC_EMAC4=y -+# CONFIG_NET_PCI is not set -+# CONFIG_B44 is not set -+# CONFIG_NETDEV_1000 is not set -+# CONFIG_NETDEV_10000 is not set -+# CONFIG_TR is not set -+ -+# -+# Wireless LAN -+# -+# CONFIG_WLAN_PRE80211 is not set -+# CONFIG_WLAN_80211 is not set -+# CONFIG_WAN is not set -+# CONFIG_FDDI is not set -+# CONFIG_HIPPI 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 -+# CONFIG_ISDN is not set -+# CONFIG_PHONE is not set -+ -+# -+# Input device support -+# -+# CONFIG_INPUT is not set -+ -+# -+# Hardware I/O ports -+# -+# CONFIG_SERIO is not set -+# CONFIG_GAMEPORT is not set -+ -+# -+# Character devices -+# -+# CONFIG_VT is not set -+# 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 is not set -+CONFIG_SERIAL_8250_SHARE_IRQ=y -+# CONFIG_SERIAL_8250_DETECT_IRQ is not set -+# CONFIG_SERIAL_8250_RSA is not set -+ -+# -+# Non-8250 serial port support -+# -+# CONFIG_SERIAL_UARTLITE is not set -+CONFIG_SERIAL_CORE=y -+CONFIG_SERIAL_CORE_CONSOLE=y -+# CONFIG_SERIAL_JSM is not set -+CONFIG_SERIAL_OF_PLATFORM=y -+CONFIG_UNIX98_PTYS=y -+CONFIG_LEGACY_PTYS=y -+CONFIG_LEGACY_PTY_COUNT=256 -+# CONFIG_IPMI_HANDLER is not set -+# CONFIG_HW_RANDOM is not set -+# CONFIG_NVRAM is not set -+# CONFIG_GEN_RTC is not set -+# CONFIG_R3964 is not set -+# CONFIG_APPLICOM is not set -+# CONFIG_RAW_DRIVER is not set -+# CONFIG_TCG_TPM is not set -+CONFIG_DEVPORT=y -+# CONFIG_I2C is not set -+ -+# -+# SPI support -+# -+# CONFIG_SPI is not set -+# CONFIG_SPI_MASTER is not set -+# CONFIG_W1 is not set -+# CONFIG_POWER_SUPPLY is not set -+# CONFIG_HWMON is not set -+# CONFIG_WATCHDOG is not set -+ -+# -+# Sonics Silicon Backplane -+# -+CONFIG_SSB_POSSIBLE=y -+# CONFIG_SSB is not set -+ -+# -+# Multifunction device drivers -+# -+# CONFIG_MFD_SM501 is not set -+ -+# -+# Multimedia devices -+# -+# CONFIG_VIDEO_DEV is not set -+# CONFIG_DVB_CORE is not set -+# CONFIG_DAB is not set -+ -+# -+# Graphics support -+# -+# CONFIG_AGP is not set -+# CONFIG_DRM is not set -+# CONFIG_VGASTATE is not set -+# CONFIG_VIDEO_OUTPUT_CONTROL is not set -+# CONFIG_FB is not set -+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set -+ -+# -+# Display device support -+# -+# CONFIG_DISPLAY_SUPPORT is not set -+ -+# -+# Sound -+# -+# CONFIG_SOUND is not set -+# CONFIG_USB_SUPPORT is not set -+# CONFIG_MMC is not set -+# CONFIG_NEW_LEDS is not set -+# CONFIG_INFINIBAND is not set -+# CONFIG_EDAC is not set -+# CONFIG_RTC_CLASS is not set -+ -+# -+# Userspace I/O -+# -+# CONFIG_UIO 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_EXT4DEV_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_GFS2_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 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_MSDOS_FS is not set -+# CONFIG_VFAT_FS is not set -+# CONFIG_NTFS_FS is not set -+ -+# -+# Pseudo filesystems -+# -+CONFIG_PROC_FS=y -+CONFIG_PROC_KCORE=y -+CONFIG_PROC_SYSCTL=y -+CONFIG_SYSFS=y -+CONFIG_TMPFS=y -+# CONFIG_TMPFS_POSIX_ACL is not set -+# CONFIG_HUGETLB_PAGE 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_JFFS2_FS is not set -+CONFIG_CRAMFS=y -+# 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 -+CONFIG_NETWORK_FILESYSTEMS=y -+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_SUNRPC_BIND34 is not set -+# 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 -+ -+# -+# Partition Types -+# -+# CONFIG_PARTITION_ADVANCED is not set -+CONFIG_MSDOS_PARTITION=y -+# CONFIG_NLS is not set -+# CONFIG_DLM is not set -+# CONFIG_UCC_SLOW is not set -+ -+# -+# Library routines -+# -+CONFIG_BITREVERSE=y -+# CONFIG_CRC_CCITT is not set -+# CONFIG_CRC16 is not set -+# CONFIG_CRC_ITU_T is not set -+CONFIG_CRC32=y -+# CONFIG_CRC7 is not set -+# CONFIG_LIBCRC32C is not set -+CONFIG_ZLIB_INFLATE=y -+CONFIG_PLIST=y -+CONFIG_HAS_IOMEM=y -+CONFIG_HAS_IOPORT=y -+CONFIG_HAS_DMA=y -+# CONFIG_INSTRUMENTATION is not set -+ -+# -+# Kernel hacking -+# -+# CONFIG_PRINTK_TIME is not set -+CONFIG_ENABLE_WARN_DEPRECATED=y -+CONFIG_ENABLE_MUST_CHECK=y -+CONFIG_MAGIC_SYSRQ=y -+# CONFIG_UNUSED_SYMBOLS is not set -+# CONFIG_DEBUG_FS is not set -+# CONFIG_HEADERS_CHECK is not set -+CONFIG_DEBUG_KERNEL=y -+# CONFIG_DEBUG_SHIRQ is not set -+CONFIG_DETECT_SOFTLOCKUP=y -+CONFIG_SCHED_DEBUG=y -+# CONFIG_SCHEDSTATS is not set -+# CONFIG_TIMER_STATS is not set -+# CONFIG_SLUB_DEBUG_ON is not set -+# CONFIG_DEBUG_RT_MUTEXES is not set -+# CONFIG_RT_MUTEX_TESTER is not set -+# CONFIG_DEBUG_SPINLOCK is not set -+# CONFIG_DEBUG_MUTEXES is not set -+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -+# CONFIG_DEBUG_KOBJECT is not set -+CONFIG_DEBUG_BUGVERBOSE=y -+# CONFIG_DEBUG_INFO is not set -+# CONFIG_DEBUG_VM is not set -+# CONFIG_DEBUG_LIST is not set -+# CONFIG_DEBUG_SG is not set -+CONFIG_FORCED_INLINING=y -+# CONFIG_BOOT_PRINTK_DELAY is not set -+# CONFIG_RCU_TORTURE_TEST is not set -+# CONFIG_FAULT_INJECTION is not set -+# CONFIG_SAMPLES is not set -+# CONFIG_DEBUG_STACKOVERFLOW is not set -+# CONFIG_DEBUG_STACK_USAGE is not set -+# CONFIG_DEBUG_PAGEALLOC is not set -+# CONFIG_DEBUGGER is not set -+# CONFIG_BDI_SWITCH is not set -+# CONFIG_PPC_EARLY_DEBUG is not set -+ -+# -+# Security options -+# -+# CONFIG_KEYS is not set -+# CONFIG_SECURITY is not set -+# CONFIG_SECURITY_FILE_CAPABILITIES is not set -+CONFIG_CRYPTO=y -+CONFIG_CRYPTO_ALGAPI=y -+CONFIG_CRYPTO_BLKCIPHER=y -+CONFIG_CRYPTO_MANAGER=y -+# CONFIG_CRYPTO_HMAC is not set -+# CONFIG_CRYPTO_XCBC is not set -+# CONFIG_CRYPTO_NULL is not set -+# CONFIG_CRYPTO_MD4 is not set -+CONFIG_CRYPTO_MD5=y -+# CONFIG_CRYPTO_SHA1 is not set -+# 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_GF128MUL is not set -+CONFIG_CRYPTO_ECB=y -+CONFIG_CRYPTO_CBC=y -+CONFIG_CRYPTO_PCBC=y -+# CONFIG_CRYPTO_LRW is not set -+# CONFIG_CRYPTO_XTS is not set -+# CONFIG_CRYPTO_CRYPTD is not set -+CONFIG_CRYPTO_DES=y -+# CONFIG_CRYPTO_FCRYPT is not set -+# 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_SEED is not set -+# CONFIG_CRYPTO_DEFLATE is not set -+# CONFIG_CRYPTO_MICHAEL_MIC is not set -+# CONFIG_CRYPTO_CRC32C is not set -+# CONFIG_CRYPTO_CAMELLIA is not set -+# CONFIG_CRYPTO_TEST is not set -+# CONFIG_CRYPTO_AUTHENC is not set -+CONFIG_CRYPTO_HW=y -+# CONFIG_PPC_CLOCK is not set ---- /dev/null -+++ b/arch/powerpc/configs/mpc5200_defconfig -@@ -0,0 +1,1286 @@ -+# -+# Automatically generated make config: don't edit -+# Linux kernel version: 2.6.24-rc6 -+# Fri Jan 18 14:19:54 2008 -+# -+# CONFIG_PPC64 is not set -+ -+# -+# Processor support -+# -+CONFIG_6xx=y -+# CONFIG_PPC_85xx is not set -+# CONFIG_PPC_8xx is not set -+# CONFIG_40x is not set -+# CONFIG_44x is not set -+# CONFIG_E200 is not set -+CONFIG_PPC_FPU=y -+# CONFIG_ALTIVEC is not set -+CONFIG_PPC_STD_MMU=y -+CONFIG_PPC_STD_MMU_32=y -+# CONFIG_PPC_MM_SLICES is not set -+# CONFIG_SMP is not set -+CONFIG_PPC32=y -+CONFIG_WORD_SIZE=32 -+CONFIG_PPC_MERGE=y -+CONFIG_MMU=y -+CONFIG_GENERIC_CMOS_UPDATE=y -+CONFIG_GENERIC_TIME=y -+CONFIG_GENERIC_TIME_VSYSCALL=y -+CONFIG_GENERIC_CLOCKEVENTS=y -+CONFIG_GENERIC_HARDIRQS=y -+CONFIG_IRQ_PER_CPU=y -+CONFIG_RWSEM_XCHGADD_ALGORITHM=y -+CONFIG_ARCH_HAS_ILOG2_U32=y -+CONFIG_GENERIC_HWEIGHT=y -+CONFIG_GENERIC_CALIBRATE_DELAY=y -+CONFIG_GENERIC_FIND_NEXT_BIT=y -+# CONFIG_ARCH_NO_VIRT_TO_BUS is not set -+CONFIG_PPC=y -+CONFIG_EARLY_PRINTK=y -+CONFIG_GENERIC_NVRAM=y -+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -+CONFIG_ARCH_MAY_HAVE_PC_FDC=y -+CONFIG_PPC_OF=y -+CONFIG_OF=y -+# CONFIG_PPC_UDBG_16550 is not set -+# CONFIG_GENERIC_TBSYNC is not set -+CONFIG_AUDIT_ARCH=y -+CONFIG_GENERIC_BUG=y -+# CONFIG_DEFAULT_UIMAGE is not set -+# CONFIG_PPC_DCR_NATIVE is not set -+# CONFIG_PPC_DCR_MMIO is not set -+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" -+ -+# -+# General setup -+# -+CONFIG_EXPERIMENTAL=y -+CONFIG_BROKEN_ON_SMP=y -+CONFIG_INIT_ENV_ARG_LIMIT=32 -+CONFIG_LOCALVERSION="" -+CONFIG_LOCALVERSION_AUTO=y -+CONFIG_SWAP=y -+CONFIG_SYSVIPC=y -+CONFIG_SYSVIPC_SYSCTL=y -+# CONFIG_POSIX_MQUEUE is not set -+# CONFIG_BSD_PROCESS_ACCT is not set -+# CONFIG_TASKSTATS is not set -+# CONFIG_USER_NS is not set -+# CONFIG_PID_NS is not set -+# CONFIG_AUDIT is not set -+# CONFIG_IKCONFIG is not set -+CONFIG_LOG_BUF_SHIFT=14 -+# CONFIG_CGROUPS is not set -+CONFIG_FAIR_GROUP_SCHED=y -+CONFIG_FAIR_USER_SCHED=y -+# CONFIG_FAIR_CGROUP_SCHED is not set -+CONFIG_SYSFS_DEPRECATED=y -+# CONFIG_RELAY is not set -+CONFIG_BLK_DEV_INITRD=y -+CONFIG_INITRAMFS_SOURCE="" -+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -+CONFIG_SYSCTL=y -+CONFIG_EMBEDDED=y -+# CONFIG_SYSCTL_SYSCALL is not set -+# CONFIG_KALLSYMS is not set -+CONFIG_HOTPLUG=y -+CONFIG_PRINTK=y -+CONFIG_BUG=y -+CONFIG_ELF_CORE=y -+CONFIG_BASE_FULL=y -+CONFIG_FUTEX=y -+CONFIG_ANON_INODES=y -+# CONFIG_EPOLL is not set -+CONFIG_SIGNALFD=y -+CONFIG_EVENTFD=y -+CONFIG_SHMEM=y -+CONFIG_VM_EVENT_COUNTERS=y -+CONFIG_SLUB_DEBUG=y -+# CONFIG_SLAB is not set -+CONFIG_SLUB=y -+# CONFIG_SLOB is not set -+CONFIG_RT_MUTEXES=y -+# CONFIG_TINY_SHMEM is not set -+CONFIG_BASE_SMALL=0 -+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 is not set -+CONFIG_BLOCK=y -+# CONFIG_LBD is not set -+# CONFIG_BLK_DEV_IO_TRACE is not set -+# CONFIG_LSF is not set -+# CONFIG_BLK_DEV_BSG is not set -+ -+# -+# IO Schedulers -+# -+CONFIG_IOSCHED_NOOP=y -+CONFIG_IOSCHED_AS=y -+CONFIG_IOSCHED_DEADLINE=y -+CONFIG_IOSCHED_CFQ=y -+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" -+ -+# -+# Platform support -+# -+CONFIG_PPC_MULTIPLATFORM=y -+# CONFIG_PPC_82xx is not set -+# CONFIG_PPC_83xx is not set -+# CONFIG_PPC_86xx is not set -+CONFIG_CLASSIC32=y -+# CONFIG_PPC_CHRP is not set -+CONFIG_PPC_MPC52xx=y -+CONFIG_PPC_MPC5200=y -+CONFIG_PPC_MPC5200_BUGFIX=y -+CONFIG_PPC_MPC5200_SIMPLE=y -+CONFIG_PPC_EFIKA=y -+CONFIG_PPC_LITE5200=y -+# CONFIG_PPC_PMAC is not set -+# CONFIG_PPC_CELL is not set -+# CONFIG_PPC_CELL_NATIVE is not set -+# CONFIG_PQ2ADS is not set -+# CONFIG_EMBEDDED6xx is not set -+CONFIG_PPC_NATIVE=y -+# CONFIG_UDBG_RTAS_CONSOLE is not set -+# CONFIG_MPIC is not set -+# CONFIG_MPIC_WEIRD is not set -+# CONFIG_PPC_I8259 is not set -+CONFIG_PPC_RTAS=y -+# CONFIG_RTAS_ERROR_LOGGING is not set -+CONFIG_RTAS_PROC=y -+# CONFIG_MMIO_NVRAM is not set -+# CONFIG_PPC_MPC106 is not set -+# CONFIG_PPC_970_NAP is not set -+# CONFIG_PPC_INDIRECT_IO is not set -+# CONFIG_GENERIC_IOMAP is not set -+# CONFIG_CPU_FREQ is not set -+# CONFIG_TAU is not set -+# CONFIG_CPM2 is not set -+# CONFIG_FSL_ULI1575 is not set -+CONFIG_PPC_BESTCOMM=y -+CONFIG_PPC_BESTCOMM_ATA=y -+CONFIG_PPC_BESTCOMM_FEC=y -+CONFIG_PPC_BESTCOMM_GEN_BD=y -+ -+# -+# Kernel options -+# -+# CONFIG_HIGHMEM is not set -+CONFIG_TICK_ONESHOT=y -+CONFIG_NO_HZ=y -+CONFIG_HIGH_RES_TIMERS=y -+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y -+# CONFIG_HZ_100 is not set -+CONFIG_HZ_250=y -+# CONFIG_HZ_300 is not set -+# CONFIG_HZ_1000 is not set -+CONFIG_HZ=250 -+CONFIG_PREEMPT_NONE=y -+# CONFIG_PREEMPT_VOLUNTARY is not set -+# CONFIG_PREEMPT is not set -+CONFIG_BINFMT_ELF=y -+# CONFIG_BINFMT_MISC is not set -+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y -+# CONFIG_KEXEC is not set -+CONFIG_ARCH_FLATMEM_ENABLE=y -+CONFIG_ARCH_POPULATES_NODE_MAP=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 is not set -+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set -+CONFIG_SPLIT_PTLOCK_CPUS=4 -+# CONFIG_RESOURCES_64BIT is not set -+CONFIG_ZONE_DMA_FLAG=1 -+CONFIG_BOUNCE=y -+CONFIG_VIRT_TO_BUS=y -+CONFIG_PROC_DEVICETREE=y -+# CONFIG_CMDLINE_BOOL is not set -+CONFIG_PM=y -+# CONFIG_PM_LEGACY is not set -+# CONFIG_PM_DEBUG is not set -+CONFIG_PM_SLEEP=y -+CONFIG_SUSPEND_UP_POSSIBLE=y -+CONFIG_SUSPEND=y -+CONFIG_HIBERNATION_UP_POSSIBLE=y -+# CONFIG_HIBERNATION is not set -+CONFIG_SECCOMP=y -+CONFIG_WANT_DEVICE_TREE=y -+CONFIG_DEVICE_TREE="" -+CONFIG_ISA_DMA_API=y -+ -+# -+# Bus options -+# -+CONFIG_ZONE_DMA=y -+CONFIG_GENERIC_ISA_DMA=y -+# CONFIG_PPC_INDIRECT_PCI is not set -+CONFIG_FSL_SOC=y -+CONFIG_PCI=y -+CONFIG_PCI_DOMAINS=y -+CONFIG_PCI_SYSCALL=y -+# CONFIG_PCIEPORTBUS is not set -+CONFIG_ARCH_SUPPORTS_MSI=y -+# CONFIG_PCI_MSI is not set -+CONFIG_PCI_LEGACY=y -+# CONFIG_PCI_DEBUG is not set -+# CONFIG_PCCARD is not set -+# CONFIG_HOTPLUG_PCI is not set -+ -+# -+# Advanced setup -+# -+# CONFIG_ADVANCED_OPTIONS is not set -+ -+# -+# Default settings for advanced configuration options are used -+# -+CONFIG_HIGHMEM_START=0xfe000000 -+CONFIG_LOWMEM_SIZE=0x30000000 -+CONFIG_KERNEL_START=0xc0000000 -+CONFIG_TASK_SIZE=0xc0000000 -+CONFIG_BOOT_LOAD=0x00800000 -+ -+# -+# Networking -+# -+CONFIG_NET=y -+ -+# -+# Networking options -+# -+CONFIG_PACKET=y -+# CONFIG_PACKET_MMAP is not set -+CONFIG_UNIX=y -+CONFIG_XFRM=y -+CONFIG_XFRM_USER=m -+# CONFIG_XFRM_SUB_POLICY is not set -+# CONFIG_XFRM_MIGRATE 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=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_XFRM_MODE_TRANSPORT=y -+CONFIG_INET_XFRM_MODE_TUNNEL=y -+CONFIG_INET_XFRM_MODE_BEET=y -+# CONFIG_INET_LRO is not set -+CONFIG_INET_DIAG=y -+CONFIG_INET_TCP_DIAG=y -+# CONFIG_TCP_CONG_ADVANCED is not set -+CONFIG_TCP_CONG_CUBIC=y -+CONFIG_DEFAULT_TCP_CONG="cubic" -+# CONFIG_TCP_MD5SIG is not set -+# 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 -+# CONFIG_IP_DCCP is not set -+# CONFIG_IP_SCTP is not set -+# 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_ECONET is not set -+# CONFIG_WAN_ROUTER is not set -+# 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_AF_RXRPC is not set -+ -+# -+# Wireless -+# -+# CONFIG_CFG80211 is not set -+# CONFIG_WIRELESS_EXT is not set -+# CONFIG_MAC80211 is not set -+# CONFIG_IEEE80211 is not set -+# CONFIG_RFKILL is not set -+# CONFIG_NET_9P is not set -+ -+# -+# Device Drivers -+# -+ -+# -+# Generic Driver Options -+# -+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -+CONFIG_STANDALONE=y -+CONFIG_PREVENT_FIRMWARE_BUILD=y -+# CONFIG_FW_LOADER is not set -+# CONFIG_DEBUG_DRIVER is not set -+# CONFIG_DEBUG_DEVRES is not set -+# CONFIG_SYS_HYPERVISOR is not set -+# CONFIG_CONNECTOR is not set -+CONFIG_MTD=y -+# CONFIG_MTD_DEBUG is not set -+CONFIG_MTD_CONCAT=y -+CONFIG_MTD_PARTITIONS=y -+# CONFIG_MTD_REDBOOT_PARTS is not set -+CONFIG_MTD_CMDLINE_PARTS=y -+ -+# -+# User Modules And Translation Layers -+# -+CONFIG_MTD_CHAR=y -+CONFIG_MTD_BLKDEVS=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 -+# CONFIG_SSFDC is not set -+# CONFIG_MTD_OOPS 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 is not set -+CONFIG_MTD_CFI_AMDSTD=y -+# CONFIG_MTD_CFI_STAA is not set -+CONFIG_MTD_CFI_UTIL=y -+CONFIG_MTD_RAM=y -+CONFIG_MTD_ROM=y -+# CONFIG_MTD_ABSENT is not set -+ -+# -+# Mapping drivers for chip access -+# -+# CONFIG_MTD_COMPLEX_MAPPINGS is not set -+# CONFIG_MTD_PHYSMAP is not set -+CONFIG_MTD_PHYSMAP_OF=y -+# CONFIG_MTD_INTEL_VR_NOR is not set -+# CONFIG_MTD_PLATRAM is not set -+ -+# -+# Self-contained MTD device drivers -+# -+# CONFIG_MTD_PMC551 is not set -+# 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 -+# CONFIG_MTD_NAND is not set -+# CONFIG_MTD_ONENAND is not set -+ -+# -+# UBI - Unsorted block images -+# -+# CONFIG_MTD_UBI is not set -+CONFIG_OF_DEVICE=y -+# CONFIG_PARPORT is not set -+CONFIG_BLK_DEV=y -+# 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=y -+# CONFIG_BLK_DEV_CRYPTOLOOP is not set -+# CONFIG_BLK_DEV_NBD is not set -+# CONFIG_BLK_DEV_SX8 is not set -+# CONFIG_BLK_DEV_UB is not set -+CONFIG_BLK_DEV_RAM=y -+CONFIG_BLK_DEV_RAM_COUNT=16 -+CONFIG_BLK_DEV_RAM_SIZE=32768 -+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 -+# CONFIG_CDROM_PKTCDVD is not set -+# CONFIG_ATA_OVER_ETH is not set -+CONFIG_MISC_DEVICES=y -+# CONFIG_PHANTOM is not set -+# CONFIG_EEPROM_93CX6 is not set -+# CONFIG_SGI_IOC4 is not set -+# CONFIG_TIFM_CORE is not set -+# CONFIG_IDE is not set -+ -+# -+# SCSI device support -+# -+# CONFIG_RAID_ATTRS is not set -+CONFIG_SCSI=y -+CONFIG_SCSI_DMA=y -+CONFIG_SCSI_TGT=y -+# CONFIG_SCSI_NETLINK is not set -+CONFIG_SCSI_PROC_FS=y -+ -+# -+# SCSI support type (disk, tape, CD-ROM) -+# -+CONFIG_BLK_DEV_SD=y -+# CONFIG_CHR_DEV_ST is not set -+# CONFIG_CHR_DEV_OSST is not set -+# CONFIG_BLK_DEV_SR is not set -+CONFIG_CHR_DEV_SG=y -+# CONFIG_CHR_DEV_SCH is not set -+ -+# -+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -+# -+# CONFIG_SCSI_MULTI_LUN is not set -+# CONFIG_SCSI_CONSTANTS is not set -+# CONFIG_SCSI_LOGGING is not set -+# CONFIG_SCSI_SCAN_ASYNC is not set -+CONFIG_SCSI_WAIT_SCAN=m -+ -+# -+# SCSI Transports -+# -+# CONFIG_SCSI_SPI_ATTRS is not set -+# CONFIG_SCSI_FC_ATTRS is not set -+# CONFIG_SCSI_ISCSI_ATTRS is not set -+# CONFIG_SCSI_SAS_LIBSAS is not set -+# CONFIG_SCSI_SRP_ATTRS is not set -+CONFIG_SCSI_LOWLEVEL=y -+# CONFIG_ISCSI_TCP is not set -+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set -+# CONFIG_SCSI_3W_9XXX is not set -+# CONFIG_SCSI_ACARD is not set -+# CONFIG_SCSI_AACRAID is not set -+# CONFIG_SCSI_AIC7XXX is not set -+# CONFIG_SCSI_AIC7XXX_OLD is not set -+# CONFIG_SCSI_AIC79XX is not set -+# CONFIG_SCSI_AIC94XX is not set -+# CONFIG_SCSI_DPT_I2O is not set -+# CONFIG_SCSI_ADVANSYS is not set -+# CONFIG_SCSI_ARCMSR is not set -+# CONFIG_MEGARAID_NEWGEN is not set -+# CONFIG_MEGARAID_LEGACY is not set -+# CONFIG_MEGARAID_SAS is not set -+# CONFIG_SCSI_HPTIOP is not set -+# CONFIG_SCSI_BUSLOGIC is not set -+# CONFIG_SCSI_DMX3191D is not set -+# CONFIG_SCSI_EATA is not set -+# CONFIG_SCSI_FUTURE_DOMAIN is not set -+# CONFIG_SCSI_GDTH is not set -+# CONFIG_SCSI_IPS is not set -+# CONFIG_SCSI_INITIO is not set -+# CONFIG_SCSI_INIA100 is not set -+# CONFIG_SCSI_STEX is not set -+# CONFIG_SCSI_SYM53C8XX_2 is not set -+# CONFIG_SCSI_IPR is not set -+# CONFIG_SCSI_QLOGIC_1280 is not set -+# CONFIG_SCSI_QLA_FC is not set -+# CONFIG_SCSI_QLA_ISCSI is not set -+# CONFIG_SCSI_LPFC is not set -+# CONFIG_SCSI_DC395x is not set -+# CONFIG_SCSI_DC390T is not set -+# CONFIG_SCSI_NSP32 is not set -+# CONFIG_SCSI_DEBUG is not set -+# CONFIG_SCSI_SRP is not set -+CONFIG_ATA=y -+# CONFIG_ATA_NONSTANDARD is not set -+# CONFIG_SATA_AHCI is not set -+# CONFIG_SATA_SVW is not set -+# CONFIG_ATA_PIIX is not set -+# CONFIG_SATA_MV is not set -+# CONFIG_SATA_NV is not set -+# CONFIG_PDC_ADMA is not set -+# CONFIG_SATA_QSTOR is not set -+# CONFIG_SATA_PROMISE is not set -+# CONFIG_SATA_SX4 is not set -+# CONFIG_SATA_SIL is not set -+# CONFIG_SATA_SIL24 is not set -+# CONFIG_SATA_SIS is not set -+# CONFIG_SATA_ULI is not set -+# CONFIG_SATA_VIA is not set -+# CONFIG_SATA_VITESSE is not set -+# CONFIG_SATA_INIC162X is not set -+# CONFIG_PATA_ALI is not set -+# CONFIG_PATA_AMD is not set -+# CONFIG_PATA_ARTOP is not set -+# CONFIG_PATA_ATIIXP is not set -+# CONFIG_PATA_CMD640_PCI is not set -+# CONFIG_PATA_CMD64X is not set -+# CONFIG_PATA_CS5520 is not set -+# CONFIG_PATA_CS5530 is not set -+# CONFIG_PATA_CYPRESS is not set -+# CONFIG_PATA_EFAR is not set -+# CONFIG_ATA_GENERIC is not set -+# CONFIG_PATA_HPT366 is not set -+# CONFIG_PATA_HPT37X is not set -+# CONFIG_PATA_HPT3X2N is not set -+# CONFIG_PATA_HPT3X3 is not set -+# CONFIG_PATA_IT821X is not set -+# CONFIG_PATA_IT8213 is not set -+# CONFIG_PATA_JMICRON is not set -+# CONFIG_PATA_TRIFLEX is not set -+# CONFIG_PATA_MARVELL is not set -+CONFIG_PATA_MPC52xx=y -+# CONFIG_PATA_MPIIX is not set -+# CONFIG_PATA_OLDPIIX is not set -+# CONFIG_PATA_NETCELL is not set -+# CONFIG_PATA_NS87410 is not set -+# CONFIG_PATA_NS87415 is not set -+# CONFIG_PATA_OPTI is not set -+# CONFIG_PATA_OPTIDMA is not set -+# CONFIG_PATA_PDC_OLD is not set -+# CONFIG_PATA_RADISYS is not set -+# CONFIG_PATA_RZ1000 is not set -+# CONFIG_PATA_SC1200 is not set -+# CONFIG_PATA_SERVERWORKS is not set -+# CONFIG_PATA_PDC2027X is not set -+# CONFIG_PATA_SIL680 is not set -+# CONFIG_PATA_SIS is not set -+# CONFIG_PATA_VIA is not set -+# CONFIG_PATA_WINBOND is not set -+CONFIG_PATA_PLATFORM=y -+# CONFIG_PATA_OF_PLATFORM is not set -+# CONFIG_MD is not set -+# CONFIG_FUSION is not set -+ -+# -+# IEEE 1394 (FireWire) support -+# -+# CONFIG_FIREWIRE is not set -+# CONFIG_IEEE1394 is not set -+# CONFIG_I2O is not set -+# CONFIG_MACINTOSH_DRIVERS is not set -+CONFIG_NETDEVICES=y -+# CONFIG_NETDEVICES_MULTIQUEUE is not set -+# CONFIG_DUMMY is not set -+# CONFIG_BONDING is not set -+# CONFIG_MACVLAN is not set -+# CONFIG_EQUALIZER is not set -+# CONFIG_TUN is not set -+# CONFIG_VETH is not set -+# CONFIG_IP1000 is not set -+# CONFIG_ARCNET is not set -+CONFIG_PHYLIB=y -+ -+# -+# MII PHY device drivers -+# -+# CONFIG_MARVELL_PHY is not set -+# CONFIG_DAVICOM_PHY is not set -+# CONFIG_QSEMI_PHY is not set -+# CONFIG_LXT_PHY is not set -+# CONFIG_CICADA_PHY is not set -+# CONFIG_VITESSE_PHY is not set -+# CONFIG_SMSC_PHY is not set -+# CONFIG_BROADCOM_PHY is not set -+# CONFIG_ICPLUS_PHY is not set -+# CONFIG_FIXED_PHY is not set -+# CONFIG_MDIO_BITBANG is not set -+CONFIG_NET_ETHERNET=y -+# CONFIG_MII is not set -+# CONFIG_HAPPYMEAL is not set -+# CONFIG_SUNGEM is not set -+# CONFIG_CASSINI is not set -+# CONFIG_NET_VENDOR_3COM is not set -+# CONFIG_NET_TULIP is not set -+# CONFIG_HP100 is not set -+# CONFIG_IBM_NEW_EMAC_ZMII is not set -+# CONFIG_IBM_NEW_EMAC_RGMII is not set -+# CONFIG_IBM_NEW_EMAC_TAH is not set -+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set -+# CONFIG_NET_PCI is not set -+# CONFIG_B44 is not set -+CONFIG_FEC_MPC52xx=y -+CONFIG_FEC_MPC52xx_MDIO=y -+# CONFIG_NETDEV_1000 is not set -+# CONFIG_NETDEV_10000 is not set -+# CONFIG_TR is not set -+ -+# -+# Wireless LAN -+# -+# CONFIG_WLAN_PRE80211 is not set -+# CONFIG_WLAN_80211 is not set -+ -+# -+# USB Network Adapters -+# -+# CONFIG_USB_CATC is not set -+# CONFIG_USB_KAWETH is not set -+# CONFIG_USB_PEGASUS is not set -+# CONFIG_USB_RTL8150 is not set -+# CONFIG_USB_USBNET is not set -+# CONFIG_WAN is not set -+# CONFIG_FDDI is not set -+# CONFIG_HIPPI is not set -+# CONFIG_PPP is not set -+# CONFIG_SLIP is not set -+# CONFIG_NET_FC 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 -+# CONFIG_ISDN is not set -+# CONFIG_PHONE is not set -+ -+# -+# Input device support -+# -+# CONFIG_INPUT is not set -+ -+# -+# Hardware I/O ports -+# -+# CONFIG_SERIO is not set -+# CONFIG_GAMEPORT is not set -+ -+# -+# Character devices -+# -+# CONFIG_VT is not set -+# CONFIG_SERIAL_NONSTANDARD is not set -+ -+# -+# Serial drivers -+# -+# CONFIG_SERIAL_8250 is not set -+ -+# -+# Non-8250 serial port support -+# -+# CONFIG_SERIAL_UARTLITE is not set -+CONFIG_SERIAL_CORE=y -+CONFIG_SERIAL_CORE_CONSOLE=y -+CONFIG_SERIAL_MPC52xx=y -+CONFIG_SERIAL_MPC52xx_CONSOLE=y -+CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200 -+# CONFIG_SERIAL_JSM is not set -+CONFIG_UNIX98_PTYS=y -+CONFIG_LEGACY_PTYS=y -+CONFIG_LEGACY_PTY_COUNT=256 -+# CONFIG_HVC_RTAS is not set -+# CONFIG_IPMI_HANDLER is not set -+# CONFIG_HW_RANDOM is not set -+# CONFIG_NVRAM is not set -+CONFIG_GEN_RTC=y -+# CONFIG_GEN_RTC_X is not set -+# CONFIG_R3964 is not set -+# CONFIG_APPLICOM is not set -+# CONFIG_RAW_DRIVER is not set -+# CONFIG_TCG_TPM is not set -+CONFIG_DEVPORT=y -+CONFIG_I2C=y -+CONFIG_I2C_BOARDINFO=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_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_MPC=y -+# CONFIG_I2C_NFORCE2 is not set -+# CONFIG_I2C_OCORES is not set -+# CONFIG_I2C_PARPORT_LIGHT is not set -+# CONFIG_I2C_PROSAVAGE is not set -+# CONFIG_I2C_SAVAGE4 is not set -+# CONFIG_I2C_SIMTEC is not set -+# CONFIG_I2C_SIS5595 is not set -+# CONFIG_I2C_SIS630 is not set -+# CONFIG_I2C_SIS96X is not set -+# CONFIG_I2C_TAOS_EVM is not set -+# CONFIG_I2C_STUB is not set -+# CONFIG_I2C_TINY_USB is not set -+# CONFIG_I2C_VIA is not set -+# CONFIG_I2C_VIAPRO is not set -+# CONFIG_I2C_VOODOO3 is not set -+ -+# -+# Miscellaneous I2C Chip support -+# -+# CONFIG_SENSORS_DS1337 is not set -+# CONFIG_SENSORS_DS1374 is not set -+# CONFIG_DS1682 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_SENSORS_M41T00 is not set -+# CONFIG_SENSORS_MAX6875 is not set -+# CONFIG_SENSORS_TSL2550 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 -+# CONFIG_W1 is not set -+# CONFIG_POWER_SUPPLY is not set -+CONFIG_HWMON=y -+# CONFIG_HWMON_VID is not set -+# CONFIG_SENSORS_AD7418 is not set -+# CONFIG_SENSORS_ADM1021 is not set -+# CONFIG_SENSORS_ADM1025 is not set -+# CONFIG_SENSORS_ADM1026 is not set -+# CONFIG_SENSORS_ADM1029 is not set -+# CONFIG_SENSORS_ADM1031 is not set -+# CONFIG_SENSORS_ADM9240 is not set -+# CONFIG_SENSORS_ADT7470 is not set -+# CONFIG_SENSORS_ATXP1 is not set -+# CONFIG_SENSORS_DS1621 is not set -+# CONFIG_SENSORS_I5K_AMB is not set -+# CONFIG_SENSORS_F71805F is not set -+# CONFIG_SENSORS_F71882FG is not set -+# CONFIG_SENSORS_F75375S 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_LM93 is not set -+# CONFIG_SENSORS_MAX1619 is not set -+# CONFIG_SENSORS_MAX6650 is not set -+# CONFIG_SENSORS_PC87360 is not set -+# CONFIG_SENSORS_PC87427 is not set -+# CONFIG_SENSORS_SIS5595 is not set -+# CONFIG_SENSORS_DME1737 is not set -+# CONFIG_SENSORS_SMSC47M1 is not set -+# CONFIG_SENSORS_SMSC47M192 is not set -+# CONFIG_SENSORS_SMSC47B397 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_W83791D is not set -+# CONFIG_SENSORS_W83792D is not set -+# CONFIG_SENSORS_W83793 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 -+CONFIG_WATCHDOG=y -+# CONFIG_WATCHDOG_NOWAYOUT is not set -+ -+# -+# Watchdog Device Drivers -+# -+# CONFIG_SOFT_WATCHDOG is not set -+# CONFIG_MPC5200_WDT is not set -+# CONFIG_WATCHDOG_RTAS is not set -+ -+# -+# PCI-based Watchdog Cards -+# -+# CONFIG_PCIPCWATCHDOG is not set -+# CONFIG_WDTPCI is not set -+ -+# -+# USB-based Watchdog Cards -+# -+# CONFIG_USBPCWATCHDOG is not set -+ -+# -+# Sonics Silicon Backplane -+# -+CONFIG_SSB_POSSIBLE=y -+# CONFIG_SSB is not set -+ -+# -+# Multifunction device drivers -+# -+# CONFIG_MFD_SM501 is not set -+ -+# -+# Multimedia devices -+# -+# CONFIG_VIDEO_DEV is not set -+# CONFIG_DVB_CORE is not set -+CONFIG_DAB=y -+# CONFIG_USB_DABUSB is not set -+ -+# -+# Graphics support -+# -+# CONFIG_AGP is not set -+# CONFIG_DRM is not set -+# CONFIG_VGASTATE is not set -+CONFIG_VIDEO_OUTPUT_CONTROL=m -+# CONFIG_FB is not set -+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set -+ -+# -+# Display device support -+# -+# CONFIG_DISPLAY_SUPPORT is not set -+ -+# -+# Sound -+# -+# CONFIG_SOUND is not set -+CONFIG_USB_SUPPORT=y -+CONFIG_USB_ARCH_HAS_HCD=y -+CONFIG_USB_ARCH_HAS_OHCI=y -+CONFIG_USB_ARCH_HAS_EHCI=y -+CONFIG_USB=y -+# CONFIG_USB_DEBUG is not set -+ -+# -+# Miscellaneous USB options -+# -+CONFIG_USB_DEVICEFS=y -+# CONFIG_USB_DEVICE_CLASS is not set -+# CONFIG_USB_DYNAMIC_MINORS is not set -+# CONFIG_USB_SUSPEND is not set -+# CONFIG_USB_PERSIST is not set -+# CONFIG_USB_OTG is not set -+ -+# -+# USB Host Controller Drivers -+# -+# CONFIG_USB_EHCI_HCD is not set -+# CONFIG_USB_ISP116X_HCD is not set -+CONFIG_USB_OHCI_HCD=y -+CONFIG_USB_OHCI_HCD_PPC_SOC=y -+CONFIG_USB_OHCI_HCD_PPC_OF=y -+CONFIG_USB_OHCI_HCD_PPC_OF_BE=y -+# CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set -+CONFIG_USB_OHCI_HCD_PCI=y -+CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y -+CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y -+CONFIG_USB_OHCI_LITTLE_ENDIAN=y -+# CONFIG_USB_UHCI_HCD is not set -+# CONFIG_USB_SL811_HCD is not set -+# CONFIG_USB_R8A66597_HCD is not set -+ -+# -+# USB Device Class drivers -+# -+# CONFIG_USB_ACM is not set -+# CONFIG_USB_PRINTER is not set -+ -+# -+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -+# -+ -+# -+# may also be needed; see USB_STORAGE Help for more information -+# -+CONFIG_USB_STORAGE=y -+# 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_USBAT is not set -+# CONFIG_USB_STORAGE_SDDR09 is not set -+# CONFIG_USB_STORAGE_SDDR55 is not set -+# CONFIG_USB_STORAGE_JUMPSHOT is not set -+# CONFIG_USB_STORAGE_ALAUDA is not set -+# CONFIG_USB_STORAGE_KARMA is not set -+# CONFIG_USB_LIBUSUAL is not set -+ -+# -+# USB Imaging devices -+# -+# CONFIG_USB_MDC800 is not set -+# CONFIG_USB_MICROTEK is not set -+CONFIG_USB_MON=y -+ -+# -+# USB port drivers -+# -+ -+# -+# USB Serial Converter support -+# -+# CONFIG_USB_SERIAL is not set -+ -+# -+# USB Miscellaneous drivers -+# -+# CONFIG_USB_EMI62 is not set -+# CONFIG_USB_EMI26 is not set -+# CONFIG_USB_ADUTUX is not set -+# CONFIG_USB_AUERSWALD is not set -+# CONFIG_USB_RIO500 is not set -+# CONFIG_USB_LEGOTOWER is not set -+# CONFIG_USB_LCD is not set -+# CONFIG_USB_BERRY_CHARGE is not set -+# CONFIG_USB_LED is not set -+# CONFIG_USB_CYPRESS_CY7C63 is not set -+# CONFIG_USB_CYTHERM is not set -+# CONFIG_USB_PHIDGET is not set -+# CONFIG_USB_IDMOUSE is not set -+# CONFIG_USB_FTDI_ELAN is not set -+# CONFIG_USB_APPLEDISPLAY is not set -+# CONFIG_USB_LD is not set -+# CONFIG_USB_TRANCEVIBRATOR is not set -+# CONFIG_USB_IOWARRIOR is not set -+# CONFIG_USB_TEST is not set -+ -+# -+# USB DSL modem support -+# -+ -+# -+# USB Gadget Support -+# -+# CONFIG_USB_GADGET is not set -+# CONFIG_MMC is not set -+CONFIG_NEW_LEDS=y -+CONFIG_LEDS_CLASS=y -+ -+# -+# LED drivers -+# -+ -+# -+# LED Triggers -+# -+CONFIG_LEDS_TRIGGERS=y -+CONFIG_LEDS_TRIGGER_TIMER=y -+# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set -+# CONFIG_INFINIBAND is not set -+# CONFIG_EDAC is not set -+# CONFIG_RTC_CLASS is not set -+ -+# -+# Userspace I/O -+# -+# CONFIG_UIO 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=y -+CONFIG_EXT3_FS_XATTR=y -+# CONFIG_EXT3_FS_POSIX_ACL is not set -+# CONFIG_EXT3_FS_SECURITY is not set -+# CONFIG_EXT4DEV_FS is not set -+CONFIG_JBD=y -+CONFIG_FS_MBCACHE=y -+# 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_GFS2_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 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_PROC_KCORE=y -+CONFIG_PROC_SYSCTL=y -+CONFIG_SYSFS=y -+CONFIG_TMPFS=y -+# CONFIG_TMPFS_POSIX_ACL is not set -+# CONFIG_HUGETLB_PAGE 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_JFFS2_FS=y -+CONFIG_JFFS2_FS_DEBUG=0 -+CONFIG_JFFS2_FS_WRITEBUFFER=y -+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set -+# 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_LZO is not set -+CONFIG_JFFS2_RTIME=y -+# CONFIG_JFFS2_RUBIN is not set -+CONFIG_CRAMFS=y -+# 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 -+CONFIG_NETWORK_FILESYSTEMS=y -+CONFIG_NFS_FS=y -+CONFIG_NFS_V3=y -+# CONFIG_NFS_V3_ACL is not set -+CONFIG_NFS_V4=y -+# 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_SUNRPC_GSS=y -+# CONFIG_SUNRPC_BIND34 is not set -+CONFIG_RPCSEC_GSS_KRB5=y -+# 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 -+ -+# -+# Partition Types -+# -+# CONFIG_PARTITION_ADVANCED is not set -+CONFIG_MSDOS_PARTITION=y -+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 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=y -+# 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 -+# CONFIG_DLM is not set -+# CONFIG_UCC_SLOW is not set -+ -+# -+# Library routines -+# -+CONFIG_BITREVERSE=y -+# CONFIG_CRC_CCITT is not set -+# CONFIG_CRC16 is not set -+# CONFIG_CRC_ITU_T is not set -+CONFIG_CRC32=y -+# CONFIG_CRC7 is not set -+# CONFIG_LIBCRC32C is not set -+CONFIG_ZLIB_INFLATE=y -+CONFIG_ZLIB_DEFLATE=y -+CONFIG_PLIST=y -+CONFIG_HAS_IOMEM=y -+CONFIG_HAS_IOPORT=y -+CONFIG_HAS_DMA=y -+# CONFIG_INSTRUMENTATION is not set -+ -+# -+# Kernel hacking -+# -+CONFIG_PRINTK_TIME=y -+CONFIG_ENABLE_WARN_DEPRECATED=y -+CONFIG_ENABLE_MUST_CHECK=y -+# CONFIG_MAGIC_SYSRQ is not set -+# CONFIG_UNUSED_SYMBOLS is not set -+# CONFIG_DEBUG_FS is not set -+# CONFIG_HEADERS_CHECK is not set -+CONFIG_DEBUG_KERNEL=y -+# CONFIG_DEBUG_SHIRQ is not set -+CONFIG_DETECT_SOFTLOCKUP=y -+CONFIG_SCHED_DEBUG=y -+# CONFIG_SCHEDSTATS is not set -+# CONFIG_TIMER_STATS is not set -+# CONFIG_SLUB_DEBUG_ON is not set -+# CONFIG_DEBUG_RT_MUTEXES is not set -+# CONFIG_RT_MUTEX_TESTER is not set -+# CONFIG_DEBUG_SPINLOCK is not set -+# CONFIG_DEBUG_MUTEXES is not set -+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -+# CONFIG_DEBUG_KOBJECT is not set -+# CONFIG_DEBUG_BUGVERBOSE is not set -+CONFIG_DEBUG_INFO=y -+# CONFIG_DEBUG_VM is not set -+# CONFIG_DEBUG_LIST is not set -+# CONFIG_DEBUG_SG is not set -+CONFIG_FORCED_INLINING=y -+# CONFIG_BOOT_PRINTK_DELAY is not set -+# CONFIG_RCU_TORTURE_TEST is not set -+# CONFIG_FAULT_INJECTION is not set -+# CONFIG_SAMPLES is not set -+# CONFIG_DEBUG_STACKOVERFLOW is not set -+# CONFIG_DEBUG_STACK_USAGE is not set -+# CONFIG_DEBUG_PAGEALLOC is not set -+# CONFIG_DEBUGGER is not set -+# CONFIG_BDI_SWITCH is not set -+# CONFIG_BOOTX_TEXT is not set -+# CONFIG_PPC_EARLY_DEBUG is not set -+ -+# -+# Security options -+# -+# CONFIG_KEYS is not set -+# CONFIG_SECURITY is not set -+# CONFIG_SECURITY_FILE_CAPABILITIES is not set -+CONFIG_CRYPTO=y -+CONFIG_CRYPTO_ALGAPI=y -+CONFIG_CRYPTO_BLKCIPHER=y -+CONFIG_CRYPTO_MANAGER=y -+# CONFIG_CRYPTO_HMAC is not set -+# CONFIG_CRYPTO_XCBC is not set -+# CONFIG_CRYPTO_NULL is not set -+# CONFIG_CRYPTO_MD4 is not set -+CONFIG_CRYPTO_MD5=y -+# CONFIG_CRYPTO_SHA1 is not set -+# 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_GF128MUL is not set -+# CONFIG_CRYPTO_ECB is not set -+CONFIG_CRYPTO_CBC=y -+# CONFIG_CRYPTO_PCBC is not set -+# CONFIG_CRYPTO_LRW is not set -+# CONFIG_CRYPTO_XTS is not set -+# CONFIG_CRYPTO_CRYPTD is not set -+CONFIG_CRYPTO_DES=y -+# CONFIG_CRYPTO_FCRYPT is not set -+# 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_SEED is not set -+# CONFIG_CRYPTO_DEFLATE is not set -+# CONFIG_CRYPTO_MICHAEL_MIC is not set -+# CONFIG_CRYPTO_CRC32C is not set -+# CONFIG_CRYPTO_CAMELLIA is not set -+# CONFIG_CRYPTO_TEST is not set -+# CONFIG_CRYPTO_AUTHENC is not set -+CONFIG_CRYPTO_HW=y -+CONFIG_PPC_CLOCK=y -+CONFIG_PPC_LIB_RHEAP=y ---- a/arch/powerpc/configs/mpc8313_rdb_defconfig -+++ b/arch/powerpc/configs/mpc8313_rdb_defconfig -@@ -1,7 +1,7 @@ - # - # Automatically generated make config: don't edit --# Linux kernel version: 2.6.24-rc4 --# Thu Dec 6 16:48:31 2007 -+# Linux kernel version: 2.6.24-rc6 -+# Thu Jan 17 16:35:55 2008 - # - # CONFIG_PPC64 is not set - -@@ -144,6 +144,7 @@ CONFIG_MPC8313_RDB=y - # CONFIG_MPC834x_MDS is not set - # CONFIG_MPC834x_ITX is not set - # CONFIG_MPC836x_MDS is not set -+# CONFIG_MPC837x_MDS is not set - CONFIG_PPC_MPC831x=y - # CONFIG_MPIC is not set - # CONFIG_MPIC_WEIRD is not set -@@ -336,15 +337,16 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y - CONFIG_MTD=y - # CONFIG_MTD_DEBUG is not set - # CONFIG_MTD_CONCAT is not set --# CONFIG_MTD_PARTITIONS is not set -+CONFIG_MTD_PARTITIONS=y -+# 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_BLKDEVS is not set --# CONFIG_MTD_BLOCK is not set --# CONFIG_MTD_BLOCK_RO is not set -+CONFIG_MTD_BLKDEVS=y -+CONFIG_MTD_BLOCK=y - # CONFIG_FTL is not set - # CONFIG_NFTL is not set - # CONFIG_INFTL is not set -@@ -381,11 +383,8 @@ CONFIG_MTD_CFI_UTIL=y - # Mapping drivers for chip access - # - # CONFIG_MTD_COMPLEX_MAPPINGS is not set --CONFIG_MTD_PHYSMAP=y --CONFIG_MTD_PHYSMAP_START=0xfe000000 --CONFIG_MTD_PHYSMAP_LEN=0x1000000 --CONFIG_MTD_PHYSMAP_BANKWIDTH=2 --# CONFIG_MTD_PHYSMAP_OF is not set -+# CONFIG_MTD_PHYSMAP is not set -+CONFIG_MTD_PHYSMAP_OF=y - # CONFIG_MTD_INTEL_VR_NOR is not set - # CONFIG_MTD_PLATRAM is not set - -@@ -406,7 +405,16 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2 - # CONFIG_MTD_DOC2000 is not set - # CONFIG_MTD_DOC2001 is not set - # CONFIG_MTD_DOC2001PLUS is not set --# CONFIG_MTD_NAND is not set -+CONFIG_MTD_NAND=y -+CONFIG_MTD_NAND_VERIFY_WRITE=y -+# CONFIG_MTD_NAND_ECC_SMC is not set -+# CONFIG_MTD_NAND_MUSEUM_IDS is not set -+CONFIG_MTD_NAND_IDS=y -+# CONFIG_MTD_NAND_DISKONCHIP is not set -+# CONFIG_MTD_NAND_CAFE is not set -+# CONFIG_MTD_NAND_NANDSIM is not set -+# CONFIG_MTD_NAND_PLATFORM is not set -+# CONFIG_MTD_ALAUDA is not set - # CONFIG_MTD_ONENAND is not set - - # -@@ -1178,7 +1186,17 @@ CONFIG_TMPFS=y - # CONFIG_BEFS_FS is not set - # CONFIG_BFS_FS is not set - # CONFIG_EFS_FS is not set --# CONFIG_JFFS2_FS is not set -+CONFIG_JFFS2_FS=y -+CONFIG_JFFS2_FS_DEBUG=0 -+CONFIG_JFFS2_FS_WRITEBUFFER=y -+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set -+# 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_LZO is not set -+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 -@@ -1242,6 +1260,8 @@ CONFIG_BITREVERSE=y - CONFIG_CRC32=y - # CONFIG_CRC7 is not set - # CONFIG_LIBCRC32C is not set -+CONFIG_ZLIB_INFLATE=y -+CONFIG_ZLIB_DEFLATE=y - CONFIG_PLIST=y - CONFIG_HAS_IOMEM=y - CONFIG_HAS_IOPORT=y ---- a/arch/powerpc/configs/mpc834x_itx_defconfig -+++ b/arch/powerpc/configs/mpc834x_itx_defconfig -@@ -570,7 +570,8 @@ CONFIG_SATA_SIL=y - # CONFIG_PATA_SIS is not set - # CONFIG_PATA_VIA is not set - # CONFIG_PATA_WINBOND is not set --# CONFIG_PATA_PLATFORM is not set -+CONFIG_PATA_PLATFORM=y -+CONFIG_PATA_OF_PLATFORM=y - CONFIG_MD=y - CONFIG_BLK_DEV_MD=y - CONFIG_MD_LINEAR=y ---- /dev/null -+++ b/arch/powerpc/configs/mpc837x_mds_defconfig -@@ -0,0 +1,878 @@ -+# -+# Automatically generated make config: don't edit -+# Linux kernel version: 2.6.23 -+# Wed Oct 10 16:31:39 2007 -+# -+# CONFIG_PPC64 is not set -+ -+# -+# Processor support -+# -+CONFIG_6xx=y -+# CONFIG_PPC_85xx is not set -+# CONFIG_PPC_8xx is not set -+# CONFIG_40x is not set -+# CONFIG_44x is not set -+# CONFIG_E200 is not set -+CONFIG_83xx=y -+CONFIG_PPC_FPU=y -+CONFIG_PPC_STD_MMU=y -+CONFIG_PPC_STD_MMU_32=y -+# CONFIG_PPC_MM_SLICES is not set -+# CONFIG_SMP is not set -+CONFIG_PPC32=y -+CONFIG_PPC_MERGE=y -+CONFIG_MMU=y -+CONFIG_GENERIC_HARDIRQS=y -+CONFIG_IRQ_PER_CPU=y -+CONFIG_RWSEM_XCHGADD_ALGORITHM=y -+CONFIG_ARCH_HAS_ILOG2_U32=y -+CONFIG_GENERIC_HWEIGHT=y -+CONFIG_GENERIC_CALIBRATE_DELAY=y -+CONFIG_GENERIC_FIND_NEXT_BIT=y -+# CONFIG_ARCH_NO_VIRT_TO_BUS is not set -+CONFIG_PPC=y -+CONFIG_EARLY_PRINTK=y -+CONFIG_GENERIC_NVRAM=y -+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -+CONFIG_ARCH_MAY_HAVE_PC_FDC=y -+CONFIG_PPC_OF=y -+CONFIG_OF=y -+CONFIG_PPC_UDBG_16550=y -+# CONFIG_GENERIC_TBSYNC is not set -+CONFIG_AUDIT_ARCH=y -+CONFIG_GENERIC_BUG=y -+CONFIG_DEFAULT_UIMAGE=y -+# CONFIG_PPC_DCR_NATIVE is not set -+# CONFIG_PPC_DCR_MMIO is not set -+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" -+ -+# -+# General setup -+# -+CONFIG_EXPERIMENTAL=y -+CONFIG_BROKEN_ON_SMP=y -+CONFIG_INIT_ENV_ARG_LIMIT=32 -+CONFIG_LOCALVERSION="" -+CONFIG_LOCALVERSION_AUTO=y -+CONFIG_SWAP=y -+CONFIG_SYSVIPC=y -+CONFIG_SYSVIPC_SYSCTL=y -+# CONFIG_POSIX_MQUEUE is not set -+# CONFIG_BSD_PROCESS_ACCT is not set -+# CONFIG_TASKSTATS is not set -+# CONFIG_USER_NS is not set -+# CONFIG_AUDIT is not set -+# CONFIG_IKCONFIG is not set -+CONFIG_LOG_BUF_SHIFT=14 -+CONFIG_SYSFS_DEPRECATED=y -+# CONFIG_RELAY is not set -+CONFIG_BLK_DEV_INITRD=y -+CONFIG_INITRAMFS_SOURCE="" -+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -+CONFIG_SYSCTL=y -+CONFIG_EMBEDDED=y -+CONFIG_SYSCTL_SYSCALL=y -+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_FUTEX=y -+CONFIG_ANON_INODES=y -+# CONFIG_EPOLL is not set -+CONFIG_SIGNALFD=y -+CONFIG_EVENTFD=y -+CONFIG_SHMEM=y -+CONFIG_VM_EVENT_COUNTERS=y -+CONFIG_SLAB=y -+# CONFIG_SLUB is not set -+# CONFIG_SLOB is not set -+CONFIG_RT_MUTEXES=y -+# CONFIG_TINY_SHMEM is not set -+CONFIG_BASE_SMALL=0 -+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 is not set -+CONFIG_BLOCK=y -+# CONFIG_LBD is not set -+# CONFIG_BLK_DEV_IO_TRACE is not set -+# CONFIG_LSF is not set -+# CONFIG_BLK_DEV_BSG is not set -+ -+# -+# IO Schedulers -+# -+CONFIG_IOSCHED_NOOP=y -+CONFIG_IOSCHED_AS=y -+CONFIG_IOSCHED_DEADLINE=y -+CONFIG_IOSCHED_CFQ=y -+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" -+ -+# -+# Platform support -+# -+# CONFIG_PPC_MULTIPLATFORM is not set -+# CONFIG_EMBEDDED6xx is not set -+# CONFIG_PPC_82xx is not set -+CONFIG_PPC_83xx=y -+# CONFIG_PPC_86xx is not set -+# CONFIG_PPC_MPC52xx is not set -+# CONFIG_PPC_MPC5200 is not set -+# CONFIG_PPC_CELL is not set -+# CONFIG_PPC_CELL_NATIVE is not set -+# CONFIG_PQ2ADS is not set -+# CONFIG_MPC8313_RDB is not set -+# CONFIG_MPC832x_MDS is not set -+# CONFIG_MPC832x_RDB is not set -+# CONFIG_MPC834x_MDS is not set -+# CONFIG_MPC834x_ITX is not set -+# CONFIG_MPC836x_MDS is not set -+CONFIG_MPC837x_MDS=y -+CONFIG_PPC_MPC837x=y -+# CONFIG_MPIC is not set -+# CONFIG_MPIC_WEIRD is not set -+# CONFIG_PPC_I8259 is not set -+# CONFIG_PPC_RTAS is not set -+# CONFIG_MMIO_NVRAM is not set -+# CONFIG_PPC_MPC106 is not set -+# CONFIG_PPC_970_NAP is not set -+# CONFIG_PPC_INDIRECT_IO is not set -+# CONFIG_GENERIC_IOMAP is not set -+# CONFIG_CPU_FREQ is not set -+# CONFIG_CPM2 is not set -+# CONFIG_FSL_ULI1575 is not set -+CONFIG_FSL_SERDES=y -+ -+# -+# Kernel options -+# -+# CONFIG_HIGHMEM is not set -+# CONFIG_HZ_100 is not set -+CONFIG_HZ_250=y -+# CONFIG_HZ_300 is not set -+# CONFIG_HZ_1000 is not set -+CONFIG_HZ=250 -+CONFIG_PREEMPT_NONE=y -+# CONFIG_PREEMPT_VOLUNTARY is not set -+# CONFIG_PREEMPT is not set -+CONFIG_BINFMT_ELF=y -+# CONFIG_BINFMT_MISC is not set -+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y -+CONFIG_ARCH_FLATMEM_ENABLE=y -+CONFIG_ARCH_POPULATES_NODE_MAP=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 is not set -+CONFIG_SPLIT_PTLOCK_CPUS=4 -+# CONFIG_RESOURCES_64BIT is not set -+CONFIG_ZONE_DMA_FLAG=1 -+CONFIG_BOUNCE=y -+CONFIG_VIRT_TO_BUS=y -+CONFIG_PROC_DEVICETREE=y -+# CONFIG_CMDLINE_BOOL is not set -+# CONFIG_PM is not set -+CONFIG_SUSPEND_UP_POSSIBLE=y -+CONFIG_HIBERNATION_UP_POSSIBLE=y -+CONFIG_SECCOMP=y -+CONFIG_WANT_DEVICE_TREE=y -+CONFIG_DEVICE_TREE="" -+CONFIG_ISA_DMA_API=y -+ -+# -+# Bus options -+# -+CONFIG_ZONE_DMA=y -+CONFIG_GENERIC_ISA_DMA=y -+CONFIG_PPC_INDIRECT_PCI=y -+CONFIG_FSL_SOC=y -+# CONFIG_PCI is not set -+# CONFIG_PCI_DOMAINS is not set -+# CONFIG_PCI_SYSCALL is not set -+# CONFIG_ARCH_SUPPORTS_MSI is not set -+ -+# -+# PCCARD (PCMCIA/CardBus) support -+# -+# CONFIG_PCCARD is not set -+ -+# -+# Advanced setup -+# -+# CONFIG_ADVANCED_OPTIONS is not set -+ -+# -+# Default settings for advanced configuration options are used -+# -+CONFIG_HIGHMEM_START=0xfe000000 -+CONFIG_LOWMEM_SIZE=0x30000000 -+CONFIG_KERNEL_START=0xc0000000 -+CONFIG_TASK_SIZE=0x80000000 -+CONFIG_BOOT_LOAD=0x00800000 -+ -+# -+# Networking -+# -+CONFIG_NET=y -+ -+# -+# Networking options -+# -+CONFIG_PACKET=y -+# CONFIG_PACKET_MMAP is not set -+CONFIG_UNIX=y -+CONFIG_XFRM=y -+CONFIG_XFRM_USER=m -+# CONFIG_XFRM_SUB_POLICY is not set -+# CONFIG_XFRM_MIGRATE 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=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_XFRM_MODE_TRANSPORT=y -+CONFIG_INET_XFRM_MODE_TUNNEL=y -+CONFIG_INET_XFRM_MODE_BEET=y -+CONFIG_INET_DIAG=y -+CONFIG_INET_TCP_DIAG=y -+# CONFIG_TCP_CONG_ADVANCED is not set -+CONFIG_TCP_CONG_CUBIC=y -+CONFIG_DEFAULT_TCP_CONG="cubic" -+# CONFIG_TCP_MD5SIG is not set -+# 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 -+# CONFIG_IP_DCCP is not set -+# CONFIG_IP_SCTP is not set -+# 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_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_AF_RXRPC is not set -+ -+# -+# Wireless -+# -+# CONFIG_CFG80211 is not set -+# CONFIG_WIRELESS_EXT is not set -+# CONFIG_MAC80211 is not set -+# CONFIG_IEEE80211 is not set -+# CONFIG_RFKILL is not set -+# CONFIG_NET_9P is not set -+ -+# -+# Device Drivers -+# -+ -+# -+# Generic Driver Options -+# -+CONFIG_STANDALONE=y -+CONFIG_PREVENT_FIRMWARE_BUILD=y -+# CONFIG_FW_LOADER is not set -+# CONFIG_SYS_HYPERVISOR is not set -+# CONFIG_CONNECTOR is not set -+# CONFIG_MTD is not set -+CONFIG_OF_DEVICE=y -+# CONFIG_PARPORT is not set -+CONFIG_BLK_DEV=y -+# CONFIG_BLK_DEV_FD is not set -+# 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=32768 -+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 -+# CONFIG_CDROM_PKTCDVD is not set -+# CONFIG_ATA_OVER_ETH is not set -+CONFIG_MISC_DEVICES=y -+# CONFIG_EEPROM_93CX6 is not set -+# CONFIG_IDE is not set -+ -+# -+# SCSI device support -+# -+# CONFIG_RAID_ATTRS is not set -+CONFIG_SCSI=y -+CONFIG_SCSI_DMA=y -+# CONFIG_SCSI_TGT is not set -+# CONFIG_SCSI_NETLINK is not set -+CONFIG_SCSI_PROC_FS=y -+ -+# -+# SCSI support type (disk, tape, CD-ROM) -+# -+CONFIG_BLK_DEV_SD=y -+# CONFIG_CHR_DEV_ST is not set -+# CONFIG_CHR_DEV_OSST is not set -+# CONFIG_BLK_DEV_SR is not set -+CONFIG_CHR_DEV_SG=y -+# CONFIG_CHR_DEV_SCH is not set -+ -+# -+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -+# -+# CONFIG_SCSI_MULTI_LUN is not set -+# CONFIG_SCSI_CONSTANTS is not set -+# CONFIG_SCSI_LOGGING is not set -+# CONFIG_SCSI_SCAN_ASYNC is not set -+CONFIG_SCSI_WAIT_SCAN=m -+ -+# -+# SCSI Transports -+# -+# CONFIG_SCSI_SPI_ATTRS is not set -+# CONFIG_SCSI_FC_ATTRS is not set -+# CONFIG_SCSI_ISCSI_ATTRS is not set -+# CONFIG_SCSI_SAS_LIBSAS is not set -+CONFIG_SCSI_LOWLEVEL=y -+# CONFIG_ISCSI_TCP is not set -+# CONFIG_SCSI_DEBUG is not set -+CONFIG_ATA=y -+# CONFIG_ATA_NONSTANDARD is not set -+CONFIG_SATA_FSL=y -+# CONFIG_PATA_PLATFORM is not set -+# CONFIG_MD is not set -+# CONFIG_MACINTOSH_DRIVERS is not set -+CONFIG_NETDEVICES=y -+# CONFIG_NETDEVICES_MULTIQUEUE is not set -+# CONFIG_DUMMY is not set -+# CONFIG_BONDING is not set -+# CONFIG_MACVLAN is not set -+# CONFIG_EQUALIZER is not set -+# CONFIG_TUN is not set -+CONFIG_PHYLIB=y -+ -+# -+# MII PHY device drivers -+# -+CONFIG_MARVELL_PHY=y -+# CONFIG_DAVICOM_PHY is not set -+# CONFIG_QSEMI_PHY is not set -+# CONFIG_LXT_PHY is not set -+# CONFIG_CICADA_PHY is not set -+# CONFIG_VITESSE_PHY is not set -+# CONFIG_SMSC_PHY is not set -+# CONFIG_BROADCOM_PHY is not set -+# CONFIG_ICPLUS_PHY is not set -+# CONFIG_FIXED_PHY is not set -+CONFIG_NET_ETHERNET=y -+CONFIG_MII=y -+CONFIG_NETDEV_1000=y -+CONFIG_GIANFAR=y -+# CONFIG_GFAR_NAPI is not set -+CONFIG_NETDEV_10000=y -+ -+# -+# Wireless LAN -+# -+# CONFIG_WLAN_PRE80211 is not set -+# CONFIG_WLAN_80211 is not set -+# 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 -+# CONFIG_ISDN is not set -+# CONFIG_PHONE is not set -+ -+# -+# Input device support -+# -+CONFIG_INPUT=y -+# CONFIG_INPUT_FF_MEMLESS is not set -+# CONFIG_INPUT_POLLDEV is not set -+ -+# -+# Userland interfaces -+# -+# CONFIG_INPUT_MOUSEDEV is not set -+# 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 is not set -+# CONFIG_INPUT_MOUSE is not set -+# CONFIG_INPUT_JOYSTICK is not set -+# CONFIG_INPUT_TABLET 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 is not set -+# CONFIG_SERIAL_NONSTANDARD is not set -+ -+# -+# Serial drivers -+# -+CONFIG_SERIAL_8250=y -+CONFIG_SERIAL_8250_CONSOLE=y -+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_UARTLITE is not set -+CONFIG_SERIAL_CORE=y -+CONFIG_SERIAL_CORE_CONSOLE=y -+# CONFIG_SERIAL_OF_PLATFORM is not set -+CONFIG_UNIX98_PTYS=y -+CONFIG_LEGACY_PTYS=y -+CONFIG_LEGACY_PTY_COUNT=256 -+# CONFIG_IPMI_HANDLER is not set -+CONFIG_WATCHDOG=y -+# CONFIG_WATCHDOG_NOWAYOUT is not set -+ -+# -+# Watchdog Device Drivers -+# -+# CONFIG_SOFT_WATCHDOG is not set -+CONFIG_83xx_WDT=y -+# CONFIG_HW_RANDOM is not set -+# CONFIG_NVRAM is not set -+CONFIG_GEN_RTC=y -+# CONFIG_GEN_RTC_X is not set -+# CONFIG_R3964 is not set -+# CONFIG_RAW_DRIVER is not set -+# CONFIG_TCG_TPM is not set -+CONFIG_I2C=y -+CONFIG_I2C_BOARDINFO=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_MPC=y -+# CONFIG_I2C_OCORES is not set -+# CONFIG_I2C_PARPORT_LIGHT is not set -+# CONFIG_I2C_SIMTEC is not set -+# CONFIG_I2C_TAOS_EVM is not set -+# CONFIG_I2C_STUB is not set -+ -+# -+# Miscellaneous I2C Chip support -+# -+# CONFIG_SENSORS_DS1337 is not set -+# CONFIG_SENSORS_DS1374 is not set -+# CONFIG_DS1682 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_SENSORS_M41T00 is not set -+# CONFIG_SENSORS_MAX6875 is not set -+# CONFIG_SENSORS_TSL2550 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 -+# CONFIG_W1 is not set -+# CONFIG_POWER_SUPPLY is not set -+CONFIG_HWMON=y -+# CONFIG_HWMON_VID is not set -+# CONFIG_SENSORS_ABITUGURU is not set -+# CONFIG_SENSORS_ABITUGURU3 is not set -+# CONFIG_SENSORS_AD7418 is not set -+# CONFIG_SENSORS_ADM1021 is not set -+# CONFIG_SENSORS_ADM1025 is not set -+# CONFIG_SENSORS_ADM1026 is not set -+# CONFIG_SENSORS_ADM1029 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_LM93 is not set -+# CONFIG_SENSORS_MAX1619 is not set -+# CONFIG_SENSORS_MAX6650 is not set -+# CONFIG_SENSORS_PC87360 is not set -+# CONFIG_SENSORS_PC87427 is not set -+# CONFIG_SENSORS_DME1737 is not set -+# CONFIG_SENSORS_SMSC47M1 is not set -+# CONFIG_SENSORS_SMSC47M192 is not set -+# CONFIG_SENSORS_SMSC47B397 is not set -+# CONFIG_SENSORS_THMC50 is not set -+# CONFIG_SENSORS_VT1211 is not set -+# CONFIG_SENSORS_W83781D is not set -+# CONFIG_SENSORS_W83791D is not set -+# CONFIG_SENSORS_W83792D is not set -+# CONFIG_SENSORS_W83793 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 -+ -+# -+# Multifunction device drivers -+# -+# CONFIG_MFD_SM501 is not set -+ -+# -+# Multimedia devices -+# -+# CONFIG_VIDEO_DEV is not set -+# CONFIG_DVB_CORE is not set -+CONFIG_DAB=y -+ -+# -+# Graphics support -+# -+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set -+ -+# -+# Display device support -+# -+# CONFIG_DISPLAY_SUPPORT is not set -+# CONFIG_VGASTATE is not set -+CONFIG_VIDEO_OUTPUT_CONTROL=m -+# CONFIG_FB is not set -+# CONFIG_FB_IBM_GXT4500 is not set -+ -+# -+# Sound -+# -+# CONFIG_SOUND is not set -+CONFIG_HID_SUPPORT=y -+CONFIG_HID=y -+# CONFIG_HID_DEBUG is not set -+CONFIG_USB_SUPPORT=y -+CONFIG_USB_ARCH_HAS_HCD=y -+# CONFIG_USB_ARCH_HAS_OHCI is not set -+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 -+# CONFIG_MMC is not set -+# CONFIG_NEW_LEDS is not set -+# CONFIG_EDAC is not set -+# CONFIG_RTC_CLASS is not set -+ -+# -+# DMA Engine support -+# -+# CONFIG_DMA_ENGINE is not set -+ -+# -+# DMA Clients -+# -+ -+# -+# DMA Devices -+# -+ -+# -+# Userspace I/O -+# -+# CONFIG_UIO 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=y -+CONFIG_EXT3_FS_XATTR=y -+# CONFIG_EXT3_FS_POSIX_ACL is not set -+# CONFIG_EXT3_FS_SECURITY is not set -+# CONFIG_EXT4DEV_FS is not set -+CONFIG_JBD=y -+# CONFIG_JBD_DEBUG is not set -+CONFIG_FS_MBCACHE=y -+# 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_GFS2_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 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_MSDOS_FS is not set -+# CONFIG_VFAT_FS is not set -+# CONFIG_NTFS_FS is not set -+ -+# -+# Pseudo filesystems -+# -+CONFIG_PROC_FS=y -+CONFIG_PROC_KCORE=y -+CONFIG_PROC_SYSCTL=y -+CONFIG_SYSFS=y -+CONFIG_TMPFS=y -+# CONFIG_TMPFS_POSIX_ACL is not set -+# 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_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=y -+# 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_SUNRPC_GSS=y -+# CONFIG_SUNRPC_BIND34 is not set -+CONFIG_RPCSEC_GSS_KRB5=y -+# 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 -+ -+# -+# Partition Types -+# -+CONFIG_PARTITION_ADVANCED=y -+# CONFIG_ACORN_PARTITION is not set -+# CONFIG_OSF_PARTITION is not set -+# CONFIG_AMIGA_PARTITION is not set -+# CONFIG_ATARI_PARTITION is not set -+# CONFIG_MAC_PARTITION is not set -+CONFIG_MSDOS_PARTITION=y -+# CONFIG_BSD_DISKLABEL is not set -+# CONFIG_MINIX_SUBPARTITION is not set -+# CONFIG_SOLARIS_X86_PARTITION is not set -+# CONFIG_UNIXWARE_DISKLABEL is not set -+# CONFIG_LDM_PARTITION is not set -+# CONFIG_SGI_PARTITION is not set -+# CONFIG_ULTRIX_PARTITION is not set -+# CONFIG_SUN_PARTITION is not set -+# CONFIG_KARMA_PARTITION is not set -+# CONFIG_EFI_PARTITION is not set -+# CONFIG_SYSV68_PARTITION is not set -+ -+# -+# Native Language Support -+# -+# CONFIG_NLS is not set -+ -+# -+# Distributed Lock Manager -+# -+# CONFIG_DLM is not set -+# CONFIG_UCC_SLOW is not set -+ -+# -+# Library routines -+# -+CONFIG_BITREVERSE=y -+# CONFIG_CRC_CCITT is not set -+# CONFIG_CRC16 is not set -+# CONFIG_CRC_ITU_T is not set -+CONFIG_CRC32=y -+# CONFIG_CRC7 is not set -+# CONFIG_LIBCRC32C is not set -+CONFIG_PLIST=y -+CONFIG_HAS_IOMEM=y -+CONFIG_HAS_IOPORT=y -+CONFIG_HAS_DMA=y -+ -+# -+# Instrumentation Support -+# -+# CONFIG_PROFILING is not set -+# CONFIG_KPROBES is not set -+ -+# -+# Kernel hacking -+# -+# CONFIG_PRINTK_TIME is not set -+CONFIG_ENABLE_MUST_CHECK=y -+# CONFIG_MAGIC_SYSRQ is not set -+# CONFIG_UNUSED_SYMBOLS is not set -+# CONFIG_DEBUG_FS is not set -+# CONFIG_HEADERS_CHECK is not set -+# CONFIG_DEBUG_KERNEL is not set -+# CONFIG_DEBUG_BUGVERBOSE is not set -+# CONFIG_PPC_EARLY_DEBUG is not set -+ -+# -+# Security options -+# -+# CONFIG_KEYS is not set -+# CONFIG_SECURITY is not set -+CONFIG_CRYPTO=y -+CONFIG_CRYPTO_ALGAPI=y -+CONFIG_CRYPTO_BLKCIPHER=y -+CONFIG_CRYPTO_MANAGER=y -+# CONFIG_CRYPTO_HMAC is not set -+# CONFIG_CRYPTO_XCBC is not set -+# CONFIG_CRYPTO_NULL is not set -+# CONFIG_CRYPTO_MD4 is not set -+CONFIG_CRYPTO_MD5=y -+# CONFIG_CRYPTO_SHA1 is not set -+# 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_GF128MUL is not set -+CONFIG_CRYPTO_ECB=m -+CONFIG_CRYPTO_CBC=y -+CONFIG_CRYPTO_PCBC=m -+# CONFIG_CRYPTO_LRW is not set -+# CONFIG_CRYPTO_CRYPTD is not set -+CONFIG_CRYPTO_DES=y -+# CONFIG_CRYPTO_FCRYPT is not set -+# 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 is not set -+# CONFIG_CRYPTO_MICHAEL_MIC is not set -+# CONFIG_CRYPTO_CRC32C is not set -+# CONFIG_CRYPTO_CAMELLIA is not set -+# CONFIG_CRYPTO_TEST is not set -+CONFIG_CRYPTO_HW=y ---- a/arch/powerpc/configs/mpc8610_hpcd_defconfig -+++ b/arch/powerpc/configs/mpc8610_hpcd_defconfig -@@ -696,7 +696,7 @@ CONFIG_SERIAL_8250_RSA=y - CONFIG_SERIAL_CORE=y - CONFIG_SERIAL_CORE_CONSOLE=y - # CONFIG_SERIAL_JSM is not set --CONFIG_SERIAL_OF_PLATFORM=y -+# CONFIG_SERIAL_OF_PLATFORM is not set - CONFIG_UNIX98_PTYS=y - # CONFIG_LEGACY_PTYS is not set - # CONFIG_IPMI_HANDLER is not set -@@ -708,7 +708,60 @@ CONFIG_UNIX98_PTYS=y - # CONFIG_RAW_DRIVER is not set - # CONFIG_TCG_TPM is not set - CONFIG_DEVPORT=y --# CONFIG_I2C is not set -+CONFIG_I2C=y -+CONFIG_I2C_BOARDINFO=y -+# CONFIG_I2C_CHARDEV is not set -+ -+# -+# 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_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_MPC=y -+# CONFIG_I2C_NFORCE2 is not set -+# CONFIG_I2C_OCORES is not set -+# CONFIG_I2C_PARPORT_LIGHT is not set -+# CONFIG_I2C_PROSAVAGE is not set -+# CONFIG_I2C_SAVAGE4 is not set -+# CONFIG_I2C_SIMTEC is not set -+# CONFIG_I2C_SIS5595 is not set -+# CONFIG_I2C_SIS630 is not set -+# CONFIG_I2C_SIS96X is not set -+# CONFIG_I2C_TAOS_EVM is not set -+# CONFIG_I2C_VIA is not set -+# CONFIG_I2C_VIAPRO is not set -+# CONFIG_I2C_VOODOO3 is not set -+ -+# -+# Miscellaneous I2C Chip support -+# -+# CONFIG_SENSORS_DS1337 is not set -+# CONFIG_SENSORS_DS1374 is not set -+# CONFIG_DS1682 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_SENSORS_M41T00 is not set -+# CONFIG_SENSORS_MAX6875 is not set -+# CONFIG_SENSORS_TSL2550 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 -@@ -763,7 +816,119 @@ CONFIG_DUMMY_CONSOLE=y - # - # Sound - # --# CONFIG_SOUND is not set -+CONFIG_SOUND=y -+ -+# -+# Advanced Linux Sound Architecture -+# -+CONFIG_SND=y -+CONFIG_SND_TIMER=y -+CONFIG_SND_PCM=y -+# CONFIG_SND_SEQUENCER is not set -+CONFIG_SND_OSSEMUL=y -+CONFIG_SND_MIXER_OSS=y -+CONFIG_SND_PCM_OSS=y -+# CONFIG_SND_PCM_OSS_PLUGINS is not set -+# CONFIG_SND_DYNAMIC_MINORS is not set -+# CONFIG_SND_SUPPORT_OLD_API is not set -+CONFIG_SND_VERBOSE_PROCFS=y -+# CONFIG_SND_VERBOSE_PRINTK is not set -+# CONFIG_SND_DEBUG is not set -+ -+# -+# 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 -+ -+# -+# PCI devices -+# -+# CONFIG_SND_AD1889 is not set -+# CONFIG_SND_ALS300 is not set -+# CONFIG_SND_ALS4000 is not set -+# CONFIG_SND_ALI5451 is not set -+# CONFIG_SND_ATIIXP is not set -+# CONFIG_SND_ATIIXP_MODEM is not set -+# CONFIG_SND_AU8810 is not set -+# CONFIG_SND_AU8820 is not set -+# CONFIG_SND_AU8830 is not set -+# CONFIG_SND_AZT3328 is not set -+# CONFIG_SND_BT87X is not set -+# CONFIG_SND_CA0106 is not set -+# CONFIG_SND_CMIPCI is not set -+# CONFIG_SND_CS4281 is not set -+# CONFIG_SND_CS46XX is not set -+# CONFIG_SND_CS5530 is not set -+# CONFIG_SND_DARLA20 is not set -+# CONFIG_SND_GINA20 is not set -+# CONFIG_SND_LAYLA20 is not set -+# CONFIG_SND_DARLA24 is not set -+# CONFIG_SND_GINA24 is not set -+# CONFIG_SND_LAYLA24 is not set -+# CONFIG_SND_MONA is not set -+# CONFIG_SND_MIA is not set -+# CONFIG_SND_ECHO3G is not set -+# CONFIG_SND_INDIGO is not set -+# CONFIG_SND_INDIGOIO is not set -+# CONFIG_SND_INDIGODJ is not set -+# CONFIG_SND_EMU10K1 is not set -+# CONFIG_SND_EMU10K1X is not set -+# CONFIG_SND_ENS1370 is not set -+# CONFIG_SND_ENS1371 is not set -+# CONFIG_SND_ES1938 is not set -+# CONFIG_SND_ES1968 is not set -+# CONFIG_SND_FM801 is not set -+# CONFIG_SND_HDA_INTEL is not set -+# CONFIG_SND_HDSP is not set -+# CONFIG_SND_HDSPM is not set -+# CONFIG_SND_ICE1712 is not set -+# CONFIG_SND_ICE1724 is not set -+# CONFIG_SND_INTEL8X0 is not set -+# CONFIG_SND_INTEL8X0M is not set -+# CONFIG_SND_KORG1212 is not set -+# CONFIG_SND_MAESTRO3 is not set -+# CONFIG_SND_MIXART is not set -+# CONFIG_SND_NM256 is not set -+# CONFIG_SND_PCXHR is not set -+# CONFIG_SND_RIPTIDE is not set -+# CONFIG_SND_RME32 is not set -+# CONFIG_SND_RME96 is not set -+# CONFIG_SND_RME9652 is not set -+# CONFIG_SND_SONICVIBES is not set -+# CONFIG_SND_TRIDENT is not set -+# CONFIG_SND_VIA82XX is not set -+# CONFIG_SND_VIA82XX_MODEM is not set -+# CONFIG_SND_VX222 is not set -+# CONFIG_SND_YMFPCI is not set -+ -+# -+# ALSA PowerMac devices -+# -+ -+# -+# ALSA PowerPC devices -+# -+ -+# -+# System on Chip audio support -+# -+CONFIG_SND_SOC=y -+ -+# -+# SoC Audio support for SuperH -+# -+ -+# -+# ALSA SoC audio for Freescale SOCs -+# -+CONFIG_SND_SOC_MPC8610=y -+CONFIG_SND_SOC_MPC8610_HPCD=y -+CONFIG_SND_SOC_CS4270=y -+CONFIG_SND_SOC_CS4270_VD33_ERRATA=y -+ - CONFIG_HID_SUPPORT=y - CONFIG_HID=y - # CONFIG_HID_DEBUG is not set ---- a/arch/powerpc/configs/pasemi_defconfig -+++ b/arch/powerpc/configs/pasemi_defconfig -@@ -1,7 +1,7 @@ - # - # Automatically generated make config: don't edit --# Linux kernel version: 2.6.24-rc4 --# Thu Dec 6 16:49:03 2007 -+# Linux kernel version: 2.6.24-rc6 -+# Tue Jan 15 10:26:10 2008 - # - CONFIG_PPC64=y - -@@ -152,7 +152,6 @@ CONFIG_PPC_PASEMI=y - CONFIG_PPC_PASEMI_IOMMU=y - # CONFIG_PPC_PASEMI_IOMMU_DMA_FORCE is not set - CONFIG_PPC_PASEMI_MDIO=y --CONFIG_ELECTRA_IDE=y - # CONFIG_PPC_CELLEB is not set - # CONFIG_PPC_PS3 is not set - # CONFIG_PPC_CELL is not set -@@ -256,7 +255,7 @@ CONFIG_PCI_DOMAINS=y - CONFIG_PCI_SYSCALL=y - # CONFIG_PCIEPORTBUS is not set - CONFIG_ARCH_SUPPORTS_MSI=y --# CONFIG_PCI_MSI is not set -+CONFIG_PCI_MSI=y - CONFIG_PCI_LEGACY=y - # CONFIG_PCI_DEBUG is not set - CONFIG_PCCARD=y -@@ -663,7 +662,26 @@ CONFIG_PATA_PCMCIA=y - # CONFIG_PATA_VIA is not set - # CONFIG_PATA_WINBOND is not set - CONFIG_PATA_PLATFORM=y --# CONFIG_MD is not set -+CONFIG_PATA_OF_PLATFORM=y -+CONFIG_MD=y -+CONFIG_BLK_DEV_MD=y -+CONFIG_MD_LINEAR=y -+CONFIG_MD_RAID0=y -+CONFIG_MD_RAID1=y -+CONFIG_MD_RAID10=y -+CONFIG_MD_RAID456=y -+CONFIG_MD_RAID5_RESHAPE=y -+# CONFIG_MD_MULTIPATH is not set -+# CONFIG_MD_FAULTY is not set -+CONFIG_BLK_DEV_DM=y -+# CONFIG_DM_DEBUG is not set -+CONFIG_DM_CRYPT=y -+# CONFIG_DM_SNAPSHOT is not set -+# CONFIG_DM_MIRROR is not set -+# CONFIG_DM_ZERO is not set -+# CONFIG_DM_MULTIPATH is not set -+# CONFIG_DM_DELAY is not set -+# CONFIG_DM_UEVENT is not set - # CONFIG_FUSION is not set - - # -@@ -1686,6 +1704,10 @@ CONFIG_XMON_DISASSEMBLY=y - # CONFIG_KEYS is not set - # CONFIG_SECURITY is not set - # CONFIG_SECURITY_FILE_CAPABILITIES is not set -+CONFIG_XOR_BLOCKS=y -+CONFIG_ASYNC_CORE=y -+CONFIG_ASYNC_MEMCPY=y -+CONFIG_ASYNC_XOR=y - CONFIG_CRYPTO=y - CONFIG_CRYPTO_ALGAPI=y - CONFIG_CRYPTO_BLKCIPHER=y ---- a/arch/powerpc/configs/ppc64_defconfig -+++ b/arch/powerpc/configs/ppc64_defconfig -@@ -1,7 +1,7 @@ - # - # Automatically generated make config: don't edit - # Linux kernel version: 2.6.24-rc4 --# Thu Dec 6 16:49:07 2007 -+# Fri Dec 21 14:47:29 2007 - # - CONFIG_PPC64=y - -@@ -211,7 +211,7 @@ CONFIG_MMIO_NVRAM=y - CONFIG_MPIC_U3_HT_IRQS=y - CONFIG_MPIC_BROKEN_REGREAD=y - CONFIG_IBMVIO=y --# CONFIG_IBMEBUS is not set -+CONFIG_IBMEBUS=y - # CONFIG_PPC_MPC106 is not set - CONFIG_PPC_970_NAP=y - CONFIG_PPC_INDIRECT_IO=y -@@ -375,7 +375,7 @@ CONFIG_INET_TUNNEL=y - CONFIG_INET_XFRM_MODE_TRANSPORT=y - CONFIG_INET_XFRM_MODE_TUNNEL=y - CONFIG_INET_XFRM_MODE_BEET=y --# CONFIG_INET_LRO is not set -+CONFIG_INET_LRO=m - CONFIG_INET_DIAG=y - CONFIG_INET_TCP_DIAG=y - # CONFIG_TCP_CONG_ADVANCED is not set -@@ -929,6 +929,7 @@ CONFIG_SPIDER_NET=m - CONFIG_NETDEV_10000=y - # CONFIG_CHELSIO_T1 is not set - # CONFIG_CHELSIO_T3 is not set -+CONFIG_EHEA=m - # CONFIG_IXGBE is not set - CONFIG_IXGB=m - # CONFIG_IXGB_NAPI is not set -@@ -1558,6 +1559,7 @@ CONFIG_INFINIBAND_ADDR_TRANS=y - CONFIG_INFINIBAND_MTHCA=m - CONFIG_INFINIBAND_MTHCA_DEBUG=y - # CONFIG_INFINIBAND_IPATH is not set -+CONFIG_INFINIBAND_EHCA=m - # CONFIG_INFINIBAND_AMSO1100 is not set - # CONFIG_MLX4_INFINIBAND is not set - CONFIG_INFINIBAND_IPOIB=m ---- a/arch/powerpc/configs/ps3_defconfig -+++ b/arch/powerpc/configs/ps3_defconfig -@@ -1,7 +1,7 @@ - # - # Automatically generated make config: don't edit --# Linux kernel version: 2.6.24-rc4 --# Tue Dec 4 22:49:57 2007 -+# Linux kernel version: 2.6.24-rc8 -+# Wed Jan 16 14:31:21 2008 - # - CONFIG_PPC64=y - -@@ -103,6 +103,7 @@ CONFIG_VM_EVENT_COUNTERS=y - CONFIG_SLAB=y - # CONFIG_SLUB is not set - # CONFIG_SLOB is not set -+CONFIG_SLABINFO=y - CONFIG_RT_MUTEXES=y - # CONFIG_TINY_SHMEM is not set - CONFIG_BASE_SMALL=0 -@@ -154,7 +155,6 @@ CONFIG_PPC_PS3=y - # CONFIG_PS3_ADVANCED is not set - CONFIG_PS3_HTAB_SIZE=20 - # CONFIG_PS3_DYNAMIC_DMA is not set --CONFIG_PS3_USE_LPAR_ADDR=y - CONFIG_PS3_VUART=y - CONFIG_PS3_PS3AV=y - CONFIG_PS3_SYS_MANAGER=y -@@ -162,6 +162,7 @@ CONFIG_PS3_STORAGE=y - CONFIG_PS3_DISK=y - CONFIG_PS3_ROM=y - CONFIG_PS3_FLASH=y -+CONFIG_PS3_LPM=m - CONFIG_PPC_CELL=y - # CONFIG_PPC_CELL_NATIVE is not set - # CONFIG_PPC_IBM_CELL_BLADE is not set -@@ -225,7 +226,7 @@ CONFIG_HAVE_MEMORY_PRESENT=y - # CONFIG_SPARSEMEM_STATIC is not set - CONFIG_SPARSEMEM_EXTREME=y - CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y --CONFIG_SPARSEMEM_VMEMMAP=y -+# CONFIG_SPARSEMEM_VMEMMAP is not set - CONFIG_MEMORY_HOTPLUG=y - CONFIG_MEMORY_HOTPLUG_SPARSE=y - CONFIG_SPLIT_PTLOCK_CPUS=4 -@@ -338,7 +339,26 @@ CONFIG_IPV6_SIT=y - # CONFIG_NET_PKTGEN is not set - # CONFIG_HAMRADIO is not set - # CONFIG_IRDA is not set --# CONFIG_BT is not set -+CONFIG_BT=m -+CONFIG_BT_L2CAP=m -+CONFIG_BT_SCO=m -+CONFIG_BT_RFCOMM=m -+CONFIG_BT_RFCOMM_TTY=y -+CONFIG_BT_BNEP=m -+CONFIG_BT_BNEP_MC_FILTER=y -+CONFIG_BT_BNEP_PROTO_FILTER=y -+CONFIG_BT_HIDP=m -+ -+# -+# Bluetooth device drivers -+# -+CONFIG_BT_HCIUSB=m -+CONFIG_BT_HCIUSB_SCO=y -+# CONFIG_BT_HCIUART is not set -+# CONFIG_BT_HCIBCM203X is not set -+# CONFIG_BT_HCIBPA10X is not set -+# CONFIG_BT_HCIBFUSB is not set -+# CONFIG_BT_HCIVHCI is not set - # CONFIG_AF_RXRPC is not set - - # -@@ -666,14 +686,14 @@ CONFIG_LOGO_LINUX_CLUT224=y - # - # Sound - # --CONFIG_SOUND=y -+CONFIG_SOUND=m - - # - # Advanced Linux Sound Architecture - # --CONFIG_SND=y --CONFIG_SND_TIMER=y --CONFIG_SND_PCM=y -+CONFIG_SND=m -+CONFIG_SND_TIMER=m -+CONFIG_SND_PCM=m - # CONFIG_SND_SEQUENCER is not set - # CONFIG_SND_MIXER_OSS is not set - # CONFIG_SND_PCM_OSS is not set -@@ -702,7 +722,7 @@ CONFIG_SND_VERBOSE_PROCFS=y - # - # ALSA PowerPC devices - # --CONFIG_SND_PS3=y -+CONFIG_SND_PS3=m - CONFIG_SND_PS3_DEFAULT_START_DELAY=2000 - - # -@@ -747,7 +767,7 @@ CONFIG_USB_SUPPORT=y - CONFIG_USB_ARCH_HAS_HCD=y - CONFIG_USB_ARCH_HAS_OHCI=y - CONFIG_USB_ARCH_HAS_EHCI=y --CONFIG_USB=y -+CONFIG_USB=m - # CONFIG_USB_DEBUG is not set - - # -@@ -761,13 +781,13 @@ CONFIG_USB_DEVICEFS=y - # - # USB Host Controller Drivers - # --CONFIG_USB_EHCI_HCD=y -+CONFIG_USB_EHCI_HCD=m - # CONFIG_USB_EHCI_SPLIT_ISO is not set - # CONFIG_USB_EHCI_ROOT_HUB_TT is not set - # CONFIG_USB_EHCI_TT_NEWSCHED is not set - CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=y - # CONFIG_USB_ISP116X_HCD is not set --CONFIG_USB_OHCI_HCD=y -+CONFIG_USB_OHCI_HCD=m - # CONFIG_USB_OHCI_HCD_PPC_OF is not set - # CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set - CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y -@@ -1033,7 +1053,8 @@ CONFIG_HAS_IOMEM=y - CONFIG_HAS_IOPORT=y - CONFIG_HAS_DMA=y - CONFIG_INSTRUMENTATION=y --# CONFIG_PROFILING is not set -+CONFIG_PROFILING=y -+CONFIG_OPROFILE=m - # CONFIG_KPROBES is not set - # CONFIG_MARKERS is not set - ---- /dev/null -+++ b/arch/powerpc/configs/rainier_defconfig -@@ -0,0 +1,873 @@ -+# -+# Automatically generated make config: don't edit -+# Linux kernel version: 2.6.24-rc6 -+# Mon Dec 24 11:22:40 2007 -+# -+# CONFIG_PPC64 is not set -+ -+# -+# Processor support -+# -+# CONFIG_6xx is not set -+# CONFIG_PPC_85xx is not set -+# CONFIG_PPC_8xx is not set -+# CONFIG_40x is not set -+CONFIG_44x=y -+# CONFIG_E200 is not set -+CONFIG_4xx=y -+CONFIG_BOOKE=y -+CONFIG_PTE_64BIT=y -+CONFIG_PHYS_64BIT=y -+# CONFIG_PPC_MM_SLICES is not set -+CONFIG_NOT_COHERENT_CACHE=y -+CONFIG_PPC32=y -+CONFIG_WORD_SIZE=32 -+CONFIG_PPC_MERGE=y -+CONFIG_MMU=y -+CONFIG_GENERIC_CMOS_UPDATE=y -+CONFIG_GENERIC_TIME=y -+CONFIG_GENERIC_TIME_VSYSCALL=y -+CONFIG_GENERIC_CLOCKEVENTS=y -+CONFIG_GENERIC_HARDIRQS=y -+CONFIG_IRQ_PER_CPU=y -+CONFIG_RWSEM_XCHGADD_ALGORITHM=y -+CONFIG_ARCH_HAS_ILOG2_U32=y -+CONFIG_GENERIC_HWEIGHT=y -+CONFIG_GENERIC_CALIBRATE_DELAY=y -+CONFIG_GENERIC_FIND_NEXT_BIT=y -+# CONFIG_ARCH_NO_VIRT_TO_BUS is not set -+CONFIG_PPC=y -+CONFIG_EARLY_PRINTK=y -+CONFIG_GENERIC_NVRAM=y -+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -+CONFIG_ARCH_MAY_HAVE_PC_FDC=y -+CONFIG_PPC_OF=y -+CONFIG_OF=y -+CONFIG_PPC_UDBG_16550=y -+# CONFIG_GENERIC_TBSYNC is not set -+CONFIG_AUDIT_ARCH=y -+CONFIG_GENERIC_BUG=y -+# CONFIG_DEFAULT_UIMAGE is not set -+CONFIG_PPC_DCR_NATIVE=y -+# CONFIG_PPC_DCR_MMIO is not set -+CONFIG_PPC_DCR=y -+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" -+ -+# -+# General setup -+# -+CONFIG_EXPERIMENTAL=y -+CONFIG_BROKEN_ON_SMP=y -+CONFIG_INIT_ENV_ARG_LIMIT=32 -+CONFIG_LOCALVERSION="" -+CONFIG_LOCALVERSION_AUTO=y -+CONFIG_SWAP=y -+CONFIG_SYSVIPC=y -+CONFIG_SYSVIPC_SYSCTL=y -+CONFIG_POSIX_MQUEUE=y -+# CONFIG_BSD_PROCESS_ACCT is not set -+# CONFIG_TASKSTATS is not set -+# CONFIG_USER_NS is not set -+# CONFIG_PID_NS is not set -+# CONFIG_AUDIT is not set -+# CONFIG_IKCONFIG is not set -+CONFIG_LOG_BUF_SHIFT=14 -+# CONFIG_CGROUPS is not set -+CONFIG_FAIR_GROUP_SCHED=y -+CONFIG_FAIR_USER_SCHED=y -+# CONFIG_FAIR_CGROUP_SCHED is not set -+CONFIG_SYSFS_DEPRECATED=y -+# CONFIG_RELAY is not set -+CONFIG_BLK_DEV_INITRD=y -+CONFIG_INITRAMFS_SOURCE="" -+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -+CONFIG_SYSCTL=y -+CONFIG_EMBEDDED=y -+CONFIG_SYSCTL_SYSCALL=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_ANON_INODES=y -+CONFIG_EPOLL=y -+CONFIG_SIGNALFD=y -+CONFIG_EVENTFD=y -+CONFIG_SHMEM=y -+CONFIG_VM_EVENT_COUNTERS=y -+CONFIG_SLUB_DEBUG=y -+# CONFIG_SLAB is not set -+CONFIG_SLUB=y -+# CONFIG_SLOB is not set -+CONFIG_RT_MUTEXES=y -+# CONFIG_TINY_SHMEM is not set -+CONFIG_BASE_SMALL=0 -+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 -+CONFIG_BLOCK=y -+CONFIG_LBD=y -+# CONFIG_BLK_DEV_IO_TRACE is not set -+# CONFIG_LSF is not set -+# CONFIG_BLK_DEV_BSG is not set -+ -+# -+# IO Schedulers -+# -+CONFIG_IOSCHED_NOOP=y -+CONFIG_IOSCHED_AS=y -+CONFIG_IOSCHED_DEADLINE=y -+CONFIG_IOSCHED_CFQ=y -+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" -+# CONFIG_PPC4xx_PCI_EXPRESS is not set -+ -+# -+# Platform support -+# -+# CONFIG_PPC_MPC52xx is not set -+# CONFIG_PPC_MPC5200 is not set -+# CONFIG_PPC_CELL is not set -+# CONFIG_PPC_CELL_NATIVE is not set -+# CONFIG_PQ2ADS is not set -+# CONFIG_BAMBOO is not set -+# CONFIG_EBONY is not set -+# CONFIG_SEQUOIA is not set -+# CONFIG_TAISHAN is not set -+# CONFIG_KATMAI is not set -+CONFIG_RAINIER=y -+CONFIG_440GRX=y -+# CONFIG_MPIC is not set -+# CONFIG_MPIC_WEIRD is not set -+# CONFIG_PPC_I8259 is not set -+# CONFIG_PPC_RTAS is not set -+# CONFIG_MMIO_NVRAM is not set -+# CONFIG_PPC_MPC106 is not set -+# CONFIG_PPC_970_NAP is not set -+# CONFIG_PPC_INDIRECT_IO is not set -+# CONFIG_GENERIC_IOMAP is not set -+# CONFIG_CPU_FREQ is not set -+# CONFIG_CPM2 is not set -+# CONFIG_FSL_ULI1575 is not set -+ -+# -+# Kernel options -+# -+# CONFIG_HIGHMEM is not set -+# CONFIG_TICK_ONESHOT is not set -+# CONFIG_NO_HZ is not set -+# CONFIG_HIGH_RES_TIMERS is not set -+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y -+# CONFIG_HZ_100 is not set -+CONFIG_HZ_250=y -+# CONFIG_HZ_300 is not set -+# CONFIG_HZ_1000 is not set -+CONFIG_HZ=250 -+CONFIG_PREEMPT_NONE=y -+# CONFIG_PREEMPT_VOLUNTARY is not set -+# CONFIG_PREEMPT is not set -+CONFIG_BINFMT_ELF=y -+# CONFIG_BINFMT_MISC is not set -+CONFIG_MATH_EMULATION=y -+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y -+CONFIG_ARCH_FLATMEM_ENABLE=y -+CONFIG_ARCH_POPULATES_NODE_MAP=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 is not set -+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set -+CONFIG_SPLIT_PTLOCK_CPUS=4 -+CONFIG_RESOURCES_64BIT=y -+CONFIG_ZONE_DMA_FLAG=1 -+CONFIG_BOUNCE=y -+CONFIG_VIRT_TO_BUS=y -+CONFIG_PROC_DEVICETREE=y -+CONFIG_CMDLINE_BOOL=y -+CONFIG_CMDLINE="" -+CONFIG_SECCOMP=y -+CONFIG_WANT_DEVICE_TREE=y -+CONFIG_DEVICE_TREE="rainier.dts" -+CONFIG_ISA_DMA_API=y -+ -+# -+# Bus options -+# -+CONFIG_ZONE_DMA=y -+CONFIG_PPC_INDIRECT_PCI=y -+CONFIG_PCI=y -+CONFIG_PCI_DOMAINS=y -+CONFIG_PCI_SYSCALL=y -+# CONFIG_PCIEPORTBUS is not set -+CONFIG_ARCH_SUPPORTS_MSI=y -+# CONFIG_PCI_MSI is not set -+CONFIG_PCI_LEGACY=y -+# CONFIG_PCI_DEBUG is not set -+# CONFIG_PCCARD is not set -+# CONFIG_HOTPLUG_PCI is not set -+ -+# -+# Advanced setup -+# -+# CONFIG_ADVANCED_OPTIONS is not set -+ -+# -+# Default settings for advanced configuration options are used -+# -+CONFIG_HIGHMEM_START=0xfe000000 -+CONFIG_LOWMEM_SIZE=0x30000000 -+CONFIG_KERNEL_START=0xc0000000 -+CONFIG_TASK_SIZE=0xc0000000 -+CONFIG_CONSISTENT_START=0xff100000 -+CONFIG_CONSISTENT_SIZE=0x00200000 -+CONFIG_BOOT_LOAD=0x01000000 -+ -+# -+# Networking -+# -+CONFIG_NET=y -+ -+# -+# Networking options -+# -+CONFIG_PACKET=y -+# CONFIG_PACKET_MMAP is not set -+CONFIG_UNIX=y -+# CONFIG_NET_KEY is not set -+CONFIG_INET=y -+# CONFIG_IP_MULTICAST is not set -+# 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_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 is not set -+# CONFIG_INET_XFRM_MODE_TUNNEL is not set -+# CONFIG_INET_XFRM_MODE_BEET is not set -+# CONFIG_INET_LRO is not set -+CONFIG_INET_DIAG=y -+CONFIG_INET_TCP_DIAG=y -+# CONFIG_TCP_CONG_ADVANCED is not set -+CONFIG_TCP_CONG_CUBIC=y -+CONFIG_DEFAULT_TCP_CONG="cubic" -+# CONFIG_TCP_MD5SIG is not set -+# 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 -+# CONFIG_IP_DCCP is not set -+# CONFIG_IP_SCTP is not set -+# 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_ECONET is not set -+# CONFIG_WAN_ROUTER is not set -+# 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_AF_RXRPC is not set -+ -+# -+# Wireless -+# -+# CONFIG_CFG80211 is not set -+# CONFIG_WIRELESS_EXT is not set -+# CONFIG_MAC80211 is not set -+# CONFIG_IEEE80211 is not set -+# CONFIG_RFKILL is not set -+# CONFIG_NET_9P is not set -+ -+# -+# Device Drivers -+# -+ -+# -+# Generic Driver Options -+# -+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -+CONFIG_STANDALONE=y -+CONFIG_PREVENT_FIRMWARE_BUILD=y -+CONFIG_FW_LOADER=y -+# CONFIG_DEBUG_DRIVER is not set -+# CONFIG_DEBUG_DEVRES is not set -+# CONFIG_SYS_HYPERVISOR is not set -+CONFIG_CONNECTOR=y -+CONFIG_PROC_EVENTS=y -+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 -+ -+# -+# User Modules And Translation Layers -+# -+CONFIG_MTD_CHAR=y -+# CONFIG_MTD_BLKDEVS 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 -+# CONFIG_SSFDC is not set -+# CONFIG_MTD_OOPS is not set -+ -+# -+# RAM/ROM/Flash chip drivers -+# -+CONFIG_MTD_CFI=y -+CONFIG_MTD_JEDECPROBE=y -+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=y -+# 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 -+ -+# -+# Mapping drivers for chip access -+# -+# CONFIG_MTD_COMPLEX_MAPPINGS is not set -+# CONFIG_MTD_PHYSMAP is not set -+CONFIG_MTD_PHYSMAP_OF=y -+# CONFIG_MTD_INTEL_VR_NOR is not set -+# CONFIG_MTD_PLATRAM is not set -+ -+# -+# Self-contained MTD device drivers -+# -+# CONFIG_MTD_PMC551 is not set -+# 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 -+# CONFIG_MTD_NAND is not set -+# CONFIG_MTD_ONENAND is not set -+ -+# -+# UBI - Unsorted block images -+# -+# CONFIG_MTD_UBI is not set -+CONFIG_OF_DEVICE=y -+# CONFIG_PARPORT is not set -+CONFIG_BLK_DEV=y -+# 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 is not set -+# CONFIG_BLK_DEV_NBD is not set -+# CONFIG_BLK_DEV_SX8 is not set -+CONFIG_BLK_DEV_RAM=y -+CONFIG_BLK_DEV_RAM_COUNT=16 -+CONFIG_BLK_DEV_RAM_SIZE=35000 -+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 -+# CONFIG_CDROM_PKTCDVD is not set -+# CONFIG_ATA_OVER_ETH is not set -+# CONFIG_XILINX_SYSACE is not set -+CONFIG_MISC_DEVICES=y -+# CONFIG_PHANTOM is not set -+# CONFIG_EEPROM_93CX6 is not set -+# CONFIG_SGI_IOC4 is not set -+# CONFIG_TIFM_CORE is not set -+# CONFIG_IDE is not set -+ -+# -+# SCSI device support -+# -+# CONFIG_RAID_ATTRS is not set -+# CONFIG_SCSI is not set -+# CONFIG_SCSI_DMA is not set -+# CONFIG_SCSI_NETLINK is not set -+# CONFIG_ATA is not set -+# CONFIG_MD is not set -+# CONFIG_FUSION is not set -+ -+# -+# IEEE 1394 (FireWire) support -+# -+# CONFIG_FIREWIRE is not set -+# CONFIG_IEEE1394 is not set -+# CONFIG_I2O is not set -+CONFIG_MACINTOSH_DRIVERS=y -+# CONFIG_MAC_EMUMOUSEBTN is not set -+# CONFIG_WINDFARM is not set -+CONFIG_NETDEVICES=y -+# CONFIG_NETDEVICES_MULTIQUEUE is not set -+# CONFIG_DUMMY is not set -+# CONFIG_BONDING is not set -+# CONFIG_MACVLAN is not set -+# CONFIG_EQUALIZER is not set -+# CONFIG_TUN is not set -+# CONFIG_VETH is not set -+# CONFIG_IP1000 is not set -+# CONFIG_ARCNET is not set -+# CONFIG_NET_ETHERNET is not set -+CONFIG_IBM_NEW_EMAC_ZMII=y -+CONFIG_IBM_NEW_EMAC_RGMII=y -+CONFIG_IBM_NEW_EMAC_EMAC4=y -+CONFIG_NETDEV_1000=y -+# CONFIG_ACENIC is not set -+# CONFIG_DL2K is not set -+# CONFIG_E1000 is not set -+# CONFIG_E1000E 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 -+# CONFIG_QLA3XXX is not set -+# CONFIG_ATL1 is not set -+CONFIG_NETDEV_10000=y -+# CONFIG_CHELSIO_T1 is not set -+# CONFIG_CHELSIO_T3 is not set -+# CONFIG_IXGBE is not set -+# CONFIG_IXGB is not set -+# CONFIG_S2IO is not set -+# CONFIG_MYRI10GE is not set -+# CONFIG_NETXEN_NIC is not set -+# CONFIG_NIU is not set -+# CONFIG_MLX4_CORE is not set -+# CONFIG_TEHUTI is not set -+# CONFIG_TR is not set -+ -+# -+# Wireless LAN -+# -+# CONFIG_WLAN_PRE80211 is not set -+# CONFIG_WLAN_80211 is not set -+# CONFIG_WAN is not set -+# CONFIG_FDDI is not set -+# CONFIG_HIPPI 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 -+# CONFIG_ISDN is not set -+# CONFIG_PHONE is not set -+ -+# -+# Input device support -+# -+# CONFIG_INPUT is not set -+ -+# -+# Hardware I/O ports -+# -+# CONFIG_SERIO is not set -+# CONFIG_GAMEPORT is not set -+ -+# -+# Character devices -+# -+# CONFIG_VT is not set -+# CONFIG_SERIAL_NONSTANDARD is not set -+ -+# -+# Serial drivers -+# -+CONFIG_SERIAL_8250=y -+CONFIG_SERIAL_8250_CONSOLE=y -+# CONFIG_SERIAL_8250_PCI is not set -+CONFIG_SERIAL_8250_NR_UARTS=4 -+CONFIG_SERIAL_8250_RUNTIME_UARTS=4 -+CONFIG_SERIAL_8250_EXTENDED=y -+# CONFIG_SERIAL_8250_MANY_PORTS is not set -+CONFIG_SERIAL_8250_SHARE_IRQ=y -+# CONFIG_SERIAL_8250_DETECT_IRQ is not set -+# CONFIG_SERIAL_8250_RSA is not set -+ -+# -+# Non-8250 serial port support -+# -+# CONFIG_SERIAL_UARTLITE is not set -+CONFIG_SERIAL_CORE=y -+CONFIG_SERIAL_CORE_CONSOLE=y -+# CONFIG_SERIAL_JSM is not set -+CONFIG_SERIAL_OF_PLATFORM=y -+CONFIG_UNIX98_PTYS=y -+CONFIG_LEGACY_PTYS=y -+CONFIG_LEGACY_PTY_COUNT=256 -+# CONFIG_IPMI_HANDLER is not set -+# CONFIG_HW_RANDOM is not set -+# CONFIG_NVRAM is not set -+# CONFIG_GEN_RTC is not set -+# CONFIG_R3964 is not set -+# CONFIG_APPLICOM is not set -+# CONFIG_RAW_DRIVER is not set -+# CONFIG_TCG_TPM is not set -+CONFIG_DEVPORT=y -+# CONFIG_I2C is not set -+ -+# -+# SPI support -+# -+# CONFIG_SPI is not set -+# CONFIG_SPI_MASTER is not set -+# CONFIG_W1 is not set -+# CONFIG_POWER_SUPPLY is not set -+# CONFIG_HWMON is not set -+# CONFIG_WATCHDOG is not set -+ -+# -+# Sonics Silicon Backplane -+# -+CONFIG_SSB_POSSIBLE=y -+# CONFIG_SSB is not set -+ -+# -+# Multifunction device drivers -+# -+# CONFIG_MFD_SM501 is not set -+ -+# -+# Multimedia devices -+# -+# CONFIG_VIDEO_DEV is not set -+# CONFIG_DVB_CORE is not set -+CONFIG_DAB=y -+ -+# -+# Graphics support -+# -+# CONFIG_AGP is not set -+# CONFIG_DRM is not set -+# CONFIG_VGASTATE is not set -+CONFIG_VIDEO_OUTPUT_CONTROL=m -+# CONFIG_FB is not set -+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set -+ -+# -+# Display device support -+# -+# CONFIG_DISPLAY_SUPPORT is not set -+ -+# -+# Sound -+# -+# CONFIG_SOUND is not set -+CONFIG_USB_SUPPORT=y -+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 -+# CONFIG_MMC is not set -+# CONFIG_NEW_LEDS is not set -+# CONFIG_INFINIBAND is not set -+# CONFIG_EDAC is not set -+# CONFIG_RTC_CLASS is not set -+ -+# -+# Userspace I/O -+# -+# CONFIG_UIO 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_EXT4DEV_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_GFS2_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 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_MSDOS_FS is not set -+# CONFIG_VFAT_FS is not set -+# CONFIG_NTFS_FS is not set -+ -+# -+# Pseudo filesystems -+# -+CONFIG_PROC_FS=y -+CONFIG_PROC_KCORE=y -+CONFIG_PROC_SYSCTL=y -+CONFIG_SYSFS=y -+CONFIG_TMPFS=y -+# CONFIG_TMPFS_POSIX_ACL is not set -+# CONFIG_HUGETLB_PAGE 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_JFFS2_FS=y -+CONFIG_JFFS2_FS_DEBUG=0 -+CONFIG_JFFS2_FS_WRITEBUFFER=y -+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set -+# 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_LZO is not set -+CONFIG_JFFS2_RTIME=y -+# CONFIG_JFFS2_RUBIN is not set -+CONFIG_CRAMFS=y -+# 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 -+CONFIG_NETWORK_FILESYSTEMS=y -+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_SUNRPC_BIND34 is not set -+# 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 -+ -+# -+# Partition Types -+# -+# CONFIG_PARTITION_ADVANCED is not set -+CONFIG_MSDOS_PARTITION=y -+# CONFIG_NLS is not set -+# CONFIG_DLM is not set -+# CONFIG_UCC_SLOW is not set -+ -+# -+# Library routines -+# -+CONFIG_BITREVERSE=y -+# CONFIG_CRC_CCITT is not set -+# CONFIG_CRC16 is not set -+# CONFIG_CRC_ITU_T is not set -+CONFIG_CRC32=y -+# CONFIG_CRC7 is not set -+# CONFIG_LIBCRC32C is not set -+CONFIG_ZLIB_INFLATE=y -+CONFIG_ZLIB_DEFLATE=y -+CONFIG_PLIST=y -+CONFIG_HAS_IOMEM=y -+CONFIG_HAS_IOPORT=y -+CONFIG_HAS_DMA=y -+CONFIG_INSTRUMENTATION=y -+# CONFIG_PROFILING is not set -+# CONFIG_KPROBES is not set -+# CONFIG_MARKERS is not set -+ -+# -+# Kernel hacking -+# -+# CONFIG_PRINTK_TIME is not set -+CONFIG_ENABLE_WARN_DEPRECATED=y -+CONFIG_ENABLE_MUST_CHECK=y -+CONFIG_MAGIC_SYSRQ=y -+# CONFIG_UNUSED_SYMBOLS is not set -+# CONFIG_DEBUG_FS is not set -+# CONFIG_HEADERS_CHECK is not set -+CONFIG_DEBUG_KERNEL=y -+# CONFIG_DEBUG_SHIRQ is not set -+CONFIG_DETECT_SOFTLOCKUP=y -+CONFIG_SCHED_DEBUG=y -+# CONFIG_SCHEDSTATS is not set -+# CONFIG_TIMER_STATS is not set -+# CONFIG_SLUB_DEBUG_ON is not set -+# CONFIG_DEBUG_RT_MUTEXES is not set -+# CONFIG_RT_MUTEX_TESTER is not set -+# CONFIG_DEBUG_SPINLOCK is not set -+# CONFIG_DEBUG_MUTEXES is not set -+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -+# CONFIG_DEBUG_KOBJECT is not set -+# CONFIG_DEBUG_BUGVERBOSE is not set -+# CONFIG_DEBUG_INFO is not set -+# CONFIG_DEBUG_VM is not set -+# CONFIG_DEBUG_LIST is not set -+# CONFIG_DEBUG_SG is not set -+CONFIG_FORCED_INLINING=y -+# CONFIG_BOOT_PRINTK_DELAY is not set -+# CONFIG_RCU_TORTURE_TEST is not set -+# CONFIG_FAULT_INJECTION is not set -+# CONFIG_SAMPLES is not set -+# CONFIG_DEBUG_STACKOVERFLOW is not set -+# CONFIG_DEBUG_STACK_USAGE is not set -+# CONFIG_DEBUG_PAGEALLOC is not set -+CONFIG_DEBUGGER=y -+# CONFIG_KGDB is not set -+# CONFIG_XMON is not set -+# CONFIG_BDI_SWITCH is not set -+CONFIG_PPC_EARLY_DEBUG=y -+# CONFIG_PPC_EARLY_DEBUG_LPAR is not set -+# CONFIG_PPC_EARLY_DEBUG_G5 is not set -+# CONFIG_PPC_EARLY_DEBUG_RTAS_PANEL is not set -+# CONFIG_PPC_EARLY_DEBUG_RTAS_CONSOLE is not set -+# CONFIG_PPC_EARLY_DEBUG_MAPLE is not set -+# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set -+# CONFIG_PPC_EARLY_DEBUG_PAS_REALMODE is not set -+# CONFIG_PPC_EARLY_DEBUG_BEAT is not set -+CONFIG_PPC_EARLY_DEBUG_44x=y -+# CONFIG_PPC_EARLY_DEBUG_40x is not set -+# CONFIG_PPC_EARLY_DEBUG_CPM is not set -+CONFIG_PPC_EARLY_DEBUG_44x_PHYSLOW=0xef600300 -+CONFIG_PPC_EARLY_DEBUG_44x_PHYSHIGH=0x1 -+ -+# -+# Security options -+# -+# CONFIG_KEYS is not set -+# CONFIG_SECURITY is not set -+# CONFIG_SECURITY_FILE_CAPABILITIES is not set -+CONFIG_CRYPTO=y -+CONFIG_CRYPTO_ALGAPI=y -+CONFIG_CRYPTO_BLKCIPHER=y -+CONFIG_CRYPTO_MANAGER=y -+# CONFIG_CRYPTO_HMAC is not set -+# CONFIG_CRYPTO_XCBC is not set -+# CONFIG_CRYPTO_NULL is not set -+# CONFIG_CRYPTO_MD4 is not set -+CONFIG_CRYPTO_MD5=y -+# CONFIG_CRYPTO_SHA1 is not set -+# 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_GF128MUL is not set -+CONFIG_CRYPTO_ECB=y -+CONFIG_CRYPTO_CBC=y -+CONFIG_CRYPTO_PCBC=y -+# CONFIG_CRYPTO_LRW is not set -+# CONFIG_CRYPTO_XTS is not set -+# CONFIG_CRYPTO_CRYPTD is not set -+CONFIG_CRYPTO_DES=y -+# CONFIG_CRYPTO_FCRYPT is not set -+# 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_SEED is not set -+# CONFIG_CRYPTO_DEFLATE is not set -+# CONFIG_CRYPTO_MICHAEL_MIC is not set -+# CONFIG_CRYPTO_CRC32C is not set -+# CONFIG_CRYPTO_CAMELLIA is not set -+# CONFIG_CRYPTO_TEST is not set -+# CONFIG_CRYPTO_AUTHENC is not set -+CONFIG_CRYPTO_HW=y -+# CONFIG_PPC_CLOCK is not set ---- a/arch/powerpc/configs/sequoia_defconfig -+++ b/arch/powerpc/configs/sequoia_defconfig -@@ -1,7 +1,7 @@ - # - # Automatically generated make config: don't edit --# Linux kernel version: 2.6.24-rc4 --# Thu Dec 6 16:49:17 2007 -+# Linux kernel version: 2.6.24-rc6 -+# Mon Dec 24 11:23:22 2007 - # - # CONFIG_PPC64 is not set - -@@ -129,6 +129,7 @@ CONFIG_DEFAULT_AS=y - # CONFIG_DEFAULT_CFQ is not set - # CONFIG_DEFAULT_NOOP is not set - CONFIG_DEFAULT_IOSCHED="anticipatory" -+# CONFIG_PPC4xx_PCI_EXPRESS is not set - - # - # Platform support -@@ -141,8 +142,10 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" - # CONFIG_BAMBOO is not set - # CONFIG_EBONY is not set - CONFIG_SEQUOIA=y -+# CONFIG_TAISHAN is not set -+# CONFIG_KATMAI is not set -+# CONFIG_RAINIER is not set - CONFIG_440EPX=y --CONFIG_440A=y - # CONFIG_MPIC is not set - # CONFIG_MPIC_WEIRD is not set - # CONFIG_PPC_I8259 is not set -@@ -446,9 +449,7 @@ CONFIG_MISC_DEVICES=y - # CONFIG_FIREWIRE is not set - # CONFIG_IEEE1394 is not set - # CONFIG_I2O is not set --CONFIG_MACINTOSH_DRIVERS=y --# CONFIG_MAC_EMUMOUSEBTN is not set --# CONFIG_WINDFARM is not set -+# CONFIG_MACINTOSH_DRIVERS is not set - CONFIG_NETDEVICES=y - # CONFIG_NETDEVICES_MULTIQUEUE is not set - # CONFIG_DUMMY is not set -@@ -459,10 +460,28 @@ CONFIG_NETDEVICES=y - # CONFIG_VETH is not set - # CONFIG_IP1000 is not set - # CONFIG_ARCNET is not set --# CONFIG_NET_ETHERNET is not set -+# CONFIG_PHYLIB is not set -+CONFIG_NET_ETHERNET=y -+# CONFIG_MII is not set -+# CONFIG_HAPPYMEAL is not set -+# CONFIG_SUNGEM is not set -+# CONFIG_CASSINI is not set -+# CONFIG_NET_VENDOR_3COM is not set -+# CONFIG_NET_TULIP is not set -+# CONFIG_HP100 is not set -+CONFIG_IBM_NEW_EMAC=y -+CONFIG_IBM_NEW_EMAC_RXB=128 -+CONFIG_IBM_NEW_EMAC_TXB=64 -+CONFIG_IBM_NEW_EMAC_POLL_WEIGHT=32 -+CONFIG_IBM_NEW_EMAC_RX_COPY_THRESHOLD=256 -+CONFIG_IBM_NEW_EMAC_RX_SKB_HEADROOM=0 -+# CONFIG_IBM_NEW_EMAC_DEBUG is not set - CONFIG_IBM_NEW_EMAC_ZMII=y - CONFIG_IBM_NEW_EMAC_RGMII=y -+# CONFIG_IBM_NEW_EMAC_TAH is not set - CONFIG_IBM_NEW_EMAC_EMAC4=y -+# CONFIG_NET_PCI is not set -+# CONFIG_B44 is not set - CONFIG_NETDEV_1000=y - # CONFIG_ACENIC is not set - # CONFIG_DL2K is not set -@@ -811,6 +830,7 @@ CONFIG_PPC_EARLY_DEBUG=y - # CONFIG_PPC_EARLY_DEBUG_PAS_REALMODE is not set - # CONFIG_PPC_EARLY_DEBUG_BEAT is not set - CONFIG_PPC_EARLY_DEBUG_44x=y -+# CONFIG_PPC_EARLY_DEBUG_40x is not set - # CONFIG_PPC_EARLY_DEBUG_CPM is not set - CONFIG_PPC_EARLY_DEBUG_44x_PHYSLOW=0xef600300 - CONFIG_PPC_EARLY_DEBUG_44x_PHYSHIGH=0x1 ---- /dev/null -+++ b/arch/powerpc/configs/storcenter_defconfig -@@ -0,0 +1,1174 @@ -+# -+# Automatically generated make config: don't edit -+# Linux kernel version: 2.6.24-rc6 -+# Tue Jan 8 09:33:54 2008 -+# -+# CONFIG_PPC64 is not set -+ -+# -+# Processor support -+# -+CONFIG_6xx=y -+# CONFIG_PPC_85xx is not set -+# CONFIG_PPC_8xx is not set -+# CONFIG_40x is not set -+# CONFIG_44x is not set -+# CONFIG_E200 is not set -+CONFIG_PPC_FPU=y -+# CONFIG_ALTIVEC is not set -+CONFIG_PPC_STD_MMU=y -+CONFIG_PPC_STD_MMU_32=y -+# CONFIG_PPC_MM_SLICES is not set -+# CONFIG_SMP is not set -+CONFIG_PPC32=y -+CONFIG_WORD_SIZE=32 -+CONFIG_PPC_MERGE=y -+CONFIG_MMU=y -+CONFIG_GENERIC_CMOS_UPDATE=y -+CONFIG_GENERIC_TIME=y -+CONFIG_GENERIC_TIME_VSYSCALL=y -+CONFIG_GENERIC_CLOCKEVENTS=y -+CONFIG_GENERIC_HARDIRQS=y -+CONFIG_IRQ_PER_CPU=y -+CONFIG_RWSEM_XCHGADD_ALGORITHM=y -+CONFIG_ARCH_HAS_ILOG2_U32=y -+CONFIG_GENERIC_HWEIGHT=y -+CONFIG_GENERIC_CALIBRATE_DELAY=y -+CONFIG_GENERIC_FIND_NEXT_BIT=y -+# CONFIG_ARCH_NO_VIRT_TO_BUS is not set -+CONFIG_PPC=y -+CONFIG_EARLY_PRINTK=y -+CONFIG_GENERIC_NVRAM=y -+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -+CONFIG_ARCH_MAY_HAVE_PC_FDC=y -+CONFIG_PPC_OF=y -+CONFIG_OF=y -+CONFIG_PPC_UDBG_16550=y -+# CONFIG_GENERIC_TBSYNC is not set -+CONFIG_AUDIT_ARCH=y -+CONFIG_GENERIC_BUG=y -+# CONFIG_DEFAULT_UIMAGE is not set -+# CONFIG_PPC_DCR_NATIVE is not set -+# CONFIG_PPC_DCR_MMIO is not set -+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" -+ -+# -+# General setup -+# -+CONFIG_EXPERIMENTAL=y -+CONFIG_BROKEN_ON_SMP=y -+CONFIG_INIT_ENV_ARG_LIMIT=32 -+CONFIG_LOCALVERSION="" -+CONFIG_LOCALVERSION_AUTO=y -+CONFIG_SWAP=y -+CONFIG_SYSVIPC=y -+CONFIG_SYSVIPC_SYSCTL=y -+# CONFIG_POSIX_MQUEUE is not set -+# CONFIG_BSD_PROCESS_ACCT is not set -+# CONFIG_TASKSTATS is not set -+# CONFIG_USER_NS is not set -+# CONFIG_PID_NS is not set -+# CONFIG_AUDIT is not set -+# CONFIG_IKCONFIG is not set -+CONFIG_LOG_BUF_SHIFT=14 -+# CONFIG_CGROUPS is not set -+CONFIG_FAIR_GROUP_SCHED=y -+CONFIG_FAIR_USER_SCHED=y -+# CONFIG_FAIR_CGROUP_SCHED is not set -+CONFIG_SYSFS_DEPRECATED=y -+# CONFIG_RELAY is not set -+# CONFIG_BLK_DEV_INITRD is not set -+CONFIG_CC_OPTIMIZE_FOR_SIZE=y -+CONFIG_SYSCTL=y -+CONFIG_EMBEDDED=y -+CONFIG_SYSCTL_SYSCALL=y -+# CONFIG_KALLSYMS is not set -+CONFIG_HOTPLUG=y -+CONFIG_PRINTK=y -+CONFIG_BUG=y -+CONFIG_ELF_CORE=y -+CONFIG_BASE_FULL=y -+CONFIG_FUTEX=y -+CONFIG_ANON_INODES=y -+CONFIG_EPOLL=y -+CONFIG_SIGNALFD=y -+CONFIG_EVENTFD=y -+CONFIG_SHMEM=y -+CONFIG_VM_EVENT_COUNTERS=y -+CONFIG_SLUB_DEBUG=y -+# CONFIG_SLAB is not set -+CONFIG_SLUB=y -+# CONFIG_SLOB is not set -+CONFIG_RT_MUTEXES=y -+# CONFIG_TINY_SHMEM is not set -+CONFIG_BASE_SMALL=0 -+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 -+CONFIG_BLOCK=y -+CONFIG_LBD=y -+# CONFIG_BLK_DEV_IO_TRACE is not set -+# CONFIG_LSF is not set -+# CONFIG_BLK_DEV_BSG 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" -+ -+# -+# Platform support -+# -+CONFIG_PPC_MULTIPLATFORM=y -+# CONFIG_PPC_82xx is not set -+# CONFIG_PPC_83xx is not set -+# CONFIG_PPC_86xx is not set -+CONFIG_CLASSIC32=y -+# CONFIG_PPC_CHRP is not set -+# CONFIG_PPC_MPC52xx is not set -+# CONFIG_PPC_MPC5200 is not set -+# CONFIG_PPC_EFIKA is not set -+# CONFIG_PPC_LITE5200 is not set -+# CONFIG_PPC_PMAC is not set -+# CONFIG_PPC_CELL is not set -+# CONFIG_PPC_CELL_NATIVE is not set -+# CONFIG_PQ2ADS is not set -+CONFIG_EMBEDDED6xx=y -+# CONFIG_LINKSTATION is not set -+CONFIG_STORCENTER=y -+# CONFIG_MPC7448HPC2 is not set -+# CONFIG_PPC_HOLLY is not set -+# CONFIG_PPC_PRPMC2800 is not set -+CONFIG_MPC10X_BRIDGE=y -+CONFIG_MPC10X_OPENPIC=y -+# CONFIG_MPC10X_STORE_GATHERING is not set -+CONFIG_MPIC=y -+# CONFIG_MPIC_WEIRD is not set -+# CONFIG_PPC_I8259 is not set -+# CONFIG_PPC_RTAS is not set -+# CONFIG_MMIO_NVRAM is not set -+# CONFIG_PPC_MPC106 is not set -+# CONFIG_PPC_970_NAP is not set -+# CONFIG_PPC_INDIRECT_IO is not set -+# CONFIG_GENERIC_IOMAP is not set -+# CONFIG_CPU_FREQ is not set -+# CONFIG_TAU is not set -+# CONFIG_CPM2 is not set -+# CONFIG_FSL_ULI1575 is not set -+ -+# -+# Kernel options -+# -+# CONFIG_HIGHMEM is not set -+# CONFIG_TICK_ONESHOT is not set -+# CONFIG_NO_HZ is not set -+# CONFIG_HIGH_RES_TIMERS is not set -+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y -+CONFIG_HZ_100=y -+# CONFIG_HZ_250 is not set -+# CONFIG_HZ_300 is not set -+# CONFIG_HZ_1000 is not set -+CONFIG_HZ=100 -+CONFIG_PREEMPT_NONE=y -+# CONFIG_PREEMPT_VOLUNTARY is not set -+# CONFIG_PREEMPT is not set -+CONFIG_BINFMT_ELF=y -+CONFIG_BINFMT_MISC=y -+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y -+# CONFIG_KEXEC is not set -+CONFIG_ARCH_FLATMEM_ENABLE=y -+CONFIG_ARCH_POPULATES_NODE_MAP=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 is not set -+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set -+CONFIG_SPLIT_PTLOCK_CPUS=4 -+# CONFIG_RESOURCES_64BIT is not set -+CONFIG_ZONE_DMA_FLAG=1 -+CONFIG_BOUNCE=y -+CONFIG_VIRT_TO_BUS=y -+CONFIG_PROC_DEVICETREE=y -+CONFIG_CMDLINE_BOOL=y -+CONFIG_CMDLINE="console=ttyS0,115200" -+# CONFIG_PM is not set -+CONFIG_SUSPEND_UP_POSSIBLE=y -+CONFIG_HIBERNATION_UP_POSSIBLE=y -+# CONFIG_SECCOMP is not set -+CONFIG_WANT_DEVICE_TREE=y -+CONFIG_DEVICE_TREE="storcenter.dts" -+CONFIG_ISA_DMA_API=y -+ -+# -+# Bus options -+# -+CONFIG_ZONE_DMA=y -+CONFIG_GENERIC_ISA_DMA=y -+CONFIG_PPC_INDIRECT_PCI=y -+CONFIG_FSL_SOC=y -+CONFIG_PCI=y -+CONFIG_PCI_DOMAINS=y -+CONFIG_PCI_SYSCALL=y -+# CONFIG_PCIEPORTBUS is not set -+CONFIG_ARCH_SUPPORTS_MSI=y -+# CONFIG_PCI_MSI is not set -+CONFIG_PCI_LEGACY=y -+# CONFIG_PCCARD is not set -+# CONFIG_HOTPLUG_PCI is not set -+ -+# -+# Advanced setup -+# -+# CONFIG_ADVANCED_OPTIONS is not set -+ -+# -+# Default settings for advanced configuration options are used -+# -+CONFIG_HIGHMEM_START=0xfe000000 -+CONFIG_LOWMEM_SIZE=0x30000000 -+CONFIG_KERNEL_START=0xc0000000 -+CONFIG_TASK_SIZE=0xc0000000 -+CONFIG_BOOT_LOAD=0x00800000 -+ -+# -+# Networking -+# -+CONFIG_NET=y -+ -+# -+# Networking options -+# -+CONFIG_PACKET=m -+# CONFIG_PACKET_MMAP is not set -+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=y -+# 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_XFRM_TUNNEL is not set -+# CONFIG_INET_TUNNEL is not set -+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -+# CONFIG_INET_XFRM_MODE_TUNNEL is not set -+# CONFIG_INET_XFRM_MODE_BEET is not set -+# CONFIG_INET_LRO is not set -+CONFIG_INET_DIAG=y -+CONFIG_INET_TCP_DIAG=y -+# CONFIG_TCP_CONG_ADVANCED is not set -+CONFIG_TCP_CONG_CUBIC=y -+CONFIG_DEFAULT_TCP_CONG="cubic" -+# CONFIG_TCP_MD5SIG is not set -+# 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 -+# CONFIG_IP_DCCP is not set -+# CONFIG_IP_SCTP is not set -+# 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_ECONET is not set -+# CONFIG_WAN_ROUTER is not set -+# 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_AF_RXRPC is not set -+ -+# -+# Wireless -+# -+# CONFIG_CFG80211 is not set -+# CONFIG_WIRELESS_EXT is not set -+# CONFIG_MAC80211 is not set -+# CONFIG_IEEE80211 is not set -+# CONFIG_RFKILL is not set -+# CONFIG_NET_9P is not set -+ -+# -+# Device Drivers -+# -+ -+# -+# Generic Driver Options -+# -+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -+CONFIG_STANDALONE=y -+CONFIG_PREVENT_FIRMWARE_BUILD=y -+# CONFIG_FW_LOADER is not set -+# CONFIG_SYS_HYPERVISOR is not set -+# CONFIG_CONNECTOR is not set -+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 is not set -+ -+# -+# User Modules And Translation Layers -+# -+CONFIG_MTD_CHAR=y -+CONFIG_MTD_BLKDEVS=y -+CONFIG_MTD_BLOCK=y -+CONFIG_FTL=y -+CONFIG_NFTL=y -+CONFIG_NFTL_RW=y -+# CONFIG_INFTL is not set -+# CONFIG_RFD_FTL is not set -+# CONFIG_SSFDC is not set -+# CONFIG_MTD_OOPS 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 is not set -+CONFIG_MTD_CFI_AMDSTD=y -+# 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 -+ -+# -+# Mapping drivers for chip access -+# -+# CONFIG_MTD_COMPLEX_MAPPINGS is not set -+CONFIG_MTD_PHYSMAP=y -+CONFIG_MTD_PHYSMAP_START=0xFF800000 -+CONFIG_MTD_PHYSMAP_LEN=0x00800000 -+CONFIG_MTD_PHYSMAP_BANKWIDTH=1 -+# CONFIG_MTD_PHYSMAP_OF is not set -+# CONFIG_MTD_INTEL_VR_NOR is not set -+# CONFIG_MTD_PLATRAM is not set -+ -+# -+# Self-contained MTD device drivers -+# -+# CONFIG_MTD_PMC551 is not set -+# 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 -+# CONFIG_MTD_NAND is not set -+# CONFIG_MTD_ONENAND is not set -+ -+# -+# UBI - Unsorted block images -+# -+# CONFIG_MTD_UBI is not set -+CONFIG_OF_DEVICE=y -+# CONFIG_PARPORT is not set -+CONFIG_BLK_DEV=y -+# 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 is not set -+# CONFIG_BLK_DEV_NBD is not set -+# CONFIG_BLK_DEV_SX8 is not set -+# CONFIG_BLK_DEV_UB is not set -+# CONFIG_BLK_DEV_RAM is not set -+# CONFIG_CDROM_PKTCDVD is not set -+# CONFIG_ATA_OVER_ETH is not set -+CONFIG_MISC_DEVICES=y -+# CONFIG_PHANTOM is not set -+# CONFIG_EEPROM_93CX6 is not set -+# CONFIG_SGI_IOC4 is not set -+# CONFIG_TIFM_CORE is not set -+CONFIG_IDE=y -+CONFIG_IDE_MAX_HWIFS=4 -+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_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_BLK_DEV_IDESCSI is not set -+# CONFIG_IDE_TASK_IOCTL is not set -+CONFIG_IDE_PROC_FS=y -+ -+# -+# IDE chipset support/bugfixes -+# -+CONFIG_IDE_GENERIC=y -+# CONFIG_BLK_DEV_PLATFORM is not set -+ -+# -+# PCI IDE chipsets support -+# -+CONFIG_BLK_DEV_IDEPCI=y -+# CONFIG_IDEPCI_SHARE_IRQ is not set -+CONFIG_IDEPCI_PCIBUS_ORDER=y -+# CONFIG_BLK_DEV_GENERIC is not set -+# CONFIG_BLK_DEV_OPTI621 is not set -+CONFIG_BLK_DEV_IDEDMA_PCI=y -+# CONFIG_BLK_DEV_AEC62XX is not set -+# CONFIG_BLK_DEV_ALI15X3 is not set -+# CONFIG_BLK_DEV_AMD74XX 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_HPT34X is not set -+# CONFIG_BLK_DEV_HPT366 is not set -+# CONFIG_BLK_DEV_JMICRON is not set -+# CONFIG_BLK_DEV_SC1200 is not set -+# CONFIG_BLK_DEV_PIIX is not set -+# CONFIG_BLK_DEV_IT8213 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_SL82C105 is not set -+# CONFIG_BLK_DEV_SLC90E66 is not set -+# CONFIG_BLK_DEV_TRM290 is not set -+CONFIG_BLK_DEV_VIA82CXXX=y -+# CONFIG_BLK_DEV_TC86C001 is not set -+# CONFIG_IDE_ARM is not set -+CONFIG_BLK_DEV_IDEDMA=y -+CONFIG_IDE_ARCH_OBSOLETE_INIT=y -+# CONFIG_BLK_DEV_HD is not set -+ -+# -+# SCSI device support -+# -+# CONFIG_RAID_ATTRS is not set -+CONFIG_SCSI=y -+CONFIG_SCSI_DMA=y -+# CONFIG_SCSI_TGT is not set -+# CONFIG_SCSI_NETLINK is not set -+CONFIG_SCSI_PROC_FS=y -+ -+# -+# SCSI support type (disk, tape, CD-ROM) -+# -+CONFIG_BLK_DEV_SD=y -+# CONFIG_CHR_DEV_ST is not set -+# CONFIG_CHR_DEV_OSST is not set -+CONFIG_BLK_DEV_SR=y -+# CONFIG_BLK_DEV_SR_VENDOR is not set -+# CONFIG_CHR_DEV_SG is not set -+# CONFIG_CHR_DEV_SCH is not set -+ -+# -+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -+# -+# CONFIG_SCSI_MULTI_LUN is not set -+# CONFIG_SCSI_CONSTANTS is not set -+# CONFIG_SCSI_LOGGING is not set -+# CONFIG_SCSI_SCAN_ASYNC is not set -+CONFIG_SCSI_WAIT_SCAN=m -+ -+# -+# SCSI Transports -+# -+CONFIG_SCSI_SPI_ATTRS=y -+# CONFIG_SCSI_FC_ATTRS is not set -+# CONFIG_SCSI_ISCSI_ATTRS is not set -+# CONFIG_SCSI_SAS_LIBSAS is not set -+# CONFIG_SCSI_SRP_ATTRS is not set -+CONFIG_SCSI_LOWLEVEL=y -+# CONFIG_ISCSI_TCP is not set -+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set -+# CONFIG_SCSI_3W_9XXX is not set -+# CONFIG_SCSI_ACARD is not set -+# CONFIG_SCSI_AACRAID is not set -+# CONFIG_SCSI_AIC7XXX is not set -+# CONFIG_SCSI_AIC7XXX_OLD is not set -+# CONFIG_SCSI_AIC79XX is not set -+# CONFIG_SCSI_AIC94XX is not set -+# CONFIG_SCSI_DPT_I2O is not set -+# CONFIG_SCSI_ADVANSYS is not set -+# CONFIG_SCSI_ARCMSR is not set -+# CONFIG_MEGARAID_NEWGEN is not set -+# CONFIG_MEGARAID_LEGACY is not set -+# CONFIG_MEGARAID_SAS is not set -+# CONFIG_SCSI_HPTIOP is not set -+# CONFIG_SCSI_BUSLOGIC is not set -+# CONFIG_SCSI_DMX3191D is not set -+# CONFIG_SCSI_EATA is not set -+# CONFIG_SCSI_FUTURE_DOMAIN is not set -+# CONFIG_SCSI_GDTH is not set -+# CONFIG_SCSI_IPS is not set -+# CONFIG_SCSI_INITIO is not set -+# CONFIG_SCSI_INIA100 is not set -+# CONFIG_SCSI_STEX is not set -+# CONFIG_SCSI_SYM53C8XX_2 is not set -+# CONFIG_SCSI_QLOGIC_1280 is not set -+# CONFIG_SCSI_QLA_FC is not set -+# CONFIG_SCSI_QLA_ISCSI is not set -+# CONFIG_SCSI_LPFC is not set -+# CONFIG_SCSI_DC395x is not set -+# CONFIG_SCSI_DC390T is not set -+# CONFIG_SCSI_NSP32 is not set -+# CONFIG_SCSI_DEBUG is not set -+# CONFIG_SCSI_SRP is not set -+# CONFIG_ATA is not set -+CONFIG_MD=y -+CONFIG_BLK_DEV_MD=y -+CONFIG_MD_LINEAR=y -+CONFIG_MD_RAID0=y -+CONFIG_MD_RAID1=y -+# CONFIG_MD_RAID10 is not set -+CONFIG_MD_RAID456=y -+CONFIG_MD_RAID5_RESHAPE=y -+# CONFIG_MD_MULTIPATH is not set -+# CONFIG_MD_FAULTY is not set -+# CONFIG_BLK_DEV_DM is not set -+# CONFIG_FUSION is not set -+ -+# -+# IEEE 1394 (FireWire) support -+# -+# CONFIG_FIREWIRE is not set -+# CONFIG_IEEE1394 is not set -+# CONFIG_I2O is not set -+# CONFIG_MACINTOSH_DRIVERS is not set -+CONFIG_NETDEVICES=y -+# CONFIG_NETDEVICES_MULTIQUEUE is not set -+CONFIG_DUMMY=m -+# CONFIG_BONDING is not set -+# CONFIG_MACVLAN is not set -+# CONFIG_EQUALIZER is not set -+# CONFIG_TUN is not set -+# CONFIG_VETH is not set -+# CONFIG_IP1000 is not set -+# CONFIG_ARCNET is not set -+# CONFIG_NET_ETHERNET is not set -+CONFIG_NETDEV_1000=y -+# CONFIG_ACENIC is not set -+# CONFIG_DL2K is not set -+# CONFIG_E1000 is not set -+# CONFIG_E1000E is not set -+# CONFIG_NS83820 is not set -+# CONFIG_HAMACHI is not set -+# CONFIG_YELLOWFIN is not set -+CONFIG_R8169=y -+# CONFIG_R8169_NAPI 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 -+# CONFIG_MV643XX_ETH is not set -+# CONFIG_QLA3XXX is not set -+# CONFIG_ATL1 is not set -+# CONFIG_NETDEV_10000 is not set -+# CONFIG_TR is not set -+ -+# -+# Wireless LAN -+# -+# CONFIG_WLAN_PRE80211 is not set -+# CONFIG_WLAN_80211 is not set -+ -+# -+# USB Network Adapters -+# -+# CONFIG_USB_CATC is not set -+# CONFIG_USB_KAWETH is not set -+# CONFIG_USB_PEGASUS is not set -+# CONFIG_USB_RTL8150 is not set -+# CONFIG_USB_USBNET is not set -+# CONFIG_WAN is not set -+# CONFIG_FDDI is not set -+# CONFIG_HIPPI is not set -+# CONFIG_PPP is not set -+# CONFIG_SLIP is not set -+# CONFIG_NET_FC 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 -+# CONFIG_ISDN is not set -+# CONFIG_PHONE is not set -+ -+# -+# Input device support -+# -+# CONFIG_INPUT is not set -+ -+# -+# Hardware I/O ports -+# -+# CONFIG_SERIO is not set -+# CONFIG_GAMEPORT is not set -+ -+# -+# Character devices -+# -+# CONFIG_VT is not set -+# CONFIG_SERIAL_NONSTANDARD is not set -+ -+# -+# Serial drivers -+# -+CONFIG_SERIAL_8250=y -+CONFIG_SERIAL_8250_CONSOLE=y -+# CONFIG_SERIAL_8250_PCI is not set -+CONFIG_SERIAL_8250_NR_UARTS=2 -+CONFIG_SERIAL_8250_RUNTIME_UARTS=2 -+# CONFIG_SERIAL_8250_EXTENDED is not set -+ -+# -+# Non-8250 serial port support -+# -+# CONFIG_SERIAL_UARTLITE is not set -+CONFIG_SERIAL_CORE=y -+CONFIG_SERIAL_CORE_CONSOLE=y -+# CONFIG_SERIAL_JSM is not set -+# CONFIG_SERIAL_OF_PLATFORM is not set -+CONFIG_UNIX98_PTYS=y -+CONFIG_LEGACY_PTYS=y -+CONFIG_LEGACY_PTY_COUNT=256 -+# CONFIG_IPMI_HANDLER is not set -+CONFIG_HW_RANDOM=m -+CONFIG_NVRAM=y -+CONFIG_GEN_RTC=y -+# CONFIG_GEN_RTC_X is not set -+# CONFIG_R3964 is not set -+# CONFIG_APPLICOM is not set -+# CONFIG_RAW_DRIVER is not set -+# CONFIG_TCG_TPM is not set -+CONFIG_DEVPORT=y -+CONFIG_I2C=y -+CONFIG_I2C_BOARDINFO=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_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_MPC=y -+# CONFIG_I2C_NFORCE2 is not set -+# CONFIG_I2C_OCORES is not set -+# CONFIG_I2C_PARPORT_LIGHT is not set -+# CONFIG_I2C_PROSAVAGE is not set -+# CONFIG_I2C_SAVAGE4 is not set -+# CONFIG_I2C_SIMTEC is not set -+# CONFIG_I2C_SIS5595 is not set -+# CONFIG_I2C_SIS630 is not set -+# CONFIG_I2C_SIS96X is not set -+# CONFIG_I2C_TAOS_EVM is not set -+# CONFIG_I2C_STUB is not set -+# CONFIG_I2C_TINY_USB is not set -+# CONFIG_I2C_VIA is not set -+# CONFIG_I2C_VIAPRO is not set -+# CONFIG_I2C_VOODOO3 is not set -+ -+# -+# Miscellaneous I2C Chip support -+# -+# CONFIG_SENSORS_DS1337 is not set -+# CONFIG_SENSORS_DS1374 is not set -+# CONFIG_DS1682 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_SENSORS_M41T00 is not set -+# CONFIG_SENSORS_MAX6875 is not set -+# CONFIG_SENSORS_TSL2550 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 -+# CONFIG_W1 is not set -+# CONFIG_POWER_SUPPLY is not set -+# CONFIG_HWMON is not set -+# CONFIG_WATCHDOG is not set -+ -+# -+# Sonics Silicon Backplane -+# -+CONFIG_SSB_POSSIBLE=y -+# CONFIG_SSB is not set -+ -+# -+# Multifunction device drivers -+# -+# CONFIG_MFD_SM501 is not set -+ -+# -+# Multimedia devices -+# -+# CONFIG_VIDEO_DEV is not set -+# CONFIG_DVB_CORE is not set -+# CONFIG_DAB is not set -+ -+# -+# Graphics support -+# -+# CONFIG_AGP is not set -+# CONFIG_DRM is not set -+# CONFIG_VGASTATE is not set -+# CONFIG_VIDEO_OUTPUT_CONTROL is not set -+# CONFIG_FB is not set -+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set -+ -+# -+# Display device support -+# -+# CONFIG_DISPLAY_SUPPORT is not set -+ -+# -+# Sound -+# -+# CONFIG_SOUND is not set -+CONFIG_USB_SUPPORT=y -+CONFIG_USB_ARCH_HAS_HCD=y -+CONFIG_USB_ARCH_HAS_OHCI=y -+CONFIG_USB_ARCH_HAS_EHCI=y -+CONFIG_USB=y -+# CONFIG_USB_DEBUG is not set -+ -+# -+# Miscellaneous USB options -+# -+CONFIG_USB_DEVICEFS=y -+CONFIG_USB_DEVICE_CLASS=y -+# CONFIG_USB_DYNAMIC_MINORS is not set -+# CONFIG_USB_OTG is not set -+ -+# -+# USB Host Controller Drivers -+# -+CONFIG_USB_EHCI_HCD=y -+# CONFIG_USB_EHCI_SPLIT_ISO is not set -+# CONFIG_USB_EHCI_ROOT_HUB_TT is not set -+# CONFIG_USB_EHCI_TT_NEWSCHED is not set -+# CONFIG_USB_ISP116X_HCD is not set -+CONFIG_USB_OHCI_HCD=y -+# CONFIG_USB_OHCI_HCD_PPC_OF is not set -+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set -+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set -+CONFIG_USB_OHCI_LITTLE_ENDIAN=y -+# CONFIG_USB_UHCI_HCD is not set -+# CONFIG_USB_SL811_HCD is not set -+# CONFIG_USB_R8A66597_HCD is not set -+ -+# -+# USB Device Class drivers -+# -+# CONFIG_USB_ACM is not set -+# CONFIG_USB_PRINTER is not set -+ -+# -+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -+# -+ -+# -+# may also be needed; see USB_STORAGE Help for more information -+# -+CONFIG_USB_STORAGE=y -+# 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_USBAT is not set -+# CONFIG_USB_STORAGE_SDDR09 is not set -+# CONFIG_USB_STORAGE_SDDR55 is not set -+# CONFIG_USB_STORAGE_JUMPSHOT is not set -+# CONFIG_USB_STORAGE_ALAUDA is not set -+# CONFIG_USB_STORAGE_KARMA is not set -+# CONFIG_USB_LIBUSUAL is not set -+ -+# -+# USB Imaging devices -+# -+# CONFIG_USB_MDC800 is not set -+# CONFIG_USB_MICROTEK is not set -+# CONFIG_USB_MON is not set -+ -+# -+# USB port drivers -+# -+ -+# -+# USB Serial Converter support -+# -+# CONFIG_USB_SERIAL is not set -+ -+# -+# USB Miscellaneous drivers -+# -+# CONFIG_USB_EMI62 is not set -+# CONFIG_USB_EMI26 is not set -+# CONFIG_USB_ADUTUX is not set -+# CONFIG_USB_AUERSWALD is not set -+# CONFIG_USB_RIO500 is not set -+# CONFIG_USB_LEGOTOWER is not set -+# CONFIG_USB_LCD is not set -+# CONFIG_USB_BERRY_CHARGE is not set -+# CONFIG_USB_LED is not set -+# CONFIG_USB_CYPRESS_CY7C63 is not set -+# CONFIG_USB_CYTHERM is not set -+# CONFIG_USB_PHIDGET is not set -+# CONFIG_USB_IDMOUSE is not set -+# CONFIG_USB_FTDI_ELAN is not set -+# CONFIG_USB_APPLEDISPLAY is not set -+# CONFIG_USB_SISUSBVGA is not set -+# CONFIG_USB_LD is not set -+# CONFIG_USB_TRANCEVIBRATOR is not set -+# CONFIG_USB_IOWARRIOR is not set -+# CONFIG_USB_TEST is not set -+ -+# -+# USB DSL modem support -+# -+ -+# -+# USB Gadget Support -+# -+# CONFIG_USB_GADGET is not set -+# CONFIG_MMC is not set -+# CONFIG_NEW_LEDS is not set -+# CONFIG_INFINIBAND is not set -+# CONFIG_EDAC is not set -+CONFIG_RTC_LIB=y -+CONFIG_RTC_CLASS=y -+CONFIG_RTC_HCTOSYS=y -+CONFIG_RTC_HCTOSYS_DEVICE="rtc0" -+# CONFIG_RTC_DEBUG is not set -+ -+# -+# RTC interfaces -+# -+CONFIG_RTC_INTF_SYSFS=y -+CONFIG_RTC_INTF_PROC=y -+CONFIG_RTC_INTF_DEV=y -+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set -+# CONFIG_RTC_DRV_TEST is not set -+ -+# -+# I2C RTC drivers -+# -+CONFIG_RTC_DRV_DS1307=y -+# CONFIG_RTC_DRV_DS1374 is not set -+# CONFIG_RTC_DRV_DS1672 is not set -+# CONFIG_RTC_DRV_MAX6900 is not set -+# CONFIG_RTC_DRV_RS5C372 is not set -+# CONFIG_RTC_DRV_ISL1208 is not set -+# CONFIG_RTC_DRV_X1205 is not set -+# CONFIG_RTC_DRV_PCF8563 is not set -+# CONFIG_RTC_DRV_PCF8583 is not set -+# CONFIG_RTC_DRV_M41T80 is not set -+ -+# -+# SPI RTC drivers -+# -+ -+# -+# Platform RTC drivers -+# -+# CONFIG_RTC_DRV_CMOS is not set -+# CONFIG_RTC_DRV_DS1553 is not set -+# CONFIG_RTC_DRV_STK17TA8 is not set -+# CONFIG_RTC_DRV_DS1742 is not set -+# CONFIG_RTC_DRV_M48T86 is not set -+# CONFIG_RTC_DRV_M48T59 is not set -+# CONFIG_RTC_DRV_V3020 is not set -+ -+# -+# on-CPU RTC drivers -+# -+ -+# -+# Userspace I/O -+# -+# CONFIG_UIO 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=y -+CONFIG_EXT3_FS_XATTR=y -+# CONFIG_EXT3_FS_POSIX_ACL is not set -+# CONFIG_EXT3_FS_SECURITY is not set -+# CONFIG_EXT4DEV_FS is not set -+CONFIG_JBD=y -+CONFIG_FS_MBCACHE=y -+# CONFIG_REISERFS_FS is not set -+# CONFIG_JFS_FS is not set -+# CONFIG_FS_POSIX_ACL is not set -+CONFIG_XFS_FS=m -+# CONFIG_XFS_QUOTA is not set -+# CONFIG_XFS_SECURITY is not set -+# CONFIG_XFS_POSIX_ACL is not set -+# CONFIG_XFS_RT is not set -+# CONFIG_GFS2_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 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_MSDOS_FS is not set -+# CONFIG_VFAT_FS is not set -+# CONFIG_NTFS_FS is not set -+ -+# -+# Pseudo filesystems -+# -+CONFIG_PROC_FS=y -+CONFIG_PROC_KCORE=y -+CONFIG_PROC_SYSCTL=y -+CONFIG_SYSFS=y -+CONFIG_TMPFS=y -+# CONFIG_TMPFS_POSIX_ACL is not set -+# CONFIG_HUGETLB_PAGE 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_JFFS2_FS=y -+CONFIG_JFFS2_FS_DEBUG=0 -+CONFIG_JFFS2_FS_WRITEBUFFER=y -+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set -+# 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_LZO is not set -+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 -+# CONFIG_NETWORK_FILESYSTEMS is not set -+ -+# -+# Partition Types -+# -+CONFIG_PARTITION_ADVANCED=y -+# CONFIG_ACORN_PARTITION is not set -+# CONFIG_OSF_PARTITION is not set -+# CONFIG_AMIGA_PARTITION is not set -+# CONFIG_ATARI_PARTITION is not set -+# CONFIG_MAC_PARTITION is not set -+CONFIG_MSDOS_PARTITION=y -+# CONFIG_BSD_DISKLABEL is not set -+# CONFIG_MINIX_SUBPARTITION is not set -+# CONFIG_SOLARIS_X86_PARTITION is not set -+# CONFIG_UNIXWARE_DISKLABEL is not set -+# CONFIG_LDM_PARTITION is not set -+# CONFIG_SGI_PARTITION is not set -+# CONFIG_ULTRIX_PARTITION is not set -+# CONFIG_SUN_PARTITION is not set -+# CONFIG_KARMA_PARTITION is not set -+# CONFIG_EFI_PARTITION is not set -+# CONFIG_SYSV68_PARTITION is not set -+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=y -+# 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=y -+# CONFIG_DLM is not set -+# CONFIG_UCC_SLOW is not set -+ -+# -+# Library routines -+# -+CONFIG_BITREVERSE=y -+# CONFIG_CRC_CCITT is not set -+# CONFIG_CRC16 is not set -+# CONFIG_CRC_ITU_T is not set -+CONFIG_CRC32=y -+# CONFIG_CRC7 is not set -+# CONFIG_LIBCRC32C is not set -+CONFIG_ZLIB_INFLATE=y -+CONFIG_ZLIB_DEFLATE=y -+CONFIG_PLIST=y -+CONFIG_HAS_IOMEM=y -+CONFIG_HAS_IOPORT=y -+CONFIG_HAS_DMA=y -+CONFIG_INSTRUMENTATION=y -+# CONFIG_PROFILING is not set -+# CONFIG_MARKERS is not set -+ -+# -+# Kernel hacking -+# -+# CONFIG_PRINTK_TIME is not set -+# CONFIG_ENABLE_WARN_DEPRECATED is not set -+# CONFIG_ENABLE_MUST_CHECK is not set -+# CONFIG_MAGIC_SYSRQ is not set -+# CONFIG_UNUSED_SYMBOLS is not set -+# CONFIG_DEBUG_FS is not set -+# CONFIG_HEADERS_CHECK is not set -+# CONFIG_DEBUG_KERNEL is not set -+# CONFIG_SLUB_DEBUG_ON is not set -+# CONFIG_DEBUG_BUGVERBOSE is not set -+# CONFIG_SAMPLES is not set -+# CONFIG_BOOTX_TEXT is not set -+# CONFIG_PPC_EARLY_DEBUG is not set -+ -+# -+# Security options -+# -+# CONFIG_KEYS is not set -+# CONFIG_SECURITY is not set -+# CONFIG_SECURITY_FILE_CAPABILITIES is not set -+CONFIG_XOR_BLOCKS=y -+CONFIG_ASYNC_CORE=y -+CONFIG_ASYNC_MEMCPY=y -+CONFIG_ASYNC_XOR=y -+# CONFIG_CRYPTO is not set -+# CONFIG_PPC_CLOCK is not set ---- /dev/null -+++ b/arch/powerpc/configs/taishan_defconfig -@@ -0,0 +1,790 @@ -+# -+# Automatically generated make config: don't edit -+# Linux kernel version: 2.6.24-rc6 -+# Mon Dec 24 11:23:39 2007 -+# -+# CONFIG_PPC64 is not set -+ -+# -+# Processor support -+# -+# CONFIG_6xx is not set -+# CONFIG_PPC_85xx is not set -+# CONFIG_PPC_8xx is not set -+# CONFIG_40x is not set -+CONFIG_44x=y -+# CONFIG_E200 is not set -+CONFIG_4xx=y -+CONFIG_BOOKE=y -+CONFIG_PTE_64BIT=y -+CONFIG_PHYS_64BIT=y -+# CONFIG_PPC_MM_SLICES is not set -+CONFIG_NOT_COHERENT_CACHE=y -+CONFIG_PPC32=y -+CONFIG_WORD_SIZE=32 -+CONFIG_PPC_MERGE=y -+CONFIG_MMU=y -+CONFIG_GENERIC_CMOS_UPDATE=y -+CONFIG_GENERIC_TIME=y -+CONFIG_GENERIC_TIME_VSYSCALL=y -+CONFIG_GENERIC_CLOCKEVENTS=y -+CONFIG_GENERIC_HARDIRQS=y -+CONFIG_IRQ_PER_CPU=y -+CONFIG_RWSEM_XCHGADD_ALGORITHM=y -+CONFIG_ARCH_HAS_ILOG2_U32=y -+CONFIG_GENERIC_HWEIGHT=y -+CONFIG_GENERIC_CALIBRATE_DELAY=y -+CONFIG_GENERIC_FIND_NEXT_BIT=y -+# CONFIG_ARCH_NO_VIRT_TO_BUS is not set -+CONFIG_PPC=y -+CONFIG_EARLY_PRINTK=y -+CONFIG_GENERIC_NVRAM=y -+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -+CONFIG_ARCH_MAY_HAVE_PC_FDC=y -+CONFIG_PPC_OF=y -+CONFIG_OF=y -+CONFIG_PPC_UDBG_16550=y -+# CONFIG_GENERIC_TBSYNC is not set -+CONFIG_AUDIT_ARCH=y -+CONFIG_GENERIC_BUG=y -+# CONFIG_DEFAULT_UIMAGE is not set -+CONFIG_PPC_DCR_NATIVE=y -+# CONFIG_PPC_DCR_MMIO is not set -+CONFIG_PPC_DCR=y -+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" -+ -+# -+# General setup -+# -+CONFIG_EXPERIMENTAL=y -+CONFIG_BROKEN_ON_SMP=y -+CONFIG_INIT_ENV_ARG_LIMIT=32 -+CONFIG_LOCALVERSION="" -+CONFIG_LOCALVERSION_AUTO=y -+CONFIG_SWAP=y -+CONFIG_SYSVIPC=y -+CONFIG_SYSVIPC_SYSCTL=y -+CONFIG_POSIX_MQUEUE=y -+# CONFIG_BSD_PROCESS_ACCT is not set -+# CONFIG_TASKSTATS is not set -+# CONFIG_USER_NS is not set -+# CONFIG_PID_NS is not set -+# CONFIG_AUDIT is not set -+# CONFIG_IKCONFIG is not set -+CONFIG_LOG_BUF_SHIFT=14 -+# CONFIG_CGROUPS is not set -+CONFIG_FAIR_GROUP_SCHED=y -+CONFIG_FAIR_USER_SCHED=y -+# CONFIG_FAIR_CGROUP_SCHED is not set -+CONFIG_SYSFS_DEPRECATED=y -+# CONFIG_RELAY is not set -+CONFIG_BLK_DEV_INITRD=y -+CONFIG_INITRAMFS_SOURCE="" -+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -+CONFIG_SYSCTL=y -+CONFIG_EMBEDDED=y -+CONFIG_SYSCTL_SYSCALL=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_ANON_INODES=y -+CONFIG_EPOLL=y -+CONFIG_SIGNALFD=y -+CONFIG_EVENTFD=y -+CONFIG_SHMEM=y -+CONFIG_VM_EVENT_COUNTERS=y -+CONFIG_SLUB_DEBUG=y -+# CONFIG_SLAB is not set -+CONFIG_SLUB=y -+# CONFIG_SLOB is not set -+CONFIG_RT_MUTEXES=y -+# CONFIG_TINY_SHMEM is not set -+CONFIG_BASE_SMALL=0 -+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 -+CONFIG_BLOCK=y -+CONFIG_LBD=y -+# CONFIG_BLK_DEV_IO_TRACE is not set -+# CONFIG_LSF is not set -+# CONFIG_BLK_DEV_BSG is not set -+ -+# -+# IO Schedulers -+# -+CONFIG_IOSCHED_NOOP=y -+CONFIG_IOSCHED_AS=y -+CONFIG_IOSCHED_DEADLINE=y -+CONFIG_IOSCHED_CFQ=y -+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" -+# CONFIG_PPC4xx_PCI_EXPRESS is not set -+ -+# -+# Platform support -+# -+# CONFIG_PPC_MPC52xx is not set -+# CONFIG_PPC_MPC5200 is not set -+# CONFIG_PPC_CELL is not set -+# CONFIG_PPC_CELL_NATIVE is not set -+# CONFIG_PQ2ADS is not set -+# CONFIG_BAMBOO is not set -+# CONFIG_EBONY is not set -+# CONFIG_SEQUOIA is not set -+CONFIG_TAISHAN=y -+# CONFIG_KATMAI is not set -+# CONFIG_RAINIER is not set -+CONFIG_440GX=y -+# CONFIG_MPIC is not set -+# CONFIG_MPIC_WEIRD is not set -+# CONFIG_PPC_I8259 is not set -+# CONFIG_PPC_RTAS is not set -+# CONFIG_MMIO_NVRAM is not set -+# CONFIG_PPC_MPC106 is not set -+# CONFIG_PPC_970_NAP is not set -+# CONFIG_PPC_INDIRECT_IO is not set -+# CONFIG_GENERIC_IOMAP is not set -+# CONFIG_CPU_FREQ is not set -+# CONFIG_CPM2 is not set -+# CONFIG_FSL_ULI1575 is not set -+ -+# -+# Kernel options -+# -+# CONFIG_HIGHMEM is not set -+# CONFIG_TICK_ONESHOT is not set -+# CONFIG_NO_HZ is not set -+# CONFIG_HIGH_RES_TIMERS is not set -+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y -+# CONFIG_HZ_100 is not set -+CONFIG_HZ_250=y -+# CONFIG_HZ_300 is not set -+# CONFIG_HZ_1000 is not set -+CONFIG_HZ=250 -+CONFIG_PREEMPT_NONE=y -+# CONFIG_PREEMPT_VOLUNTARY is not set -+# CONFIG_PREEMPT is not set -+CONFIG_BINFMT_ELF=y -+# CONFIG_BINFMT_MISC is not set -+# CONFIG_MATH_EMULATION is not set -+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y -+CONFIG_ARCH_FLATMEM_ENABLE=y -+CONFIG_ARCH_POPULATES_NODE_MAP=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 is not set -+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set -+CONFIG_SPLIT_PTLOCK_CPUS=4 -+CONFIG_RESOURCES_64BIT=y -+CONFIG_ZONE_DMA_FLAG=1 -+CONFIG_BOUNCE=y -+CONFIG_VIRT_TO_BUS=y -+CONFIG_PROC_DEVICETREE=y -+CONFIG_CMDLINE_BOOL=y -+CONFIG_CMDLINE="" -+CONFIG_SECCOMP=y -+CONFIG_WANT_DEVICE_TREE=y -+CONFIG_DEVICE_TREE="taishan.dts" -+CONFIG_ISA_DMA_API=y -+ -+# -+# Bus options -+# -+CONFIG_ZONE_DMA=y -+CONFIG_PPC_INDIRECT_PCI=y -+CONFIG_PCI=y -+CONFIG_PCI_DOMAINS=y -+CONFIG_PCI_SYSCALL=y -+# CONFIG_PCIEPORTBUS is not set -+CONFIG_ARCH_SUPPORTS_MSI=y -+# CONFIG_PCI_MSI is not set -+CONFIG_PCI_LEGACY=y -+# CONFIG_PCI_DEBUG is not set -+# CONFIG_PCCARD is not set -+# CONFIG_HOTPLUG_PCI is not set -+ -+# -+# Advanced setup -+# -+# CONFIG_ADVANCED_OPTIONS is not set -+ -+# -+# Default settings for advanced configuration options are used -+# -+CONFIG_HIGHMEM_START=0xfe000000 -+CONFIG_LOWMEM_SIZE=0x30000000 -+CONFIG_KERNEL_START=0xc0000000 -+CONFIG_TASK_SIZE=0xc0000000 -+CONFIG_CONSISTENT_START=0xff100000 -+CONFIG_CONSISTENT_SIZE=0x00200000 -+CONFIG_BOOT_LOAD=0x01000000 -+ -+# -+# Networking -+# -+CONFIG_NET=y -+ -+# -+# Networking options -+# -+CONFIG_PACKET=y -+# CONFIG_PACKET_MMAP is not set -+CONFIG_UNIX=y -+# CONFIG_NET_KEY is not set -+CONFIG_INET=y -+# CONFIG_IP_MULTICAST is not set -+# 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_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 is not set -+# CONFIG_INET_XFRM_MODE_TUNNEL is not set -+# CONFIG_INET_XFRM_MODE_BEET is not set -+# CONFIG_INET_LRO is not set -+CONFIG_INET_DIAG=y -+CONFIG_INET_TCP_DIAG=y -+# CONFIG_TCP_CONG_ADVANCED is not set -+CONFIG_TCP_CONG_CUBIC=y -+CONFIG_DEFAULT_TCP_CONG="cubic" -+# CONFIG_TCP_MD5SIG is not set -+# 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 -+# CONFIG_IP_DCCP is not set -+# CONFIG_IP_SCTP is not set -+# 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_ECONET is not set -+# CONFIG_WAN_ROUTER is not set -+# 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_AF_RXRPC is not set -+ -+# -+# Wireless -+# -+# CONFIG_CFG80211 is not set -+# CONFIG_WIRELESS_EXT is not set -+# CONFIG_MAC80211 is not set -+# CONFIG_IEEE80211 is not set -+# CONFIG_RFKILL is not set -+# CONFIG_NET_9P is not set -+ -+# -+# Device Drivers -+# -+ -+# -+# Generic Driver Options -+# -+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -+CONFIG_STANDALONE=y -+CONFIG_PREVENT_FIRMWARE_BUILD=y -+CONFIG_FW_LOADER=y -+# CONFIG_DEBUG_DRIVER is not set -+# CONFIG_DEBUG_DEVRES is not set -+# CONFIG_SYS_HYPERVISOR is not set -+CONFIG_CONNECTOR=y -+CONFIG_PROC_EVENTS=y -+# CONFIG_MTD is not set -+CONFIG_OF_DEVICE=y -+# CONFIG_PARPORT is not set -+CONFIG_BLK_DEV=y -+# 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 is not set -+# CONFIG_BLK_DEV_NBD is not set -+# CONFIG_BLK_DEV_SX8 is not set -+CONFIG_BLK_DEV_RAM=y -+CONFIG_BLK_DEV_RAM_COUNT=16 -+CONFIG_BLK_DEV_RAM_SIZE=35000 -+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 -+# CONFIG_CDROM_PKTCDVD is not set -+# CONFIG_ATA_OVER_ETH is not set -+# CONFIG_XILINX_SYSACE is not set -+CONFIG_MISC_DEVICES=y -+# CONFIG_PHANTOM is not set -+# CONFIG_EEPROM_93CX6 is not set -+# CONFIG_SGI_IOC4 is not set -+# CONFIG_TIFM_CORE is not set -+# CONFIG_IDE is not set -+ -+# -+# SCSI device support -+# -+# CONFIG_RAID_ATTRS is not set -+# CONFIG_SCSI is not set -+# CONFIG_SCSI_DMA is not set -+# CONFIG_SCSI_NETLINK is not set -+# CONFIG_ATA is not set -+# CONFIG_MD is not set -+# CONFIG_FUSION is not set -+ -+# -+# IEEE 1394 (FireWire) support -+# -+# CONFIG_FIREWIRE is not set -+# CONFIG_IEEE1394 is not set -+# CONFIG_I2O is not set -+CONFIG_MACINTOSH_DRIVERS=y -+# CONFIG_MAC_EMUMOUSEBTN is not set -+# CONFIG_WINDFARM is not set -+CONFIG_NETDEVICES=y -+# CONFIG_NETDEVICES_MULTIQUEUE is not set -+# CONFIG_DUMMY is not set -+# CONFIG_BONDING is not set -+# CONFIG_MACVLAN is not set -+# CONFIG_EQUALIZER is not set -+# CONFIG_TUN is not set -+# CONFIG_VETH is not set -+# CONFIG_IP1000 is not set -+# CONFIG_ARCNET is not set -+# CONFIG_PHYLIB is not set -+CONFIG_NET_ETHERNET=y -+# CONFIG_MII is not set -+# CONFIG_HAPPYMEAL is not set -+# CONFIG_SUNGEM is not set -+# CONFIG_CASSINI is not set -+# CONFIG_NET_VENDOR_3COM is not set -+# CONFIG_NET_TULIP is not set -+# CONFIG_HP100 is not set -+CONFIG_IBM_NEW_EMAC=y -+CONFIG_IBM_NEW_EMAC_RXB=128 -+CONFIG_IBM_NEW_EMAC_TXB=64 -+CONFIG_IBM_NEW_EMAC_POLL_WEIGHT=32 -+CONFIG_IBM_NEW_EMAC_RX_COPY_THRESHOLD=256 -+CONFIG_IBM_NEW_EMAC_RX_SKB_HEADROOM=0 -+# CONFIG_IBM_NEW_EMAC_DEBUG is not set -+CONFIG_IBM_NEW_EMAC_ZMII=y -+CONFIG_IBM_NEW_EMAC_RGMII=y -+CONFIG_IBM_NEW_EMAC_TAH=y -+CONFIG_IBM_NEW_EMAC_EMAC4=y -+# CONFIG_NET_PCI is not set -+# CONFIG_B44 is not set -+CONFIG_NETDEV_1000=y -+# CONFIG_ACENIC is not set -+# CONFIG_DL2K is not set -+# CONFIG_E1000 is not set -+# CONFIG_E1000E 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 -+# CONFIG_QLA3XXX is not set -+# CONFIG_ATL1 is not set -+CONFIG_NETDEV_10000=y -+# CONFIG_CHELSIO_T1 is not set -+# CONFIG_CHELSIO_T3 is not set -+# CONFIG_IXGBE is not set -+# CONFIG_IXGB is not set -+# CONFIG_S2IO is not set -+# CONFIG_MYRI10GE is not set -+# CONFIG_NETXEN_NIC is not set -+# CONFIG_NIU is not set -+# CONFIG_MLX4_CORE is not set -+# CONFIG_TEHUTI is not set -+# CONFIG_TR is not set -+ -+# -+# Wireless LAN -+# -+# CONFIG_WLAN_PRE80211 is not set -+# CONFIG_WLAN_80211 is not set -+# CONFIG_WAN is not set -+# CONFIG_FDDI is not set -+# CONFIG_HIPPI 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 -+# CONFIG_ISDN is not set -+# CONFIG_PHONE is not set -+ -+# -+# Input device support -+# -+# CONFIG_INPUT is not set -+ -+# -+# Hardware I/O ports -+# -+# CONFIG_SERIO is not set -+# CONFIG_GAMEPORT is not set -+ -+# -+# Character devices -+# -+# CONFIG_VT is not set -+# CONFIG_SERIAL_NONSTANDARD is not set -+ -+# -+# Serial drivers -+# -+CONFIG_SERIAL_8250=y -+CONFIG_SERIAL_8250_CONSOLE=y -+# CONFIG_SERIAL_8250_PCI is not set -+CONFIG_SERIAL_8250_NR_UARTS=4 -+CONFIG_SERIAL_8250_RUNTIME_UARTS=4 -+CONFIG_SERIAL_8250_EXTENDED=y -+# CONFIG_SERIAL_8250_MANY_PORTS is not set -+CONFIG_SERIAL_8250_SHARE_IRQ=y -+# CONFIG_SERIAL_8250_DETECT_IRQ is not set -+# CONFIG_SERIAL_8250_RSA is not set -+ -+# -+# Non-8250 serial port support -+# -+# CONFIG_SERIAL_UARTLITE is not set -+CONFIG_SERIAL_CORE=y -+CONFIG_SERIAL_CORE_CONSOLE=y -+# CONFIG_SERIAL_JSM is not set -+CONFIG_SERIAL_OF_PLATFORM=y -+CONFIG_UNIX98_PTYS=y -+CONFIG_LEGACY_PTYS=y -+CONFIG_LEGACY_PTY_COUNT=256 -+# CONFIG_IPMI_HANDLER is not set -+# CONFIG_HW_RANDOM is not set -+# CONFIG_NVRAM is not set -+# CONFIG_GEN_RTC is not set -+# CONFIG_R3964 is not set -+# CONFIG_APPLICOM is not set -+# CONFIG_RAW_DRIVER is not set -+# CONFIG_TCG_TPM is not set -+CONFIG_DEVPORT=y -+# CONFIG_I2C is not set -+ -+# -+# SPI support -+# -+# CONFIG_SPI is not set -+# CONFIG_SPI_MASTER is not set -+# CONFIG_W1 is not set -+# CONFIG_POWER_SUPPLY is not set -+# CONFIG_HWMON is not set -+# CONFIG_WATCHDOG is not set -+ -+# -+# Sonics Silicon Backplane -+# -+CONFIG_SSB_POSSIBLE=y -+# CONFIG_SSB is not set -+ -+# -+# Multifunction device drivers -+# -+# CONFIG_MFD_SM501 is not set -+ -+# -+# Multimedia devices -+# -+# CONFIG_VIDEO_DEV is not set -+# CONFIG_DVB_CORE is not set -+CONFIG_DAB=y -+ -+# -+# Graphics support -+# -+# CONFIG_AGP is not set -+# CONFIG_DRM is not set -+# CONFIG_VGASTATE is not set -+CONFIG_VIDEO_OUTPUT_CONTROL=m -+# CONFIG_FB is not set -+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set -+ -+# -+# Display device support -+# -+# CONFIG_DISPLAY_SUPPORT is not set -+ -+# -+# Sound -+# -+# CONFIG_SOUND is not set -+CONFIG_USB_SUPPORT=y -+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 -+# CONFIG_MMC is not set -+# CONFIG_NEW_LEDS is not set -+# CONFIG_INFINIBAND is not set -+# CONFIG_EDAC is not set -+# CONFIG_RTC_CLASS is not set -+ -+# -+# Userspace I/O -+# -+# CONFIG_UIO 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_EXT4DEV_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_GFS2_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 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_MSDOS_FS is not set -+# CONFIG_VFAT_FS is not set -+# CONFIG_NTFS_FS is not set -+ -+# -+# Pseudo filesystems -+# -+CONFIG_PROC_FS=y -+CONFIG_PROC_KCORE=y -+CONFIG_PROC_SYSCTL=y -+CONFIG_SYSFS=y -+CONFIG_TMPFS=y -+# CONFIG_TMPFS_POSIX_ACL is not set -+# CONFIG_HUGETLB_PAGE 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_CRAMFS=y -+# 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 -+CONFIG_NETWORK_FILESYSTEMS=y -+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_SUNRPC_BIND34 is not set -+# 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 -+ -+# -+# Partition Types -+# -+# CONFIG_PARTITION_ADVANCED is not set -+CONFIG_MSDOS_PARTITION=y -+# CONFIG_NLS is not set -+# CONFIG_DLM is not set -+# CONFIG_UCC_SLOW is not set -+ -+# -+# Library routines -+# -+CONFIG_BITREVERSE=y -+# CONFIG_CRC_CCITT is not set -+# CONFIG_CRC16 is not set -+# CONFIG_CRC_ITU_T is not set -+CONFIG_CRC32=y -+# CONFIG_CRC7 is not set -+# CONFIG_LIBCRC32C is not set -+CONFIG_ZLIB_INFLATE=y -+CONFIG_PLIST=y -+CONFIG_HAS_IOMEM=y -+CONFIG_HAS_IOPORT=y -+CONFIG_HAS_DMA=y -+CONFIG_INSTRUMENTATION=y -+# CONFIG_PROFILING is not set -+# CONFIG_KPROBES is not set -+# CONFIG_MARKERS is not set -+ -+# -+# Kernel hacking -+# -+# CONFIG_PRINTK_TIME is not set -+CONFIG_ENABLE_WARN_DEPRECATED=y -+CONFIG_ENABLE_MUST_CHECK=y -+CONFIG_MAGIC_SYSRQ=y -+# CONFIG_UNUSED_SYMBOLS is not set -+# CONFIG_DEBUG_FS is not set -+# CONFIG_HEADERS_CHECK is not set -+CONFIG_DEBUG_KERNEL=y -+# CONFIG_DEBUG_SHIRQ is not set -+CONFIG_DETECT_SOFTLOCKUP=y -+CONFIG_SCHED_DEBUG=y -+# CONFIG_SCHEDSTATS is not set -+# CONFIG_TIMER_STATS is not set -+# CONFIG_SLUB_DEBUG_ON is not set -+# CONFIG_DEBUG_RT_MUTEXES is not set -+# CONFIG_RT_MUTEX_TESTER is not set -+# CONFIG_DEBUG_SPINLOCK is not set -+# CONFIG_DEBUG_MUTEXES is not set -+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -+# CONFIG_DEBUG_KOBJECT is not set -+# CONFIG_DEBUG_BUGVERBOSE is not set -+# CONFIG_DEBUG_INFO is not set -+# CONFIG_DEBUG_VM is not set -+# CONFIG_DEBUG_LIST is not set -+# CONFIG_DEBUG_SG is not set -+CONFIG_FORCED_INLINING=y -+# CONFIG_BOOT_PRINTK_DELAY is not set -+# CONFIG_RCU_TORTURE_TEST is not set -+# CONFIG_FAULT_INJECTION is not set -+# CONFIG_SAMPLES is not set -+# CONFIG_DEBUG_STACKOVERFLOW is not set -+# CONFIG_DEBUG_STACK_USAGE is not set -+# CONFIG_DEBUG_PAGEALLOC is not set -+CONFIG_DEBUGGER=y -+# CONFIG_KGDB is not set -+# CONFIG_XMON is not set -+# CONFIG_BDI_SWITCH is not set -+# CONFIG_PPC_EARLY_DEBUG is not set -+ -+# -+# Security options -+# -+# CONFIG_KEYS is not set -+# CONFIG_SECURITY is not set -+# CONFIG_SECURITY_FILE_CAPABILITIES is not set -+CONFIG_CRYPTO=y -+CONFIG_CRYPTO_ALGAPI=y -+CONFIG_CRYPTO_BLKCIPHER=y -+CONFIG_CRYPTO_MANAGER=y -+# CONFIG_CRYPTO_HMAC is not set -+# CONFIG_CRYPTO_XCBC is not set -+# CONFIG_CRYPTO_NULL is not set -+# CONFIG_CRYPTO_MD4 is not set -+CONFIG_CRYPTO_MD5=y -+# CONFIG_CRYPTO_SHA1 is not set -+# 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_GF128MUL is not set -+CONFIG_CRYPTO_ECB=y -+CONFIG_CRYPTO_CBC=y -+CONFIG_CRYPTO_PCBC=y -+# CONFIG_CRYPTO_LRW is not set -+# CONFIG_CRYPTO_XTS is not set -+# CONFIG_CRYPTO_CRYPTD is not set -+CONFIG_CRYPTO_DES=y -+# CONFIG_CRYPTO_FCRYPT is not set -+# 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_SEED is not set -+# CONFIG_CRYPTO_DEFLATE is not set -+# CONFIG_CRYPTO_MICHAEL_MIC is not set -+# CONFIG_CRYPTO_CRC32C is not set -+# CONFIG_CRYPTO_CAMELLIA is not set -+# CONFIG_CRYPTO_TEST is not set -+# CONFIG_CRYPTO_AUTHENC is not set -+CONFIG_CRYPTO_HW=y -+# CONFIG_PPC_CLOCK is not set ---- a/arch/powerpc/configs/walnut_defconfig -+++ b/arch/powerpc/configs/walnut_defconfig -@@ -1,7 +1,7 @@ - # - # Automatically generated make config: don't edit --# Linux kernel version: 2.6.24-rc4 --# Thu Dec 6 16:49:33 2007 -+# Linux kernel version: 2.6.24-rc6 -+# Mon Dec 24 11:23:58 2007 - # - # CONFIG_PPC64 is not set - -@@ -40,7 +40,7 @@ CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y - CONFIG_ARCH_MAY_HAVE_PC_FDC=y - CONFIG_PPC_OF=y - CONFIG_OF=y --# CONFIG_PPC_UDBG_16550 is not set -+CONFIG_PPC_UDBG_16550=y - # CONFIG_GENERIC_TBSYNC is not set - CONFIG_AUDIT_ARCH=y - CONFIG_GENERIC_BUG=y -@@ -127,6 +127,7 @@ CONFIG_DEFAULT_AS=y - # CONFIG_DEFAULT_CFQ is not set - # CONFIG_DEFAULT_NOOP is not set - CONFIG_DEFAULT_IOSCHED="anticipatory" -+# CONFIG_PPC4xx_PCI_EXPRESS is not set - - # - # Platform support -@@ -136,7 +137,9 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" - # CONFIG_PPC_CELL is not set - # CONFIG_PPC_CELL_NATIVE is not set - # CONFIG_PQ2ADS is not set -+# CONFIG_EP405 is not set - # CONFIG_KILAUEA is not set -+# CONFIG_MAKALU is not set - CONFIG_WALNUT=y - # CONFIG_XILINX_VIRTEX_GENERIC_BOARD is not set - CONFIG_405GP=y -@@ -204,11 +207,17 @@ CONFIG_ISA_DMA_API=y - # Bus options - # - CONFIG_ZONE_DMA=y --# CONFIG_PCI is not set --# CONFIG_PCI_DOMAINS is not set --# CONFIG_PCI_SYSCALL is not set --# CONFIG_ARCH_SUPPORTS_MSI is not set -+CONFIG_PPC_INDIRECT_PCI=y -+CONFIG_PCI=y -+CONFIG_PCI_DOMAINS=y -+CONFIG_PCI_SYSCALL=y -+# CONFIG_PCIEPORTBUS is not set -+CONFIG_ARCH_SUPPORTS_MSI=y -+# CONFIG_PCI_MSI is not set -+# CONFIG_PCI_LEGACY is not set -+# CONFIG_PCI_DEBUG is not set - # CONFIG_PCCARD is not set -+# CONFIG_HOTPLUG_PCI is not set - - # - # Advanced setup -@@ -373,11 +382,13 @@ CONFIG_MTD_CFI_UTIL=y - # CONFIG_MTD_COMPLEX_MAPPINGS is not set - # CONFIG_MTD_PHYSMAP is not set - CONFIG_MTD_PHYSMAP_OF=y -+# CONFIG_MTD_INTEL_VR_NOR is not set - # CONFIG_MTD_PLATRAM is not set - - # - # Self-contained MTD device drivers - # -+# CONFIG_MTD_PMC551 is not set - # CONFIG_MTD_SLRAM is not set - # CONFIG_MTD_PHRAM is not set - # CONFIG_MTD_MTDRAM is not set -@@ -400,9 +411,14 @@ CONFIG_OF_DEVICE=y - # CONFIG_PARPORT is not set - CONFIG_BLK_DEV=y - # 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 is not set - # CONFIG_BLK_DEV_NBD is not set -+# CONFIG_BLK_DEV_SX8 is not set - CONFIG_BLK_DEV_RAM=y - CONFIG_BLK_DEV_RAM_COUNT=16 - CONFIG_BLK_DEV_RAM_SIZE=35000 -@@ -411,7 +427,10 @@ CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 - # CONFIG_ATA_OVER_ETH is not set - # CONFIG_XILINX_SYSACE is not set - CONFIG_MISC_DEVICES=y -+# CONFIG_PHANTOM is not set - # CONFIG_EEPROM_93CX6 is not set -+# CONFIG_SGI_IOC4 is not set -+# CONFIG_TIFM_CORE is not set - # CONFIG_IDE is not set - - # -@@ -423,6 +442,14 @@ CONFIG_MISC_DEVICES=y - # CONFIG_SCSI_NETLINK is not set - # CONFIG_ATA is not set - # CONFIG_MD is not set -+# CONFIG_FUSION is not set -+ -+# -+# IEEE 1394 (FireWire) support -+# -+# CONFIG_FIREWIRE is not set -+# CONFIG_IEEE1394 is not set -+# CONFIG_I2O is not set - # CONFIG_MACINTOSH_DRIVERS is not set - CONFIG_NETDEVICES=y - # CONFIG_NETDEVICES_MULTIQUEUE is not set -@@ -432,9 +459,17 @@ CONFIG_NETDEVICES=y - # CONFIG_EQUALIZER is not set - # CONFIG_TUN is not set - # CONFIG_VETH is not set -+# CONFIG_IP1000 is not set -+# CONFIG_ARCNET is not set - # CONFIG_PHYLIB is not set - CONFIG_NET_ETHERNET=y - # CONFIG_MII is not set -+# CONFIG_HAPPYMEAL is not set -+# CONFIG_SUNGEM is not set -+# CONFIG_CASSINI is not set -+# CONFIG_NET_VENDOR_3COM is not set -+# CONFIG_NET_TULIP is not set -+# CONFIG_HP100 is not set - CONFIG_IBM_NEW_EMAC=y - CONFIG_IBM_NEW_EMAC_RXB=128 - CONFIG_IBM_NEW_EMAC_TXB=64 -@@ -446,9 +481,38 @@ CONFIG_IBM_NEW_EMAC_ZMII=y - # CONFIG_IBM_NEW_EMAC_RGMII is not set - # CONFIG_IBM_NEW_EMAC_TAH is not set - # CONFIG_IBM_NEW_EMAC_EMAC4 is not set -+# CONFIG_NET_PCI is not set - # CONFIG_B44 is not set - CONFIG_NETDEV_1000=y -+# CONFIG_ACENIC is not set -+# CONFIG_DL2K is not set -+# CONFIG_E1000 is not set -+# CONFIG_E1000E 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 -+# CONFIG_QLA3XXX is not set -+# CONFIG_ATL1 is not set - CONFIG_NETDEV_10000=y -+# CONFIG_CHELSIO_T1 is not set -+# CONFIG_CHELSIO_T3 is not set -+# CONFIG_IXGBE is not set -+# CONFIG_IXGB is not set -+# CONFIG_S2IO is not set -+# CONFIG_MYRI10GE is not set -+# CONFIG_NETXEN_NIC is not set -+# CONFIG_NIU is not set -+# CONFIG_MLX4_CORE is not set -+# CONFIG_TEHUTI is not set -+# CONFIG_TR is not set - - # - # Wireless LAN -@@ -456,6 +520,8 @@ CONFIG_NETDEV_10000=y - # CONFIG_WLAN_PRE80211 is not set - # CONFIG_WLAN_80211 is not set - # CONFIG_WAN is not set -+# CONFIG_FDDI is not set -+# CONFIG_HIPPI is not set - # CONFIG_PPP is not set - # CONFIG_SLIP is not set - # CONFIG_SHAPER is not set -@@ -487,6 +553,7 @@ CONFIG_NETDEV_10000=y - # - 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 -@@ -501,6 +568,7 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y - # CONFIG_SERIAL_UARTLITE is not set - CONFIG_SERIAL_CORE=y - CONFIG_SERIAL_CORE_CONSOLE=y -+# CONFIG_SERIAL_JSM is not set - CONFIG_SERIAL_OF_PLATFORM=y - CONFIG_UNIX98_PTYS=y - CONFIG_LEGACY_PTYS=y -@@ -510,8 +578,10 @@ CONFIG_LEGACY_PTY_COUNT=256 - # CONFIG_NVRAM is not set - # CONFIG_GEN_RTC is not set - # CONFIG_R3964 is not set -+# CONFIG_APPLICOM is not set - # CONFIG_RAW_DRIVER is not set - # CONFIG_TCG_TPM is not set -+CONFIG_DEVPORT=y - # CONFIG_I2C is not set - - # -@@ -545,6 +615,8 @@ CONFIG_SSB_POSSIBLE=y - # - # Graphics support - # -+# CONFIG_AGP is not set -+# CONFIG_DRM is not set - # CONFIG_VGASTATE is not set - CONFIG_VIDEO_OUTPUT_CONTROL=m - # CONFIG_FB is not set -@@ -560,9 +632,10 @@ CONFIG_VIDEO_OUTPUT_CONTROL=m - # - # CONFIG_SOUND is not set - CONFIG_USB_SUPPORT=y --# CONFIG_USB_ARCH_HAS_HCD is not set --# CONFIG_USB_ARCH_HAS_OHCI is not set --# CONFIG_USB_ARCH_HAS_EHCI is not set -+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' -@@ -574,6 +647,7 @@ CONFIG_USB_SUPPORT=y - # CONFIG_USB_GADGET is not set - # CONFIG_MMC is not set - # CONFIG_NEW_LEDS is not set -+# CONFIG_INFINIBAND is not set - # CONFIG_EDAC is not set - # CONFIG_RTC_CLASS is not set - ---- /dev/null -+++ b/arch/powerpc/configs/warp_defconfig -@@ -0,0 +1,1057 @@ -+# -+# Automatically generated make config: don't edit -+# Linux kernel version: 2.6.24-rc6 -+# Tue Jan 8 12:23:23 2008 -+# -+# CONFIG_PPC64 is not set -+ -+# -+# Processor support -+# -+# CONFIG_6xx is not set -+# CONFIG_PPC_85xx is not set -+# CONFIG_PPC_8xx is not set -+# CONFIG_40x is not set -+CONFIG_44x=y -+# CONFIG_E200 is not set -+CONFIG_PPC_FPU=y -+CONFIG_4xx=y -+CONFIG_BOOKE=y -+CONFIG_PTE_64BIT=y -+CONFIG_PHYS_64BIT=y -+# CONFIG_PPC_MM_SLICES is not set -+CONFIG_NOT_COHERENT_CACHE=y -+CONFIG_PPC32=y -+CONFIG_WORD_SIZE=32 -+CONFIG_PPC_MERGE=y -+CONFIG_MMU=y -+CONFIG_GENERIC_CMOS_UPDATE=y -+CONFIG_GENERIC_TIME=y -+CONFIG_GENERIC_TIME_VSYSCALL=y -+CONFIG_GENERIC_CLOCKEVENTS=y -+CONFIG_GENERIC_HARDIRQS=y -+CONFIG_IRQ_PER_CPU=y -+CONFIG_RWSEM_XCHGADD_ALGORITHM=y -+CONFIG_ARCH_HAS_ILOG2_U32=y -+CONFIG_GENERIC_HWEIGHT=y -+CONFIG_GENERIC_CALIBRATE_DELAY=y -+CONFIG_GENERIC_FIND_NEXT_BIT=y -+# CONFIG_ARCH_NO_VIRT_TO_BUS is not set -+CONFIG_PPC=y -+CONFIG_EARLY_PRINTK=y -+CONFIG_GENERIC_NVRAM=y -+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y -+CONFIG_ARCH_MAY_HAVE_PC_FDC=y -+CONFIG_PPC_OF=y -+CONFIG_OF=y -+CONFIG_PPC_UDBG_16550=y -+# CONFIG_GENERIC_TBSYNC is not set -+CONFIG_AUDIT_ARCH=y -+CONFIG_GENERIC_BUG=y -+# CONFIG_DEFAULT_UIMAGE is not set -+CONFIG_PPC_DCR_NATIVE=y -+# CONFIG_PPC_DCR_MMIO is not set -+CONFIG_PPC_DCR=y -+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" -+ -+# -+# General setup -+# -+CONFIG_EXPERIMENTAL=y -+CONFIG_BROKEN_ON_SMP=y -+CONFIG_INIT_ENV_ARG_LIMIT=32 -+CONFIG_LOCALVERSION="-pika" -+# CONFIG_LOCALVERSION_AUTO is not set -+CONFIG_SWAP=y -+CONFIG_SYSVIPC=y -+CONFIG_SYSVIPC_SYSCTL=y -+# CONFIG_POSIX_MQUEUE is not set -+# CONFIG_BSD_PROCESS_ACCT is not set -+# CONFIG_TASKSTATS is not set -+# CONFIG_USER_NS is not set -+# CONFIG_PID_NS is not set -+# CONFIG_AUDIT is not set -+# CONFIG_IKCONFIG is not set -+CONFIG_LOG_BUF_SHIFT=14 -+# CONFIG_CGROUPS is not set -+CONFIG_FAIR_GROUP_SCHED=y -+CONFIG_FAIR_USER_SCHED=y -+# CONFIG_FAIR_CGROUP_SCHED is not set -+CONFIG_SYSFS_DEPRECATED=y -+# CONFIG_RELAY is not set -+CONFIG_BLK_DEV_INITRD=y -+CONFIG_INITRAMFS_SOURCE="" -+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -+CONFIG_SYSCTL=y -+CONFIG_EMBEDDED=y -+CONFIG_SYSCTL_SYSCALL=y -+CONFIG_KALLSYMS=y -+# CONFIG_KALLSYMS_ALL is not set -+# CONFIG_KALLSYMS_EXTRA_PASS is not set -+# CONFIG_HOTPLUG is not set -+CONFIG_PRINTK=y -+CONFIG_BUG=y -+CONFIG_ELF_CORE=y -+CONFIG_BASE_FULL=y -+CONFIG_FUTEX=y -+CONFIG_ANON_INODES=y -+CONFIG_EPOLL=y -+CONFIG_SIGNALFD=y -+CONFIG_EVENTFD=y -+CONFIG_SHMEM=y -+CONFIG_VM_EVENT_COUNTERS=y -+CONFIG_SLAB=y -+# CONFIG_SLUB is not set -+# CONFIG_SLOB is not set -+CONFIG_RT_MUTEXES=y -+# CONFIG_TINY_SHMEM is not set -+CONFIG_BASE_SMALL=0 -+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 -+CONFIG_BLOCK=y -+# CONFIG_LBD is not set -+# CONFIG_BLK_DEV_IO_TRACE is not set -+# CONFIG_LSF is not set -+# CONFIG_BLK_DEV_BSG is not set -+ -+# -+# IO Schedulers -+# -+CONFIG_IOSCHED_NOOP=y -+CONFIG_IOSCHED_AS=y -+CONFIG_IOSCHED_DEADLINE=y -+CONFIG_IOSCHED_CFQ=y -+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" -+ -+# -+# Platform support -+# -+# CONFIG_PPC_MPC52xx is not set -+# CONFIG_PPC_MPC5200 is not set -+# CONFIG_PPC_CELL is not set -+# CONFIG_PPC_CELL_NATIVE is not set -+# CONFIG_PQ2ADS is not set -+# CONFIG_BAMBOO is not set -+# CONFIG_EBONY is not set -+# CONFIG_SEQUOIA is not set -+# CONFIG_TAISHAN is not set -+# CONFIG_KATMAI is not set -+# CONFIG_RAINIER is not set -+CONFIG_WARP=y -+CONFIG_440EP=y -+CONFIG_IBM440EP_ERR42=y -+# CONFIG_MPIC is not set -+# CONFIG_MPIC_WEIRD is not set -+# CONFIG_PPC_I8259 is not set -+# CONFIG_PPC_RTAS is not set -+# CONFIG_MMIO_NVRAM is not set -+# CONFIG_PPC_MPC106 is not set -+# CONFIG_PPC_970_NAP is not set -+# CONFIG_PPC_INDIRECT_IO is not set -+# CONFIG_GENERIC_IOMAP is not set -+# CONFIG_CPU_FREQ is not set -+# CONFIG_CPM2 is not set -+# CONFIG_FSL_ULI1575 is not set -+ -+# -+# Kernel options -+# -+# CONFIG_HIGHMEM is not set -+# CONFIG_TICK_ONESHOT is not set -+# CONFIG_NO_HZ is not set -+# CONFIG_HIGH_RES_TIMERS is not set -+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y -+# CONFIG_HZ_100 is not set -+# CONFIG_HZ_250 is not set -+# CONFIG_HZ_300 is not set -+CONFIG_HZ_1000=y -+CONFIG_HZ=1000 -+CONFIG_PREEMPT_NONE=y -+# CONFIG_PREEMPT_VOLUNTARY is not set -+# CONFIG_PREEMPT is not set -+CONFIG_BINFMT_ELF=y -+# CONFIG_BINFMT_MISC is not set -+# CONFIG_MATH_EMULATION is not set -+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y -+CONFIG_ARCH_FLATMEM_ENABLE=y -+CONFIG_ARCH_POPULATES_NODE_MAP=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 is not set -+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set -+CONFIG_SPLIT_PTLOCK_CPUS=4 -+CONFIG_RESOURCES_64BIT=y -+CONFIG_ZONE_DMA_FLAG=1 -+CONFIG_BOUNCE=y -+CONFIG_VIRT_TO_BUS=y -+CONFIG_PROC_DEVICETREE=y -+CONFIG_CMDLINE_BOOL=y -+CONFIG_CMDLINE="ip=on" -+CONFIG_SECCOMP=y -+CONFIG_WANT_DEVICE_TREE=y -+CONFIG_DEVICE_TREE="warp.dts" -+CONFIG_ISA_DMA_API=y -+ -+# -+# Bus options -+# -+CONFIG_ZONE_DMA=y -+# CONFIG_PCI is not set -+# CONFIG_PCI_DOMAINS is not set -+# CONFIG_PCI_SYSCALL is not set -+# CONFIG_ARCH_SUPPORTS_MSI is not set -+ -+# -+# Advanced setup -+# -+# CONFIG_ADVANCED_OPTIONS is not set -+ -+# -+# Default settings for advanced configuration options are used -+# -+CONFIG_HIGHMEM_START=0xfe000000 -+CONFIG_LOWMEM_SIZE=0x30000000 -+CONFIG_KERNEL_START=0xc0000000 -+CONFIG_TASK_SIZE=0xc0000000 -+CONFIG_CONSISTENT_START=0xff100000 -+CONFIG_CONSISTENT_SIZE=0x00200000 -+CONFIG_BOOT_LOAD=0x01000000 -+ -+# -+# Networking -+# -+CONFIG_NET=y -+ -+# -+# Networking options -+# -+CONFIG_PACKET=y -+# CONFIG_PACKET_MMAP is not set -+CONFIG_UNIX=y -+CONFIG_XFRM=y -+# CONFIG_XFRM_USER is not set -+# CONFIG_XFRM_SUB_POLICY is not set -+# CONFIG_XFRM_MIGRATE is not set -+# CONFIG_NET_KEY is not set -+CONFIG_INET=y -+# CONFIG_IP_MULTICAST is not set -+# 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 is not set -+# CONFIG_IP_PNP_RARP is not set -+# CONFIG_NET_IPIP is not set -+# CONFIG_NET_IPGRE 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_XFRM_MODE_BEET=y -+# CONFIG_INET_LRO is not set -+CONFIG_INET_DIAG=y -+CONFIG_INET_TCP_DIAG=y -+# CONFIG_TCP_CONG_ADVANCED is not set -+CONFIG_TCP_CONG_CUBIC=y -+CONFIG_DEFAULT_TCP_CONG="cubic" -+# CONFIG_TCP_MD5SIG is not set -+# CONFIG_IP_VS is not set -+# 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=y -+# CONFIG_NETFILTER_DEBUG is not set -+ -+# -+# Core Netfilter Configuration -+# -+# CONFIG_NETFILTER_NETLINK is not set -+# CONFIG_NF_CONNTRACK_ENABLED is not set -+# CONFIG_NF_CONNTRACK is not set -+# CONFIG_NETFILTER_XTABLES is not set -+ -+# -+# IP: Netfilter Configuration -+# -+# CONFIG_IP_NF_QUEUE is not set -+# CONFIG_IP_NF_IPTABLES is not set -+# CONFIG_IP_NF_ARPTABLES is not set -+# CONFIG_IP_DCCP is not set -+# CONFIG_IP_SCTP is not set -+# CONFIG_TIPC is not set -+# CONFIG_ATM is not set -+# CONFIG_BRIDGE is not set -+CONFIG_VLAN_8021Q=y -+# 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_ECONET is not set -+# CONFIG_WAN_ROUTER is not set -+# 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_AF_RXRPC is not set -+ -+# -+# Wireless -+# -+# CONFIG_CFG80211 is not set -+# CONFIG_WIRELESS_EXT is not set -+# CONFIG_MAC80211 is not set -+# CONFIG_IEEE80211 is not set -+# CONFIG_RFKILL is not set -+# CONFIG_NET_9P is not set -+ -+# -+# Device Drivers -+# -+ -+# -+# Generic Driver Options -+# -+# CONFIG_STANDALONE is not set -+CONFIG_PREVENT_FIRMWARE_BUILD=y -+# CONFIG_DEBUG_DRIVER is not set -+# CONFIG_DEBUG_DEVRES is not set -+# CONFIG_SYS_HYPERVISOR is not set -+# CONFIG_CONNECTOR is not set -+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 is not set -+ -+# -+# User Modules And Translation Layers -+# -+CONFIG_MTD_CHAR=y -+CONFIG_MTD_BLKDEVS=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 -+# CONFIG_SSFDC is not set -+CONFIG_MTD_OOPS=m -+ -+# -+# 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 is not set -+CONFIG_MTD_CFI_AMDSTD=y -+# 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 -+ -+# -+# Mapping drivers for chip access -+# -+# CONFIG_MTD_COMPLEX_MAPPINGS is not set -+# CONFIG_MTD_PHYSMAP is not set -+CONFIG_MTD_PHYSMAP_OF=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 -+CONFIG_MTD_NAND=y -+# CONFIG_MTD_NAND_VERIFY_WRITE is not set -+CONFIG_MTD_NAND_ECC_SMC=y -+# CONFIG_MTD_NAND_MUSEUM_IDS is not set -+CONFIG_MTD_NAND_IDS=y -+CONFIG_MTD_NAND_NDFC=y -+# CONFIG_MTD_NAND_DISKONCHIP is not set -+# CONFIG_MTD_NAND_NANDSIM is not set -+# CONFIG_MTD_NAND_PLATFORM is not set -+# CONFIG_MTD_ALAUDA is not set -+# CONFIG_MTD_ONENAND is not set -+ -+# -+# UBI - Unsorted block images -+# -+# CONFIG_MTD_UBI is not set -+CONFIG_OF_DEVICE=y -+# CONFIG_PARPORT is not set -+CONFIG_BLK_DEV=y -+# CONFIG_BLK_DEV_FD is not set -+# CONFIG_BLK_DEV_COW_COMMON is not set -+# CONFIG_BLK_DEV_LOOP is not set -+# CONFIG_BLK_DEV_NBD is not set -+# CONFIG_BLK_DEV_UB is not set -+CONFIG_BLK_DEV_RAM=y -+CONFIG_BLK_DEV_RAM_COUNT=16 -+CONFIG_BLK_DEV_RAM_SIZE=4096 -+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 -+# CONFIG_CDROM_PKTCDVD is not set -+# CONFIG_ATA_OVER_ETH is not set -+# CONFIG_XILINX_SYSACE is not set -+CONFIG_MISC_DEVICES=y -+# CONFIG_EEPROM_93CX6 is not set -+# CONFIG_IDE is not set -+ -+# -+# SCSI device support -+# -+# CONFIG_RAID_ATTRS is not set -+CONFIG_SCSI=y -+CONFIG_SCSI_DMA=y -+# CONFIG_SCSI_TGT is not set -+# CONFIG_SCSI_NETLINK is not set -+CONFIG_SCSI_PROC_FS=y -+ -+# -+# SCSI support type (disk, tape, CD-ROM) -+# -+CONFIG_BLK_DEV_SD=y -+# CONFIG_CHR_DEV_ST is not set -+# CONFIG_CHR_DEV_OSST is not set -+# CONFIG_BLK_DEV_SR is not set -+# CONFIG_CHR_DEV_SG is not set -+# CONFIG_CHR_DEV_SCH is not set -+ -+# -+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -+# -+# CONFIG_SCSI_MULTI_LUN is not set -+# CONFIG_SCSI_CONSTANTS is not set -+# CONFIG_SCSI_LOGGING is not set -+# CONFIG_SCSI_SCAN_ASYNC is not set -+# CONFIG_SCSI_WAIT_SCAN is not set -+ -+# -+# SCSI Transports -+# -+CONFIG_SCSI_SPI_ATTRS=y -+# CONFIG_SCSI_FC_ATTRS is not set -+# CONFIG_SCSI_ISCSI_ATTRS is not set -+# CONFIG_SCSI_SAS_LIBSAS is not set -+# CONFIG_SCSI_SRP_ATTRS is not set -+# CONFIG_SCSI_LOWLEVEL is not set -+# CONFIG_ATA is not set -+# CONFIG_MD is not set -+# CONFIG_MACINTOSH_DRIVERS is not set -+CONFIG_NETDEVICES=y -+# CONFIG_NETDEVICES_MULTIQUEUE is not set -+# CONFIG_DUMMY is not set -+# CONFIG_BONDING is not set -+# CONFIG_MACVLAN is not set -+# CONFIG_EQUALIZER is not set -+# CONFIG_TUN is not set -+# CONFIG_VETH is not set -+# CONFIG_PHYLIB is not set -+CONFIG_NET_ETHERNET=y -+CONFIG_MII=y -+CONFIG_IBM_NEW_EMAC=y -+CONFIG_IBM_NEW_EMAC_RXB=128 -+CONFIG_IBM_NEW_EMAC_TXB=64 -+CONFIG_IBM_NEW_EMAC_POLL_WEIGHT=32 -+CONFIG_IBM_NEW_EMAC_RX_COPY_THRESHOLD=256 -+CONFIG_IBM_NEW_EMAC_RX_SKB_HEADROOM=0 -+# CONFIG_IBM_NEW_EMAC_DEBUG is not set -+CONFIG_IBM_NEW_EMAC_ZMII=y -+# CONFIG_IBM_NEW_EMAC_RGMII is not set -+# CONFIG_IBM_NEW_EMAC_TAH is not set -+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set -+# CONFIG_B44 is not set -+# CONFIG_NETDEV_1000 is not set -+# CONFIG_NETDEV_10000 is not set -+ -+# -+# Wireless LAN -+# -+# CONFIG_WLAN_PRE80211 is not set -+# CONFIG_WLAN_80211 is not set -+ -+# -+# USB Network Adapters -+# -+# CONFIG_USB_CATC is not set -+# CONFIG_USB_KAWETH is not set -+# CONFIG_USB_PEGASUS is not set -+# CONFIG_USB_RTL8150 is not set -+# CONFIG_USB_USBNET is not set -+# 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 -+# CONFIG_ISDN is not set -+# CONFIG_PHONE is not set -+ -+# -+# Input device support -+# -+# CONFIG_INPUT is not set -+ -+# -+# Hardware I/O ports -+# -+# CONFIG_SERIO is not set -+# CONFIG_GAMEPORT is not set -+ -+# -+# Character devices -+# -+# CONFIG_VT is not set -+# CONFIG_SERIAL_NONSTANDARD is not set -+ -+# -+# Serial drivers -+# -+CONFIG_SERIAL_8250=y -+CONFIG_SERIAL_8250_CONSOLE=y -+CONFIG_SERIAL_8250_NR_UARTS=4 -+CONFIG_SERIAL_8250_RUNTIME_UARTS=4 -+CONFIG_SERIAL_8250_EXTENDED=y -+# CONFIG_SERIAL_8250_MANY_PORTS is not set -+CONFIG_SERIAL_8250_SHARE_IRQ=y -+# CONFIG_SERIAL_8250_DETECT_IRQ is not set -+# CONFIG_SERIAL_8250_RSA is not set -+ -+# -+# Non-8250 serial port support -+# -+# CONFIG_SERIAL_UARTLITE is not set -+CONFIG_SERIAL_CORE=y -+CONFIG_SERIAL_CORE_CONSOLE=y -+# CONFIG_SERIAL_OF_PLATFORM is not set -+CONFIG_UNIX98_PTYS=y -+CONFIG_LEGACY_PTYS=y -+CONFIG_LEGACY_PTY_COUNT=256 -+# CONFIG_IPMI_HANDLER is not set -+CONFIG_HW_RANDOM=y -+# CONFIG_NVRAM is not set -+# CONFIG_GEN_RTC is not set -+# CONFIG_R3964 is not set -+# CONFIG_RAW_DRIVER is not set -+# CONFIG_TCG_TPM is not set -+CONFIG_I2C=y -+CONFIG_I2C_BOARDINFO=y -+# CONFIG_I2C_CHARDEV is not set -+ -+# -+# 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_IBM_IIC=y -+# CONFIG_I2C_MPC is not set -+# CONFIG_I2C_OCORES is not set -+# CONFIG_I2C_PARPORT_LIGHT is not set -+# CONFIG_I2C_SIMTEC is not set -+# CONFIG_I2C_TAOS_EVM is not set -+# CONFIG_I2C_STUB is not set -+# CONFIG_I2C_TINY_USB is not set -+ -+# -+# Miscellaneous I2C Chip support -+# -+# CONFIG_SENSORS_DS1337 is not set -+# CONFIG_SENSORS_DS1374 is not set -+# CONFIG_DS1682 is not set -+CONFIG_SENSORS_EEPROM=y -+# CONFIG_SENSORS_PCF8574 is not set -+# CONFIG_SENSORS_PCA9539 is not set -+# CONFIG_SENSORS_PCF8591 is not set -+# CONFIG_SENSORS_M41T00 is not set -+# CONFIG_SENSORS_MAX6875 is not set -+# CONFIG_SENSORS_TSL2550 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 -+# CONFIG_W1 is not set -+# CONFIG_POWER_SUPPLY is not set -+CONFIG_HWMON=y -+# CONFIG_HWMON_VID is not set -+CONFIG_SENSORS_AD7414=y -+# CONFIG_SENSORS_AD7418 is not set -+# CONFIG_SENSORS_ADM1021 is not set -+# CONFIG_SENSORS_ADM1025 is not set -+# CONFIG_SENSORS_ADM1026 is not set -+# CONFIG_SENSORS_ADM1029 is not set -+# CONFIG_SENSORS_ADM1031 is not set -+# CONFIG_SENSORS_ADM9240 is not set -+# CONFIG_SENSORS_ADT7470 is not set -+# CONFIG_SENSORS_ATXP1 is not set -+# CONFIG_SENSORS_DS1621 is not set -+# CONFIG_SENSORS_F71805F is not set -+# CONFIG_SENSORS_F71882FG is not set -+# CONFIG_SENSORS_F75375S 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_LM93 is not set -+# CONFIG_SENSORS_MAX1619 is not set -+# CONFIG_SENSORS_MAX6650 is not set -+# CONFIG_SENSORS_PC87360 is not set -+# CONFIG_SENSORS_PC87427 is not set -+# CONFIG_SENSORS_DME1737 is not set -+# CONFIG_SENSORS_SMSC47M1 is not set -+# CONFIG_SENSORS_SMSC47M192 is not set -+# CONFIG_SENSORS_SMSC47B397 is not set -+# CONFIG_SENSORS_THMC50 is not set -+# CONFIG_SENSORS_VT1211 is not set -+# CONFIG_SENSORS_W83781D is not set -+# CONFIG_SENSORS_W83791D is not set -+# CONFIG_SENSORS_W83792D is not set -+# CONFIG_SENSORS_W83793 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 -+# CONFIG_WATCHDOG is not set -+ -+# -+# Sonics Silicon Backplane -+# -+CONFIG_SSB_POSSIBLE=y -+# CONFIG_SSB is not set -+ -+# -+# Multifunction device drivers -+# -+# CONFIG_MFD_SM501 is not set -+ -+# -+# Multimedia devices -+# -+# CONFIG_VIDEO_DEV is not set -+# CONFIG_DVB_CORE is not set -+# CONFIG_DAB is not set -+ -+# -+# Graphics support -+# -+# CONFIG_VGASTATE is not set -+# CONFIG_VIDEO_OUTPUT_CONTROL is not set -+# CONFIG_FB is not set -+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set -+ -+# -+# Display device support -+# -+# CONFIG_DISPLAY_SUPPORT is not set -+ -+# -+# Sound -+# -+# CONFIG_SOUND is not set -+CONFIG_USB_SUPPORT=y -+CONFIG_USB_ARCH_HAS_HCD=y -+CONFIG_USB_ARCH_HAS_OHCI=y -+# CONFIG_USB_ARCH_HAS_EHCI is not set -+CONFIG_USB=y -+# CONFIG_USB_DEBUG is not set -+ -+# -+# Miscellaneous USB options -+# -+# CONFIG_USB_DEVICEFS is not set -+CONFIG_USB_DEVICE_CLASS=y -+# CONFIG_USB_DYNAMIC_MINORS is not set -+# CONFIG_USB_OTG is not set -+ -+# -+# USB Host Controller Drivers -+# -+# CONFIG_USB_ISP116X_HCD is not set -+CONFIG_USB_OHCI_HCD=y -+CONFIG_USB_OHCI_HCD_PPC_OF=y -+CONFIG_USB_OHCI_HCD_PPC_OF_BE=y -+# CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set -+CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y -+CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y -+CONFIG_USB_OHCI_LITTLE_ENDIAN=y -+# CONFIG_USB_SL811_HCD is not set -+# CONFIG_USB_R8A66597_HCD is not set -+ -+# -+# USB Device Class drivers -+# -+# CONFIG_USB_ACM is not set -+# CONFIG_USB_PRINTER is not set -+ -+# -+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -+# -+ -+# -+# may also be needed; see USB_STORAGE Help for more information -+# -+CONFIG_USB_STORAGE=y -+# 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_USBAT is not set -+# CONFIG_USB_STORAGE_SDDR09 is not set -+# CONFIG_USB_STORAGE_SDDR55 is not set -+# CONFIG_USB_STORAGE_JUMPSHOT is not set -+# CONFIG_USB_STORAGE_ALAUDA is not set -+# CONFIG_USB_STORAGE_KARMA is not set -+# CONFIG_USB_LIBUSUAL is not set -+ -+# -+# USB Imaging devices -+# -+# CONFIG_USB_MDC800 is not set -+# CONFIG_USB_MICROTEK is not set -+CONFIG_USB_MON=y -+ -+# -+# USB port drivers -+# -+ -+# -+# USB Serial Converter support -+# -+# CONFIG_USB_SERIAL is not set -+ -+# -+# USB Miscellaneous drivers -+# -+# CONFIG_USB_EMI62 is not set -+# CONFIG_USB_EMI26 is not set -+# CONFIG_USB_ADUTUX is not set -+# CONFIG_USB_AUERSWALD is not set -+# CONFIG_USB_RIO500 is not set -+# CONFIG_USB_LEGOTOWER is not set -+# CONFIG_USB_LCD is not set -+# CONFIG_USB_BERRY_CHARGE is not set -+# CONFIG_USB_LED is not set -+# CONFIG_USB_CYPRESS_CY7C63 is not set -+# CONFIG_USB_CYTHERM is not set -+# CONFIG_USB_PHIDGET is not set -+# CONFIG_USB_IDMOUSE is not set -+# CONFIG_USB_FTDI_ELAN is not set -+# CONFIG_USB_APPLEDISPLAY is not set -+# CONFIG_USB_LD is not set -+# CONFIG_USB_TRANCEVIBRATOR is not set -+# CONFIG_USB_IOWARRIOR is not set -+ -+# -+# USB DSL modem support -+# -+ -+# -+# USB Gadget Support -+# -+# CONFIG_USB_GADGET is not set -+CONFIG_MMC=m -+# CONFIG_MMC_DEBUG is not set -+# CONFIG_MMC_UNSAFE_RESUME is not set -+ -+# -+# MMC/SD Card Drivers -+# -+CONFIG_MMC_BLOCK=m -+CONFIG_MMC_BLOCK_BOUNCE=y -+# CONFIG_SDIO_UART is not set -+ -+# -+# MMC/SD Host Controller Drivers -+# -+# CONFIG_MMC_WBSD is not set -+# CONFIG_NEW_LEDS is not set -+# CONFIG_EDAC is not set -+# CONFIG_RTC_CLASS is not set -+ -+# -+# Userspace I/O -+# -+# CONFIG_UIO 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_EXT4DEV_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_GFS2_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 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_PROC_KCORE=y -+CONFIG_PROC_SYSCTL=y -+CONFIG_SYSFS=y -+# CONFIG_TMPFS is not set -+# CONFIG_HUGETLB_PAGE 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_JFFS2_FS=y -+CONFIG_JFFS2_FS_DEBUG=0 -+CONFIG_JFFS2_FS_WRITEBUFFER=y -+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set -+# 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_LZO is not set -+CONFIG_JFFS2_RTIME=y -+# CONFIG_JFFS2_RUBIN is not set -+CONFIG_CRAMFS=y -+# 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 -+CONFIG_NETWORK_FILESYSTEMS=y -+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_SUNRPC_BIND34 is not set -+# 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 -+ -+# -+# Partition Types -+# -+# CONFIG_PARTITION_ADVANCED is not set -+CONFIG_MSDOS_PARTITION=y -+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 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=y -+CONFIG_NLS_ISO8859_1=y -+# 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=y -+# CONFIG_NLS_KOI8_R is not set -+# CONFIG_NLS_KOI8_U is not set -+CONFIG_NLS_UTF8=y -+# CONFIG_DLM is not set -+# CONFIG_UCC_SLOW is not set -+ -+# -+# Library routines -+# -+CONFIG_BITREVERSE=y -+CONFIG_CRC_CCITT=y -+# CONFIG_CRC16 is not set -+# CONFIG_CRC_ITU_T is not set -+CONFIG_CRC32=y -+# CONFIG_CRC7 is not set -+# CONFIG_LIBCRC32C is not set -+CONFIG_ZLIB_INFLATE=y -+CONFIG_ZLIB_DEFLATE=y -+CONFIG_PLIST=y -+CONFIG_HAS_IOMEM=y -+CONFIG_HAS_IOPORT=y -+CONFIG_HAS_DMA=y -+# CONFIG_INSTRUMENTATION is not set -+ -+# -+# Kernel hacking -+# -+# CONFIG_PRINTK_TIME is not set -+CONFIG_ENABLE_WARN_DEPRECATED=y -+CONFIG_ENABLE_MUST_CHECK=y -+CONFIG_MAGIC_SYSRQ=y -+# CONFIG_UNUSED_SYMBOLS is not set -+# CONFIG_DEBUG_FS is not set -+# CONFIG_HEADERS_CHECK is not set -+CONFIG_DEBUG_KERNEL=y -+# CONFIG_DEBUG_SHIRQ is not set -+CONFIG_DETECT_SOFTLOCKUP=y -+# CONFIG_SCHED_DEBUG is not set -+# CONFIG_SCHEDSTATS is not set -+# CONFIG_TIMER_STATS is not set -+# CONFIG_DEBUG_SLAB is not set -+# CONFIG_DEBUG_RT_MUTEXES is not set -+# CONFIG_RT_MUTEX_TESTER is not set -+# CONFIG_DEBUG_SPINLOCK is not set -+# CONFIG_DEBUG_MUTEXES is not set -+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -+# CONFIG_DEBUG_KOBJECT is not set -+# CONFIG_DEBUG_BUGVERBOSE is not set -+CONFIG_DEBUG_INFO=y -+# CONFIG_DEBUG_VM is not set -+# CONFIG_DEBUG_LIST is not set -+# CONFIG_DEBUG_SG is not set -+CONFIG_FORCED_INLINING=y -+# CONFIG_BOOT_PRINTK_DELAY is not set -+# CONFIG_RCU_TORTURE_TEST is not set -+# CONFIG_FAULT_INJECTION is not set -+# CONFIG_SAMPLES is not set -+# CONFIG_DEBUG_STACKOVERFLOW is not set -+# CONFIG_DEBUG_STACK_USAGE is not set -+# CONFIG_DEBUG_PAGEALLOC is not set -+# CONFIG_DEBUGGER is not set -+CONFIG_BDI_SWITCH=y -+# CONFIG_PPC_EARLY_DEBUG is not set -+ -+# -+# Security options -+# -+# CONFIG_KEYS is not set -+# CONFIG_SECURITY is not set -+# CONFIG_SECURITY_FILE_CAPABILITIES is not set -+# CONFIG_CRYPTO is not set -+# CONFIG_PPC_CLOCK is not set ---- a/arch/powerpc/kernel/Makefile -+++ b/arch/powerpc/kernel/Makefile -@@ -3,7 +3,7 @@ - # - - ifeq ($(CONFIG_PPC64),y) --EXTRA_CFLAGS += -mno-minimal-toc -+CFLAGS_prom_init.o += -mno-minimal-toc - endif - ifeq ($(CONFIG_PPC32),y) - CFLAGS_prom_init.o += -fPIC -@@ -70,6 +70,7 @@ pci64-$(CONFIG_PPC64) += pci_dn.o isa-b - obj-$(CONFIG_PCI) += pci_$(CONFIG_WORD_SIZE).o $(pci64-y) \ - pci-common.o - obj-$(CONFIG_PCI_MSI) += msi.o -+obj-$(CONFIG_RAPIDIO) += rio.o - obj-$(CONFIG_KEXEC) += machine_kexec.o crash.o \ - machine_kexec_$(CONFIG_WORD_SIZE).o - obj-$(CONFIG_AUDIT) += audit.o -@@ -91,3 +92,13 @@ obj-$(CONFIG_PPC64) += $(obj64-y) - - extra-$(CONFIG_PPC_FPU) += fpu.o - extra-$(CONFIG_PPC64) += entry_64.o -+ -+extra-y += systbl_chk.i -+$(obj)/systbl.o: systbl_chk -+ -+quiet_cmd_systbl_chk = CALL $< -+ cmd_systbl_chk = $(CONFIG_SHELL) $< $(obj)/systbl_chk.i -+ -+PHONY += systbl_chk -+systbl_chk: $(src)/systbl_chk.sh $(obj)/systbl_chk.i -+ $(call cmd,systbl_chk) ---- a/arch/powerpc/kernel/btext.c -+++ b/arch/powerpc/kernel/btext.c -@@ -236,7 +236,7 @@ int __init btext_find_display(int allow_ - if (rc == 0 || !allow_nonstdout) - return rc; - -- for (np = NULL; (np = of_find_node_by_type(np, "display"));) { -+ for_each_node_by_type(np, "display") { - if (of_get_property(np, "linux,opened", NULL)) { - printk("trying %s ...\n", np->full_name); - rc = btext_initialize(np); ---- a/arch/powerpc/kernel/cpu_setup_44x.S -+++ b/arch/powerpc/kernel/cpu_setup_44x.S -@@ -23,11 +23,24 @@ _GLOBAL(__setup_cpu_440epx) - mflr r4 - bl __init_fpu_44x - bl __plb_disable_wrp -+ bl __fixup_440A_mcheck - mtlr r4 - blr - _GLOBAL(__setup_cpu_440grx) -- b __plb_disable_wrp -+ mflr r4 -+ bl __plb_disable_wrp -+ bl __fixup_440A_mcheck -+ mtlr r4 -+ blr -+_GLOBAL(__setup_cpu_440gx) -+_GLOBAL(__setup_cpu_440spe) -+ b __fixup_440A_mcheck - -+ /* Temporary fixup for arch/ppc until we kill the whole thing */ -+#ifndef CONFIG_PPC_MERGE -+_GLOBAL(__fixup_440A_mcheck) -+ blr -+#endif - - /* enable APU between CPU and FPU */ - _GLOBAL(__init_fpu_44x) ---- a/arch/powerpc/kernel/cputable.c -+++ b/arch/powerpc/kernel/cputable.c -@@ -33,7 +33,9 @@ EXPORT_SYMBOL(cur_cpu_spec); - #ifdef CONFIG_PPC32 - extern void __setup_cpu_440ep(unsigned long offset, struct cpu_spec* spec); - extern void __setup_cpu_440epx(unsigned long offset, struct cpu_spec* spec); -+extern void __setup_cpu_440gx(unsigned long offset, struct cpu_spec* spec); - extern void __setup_cpu_440grx(unsigned long offset, struct cpu_spec* spec); -+extern void __setup_cpu_440spe(unsigned long offset, struct cpu_spec* spec); - extern void __setup_cpu_603(unsigned long offset, struct cpu_spec* spec); - extern void __setup_cpu_604(unsigned long offset, struct cpu_spec* spec); - extern void __setup_cpu_750(unsigned long offset, struct cpu_spec* spec); -@@ -85,6 +87,7 @@ static struct cpu_spec __initdata cpu_sp - .pmc_type = PPC_PMC_IBM, - .oprofile_cpu_type = "ppc64/power3", - .oprofile_type = PPC_OPROFILE_RS64, -+ .machine_check = machine_check_generic, - .platform = "power3", - }, - { /* Power3+ */ -@@ -99,6 +102,7 @@ static struct cpu_spec __initdata cpu_sp - .pmc_type = PPC_PMC_IBM, - .oprofile_cpu_type = "ppc64/power3", - .oprofile_type = PPC_OPROFILE_RS64, -+ .machine_check = machine_check_generic, - .platform = "power3", - }, - { /* Northstar */ -@@ -113,6 +117,7 @@ static struct cpu_spec __initdata cpu_sp - .pmc_type = PPC_PMC_IBM, - .oprofile_cpu_type = "ppc64/rs64", - .oprofile_type = PPC_OPROFILE_RS64, -+ .machine_check = machine_check_generic, - .platform = "rs64", - }, - { /* Pulsar */ -@@ -127,6 +132,7 @@ static struct cpu_spec __initdata cpu_sp - .pmc_type = PPC_PMC_IBM, - .oprofile_cpu_type = "ppc64/rs64", - .oprofile_type = PPC_OPROFILE_RS64, -+ .machine_check = machine_check_generic, - .platform = "rs64", - }, - { /* I-star */ -@@ -141,6 +147,7 @@ static struct cpu_spec __initdata cpu_sp - .pmc_type = PPC_PMC_IBM, - .oprofile_cpu_type = "ppc64/rs64", - .oprofile_type = PPC_OPROFILE_RS64, -+ .machine_check = machine_check_generic, - .platform = "rs64", - }, - { /* S-star */ -@@ -155,6 +162,7 @@ static struct cpu_spec __initdata cpu_sp - .pmc_type = PPC_PMC_IBM, - .oprofile_cpu_type = "ppc64/rs64", - .oprofile_type = PPC_OPROFILE_RS64, -+ .machine_check = machine_check_generic, - .platform = "rs64", - }, - { /* Power4 */ -@@ -169,6 +177,7 @@ static struct cpu_spec __initdata cpu_sp - .pmc_type = PPC_PMC_IBM, - .oprofile_cpu_type = "ppc64/power4", - .oprofile_type = PPC_OPROFILE_POWER4, -+ .machine_check = machine_check_generic, - .platform = "power4", - }, - { /* Power4+ */ -@@ -183,6 +192,7 @@ static struct cpu_spec __initdata cpu_sp - .pmc_type = PPC_PMC_IBM, - .oprofile_cpu_type = "ppc64/power4", - .oprofile_type = PPC_OPROFILE_POWER4, -+ .machine_check = machine_check_generic, - .platform = "power4", - }, - { /* PPC970 */ -@@ -200,6 +210,7 @@ static struct cpu_spec __initdata cpu_sp - .cpu_restore = __restore_cpu_ppc970, - .oprofile_cpu_type = "ppc64/970", - .oprofile_type = PPC_OPROFILE_POWER4, -+ .machine_check = machine_check_generic, - .platform = "ppc970", - }, - { /* PPC970FX */ -@@ -217,6 +228,7 @@ static struct cpu_spec __initdata cpu_sp - .cpu_restore = __restore_cpu_ppc970, - .oprofile_cpu_type = "ppc64/970", - .oprofile_type = PPC_OPROFILE_POWER4, -+ .machine_check = machine_check_generic, - .platform = "ppc970", - }, - { /* PPC970MP DD1.0 - no DEEPNAP, use regular 970 init */ -@@ -234,6 +246,7 @@ static struct cpu_spec __initdata cpu_sp - .cpu_restore = __restore_cpu_ppc970, - .oprofile_cpu_type = "ppc64/970MP", - .oprofile_type = PPC_OPROFILE_POWER4, -+ .machine_check = machine_check_generic, - .platform = "ppc970", - }, - { /* PPC970MP */ -@@ -251,6 +264,7 @@ static struct cpu_spec __initdata cpu_sp - .cpu_restore = __restore_cpu_ppc970, - .oprofile_cpu_type = "ppc64/970MP", - .oprofile_type = PPC_OPROFILE_POWER4, -+ .machine_check = machine_check_generic, - .platform = "ppc970", - }, - { /* PPC970GX */ -@@ -267,6 +281,7 @@ static struct cpu_spec __initdata cpu_sp - .cpu_setup = __setup_cpu_ppc970, - .oprofile_cpu_type = "ppc64/970", - .oprofile_type = PPC_OPROFILE_POWER4, -+ .machine_check = machine_check_generic, - .platform = "ppc970", - }, - { /* Power5 GR */ -@@ -286,6 +301,7 @@ static struct cpu_spec __initdata cpu_sp - */ - .oprofile_mmcra_sihv = MMCRA_SIHV, - .oprofile_mmcra_sipr = MMCRA_SIPR, -+ .machine_check = machine_check_generic, - .platform = "power5", - }, - { /* Power5++ */ -@@ -301,6 +317,7 @@ static struct cpu_spec __initdata cpu_sp - .oprofile_type = PPC_OPROFILE_POWER4, - .oprofile_mmcra_sihv = MMCRA_SIHV, - .oprofile_mmcra_sipr = MMCRA_SIPR, -+ .machine_check = machine_check_generic, - .platform = "power5+", - }, - { /* Power5 GS */ -@@ -317,6 +334,7 @@ static struct cpu_spec __initdata cpu_sp - .oprofile_type = PPC_OPROFILE_POWER4, - .oprofile_mmcra_sihv = MMCRA_SIHV, - .oprofile_mmcra_sipr = MMCRA_SIPR, -+ .machine_check = machine_check_generic, - .platform = "power5+", - }, - { /* POWER6 in P5+ mode; 2.04-compliant processor */ -@@ -327,6 +345,7 @@ static struct cpu_spec __initdata cpu_sp - .cpu_user_features = COMMON_USER_POWER5_PLUS, - .icache_bsize = 128, - .dcache_bsize = 128, -+ .machine_check = machine_check_generic, - .platform = "power5+", - }, - { /* Power6 */ -@@ -346,6 +365,7 @@ static struct cpu_spec __initdata cpu_sp - .oprofile_mmcra_sipr = POWER6_MMCRA_SIPR, - .oprofile_mmcra_clear = POWER6_MMCRA_THRM | - POWER6_MMCRA_OTHER, -+ .machine_check = machine_check_generic, - .platform = "power6x", - }, - { /* 2.05-compliant processor, i.e. Power6 "architected" mode */ -@@ -356,6 +376,7 @@ static struct cpu_spec __initdata cpu_sp - .cpu_user_features = COMMON_USER_POWER6, - .icache_bsize = 128, - .dcache_bsize = 128, -+ .machine_check = machine_check_generic, - .platform = "power6", - }, - { /* Cell Broadband Engine */ -@@ -372,6 +393,7 @@ static struct cpu_spec __initdata cpu_sp - .pmc_type = PPC_PMC_IBM, - .oprofile_cpu_type = "ppc64/cell-be", - .oprofile_type = PPC_OPROFILE_CELL, -+ .machine_check = machine_check_generic, - .platform = "ppc-cell-be", - }, - { /* PA Semi PA6T */ -@@ -388,6 +410,7 @@ static struct cpu_spec __initdata cpu_sp - .cpu_restore = __restore_cpu_pa6t, - .oprofile_cpu_type = "ppc64/pa6t", - .oprofile_type = PPC_OPROFILE_PA6T, -+ .machine_check = machine_check_generic, - .platform = "pa6t", - }, - { /* default match */ -@@ -400,6 +423,7 @@ static struct cpu_spec __initdata cpu_sp - .dcache_bsize = 128, - .num_pmcs = 6, - .pmc_type = PPC_PMC_IBM, -+ .machine_check = machine_check_generic, - .platform = "power4", - } - #endif /* CONFIG_PPC64 */ -@@ -414,6 +438,7 @@ static struct cpu_spec __initdata cpu_sp - PPC_FEATURE_UNIFIED_CACHE | PPC_FEATURE_NO_TB, - .icache_bsize = 32, - .dcache_bsize = 32, -+ .machine_check = machine_check_generic, - .platform = "ppc601", - }, - { /* 603 */ -@@ -425,6 +450,7 @@ static struct cpu_spec __initdata cpu_sp - .icache_bsize = 32, - .dcache_bsize = 32, - .cpu_setup = __setup_cpu_603, -+ .machine_check = machine_check_generic, - .platform = "ppc603", - }, - { /* 603e */ -@@ -436,6 +462,7 @@ static struct cpu_spec __initdata cpu_sp - .icache_bsize = 32, - .dcache_bsize = 32, - .cpu_setup = __setup_cpu_603, -+ .machine_check = machine_check_generic, - .platform = "ppc603", - }, - { /* 603ev */ -@@ -447,6 +474,7 @@ static struct cpu_spec __initdata cpu_sp - .icache_bsize = 32, - .dcache_bsize = 32, - .cpu_setup = __setup_cpu_603, -+ .machine_check = machine_check_generic, - .platform = "ppc603", - }, - { /* 604 */ -@@ -459,6 +487,7 @@ static struct cpu_spec __initdata cpu_sp - .dcache_bsize = 32, - .num_pmcs = 2, - .cpu_setup = __setup_cpu_604, -+ .machine_check = machine_check_generic, - .platform = "ppc604", - }, - { /* 604e */ -@@ -471,6 +500,7 @@ static struct cpu_spec __initdata cpu_sp - .dcache_bsize = 32, - .num_pmcs = 4, - .cpu_setup = __setup_cpu_604, -+ .machine_check = machine_check_generic, - .platform = "ppc604", - }, - { /* 604r */ -@@ -483,6 +513,7 @@ static struct cpu_spec __initdata cpu_sp - .dcache_bsize = 32, - .num_pmcs = 4, - .cpu_setup = __setup_cpu_604, -+ .machine_check = machine_check_generic, - .platform = "ppc604", - }, - { /* 604ev */ -@@ -495,6 +526,7 @@ static struct cpu_spec __initdata cpu_sp - .dcache_bsize = 32, - .num_pmcs = 4, - .cpu_setup = __setup_cpu_604, -+ .machine_check = machine_check_generic, - .platform = "ppc604", - }, - { /* 740/750 (0x4202, don't support TAU ?) */ -@@ -507,6 +539,7 @@ static struct cpu_spec __initdata cpu_sp - .dcache_bsize = 32, - .num_pmcs = 4, - .cpu_setup = __setup_cpu_750, -+ .machine_check = machine_check_generic, - .platform = "ppc750", - }, - { /* 750CX (80100 and 8010x?) */ -@@ -519,6 +552,7 @@ static struct cpu_spec __initdata cpu_sp - .dcache_bsize = 32, - .num_pmcs = 4, - .cpu_setup = __setup_cpu_750cx, -+ .machine_check = machine_check_generic, - .platform = "ppc750", - }, - { /* 750CX (82201 and 82202) */ -@@ -531,6 +565,7 @@ static struct cpu_spec __initdata cpu_sp - .dcache_bsize = 32, - .num_pmcs = 4, - .cpu_setup = __setup_cpu_750cx, -+ .machine_check = machine_check_generic, - .platform = "ppc750", - }, - { /* 750CXe (82214) */ -@@ -543,6 +578,7 @@ static struct cpu_spec __initdata cpu_sp - .dcache_bsize = 32, - .num_pmcs = 4, - .cpu_setup = __setup_cpu_750cx, -+ .machine_check = machine_check_generic, - .platform = "ppc750", - }, - { /* 750CXe "Gekko" (83214) */ -@@ -555,6 +591,7 @@ static struct cpu_spec __initdata cpu_sp - .dcache_bsize = 32, - .num_pmcs = 4, - .cpu_setup = __setup_cpu_750cx, -+ .machine_check = machine_check_generic, - .platform = "ppc750", - }, - { /* 750CL */ -@@ -567,6 +604,7 @@ static struct cpu_spec __initdata cpu_sp - .dcache_bsize = 32, - .num_pmcs = 4, - .cpu_setup = __setup_cpu_750, -+ .machine_check = machine_check_generic, - .platform = "ppc750", - }, - { /* 745/755 */ -@@ -579,6 +617,7 @@ static struct cpu_spec __initdata cpu_sp - .dcache_bsize = 32, - .num_pmcs = 4, - .cpu_setup = __setup_cpu_750, -+ .machine_check = machine_check_generic, - .platform = "ppc750", - }, - { /* 750FX rev 1.x */ -@@ -591,6 +630,7 @@ static struct cpu_spec __initdata cpu_sp - .dcache_bsize = 32, - .num_pmcs = 4, - .cpu_setup = __setup_cpu_750, -+ .machine_check = machine_check_generic, - .platform = "ppc750", - }, - { /* 750FX rev 2.0 must disable HID0[DPM] */ -@@ -603,6 +643,7 @@ static struct cpu_spec __initdata cpu_sp - .dcache_bsize = 32, - .num_pmcs = 4, - .cpu_setup = __setup_cpu_750, -+ .machine_check = machine_check_generic, - .platform = "ppc750", - }, - { /* 750FX (All revs except 2.0) */ -@@ -615,6 +656,7 @@ static struct cpu_spec __initdata cpu_sp - .dcache_bsize = 32, - .num_pmcs = 4, - .cpu_setup = __setup_cpu_750fx, -+ .machine_check = machine_check_generic, - .platform = "ppc750", - }, - { /* 750GX */ -@@ -627,6 +669,7 @@ static struct cpu_spec __initdata cpu_sp - .dcache_bsize = 32, - .num_pmcs = 4, - .cpu_setup = __setup_cpu_750fx, -+ .machine_check = machine_check_generic, - .platform = "ppc750", - }, - { /* 740/750 (L2CR bit need fixup for 740) */ -@@ -639,6 +682,7 @@ static struct cpu_spec __initdata cpu_sp - .dcache_bsize = 32, - .num_pmcs = 4, - .cpu_setup = __setup_cpu_750, -+ .machine_check = machine_check_generic, - .platform = "ppc750", - }, - { /* 7400 rev 1.1 ? (no TAU) */ -@@ -652,6 +696,7 @@ static struct cpu_spec __initdata cpu_sp - .dcache_bsize = 32, - .num_pmcs = 4, - .cpu_setup = __setup_cpu_7400, -+ .machine_check = machine_check_generic, - .platform = "ppc7400", - }, - { /* 7400 */ -@@ -665,6 +710,7 @@ static struct cpu_spec __initdata cpu_sp - .dcache_bsize = 32, - .num_pmcs = 4, - .cpu_setup = __setup_cpu_7400, -+ .machine_check = machine_check_generic, - .platform = "ppc7400", - }, - { /* 7410 */ -@@ -678,6 +724,7 @@ static struct cpu_spec __initdata cpu_sp - .dcache_bsize = 32, - .num_pmcs = 4, - .cpu_setup = __setup_cpu_7410, -+ .machine_check = machine_check_generic, - .platform = "ppc7400", - }, - { /* 7450 2.0 - no doze/nap */ -@@ -693,6 +740,7 @@ static struct cpu_spec __initdata cpu_sp - .cpu_setup = __setup_cpu_745x, - .oprofile_cpu_type = "ppc/7450", - .oprofile_type = PPC_OPROFILE_G4, -+ .machine_check = machine_check_generic, - .platform = "ppc7450", - }, - { /* 7450 2.1 */ -@@ -708,6 +756,7 @@ static struct cpu_spec __initdata cpu_sp - .cpu_setup = __setup_cpu_745x, - .oprofile_cpu_type = "ppc/7450", - .oprofile_type = PPC_OPROFILE_G4, -+ .machine_check = machine_check_generic, - .platform = "ppc7450", - }, - { /* 7450 2.3 and newer */ -@@ -723,6 +772,7 @@ static struct cpu_spec __initdata cpu_sp - .cpu_setup = __setup_cpu_745x, - .oprofile_cpu_type = "ppc/7450", - .oprofile_type = PPC_OPROFILE_G4, -+ .machine_check = machine_check_generic, - .platform = "ppc7450", - }, - { /* 7455 rev 1.x */ -@@ -738,6 +788,7 @@ static struct cpu_spec __initdata cpu_sp - .cpu_setup = __setup_cpu_745x, - .oprofile_cpu_type = "ppc/7450", - .oprofile_type = PPC_OPROFILE_G4, -+ .machine_check = machine_check_generic, - .platform = "ppc7450", - }, - { /* 7455 rev 2.0 */ -@@ -753,6 +804,7 @@ static struct cpu_spec __initdata cpu_sp - .cpu_setup = __setup_cpu_745x, - .oprofile_cpu_type = "ppc/7450", - .oprofile_type = PPC_OPROFILE_G4, -+ .machine_check = machine_check_generic, - .platform = "ppc7450", - }, - { /* 7455 others */ -@@ -768,6 +820,7 @@ static struct cpu_spec __initdata cpu_sp - .cpu_setup = __setup_cpu_745x, - .oprofile_cpu_type = "ppc/7450", - .oprofile_type = PPC_OPROFILE_G4, -+ .machine_check = machine_check_generic, - .platform = "ppc7450", - }, - { /* 7447/7457 Rev 1.0 */ -@@ -783,6 +836,7 @@ static struct cpu_spec __initdata cpu_sp - .cpu_setup = __setup_cpu_745x, - .oprofile_cpu_type = "ppc/7450", - .oprofile_type = PPC_OPROFILE_G4, -+ .machine_check = machine_check_generic, - .platform = "ppc7450", - }, - { /* 7447/7457 Rev 1.1 */ -@@ -798,6 +852,7 @@ static struct cpu_spec __initdata cpu_sp - .cpu_setup = __setup_cpu_745x, - .oprofile_cpu_type = "ppc/7450", - .oprofile_type = PPC_OPROFILE_G4, -+ .machine_check = machine_check_generic, - .platform = "ppc7450", - }, - { /* 7447/7457 Rev 1.2 and later */ -@@ -812,6 +867,7 @@ static struct cpu_spec __initdata cpu_sp - .cpu_setup = __setup_cpu_745x, - .oprofile_cpu_type = "ppc/7450", - .oprofile_type = PPC_OPROFILE_G4, -+ .machine_check = machine_check_generic, - .platform = "ppc7450", - }, - { /* 7447A */ -@@ -827,6 +883,7 @@ static struct cpu_spec __initdata cpu_sp - .cpu_setup = __setup_cpu_745x, - .oprofile_cpu_type = "ppc/7450", - .oprofile_type = PPC_OPROFILE_G4, -+ .machine_check = machine_check_generic, - .platform = "ppc7450", - }, - { /* 7448 */ -@@ -842,6 +899,7 @@ static struct cpu_spec __initdata cpu_sp - .cpu_setup = __setup_cpu_745x, - .oprofile_cpu_type = "ppc/7450", - .oprofile_type = PPC_OPROFILE_G4, -+ .machine_check = machine_check_generic, - .platform = "ppc7450", - }, - { /* 82xx (8240, 8245, 8260 are all 603e cores) */ -@@ -853,6 +911,7 @@ static struct cpu_spec __initdata cpu_sp - .icache_bsize = 32, - .dcache_bsize = 32, - .cpu_setup = __setup_cpu_603, -+ .machine_check = machine_check_generic, - .platform = "ppc603", - }, - { /* All G2_LE (603e core, plus some) have the same pvr */ -@@ -864,6 +923,7 @@ static struct cpu_spec __initdata cpu_sp - .icache_bsize = 32, - .dcache_bsize = 32, - .cpu_setup = __setup_cpu_603, -+ .machine_check = machine_check_generic, - .platform = "ppc603", - }, - { /* e300c1 (a 603e core, plus some) on 83xx */ -@@ -875,6 +935,7 @@ static struct cpu_spec __initdata cpu_sp - .icache_bsize = 32, - .dcache_bsize = 32, - .cpu_setup = __setup_cpu_603, -+ .machine_check = machine_check_generic, - .platform = "ppc603", - }, - { /* e300c2 (an e300c1 core, plus some, minus FPU) on 83xx */ -@@ -886,9 +947,10 @@ static struct cpu_spec __initdata cpu_sp - .icache_bsize = 32, - .dcache_bsize = 32, - .cpu_setup = __setup_cpu_603, -+ .machine_check = machine_check_generic, - .platform = "ppc603", - }, -- { /* e300c3 on 83xx */ -+ { /* e300c3 (e300c1, plus one IU, half cache size) on 83xx */ - .pvr_mask = 0x7fff0000, - .pvr_value = 0x00850000, - .cpu_name = "e300c3", -@@ -899,6 +961,18 @@ static struct cpu_spec __initdata cpu_sp - .cpu_setup = __setup_cpu_603, - .platform = "ppc603", - }, -+ { /* e300c4 (e300c1, plus one IU) */ -+ .pvr_mask = 0x7fff0000, -+ .pvr_value = 0x00860000, -+ .cpu_name = "e300c4", -+ .cpu_features = CPU_FTRS_E300, -+ .cpu_user_features = COMMON_USER, -+ .icache_bsize = 32, -+ .dcache_bsize = 32, -+ .cpu_setup = __setup_cpu_603, -+ .machine_check = machine_check_generic, -+ .platform = "ppc603", -+ }, - { /* default match, we assume split I/D cache & TB (non-601)... */ - .pvr_mask = 0x00000000, - .pvr_value = 0x00000000, -@@ -907,6 +981,7 @@ static struct cpu_spec __initdata cpu_sp - .cpu_user_features = COMMON_USER, - .icache_bsize = 32, - .dcache_bsize = 32, -+ .machine_check = machine_check_generic, - .platform = "ppc603", - }, - #endif /* CLASSIC_PPC */ -@@ -933,6 +1008,7 @@ static struct cpu_spec __initdata cpu_sp - .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, - .icache_bsize = 16, - .dcache_bsize = 16, -+ .machine_check = machine_check_4xx, - .platform = "ppc403", - }, - { /* 403GCX */ -@@ -944,6 +1020,7 @@ static struct cpu_spec __initdata cpu_sp - PPC_FEATURE_HAS_MMU | PPC_FEATURE_NO_TB, - .icache_bsize = 16, - .dcache_bsize = 16, -+ .machine_check = machine_check_4xx, - .platform = "ppc403", - }, - { /* 403G ?? */ -@@ -954,6 +1031,7 @@ static struct cpu_spec __initdata cpu_sp - .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, - .icache_bsize = 16, - .dcache_bsize = 16, -+ .machine_check = machine_check_4xx, - .platform = "ppc403", - }, - { /* 405GP */ -@@ -965,6 +1043,7 @@ static struct cpu_spec __initdata cpu_sp - PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, - .icache_bsize = 32, - .dcache_bsize = 32, -+ .machine_check = machine_check_4xx, - .platform = "ppc405", - }, - { /* STB 03xxx */ -@@ -976,6 +1055,7 @@ static struct cpu_spec __initdata cpu_sp - PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, - .icache_bsize = 32, - .dcache_bsize = 32, -+ .machine_check = machine_check_4xx, - .platform = "ppc405", - }, - { /* STB 04xxx */ -@@ -987,6 +1067,7 @@ static struct cpu_spec __initdata cpu_sp - PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, - .icache_bsize = 32, - .dcache_bsize = 32, -+ .machine_check = machine_check_4xx, - .platform = "ppc405", - }, - { /* NP405L */ -@@ -998,6 +1079,7 @@ static struct cpu_spec __initdata cpu_sp - PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, - .icache_bsize = 32, - .dcache_bsize = 32, -+ .machine_check = machine_check_4xx, - .platform = "ppc405", - }, - { /* NP4GS3 */ -@@ -1009,6 +1091,7 @@ static struct cpu_spec __initdata cpu_sp - PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, - .icache_bsize = 32, - .dcache_bsize = 32, -+ .machine_check = machine_check_4xx, - .platform = "ppc405", - }, - { /* NP405H */ -@@ -1020,6 +1103,7 @@ static struct cpu_spec __initdata cpu_sp - PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, - .icache_bsize = 32, - .dcache_bsize = 32, -+ .machine_check = machine_check_4xx, - .platform = "ppc405", - }, - { /* 405GPr */ -@@ -1031,6 +1115,7 @@ static struct cpu_spec __initdata cpu_sp - PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, - .icache_bsize = 32, - .dcache_bsize = 32, -+ .machine_check = machine_check_4xx, - .platform = "ppc405", - }, - { /* STBx25xx */ -@@ -1042,6 +1127,7 @@ static struct cpu_spec __initdata cpu_sp - PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, - .icache_bsize = 32, - .dcache_bsize = 32, -+ .machine_check = machine_check_4xx, - .platform = "ppc405", - }, - { /* 405LP */ -@@ -1052,6 +1138,7 @@ static struct cpu_spec __initdata cpu_sp - .cpu_user_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU, - .icache_bsize = 32, - .dcache_bsize = 32, -+ .machine_check = machine_check_4xx, - .platform = "ppc405", - }, - { /* Xilinx Virtex-II Pro */ -@@ -1063,6 +1150,7 @@ static struct cpu_spec __initdata cpu_sp - PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, - .icache_bsize = 32, - .dcache_bsize = 32, -+ .machine_check = machine_check_4xx, - .platform = "ppc405", - }, - { /* Xilinx Virtex-4 FX */ -@@ -1074,6 +1162,7 @@ static struct cpu_spec __initdata cpu_sp - PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, - .icache_bsize = 32, - .dcache_bsize = 32, -+ .machine_check = machine_check_4xx, - .platform = "ppc405", - }, - { /* 405EP */ -@@ -1085,17 +1174,31 @@ static struct cpu_spec __initdata cpu_sp - PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, - .icache_bsize = 32, - .dcache_bsize = 32, -+ .machine_check = machine_check_4xx, - .platform = "ppc405", - }, - { /* 405EX */ -- .pvr_mask = 0xffff0000, -- .pvr_value = 0x12910000, -+ .pvr_mask = 0xffff0004, -+ .pvr_value = 0x12910004, - .cpu_name = "405EX", - .cpu_features = CPU_FTRS_40X, - .cpu_user_features = PPC_FEATURE_32 | - PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, - .icache_bsize = 32, - .dcache_bsize = 32, -+ .machine_check = machine_check_4xx, -+ .platform = "ppc405", -+ }, -+ { /* 405EXr */ -+ .pvr_mask = 0xffff0004, -+ .pvr_value = 0x12910000, -+ .cpu_name = "405EXr", -+ .cpu_features = CPU_FTRS_40X, -+ .cpu_user_features = PPC_FEATURE_32 | -+ PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, -+ .icache_bsize = 32, -+ .dcache_bsize = 32, -+ .machine_check = machine_check_4xx, - .platform = "ppc405", - }, - -@@ -1109,6 +1212,7 @@ static struct cpu_spec __initdata cpu_sp - .cpu_user_features = COMMON_USER_BOOKE, - .icache_bsize = 32, - .dcache_bsize = 32, -+ .machine_check = machine_check_4xx, - .platform = "ppc440", - }, - { /* Use logical PVR for 440EP (logical pvr = pvr | 0x8) */ -@@ -1120,6 +1224,7 @@ static struct cpu_spec __initdata cpu_sp - .icache_bsize = 32, - .dcache_bsize = 32, - .cpu_setup = __setup_cpu_440ep, -+ .machine_check = machine_check_4xx, - .platform = "ppc440", - }, - { -@@ -1130,6 +1235,19 @@ static struct cpu_spec __initdata cpu_sp - .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU, - .icache_bsize = 32, - .dcache_bsize = 32, -+ .machine_check = machine_check_4xx, -+ .platform = "ppc440", -+ }, -+ { /* Matches both physical and logical PVR for 440EP (logical pvr = pvr | 0x8) */ -+ .pvr_mask = 0xf0000ff7, -+ .pvr_value = 0x400008d4, -+ .cpu_name = "440EP Rev. C", -+ .cpu_features = CPU_FTRS_44X, -+ .cpu_user_features = COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU, -+ .icache_bsize = 32, -+ .dcache_bsize = 32, -+ .cpu_setup = __setup_cpu_440ep, -+ .machine_check = machine_check_4xx, - .platform = "ppc440", - }, - { /* Use logical PVR for 440EP (logical pvr = pvr | 0x8) */ -@@ -1141,6 +1259,7 @@ static struct cpu_spec __initdata cpu_sp - .icache_bsize = 32, - .dcache_bsize = 32, - .cpu_setup = __setup_cpu_440ep, -+ .machine_check = machine_check_4xx, - .platform = "ppc440", - }, - { /* 440GRX */ -@@ -1152,6 +1271,7 @@ static struct cpu_spec __initdata cpu_sp - .icache_bsize = 32, - .dcache_bsize = 32, - .cpu_setup = __setup_cpu_440grx, -+ .machine_check = machine_check_440A, - .platform = "ppc440", - }, - { /* Use logical PVR for 440EPx (logical pvr = pvr | 0x8) */ -@@ -1163,6 +1283,7 @@ static struct cpu_spec __initdata cpu_sp - .icache_bsize = 32, - .dcache_bsize = 32, - .cpu_setup = __setup_cpu_440epx, -+ .machine_check = machine_check_440A, - .platform = "ppc440", - }, - { /* 440GP Rev. B */ -@@ -1173,6 +1294,7 @@ static struct cpu_spec __initdata cpu_sp - .cpu_user_features = COMMON_USER_BOOKE, - .icache_bsize = 32, - .dcache_bsize = 32, -+ .machine_check = machine_check_4xx, - .platform = "ppc440gp", - }, - { /* 440GP Rev. C */ -@@ -1183,6 +1305,7 @@ static struct cpu_spec __initdata cpu_sp - .cpu_user_features = COMMON_USER_BOOKE, - .icache_bsize = 32, - .dcache_bsize = 32, -+ .machine_check = machine_check_4xx, - .platform = "ppc440gp", - }, - { /* 440GX Rev. A */ -@@ -1193,6 +1316,8 @@ static struct cpu_spec __initdata cpu_sp - .cpu_user_features = COMMON_USER_BOOKE, - .icache_bsize = 32, - .dcache_bsize = 32, -+ .cpu_setup = __setup_cpu_440gx, -+ .machine_check = machine_check_440A, - .platform = "ppc440", - }, - { /* 440GX Rev. B */ -@@ -1203,6 +1328,8 @@ static struct cpu_spec __initdata cpu_sp - .cpu_user_features = COMMON_USER_BOOKE, - .icache_bsize = 32, - .dcache_bsize = 32, -+ .cpu_setup = __setup_cpu_440gx, -+ .machine_check = machine_check_440A, - .platform = "ppc440", - }, - { /* 440GX Rev. C */ -@@ -1213,6 +1340,8 @@ static struct cpu_spec __initdata cpu_sp - .cpu_user_features = COMMON_USER_BOOKE, - .icache_bsize = 32, - .dcache_bsize = 32, -+ .cpu_setup = __setup_cpu_440gx, -+ .machine_check = machine_check_440A, - .platform = "ppc440", - }, - { /* 440GX Rev. F */ -@@ -1223,6 +1352,8 @@ static struct cpu_spec __initdata cpu_sp - .cpu_user_features = COMMON_USER_BOOKE, - .icache_bsize = 32, - .dcache_bsize = 32, -+ .cpu_setup = __setup_cpu_440gx, -+ .machine_check = machine_check_440A, - .platform = "ppc440", - }, - { /* 440SP Rev. A */ -@@ -1233,6 +1364,7 @@ static struct cpu_spec __initdata cpu_sp - .cpu_user_features = COMMON_USER_BOOKE, - .icache_bsize = 32, - .dcache_bsize = 32, -+ .machine_check = machine_check_4xx, - .platform = "ppc440", - }, - { /* 440SPe Rev. A */ -@@ -1243,6 +1375,8 @@ static struct cpu_spec __initdata cpu_sp - .cpu_user_features = COMMON_USER_BOOKE, - .icache_bsize = 32, - .dcache_bsize = 32, -+ .cpu_setup = __setup_cpu_440spe, -+ .machine_check = machine_check_440A, - .platform = "ppc440", - }, - { /* 440SPe Rev. B */ -@@ -1253,10 +1387,13 @@ static struct cpu_spec __initdata cpu_sp - .cpu_user_features = COMMON_USER_BOOKE, - .icache_bsize = 32, - .dcache_bsize = 32, -+ .cpu_setup = __setup_cpu_440spe, -+ .machine_check = machine_check_440A, - .platform = "ppc440", - }, - #endif /* CONFIG_44x */ - #ifdef CONFIG_FSL_BOOKE -+#ifdef CONFIG_E200 - { /* e200z5 */ - .pvr_mask = 0xfff00000, - .pvr_value = 0x81000000, -@@ -1267,6 +1404,7 @@ static struct cpu_spec __initdata cpu_sp - PPC_FEATURE_HAS_EFP_SINGLE | - PPC_FEATURE_UNIFIED_CACHE, - .dcache_bsize = 32, -+ .machine_check = machine_check_e200, - .platform = "ppc5554", - }, - { /* e200z6 */ -@@ -1280,8 +1418,10 @@ static struct cpu_spec __initdata cpu_sp - PPC_FEATURE_HAS_EFP_SINGLE_COMP | - PPC_FEATURE_UNIFIED_CACHE, - .dcache_bsize = 32, -+ .machine_check = machine_check_e200, - .platform = "ppc5554", - }, -+#elif defined(CONFIG_E500) - { /* e500 */ - .pvr_mask = 0xffff0000, - .pvr_value = 0x80200000, -@@ -1296,6 +1436,7 @@ static struct cpu_spec __initdata cpu_sp - .num_pmcs = 4, - .oprofile_cpu_type = "ppc/e500", - .oprofile_type = PPC_OPROFILE_BOOKE, -+ .machine_check = machine_check_e500, - .platform = "ppc8540", - }, - { /* e500v2 */ -@@ -1313,9 +1454,11 @@ static struct cpu_spec __initdata cpu_sp - .num_pmcs = 4, - .oprofile_cpu_type = "ppc/e500", - .oprofile_type = PPC_OPROFILE_BOOKE, -+ .machine_check = machine_check_e500, - .platform = "ppc8548", - }, - #endif -+#endif - #if !CLASSIC_PPC - { /* default match */ - .pvr_mask = 0x00000000, ---- a/arch/powerpc/kernel/crash.c -+++ b/arch/powerpc/kernel/crash.c -@@ -32,6 +32,8 @@ - #include - #include - #include -+#include -+#include - - #ifdef DEBUG - #include -@@ -45,6 +47,11 @@ int crashing_cpu = -1; - static cpumask_t cpus_in_crash = CPU_MASK_NONE; - cpumask_t cpus_in_sr = CPU_MASK_NONE; - -+#define CRASH_HANDLER_MAX 1 -+/* NULL terminated list of shutdown handles */ -+static crash_shutdown_t crash_shutdown_handles[CRASH_HANDLER_MAX+1]; -+static DEFINE_SPINLOCK(crash_handlers_lock); -+ - #ifdef CONFIG_SMP - static atomic_t enter_on_soft_reset = ATOMIC_INIT(0); - -@@ -285,9 +292,72 @@ static inline void crash_kexec_stop_spus - } - #endif /* CONFIG_SPU_BASE */ - -+/* -+ * Register a function to be called on shutdown. Only use this if you -+ * can't reset your device in the second kernel. -+ */ -+int crash_shutdown_register(crash_shutdown_t handler) -+{ -+ unsigned int i, rc; -+ -+ spin_lock(&crash_handlers_lock); -+ for (i = 0 ; i < CRASH_HANDLER_MAX; i++) -+ if (!crash_shutdown_handles[i]) { -+ /* Insert handle at first empty entry */ -+ crash_shutdown_handles[i] = handler; -+ rc = 0; -+ break; -+ } -+ -+ if (i == CRASH_HANDLER_MAX) { -+ printk(KERN_ERR "Crash shutdown handles full, " -+ "not registered.\n"); -+ rc = 1; -+ } -+ -+ spin_unlock(&crash_handlers_lock); -+ return rc; -+} -+EXPORT_SYMBOL(crash_shutdown_register); -+ -+int crash_shutdown_unregister(crash_shutdown_t handler) -+{ -+ unsigned int i, rc; -+ -+ spin_lock(&crash_handlers_lock); -+ for (i = 0 ; i < CRASH_HANDLER_MAX; i++) -+ if (crash_shutdown_handles[i] == handler) -+ break; -+ -+ if (i == CRASH_HANDLER_MAX) { -+ printk(KERN_ERR "Crash shutdown handle not found\n"); -+ rc = 1; -+ } else { -+ /* Shift handles down */ -+ for (; crash_shutdown_handles[i]; i++) -+ crash_shutdown_handles[i] = -+ crash_shutdown_handles[i+1]; -+ rc = 0; -+ } -+ -+ spin_unlock(&crash_handlers_lock); -+ return rc; -+} -+EXPORT_SYMBOL(crash_shutdown_unregister); -+ -+static unsigned long crash_shutdown_buf[JMP_BUF_LEN]; -+ -+static int handle_fault(struct pt_regs *regs) -+{ -+ longjmp(crash_shutdown_buf, 1); -+ return 0; -+} -+ - void default_machine_crash_shutdown(struct pt_regs *regs) - { -- unsigned int irq; -+ unsigned int i; -+ int (*old_handler)(struct pt_regs *regs); -+ - - /* - * This function is only called after the system -@@ -301,15 +371,36 @@ void default_machine_crash_shutdown(stru - */ - hard_irq_disable(); - -- for_each_irq(irq) { -- struct irq_desc *desc = irq_desc + irq; -+ for_each_irq(i) { -+ struct irq_desc *desc = irq_desc + i; - - if (desc->status & IRQ_INPROGRESS) -- desc->chip->eoi(irq); -+ desc->chip->eoi(i); - - if (!(desc->status & IRQ_DISABLED)) -- desc->chip->disable(irq); -+ desc->chip->disable(i); -+ } -+ -+ /* -+ * Call registered shutdown routines savely. Swap out -+ * __debugger_fault_handler, and replace on exit. -+ */ -+ old_handler = __debugger_fault_handler; -+ __debugger_fault_handler = handle_fault; -+ for (i = 0; crash_shutdown_handles[i]; i++) { -+ if (setjmp(crash_shutdown_buf) == 0) { -+ /* -+ * Insert syncs and delay to ensure -+ * instructions in the dangerous region don't -+ * leak away from this protected region. -+ */ -+ asm volatile("sync; isync"); -+ /* dangerous region */ -+ crash_shutdown_handles[i](); -+ asm volatile("sync; isync"); -+ } - } -+ __debugger_fault_handler = old_handler; - - /* - * Make a note of crashing cpu. Will be used in machine_kexec ---- a/arch/powerpc/kernel/dma_64.c -+++ b/arch/powerpc/kernel/dma_64.c -@@ -112,10 +112,16 @@ EXPORT_SYMBOL(dma_iommu_ops); - /* - * Generic direct DMA implementation - * -- * This implementation supports a global offset that can be applied if -- * the address at which memory is visible to devices is not 0. -+ * This implementation supports a per-device offset that can be applied if -+ * the address at which memory is visible to devices is not 0. Platform code -+ * can set archdata.dma_data to an unsigned long holding the offset. By -+ * default the offset is zero. - */ --unsigned long dma_direct_offset; -+ -+static unsigned long get_dma_direct_offset(struct device *dev) -+{ -+ return (unsigned long)dev->archdata.dma_data; -+} - - static void *dma_direct_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t flag) -@@ -124,13 +130,12 @@ static void *dma_direct_alloc_coherent(s - void *ret; - int node = dev->archdata.numa_node; - -- /* TODO: Maybe use the numa node here too ? */ - page = alloc_pages_node(node, flag, get_order(size)); - if (page == NULL) - return NULL; - ret = page_address(page); - memset(ret, 0, size); -- *dma_handle = virt_to_abs(ret) | dma_direct_offset; -+ *dma_handle = virt_to_abs(ret) + get_dma_direct_offset(dev); - - return ret; - } -@@ -145,7 +150,7 @@ static dma_addr_t dma_direct_map_single( - size_t size, - enum dma_data_direction direction) - { -- return virt_to_abs(ptr) | dma_direct_offset; -+ return virt_to_abs(ptr) + get_dma_direct_offset(dev); - } - - static void dma_direct_unmap_single(struct device *dev, dma_addr_t dma_addr, -@@ -161,7 +166,7 @@ static int dma_direct_map_sg(struct devi - int i; - - for_each_sg(sgl, sg, nents, i) { -- sg->dma_address = sg_phys(sg) | dma_direct_offset; -+ sg->dma_address = sg_phys(sg) + get_dma_direct_offset(dev); - sg->dma_length = sg->length; - } - ---- a/arch/powerpc/kernel/head_44x.S -+++ b/arch/powerpc/kernel/head_44x.S -@@ -289,11 +289,8 @@ interrupt_base: - CRITICAL_EXCEPTION(0x0100, CriticalInput, unknown_exception) - - /* Machine Check Interrupt */ --#ifdef CONFIG_440A -- MCHECK_EXCEPTION(0x0200, MachineCheck, machine_check_exception) --#else - CRITICAL_EXCEPTION(0x0200, MachineCheck, machine_check_exception) --#endif -+ MCHECK_EXCEPTION(0x0210, MachineCheckA, machine_check_exception) - - /* Data Storage Interrupt */ - START_EXCEPTION(DataStorage) -@@ -674,6 +671,15 @@ finish_tlb_load: - */ - - /* -+ * Adjust the machine check IVOR on 440A cores -+ */ -+_GLOBAL(__fixup_440A_mcheck) -+ li r3,MachineCheckA@l -+ mtspr SPRN_IVOR1,r3 -+ sync -+ blr -+ -+/* - * extern void giveup_altivec(struct task_struct *prev) - * - * The 44x core does not have an AltiVec unit. ---- a/arch/powerpc/kernel/head_booke.h -+++ b/arch/powerpc/kernel/head_booke.h -@@ -166,7 +166,7 @@ label: - mfspr r5,SPRN_ESR; \ - stw r5,_ESR(r11); \ - addi r3,r1,STACK_FRAME_OVERHEAD; \ -- EXC_XFER_TEMPLATE(hdlr, n+2, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \ -+ EXC_XFER_TEMPLATE(hdlr, n+4, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \ - NOCOPY, mcheck_transfer_to_handler, \ - ret_from_mcheck_exc) - ---- a/arch/powerpc/kernel/head_fsl_booke.S -+++ b/arch/powerpc/kernel/head_fsl_booke.S -@@ -73,8 +73,8 @@ _ENTRY(_start); - /* We try to not make any assumptions about how the boot loader - * setup or used the TLBs. We invalidate all mappings from the - * boot loader and load a single entry in TLB1[0] to map the -- * first 16M of kernel memory. Any boot info passed from the -- * bootloader needs to live in this first 16M. -+ * first 64M of kernel memory. Any boot info passed from the -+ * bootloader needs to live in this first 64M. - * - * Requirement on bootloader: - * - The page we're executing in needs to reside in TLB1 and -@@ -167,7 +167,7 @@ skpinv: addi r6,r6,1 /* Increment */ - mtspr SPRN_MAS0,r7 - tlbre - -- /* Just modify the entry ID and EPN for the temp mapping */ -+ /* Just modify the entry ID, EPN and RPN for the temp mapping */ - lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */ - rlwimi r7,r5,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r5) */ - mtspr SPRN_MAS0,r7 -@@ -177,9 +177,12 @@ skpinv: addi r6,r6,1 /* Increment */ - ori r6,r6,(MAS1_TSIZE(BOOKE_PAGESZ_4K))@l - mtspr SPRN_MAS1,r6 - mfspr r6,SPRN_MAS2 -- li r7,0 /* temp EPN = 0 */ -+ lis r7,PHYSICAL_START@h - rlwimi r7,r6,0,20,31 - mtspr SPRN_MAS2,r7 -+ mfspr r6,SPRN_MAS3 -+ rlwimi r7,r6,0,20,31 -+ mtspr SPRN_MAS3,r7 - tlbwe - - xori r6,r4,1 -@@ -222,11 +225,11 @@ skpinv: addi r6,r6,1 /* Increment */ - lis r6,0x1000 /* Set MAS0(TLBSEL) = TLB1(1), ESEL = 0 */ - mtspr SPRN_MAS0,r6 - lis r6,(MAS1_VALID|MAS1_IPROT)@h -- ori r6,r6,(MAS1_TSIZE(BOOKE_PAGESZ_16M))@l -+ ori r6,r6,(MAS1_TSIZE(BOOKE_PAGESZ_64M))@l - mtspr SPRN_MAS1,r6 - li r7,0 -- lis r6,KERNELBASE@h -- ori r6,r6,KERNELBASE@l -+ lis r6,PAGE_OFFSET@h -+ ori r6,r6,PAGE_OFFSET@l - rlwimi r6,r7,0,20,31 - mtspr SPRN_MAS2,r6 - li r7,(MAS3_SX|MAS3_SW|MAS3_SR) -@@ -234,6 +237,9 @@ skpinv: addi r6,r6,1 /* Increment */ - tlbwe - - /* 7. Jump to KERNELBASE mapping */ -+ lis r6,KERNELBASE@h -+ ori r6,r6,KERNELBASE@l -+ rlwimi r6,r7,0,20,31 - lis r7,MSR_KERNEL@h - ori r7,r7,MSR_KERNEL@l - bl 1f /* Find our address */ ---- a/arch/powerpc/kernel/ibmebus.c -+++ b/arch/powerpc/kernel/ibmebus.c -@@ -41,6 +41,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -52,7 +53,7 @@ static struct device ibmebus_bus_device - struct bus_type ibmebus_bus_type; - - /* These devices will automatically be added to the bus during init */ --static struct of_device_id builtin_matches[] = { -+static struct of_device_id __initdata builtin_matches[] = { - { .compatible = "IBM,lhca" }, - { .compatible = "IBM,lhea" }, - {}, -@@ -171,7 +172,7 @@ static int ibmebus_create_devices(const - - root = of_find_node_by_path("/"); - -- for (child = NULL; (child = of_get_next_child(root, child)); ) { -+ for_each_child_of_node(root, child) { - if (!of_match_node(matches, child)) - continue; - -@@ -197,16 +198,13 @@ int ibmebus_register_driver(struct of_pl - /* If the driver uses devices that ibmebus doesn't know, add them */ - ibmebus_create_devices(drv->match_table); - -- drv->driver.name = drv->name; -- drv->driver.bus = &ibmebus_bus_type; -- -- return driver_register(&drv->driver); -+ return of_register_driver(drv, &ibmebus_bus_type); - } - EXPORT_SYMBOL(ibmebus_register_driver); - - void ibmebus_unregister_driver(struct of_platform_driver *drv) - { -- driver_unregister(&drv->driver); -+ of_unregister_driver(drv); - } - EXPORT_SYMBOL(ibmebus_unregister_driver); - ---- a/arch/powerpc/kernel/iommu.c -+++ b/arch/powerpc/kernel/iommu.c -@@ -532,16 +532,14 @@ struct iommu_table *iommu_init_table(str - return tbl; - } - --void iommu_free_table(struct device_node *dn) -+void iommu_free_table(struct iommu_table *tbl, const char *node_name) - { -- struct pci_dn *pdn = dn->data; -- struct iommu_table *tbl = pdn->iommu_table; - unsigned long bitmap_sz, i; - unsigned int order; - - if (!tbl || !tbl->it_map) { - printk(KERN_ERR "%s: expected TCE map for %s\n", __FUNCTION__, -- dn->full_name); -+ node_name); - return; - } - -@@ -550,7 +548,7 @@ void iommu_free_table(struct device_node - for (i = 0; i < (tbl->it_size/64); i++) { - if (tbl->it_map[i] != 0) { - printk(KERN_WARNING "%s: Unexpected TCEs for %s\n", -- __FUNCTION__, dn->full_name); -+ __FUNCTION__, node_name); - break; - } - } ---- a/arch/powerpc/kernel/isa-bridge.c -+++ b/arch/powerpc/kernel/isa-bridge.c -@@ -108,7 +108,7 @@ static void __devinit pci_process_ISA_OF - if (size > 0x10000) - size = 0x10000; - -- printk(KERN_ERR "no ISA IO ranges or unexpected isa range," -+ printk(KERN_ERR "no ISA IO ranges or unexpected isa range, " - "mapping 64k\n"); - - __ioremap_at(phb_io_base_phys, (void *)ISA_IO_BASE, -@@ -116,7 +116,7 @@ static void __devinit pci_process_ISA_OF - return; - - inval_range: -- printk(KERN_ERR "no ISA IO ranges or unexpected isa range," -+ printk(KERN_ERR "no ISA IO ranges or unexpected isa range, " - "mapping 64k\n"); - __ioremap_at(phb_io_base_phys, (void *)ISA_IO_BASE, - 0x10000, _PAGE_NO_CACHE|_PAGE_GUARDED); -@@ -145,7 +145,7 @@ void __init isa_bridge_find_early(struct - for_each_node_by_type(np, "isa") { - /* Look for our hose being a parent */ - for (parent = of_get_parent(np); parent;) { -- if (parent == hose->arch_data) { -+ if (parent == hose->dn) { - of_node_put(parent); - break; - } ---- a/arch/powerpc/kernel/legacy_serial.c -+++ b/arch/powerpc/kernel/legacy_serial.c -@@ -307,7 +307,7 @@ void __init find_legacy_serial_ports(voi - } - - /* First fill our array with SOC ports */ -- for (np = NULL; (np = of_find_compatible_node(np, "serial", "ns16550")) != NULL;) { -+ for_each_compatible_node(np, "serial", "ns16550") { - struct device_node *soc = of_get_parent(np); - if (soc && !strcmp(soc->type, "soc")) { - index = add_legacy_soc_port(np, np); -@@ -318,7 +318,7 @@ void __init find_legacy_serial_ports(voi - } - - /* First fill our array with ISA ports */ -- for (np = NULL; (np = of_find_node_by_type(np, "serial"));) { -+ for_each_node_by_type(np, "serial") { - struct device_node *isa = of_get_parent(np); - if (isa && !strcmp(isa->name, "isa")) { - index = add_legacy_isa_port(np, isa); -@@ -329,7 +329,7 @@ void __init find_legacy_serial_ports(voi - } - - /* First fill our array with tsi-bridge ports */ -- for (np = NULL; (np = of_find_compatible_node(np, "serial", "ns16550")) != NULL;) { -+ for_each_compatible_node(np, "serial", "ns16550") { - struct device_node *tsi = of_get_parent(np); - if (tsi && !strcmp(tsi->type, "tsi-bridge")) { - index = add_legacy_soc_port(np, np); -@@ -340,7 +340,7 @@ void __init find_legacy_serial_ports(voi - } - - /* First fill our array with opb bus ports */ -- for (np = NULL; (np = of_find_compatible_node(np, "serial", "ns16550")) != NULL;) { -+ for_each_compatible_node(np, "serial", "ns16550") { - struct device_node *opb = of_get_parent(np); - if (opb && (!strcmp(opb->type, "opb") || - of_device_is_compatible(opb, "ibm,opb"))) { -@@ -474,7 +474,7 @@ static int __init serial_dev_init(void) - - /* - * Before we register the platfrom serial devices, we need -- * to fixup their interrutps and their IO ports. -+ * to fixup their interrupts and their IO ports. - */ - DBG("Fixing serial ports interrupts and IO ports ...\n"); - ---- a/arch/powerpc/kernel/lparcfg.c -+++ b/arch/powerpc/kernel/lparcfg.c -@@ -41,7 +41,6 @@ - /* #define LPARCFG_DEBUG */ - - static struct proc_dir_entry *proc_ppc64_lparcfg; --#define LPARCFG_BUFF_SIZE 4096 - - /* - * Track sum of all purrs across all processors. This is used to further -@@ -595,13 +594,6 @@ int __init lparcfg_init(void) - ent = create_proc_entry("ppc64/lparcfg", mode, NULL); - if (ent) { - ent->proc_fops = &lparcfg_fops; -- ent->data = kmalloc(LPARCFG_BUFF_SIZE, GFP_KERNEL); -- if (!ent->data) { -- printk(KERN_ERR -- "Failed to allocate buffer for lparcfg\n"); -- remove_proc_entry("lparcfg", ent->parent); -- return -ENOMEM; -- } - } else { - printk(KERN_ERR "Failed to create ppc64/lparcfg\n"); - return -EIO; -@@ -613,10 +605,8 @@ int __init lparcfg_init(void) - - void __exit lparcfg_cleanup(void) - { -- if (proc_ppc64_lparcfg) { -- kfree(proc_ppc64_lparcfg->data); -+ if (proc_ppc64_lparcfg) - remove_proc_entry("lparcfg", proc_ppc64_lparcfg->parent); -- } - } - - module_init(lparcfg_init); ---- a/arch/powerpc/kernel/misc.S -+++ b/arch/powerpc/kernel/misc.S -@@ -8,12 +8,17 @@ - * Adapted for iSeries by Mike Corrigan (mikejc@us.ibm.com) - * PPC64 updates by Dave Engebretsen (engebret@us.ibm.com) - * -+ * setjmp/longjmp code by Paul Mackerras. -+ * - * 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 - - .text - -@@ -43,3 +48,71 @@ _GLOBAL(add_reloc_offset) - add r3,r3,r5 - mtlr r0 - blr -+ -+_GLOBAL(kernel_execve) -+ li r0,__NR_execve -+ sc -+ bnslr -+ neg r3,r3 -+ blr -+ -+_GLOBAL(setjmp) -+ mflr r0 -+ PPC_STL r0,0(r3) -+ PPC_STL r1,SZL(r3) -+ PPC_STL r2,2*SZL(r3) -+ mfcr r0 -+ PPC_STL r0,3*SZL(r3) -+ PPC_STL r13,4*SZL(r3) -+ PPC_STL r14,5*SZL(r3) -+ PPC_STL r15,6*SZL(r3) -+ PPC_STL r16,7*SZL(r3) -+ PPC_STL r17,8*SZL(r3) -+ PPC_STL r18,9*SZL(r3) -+ PPC_STL r19,10*SZL(r3) -+ PPC_STL r20,11*SZL(r3) -+ PPC_STL r21,12*SZL(r3) -+ PPC_STL r22,13*SZL(r3) -+ PPC_STL r23,14*SZL(r3) -+ PPC_STL r24,15*SZL(r3) -+ PPC_STL r25,16*SZL(r3) -+ PPC_STL r26,17*SZL(r3) -+ PPC_STL r27,18*SZL(r3) -+ PPC_STL r28,19*SZL(r3) -+ PPC_STL r29,20*SZL(r3) -+ PPC_STL r30,21*SZL(r3) -+ PPC_STL r31,22*SZL(r3) -+ li r3,0 -+ blr -+ -+_GLOBAL(longjmp) -+ PPC_LCMPI r4,0 -+ bne 1f -+ li r4,1 -+1: PPC_LL r13,4*SZL(r3) -+ PPC_LL r14,5*SZL(r3) -+ PPC_LL r15,6*SZL(r3) -+ PPC_LL r16,7*SZL(r3) -+ PPC_LL r17,8*SZL(r3) -+ PPC_LL r18,9*SZL(r3) -+ PPC_LL r19,10*SZL(r3) -+ PPC_LL r20,11*SZL(r3) -+ PPC_LL r21,12*SZL(r3) -+ PPC_LL r22,13*SZL(r3) -+ PPC_LL r23,14*SZL(r3) -+ PPC_LL r24,15*SZL(r3) -+ PPC_LL r25,16*SZL(r3) -+ PPC_LL r26,17*SZL(r3) -+ PPC_LL r27,18*SZL(r3) -+ PPC_LL r28,19*SZL(r3) -+ PPC_LL r29,20*SZL(r3) -+ PPC_LL r30,21*SZL(r3) -+ PPC_LL r31,22*SZL(r3) -+ PPC_LL r0,3*SZL(r3) -+ mtcrf 0x38,r0 -+ PPC_LL r0,0(r3) -+ PPC_LL r1,SZL(r3) -+ PPC_LL r2,2*SZL(r3) -+ mtlr r0 -+ mr r3,r4 -+ blr ---- a/arch/powerpc/kernel/misc_32.S -+++ b/arch/powerpc/kernel/misc_32.S -@@ -206,6 +206,45 @@ _GLOBAL(_nmask_and_or_msr) - isync - blr /* Done */ - -+#ifdef CONFIG_40x -+ -+/* -+ * Do an IO access in real mode -+ */ -+_GLOBAL(real_readb) -+ mfmsr r7 -+ ori r0,r7,MSR_DR -+ xori r0,r0,MSR_DR -+ sync -+ mtmsr r0 -+ sync -+ isync -+ lbz r3,0(r3) -+ sync -+ mtmsr r7 -+ sync -+ isync -+ blr -+ -+ /* -+ * Do an IO access in real mode -+ */ -+_GLOBAL(real_writeb) -+ mfmsr r7 -+ ori r0,r7,MSR_DR -+ xori r0,r0,MSR_DR -+ sync -+ mtmsr r0 -+ sync -+ isync -+ stb r3,0(r4) -+ sync -+ mtmsr r7 -+ sync -+ isync -+ blr -+ -+#endif /* CONFIG_40x */ - - /* - * Flush MMU TLB -@@ -793,13 +832,6 @@ _GLOBAL(kernel_thread) - addi r1,r1,16 - blr - --_GLOBAL(kernel_execve) -- li r0,__NR_execve -- sc -- bnslr -- neg r3,r3 -- blr -- - /* - * This routine is just here to keep GCC happy - sigh... - */ ---- a/arch/powerpc/kernel/misc_64.S -+++ b/arch/powerpc/kernel/misc_64.S -@@ -518,13 +518,6 @@ _GLOBAL(giveup_altivec) - - #endif /* CONFIG_ALTIVEC */ - --_GLOBAL(kernel_execve) -- li r0,__NR_execve -- sc -- bnslr -- neg r3,r3 -- blr -- - /* kexec_wait(phys_cpu) - * - * wait for the flag to change, indicating this kernel is going away but ---- a/arch/powerpc/kernel/module_32.c -+++ b/arch/powerpc/kernel/module_32.c -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include - - #include "setup.h" - -@@ -54,22 +55,60 @@ void module_free(struct module *mod, voi - addend) */ - static unsigned int count_relocs(const Elf32_Rela *rela, unsigned int num) - { -- unsigned int i, j, ret = 0; -+ unsigned int i, r_info, r_addend, _count_relocs; - -- /* Sure, this is order(n^2), but it's usually short, and not -- time critical */ -- for (i = 0; i < num; i++) { -- for (j = 0; j < i; j++) { -- /* If this addend appeared before, it's -- already been counted */ -- if (ELF32_R_SYM(rela[i].r_info) -- == ELF32_R_SYM(rela[j].r_info) -- && rela[i].r_addend == rela[j].r_addend) -- break; -+ _count_relocs = 0; -+ r_info = 0; -+ r_addend = 0; -+ for (i = 0; i < num; i++) -+ /* Only count 24-bit relocs, others don't need stubs */ -+ if (ELF32_R_TYPE(rela[i].r_info) == R_PPC_REL24 && -+ (r_info != ELF32_R_SYM(rela[i].r_info) || -+ r_addend != rela[i].r_addend)) { -+ _count_relocs++; -+ r_info = ELF32_R_SYM(rela[i].r_info); -+ r_addend = rela[i].r_addend; - } -- if (j == i) ret++; -+ -+ return _count_relocs; -+} -+ -+static int relacmp(const void *_x, const void *_y) -+{ -+ const Elf32_Rela *x, *y; -+ -+ y = (Elf32_Rela *)_x; -+ x = (Elf32_Rela *)_y; -+ -+ /* Compare the entire r_info (as opposed to ELF32_R_SYM(r_info) only) to -+ * make the comparison cheaper/faster. It won't affect the sorting or -+ * the counting algorithms' performance -+ */ -+ if (x->r_info < y->r_info) -+ return -1; -+ else if (x->r_info > y->r_info) -+ return 1; -+ else if (x->r_addend < y->r_addend) -+ return -1; -+ else if (x->r_addend > y->r_addend) -+ return 1; -+ else -+ return 0; -+} -+ -+static void relaswap(void *_x, void *_y, int size) -+{ -+ uint32_t *x, *y, tmp; -+ int i; -+ -+ y = (uint32_t *)_x; -+ x = (uint32_t *)_y; -+ -+ for (i = 0; i < sizeof(Elf32_Rela) / sizeof(uint32_t); i++) { -+ tmp = x[i]; -+ x[i] = y[i]; -+ y[i] = tmp; - } -- return ret; - } - - /* Get the potential trampolines size required of the init and -@@ -100,6 +139,16 @@ static unsigned long get_plt_size(const - DEBUGP("Ptr: %p. Number: %u\n", - (void *)hdr + sechdrs[i].sh_offset, - sechdrs[i].sh_size / sizeof(Elf32_Rela)); -+ -+ /* Sort the relocation information based on a symbol and -+ * addend key. This is a stable O(n*log n) complexity -+ * alogrithm but it will reduce the complexity of -+ * count_relocs() to linear complexity O(n) -+ */ -+ sort((void *)hdr + sechdrs[i].sh_offset, -+ sechdrs[i].sh_size / sizeof(Elf32_Rela), -+ sizeof(Elf32_Rela), relacmp, relaswap); -+ - ret += count_relocs((void *)hdr - + sechdrs[i].sh_offset, - sechdrs[i].sh_size ---- a/arch/powerpc/kernel/module_64.c -+++ b/arch/powerpc/kernel/module_64.c -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include - - #include "setup.h" - -@@ -81,25 +82,23 @@ static struct ppc64_stub_entry ppc64_stu - different addend) */ - static unsigned int count_relocs(const Elf64_Rela *rela, unsigned int num) - { -- unsigned int i, j, ret = 0; -+ unsigned int i, r_info, r_addend, _count_relocs; - - /* FIXME: Only count external ones --RR */ -- /* Sure, this is order(n^2), but it's usually short, and not -- time critical */ -- for (i = 0; i < num; i++) { -+ _count_relocs = 0; -+ r_info = 0; -+ r_addend = 0; -+ for (i = 0; i < num; i++) - /* Only count 24-bit relocs, others don't need stubs */ -- if (ELF64_R_TYPE(rela[i].r_info) != R_PPC_REL24) -- continue; -- for (j = 0; j < i; j++) { -- /* If this addend appeared before, it's -- already been counted */ -- if (rela[i].r_info == rela[j].r_info -- && rela[i].r_addend == rela[j].r_addend) -- break; -+ if (ELF64_R_TYPE(rela[i].r_info) == R_PPC_REL24 && -+ (r_info != ELF64_R_SYM(rela[i].r_info) || -+ r_addend != rela[i].r_addend)) { -+ _count_relocs++; -+ r_info = ELF64_R_SYM(rela[i].r_info); -+ r_addend = rela[i].r_addend; - } -- if (j == i) ret++; -- } -- return ret; -+ -+ return _count_relocs; - } - - void *module_alloc(unsigned long size) -@@ -118,6 +117,44 @@ void module_free(struct module *mod, voi - table entries. */ - } - -+static int relacmp(const void *_x, const void *_y) -+{ -+ const Elf64_Rela *x, *y; -+ -+ y = (Elf64_Rela *)_x; -+ x = (Elf64_Rela *)_y; -+ -+ /* Compare the entire r_info (as opposed to ELF64_R_SYM(r_info) only) to -+ * make the comparison cheaper/faster. It won't affect the sorting or -+ * the counting algorithms' performance -+ */ -+ if (x->r_info < y->r_info) -+ return -1; -+ else if (x->r_info > y->r_info) -+ return 1; -+ else if (x->r_addend < y->r_addend) -+ return -1; -+ else if (x->r_addend > y->r_addend) -+ return 1; -+ else -+ return 0; -+} -+ -+static void relaswap(void *_x, void *_y, int size) -+{ -+ uint64_t *x, *y, tmp; -+ int i; -+ -+ y = (uint64_t *)_x; -+ x = (uint64_t *)_y; -+ -+ for (i = 0; i < sizeof(Elf64_Rela) / sizeof(uint64_t); i++) { -+ tmp = x[i]; -+ x[i] = y[i]; -+ y[i] = tmp; -+ } -+} -+ - /* Get size of potential trampolines required. */ - static unsigned long get_stubs_size(const Elf64_Ehdr *hdr, - const Elf64_Shdr *sechdrs) -@@ -133,6 +170,16 @@ static unsigned long get_stubs_size(cons - DEBUGP("Ptr: %p. Number: %lu\n", - (void *)sechdrs[i].sh_addr, - sechdrs[i].sh_size / sizeof(Elf64_Rela)); -+ -+ /* Sort the relocation information based on a symbol and -+ * addend key. This is a stable O(n*log n) complexity -+ * alogrithm but it will reduce the complexity of -+ * count_relocs() to linear complexity O(n) -+ */ -+ sort((void *)sechdrs[i].sh_addr, -+ sechdrs[i].sh_size / sizeof(Elf64_Rela), -+ sizeof(Elf64_Rela), relacmp, relaswap); -+ - relocs += count_relocs((void *)sechdrs[i].sh_addr, - sechdrs[i].sh_size - / sizeof(Elf64_Rela)); -@@ -343,7 +390,7 @@ int apply_relocate_add(Elf64_Shdr *sechd - /* Simply set it */ - *(u32 *)location = value; - break; -- -+ - case R_PPC64_ADDR64: - /* Simply set it */ - *(unsigned long *)location = value; -@@ -399,7 +446,7 @@ int apply_relocate_add(Elf64_Shdr *sechd - } - - /* Only replace bits 2 through 26 */ -- *(uint32_t *)location -+ *(uint32_t *)location - = (*(uint32_t *)location & ~0x03fffffc) - | (value & 0x03fffffc); - break; ---- a/arch/powerpc/kernel/of_device.c -+++ b/arch/powerpc/kernel/of_device.c -@@ -5,10 +5,10 @@ - #include - #include - #include -+#include - - #include - #include --#include - - static void of_device_make_bus_id(struct of_device *dev) - { ---- a/arch/powerpc/kernel/of_platform.c -+++ b/arch/powerpc/kernel/of_platform.c -@@ -19,6 +19,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -40,7 +41,7 @@ - * a bus type in the list - */ - --static struct of_device_id of_default_bus_ids[] = { -+static const struct of_device_id of_default_bus_ids[] = { - { .type = "soc", }, - { .compatible = "soc", }, - { .type = "spider", }, -@@ -64,26 +65,6 @@ static int __init of_bus_driver_init(voi - - postcore_initcall(of_bus_driver_init); - --int of_register_platform_driver(struct of_platform_driver *drv) --{ -- /* initialize common driver fields */ -- if (!drv->driver.name) -- drv->driver.name = drv->name; -- if (!drv->driver.owner) -- drv->driver.owner = drv->owner; -- drv->driver.bus = &of_platform_bus_type; -- -- /* register with core */ -- return driver_register(&drv->driver); --} --EXPORT_SYMBOL(of_register_platform_driver); -- --void of_unregister_platform_driver(struct of_platform_driver *drv) --{ -- driver_unregister(&drv->driver); --} --EXPORT_SYMBOL(of_unregister_platform_driver); -- - struct of_device* of_platform_device_create(struct device_node *np, - const char *bus_id, - struct device *parent) -@@ -120,15 +101,15 @@ EXPORT_SYMBOL(of_platform_device_create) - * @matches: match table, NULL to use the default, OF_NO_DEEP_PROBE to - * disallow recursive creation of child busses - */ --static int of_platform_bus_create(struct device_node *bus, -- struct of_device_id *matches, -+static int of_platform_bus_create(const struct device_node *bus, -+ const struct of_device_id *matches, - struct device *parent) - { - struct device_node *child; - struct of_device *dev; - int rc = 0; - -- for (child = NULL; (child = of_get_next_child(bus, child)); ) { -+ for_each_child_of_node(bus, child) { - pr_debug(" create child: %s\n", child->full_name); - dev = of_platform_device_create(child, NULL, parent); - if (dev == NULL) -@@ -157,7 +138,7 @@ static int of_platform_bus_create(struct - */ - - int of_platform_bus_probe(struct device_node *root, -- struct of_device_id *matches, -+ const struct of_device_id *matches, - struct device *parent) - { - struct device_node *child; -@@ -190,7 +171,7 @@ int of_platform_bus_probe(struct device_ - rc = of_platform_bus_create(root, matches, &dev->dev); - goto bail; - } -- for (child = NULL; (child = of_get_next_child(root, child)); ) { -+ for_each_child_of_node(root, child) { - if (!of_match_node(matches, child)) - continue; - ---- a/arch/powerpc/kernel/pci-common.c -+++ b/arch/powerpc/kernel/pci-common.c -@@ -48,32 +48,26 @@ - static DEFINE_SPINLOCK(hose_spinlock); - - /* XXX kill that some day ... */ --int global_phb_number; /* Global phb counter */ -+static int global_phb_number; /* Global phb counter */ - --extern struct list_head hose_list; -+/* ISA Memory physical address */ -+resource_size_t isa_mem_base; - --/* -- * pci_controller(phb) initialized common variables. -- */ --static void __devinit pci_setup_pci_controller(struct pci_controller *hose) --{ -- memset(hose, 0, sizeof(struct pci_controller)); -- -- spin_lock(&hose_spinlock); -- hose->global_number = global_phb_number++; -- list_add_tail(&hose->list_node, &hose_list); -- spin_unlock(&hose_spinlock); --} -+/* Default PCI flags is 0 */ -+unsigned int ppc_pci_flags; - --struct pci_controller * pcibios_alloc_controller(struct device_node *dev) -+struct pci_controller *pcibios_alloc_controller(struct device_node *dev) - { - struct pci_controller *phb; - -- phb = alloc_maybe_bootmem(sizeof(struct pci_controller), GFP_KERNEL); -+ phb = zalloc_maybe_bootmem(sizeof(struct pci_controller), GFP_KERNEL); - if (phb == NULL) - return NULL; -- pci_setup_pci_controller(phb); -- phb->arch_data = dev; -+ spin_lock(&hose_spinlock); -+ phb->global_number = global_phb_number++; -+ list_add_tail(&phb->list_node, &hose_list); -+ spin_unlock(&hose_spinlock); -+ phb->dn = dev; - phb->is_dynamic = mem_init_done; - #ifdef CONFIG_PPC64 - if (dev) { -@@ -126,15 +120,10 @@ int pcibios_vaddr_is_ioport(void __iomem - */ - int pci_domain_nr(struct pci_bus *bus) - { -- if (firmware_has_feature(FW_FEATURE_ISERIES)) -- return 0; -- else { -- struct pci_controller *hose = pci_bus_to_host(bus); -+ struct pci_controller *hose = pci_bus_to_host(bus); - -- return hose->global_number; -- } -+ return hose->global_number; - } -- - EXPORT_SYMBOL(pci_domain_nr); - - #ifdef CONFIG_PPC_OF -@@ -153,7 +142,7 @@ struct pci_controller* pci_find_hose_for - while(node) { - struct pci_controller *hose, *tmp; - list_for_each_entry_safe(hose, tmp, &hose_list, list_node) -- if (hose->arch_data == node) -+ if (hose->dn == node) - return hose; - node = node->parent; - } -@@ -201,6 +190,20 @@ int pci_read_irq_line(struct pci_dev *pc - struct of_irq oirq; - unsigned int virq; - -+ /* The current device-tree that iSeries generates from the HV -+ * PCI informations doesn't contain proper interrupt routing, -+ * and all the fallback would do is print out crap, so we -+ * don't attempt to resolve the interrupts here at all, some -+ * iSeries specific fixup does it. -+ * -+ * In the long run, we will hopefully fix the generated device-tree -+ * instead. -+ */ -+#ifdef CONFIG_PPC_ISERIES -+ if (firmware_has_feature(FW_FEATURE_ISERIES)) -+ return -1; -+#endif -+ - DBG("Try to map irq for %s...\n", pci_name(pci_dev)); - - #ifdef DEBUG -@@ -222,10 +225,11 @@ int pci_read_irq_line(struct pci_dev *pc - if (pin == 0) - return -1; - if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_LINE, &line) || -- line == 0xff) { -+ line == 0xff || line == 0) { - return -1; - } -- DBG(" -> no map ! Using irq line %d from PCI config\n", line); -+ DBG(" -> no map ! Using line %d (pin %d) from PCI config\n", -+ line, pin); - - virq = irq_create_mapping(NULL, line); - if (virq != NO_IRQ) -@@ -475,3 +479,717 @@ void pci_resource_to_user(const struct p - *start = rsrc->start - offset; - *end = rsrc->end - offset; - } -+ -+/** -+ * pci_process_bridge_OF_ranges - Parse PCI bridge resources from device tree -+ * @hose: newly allocated pci_controller to be setup -+ * @dev: device node of the host bridge -+ * @primary: set if primary bus (32 bits only, soon to be deprecated) -+ * -+ * This function will parse the "ranges" property of a PCI host bridge device -+ * node and setup the resource mapping of a pci controller based on its -+ * content. -+ * -+ * Life would be boring if it wasn't for a few issues that we have to deal -+ * with here: -+ * -+ * - We can only cope with one IO space range and up to 3 Memory space -+ * ranges. However, some machines (thanks Apple !) tend to split their -+ * space into lots of small contiguous ranges. So we have to coalesce. -+ * -+ * - We can only cope with all memory ranges having the same offset -+ * between CPU addresses and PCI addresses. Unfortunately, some bridges -+ * are setup for a large 1:1 mapping along with a small "window" which -+ * maps PCI address 0 to some arbitrary high address of the CPU space in -+ * order to give access to the ISA memory hole. -+ * The way out of here that I've chosen for now is to always set the -+ * offset based on the first resource found, then override it if we -+ * have a different offset and the previous was set by an ISA hole. -+ * -+ * - Some busses have IO space not starting at 0, which causes trouble with -+ * the way we do our IO resource renumbering. The code somewhat deals with -+ * it for 64 bits but I would expect problems on 32 bits. -+ * -+ * - Some 32 bits platforms such as 4xx can have physical space larger than -+ * 32 bits so we need to use 64 bits values for the parsing -+ */ -+void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose, -+ struct device_node *dev, -+ int primary) -+{ -+ const u32 *ranges; -+ int rlen; -+ int pna = of_n_addr_cells(dev); -+ int np = pna + 5; -+ int memno = 0, isa_hole = -1; -+ u32 pci_space; -+ unsigned long long pci_addr, cpu_addr, pci_next, cpu_next, size; -+ unsigned long long isa_mb = 0; -+ struct resource *res; -+ -+ printk(KERN_INFO "PCI host bridge %s %s ranges:\n", -+ dev->full_name, primary ? "(primary)" : ""); -+ -+ /* Get ranges property */ -+ ranges = of_get_property(dev, "ranges", &rlen); -+ if (ranges == NULL) -+ return; -+ -+ /* Parse it */ -+ while ((rlen -= np * 4) >= 0) { -+ /* Read next ranges element */ -+ pci_space = ranges[0]; -+ pci_addr = of_read_number(ranges + 1, 2); -+ cpu_addr = of_translate_address(dev, ranges + 3); -+ size = of_read_number(ranges + pna + 3, 2); -+ ranges += np; -+ if (cpu_addr == OF_BAD_ADDR || size == 0) -+ continue; -+ -+ /* Now consume following elements while they are contiguous */ -+ for (; rlen >= np * sizeof(u32); -+ ranges += np, rlen -= np * 4) { -+ if (ranges[0] != pci_space) -+ break; -+ pci_next = of_read_number(ranges + 1, 2); -+ cpu_next = of_translate_address(dev, ranges + 3); -+ if (pci_next != pci_addr + size || -+ cpu_next != cpu_addr + size) -+ break; -+ size += of_read_number(ranges + pna + 3, 2); -+ } -+ -+ /* Act based on address space type */ -+ res = NULL; -+ switch ((pci_space >> 24) & 0x3) { -+ case 1: /* PCI IO space */ -+ printk(KERN_INFO -+ " IO 0x%016llx..0x%016llx -> 0x%016llx\n", -+ cpu_addr, cpu_addr + size - 1, pci_addr); -+ -+ /* We support only one IO range */ -+ if (hose->pci_io_size) { -+ printk(KERN_INFO -+ " \\--> Skipped (too many) !\n"); -+ continue; -+ } -+#ifdef CONFIG_PPC32 -+ /* On 32 bits, limit I/O space to 16MB */ -+ if (size > 0x01000000) -+ size = 0x01000000; -+ -+ /* 32 bits needs to map IOs here */ -+ hose->io_base_virt = ioremap(cpu_addr, size); -+ -+ /* Expect trouble if pci_addr is not 0 */ -+ if (primary) -+ isa_io_base = -+ (unsigned long)hose->io_base_virt; -+#endif /* CONFIG_PPC32 */ -+ /* pci_io_size and io_base_phys always represent IO -+ * space starting at 0 so we factor in pci_addr -+ */ -+ hose->pci_io_size = pci_addr + size; -+ hose->io_base_phys = cpu_addr - pci_addr; -+ -+ /* Build resource */ -+ res = &hose->io_resource; -+ res->flags = IORESOURCE_IO; -+ res->start = pci_addr; -+ break; -+ case 2: /* PCI Memory space */ -+ printk(KERN_INFO -+ " MEM 0x%016llx..0x%016llx -> 0x%016llx %s\n", -+ cpu_addr, cpu_addr + size - 1, pci_addr, -+ (pci_space & 0x40000000) ? "Prefetch" : ""); -+ -+ /* We support only 3 memory ranges */ -+ if (memno >= 3) { -+ printk(KERN_INFO -+ " \\--> Skipped (too many) !\n"); -+ continue; -+ } -+ /* Handles ISA memory hole space here */ -+ if (pci_addr == 0) { -+ isa_mb = cpu_addr; -+ isa_hole = memno; -+ if (primary || isa_mem_base == 0) -+ isa_mem_base = cpu_addr; -+ } -+ -+ /* We get the PCI/Mem offset from the first range or -+ * the, current one if the offset came from an ISA -+ * hole. If they don't match, bugger. -+ */ -+ if (memno == 0 || -+ (isa_hole >= 0 && pci_addr != 0 && -+ hose->pci_mem_offset == isa_mb)) -+ hose->pci_mem_offset = cpu_addr - pci_addr; -+ else if (pci_addr != 0 && -+ hose->pci_mem_offset != cpu_addr - pci_addr) { -+ printk(KERN_INFO -+ " \\--> Skipped (offset mismatch) !\n"); -+ continue; -+ } -+ -+ /* Build resource */ -+ res = &hose->mem_resources[memno++]; -+ res->flags = IORESOURCE_MEM; -+ if (pci_space & 0x40000000) -+ res->flags |= IORESOURCE_PREFETCH; -+ res->start = cpu_addr; -+ break; -+ } -+ if (res != NULL) { -+ res->name = dev->full_name; -+ res->end = res->start + size - 1; -+ res->parent = NULL; -+ res->sibling = NULL; -+ res->child = NULL; -+ } -+ } -+ -+ /* Out of paranoia, let's put the ISA hole last if any */ -+ if (isa_hole >= 0 && memno > 0 && isa_hole != (memno-1)) { -+ struct resource tmp = hose->mem_resources[isa_hole]; -+ hose->mem_resources[isa_hole] = hose->mem_resources[memno-1]; -+ hose->mem_resources[memno-1] = tmp; -+ } -+} -+ -+/* Decide whether to display the domain number in /proc */ -+int pci_proc_domain(struct pci_bus *bus) -+{ -+ struct pci_controller *hose = pci_bus_to_host(bus); -+#ifdef CONFIG_PPC64 -+ return hose->buid != 0; -+#else -+ if (!(ppc_pci_flags & PPC_PCI_ENABLE_PROC_DOMAINS)) -+ return 0; -+ if (ppc_pci_flags & PPC_PCI_COMPAT_DOMAIN_0) -+ return hose->global_number != 0; -+ return 1; -+#endif -+} -+ -+void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, -+ struct resource *res) -+{ -+ resource_size_t offset = 0, mask = (resource_size_t)-1; -+ struct pci_controller *hose = pci_bus_to_host(dev->bus); -+ -+ if (!hose) -+ return; -+ if (res->flags & IORESOURCE_IO) { -+ offset = (unsigned long)hose->io_base_virt - _IO_BASE; -+ mask = 0xffffffffu; -+ } else if (res->flags & IORESOURCE_MEM) -+ offset = hose->pci_mem_offset; -+ -+ region->start = (res->start - offset) & mask; -+ region->end = (res->end - offset) & mask; -+} -+EXPORT_SYMBOL(pcibios_resource_to_bus); -+ -+void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, -+ struct pci_bus_region *region) -+{ -+ resource_size_t offset = 0, mask = (resource_size_t)-1; -+ struct pci_controller *hose = pci_bus_to_host(dev->bus); -+ -+ if (!hose) -+ return; -+ if (res->flags & IORESOURCE_IO) { -+ offset = (unsigned long)hose->io_base_virt - _IO_BASE; -+ mask = 0xffffffffu; -+ } else if (res->flags & IORESOURCE_MEM) -+ offset = hose->pci_mem_offset; -+ res->start = (region->start + offset) & mask; -+ res->end = (region->end + offset) & mask; -+} -+EXPORT_SYMBOL(pcibios_bus_to_resource); -+ -+/* Fixup a bus resource into a linux resource */ -+static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev) -+{ -+ struct pci_controller *hose = pci_bus_to_host(dev->bus); -+ resource_size_t offset = 0, mask = (resource_size_t)-1; -+ -+ if (res->flags & IORESOURCE_IO) { -+ offset = (unsigned long)hose->io_base_virt - _IO_BASE; -+ mask = 0xffffffffu; -+ } else if (res->flags & IORESOURCE_MEM) -+ offset = hose->pci_mem_offset; -+ -+ res->start = (res->start + offset) & mask; -+ res->end = (res->end + offset) & mask; -+ -+ pr_debug("PCI:%s %016llx-%016llx\n", -+ pci_name(dev), -+ (unsigned long long)res->start, -+ (unsigned long long)res->end); -+} -+ -+ -+/* This header fixup will do the resource fixup for all devices as they are -+ * probed, but not for bridge ranges -+ */ -+static void __devinit pcibios_fixup_resources(struct pci_dev *dev) -+{ -+ struct pci_controller *hose = pci_bus_to_host(dev->bus); -+ int i; -+ -+ if (!hose) { -+ printk(KERN_ERR "No host bridge for PCI dev %s !\n", -+ pci_name(dev)); -+ return; -+ } -+ for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { -+ struct resource *res = dev->resource + i; -+ if (!res->flags) -+ continue; -+ if (res->end == 0xffffffff) { -+ pr_debug("PCI:%s Resource %d %016llx-%016llx [%x] is unassigned\n", -+ pci_name(dev), i, -+ (unsigned long long)res->start, -+ (unsigned long long)res->end, -+ (unsigned int)res->flags); -+ res->end -= res->start; -+ res->start = 0; -+ res->flags |= IORESOURCE_UNSET; -+ continue; -+ } -+ -+ pr_debug("PCI:%s Resource %d %016llx-%016llx [%x] fixup...\n", -+ pci_name(dev), i, -+ (unsigned long long)res->start,\ -+ (unsigned long long)res->end, -+ (unsigned int)res->flags); -+ -+ fixup_resource(res, dev); -+ } -+ -+ /* Call machine specific resource fixup */ -+ if (ppc_md.pcibios_fixup_resources) -+ ppc_md.pcibios_fixup_resources(dev); -+} -+DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_resources); -+ -+static void __devinit __pcibios_fixup_bus(struct pci_bus *bus) -+{ -+ struct pci_controller *hose = pci_bus_to_host(bus); -+ struct pci_dev *dev = bus->self; -+ -+ pr_debug("PCI: Fixup bus %d (%s)\n", bus->number, dev ? pci_name(dev) : "PHB"); -+ -+ /* Fixup PCI<->PCI bridges. Host bridges are handled separately, for -+ * now differently between 32 and 64 bits. -+ */ -+ if (dev != NULL) { -+ struct resource *res; -+ int i; -+ -+ for (i = 0; i < PCI_BUS_NUM_RESOURCES; ++i) { -+ if ((res = bus->resource[i]) == NULL) -+ continue; -+ if (!res->flags) -+ continue; -+ if (i >= 3 && bus->self->transparent) -+ continue; -+ /* On PowerMac, Apple leaves bridge windows open over -+ * an inaccessible region of memory space (0...fffff) -+ * which is somewhat bogus, but that's what they think -+ * means disabled... -+ * -+ * We clear those to force them to be reallocated later -+ * -+ * We detect such regions by the fact that the base is -+ * equal to the pci_mem_offset of the host bridge and -+ * their size is smaller than 1M. -+ */ -+ if (res->flags & IORESOURCE_MEM && -+ res->start == hose->pci_mem_offset && -+ res->end < 0x100000) { -+ printk(KERN_INFO -+ "PCI: Closing bogus Apple Firmware" -+ " region %d on bus 0x%02x\n", -+ i, bus->number); -+ res->flags = 0; -+ continue; -+ } -+ -+ pr_debug("PCI:%s Bus rsrc %d %016llx-%016llx [%x] fixup...\n", -+ pci_name(dev), i, -+ (unsigned long long)res->start,\ -+ (unsigned long long)res->end, -+ (unsigned int)res->flags); -+ -+ fixup_resource(res, dev); -+ } -+ } -+ -+ /* Additional setup that is different between 32 and 64 bits for now */ -+ pcibios_do_bus_setup(bus); -+ -+ /* Platform specific bus fixups */ -+ if (ppc_md.pcibios_fixup_bus) -+ ppc_md.pcibios_fixup_bus(bus); -+ -+ /* Read default IRQs and fixup if necessary */ -+ list_for_each_entry(dev, &bus->devices, bus_list) { -+ pci_read_irq_line(dev); -+ if (ppc_md.pci_irq_fixup) -+ ppc_md.pci_irq_fixup(dev); -+ } -+} -+ -+void __devinit pcibios_fixup_bus(struct pci_bus *bus) -+{ -+ /* When called from the generic PCI probe, read PCI<->PCI bridge -+ * bases before proceeding -+ */ -+ if (bus->self != NULL) -+ pci_read_bridge_bases(bus); -+ __pcibios_fixup_bus(bus); -+} -+EXPORT_SYMBOL(pcibios_fixup_bus); -+ -+/* When building a bus from the OF tree rather than probing, we need a -+ * slightly different version of the fixup which doesn't read the -+ * bridge bases using config space accesses -+ */ -+void __devinit pcibios_fixup_of_probed_bus(struct pci_bus *bus) -+{ -+ __pcibios_fixup_bus(bus); -+} -+ -+static int skip_isa_ioresource_align(struct pci_dev *dev) -+{ -+ if ((ppc_pci_flags & PPC_PCI_CAN_SKIP_ISA_ALIGN) && -+ !(dev->bus->bridge_ctl & PCI_BRIDGE_CTL_ISA)) -+ return 1; -+ return 0; -+} -+ -+/* -+ * We need to avoid collisions with `mirrored' VGA ports -+ * and other strange ISA hardware, so we always want the -+ * addresses to be allocated in the 0x000-0x0ff region -+ * modulo 0x400. -+ * -+ * Why? Because some silly external IO cards only decode -+ * the low 10 bits of the IO address. The 0x00-0xff region -+ * is reserved for motherboard devices that decode all 16 -+ * bits, so it's ok to allocate at, say, 0x2800-0x28ff, -+ * but we want to try to avoid allocating at 0x2900-0x2bff -+ * which might have be mirrored at 0x0100-0x03ff.. -+ */ -+void pcibios_align_resource(void *data, struct resource *res, -+ resource_size_t size, resource_size_t align) -+{ -+ struct pci_dev *dev = data; -+ -+ if (res->flags & IORESOURCE_IO) { -+ resource_size_t start = res->start; -+ -+ if (skip_isa_ioresource_align(dev)) -+ return; -+ if (start & 0x300) { -+ start = (start + 0x3ff) & ~0x3ff; -+ res->start = start; -+ } -+ } -+} -+EXPORT_SYMBOL(pcibios_align_resource); -+ -+/* -+ * Reparent resource children of pr that conflict with res -+ * under res, and make res replace those children. -+ */ -+static int __init reparent_resources(struct resource *parent, -+ struct resource *res) -+{ -+ struct resource *p, **pp; -+ struct resource **firstpp = NULL; -+ -+ for (pp = &parent->child; (p = *pp) != NULL; pp = &p->sibling) { -+ if (p->end < res->start) -+ continue; -+ if (res->end < p->start) -+ break; -+ if (p->start < res->start || p->end > res->end) -+ return -1; /* not completely contained */ -+ if (firstpp == NULL) -+ firstpp = pp; -+ } -+ if (firstpp == NULL) -+ return -1; /* didn't find any conflicting entries? */ -+ res->parent = parent; -+ res->child = *firstpp; -+ res->sibling = *pp; -+ *firstpp = res; -+ *pp = NULL; -+ for (p = res->child; p != NULL; p = p->sibling) { -+ p->parent = res; -+ DBG(KERN_INFO "PCI: reparented %s [%llx..%llx] under %s\n", -+ p->name, -+ (unsigned long long)p->start, -+ (unsigned long long)p->end, res->name); -+ } -+ return 0; -+} -+ -+/* -+ * Handle resources of PCI devices. If the world were perfect, we could -+ * just allocate all the resource regions and do nothing more. It isn't. -+ * On the other hand, we cannot just re-allocate all devices, as it would -+ * require us to know lots of host bridge internals. So we attempt to -+ * keep as much of the original configuration as possible, but tweak it -+ * when it's found to be wrong. -+ * -+ * Known BIOS problems we have to work around: -+ * - I/O or memory regions not configured -+ * - regions configured, but not enabled in the command register -+ * - bogus I/O addresses above 64K used -+ * - expansion ROMs left enabled (this may sound harmless, but given -+ * the fact the PCI specs explicitly allow address decoders to be -+ * shared between expansion ROMs and other resource regions, it's -+ * at least dangerous) -+ * -+ * Our solution: -+ * (1) Allocate resources for all buses behind PCI-to-PCI bridges. -+ * This gives us fixed barriers on where we can allocate. -+ * (2) Allocate resources for all enabled devices. If there is -+ * a collision, just mark the resource as unallocated. Also -+ * disable expansion ROMs during this step. -+ * (3) Try to allocate resources for disabled devices. If the -+ * resources were assigned correctly, everything goes well, -+ * if they weren't, they won't disturb allocation of other -+ * resources. -+ * (4) Assign new addresses to resources which were either -+ * not configured at all or misconfigured. If explicitly -+ * requested by the user, configure expansion ROM address -+ * as well. -+ */ -+ -+static void __init pcibios_allocate_bus_resources(struct list_head *bus_list) -+{ -+ struct pci_bus *bus; -+ int i; -+ struct resource *res, *pr; -+ -+ /* Depth-First Search on bus tree */ -+ list_for_each_entry(bus, bus_list, node) { -+ for (i = 0; i < PCI_BUS_NUM_RESOURCES; ++i) { -+ if ((res = bus->resource[i]) == NULL || !res->flags -+ || res->start > res->end) -+ continue; -+ if (bus->parent == NULL) -+ pr = (res->flags & IORESOURCE_IO) ? -+ &ioport_resource : &iomem_resource; -+ else { -+ /* Don't bother with non-root busses when -+ * re-assigning all resources. We clear the -+ * resource flags as if they were colliding -+ * and as such ensure proper re-allocation -+ * later. -+ */ -+ if (ppc_pci_flags & PPC_PCI_REASSIGN_ALL_RSRC) -+ goto clear_resource; -+ pr = pci_find_parent_resource(bus->self, res); -+ if (pr == res) { -+ /* this happens when the generic PCI -+ * code (wrongly) decides that this -+ * bridge is transparent -- paulus -+ */ -+ continue; -+ } -+ } -+ -+ DBG("PCI: %s (bus %d) bridge rsrc %d: %016llx-%016llx " -+ "[0x%x], parent %p (%s)\n", -+ bus->self ? pci_name(bus->self) : "PHB", -+ bus->number, i, -+ (unsigned long long)res->start, -+ (unsigned long long)res->end, -+ (unsigned int)res->flags, -+ pr, (pr && pr->name) ? pr->name : "nil"); -+ -+ if (pr && !(pr->flags & IORESOURCE_UNSET)) { -+ if (request_resource(pr, res) == 0) -+ continue; -+ /* -+ * Must be a conflict with an existing entry. -+ * Move that entry (or entries) under the -+ * bridge resource and try again. -+ */ -+ if (reparent_resources(pr, res) == 0) -+ continue; -+ } -+ printk(KERN_WARNING -+ "PCI: Cannot allocate resource region " -+ "%d of PCI bridge %d, will remap\n", -+ i, bus->number); -+clear_resource: -+ res->flags = 0; -+ } -+ pcibios_allocate_bus_resources(&bus->children); -+ } -+} -+ -+static inline void __devinit alloc_resource(struct pci_dev *dev, int idx) -+{ -+ struct resource *pr, *r = &dev->resource[idx]; -+ -+ DBG("PCI: Allocating %s: Resource %d: %016llx..%016llx [%x]\n", -+ pci_name(dev), idx, -+ (unsigned long long)r->start, -+ (unsigned long long)r->end, -+ (unsigned int)r->flags); -+ -+ pr = pci_find_parent_resource(dev, r); -+ if (!pr || (pr->flags & IORESOURCE_UNSET) || -+ request_resource(pr, r) < 0) { -+ printk(KERN_WARNING "PCI: Cannot allocate resource region %d" -+ " of device %s, will remap\n", idx, pci_name(dev)); -+ if (pr) -+ DBG("PCI: parent is %p: %016llx-%016llx [%x]\n", pr, -+ (unsigned long long)pr->start, -+ (unsigned long long)pr->end, -+ (unsigned int)pr->flags); -+ /* We'll assign a new address later */ -+ r->flags |= IORESOURCE_UNSET; -+ r->end -= r->start; -+ r->start = 0; -+ } -+} -+ -+static void __init pcibios_allocate_resources(int pass) -+{ -+ struct pci_dev *dev = NULL; -+ int idx, disabled; -+ u16 command; -+ struct resource *r; -+ -+ for_each_pci_dev(dev) { -+ pci_read_config_word(dev, PCI_COMMAND, &command); -+ for (idx = 0; idx < 6; idx++) { -+ r = &dev->resource[idx]; -+ if (r->parent) /* Already allocated */ -+ continue; -+ if (!r->flags || (r->flags & IORESOURCE_UNSET)) -+ continue; /* Not assigned at all */ -+ if (r->flags & IORESOURCE_IO) -+ disabled = !(command & PCI_COMMAND_IO); -+ else -+ disabled = !(command & PCI_COMMAND_MEMORY); -+ if (pass == disabled) -+ alloc_resource(dev, idx); -+ } -+ if (pass) -+ continue; -+ r = &dev->resource[PCI_ROM_RESOURCE]; -+ if (r->flags & IORESOURCE_ROM_ENABLE) { -+ /* Turn the ROM off, leave the resource region, -+ * but keep it unregistered. -+ */ -+ u32 reg; -+ DBG("PCI: Switching off ROM of %s\n", pci_name(dev)); -+ r->flags &= ~IORESOURCE_ROM_ENABLE; -+ pci_read_config_dword(dev, dev->rom_base_reg, ®); -+ pci_write_config_dword(dev, dev->rom_base_reg, -+ reg & ~PCI_ROM_ADDRESS_ENABLE); -+ } -+ } -+} -+ -+void __init pcibios_resource_survey(void) -+{ -+ /* Allocate and assign resources. If we re-assign everything, then -+ * we skip the allocate phase -+ */ -+ pcibios_allocate_bus_resources(&pci_root_buses); -+ -+ if (!(ppc_pci_flags & PPC_PCI_REASSIGN_ALL_RSRC)) { -+ pcibios_allocate_resources(0); -+ pcibios_allocate_resources(1); -+ } -+ -+ if (!(ppc_pci_flags & PPC_PCI_PROBE_ONLY)) { -+ DBG("PCI: Assigning unassigned resouces...\n"); -+ pci_assign_unassigned_resources(); -+ } -+ -+ /* Call machine dependent fixup */ -+ if (ppc_md.pcibios_fixup) -+ ppc_md.pcibios_fixup(); -+} -+ -+#ifdef CONFIG_HOTPLUG -+/* This is used by the pSeries hotplug driver to allocate resource -+ * of newly plugged busses. We can try to consolidate with the -+ * rest of the code later, for now, keep it as-is -+ */ -+void __devinit pcibios_claim_one_bus(struct pci_bus *bus) -+{ -+ struct pci_dev *dev; -+ struct pci_bus *child_bus; -+ -+ list_for_each_entry(dev, &bus->devices, bus_list) { -+ int i; -+ -+ for (i = 0; i < PCI_NUM_RESOURCES; i++) { -+ struct resource *r = &dev->resource[i]; -+ -+ if (r->parent || !r->start || !r->flags) -+ continue; -+ pci_claim_resource(dev, i); -+ } -+ } -+ -+ list_for_each_entry(child_bus, &bus->children, node) -+ pcibios_claim_one_bus(child_bus); -+} -+EXPORT_SYMBOL_GPL(pcibios_claim_one_bus); -+#endif /* CONFIG_HOTPLUG */ -+ -+int pcibios_enable_device(struct pci_dev *dev, int mask) -+{ -+ u16 cmd, old_cmd; -+ int idx; -+ struct resource *r; -+ -+ if (ppc_md.pcibios_enable_device_hook) -+ if (ppc_md.pcibios_enable_device_hook(dev)) -+ return -EINVAL; -+ -+ pci_read_config_word(dev, PCI_COMMAND, &cmd); -+ old_cmd = cmd; -+ for (idx = 0; idx < PCI_NUM_RESOURCES; idx++) { -+ /* Only set up the requested stuff */ -+ if (!(mask & (1 << idx))) -+ continue; -+ r = &dev->resource[idx]; -+ if (!(r->flags & (IORESOURCE_IO | IORESOURCE_MEM))) -+ continue; -+ if ((idx == PCI_ROM_RESOURCE) && -+ (!(r->flags & IORESOURCE_ROM_ENABLE))) -+ continue; -+ if (r->parent == NULL) { -+ printk(KERN_ERR "PCI: Device %s not available because" -+ " of resource collisions\n", pci_name(dev)); -+ return -EINVAL; -+ } -+ if (r->flags & IORESOURCE_IO) -+ cmd |= PCI_COMMAND_IO; -+ if (r->flags & IORESOURCE_MEM) -+ cmd |= PCI_COMMAND_MEMORY; -+ } -+ if (cmd != old_cmd) { -+ printk("PCI: Enabling device %s (%04x -> %04x)\n", -+ pci_name(dev), old_cmd, cmd); -+ pci_write_config_word(dev, PCI_COMMAND, cmd); -+ } -+ return 0; -+} -+ ---- a/arch/powerpc/kernel/pci_32.c -+++ b/arch/powerpc/kernel/pci_32.c -@@ -13,6 +13,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -32,19 +33,12 @@ - #endif - - unsigned long isa_io_base = 0; --unsigned long isa_mem_base = 0; - unsigned long pci_dram_offset = 0; - int pcibios_assign_bus_offset = 1; - - void pcibios_make_OF_bus_map(void); - --static int pci_relocate_bridge_resource(struct pci_bus *bus, int i); --static int probe_resource(struct pci_bus *parent, struct resource *pr, -- struct resource *res, struct resource **conflict); --static void update_bridge_base(struct pci_bus *bus, int i); --static void pcibios_fixup_resources(struct pci_dev* dev); - static void fixup_broken_pcnet32(struct pci_dev* dev); --static int reparent_resources(struct resource *parent, struct resource *res); - static void fixup_cpc710_pci64(struct pci_dev* dev); - #ifdef CONFIG_PPC_OF - static u8* pci_to_OF_bus_map; -@@ -53,7 +47,7 @@ static u8* pci_to_OF_bus_map; - /* By default, we don't re-assign bus numbers. We do this only on - * some pmacs - */ --int pci_assign_all_buses; -+static int pci_assign_all_buses; - - LIST_HEAD(hose_list); - -@@ -100,505 +94,6 @@ fixup_cpc710_pci64(struct pci_dev* dev) - } - DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CPC710_PCI64, fixup_cpc710_pci64); - --static void --pcibios_fixup_resources(struct pci_dev *dev) --{ -- struct pci_controller* hose = (struct pci_controller *)dev->sysdata; -- int i; -- unsigned long offset; -- -- if (!hose) { -- printk(KERN_ERR "No hose for PCI dev %s!\n", pci_name(dev)); -- return; -- } -- for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { -- struct resource *res = dev->resource + i; -- if (!res->flags) -- continue; -- if (res->end == 0xffffffff) { -- DBG("PCI:%s Resource %d [%016llx-%016llx] is unassigned\n", -- pci_name(dev), i, (u64)res->start, (u64)res->end); -- res->end -= res->start; -- res->start = 0; -- res->flags |= IORESOURCE_UNSET; -- continue; -- } -- offset = 0; -- if (res->flags & IORESOURCE_MEM) { -- offset = hose->pci_mem_offset; -- } else if (res->flags & IORESOURCE_IO) { -- offset = (unsigned long) hose->io_base_virt -- - isa_io_base; -- } -- if (offset != 0) { -- res->start += offset; -- res->end += offset; -- DBG("Fixup res %d (%lx) of dev %s: %llx -> %llx\n", -- i, res->flags, pci_name(dev), -- (u64)res->start - offset, (u64)res->start); -- } -- } -- -- /* Call machine specific resource fixup */ -- if (ppc_md.pcibios_fixup_resources) -- ppc_md.pcibios_fixup_resources(dev); --} --DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_resources); -- --void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, -- struct resource *res) --{ -- unsigned long offset = 0; -- struct pci_controller *hose = dev->sysdata; -- -- if (hose && res->flags & IORESOURCE_IO) -- offset = (unsigned long)hose->io_base_virt - isa_io_base; -- else if (hose && res->flags & IORESOURCE_MEM) -- offset = hose->pci_mem_offset; -- region->start = res->start - offset; -- region->end = res->end - offset; --} --EXPORT_SYMBOL(pcibios_resource_to_bus); -- --void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, -- struct pci_bus_region *region) --{ -- unsigned long offset = 0; -- struct pci_controller *hose = dev->sysdata; -- -- if (hose && res->flags & IORESOURCE_IO) -- offset = (unsigned long)hose->io_base_virt - isa_io_base; -- else if (hose && res->flags & IORESOURCE_MEM) -- offset = hose->pci_mem_offset; -- res->start = region->start + offset; -- res->end = region->end + offset; --} --EXPORT_SYMBOL(pcibios_bus_to_resource); -- --/* -- * We need to avoid collisions with `mirrored' VGA ports -- * and other strange ISA hardware, so we always want the -- * addresses to be allocated in the 0x000-0x0ff region -- * modulo 0x400. -- * -- * Why? Because some silly external IO cards only decode -- * the low 10 bits of the IO address. The 0x00-0xff region -- * is reserved for motherboard devices that decode all 16 -- * bits, so it's ok to allocate at, say, 0x2800-0x28ff, -- * but we want to try to avoid allocating at 0x2900-0x2bff -- * which might have be mirrored at 0x0100-0x03ff.. -- */ --void pcibios_align_resource(void *data, struct resource *res, -- resource_size_t size, resource_size_t align) --{ -- struct pci_dev *dev = data; -- -- if (res->flags & IORESOURCE_IO) { -- resource_size_t start = res->start; -- -- if (size > 0x100) { -- printk(KERN_ERR "PCI: I/O Region %s/%d too large" -- " (%lld bytes)\n", pci_name(dev), -- dev->resource - res, (unsigned long long)size); -- } -- -- if (start & 0x300) { -- start = (start + 0x3ff) & ~0x3ff; -- res->start = start; -- } -- } --} --EXPORT_SYMBOL(pcibios_align_resource); -- --/* -- * Handle resources of PCI devices. If the world were perfect, we could -- * just allocate all the resource regions and do nothing more. It isn't. -- * On the other hand, we cannot just re-allocate all devices, as it would -- * require us to know lots of host bridge internals. So we attempt to -- * keep as much of the original configuration as possible, but tweak it -- * when it's found to be wrong. -- * -- * Known BIOS problems we have to work around: -- * - I/O or memory regions not configured -- * - regions configured, but not enabled in the command register -- * - bogus I/O addresses above 64K used -- * - expansion ROMs left enabled (this may sound harmless, but given -- * the fact the PCI specs explicitly allow address decoders to be -- * shared between expansion ROMs and other resource regions, it's -- * at least dangerous) -- * -- * Our solution: -- * (1) Allocate resources for all buses behind PCI-to-PCI bridges. -- * This gives us fixed barriers on where we can allocate. -- * (2) Allocate resources for all enabled devices. If there is -- * a collision, just mark the resource as unallocated. Also -- * disable expansion ROMs during this step. -- * (3) Try to allocate resources for disabled devices. If the -- * resources were assigned correctly, everything goes well, -- * if they weren't, they won't disturb allocation of other -- * resources. -- * (4) Assign new addresses to resources which were either -- * not configured at all or misconfigured. If explicitly -- * requested by the user, configure expansion ROM address -- * as well. -- */ -- --static void __init --pcibios_allocate_bus_resources(struct list_head *bus_list) --{ -- struct pci_bus *bus; -- int i; -- struct resource *res, *pr; -- -- /* Depth-First Search on bus tree */ -- list_for_each_entry(bus, bus_list, node) { -- for (i = 0; i < 4; ++i) { -- if ((res = bus->resource[i]) == NULL || !res->flags -- || res->start > res->end) -- continue; -- if (bus->parent == NULL) -- pr = (res->flags & IORESOURCE_IO)? -- &ioport_resource: &iomem_resource; -- else { -- pr = pci_find_parent_resource(bus->self, res); -- if (pr == res) { -- /* this happens when the generic PCI -- * code (wrongly) decides that this -- * bridge is transparent -- paulus -- */ -- continue; -- } -- } -- -- DBG("PCI: bridge rsrc %llx..%llx (%lx), parent %p\n", -- (u64)res->start, (u64)res->end, res->flags, pr); -- if (pr) { -- if (request_resource(pr, res) == 0) -- continue; -- /* -- * Must be a conflict with an existing entry. -- * Move that entry (or entries) under the -- * bridge resource and try again. -- */ -- if (reparent_resources(pr, res) == 0) -- continue; -- } -- printk(KERN_ERR "PCI: Cannot allocate resource region " -- "%d of PCI bridge %d\n", i, bus->number); -- if (pci_relocate_bridge_resource(bus, i)) -- bus->resource[i] = NULL; -- } -- pcibios_allocate_bus_resources(&bus->children); -- } --} -- --/* -- * Reparent resource children of pr that conflict with res -- * under res, and make res replace those children. -- */ --static int __init --reparent_resources(struct resource *parent, struct resource *res) --{ -- struct resource *p, **pp; -- struct resource **firstpp = NULL; -- -- for (pp = &parent->child; (p = *pp) != NULL; pp = &p->sibling) { -- if (p->end < res->start) -- continue; -- if (res->end < p->start) -- break; -- if (p->start < res->start || p->end > res->end) -- return -1; /* not completely contained */ -- if (firstpp == NULL) -- firstpp = pp; -- } -- if (firstpp == NULL) -- return -1; /* didn't find any conflicting entries? */ -- res->parent = parent; -- res->child = *firstpp; -- res->sibling = *pp; -- *firstpp = res; -- *pp = NULL; -- for (p = res->child; p != NULL; p = p->sibling) { -- p->parent = res; -- DBG(KERN_INFO "PCI: reparented %s [%llx..%llx] under %s\n", -- p->name, (u64)p->start, (u64)p->end, res->name); -- } -- return 0; --} -- --/* -- * A bridge has been allocated a range which is outside the range -- * of its parent bridge, so it needs to be moved. -- */ --static int __init --pci_relocate_bridge_resource(struct pci_bus *bus, int i) --{ -- struct resource *res, *pr, *conflict; -- unsigned long try, size; -- int j; -- struct pci_bus *parent = bus->parent; -- -- if (parent == NULL) { -- /* shouldn't ever happen */ -- printk(KERN_ERR "PCI: can't move host bridge resource\n"); -- return -1; -- } -- res = bus->resource[i]; -- if (res == NULL) -- return -1; -- pr = NULL; -- for (j = 0; j < 4; j++) { -- struct resource *r = parent->resource[j]; -- if (!r) -- continue; -- if ((res->flags ^ r->flags) & (IORESOURCE_IO | IORESOURCE_MEM)) -- continue; -- if (!((res->flags ^ r->flags) & IORESOURCE_PREFETCH)) { -- pr = r; -- break; -- } -- if (res->flags & IORESOURCE_PREFETCH) -- pr = r; -- } -- if (pr == NULL) -- return -1; -- size = res->end - res->start; -- if (pr->start > pr->end || size > pr->end - pr->start) -- return -1; -- try = pr->end; -- for (;;) { -- res->start = try - size; -- res->end = try; -- if (probe_resource(bus->parent, pr, res, &conflict) == 0) -- break; -- if (conflict->start <= pr->start + size) -- return -1; -- try = conflict->start - 1; -- } -- if (request_resource(pr, res)) { -- DBG(KERN_ERR "PCI: huh? couldn't move to %llx..%llx\n", -- (u64)res->start, (u64)res->end); -- return -1; /* "can't happen" */ -- } -- update_bridge_base(bus, i); -- printk(KERN_INFO "PCI: bridge %d resource %d moved to %llx..%llx\n", -- bus->number, i, (unsigned long long)res->start, -- (unsigned long long)res->end); -- return 0; --} -- --static int __init --probe_resource(struct pci_bus *parent, struct resource *pr, -- struct resource *res, struct resource **conflict) --{ -- struct pci_bus *bus; -- struct pci_dev *dev; -- struct resource *r; -- int i; -- -- for (r = pr->child; r != NULL; r = r->sibling) { -- if (r->end >= res->start && res->end >= r->start) { -- *conflict = r; -- return 1; -- } -- } -- list_for_each_entry(bus, &parent->children, node) { -- for (i = 0; i < 4; ++i) { -- if ((r = bus->resource[i]) == NULL) -- continue; -- if (!r->flags || r->start > r->end || r == res) -- continue; -- if (pci_find_parent_resource(bus->self, r) != pr) -- continue; -- if (r->end >= res->start && res->end >= r->start) { -- *conflict = r; -- return 1; -- } -- } -- } -- list_for_each_entry(dev, &parent->devices, bus_list) { -- for (i = 0; i < 6; ++i) { -- r = &dev->resource[i]; -- if (!r->flags || (r->flags & IORESOURCE_UNSET)) -- continue; -- if (pci_find_parent_resource(dev, r) != pr) -- continue; -- if (r->end >= res->start && res->end >= r->start) { -- *conflict = r; -- return 1; -- } -- } -- } -- return 0; --} -- --void __init --update_bridge_resource(struct pci_dev *dev, struct resource *res) --{ -- u8 io_base_lo, io_limit_lo; -- u16 mem_base, mem_limit; -- u16 cmd; -- unsigned long start, end, off; -- struct pci_controller *hose = dev->sysdata; -- -- if (!hose) { -- printk("update_bridge_base: no hose?\n"); -- return; -- } -- pci_read_config_word(dev, PCI_COMMAND, &cmd); -- pci_write_config_word(dev, PCI_COMMAND, -- cmd & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY)); -- if (res->flags & IORESOURCE_IO) { -- off = (unsigned long) hose->io_base_virt - isa_io_base; -- start = res->start - off; -- end = res->end - off; -- io_base_lo = (start >> 8) & PCI_IO_RANGE_MASK; -- io_limit_lo = (end >> 8) & PCI_IO_RANGE_MASK; -- if (end > 0xffff) -- io_base_lo |= PCI_IO_RANGE_TYPE_32; -- else -- io_base_lo |= PCI_IO_RANGE_TYPE_16; -- pci_write_config_word(dev, PCI_IO_BASE_UPPER16, -- start >> 16); -- pci_write_config_word(dev, PCI_IO_LIMIT_UPPER16, -- end >> 16); -- pci_write_config_byte(dev, PCI_IO_BASE, io_base_lo); -- pci_write_config_byte(dev, PCI_IO_LIMIT, io_limit_lo); -- -- } else if ((res->flags & (IORESOURCE_MEM | IORESOURCE_PREFETCH)) -- == IORESOURCE_MEM) { -- off = hose->pci_mem_offset; -- mem_base = ((res->start - off) >> 16) & PCI_MEMORY_RANGE_MASK; -- mem_limit = ((res->end - off) >> 16) & PCI_MEMORY_RANGE_MASK; -- pci_write_config_word(dev, PCI_MEMORY_BASE, mem_base); -- pci_write_config_word(dev, PCI_MEMORY_LIMIT, mem_limit); -- -- } else if ((res->flags & (IORESOURCE_MEM | IORESOURCE_PREFETCH)) -- == (IORESOURCE_MEM | IORESOURCE_PREFETCH)) { -- off = hose->pci_mem_offset; -- mem_base = ((res->start - off) >> 16) & PCI_PREF_RANGE_MASK; -- mem_limit = ((res->end - off) >> 16) & PCI_PREF_RANGE_MASK; -- pci_write_config_word(dev, PCI_PREF_MEMORY_BASE, mem_base); -- pci_write_config_word(dev, PCI_PREF_MEMORY_LIMIT, mem_limit); -- -- } else { -- DBG(KERN_ERR "PCI: ugh, bridge %s res has flags=%lx\n", -- pci_name(dev), res->flags); -- } -- pci_write_config_word(dev, PCI_COMMAND, cmd); --} -- --static void __init --update_bridge_base(struct pci_bus *bus, int i) --{ -- struct resource *res = bus->resource[i]; -- struct pci_dev *dev = bus->self; -- update_bridge_resource(dev, res); --} -- --static inline void alloc_resource(struct pci_dev *dev, int idx) --{ -- struct resource *pr, *r = &dev->resource[idx]; -- -- DBG("PCI:%s: Resource %d: %016llx-%016llx (f=%lx)\n", -- pci_name(dev), idx, (u64)r->start, (u64)r->end, r->flags); -- pr = pci_find_parent_resource(dev, r); -- if (!pr || request_resource(pr, r) < 0) { -- printk(KERN_ERR "PCI: Cannot allocate resource region %d" -- " of device %s\n", idx, pci_name(dev)); -- if (pr) -- DBG("PCI: parent is %p: %016llx-%016llx (f=%lx)\n", -- pr, (u64)pr->start, (u64)pr->end, pr->flags); -- /* We'll assign a new address later */ -- r->flags |= IORESOURCE_UNSET; -- r->end -= r->start; -- r->start = 0; -- } --} -- --static void __init --pcibios_allocate_resources(int pass) --{ -- struct pci_dev *dev = NULL; -- int idx, disabled; -- u16 command; -- struct resource *r; -- -- for_each_pci_dev(dev) { -- pci_read_config_word(dev, PCI_COMMAND, &command); -- for (idx = 0; idx < 6; idx++) { -- r = &dev->resource[idx]; -- if (r->parent) /* Already allocated */ -- continue; -- if (!r->flags || (r->flags & IORESOURCE_UNSET)) -- continue; /* Not assigned at all */ -- if (r->flags & IORESOURCE_IO) -- disabled = !(command & PCI_COMMAND_IO); -- else -- disabled = !(command & PCI_COMMAND_MEMORY); -- if (pass == disabled) -- alloc_resource(dev, idx); -- } -- if (pass) -- continue; -- r = &dev->resource[PCI_ROM_RESOURCE]; -- if (r->flags & IORESOURCE_ROM_ENABLE) { -- /* Turn the ROM off, leave the resource region, but keep it unregistered. */ -- u32 reg; -- DBG("PCI: Switching off ROM of %s\n", pci_name(dev)); -- r->flags &= ~IORESOURCE_ROM_ENABLE; -- pci_read_config_dword(dev, dev->rom_base_reg, ®); -- pci_write_config_dword(dev, dev->rom_base_reg, -- reg & ~PCI_ROM_ADDRESS_ENABLE); -- } -- } --} -- --static void __init --pcibios_assign_resources(void) --{ -- struct pci_dev *dev = NULL; -- int idx; -- struct resource *r; -- -- for_each_pci_dev(dev) { -- int class = dev->class >> 8; -- -- /* Don't touch classless devices and host bridges */ -- if (!class || class == PCI_CLASS_BRIDGE_HOST) -- continue; -- -- for (idx = 0; idx < 6; idx++) { -- r = &dev->resource[idx]; -- -- /* -- * We shall assign a new address to this resource, -- * either because the BIOS (sic) forgot to do so -- * or because we have decided the old address was -- * unusable for some reason. -- */ -- if ((r->flags & IORESOURCE_UNSET) && r->end && -- (!ppc_md.pcibios_enable_device_hook || -- !ppc_md.pcibios_enable_device_hook(dev, 1))) { -- int rc; -- -- r->flags &= ~IORESOURCE_UNSET; -- rc = pci_assign_resource(dev, idx); -- BUG_ON(rc); -- } -- } -- --#if 0 /* don't assign ROMs */ -- r = &dev->resource[PCI_ROM_RESOURCE]; -- r->end -= r->start; -- r->start = 0; -- if (r->end) -- pci_assign_resource(dev, PCI_ROM_RESOURCE); --#endif -- } --} -- - #ifdef CONFIG_PPC_OF - /* - * Functions below are used on OpenFirmware machines. -@@ -619,7 +114,7 @@ make_one_node_map(struct device_node* no - } else - pci_to_OF_bus_map[pci_bus] = bus_range[0]; - -- for (node=node->child; node != 0;node = node->sibling) { -+ for_each_child_of_node(node, node) { - struct pci_dev* dev; - const unsigned int *class_code, *reg; - -@@ -662,8 +157,8 @@ pcibios_make_OF_bus_map(void) - - /* For each hose, we begin searching bridges */ - list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { -- struct device_node* node; -- node = (struct device_node *)hose->arch_data; -+ struct device_node* node = hose->dn; -+ - if (!node) - continue; - make_one_node_map(node, hose->first_busno); -@@ -688,15 +183,18 @@ pcibios_make_OF_bus_map(void) - typedef int (*pci_OF_scan_iterator)(struct device_node* node, void* data); - - static struct device_node* --scan_OF_pci_childs(struct device_node* node, pci_OF_scan_iterator filter, void* data) -+scan_OF_pci_childs(struct device_node *parent, pci_OF_scan_iterator filter, void* data) - { -+ struct device_node *node; - struct device_node* sub_node; - -- for (; node != 0;node = node->sibling) { -+ for_each_child_of_node(parent, node) { - const unsigned int *class_code; - -- if (filter(node, data)) -+ if (filter(node, data)) { -+ of_node_put(node); - return node; -+ } - - /* For PCI<->PCI bridges or CardBus bridges, we go down - * Note: some OFs create a parent node "multifunc-device" as -@@ -708,9 +206,11 @@ scan_OF_pci_childs(struct device_node* n - (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) && - strcmp(node->name, "multifunc-device")) - continue; -- sub_node = scan_OF_pci_childs(node->child, filter, data); -- if (sub_node) -+ sub_node = scan_OF_pci_childs(node, filter, data); -+ if (sub_node) { -+ of_node_put(node); - return sub_node; -+ } - } - return NULL; - } -@@ -718,11 +218,11 @@ scan_OF_pci_childs(struct device_node* n - static struct device_node *scan_OF_for_pci_dev(struct device_node *parent, - unsigned int devfn) - { -- struct device_node *np = NULL; -+ struct device_node *np; - const u32 *reg; - unsigned int psize; - -- while ((np = of_get_next_child(parent, np)) != NULL) { -+ for_each_child_of_node(parent, np) { - reg = of_get_property(np, "reg", &psize); - if (reg == NULL || psize < 4) - continue; -@@ -742,7 +242,7 @@ static struct device_node *scan_OF_for_p - struct pci_controller *hose = pci_bus_to_host(bus); - if (hose == NULL) - return NULL; -- return of_node_get(hose->arch_data); -+ return of_node_get(hose->dn); - } - - /* not a root bus, we need to get our parent */ -@@ -812,9 +312,9 @@ pci_device_from_OF_node(struct device_no - return -ENODEV; - /* Make sure it's really a PCI device */ - hose = pci_find_hose_for_OF_device(node); -- if (!hose || !hose->arch_data) -+ if (!hose || !hose->dn) - return -ENODEV; -- if (!scan_OF_pci_childs(((struct device_node*)hose->arch_data)->child, -+ if (!scan_OF_pci_childs(hose->dn, - find_OF_pci_device_filter, (void *)node)) - return -ENODEV; - reg = of_get_property(node, "reg", NULL); -@@ -843,120 +343,6 @@ pci_device_from_OF_node(struct device_no - } - EXPORT_SYMBOL(pci_device_from_OF_node); - --void __init --pci_process_bridge_OF_ranges(struct pci_controller *hose, -- struct device_node *dev, int primary) --{ -- static unsigned int static_lc_ranges[256] __initdata; -- const unsigned int *dt_ranges; -- unsigned int *lc_ranges, *ranges, *prev, size; -- int rlen = 0, orig_rlen; -- int memno = 0; -- struct resource *res; -- int np, na = of_n_addr_cells(dev); -- np = na + 5; -- -- /* First we try to merge ranges to fix a problem with some pmacs -- * that can have more than 3 ranges, fortunately using contiguous -- * addresses -- BenH -- */ -- dt_ranges = of_get_property(dev, "ranges", &rlen); -- if (!dt_ranges) -- return; -- /* Sanity check, though hopefully that never happens */ -- if (rlen > sizeof(static_lc_ranges)) { -- printk(KERN_WARNING "OF ranges property too large !\n"); -- rlen = sizeof(static_lc_ranges); -- } -- lc_ranges = static_lc_ranges; -- memcpy(lc_ranges, dt_ranges, rlen); -- orig_rlen = rlen; -- -- /* Let's work on a copy of the "ranges" property instead of damaging -- * the device-tree image in memory -- */ -- ranges = lc_ranges; -- prev = NULL; -- while ((rlen -= np * sizeof(unsigned int)) >= 0) { -- if (prev) { -- if (prev[0] == ranges[0] && prev[1] == ranges[1] && -- (prev[2] + prev[na+4]) == ranges[2] && -- (prev[na+2] + prev[na+4]) == ranges[na+2]) { -- prev[na+4] += ranges[na+4]; -- ranges[0] = 0; -- ranges += np; -- continue; -- } -- } -- prev = ranges; -- ranges += np; -- } -- -- /* -- * The ranges property is laid out as an array of elements, -- * each of which comprises: -- * cells 0 - 2: a PCI address -- * cells 3 or 3+4: a CPU physical address -- * (size depending on dev->n_addr_cells) -- * cells 4+5 or 5+6: the size of the range -- */ -- ranges = lc_ranges; -- rlen = orig_rlen; -- while (ranges && (rlen -= np * sizeof(unsigned int)) >= 0) { -- res = NULL; -- size = ranges[na+4]; -- switch ((ranges[0] >> 24) & 0x3) { -- case 1: /* I/O space */ -- if (ranges[2] != 0) -- break; -- hose->io_base_phys = ranges[na+2]; -- /* limit I/O space to 16MB */ -- if (size > 0x01000000) -- size = 0x01000000; -- hose->io_base_virt = ioremap(ranges[na+2], size); -- if (primary) -- isa_io_base = (unsigned long) hose->io_base_virt; -- res = &hose->io_resource; -- res->flags = IORESOURCE_IO; -- res->start = ranges[2]; -- DBG("PCI: IO 0x%llx -> 0x%llx\n", -- (u64)res->start, (u64)res->start + size - 1); -- break; -- case 2: /* memory space */ -- memno = 0; -- if (ranges[1] == 0 && ranges[2] == 0 -- && ranges[na+4] <= (16 << 20)) { -- /* 1st 16MB, i.e. ISA memory area */ -- if (primary) -- isa_mem_base = ranges[na+2]; -- memno = 1; -- } -- while (memno < 3 && hose->mem_resources[memno].flags) -- ++memno; -- if (memno == 0) -- hose->pci_mem_offset = ranges[na+2] - ranges[2]; -- if (memno < 3) { -- res = &hose->mem_resources[memno]; -- res->flags = IORESOURCE_MEM; -- if(ranges[0] & 0x40000000) -- res->flags |= IORESOURCE_PREFETCH; -- res->start = ranges[na+2]; -- DBG("PCI: MEM[%d] 0x%llx -> 0x%llx\n", memno, -- (u64)res->start, (u64)res->start + size - 1); -- } -- break; -- } -- if (res != NULL) { -- res->name = dev->full_name; -- res->end = res->start + size - 1; -- res->parent = NULL; -- res->sibling = NULL; -- res->child = NULL; -- } -- ranges += np; -- } --} -- - /* We create the "pci-OF-bus-map" property now so it appears in the - * /proc device tree - */ -@@ -986,219 +372,7 @@ void pcibios_make_OF_bus_map(void) - } - #endif /* CONFIG_PPC_OF */ - --#ifdef CONFIG_PPC_PMAC --/* -- * This set of routines checks for PCI<->PCI bridges that have closed -- * IO resources and have child devices. It tries to re-open an IO -- * window on them. -- * -- * This is a _temporary_ fix to workaround a problem with Apple's OF -- * closing IO windows on P2P bridges when the OF drivers of cards -- * below this bridge don't claim any IO range (typically ATI or -- * Adaptec). -- * -- * A more complete fix would be to use drivers/pci/setup-bus.c, which -- * involves a working pcibios_fixup_pbus_ranges(), some more care about -- * ordering when creating the host bus resources, and maybe a few more -- * minor tweaks -- */ -- --/* Initialize bridges with base/limit values we have collected */ --static void __init --do_update_p2p_io_resource(struct pci_bus *bus, int enable_vga) --{ -- struct pci_dev *bridge = bus->self; -- struct pci_controller* hose = (struct pci_controller *)bridge->sysdata; -- u32 l; -- u16 w; -- struct resource res; -- -- if (bus->resource[0] == NULL) -- return; -- res = *(bus->resource[0]); -- -- DBG("Remapping Bus %d, bridge: %s\n", bus->number, pci_name(bridge)); -- res.start -= ((unsigned long) hose->io_base_virt - isa_io_base); -- res.end -= ((unsigned long) hose->io_base_virt - isa_io_base); -- DBG(" IO window: %016llx-%016llx\n", res.start, res.end); -- -- /* Set up the top and bottom of the PCI I/O segment for this bus. */ -- pci_read_config_dword(bridge, PCI_IO_BASE, &l); -- l &= 0xffff000f; -- l |= (res.start >> 8) & 0x00f0; -- l |= res.end & 0xf000; -- pci_write_config_dword(bridge, PCI_IO_BASE, l); -- -- if ((l & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32) { -- l = (res.start >> 16) | (res.end & 0xffff0000); -- pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, l); -- } -- -- pci_read_config_word(bridge, PCI_COMMAND, &w); -- w |= PCI_COMMAND_IO; -- pci_write_config_word(bridge, PCI_COMMAND, w); -- --#if 0 /* Enabling this causes XFree 4.2.0 to hang during PCI probe */ -- if (enable_vga) { -- pci_read_config_word(bridge, PCI_BRIDGE_CONTROL, &w); -- w |= PCI_BRIDGE_CTL_VGA; -- pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, w); -- } --#endif --} -- --/* This function is pretty basic and actually quite broken for the -- * general case, it's enough for us right now though. It's supposed -- * to tell us if we need to open an IO range at all or not and what -- * size. -- */ --static int __init --check_for_io_childs(struct pci_bus *bus, struct resource* res, int *found_vga) --{ -- struct pci_dev *dev; -- int i; -- int rc = 0; -- --#define push_end(res, mask) do { \ -- BUG_ON((mask+1) & mask); \ -- res->end = (res->end + mask) | mask; \ --} while (0) -- -- list_for_each_entry(dev, &bus->devices, bus_list) { -- u16 class = dev->class >> 8; -- -- if (class == PCI_CLASS_DISPLAY_VGA || -- class == PCI_CLASS_NOT_DEFINED_VGA) -- *found_vga = 1; -- if (class >> 8 == PCI_BASE_CLASS_BRIDGE && dev->subordinate) -- rc |= check_for_io_childs(dev->subordinate, res, found_vga); -- if (class == PCI_CLASS_BRIDGE_CARDBUS) -- push_end(res, 0xfff); -- -- for (i=0; iclass >> 8 == PCI_CLASS_BRIDGE_PCI -- && i >= PCI_BRIDGE_RESOURCES) -- continue; -- r = &dev->resource[i]; -- r_size = r->end - r->start; -- if (r_size < 0xfff) -- r_size = 0xfff; -- if (r->flags & IORESOURCE_IO && (r_size) != 0) { -- rc = 1; -- push_end(res, r_size); -- } -- } -- } -- -- return rc; --} -- --/* Here we scan all P2P bridges of a given level that have a closed -- * IO window. Note that the test for the presence of a VGA card should -- * be improved to take into account already configured P2P bridges, -- * currently, we don't see them and might end up configuring 2 bridges -- * with VGA pass through enabled -- */ --static void __init --do_fixup_p2p_level(struct pci_bus *bus) --{ -- struct pci_bus *b; -- int i, parent_io; -- int has_vga = 0; -- -- for (parent_io=0; parent_io<4; parent_io++) -- if (bus->resource[parent_io] -- && bus->resource[parent_io]->flags & IORESOURCE_IO) -- break; -- if (parent_io >= 4) -- return; -- -- list_for_each_entry(b, &bus->children, node) { -- struct pci_dev *d = b->self; -- struct pci_controller* hose = (struct pci_controller *)d->sysdata; -- struct resource *res = b->resource[0]; -- struct resource tmp_res; -- unsigned long max; -- int found_vga = 0; -- -- memset(&tmp_res, 0, sizeof(tmp_res)); -- tmp_res.start = bus->resource[parent_io]->start; -- -- /* We don't let low addresses go through that closed P2P bridge, well, -- * that may not be necessary but I feel safer that way -- */ -- if (tmp_res.start == 0) -- tmp_res.start = 0x1000; -- -- if (!list_empty(&b->devices) && res && res->flags == 0 && -- res != bus->resource[parent_io] && -- (d->class >> 8) == PCI_CLASS_BRIDGE_PCI && -- check_for_io_childs(b, &tmp_res, &found_vga)) { -- u8 io_base_lo; -- -- printk(KERN_INFO "Fixing up IO bus %s\n", b->name); -- -- if (found_vga) { -- if (has_vga) { -- printk(KERN_WARNING "Skipping VGA, already active" -- " on bus segment\n"); -- found_vga = 0; -- } else -- has_vga = 1; -- } -- pci_read_config_byte(d, PCI_IO_BASE, &io_base_lo); -- -- if ((io_base_lo & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32) -- max = ((unsigned long) hose->io_base_virt -- - isa_io_base) + 0xffffffff; -- else -- max = ((unsigned long) hose->io_base_virt -- - isa_io_base) + 0xffff; -- -- *res = tmp_res; -- res->flags = IORESOURCE_IO; -- res->name = b->name; -- -- /* Find a resource in the parent where we can allocate */ -- for (i = 0 ; i < 4; i++) { -- struct resource *r = bus->resource[i]; -- if (!r) -- continue; -- if ((r->flags & IORESOURCE_IO) == 0) -- continue; -- DBG("Trying to allocate from %016llx, size %016llx from parent" -- " res %d: %016llx -> %016llx\n", -- res->start, res->end, i, r->start, r->end); -- -- if (allocate_resource(r, res, res->end + 1, res->start, max, -- res->end + 1, NULL, NULL) < 0) { -- DBG("Failed !\n"); -- continue; -- } -- do_update_p2p_io_resource(b, found_vga); -- break; -- } -- } -- do_fixup_p2p_level(b); -- } --} -- --static void --pcibios_fixup_p2p_bridges(void) --{ -- struct pci_bus *b; -- -- list_for_each_entry(b, &pci_root_buses, node) -- do_fixup_p2p_level(b); --} -- --#endif /* CONFIG_PPC_PMAC */ -- --static int __init --pcibios_init(void) -+static int __init pcibios_init(void) - { - struct pci_controller *hose, *tmp; - struct pci_bus *bus; -@@ -1206,6 +380,9 @@ pcibios_init(void) - - printk(KERN_INFO "PCI: Probing PCI hardware\n"); - -+ if (ppc_pci_flags & PPC_PCI_REASSIGN_ALL_BUS) -+ pci_assign_all_buses = 1; -+ - /* Scan all of the recorded PCI controllers. */ - list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { - if (pci_assign_all_buses) -@@ -1213,9 +390,10 @@ pcibios_init(void) - hose->last_busno = 0xff; - bus = pci_scan_bus_parented(hose->parent, hose->first_busno, - hose->ops, hose); -- if (bus) -+ if (bus) { - pci_bus_add_devices(bus); -- hose->last_busno = bus->subordinate; -+ hose->last_busno = bus->subordinate; -+ } - if (pci_assign_all_buses || next_busno <= hose->last_busno) - next_busno = hose->last_busno + pcibios_assign_bus_offset; - } -@@ -1228,18 +406,8 @@ pcibios_init(void) - if (pci_assign_all_buses && have_of) - pcibios_make_OF_bus_map(); - -- /* Call machine dependent fixup */ -- if (ppc_md.pcibios_fixup) -- ppc_md.pcibios_fixup(); -- -- /* Allocate and assign resources */ -- pcibios_allocate_bus_resources(&pci_root_buses); -- pcibios_allocate_resources(0); -- pcibios_allocate_resources(1); --#ifdef CONFIG_PPC_PMAC -- pcibios_fixup_p2p_bridges(); --#endif /* CONFIG_PPC_PMAC */ -- pcibios_assign_resources(); -+ /* Call common code to handle resource allocation */ -+ pcibios_resource_survey(); - - /* Call machine dependent post-init code */ - if (ppc_md.pcibios_after_init) -@@ -1250,14 +418,14 @@ pcibios_init(void) - - subsys_initcall(pcibios_init); - --void pcibios_fixup_bus(struct pci_bus *bus) -+void __devinit pcibios_do_bus_setup(struct pci_bus *bus) - { - struct pci_controller *hose = (struct pci_controller *) bus->sysdata; - unsigned long io_offset; - struct resource *res; -- struct pci_dev *dev; - int i; - -+ /* Hookup PHB resources */ - io_offset = (unsigned long)hose->io_base_virt - isa_io_base; - if (bus->parent == NULL) { - /* This is a host bridge - fill in its resources */ -@@ -1272,8 +440,8 @@ void pcibios_fixup_bus(struct pci_bus *b - res->end = IO_SPACE_LIMIT; - res->flags = IORESOURCE_IO; - } -- res->start += io_offset; -- res->end += io_offset; -+ res->start = (res->start + io_offset) & 0xffffffffu; -+ res->end = (res->end + io_offset) & 0xffffffffu; - - for (i = 0; i < 3; ++i) { - res = &hose->mem_resources[i]; -@@ -1288,35 +456,6 @@ void pcibios_fixup_bus(struct pci_bus *b - } - bus->resource[i+1] = res; - } -- } else { -- /* This is a subordinate bridge */ -- pci_read_bridge_bases(bus); -- -- for (i = 0; i < 4; ++i) { -- if ((res = bus->resource[i]) == NULL) -- continue; -- if (!res->flags || bus->self->transparent) -- continue; -- if (io_offset && (res->flags & IORESOURCE_IO)) { -- res->start += io_offset; -- res->end += io_offset; -- } else if (hose->pci_mem_offset -- && (res->flags & IORESOURCE_MEM)) { -- res->start += hose->pci_mem_offset; -- res->end += hose->pci_mem_offset; -- } -- } -- } -- -- /* Platform specific bus fixups */ -- if (ppc_md.pcibios_fixup_bus) -- ppc_md.pcibios_fixup_bus(bus); -- -- /* Read default IRQs and fixup if necessary */ -- list_for_each_entry(dev, &bus->devices, bus_list) { -- pci_read_irq_line(dev); -- if (ppc_md.pci_irq_fixup) -- ppc_md.pci_irq_fixup(dev); - } - } - -@@ -1328,37 +467,6 @@ pcibios_update_irq(struct pci_dev *dev, - /* XXX FIXME - update OF device tree node interrupt property */ - } - --int pcibios_enable_device(struct pci_dev *dev, int mask) --{ -- u16 cmd, old_cmd; -- int idx; -- struct resource *r; -- -- if (ppc_md.pcibios_enable_device_hook) -- if (ppc_md.pcibios_enable_device_hook(dev, 0)) -- return -EINVAL; -- -- pci_read_config_word(dev, PCI_COMMAND, &cmd); -- old_cmd = cmd; -- for (idx=0; idx<6; idx++) { -- r = &dev->resource[idx]; -- if (r->flags & IORESOURCE_UNSET) { -- printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", pci_name(dev)); -- return -EINVAL; -- } -- if (r->flags & IORESOURCE_IO) -- cmd |= PCI_COMMAND_IO; -- if (r->flags & IORESOURCE_MEM) -- cmd |= PCI_COMMAND_MEMORY; -- } -- if (cmd != old_cmd) { -- printk("PCI: Enabling device %s (%04x -> %04x)\n", -- pci_name(dev), old_cmd, cmd); -- pci_write_config_word(dev, PCI_COMMAND, cmd); -- } -- return 0; --} -- - static struct pci_controller* - pci_bus_to_hose(int bus) - { -@@ -1381,17 +489,6 @@ long sys_pciconfig_iobase(long which, un - struct pci_controller* hose; - long result = -EOPNOTSUPP; - -- /* Argh ! Please forgive me for that hack, but that's the -- * simplest way to get existing XFree to not lockup on some -- * G5 machines... So when something asks for bus 0 io base -- * (bus 0 is HT root), we return the AGP one instead. -- */ --#ifdef CONFIG_PPC_PMAC -- if (machine_is(powermac) && machine_is_compatible("MacRISC4")) -- if (bus == 0) -- bus = 0xf0; --#endif /* CONFIG_PPC_PMAC */ -- - hose = pci_bus_to_hose(bus); - if (!hose) - return -ENODEV; ---- a/arch/powerpc/kernel/pci_64.c -+++ b/arch/powerpc/kernel/pci_64.c -@@ -31,7 +31,6 @@ - #include - #include - #include --#include - - #ifdef DEBUG - #include -@@ -41,10 +40,6 @@ - #endif - - unsigned long pci_probe_only = 1; --int pci_assign_all_buses = 0; -- --static void fixup_resource(struct resource *res, struct pci_dev *dev); --static void do_bus_setup(struct pci_bus *bus); - - /* pci_io_base -- the base address from which io bars are offsets. - * This is the lowest I/O base address (so bar values are always positive), -@@ -70,139 +65,31 @@ struct dma_mapping_ops *get_pci_dma_ops( - } - EXPORT_SYMBOL(get_pci_dma_ops); - --static void fixup_broken_pcnet32(struct pci_dev* dev) --{ -- if ((dev->class>>8 == PCI_CLASS_NETWORK_ETHERNET)) { -- dev->vendor = PCI_VENDOR_ID_AMD; -- pci_write_config_word(dev, PCI_VENDOR_ID, PCI_VENDOR_ID_AMD); -- } --} --DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TRIDENT, PCI_ANY_ID, fixup_broken_pcnet32); -- --void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, -- struct resource *res) --{ -- unsigned long offset = 0; -- struct pci_controller *hose = pci_bus_to_host(dev->bus); -- -- if (!hose) -- return; -- -- if (res->flags & IORESOURCE_IO) -- offset = (unsigned long)hose->io_base_virt - _IO_BASE; -- -- if (res->flags & IORESOURCE_MEM) -- offset = hose->pci_mem_offset; -- -- region->start = res->start - offset; -- region->end = res->end - offset; --} - --void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, -- struct pci_bus_region *region) -+int pci_set_dma_mask(struct pci_dev *dev, u64 mask) - { -- unsigned long offset = 0; -- struct pci_controller *hose = pci_bus_to_host(dev->bus); -- -- if (!hose) -- return; -- -- if (res->flags & IORESOURCE_IO) -- offset = (unsigned long)hose->io_base_virt - _IO_BASE; -- -- if (res->flags & IORESOURCE_MEM) -- offset = hose->pci_mem_offset; -- -- res->start = region->start + offset; -- res->end = region->end + offset; -+ return dma_set_mask(&dev->dev, mask); - } - --#ifdef CONFIG_HOTPLUG --EXPORT_SYMBOL(pcibios_resource_to_bus); --EXPORT_SYMBOL(pcibios_bus_to_resource); --#endif -- --/* -- * We need to avoid collisions with `mirrored' VGA ports -- * and other strange ISA hardware, so we always want the -- * addresses to be allocated in the 0x000-0x0ff region -- * modulo 0x400. -- * -- * Why? Because some silly external IO cards only decode -- * the low 10 bits of the IO address. The 0x00-0xff region -- * is reserved for motherboard devices that decode all 16 -- * bits, so it's ok to allocate at, say, 0x2800-0x28ff, -- * but we want to try to avoid allocating at 0x2900-0x2bff -- * which might have be mirrored at 0x0100-0x03ff.. -- */ --void pcibios_align_resource(void *data, struct resource *res, -- resource_size_t size, resource_size_t align) -+int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask) - { -- struct pci_dev *dev = data; -- struct pci_controller *hose = pci_bus_to_host(dev->bus); -- resource_size_t start = res->start; -- unsigned long alignto; -- -- if (res->flags & IORESOURCE_IO) { -- unsigned long offset = (unsigned long)hose->io_base_virt - -- _IO_BASE; -- /* Make sure we start at our min on all hoses */ -- if (start - offset < PCIBIOS_MIN_IO) -- start = PCIBIOS_MIN_IO + offset; -- -- /* -- * Put everything into 0x00-0xff region modulo 0x400 -- */ -- if (start & 0x300) -- start = (start + 0x3ff) & ~0x3ff; -+ int rc; - -- } else if (res->flags & IORESOURCE_MEM) { -- /* Make sure we start at our min on all hoses */ -- if (start - hose->pci_mem_offset < PCIBIOS_MIN_MEM) -- start = PCIBIOS_MIN_MEM + hose->pci_mem_offset; -+ rc = dma_set_mask(&dev->dev, mask); -+ dev->dev.coherent_dma_mask = dev->dma_mask; - -- /* Align to multiple of size of minimum base. */ -- alignto = max(0x1000UL, align); -- start = ALIGN(start, alignto); -- } -- -- res->start = start; -+ return rc; - } - --void __devinit pcibios_claim_one_bus(struct pci_bus *b) -+static void fixup_broken_pcnet32(struct pci_dev* dev) - { -- struct pci_dev *dev; -- struct pci_bus *child_bus; -- -- list_for_each_entry(dev, &b->devices, bus_list) { -- int i; -- -- for (i = 0; i < PCI_NUM_RESOURCES; i++) { -- struct resource *r = &dev->resource[i]; -- -- if (r->parent || !r->start || !r->flags) -- continue; -- pci_claim_resource(dev, i); -- } -+ if ((dev->class>>8 == PCI_CLASS_NETWORK_ETHERNET)) { -+ dev->vendor = PCI_VENDOR_ID_AMD; -+ pci_write_config_word(dev, PCI_VENDOR_ID, PCI_VENDOR_ID_AMD); - } -- -- list_for_each_entry(child_bus, &b->children, node) -- pcibios_claim_one_bus(child_bus); - } --#ifdef CONFIG_HOTPLUG --EXPORT_SYMBOL_GPL(pcibios_claim_one_bus); --#endif -- --static void __init pcibios_claim_of_setup(void) --{ -- struct pci_bus *b; -- -- if (firmware_has_feature(FW_FEATURE_ISERIES)) -- return; -+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TRIDENT, PCI_ANY_ID, fixup_broken_pcnet32); - -- list_for_each_entry(b, &pci_root_buses, node) -- pcibios_claim_one_bus(b); --} - - static u32 get_int_prop(struct device_node *np, const char *name, u32 def) - { -@@ -270,7 +157,6 @@ static void pci_parse_of_addrs(struct de - res->end = base + size - 1; - res->flags = flags; - res->name = pci_name(dev); -- fixup_resource(res, dev); - } - } - -@@ -339,16 +225,17 @@ struct pci_dev *of_create_pci_dev(struct - EXPORT_SYMBOL(of_create_pci_dev); - - void __devinit of_scan_bus(struct device_node *node, -- struct pci_bus *bus) -+ struct pci_bus *bus) - { -- struct device_node *child = NULL; -+ struct device_node *child; - const u32 *reg; - int reglen, devfn; - struct pci_dev *dev; - - DBG("of_scan_bus(%s) bus no %d... \n", node->full_name, bus->number); - -- while ((child = of_get_next_child(node, child)) != NULL) { -+ /* Scan direct children */ -+ for_each_child_of_node(node, child) { - DBG(" * %s\n", child->full_name); - reg = of_get_property(child, "reg", ®len); - if (reg == NULL || reglen < 20) -@@ -359,19 +246,26 @@ void __devinit of_scan_bus(struct device - dev = of_create_pci_dev(child, bus, devfn); - if (!dev) - continue; -- DBG("dev header type: %x\n", dev->hdr_type); -+ DBG(" dev header type: %x\n", dev->hdr_type); -+ } - -+ /* Ally all fixups */ -+ pcibios_fixup_of_probed_bus(bus); -+ -+ /* Now scan child busses */ -+ list_for_each_entry(dev, &bus->devices, bus_list) { - if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || -- dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) -- of_scan_pci_bridge(child, dev); -+ dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) { -+ struct device_node *child = pci_device_to_OF_node(dev); -+ if (dev) -+ of_scan_pci_bridge(child, dev); -+ } - } -- -- do_bus_setup(bus); - } - EXPORT_SYMBOL(of_scan_bus); - - void __devinit of_scan_pci_bridge(struct device_node *node, -- struct pci_dev *dev) -+ struct pci_dev *dev) - { - struct pci_bus *bus; - const u32 *busrange, *ranges; -@@ -441,7 +335,6 @@ void __devinit of_scan_pci_bridge(struct - res->start = of_read_number(&ranges[1], 2); - res->end = res->start + size - 1; - res->flags = flags; -- fixup_resource(res, dev); - } - sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus), - bus->number); -@@ -462,12 +355,12 @@ EXPORT_SYMBOL(of_scan_pci_bridge); - void __devinit scan_phb(struct pci_controller *hose) - { - struct pci_bus *bus; -- struct device_node *node = hose->arch_data; -+ struct device_node *node = hose->dn; - int i, mode; -- struct resource *res; - -- DBG("Scanning PHB %s\n", node ? node->full_name : ""); -+ DBG("PCI: Scanning PHB %s\n", node ? node->full_name : ""); - -+ /* Create an empty bus for the toplevel */ - bus = pci_create_bus(hose->parent, hose->first_busno, hose->ops, node); - if (bus == NULL) { - printk(KERN_ERR "Failed to create bus for PCI domain %04x\n", -@@ -477,27 +370,27 @@ void __devinit scan_phb(struct pci_contr - bus->secondary = hose->first_busno; - hose->bus = bus; - -- if (!firmware_has_feature(FW_FEATURE_ISERIES)) -- pcibios_map_io_space(bus); -- -- bus->resource[0] = res = &hose->io_resource; -- if (res->flags && request_resource(&ioport_resource, res)) { -- printk(KERN_ERR "Failed to request PCI IO region " -- "on PCI domain %04x\n", hose->global_number); -- DBG("res->start = 0x%016lx, res->end = 0x%016lx\n", -- res->start, res->end); -- } -+ /* Get some IO space for the new PHB */ -+ pcibios_map_io_space(bus); - -+ /* Wire up PHB bus resources */ -+ DBG("PCI: PHB IO resource = %016lx-%016lx [%lx]\n", -+ hose->io_resource.start, hose->io_resource.end, -+ hose->io_resource.flags); -+ bus->resource[0] = &hose->io_resource; - for (i = 0; i < 3; ++i) { -- res = &hose->mem_resources[i]; -- bus->resource[i+1] = res; -- if (res->flags && request_resource(&iomem_resource, res)) -- printk(KERN_ERR "Failed to request PCI memory region " -- "on PCI domain %04x\n", hose->global_number); -- } -+ DBG("PCI: PHB MEM resource %d = %016lx-%016lx [%lx]\n", i, -+ hose->mem_resources[i].start, -+ hose->mem_resources[i].end, -+ hose->mem_resources[i].flags); -+ bus->resource[i+1] = &hose->mem_resources[i]; -+ } -+ DBG("PCI: PHB MEM offset = %016lx\n", hose->pci_mem_offset); -+ DBG("PCI: PHB IO offset = %08lx\n", -+ (unsigned long)hose->io_base_virt - _IO_BASE); - -+ /* Get probe mode and perform scan */ - mode = PCI_PROBE_NORMAL; -- - if (node && ppc_md.pci_probe_mode) - mode = ppc_md.pci_probe_mode(bus); - DBG(" probe mode: %d\n", mode); -@@ -514,15 +407,15 @@ static int __init pcibios_init(void) - { - struct pci_controller *hose, *tmp; - -+ printk(KERN_INFO "PCI: Probing PCI hardware\n"); -+ - /* For now, override phys_mem_access_prot. If we need it, - * later, we may move that initialization to each ppc_md - */ - ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot; - -- if (firmware_has_feature(FW_FEATURE_ISERIES)) -- iSeries_pcibios_init(); -- -- printk(KERN_DEBUG "PCI: Probing PCI hardware\n"); -+ if (pci_probe_only) -+ ppc_pci_flags |= PPC_PCI_PROBE_ONLY; - - /* Scan all of the recorded PCI controllers. */ - list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { -@@ -530,19 +423,8 @@ static int __init pcibios_init(void) - pci_bus_add_devices(hose->bus); - } - -- if (!firmware_has_feature(FW_FEATURE_ISERIES)) { -- if (pci_probe_only) -- pcibios_claim_of_setup(); -- else -- /* FIXME: `else' will be removed when -- pci_assign_unassigned_resources() is able to work -- correctly with [partially] allocated PCI tree. */ -- pci_assign_unassigned_resources(); -- } -- -- /* Call machine dependent final fixup */ -- if (ppc_md.pcibios_fixup) -- ppc_md.pcibios_fixup(); -+ /* Call common code to handle resource allocation */ -+ pcibios_resource_survey(); - - printk(KERN_DEBUG "PCI: Probing PCI hardware done\n"); - -@@ -551,141 +433,6 @@ static int __init pcibios_init(void) - - subsys_initcall(pcibios_init); - --int pcibios_enable_device(struct pci_dev *dev, int mask) --{ -- u16 cmd, oldcmd; -- int i; -- -- pci_read_config_word(dev, PCI_COMMAND, &cmd); -- oldcmd = cmd; -- -- for (i = 0; i < PCI_NUM_RESOURCES; i++) { -- struct resource *res = &dev->resource[i]; -- -- /* Only set up the requested stuff */ -- if (!(mask & (1<flags & IORESOURCE_IO) -- cmd |= PCI_COMMAND_IO; -- if (res->flags & IORESOURCE_MEM) -- cmd |= PCI_COMMAND_MEMORY; -- } -- -- if (cmd != oldcmd) { -- printk(KERN_DEBUG "PCI: Enabling device: (%s), cmd %x\n", -- pci_name(dev), cmd); -- /* Enable the appropriate bits in the PCI command register. */ -- pci_write_config_word(dev, PCI_COMMAND, cmd); -- } -- return 0; --} -- --/* Decide whether to display the domain number in /proc */ --int pci_proc_domain(struct pci_bus *bus) --{ -- if (firmware_has_feature(FW_FEATURE_ISERIES)) -- return 0; -- else { -- struct pci_controller *hose = pci_bus_to_host(bus); -- return hose->buid != 0; -- } --} -- --void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose, -- struct device_node *dev, int prim) --{ -- const unsigned int *ranges; -- unsigned int pci_space; -- unsigned long size; -- int rlen = 0; -- int memno = 0; -- struct resource *res; -- int np, na = of_n_addr_cells(dev); -- unsigned long pci_addr, cpu_phys_addr; -- -- np = na + 5; -- -- /* From "PCI Binding to 1275" -- * The ranges property is laid out as an array of elements, -- * each of which comprises: -- * cells 0 - 2: a PCI address -- * cells 3 or 3+4: a CPU physical address -- * (size depending on dev->n_addr_cells) -- * cells 4+5 or 5+6: the size of the range -- */ -- ranges = of_get_property(dev, "ranges", &rlen); -- if (ranges == NULL) -- return; -- hose->io_base_phys = 0; -- while ((rlen -= np * sizeof(unsigned int)) >= 0) { -- res = NULL; -- pci_space = ranges[0]; -- pci_addr = ((unsigned long)ranges[1] << 32) | ranges[2]; -- cpu_phys_addr = of_translate_address(dev, &ranges[3]); -- size = ((unsigned long)ranges[na+3] << 32) | ranges[na+4]; -- ranges += np; -- if (size == 0) -- continue; -- -- /* Now consume following elements while they are contiguous */ -- while (rlen >= np * sizeof(unsigned int)) { -- unsigned long addr, phys; -- -- if (ranges[0] != pci_space) -- break; -- addr = ((unsigned long)ranges[1] << 32) | ranges[2]; -- phys = ranges[3]; -- if (na >= 2) -- phys = (phys << 32) | ranges[4]; -- if (addr != pci_addr + size || -- phys != cpu_phys_addr + size) -- break; -- -- size += ((unsigned long)ranges[na+3] << 32) -- | ranges[na+4]; -- ranges += np; -- rlen -= np * sizeof(unsigned int); -- } -- -- switch ((pci_space >> 24) & 0x3) { -- case 1: /* I/O space */ -- hose->io_base_phys = cpu_phys_addr - pci_addr; -- /* handle from 0 to top of I/O window */ -- hose->pci_io_size = pci_addr + size; -- -- res = &hose->io_resource; -- res->flags = IORESOURCE_IO; -- res->start = pci_addr; -- DBG("phb%d: IO 0x%lx -> 0x%lx\n", hose->global_number, -- res->start, res->start + size - 1); -- break; -- case 2: /* memory space */ -- memno = 0; -- while (memno < 3 && hose->mem_resources[memno].flags) -- ++memno; -- -- if (memno == 0) -- hose->pci_mem_offset = cpu_phys_addr - pci_addr; -- if (memno < 3) { -- res = &hose->mem_resources[memno]; -- res->flags = IORESOURCE_MEM; -- res->start = cpu_phys_addr; -- DBG("phb%d: MEM 0x%lx -> 0x%lx\n", hose->global_number, -- res->start, res->start + size - 1); -- } -- break; -- } -- if (res != NULL) { -- res->name = dev->full_name; -- res->end = res->start + size - 1; -- res->parent = NULL; -- res->sibling = NULL; -- res->child = NULL; -- } -- } --} -- - #ifdef CONFIG_HOTPLUG - - int pcibios_unmap_io_space(struct pci_bus *bus) -@@ -719,8 +466,7 @@ int pcibios_unmap_io_space(struct pci_bu - if (hose->io_base_alloc == 0) - return 0; - -- DBG("IO unmapping for PHB %s\n", -- ((struct device_node *)hose->arch_data)->full_name); -+ DBG("IO unmapping for PHB %s\n", hose->dn->full_name); - DBG(" alloc=0x%p\n", hose->io_base_alloc); - - /* This is a PHB, we fully unmap the IO area */ -@@ -779,8 +525,7 @@ int __devinit pcibios_map_io_space(struc - hose->io_base_virt = (void __iomem *)(area->addr + - hose->io_base_phys - phys_page); - -- DBG("IO mapping for PHB %s\n", -- ((struct device_node *)hose->arch_data)->full_name); -+ DBG("IO mapping for PHB %s\n", hose->dn->full_name); - DBG(" phys=0x%016lx, virt=0x%p (alloc=0x%p)\n", - hose->io_base_phys, hose->io_base_virt, hose->io_base_alloc); - DBG(" size=0x%016lx (alloc=0x%016lx)\n", -@@ -803,51 +548,13 @@ int __devinit pcibios_map_io_space(struc - } - EXPORT_SYMBOL_GPL(pcibios_map_io_space); - --static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev) --{ -- struct pci_controller *hose = pci_bus_to_host(dev->bus); -- unsigned long offset; -- -- if (res->flags & IORESOURCE_IO) { -- offset = (unsigned long)hose->io_base_virt - _IO_BASE; -- res->start += offset; -- res->end += offset; -- } else if (res->flags & IORESOURCE_MEM) { -- res->start += hose->pci_mem_offset; -- res->end += hose->pci_mem_offset; -- } --} -- --void __devinit pcibios_fixup_device_resources(struct pci_dev *dev, -- struct pci_bus *bus) --{ -- /* Update device resources. */ -- int i; -- -- DBG("%s: Fixup resources:\n", pci_name(dev)); -- for (i = 0; i < PCI_NUM_RESOURCES; i++) { -- struct resource *res = &dev->resource[i]; -- if (!res->flags) -- continue; -- -- DBG(" 0x%02x < %08lx:0x%016lx...0x%016lx\n", -- i, res->flags, res->start, res->end); -- -- fixup_resource(res, dev); -- -- DBG(" > %08lx:0x%016lx...0x%016lx\n", -- res->flags, res->start, res->end); -- } --} --EXPORT_SYMBOL(pcibios_fixup_device_resources); -- - void __devinit pcibios_setup_new_device(struct pci_dev *dev) - { - struct dev_archdata *sd = &dev->dev.archdata; - - sd->of_node = pci_device_to_OF_node(dev); - -- DBG("PCI device %s OF node: %s\n", pci_name(dev), -+ DBG("PCI: device %s OF node: %s\n", pci_name(dev), - sd->of_node ? sd->of_node->full_name : ""); - - sd->dma_ops = pci_dma_ops; -@@ -861,7 +568,7 @@ void __devinit pcibios_setup_new_device( - } - EXPORT_SYMBOL(pcibios_setup_new_device); - --static void __devinit do_bus_setup(struct pci_bus *bus) -+void __devinit pcibios_do_bus_setup(struct pci_bus *bus) - { - struct pci_dev *dev; - -@@ -870,42 +577,7 @@ static void __devinit do_bus_setup(struc - - list_for_each_entry(dev, &bus->devices, bus_list) - pcibios_setup_new_device(dev); -- -- /* Read default IRQs and fixup if necessary */ -- list_for_each_entry(dev, &bus->devices, bus_list) { -- pci_read_irq_line(dev); -- if (ppc_md.pci_irq_fixup) -- ppc_md.pci_irq_fixup(dev); -- } --} -- --void __devinit pcibios_fixup_bus(struct pci_bus *bus) --{ -- struct pci_dev *dev = bus->self; -- struct device_node *np; -- -- np = pci_bus_to_OF_node(bus); -- -- DBG("pcibios_fixup_bus(%s)\n", np ? np->full_name : ""); -- -- if (dev && pci_probe_only && -- (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { -- /* This is a subordinate bridge */ -- -- pci_read_bridge_bases(bus); -- pcibios_fixup_device_resources(dev, bus); -- } -- -- do_bus_setup(bus); -- -- if (!pci_probe_only) -- return; -- -- list_for_each_entry(dev, &bus->devices, bus_list) -- if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI) -- pcibios_fixup_device_resources(dev, bus); - } --EXPORT_SYMBOL(pcibios_fixup_bus); - - unsigned long pci_address_to_pio(phys_addr_t address) - { ---- a/arch/powerpc/kernel/pci_dn.c -+++ b/arch/powerpc/kernel/pci_dn.c -@@ -56,11 +56,6 @@ static void * __devinit update_dn_pci_in - pdn->busno = (regs[0] >> 16) & 0xff; - pdn->devfn = (regs[0] >> 8) & 0xff; - } -- if (firmware_has_feature(FW_FEATURE_ISERIES)) { -- const u32 *busp = of_get_property(dn, "linux,subbus", NULL); -- if (busp) -- pdn->bussubno = *busp; -- } - - pdn->pci_ext_config_space = (type && *type == 1); - return NULL; -@@ -133,7 +128,7 @@ void *traverse_pci_devices(struct device - */ - void __devinit pci_devs_phb_init_dynamic(struct pci_controller *phb) - { -- struct device_node * dn = (struct device_node *) phb->arch_data; -+ struct device_node *dn = phb->dn; - struct pci_dn *pdn; - - /* PHB nodes themselves must not match */ ---- a/arch/powerpc/kernel/ppc_ksyms.c -+++ b/arch/powerpc/kernel/ppc_ksyms.c -@@ -59,6 +59,7 @@ extern void single_step_exception(struct - extern int sys_sigreturn(struct pt_regs *regs); - - EXPORT_SYMBOL(clear_pages); -+EXPORT_SYMBOL(copy_page); - EXPORT_SYMBOL(ISA_DMA_THRESHOLD); - EXPORT_SYMBOL(DMA_MODE_READ); - EXPORT_SYMBOL(DMA_MODE_WRITE); ---- a/arch/powerpc/kernel/prom.c -+++ b/arch/powerpc/kernel/prom.c -@@ -583,6 +583,20 @@ static void __init check_cpu_pa_features - ibm_pa_features, ARRAY_SIZE(ibm_pa_features)); - } - -+#ifdef CONFIG_PPC64 -+static void __init check_cpu_slb_size(unsigned long node) -+{ -+ u32 *slb_size_ptr; -+ -+ slb_size_ptr = of_get_flat_dt_prop(node, "ibm,slb-size", NULL); -+ if (slb_size_ptr != NULL) { -+ mmu_slb_size = *slb_size_ptr; -+ } -+} -+#else -+#define check_cpu_slb_size(node) do { } while(0) -+#endif -+ - static struct feature_property { - const char *name; - u32 min_value; -@@ -600,6 +614,29 @@ static struct feature_property { - #endif /* CONFIG_PPC64 */ - }; - -+#if defined(CONFIG_44x) && defined(CONFIG_PPC_FPU) -+static inline void identical_pvr_fixup(unsigned long node) -+{ -+ unsigned int pvr; -+ char *model = of_get_flat_dt_prop(node, "model", NULL); -+ -+ /* -+ * Since 440GR(x)/440EP(x) processors have the same pvr, -+ * we check the node path and set bit 28 in the cur_cpu_spec -+ * pvr for EP(x) processor version. This bit is always 0 in -+ * the "real" pvr. Then we call identify_cpu again with -+ * the new logical pvr to enable FPU support. -+ */ -+ if (model && strstr(model, "440EP")) { -+ pvr = cur_cpu_spec->pvr_value | 0x8; -+ identify_cpu(0, pvr); -+ DBG("Using logical pvr %x for %s\n", pvr, model); -+ } -+} -+#else -+#define identical_pvr_fixup(node) do { } while(0) -+#endif -+ - static void __init check_cpu_feature_properties(unsigned long node) - { - unsigned long i; -@@ -697,22 +734,13 @@ static int __init early_init_dt_scan_cpu - prop = of_get_flat_dt_prop(node, "cpu-version", NULL); - if (prop && (*prop & 0xff000000) == 0x0f000000) - identify_cpu(0, *prop); --#if defined(CONFIG_44x) && defined(CONFIG_PPC_FPU) -- /* -- * Since 440GR(x)/440EP(x) processors have the same pvr, -- * we check the node path and set bit 28 in the cur_cpu_spec -- * pvr for EP(x) processor version. This bit is always 0 in -- * the "real" pvr. Then we call identify_cpu again with -- * the new logical pvr to enable FPU support. -- */ -- if (strstr(uname, "440EP")) { -- identify_cpu(0, cur_cpu_spec->pvr_value | 0x8); -- } --#endif -+ -+ identical_pvr_fixup(node); - } - - check_cpu_feature_properties(node); - check_cpu_pa_features(node); -+ check_cpu_slb_size(node); - - #ifdef CONFIG_PPC_PSERIES - if (nthreads > 1) ---- a/arch/powerpc/kernel/prom_parse.c -+++ b/arch/powerpc/kernel/prom_parse.c -@@ -273,7 +273,7 @@ int of_irq_map_pci(struct pci_dev *pdev, - #else - struct pci_controller *host; - host = pci_bus_to_host(pdev->bus); -- ppnode = host ? host->arch_data : NULL; -+ ppnode = host ? host->dn : NULL; - #endif - /* No node for host bridge ? give up */ - if (ppnode == NULL) -@@ -419,7 +419,7 @@ static struct of_bus *of_match_bus(struc - - static int of_translate_one(struct device_node *parent, struct of_bus *bus, - struct of_bus *pbus, u32 *addr, -- int na, int ns, int pna) -+ int na, int ns, int pna, const char *rprop) - { - const u32 *ranges; - unsigned int rlen; -@@ -438,7 +438,7 @@ static int of_translate_one(struct devic - * to translate addresses that aren't supposed to be translated in - * the first place. --BenH. - */ -- ranges = of_get_property(parent, "ranges", &rlen); -+ ranges = of_get_property(parent, rprop, &rlen); - if (ranges == NULL || rlen == 0) { - offset = of_read_number(addr, na); - memset(addr, 0, pna * 4); -@@ -481,7 +481,8 @@ static int of_translate_one(struct devic - * that can be mapped to a cpu physical address). This is not really specified - * that way, but this is traditionally the way IBM at least do things - */ --u64 of_translate_address(struct device_node *dev, const u32 *in_addr) -+u64 __of_translate_address(struct device_node *dev, const u32 *in_addr, -+ const char *rprop) - { - struct device_node *parent = NULL; - struct of_bus *bus, *pbus; -@@ -540,7 +541,7 @@ u64 of_translate_address(struct device_n - pbus->name, pna, pns, parent->full_name); - - /* Apply bus translation */ -- if (of_translate_one(dev, bus, pbus, addr, na, ns, pna)) -+ if (of_translate_one(dev, bus, pbus, addr, na, ns, pna, rprop)) - break; - - /* Complete the move up one level */ -@@ -556,8 +557,19 @@ u64 of_translate_address(struct device_n - - return result; - } -+ -+u64 of_translate_address(struct device_node *dev, const u32 *in_addr) -+{ -+ return __of_translate_address(dev, in_addr, "ranges"); -+} - EXPORT_SYMBOL(of_translate_address); - -+u64 of_translate_dma_address(struct device_node *dev, const u32 *in_addr) -+{ -+ return __of_translate_address(dev, in_addr, "dma-ranges"); -+} -+EXPORT_SYMBOL(of_translate_dma_address); -+ - const u32 *of_get_address(struct device_node *dev, int index, u64 *size, - unsigned int *flags) - { ---- /dev/null -+++ b/arch/powerpc/kernel/rio.c -@@ -0,0 +1,52 @@ -+/* -+ * RapidIO PPC32 support -+ * -+ * Copyright 2005 MontaVista Software, Inc. -+ * Matt Porter -+ * -+ * 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 -+ -+/** -+ * platform_rio_init - Do platform specific RIO init -+ * -+ * Any platform specific initialization of RapdIO -+ * hardware is done here as well as registration -+ * of any active master ports in the system. -+ */ -+void __attribute__ ((weak)) -+ platform_rio_init(void) -+{ -+ printk(KERN_WARNING "RIO: No platform_rio_init() present\n"); -+} -+ -+/** -+ * ppc_rio_init - Do PPC32 RIO init -+ * -+ * Calls platform-specific RIO init code and then calls -+ * rio_init_mports() to initialize any master ports that -+ * have been registered with the RIO subsystem. -+ */ -+static int __init ppc_rio_init(void) -+{ -+ printk(KERN_INFO "RIO: RapidIO init\n"); -+ -+ /* Platform specific initialization */ -+ platform_rio_init(); -+ -+ /* Enumerate all registered ports */ -+ rio_init_mports(); -+ -+ return 0; -+} -+ -+subsys_initcall(ppc_rio_init); ---- a/arch/powerpc/kernel/rtas_pci.c -+++ b/arch/powerpc/kernel/rtas_pci.c -@@ -260,7 +260,7 @@ static int phb_set_bus_ranges(struct dev - - int __devinit rtas_setup_phb(struct pci_controller *phb) - { -- struct device_node *dev = phb->arch_data; -+ struct device_node *dev = phb->dn; - - if (is_python(dev)) - python_countermeasures(dev); -@@ -280,10 +280,7 @@ void __init find_and_init_phbs(void) - struct pci_controller *phb; - struct device_node *root = of_find_node_by_path("/"); - -- for (node = of_get_next_child(root, NULL); -- node != NULL; -- node = of_get_next_child(root, node)) { -- -+ for_each_child_of_node(root, node) { - if (node->type == NULL || (strcmp(node->type, "pci") != 0 && - strcmp(node->type, "pciex") != 0)) - continue; -@@ -311,10 +308,12 @@ void __init find_and_init_phbs(void) - if (prop) - pci_probe_only = *prop; - -+#ifdef CONFIG_PPC32 /* Will be made generic soon */ - prop = of_get_property(of_chosen, - "linux,pci-assign-all-buses", NULL); -- if (prop) -- pci_assign_all_buses = *prop; -+ if (prop && *prop) -+ ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS; -+#endif /* CONFIG_PPC32 */ - } - } - ---- a/arch/powerpc/kernel/setup-common.c -+++ b/arch/powerpc/kernel/setup-common.c -@@ -33,6 +33,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -57,6 +58,7 @@ - #include - #include - #include -+#include - - #include "setup.h" - -@@ -327,6 +329,31 @@ void __init check_for_initrd(void) - - #ifdef CONFIG_SMP - -+int threads_per_core, threads_shift; -+cpumask_t threads_core_mask; -+ -+static void __init cpu_init_thread_core_maps(int tpc) -+{ -+ int i; -+ -+ threads_per_core = tpc; -+ threads_core_mask = CPU_MASK_NONE; -+ -+ /* This implementation only supports power of 2 number of threads -+ * for simplicity and performance -+ */ -+ threads_shift = ilog2(tpc); -+ BUG_ON(tpc != (1 << threads_shift)); -+ -+ for (i = 0; i < tpc; i++) -+ cpu_set(i, threads_core_mask); -+ -+ printk(KERN_INFO "CPU maps initialized for %d thread%s per core\n", -+ tpc, tpc > 1 ? "s" : ""); -+ printk(KERN_DEBUG " (thread shift is %d)\n", threads_shift); -+} -+ -+ - /** - * setup_cpu_maps - initialize the following cpu maps: - * cpu_possible_map -@@ -350,22 +377,32 @@ void __init smp_setup_cpu_maps(void) - { - struct device_node *dn = NULL; - int cpu = 0; -+ int nthreads = 1; -+ -+ DBG("smp_setup_cpu_maps()\n"); - - while ((dn = of_find_node_by_type(dn, "cpu")) && cpu < NR_CPUS) { - const int *intserv; -- int j, len = sizeof(u32), nthreads = 1; -+ int j, len; -+ -+ DBG(" * %s...\n", dn->full_name); - - intserv = of_get_property(dn, "ibm,ppc-interrupt-server#s", - &len); -- if (intserv) -+ if (intserv) { - nthreads = len / sizeof(int); -- else { -+ DBG(" ibm,ppc-interrupt-server#s -> %d threads\n", -+ nthreads); -+ } else { -+ DBG(" no ibm,ppc-interrupt-server#s -> 1 thread\n"); - intserv = of_get_property(dn, "reg", NULL); - if (!intserv) - intserv = &cpu; /* assume logical == phys */ - } - - for (j = 0; j < nthreads && cpu < NR_CPUS; j++) { -+ DBG(" thread %d -> cpu %d (hard id %d)\n", -+ j, cpu, intserv[j]); - cpu_set(cpu, cpu_present_map); - set_hard_smp_processor_id(cpu, intserv[j]); - cpu_set(cpu, cpu_possible_map); -@@ -373,6 +410,12 @@ void __init smp_setup_cpu_maps(void) - } - } - -+ /* If no SMT supported, nthreads is forced to 1 */ -+ if (!cpu_has_feature(CPU_FTR_SMT)) { -+ DBG(" SMT disabled ! nthreads forced to 1\n"); -+ nthreads = 1; -+ } -+ - #ifdef CONFIG_PPC64 - /* - * On pSeries LPAR, we need to know how many cpus -@@ -395,7 +438,7 @@ void __init smp_setup_cpu_maps(void) - - /* Double maxcpus for processors which have SMT capability */ - if (cpu_has_feature(CPU_FTR_SMT)) -- maxcpus *= 2; -+ maxcpus *= nthreads; - - if (maxcpus > NR_CPUS) { - printk(KERN_WARNING -@@ -412,9 +455,16 @@ void __init smp_setup_cpu_maps(void) - out: - of_node_put(dn); - } -- - vdso_data->processorCount = num_present_cpus(); - #endif /* CONFIG_PPC64 */ -+ -+ /* Initialize CPU <=> thread mapping/ -+ * -+ * WARNING: We assume that the number of threads is the same for -+ * every CPU in the system. If that is not the case, then some code -+ * here will have to be reworked -+ */ -+ cpu_init_thread_core_maps(nthreads); - } - - /* -@@ -424,17 +474,19 @@ void __init smp_setup_cpu_maps(void) - */ - void __init smp_setup_cpu_sibling_map(void) - { --#if defined(CONFIG_PPC64) -- int cpu; -+#ifdef CONFIG_PPC64 -+ int i, cpu, base; - -- /* -- * Do the sibling map; assume only two threads per processor. -- */ - for_each_possible_cpu(cpu) { -- cpu_set(cpu, per_cpu(cpu_sibling_map, cpu)); -- if (cpu_has_feature(CPU_FTR_SMT)) -- cpu_set(cpu ^ 0x1, per_cpu(cpu_sibling_map, cpu)); -+ DBG("Sibling map for CPU %d:", cpu); -+ base = cpu_first_thread_in_core(cpu); -+ for (i = 0; i < threads_per_core; i++) { -+ cpu_set(base + i, per_cpu(cpu_sibling_map, cpu)); -+ DBG(" %d", base + i); -+ } -+ DBG("\n"); - } -+ - #endif /* CONFIG_PPC64 */ - } - #endif /* CONFIG_SMP */ ---- a/arch/powerpc/kernel/signal_32.c -+++ b/arch/powerpc/kernel/signal_32.c -@@ -24,13 +24,12 @@ - #include - #include - #include -+#include - #ifdef CONFIG_PPC64 - #include - #include --#include - #else - #include --#include - #include - #include - #include ---- a/arch/powerpc/kernel/smp.c -+++ b/arch/powerpc/kernel/smp.c -@@ -76,6 +76,8 @@ void smp_call_function_interrupt(void); - - int smt_enabled_at_boot = 1; - -+static int ipi_fail_ok; -+ - static void (*crash_ipi_function_ptr)(struct pt_regs *) = NULL; - - #ifdef CONFIG_PPC64 -@@ -181,12 +183,13 @@ static struct call_data_struct { - * If true, wait (atomically) until function has completed on other CPUs. - * [RETURNS] 0 on success, else a negative status code. Does not return until - * remote CPUs are nearly ready to execute <> or are or have executed. -+ * is a cpu map of the cpus to send IPI to. - * - * You must not call this function with disabled interrupts or from a - * hardware interrupt handler or from a bottom half handler. - */ --int smp_call_function_map(void (*func) (void *info), void *info, int nonatomic, -- int wait, cpumask_t map) -+static int __smp_call_function_map(void (*func) (void *info), void *info, -+ int nonatomic, int wait, cpumask_t map) - { - struct call_data_struct data; - int ret = -1, num_cpus; -@@ -203,8 +206,6 @@ int smp_call_function_map(void (*func) ( - if (wait) - atomic_set(&data.finished, 0); - -- spin_lock(&call_lock); -- - /* remove 'self' from the map */ - if (cpu_isset(smp_processor_id(), map)) - cpu_clear(smp_processor_id(), map); -@@ -231,7 +232,8 @@ int smp_call_function_map(void (*func) ( - printk("smp_call_function on cpu %d: other cpus not " - "responding (%d)\n", smp_processor_id(), - atomic_read(&data.started)); -- debugger(NULL); -+ if (!ipi_fail_ok) -+ debugger(NULL); - goto out; - } - } -@@ -258,14 +260,18 @@ int smp_call_function_map(void (*func) ( - out: - call_data = NULL; - HMT_medium(); -- spin_unlock(&call_lock); - return ret; - } - - static int __smp_call_function(void (*func)(void *info), void *info, - int nonatomic, int wait) - { -- return smp_call_function_map(func,info,nonatomic,wait,cpu_online_map); -+ int ret; -+ spin_lock(&call_lock); -+ ret =__smp_call_function_map(func, info, nonatomic, wait, -+ cpu_online_map); -+ spin_unlock(&call_lock); -+ return ret; - } - - int smp_call_function(void (*func) (void *info), void *info, int nonatomic, -@@ -278,8 +284,8 @@ int smp_call_function(void (*func) (void - } - EXPORT_SYMBOL(smp_call_function); - --int smp_call_function_single(int cpu, void (*func) (void *info), void *info, int nonatomic, -- int wait) -+int smp_call_function_single(int cpu, void (*func) (void *info), void *info, -+ int nonatomic, int wait) - { - cpumask_t map = CPU_MASK_NONE; - int ret = 0; -@@ -291,9 +297,11 @@ int smp_call_function_single(int cpu, vo - return -EINVAL; - - cpu_set(cpu, map); -- if (cpu != get_cpu()) -- ret = smp_call_function_map(func,info,nonatomic,wait,map); -- else { -+ if (cpu != get_cpu()) { -+ spin_lock(&call_lock); -+ ret = __smp_call_function_map(func, info, nonatomic, wait, map); -+ spin_unlock(&call_lock); -+ } else { - local_irq_disable(); - func(info); - local_irq_enable(); -@@ -305,7 +313,22 @@ EXPORT_SYMBOL(smp_call_function_single); - - void smp_send_stop(void) - { -- __smp_call_function(stop_this_cpu, NULL, 1, 0); -+ int nolock; -+ -+ /* It's OK to fail sending the IPI, since the alternative is to -+ * be stuck forever waiting on the other CPU to take the interrupt. -+ * -+ * It's better to at least continue and go through reboot, since this -+ * function is usually called at panic or reboot time in the first -+ * place. -+ */ -+ ipi_fail_ok = 1; -+ -+ /* Don't deadlock in case we got called through panic */ -+ nolock = !spin_trylock(&call_lock); -+ __smp_call_function_map(stop_this_cpu, NULL, 1, 0, cpu_online_map); -+ if (!nolock) -+ spin_unlock(&call_lock); - } - - void smp_call_function_interrupt(void) ---- /dev/null -+++ b/arch/powerpc/kernel/systbl_chk.c -@@ -0,0 +1,58 @@ -+/* -+ * This file, when run through CPP produces a list of syscall numbers -+ * in the order of systbl.h. That way we can check for gaps and syscalls -+ * that are out of order. -+ * -+ * Unfortunately, we cannot check for the correct ordering of entries -+ * using SYSX(). -+ * -+ * Copyright © IBM Corporation -+ * -+ * 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 -+ -+#define SYSCALL(func) __NR_##func -+#define COMPAT_SYS(func) __NR_##func -+#define PPC_SYS(func) __NR_##func -+#ifdef CONFIG_PPC64 -+#define OLDSYS(func) -1 -+#define SYS32ONLY(func) -1 -+#else -+#define OLDSYS(func) __NR_old##func -+#define SYS32ONLY(func) __NR_##func -+#endif -+#define SYSX(f, f3264, f32) -1 -+ -+#define SYSCALL_SPU(func) SYSCALL(func) -+#define COMPAT_SYS_SPU(func) COMPAT_SYS(func) -+#define PPC_SYS_SPU(func) PPC_SYS(func) -+#define SYSX_SPU(f, f3264, f32) SYSX(f, f3264, f32) -+ -+/* Just insert a marker for ni_syscalls */ -+#define __NR_ni_syscall -1 -+ -+/* -+ * These are the known exceptions. -+ * Hopefully, there will be no more. -+ */ -+#define __NR_llseek __NR__llseek -+#undef __NR_umount -+#define __NR_umount __NR_umount2 -+#define __NR_old_getrlimit __NR_getrlimit -+#define __NR_newstat __NR_stat -+#define __NR_newlstat __NR_lstat -+#define __NR_newfstat __NR_fstat -+#define __NR_newuname __NR_uname -+#define __NR_sysctl __NR__sysctl -+#define __NR_olddebug_setcontext __NR_sys_debug_setcontext -+ -+/* We call sys_ugetrlimit for syscall number __NR_getrlimit */ -+#define getrlimit ugetrlimit -+ -+START_TABLE -+#include -+END_TABLE __NR_syscalls ---- /dev/null -+++ b/arch/powerpc/kernel/systbl_chk.sh -@@ -0,0 +1,33 @@ -+#!/bin/sh -+# -+# Just process the CPP output from systbl_chk.c and complain -+# if anything is out of order. -+# -+# Copyright © 2008 IBM Corporation -+# -+# 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. -+ -+awk 'BEGIN { num = -1; } # Ignore the beginning of the file -+ /^#/ { next; } -+ /^[ \t]*$/ { next; } -+ /^START_TABLE/ { num = 0; next; } -+ /^END_TABLE/ { -+ if (num != $2) { -+ printf "__NR_syscalls (%s) is not one more than the last syscall (%s)\n", -+ $2, num - 1; -+ exit(1); -+ } -+ num = -1; # Ignore the rest of the file -+ } -+ { -+ if (num == -1) next; -+ if (($1 != -1) && ($1 != num)) { -+ printf "Syscall %s out of order (expected %s)\n", -+ $1, num; -+ exit(1); -+ }; -+ num++; -+ }' "$1" ---- a/arch/powerpc/kernel/time.c -+++ b/arch/powerpc/kernel/time.c -@@ -116,9 +116,12 @@ static struct clock_event_device decreme - .features = CLOCK_EVT_FEAT_ONESHOT, - }; - --static DEFINE_PER_CPU(struct clock_event_device, decrementers); --void init_decrementer_clockevent(void); --static DEFINE_PER_CPU(u64, decrementer_next_tb); -+struct decrementer_clock { -+ struct clock_event_device event; -+ u64 next_tb; -+}; -+ -+static DEFINE_PER_CPU(struct decrementer_clock, decrementers); - - #ifdef CONFIG_PPC_ISERIES - static unsigned long __initdata iSeries_recal_titan; -@@ -216,7 +219,11 @@ static u64 read_purr(void) - */ - static u64 read_spurr(u64 purr) - { -- if (cpu_has_feature(CPU_FTR_SPURR)) -+ /* -+ * cpus without PURR won't have a SPURR -+ * We already know the former when we use this, so tell gcc -+ */ -+ if (cpu_has_feature(CPU_FTR_PURR) && cpu_has_feature(CPU_FTR_SPURR)) - return mfspr(SPRN_SPURR); - return purr; - } -@@ -227,29 +234,30 @@ static u64 read_spurr(u64 purr) - */ - void account_system_vtime(struct task_struct *tsk) - { -- u64 now, nowscaled, delta, deltascaled; -+ u64 now, nowscaled, delta, deltascaled, sys_time; - unsigned long flags; - - local_irq_save(flags); - now = read_purr(); -- delta = now - get_paca()->startpurr; -- get_paca()->startpurr = now; - nowscaled = read_spurr(now); -+ delta = now - get_paca()->startpurr; - deltascaled = nowscaled - get_paca()->startspurr; -+ get_paca()->startpurr = now; - get_paca()->startspurr = nowscaled; - if (!in_interrupt()) { - /* deltascaled includes both user and system time. - * Hence scale it based on the purr ratio to estimate - * the system time */ -+ sys_time = get_paca()->system_time; - if (get_paca()->user_time) -- deltascaled = deltascaled * get_paca()->system_time / -- (get_paca()->system_time + get_paca()->user_time); -- delta += get_paca()->system_time; -+ deltascaled = deltascaled * sys_time / -+ (sys_time + get_paca()->user_time); -+ delta += sys_time; - get_paca()->system_time = 0; - } - account_system_time(tsk, 0, delta); -- get_paca()->purrdelta = delta; - account_system_time_scaled(tsk, deltascaled); -+ get_paca()->purrdelta = delta; - get_paca()->spurrdelta = deltascaled; - local_irq_restore(flags); - } -@@ -326,11 +334,9 @@ void calculate_steal_time(void) - s64 stolen; - struct cpu_purr_data *pme; - -- if (!cpu_has_feature(CPU_FTR_PURR)) -- return; -- pme = &per_cpu(cpu_purr_data, smp_processor_id()); -+ pme = &__get_cpu_var(cpu_purr_data); - if (!pme->initialized) -- return; /* this can happen in early boot */ -+ return; /* !CPU_FTR_PURR or early in early boot */ - tb = mftb(); - purr = mfspr(SPRN_PURR); - stolen = (tb - pme->tb) - (purr - pme->purr); -@@ -353,7 +359,7 @@ static void snapshot_purr(void) - if (!cpu_has_feature(CPU_FTR_PURR)) - return; - local_irq_save(flags); -- pme = &per_cpu(cpu_purr_data, smp_processor_id()); -+ pme = &__get_cpu_var(cpu_purr_data); - pme->tb = mftb(); - pme->purr = mfspr(SPRN_PURR); - pme->initialized = 1; -@@ -556,8 +562,8 @@ void __init iSeries_time_init_early(void - void timer_interrupt(struct pt_regs * regs) - { - struct pt_regs *old_regs; -- int cpu = smp_processor_id(); -- struct clock_event_device *evt = &per_cpu(decrementers, cpu); -+ struct decrementer_clock *decrementer = &__get_cpu_var(decrementers); -+ struct clock_event_device *evt = &decrementer->event; - u64 now; - - /* Ensure a positive value is written to the decrementer, or else -@@ -570,9 +576,9 @@ void timer_interrupt(struct pt_regs * re - #endif - - now = get_tb_or_rtc(); -- if (now < per_cpu(decrementer_next_tb, cpu)) { -+ if (now < decrementer->next_tb) { - /* not time for this event yet */ -- now = per_cpu(decrementer_next_tb, cpu) - now; -+ now = decrementer->next_tb - now; - if (now <= DECREMENTER_MAX) - set_dec((int)now); - return; -@@ -623,6 +629,45 @@ void wakeup_decrementer(void) - set_dec(ticks); - } - -+#ifdef CONFIG_SUSPEND -+void generic_suspend_disable_irqs(void) -+{ -+ preempt_disable(); -+ -+ /* Disable the decrementer, so that it doesn't interfere -+ * with suspending. -+ */ -+ -+ set_dec(0x7fffffff); -+ local_irq_disable(); -+ set_dec(0x7fffffff); -+} -+ -+void generic_suspend_enable_irqs(void) -+{ -+ wakeup_decrementer(); -+ -+ local_irq_enable(); -+ preempt_enable(); -+} -+ -+/* Overrides the weak version in kernel/power/main.c */ -+void arch_suspend_disable_irqs(void) -+{ -+ if (ppc_md.suspend_disable_irqs) -+ ppc_md.suspend_disable_irqs(); -+ generic_suspend_disable_irqs(); -+} -+ -+/* Overrides the weak version in kernel/power/main.c */ -+void arch_suspend_enable_irqs(void) -+{ -+ generic_suspend_enable_irqs(); -+ if (ppc_md.suspend_enable_irqs) -+ ppc_md.suspend_enable_irqs(); -+} -+#endif -+ - #ifdef CONFIG_SMP - void __init smp_space_timers(unsigned int max_cpus) - { -@@ -811,7 +856,7 @@ void __init clocksource_init(void) - static int decrementer_set_next_event(unsigned long evt, - struct clock_event_device *dev) - { -- __get_cpu_var(decrementer_next_tb) = get_tb_or_rtc() + evt; -+ __get_cpu_var(decrementers).next_tb = get_tb_or_rtc() + evt; - set_dec(evt); - return 0; - } -@@ -825,7 +870,7 @@ static void decrementer_set_mode(enum cl - - static void register_decrementer_clockevent(int cpu) - { -- struct clock_event_device *dec = &per_cpu(decrementers, cpu); -+ struct clock_event_device *dec = &per_cpu(decrementers, cpu).event; - - *dec = decrementer_clockevent; - dec->cpumask = cpumask_of_cpu(cpu); -@@ -836,7 +881,7 @@ static void register_decrementer_clockev - clockevents_register_device(dec); - } - --void init_decrementer_clockevent(void) -+static void __init init_decrementer_clockevent(void) - { - int cpu = smp_processor_id(); - ---- a/arch/powerpc/kernel/traps.c -+++ b/arch/powerpc/kernel/traps.c -@@ -334,18 +334,25 @@ static inline int check_io_access(struct - #define clear_single_step(regs) ((regs)->msr &= ~MSR_SE) - #endif - --static int generic_machine_check_exception(struct pt_regs *regs) -+#if defined(CONFIG_4xx) -+int machine_check_4xx(struct pt_regs *regs) - { - unsigned long reason = get_mc_reason(regs); - --#if defined(CONFIG_4xx) && !defined(CONFIG_440A) - if (reason & ESR_IMCP) { - printk("Instruction"); - mtspr(SPRN_ESR, reason & ~ESR_IMCP); - } else - printk("Data"); - printk(" machine check in kernel mode.\n"); --#elif defined(CONFIG_440A) -+ -+ return 0; -+} -+ -+int machine_check_440A(struct pt_regs *regs) -+{ -+ unsigned long reason = get_mc_reason(regs); -+ - printk("Machine check in kernel mode.\n"); - if (reason & ESR_IMCP){ - printk("Instruction Synchronous Machine Check exception\n"); -@@ -375,7 +382,13 @@ static int generic_machine_check_excepti - /* Clear MCSR */ - mtspr(SPRN_MCSR, mcsr); - } --#elif defined (CONFIG_E500) -+ return 0; -+} -+#elif defined(CONFIG_E500) -+int machine_check_e500(struct pt_regs *regs) -+{ -+ unsigned long reason = get_mc_reason(regs); -+ - printk("Machine check in kernel mode.\n"); - printk("Caused by (from MCSR=%lx): ", reason); - -@@ -403,7 +416,14 @@ static int generic_machine_check_excepti - printk("Bus - Instruction Parity Error\n"); - if (reason & MCSR_BUS_RPERR) - printk("Bus - Read Parity Error\n"); --#elif defined (CONFIG_E200) -+ -+ return 0; -+} -+#elif defined(CONFIG_E200) -+int machine_check_e200(struct pt_regs *regs) -+{ -+ unsigned long reason = get_mc_reason(regs); -+ - printk("Machine check in kernel mode.\n"); - printk("Caused by (from MCSR=%lx): ", reason); - -@@ -421,7 +441,14 @@ static int generic_machine_check_excepti - printk("Bus - Read Bus Error on data load\n"); - if (reason & MCSR_BUS_WRERR) - printk("Bus - Write Bus Error on buffered store or cache line push\n"); --#else /* !CONFIG_4xx && !CONFIG_E500 && !CONFIG_E200 */ -+ -+ return 0; -+} -+#else -+int machine_check_generic(struct pt_regs *regs) -+{ -+ unsigned long reason = get_mc_reason(regs); -+ - printk("Machine check in kernel mode.\n"); - printk("Caused by (from SRR1=%lx): ", reason); - switch (reason & 0x601F0000) { -@@ -451,22 +478,26 @@ static int generic_machine_check_excepti - default: - printk("Unknown values in msr\n"); - } --#endif /* CONFIG_4xx */ -- - return 0; - } -+#endif /* everything else */ - - void machine_check_exception(struct pt_regs *regs) - { - int recover = 0; - -- /* See if any machine dependent calls */ -+ /* See if any machine dependent calls. In theory, we would want -+ * to call the CPU first, and call the ppc_md. one if the CPU -+ * one returns a positive number. However there is existing code -+ * that assumes the board gets a first chance, so let's keep it -+ * that way for now and fix things later. --BenH. -+ */ - if (ppc_md.machine_check_exception) - recover = ppc_md.machine_check_exception(regs); -- else -- recover = generic_machine_check_exception(regs); -+ else if (cur_cpu_spec->machine_check) -+ recover = cur_cpu_spec->machine_check(regs); - -- if (recover) -+ if (recover > 0) - return; - - if (user_mode(regs)) { -@@ -476,7 +507,12 @@ void machine_check_exception(struct pt_r - } - - #if defined(CONFIG_8xx) && defined(CONFIG_PCI) -- /* the qspan pci read routines can cause machine checks -- Cort */ -+ /* the qspan pci read routines can cause machine checks -- Cort -+ * -+ * yuck !!! that totally needs to go away ! There are better ways -+ * to deal with that than having a wart in the mcheck handler. -+ * -- BenH -+ */ - bad_page_fault(regs, regs->dar, SIGBUS); - return; - #endif -@@ -622,6 +658,9 @@ static void parse_fpe(struct pt_regs *re - #define INST_POPCNTB 0x7c0000f4 - #define INST_POPCNTB_MASK 0xfc0007fe - -+#define INST_ISEL 0x7c00001e -+#define INST_ISEL_MASK 0xfc00003e -+ - static int emulate_string_inst(struct pt_regs *regs, u32 instword) - { - u8 rT = (instword >> 21) & 0x1f; -@@ -707,6 +746,23 @@ static int emulate_popcntb_inst(struct p - return 0; - } - -+static int emulate_isel(struct pt_regs *regs, u32 instword) -+{ -+ u8 rT = (instword >> 21) & 0x1f; -+ u8 rA = (instword >> 16) & 0x1f; -+ u8 rB = (instword >> 11) & 0x1f; -+ u8 BC = (instword >> 6) & 0x1f; -+ u8 bit; -+ unsigned long tmp; -+ -+ tmp = (rA == 0) ? 0 : regs->gpr[rA]; -+ bit = (regs->ccr >> (31 - BC)) & 0x1; -+ -+ regs->gpr[rT] = bit ? tmp : regs->gpr[rB]; -+ -+ return 0; -+} -+ - static int emulate_instruction(struct pt_regs *regs) - { - u32 instword; -@@ -749,6 +805,11 @@ static int emulate_instruction(struct pt - return emulate_popcntb_inst(regs, instword); - } - -+ /* Emulate isel (Integer Select) instruction */ -+ if ((instword & INST_ISEL_MASK) == INST_ISEL) { -+ return emulate_isel(regs, instword); -+ } -+ - return -EINVAL; - } - ---- a/arch/powerpc/kernel/udbg.c -+++ b/arch/powerpc/kernel/udbg.c -@@ -54,9 +54,16 @@ void __init udbg_early_init(void) - #elif defined(CONFIG_PPC_EARLY_DEBUG_44x) - /* PPC44x debug */ - udbg_init_44x_as1(); -+#elif defined(CONFIG_PPC_EARLY_DEBUG_40x) -+ /* PPC40x debug */ -+ udbg_init_40x_realmode(); - #elif defined(CONFIG_PPC_EARLY_DEBUG_CPM) - udbg_init_cpm(); - #endif -+ -+#ifdef CONFIG_PPC_EARLY_DEBUG -+ console_loglevel = 10; -+#endif - } - - /* udbg library, used by xmon et al */ ---- a/arch/powerpc/kernel/udbg_16550.c -+++ b/arch/powerpc/kernel/udbg_16550.c -@@ -46,7 +46,7 @@ struct NS16550 { - - #define LCR_DLAB 0x80 - --static volatile struct NS16550 __iomem *udbg_comport; -+static struct NS16550 __iomem *udbg_comport; - - static void udbg_550_putc(char c) - { -@@ -117,7 +117,7 @@ unsigned int udbg_probe_uart_speed(void - { - unsigned int dll, dlm, divisor, prescaler, speed; - u8 old_lcr; -- volatile struct NS16550 __iomem *port = comport; -+ struct NS16550 __iomem *port = comport; - - old_lcr = in_8(&port->lcr); - -@@ -162,7 +162,7 @@ void udbg_maple_real_putc(char c) - - void __init udbg_init_maple_realmode(void) - { -- udbg_comport = (volatile struct NS16550 __iomem *)0xf40003f8; -+ udbg_comport = (struct NS16550 __iomem *)0xf40003f8; - - udbg_putc = udbg_maple_real_putc; - udbg_getc = NULL; -@@ -184,7 +184,7 @@ void udbg_pas_real_putc(char c) - - void udbg_init_pas_realmode(void) - { -- udbg_comport = (volatile struct NS16550 __iomem *)0xfcff03f8UL; -+ udbg_comport = (struct NS16550 __iomem *)0xfcff03f8UL; - - udbg_putc = udbg_pas_real_putc; - udbg_getc = NULL; -@@ -219,9 +219,42 @@ static int udbg_44x_as1_getc(void) - void __init udbg_init_44x_as1(void) - { - udbg_comport = -- (volatile struct NS16550 __iomem *)PPC44x_EARLY_DEBUG_VIRTADDR; -+ (struct NS16550 __iomem *)PPC44x_EARLY_DEBUG_VIRTADDR; - - udbg_putc = udbg_44x_as1_putc; - udbg_getc = udbg_44x_as1_getc; - } - #endif /* CONFIG_PPC_EARLY_DEBUG_44x */ -+ -+#ifdef CONFIG_PPC_EARLY_DEBUG_40x -+static void udbg_40x_real_putc(char c) -+{ -+ if (udbg_comport) { -+ while ((real_readb(&udbg_comport->lsr) & LSR_THRE) == 0) -+ /* wait for idle */; -+ real_writeb(c, &udbg_comport->thr); eieio(); -+ if (c == '\n') -+ udbg_40x_real_putc('\r'); -+ } -+} -+ -+static int udbg_40x_real_getc(void) -+{ -+ if (udbg_comport) { -+ while ((real_readb(&udbg_comport->lsr) & LSR_DR) == 0) -+ ; /* wait for char */ -+ return real_readb(&udbg_comport->rbr); -+ } -+ return -1; -+} -+ -+void __init udbg_init_40x_realmode(void) -+{ -+ udbg_comport = (struct NS16550 __iomem *) -+ CONFIG_PPC_EARLY_DEBUG_40x_PHYSADDR; -+ -+ udbg_putc = udbg_40x_real_putc; -+ udbg_getc = udbg_40x_real_getc; -+ udbg_getc_poll = NULL; -+} -+#endif /* CONFIG_PPC_EARLY_DEBUG_40x */ ---- a/arch/powerpc/math-emu/op-4.h -+++ b/arch/powerpc/math-emu/op-4.h -@@ -194,19 +194,39 @@ - (X##_f[3] = I3, X##_f[2] = I2, X##_f[1] = I1, X##_f[0] = I0) - - #ifndef __FP_FRAC_ADD_4 --#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \ -- (r0 = x0 + y0, \ -- r1 = x1 + y1 + (r0 < x0), \ -- r2 = x2 + y2 + (r1 < x1), \ -- r3 = x3 + y3 + (r2 < x2)) -+#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \ -+ do { \ -+ int _c1, _c2, _c3; \ -+ r0 = x0 + y0; \ -+ _c1 = r0 < x0; \ -+ r1 = x1 + y1; \ -+ _c2 = r1 < x1; \ -+ r1 += _c1; \ -+ _c2 |= r1 < _c1; \ -+ r2 = x2 + y2; \ -+ _c3 = r2 < x2; \ -+ r2 += _c2; \ -+ _c3 |= r2 < _c2; \ -+ r3 = x3 + y3 + _c3; \ -+ } while (0) - #endif - - #ifndef __FP_FRAC_SUB_4 --#define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \ -- (r0 = x0 - y0, \ -- r1 = x1 - y1 - (r0 > x0), \ -- r2 = x2 - y2 - (r1 > x1), \ -- r3 = x3 - y3 - (r2 > x2)) -+#define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \ -+ do { \ -+ int _c1, _c2, _c3; \ -+ r0 = x0 - y0; \ -+ _c1 = r0 > x0; \ -+ r1 = x1 - y1; \ -+ _c2 = r1 > x1; \ -+ r1 -= _c1; \ -+ _c2 |= r1 > _c1; \ -+ r2 = x2 - y2; \ -+ _c3 = r2 > x2; \ -+ r2 -= _c2; \ -+ _c3 |= r2 > _c2; \ -+ r3 = x3 - y3 - _c3; \ -+ } while (0) - #endif - - #ifndef __FP_FRAC_ADDI_4 ---- a/arch/powerpc/mm/fault.c -+++ b/arch/powerpc/mm/fault.c -@@ -167,10 +167,8 @@ int __kprobes do_page_fault(struct pt_re - if (notify_page_fault(regs)) - return 0; - -- if (trap == 0x300) { -- if (debugger_fault_handler(regs)) -- return 0; -- } -+ if (unlikely(debugger_fault_handler(regs))) -+ return 0; - - /* On a kernel SLB miss we can only check for a valid exception entry */ - if (!user_mode(regs) && (address >= TASK_SIZE)) -@@ -189,7 +187,7 @@ int __kprobes do_page_fault(struct pt_re - return SIGSEGV; - /* in_atomic() in user mode is really bad, - as is current->mm == NULL. */ -- printk(KERN_EMERG "Page fault in user mode with" -+ printk(KERN_EMERG "Page fault in user mode with " - "in_atomic() = %d mm = %p\n", in_atomic(), mm); - printk(KERN_EMERG "NIP = %lx MSR = %lx\n", - regs->nip, regs->msr); ---- a/arch/powerpc/mm/fsl_booke_mmu.c -+++ b/arch/powerpc/mm/fsl_booke_mmu.c -@@ -165,15 +165,15 @@ void invalidate_tlbcam_entry(int index) - void __init cam_mapin_ram(unsigned long cam0, unsigned long cam1, - unsigned long cam2) - { -- settlbcam(0, KERNELBASE, PPC_MEMSTART, cam0, _PAGE_KERNEL, 0); -+ settlbcam(0, PAGE_OFFSET, PPC_MEMSTART, cam0, _PAGE_KERNEL, 0); - tlbcam_index++; - if (cam1) { - tlbcam_index++; -- settlbcam(1, KERNELBASE+cam0, PPC_MEMSTART+cam0, cam1, _PAGE_KERNEL, 0); -+ settlbcam(1, PAGE_OFFSET+cam0, PPC_MEMSTART+cam0, cam1, _PAGE_KERNEL, 0); - } - if (cam2) { - tlbcam_index++; -- settlbcam(2, KERNELBASE+cam0+cam1, PPC_MEMSTART+cam0+cam1, cam2, _PAGE_KERNEL, 0); -+ settlbcam(2, PAGE_OFFSET+cam0+cam1, PPC_MEMSTART+cam0+cam1, cam2, _PAGE_KERNEL, 0); - } - } - ---- a/arch/powerpc/mm/hash_utils_64.c -+++ b/arch/powerpc/mm/hash_utils_64.c -@@ -96,6 +96,7 @@ int mmu_vmalloc_psize = MMU_PAGE_4K; - int mmu_io_psize = MMU_PAGE_4K; - int mmu_kernel_ssize = MMU_SEGSIZE_256M; - int mmu_highuser_ssize = MMU_SEGSIZE_256M; -+u16 mmu_slb_size = 64; - #ifdef CONFIG_HUGETLB_PAGE - int mmu_huge_psize = MMU_PAGE_16M; - unsigned int HPAGE_SHIFT; -@@ -368,18 +369,11 @@ static void __init htab_init_page_sizes( - * on what is available - */ - if (mmu_psize_defs[MMU_PAGE_16M].shift) -- mmu_huge_psize = MMU_PAGE_16M; -+ set_huge_psize(MMU_PAGE_16M); - /* With 4k/4level pagetables, we can't (for now) cope with a - * huge page size < PMD_SIZE */ - else if (mmu_psize_defs[MMU_PAGE_1M].shift) -- mmu_huge_psize = MMU_PAGE_1M; -- -- /* Calculate HPAGE_SHIFT and sanity check it */ -- if (mmu_psize_defs[mmu_huge_psize].shift > MIN_HUGEPTE_SHIFT && -- mmu_psize_defs[mmu_huge_psize].shift < SID_SHIFT) -- HPAGE_SHIFT = mmu_psize_defs[mmu_huge_psize].shift; -- else -- HPAGE_SHIFT = 0; /* No huge pages dude ! */ -+ set_huge_psize(MMU_PAGE_1M); - #endif /* CONFIG_HUGETLB_PAGE */ - } - ---- a/arch/powerpc/mm/hugetlbpage.c -+++ b/arch/powerpc/mm/hugetlbpage.c -@@ -24,18 +24,17 @@ - #include - #include - -+#define HPAGE_SHIFT_64K 16 -+#define HPAGE_SHIFT_16M 24 -+ - #define NUM_LOW_AREAS (0x100000000UL >> SID_SHIFT) - #define NUM_HIGH_AREAS (PGTABLE_RANGE >> HTLB_AREA_SHIFT) - --#ifdef CONFIG_PPC_64K_PAGES --#define HUGEPTE_INDEX_SIZE (PMD_SHIFT-HPAGE_SHIFT) --#else --#define HUGEPTE_INDEX_SIZE (PUD_SHIFT-HPAGE_SHIFT) --#endif --#define PTRS_PER_HUGEPTE (1 << HUGEPTE_INDEX_SIZE) --#define HUGEPTE_TABLE_SIZE (sizeof(pte_t) << HUGEPTE_INDEX_SIZE) -+unsigned int hugepte_shift; -+#define PTRS_PER_HUGEPTE (1 << hugepte_shift) -+#define HUGEPTE_TABLE_SIZE (sizeof(pte_t) << hugepte_shift) - --#define HUGEPD_SHIFT (HPAGE_SHIFT + HUGEPTE_INDEX_SIZE) -+#define HUGEPD_SHIFT (HPAGE_SHIFT + hugepte_shift) - #define HUGEPD_SIZE (1UL << HUGEPD_SHIFT) - #define HUGEPD_MASK (~(HUGEPD_SIZE-1)) - -@@ -82,11 +81,35 @@ static int __hugepte_alloc(struct mm_str - return 0; - } - -+/* Base page size affects how we walk hugetlb page tables */ -+#ifdef CONFIG_PPC_64K_PAGES -+#define hpmd_offset(pud, addr) pmd_offset(pud, addr) -+#define hpmd_alloc(mm, pud, addr) pmd_alloc(mm, pud, addr) -+#else -+static inline -+pmd_t *hpmd_offset(pud_t *pud, unsigned long addr) -+{ -+ if (HPAGE_SHIFT == HPAGE_SHIFT_64K) -+ return pmd_offset(pud, addr); -+ else -+ return (pmd_t *) pud; -+} -+static inline -+pmd_t *hpmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long addr) -+{ -+ if (HPAGE_SHIFT == HPAGE_SHIFT_64K) -+ return pmd_alloc(mm, pud, addr); -+ else -+ return (pmd_t *) pud; -+} -+#endif -+ - /* Modelled after find_linux_pte() */ - pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr) - { - pgd_t *pg; - pud_t *pu; -+ pmd_t *pm; - - BUG_ON(get_slice_psize(mm, addr) != mmu_huge_psize); - -@@ -96,14 +119,9 @@ pte_t *huge_pte_offset(struct mm_struct - if (!pgd_none(*pg)) { - pu = pud_offset(pg, addr); - if (!pud_none(*pu)) { --#ifdef CONFIG_PPC_64K_PAGES -- pmd_t *pm; -- pm = pmd_offset(pu, addr); -+ pm = hpmd_offset(pu, addr); - if (!pmd_none(*pm)) - return hugepte_offset((hugepd_t *)pm, addr); --#else -- return hugepte_offset((hugepd_t *)pu, addr); --#endif - } - } - -@@ -114,6 +132,7 @@ pte_t *huge_pte_alloc(struct mm_struct * - { - pgd_t *pg; - pud_t *pu; -+ pmd_t *pm; - hugepd_t *hpdp = NULL; - - BUG_ON(get_slice_psize(mm, addr) != mmu_huge_psize); -@@ -124,14 +143,9 @@ pte_t *huge_pte_alloc(struct mm_struct * - pu = pud_alloc(mm, pg, addr); - - if (pu) { --#ifdef CONFIG_PPC_64K_PAGES -- pmd_t *pm; -- pm = pmd_alloc(mm, pu, addr); -+ pm = hpmd_alloc(mm, pu, addr); - if (pm) - hpdp = (hugepd_t *)pm; --#else -- hpdp = (hugepd_t *)pu; --#endif - } - - if (! hpdp) -@@ -158,7 +172,6 @@ static void free_hugepte_range(struct mm - PGF_CACHENUM_MASK)); - } - --#ifdef CONFIG_PPC_64K_PAGES - static void hugetlb_free_pmd_range(struct mmu_gather *tlb, pud_t *pud, - unsigned long addr, unsigned long end, - unsigned long floor, unsigned long ceiling) -@@ -191,7 +204,6 @@ static void hugetlb_free_pmd_range(struc - pud_clear(pud); - pmd_free_tlb(tlb, pmd); - } --#endif - - static void hugetlb_free_pud_range(struct mmu_gather *tlb, pgd_t *pgd, - unsigned long addr, unsigned long end, -@@ -210,9 +222,15 @@ static void hugetlb_free_pud_range(struc - continue; - hugetlb_free_pmd_range(tlb, pud, addr, next, floor, ceiling); - #else -- if (pud_none(*pud)) -- continue; -- free_hugepte_range(tlb, (hugepd_t *)pud); -+ if (HPAGE_SHIFT == HPAGE_SHIFT_64K) { -+ if (pud_none_or_clear_bad(pud)) -+ continue; -+ hugetlb_free_pmd_range(tlb, pud, addr, next, floor, ceiling); -+ } else { -+ if (pud_none(*pud)) -+ continue; -+ free_hugepte_range(tlb, (hugepd_t *)pud); -+ } - #endif - } while (pud++, addr = next, addr != end); - -@@ -526,6 +544,57 @@ repeat: - return err; - } - -+void set_huge_psize(int psize) -+{ -+ /* Check that it is a page size supported by the hardware and -+ * that it fits within pagetable limits. */ -+ if (mmu_psize_defs[psize].shift && mmu_psize_defs[psize].shift < SID_SHIFT && -+ (mmu_psize_defs[psize].shift > MIN_HUGEPTE_SHIFT || -+ mmu_psize_defs[psize].shift == HPAGE_SHIFT_64K)) { -+ HPAGE_SHIFT = mmu_psize_defs[psize].shift; -+ mmu_huge_psize = psize; -+#ifdef CONFIG_PPC_64K_PAGES -+ hugepte_shift = (PMD_SHIFT-HPAGE_SHIFT); -+#else -+ if (HPAGE_SHIFT == HPAGE_SHIFT_64K) -+ hugepte_shift = (PMD_SHIFT-HPAGE_SHIFT); -+ else -+ hugepte_shift = (PUD_SHIFT-HPAGE_SHIFT); -+#endif -+ -+ } else -+ HPAGE_SHIFT = 0; -+} -+ -+static int __init hugepage_setup_sz(char *str) -+{ -+ unsigned long long size; -+ int mmu_psize = -1; -+ int shift; -+ -+ size = memparse(str, &str); -+ -+ shift = __ffs(size); -+ switch (shift) { -+#ifndef CONFIG_PPC_64K_PAGES -+ case HPAGE_SHIFT_64K: -+ mmu_psize = MMU_PAGE_64K; -+ break; -+#endif -+ case HPAGE_SHIFT_16M: -+ mmu_psize = MMU_PAGE_16M; -+ break; -+ } -+ -+ if (mmu_psize >=0 && mmu_psize_defs[mmu_psize].shift) -+ set_huge_psize(mmu_psize); -+ else -+ printk(KERN_WARNING "Invalid huge page size specified(%llu)\n", size); -+ -+ return 1; -+} -+__setup("hugepagesz=", hugepage_setup_sz); -+ - static void zero_ctor(struct kmem_cache *cache, void *addr) - { - memset(addr, 0, kmem_cache_size(cache)); ---- a/arch/powerpc/mm/lmb.c -+++ b/arch/powerpc/mm/lmb.c -@@ -342,3 +342,16 @@ void __init lmb_enforce_memory_limit(uns - } - } - } -+ -+int __init lmb_is_reserved(unsigned long addr) -+{ -+ int i; -+ -+ for (i = 0; i < lmb.reserved.cnt; i++) { -+ unsigned long upper = lmb.reserved.region[i].base + -+ lmb.reserved.region[i].size - 1; -+ if ((addr >= lmb.reserved.region[i].base) && (addr <= upper)) -+ return 1; -+ } -+ return 0; -+} ---- a/arch/powerpc/mm/mem.c -+++ b/arch/powerpc/mm/mem.c -@@ -213,15 +213,30 @@ void __init do_init_bootmem(void) - */ - #ifdef CONFIG_HIGHMEM - free_bootmem_with_active_regions(0, total_lowmem >> PAGE_SHIFT); -+ -+ /* reserve the sections we're already using */ -+ for (i = 0; i < lmb.reserved.cnt; i++) { -+ unsigned long addr = lmb.reserved.region[i].base + -+ lmb_size_bytes(&lmb.reserved, i) - 1; -+ if (addr < total_lowmem) -+ reserve_bootmem(lmb.reserved.region[i].base, -+ lmb_size_bytes(&lmb.reserved, i)); -+ else if (lmb.reserved.region[i].base < total_lowmem) { -+ unsigned long adjusted_size = total_lowmem - -+ lmb.reserved.region[i].base; -+ reserve_bootmem(lmb.reserved.region[i].base, -+ adjusted_size); -+ } -+ } - #else - free_bootmem_with_active_regions(0, max_pfn); --#endif - - /* reserve the sections we're already using */ - for (i = 0; i < lmb.reserved.cnt; i++) - reserve_bootmem(lmb.reserved.region[i].base, - lmb_size_bytes(&lmb.reserved, i)); - -+#endif - /* XXX need to clip this if using highmem? */ - sparse_memory_present_with_active_regions(0); - -@@ -334,11 +349,13 @@ void __init mem_init(void) - highmem_mapnr = total_lowmem >> PAGE_SHIFT; - for (pfn = highmem_mapnr; pfn < max_mapnr; ++pfn) { - struct page *page = pfn_to_page(pfn); -- -+ if (lmb_is_reserved(pfn << PAGE_SHIFT)) -+ continue; - ClearPageReserved(page); - init_page_count(page); - __free_page(page); - totalhigh_pages++; -+ reservedpages--; - } - totalram_pages += totalhigh_pages; - printk(KERN_DEBUG "High memory: %luk\n", ---- a/arch/powerpc/mm/slb.c -+++ b/arch/powerpc/mm/slb.c -@@ -256,6 +256,7 @@ void slb_initialize(void) - static int slb_encoding_inited; - extern unsigned int *slb_miss_kernel_load_linear; - extern unsigned int *slb_miss_kernel_load_io; -+ extern unsigned int *slb_compare_rr_to_size; - - /* Prepare our SLB miss handler based on our page size */ - linear_llp = mmu_psize_defs[mmu_linear_psize].sllp; -@@ -269,6 +270,8 @@ void slb_initialize(void) - SLB_VSID_KERNEL | linear_llp); - patch_slb_encoding(slb_miss_kernel_load_io, - SLB_VSID_KERNEL | io_llp); -+ patch_slb_encoding(slb_compare_rr_to_size, -+ mmu_slb_size); - - DBG("SLB: linear LLP = %04x\n", linear_llp); - DBG("SLB: io LLP = %04x\n", io_llp); ---- a/arch/powerpc/mm/slb_low.S -+++ b/arch/powerpc/mm/slb_low.S -@@ -227,8 +227,9 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISER - - 7: ld r10,PACASTABRR(r13) - addi r10,r10,1 -- /* use a cpu feature mask if we ever change our slb size */ -- cmpldi r10,SLB_NUM_ENTRIES -+ /* This gets soft patched on boot. */ -+_GLOBAL(slb_compare_rr_to_size) -+ cmpldi r10,0 - - blt+ 4f - li r10,SLB_NUM_BOLTED ---- a/arch/powerpc/oprofile/op_model_cell.c -+++ b/arch/powerpc/oprofile/op_model_cell.c -@@ -61,7 +61,7 @@ static unsigned int spu_cycle_reset; - #define NUM_THREADS 2 /* number of physical threads in - * physical processor - */ --#define NUM_TRACE_BUS_WORDS 4 -+#define NUM_DEBUG_BUS_WORDS 4 - #define NUM_INPUT_BUS_WORDS 2 - - #define MAX_SPU_COUNT 0xFFFFFF /* maximum 24 bit LFSR value */ -@@ -169,7 +169,6 @@ static DEFINE_SPINLOCK(virt_cntr_lock); - - static u32 ctr_enabled; - --static unsigned char trace_bus[NUM_TRACE_BUS_WORDS]; - static unsigned char input_bus[NUM_INPUT_BUS_WORDS]; - - /* -@@ -298,7 +297,7 @@ static void set_pm_event(u32 ctr, int ev - - p->signal_group = event / 100; - p->bus_word = bus_word; -- p->sub_unit = (unit_mask & 0x0000f000) >> 12; -+ p->sub_unit = GET_SUB_UNIT(unit_mask); - - pm_regs.pm07_cntrl[ctr] = 0; - pm_regs.pm07_cntrl[ctr] |= PM07_CTR_COUNT_CYCLES(count_cycles); -@@ -334,16 +333,16 @@ static void set_pm_event(u32 ctr, int ev - p->bit = signal_bit; - } - -- for (i = 0; i < NUM_TRACE_BUS_WORDS; i++) { -+ for (i = 0; i < NUM_DEBUG_BUS_WORDS; i++) { - if (bus_word & (1 << i)) { - pm_regs.debug_bus_control |= -- (bus_type << (31 - (2 * i) + 1)); -+ (bus_type << (30 - (2 * i))); - - for (j = 0; j < NUM_INPUT_BUS_WORDS; j++) { - if (input_bus[j] == 0xff) { - input_bus[j] = i; - pm_regs.group_control |= -- (i << (31 - i)); -+ (i << (30 - (2 * j))); - - break; - } -@@ -450,6 +449,12 @@ static void cell_virtual_cntr(unsigned l - hdw_thread = 1 ^ hdw_thread; - next_hdw_thread = hdw_thread; - -+ pm_regs.group_control = 0; -+ pm_regs.debug_bus_control = 0; -+ -+ for (i = 0; i < NUM_INPUT_BUS_WORDS; i++) -+ input_bus[i] = 0xff; -+ - /* - * There are some per thread events. Must do the - * set event, for the thread that is being started -@@ -619,9 +624,6 @@ static int cell_reg_setup(struct op_coun - pmc_cntrl[1][i].vcntr = i; - } - -- for (i = 0; i < NUM_TRACE_BUS_WORDS; i++) -- trace_bus[i] = 0xff; -- - for (i = 0; i < NUM_INPUT_BUS_WORDS; i++) - input_bus[i] = 0xff; - ---- a/arch/powerpc/platforms/40x/Kconfig -+++ b/arch/powerpc/platforms/40x/Kconfig -@@ -14,28 +14,34 @@ - # help - # This option enables support for the CPCI405 board. - --#config EP405 --# bool "EP405/EP405PC" --# depends on 40x --# default n --# select 405GP --# help --# This option enables support for the EP405/EP405PC boards. -- --#config EP405PC --# bool "EP405PC Support" --# depends on EP405 --# default y --# help --# This option enables support for the extra features of the EP405PC board. -+config EP405 -+ bool "EP405/EP405PC" -+ depends on 40x -+ default n -+ select 405GP -+ select PCI -+ help -+ This option enables support for the EP405/EP405PC boards. - - config KILAUEA - bool "Kilauea" - depends on 40x - default n -+ select 405EX -+ select PPC4xx_PCI_EXPRESS - help - This option enables support for the AMCC PPC405EX evaluation board. - -+config MAKALU -+ bool "Makalu" -+ depends on 40x -+ default n -+ select 405EX -+ select PCI -+ select PPC4xx_PCI_EXPRESS -+ help -+ This option enables support for the AMCC PPC405EX board. -+ - #config REDWOOD_5 - # bool "Redwood-5" - # depends on 40x -@@ -65,6 +71,7 @@ config WALNUT - depends on 40x - default y - select 405GP -+ select PCI - help - This option enables support for the IBM PPC405GP evaluation board. - -@@ -105,6 +112,11 @@ config 405GP - config 405EP - bool - -+config 405EX -+ bool -+ select IBM_NEW_EMAC_EMAC4 -+ select IBM_NEW_EMAC_RGMII -+ - config 405GPR - bool - ---- a/arch/powerpc/platforms/40x/Makefile -+++ b/arch/powerpc/platforms/40x/Makefile -@@ -1,3 +1,5 @@ - obj-$(CONFIG_KILAUEA) += kilauea.o -+obj-$(CONFIG_MAKALU) += makalu.o - obj-$(CONFIG_WALNUT) += walnut.o - obj-$(CONFIG_XILINX_VIRTEX_GENERIC_BOARD) += virtex.o -+obj-$(CONFIG_EP405) += ep405.o ---- /dev/null -+++ b/arch/powerpc/platforms/40x/ep405.c -@@ -0,0 +1,123 @@ -+/* -+ * Architecture- / platform-specific boot-time initialization code for -+ * IBM PowerPC 4xx based boards. Adapted from original -+ * code by Gary Thomas, Cort Dougan , and Dan Malek -+ * . -+ * -+ * Copyright(c) 1999-2000 Grant Erickson -+ * -+ * Rewritten and ported to the merged powerpc tree: -+ * Copyright 2007 IBM Corporation -+ * Josh Boyer -+ * -+ * Adapted to EP405 by Ben. Herrenschmidt -+ * -+ * TODO: Wire up the PCI IRQ mux and the southbridge interrupts -+ * -+ * 2002 (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 -+ -+static struct device_node *bcsr_node; -+static void __iomem *bcsr_regs; -+ -+/* BCSR registers */ -+#define BCSR_ID 0 -+#define BCSR_PCI_CTRL 1 -+#define BCSR_FLASH_NV_POR_CTRL 2 -+#define BCSR_FENET_UART_CTRL 3 -+#define BCSR_PCI_IRQ 4 -+#define BCSR_XIRQ_SELECT 5 -+#define BCSR_XIRQ_ROUTING 6 -+#define BCSR_XIRQ_STATUS 7 -+#define BCSR_XIRQ_STATUS2 8 -+#define BCSR_SW_STAT_LED_CTRL 9 -+#define BCSR_GPIO_IRQ_PAR_CTRL 10 -+/* there's more, can't be bothered typing them tho */ -+ -+ -+static __initdata struct of_device_id ep405_of_bus[] = { -+ { .compatible = "ibm,plb3", }, -+ { .compatible = "ibm,opb", }, -+ { .compatible = "ibm,ebc", }, -+ {}, -+}; -+ -+static int __init ep405_device_probe(void) -+{ -+ of_platform_bus_probe(NULL, ep405_of_bus, NULL); -+ -+ return 0; -+} -+machine_device_initcall(ep405, ep405_device_probe); -+ -+static void __init ep405_init_bcsr(void) -+{ -+ const u8 *irq_routing; -+ int i; -+ -+ /* Find the bloody thing & map it */ -+ bcsr_node = of_find_compatible_node(NULL, NULL, "ep405-bcsr"); -+ if (bcsr_node == NULL) { -+ printk(KERN_ERR "EP405 BCSR not found !\n"); -+ return; -+ } -+ bcsr_regs = of_iomap(bcsr_node, 0); -+ if (bcsr_regs == NULL) { -+ printk(KERN_ERR "EP405 BCSR failed to map !\n"); -+ return; -+ } -+ -+ /* Get the irq-routing property and apply the routing to the CPLD */ -+ irq_routing = of_get_property(bcsr_node, "irq-routing", NULL); -+ if (irq_routing == NULL) -+ return; -+ for (i = 0; i < 16; i++) { -+ u8 irq = irq_routing[i]; -+ out_8(bcsr_regs + BCSR_XIRQ_SELECT, i); -+ out_8(bcsr_regs + BCSR_XIRQ_ROUTING, irq); -+ } -+ in_8(bcsr_regs + BCSR_XIRQ_SELECT); -+ mb(); -+ out_8(bcsr_regs + BCSR_GPIO_IRQ_PAR_CTRL, 0xfe); -+} -+ -+static void __init ep405_setup_arch(void) -+{ -+ /* Find & init the BCSR CPLD */ -+ ep405_init_bcsr(); -+ -+ ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC; -+} -+ -+static int __init ep405_probe(void) -+{ -+ unsigned long root = of_get_flat_dt_root(); -+ -+ if (!of_flat_dt_is_compatible(root, "ep405")) -+ return 0; -+ -+ return 1; -+} -+ -+define_machine(ep405) { -+ .name = "EP405", -+ .probe = ep405_probe, -+ .setup_arch = ep405_setup_arch, -+ .progress = udbg_progress, -+ .init_IRQ = uic_init_tree, -+ .get_irq = uic_get_irq, -+ .calibrate_decr = generic_calibrate_decr, -+}; ---- a/arch/powerpc/platforms/40x/kilauea.c -+++ b/arch/powerpc/platforms/40x/kilauea.c -@@ -19,8 +19,9 @@ - #include - #include - #include -+#include - --static struct of_device_id kilauea_of_bus[] = { -+static __initdata struct of_device_id kilauea_of_bus[] = { - { .compatible = "ibm,plb4", }, - { .compatible = "ibm,opb", }, - { .compatible = "ibm,ebc", }, -@@ -29,14 +30,11 @@ static struct of_device_id kilauea_of_bu - - static int __init kilauea_device_probe(void) - { -- if (!machine_is(kilauea)) -- return 0; -- - of_platform_bus_probe(NULL, kilauea_of_bus, NULL); - - return 0; - } --device_initcall(kilauea_device_probe); -+machine_device_initcall(kilauea, kilauea_device_probe); - - static int __init kilauea_probe(void) - { -@@ -45,6 +43,8 @@ static int __init kilauea_probe(void) - if (!of_flat_dt_is_compatible(root, "amcc,kilauea")) - return 0; - -+ ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC; -+ - return 1; - } - ---- /dev/null -+++ b/arch/powerpc/platforms/40x/makalu.c -@@ -0,0 +1,58 @@ -+/* -+ * Makalu board specific routines -+ * -+ * Copyright 2007 DENX Software Engineering, Stefan Roese -+ * -+ * Based on the Walnut code by -+ * Josh Boyer -+ * Copyright 2007 IBM Corporation -+ * -+ * 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 -+ -+static __initdata struct of_device_id makalu_of_bus[] = { -+ { .compatible = "ibm,plb4", }, -+ { .compatible = "ibm,opb", }, -+ { .compatible = "ibm,ebc", }, -+ {}, -+}; -+ -+static int __init makalu_device_probe(void) -+{ -+ of_platform_bus_probe(NULL, makalu_of_bus, NULL); -+ -+ return 0; -+} -+machine_device_initcall(makalu, makalu_device_probe); -+ -+static int __init makalu_probe(void) -+{ -+ unsigned long root = of_get_flat_dt_root(); -+ -+ if (!of_flat_dt_is_compatible(root, "amcc,makalu")) -+ return 0; -+ -+ ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC; -+ -+ return 1; -+} -+ -+define_machine(makalu) { -+ .name = "Makalu", -+ .probe = makalu_probe, -+ .progress = udbg_progress, -+ .init_IRQ = uic_init_tree, -+ .get_irq = uic_get_irq, -+ .calibrate_decr = generic_calibrate_decr, -+}; ---- a/arch/powerpc/platforms/40x/virtex.c -+++ b/arch/powerpc/platforms/40x/virtex.c -@@ -15,16 +15,23 @@ - #include - #include - -+static struct of_device_id xilinx_of_bus_ids[] __initdata = { -+ { .compatible = "xlnx,plb-v46-1.00.a", }, -+ { .compatible = "xlnx,plb-v34-1.01.a", }, -+ { .compatible = "xlnx,plb-v34-1.02.a", }, -+ { .compatible = "xlnx,opb-v20-1.10.c", }, -+ { .compatible = "xlnx,dcr-v29-1.00.a", }, -+ { .compatible = "xlnx,compound", }, -+ {} -+}; -+ - static int __init virtex_device_probe(void) - { -- if (!machine_is(virtex)) -- return 0; -- -- of_platform_bus_probe(NULL, NULL, NULL); -+ of_platform_bus_probe(NULL, xilinx_of_bus_ids, NULL); - - return 0; - } --device_initcall(virtex_device_probe); -+machine_device_initcall(virtex, virtex_device_probe); - - static int __init virtex_probe(void) - { ---- a/arch/powerpc/platforms/40x/walnut.c -+++ b/arch/powerpc/platforms/40x/walnut.c -@@ -24,8 +24,9 @@ - #include - #include - #include -+#include - --static struct of_device_id walnut_of_bus[] = { -+static __initdata struct of_device_id walnut_of_bus[] = { - { .compatible = "ibm,plb3", }, - { .compatible = "ibm,opb", }, - { .compatible = "ibm,ebc", }, -@@ -34,15 +35,12 @@ static struct of_device_id walnut_of_bus - - static int __init walnut_device_probe(void) - { -- if (!machine_is(walnut)) -- return 0; -- -- /* FIXME: do bus probe here */ - of_platform_bus_probe(NULL, walnut_of_bus, NULL); -+ of_instantiate_rtc(); - - return 0; - } --device_initcall(walnut_device_probe); -+machine_device_initcall(walnut, walnut_device_probe); - - static int __init walnut_probe(void) - { -@@ -51,6 +49,8 @@ static int __init walnut_probe(void) - if (!of_flat_dt_is_compatible(root, "ibm,walnut")) - return 0; - -+ ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC; -+ - return 1; - } - ---- a/arch/powerpc/platforms/44x/Kconfig -+++ b/arch/powerpc/platforms/44x/Kconfig -@@ -3,6 +3,7 @@ config BAMBOO - depends on 44x - default n - select 440EP -+ select PCI - help - This option enables support for the IBM PPC440EP evaluation board. - -@@ -11,6 +12,8 @@ config EBONY - depends on 44x - default y - select 440GP -+ select PCI -+ select OF_RTC - help - This option enables support for the IBM PPC440GP evaluation board. - -@@ -22,6 +25,48 @@ config SEQUOIA - help - This option enables support for the AMCC PPC440EPX evaluation board. - -+config TAISHAN -+ bool "Taishan" -+ depends on 44x -+ default n -+ select 440GX -+ select PCI -+ help -+ This option enables support for the AMCC PPC440GX "Taishan" -+ evaluation board. -+ -+config KATMAI -+ bool "Katmai" -+ depends on 44x -+ default n -+ select 440SPe -+ select PCI -+ select PPC4xx_PCI_EXPRESS -+ help -+ This option enables support for the AMCC PPC440SPe evaluation board. -+ -+config RAINIER -+ bool "Rainier" -+ depends on 44x -+ default n -+ select 440GRX -+ select PCI -+ help -+ This option enables support for the AMCC PPC440GRX evaluation board. -+ -+config WARP -+ bool "PIKA Warp" -+ depends on 44x -+ default n -+ select 440EP -+ help -+ This option enables support for the PIKA Warp(tm) Appliance. The Warp -+ is a small computer replacement with up to 9 ports of FXO/FXS plus VOIP -+ stations and trunks. -+ -+ See http://www.pikatechnologies.com/ and follow the "PIKA for Computer -+ Telephony Developers" link for more information. -+ - #config LUAN - # bool "Luan" - # depends on 44x -@@ -44,6 +89,7 @@ config 440EP - select PPC_FPU - select IBM440EP_ERR42 - select IBM_NEW_EMAC_ZMII -+ select USB_ARCH_HAS_OHCI - - config 440EPX - bool -@@ -52,20 +98,29 @@ config 440EPX - select IBM_NEW_EMAC_RGMII - select IBM_NEW_EMAC_ZMII - -+config 440GRX -+ bool -+ select IBM_NEW_EMAC_EMAC4 -+ select IBM_NEW_EMAC_RGMII -+ select IBM_NEW_EMAC_ZMII -+ - config 440GP - bool - select IBM_NEW_EMAC_ZMII - - config 440GX - bool -+ select IBM_NEW_EMAC_EMAC4 -+ select IBM_NEW_EMAC_RGMII -+ select IBM_NEW_EMAC_ZMII #test only -+ select IBM_NEW_EMAC_TAH #test only - - config 440SP - bool - --config 440A -+config 440SPe -+ select IBM_NEW_EMAC_EMAC4 - bool -- depends on 440GX || 440EPX -- default y - - # 44x errata/workaround config symbols, selected by the CPU models above - config IBM440EP_ERR42 ---- a/arch/powerpc/platforms/44x/Makefile -+++ b/arch/powerpc/platforms/44x/Makefile -@@ -1,4 +1,9 @@ - obj-$(CONFIG_44x) := misc_44x.o - obj-$(CONFIG_EBONY) += ebony.o --obj-$(CONFIG_BAMBOO) += bamboo.o -+obj-$(CONFIG_TAISHAN) += taishan.o -+obj-$(CONFIG_BAMBOO) += bamboo.o - obj-$(CONFIG_SEQUOIA) += sequoia.o -+obj-$(CONFIG_KATMAI) += katmai.o -+obj-$(CONFIG_RAINIER) += rainier.o -+obj-$(CONFIG_WARP) += warp.o -+obj-$(CONFIG_WARP) += warp-nand.o ---- a/arch/powerpc/platforms/44x/bamboo.c -+++ b/arch/powerpc/platforms/44x/bamboo.c -@@ -21,9 +21,11 @@ - #include - #include - #include -+#include -+ - #include "44x.h" - --static struct of_device_id bamboo_of_bus[] = { -+static __initdata struct of_device_id bamboo_of_bus[] = { - { .compatible = "ibm,plb4", }, - { .compatible = "ibm,opb", }, - { .compatible = "ibm,ebc", }, -@@ -32,14 +34,11 @@ static struct of_device_id bamboo_of_bus - - static int __init bamboo_device_probe(void) - { -- if (!machine_is(bamboo)) -- return 0; -- - of_platform_bus_probe(NULL, bamboo_of_bus, NULL); - - return 0; - } --device_initcall(bamboo_device_probe); -+machine_device_initcall(bamboo, bamboo_device_probe); - - static int __init bamboo_probe(void) - { -@@ -48,6 +47,8 @@ static int __init bamboo_probe(void) - if (!of_flat_dt_is_compatible(root, "amcc,bamboo")) - return 0; - -+ ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC; -+ - return 1; - } - ---- a/arch/powerpc/platforms/44x/ebony.c -+++ b/arch/powerpc/platforms/44x/ebony.c -@@ -18,16 +18,18 @@ - - #include - #include -+#include - - #include - #include - #include - #include - #include -+#include - - #include "44x.h" - --static struct of_device_id ebony_of_bus[] = { -+static __initdata struct of_device_id ebony_of_bus[] = { - { .compatible = "ibm,plb4", }, - { .compatible = "ibm,opb", }, - { .compatible = "ibm,ebc", }, -@@ -36,14 +38,12 @@ static struct of_device_id ebony_of_bus[ - - static int __init ebony_device_probe(void) - { -- if (!machine_is(ebony)) -- return 0; -- - of_platform_bus_probe(NULL, ebony_of_bus, NULL); -+ of_instantiate_rtc(); - - return 0; - } --device_initcall(ebony_device_probe); -+machine_device_initcall(ebony, ebony_device_probe); - - /* - * Called very early, MMU is off, device-tree isn't unflattened -@@ -55,6 +55,8 @@ static int __init ebony_probe(void) - if (!of_flat_dt_is_compatible(root, "ibm,ebony")) - return 0; - -+ ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC; -+ - return 1; - } - ---- /dev/null -+++ b/arch/powerpc/platforms/44x/katmai.c -@@ -0,0 +1,63 @@ -+/* -+ * Katmai board specific routines -+ * -+ * Benjamin Herrenschmidt -+ * Copyright 2007 IBM Corp. -+ * -+ * Based on the Bamboo code by -+ * Josh Boyer -+ * Copyright 2007 IBM Corporation -+ * -+ * 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 "44x.h" -+ -+static __initdata struct of_device_id katmai_of_bus[] = { -+ { .compatible = "ibm,plb4", }, -+ { .compatible = "ibm,opb", }, -+ { .compatible = "ibm,ebc", }, -+ {}, -+}; -+ -+static int __init katmai_device_probe(void) -+{ -+ of_platform_bus_probe(NULL, katmai_of_bus, NULL); -+ -+ return 0; -+} -+machine_device_initcall(katmai, katmai_device_probe); -+ -+static int __init katmai_probe(void) -+{ -+ unsigned long root = of_get_flat_dt_root(); -+ -+ if (!of_flat_dt_is_compatible(root, "amcc,katmai")) -+ return 0; -+ -+ ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC; -+ -+ return 1; -+} -+ -+define_machine(katmai) { -+ .name = "Katmai", -+ .probe = katmai_probe, -+ .progress = udbg_progress, -+ .init_IRQ = uic_init_tree, -+ .get_irq = uic_get_irq, -+ .restart = ppc44x_reset_system, -+ .calibrate_decr = generic_calibrate_decr, -+}; ---- /dev/null -+++ b/arch/powerpc/platforms/44x/rainier.c -@@ -0,0 +1,62 @@ -+/* -+ * Rainier board specific routines -+ * -+ * Valentine Barshak -+ * Copyright 2007 MontaVista Software Inc. -+ * -+ * Based on the Bamboo code by -+ * Josh Boyer -+ * Copyright 2007 IBM Corporation -+ * -+ * 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 "44x.h" -+ -+static __initdata struct of_device_id rainier_of_bus[] = { -+ { .compatible = "ibm,plb4", }, -+ { .compatible = "ibm,opb", }, -+ { .compatible = "ibm,ebc", }, -+ {}, -+}; -+ -+static int __init rainier_device_probe(void) -+{ -+ of_platform_bus_probe(NULL, rainier_of_bus, NULL); -+ -+ return 0; -+} -+machine_device_initcall(rainier, rainier_device_probe); -+ -+static int __init rainier_probe(void) -+{ -+ unsigned long root = of_get_flat_dt_root(); -+ -+ if (!of_flat_dt_is_compatible(root, "amcc,rainier")) -+ return 0; -+ -+ ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC; -+ -+ return 1; -+} -+ -+define_machine(rainier) { -+ .name = "Rainier", -+ .probe = rainier_probe, -+ .progress = udbg_progress, -+ .init_IRQ = uic_init_tree, -+ .get_irq = uic_get_irq, -+ .restart = ppc44x_reset_system, -+ .calibrate_decr = generic_calibrate_decr, -+}; ---- a/arch/powerpc/platforms/44x/sequoia.c -+++ b/arch/powerpc/platforms/44x/sequoia.c -@@ -21,9 +21,11 @@ - #include - #include - #include -+#include -+ - #include "44x.h" - --static struct of_device_id sequoia_of_bus[] = { -+static __initdata struct of_device_id sequoia_of_bus[] = { - { .compatible = "ibm,plb4", }, - { .compatible = "ibm,opb", }, - { .compatible = "ibm,ebc", }, -@@ -32,14 +34,11 @@ static struct of_device_id sequoia_of_bu - - static int __init sequoia_device_probe(void) - { -- if (!machine_is(sequoia)) -- return 0; -- - of_platform_bus_probe(NULL, sequoia_of_bus, NULL); - - return 0; - } --device_initcall(sequoia_device_probe); -+machine_device_initcall(sequoia, sequoia_device_probe); - - static int __init sequoia_probe(void) - { -@@ -48,6 +47,8 @@ static int __init sequoia_probe(void) - if (!of_flat_dt_is_compatible(root, "amcc,sequoia")) - return 0; - -+ ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC; -+ - return 1; - } - ---- /dev/null -+++ b/arch/powerpc/platforms/44x/taishan.c -@@ -0,0 +1,73 @@ -+/* -+ * Taishan board specific routines based off ebony.c code -+ * original copyrights below -+ * -+ * Matt Porter -+ * Copyright 2002-2005 MontaVista Software Inc. -+ * -+ * Eugene Surovegin or -+ * Copyright (c) 2003-2005 Zultys Technologies -+ * -+ * Rewritten and ported to the merged powerpc tree: -+ * Copyright 2007 David Gibson , IBM Corporation. -+ * -+ * Modified from ebony.c for taishan: -+ * Copyright 2007 Hugh Blemings , IBM Corporation. -+ * -+ * 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 "44x.h" -+ -+static __initdata struct of_device_id taishan_of_bus[] = { -+ { .compatible = "ibm,plb4", }, -+ { .compatible = "ibm,opb", }, -+ { .compatible = "ibm,ebc", }, -+ {}, -+}; -+ -+static int __init taishan_device_probe(void) -+{ -+ of_platform_bus_probe(NULL, taishan_of_bus, NULL); -+ -+ return 0; -+} -+machine_device_initcall(taishan, taishan_device_probe); -+ -+/* -+ * Called very early, MMU is off, device-tree isn't unflattened -+ */ -+static int __init taishan_probe(void) -+{ -+ unsigned long root = of_get_flat_dt_root(); -+ -+ if (!of_flat_dt_is_compatible(root, "amcc,taishan")) -+ return 0; -+ -+ ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC; -+ -+ return 1; -+} -+ -+define_machine(taishan) { -+ .name = "Taishan", -+ .probe = taishan_probe, -+ .progress = udbg_progress, -+ .init_IRQ = uic_init_tree, -+ .get_irq = uic_get_irq, -+ .restart = ppc44x_reset_system, -+ .calibrate_decr = generic_calibrate_decr, -+}; ---- /dev/null -+++ b/arch/powerpc/platforms/44x/warp-nand.c -@@ -0,0 +1,105 @@ -+/* -+ * PIKA Warp(tm) NAND flash specific routines -+ * -+ * Copyright (c) 2008 PIKA Technologies -+ * Sean MacLennan -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#ifdef CONFIG_MTD_NAND_NDFC -+ -+#define CS_NAND_0 1 /* use chip select 1 for NAND device 0 */ -+ -+#define WARP_NAND_FLASH_REG_ADDR 0xD0000000UL -+#define WARP_NAND_FLASH_REG_SIZE 0x2000 -+ -+static struct resource warp_ndfc = { -+ .start = WARP_NAND_FLASH_REG_ADDR, -+ .end = WARP_NAND_FLASH_REG_ADDR + WARP_NAND_FLASH_REG_SIZE, -+ .flags = IORESOURCE_MEM, -+}; -+ -+static struct mtd_partition nand_parts[] = { -+ { -+ .name = "kernel", -+ .offset = 0, -+ .size = 0x0200000 -+ }, -+ { -+ .name = "root", -+ .offset = 0x0200000, -+ .size = 0x3400000 -+ }, -+ { -+ .name = "user", -+ .offset = 0x3600000, -+ .size = 0x0A00000 -+ }, -+}; -+ -+struct ndfc_controller_settings warp_ndfc_settings = { -+ .ccr_settings = (NDFC_CCR_BS(CS_NAND_0) | NDFC_CCR_ARAC1), -+ .ndfc_erpn = 0, -+}; -+ -+static struct ndfc_chip_settings warp_chip0_settings = { -+ .bank_settings = 0x80002222, -+}; -+ -+struct platform_nand_ctrl warp_nand_ctrl = { -+ .priv = &warp_ndfc_settings, -+}; -+ -+static struct platform_device warp_ndfc_device = { -+ .name = "ndfc-nand", -+ .id = 0, -+ .dev = { -+ .platform_data = &warp_nand_ctrl, -+ }, -+ .num_resources = 1, -+ .resource = &warp_ndfc, -+}; -+ -+static struct nand_ecclayout nand_oob_16 = { -+ .eccbytes = 3, -+ .eccpos = { 0, 1, 2, 3, 6, 7 }, -+ .oobfree = { {.offset = 8, .length = 16} } -+}; -+ -+static struct platform_nand_chip warp_nand_chip0 = { -+ .nr_chips = 1, -+ .chip_offset = CS_NAND_0, -+ .nr_partitions = ARRAY_SIZE(nand_parts), -+ .partitions = nand_parts, -+ .chip_delay = 50, -+ .ecclayout = &nand_oob_16, -+ .priv = &warp_chip0_settings, -+}; -+ -+static struct platform_device warp_nand_device = { -+ .name = "ndfc-chip", -+ .id = 0, -+ .num_resources = 1, -+ .resource = &warp_ndfc, -+ .dev = { -+ .platform_data = &warp_nand_chip0, -+ .parent = &warp_ndfc_device.dev, -+ } -+}; -+ -+static int warp_setup_nand_flash(void) -+{ -+ platform_device_register(&warp_ndfc_device); -+ platform_device_register(&warp_nand_device); -+ -+ return 0; -+} -+device_initcall(warp_setup_nand_flash); -+ -+#endif ---- /dev/null -+++ b/arch/powerpc/platforms/44x/warp.c -@@ -0,0 +1,153 @@ -+/* -+ * PIKA Warp(tm) board specific routines -+ * -+ * Copyright (c) 2008 PIKA Technologies -+ * Sean MacLennan -+ * -+ * 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 "44x.h" -+ -+ -+static __initdata struct of_device_id warp_of_bus[] = { -+ { .compatible = "ibm,plb4", }, -+ { .compatible = "ibm,opb", }, -+ { .compatible = "ibm,ebc", }, -+ {}, -+}; -+ -+static int __init warp_device_probe(void) -+{ -+ of_platform_bus_probe(NULL, warp_of_bus, NULL); -+ return 0; -+} -+machine_device_initcall(warp, warp_device_probe); -+ -+static int __init warp_probe(void) -+{ -+ unsigned long root = of_get_flat_dt_root(); -+ -+ return of_flat_dt_is_compatible(root, "pika,warp"); -+} -+ -+define_machine(warp) { -+ .name = "Warp", -+ .probe = warp_probe, -+ .progress = udbg_progress, -+ .init_IRQ = uic_init_tree, -+ .get_irq = uic_get_irq, -+ .restart = ppc44x_reset_system, -+ .calibrate_decr = generic_calibrate_decr, -+}; -+ -+ -+#define LED_GREEN (0x80000000 >> 0) -+#define LED_RED (0x80000000 >> 1) -+ -+ -+/* This is for the power LEDs 1 = on, 0 = off, -1 = leave alone */ -+void warp_set_power_leds(int green, int red) -+{ -+ static void __iomem *gpio_base = NULL; -+ unsigned leds; -+ -+ if (gpio_base == NULL) { -+ struct device_node *np; -+ -+ /* Power LEDS are on the second GPIO controller */ -+ np = of_find_compatible_node(NULL, NULL, "ibm,gpio-440EP"); -+ if (np) -+ np = of_find_compatible_node(np, NULL, "ibm,gpio-440EP"); -+ if (np == NULL) { -+ printk(KERN_ERR __FILE__ ": Unable to find gpio\n"); -+ return; -+ } -+ -+ gpio_base = of_iomap(np, 0); -+ of_node_put(np); -+ if (gpio_base == NULL) { -+ printk(KERN_ERR __FILE__ ": Unable to map gpio"); -+ return; -+ } -+ } -+ -+ leds = in_be32(gpio_base); -+ -+ switch (green) { -+ case 0: leds &= ~LED_GREEN; break; -+ case 1: leds |= LED_GREEN; break; -+ } -+ switch (red) { -+ case 0: leds &= ~LED_RED; break; -+ case 1: leds |= LED_RED; break; -+ } -+ -+ out_be32(gpio_base, leds); -+} -+EXPORT_SYMBOL(warp_set_power_leds); -+ -+ -+#ifdef CONFIG_SENSORS_AD7414 -+static int pika_dtm_thread(void __iomem *fpga) -+{ -+ extern int ad7414_get_temp(int index); -+ -+ while (!kthread_should_stop()) { -+ int temp = ad7414_get_temp(0); -+ -+ out_be32(fpga, temp); -+ -+ set_current_state(TASK_INTERRUPTIBLE); -+ schedule_timeout(HZ); -+ } -+ -+ return 0; -+} -+ -+static int __init pika_dtm_start(void) -+{ -+ struct task_struct *dtm_thread; -+ struct device_node *np; -+ struct resource res; -+ void __iomem *fpga; -+ -+ np = of_find_compatible_node(NULL, NULL, "pika,fpga"); -+ if (np == NULL) -+ return -ENOENT; -+ -+ /* We do not call of_iomap here since it would map in the entire -+ * fpga space, which is over 8k. -+ */ -+ if (of_address_to_resource(np, 0, &res)) { -+ of_node_put(np); -+ return -ENOENT; -+ } -+ of_node_put(np); -+ -+ fpga = ioremap(res.start + 0x20, 4); -+ if (fpga == NULL) -+ return -ENOENT; -+ -+ dtm_thread = kthread_run(pika_dtm_thread, fpga + 0x20, "pika-dtm"); -+ if (IS_ERR(dtm_thread)) { -+ iounmap(fpga); -+ return PTR_ERR(dtm_thread); -+ } -+ -+ return 0; -+} -+device_initcall(pika_dtm_start); -+#endif ---- a/arch/powerpc/platforms/52xx/Kconfig -+++ b/arch/powerpc/platforms/52xx/Kconfig -@@ -19,6 +19,28 @@ config PPC_MPC5200_BUGFIX - - It is safe to say 'Y' here - -+config PPC_MPC5200_SIMPLE -+ bool "Generic support for simple MPC5200 based boards" -+ depends on PPC_MULTIPLATFORM && PPC32 -+ select PPC_MPC5200 -+ select DEFAULT_UIMAGE -+ select WANT_DEVICE_TREE -+ default n -+ help -+ This option enables support for a simple MPC52xx based boards which -+ do not need a custom platform specific setup. Such boards are -+ supported assuming the following: -+ -+ - GPIO pins are configured by the firmware, -+ - CDM configuration (clocking) is setup correctly by firmware, -+ - if the 'fsl,has-wdt' property is present in one of the -+ gpt nodes, then it is safe to use such gpt to reset the board, -+ - PCI is supported if enabled in the kernel configuration -+ and if there is a PCI bus node defined in the device tree. -+ -+ Boards that are compatible with this generic platform support -+ are: 'tqc,tqm5200', 'promess,motionpro', 'schindler,cm5200'. -+ - config PPC_EFIKA - bool "bPlan Efika 5k2. MPC5200B based computer" - depends on PPC_MULTIPLATFORM && PPC32 -@@ -31,8 +53,7 @@ config PPC_EFIKA - config PPC_LITE5200 - bool "Freescale Lite5200 Eval Board" - depends on PPC_MULTIPLATFORM && PPC32 -- select WANT_DEVICE_TREE - select PPC_MPC5200 -+ select DEFAULT_UIMAGE -+ select WANT_DEVICE_TREE - default n -- -- ---- a/arch/powerpc/platforms/52xx/Makefile -+++ b/arch/powerpc/platforms/52xx/Makefile -@@ -6,6 +6,7 @@ obj-y += mpc52xx_pic.o mpc52xx_common - obj-$(CONFIG_PCI) += mpc52xx_pci.o - endif - -+obj-$(CONFIG_PPC_MPC5200_SIMPLE) += mpc5200_simple.o - obj-$(CONFIG_PPC_EFIKA) += efika.o - obj-$(CONFIG_PPC_LITE5200) += lite5200.o - ---- a/arch/powerpc/platforms/52xx/lite5200.c -+++ b/arch/powerpc/platforms/52xx/lite5200.c -@@ -42,10 +42,13 @@ - static void __init - lite5200_fix_clock_config(void) - { -+ struct device_node *np; - struct mpc52xx_cdm __iomem *cdm; - - /* Map zones */ -- cdm = mpc52xx_find_and_map("mpc5200-cdm"); -+ np = of_find_compatible_node(NULL, NULL, "mpc5200-cdm"); -+ cdm = of_iomap(np, 0); -+ of_node_put(np); - if (!cdm) { - printk(KERN_ERR "%s() failed; expect abnormal behaviour\n", - __FUNCTION__); -@@ -74,10 +77,13 @@ lite5200_fix_clock_config(void) - static void __init - lite5200_fix_port_config(void) - { -+ struct device_node *np; - struct mpc52xx_gpio __iomem *gpio; - u32 port_config; - -- gpio = mpc52xx_find_and_map("mpc5200-gpio"); -+ np = of_find_compatible_node(NULL, NULL, "mpc5200-gpio"); -+ gpio = of_iomap(np, 0); -+ of_node_put(np); - if (!gpio) { - printk(KERN_ERR "%s() failed. expect abnormal behavior\n", - __FUNCTION__); -@@ -131,10 +137,6 @@ static void lite5200_resume_finish(void - - static void __init lite5200_setup_arch(void) - { --#ifdef CONFIG_PCI -- struct device_node *np; --#endif -- - if (ppc_md.progress) - ppc_md.progress("lite5200_setup_arch()", 0); - -@@ -154,13 +156,7 @@ static void __init lite5200_setup_arch(v - lite5200_pm_init(); - #endif - --#ifdef CONFIG_PCI -- np = of_find_node_by_type(NULL, "pci"); -- if (np) { -- mpc52xx_add_bridge(np); -- of_node_put(np); -- } --#endif -+ mpc52xx_setup_pci(); - } - - /* ---- a/arch/powerpc/platforms/52xx/lite5200_pm.c -+++ b/arch/powerpc/platforms/52xx/lite5200_pm.c -@@ -42,6 +42,8 @@ static int lite5200_pm_set_target(suspen - - static int lite5200_pm_prepare(void) - { -+ struct device_node *np; -+ - /* deep sleep? let mpc52xx code handle that */ - if (lite5200_pm_target_state == PM_SUSPEND_STANDBY) - return mpc52xx_pm_prepare(); -@@ -50,7 +52,9 @@ static int lite5200_pm_prepare(void) - return -EINVAL; - - /* map registers */ -- mbar = mpc52xx_find_and_map("mpc5200"); -+ np = of_find_compatible_node(NULL, NULL, "mpc5200"); -+ mbar = of_iomap(np, 0); -+ of_node_put(np); - if (!mbar) { - printk(KERN_ERR "%s:%i Error mapping registers\n", __func__, __LINE__); - return -ENOSYS; ---- /dev/null -+++ b/arch/powerpc/platforms/52xx/mpc5200_simple.c -@@ -0,0 +1,85 @@ -+/* -+ * Support for 'mpc5200-simple-platform' compatible boards. -+ * -+ * Written by Marian Balakowicz -+ * Copyright (C) 2007 Semihalf -+ * -+ * 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. -+ * -+ * Description: -+ * This code implements support for a simple MPC52xx based boards which -+ * do not need a custom platform specific setup. Such boards are -+ * supported assuming the following: -+ * -+ * - GPIO pins are configured by the firmware, -+ * - CDM configuration (clocking) is setup correctly by firmware, -+ * - if the 'fsl,has-wdt' property is present in one of the -+ * gpt nodes, then it is safe to use such gpt to reset the board, -+ * - PCI is supported if enabled in the kernel configuration -+ * and if there is a PCI bus node defined in the device tree. -+ * -+ * Boards that are compatible with this generic platform support -+ * are listed in a 'board' table. -+ */ -+ -+#undef DEBUG -+#include -+#include -+#include -+#include -+ -+/* -+ * Setup the architecture -+ */ -+static void __init mpc5200_simple_setup_arch(void) -+{ -+ if (ppc_md.progress) -+ ppc_md.progress("mpc5200_simple_setup_arch()", 0); -+ -+ /* Some mpc5200 & mpc5200b related configuration */ -+ mpc5200_setup_xlb_arbiter(); -+ -+ /* Map wdt for mpc52xx_restart() */ -+ mpc52xx_map_wdt(); -+ -+ mpc52xx_setup_pci(); -+} -+ -+/* list of the supported boards */ -+static char *board[] __initdata = { -+ "promess,motionpro", -+ "schindler,cm5200", -+ "tqc,tqm5200", -+ NULL -+}; -+ -+/* -+ * Called very early, MMU is off, device-tree isn't unflattened -+ */ -+static int __init mpc5200_simple_probe(void) -+{ -+ unsigned long node = of_get_flat_dt_root(); -+ int i = 0; -+ -+ while (board[i]) { -+ if (of_flat_dt_is_compatible(node, board[i])) -+ break; -+ i++; -+ } -+ -+ return (board[i] != NULL); -+} -+ -+define_machine(mpc5200_simple_platform) { -+ .name = "mpc5200-simple-platform", -+ .probe = mpc5200_simple_probe, -+ .setup_arch = mpc5200_simple_setup_arch, -+ .init = mpc52xx_declare_of_platform_devices, -+ .init_IRQ = mpc52xx_init_irq, -+ .get_irq = mpc52xx_get_irq, -+ .restart = mpc52xx_restart, -+ .calibrate_decr = generic_calibrate_decr, -+}; ---- a/arch/powerpc/platforms/52xx/mpc52xx_common.c -+++ b/arch/powerpc/platforms/52xx/mpc52xx_common.c -@@ -26,45 +26,6 @@ - */ - static volatile struct mpc52xx_gpt *mpc52xx_wdt = NULL; - --static void __iomem * --mpc52xx_map_node(struct device_node *ofn) --{ -- const u32 *regaddr_p; -- u64 regaddr64, size64; -- -- if (!ofn) -- return NULL; -- -- regaddr_p = of_get_address(ofn, 0, &size64, NULL); -- if (!regaddr_p) { -- of_node_put(ofn); -- return NULL; -- } -- -- regaddr64 = of_translate_address(ofn, regaddr_p); -- -- of_node_put(ofn); -- -- return ioremap((u32)regaddr64, (u32)size64); --} -- --void __iomem * --mpc52xx_find_and_map(const char *compatible) --{ -- return mpc52xx_map_node( -- of_find_compatible_node(NULL, NULL, compatible)); --} -- --EXPORT_SYMBOL(mpc52xx_find_and_map); -- --void __iomem * --mpc52xx_find_and_map_path(const char *path) --{ -- return mpc52xx_map_node(of_find_node_by_path(path)); --} -- --EXPORT_SYMBOL(mpc52xx_find_and_map_path); -- - /** - * mpc52xx_find_ipb_freq - Find the IPB bus frequency for a device - * @node: device node -@@ -101,9 +62,12 @@ EXPORT_SYMBOL(mpc52xx_find_ipb_freq); - void __init - mpc5200_setup_xlb_arbiter(void) - { -+ struct device_node *np; - struct mpc52xx_xlb __iomem *xlb; - -- xlb = mpc52xx_find_and_map("mpc5200-xlb"); -+ np = of_find_compatible_node(NULL, NULL, "mpc5200-xlb"); -+ xlb = of_iomap(np, 0); -+ of_node_put(np); - if (!xlb) { - printk(KERN_ERR __FILE__ ": " - "Error mapping XLB in mpc52xx_setup_cpu(). " -@@ -124,11 +88,21 @@ mpc5200_setup_xlb_arbiter(void) - iounmap(xlb); - } - -+static struct of_device_id mpc52xx_bus_ids[] __initdata= { -+ { .compatible = "fsl,mpc5200-immr", }, -+ { .compatible = "fsl,lpb", }, -+ -+ /* depreciated matches; shouldn't be used in new device trees */ -+ { .type = "builtin", .compatible = "mpc5200", }, /* efika */ -+ { .type = "soc", .compatible = "mpc5200", }, /* lite5200 */ -+ {}, -+}; -+ - void __init - mpc52xx_declare_of_platform_devices(void) - { - /* Find every child of the SOC node and add it to of_platform */ -- if (of_platform_bus_probe(NULL, NULL, NULL)) -+ if (of_platform_bus_probe(NULL, mpc52xx_bus_ids, NULL)) - printk(KERN_ERR __FILE__ ": " - "Error while probing of_platform bus\n"); - } -@@ -146,16 +120,19 @@ mpc52xx_map_wdt(void) - for_each_compatible_node(np, NULL, "fsl,mpc5200-gpt") { - has_wdt = of_get_property(np, "fsl,has-wdt", NULL); - if (has_wdt) { -- mpc52xx_wdt = mpc52xx_map_node(np); -+ mpc52xx_wdt = of_iomap(np, 0); -+ of_node_put(np); - return; - } - } - for_each_compatible_node(np, NULL, "mpc5200-gpt") { - has_wdt = of_get_property(np, "has-wdt", NULL); - if (has_wdt) { -- mpc52xx_wdt = mpc52xx_map_node(np); -+ mpc52xx_wdt = of_iomap(np, 0); -+ of_node_put(np); - return; - } -+ - } - } - ---- a/arch/powerpc/platforms/52xx/mpc52xx_pci.c -+++ b/arch/powerpc/platforms/52xx/mpc52xx_pci.c -@@ -363,7 +363,7 @@ mpc52xx_add_bridge(struct device_node *n - - pr_debug("Adding MPC52xx PCI host bridge %s\n", node->full_name); - -- pci_assign_all_buses = 1; -+ ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS; - - if (of_address_to_resource(node, 0, &rsrc) != 0) { - printk(KERN_ERR "Can't get %s resources\n", node->full_name); -@@ -406,3 +406,17 @@ mpc52xx_add_bridge(struct device_node *n - - return 0; - } -+ -+void __init mpc52xx_setup_pci(void) -+{ -+ struct device_node *pci; -+ -+ pci = of_find_compatible_node(NULL, NULL, "fsl,mpc5200-pci"); -+ if (!pci) -+ pci = of_find_compatible_node(NULL, NULL, "mpc5200-pci"); -+ if (!pci) -+ return; -+ -+ mpc52xx_add_bridge(pci); -+ of_node_put(pci); -+} ---- a/arch/powerpc/platforms/52xx/mpc52xx_pic.c -+++ b/arch/powerpc/platforms/52xx/mpc52xx_pic.c -@@ -364,16 +364,18 @@ void __init mpc52xx_init_irq(void) - { - u32 intr_ctrl; - struct device_node *picnode; -+ struct device_node *np; - - /* Remap the necessary zones */ - picnode = of_find_compatible_node(NULL, NULL, "mpc5200-pic"); -- -- intr = mpc52xx_find_and_map("mpc5200-pic"); -+ intr = of_iomap(picnode, 0); - if (!intr) - panic(__FILE__ ": find_and_map failed on 'mpc5200-pic'. " - "Check node !"); - -- sdma = mpc52xx_find_and_map("mpc5200-bestcomm"); -+ np = of_find_compatible_node(NULL, NULL, "mpc5200-bestcomm"); -+ sdma = of_iomap(np, 0); -+ of_node_put(np); - if (!sdma) - panic(__FILE__ ": find_and_map failed on 'mpc5200-bestcomm'. " - "Check node !"); ---- a/arch/powerpc/platforms/52xx/mpc52xx_pm.c -+++ b/arch/powerpc/platforms/52xx/mpc52xx_pm.c -@@ -59,10 +59,14 @@ int mpc52xx_set_wakeup_gpio(u8 pin, u8 l - - int mpc52xx_pm_prepare(void) - { -+ struct device_node *np; -+ - /* map the whole register space */ -- mbar = mpc52xx_find_and_map("mpc5200"); -+ np = of_find_compatible_node(NULL, NULL, "mpc5200"); -+ mbar = of_iomap(np, 0); -+ of_node_put(np); - if (!mbar) { -- printk(KERN_ERR "%s:%i Error mapping registers\n", __func__, __LINE__); -+ pr_err("mpc52xx_pm_prepare(): could not map registers\n"); - return -ENOSYS; - } - /* these offsets are from mpc5200 users manual */ ---- a/arch/powerpc/platforms/82xx/Kconfig -+++ b/arch/powerpc/platforms/82xx/Kconfig -@@ -26,6 +26,19 @@ config PQ2FADS - help - This option enables support for the PQ2FADS board - -+config EP8248E -+ bool "Embedded Planet EP8248E (a.k.a. CWH-PPC-8248N-VE)" -+ select 8272 -+ select 8260 -+ select FSL_SOC -+ select PPC_CPM_NEW_BINDING -+ select MDIO_BITBANG -+ help -+ This enables support for the Embedded Planet EP8248E board. -+ -+ This board is also resold by Freescale as the QUICCStart -+ MPC8248 Evaluation System and/or the CWH-PPC-8248N-VE. -+ - endchoice - - config PQ2ADS ---- a/arch/powerpc/platforms/82xx/Makefile -+++ b/arch/powerpc/platforms/82xx/Makefile -@@ -5,3 +5,4 @@ obj-$(CONFIG_MPC8272_ADS) += mpc8272_ads - obj-$(CONFIG_CPM2) += pq2.o - obj-$(CONFIG_PQ2_ADS_PCI_PIC) += pq2ads-pci-pic.o - obj-$(CONFIG_PQ2FADS) += pq2fads.o -+obj-$(CONFIG_EP8248E) += ep8248e.o ---- /dev/null -+++ b/arch/powerpc/platforms/82xx/ep8248e.c -@@ -0,0 +1,324 @@ -+/* -+ * Embedded Planet EP8248E support -+ * -+ * Copyright 2007 Freescale Semiconductor, Inc. -+ * Author: Scott Wood -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "pq2.h" -+ -+static u8 __iomem *ep8248e_bcsr; -+static struct device_node *ep8248e_bcsr_node; -+ -+#define BCSR7_SCC2_ENABLE 0x10 -+ -+#define BCSR8_PHY1_ENABLE 0x80 -+#define BCSR8_PHY1_POWER 0x40 -+#define BCSR8_PHY2_ENABLE 0x20 -+#define BCSR8_PHY2_POWER 0x10 -+#define BCSR8_MDIO_READ 0x04 -+#define BCSR8_MDIO_CLOCK 0x02 -+#define BCSR8_MDIO_DATA 0x01 -+ -+#define BCSR9_USB_ENABLE 0x80 -+#define BCSR9_USB_POWER 0x40 -+#define BCSR9_USB_HOST 0x20 -+#define BCSR9_USB_FULL_SPEED_TARGET 0x10 -+ -+static void __init ep8248e_pic_init(void) -+{ -+ struct device_node *np = of_find_compatible_node(NULL, NULL, "fsl,pq2-pic"); -+ if (!np) { -+ printk(KERN_ERR "PIC init: can not find cpm-pic node\n"); -+ return; -+ } -+ -+ cpm2_pic_init(np); -+ of_node_put(np); -+} -+ -+static void ep8248e_set_mdc(struct mdiobb_ctrl *ctrl, int level) -+{ -+ if (level) -+ setbits8(&ep8248e_bcsr[8], BCSR8_MDIO_CLOCK); -+ else -+ clrbits8(&ep8248e_bcsr[8], BCSR8_MDIO_CLOCK); -+ -+ /* Read back to flush the write. */ -+ in_8(&ep8248e_bcsr[8]); -+} -+ -+static void ep8248e_set_mdio_dir(struct mdiobb_ctrl *ctrl, int output) -+{ -+ if (output) -+ clrbits8(&ep8248e_bcsr[8], BCSR8_MDIO_READ); -+ else -+ setbits8(&ep8248e_bcsr[8], BCSR8_MDIO_READ); -+ -+ /* Read back to flush the write. */ -+ in_8(&ep8248e_bcsr[8]); -+} -+ -+static void ep8248e_set_mdio_data(struct mdiobb_ctrl *ctrl, int data) -+{ -+ if (data) -+ setbits8(&ep8248e_bcsr[8], BCSR8_MDIO_DATA); -+ else -+ clrbits8(&ep8248e_bcsr[8], BCSR8_MDIO_DATA); -+ -+ /* Read back to flush the write. */ -+ in_8(&ep8248e_bcsr[8]); -+} -+ -+static int ep8248e_get_mdio_data(struct mdiobb_ctrl *ctrl) -+{ -+ return in_8(&ep8248e_bcsr[8]) & BCSR8_MDIO_DATA; -+} -+ -+static const struct mdiobb_ops ep8248e_mdio_ops = { -+ .set_mdc = ep8248e_set_mdc, -+ .set_mdio_dir = ep8248e_set_mdio_dir, -+ .set_mdio_data = ep8248e_set_mdio_data, -+ .get_mdio_data = ep8248e_get_mdio_data, -+ .owner = THIS_MODULE, -+}; -+ -+static struct mdiobb_ctrl ep8248e_mdio_ctrl = { -+ .ops = &ep8248e_mdio_ops, -+}; -+ -+static int __devinit ep8248e_mdio_probe(struct of_device *ofdev, -+ const struct of_device_id *match) -+{ -+ struct mii_bus *bus; -+ struct resource res; -+ struct device_node *node; -+ int ret, i; -+ -+ node = of_get_parent(ofdev->node); -+ of_node_put(node); -+ if (node != ep8248e_bcsr_node) -+ return -ENODEV; -+ -+ ret = of_address_to_resource(ofdev->node, 0, &res); -+ if (ret) -+ return ret; -+ -+ bus = alloc_mdio_bitbang(&ep8248e_mdio_ctrl); -+ if (!bus) -+ return -ENOMEM; -+ -+ bus->phy_mask = 0; -+ bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); -+ -+ for (i = 0; i < PHY_MAX_ADDR; i++) -+ bus->irq[i] = -1; -+ -+ bus->name = "ep8248e-mdio-bitbang"; -+ bus->dev = &ofdev->dev; -+ bus->id = res.start; -+ -+ return mdiobus_register(bus); -+} -+ -+static int ep8248e_mdio_remove(struct of_device *ofdev) -+{ -+ BUG(); -+ return 0; -+} -+ -+static const struct of_device_id ep8248e_mdio_match[] = { -+ { -+ .compatible = "fsl,ep8248e-mdio-bitbang", -+ }, -+ {}, -+}; -+ -+static struct of_platform_driver ep8248e_mdio_driver = { -+ .driver = { -+ .name = "ep8248e-mdio-bitbang", -+ }, -+ .match_table = ep8248e_mdio_match, -+ .probe = ep8248e_mdio_probe, -+ .remove = ep8248e_mdio_remove, -+}; -+ -+struct cpm_pin { -+ int port, pin, flags; -+}; -+ -+static __initdata struct cpm_pin ep8248e_pins[] = { -+ /* SMC1 */ -+ {2, 4, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, -+ {2, 5, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, -+ -+ /* SCC1 */ -+ {2, 14, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, -+ {2, 15, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, -+ {3, 29, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, -+ {3, 30, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY}, -+ {3, 31, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, -+ -+ /* FCC1 */ -+ {0, 14, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, -+ {0, 15, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, -+ {0, 16, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, -+ {0, 17, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, -+ {0, 18, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, -+ {0, 19, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, -+ {0, 20, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, -+ {0, 21, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, -+ {0, 26, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, -+ {0, 27, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, -+ {0, 28, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY}, -+ {0, 29, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY}, -+ {0, 30, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, -+ {0, 31, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, -+ {2, 21, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, -+ {2, 22, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, -+ -+ /* FCC2 */ -+ {1, 18, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, -+ {1, 19, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, -+ {1, 20, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, -+ {1, 21, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, -+ {1, 22, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, -+ {1, 23, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, -+ {1, 24, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, -+ {1, 25, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, -+ {1, 26, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, -+ {1, 27, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, -+ {1, 28, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, -+ {1, 29, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY}, -+ {1, 30, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, -+ {1, 31, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, -+ {2, 18, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, -+ {2, 19, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, -+ -+ /* I2C */ -+ {4, 14, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, -+ {4, 15, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, -+ -+ /* USB */ -+ {2, 10, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, -+ {2, 11, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, -+ {2, 20, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, -+ {2, 24, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, -+ {3, 23, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, -+ {3, 24, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, -+ {3, 25, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, -+}; -+ -+static void __init init_ioports(void) -+{ -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(ep8248e_pins); i++) { -+ const struct cpm_pin *pin = &ep8248e_pins[i]; -+ cpm2_set_pin(pin->port, pin->pin, pin->flags); -+ } -+ -+ cpm2_smc_clk_setup(CPM_CLK_SMC1, CPM_BRG7); -+ cpm2_clk_setup(CPM_CLK_SCC1, CPM_BRG1, CPM_CLK_RX); -+ cpm2_clk_setup(CPM_CLK_SCC1, CPM_BRG1, CPM_CLK_TX); -+ cpm2_clk_setup(CPM_CLK_SCC3, CPM_CLK8, CPM_CLK_TX); /* USB */ -+ cpm2_clk_setup(CPM_CLK_FCC1, CPM_CLK11, CPM_CLK_RX); -+ cpm2_clk_setup(CPM_CLK_FCC1, CPM_CLK10, CPM_CLK_TX); -+ cpm2_clk_setup(CPM_CLK_FCC2, CPM_CLK13, CPM_CLK_RX); -+ cpm2_clk_setup(CPM_CLK_FCC2, CPM_CLK14, CPM_CLK_TX); -+} -+ -+static void __init ep8248e_setup_arch(void) -+{ -+ if (ppc_md.progress) -+ ppc_md.progress("ep8248e_setup_arch()", 0); -+ -+ cpm2_reset(); -+ -+ /* When this is set, snooping CPM DMA from RAM causes -+ * machine checks. See erratum SIU18. -+ */ -+ clrbits32(&cpm2_immr->im_siu_conf.siu_82xx.sc_bcr, MPC82XX_BCR_PLDP); -+ -+ ep8248e_bcsr_node = -+ of_find_compatible_node(NULL, NULL, "fsl,ep8248e-bcsr"); -+ if (!ep8248e_bcsr_node) { -+ printk(KERN_ERR "No bcsr in device tree\n"); -+ return; -+ } -+ -+ ep8248e_bcsr = of_iomap(ep8248e_bcsr_node, 0); -+ if (!ep8248e_bcsr) { -+ printk(KERN_ERR "Cannot map BCSR registers\n"); -+ of_node_put(ep8248e_bcsr_node); -+ ep8248e_bcsr_node = NULL; -+ return; -+ } -+ -+ setbits8(&ep8248e_bcsr[7], BCSR7_SCC2_ENABLE); -+ setbits8(&ep8248e_bcsr[8], BCSR8_PHY1_ENABLE | BCSR8_PHY1_POWER | -+ BCSR8_PHY2_ENABLE | BCSR8_PHY2_POWER); -+ -+ init_ioports(); -+ -+ if (ppc_md.progress) -+ ppc_md.progress("ep8248e_setup_arch(), finish", 0); -+} -+ -+static __initdata struct of_device_id of_bus_ids[] = { -+ { .compatible = "simple-bus", }, -+ { .compatible = "fsl,ep8248e-bcsr", }, -+ {}, -+}; -+ -+static int __init declare_of_platform_devices(void) -+{ -+ of_platform_bus_probe(NULL, of_bus_ids, NULL); -+ of_register_platform_driver(&ep8248e_mdio_driver); -+ -+ return 0; -+} -+machine_device_initcall(ep8248e, declare_of_platform_devices); -+ -+/* -+ * Called very early, device-tree isn't unflattened -+ */ -+static int __init ep8248e_probe(void) -+{ -+ unsigned long root = of_get_flat_dt_root(); -+ return of_flat_dt_is_compatible(root, "fsl,ep8248e"); -+} -+ -+define_machine(ep8248e) -+{ -+ .name = "Embedded Planet EP8248E", -+ .probe = ep8248e_probe, -+ .setup_arch = ep8248e_setup_arch, -+ .init_IRQ = ep8248e_pic_init, -+ .get_irq = cpm2_get_irq, -+ .calibrate_decr = generic_calibrate_decr, -+ .restart = pq2_restart, -+ .progress = udbg_progress, -+}; ---- a/arch/powerpc/platforms/82xx/pq2.c -+++ b/arch/powerpc/platforms/82xx/pq2.c -@@ -53,13 +53,13 @@ static void __init pq2_pci_add_bridge(st - if (of_address_to_resource(np, 0, &r) || r.end - r.start < 0x10b) - goto err; - -- pci_assign_all_buses = 1; -+ ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS; - - hose = pcibios_alloc_controller(np); - if (!hose) - return; - -- hose->arch_data = np; -+ hose->dn = np; - - setup_indirect_pci(hose, r.start + 0x100, r.start + 0x104, 0); - pci_process_bridge_OF_ranges(hose, np, 1); ---- a/arch/powerpc/platforms/82xx/pq2fads.c -+++ b/arch/powerpc/platforms/82xx/pq2fads.c -@@ -15,12 +15,12 @@ - #include - #include - #include -+#include - - #include - #include - #include - #include --#include - #include - - #include ---- a/arch/powerpc/platforms/83xx/Kconfig -+++ b/arch/powerpc/platforms/83xx/Kconfig -@@ -50,6 +50,11 @@ config MPC836x_MDS - help - This option enables support for the MPC836x MDS Processor Board. - -+config MPC837x_MDS -+ bool "Freescale MPC837x MDS" -+ select DEFAULT_UIMAGE -+ help -+ This option enables support for the MPC837x MDS Processor Board. - endchoice - - config PPC_MPC831x -@@ -75,3 +80,9 @@ config PPC_MPC836x - select PPC_UDBG_16550 - select PPC_INDIRECT_PCI - default y if MPC836x_MDS -+ -+config PPC_MPC837x -+ bool -+ select PPC_UDBG_16550 -+ select PPC_INDIRECT_PCI -+ default y if MPC837x_MDS ---- a/arch/powerpc/platforms/83xx/Makefile -+++ b/arch/powerpc/platforms/83xx/Makefile -@@ -9,3 +9,4 @@ obj-$(CONFIG_MPC834x_MDS) += mpc834x_mds - obj-$(CONFIG_MPC834x_ITX) += mpc834x_itx.o - obj-$(CONFIG_MPC836x_MDS) += mpc836x_mds.o - obj-$(CONFIG_MPC832x_MDS) += mpc832x_mds.o -+obj-$(CONFIG_MPC837x_MDS) += mpc837x_mds.o ---- a/arch/powerpc/platforms/83xx/mpc8313_rdb.c -+++ b/arch/powerpc/platforms/83xx/mpc8313_rdb.c -@@ -14,6 +14,7 @@ - */ - - #include -+#include - - #include - #include -@@ -70,11 +71,23 @@ void __init mpc8313_rdb_init_IRQ(void) - */ - static int __init mpc8313_rdb_probe(void) - { -- unsigned long root = of_get_flat_dt_root(); -+ unsigned long root = of_get_flat_dt_root(); - -- return of_flat_dt_is_compatible(root, "MPC8313ERDB"); -+ return of_flat_dt_is_compatible(root, "MPC8313ERDB"); - } - -+static struct of_device_id __initdata of_bus_ids[] = { -+ { .compatible = "simple-bus" }, -+ {}, -+}; -+ -+static int __init declare_of_platform_devices(void) -+{ -+ of_platform_bus_probe(NULL, of_bus_ids, NULL); -+ return 0; -+} -+machine_device_initcall(mpc8313_rdb, declare_of_platform_devices); -+ - define_machine(mpc8313_rdb) { - .name = "MPC8313 RDB", - .probe = mpc8313_rdb_probe, ---- a/arch/powerpc/platforms/83xx/mpc832x_mds.c -+++ b/arch/powerpc/platforms/83xx/mpc832x_mds.c -@@ -23,9 +23,9 @@ - #include - #include - #include -+#include -+#include - --#include --#include - #include - #include - #include -@@ -110,15 +110,12 @@ static struct of_device_id mpc832x_ids[] - - static int __init mpc832x_declare_of_platform_devices(void) - { -- if (!machine_is(mpc832x_mds)) -- return 0; -- - /* Publish the QE devices */ - of_platform_bus_probe(NULL, mpc832x_ids, NULL); - - return 0; - } --device_initcall(mpc832x_declare_of_platform_devices); -+machine_device_initcall(mpc832x_mds, mpc832x_declare_of_platform_devices); - - static void __init mpc832x_sys_init_IRQ(void) - { ---- a/arch/powerpc/platforms/83xx/mpc832x_rdb.c -+++ b/arch/powerpc/platforms/83xx/mpc832x_rdb.c -@@ -19,8 +19,8 @@ - #include - #include - #include -+#include - --#include - #include - #include - #include -@@ -63,9 +63,6 @@ static struct spi_board_info mpc832x_spi - - static int __init mpc832x_spi_init(void) - { -- if (!machine_is(mpc832x_rdb)) -- return 0; -- - par_io_config_pin(3, 0, 3, 0, 1, 0); /* SPI1 MOSI, I/O */ - par_io_config_pin(3, 1, 3, 0, 1, 0); /* SPI1 MISO, I/O */ - par_io_config_pin(3, 2, 3, 0, 1, 0); /* SPI1 CLK, I/O */ -@@ -80,7 +77,7 @@ static int __init mpc832x_spi_init(void) - mpc83xx_spi_deactivate_cs); - } - --device_initcall(mpc832x_spi_init); -+machine_device_initcall(mpc832x_rdb, mpc832x_spi_init); - - /* ************************************************************************ - * -@@ -123,15 +120,12 @@ static struct of_device_id mpc832x_ids[] - - static int __init mpc832x_declare_of_platform_devices(void) - { -- if (!machine_is(mpc832x_rdb)) -- return 0; -- - /* Publish the QE devices */ - of_platform_bus_probe(NULL, mpc832x_ids, NULL); - - return 0; - } --device_initcall(mpc832x_declare_of_platform_devices); -+machine_device_initcall(mpc832x_rdb, mpc832x_declare_of_platform_devices); - - void __init mpc832x_rdb_init_IRQ(void) - { ---- a/arch/powerpc/platforms/83xx/mpc834x_itx.c -+++ b/arch/powerpc/platforms/83xx/mpc834x_itx.c -@@ -23,6 +23,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -37,6 +38,17 @@ - - #include "mpc83xx.h" - -+static struct of_device_id __initdata mpc834x_itx_ids[] = { -+ { .compatible = "fsl,pq2pro-localbus", }, -+ {}, -+}; -+ -+static int __init mpc834x_itx_declare_of_platform_devices(void) -+{ -+ return of_platform_bus_probe(NULL, mpc834x_itx_ids, NULL); -+} -+machine_device_initcall(mpc834x_itx, mpc834x_itx_declare_of_platform_devices); -+ - /* ************************************************************************ - * - * Setup the architecture ---- a/arch/powerpc/platforms/83xx/mpc834x_mds.c -+++ b/arch/powerpc/platforms/83xx/mpc834x_mds.c -@@ -23,6 +23,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -106,14 +107,27 @@ static void __init mpc834x_mds_init_IRQ( - ipic_set_default_priority(); - } - -+static struct of_device_id mpc834x_ids[] = { -+ { .type = "soc", }, -+ { .compatible = "soc", }, -+ {}, -+}; -+ -+static int __init mpc834x_declare_of_platform_devices(void) -+{ -+ of_platform_bus_probe(NULL, mpc834x_ids, NULL); -+ return 0; -+} -+machine_device_initcall(mpc834x_mds, mpc834x_declare_of_platform_devices); -+ - /* - * Called very early, MMU is off, device-tree isn't unflattened - */ - static int __init mpc834x_mds_probe(void) - { -- unsigned long root = of_get_flat_dt_root(); -+ unsigned long root = of_get_flat_dt_root(); - -- return of_flat_dt_is_compatible(root, "MPC834xMDS"); -+ return of_flat_dt_is_compatible(root, "MPC834xMDS"); - } - - define_machine(mpc834x_mds) { ---- a/arch/powerpc/platforms/83xx/mpc836x_mds.c -+++ b/arch/powerpc/platforms/83xx/mpc836x_mds.c -@@ -29,9 +29,9 @@ - #include - #include - #include -+#include -+#include - --#include --#include - #include - #include - #include -@@ -141,15 +141,12 @@ static struct of_device_id mpc836x_ids[] - - static int __init mpc836x_declare_of_platform_devices(void) - { -- if (!machine_is(mpc836x_mds)) -- return 0; -- - /* Publish the QE devices */ - of_platform_bus_probe(NULL, mpc836x_ids, NULL); - - return 0; - } --device_initcall(mpc836x_declare_of_platform_devices); -+machine_device_initcall(mpc836x_mds, mpc836x_declare_of_platform_devices); - - static void __init mpc836x_mds_init_IRQ(void) - { ---- /dev/null -+++ b/arch/powerpc/platforms/83xx/mpc837x_mds.c -@@ -0,0 +1,147 @@ -+/* -+ * arch/powerpc/platforms/83xx/mpc837x_mds.c -+ * -+ * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved. -+ * -+ * MPC837x MDS board specific routines -+ * -+ * 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 "mpc83xx.h" -+ -+#define BCSR12_USB_SER_MASK 0x8a -+#define BCSR12_USB_SER_PIN 0x80 -+#define BCSR12_USB_SER_DEVICE 0x02 -+extern int mpc837x_usb_cfg(void); -+ -+static int mpc837xmds_usb_cfg(void) -+{ -+ struct device_node *np; -+ const void *phy_type, *mode; -+ void __iomem *bcsr_regs = NULL; -+ u8 bcsr12; -+ int ret; -+ -+ ret = mpc837x_usb_cfg(); -+ if (ret) -+ return ret; -+ /* Map BCSR area */ -+ np = of_find_node_by_name(NULL, "bcsr"); -+ if (np) { -+ struct resource res; -+ -+ of_address_to_resource(np, 0, &res); -+ bcsr_regs = ioremap(res.start, res.end - res.start + 1); -+ of_node_put(np); -+ } -+ if (!bcsr_regs) -+ return -1; -+ -+ np = of_find_node_by_name(NULL, "usb"); -+ if (!np) -+ return -ENODEV; -+ phy_type = of_get_property(np, "phy_type", NULL); -+ if (phy_type && !strcmp(phy_type, "ulpi")) { -+ clrbits8(bcsr_regs + 12, BCSR12_USB_SER_PIN); -+ } else if (phy_type && !strcmp(phy_type, "serial")) { -+ mode = of_get_property(np, "dr_mode", NULL); -+ bcsr12 = in_8(bcsr_regs + 12) & ~BCSR12_USB_SER_MASK; -+ bcsr12 |= BCSR12_USB_SER_PIN; -+ if (mode && !strcmp(mode, "peripheral")) -+ bcsr12 |= BCSR12_USB_SER_DEVICE; -+ out_8(bcsr_regs + 12, bcsr12); -+ } else { -+ printk(KERN_ERR "USB DR: unsupported PHY\n"); -+ } -+ -+ of_node_put(np); -+ iounmap(bcsr_regs); -+ return 0; -+} -+ -+/* ************************************************************************ -+ * -+ * Setup the architecture -+ * -+ */ -+static void __init mpc837x_mds_setup_arch(void) -+{ -+#ifdef CONFIG_PCI -+ struct device_node *np; -+#endif -+ -+ if (ppc_md.progress) -+ ppc_md.progress("mpc837x_mds_setup_arch()", 0); -+ -+#ifdef CONFIG_PCI -+ for_each_compatible_node(np, "pci", "fsl,mpc8349-pci") -+ mpc83xx_add_bridge(np); -+#endif -+ mpc837xmds_usb_cfg(); -+} -+ -+static struct of_device_id mpc837x_ids[] = { -+ { .type = "soc", }, -+ { .compatible = "soc", }, -+ {}, -+}; -+ -+static int __init mpc837x_declare_of_platform_devices(void) -+{ -+ /* Publish of_device */ -+ of_platform_bus_probe(NULL, mpc837x_ids, NULL); -+ -+ return 0; -+} -+machine_device_initcall(mpc837x_mds, mpc837x_declare_of_platform_devices); -+ -+static void __init mpc837x_mds_init_IRQ(void) -+{ -+ struct device_node *np; -+ -+ np = of_find_compatible_node(NULL, NULL, "fsl,ipic"); -+ if (!np) -+ return; -+ -+ ipic_init(np, 0); -+ -+ /* Initialize the default interrupt mapping priorities, -+ * in case the boot rom changed something on us. -+ */ -+ ipic_set_default_priority(); -+} -+ -+/* -+ * Called very early, MMU is off, device-tree isn't unflattened -+ */ -+static int __init mpc837x_mds_probe(void) -+{ -+ unsigned long root = of_get_flat_dt_root(); -+ -+ return of_flat_dt_is_compatible(root, "fsl,mpc837xmds"); -+} -+ -+define_machine(mpc837x_mds) { -+ .name = "MPC837x MDS", -+ .probe = mpc837x_mds_probe, -+ .setup_arch = mpc837x_mds_setup_arch, -+ .init_IRQ = mpc837x_mds_init_IRQ, -+ .get_irq = ipic_get_irq, -+ .restart = mpc83xx_restart, -+ .time_init = mpc83xx_time_init, -+ .calibrate_decr = generic_calibrate_decr, -+ .progress = udbg_progress, -+}; ---- a/arch/powerpc/platforms/83xx/mpc83xx.h -+++ b/arch/powerpc/platforms/83xx/mpc83xx.h -@@ -14,6 +14,7 @@ - #define MPC83XX_SCCR_USB_DRCM_11 0x00300000 - #define MPC83XX_SCCR_USB_DRCM_01 0x00100000 - #define MPC83XX_SCCR_USB_DRCM_10 0x00200000 -+#define MPC837X_SCCR_USB_DRCM_11 0x00c00000 - - /* system i/o configuration register low */ - #define MPC83XX_SICRL_OFFS 0x114 -@@ -22,6 +23,8 @@ - #define MPC834X_SICRL_USB1 0x20000000 - #define MPC831X_SICRL_USB_MASK 0x00000c00 - #define MPC831X_SICRL_USB_ULPI 0x00000800 -+#define MPC837X_SICRL_USB_MASK 0xf0000000 -+#define MPC837X_SICRL_USB_ULPI 0x50000000 - - /* system i/o configuration register high */ - #define MPC83XX_SICRH_OFFS 0x118 ---- a/arch/powerpc/platforms/83xx/pci.c -+++ b/arch/powerpc/platforms/83xx/pci.c -@@ -54,7 +54,7 @@ int __init mpc83xx_add_bridge(struct dev - " bus 0\n", dev->full_name); - } - -- pci_assign_all_buses = 1; -+ ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS; - hose = pcibios_alloc_controller(dev); - if (!hose) - return -ENOMEM; ---- a/arch/powerpc/platforms/83xx/usb.c -+++ b/arch/powerpc/platforms/83xx/usb.c -@@ -41,7 +41,7 @@ int mpc834x_usb_cfg(void) - sicrl = in_be32(immap + MPC83XX_SICRL_OFFS) & ~MPC834X_SICRL_USB_MASK; - sicrh = in_be32(immap + MPC83XX_SICRH_OFFS) & ~MPC834X_SICRH_USB_UTMI; - -- np = of_find_compatible_node(NULL, "usb", "fsl-usb2-dr"); -+ np = of_find_compatible_node(NULL, NULL, "fsl-usb2-dr"); - if (np) { - sccr |= MPC83XX_SCCR_USB_DRCM_11; /* 1:3 */ - -@@ -67,7 +67,7 @@ int mpc834x_usb_cfg(void) - port0_is_dr = 1; - of_node_put(np); - } -- np = of_find_compatible_node(NULL, "usb", "fsl-usb2-mph"); -+ np = of_find_compatible_node(NULL, NULL, "fsl-usb2-mph"); - if (np) { - sccr |= MPC83XX_SCCR_USB_MPHCM_11; /* 1:3 */ - -@@ -111,7 +111,7 @@ int mpc831x_usb_cfg(void) - const void *dr_mode; - #endif - -- np = of_find_compatible_node(NULL, "usb", "fsl-usb2-dr"); -+ np = of_find_compatible_node(NULL, NULL, "fsl-usb2-dr"); - if (!np) - return -ENODEV; - prop = of_get_property(np, "phy_type", NULL); -@@ -179,3 +179,43 @@ int mpc831x_usb_cfg(void) - return ret; - } - #endif /* CONFIG_PPC_MPC831x */ -+ -+#ifdef CONFIG_PPC_MPC837x -+int mpc837x_usb_cfg(void) -+{ -+ void __iomem *immap; -+ struct device_node *np = NULL; -+ const void *prop; -+ int ret = 0; -+ -+ np = of_find_compatible_node(NULL, NULL, "fsl-usb2-dr"); -+ if (!np) -+ return -ENODEV; -+ prop = of_get_property(np, "phy_type", NULL); -+ -+ if (!prop || (strcmp(prop, "ulpi") && strcmp(prop, "serial"))) { -+ printk(KERN_WARNING "837x USB PHY type not supported\n"); -+ of_node_put(np); -+ return -EINVAL; -+ } -+ -+ /* Map IMMR space for pin and clock settings */ -+ immap = ioremap(get_immrbase(), 0x1000); -+ if (!immap) { -+ of_node_put(np); -+ return -ENOMEM; -+ } -+ -+ /* Configure clock */ -+ clrsetbits_be32(immap + MPC83XX_SCCR_OFFS, MPC837X_SCCR_USB_DRCM_11, -+ MPC837X_SCCR_USB_DRCM_11); -+ -+ /* Configure pin mux for ULPI/serial */ -+ clrsetbits_be32(immap + MPC83XX_SICRL_OFFS, MPC837X_SICRL_USB_MASK, -+ MPC837X_SICRL_USB_ULPI); -+ -+ iounmap(immap); -+ of_node_put(np); -+ return ret; -+} -+#endif /* CONFIG_PPC_MPC837x */ ---- a/arch/powerpc/platforms/85xx/mpc85xx_ads.c -+++ b/arch/powerpc/platforms/85xx/mpc85xx_ads.c -@@ -52,9 +52,9 @@ static void cpm2_cascade(unsigned int ir - { - int cascade_irq; - -- while ((cascade_irq = cpm2_get_irq()) >= 0) { -+ while ((cascade_irq = cpm2_get_irq()) >= 0) - generic_handle_irq(cascade_irq); -- } -+ - desc->chip->eoi(irq); - } - -@@ -70,13 +70,12 @@ static void __init mpc85xx_ads_pic_init( - #endif - - np = of_find_node_by_type(np, "open-pic"); -- -- if (np == NULL) { -+ if (!np) { - printk(KERN_ERR "Could not find open-pic node\n"); - return; - } - -- if(of_address_to_resource(np, 0, &r)) { -+ if (of_address_to_resource(np, 0, &r)) { - printk(KERN_ERR "Could not map mpic register space\n"); - of_node_put(np); - return; -@@ -100,6 +99,7 @@ static void __init mpc85xx_ads_pic_init( - irq = irq_of_parse_and_map(np, 0); - - cpm2_pic_init(np); -+ of_node_put(np); - set_irq_chained_handler(irq, cpm2_cascade); - #endif - } -@@ -112,7 +112,7 @@ struct cpm_pin { - int port, pin, flags; - }; - --static struct cpm_pin mpc8560_ads_pins[] = { -+static const struct cpm_pin mpc8560_ads_pins[] = { - /* SCC1 */ - {3, 29, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, - {3, 30, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY}, -@@ -233,13 +233,11 @@ static struct of_device_id __initdata of - - static int __init declare_of_platform_devices(void) - { -- if (!machine_is(mpc85xx_ads)) -- return 0; -- - of_platform_bus_probe(NULL, of_bus_ids, NULL); -+ - return 0; - } --device_initcall(declare_of_platform_devices); -+machine_device_initcall(mpc85xx_ads, declare_of_platform_devices); - - /* - * Called very early, device-tree isn't unflattened ---- a/arch/powerpc/platforms/85xx/mpc85xx_cds.c -+++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.c -@@ -222,9 +222,6 @@ static int mpc85xx_cds_8259_attach(void) - struct device_node *cascade_node = NULL; - int cascade_irq; - -- if (!machine_is(mpc85xx_cds)) -- return 0; -- - /* Initialize the i8259 controller */ - for_each_node_by_type(np, "interrupt-controller") - if (of_device_is_compatible(np, "chrp,iic")) { -@@ -262,8 +259,7 @@ static int mpc85xx_cds_8259_attach(void) - - return 0; - } -- --device_initcall(mpc85xx_cds_8259_attach); -+machine_device_initcall(mpc85xx_cds, mpc85xx_cds_8259_attach); - - #endif /* CONFIG_PPC_I8259 */ - ---- a/arch/powerpc/platforms/85xx/mpc85xx_ds.c -+++ b/arch/powerpc/platforms/85xx/mpc85xx_ds.c -@@ -123,7 +123,7 @@ static int mpc85xx_exclude_device(struct - struct device_node* node; - struct resource rsrc; - -- node = (struct device_node *)hose->arch_data; -+ node = hose->dn; - of_address_to_resource(node, 0, &rsrc); - - if ((rsrc.start & 0xfffff) == primary_phb_addr) { ---- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c -+++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c -@@ -30,9 +30,9 @@ - #include - #include - #include -+#include -+#include - --#include --#include - #include - #include - #include -@@ -144,15 +144,12 @@ static struct of_device_id mpc85xx_ids[] - - static int __init mpc85xx_publish_devices(void) - { -- if (!machine_is(mpc85xx_mds)) -- return 0; -- - /* Publish the QE devices */ -- of_platform_bus_probe(NULL,mpc85xx_ids,NULL); -+ of_platform_bus_probe(NULL, mpc85xx_ids, NULL); - - return 0; - } --device_initcall(mpc85xx_publish_devices); -+machine_device_initcall(mpc85xx_mds, mpc85xx_publish_devices); - - static void __init mpc85xx_mds_pic_init(void) - { ---- a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c -+++ b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c -@@ -34,9 +34,24 @@ - - #include - -+#include - #include - #include - -+static struct of_device_id __initdata mpc8610_ids[] = { -+ { .compatible = "fsl,mpc8610-immr", }, -+ {} -+}; -+ -+static int __init mpc8610_declare_of_platform_devices(void) -+{ -+ /* Without this call, the SSI device driver won't get probed. */ -+ of_platform_bus_probe(NULL, mpc8610_ids, NULL); -+ -+ return 0; -+} -+machine_device_initcall(mpc86xx_hpcd, mpc8610_declare_of_platform_devices); -+ - void __init - mpc86xx_hpcd_init_irq(void) - { -@@ -124,7 +139,7 @@ static void __devinit quirk_uli5229(stru - static void __devinit final_uli5288(struct pci_dev *dev) - { - struct pci_controller *hose = pci_bus_to_host(dev->bus); -- struct device_node *hosenode = hose ? hose->arch_data : NULL; -+ struct device_node *hosenode = hose ? hose->dn : NULL; - struct of_irq oirq; - int virq, pin = 2; - u32 laddr[3]; ---- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c -+++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c -@@ -18,6 +18,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -116,7 +117,7 @@ static int mpc86xx_exclude_device(struct - struct device_node* node; - struct resource rsrc; - -- node = (struct device_node *)hose->arch_data; -+ node = hose->dn; - of_address_to_resource(node, 0, &rsrc); - - if ((rsrc.start & 0xfffff) == 0x8000) { -@@ -212,6 +213,19 @@ mpc86xx_time_init(void) - return 0; - } - -+static __initdata struct of_device_id of_bus_ids[] = { -+ { .compatible = "simple-bus", }, -+ {}, -+}; -+ -+static int __init declare_of_platform_devices(void) -+{ -+ of_platform_bus_probe(NULL, of_bus_ids, NULL); -+ -+ return 0; -+} -+machine_device_initcall(mpc86xx_hpcn, declare_of_platform_devices); -+ - define_machine(mpc86xx_hpcn) { - .name = "MPC86xx HPCN", - .probe = mpc86xx_hpcn_probe, ---- a/arch/powerpc/platforms/8xx/Kconfig -+++ b/arch/powerpc/platforms/8xx/Kconfig -@@ -18,6 +18,7 @@ config MPC8XXFADS - config MPC86XADS - bool "MPC86XADS" - select CPM1 -+ select PPC_CPM_NEW_BINDING - help - MPC86x Application Development System by Freescale Semiconductor. - The MPC86xADS is meant to serve as a platform for s/w and h/w -@@ -43,6 +44,15 @@ config PPC_EP88XC - This board is also resold by Freescale as the QUICCStart - MPC885 Evaluation System and/or the CWH-PPC-885XN-VE. - -+config PPC_ADDER875 -+ bool "Analogue & Micro Adder 875" -+ select CPM1 -+ select PPC_CPM_NEW_BINDING -+ select REDBOOT -+ help -+ This enables support for the Analogue & Micro Adder 875 -+ board. -+ - endchoice - - menu "Freescale Ethernet driver platform-specific options" ---- a/arch/powerpc/platforms/8xx/Makefile -+++ b/arch/powerpc/platforms/8xx/Makefile -@@ -5,3 +5,4 @@ obj-$(CONFIG_PPC_8xx) += m8xx_setup.o - obj-$(CONFIG_MPC885ADS) += mpc885ads_setup.o - obj-$(CONFIG_MPC86XADS) += mpc86xads_setup.o - obj-$(CONFIG_PPC_EP88XC) += ep88xc.o -+obj-$(CONFIG_PPC_ADDER875) += adder875.o ---- /dev/null -+++ b/arch/powerpc/platforms/8xx/adder875.c -@@ -0,0 +1,118 @@ -+/* Analogue & Micro Adder MPC875 board support -+ * -+ * Author: Scott Wood -+ * -+ * Copyright (c) 2007 Freescale Semiconductor, Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, version 2, as -+ * published by the Free Software Foundation. -+ */ -+ -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+struct cpm_pin { -+ int port, pin, flags; -+}; -+ -+static __initdata struct cpm_pin adder875_pins[] = { -+ /* SMC1 */ -+ {CPM_PORTB, 24, CPM_PIN_INPUT}, /* RX */ -+ {CPM_PORTB, 25, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, /* TX */ -+ -+ /* MII1 */ -+ {CPM_PORTA, 0, CPM_PIN_INPUT}, -+ {CPM_PORTA, 1, CPM_PIN_INPUT}, -+ {CPM_PORTA, 2, CPM_PIN_INPUT}, -+ {CPM_PORTA, 3, CPM_PIN_INPUT}, -+ {CPM_PORTA, 4, CPM_PIN_OUTPUT}, -+ {CPM_PORTA, 10, CPM_PIN_OUTPUT}, -+ {CPM_PORTA, 11, CPM_PIN_OUTPUT}, -+ {CPM_PORTB, 19, CPM_PIN_INPUT}, -+ {CPM_PORTB, 31, CPM_PIN_INPUT}, -+ {CPM_PORTC, 12, CPM_PIN_INPUT}, -+ {CPM_PORTC, 13, CPM_PIN_INPUT}, -+ {CPM_PORTE, 30, CPM_PIN_OUTPUT}, -+ {CPM_PORTE, 31, CPM_PIN_OUTPUT}, -+ -+ /* MII2 */ -+ {CPM_PORTE, 14, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY}, -+ {CPM_PORTE, 15, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY}, -+ {CPM_PORTE, 16, CPM_PIN_OUTPUT}, -+ {CPM_PORTE, 17, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY}, -+ {CPM_PORTE, 18, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY}, -+ {CPM_PORTE, 19, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY}, -+ {CPM_PORTE, 20, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY}, -+ {CPM_PORTE, 21, CPM_PIN_OUTPUT}, -+ {CPM_PORTE, 22, CPM_PIN_OUTPUT}, -+ {CPM_PORTE, 23, CPM_PIN_OUTPUT}, -+ {CPM_PORTE, 24, CPM_PIN_OUTPUT}, -+ {CPM_PORTE, 25, CPM_PIN_OUTPUT}, -+ {CPM_PORTE, 26, CPM_PIN_OUTPUT}, -+ {CPM_PORTE, 27, CPM_PIN_OUTPUT}, -+ {CPM_PORTE, 28, CPM_PIN_OUTPUT}, -+ {CPM_PORTE, 29, CPM_PIN_OUTPUT}, -+}; -+ -+static void __init init_ioports(void) -+{ -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(adder875_pins); i++) { -+ const struct cpm_pin *pin = &adder875_pins[i]; -+ cpm1_set_pin(pin->port, pin->pin, pin->flags); -+ } -+ -+ cpm1_clk_setup(CPM_CLK_SMC1, CPM_BRG1, CPM_CLK_RTX); -+ -+ /* Set FEC1 and FEC2 to MII mode */ -+ clrbits32(&mpc8xx_immr->im_cpm.cp_cptr, 0x00000180); -+} -+ -+static void __init adder875_setup(void) -+{ -+ cpm_reset(); -+ init_ioports(); -+} -+ -+static int __init adder875_probe(void) -+{ -+ unsigned long root = of_get_flat_dt_root(); -+ return of_flat_dt_is_compatible(root, "analogue-and-micro,adder875"); -+} -+ -+static __initdata struct of_device_id of_bus_ids[] = { -+ { .compatible = "simple-bus", }, -+ {}, -+}; -+ -+static int __init declare_of_platform_devices(void) -+{ -+ of_platform_bus_probe(NULL, of_bus_ids, NULL); -+ return 0; -+} -+machine_device_initcall(adder875, declare_of_platform_devices); -+ -+define_machine(adder875) { -+ .name = "Adder MPC875", -+ .probe = adder875_probe, -+ .setup_arch = adder875_setup, -+ .init_IRQ = m8xx_pic_init, -+ .get_irq = mpc8xx_get_irq, -+ .restart = mpc8xx_restart, -+ .calibrate_decr = generic_calibrate_decr, -+ .set_rtc_time = mpc8xx_set_rtc_time, -+ .get_rtc_time = mpc8xx_get_rtc_time, -+ .progress = udbg_progress, -+}; ---- a/arch/powerpc/platforms/8xx/ep88xc.c -+++ b/arch/powerpc/platforms/8xx/ep88xc.c -@@ -155,12 +155,11 @@ static struct of_device_id __initdata of - static int __init declare_of_platform_devices(void) - { - /* Publish the QE devices */ -- if (machine_is(ep88xc)) -- of_platform_bus_probe(NULL, of_bus_ids, NULL); -+ of_platform_bus_probe(NULL, of_bus_ids, NULL); - - return 0; - } --device_initcall(declare_of_platform_devices); -+machine_device_initcall(ep88xc, declare_of_platform_devices); - - define_machine(ep88xc) { - .name = "Embedded Planet EP88xC", ---- a/arch/powerpc/platforms/8xx/m8xx_setup.c -+++ b/arch/powerpc/platforms/8xx/m8xx_setup.c -@@ -120,7 +120,7 @@ void __init mpc8xx_calibrate_decr(void) - ppc_tb_freq /= 16; - ppc_proc_freq = 50000000; - if (!get_freq("clock-frequency", &ppc_proc_freq)) -- printk(KERN_ERR "WARNING: Estimating processor frequency" -+ printk(KERN_ERR "WARNING: Estimating processor frequency " - "(not found)\n"); - - printk("Decrementer Frequency = 0x%lx\n", ppc_tb_freq); ---- a/arch/powerpc/platforms/8xx/mpc86xads.h -+++ b/arch/powerpc/platforms/8xx/mpc86xads.h -@@ -15,27 +15,6 @@ - #ifndef __ASM_MPC86XADS_H__ - #define __ASM_MPC86XADS_H__ - --#include -- --/* U-Boot maps BCSR to 0xff080000 */ --#define BCSR_ADDR ((uint)0xff080000) --#define BCSR_SIZE ((uint)32) --#define BCSR0 ((uint)(BCSR_ADDR + 0x00)) --#define BCSR1 ((uint)(BCSR_ADDR + 0x04)) --#define BCSR2 ((uint)(BCSR_ADDR + 0x08)) --#define BCSR3 ((uint)(BCSR_ADDR + 0x0c)) --#define BCSR4 ((uint)(BCSR_ADDR + 0x10)) -- --#define CFG_PHYDEV_ADDR ((uint)0xff0a0000) --#define BCSR5 ((uint)(CFG_PHYDEV_ADDR + 0x300)) -- --#define MPC8xx_CPM_OFFSET (0x9c0) --#define CPM_MAP_ADDR (get_immrbase() + MPC8xx_CPM_OFFSET) --#define CPM_IRQ_OFFSET 16 // for compability with cpm_uart driver -- --#define PCMCIA_MEM_ADDR ((uint)0xff020000) --#define PCMCIA_MEM_SIZE ((uint)(64 * 1024)) -- - /* Bits of interest in the BCSRs. - */ - #define BCSR1_ETHEN ((uint)0x20000000) -@@ -64,28 +43,5 @@ - #define BCSR5_MII1_EN 0x02 - #define BCSR5_MII1_RST 0x01 - --/* Interrupt level assignments */ --#define PHY_INTERRUPT SIU_IRQ7 /* PHY link change interrupt */ --#define SIU_INT_FEC1 SIU_LEVEL1 /* FEC1 interrupt */ --#define FEC_INTERRUPT SIU_INT_FEC1 /* FEC interrupt */ -- --/* We don't use the 8259 */ --#define NR_8259_INTS 0 -- --/* CPM Ethernet through SCC1 */ --#define PA_ENET_RXD ((ushort)0x0001) --#define PA_ENET_TXD ((ushort)0x0002) --#define PA_ENET_TCLK ((ushort)0x0100) --#define PA_ENET_RCLK ((ushort)0x0200) --#define PB_ENET_TENA ((uint)0x00001000) --#define PC_ENET_CLSN ((ushort)0x0010) --#define PC_ENET_RENA ((ushort)0x0020) -- --/* Control bits in the SICR to route TCLK (CLK1) and RCLK (CLK2) to -- * SCC1. Also, make sure GR1 (bit 24) and SC1 (bit 25) are zero. -- */ --#define SICR_ENET_MASK ((uint)0x000000ff) --#define SICR_ENET_CLKRT ((uint)0x0000002c) -- - #endif /* __ASM_MPC86XADS_H__ */ - #endif /* __KERNEL__ */ ---- a/arch/powerpc/platforms/8xx/mpc86xads_setup.c -+++ b/arch/powerpc/platforms/8xx/mpc86xads_setup.c -@@ -6,264 +6,133 @@ - * - * Copyright 2005 MontaVista Software Inc. - * -+ * Heavily modified by Scott Wood -+ * Copyright 2007 Freescale Semiconductor, Inc. -+ * - * This file is licensed under the terms of the GNU General Public License - * version 2. This program is licensed "as is" without any warranty of any - * kind, whether express or implied. - */ - - #include --#include --#include --#include --#include --#include --#include --#include -- --#include --#include --#include -+#include - --#include - #include - #include --#include --#include - #include - #include - #include - #include - #include - #include --#include -+#include - - #include - --static void init_smc1_uart_ioports(struct fs_uart_platform_info* fpi); --static void init_smc2_uart_ioports(struct fs_uart_platform_info* fpi); --static void init_scc1_ioports(struct fs_platform_info* ptr); -- --void __init mpc86xads_board_setup(void) --{ -- cpm8xx_t *cp; -- unsigned int *bcsr_io; -- u8 tmpval8; -- -- bcsr_io = ioremap(BCSR1, sizeof(unsigned long)); -- cp = (cpm8xx_t *)immr_map(im_cpm); -+#include "mpc86xads.h" - -- if (bcsr_io == NULL) { -- printk(KERN_CRIT "Could not remap BCSR\n"); -- return; -- } --#ifdef CONFIG_SERIAL_CPM_SMC1 -- clrbits32(bcsr_io, BCSR1_RS232EN_1); -- clrbits32(&cp->cp_simode, 0xe0000000 >> 17); /* brg1 */ -- tmpval8 = in_8(&(cp->cp_smc[0].smc_smcm)) | (SMCM_RX | SMCM_TX); -- out_8(&(cp->cp_smc[0].smc_smcm), tmpval8); -- clrbits16(&cp->cp_smc[0].smc_smcmr, SMCMR_REN | SMCMR_TEN); --#else -- setbits32(bcsr_io,BCSR1_RS232EN_1); -- out_be16(&cp->cp_smc[0].smc_smcmr, 0); -- out_8(&cp->cp_smc[0].smc_smce, 0); --#endif -- --#ifdef CONFIG_SERIAL_CPM_SMC2 -- clrbits32(bcsr_io,BCSR1_RS232EN_2); -- clrbits32(&cp->cp_simode, 0xe0000000 >> 1); -- setbits32(&cp->cp_simode, 0x20000000 >> 1); /* brg2 */ -- tmpval8 = in_8(&(cp->cp_smc[1].smc_smcm)) | (SMCM_RX | SMCM_TX); -- out_8(&(cp->cp_smc[1].smc_smcm), tmpval8); -- clrbits16(&cp->cp_smc[1].smc_smcmr, SMCMR_REN | SMCMR_TEN); -- -- init_smc2_uart_ioports(0); --#else -- setbits32(bcsr_io,BCSR1_RS232EN_2); -- out_be16(&cp->cp_smc[1].smc_smcmr, 0); -- out_8(&cp->cp_smc[1].smc_smce, 0); --#endif -- immr_unmap(cp); -- iounmap(bcsr_io); --} -+struct cpm_pin { -+ int port, pin, flags; -+}; - -+static struct cpm_pin mpc866ads_pins[] = { -+ /* SMC1 */ -+ {CPM_PORTB, 24, CPM_PIN_INPUT}, /* RX */ -+ {CPM_PORTB, 25, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, /* TX */ -+ -+ /* SMC2 */ -+ {CPM_PORTB, 21, CPM_PIN_INPUT}, /* RX */ -+ {CPM_PORTB, 20, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, /* TX */ -+ -+ /* SCC1 */ -+ {CPM_PORTA, 6, CPM_PIN_INPUT}, /* CLK1 */ -+ {CPM_PORTA, 7, CPM_PIN_INPUT}, /* CLK2 */ -+ {CPM_PORTA, 14, CPM_PIN_INPUT}, /* TX */ -+ {CPM_PORTA, 15, CPM_PIN_INPUT}, /* RX */ -+ {CPM_PORTB, 19, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, /* TENA */ -+ {CPM_PORTC, 10, CPM_PIN_INPUT | CPM_PIN_SECONDARY | CPM_PIN_GPIO}, /* RENA */ -+ {CPM_PORTC, 11, CPM_PIN_INPUT | CPM_PIN_SECONDARY | CPM_PIN_GPIO}, /* CLSN */ -+ -+ /* MII */ -+ {CPM_PORTD, 3, CPM_PIN_OUTPUT}, -+ {CPM_PORTD, 4, CPM_PIN_OUTPUT}, -+ {CPM_PORTD, 5, CPM_PIN_OUTPUT}, -+ {CPM_PORTD, 6, CPM_PIN_OUTPUT}, -+ {CPM_PORTD, 7, CPM_PIN_OUTPUT}, -+ {CPM_PORTD, 8, CPM_PIN_OUTPUT}, -+ {CPM_PORTD, 9, CPM_PIN_OUTPUT}, -+ {CPM_PORTD, 10, CPM_PIN_OUTPUT}, -+ {CPM_PORTD, 11, CPM_PIN_OUTPUT}, -+ {CPM_PORTD, 12, CPM_PIN_OUTPUT}, -+ {CPM_PORTD, 13, CPM_PIN_OUTPUT}, -+ {CPM_PORTD, 14, CPM_PIN_OUTPUT}, -+ {CPM_PORTD, 15, CPM_PIN_OUTPUT}, -+}; - --static void init_fec1_ioports(struct fs_platform_info* ptr) -+static void __init init_ioports(void) - { -- iop8xx_t *io_port = (iop8xx_t *)immr_map(im_ioport); -+ int i; - -- /* configure FEC1 pins */ -+ for (i = 0; i < ARRAY_SIZE(mpc866ads_pins); i++) { -+ struct cpm_pin *pin = &mpc866ads_pins[i]; -+ cpm1_set_pin(pin->port, pin->pin, pin->flags); -+ } - -- setbits16(&io_port->iop_pdpar, 0x1fff); -- setbits16(&io_port->iop_pddir, 0x1fff); -+ cpm1_clk_setup(CPM_CLK_SMC1, CPM_BRG1, CPM_CLK_RTX); -+ cpm1_clk_setup(CPM_CLK_SMC2, CPM_BRG2, CPM_CLK_RTX); -+ cpm1_clk_setup(CPM_CLK_SCC1, CPM_CLK1, CPM_CLK_TX); -+ cpm1_clk_setup(CPM_CLK_SCC1, CPM_CLK2, CPM_CLK_RX); - -- immr_unmap(io_port); -+ /* Set FEC1 and FEC2 to MII mode */ -+ clrbits32(&mpc8xx_immr->im_cpm.cp_cptr, 0x00000180); - } - --void init_fec_ioports(struct fs_platform_info *fpi) -+static void __init mpc86xads_setup_arch(void) - { -- int fec_no = fs_get_fec_index(fpi->fs_no); -+ struct device_node *np; -+ u32 __iomem *bcsr_io; -+ -+ cpm_reset(); -+ init_ioports(); - -- switch (fec_no) { -- case 0: -- init_fec1_ioports(fpi); -- break; -- default: -- printk(KERN_ERR "init_fec_ioports: invalid FEC number\n"); -+ np = of_find_compatible_node(NULL, NULL, "fsl,mpc866ads-bcsr"); -+ if (!np) { -+ printk(KERN_CRIT "Could not find fsl,mpc866ads-bcsr node\n"); - return; - } --} - --static void init_scc1_ioports(struct fs_platform_info* fpi) --{ -- unsigned *bcsr_io; -- iop8xx_t *io_port; -- cpm8xx_t *cp; -- -- bcsr_io = ioremap(BCSR_ADDR, BCSR_SIZE); -- io_port = (iop8xx_t *)immr_map(im_ioport); -- cp = (cpm8xx_t *)immr_map(im_cpm); -+ bcsr_io = of_iomap(np, 0); -+ of_node_put(np); - - if (bcsr_io == NULL) { - printk(KERN_CRIT "Could not remap BCSR\n"); - return; - } - -- /* Configure port A pins for Txd and Rxd. -- */ -- setbits16(&io_port->iop_papar, PA_ENET_RXD | PA_ENET_TXD); -- clrbits16(&io_port->iop_padir, PA_ENET_RXD | PA_ENET_TXD); -- clrbits16(&io_port->iop_paodr, PA_ENET_TXD); -- -- /* Configure port C pins to enable CLSN and RENA. -- */ -- clrbits16(&io_port->iop_pcpar, PC_ENET_CLSN | PC_ENET_RENA); -- clrbits16(&io_port->iop_pcdir, PC_ENET_CLSN | PC_ENET_RENA); -- setbits16(&io_port->iop_pcso, PC_ENET_CLSN | PC_ENET_RENA); -- -- /* Configure port A for TCLK and RCLK. -- */ -- setbits16(&io_port->iop_papar, PA_ENET_TCLK | PA_ENET_RCLK); -- clrbits16(&io_port->iop_padir, PA_ENET_TCLK | PA_ENET_RCLK); -- clrbits32(&cp->cp_pbpar, PB_ENET_TENA); -- clrbits32(&cp->cp_pbdir, PB_ENET_TENA); -- -- /* Configure Serial Interface clock routing. -- * First, clear all SCC bits to zero, then set the ones we want. -- */ -- clrbits32(&cp->cp_sicr, SICR_ENET_MASK); -- setbits32(&cp->cp_sicr, SICR_ENET_CLKRT); -- -- /* In the original SCC enet driver the following code is placed at -- the end of the initialization */ -- setbits32(&cp->cp_pbpar, PB_ENET_TENA); -- setbits32(&cp->cp_pbdir, PB_ENET_TENA); -- -- clrbits32(bcsr_io+1, BCSR1_ETHEN); -+ clrbits32(bcsr_io, BCSR1_RS232EN_1 | BCSR1_RS232EN_2 | BCSR1_ETHEN); - iounmap(bcsr_io); -- immr_unmap(cp); -- immr_unmap(io_port); --} -- --void init_scc_ioports(struct fs_platform_info *fpi) --{ -- int scc_no = fs_get_scc_index(fpi->fs_no); -- -- switch (scc_no) { -- case 0: -- init_scc1_ioports(fpi); -- break; -- default: -- printk(KERN_ERR "init_scc_ioports: invalid SCC number\n"); -- return; -- } - } - -- -- --static void init_smc1_uart_ioports(struct fs_uart_platform_info* ptr) -+static int __init mpc86xads_probe(void) - { -- unsigned *bcsr_io; -- cpm8xx_t *cp = (cpm8xx_t *)immr_map(im_cpm); -- -- setbits32(&cp->cp_pbpar, 0x000000c0); -- clrbits32(&cp->cp_pbdir, 0x000000c0); -- clrbits16(&cp->cp_pbodr, 0x00c0); -- immr_unmap(cp); -- -- bcsr_io = ioremap(BCSR1, sizeof(unsigned long)); -- -- if (bcsr_io == NULL) { -- printk(KERN_CRIT "Could not remap BCSR1\n"); -- return; -- } -- clrbits32(bcsr_io,BCSR1_RS232EN_1); -- iounmap(bcsr_io); -+ unsigned long root = of_get_flat_dt_root(); -+ return of_flat_dt_is_compatible(root, "fsl,mpc866ads"); - } - --static void init_smc2_uart_ioports(struct fs_uart_platform_info* fpi) --{ -- unsigned *bcsr_io; -- cpm8xx_t *cp = (cpm8xx_t *)immr_map(im_cpm); -- -- setbits32(&cp->cp_pbpar, 0x00000c00); -- clrbits32(&cp->cp_pbdir, 0x00000c00); -- clrbits16(&cp->cp_pbodr, 0x0c00); -- immr_unmap(cp); -- -- bcsr_io = ioremap(BCSR1, sizeof(unsigned long)); -- -- if (bcsr_io == NULL) { -- printk(KERN_CRIT "Could not remap BCSR1\n"); -- return; -- } -- clrbits32(bcsr_io,BCSR1_RS232EN_2); -- iounmap(bcsr_io); --} -+static struct of_device_id __initdata of_bus_ids[] = { -+ { .name = "soc", }, -+ { .name = "cpm", }, -+ { .name = "localbus", }, -+ {}, -+}; - --void init_smc_ioports(struct fs_uart_platform_info *data) -+static int __init declare_of_platform_devices(void) - { -- int smc_no = fs_uart_id_fsid2smc(data->fs_no); -- -- switch (smc_no) { -- case 0: -- init_smc1_uart_ioports(data); -- data->brg = data->clk_rx; -- break; -- case 1: -- init_smc2_uart_ioports(data); -- data->brg = data->clk_rx; -- break; -- default: -- printk(KERN_ERR "init_scc_ioports: invalid SCC number\n"); -- return; -- } --} -+ of_platform_bus_probe(NULL, of_bus_ids, NULL); - --int platform_device_skip(const char *model, int id) --{ - return 0; - } -- --static void __init mpc86xads_setup_arch(void) --{ -- cpm_reset(); -- -- mpc86xads_board_setup(); -- -- ROOT_DEV = Root_NFS; --} -- --static int __init mpc86xads_probe(void) --{ -- char *model = of_get_flat_dt_prop(of_get_flat_dt_root(), -- "model", NULL); -- if (model == NULL) -- return 0; -- if (strcmp(model, "MPC866ADS")) -- return 0; -- -- return 1; --} -+machine_device_initcall(mpc86x_ads, declare_of_platform_devices); - - define_machine(mpc86x_ads) { - .name = "MPC86x ADS", -@@ -275,4 +144,5 @@ define_machine(mpc86x_ads) { - .calibrate_decr = mpc8xx_calibrate_decr, - .set_rtc_time = mpc8xx_set_rtc_time, - .get_rtc_time = mpc8xx_get_rtc_time, -+ .progress = udbg_progress, - }; ---- a/arch/powerpc/platforms/8xx/mpc885ads_setup.c -+++ b/arch/powerpc/platforms/8xx/mpc885ads_setup.c -@@ -264,12 +264,11 @@ static struct of_device_id __initdata of - static int __init declare_of_platform_devices(void) - { - /* Publish the QE devices */ -- if (machine_is(mpc885_ads)) -- of_platform_bus_probe(NULL, of_bus_ids, NULL); -+ of_platform_bus_probe(NULL, of_bus_ids, NULL); - - return 0; - } --device_initcall(declare_of_platform_devices); -+machine_device_initcall(mpc885_ads, declare_of_platform_devices); - - define_machine(mpc885_ads) { - .name = "Freescale MPC885 ADS", ---- a/arch/powerpc/platforms/Kconfig -+++ b/arch/powerpc/platforms/Kconfig -@@ -22,6 +22,7 @@ config PPC_83xx - depends on 6xx - select FSL_SOC - select 83xx -+ select IPIC - select WANT_DEVICE_TREE - - config PPC_86xx -@@ -80,6 +81,10 @@ config XICS - bool - default y - -+config IPIC -+ bool -+ default n -+ - config MPIC - bool - default n -@@ -265,6 +270,7 @@ config TAU_AVERAGE - config QUICC_ENGINE - bool - select PPC_LIB_RHEAP -+ select CRC32 - help - The QUICC Engine (QE) is a new generation of communications - coprocessors on Freescale embedded CPUs (akin to CPM in older chips). -@@ -315,6 +321,12 @@ config FSL_ULI1575 - config CPM - bool - -+config OF_RTC -+ bool -+ help -+ Uses information from the OF or flattened device tree to instatiate -+ platform devices for direct mapped RTC chips like the DS1742 or DS1743. -+ - source "arch/powerpc/sysdev/bestcomm/Kconfig" - - endmenu ---- a/arch/powerpc/platforms/Kconfig.cputype -+++ b/arch/powerpc/platforms/Kconfig.cputype -@@ -43,6 +43,7 @@ config 40x - bool "AMCC 40x" - select PPC_DCR_NATIVE - select WANT_DEVICE_TREE -+ select PPC_UDBG_16550 - - config 44x - bool "AMCC 44x" ---- a/arch/powerpc/platforms/cell/Makefile -+++ b/arch/powerpc/platforms/cell/Makefile -@@ -20,7 +20,7 @@ spu-manage-$(CONFIG_PPC_CELL_NATIVE) += - - obj-$(CONFIG_SPU_BASE) += spu_callbacks.o spu_base.o \ - spu_notify.o \ -- spu_syscalls.o \ -+ spu_syscalls.o spu_fault.o \ - $(spu-priv1-y) \ - $(spu-manage-y) \ - spufs/ ---- a/arch/powerpc/platforms/cell/cbe_cpufreq.c -+++ b/arch/powerpc/platforms/cell/cbe_cpufreq.c -@@ -21,8 +21,9 @@ - */ - - #include -+#include -+ - #include --#include - #include - #include - #include "cbe_cpufreq.h" ---- a/arch/powerpc/platforms/cell/cbe_cpufreq_pmi.c -+++ b/arch/powerpc/platforms/cell/cbe_cpufreq_pmi.c -@@ -23,7 +23,8 @@ - #include - #include - #include --#include -+#include -+ - #include - #include - #include ---- a/arch/powerpc/platforms/cell/cbe_regs.c -+++ b/arch/powerpc/platforms/cell/cbe_regs.c -@@ -9,13 +9,13 @@ - #include - #include - #include -+#include -+#include - - #include - #include - #include - #include --#include --#include - #include - - /* -@@ -256,6 +256,7 @@ void __init cbe_regs_init(void) - printk(KERN_ERR "cbe_regs: More BE chips than supported" - "!\n"); - cbe_regs_map_count--; -+ of_node_put(cpu); - return; - } - map->cpu_node = cpu; ---- a/arch/powerpc/platforms/cell/io-workarounds.c -+++ b/arch/powerpc/platforms/cell/io-workarounds.c -@@ -238,7 +238,7 @@ static void __init spider_pci_setup_chip - static void __init spider_pci_add_one(struct pci_controller *phb) - { - struct spider_pci_bus *bus = &spider_pci_busses[spider_pci_count]; -- struct device_node *np = phb->arch_data; -+ struct device_node *np = phb->dn; - struct resource rsrc; - void __iomem *regs; - -@@ -309,15 +309,12 @@ static int __init spider_pci_workaround_ - { - struct pci_controller *phb; - -- if (!machine_is(cell)) -- return 0; -- - /* Find spider bridges. We assume they have been all probed - * in setup_arch(). If that was to change, we would need to - * update this code to cope with dynamically added busses - */ - list_for_each_entry(phb, &hose_list, list_node) { -- struct device_node *np = phb->arch_data; -+ struct device_node *np = phb->dn; - const char *model = of_get_property(np, "model", NULL); - - /* If no model property or name isn't exactly "pci", skip */ -@@ -343,4 +340,4 @@ static int __init spider_pci_workaround_ - - return 0; - } --arch_initcall(spider_pci_workaround_init); -+machine_arch_initcall(cell, spider_pci_workaround_init); ---- a/arch/powerpc/platforms/cell/iommu.c -+++ b/arch/powerpc/platforms/cell/iommu.c -@@ -26,14 +26,15 @@ - #include - #include - #include -+#include - - #include - #include - #include - #include - #include --#include - #include -+#include - #include - - #include "interrupt.h" -@@ -309,8 +310,8 @@ static void cell_iommu_setup_hardware(st - { - struct page *page; - int ret, i; -- unsigned long reg, segments, pages_per_segment, ptab_size, n_pte_pages; -- unsigned long xlate_base; -+ unsigned long reg, segments, pages_per_segment, ptab_size, stab_size, -+ n_pte_pages, xlate_base; - unsigned int virq; - - if (cell_iommu_find_ioc(iommu->nid, &xlate_base)) -@@ -327,7 +328,8 @@ static void cell_iommu_setup_hardware(st - __FUNCTION__, iommu->nid, segments, pages_per_segment); - - /* set up the segment table */ -- page = alloc_pages_node(iommu->nid, GFP_KERNEL, 0); -+ stab_size = segments * sizeof(unsigned long); -+ page = alloc_pages_node(iommu->nid, GFP_KERNEL, get_order(stab_size)); - BUG_ON(!page); - iommu->stab = page_address(page); - clear_page(iommu->stab); -@@ -489,15 +491,18 @@ static struct cbe_iommu *cell_iommu_for_ - return NULL; - } - -+static unsigned long cell_dma_direct_offset; -+ - static void cell_dma_dev_setup(struct device *dev) - { - struct iommu_window *window; - struct cbe_iommu *iommu; - struct dev_archdata *archdata = &dev->archdata; - -- /* If we run without iommu, no need to do anything */ -- if (get_pci_dma_ops() == &dma_direct_ops) -+ if (get_pci_dma_ops() == &dma_direct_ops) { -+ archdata->dma_data = (void *)cell_dma_direct_offset; - return; -+ } - - /* Current implementation uses the first window available in that - * node's iommu. We -might- do something smarter later though it may -@@ -653,7 +658,7 @@ static int __init cell_iommu_init_disabl - - /* If we have no Axon, we set up the spider DMA magic offset */ - if (of_find_node_by_name(NULL, "axon") == NULL) -- dma_direct_offset = SPIDER_DMA_OFFSET; -+ cell_dma_direct_offset = SPIDER_DMA_OFFSET; - - /* Now we need to check to see where the memory is mapped - * in PCI space. We assume that all busses use the same dma -@@ -687,10 +692,13 @@ static int __init cell_iommu_init_disabl - return -ENODEV; - } - -- dma_direct_offset += base; -+ cell_dma_direct_offset += base; -+ -+ if (cell_dma_direct_offset != 0) -+ ppc_md.pci_dma_dev_setup = cell_pci_dma_dev_setup; - - printk("iommu: disabled, direct DMA offset is 0x%lx\n", -- dma_direct_offset); -+ cell_dma_direct_offset); - - return 0; - } -@@ -699,9 +707,6 @@ static int __init cell_iommu_init(void) - { - struct device_node *np; - -- if (!machine_is(cell)) -- return -ENODEV; -- - /* If IOMMU is disabled or we have little enough RAM to not need - * to enable it, we setup a direct mapping. - * -@@ -744,5 +749,6 @@ static int __init cell_iommu_init(void) - - return 0; - } --arch_initcall(cell_iommu_init); -+machine_arch_initcall(cell, cell_iommu_init); -+machine_arch_initcall(celleb_native, cell_iommu_init); - ---- a/arch/powerpc/platforms/cell/pmu.c -+++ b/arch/powerpc/platforms/cell/pmu.c -@@ -213,7 +213,7 @@ u32 cbe_read_pm(u32 cpu, enum pm_reg_nam - break; - - case pm_interval: -- READ_SHADOW_REG(val, pm_interval); -+ READ_MMIO_UPPER32(val, pm_interval); - break; - - case pm_start_stop: -@@ -381,9 +381,6 @@ static int __init cbe_init_pm_irq(void) - unsigned int irq; - int rc, node; - -- if (!machine_is(cell)) -- return 0; -- - for_each_node(node) { - irq = irq_create_mapping(NULL, IIC_IRQ_IOEX_PMI | - (node << IIC_IRQ_NODE_SHIFT)); -@@ -404,7 +401,7 @@ static int __init cbe_init_pm_irq(void) - - return 0; - } --arch_initcall(cbe_init_pm_irq); -+machine_arch_initcall(cell, cbe_init_pm_irq); - - void cbe_sync_irq(int node) - { ---- a/arch/powerpc/platforms/cell/setup.c -+++ b/arch/powerpc/platforms/cell/setup.c -@@ -30,6 +30,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -51,7 +52,6 @@ - #include - #include - #include --#include - #include - - #include "interrupt.h" -@@ -85,9 +85,6 @@ static int __init cell_publish_devices(v - { - int node; - -- if (!machine_is(cell)) -- return 0; -- - /* Publish OF platform devices for southbridge IOs */ - of_platform_bus_probe(NULL, NULL, NULL); - -@@ -101,7 +98,7 @@ static int __init cell_publish_devices(v - } - return 0; - } --device_initcall(cell_publish_devices); -+machine_device_initcall(cell, cell_publish_devices); - - static void cell_mpic_cascade(unsigned int irq, struct irq_desc *desc) - { ---- a/arch/powerpc/platforms/cell/smp.c -+++ b/arch/powerpc/platforms/cell/smp.c -@@ -42,6 +42,7 @@ - #include - #include - #include -+#include - - #include "interrupt.h" - #include -@@ -182,7 +183,7 @@ static int smp_cell_cpu_bootable(unsigne - */ - if (system_state < SYSTEM_RUNNING && - cpu_has_feature(CPU_FTR_SMT) && -- !smt_enabled_at_boot && nr % 2 != 0) -+ !smt_enabled_at_boot && cpu_thread_in_core(nr) != 0) - return 0; - - return 1; ---- a/arch/powerpc/platforms/cell/spu_base.c -+++ b/arch/powerpc/platforms/cell/spu_base.c -@@ -34,6 +34,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -47,6 +48,13 @@ struct cbe_spu_info cbe_spu_info[MAX_NUM - EXPORT_SYMBOL_GPL(cbe_spu_info); - - /* -+ * The spufs fault-handling code needs to call force_sig_info to raise signals -+ * on DMA errors. Export it here to avoid general kernel-wide access to this -+ * function -+ */ -+EXPORT_SYMBOL_GPL(force_sig_info); -+ -+/* - * Protects cbe_spu_info and spu->number. - */ - static DEFINE_SPINLOCK(spu_lock); -@@ -66,6 +74,10 @@ static LIST_HEAD(spu_full_list); - static DEFINE_SPINLOCK(spu_full_list_lock); - static DEFINE_MUTEX(spu_full_list_mutex); - -+struct spu_slb { -+ u64 esid, vsid; -+}; -+ - void spu_invalidate_slbs(struct spu *spu) - { - struct spu_priv2 __iomem *priv2 = spu->priv2; -@@ -114,40 +126,36 @@ void spu_associate_mm(struct spu *spu, s - } - EXPORT_SYMBOL_GPL(spu_associate_mm); - --static int __spu_trap_invalid_dma(struct spu *spu) -+int spu_64k_pages_available(void) - { -- pr_debug("%s\n", __FUNCTION__); -- spu->dma_callback(spu, SPE_EVENT_INVALID_DMA); -- return 0; -+ return mmu_psize_defs[MMU_PAGE_64K].shift != 0; - } -+EXPORT_SYMBOL_GPL(spu_64k_pages_available); - --static int __spu_trap_dma_align(struct spu *spu) -+static void spu_restart_dma(struct spu *spu) - { -- pr_debug("%s\n", __FUNCTION__); -- spu->dma_callback(spu, SPE_EVENT_DMA_ALIGNMENT); -- return 0; --} -+ struct spu_priv2 __iomem *priv2 = spu->priv2; - --static int __spu_trap_error(struct spu *spu) --{ -- pr_debug("%s\n", __FUNCTION__); -- spu->dma_callback(spu, SPE_EVENT_SPE_ERROR); -- return 0; -+ if (!test_bit(SPU_CONTEXT_SWITCH_PENDING, &spu->flags)) -+ out_be64(&priv2->mfc_control_RW, MFC_CNTL_RESTART_DMA_COMMAND); - } - --static void spu_restart_dma(struct spu *spu) -+static inline void spu_load_slb(struct spu *spu, int slbe, struct spu_slb *slb) - { - struct spu_priv2 __iomem *priv2 = spu->priv2; - -- if (!test_bit(SPU_CONTEXT_SWITCH_PENDING, &spu->flags)) -- out_be64(&priv2->mfc_control_RW, MFC_CNTL_RESTART_DMA_COMMAND); -+ pr_debug("%s: adding SLB[%d] 0x%016lx 0x%016lx\n", -+ __func__, slbe, slb->vsid, slb->esid); -+ -+ out_be64(&priv2->slb_index_W, slbe); -+ out_be64(&priv2->slb_vsid_RW, slb->vsid); -+ out_be64(&priv2->slb_esid_RW, slb->esid); - } - - static int __spu_trap_data_seg(struct spu *spu, unsigned long ea) - { -- struct spu_priv2 __iomem *priv2 = spu->priv2; - struct mm_struct *mm = spu->mm; -- u64 esid, vsid, llp; -+ struct spu_slb slb; - int psize; - - pr_debug("%s\n", __FUNCTION__); -@@ -159,7 +167,7 @@ static int __spu_trap_data_seg(struct sp - printk("%s: invalid access during switch!\n", __func__); - return 1; - } -- esid = (ea & ESID_MASK) | SLB_ESID_V; -+ slb.esid = (ea & ESID_MASK) | SLB_ESID_V; - - switch(REGION_ID(ea)) { - case USER_REGION_ID: -@@ -168,21 +176,21 @@ static int __spu_trap_data_seg(struct sp - #else - psize = mm->context.user_psize; - #endif -- vsid = (get_vsid(mm->context.id, ea, MMU_SEGSIZE_256M) << SLB_VSID_SHIFT) | -- SLB_VSID_USER; -+ slb.vsid = (get_vsid(mm->context.id, ea, MMU_SEGSIZE_256M) -+ << SLB_VSID_SHIFT) | SLB_VSID_USER; - break; - case VMALLOC_REGION_ID: - if (ea < VMALLOC_END) - psize = mmu_vmalloc_psize; - else - psize = mmu_io_psize; -- vsid = (get_kernel_vsid(ea, MMU_SEGSIZE_256M) << SLB_VSID_SHIFT) | -- SLB_VSID_KERNEL; -+ slb.vsid = (get_kernel_vsid(ea, MMU_SEGSIZE_256M) -+ << SLB_VSID_SHIFT) | SLB_VSID_KERNEL; - break; - case KERNEL_REGION_ID: - psize = mmu_linear_psize; -- vsid = (get_kernel_vsid(ea, MMU_SEGSIZE_256M) << SLB_VSID_SHIFT) | -- SLB_VSID_KERNEL; -+ slb.vsid = (get_kernel_vsid(ea, MMU_SEGSIZE_256M) -+ << SLB_VSID_SHIFT) | SLB_VSID_KERNEL; - break; - default: - /* Future: support kernel segments so that drivers -@@ -191,11 +199,9 @@ static int __spu_trap_data_seg(struct sp - pr_debug("invalid region access at %016lx\n", ea); - return 1; - } -- llp = mmu_psize_defs[psize].sllp; -+ slb.vsid |= mmu_psize_defs[psize].sllp; - -- out_be64(&priv2->slb_index_W, spu->slb_replace); -- out_be64(&priv2->slb_vsid_RW, vsid | llp); -- out_be64(&priv2->slb_esid_RW, esid); -+ spu_load_slb(spu, spu->slb_replace, &slb); - - spu->slb_replace++; - if (spu->slb_replace >= 8) -@@ -225,13 +231,83 @@ static int __spu_trap_data_map(struct sp - return 1; - } - -+ spu->class_0_pending = 0; - spu->dar = ea; - spu->dsisr = dsisr; -- mb(); -+ - spu->stop_callback(spu); -+ - return 0; - } - -+static void __spu_kernel_slb(void *addr, struct spu_slb *slb) -+{ -+ unsigned long ea = (unsigned long)addr; -+ u64 llp; -+ -+ if (REGION_ID(ea) == KERNEL_REGION_ID) -+ llp = mmu_psize_defs[mmu_linear_psize].sllp; -+ else -+ llp = mmu_psize_defs[mmu_virtual_psize].sllp; -+ -+ slb->vsid = (get_kernel_vsid(ea, MMU_SEGSIZE_256M) << SLB_VSID_SHIFT) | -+ SLB_VSID_KERNEL | llp; -+ slb->esid = (ea & ESID_MASK) | SLB_ESID_V; -+} -+ -+/** -+ * Given an array of @nr_slbs SLB entries, @slbs, return non-zero if the -+ * address @new_addr is present. -+ */ -+static inline int __slb_present(struct spu_slb *slbs, int nr_slbs, -+ void *new_addr) -+{ -+ unsigned long ea = (unsigned long)new_addr; -+ int i; -+ -+ for (i = 0; i < nr_slbs; i++) -+ if (!((slbs[i].esid ^ ea) & ESID_MASK)) -+ return 1; -+ -+ return 0; -+} -+ -+/** -+ * Setup the SPU kernel SLBs, in preparation for a context save/restore. We -+ * need to map both the context save area, and the save/restore code. -+ * -+ * Because the lscsa and code may cross segment boundaires, we check to see -+ * if mappings are required for the start and end of each range. We currently -+ * assume that the mappings are smaller that one segment - if not, something -+ * is seriously wrong. -+ */ -+void spu_setup_kernel_slbs(struct spu *spu, struct spu_lscsa *lscsa, -+ void *code, int code_size) -+{ -+ struct spu_slb slbs[4]; -+ int i, nr_slbs = 0; -+ /* start and end addresses of both mappings */ -+ void *addrs[] = { -+ lscsa, (void *)lscsa + sizeof(*lscsa) - 1, -+ code, code + code_size - 1 -+ }; -+ -+ /* check the set of addresses, and create a new entry in the slbs array -+ * if there isn't already a SLB for that address */ -+ for (i = 0; i < ARRAY_SIZE(addrs); i++) { -+ if (__slb_present(slbs, nr_slbs, addrs[i])) -+ continue; -+ -+ __spu_kernel_slb(addrs[i], &slbs[nr_slbs]); -+ nr_slbs++; -+ } -+ -+ /* Add the set of SLBs */ -+ for (i = 0; i < nr_slbs; i++) -+ spu_load_slb(spu, i, &slbs[i]); -+} -+EXPORT_SYMBOL_GPL(spu_setup_kernel_slbs); -+ - static irqreturn_t - spu_irq_class_0(int irq, void *data) - { -@@ -240,12 +316,13 @@ spu_irq_class_0(int irq, void *data) - - spu = data; - -+ spin_lock(&spu->register_lock); - mask = spu_int_mask_get(spu, 0); -- stat = spu_int_stat_get(spu, 0); -- stat &= mask; -+ stat = spu_int_stat_get(spu, 0) & mask; - -- spin_lock(&spu->register_lock); - spu->class_0_pending |= stat; -+ spu->dsisr = spu_mfc_dsisr_get(spu); -+ spu->dar = spu_mfc_dar_get(spu); - spin_unlock(&spu->register_lock); - - spu->stop_callback(spu); -@@ -255,31 +332,6 @@ spu_irq_class_0(int irq, void *data) - return IRQ_HANDLED; - } - --int --spu_irq_class_0_bottom(struct spu *spu) --{ -- unsigned long flags; -- unsigned long stat; -- -- spin_lock_irqsave(&spu->register_lock, flags); -- stat = spu->class_0_pending; -- spu->class_0_pending = 0; -- -- if (stat & 1) /* invalid DMA alignment */ -- __spu_trap_dma_align(spu); -- -- if (stat & 2) /* invalid MFC DMA */ -- __spu_trap_invalid_dma(spu); -- -- if (stat & 4) /* error on SPU */ -- __spu_trap_error(spu); -- -- spin_unlock_irqrestore(&spu->register_lock, flags); -- -- return (stat & 0x7) ? -EIO : 0; --} --EXPORT_SYMBOL_GPL(spu_irq_class_0_bottom); -- - static irqreturn_t - spu_irq_class_1(int irq, void *data) - { -@@ -294,24 +346,23 @@ spu_irq_class_1(int irq, void *data) - stat = spu_int_stat_get(spu, 1) & mask; - dar = spu_mfc_dar_get(spu); - dsisr = spu_mfc_dsisr_get(spu); -- if (stat & 2) /* mapping fault */ -+ if (stat & CLASS1_STORAGE_FAULT_INTR) - spu_mfc_dsisr_set(spu, 0ul); - spu_int_stat_clear(spu, 1, stat); - spin_unlock(&spu->register_lock); - pr_debug("%s: %lx %lx %lx %lx\n", __FUNCTION__, mask, stat, - dar, dsisr); - -- if (stat & 1) /* segment fault */ -+ if (stat & CLASS1_SEGMENT_FAULT_INTR) - __spu_trap_data_seg(spu, dar); - -- if (stat & 2) { /* mapping fault */ -+ if (stat & CLASS1_STORAGE_FAULT_INTR) - __spu_trap_data_map(spu, dar, dsisr); -- } - -- if (stat & 4) /* ls compare & suspend on get */ -+ if (stat & CLASS1_LS_COMPARE_SUSPEND_ON_GET_INTR) - ; - -- if (stat & 8) /* ls compare & suspend on put */ -+ if (stat & CLASS1_LS_COMPARE_SUSPEND_ON_PUT_INTR) - ; - - return stat ? IRQ_HANDLED : IRQ_NONE; -@@ -323,6 +374,8 @@ spu_irq_class_2(int irq, void *data) - struct spu *spu; - unsigned long stat; - unsigned long mask; -+ const int mailbox_intrs = -+ CLASS2_MAILBOX_THRESHOLD_INTR | CLASS2_MAILBOX_INTR; - - spu = data; - spin_lock(&spu->register_lock); -@@ -330,31 +383,30 @@ spu_irq_class_2(int irq, void *data) - mask = spu_int_mask_get(spu, 2); - /* ignore interrupts we're not waiting for */ - stat &= mask; -- /* -- * mailbox interrupts (0x1 and 0x10) are level triggered. -- * mask them now before acknowledging. -- */ -- if (stat & 0x11) -- spu_int_mask_and(spu, 2, ~(stat & 0x11)); -+ -+ /* mailbox interrupts are level triggered. mask them now before -+ * acknowledging */ -+ if (stat & mailbox_intrs) -+ spu_int_mask_and(spu, 2, ~(stat & mailbox_intrs)); - /* acknowledge all interrupts before the callbacks */ - spu_int_stat_clear(spu, 2, stat); - spin_unlock(&spu->register_lock); - - pr_debug("class 2 interrupt %d, %lx, %lx\n", irq, stat, mask); - -- if (stat & 1) /* PPC core mailbox */ -+ if (stat & CLASS2_MAILBOX_INTR) - spu->ibox_callback(spu); - -- if (stat & 2) /* SPU stop-and-signal */ -+ if (stat & CLASS2_SPU_STOP_INTR) - spu->stop_callback(spu); - -- if (stat & 4) /* SPU halted */ -+ if (stat & CLASS2_SPU_HALT_INTR) - spu->stop_callback(spu); - -- if (stat & 8) /* DMA tag group complete */ -+ if (stat & CLASS2_SPU_DMA_TAG_GROUP_COMPLETE_INTR) - spu->mfc_callback(spu); - -- if (stat & 0x10) /* SPU mailbox threshold */ -+ if (stat & CLASS2_MAILBOX_THRESHOLD_INTR) - spu->wbox_callback(spu); - - spu->stats.class2_intr++; -@@ -479,13 +531,27 @@ EXPORT_SYMBOL_GPL(spu_add_sysdev_attr); - int spu_add_sysdev_attr_group(struct attribute_group *attrs) - { - struct spu *spu; -+ int rc = 0; - - mutex_lock(&spu_full_list_mutex); -- list_for_each_entry(spu, &spu_full_list, full_list) -- sysfs_create_group(&spu->sysdev.kobj, attrs); -+ list_for_each_entry(spu, &spu_full_list, full_list) { -+ rc = sysfs_create_group(&spu->sysdev.kobj, attrs); -+ -+ /* we're in trouble here, but try unwinding anyway */ -+ if (rc) { -+ printk(KERN_ERR "%s: can't create sysfs group '%s'\n", -+ __func__, attrs->name); -+ -+ list_for_each_entry_continue_reverse(spu, -+ &spu_full_list, full_list) -+ sysfs_remove_group(&spu->sysdev.kobj, attrs); -+ break; -+ } -+ } -+ - mutex_unlock(&spu_full_list_mutex); - -- return 0; -+ return rc; - } - EXPORT_SYMBOL_GPL(spu_add_sysdev_attr_group); - ---- /dev/null -+++ b/arch/powerpc/platforms/cell/spu_fault.c -@@ -0,0 +1,98 @@ -+/* -+ * SPU mm fault handler -+ * -+ * (C) Copyright IBM Deutschland Entwicklung GmbH 2007 -+ * -+ * Author: Arnd Bergmann -+ * Author: Jeremy Kerr -+ * -+ * 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, 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 -+ -+/* -+ * This ought to be kept in sync with the powerpc specific do_page_fault -+ * function. Currently, there are a few corner cases that we haven't had -+ * to handle fortunately. -+ */ -+int spu_handle_mm_fault(struct mm_struct *mm, unsigned long ea, -+ unsigned long dsisr, unsigned *flt) -+{ -+ struct vm_area_struct *vma; -+ unsigned long is_write; -+ int ret; -+ -+#if 0 -+ if (!IS_VALID_EA(ea)) { -+ return -EFAULT; -+ } -+#endif /* XXX */ -+ if (mm == NULL) { -+ return -EFAULT; -+ } -+ if (mm->pgd == NULL) { -+ return -EFAULT; -+ } -+ -+ down_read(&mm->mmap_sem); -+ vma = find_vma(mm, ea); -+ if (!vma) -+ goto bad_area; -+ if (vma->vm_start <= ea) -+ goto good_area; -+ if (!(vma->vm_flags & VM_GROWSDOWN)) -+ goto bad_area; -+ if (expand_stack(vma, ea)) -+ goto bad_area; -+good_area: -+ is_write = dsisr & MFC_DSISR_ACCESS_PUT; -+ if (is_write) { -+ if (!(vma->vm_flags & VM_WRITE)) -+ goto bad_area; -+ } else { -+ if (dsisr & MFC_DSISR_ACCESS_DENIED) -+ goto bad_area; -+ if (!(vma->vm_flags & (VM_READ | VM_EXEC))) -+ goto bad_area; -+ } -+ ret = 0; -+ *flt = handle_mm_fault(mm, vma, ea, is_write); -+ if (unlikely(*flt & VM_FAULT_ERROR)) { -+ if (*flt & VM_FAULT_OOM) { -+ ret = -ENOMEM; -+ goto bad_area; -+ } else if (*flt & VM_FAULT_SIGBUS) { -+ ret = -EFAULT; -+ goto bad_area; -+ } -+ BUG(); -+ } -+ if (*flt & VM_FAULT_MAJOR) -+ current->maj_flt++; -+ else -+ current->min_flt++; -+ up_read(&mm->mmap_sem); -+ return ret; -+ -+bad_area: -+ up_read(&mm->mmap_sem); -+ return -EFAULT; -+} -+EXPORT_SYMBOL_GPL(spu_handle_mm_fault); ---- a/arch/powerpc/platforms/cell/spu_manage.c -+++ b/arch/powerpc/platforms/cell/spu_manage.c -@@ -35,6 +35,7 @@ - #include - #include - -+#include "spufs/spufs.h" - #include "interrupt.h" - - struct device_node *spu_devnode(struct spu *spu) -@@ -345,7 +346,7 @@ static int __init of_create_spu(struct s - } - ret = spu_map_interrupts_old(spu, spe); - if (ret) { -- printk(KERN_ERR "%s: could not map interrupts", -+ printk(KERN_ERR "%s: could not map interrupts\n", - spu->name); - goto out_unmap; - } -@@ -369,6 +370,16 @@ static int of_destroy_spu(struct spu *sp - return 0; - } - -+static void enable_spu_by_master_run(struct spu_context *ctx) -+{ -+ ctx->ops->master_start(ctx); -+} -+ -+static void disable_spu_by_master_run(struct spu_context *ctx) -+{ -+ ctx->ops->master_stop(ctx); -+} -+ - /* Hardcoded affinity idxs for qs20 */ - #define QS20_SPES_PER_BE 8 - static int qs20_reg_idxs[QS20_SPES_PER_BE] = { 0, 2, 4, 6, 7, 5, 3, 1 }; -@@ -411,10 +422,15 @@ static void init_affinity_qs20_harcoded( - - static int of_has_vicinity(void) - { -- struct spu* spu; -+ struct device_node *dn; - -- spu = list_first_entry(&cbe_spu_info[0].spus, struct spu, cbe_list); -- return of_find_property(spu_devnode(spu), "vicinity", NULL) != NULL; -+ for_each_node_by_type(dn, "spe") { -+ if (of_find_property(dn, "vicinity", NULL)) { -+ of_node_put(dn); -+ return 1; -+ } -+ } -+ return 0; - } - - static struct spu *devnode_spu(int cbe, struct device_node *dn) -@@ -525,7 +541,7 @@ static int __init init_affinity(void) - if (of_flat_dt_is_compatible(root, "IBM,CPBW-1.0")) - init_affinity_qs20_harcoded(); - else -- printk("No affinity configuration found"); -+ printk("No affinity configuration found\n"); - } - - return 0; -@@ -535,5 +551,7 @@ const struct spu_management_ops spu_mana - .enumerate_spus = of_enumerate_spus, - .create_spu = of_create_spu, - .destroy_spu = of_destroy_spu, -+ .enable_spu = enable_spu_by_master_run, -+ .disable_spu = disable_spu_by_master_run, - .init_affinity = init_affinity, - }; ---- a/arch/powerpc/platforms/cell/spufs/Makefile -+++ b/arch/powerpc/platforms/cell/spufs/Makefile -@@ -1,8 +1,8 @@ --obj-y += switch.o fault.o lscsa_alloc.o - - obj-$(CONFIG_SPU_FS) += spufs.o - spufs-y += inode.o file.o context.o syscalls.o coredump.o - spufs-y += sched.o backing_ops.o hw_ops.o run.o gang.o -+spufs-y += switch.o fault.o lscsa_alloc.o - - # Rules to build switch.o with the help of SPU tool chain - SPU_CROSS := spu- ---- a/arch/powerpc/platforms/cell/spufs/backing_ops.c -+++ b/arch/powerpc/platforms/cell/spufs/backing_ops.c -@@ -106,16 +106,20 @@ static unsigned int spu_backing_mbox_sta - if (stat & 0xff0000) - ret |= POLLIN | POLLRDNORM; - else { -- ctx->csa.priv1.int_stat_class0_RW &= ~0x1; -- ctx->csa.priv1.int_mask_class2_RW |= 0x1; -+ ctx->csa.priv1.int_stat_class2_RW &= -+ ~CLASS2_MAILBOX_INTR; -+ ctx->csa.priv1.int_mask_class2_RW |= -+ CLASS2_ENABLE_MAILBOX_INTR; - } - } - if (events & (POLLOUT | POLLWRNORM)) { - if (stat & 0x00ff00) - ret = POLLOUT | POLLWRNORM; - else { -- ctx->csa.priv1.int_stat_class0_RW &= ~0x10; -- ctx->csa.priv1.int_mask_class2_RW |= 0x10; -+ ctx->csa.priv1.int_stat_class2_RW &= -+ ~CLASS2_MAILBOX_THRESHOLD_INTR; -+ ctx->csa.priv1.int_mask_class2_RW |= -+ CLASS2_ENABLE_MAILBOX_THRESHOLD_INTR; - } - } - spin_unlock_irq(&ctx->csa.register_lock); -@@ -139,7 +143,7 @@ static int spu_backing_ibox_read(struct - ret = 4; - } else { - /* make sure we get woken up by the interrupt */ -- ctx->csa.priv1.int_mask_class2_RW |= 0x1UL; -+ ctx->csa.priv1.int_mask_class2_RW |= CLASS2_ENABLE_MAILBOX_INTR; - ret = 0; - } - spin_unlock(&ctx->csa.register_lock); -@@ -169,7 +173,8 @@ static int spu_backing_wbox_write(struct - } else { - /* make sure we get woken up by the interrupt when space - becomes available */ -- ctx->csa.priv1.int_mask_class2_RW |= 0x10; -+ ctx->csa.priv1.int_mask_class2_RW |= -+ CLASS2_ENABLE_MAILBOX_THRESHOLD_INTR; - ret = 0; - } - spin_unlock(&ctx->csa.register_lock); -@@ -268,6 +273,11 @@ static char *spu_backing_get_ls(struct s - return ctx->csa.lscsa->ls; - } - -+static void spu_backing_privcntl_write(struct spu_context *ctx, u64 val) -+{ -+ ctx->csa.priv2.spu_privcntl_RW = val; -+} -+ - static u32 spu_backing_runcntl_read(struct spu_context *ctx) - { - return ctx->csa.prob.spu_runcntl_RW; -@@ -285,6 +295,11 @@ static void spu_backing_runcntl_write(st - spin_unlock(&ctx->csa.register_lock); - } - -+static void spu_backing_runcntl_stop(struct spu_context *ctx) -+{ -+ spu_backing_runcntl_write(ctx, SPU_RUNCNTL_STOP); -+} -+ - static void spu_backing_master_start(struct spu_context *ctx) - { - struct spu_state *csa = &ctx->csa; -@@ -358,7 +373,7 @@ static int spu_backing_send_mfc_command( - - static void spu_backing_restart_dma(struct spu_context *ctx) - { -- /* nothing to do here */ -+ ctx->csa.priv2.mfc_control_RW |= MFC_CNTL_RESTART_DMA_COMMAND; - } - - struct spu_context_ops spu_backing_ops = { -@@ -379,8 +394,10 @@ struct spu_context_ops spu_backing_ops = - .npc_write = spu_backing_npc_write, - .status_read = spu_backing_status_read, - .get_ls = spu_backing_get_ls, -+ .privcntl_write = spu_backing_privcntl_write, - .runcntl_read = spu_backing_runcntl_read, - .runcntl_write = spu_backing_runcntl_write, -+ .runcntl_stop = spu_backing_runcntl_stop, - .master_start = spu_backing_master_start, - .master_stop = spu_backing_master_stop, - .set_mfc_query = spu_backing_set_mfc_query, ---- a/arch/powerpc/platforms/cell/spufs/context.c -+++ b/arch/powerpc/platforms/cell/spufs/context.c -@@ -52,6 +52,7 @@ struct spu_context *alloc_spu_context(st - init_waitqueue_head(&ctx->wbox_wq); - init_waitqueue_head(&ctx->stop_wq); - init_waitqueue_head(&ctx->mfc_wq); -+ init_waitqueue_head(&ctx->run_wq); - ctx->state = SPU_STATE_SAVED; - ctx->ops = &spu_backing_ops; - ctx->owner = get_task_mm(current); -@@ -105,7 +106,17 @@ int put_spu_context(struct spu_context * - void spu_forget(struct spu_context *ctx) - { - struct mm_struct *mm; -- spu_acquire_saved(ctx); -+ -+ /* -+ * This is basically an open-coded spu_acquire_saved, except that -+ * we don't acquire the state mutex interruptible. -+ */ -+ mutex_lock(&ctx->state_mutex); -+ if (ctx->state != SPU_STATE_SAVED) { -+ set_bit(SPU_SCHED_WAS_ACTIVE, &ctx->sched_flags); -+ spu_deactivate(ctx); -+ } -+ - mm = ctx->owner; - ctx->owner = NULL; - mmput(mm); -@@ -133,47 +144,23 @@ void spu_unmap_mappings(struct spu_conte - } - - /** -- * spu_acquire_runnable - lock spu contex and make sure it is in runnable state -+ * spu_acquire_saved - lock spu contex and make sure it is in saved state - * @ctx: spu contex to lock -- * -- * Note: -- * Returns 0 and with the context locked on success -- * Returns negative error and with the context _unlocked_ on failure. - */ --int spu_acquire_runnable(struct spu_context *ctx, unsigned long flags) -+int spu_acquire_saved(struct spu_context *ctx) - { -- int ret = -EINVAL; -+ int ret; - -- spu_acquire(ctx); -- if (ctx->state == SPU_STATE_SAVED) { -- /* -- * Context is about to be freed, so we can't acquire it anymore. -- */ -- if (!ctx->owner) -- goto out_unlock; -- ret = spu_activate(ctx, flags); -- if (ret) -- goto out_unlock; -- } -- -- return 0; -+ ret = spu_acquire(ctx); -+ if (ret) -+ return ret; - -- out_unlock: -- spu_release(ctx); -- return ret; --} -- --/** -- * spu_acquire_saved - lock spu contex and make sure it is in saved state -- * @ctx: spu contex to lock -- */ --void spu_acquire_saved(struct spu_context *ctx) --{ -- spu_acquire(ctx); - if (ctx->state != SPU_STATE_SAVED) { - set_bit(SPU_SCHED_WAS_ACTIVE, &ctx->sched_flags); - spu_deactivate(ctx); - } -+ -+ return 0; - } - - /** ---- a/arch/powerpc/platforms/cell/spufs/coredump.c -+++ b/arch/powerpc/platforms/cell/spufs/coredump.c -@@ -148,7 +148,9 @@ int spufs_coredump_extra_notes_size(void - - fd = 0; - while ((ctx = coredump_next_context(&fd)) != NULL) { -- spu_acquire_saved(ctx); -+ rc = spu_acquire_saved(ctx); -+ if (rc) -+ break; - rc = spufs_ctx_note_size(ctx, fd); - spu_release_saved(ctx); - if (rc < 0) -@@ -224,7 +226,9 @@ int spufs_coredump_extra_notes_write(str - - fd = 0; - while ((ctx = coredump_next_context(&fd)) != NULL) { -- spu_acquire_saved(ctx); -+ rc = spu_acquire_saved(ctx); -+ if (rc) -+ return rc; - - for (j = 0; spufs_coredump_read[j].name != NULL; j++) { - rc = spufs_arch_write_note(ctx, j, file, fd, foffset); ---- a/arch/powerpc/platforms/cell/spufs/fault.c -+++ b/arch/powerpc/platforms/cell/spufs/fault.c -@@ -28,117 +28,71 @@ - - #include "spufs.h" - --/* -- * This ought to be kept in sync with the powerpc specific do_page_fault -- * function. Currently, there are a few corner cases that we haven't had -- * to handle fortunately. -+/** -+ * Handle an SPE event, depending on context SPU_CREATE_EVENTS_ENABLED flag. -+ * -+ * If the context was created with events, we just set the return event. -+ * Otherwise, send an appropriate signal to the process. - */ --static int spu_handle_mm_fault(struct mm_struct *mm, unsigned long ea, -- unsigned long dsisr, unsigned *flt) --{ -- struct vm_area_struct *vma; -- unsigned long is_write; -- int ret; -- --#if 0 -- if (!IS_VALID_EA(ea)) { -- return -EFAULT; -- } --#endif /* XXX */ -- if (mm == NULL) { -- return -EFAULT; -- } -- if (mm->pgd == NULL) { -- return -EFAULT; -- } -- -- down_read(&mm->mmap_sem); -- vma = find_vma(mm, ea); -- if (!vma) -- goto bad_area; -- if (vma->vm_start <= ea) -- goto good_area; -- if (!(vma->vm_flags & VM_GROWSDOWN)) -- goto bad_area; -- if (expand_stack(vma, ea)) -- goto bad_area; --good_area: -- is_write = dsisr & MFC_DSISR_ACCESS_PUT; -- if (is_write) { -- if (!(vma->vm_flags & VM_WRITE)) -- goto bad_area; -- } else { -- if (dsisr & MFC_DSISR_ACCESS_DENIED) -- goto bad_area; -- if (!(vma->vm_flags & (VM_READ | VM_EXEC))) -- goto bad_area; -- } -- ret = 0; -- *flt = handle_mm_fault(mm, vma, ea, is_write); -- if (unlikely(*flt & VM_FAULT_ERROR)) { -- if (*flt & VM_FAULT_OOM) { -- ret = -ENOMEM; -- goto bad_area; -- } else if (*flt & VM_FAULT_SIGBUS) { -- ret = -EFAULT; -- goto bad_area; -- } -- BUG(); -- } -- if (*flt & VM_FAULT_MAJOR) -- current->maj_flt++; -- else -- current->min_flt++; -- up_read(&mm->mmap_sem); -- return ret; -- --bad_area: -- up_read(&mm->mmap_sem); -- return -EFAULT; --} -- --static void spufs_handle_dma_error(struct spu_context *ctx, -+static void spufs_handle_event(struct spu_context *ctx, - unsigned long ea, int type) - { -+ siginfo_t info; -+ - if (ctx->flags & SPU_CREATE_EVENTS_ENABLED) { - ctx->event_return |= type; - wake_up_all(&ctx->stop_wq); -- } else { -- siginfo_t info; -- memset(&info, 0, sizeof(info)); -- -- switch (type) { -- case SPE_EVENT_INVALID_DMA: -- info.si_signo = SIGBUS; -- info.si_code = BUS_OBJERR; -- break; -- case SPE_EVENT_SPE_DATA_STORAGE: -- info.si_signo = SIGBUS; -- info.si_addr = (void __user *)ea; -- info.si_code = BUS_ADRERR; -- break; -- case SPE_EVENT_DMA_ALIGNMENT: -- info.si_signo = SIGBUS; -- /* DAR isn't set for an alignment fault :( */ -- info.si_code = BUS_ADRALN; -- break; -- case SPE_EVENT_SPE_ERROR: -- info.si_signo = SIGILL; -- info.si_addr = (void __user *)(unsigned long) -- ctx->ops->npc_read(ctx) - 4; -- info.si_code = ILL_ILLOPC; -- break; -- } -- if (info.si_signo) -- force_sig_info(info.si_signo, &info, current); -+ return; - } -+ -+ memset(&info, 0, sizeof(info)); -+ -+ switch (type) { -+ case SPE_EVENT_INVALID_DMA: -+ info.si_signo = SIGBUS; -+ info.si_code = BUS_OBJERR; -+ break; -+ case SPE_EVENT_SPE_DATA_STORAGE: -+ info.si_signo = SIGSEGV; -+ info.si_addr = (void __user *)ea; -+ info.si_code = SEGV_ACCERR; -+ ctx->ops->restart_dma(ctx); -+ break; -+ case SPE_EVENT_DMA_ALIGNMENT: -+ info.si_signo = SIGBUS; -+ /* DAR isn't set for an alignment fault :( */ -+ info.si_code = BUS_ADRALN; -+ break; -+ case SPE_EVENT_SPE_ERROR: -+ info.si_signo = SIGILL; -+ info.si_addr = (void __user *)(unsigned long) -+ ctx->ops->npc_read(ctx) - 4; -+ info.si_code = ILL_ILLOPC; -+ break; -+ } -+ -+ if (info.si_signo) -+ force_sig_info(info.si_signo, &info, current); - } - --void spufs_dma_callback(struct spu *spu, int type) -+int spufs_handle_class0(struct spu_context *ctx) - { -- spufs_handle_dma_error(spu->ctx, spu->dar, type); -+ unsigned long stat = ctx->csa.class_0_pending & CLASS0_INTR_MASK; -+ -+ if (likely(!stat)) -+ return 0; -+ -+ if (stat & CLASS0_DMA_ALIGNMENT_INTR) -+ spufs_handle_event(ctx, ctx->csa.dar, SPE_EVENT_DMA_ALIGNMENT); -+ -+ if (stat & CLASS0_INVALID_DMA_COMMAND_INTR) -+ spufs_handle_event(ctx, ctx->csa.dar, SPE_EVENT_INVALID_DMA); -+ -+ if (stat & CLASS0_SPU_ERROR_INTR) -+ spufs_handle_event(ctx, ctx->csa.dar, SPE_EVENT_SPE_ERROR); -+ -+ return -EIO; - } --EXPORT_SYMBOL_GPL(spufs_dma_callback); - - /* - * bottom half handler for page faults, we can't do this from -@@ -154,7 +108,7 @@ int spufs_handle_class1(struct spu_conte - u64 ea, dsisr, access; - unsigned long flags; - unsigned flt = 0; -- int ret; -+ int ret, ret2; - - /* - * dar and dsisr get passed from the registers -@@ -165,16 +119,8 @@ int spufs_handle_class1(struct spu_conte - * in time, we can still expect to get the same fault - * the immediately after the context restore. - */ -- if (ctx->state == SPU_STATE_RUNNABLE) { -- ea = ctx->spu->dar; -- dsisr = ctx->spu->dsisr; -- ctx->spu->dar= ctx->spu->dsisr = 0; -- } else { -- ea = ctx->csa.priv1.mfc_dar_RW; -- dsisr = ctx->csa.priv1.mfc_dsisr_RW; -- ctx->csa.priv1.mfc_dar_RW = 0; -- ctx->csa.priv1.mfc_dsisr_RW = 0; -- } -+ ea = ctx->csa.dar; -+ dsisr = ctx->csa.dsisr; - - if (!(dsisr & (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED))) - return 0; -@@ -201,7 +147,22 @@ int spufs_handle_class1(struct spu_conte - if (ret) - ret = spu_handle_mm_fault(current->mm, ea, dsisr, &flt); - -- spu_acquire(ctx); -+ /* -+ * If spu_acquire fails due to a pending signal we just want to return -+ * EINTR to userspace even if that means missing the dma restart or -+ * updating the page fault statistics. -+ */ -+ ret2 = spu_acquire(ctx); -+ if (ret2) -+ goto out; -+ -+ /* -+ * Clear dsisr under ctxt lock after handling the fault, so that -+ * time slicing will not preempt the context while the page fault -+ * handler is running. Context switch code removes mappings. -+ */ -+ ctx->csa.dar = ctx->csa.dsisr = 0; -+ - /* - * If we handled the fault successfully and are in runnable - * state, restart the DMA. -@@ -222,9 +183,9 @@ int spufs_handle_class1(struct spu_conte - if (ctx->spu) - ctx->ops->restart_dma(ctx); - } else -- spufs_handle_dma_error(ctx, ea, SPE_EVENT_SPE_DATA_STORAGE); -+ spufs_handle_event(ctx, ea, SPE_EVENT_SPE_DATA_STORAGE); - -+ out: - spuctx_switch_state(ctx, SPU_UTIL_SYSTEM); - return ret; - } --EXPORT_SYMBOL_GPL(spufs_handle_class1); ---- a/arch/powerpc/platforms/cell/spufs/file.c -+++ b/arch/powerpc/platforms/cell/spufs/file.c -@@ -40,6 +40,120 @@ - - #define SPUFS_MMAP_4K (PAGE_SIZE == 0x1000) - -+/* Simple attribute files */ -+struct spufs_attr { -+ int (*get)(void *, u64 *); -+ int (*set)(void *, u64); -+ char get_buf[24]; /* enough to store a u64 and "\n\0" */ -+ char set_buf[24]; -+ void *data; -+ const char *fmt; /* format for read operation */ -+ struct mutex mutex; /* protects access to these buffers */ -+}; -+ -+static int spufs_attr_open(struct inode *inode, struct file *file, -+ int (*get)(void *, u64 *), int (*set)(void *, u64), -+ const char *fmt) -+{ -+ struct spufs_attr *attr; -+ -+ attr = kmalloc(sizeof(*attr), GFP_KERNEL); -+ if (!attr) -+ return -ENOMEM; -+ -+ attr->get = get; -+ attr->set = set; -+ attr->data = inode->i_private; -+ attr->fmt = fmt; -+ mutex_init(&attr->mutex); -+ file->private_data = attr; -+ -+ return nonseekable_open(inode, file); -+} -+ -+static int spufs_attr_release(struct inode *inode, struct file *file) -+{ -+ kfree(file->private_data); -+ return 0; -+} -+ -+static ssize_t spufs_attr_read(struct file *file, char __user *buf, -+ size_t len, loff_t *ppos) -+{ -+ struct spufs_attr *attr; -+ size_t size; -+ ssize_t ret; -+ -+ attr = file->private_data; -+ if (!attr->get) -+ return -EACCES; -+ -+ ret = mutex_lock_interruptible(&attr->mutex); -+ if (ret) -+ return ret; -+ -+ if (*ppos) { /* continued read */ -+ size = strlen(attr->get_buf); -+ } else { /* first read */ -+ u64 val; -+ ret = attr->get(attr->data, &val); -+ if (ret) -+ goto out; -+ -+ size = scnprintf(attr->get_buf, sizeof(attr->get_buf), -+ attr->fmt, (unsigned long long)val); -+ } -+ -+ ret = simple_read_from_buffer(buf, len, ppos, attr->get_buf, size); -+out: -+ mutex_unlock(&attr->mutex); -+ return ret; -+} -+ -+static ssize_t spufs_attr_write(struct file *file, const char __user *buf, -+ size_t len, loff_t *ppos) -+{ -+ struct spufs_attr *attr; -+ u64 val; -+ size_t size; -+ ssize_t ret; -+ -+ attr = file->private_data; -+ if (!attr->set) -+ return -EACCES; -+ -+ ret = mutex_lock_interruptible(&attr->mutex); -+ if (ret) -+ return ret; -+ -+ ret = -EFAULT; -+ size = min(sizeof(attr->set_buf) - 1, len); -+ if (copy_from_user(attr->set_buf, buf, size)) -+ goto out; -+ -+ ret = len; /* claim we got the whole input */ -+ attr->set_buf[size] = '\0'; -+ val = simple_strtol(attr->set_buf, NULL, 0); -+ attr->set(attr->data, val); -+out: -+ mutex_unlock(&attr->mutex); -+ return ret; -+} -+ -+#define DEFINE_SPUFS_SIMPLE_ATTRIBUTE(__fops, __get, __set, __fmt) \ -+static int __fops ## _open(struct inode *inode, struct file *file) \ -+{ \ -+ __simple_attr_check_format(__fmt, 0ull); \ -+ return spufs_attr_open(inode, file, __get, __set, __fmt); \ -+} \ -+static struct file_operations __fops = { \ -+ .owner = THIS_MODULE, \ -+ .open = __fops ## _open, \ -+ .release = spufs_attr_release, \ -+ .read = spufs_attr_read, \ -+ .write = spufs_attr_write, \ -+}; -+ - - static int - spufs_mem_open(struct inode *inode, struct file *file) -@@ -84,9 +198,12 @@ spufs_mem_read(struct file *file, char _ - struct spu_context *ctx = file->private_data; - ssize_t ret; - -- spu_acquire(ctx); -+ ret = spu_acquire(ctx); -+ if (ret) -+ return ret; - ret = __spufs_mem_read(ctx, buffer, size, pos); - spu_release(ctx); -+ - return ret; - } - -@@ -106,7 +223,10 @@ spufs_mem_write(struct file *file, const - if (size > LS_SIZE - pos) - size = LS_SIZE - pos; - -- spu_acquire(ctx); -+ ret = spu_acquire(ctx); -+ if (ret) -+ return ret; -+ - local_store = ctx->ops->get_ls(ctx); - ret = copy_from_user(local_store + pos, buffer, size); - spu_release(ctx); -@@ -146,7 +266,8 @@ static unsigned long spufs_mem_mmap_nopf - pr_debug("spufs_mem_mmap_nopfn address=0x%lx -> 0x%lx, offset=0x%lx\n", - addr0, address, offset); - -- spu_acquire(ctx); -+ if (spu_acquire(ctx)) -+ return NOPFN_REFAULT; - - if (ctx->state == SPU_STATE_SAVED) { - vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) -@@ -236,23 +357,32 @@ static unsigned long spufs_ps_nopfn(stru - { - struct spu_context *ctx = vma->vm_file->private_data; - unsigned long area, offset = address - vma->vm_start; -- int ret; - - offset += vma->vm_pgoff << PAGE_SHIFT; - if (offset >= ps_size) - return NOPFN_SIGBUS; - -- /* error here usually means a signal.. we might want to test -- * the error code more precisely though -+ /* -+ * We have to wait for context to be loaded before we have -+ * pages to hand out to the user, but we don't want to wait -+ * with the mmap_sem held. -+ * It is possible to drop the mmap_sem here, but then we need -+ * to return NOPFN_REFAULT because the mappings may have -+ * hanged. - */ -- ret = spu_acquire_runnable(ctx, 0); -- if (ret) -+ if (spu_acquire(ctx)) - return NOPFN_REFAULT; - -- area = ctx->spu->problem_phys + ps_offs; -- vm_insert_pfn(vma, address, (area + offset) >> PAGE_SHIFT); -- spu_release(ctx); -+ if (ctx->state == SPU_STATE_SAVED) { -+ up_read(¤t->mm->mmap_sem); -+ spufs_wait(ctx->run_wq, ctx->state == SPU_STATE_RUNNABLE); -+ down_read(¤t->mm->mmap_sem); -+ } else { -+ area = ctx->spu->problem_phys + ps_offs; -+ vm_insert_pfn(vma, address, (area + offset) >> PAGE_SHIFT); -+ } - -+ spu_release(ctx); - return NOPFN_REFAULT; - } - -@@ -286,25 +416,32 @@ static int spufs_cntl_mmap(struct file * - #define spufs_cntl_mmap NULL - #endif /* !SPUFS_MMAP_4K */ - --static u64 spufs_cntl_get(void *data) -+static int spufs_cntl_get(void *data, u64 *val) - { - struct spu_context *ctx = data; -- u64 val; -+ int ret; - -- spu_acquire(ctx); -- val = ctx->ops->status_read(ctx); -+ ret = spu_acquire(ctx); -+ if (ret) -+ return ret; -+ *val = ctx->ops->status_read(ctx); - spu_release(ctx); - -- return val; -+ return 0; - } - --static void spufs_cntl_set(void *data, u64 val) -+static int spufs_cntl_set(void *data, u64 val) - { - struct spu_context *ctx = data; -+ int ret; - -- spu_acquire(ctx); -+ ret = spu_acquire(ctx); -+ if (ret) -+ return ret; - ctx->ops->runcntl_write(ctx, val); - spu_release(ctx); -+ -+ return 0; - } - - static int spufs_cntl_open(struct inode *inode, struct file *file) -@@ -317,7 +454,7 @@ static int spufs_cntl_open(struct inode - if (!i->i_openers++) - ctx->cntl = inode->i_mapping; - mutex_unlock(&ctx->mapping_lock); -- return simple_attr_open(inode, file, spufs_cntl_get, -+ return spufs_attr_open(inode, file, spufs_cntl_get, - spufs_cntl_set, "0x%08lx"); - } - -@@ -327,7 +464,7 @@ spufs_cntl_release(struct inode *inode, - struct spufs_inode_info *i = SPUFS_I(inode); - struct spu_context *ctx = i->i_ctx; - -- simple_attr_close(inode, file); -+ spufs_attr_release(inode, file); - - mutex_lock(&ctx->mapping_lock); - if (!--i->i_openers) -@@ -339,8 +476,8 @@ spufs_cntl_release(struct inode *inode, - static const struct file_operations spufs_cntl_fops = { - .open = spufs_cntl_open, - .release = spufs_cntl_release, -- .read = simple_attr_read, -- .write = simple_attr_write, -+ .read = spufs_attr_read, -+ .write = spufs_attr_write, - .mmap = spufs_cntl_mmap, - }; - -@@ -368,7 +505,9 @@ spufs_regs_read(struct file *file, char - int ret; - struct spu_context *ctx = file->private_data; - -- spu_acquire_saved(ctx); -+ ret = spu_acquire_saved(ctx); -+ if (ret) -+ return ret; - ret = __spufs_regs_read(ctx, buffer, size, pos); - spu_release_saved(ctx); - return ret; -@@ -387,7 +526,9 @@ spufs_regs_write(struct file *file, cons - return -EFBIG; - *pos += size; - -- spu_acquire_saved(ctx); -+ ret = spu_acquire_saved(ctx); -+ if (ret) -+ return ret; - - ret = copy_from_user(lscsa->gprs + *pos - size, - buffer, size) ? -EFAULT : size; -@@ -419,7 +560,9 @@ spufs_fpcr_read(struct file *file, char - int ret; - struct spu_context *ctx = file->private_data; - -- spu_acquire_saved(ctx); -+ ret = spu_acquire_saved(ctx); -+ if (ret) -+ return ret; - ret = __spufs_fpcr_read(ctx, buffer, size, pos); - spu_release_saved(ctx); - return ret; -@@ -436,10 +579,12 @@ spufs_fpcr_write(struct file *file, cons - size = min_t(ssize_t, sizeof(lscsa->fpcr) - *pos, size); - if (size <= 0) - return -EFBIG; -- *pos += size; - -- spu_acquire_saved(ctx); -+ ret = spu_acquire_saved(ctx); -+ if (ret) -+ return ret; - -+ *pos += size; - ret = copy_from_user((char *)&lscsa->fpcr + *pos - size, - buffer, size) ? -EFAULT : size; - -@@ -486,7 +631,10 @@ static ssize_t spufs_mbox_read(struct fi - - udata = (void __user *)buf; - -- spu_acquire(ctx); -+ count = spu_acquire(ctx); -+ if (count) -+ return count; -+ - for (count = 0; (count + 4) <= len; count += 4, udata++) { - int ret; - ret = ctx->ops->mbox_read(ctx, &mbox_data); -@@ -522,12 +670,15 @@ static ssize_t spufs_mbox_stat_read(stru - size_t len, loff_t *pos) - { - struct spu_context *ctx = file->private_data; -+ ssize_t ret; - u32 mbox_stat; - - if (len < 4) - return -EINVAL; - -- spu_acquire(ctx); -+ ret = spu_acquire(ctx); -+ if (ret) -+ return ret; - - mbox_stat = ctx->ops->mbox_stat_read(ctx) & 0xff; - -@@ -562,6 +713,9 @@ void spufs_ibox_callback(struct spu *spu - { - struct spu_context *ctx = spu->ctx; - -+ if (!ctx) -+ return; -+ - wake_up_all(&ctx->ibox_wq); - kill_fasync(&ctx->ibox_fasync, SIGIO, POLLIN); - } -@@ -593,7 +747,9 @@ static ssize_t spufs_ibox_read(struct fi - - udata = (void __user *)buf; - -- spu_acquire(ctx); -+ count = spu_acquire(ctx); -+ if (count) -+ return count; - - /* wait only for the first element */ - count = 0; -@@ -639,7 +795,11 @@ static unsigned int spufs_ibox_poll(stru - - poll_wait(file, &ctx->ibox_wq, wait); - -- spu_acquire(ctx); -+ /* -+ * For now keep this uninterruptible and also ignore the rule -+ * that poll should not sleep. Will be fixed later. -+ */ -+ mutex_lock(&ctx->state_mutex); - mask = ctx->ops->mbox_stat_poll(ctx, POLLIN | POLLRDNORM); - spu_release(ctx); - -@@ -657,12 +817,15 @@ static ssize_t spufs_ibox_stat_read(stru - size_t len, loff_t *pos) - { - struct spu_context *ctx = file->private_data; -+ ssize_t ret; - u32 ibox_stat; - - if (len < 4) - return -EINVAL; - -- spu_acquire(ctx); -+ ret = spu_acquire(ctx); -+ if (ret) -+ return ret; - ibox_stat = (ctx->ops->mbox_stat_read(ctx) >> 16) & 0xff; - spu_release(ctx); - -@@ -698,6 +861,9 @@ void spufs_wbox_callback(struct spu *spu - { - struct spu_context *ctx = spu->ctx; - -+ if (!ctx) -+ return; -+ - wake_up_all(&ctx->wbox_wq); - kill_fasync(&ctx->wbox_fasync, SIGIO, POLLOUT); - } -@@ -731,7 +897,9 @@ static ssize_t spufs_wbox_write(struct f - if (__get_user(wbox_data, udata)) - return -EFAULT; - -- spu_acquire(ctx); -+ count = spu_acquire(ctx); -+ if (count) -+ return count; - - /* - * make sure we can at least write one element, by waiting -@@ -772,7 +940,11 @@ static unsigned int spufs_wbox_poll(stru - - poll_wait(file, &ctx->wbox_wq, wait); - -- spu_acquire(ctx); -+ /* -+ * For now keep this uninterruptible and also ignore the rule -+ * that poll should not sleep. Will be fixed later. -+ */ -+ mutex_lock(&ctx->state_mutex); - mask = ctx->ops->mbox_stat_poll(ctx, POLLOUT | POLLWRNORM); - spu_release(ctx); - -@@ -790,12 +962,15 @@ static ssize_t spufs_wbox_stat_read(stru - size_t len, loff_t *pos) - { - struct spu_context *ctx = file->private_data; -+ ssize_t ret; - u32 wbox_stat; - - if (len < 4) - return -EINVAL; - -- spu_acquire(ctx); -+ ret = spu_acquire(ctx); -+ if (ret) -+ return ret; - wbox_stat = (ctx->ops->mbox_stat_read(ctx) >> 8) & 0xff; - spu_release(ctx); - -@@ -866,7 +1041,9 @@ static ssize_t spufs_signal1_read(struct - int ret; - struct spu_context *ctx = file->private_data; - -- spu_acquire_saved(ctx); -+ ret = spu_acquire_saved(ctx); -+ if (ret) -+ return ret; - ret = __spufs_signal1_read(ctx, buf, len, pos); - spu_release_saved(ctx); - -@@ -877,6 +1054,7 @@ static ssize_t spufs_signal1_write(struc - size_t len, loff_t *pos) - { - struct spu_context *ctx; -+ ssize_t ret; - u32 data; - - ctx = file->private_data; -@@ -887,7 +1065,9 @@ static ssize_t spufs_signal1_write(struc - if (copy_from_user(&data, buf, 4)) - return -EFAULT; - -- spu_acquire(ctx); -+ ret = spu_acquire(ctx); -+ if (ret) -+ return ret; - ctx->ops->signal1_write(ctx, data); - spu_release(ctx); - -@@ -997,7 +1177,9 @@ static ssize_t spufs_signal2_read(struct - struct spu_context *ctx = file->private_data; - int ret; - -- spu_acquire_saved(ctx); -+ ret = spu_acquire_saved(ctx); -+ if (ret) -+ return ret; - ret = __spufs_signal2_read(ctx, buf, len, pos); - spu_release_saved(ctx); - -@@ -1008,6 +1190,7 @@ static ssize_t spufs_signal2_write(struc - size_t len, loff_t *pos) - { - struct spu_context *ctx; -+ ssize_t ret; - u32 data; - - ctx = file->private_data; -@@ -1018,7 +1201,9 @@ static ssize_t spufs_signal2_write(struc - if (copy_from_user(&data, buf, 4)) - return -EFAULT; - -- spu_acquire(ctx); -+ ret = spu_acquire(ctx); -+ if (ret) -+ return ret; - ctx->ops->signal2_write(ctx, data); - spu_release(ctx); - -@@ -1086,33 +1271,42 @@ static const struct file_operations spuf - #define SPU_ATTR_ACQUIRE_SAVED 2 - - #define DEFINE_SPUFS_ATTRIBUTE(__name, __get, __set, __fmt, __acquire) \ --static u64 __##__get(void *data) \ -+static int __##__get(void *data, u64 *val) \ - { \ - struct spu_context *ctx = data; \ -- u64 ret; \ -+ int ret = 0; \ - \ - if (__acquire == SPU_ATTR_ACQUIRE) { \ -- spu_acquire(ctx); \ -- ret = __get(ctx); \ -+ ret = spu_acquire(ctx); \ -+ if (ret) \ -+ return ret; \ -+ *val = __get(ctx); \ - spu_release(ctx); \ - } else if (__acquire == SPU_ATTR_ACQUIRE_SAVED) { \ -- spu_acquire_saved(ctx); \ -- ret = __get(ctx); \ -+ ret = spu_acquire_saved(ctx); \ -+ if (ret) \ -+ return ret; \ -+ *val = __get(ctx); \ - spu_release_saved(ctx); \ - } else \ -- ret = __get(ctx); \ -+ *val = __get(ctx); \ - \ -- return ret; \ -+ return 0; \ - } \ --DEFINE_SIMPLE_ATTRIBUTE(__name, __##__get, __set, __fmt); -+DEFINE_SPUFS_SIMPLE_ATTRIBUTE(__name, __##__get, __set, __fmt); - --static void spufs_signal1_type_set(void *data, u64 val) -+static int spufs_signal1_type_set(void *data, u64 val) - { - struct spu_context *ctx = data; -+ int ret; - -- spu_acquire(ctx); -+ ret = spu_acquire(ctx); -+ if (ret) -+ return ret; - ctx->ops->signal1_type_set(ctx, val); - spu_release(ctx); -+ -+ return 0; - } - - static u64 spufs_signal1_type_get(struct spu_context *ctx) -@@ -1123,13 +1317,18 @@ DEFINE_SPUFS_ATTRIBUTE(spufs_signal1_typ - spufs_signal1_type_set, "%llu", SPU_ATTR_ACQUIRE); - - --static void spufs_signal2_type_set(void *data, u64 val) -+static int spufs_signal2_type_set(void *data, u64 val) - { - struct spu_context *ctx = data; -+ int ret; - -- spu_acquire(ctx); -+ ret = spu_acquire(ctx); -+ if (ret) -+ return ret; - ctx->ops->signal2_type_set(ctx, val); - spu_release(ctx); -+ -+ return 0; - } - - static u64 spufs_signal2_type_get(struct spu_context *ctx) -@@ -1329,6 +1528,9 @@ void spufs_mfc_callback(struct spu *spu) - { - struct spu_context *ctx = spu->ctx; - -+ if (!ctx) -+ return; -+ - wake_up_all(&ctx->mfc_wq); - - pr_debug("%s %s\n", __FUNCTION__, spu->name); -@@ -1375,12 +1577,17 @@ static ssize_t spufs_mfc_read(struct fil - if (size != 4) - goto out; - -- spu_acquire(ctx); -+ ret = spu_acquire(ctx); -+ if (ret) -+ return ret; -+ -+ ret = -EINVAL; - if (file->f_flags & O_NONBLOCK) { - status = ctx->ops->read_mfc_tagstatus(ctx); - if (!(status & ctx->tagwait)) - ret = -EAGAIN; - else -+ /* XXX(hch): shouldn't we clear ret here? */ - ctx->tagwait &= ~status; - } else { - ret = spufs_wait(ctx->mfc_wq, -@@ -1505,7 +1712,11 @@ static ssize_t spufs_mfc_write(struct fi - if (ret) - goto out; - -- ret = spu_acquire_runnable(ctx, 0); -+ ret = spu_acquire(ctx); -+ if (ret) -+ goto out; -+ -+ ret = spufs_wait(ctx->run_wq, ctx->state == SPU_STATE_RUNNABLE); - if (ret) - goto out; - -@@ -1539,7 +1750,11 @@ static unsigned int spufs_mfc_poll(struc - - poll_wait(file, &ctx->mfc_wq, wait); - -- spu_acquire(ctx); -+ /* -+ * For now keep this uninterruptible and also ignore the rule -+ * that poll should not sleep. Will be fixed later. -+ */ -+ mutex_lock(&ctx->state_mutex); - ctx->ops->set_mfc_query(ctx, ctx->tagwait, 2); - free_elements = ctx->ops->get_mfc_free_elements(ctx); - tagstatus = ctx->ops->read_mfc_tagstatus(ctx); -@@ -1562,7 +1777,9 @@ static int spufs_mfc_flush(struct file * - struct spu_context *ctx = file->private_data; - int ret; - -- spu_acquire(ctx); -+ ret = spu_acquire(ctx); -+ if (ret) -+ return ret; - #if 0 - /* this currently hangs */ - ret = spufs_wait(ctx->mfc_wq, -@@ -1605,12 +1822,18 @@ static const struct file_operations spuf - .mmap = spufs_mfc_mmap, - }; - --static void spufs_npc_set(void *data, u64 val) -+static int spufs_npc_set(void *data, u64 val) - { - struct spu_context *ctx = data; -- spu_acquire(ctx); -+ int ret; -+ -+ ret = spu_acquire(ctx); -+ if (ret) -+ return ret; - ctx->ops->npc_write(ctx, val); - spu_release(ctx); -+ -+ return 0; - } - - static u64 spufs_npc_get(struct spu_context *ctx) -@@ -1620,13 +1843,19 @@ static u64 spufs_npc_get(struct spu_cont - DEFINE_SPUFS_ATTRIBUTE(spufs_npc_ops, spufs_npc_get, spufs_npc_set, - "0x%llx\n", SPU_ATTR_ACQUIRE); - --static void spufs_decr_set(void *data, u64 val) -+static int spufs_decr_set(void *data, u64 val) - { - struct spu_context *ctx = data; - struct spu_lscsa *lscsa = ctx->csa.lscsa; -- spu_acquire_saved(ctx); -+ int ret; -+ -+ ret = spu_acquire_saved(ctx); -+ if (ret) -+ return ret; - lscsa->decr.slot[0] = (u32) val; - spu_release_saved(ctx); -+ -+ return 0; - } - - static u64 spufs_decr_get(struct spu_context *ctx) -@@ -1637,15 +1866,21 @@ static u64 spufs_decr_get(struct spu_con - DEFINE_SPUFS_ATTRIBUTE(spufs_decr_ops, spufs_decr_get, spufs_decr_set, - "0x%llx\n", SPU_ATTR_ACQUIRE_SAVED); - --static void spufs_decr_status_set(void *data, u64 val) -+static int spufs_decr_status_set(void *data, u64 val) - { - struct spu_context *ctx = data; -- spu_acquire_saved(ctx); -+ int ret; -+ -+ ret = spu_acquire_saved(ctx); -+ if (ret) -+ return ret; - if (val) - ctx->csa.priv2.mfc_control_RW |= MFC_CNTL_DECREMENTER_RUNNING; - else - ctx->csa.priv2.mfc_control_RW &= ~MFC_CNTL_DECREMENTER_RUNNING; - spu_release_saved(ctx); -+ -+ return 0; - } - - static u64 spufs_decr_status_get(struct spu_context *ctx) -@@ -1659,13 +1894,19 @@ DEFINE_SPUFS_ATTRIBUTE(spufs_decr_status - spufs_decr_status_set, "0x%llx\n", - SPU_ATTR_ACQUIRE_SAVED); - --static void spufs_event_mask_set(void *data, u64 val) -+static int spufs_event_mask_set(void *data, u64 val) - { - struct spu_context *ctx = data; - struct spu_lscsa *lscsa = ctx->csa.lscsa; -- spu_acquire_saved(ctx); -+ int ret; -+ -+ ret = spu_acquire_saved(ctx); -+ if (ret) -+ return ret; - lscsa->event_mask.slot[0] = (u32) val; - spu_release_saved(ctx); -+ -+ return 0; - } - - static u64 spufs_event_mask_get(struct spu_context *ctx) -@@ -1690,13 +1931,19 @@ static u64 spufs_event_status_get(struct - DEFINE_SPUFS_ATTRIBUTE(spufs_event_status_ops, spufs_event_status_get, - NULL, "0x%llx\n", SPU_ATTR_ACQUIRE_SAVED) - --static void spufs_srr0_set(void *data, u64 val) -+static int spufs_srr0_set(void *data, u64 val) - { - struct spu_context *ctx = data; - struct spu_lscsa *lscsa = ctx->csa.lscsa; -- spu_acquire_saved(ctx); -+ int ret; -+ -+ ret = spu_acquire_saved(ctx); -+ if (ret) -+ return ret; - lscsa->srr0.slot[0] = (u32) val; - spu_release_saved(ctx); -+ -+ return 0; - } - - static u64 spufs_srr0_get(struct spu_context *ctx) -@@ -1727,10 +1974,12 @@ static u64 spufs_object_id_get(struct sp - return ctx->object_id; - } - --static void spufs_object_id_set(void *data, u64 id) -+static int spufs_object_id_set(void *data, u64 id) - { - struct spu_context *ctx = data; - ctx->object_id = id; -+ -+ return 0; - } - - DEFINE_SPUFS_ATTRIBUTE(spufs_object_id_ops, spufs_object_id_get, -@@ -1777,13 +2026,13 @@ static const struct file_operations spuf - static ssize_t __spufs_mbox_info_read(struct spu_context *ctx, - char __user *buf, size_t len, loff_t *pos) - { -- u32 mbox_stat; - u32 data; - -- mbox_stat = ctx->csa.prob.mb_stat_R; -- if (mbox_stat & 0x0000ff) { -- data = ctx->csa.prob.pu_mb_R; -- } -+ /* EOF if there's no entry in the mbox */ -+ if (!(ctx->csa.prob.mb_stat_R & 0x0000ff)) -+ return 0; -+ -+ data = ctx->csa.prob.pu_mb_R; - - return simple_read_from_buffer(buf, len, pos, &data, sizeof data); - } -@@ -1797,7 +2046,9 @@ static ssize_t spufs_mbox_info_read(stru - if (!access_ok(VERIFY_WRITE, buf, len)) - return -EFAULT; - -- spu_acquire_saved(ctx); -+ ret = spu_acquire_saved(ctx); -+ if (ret) -+ return ret; - spin_lock(&ctx->csa.register_lock); - ret = __spufs_mbox_info_read(ctx, buf, len, pos); - spin_unlock(&ctx->csa.register_lock); -@@ -1815,13 +2066,13 @@ static const struct file_operations spuf - static ssize_t __spufs_ibox_info_read(struct spu_context *ctx, - char __user *buf, size_t len, loff_t *pos) - { -- u32 ibox_stat; - u32 data; - -- ibox_stat = ctx->csa.prob.mb_stat_R; -- if (ibox_stat & 0xff0000) { -- data = ctx->csa.priv2.puint_mb_R; -- } -+ /* EOF if there's no entry in the ibox */ -+ if (!(ctx->csa.prob.mb_stat_R & 0xff0000)) -+ return 0; -+ -+ data = ctx->csa.priv2.puint_mb_R; - - return simple_read_from_buffer(buf, len, pos, &data, sizeof data); - } -@@ -1835,7 +2086,9 @@ static ssize_t spufs_ibox_info_read(stru - if (!access_ok(VERIFY_WRITE, buf, len)) - return -EFAULT; - -- spu_acquire_saved(ctx); -+ ret = spu_acquire_saved(ctx); -+ if (ret) -+ return ret; - spin_lock(&ctx->csa.register_lock); - ret = __spufs_ibox_info_read(ctx, buf, len, pos); - spin_unlock(&ctx->csa.register_lock); -@@ -1876,7 +2129,9 @@ static ssize_t spufs_wbox_info_read(stru - if (!access_ok(VERIFY_WRITE, buf, len)) - return -EFAULT; - -- spu_acquire_saved(ctx); -+ ret = spu_acquire_saved(ctx); -+ if (ret) -+ return ret; - spin_lock(&ctx->csa.register_lock); - ret = __spufs_wbox_info_read(ctx, buf, len, pos); - spin_unlock(&ctx->csa.register_lock); -@@ -1926,7 +2181,9 @@ static ssize_t spufs_dma_info_read(struc - if (!access_ok(VERIFY_WRITE, buf, len)) - return -EFAULT; - -- spu_acquire_saved(ctx); -+ ret = spu_acquire_saved(ctx); -+ if (ret) -+ return ret; - spin_lock(&ctx->csa.register_lock); - ret = __spufs_dma_info_read(ctx, buf, len, pos); - spin_unlock(&ctx->csa.register_lock); -@@ -1977,7 +2234,9 @@ static ssize_t spufs_proxydma_info_read( - struct spu_context *ctx = file->private_data; - int ret; - -- spu_acquire_saved(ctx); -+ ret = spu_acquire_saved(ctx); -+ if (ret) -+ return ret; - spin_lock(&ctx->csa.register_lock); - ret = __spufs_proxydma_info_read(ctx, buf, len, pos); - spin_unlock(&ctx->csa.register_lock); -@@ -2066,8 +2325,12 @@ static unsigned long long spufs_class2_i - static int spufs_show_stat(struct seq_file *s, void *private) - { - struct spu_context *ctx = s->private; -+ int ret; -+ -+ ret = spu_acquire(ctx); -+ if (ret) -+ return ret; - -- spu_acquire(ctx); - seq_printf(s, "%s %llu %llu %llu %llu " - "%llu %llu %llu %llu %llu %llu %llu %llu\n", - ctx_state_names[ctx->stats.util_state], ---- a/arch/powerpc/platforms/cell/spufs/hw_ops.c -+++ b/arch/powerpc/platforms/cell/spufs/hw_ops.c -@@ -76,16 +76,18 @@ static unsigned int spu_hw_mbox_stat_pol - if (stat & 0xff0000) - ret |= POLLIN | POLLRDNORM; - else { -- spu_int_stat_clear(spu, 2, 0x1); -- spu_int_mask_or(spu, 2, 0x1); -+ spu_int_stat_clear(spu, 2, CLASS2_MAILBOX_INTR); -+ spu_int_mask_or(spu, 2, CLASS2_ENABLE_MAILBOX_INTR); - } - } - if (events & (POLLOUT | POLLWRNORM)) { - if (stat & 0x00ff00) - ret = POLLOUT | POLLWRNORM; - else { -- spu_int_stat_clear(spu, 2, 0x10); -- spu_int_mask_or(spu, 2, 0x10); -+ spu_int_stat_clear(spu, 2, -+ CLASS2_MAILBOX_THRESHOLD_INTR); -+ spu_int_mask_or(spu, 2, -+ CLASS2_ENABLE_MAILBOX_THRESHOLD_INTR); - } - } - spin_unlock_irq(&spu->register_lock); -@@ -106,7 +108,7 @@ static int spu_hw_ibox_read(struct spu_c - ret = 4; - } else { - /* make sure we get woken up by the interrupt */ -- spu_int_mask_or(spu, 2, 0x1); -+ spu_int_mask_or(spu, 2, CLASS2_ENABLE_MAILBOX_INTR); - ret = 0; - } - spin_unlock_irq(&spu->register_lock); -@@ -127,7 +129,7 @@ static int spu_hw_wbox_write(struct spu_ - } else { - /* make sure we get woken up by the interrupt when space - becomes available */ -- spu_int_mask_or(spu, 2, 0x10); -+ spu_int_mask_or(spu, 2, CLASS2_ENABLE_MAILBOX_THRESHOLD_INTR); - ret = 0; - } - spin_unlock_irq(&spu->register_lock); -@@ -206,6 +208,11 @@ static char *spu_hw_get_ls(struct spu_co - return ctx->spu->local_store; - } - -+static void spu_hw_privcntl_write(struct spu_context *ctx, u64 val) -+{ -+ out_be64(&ctx->spu->priv2->spu_privcntl_RW, val); -+} -+ - static u32 spu_hw_runcntl_read(struct spu_context *ctx) - { - return in_be32(&ctx->spu->problem->spu_runcntl_RW); -@@ -215,11 +222,21 @@ static void spu_hw_runcntl_write(struct - { - spin_lock_irq(&ctx->spu->register_lock); - if (val & SPU_RUNCNTL_ISOLATE) -- out_be64(&ctx->spu->priv2->spu_privcntl_RW, 4LL); -+ spu_hw_privcntl_write(ctx, -+ SPU_PRIVCNT_LOAD_REQUEST_ENABLE_MASK); - out_be32(&ctx->spu->problem->spu_runcntl_RW, val); - spin_unlock_irq(&ctx->spu->register_lock); - } - -+static void spu_hw_runcntl_stop(struct spu_context *ctx) -+{ -+ spin_lock_irq(&ctx->spu->register_lock); -+ out_be32(&ctx->spu->problem->spu_runcntl_RW, SPU_RUNCNTL_STOP); -+ while (in_be32(&ctx->spu->problem->spu_status_R) & SPU_STATUS_RUNNING) -+ cpu_relax(); -+ spin_unlock_irq(&ctx->spu->register_lock); -+} -+ - static void spu_hw_master_start(struct spu_context *ctx) - { - struct spu *spu = ctx->spu; -@@ -319,8 +336,10 @@ struct spu_context_ops spu_hw_ops = { - .npc_write = spu_hw_npc_write, - .status_read = spu_hw_status_read, - .get_ls = spu_hw_get_ls, -+ .privcntl_write = spu_hw_privcntl_write, - .runcntl_read = spu_hw_runcntl_read, - .runcntl_write = spu_hw_runcntl_write, -+ .runcntl_stop = spu_hw_runcntl_stop, - .master_start = spu_hw_master_start, - .master_stop = spu_hw_master_stop, - .set_mfc_query = spu_hw_set_mfc_query, ---- a/arch/powerpc/platforms/cell/spufs/lscsa_alloc.c -+++ b/arch/powerpc/platforms/cell/spufs/lscsa_alloc.c -@@ -28,6 +28,8 @@ - #include - #include - -+#include "spufs.h" -+ - static int spu_alloc_lscsa_std(struct spu_state *csa) - { - struct spu_lscsa *lscsa; -@@ -73,7 +75,7 @@ int spu_alloc_lscsa(struct spu_state *cs - int i, j, n_4k; - - /* Check availability of 64K pages */ -- if (mmu_psize_defs[MMU_PAGE_64K].shift == 0) -+ if (!spu_64k_pages_available()) - goto fail; - - csa->use_big_pages = 1; ---- a/arch/powerpc/platforms/cell/spufs/run.c -+++ b/arch/powerpc/platforms/cell/spufs/run.c -@@ -15,24 +15,55 @@ void spufs_stop_callback(struct spu *spu - { - struct spu_context *ctx = spu->ctx; - -- wake_up_all(&ctx->stop_wq); -+ /* -+ * It should be impossible to preempt a context while an exception -+ * is being processed, since the context switch code is specially -+ * coded to deal with interrupts ... But, just in case, sanity check -+ * the context pointer. It is OK to return doing nothing since -+ * the exception will be regenerated when the context is resumed. -+ */ -+ if (ctx) { -+ /* Copy exception arguments into module specific structure */ -+ ctx->csa.class_0_pending = spu->class_0_pending; -+ ctx->csa.dsisr = spu->dsisr; -+ ctx->csa.dar = spu->dar; -+ -+ /* ensure that the exception status has hit memory before a -+ * thread waiting on the context's stop queue is woken */ -+ smp_wmb(); -+ -+ wake_up_all(&ctx->stop_wq); -+ } -+ -+ /* Clear callback arguments from spu structure */ -+ spu->class_0_pending = 0; -+ spu->dsisr = 0; -+ spu->dar = 0; - } - --static inline int spu_stopped(struct spu_context *ctx, u32 *stat) -+int spu_stopped(struct spu_context *ctx, u32 *stat) - { -- struct spu *spu; -- u64 pte_fault; -+ u64 dsisr; -+ u32 stopped; - - *stat = ctx->ops->status_read(ctx); - -- spu = ctx->spu; -- if (ctx->state != SPU_STATE_RUNNABLE || -- test_bit(SPU_SCHED_NOTIFY_ACTIVE, &ctx->sched_flags)) -+ if (test_bit(SPU_SCHED_NOTIFY_ACTIVE, &ctx->sched_flags)) -+ return 1; -+ -+ stopped = SPU_STATUS_INVALID_INSTR | SPU_STATUS_SINGLE_STEP | -+ SPU_STATUS_STOPPED_BY_HALT | SPU_STATUS_STOPPED_BY_STOP; -+ if (*stat & stopped) -+ return 1; -+ -+ dsisr = ctx->csa.dsisr; -+ if (dsisr & (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED)) - return 1; -- pte_fault = spu->dsisr & -- (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED); -- return (!(*stat & SPU_STATUS_RUNNING) || pte_fault || spu->class_0_pending) ? -- 1 : 0; -+ -+ if (ctx->csa.class_0_pending) -+ return 1; -+ -+ return 0; - } - - static int spu_setup_isolated(struct spu_context *ctx) -@@ -128,34 +159,66 @@ out: - - static int spu_run_init(struct spu_context *ctx, u32 *npc) - { -+ unsigned long runcntl = SPU_RUNCNTL_RUNNABLE; -+ int ret; -+ - spuctx_switch_state(ctx, SPU_UTIL_SYSTEM); - -- if (ctx->flags & SPU_CREATE_ISOLATE) { -- unsigned long runcntl; -+ /* -+ * NOSCHED is synchronous scheduling with respect to the caller. -+ * The caller waits for the context to be loaded. -+ */ -+ if (ctx->flags & SPU_CREATE_NOSCHED) { -+ if (ctx->state == SPU_STATE_SAVED) { -+ ret = spu_activate(ctx, 0); -+ if (ret) -+ return ret; -+ } -+ } - -+ /* -+ * Apply special setup as required. -+ */ -+ if (ctx->flags & SPU_CREATE_ISOLATE) { - if (!(ctx->ops->status_read(ctx) & SPU_STATUS_ISOLATED_STATE)) { -- int ret = spu_setup_isolated(ctx); -+ ret = spu_setup_isolated(ctx); - if (ret) - return ret; - } - -- /* if userspace has set the runcntrl register (eg, to issue an -- * isolated exit), we need to re-set it here */ -+ /* -+ * If userspace has set the runcntrl register (eg, to -+ * issue an isolated exit), we need to re-set it here -+ */ - runcntl = ctx->ops->runcntl_read(ctx) & - (SPU_RUNCNTL_RUNNABLE | SPU_RUNCNTL_ISOLATE); - if (runcntl == 0) - runcntl = SPU_RUNCNTL_RUNNABLE; -+ } -+ -+ if (ctx->flags & SPU_CREATE_NOSCHED) { -+ spuctx_switch_state(ctx, SPU_UTIL_USER); - ctx->ops->runcntl_write(ctx, runcntl); - } else { -- unsigned long mode = SPU_PRIVCNTL_MODE_NORMAL; -- ctx->ops->npc_write(ctx, *npc); -+ unsigned long privcntl; -+ - if (test_thread_flag(TIF_SINGLESTEP)) -- mode = SPU_PRIVCNTL_MODE_SINGLE_STEP; -- out_be64(&ctx->spu->priv2->spu_privcntl_RW, mode); -- ctx->ops->runcntl_write(ctx, SPU_RUNCNTL_RUNNABLE); -- } -+ privcntl = SPU_PRIVCNTL_MODE_SINGLE_STEP; -+ else -+ privcntl = SPU_PRIVCNTL_MODE_NORMAL; - -- spuctx_switch_state(ctx, SPU_UTIL_USER); -+ ctx->ops->npc_write(ctx, *npc); -+ ctx->ops->privcntl_write(ctx, privcntl); -+ ctx->ops->runcntl_write(ctx, runcntl); -+ -+ if (ctx->state == SPU_STATE_SAVED) { -+ ret = spu_activate(ctx, 0); -+ if (ret) -+ return ret; -+ } else { -+ spuctx_switch_state(ctx, SPU_UTIL_USER); -+ } -+ } - - return 0; - } -@@ -165,6 +228,8 @@ static int spu_run_fini(struct spu_conte - { - int ret = 0; - -+ spu_del_from_rq(ctx); -+ - *status = ctx->ops->status_read(ctx); - *npc = ctx->ops->npc_read(ctx); - -@@ -177,26 +242,6 @@ static int spu_run_fini(struct spu_conte - return ret; - } - --static int spu_reacquire_runnable(struct spu_context *ctx, u32 *npc, -- u32 *status) --{ -- int ret; -- -- ret = spu_run_fini(ctx, npc, status); -- if (ret) -- return ret; -- -- if (*status & (SPU_STATUS_STOPPED_BY_STOP | SPU_STATUS_STOPPED_BY_HALT)) -- return *status; -- -- ret = spu_acquire_runnable(ctx, 0); -- if (ret) -- return ret; -- -- spuctx_switch_state(ctx, SPU_UTIL_USER); -- return 0; --} -- - /* - * SPU syscall restarting is tricky because we violate the basic - * assumption that the signal handler is running on the interrupted -@@ -247,7 +292,7 @@ static int spu_process_callback(struct s - u32 ls_pointer, npc; - void __iomem *ls; - long spu_ret; -- int ret; -+ int ret, ret2; - - /* get syscall block from local store */ - npc = ctx->ops->npc_read(ctx) & ~3; -@@ -269,9 +314,11 @@ static int spu_process_callback(struct s - if (spu_ret <= -ERESTARTSYS) { - ret = spu_handle_restartsys(ctx, &spu_ret, &npc); - } -- spu_acquire(ctx); -+ ret2 = spu_acquire(ctx); - if (ret == -ERESTARTSYS) - return ret; -+ if (ret2) -+ return -EINTR; - } - - /* write result, jump over indirect pointer */ -@@ -281,18 +328,6 @@ static int spu_process_callback(struct s - return ret; - } - --static inline int spu_process_events(struct spu_context *ctx) --{ -- struct spu *spu = ctx->spu; -- int ret = 0; -- -- if (spu->class_0_pending) -- ret = spu_irq_class_0_bottom(spu); -- if (!ret && signal_pending(current)) -- ret = -ERESTARTSYS; -- return ret; --} -- - long spufs_run_spu(struct spu_context *ctx, u32 *npc, u32 *event) - { - int ret; -@@ -302,29 +337,14 @@ long spufs_run_spu(struct spu_context *c - if (mutex_lock_interruptible(&ctx->run_mutex)) - return -ERESTARTSYS; - -- ctx->ops->master_start(ctx); -+ spu_enable_spu(ctx); - ctx->event_return = 0; - -- spu_acquire(ctx); -- if (ctx->state == SPU_STATE_SAVED) { -- __spu_update_sched_info(ctx); -- spu_set_timeslice(ctx); -- -- ret = spu_activate(ctx, 0); -- if (ret) { -- spu_release(ctx); -- goto out; -- } -- } else { -- /* -- * We have to update the scheduling priority under active_mutex -- * to protect against find_victim(). -- * -- * No need to update the timeslice ASAP, it will get updated -- * once the current one has expired. -- */ -- spu_update_sched_info(ctx); -- } -+ ret = spu_acquire(ctx); -+ if (ret) -+ goto out_unlock; -+ -+ spu_update_sched_info(ctx); - - ret = spu_run_init(ctx, npc); - if (ret) { -@@ -358,14 +378,12 @@ long spufs_run_spu(struct spu_context *c - if (ret) - break; - -- if (unlikely(ctx->state != SPU_STATE_RUNNABLE)) { -- ret = spu_reacquire_runnable(ctx, npc, &status); -- if (ret) -- goto out2; -- continue; -- } -- ret = spu_process_events(ctx); -+ ret = spufs_handle_class0(ctx); -+ if (ret) -+ break; - -+ if (signal_pending(current)) -+ ret = -ERESTARTSYS; - } while (!ret && !(status & (SPU_STATUS_STOPPED_BY_STOP | - SPU_STATUS_STOPPED_BY_HALT | - SPU_STATUS_SINGLE_STEP))); -@@ -376,11 +394,10 @@ long spufs_run_spu(struct spu_context *c - ctx->stats.libassist++; - - -- ctx->ops->master_stop(ctx); -+ spu_disable_spu(ctx); - ret = spu_run_fini(ctx, npc, &status); - spu_yield(ctx); - --out2: - if ((ret == 0) || - ((ret == -ERESTARTSYS) && - ((status & SPU_STATUS_STOPPED_BY_HALT) || -@@ -401,6 +418,7 @@ out2: - - out: - *event = ctx->event_return; -+out_unlock: - mutex_unlock(&ctx->run_mutex); - return ret; - } ---- a/arch/powerpc/platforms/cell/spufs/sched.c -+++ b/arch/powerpc/platforms/cell/spufs/sched.c -@@ -58,6 +58,7 @@ static unsigned long spu_avenrun[3]; - static struct spu_prio_array *spu_prio; - static struct task_struct *spusched_task; - static struct timer_list spusched_timer; -+static struct timer_list spuloadavg_timer; - - /* - * Priority of a normal, non-rt, non-niced'd process (aka nice level 0). -@@ -105,15 +106,21 @@ void spu_set_timeslice(struct spu_contex - void __spu_update_sched_info(struct spu_context *ctx) - { - /* -- * 32-Bit assignment are atomic on powerpc, and we don't care about -- * memory ordering here because retriving the controlling thread is -- * per defintion racy. -+ * assert that the context is not on the runqueue, so it is safe -+ * to change its scheduling parameters. -+ */ -+ BUG_ON(!list_empty(&ctx->rq)); -+ -+ /* -+ * 32-Bit assignments are atomic on powerpc, and we don't care about -+ * memory ordering here because retrieving the controlling thread is -+ * per definition racy. - */ - ctx->tid = current->pid; - - /* - * We do our own priority calculations, so we normally want -- * ->static_prio to start with. Unfortunately thies field -+ * ->static_prio to start with. Unfortunately this field - * contains junk for threads with a realtime scheduling - * policy so we have to look at ->prio in this case. - */ -@@ -124,23 +131,32 @@ void __spu_update_sched_info(struct spu_ - ctx->policy = current->policy; - - /* -- * A lot of places that don't hold list_mutex poke into -- * cpus_allowed, including grab_runnable_context which -- * already holds the runq_lock. So abuse runq_lock -- * to protect this field aswell. -+ * TO DO: the context may be loaded, so we may need to activate -+ * it again on a different node. But it shouldn't hurt anything -+ * to update its parameters, because we know that the scheduler -+ * is not actively looking at this field, since it is not on the -+ * runqueue. The context will be rescheduled on the proper node -+ * if it is timesliced or preempted. - */ -- spin_lock(&spu_prio->runq_lock); - ctx->cpus_allowed = current->cpus_allowed; -- spin_unlock(&spu_prio->runq_lock); - } - - void spu_update_sched_info(struct spu_context *ctx) - { -- int node = ctx->spu->node; -+ int node; - -- mutex_lock(&cbe_spu_info[node].list_mutex); -- __spu_update_sched_info(ctx); -- mutex_unlock(&cbe_spu_info[node].list_mutex); -+ if (ctx->state == SPU_STATE_RUNNABLE) { -+ node = ctx->spu->node; -+ -+ /* -+ * Take list_mutex to sync with find_victim(). -+ */ -+ mutex_lock(&cbe_spu_info[node].list_mutex); -+ __spu_update_sched_info(ctx); -+ mutex_unlock(&cbe_spu_info[node].list_mutex); -+ } else { -+ __spu_update_sched_info(ctx); -+ } - } - - static int __node_allowed(struct spu_context *ctx, int node) -@@ -174,7 +190,7 @@ void do_notify_spus_active(void) - * Wake up the active spu_contexts. - * - * When the awakened processes see their "notify_active" flag is set, -- * they will call spu_switch_notify(); -+ * they will call spu_switch_notify(). - */ - for_each_online_node(node) { - struct spu *spu; -@@ -221,7 +237,6 @@ static void spu_bind_context(struct spu - spu->wbox_callback = spufs_wbox_callback; - spu->stop_callback = spufs_stop_callback; - spu->mfc_callback = spufs_mfc_callback; -- spu->dma_callback = spufs_dma_callback; - mb(); - spu_unmap_mappings(ctx); - spu_restore(&ctx->csa, spu); -@@ -409,7 +424,6 @@ static void spu_unbind_context(struct sp - spu->wbox_callback = NULL; - spu->stop_callback = NULL; - spu->mfc_callback = NULL; -- spu->dma_callback = NULL; - spu_associate_mm(spu, NULL); - spu->pid = 0; - spu->tgid = 0; -@@ -454,6 +468,13 @@ static void __spu_add_to_rq(struct spu_c - } - } - -+static void spu_add_to_rq(struct spu_context *ctx) -+{ -+ spin_lock(&spu_prio->runq_lock); -+ __spu_add_to_rq(ctx); -+ spin_unlock(&spu_prio->runq_lock); -+} -+ - static void __spu_del_from_rq(struct spu_context *ctx) - { - int prio = ctx->prio; -@@ -468,10 +489,24 @@ static void __spu_del_from_rq(struct spu - } - } - -+void spu_del_from_rq(struct spu_context *ctx) -+{ -+ spin_lock(&spu_prio->runq_lock); -+ __spu_del_from_rq(ctx); -+ spin_unlock(&spu_prio->runq_lock); -+} -+ - static void spu_prio_wait(struct spu_context *ctx) - { - DEFINE_WAIT(wait); - -+ /* -+ * The caller must explicitly wait for a context to be loaded -+ * if the nosched flag is set. If NOSCHED is not set, the caller -+ * queues the context and waits for an spu event or error. -+ */ -+ BUG_ON(!(ctx->flags & SPU_CREATE_NOSCHED)); -+ - spin_lock(&spu_prio->runq_lock); - prepare_to_wait_exclusive(&ctx->stop_wq, &wait, TASK_INTERRUPTIBLE); - if (!signal_pending(current)) { -@@ -555,7 +590,7 @@ static struct spu *find_victim(struct sp - /* - * Look for a possible preemption candidate on the local node first. - * If there is no candidate look at the other nodes. This isn't -- * exactly fair, but so far the whole spu schedule tries to keep -+ * exactly fair, but so far the whole spu scheduler tries to keep - * a strong node affinity. We might want to fine-tune this in - * the future. - */ -@@ -571,6 +606,7 @@ static struct spu *find_victim(struct sp - struct spu_context *tmp = spu->ctx; - - if (tmp && tmp->prio > ctx->prio && -+ !(tmp->flags & SPU_CREATE_NOSCHED) && - (!victim || tmp->prio > victim->prio)) - victim = spu->ctx; - } -@@ -582,6 +618,10 @@ static struct spu *find_victim(struct sp - * higher priority contexts before lower priority - * ones, so this is safe until we introduce - * priority inheritance schemes. -+ * -+ * XXX if the highest priority context is locked, -+ * this can loop a long time. Might be better to -+ * look at another context or give up after X retries. - */ - if (!mutex_trylock(&victim->state_mutex)) { - victim = NULL; -@@ -589,10 +629,10 @@ static struct spu *find_victim(struct sp - } - - spu = victim->spu; -- if (!spu) { -+ if (!spu || victim->prio <= ctx->prio) { - /* - * This race can happen because we've dropped -- * the active list mutex. No a problem, just -+ * the active list mutex. Not a problem, just - * restart the search. - */ - mutex_unlock(&victim->state_mutex); -@@ -607,13 +647,10 @@ static struct spu *find_victim(struct sp - - victim->stats.invol_ctx_switch++; - spu->stats.invol_ctx_switch++; -+ spu_add_to_rq(victim); -+ - mutex_unlock(&victim->state_mutex); -- /* -- * We need to break out of the wait loop in spu_run -- * manually to ensure this context gets put on the -- * runqueue again ASAP. -- */ -- wake_up(&victim->stop_wq); -+ - return spu; - } - } -@@ -621,6 +658,50 @@ static struct spu *find_victim(struct sp - return NULL; - } - -+static void __spu_schedule(struct spu *spu, struct spu_context *ctx) -+{ -+ int node = spu->node; -+ int success = 0; -+ -+ spu_set_timeslice(ctx); -+ -+ mutex_lock(&cbe_spu_info[node].list_mutex); -+ if (spu->ctx == NULL) { -+ spu_bind_context(spu, ctx); -+ cbe_spu_info[node].nr_active++; -+ spu->alloc_state = SPU_USED; -+ success = 1; -+ } -+ mutex_unlock(&cbe_spu_info[node].list_mutex); -+ -+ if (success) -+ wake_up_all(&ctx->run_wq); -+ else -+ spu_add_to_rq(ctx); -+} -+ -+static void spu_schedule(struct spu *spu, struct spu_context *ctx) -+{ -+ /* not a candidate for interruptible because it's called either -+ from the scheduler thread or from spu_deactivate */ -+ mutex_lock(&ctx->state_mutex); -+ __spu_schedule(spu, ctx); -+ spu_release(ctx); -+} -+ -+static void spu_unschedule(struct spu *spu, struct spu_context *ctx) -+{ -+ int node = spu->node; -+ -+ mutex_lock(&cbe_spu_info[node].list_mutex); -+ cbe_spu_info[node].nr_active--; -+ spu->alloc_state = SPU_FREE; -+ spu_unbind_context(spu, ctx); -+ ctx->stats.invol_ctx_switch++; -+ spu->stats.invol_ctx_switch++; -+ mutex_unlock(&cbe_spu_info[node].list_mutex); -+} -+ - /** - * spu_activate - find a free spu for a context and execute it - * @ctx: spu context to schedule -@@ -632,39 +713,47 @@ static struct spu *find_victim(struct sp - */ - int spu_activate(struct spu_context *ctx, unsigned long flags) - { -- do { -- struct spu *spu; -+ struct spu *spu; - -- /* -- * If there are multiple threads waiting for a single context -- * only one actually binds the context while the others will -- * only be able to acquire the state_mutex once the context -- * already is in runnable state. -- */ -- if (ctx->spu) -- return 0; -+ /* -+ * If there are multiple threads waiting for a single context -+ * only one actually binds the context while the others will -+ * only be able to acquire the state_mutex once the context -+ * already is in runnable state. -+ */ -+ if (ctx->spu) -+ return 0; - -- spu = spu_get_idle(ctx); -- /* -- * If this is a realtime thread we try to get it running by -- * preempting a lower priority thread. -- */ -- if (!spu && rt_prio(ctx->prio)) -- spu = find_victim(ctx); -- if (spu) { -- int node = spu->node; -+spu_activate_top: -+ if (signal_pending(current)) -+ return -ERESTARTSYS; - -- mutex_lock(&cbe_spu_info[node].list_mutex); -- spu_bind_context(spu, ctx); -- cbe_spu_info[node].nr_active++; -- mutex_unlock(&cbe_spu_info[node].list_mutex); -- return 0; -- } -+ spu = spu_get_idle(ctx); -+ /* -+ * If this is a realtime thread we try to get it running by -+ * preempting a lower priority thread. -+ */ -+ if (!spu && rt_prio(ctx->prio)) -+ spu = find_victim(ctx); -+ if (spu) { -+ unsigned long runcntl; - -+ runcntl = ctx->ops->runcntl_read(ctx); -+ __spu_schedule(spu, ctx); -+ if (runcntl & SPU_RUNCNTL_RUNNABLE) -+ spuctx_switch_state(ctx, SPU_UTIL_USER); -+ -+ return 0; -+ } -+ -+ if (ctx->flags & SPU_CREATE_NOSCHED) { - spu_prio_wait(ctx); -- } while (!signal_pending(current)); -+ goto spu_activate_top; -+ } -+ -+ spu_add_to_rq(ctx); - -- return -ERESTARTSYS; -+ return 0; - } - - /** -@@ -706,21 +795,19 @@ static int __spu_deactivate(struct spu_c - if (spu) { - new = grab_runnable_context(max_prio, spu->node); - if (new || force) { -- int node = spu->node; -- -- mutex_lock(&cbe_spu_info[node].list_mutex); -- spu_unbind_context(spu, ctx); -- spu->alloc_state = SPU_FREE; -- cbe_spu_info[node].nr_active--; -- mutex_unlock(&cbe_spu_info[node].list_mutex); -- -- ctx->stats.vol_ctx_switch++; -- spu->stats.vol_ctx_switch++; -- -- if (new) -- wake_up(&new->stop_wq); -+ spu_unschedule(spu, ctx); -+ if (new) { -+ if (new->flags & SPU_CREATE_NOSCHED) -+ wake_up(&new->stop_wq); -+ else { -+ spu_release(ctx); -+ spu_schedule(spu, new); -+ /* this one can't easily be made -+ interruptible */ -+ mutex_lock(&ctx->state_mutex); -+ } -+ } - } -- - } - - return new != NULL; -@@ -757,43 +844,38 @@ void spu_yield(struct spu_context *ctx) - - static noinline void spusched_tick(struct spu_context *ctx) - { -+ struct spu_context *new = NULL; -+ struct spu *spu = NULL; -+ u32 status; -+ -+ if (spu_acquire(ctx)) -+ BUG(); /* a kernel thread never has signals pending */ -+ -+ if (ctx->state != SPU_STATE_RUNNABLE) -+ goto out; -+ if (spu_stopped(ctx, &status)) -+ goto out; - if (ctx->flags & SPU_CREATE_NOSCHED) -- return; -+ goto out; - if (ctx->policy == SCHED_FIFO) -- return; -+ goto out; - - if (--ctx->time_slice) -- return; -- -- /* -- * Unfortunately list_mutex ranks outside of state_mutex, so -- * we have to trylock here. If we fail give the context another -- * tick and try again. -- */ -- if (mutex_trylock(&ctx->state_mutex)) { -- struct spu *spu = ctx->spu; -- struct spu_context *new; -+ goto out; - -- new = grab_runnable_context(ctx->prio + 1, spu->node); -- if (new) { -- spu_unbind_context(spu, ctx); -- ctx->stats.invol_ctx_switch++; -- spu->stats.invol_ctx_switch++; -- spu->alloc_state = SPU_FREE; -- cbe_spu_info[spu->node].nr_active--; -- wake_up(&new->stop_wq); -- /* -- * We need to break out of the wait loop in -- * spu_run manually to ensure this context -- * gets put on the runqueue again ASAP. -- */ -- wake_up(&ctx->stop_wq); -- } -- spu_set_timeslice(ctx); -- mutex_unlock(&ctx->state_mutex); -+ spu = ctx->spu; -+ new = grab_runnable_context(ctx->prio + 1, spu->node); -+ if (new) { -+ spu_unschedule(spu, ctx); -+ spu_add_to_rq(ctx); - } else { - ctx->time_slice++; - } -+out: -+ spu_release(ctx); -+ -+ if (new) -+ spu_schedule(spu, new); - } - - /** -@@ -817,35 +899,31 @@ static unsigned long count_active_contex - } - - /** -- * spu_calc_load - given tick count, update the avenrun load estimates. -- * @tick: tick count -+ * spu_calc_load - update the avenrun load estimates. - * - * No locking against reading these values from userspace, as for - * the CPU loadavg code. - */ --static void spu_calc_load(unsigned long ticks) -+static void spu_calc_load(void) - { - unsigned long active_tasks; /* fixed-point */ -- static int count = LOAD_FREQ; - -- count -= ticks; -- -- if (unlikely(count < 0)) { -- active_tasks = count_active_contexts() * FIXED_1; -- do { -- CALC_LOAD(spu_avenrun[0], EXP_1, active_tasks); -- CALC_LOAD(spu_avenrun[1], EXP_5, active_tasks); -- CALC_LOAD(spu_avenrun[2], EXP_15, active_tasks); -- count += LOAD_FREQ; -- } while (count < 0); -- } -+ active_tasks = count_active_contexts() * FIXED_1; -+ CALC_LOAD(spu_avenrun[0], EXP_1, active_tasks); -+ CALC_LOAD(spu_avenrun[1], EXP_5, active_tasks); -+ CALC_LOAD(spu_avenrun[2], EXP_15, active_tasks); - } - - static void spusched_wake(unsigned long data) - { - mod_timer(&spusched_timer, jiffies + SPUSCHED_TICK); - wake_up_process(spusched_task); -- spu_calc_load(SPUSCHED_TICK); -+} -+ -+static void spuloadavg_wake(unsigned long data) -+{ -+ mod_timer(&spuloadavg_timer, jiffies + LOAD_FREQ); -+ spu_calc_load(); - } - - static int spusched_thread(void *unused) -@@ -857,17 +935,58 @@ static int spusched_thread(void *unused) - set_current_state(TASK_INTERRUPTIBLE); - schedule(); - for (node = 0; node < MAX_NUMNODES; node++) { -- mutex_lock(&cbe_spu_info[node].list_mutex); -- list_for_each_entry(spu, &cbe_spu_info[node].spus, cbe_list) -- if (spu->ctx) -- spusched_tick(spu->ctx); -- mutex_unlock(&cbe_spu_info[node].list_mutex); -+ struct mutex *mtx = &cbe_spu_info[node].list_mutex; -+ -+ mutex_lock(mtx); -+ list_for_each_entry(spu, &cbe_spu_info[node].spus, -+ cbe_list) { -+ struct spu_context *ctx = spu->ctx; -+ -+ if (ctx) { -+ mutex_unlock(mtx); -+ spusched_tick(ctx); -+ mutex_lock(mtx); -+ } -+ } -+ mutex_unlock(mtx); - } - } - - return 0; - } - -+void spuctx_switch_state(struct spu_context *ctx, -+ enum spu_utilization_state new_state) -+{ -+ unsigned long long curtime; -+ signed long long delta; -+ struct timespec ts; -+ struct spu *spu; -+ enum spu_utilization_state old_state; -+ -+ ktime_get_ts(&ts); -+ curtime = timespec_to_ns(&ts); -+ delta = curtime - ctx->stats.tstamp; -+ -+ WARN_ON(!mutex_is_locked(&ctx->state_mutex)); -+ WARN_ON(delta < 0); -+ -+ spu = ctx->spu; -+ old_state = ctx->stats.util_state; -+ ctx->stats.util_state = new_state; -+ ctx->stats.tstamp = curtime; -+ -+ /* -+ * Update the physical SPU utilization statistics. -+ */ -+ if (spu) { -+ ctx->stats.times[old_state] += delta; -+ spu->stats.times[old_state] += delta; -+ spu->stats.util_state = new_state; -+ spu->stats.tstamp = curtime; -+ } -+} -+ - #define LOAD_INT(x) ((x) >> FSHIFT) - #define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100) - -@@ -881,7 +1000,7 @@ static int show_spu_loadavg(struct seq_f - - /* - * Note that last_pid doesn't really make much sense for the -- * SPU loadavg (it even seems very odd on the CPU side..), -+ * SPU loadavg (it even seems very odd on the CPU side...), - * but we include it here to have a 100% compatible interface. - */ - seq_printf(s, "%d.%02d %d.%02d %d.%02d %ld/%d %d\n", -@@ -922,6 +1041,7 @@ int __init spu_sched_init(void) - spin_lock_init(&spu_prio->runq_lock); - - setup_timer(&spusched_timer, spusched_wake, 0); -+ setup_timer(&spuloadavg_timer, spuloadavg_wake, 0); - - spusched_task = kthread_run(spusched_thread, NULL, "spusched"); - if (IS_ERR(spusched_task)) { -@@ -929,6 +1049,8 @@ int __init spu_sched_init(void) - goto out_free_spu_prio; - } - -+ mod_timer(&spuloadavg_timer, 0); -+ - entry = create_proc_entry("spu_loadavg", 0, NULL); - if (!entry) - goto out_stop_kthread; -@@ -954,6 +1076,7 @@ void spu_sched_exit(void) - remove_proc_entry("spu_loadavg", NULL); - - del_timer_sync(&spusched_timer); -+ del_timer_sync(&spuloadavg_timer); - kthread_stop(spusched_task); - - for (node = 0; node < MAX_NUMNODES; node++) { ---- a/arch/powerpc/platforms/cell/spufs/spufs.h -+++ b/arch/powerpc/platforms/cell/spufs/spufs.h -@@ -71,6 +71,7 @@ struct spu_context { - wait_queue_head_t wbox_wq; - wait_queue_head_t stop_wq; - wait_queue_head_t mfc_wq; -+ wait_queue_head_t run_wq; - struct fasync_struct *ibox_fasync; - struct fasync_struct *wbox_fasync; - struct fasync_struct *mfc_fasync; -@@ -168,8 +169,10 @@ struct spu_context_ops { - void (*npc_write) (struct spu_context * ctx, u32 data); - u32(*status_read) (struct spu_context * ctx); - char*(*get_ls) (struct spu_context * ctx); -+ void (*privcntl_write) (struct spu_context *ctx, u64 data); - u32 (*runcntl_read) (struct spu_context * ctx); - void (*runcntl_write) (struct spu_context * ctx, u32 data); -+ void (*runcntl_stop) (struct spu_context * ctx); - void (*master_start) (struct spu_context * ctx); - void (*master_stop) (struct spu_context * ctx); - int (*set_mfc_query)(struct spu_context * ctx, u32 mask, u32 mode); -@@ -219,15 +222,16 @@ void spu_gang_add_ctx(struct spu_gang *g - - /* fault handling */ - int spufs_handle_class1(struct spu_context *ctx); -+int spufs_handle_class0(struct spu_context *ctx); - - /* affinity */ - struct spu *affinity_check(struct spu_context *ctx); - - /* context management */ - extern atomic_t nr_spu_contexts; --static inline void spu_acquire(struct spu_context *ctx) -+static inline int __must_check spu_acquire(struct spu_context *ctx) - { -- mutex_lock(&ctx->state_mutex); -+ return mutex_lock_interruptible(&ctx->state_mutex); - } - - static inline void spu_release(struct spu_context *ctx) -@@ -242,10 +246,11 @@ int put_spu_context(struct spu_context * - void spu_unmap_mappings(struct spu_context *ctx); - - void spu_forget(struct spu_context *ctx); --int spu_acquire_runnable(struct spu_context *ctx, unsigned long flags); --void spu_acquire_saved(struct spu_context *ctx); -+int __must_check spu_acquire_saved(struct spu_context *ctx); - void spu_release_saved(struct spu_context *ctx); - -+int spu_stopped(struct spu_context *ctx, u32 * stat); -+void spu_del_from_rq(struct spu_context *ctx); - int spu_activate(struct spu_context *ctx, unsigned long flags); - void spu_deactivate(struct spu_context *ctx); - void spu_yield(struct spu_context *ctx); -@@ -279,7 +284,9 @@ extern char *isolated_loader; - } \ - spu_release(ctx); \ - schedule(); \ -- spu_acquire(ctx); \ -+ __ret = spu_acquire(ctx); \ -+ if (__ret) \ -+ break; \ - } \ - finish_wait(&(wq), &__wait); \ - __ret; \ -@@ -306,41 +313,16 @@ struct spufs_coredump_reader { - extern struct spufs_coredump_reader spufs_coredump_read[]; - extern int spufs_coredump_num_notes; - --/* -- * This function is a little bit too large for an inline, but -- * as fault.c is built into the kernel we can't move it out of -- * line. -- */ --static inline void spuctx_switch_state(struct spu_context *ctx, -- enum spu_utilization_state new_state) --{ -- unsigned long long curtime; -- signed long long delta; -- struct timespec ts; -- struct spu *spu; -- enum spu_utilization_state old_state; -- -- ktime_get_ts(&ts); -- curtime = timespec_to_ns(&ts); -- delta = curtime - ctx->stats.tstamp; -- -- WARN_ON(!mutex_is_locked(&ctx->state_mutex)); -- WARN_ON(delta < 0); -- -- spu = ctx->spu; -- old_state = ctx->stats.util_state; -- ctx->stats.util_state = new_state; -- ctx->stats.tstamp = curtime; -- -- /* -- * Update the physical SPU utilization statistics. -- */ -- if (spu) { -- ctx->stats.times[old_state] += delta; -- spu->stats.times[old_state] += delta; -- spu->stats.util_state = new_state; -- spu->stats.tstamp = curtime; -- } --} -+extern int spu_init_csa(struct spu_state *csa); -+extern void spu_fini_csa(struct spu_state *csa); -+extern int spu_save(struct spu_state *prev, struct spu *spu); -+extern int spu_restore(struct spu_state *new, struct spu *spu); -+extern int spu_switch(struct spu_state *prev, struct spu_state *new, -+ struct spu *spu); -+extern int spu_alloc_lscsa(struct spu_state *csa); -+extern void spu_free_lscsa(struct spu_state *csa); -+ -+extern void spuctx_switch_state(struct spu_context *ctx, -+ enum spu_utilization_state new_state); - - #endif ---- a/arch/powerpc/platforms/cell/spufs/switch.c -+++ b/arch/powerpc/platforms/cell/spufs/switch.c -@@ -48,6 +48,8 @@ - #include - #include - -+#include "spufs.h" -+ - #include "spu_save_dump.h" - #include "spu_restore_dump.h" - -@@ -691,35 +693,9 @@ static inline void resume_mfc_queue(stru - out_be64(&priv2->mfc_control_RW, MFC_CNTL_RESUME_DMA_QUEUE); - } - --static inline void get_kernel_slb(u64 ea, u64 slb[2]) -+static inline void setup_mfc_slbs(struct spu_state *csa, struct spu *spu, -+ unsigned int *code, int code_size) - { -- u64 llp; -- -- if (REGION_ID(ea) == KERNEL_REGION_ID) -- llp = mmu_psize_defs[mmu_linear_psize].sllp; -- else -- llp = mmu_psize_defs[mmu_virtual_psize].sllp; -- slb[0] = (get_kernel_vsid(ea, MMU_SEGSIZE_256M) << SLB_VSID_SHIFT) | -- SLB_VSID_KERNEL | llp; -- slb[1] = (ea & ESID_MASK) | SLB_ESID_V; --} -- --static inline void load_mfc_slb(struct spu *spu, u64 slb[2], int slbe) --{ -- struct spu_priv2 __iomem *priv2 = spu->priv2; -- -- out_be64(&priv2->slb_index_W, slbe); -- eieio(); -- out_be64(&priv2->slb_vsid_RW, slb[0]); -- out_be64(&priv2->slb_esid_RW, slb[1]); -- eieio(); --} -- --static inline void setup_mfc_slbs(struct spu_state *csa, struct spu *spu) --{ -- u64 code_slb[2]; -- u64 lscsa_slb[2]; -- - /* Save, Step 47: - * Restore, Step 30. - * If MFC_SR1[R]=1, write 0 to SLB_Invalidate_All -@@ -735,11 +711,7 @@ static inline void setup_mfc_slbs(struct - * translation is desired by OS environment). - */ - spu_invalidate_slbs(spu); -- get_kernel_slb((unsigned long)&spu_save_code[0], code_slb); -- get_kernel_slb((unsigned long)csa->lscsa, lscsa_slb); -- load_mfc_slb(spu, code_slb, 0); -- if ((lscsa_slb[0] != code_slb[0]) || (lscsa_slb[1] != code_slb[1])) -- load_mfc_slb(spu, lscsa_slb, 1); -+ spu_setup_kernel_slbs(spu, csa->lscsa, code, code_size); - } - - static inline void set_switch_active(struct spu_state *csa, struct spu *spu) -@@ -768,9 +740,9 @@ static inline void enable_interrupts(str - * (translation) interrupts. - */ - spin_lock_irq(&spu->register_lock); -- spu_int_stat_clear(spu, 0, ~0ul); -- spu_int_stat_clear(spu, 1, ~0ul); -- spu_int_stat_clear(spu, 2, ~0ul); -+ spu_int_stat_clear(spu, 0, CLASS0_INTR_MASK); -+ spu_int_stat_clear(spu, 1, CLASS1_INTR_MASK); -+ spu_int_stat_clear(spu, 2, CLASS2_INTR_MASK); - spu_int_mask_set(spu, 0, 0ul); - spu_int_mask_set(spu, 1, class1_mask); - spu_int_mask_set(spu, 2, 0ul); -@@ -927,8 +899,8 @@ static inline void wait_tag_complete(str - POLL_WHILE_FALSE(in_be32(&prob->dma_tagstatus_R) & mask); - - local_irq_save(flags); -- spu_int_stat_clear(spu, 0, ~(0ul)); -- spu_int_stat_clear(spu, 2, ~(0ul)); -+ spu_int_stat_clear(spu, 0, CLASS0_INTR_MASK); -+ spu_int_stat_clear(spu, 2, CLASS2_INTR_MASK); - local_irq_restore(flags); - } - -@@ -946,8 +918,8 @@ static inline void wait_spu_stopped(stru - POLL_WHILE_TRUE(in_be32(&prob->spu_status_R) & SPU_STATUS_RUNNING); - - local_irq_save(flags); -- spu_int_stat_clear(spu, 0, ~(0ul)); -- spu_int_stat_clear(spu, 2, ~(0ul)); -+ spu_int_stat_clear(spu, 0, CLASS0_INTR_MASK); -+ spu_int_stat_clear(spu, 2, CLASS2_INTR_MASK); - local_irq_restore(flags); - } - -@@ -1423,9 +1395,9 @@ static inline void clear_interrupts(stru - spu_int_mask_set(spu, 0, 0ul); - spu_int_mask_set(spu, 1, 0ul); - spu_int_mask_set(spu, 2, 0ul); -- spu_int_stat_clear(spu, 0, ~0ul); -- spu_int_stat_clear(spu, 1, ~0ul); -- spu_int_stat_clear(spu, 2, ~0ul); -+ spu_int_stat_clear(spu, 0, CLASS0_INTR_MASK); -+ spu_int_stat_clear(spu, 1, CLASS1_INTR_MASK); -+ spu_int_stat_clear(spu, 2, CLASS2_INTR_MASK); - spin_unlock_irq(&spu->register_lock); - } - -@@ -1866,7 +1838,8 @@ static void save_lscsa(struct spu_state - */ - - resume_mfc_queue(prev, spu); /* Step 46. */ -- setup_mfc_slbs(prev, spu); /* Step 47. */ -+ /* Step 47. */ -+ setup_mfc_slbs(prev, spu, spu_save_code, sizeof(spu_save_code)); - set_switch_active(prev, spu); /* Step 48. */ - enable_interrupts(prev, spu); /* Step 49. */ - save_ls_16kb(prev, spu); /* Step 50. */ -@@ -1971,7 +1944,8 @@ static void restore_lscsa(struct spu_sta - setup_spu_status_part1(next, spu); /* Step 27. */ - setup_spu_status_part2(next, spu); /* Step 28. */ - restore_mfc_rag(next, spu); /* Step 29. */ -- setup_mfc_slbs(next, spu); /* Step 30. */ -+ /* Step 30. */ -+ setup_mfc_slbs(next, spu, spu_restore_code, sizeof(spu_restore_code)); - set_spu_npc(next, spu); /* Step 31. */ - set_signot1(next, spu); /* Step 32. */ - set_signot2(next, spu); /* Step 33. */ -@@ -2103,10 +2077,6 @@ int spu_save(struct spu_state *prev, str - int rc; - - acquire_spu_lock(spu); /* Step 1. */ -- prev->dar = spu->dar; -- prev->dsisr = spu->dsisr; -- spu->dar = 0; -- spu->dsisr = 0; - rc = __do_spu_save(prev, spu); /* Steps 2-53. */ - release_spu_lock(spu); - if (rc != 0 && rc != 2 && rc != 6) { -@@ -2133,9 +2103,6 @@ int spu_restore(struct spu_state *new, s - acquire_spu_lock(spu); - harvest(NULL, spu); - spu->slb_replace = 0; -- new->dar = 0; -- new->dsisr = 0; -- spu->class_0_pending = 0; - rc = __do_spu_restore(new, spu); - release_spu_lock(spu); - if (rc) { -@@ -2215,10 +2182,8 @@ int spu_init_csa(struct spu_state *csa) - - return 0; - } --EXPORT_SYMBOL_GPL(spu_init_csa); - - void spu_fini_csa(struct spu_state *csa) - { - spu_free_lscsa(csa); - } --EXPORT_SYMBOL_GPL(spu_fini_csa); ---- a/arch/powerpc/platforms/celleb/Kconfig -+++ b/arch/powerpc/platforms/celleb/Kconfig -@@ -2,6 +2,8 @@ config PPC_CELLEB - bool "Toshiba's Cell Reference Set 'Celleb' Architecture" - depends on PPC_MULTIPLATFORM && PPC64 - select PPC_CELL -+ select PPC_CELL_NATIVE -+ select PPC_RTAS - select PPC_INDIRECT_IO - select PPC_OF_PLATFORM_PCI - select HAS_TXX9_SERIAL ---- a/arch/powerpc/platforms/celleb/io-workarounds.c -+++ b/arch/powerpc/platforms/celleb/io-workarounds.c -@@ -22,6 +22,7 @@ - - #undef DEBUG - -+#include - #include - #include - -@@ -222,7 +223,7 @@ void __init celleb_pci_add_one(struct pc - void (*dummy_read)(struct pci_controller *)) - { - struct celleb_pci_bus *bus = &celleb_pci_busses[celleb_pci_count]; -- struct device_node *np = phb->arch_data; -+ struct device_node *np = phb->dn; - - if (celleb_pci_count >= MAX_CELLEB_PCI_BUS) { - printk(KERN_ERR "Too many pci bridges, workarounds" -@@ -256,13 +257,13 @@ int __init celleb_pci_workaround_init(vo - - celleb_dummy_page_va = kmalloc(PAGE_SIZE, GFP_KERNEL); - if (!celleb_dummy_page_va) { -- printk(KERN_ERR "Celleb: dummy read disabled." -+ printk(KERN_ERR "Celleb: dummy read disabled. " - "Alloc celleb_dummy_page_va failed\n"); - return 1; - } - - list_for_each_entry(phb, &hose_list, list_node) { -- node = phb->arch_data; -+ node = phb->dn; - match = of_match_node(celleb_pci_workaround_match, node); - - if (match) { ---- a/arch/powerpc/platforms/celleb/iommu.c -+++ b/arch/powerpc/platforms/celleb/iommu.c -@@ -22,8 +22,9 @@ - #include - #include - #include -+#include - --#include -+#include - - #include "beat_wrapper.h" - -@@ -51,6 +52,8 @@ static int __init find_dma_window(u64 *i - return 0; - } - -+static unsigned long celleb_dma_direct_offset; -+ - static void __init celleb_init_direct_mapping(void) - { - u64 lpar_addr, io_addr; -@@ -68,7 +71,18 @@ static void __init celleb_init_direct_ma - ioid, DMA_FLAGS); - } - -- dma_direct_offset = dma_base; -+ celleb_dma_direct_offset = dma_base; -+} -+ -+static void celleb_dma_dev_setup(struct device *dev) -+{ -+ dev->archdata.dma_ops = get_pci_dma_ops(); -+ dev->archdata.dma_data = (void *)celleb_dma_direct_offset; -+} -+ -+static void celleb_pci_dma_dev_setup(struct pci_dev *pdev) -+{ -+ celleb_dma_dev_setup(&pdev->dev); - } - - static int celleb_of_bus_notify(struct notifier_block *nb, -@@ -80,7 +94,7 @@ static int celleb_of_bus_notify(struct n - if (action != BUS_NOTIFY_ADD_DEVICE) - return 0; - -- dev->archdata.dma_ops = get_pci_dma_ops(); -+ celleb_dma_dev_setup(dev); - - return 0; - } -@@ -91,14 +105,12 @@ static struct notifier_block celleb_of_b - - static int __init celleb_init_iommu(void) - { -- if (!machine_is(celleb)) -- return -ENODEV; -- - celleb_init_direct_mapping(); - set_pci_dma_ops(&dma_direct_ops); -+ ppc_md.pci_dma_dev_setup = celleb_pci_dma_dev_setup; - bus_register_notifier(&of_platform_bus_type, &celleb_of_bus_notifier); - - return 0; - } - --arch_initcall(celleb_init_iommu); -+machine_arch_initcall(celleb_beat, celleb_init_iommu); ---- a/arch/powerpc/platforms/celleb/pci.c -+++ b/arch/powerpc/platforms/celleb/pci.c -@@ -31,6 +31,7 @@ - #include - #include - #include -+#include - #include - - #include -@@ -138,8 +139,6 @@ static void celleb_config_read_fake(unsi - *val = celleb_fake_config_readl(p); - break; - } -- -- return; - } - - static void celleb_config_write_fake(unsigned char *config, int where, -@@ -158,7 +157,6 @@ static void celleb_config_write_fake(uns - celleb_fake_config_writel(val, p); - break; - } -- return; - } - - static int celleb_fake_pci_read_config(struct pci_bus *bus, -@@ -351,6 +349,10 @@ static int __init celleb_setup_fake_pci_ - wi1 = of_get_property(node, "vendor-id", NULL); - wi2 = of_get_property(node, "class-code", NULL); - wi3 = of_get_property(node, "revision-id", NULL); -+ if (!wi0 || !wi1 || !wi2 || !wi3) { -+ printk(KERN_ERR "PCI: Missing device tree properties.\n"); -+ goto error; -+ } - - celleb_config_write_fake(*config, PCI_DEVICE_ID, 2, wi0[0] & 0xffff); - celleb_config_write_fake(*config, PCI_VENDOR_ID, 2, wi1[0] & 0xffff); -@@ -372,6 +374,10 @@ static int __init celleb_setup_fake_pci_ - celleb_setup_pci_base_addrs(hose, devno, fn, num_base_addr); - - li = of_get_property(node, "interrupts", &rlen); -+ if (!li) { -+ printk(KERN_ERR "PCI: interrupts not found.\n"); -+ goto error; -+ } - val = li[0]; - celleb_config_write_fake(*config, PCI_INTERRUPT_PIN, 1, 1); - celleb_config_write_fake(*config, PCI_INTERRUPT_LINE, 1, val); -@@ -475,7 +481,7 @@ static struct of_device_id celleb_phb_ma - - int __init celleb_setup_phb(struct pci_controller *phb) - { -- struct device_node *dev = phb->arch_data; -+ struct device_node *dev = phb->dn; - const struct of_device_id *match; - int (*setup_func)(struct device_node *, struct pci_controller *); - ---- a/arch/powerpc/platforms/celleb/scc_epci.c -+++ b/arch/powerpc/platforms/celleb/scc_epci.c -@@ -95,7 +95,7 @@ void __init epci_workaround_init(struct - private->dummy_page_da = dma_map_single(hose->parent, - celleb_dummy_page_va, PAGE_SIZE, DMA_FROM_DEVICE); - if (private->dummy_page_da == DMA_ERROR_CODE) { -- printk(KERN_ERR "EPCI: dummy read disabled." -+ printk(KERN_ERR "EPCI: dummy read disabled. " - "Map dummy page failed.\n"); - return; - } ---- a/arch/powerpc/platforms/celleb/scc_uhc.c -+++ b/arch/powerpc/platforms/celleb/scc_uhc.c -@@ -47,7 +47,8 @@ static void enable_scc_uhc(struct pci_de - u32 val = 0; - int i; - -- if (!machine_is(celleb)) -+ if (!machine_is(celleb_beat) && -+ !machine_is(celleb_native)) - return; - - uhc_base = ioremap(pci_resource_start(dev, 0), ---- a/arch/powerpc/platforms/celleb/setup.c -+++ b/arch/powerpc/platforms/celleb/setup.c -@@ -40,6 +40,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -52,12 +53,16 @@ - #include - #include - #include --#include -+#include -+#include - - #include "interrupt.h" - #include "beat_wrapper.h" - #include "beat.h" - #include "pci.h" -+#include "../cell/interrupt.h" -+#include "../cell/pervasive.h" -+#include "../cell/ras.h" - - static char celleb_machine_type[128] = "Celleb"; - -@@ -88,61 +93,122 @@ static void celleb_progress(char *s, uns - printk("*** %04x : %s\n", hex, s ? s : ""); - } - --static void __init celleb_setup_arch(void) -+static void __init celleb_setup_arch_common(void) -+{ -+ /* init to some ~sane value until calibrate_delay() runs */ -+ loops_per_jiffy = 50000000; -+ -+#ifdef CONFIG_DUMMY_CONSOLE -+ conswitchp = &dummy_con; -+#endif -+} -+ -+static struct of_device_id celleb_bus_ids[] __initdata = { -+ { .type = "scc", }, -+ { .type = "ioif", }, /* old style */ -+ {}, -+}; -+ -+static int __init celleb_publish_devices(void) -+{ -+ /* Publish OF platform devices for southbridge IOs */ -+ of_platform_bus_probe(NULL, celleb_bus_ids, NULL); -+ -+ celleb_pci_workaround_init(); -+ -+ return 0; -+} -+machine_device_initcall(celleb_beat, celleb_publish_devices); -+machine_device_initcall(celleb_native, celleb_publish_devices); -+ -+ -+/* -+ * functions for Celleb-Beat -+ */ -+static void __init celleb_setup_arch_beat(void) - { - #ifdef CONFIG_SPU_BASE -- spu_priv1_ops = &spu_priv1_beat_ops; -- spu_management_ops = &spu_management_of_ops; -+ spu_priv1_ops = &spu_priv1_beat_ops; -+ spu_management_ops = &spu_management_of_ops; - #endif - - #ifdef CONFIG_SMP - smp_init_celleb(); - #endif - -- /* init to some ~sane value until calibrate_delay() runs */ -- loops_per_jiffy = 50000000; -- --#ifdef CONFIG_DUMMY_CONSOLE -- conswitchp = &dummy_con; --#endif -+ celleb_setup_arch_common(); - } - --static int __init celleb_probe(void) -+static int __init celleb_probe_beat(void) - { - unsigned long root = of_get_flat_dt_root(); - - if (!of_flat_dt_is_compatible(root, "Beat")) - return 0; - -- powerpc_firmware_features |= FW_FEATURE_CELLEB_POSSIBLE; -+ powerpc_firmware_features |= FW_FEATURE_CELLEB_ALWAYS -+ | FW_FEATURE_BEAT | FW_FEATURE_LPAR; - hpte_init_beat_v3(); -+ - return 1; - } - --static struct of_device_id celleb_bus_ids[] __initdata = { -- { .type = "scc", }, -- { .type = "ioif", }, /* old style */ -- {}, --}; - --static int __init celleb_publish_devices(void) -+/* -+ * functions for Celleb-native -+ */ -+static void __init celleb_init_IRQ_native(void) - { -- if (!machine_is(celleb)) -- return 0; -+ iic_init_IRQ(); -+ spider_init_IRQ(); -+} - -- /* Publish OF platform devices for southbridge IOs */ -- of_platform_bus_probe(NULL, celleb_bus_ids, NULL); -+static void __init celleb_setup_arch_native(void) -+{ -+#ifdef CONFIG_SPU_BASE -+ spu_priv1_ops = &spu_priv1_mmio_ops; -+ spu_management_ops = &spu_management_of_ops; -+#endif - -- celleb_pci_workaround_init(); -+ cbe_regs_init(); - -- return 0; -+#ifdef CONFIG_CBE_RAS -+ cbe_ras_init(); -+#endif -+ -+#ifdef CONFIG_SMP -+ smp_init_cell(); -+#endif -+ -+ cbe_pervasive_init(); -+ -+ /* XXX: nvram initialization should be added */ -+ -+ celleb_setup_arch_common(); -+} -+ -+static int __init celleb_probe_native(void) -+{ -+ unsigned long root = of_get_flat_dt_root(); -+ -+ if (of_flat_dt_is_compatible(root, "Beat") || -+ !of_flat_dt_is_compatible(root, "TOSHIBA,Celleb")) -+ return 0; -+ -+ powerpc_firmware_features |= FW_FEATURE_CELLEB_ALWAYS; -+ hpte_init_native(); -+ -+ return 1; - } --device_initcall(celleb_publish_devices); - --define_machine(celleb) { -- .name = "Cell Reference Set", -- .probe = celleb_probe, -- .setup_arch = celleb_setup_arch, -+ -+/* -+ * machine definitions -+ */ -+define_machine(celleb_beat) { -+ .name = "Cell Reference Set (Beat)", -+ .probe = celleb_probe_beat, -+ .setup_arch = celleb_setup_arch_beat, - .show_cpuinfo = celleb_show_cpuinfo, - .restart = beat_restart, - .power_off = beat_power_off, -@@ -167,3 +233,26 @@ define_machine(celleb) { - .machine_crash_shutdown = default_machine_crash_shutdown, - #endif - }; -+ -+define_machine(celleb_native) { -+ .name = "Cell Reference Set (native)", -+ .probe = celleb_probe_native, -+ .setup_arch = celleb_setup_arch_native, -+ .show_cpuinfo = celleb_show_cpuinfo, -+ .restart = rtas_restart, -+ .power_off = rtas_power_off, -+ .halt = rtas_halt, -+ .get_boot_time = rtas_get_boot_time, -+ .get_rtc_time = rtas_get_rtc_time, -+ .set_rtc_time = rtas_set_rtc_time, -+ .calibrate_decr = generic_calibrate_decr, -+ .progress = celleb_progress, -+ .pci_probe_mode = celleb_pci_probe_mode, -+ .pci_setup_phb = celleb_setup_phb, -+ .init_IRQ = celleb_init_IRQ_native, -+#ifdef CONFIG_KEXEC -+ .machine_kexec = default_machine_kexec, -+ .machine_kexec_prepare = default_machine_kexec_prepare, -+ .machine_crash_shutdown = default_machine_crash_shutdown, -+#endif -+}; ---- a/arch/powerpc/platforms/chrp/pci.c -+++ b/arch/powerpc/platforms/chrp/pci.c -@@ -198,7 +198,7 @@ static void __init setup_peg2(struct pci - printk ("RTAS supporting Pegasos OF not found, please upgrade" - " your firmware\n"); - } -- pci_assign_all_buses = 1; -+ ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS; - /* keep the reference to the root node */ - } - ---- a/arch/powerpc/platforms/chrp/setup.c -+++ b/arch/powerpc/platforms/chrp/setup.c -@@ -115,7 +115,7 @@ void chrp_show_cpuinfo(struct seq_file * - seq_printf(m, "machine\t\t: CHRP %s\n", model); - - /* longtrail (goldengate) stuff */ -- if (!strncmp(model, "IBM,LongTrail", 13)) { -+ if (model && !strncmp(model, "IBM,LongTrail", 13)) { - /* VLSI VAS96011/12 `Golden Gate 2' */ - /* Memory banks */ - sdramen = (in_le32(gg2_pci_config_base + GG2_PCI_DRAM_CTRL) -@@ -203,15 +203,20 @@ static void __init sio_fixup_irq(const c - static void __init sio_init(void) - { - struct device_node *root; -+ const char *model; - -- if ((root = of_find_node_by_path("/")) && -- !strncmp(of_get_property(root, "model", NULL), -- "IBM,LongTrail", 13)) { -+ root = of_find_node_by_path("/"); -+ if (!root) -+ return; -+ -+ model = of_get_property(root, "model", NULL); -+ if (model && !strncmp(model, "IBM,LongTrail", 13)) { - /* logical device 0 (KBC/Keyboard) */ - sio_fixup_irq("keyboard", 0, 1, 2); - /* select logical device 1 (KBC/Mouse) */ - sio_fixup_irq("mouse", 1, 12, 2); - } -+ - of_node_put(root); - } - -@@ -251,6 +256,57 @@ static void briq_restart(char *cmd) - for(;;); - } - -+/* -+ * Per default, input/output-device points to the keyboard/screen -+ * If no card is installed, the built-in serial port is used as a fallback. -+ * But unfortunately, the firmware does not connect /chosen/{stdin,stdout} -+ * the the built-in serial node. Instead, a /failsafe node is created. -+ */ -+static void chrp_init_early(void) -+{ -+ struct device_node *node; -+ const char *property; -+ -+ if (strstr(cmd_line, "console=")) -+ return; -+ /* find the boot console from /chosen/stdout */ -+ if (!of_chosen) -+ return; -+ node = of_find_node_by_path("/"); -+ if (!node) -+ return; -+ property = of_get_property(node, "model", NULL); -+ if (!property) -+ goto out_put; -+ if (strcmp(property, "Pegasos2")) -+ goto out_put; -+ /* this is a Pegasos2 */ -+ property = of_get_property(of_chosen, "linux,stdout-path", NULL); -+ if (!property) -+ goto out_put; -+ of_node_put(node); -+ node = of_find_node_by_path(property); -+ if (!node) -+ return; -+ property = of_get_property(node, "device_type", NULL); -+ if (!property) -+ goto out_put; -+ if (strcmp(property, "serial")) -+ goto out_put; -+ /* -+ * The 9pin connector is either /failsafe -+ * or /pci@80000000/isa@C/serial@i2F8 -+ * The optional graphics card has also type 'serial' in VGA mode. -+ */ -+ property = of_get_property(node, "name", NULL); -+ if (!property) -+ goto out_put; -+ if (!strcmp(property, "failsafe") || !strcmp(property, "serial")) -+ add_preferred_console("ttyS", 0, NULL); -+out_put: -+ of_node_put(node); -+} -+ - void __init chrp_setup_arch(void) - { - struct device_node *root = of_find_node_by_path("/"); -@@ -594,6 +650,7 @@ define_machine(chrp) { - .probe = chrp_probe, - .setup_arch = chrp_setup_arch, - .init = chrp_init2, -+ .init_early = chrp_init_early, - .show_cpuinfo = chrp_show_cpuinfo, - .init_IRQ = chrp_init_IRQ, - .restart = rtas_restart, ---- a/arch/powerpc/platforms/embedded6xx/Kconfig -+++ b/arch/powerpc/platforms/embedded6xx/Kconfig -@@ -9,6 +9,8 @@ config LINKSTATION - select FSL_SOC - select PPC_UDBG_16550 if SERIAL_8250 - select DEFAULT_UIMAGE -+ select MPC10X_OPENPIC -+ select MPC10X_BRIDGE - help - Select LINKSTATION if configuring for one of PPC- (MPC8241) - based NAS systems from Buffalo Technology. So far only -@@ -16,6 +18,19 @@ config LINKSTATION - Linkstation-I HD-HLAN and HD-HGLAN versions, and PPC-based - Terastation systems should be supported too. - -+config STORCENTER -+ bool "IOMEGA StorCenter" -+ depends on EMBEDDED6xx -+ select MPIC -+ select FSL_SOC -+ select PPC_UDBG_16550 if SERIAL_8250 -+ select WANT_DEVICE_TREE -+ select MPC10X_OPENPIC -+ select MPC10X_BRIDGE -+ help -+ Select STORCENTER if configuring for the iomega StorCenter -+ with an 8241 CPU in it. -+ - config MPC7448HPC2 - bool "Freescale MPC7448HPC2(Taiga)" - depends on EMBEDDED6xx -@@ -23,6 +38,7 @@ config MPC7448HPC2 - select DEFAULT_UIMAGE - select PPC_UDBG_16550 - select WANT_DEVICE_TREE -+ select TSI108_BRIDGE - help - Select MPC7448HPC2 if configuring for Freescale MPC7448HPC2 (Taiga) - platform -@@ -33,6 +49,7 @@ config PPC_HOLLY - select TSI108_BRIDGE - select PPC_UDBG_16550 - select WANT_DEVICE_TREE -+ select TSI108_BRIDGE - help - Select PPC_HOLLY if configuring for an IBM 750GX/CL Eval - Board with TSI108/9 bridge (Hickory/Holly) -@@ -48,17 +65,13 @@ config PPC_PRPMC2800 - - config TSI108_BRIDGE - bool -- depends on MPC7448HPC2 || PPC_HOLLY - select PCI - select MPIC - select MPIC_WEIRD -- default y - - config MPC10X_BRIDGE - bool -- depends on LINKSTATION - select PPC_INDIRECT_PCI -- default y - - config MV64X60 - bool -@@ -67,8 +80,6 @@ config MV64X60 - - config MPC10X_OPENPIC - bool -- depends on LINKSTATION -- default y - - config MPC10X_STORE_GATHERING - bool "Enable MPC10x store gathering" ---- a/arch/powerpc/platforms/embedded6xx/Makefile -+++ b/arch/powerpc/platforms/embedded6xx/Makefile -@@ -3,5 +3,6 @@ - # - obj-$(CONFIG_MPC7448HPC2) += mpc7448_hpc2.o - obj-$(CONFIG_LINKSTATION) += linkstation.o ls_uart.o -+obj-$(CONFIG_STORCENTER) += storcenter.o - obj-$(CONFIG_PPC_HOLLY) += holly.o - obj-$(CONFIG_PPC_PRPMC2800) += prpmc2800.o ---- a/arch/powerpc/platforms/embedded6xx/holly.c -+++ b/arch/powerpc/platforms/embedded6xx/holly.c -@@ -20,12 +20,12 @@ - #include - #include - #include --#include - #include - #include - #include - #include - #include -+#include - - #include - #include -@@ -39,7 +39,6 @@ - #include - #include - #include --#include - - #undef DEBUG - ---- a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c -+++ b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c -@@ -53,8 +53,6 @@ - - #define MPC7448HPC2_PCI_CFG_PHYS 0xfb000000 - --extern void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val); -- - int mpc7448_hpc2_exclude_device(struct pci_controller *hose, - u_char bus, u_char devfn) - { ---- /dev/null -+++ b/arch/powerpc/platforms/embedded6xx/storcenter.c -@@ -0,0 +1,192 @@ -+/* -+ * Board setup routines for the storcenter -+ * -+ * Copyright 2007 (C) Oyvind Repvik (nail@nslu2-linux.org) -+ * Copyright 2007 Andy Wilcox, Jon Loeliger -+ * -+ * Based on linkstation.c by G. Liakhovetski -+ * -+ * 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 "mpc10x.h" -+ -+ -+#ifdef CONFIG_MTD_PHYSMAP -+static struct mtd_partition storcenter_physmap_partitions[] = { -+ { -+ .name = "kernel", -+ .offset = 0x000000, -+ .size = 0x170000, -+ }, -+ { -+ .name = "rootfs", -+ .offset = 0x170000, -+ .size = 0x590000, -+ }, -+ { -+ .name = "uboot", -+ .offset = 0x700000, -+ .size = 0x040000, -+ }, -+ { -+ .name = "config", -+ .offset = 0x740000, -+ .size = 0x0c0000, -+ }, -+}; -+#endif -+ -+ -+static __initdata struct of_device_id storcenter_of_bus[] = { -+ { .name = "soc", }, -+ {}, -+}; -+ -+static int __init storcenter_device_probe(void) -+{ -+ of_platform_bus_probe(NULL, storcenter_of_bus, NULL); -+ return 0; -+} -+machine_device_initcall(storcenter, storcenter_device_probe); -+ -+ -+static int __init storcenter_add_bridge(struct device_node *dev) -+{ -+#ifdef CONFIG_PCI -+ int len; -+ struct pci_controller *hose; -+ const int *bus_range; -+ -+ printk("Adding PCI host bridge %s\n", dev->full_name); -+ -+ hose = pcibios_alloc_controller(dev); -+ if (hose == NULL) -+ return -ENOMEM; -+ -+ bus_range = of_get_property(dev, "bus-range", &len); -+ hose->first_busno = bus_range ? bus_range[0] : 0; -+ hose->last_busno = bus_range ? bus_range[1] : 0xff; -+ -+ setup_indirect_pci(hose, MPC10X_MAPB_CNFG_ADDR, MPC10X_MAPB_CNFG_DATA, 0); -+ -+ /* Interpret the "ranges" property */ -+ /* This also maps the I/O region and sets isa_io/mem_base */ -+ pci_process_bridge_OF_ranges(hose, dev, 1); -+#endif -+ -+ return 0; -+} -+ -+static void __init storcenter_setup_arch(void) -+{ -+ struct device_node *np; -+ -+#ifdef CONFIG_MTD_PHYSMAP -+ physmap_set_partitions(storcenter_physmap_partitions, -+ ARRAY_SIZE(storcenter_physmap_partitions)); -+#endif -+ -+ /* Lookup PCI host bridges */ -+ for_each_compatible_node(np, "pci", "mpc10x-pci") -+ storcenter_add_bridge(np); -+ -+ printk(KERN_INFO "IOMEGA StorCenter\n"); -+} -+ -+/* -+ * Interrupt setup and service. Interrrupts on the turbostation come -+ * from the four PCI slots plus onboard 8241 devices: I2C, DUART. -+ */ -+static void __init storcenter_init_IRQ(void) -+{ -+ struct mpic *mpic; -+ struct device_node *dnp; -+ const void *prop; -+ int size; -+ phys_addr_t paddr; -+ -+ dnp = of_find_node_by_type(NULL, "open-pic"); -+ if (dnp == NULL) -+ return; -+ -+ prop = of_get_property(dnp, "reg", &size); -+ if (prop == NULL) { -+ of_node_put(dnp); -+ return; -+ } -+ -+ paddr = (phys_addr_t)of_translate_address(dnp, prop); -+ mpic = mpic_alloc(dnp, paddr, MPIC_PRIMARY | MPIC_WANTS_RESET, -+ 4, 32, " EPIC "); -+ -+ of_node_put(dnp); -+ -+ BUG_ON(mpic == NULL); -+ -+ /* PCI IRQs */ -+ /* -+ * 2.6.12 patch: -+ * openpic_set_sources(0, 5, OpenPIC_Addr + 0x10200); -+ * openpic_set_sources(5, 2, OpenPIC_Addr + 0x11120); -+ * first_irq, num_irqs, __iomem first_ISR -+ * o_ss: i, src: 0, fdf50200 -+ * o_ss: i, src: 1, fdf50220 -+ * o_ss: i, src: 2, fdf50240 -+ * o_ss: i, src: 3, fdf50260 -+ * o_ss: i, src: 4, fdf50280 -+ * o_ss: i, src: 5, fdf51120 -+ * o_ss: i, src: 6, fdf51140 -+ */ -+ mpic_assign_isu(mpic, 0, paddr + 0x10200); -+ mpic_assign_isu(mpic, 1, paddr + 0x10220); -+ mpic_assign_isu(mpic, 2, paddr + 0x10240); -+ mpic_assign_isu(mpic, 3, paddr + 0x10260); -+ mpic_assign_isu(mpic, 4, paddr + 0x10280); -+ mpic_assign_isu(mpic, 5, paddr + 0x11120); -+ mpic_assign_isu(mpic, 6, paddr + 0x11140); -+ -+ mpic_init(mpic); -+} -+ -+static void storcenter_restart(char *cmd) -+{ -+ local_irq_disable(); -+ -+ /* Set exception prefix high - to the firmware */ -+ _nmask_and_or_msr(0, MSR_IP); -+ -+ /* Wait for reset to happen */ -+ for (;;) ; -+} -+ -+static int __init storcenter_probe(void) -+{ -+ unsigned long root = of_get_flat_dt_root(); -+ -+ return of_flat_dt_is_compatible(root, "storcenter"); -+} -+ -+define_machine(storcenter){ -+ .name = "IOMEGA StorCenter", -+ .probe = storcenter_probe, -+ .setup_arch = storcenter_setup_arch, -+ .init_IRQ = storcenter_init_IRQ, -+ .get_irq = mpic_get_irq, -+ .restart = storcenter_restart, -+ .calibrate_decr = generic_calibrate_decr, -+}; ---- a/arch/powerpc/platforms/iseries/Makefile -+++ b/arch/powerpc/platforms/iseries/Makefile -@@ -5,7 +5,7 @@ extra-y += dt.o - obj-y += exception.o - obj-y += hvlog.o hvlpconfig.o lpardata.o setup.o dt_mod.o mf.o lpevents.o \ - hvcall.o proc.o htab.o iommu.o misc.o irq.o --obj-$(CONFIG_PCI) += pci.o vpdinfo.o -+obj-$(CONFIG_PCI) += pci.o - obj-$(CONFIG_SMP) += smp.o - obj-$(CONFIG_VIOPATH) += viopath.o vio.o - obj-$(CONFIG_MODULES) += ksyms.o ---- a/arch/powerpc/platforms/iseries/iommu.c -+++ b/arch/powerpc/platforms/iseries/iommu.c -@@ -163,8 +163,10 @@ static struct iommu_table *iommu_table_f - (it->it_type == TCE_PCI) && - (it->it_offset == tbl->it_offset) && - (it->it_index == tbl->it_index) && -- (it->it_size == tbl->it_size)) -+ (it->it_size == tbl->it_size)) { -+ of_node_put(node); - return it; -+ } - } - return NULL; - } ---- a/arch/powerpc/platforms/iseries/lpevents.c -+++ b/arch/powerpc/platforms/iseries/lpevents.c -@@ -239,7 +239,7 @@ int HvLpEvent_unregisterHandler(HvLpEven - * other CPUs, and that the deleted handler isn't - * still running on another CPU when we return. - */ -- synchronize_rcu(); -+ synchronize_sched(); - return 0; - } - } ---- a/arch/powerpc/platforms/iseries/pci.c -+++ b/arch/powerpc/platforms/iseries/pci.c -@@ -1,5 +1,6 @@ - /* - * Copyright (C) 2001 Allan Trautman, IBM Corporation -+ * Copyright (C) 2005,2007 Stephen Rothwell, IBM Corp - * - * iSeries specific routines for PCI. - * -@@ -19,13 +20,18 @@ - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -+ -+#undef DEBUG -+ - #include - #include - #include - #include - #include - #include -+#include - -+#include - #include - #include - #include -@@ -35,6 +41,7 @@ - #include - #include - -+#include - #include - #include - #include -@@ -45,15 +52,8 @@ - #include "pci.h" - #include "call_pci.h" - --/* -- * Forward declares of prototypes. -- */ --static struct device_node *find_Device_Node(int bus, int devfn); -- --static int Pci_Retry_Max = 3; /* Only retry 3 times */ --static int Pci_Error_Flag = 1; /* Set Retry Error on. */ -- --static struct pci_ops iSeries_pci_ops; -+#define PCI_RETRY_MAX 3 -+static int limit_pci_retries = 1; /* Set Retry Error on. */ - - /* - * Table defines -@@ -62,6 +62,7 @@ static struct pci_ops iSeries_pci_ops; - #define IOMM_TABLE_MAX_ENTRIES 1024 - #define IOMM_TABLE_ENTRY_SIZE 0x0000000000400000UL - #define BASE_IO_MEMORY 0xE000000000000000UL -+#define END_IO_MEMORY 0xEFFFFFFFFFFFFFFFUL - - static unsigned long max_io_memory = BASE_IO_MEMORY; - static long current_iomm_table_entry; -@@ -70,12 +71,237 @@ static long current_iomm_table_entry; - * Lookup Tables. - */ - static struct device_node *iomm_table[IOMM_TABLE_MAX_ENTRIES]; --static u8 iobar_table[IOMM_TABLE_MAX_ENTRIES]; -+static u64 ds_addr_table[IOMM_TABLE_MAX_ENTRIES]; - --static const char pci_io_text[] = "iSeries PCI I/O"; - static DEFINE_SPINLOCK(iomm_table_lock); - - /* -+ * Generate a Direct Select Address for the Hypervisor -+ */ -+static inline u64 iseries_ds_addr(struct device_node *node) -+{ -+ struct pci_dn *pdn = PCI_DN(node); -+ const u32 *sbp = of_get_property(node, "linux,subbus", NULL); -+ -+ return ((u64)pdn->busno << 48) + ((u64)(sbp ? *sbp : 0) << 40) -+ + ((u64)0x10 << 32); -+} -+ -+/* -+ * Size of Bus VPD data -+ */ -+#define BUS_VPDSIZE 1024 -+ -+/* -+ * Bus Vpd Tags -+ */ -+#define VPD_END_OF_AREA 0x79 -+#define VPD_ID_STRING 0x82 -+#define VPD_VENDOR_AREA 0x84 -+ -+/* -+ * Mfg Area Tags -+ */ -+#define VPD_FRU_FRAME_ID 0x4649 /* "FI" */ -+#define VPD_SLOT_MAP_FORMAT 0x4D46 /* "MF" */ -+#define VPD_SLOT_MAP 0x534D /* "SM" */ -+ -+/* -+ * Structures of the areas -+ */ -+struct mfg_vpd_area { -+ u16 tag; -+ u8 length; -+ u8 data1; -+ u8 data2; -+}; -+#define MFG_ENTRY_SIZE 3 -+ -+struct slot_map { -+ u8 agent; -+ u8 secondary_agent; -+ u8 phb; -+ char card_location[3]; -+ char parms[8]; -+ char reserved[2]; -+}; -+#define SLOT_ENTRY_SIZE 16 -+ -+/* -+ * Parse the Slot Area -+ */ -+static void __init iseries_parse_slot_area(struct slot_map *map, int len, -+ HvAgentId agent, u8 *phb, char card[4]) -+{ -+ /* -+ * Parse Slot label until we find the one requested -+ */ -+ while (len > 0) { -+ if (map->agent == agent) { -+ /* -+ * If Phb wasn't found, grab the entry first one found. -+ */ -+ if (*phb == 0xff) -+ *phb = map->phb; -+ /* Found it, extract the data. */ -+ if (map->phb == *phb) { -+ memcpy(card, &map->card_location, 3); -+ card[3] = 0; -+ break; -+ } -+ } -+ /* Point to the next Slot */ -+ map = (struct slot_map *)((char *)map + SLOT_ENTRY_SIZE); -+ len -= SLOT_ENTRY_SIZE; -+ } -+} -+ -+/* -+ * Parse the Mfg Area -+ */ -+static void __init iseries_parse_mfg_area(struct mfg_vpd_area *area, int len, -+ HvAgentId agent, u8 *phb, u8 *frame, char card[4]) -+{ -+ u16 slot_map_fmt = 0; -+ -+ /* Parse Mfg Data */ -+ while (len > 0) { -+ int mfg_tag_len = area->length; -+ /* Frame ID (FI 4649020310 ) */ -+ if (area->tag == VPD_FRU_FRAME_ID) -+ *frame = area->data1; -+ /* Slot Map Format (MF 4D46020004 ) */ -+ else if (area->tag == VPD_SLOT_MAP_FORMAT) -+ slot_map_fmt = (area->data1 * 256) -+ + area->data2; -+ /* Slot Map (SM 534D90 */ -+ else if (area->tag == VPD_SLOT_MAP) { -+ struct slot_map *slot_map; -+ -+ if (slot_map_fmt == 0x1004) -+ slot_map = (struct slot_map *)((char *)area -+ + MFG_ENTRY_SIZE + 1); -+ else -+ slot_map = (struct slot_map *)((char *)area -+ + MFG_ENTRY_SIZE); -+ iseries_parse_slot_area(slot_map, mfg_tag_len, -+ agent, phb, card); -+ } -+ /* -+ * Point to the next Mfg Area -+ * Use defined size, sizeof give wrong answer -+ */ -+ area = (struct mfg_vpd_area *)((char *)area + mfg_tag_len -+ + MFG_ENTRY_SIZE); -+ len -= (mfg_tag_len + MFG_ENTRY_SIZE); -+ } -+} -+ -+/* -+ * Look for "BUS".. Data is not Null terminated. -+ * PHBID of 0xFF indicates PHB was not found in VPD Data. -+ */ -+static u8 __init iseries_parse_phbid(u8 *area, int len) -+{ -+ while (len > 0) { -+ if ((*area == 'B') && (*(area + 1) == 'U') -+ && (*(area + 2) == 'S')) { -+ area += 3; -+ while (*area == ' ') -+ area++; -+ return *area & 0x0F; -+ } -+ area++; -+ len--; -+ } -+ return 0xff; -+} -+ -+/* -+ * Parse out the VPD Areas -+ */ -+static void __init iseries_parse_vpd(u8 *data, int data_len, -+ HvAgentId agent, u8 *frame, char card[4]) -+{ -+ u8 phb = 0xff; -+ -+ while (data_len > 0) { -+ int len; -+ u8 tag = *data; -+ -+ if (tag == VPD_END_OF_AREA) -+ break; -+ len = *(data + 1) + (*(data + 2) * 256); -+ data += 3; -+ data_len -= 3; -+ if (tag == VPD_ID_STRING) -+ phb = iseries_parse_phbid(data, len); -+ else if (tag == VPD_VENDOR_AREA) -+ iseries_parse_mfg_area((struct mfg_vpd_area *)data, len, -+ agent, &phb, frame, card); -+ /* Point to next Area. */ -+ data += len; -+ data_len -= len; -+ } -+} -+ -+static int __init iseries_get_location_code(u16 bus, HvAgentId agent, -+ u8 *frame, char card[4]) -+{ -+ int status = 0; -+ int bus_vpd_len = 0; -+ u8 *bus_vpd = kmalloc(BUS_VPDSIZE, GFP_KERNEL); -+ -+ if (bus_vpd == NULL) { -+ printk("PCI: Bus VPD Buffer allocation failure.\n"); -+ return 0; -+ } -+ bus_vpd_len = HvCallPci_getBusVpd(bus, iseries_hv_addr(bus_vpd), -+ BUS_VPDSIZE); -+ if (bus_vpd_len == 0) { -+ printk("PCI: Bus VPD Buffer zero length.\n"); -+ goto out_free; -+ } -+ /* printk("PCI: bus_vpd: %p, %d\n",bus_vpd, bus_vpd_len); */ -+ /* Make sure this is what I think it is */ -+ if (*bus_vpd != VPD_ID_STRING) { -+ printk("PCI: Bus VPD Buffer missing starting tag.\n"); -+ goto out_free; -+ } -+ iseries_parse_vpd(bus_vpd, bus_vpd_len, agent, frame, card); -+ status = 1; -+out_free: -+ kfree(bus_vpd); -+ return status; -+} -+ -+/* -+ * Prints the device information. -+ * - Pass in pci_dev* pointer to the device. -+ * - Pass in the device count -+ * -+ * Format: -+ * PCI: Bus 0, Device 26, Vendor 0x12AE Frame 1, Card C10 Ethernet -+ * controller -+ */ -+static void __init iseries_device_information(struct pci_dev *pdev, -+ u16 bus, HvSubBusNumber subbus) -+{ -+ u8 frame = 0; -+ char card[4]; -+ HvAgentId agent; -+ -+ agent = ISERIES_PCI_AGENTID(ISERIES_GET_DEVICE_FROM_SUBBUS(subbus), -+ ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus)); -+ -+ if (iseries_get_location_code(bus, agent, &frame, card)) { -+ printk(KERN_INFO "PCI: %s, Vendor %04X Frame%3d, " -+ "Card %4s 0x%04X\n", pci_name(pdev), pdev->vendor, -+ frame, card, (int)(pdev->class >> 8)); -+ } -+} -+ -+/* - * iomm_table_allocate_entry - * - * Adds pci_dev entry in address translation table -@@ -87,7 +313,7 @@ static DEFINE_SPINLOCK(iomm_table_lock); - * - CurrentIndex is incremented to keep track of the last entry. - * - Builds the resource entry for allocated BARs. - */ --static void iomm_table_allocate_entry(struct pci_dev *dev, int bar_num) -+static void __init iomm_table_allocate_entry(struct pci_dev *dev, int bar_num) - { - struct resource *bar_res = &dev->resource[bar_num]; - long bar_size = pci_resource_len(dev, bar_num); -@@ -101,7 +327,6 @@ static void iomm_table_allocate_entry(st - * Set Resource values. - */ - spin_lock(&iomm_table_lock); -- bar_res->name = pci_io_text; - bar_res->start = BASE_IO_MEMORY + - IOMM_TABLE_ENTRY_SIZE * current_iomm_table_entry; - bar_res->end = bar_res->start + bar_size - 1; -@@ -110,7 +335,8 @@ static void iomm_table_allocate_entry(st - */ - while (bar_size > 0 ) { - iomm_table[current_iomm_table_entry] = dev->sysdata; -- iobar_table[current_iomm_table_entry] = bar_num; -+ ds_addr_table[current_iomm_table_entry] = -+ iseries_ds_addr(dev->sysdata) | (bar_num << 24); - bar_size -= IOMM_TABLE_ENTRY_SIZE; - ++current_iomm_table_entry; - } -@@ -130,7 +356,7 @@ static void iomm_table_allocate_entry(st - * - Loops through The Bar resources(0 - 5) including the ROM - * is resource(6). - */ --static void allocate_device_bars(struct pci_dev *dev) -+static void __init allocate_device_bars(struct pci_dev *dev) - { - int bar_num; - -@@ -145,79 +371,19 @@ static void allocate_device_bars(struct - * PCI: Read Vendor Failed 0x18.58.10 Rc: 0x00xx - * PCI: Connect Bus Unit Failed 0x18.58.10 Rc: 0x00xx - */ --static void pci_Log_Error(char *Error_Text, int Bus, int SubBus, -- int AgentId, int HvRc) -+static void pci_log_error(char *error, int bus, int subbus, -+ int agent, int hv_res) - { -- if (HvRc == 0x0302) -+ if (hv_res == 0x0302) - return; - printk(KERN_ERR "PCI: %s Failed: 0x%02X.%02X.%02X Rc: 0x%04X", -- Error_Text, Bus, SubBus, AgentId, HvRc); --} -- --/* -- * iSeries_pci_final_fixup(void) -- */ --void __init iSeries_pci_final_fixup(void) --{ -- struct pci_dev *pdev = NULL; -- struct device_node *node; -- int DeviceCount = 0; -- -- /* Fix up at the device node and pci_dev relationship */ -- mf_display_src(0xC9000100); -- -- printk("pcibios_final_fixup\n"); -- for_each_pci_dev(pdev) { -- node = find_Device_Node(pdev->bus->number, pdev->devfn); -- printk("pci dev %p (%x.%x), node %p\n", pdev, -- pdev->bus->number, pdev->devfn, node); -- -- if (node != NULL) { -- struct pci_dn *pdn = PCI_DN(node); -- const u32 *agent; -- -- agent = of_get_property(node, "linux,agent-id", NULL); -- if ((pdn != NULL) && (agent != NULL)) { -- u8 irq = iSeries_allocate_IRQ(pdn->busno, 0, -- pdn->bussubno); -- int err; -- -- err = HvCallXm_connectBusUnit(pdn->busno, pdn->bussubno, -- *agent, irq); -- if (err) -- pci_Log_Error("Connect Bus Unit", -- pdn->busno, pdn->bussubno, *agent, err); -- else { -- err = HvCallPci_configStore8(pdn->busno, pdn->bussubno, -- *agent, -- PCI_INTERRUPT_LINE, -- irq); -- if (err) -- pci_Log_Error("PciCfgStore Irq Failed!", -- pdn->busno, pdn->bussubno, *agent, err); -- } -- if (!err) -- pdev->irq = irq; -- } -- -- ++DeviceCount; -- pdev->sysdata = (void *)node; -- PCI_DN(node)->pcidev = pdev; -- allocate_device_bars(pdev); -- iSeries_Device_Information(pdev, DeviceCount); -- iommu_devnode_init_iSeries(pdev, node); -- } else -- printk("PCI: Device Tree not found for 0x%016lX\n", -- (unsigned long)pdev); -- } -- iSeries_activate_IRQs(); -- mf_display_src(0xC9000200); -+ error, bus, subbus, agent, hv_res); - } - - /* - * Look down the chain to find the matching Device Device - */ --static struct device_node *find_Device_Node(int bus, int devfn) -+static struct device_node *find_device_node(int bus, int devfn) - { - struct device_node *node; - -@@ -230,22 +396,66 @@ static struct device_node *find_Device_N - return NULL; - } - --#if 0 - /* -- * Returns the device node for the passed pci_dev -- * Sanity Check Node PciDev to passed pci_dev -- * If none is found, returns a NULL which the client must handle. -+ * iSeries_pcibios_fixup_resources -+ * -+ * Fixes up all resources for devices - */ --static struct device_node *get_Device_Node(struct pci_dev *pdev) -+void __init iSeries_pcibios_fixup_resources(struct pci_dev *pdev) - { -+ const u32 *agent; -+ const u32 *sub_bus; -+ unsigned char bus = pdev->bus->number; - struct device_node *node; -+ int i; -+ -+ node = find_device_node(bus, pdev->devfn); -+ pr_debug("PCI: iSeries %s, pdev %p, node %p\n", -+ pci_name(pdev), pdev, node); -+ if (!node) { -+ printk("PCI: %s disabled, device tree entry not found !\n", -+ pci_name(pdev)); -+ for (i = 0; i <= PCI_ROM_RESOURCE; i++) -+ pdev->resource[i].flags = 0; -+ return; -+ } -+ sub_bus = of_get_property(node, "linux,subbus", NULL); -+ agent = of_get_property(node, "linux,agent-id", NULL); -+ if (agent && sub_bus) { -+ u8 irq = iSeries_allocate_IRQ(bus, 0, *sub_bus); -+ int err; -+ -+ err = HvCallXm_connectBusUnit(bus, *sub_bus, *agent, irq); -+ if (err) -+ pci_log_error("Connect Bus Unit", -+ bus, *sub_bus, *agent, err); -+ else { -+ err = HvCallPci_configStore8(bus, *sub_bus, -+ *agent, PCI_INTERRUPT_LINE, irq); -+ if (err) -+ pci_log_error("PciCfgStore Irq Failed!", -+ bus, *sub_bus, *agent, err); -+ else -+ pdev->irq = irq; -+ } -+ } - -- node = pdev->sysdata; -- if (node == NULL || PCI_DN(node)->pcidev != pdev) -- node = find_Device_Node(pdev->bus->number, pdev->devfn); -- return node; -+ pdev->sysdata = node; -+ allocate_device_bars(pdev); -+ iseries_device_information(pdev, bus, *sub_bus); -+ iommu_devnode_init_iSeries(pdev, node); -+} -+ -+/* -+ * iSeries_pci_final_fixup(void) -+ */ -+void __init iSeries_pci_final_fixup(void) -+{ -+ /* Fix up at the device node and pci_dev relationship */ -+ mf_display_src(0xC9000100); -+ iSeries_activate_IRQs(); -+ mf_display_src(0xC9000200); - } --#endif - - /* - * Config space read and write functions. -@@ -269,7 +479,7 @@ static u64 hv_cfg_write_func[4] = { - static int iSeries_pci_read_config(struct pci_bus *bus, unsigned int devfn, - int offset, int size, u32 *val) - { -- struct device_node *node = find_Device_Node(bus->number, devfn); -+ struct device_node *node = find_device_node(bus->number, devfn); - u64 fn; - struct HvCallPci_LoadReturn ret; - -@@ -299,7 +509,7 @@ static int iSeries_pci_read_config(struc - static int iSeries_pci_write_config(struct pci_bus *bus, unsigned int devfn, - int offset, int size, u32 val) - { -- struct device_node *node = find_Device_Node(bus->number, devfn); -+ struct device_node *node = find_device_node(bus->number, devfn); - u64 fn; - u64 ret; - -@@ -331,22 +541,22 @@ static struct pci_ops iSeries_pci_ops = - * PCI: Device 23.90 ReadL Retry( 1) - * PCI: Device 23.90 ReadL Retry Successful(1) - */ --static int CheckReturnCode(char *TextHdr, struct device_node *DevNode, -+static int check_return_code(char *type, struct device_node *dn, - int *retry, u64 ret) - { - if (ret != 0) { -- struct pci_dn *pdn = PCI_DN(DevNode); -+ struct pci_dn *pdn = PCI_DN(dn); - - (*retry)++; - printk("PCI: %s: Device 0x%04X:%02X I/O Error(%2d): 0x%04X\n", -- TextHdr, pdn->busno, pdn->devfn, -+ type, pdn->busno, pdn->devfn, - *retry, (int)ret); - /* - * Bump the retry and check for retry count exceeded. - * If, Exceeded, panic the system. - */ -- if (((*retry) > Pci_Retry_Max) && -- (Pci_Error_Flag > 0)) { -+ if (((*retry) > PCI_RETRY_MAX) && -+ (limit_pci_retries > 0)) { - mf_display_src(0xB6000103); - panic_timeout = 0; - panic("PCI: Hardware I/O Error, SRC B6000103, " -@@ -363,28 +573,39 @@ static int CheckReturnCode(char *TextHdr - * the exposure of being device global. - */ - static inline struct device_node *xlate_iomm_address( -- const volatile void __iomem *IoAddress, -- u64 *dsaptr, u64 *BarOffsetPtr) -+ const volatile void __iomem *addr, -+ u64 *dsaptr, u64 *bar_offset, const char *func) - { -- unsigned long OrigIoAddr; -- unsigned long BaseIoAddr; -- unsigned long TableIndex; -- struct device_node *DevNode; -+ unsigned long orig_addr; -+ unsigned long base_addr; -+ unsigned long ind; -+ struct device_node *dn; - -- OrigIoAddr = (unsigned long __force)IoAddress; -- if ((OrigIoAddr < BASE_IO_MEMORY) || (OrigIoAddr >= max_io_memory)) -+ orig_addr = (unsigned long __force)addr; -+ if ((orig_addr < BASE_IO_MEMORY) || (orig_addr >= max_io_memory)) { -+ static unsigned long last_jiffies; -+ static int num_printed; -+ -+ if ((jiffies - last_jiffies) > 60 * HZ) { -+ last_jiffies = jiffies; -+ num_printed = 0; -+ } -+ if (num_printed++ < 10) -+ printk(KERN_ERR -+ "iSeries_%s: invalid access at IO address %p\n", -+ func, addr); - return NULL; -- BaseIoAddr = OrigIoAddr - BASE_IO_MEMORY; -- TableIndex = BaseIoAddr / IOMM_TABLE_ENTRY_SIZE; -- DevNode = iomm_table[TableIndex]; -- -- if (DevNode != NULL) { -- int barnum = iobar_table[TableIndex]; -- *dsaptr = iseries_ds_addr(DevNode) | (barnum << 24); -- *BarOffsetPtr = BaseIoAddr % IOMM_TABLE_ENTRY_SIZE; -+ } -+ base_addr = orig_addr - BASE_IO_MEMORY; -+ ind = base_addr / IOMM_TABLE_ENTRY_SIZE; -+ dn = iomm_table[ind]; -+ -+ if (dn != NULL) { -+ *dsaptr = ds_addr_table[ind]; -+ *bar_offset = base_addr % IOMM_TABLE_ENTRY_SIZE; - } else -- panic("PCI: Invalid PCI IoAddress detected!\n"); -- return DevNode; -+ panic("PCI: Invalid PCI IO address detected!\n"); -+ return dn; - } - - /* -@@ -392,91 +613,58 @@ static inline struct device_node *xlate_ - * On MM I/O error, all ones are returned and iSeries_pci_IoError is cal - * else, data is returned in Big Endian format. - */ --static u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress) -+static u8 iseries_readb(const volatile void __iomem *addr) - { -- u64 BarOffset; -+ u64 bar_offset; - u64 dsa; - int retry = 0; - struct HvCallPci_LoadReturn ret; -- struct device_node *DevNode = -- xlate_iomm_address(IoAddress, &dsa, &BarOffset); -- -- if (DevNode == NULL) { -- static unsigned long last_jiffies; -- static int num_printed; -+ struct device_node *dn = -+ xlate_iomm_address(addr, &dsa, &bar_offset, "read_byte"); - -- if ((jiffies - last_jiffies) > 60 * HZ) { -- last_jiffies = jiffies; -- num_printed = 0; -- } -- if (num_printed++ < 10) -- printk(KERN_ERR "iSeries_Read_Byte: invalid access at IO address %p\n", -- IoAddress); -+ if (dn == NULL) - return 0xff; -- } - do { -- HvCall3Ret16(HvCallPciBarLoad8, &ret, dsa, BarOffset, 0); -- } while (CheckReturnCode("RDB", DevNode, &retry, ret.rc) != 0); -+ HvCall3Ret16(HvCallPciBarLoad8, &ret, dsa, bar_offset, 0); -+ } while (check_return_code("RDB", dn, &retry, ret.rc) != 0); - - return ret.value; - } - --static u16 iSeries_Read_Word(const volatile void __iomem *IoAddress) -+static u16 iseries_readw_be(const volatile void __iomem *addr) - { -- u64 BarOffset; -+ u64 bar_offset; - u64 dsa; - int retry = 0; - struct HvCallPci_LoadReturn ret; -- struct device_node *DevNode = -- xlate_iomm_address(IoAddress, &dsa, &BarOffset); -- -- if (DevNode == NULL) { -- static unsigned long last_jiffies; -- static int num_printed; -+ struct device_node *dn = -+ xlate_iomm_address(addr, &dsa, &bar_offset, "read_word"); - -- if ((jiffies - last_jiffies) > 60 * HZ) { -- last_jiffies = jiffies; -- num_printed = 0; -- } -- if (num_printed++ < 10) -- printk(KERN_ERR "iSeries_Read_Word: invalid access at IO address %p\n", -- IoAddress); -+ if (dn == NULL) - return 0xffff; -- } - do { - HvCall3Ret16(HvCallPciBarLoad16, &ret, dsa, -- BarOffset, 0); -- } while (CheckReturnCode("RDW", DevNode, &retry, ret.rc) != 0); -+ bar_offset, 0); -+ } while (check_return_code("RDW", dn, &retry, ret.rc) != 0); - - return ret.value; - } - --static u32 iSeries_Read_Long(const volatile void __iomem *IoAddress) -+static u32 iseries_readl_be(const volatile void __iomem *addr) - { -- u64 BarOffset; -+ u64 bar_offset; - u64 dsa; - int retry = 0; - struct HvCallPci_LoadReturn ret; -- struct device_node *DevNode = -- xlate_iomm_address(IoAddress, &dsa, &BarOffset); -+ struct device_node *dn = -+ xlate_iomm_address(addr, &dsa, &bar_offset, "read_long"); - -- if (DevNode == NULL) { -- static unsigned long last_jiffies; -- static int num_printed; -- -- if ((jiffies - last_jiffies) > 60 * HZ) { -- last_jiffies = jiffies; -- num_printed = 0; -- } -- if (num_printed++ < 10) -- printk(KERN_ERR "iSeries_Read_Long: invalid access at IO address %p\n", -- IoAddress); -+ if (dn == NULL) - return 0xffffffff; -- } - do { - HvCall3Ret16(HvCallPciBarLoad32, &ret, dsa, -- BarOffset, 0); -- } while (CheckReturnCode("RDL", DevNode, &retry, ret.rc) != 0); -+ bar_offset, 0); -+ } while (check_return_code("RDL", dn, &retry, ret.rc) != 0); - - return ret.value; - } -@@ -485,134 +673,72 @@ static u32 iSeries_Read_Long(const volat - * Write MM I/O Instructions for the iSeries - * - */ --static void iSeries_Write_Byte(u8 data, volatile void __iomem *IoAddress) -+static void iseries_writeb(u8 data, volatile void __iomem *addr) - { -- u64 BarOffset; -+ u64 bar_offset; - u64 dsa; - int retry = 0; - u64 rc; -- struct device_node *DevNode = -- xlate_iomm_address(IoAddress, &dsa, &BarOffset); -- -- if (DevNode == NULL) { -- static unsigned long last_jiffies; -- static int num_printed; -+ struct device_node *dn = -+ xlate_iomm_address(addr, &dsa, &bar_offset, "write_byte"); - -- if ((jiffies - last_jiffies) > 60 * HZ) { -- last_jiffies = jiffies; -- num_printed = 0; -- } -- if (num_printed++ < 10) -- printk(KERN_ERR "iSeries_Write_Byte: invalid access at IO address %p\n", IoAddress); -+ if (dn == NULL) - return; -- } - do { -- rc = HvCall4(HvCallPciBarStore8, dsa, BarOffset, data, 0); -- } while (CheckReturnCode("WWB", DevNode, &retry, rc) != 0); -+ rc = HvCall4(HvCallPciBarStore8, dsa, bar_offset, data, 0); -+ } while (check_return_code("WWB", dn, &retry, rc) != 0); - } - --static void iSeries_Write_Word(u16 data, volatile void __iomem *IoAddress) -+static void iseries_writew_be(u16 data, volatile void __iomem *addr) - { -- u64 BarOffset; -+ u64 bar_offset; - u64 dsa; - int retry = 0; - u64 rc; -- struct device_node *DevNode = -- xlate_iomm_address(IoAddress, &dsa, &BarOffset); -+ struct device_node *dn = -+ xlate_iomm_address(addr, &dsa, &bar_offset, "write_word"); - -- if (DevNode == NULL) { -- static unsigned long last_jiffies; -- static int num_printed; -- -- if ((jiffies - last_jiffies) > 60 * HZ) { -- last_jiffies = jiffies; -- num_printed = 0; -- } -- if (num_printed++ < 10) -- printk(KERN_ERR "iSeries_Write_Word: invalid access at IO address %p\n", -- IoAddress); -+ if (dn == NULL) - return; -- } - do { -- rc = HvCall4(HvCallPciBarStore16, dsa, BarOffset, data, 0); -- } while (CheckReturnCode("WWW", DevNode, &retry, rc) != 0); -+ rc = HvCall4(HvCallPciBarStore16, dsa, bar_offset, data, 0); -+ } while (check_return_code("WWW", dn, &retry, rc) != 0); - } - --static void iSeries_Write_Long(u32 data, volatile void __iomem *IoAddress) -+static void iseries_writel_be(u32 data, volatile void __iomem *addr) - { -- u64 BarOffset; -+ u64 bar_offset; - u64 dsa; - int retry = 0; - u64 rc; -- struct device_node *DevNode = -- xlate_iomm_address(IoAddress, &dsa, &BarOffset); -- -- if (DevNode == NULL) { -- static unsigned long last_jiffies; -- static int num_printed; -+ struct device_node *dn = -+ xlate_iomm_address(addr, &dsa, &bar_offset, "write_long"); - -- if ((jiffies - last_jiffies) > 60 * HZ) { -- last_jiffies = jiffies; -- num_printed = 0; -- } -- if (num_printed++ < 10) -- printk(KERN_ERR "iSeries_Write_Long: invalid access at IO address %p\n", -- IoAddress); -+ if (dn == NULL) - return; -- } - do { -- rc = HvCall4(HvCallPciBarStore32, dsa, BarOffset, data, 0); -- } while (CheckReturnCode("WWL", DevNode, &retry, rc) != 0); --} -- --static u8 iseries_readb(const volatile void __iomem *addr) --{ -- return iSeries_Read_Byte(addr); -+ rc = HvCall4(HvCallPciBarStore32, dsa, bar_offset, data, 0); -+ } while (check_return_code("WWL", dn, &retry, rc) != 0); - } - - static u16 iseries_readw(const volatile void __iomem *addr) - { -- return le16_to_cpu(iSeries_Read_Word(addr)); -+ return le16_to_cpu(iseries_readw_be(addr)); - } - - static u32 iseries_readl(const volatile void __iomem *addr) - { -- return le32_to_cpu(iSeries_Read_Long(addr)); --} -- --static u16 iseries_readw_be(const volatile void __iomem *addr) --{ -- return iSeries_Read_Word(addr); --} -- --static u32 iseries_readl_be(const volatile void __iomem *addr) --{ -- return iSeries_Read_Long(addr); --} -- --static void iseries_writeb(u8 data, volatile void __iomem *addr) --{ -- iSeries_Write_Byte(data, addr); -+ return le32_to_cpu(iseries_readl_be(addr)); - } - - static void iseries_writew(u16 data, volatile void __iomem *addr) - { -- iSeries_Write_Word(cpu_to_le16(data), addr); -+ iseries_writew_be(cpu_to_le16(data), addr); - } - - static void iseries_writel(u32 data, volatile void __iomem *addr) - { -- iSeries_Write_Long(cpu_to_le32(data), addr); --} -- --static void iseries_writew_be(u16 data, volatile void __iomem *addr) --{ -- iSeries_Write_Word(data, addr); --} -- --static void iseries_writel_be(u32 data, volatile void __iomem *addr) --{ -- iSeries_Write_Long(data, addr); -+ iseries_writel(cpu_to_le32(data), addr); - } - - static void iseries_readsb(const volatile void __iomem *addr, void *buf, -@@ -620,7 +746,7 @@ static void iseries_readsb(const volatil - { - u8 *dst = buf; - while(count-- > 0) -- *(dst++) = iSeries_Read_Byte(addr); -+ *(dst++) = iseries_readb(addr); - } - - static void iseries_readsw(const volatile void __iomem *addr, void *buf, -@@ -628,7 +754,7 @@ static void iseries_readsw(const volatil - { - u16 *dst = buf; - while(count-- > 0) -- *(dst++) = iSeries_Read_Word(addr); -+ *(dst++) = iseries_readw_be(addr); - } - - static void iseries_readsl(const volatile void __iomem *addr, void *buf, -@@ -636,7 +762,7 @@ static void iseries_readsl(const volatil - { - u32 *dst = buf; - while(count-- > 0) -- *(dst++) = iSeries_Read_Long(addr); -+ *(dst++) = iseries_readl_be(addr); - } - - static void iseries_writesb(volatile void __iomem *addr, const void *buf, -@@ -644,7 +770,7 @@ static void iseries_writesb(volatile voi - { - const u8 *src = buf; - while(count-- > 0) -- iSeries_Write_Byte(*(src++), addr); -+ iseries_writeb(*(src++), addr); - } - - static void iseries_writesw(volatile void __iomem *addr, const void *buf, -@@ -652,7 +778,7 @@ static void iseries_writesw(volatile voi - { - const u16 *src = buf; - while(count-- > 0) -- iSeries_Write_Word(*(src++), addr); -+ iseries_writew_be(*(src++), addr); - } - - static void iseries_writesl(volatile void __iomem *addr, const void *buf, -@@ -660,7 +786,7 @@ static void iseries_writesl(volatile voi - { - const u32 *src = buf; - while(count-- > 0) -- iSeries_Write_Long(*(src++), addr); -+ iseries_writel_be(*(src++), addr); - } - - static void iseries_memset_io(volatile void __iomem *addr, int c, -@@ -669,7 +795,7 @@ static void iseries_memset_io(volatile v - volatile char __iomem *d = addr; - - while (n-- > 0) -- iSeries_Write_Byte(c, d++); -+ iseries_writeb(c, d++); - } - - static void iseries_memcpy_fromio(void *dest, const volatile void __iomem *src, -@@ -679,7 +805,7 @@ static void iseries_memcpy_fromio(void * - const volatile char __iomem *s = src; - - while (n-- > 0) -- *d++ = iSeries_Read_Byte(s++); -+ *d++ = iseries_readb(s++); - } - - static void iseries_memcpy_toio(volatile void __iomem *dest, const void *src, -@@ -689,7 +815,7 @@ static void iseries_memcpy_toio(volatile - volatile char __iomem *d = dest; - - while (n-- > 0) -- iSeries_Write_Byte(*s++, d++); -+ iseries_writeb(*s++, d++); - } - - /* We only set MMIO ops. The default PIO ops will be default -@@ -742,6 +868,8 @@ void __init iSeries_pcibios_init(void) - /* Install IO hooks */ - ppc_pci_io = iseries_pci_io; - -+ pci_probe_only = 1; -+ - /* iSeries has no IO space in the common sense, it needs to set - * the IO base to 0 - */ -@@ -767,11 +895,21 @@ void __init iSeries_pcibios_init(void) - phb = pcibios_alloc_controller(node); - if (phb == NULL) - continue; -+ /* All legacy iSeries PHBs are in domain zero */ -+ phb->global_number = 0; - -- phb->pci_mem_offset = bus; - phb->first_busno = bus; - phb->last_busno = bus; - phb->ops = &iSeries_pci_ops; -+ phb->io_base_virt = (void __iomem *)_IO_BASE; -+ phb->io_resource.flags = IORESOURCE_IO; -+ phb->io_resource.start = BASE_IO_MEMORY; -+ phb->io_resource.end = END_IO_MEMORY; -+ phb->io_resource.name = "iSeries PCI IO"; -+ phb->mem_resources[0].flags = IORESOURCE_MEM; -+ phb->mem_resources[0].start = BASE_IO_MEMORY; -+ phb->mem_resources[0].end = END_IO_MEMORY; -+ phb->mem_resources[0].name = "Series PCI MEM"; - } - - of_node_put(root); ---- a/arch/powerpc/platforms/iseries/pci.h -+++ b/arch/powerpc/platforms/iseries/pci.h -@@ -30,10 +30,6 @@ - * End Change Activity - */ - --#include -- --struct pci_dev; /* For Forward Reference */ -- - /* - * Decodes Linux DevFn to iSeries DevFn, bridge device, or function. - * For Linux, see PCI_SLOT and PCI_FUNC in include/linux/pci.h -@@ -47,17 +43,16 @@ struct pci_dev; /* For Forward Refere - #define ISERIES_GET_DEVICE_FROM_SUBBUS(subbus) ((subbus >> 5) & 0x7) - #define ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus) ((subbus >> 2) & 0x7) - --/* -- * Generate a Direct Select Address for the Hypervisor -- */ --static inline u64 iseries_ds_addr(struct device_node *node) --{ -- struct pci_dn *pdn = PCI_DN(node); -- -- return ((u64)pdn->busno << 48) + ((u64)pdn->bussubno << 40) -- + ((u64)0x10 << 32); --} -+struct pci_dev; - --extern void iSeries_Device_Information(struct pci_dev*, int); -+#ifdef CONFIG_PCI -+extern void iSeries_pcibios_init(void); -+extern void iSeries_pci_final_fixup(void); -+extern void iSeries_pcibios_fixup_resources(struct pci_dev *dev); -+#else -+static inline void iSeries_pcibios_init(void) { } -+static inline void iSeries_pci_final_fixup(void) { } -+static inline void iSeries_pcibios_fixup_resources(struct pci_dev *dev) {} -+#endif - - #endif /* _PLATFORMS_ISERIES_PCI_H */ ---- a/arch/powerpc/platforms/iseries/setup.c -+++ b/arch/powerpc/platforms/iseries/setup.c -@@ -63,6 +63,7 @@ - #include "main_store.h" - #include "call_sm.h" - #include "call_hpt.h" -+#include "pci.h" - - #ifdef DEBUG - #define DBG(fmt...) udbg_printf(fmt) -@@ -74,11 +75,6 @@ - static unsigned long build_iSeries_Memory_Map(void); - static void iseries_shared_idle(void); - static void iseries_dedicated_idle(void); --#ifdef CONFIG_PCI --extern void iSeries_pci_final_fixup(void); --#else --static void iSeries_pci_final_fixup(void) { } --#endif - - - struct MemoryBlock { -@@ -112,13 +108,13 @@ static unsigned long iSeries_process_Con - * correctly. - */ - mb_array[0].logicalStart = 0; -- mb_array[0].logicalEnd = 0x100000000; -+ mb_array[0].logicalEnd = 0x100000000UL; - mb_array[0].absStart = 0; -- mb_array[0].absEnd = 0x100000000; -+ mb_array[0].absEnd = 0x100000000UL; - - if (holeSize) { - numMemoryBlocks = 2; -- holeStart = holeStart & 0x000fffffffffffff; -+ holeStart = holeStart & 0x000fffffffffffffUL; - holeStart = addr_to_chunk(holeStart); - holeFirstChunk = holeStart; - holeSize = addr_to_chunk(holeSize); -@@ -128,9 +124,9 @@ static unsigned long iSeries_process_Con - mb_array[0].logicalEnd = holeFirstChunk; - mb_array[0].absEnd = holeFirstChunk; - mb_array[1].logicalStart = holeFirstChunk; -- mb_array[1].logicalEnd = 0x100000000 - holeSizeChunks; -+ mb_array[1].logicalEnd = 0x100000000UL - holeSizeChunks; - mb_array[1].absStart = holeFirstChunk + holeSizeChunks; -- mb_array[1].absEnd = 0x100000000; -+ mb_array[1].absEnd = 0x100000000UL; - } - return numMemoryBlocks; - } -@@ -234,9 +230,9 @@ static unsigned long iSeries_process_Reg - mb_array[i].logicalEnd, - mb_array[i].absStart, mb_array[i].absEnd); - mb_array[i].absStart = addr_to_chunk(mb_array[i].absStart & -- 0x000fffffffffffff); -+ 0x000fffffffffffffUL); - mb_array[i].absEnd = addr_to_chunk(mb_array[i].absEnd & -- 0x000fffffffffffff); -+ 0x000fffffffffffffUL); - mb_array[i].logicalStart = - addr_to_chunk(mb_array[i].logicalStart); - mb_array[i].logicalEnd = addr_to_chunk(mb_array[i].logicalEnd); -@@ -320,7 +316,7 @@ struct mschunks_map mschunks_map = { - }; - EXPORT_SYMBOL(mschunks_map); - --void mschunks_alloc(unsigned long num_chunks) -+static void mschunks_alloc(unsigned long num_chunks) - { - klimit = _ALIGN(klimit, sizeof(u32)); - mschunks_map.mapping = (u32 *)klimit; -@@ -499,6 +495,8 @@ static void __init iSeries_setup_arch(vo - itVpdAreas.xSlicMaxLogicalProcs); - printk("Max physical processors = %d\n", - itVpdAreas.xSlicMaxPhysicalProcs); -+ -+ iSeries_pcibios_init(); - } - - static void iSeries_show_cpuinfo(struct seq_file *m) -@@ -641,24 +639,25 @@ static int __init iseries_probe(void) - } - - define_machine(iseries) { -- .name = "iSeries", -- .setup_arch = iSeries_setup_arch, -- .show_cpuinfo = iSeries_show_cpuinfo, -- .init_IRQ = iSeries_init_IRQ, -- .get_irq = iSeries_get_irq, -- .init_early = iSeries_init_early, -- .pcibios_fixup = iSeries_pci_final_fixup, -- .restart = mf_reboot, -- .power_off = mf_power_off, -- .halt = mf_power_off, -- .get_boot_time = iSeries_get_boot_time, -- .set_rtc_time = iSeries_set_rtc_time, -- .get_rtc_time = iSeries_get_rtc_time, -- .calibrate_decr = generic_calibrate_decr, -- .progress = iSeries_progress, -- .probe = iseries_probe, -- .ioremap = iseries_ioremap, -- .iounmap = iseries_iounmap, -+ .name = "iSeries", -+ .setup_arch = iSeries_setup_arch, -+ .show_cpuinfo = iSeries_show_cpuinfo, -+ .init_IRQ = iSeries_init_IRQ, -+ .get_irq = iSeries_get_irq, -+ .init_early = iSeries_init_early, -+ .pcibios_fixup = iSeries_pci_final_fixup, -+ .pcibios_fixup_resources= iSeries_pcibios_fixup_resources, -+ .restart = mf_reboot, -+ .power_off = mf_power_off, -+ .halt = mf_power_off, -+ .get_boot_time = iSeries_get_boot_time, -+ .set_rtc_time = iSeries_set_rtc_time, -+ .get_rtc_time = iSeries_get_rtc_time, -+ .calibrate_decr = generic_calibrate_decr, -+ .progress = iSeries_progress, -+ .probe = iseries_probe, -+ .ioremap = iseries_ioremap, -+ .iounmap = iseries_iounmap, - /* XXX Implement enable_pmcs for iSeries */ - }; - ---- a/arch/powerpc/platforms/iseries/setup.h -+++ b/arch/powerpc/platforms/iseries/setup.h -@@ -17,6 +17,7 @@ - #ifndef __ISERIES_SETUP_H__ - #define __ISERIES_SETUP_H__ - -+extern void *iSeries_early_setup(void); - extern unsigned long iSeries_get_boot_time(void); - extern int iSeries_set_rtc_time(struct rtc_time *tm); - extern void iSeries_get_rtc_time(struct rtc_time *tm); ---- a/arch/powerpc/platforms/iseries/vpdinfo.c -+++ /dev/null -@@ -1,275 +0,0 @@ --/* -- * This code gets the card location of the hardware -- * Copyright (C) 2001 -- * Copyright (C) 2005 Stephen Rothwel, IBM Corp -- * -- * 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 -- * -- * Change Activity: -- * Created, Feb 2, 2001 -- * Ported to ppc64, August 20, 2001 -- * End Change Activity -- */ --#include --#include --#include -- --#include --#include --#include --#include --#include -- --#include "pci.h" --#include "call_pci.h" -- --/* -- * Size of Bus VPD data -- */ --#define BUS_VPDSIZE 1024 -- --/* -- * Bus Vpd Tags -- */ --#define VpdEndOfAreaTag 0x79 --#define VpdIdStringTag 0x82 --#define VpdVendorAreaTag 0x84 -- --/* -- * Mfg Area Tags -- */ --#define VpdFruFrameId 0x4649 // "FI" --#define VpdSlotMapFormat 0x4D46 // "MF" --#define VpdSlotMap 0x534D // "SM" -- --/* -- * Structures of the areas -- */ --struct MfgVpdAreaStruct { -- u16 Tag; -- u8 TagLength; -- u8 AreaData1; -- u8 AreaData2; --}; --typedef struct MfgVpdAreaStruct MfgArea; --#define MFG_ENTRY_SIZE 3 -- --struct SlotMapStruct { -- u8 AgentId; -- u8 SecondaryAgentId; -- u8 PhbId; -- char CardLocation[3]; -- char Parms[8]; -- char Reserved[2]; --}; --typedef struct SlotMapStruct SlotMap; --#define SLOT_ENTRY_SIZE 16 -- --/* -- * Parse the Slot Area -- */ --static void __init iSeries_Parse_SlotArea(SlotMap *MapPtr, int MapLen, -- HvAgentId agent, u8 *PhbId, char card[4]) --{ -- int SlotMapLen = MapLen; -- SlotMap *SlotMapPtr = MapPtr; -- -- /* -- * Parse Slot label until we find the one requested -- */ -- while (SlotMapLen > 0) { -- if (SlotMapPtr->AgentId == agent) { -- /* -- * If Phb wasn't found, grab the entry first one found. -- */ -- if (*PhbId == 0xff) -- *PhbId = SlotMapPtr->PhbId; -- /* Found it, extract the data. */ -- if (SlotMapPtr->PhbId == *PhbId) { -- memcpy(card, &SlotMapPtr->CardLocation, 3); -- card[3] = 0; -- break; -- } -- } -- /* Point to the next Slot */ -- SlotMapPtr = (SlotMap *)((char *)SlotMapPtr + SLOT_ENTRY_SIZE); -- SlotMapLen -= SLOT_ENTRY_SIZE; -- } --} -- --/* -- * Parse the Mfg Area -- */ --static void __init iSeries_Parse_MfgArea(u8 *AreaData, int AreaLen, -- HvAgentId agent, u8 *PhbId, -- u8 *frame, char card[4]) --{ -- MfgArea *MfgAreaPtr = (MfgArea *)AreaData; -- int MfgAreaLen = AreaLen; -- u16 SlotMapFmt = 0; -- -- /* Parse Mfg Data */ -- while (MfgAreaLen > 0) { -- int MfgTagLen = MfgAreaPtr->TagLength; -- /* Frame ID (FI 4649020310 ) */ -- if (MfgAreaPtr->Tag == VpdFruFrameId) /* FI */ -- *frame = MfgAreaPtr->AreaData1; -- /* Slot Map Format (MF 4D46020004 ) */ -- else if (MfgAreaPtr->Tag == VpdSlotMapFormat) /* MF */ -- SlotMapFmt = (MfgAreaPtr->AreaData1 * 256) -- + MfgAreaPtr->AreaData2; -- /* Slot Map (SM 534D90 */ -- else if (MfgAreaPtr->Tag == VpdSlotMap) { /* SM */ -- SlotMap *SlotMapPtr; -- -- if (SlotMapFmt == 0x1004) -- SlotMapPtr = (SlotMap *)((char *)MfgAreaPtr -- + MFG_ENTRY_SIZE + 1); -- else -- SlotMapPtr = (SlotMap *)((char *)MfgAreaPtr -- + MFG_ENTRY_SIZE); -- iSeries_Parse_SlotArea(SlotMapPtr, MfgTagLen, -- agent, PhbId, card); -- } -- /* -- * Point to the next Mfg Area -- * Use defined size, sizeof give wrong answer -- */ -- MfgAreaPtr = (MfgArea *)((char *)MfgAreaPtr + MfgTagLen -- + MFG_ENTRY_SIZE); -- MfgAreaLen -= (MfgTagLen + MFG_ENTRY_SIZE); -- } --} -- --/* -- * Look for "BUS".. Data is not Null terminated. -- * PHBID of 0xFF indicates PHB was not found in VPD Data. -- */ --static int __init iSeries_Parse_PhbId(u8 *AreaPtr, int AreaLength) --{ -- u8 *PhbPtr = AreaPtr; -- int DataLen = AreaLength; -- char PhbId = 0xFF; -- -- while (DataLen > 0) { -- if ((*PhbPtr == 'B') && (*(PhbPtr + 1) == 'U') -- && (*(PhbPtr + 2) == 'S')) { -- PhbPtr += 3; -- while (*PhbPtr == ' ') -- ++PhbPtr; -- PhbId = (*PhbPtr & 0x0F); -- break; -- } -- ++PhbPtr; -- --DataLen; -- } -- return PhbId; --} -- --/* -- * Parse out the VPD Areas -- */ --static void __init iSeries_Parse_Vpd(u8 *VpdData, int VpdDataLen, -- HvAgentId agent, u8 *frame, char card[4]) --{ -- u8 *TagPtr = VpdData; -- int DataLen = VpdDataLen - 3; -- u8 PhbId = 0xff; -- -- while ((*TagPtr != VpdEndOfAreaTag) && (DataLen > 0)) { -- int AreaLen = *(TagPtr + 1) + (*(TagPtr + 2) * 256); -- u8 *AreaData = TagPtr + 3; -- -- if (*TagPtr == VpdIdStringTag) -- PhbId = iSeries_Parse_PhbId(AreaData, AreaLen); -- else if (*TagPtr == VpdVendorAreaTag) -- iSeries_Parse_MfgArea(AreaData, AreaLen, -- agent, &PhbId, frame, card); -- /* Point to next Area. */ -- TagPtr = AreaData + AreaLen; -- DataLen -= AreaLen; -- } --} -- --static int __init iSeries_Get_Location_Code(u16 bus, HvAgentId agent, -- u8 *frame, char card[4]) --{ -- int status = 0; -- int BusVpdLen = 0; -- u8 *BusVpdPtr = kmalloc(BUS_VPDSIZE, GFP_KERNEL); -- -- if (BusVpdPtr == NULL) { -- printk("PCI: Bus VPD Buffer allocation failure.\n"); -- return 0; -- } -- BusVpdLen = HvCallPci_getBusVpd(bus, iseries_hv_addr(BusVpdPtr), -- BUS_VPDSIZE); -- if (BusVpdLen == 0) { -- printk("PCI: Bus VPD Buffer zero length.\n"); -- goto out_free; -- } -- /* printk("PCI: BusVpdPtr: %p, %d\n",BusVpdPtr, BusVpdLen); */ -- /* Make sure this is what I think it is */ -- if (*BusVpdPtr != VpdIdStringTag) { /* 0x82 */ -- printk("PCI: Bus VPD Buffer missing starting tag.\n"); -- goto out_free; -- } -- iSeries_Parse_Vpd(BusVpdPtr, BusVpdLen, agent, frame, card); -- status = 1; --out_free: -- kfree(BusVpdPtr); -- return status; --} -- --/* -- * Prints the device information. -- * - Pass in pci_dev* pointer to the device. -- * - Pass in the device count -- * -- * Format: -- * PCI: Bus 0, Device 26, Vendor 0x12AE Frame 1, Card C10 Ethernet -- * controller -- */ --void __init iSeries_Device_Information(struct pci_dev *PciDev, int count) --{ -- struct device_node *DevNode = PciDev->sysdata; -- struct pci_dn *pdn; -- u16 bus; -- u8 frame = 0; -- char card[4]; -- HvSubBusNumber subbus; -- HvAgentId agent; -- -- if (DevNode == NULL) { -- printk("%d. PCI: iSeries_Device_Information DevNode is NULL\n", -- count); -- return; -- } -- -- pdn = PCI_DN(DevNode); -- bus = pdn->busno; -- subbus = pdn->bussubno; -- agent = ISERIES_PCI_AGENTID(ISERIES_GET_DEVICE_FROM_SUBBUS(subbus), -- ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus)); -- -- if (iSeries_Get_Location_Code(bus, agent, &frame, card)) { -- printk("%d. PCI: Bus%3d, Device%3d, Vendor %04X Frame%3d, " -- "Card %4s 0x%04X\n", count, bus, -- PCI_SLOT(PciDev->devfn), PciDev->vendor, frame, -- card, (int)(PciDev->class >> 8)); -- } --} ---- a/arch/powerpc/platforms/maple/Kconfig -+++ b/arch/powerpc/platforms/maple/Kconfig -@@ -1,6 +1,7 @@ - config PPC_MAPLE - depends on PPC_MULTIPLATFORM && PPC64 - bool "Maple 970FX Evaluation Board" -+ select PCI - select MPIC - select U3_DART - select MPIC_U3_HT_IRQS ---- a/arch/powerpc/platforms/maple/pci.c -+++ b/arch/powerpc/platforms/maple/pci.c -@@ -558,7 +558,7 @@ void __init maple_pci_init(void) - * safe assumptions hopefully. - */ - if (u3_agp) { -- struct device_node *np = u3_agp->arch_data; -+ struct device_node *np = u3_agp->dn; - PCI_DN(np)->busno = 0xf0; - for (np = np->child; np; np = np->sibling) - PCI_DN(np)->busno = 0xf0; ---- a/arch/powerpc/platforms/maple/setup.c -+++ b/arch/powerpc/platforms/maple/setup.c -@@ -42,6 +42,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -56,7 +57,6 @@ - #include - #include - #include --#include - #include - #include - #include ---- a/arch/powerpc/platforms/pasemi/Kconfig -+++ b/arch/powerpc/platforms/pasemi/Kconfig -@@ -3,6 +3,7 @@ config PPC_PASEMI - bool "PA Semi SoC-based platforms" - default n - select MPIC -+ select PCI - select PPC_UDBG_16550 - select PPC_NATIVE - select MPIC_BROKEN_REGREAD -@@ -17,7 +18,7 @@ config PPC_PASEMI_IOMMU - bool "PA Semi IOMMU support" - depends on PPC_PASEMI - help -- IOMMU support for PA6T-1682M -+ IOMMU support for PA Semi PWRficient - - config PPC_PASEMI_IOMMU_DMA_FORCE - bool "Force DMA engine to use IOMMU" -@@ -36,13 +37,4 @@ config PPC_PASEMI_MDIO - help - Driver for MDIO via GPIO on PWRficient platforms - --config ELECTRA_IDE -- tristate "Electra IDE driver" -- default y -- depends on PPC_PASEMI && ATA -- select PATA_PLATFORM -- help -- This includes driver support for the Electra on-board IDE -- interface. -- - endmenu ---- a/arch/powerpc/platforms/pasemi/Makefile -+++ b/arch/powerpc/platforms/pasemi/Makefile -@@ -1,4 +1,3 @@ - obj-y += setup.o pci.o time.o idle.o powersave.o iommu.o - obj-$(CONFIG_PPC_PASEMI_MDIO) += gpio_mdio.o --obj-$(CONFIG_ELECTRA_IDE) += electra_ide.o - obj-$(CONFIG_PPC_PASEMI_CPUFREQ) += cpufreq.o ---- a/arch/powerpc/platforms/pasemi/cpufreq.c -+++ b/arch/powerpc/platforms/pasemi/cpufreq.c -@@ -32,6 +32,7 @@ - #include - #include - #include -+#include - - #define SDCASR_REG 0x0100 - #define SDCASR_REG_STRIDE 0x1000 -@@ -124,6 +125,11 @@ static void set_astate(int cpu, unsigned - local_irq_restore(flags); - } - -+int check_astate(void) -+{ -+ return get_cur_astate(hard_smp_processor_id()); -+} -+ - void restore_astate(int cpu) - { - set_astate(cpu, current_astate); -@@ -147,7 +153,10 @@ static int pas_cpufreq_cpu_init(struct c - if (!cpu) - goto out; - -- dn = of_find_compatible_node(NULL, "sdc", "1682m-sdc"); -+ dn = of_find_compatible_node(NULL, NULL, "1682m-sdc"); -+ if (!dn) -+ dn = of_find_compatible_node(NULL, NULL, -+ "pasemi,pwrficient-sdc"); - if (!dn) - goto out; - err = of_address_to_resource(dn, 0, &res); -@@ -160,7 +169,10 @@ static int pas_cpufreq_cpu_init(struct c - goto out; - } - -- dn = of_find_compatible_node(NULL, "gizmo", "1682m-gizmo"); -+ dn = of_find_compatible_node(NULL, NULL, "1682m-gizmo"); -+ if (!dn) -+ dn = of_find_compatible_node(NULL, NULL, -+ "pasemi,pwrficient-gizmo"); - if (!dn) { - err = -ENODEV; - goto out_unmap_sdcasr; -@@ -292,7 +304,8 @@ static struct cpufreq_driver pas_cpufreq - - static int __init pas_cpufreq_init(void) - { -- if (!machine_is_compatible("PA6T-1682M")) -+ if (!machine_is_compatible("PA6T-1682M") && -+ !machine_is_compatible("pasemi,pwrficient")) - return -ENODEV; - - return cpufreq_register_driver(&pas_cpufreq_driver); ---- a/arch/powerpc/platforms/pasemi/electra_ide.c -+++ /dev/null -@@ -1,96 +0,0 @@ --/* -- * Copyright (C) 2007 PA Semi, Inc -- * -- * Maintained by: Olof Johansson -- * -- * 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. -- * -- * 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 -- --/* The electra IDE interface is incredibly simple: Just a device on the localbus -- * with interrupts hooked up to one of the GPIOs. The device tree contains the -- * address window and interrupt mappings already, and the pata_platform driver handles -- * the rest. We just need to hook the two up. -- */ -- --#define MAX_IFS 4 /* really, we have only one */ -- --static struct platform_device *pdevs[MAX_IFS]; -- --static int __devinit electra_ide_init(void) --{ -- struct device_node *np; -- struct resource r[3]; -- int ret = 0; -- int i; -- -- np = of_find_compatible_node(NULL, "ide", "electra-ide"); -- i = 0; -- -- while (np && i < MAX_IFS) { -- memset(r, 0, sizeof(r)); -- -- /* pata_platform wants two address ranges: one for the base registers, -- * another for the control (altstatus). It's located at offset 0x3f6 in -- * the window, but the device tree only has one large register window -- * that covers both ranges. So we need to split it up by hand here: -- */ -- -- ret = of_address_to_resource(np, 0, &r[0]); -- if (ret) -- goto out; -- ret = of_address_to_resource(np, 0, &r[1]); -- if (ret) -- goto out; -- -- r[1].start += 0x3f6; -- r[0].end = r[1].start-1; -- -- r[2].start = irq_of_parse_and_map(np, 0); -- r[2].end = irq_of_parse_and_map(np, 0); -- r[2].flags = IORESOURCE_IRQ; -- -- pr_debug("registering platform device at 0x%lx/0x%lx, irq is %ld\n", -- r[0].start, r[1].start, r[2].start); -- pdevs[i] = platform_device_register_simple("pata_platform", i, r, 3); -- if (IS_ERR(pdevs[i])) { -- ret = PTR_ERR(pdevs[i]); -- pdevs[i] = NULL; -- goto out; -- } -- np = of_find_compatible_node(np, "ide", "electra-ide"); -- } --out: -- return ret; --} --module_init(electra_ide_init); -- --static void __devexit electra_ide_exit(void) --{ -- int i; -- -- for (i = 0; i < MAX_IFS; i++) -- if (pdevs[i]) -- platform_device_unregister(pdevs[i]); --} --module_exit(electra_ide_exit); -- -- --MODULE_LICENSE("GPL"); --MODULE_AUTHOR ("Olof Johansson "); --MODULE_DESCRIPTION("PA Semi Electra IDE driver"); ---- a/arch/powerpc/platforms/pasemi/gpio_mdio.c -+++ b/arch/powerpc/platforms/pasemi/gpio_mdio.c -@@ -30,7 +30,7 @@ - #include - #include - #include --#include -+#include - - #define DELAY 1 - -@@ -218,45 +218,27 @@ static int __devinit gpio_mdio_probe(str - const struct of_device_id *match) - { - struct device *dev = &ofdev->dev; -- struct device_node *np = ofdev->node; -- struct device_node *gpio_np; -+ struct device_node *phy_dn, *np = ofdev->node; - struct mii_bus *new_bus; -- struct resource res; - struct gpio_priv *priv; - const unsigned int *prop; -- int err = 0; -+ int err; - int i; - -- gpio_np = of_find_compatible_node(NULL, "gpio", "1682m-gpio"); -- -- if (!gpio_np) -- return -ENODEV; -- -- err = of_address_to_resource(gpio_np, 0, &res); -- of_node_put(gpio_np); -- -- if (err) -- return -EINVAL; -- -- if (!gpio_regs) -- gpio_regs = ioremap(res.start, 0x100); -- -- if (!gpio_regs) -- return -EPERM; -- -+ err = -ENOMEM; - priv = kzalloc(sizeof(struct gpio_priv), GFP_KERNEL); -- if (priv == NULL) -- return -ENOMEM; -+ if (!priv) -+ goto out; - - new_bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL); - -- if (new_bus == NULL) -- return -ENOMEM; -+ if (!new_bus) -+ goto out_free_priv; - -- new_bus->name = "pasemi gpio mdio bus", -- new_bus->read = &gpio_mdio_read, -- new_bus->write = &gpio_mdio_write, -- new_bus->reset = &gpio_mdio_reset, -+ new_bus->name = "pasemi gpio mdio bus"; -+ new_bus->read = &gpio_mdio_read; -+ new_bus->write = &gpio_mdio_write; -+ new_bus->reset = &gpio_mdio_reset; - - prop = of_get_property(np, "reg", NULL); - new_bus->id = *prop; -@@ -265,9 +247,24 @@ static int __devinit gpio_mdio_probe(str - new_bus->phy_mask = 0; - - new_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL); -- for(i = 0; i < PHY_MAX_ADDR; ++i) -- new_bus->irq[i] = irq_create_mapping(NULL, 10); - -+ if (!new_bus->irq) -+ goto out_free_bus; -+ -+ for (i = 0; i < PHY_MAX_ADDR; i++) -+ new_bus->irq[i] = NO_IRQ; -+ -+ for (phy_dn = of_get_next_child(np, NULL); -+ phy_dn != NULL; -+ phy_dn = of_get_next_child(np, phy_dn)) { -+ const unsigned int *ip, *regp; -+ -+ ip = of_get_property(phy_dn, "interrupts", NULL); -+ regp = of_get_property(phy_dn, "reg", NULL); -+ if (!ip || !regp || *regp >= PHY_MAX_ADDR) -+ continue; -+ new_bus->irq[*regp] = irq_create_mapping(NULL, *ip); -+ } - - prop = of_get_property(np, "mdc-pin", NULL); - priv->mdc_pin = *prop; -@@ -280,17 +277,21 @@ static int __devinit gpio_mdio_probe(str - - err = mdiobus_register(new_bus); - -- if (0 != err) { -+ if (err != 0) { - printk(KERN_ERR "%s: Cannot register as MDIO bus, err %d\n", - new_bus->name, err); -- goto bus_register_fail; -+ goto out_free_irq; - } - - return 0; - --bus_register_fail: -+out_free_irq: -+ kfree(new_bus->irq); -+out_free_bus: - kfree(new_bus); -- -+out_free_priv: -+ kfree(priv); -+out: - return err; - } - -@@ -317,6 +318,7 @@ static struct of_device_id gpio_mdio_mat - }, - {}, - }; -+MODULE_DEVICE_TABLE(of, gpio_mdio_match); - - static struct of_platform_driver gpio_mdio_driver = - { -@@ -330,12 +332,32 @@ static struct of_platform_driver gpio_md - - int gpio_mdio_init(void) - { -+ struct device_node *np; -+ -+ np = of_find_compatible_node(NULL, NULL, "1682m-gpio"); -+ if (!np) -+ np = of_find_compatible_node(NULL, NULL, -+ "pasemi,pwrficient-gpio"); -+ if (!np) -+ return -ENODEV; -+ gpio_regs = of_iomap(np, 0); -+ of_node_put(np); -+ -+ if (!gpio_regs) -+ return -ENODEV; -+ - return of_register_platform_driver(&gpio_mdio_driver); - } -+module_init(gpio_mdio_init); - - void gpio_mdio_exit(void) - { - of_unregister_platform_driver(&gpio_mdio_driver); -+ if (gpio_regs) -+ iounmap(gpio_regs); - } --device_initcall(gpio_mdio_init); -+module_exit(gpio_mdio_exit); - -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Olof Johansson "); -+MODULE_DESCRIPTION("Driver for MDIO over GPIO on PA Semi PWRficient-based boards"); ---- a/arch/powerpc/platforms/pasemi/idle.c -+++ b/arch/powerpc/platforms/pasemi/idle.c -@@ -74,9 +74,6 @@ static int pasemi_system_reset_exception - - static int __init pasemi_idle_init(void) - { -- if (!machine_is(pasemi)) -- return -ENODEV; -- - #ifndef CONFIG_PPC_PASEMI_CPUFREQ - printk(KERN_WARNING "No cpufreq driver, powersavings modes disabled\n"); - current_mode = 0; -@@ -88,7 +85,7 @@ static int __init pasemi_idle_init(void) - - return 0; - } --late_initcall(pasemi_idle_init); -+machine_late_initcall(pasemi, pasemi_idle_init); - - static int __init idle_param(char *p) - { ---- a/arch/powerpc/platforms/pasemi/pasemi.h -+++ b/arch/powerpc/platforms/pasemi/pasemi.h -@@ -16,8 +16,14 @@ extern void idle_doze(void); - - /* Restore astate to last set */ - #ifdef CONFIG_PPC_PASEMI_CPUFREQ -+extern int check_astate(void); - extern void restore_astate(int cpu); - #else -+static inline int check_astate(void) -+{ -+ /* Always return >0 so we never power save */ -+ return 1; -+} - static inline void restore_astate(int cpu) - { - } ---- a/arch/powerpc/platforms/pasemi/powersave.S -+++ b/arch/powerpc/platforms/pasemi/powersave.S -@@ -62,7 +62,16 @@ sleep_common: - mflr r0 - std r0, 16(r1) - stdu r1,-64(r1) -+#ifdef CONFIG_PPC_PASEMI_CPUFREQ -+ std r3, 48(r1) - -+ /* Only do power savings when in astate 0 */ -+ bl .check_astate -+ cmpwi r3,0 -+ bne 1f -+ -+ ld r3, 48(r1) -+#endif - LOAD_REG_IMMEDIATE(r6,MSR_DR|MSR_IR|MSR_ME|MSR_EE) - mfmsr r4 - andc r5,r4,r6 -@@ -73,7 +82,7 @@ sleep_common: - - mtmsrd r4,0 - -- addi r1,r1,64 -+1: addi r1,r1,64 - ld r0,16(r1) - mtlr r0 - blr ---- a/arch/powerpc/platforms/pasemi/setup.c -+++ b/arch/powerpc/platforms/pasemi/setup.c -@@ -27,6 +27,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -35,7 +36,7 @@ - #include - #include - #include --#include -+#include - - #include - #include -@@ -43,6 +44,10 @@ - - #include "pasemi.h" - -+#if !defined(CONFIG_SMP) -+static void smp_send_stop(void) {} -+#endif -+ - /* SDC reset register, must be pre-mapped at reset time */ - static void __iomem *reset_reg; - -@@ -56,10 +61,14 @@ struct mce_regs { - - static struct mce_regs mce_regs[MAX_MCE_REGS]; - static int num_mce_regs; -+static int nmi_virq = NO_IRQ; - - - static void pas_restart(char *cmd) - { -+ /* Need to put others cpu in hold loop so they're not sleeping */ -+ smp_send_stop(); -+ udelay(10000); - printk("Restarting...\n"); - while (1) - out_le32(reset_reg, 0x6000000); -@@ -126,9 +135,6 @@ static int __init pas_setup_mce_regs(voi - struct pci_dev *dev; - int reg; - -- if (!machine_is(pasemi)) -- return -ENODEV; -- - /* Remap various SoC status registers for use by the MCE handler */ - - reg = 0; -@@ -172,7 +178,7 @@ static int __init pas_setup_mce_regs(voi - - return 0; - } --device_initcall(pas_setup_mce_regs); -+machine_device_initcall(pasemi, pas_setup_mce_regs); - - static __init void pas_init_IRQ(void) - { -@@ -181,6 +187,8 @@ static __init void pas_init_IRQ(void) - unsigned long openpic_addr; - const unsigned int *opprop; - int naddr, opplen; -+ int mpic_flags; -+ const unsigned int *nmiprop; - struct mpic *mpic; - - mpic_node = NULL; -@@ -213,13 +221,26 @@ static __init void pas_init_IRQ(void) - openpic_addr = of_read_number(opprop, naddr); - printk(KERN_DEBUG "OpenPIC addr: %lx\n", openpic_addr); - -+ mpic_flags = MPIC_PRIMARY | MPIC_LARGE_VECTORS | MPIC_NO_BIAS; -+ -+ nmiprop = of_get_property(mpic_node, "nmi-source", NULL); -+ if (nmiprop) -+ mpic_flags |= MPIC_ENABLE_MCK; -+ - mpic = mpic_alloc(mpic_node, openpic_addr, -- MPIC_PRIMARY|MPIC_LARGE_VECTORS, -- 0, 0, " PAS-OPIC "); -+ mpic_flags, 0, 0, "PASEMI-OPIC"); - BUG_ON(!mpic); - - mpic_assign_isu(mpic, 0, openpic_addr + 0x10000); - mpic_init(mpic); -+ /* The NMI/MCK source needs to be prio 15 */ -+ if (nmiprop) { -+ nmi_virq = irq_create_mapping(NULL, *nmiprop); -+ mpic_irq_set_priority(nmi_virq, 15); -+ set_irq_type(nmi_virq, IRQ_TYPE_EDGE_RISING); -+ mpic_unmask_irq(nmi_virq); -+ } -+ - of_node_put(mpic_node); - of_node_put(root); - } -@@ -239,6 +260,14 @@ static int pas_machine_check_handler(str - - srr0 = regs->nip; - srr1 = regs->msr; -+ -+ if (nmi_virq != NO_IRQ && mpic_get_mcirq() == nmi_virq) { -+ printk(KERN_ERR "NMI delivered\n"); -+ debugger(regs); -+ mpic_end_irq(nmi_virq); -+ goto out; -+ } -+ - dsisr = mfspr(SPRN_DSISR); - printk(KERN_ERR "Machine Check on CPU %d\n", cpu); - printk(KERN_ERR "SRR0 0x%016lx SRR1 0x%016lx\n", srr0, srr1); -@@ -295,14 +324,14 @@ static int pas_machine_check_handler(str - int i; - - printk(KERN_ERR "slb contents:\n"); -- for (i = 0; i < SLB_NUM_ENTRIES; i++) { -+ for (i = 0; i < mmu_slb_size; i++) { - asm volatile("slbmfee %0,%1" : "=r" (e) : "r" (i)); - asm volatile("slbmfev %0,%1" : "=r" (v) : "r" (i)); - printk(KERN_ERR "%02d %016lx %016lx\n", i, e, v); - } - } - -- -+out: - /* SRR1[62] is from MSR[62] if recoverable, so pass that back */ - return !!(srr1 & 0x2); - } -@@ -362,16 +391,17 @@ static inline void pasemi_pcmcia_init(vo - - - static struct of_device_id pasemi_bus_ids[] = { -+ /* Unfortunately needed for legacy firmwares */ - { .type = "localbus", }, - { .type = "sdc", }, -+ /* These are the proper entries, which newer firmware uses */ -+ { .compatible = "pasemi,localbus", }, -+ { .compatible = "pasemi,sdc", }, - {}, - }; - - static int __init pasemi_publish_devices(void) - { -- if (!machine_is(pasemi)) -- return 0; -- - pasemi_pcmcia_init(); - - /* Publish OF platform devices for SDC and other non-PCI devices */ -@@ -379,7 +409,7 @@ static int __init pasemi_publish_devices - - return 0; - } --device_initcall(pasemi_publish_devices); -+machine_device_initcall(pasemi, pasemi_publish_devices); - - - /* -@@ -389,7 +419,8 @@ static int __init pas_probe(void) - { - unsigned long root = of_get_flat_dt_root(); - -- if (!of_flat_dt_is_compatible(root, "PA6T-1682M")) -+ if (!of_flat_dt_is_compatible(root, "PA6T-1682M") && -+ !of_flat_dt_is_compatible(root, "pasemi,pwrficient")) - return 0; - - hpte_init_native(); -@@ -400,7 +431,7 @@ static int __init pas_probe(void) - } - - define_machine(pasemi) { -- .name = "PA Semi PA6T-1682M", -+ .name = "PA Semi PWRficient", - .probe = pas_probe, - .setup_arch = pas_setup_arch, - .init_early = pas_init_early, ---- a/arch/powerpc/platforms/powermac/low_i2c.c -+++ b/arch/powerpc/platforms/powermac/low_i2c.c -@@ -585,8 +585,7 @@ static void __init kw_i2c_probe(void) - struct device_node *np, *child, *parent; - - /* Probe keywest-i2c busses */ -- for (np = NULL; -- (np = of_find_compatible_node(np, "i2c","keywest-i2c")) != NULL;){ -+ for_each_compatible_node(np, "i2c","keywest-i2c") { - struct pmac_i2c_host_kw *host; - int multibus, chans, i; - -@@ -1462,9 +1461,6 @@ int __init pmac_i2c_init(void) - return 0; - i2c_inited = 1; - -- if (!machine_is(powermac)) -- return 0; -- - /* Probe keywest-i2c busses */ - kw_i2c_probe(); - -@@ -1483,7 +1479,7 @@ int __init pmac_i2c_init(void) - - return 0; - } --arch_initcall(pmac_i2c_init); -+machine_arch_initcall(powermac, pmac_i2c_init); - - /* Since pmac_i2c_init can be called too early for the platform device - * registration, we need to do it at a later time. In our case, subsys -@@ -1515,4 +1511,4 @@ static int __init pmac_i2c_create_platfo - - return 0; - } --subsys_initcall(pmac_i2c_create_platform_devices); -+machine_subsys_initcall(powermac, pmac_i2c_create_platform_devices); ---- a/arch/powerpc/platforms/powermac/pci.c -+++ b/arch/powerpc/platforms/powermac/pci.c -@@ -40,8 +40,6 @@ - static int has_uninorth; - #ifdef CONFIG_PPC64 - static struct pci_controller *u3_agp; --static struct pci_controller *u4_pcie; --static struct pci_controller *u3_ht; - #else - static int has_second_ohare; - #endif /* CONFIG_PPC64 */ -@@ -314,12 +312,15 @@ static int u3_ht_skip_device(struct pci_ - - /* We only allow config cycles to devices that are in OF device-tree - * as we are apparently having some weird things going on with some -- * revs of K2 on recent G5s -+ * revs of K2 on recent G5s, except for the host bridge itself, which -+ * is missing from the tree but we know we can probe. - */ - if (bus->self) - busdn = pci_device_to_OF_node(bus->self); -+ else if (devfn == 0) -+ return 0; - else -- busdn = hose->arch_data; -+ busdn = hose->dn; - for (dn = busdn->child; dn; dn = dn->sibling) - if (PCI_DN(dn) && PCI_DN(dn)->devfn == devfn) - break; -@@ -344,14 +345,15 @@ static int u3_ht_skip_device(struct pci_ - + (((unsigned int)bus) << 16) \ - + 0x01000000UL) - --static volatile void __iomem *u3_ht_cfg_access(struct pci_controller* hose, -- u8 bus, u8 devfn, u8 offset) -+static void __iomem *u3_ht_cfg_access(struct pci_controller *hose, u8 bus, -+ u8 devfn, u8 offset, int *swap) - { -+ *swap = 1; - if (bus == hose->first_busno) { -- /* For now, we don't self probe U3 HT bridge */ -- if (PCI_SLOT(devfn) == 0) -- return NULL; -- return hose->cfg_data + U3_HT_CFA0(devfn, offset); -+ if (devfn != 0) -+ return hose->cfg_data + U3_HT_CFA0(devfn, offset); -+ *swap = 0; -+ return ((void __iomem *)hose->cfg_addr) + (offset << 2); - } else - return hose->cfg_data + U3_HT_CFA1(bus, devfn, offset); - } -@@ -360,14 +362,15 @@ static int u3_ht_read_config(struct pci_ - int offset, int len, u32 *val) - { - struct pci_controller *hose; -- volatile void __iomem *addr; -+ void __iomem *addr; -+ int swap; - - hose = pci_bus_to_host(bus); - if (hose == NULL) - return PCIBIOS_DEVICE_NOT_FOUND; - if (offset >= 0x100) - return PCIBIOS_BAD_REGISTER_NUMBER; -- addr = u3_ht_cfg_access(hose, bus->number, devfn, offset); -+ addr = u3_ht_cfg_access(hose, bus->number, devfn, offset, &swap); - if (!addr) - return PCIBIOS_DEVICE_NOT_FOUND; - -@@ -397,10 +400,10 @@ static int u3_ht_read_config(struct pci_ - *val = in_8(addr); - break; - case 2: -- *val = in_le16(addr); -+ *val = swap ? in_le16(addr) : in_be16(addr); - break; - default: -- *val = in_le32(addr); -+ *val = swap ? in_le32(addr) : in_be32(addr); - break; - } - return PCIBIOS_SUCCESSFUL; -@@ -410,14 +413,15 @@ static int u3_ht_write_config(struct pci - int offset, int len, u32 val) - { - struct pci_controller *hose; -- volatile void __iomem *addr; -+ void __iomem *addr; -+ int swap; - - hose = pci_bus_to_host(bus); - if (hose == NULL) - return PCIBIOS_DEVICE_NOT_FOUND; - if (offset >= 0x100) - return PCIBIOS_BAD_REGISTER_NUMBER; -- addr = u3_ht_cfg_access(hose, bus->number, devfn, offset); -+ addr = u3_ht_cfg_access(hose, bus->number, devfn, offset, &swap); - if (!addr) - return PCIBIOS_DEVICE_NOT_FOUND; - -@@ -439,10 +443,10 @@ static int u3_ht_write_config(struct pci - out_8(addr, val); - break; - case 2: -- out_le16(addr, val); -+ swap ? out_le16(addr, val) : out_be16(addr, val); - break; - default: -- out_le32((u32 __iomem *)addr, val); -+ swap ? out_le32(addr, val) : out_be32(addr, val); - break; - } - return PCIBIOS_SUCCESSFUL; -@@ -725,7 +729,7 @@ static void __init setup_bandit(struct p - static int __init setup_uninorth(struct pci_controller *hose, - struct resource *addr) - { -- pci_assign_all_buses = 1; -+ ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS; - has_uninorth = 1; - hose->ops = ¯isc_pci_ops; - hose->cfg_addr = ioremap(addr->start + 0x800000, 0x1000); -@@ -773,31 +777,72 @@ static void __init setup_u4_pcie(struct - */ - hose->first_busno = 0x00; - hose->last_busno = 0xff; -- u4_pcie = hose; - } - --static void __init setup_u3_ht(struct pci_controller* hose) -+static void __init parse_region_decode(struct pci_controller *hose, -+ u32 decode) - { -- struct device_node *np = (struct device_node *)hose->arch_data; -- struct pci_controller *other = NULL; -- int i, cur; -+ unsigned long base, end, next = -1; -+ int i, cur = -1; - -+ /* Iterate through all bits. We ignore the last bit as this region is -+ * reserved for the ROM among other niceties -+ */ -+ for (i = 0; i < 31; i++) { -+ if ((decode & (0x80000000 >> i)) == 0) -+ continue; -+ if (i < 16) { -+ base = 0xf0000000 | (((u32)i) << 24); -+ end = base + 0x00ffffff; -+ } else { -+ base = ((u32)i-16) << 28; -+ end = base + 0x0fffffff; -+ } -+ if (base != next) { -+ if (++cur >= 3) { -+ printk(KERN_WARNING "PCI: Too many ranges !\n"); -+ break; -+ } -+ hose->mem_resources[cur].flags = IORESOURCE_MEM; -+ hose->mem_resources[cur].name = hose->dn->full_name; -+ hose->mem_resources[cur].start = base; -+ hose->mem_resources[cur].end = end; -+ DBG(" %d: 0x%08lx-0x%08lx\n", cur, base, end); -+ } else { -+ DBG(" : -0x%08lx\n", end); -+ hose->mem_resources[cur].end = end; -+ } -+ next = end + 1; -+ } -+} -+ -+static void __init setup_u3_ht(struct pci_controller* hose) -+{ -+ struct device_node *np = hose->dn; -+ struct resource cfg_res, self_res; -+ u32 decode; - - hose->ops = &u3_ht_pci_ops; - -- /* We hard code the address because of the different size of -- * the reg address cell, we shall fix that by killing struct -- * reg_property and using some accessor functions instead -+ /* Get base addresses from OF tree - */ -- hose->cfg_data = ioremap(0xf2000000, 0x02000000); -+ if (of_address_to_resource(np, 0, &cfg_res) || -+ of_address_to_resource(np, 1, &self_res)) { -+ printk(KERN_ERR "PCI: Failed to get U3/U4 HT resources !\n"); -+ return; -+ } -+ -+ /* Map external cfg space access into cfg_data and self registers -+ * into cfg_addr -+ */ -+ hose->cfg_data = ioremap(cfg_res.start, 0x02000000); -+ hose->cfg_addr = ioremap(self_res.start, -+ self_res.end - self_res.start + 1); - - /* -- * /ht node doesn't expose a "ranges" property, so we "remove" -- * regions that have been allocated to AGP. So far, this version of -- * the code doesn't assign any of the 0xfxxxxxxx "fine" memory regions -- * to /ht. We need to fix that sooner or later by either parsing all -- * child "ranges" properties or figuring out the U3 address space -- * decoding logic and then read its configuration register (if any). -+ * /ht node doesn't expose a "ranges" property, we read the register -+ * that controls the decoding logic and use that for memory regions. -+ * The IO region is hard coded since it is fixed in HW as well. - */ - hose->io_base_phys = 0xf4000000; - hose->pci_io_size = 0x00400000; -@@ -808,76 +853,33 @@ static void __init setup_u3_ht(struct pc - hose->pci_mem_offset = 0; - hose->first_busno = 0; - hose->last_busno = 0xef; -- hose->mem_resources[0].name = np->full_name; -- hose->mem_resources[0].start = 0x80000000; -- hose->mem_resources[0].end = 0xefffffff; -- hose->mem_resources[0].flags = IORESOURCE_MEM; -- -- u3_ht = hose; -- -- if (u3_agp != NULL) -- other = u3_agp; -- else if (u4_pcie != NULL) -- other = u4_pcie; - -- if (other == NULL) { -- DBG("U3/4 has no AGP/PCIE, using full resource range\n"); -- return; -- } -+ /* Note: fix offset when cfg_addr becomes a void * */ -+ decode = in_be32(hose->cfg_addr + 0x80); - -- /* Fixup bus range vs. PCIE */ -- if (u4_pcie) -- hose->last_busno = u4_pcie->first_busno - 1; -- -- /* We "remove" the AGP resources from the resources allocated to HT, -- * that is we create "holes". However, that code does assumptions -- * that so far happen to be true (cross fingers...), typically that -- * resources in the AGP node are properly ordered -- */ -- cur = 0; -- for (i=0; i<3; i++) { -- struct resource *res = &other->mem_resources[i]; -- if (res->flags != IORESOURCE_MEM) -- continue; -- /* We don't care about "fine" resources */ -- if (res->start >= 0xf0000000) -- continue; -- /* Check if it's just a matter of "shrinking" us in one -- * direction -- */ -- if (hose->mem_resources[cur].start == res->start) { -- DBG("U3/HT: shrink start of %d, %08lx -> %08lx\n", -- cur, hose->mem_resources[cur].start, -- res->end + 1); -- hose->mem_resources[cur].start = res->end + 1; -- continue; -- } -- if (hose->mem_resources[cur].end == res->end) { -- DBG("U3/HT: shrink end of %d, %08lx -> %08lx\n", -- cur, hose->mem_resources[cur].end, -- res->start - 1); -- hose->mem_resources[cur].end = res->start - 1; -- continue; -- } -- /* No, it's not the case, we need a hole */ -- if (cur == 2) { -- /* not enough resources for a hole, we drop part -- * of the range -- */ -- printk(KERN_WARNING "Running out of resources" -- " for /ht host !\n"); -- hose->mem_resources[cur].end = res->start - 1; -- continue; -- } -- cur++; -- DBG("U3/HT: hole, %d end at %08lx, %d start at %08lx\n", -- cur-1, res->start - 1, cur, res->end + 1); -- hose->mem_resources[cur].name = np->full_name; -- hose->mem_resources[cur].flags = IORESOURCE_MEM; -- hose->mem_resources[cur].start = res->end + 1; -- hose->mem_resources[cur].end = hose->mem_resources[cur-1].end; -- hose->mem_resources[cur-1].end = res->start - 1; -- } -+ DBG("PCI: Apple HT bridge decode register: 0x%08x\n", decode); -+ -+ /* NOTE: The decode register setup is a bit weird... region -+ * 0xf8000000 for example is marked as enabled in there while it's -+ & actually the memory controller registers. -+ * That means that we are incorrectly attributing it to HT. -+ * -+ * In a similar vein, region 0xf4000000 is actually the HT IO space but -+ * also marked as enabled in here and 0xf9000000 is used by some other -+ * internal bits of the northbridge. -+ * -+ * Unfortunately, we can't just mask out those bit as we would end -+ * up with more regions than we can cope (linux can only cope with -+ * 3 memory regions for a PHB at this stage). -+ * -+ * So for now, we just do a little hack. We happen to -know- that -+ * Apple firmware doesn't assign things below 0xfa000000 for that -+ * bridge anyway so we mask out all bits we don't want. -+ */ -+ decode &= 0x003fffff; -+ -+ /* Now parse the resulting bits and build resources */ -+ parse_region_decode(hose, decode); - } - #endif /* CONFIG_PPC64 */ - -@@ -994,6 +996,8 @@ void __init pmac_pci_init(void) - struct device_node *np, *root; - struct device_node *ht = NULL; - -+ ppc_pci_flags = PPC_PCI_CAN_SKIP_ISA_ALIGN; -+ - root = of_find_node_by_path("/"); - if (root == NULL) { - printk(KERN_CRIT "pmac_pci_init: can't find root " -@@ -1032,15 +1036,15 @@ void __init pmac_pci_init(void) - * future though - */ - if (u3_agp) { -- struct device_node *np = u3_agp->arch_data; -+ struct device_node *np = u3_agp->dn; - PCI_DN(np)->busno = 0xf0; - for (np = np->child; np; np = np->sibling) - PCI_DN(np)->busno = 0xf0; - } - /* pmac_check_ht_link(); */ - -- /* Tell pci.c to not use the common resource allocation mechanism */ -- pci_probe_only = 1; -+ /* We can allocate missing resources if any */ -+ pci_probe_only = 0; - - #else /* CONFIG_PPC64 */ - init_p2pbridge(); -@@ -1051,13 +1055,13 @@ void __init pmac_pci_init(void) - * some offset between bus number and domains for now when we - * assign all busses should help for now - */ -- if (pci_assign_all_buses) -+ if (ppc_pci_flags & PPC_PCI_REASSIGN_ALL_BUS) - pcibios_assign_bus_offset = 0x10; - #endif - } - --int --pmac_pci_enable_device_hook(struct pci_dev *dev, int initial) -+#ifdef CONFIG_PPC32 -+int pmac_pci_enable_device_hook(struct pci_dev *dev) - { - struct device_node* node; - int updatecfg = 0; -@@ -1099,24 +1103,21 @@ pmac_pci_enable_device_hook(struct pci_d - updatecfg = 1; - } - -+ /* -+ * Fixup various header fields on 32 bits. We don't do that on -+ * 64 bits as some of these have strange values behind the HT -+ * bridge and we must not, for example, enable MWI or set the -+ * cache line size on them. -+ */ - if (updatecfg) { - u16 cmd; - -- /* -- * Make sure PCI is correctly configured -- * -- * We use old pci_bios versions of the function since, by -- * default, gmac is not powered up, and so will be absent -- * from the kernel initial PCI lookup. -- * -- * Should be replaced by 2.4 new PCI mechanisms and really -- * register the device. -- */ - pci_read_config_word(dev, PCI_COMMAND, &cmd); - cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER - | PCI_COMMAND_INVALIDATE; - pci_write_config_word(dev, PCI_COMMAND, cmd); - pci_write_config_byte(dev, PCI_LATENCY_TIMER, 16); -+ - pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, - L1_CACHE_BYTES >> 2); - } -@@ -1124,6 +1125,18 @@ pmac_pci_enable_device_hook(struct pci_d - return 0; - } - -+void __devinit pmac_pci_fixup_ohci(struct pci_dev *dev) -+{ -+ struct device_node *node = pci_device_to_OF_node(dev); -+ -+ /* We don't want to assign resources to USB controllers -+ * absent from the OF tree (iBook second controller) -+ */ -+ if (dev->class == PCI_CLASS_SERIAL_USB_OHCI && !node) -+ dev->resource[0].flags = 0; -+} -+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_APPLE, PCI_ANY_ID, pmac_pci_fixup_ohci); -+ - /* We power down some devices after they have been probed. They'll - * be powered back on later on - */ -@@ -1171,7 +1184,6 @@ void __init pmac_pcibios_after_init(void - of_node_put(nd); - } - --#ifdef CONFIG_PPC32 - void pmac_pci_fixup_cardbus(struct pci_dev* dev) - { - if (!machine_is(powermac)) -@@ -1259,7 +1271,7 @@ void pmac_pci_fixup_pciata(struct pci_de - } - } - DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, pmac_pci_fixup_pciata); --#endif -+#endif /* CONFIG_PPC32 */ - - /* - * Disable second function on K2-SATA, it's broken ---- a/arch/powerpc/platforms/powermac/pfunc_base.c -+++ b/arch/powerpc/platforms/powermac/pfunc_base.c -@@ -363,8 +363,7 @@ int __init pmac_pfunc_base_install(void) - - return 0; - } -- --arch_initcall(pmac_pfunc_base_install); -+machine_arch_initcall(powermac, pmac_pfunc_base_install); - - #ifdef CONFIG_PM - ---- a/arch/powerpc/platforms/powermac/pic.c -+++ b/arch/powerpc/platforms/powermac/pic.c -@@ -690,6 +690,5 @@ static int __init init_pmacpic_sysfs(voi - sysdev_driver_register(&pmacpic_sysclass, &driver_pmacpic); - return 0; - } -- --subsys_initcall(init_pmacpic_sysfs); -+machine_subsys_initcall(powermac, init_pmacpic_sysfs); - ---- a/arch/powerpc/platforms/powermac/pmac.h -+++ b/arch/powerpc/platforms/powermac/pmac.h -@@ -26,7 +26,7 @@ extern void pmac_pci_init(void); - extern void pmac_nvram_update(void); - extern unsigned char pmac_nvram_read_byte(int addr); - extern void pmac_nvram_write_byte(int addr, unsigned char val); --extern int pmac_pci_enable_device_hook(struct pci_dev *dev, int initial); -+extern int pmac_pci_enable_device_hook(struct pci_dev *dev); - extern void pmac_pcibios_after_init(void); - extern int of_show_percpuinfo(struct seq_file *m, int i); - ---- a/arch/powerpc/platforms/powermac/setup.c -+++ b/arch/powerpc/platforms/powermac/setup.c -@@ -51,6 +51,8 @@ - #include - #include - #include -+#include -+#include - - #include - #include -@@ -68,8 +70,6 @@ - #include - #include - #include --#include --#include - #include - #include - #include -@@ -94,7 +94,6 @@ extern struct machdep_calls pmac_md; - #define DEFAULT_ROOT_DEVICE Root_SDA1 /* sda1 - slightly silly choice */ - - #ifdef CONFIG_PPC64 --#include - int sccdbg; - #endif - -@@ -398,17 +397,13 @@ static int initializing = 1; - - static int pmac_late_init(void) - { -- if (!machine_is(powermac)) -- return -ENODEV; -- - initializing = 0; - /* this is udbg (which is __init) and we can later use it during - * cpu hotplug (in smp_core99_kick_cpu) */ - ppc_md.progress = NULL; - return 0; - } -- --late_initcall(pmac_late_init); -+machine_late_initcall(powermac, pmac_late_init); - - /* - * This is __init_refok because we check for "initializing" before -@@ -535,9 +530,6 @@ static int __init pmac_declare_of_platfo - if (machine_is(chrp)) - return -1; - -- if (!machine_is(powermac)) -- return 0; -- - np = of_find_node_by_name(NULL, "valkyrie"); - if (np) - of_platform_device_create(np, "valkyrie", NULL); -@@ -552,8 +544,7 @@ static int __init pmac_declare_of_platfo - - return 0; - } -- --device_initcall(pmac_declare_of_platform_devices); -+machine_device_initcall(powermac, pmac_declare_of_platform_devices); - - /* - * Called very early, MMU is off, device-tree isn't unflattened -@@ -613,9 +604,11 @@ static int pmac_pci_probe_mode(struct pc - - /* We need to use normal PCI probing for the AGP bus, - * since the device for the AGP bridge isn't in the tree. -+ * Same for the PCIe host on U4 and the HT host bridge. - */ - if (bus->self == NULL && (of_device_is_compatible(node, "u3-agp") || -- of_device_is_compatible(node, "u4-pcie"))) -+ of_device_is_compatible(node, "u4-pcie") || -+ of_device_is_compatible(node, "u3-ht"))) - return PCI_PROBE_NORMAL; - return PCI_PROBE_DEVTREE; - } ---- a/arch/powerpc/platforms/powermac/time.c -+++ b/arch/powerpc/platforms/powermac/time.c -@@ -84,12 +84,14 @@ long __init pmac_time_init(void) - return delta; - } - -+#if defined(CONFIG_ADB_CUDA) || defined(CONFIG_ADB_PMU) - static void to_rtc_time(unsigned long now, struct rtc_time *tm) - { - to_tm(now, tm); - tm->tm_year -= 1900; - tm->tm_mon -= 1; - } -+#endif - - static unsigned long from_rtc_time(struct rtc_time *tm) - { ---- a/arch/powerpc/platforms/ps3/Kconfig -+++ b/arch/powerpc/platforms/ps3/Kconfig -@@ -61,17 +61,6 @@ config PS3_DYNAMIC_DMA - This support is mainly for Linux kernel development. If unsure, - say N. - --config PS3_USE_LPAR_ADDR -- depends on PPC_PS3 && EXPERIMENTAL -- bool "PS3 use lpar address space" -- default y -- help -- This option is solely for experimentation by experts. Disables -- translation of lpar addresses. SPE support currently won't work -- without this set to y. -- -- If you have any doubt, choose the default y. -- - config PS3_VUART - depends on PPC_PS3 - tristate -@@ -138,4 +127,17 @@ config PS3_FLASH - be disabled on the kernel command line using "ps3flash=off", to - not allocate this fixed buffer. - -+config PS3_LPM -+ tristate "PS3 Logical Performance Monitor support" -+ depends on PPC_PS3 -+ help -+ Include support for the PS3 Logical Performance Monitor. -+ -+ This support is required to use the logical performance monitor -+ of the PS3's LV1 hypervisor. -+ -+ If you intend to use the advanced performance monitoring and -+ profiling support of the Cell processor with programs like -+ oprofile and perfmon2, then say Y or M, otherwise say N. -+ - endmenu ---- a/arch/powerpc/platforms/ps3/device-init.c -+++ b/arch/powerpc/platforms/ps3/device-init.c -@@ -23,6 +23,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -30,6 +31,89 @@ - - #include "platform.h" - -+static int __init ps3_register_lpm_devices(void) -+{ -+ int result; -+ u64 tmp1; -+ u64 tmp2; -+ struct ps3_system_bus_device *dev; -+ -+ pr_debug(" -> %s:%d\n", __func__, __LINE__); -+ -+ dev = kzalloc(sizeof(*dev), GFP_KERNEL); -+ if (!dev) -+ return -ENOMEM; -+ -+ dev->match_id = PS3_MATCH_ID_LPM; -+ dev->dev_type = PS3_DEVICE_TYPE_LPM; -+ -+ /* The current lpm driver only supports a single BE processor. */ -+ -+ result = ps3_repository_read_be_node_id(0, &dev->lpm.node_id); -+ -+ if (result) { -+ pr_debug("%s:%d: ps3_repository_read_be_node_id failed \n", -+ __func__, __LINE__); -+ goto fail_read_repo; -+ } -+ -+ result = ps3_repository_read_lpm_privileges(dev->lpm.node_id, &tmp1, -+ &dev->lpm.rights); -+ -+ if (result) { -+ pr_debug("%s:%d: ps3_repository_read_lpm_privleges failed \n", -+ __func__, __LINE__); -+ goto fail_read_repo; -+ } -+ -+ lv1_get_logical_partition_id(&tmp2); -+ -+ if (tmp1 != tmp2) { -+ pr_debug("%s:%d: wrong lpar\n", -+ __func__, __LINE__); -+ result = -ENODEV; -+ goto fail_rights; -+ } -+ -+ if (!(dev->lpm.rights & PS3_LPM_RIGHTS_USE_LPM)) { -+ pr_debug("%s:%d: don't have rights to use lpm\n", -+ __func__, __LINE__); -+ result = -EPERM; -+ goto fail_rights; -+ } -+ -+ pr_debug("%s:%d: pu_id %lu, rights %lu(%lxh)\n", -+ __func__, __LINE__, dev->lpm.pu_id, dev->lpm.rights, -+ dev->lpm.rights); -+ -+ result = ps3_repository_read_pu_id(0, &dev->lpm.pu_id); -+ -+ if (result) { -+ pr_debug("%s:%d: ps3_repository_read_pu_id failed \n", -+ __func__, __LINE__); -+ goto fail_read_repo; -+ } -+ -+ result = ps3_system_bus_device_register(dev); -+ -+ if (result) { -+ pr_debug("%s:%d ps3_system_bus_device_register failed\n", -+ __func__, __LINE__); -+ goto fail_register; -+ } -+ -+ pr_debug(" <- %s:%d\n", __func__, __LINE__); -+ return 0; -+ -+ -+fail_register: -+fail_rights: -+fail_read_repo: -+ kfree(dev); -+ pr_debug(" <- %s:%d: failed\n", __func__, __LINE__); -+ return result; -+} -+ - /** - * ps3_setup_gelic_device - Setup and register a gelic device instance. - * -@@ -238,166 +322,6 @@ static int __init ps3_setup_vuart_device - return result; - } - --static int ps3stor_wait_for_completion(u64 dev_id, u64 tag, -- unsigned int timeout) --{ -- int result = -1; -- unsigned int retries = 0; -- u64 status; -- -- for (retries = 0; retries < timeout; retries++) { -- result = lv1_storage_check_async_status(dev_id, tag, &status); -- if (!result) -- break; -- -- msleep(1); -- } -- -- if (result) -- pr_debug("%s:%u: check_async_status: %s, status %lx\n", -- __func__, __LINE__, ps3_result(result), status); -- -- return result; --} -- --/** -- * ps3_storage_wait_for_device - Wait for a storage device to become ready. -- * @repo: The repository device to wait for. -- * -- * Uses the hypervisor's storage device notification mechanism to wait until -- * a storage device is ready. The device notification mechanism uses a -- * psuedo device (id = -1) to asynchronously notify the guest when storage -- * devices become ready. The notification device has a block size of 512 -- * bytes. -- */ -- --static int ps3_storage_wait_for_device(const struct ps3_repository_device *repo) --{ -- int error = -ENODEV; -- int result; -- const u64 notification_dev_id = (u64)-1LL; -- const unsigned int timeout = HZ; -- u64 lpar; -- u64 tag; -- void *buf; -- enum ps3_notify_type { -- notify_device_ready = 0, -- notify_region_probe = 1, -- notify_region_update = 2, -- }; -- struct { -- u64 operation_code; /* must be zero */ -- u64 event_mask; /* OR of 1UL << enum ps3_notify_type */ -- } *notify_cmd; -- struct { -- u64 event_type; /* enum ps3_notify_type */ -- u64 bus_id; -- u64 dev_id; -- u64 dev_type; -- u64 dev_port; -- } *notify_event; -- -- pr_debug(" -> %s:%u: (%u:%u:%u)\n", __func__, __LINE__, repo->bus_id, -- repo->dev_id, repo->dev_type); -- -- buf = kzalloc(512, GFP_KERNEL); -- if (!buf) -- return -ENOMEM; -- -- lpar = ps3_mm_phys_to_lpar(__pa(buf)); -- notify_cmd = buf; -- notify_event = buf; -- -- result = lv1_open_device(repo->bus_id, notification_dev_id, 0); -- if (result) { -- printk(KERN_ERR "%s:%u: lv1_open_device %s\n", __func__, -- __LINE__, ps3_result(result)); -- goto fail_free; -- } -- -- /* Setup and write the request for device notification. */ -- -- notify_cmd->operation_code = 0; /* must be zero */ -- notify_cmd->event_mask = 1UL << notify_region_probe; -- -- result = lv1_storage_write(notification_dev_id, 0, 0, 1, 0, lpar, -- &tag); -- if (result) { -- printk(KERN_ERR "%s:%u: write failed %s\n", __func__, __LINE__, -- ps3_result(result)); -- goto fail_close; -- } -- -- /* Wait for the write completion */ -- -- result = ps3stor_wait_for_completion(notification_dev_id, tag, -- timeout); -- if (result) { -- printk(KERN_ERR "%s:%u: write not completed %s\n", __func__, -- __LINE__, ps3_result(result)); -- goto fail_close; -- } -- -- /* Loop here processing the requested notification events. */ -- -- while (1) { -- memset(notify_event, 0, sizeof(*notify_event)); -- -- result = lv1_storage_read(notification_dev_id, 0, 0, 1, 0, -- lpar, &tag); -- if (result) { -- printk(KERN_ERR "%s:%u: write failed %s\n", __func__, -- __LINE__, ps3_result(result)); -- break; -- } -- -- result = ps3stor_wait_for_completion(notification_dev_id, tag, -- timeout); -- if (result) { -- printk(KERN_ERR "%s:%u: read not completed %s\n", -- __func__, __LINE__, ps3_result(result)); -- break; -- } -- -- pr_debug("%s:%d: notify event (%u:%u:%u): event_type 0x%lx, " -- "port %lu\n", __func__, __LINE__, repo->bus_index, -- repo->dev_index, repo->dev_type, -- notify_event->event_type, notify_event->dev_port); -- -- if (notify_event->event_type != notify_region_probe || -- notify_event->bus_id != repo->bus_id) { -- pr_debug("%s:%u: bad notify_event: event %lu, " -- "dev_id %lu, dev_type %lu\n", -- __func__, __LINE__, notify_event->event_type, -- notify_event->dev_id, notify_event->dev_type); -- break; -- } -- -- if (notify_event->dev_id == repo->dev_id && -- notify_event->dev_type == repo->dev_type) { -- pr_debug("%s:%u: device ready (%u:%u:%u)\n", __func__, -- __LINE__, repo->bus_index, repo->dev_index, -- repo->dev_type); -- error = 0; -- break; -- } -- -- if (notify_event->dev_id == repo->dev_id && -- notify_event->dev_type == PS3_DEV_TYPE_NOACCESS) { -- pr_debug("%s:%u: no access: dev_id %u\n", __func__, -- __LINE__, repo->dev_id); -- break; -- } -- } -- --fail_close: -- lv1_close_device(repo->bus_id, notification_dev_id); --fail_free: -- kfree(buf); -- pr_debug(" <- %s:%u\n", __func__, __LINE__); -- return error; --} -- - static int ps3_setup_storage_dev(const struct ps3_repository_device *repo, - enum ps3_match_id match_id) - { -@@ -449,16 +373,6 @@ static int ps3_setup_storage_dev(const s - goto fail_find_interrupt; - } - -- /* FIXME: Arrange to only do this on a 'cold' boot */ -- -- result = ps3_storage_wait_for_device(repo); -- if (result) { -- printk(KERN_ERR "%s:%u: storage_notification failed %d\n", -- __func__, __LINE__, result); -- result = -ENODEV; -- goto fail_probe_notification; -- } -- - for (i = 0; i < num_regions; i++) { - unsigned int id; - u64 start, size; -@@ -494,7 +408,6 @@ static int ps3_setup_storage_dev(const s - - fail_device_register: - fail_read_region: --fail_probe_notification: - fail_find_interrupt: - kfree(p); - fail_malloc: -@@ -659,62 +572,268 @@ static int ps3_register_repository_devic - return result; - } - -+static void ps3_find_and_add_device(u64 bus_id, u64 dev_id) -+{ -+ struct ps3_repository_device repo; -+ int res; -+ unsigned int retries; -+ unsigned long rem; -+ -+ /* -+ * On some firmware versions (e.g. 1.90), the device may not show up -+ * in the repository immediately -+ */ -+ for (retries = 0; retries < 10; retries++) { -+ res = ps3_repository_find_device_by_id(&repo, bus_id, dev_id); -+ if (!res) -+ goto found; -+ -+ rem = msleep_interruptible(100); -+ if (rem) -+ break; -+ } -+ pr_warning("%s:%u: device %lu:%lu not found\n", __func__, __LINE__, -+ bus_id, dev_id); -+ return; -+ -+found: -+ if (retries) -+ pr_debug("%s:%u: device %lu:%lu found after %u retries\n", -+ __func__, __LINE__, bus_id, dev_id, retries); -+ -+ ps3_register_repository_device(&repo); -+ return; -+} -+ -+#define PS3_NOTIFICATION_DEV_ID ULONG_MAX -+#define PS3_NOTIFICATION_INTERRUPT_ID 0 -+ -+struct ps3_notification_device { -+ struct ps3_system_bus_device sbd; -+ spinlock_t lock; -+ u64 tag; -+ u64 lv1_status; -+ struct completion done; -+}; -+ -+enum ps3_notify_type { -+ notify_device_ready = 0, -+ notify_region_probe = 1, -+ notify_region_update = 2, -+}; -+ -+struct ps3_notify_cmd { -+ u64 operation_code; /* must be zero */ -+ u64 event_mask; /* OR of 1UL << enum ps3_notify_type */ -+}; -+ -+struct ps3_notify_event { -+ u64 event_type; /* enum ps3_notify_type */ -+ u64 bus_id; -+ u64 dev_id; -+ u64 dev_type; -+ u64 dev_port; -+}; -+ -+static irqreturn_t ps3_notification_interrupt(int irq, void *data) -+{ -+ struct ps3_notification_device *dev = data; -+ int res; -+ u64 tag, status; -+ -+ spin_lock(&dev->lock); -+ res = lv1_storage_get_async_status(PS3_NOTIFICATION_DEV_ID, &tag, -+ &status); -+ if (tag != dev->tag) -+ pr_err("%s:%u: tag mismatch, got %lx, expected %lx\n", -+ __func__, __LINE__, tag, dev->tag); -+ -+ if (res) { -+ pr_err("%s:%u: res %d status 0x%lx\n", __func__, __LINE__, res, -+ status); -+ } else { -+ pr_debug("%s:%u: completed, status 0x%lx\n", __func__, -+ __LINE__, status); -+ dev->lv1_status = status; -+ complete(&dev->done); -+ } -+ spin_unlock(&dev->lock); -+ return IRQ_HANDLED; -+} -+ -+static int ps3_notification_read_write(struct ps3_notification_device *dev, -+ u64 lpar, int write) -+{ -+ const char *op = write ? "write" : "read"; -+ unsigned long flags; -+ int res; -+ -+ init_completion(&dev->done); -+ spin_lock_irqsave(&dev->lock, flags); -+ res = write ? lv1_storage_write(dev->sbd.dev_id, 0, 0, 1, 0, lpar, -+ &dev->tag) -+ : lv1_storage_read(dev->sbd.dev_id, 0, 0, 1, 0, lpar, -+ &dev->tag); -+ spin_unlock_irqrestore(&dev->lock, flags); -+ if (res) { -+ pr_err("%s:%u: %s failed %d\n", __func__, __LINE__, op, res); -+ return -EPERM; -+ } -+ pr_debug("%s:%u: notification %s issued\n", __func__, __LINE__, op); -+ -+ res = wait_event_interruptible(dev->done.wait, -+ dev->done.done || kthread_should_stop()); -+ if (kthread_should_stop()) -+ res = -EINTR; -+ if (res) { -+ pr_debug("%s:%u: interrupted %s\n", __func__, __LINE__, op); -+ return res; -+ } -+ -+ if (dev->lv1_status) { -+ pr_err("%s:%u: %s not completed, status 0x%lx\n", __func__, -+ __LINE__, op, dev->lv1_status); -+ return -EIO; -+ } -+ pr_debug("%s:%u: notification %s completed\n", __func__, __LINE__, op); -+ -+ return 0; -+} -+ -+static struct task_struct *probe_task; -+ - /** - * ps3_probe_thread - Background repository probing at system startup. - * - * This implementation only supports background probing on a single bus. -+ * It uses the hypervisor's storage device notification mechanism to wait until -+ * a storage device is ready. The device notification mechanism uses a -+ * pseudo device to asynchronously notify the guest when storage devices become -+ * ready. The notification device has a block size of 512 bytes. - */ - - static int ps3_probe_thread(void *data) - { -- struct ps3_repository_device *repo = data; -- int result; -- unsigned int ms = 250; -+ struct ps3_notification_device dev; -+ int res; -+ unsigned int irq; -+ u64 lpar; -+ void *buf; -+ struct ps3_notify_cmd *notify_cmd; -+ struct ps3_notify_event *notify_event; - - pr_debug(" -> %s:%u: kthread started\n", __func__, __LINE__); - -- do { -- try_to_freeze(); -+ buf = kzalloc(512, GFP_KERNEL); -+ if (!buf) -+ return -ENOMEM; - -- pr_debug("%s:%u: probing...\n", __func__, __LINE__); -+ lpar = ps3_mm_phys_to_lpar(__pa(buf)); -+ notify_cmd = buf; -+ notify_event = buf; -+ -+ /* dummy system bus device */ -+ dev.sbd.bus_id = (u64)data; -+ dev.sbd.dev_id = PS3_NOTIFICATION_DEV_ID; -+ dev.sbd.interrupt_id = PS3_NOTIFICATION_INTERRUPT_ID; -+ -+ res = lv1_open_device(dev.sbd.bus_id, dev.sbd.dev_id, 0); -+ if (res) { -+ pr_err("%s:%u: lv1_open_device failed %s\n", __func__, -+ __LINE__, ps3_result(res)); -+ goto fail_free; -+ } -+ -+ res = ps3_sb_event_receive_port_setup(&dev.sbd, PS3_BINDING_CPU_ANY, -+ &irq); -+ if (res) { -+ pr_err("%s:%u: ps3_sb_event_receive_port_setup failed %d\n", -+ __func__, __LINE__, res); -+ goto fail_close_device; -+ } -+ -+ spin_lock_init(&dev.lock); -+ -+ res = request_irq(irq, ps3_notification_interrupt, IRQF_DISABLED, -+ "ps3_notification", &dev); -+ if (res) { -+ pr_err("%s:%u: request_irq failed %d\n", __func__, __LINE__, -+ res); -+ goto fail_sb_event_receive_port_destroy; -+ } -+ -+ /* Setup and write the request for device notification. */ -+ notify_cmd->operation_code = 0; /* must be zero */ -+ notify_cmd->event_mask = 1UL << notify_region_probe; - -- do { -- result = ps3_repository_find_device(repo); -+ res = ps3_notification_read_write(&dev, lpar, 1); -+ if (res) -+ goto fail_free_irq; - -- if (result == -ENODEV) -- pr_debug("%s:%u: nothing new\n", __func__, -- __LINE__); -- else if (result) -- pr_debug("%s:%u: find device error.\n", -- __func__, __LINE__); -- else { -- pr_debug("%s:%u: found device (%u:%u:%u)\n", -- __func__, __LINE__, repo->bus_index, -- repo->dev_index, repo->dev_type); -- ps3_register_repository_device(repo); -- ps3_repository_bump_device(repo); -- ms = 250; -- } -- } while (!result); -+ /* Loop here processing the requested notification events. */ -+ do { -+ try_to_freeze(); - -- pr_debug("%s:%u: ms %u\n", __func__, __LINE__, ms); -+ memset(notify_event, 0, sizeof(*notify_event)); - -- if ( ms > 60000) -+ res = ps3_notification_read_write(&dev, lpar, 0); -+ if (res) - break; - -- msleep_interruptible(ms); -+ pr_debug("%s:%u: notify event type 0x%lx bus id %lu dev id %lu" -+ " type %lu port %lu\n", __func__, __LINE__, -+ notify_event->event_type, notify_event->bus_id, -+ notify_event->dev_id, notify_event->dev_type, -+ notify_event->dev_port); -+ -+ if (notify_event->event_type != notify_region_probe || -+ notify_event->bus_id != dev.sbd.bus_id) { -+ pr_warning("%s:%u: bad notify_event: event %lu, " -+ "dev_id %lu, dev_type %lu\n", -+ __func__, __LINE__, notify_event->event_type, -+ notify_event->dev_id, -+ notify_event->dev_type); -+ continue; -+ } - -- /* An exponential backoff. */ -- ms <<= 1; -+ ps3_find_and_add_device(dev.sbd.bus_id, notify_event->dev_id); - - } while (!kthread_should_stop()); - -+fail_free_irq: -+ free_irq(irq, &dev); -+fail_sb_event_receive_port_destroy: -+ ps3_sb_event_receive_port_destroy(&dev.sbd, irq); -+fail_close_device: -+ lv1_close_device(dev.sbd.bus_id, dev.sbd.dev_id); -+fail_free: -+ kfree(buf); -+ -+ probe_task = NULL; -+ - pr_debug(" <- %s:%u: kthread finished\n", __func__, __LINE__); - - return 0; - } - - /** -+ * ps3_stop_probe_thread - Stops the background probe thread. -+ * -+ */ -+ -+static int ps3_stop_probe_thread(struct notifier_block *nb, unsigned long code, -+ void *data) -+{ -+ if (probe_task) -+ kthread_stop(probe_task); -+ return 0; -+} -+ -+static struct notifier_block nb = { -+ .notifier_call = ps3_stop_probe_thread -+}; -+ -+/** - * ps3_start_probe_thread - Starts the background probe thread. - * - */ -@@ -723,7 +842,7 @@ static int __init ps3_start_probe_thread - { - int result; - struct task_struct *task; -- static struct ps3_repository_device repo; /* must be static */ -+ struct ps3_repository_device repo; - - pr_debug(" -> %s:%d\n", __func__, __LINE__); - -@@ -746,7 +865,8 @@ static int __init ps3_start_probe_thread - return -ENODEV; - } - -- task = kthread_run(ps3_probe_thread, &repo, "ps3-probe-%u", bus_type); -+ task = kthread_run(ps3_probe_thread, (void *)repo.bus_id, -+ "ps3-probe-%u", bus_type); - - if (IS_ERR(task)) { - result = PTR_ERR(task); -@@ -755,6 +875,9 @@ static int __init ps3_start_probe_thread - return result; - } - -+ probe_task = task; -+ register_reboot_notifier(&nb); -+ - pr_debug(" <- %s:%d\n", __func__, __LINE__); - return 0; - } -@@ -787,6 +910,8 @@ static int __init ps3_register_devices(v - - ps3_register_sound_devices(); - -+ ps3_register_lpm_devices(); -+ - pr_debug(" <- %s:%d\n", __func__, __LINE__); - return 0; - } ---- a/arch/powerpc/platforms/ps3/mm.c -+++ b/arch/powerpc/platforms/ps3/mm.c -@@ -36,11 +36,6 @@ - #endif - - enum { --#if defined(CONFIG_PS3_USE_LPAR_ADDR) -- USE_LPAR_ADDR = 1, --#else -- USE_LPAR_ADDR = 0, --#endif - #if defined(CONFIG_PS3_DYNAMIC_DMA) - USE_DYNAMIC_DMA = 1, - #else -@@ -137,11 +132,8 @@ static struct map map; - unsigned long ps3_mm_phys_to_lpar(unsigned long phys_addr) - { - BUG_ON(is_kernel_addr(phys_addr)); -- if (USE_LPAR_ADDR) -- return phys_addr; -- else -- return (phys_addr < map.rm.size || phys_addr >= map.total) -- ? phys_addr : phys_addr + map.r1.offset; -+ return (phys_addr < map.rm.size || phys_addr >= map.total) -+ ? phys_addr : phys_addr + map.r1.offset; - } - - EXPORT_SYMBOL(ps3_mm_phys_to_lpar); -@@ -309,7 +301,7 @@ static int __init ps3_mm_add_memory(void - - BUG_ON(!mem_init_done); - -- start_addr = USE_LPAR_ADDR ? map.r1.base : map.rm.size; -+ start_addr = map.rm.size; - start_pfn = start_addr >> PAGE_SHIFT; - nr_pages = (map.r1.size + PAGE_SIZE - 1) >> PAGE_SHIFT; - -@@ -359,7 +351,7 @@ static unsigned long dma_sb_lpar_to_bus( - static void __maybe_unused _dma_dump_region(const struct ps3_dma_region *r, - const char *func, int line) - { -- DBG("%s:%d: dev %u:%u\n", func, line, r->dev->bus_id, -+ DBG("%s:%d: dev %lu:%lu\n", func, line, r->dev->bus_id, - r->dev->dev_id); - DBG("%s:%d: page_size %u\n", func, line, r->page_size); - DBG("%s:%d: bus_addr %lxh\n", func, line, r->bus_addr); -@@ -394,7 +386,7 @@ struct dma_chunk { - static void _dma_dump_chunk (const struct dma_chunk* c, const char* func, - int line) - { -- DBG("%s:%d: r.dev %u:%u\n", func, line, -+ DBG("%s:%d: r.dev %lu:%lu\n", func, line, - c->region->dev->bus_id, c->region->dev->dev_id); - DBG("%s:%d: r.bus_addr %lxh\n", func, line, c->region->bus_addr); - DBG("%s:%d: r.page_size %u\n", func, line, c->region->page_size); -@@ -658,7 +650,7 @@ static int dma_sb_region_create(struct p - BUG_ON(!r); - - if (!r->dev->bus_id) { -- pr_info("%s:%d: %u:%u no dma\n", __func__, __LINE__, -+ pr_info("%s:%d: %lu:%lu no dma\n", __func__, __LINE__, - r->dev->bus_id, r->dev->dev_id); - return 0; - } -@@ -724,7 +716,7 @@ static int dma_sb_region_free(struct ps3 - BUG_ON(!r); - - if (!r->dev->bus_id) { -- pr_info("%s:%d: %u:%u no dma\n", __func__, __LINE__, -+ pr_info("%s:%d: %lu:%lu no dma\n", __func__, __LINE__, - r->dev->bus_id, r->dev->dev_id); - return 0; - } -@@ -1007,7 +999,7 @@ static int dma_sb_region_create_linear(s - - if (r->offset + r->len > map.rm.size) { - /* Map (part of) 2nd RAM chunk */ -- virt_addr = USE_LPAR_ADDR ? map.r1.base : map.rm.size; -+ virt_addr = map.rm.size; - len = r->len; - if (r->offset >= map.rm.size) - virt_addr += r->offset - map.rm.size; ---- a/arch/powerpc/platforms/ps3/platform.h -+++ b/arch/powerpc/platforms/ps3/platform.h -@@ -89,13 +89,11 @@ enum ps3_dev_type { - PS3_DEV_TYPE_STOR_ROM = TYPE_ROM, /* 5 */ - PS3_DEV_TYPE_SB_GPIO = 6, - PS3_DEV_TYPE_STOR_FLASH = TYPE_RBC, /* 14 */ -- PS3_DEV_TYPE_STOR_DUMMY = 32, -- PS3_DEV_TYPE_NOACCESS = 255, - }; - - int ps3_repository_read_bus_str(unsigned int bus_index, const char *bus_str, - u64 *value); --int ps3_repository_read_bus_id(unsigned int bus_index, unsigned int *bus_id); -+int ps3_repository_read_bus_id(unsigned int bus_index, u64 *bus_id); - int ps3_repository_read_bus_type(unsigned int bus_index, - enum ps3_bus_type *bus_type); - int ps3_repository_read_bus_num_dev(unsigned int bus_index, -@@ -119,7 +117,7 @@ enum ps3_reg_type { - int ps3_repository_read_dev_str(unsigned int bus_index, - unsigned int dev_index, const char *dev_str, u64 *value); - int ps3_repository_read_dev_id(unsigned int bus_index, unsigned int dev_index, -- unsigned int *dev_id); -+ u64 *dev_id); - int ps3_repository_read_dev_type(unsigned int bus_index, - unsigned int dev_index, enum ps3_dev_type *dev_type); - int ps3_repository_read_dev_intr(unsigned int bus_index, -@@ -138,21 +136,17 @@ int ps3_repository_read_dev_reg(unsigned - /* repository bus enumerators */ - - struct ps3_repository_device { -- enum ps3_bus_type bus_type; - unsigned int bus_index; -- unsigned int bus_id; -- enum ps3_dev_type dev_type; - unsigned int dev_index; -- unsigned int dev_id; -+ enum ps3_bus_type bus_type; -+ enum ps3_dev_type dev_type; -+ u64 bus_id; -+ u64 dev_id; - }; - --static inline struct ps3_repository_device *ps3_repository_bump_device( -- struct ps3_repository_device *repo) --{ -- repo->dev_index++; -- return repo; --} - int ps3_repository_find_device(struct ps3_repository_device *repo); -+int ps3_repository_find_device_by_id(struct ps3_repository_device *repo, -+ u64 bus_id, u64 dev_id); - int ps3_repository_find_devices(enum ps3_bus_type bus_type, - int (*callback)(const struct ps3_repository_device *repo)); - int ps3_repository_find_bus(enum ps3_bus_type bus_type, unsigned int from, -@@ -186,10 +180,10 @@ int ps3_repository_read_stor_dev_region( - unsigned int dev_index, unsigned int region_index, - unsigned int *region_id, u64 *region_start, u64 *region_size); - --/* repository pu and memory info */ -+/* repository logical pu and memory info */ - --int ps3_repository_read_num_pu(unsigned int *num_pu); --int ps3_repository_read_ppe_id(unsigned int *pu_index, unsigned int *ppe_id); -+int ps3_repository_read_num_pu(u64 *num_pu); -+int ps3_repository_read_pu_id(unsigned int pu_index, u64 *pu_id); - int ps3_repository_read_rm_base(unsigned int ppe_id, u64 *rm_base); - int ps3_repository_read_rm_size(unsigned int ppe_id, u64 *rm_size); - int ps3_repository_read_region_total(u64 *region_total); -@@ -200,9 +194,15 @@ int ps3_repository_read_mm_info(u64 *rm_ - - int ps3_repository_read_num_be(unsigned int *num_be); - int ps3_repository_read_be_node_id(unsigned int be_index, u64 *node_id); -+int ps3_repository_read_be_id(u64 node_id, u64 *be_id); - int ps3_repository_read_tb_freq(u64 node_id, u64 *tb_freq); - int ps3_repository_read_be_tb_freq(unsigned int be_index, u64 *tb_freq); - -+/* repository performance monitor info */ -+ -+int ps3_repository_read_lpm_privileges(unsigned int be_index, u64 *lpar, -+ u64 *rights); -+ - /* repository 'Other OS' area */ - - int ps3_repository_read_boot_dat_addr(u64 *lpar_addr); ---- a/arch/powerpc/platforms/ps3/repository.c -+++ b/arch/powerpc/platforms/ps3/repository.c -@@ -33,7 +33,7 @@ enum ps3_lpar_id { - }; - - #define dump_field(_a, _b) _dump_field(_a, _b, __func__, __LINE__) --static void _dump_field(const char *hdr, u64 n, const char* func, int line) -+static void _dump_field(const char *hdr, u64 n, const char *func, int line) - { - #if defined(DEBUG) - char s[16]; -@@ -50,8 +50,8 @@ static void _dump_field(const char *hdr, - - #define dump_node_name(_a, _b, _c, _d, _e) \ - _dump_node_name(_a, _b, _c, _d, _e, __func__, __LINE__) --static void _dump_node_name (unsigned int lpar_id, u64 n1, u64 n2, u64 n3, -- u64 n4, const char* func, int line) -+static void _dump_node_name(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, -+ u64 n4, const char *func, int line) - { - pr_debug("%s:%d: lpar: %u\n", func, line, lpar_id); - _dump_field("n1: ", n1, func, line); -@@ -63,7 +63,7 @@ static void _dump_node_name (unsigned in - #define dump_node(_a, _b, _c, _d, _e, _f, _g) \ - _dump_node(_a, _b, _c, _d, _e, _f, _g, __func__, __LINE__) - static void _dump_node(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, u64 n4, -- u64 v1, u64 v2, const char* func, int line) -+ u64 v1, u64 v2, const char *func, int line) - { - pr_debug("%s:%d: lpar: %u\n", func, line, lpar_id); - _dump_field("n1: ", n1, func, line); -@@ -165,21 +165,18 @@ int ps3_repository_read_bus_str(unsigned - make_first_field("bus", bus_index), - make_field(bus_str, 0), - 0, 0, -- value, 0); -+ value, NULL); - } - --int ps3_repository_read_bus_id(unsigned int bus_index, unsigned int *bus_id) -+int ps3_repository_read_bus_id(unsigned int bus_index, u64 *bus_id) - { - int result; -- u64 v1; -- u64 v2; /* unused */ - - result = read_node(PS3_LPAR_ID_PME, - make_first_field("bus", bus_index), - make_field("id", 0), - 0, 0, -- &v1, &v2); -- *bus_id = v1; -+ bus_id, NULL); - return result; - } - -@@ -193,7 +190,7 @@ int ps3_repository_read_bus_type(unsigne - make_first_field("bus", bus_index), - make_field("type", 0), - 0, 0, -- &v1, 0); -+ &v1, NULL); - *bus_type = v1; - return result; - } -@@ -208,7 +205,7 @@ int ps3_repository_read_bus_num_dev(unsi - make_first_field("bus", bus_index), - make_field("num_dev", 0), - 0, 0, -- &v1, 0); -+ &v1, NULL); - *num_dev = v1; - return result; - } -@@ -221,22 +218,20 @@ int ps3_repository_read_dev_str(unsigned - make_field("dev", dev_index), - make_field(dev_str, 0), - 0, -- value, 0); -+ value, NULL); - } - - int ps3_repository_read_dev_id(unsigned int bus_index, unsigned int dev_index, -- unsigned int *dev_id) -+ u64 *dev_id) - { - int result; -- u64 v1; - - result = read_node(PS3_LPAR_ID_PME, - make_first_field("bus", bus_index), - make_field("dev", dev_index), - make_field("id", 0), - 0, -- &v1, 0); -- *dev_id = v1; -+ dev_id, NULL); - return result; - } - -@@ -251,14 +246,14 @@ int ps3_repository_read_dev_type(unsigne - make_field("dev", dev_index), - make_field("type", 0), - 0, -- &v1, 0); -+ &v1, NULL); - *dev_type = v1; - return result; - } - - int ps3_repository_read_dev_intr(unsigned int bus_index, - unsigned int dev_index, unsigned int intr_index, -- enum ps3_interrupt_type *intr_type, unsigned int* interrupt_id) -+ enum ps3_interrupt_type *intr_type, unsigned int *interrupt_id) - { - int result; - u64 v1; -@@ -287,7 +282,7 @@ int ps3_repository_read_dev_reg_type(uns - make_field("dev", dev_index), - make_field("reg", reg_index), - make_field("type", 0), -- &v1, 0); -+ &v1, NULL); - *reg_type = v1; - return result; - } -@@ -332,7 +327,7 @@ int ps3_repository_find_device(struct ps - return result; - } - -- pr_debug("%s:%d: bus_type %u, bus_index %u, bus_id %u, num_dev %u\n", -+ pr_debug("%s:%d: bus_type %u, bus_index %u, bus_id %lu, num_dev %u\n", - __func__, __LINE__, tmp.bus_type, tmp.bus_index, tmp.bus_id, - num_dev); - -@@ -349,47 +344,95 @@ int ps3_repository_find_device(struct ps - return result; - } - -- if (tmp.bus_type == PS3_BUS_TYPE_STORAGE) { -- /* -- * A storage device may show up in the repository before the -- * hypervisor has finished probing its type and regions -- */ -- unsigned int num_regions; -- -- if (tmp.dev_type == PS3_DEV_TYPE_STOR_DUMMY) { -- pr_debug("%s:%u storage device not ready\n", __func__, -- __LINE__); -- return -ENODEV; -- } -+ result = ps3_repository_read_dev_id(tmp.bus_index, tmp.dev_index, -+ &tmp.dev_id); - -- result = ps3_repository_read_stor_dev_num_regions(tmp.bus_index, -- tmp.dev_index, -- &num_regions); -+ if (result) { -+ pr_debug("%s:%d ps3_repository_read_dev_id failed\n", __func__, -+ __LINE__); -+ return result; -+ } -+ -+ pr_debug("%s:%d: found: dev_type %u, dev_index %u, dev_id %lu\n", -+ __func__, __LINE__, tmp.dev_type, tmp.dev_index, tmp.dev_id); -+ -+ *repo = tmp; -+ return 0; -+} -+ -+int ps3_repository_find_device_by_id(struct ps3_repository_device *repo, -+ u64 bus_id, u64 dev_id) -+{ -+ int result = -ENODEV; -+ struct ps3_repository_device tmp; -+ unsigned int num_dev; -+ -+ pr_debug(" -> %s:%u: find device by id %lu:%lu\n", __func__, __LINE__, -+ bus_id, dev_id); -+ -+ for (tmp.bus_index = 0; tmp.bus_index < 10; tmp.bus_index++) { -+ result = ps3_repository_read_bus_id(tmp.bus_index, -+ &tmp.bus_id); - if (result) { -- pr_debug("%s:%d read_stor_dev_num_regions failed\n", -- __func__, __LINE__); -+ pr_debug("%s:%u read_bus_id(%u) failed\n", __func__, -+ __LINE__, tmp.bus_index); - return result; - } - -- if (!num_regions) { -- pr_debug("%s:%u storage device has no regions yet\n", -- __func__, __LINE__); -- return -ENODEV; -- } -+ if (tmp.bus_id == bus_id) -+ goto found_bus; -+ -+ pr_debug("%s:%u: skip, bus_id %lu\n", __func__, __LINE__, -+ tmp.bus_id); - } -+ pr_debug(" <- %s:%u: bus not found\n", __func__, __LINE__); -+ return result; - -- result = ps3_repository_read_dev_id(tmp.bus_index, tmp.dev_index, -- &tmp.dev_id); -+found_bus: -+ result = ps3_repository_read_bus_type(tmp.bus_index, &tmp.bus_type); -+ if (result) { -+ pr_debug("%s:%u read_bus_type(%u) failed\n", __func__, -+ __LINE__, tmp.bus_index); -+ return result; -+ } - -+ result = ps3_repository_read_bus_num_dev(tmp.bus_index, &num_dev); - if (result) { -- pr_debug("%s:%d ps3_repository_read_dev_id failed\n", __func__, -- __LINE__); -+ pr_debug("%s:%u read_bus_num_dev failed\n", __func__, -+ __LINE__); - return result; - } - -- pr_debug("%s:%d: found: dev_type %u, dev_index %u, dev_id %u\n", -- __func__, __LINE__, tmp.dev_type, tmp.dev_index, tmp.dev_id); -+ for (tmp.dev_index = 0; tmp.dev_index < num_dev; tmp.dev_index++) { -+ result = ps3_repository_read_dev_id(tmp.bus_index, -+ tmp.dev_index, -+ &tmp.dev_id); -+ if (result) { -+ pr_debug("%s:%u read_dev_id(%u:%u) failed\n", __func__, -+ __LINE__, tmp.bus_index, tmp.dev_index); -+ return result; -+ } -+ -+ if (tmp.dev_id == dev_id) -+ goto found_dev; -+ -+ pr_debug("%s:%u: skip, dev_id %lu\n", __func__, __LINE__, -+ tmp.dev_id); -+ } -+ pr_debug(" <- %s:%u: dev not found\n", __func__, __LINE__); -+ return result; -+ -+found_dev: -+ result = ps3_repository_read_dev_type(tmp.bus_index, tmp.dev_index, -+ &tmp.dev_type); -+ if (result) { -+ pr_debug("%s:%u read_dev_type failed\n", __func__, __LINE__); -+ return result; -+ } - -+ pr_debug(" <- %s:%u: found: type (%u:%u) index (%u:%u) id (%lu:%lu)\n", -+ __func__, __LINE__, tmp.bus_type, tmp.dev_type, tmp.bus_index, -+ tmp.dev_index, tmp.bus_id, tmp.dev_id); - *repo = tmp; - return 0; - } -@@ -402,50 +445,34 @@ int __devinit ps3_repository_find_device - - pr_debug(" -> %s:%d: find bus_type %u\n", __func__, __LINE__, bus_type); - -- for (repo.bus_index = 0; repo.bus_index < 10; repo.bus_index++) { -+ repo.bus_type = bus_type; -+ result = ps3_repository_find_bus(repo.bus_type, 0, &repo.bus_index); -+ if (result) { -+ pr_debug(" <- %s:%u: bus not found\n", __func__, __LINE__); -+ return result; -+ } - -- result = ps3_repository_read_bus_type(repo.bus_index, -- &repo.bus_type); -+ result = ps3_repository_read_bus_id(repo.bus_index, &repo.bus_id); -+ if (result) { -+ pr_debug("%s:%d read_bus_id(%u) failed\n", __func__, __LINE__, -+ repo.bus_index); -+ return result; -+ } - -- if (result) { -- pr_debug("%s:%d read_bus_type(%u) failed\n", -- __func__, __LINE__, repo.bus_index); -+ for (repo.dev_index = 0; ; repo.dev_index++) { -+ result = ps3_repository_find_device(&repo); -+ if (result == -ENODEV) { -+ result = 0; -+ break; -+ } else if (result) - break; -- } -- -- if (repo.bus_type != bus_type) { -- pr_debug("%s:%d: skip, bus_type %u\n", __func__, -- __LINE__, repo.bus_type); -- continue; -- } -- -- result = ps3_repository_read_bus_id(repo.bus_index, -- &repo.bus_id); - -+ result = callback(&repo); - if (result) { -- pr_debug("%s:%d read_bus_id(%u) failed\n", -- __func__, __LINE__, repo.bus_index); -- continue; -- } -- -- for (repo.dev_index = 0; ; repo.dev_index++) { -- result = ps3_repository_find_device(&repo); -- -- if (result == -ENODEV) { -- result = 0; -- break; -- } else if (result) -- break; -- -- result = callback(&repo); -- -- if (result) { -- pr_debug("%s:%d: abort at callback\n", __func__, -- __LINE__); -- break; -- } -+ pr_debug("%s:%d: abort at callback\n", __func__, -+ __LINE__); -+ break; - } -- break; - } - - pr_debug(" <- %s:%d\n", __func__, __LINE__); -@@ -561,7 +588,7 @@ int ps3_repository_read_stor_dev_port(un - make_first_field("bus", bus_index), - make_field("dev", dev_index), - make_field("port", 0), -- 0, port, 0); -+ 0, port, NULL); - } - - int ps3_repository_read_stor_dev_blk_size(unsigned int bus_index, -@@ -571,7 +598,7 @@ int ps3_repository_read_stor_dev_blk_siz - make_first_field("bus", bus_index), - make_field("dev", dev_index), - make_field("blk_size", 0), -- 0, blk_size, 0); -+ 0, blk_size, NULL); - } - - int ps3_repository_read_stor_dev_num_blocks(unsigned int bus_index, -@@ -581,7 +608,7 @@ int ps3_repository_read_stor_dev_num_blo - make_first_field("bus", bus_index), - make_field("dev", dev_index), - make_field("n_blocks", 0), -- 0, num_blocks, 0); -+ 0, num_blocks, NULL); - } - - int ps3_repository_read_stor_dev_num_regions(unsigned int bus_index, -@@ -594,7 +621,7 @@ int ps3_repository_read_stor_dev_num_reg - make_first_field("bus", bus_index), - make_field("dev", dev_index), - make_field("n_regs", 0), -- 0, &v1, 0); -+ 0, &v1, NULL); - *num_regions = v1; - return result; - } -@@ -611,7 +638,7 @@ int ps3_repository_read_stor_dev_region_ - make_field("dev", dev_index), - make_field("region", region_index), - make_field("id", 0), -- &v1, 0); -+ &v1, NULL); - *region_id = v1; - return result; - } -@@ -624,7 +651,7 @@ int ps3_repository_read_stor_dev_region_ - make_field("dev", dev_index), - make_field("region", region_index), - make_field("size", 0), -- region_size, 0); -+ region_size, NULL); - } - - int ps3_repository_read_stor_dev_region_start(unsigned int bus_index, -@@ -635,7 +662,7 @@ int ps3_repository_read_stor_dev_region_ - make_field("dev", dev_index), - make_field("region", region_index), - make_field("start", 0), -- region_start, 0); -+ region_start, NULL); - } - - int ps3_repository_read_stor_dev_info(unsigned int bus_index, -@@ -684,6 +711,35 @@ int ps3_repository_read_stor_dev_region( - return result; - } - -+/** -+ * ps3_repository_read_num_pu - Number of logical PU processors for this lpar. -+ */ -+ -+int ps3_repository_read_num_pu(u64 *num_pu) -+{ -+ *num_pu = 0; -+ return read_node(PS3_LPAR_ID_CURRENT, -+ make_first_field("bi", 0), -+ make_field("pun", 0), -+ 0, 0, -+ num_pu, NULL); -+} -+ -+/** -+ * ps3_repository_read_pu_id - Read the logical PU id. -+ * @pu_index: Zero based index. -+ * @pu_id: The logical PU id. -+ */ -+ -+int ps3_repository_read_pu_id(unsigned int pu_index, u64 *pu_id) -+{ -+ return read_node(PS3_LPAR_ID_CURRENT, -+ make_first_field("bi", 0), -+ make_field("pu", pu_index), -+ 0, 0, -+ pu_id, NULL); -+} -+ - int ps3_repository_read_rm_size(unsigned int ppe_id, u64 *rm_size) - { - return read_node(PS3_LPAR_ID_CURRENT, -@@ -691,7 +747,7 @@ int ps3_repository_read_rm_size(unsigned - make_field("pu", 0), - ppe_id, - make_field("rm_size", 0), -- rm_size, 0); -+ rm_size, NULL); - } - - int ps3_repository_read_region_total(u64 *region_total) -@@ -700,7 +756,7 @@ int ps3_repository_read_region_total(u64 - make_first_field("bi", 0), - make_field("rgntotal", 0), - 0, 0, -- region_total, 0); -+ region_total, NULL); - } - - /** -@@ -736,7 +792,7 @@ int ps3_repository_read_num_spu_reserved - make_first_field("bi", 0), - make_field("spun", 0), - 0, 0, -- &v1, 0); -+ &v1, NULL); - *num_spu_reserved = v1; - return result; - } -@@ -755,7 +811,7 @@ int ps3_repository_read_num_spu_resource - make_first_field("bi", 0), - make_field("spursvn", 0), - 0, 0, -- &v1, 0); -+ &v1, NULL); - *num_resource_id = v1; - return result; - } -@@ -768,7 +824,7 @@ int ps3_repository_read_num_spu_resource - */ - - int ps3_repository_read_spu_resource_id(unsigned int res_index, -- enum ps3_spu_resource_type* resource_type, unsigned int *resource_id) -+ enum ps3_spu_resource_type *resource_type, unsigned int *resource_id) - { - int result; - u64 v1; -@@ -785,14 +841,14 @@ int ps3_repository_read_spu_resource_id( - return result; - } - --int ps3_repository_read_boot_dat_address(u64 *address) -+static int ps3_repository_read_boot_dat_address(u64 *address) - { - return read_node(PS3_LPAR_ID_CURRENT, - make_first_field("bi", 0), - make_field("boot_dat", 0), - make_field("address", 0), - 0, -- address, 0); -+ address, NULL); - } - - int ps3_repository_read_boot_dat_size(unsigned int *size) -@@ -805,7 +861,7 @@ int ps3_repository_read_boot_dat_size(un - make_field("boot_dat", 0), - make_field("size", 0), - 0, -- &v1, 0); -+ &v1, NULL); - *size = v1; - return result; - } -@@ -820,7 +876,7 @@ int ps3_repository_read_vuart_av_port(un - make_field("vir_uart", 0), - make_field("port", 0), - make_field("avset", 0), -- &v1, 0); -+ &v1, NULL); - *port = v1; - return result; - } -@@ -835,7 +891,7 @@ int ps3_repository_read_vuart_sysmgr_por - make_field("vir_uart", 0), - make_field("port", 0), - make_field("sysmgr", 0), -- &v1, 0); -+ &v1, NULL); - *port = v1; - return result; - } -@@ -856,6 +912,10 @@ int ps3_repository_read_boot_dat_info(u6 - : ps3_repository_read_boot_dat_size(size); - } - -+/** -+ * ps3_repository_read_num_be - Number of physical BE processors in the system. -+ */ -+ - int ps3_repository_read_num_be(unsigned int *num_be) - { - int result; -@@ -866,11 +926,17 @@ int ps3_repository_read_num_be(unsigned - 0, - 0, - 0, -- &v1, 0); -+ &v1, NULL); - *num_be = v1; - return result; - } - -+/** -+ * ps3_repository_read_be_node_id - Read the physical BE processor node id. -+ * @be_index: Zero based index. -+ * @node_id: The BE processor node id. -+ */ -+ - int ps3_repository_read_be_node_id(unsigned int be_index, u64 *node_id) - { - return read_node(PS3_LPAR_ID_PME, -@@ -878,7 +944,23 @@ int ps3_repository_read_be_node_id(unsig - 0, - 0, - 0, -- node_id, 0); -+ node_id, NULL); -+} -+ -+/** -+ * ps3_repository_read_be_id - Read the physical BE processor id. -+ * @node_id: The BE processor node id. -+ * @be_id: The BE processor id. -+ */ -+ -+int ps3_repository_read_be_id(u64 node_id, u64 *be_id) -+{ -+ return read_node(PS3_LPAR_ID_PME, -+ make_first_field("be", 0), -+ node_id, -+ 0, -+ 0, -+ be_id, NULL); - } - - int ps3_repository_read_tb_freq(u64 node_id, u64 *tb_freq) -@@ -888,7 +970,7 @@ int ps3_repository_read_tb_freq(u64 node - node_id, - make_field("clock", 0), - 0, -- tb_freq, 0); -+ tb_freq, NULL); - } - - int ps3_repository_read_be_tb_freq(unsigned int be_index, u64 *tb_freq) -@@ -897,11 +979,29 @@ int ps3_repository_read_be_tb_freq(unsig - u64 node_id; - - *tb_freq = 0; -- result = ps3_repository_read_be_node_id(0, &node_id); -+ result = ps3_repository_read_be_node_id(be_index, &node_id); - return result ? result - : ps3_repository_read_tb_freq(node_id, tb_freq); - } - -+int ps3_repository_read_lpm_privileges(unsigned int be_index, u64 *lpar, -+ u64 *rights) -+{ -+ int result; -+ u64 node_id; -+ -+ *lpar = 0; -+ *rights = 0; -+ result = ps3_repository_read_be_node_id(be_index, &node_id); -+ return result ? result -+ : read_node(PS3_LPAR_ID_PME, -+ make_first_field("be", 0), -+ node_id, -+ make_field("lpm", 0), -+ make_field("priv", 0), -+ lpar, rights); -+} -+ - #if defined(DEBUG) - - int ps3_repository_dump_resource_info(const struct ps3_repository_device *repo) -@@ -1034,7 +1134,7 @@ static int dump_device_info(struct ps3_r - continue; - } - -- pr_debug("%s:%d (%u:%u): dev_type %u, dev_id %u\n", __func__, -+ pr_debug("%s:%d (%u:%u): dev_type %u, dev_id %lu\n", __func__, - __LINE__, repo->bus_index, repo->dev_index, - repo->dev_type, repo->dev_id); - -@@ -1091,7 +1191,7 @@ int ps3_repository_dump_bus_info(void) - continue; - } - -- pr_debug("%s:%d bus_%u: bus_type %u, bus_id %u, num_dev %u\n", -+ pr_debug("%s:%d bus_%u: bus_type %u, bus_id %lu, num_dev %u\n", - __func__, __LINE__, repo.bus_index, repo.bus_type, - repo.bus_id, num_dev); - ---- a/arch/powerpc/platforms/ps3/spu.c -+++ b/arch/powerpc/platforms/ps3/spu.c -@@ -28,6 +28,7 @@ - #include - #include - -+#include "../cell/spufs/spufs.h" - #include "platform.h" - - /* spu_management_ops */ -@@ -419,10 +420,34 @@ static int ps3_init_affinity(void) - return 0; - } - -+/** -+ * ps3_enable_spu - Enable SPU run control. -+ * -+ * An outstanding enhancement for the PS3 would be to add a guard to check -+ * for incorrect access to the spu problem state when the spu context is -+ * disabled. This check could be implemented with a flag added to the spu -+ * context that would inhibit mapping problem state pages, and a routine -+ * to unmap spu problem state pages. When the spu is enabled with -+ * ps3_enable_spu() the flag would be set allowing pages to be mapped, -+ * and when the spu is disabled with ps3_disable_spu() the flag would be -+ * cleared and the mapped problem state pages would be unmapped. -+ */ -+ -+static void ps3_enable_spu(struct spu_context *ctx) -+{ -+} -+ -+static void ps3_disable_spu(struct spu_context *ctx) -+{ -+ ctx->ops->runcntl_stop(ctx); -+} -+ - const struct spu_management_ops spu_management_ps3_ops = { - .enumerate_spus = ps3_enumerate_spus, - .create_spu = ps3_create_spu, - .destroy_spu = ps3_destroy_spu, -+ .enable_spu = ps3_enable_spu, -+ .disable_spu = ps3_disable_spu, - .init_affinity = ps3_init_affinity, - }; - -@@ -505,8 +530,6 @@ static void mfc_sr1_set(struct spu *spu, - static const u64 allowed = ~(MFC_STATE1_LOCAL_STORAGE_DECODE_MASK - | MFC_STATE1_PROBLEM_STATE_MASK); - -- sr1 |= MFC_STATE1_MASTER_RUN_CONTROL_MASK; -- - BUG_ON((sr1 & allowed) != (spu_pdata(spu)->cache.sr1 & allowed)); - - spu_pdata(spu)->cache.sr1 = sr1; ---- a/arch/powerpc/platforms/ps3/system-bus.c -+++ b/arch/powerpc/platforms/ps3/system-bus.c -@@ -42,8 +42,8 @@ struct { - int gpu; - } static usage_hack; - --static int ps3_is_device(struct ps3_system_bus_device *dev, -- unsigned int bus_id, unsigned int dev_id) -+static int ps3_is_device(struct ps3_system_bus_device *dev, u64 bus_id, -+ u64 dev_id) - { - return dev->bus_id == bus_id && dev->dev_id == dev_id; - } -@@ -182,8 +182,8 @@ int ps3_open_hv_device(struct ps3_system - case PS3_MATCH_ID_SYSTEM_MANAGER: - pr_debug("%s:%d: unsupported match_id: %u\n", __func__, - __LINE__, dev->match_id); -- pr_debug("%s:%d: bus_id: %u\n", __func__, -- __LINE__, dev->bus_id); -+ pr_debug("%s:%d: bus_id: %lu\n", __func__, __LINE__, -+ dev->bus_id); - BUG(); - return -EINVAL; - -@@ -220,8 +220,8 @@ int ps3_close_hv_device(struct ps3_syste - case PS3_MATCH_ID_SYSTEM_MANAGER: - pr_debug("%s:%d: unsupported match_id: %u\n", __func__, - __LINE__, dev->match_id); -- pr_debug("%s:%d: bus_id: %u\n", __func__, -- __LINE__, dev->bus_id); -+ pr_debug("%s:%d: bus_id: %lu\n", __func__, __LINE__, -+ dev->bus_id); - BUG(); - return -EINVAL; - -@@ -240,7 +240,7 @@ EXPORT_SYMBOL_GPL(ps3_close_hv_device); - static void _dump_mmio_region(const struct ps3_mmio_region* r, - const char* func, int line) - { -- pr_debug("%s:%d: dev %u:%u\n", func, line, r->dev->bus_id, -+ pr_debug("%s:%d: dev %lu:%lu\n", func, line, r->dev->bus_id, - r->dev->dev_id); - pr_debug("%s:%d: bus_addr %lxh\n", func, line, r->bus_addr); - pr_debug("%s:%d: len %lxh\n", func, line, r->len); -@@ -715,6 +715,7 @@ int ps3_system_bus_device_register(struc - static unsigned int dev_ioc0_count; - static unsigned int dev_sb_count; - static unsigned int dev_vuart_count; -+ static unsigned int dev_lpm_count; - - if (!dev->core.parent) - dev->core.parent = &ps3_system_bus; -@@ -737,6 +738,10 @@ int ps3_system_bus_device_register(struc - snprintf(dev->core.bus_id, sizeof(dev->core.bus_id), - "vuart_%02x", ++dev_vuart_count); - break; -+ case PS3_DEVICE_TYPE_LPM: -+ snprintf(dev->core.bus_id, sizeof(dev->core.bus_id), -+ "lpm_%02x", ++dev_lpm_count); -+ break; - default: - BUG(); - }; ---- a/arch/powerpc/platforms/pseries/eeh.c -+++ b/arch/powerpc/platforms/pseries/eeh.c -@@ -29,6 +29,8 @@ - #include - #include - #include -+#include -+ - #include - #include - #include -@@ -169,7 +171,6 @@ static void rtas_slot_error_detail(struc - */ - static size_t gather_pci_data(struct pci_dn *pdn, char * buf, size_t len) - { -- struct device_node *dn; - struct pci_dev *dev = pdn->pcidev; - u32 cfg; - int cap, i; -@@ -243,12 +244,12 @@ static size_t gather_pci_data(struct pci - - /* Gather status on devices under the bridge */ - if (dev->class >> 16 == PCI_BASE_CLASS_BRIDGE) { -- dn = pdn->node->child; -- while (dn) { -+ struct device_node *dn; -+ -+ for_each_child_of_node(pdn->node, dn) { - pdn = PCI_DN(dn); - if (pdn) - n += gather_pci_data(pdn, buf+n, len-n); -- dn = dn->sibling; - } - } - -@@ -372,7 +373,7 @@ struct device_node * find_device_pe(stru - return dn; - } - --/** Mark all devices that are peers of this device as failed. -+/** Mark all devices that are children of this device as failed. - * Mark the device driver too, so that it can see the failure - * immediately; this is critical, since some drivers poll - * status registers in interrupts ... If a driver is polling, -@@ -380,9 +381,11 @@ struct device_node * find_device_pe(stru - * an interrupt context, which is bad. - */ - --static void __eeh_mark_slot (struct device_node *dn, int mode_flag) -+static void __eeh_mark_slot(struct device_node *parent, int mode_flag) - { -- while (dn) { -+ struct device_node *dn; -+ -+ for_each_child_of_node(parent, dn) { - if (PCI_DN(dn)) { - /* Mark the pci device driver too */ - struct pci_dev *dev = PCI_DN(dn)->pcidev; -@@ -392,10 +395,8 @@ static void __eeh_mark_slot (struct devi - if (dev && dev->driver) - dev->error_state = pci_channel_io_frozen; - -- if (dn->child) -- __eeh_mark_slot (dn->child, mode_flag); -+ __eeh_mark_slot(dn, mode_flag); - } -- dn = dn->sibling; - } - } - -@@ -415,19 +416,19 @@ void eeh_mark_slot (struct device_node * - if (dev) - dev->error_state = pci_channel_io_frozen; - -- __eeh_mark_slot (dn->child, mode_flag); -+ __eeh_mark_slot(dn, mode_flag); - } - --static void __eeh_clear_slot (struct device_node *dn, int mode_flag) -+static void __eeh_clear_slot(struct device_node *parent, int mode_flag) - { -- while (dn) { -+ struct device_node *dn; -+ -+ for_each_child_of_node(parent, dn) { - if (PCI_DN(dn)) { - PCI_DN(dn)->eeh_mode &= ~mode_flag; - PCI_DN(dn)->eeh_check_count = 0; -- if (dn->child) -- __eeh_clear_slot (dn->child, mode_flag); -+ __eeh_clear_slot(dn, mode_flag); - } -- dn = dn->sibling; - } - } - -@@ -444,7 +445,7 @@ void eeh_clear_slot (struct device_node - - PCI_DN(dn)->eeh_mode &= ~mode_flag; - PCI_DN(dn)->eeh_check_count = 0; -- __eeh_clear_slot (dn->child, mode_flag); -+ __eeh_clear_slot(dn, mode_flag); - spin_unlock_irqrestore(&confirm_error_lock, flags); - } - -@@ -480,6 +481,7 @@ int eeh_dn_check_failure(struct device_n - no_dn++; - return 0; - } -+ dn = find_device_pe(dn); - pdn = PCI_DN(dn); - - /* Access to IO BARs might get this far and still not want checking. */ -@@ -545,7 +547,7 @@ int eeh_dn_check_failure(struct device_n - - /* Note that config-io to empty slots may fail; - * they are empty when they don't have children. */ -- if ((rets[0] == 5) && (dn->child == NULL)) { -+ if ((rets[0] == 5) && (rets[2] == 0) && (dn->child == NULL)) { - false_positives++; - pdn->eeh_false_positives ++; - rc = 0; -@@ -848,11 +850,8 @@ void eeh_restore_bars(struct pci_dn *pdn - if ((pdn->eeh_mode & EEH_MODE_SUPPORTED) && !IS_BRIDGE(pdn->class_code)) - __restore_bars (pdn); - -- dn = pdn->node->child; -- while (dn) { -+ for_each_child_of_node(pdn->node, dn) - eeh_restore_bars (PCI_DN(dn)); -- dn = dn->sibling; -- } - } - - /** -@@ -1130,7 +1129,8 @@ static void eeh_add_device_early(struct - void eeh_add_device_tree_early(struct device_node *dn) - { - struct device_node *sib; -- for (sib = dn->child; sib; sib = sib->sibling) -+ -+ for_each_child_of_node(dn, sib) - eeh_add_device_tree_early(sib); - eeh_add_device_early(dn); - } ---- a/arch/powerpc/platforms/pseries/eeh_driver.c -+++ b/arch/powerpc/platforms/pseries/eeh_driver.c -@@ -310,8 +310,6 @@ struct pci_dn * handle_eeh_events (struc - const char *location, *pci_str, *drv_str; - - frozen_dn = find_device_pe(event->dn); -- frozen_bus = pcibios_find_pci_bus(frozen_dn); -- - if (!frozen_dn) { - - location = of_get_property(event->dn, "ibm,loc-code", NULL); -@@ -321,6 +319,8 @@ struct pci_dn * handle_eeh_events (struc - location, pci_name(event->dev)); - return NULL; - } -+ -+ frozen_bus = pcibios_find_pci_bus(frozen_dn); - location = of_get_property(frozen_dn, "ibm,loc-code", NULL); - location = location ? location : "unknown"; - -@@ -354,13 +354,6 @@ struct pci_dn * handle_eeh_events (struc - if (frozen_pdn->eeh_freeze_count > EEH_MAX_ALLOWED_FREEZES) - goto excess_failures; - -- /* Get the current PCI slot state. */ -- rc = eeh_wait_for_slot_status (frozen_pdn, MAX_WAIT_FOR_RECOVERY*1000); -- if (rc < 0) { -- printk(KERN_WARNING "EEH: Permanent failure\n"); -- goto hard_fail; -- } -- - printk(KERN_WARNING - "EEH: This PCI device has failed %d times in the last hour:\n", - frozen_pdn->eeh_freeze_count); -@@ -376,6 +369,14 @@ struct pci_dn * handle_eeh_events (struc - */ - pci_walk_bus(frozen_bus, eeh_report_error, &result); - -+ /* Get the current PCI slot state. This can take a long time, -+ * sometimes over 3 seconds for certain systems. */ -+ rc = eeh_wait_for_slot_status (frozen_pdn, MAX_WAIT_FOR_RECOVERY*1000); -+ if (rc < 0) { -+ printk(KERN_WARNING "EEH: Permanent failure\n"); -+ goto hard_fail; -+ } -+ - /* Since rtas may enable MMIO when posting the error log, - * don't post the error log until after all dev drivers - * have been informed. ---- a/arch/powerpc/platforms/pseries/iommu.c -+++ b/arch/powerpc/platforms/pseries/iommu.c -@@ -251,7 +251,7 @@ static void iommu_table_setparms(struct - const unsigned long *basep; - const u32 *sizep; - -- node = (struct device_node *)phb->arch_data; -+ node = phb->dn; - - basep = of_get_property(node, "linux,tce-base", NULL); - sizep = of_get_property(node, "linux,tce-size", NULL); -@@ -296,11 +296,12 @@ static void iommu_table_setparms(struct - static void iommu_table_setparms_lpar(struct pci_controller *phb, - struct device_node *dn, - struct iommu_table *tbl, -- const void *dma_window) -+ const void *dma_window, -+ int bussubno) - { - unsigned long offset, size; - -- tbl->it_busno = PCI_DN(dn)->bussubno; -+ tbl->it_busno = bussubno; - of_parse_dma_window(dn, dma_window, &tbl->it_index, &offset, &size); - - tbl->it_base = 0; -@@ -420,17 +421,10 @@ static void pci_dma_bus_setup_pSeriesLP( - pdn->full_name, ppci->iommu_table); - - if (!ppci->iommu_table) { -- /* Bussubno hasn't been copied yet. -- * Do it now because iommu_table_setparms_lpar needs it. -- */ -- -- ppci->bussubno = bus->number; -- - tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL, - ppci->phb->node); -- -- iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window); -- -+ iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window, -+ bus->number); - ppci->iommu_table = iommu_init_table(tbl, ppci->phb->node); - DBG(" created table: %p\n", ppci->iommu_table); - } -@@ -523,14 +517,10 @@ static void pci_dma_dev_setup_pSeriesLP( - - pci = PCI_DN(pdn); - if (!pci->iommu_table) { -- /* iommu_table_setparms_lpar needs bussubno. */ -- pci->bussubno = pci->phb->bus->number; -- - tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL, - pci->phb->node); -- -- iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window); -- -+ iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window, -+ pci->phb->bus->number); - pci->iommu_table = iommu_init_table(tbl, pci->phb->node); - DBG(" created table: %p\n", pci->iommu_table); - } else { -@@ -556,7 +546,7 @@ static int iommu_reconfig_notifier(struc - case PSERIES_RECONFIG_REMOVE: - if (pci && pci->iommu_table && - of_get_property(np, "ibm,dma-window", NULL)) -- iommu_free_table(np); -+ iommu_free_table(pci->iommu_table, np->full_name); - break; - default: - err = NOTIFY_DONE; ---- a/arch/powerpc/platforms/pseries/pci_dlpar.c -+++ b/arch/powerpc/platforms/pseries/pci_dlpar.c -@@ -83,7 +83,7 @@ EXPORT_SYMBOL_GPL(pcibios_remove_pci_dev - - /* Must be called before pci_bus_add_devices */ - void --pcibios_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus) -+pcibios_fixup_new_pci_devices(struct pci_bus *bus) - { - struct pci_dev *dev; - -@@ -98,8 +98,6 @@ pcibios_fixup_new_pci_devices(struct pci - /* Fill device archdata and setup iommu table */ - pcibios_setup_new_device(dev); - -- if(fix_bus) -- pcibios_fixup_device_resources(dev, bus); - pci_read_irq_line(dev); - for (i = 0; i < PCI_NUM_RESOURCES; i++) { - struct resource *r = &dev->resource[i]; -@@ -132,8 +130,8 @@ pcibios_pci_config_bridge(struct pci_dev - - pci_scan_child_bus(child_bus); - -- /* Fixup new pci devices without touching bus struct */ -- pcibios_fixup_new_pci_devices(child_bus, 0); -+ /* Fixup new pci devices */ -+ pcibios_fixup_new_pci_devices(child_bus); - - /* Make the discovered devices available */ - pci_bus_add_devices(child_bus); -@@ -169,7 +167,7 @@ pcibios_add_pci_devices(struct pci_bus * - /* use ofdt-based probe */ - of_scan_bus(dn, bus); - if (!list_empty(&bus->devices)) { -- pcibios_fixup_new_pci_devices(bus, 0); -+ pcibios_fixup_new_pci_devices(bus); - pci_bus_add_devices(bus); - eeh_add_device_tree_late(bus); - } -@@ -178,7 +176,7 @@ pcibios_add_pci_devices(struct pci_bus * - slotno = PCI_SLOT(PCI_DN(dn->child)->devfn); - num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0)); - if (num) { -- pcibios_fixup_new_pci_devices(bus, 1); -+ pcibios_fixup_new_pci_devices(bus); - pci_bus_add_devices(bus); - eeh_add_device_tree_late(bus); - } -@@ -208,7 +206,7 @@ struct pci_controller * __devinit init_p - eeh_add_device_tree_early(dn); - - scan_phb(phb); -- pcibios_fixup_new_pci_devices(phb->bus, 0); -+ pcibios_fixup_new_pci_devices(phb->bus); - pci_bus_add_devices(phb->bus); - eeh_add_device_tree_late(phb->bus); - ---- a/arch/powerpc/platforms/pseries/plpar_wrappers.h -+++ b/arch/powerpc/platforms/pseries/plpar_wrappers.h -@@ -8,11 +8,6 @@ static inline long poll_pending(void) - return plpar_hcall_norets(H_POLL_PENDING); - } - --static inline long prod_processor(void) --{ -- return plpar_hcall_norets(H_PROD); --} -- - static inline long cede_processor(void) - { - return plpar_hcall_norets(H_CEDE); ---- a/arch/powerpc/platforms/pseries/smp.c -+++ b/arch/powerpc/platforms/pseries/smp.c -@@ -46,6 +46,7 @@ - #include - #include - #include -+#include - - #include "plpar_wrappers.h" - #include "pseries.h" -@@ -202,7 +203,7 @@ static int smp_pSeries_cpu_bootable(unsi - */ - if (system_state < SYSTEM_RUNNING && - cpu_has_feature(CPU_FTR_SMT) && -- !smt_enabled_at_boot && nr % 2 != 0) -+ !smt_enabled_at_boot && cpu_thread_in_core(nr) != 0) - return 0; - - return 1; ---- a/arch/powerpc/platforms/pseries/xics.c -+++ b/arch/powerpc/platforms/pseries/xics.c -@@ -87,19 +87,25 @@ static int ibm_int_off; - /* Direct HW low level accessors */ - - --static inline unsigned int direct_xirr_info_get(int n_cpu) -+static inline unsigned int direct_xirr_info_get(void) - { -- return in_be32(&xics_per_cpu[n_cpu]->xirr.word); -+ int cpu = smp_processor_id(); -+ -+ return in_be32(&xics_per_cpu[cpu]->xirr.word); - } - --static inline void direct_xirr_info_set(int n_cpu, int value) -+static inline void direct_xirr_info_set(int value) - { -- out_be32(&xics_per_cpu[n_cpu]->xirr.word, value); -+ int cpu = smp_processor_id(); -+ -+ out_be32(&xics_per_cpu[cpu]->xirr.word, value); - } - --static inline void direct_cppr_info(int n_cpu, u8 value) -+static inline void direct_cppr_info(u8 value) - { -- out_8(&xics_per_cpu[n_cpu]->xirr.bytes[0], value); -+ int cpu = smp_processor_id(); -+ -+ out_8(&xics_per_cpu[cpu]->xirr.bytes[0], value); - } - - static inline void direct_qirr_info(int n_cpu, u8 value) -@@ -111,7 +117,7 @@ static inline void direct_qirr_info(int - /* LPAR low level accessors */ - - --static inline unsigned int lpar_xirr_info_get(int n_cpu) -+static inline unsigned int lpar_xirr_info_get(void) - { - unsigned long lpar_rc; - unsigned long return_value; -@@ -122,7 +128,7 @@ static inline unsigned int lpar_xirr_inf - return (unsigned int)return_value; - } - --static inline void lpar_xirr_info_set(int n_cpu, int value) -+static inline void lpar_xirr_info_set(int value) - { - unsigned long lpar_rc; - unsigned long val64 = value & 0xffffffff; -@@ -133,7 +139,7 @@ static inline void lpar_xirr_info_set(in - val64); - } - --static inline void lpar_cppr_info(int n_cpu, u8 value) -+static inline void lpar_cppr_info(u8 value) - { - unsigned long lpar_rc; - -@@ -275,21 +281,19 @@ static unsigned int xics_startup(unsigne - - static void xics_eoi_direct(unsigned int virq) - { -- int cpu = smp_processor_id(); - unsigned int irq = (unsigned int)irq_map[virq].hwirq; - - iosync(); -- direct_xirr_info_set(cpu, (0xff << 24) | irq); -+ direct_xirr_info_set((0xff << 24) | irq); - } - - - static void xics_eoi_lpar(unsigned int virq) - { -- int cpu = smp_processor_id(); - unsigned int irq = (unsigned int)irq_map[virq].hwirq; - - iosync(); -- lpar_xirr_info_set(cpu, (0xff << 24) | irq); -+ lpar_xirr_info_set((0xff << 24) | irq); - } - - static inline unsigned int xics_remap_irq(unsigned int vec) -@@ -312,16 +316,12 @@ static inline unsigned int xics_remap_ir - - static unsigned int xics_get_irq_direct(void) - { -- unsigned int cpu = smp_processor_id(); -- -- return xics_remap_irq(direct_xirr_info_get(cpu)); -+ return xics_remap_irq(direct_xirr_info_get()); - } - - static unsigned int xics_get_irq_lpar(void) - { -- unsigned int cpu = smp_processor_id(); -- -- return xics_remap_irq(lpar_xirr_info_get(cpu)); -+ return xics_remap_irq(lpar_xirr_info_get()); - } - - #ifdef CONFIG_SMP -@@ -387,12 +387,12 @@ void xics_cause_IPI(int cpu) - - #endif /* CONFIG_SMP */ - --static void xics_set_cpu_priority(int cpu, unsigned char cppr) -+static void xics_set_cpu_priority(unsigned char cppr) - { - if (firmware_has_feature(FW_FEATURE_LPAR)) -- lpar_cppr_info(cpu, cppr); -+ lpar_cppr_info(cppr); - else -- direct_cppr_info(cpu, cppr); -+ direct_cppr_info(cppr); - iosync(); - } - -@@ -440,9 +440,7 @@ static void xics_set_affinity(unsigned i - - void xics_setup_cpu(void) - { -- int cpu = smp_processor_id(); -- -- xics_set_cpu_priority(cpu, 0xff); -+ xics_set_cpu_priority(0xff); - - /* - * Put the calling processor into the GIQ. This is really only -@@ -783,7 +781,7 @@ void xics_teardown_cpu(int secondary) - unsigned int ipi; - struct irq_desc *desc; - -- xics_set_cpu_priority(cpu, 0); -+ xics_set_cpu_priority(0); - - /* - * Clear IPI -@@ -824,10 +822,11 @@ void xics_teardown_cpu(int secondary) - void xics_migrate_irqs_away(void) - { - int status; -- unsigned int irq, virq, cpu = smp_processor_id(); -+ int cpu = smp_processor_id(), hw_cpu = hard_smp_processor_id(); -+ unsigned int irq, virq; - - /* Reject any interrupt that was queued to us... */ -- xics_set_cpu_priority(cpu, 0); -+ xics_set_cpu_priority(0); - - /* remove ourselves from the global interrupt queue */ - status = rtas_set_indicator_fast(GLOBAL_INTERRUPT_QUEUE, -@@ -835,7 +834,7 @@ void xics_migrate_irqs_away(void) - WARN_ON(status < 0); - - /* Allow IPIs again... */ -- xics_set_cpu_priority(cpu, DEFAULT_PRIORITY); -+ xics_set_cpu_priority(DEFAULT_PRIORITY); - - for_each_irq(virq) { - struct irq_desc *desc; -@@ -874,7 +873,7 @@ void xics_migrate_irqs_away(void) - * The irq has to be migrated only in the single cpu - * case. - */ -- if (xics_status[0] != get_hard_smp_processor_id(cpu)) -+ if (xics_status[0] != hw_cpu) - goto unlock; - - printk(KERN_WARNING "IRQ %u affinity broken off cpu %u\n", ---- a/arch/powerpc/platforms/pseries/xics.h -+++ b/arch/powerpc/platforms/pseries/xics.h -@@ -21,9 +21,6 @@ extern void xics_cause_IPI(int cpu); - extern void xics_request_IPIs(void); - extern void xics_migrate_irqs_away(void); - --/* first argument is ignored for now*/ --void pSeriesLP_cppr_info(int n_cpu, u8 value); -- - struct xics_ipi_struct { - volatile unsigned long value; - } ____cacheline_aligned; ---- /dev/null -+++ b/arch/powerpc/sysdev/Kconfig -@@ -0,0 +1,8 @@ -+# For a description of the syntax of this configuration file, -+# see Documentation/kbuild/kconfig-language.txt. -+# -+ -+config PPC4xx_PCI_EXPRESS -+ bool -+ depends on PCI && 4xx -+ default n ---- a/arch/powerpc/sysdev/Makefile -+++ b/arch/powerpc/sysdev/Makefile -@@ -2,7 +2,7 @@ ifeq ($(CONFIG_PPC64),y) - EXTRA_CFLAGS += -mno-minimal-toc - endif - --mpic-msi-obj-$(CONFIG_PCI_MSI) += mpic_msi.o mpic_u3msi.o -+mpic-msi-obj-$(CONFIG_PCI_MSI) += mpic_msi.o mpic_u3msi.o mpic_pasemi_msi.o - obj-$(CONFIG_MPIC) += mpic.o $(mpic-msi-obj-y) - - obj-$(CONFIG_PPC_MPC106) += grackle.o -@@ -12,6 +12,7 @@ obj-$(CONFIG_U3_DART) += dart_iommu.o - obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o - obj-$(CONFIG_FSL_SOC) += fsl_soc.o - obj-$(CONFIG_FSL_PCI) += fsl_pci.o -+obj-$(CONFIG_RAPIDIO) += fsl_rio.o - obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o - obj-$(CONFIG_QUICC_ENGINE) += qe_lib/ - obj-$(CONFIG_PPC_BESTCOMM) += bestcomm/ -@@ -24,9 +25,13 @@ obj-$(CONFIG_AXON_RAM) += axonram.o - ifeq ($(CONFIG_PPC_MERGE),y) - obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o - obj-$(CONFIG_PPC_I8259) += i8259.o --obj-$(CONFIG_PPC_83xx) += ipic.o -+obj-$(CONFIG_IPIC) += ipic.o - obj-$(CONFIG_4xx) += uic.o - obj-$(CONFIG_XILINX_VIRTEX) += xilinx_intc.o -+obj-$(CONFIG_OF_RTC) += of_rtc.o -+ifeq ($(CONFIG_PCI),y) -+obj-$(CONFIG_4xx) += ppc4xx_pci.o -+endif - endif - - # Temporary hack until we have migrated to asm-powerpc ---- a/arch/powerpc/sysdev/axonram.c -+++ b/arch/powerpc/sysdev/axonram.c -@@ -42,8 +42,9 @@ - #include - #include - #include --#include --#include -+#include -+#include -+ - #include - #include - ---- a/arch/powerpc/sysdev/bestcomm/bestcomm.h -+++ b/arch/powerpc/sysdev/bestcomm/bestcomm.h -@@ -20,7 +20,7 @@ struct bcom_bd; /* defined later on ... - - - /* ======================================================================== */ --/* Generic task managment */ -+/* Generic task management */ - /* ======================================================================== */ - - /** ---- a/arch/powerpc/sysdev/commproc.c -+++ b/arch/powerpc/sysdev/commproc.c -@@ -240,6 +240,34 @@ void __init cpm_reset(void) - #endif - } - -+static DEFINE_SPINLOCK(cmd_lock); -+ -+#define MAX_CR_CMD_LOOPS 10000 -+ -+int cpm_command(u32 command, u8 opcode) -+{ -+ int i, ret; -+ unsigned long flags; -+ -+ if (command & 0xffffff0f) -+ return -EINVAL; -+ -+ spin_lock_irqsave(&cmd_lock, flags); -+ -+ ret = 0; -+ out_be16(&cpmp->cp_cpcr, command | CPM_CR_FLG | (opcode << 8)); -+ for (i = 0; i < MAX_CR_CMD_LOOPS; i++) -+ if ((in_be16(&cpmp->cp_cpcr) & CPM_CR_FLG) == 0) -+ goto out; -+ -+ printk(KERN_ERR "%s(): Not able to issue CPM command\n", __FUNCTION__); -+ ret = -EIO; -+out: -+ spin_unlock_irqrestore(&cmd_lock, flags); -+ return ret; -+} -+EXPORT_SYMBOL(cpm_command); -+ - /* We used to do this earlier, but have to postpone as long as possible - * to ensure the kernel VM is now running. - */ -@@ -408,7 +436,7 @@ EXPORT_SYMBOL(cpm_dpram_phys); - #endif /* !CONFIG_PPC_CPM_NEW_BINDING */ - - struct cpm_ioport16 { -- __be16 dir, par, sor, dat, intr; -+ __be16 dir, par, odr_sor, dat, intr; - __be16 res[3]; - }; - -@@ -438,6 +466,13 @@ static void cpm1_set_pin32(int port, int - else - clrbits32(&iop->par, pin); - -+ if (port == CPM_PORTB) { -+ if (flags & CPM_PIN_OPENDRAIN) -+ setbits16(&mpc8xx_immr->im_cpm.cp_pbodr, pin); -+ else -+ clrbits16(&mpc8xx_immr->im_cpm.cp_pbodr, pin); -+ } -+ - if (port == CPM_PORTE) { - if (flags & CPM_PIN_SECONDARY) - setbits32(&iop->sor, pin); -@@ -471,11 +506,17 @@ static void cpm1_set_pin16(int port, int - else - clrbits16(&iop->par, pin); - -+ if (port == CPM_PORTA) { -+ if (flags & CPM_PIN_OPENDRAIN) -+ setbits16(&iop->odr_sor, pin); -+ else -+ clrbits16(&iop->odr_sor, pin); -+ } - if (port == CPM_PORTC) { - if (flags & CPM_PIN_SECONDARY) -- setbits16(&iop->sor, pin); -+ setbits16(&iop->odr_sor, pin); - else -- clrbits16(&iop->sor, pin); -+ clrbits16(&iop->odr_sor, pin); - } - } - ---- a/arch/powerpc/sysdev/cpm2_common.c -+++ b/arch/powerpc/sysdev/cpm2_common.c -@@ -82,6 +82,31 @@ void __init cpm2_reset(void) - cpmp = &cpm2_immr->im_cpm; - } - -+static DEFINE_SPINLOCK(cmd_lock); -+ -+#define MAX_CR_CMD_LOOPS 10000 -+ -+int cpm_command(u32 command, u8 opcode) -+{ -+ int i, ret; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&cmd_lock, flags); -+ -+ ret = 0; -+ out_be32(&cpmp->cp_cpcr, command | opcode | CPM_CR_FLG); -+ for (i = 0; i < MAX_CR_CMD_LOOPS; i++) -+ if ((in_be32(&cpmp->cp_cpcr) & CPM_CR_FLG) == 0) -+ goto out; -+ -+ printk(KERN_ERR "%s(): Not able to issue CPM command\n", __FUNCTION__); -+ ret = -EIO; -+out: -+ spin_unlock_irqrestore(&cmd_lock, flags); -+ return ret; -+} -+EXPORT_SYMBOL(cpm_command); -+ - /* Set a baud rate generator. This needs lots of work. There are - * eight BRGs, which can be connected to the CPM channels or output - * as clocks. The BRGs are in two different block of internal ---- a/arch/powerpc/sysdev/fsl_pci.c -+++ b/arch/powerpc/sysdev/fsl_pci.c -@@ -33,8 +33,8 @@ void __init setup_pci_atmu(struct pci_co - struct ccsr_pci __iomem *pci; - int i; - -- pr_debug("PCI memory map start 0x%x, size 0x%x\n", rsrc->start, -- rsrc->end - rsrc->start + 1); -+ pr_debug("PCI memory map start 0x%016llx, size 0x%016llx\n", -+ (u64)rsrc->start, (u64)rsrc->end - (u64)rsrc->start + 1); - pci = ioremap(rsrc->start, rsrc->end - rsrc->start + 1); - - /* Disable all windows (except powar0 since its ignored) */ -@@ -46,17 +46,17 @@ void __init setup_pci_atmu(struct pci_co - /* Setup outbound MEM window */ - for(i = 0; i < 3; i++) - if (hose->mem_resources[i].flags & IORESOURCE_MEM){ -- pr_debug("PCI MEM resource start 0x%08x, size 0x%08x.\n", -- hose->mem_resources[i].start, -- hose->mem_resources[i].end -- - hose->mem_resources[i].start + 1); -- out_be32(&pci->pow[i+1].potar, -- (hose->mem_resources[i].start >> 12) -- & 0x000fffff); -+ resource_size_t pci_addr_start = -+ hose->mem_resources[i].start - -+ hose->pci_mem_offset; -+ pr_debug("PCI MEM resource start 0x%016llx, size 0x%016llx.\n", -+ (u64)hose->mem_resources[i].start, -+ (u64)hose->mem_resources[i].end -+ - (u64)hose->mem_resources[i].start + 1); -+ out_be32(&pci->pow[i+1].potar, (pci_addr_start >> 12)); - out_be32(&pci->pow[i+1].potear, 0); - out_be32(&pci->pow[i+1].powbar, -- (hose->mem_resources[i].start >> 12) -- & 0x000fffff); -+ (hose->mem_resources[i].start >> 12)); - /* Enable, Mem R/W */ - out_be32(&pci->pow[i+1].powar, 0x80044000 - | (__ilog2(hose->mem_resources[i].end -@@ -65,15 +65,14 @@ void __init setup_pci_atmu(struct pci_co - - /* Setup outbound IO window */ - if (hose->io_resource.flags & IORESOURCE_IO){ -- pr_debug("PCI IO resource start 0x%08x, size 0x%08x, phy base 0x%08x.\n", -- hose->io_resource.start, -- hose->io_resource.end - hose->io_resource.start + 1, -- hose->io_base_phys); -- out_be32(&pci->pow[i+1].potar, (hose->io_resource.start >> 12) -- & 0x000fffff); -+ pr_debug("PCI IO resource start 0x%016llx, size 0x%016llx, " -+ "phy base 0x%016llx.\n", -+ (u64)hose->io_resource.start, -+ (u64)hose->io_resource.end - (u64)hose->io_resource.start + 1, -+ (u64)hose->io_base_phys); -+ out_be32(&pci->pow[i+1].potar, (hose->io_resource.start >> 12)); - out_be32(&pci->pow[i+1].potear, 0); -- out_be32(&pci->pow[i+1].powbar, (hose->io_base_phys >> 12) -- & 0x000fffff); -+ out_be32(&pci->pow[i+1].powbar, (hose->io_base_phys >> 12)); - /* Enable, IO R/W */ - out_be32(&pci->pow[i+1].powar, 0x80088000 - | (__ilog2(hose->io_resource.end -@@ -107,55 +106,17 @@ void __init setup_pci_cmd(struct pci_con - } - } - --static void __init quirk_fsl_pcie_transparent(struct pci_dev *dev) --{ -- struct resource *res; -- int i, res_idx = PCI_BRIDGE_RESOURCES; -- struct pci_controller *hose; -+static int fsl_pcie_bus_fixup; - -+static void __init quirk_fsl_pcie_header(struct pci_dev *dev) -+{ - /* if we aren't a PCIe don't bother */ - if (!pci_find_capability(dev, PCI_CAP_ID_EXP)) - return ; - -- /* -- * Make the bridge be transparent. -- */ -- dev->transparent = 1; -- -- hose = pci_bus_to_host(dev->bus); -- if (!hose) { -- printk(KERN_ERR "Can't find hose for bus %d\n", -- dev->bus->number); -- return; -- } -- -- /* Clear out any of the virtual P2P bridge registers */ -- pci_write_config_word(dev, PCI_IO_BASE_UPPER16, 0); -- pci_write_config_word(dev, PCI_IO_LIMIT_UPPER16, 0); -- pci_write_config_byte(dev, PCI_IO_BASE, 0x10); -- pci_write_config_byte(dev, PCI_IO_LIMIT, 0); -- pci_write_config_word(dev, PCI_MEMORY_BASE, 0x10); -- pci_write_config_word(dev, PCI_MEMORY_LIMIT, 0); -- pci_write_config_word(dev, PCI_PREF_BASE_UPPER32, 0x0); -- pci_write_config_word(dev, PCI_PREF_LIMIT_UPPER32, 0x0); -- pci_write_config_word(dev, PCI_PREF_MEMORY_BASE, 0x10); -- pci_write_config_word(dev, PCI_PREF_MEMORY_LIMIT, 0); -- -- if (hose->io_resource.flags) { -- res = &dev->resource[res_idx++]; -- res->start = hose->io_resource.start; -- res->end = hose->io_resource.end; -- res->flags = hose->io_resource.flags; -- update_bridge_resource(dev, res); -- } -- -- for (i = 0; i < 3; i++) { -- res = &dev->resource[res_idx + i]; -- res->start = hose->mem_resources[i].start; -- res->end = hose->mem_resources[i].end; -- res->flags = hose->mem_resources[i].flags; -- update_bridge_resource(dev, res); -- } -+ dev->class = PCI_CLASS_BRIDGE_PCI << 8; -+ fsl_pcie_bus_fixup = 1; -+ return ; - } - - int __init fsl_pcie_check_link(struct pci_controller *hose) -@@ -172,11 +133,24 @@ void fsl_pcibios_fixup_bus(struct pci_bu - struct pci_controller *hose = (struct pci_controller *) bus->sysdata; - int i; - -- /* deal with bogus pci_bus when we don't have anything connected on PCIe */ -- if (hose->indirect_type & PPC_INDIRECT_TYPE_NO_PCIE_LINK) { -- if (bus->parent) { -- for (i = 0; i < 4; ++i) -- bus->resource[i] = bus->parent->resource[i]; -+ if ((bus->parent == hose->bus) && -+ ((fsl_pcie_bus_fixup && -+ early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) || -+ (hose->indirect_type & PPC_INDIRECT_TYPE_NO_PCIE_LINK))) -+ { -+ for (i = 0; i < 4; ++i) { -+ struct resource *res = bus->resource[i]; -+ struct resource *par = bus->parent->resource[i]; -+ if (res) { -+ res->start = 0; -+ res->end = 0; -+ res->flags = 0; -+ } -+ if (res && par) { -+ res->start = par->start; -+ res->end = par->end; -+ res->flags = par->flags; -+ } - } - } - } -@@ -202,7 +176,7 @@ int __init fsl_add_bridge(struct device_ - printk(KERN_WARNING "Can't get bus-range for %s, assume" - " bus 0\n", dev->full_name); - -- pci_assign_all_buses = 1; -+ ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS; - hose = pcibios_alloc_controller(dev); - if (!hose) - return -ENOMEM; -@@ -222,7 +196,7 @@ int __init fsl_add_bridge(struct device_ - hose->indirect_type |= PPC_INDIRECT_TYPE_NO_PCIE_LINK; - } - -- printk(KERN_INFO "Found FSL PCI host bridge at 0x%016llx." -+ printk(KERN_INFO "Found FSL PCI host bridge at 0x%016llx. " - "Firmware bus number: %d->%d\n", - (unsigned long long)rsrc.start, hose->first_busno, - hose->last_busno); -@@ -240,23 +214,23 @@ int __init fsl_add_bridge(struct device_ - return 0; - } - --DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8548E, quirk_fsl_pcie_transparent); --DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8548, quirk_fsl_pcie_transparent); --DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8543E, quirk_fsl_pcie_transparent); --DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8543, quirk_fsl_pcie_transparent); --DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8547E, quirk_fsl_pcie_transparent); --DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8545E, quirk_fsl_pcie_transparent); --DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8545, quirk_fsl_pcie_transparent); --DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8568E, quirk_fsl_pcie_transparent); --DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8568, quirk_fsl_pcie_transparent); --DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8567E, quirk_fsl_pcie_transparent); --DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8567, quirk_fsl_pcie_transparent); --DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8533E, quirk_fsl_pcie_transparent); --DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8533, quirk_fsl_pcie_transparent); --DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8544E, quirk_fsl_pcie_transparent); --DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8544, quirk_fsl_pcie_transparent); --DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8572E, quirk_fsl_pcie_transparent); --DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8572, quirk_fsl_pcie_transparent); --DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8641, quirk_fsl_pcie_transparent); --DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8641D, quirk_fsl_pcie_transparent); --DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8610, quirk_fsl_pcie_transparent); -+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8548E, quirk_fsl_pcie_header); -+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8548, quirk_fsl_pcie_header); -+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8543E, quirk_fsl_pcie_header); -+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8543, quirk_fsl_pcie_header); -+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8547E, quirk_fsl_pcie_header); -+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8545E, quirk_fsl_pcie_header); -+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8545, quirk_fsl_pcie_header); -+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8568E, quirk_fsl_pcie_header); -+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8568, quirk_fsl_pcie_header); -+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8567E, quirk_fsl_pcie_header); -+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8567, quirk_fsl_pcie_header); -+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8533E, quirk_fsl_pcie_header); -+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8533, quirk_fsl_pcie_header); -+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8544E, quirk_fsl_pcie_header); -+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8544, quirk_fsl_pcie_header); -+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8572E, quirk_fsl_pcie_header); -+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8572, quirk_fsl_pcie_header); -+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8641, quirk_fsl_pcie_header); -+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8641D, quirk_fsl_pcie_header); -+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8610, quirk_fsl_pcie_header); ---- /dev/null -+++ b/arch/powerpc/sysdev/fsl_rio.c -@@ -0,0 +1,932 @@ -+/* -+ * MPC85xx RapidIO support -+ * -+ * Copyright 2005 MontaVista Software, Inc. -+ * Matt Porter -+ * -+ * 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 -+ -+#define RIO_REGS_BASE (CCSRBAR + 0xc0000) -+#define RIO_ATMU_REGS_OFFSET 0x10c00 -+#define RIO_MSG_REGS_OFFSET 0x11000 -+#define RIO_MAINT_WIN_SIZE 0x400000 -+#define RIO_DBELL_WIN_SIZE 0x1000 -+ -+#define RIO_MSG_OMR_MUI 0x00000002 -+#define RIO_MSG_OSR_TE 0x00000080 -+#define RIO_MSG_OSR_QOI 0x00000020 -+#define RIO_MSG_OSR_QFI 0x00000010 -+#define RIO_MSG_OSR_MUB 0x00000004 -+#define RIO_MSG_OSR_EOMI 0x00000002 -+#define RIO_MSG_OSR_QEI 0x00000001 -+ -+#define RIO_MSG_IMR_MI 0x00000002 -+#define RIO_MSG_ISR_TE 0x00000080 -+#define RIO_MSG_ISR_QFI 0x00000010 -+#define RIO_MSG_ISR_DIQI 0x00000001 -+ -+#define RIO_MSG_DESC_SIZE 32 -+#define RIO_MSG_BUFFER_SIZE 4096 -+#define RIO_MIN_TX_RING_SIZE 2 -+#define RIO_MAX_TX_RING_SIZE 2048 -+#define RIO_MIN_RX_RING_SIZE 2 -+#define RIO_MAX_RX_RING_SIZE 2048 -+ -+#define DOORBELL_DMR_DI 0x00000002 -+#define DOORBELL_DSR_TE 0x00000080 -+#define DOORBELL_DSR_QFI 0x00000010 -+#define DOORBELL_DSR_DIQI 0x00000001 -+#define DOORBELL_TID_OFFSET 0x03 -+#define DOORBELL_SID_OFFSET 0x05 -+#define DOORBELL_INFO_OFFSET 0x06 -+ -+#define DOORBELL_MESSAGE_SIZE 0x08 -+#define DBELL_SID(x) (*(u8 *)(x + DOORBELL_SID_OFFSET)) -+#define DBELL_TID(x) (*(u8 *)(x + DOORBELL_TID_OFFSET)) -+#define DBELL_INF(x) (*(u16 *)(x + DOORBELL_INFO_OFFSET)) -+ -+struct rio_atmu_regs { -+ u32 rowtar; -+ u32 pad1; -+ u32 rowbar; -+ u32 pad2; -+ u32 rowar; -+ u32 pad3[3]; -+}; -+ -+struct rio_msg_regs { -+ u32 omr; -+ u32 osr; -+ u32 pad1; -+ u32 odqdpar; -+ u32 pad2; -+ u32 osar; -+ u32 odpr; -+ u32 odatr; -+ u32 odcr; -+ u32 pad3; -+ u32 odqepar; -+ u32 pad4[13]; -+ u32 imr; -+ u32 isr; -+ u32 pad5; -+ u32 ifqdpar; -+ u32 pad6; -+ u32 ifqepar; -+ u32 pad7[250]; -+ u32 dmr; -+ u32 dsr; -+ u32 pad8; -+ u32 dqdpar; -+ u32 pad9; -+ u32 dqepar; -+ u32 pad10[26]; -+ u32 pwmr; -+ u32 pwsr; -+ u32 pad11; -+ u32 pwqbar; -+}; -+ -+struct rio_tx_desc { -+ u32 res1; -+ u32 saddr; -+ u32 dport; -+ u32 dattr; -+ u32 res2; -+ u32 res3; -+ u32 dwcnt; -+ u32 res4; -+}; -+ -+static u32 regs_win; -+static struct rio_atmu_regs *atmu_regs; -+static struct rio_atmu_regs *maint_atmu_regs; -+static struct rio_atmu_regs *dbell_atmu_regs; -+static u32 dbell_win; -+static u32 maint_win; -+static struct rio_msg_regs *msg_regs; -+ -+static struct rio_dbell_ring { -+ void *virt; -+ dma_addr_t phys; -+} dbell_ring; -+ -+static struct rio_msg_tx_ring { -+ void *virt; -+ dma_addr_t phys; -+ void *virt_buffer[RIO_MAX_TX_RING_SIZE]; -+ dma_addr_t phys_buffer[RIO_MAX_TX_RING_SIZE]; -+ int tx_slot; -+ int size; -+ void *dev_id; -+} msg_tx_ring; -+ -+static struct rio_msg_rx_ring { -+ void *virt; -+ dma_addr_t phys; -+ void *virt_buffer[RIO_MAX_RX_RING_SIZE]; -+ int rx_slot; -+ int size; -+ void *dev_id; -+} msg_rx_ring; -+ -+/** -+ * mpc85xx_rio_doorbell_send - Send a MPC85xx doorbell message -+ * @index: ID of RapidIO interface -+ * @destid: Destination ID of target device -+ * @data: 16-bit info field of RapidIO doorbell message -+ * -+ * Sends a MPC85xx doorbell message. Returns %0 on success or -+ * %-EINVAL on failure. -+ */ -+static int mpc85xx_rio_doorbell_send(int index, u16 destid, u16 data) -+{ -+ pr_debug("mpc85xx_doorbell_send: index %d destid %4.4x data %4.4x\n", -+ index, destid, data); -+ out_be32((void *)&dbell_atmu_regs->rowtar, destid << 22); -+ out_be16((void *)(dbell_win), data); -+ -+ return 0; -+} -+ -+/** -+ * mpc85xx_local_config_read - Generate a MPC85xx local config space read -+ * @index: ID of RapdiIO interface -+ * @offset: Offset into configuration space -+ * @len: Length (in bytes) of the maintenance transaction -+ * @data: Value to be read into -+ * -+ * Generates a MPC85xx local configuration space read. Returns %0 on -+ * success or %-EINVAL on failure. -+ */ -+static int mpc85xx_local_config_read(int index, u32 offset, int len, u32 * data) -+{ -+ pr_debug("mpc85xx_local_config_read: index %d offset %8.8x\n", index, -+ offset); -+ *data = in_be32((void *)(regs_win + offset)); -+ -+ return 0; -+} -+ -+/** -+ * mpc85xx_local_config_write - Generate a MPC85xx local config space write -+ * @index: ID of RapdiIO interface -+ * @offset: Offset into configuration space -+ * @len: Length (in bytes) of the maintenance transaction -+ * @data: Value to be written -+ * -+ * Generates a MPC85xx local configuration space write. Returns %0 on -+ * success or %-EINVAL on failure. -+ */ -+static int mpc85xx_local_config_write(int index, u32 offset, int len, u32 data) -+{ -+ pr_debug -+ ("mpc85xx_local_config_write: index %d offset %8.8x data %8.8x\n", -+ index, offset, data); -+ out_be32((void *)(regs_win + offset), data); -+ -+ return 0; -+} -+ -+/** -+ * mpc85xx_rio_config_read - Generate a MPC85xx read maintenance transaction -+ * @index: ID of RapdiIO interface -+ * @destid: Destination ID of transaction -+ * @hopcount: Number of hops to target device -+ * @offset: Offset into configuration space -+ * @len: Length (in bytes) of the maintenance transaction -+ * @val: Location to be read into -+ * -+ * Generates a MPC85xx read maintenance transaction. Returns %0 on -+ * success or %-EINVAL on failure. -+ */ -+static int -+mpc85xx_rio_config_read(int index, u16 destid, u8 hopcount, u32 offset, int len, -+ u32 * val) -+{ -+ u8 *data; -+ -+ pr_debug -+ ("mpc85xx_rio_config_read: index %d destid %d hopcount %d offset %8.8x len %d\n", -+ index, destid, hopcount, offset, len); -+ out_be32((void *)&maint_atmu_regs->rowtar, -+ (destid << 22) | (hopcount << 12) | ((offset & ~0x3) >> 9)); -+ -+ data = (u8 *) maint_win + offset; -+ switch (len) { -+ case 1: -+ *val = in_8((u8 *) data); -+ break; -+ case 2: -+ *val = in_be16((u16 *) data); -+ break; -+ default: -+ *val = in_be32((u32 *) data); -+ break; -+ } -+ -+ return 0; -+} -+ -+/** -+ * mpc85xx_rio_config_write - Generate a MPC85xx write maintenance transaction -+ * @index: ID of RapdiIO interface -+ * @destid: Destination ID of transaction -+ * @hopcount: Number of hops to target device -+ * @offset: Offset into configuration space -+ * @len: Length (in bytes) of the maintenance transaction -+ * @val: Value to be written -+ * -+ * Generates an MPC85xx write maintenance transaction. Returns %0 on -+ * success or %-EINVAL on failure. -+ */ -+static int -+mpc85xx_rio_config_write(int index, u16 destid, u8 hopcount, u32 offset, -+ int len, u32 val) -+{ -+ u8 *data; -+ pr_debug -+ ("mpc85xx_rio_config_write: index %d destid %d hopcount %d offset %8.8x len %d val %8.8x\n", -+ index, destid, hopcount, offset, len, val); -+ out_be32((void *)&maint_atmu_regs->rowtar, -+ (destid << 22) | (hopcount << 12) | ((offset & ~0x3) >> 9)); -+ -+ data = (u8 *) maint_win + offset; -+ switch (len) { -+ case 1: -+ out_8((u8 *) data, val); -+ break; -+ case 2: -+ out_be16((u16 *) data, val); -+ break; -+ default: -+ out_be32((u32 *) data, val); -+ break; -+ } -+ -+ return 0; -+} -+ -+/** -+ * rio_hw_add_outb_message - Add message to the MPC85xx outbound message queue -+ * @mport: Master port with outbound message queue -+ * @rdev: Target of outbound message -+ * @mbox: Outbound mailbox -+ * @buffer: Message to add to outbound queue -+ * @len: Length of message -+ * -+ * Adds the @buffer message to the MPC85xx outbound message queue. Returns -+ * %0 on success or %-EINVAL on failure. -+ */ -+int -+rio_hw_add_outb_message(struct rio_mport *mport, struct rio_dev *rdev, int mbox, -+ void *buffer, size_t len) -+{ -+ u32 omr; -+ struct rio_tx_desc *desc = -+ (struct rio_tx_desc *)msg_tx_ring.virt + msg_tx_ring.tx_slot; -+ int ret = 0; -+ -+ pr_debug -+ ("RIO: rio_hw_add_outb_message(): destid %4.4x mbox %d buffer %8.8x len %8.8x\n", -+ rdev->destid, mbox, (int)buffer, len); -+ -+ if ((len < 8) || (len > RIO_MAX_MSG_SIZE)) { -+ ret = -EINVAL; -+ goto out; -+ } -+ -+ /* Copy and clear rest of buffer */ -+ memcpy(msg_tx_ring.virt_buffer[msg_tx_ring.tx_slot], buffer, len); -+ if (len < (RIO_MAX_MSG_SIZE - 4)) -+ memset((void *)((u32) msg_tx_ring. -+ virt_buffer[msg_tx_ring.tx_slot] + len), 0, -+ RIO_MAX_MSG_SIZE - len); -+ -+ /* Set mbox field for message */ -+ desc->dport = mbox & 0x3; -+ -+ /* Enable EOMI interrupt, set priority, and set destid */ -+ desc->dattr = 0x28000000 | (rdev->destid << 2); -+ -+ /* Set transfer size aligned to next power of 2 (in double words) */ -+ desc->dwcnt = is_power_of_2(len) ? len : 1 << get_bitmask_order(len); -+ -+ /* Set snooping and source buffer address */ -+ desc->saddr = 0x00000004 | msg_tx_ring.phys_buffer[msg_tx_ring.tx_slot]; -+ -+ /* Increment enqueue pointer */ -+ omr = in_be32((void *)&msg_regs->omr); -+ out_be32((void *)&msg_regs->omr, omr | RIO_MSG_OMR_MUI); -+ -+ /* Go to next descriptor */ -+ if (++msg_tx_ring.tx_slot == msg_tx_ring.size) -+ msg_tx_ring.tx_slot = 0; -+ -+ out: -+ return ret; -+} -+ -+EXPORT_SYMBOL_GPL(rio_hw_add_outb_message); -+ -+/** -+ * mpc85xx_rio_tx_handler - MPC85xx outbound message interrupt handler -+ * @irq: Linux interrupt number -+ * @dev_instance: Pointer to interrupt-specific data -+ * -+ * Handles outbound message interrupts. Executes a register outbound -+ * mailbox event handler and acks the interrupt occurrence. -+ */ -+static irqreturn_t -+mpc85xx_rio_tx_handler(int irq, void *dev_instance) -+{ -+ int osr; -+ struct rio_mport *port = (struct rio_mport *)dev_instance; -+ -+ osr = in_be32((void *)&msg_regs->osr); -+ -+ if (osr & RIO_MSG_OSR_TE) { -+ pr_info("RIO: outbound message transmission error\n"); -+ out_be32((void *)&msg_regs->osr, RIO_MSG_OSR_TE); -+ goto out; -+ } -+ -+ if (osr & RIO_MSG_OSR_QOI) { -+ pr_info("RIO: outbound message queue overflow\n"); -+ out_be32((void *)&msg_regs->osr, RIO_MSG_OSR_QOI); -+ goto out; -+ } -+ -+ if (osr & RIO_MSG_OSR_EOMI) { -+ u32 dqp = in_be32((void *)&msg_regs->odqdpar); -+ int slot = (dqp - msg_tx_ring.phys) >> 5; -+ port->outb_msg[0].mcback(port, msg_tx_ring.dev_id, -1, slot); -+ -+ /* Ack the end-of-message interrupt */ -+ out_be32((void *)&msg_regs->osr, RIO_MSG_OSR_EOMI); -+ } -+ -+ out: -+ return IRQ_HANDLED; -+} -+ -+/** -+ * rio_open_outb_mbox - Initialize MPC85xx outbound mailbox -+ * @mport: Master port implementing the outbound message unit -+ * @dev_id: Device specific pointer to pass on event -+ * @mbox: Mailbox to open -+ * @entries: Number of entries in the outbound mailbox ring -+ * -+ * Initializes buffer ring, request the outbound message interrupt, -+ * and enables the outbound message unit. Returns %0 on success and -+ * %-EINVAL or %-ENOMEM on failure. -+ */ -+int rio_open_outb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entries) -+{ -+ int i, j, rc = 0; -+ -+ if ((entries < RIO_MIN_TX_RING_SIZE) || -+ (entries > RIO_MAX_TX_RING_SIZE) || (!is_power_of_2(entries))) { -+ rc = -EINVAL; -+ goto out; -+ } -+ -+ /* Initialize shadow copy ring */ -+ msg_tx_ring.dev_id = dev_id; -+ msg_tx_ring.size = entries; -+ -+ for (i = 0; i < msg_tx_ring.size; i++) { -+ if (! -+ (msg_tx_ring.virt_buffer[i] = -+ dma_alloc_coherent(NULL, RIO_MSG_BUFFER_SIZE, -+ &msg_tx_ring.phys_buffer[i], -+ GFP_KERNEL))) { -+ rc = -ENOMEM; -+ for (j = 0; j < msg_tx_ring.size; j++) -+ if (msg_tx_ring.virt_buffer[j]) -+ dma_free_coherent(NULL, -+ RIO_MSG_BUFFER_SIZE, -+ msg_tx_ring. -+ virt_buffer[j], -+ msg_tx_ring. -+ phys_buffer[j]); -+ goto out; -+ } -+ } -+ -+ /* Initialize outbound message descriptor ring */ -+ if (!(msg_tx_ring.virt = dma_alloc_coherent(NULL, -+ msg_tx_ring.size * -+ RIO_MSG_DESC_SIZE, -+ &msg_tx_ring.phys, -+ GFP_KERNEL))) { -+ rc = -ENOMEM; -+ goto out_dma; -+ } -+ memset(msg_tx_ring.virt, 0, msg_tx_ring.size * RIO_MSG_DESC_SIZE); -+ msg_tx_ring.tx_slot = 0; -+ -+ /* Point dequeue/enqueue pointers at first entry in ring */ -+ out_be32((void *)&msg_regs->odqdpar, msg_tx_ring.phys); -+ out_be32((void *)&msg_regs->odqepar, msg_tx_ring.phys); -+ -+ /* Configure for snooping */ -+ out_be32((void *)&msg_regs->osar, 0x00000004); -+ -+ /* Clear interrupt status */ -+ out_be32((void *)&msg_regs->osr, 0x000000b3); -+ -+ /* Hook up outbound message handler */ -+ if ((rc = -+ request_irq(MPC85xx_IRQ_RIO_TX, mpc85xx_rio_tx_handler, 0, -+ "msg_tx", (void *)mport)) < 0) -+ goto out_irq; -+ -+ /* -+ * Configure outbound message unit -+ * Snooping -+ * Interrupts (all enabled, except QEIE) -+ * Chaining mode -+ * Disable -+ */ -+ out_be32((void *)&msg_regs->omr, 0x00100220); -+ -+ /* Set number of entries */ -+ out_be32((void *)&msg_regs->omr, -+ in_be32((void *)&msg_regs->omr) | -+ ((get_bitmask_order(entries) - 2) << 12)); -+ -+ /* Now enable the unit */ -+ out_be32((void *)&msg_regs->omr, in_be32((void *)&msg_regs->omr) | 0x1); -+ -+ out: -+ return rc; -+ -+ out_irq: -+ dma_free_coherent(NULL, msg_tx_ring.size * RIO_MSG_DESC_SIZE, -+ msg_tx_ring.virt, msg_tx_ring.phys); -+ -+ out_dma: -+ for (i = 0; i < msg_tx_ring.size; i++) -+ dma_free_coherent(NULL, RIO_MSG_BUFFER_SIZE, -+ msg_tx_ring.virt_buffer[i], -+ msg_tx_ring.phys_buffer[i]); -+ -+ return rc; -+} -+ -+/** -+ * rio_close_outb_mbox - Shut down MPC85xx outbound mailbox -+ * @mport: Master port implementing the outbound message unit -+ * @mbox: Mailbox to close -+ * -+ * Disables the outbound message unit, free all buffers, and -+ * frees the outbound message interrupt. -+ */ -+void rio_close_outb_mbox(struct rio_mport *mport, int mbox) -+{ -+ /* Disable inbound message unit */ -+ out_be32((void *)&msg_regs->omr, 0); -+ -+ /* Free ring */ -+ dma_free_coherent(NULL, msg_tx_ring.size * RIO_MSG_DESC_SIZE, -+ msg_tx_ring.virt, msg_tx_ring.phys); -+ -+ /* Free interrupt */ -+ free_irq(MPC85xx_IRQ_RIO_TX, (void *)mport); -+} -+ -+/** -+ * mpc85xx_rio_rx_handler - MPC85xx inbound message interrupt handler -+ * @irq: Linux interrupt number -+ * @dev_instance: Pointer to interrupt-specific data -+ * -+ * Handles inbound message interrupts. Executes a registered inbound -+ * mailbox event handler and acks the interrupt occurrence. -+ */ -+static irqreturn_t -+mpc85xx_rio_rx_handler(int irq, void *dev_instance) -+{ -+ int isr; -+ struct rio_mport *port = (struct rio_mport *)dev_instance; -+ -+ isr = in_be32((void *)&msg_regs->isr); -+ -+ if (isr & RIO_MSG_ISR_TE) { -+ pr_info("RIO: inbound message reception error\n"); -+ out_be32((void *)&msg_regs->isr, RIO_MSG_ISR_TE); -+ goto out; -+ } -+ -+ /* XXX Need to check/dispatch until queue empty */ -+ if (isr & RIO_MSG_ISR_DIQI) { -+ /* -+ * We implement *only* mailbox 0, but can receive messages -+ * for any mailbox/letter to that mailbox destination. So, -+ * make the callback with an unknown/invalid mailbox number -+ * argument. -+ */ -+ port->inb_msg[0].mcback(port, msg_rx_ring.dev_id, -1, -1); -+ -+ /* Ack the queueing interrupt */ -+ out_be32((void *)&msg_regs->isr, RIO_MSG_ISR_DIQI); -+ } -+ -+ out: -+ return IRQ_HANDLED; -+} -+ -+/** -+ * rio_open_inb_mbox - Initialize MPC85xx inbound mailbox -+ * @mport: Master port implementing the inbound message unit -+ * @dev_id: Device specific pointer to pass on event -+ * @mbox: Mailbox to open -+ * @entries: Number of entries in the inbound mailbox ring -+ * -+ * Initializes buffer ring, request the inbound message interrupt, -+ * and enables the inbound message unit. Returns %0 on success -+ * and %-EINVAL or %-ENOMEM on failure. -+ */ -+int rio_open_inb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entries) -+{ -+ int i, rc = 0; -+ -+ if ((entries < RIO_MIN_RX_RING_SIZE) || -+ (entries > RIO_MAX_RX_RING_SIZE) || (!is_power_of_2(entries))) { -+ rc = -EINVAL; -+ goto out; -+ } -+ -+ /* Initialize client buffer ring */ -+ msg_rx_ring.dev_id = dev_id; -+ msg_rx_ring.size = entries; -+ msg_rx_ring.rx_slot = 0; -+ for (i = 0; i < msg_rx_ring.size; i++) -+ msg_rx_ring.virt_buffer[i] = NULL; -+ -+ /* Initialize inbound message ring */ -+ if (!(msg_rx_ring.virt = dma_alloc_coherent(NULL, -+ msg_rx_ring.size * -+ RIO_MAX_MSG_SIZE, -+ &msg_rx_ring.phys, -+ GFP_KERNEL))) { -+ rc = -ENOMEM; -+ goto out; -+ } -+ -+ /* Point dequeue/enqueue pointers at first entry in ring */ -+ out_be32((void *)&msg_regs->ifqdpar, (u32) msg_rx_ring.phys); -+ out_be32((void *)&msg_regs->ifqepar, (u32) msg_rx_ring.phys); -+ -+ /* Clear interrupt status */ -+ out_be32((void *)&msg_regs->isr, 0x00000091); -+ -+ /* Hook up inbound message handler */ -+ if ((rc = -+ request_irq(MPC85xx_IRQ_RIO_RX, mpc85xx_rio_rx_handler, 0, -+ "msg_rx", (void *)mport)) < 0) { -+ dma_free_coherent(NULL, RIO_MSG_BUFFER_SIZE, -+ msg_tx_ring.virt_buffer[i], -+ msg_tx_ring.phys_buffer[i]); -+ goto out; -+ } -+ -+ /* -+ * Configure inbound message unit: -+ * Snooping -+ * 4KB max message size -+ * Unmask all interrupt sources -+ * Disable -+ */ -+ out_be32((void *)&msg_regs->imr, 0x001b0060); -+ -+ /* Set number of queue entries */ -+ out_be32((void *)&msg_regs->imr, -+ in_be32((void *)&msg_regs->imr) | -+ ((get_bitmask_order(entries) - 2) << 12)); -+ -+ /* Now enable the unit */ -+ out_be32((void *)&msg_regs->imr, in_be32((void *)&msg_regs->imr) | 0x1); -+ -+ out: -+ return rc; -+} -+ -+/** -+ * rio_close_inb_mbox - Shut down MPC85xx inbound mailbox -+ * @mport: Master port implementing the inbound message unit -+ * @mbox: Mailbox to close -+ * -+ * Disables the inbound message unit, free all buffers, and -+ * frees the inbound message interrupt. -+ */ -+void rio_close_inb_mbox(struct rio_mport *mport, int mbox) -+{ -+ /* Disable inbound message unit */ -+ out_be32((void *)&msg_regs->imr, 0); -+ -+ /* Free ring */ -+ dma_free_coherent(NULL, msg_rx_ring.size * RIO_MAX_MSG_SIZE, -+ msg_rx_ring.virt, msg_rx_ring.phys); -+ -+ /* Free interrupt */ -+ free_irq(MPC85xx_IRQ_RIO_RX, (void *)mport); -+} -+ -+/** -+ * rio_hw_add_inb_buffer - Add buffer to the MPC85xx inbound message queue -+ * @mport: Master port implementing the inbound message unit -+ * @mbox: Inbound mailbox number -+ * @buf: Buffer to add to inbound queue -+ * -+ * Adds the @buf buffer to the MPC85xx inbound message queue. Returns -+ * %0 on success or %-EINVAL on failure. -+ */ -+int rio_hw_add_inb_buffer(struct rio_mport *mport, int mbox, void *buf) -+{ -+ int rc = 0; -+ -+ pr_debug("RIO: rio_hw_add_inb_buffer(), msg_rx_ring.rx_slot %d\n", -+ msg_rx_ring.rx_slot); -+ -+ if (msg_rx_ring.virt_buffer[msg_rx_ring.rx_slot]) { -+ printk(KERN_ERR -+ "RIO: error adding inbound buffer %d, buffer exists\n", -+ msg_rx_ring.rx_slot); -+ rc = -EINVAL; -+ goto out; -+ } -+ -+ msg_rx_ring.virt_buffer[msg_rx_ring.rx_slot] = buf; -+ if (++msg_rx_ring.rx_slot == msg_rx_ring.size) -+ msg_rx_ring.rx_slot = 0; -+ -+ out: -+ return rc; -+} -+ -+EXPORT_SYMBOL_GPL(rio_hw_add_inb_buffer); -+ -+/** -+ * rio_hw_get_inb_message - Fetch inbound message from the MPC85xx message unit -+ * @mport: Master port implementing the inbound message unit -+ * @mbox: Inbound mailbox number -+ * -+ * Gets the next available inbound message from the inbound message queue. -+ * A pointer to the message is returned on success or NULL on failure. -+ */ -+void *rio_hw_get_inb_message(struct rio_mport *mport, int mbox) -+{ -+ u32 imr; -+ u32 phys_buf, virt_buf; -+ void *buf = NULL; -+ int buf_idx; -+ -+ phys_buf = in_be32((void *)&msg_regs->ifqdpar); -+ -+ /* If no more messages, then bail out */ -+ if (phys_buf == in_be32((void *)&msg_regs->ifqepar)) -+ goto out2; -+ -+ virt_buf = (u32) msg_rx_ring.virt + (phys_buf - msg_rx_ring.phys); -+ buf_idx = (phys_buf - msg_rx_ring.phys) / RIO_MAX_MSG_SIZE; -+ buf = msg_rx_ring.virt_buffer[buf_idx]; -+ -+ if (!buf) { -+ printk(KERN_ERR -+ "RIO: inbound message copy failed, no buffers\n"); -+ goto out1; -+ } -+ -+ /* Copy max message size, caller is expected to allocate that big */ -+ memcpy(buf, (void *)virt_buf, RIO_MAX_MSG_SIZE); -+ -+ /* Clear the available buffer */ -+ msg_rx_ring.virt_buffer[buf_idx] = NULL; -+ -+ out1: -+ imr = in_be32((void *)&msg_regs->imr); -+ out_be32((void *)&msg_regs->imr, imr | RIO_MSG_IMR_MI); -+ -+ out2: -+ return buf; -+} -+ -+EXPORT_SYMBOL_GPL(rio_hw_get_inb_message); -+ -+/** -+ * mpc85xx_rio_dbell_handler - MPC85xx doorbell interrupt handler -+ * @irq: Linux interrupt number -+ * @dev_instance: Pointer to interrupt-specific data -+ * -+ * Handles doorbell interrupts. Parses a list of registered -+ * doorbell event handlers and executes a matching event handler. -+ */ -+static irqreturn_t -+mpc85xx_rio_dbell_handler(int irq, void *dev_instance) -+{ -+ int dsr; -+ struct rio_mport *port = (struct rio_mport *)dev_instance; -+ -+ dsr = in_be32((void *)&msg_regs->dsr); -+ -+ if (dsr & DOORBELL_DSR_TE) { -+ pr_info("RIO: doorbell reception error\n"); -+ out_be32((void *)&msg_regs->dsr, DOORBELL_DSR_TE); -+ goto out; -+ } -+ -+ if (dsr & DOORBELL_DSR_QFI) { -+ pr_info("RIO: doorbell queue full\n"); -+ out_be32((void *)&msg_regs->dsr, DOORBELL_DSR_QFI); -+ goto out; -+ } -+ -+ /* XXX Need to check/dispatch until queue empty */ -+ if (dsr & DOORBELL_DSR_DIQI) { -+ u32 dmsg = -+ (u32) dbell_ring.virt + -+ (in_be32((void *)&msg_regs->dqdpar) & 0xfff); -+ u32 dmr; -+ struct rio_dbell *dbell; -+ int found = 0; -+ -+ pr_debug -+ ("RIO: processing doorbell, sid %2.2x tid %2.2x info %4.4x\n", -+ DBELL_SID(dmsg), DBELL_TID(dmsg), DBELL_INF(dmsg)); -+ -+ list_for_each_entry(dbell, &port->dbells, node) { -+ if ((dbell->res->start <= DBELL_INF(dmsg)) && -+ (dbell->res->end >= DBELL_INF(dmsg))) { -+ found = 1; -+ break; -+ } -+ } -+ if (found) { -+ dbell->dinb(port, dbell->dev_id, DBELL_SID(dmsg), DBELL_TID(dmsg), -+ DBELL_INF(dmsg)); -+ } else { -+ pr_debug -+ ("RIO: spurious doorbell, sid %2.2x tid %2.2x info %4.4x\n", -+ DBELL_SID(dmsg), DBELL_TID(dmsg), DBELL_INF(dmsg)); -+ } -+ dmr = in_be32((void *)&msg_regs->dmr); -+ out_be32((void *)&msg_regs->dmr, dmr | DOORBELL_DMR_DI); -+ out_be32((void *)&msg_regs->dsr, DOORBELL_DSR_DIQI); -+ } -+ -+ out: -+ return IRQ_HANDLED; -+} -+ -+/** -+ * mpc85xx_rio_doorbell_init - MPC85xx doorbell interface init -+ * @mport: Master port implementing the inbound doorbell unit -+ * -+ * Initializes doorbell unit hardware and inbound DMA buffer -+ * ring. Called from mpc85xx_rio_setup(). Returns %0 on success -+ * or %-ENOMEM on failure. -+ */ -+static int mpc85xx_rio_doorbell_init(struct rio_mport *mport) -+{ -+ int rc = 0; -+ -+ /* Map outbound doorbell window immediately after maintenance window */ -+ if (!(dbell_win = -+ (u32) ioremap(mport->iores.start + RIO_MAINT_WIN_SIZE, -+ RIO_DBELL_WIN_SIZE))) { -+ printk(KERN_ERR -+ "RIO: unable to map outbound doorbell window\n"); -+ rc = -ENOMEM; -+ goto out; -+ } -+ -+ /* Initialize inbound doorbells */ -+ if (!(dbell_ring.virt = dma_alloc_coherent(NULL, -+ 512 * DOORBELL_MESSAGE_SIZE, -+ &dbell_ring.phys, -+ GFP_KERNEL))) { -+ printk(KERN_ERR "RIO: unable allocate inbound doorbell ring\n"); -+ rc = -ENOMEM; -+ iounmap((void *)dbell_win); -+ goto out; -+ } -+ -+ /* Point dequeue/enqueue pointers at first entry in ring */ -+ out_be32((void *)&msg_regs->dqdpar, (u32) dbell_ring.phys); -+ out_be32((void *)&msg_regs->dqepar, (u32) dbell_ring.phys); -+ -+ /* Clear interrupt status */ -+ out_be32((void *)&msg_regs->dsr, 0x00000091); -+ -+ /* Hook up doorbell handler */ -+ if ((rc = -+ request_irq(MPC85xx_IRQ_RIO_BELL, mpc85xx_rio_dbell_handler, 0, -+ "dbell_rx", (void *)mport) < 0)) { -+ iounmap((void *)dbell_win); -+ dma_free_coherent(NULL, 512 * DOORBELL_MESSAGE_SIZE, -+ dbell_ring.virt, dbell_ring.phys); -+ printk(KERN_ERR -+ "MPC85xx RIO: unable to request inbound doorbell irq"); -+ goto out; -+ } -+ -+ /* Configure doorbells for snooping, 512 entries, and enable */ -+ out_be32((void *)&msg_regs->dmr, 0x00108161); -+ -+ out: -+ return rc; -+} -+ -+static char *cmdline = NULL; -+ -+static int mpc85xx_rio_get_hdid(int index) -+{ -+ /* XXX Need to parse multiple entries in some format */ -+ if (!cmdline) -+ return -1; -+ -+ return simple_strtol(cmdline, NULL, 0); -+} -+ -+static int mpc85xx_rio_get_cmdline(char *s) -+{ -+ if (!s) -+ return 0; -+ -+ cmdline = s; -+ return 1; -+} -+ -+__setup("riohdid=", mpc85xx_rio_get_cmdline); -+ -+/** -+ * mpc85xx_rio_setup - Setup MPC85xx RapidIO interface -+ * @law_start: Starting physical address of RapidIO LAW -+ * @law_size: Size of RapidIO LAW -+ * -+ * Initializes MPC85xx RapidIO hardware interface, configures -+ * master port with system-specific info, and registers the -+ * master port with the RapidIO subsystem. -+ */ -+void mpc85xx_rio_setup(int law_start, int law_size) -+{ -+ struct rio_ops *ops; -+ struct rio_mport *port; -+ -+ ops = kmalloc(sizeof(struct rio_ops), GFP_KERNEL); -+ ops->lcread = mpc85xx_local_config_read; -+ ops->lcwrite = mpc85xx_local_config_write; -+ ops->cread = mpc85xx_rio_config_read; -+ ops->cwrite = mpc85xx_rio_config_write; -+ ops->dsend = mpc85xx_rio_doorbell_send; -+ -+ port = kmalloc(sizeof(struct rio_mport), GFP_KERNEL); -+ port->id = 0; -+ port->index = 0; -+ INIT_LIST_HEAD(&port->dbells); -+ port->iores.start = law_start; -+ port->iores.end = law_start + law_size; -+ port->iores.flags = IORESOURCE_MEM; -+ -+ rio_init_dbell_res(&port->riores[RIO_DOORBELL_RESOURCE], 0, 0xffff); -+ rio_init_mbox_res(&port->riores[RIO_INB_MBOX_RESOURCE], 0, 0); -+ rio_init_mbox_res(&port->riores[RIO_OUTB_MBOX_RESOURCE], 0, 0); -+ strcpy(port->name, "RIO0 mport"); -+ -+ port->ops = ops; -+ port->host_deviceid = mpc85xx_rio_get_hdid(port->id); -+ -+ rio_register_mport(port); -+ -+ regs_win = (u32) ioremap(RIO_REGS_BASE, 0x20000); -+ atmu_regs = (struct rio_atmu_regs *)(regs_win + RIO_ATMU_REGS_OFFSET); -+ maint_atmu_regs = atmu_regs + 1; -+ dbell_atmu_regs = atmu_regs + 2; -+ msg_regs = (struct rio_msg_regs *)(regs_win + RIO_MSG_REGS_OFFSET); -+ -+ /* Configure maintenance transaction window */ -+ out_be32((void *)&maint_atmu_regs->rowbar, 0x000c0000); -+ out_be32((void *)&maint_atmu_regs->rowar, 0x80077015); -+ -+ maint_win = (u32) ioremap(law_start, RIO_MAINT_WIN_SIZE); -+ -+ /* Configure outbound doorbell window */ -+ out_be32((void *)&dbell_atmu_regs->rowbar, 0x000c0400); -+ out_be32((void *)&dbell_atmu_regs->rowar, 0x8004200b); -+ mpc85xx_rio_doorbell_init(port); -+} ---- /dev/null -+++ b/arch/powerpc/sysdev/fsl_rio.h -@@ -0,0 +1,20 @@ -+/* -+ * MPC85xx RapidIO definitions -+ * -+ * Copyright 2005 MontaVista Software, Inc. -+ * Matt Porter -+ * -+ * 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 __PPC_SYSLIB_PPC85XX_RIO_H -+#define __PPC_SYSLIB_PPC85XX_RIO_H -+ -+#include -+ -+extern void mpc85xx_rio_setup(int law_start, int law_size); -+ -+#endif /* __PPC_SYSLIB_PPC85XX_RIO_H */ ---- a/arch/powerpc/sysdev/fsl_soc.c -+++ b/arch/powerpc/sysdev/fsl_soc.c -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -54,10 +55,18 @@ phys_addr_t get_immrbase(void) - soc = of_find_node_by_type(NULL, "soc"); - if (soc) { - int size; -- const void *prop = of_get_property(soc, "reg", &size); -+ u32 naddr; -+ const u32 *prop = of_get_property(soc, "#address-cells", &size); - -+ if (prop && size == 4) -+ naddr = *prop; -+ else -+ naddr = 2; -+ -+ prop = of_get_property(soc, "ranges", &size); - if (prop) -- immrbase = of_translate_address(soc, prop); -+ immrbase = of_translate_address(soc, prop + naddr); -+ - of_node_put(soc); - } - -@@ -130,17 +139,51 @@ u32 get_baudrate(void) - EXPORT_SYMBOL(get_baudrate); - #endif /* CONFIG_CPM2 */ - --static int __init gfar_mdio_of_init(void) -+#ifdef CONFIG_FIXED_PHY -+static int __init of_add_fixed_phys(void) - { -+ int ret; - struct device_node *np; -- unsigned int i; -+ u32 *fixed_link; -+ struct fixed_phy_status status = {}; -+ -+ for_each_node_by_name(np, "ethernet") { -+ fixed_link = (u32 *)of_get_property(np, "fixed-link", NULL); -+ if (!fixed_link) -+ continue; -+ -+ status.link = 1; -+ status.duplex = fixed_link[1]; -+ status.speed = fixed_link[2]; -+ status.pause = fixed_link[3]; -+ status.asym_pause = fixed_link[4]; -+ -+ ret = fixed_phy_add(PHY_POLL, fixed_link[0], &status); -+ if (ret) { -+ of_node_put(np); -+ return ret; -+ } -+ } -+ -+ return 0; -+} -+arch_initcall(of_add_fixed_phys); -+#endif /* CONFIG_FIXED_PHY */ -+ -+static int __init gfar_mdio_of_init(void) -+{ -+ struct device_node *np = NULL; - struct platform_device *mdio_dev; - struct resource res; - int ret; - -- for (np = NULL, i = 0; -- (np = of_find_compatible_node(np, "mdio", "gianfar")) != NULL; -- i++) { -+ np = of_find_compatible_node(np, NULL, "fsl,gianfar-mdio"); -+ -+ /* try the deprecated version */ -+ if (!np) -+ np = of_find_compatible_node(np, "mdio", "gianfar"); -+ -+ if (np) { - int k; - struct device_node *child = NULL; - struct gianfar_mdio_data mdio_data; -@@ -179,11 +222,13 @@ static int __init gfar_mdio_of_init(void - goto unreg; - } - -+ of_node_put(np); - return 0; - - unreg: - platform_device_unregister(mdio_dev); - err: -+ of_node_put(np); - return ret; - } - -@@ -193,7 +238,6 @@ static const char *gfar_tx_intr = "tx"; - static const char *gfar_rx_intr = "rx"; - static const char *gfar_err_intr = "error"; - -- - static int __init gfar_of_init(void) - { - struct device_node *np; -@@ -277,29 +321,43 @@ static int __init gfar_of_init(void) - gfar_data.interface = PHY_INTERFACE_MODE_MII; - - ph = of_get_property(np, "phy-handle", NULL); -- phy = of_find_node_by_phandle(*ph); -+ if (ph == NULL) { -+ u32 *fixed_link; - -- if (phy == NULL) { -- ret = -ENODEV; -- goto unreg; -- } -+ fixed_link = (u32 *)of_get_property(np, "fixed-link", -+ NULL); -+ if (!fixed_link) { -+ ret = -ENODEV; -+ goto unreg; -+ } - -- mdio = of_get_parent(phy); -+ gfar_data.bus_id = 0; -+ gfar_data.phy_id = fixed_link[0]; -+ } else { -+ phy = of_find_node_by_phandle(*ph); -+ -+ if (phy == NULL) { -+ ret = -ENODEV; -+ goto unreg; -+ } -+ -+ mdio = of_get_parent(phy); -+ -+ id = of_get_property(phy, "reg", NULL); -+ ret = of_address_to_resource(mdio, 0, &res); -+ if (ret) { -+ of_node_put(phy); -+ of_node_put(mdio); -+ goto unreg; -+ } -+ -+ gfar_data.phy_id = *id; -+ gfar_data.bus_id = res.start; - -- id = of_get_property(phy, "reg", NULL); -- ret = of_address_to_resource(mdio, 0, &res); -- if (ret) { - of_node_put(phy); - of_node_put(mdio); -- goto unreg; - } - -- gfar_data.phy_id = *id; -- gfar_data.bus_id = res.start; -- -- of_node_put(phy); -- of_node_put(mdio); -- - ret = - platform_device_add_data(gfar_dev, &gfar_data, - sizeof(struct -@@ -390,13 +448,11 @@ static void __init of_register_i2c_devic - static int __init fsl_i2c_of_init(void) - { - struct device_node *np; -- unsigned int i; -+ unsigned int i = 0; - struct platform_device *i2c_dev; - int ret; - -- for (np = NULL, i = 0; -- (np = of_find_compatible_node(np, "i2c", "fsl-i2c")) != NULL; -- i++) { -+ for_each_compatible_node(np, NULL, "fsl-i2c") { - struct resource r[2]; - struct fsl_i2c_platform_data i2c_data; - const unsigned char *flags = NULL; -@@ -432,7 +488,7 @@ static int __init fsl_i2c_of_init(void) - if (ret) - goto unreg; - -- of_register_i2c_devices(np, i); -+ of_register_i2c_devices(np, i++); - } - - return 0; -@@ -528,14 +584,12 @@ static enum fsl_usb2_phy_modes determine - static int __init fsl_usb_of_init(void) - { - struct device_node *np; -- unsigned int i; -+ unsigned int i = 0; - struct platform_device *usb_dev_mph = NULL, *usb_dev_dr_host = NULL, - *usb_dev_dr_client = NULL; - int ret; - -- for (np = NULL, i = 0; -- (np = of_find_compatible_node(np, "usb", "fsl-usb2-mph")) != NULL; -- i++) { -+ for_each_compatible_node(np, NULL, "fsl-usb2-mph") { - struct resource r[2]; - struct fsl_usb2_platform_data usb_data; - const unsigned char *prop = NULL; -@@ -578,11 +632,10 @@ static int __init fsl_usb_of_init(void) - fsl_usb2_platform_data)); - if (ret) - goto unreg_mph; -+ i++; - } - -- for (np = NULL; -- (np = of_find_compatible_node(np, "usb", "fsl-usb2-dr")) != NULL; -- i++) { -+ for_each_compatible_node(np, NULL, "fsl-usb2-dr") { - struct resource r[2]; - struct fsl_usb2_platform_data usb_data; - const unsigned char *prop = NULL; -@@ -654,6 +707,7 @@ static int __init fsl_usb_of_init(void) - fsl_usb2_platform_data)))) - goto unreg_dr; - } -+ i++; - } - return 0; - -@@ -1125,13 +1179,12 @@ arch_initcall(fs_enet_of_init); - - static int __init fsl_pcmcia_of_init(void) - { -- struct device_node *np = NULL; -+ struct device_node *np; - /* - * Register all the devices which type is "pcmcia" - */ -- while ((np = of_find_compatible_node(np, -- "pcmcia", "fsl,pq-pcmcia")) != NULL) -- of_platform_device_create(np, "m8xx-pcmcia", NULL); -+ for_each_compatible_node(np, "pcmcia", "fsl,pq-pcmcia") -+ of_platform_device_create(np, "m8xx-pcmcia", NULL); - return 0; - } - ---- a/arch/powerpc/sysdev/grackle.c -+++ b/arch/powerpc/sysdev/grackle.c -@@ -57,7 +57,7 @@ void __init setup_grackle(struct pci_con - { - setup_indirect_pci(hose, 0xfec00000, 0xfee00000, 0); - if (machine_is_compatible("PowerMac1,1")) -- pci_assign_all_buses = 1; -+ ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS; - if (machine_is_compatible("AAPL,PowerBook1998")) - grackle_set_loop_snoop(hose, 1); - #if 0 /* Disabled for now, HW problems ??? */ ---- a/arch/powerpc/sysdev/ipic.c -+++ b/arch/powerpc/sysdev/ipic.c -@@ -30,11 +30,67 @@ - #include "ipic.h" - - static struct ipic * primary_ipic; -+static struct irq_chip ipic_level_irq_chip, ipic_edge_irq_chip; - static DEFINE_SPINLOCK(ipic_lock); - - static struct ipic_info ipic_info[] = { -+ [1] = { -+ .mask = IPIC_SIMSR_H, -+ .prio = IPIC_SIPRR_C, -+ .force = IPIC_SIFCR_H, -+ .bit = 16, -+ .prio_mask = 0, -+ }, -+ [2] = { -+ .mask = IPIC_SIMSR_H, -+ .prio = IPIC_SIPRR_C, -+ .force = IPIC_SIFCR_H, -+ .bit = 17, -+ .prio_mask = 1, -+ }, -+ [3] = { -+ .mask = IPIC_SIMSR_H, -+ .prio = IPIC_SIPRR_C, -+ .force = IPIC_SIFCR_H, -+ .bit = 18, -+ .prio_mask = 2, -+ }, -+ [4] = { -+ .mask = IPIC_SIMSR_H, -+ .prio = IPIC_SIPRR_C, -+ .force = IPIC_SIFCR_H, -+ .bit = 19, -+ .prio_mask = 3, -+ }, -+ [5] = { -+ .mask = IPIC_SIMSR_H, -+ .prio = IPIC_SIPRR_C, -+ .force = IPIC_SIFCR_H, -+ .bit = 20, -+ .prio_mask = 4, -+ }, -+ [6] = { -+ .mask = IPIC_SIMSR_H, -+ .prio = IPIC_SIPRR_C, -+ .force = IPIC_SIFCR_H, -+ .bit = 21, -+ .prio_mask = 5, -+ }, -+ [7] = { -+ .mask = IPIC_SIMSR_H, -+ .prio = IPIC_SIPRR_C, -+ .force = IPIC_SIFCR_H, -+ .bit = 22, -+ .prio_mask = 6, -+ }, -+ [8] = { -+ .mask = IPIC_SIMSR_H, -+ .prio = IPIC_SIPRR_C, -+ .force = IPIC_SIFCR_H, -+ .bit = 23, -+ .prio_mask = 7, -+ }, - [9] = { -- .pend = IPIC_SIPNR_H, - .mask = IPIC_SIMSR_H, - .prio = IPIC_SIPRR_D, - .force = IPIC_SIFCR_H, -@@ -42,7 +98,6 @@ static struct ipic_info ipic_info[] = { - .prio_mask = 0, - }, - [10] = { -- .pend = IPIC_SIPNR_H, - .mask = IPIC_SIMSR_H, - .prio = IPIC_SIPRR_D, - .force = IPIC_SIFCR_H, -@@ -50,15 +105,27 @@ static struct ipic_info ipic_info[] = { - .prio_mask = 1, - }, - [11] = { -- .pend = IPIC_SIPNR_H, - .mask = IPIC_SIMSR_H, - .prio = IPIC_SIPRR_D, - .force = IPIC_SIFCR_H, - .bit = 26, - .prio_mask = 2, - }, -+ [12] = { -+ .mask = IPIC_SIMSR_H, -+ .prio = IPIC_SIPRR_D, -+ .force = IPIC_SIFCR_H, -+ .bit = 27, -+ .prio_mask = 3, -+ }, -+ [13] = { -+ .mask = IPIC_SIMSR_H, -+ .prio = IPIC_SIPRR_D, -+ .force = IPIC_SIFCR_H, -+ .bit = 28, -+ .prio_mask = 4, -+ }, - [14] = { -- .pend = IPIC_SIPNR_H, - .mask = IPIC_SIMSR_H, - .prio = IPIC_SIPRR_D, - .force = IPIC_SIFCR_H, -@@ -66,7 +133,6 @@ static struct ipic_info ipic_info[] = { - .prio_mask = 5, - }, - [15] = { -- .pend = IPIC_SIPNR_H, - .mask = IPIC_SIMSR_H, - .prio = IPIC_SIPRR_D, - .force = IPIC_SIFCR_H, -@@ -74,7 +140,6 @@ static struct ipic_info ipic_info[] = { - .prio_mask = 6, - }, - [16] = { -- .pend = IPIC_SIPNR_H, - .mask = IPIC_SIMSR_H, - .prio = IPIC_SIPRR_D, - .force = IPIC_SIFCR_H, -@@ -82,7 +147,7 @@ static struct ipic_info ipic_info[] = { - .prio_mask = 7, - }, - [17] = { -- .pend = IPIC_SEPNR, -+ .ack = IPIC_SEPNR, - .mask = IPIC_SEMSR, - .prio = IPIC_SMPRR_A, - .force = IPIC_SEFCR, -@@ -90,7 +155,7 @@ static struct ipic_info ipic_info[] = { - .prio_mask = 5, - }, - [18] = { -- .pend = IPIC_SEPNR, -+ .ack = IPIC_SEPNR, - .mask = IPIC_SEMSR, - .prio = IPIC_SMPRR_A, - .force = IPIC_SEFCR, -@@ -98,7 +163,7 @@ static struct ipic_info ipic_info[] = { - .prio_mask = 6, - }, - [19] = { -- .pend = IPIC_SEPNR, -+ .ack = IPIC_SEPNR, - .mask = IPIC_SEMSR, - .prio = IPIC_SMPRR_A, - .force = IPIC_SEFCR, -@@ -106,7 +171,7 @@ static struct ipic_info ipic_info[] = { - .prio_mask = 7, - }, - [20] = { -- .pend = IPIC_SEPNR, -+ .ack = IPIC_SEPNR, - .mask = IPIC_SEMSR, - .prio = IPIC_SMPRR_B, - .force = IPIC_SEFCR, -@@ -114,7 +179,7 @@ static struct ipic_info ipic_info[] = { - .prio_mask = 4, - }, - [21] = { -- .pend = IPIC_SEPNR, -+ .ack = IPIC_SEPNR, - .mask = IPIC_SEMSR, - .prio = IPIC_SMPRR_B, - .force = IPIC_SEFCR, -@@ -122,7 +187,7 @@ static struct ipic_info ipic_info[] = { - .prio_mask = 5, - }, - [22] = { -- .pend = IPIC_SEPNR, -+ .ack = IPIC_SEPNR, - .mask = IPIC_SEMSR, - .prio = IPIC_SMPRR_B, - .force = IPIC_SEFCR, -@@ -130,7 +195,7 @@ static struct ipic_info ipic_info[] = { - .prio_mask = 6, - }, - [23] = { -- .pend = IPIC_SEPNR, -+ .ack = IPIC_SEPNR, - .mask = IPIC_SEMSR, - .prio = IPIC_SMPRR_B, - .force = IPIC_SEFCR, -@@ -138,7 +203,6 @@ static struct ipic_info ipic_info[] = { - .prio_mask = 7, - }, - [32] = { -- .pend = IPIC_SIPNR_H, - .mask = IPIC_SIMSR_H, - .prio = IPIC_SIPRR_A, - .force = IPIC_SIFCR_H, -@@ -146,7 +210,6 @@ static struct ipic_info ipic_info[] = { - .prio_mask = 0, - }, - [33] = { -- .pend = IPIC_SIPNR_H, - .mask = IPIC_SIMSR_H, - .prio = IPIC_SIPRR_A, - .force = IPIC_SIFCR_H, -@@ -154,7 +217,6 @@ static struct ipic_info ipic_info[] = { - .prio_mask = 1, - }, - [34] = { -- .pend = IPIC_SIPNR_H, - .mask = IPIC_SIMSR_H, - .prio = IPIC_SIPRR_A, - .force = IPIC_SIFCR_H, -@@ -162,7 +224,6 @@ static struct ipic_info ipic_info[] = { - .prio_mask = 2, - }, - [35] = { -- .pend = IPIC_SIPNR_H, - .mask = IPIC_SIMSR_H, - .prio = IPIC_SIPRR_A, - .force = IPIC_SIFCR_H, -@@ -170,7 +231,6 @@ static struct ipic_info ipic_info[] = { - .prio_mask = 3, - }, - [36] = { -- .pend = IPIC_SIPNR_H, - .mask = IPIC_SIMSR_H, - .prio = IPIC_SIPRR_A, - .force = IPIC_SIFCR_H, -@@ -178,7 +238,6 @@ static struct ipic_info ipic_info[] = { - .prio_mask = 4, - }, - [37] = { -- .pend = IPIC_SIPNR_H, - .mask = IPIC_SIMSR_H, - .prio = IPIC_SIPRR_A, - .force = IPIC_SIFCR_H, -@@ -186,7 +245,6 @@ static struct ipic_info ipic_info[] = { - .prio_mask = 5, - }, - [38] = { -- .pend = IPIC_SIPNR_H, - .mask = IPIC_SIMSR_H, - .prio = IPIC_SIPRR_A, - .force = IPIC_SIFCR_H, -@@ -194,15 +252,69 @@ static struct ipic_info ipic_info[] = { - .prio_mask = 6, - }, - [39] = { -- .pend = IPIC_SIPNR_H, - .mask = IPIC_SIMSR_H, - .prio = IPIC_SIPRR_A, - .force = IPIC_SIFCR_H, - .bit = 7, - .prio_mask = 7, - }, -+ [40] = { -+ .mask = IPIC_SIMSR_H, -+ .prio = IPIC_SIPRR_B, -+ .force = IPIC_SIFCR_H, -+ .bit = 8, -+ .prio_mask = 0, -+ }, -+ [41] = { -+ .mask = IPIC_SIMSR_H, -+ .prio = IPIC_SIPRR_B, -+ .force = IPIC_SIFCR_H, -+ .bit = 9, -+ .prio_mask = 1, -+ }, -+ [42] = { -+ .mask = IPIC_SIMSR_H, -+ .prio = IPIC_SIPRR_B, -+ .force = IPIC_SIFCR_H, -+ .bit = 10, -+ .prio_mask = 2, -+ }, -+ [43] = { -+ .mask = IPIC_SIMSR_H, -+ .prio = IPIC_SIPRR_B, -+ .force = IPIC_SIFCR_H, -+ .bit = 11, -+ .prio_mask = 3, -+ }, -+ [44] = { -+ .mask = IPIC_SIMSR_H, -+ .prio = IPIC_SIPRR_B, -+ .force = IPIC_SIFCR_H, -+ .bit = 12, -+ .prio_mask = 4, -+ }, -+ [45] = { -+ .mask = IPIC_SIMSR_H, -+ .prio = IPIC_SIPRR_B, -+ .force = IPIC_SIFCR_H, -+ .bit = 13, -+ .prio_mask = 5, -+ }, -+ [46] = { -+ .mask = IPIC_SIMSR_H, -+ .prio = IPIC_SIPRR_B, -+ .force = IPIC_SIFCR_H, -+ .bit = 14, -+ .prio_mask = 6, -+ }, -+ [47] = { -+ .mask = IPIC_SIMSR_H, -+ .prio = IPIC_SIPRR_B, -+ .force = IPIC_SIFCR_H, -+ .bit = 15, -+ .prio_mask = 7, -+ }, - [48] = { -- .pend = IPIC_SEPNR, - .mask = IPIC_SEMSR, - .prio = IPIC_SMPRR_A, - .force = IPIC_SEFCR, -@@ -210,7 +322,6 @@ static struct ipic_info ipic_info[] = { - .prio_mask = 4, - }, - [64] = { -- .pend = IPIC_SIPNR_L, - .mask = IPIC_SIMSR_L, - .prio = IPIC_SMPRR_A, - .force = IPIC_SIFCR_L, -@@ -218,7 +329,6 @@ static struct ipic_info ipic_info[] = { - .prio_mask = 0, - }, - [65] = { -- .pend = IPIC_SIPNR_L, - .mask = IPIC_SIMSR_L, - .prio = IPIC_SMPRR_A, - .force = IPIC_SIFCR_L, -@@ -226,7 +336,6 @@ static struct ipic_info ipic_info[] = { - .prio_mask = 1, - }, - [66] = { -- .pend = IPIC_SIPNR_L, - .mask = IPIC_SIMSR_L, - .prio = IPIC_SMPRR_A, - .force = IPIC_SIFCR_L, -@@ -234,7 +343,6 @@ static struct ipic_info ipic_info[] = { - .prio_mask = 2, - }, - [67] = { -- .pend = IPIC_SIPNR_L, - .mask = IPIC_SIMSR_L, - .prio = IPIC_SMPRR_A, - .force = IPIC_SIFCR_L, -@@ -242,7 +350,6 @@ static struct ipic_info ipic_info[] = { - .prio_mask = 3, - }, - [68] = { -- .pend = IPIC_SIPNR_L, - .mask = IPIC_SIMSR_L, - .prio = IPIC_SMPRR_B, - .force = IPIC_SIFCR_L, -@@ -250,7 +357,6 @@ static struct ipic_info ipic_info[] = { - .prio_mask = 0, - }, - [69] = { -- .pend = IPIC_SIPNR_L, - .mask = IPIC_SIMSR_L, - .prio = IPIC_SMPRR_B, - .force = IPIC_SIFCR_L, -@@ -258,7 +364,6 @@ static struct ipic_info ipic_info[] = { - .prio_mask = 1, - }, - [70] = { -- .pend = IPIC_SIPNR_L, - .mask = IPIC_SIMSR_L, - .prio = IPIC_SMPRR_B, - .force = IPIC_SIFCR_L, -@@ -266,7 +371,6 @@ static struct ipic_info ipic_info[] = { - .prio_mask = 2, - }, - [71] = { -- .pend = IPIC_SIPNR_L, - .mask = IPIC_SIMSR_L, - .prio = IPIC_SMPRR_B, - .force = IPIC_SIFCR_L, -@@ -274,91 +378,120 @@ static struct ipic_info ipic_info[] = { - .prio_mask = 3, - }, - [72] = { -- .pend = IPIC_SIPNR_L, - .mask = IPIC_SIMSR_L, - .prio = 0, - .force = IPIC_SIFCR_L, - .bit = 8, - }, - [73] = { -- .pend = IPIC_SIPNR_L, - .mask = IPIC_SIMSR_L, - .prio = 0, - .force = IPIC_SIFCR_L, - .bit = 9, - }, - [74] = { -- .pend = IPIC_SIPNR_L, - .mask = IPIC_SIMSR_L, - .prio = 0, - .force = IPIC_SIFCR_L, - .bit = 10, - }, - [75] = { -- .pend = IPIC_SIPNR_L, - .mask = IPIC_SIMSR_L, - .prio = 0, - .force = IPIC_SIFCR_L, - .bit = 11, - }, - [76] = { -- .pend = IPIC_SIPNR_L, - .mask = IPIC_SIMSR_L, - .prio = 0, - .force = IPIC_SIFCR_L, - .bit = 12, - }, - [77] = { -- .pend = IPIC_SIPNR_L, - .mask = IPIC_SIMSR_L, - .prio = 0, - .force = IPIC_SIFCR_L, - .bit = 13, - }, - [78] = { -- .pend = IPIC_SIPNR_L, - .mask = IPIC_SIMSR_L, - .prio = 0, - .force = IPIC_SIFCR_L, - .bit = 14, - }, - [79] = { -- .pend = IPIC_SIPNR_L, - .mask = IPIC_SIMSR_L, - .prio = 0, - .force = IPIC_SIFCR_L, - .bit = 15, - }, - [80] = { -- .pend = IPIC_SIPNR_L, - .mask = IPIC_SIMSR_L, - .prio = 0, - .force = IPIC_SIFCR_L, - .bit = 16, - }, -+ [81] = { -+ .mask = IPIC_SIMSR_L, -+ .prio = 0, -+ .force = IPIC_SIFCR_L, -+ .bit = 17, -+ }, -+ [82] = { -+ .mask = IPIC_SIMSR_L, -+ .prio = 0, -+ .force = IPIC_SIFCR_L, -+ .bit = 18, -+ }, -+ [83] = { -+ .mask = IPIC_SIMSR_L, -+ .prio = 0, -+ .force = IPIC_SIFCR_L, -+ .bit = 19, -+ }, - [84] = { -- .pend = IPIC_SIPNR_L, - .mask = IPIC_SIMSR_L, - .prio = 0, - .force = IPIC_SIFCR_L, - .bit = 20, - }, - [85] = { -- .pend = IPIC_SIPNR_L, - .mask = IPIC_SIMSR_L, - .prio = 0, - .force = IPIC_SIFCR_L, - .bit = 21, - }, -+ [86] = { -+ .mask = IPIC_SIMSR_L, -+ .prio = 0, -+ .force = IPIC_SIFCR_L, -+ .bit = 22, -+ }, -+ [87] = { -+ .mask = IPIC_SIMSR_L, -+ .prio = 0, -+ .force = IPIC_SIFCR_L, -+ .bit = 23, -+ }, -+ [88] = { -+ .mask = IPIC_SIMSR_L, -+ .prio = 0, -+ .force = IPIC_SIFCR_L, -+ .bit = 24, -+ }, -+ [89] = { -+ .mask = IPIC_SIMSR_L, -+ .prio = 0, -+ .force = IPIC_SIFCR_L, -+ .bit = 25, -+ }, - [90] = { -- .pend = IPIC_SIPNR_L, - .mask = IPIC_SIMSR_L, - .prio = 0, - .force = IPIC_SIFCR_L, - .bit = 26, - }, - [91] = { -- .pend = IPIC_SIPNR_L, - .mask = IPIC_SIMSR_L, - .prio = 0, - .force = IPIC_SIFCR_L, -@@ -412,6 +545,10 @@ static void ipic_mask_irq(unsigned int v - temp &= ~(1 << (31 - ipic_info[src].bit)); - ipic_write(ipic->regs, ipic_info[src].mask, temp); - -+ /* mb() can't guarantee that masking is finished. But it does finish -+ * for nearly all cases. */ -+ mb(); -+ - spin_unlock_irqrestore(&ipic_lock, flags); - } - -@@ -424,9 +561,13 @@ static void ipic_ack_irq(unsigned int vi - - spin_lock_irqsave(&ipic_lock, flags); - -- temp = ipic_read(ipic->regs, ipic_info[src].pend); -+ temp = ipic_read(ipic->regs, ipic_info[src].ack); - temp |= (1 << (31 - ipic_info[src].bit)); -- ipic_write(ipic->regs, ipic_info[src].pend, temp); -+ ipic_write(ipic->regs, ipic_info[src].ack, temp); -+ -+ /* mb() can't guarantee that ack is finished. But it does finish -+ * for nearly all cases. */ -+ mb(); - - spin_unlock_irqrestore(&ipic_lock, flags); - } -@@ -444,9 +585,13 @@ static void ipic_mask_irq_and_ack(unsign - temp &= ~(1 << (31 - ipic_info[src].bit)); - ipic_write(ipic->regs, ipic_info[src].mask, temp); - -- temp = ipic_read(ipic->regs, ipic_info[src].pend); -+ temp = ipic_read(ipic->regs, ipic_info[src].ack); - temp |= (1 << (31 - ipic_info[src].bit)); -- ipic_write(ipic->regs, ipic_info[src].pend, temp); -+ ipic_write(ipic->regs, ipic_info[src].ack, temp); -+ -+ /* mb() can't guarantee that ack is finished. But it does finish -+ * for nearly all cases. */ -+ mb(); - - spin_unlock_irqrestore(&ipic_lock, flags); - } -@@ -468,14 +613,22 @@ static int ipic_set_irq_type(unsigned in - flow_type); - return -EINVAL; - } -+ /* ipic supports only edge mode on external interrupts */ -+ if ((flow_type & IRQ_TYPE_EDGE_FALLING) && !ipic_info[src].ack) { -+ printk(KERN_ERR "ipic: edge sense not supported on internal " -+ "interrupts\n"); -+ return -EINVAL; -+ } - - desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL); - desc->status |= flow_type & IRQ_TYPE_SENSE_MASK; - if (flow_type & IRQ_TYPE_LEVEL_LOW) { - desc->status |= IRQ_LEVEL; - desc->handle_irq = handle_level_irq; -+ desc->chip = &ipic_level_irq_chip; - } else { - desc->handle_irq = handle_edge_irq; -+ desc->chip = &ipic_edge_irq_chip; - } - - /* only EXT IRQ senses are programmable on ipic -@@ -500,7 +653,16 @@ static int ipic_set_irq_type(unsigned in - return 0; - } - --static struct irq_chip ipic_irq_chip = { -+/* level interrupts and edge interrupts have different ack operations */ -+static struct irq_chip ipic_level_irq_chip = { -+ .typename = " IPIC ", -+ .unmask = ipic_unmask_irq, -+ .mask = ipic_mask_irq, -+ .mask_ack = ipic_mask_irq, -+ .set_type = ipic_set_irq_type, -+}; -+ -+static struct irq_chip ipic_edge_irq_chip = { - .typename = " IPIC ", - .unmask = ipic_unmask_irq, - .mask = ipic_mask_irq, -@@ -519,13 +681,9 @@ static int ipic_host_map(struct irq_host - irq_hw_number_t hw) - { - struct ipic *ipic = h->host_data; -- struct irq_chip *chip; -- -- /* Default chip */ -- chip = &ipic->hc_irq; - - set_irq_chip_data(virq, ipic); -- set_irq_chip_and_handler(virq, chip, handle_level_irq); -+ set_irq_chip_and_handler(virq, &ipic_level_irq_chip, handle_level_irq); - - /* Set default irq type */ - set_irq_type(virq, IRQ_TYPE_NONE); -@@ -584,7 +742,6 @@ struct ipic * __init ipic_init(struct de - ipic->regs = ioremap(res.start, res.end - res.start + 1); - - ipic->irqhost->host_data = ipic; -- ipic->hc_irq = ipic_irq_chip; - - /* init hw */ - ipic_write(ipic->regs, IPIC_SICNR, 0x0); -@@ -593,6 +750,10 @@ struct ipic * __init ipic_init(struct de - * configure SICFR accordingly */ - if (flags & IPIC_SPREADMODE_GRP_A) - temp |= SICFR_IPSA; -+ if (flags & IPIC_SPREADMODE_GRP_B) -+ temp |= SICFR_IPSB; -+ if (flags & IPIC_SPREADMODE_GRP_C) -+ temp |= SICFR_IPSC; - if (flags & IPIC_SPREADMODE_GRP_D) - temp |= SICFR_IPSD; - if (flags & IPIC_SPREADMODE_MIX_A) -@@ -600,7 +761,7 @@ struct ipic * __init ipic_init(struct de - if (flags & IPIC_SPREADMODE_MIX_B) - temp |= SICFR_MPSB; - -- ipic_write(ipic->regs, IPIC_SICNR, temp); -+ ipic_write(ipic->regs, IPIC_SICFR, temp); - - /* handle MCP route */ - temp = 0; -@@ -672,10 +833,12 @@ void ipic_set_highest_priority(unsigned - - void ipic_set_default_priority(void) - { -- ipic_write(primary_ipic->regs, IPIC_SIPRR_A, IPIC_SIPRR_A_DEFAULT); -- ipic_write(primary_ipic->regs, IPIC_SIPRR_D, IPIC_SIPRR_D_DEFAULT); -- ipic_write(primary_ipic->regs, IPIC_SMPRR_A, IPIC_SMPRR_A_DEFAULT); -- ipic_write(primary_ipic->regs, IPIC_SMPRR_B, IPIC_SMPRR_B_DEFAULT); -+ ipic_write(primary_ipic->regs, IPIC_SIPRR_A, IPIC_PRIORITY_DEFAULT); -+ ipic_write(primary_ipic->regs, IPIC_SIPRR_B, IPIC_PRIORITY_DEFAULT); -+ ipic_write(primary_ipic->regs, IPIC_SIPRR_C, IPIC_PRIORITY_DEFAULT); -+ ipic_write(primary_ipic->regs, IPIC_SIPRR_D, IPIC_PRIORITY_DEFAULT); -+ ipic_write(primary_ipic->regs, IPIC_SMPRR_A, IPIC_PRIORITY_DEFAULT); -+ ipic_write(primary_ipic->regs, IPIC_SMPRR_B, IPIC_PRIORITY_DEFAULT); - } - - void ipic_enable_mcp(enum ipic_mcp_irq mcp_irq) ---- a/arch/powerpc/sysdev/ipic.h -+++ b/arch/powerpc/sysdev/ipic.h -@@ -23,13 +23,12 @@ - #define IPIC_IRQ_EXT7 23 - - /* Default Priority Registers */ --#define IPIC_SIPRR_A_DEFAULT 0x05309770 --#define IPIC_SIPRR_D_DEFAULT 0x05309770 --#define IPIC_SMPRR_A_DEFAULT 0x05309770 --#define IPIC_SMPRR_B_DEFAULT 0x05309770 -+#define IPIC_PRIORITY_DEFAULT 0x05309770 - - /* System Global Interrupt Configuration Register */ - #define SICFR_IPSA 0x00010000 -+#define SICFR_IPSB 0x00020000 -+#define SICFR_IPSC 0x00040000 - #define SICFR_IPSD 0x00080000 - #define SICFR_MPSA 0x00200000 - #define SICFR_MPSB 0x00400000 -@@ -45,13 +44,11 @@ struct ipic { - - /* The remapper for this IPIC */ - struct irq_host *irqhost; -- -- /* The "linux" controller struct */ -- struct irq_chip hc_irq; - }; - - struct ipic_info { -- u8 pend; /* pending register offset from base */ -+ u8 ack; /* pending register offset from base if the irq -+ supports ack operation */ - u8 mask; /* mask register offset from base */ - u8 prio; /* priority register offset from base */ - u8 force; /* force register offset from base */ ---- a/arch/powerpc/sysdev/mmio_nvram.c -+++ b/arch/powerpc/sysdev/mmio_nvram.c -@@ -99,7 +99,7 @@ int __init mmio_nvram_init(void) - nvram_addr = r.start; - mmio_nvram_len = r.end - r.start + 1; - if ( (!mmio_nvram_len) || (!nvram_addr) ) { -- printk(KERN_WARNING "nvram: address or lenght is 0\n"); -+ printk(KERN_WARNING "nvram: address or length is 0\n"); - ret = -EIO; - goto out; - } ---- a/arch/powerpc/sysdev/mpic.c -+++ b/arch/powerpc/sysdev/mpic.c -@@ -83,6 +83,7 @@ static u32 mpic_infos[][MPIC_IDX_END] = - MPIC_CPU_WHOAMI, - MPIC_CPU_INTACK, - MPIC_CPU_EOI, -+ MPIC_CPU_MCACK, - - MPIC_IRQ_BASE, - MPIC_IRQ_STRIDE, -@@ -121,6 +122,7 @@ static u32 mpic_infos[][MPIC_IDX_END] = - TSI108_CPU_WHOAMI, - TSI108_CPU_INTACK, - TSI108_CPU_EOI, -+ TSI108_CPU_MCACK, - - TSI108_IRQ_BASE, - TSI108_IRQ_STRIDE, -@@ -265,7 +267,7 @@ static inline void _mpic_irq_write(struc - */ - - --static void _mpic_map_mmio(struct mpic *mpic, unsigned long phys_addr, -+static void _mpic_map_mmio(struct mpic *mpic, phys_addr_t phys_addr, - struct mpic_reg_bank *rb, unsigned int offset, - unsigned int size) - { -@@ -285,7 +287,7 @@ static void _mpic_map_dcr(struct mpic *m - BUG_ON(!DCR_MAP_OK(rb->dhost)); - } - --static inline void mpic_map(struct mpic *mpic, unsigned long phys_addr, -+static inline void mpic_map(struct mpic *mpic, phys_addr_t phys_addr, - struct mpic_reg_bank *rb, unsigned int offset, - unsigned int size) - { -@@ -612,12 +614,11 @@ static inline void mpic_eoi(struct mpic - } - - #ifdef CONFIG_SMP --static irqreturn_t mpic_ipi_action(int irq, void *dev_id) -+static irqreturn_t mpic_ipi_action(int irq, void *data) - { -- struct mpic *mpic; -+ long ipi = (long)data; - -- mpic = mpic_find(irq, NULL); -- smp_message_recv(mpic_irq_to_hw(irq) - mpic->ipi_vecs[0]); -+ smp_message_recv(ipi); - - return IRQ_HANDLED; - } -@@ -842,6 +843,24 @@ int mpic_set_irq_type(unsigned int virq, - return 0; - } - -+void mpic_set_vector(unsigned int virq, unsigned int vector) -+{ -+ struct mpic *mpic = mpic_from_irq(virq); -+ unsigned int src = mpic_irq_to_hw(virq); -+ unsigned int vecpri; -+ -+ DBG("mpic: set_vector(mpic:@%p,virq:%d,src:%d,vector:0x%x)\n", -+ mpic, virq, src, vector); -+ -+ if (src >= mpic->irq_count) -+ return; -+ -+ vecpri = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI)); -+ vecpri = vecpri & ~MPIC_INFO(VECPRI_VECTOR_MASK); -+ vecpri |= vector; -+ mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI), vecpri); -+} -+ - static struct irq_chip mpic_irq_chip = { - .mask = mpic_mask_irq, - .unmask = mpic_unmask_irq, -@@ -1109,6 +1128,11 @@ struct mpic * __init mpic_alloc(struct d - mb(); - } - -+ if (flags & MPIC_ENABLE_MCK) -+ mpic_write(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0), -+ mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0)) -+ | MPIC_GREG_GCONF_MCK); -+ - /* Read feature register, calculate num CPUs and, for non-ISU - * MPICs, num sources as well. On ISU MPICs, sources are counted - * as ISUs are added -@@ -1230,6 +1254,8 @@ void __init mpic_init(struct mpic *mpic) - mpic_u3msi_init(mpic); - } - -+ mpic_pasemi_msi_init(mpic); -+ - for (i = 0; i < mpic->num_sources; i++) { - /* start with vector = source number, and masked */ - u32 vecpri = MPIC_VECPRI_MASK | i | -@@ -1253,6 +1279,11 @@ void __init mpic_init(struct mpic *mpic) - mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0)) - | MPIC_GREG_GCONF_8259_PTHROU_DIS); - -+ if (mpic->flags & MPIC_NO_BIAS) -+ mpic_write(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0), -+ mpic_read(mpic->gregs, MPIC_INFO(GREG_GLOBAL_CONF_0)) -+ | MPIC_GREG_GCONF_NO_BIAS); -+ - /* Set current processor priority to 0 */ - mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0); - -@@ -1419,13 +1450,13 @@ void mpic_send_ipi(unsigned int ipi_no, - mpic_physmask(cpu_mask & cpus_addr(cpu_online_map)[0])); - } - --unsigned int mpic_get_one_irq(struct mpic *mpic) -+static unsigned int _mpic_get_one_irq(struct mpic *mpic, int reg) - { - u32 src; - -- src = mpic_cpu_read(MPIC_INFO(CPU_INTACK)) & MPIC_INFO(VECPRI_VECTOR_MASK); -+ src = mpic_cpu_read(reg) & MPIC_INFO(VECPRI_VECTOR_MASK); - #ifdef DEBUG_LOW -- DBG("%s: get_one_irq(): %d\n", mpic->name, src); -+ DBG("%s: get_one_irq(reg 0x%x): %d\n", mpic->name, reg, src); - #endif - if (unlikely(src == mpic->spurious_vec)) { - if (mpic->flags & MPIC_SPV_EOI) -@@ -1443,6 +1474,11 @@ unsigned int mpic_get_one_irq(struct mpi - return irq_linear_revmap(mpic->irqhost, src); - } - -+unsigned int mpic_get_one_irq(struct mpic *mpic) -+{ -+ return _mpic_get_one_irq(mpic, MPIC_INFO(CPU_INTACK)); -+} -+ - unsigned int mpic_get_irq(void) - { - struct mpic *mpic = mpic_primary; -@@ -1452,12 +1488,20 @@ unsigned int mpic_get_irq(void) - return mpic_get_one_irq(mpic); - } - -+unsigned int mpic_get_mcirq(void) -+{ -+ struct mpic *mpic = mpic_primary; -+ -+ BUG_ON(mpic == NULL); -+ -+ return _mpic_get_one_irq(mpic, MPIC_INFO(CPU_MCACK)); -+} - - #ifdef CONFIG_SMP - void mpic_request_ipis(void) - { - struct mpic *mpic = mpic_primary; -- int i, err; -+ long i, err; - static char *ipi_names[] = { - "IPI0 (call function)", - "IPI1 (reschedule)", -@@ -1472,14 +1516,14 @@ void mpic_request_ipis(void) - unsigned int vipi = irq_create_mapping(mpic->irqhost, - mpic->ipi_vecs[0] + i); - if (vipi == NO_IRQ) { -- printk(KERN_ERR "Failed to map IPI %d\n", i); -+ printk(KERN_ERR "Failed to map IPI %ld\n", i); - break; - } - err = request_irq(vipi, mpic_ipi_action, - IRQF_DISABLED|IRQF_PERCPU, -- ipi_names[i], mpic); -+ ipi_names[i], (void *)i); - if (err) { -- printk(KERN_ERR "Request of irq %d for IPI %d failed\n", -+ printk(KERN_ERR "Request of irq %d for IPI %ld failed\n", - vipi, i); - break; - } ---- a/arch/powerpc/sysdev/mpic.h -+++ b/arch/powerpc/sysdev/mpic.h -@@ -17,6 +17,7 @@ extern int mpic_msi_init_allocator(struc - extern irq_hw_number_t mpic_msi_alloc_hwirqs(struct mpic *mpic, int num); - extern void mpic_msi_free_hwirqs(struct mpic *mpic, int offset, int num); - extern int mpic_u3msi_init(struct mpic *mpic); -+extern int mpic_pasemi_msi_init(struct mpic *mpic); - #else - static inline void mpic_msi_reserve_hwirq(struct mpic *mpic, - irq_hw_number_t hwirq) -@@ -28,12 +29,15 @@ static inline int mpic_u3msi_init(struct - { - return -1; - } -+ -+static inline int mpic_pasemi_msi_init(struct mpic *mpic) -+{ -+ return -1; -+} - #endif - - extern int mpic_set_irq_type(unsigned int virq, unsigned int flow_type); --extern void mpic_end_irq(unsigned int irq); --extern void mpic_mask_irq(unsigned int irq); --extern void mpic_unmask_irq(unsigned int irq); -+extern void mpic_set_vector(unsigned int virq, unsigned int vector); - extern void mpic_set_affinity(unsigned int irq, cpumask_t cpumask); - - #endif /* _POWERPC_SYSDEV_MPIC_H */ ---- /dev/null -+++ b/arch/powerpc/sysdev/mpic_pasemi_msi.c -@@ -0,0 +1,172 @@ -+/* -+ * Copyright 2007, Olof Johansson, PA Semi -+ * -+ * Based on arch/powerpc/sysdev/mpic_u3msi.c: -+ * -+ * Copyright 2006, Segher Boessenkool, IBM Corporation. -+ * Copyright 2006-2007, Michael Ellerman, IBM Corporation. -+ * -+ * 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 of the -+ * License. -+ * -+ */ -+ -+#undef DEBUG -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "mpic.h" -+ -+/* Allocate 16 interrupts per device, to give an alignment of 16, -+ * since that's the size of the grouping w.r.t. affinity. If someone -+ * needs more than 32 MSI's down the road we'll have to rethink this, -+ * but it should be OK for now. -+ */ -+#define ALLOC_CHUNK 16 -+ -+#define PASEMI_MSI_ADDR 0xfc080000 -+ -+/* A bit ugly, can we get this from the pci_dev somehow? */ -+static struct mpic *msi_mpic; -+ -+ -+static void mpic_pasemi_msi_mask_irq(unsigned int irq) -+{ -+ pr_debug("mpic_pasemi_msi_mask_irq %d\n", irq); -+ mask_msi_irq(irq); -+ mpic_mask_irq(irq); -+} -+ -+static void mpic_pasemi_msi_unmask_irq(unsigned int irq) -+{ -+ pr_debug("mpic_pasemi_msi_unmask_irq %d\n", irq); -+ mpic_unmask_irq(irq); -+ unmask_msi_irq(irq); -+} -+ -+static struct irq_chip mpic_pasemi_msi_chip = { -+ .shutdown = mpic_pasemi_msi_mask_irq, -+ .mask = mpic_pasemi_msi_mask_irq, -+ .unmask = mpic_pasemi_msi_unmask_irq, -+ .eoi = mpic_end_irq, -+ .set_type = mpic_set_irq_type, -+ .set_affinity = mpic_set_affinity, -+ .typename = "PASEMI-MSI ", -+}; -+ -+static int pasemi_msi_check_device(struct pci_dev *pdev, int nvec, int type) -+{ -+ if (type == PCI_CAP_ID_MSIX) -+ pr_debug("pasemi_msi: MSI-X untested, trying anyway\n"); -+ -+ return 0; -+} -+ -+static void pasemi_msi_teardown_msi_irqs(struct pci_dev *pdev) -+{ -+ struct msi_desc *entry; -+ -+ pr_debug("pasemi_msi_teardown_msi_irqs, pdev %p\n", pdev); -+ -+ list_for_each_entry(entry, &pdev->msi_list, list) { -+ if (entry->irq == NO_IRQ) -+ continue; -+ -+ set_irq_msi(entry->irq, NULL); -+ mpic_msi_free_hwirqs(msi_mpic, virq_to_hw(entry->irq), -+ ALLOC_CHUNK); -+ irq_dispose_mapping(entry->irq); -+ } -+ -+ return; -+} -+ -+static int pasemi_msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) -+{ -+ irq_hw_number_t hwirq; -+ unsigned int virq; -+ struct msi_desc *entry; -+ struct msi_msg msg; -+ u64 addr; -+ -+ pr_debug("pasemi_msi_setup_msi_irqs, pdev %p nvec %d type %d\n", -+ pdev, nvec, type); -+ -+ msg.address_hi = 0; -+ msg.address_lo = PASEMI_MSI_ADDR; -+ -+ list_for_each_entry(entry, &pdev->msi_list, list) { -+ /* Allocate 16 interrupts for now, since that's the grouping for -+ * affinity. This can be changed later if it turns out 32 is too -+ * few MSIs for someone, but restrictions will apply to how the -+ * sources can be changed independently. -+ */ -+ hwirq = mpic_msi_alloc_hwirqs(msi_mpic, ALLOC_CHUNK); -+ if (hwirq < 0) { -+ pr_debug("pasemi_msi: failed allocating hwirq\n"); -+ return hwirq; -+ } -+ -+ virq = irq_create_mapping(msi_mpic->irqhost, hwirq); -+ if (virq == NO_IRQ) { -+ pr_debug("pasemi_msi: failed mapping hwirq 0x%lx\n", hwirq); -+ mpic_msi_free_hwirqs(msi_mpic, hwirq, ALLOC_CHUNK); -+ return -ENOSPC; -+ } -+ -+ /* Vector on MSI is really an offset, the hardware adds -+ * it to the value written at the magic address. So set -+ * it to 0 to remain sane. -+ */ -+ mpic_set_vector(virq, 0); -+ -+ set_irq_msi(virq, entry); -+ set_irq_chip(virq, &mpic_pasemi_msi_chip); -+ set_irq_type(virq, IRQ_TYPE_EDGE_RISING); -+ -+ pr_debug("pasemi_msi: allocated virq 0x%x (hw 0x%lx) addr 0x%lx\n", -+ virq, hwirq, addr); -+ -+ /* Likewise, the device writes [0...511] into the target -+ * register to generate MSI [512...1023] -+ */ -+ msg.data = hwirq-0x200; -+ write_msi_msg(virq, &msg); -+ } -+ -+ return 0; -+} -+ -+int mpic_pasemi_msi_init(struct mpic *mpic) -+{ -+ int rc; -+ -+ if (!mpic->irqhost->of_node || -+ !of_device_is_compatible(mpic->irqhost->of_node, -+ "pasemi,pwrficient-openpic")) -+ return -ENODEV; -+ -+ rc = mpic_msi_init_allocator(mpic); -+ if (rc) { -+ pr_debug("pasemi_msi: Error allocating bitmap!\n"); -+ return rc; -+ } -+ -+ pr_debug("pasemi_msi: Registering PA Semi MPIC MSI callbacks\n"); -+ -+ msi_mpic = mpic; -+ WARN_ON(ppc_md.setup_msi_irqs); -+ ppc_md.setup_msi_irqs = pasemi_msi_setup_msi_irqs; -+ ppc_md.teardown_msi_irqs = pasemi_msi_teardown_msi_irqs; -+ ppc_md.msi_check_device = pasemi_msi_check_device; -+ -+ return 0; -+} ---- a/arch/powerpc/sysdev/mv64x60_dev.c -+++ b/arch/powerpc/sysdev/mv64x60_dev.c -@@ -241,7 +241,7 @@ static int __init mv64x60_eth_device_set - - /* only register the shared platform device the first time through */ - if (id == 0 && (err = eth_register_shared_pdev(np))) -- return err;; -+ return err; - - memset(r, 0, sizeof(r)); - of_irq_to_resource(np, 0, &r[0]); -@@ -451,22 +451,19 @@ static int __init mv64x60_device_setup(v - int id; - int err; - -- for (id = 0; -- (np = of_find_compatible_node(np, "serial", "marvell,mpsc")); id++) -- if ((err = mv64x60_mpsc_device_setup(np, id))) -+ id = 0; -+ for_each_compatible_node(np, "serial", "marvell,mpsc") -+ if ((err = mv64x60_mpsc_device_setup(np, id++))) - goto error; - -- for (id = 0; -- (np = of_find_compatible_node(np, "network", -- "marvell,mv64x60-eth")); -- id++) -- if ((err = mv64x60_eth_device_setup(np, id))) -+ id = 0; -+ for_each_compatible_node(np, "network", "marvell,mv64x60-eth") -+ if ((err = mv64x60_eth_device_setup(np, id++))) - goto error; - -- for (id = 0; -- (np = of_find_compatible_node(np, "i2c", "marvell,mv64x60-i2c")); -- id++) -- if ((err = mv64x60_i2c_device_setup(np, id))) -+ id = 0; -+ for_each_compatible_node(np, "i2c", "marvell,mv64x60-i2c") -+ if ((err = mv64x60_i2c_device_setup(np, id++))) - goto error; - - /* support up to one watchdog timer */ -@@ -477,7 +474,6 @@ static int __init mv64x60_device_setup(v - of_node_put(np); - } - -- - return 0; - - error: ---- a/arch/powerpc/sysdev/mv64x60_pci.c -+++ b/arch/powerpc/sysdev/mv64x60_pci.c -@@ -164,8 +164,8 @@ static int __init mv64x60_add_bridge(str - - void __init mv64x60_pci_init(void) - { -- struct device_node *np = NULL; -+ struct device_node *np; - -- while ((np = of_find_compatible_node(np, "pci", "marvell,mv64x60-pci"))) -+ for_each_compatible_node(np, "pci", "marvell,mv64x60-pci") - mv64x60_add_bridge(np); - } ---- a/arch/powerpc/sysdev/mv64x60_udbg.c -+++ b/arch/powerpc/sysdev/mv64x60_udbg.c -@@ -85,10 +85,10 @@ static void mv64x60_udbg_init(void) - if (!stdout) - return; - -- for (np = NULL; -- (np = of_find_compatible_node(np, "serial", "marvell,mpsc")); ) -+ for_each_compatible_node(np, "serial", "marvell,mpsc") { - if (np == stdout) - break; -+ } - - of_node_put(stdout); - if (!np) ---- /dev/null -+++ b/arch/powerpc/sysdev/of_rtc.c -@@ -0,0 +1,59 @@ -+/* -+ * Instantiate mmio-mapped RTC chips based on device tree information -+ * -+ * Copyright 2007 David Gibson , IBM Corporation. -+ * -+ * 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 -+ -+static __initdata struct { -+ const char *compatible; -+ char *plat_name; -+} of_rtc_table[] = { -+ { "ds1743-nvram", "rtc-ds1742" }, -+}; -+ -+void __init of_instantiate_rtc(void) -+{ -+ struct device_node *node; -+ int err; -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(of_rtc_table); i++) { -+ char *plat_name = of_rtc_table[i].plat_name; -+ -+ for_each_compatible_node(node, NULL, -+ of_rtc_table[i].compatible) { -+ struct resource *res; -+ -+ res = kmalloc(sizeof(*res), GFP_KERNEL); -+ if (!res) { -+ printk(KERN_ERR "OF RTC: Out of memory " -+ "allocating resource structure for %s\n", -+ node->full_name); -+ continue; -+ } -+ -+ err = of_address_to_resource(node, 0, res); -+ if (err) { -+ printk(KERN_ERR "OF RTC: Error " -+ "translating resources for %s\n", -+ node->full_name); -+ continue; -+ } -+ -+ printk(KERN_INFO "OF_RTC: %s is a %s @ 0x%llx-0x%llx\n", -+ node->full_name, plat_name, -+ (unsigned long long)res->start, -+ (unsigned long long)res->end); -+ platform_device_register_simple(plat_name, -1, res, 1); -+ } -+ } -+} ---- a/arch/powerpc/sysdev/pmi.c -+++ b/arch/powerpc/sysdev/pmi.c -@@ -28,9 +28,9 @@ - #include - #include - #include -+#include -+#include - --#include --#include - #include - #include - #include ---- /dev/null -+++ b/arch/powerpc/sysdev/ppc4xx_pci.c -@@ -0,0 +1,1528 @@ -+/* -+ * PCI / PCI-X / PCI-Express support for 4xx parts -+ * -+ * Copyright 2007 Ben. Herrenschmidt , IBM Corp. -+ * -+ * Most PCI Express code is coming from Stefan Roese implementation for -+ * arch/ppc in the Denx tree, slightly reworked by me. -+ * -+ * Copyright 2007 DENX Software Engineering, Stefan Roese -+ * -+ * Some of that comes itself from a previous implementation for 440SPE only -+ * by Roland Dreier: -+ * -+ * Copyright (c) 2005 Cisco Systems. All rights reserved. -+ * Roland Dreier -+ * -+ */ -+ -+#undef DEBUG -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "ppc4xx_pci.h" -+ -+static int dma_offset_set; -+ -+/* Move that to a useable header */ -+extern unsigned long total_memory; -+ -+#define U64_TO_U32_LOW(val) ((u32)((val) & 0x00000000ffffffffULL)) -+#define U64_TO_U32_HIGH(val) ((u32)((val) >> 32)) -+ -+#ifdef CONFIG_RESOURCES_64BIT -+#define RES_TO_U32_LOW(val) U64_TO_U32_LOW(val) -+#define RES_TO_U32_HIGH(val) U64_TO_U32_HIGH(val) -+#else -+#define RES_TO_U32_LOW(val) (val) -+#define RES_TO_U32_HIGH(val) (0) -+#endif -+ -+static inline int ppc440spe_revA(void) -+{ -+ /* Catch both 440SPe variants, with and without RAID6 support */ -+ if ((mfspr(SPRN_PVR) & 0xffefffff) == 0x53421890) -+ return 1; -+ else -+ return 0; -+} -+ -+static void fixup_ppc4xx_pci_bridge(struct pci_dev *dev) -+{ -+ struct pci_controller *hose; -+ int i; -+ -+ if (dev->devfn != 0 || dev->bus->self != NULL) -+ return; -+ -+ hose = pci_bus_to_host(dev->bus); -+ if (hose == NULL) -+ return; -+ -+ if (!of_device_is_compatible(hose->dn, "ibm,plb-pciex") && -+ !of_device_is_compatible(hose->dn, "ibm,plb-pcix") && -+ !of_device_is_compatible(hose->dn, "ibm,plb-pci")) -+ return; -+ -+ /* Hide the PCI host BARs from the kernel as their content doesn't -+ * fit well in the resource management -+ */ -+ for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { -+ dev->resource[i].start = dev->resource[i].end = 0; -+ dev->resource[i].flags = 0; -+ } -+ -+ printk(KERN_INFO "PCI: Hiding 4xx host bridge resources %s\n", -+ pci_name(dev)); -+} -+DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, fixup_ppc4xx_pci_bridge); -+ -+static int __init ppc4xx_parse_dma_ranges(struct pci_controller *hose, -+ void __iomem *reg, -+ struct resource *res) -+{ -+ u64 size; -+ const u32 *ranges; -+ int rlen; -+ int pna = of_n_addr_cells(hose->dn); -+ int np = pna + 5; -+ -+ /* Default */ -+ res->start = 0; -+ res->end = size = 0x80000000; -+ res->flags = IORESOURCE_MEM | IORESOURCE_PREFETCH; -+ -+ /* Get dma-ranges property */ -+ ranges = of_get_property(hose->dn, "dma-ranges", &rlen); -+ if (ranges == NULL) -+ goto out; -+ -+ /* Walk it */ -+ while ((rlen -= np * 4) >= 0) { -+ u32 pci_space = ranges[0]; -+ u64 pci_addr = of_read_number(ranges + 1, 2); -+ u64 cpu_addr = of_translate_dma_address(hose->dn, ranges + 3); -+ size = of_read_number(ranges + pna + 3, 2); -+ ranges += np; -+ if (cpu_addr == OF_BAD_ADDR || size == 0) -+ continue; -+ -+ /* We only care about memory */ -+ if ((pci_space & 0x03000000) != 0x02000000) -+ continue; -+ -+ /* We currently only support memory at 0, and pci_addr -+ * within 32 bits space -+ */ -+ if (cpu_addr != 0 || pci_addr > 0xffffffff) { -+ printk(KERN_WARNING "%s: Ignored unsupported dma range" -+ " 0x%016llx...0x%016llx -> 0x%016llx\n", -+ hose->dn->full_name, -+ pci_addr, pci_addr + size - 1, cpu_addr); -+ continue; -+ } -+ -+ /* Check if not prefetchable */ -+ if (!(pci_space & 0x40000000)) -+ res->flags &= ~IORESOURCE_PREFETCH; -+ -+ -+ /* Use that */ -+ res->start = pci_addr; -+#ifndef CONFIG_RESOURCES_64BIT -+ /* Beware of 32 bits resources */ -+ if ((pci_addr + size) > 0x100000000ull) -+ res->end = 0xffffffff; -+ else -+#endif -+ res->end = res->start + size - 1; -+ break; -+ } -+ -+ /* We only support one global DMA offset */ -+ if (dma_offset_set && pci_dram_offset != res->start) { -+ printk(KERN_ERR "%s: dma-ranges(s) mismatch\n", -+ hose->dn->full_name); -+ return -ENXIO; -+ } -+ -+ /* Check that we can fit all of memory as we don't support -+ * DMA bounce buffers -+ */ -+ if (size < total_memory) { -+ printk(KERN_ERR "%s: dma-ranges too small " -+ "(size=%llx total_memory=%lx)\n", -+ hose->dn->full_name, size, total_memory); -+ return -ENXIO; -+ } -+ -+ /* Check we are a power of 2 size and that base is a multiple of size*/ -+ if (!is_power_of_2(size) || -+ (res->start & (size - 1)) != 0) { -+ printk(KERN_ERR "%s: dma-ranges unaligned\n", -+ hose->dn->full_name); -+ return -ENXIO; -+ } -+ -+ /* Check that we are fully contained within 32 bits space */ -+ if (res->end > 0xffffffff) { -+ printk(KERN_ERR "%s: dma-ranges outside of 32 bits space\n", -+ hose->dn->full_name); -+ return -ENXIO; -+ } -+ out: -+ dma_offset_set = 1; -+ pci_dram_offset = res->start; -+ -+ printk(KERN_INFO "4xx PCI DMA offset set to 0x%08lx\n", -+ pci_dram_offset); -+ return 0; -+} -+ -+/* -+ * 4xx PCI 2.x part -+ */ -+ -+static void __init ppc4xx_configure_pci_PMMs(struct pci_controller *hose, -+ void __iomem *reg) -+{ -+ u32 la, ma, pcila, pciha; -+ int i, j; -+ -+ /* Setup outbound memory windows */ -+ for (i = j = 0; i < 3; i++) { -+ struct resource *res = &hose->mem_resources[i]; -+ -+ /* we only care about memory windows */ -+ if (!(res->flags & IORESOURCE_MEM)) -+ continue; -+ if (j > 2) { -+ printk(KERN_WARNING "%s: Too many ranges\n", -+ hose->dn->full_name); -+ break; -+ } -+ -+ /* Calculate register values */ -+ la = res->start; -+ pciha = RES_TO_U32_HIGH(res->start - hose->pci_mem_offset); -+ pcila = RES_TO_U32_LOW(res->start - hose->pci_mem_offset); -+ -+ ma = res->end + 1 - res->start; -+ if (!is_power_of_2(ma) || ma < 0x1000 || ma > 0xffffffffu) { -+ printk(KERN_WARNING "%s: Resource out of range\n", -+ hose->dn->full_name); -+ continue; -+ } -+ ma = (0xffffffffu << ilog2(ma)) | 0x1; -+ if (res->flags & IORESOURCE_PREFETCH) -+ ma |= 0x2; -+ -+ /* Program register values */ -+ writel(la, reg + PCIL0_PMM0LA + (0x10 * j)); -+ writel(pcila, reg + PCIL0_PMM0PCILA + (0x10 * j)); -+ writel(pciha, reg + PCIL0_PMM0PCIHA + (0x10 * j)); -+ writel(ma, reg + PCIL0_PMM0MA + (0x10 * j)); -+ j++; -+ } -+} -+ -+static void __init ppc4xx_configure_pci_PTMs(struct pci_controller *hose, -+ void __iomem *reg, -+ const struct resource *res) -+{ -+ resource_size_t size = res->end - res->start + 1; -+ u32 sa; -+ -+ /* Calculate window size */ -+ sa = (0xffffffffu << ilog2(size)) | 1; -+ sa |= 0x1; -+ -+ /* RAM is always at 0 local for now */ -+ writel(0, reg + PCIL0_PTM1LA); -+ writel(sa, reg + PCIL0_PTM1MS); -+ -+ /* Map on PCI side */ -+ early_write_config_dword(hose, hose->first_busno, 0, -+ PCI_BASE_ADDRESS_1, res->start); -+ early_write_config_dword(hose, hose->first_busno, 0, -+ PCI_BASE_ADDRESS_2, 0x00000000); -+ early_write_config_word(hose, hose->first_busno, 0, -+ PCI_COMMAND, 0x0006); -+} -+ -+static void __init ppc4xx_probe_pci_bridge(struct device_node *np) -+{ -+ /* NYI */ -+ struct resource rsrc_cfg; -+ struct resource rsrc_reg; -+ struct resource dma_window; -+ struct pci_controller *hose = NULL; -+ void __iomem *reg = NULL; -+ const int *bus_range; -+ int primary = 0; -+ -+ /* Fetch config space registers address */ -+ if (of_address_to_resource(np, 0, &rsrc_cfg)) { -+ printk(KERN_ERR "%s:Can't get PCI config register base !", -+ np->full_name); -+ return; -+ } -+ /* Fetch host bridge internal registers address */ -+ if (of_address_to_resource(np, 3, &rsrc_reg)) { -+ printk(KERN_ERR "%s: Can't get PCI internal register base !", -+ np->full_name); -+ return; -+ } -+ -+ /* Check if primary bridge */ -+ if (of_get_property(np, "primary", NULL)) -+ primary = 1; -+ -+ /* Get bus range if any */ -+ bus_range = of_get_property(np, "bus-range", NULL); -+ -+ /* Map registers */ -+ reg = ioremap(rsrc_reg.start, rsrc_reg.end + 1 - rsrc_reg.start); -+ if (reg == NULL) { -+ printk(KERN_ERR "%s: Can't map registers !", np->full_name); -+ goto fail; -+ } -+ -+ /* Allocate the host controller data structure */ -+ hose = pcibios_alloc_controller(np); -+ if (!hose) -+ goto fail; -+ -+ hose->first_busno = bus_range ? bus_range[0] : 0x0; -+ hose->last_busno = bus_range ? bus_range[1] : 0xff; -+ -+ /* Setup config space */ -+ setup_indirect_pci(hose, rsrc_cfg.start, rsrc_cfg.start + 0x4, 0); -+ -+ /* Disable all windows */ -+ writel(0, reg + PCIL0_PMM0MA); -+ writel(0, reg + PCIL0_PMM1MA); -+ writel(0, reg + PCIL0_PMM2MA); -+ writel(0, reg + PCIL0_PTM1MS); -+ writel(0, reg + PCIL0_PTM2MS); -+ -+ /* Parse outbound mapping resources */ -+ pci_process_bridge_OF_ranges(hose, np, primary); -+ -+ /* Parse inbound mapping resources */ -+ if (ppc4xx_parse_dma_ranges(hose, reg, &dma_window) != 0) -+ goto fail; -+ -+ /* Configure outbound ranges POMs */ -+ ppc4xx_configure_pci_PMMs(hose, reg); -+ -+ /* Configure inbound ranges PIMs */ -+ ppc4xx_configure_pci_PTMs(hose, reg, &dma_window); -+ -+ /* We don't need the registers anymore */ -+ iounmap(reg); -+ return; -+ -+ fail: -+ if (hose) -+ pcibios_free_controller(hose); -+ if (reg) -+ iounmap(reg); -+} -+ -+/* -+ * 4xx PCI-X part -+ */ -+ -+static void __init ppc4xx_configure_pcix_POMs(struct pci_controller *hose, -+ void __iomem *reg) -+{ -+ u32 lah, lal, pciah, pcial, sa; -+ int i, j; -+ -+ /* Setup outbound memory windows */ -+ for (i = j = 0; i < 3; i++) { -+ struct resource *res = &hose->mem_resources[i]; -+ -+ /* we only care about memory windows */ -+ if (!(res->flags & IORESOURCE_MEM)) -+ continue; -+ if (j > 1) { -+ printk(KERN_WARNING "%s: Too many ranges\n", -+ hose->dn->full_name); -+ break; -+ } -+ -+ /* Calculate register values */ -+ lah = RES_TO_U32_HIGH(res->start); -+ lal = RES_TO_U32_LOW(res->start); -+ pciah = RES_TO_U32_HIGH(res->start - hose->pci_mem_offset); -+ pcial = RES_TO_U32_LOW(res->start - hose->pci_mem_offset); -+ sa = res->end + 1 - res->start; -+ if (!is_power_of_2(sa) || sa < 0x100000 || -+ sa > 0xffffffffu) { -+ printk(KERN_WARNING "%s: Resource out of range\n", -+ hose->dn->full_name); -+ continue; -+ } -+ sa = (0xffffffffu << ilog2(sa)) | 0x1; -+ -+ /* Program register values */ -+ if (j == 0) { -+ writel(lah, reg + PCIX0_POM0LAH); -+ writel(lal, reg + PCIX0_POM0LAL); -+ writel(pciah, reg + PCIX0_POM0PCIAH); -+ writel(pcial, reg + PCIX0_POM0PCIAL); -+ writel(sa, reg + PCIX0_POM0SA); -+ } else { -+ writel(lah, reg + PCIX0_POM1LAH); -+ writel(lal, reg + PCIX0_POM1LAL); -+ writel(pciah, reg + PCIX0_POM1PCIAH); -+ writel(pcial, reg + PCIX0_POM1PCIAL); -+ writel(sa, reg + PCIX0_POM1SA); -+ } -+ j++; -+ } -+} -+ -+static void __init ppc4xx_configure_pcix_PIMs(struct pci_controller *hose, -+ void __iomem *reg, -+ const struct resource *res, -+ int big_pim, -+ int enable_msi_hole) -+{ -+ resource_size_t size = res->end - res->start + 1; -+ u32 sa; -+ -+ /* RAM is always at 0 */ -+ writel(0x00000000, reg + PCIX0_PIM0LAH); -+ writel(0x00000000, reg + PCIX0_PIM0LAL); -+ -+ /* Calculate window size */ -+ sa = (0xffffffffu << ilog2(size)) | 1; -+ sa |= 0x1; -+ if (res->flags & IORESOURCE_PREFETCH) -+ sa |= 0x2; -+ if (enable_msi_hole) -+ sa |= 0x4; -+ writel(sa, reg + PCIX0_PIM0SA); -+ if (big_pim) -+ writel(0xffffffff, reg + PCIX0_PIM0SAH); -+ -+ /* Map on PCI side */ -+ writel(0x00000000, reg + PCIX0_BAR0H); -+ writel(res->start, reg + PCIX0_BAR0L); -+ writew(0x0006, reg + PCIX0_COMMAND); -+} -+ -+static void __init ppc4xx_probe_pcix_bridge(struct device_node *np) -+{ -+ struct resource rsrc_cfg; -+ struct resource rsrc_reg; -+ struct resource dma_window; -+ struct pci_controller *hose = NULL; -+ void __iomem *reg = NULL; -+ const int *bus_range; -+ int big_pim = 0, msi = 0, primary = 0; -+ -+ /* Fetch config space registers address */ -+ if (of_address_to_resource(np, 0, &rsrc_cfg)) { -+ printk(KERN_ERR "%s:Can't get PCI-X config register base !", -+ np->full_name); -+ return; -+ } -+ /* Fetch host bridge internal registers address */ -+ if (of_address_to_resource(np, 3, &rsrc_reg)) { -+ printk(KERN_ERR "%s: Can't get PCI-X internal register base !", -+ np->full_name); -+ return; -+ } -+ -+ /* Check if it supports large PIMs (440GX) */ -+ if (of_get_property(np, "large-inbound-windows", NULL)) -+ big_pim = 1; -+ -+ /* Check if we should enable MSIs inbound hole */ -+ if (of_get_property(np, "enable-msi-hole", NULL)) -+ msi = 1; -+ -+ /* Check if primary bridge */ -+ if (of_get_property(np, "primary", NULL)) -+ primary = 1; -+ -+ /* Get bus range if any */ -+ bus_range = of_get_property(np, "bus-range", NULL); -+ -+ /* Map registers */ -+ reg = ioremap(rsrc_reg.start, rsrc_reg.end + 1 - rsrc_reg.start); -+ if (reg == NULL) { -+ printk(KERN_ERR "%s: Can't map registers !", np->full_name); -+ goto fail; -+ } -+ -+ /* Allocate the host controller data structure */ -+ hose = pcibios_alloc_controller(np); -+ if (!hose) -+ goto fail; -+ -+ hose->first_busno = bus_range ? bus_range[0] : 0x0; -+ hose->last_busno = bus_range ? bus_range[1] : 0xff; -+ -+ /* Setup config space */ -+ setup_indirect_pci(hose, rsrc_cfg.start, rsrc_cfg.start + 0x4, 0); -+ -+ /* Disable all windows */ -+ writel(0, reg + PCIX0_POM0SA); -+ writel(0, reg + PCIX0_POM1SA); -+ writel(0, reg + PCIX0_POM2SA); -+ writel(0, reg + PCIX0_PIM0SA); -+ writel(0, reg + PCIX0_PIM1SA); -+ writel(0, reg + PCIX0_PIM2SA); -+ if (big_pim) { -+ writel(0, reg + PCIX0_PIM0SAH); -+ writel(0, reg + PCIX0_PIM2SAH); -+ } -+ -+ /* Parse outbound mapping resources */ -+ pci_process_bridge_OF_ranges(hose, np, primary); -+ -+ /* Parse inbound mapping resources */ -+ if (ppc4xx_parse_dma_ranges(hose, reg, &dma_window) != 0) -+ goto fail; -+ -+ /* Configure outbound ranges POMs */ -+ ppc4xx_configure_pcix_POMs(hose, reg); -+ -+ /* Configure inbound ranges PIMs */ -+ ppc4xx_configure_pcix_PIMs(hose, reg, &dma_window, big_pim, msi); -+ -+ /* We don't need the registers anymore */ -+ iounmap(reg); -+ return; -+ -+ fail: -+ if (hose) -+ pcibios_free_controller(hose); -+ if (reg) -+ iounmap(reg); -+} -+ -+#ifdef CONFIG_PPC4xx_PCI_EXPRESS -+ -+/* -+ * 4xx PCI-Express part -+ * -+ * We support 3 parts currently based on the compatible property: -+ * -+ * ibm,plb-pciex-440spe -+ * ibm,plb-pciex-405ex -+ * -+ * Anything else will be rejected for now as they are all subtly -+ * different unfortunately. -+ * -+ */ -+ -+#define MAX_PCIE_BUS_MAPPED 0x40 -+ -+struct ppc4xx_pciex_port -+{ -+ struct pci_controller *hose; -+ struct device_node *node; -+ unsigned int index; -+ int endpoint; -+ int link; -+ int has_ibpre; -+ unsigned int sdr_base; -+ dcr_host_t dcrs; -+ struct resource cfg_space; -+ struct resource utl_regs; -+ void __iomem *utl_base; -+}; -+ -+static struct ppc4xx_pciex_port *ppc4xx_pciex_ports; -+static unsigned int ppc4xx_pciex_port_count; -+ -+struct ppc4xx_pciex_hwops -+{ -+ int (*core_init)(struct device_node *np); -+ int (*port_init_hw)(struct ppc4xx_pciex_port *port); -+ int (*setup_utl)(struct ppc4xx_pciex_port *port); -+}; -+ -+static struct ppc4xx_pciex_hwops *ppc4xx_pciex_hwops; -+ -+#ifdef CONFIG_44x -+ -+/* Check various reset bits of the 440SPe PCIe core */ -+static int __init ppc440spe_pciex_check_reset(struct device_node *np) -+{ -+ u32 valPE0, valPE1, valPE2; -+ int err = 0; -+ -+ /* SDR0_PEGPLLLCT1 reset */ -+ if (!(mfdcri(SDR0, PESDR0_PLLLCT1) & 0x01000000)) { -+ /* -+ * the PCIe core was probably already initialised -+ * by firmware - let's re-reset RCSSET regs -+ * -+ * -- Shouldn't we also re-reset the whole thing ? -- BenH -+ */ -+ pr_debug("PCIE: SDR0_PLLLCT1 already reset.\n"); -+ mtdcri(SDR0, PESDR0_440SPE_RCSSET, 0x01010000); -+ mtdcri(SDR0, PESDR1_440SPE_RCSSET, 0x01010000); -+ mtdcri(SDR0, PESDR2_440SPE_RCSSET, 0x01010000); -+ } -+ -+ valPE0 = mfdcri(SDR0, PESDR0_440SPE_RCSSET); -+ valPE1 = mfdcri(SDR0, PESDR1_440SPE_RCSSET); -+ valPE2 = mfdcri(SDR0, PESDR2_440SPE_RCSSET); -+ -+ /* SDR0_PExRCSSET rstgu */ -+ if (!(valPE0 & 0x01000000) || -+ !(valPE1 & 0x01000000) || -+ !(valPE2 & 0x01000000)) { -+ printk(KERN_INFO "PCIE: SDR0_PExRCSSET rstgu error\n"); -+ err = -1; -+ } -+ -+ /* SDR0_PExRCSSET rstdl */ -+ if (!(valPE0 & 0x00010000) || -+ !(valPE1 & 0x00010000) || -+ !(valPE2 & 0x00010000)) { -+ printk(KERN_INFO "PCIE: SDR0_PExRCSSET rstdl error\n"); -+ err = -1; -+ } -+ -+ /* SDR0_PExRCSSET rstpyn */ -+ if ((valPE0 & 0x00001000) || -+ (valPE1 & 0x00001000) || -+ (valPE2 & 0x00001000)) { -+ printk(KERN_INFO "PCIE: SDR0_PExRCSSET rstpyn error\n"); -+ err = -1; -+ } -+ -+ /* SDR0_PExRCSSET hldplb */ -+ if ((valPE0 & 0x10000000) || -+ (valPE1 & 0x10000000) || -+ (valPE2 & 0x10000000)) { -+ printk(KERN_INFO "PCIE: SDR0_PExRCSSET hldplb error\n"); -+ err = -1; -+ } -+ -+ /* SDR0_PExRCSSET rdy */ -+ if ((valPE0 & 0x00100000) || -+ (valPE1 & 0x00100000) || -+ (valPE2 & 0x00100000)) { -+ printk(KERN_INFO "PCIE: SDR0_PExRCSSET rdy error\n"); -+ err = -1; -+ } -+ -+ /* SDR0_PExRCSSET shutdown */ -+ if ((valPE0 & 0x00000100) || -+ (valPE1 & 0x00000100) || -+ (valPE2 & 0x00000100)) { -+ printk(KERN_INFO "PCIE: SDR0_PExRCSSET shutdown error\n"); -+ err = -1; -+ } -+ -+ return err; -+} -+ -+/* Global PCIe core initializations for 440SPe core */ -+static int __init ppc440spe_pciex_core_init(struct device_node *np) -+{ -+ int time_out = 20; -+ -+ /* Set PLL clock receiver to LVPECL */ -+ mtdcri(SDR0, PESDR0_PLLLCT1, mfdcri(SDR0, PESDR0_PLLLCT1) | 1 << 28); -+ -+ /* Shouldn't we do all the calibration stuff etc... here ? */ -+ if (ppc440spe_pciex_check_reset(np)) -+ return -ENXIO; -+ -+ if (!(mfdcri(SDR0, PESDR0_PLLLCT2) & 0x10000)) { -+ printk(KERN_INFO "PCIE: PESDR_PLLCT2 resistance calibration " -+ "failed (0x%08x)\n", -+ mfdcri(SDR0, PESDR0_PLLLCT2)); -+ return -1; -+ } -+ -+ /* De-assert reset of PCIe PLL, wait for lock */ -+ mtdcri(SDR0, PESDR0_PLLLCT1, -+ mfdcri(SDR0, PESDR0_PLLLCT1) & ~(1 << 24)); -+ udelay(3); -+ -+ while (time_out) { -+ if (!(mfdcri(SDR0, PESDR0_PLLLCT3) & 0x10000000)) { -+ time_out--; -+ udelay(1); -+ } else -+ break; -+ } -+ if (!time_out) { -+ printk(KERN_INFO "PCIE: VCO output not locked\n"); -+ return -1; -+ } -+ -+ pr_debug("PCIE initialization OK\n"); -+ -+ return 3; -+} -+ -+static int ppc440spe_pciex_init_port_hw(struct ppc4xx_pciex_port *port) -+{ -+ u32 val = 1 << 24; -+ -+ if (port->endpoint) -+ val = PTYPE_LEGACY_ENDPOINT << 20; -+ else -+ val = PTYPE_ROOT_PORT << 20; -+ -+ if (port->index == 0) -+ val |= LNKW_X8 << 12; -+ else -+ val |= LNKW_X4 << 12; -+ -+ mtdcri(SDR0, port->sdr_base + PESDRn_DLPSET, val); -+ mtdcri(SDR0, port->sdr_base + PESDRn_UTLSET1, 0x20222222); -+ if (ppc440spe_revA()) -+ mtdcri(SDR0, port->sdr_base + PESDRn_UTLSET2, 0x11000000); -+ mtdcri(SDR0, port->sdr_base + PESDRn_440SPE_HSSL0SET1, 0x35000000); -+ mtdcri(SDR0, port->sdr_base + PESDRn_440SPE_HSSL1SET1, 0x35000000); -+ mtdcri(SDR0, port->sdr_base + PESDRn_440SPE_HSSL2SET1, 0x35000000); -+ mtdcri(SDR0, port->sdr_base + PESDRn_440SPE_HSSL3SET1, 0x35000000); -+ if (port->index == 0) { -+ mtdcri(SDR0, port->sdr_base + PESDRn_440SPE_HSSL4SET1, -+ 0x35000000); -+ mtdcri(SDR0, port->sdr_base + PESDRn_440SPE_HSSL5SET1, -+ 0x35000000); -+ mtdcri(SDR0, port->sdr_base + PESDRn_440SPE_HSSL6SET1, -+ 0x35000000); -+ mtdcri(SDR0, port->sdr_base + PESDRn_440SPE_HSSL7SET1, -+ 0x35000000); -+ } -+ val = mfdcri(SDR0, port->sdr_base + PESDRn_RCSSET); -+ mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET, -+ (val & ~(1 << 24 | 1 << 16)) | 1 << 12); -+ -+ return 0; -+} -+ -+static int ppc440speA_pciex_init_port_hw(struct ppc4xx_pciex_port *port) -+{ -+ return ppc440spe_pciex_init_port_hw(port); -+} -+ -+static int ppc440speB_pciex_init_port_hw(struct ppc4xx_pciex_port *port) -+{ -+ int rc = ppc440spe_pciex_init_port_hw(port); -+ -+ port->has_ibpre = 1; -+ -+ return rc; -+} -+ -+static int ppc440speA_pciex_init_utl(struct ppc4xx_pciex_port *port) -+{ -+ /* XXX Check what that value means... I hate magic */ -+ dcr_write(port->dcrs, DCRO_PEGPL_SPECIAL, 0x68782800); -+ -+ /* -+ * Set buffer allocations and then assert VRB and TXE. -+ */ -+ out_be32(port->utl_base + PEUTL_OUTTR, 0x08000000); -+ out_be32(port->utl_base + PEUTL_INTR, 0x02000000); -+ out_be32(port->utl_base + PEUTL_OPDBSZ, 0x10000000); -+ out_be32(port->utl_base + PEUTL_PBBSZ, 0x53000000); -+ out_be32(port->utl_base + PEUTL_IPHBSZ, 0x08000000); -+ out_be32(port->utl_base + PEUTL_IPDBSZ, 0x10000000); -+ out_be32(port->utl_base + PEUTL_RCIRQEN, 0x00f00000); -+ out_be32(port->utl_base + PEUTL_PCTL, 0x80800066); -+ -+ return 0; -+} -+ -+static int ppc440speB_pciex_init_utl(struct ppc4xx_pciex_port *port) -+{ -+ /* Report CRS to the operating system */ -+ out_be32(port->utl_base + PEUTL_PBCTL, 0x08000000); -+ -+ return 0; -+} -+ -+static struct ppc4xx_pciex_hwops ppc440speA_pcie_hwops __initdata = -+{ -+ .core_init = ppc440spe_pciex_core_init, -+ .port_init_hw = ppc440speA_pciex_init_port_hw, -+ .setup_utl = ppc440speA_pciex_init_utl, -+}; -+ -+static struct ppc4xx_pciex_hwops ppc440speB_pcie_hwops __initdata = -+{ -+ .core_init = ppc440spe_pciex_core_init, -+ .port_init_hw = ppc440speB_pciex_init_port_hw, -+ .setup_utl = ppc440speB_pciex_init_utl, -+}; -+ -+#endif /* CONFIG_44x */ -+ -+#ifdef CONFIG_40x -+ -+static int __init ppc405ex_pciex_core_init(struct device_node *np) -+{ -+ /* Nothing to do, return 2 ports */ -+ return 2; -+} -+ -+static void ppc405ex_pcie_phy_reset(struct ppc4xx_pciex_port *port) -+{ -+ /* Assert the PE0_PHY reset */ -+ mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET, 0x01010000); -+ msleep(1); -+ -+ /* deassert the PE0_hotreset */ -+ if (port->endpoint) -+ mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET, 0x01111000); -+ else -+ mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET, 0x01101000); -+ -+ /* poll for phy !reset */ -+ /* XXX FIXME add timeout */ -+ while (!(mfdcri(SDR0, port->sdr_base + PESDRn_405EX_PHYSTA) & 0x00001000)) -+ ; -+ -+ /* deassert the PE0_gpl_utl_reset */ -+ mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET, 0x00101000); -+} -+ -+static int ppc405ex_pciex_init_port_hw(struct ppc4xx_pciex_port *port) -+{ -+ u32 val; -+ -+ if (port->endpoint) -+ val = PTYPE_LEGACY_ENDPOINT; -+ else -+ val = PTYPE_ROOT_PORT; -+ -+ mtdcri(SDR0, port->sdr_base + PESDRn_DLPSET, -+ 1 << 24 | val << 20 | LNKW_X1 << 12); -+ -+ mtdcri(SDR0, port->sdr_base + PESDRn_UTLSET1, 0x00000000); -+ mtdcri(SDR0, port->sdr_base + PESDRn_UTLSET2, 0x01010000); -+ mtdcri(SDR0, port->sdr_base + PESDRn_405EX_PHYSET1, 0x720F0000); -+ mtdcri(SDR0, port->sdr_base + PESDRn_405EX_PHYSET2, 0x70600003); -+ -+ /* -+ * Only reset the PHY when no link is currently established. -+ * This is for the Atheros PCIe board which has problems to establish -+ * the link (again) after this PHY reset. All other currently tested -+ * PCIe boards don't show this problem. -+ * This has to be re-tested and fixed in a later release! -+ */ -+#if 0 /* XXX FIXME: Not resetting the PHY will leave all resources -+ * configured as done previously by U-Boot. Then Linux will currently -+ * not reassign them. So the PHY reset is now done always. This will -+ * lead to problems with the Atheros PCIe board again. -+ */ -+ val = mfdcri(SDR0, port->sdr_base + PESDRn_LOOP); -+ if (!(val & 0x00001000)) -+ ppc405ex_pcie_phy_reset(port); -+#else -+ ppc405ex_pcie_phy_reset(port); -+#endif -+ -+ dcr_write(port->dcrs, DCRO_PEGPL_CFG, 0x10000000); /* guarded on */ -+ -+ port->has_ibpre = 1; -+ -+ return 0; -+} -+ -+static int ppc405ex_pciex_init_utl(struct ppc4xx_pciex_port *port) -+{ -+ dcr_write(port->dcrs, DCRO_PEGPL_SPECIAL, 0x0); -+ -+ /* -+ * Set buffer allocations and then assert VRB and TXE. -+ */ -+ out_be32(port->utl_base + PEUTL_OUTTR, 0x02000000); -+ out_be32(port->utl_base + PEUTL_INTR, 0x02000000); -+ out_be32(port->utl_base + PEUTL_OPDBSZ, 0x04000000); -+ out_be32(port->utl_base + PEUTL_PBBSZ, 0x21000000); -+ out_be32(port->utl_base + PEUTL_IPHBSZ, 0x02000000); -+ out_be32(port->utl_base + PEUTL_IPDBSZ, 0x04000000); -+ out_be32(port->utl_base + PEUTL_RCIRQEN, 0x00f00000); -+ out_be32(port->utl_base + PEUTL_PCTL, 0x80800066); -+ -+ out_be32(port->utl_base + PEUTL_PBCTL, 0x08000000); -+ -+ return 0; -+} -+ -+static struct ppc4xx_pciex_hwops ppc405ex_pcie_hwops __initdata = -+{ -+ .core_init = ppc405ex_pciex_core_init, -+ .port_init_hw = ppc405ex_pciex_init_port_hw, -+ .setup_utl = ppc405ex_pciex_init_utl, -+}; -+ -+#endif /* CONFIG_40x */ -+ -+ -+/* Check that the core has been initied and if not, do it */ -+static int __init ppc4xx_pciex_check_core_init(struct device_node *np) -+{ -+ static int core_init; -+ int count = -ENODEV; -+ -+ if (core_init++) -+ return 0; -+ -+#ifdef CONFIG_44x -+ if (of_device_is_compatible(np, "ibm,plb-pciex-440spe")) { -+ if (ppc440spe_revA()) -+ ppc4xx_pciex_hwops = &ppc440speA_pcie_hwops; -+ else -+ ppc4xx_pciex_hwops = &ppc440speB_pcie_hwops; -+ } -+#endif /* CONFIG_44x */ -+#ifdef CONFIG_40x -+ if (of_device_is_compatible(np, "ibm,plb-pciex-405ex")) -+ ppc4xx_pciex_hwops = &ppc405ex_pcie_hwops; -+#endif -+ if (ppc4xx_pciex_hwops == NULL) { -+ printk(KERN_WARNING "PCIE: unknown host type %s\n", -+ np->full_name); -+ return -ENODEV; -+ } -+ -+ count = ppc4xx_pciex_hwops->core_init(np); -+ if (count > 0) { -+ ppc4xx_pciex_ports = -+ kzalloc(count * sizeof(struct ppc4xx_pciex_port), -+ GFP_KERNEL); -+ if (ppc4xx_pciex_ports) { -+ ppc4xx_pciex_port_count = count; -+ return 0; -+ } -+ printk(KERN_WARNING "PCIE: failed to allocate ports array\n"); -+ return -ENOMEM; -+ } -+ return -ENODEV; -+} -+ -+static void __init ppc4xx_pciex_port_init_mapping(struct ppc4xx_pciex_port *port) -+{ -+ /* We map PCI Express configuration based on the reg property */ -+ dcr_write(port->dcrs, DCRO_PEGPL_CFGBAH, -+ RES_TO_U32_HIGH(port->cfg_space.start)); -+ dcr_write(port->dcrs, DCRO_PEGPL_CFGBAL, -+ RES_TO_U32_LOW(port->cfg_space.start)); -+ -+ /* XXX FIXME: Use size from reg property. For now, map 512M */ -+ dcr_write(port->dcrs, DCRO_PEGPL_CFGMSK, 0xe0000001); -+ -+ /* We map UTL registers based on the reg property */ -+ dcr_write(port->dcrs, DCRO_PEGPL_REGBAH, -+ RES_TO_U32_HIGH(port->utl_regs.start)); -+ dcr_write(port->dcrs, DCRO_PEGPL_REGBAL, -+ RES_TO_U32_LOW(port->utl_regs.start)); -+ -+ /* XXX FIXME: Use size from reg property */ -+ dcr_write(port->dcrs, DCRO_PEGPL_REGMSK, 0x00007001); -+ -+ /* Disable all other outbound windows */ -+ dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL, 0); -+ dcr_write(port->dcrs, DCRO_PEGPL_OMR2MSKL, 0); -+ dcr_write(port->dcrs, DCRO_PEGPL_OMR3MSKL, 0); -+ dcr_write(port->dcrs, DCRO_PEGPL_MSGMSK, 0); -+} -+ -+static int __init ppc4xx_pciex_wait_on_sdr(struct ppc4xx_pciex_port *port, -+ unsigned int sdr_offset, -+ unsigned int mask, -+ unsigned int value, -+ int timeout_ms) -+{ -+ u32 val; -+ -+ while(timeout_ms--) { -+ val = mfdcri(SDR0, port->sdr_base + sdr_offset); -+ if ((val & mask) == value) { -+ pr_debug("PCIE%d: Wait on SDR %x success with tm %d (%08x)\n", -+ port->index, sdr_offset, timeout_ms, val); -+ return 0; -+ } -+ msleep(1); -+ } -+ return -1; -+} -+ -+static int __init ppc4xx_pciex_port_init(struct ppc4xx_pciex_port *port) -+{ -+ int rc = 0; -+ -+ /* Init HW */ -+ if (ppc4xx_pciex_hwops->port_init_hw) -+ rc = ppc4xx_pciex_hwops->port_init_hw(port); -+ if (rc != 0) -+ return rc; -+ -+ printk(KERN_INFO "PCIE%d: Checking link...\n", -+ port->index); -+ -+ /* Wait for reset to complete */ -+ if (ppc4xx_pciex_wait_on_sdr(port, PESDRn_RCSSTS, 1 << 20, 0, 10)) { -+ printk(KERN_WARNING "PCIE%d: PGRST failed\n", -+ port->index); -+ return -1; -+ } -+ -+ /* Check for card presence detect if supported, if not, just wait for -+ * link unconditionally. -+ * -+ * note that we don't fail if there is no link, we just filter out -+ * config space accesses. That way, it will be easier to implement -+ * hotplug later on. -+ */ -+ if (!port->has_ibpre || -+ !ppc4xx_pciex_wait_on_sdr(port, PESDRn_LOOP, -+ 1 << 28, 1 << 28, 100)) { -+ printk(KERN_INFO -+ "PCIE%d: Device detected, waiting for link...\n", -+ port->index); -+ if (ppc4xx_pciex_wait_on_sdr(port, PESDRn_LOOP, -+ 0x1000, 0x1000, 2000)) -+ printk(KERN_WARNING -+ "PCIE%d: Link up failed\n", port->index); -+ else { -+ printk(KERN_INFO -+ "PCIE%d: link is up !\n", port->index); -+ port->link = 1; -+ } -+ } else -+ printk(KERN_INFO "PCIE%d: No device detected.\n", port->index); -+ -+ /* -+ * Initialize mapping: disable all regions and configure -+ * CFG and REG regions based on resources in the device tree -+ */ -+ ppc4xx_pciex_port_init_mapping(port); -+ -+ /* -+ * Map UTL -+ */ -+ port->utl_base = ioremap(port->utl_regs.start, 0x100); -+ BUG_ON(port->utl_base == NULL); -+ -+ /* -+ * Setup UTL registers --BenH. -+ */ -+ if (ppc4xx_pciex_hwops->setup_utl) -+ ppc4xx_pciex_hwops->setup_utl(port); -+ -+ /* -+ * Check for VC0 active and assert RDY. -+ */ -+ if (port->link && -+ ppc4xx_pciex_wait_on_sdr(port, PESDRn_RCSSTS, -+ 1 << 16, 1 << 16, 5000)) { -+ printk(KERN_INFO "PCIE%d: VC0 not active\n", port->index); -+ port->link = 0; -+ } -+ -+ mtdcri(SDR0, port->sdr_base + PESDRn_RCSSET, -+ mfdcri(SDR0, port->sdr_base + PESDRn_RCSSET) | 1 << 20); -+ msleep(100); -+ -+ return 0; -+} -+ -+static int ppc4xx_pciex_validate_bdf(struct ppc4xx_pciex_port *port, -+ struct pci_bus *bus, -+ unsigned int devfn) -+{ -+ static int message; -+ -+ /* Endpoint can not generate upstream(remote) config cycles */ -+ if (port->endpoint && bus->number != port->hose->first_busno) -+ return PCIBIOS_DEVICE_NOT_FOUND; -+ -+ /* Check we are within the mapped range */ -+ if (bus->number > port->hose->last_busno) { -+ if (!message) { -+ printk(KERN_WARNING "Warning! Probing bus %u" -+ " out of range !\n", bus->number); -+ message++; -+ } -+ return PCIBIOS_DEVICE_NOT_FOUND; -+ } -+ -+ /* The root complex has only one device / function */ -+ if (bus->number == port->hose->first_busno && devfn != 0) -+ return PCIBIOS_DEVICE_NOT_FOUND; -+ -+ /* The other side of the RC has only one device as well */ -+ if (bus->number == (port->hose->first_busno + 1) && -+ PCI_SLOT(devfn) != 0) -+ return PCIBIOS_DEVICE_NOT_FOUND; -+ -+ /* Check if we have a link */ -+ if ((bus->number != port->hose->first_busno) && !port->link) -+ return PCIBIOS_DEVICE_NOT_FOUND; -+ -+ return 0; -+} -+ -+static void __iomem *ppc4xx_pciex_get_config_base(struct ppc4xx_pciex_port *port, -+ struct pci_bus *bus, -+ unsigned int devfn) -+{ -+ int relbus; -+ -+ /* Remove the casts when we finally remove the stupid volatile -+ * in struct pci_controller -+ */ -+ if (bus->number == port->hose->first_busno) -+ return (void __iomem *)port->hose->cfg_addr; -+ -+ relbus = bus->number - (port->hose->first_busno + 1); -+ return (void __iomem *)port->hose->cfg_data + -+ ((relbus << 20) | (devfn << 12)); -+} -+ -+static int ppc4xx_pciex_read_config(struct pci_bus *bus, unsigned int devfn, -+ int offset, int len, u32 *val) -+{ -+ struct pci_controller *hose = (struct pci_controller *) bus->sysdata; -+ struct ppc4xx_pciex_port *port = -+ &ppc4xx_pciex_ports[hose->indirect_type]; -+ void __iomem *addr; -+ u32 gpl_cfg; -+ -+ BUG_ON(hose != port->hose); -+ -+ if (ppc4xx_pciex_validate_bdf(port, bus, devfn) != 0) -+ return PCIBIOS_DEVICE_NOT_FOUND; -+ -+ addr = ppc4xx_pciex_get_config_base(port, bus, devfn); -+ -+ /* -+ * Reading from configuration space of non-existing device can -+ * generate transaction errors. For the read duration we suppress -+ * assertion of machine check exceptions to avoid those. -+ */ -+ gpl_cfg = dcr_read(port->dcrs, DCRO_PEGPL_CFG); -+ dcr_write(port->dcrs, DCRO_PEGPL_CFG, gpl_cfg | GPL_DMER_MASK_DISA); -+ -+ /* Make sure no CRS is recorded */ -+ out_be32(port->utl_base + PEUTL_RCSTA, 0x00040000); -+ -+ switch (len) { -+ case 1: -+ *val = in_8((u8 *)(addr + offset)); -+ break; -+ case 2: -+ *val = in_le16((u16 *)(addr + offset)); -+ break; -+ default: -+ *val = in_le32((u32 *)(addr + offset)); -+ break; -+ } -+ -+ pr_debug("pcie-config-read: bus=%3d [%3d..%3d] devfn=0x%04x" -+ " offset=0x%04x len=%d, addr=0x%p val=0x%08x\n", -+ bus->number, hose->first_busno, hose->last_busno, -+ devfn, offset, len, addr + offset, *val); -+ -+ /* Check for CRS (440SPe rev B does that for us but heh ..) */ -+ if (in_be32(port->utl_base + PEUTL_RCSTA) & 0x00040000) { -+ pr_debug("Got CRS !\n"); -+ if (len != 4 || offset != 0) -+ return PCIBIOS_DEVICE_NOT_FOUND; -+ *val = 0xffff0001; -+ } -+ -+ dcr_write(port->dcrs, DCRO_PEGPL_CFG, gpl_cfg); -+ -+ return PCIBIOS_SUCCESSFUL; -+} -+ -+static int ppc4xx_pciex_write_config(struct pci_bus *bus, unsigned int devfn, -+ int offset, int len, u32 val) -+{ -+ struct pci_controller *hose = (struct pci_controller *) bus->sysdata; -+ struct ppc4xx_pciex_port *port = -+ &ppc4xx_pciex_ports[hose->indirect_type]; -+ void __iomem *addr; -+ u32 gpl_cfg; -+ -+ if (ppc4xx_pciex_validate_bdf(port, bus, devfn) != 0) -+ return PCIBIOS_DEVICE_NOT_FOUND; -+ -+ addr = ppc4xx_pciex_get_config_base(port, bus, devfn); -+ -+ /* -+ * Reading from configuration space of non-existing device can -+ * generate transaction errors. For the read duration we suppress -+ * assertion of machine check exceptions to avoid those. -+ */ -+ gpl_cfg = dcr_read(port->dcrs, DCRO_PEGPL_CFG); -+ dcr_write(port->dcrs, DCRO_PEGPL_CFG, gpl_cfg | GPL_DMER_MASK_DISA); -+ -+ pr_debug("pcie-config-write: bus=%3d [%3d..%3d] devfn=0x%04x" -+ " offset=0x%04x len=%d, addr=0x%p val=0x%08x\n", -+ bus->number, hose->first_busno, hose->last_busno, -+ devfn, offset, len, addr + offset, val); -+ -+ switch (len) { -+ case 1: -+ out_8((u8 *)(addr + offset), val); -+ break; -+ case 2: -+ out_le16((u16 *)(addr + offset), val); -+ break; -+ default: -+ out_le32((u32 *)(addr + offset), val); -+ break; -+ } -+ -+ dcr_write(port->dcrs, DCRO_PEGPL_CFG, gpl_cfg); -+ -+ return PCIBIOS_SUCCESSFUL; -+} -+ -+static struct pci_ops ppc4xx_pciex_pci_ops = -+{ -+ .read = ppc4xx_pciex_read_config, -+ .write = ppc4xx_pciex_write_config, -+}; -+ -+static void __init ppc4xx_configure_pciex_POMs(struct ppc4xx_pciex_port *port, -+ struct pci_controller *hose, -+ void __iomem *mbase) -+{ -+ u32 lah, lal, pciah, pcial, sa; -+ int i, j; -+ -+ /* Setup outbound memory windows */ -+ for (i = j = 0; i < 3; i++) { -+ struct resource *res = &hose->mem_resources[i]; -+ -+ /* we only care about memory windows */ -+ if (!(res->flags & IORESOURCE_MEM)) -+ continue; -+ if (j > 1) { -+ printk(KERN_WARNING "%s: Too many ranges\n", -+ port->node->full_name); -+ break; -+ } -+ -+ /* Calculate register values */ -+ lah = RES_TO_U32_HIGH(res->start); -+ lal = RES_TO_U32_LOW(res->start); -+ pciah = RES_TO_U32_HIGH(res->start - hose->pci_mem_offset); -+ pcial = RES_TO_U32_LOW(res->start - hose->pci_mem_offset); -+ sa = res->end + 1 - res->start; -+ if (!is_power_of_2(sa) || sa < 0x100000 || -+ sa > 0xffffffffu) { -+ printk(KERN_WARNING "%s: Resource out of range\n", -+ port->node->full_name); -+ continue; -+ } -+ sa = (0xffffffffu << ilog2(sa)) | 0x1; -+ -+ /* Program register values */ -+ switch (j) { -+ case 0: -+ out_le32(mbase + PECFG_POM0LAH, pciah); -+ out_le32(mbase + PECFG_POM0LAL, pcial); -+ dcr_write(port->dcrs, DCRO_PEGPL_OMR1BAH, lah); -+ dcr_write(port->dcrs, DCRO_PEGPL_OMR1BAL, lal); -+ dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKH, 0x7fffffff); -+ dcr_write(port->dcrs, DCRO_PEGPL_OMR1MSKL, sa | 3); -+ break; -+ case 1: -+ out_le32(mbase + PECFG_POM1LAH, pciah); -+ out_le32(mbase + PECFG_POM1LAL, pcial); -+ dcr_write(port->dcrs, DCRO_PEGPL_OMR2BAH, lah); -+ dcr_write(port->dcrs, DCRO_PEGPL_OMR2BAL, lal); -+ dcr_write(port->dcrs, DCRO_PEGPL_OMR2MSKH, 0x7fffffff); -+ dcr_write(port->dcrs, DCRO_PEGPL_OMR2MSKL, sa | 3); -+ break; -+ } -+ j++; -+ } -+ -+ /* Configure IO, always 64K starting at 0 */ -+ if (hose->io_resource.flags & IORESOURCE_IO) { -+ lah = RES_TO_U32_HIGH(hose->io_base_phys); -+ lal = RES_TO_U32_LOW(hose->io_base_phys); -+ out_le32(mbase + PECFG_POM2LAH, 0); -+ out_le32(mbase + PECFG_POM2LAL, 0); -+ dcr_write(port->dcrs, DCRO_PEGPL_OMR3BAH, lah); -+ dcr_write(port->dcrs, DCRO_PEGPL_OMR3BAL, lal); -+ dcr_write(port->dcrs, DCRO_PEGPL_OMR3MSKH, 0x7fffffff); -+ dcr_write(port->dcrs, DCRO_PEGPL_OMR3MSKL, 0xffff0000 | 3); -+ } -+} -+ -+static void __init ppc4xx_configure_pciex_PIMs(struct ppc4xx_pciex_port *port, -+ struct pci_controller *hose, -+ void __iomem *mbase, -+ struct resource *res) -+{ -+ resource_size_t size = res->end - res->start + 1; -+ u64 sa; -+ -+ /* Calculate window size */ -+ sa = (0xffffffffffffffffull << ilog2(size));; -+ if (res->flags & IORESOURCE_PREFETCH) -+ sa |= 0x8; -+ -+ out_le32(mbase + PECFG_BAR0HMPA, RES_TO_U32_HIGH(sa)); -+ out_le32(mbase + PECFG_BAR0LMPA, RES_TO_U32_LOW(sa)); -+ -+ /* The setup of the split looks weird to me ... let's see if it works */ -+ out_le32(mbase + PECFG_PIM0LAL, 0x00000000); -+ out_le32(mbase + PECFG_PIM0LAH, 0x00000000); -+ out_le32(mbase + PECFG_PIM1LAL, 0x00000000); -+ out_le32(mbase + PECFG_PIM1LAH, 0x00000000); -+ out_le32(mbase + PECFG_PIM01SAH, 0xffff0000); -+ out_le32(mbase + PECFG_PIM01SAL, 0x00000000); -+ -+ /* Enable inbound mapping */ -+ out_le32(mbase + PECFG_PIMEN, 0x1); -+ -+ out_le32(mbase + PCI_BASE_ADDRESS_0, RES_TO_U32_LOW(res->start)); -+ out_le32(mbase + PCI_BASE_ADDRESS_1, RES_TO_U32_HIGH(res->start)); -+ -+ /* Enable I/O, Mem, and Busmaster cycles */ -+ out_le16(mbase + PCI_COMMAND, -+ in_le16(mbase + PCI_COMMAND) | -+ PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); -+} -+ -+static void __init ppc4xx_pciex_port_setup_hose(struct ppc4xx_pciex_port *port) -+{ -+ struct resource dma_window; -+ struct pci_controller *hose = NULL; -+ const int *bus_range; -+ int primary = 0, busses; -+ void __iomem *mbase = NULL, *cfg_data = NULL; -+ -+ /* XXX FIXME: Handle endpoint mode properly */ -+ if (port->endpoint) { -+ printk(KERN_WARNING "PCIE%d: Port in endpoint mode !\n", -+ port->index); -+ return; -+ } -+ -+ /* Check if primary bridge */ -+ if (of_get_property(port->node, "primary", NULL)) -+ primary = 1; -+ -+ /* Get bus range if any */ -+ bus_range = of_get_property(port->node, "bus-range", NULL); -+ -+ /* Allocate the host controller data structure */ -+ hose = pcibios_alloc_controller(port->node); -+ if (!hose) -+ goto fail; -+ -+ /* We stick the port number in "indirect_type" so the config space -+ * ops can retrieve the port data structure easily -+ */ -+ hose->indirect_type = port->index; -+ -+ /* Get bus range */ -+ hose->first_busno = bus_range ? bus_range[0] : 0x0; -+ hose->last_busno = bus_range ? bus_range[1] : 0xff; -+ -+ /* Because of how big mapping the config space is (1M per bus), we -+ * limit how many busses we support. In the long run, we could replace -+ * that with something akin to kmap_atomic instead. We set aside 1 bus -+ * for the host itself too. -+ */ -+ busses = hose->last_busno - hose->first_busno; /* This is off by 1 */ -+ if (busses > MAX_PCIE_BUS_MAPPED) { -+ busses = MAX_PCIE_BUS_MAPPED; -+ hose->last_busno = hose->first_busno + busses; -+ } -+ -+ /* We map the external config space in cfg_data and the host config -+ * space in cfg_addr. External space is 1M per bus, internal space -+ * is 4K -+ */ -+ cfg_data = ioremap(port->cfg_space.start + -+ (hose->first_busno + 1) * 0x100000, -+ busses * 0x100000); -+ mbase = ioremap(port->cfg_space.start + 0x10000000, 0x1000); -+ if (cfg_data == NULL || mbase == NULL) { -+ printk(KERN_ERR "%s: Can't map config space !", -+ port->node->full_name); -+ goto fail; -+ } -+ -+ hose->cfg_data = cfg_data; -+ hose->cfg_addr = mbase; -+ -+ pr_debug("PCIE %s, bus %d..%d\n", port->node->full_name, -+ hose->first_busno, hose->last_busno); -+ pr_debug(" config space mapped at: root @0x%p, other @0x%p\n", -+ hose->cfg_addr, hose->cfg_data); -+ -+ /* Setup config space */ -+ hose->ops = &ppc4xx_pciex_pci_ops; -+ port->hose = hose; -+ mbase = (void __iomem *)hose->cfg_addr; -+ -+ /* -+ * Set bus numbers on our root port -+ */ -+ out_8(mbase + PCI_PRIMARY_BUS, hose->first_busno); -+ out_8(mbase + PCI_SECONDARY_BUS, hose->first_busno + 1); -+ out_8(mbase + PCI_SUBORDINATE_BUS, hose->last_busno); -+ -+ /* -+ * OMRs are already reset, also disable PIMs -+ */ -+ out_le32(mbase + PECFG_PIMEN, 0); -+ -+ /* Parse outbound mapping resources */ -+ pci_process_bridge_OF_ranges(hose, port->node, primary); -+ -+ /* Parse inbound mapping resources */ -+ if (ppc4xx_parse_dma_ranges(hose, mbase, &dma_window) != 0) -+ goto fail; -+ -+ /* Configure outbound ranges POMs */ -+ ppc4xx_configure_pciex_POMs(port, hose, mbase); -+ -+ /* Configure inbound ranges PIMs */ -+ ppc4xx_configure_pciex_PIMs(port, hose, mbase, &dma_window); -+ -+ /* The root complex doesn't show up if we don't set some vendor -+ * and device IDs into it. Those are the same bogus one that the -+ * initial code in arch/ppc add. We might want to change that. -+ */ -+ out_le16(mbase + 0x200, 0xaaa0 + port->index); -+ out_le16(mbase + 0x202, 0xbed0 + port->index); -+ -+ /* Set Class Code to PCI-PCI bridge and Revision Id to 1 */ -+ out_le32(mbase + 0x208, 0x06040001); -+ -+ printk(KERN_INFO "PCIE%d: successfully set as root-complex\n", -+ port->index); -+ return; -+ fail: -+ if (hose) -+ pcibios_free_controller(hose); -+ if (cfg_data) -+ iounmap(cfg_data); -+ if (mbase) -+ iounmap(mbase); -+} -+ -+static void __init ppc4xx_probe_pciex_bridge(struct device_node *np) -+{ -+ struct ppc4xx_pciex_port *port; -+ const u32 *pval; -+ int portno; -+ unsigned int dcrs; -+ -+ /* First, proceed to core initialization as we assume there's -+ * only one PCIe core in the system -+ */ -+ if (ppc4xx_pciex_check_core_init(np)) -+ return; -+ -+ /* Get the port number from the device-tree */ -+ pval = of_get_property(np, "port", NULL); -+ if (pval == NULL) { -+ printk(KERN_ERR "PCIE: Can't find port number for %s\n", -+ np->full_name); -+ return; -+ } -+ portno = *pval; -+ if (portno >= ppc4xx_pciex_port_count) { -+ printk(KERN_ERR "PCIE: port number out of range for %s\n", -+ np->full_name); -+ return; -+ } -+ port = &ppc4xx_pciex_ports[portno]; -+ port->index = portno; -+ port->node = of_node_get(np); -+ pval = of_get_property(np, "sdr-base", NULL); -+ if (pval == NULL) { -+ printk(KERN_ERR "PCIE: missing sdr-base for %s\n", -+ np->full_name); -+ return; -+ } -+ port->sdr_base = *pval; -+ -+ /* XXX Currently, we only support root complex mode */ -+ port->endpoint = 0; -+ -+ /* Fetch config space registers address */ -+ if (of_address_to_resource(np, 0, &port->cfg_space)) { -+ printk(KERN_ERR "%s: Can't get PCI-E config space !", -+ np->full_name); -+ return; -+ } -+ /* Fetch host bridge internal registers address */ -+ if (of_address_to_resource(np, 1, &port->utl_regs)) { -+ printk(KERN_ERR "%s: Can't get UTL register base !", -+ np->full_name); -+ return; -+ } -+ -+ /* Map DCRs */ -+ dcrs = dcr_resource_start(np, 0); -+ if (dcrs == 0) { -+ printk(KERN_ERR "%s: Can't get DCR register base !", -+ np->full_name); -+ return; -+ } -+ port->dcrs = dcr_map(np, dcrs, dcr_resource_len(np, 0)); -+ -+ /* Initialize the port specific registers */ -+ if (ppc4xx_pciex_port_init(port)) { -+ printk(KERN_WARNING "PCIE%d: Port init failed\n", port->index); -+ return; -+ } -+ -+ /* Setup the linux hose data structure */ -+ ppc4xx_pciex_port_setup_hose(port); -+} -+ -+#endif /* CONFIG_PPC4xx_PCI_EXPRESS */ -+ -+static int __init ppc4xx_pci_find_bridges(void) -+{ -+ struct device_node *np; -+ -+#ifdef CONFIG_PPC4xx_PCI_EXPRESS -+ for_each_compatible_node(np, NULL, "ibm,plb-pciex") -+ ppc4xx_probe_pciex_bridge(np); -+#endif -+ for_each_compatible_node(np, NULL, "ibm,plb-pcix") -+ ppc4xx_probe_pcix_bridge(np); -+ for_each_compatible_node(np, NULL, "ibm,plb-pci") -+ ppc4xx_probe_pci_bridge(np); -+ -+ return 0; -+} -+arch_initcall(ppc4xx_pci_find_bridges); -+ ---- /dev/null -+++ b/arch/powerpc/sysdev/ppc4xx_pci.h -@@ -0,0 +1,369 @@ -+/* -+ * PCI / PCI-X / PCI-Express support for 4xx parts -+ * -+ * Copyright 2007 Ben. Herrenschmidt , IBM Corp. -+ * -+ * Bits and pieces extracted from arch/ppc support by -+ * -+ * Matt Porter -+ * -+ * Copyright 2002-2005 MontaVista Software Inc. -+ */ -+#ifndef __PPC4XX_PCI_H__ -+#define __PPC4XX_PCI_H__ -+ -+/* -+ * 4xx PCI-X bridge register definitions -+ */ -+#define PCIX0_VENDID 0x000 -+#define PCIX0_DEVID 0x002 -+#define PCIX0_COMMAND 0x004 -+#define PCIX0_STATUS 0x006 -+#define PCIX0_REVID 0x008 -+#define PCIX0_CLS 0x009 -+#define PCIX0_CACHELS 0x00c -+#define PCIX0_LATTIM 0x00d -+#define PCIX0_HDTYPE 0x00e -+#define PCIX0_BIST 0x00f -+#define PCIX0_BAR0L 0x010 -+#define PCIX0_BAR0H 0x014 -+#define PCIX0_BAR1 0x018 -+#define PCIX0_BAR2L 0x01c -+#define PCIX0_BAR2H 0x020 -+#define PCIX0_BAR3 0x024 -+#define PCIX0_CISPTR 0x028 -+#define PCIX0_SBSYSVID 0x02c -+#define PCIX0_SBSYSID 0x02e -+#define PCIX0_EROMBA 0x030 -+#define PCIX0_CAP 0x034 -+#define PCIX0_RES0 0x035 -+#define PCIX0_RES1 0x036 -+#define PCIX0_RES2 0x038 -+#define PCIX0_INTLN 0x03c -+#define PCIX0_INTPN 0x03d -+#define PCIX0_MINGNT 0x03e -+#define PCIX0_MAXLTNCY 0x03f -+#define PCIX0_BRDGOPT1 0x040 -+#define PCIX0_BRDGOPT2 0x044 -+#define PCIX0_ERREN 0x050 -+#define PCIX0_ERRSTS 0x054 -+#define PCIX0_PLBBESR 0x058 -+#define PCIX0_PLBBEARL 0x05c -+#define PCIX0_PLBBEARH 0x060 -+#define PCIX0_POM0LAL 0x068 -+#define PCIX0_POM0LAH 0x06c -+#define PCIX0_POM0SA 0x070 -+#define PCIX0_POM0PCIAL 0x074 -+#define PCIX0_POM0PCIAH 0x078 -+#define PCIX0_POM1LAL 0x07c -+#define PCIX0_POM1LAH 0x080 -+#define PCIX0_POM1SA 0x084 -+#define PCIX0_POM1PCIAL 0x088 -+#define PCIX0_POM1PCIAH 0x08c -+#define PCIX0_POM2SA 0x090 -+#define PCIX0_PIM0SAL 0x098 -+#define PCIX0_PIM0SA PCIX0_PIM0SAL -+#define PCIX0_PIM0LAL 0x09c -+#define PCIX0_PIM0LAH 0x0a0 -+#define PCIX0_PIM1SA 0x0a4 -+#define PCIX0_PIM1LAL 0x0a8 -+#define PCIX0_PIM1LAH 0x0ac -+#define PCIX0_PIM2SAL 0x0b0 -+#define PCIX0_PIM2SA PCIX0_PIM2SAL -+#define PCIX0_PIM2LAL 0x0b4 -+#define PCIX0_PIM2LAH 0x0b8 -+#define PCIX0_OMCAPID 0x0c0 -+#define PCIX0_OMNIPTR 0x0c1 -+#define PCIX0_OMMC 0x0c2 -+#define PCIX0_OMMA 0x0c4 -+#define PCIX0_OMMUA 0x0c8 -+#define PCIX0_OMMDATA 0x0cc -+#define PCIX0_OMMEOI 0x0ce -+#define PCIX0_PMCAPID 0x0d0 -+#define PCIX0_PMNIPTR 0x0d1 -+#define PCIX0_PMC 0x0d2 -+#define PCIX0_PMCSR 0x0d4 -+#define PCIX0_PMCSRBSE 0x0d6 -+#define PCIX0_PMDATA 0x0d7 -+#define PCIX0_PMSCRR 0x0d8 -+#define PCIX0_CAPID 0x0dc -+#define PCIX0_NIPTR 0x0dd -+#define PCIX0_CMD 0x0de -+#define PCIX0_STS 0x0e0 -+#define PCIX0_IDR 0x0e4 -+#define PCIX0_CID 0x0e8 -+#define PCIX0_RID 0x0ec -+#define PCIX0_PIM0SAH 0x0f8 -+#define PCIX0_PIM2SAH 0x0fc -+#define PCIX0_MSGIL 0x100 -+#define PCIX0_MSGIH 0x104 -+#define PCIX0_MSGOL 0x108 -+#define PCIX0_MSGOH 0x10c -+#define PCIX0_IM 0x1f8 -+ -+/* -+ * 4xx PCI bridge register definitions -+ */ -+#define PCIL0_PMM0LA 0x00 -+#define PCIL0_PMM0MA 0x04 -+#define PCIL0_PMM0PCILA 0x08 -+#define PCIL0_PMM0PCIHA 0x0c -+#define PCIL0_PMM1LA 0x10 -+#define PCIL0_PMM1MA 0x14 -+#define PCIL0_PMM1PCILA 0x18 -+#define PCIL0_PMM1PCIHA 0x1c -+#define PCIL0_PMM2LA 0x20 -+#define PCIL0_PMM2MA 0x24 -+#define PCIL0_PMM2PCILA 0x28 -+#define PCIL0_PMM2PCIHA 0x2c -+#define PCIL0_PTM1MS 0x30 -+#define PCIL0_PTM1LA 0x34 -+#define PCIL0_PTM2MS 0x38 -+#define PCIL0_PTM2LA 0x3c -+ -+/* -+ * 4xx PCIe bridge register definitions -+ */ -+ -+/* DCR offsets */ -+#define DCRO_PEGPL_CFGBAH 0x00 -+#define DCRO_PEGPL_CFGBAL 0x01 -+#define DCRO_PEGPL_CFGMSK 0x02 -+#define DCRO_PEGPL_MSGBAH 0x03 -+#define DCRO_PEGPL_MSGBAL 0x04 -+#define DCRO_PEGPL_MSGMSK 0x05 -+#define DCRO_PEGPL_OMR1BAH 0x06 -+#define DCRO_PEGPL_OMR1BAL 0x07 -+#define DCRO_PEGPL_OMR1MSKH 0x08 -+#define DCRO_PEGPL_OMR1MSKL 0x09 -+#define DCRO_PEGPL_OMR2BAH 0x0a -+#define DCRO_PEGPL_OMR2BAL 0x0b -+#define DCRO_PEGPL_OMR2MSKH 0x0c -+#define DCRO_PEGPL_OMR2MSKL 0x0d -+#define DCRO_PEGPL_OMR3BAH 0x0e -+#define DCRO_PEGPL_OMR3BAL 0x0f -+#define DCRO_PEGPL_OMR3MSKH 0x10 -+#define DCRO_PEGPL_OMR3MSKL 0x11 -+#define DCRO_PEGPL_REGBAH 0x12 -+#define DCRO_PEGPL_REGBAL 0x13 -+#define DCRO_PEGPL_REGMSK 0x14 -+#define DCRO_PEGPL_SPECIAL 0x15 -+#define DCRO_PEGPL_CFG 0x16 -+#define DCRO_PEGPL_ESR 0x17 -+#define DCRO_PEGPL_EARH 0x18 -+#define DCRO_PEGPL_EARL 0x19 -+#define DCRO_PEGPL_EATR 0x1a -+ -+/* DMER mask */ -+#define GPL_DMER_MASK_DISA 0x02000000 -+ -+/* -+ * System DCRs (SDRs) -+ */ -+#define PESDR0_PLLLCT1 0x03a0 -+#define PESDR0_PLLLCT2 0x03a1 -+#define PESDR0_PLLLCT3 0x03a2 -+ -+/* -+ * 440SPe additional DCRs -+ */ -+#define PESDR0_440SPE_UTLSET1 0x0300 -+#define PESDR0_440SPE_UTLSET2 0x0301 -+#define PESDR0_440SPE_DLPSET 0x0302 -+#define PESDR0_440SPE_LOOP 0x0303 -+#define PESDR0_440SPE_RCSSET 0x0304 -+#define PESDR0_440SPE_RCSSTS 0x0305 -+#define PESDR0_440SPE_HSSL0SET1 0x0306 -+#define PESDR0_440SPE_HSSL0SET2 0x0307 -+#define PESDR0_440SPE_HSSL0STS 0x0308 -+#define PESDR0_440SPE_HSSL1SET1 0x0309 -+#define PESDR0_440SPE_HSSL1SET2 0x030a -+#define PESDR0_440SPE_HSSL1STS 0x030b -+#define PESDR0_440SPE_HSSL2SET1 0x030c -+#define PESDR0_440SPE_HSSL2SET2 0x030d -+#define PESDR0_440SPE_HSSL2STS 0x030e -+#define PESDR0_440SPE_HSSL3SET1 0x030f -+#define PESDR0_440SPE_HSSL3SET2 0x0310 -+#define PESDR0_440SPE_HSSL3STS 0x0311 -+#define PESDR0_440SPE_HSSL4SET1 0x0312 -+#define PESDR0_440SPE_HSSL4SET2 0x0313 -+#define PESDR0_440SPE_HSSL4STS 0x0314 -+#define PESDR0_440SPE_HSSL5SET1 0x0315 -+#define PESDR0_440SPE_HSSL5SET2 0x0316 -+#define PESDR0_440SPE_HSSL5STS 0x0317 -+#define PESDR0_440SPE_HSSL6SET1 0x0318 -+#define PESDR0_440SPE_HSSL6SET2 0x0319 -+#define PESDR0_440SPE_HSSL6STS 0x031a -+#define PESDR0_440SPE_HSSL7SET1 0x031b -+#define PESDR0_440SPE_HSSL7SET2 0x031c -+#define PESDR0_440SPE_HSSL7STS 0x031d -+#define PESDR0_440SPE_HSSCTLSET 0x031e -+#define PESDR0_440SPE_LANE_ABCD 0x031f -+#define PESDR0_440SPE_LANE_EFGH 0x0320 -+ -+#define PESDR1_440SPE_UTLSET1 0x0340 -+#define PESDR1_440SPE_UTLSET2 0x0341 -+#define PESDR1_440SPE_DLPSET 0x0342 -+#define PESDR1_440SPE_LOOP 0x0343 -+#define PESDR1_440SPE_RCSSET 0x0344 -+#define PESDR1_440SPE_RCSSTS 0x0345 -+#define PESDR1_440SPE_HSSL0SET1 0x0346 -+#define PESDR1_440SPE_HSSL0SET2 0x0347 -+#define PESDR1_440SPE_HSSL0STS 0x0348 -+#define PESDR1_440SPE_HSSL1SET1 0x0349 -+#define PESDR1_440SPE_HSSL1SET2 0x034a -+#define PESDR1_440SPE_HSSL1STS 0x034b -+#define PESDR1_440SPE_HSSL2SET1 0x034c -+#define PESDR1_440SPE_HSSL2SET2 0x034d -+#define PESDR1_440SPE_HSSL2STS 0x034e -+#define PESDR1_440SPE_HSSL3SET1 0x034f -+#define PESDR1_440SPE_HSSL3SET2 0x0350 -+#define PESDR1_440SPE_HSSL3STS 0x0351 -+#define PESDR1_440SPE_HSSCTLSET 0x0352 -+#define PESDR1_440SPE_LANE_ABCD 0x0353 -+ -+#define PESDR2_440SPE_UTLSET1 0x0370 -+#define PESDR2_440SPE_UTLSET2 0x0371 -+#define PESDR2_440SPE_DLPSET 0x0372 -+#define PESDR2_440SPE_LOOP 0x0373 -+#define PESDR2_440SPE_RCSSET 0x0374 -+#define PESDR2_440SPE_RCSSTS 0x0375 -+#define PESDR2_440SPE_HSSL0SET1 0x0376 -+#define PESDR2_440SPE_HSSL0SET2 0x0377 -+#define PESDR2_440SPE_HSSL0STS 0x0378 -+#define PESDR2_440SPE_HSSL1SET1 0x0379 -+#define PESDR2_440SPE_HSSL1SET2 0x037a -+#define PESDR2_440SPE_HSSL1STS 0x037b -+#define PESDR2_440SPE_HSSL2SET1 0x037c -+#define PESDR2_440SPE_HSSL2SET2 0x037d -+#define PESDR2_440SPE_HSSL2STS 0x037e -+#define PESDR2_440SPE_HSSL3SET1 0x037f -+#define PESDR2_440SPE_HSSL3SET2 0x0380 -+#define PESDR2_440SPE_HSSL3STS 0x0381 -+#define PESDR2_440SPE_HSSCTLSET 0x0382 -+#define PESDR2_440SPE_LANE_ABCD 0x0383 -+ -+/* -+ * 405EX additional DCRs -+ */ -+#define PESDR0_405EX_UTLSET1 0x0400 -+#define PESDR0_405EX_UTLSET2 0x0401 -+#define PESDR0_405EX_DLPSET 0x0402 -+#define PESDR0_405EX_LOOP 0x0403 -+#define PESDR0_405EX_RCSSET 0x0404 -+#define PESDR0_405EX_RCSSTS 0x0405 -+#define PESDR0_405EX_PHYSET1 0x0406 -+#define PESDR0_405EX_PHYSET2 0x0407 -+#define PESDR0_405EX_BIST 0x0408 -+#define PESDR0_405EX_LPB 0x040B -+#define PESDR0_405EX_PHYSTA 0x040C -+ -+#define PESDR1_405EX_UTLSET1 0x0440 -+#define PESDR1_405EX_UTLSET2 0x0441 -+#define PESDR1_405EX_DLPSET 0x0442 -+#define PESDR1_405EX_LOOP 0x0443 -+#define PESDR1_405EX_RCSSET 0x0444 -+#define PESDR1_405EX_RCSSTS 0x0445 -+#define PESDR1_405EX_PHYSET1 0x0446 -+#define PESDR1_405EX_PHYSET2 0x0447 -+#define PESDR1_405EX_BIST 0x0448 -+#define PESDR1_405EX_LPB 0x044B -+#define PESDR1_405EX_PHYSTA 0x044C -+ -+/* -+ * Of the above, some are common offsets from the base -+ */ -+#define PESDRn_UTLSET1 0x00 -+#define PESDRn_UTLSET2 0x01 -+#define PESDRn_DLPSET 0x02 -+#define PESDRn_LOOP 0x03 -+#define PESDRn_RCSSET 0x04 -+#define PESDRn_RCSSTS 0x05 -+ -+/* 440spe only */ -+#define PESDRn_440SPE_HSSL0SET1 0x06 -+#define PESDRn_440SPE_HSSL0SET2 0x07 -+#define PESDRn_440SPE_HSSL0STS 0x08 -+#define PESDRn_440SPE_HSSL1SET1 0x09 -+#define PESDRn_440SPE_HSSL1SET2 0x0a -+#define PESDRn_440SPE_HSSL1STS 0x0b -+#define PESDRn_440SPE_HSSL2SET1 0x0c -+#define PESDRn_440SPE_HSSL2SET2 0x0d -+#define PESDRn_440SPE_HSSL2STS 0x0e -+#define PESDRn_440SPE_HSSL3SET1 0x0f -+#define PESDRn_440SPE_HSSL3SET2 0x10 -+#define PESDRn_440SPE_HSSL3STS 0x11 -+ -+/* 440spe port 0 only */ -+#define PESDRn_440SPE_HSSL4SET1 0x12 -+#define PESDRn_440SPE_HSSL4SET2 0x13 -+#define PESDRn_440SPE_HSSL4STS 0x14 -+#define PESDRn_440SPE_HSSL5SET1 0x15 -+#define PESDRn_440SPE_HSSL5SET2 0x16 -+#define PESDRn_440SPE_HSSL5STS 0x17 -+#define PESDRn_440SPE_HSSL6SET1 0x18 -+#define PESDRn_440SPE_HSSL6SET2 0x19 -+#define PESDRn_440SPE_HSSL6STS 0x1a -+#define PESDRn_440SPE_HSSL7SET1 0x1b -+#define PESDRn_440SPE_HSSL7SET2 0x1c -+#define PESDRn_440SPE_HSSL7STS 0x1d -+ -+/* 405ex only */ -+#define PESDRn_405EX_PHYSET1 0x06 -+#define PESDRn_405EX_PHYSET2 0x07 -+#define PESDRn_405EX_PHYSTA 0x0c -+ -+/* -+ * UTL register offsets -+ */ -+#define PEUTL_PBCTL 0x00 -+#define PEUTL_PBBSZ 0x20 -+#define PEUTL_OPDBSZ 0x68 -+#define PEUTL_IPHBSZ 0x70 -+#define PEUTL_IPDBSZ 0x78 -+#define PEUTL_OUTTR 0x90 -+#define PEUTL_INTR 0x98 -+#define PEUTL_PCTL 0xa0 -+#define PEUTL_RCSTA 0xB0 -+#define PEUTL_RCIRQEN 0xb8 -+ -+/* -+ * Config space register offsets -+ */ -+#define PECFG_ECRTCTL 0x074 -+ -+#define PECFG_BAR0LMPA 0x210 -+#define PECFG_BAR0HMPA 0x214 -+#define PECFG_BAR1MPA 0x218 -+#define PECFG_BAR2LMPA 0x220 -+#define PECFG_BAR2HMPA 0x224 -+ -+#define PECFG_PIMEN 0x33c -+#define PECFG_PIM0LAL 0x340 -+#define PECFG_PIM0LAH 0x344 -+#define PECFG_PIM1LAL 0x348 -+#define PECFG_PIM1LAH 0x34c -+#define PECFG_PIM01SAL 0x350 -+#define PECFG_PIM01SAH 0x354 -+ -+#define PECFG_POM0LAL 0x380 -+#define PECFG_POM0LAH 0x384 -+#define PECFG_POM1LAL 0x388 -+#define PECFG_POM1LAH 0x38c -+#define PECFG_POM2LAL 0x390 -+#define PECFG_POM2LAH 0x394 -+ -+ -+enum -+{ -+ PTYPE_ENDPOINT = 0x0, -+ PTYPE_LEGACY_ENDPOINT = 0x1, -+ PTYPE_ROOT_PORT = 0x4, -+ -+ LNKW_X1 = 0x1, -+ LNKW_X4 = 0x4, -+ LNKW_X8 = 0x8 -+}; -+ -+ -+#endif /* __PPC4XX_PCI_H__ */ ---- a/arch/powerpc/sysdev/qe_lib/Kconfig -+++ b/arch/powerpc/sysdev/qe_lib/Kconfig -@@ -4,7 +4,7 @@ - - config UCC_SLOW - bool -- default n -+ default y if SERIAL_QE - help - This option provides qe_lib support to UCC slow - protocols: UART, BISYNC, QMC ---- a/arch/powerpc/sysdev/qe_lib/qe.c -+++ b/arch/powerpc/sysdev/qe_lib/qe.c -@@ -25,6 +25,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -167,19 +168,20 @@ unsigned int get_brg_clk(void) - - /* Program the BRG to the given sampling rate and multiplier - * -- * @brg: the BRG, 1-16 -+ * @brg: the BRG, QE_BRG1 - QE_BRG16 - * @rate: the desired sampling rate - * @multiplier: corresponds to the value programmed in GUMR_L[RDCR] or - * GUMR_L[TDCR]. E.g., if this BRG is the RX clock, and GUMR_L[RDCR]=01, - * then 'multiplier' should be 8. -- * -- * Also note that the value programmed into the BRGC register must be even. - */ --void qe_setbrg(unsigned int brg, unsigned int rate, unsigned int multiplier) -+int qe_setbrg(enum qe_clock brg, unsigned int rate, unsigned int multiplier) - { - u32 divisor, tempval; - u32 div16 = 0; - -+ if ((brg < QE_BRG1) || (brg > QE_BRG16)) -+ return -EINVAL; -+ - divisor = get_brg_clk() / (rate * multiplier); - - if (divisor > QE_BRGC_DIVISOR_MAX + 1) { -@@ -196,8 +198,43 @@ void qe_setbrg(unsigned int brg, unsigne - tempval = ((divisor - 1) << QE_BRGC_DIVISOR_SHIFT) | - QE_BRGC_ENABLE | div16; - -- out_be32(&qe_immr->brg.brgc[brg - 1], tempval); -+ out_be32(&qe_immr->brg.brgc[brg - QE_BRG1], tempval); -+ -+ return 0; -+} -+EXPORT_SYMBOL(qe_setbrg); -+ -+/* Convert a string to a QE clock source enum -+ * -+ * This function takes a string, typically from a property in the device -+ * tree, and returns the corresponding "enum qe_clock" value. -+*/ -+enum qe_clock qe_clock_source(const char *source) -+{ -+ unsigned int i; -+ -+ if (strcasecmp(source, "none") == 0) -+ return QE_CLK_NONE; -+ -+ if (strncasecmp(source, "brg", 3) == 0) { -+ i = simple_strtoul(source + 3, NULL, 10); -+ if ((i >= 1) && (i <= 16)) -+ return (QE_BRG1 - 1) + i; -+ else -+ return QE_CLK_DUMMY; -+ } -+ -+ if (strncasecmp(source, "clk", 3) == 0) { -+ i = simple_strtoul(source + 3, NULL, 10); -+ if ((i >= 1) && (i <= 24)) -+ return (QE_CLK1 - 1) + i; -+ else -+ return QE_CLK_DUMMY; -+ } -+ -+ return QE_CLK_DUMMY; - } -+EXPORT_SYMBOL(qe_clock_source); - - /* Initialize SNUMs (thread serial numbers) according to - * QE Module Control chapter, SNUM table -@@ -358,3 +395,249 @@ void *qe_muram_addr(unsigned long offset - return (void *)&qe_immr->muram[offset]; - } - EXPORT_SYMBOL(qe_muram_addr); -+ -+/* The maximum number of RISCs we support */ -+#define MAX_QE_RISC 2 -+ -+/* Firmware information stored here for qe_get_firmware_info() */ -+static struct qe_firmware_info qe_firmware_info; -+ -+/* -+ * Set to 1 if QE firmware has been uploaded, and therefore -+ * qe_firmware_info contains valid data. -+ */ -+static int qe_firmware_uploaded; -+ -+/* -+ * Upload a QE microcode -+ * -+ * This function is a worker function for qe_upload_firmware(). It does -+ * the actual uploading of the microcode. -+ */ -+static void qe_upload_microcode(const void *base, -+ const struct qe_microcode *ucode) -+{ -+ const __be32 *code = base + be32_to_cpu(ucode->code_offset); -+ unsigned int i; -+ -+ if (ucode->major || ucode->minor || ucode->revision) -+ printk(KERN_INFO "qe-firmware: " -+ "uploading microcode '%s' version %u.%u.%u\n", -+ ucode->id, ucode->major, ucode->minor, ucode->revision); -+ else -+ printk(KERN_INFO "qe-firmware: " -+ "uploading microcode '%s'\n", ucode->id); -+ -+ /* Use auto-increment */ -+ out_be32(&qe_immr->iram.iadd, be32_to_cpu(ucode->iram_offset) | -+ QE_IRAM_IADD_AIE | QE_IRAM_IADD_BADDR); -+ -+ for (i = 0; i < be32_to_cpu(ucode->count); i++) -+ out_be32(&qe_immr->iram.idata, be32_to_cpu(code[i])); -+} -+ -+/* -+ * Upload a microcode to the I-RAM at a specific address. -+ * -+ * See Documentation/powerpc/qe-firmware.txt for information on QE microcode -+ * uploading. -+ * -+ * Currently, only version 1 is supported, so the 'version' field must be -+ * set to 1. -+ * -+ * The SOC model and revision are not validated, they are only displayed for -+ * informational purposes. -+ * -+ * 'calc_size' is the calculated size, in bytes, of the firmware structure and -+ * all of the microcode structures, minus the CRC. -+ * -+ * 'length' is the size that the structure says it is, including the CRC. -+ */ -+int qe_upload_firmware(const struct qe_firmware *firmware) -+{ -+ unsigned int i; -+ unsigned int j; -+ u32 crc; -+ size_t calc_size = sizeof(struct qe_firmware); -+ size_t length; -+ const struct qe_header *hdr; -+ -+ if (!firmware) { -+ printk(KERN_ERR "qe-firmware: invalid pointer\n"); -+ return -EINVAL; -+ } -+ -+ hdr = &firmware->header; -+ length = be32_to_cpu(hdr->length); -+ -+ /* Check the magic */ -+ if ((hdr->magic[0] != 'Q') || (hdr->magic[1] != 'E') || -+ (hdr->magic[2] != 'F')) { -+ printk(KERN_ERR "qe-firmware: not a microcode\n"); -+ return -EPERM; -+ } -+ -+ /* Check the version */ -+ if (hdr->version != 1) { -+ printk(KERN_ERR "qe-firmware: unsupported version\n"); -+ return -EPERM; -+ } -+ -+ /* Validate some of the fields */ -+ if ((firmware->count < 1) || (firmware->count >= MAX_QE_RISC)) { -+ printk(KERN_ERR "qe-firmware: invalid data\n"); -+ return -EINVAL; -+ } -+ -+ /* Validate the length and check if there's a CRC */ -+ calc_size += (firmware->count - 1) * sizeof(struct qe_microcode); -+ -+ for (i = 0; i < firmware->count; i++) -+ /* -+ * For situations where the second RISC uses the same microcode -+ * as the first, the 'code_offset' and 'count' fields will be -+ * zero, so it's okay to add those. -+ */ -+ calc_size += sizeof(__be32) * -+ be32_to_cpu(firmware->microcode[i].count); -+ -+ /* Validate the length */ -+ if (length != calc_size + sizeof(__be32)) { -+ printk(KERN_ERR "qe-firmware: invalid length\n"); -+ return -EPERM; -+ } -+ -+ /* Validate the CRC */ -+ crc = be32_to_cpu(*(__be32 *)((void *)firmware + calc_size)); -+ if (crc != crc32(0, firmware, calc_size)) { -+ printk(KERN_ERR "qe-firmware: firmware CRC is invalid\n"); -+ return -EIO; -+ } -+ -+ /* -+ * If the microcode calls for it, split the I-RAM. -+ */ -+ if (!firmware->split) -+ setbits16(&qe_immr->cp.cercr, QE_CP_CERCR_CIR); -+ -+ if (firmware->soc.model) -+ printk(KERN_INFO -+ "qe-firmware: firmware '%s' for %u V%u.%u\n", -+ firmware->id, be16_to_cpu(firmware->soc.model), -+ firmware->soc.major, firmware->soc.minor); -+ else -+ printk(KERN_INFO "qe-firmware: firmware '%s'\n", -+ firmware->id); -+ -+ /* -+ * The QE only supports one microcode per RISC, so clear out all the -+ * saved microcode information and put in the new. -+ */ -+ memset(&qe_firmware_info, 0, sizeof(qe_firmware_info)); -+ strcpy(qe_firmware_info.id, firmware->id); -+ qe_firmware_info.extended_modes = firmware->extended_modes; -+ memcpy(qe_firmware_info.vtraps, firmware->vtraps, -+ sizeof(firmware->vtraps)); -+ -+ /* Loop through each microcode. */ -+ for (i = 0; i < firmware->count; i++) { -+ const struct qe_microcode *ucode = &firmware->microcode[i]; -+ -+ /* Upload a microcode if it's present */ -+ if (ucode->code_offset) -+ qe_upload_microcode(firmware, ucode); -+ -+ /* Program the traps for this processor */ -+ for (j = 0; j < 16; j++) { -+ u32 trap = be32_to_cpu(ucode->traps[j]); -+ -+ if (trap) -+ out_be32(&qe_immr->rsp[i].tibcr[j], trap); -+ } -+ -+ /* Enable traps */ -+ out_be32(&qe_immr->rsp[i].eccr, be32_to_cpu(ucode->eccr)); -+ } -+ -+ qe_firmware_uploaded = 1; -+ -+ return 0; -+} -+EXPORT_SYMBOL(qe_upload_firmware); -+ -+/* -+ * Get info on the currently-loaded firmware -+ * -+ * This function also checks the device tree to see if the boot loader has -+ * uploaded a firmware already. -+ */ -+struct qe_firmware_info *qe_get_firmware_info(void) -+{ -+ static int initialized; -+ struct property *prop; -+ struct device_node *qe; -+ struct device_node *fw = NULL; -+ const char *sprop; -+ unsigned int i; -+ -+ /* -+ * If we haven't checked yet, and a driver hasn't uploaded a firmware -+ * yet, then check the device tree for information. -+ */ -+ if (initialized || qe_firmware_uploaded) -+ return NULL; -+ -+ initialized = 1; -+ -+ /* -+ * Newer device trees have an "fsl,qe" compatible property for the QE -+ * node, but we still need to support older device trees. -+ */ -+ qe = of_find_compatible_node(NULL, NULL, "fsl,qe"); -+ if (!qe) { -+ qe = of_find_node_by_type(NULL, "qe"); -+ if (!qe) -+ return NULL; -+ } -+ -+ /* Find the 'firmware' child node */ -+ for_each_child_of_node(qe, fw) { -+ if (strcmp(fw->name, "firmware") == 0) -+ break; -+ } -+ -+ of_node_put(qe); -+ -+ /* Did we find the 'firmware' node? */ -+ if (!fw) -+ return NULL; -+ -+ qe_firmware_uploaded = 1; -+ -+ /* Copy the data into qe_firmware_info*/ -+ sprop = of_get_property(fw, "id", NULL); -+ if (sprop) -+ strncpy(qe_firmware_info.id, sprop, -+ sizeof(qe_firmware_info.id) - 1); -+ -+ prop = of_find_property(fw, "extended-modes", NULL); -+ if (prop && (prop->length == sizeof(u64))) { -+ const u64 *iprop = prop->value; -+ -+ qe_firmware_info.extended_modes = *iprop; -+ } -+ -+ prop = of_find_property(fw, "virtual-traps", NULL); -+ if (prop && (prop->length == 32)) { -+ const u32 *iprop = prop->value; -+ -+ for (i = 0; i < ARRAY_SIZE(qe_firmware_info.vtraps); i++) -+ qe_firmware_info.vtraps[i] = iprop[i]; -+ } -+ -+ of_node_put(fw); -+ -+ return &qe_firmware_info; -+} -+EXPORT_SYMBOL(qe_get_firmware_info); -+ ---- a/arch/powerpc/sysdev/qe_lib/ucc_slow.c -+++ b/arch/powerpc/sysdev/qe_lib/ucc_slow.c -@@ -19,6 +19,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -41,6 +42,7 @@ u32 ucc_slow_get_qe_cr_subblock(int uccs - default: return QE_CR_SUBBLOCK_INVALID; - } - } -+EXPORT_SYMBOL(ucc_slow_get_qe_cr_subblock); - - void ucc_slow_poll_transmitter_now(struct ucc_slow_private * uccs) - { -@@ -56,6 +58,7 @@ void ucc_slow_graceful_stop_tx(struct uc - qe_issue_cmd(QE_GRACEFUL_STOP_TX, id, - QE_CR_PROTOCOL_UNSPECIFIED, 0); - } -+EXPORT_SYMBOL(ucc_slow_graceful_stop_tx); - - void ucc_slow_stop_tx(struct ucc_slow_private * uccs) - { -@@ -65,6 +68,7 @@ void ucc_slow_stop_tx(struct ucc_slow_pr - id = ucc_slow_get_qe_cr_subblock(us_info->ucc_num); - qe_issue_cmd(QE_STOP_TX, id, QE_CR_PROTOCOL_UNSPECIFIED, 0); - } -+EXPORT_SYMBOL(ucc_slow_stop_tx); - - void ucc_slow_restart_tx(struct ucc_slow_private * uccs) - { -@@ -74,6 +78,7 @@ void ucc_slow_restart_tx(struct ucc_slow - id = ucc_slow_get_qe_cr_subblock(us_info->ucc_num); - qe_issue_cmd(QE_RESTART_TX, id, QE_CR_PROTOCOL_UNSPECIFIED, 0); - } -+EXPORT_SYMBOL(ucc_slow_restart_tx); - - void ucc_slow_enable(struct ucc_slow_private * uccs, enum comm_dir mode) - { -@@ -94,6 +99,7 @@ void ucc_slow_enable(struct ucc_slow_pri - } - out_be32(&us_regs->gumr_l, gumr_l); - } -+EXPORT_SYMBOL(ucc_slow_enable); - - void ucc_slow_disable(struct ucc_slow_private * uccs, enum comm_dir mode) - { -@@ -114,6 +120,7 @@ void ucc_slow_disable(struct ucc_slow_pr - } - out_be32(&us_regs->gumr_l, gumr_l); - } -+EXPORT_SYMBOL(ucc_slow_disable); - - /* Initialize the UCC for Slow operations - * -@@ -347,6 +354,7 @@ int ucc_slow_init(struct ucc_slow_info * - *uccs_ret = uccs; - return 0; - } -+EXPORT_SYMBOL(ucc_slow_init); - - void ucc_slow_free(struct ucc_slow_private * uccs) - { -@@ -366,5 +374,5 @@ void ucc_slow_free(struct ucc_slow_priva - - kfree(uccs); - } -- -+EXPORT_SYMBOL(ucc_slow_free); - ---- a/arch/powerpc/sysdev/tsi108_dev.c -+++ b/arch/powerpc/sysdev/tsi108_dev.c -@@ -66,14 +66,12 @@ EXPORT_SYMBOL(get_vir_csrbase); - static int __init tsi108_eth_of_init(void) - { - struct device_node *np; -- unsigned int i; -+ unsigned int i = 0; - struct platform_device *tsi_eth_dev; - struct resource res; - int ret; - -- for (np = NULL, i = 0; -- (np = of_find_compatible_node(np, "network", "tsi108-ethernet")) != NULL; -- i++) { -+ for_each_compatible_node(np, "network", "tsi108-ethernet") { - struct resource r[2]; - struct device_node *phy, *mdio; - hw_info tsi_eth_data; -@@ -98,7 +96,7 @@ static int __init tsi108_eth_of_init(voi - __FUNCTION__,r[1].name, r[1].start, r[1].end); - - tsi_eth_dev = -- platform_device_register_simple("tsi-ethernet", i, &r[0], -+ platform_device_register_simple("tsi-ethernet", i++, &r[0], - 1); - - if (IS_ERR(tsi_eth_dev)) { -@@ -154,6 +152,7 @@ static int __init tsi108_eth_of_init(voi - unreg: - platform_device_unregister(tsi_eth_dev); - err: -+ of_node_put(np); - return ret; - } - ---- a/arch/powerpc/sysdev/uic.c -+++ b/arch/powerpc/sysdev/uic.c -@@ -53,21 +53,23 @@ struct uic { - - /* The remapper for this UIC */ - struct irq_host *irqhost; -- -- /* For secondary UICs, the cascade interrupt's irqaction */ -- struct irqaction cascade; - }; - - static void uic_unmask_irq(unsigned int virq) - { -+ struct irq_desc *desc = get_irq_desc(virq); - struct uic *uic = get_irq_chip_data(virq); - unsigned int src = uic_irq_to_hw(virq); - unsigned long flags; -- u32 er; -+ u32 er, sr; - -+ sr = 1 << (31-src); - spin_lock_irqsave(&uic->lock, flags); -+ /* ack level-triggered interrupts here */ -+ if (desc->status & IRQ_LEVEL) -+ mtdcr(uic->dcrbase + UIC_SR, sr); - er = mfdcr(uic->dcrbase + UIC_ER); -- er |= 1 << (31 - src); -+ er |= sr; - mtdcr(uic->dcrbase + UIC_ER, er); - spin_unlock_irqrestore(&uic->lock, flags); - } -@@ -99,6 +101,7 @@ static void uic_ack_irq(unsigned int vir - - static void uic_mask_ack_irq(unsigned int virq) - { -+ struct irq_desc *desc = get_irq_desc(virq); - struct uic *uic = get_irq_chip_data(virq); - unsigned int src = uic_irq_to_hw(virq); - unsigned long flags; -@@ -109,7 +112,16 @@ static void uic_mask_ack_irq(unsigned in - er = mfdcr(uic->dcrbase + UIC_ER); - er &= ~sr; - mtdcr(uic->dcrbase + UIC_ER, er); -- mtdcr(uic->dcrbase + UIC_SR, sr); -+ /* On the UIC, acking (i.e. clearing the SR bit) -+ * a level irq will have no effect if the interrupt -+ * is still asserted by the device, even if -+ * the interrupt is already masked. Therefore -+ * we only ack the egde interrupts here, while -+ * level interrupts are ack'ed after the actual -+ * isr call in the uic_unmask_irq() -+ */ -+ if (!(desc->status & IRQ_LEVEL)) -+ mtdcr(uic->dcrbase + UIC_SR, sr); - spin_unlock_irqrestore(&uic->lock, flags); - } - -@@ -173,64 +185,6 @@ static struct irq_chip uic_irq_chip = { - .set_type = uic_set_irq_type, - }; - --/** -- * handle_uic_irq - irq flow handler for UIC -- * @irq: the interrupt number -- * @desc: the interrupt description structure for this irq -- * -- * This is modified version of the generic handle_level_irq() suitable -- * for the UIC. On the UIC, acking (i.e. clearing the SR bit) a level -- * irq will have no effect if the interrupt is still asserted by the -- * device, even if the interrupt is already masked. Therefore, unlike -- * the standard handle_level_irq(), we must ack the interrupt *after* -- * invoking the ISR (which should have de-asserted the interrupt in -- * the external source). For edge interrupts we ack at the beginning -- * instead of the end, to keep the window in which we can miss an -- * interrupt as small as possible. -- */ --void fastcall handle_uic_irq(unsigned int irq, struct irq_desc *desc) --{ -- unsigned int cpu = smp_processor_id(); -- struct irqaction *action; -- irqreturn_t action_ret; -- -- spin_lock(&desc->lock); -- if (desc->status & IRQ_LEVEL) -- desc->chip->mask(irq); -- else -- desc->chip->mask_ack(irq); -- -- if (unlikely(desc->status & IRQ_INPROGRESS)) -- goto out_unlock; -- desc->status &= ~(IRQ_REPLAY | IRQ_WAITING); -- kstat_cpu(cpu).irqs[irq]++; -- -- /* -- * If its disabled or no action available -- * keep it masked and get out of here -- */ -- action = desc->action; -- if (unlikely(!action || (desc->status & IRQ_DISABLED))) { -- desc->status |= IRQ_PENDING; -- goto out_unlock; -- } -- -- desc->status |= IRQ_INPROGRESS; -- desc->status &= ~IRQ_PENDING; -- spin_unlock(&desc->lock); -- -- action_ret = handle_IRQ_event(irq, action); -- -- spin_lock(&desc->lock); -- desc->status &= ~IRQ_INPROGRESS; -- if (desc->status & IRQ_LEVEL) -- desc->chip->ack(irq); -- if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask) -- desc->chip->unmask(irq); --out_unlock: -- spin_unlock(&desc->lock); --} -- - static int uic_host_map(struct irq_host *h, unsigned int virq, - irq_hw_number_t hw) - { -@@ -239,7 +193,7 @@ static int uic_host_map(struct irq_host - set_irq_chip_data(virq, uic); - /* Despite the name, handle_level_irq() works for both level - * and edge irqs on UIC. FIXME: check this is correct */ -- set_irq_chip_and_handler(virq, &uic_irq_chip, handle_uic_irq); -+ set_irq_chip_and_handler(virq, &uic_irq_chip, handle_level_irq); - - /* Set default irq type */ - set_irq_type(virq, IRQ_TYPE_NONE); -@@ -264,23 +218,36 @@ static struct irq_host_ops uic_host_ops - .xlate = uic_host_xlate, - }; - --irqreturn_t uic_cascade(int virq, void *data) -+void uic_irq_cascade(unsigned int virq, struct irq_desc *desc) - { -- struct uic *uic = data; -+ struct uic *uic = get_irq_data(virq); - u32 msr; - int src; - int subvirq; - -+ spin_lock(&desc->lock); -+ if (desc->status & IRQ_LEVEL) -+ desc->chip->mask(virq); -+ else -+ desc->chip->mask_ack(virq); -+ spin_unlock(&desc->lock); -+ - msr = mfdcr(uic->dcrbase + UIC_MSR); - if (!msr) /* spurious interrupt */ -- return IRQ_HANDLED; -+ goto uic_irq_ret; - - src = 32 - ffs(msr); - - subvirq = irq_linear_revmap(uic->irqhost, src); - generic_handle_irq(subvirq); - -- return IRQ_HANDLED; -+uic_irq_ret: -+ spin_lock(&desc->lock); -+ if (desc->status & IRQ_LEVEL) -+ desc->chip->ack(virq); -+ if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask) -+ desc->chip->unmask(virq); -+ spin_unlock(&desc->lock); - } - - static struct uic * __init uic_init_one(struct device_node *node) -@@ -342,33 +309,27 @@ void __init uic_init_tree(void) - const u32 *interrupts; - - /* First locate and initialize the top-level UIC */ -- -- np = of_find_compatible_node(NULL, NULL, "ibm,uic"); -- while (np) { -+ for_each_compatible_node(np, NULL, "ibm,uic") { - interrupts = of_get_property(np, "interrupts", NULL); -- if (! interrupts) -+ if (!interrupts) - break; -- -- np = of_find_compatible_node(np, NULL, "ibm,uic"); - } - - BUG_ON(!np); /* uic_init_tree() assumes there's a UIC as the - * top-level interrupt controller */ - primary_uic = uic_init_one(np); -- if (! primary_uic) -+ if (!primary_uic) - panic("Unable to initialize primary UIC %s\n", np->full_name); - - irq_set_default_host(primary_uic->irqhost); - of_node_put(np); - - /* The scan again for cascaded UICs */ -- np = of_find_compatible_node(NULL, NULL, "ibm,uic"); -- while (np) { -+ for_each_compatible_node(np, NULL, "ibm,uic") { - interrupts = of_get_property(np, "interrupts", NULL); - if (interrupts) { - /* Secondary UIC */ - int cascade_virq; -- int ret; - - uic = uic_init_one(np); - if (! uic) -@@ -377,20 +338,11 @@ void __init uic_init_tree(void) - - cascade_virq = irq_of_parse_and_map(np, 0); - -- uic->cascade.handler = uic_cascade; -- uic->cascade.name = "UIC cascade"; -- uic->cascade.dev_id = uic; -- -- ret = setup_irq(cascade_virq, &uic->cascade); -- if (ret) -- printk(KERN_ERR "Failed to setup_irq(%d) for " -- "UIC%d cascade\n", cascade_virq, -- uic->index); -+ set_irq_data(cascade_virq, uic); -+ set_irq_chained_handler(cascade_virq, uic_irq_cascade); - - /* FIXME: setup critical cascade?? */ - } -- -- np = of_find_compatible_node(np, NULL, "ibm,uic"); - } - } - ---- a/arch/powerpc/sysdev/xilinx_intc.c -+++ b/arch/powerpc/sysdev/xilinx_intc.c -@@ -135,10 +135,16 @@ void __init xilinx_intc_init_tree(void) - struct device_node *np; - - /* find top level interrupt controller */ -- for_each_compatible_node(np, NULL, "xilinx,intc") { -+ for_each_compatible_node(np, NULL, "xlnx,opb-intc-1.00.c") { - if (!of_get_property(np, "interrupts", NULL)) - break; - } -+ if (!np) { -+ for_each_compatible_node(np, NULL, "xlnx,xps-intc-1.00.a") { -+ if (!of_get_property(np, "interrupts", NULL)) -+ break; -+ } -+ } - - /* xilinx interrupt controller needs to be top level */ - BUG_ON(!np); ---- a/arch/powerpc/xmon/setjmp.S -+++ b/arch/powerpc/xmon/setjmp.S -@@ -12,67 +12,6 @@ - #include - #include - --_GLOBAL(xmon_setjmp) -- mflr r0 -- PPC_STL r0,0(r3) -- PPC_STL r1,SZL(r3) -- PPC_STL r2,2*SZL(r3) -- mfcr r0 -- PPC_STL r0,3*SZL(r3) -- PPC_STL r13,4*SZL(r3) -- PPC_STL r14,5*SZL(r3) -- PPC_STL r15,6*SZL(r3) -- PPC_STL r16,7*SZL(r3) -- PPC_STL r17,8*SZL(r3) -- PPC_STL r18,9*SZL(r3) -- PPC_STL r19,10*SZL(r3) -- PPC_STL r20,11*SZL(r3) -- PPC_STL r21,12*SZL(r3) -- PPC_STL r22,13*SZL(r3) -- PPC_STL r23,14*SZL(r3) -- PPC_STL r24,15*SZL(r3) -- PPC_STL r25,16*SZL(r3) -- PPC_STL r26,17*SZL(r3) -- PPC_STL r27,18*SZL(r3) -- PPC_STL r28,19*SZL(r3) -- PPC_STL r29,20*SZL(r3) -- PPC_STL r30,21*SZL(r3) -- PPC_STL r31,22*SZL(r3) -- li r3,0 -- blr -- --_GLOBAL(xmon_longjmp) -- PPC_LCMPI r4,0 -- bne 1f -- li r4,1 --1: PPC_LL r13,4*SZL(r3) -- PPC_LL r14,5*SZL(r3) -- PPC_LL r15,6*SZL(r3) -- PPC_LL r16,7*SZL(r3) -- PPC_LL r17,8*SZL(r3) -- PPC_LL r18,9*SZL(r3) -- PPC_LL r19,10*SZL(r3) -- PPC_LL r20,11*SZL(r3) -- PPC_LL r21,12*SZL(r3) -- PPC_LL r22,13*SZL(r3) -- PPC_LL r23,14*SZL(r3) -- PPC_LL r24,15*SZL(r3) -- PPC_LL r25,16*SZL(r3) -- PPC_LL r26,17*SZL(r3) -- PPC_LL r27,18*SZL(r3) -- PPC_LL r28,19*SZL(r3) -- PPC_LL r29,20*SZL(r3) -- PPC_LL r30,21*SZL(r3) -- PPC_LL r31,22*SZL(r3) -- PPC_LL r0,3*SZL(r3) -- mtcrf 0x38,r0 -- PPC_LL r0,0(r3) -- PPC_LL r1,SZL(r3) -- PPC_LL r2,2*SZL(r3) -- mtlr r0 -- mr r3,r4 -- blr -- - /* - * Grab the register values as they are now. - * This won't do a particularily good job because we really ---- a/arch/powerpc/xmon/xmon.c -+++ b/arch/powerpc/xmon/xmon.c -@@ -40,6 +40,7 @@ - #include - #include - #include -+#include - - #ifdef CONFIG_PPC64 - #include -@@ -71,12 +72,9 @@ static unsigned long ncsum = 4096; - static int termch; - static char tmpstr[128]; - --#define JMP_BUF_LEN 23 - static long bus_error_jmp[JMP_BUF_LEN]; - static int catch_memory_errors; - static long *xmon_fault_jmp[NR_CPUS]; --#define setjmp xmon_setjmp --#define longjmp xmon_longjmp - - /* Breakpoint stuff */ - struct bpt { -@@ -153,13 +151,15 @@ static const char *getvecname(unsigned l - - static int do_spu_cmd(void); - -+#ifdef CONFIG_44x -+static void dump_tlb_44x(void); -+#endif -+ - int xmon_no_auto_backtrace; - - extern void xmon_enter(void); - extern void xmon_leave(void); - --extern long setjmp(long *); --extern void longjmp(long *, long); - extern void xmon_save_regs(struct pt_regs *); - - #ifdef CONFIG_PPC64 -@@ -231,6 +231,9 @@ Commands:\n\ - #ifdef CONFIG_PPC_STD_MMU_32 - " u dump segment registers\n" - #endif -+#ifdef CONFIG_44x -+" u dump TLB\n" -+#endif - " ? help\n" - " zr reboot\n\ - zh halt\n" -@@ -856,6 +859,11 @@ cmds(struct pt_regs *excp) - dump_segments(); - break; - #endif -+#ifdef CONFIG_4xx -+ case 'u': -+ dump_tlb_44x(); -+ break; -+#endif - default: - printf("Unrecognized command: "); - do { -@@ -2527,16 +2535,33 @@ static void xmon_print_symbol(unsigned l - static void dump_slb(void) - { - int i; -- unsigned long tmp; -+ unsigned long esid,vsid,valid; -+ unsigned long llp; - - printf("SLB contents of cpu %x\n", smp_processor_id()); - -- for (i = 0; i < SLB_NUM_ENTRIES; i++) { -- asm volatile("slbmfee %0,%1" : "=r" (tmp) : "r" (i)); -- printf("%02d %016lx ", i, tmp); -- -- asm volatile("slbmfev %0,%1" : "=r" (tmp) : "r" (i)); -- printf("%016lx\n", tmp); -+ for (i = 0; i < mmu_slb_size; i++) { -+ asm volatile("slbmfee %0,%1" : "=r" (esid) : "r" (i)); -+ asm volatile("slbmfev %0,%1" : "=r" (vsid) : "r" (i)); -+ valid = (esid & SLB_ESID_V); -+ if (valid | esid | vsid) { -+ printf("%02d %016lx %016lx", i, esid, vsid); -+ if (valid) { -+ llp = vsid & SLB_VSID_LLP; -+ if (vsid & SLB_VSID_B_1T) { -+ printf(" 1T ESID=%9lx VSID=%13lx LLP:%3lx \n", -+ GET_ESID_1T(esid), -+ (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT_1T, -+ llp); -+ } else { -+ printf(" 256M ESID=%9lx VSID=%13lx LLP:%3lx \n", -+ GET_ESID(esid), -+ (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT, -+ llp); -+ } -+ } else -+ printf("\n"); -+ } - } - } - -@@ -2581,6 +2606,32 @@ void dump_segments(void) - } - #endif - -+#ifdef CONFIG_44x -+static void dump_tlb_44x(void) -+{ -+ int i; -+ -+ for (i = 0; i < PPC44x_TLB_SIZE; i++) { -+ unsigned long w0,w1,w2; -+ asm volatile("tlbre %0,%1,0" : "=r" (w0) : "r" (i)); -+ asm volatile("tlbre %0,%1,1" : "=r" (w1) : "r" (i)); -+ asm volatile("tlbre %0,%1,2" : "=r" (w2) : "r" (i)); -+ printf("[%02x] %08x %08x %08x ", i, w0, w1, w2); -+ if (w0 & PPC44x_TLB_VALID) { -+ printf("V %08x -> %01x%08x %c%c%c%c%c", -+ w0 & PPC44x_TLB_EPN_MASK, -+ w1 & PPC44x_TLB_ERPN_MASK, -+ w1 & PPC44x_TLB_RPN_MASK, -+ (w2 & PPC44x_TLB_W) ? 'W' : 'w', -+ (w2 & PPC44x_TLB_I) ? 'I' : 'i', -+ (w2 & PPC44x_TLB_M) ? 'M' : 'm', -+ (w2 & PPC44x_TLB_G) ? 'G' : 'g', -+ (w2 & PPC44x_TLB_E) ? 'E' : 'e'); -+ } -+ printf("\n"); -+ } -+} -+#endif /* CONFIG_44x */ - void xmon_init(int enable) - { - #ifdef CONFIG_PPC_ISERIES ---- a/arch/ppc/kernel/Makefile -+++ b/arch/ppc/kernel/Makefile -@@ -13,7 +13,6 @@ obj-y := entry.o traps.o time.o misc. - ppc_htab.o - obj-$(CONFIG_MODULES) += ppc_ksyms.o - obj-$(CONFIG_PCI) += pci.o --obj-$(CONFIG_RAPIDIO) += rio.o - obj-$(CONFIG_KGDB) += ppc-stub.o - obj-$(CONFIG_SMP) += smp.o smp-tbsync.o - obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o ---- a/arch/ppc/kernel/head_44x.S -+++ b/arch/ppc/kernel/head_44x.S -@@ -195,7 +195,7 @@ skpinv: addi r4,r4,1 /* Increment */ - li r5,0 - ori r5,r5,(PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_I | PPC44x_TLB_G) - -- li r0,0 /* TLB slot 0 */ -+ li r0,62 /* TLB slot 62 */ - - tlbwe r3,r0,PPC44x_TLB_PAGEID /* Load the pageid fields */ - tlbwe r4,r0,PPC44x_TLB_XLAT /* Load the translation fields */ ---- a/arch/ppc/kernel/rio.c -+++ /dev/null -@@ -1,52 +0,0 @@ --/* -- * RapidIO PPC32 support -- * -- * Copyright 2005 MontaVista Software, Inc. -- * Matt Porter -- * -- * 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 -- --/** -- * platform_rio_init - Do platform specific RIO init -- * -- * Any platform specific initialization of RapdIO -- * hardware is done here as well as registration -- * of any active master ports in the system. -- */ --void __attribute__ ((weak)) -- platform_rio_init(void) --{ -- printk(KERN_WARNING "RIO: No platform_rio_init() present\n"); --} -- --/** -- * ppc_rio_init - Do PPC32 RIO init -- * -- * Calls platform-specific RIO init code and then calls -- * rio_init_mports() to initialize any master ports that -- * have been registered with the RIO subsystem. -- */ --static int __init ppc_rio_init(void) --{ -- printk(KERN_INFO "RIO: RapidIO init\n"); -- -- /* Platform specific initialization */ -- platform_rio_init(); -- -- /* Enumerate all registered ports */ -- rio_init_mports(); -- -- return 0; --} -- --subsys_initcall(ppc_rio_init); ---- a/arch/ppc/kernel/setup.c -+++ b/arch/ppc/kernel/setup.c -@@ -37,7 +37,6 @@ - #include - #include - #include --#include - - #define USES_PPC_SYS (defined(CONFIG_85xx) || defined(CONFIG_83xx) || \ - defined(CONFIG_MPC10X_BRIDGE) || defined(CONFIG_8260) || \ ---- a/arch/ppc/kernel/traps.c -+++ b/arch/ppc/kernel/traps.c -@@ -231,39 +231,25 @@ platform_machine_check(struct pt_regs *r - { - } - --void machine_check_exception(struct pt_regs *regs) -+#if defined(CONFIG_4xx) -+int machine_check_4xx(struct pt_regs *regs) - { - unsigned long reason = get_mc_reason(regs); - -- if (user_mode(regs)) { -- regs->msr |= MSR_RI; -- _exception(SIGBUS, regs, BUS_ADRERR, regs->nip); -- return; -- } -- --#if defined(CONFIG_8xx) && defined(CONFIG_PCI) -- /* the qspan pci read routines can cause machine checks -- Cort */ -- bad_page_fault(regs, regs->dar, SIGBUS); -- return; --#endif -- -- if (debugger_fault_handler) { -- debugger_fault_handler(regs); -- regs->msr |= MSR_RI; -- return; -- } -- -- if (check_io_access(regs)) -- return; -- --#if defined(CONFIG_4xx) && !defined(CONFIG_440A) - if (reason & ESR_IMCP) { - printk("Instruction"); - mtspr(SPRN_ESR, reason & ~ESR_IMCP); - } else - printk("Data"); - printk(" machine check in kernel mode.\n"); --#elif defined(CONFIG_440A) -+ -+ return 0; -+} -+ -+int machine_check_440A(struct pt_regs *regs) -+{ -+ unsigned long reason = get_mc_reason(regs); -+ - printk("Machine check in kernel mode.\n"); - if (reason & ESR_IMCP){ - printk("Instruction Synchronous Machine Check exception\n"); -@@ -293,7 +279,13 @@ void machine_check_exception(struct pt_r - /* Clear MCSR */ - mtspr(SPRN_MCSR, mcsr); - } --#elif defined (CONFIG_E500) -+ return 0; -+} -+#elif defined(CONFIG_E500) -+int machine_check_e500(struct pt_regs *regs) -+{ -+ unsigned long reason = get_mc_reason(regs); -+ - printk("Machine check in kernel mode.\n"); - printk("Caused by (from MCSR=%lx): ", reason); - -@@ -305,8 +297,6 @@ void machine_check_exception(struct pt_r - printk("Data Cache Push Parity Error\n"); - if (reason & MCSR_DCPERR) - printk("Data Cache Parity Error\n"); -- if (reason & MCSR_GL_CI) -- printk("Guarded Load or Cache-Inhibited stwcx.\n"); - if (reason & MCSR_BUS_IAERR) - printk("Bus - Instruction Address Error\n"); - if (reason & MCSR_BUS_RAERR) -@@ -318,12 +308,19 @@ void machine_check_exception(struct pt_r - if (reason & MCSR_BUS_RBERR) - printk("Bus - Read Data Bus Error\n"); - if (reason & MCSR_BUS_WBERR) -- printk("Bus - Write Data Bus Error\n"); -+ printk("Bus - Read Data Bus Error\n"); - if (reason & MCSR_BUS_IPERR) - printk("Bus - Instruction Parity Error\n"); - if (reason & MCSR_BUS_RPERR) - printk("Bus - Read Parity Error\n"); --#elif defined (CONFIG_E200) -+ -+ return 0; -+} -+#elif defined(CONFIG_E200) -+int machine_check_e200(struct pt_regs *regs) -+{ -+ unsigned long reason = get_mc_reason(regs); -+ - printk("Machine check in kernel mode.\n"); - printk("Caused by (from MCSR=%lx): ", reason); - -@@ -341,7 +338,14 @@ void machine_check_exception(struct pt_r - printk("Bus - Read Bus Error on data load\n"); - if (reason & MCSR_BUS_WRERR) - printk("Bus - Write Bus Error on buffered store or cache line push\n"); --#else /* !CONFIG_4xx && !CONFIG_E500 && !CONFIG_E200 */ -+ -+ return 0; -+} -+#else -+int machine_check_generic(struct pt_regs *regs) -+{ -+ unsigned long reason = get_mc_reason(regs); -+ - printk("Machine check in kernel mode.\n"); - printk("Caused by (from SRR1=%lx): ", reason); - switch (reason & 0x601F0000) { -@@ -371,7 +375,39 @@ void machine_check_exception(struct pt_r - default: - printk("Unknown values in msr\n"); - } --#endif /* CONFIG_4xx */ -+ return 0; -+} -+#endif /* everything else */ -+ -+void machine_check_exception(struct pt_regs *regs) -+{ -+ int recover = 0; -+ -+ if (cur_cpu_spec->machine_check) -+ recover = cur_cpu_spec->machine_check(regs); -+ if (recover > 0) -+ return; -+ -+ if (user_mode(regs)) { -+ regs->msr |= MSR_RI; -+ _exception(SIGBUS, regs, BUS_ADRERR, regs->nip); -+ return; -+ } -+ -+#if defined(CONFIG_8xx) && defined(CONFIG_PCI) -+ /* the qspan pci read routines can cause machine checks -- Cort */ -+ bad_page_fault(regs, regs->dar, SIGBUS); -+ return; -+#endif -+ -+ if (debugger_fault_handler) { -+ debugger_fault_handler(regs); -+ regs->msr |= MSR_RI; -+ return; -+ } -+ -+ if (check_io_access(regs)) -+ return; - - /* - * Optional platform-provided routine to print out ---- a/arch/ppc/mm/44x_mmu.c -+++ b/arch/ppc/mm/44x_mmu.c -@@ -60,38 +60,28 @@ extern char etext[], _stext[]; - * Just needed it declared someplace. - */ - unsigned int tlb_44x_index = 0; --unsigned int tlb_44x_hwater = 62; -+unsigned int tlb_44x_hwater = PPC4XX_TLB_SIZE - 1 - PPC44x_EARLY_TLBS; - int icache_44x_need_flush; - - /* - * "Pins" a 256MB TLB entry in AS0 for kernel lowmem - */ --static void __init --ppc44x_pin_tlb(int slot, unsigned int virt, unsigned int phys) -+static void __init ppc44x_pin_tlb(unsigned int virt, unsigned int phys) - { -- unsigned long attrib = 0; -- -- __asm__ __volatile__("\ -- clrrwi %2,%2,10\n\ -- ori %2,%2,%4\n\ -- clrrwi %1,%1,10\n\ -- li %0,0\n\ -- ori %0,%0,%5\n\ -- tlbwe %2,%3,%6\n\ -- tlbwe %1,%3,%7\n\ -- tlbwe %0,%3,%8" -+ __asm__ __volatile__( -+ "tlbwe %2,%3,%4\n" -+ "tlbwe %1,%3,%5\n" -+ "tlbwe %0,%3,%6\n" - : -- : "r" (attrib), "r" (phys), "r" (virt), "r" (slot), -- "i" (PPC44x_TLB_VALID | PPC44x_TLB_256M), -- "i" (PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_SX | PPC44x_TLB_G), -+ : "r" (PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_SX | PPC44x_TLB_G), -+ "r" (phys), -+ "r" (virt | PPC44x_TLB_VALID | PPC44x_TLB_256M), -+ "r" (tlb_44x_hwater--), /* slot for this TLB entry */ - "i" (PPC44x_TLB_PAGEID), - "i" (PPC44x_TLB_XLAT), - "i" (PPC44x_TLB_ATTRIB)); - } - --/* -- * MMU_init_hw does the chip-specific initialization of the MMU hardware. -- */ - void __init MMU_init_hw(void) - { - flush_instruction_cache(); -@@ -99,22 +89,13 @@ void __init MMU_init_hw(void) - - unsigned long __init mmu_mapin_ram(void) - { -- unsigned int pinned_tlbs = 1; -- int i; -- -- /* Determine number of entries necessary to cover lowmem */ -- pinned_tlbs = (unsigned int) -- (_ALIGN(total_lowmem, PPC_PIN_SIZE) >> PPC44x_PIN_SHIFT); -- -- /* Write upper watermark to save location */ -- tlb_44x_hwater = PPC44x_LOW_SLOT - pinned_tlbs; -+ unsigned long addr; - -- /* If necessary, set additional pinned TLBs */ -- if (pinned_tlbs > 1) -- for (i = (PPC44x_LOW_SLOT-(pinned_tlbs-1)); i < PPC44x_LOW_SLOT; i++) { -- unsigned int phys_addr = (PPC44x_LOW_SLOT-i) * PPC_PIN_SIZE; -- ppc44x_pin_tlb(i, phys_addr+PAGE_OFFSET, phys_addr); -- } -+ /* Pin in enough TLBs to cover any lowmem not covered by the -+ * initial 256M mapping established in head_44x.S */ -+ for (addr = PPC_PIN_SIZE; addr < total_lowmem; -+ addr += PPC_PIN_SIZE) -+ ppc44x_pin_tlb(addr + PAGE_OFFSET, addr); - - return total_lowmem; - } ---- a/arch/ppc/platforms/85xx/mpc85xx_ads_common.c -+++ b/arch/ppc/platforms/85xx/mpc85xx_ads_common.c -@@ -42,8 +42,6 @@ - - #include - --#include -- - #include - - #ifndef CONFIG_PCI -@@ -190,6 +188,7 @@ mpc85xx_exclude_device(u_char bus, u_cha - #endif /* CONFIG_PCI */ - - #ifdef CONFIG_RAPIDIO -+extern void mpc85xx_rio_setup(int law_start, int law_size); - void platform_rio_init(void) - { - /* 512MB RIO LAW at 0xc0000000 */ ---- a/arch/ppc/platforms/85xx/stx_gp3.c -+++ b/arch/ppc/platforms/85xx/stx_gp3.c -@@ -50,12 +50,10 @@ - #include - #include - #include --#include - #include - - #include - #include --#include - - - unsigned char __res[sizeof(bd_t)]; -@@ -271,6 +269,7 @@ int mpc85xx_exclude_device(u_char bus, u - #endif /* CONFIG_PCI */ - - #ifdef CONFIG_RAPIDIO -+extern void mpc85xx_rio_setup(int law_start, int law_size); - void - platform_rio_init(void) - { ---- a/arch/ppc/platforms/85xx/tqm85xx.c -+++ b/arch/ppc/platforms/85xx/tqm85xx.c -@@ -54,7 +54,6 @@ - #include - #include - #include --#include - - #ifndef CONFIG_PCI - unsigned long isa_io_base = 0; -@@ -309,6 +308,7 @@ int mpc85xx_exclude_device(u_char bus, u - #endif /* CONFIG_PCI */ - - #ifdef CONFIG_RAPIDIO -+extern void mpc85xx_rio_setup(int law_start, int law_size); - void platform_rio_init(void) - { - /* 512MB RIO LAW at 0xc0000000 */ ---- a/arch/ppc/platforms/ev64260.c -+++ b/arch/ppc/platforms/ev64260.c -@@ -336,7 +336,7 @@ ev64260_early_serial_map(void) - #endif - - if (early_serial_setup(&port) != 0) -- printk(KERN_WARNING "Early serial init of port 0" -+ printk(KERN_WARNING "Early serial init of port 0 " - "failed\n"); - - first_time = 0; -@@ -388,7 +388,7 @@ ev64260_setup_arch(void) - ev64260_early_serial_map(); - #endif - -- printk(KERN_INFO "%s %s port (C) 2001 MontaVista Software, Inc." -+ printk(KERN_INFO "%s %s port (C) 2001 MontaVista Software, Inc. " - "(source@mvista.com)\n", BOARD_VENDOR, BOARD_MACHINE); - - if (ppc_md.progress) ---- a/arch/ppc/platforms/prep_pci.c -+++ b/arch/ppc/platforms/prep_pci.c -@@ -1099,7 +1099,6 @@ prep_pib_init(void) - pci_write_config_byte(dev, 0x43, reg); - } - } -- pci_dev_put(dev); - } - - if ((dev = pci_get_device(PCI_VENDOR_ID_WINBOND, ---- a/arch/ppc/syslib/Makefile -+++ b/arch/ppc/syslib/Makefile -@@ -93,7 +93,6 @@ obj-$(CONFIG_85xx) += open_pic.o ppc85x - ifeq ($(CONFIG_85xx),y) - obj-$(CONFIG_PCI) += pci_auto.o - endif --obj-$(CONFIG_RAPIDIO) += ppc85xx_rio.o - obj-$(CONFIG_83xx) += ppc83xx_setup.o ppc_sys.o \ - mpc83xx_sys.o mpc83xx_devices.o ipic.o - ifeq ($(CONFIG_83xx),y) ---- a/arch/ppc/syslib/gt64260_pic.c -+++ b/arch/ppc/syslib/gt64260_pic.c -@@ -35,7 +35,6 @@ - #include - #include - #include --#include - #include - #include - ---- a/arch/ppc/syslib/mpc52xx_pic.c -+++ b/arch/ppc/syslib/mpc52xx_pic.c -@@ -20,7 +20,6 @@ - #include - #include - #include --#include - #include - #include - ---- a/arch/ppc/syslib/mv64360_pic.c -+++ b/arch/ppc/syslib/mv64360_pic.c -@@ -36,7 +36,6 @@ - #include - #include - #include --#include - #include - #include - #include ---- a/arch/ppc/syslib/ocp.c -+++ b/arch/ppc/syslib/ocp.c -@@ -376,7 +376,7 @@ ocp_remove_one_device(unsigned int vendo - - down_write(&ocp_devices_sem); - dev = __ocp_find_device(vendor, function, index); -- list_del((struct list_head *)dev); -+ list_del(&dev->link); - up_write(&ocp_devices_sem); - - DBG(("ocp: ocp_remove_one_device(vendor: %x, function: %x, index: %d)... done.\n", vendor, function, index)); ---- a/arch/ppc/syslib/ppc83xx_setup.c -+++ b/arch/ppc/syslib/ppc83xx_setup.c -@@ -41,7 +41,6 @@ - - #include - #if defined(CONFIG_PCI) --#include - #include - #endif - ---- a/arch/ppc/syslib/ppc85xx_rio.c -+++ /dev/null -@@ -1,932 +0,0 @@ --/* -- * MPC85xx RapidIO support -- * -- * Copyright 2005 MontaVista Software, Inc. -- * Matt Porter -- * -- * 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 -- --#define RIO_REGS_BASE (CCSRBAR + 0xc0000) --#define RIO_ATMU_REGS_OFFSET 0x10c00 --#define RIO_MSG_REGS_OFFSET 0x11000 --#define RIO_MAINT_WIN_SIZE 0x400000 --#define RIO_DBELL_WIN_SIZE 0x1000 -- --#define RIO_MSG_OMR_MUI 0x00000002 --#define RIO_MSG_OSR_TE 0x00000080 --#define RIO_MSG_OSR_QOI 0x00000020 --#define RIO_MSG_OSR_QFI 0x00000010 --#define RIO_MSG_OSR_MUB 0x00000004 --#define RIO_MSG_OSR_EOMI 0x00000002 --#define RIO_MSG_OSR_QEI 0x00000001 -- --#define RIO_MSG_IMR_MI 0x00000002 --#define RIO_MSG_ISR_TE 0x00000080 --#define RIO_MSG_ISR_QFI 0x00000010 --#define RIO_MSG_ISR_DIQI 0x00000001 -- --#define RIO_MSG_DESC_SIZE 32 --#define RIO_MSG_BUFFER_SIZE 4096 --#define RIO_MIN_TX_RING_SIZE 2 --#define RIO_MAX_TX_RING_SIZE 2048 --#define RIO_MIN_RX_RING_SIZE 2 --#define RIO_MAX_RX_RING_SIZE 2048 -- --#define DOORBELL_DMR_DI 0x00000002 --#define DOORBELL_DSR_TE 0x00000080 --#define DOORBELL_DSR_QFI 0x00000010 --#define DOORBELL_DSR_DIQI 0x00000001 --#define DOORBELL_TID_OFFSET 0x03 --#define DOORBELL_SID_OFFSET 0x05 --#define DOORBELL_INFO_OFFSET 0x06 -- --#define DOORBELL_MESSAGE_SIZE 0x08 --#define DBELL_SID(x) (*(u8 *)(x + DOORBELL_SID_OFFSET)) --#define DBELL_TID(x) (*(u8 *)(x + DOORBELL_TID_OFFSET)) --#define DBELL_INF(x) (*(u16 *)(x + DOORBELL_INFO_OFFSET)) -- --struct rio_atmu_regs { -- u32 rowtar; -- u32 pad1; -- u32 rowbar; -- u32 pad2; -- u32 rowar; -- u32 pad3[3]; --}; -- --struct rio_msg_regs { -- u32 omr; -- u32 osr; -- u32 pad1; -- u32 odqdpar; -- u32 pad2; -- u32 osar; -- u32 odpr; -- u32 odatr; -- u32 odcr; -- u32 pad3; -- u32 odqepar; -- u32 pad4[13]; -- u32 imr; -- u32 isr; -- u32 pad5; -- u32 ifqdpar; -- u32 pad6; -- u32 ifqepar; -- u32 pad7[250]; -- u32 dmr; -- u32 dsr; -- u32 pad8; -- u32 dqdpar; -- u32 pad9; -- u32 dqepar; -- u32 pad10[26]; -- u32 pwmr; -- u32 pwsr; -- u32 pad11; -- u32 pwqbar; --}; -- --struct rio_tx_desc { -- u32 res1; -- u32 saddr; -- u32 dport; -- u32 dattr; -- u32 res2; -- u32 res3; -- u32 dwcnt; -- u32 res4; --}; -- --static u32 regs_win; --static struct rio_atmu_regs *atmu_regs; --static struct rio_atmu_regs *maint_atmu_regs; --static struct rio_atmu_regs *dbell_atmu_regs; --static u32 dbell_win; --static u32 maint_win; --static struct rio_msg_regs *msg_regs; -- --static struct rio_dbell_ring { -- void *virt; -- dma_addr_t phys; --} dbell_ring; -- --static struct rio_msg_tx_ring { -- void *virt; -- dma_addr_t phys; -- void *virt_buffer[RIO_MAX_TX_RING_SIZE]; -- dma_addr_t phys_buffer[RIO_MAX_TX_RING_SIZE]; -- int tx_slot; -- int size; -- void *dev_id; --} msg_tx_ring; -- --static struct rio_msg_rx_ring { -- void *virt; -- dma_addr_t phys; -- void *virt_buffer[RIO_MAX_RX_RING_SIZE]; -- int rx_slot; -- int size; -- void *dev_id; --} msg_rx_ring; -- --/** -- * mpc85xx_rio_doorbell_send - Send a MPC85xx doorbell message -- * @index: ID of RapidIO interface -- * @destid: Destination ID of target device -- * @data: 16-bit info field of RapidIO doorbell message -- * -- * Sends a MPC85xx doorbell message. Returns %0 on success or -- * %-EINVAL on failure. -- */ --static int mpc85xx_rio_doorbell_send(int index, u16 destid, u16 data) --{ -- pr_debug("mpc85xx_doorbell_send: index %d destid %4.4x data %4.4x\n", -- index, destid, data); -- out_be32((void *)&dbell_atmu_regs->rowtar, destid << 22); -- out_be16((void *)(dbell_win), data); -- -- return 0; --} -- --/** -- * mpc85xx_local_config_read - Generate a MPC85xx local config space read -- * @index: ID of RapdiIO interface -- * @offset: Offset into configuration space -- * @len: Length (in bytes) of the maintenance transaction -- * @data: Value to be read into -- * -- * Generates a MPC85xx local configuration space read. Returns %0 on -- * success or %-EINVAL on failure. -- */ --static int mpc85xx_local_config_read(int index, u32 offset, int len, u32 * data) --{ -- pr_debug("mpc85xx_local_config_read: index %d offset %8.8x\n", index, -- offset); -- *data = in_be32((void *)(regs_win + offset)); -- -- return 0; --} -- --/** -- * mpc85xx_local_config_write - Generate a MPC85xx local config space write -- * @index: ID of RapdiIO interface -- * @offset: Offset into configuration space -- * @len: Length (in bytes) of the maintenance transaction -- * @data: Value to be written -- * -- * Generates a MPC85xx local configuration space write. Returns %0 on -- * success or %-EINVAL on failure. -- */ --static int mpc85xx_local_config_write(int index, u32 offset, int len, u32 data) --{ -- pr_debug -- ("mpc85xx_local_config_write: index %d offset %8.8x data %8.8x\n", -- index, offset, data); -- out_be32((void *)(regs_win + offset), data); -- -- return 0; --} -- --/** -- * mpc85xx_rio_config_read - Generate a MPC85xx read maintenance transaction -- * @index: ID of RapdiIO interface -- * @destid: Destination ID of transaction -- * @hopcount: Number of hops to target device -- * @offset: Offset into configuration space -- * @len: Length (in bytes) of the maintenance transaction -- * @val: Location to be read into -- * -- * Generates a MPC85xx read maintenance transaction. Returns %0 on -- * success or %-EINVAL on failure. -- */ --static int --mpc85xx_rio_config_read(int index, u16 destid, u8 hopcount, u32 offset, int len, -- u32 * val) --{ -- u8 *data; -- -- pr_debug -- ("mpc85xx_rio_config_read: index %d destid %d hopcount %d offset %8.8x len %d\n", -- index, destid, hopcount, offset, len); -- out_be32((void *)&maint_atmu_regs->rowtar, -- (destid << 22) | (hopcount << 12) | ((offset & ~0x3) >> 9)); -- -- data = (u8 *) maint_win + offset; -- switch (len) { -- case 1: -- *val = in_8((u8 *) data); -- break; -- case 2: -- *val = in_be16((u16 *) data); -- break; -- default: -- *val = in_be32((u32 *) data); -- break; -- } -- -- return 0; --} -- --/** -- * mpc85xx_rio_config_write - Generate a MPC85xx write maintenance transaction -- * @index: ID of RapdiIO interface -- * @destid: Destination ID of transaction -- * @hopcount: Number of hops to target device -- * @offset: Offset into configuration space -- * @len: Length (in bytes) of the maintenance transaction -- * @val: Value to be written -- * -- * Generates an MPC85xx write maintenance transaction. Returns %0 on -- * success or %-EINVAL on failure. -- */ --static int --mpc85xx_rio_config_write(int index, u16 destid, u8 hopcount, u32 offset, -- int len, u32 val) --{ -- u8 *data; -- pr_debug -- ("mpc85xx_rio_config_write: index %d destid %d hopcount %d offset %8.8x len %d val %8.8x\n", -- index, destid, hopcount, offset, len, val); -- out_be32((void *)&maint_atmu_regs->rowtar, -- (destid << 22) | (hopcount << 12) | ((offset & ~0x3) >> 9)); -- -- data = (u8 *) maint_win + offset; -- switch (len) { -- case 1: -- out_8((u8 *) data, val); -- break; -- case 2: -- out_be16((u16 *) data, val); -- break; -- default: -- out_be32((u32 *) data, val); -- break; -- } -- -- return 0; --} -- --/** -- * rio_hw_add_outb_message - Add message to the MPC85xx outbound message queue -- * @mport: Master port with outbound message queue -- * @rdev: Target of outbound message -- * @mbox: Outbound mailbox -- * @buffer: Message to add to outbound queue -- * @len: Length of message -- * -- * Adds the @buffer message to the MPC85xx outbound message queue. Returns -- * %0 on success or %-EINVAL on failure. -- */ --int --rio_hw_add_outb_message(struct rio_mport *mport, struct rio_dev *rdev, int mbox, -- void *buffer, size_t len) --{ -- u32 omr; -- struct rio_tx_desc *desc = -- (struct rio_tx_desc *)msg_tx_ring.virt + msg_tx_ring.tx_slot; -- int ret = 0; -- -- pr_debug -- ("RIO: rio_hw_add_outb_message(): destid %4.4x mbox %d buffer %8.8x len %8.8x\n", -- rdev->destid, mbox, (int)buffer, len); -- -- if ((len < 8) || (len > RIO_MAX_MSG_SIZE)) { -- ret = -EINVAL; -- goto out; -- } -- -- /* Copy and clear rest of buffer */ -- memcpy(msg_tx_ring.virt_buffer[msg_tx_ring.tx_slot], buffer, len); -- if (len < (RIO_MAX_MSG_SIZE - 4)) -- memset((void *)((u32) msg_tx_ring. -- virt_buffer[msg_tx_ring.tx_slot] + len), 0, -- RIO_MAX_MSG_SIZE - len); -- -- /* Set mbox field for message */ -- desc->dport = mbox & 0x3; -- -- /* Enable EOMI interrupt, set priority, and set destid */ -- desc->dattr = 0x28000000 | (rdev->destid << 2); -- -- /* Set transfer size aligned to next power of 2 (in double words) */ -- desc->dwcnt = is_power_of_2(len) ? len : 1 << get_bitmask_order(len); -- -- /* Set snooping and source buffer address */ -- desc->saddr = 0x00000004 | msg_tx_ring.phys_buffer[msg_tx_ring.tx_slot]; -- -- /* Increment enqueue pointer */ -- omr = in_be32((void *)&msg_regs->omr); -- out_be32((void *)&msg_regs->omr, omr | RIO_MSG_OMR_MUI); -- -- /* Go to next descriptor */ -- if (++msg_tx_ring.tx_slot == msg_tx_ring.size) -- msg_tx_ring.tx_slot = 0; -- -- out: -- return ret; --} -- --EXPORT_SYMBOL_GPL(rio_hw_add_outb_message); -- --/** -- * mpc85xx_rio_tx_handler - MPC85xx outbound message interrupt handler -- * @irq: Linux interrupt number -- * @dev_instance: Pointer to interrupt-specific data -- * -- * Handles outbound message interrupts. Executes a register outbound -- * mailbox event handler and acks the interrupt occurrence. -- */ --static irqreturn_t --mpc85xx_rio_tx_handler(int irq, void *dev_instance) --{ -- int osr; -- struct rio_mport *port = (struct rio_mport *)dev_instance; -- -- osr = in_be32((void *)&msg_regs->osr); -- -- if (osr & RIO_MSG_OSR_TE) { -- pr_info("RIO: outbound message transmission error\n"); -- out_be32((void *)&msg_regs->osr, RIO_MSG_OSR_TE); -- goto out; -- } -- -- if (osr & RIO_MSG_OSR_QOI) { -- pr_info("RIO: outbound message queue overflow\n"); -- out_be32((void *)&msg_regs->osr, RIO_MSG_OSR_QOI); -- goto out; -- } -- -- if (osr & RIO_MSG_OSR_EOMI) { -- u32 dqp = in_be32((void *)&msg_regs->odqdpar); -- int slot = (dqp - msg_tx_ring.phys) >> 5; -- port->outb_msg[0].mcback(port, msg_tx_ring.dev_id, -1, slot); -- -- /* Ack the end-of-message interrupt */ -- out_be32((void *)&msg_regs->osr, RIO_MSG_OSR_EOMI); -- } -- -- out: -- return IRQ_HANDLED; --} -- --/** -- * rio_open_outb_mbox - Initialize MPC85xx outbound mailbox -- * @mport: Master port implementing the outbound message unit -- * @dev_id: Device specific pointer to pass on event -- * @mbox: Mailbox to open -- * @entries: Number of entries in the outbound mailbox ring -- * -- * Initializes buffer ring, request the outbound message interrupt, -- * and enables the outbound message unit. Returns %0 on success and -- * %-EINVAL or %-ENOMEM on failure. -- */ --int rio_open_outb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entries) --{ -- int i, j, rc = 0; -- -- if ((entries < RIO_MIN_TX_RING_SIZE) || -- (entries > RIO_MAX_TX_RING_SIZE) || (!is_power_of_2(entries))) { -- rc = -EINVAL; -- goto out; -- } -- -- /* Initialize shadow copy ring */ -- msg_tx_ring.dev_id = dev_id; -- msg_tx_ring.size = entries; -- -- for (i = 0; i < msg_tx_ring.size; i++) { -- if (! -- (msg_tx_ring.virt_buffer[i] = -- dma_alloc_coherent(NULL, RIO_MSG_BUFFER_SIZE, -- &msg_tx_ring.phys_buffer[i], -- GFP_KERNEL))) { -- rc = -ENOMEM; -- for (j = 0; j < msg_tx_ring.size; j++) -- if (msg_tx_ring.virt_buffer[j]) -- dma_free_coherent(NULL, -- RIO_MSG_BUFFER_SIZE, -- msg_tx_ring. -- virt_buffer[j], -- msg_tx_ring. -- phys_buffer[j]); -- goto out; -- } -- } -- -- /* Initialize outbound message descriptor ring */ -- if (!(msg_tx_ring.virt = dma_alloc_coherent(NULL, -- msg_tx_ring.size * -- RIO_MSG_DESC_SIZE, -- &msg_tx_ring.phys, -- GFP_KERNEL))) { -- rc = -ENOMEM; -- goto out_dma; -- } -- memset(msg_tx_ring.virt, 0, msg_tx_ring.size * RIO_MSG_DESC_SIZE); -- msg_tx_ring.tx_slot = 0; -- -- /* Point dequeue/enqueue pointers at first entry in ring */ -- out_be32((void *)&msg_regs->odqdpar, msg_tx_ring.phys); -- out_be32((void *)&msg_regs->odqepar, msg_tx_ring.phys); -- -- /* Configure for snooping */ -- out_be32((void *)&msg_regs->osar, 0x00000004); -- -- /* Clear interrupt status */ -- out_be32((void *)&msg_regs->osr, 0x000000b3); -- -- /* Hook up outbound message handler */ -- if ((rc = -- request_irq(MPC85xx_IRQ_RIO_TX, mpc85xx_rio_tx_handler, 0, -- "msg_tx", (void *)mport)) < 0) -- goto out_irq; -- -- /* -- * Configure outbound message unit -- * Snooping -- * Interrupts (all enabled, except QEIE) -- * Chaining mode -- * Disable -- */ -- out_be32((void *)&msg_regs->omr, 0x00100220); -- -- /* Set number of entries */ -- out_be32((void *)&msg_regs->omr, -- in_be32((void *)&msg_regs->omr) | -- ((get_bitmask_order(entries) - 2) << 12)); -- -- /* Now enable the unit */ -- out_be32((void *)&msg_regs->omr, in_be32((void *)&msg_regs->omr) | 0x1); -- -- out: -- return rc; -- -- out_irq: -- dma_free_coherent(NULL, msg_tx_ring.size * RIO_MSG_DESC_SIZE, -- msg_tx_ring.virt, msg_tx_ring.phys); -- -- out_dma: -- for (i = 0; i < msg_tx_ring.size; i++) -- dma_free_coherent(NULL, RIO_MSG_BUFFER_SIZE, -- msg_tx_ring.virt_buffer[i], -- msg_tx_ring.phys_buffer[i]); -- -- return rc; --} -- --/** -- * rio_close_outb_mbox - Shut down MPC85xx outbound mailbox -- * @mport: Master port implementing the outbound message unit -- * @mbox: Mailbox to close -- * -- * Disables the outbound message unit, free all buffers, and -- * frees the outbound message interrupt. -- */ --void rio_close_outb_mbox(struct rio_mport *mport, int mbox) --{ -- /* Disable inbound message unit */ -- out_be32((void *)&msg_regs->omr, 0); -- -- /* Free ring */ -- dma_free_coherent(NULL, msg_tx_ring.size * RIO_MSG_DESC_SIZE, -- msg_tx_ring.virt, msg_tx_ring.phys); -- -- /* Free interrupt */ -- free_irq(MPC85xx_IRQ_RIO_TX, (void *)mport); --} -- --/** -- * mpc85xx_rio_rx_handler - MPC85xx inbound message interrupt handler -- * @irq: Linux interrupt number -- * @dev_instance: Pointer to interrupt-specific data -- * -- * Handles inbound message interrupts. Executes a registered inbound -- * mailbox event handler and acks the interrupt occurrence. -- */ --static irqreturn_t --mpc85xx_rio_rx_handler(int irq, void *dev_instance) --{ -- int isr; -- struct rio_mport *port = (struct rio_mport *)dev_instance; -- -- isr = in_be32((void *)&msg_regs->isr); -- -- if (isr & RIO_MSG_ISR_TE) { -- pr_info("RIO: inbound message reception error\n"); -- out_be32((void *)&msg_regs->isr, RIO_MSG_ISR_TE); -- goto out; -- } -- -- /* XXX Need to check/dispatch until queue empty */ -- if (isr & RIO_MSG_ISR_DIQI) { -- /* -- * We implement *only* mailbox 0, but can receive messages -- * for any mailbox/letter to that mailbox destination. So, -- * make the callback with an unknown/invalid mailbox number -- * argument. -- */ -- port->inb_msg[0].mcback(port, msg_rx_ring.dev_id, -1, -1); -- -- /* Ack the queueing interrupt */ -- out_be32((void *)&msg_regs->isr, RIO_MSG_ISR_DIQI); -- } -- -- out: -- return IRQ_HANDLED; --} -- --/** -- * rio_open_inb_mbox - Initialize MPC85xx inbound mailbox -- * @mport: Master port implementing the inbound message unit -- * @dev_id: Device specific pointer to pass on event -- * @mbox: Mailbox to open -- * @entries: Number of entries in the inbound mailbox ring -- * -- * Initializes buffer ring, request the inbound message interrupt, -- * and enables the inbound message unit. Returns %0 on success -- * and %-EINVAL or %-ENOMEM on failure. -- */ --int rio_open_inb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entries) --{ -- int i, rc = 0; -- -- if ((entries < RIO_MIN_RX_RING_SIZE) || -- (entries > RIO_MAX_RX_RING_SIZE) || (!is_power_of_2(entries))) { -- rc = -EINVAL; -- goto out; -- } -- -- /* Initialize client buffer ring */ -- msg_rx_ring.dev_id = dev_id; -- msg_rx_ring.size = entries; -- msg_rx_ring.rx_slot = 0; -- for (i = 0; i < msg_rx_ring.size; i++) -- msg_rx_ring.virt_buffer[i] = NULL; -- -- /* Initialize inbound message ring */ -- if (!(msg_rx_ring.virt = dma_alloc_coherent(NULL, -- msg_rx_ring.size * -- RIO_MAX_MSG_SIZE, -- &msg_rx_ring.phys, -- GFP_KERNEL))) { -- rc = -ENOMEM; -- goto out; -- } -- -- /* Point dequeue/enqueue pointers at first entry in ring */ -- out_be32((void *)&msg_regs->ifqdpar, (u32) msg_rx_ring.phys); -- out_be32((void *)&msg_regs->ifqepar, (u32) msg_rx_ring.phys); -- -- /* Clear interrupt status */ -- out_be32((void *)&msg_regs->isr, 0x00000091); -- -- /* Hook up inbound message handler */ -- if ((rc = -- request_irq(MPC85xx_IRQ_RIO_RX, mpc85xx_rio_rx_handler, 0, -- "msg_rx", (void *)mport)) < 0) { -- dma_free_coherent(NULL, RIO_MSG_BUFFER_SIZE, -- msg_tx_ring.virt_buffer[i], -- msg_tx_ring.phys_buffer[i]); -- goto out; -- } -- -- /* -- * Configure inbound message unit: -- * Snooping -- * 4KB max message size -- * Unmask all interrupt sources -- * Disable -- */ -- out_be32((void *)&msg_regs->imr, 0x001b0060); -- -- /* Set number of queue entries */ -- out_be32((void *)&msg_regs->imr, -- in_be32((void *)&msg_regs->imr) | -- ((get_bitmask_order(entries) - 2) << 12)); -- -- /* Now enable the unit */ -- out_be32((void *)&msg_regs->imr, in_be32((void *)&msg_regs->imr) | 0x1); -- -- out: -- return rc; --} -- --/** -- * rio_close_inb_mbox - Shut down MPC85xx inbound mailbox -- * @mport: Master port implementing the inbound message unit -- * @mbox: Mailbox to close -- * -- * Disables the inbound message unit, free all buffers, and -- * frees the inbound message interrupt. -- */ --void rio_close_inb_mbox(struct rio_mport *mport, int mbox) --{ -- /* Disable inbound message unit */ -- out_be32((void *)&msg_regs->imr, 0); -- -- /* Free ring */ -- dma_free_coherent(NULL, msg_rx_ring.size * RIO_MAX_MSG_SIZE, -- msg_rx_ring.virt, msg_rx_ring.phys); -- -- /* Free interrupt */ -- free_irq(MPC85xx_IRQ_RIO_RX, (void *)mport); --} -- --/** -- * rio_hw_add_inb_buffer - Add buffer to the MPC85xx inbound message queue -- * @mport: Master port implementing the inbound message unit -- * @mbox: Inbound mailbox number -- * @buf: Buffer to add to inbound queue -- * -- * Adds the @buf buffer to the MPC85xx inbound message queue. Returns -- * %0 on success or %-EINVAL on failure. -- */ --int rio_hw_add_inb_buffer(struct rio_mport *mport, int mbox, void *buf) --{ -- int rc = 0; -- -- pr_debug("RIO: rio_hw_add_inb_buffer(), msg_rx_ring.rx_slot %d\n", -- msg_rx_ring.rx_slot); -- -- if (msg_rx_ring.virt_buffer[msg_rx_ring.rx_slot]) { -- printk(KERN_ERR -- "RIO: error adding inbound buffer %d, buffer exists\n", -- msg_rx_ring.rx_slot); -- rc = -EINVAL; -- goto out; -- } -- -- msg_rx_ring.virt_buffer[msg_rx_ring.rx_slot] = buf; -- if (++msg_rx_ring.rx_slot == msg_rx_ring.size) -- msg_rx_ring.rx_slot = 0; -- -- out: -- return rc; --} -- --EXPORT_SYMBOL_GPL(rio_hw_add_inb_buffer); -- --/** -- * rio_hw_get_inb_message - Fetch inbound message from the MPC85xx message unit -- * @mport: Master port implementing the inbound message unit -- * @mbox: Inbound mailbox number -- * -- * Gets the next available inbound message from the inbound message queue. -- * A pointer to the message is returned on success or NULL on failure. -- */ --void *rio_hw_get_inb_message(struct rio_mport *mport, int mbox) --{ -- u32 imr; -- u32 phys_buf, virt_buf; -- void *buf = NULL; -- int buf_idx; -- -- phys_buf = in_be32((void *)&msg_regs->ifqdpar); -- -- /* If no more messages, then bail out */ -- if (phys_buf == in_be32((void *)&msg_regs->ifqepar)) -- goto out2; -- -- virt_buf = (u32) msg_rx_ring.virt + (phys_buf - msg_rx_ring.phys); -- buf_idx = (phys_buf - msg_rx_ring.phys) / RIO_MAX_MSG_SIZE; -- buf = msg_rx_ring.virt_buffer[buf_idx]; -- -- if (!buf) { -- printk(KERN_ERR -- "RIO: inbound message copy failed, no buffers\n"); -- goto out1; -- } -- -- /* Copy max message size, caller is expected to allocate that big */ -- memcpy(buf, (void *)virt_buf, RIO_MAX_MSG_SIZE); -- -- /* Clear the available buffer */ -- msg_rx_ring.virt_buffer[buf_idx] = NULL; -- -- out1: -- imr = in_be32((void *)&msg_regs->imr); -- out_be32((void *)&msg_regs->imr, imr | RIO_MSG_IMR_MI); -- -- out2: -- return buf; --} -- --EXPORT_SYMBOL_GPL(rio_hw_get_inb_message); -- --/** -- * mpc85xx_rio_dbell_handler - MPC85xx doorbell interrupt handler -- * @irq: Linux interrupt number -- * @dev_instance: Pointer to interrupt-specific data -- * -- * Handles doorbell interrupts. Parses a list of registered -- * doorbell event handlers and executes a matching event handler. -- */ --static irqreturn_t --mpc85xx_rio_dbell_handler(int irq, void *dev_instance) --{ -- int dsr; -- struct rio_mport *port = (struct rio_mport *)dev_instance; -- -- dsr = in_be32((void *)&msg_regs->dsr); -- -- if (dsr & DOORBELL_DSR_TE) { -- pr_info("RIO: doorbell reception error\n"); -- out_be32((void *)&msg_regs->dsr, DOORBELL_DSR_TE); -- goto out; -- } -- -- if (dsr & DOORBELL_DSR_QFI) { -- pr_info("RIO: doorbell queue full\n"); -- out_be32((void *)&msg_regs->dsr, DOORBELL_DSR_QFI); -- goto out; -- } -- -- /* XXX Need to check/dispatch until queue empty */ -- if (dsr & DOORBELL_DSR_DIQI) { -- u32 dmsg = -- (u32) dbell_ring.virt + -- (in_be32((void *)&msg_regs->dqdpar) & 0xfff); -- u32 dmr; -- struct rio_dbell *dbell; -- int found = 0; -- -- pr_debug -- ("RIO: processing doorbell, sid %2.2x tid %2.2x info %4.4x\n", -- DBELL_SID(dmsg), DBELL_TID(dmsg), DBELL_INF(dmsg)); -- -- list_for_each_entry(dbell, &port->dbells, node) { -- if ((dbell->res->start <= DBELL_INF(dmsg)) && -- (dbell->res->end >= DBELL_INF(dmsg))) { -- found = 1; -- break; -- } -- } -- if (found) { -- dbell->dinb(port, dbell->dev_id, DBELL_SID(dmsg), DBELL_TID(dmsg), -- DBELL_INF(dmsg)); -- } else { -- pr_debug -- ("RIO: spurious doorbell, sid %2.2x tid %2.2x info %4.4x\n", -- DBELL_SID(dmsg), DBELL_TID(dmsg), DBELL_INF(dmsg)); -- } -- dmr = in_be32((void *)&msg_regs->dmr); -- out_be32((void *)&msg_regs->dmr, dmr | DOORBELL_DMR_DI); -- out_be32((void *)&msg_regs->dsr, DOORBELL_DSR_DIQI); -- } -- -- out: -- return IRQ_HANDLED; --} -- --/** -- * mpc85xx_rio_doorbell_init - MPC85xx doorbell interface init -- * @mport: Master port implementing the inbound doorbell unit -- * -- * Initializes doorbell unit hardware and inbound DMA buffer -- * ring. Called from mpc85xx_rio_setup(). Returns %0 on success -- * or %-ENOMEM on failure. -- */ --static int mpc85xx_rio_doorbell_init(struct rio_mport *mport) --{ -- int rc = 0; -- -- /* Map outbound doorbell window immediately after maintenance window */ -- if (!(dbell_win = -- (u32) ioremap(mport->iores.start + RIO_MAINT_WIN_SIZE, -- RIO_DBELL_WIN_SIZE))) { -- printk(KERN_ERR -- "RIO: unable to map outbound doorbell window\n"); -- rc = -ENOMEM; -- goto out; -- } -- -- /* Initialize inbound doorbells */ -- if (!(dbell_ring.virt = dma_alloc_coherent(NULL, -- 512 * DOORBELL_MESSAGE_SIZE, -- &dbell_ring.phys, -- GFP_KERNEL))) { -- printk(KERN_ERR "RIO: unable allocate inbound doorbell ring\n"); -- rc = -ENOMEM; -- iounmap((void *)dbell_win); -- goto out; -- } -- -- /* Point dequeue/enqueue pointers at first entry in ring */ -- out_be32((void *)&msg_regs->dqdpar, (u32) dbell_ring.phys); -- out_be32((void *)&msg_regs->dqepar, (u32) dbell_ring.phys); -- -- /* Clear interrupt status */ -- out_be32((void *)&msg_regs->dsr, 0x00000091); -- -- /* Hook up doorbell handler */ -- if ((rc = -- request_irq(MPC85xx_IRQ_RIO_BELL, mpc85xx_rio_dbell_handler, 0, -- "dbell_rx", (void *)mport) < 0)) { -- iounmap((void *)dbell_win); -- dma_free_coherent(NULL, 512 * DOORBELL_MESSAGE_SIZE, -- dbell_ring.virt, dbell_ring.phys); -- printk(KERN_ERR -- "MPC85xx RIO: unable to request inbound doorbell irq"); -- goto out; -- } -- -- /* Configure doorbells for snooping, 512 entries, and enable */ -- out_be32((void *)&msg_regs->dmr, 0x00108161); -- -- out: -- return rc; --} -- --static char *cmdline = NULL; -- --static int mpc85xx_rio_get_hdid(int index) --{ -- /* XXX Need to parse multiple entries in some format */ -- if (!cmdline) -- return -1; -- -- return simple_strtol(cmdline, NULL, 0); --} -- --static int mpc85xx_rio_get_cmdline(char *s) --{ -- if (!s) -- return 0; -- -- cmdline = s; -- return 1; --} -- --__setup("riohdid=", mpc85xx_rio_get_cmdline); -- --/** -- * mpc85xx_rio_setup - Setup MPC85xx RapidIO interface -- * @law_start: Starting physical address of RapidIO LAW -- * @law_size: Size of RapidIO LAW -- * -- * Initializes MPC85xx RapidIO hardware interface, configures -- * master port with system-specific info, and registers the -- * master port with the RapidIO subsystem. -- */ --void mpc85xx_rio_setup(int law_start, int law_size) --{ -- struct rio_ops *ops; -- struct rio_mport *port; -- -- ops = kmalloc(sizeof(struct rio_ops), GFP_KERNEL); -- ops->lcread = mpc85xx_local_config_read; -- ops->lcwrite = mpc85xx_local_config_write; -- ops->cread = mpc85xx_rio_config_read; -- ops->cwrite = mpc85xx_rio_config_write; -- ops->dsend = mpc85xx_rio_doorbell_send; -- -- port = kmalloc(sizeof(struct rio_mport), GFP_KERNEL); -- port->id = 0; -- port->index = 0; -- INIT_LIST_HEAD(&port->dbells); -- port->iores.start = law_start; -- port->iores.end = law_start + law_size; -- port->iores.flags = IORESOURCE_MEM; -- -- rio_init_dbell_res(&port->riores[RIO_DOORBELL_RESOURCE], 0, 0xffff); -- rio_init_mbox_res(&port->riores[RIO_INB_MBOX_RESOURCE], 0, 0); -- rio_init_mbox_res(&port->riores[RIO_OUTB_MBOX_RESOURCE], 0, 0); -- strcpy(port->name, "RIO0 mport"); -- -- port->ops = ops; -- port->host_deviceid = mpc85xx_rio_get_hdid(port->id); -- -- rio_register_mport(port); -- -- regs_win = (u32) ioremap(RIO_REGS_BASE, 0x20000); -- atmu_regs = (struct rio_atmu_regs *)(regs_win + RIO_ATMU_REGS_OFFSET); -- maint_atmu_regs = atmu_regs + 1; -- dbell_atmu_regs = atmu_regs + 2; -- msg_regs = (struct rio_msg_regs *)(regs_win + RIO_MSG_REGS_OFFSET); -- -- /* Configure maintenance transaction window */ -- out_be32((void *)&maint_atmu_regs->rowbar, 0x000c0000); -- out_be32((void *)&maint_atmu_regs->rowar, 0x80077015); -- -- maint_win = (u32) ioremap(law_start, RIO_MAINT_WIN_SIZE); -- -- /* Configure outbound doorbell window */ -- out_be32((void *)&dbell_atmu_regs->rowbar, 0x000c0400); -- out_be32((void *)&dbell_atmu_regs->rowar, 0x8004200b); -- mpc85xx_rio_doorbell_init(port); --} ---- a/arch/ppc/syslib/ppc85xx_rio.h -+++ /dev/null -@@ -1,20 +0,0 @@ --/* -- * MPC85xx RapidIO definitions -- * -- * Copyright 2005 MontaVista Software, Inc. -- * Matt Porter -- * -- * 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 __PPC_SYSLIB_PPC85XX_RIO_H --#define __PPC_SYSLIB_PPC85XX_RIO_H -- --#include -- --extern void mpc85xx_rio_setup(int law_start, int law_size); -- --#endif /* __PPC_SYSLIB_PPC85XX_RIO_H */ ---- a/arch/ppc/syslib/ppc8xx_pic.c -+++ b/arch/ppc/syslib/ppc8xx_pic.c -@@ -16,7 +16,7 @@ extern int cpm_get_irq(void); - * the only interrupt controller. Some boards, like the MBX and - * Sandpoint have the 8259 as a secondary controller. Depending - * upon the processor type, the internal controller can have as -- * few as 16 interrups or as many as 64. We could use the -+ * few as 16 interrupts or as many as 64. We could use the - * "clear_bit()" and "set_bit()" functions like other platforms, - * but they are overkill for us. - */ ---- a/arch/ppc/syslib/ppc_sys.c -+++ b/arch/ppc/syslib/ppc_sys.c -@@ -185,7 +185,7 @@ void platform_notify_map(const struct pl - */ - - /* -- Here we'll replace .name pointers with fixed-lenght strings -+ Here we'll replace .name pointers with fixed-length strings - Hereby, this should be called *before* any func stuff triggeded. - */ - void ppc_sys_device_initfunc(void) ---- a/arch/ppc/xmon/start.c -+++ b/arch/ppc/xmon/start.c -@@ -10,7 +10,6 @@ - #include - #include - #include --#include - #include - #include - #include ---- a/drivers/ata/Kconfig -+++ b/drivers/ata/Kconfig -@@ -607,13 +607,23 @@ config PATA_WINBOND_VLB - - config PATA_PLATFORM - tristate "Generic platform device PATA support" -- depends on EMBEDDED || ARCH_RPC -+ depends on EMBEDDED || ARCH_RPC || PPC - help - This option enables support for generic directly connected ATA - devices commonly found on embedded systems. - - If unsure, say N. - -+config PATA_OF_PLATFORM -+ tristate "OpenFirmware platform device PATA support" -+ depends on PATA_PLATFORM && PPC_OF -+ help -+ This option enables support for generic directly connected ATA -+ devices commonly found on embedded systems with OpenFirmware -+ bindings. -+ -+ If unsure, say N. -+ - config PATA_ICSIDE - tristate "Acorn ICS PATA support" - depends on ARM && ARCH_ACORN ---- a/drivers/ata/Makefile -+++ b/drivers/ata/Makefile -@@ -67,6 +67,7 @@ obj-$(CONFIG_PATA_IXP4XX_CF) += pata_ixp - obj-$(CONFIG_PATA_SCC) += pata_scc.o - obj-$(CONFIG_PATA_BF54X) += pata_bf54x.o - obj-$(CONFIG_PATA_PLATFORM) += pata_platform.o -+obj-$(CONFIG_PATA_OF_PLATFORM) += pata_of_platform.o - obj-$(CONFIG_PATA_ICSIDE) += pata_icside.o - # Should be last but two libata driver - obj-$(CONFIG_PATA_ACPI) += pata_acpi.o ---- /dev/null -+++ b/drivers/ata/pata_of_platform.c -@@ -0,0 +1,114 @@ -+/* -+ * OF-platform PATA driver -+ * -+ * Copyright (c) 2007 MontaVista Software, Inc. -+ * Anton Vorontsov -+ * -+ * 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 -+ -+static int __devinit pata_of_platform_probe(struct of_device *ofdev, -+ const struct of_device_id *match) -+{ -+ int ret; -+ struct device_node *dn = ofdev->node; -+ struct resource io_res; -+ struct resource ctl_res; -+ struct resource irq_res; -+ unsigned int reg_shift = 0; -+ int pio_mode = 0; -+ int pio_mask; -+ const u32 *prop; -+ -+ ret = of_address_to_resource(dn, 0, &io_res); -+ if (ret) { -+ dev_err(&ofdev->dev, "can't get IO address from " -+ "device tree\n"); -+ return -EINVAL; -+ } -+ -+ if (of_device_is_compatible(dn, "electra-ide")) { -+ /* Altstatus is really at offset 0x3f6 from the primary window -+ * on electra-ide. Adjust ctl_res and io_res accordingly. -+ */ -+ ctl_res = io_res; -+ ctl_res.start = ctl_res.start+0x3f6; -+ io_res.end = ctl_res.start-1; -+ } else { -+ ret = of_address_to_resource(dn, 1, &ctl_res); -+ if (ret) { -+ dev_err(&ofdev->dev, "can't get CTL address from " -+ "device tree\n"); -+ return -EINVAL; -+ } -+ } -+ -+ ret = of_irq_to_resource(dn, 0, &irq_res); -+ if (ret == NO_IRQ) -+ irq_res.start = irq_res.end = -1; -+ else -+ irq_res.flags = 0; -+ -+ prop = of_get_property(dn, "reg-shift", NULL); -+ if (prop) -+ reg_shift = *prop; -+ -+ prop = of_get_property(dn, "pio-mode", NULL); -+ if (prop) { -+ pio_mode = *prop; -+ if (pio_mode > 6) { -+ dev_err(&ofdev->dev, "invalid pio-mode\n"); -+ return -EINVAL; -+ } -+ } else { -+ dev_info(&ofdev->dev, "pio-mode unspecified, assuming PIO0\n"); -+ } -+ -+ pio_mask = 1 << pio_mode; -+ pio_mask |= (1 << pio_mode) - 1; -+ -+ return __pata_platform_probe(&ofdev->dev, &io_res, &ctl_res, &irq_res, -+ reg_shift, pio_mask); -+} -+ -+static int __devexit pata_of_platform_remove(struct of_device *ofdev) -+{ -+ return __pata_platform_remove(&ofdev->dev); -+} -+ -+static struct of_device_id pata_of_platform_match[] = { -+ { .compatible = "ata-generic", }, -+ { .compatible = "electra-ide", }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, pata_of_platform_match); -+ -+static struct of_platform_driver pata_of_platform_driver = { -+ .name = "pata_of_platform", -+ .match_table = pata_of_platform_match, -+ .probe = pata_of_platform_probe, -+ .remove = __devexit_p(pata_of_platform_remove), -+}; -+ -+static int __init pata_of_platform_init(void) -+{ -+ return of_register_platform_driver(&pata_of_platform_driver); -+} -+module_init(pata_of_platform_init); -+ -+static void __exit pata_of_platform_exit(void) -+{ -+ of_unregister_platform_driver(&pata_of_platform_driver); -+} -+module_exit(pata_of_platform_exit); -+ -+MODULE_DESCRIPTION("OF-platform PATA driver"); -+MODULE_AUTHOR("Anton Vorontsov "); -+MODULE_LICENSE("GPL"); ---- a/drivers/ata/pata_platform.c -+++ b/drivers/ata/pata_platform.c -@@ -93,14 +93,9 @@ static struct ata_port_operations pata_p - }; - - static void pata_platform_setup_port(struct ata_ioports *ioaddr, -- struct pata_platform_info *info) -+ unsigned int shift) - { -- unsigned int shift = 0; -- - /* Fixup the port shift for platforms that need it */ -- if (info && info->ioport_shift) -- shift = info->ioport_shift; -- - ioaddr->data_addr = ioaddr->cmd_addr + (ATA_REG_DATA << shift); - ioaddr->error_addr = ioaddr->cmd_addr + (ATA_REG_ERR << shift); - ioaddr->feature_addr = ioaddr->cmd_addr + (ATA_REG_FEATURE << shift); -@@ -114,8 +109,13 @@ static void pata_platform_setup_port(str - } - - /** -- * pata_platform_probe - attach a platform interface -- * @pdev: platform device -+ * __pata_platform_probe - attach a platform interface -+ * @dev: device -+ * @io_res: Resource representing I/O base -+ * @ctl_res: Resource representing CTL base -+ * @irq_res: Resource representing IRQ and its flags -+ * @ioport_shift: I/O port shift -+ * @__pio_mask: PIO mask - * - * Register a platform bus IDE interface. Such interfaces are PIO and we - * assume do not support IRQ sharing. -@@ -135,42 +135,18 @@ static void pata_platform_setup_port(str - * - * If no IRQ resource is present, PIO polling mode is used instead. - */ --static int __devinit pata_platform_probe(struct platform_device *pdev) -+int __devinit __pata_platform_probe(struct device *dev, -+ struct resource *io_res, -+ struct resource *ctl_res, -+ struct resource *irq_res, -+ unsigned int ioport_shift, -+ int __pio_mask) - { -- struct resource *io_res, *ctl_res; - struct ata_host *host; - struct ata_port *ap; -- struct pata_platform_info *pp_info; - unsigned int mmio; -- int irq; -- -- /* -- * Simple resource validation .. -- */ -- if ((pdev->num_resources != 3) && (pdev->num_resources != 2)) { -- dev_err(&pdev->dev, "invalid number of resources\n"); -- return -EINVAL; -- } -- -- /* -- * Get the I/O base first -- */ -- io_res = platform_get_resource(pdev, IORESOURCE_IO, 0); -- if (io_res == NULL) { -- io_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- if (unlikely(io_res == NULL)) -- return -EINVAL; -- } -- -- /* -- * Then the CTL base -- */ -- ctl_res = platform_get_resource(pdev, IORESOURCE_IO, 1); -- if (ctl_res == NULL) { -- ctl_res = platform_get_resource(pdev, IORESOURCE_MEM, 1); -- if (unlikely(ctl_res == NULL)) -- return -EINVAL; -- } -+ int irq = 0; -+ int irq_flags = 0; - - /* - * Check for MMIO -@@ -181,20 +157,21 @@ static int __devinit pata_platform_probe - /* - * And the IRQ - */ -- irq = platform_get_irq(pdev, 0); -- if (irq < 0) -- irq = 0; /* no irq */ -+ if (irq_res && irq_res->start > 0) { -+ irq = irq_res->start; -+ irq_flags = irq_res->flags; -+ } - - /* - * Now that that's out of the way, wire up the port.. - */ -- host = ata_host_alloc(&pdev->dev, 1); -+ host = ata_host_alloc(dev, 1); - if (!host) - return -ENOMEM; - ap = host->ports[0]; - - ap->ops = &pata_platform_port_ops; -- ap->pio_mask = pio_mask; -+ ap->pio_mask = __pio_mask; - ap->flags |= ATA_FLAG_SLAVE_POSS; - - /* -@@ -209,25 +186,24 @@ static int __devinit pata_platform_probe - * Handle the MMIO case - */ - if (mmio) { -- ap->ioaddr.cmd_addr = devm_ioremap(&pdev->dev, io_res->start, -+ ap->ioaddr.cmd_addr = devm_ioremap(dev, io_res->start, - io_res->end - io_res->start + 1); -- ap->ioaddr.ctl_addr = devm_ioremap(&pdev->dev, ctl_res->start, -+ ap->ioaddr.ctl_addr = devm_ioremap(dev, ctl_res->start, - ctl_res->end - ctl_res->start + 1); - } else { -- ap->ioaddr.cmd_addr = devm_ioport_map(&pdev->dev, io_res->start, -+ ap->ioaddr.cmd_addr = devm_ioport_map(dev, io_res->start, - io_res->end - io_res->start + 1); -- ap->ioaddr.ctl_addr = devm_ioport_map(&pdev->dev, ctl_res->start, -+ ap->ioaddr.ctl_addr = devm_ioport_map(dev, ctl_res->start, - ctl_res->end - ctl_res->start + 1); - } - if (!ap->ioaddr.cmd_addr || !ap->ioaddr.ctl_addr) { -- dev_err(&pdev->dev, "failed to map IO/CTL base\n"); -+ dev_err(dev, "failed to map IO/CTL base\n"); - return -ENOMEM; - } - - ap->ioaddr.altstatus_addr = ap->ioaddr.ctl_addr; - -- pp_info = pdev->dev.platform_data; -- pata_platform_setup_port(&ap->ioaddr, pp_info); -+ pata_platform_setup_port(&ap->ioaddr, ioport_shift); - - ata_port_desc(ap, "%s cmd 0x%llx ctl 0x%llx", mmio ? "mmio" : "ioport", - (unsigned long long)io_res->start, -@@ -235,26 +211,78 @@ static int __devinit pata_platform_probe - - /* activate */ - return ata_host_activate(host, irq, irq ? ata_interrupt : NULL, -- pp_info ? pp_info->irq_flags : 0, -- &pata_platform_sht); -+ irq_flags, &pata_platform_sht); - } -+EXPORT_SYMBOL_GPL(__pata_platform_probe); - - /** -- * pata_platform_remove - unplug a platform interface -- * @pdev: platform device -+ * __pata_platform_remove - unplug a platform interface -+ * @dev: device - * - * A platform bus ATA device has been unplugged. Perform the needed - * cleanup. Also called on module unload for any active devices. - */ --static int __devexit pata_platform_remove(struct platform_device *pdev) -+int __devexit __pata_platform_remove(struct device *dev) - { -- struct device *dev = &pdev->dev; - struct ata_host *host = dev_get_drvdata(dev); - - ata_host_detach(host); - - return 0; - } -+EXPORT_SYMBOL_GPL(__pata_platform_remove); -+ -+static int __devinit pata_platform_probe(struct platform_device *pdev) -+{ -+ struct resource *io_res; -+ struct resource *ctl_res; -+ struct resource *irq_res; -+ struct pata_platform_info *pp_info = pdev->dev.platform_data; -+ -+ /* -+ * Simple resource validation .. -+ */ -+ if ((pdev->num_resources != 3) && (pdev->num_resources != 2)) { -+ dev_err(&pdev->dev, "invalid number of resources\n"); -+ return -EINVAL; -+ } -+ -+ /* -+ * Get the I/O base first -+ */ -+ io_res = platform_get_resource(pdev, IORESOURCE_IO, 0); -+ if (io_res == NULL) { -+ io_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (unlikely(io_res == NULL)) -+ return -EINVAL; -+ } -+ -+ /* -+ * Then the CTL base -+ */ -+ ctl_res = platform_get_resource(pdev, IORESOURCE_IO, 1); -+ if (ctl_res == NULL) { -+ ctl_res = platform_get_resource(pdev, IORESOURCE_MEM, 1); -+ if (unlikely(ctl_res == NULL)) -+ return -EINVAL; -+ } -+ -+ /* -+ * And the IRQ -+ */ -+ irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); -+ if (irq_res) -+ irq_res->flags = pp_info ? pp_info->irq_flags : 0; -+ -+ return __pata_platform_probe(&pdev->dev, io_res, ctl_res, irq_res, -+ pp_info ? pp_info->ioport_shift : 0, -+ pio_mask); -+} -+ -+static int __devexit pata_platform_remove(struct platform_device *pdev) -+{ -+ return __pata_platform_remove(&pdev->dev); -+} - - static struct platform_driver pata_platform_driver = { - .probe = pata_platform_probe, ---- a/drivers/char/hw_random/Kconfig -+++ b/drivers/char/hw_random/Kconfig -@@ -98,7 +98,7 @@ config HW_RANDOM_PASEMI - default HW_RANDOM - ---help--- - This driver provides kernel-side support for the Random Number -- Generator hardware found on PA6T-1682M processor. -+ Generator hardware found on PA Semi PWRficient SoCs. - - To compile this driver as a module, choose M here: the - module will be called pasemi-rng. ---- a/drivers/char/hw_random/pasemi-rng.c -+++ b/drivers/char/hw_random/pasemi-rng.c -@@ -126,10 +126,9 @@ static int __devexit rng_remove(struct o - } - - static struct of_device_id rng_match[] = { -- { -- .compatible = "1682m-rng", -- }, -- {}, -+ { .compatible = "1682m-rng", }, -+ { .compatible = "pasemi,pwrficient-rng", }, -+ { }, - }; - - static struct of_platform_driver rng_driver = { ---- a/drivers/edac/pasemi_edac.c -+++ b/drivers/edac/pasemi_edac.c -@@ -225,7 +225,7 @@ static int __devinit pasemi_edac_probe(s - EDAC_FLAG_NONE; - mci->mod_name = MODULE_NAME; - mci->dev_name = pci_name(pdev); -- mci->ctl_name = "pasemi,1682m-mc"; -+ mci->ctl_name = "pasemi,pwrficient-mc"; - mci->edac_check = pasemi_edac_check; - mci->ctl_page_to_phys = NULL; - pci_read_config_dword(pdev, MCCFG_SCRUB, &scrub); -@@ -297,4 +297,4 @@ module_exit(pasemi_edac_exit); - - MODULE_LICENSE("GPL"); - MODULE_AUTHOR("Egor Martovetsky "); --MODULE_DESCRIPTION("MC support for PA Semi PA6T-1682M memory controller"); -+MODULE_DESCRIPTION("MC support for PA Semi PWRficient memory controller"); ---- a/drivers/macintosh/adb.c -+++ b/drivers/macintosh/adb.c -@@ -35,6 +35,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -82,21 +83,11 @@ struct adb_driver *adb_controller; - BLOCKING_NOTIFIER_HEAD(adb_client_list); - static int adb_got_sleep; - static int adb_inited; --static pid_t adb_probe_task_pid; - static DECLARE_MUTEX(adb_probe_mutex); --static struct completion adb_probe_task_comp; - static int sleepy_trackpad; - static int autopoll_devs; - int __adb_probe_sync; - --#ifdef CONFIG_PM_SLEEP --static void adb_notify_sleep(struct pmu_sleep_notifier *self, int when); --static struct pmu_sleep_notifier adb_sleep_notifier = { -- adb_notify_sleep, -- SLEEP_LEVEL_ADB, --}; --#endif -- - static int adb_scan_bus(void); - static int do_adb_reset_bus(void); - static void adbdev_init(void); -@@ -134,16 +125,6 @@ static void printADBreply(struct adb_req - } - #endif - -- --static __inline__ void adb_wait_ms(unsigned int ms) --{ -- if (current->pid && adb_probe_task_pid && -- adb_probe_task_pid == current->pid) -- msleep(ms); -- else -- mdelay(ms); --} -- - static int adb_scan_bus(void) - { - int i, highFree=0, noMovement; -@@ -248,13 +229,10 @@ static int adb_scan_bus(void) - static int - adb_probe_task(void *x) - { -- strcpy(current->comm, "kadbprobe"); -- - printk(KERN_INFO "adb: starting probe task...\n"); - do_adb_reset_bus(); - printk(KERN_INFO "adb: finished probe task...\n"); - -- adb_probe_task_pid = 0; - up(&adb_probe_mutex); - - return 0; -@@ -263,7 +241,7 @@ adb_probe_task(void *x) - static void - __adb_probe_task(struct work_struct *bullshit) - { -- adb_probe_task_pid = kernel_thread(adb_probe_task, NULL, SIGCHLD | CLONE_KERNEL); -+ kthread_run(adb_probe_task, NULL, "kadbprobe"); - } - - static DECLARE_WORK(adb_reset_work, __adb_probe_task); -@@ -281,6 +259,36 @@ adb_reset_bus(void) - return 0; - } - -+#ifdef CONFIG_PM -+/* -+ * notify clients before sleep -+ */ -+static int adb_suspend(struct platform_device *dev, pm_message_t state) -+{ -+ adb_got_sleep = 1; -+ /* We need to get a lock on the probe thread */ -+ down(&adb_probe_mutex); -+ /* Stop autopoll */ -+ if (adb_controller->autopoll) -+ adb_controller->autopoll(0); -+ blocking_notifier_call_chain(&adb_client_list, ADB_MSG_POWERDOWN, NULL); -+ -+ return 0; -+} -+ -+/* -+ * reset bus after sleep -+ */ -+static int adb_resume(struct platform_device *dev) -+{ -+ adb_got_sleep = 0; -+ up(&adb_probe_mutex); -+ adb_reset_bus(); -+ -+ return 0; -+} -+#endif /* CONFIG_PM */ -+ - int __init adb_init(void) - { - struct adb_driver *driver; -@@ -313,15 +321,12 @@ int __init adb_init(void) - printk(KERN_WARNING "Warning: no ADB interface detected\n"); - adb_controller = NULL; - } else { --#ifdef CONFIG_PM_SLEEP -- pmu_register_sleep_notifier(&adb_sleep_notifier); --#endif /* CONFIG_PM */ - #ifdef CONFIG_PPC - if (machine_is_compatible("AAPL,PowerBook1998") || - machine_is_compatible("PowerBook1,1")) - sleepy_trackpad = 1; - #endif /* CONFIG_PPC */ -- init_completion(&adb_probe_task_comp); -+ - adbdev_init(); - adb_reset_bus(); - } -@@ -330,33 +335,6 @@ int __init adb_init(void) - - __initcall(adb_init); - --#ifdef CONFIG_PM --/* -- * notify clients before sleep and reset bus afterwards -- */ --void --adb_notify_sleep(struct pmu_sleep_notifier *self, int when) --{ -- switch (when) { -- case PBOOK_SLEEP_REQUEST: -- adb_got_sleep = 1; -- /* We need to get a lock on the probe thread */ -- down(&adb_probe_mutex); -- /* Stop autopoll */ -- if (adb_controller->autopoll) -- adb_controller->autopoll(0); -- blocking_notifier_call_chain(&adb_client_list, -- ADB_MSG_POWERDOWN, NULL); -- break; -- case PBOOK_WAKE: -- adb_got_sleep = 0; -- up(&adb_probe_mutex); -- adb_reset_bus(); -- break; -- } --} --#endif /* CONFIG_PM */ -- - static int - do_adb_reset_bus(void) - { -@@ -373,7 +351,7 @@ do_adb_reset_bus(void) - - if (sleepy_trackpad) { - /* Let the trackpad settle down */ -- adb_wait_ms(500); -+ msleep(500); - } - - down(&adb_handler_sem); -@@ -389,7 +367,7 @@ do_adb_reset_bus(void) - - if (sleepy_trackpad) { - /* Let the trackpad settle down */ -- adb_wait_ms(1500); -+ msleep(1500); - } - - if (!ret) { -@@ -413,41 +391,27 @@ adb_poll(void) - adb_controller->poll(); - } - --static void --adb_probe_wakeup(struct adb_request *req) -+static void adb_sync_req_done(struct adb_request *req) - { -- complete(&adb_probe_task_comp); --} -+ struct completion *comp = req->arg; - --/* Static request used during probe */ --static struct adb_request adb_sreq; --static unsigned long adb_sreq_lock; // Use semaphore ! */ -+ complete(comp); -+} - - int - adb_request(struct adb_request *req, void (*done)(struct adb_request *), - int flags, int nbytes, ...) - { - va_list list; -- int i, use_sreq; -+ int i; - int rc; -+ struct completion comp; - - if ((adb_controller == NULL) || (adb_controller->send_request == NULL)) - return -ENXIO; - if (nbytes < 1) - return -EINVAL; -- if (req == NULL && (flags & ADBREQ_NOSEND)) -- return -EINVAL; -- -- if (req == NULL) { -- if (test_and_set_bit(0,&adb_sreq_lock)) { -- printk("adb.c: Warning: contention on static request !\n"); -- return -EPERM; -- } -- req = &adb_sreq; -- flags |= ADBREQ_SYNC; -- use_sreq = 1; -- } else -- use_sreq = 0; -+ - req->nbytes = nbytes+1; - req->done = done; - req->reply_expected = flags & ADBREQ_REPLY; -@@ -460,25 +424,18 @@ adb_request(struct adb_request *req, voi - if (flags & ADBREQ_NOSEND) - return 0; - -- /* Synchronous requests send from the probe thread cause it to -- * block. Beware that the "done" callback will be overriden ! -- */ -- if ((flags & ADBREQ_SYNC) && -- (current->pid && adb_probe_task_pid && -- adb_probe_task_pid == current->pid)) { -- req->done = adb_probe_wakeup; -- rc = adb_controller->send_request(req, 0); -- if (rc || req->complete) -- goto bail; -- wait_for_completion(&adb_probe_task_comp); -- rc = 0; -- goto bail; -- } -- -- rc = adb_controller->send_request(req, flags & ADBREQ_SYNC); --bail: -- if (use_sreq) -- clear_bit(0, &adb_sreq_lock); -+ /* Synchronous requests block using an on-stack completion */ -+ if (flags & ADBREQ_SYNC) { -+ WARN_ON(done); -+ req->done = adb_sync_req_done; -+ req->arg = ∁ -+ init_completion(&comp); -+ } -+ -+ rc = adb_controller->send_request(req, 0); -+ -+ if ((flags & ADBREQ_SYNC) && !rc && !req->complete) -+ wait_for_completion(&comp); - - return rc; - } -@@ -864,7 +821,29 @@ static const struct file_operations adb_ - .release = adb_release, - }; - --static void -+static struct platform_driver adb_pfdrv = { -+ .driver = { -+ .name = "adb", -+ }, -+#ifdef CONFIG_PM -+ .suspend = adb_suspend, -+ .resume = adb_resume, -+#endif -+}; -+ -+static struct platform_device adb_pfdev = { -+ .name = "adb", -+}; -+ -+static int __init -+adb_dummy_probe(struct platform_device *dev) -+{ -+ if (dev == &adb_pfdev) -+ return 0; -+ return -ENODEV; -+} -+ -+static void __init - adbdev_init(void) - { - if (register_chrdev(ADB_MAJOR, "adb", &adb_fops)) { -@@ -876,4 +855,7 @@ adbdev_init(void) - if (IS_ERR(adb_dev_class)) - return; - class_device_create(adb_dev_class, NULL, MKDEV(ADB_MAJOR, 0), NULL, "adb"); -+ -+ platform_device_register(&adb_pfdev); -+ platform_driver_probe(&adb_pfdrv, adb_dummy_probe); - } ---- a/drivers/macintosh/mediabay.c -+++ b/drivers/macintosh/mediabay.c -@@ -20,6 +20,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -35,7 +36,6 @@ - - - #define MB_DEBUG --#define MB_IGNORE_SIGNALS - - #ifdef MB_DEBUG - #define MBDBG(fmt, arg...) printk(KERN_INFO fmt , ## arg) -@@ -622,12 +622,7 @@ static int media_bay_task(void *x) - { - int i; - -- strcpy(current->comm, "media-bay"); --#ifdef MB_IGNORE_SIGNALS -- sigfillset(¤t->blocked); --#endif -- -- for (;;) { -+ while (!kthread_should_stop()) { - for (i = 0; i < media_bay_count; ++i) { - down(&media_bays[i].lock); - if (!media_bays[i].sleeping) -@@ -636,9 +631,8 @@ static int media_bay_task(void *x) - } - - msleep_interruptible(MB_POLL_DELAY); -- if (signal_pending(current)) -- return 0; - } -+ return 0; - } - - static int __devinit media_bay_attach(struct macio_dev *mdev, const struct of_device_id *match) -@@ -699,7 +693,7 @@ static int __devinit media_bay_attach(st - - /* Startup kernel thread */ - if (i == 0) -- kernel_thread(media_bay_task, NULL, CLONE_KERNEL); -+ kthread_run(media_bay_task, NULL, "media-bay"); - - return 0; - ---- a/drivers/macintosh/therm_adt746x.c -+++ b/drivers/macintosh/therm_adt746x.c -@@ -553,6 +553,7 @@ thermostat_init(void) - struct device_node* np; - const u32 *prop; - int i = 0, offset = 0; -+ int err; - - np = of_find_node_by_name(NULL, "fan"); - if (!np) -@@ -612,17 +613,20 @@ thermostat_init(void) - return -ENODEV; - } - -- device_create_file(&of_dev->dev, &dev_attr_sensor1_temperature); -- device_create_file(&of_dev->dev, &dev_attr_sensor2_temperature); -- device_create_file(&of_dev->dev, &dev_attr_sensor1_limit); -- device_create_file(&of_dev->dev, &dev_attr_sensor2_limit); -- device_create_file(&of_dev->dev, &dev_attr_sensor1_location); -- device_create_file(&of_dev->dev, &dev_attr_sensor2_location); -- device_create_file(&of_dev->dev, &dev_attr_limit_adjust); -- device_create_file(&of_dev->dev, &dev_attr_specified_fan_speed); -- device_create_file(&of_dev->dev, &dev_attr_sensor1_fan_speed); -+ err = device_create_file(&of_dev->dev, &dev_attr_sensor1_temperature); -+ err |= device_create_file(&of_dev->dev, &dev_attr_sensor2_temperature); -+ err |= device_create_file(&of_dev->dev, &dev_attr_sensor1_limit); -+ err |= device_create_file(&of_dev->dev, &dev_attr_sensor2_limit); -+ err |= device_create_file(&of_dev->dev, &dev_attr_sensor1_location); -+ err |= device_create_file(&of_dev->dev, &dev_attr_sensor2_location); -+ err |= device_create_file(&of_dev->dev, &dev_attr_limit_adjust); -+ err |= device_create_file(&of_dev->dev, &dev_attr_specified_fan_speed); -+ err |= device_create_file(&of_dev->dev, &dev_attr_sensor1_fan_speed); - if(therm_type == ADT7460) -- device_create_file(&of_dev->dev, &dev_attr_sensor2_fan_speed); -+ err |= device_create_file(&of_dev->dev, &dev_attr_sensor2_fan_speed); -+ if (err) -+ printk(KERN_WARNING -+ "Failed to create tempertaure attribute file(s).\n"); - - #ifndef CONFIG_I2C_POWERMAC - request_module("i2c-powermac"); ---- a/drivers/macintosh/therm_pm72.c -+++ b/drivers/macintosh/therm_pm72.c -@@ -121,6 +121,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -161,7 +162,7 @@ static struct slots_pid_state slots_sta - static int state; - static int cpu_count; - static int cpu_pid_type; --static pid_t ctrl_task; -+static struct task_struct *ctrl_task; - static struct completion ctrl_complete; - static int critical_state; - static int rackmac; -@@ -1156,6 +1157,8 @@ static void do_monitor_cpu_rack(struct c - */ - static int init_cpu_state(struct cpu_pid_state *state, int index) - { -+ int err; -+ - state->index = index; - state->first = 1; - state->rpm = (cpu_pid_type == CPU_PID_TYPE_RACKMAC) ? 4000 : 1000; -@@ -1181,18 +1184,21 @@ static int init_cpu_state(struct cpu_pid - DBG("CPU %d Using %d power history entries\n", index, state->count_power); - - if (index == 0) { -- device_create_file(&of_dev->dev, &dev_attr_cpu0_temperature); -- device_create_file(&of_dev->dev, &dev_attr_cpu0_voltage); -- device_create_file(&of_dev->dev, &dev_attr_cpu0_current); -- device_create_file(&of_dev->dev, &dev_attr_cpu0_exhaust_fan_rpm); -- device_create_file(&of_dev->dev, &dev_attr_cpu0_intake_fan_rpm); -+ err = device_create_file(&of_dev->dev, &dev_attr_cpu0_temperature); -+ err |= device_create_file(&of_dev->dev, &dev_attr_cpu0_voltage); -+ err |= device_create_file(&of_dev->dev, &dev_attr_cpu0_current); -+ err |= device_create_file(&of_dev->dev, &dev_attr_cpu0_exhaust_fan_rpm); -+ err |= device_create_file(&of_dev->dev, &dev_attr_cpu0_intake_fan_rpm); - } else { -- device_create_file(&of_dev->dev, &dev_attr_cpu1_temperature); -- device_create_file(&of_dev->dev, &dev_attr_cpu1_voltage); -- device_create_file(&of_dev->dev, &dev_attr_cpu1_current); -- device_create_file(&of_dev->dev, &dev_attr_cpu1_exhaust_fan_rpm); -- device_create_file(&of_dev->dev, &dev_attr_cpu1_intake_fan_rpm); -- } -+ err = device_create_file(&of_dev->dev, &dev_attr_cpu1_temperature); -+ err |= device_create_file(&of_dev->dev, &dev_attr_cpu1_voltage); -+ err |= device_create_file(&of_dev->dev, &dev_attr_cpu1_current); -+ err |= device_create_file(&of_dev->dev, &dev_attr_cpu1_exhaust_fan_rpm); -+ err |= device_create_file(&of_dev->dev, &dev_attr_cpu1_intake_fan_rpm); -+ } -+ if (err) -+ printk(KERN_WARNING "Failed to create some of the atribute" -+ "files for CPU %d\n", index); - - return 0; - fail: -@@ -1328,6 +1334,7 @@ static int init_backside_state(struct ba - { - struct device_node *u3; - int u3h = 1; /* conservative by default */ -+ int err; - - /* - * There are different PID params for machines with U3 and machines -@@ -1379,8 +1386,11 @@ static int init_backside_state(struct ba - if (state->monitor == NULL) - return -ENODEV; - -- device_create_file(&of_dev->dev, &dev_attr_backside_temperature); -- device_create_file(&of_dev->dev, &dev_attr_backside_fan_pwm); -+ err = device_create_file(&of_dev->dev, &dev_attr_backside_temperature); -+ err |= device_create_file(&of_dev->dev, &dev_attr_backside_fan_pwm); -+ if (err) -+ printk(KERN_WARNING "Failed to create attribute file(s)" -+ " for backside fan\n"); - - return 0; - } -@@ -1491,6 +1501,8 @@ static void do_monitor_drives(struct dri - */ - static int init_drives_state(struct drives_pid_state *state) - { -+ int err; -+ - state->ticks = 1; - state->first = 1; - state->rpm = 1000; -@@ -1499,8 +1511,11 @@ static int init_drives_state(struct driv - if (state->monitor == NULL) - return -ENODEV; - -- device_create_file(&of_dev->dev, &dev_attr_drives_temperature); -- device_create_file(&of_dev->dev, &dev_attr_drives_fan_rpm); -+ err = device_create_file(&of_dev->dev, &dev_attr_drives_temperature); -+ err |= device_create_file(&of_dev->dev, &dev_attr_drives_fan_rpm); -+ if (err) -+ printk(KERN_WARNING "Failed to create attribute file(s)" -+ " for drives bay fan\n"); - - return 0; - } -@@ -1621,7 +1636,9 @@ static int init_dimms_state(struct dimm_ - if (state->monitor == NULL) - return -ENODEV; - -- device_create_file(&of_dev->dev, &dev_attr_dimms_temperature); -+ if (device_create_file(&of_dev->dev, &dev_attr_dimms_temperature)) -+ printk(KERN_WARNING "Failed to create attribute file" -+ " for DIMM temperature\n"); - - return 0; - } -@@ -1731,6 +1748,8 @@ static void do_monitor_slots(struct slot - */ - static int init_slots_state(struct slots_pid_state *state) - { -+ int err; -+ - state->ticks = 1; - state->first = 1; - state->pwm = 50; -@@ -1739,8 +1758,11 @@ static int init_slots_state(struct slots - if (state->monitor == NULL) - return -ENODEV; - -- device_create_file(&of_dev->dev, &dev_attr_slots_temperature); -- device_create_file(&of_dev->dev, &dev_attr_slots_fan_pwm); -+ err = device_create_file(&of_dev->dev, &dev_attr_slots_temperature); -+ err |= device_create_file(&of_dev->dev, &dev_attr_slots_fan_pwm); -+ if (err) -+ printk(KERN_WARNING "Failed to create attribute file(s)" -+ " for slots bay fan\n"); - - return 0; - } -@@ -1779,8 +1801,6 @@ static int call_critical_overtemp(void) - */ - static int main_control_loop(void *x) - { -- daemonize("kfand"); -- - DBG("main_control_loop started\n"); - - down(&driver_lock); -@@ -1956,7 +1976,7 @@ static void start_control_loops(void) - { - init_completion(&ctrl_complete); - -- ctrl_task = kernel_thread(main_control_loop, NULL, SIGCHLD | CLONE_KERNEL); -+ ctrl_task = kthread_run(main_control_loop, NULL, "kfand"); - } - - /* -@@ -1964,7 +1984,7 @@ static void start_control_loops(void) - */ - static void stop_control_loops(void) - { -- if (ctrl_task != 0) -+ if (ctrl_task) - wait_for_completion(&ctrl_complete); - } - ---- a/drivers/macintosh/therm_windtunnel.c -+++ b/drivers/macintosh/therm_windtunnel.c -@@ -36,6 +36,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -61,8 +62,7 @@ I2C_CLIENT_INSMOD; - - static struct { - volatile int running; -- struct completion completion; -- pid_t poll_task; -+ struct task_struct *poll_task; - - struct semaphore lock; - struct of_device *of_dev; -@@ -223,6 +223,7 @@ static void - setup_hardware( void ) - { - int val; -+ int err; - - /* save registers (if we unload the module) */ - x.r0 = read_reg( x.fan, 0x00, 1 ); -@@ -265,8 +266,11 @@ setup_hardware( void ) - x.upind = -1; - /* tune_fan( fan_up_table[x.upind].fan_setting ); */ - -- device_create_file( &x.of_dev->dev, &dev_attr_cpu_temperature ); -- device_create_file( &x.of_dev->dev, &dev_attr_case_temperature ); -+ err = device_create_file( &x.of_dev->dev, &dev_attr_cpu_temperature ); -+ err |= device_create_file( &x.of_dev->dev, &dev_attr_case_temperature ); -+ if (err) -+ printk(KERN_WARNING -+ "Failed to create temperature attribute file(s).\n"); - } - - static void -@@ -282,27 +286,27 @@ restore_regs( void ) - write_reg( x.fan, 0x00, x.r0, 1 ); - } - --static int --control_loop( void *dummy ) -+static int control_loop(void *dummy) - { -- daemonize("g4fand"); -- -- down( &x.lock ); -+ down(&x.lock); - setup_hardware(); -+ up(&x.lock); - -- while( x.running ) { -- up( &x.lock ); -- -+ for (;;) { - msleep_interruptible(8000); -- -- down( &x.lock ); -+ if (kthread_should_stop()) -+ break; -+ -+ down(&x.lock); - poll_temp(); -+ up(&x.lock); - } - -+ down(&x.lock); - restore_regs(); -- up( &x.lock ); -+ up(&x.lock); - -- complete_and_exit( &x.completion, 0 ); -+ return 0; - } - - -@@ -322,8 +326,7 @@ do_attach( struct i2c_adapter *adapter ) - ret = i2c_probe( adapter, &addr_data, &do_probe ); - if( x.thermostat && x.fan ) { - x.running = 1; -- init_completion( &x.completion ); -- x.poll_task = kernel_thread( control_loop, NULL, SIGCHLD | CLONE_KERNEL ); -+ x.poll_task = kthread_run(control_loop, NULL, "g4fand"); - } - } - return ret; -@@ -339,7 +342,8 @@ do_detach( struct i2c_client *client ) - else { - if( x.running ) { - x.running = 0; -- wait_for_completion( &x.completion ); -+ kthread_stop(x.poll_task); -+ x.poll_task = NULL; - } - if( client == x.thermostat ) - x.thermostat = NULL; ---- a/drivers/macintosh/via-pmu-backlight.c -+++ b/drivers/macintosh/via-pmu-backlight.c -@@ -22,7 +22,7 @@ static u8 bl_curve[FB_BACKLIGHT_LEVELS]; - - static void pmu_backlight_init_curve(u8 off, u8 min, u8 max) - { -- unsigned int i, flat, count, range = (max - min); -+ int i, flat, count, range = (max - min); - - bl_curve[0] = off; - -@@ -68,17 +68,11 @@ static int pmu_backlight_get_level_brigh - return pmulevel; - } - --static int pmu_backlight_update_status(struct backlight_device *bd) -+static int __pmu_backlight_update_status(struct backlight_device *bd) - { - struct adb_request req; -- unsigned long flags; - int level = bd->props.brightness; - -- spin_lock_irqsave(&pmu_backlight_lock, flags); -- -- /* Don't update brightness when sleeping */ -- if (sleeping) -- goto out; - - if (bd->props.power != FB_BLANK_UNBLANK || - bd->props.fb_blank != FB_BLANK_UNBLANK) -@@ -99,12 +93,23 @@ static int pmu_backlight_update_status(s - pmu_wait_complete(&req); - } - --out: -- spin_unlock_irqrestore(&pmu_backlight_lock, flags); -- - return 0; - } - -+static int pmu_backlight_update_status(struct backlight_device *bd) -+{ -+ unsigned long flags; -+ int rc = 0; -+ -+ spin_lock_irqsave(&pmu_backlight_lock, flags); -+ /* Don't update brightness when sleeping */ -+ if (!sleeping) -+ rc = __pmu_backlight_update_status(bd); -+ spin_unlock_irqrestore(&pmu_backlight_lock, flags); -+ return rc; -+} -+ -+ - static int pmu_backlight_get_brightness(struct backlight_device *bd) - { - return bd->props.brightness; -@@ -123,6 +128,16 @@ void pmu_backlight_set_sleep(int sleep) - - spin_lock_irqsave(&pmu_backlight_lock, flags); - sleeping = sleep; -+ if (pmac_backlight) { -+ if (sleep) { -+ struct adb_request req; -+ -+ pmu_request(&req, NULL, 2, PMU_POWER_CTRL, -+ PMU_POW_BACKLIGHT | PMU_POW_OFF); -+ pmu_wait_complete(&req); -+ } else -+ __pmu_backlight_update_status(pmac_backlight); -+ } - spin_unlock_irqrestore(&pmu_backlight_lock, flags); - } - #endif /* CONFIG_PM */ -@@ -148,8 +163,8 @@ void __init pmu_backlight_init() - - bd = backlight_device_register(name, NULL, NULL, &pmu_backlight_data); - if (IS_ERR(bd)) { -- printk("pmubl: Backlight registration failed\n"); -- goto error; -+ printk(KERN_ERR "PMU Backlight registration failed\n"); -+ return; - } - bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1; - pmu_backlight_init_curve(0x7F, 0x46, 0x0E); -@@ -171,10 +186,5 @@ void __init pmu_backlight_init() - bd->props.power = FB_BLANK_UNBLANK; - backlight_update_status(bd); - -- printk("pmubl: Backlight initialized (%s)\n", name); -- -- return; -- --error: -- return; -+ printk(KERN_INFO "PMU Backlight initialized (%s)\n", name); - } ---- a/drivers/macintosh/via-pmu.c -+++ b/drivers/macintosh/via-pmu.c -@@ -10,13 +10,11 @@ - * - * Copyright (C) 1998 Paul Mackerras and Fabio Riccardi. - * Copyright (C) 2001-2002 Benjamin Herrenschmidt -+ * Copyright (C) 2006-2007 Johannes Berg - * - * THIS DRIVER IS BECOMING A TOTAL MESS ! - * - Cleanup atomically disabling reply to PMU events after - * a sleep or a freq. switch -- * - Move sleep code out of here to pmac_pm, merge into new -- * common PM infrastructure -- * - Save/Restore PCI space properly - * - */ - #include -@@ -33,7 +31,6 @@ - #include - #include - #include --#include - #include - #include - #include -@@ -65,9 +62,7 @@ - #include "via-pmu-event.h" - - /* Some compile options */ --#undef SUSPEND_USES_PMU --#define DEBUG_SLEEP --#undef HACKED_PCI_SAVE -+#undef DEBUG_SLEEP - - /* Misc minor number allocated for /dev/pmu */ - #define PMU_MINOR 154 -@@ -152,12 +147,9 @@ static spinlock_t pmu_lock; - static u8 pmu_intr_mask; - static int pmu_version; - static int drop_interrupts; --#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32) -+#if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32) - static int option_lid_wakeup = 1; --#endif /* CONFIG_PM_SLEEP && CONFIG_PPC32 */ --#if (defined(CONFIG_PM_SLEEP)&&defined(CONFIG_PPC32))||defined(CONFIG_PMAC_BACKLIGHT_LEGACY) --static int sleep_in_progress; --#endif -+#endif /* CONFIG_SUSPEND && CONFIG_PPC32 */ - static unsigned long async_req_locks; - static unsigned int pmu_irq_stats[11]; - -@@ -177,7 +169,6 @@ static struct proc_dir_entry *proc_pmu_b - - int __fake_sleep; - int asleep; --BLOCKING_NOTIFIER_HEAD(sleep_notifier_list); - - #ifdef CONFIG_ADB - static int adb_dev_map; -@@ -224,7 +215,7 @@ extern void enable_kernel_fp(void); - - #ifdef DEBUG_SLEEP - int pmu_polled_request(struct adb_request *req); --int pmu_wink(struct adb_request *req); -+void pmu_blink(int n); - #endif - - /* -@@ -875,7 +866,7 @@ proc_read_options(char *page, char **sta - { - char *p = page; - --#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32) -+#if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32) - if (pmu_kind == PMU_KEYLARGO_BASED && - pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) >= 0) - p += sprintf(p, "lid_wakeup=%d\n", option_lid_wakeup); -@@ -916,7 +907,7 @@ proc_write_options(struct file *file, co - *(val++) = 0; - while(*val == ' ') - val++; --#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32) -+#if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32) - if (pmu_kind == PMU_KEYLARGO_BASED && - pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) >= 0) - if (!strcmp(label, "lid_wakeup")) -@@ -1256,9 +1247,7 @@ void - pmu_suspend(void) - { - unsigned long flags; --#ifdef SUSPEND_USES_PMU -- struct adb_request *req; --#endif -+ - if (!via) - return; - -@@ -1276,17 +1265,10 @@ pmu_suspend(void) - via_pmu_interrupt(0, NULL); - spin_lock_irqsave(&pmu_lock, flags); - if (!adb_int_pending && pmu_state == idle && !req_awaiting_reply) { --#ifdef SUSPEND_USES_PMU -- pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, 0); -- spin_unlock_irqrestore(&pmu_lock, flags); -- while(!req.complete) -- pmu_poll(); --#else /* SUSPEND_USES_PMU */ - if (gpio_irq >= 0) - disable_irq_nosync(gpio_irq); - out_8(&via[IER], CB1_INT | IER_CLR); - spin_unlock_irqrestore(&pmu_lock, flags); --#endif /* SUSPEND_USES_PMU */ - break; - } - } while (1); -@@ -1307,18 +1289,11 @@ pmu_resume(void) - return; - } - adb_int_pending = 1; --#ifdef SUSPEND_USES_PMU -- pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, pmu_intr_mask); -- spin_unlock_irqrestore(&pmu_lock, flags); -- while(!req.complete) -- pmu_poll(); --#else /* SUSPEND_USES_PMU */ - if (gpio_irq >= 0) - enable_irq(gpio_irq); - out_8(&via[IER], CB1_INT | IER_SET); - spin_unlock_irqrestore(&pmu_lock, flags); - pmu_poll(); --#endif /* SUSPEND_USES_PMU */ - } - - /* Interrupt data could be the result data from an ADB cmd */ -@@ -1738,228 +1713,7 @@ pmu_present(void) - return via != 0; - } - --#ifdef CONFIG_PM_SLEEP -- --static LIST_HEAD(sleep_notifiers); -- --int --pmu_register_sleep_notifier(struct pmu_sleep_notifier *n) --{ -- struct list_head *list; -- struct pmu_sleep_notifier *notifier; -- -- for (list = sleep_notifiers.next; list != &sleep_notifiers; -- list = list->next) { -- notifier = list_entry(list, struct pmu_sleep_notifier, list); -- if (n->priority > notifier->priority) -- break; -- } -- __list_add(&n->list, list->prev, list); -- return 0; --} --EXPORT_SYMBOL(pmu_register_sleep_notifier); -- --int --pmu_unregister_sleep_notifier(struct pmu_sleep_notifier* n) --{ -- if (n->list.next == 0) -- return -ENOENT; -- list_del(&n->list); -- n->list.next = NULL; -- return 0; --} --EXPORT_SYMBOL(pmu_unregister_sleep_notifier); --#endif /* CONFIG_PM_SLEEP */ -- --#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32) -- --/* Sleep is broadcast last-to-first */ --static void broadcast_sleep(int when) --{ -- struct list_head *list; -- struct pmu_sleep_notifier *notifier; -- -- for (list = sleep_notifiers.prev; list != &sleep_notifiers; -- list = list->prev) { -- notifier = list_entry(list, struct pmu_sleep_notifier, list); -- notifier->notifier_call(notifier, when); -- } --} -- --/* Wake is broadcast first-to-last */ --static void broadcast_wake(void) --{ -- struct list_head *list; -- struct pmu_sleep_notifier *notifier; -- -- for (list = sleep_notifiers.next; list != &sleep_notifiers; -- list = list->next) { -- notifier = list_entry(list, struct pmu_sleep_notifier, list); -- notifier->notifier_call(notifier, PBOOK_WAKE); -- } --} -- --/* -- * This struct is used to store config register values for -- * PCI devices which may get powered off when we sleep. -- */ --static struct pci_save { --#ifndef HACKED_PCI_SAVE -- u16 command; -- u16 cache_lat; -- u16 intr; -- u32 rom_address; --#else -- u32 config[16]; --#endif --} *pbook_pci_saves; --static int pbook_npci_saves; -- --static void --pbook_alloc_pci_save(void) --{ -- int npci; -- struct pci_dev *pd = NULL; -- -- npci = 0; -- while ((pd = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) { -- ++npci; -- } -- if (npci == 0) -- return; -- pbook_pci_saves = (struct pci_save *) -- kmalloc(npci * sizeof(struct pci_save), GFP_KERNEL); -- pbook_npci_saves = npci; --} -- --static void --pbook_free_pci_save(void) --{ -- if (pbook_pci_saves == NULL) -- return; -- kfree(pbook_pci_saves); -- pbook_pci_saves = NULL; -- pbook_npci_saves = 0; --} -- --static void --pbook_pci_save(void) --{ -- struct pci_save *ps = pbook_pci_saves; -- struct pci_dev *pd = NULL; -- int npci = pbook_npci_saves; -- -- if (ps == NULL) -- return; -- -- while ((pd = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) { -- if (npci-- == 0) { -- pci_dev_put(pd); -- return; -- } --#ifndef HACKED_PCI_SAVE -- pci_read_config_word(pd, PCI_COMMAND, &ps->command); -- pci_read_config_word(pd, PCI_CACHE_LINE_SIZE, &ps->cache_lat); -- pci_read_config_word(pd, PCI_INTERRUPT_LINE, &ps->intr); -- pci_read_config_dword(pd, PCI_ROM_ADDRESS, &ps->rom_address); --#else -- int i; -- for (i=1;i<16;i++) -- pci_read_config_dword(pd, i<<4, &ps->config[i]); --#endif -- ++ps; -- } --} -- --/* For this to work, we must take care of a few things: If gmac was enabled -- * during boot, it will be in the pci dev list. If it's disabled at this point -- * (and it will probably be), then you can't access it's config space. -- */ --static void --pbook_pci_restore(void) --{ -- u16 cmd; -- struct pci_save *ps = pbook_pci_saves - 1; -- struct pci_dev *pd = NULL; -- int npci = pbook_npci_saves; -- int j; -- -- while ((pd = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) { --#ifdef HACKED_PCI_SAVE -- int i; -- if (npci-- == 0) { -- pci_dev_put(pd); -- return; -- } -- ps++; -- for (i=2;i<16;i++) -- pci_write_config_dword(pd, i<<4, ps->config[i]); -- pci_write_config_dword(pd, 4, ps->config[1]); --#else -- if (npci-- == 0) -- return; -- ps++; -- if (ps->command == 0) -- continue; -- pci_read_config_word(pd, PCI_COMMAND, &cmd); -- if ((ps->command & ~cmd) == 0) -- continue; -- switch (pd->hdr_type) { -- case PCI_HEADER_TYPE_NORMAL: -- for (j = 0; j < 6; ++j) -- pci_write_config_dword(pd, -- PCI_BASE_ADDRESS_0 + j*4, -- pd->resource[j].start); -- pci_write_config_dword(pd, PCI_ROM_ADDRESS, -- ps->rom_address); -- pci_write_config_word(pd, PCI_CACHE_LINE_SIZE, -- ps->cache_lat); -- pci_write_config_word(pd, PCI_INTERRUPT_LINE, -- ps->intr); -- pci_write_config_word(pd, PCI_COMMAND, ps->command); -- break; -- } --#endif -- } --} -- --#ifdef DEBUG_SLEEP --/* N.B. This doesn't work on the 3400 */ --void --pmu_blink(int n) --{ -- struct adb_request req; -- -- memset(&req, 0, sizeof(req)); -- -- for (; n > 0; --n) { -- req.nbytes = 4; -- req.done = NULL; -- req.data[0] = 0xee; -- req.data[1] = 4; -- req.data[2] = 0; -- req.data[3] = 1; -- req.reply[0] = ADB_RET_OK; -- req.reply_len = 1; -- req.reply_expected = 0; -- pmu_polled_request(&req); -- mdelay(50); -- req.nbytes = 4; -- req.done = NULL; -- req.data[0] = 0xee; -- req.data[1] = 4; -- req.data[2] = 0; -- req.data[3] = 0; -- req.reply[0] = ADB_RET_OK; -- req.reply_len = 1; -- req.reply_expected = 0; -- pmu_polled_request(&req); -- mdelay(50); -- } -- mdelay(50); --} --#endif -- -+#if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32) - /* - * Put the powerbook to sleep. - */ -@@ -1994,134 +1748,6 @@ restore_via_state(void) - out_8(&via[IER], IER_SET | SR_INT | CB1_INT); - } - --extern void pmu_backlight_set_sleep(int sleep); -- --static int --pmac_suspend_devices(void) --{ -- int ret; -- -- pm_prepare_console(); -- -- /* Notify old-style device drivers */ -- broadcast_sleep(PBOOK_SLEEP_REQUEST); -- -- /* Sync the disks. */ -- /* XXX It would be nice to have some way to ensure that -- * nobody is dirtying any new buffers while we wait. That -- * could be achieved using the refrigerator for processes -- * that swsusp uses -- */ -- sys_sync(); -- -- broadcast_sleep(PBOOK_SLEEP_NOW); -- -- /* Send suspend call to devices, hold the device core's dpm_sem */ -- ret = device_suspend(PMSG_SUSPEND); -- if (ret) { -- broadcast_wake(); -- printk(KERN_ERR "Driver sleep failed\n"); -- return -EBUSY; -- } -- --#ifdef CONFIG_PMAC_BACKLIGHT -- /* Tell backlight code not to muck around with the chip anymore */ -- pmu_backlight_set_sleep(1); --#endif -- -- /* Call platform functions marked "on sleep" */ -- pmac_pfunc_i2c_suspend(); -- pmac_pfunc_base_suspend(); -- -- /* Stop preemption */ -- preempt_disable(); -- -- /* Make sure the decrementer won't interrupt us */ -- asm volatile("mtdec %0" : : "r" (0x7fffffff)); -- /* Make sure any pending DEC interrupt occurring while we did -- * the above didn't re-enable the DEC */ -- mb(); -- asm volatile("mtdec %0" : : "r" (0x7fffffff)); -- -- /* We can now disable MSR_EE. This code of course works properly only -- * on UP machines... For SMP, if we ever implement sleep, we'll have to -- * stop the "other" CPUs way before we do all that stuff. -- */ -- local_irq_disable(); -- -- /* Broadcast power down irq -- * This isn't that useful in most cases (only directly wired devices can -- * use this but still... This will take care of sysdev's as well, so -- * we exit from here with local irqs disabled and PIC off. -- */ -- ret = device_power_down(PMSG_SUSPEND); -- if (ret) { -- wakeup_decrementer(); -- local_irq_enable(); -- preempt_enable(); -- device_resume(); -- broadcast_wake(); -- printk(KERN_ERR "Driver powerdown failed\n"); -- return -EBUSY; -- } -- -- /* Wait for completion of async requests */ -- while (!batt_req.complete) -- pmu_poll(); -- -- /* Giveup the lazy FPU & vec so we don't have to back them -- * up from the low level code -- */ -- enable_kernel_fp(); -- --#ifdef CONFIG_ALTIVEC -- if (cpu_has_feature(CPU_FTR_ALTIVEC)) -- enable_kernel_altivec(); --#endif /* CONFIG_ALTIVEC */ -- -- return 0; --} -- --static int --pmac_wakeup_devices(void) --{ -- mdelay(100); -- --#ifdef CONFIG_PMAC_BACKLIGHT -- /* Tell backlight code it can use the chip again */ -- pmu_backlight_set_sleep(0); --#endif -- -- /* Power back up system devices (including the PIC) */ -- device_power_up(); -- -- /* Force a poll of ADB interrupts */ -- adb_int_pending = 1; -- via_pmu_interrupt(0, NULL); -- -- /* Restart jiffies & scheduling */ -- wakeup_decrementer(); -- -- /* Re-enable local CPU interrupts */ -- local_irq_enable(); -- mdelay(10); -- preempt_enable(); -- -- /* Call platform functions marked "on wake" */ -- pmac_pfunc_base_resume(); -- pmac_pfunc_i2c_resume(); -- -- /* Resume devices */ -- device_resume(); -- -- /* Notify old style drivers */ -- broadcast_wake(); -- -- pm_restore_console(); -- -- return 0; --} -- - #define GRACKLE_PM (1<<7) - #define GRACKLE_DOZE (1<<5) - #define GRACKLE_NAP (1<<4) -@@ -2132,19 +1758,12 @@ static int powerbook_sleep_grackle(void) - unsigned long save_l2cr; - unsigned short pmcr1; - struct adb_request req; -- int ret; - struct pci_dev *grackle; - - grackle = pci_get_bus_and_slot(0, 0); - if (!grackle) - return -ENODEV; - -- ret = pmac_suspend_devices(); -- if (ret) { -- printk(KERN_ERR "Sleep rejected by devices\n"); -- return ret; -- } -- - /* Turn off various things. Darwin does some retry tests here... */ - pmu_request(&req, NULL, 2, PMU_POWER_CTRL0, PMU_POW0_OFF|PMU_POW0_HARD_DRIVE); - pmu_wait_complete(&req); -@@ -2207,8 +1826,6 @@ static int powerbook_sleep_grackle(void) - PMU_POW_ON|PMU_POW_BACKLIGHT|PMU_POW_CHARGER|PMU_POW_IRLED|PMU_POW_MEDIABAY); - pmu_wait_complete(&req); - -- pmac_wakeup_devices(); -- - return 0; - } - -@@ -2218,7 +1835,6 @@ powerbook_sleep_Core99(void) - unsigned long save_l2cr; - unsigned long save_l3cr; - struct adb_request req; -- int ret; - - if (pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) < 0) { - printk(KERN_ERR "Sleep mode not supported on this machine\n"); -@@ -2228,12 +1844,6 @@ powerbook_sleep_Core99(void) - if (num_online_cpus() > 1 || cpu_is_offline(0)) - return -EAGAIN; - -- ret = pmac_suspend_devices(); -- if (ret) { -- printk(KERN_ERR "Sleep rejected by devices\n"); -- return ret; -- } -- - /* Stop environment and ADB interrupts */ - pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, 0); - pmu_wait_complete(&req); -@@ -2304,45 +1914,33 @@ powerbook_sleep_Core99(void) - /* Restore LPJ, cpufreq will adjust the cpu frequency */ - loops_per_jiffy /= 2; - -- pmac_wakeup_devices(); -- - return 0; - } - - #define PB3400_MEM_CTRL 0xf8000000 - #define PB3400_MEM_CTRL_SLEEP 0x70 - --static int --powerbook_sleep_3400(void) -+static void __iomem *pb3400_mem_ctrl; -+ -+static void powerbook_sleep_init_3400(void) - { -- int ret, i, x; -+ /* map in the memory controller registers */ -+ pb3400_mem_ctrl = ioremap(PB3400_MEM_CTRL, 0x100); -+ if (pb3400_mem_ctrl == NULL) -+ printk(KERN_WARNING "ioremap failed: sleep won't be possible"); -+} -+ -+static int powerbook_sleep_3400(void) -+{ -+ int i, x; - unsigned int hid0; -- unsigned long p; -+ unsigned long msr; - struct adb_request sleep_req; -- void __iomem *mem_ctrl; - unsigned int __iomem *mem_ctrl_sleep; - -- /* first map in the memory controller registers */ -- mem_ctrl = ioremap(PB3400_MEM_CTRL, 0x100); -- if (mem_ctrl == NULL) { -- printk("powerbook_sleep_3400: ioremap failed\n"); -+ if (pb3400_mem_ctrl == NULL) - return -ENOMEM; -- } -- mem_ctrl_sleep = mem_ctrl + PB3400_MEM_CTRL_SLEEP; -- -- /* Allocate room for PCI save */ -- pbook_alloc_pci_save(); -- -- ret = pmac_suspend_devices(); -- if (ret) { -- pbook_free_pci_save(); -- iounmap(mem_ctrl); -- printk(KERN_ERR "Sleep rejected by devices\n"); -- return ret; -- } -- -- /* Save the state of PCI config space for some slots */ -- pbook_pci_save(); -+ mem_ctrl_sleep = pb3400_mem_ctrl + PB3400_MEM_CTRL_SLEEP; - - /* Set the memory controller to keep the memory refreshed - while we're asleep */ -@@ -2357,41 +1955,34 @@ powerbook_sleep_3400(void) - - /* Ask the PMU to put us to sleep */ - pmu_request(&sleep_req, NULL, 5, PMU_SLEEP, 'M', 'A', 'T', 'T'); -- while (!sleep_req.complete) -- mb(); -+ pmu_wait_complete(&sleep_req); -+ pmu_unlock(); - -- pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,1); -+ pmac_call_feature(PMAC_FTR_SLEEP_STATE, NULL, 0, 1); - -- /* displacement-flush the L2 cache - necessary? */ -- for (p = KERNELBASE; p < KERNELBASE + 0x100000; p += 0x1000) -- i = *(volatile int *)p; - asleep = 1; - - /* Put the CPU into sleep mode */ - hid0 = mfspr(SPRN_HID0); - hid0 = (hid0 & ~(HID0_NAP | HID0_DOZE)) | HID0_SLEEP; - mtspr(SPRN_HID0, hid0); -- mtmsr(mfmsr() | MSR_POW | MSR_EE); -- udelay(10); -+ local_irq_enable(); -+ msr = mfmsr() | MSR_POW; -+ while (asleep) { -+ mb(); -+ mtmsr(msr); -+ isync(); -+ } -+ local_irq_disable(); - - /* OK, we're awake again, start restoring things */ - out_be32(mem_ctrl_sleep, 0x3f); -- pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,0); -- pbook_pci_restore(); -- pmu_unlock(); -- -- /* wait for the PMU interrupt sequence to complete */ -- while (asleep) -- mb(); -- -- pmac_wakeup_devices(); -- pbook_free_pci_save(); -- iounmap(mem_ctrl); -+ pmac_call_feature(PMAC_FTR_SLEEP_STATE, NULL, 0, 0); - - return 0; - } - --#endif /* CONFIG_PM_SLEEP && CONFIG_PPC32 */ -+#endif /* CONFIG_SUSPEND && CONFIG_PPC32 */ - - /* - * Support for /dev/pmu device -@@ -2548,7 +2139,6 @@ pmu_release(struct inode *inode, struct - struct pmu_private *pp = file->private_data; - unsigned long flags; - -- lock_kernel(); - if (pp != 0) { - file->private_data = NULL; - spin_lock_irqsave(&all_pvt_lock, flags); -@@ -2562,10 +2152,96 @@ pmu_release(struct inode *inode, struct - - kfree(pp); - } -- unlock_kernel(); - return 0; - } - -+#if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32) -+static void pmac_suspend_disable_irqs(void) -+{ -+ /* Call platform functions marked "on sleep" */ -+ pmac_pfunc_i2c_suspend(); -+ pmac_pfunc_base_suspend(); -+} -+ -+static int powerbook_sleep(suspend_state_t state) -+{ -+ int error = 0; -+ -+ /* Wait for completion of async requests */ -+ while (!batt_req.complete) -+ pmu_poll(); -+ -+ /* Giveup the lazy FPU & vec so we don't have to back them -+ * up from the low level code -+ */ -+ enable_kernel_fp(); -+ -+#ifdef CONFIG_ALTIVEC -+ if (cpu_has_feature(CPU_FTR_ALTIVEC)) -+ enable_kernel_altivec(); -+#endif /* CONFIG_ALTIVEC */ -+ -+ switch (pmu_kind) { -+ case PMU_OHARE_BASED: -+ error = powerbook_sleep_3400(); -+ break; -+ case PMU_HEATHROW_BASED: -+ case PMU_PADDINGTON_BASED: -+ error = powerbook_sleep_grackle(); -+ break; -+ case PMU_KEYLARGO_BASED: -+ error = powerbook_sleep_Core99(); -+ break; -+ default: -+ return -ENOSYS; -+ } -+ -+ if (error) -+ return error; -+ -+ mdelay(100); -+ -+ return 0; -+} -+ -+static void pmac_suspend_enable_irqs(void) -+{ -+ /* Force a poll of ADB interrupts */ -+ adb_int_pending = 1; -+ via_pmu_interrupt(0, NULL); -+ -+ mdelay(10); -+ -+ /* Call platform functions marked "on wake" */ -+ pmac_pfunc_base_resume(); -+ pmac_pfunc_i2c_resume(); -+} -+ -+static int pmu_sleep_valid(suspend_state_t state) -+{ -+ return state == PM_SUSPEND_MEM -+ && (pmac_call_feature(PMAC_FTR_SLEEP_STATE, NULL, 0, -1) >= 0); -+} -+ -+static struct platform_suspend_ops pmu_pm_ops = { -+ .enter = powerbook_sleep, -+ .valid = pmu_sleep_valid, -+}; -+ -+static int register_pmu_pm_ops(void) -+{ -+ if (pmu_kind == PMU_OHARE_BASED) -+ powerbook_sleep_init_3400(); -+ ppc_md.suspend_disable_irqs = pmac_suspend_disable_irqs; -+ ppc_md.suspend_enable_irqs = pmac_suspend_enable_irqs; -+ suspend_set_ops(&pmu_pm_ops); -+ -+ return 0; -+} -+ -+device_initcall(register_pmu_pm_ops); -+#endif -+ - static int - pmu_ioctl(struct inode * inode, struct file *filp, - u_int cmd, u_long arg) -@@ -2574,35 +2250,15 @@ pmu_ioctl(struct inode * inode, struct f - int error = -EINVAL; - - switch (cmd) { --#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32) - case PMU_IOC_SLEEP: - if (!capable(CAP_SYS_ADMIN)) - return -EACCES; -- if (sleep_in_progress) -- return -EBUSY; -- sleep_in_progress = 1; -- switch (pmu_kind) { -- case PMU_OHARE_BASED: -- error = powerbook_sleep_3400(); -- break; -- case PMU_HEATHROW_BASED: -- case PMU_PADDINGTON_BASED: -- error = powerbook_sleep_grackle(); -- break; -- case PMU_KEYLARGO_BASED: -- error = powerbook_sleep_Core99(); -- break; -- default: -- error = -ENOSYS; -- } -- sleep_in_progress = 0; -- break; -+ return pm_suspend(PM_SUSPEND_MEM); - case PMU_IOC_CAN_SLEEP: -- if (pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) < 0) -+ if (pmac_call_feature(PMAC_FTR_SLEEP_STATE, NULL, 0, -1) < 0) - return put_user(0, argp); - else - return put_user(1, argp); --#endif /* CONFIG_PM_SLEEP && CONFIG_PPC32 */ - - #ifdef CONFIG_PMAC_BACKLIGHT_LEGACY - /* Compatibility ioctl's for backlight */ -@@ -2610,9 +2266,6 @@ pmu_ioctl(struct inode * inode, struct f - { - int brightness; - -- if (sleep_in_progress) -- return -EBUSY; -- - brightness = pmac_backlight_get_legacy_brightness(); - if (brightness < 0) - return brightness; -@@ -2624,9 +2277,6 @@ pmu_ioctl(struct inode * inode, struct f - { - int brightness; - -- if (sleep_in_progress) -- return -EBUSY; -- - error = get_user(brightness, argp); - if (error) - return error; -@@ -2751,15 +2401,43 @@ pmu_polled_request(struct adb_request *r - local_irq_restore(flags); - return 0; - } --#endif /* DEBUG_SLEEP */ - -+/* N.B. This doesn't work on the 3400 */ -+void pmu_blink(int n) -+{ -+ struct adb_request req; - --/* FIXME: This is a temporary set of callbacks to enable us -- * to do suspend-to-disk. -- */ -+ memset(&req, 0, sizeof(req)); - --#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32) -+ for (; n > 0; --n) { -+ req.nbytes = 4; -+ req.done = NULL; -+ req.data[0] = 0xee; -+ req.data[1] = 4; -+ req.data[2] = 0; -+ req.data[3] = 1; -+ req.reply[0] = ADB_RET_OK; -+ req.reply_len = 1; -+ req.reply_expected = 0; -+ pmu_polled_request(&req); -+ mdelay(50); -+ req.nbytes = 4; -+ req.done = NULL; -+ req.data[0] = 0xee; -+ req.data[1] = 4; -+ req.data[2] = 0; -+ req.data[3] = 0; -+ req.reply[0] = ADB_RET_OK; -+ req.reply_len = 1; -+ req.reply_expected = 0; -+ pmu_polled_request(&req); -+ mdelay(50); -+ } -+ mdelay(50); -+} -+#endif /* DEBUG_SLEEP */ - -+#if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32) - int pmu_sys_suspended; - - static int pmu_sys_suspend(struct sys_device *sysdev, pm_message_t state) -@@ -2767,10 +2445,15 @@ static int pmu_sys_suspend(struct sys_de - if (state.event != PM_EVENT_SUSPEND || pmu_sys_suspended) - return 0; - -- /* Suspend PMU event interrupts */ -+ /* Suspend PMU event interrupts */\ - pmu_suspend(); -- - pmu_sys_suspended = 1; -+ -+#ifdef CONFIG_PMAC_BACKLIGHT -+ /* Tell backlight code not to muck around with the chip anymore */ -+ pmu_backlight_set_sleep(1); -+#endif -+ - return 0; - } - -@@ -2785,15 +2468,18 @@ static int pmu_sys_resume(struct sys_dev - pmu_request(&req, NULL, 2, PMU_SYSTEM_READY, 2); - pmu_wait_complete(&req); - -+#ifdef CONFIG_PMAC_BACKLIGHT -+ /* Tell backlight code it can use the chip again */ -+ pmu_backlight_set_sleep(0); -+#endif - /* Resume PMU event interrupts */ - pmu_resume(); -- - pmu_sys_suspended = 0; - - return 0; - } - --#endif /* CONFIG_PM_SLEEP && CONFIG_PPC32 */ -+#endif /* CONFIG_SUSPEND && CONFIG_PPC32 */ - - static struct sysdev_class pmu_sysclass = { - set_kset_name("pmu"), -@@ -2804,10 +2490,10 @@ static struct sys_device device_pmu = { - }; - - static struct sysdev_driver driver_pmu = { --#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32) -+#if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32) - .suspend = &pmu_sys_suspend, - .resume = &pmu_sys_resume, --#endif /* CONFIG_PM_SLEEP && CONFIG_PPC32 */ -+#endif /* CONFIG_SUSPEND && CONFIG_PPC32 */ - }; - - static int __init init_pmu_sysfs(void) -@@ -2842,10 +2528,10 @@ EXPORT_SYMBOL(pmu_wait_complete); - EXPORT_SYMBOL(pmu_suspend); - EXPORT_SYMBOL(pmu_resume); - EXPORT_SYMBOL(pmu_unlock); --#if defined(CONFIG_PPC32) -+#if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32) - EXPORT_SYMBOL(pmu_enable_irled); - EXPORT_SYMBOL(pmu_battery_count); - EXPORT_SYMBOL(pmu_batteries); - EXPORT_SYMBOL(pmu_power_flags); --#endif /* CONFIG_PM_SLEEP && CONFIG_PPC32 */ -+#endif /* CONFIG_SUSPEND && CONFIG_PPC32 */ - ---- a/drivers/net/fs_enet/fs_enet-main.c -+++ b/drivers/net/fs_enet/fs_enet-main.c -@@ -1178,8 +1178,15 @@ static int __devinit find_phy(struct dev - struct device_node *phynode, *mdionode; - struct resource res; - int ret = 0, len; -+ const u32 *data; -+ -+ data = of_get_property(np, "fixed-link", NULL); -+ if (data) { -+ snprintf(fpi->bus_id, 16, PHY_ID_FMT, 0, *data); -+ return 0; -+ } - -- const u32 *data = of_get_property(np, "phy-handle", &len); -+ data = of_get_property(np, "phy-handle", &len); - if (!data || len != 4) - return -EINVAL; - ---- a/drivers/net/fs_enet/mac-fcc.c -+++ b/drivers/net/fs_enet/mac-fcc.c -@@ -81,16 +81,8 @@ - static inline int fcc_cr_cmd(struct fs_enet_private *fep, u32 op) - { - const struct fs_platform_info *fpi = fep->fpi; -- int i; - -- W32(cpmp, cp_cpcr, fpi->cp_command | op | CPM_CR_FLG); -- for (i = 0; i < MAX_CR_CMD_LOOPS; i++) -- if ((R32(cpmp, cp_cpcr) & CPM_CR_FLG) == 0) -- return 0; -- -- printk(KERN_ERR "%s(): Not able to issue CPM command\n", -- __FUNCTION__); -- return 1; -+ return cpm_command(fpi->cp_command, op); - } - - static int do_pd_setup(struct fs_enet_private *fep) ---- a/drivers/net/fs_enet/mac-scc.c -+++ b/drivers/net/fs_enet/mac-scc.c -@@ -89,21 +89,12 @@ - * Delay to wait for SCC reset command to complete (in us) - */ - #define SCC_RESET_DELAY 50 --#define MAX_CR_CMD_LOOPS 10000 - - static inline int scc_cr_cmd(struct fs_enet_private *fep, u32 op) - { - const struct fs_platform_info *fpi = fep->fpi; -- int i; - -- W16(cpmp, cp_cpcr, fpi->cp_command | CPM_CR_FLG | (op << 8)); -- for (i = 0; i < MAX_CR_CMD_LOOPS; i++) -- if ((R16(cpmp, cp_cpcr) & CPM_CR_FLG) == 0) -- return 0; -- -- printk(KERN_ERR "%s(): Not able to issue CPM command\n", -- __FUNCTION__); -- return 1; -+ return cpm_command(fpi->cp_command, op); - } - - static int do_pd_setup(struct fs_enet_private *fep) ---- a/drivers/net/ibm_newemac/core.c -+++ b/drivers/net/ibm_newemac/core.c -@@ -37,6 +37,7 @@ - #include - #include - #include -+#include - - #include - #include ---- a/drivers/net/phy/Kconfig -+++ b/drivers/net/phy/Kconfig -@@ -61,34 +61,12 @@ config ICPLUS_PHY - Currently supports the IP175C PHY. - - config FIXED_PHY -- tristate "Drivers for PHY emulation on fixed speed/link" -+ bool "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs" - ---help--- -- Adds the driver to PHY layer to cover the boards that do not have any PHY bound, -- but with the ability to manipulate the speed/link in software. The relevant MII -- speed/duplex parameters could be effectively handled in a user-specified function. -- Currently tested with mpc866ads. -+ Adds the platform "fixed" MDIO Bus to cover the boards that use -+ PHYs that are not connected to the real MDIO bus. - --config FIXED_MII_10_FDX -- bool "Emulation for 10M Fdx fixed PHY behavior" -- depends on FIXED_PHY -- --config FIXED_MII_100_FDX -- bool "Emulation for 100M Fdx fixed PHY behavior" -- depends on FIXED_PHY -- --config FIXED_MII_1000_FDX -- bool "Emulation for 1000M Fdx fixed PHY behavior" -- depends on FIXED_PHY -- --config FIXED_MII_AMNT -- int "Number of emulated PHYs to allocate " -- depends on FIXED_PHY -- default "1" -- ---help--- -- Sometimes it is required to have several independent emulated -- PHYs on the bus (in case of multi-eth but phy-less HW for instance). -- This control will have specified number allocated for each fixed -- PHY type enabled. -+ Currently tested with mpc866ads and mpc8349e-mitx. - - config MDIO_BITBANG - tristate "Support for bitbanged MDIO buses" ---- a/drivers/net/phy/fixed.c -+++ b/drivers/net/phy/fixed.c -@@ -1,362 +1,253 @@ - /* -- * drivers/net/phy/fixed.c -+ * Fixed MDIO bus (MDIO bus emulation with fixed PHYs) - * -- * Driver for fixed PHYs, when transceiver is able to operate in one fixed mode. -+ * Author: Vitaly Bordug -+ * Anton Vorontsov - * -- * Author: Vitaly Bordug -- * -- * Copyright (c) 2006 MontaVista Software, Inc. -+ * Copyright (c) 2006-2007 MontaVista Software, Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. -- * - */ -+ - #include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include - #include -+#include -+#include - #include --#include - #include - #include - --#include --#include --#include -- --/* we need to track the allocated pointers in order to free them on exit */ --static struct fixed_info *fixed_phy_ptrs[CONFIG_FIXED_MII_AMNT*MAX_PHY_AMNT]; -- --/*----------------------------------------------------------------------------- -- * If something weird is required to be done with link/speed, -- * network driver is able to assign a function to implement this. -- * May be useful for PHY's that need to be software-driven. -- *-----------------------------------------------------------------------------*/ --int fixed_mdio_set_link_update(struct phy_device *phydev, -- int (*link_update) (struct net_device *, -- struct fixed_phy_status *)) --{ -- struct fixed_info *fixed; -- -- if (link_update == NULL) -- return -EINVAL; -+#define MII_REGS_NUM 29 - -- if (phydev) { -- if (phydev->bus) { -- fixed = phydev->bus->priv; -- fixed->link_update = link_update; -- return 0; -- } -- } -- return -EINVAL; --} -- --EXPORT_SYMBOL(fixed_mdio_set_link_update); -+struct fixed_mdio_bus { -+ int irqs[PHY_MAX_ADDR]; -+ struct mii_bus mii_bus; -+ struct list_head phys; -+}; - --struct fixed_info *fixed_mdio_get_phydev (int phydev_ind) --{ -- if (phydev_ind >= MAX_PHY_AMNT) -- return NULL; -- return fixed_phy_ptrs[phydev_ind]; --} -+struct fixed_phy { -+ int id; -+ u16 regs[MII_REGS_NUM]; -+ struct phy_device *phydev; -+ struct fixed_phy_status status; -+ int (*link_update)(struct net_device *, struct fixed_phy_status *); -+ struct list_head node; -+}; - --EXPORT_SYMBOL(fixed_mdio_get_phydev); -+static struct platform_device *pdev; -+static struct fixed_mdio_bus platform_fmb = { -+ .phys = LIST_HEAD_INIT(platform_fmb.phys), -+}; - --/*----------------------------------------------------------------------------- -- * This is used for updating internal mii regs from the status -- *-----------------------------------------------------------------------------*/ --#if defined(CONFIG_FIXED_MII_100_FDX) || defined(CONFIG_FIXED_MII_10_FDX) || defined(CONFIG_FIXED_MII_1000_FDX) --static int fixed_mdio_update_regs(struct fixed_info *fixed) -+static int fixed_phy_update_regs(struct fixed_phy *fp) - { -- u16 *regs = fixed->regs; -- u16 bmsr = 0; -+ u16 bmsr = BMSR_ANEGCAPABLE; - u16 bmcr = 0; -+ u16 lpagb = 0; -+ u16 lpa = 0; - -- if (!regs) { -- printk(KERN_ERR "%s: regs not set up", __FUNCTION__); -- return -EINVAL; -- } -- -- if (fixed->phy_status.link) -- bmsr |= BMSR_LSTATUS; -- -- if (fixed->phy_status.duplex) { -+ if (fp->status.duplex) { - bmcr |= BMCR_FULLDPLX; - -- switch (fixed->phy_status.speed) { -+ switch (fp->status.speed) { -+ case 1000: -+ bmsr |= BMSR_ESTATEN; -+ bmcr |= BMCR_SPEED1000; -+ lpagb |= LPA_1000FULL; -+ break; - case 100: - bmsr |= BMSR_100FULL; - bmcr |= BMCR_SPEED100; -+ lpa |= LPA_100FULL; - break; -- - case 10: - bmsr |= BMSR_10FULL; -+ lpa |= LPA_10FULL; - break; -+ default: -+ printk(KERN_WARNING "fixed phy: unknown speed\n"); -+ return -EINVAL; - } - } else { -- switch (fixed->phy_status.speed) { -+ switch (fp->status.speed) { -+ case 1000: -+ bmsr |= BMSR_ESTATEN; -+ bmcr |= BMCR_SPEED1000; -+ lpagb |= LPA_1000HALF; -+ break; - case 100: - bmsr |= BMSR_100HALF; - bmcr |= BMCR_SPEED100; -+ lpa |= LPA_100HALF; - break; -- - case 10: -- bmsr |= BMSR_100HALF; -+ bmsr |= BMSR_10HALF; -+ lpa |= LPA_10HALF; - break; -+ default: -+ printk(KERN_WARNING "fixed phy: unknown speed\n"); -+ return -EINVAL; - } - } - -- regs[MII_BMCR] = bmcr; -- regs[MII_BMSR] = bmsr | 0x800; /*we are always capable of 10 hdx */ -+ if (fp->status.link) -+ bmsr |= BMSR_LSTATUS | BMSR_ANEGCOMPLETE; -+ -+ if (fp->status.pause) -+ lpa |= LPA_PAUSE_CAP; -+ -+ if (fp->status.asym_pause) -+ lpa |= LPA_PAUSE_ASYM; -+ -+ fp->regs[MII_PHYSID1] = fp->id >> 16; -+ fp->regs[MII_PHYSID2] = fp->id; -+ -+ fp->regs[MII_BMSR] = bmsr; -+ fp->regs[MII_BMCR] = bmcr; -+ fp->regs[MII_LPA] = lpa; -+ fp->regs[MII_STAT1000] = lpagb; - - return 0; - } - --static int fixed_mii_read(struct mii_bus *bus, int phy_id, int location) -+static int fixed_mdio_read(struct mii_bus *bus, int phy_id, int reg_num) - { -- struct fixed_info *fixed = bus->priv; -+ struct fixed_mdio_bus *fmb = container_of(bus, struct fixed_mdio_bus, -+ mii_bus); -+ struct fixed_phy *fp; - -- /* if user has registered link update callback, use it */ -- if (fixed->phydev) -- if (fixed->phydev->attached_dev) { -- if (fixed->link_update) { -- fixed->link_update(fixed->phydev->attached_dev, -- &fixed->phy_status); -- fixed_mdio_update_regs(fixed); -+ if (reg_num >= MII_REGS_NUM) -+ return -1; -+ -+ list_for_each_entry(fp, &fmb->phys, node) { -+ if (fp->id == phy_id) { -+ /* Issue callback if user registered it. */ -+ if (fp->link_update) { -+ fp->link_update(fp->phydev->attached_dev, -+ &fp->status); -+ fixed_phy_update_regs(fp); - } -+ return fp->regs[reg_num]; - } -+ } - -- if ((unsigned int)location >= fixed->regs_num) -- return -1; -- return fixed->regs[location]; -+ return 0xFFFF; - } - --static int fixed_mii_write(struct mii_bus *bus, int phy_id, int location, -- u16 val) -+static int fixed_mdio_write(struct mii_bus *bus, int phy_id, int reg_num, -+ u16 val) - { -- /* do nothing for now */ - return 0; - } - --static int fixed_mii_reset(struct mii_bus *bus) -+/* -+ * If something weird is required to be done with link/speed, -+ * network driver is able to assign a function to implement this. -+ * May be useful for PHY's that need to be software-driven. -+ */ -+int fixed_phy_set_link_update(struct phy_device *phydev, -+ int (*link_update)(struct net_device *, -+ struct fixed_phy_status *)) - { -- /*nothing here - no way/need to reset it */ -- return 0; --} --#endif -+ struct fixed_mdio_bus *fmb = &platform_fmb; -+ struct fixed_phy *fp; - --static int fixed_config_aneg(struct phy_device *phydev) --{ -- /* :TODO:03/13/2006 09:45:37 PM:: -- The full autoneg funcionality can be emulated, -- but no need to have anything here for now -- */ -- return 0; --} -+ if (!link_update || !phydev || !phydev->bus) -+ return -EINVAL; - --/*----------------------------------------------------------------------------- -- * the manual bind will do the magic - with phy_id_mask == 0 -- * match will never return true... -- *-----------------------------------------------------------------------------*/ --static struct phy_driver fixed_mdio_driver = { -- .name = "Fixed PHY", --#ifdef CONFIG_FIXED_MII_1000_FDX -- .features = PHY_GBIT_FEATURES, --#else -- .features = PHY_BASIC_FEATURES, --#endif -- .config_aneg = fixed_config_aneg, -- .read_status = genphy_read_status, -- .driver = { .owner = THIS_MODULE, }, --}; -+ list_for_each_entry(fp, &fmb->phys, node) { -+ if (fp->id == phydev->phy_id) { -+ fp->link_update = link_update; -+ fp->phydev = phydev; -+ return 0; -+ } -+ } - --static void fixed_mdio_release(struct device *dev) --{ -- struct phy_device *phydev = container_of(dev, struct phy_device, dev); -- struct mii_bus *bus = phydev->bus; -- struct fixed_info *fixed = bus->priv; -- -- kfree(phydev); -- kfree(bus->dev); -- kfree(bus); -- kfree(fixed->regs); -- kfree(fixed); -+ return -ENOENT; - } -+EXPORT_SYMBOL_GPL(fixed_phy_set_link_update); - --/*----------------------------------------------------------------------------- -- * This func is used to create all the necessary stuff, bind -- * the fixed phy driver and register all it on the mdio_bus_type. -- * speed is either 10 or 100 or 1000, duplex is boolean. -- * number is used to create multiple fixed PHYs, so that several devices can -- * utilize them simultaneously. -- * -- * The device on mdio bus will look like [bus_id]:[phy_id], -- * bus_id = number -- * phy_id = speed+duplex. -- *-----------------------------------------------------------------------------*/ --#if defined(CONFIG_FIXED_MII_100_FDX) || defined(CONFIG_FIXED_MII_10_FDX) || defined(CONFIG_FIXED_MII_1000_FDX) --struct fixed_info *fixed_mdio_register_device( -- int bus_id, int speed, int duplex, u8 phy_id) -+int fixed_phy_add(unsigned int irq, int phy_id, -+ struct fixed_phy_status *status) - { -- struct mii_bus *new_bus; -- struct fixed_info *fixed; -- struct phy_device *phydev; -- int err; -+ int ret; -+ struct fixed_mdio_bus *fmb = &platform_fmb; -+ struct fixed_phy *fp; - -- struct device *dev = kzalloc(sizeof(struct device), GFP_KERNEL); -+ fp = kzalloc(sizeof(*fp), GFP_KERNEL); -+ if (!fp) -+ return -ENOMEM; - -- if (dev == NULL) -- goto err_dev_alloc; -+ memset(fp->regs, 0xFF, sizeof(fp->regs[0]) * MII_REGS_NUM); - -- new_bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL); -+ fmb->irqs[phy_id] = irq; - -- if (new_bus == NULL) -- goto err_bus_alloc; -- -- fixed = kzalloc(sizeof(struct fixed_info), GFP_KERNEL); -- -- if (fixed == NULL) -- goto err_fixed_alloc; -- -- fixed->regs = kzalloc(MII_REGS_NUM * sizeof(int), GFP_KERNEL); -- if (NULL == fixed->regs) -- goto err_fixed_regs_alloc; -- -- fixed->regs_num = MII_REGS_NUM; -- fixed->phy_status.speed = speed; -- fixed->phy_status.duplex = duplex; -- fixed->phy_status.link = 1; -- -- new_bus->name = "Fixed MII Bus"; -- new_bus->read = &fixed_mii_read; -- new_bus->write = &fixed_mii_write; -- new_bus->reset = &fixed_mii_reset; -- /*set up workspace */ -- fixed_mdio_update_regs(fixed); -- new_bus->priv = fixed; -- -- new_bus->dev = dev; -- dev_set_drvdata(dev, new_bus); -- -- /* create phy_device and register it on the mdio bus */ -- phydev = phy_device_create(new_bus, 0, 0); -- if (phydev == NULL) -- goto err_phy_dev_create; -- -- /* -- * Put the phydev pointer into the fixed pack so that bus read/write -- * code could be able to access for instance attached netdev. Well it -- * doesn't have to do so, only in case of utilizing user-specified -- * link-update... -- */ -- -- fixed->phydev = phydev; -- phydev->speed = speed; -- phydev->duplex = duplex; -- -- phydev->irq = PHY_IGNORE_INTERRUPT; -- phydev->dev.bus = &mdio_bus_type; -- -- snprintf(phydev->dev.bus_id, BUS_ID_SIZE, -- PHY_ID_FMT, bus_id, phy_id); -- -- phydev->bus = new_bus; -- -- phydev->dev.driver = &fixed_mdio_driver.driver; -- phydev->dev.release = fixed_mdio_release; -- err = phydev->dev.driver->probe(&phydev->dev); -- if (err < 0) { -- printk(KERN_ERR "Phy %s: problems with fixed driver\n", -- phydev->dev.bus_id); -- goto err_out; -- } -- err = device_register(&phydev->dev); -- if (err) { -- printk(KERN_ERR "Phy %s failed to register\n", -- phydev->dev.bus_id); -- goto err_out; -- } -- //phydev->state = PHY_RUNNING; /* make phy go up quick, but in 10Mbit/HDX -- return fixed; -+ fp->id = phy_id; -+ fp->status = *status; - --err_out: -- kfree(phydev); --err_phy_dev_create: -- kfree(fixed->regs); --err_fixed_regs_alloc: -- kfree(fixed); --err_fixed_alloc: -- kfree(new_bus); --err_bus_alloc: -- kfree(dev); --err_dev_alloc: -+ ret = fixed_phy_update_regs(fp); -+ if (ret) -+ goto err_regs; - -- return NULL; -+ list_add_tail(&fp->node, &fmb->phys); - --} --#endif -+ return 0; - --MODULE_DESCRIPTION("Fixed PHY device & driver for PAL"); --MODULE_AUTHOR("Vitaly Bordug"); --MODULE_LICENSE("GPL"); -+err_regs: -+ kfree(fp); -+ return ret; -+} -+EXPORT_SYMBOL_GPL(fixed_phy_add); - --static int __init fixed_init(void) -+static int __init fixed_mdio_bus_init(void) - { -- int cnt = 0; -- int i; --/* register on the bus... Not expected to be matched -- * with anything there... -- * -- */ -- phy_driver_register(&fixed_mdio_driver); -+ struct fixed_mdio_bus *fmb = &platform_fmb; -+ int ret; - --/* We will create several mdio devices here, and will bound the upper -- * driver to them. -- * -- * Then the external software can lookup the phy bus by searching -- * for 0:101, to be connected to the virtual 100M Fdx phy. -- * -- * In case several virtual PHYs required, the bus_id will be in form -- * [num]:[duplex]+[speed], which make it able even to define -- * driver-specific link control callback, if for instance PHY is -- * completely SW-driven. -- */ -- for (i=1; i <= CONFIG_FIXED_MII_AMNT; i++) { --#ifdef CONFIG_FIXED_MII_1000_FDX -- fixed_phy_ptrs[cnt++] = fixed_mdio_register_device(0, 1000, 1, i); --#endif --#ifdef CONFIG_FIXED_MII_100_FDX -- fixed_phy_ptrs[cnt++] = fixed_mdio_register_device(1, 100, 1, i); --#endif --#ifdef CONFIG_FIXED_MII_10_FDX -- fixed_phy_ptrs[cnt++] = fixed_mdio_register_device(2, 10, 1, i); --#endif -+ pdev = platform_device_register_simple("Fixed MDIO bus", 0, NULL, 0); -+ if (!pdev) { -+ ret = -ENOMEM; -+ goto err_pdev; - } - -+ fmb->mii_bus.id = 0; -+ fmb->mii_bus.name = "Fixed MDIO Bus"; -+ fmb->mii_bus.dev = &pdev->dev; -+ fmb->mii_bus.read = &fixed_mdio_read; -+ fmb->mii_bus.write = &fixed_mdio_write; -+ fmb->mii_bus.irq = fmb->irqs; -+ -+ ret = mdiobus_register(&fmb->mii_bus); -+ if (ret) -+ goto err_mdiobus_reg; -+ - return 0; -+ -+err_mdiobus_reg: -+ platform_device_unregister(pdev); -+err_pdev: -+ return ret; - } -+module_init(fixed_mdio_bus_init); - --static void __exit fixed_exit(void) -+static void __exit fixed_mdio_bus_exit(void) - { -- int i; -+ struct fixed_mdio_bus *fmb = &platform_fmb; -+ struct fixed_phy *fp; - -- phy_driver_unregister(&fixed_mdio_driver); -- for (i=0; i < MAX_PHY_AMNT; i++) -- if ( fixed_phy_ptrs[i] ) -- device_unregister(&fixed_phy_ptrs[i]->phydev->dev); -+ mdiobus_unregister(&fmb->mii_bus); -+ platform_device_unregister(pdev); -+ -+ list_for_each_entry(fp, &fmb->phys, node) { -+ list_del(&fp->node); -+ kfree(fp); -+ } - } -+module_exit(fixed_mdio_bus_exit); - --module_init(fixed_init); --module_exit(fixed_exit); -+MODULE_DESCRIPTION("Fixed MDIO bus (MDIO bus emulation with fixed PHYs)"); -+MODULE_AUTHOR("Vitaly Bordug"); -+MODULE_LICENSE("GPL"); ---- a/drivers/net/ps3_gelic_net.c -+++ b/drivers/net/ps3_gelic_net.c -@@ -58,11 +58,11 @@ static inline struct device *ctodev(stru - { - return &card->dev->core; - } --static inline unsigned int bus_id(struct gelic_net_card *card) -+static inline u64 bus_id(struct gelic_net_card *card) - { - return card->dev->bus_id; - } --static inline unsigned int dev_id(struct gelic_net_card *card) -+static inline u64 dev_id(struct gelic_net_card *card) - { - return card->dev->dev_id; - } ---- a/drivers/net/ucc_geth.c -+++ b/drivers/net/ucc_geth.c -@@ -3822,6 +3822,7 @@ static int ucc_geth_probe(struct of_devi - int err, ucc_num, max_speed = 0; - const phandle *ph; - const unsigned int *prop; -+ const char *sprop; - const void *mac_addr; - phy_interface_t phy_interface; - static const int enet_to_speed[] = { -@@ -3854,10 +3855,56 @@ static int ucc_geth_probe(struct of_devi - - ug_info->uf_info.ucc_num = ucc_num; - -- prop = of_get_property(np, "rx-clock", NULL); -- ug_info->uf_info.rx_clock = *prop; -- prop = of_get_property(np, "tx-clock", NULL); -- ug_info->uf_info.tx_clock = *prop; -+ sprop = of_get_property(np, "rx-clock-name", NULL); -+ if (sprop) { -+ ug_info->uf_info.rx_clock = qe_clock_source(sprop); -+ if ((ug_info->uf_info.rx_clock < QE_CLK_NONE) || -+ (ug_info->uf_info.rx_clock > QE_CLK24)) { -+ printk(KERN_ERR -+ "ucc_geth: invalid rx-clock-name property\n"); -+ return -EINVAL; -+ } -+ } else { -+ prop = of_get_property(np, "rx-clock", NULL); -+ if (!prop) { -+ /* If both rx-clock-name and rx-clock are missing, -+ we want to tell people to use rx-clock-name. */ -+ printk(KERN_ERR -+ "ucc_geth: missing rx-clock-name property\n"); -+ return -EINVAL; -+ } -+ if ((*prop < QE_CLK_NONE) || (*prop > QE_CLK24)) { -+ printk(KERN_ERR -+ "ucc_geth: invalid rx-clock propperty\n"); -+ return -EINVAL; -+ } -+ ug_info->uf_info.rx_clock = *prop; -+ } -+ -+ sprop = of_get_property(np, "tx-clock-name", NULL); -+ if (sprop) { -+ ug_info->uf_info.tx_clock = qe_clock_source(sprop); -+ if ((ug_info->uf_info.tx_clock < QE_CLK_NONE) || -+ (ug_info->uf_info.tx_clock > QE_CLK24)) { -+ printk(KERN_ERR -+ "ucc_geth: invalid tx-clock-name property\n"); -+ return -EINVAL; -+ } -+ } else { -+ prop = of_get_property(np, "rx-clock", NULL); -+ if (!prop) { -+ printk(KERN_ERR -+ "ucc_geth: mising tx-clock-name property\n"); -+ return -EINVAL; -+ } -+ if ((*prop < QE_CLK_NONE) || (*prop > QE_CLK24)) { -+ printk(KERN_ERR -+ "ucc_geth: invalid tx-clock property\n"); -+ return -EINVAL; -+ } -+ ug_info->uf_info.tx_clock = *prop; -+ } -+ - err = of_address_to_resource(np, 0, &res); - if (err) - return -EINVAL; ---- a/drivers/of/base.c -+++ b/drivers/of/base.c -@@ -273,3 +273,61 @@ struct device_node *of_find_compatible_n - return np; - } - EXPORT_SYMBOL(of_find_compatible_node); -+ -+/** -+ * of_match_node - Tell if an device_node has a matching of_match structure -+ * @matches: array of of device match structures to search in -+ * @node: the of device structure to match against -+ * -+ * Low level utility function used by device matching. -+ */ -+const struct of_device_id *of_match_node(const struct of_device_id *matches, -+ const struct device_node *node) -+{ -+ while (matches->name[0] || matches->type[0] || matches->compatible[0]) { -+ int match = 1; -+ if (matches->name[0]) -+ match &= node->name -+ && !strcmp(matches->name, node->name); -+ if (matches->type[0]) -+ match &= node->type -+ && !strcmp(matches->type, node->type); -+ if (matches->compatible[0]) -+ match &= of_device_is_compatible(node, -+ matches->compatible); -+ if (match) -+ return matches; -+ matches++; -+ } -+ return NULL; -+} -+EXPORT_SYMBOL(of_match_node); -+ -+/** -+ * of_find_matching_node - Find a node based on an of_device_id match -+ * table. -+ * @from: The node to start searching from or NULL, the node -+ * you pass will not be searched, only the next one -+ * will; typically, you pass what the previous call -+ * returned. of_node_put() will be called on it -+ * @matches: array of of device match structures to search in -+ * -+ * Returns a node pointer with refcount incremented, use -+ * of_node_put() on it when done. -+ */ -+struct device_node *of_find_matching_node(struct device_node *from, -+ const struct of_device_id *matches) -+{ -+ struct device_node *np; -+ -+ read_lock(&devtree_lock); -+ np = from ? from->allnext : allnodes; -+ for (; np; np = np->allnext) { -+ if (of_match_node(matches, np) && of_node_get(np)) -+ break; -+ } -+ of_node_put(from); -+ read_unlock(&devtree_lock); -+ return np; -+} -+EXPORT_SYMBOL(of_find_matching_node); ---- a/drivers/of/device.c -+++ b/drivers/of/device.c -@@ -10,35 +10,6 @@ - #include - - /** -- * of_match_node - Tell if an device_node has a matching of_match structure -- * @ids: array of of device match structures to search in -- * @node: the of device structure to match against -- * -- * Low level utility function used by device matching. -- */ --const struct of_device_id *of_match_node(const struct of_device_id *matches, -- const struct device_node *node) --{ -- while (matches->name[0] || matches->type[0] || matches->compatible[0]) { -- int match = 1; -- if (matches->name[0]) -- match &= node->name -- && !strcmp(matches->name, node->name); -- if (matches->type[0]) -- match &= node->type -- && !strcmp(matches->type, node->type); -- if (matches->compatible[0]) -- match &= of_device_is_compatible(node, -- matches->compatible); -- if (match) -- return matches; -- matches++; -- } -- return NULL; --} --EXPORT_SYMBOL(of_match_node); -- --/** - * of_match_device - Tell if an of_device structure has a matching - * of_match structure - * @ids: array of of device match structures to search in ---- a/drivers/ps3/Makefile -+++ b/drivers/ps3/Makefile -@@ -4,3 +4,4 @@ ps3av_mod-objs += ps3av.o ps3av_cmd.o - obj-$(CONFIG_PPC_PS3) += sys-manager-core.o - obj-$(CONFIG_PS3_SYS_MANAGER) += ps3-sys-manager.o - obj-$(CONFIG_PS3_STORAGE) += ps3stor_lib.o -+obj-$(CONFIG_PS3_LPM) += ps3-lpm.o ---- /dev/null -+++ b/drivers/ps3/ps3-lpm.c -@@ -0,0 +1,1248 @@ -+/* -+ * PS3 Logical Performance Monitor. -+ * -+ * Copyright (C) 2007 Sony Computer Entertainment Inc. -+ * Copyright 2007 Sony Corp. -+ * -+ * 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 of the License. -+ * -+ * 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 -+ -+ -+/* BOOKMARK tag macros */ -+#define PS3_PM_BOOKMARK_START 0x8000000000000000ULL -+#define PS3_PM_BOOKMARK_STOP 0x4000000000000000ULL -+#define PS3_PM_BOOKMARK_TAG_KERNEL 0x1000000000000000ULL -+#define PS3_PM_BOOKMARK_TAG_USER 0x3000000000000000ULL -+#define PS3_PM_BOOKMARK_TAG_MASK_HI 0xF000000000000000ULL -+#define PS3_PM_BOOKMARK_TAG_MASK_LO 0x0F00000000000000ULL -+ -+/* CBE PM CONTROL register macros */ -+#define PS3_PM_CONTROL_PPU_TH0_BOOKMARK 0x00001000 -+#define PS3_PM_CONTROL_PPU_TH1_BOOKMARK 0x00000800 -+#define PS3_PM_CONTROL_PPU_COUNT_MODE_MASK 0x000C0000 -+#define PS3_PM_CONTROL_PPU_COUNT_MODE_PROBLEM 0x00080000 -+#define PS3_WRITE_PM_MASK 0xFFFFFFFFFFFFFFFFULL -+ -+/* CBE PM START STOP register macros */ -+#define PS3_PM_START_STOP_PPU_TH0_BOOKMARK_START 0x02000000 -+#define PS3_PM_START_STOP_PPU_TH1_BOOKMARK_START 0x01000000 -+#define PS3_PM_START_STOP_PPU_TH0_BOOKMARK_STOP 0x00020000 -+#define PS3_PM_START_STOP_PPU_TH1_BOOKMARK_STOP 0x00010000 -+#define PS3_PM_START_STOP_START_MASK 0xFF000000 -+#define PS3_PM_START_STOP_STOP_MASK 0x00FF0000 -+ -+/* CBE PM COUNTER register macres */ -+#define PS3_PM_COUNTER_MASK_HI 0xFFFFFFFF00000000ULL -+#define PS3_PM_COUNTER_MASK_LO 0x00000000FFFFFFFFULL -+ -+/* BASE SIGNAL GROUP NUMBER macros */ -+#define PM_ISLAND2_BASE_SIGNAL_GROUP_NUMBER 0 -+#define PM_ISLAND2_SIGNAL_GROUP_NUMBER1 6 -+#define PM_ISLAND2_SIGNAL_GROUP_NUMBER2 7 -+#define PM_ISLAND3_BASE_SIGNAL_GROUP_NUMBER 7 -+#define PM_ISLAND4_BASE_SIGNAL_GROUP_NUMBER 15 -+#define PM_SPU_TRIGGER_SIGNAL_GROUP_NUMBER 17 -+#define PM_SPU_EVENT_SIGNAL_GROUP_NUMBER 18 -+#define PM_ISLAND5_BASE_SIGNAL_GROUP_NUMBER 18 -+#define PM_ISLAND6_BASE_SIGNAL_GROUP_NUMBER 24 -+#define PM_ISLAND7_BASE_SIGNAL_GROUP_NUMBER 49 -+#define PM_ISLAND8_BASE_SIGNAL_GROUP_NUMBER 52 -+#define PM_SIG_GROUP_SPU 41 -+#define PM_SIG_GROUP_SPU_TRIGGER 42 -+#define PM_SIG_GROUP_SPU_EVENT 43 -+#define PM_SIG_GROUP_MFC_MAX 60 -+ -+/** -+ * struct ps3_lpm_shadow_regs - Performance monitor shadow registers. -+ * -+ * @pm_control: Shadow of the processor's pm_control register. -+ * @pm_start_stop: Shadow of the processor's pm_start_stop register. -+ * @pm_interval: Shadow of the processor's pm_interval register. -+ * @group_control: Shadow of the processor's group_control register. -+ * @debug_bus_control: Shadow of the processor's debug_bus_control register. -+ * -+ * The logical performance monitor provides a write-only interface to -+ * these processor registers. These shadow variables cache the processor -+ * register values for reading. -+ * -+ * The initial value of the shadow registers at lpm creation is -+ * PS3_LPM_SHADOW_REG_INIT. -+ */ -+ -+struct ps3_lpm_shadow_regs { -+ u64 pm_control; -+ u64 pm_start_stop; -+ u64 pm_interval; -+ u64 group_control; -+ u64 debug_bus_control; -+}; -+ -+#define PS3_LPM_SHADOW_REG_INIT 0xFFFFFFFF00000000ULL -+ -+/** -+ * struct ps3_lpm_priv - Private lpm device data. -+ * -+ * @open: An atomic variable indicating the lpm driver has been opened. -+ * @rights: The lpm rigths granted by the system policy module. A logical -+ * OR of enum ps3_lpm_rights. -+ * @node_id: The node id of a BE prosessor whose performance monitor this -+ * lpar has the right to use. -+ * @pu_id: The lv1 id of the logical PU. -+ * @lpm_id: The lv1 id of this lpm instance. -+ * @outlet_id: The outlet created by lv1 for this lpm instance. -+ * @tb_count: The number of bytes of data held in the lv1 trace buffer. -+ * @tb_cache: Kernel buffer to receive the data from the lv1 trace buffer. -+ * Must be 128 byte aligned. -+ * @tb_cache_size: Size of the kernel @tb_cache buffer. Must be 128 byte -+ * aligned. -+ * @tb_cache_internal: An unaligned buffer allocated by this driver to be -+ * used for the trace buffer cache when ps3_lpm_open() is called with a -+ * NULL tb_cache argument. Otherwise unused. -+ * @shadow: Processor register shadow of type struct ps3_lpm_shadow_regs. -+ * @sbd: The struct ps3_system_bus_device attached to this driver. -+ * -+ * The trace buffer is a buffer allocated and used internally to the lv1 -+ * hypervisor to collect trace data. The trace buffer cache is a guest -+ * buffer that accepts the trace data from the trace buffer. -+ */ -+ -+struct ps3_lpm_priv { -+ atomic_t open; -+ u64 rights; -+ u64 node_id; -+ u64 pu_id; -+ u64 lpm_id; -+ u64 outlet_id; -+ u64 tb_count; -+ void *tb_cache; -+ u64 tb_cache_size; -+ void *tb_cache_internal; -+ struct ps3_lpm_shadow_regs shadow; -+ struct ps3_system_bus_device *sbd; -+}; -+ -+enum { -+ PS3_LPM_DEFAULT_TB_CACHE_SIZE = 0x4000, -+}; -+ -+/** -+ * lpm_priv - Static instance of the lpm data. -+ * -+ * Since the exported routines don't support the notion of a device -+ * instance we need to hold the instance in this static variable -+ * and then only allow at most one instance at a time to be created. -+ */ -+ -+static struct ps3_lpm_priv *lpm_priv; -+ -+static struct device *sbd_core(void) -+{ -+ BUG_ON(!lpm_priv || !lpm_priv->sbd); -+ return &lpm_priv->sbd->core; -+} -+ -+/** -+ * use_start_stop_bookmark - Enable the PPU bookmark trace. -+ * -+ * And it enables PPU bookmark triggers ONLY if the other triggers are not set. -+ * The start/stop bookmarks are inserted at ps3_enable_pm() and ps3_disable_pm() -+ * to start/stop LPM. -+ * -+ * Used to get good quality of the performance counter. -+ */ -+ -+enum {use_start_stop_bookmark = 1,}; -+ -+void ps3_set_bookmark(u64 bookmark) -+{ -+ /* -+ * As per the PPE book IV, to avoid bookmark loss there must -+ * not be a traced branch within 10 cycles of setting the -+ * SPRN_BKMK register. The actual text is unclear if 'within' -+ * includes cycles before the call. -+ */ -+ -+ asm volatile("or 29, 29, 29;"); /* db10cyc */ -+ mtspr(SPRN_BKMK, bookmark); -+ asm volatile("or 29, 29, 29;"); /* db10cyc */ -+} -+EXPORT_SYMBOL_GPL(ps3_set_bookmark); -+ -+void ps3_set_pm_bookmark(u64 tag, u64 incident, u64 th_id) -+{ -+ u64 bookmark; -+ -+ bookmark = (get_tb() & 0x00000000FFFFFFFFULL) | -+ PS3_PM_BOOKMARK_TAG_KERNEL; -+ bookmark = ((tag << 56) & PS3_PM_BOOKMARK_TAG_MASK_LO) | -+ (incident << 48) | (th_id << 32) | bookmark; -+ ps3_set_bookmark(bookmark); -+} -+EXPORT_SYMBOL_GPL(ps3_set_pm_bookmark); -+ -+/** -+ * ps3_read_phys_ctr - Read physical counter registers. -+ * -+ * Each physical counter can act as one 32 bit counter or as two 16 bit -+ * counters. -+ */ -+ -+u32 ps3_read_phys_ctr(u32 cpu, u32 phys_ctr) -+{ -+ int result; -+ u64 counter0415; -+ u64 counter2637; -+ -+ if (phys_ctr >= NR_PHYS_CTRS) { -+ dev_dbg(sbd_core(), "%s:%u: phys_ctr too big: %u\n", __func__, -+ __LINE__, phys_ctr); -+ return 0; -+ } -+ -+ result = lv1_set_lpm_counter(lpm_priv->lpm_id, 0, 0, 0, 0, &counter0415, -+ &counter2637); -+ if (result) { -+ dev_err(sbd_core(), "%s:%u: lv1_set_lpm_counter failed: " -+ "phys_ctr %u, %s\n", __func__, __LINE__, phys_ctr, -+ ps3_result(result)); -+ return 0; -+ } -+ -+ switch (phys_ctr) { -+ case 0: -+ return counter0415 >> 32; -+ case 1: -+ return counter0415 & PS3_PM_COUNTER_MASK_LO; -+ case 2: -+ return counter2637 >> 32; -+ case 3: -+ return counter2637 & PS3_PM_COUNTER_MASK_LO; -+ default: -+ BUG(); -+ } -+ return 0; -+} -+EXPORT_SYMBOL_GPL(ps3_read_phys_ctr); -+ -+/** -+ * ps3_write_phys_ctr - Write physical counter registers. -+ * -+ * Each physical counter can act as one 32 bit counter or as two 16 bit -+ * counters. -+ */ -+ -+void ps3_write_phys_ctr(u32 cpu, u32 phys_ctr, u32 val) -+{ -+ u64 counter0415; -+ u64 counter0415_mask; -+ u64 counter2637; -+ u64 counter2637_mask; -+ int result; -+ -+ if (phys_ctr >= NR_PHYS_CTRS) { -+ dev_dbg(sbd_core(), "%s:%u: phys_ctr too big: %u\n", __func__, -+ __LINE__, phys_ctr); -+ return; -+ } -+ -+ switch (phys_ctr) { -+ case 0: -+ counter0415 = (u64)val << 32; -+ counter0415_mask = PS3_PM_COUNTER_MASK_HI; -+ counter2637 = 0x0; -+ counter2637_mask = 0x0; -+ break; -+ case 1: -+ counter0415 = (u64)val; -+ counter0415_mask = PS3_PM_COUNTER_MASK_LO; -+ counter2637 = 0x0; -+ counter2637_mask = 0x0; -+ break; -+ case 2: -+ counter0415 = 0x0; -+ counter0415_mask = 0x0; -+ counter2637 = (u64)val << 32; -+ counter2637_mask = PS3_PM_COUNTER_MASK_HI; -+ break; -+ case 3: -+ counter0415 = 0x0; -+ counter0415_mask = 0x0; -+ counter2637 = (u64)val; -+ counter2637_mask = PS3_PM_COUNTER_MASK_LO; -+ break; -+ default: -+ BUG(); -+ } -+ -+ result = lv1_set_lpm_counter(lpm_priv->lpm_id, -+ counter0415, counter0415_mask, -+ counter2637, counter2637_mask, -+ &counter0415, &counter2637); -+ if (result) -+ dev_err(sbd_core(), "%s:%u: lv1_set_lpm_counter failed: " -+ "phys_ctr %u, val %u, %s\n", __func__, __LINE__, -+ phys_ctr, val, ps3_result(result)); -+} -+EXPORT_SYMBOL_GPL(ps3_write_phys_ctr); -+ -+/** -+ * ps3_read_ctr - Read counter. -+ * -+ * Read 16 or 32 bits depending on the current size of the counter. -+ * Counters 4, 5, 6 & 7 are always 16 bit. -+ */ -+ -+u32 ps3_read_ctr(u32 cpu, u32 ctr) -+{ -+ u32 val; -+ u32 phys_ctr = ctr & (NR_PHYS_CTRS - 1); -+ -+ val = ps3_read_phys_ctr(cpu, phys_ctr); -+ -+ if (ps3_get_ctr_size(cpu, phys_ctr) == 16) -+ val = (ctr < NR_PHYS_CTRS) ? (val >> 16) : (val & 0xffff); -+ -+ return val; -+} -+EXPORT_SYMBOL_GPL(ps3_read_ctr); -+ -+/** -+ * ps3_write_ctr - Write counter. -+ * -+ * Write 16 or 32 bits depending on the current size of the counter. -+ * Counters 4, 5, 6 & 7 are always 16 bit. -+ */ -+ -+void ps3_write_ctr(u32 cpu, u32 ctr, u32 val) -+{ -+ u32 phys_ctr; -+ u32 phys_val; -+ -+ phys_ctr = ctr & (NR_PHYS_CTRS - 1); -+ -+ if (ps3_get_ctr_size(cpu, phys_ctr) == 16) { -+ phys_val = ps3_read_phys_ctr(cpu, phys_ctr); -+ -+ if (ctr < NR_PHYS_CTRS) -+ val = (val << 16) | (phys_val & 0xffff); -+ else -+ val = (val & 0xffff) | (phys_val & 0xffff0000); -+ } -+ -+ ps3_write_phys_ctr(cpu, phys_ctr, val); -+} -+EXPORT_SYMBOL_GPL(ps3_write_ctr); -+ -+/** -+ * ps3_read_pm07_control - Read counter control registers. -+ * -+ * Each logical counter has a corresponding control register. -+ */ -+ -+u32 ps3_read_pm07_control(u32 cpu, u32 ctr) -+{ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(ps3_read_pm07_control); -+ -+/** -+ * ps3_write_pm07_control - Write counter control registers. -+ * -+ * Each logical counter has a corresponding control register. -+ */ -+ -+void ps3_write_pm07_control(u32 cpu, u32 ctr, u32 val) -+{ -+ int result; -+ static const u64 mask = 0xFFFFFFFFFFFFFFFFULL; -+ u64 old_value; -+ -+ if (ctr >= NR_CTRS) { -+ dev_dbg(sbd_core(), "%s:%u: ctr too big: %u\n", __func__, -+ __LINE__, ctr); -+ return; -+ } -+ -+ result = lv1_set_lpm_counter_control(lpm_priv->lpm_id, ctr, val, mask, -+ &old_value); -+ if (result) -+ dev_err(sbd_core(), "%s:%u: lv1_set_lpm_counter_control " -+ "failed: ctr %u, %s\n", __func__, __LINE__, ctr, -+ ps3_result(result)); -+} -+EXPORT_SYMBOL_GPL(ps3_write_pm07_control); -+ -+/** -+ * ps3_read_pm - Read Other LPM control registers. -+ */ -+ -+u32 ps3_read_pm(u32 cpu, enum pm_reg_name reg) -+{ -+ int result = 0; -+ u64 val = 0; -+ -+ switch (reg) { -+ case pm_control: -+ return lpm_priv->shadow.pm_control; -+ case trace_address: -+ return CBE_PM_TRACE_BUF_EMPTY; -+ case pm_start_stop: -+ return lpm_priv->shadow.pm_start_stop; -+ case pm_interval: -+ return lpm_priv->shadow.pm_interval; -+ case group_control: -+ return lpm_priv->shadow.group_control; -+ case debug_bus_control: -+ return lpm_priv->shadow.debug_bus_control; -+ case pm_status: -+ result = lv1_get_lpm_interrupt_status(lpm_priv->lpm_id, -+ &val); -+ if (result) { -+ val = 0; -+ dev_dbg(sbd_core(), "%s:%u: lv1 get_lpm_status failed: " -+ "reg %u, %s\n", __func__, __LINE__, reg, -+ ps3_result(result)); -+ } -+ return (u32)val; -+ case ext_tr_timer: -+ return 0; -+ default: -+ dev_dbg(sbd_core(), "%s:%u: unknown reg: %d\n", __func__, -+ __LINE__, reg); -+ BUG(); -+ break; -+ } -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(ps3_read_pm); -+ -+/** -+ * ps3_write_pm - Write Other LPM control registers. -+ */ -+ -+void ps3_write_pm(u32 cpu, enum pm_reg_name reg, u32 val) -+{ -+ int result = 0; -+ u64 dummy; -+ -+ switch (reg) { -+ case group_control: -+ if (val != lpm_priv->shadow.group_control) -+ result = lv1_set_lpm_group_control(lpm_priv->lpm_id, -+ val, -+ PS3_WRITE_PM_MASK, -+ &dummy); -+ lpm_priv->shadow.group_control = val; -+ break; -+ case debug_bus_control: -+ if (val != lpm_priv->shadow.debug_bus_control) -+ result = lv1_set_lpm_debug_bus_control(lpm_priv->lpm_id, -+ val, -+ PS3_WRITE_PM_MASK, -+ &dummy); -+ lpm_priv->shadow.debug_bus_control = val; -+ break; -+ case pm_control: -+ if (use_start_stop_bookmark) -+ val |= (PS3_PM_CONTROL_PPU_TH0_BOOKMARK | -+ PS3_PM_CONTROL_PPU_TH1_BOOKMARK); -+ if (val != lpm_priv->shadow.pm_control) -+ result = lv1_set_lpm_general_control(lpm_priv->lpm_id, -+ val, -+ PS3_WRITE_PM_MASK, -+ 0, 0, &dummy, -+ &dummy); -+ lpm_priv->shadow.pm_control = val; -+ break; -+ case pm_interval: -+ if (val != lpm_priv->shadow.pm_interval) -+ result = lv1_set_lpm_interval(lpm_priv->lpm_id, val, -+ PS3_WRITE_PM_MASK, &dummy); -+ lpm_priv->shadow.pm_interval = val; -+ break; -+ case pm_start_stop: -+ if (val != lpm_priv->shadow.pm_start_stop) -+ result = lv1_set_lpm_trigger_control(lpm_priv->lpm_id, -+ val, -+ PS3_WRITE_PM_MASK, -+ &dummy); -+ lpm_priv->shadow.pm_start_stop = val; -+ break; -+ case trace_address: -+ case ext_tr_timer: -+ case pm_status: -+ break; -+ default: -+ dev_dbg(sbd_core(), "%s:%u: unknown reg: %d\n", __func__, -+ __LINE__, reg); -+ BUG(); -+ break; -+ } -+ -+ if (result) -+ dev_err(sbd_core(), "%s:%u: lv1 set_control failed: " -+ "reg %u, %s\n", __func__, __LINE__, reg, -+ ps3_result(result)); -+} -+EXPORT_SYMBOL_GPL(ps3_write_pm); -+ -+/** -+ * ps3_get_ctr_size - Get the size of a physical counter. -+ * -+ * Returns either 16 or 32. -+ */ -+ -+u32 ps3_get_ctr_size(u32 cpu, u32 phys_ctr) -+{ -+ u32 pm_ctrl; -+ -+ if (phys_ctr >= NR_PHYS_CTRS) { -+ dev_dbg(sbd_core(), "%s:%u: phys_ctr too big: %u\n", __func__, -+ __LINE__, phys_ctr); -+ return 0; -+ } -+ -+ pm_ctrl = ps3_read_pm(cpu, pm_control); -+ return (pm_ctrl & CBE_PM_16BIT_CTR(phys_ctr)) ? 16 : 32; -+} -+EXPORT_SYMBOL_GPL(ps3_get_ctr_size); -+ -+/** -+ * ps3_set_ctr_size - Set the size of a physical counter to 16 or 32 bits. -+ */ -+ -+void ps3_set_ctr_size(u32 cpu, u32 phys_ctr, u32 ctr_size) -+{ -+ u32 pm_ctrl; -+ -+ if (phys_ctr >= NR_PHYS_CTRS) { -+ dev_dbg(sbd_core(), "%s:%u: phys_ctr too big: %u\n", __func__, -+ __LINE__, phys_ctr); -+ return; -+ } -+ -+ pm_ctrl = ps3_read_pm(cpu, pm_control); -+ -+ switch (ctr_size) { -+ case 16: -+ pm_ctrl |= CBE_PM_16BIT_CTR(phys_ctr); -+ ps3_write_pm(cpu, pm_control, pm_ctrl); -+ break; -+ -+ case 32: -+ pm_ctrl &= ~CBE_PM_16BIT_CTR(phys_ctr); -+ ps3_write_pm(cpu, pm_control, pm_ctrl); -+ break; -+ default: -+ BUG(); -+ } -+} -+EXPORT_SYMBOL_GPL(ps3_set_ctr_size); -+ -+static u64 pm_translate_signal_group_number_on_island2(u64 subgroup) -+{ -+ -+ if (subgroup == 2) -+ subgroup = 3; -+ -+ if (subgroup <= 6) -+ return PM_ISLAND2_BASE_SIGNAL_GROUP_NUMBER + subgroup; -+ else if (subgroup == 7) -+ return PM_ISLAND2_SIGNAL_GROUP_NUMBER1; -+ else -+ return PM_ISLAND2_SIGNAL_GROUP_NUMBER2; -+} -+ -+static u64 pm_translate_signal_group_number_on_island3(u64 subgroup) -+{ -+ -+ switch (subgroup) { -+ case 2: -+ case 3: -+ case 4: -+ subgroup += 2; -+ break; -+ case 5: -+ subgroup = 8; -+ break; -+ default: -+ break; -+ } -+ return PM_ISLAND3_BASE_SIGNAL_GROUP_NUMBER + subgroup; -+} -+ -+static u64 pm_translate_signal_group_number_on_island4(u64 subgroup) -+{ -+ return PM_ISLAND4_BASE_SIGNAL_GROUP_NUMBER + subgroup; -+} -+ -+static u64 pm_translate_signal_group_number_on_island5(u64 subgroup) -+{ -+ -+ switch (subgroup) { -+ case 3: -+ subgroup = 4; -+ break; -+ case 4: -+ subgroup = 6; -+ break; -+ default: -+ break; -+ } -+ return PM_ISLAND5_BASE_SIGNAL_GROUP_NUMBER + subgroup; -+} -+ -+static u64 pm_translate_signal_group_number_on_island6(u64 subgroup, -+ u64 subsubgroup) -+{ -+ switch (subgroup) { -+ case 3: -+ case 4: -+ case 5: -+ subgroup += 1; -+ break; -+ default: -+ break; -+ } -+ -+ switch (subsubgroup) { -+ case 4: -+ case 5: -+ case 6: -+ subsubgroup += 2; -+ break; -+ case 7: -+ case 8: -+ case 9: -+ case 10: -+ subsubgroup += 4; -+ break; -+ case 11: -+ case 12: -+ case 13: -+ subsubgroup += 5; -+ break; -+ default: -+ break; -+ } -+ -+ if (subgroup <= 5) -+ return (PM_ISLAND6_BASE_SIGNAL_GROUP_NUMBER + subgroup); -+ else -+ return (PM_ISLAND6_BASE_SIGNAL_GROUP_NUMBER + subgroup -+ + subsubgroup - 1); -+} -+ -+static u64 pm_translate_signal_group_number_on_island7(u64 subgroup) -+{ -+ return PM_ISLAND7_BASE_SIGNAL_GROUP_NUMBER + subgroup; -+} -+ -+static u64 pm_translate_signal_group_number_on_island8(u64 subgroup) -+{ -+ return PM_ISLAND8_BASE_SIGNAL_GROUP_NUMBER + subgroup; -+} -+ -+static u64 pm_signal_group_to_ps3_lv1_signal_group(u64 group) -+{ -+ u64 island; -+ u64 subgroup; -+ u64 subsubgroup; -+ -+ subgroup = 0; -+ subsubgroup = 0; -+ island = 0; -+ if (group < 1000) { -+ if (group < 100) { -+ if (20 <= group && group < 30) { -+ island = 2; -+ subgroup = group - 20; -+ } else if (30 <= group && group < 40) { -+ island = 3; -+ subgroup = group - 30; -+ } else if (40 <= group && group < 50) { -+ island = 4; -+ subgroup = group - 40; -+ } else if (50 <= group && group < 60) { -+ island = 5; -+ subgroup = group - 50; -+ } else if (60 <= group && group < 70) { -+ island = 6; -+ subgroup = group - 60; -+ } else if (70 <= group && group < 80) { -+ island = 7; -+ subgroup = group - 70; -+ } else if (80 <= group && group < 90) { -+ island = 8; -+ subgroup = group - 80; -+ } -+ } else if (200 <= group && group < 300) { -+ island = 2; -+ subgroup = group - 200; -+ } else if (600 <= group && group < 700) { -+ island = 6; -+ subgroup = 5; -+ subsubgroup = group - 650; -+ } -+ } else if (6000 <= group && group < 7000) { -+ island = 6; -+ subgroup = 5; -+ subsubgroup = group - 6500; -+ } -+ -+ switch (island) { -+ case 2: -+ return pm_translate_signal_group_number_on_island2(subgroup); -+ case 3: -+ return pm_translate_signal_group_number_on_island3(subgroup); -+ case 4: -+ return pm_translate_signal_group_number_on_island4(subgroup); -+ case 5: -+ return pm_translate_signal_group_number_on_island5(subgroup); -+ case 6: -+ return pm_translate_signal_group_number_on_island6(subgroup, -+ subsubgroup); -+ case 7: -+ return pm_translate_signal_group_number_on_island7(subgroup); -+ case 8: -+ return pm_translate_signal_group_number_on_island8(subgroup); -+ default: -+ dev_dbg(sbd_core(), "%s:%u: island not found: %lu\n", __func__, -+ __LINE__, group); -+ BUG(); -+ break; -+ } -+ return 0; -+} -+ -+static u64 pm_bus_word_to_ps3_lv1_bus_word(u8 word) -+{ -+ -+ switch (word) { -+ case 1: -+ return 0xF000; -+ case 2: -+ return 0x0F00; -+ case 4: -+ return 0x00F0; -+ case 8: -+ default: -+ return 0x000F; -+ } -+} -+ -+static int __ps3_set_signal(u64 lv1_signal_group, u64 bus_select, -+ u64 signal_select, u64 attr1, u64 attr2, u64 attr3) -+{ -+ int ret; -+ -+ ret = lv1_set_lpm_signal(lpm_priv->lpm_id, lv1_signal_group, bus_select, -+ signal_select, attr1, attr2, attr3); -+ if (ret) -+ dev_err(sbd_core(), -+ "%s:%u: error:%d 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx\n", -+ __func__, __LINE__, ret, lv1_signal_group, bus_select, -+ signal_select, attr1, attr2, attr3); -+ -+ return ret; -+} -+ -+int ps3_set_signal(u64 signal_group, u8 signal_bit, u16 sub_unit, -+ u8 bus_word) -+{ -+ int ret; -+ u64 lv1_signal_group; -+ u64 bus_select; -+ u64 signal_select; -+ u64 attr1, attr2, attr3; -+ -+ if (signal_group == 0) -+ return __ps3_set_signal(0, 0, 0, 0, 0, 0); -+ -+ lv1_signal_group = -+ pm_signal_group_to_ps3_lv1_signal_group(signal_group); -+ bus_select = pm_bus_word_to_ps3_lv1_bus_word(bus_word); -+ -+ switch (signal_group) { -+ case PM_SIG_GROUP_SPU_TRIGGER: -+ signal_select = 1; -+ signal_select = signal_select << (63 - signal_bit); -+ break; -+ case PM_SIG_GROUP_SPU_EVENT: -+ signal_select = 1; -+ signal_select = (signal_select << (63 - signal_bit)) | 0x3; -+ break; -+ default: -+ signal_select = 0; -+ break; -+ } -+ -+ /* -+ * 0: physical object. -+ * 1: logical object. -+ * This parameter is only used for the PPE and SPE signals. -+ */ -+ attr1 = 1; -+ -+ /* -+ * This parameter is used to specify the target physical/logical -+ * PPE/SPE object. -+ */ -+ if (PM_SIG_GROUP_SPU <= signal_group && -+ signal_group < PM_SIG_GROUP_MFC_MAX) -+ attr2 = sub_unit; -+ else -+ attr2 = lpm_priv->pu_id; -+ -+ /* -+ * This parameter is only used for setting the SPE signal. -+ */ -+ attr3 = 0; -+ -+ ret = __ps3_set_signal(lv1_signal_group, bus_select, signal_select, -+ attr1, attr2, attr3); -+ if (ret) -+ dev_err(sbd_core(), "%s:%u: __ps3_set_signal failed: %d\n", -+ __func__, __LINE__, ret); -+ -+ return ret; -+} -+EXPORT_SYMBOL_GPL(ps3_set_signal); -+ -+u32 ps3_get_hw_thread_id(int cpu) -+{ -+ return get_hard_smp_processor_id(cpu); -+} -+EXPORT_SYMBOL_GPL(ps3_get_hw_thread_id); -+ -+/** -+ * ps3_enable_pm - Enable the entire performance monitoring unit. -+ * -+ * When we enable the LPM, all pending writes to counters get committed. -+ */ -+ -+void ps3_enable_pm(u32 cpu) -+{ -+ int result; -+ u64 tmp; -+ int insert_bookmark = 0; -+ -+ lpm_priv->tb_count = 0; -+ -+ if (use_start_stop_bookmark) { -+ if (!(lpm_priv->shadow.pm_start_stop & -+ (PS3_PM_START_STOP_START_MASK -+ | PS3_PM_START_STOP_STOP_MASK))) { -+ result = lv1_set_lpm_trigger_control(lpm_priv->lpm_id, -+ (PS3_PM_START_STOP_PPU_TH0_BOOKMARK_START | -+ PS3_PM_START_STOP_PPU_TH1_BOOKMARK_START | -+ PS3_PM_START_STOP_PPU_TH0_BOOKMARK_STOP | -+ PS3_PM_START_STOP_PPU_TH1_BOOKMARK_STOP), -+ 0xFFFFFFFFFFFFFFFFULL, &tmp); -+ -+ if (result) -+ dev_err(sbd_core(), "%s:%u: " -+ "lv1_set_lpm_trigger_control failed: " -+ "%s\n", __func__, __LINE__, -+ ps3_result(result)); -+ -+ insert_bookmark = !result; -+ } -+ } -+ -+ result = lv1_start_lpm(lpm_priv->lpm_id); -+ -+ if (result) -+ dev_err(sbd_core(), "%s:%u: lv1_start_lpm failed: %s\n", -+ __func__, __LINE__, ps3_result(result)); -+ -+ if (use_start_stop_bookmark && !result && insert_bookmark) -+ ps3_set_bookmark(get_tb() | PS3_PM_BOOKMARK_START); -+} -+EXPORT_SYMBOL_GPL(ps3_enable_pm); -+ -+/** -+ * ps3_disable_pm - Disable the entire performance monitoring unit. -+ */ -+ -+void ps3_disable_pm(u32 cpu) -+{ -+ int result; -+ u64 tmp; -+ -+ ps3_set_bookmark(get_tb() | PS3_PM_BOOKMARK_STOP); -+ -+ result = lv1_stop_lpm(lpm_priv->lpm_id, &tmp); -+ -+ if (result) { -+ if(result != LV1_WRONG_STATE) -+ dev_err(sbd_core(), "%s:%u: lv1_stop_lpm failed: %s\n", -+ __func__, __LINE__, ps3_result(result)); -+ return; -+ } -+ -+ lpm_priv->tb_count = tmp; -+ -+ dev_dbg(sbd_core(), "%s:%u: tb_count %lu (%lxh)\n", __func__, __LINE__, -+ lpm_priv->tb_count, lpm_priv->tb_count); -+} -+EXPORT_SYMBOL_GPL(ps3_disable_pm); -+ -+/** -+ * ps3_lpm_copy_tb - Copy data from the trace buffer to a kernel buffer. -+ * @offset: Offset in bytes from the start of the trace buffer. -+ * @buf: Copy destination. -+ * @count: Maximum count of bytes to copy. -+ * @bytes_copied: Pointer to a variable that will recieve the number of -+ * bytes copied to @buf. -+ * -+ * On error @buf will contain any successfully copied trace buffer data -+ * and bytes_copied will be set to the number of bytes successfully copied. -+ */ -+ -+int ps3_lpm_copy_tb(unsigned long offset, void *buf, unsigned long count, -+ unsigned long *bytes_copied) -+{ -+ int result; -+ -+ *bytes_copied = 0; -+ -+ if (!lpm_priv->tb_cache) -+ return -EPERM; -+ -+ if (offset >= lpm_priv->tb_count) -+ return 0; -+ -+ count = min(count, lpm_priv->tb_count - offset); -+ -+ while (*bytes_copied < count) { -+ const unsigned long request = count - *bytes_copied; -+ u64 tmp; -+ -+ result = lv1_copy_lpm_trace_buffer(lpm_priv->lpm_id, offset, -+ request, &tmp); -+ if (result) { -+ dev_dbg(sbd_core(), "%s:%u: 0x%lx bytes at 0x%lx\n", -+ __func__, __LINE__, request, offset); -+ -+ dev_err(sbd_core(), "%s:%u: lv1_copy_lpm_trace_buffer " -+ "failed: %s\n", __func__, __LINE__, -+ ps3_result(result)); -+ return result == LV1_WRONG_STATE ? -EBUSY : -EINVAL; -+ } -+ -+ memcpy(buf, lpm_priv->tb_cache, tmp); -+ buf += tmp; -+ *bytes_copied += tmp; -+ offset += tmp; -+ } -+ dev_dbg(sbd_core(), "%s:%u: copied %lxh bytes\n", __func__, __LINE__, -+ *bytes_copied); -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(ps3_lpm_copy_tb); -+ -+/** -+ * ps3_lpm_copy_tb_to_user - Copy data from the trace buffer to a user buffer. -+ * @offset: Offset in bytes from the start of the trace buffer. -+ * @buf: A __user copy destination. -+ * @count: Maximum count of bytes to copy. -+ * @bytes_copied: Pointer to a variable that will recieve the number of -+ * bytes copied to @buf. -+ * -+ * On error @buf will contain any successfully copied trace buffer data -+ * and bytes_copied will be set to the number of bytes successfully copied. -+ */ -+ -+int ps3_lpm_copy_tb_to_user(unsigned long offset, void __user *buf, -+ unsigned long count, unsigned long *bytes_copied) -+{ -+ int result; -+ -+ *bytes_copied = 0; -+ -+ if (!lpm_priv->tb_cache) -+ return -EPERM; -+ -+ if (offset >= lpm_priv->tb_count) -+ return 0; -+ -+ count = min(count, lpm_priv->tb_count - offset); -+ -+ while (*bytes_copied < count) { -+ const unsigned long request = count - *bytes_copied; -+ u64 tmp; -+ -+ result = lv1_copy_lpm_trace_buffer(lpm_priv->lpm_id, offset, -+ request, &tmp); -+ if (result) { -+ dev_dbg(sbd_core(), "%s:%u: 0x%lx bytes at 0x%lx\n", -+ __func__, __LINE__, request, offset); -+ dev_err(sbd_core(), "%s:%u: lv1_copy_lpm_trace_buffer " -+ "failed: %s\n", __func__, __LINE__, -+ ps3_result(result)); -+ return result == LV1_WRONG_STATE ? -EBUSY : -EINVAL; -+ } -+ -+ result = copy_to_user(buf, lpm_priv->tb_cache, tmp); -+ -+ if (result) { -+ dev_dbg(sbd_core(), "%s:%u: 0x%lx bytes at 0x%p\n", -+ __func__, __LINE__, tmp, buf); -+ dev_err(sbd_core(), "%s:%u: copy_to_user failed: %d\n", -+ __func__, __LINE__, result); -+ return -EFAULT; -+ } -+ -+ buf += tmp; -+ *bytes_copied += tmp; -+ offset += tmp; -+ } -+ dev_dbg(sbd_core(), "%s:%u: copied %lxh bytes\n", __func__, __LINE__, -+ *bytes_copied); -+ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(ps3_lpm_copy_tb_to_user); -+ -+/** -+ * ps3_get_and_clear_pm_interrupts - -+ * -+ * Clearing interrupts for the entire performance monitoring unit. -+ * Reading pm_status clears the interrupt bits. -+ */ -+ -+u32 ps3_get_and_clear_pm_interrupts(u32 cpu) -+{ -+ return ps3_read_pm(cpu, pm_status); -+} -+EXPORT_SYMBOL_GPL(ps3_get_and_clear_pm_interrupts); -+ -+/** -+ * ps3_enable_pm_interrupts - -+ * -+ * Enabling interrupts for the entire performance monitoring unit. -+ * Enables the interrupt bits in the pm_status register. -+ */ -+ -+void ps3_enable_pm_interrupts(u32 cpu, u32 thread, u32 mask) -+{ -+ if (mask) -+ ps3_write_pm(cpu, pm_status, mask); -+} -+EXPORT_SYMBOL_GPL(ps3_enable_pm_interrupts); -+ -+/** -+ * ps3_enable_pm_interrupts - -+ * -+ * Disabling interrupts for the entire performance monitoring unit. -+ */ -+ -+void ps3_disable_pm_interrupts(u32 cpu) -+{ -+ ps3_get_and_clear_pm_interrupts(cpu); -+ ps3_write_pm(cpu, pm_status, 0); -+} -+EXPORT_SYMBOL_GPL(ps3_disable_pm_interrupts); -+ -+/** -+ * ps3_lpm_open - Open the logical performance monitor device. -+ * @tb_type: Specifies the type of trace buffer lv1 sould use for this lpm -+ * instance, specified by one of enum ps3_lpm_tb_type. -+ * @tb_cache: Optional user supplied buffer to use as the trace buffer cache. -+ * If NULL, the driver will allocate and manage an internal buffer. -+ * Unused when when @tb_type is PS3_LPM_TB_TYPE_NONE. -+ * @tb_cache_size: The size in bytes of the user supplied @tb_cache buffer. -+ * Unused when @tb_cache is NULL or @tb_type is PS3_LPM_TB_TYPE_NONE. -+ */ -+ -+int ps3_lpm_open(enum ps3_lpm_tb_type tb_type, void *tb_cache, -+ u64 tb_cache_size) -+{ -+ int result; -+ u64 tb_size; -+ -+ BUG_ON(!lpm_priv); -+ BUG_ON(tb_type != PS3_LPM_TB_TYPE_NONE -+ && tb_type != PS3_LPM_TB_TYPE_INTERNAL); -+ -+ if (tb_type == PS3_LPM_TB_TYPE_NONE && tb_cache) -+ dev_dbg(sbd_core(), "%s:%u: bad in vals\n", __func__, __LINE__); -+ -+ if (!atomic_add_unless(&lpm_priv->open, 1, 1)) { -+ dev_dbg(sbd_core(), "%s:%u: busy\n", __func__, __LINE__); -+ return -EBUSY; -+ } -+ -+ /* Note tb_cache needs 128 byte alignment. */ -+ -+ if (tb_type == PS3_LPM_TB_TYPE_NONE) { -+ lpm_priv->tb_cache_size = 0; -+ lpm_priv->tb_cache_internal = NULL; -+ lpm_priv->tb_cache = NULL; -+ } else if (tb_cache) { -+ if (tb_cache != (void *)_ALIGN_UP((unsigned long)tb_cache, 128) -+ || tb_cache_size != _ALIGN_UP(tb_cache_size, 128)) { -+ dev_err(sbd_core(), "%s:%u: unaligned tb_cache\n", -+ __func__, __LINE__); -+ result = -EINVAL; -+ goto fail_align; -+ } -+ lpm_priv->tb_cache_size = tb_cache_size; -+ lpm_priv->tb_cache_internal = NULL; -+ lpm_priv->tb_cache = tb_cache; -+ } else { -+ lpm_priv->tb_cache_size = PS3_LPM_DEFAULT_TB_CACHE_SIZE; -+ lpm_priv->tb_cache_internal = kzalloc( -+ lpm_priv->tb_cache_size + 127, GFP_KERNEL); -+ if (!lpm_priv->tb_cache_internal) { -+ dev_err(sbd_core(), "%s:%u: alloc internal tb_cache " -+ "failed\n", __func__, __LINE__); -+ result = -ENOMEM; -+ goto fail_malloc; -+ } -+ lpm_priv->tb_cache = (void *)_ALIGN_UP( -+ (unsigned long)lpm_priv->tb_cache_internal, 128); -+ } -+ -+ result = lv1_construct_lpm(lpm_priv->node_id, tb_type, 0, 0, -+ ps3_mm_phys_to_lpar(__pa(lpm_priv->tb_cache)), -+ lpm_priv->tb_cache_size, &lpm_priv->lpm_id, -+ &lpm_priv->outlet_id, &tb_size); -+ -+ if (result) { -+ dev_err(sbd_core(), "%s:%u: lv1_construct_lpm failed: %s\n", -+ __func__, __LINE__, ps3_result(result)); -+ result = -EINVAL; -+ goto fail_construct; -+ } -+ -+ lpm_priv->shadow.pm_control = PS3_LPM_SHADOW_REG_INIT; -+ lpm_priv->shadow.pm_start_stop = PS3_LPM_SHADOW_REG_INIT; -+ lpm_priv->shadow.pm_interval = PS3_LPM_SHADOW_REG_INIT; -+ lpm_priv->shadow.group_control = PS3_LPM_SHADOW_REG_INIT; -+ lpm_priv->shadow.debug_bus_control = PS3_LPM_SHADOW_REG_INIT; -+ -+ dev_dbg(sbd_core(), "%s:%u: lpm_id 0x%lx, outlet_id 0x%lx, " -+ "tb_size 0x%lx\n", __func__, __LINE__, lpm_priv->lpm_id, -+ lpm_priv->outlet_id, tb_size); -+ -+ return 0; -+ -+fail_construct: -+ kfree(lpm_priv->tb_cache_internal); -+ lpm_priv->tb_cache_internal = NULL; -+fail_malloc: -+fail_align: -+ atomic_dec(&lpm_priv->open); -+ return result; -+} -+EXPORT_SYMBOL_GPL(ps3_lpm_open); -+ -+/** -+ * ps3_lpm_close - Close the lpm device. -+ * -+ */ -+ -+int ps3_lpm_close(void) -+{ -+ dev_dbg(sbd_core(), "%s:%u\n", __func__, __LINE__); -+ -+ lv1_destruct_lpm(lpm_priv->lpm_id); -+ lpm_priv->lpm_id = 0; -+ -+ kfree(lpm_priv->tb_cache_internal); -+ lpm_priv->tb_cache_internal = NULL; -+ -+ atomic_dec(&lpm_priv->open); -+ return 0; -+} -+EXPORT_SYMBOL_GPL(ps3_lpm_close); -+ -+static int __devinit ps3_lpm_probe(struct ps3_system_bus_device *dev) -+{ -+ dev_dbg(&dev->core, " -> %s:%u\n", __func__, __LINE__); -+ -+ if (lpm_priv) { -+ dev_info(&dev->core, "%s:%u: called twice\n", -+ __func__, __LINE__); -+ return -EBUSY; -+ } -+ -+ lpm_priv = kzalloc(sizeof(*lpm_priv), GFP_KERNEL); -+ -+ if (!lpm_priv) -+ return -ENOMEM; -+ -+ lpm_priv->sbd = dev; -+ lpm_priv->node_id = dev->lpm.node_id; -+ lpm_priv->pu_id = dev->lpm.pu_id; -+ lpm_priv->rights = dev->lpm.rights; -+ -+ dev_info(&dev->core, " <- %s:%u:\n", __func__, __LINE__); -+ -+ return 0; -+} -+ -+static int ps3_lpm_remove(struct ps3_system_bus_device *dev) -+{ -+ dev_dbg(&dev->core, " -> %s:%u:\n", __func__, __LINE__); -+ -+ ps3_lpm_close(); -+ -+ kfree(lpm_priv); -+ lpm_priv = NULL; -+ -+ dev_info(&dev->core, " <- %s:%u:\n", __func__, __LINE__); -+ return 0; -+} -+ -+static struct ps3_system_bus_driver ps3_lpm_driver = { -+ .match_id = PS3_MATCH_ID_LPM, -+ .core.name = "ps3-lpm", -+ .core.owner = THIS_MODULE, -+ .probe = ps3_lpm_probe, -+ .remove = ps3_lpm_remove, -+ .shutdown = ps3_lpm_remove, -+}; -+ -+static int __init ps3_lpm_init(void) -+{ -+ pr_debug("%s:%d:\n", __func__, __LINE__); -+ return ps3_system_bus_driver_register(&ps3_lpm_driver); -+} -+ -+static void __exit ps3_lpm_exit(void) -+{ -+ pr_debug("%s:%d:\n", __func__, __LINE__); -+ ps3_system_bus_driver_unregister(&ps3_lpm_driver); -+} -+ -+module_init(ps3_lpm_init); -+module_exit(ps3_lpm_exit); -+ -+MODULE_LICENSE("GPL v2"); -+MODULE_DESCRIPTION("PS3 Logical Performance Monitor Driver"); -+MODULE_AUTHOR("Sony Corporation"); -+MODULE_ALIAS(PS3_MODULE_ALIAS_LPM); ---- a/drivers/ps3/ps3-sys-manager.c -+++ b/drivers/ps3/ps3-sys-manager.c -@@ -452,7 +452,7 @@ static int ps3_sys_manager_handle_event( - case PS3_SM_EVENT_THERMAL_ALERT: - dev_dbg(&dev->core, "%s:%d: THERMAL_ALERT (zone %u)\n", - __func__, __LINE__, event.value); -- printk(KERN_INFO "PS3 Thermal Alert Zone %u\n", event.value); -+ pr_info("PS3 Thermal Alert Zone %u\n", event.value); - break; - case PS3_SM_EVENT_THERMAL_CLEARED: - dev_dbg(&dev->core, "%s:%d: THERMAL_CLEARED (zone %u)\n", -@@ -488,7 +488,7 @@ static int ps3_sys_manager_handle_cmd(st - result = ps3_vuart_read(dev, &cmd, sizeof(cmd)); - BUG_ON(result && "need to retry here"); - -- if(result) -+ if (result) - return result; - - if (cmd.version != 1) { -@@ -521,7 +521,7 @@ static int ps3_sys_manager_handle_msg(st - result = ps3_vuart_read(dev, &header, - sizeof(struct ps3_sys_manager_header)); - -- if(result) -+ if (result) - return result; - - if (header.version != 1) { -@@ -589,9 +589,9 @@ static void ps3_sys_manager_final_power_ - PS3_SM_WAKE_DEFAULT); - ps3_sys_manager_send_request_shutdown(dev); - -- printk(KERN_EMERG "System Halted, OK to turn off power\n"); -+ pr_emerg("System Halted, OK to turn off power\n"); - -- while(1) -+ while (1) - ps3_sys_manager_handle_msg(dev); - } - -@@ -626,9 +626,9 @@ static void ps3_sys_manager_final_restar - PS3_SM_WAKE_DEFAULT); - ps3_sys_manager_send_request_shutdown(dev); - -- printk(KERN_EMERG "System Halted, OK to turn off power\n"); -+ pr_emerg("System Halted, OK to turn off power\n"); - -- while(1) -+ while (1) - ps3_sys_manager_handle_msg(dev); - } - ---- a/drivers/ps3/ps3-vuart.c -+++ b/drivers/ps3/ps3-vuart.c -@@ -108,18 +108,18 @@ static struct ps3_vuart_port_priv *to_po - struct ports_bmp { - u64 status; - u64 unused[3]; --} __attribute__ ((aligned (32))); -+} __attribute__((aligned(32))); - - #define dump_ports_bmp(_b) _dump_ports_bmp(_b, __func__, __LINE__) - static void __maybe_unused _dump_ports_bmp( -- const struct ports_bmp* bmp, const char* func, int line) -+ const struct ports_bmp *bmp, const char *func, int line) - { - pr_debug("%s:%d: ports_bmp: %016lxh\n", func, line, bmp->status); - } - - #define dump_port_params(_b) _dump_port_params(_b, __func__, __LINE__) - static void __maybe_unused _dump_port_params(unsigned int port_number, -- const char* func, int line) -+ const char *func, int line) - { - #if defined(DEBUG) - static const char *strings[] = { -@@ -363,7 +363,7 @@ int ps3_vuart_disable_interrupt_disconne - */ - - static int ps3_vuart_raw_write(struct ps3_system_bus_device *dev, -- const void* buf, unsigned int bytes, unsigned long *bytes_written) -+ const void *buf, unsigned int bytes, unsigned long *bytes_written) - { - int result; - struct ps3_vuart_port_priv *priv = to_port_priv(dev); -@@ -431,7 +431,7 @@ void ps3_vuart_clear_rx_bytes(struct ps3 - int result; - struct ps3_vuart_port_priv *priv = to_port_priv(dev); - u64 bytes_waiting; -- void* tmp; -+ void *tmp; - - result = ps3_vuart_get_rx_bytes_waiting(dev, &bytes_waiting); - -@@ -526,9 +526,8 @@ int ps3_vuart_write(struct ps3_system_bu - - lb = kmalloc(sizeof(struct list_buffer) + bytes, GFP_KERNEL); - -- if (!lb) { -+ if (!lb) - return -ENOMEM; -- } - - memcpy(lb->data, buf, bytes); - lb->head = lb->data; -@@ -878,7 +877,7 @@ static int ps3_vuart_handle_port_interru - struct vuart_bus_priv { - struct ports_bmp *bmp; - unsigned int virq; -- struct semaphore probe_mutex; -+ struct mutex probe_mutex; - int use_count; - struct ps3_system_bus_device *devices[PORT_COUNT]; - } static vuart_bus_priv; -@@ -926,9 +925,8 @@ static int ps3_vuart_bus_interrupt_get(v - - BUG_ON(vuart_bus_priv.use_count > 2); - -- if (vuart_bus_priv.use_count != 1) { -+ if (vuart_bus_priv.use_count != 1) - return 0; -- } - - BUG_ON(vuart_bus_priv.bmp); - -@@ -1017,7 +1015,7 @@ static int ps3_vuart_probe(struct ps3_sy - return -EINVAL; - } - -- down(&vuart_bus_priv.probe_mutex); -+ mutex_lock(&vuart_bus_priv.probe_mutex); - - result = ps3_vuart_bus_interrupt_get(); - -@@ -1077,7 +1075,7 @@ static int ps3_vuart_probe(struct ps3_sy - goto fail_probe; - } - -- up(&vuart_bus_priv.probe_mutex); -+ mutex_unlock(&vuart_bus_priv.probe_mutex); - - return result; - -@@ -1090,7 +1088,7 @@ fail_dev_malloc: - fail_busy: - ps3_vuart_bus_interrupt_put(); - fail_setup_interrupt: -- up(&vuart_bus_priv.probe_mutex); -+ mutex_unlock(&vuart_bus_priv.probe_mutex); - dev_dbg(&dev->core, "%s:%d: failed\n", __func__, __LINE__); - return result; - } -@@ -1129,7 +1127,7 @@ static int ps3_vuart_remove(struct ps3_s - - BUG_ON(!dev); - -- down(&vuart_bus_priv.probe_mutex); -+ mutex_lock(&vuart_bus_priv.probe_mutex); - - dev_dbg(&dev->core, " -> %s:%d: match_id %d\n", __func__, __LINE__, - dev->match_id); -@@ -1137,7 +1135,7 @@ static int ps3_vuart_remove(struct ps3_s - if (!dev->core.driver) { - dev_dbg(&dev->core, "%s:%d: no driver bound\n", __func__, - __LINE__); -- up(&vuart_bus_priv.probe_mutex); -+ mutex_unlock(&vuart_bus_priv.probe_mutex); - return 0; - } - -@@ -1160,7 +1158,7 @@ static int ps3_vuart_remove(struct ps3_s - priv = NULL; - - dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__); -- up(&vuart_bus_priv.probe_mutex); -+ mutex_unlock(&vuart_bus_priv.probe_mutex); - return 0; - } - -@@ -1180,7 +1178,7 @@ static int ps3_vuart_shutdown(struct ps3 - - BUG_ON(!dev); - -- down(&vuart_bus_priv.probe_mutex); -+ mutex_lock(&vuart_bus_priv.probe_mutex); - - dev_dbg(&dev->core, " -> %s:%d: match_id %d\n", __func__, __LINE__, - dev->match_id); -@@ -1188,7 +1186,7 @@ static int ps3_vuart_shutdown(struct ps3 - if (!dev->core.driver) { - dev_dbg(&dev->core, "%s:%d: no driver bound\n", __func__, - __LINE__); -- up(&vuart_bus_priv.probe_mutex); -+ mutex_unlock(&vuart_bus_priv.probe_mutex); - return 0; - } - -@@ -1212,7 +1210,7 @@ static int ps3_vuart_shutdown(struct ps3 - - dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__); - -- up(&vuart_bus_priv.probe_mutex); -+ mutex_unlock(&vuart_bus_priv.probe_mutex); - return 0; - } - -@@ -1223,7 +1221,7 @@ static int __init ps3_vuart_bus_init(voi - if (!firmware_has_feature(FW_FEATURE_PS3_LV1)) - return -ENODEV; - -- init_MUTEX(&vuart_bus_priv.probe_mutex); -+ mutex_init(&vuart_bus_priv.probe_mutex); - - return 0; - } ---- a/drivers/serial/Kconfig -+++ b/drivers/serial/Kconfig -@@ -1284,4 +1284,14 @@ config SERIAL_OF_PLATFORM - Currently, only 8250 compatible ports are supported, but - others can easily be added. - -+config SERIAL_QE -+ tristate "Freescale QUICC Engine serial port support" -+ depends on QUICC_ENGINE -+ select SERIAL_CORE -+ select FW_LOADER -+ default n -+ help -+ This driver supports the QE serial ports on Freescale embedded -+ PowerPC that contain a QUICC Engine. -+ - endmenu ---- a/drivers/serial/Makefile -+++ b/drivers/serial/Makefile -@@ -64,3 +64,4 @@ obj-$(CONFIG_SERIAL_UARTLITE) += uartlit - obj-$(CONFIG_SERIAL_NETX) += netx-serial.o - obj-$(CONFIG_SERIAL_OF_PLATFORM) += of_serial.o - obj-$(CONFIG_SERIAL_KS8695) += serial_ks8695.o -+obj-$(CONFIG_SERIAL_QE) += ucc_uart.o ---- a/drivers/serial/cpm_uart/cpm_uart_cpm1.c -+++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.c -@@ -52,11 +52,7 @@ - #ifdef CONFIG_PPC_CPM_NEW_BINDING - void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd) - { -- u16 __iomem *cpcr = &cpmp->cp_cpcr; -- -- out_be16(cpcr, port->command | (cmd << 8) | CPM_CR_FLG); -- while (in_be16(cpcr) & CPM_CR_FLG) -- ; -+ cpm_command(port->command, cmd); - } - #else - void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd) ---- a/drivers/serial/cpm_uart/cpm_uart_cpm2.c -+++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c -@@ -52,13 +52,7 @@ - #ifdef CONFIG_PPC_CPM_NEW_BINDING - void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd) - { -- cpm_cpm2_t __iomem *cp = cpm2_map(im_cpm); -- -- out_be32(&cp->cp_cpcr, port->command | cmd | CPM_CR_FLG); -- while (in_be32(&cp->cp_cpcr) & CPM_CR_FLG) -- ; -- -- cpm2_unmap(cp); -+ cpm_command(port->command, cmd); - } - #else - void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd) -@@ -171,9 +165,9 @@ void scc2_lineif(struct uart_cpm_port *p - * really has to get out of the driver so boards can - * be supported in a sane fashion. - */ -+ volatile cpmux_t *cpmux = cpm2_map(im_cpmux); - #ifndef CONFIG_STX_GP3 - volatile iop_cpm2_t *io = cpm2_map(im_ioport); -- volatile cpmux_t *cpmux = cpm2_map(im_cpmux); - - io->iop_pparb |= 0x008b0000; - io->iop_pdirb |= 0x00880000; ---- a/drivers/serial/mpc52xx_uart.c -+++ b/drivers/serial/mpc52xx_uart.c -@@ -36,7 +36,7 @@ - * DCD. However, the pin multiplexing aren't changed and should be set either - * by the bootloader or in the platform init code. - * -- * The idx field must be equal to the PSC index ( e.g. 0 for PSC1, 1 for PSC2, -+ * The idx field must be equal to the PSC index (e.g. 0 for PSC1, 1 for PSC2, - * and so on). So the PSC1 is mapped to /dev/ttyPSC0, PSC2 to /dev/ttyPSC1 and - * so on. But be warned, it's an ABSOLUTE REQUIREMENT ! This is needed mainly - * fpr the console code : without this 1:1 mapping, at early boot time, when we -@@ -68,11 +68,12 @@ - #include - #include - --#include --#include -+#include -+#include - - #if defined(CONFIG_PPC_MERGE) --#include -+#include -+#include - #else - #include - #endif -@@ -111,16 +112,18 @@ static void mpc52xx_uart_of_enumerate(vo - #endif - - #define PSC(port) ((struct mpc52xx_psc __iomem *)((port)->membase)) -+#define FIFO(port) ((struct mpc52xx_psc_fifo __iomem *)(PSC(port)+1)) - - - /* Forward declaration of the interruption handling routine */ --static irqreturn_t mpc52xx_uart_int(int irq,void *dev_id); -+static irqreturn_t mpc52xx_uart_int(int irq, void *dev_id); - - - /* Simple macro to test if a port is console or not. This one is taken - * for serial_core.c and maybe should be moved to serial_core.h ? */ - #ifdef CONFIG_SERIAL_CORE_CONSOLE --#define uart_console(port) ((port)->cons && (port)->cons->index == (port)->line) -+#define uart_console(port) \ -+ ((port)->cons && (port)->cons->index == (port)->line) - #else - #define uart_console(port) (0) - #endif -@@ -162,7 +165,7 @@ mpc52xx_uart_stop_tx(struct uart_port *p - { - /* port->lock taken by caller */ - port->read_status_mask &= ~MPC52xx_PSC_IMR_TXRDY; -- out_be16(&PSC(port)->mpc52xx_psc_imr,port->read_status_mask); -+ out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask); - } - - static void -@@ -170,7 +173,7 @@ mpc52xx_uart_start_tx(struct uart_port * - { - /* port->lock taken by caller */ - port->read_status_mask |= MPC52xx_PSC_IMR_TXRDY; -- out_be16(&PSC(port)->mpc52xx_psc_imr,port->read_status_mask); -+ out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask); - } - - static void -@@ -184,7 +187,7 @@ mpc52xx_uart_send_xchar(struct uart_port - /* Make sure tx interrupts are on */ - /* Truly necessary ??? They should be anyway */ - port->read_status_mask |= MPC52xx_PSC_IMR_TXRDY; -- out_be16(&PSC(port)->mpc52xx_psc_imr,port->read_status_mask); -+ out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask); - } - - spin_unlock_irqrestore(&port->lock, flags); -@@ -195,7 +198,7 @@ mpc52xx_uart_stop_rx(struct uart_port *p - { - /* port->lock taken by caller */ - port->read_status_mask &= ~MPC52xx_PSC_IMR_RXRDY; -- out_be16(&PSC(port)->mpc52xx_psc_imr,port->read_status_mask); -+ out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask); - } - - static void -@@ -210,10 +213,10 @@ mpc52xx_uart_break_ctl(struct uart_port - unsigned long flags; - spin_lock_irqsave(&port->lock, flags); - -- if ( ctl == -1 ) -- out_8(&PSC(port)->command,MPC52xx_PSC_START_BRK); -+ if (ctl == -1) -+ out_8(&PSC(port)->command, MPC52xx_PSC_START_BRK); - else -- out_8(&PSC(port)->command,MPC52xx_PSC_STOP_BRK); -+ out_8(&PSC(port)->command, MPC52xx_PSC_STOP_BRK); - - spin_unlock_irqrestore(&port->lock, flags); - } -@@ -222,6 +225,7 @@ static int - mpc52xx_uart_startup(struct uart_port *port) - { - struct mpc52xx_psc __iomem *psc = PSC(port); -+ struct mpc52xx_psc_fifo __iomem *fifo = FIFO(port); - int ret; - - /* Request IRQ */ -@@ -231,23 +235,23 @@ mpc52xx_uart_startup(struct uart_port *p - return ret; - - /* Reset/activate the port, clear and enable interrupts */ -- out_8(&psc->command,MPC52xx_PSC_RST_RX); -- out_8(&psc->command,MPC52xx_PSC_RST_TX); -+ out_8(&psc->command, MPC52xx_PSC_RST_RX); -+ out_8(&psc->command, MPC52xx_PSC_RST_TX); - -- out_be32(&psc->sicr,0); /* UART mode DCD ignored */ -+ out_be32(&psc->sicr, 0); /* UART mode DCD ignored */ - - out_be16(&psc->mpc52xx_psc_clock_select, 0xdd00); /* /16 prescaler on */ - -- out_8(&psc->rfcntl, 0x00); -- out_be16(&psc->rfalarm, 0x1ff); -- out_8(&psc->tfcntl, 0x07); -- out_be16(&psc->tfalarm, 0x80); -+ out_8(&fifo->rfcntl, 0x00); -+ out_be16(&fifo->rfalarm, 0x1ff); -+ out_8(&fifo->tfcntl, 0x07); -+ out_be16(&fifo->tfalarm, 0x80); - - port->read_status_mask |= MPC52xx_PSC_IMR_RXRDY | MPC52xx_PSC_IMR_TXRDY; -- out_be16(&psc->mpc52xx_psc_imr,port->read_status_mask); -+ out_be16(&psc->mpc52xx_psc_imr, port->read_status_mask); - -- out_8(&psc->command,MPC52xx_PSC_TX_ENABLE); -- out_8(&psc->command,MPC52xx_PSC_RX_ENABLE); -+ out_8(&psc->command, MPC52xx_PSC_TX_ENABLE); -+ out_8(&psc->command, MPC52xx_PSC_RX_ENABLE); - - return 0; - } -@@ -258,12 +262,12 @@ mpc52xx_uart_shutdown(struct uart_port * - struct mpc52xx_psc __iomem *psc = PSC(port); - - /* Shut down the port. Leave TX active if on a console port */ -- out_8(&psc->command,MPC52xx_PSC_RST_RX); -+ out_8(&psc->command, MPC52xx_PSC_RST_RX); - if (!uart_console(port)) -- out_8(&psc->command,MPC52xx_PSC_RST_TX); -+ out_8(&psc->command, MPC52xx_PSC_RST_TX); - - port->read_status_mask = 0; -- out_be16(&psc->mpc52xx_psc_imr,port->read_status_mask); -+ out_be16(&psc->mpc52xx_psc_imr, port->read_status_mask); - - /* Release interrupt */ - free_irq(port->irq, port); -@@ -271,7 +275,7 @@ mpc52xx_uart_shutdown(struct uart_port * - - static void - mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new, -- struct ktermios *old) -+ struct ktermios *old) - { - struct mpc52xx_psc __iomem *psc = PSC(port); - unsigned long flags; -@@ -283,14 +287,14 @@ mpc52xx_uart_set_termios(struct uart_por - mr1 = 0; - - switch (new->c_cflag & CSIZE) { -- case CS5: mr1 |= MPC52xx_PSC_MODE_5_BITS; -- break; -- case CS6: mr1 |= MPC52xx_PSC_MODE_6_BITS; -- break; -- case CS7: mr1 |= MPC52xx_PSC_MODE_7_BITS; -- break; -- case CS8: -- default: mr1 |= MPC52xx_PSC_MODE_8_BITS; -+ case CS5: mr1 |= MPC52xx_PSC_MODE_5_BITS; -+ break; -+ case CS6: mr1 |= MPC52xx_PSC_MODE_6_BITS; -+ break; -+ case CS7: mr1 |= MPC52xx_PSC_MODE_7_BITS; -+ break; -+ case CS8: -+ default: mr1 |= MPC52xx_PSC_MODE_8_BITS; - } - - if (new->c_cflag & PARENB) { -@@ -332,24 +336,24 @@ mpc52xx_uart_set_termios(struct uart_por - udelay(1); - - if (!j) -- printk( KERN_ERR "mpc52xx_uart.c: " -+ printk(KERN_ERR "mpc52xx_uart.c: " - "Unable to flush RX & TX fifos in-time in set_termios." -- "Some chars may have been lost.\n" ); -+ "Some chars may have been lost.\n"); - - /* Reset the TX & RX */ -- out_8(&psc->command,MPC52xx_PSC_RST_RX); -- out_8(&psc->command,MPC52xx_PSC_RST_TX); -+ out_8(&psc->command, MPC52xx_PSC_RST_RX); -+ out_8(&psc->command, MPC52xx_PSC_RST_TX); - - /* Send new mode settings */ -- out_8(&psc->command,MPC52xx_PSC_SEL_MODE_REG_1); -- out_8(&psc->mode,mr1); -- out_8(&psc->mode,mr2); -- out_8(&psc->ctur,ctr >> 8); -- out_8(&psc->ctlr,ctr & 0xff); -+ out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1); -+ out_8(&psc->mode, mr1); -+ out_8(&psc->mode, mr2); -+ out_8(&psc->ctur, ctr >> 8); -+ out_8(&psc->ctlr, ctr & 0xff); - - /* Reenable TX & RX */ -- out_8(&psc->command,MPC52xx_PSC_TX_ENABLE); -- out_8(&psc->command,MPC52xx_PSC_RX_ENABLE); -+ out_8(&psc->command, MPC52xx_PSC_TX_ENABLE); -+ out_8(&psc->command, MPC52xx_PSC_RX_ENABLE); - - /* We're all set, release the lock */ - spin_unlock_irqrestore(&port->lock, flags); -@@ -364,7 +368,8 @@ mpc52xx_uart_type(struct uart_port *port - static void - mpc52xx_uart_release_port(struct uart_port *port) - { -- if (port->flags & UPF_IOREMAP) { /* remapped by us ? */ -+ /* remapped by us ? */ -+ if (port->flags & UPF_IOREMAP) { - iounmap(port->membase); - port->membase = NULL; - } -@@ -379,7 +384,7 @@ mpc52xx_uart_request_port(struct uart_po - - if (port->flags & UPF_IOREMAP) /* Need to remap ? */ - port->membase = ioremap(port->mapbase, -- sizeof(struct mpc52xx_psc)); -+ sizeof(struct mpc52xx_psc)); - - if (!port->membase) - return -EINVAL; -@@ -398,22 +403,22 @@ mpc52xx_uart_request_port(struct uart_po - static void - mpc52xx_uart_config_port(struct uart_port *port, int flags) - { -- if ( (flags & UART_CONFIG_TYPE) && -- (mpc52xx_uart_request_port(port) == 0) ) -- port->type = PORT_MPC52xx; -+ if ((flags & UART_CONFIG_TYPE) -+ && (mpc52xx_uart_request_port(port) == 0)) -+ port->type = PORT_MPC52xx; - } - - static int - mpc52xx_uart_verify_port(struct uart_port *port, struct serial_struct *ser) - { -- if ( ser->type != PORT_UNKNOWN && ser->type != PORT_MPC52xx ) -+ if (ser->type != PORT_UNKNOWN && ser->type != PORT_MPC52xx) - return -EINVAL; - -- if ( (ser->irq != port->irq) || -- (ser->io_type != SERIAL_IO_MEM) || -- (ser->baud_base != port->uartclk) || -- (ser->iomem_base != (void*)port->mapbase) || -- (ser->hub6 != 0 ) ) -+ if ((ser->irq != port->irq) || -+ (ser->io_type != SERIAL_IO_MEM) || -+ (ser->baud_base != port->uartclk) || -+ (ser->iomem_base != (void *)port->mapbase) || -+ (ser->hub6 != 0)) - return -EINVAL; - - return 0; -@@ -455,8 +460,8 @@ mpc52xx_uart_int_rx_chars(struct uart_po - unsigned short status; - - /* While we can read, do so ! */ -- while ( (status = in_be16(&PSC(port)->mpc52xx_psc_status)) & -- MPC52xx_PSC_SR_RXRDY) { -+ while ((status = in_be16(&PSC(port)->mpc52xx_psc_status)) & -+ MPC52xx_PSC_SR_RXRDY) { - - /* Get the char */ - ch = in_8(&PSC(port)->mpc52xx_psc_buffer_8); -@@ -474,9 +479,9 @@ mpc52xx_uart_int_rx_chars(struct uart_po - flag = TTY_NORMAL; - port->icount.rx++; - -- if ( status & (MPC52xx_PSC_SR_PE | -- MPC52xx_PSC_SR_FE | -- MPC52xx_PSC_SR_RB) ) { -+ if (status & (MPC52xx_PSC_SR_PE | -+ MPC52xx_PSC_SR_FE | -+ MPC52xx_PSC_SR_RB)) { - - if (status & MPC52xx_PSC_SR_RB) { - flag = TTY_BREAK; -@@ -487,7 +492,7 @@ mpc52xx_uart_int_rx_chars(struct uart_po - flag = TTY_FRAME; - - /* Clear error condition */ -- out_8(&PSC(port)->command,MPC52xx_PSC_RST_ERR_STAT); -+ out_8(&PSC(port)->command, MPC52xx_PSC_RST_ERR_STAT); - - } - tty_insert_flip_char(tty, ch, flag); -@@ -568,16 +573,16 @@ mpc52xx_uart_int(int irq, void *dev_id) - - /* Do we need to receive chars ? */ - /* For this RX interrupts must be on and some chars waiting */ -- if ( status & MPC52xx_PSC_IMR_RXRDY ) -+ if (status & MPC52xx_PSC_IMR_RXRDY) - keepgoing |= mpc52xx_uart_int_rx_chars(port); - - /* Do we need to send chars ? */ - /* For this, TX must be ready and TX interrupt enabled */ -- if ( status & MPC52xx_PSC_IMR_TXRDY ) -+ if (status & MPC52xx_PSC_IMR_TXRDY) - keepgoing |= mpc52xx_uart_int_tx_chars(port); - - /* Limit number of iteration */ -- if ( !(--pass) ) -+ if (!(--pass)) - keepgoing = 0; - - } while (keepgoing); -@@ -596,7 +601,7 @@ mpc52xx_uart_int(int irq, void *dev_id) - - static void __init - mpc52xx_console_get_options(struct uart_port *port, -- int *baud, int *parity, int *bits, int *flow) -+ int *baud, int *parity, int *bits, int *flow) - { - struct mpc52xx_psc __iomem *psc = PSC(port); - unsigned char mr1; -@@ -604,7 +609,7 @@ mpc52xx_console_get_options(struct uart_ - pr_debug("mpc52xx_console_get_options(port=%p)\n", port); - - /* Read the mode registers */ -- out_8(&psc->command,MPC52xx_PSC_SEL_MODE_REG_1); -+ out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1); - mr1 = in_8(&psc->mode); - - /* CT{U,L}R are write-only ! */ -@@ -616,11 +621,18 @@ mpc52xx_console_get_options(struct uart_ - - /* Parse them */ - switch (mr1 & MPC52xx_PSC_MODE_BITS_MASK) { -- case MPC52xx_PSC_MODE_5_BITS: *bits = 5; break; -- case MPC52xx_PSC_MODE_6_BITS: *bits = 6; break; -- case MPC52xx_PSC_MODE_7_BITS: *bits = 7; break; -- case MPC52xx_PSC_MODE_8_BITS: -- default: *bits = 8; -+ case MPC52xx_PSC_MODE_5_BITS: -+ *bits = 5; -+ break; -+ case MPC52xx_PSC_MODE_6_BITS: -+ *bits = 6; -+ break; -+ case MPC52xx_PSC_MODE_7_BITS: -+ *bits = 7; -+ break; -+ case MPC52xx_PSC_MODE_8_BITS: -+ default: -+ *bits = 8; - } - - if (mr1 & MPC52xx_PSC_MODE_PARNONE) -@@ -657,7 +669,7 @@ mpc52xx_console_write(struct console *co - /* Wait the TX buffer to be empty */ - j = 20000; /* Maximum wait */ - while (!(in_be16(&psc->mpc52xx_psc_status) & -- MPC52xx_PSC_SR_TXEMP) && --j) -+ MPC52xx_PSC_SR_TXEMP) && --j) - udelay(1); - } - -@@ -730,16 +742,18 @@ mpc52xx_console_setup(struct console *co - } - - pr_debug("Console on ttyPSC%x is %s\n", -- co->index, mpc52xx_uart_nodes[co->index]->full_name); -+ co->index, mpc52xx_uart_nodes[co->index]->full_name); - - /* Fetch register locations */ -- if ((ret = of_address_to_resource(np, 0, &res)) != 0) { -+ ret = of_address_to_resource(np, 0, &res); -+ if (ret) { - pr_debug("Could not get resources for PSC%x\n", co->index); - return ret; - } - - /* Search for bus-frequency property in this node or a parent */ -- if ((ipb_freq = mpc52xx_find_ipb_freq(np)) == 0) { -+ ipb_freq = mpc52xx_find_ipb_freq(np); -+ if (ipb_freq == 0) { - pr_debug("Could not find IPB bus frequency!\n"); - return -EINVAL; - } -@@ -757,7 +771,8 @@ mpc52xx_console_setup(struct console *co - return -EINVAL; - - pr_debug("mpc52xx-psc uart at %p, mapped to %p, irq=%x, freq=%i\n", -- (void*)port->mapbase, port->membase, port->irq, port->uartclk); -+ (void *)port->mapbase, port->membase, -+ port->irq, port->uartclk); - - /* Setup the port parameters accoding to options */ - if (options) -@@ -766,7 +781,7 @@ mpc52xx_console_setup(struct console *co - mpc52xx_console_get_options(port, &baud, &parity, &bits, &flow); - - pr_debug("Setting console parameters: %i %i%c1 flow=%c\n", -- baud, bits, parity, flow); -+ baud, bits, parity, flow); - - return uart_set_options(port, co, baud, parity, bits, flow); - } -@@ -781,7 +796,7 @@ static struct console mpc52xx_console = - .device = uart_console_device, - .setup = mpc52xx_console_setup, - .flags = CON_PRINTBUFFER, -- .index = -1, /* Specified on the cmdline (e.g. console=ttyPSC0 ) */ -+ .index = -1, /* Specified on the cmdline (e.g. console=ttyPSC0) */ - .data = &mpc52xx_uart_driver, - }; - -@@ -809,7 +824,6 @@ console_initcall(mpc52xx_console_init); - /* ======================================================================== */ - - static struct uart_driver mpc52xx_uart_driver = { -- .owner = THIS_MODULE, - .driver_name = "mpc52xx_psc_uart", - .dev_name = "ttyPSC", - .major = SERIAL_PSC_MAJOR, -@@ -837,7 +851,7 @@ mpc52xx_uart_probe(struct platform_devic - if (idx < 0 || idx >= MPC52xx_PSC_MAXNUM) - return -EINVAL; - -- if (!mpc52xx_match_psc_function(idx,"uart")) -+ if (!mpc52xx_match_psc_function(idx, "uart")) - return -ENODEV; - - /* Init the port structure */ -@@ -848,13 +862,13 @@ mpc52xx_uart_probe(struct platform_devic - port->fifosize = 512; - port->iotype = UPIO_MEM; - port->flags = UPF_BOOT_AUTOCONF | -- ( uart_console(port) ? 0 : UPF_IOREMAP ); -+ (uart_console(port) ? 0 : UPF_IOREMAP); - port->line = idx; - port->ops = &mpc52xx_uart_ops; - port->dev = &dev->dev; - - /* Search for IRQ and mapbase */ -- for (i=0 ; inum_resources ; i++, res++) { -+ for (i = 0 ; i < dev->num_resources ; i++, res++) { - if (res->flags & IORESOURCE_MEM) - port->mapbase = res->start; - else if (res->flags & IORESOURCE_IRQ) -@@ -866,7 +880,7 @@ mpc52xx_uart_probe(struct platform_devic - /* Add the port to the uart sub-system */ - ret = uart_add_one_port(&mpc52xx_uart_driver, port); - if (!ret) -- platform_set_drvdata(dev, (void*)port); -+ platform_set_drvdata(dev, (void *)port); - - return ret; - } -@@ -917,6 +931,7 @@ static struct platform_driver mpc52xx_ua - .resume = mpc52xx_uart_resume, - #endif - .driver = { -+ .owner = THIS_MODULE, - .name = "mpc52xx-psc", - }, - }; -@@ -946,10 +961,11 @@ mpc52xx_uart_of_probe(struct of_device * - if (idx >= MPC52xx_PSC_MAXNUM) - return -EINVAL; - pr_debug("Found %s assigned to ttyPSC%x\n", -- mpc52xx_uart_nodes[idx]->full_name, idx); -+ mpc52xx_uart_nodes[idx]->full_name, idx); - - /* Search for bus-frequency property in this node or a parent */ -- if ((ipb_freq = mpc52xx_find_ipb_freq(op->node)) == 0) { -+ ipb_freq = mpc52xx_find_ipb_freq(op->node); -+ if (ipb_freq == 0) { - dev_dbg(&op->dev, "Could not find IPB bus frequency!\n"); - return -EINVAL; - } -@@ -962,22 +978,23 @@ mpc52xx_uart_of_probe(struct of_device * - port->fifosize = 512; - port->iotype = UPIO_MEM; - port->flags = UPF_BOOT_AUTOCONF | -- ( uart_console(port) ? 0 : UPF_IOREMAP ); -+ (uart_console(port) ? 0 : UPF_IOREMAP); - port->line = idx; - port->ops = &mpc52xx_uart_ops; - port->dev = &op->dev; - - /* Search for IRQ and mapbase */ -- if ((ret = of_address_to_resource(op->node, 0, &res)) != 0) -+ ret = of_address_to_resource(op->node, 0, &res); -+ if (ret) - return ret; - - port->mapbase = res.start; - port->irq = irq_of_parse_and_map(op->node, 0); - - dev_dbg(&op->dev, "mpc52xx-psc uart at %p, irq=%x, freq=%i\n", -- (void*)port->mapbase, port->irq, port->uartclk); -+ (void *)port->mapbase, port->irq, port->uartclk); - -- if ((port->irq==NO_IRQ) || !port->mapbase) { -+ if ((port->irq == NO_IRQ) || !port->mapbase) { - printk(KERN_ERR "Could not allocate resources for PSC\n"); - return -EINVAL; - } -@@ -985,7 +1002,7 @@ mpc52xx_uart_of_probe(struct of_device * - /* Add the port to the uart sub-system */ - ret = uart_add_one_port(&mpc52xx_uart_driver, port); - if (!ret) -- dev_set_drvdata(&op->dev, (void*)port); -+ dev_set_drvdata(&op->dev, (void *)port); - - return ret; - } -@@ -1048,6 +1065,7 @@ mpc52xx_uart_of_assign(struct device_nod - if (idx < 0) - return; /* No free slot; abort */ - -+ of_node_get(np); - /* If the slot is already occupied, then swap slots */ - if (mpc52xx_uart_nodes[idx] && (free_idx != -1)) - mpc52xx_uart_nodes[free_idx] = mpc52xx_uart_nodes[idx]; -@@ -1057,7 +1075,7 @@ mpc52xx_uart_of_assign(struct device_nod - static void - mpc52xx_uart_of_enumerate(void) - { -- static int enum_done = 0; -+ static int enum_done; - struct device_node *np; - const unsigned int *devno; - int i; -@@ -1071,7 +1089,7 @@ mpc52xx_uart_of_enumerate(void) - - /* Is a particular device number requested? */ - devno = of_get_property(np, "port-number", NULL); -- mpc52xx_uart_of_assign(of_node_get(np), devno ? *devno : -1); -+ mpc52xx_uart_of_assign(np, devno ? *devno : -1); - } - - enum_done = 1; -@@ -1079,15 +1097,13 @@ mpc52xx_uart_of_enumerate(void) - for (i = 0; i < MPC52xx_PSC_MAXNUM; i++) { - if (mpc52xx_uart_nodes[i]) - pr_debug("%s assigned to ttyPSC%x\n", -- mpc52xx_uart_nodes[i]->full_name, i); -+ mpc52xx_uart_nodes[i]->full_name, i); - } - } - - MODULE_DEVICE_TABLE(of, mpc52xx_uart_of_match); - - static struct of_platform_driver mpc52xx_uart_of_driver = { -- .owner = THIS_MODULE, -- .name = "mpc52xx-psc-uart", - .match_table = mpc52xx_uart_of_match, - .probe = mpc52xx_uart_of_probe, - .remove = mpc52xx_uart_of_remove, -@@ -1113,7 +1129,8 @@ mpc52xx_uart_init(void) - - printk(KERN_INFO "Serial: MPC52xx PSC UART driver\n"); - -- if ((ret = uart_register_driver(&mpc52xx_uart_driver)) != 0) { -+ ret = uart_register_driver(&mpc52xx_uart_driver); -+ if (ret) { - printk(KERN_ERR "%s: uart_register_driver failed (%i)\n", - __FILE__, ret); - return ret; ---- a/drivers/serial/uartlite.c -+++ b/drivers/serial/uartlite.c -@@ -539,7 +539,7 @@ static int __devinit ulite_assign(struct - * - * @dev: pointer to device structure - */ --static int __devinit ulite_release(struct device *dev) -+static int __devexit ulite_release(struct device *dev) - { - struct uart_port *port = dev_get_drvdata(dev); - int rc = 0; -@@ -572,14 +572,14 @@ static int __devinit ulite_probe(struct - return ulite_assign(&pdev->dev, pdev->id, res->start, res2->start); - } - --static int ulite_remove(struct platform_device *pdev) -+static int __devexit ulite_remove(struct platform_device *pdev) - { - return ulite_release(&pdev->dev); - } - - static struct platform_driver ulite_platform_driver = { - .probe = ulite_probe, -- .remove = ulite_remove, -+ .remove = __devexit_p(ulite_remove), - .driver = { - .owner = THIS_MODULE, - .name = "uartlite", ---- /dev/null -+++ b/drivers/serial/ucc_uart.c -@@ -0,0 +1,1514 @@ -+/* -+ * Freescale QUICC Engine UART device driver -+ * -+ * Author: Timur Tabi -+ * -+ * Copyright 2007 Freescale Semiconductor, Inc. This file is licensed under -+ * the terms of the GNU General Public License version 2. This program -+ * is licensed "as is" without any warranty of any kind, whether express -+ * or implied. -+ * -+ * This driver adds support for UART devices via Freescale's QUICC Engine -+ * found on some Freescale SOCs. -+ * -+ * If Soft-UART support is needed but not already present, then this driver -+ * will request and upload the "Soft-UART" microcode upon probe. The -+ * filename of the microcode should be fsl_qe_ucode_uart_X_YZ.bin, where "X" -+ * is the name of the SOC (e.g. 8323), and YZ is the revision of the SOC, -+ * (e.g. "11" for 1.1). -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include -+#include -+ -+/* -+ * The GUMR flag for Soft UART. This would normally be defined in qe.h, -+ * but Soft-UART is a hack and we want to keep everything related to it in -+ * this file. -+ */ -+#define UCC_SLOW_GUMR_H_SUART 0x00004000 /* Soft-UART */ -+ -+/* -+ * soft_uart is 1 if we need to use Soft-UART mode -+ */ -+static int soft_uart; -+/* -+ * firmware_loaded is 1 if the firmware has been loaded, 0 otherwise. -+ */ -+static int firmware_loaded; -+ -+/* Enable this macro to configure all serial ports in internal loopback -+ mode */ -+/* #define LOOPBACK */ -+ -+/* The major and minor device numbers are defined in -+ * http://www.lanana.org/docs/device-list/devices-2.6+.txt. For the QE -+ * UART, we have major number 204 and minor numbers 46 - 49, which are the -+ * same as for the CPM2. This decision was made because no Freescale part -+ * has both a CPM and a QE. -+ */ -+#define SERIAL_QE_MAJOR 204 -+#define SERIAL_QE_MINOR 46 -+ -+/* Since we only have minor numbers 46 - 49, there is a hard limit of 4 ports */ -+#define UCC_MAX_UART 4 -+ -+/* The number of buffer descriptors for receiving characters. */ -+#define RX_NUM_FIFO 4 -+ -+/* The number of buffer descriptors for transmitting characters. */ -+#define TX_NUM_FIFO 4 -+ -+/* The maximum size of the character buffer for a single RX BD. */ -+#define RX_BUF_SIZE 32 -+ -+/* The maximum size of the character buffer for a single TX BD. */ -+#define TX_BUF_SIZE 32 -+ -+/* -+ * The number of jiffies to wait after receiving a close command before the -+ * device is actually closed. This allows the last few characters to be -+ * sent over the wire. -+ */ -+#define UCC_WAIT_CLOSING 100 -+ -+struct ucc_uart_pram { -+ struct ucc_slow_pram common; -+ u8 res1[8]; /* reserved */ -+ __be16 maxidl; /* Maximum idle chars */ -+ __be16 idlc; /* temp idle counter */ -+ __be16 brkcr; /* Break count register */ -+ __be16 parec; /* receive parity error counter */ -+ __be16 frmec; /* receive framing error counter */ -+ __be16 nosec; /* receive noise counter */ -+ __be16 brkec; /* receive break condition counter */ -+ __be16 brkln; /* last received break length */ -+ __be16 uaddr[2]; /* UART address character 1 & 2 */ -+ __be16 rtemp; /* Temp storage */ -+ __be16 toseq; /* Transmit out of sequence char */ -+ __be16 cchars[8]; /* control characters 1-8 */ -+ __be16 rccm; /* receive control character mask */ -+ __be16 rccr; /* receive control character register */ -+ __be16 rlbc; /* receive last break character */ -+ __be16 res2; /* reserved */ -+ __be32 res3; /* reserved, should be cleared */ -+ u8 res4; /* reserved, should be cleared */ -+ u8 res5[3]; /* reserved, should be cleared */ -+ __be32 res6; /* reserved, should be cleared */ -+ __be32 res7; /* reserved, should be cleared */ -+ __be32 res8; /* reserved, should be cleared */ -+ __be32 res9; /* reserved, should be cleared */ -+ __be32 res10; /* reserved, should be cleared */ -+ __be32 res11; /* reserved, should be cleared */ -+ __be32 res12; /* reserved, should be cleared */ -+ __be32 res13; /* reserved, should be cleared */ -+/* The rest is for Soft-UART only */ -+ __be16 supsmr; /* 0x90, Shadow UPSMR */ -+ __be16 res92; /* 0x92, reserved, initialize to 0 */ -+ __be32 rx_state; /* 0x94, RX state, initialize to 0 */ -+ __be32 rx_cnt; /* 0x98, RX count, initialize to 0 */ -+ u8 rx_length; /* 0x9C, Char length, set to 1+CL+PEN+1+SL */ -+ u8 rx_bitmark; /* 0x9D, reserved, initialize to 0 */ -+ u8 rx_temp_dlst_qe; /* 0x9E, reserved, initialize to 0 */ -+ u8 res14[0xBC - 0x9F]; /* reserved */ -+ __be32 dump_ptr; /* 0xBC, Dump pointer */ -+ __be32 rx_frame_rem; /* 0xC0, reserved, initialize to 0 */ -+ u8 rx_frame_rem_size; /* 0xC4, reserved, initialize to 0 */ -+ u8 tx_mode; /* 0xC5, mode, 0=AHDLC, 1=UART */ -+ __be16 tx_state; /* 0xC6, TX state */ -+ u8 res15[0xD0 - 0xC8]; /* reserved */ -+ __be32 resD0; /* 0xD0, reserved, initialize to 0 */ -+ u8 resD4; /* 0xD4, reserved, initialize to 0 */ -+ __be16 resD5; /* 0xD5, reserved, initialize to 0 */ -+} __attribute__ ((packed)); -+ -+/* SUPSMR definitions, for Soft-UART only */ -+#define UCC_UART_SUPSMR_SL 0x8000 -+#define UCC_UART_SUPSMR_RPM_MASK 0x6000 -+#define UCC_UART_SUPSMR_RPM_ODD 0x0000 -+#define UCC_UART_SUPSMR_RPM_LOW 0x2000 -+#define UCC_UART_SUPSMR_RPM_EVEN 0x4000 -+#define UCC_UART_SUPSMR_RPM_HIGH 0x6000 -+#define UCC_UART_SUPSMR_PEN 0x1000 -+#define UCC_UART_SUPSMR_TPM_MASK 0x0C00 -+#define UCC_UART_SUPSMR_TPM_ODD 0x0000 -+#define UCC_UART_SUPSMR_TPM_LOW 0x0400 -+#define UCC_UART_SUPSMR_TPM_EVEN 0x0800 -+#define UCC_UART_SUPSMR_TPM_HIGH 0x0C00 -+#define UCC_UART_SUPSMR_FRZ 0x0100 -+#define UCC_UART_SUPSMR_UM_MASK 0x00c0 -+#define UCC_UART_SUPSMR_UM_NORMAL 0x0000 -+#define UCC_UART_SUPSMR_UM_MAN_MULTI 0x0040 -+#define UCC_UART_SUPSMR_UM_AUTO_MULTI 0x00c0 -+#define UCC_UART_SUPSMR_CL_MASK 0x0030 -+#define UCC_UART_SUPSMR_CL_8 0x0030 -+#define UCC_UART_SUPSMR_CL_7 0x0020 -+#define UCC_UART_SUPSMR_CL_6 0x0010 -+#define UCC_UART_SUPSMR_CL_5 0x0000 -+ -+#define UCC_UART_TX_STATE_AHDLC 0x00 -+#define UCC_UART_TX_STATE_UART 0x01 -+#define UCC_UART_TX_STATE_X1 0x00 -+#define UCC_UART_TX_STATE_X16 0x80 -+ -+#define UCC_UART_PRAM_ALIGNMENT 0x100 -+ -+#define UCC_UART_SIZE_OF_BD UCC_SLOW_SIZE_OF_BD -+#define NUM_CONTROL_CHARS 8 -+ -+/* Private per-port data structure */ -+struct uart_qe_port { -+ struct uart_port port; -+ struct ucc_slow __iomem *uccp; -+ struct ucc_uart_pram __iomem *uccup; -+ struct ucc_slow_info us_info; -+ struct ucc_slow_private *us_private; -+ struct device_node *np; -+ unsigned int ucc_num; /* First ucc is 0, not 1 */ -+ -+ u16 rx_nrfifos; -+ u16 rx_fifosize; -+ u16 tx_nrfifos; -+ u16 tx_fifosize; -+ int wait_closing; -+ u32 flags; -+ struct qe_bd *rx_bd_base; -+ struct qe_bd *rx_cur; -+ struct qe_bd *tx_bd_base; -+ struct qe_bd *tx_cur; -+ unsigned char *tx_buf; -+ unsigned char *rx_buf; -+ void *bd_virt; /* virtual address of the BD buffers */ -+ dma_addr_t bd_dma_addr; /* bus address of the BD buffers */ -+ unsigned int bd_size; /* size of BD buffer space */ -+}; -+ -+static struct uart_driver ucc_uart_driver = { -+ .owner = THIS_MODULE, -+ .driver_name = "serial", -+ .dev_name = "ttyQE", -+ .major = SERIAL_QE_MAJOR, -+ .minor = SERIAL_QE_MINOR, -+ .nr = UCC_MAX_UART, -+}; -+ -+/* -+ * Virtual to physical address translation. -+ * -+ * Given the virtual address for a character buffer, this function returns -+ * the physical (DMA) equivalent. -+ */ -+static inline dma_addr_t cpu2qe_addr(void *addr, struct uart_qe_port *qe_port) -+{ -+ if (likely((addr >= qe_port->bd_virt)) && -+ (addr < (qe_port->bd_virt + qe_port->bd_size))) -+ return qe_port->bd_dma_addr + (addr - qe_port->bd_virt); -+ -+ /* something nasty happened */ -+ printk(KERN_ERR "%s: addr=%p\n", __FUNCTION__, addr); -+ BUG(); -+ return 0; -+} -+ -+/* -+ * Physical to virtual address translation. -+ * -+ * Given the physical (DMA) address for a character buffer, this function -+ * returns the virtual equivalent. -+ */ -+static inline void *qe2cpu_addr(dma_addr_t addr, struct uart_qe_port *qe_port) -+{ -+ /* sanity check */ -+ if (likely((addr >= qe_port->bd_dma_addr) && -+ (addr < (qe_port->bd_dma_addr + qe_port->bd_size)))) -+ return qe_port->bd_virt + (addr - qe_port->bd_dma_addr); -+ -+ /* something nasty happened */ -+ printk(KERN_ERR "%s: addr=%x\n", __FUNCTION__, addr); -+ BUG(); -+ return NULL; -+} -+ -+/* -+ * Return 1 if the QE is done transmitting all buffers for this port -+ * -+ * This function scans each BD in sequence. If we find a BD that is not -+ * ready (READY=1), then we return 0 indicating that the QE is still sending -+ * data. If we reach the last BD (WRAP=1), then we know we've scanned -+ * the entire list, and all BDs are done. -+ */ -+static unsigned int qe_uart_tx_empty(struct uart_port *port) -+{ -+ struct uart_qe_port *qe_port = -+ container_of(port, struct uart_qe_port, port); -+ struct qe_bd *bdp = qe_port->tx_bd_base; -+ -+ while (1) { -+ if (in_be16(&bdp->status) & BD_SC_READY) -+ /* This BD is not done, so return "not done" */ -+ return 0; -+ -+ if (in_be16(&bdp->status) & BD_SC_WRAP) -+ /* -+ * This BD is done and it's the last one, so return -+ * "done" -+ */ -+ return 1; -+ -+ bdp++; -+ }; -+} -+ -+/* -+ * Set the modem control lines -+ * -+ * Although the QE can control the modem control lines (e.g. CTS), we -+ * don't need that support. This function must exist, however, otherwise -+ * the kernel will panic. -+ */ -+void qe_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) -+{ -+} -+ -+/* -+ * Get the current modem control line status -+ * -+ * Although the QE can control the modem control lines (e.g. CTS), this -+ * driver currently doesn't support that, so we always return Carrier -+ * Detect, Data Set Ready, and Clear To Send. -+ */ -+static unsigned int qe_uart_get_mctrl(struct uart_port *port) -+{ -+ return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS; -+} -+ -+/* -+ * Disable the transmit interrupt. -+ * -+ * Although this function is called "stop_tx", it does not actually stop -+ * transmission of data. Instead, it tells the QE to not generate an -+ * interrupt when the UCC is finished sending characters. -+ */ -+static void qe_uart_stop_tx(struct uart_port *port) -+{ -+ struct uart_qe_port *qe_port = -+ container_of(port, struct uart_qe_port, port); -+ -+ clrbits16(&qe_port->uccp->uccm, UCC_UART_UCCE_TX); -+} -+ -+/* -+ * Transmit as many characters to the HW as possible. -+ * -+ * This function will attempt to stuff of all the characters from the -+ * kernel's transmit buffer into TX BDs. -+ * -+ * A return value of non-zero indicates that it sucessfully stuffed all -+ * characters from the kernel buffer. -+ * -+ * A return value of zero indicates that there are still characters in the -+ * kernel's buffer that have not been transmitted, but there are no more BDs -+ * available. This function should be called again after a BD has been made -+ * available. -+ */ -+static int qe_uart_tx_pump(struct uart_qe_port *qe_port) -+{ -+ struct qe_bd *bdp; -+ unsigned char *p; -+ unsigned int count; -+ struct uart_port *port = &qe_port->port; -+ struct circ_buf *xmit = &port->info->xmit; -+ -+ bdp = qe_port->rx_cur; -+ -+ /* Handle xon/xoff */ -+ if (port->x_char) { -+ /* Pick next descriptor and fill from buffer */ -+ bdp = qe_port->tx_cur; -+ -+ p = qe2cpu_addr(bdp->buf, qe_port); -+ -+ *p++ = port->x_char; -+ out_be16(&bdp->length, 1); -+ setbits16(&bdp->status, BD_SC_READY); -+ /* Get next BD. */ -+ if (in_be16(&bdp->status) & BD_SC_WRAP) -+ bdp = qe_port->tx_bd_base; -+ else -+ bdp++; -+ qe_port->tx_cur = bdp; -+ -+ port->icount.tx++; -+ port->x_char = 0; -+ return 1; -+ } -+ -+ if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { -+ qe_uart_stop_tx(port); -+ return 0; -+ } -+ -+ /* Pick next descriptor and fill from buffer */ -+ bdp = qe_port->tx_cur; -+ -+ while (!(in_be16(&bdp->status) & BD_SC_READY) && -+ (xmit->tail != xmit->head)) { -+ count = 0; -+ p = qe2cpu_addr(bdp->buf, qe_port); -+ while (count < qe_port->tx_fifosize) { -+ *p++ = xmit->buf[xmit->tail]; -+ xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); -+ port->icount.tx++; -+ count++; -+ if (xmit->head == xmit->tail) -+ break; -+ } -+ -+ out_be16(&bdp->length, count); -+ setbits16(&bdp->status, BD_SC_READY); -+ -+ /* Get next BD. */ -+ if (in_be16(&bdp->status) & BD_SC_WRAP) -+ bdp = qe_port->tx_bd_base; -+ else -+ bdp++; -+ } -+ qe_port->tx_cur = bdp; -+ -+ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) -+ uart_write_wakeup(port); -+ -+ if (uart_circ_empty(xmit)) { -+ /* The kernel buffer is empty, so turn off TX interrupts. We -+ don't need to be told when the QE is finished transmitting -+ the data. */ -+ qe_uart_stop_tx(port); -+ return 0; -+ } -+ -+ return 1; -+} -+ -+/* -+ * Start transmitting data -+ * -+ * This function will start transmitting any available data, if the port -+ * isn't already transmitting data. -+ */ -+static void qe_uart_start_tx(struct uart_port *port) -+{ -+ struct uart_qe_port *qe_port = -+ container_of(port, struct uart_qe_port, port); -+ -+ /* If we currently are transmitting, then just return */ -+ if (in_be16(&qe_port->uccp->uccm) & UCC_UART_UCCE_TX) -+ return; -+ -+ /* Otherwise, pump the port and start transmission */ -+ if (qe_uart_tx_pump(qe_port)) -+ setbits16(&qe_port->uccp->uccm, UCC_UART_UCCE_TX); -+} -+ -+/* -+ * Stop transmitting data -+ */ -+static void qe_uart_stop_rx(struct uart_port *port) -+{ -+ struct uart_qe_port *qe_port = -+ container_of(port, struct uart_qe_port, port); -+ -+ clrbits16(&qe_port->uccp->uccm, UCC_UART_UCCE_RX); -+} -+ -+/* -+ * Enable status change interrupts -+ * -+ * We don't support status change interrupts, but we need to define this -+ * function otherwise the kernel will panic. -+ */ -+static void qe_uart_enable_ms(struct uart_port *port) -+{ -+} -+ -+/* Start or stop sending break signal -+ * -+ * This function controls the sending of a break signal. If break_state=1, -+ * then we start sending a break signal. If break_state=0, then we stop -+ * sending the break signal. -+ */ -+static void qe_uart_break_ctl(struct uart_port *port, int break_state) -+{ -+ struct uart_qe_port *qe_port = -+ container_of(port, struct uart_qe_port, port); -+ -+ if (break_state) -+ ucc_slow_stop_tx(qe_port->us_private); -+ else -+ ucc_slow_restart_tx(qe_port->us_private); -+} -+ -+/* ISR helper function for receiving character. -+ * -+ * This function is called by the ISR to handling receiving characters -+ */ -+static void qe_uart_int_rx(struct uart_qe_port *qe_port) -+{ -+ int i; -+ unsigned char ch, *cp; -+ struct uart_port *port = &qe_port->port; -+ struct tty_struct *tty = port->info->tty; -+ struct qe_bd *bdp; -+ u16 status; -+ unsigned int flg; -+ -+ /* Just loop through the closed BDs and copy the characters into -+ * the buffer. -+ */ -+ bdp = qe_port->rx_cur; -+ while (1) { -+ status = in_be16(&bdp->status); -+ -+ /* If this one is empty, then we assume we've read them all */ -+ if (status & BD_SC_EMPTY) -+ break; -+ -+ /* get number of characters, and check space in RX buffer */ -+ i = in_be16(&bdp->length); -+ -+ /* If we don't have enough room in RX buffer for the entire BD, -+ * then we try later, which will be the next RX interrupt. -+ */ -+ if (tty_buffer_request_room(tty, i) < i) { -+ dev_dbg(port->dev, "ucc-uart: no room in RX buffer\n"); -+ return; -+ } -+ -+ /* get pointer */ -+ cp = qe2cpu_addr(bdp->buf, qe_port); -+ -+ /* loop through the buffer */ -+ while (i-- > 0) { -+ ch = *cp++; -+ port->icount.rx++; -+ flg = TTY_NORMAL; -+ -+ if (!i && status & -+ (BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV)) -+ goto handle_error; -+ if (uart_handle_sysrq_char(port, ch)) -+ continue; -+ -+error_return: -+ tty_insert_flip_char(tty, ch, flg); -+ -+ } -+ -+ /* This BD is ready to be used again. Clear status. get next */ -+ clrsetbits_be16(&bdp->status, BD_SC_BR | BD_SC_FR | BD_SC_PR | -+ BD_SC_OV | BD_SC_ID, BD_SC_EMPTY); -+ if (in_be16(&bdp->status) & BD_SC_WRAP) -+ bdp = qe_port->rx_bd_base; -+ else -+ bdp++; -+ -+ } -+ -+ /* Write back buffer pointer */ -+ qe_port->rx_cur = bdp; -+ -+ /* Activate BH processing */ -+ tty_flip_buffer_push(tty); -+ -+ return; -+ -+ /* Error processing */ -+ -+handle_error: -+ /* Statistics */ -+ if (status & BD_SC_BR) -+ port->icount.brk++; -+ if (status & BD_SC_PR) -+ port->icount.parity++; -+ if (status & BD_SC_FR) -+ port->icount.frame++; -+ if (status & BD_SC_OV) -+ port->icount.overrun++; -+ -+ /* Mask out ignored conditions */ -+ status &= port->read_status_mask; -+ -+ /* Handle the remaining ones */ -+ if (status & BD_SC_BR) -+ flg = TTY_BREAK; -+ else if (status & BD_SC_PR) -+ flg = TTY_PARITY; -+ else if (status & BD_SC_FR) -+ flg = TTY_FRAME; -+ -+ /* Overrun does not affect the current character ! */ -+ if (status & BD_SC_OV) -+ tty_insert_flip_char(tty, 0, TTY_OVERRUN); -+#ifdef SUPPORT_SYSRQ -+ port->sysrq = 0; -+#endif -+ goto error_return; -+} -+ -+/* Interrupt handler -+ * -+ * This interrupt handler is called after a BD is processed. -+ */ -+static irqreturn_t qe_uart_int(int irq, void *data) -+{ -+ struct uart_qe_port *qe_port = (struct uart_qe_port *) data; -+ struct ucc_slow __iomem *uccp = qe_port->uccp; -+ u16 events; -+ -+ /* Clear the interrupts */ -+ events = in_be16(&uccp->ucce); -+ out_be16(&uccp->ucce, events); -+ -+ if (events & UCC_UART_UCCE_BRKE) -+ uart_handle_break(&qe_port->port); -+ -+ if (events & UCC_UART_UCCE_RX) -+ qe_uart_int_rx(qe_port); -+ -+ if (events & UCC_UART_UCCE_TX) -+ qe_uart_tx_pump(qe_port); -+ -+ return events ? IRQ_HANDLED : IRQ_NONE; -+} -+ -+/* Initialize buffer descriptors -+ * -+ * This function initializes all of the RX and TX buffer descriptors. -+ */ -+static void qe_uart_initbd(struct uart_qe_port *qe_port) -+{ -+ int i; -+ void *bd_virt; -+ struct qe_bd *bdp; -+ -+ /* Set the physical address of the host memory buffers in the buffer -+ * descriptors, and the virtual address for us to work with. -+ */ -+ bd_virt = qe_port->bd_virt; -+ bdp = qe_port->rx_bd_base; -+ qe_port->rx_cur = qe_port->rx_bd_base; -+ for (i = 0; i < (qe_port->rx_nrfifos - 1); i++) { -+ out_be16(&bdp->status, BD_SC_EMPTY | BD_SC_INTRPT); -+ out_be32(&bdp->buf, cpu2qe_addr(bd_virt, qe_port)); -+ out_be16(&bdp->length, 0); -+ bd_virt += qe_port->rx_fifosize; -+ bdp++; -+ } -+ -+ /* */ -+ out_be16(&bdp->status, BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT); -+ out_be32(&bdp->buf, cpu2qe_addr(bd_virt, qe_port)); -+ out_be16(&bdp->length, 0); -+ -+ /* Set the physical address of the host memory -+ * buffers in the buffer descriptors, and the -+ * virtual address for us to work with. -+ */ -+ bd_virt = qe_port->bd_virt + -+ L1_CACHE_ALIGN(qe_port->rx_nrfifos * qe_port->rx_fifosize); -+ qe_port->tx_cur = qe_port->tx_bd_base; -+ bdp = qe_port->tx_bd_base; -+ for (i = 0; i < (qe_port->tx_nrfifos - 1); i++) { -+ out_be16(&bdp->status, BD_SC_INTRPT); -+ out_be32(&bdp->buf, cpu2qe_addr(bd_virt, qe_port)); -+ out_be16(&bdp->length, 0); -+ bd_virt += qe_port->tx_fifosize; -+ bdp++; -+ } -+ -+ /* Loopback requires the preamble bit to be set on the first TX BD */ -+#ifdef LOOPBACK -+ setbits16(&qe_port->tx_cur->status, BD_SC_P); -+#endif -+ -+ out_be16(&bdp->status, BD_SC_WRAP | BD_SC_INTRPT); -+ out_be32(&bdp->buf, cpu2qe_addr(bd_virt, qe_port)); -+ out_be16(&bdp->length, 0); -+} -+ -+/* -+ * Initialize a UCC for UART. -+ * -+ * This function configures a given UCC to be used as a UART device. Basic -+ * UCC initialization is handled in qe_uart_request_port(). This function -+ * does all the UART-specific stuff. -+ */ -+static void qe_uart_init_ucc(struct uart_qe_port *qe_port) -+{ -+ u32 cecr_subblock; -+ struct ucc_slow __iomem *uccp = qe_port->uccp; -+ struct ucc_uart_pram *uccup = qe_port->uccup; -+ -+ unsigned int i; -+ -+ /* First, disable TX and RX in the UCC */ -+ ucc_slow_disable(qe_port->us_private, COMM_DIR_RX_AND_TX); -+ -+ /* Program the UCC UART parameter RAM */ -+ out_8(&uccup->common.rbmr, UCC_BMR_GBL | UCC_BMR_BO_BE); -+ out_8(&uccup->common.tbmr, UCC_BMR_GBL | UCC_BMR_BO_BE); -+ out_be16(&uccup->common.mrblr, qe_port->rx_fifosize); -+ out_be16(&uccup->maxidl, 0x10); -+ out_be16(&uccup->brkcr, 1); -+ out_be16(&uccup->parec, 0); -+ out_be16(&uccup->frmec, 0); -+ out_be16(&uccup->nosec, 0); -+ out_be16(&uccup->brkec, 0); -+ out_be16(&uccup->uaddr[0], 0); -+ out_be16(&uccup->uaddr[1], 0); -+ out_be16(&uccup->toseq, 0); -+ for (i = 0; i < 8; i++) -+ out_be16(&uccup->cchars[i], 0xC000); -+ out_be16(&uccup->rccm, 0xc0ff); -+ -+ /* Configure the GUMR registers for UART */ -+ if (soft_uart) -+ /* Soft-UART requires a 1X multiplier for TX */ -+ clrsetbits_be32(&uccp->gumr_l, -+ UCC_SLOW_GUMR_L_MODE_MASK | UCC_SLOW_GUMR_L_TDCR_MASK | -+ UCC_SLOW_GUMR_L_RDCR_MASK, -+ UCC_SLOW_GUMR_L_MODE_UART | UCC_SLOW_GUMR_L_TDCR_1 | -+ UCC_SLOW_GUMR_L_RDCR_16); -+ else -+ clrsetbits_be32(&uccp->gumr_l, -+ UCC_SLOW_GUMR_L_MODE_MASK | UCC_SLOW_GUMR_L_TDCR_MASK | -+ UCC_SLOW_GUMR_L_RDCR_MASK, -+ UCC_SLOW_GUMR_L_MODE_UART | UCC_SLOW_GUMR_L_TDCR_16 | -+ UCC_SLOW_GUMR_L_RDCR_16); -+ -+ clrsetbits_be32(&uccp->gumr_h, UCC_SLOW_GUMR_H_RFW, -+ UCC_SLOW_GUMR_H_TRX | UCC_SLOW_GUMR_H_TTX); -+ -+#ifdef LOOPBACK -+ clrsetbits_be32(&uccp->gumr_l, UCC_SLOW_GUMR_L_DIAG_MASK, -+ UCC_SLOW_GUMR_L_DIAG_LOOP); -+ clrsetbits_be32(&uccp->gumr_h, -+ UCC_SLOW_GUMR_H_CTSP | UCC_SLOW_GUMR_H_RSYN, -+ UCC_SLOW_GUMR_H_CDS); -+#endif -+ -+ /* Enable rx interrupts and clear all pending events. */ -+ out_be16(&uccp->uccm, 0); -+ out_be16(&uccp->ucce, 0xffff); -+ out_be16(&uccp->udsr, 0x7e7e); -+ -+ /* Initialize UPSMR */ -+ out_be16(&uccp->upsmr, 0); -+ -+ if (soft_uart) { -+ out_be16(&uccup->supsmr, 0x30); -+ out_be16(&uccup->res92, 0); -+ out_be32(&uccup->rx_state, 0); -+ out_be32(&uccup->rx_cnt, 0); -+ out_8(&uccup->rx_bitmark, 0); -+ out_8(&uccup->rx_length, 10); -+ out_be32(&uccup->dump_ptr, 0x4000); -+ out_8(&uccup->rx_temp_dlst_qe, 0); -+ out_be32(&uccup->rx_frame_rem, 0); -+ out_8(&uccup->rx_frame_rem_size, 0); -+ /* Soft-UART requires TX to be 1X */ -+ out_8(&uccup->tx_mode, -+ UCC_UART_TX_STATE_UART | UCC_UART_TX_STATE_X1); -+ out_be16(&uccup->tx_state, 0); -+ out_8(&uccup->resD4, 0); -+ out_be16(&uccup->resD5, 0); -+ -+ /* Set UART mode. -+ * Enable receive and transmit. -+ */ -+ -+ /* From the microcode errata: -+ * 1.GUMR_L register, set mode=0010 (QMC). -+ * 2.Set GUMR_H[17] bit. (UART/AHDLC mode). -+ * 3.Set GUMR_H[19:20] (Transparent mode) -+ * 4.Clear GUMR_H[26] (RFW) -+ * ... -+ * 6.Receiver must use 16x over sampling -+ */ -+ clrsetbits_be32(&uccp->gumr_l, -+ UCC_SLOW_GUMR_L_MODE_MASK | UCC_SLOW_GUMR_L_TDCR_MASK | -+ UCC_SLOW_GUMR_L_RDCR_MASK, -+ UCC_SLOW_GUMR_L_MODE_QMC | UCC_SLOW_GUMR_L_TDCR_16 | -+ UCC_SLOW_GUMR_L_RDCR_16); -+ -+ clrsetbits_be32(&uccp->gumr_h, -+ UCC_SLOW_GUMR_H_RFW | UCC_SLOW_GUMR_H_RSYN, -+ UCC_SLOW_GUMR_H_SUART | UCC_SLOW_GUMR_H_TRX | -+ UCC_SLOW_GUMR_H_TTX | UCC_SLOW_GUMR_H_TFL); -+ -+#ifdef LOOPBACK -+ clrsetbits_be32(&uccp->gumr_l, UCC_SLOW_GUMR_L_DIAG_MASK, -+ UCC_SLOW_GUMR_L_DIAG_LOOP); -+ clrbits32(&uccp->gumr_h, UCC_SLOW_GUMR_H_CTSP | -+ UCC_SLOW_GUMR_H_CDS); -+#endif -+ -+ cecr_subblock = ucc_slow_get_qe_cr_subblock(qe_port->ucc_num); -+ qe_issue_cmd(QE_INIT_TX_RX, cecr_subblock, -+ QE_CR_PROTOCOL_UNSPECIFIED, 0); -+ } -+} -+ -+/* -+ * Initialize the port. -+ */ -+static int qe_uart_startup(struct uart_port *port) -+{ -+ struct uart_qe_port *qe_port = -+ container_of(port, struct uart_qe_port, port); -+ int ret; -+ -+ /* -+ * If we're using Soft-UART mode, then we need to make sure the -+ * firmware has been uploaded first. -+ */ -+ if (soft_uart && !firmware_loaded) { -+ dev_err(port->dev, "Soft-UART firmware not uploaded\n"); -+ return -ENODEV; -+ } -+ -+ qe_uart_initbd(qe_port); -+ qe_uart_init_ucc(qe_port); -+ -+ /* Install interrupt handler. */ -+ ret = request_irq(port->irq, qe_uart_int, IRQF_SHARED, "ucc-uart", -+ qe_port); -+ if (ret) { -+ dev_err(port->dev, "could not claim IRQ %u\n", port->irq); -+ return ret; -+ } -+ -+ /* Startup rx-int */ -+ setbits16(&qe_port->uccp->uccm, UCC_UART_UCCE_RX); -+ ucc_slow_enable(qe_port->us_private, COMM_DIR_RX_AND_TX); -+ -+ return 0; -+} -+ -+/* -+ * Shutdown the port. -+ */ -+static void qe_uart_shutdown(struct uart_port *port) -+{ -+ struct uart_qe_port *qe_port = -+ container_of(port, struct uart_qe_port, port); -+ struct ucc_slow __iomem *uccp = qe_port->uccp; -+ unsigned int timeout = 20; -+ -+ /* Disable RX and TX */ -+ -+ /* Wait for all the BDs marked sent */ -+ while (!qe_uart_tx_empty(port)) { -+ if (!--timeout) { -+ dev_warn(port->dev, "shutdown timeout\n"); -+ break; -+ } -+ set_current_state(TASK_UNINTERRUPTIBLE); -+ schedule_timeout(2); -+ } -+ -+ if (qe_port->wait_closing) { -+ /* Wait a bit longer */ -+ set_current_state(TASK_UNINTERRUPTIBLE); -+ schedule_timeout(qe_port->wait_closing); -+ } -+ -+ /* Stop uarts */ -+ ucc_slow_disable(qe_port->us_private, COMM_DIR_RX_AND_TX); -+ clrbits16(&uccp->uccm, UCC_UART_UCCE_TX | UCC_UART_UCCE_RX); -+ -+ /* Shut them really down and reinit buffer descriptors */ -+ ucc_slow_graceful_stop_tx(qe_port->us_private); -+ qe_uart_initbd(qe_port); -+ -+ free_irq(port->irq, qe_port); -+} -+ -+/* -+ * Set the serial port parameters. -+ */ -+static void qe_uart_set_termios(struct uart_port *port, -+ struct ktermios *termios, struct ktermios *old) -+{ -+ struct uart_qe_port *qe_port = -+ container_of(port, struct uart_qe_port, port); -+ struct ucc_slow __iomem *uccp = qe_port->uccp; -+ unsigned int baud; -+ unsigned long flags; -+ u16 upsmr = in_be16(&uccp->upsmr); -+ struct ucc_uart_pram __iomem *uccup = qe_port->uccup; -+ u16 supsmr = in_be16(&uccup->supsmr); -+ u8 char_length = 2; /* 1 + CL + PEN + 1 + SL */ -+ -+ /* Character length programmed into the mode register is the -+ * sum of: 1 start bit, number of data bits, 0 or 1 parity bit, -+ * 1 or 2 stop bits, minus 1. -+ * The value 'bits' counts this for us. -+ */ -+ -+ /* byte size */ -+ upsmr &= UCC_UART_UPSMR_CL_MASK; -+ supsmr &= UCC_UART_SUPSMR_CL_MASK; -+ -+ switch (termios->c_cflag & CSIZE) { -+ case CS5: -+ upsmr |= UCC_UART_UPSMR_CL_5; -+ supsmr |= UCC_UART_SUPSMR_CL_5; -+ char_length += 5; -+ break; -+ case CS6: -+ upsmr |= UCC_UART_UPSMR_CL_6; -+ supsmr |= UCC_UART_SUPSMR_CL_6; -+ char_length += 6; -+ break; -+ case CS7: -+ upsmr |= UCC_UART_UPSMR_CL_7; -+ supsmr |= UCC_UART_SUPSMR_CL_7; -+ char_length += 7; -+ break; -+ default: /* case CS8 */ -+ upsmr |= UCC_UART_UPSMR_CL_8; -+ supsmr |= UCC_UART_SUPSMR_CL_8; -+ char_length += 8; -+ break; -+ } -+ -+ /* If CSTOPB is set, we want two stop bits */ -+ if (termios->c_cflag & CSTOPB) { -+ upsmr |= UCC_UART_UPSMR_SL; -+ supsmr |= UCC_UART_SUPSMR_SL; -+ char_length++; /* + SL */ -+ } -+ -+ if (termios->c_cflag & PARENB) { -+ upsmr |= UCC_UART_UPSMR_PEN; -+ supsmr |= UCC_UART_SUPSMR_PEN; -+ char_length++; /* + PEN */ -+ -+ if (!(termios->c_cflag & PARODD)) { -+ upsmr &= ~(UCC_UART_UPSMR_RPM_MASK | -+ UCC_UART_UPSMR_TPM_MASK); -+ upsmr |= UCC_UART_UPSMR_RPM_EVEN | -+ UCC_UART_UPSMR_TPM_EVEN; -+ supsmr &= ~(UCC_UART_SUPSMR_RPM_MASK | -+ UCC_UART_SUPSMR_TPM_MASK); -+ supsmr |= UCC_UART_SUPSMR_RPM_EVEN | -+ UCC_UART_SUPSMR_TPM_EVEN; -+ } -+ } -+ -+ /* -+ * Set up parity check flag -+ */ -+ port->read_status_mask = BD_SC_EMPTY | BD_SC_OV; -+ if (termios->c_iflag & INPCK) -+ port->read_status_mask |= BD_SC_FR | BD_SC_PR; -+ if (termios->c_iflag & (BRKINT | PARMRK)) -+ port->read_status_mask |= BD_SC_BR; -+ -+ /* -+ * Characters to ignore -+ */ -+ port->ignore_status_mask = 0; -+ if (termios->c_iflag & IGNPAR) -+ port->ignore_status_mask |= BD_SC_PR | BD_SC_FR; -+ if (termios->c_iflag & IGNBRK) { -+ port->ignore_status_mask |= BD_SC_BR; -+ /* -+ * If we're ignore parity and break indicators, ignore -+ * overruns too. (For real raw support). -+ */ -+ if (termios->c_iflag & IGNPAR) -+ port->ignore_status_mask |= BD_SC_OV; -+ } -+ /* -+ * !!! ignore all characters if CREAD is not set -+ */ -+ if ((termios->c_cflag & CREAD) == 0) -+ port->read_status_mask &= ~BD_SC_EMPTY; -+ -+ baud = uart_get_baud_rate(port, termios, old, 0, 115200); -+ -+ /* Do we really need a spinlock here? */ -+ spin_lock_irqsave(&port->lock, flags); -+ -+ out_be16(&uccp->upsmr, upsmr); -+ if (soft_uart) { -+ out_be16(&uccup->supsmr, supsmr); -+ out_8(&uccup->rx_length, char_length); -+ -+ /* Soft-UART requires a 1X multiplier for TX */ -+ qe_setbrg(qe_port->us_info.rx_clock, baud, 16); -+ qe_setbrg(qe_port->us_info.tx_clock, baud, 1); -+ } else { -+ qe_setbrg(qe_port->us_info.rx_clock, baud, 16); -+ qe_setbrg(qe_port->us_info.tx_clock, baud, 16); -+ } -+ -+ spin_unlock_irqrestore(&port->lock, flags); -+} -+ -+/* -+ * Return a pointer to a string that describes what kind of port this is. -+ */ -+static const char *qe_uart_type(struct uart_port *port) -+{ -+ return "QE"; -+} -+ -+/* -+ * Allocate any memory and I/O resources required by the port. -+ */ -+static int qe_uart_request_port(struct uart_port *port) -+{ -+ int ret; -+ struct uart_qe_port *qe_port = -+ container_of(port, struct uart_qe_port, port); -+ struct ucc_slow_info *us_info = &qe_port->us_info; -+ struct ucc_slow_private *uccs; -+ unsigned int rx_size, tx_size; -+ void *bd_virt; -+ dma_addr_t bd_dma_addr = 0; -+ -+ ret = ucc_slow_init(us_info, &uccs); -+ if (ret) { -+ dev_err(port->dev, "could not initialize UCC%u\n", -+ qe_port->ucc_num); -+ return ret; -+ } -+ -+ qe_port->us_private = uccs; -+ qe_port->uccp = uccs->us_regs; -+ qe_port->uccup = (struct ucc_uart_pram *) uccs->us_pram; -+ qe_port->rx_bd_base = uccs->rx_bd; -+ qe_port->tx_bd_base = uccs->tx_bd; -+ -+ /* -+ * Allocate the transmit and receive data buffers. -+ */ -+ -+ rx_size = L1_CACHE_ALIGN(qe_port->rx_nrfifos * qe_port->rx_fifosize); -+ tx_size = L1_CACHE_ALIGN(qe_port->tx_nrfifos * qe_port->tx_fifosize); -+ -+ bd_virt = dma_alloc_coherent(NULL, rx_size + tx_size, &bd_dma_addr, -+ GFP_KERNEL); -+ if (!bd_virt) { -+ dev_err(port->dev, "could not allocate buffer descriptors\n"); -+ return -ENOMEM; -+ } -+ -+ qe_port->bd_virt = bd_virt; -+ qe_port->bd_dma_addr = bd_dma_addr; -+ qe_port->bd_size = rx_size + tx_size; -+ -+ qe_port->rx_buf = bd_virt; -+ qe_port->tx_buf = qe_port->rx_buf + rx_size; -+ -+ return 0; -+} -+ -+/* -+ * Configure the port. -+ * -+ * We say we're a CPM-type port because that's mostly true. Once the device -+ * is configured, this driver operates almost identically to the CPM serial -+ * driver. -+ */ -+static void qe_uart_config_port(struct uart_port *port, int flags) -+{ -+ if (flags & UART_CONFIG_TYPE) { -+ port->type = PORT_CPM; -+ qe_uart_request_port(port); -+ } -+} -+ -+/* -+ * Release any memory and I/O resources that were allocated in -+ * qe_uart_request_port(). -+ */ -+static void qe_uart_release_port(struct uart_port *port) -+{ -+ struct uart_qe_port *qe_port = -+ container_of(port, struct uart_qe_port, port); -+ struct ucc_slow_private *uccs = qe_port->us_private; -+ -+ dma_free_coherent(NULL, qe_port->bd_size, qe_port->bd_virt, -+ qe_port->bd_dma_addr); -+ -+ ucc_slow_free(uccs); -+} -+ -+/* -+ * Verify that the data in serial_struct is suitable for this device. -+ */ -+static int qe_uart_verify_port(struct uart_port *port, -+ struct serial_struct *ser) -+{ -+ if (ser->type != PORT_UNKNOWN && ser->type != PORT_CPM) -+ return -EINVAL; -+ -+ if (ser->irq < 0 || ser->irq >= NR_IRQS) -+ return -EINVAL; -+ -+ if (ser->baud_base < 9600) -+ return -EINVAL; -+ -+ return 0; -+} -+/* UART operations -+ * -+ * Details on these functions can be found in Documentation/serial/driver -+ */ -+static struct uart_ops qe_uart_pops = { -+ .tx_empty = qe_uart_tx_empty, -+ .set_mctrl = qe_uart_set_mctrl, -+ .get_mctrl = qe_uart_get_mctrl, -+ .stop_tx = qe_uart_stop_tx, -+ .start_tx = qe_uart_start_tx, -+ .stop_rx = qe_uart_stop_rx, -+ .enable_ms = qe_uart_enable_ms, -+ .break_ctl = qe_uart_break_ctl, -+ .startup = qe_uart_startup, -+ .shutdown = qe_uart_shutdown, -+ .set_termios = qe_uart_set_termios, -+ .type = qe_uart_type, -+ .release_port = qe_uart_release_port, -+ .request_port = qe_uart_request_port, -+ .config_port = qe_uart_config_port, -+ .verify_port = qe_uart_verify_port, -+}; -+ -+/* -+ * Obtain the SOC model number and revision level -+ * -+ * This function parses the device tree to obtain the SOC model. It then -+ * reads the SVR register to the revision. -+ * -+ * The device tree stores the SOC model two different ways. -+ * -+ * The new way is: -+ * -+ * cpu@0 { -+ * compatible = "PowerPC,8323"; -+ * device_type = "cpu"; -+ * ... -+ * -+ * -+ * The old way is: -+ * PowerPC,8323@0 { -+ * device_type = "cpu"; -+ * ... -+ * -+ * This code first checks the new way, and then the old way. -+ */ -+static unsigned int soc_info(unsigned int *rev_h, unsigned int *rev_l) -+{ -+ struct device_node *np; -+ const char *soc_string; -+ unsigned int svr; -+ unsigned int soc; -+ -+ /* Find the CPU node */ -+ np = of_find_node_by_type(NULL, "cpu"); -+ if (!np) -+ return 0; -+ /* Find the compatible property */ -+ soc_string = of_get_property(np, "compatible", NULL); -+ if (!soc_string) -+ /* No compatible property, so try the name. */ -+ soc_string = np->name; -+ -+ /* Extract the SOC number from the "PowerPC," string */ -+ if ((sscanf(soc_string, "PowerPC,%u", &soc) != 1) || !soc) -+ return 0; -+ -+ /* Get the revision from the SVR */ -+ svr = mfspr(SPRN_SVR); -+ *rev_h = (svr >> 4) & 0xf; -+ *rev_l = svr & 0xf; -+ -+ return soc; -+} -+ -+/* -+ * requst_firmware_nowait() callback function -+ * -+ * This function is called by the kernel when a firmware is made available, -+ * or if it times out waiting for the firmware. -+ */ -+static void uart_firmware_cont(const struct firmware *fw, void *context) -+{ -+ struct qe_firmware *firmware; -+ struct device *dev = context; -+ int ret; -+ -+ if (!fw) { -+ dev_err(dev, "firmware not found\n"); -+ return; -+ } -+ -+ firmware = (struct qe_firmware *) fw->data; -+ -+ if (firmware->header.length != fw->size) { -+ dev_err(dev, "invalid firmware\n"); -+ return; -+ } -+ -+ ret = qe_upload_firmware(firmware); -+ if (ret) { -+ dev_err(dev, "could not load firmware\n"); -+ return; -+ } -+ -+ firmware_loaded = 1; -+} -+ -+static int ucc_uart_probe(struct of_device *ofdev, -+ const struct of_device_id *match) -+{ -+ struct device_node *np = ofdev->node; -+ const unsigned int *iprop; /* Integer OF properties */ -+ const char *sprop; /* String OF properties */ -+ struct uart_qe_port *qe_port = NULL; -+ struct resource res; -+ int ret; -+ -+ /* -+ * Determine if we need Soft-UART mode -+ */ -+ if (of_find_property(np, "soft-uart", NULL)) { -+ dev_dbg(&ofdev->dev, "using Soft-UART mode\n"); -+ soft_uart = 1; -+ } -+ -+ /* -+ * If we are using Soft-UART, determine if we need to upload the -+ * firmware, too. -+ */ -+ if (soft_uart) { -+ struct qe_firmware_info *qe_fw_info; -+ -+ qe_fw_info = qe_get_firmware_info(); -+ -+ /* Check if the firmware has been uploaded. */ -+ if (qe_fw_info && strstr(qe_fw_info->id, "Soft-UART")) { -+ firmware_loaded = 1; -+ } else { -+ char filename[32]; -+ unsigned int soc; -+ unsigned int rev_h; -+ unsigned int rev_l; -+ -+ soc = soc_info(&rev_h, &rev_l); -+ if (!soc) { -+ dev_err(&ofdev->dev, "unknown CPU model\n"); -+ return -ENXIO; -+ } -+ sprintf(filename, "fsl_qe_ucode_uart_%u_%u%u.bin", -+ soc, rev_h, rev_l); -+ -+ dev_info(&ofdev->dev, "waiting for firmware %s\n", -+ filename); -+ -+ /* -+ * We call request_firmware_nowait instead of -+ * request_firmware so that the driver can load and -+ * initialize the ports without holding up the rest of -+ * the kernel. If hotplug support is enabled in the -+ * kernel, then we use it. -+ */ -+ ret = request_firmware_nowait(THIS_MODULE, -+ FW_ACTION_HOTPLUG, filename, &ofdev->dev, -+ &ofdev->dev, uart_firmware_cont); -+ if (ret) { -+ dev_err(&ofdev->dev, -+ "could not load firmware %s\n", -+ filename); -+ return ret; -+ } -+ } -+ } -+ -+ qe_port = kzalloc(sizeof(struct uart_qe_port), GFP_KERNEL); -+ if (!qe_port) { -+ dev_err(&ofdev->dev, "can't allocate QE port structure\n"); -+ return -ENOMEM; -+ } -+ -+ /* Search for IRQ and mapbase */ -+ ret = of_address_to_resource(np, 0, &res); -+ if (ret) { -+ dev_err(&ofdev->dev, "missing 'reg' property in device tree\n"); -+ kfree(qe_port); -+ return ret; -+ } -+ if (!res.start) { -+ dev_err(&ofdev->dev, "invalid 'reg' property in device tree\n"); -+ kfree(qe_port); -+ return -EINVAL; -+ } -+ qe_port->port.mapbase = res.start; -+ -+ /* Get the UCC number (device ID) */ -+ /* UCCs are numbered 1-7 */ -+ iprop = of_get_property(np, "device-id", NULL); -+ if (!iprop || (*iprop < 1) || (*iprop > UCC_MAX_NUM)) { -+ dev_err(&ofdev->dev, -+ "missing or invalid UCC specified in device tree\n"); -+ kfree(qe_port); -+ return -ENODEV; -+ } -+ qe_port->ucc_num = *iprop - 1; -+ -+ /* -+ * In the future, we should not require the BRG to be specified in the -+ * device tree. If no clock-source is specified, then just pick a BRG -+ * to use. This requires a new QE library function that manages BRG -+ * assignments. -+ */ -+ -+ sprop = of_get_property(np, "rx-clock-name", NULL); -+ if (!sprop) { -+ dev_err(&ofdev->dev, "missing rx-clock-name in device tree\n"); -+ kfree(qe_port); -+ return -ENODEV; -+ } -+ -+ qe_port->us_info.rx_clock = qe_clock_source(sprop); -+ if ((qe_port->us_info.rx_clock < QE_BRG1) || -+ (qe_port->us_info.rx_clock > QE_BRG16)) { -+ dev_err(&ofdev->dev, "rx-clock-name must be a BRG for UART\n"); -+ kfree(qe_port); -+ return -ENODEV; -+ } -+ -+#ifdef LOOPBACK -+ /* In internal loopback mode, TX and RX must use the same clock */ -+ qe_port->us_info.tx_clock = qe_port->us_info.rx_clock; -+#else -+ sprop = of_get_property(np, "tx-clock-name", NULL); -+ if (!sprop) { -+ dev_err(&ofdev->dev, "missing tx-clock-name in device tree\n"); -+ kfree(qe_port); -+ return -ENODEV; -+ } -+ qe_port->us_info.tx_clock = qe_clock_source(sprop); -+#endif -+ if ((qe_port->us_info.tx_clock < QE_BRG1) || -+ (qe_port->us_info.tx_clock > QE_BRG16)) { -+ dev_err(&ofdev->dev, "tx-clock-name must be a BRG for UART\n"); -+ kfree(qe_port); -+ return -ENODEV; -+ } -+ -+ /* Get the port number, numbered 0-3 */ -+ iprop = of_get_property(np, "port-number", NULL); -+ if (!iprop) { -+ dev_err(&ofdev->dev, "missing port-number in device tree\n"); -+ kfree(qe_port); -+ return -EINVAL; -+ } -+ qe_port->port.line = *iprop; -+ if (qe_port->port.line >= UCC_MAX_UART) { -+ dev_err(&ofdev->dev, "port-number must be 0-%u\n", -+ UCC_MAX_UART - 1); -+ kfree(qe_port); -+ return -EINVAL; -+ } -+ -+ qe_port->port.irq = irq_of_parse_and_map(np, 0); -+ if (qe_port->port.irq == NO_IRQ) { -+ dev_err(&ofdev->dev, "could not map IRQ for UCC%u\n", -+ qe_port->ucc_num + 1); -+ kfree(qe_port); -+ return -EINVAL; -+ } -+ -+ /* -+ * Newer device trees have an "fsl,qe" compatible property for the QE -+ * node, but we still need to support older device trees. -+ */ -+ np = of_find_compatible_node(NULL, NULL, "fsl,qe"); -+ if (!np) { -+ np = of_find_node_by_type(NULL, "qe"); -+ if (!np) { -+ dev_err(&ofdev->dev, "could not find 'qe' node\n"); -+ kfree(qe_port); -+ return -EINVAL; -+ } -+ } -+ -+ iprop = of_get_property(np, "brg-frequency", NULL); -+ if (!iprop) { -+ dev_err(&ofdev->dev, -+ "missing brg-frequency in device tree\n"); -+ kfree(qe_port); -+ return -EINVAL; -+ } -+ -+ if (*iprop) -+ qe_port->port.uartclk = *iprop; -+ else { -+ /* -+ * Older versions of U-Boot do not initialize the brg-frequency -+ * property, so in this case we assume the BRG frequency is -+ * half the QE bus frequency. -+ */ -+ iprop = of_get_property(np, "bus-frequency", NULL); -+ if (!iprop) { -+ dev_err(&ofdev->dev, -+ "missing QE bus-frequency in device tree\n"); -+ kfree(qe_port); -+ return -EINVAL; -+ } -+ if (*iprop) -+ qe_port->port.uartclk = *iprop / 2; -+ else { -+ dev_err(&ofdev->dev, -+ "invalid QE bus-frequency in device tree\n"); -+ kfree(qe_port); -+ return -EINVAL; -+ } -+ } -+ -+ spin_lock_init(&qe_port->port.lock); -+ qe_port->np = np; -+ qe_port->port.dev = &ofdev->dev; -+ qe_port->port.ops = &qe_uart_pops; -+ qe_port->port.iotype = UPIO_MEM; -+ -+ qe_port->tx_nrfifos = TX_NUM_FIFO; -+ qe_port->tx_fifosize = TX_BUF_SIZE; -+ qe_port->rx_nrfifos = RX_NUM_FIFO; -+ qe_port->rx_fifosize = RX_BUF_SIZE; -+ -+ qe_port->wait_closing = UCC_WAIT_CLOSING; -+ qe_port->port.fifosize = 512; -+ qe_port->port.flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP; -+ -+ qe_port->us_info.ucc_num = qe_port->ucc_num; -+ qe_port->us_info.regs = (phys_addr_t) res.start; -+ qe_port->us_info.irq = qe_port->port.irq; -+ -+ qe_port->us_info.rx_bd_ring_len = qe_port->rx_nrfifos; -+ qe_port->us_info.tx_bd_ring_len = qe_port->tx_nrfifos; -+ -+ /* Make sure ucc_slow_init() initializes both TX and RX */ -+ qe_port->us_info.init_tx = 1; -+ qe_port->us_info.init_rx = 1; -+ -+ /* Add the port to the uart sub-system. This will cause -+ * qe_uart_config_port() to be called, so the us_info structure must -+ * be initialized. -+ */ -+ ret = uart_add_one_port(&ucc_uart_driver, &qe_port->port); -+ if (ret) { -+ dev_err(&ofdev->dev, "could not add /dev/ttyQE%u\n", -+ qe_port->port.line); -+ kfree(qe_port); -+ return ret; -+ } -+ -+ dev_set_drvdata(&ofdev->dev, qe_port); -+ -+ dev_info(&ofdev->dev, "UCC%u assigned to /dev/ttyQE%u\n", -+ qe_port->ucc_num + 1, qe_port->port.line); -+ -+ /* Display the mknod command for this device */ -+ dev_dbg(&ofdev->dev, "mknod command is 'mknod /dev/ttyQE%u c %u %u'\n", -+ qe_port->port.line, SERIAL_QE_MAJOR, -+ SERIAL_QE_MINOR + qe_port->port.line); -+ -+ return 0; -+} -+ -+static int ucc_uart_remove(struct of_device *ofdev) -+{ -+ struct uart_qe_port *qe_port = dev_get_drvdata(&ofdev->dev); -+ -+ dev_info(&ofdev->dev, "removing /dev/ttyQE%u\n", qe_port->port.line); -+ -+ uart_remove_one_port(&ucc_uart_driver, &qe_port->port); -+ -+ dev_set_drvdata(&ofdev->dev, NULL); -+ kfree(qe_port); -+ -+ return 0; -+} -+ -+static struct of_device_id ucc_uart_match[] = { -+ { -+ .type = "serial", -+ .compatible = "ucc_uart", -+ }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, ucc_uart_match); -+ -+static struct of_platform_driver ucc_uart_of_driver = { -+ .owner = THIS_MODULE, -+ .name = "ucc_uart", -+ .match_table = ucc_uart_match, -+ .probe = ucc_uart_probe, -+ .remove = ucc_uart_remove, -+}; -+ -+static int __init ucc_uart_init(void) -+{ -+ int ret; -+ -+ printk(KERN_INFO "Freescale QUICC Engine UART device driver\n"); -+#ifdef LOOPBACK -+ printk(KERN_INFO "ucc-uart: Using loopback mode\n"); -+#endif -+ -+ ret = uart_register_driver(&ucc_uart_driver); -+ if (ret) { -+ printk(KERN_ERR "ucc-uart: could not register UART driver\n"); -+ return ret; -+ } -+ -+ ret = of_register_platform_driver(&ucc_uart_of_driver); -+ if (ret) -+ printk(KERN_ERR -+ "ucc-uart: could not register platform driver\n"); -+ -+ return ret; -+} -+ -+static void __exit ucc_uart_exit(void) -+{ -+ printk(KERN_INFO -+ "Freescale QUICC Engine UART device driver unloading\n"); -+ -+ of_unregister_platform_driver(&ucc_uart_of_driver); -+ uart_unregister_driver(&ucc_uart_driver); -+} -+ -+module_init(ucc_uart_init); -+module_exit(ucc_uart_exit); -+ -+MODULE_DESCRIPTION("Freescale QUICC Engine (QE) UART"); -+MODULE_AUTHOR("Timur Tabi "); -+MODULE_LICENSE("GPL v2"); -+MODULE_ALIAS_CHARDEV_MAJOR(SERIAL_QE_MAJOR); -+ ---- a/drivers/spi/mpc52xx_psc_spi.c -+++ b/drivers/spi/mpc52xx_psc_spi.c -@@ -330,6 +330,7 @@ static void mpc52xx_psc_spi_cleanup(stru - - static int mpc52xx_psc_spi_port_config(int psc_id, struct mpc52xx_psc_spi *mps) - { -+ struct device_node *np; - struct mpc52xx_cdm __iomem *cdm; - struct mpc52xx_gpio __iomem *gpio; - struct mpc52xx_psc __iomem *psc = mps->psc; -@@ -338,8 +339,12 @@ static int mpc52xx_psc_spi_port_config(i - int ret = 0; - - #if defined(CONFIG_PPC_MERGE) -- cdm = mpc52xx_find_and_map("mpc5200-cdm"); -- gpio = mpc52xx_find_and_map("mpc5200-gpio"); -+ np = of_find_compatible_node(NULL, NULL, "mpc5200-cdm"); -+ cdm = of_iomap(np, 0); -+ of_node_put(np); -+ np = of_find_compatible_node(NULL, NULL, "mpc5200-gpio"); -+ gpio = of_iomap(np, 0); -+ of_node_put(np); - #else - cdm = ioremap(MPC52xx_PA(MPC52xx_CDM_OFFSET), MPC52xx_CDM_SIZE); - gpio = ioremap(MPC52xx_PA(MPC52xx_GPIO_OFFSET), MPC52xx_GPIO_SIZE); ---- a/fs/openpromfs/inode.c -+++ b/fs/openpromfs/inode.c -@@ -131,7 +131,7 @@ static void property_stop(struct seq_fil - /* Nothing to do */ - } - --static const struct seq_operations property_op = { -+static struct seq_operations property_op = { - .start = property_start, - .next = property_next, - .stop = property_stop, ---- a/include/asm-powerpc/8xx_immap.h -+++ b/include/asm-powerpc/8xx_immap.h -@@ -123,7 +123,7 @@ typedef struct mem_ctlr { - #define OR_G5LA 0x00000400 /* Output #GPL5 on #GPL_A5 */ - #define OR_G5LS 0x00000200 /* Drive #GPL high on falling edge of...*/ - #define OR_BI 0x00000100 /* Burst inhibit */ --#define OR_SCY_MSK 0x000000f0 /* Cycle Lenght in Clocks */ -+#define OR_SCY_MSK 0x000000f0 /* Cycle Length in Clocks */ - #define OR_SCY_0_CLK 0x00000000 /* 0 clock cycles wait states */ - #define OR_SCY_1_CLK 0x00000010 /* 1 clock cycles wait states */ - #define OR_SCY_2_CLK 0x00000020 /* 2 clock cycles wait states */ ---- a/include/asm-powerpc/commproc.h -+++ b/include/asm-powerpc/commproc.h -@@ -693,7 +693,7 @@ typedef struct risc_timer_pram { - #define CICR_SCC_SCC3 ((uint)0x00200000) /* SCC3 @ SCCc */ - #define CICR_SCB_SCC2 ((uint)0x00040000) /* SCC2 @ SCCb */ - #define CICR_SCA_SCC1 ((uint)0x00000000) /* SCC1 @ SCCa */ --#define CICR_IRL_MASK ((uint)0x0000e000) /* Core interrrupt */ -+#define CICR_IRL_MASK ((uint)0x0000e000) /* Core interrupt */ - #define CICR_HP_MASK ((uint)0x00001f00) /* Hi-pri int. */ - #define CICR_IEN ((uint)0x00000080) /* Int. enable */ - #define CICR_SPS ((uint)0x00000001) /* SCC Spread */ ---- a/include/asm-powerpc/cpm.h -+++ b/include/asm-powerpc/cpm.h -@@ -10,5 +10,6 @@ int cpm_muram_free(unsigned long offset) - unsigned long cpm_muram_alloc_fixed(unsigned long offset, unsigned long size); - void __iomem *cpm_muram_addr(unsigned long offset); - dma_addr_t cpm_muram_dma(void __iomem *addr); -+int cpm_command(u32 command, u8 opcode); - - #endif ---- a/include/asm-powerpc/cputable.h -+++ b/include/asm-powerpc/cputable.h -@@ -57,6 +57,14 @@ enum powerpc_pmc_type { - PPC_PMC_PA6T = 2, - }; - -+struct pt_regs; -+ -+extern int machine_check_generic(struct pt_regs *regs); -+extern int machine_check_4xx(struct pt_regs *regs); -+extern int machine_check_440A(struct pt_regs *regs); -+extern int machine_check_e500(struct pt_regs *regs); -+extern int machine_check_e200(struct pt_regs *regs); -+ - /* NOTE WELL: Update identify_cpu() if fields are added or removed! */ - struct cpu_spec { - /* CPU is matched via (PVR & pvr_mask) == pvr_value */ -@@ -97,6 +105,11 @@ struct cpu_spec { - - /* Name of processor class, for the ELF AT_PLATFORM entry */ - char *platform; -+ -+ /* Processor specific machine check handling. Return negative -+ * if the error is fatal, 1 if it was fully recovered and 0 to -+ * pass up (not CPU originated) */ -+ int (*machine_check)(struct pt_regs *regs); - }; - - extern struct cpu_spec *cur_cpu_spec; ---- /dev/null -+++ b/include/asm-powerpc/cputhreads.h -@@ -0,0 +1,71 @@ -+#ifndef _ASM_POWERPC_CPUTHREADS_H -+#define _ASM_POWERPC_CPUTHREADS_H -+ -+#include -+ -+/* -+ * Mapping of threads to cores -+ */ -+ -+#ifdef CONFIG_SMP -+extern int threads_per_core; -+extern int threads_shift; -+extern cpumask_t threads_core_mask; -+#else -+#define threads_per_core 1 -+#define threads_shift 0 -+#define threads_core_mask (CPU_MASK_CPU0) -+#endif -+ -+/* cpu_thread_mask_to_cores - Return a cpumask of one per cores -+ * hit by the argument -+ * -+ * @threads: a cpumask of threads -+ * -+ * This function returns a cpumask which will have one "cpu" (or thread) -+ * bit set for each core that has at least one thread set in the argument. -+ * -+ * This can typically be used for things like IPI for tlb invalidations -+ * since those need to be done only once per core/TLB -+ */ -+static inline cpumask_t cpu_thread_mask_to_cores(cpumask_t threads) -+{ -+ cpumask_t tmp, res; -+ int i; -+ -+ res = CPU_MASK_NONE; -+ for (i = 0; i < NR_CPUS; i += threads_per_core) { -+ cpus_shift_right(tmp, threads_core_mask, i); -+ if (cpus_intersects(threads, tmp)) -+ cpu_set(i, res); -+ } -+ return res; -+} -+ -+static inline int cpu_nr_cores(void) -+{ -+ return NR_CPUS >> threads_shift; -+} -+ -+static inline cpumask_t cpu_online_cores_map(void) -+{ -+ return cpu_thread_mask_to_cores(cpu_online_map); -+} -+ -+static inline int cpu_thread_to_core(int cpu) -+{ -+ return cpu >> threads_shift; -+} -+ -+static inline int cpu_thread_in_core(int cpu) -+{ -+ return cpu & (threads_per_core - 1); -+} -+ -+static inline int cpu_first_thread_in_core(int cpu) -+{ -+ return cpu & ~(threads_per_core - 1); -+} -+ -+#endif /* _ASM_POWERPC_CPUTHREADS_H */ -+ ---- a/include/asm-powerpc/dcr-native.h -+++ b/include/asm-powerpc/dcr-native.h -@@ -22,6 +22,8 @@ - #ifdef __KERNEL__ - #ifndef __ASSEMBLY__ - -+#include -+ - typedef struct { - unsigned int base; - } dcr_host_t; -@@ -55,20 +57,28 @@ do { \ - } while (0) - - /* R/W of indirect DCRs make use of standard naming conventions for DCRs */ --#define mfdcri(base, reg) \ --({ \ -- mtdcr(base ## _CFGADDR, base ## _ ## reg); \ -- mfdcr(base ## _CFGDATA); \ -+extern spinlock_t dcr_ind_lock; -+ -+#define mfdcri(base, reg) \ -+({ \ -+ unsigned long flags; \ -+ unsigned int val; \ -+ spin_lock_irqsave(&dcr_ind_lock, flags); \ -+ mtdcr(DCRN_ ## base ## _CONFIG_ADDR, reg); \ -+ val = mfdcr(DCRN_ ## base ## _CONFIG_DATA); \ -+ spin_unlock_irqrestore(&dcr_ind_lock, flags); \ -+ val; \ - }) - --#define mtdcri(base, reg, data) \ --do { \ -- mtdcr(base ## _CFGADDR, base ## _ ## reg); \ -- mtdcr(base ## _CFGDATA, data); \ -+#define mtdcri(base, reg, data) \ -+do { \ -+ unsigned long flags; \ -+ spin_lock_irqsave(&dcr_ind_lock, flags); \ -+ mtdcr(DCRN_ ## base ## _CONFIG_ADDR, reg); \ -+ mtdcr(DCRN_ ## base ## _CONFIG_DATA, data); \ -+ spin_unlock_irqrestore(&dcr_ind_lock, flags); \ - } while (0) - - #endif /* __ASSEMBLY__ */ - #endif /* __KERNEL__ */ - #endif /* _ASM_POWERPC_DCR_NATIVE_H */ -- -- ---- /dev/null -+++ b/include/asm-powerpc/dcr-regs.h -@@ -0,0 +1,71 @@ -+/* -+ * Common DCR / SDR / CPR register definitions used on various IBM/AMCC -+ * 4xx processors -+ * -+ * Copyright 2007 Benjamin Herrenschmidt, IBM Corp -+ * -+ * -+ * Mostly lifted from asm-ppc/ibm4xx.h by -+ * -+ * Copyright (c) 1999 Grant Erickson -+ * -+ */ -+ -+#ifndef __DCR_REGS_H__ -+#define __DCR_REGS_H__ -+ -+/* -+ * Most DCRs used for controlling devices such as the MAL, DMA engine, -+ * etc... are obtained for the device tree. -+ * -+ * The definitions in this files are fixed DCRs and indirect DCRs that -+ * are commonly used outside of specific drivers or refer to core -+ * common registers that may occasionally have to be tweaked outside -+ * of the driver main register set -+ */ -+ -+/* CPRs (440GX and 440SP/440SPe) */ -+#define DCRN_CPR0_CONFIG_ADDR 0xc -+#define DCRN_CPR0_CONFIG_DATA 0xd -+ -+/* SDRs (440GX and 440SP/440SPe) */ -+#define DCRN_SDR0_CONFIG_ADDR 0xe -+#define DCRN_SDR0_CONFIG_DATA 0xf -+ -+#define SDR0_PFC0 0x4100 -+#define SDR0_PFC1 0x4101 -+#define SDR0_PFC1_EPS 0x1c00000 -+#define SDR0_PFC1_EPS_SHIFT 22 -+#define SDR0_PFC1_RMII 0x02000000 -+#define SDR0_MFR 0x4300 -+#define SDR0_MFR_TAH0 0x80000000 /* TAHOE0 Enable */ -+#define SDR0_MFR_TAH1 0x40000000 /* TAHOE1 Enable */ -+#define SDR0_MFR_PCM 0x10000000 /* PPC440GP irq compat mode */ -+#define SDR0_MFR_ECS 0x08000000 /* EMAC int clk */ -+#define SDR0_MFR_T0TXFL 0x00080000 -+#define SDR0_MFR_T0TXFH 0x00040000 -+#define SDR0_MFR_T1TXFL 0x00020000 -+#define SDR0_MFR_T1TXFH 0x00010000 -+#define SDR0_MFR_E0TXFL 0x00008000 -+#define SDR0_MFR_E0TXFH 0x00004000 -+#define SDR0_MFR_E0RXFL 0x00002000 -+#define SDR0_MFR_E0RXFH 0x00001000 -+#define SDR0_MFR_E1TXFL 0x00000800 -+#define SDR0_MFR_E1TXFH 0x00000400 -+#define SDR0_MFR_E1RXFL 0x00000200 -+#define SDR0_MFR_E1RXFH 0x00000100 -+#define SDR0_MFR_E2TXFL 0x00000080 -+#define SDR0_MFR_E2TXFH 0x00000040 -+#define SDR0_MFR_E2RXFL 0x00000020 -+#define SDR0_MFR_E2RXFH 0x00000010 -+#define SDR0_MFR_E3TXFL 0x00000008 -+#define SDR0_MFR_E3TXFH 0x00000004 -+#define SDR0_MFR_E3RXFL 0x00000002 -+#define SDR0_MFR_E3RXFH 0x00000001 -+#define SDR0_UART0 0x0120 -+#define SDR0_UART1 0x0121 -+#define SDR0_UART2 0x0122 -+#define SDR0_UART3 0x0123 -+#define SDR0_CUST0 0x4000 -+ -+#endif /* __DCR_REGS_H__ */ ---- a/include/asm-powerpc/dma-mapping.h -+++ b/include/asm-powerpc/dma-mapping.h -@@ -87,6 +87,9 @@ static inline int dma_supported(struct d - return dma_ops->dma_supported(dev, mask); - } - -+/* We have our own implementation of pci_set_dma_mask() */ -+#define HAVE_ARCH_PCI_SET_DMA_MASK -+ - static inline int dma_set_mask(struct device *dev, u64 dma_mask) - { - struct dma_mapping_ops *dma_ops = get_dma_ops(dev); -@@ -186,8 +189,6 @@ static inline void dma_unmap_sg(struct d - extern struct dma_mapping_ops dma_iommu_ops; - extern struct dma_mapping_ops dma_direct_ops; - --extern unsigned long dma_direct_offset; -- - #else /* CONFIG_PPC64 */ - - #define dma_supported(dev, mask) (1) ---- a/include/asm-powerpc/firmware.h -+++ b/include/asm-powerpc/firmware.h -@@ -64,7 +64,7 @@ enum { - FW_FEATURE_PS3_POSSIBLE = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1, - FW_FEATURE_PS3_ALWAYS = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1, - FW_FEATURE_CELLEB_POSSIBLE = FW_FEATURE_LPAR | FW_FEATURE_BEAT, -- FW_FEATURE_CELLEB_ALWAYS = FW_FEATURE_LPAR | FW_FEATURE_BEAT, -+ FW_FEATURE_CELLEB_ALWAYS = 0, - FW_FEATURE_NATIVE_POSSIBLE = 0, - FW_FEATURE_NATIVE_ALWAYS = 0, - FW_FEATURE_POSSIBLE = ---- a/include/asm-powerpc/immap_86xx.h -+++ b/include/asm-powerpc/immap_86xx.h -@@ -89,14 +89,14 @@ struct ccsr_guts { - * them. - * - * guts: Pointer to GUTS structure -- * co: The DMA controller (1 or 2) -+ * co: The DMA controller (0 or 1) - * ch: The channel on the DMA controller (0, 1, 2, or 3) - * device: The device to set as the source (CCSR_GUTS_DMACR_DEV_xx) - */ - static inline void guts_set_dmacr(struct ccsr_guts __iomem *guts, - unsigned int co, unsigned int ch, unsigned int device) - { -- unsigned int shift = 16 + (8 * (2 - co) + 2 * (3 - ch)); -+ unsigned int shift = 16 + (8 * (1 - co) + 2 * (3 - ch)); - - clrsetbits_be32(&guts->dmacr, 3 << shift, device << shift); - } -@@ -118,6 +118,27 @@ static inline void guts_set_dmacr(struct - #define CCSR_GUTS_PMUXCR_DMA1_0 0x00000002 - #define CCSR_GUTS_PMUXCR_DMA1_3 0x00000001 - -+/* -+ * Set the DMA external control bits in the GUTS -+ * -+ * The DMA external control bits in the PMUXCR are only meaningful for -+ * channels 0 and 3. Any other channels are ignored. -+ * -+ * guts: Pointer to GUTS structure -+ * co: The DMA controller (0 or 1) -+ * ch: The channel on the DMA controller (0, 1, 2, or 3) -+ * value: the new value for the bit (0 or 1) -+ */ -+static inline void guts_set_pmuxcr_dma(struct ccsr_guts __iomem *guts, -+ unsigned int co, unsigned int ch, unsigned int value) -+{ -+ if ((ch == 0) || (ch == 3)) { -+ unsigned int shift = 2 * (co + 1) - (ch & 1) - 1; -+ -+ clrsetbits_be32(&guts->pmuxcr, 1 << shift, value << shift); -+ } -+} -+ - #define CCSR_GUTS_CLKDVDR_PXCKEN 0x80000000 - #define CCSR_GUTS_CLKDVDR_SSICKEN 0x20000000 - #define CCSR_GUTS_CLKDVDR_PXCKINV 0x10000000 ---- a/include/asm-powerpc/immap_qe.h -+++ b/include/asm-powerpc/immap_qe.h -@@ -393,9 +393,39 @@ struct dbg { - u8 res2[0x48]; - } __attribute__ ((packed)); - --/* RISC Special Registers (Trap and Breakpoint) */ -+/* -+ * RISC Special Registers (Trap and Breakpoint). These are described in -+ * the QE Developer's Handbook. -+ */ - struct rsp { -- u32 reg[0x40]; /* 64 32-bit registers */ -+ __be32 tibcr[16]; /* Trap/instruction breakpoint control regs */ -+ u8 res0[64]; -+ __be32 ibcr0; -+ __be32 ibs0; -+ __be32 ibcnr0; -+ u8 res1[4]; -+ __be32 ibcr1; -+ __be32 ibs1; -+ __be32 ibcnr1; -+ __be32 npcr; -+ __be32 dbcr; -+ __be32 dbar; -+ __be32 dbamr; -+ __be32 dbsr; -+ __be32 dbcnr; -+ u8 res2[12]; -+ __be32 dbdr_h; -+ __be32 dbdr_l; -+ __be32 dbdmr_h; -+ __be32 dbdmr_l; -+ __be32 bsr; -+ __be32 bor; -+ __be32 bior; -+ u8 res3[4]; -+ __be32 iatr[4]; -+ __be32 eccr; /* Exception control configuration register */ -+ __be32 eicr; -+ u8 res4[0x100-0xf8]; - } __attribute__ ((packed)); - - struct qe_immap { ---- a/include/asm-powerpc/io.h -+++ b/include/asm-powerpc/io.h -@@ -50,15 +50,16 @@ extern int check_legacy_ioport(unsigned - #define PCI_DRAM_OFFSET pci_dram_offset - #else - #define _IO_BASE pci_io_base --#define _ISA_MEM_BASE 0 -+#define _ISA_MEM_BASE isa_mem_base - #define PCI_DRAM_OFFSET 0 - #endif - - extern unsigned long isa_io_base; --extern unsigned long isa_mem_base; - extern unsigned long pci_io_base; - extern unsigned long pci_dram_offset; - -+extern resource_size_t isa_mem_base; -+ - #if defined(CONFIG_PPC32) && defined(CONFIG_PPC_INDIRECT_IO) - #error CONFIG_PPC_INDIRECT_IO is not yet supported on 32 bits - #endif ---- a/include/asm-powerpc/iommu.h -+++ b/include/asm-powerpc/iommu.h -@@ -69,10 +69,9 @@ struct iommu_table { - }; - - struct scatterlist; --struct device_node; - - /* Frees table for an individual device node */ --extern void iommu_free_table(struct device_node *dn); -+extern void iommu_free_table(struct iommu_table *tbl, const char *node_name); - - /* Initializes an iommu_table based in values set in the passed-in - * structure ---- a/include/asm-powerpc/ipic.h -+++ b/include/asm-powerpc/ipic.h -@@ -20,11 +20,13 @@ - - /* Flags when we init the IPIC */ - #define IPIC_SPREADMODE_GRP_A 0x00000001 --#define IPIC_SPREADMODE_GRP_D 0x00000002 --#define IPIC_SPREADMODE_MIX_A 0x00000004 --#define IPIC_SPREADMODE_MIX_B 0x00000008 --#define IPIC_DISABLE_MCP_OUT 0x00000010 --#define IPIC_IRQ0_MCP 0x00000020 -+#define IPIC_SPREADMODE_GRP_B 0x00000002 -+#define IPIC_SPREADMODE_GRP_C 0x00000004 -+#define IPIC_SPREADMODE_GRP_D 0x00000008 -+#define IPIC_SPREADMODE_MIX_A 0x00000010 -+#define IPIC_SPREADMODE_MIX_B 0x00000020 -+#define IPIC_DISABLE_MCP_OUT 0x00000040 -+#define IPIC_IRQ0_MCP 0x00000080 - - /* IPIC registers offsets */ - #define IPIC_SICFR 0x00 /* System Global Interrupt Configuration Register */ ---- a/include/asm-powerpc/iseries/hv_lp_event.h -+++ b/include/asm-powerpc/iseries/hv_lp_event.h -@@ -78,7 +78,7 @@ extern int HvLpEvent_openPath(HvLpEvent_ - - /* - * Close an Lp Event Path for a type and partition -- * returns 0 on sucess -+ * returns 0 on success - */ - extern int HvLpEvent_closePath(HvLpEvent_Type eventType, HvLpIndex lpIndex); - ---- a/include/asm-powerpc/kexec.h -+++ b/include/asm-powerpc/kexec.h -@@ -123,6 +123,9 @@ struct pt_regs; - extern void default_machine_kexec(struct kimage *image); - extern int default_machine_kexec_prepare(struct kimage *image); - extern void default_machine_crash_shutdown(struct pt_regs *regs); -+typedef void (*crash_shutdown_t)(void); -+extern int crash_shutdown_register(crash_shutdown_t handler); -+extern int crash_shutdown_unregister(crash_shutdown_t handler); - - extern void machine_kexec_simple(struct kimage *image); - extern void crash_kexec_secondary(struct pt_regs *regs); ---- a/include/asm-powerpc/lmb.h -+++ b/include/asm-powerpc/lmb.h -@@ -51,6 +51,7 @@ extern unsigned long __init __lmb_alloc_ - extern unsigned long __init lmb_phys_mem_size(void); - extern unsigned long __init lmb_end_of_DRAM(void); - extern void __init lmb_enforce_memory_limit(unsigned long memory_limit); -+extern int __init lmb_is_reserved(unsigned long addr); - - extern void lmb_dump_all(void); - ---- a/include/asm-powerpc/machdep.h -+++ b/include/asm-powerpc/machdep.h -@@ -204,6 +204,13 @@ struct machdep_calls { - /* - * optional PCI "hooks" - */ -+ /* Called in indirect_* to avoid touching devices */ -+ int (*pci_exclude_device)(struct pci_controller *, unsigned char, unsigned char); -+ -+ /* Called at then very end of pcibios_init() */ -+ void (*pcibios_after_init)(void); -+ -+#endif /* CONFIG_PPC32 */ - - /* Called after PPC generic resource fixup to perform - machine specific fixups */ -@@ -212,18 +219,9 @@ struct machdep_calls { - /* Called for each PCI bus in the system when it's probed */ - void (*pcibios_fixup_bus)(struct pci_bus *); - -- /* Called when pci_enable_device() is called (initial=0) or -- * when a device with no assigned resource is found (initial=1). -- * Returns 0 to allow assignment/enabling of the device. */ -- int (*pcibios_enable_device_hook)(struct pci_dev *, int initial); -- -- /* Called in indirect_* to avoid touching devices */ -- int (*pci_exclude_device)(struct pci_controller *, unsigned char, unsigned char); -- -- /* Called at then very end of pcibios_init() */ -- void (*pcibios_after_init)(void); -- --#endif /* CONFIG_PPC32 */ -+ /* Called when pci_enable_device() is called. Returns 0 to -+ * allow assignment/enabling of the device. */ -+ int (*pcibios_enable_device_hook)(struct pci_dev *); - - /* Called to shutdown machine specific hardware not already controlled - * by other drivers. -@@ -253,6 +251,16 @@ struct machdep_calls { - */ - void (*machine_kexec)(struct kimage *image); - #endif /* CONFIG_KEXEC */ -+ -+#ifdef CONFIG_SUSPEND -+ /* These are called to disable and enable, respectively, IRQs when -+ * entering a suspend state. If NULL, then the generic versions -+ * will be called. The generic versions disable/enable the -+ * decrementer along with interrupts. -+ */ -+ void (*suspend_disable_irqs)(void); -+ void (*suspend_enable_irqs)(void); -+#endif - }; - - extern void power4_idle(void); -@@ -326,5 +334,31 @@ static inline void log_error(char *buf, - ppc_md.log_error(buf, err_type, fatal); - } - -+#define __define_machine_initcall(mach,level,fn,id) \ -+ static int __init __machine_initcall_##mach##_##fn(void) { \ -+ if (machine_is(mach)) return fn(); \ -+ return 0; \ -+ } \ -+ __define_initcall(level,__machine_initcall_##mach##_##fn,id); -+ -+#define machine_core_initcall(mach,fn) __define_machine_initcall(mach,"1",fn,1) -+#define machine_core_initcall_sync(mach,fn) __define_machine_initcall(mach,"1s",fn,1s) -+#define machine_postcore_initcall(mach,fn) __define_machine_initcall(mach,"2",fn,2) -+#define machine_postcore_initcall_sync(mach,fn) __define_machine_initcall(mach,"2s",fn,2s) -+#define machine_arch_initcall(mach,fn) __define_machine_initcall(mach,"3",fn,3) -+#define machine_arch_initcall_sync(mach,fn) __define_machine_initcall(mach,"3s",fn,3s) -+#define machine_subsys_initcall(mach,fn) __define_machine_initcall(mach,"4",fn,4) -+#define machine_subsys_initcall_sync(mach,fn) __define_machine_initcall(mach,"4s",fn,4s) -+#define machine_fs_initcall(mach,fn) __define_machine_initcall(mach,"5",fn,5) -+#define machine_fs_initcall_sync(mach,fn) __define_machine_initcall(mach,"5s",fn,5s) -+#define machine_rootfs_initcall(mach,fn) __define_machine_initcall(mach,"rootfs",fn,rootfs) -+#define machine_device_initcall(mach,fn) __define_machine_initcall(mach,"6",fn,6) -+#define machine_device_initcall_sync(mach,fn) __define_machine_initcall(mach,"6s",fn,6s) -+#define machine_late_initcall(mach,fn) __define_machine_initcall(mach,"7",fn,7) -+#define machine_late_initcall_sync(mach,fn) __define_machine_initcall(mach,"7s",fn,7s) -+ -+void generic_suspend_disable_irqs(void); -+void generic_suspend_enable_irqs(void); -+ - #endif /* __KERNEL__ */ - #endif /* _ASM_POWERPC_MACHDEP_H */ ---- a/include/asm-powerpc/mmu-hash64.h -+++ b/include/asm-powerpc/mmu-hash64.h -@@ -80,7 +80,7 @@ extern char initial_stab[]; - #define HPTE_V_AVPN_SHIFT 7 - #define HPTE_V_AVPN ASM_CONST(0x3fffffffffffff80) - #define HPTE_V_AVPN_VAL(x) (((x) & HPTE_V_AVPN) >> HPTE_V_AVPN_SHIFT) --#define HPTE_V_COMPARE(x,y) (!(((x) ^ (y)) & 0xffffffffffffff80)) -+#define HPTE_V_COMPARE(x,y) (!(((x) ^ (y)) & 0xffffffffffffff80UL)) - #define HPTE_V_BOLTED ASM_CONST(0x0000000000000010) - #define HPTE_V_LOCK ASM_CONST(0x0000000000000008) - #define HPTE_V_LARGE ASM_CONST(0x0000000000000004) -@@ -180,6 +180,7 @@ extern int mmu_vmalloc_psize; - extern int mmu_io_psize; - extern int mmu_kernel_ssize; - extern int mmu_highuser_ssize; -+extern u16 mmu_slb_size; - - /* - * If the processor supports 64k normal pages but not 64k cache -@@ -277,6 +278,7 @@ extern int hash_huge_page(struct mm_stru - extern int htab_bolt_mapping(unsigned long vstart, unsigned long vend, - unsigned long pstart, unsigned long mode, - int psize, int ssize); -+extern void set_huge_psize(int psize); - - extern void htab_initialize(void); - extern void htab_initialize_secondary(void); ---- a/include/asm-powerpc/mpc52xx.h -+++ b/include/asm-powerpc/mpc52xx.h -@@ -248,8 +248,6 @@ struct mpc52xx_cdm { - - #ifndef __ASSEMBLY__ - --extern void __iomem * mpc52xx_find_and_map(const char *); --extern void __iomem * mpc52xx_find_and_map_path(const char *path); - extern unsigned int mpc52xx_find_ipb_freq(struct device_node *node); - extern void mpc5200_setup_xlb_arbiter(void); - extern void mpc52xx_declare_of_platform_devices(void); -@@ -257,7 +255,12 @@ extern void mpc52xx_declare_of_platform_ - extern void mpc52xx_init_irq(void); - extern unsigned int mpc52xx_get_irq(void); - -+#ifdef CONFIG_PCI - extern int __init mpc52xx_add_bridge(struct device_node *node); -+extern void __init mpc52xx_setup_pci(void); -+#else -+static inline void mpc52xx_setup_pci(void) { } -+#endif - - extern void __init mpc52xx_map_wdt(void); - extern void mpc52xx_restart(char *cmd); ---- a/include/asm-powerpc/mpc52xx_psc.h -+++ b/include/asm-powerpc/mpc52xx_psc.h -@@ -153,6 +153,9 @@ struct mpc52xx_psc { - u8 reserved16[3]; - u8 irfdr; /* PSC + 0x54 */ - u8 reserved17[3]; -+}; -+ -+struct mpc52xx_psc_fifo { - u16 rfnum; /* PSC + 0x58 */ - u16 reserved18; - u16 tfnum; /* PSC + 0x5c */ ---- a/include/asm-powerpc/mpc8260.h -+++ b/include/asm-powerpc/mpc8260.h -@@ -8,6 +8,7 @@ - #ifndef __ASM_POWERPC_MPC8260_H__ - #define __ASM_POWERPC_MPC8260_H__ - -+#define MPC82XX_BCR_PLDP 0x00800000 /* Pipeline Maximum Depth */ - - #ifdef CONFIG_8260 - ---- a/include/asm-powerpc/mpic.h -+++ b/include/asm-powerpc/mpic.h -@@ -22,7 +22,9 @@ - #define MPIC_GREG_GLOBAL_CONF_0 0x00020 - #define MPIC_GREG_GCONF_RESET 0x80000000 - #define MPIC_GREG_GCONF_8259_PTHROU_DIS 0x20000000 -+#define MPIC_GREG_GCONF_NO_BIAS 0x10000000 - #define MPIC_GREG_GCONF_BASE_MASK 0x000fffff -+#define MPIC_GREG_GCONF_MCK 0x08000000 - #define MPIC_GREG_GLOBAL_CONF_1 0x00030 - #define MPIC_GREG_GLOBAL_CONF_1_SIE 0x08000000 - #define MPIC_GREG_GLOBAL_CONF_1_CLK_RATIO_MASK 0x70000000 -@@ -78,6 +80,7 @@ - #define MPIC_CPU_WHOAMI_MASK 0x0000001f - #define MPIC_CPU_INTACK 0x000a0 - #define MPIC_CPU_EOI 0x000b0 -+#define MPIC_CPU_MCACK 0x000c0 - - /* - * Per-source registers -@@ -141,6 +144,7 @@ - #define TSI108_CPU_WHOAMI 0xffffffff - #define TSI108_CPU_INTACK 0x00004 - #define TSI108_CPU_EOI 0x00008 -+#define TSI108_CPU_MCACK 0x00004 /* Doesn't really exist here */ - - /* - * Per-source registers -@@ -183,6 +187,7 @@ enum { - MPIC_IDX_CPU_WHOAMI, - MPIC_IDX_CPU_INTACK, - MPIC_IDX_CPU_EOI, -+ MPIC_IDX_CPU_MCACK, - - MPIC_IDX_IRQ_BASE, - MPIC_IDX_IRQ_STRIDE, -@@ -344,6 +349,10 @@ struct mpic - #define MPIC_USES_DCR 0x00000080 - /* MPIC has 11-bit vector fields (or larger) */ - #define MPIC_LARGE_VECTORS 0x00000100 -+/* Enable delivery of prio 15 interrupts as MCK instead of EE */ -+#define MPIC_ENABLE_MCK 0x00000200 -+/* Disable bias among target selection, spread interrupts evenly */ -+#define MPIC_NO_BIAS 0x00000400 - - /* MPIC HW modification ID */ - #define MPIC_REGSET_MASK 0xf0000000 -@@ -447,10 +456,19 @@ extern void mpic_send_ipi(unsigned int i - /* Send a message (IPI) to a given target (cpu number or MSG_*) */ - void smp_mpic_message_pass(int target, int msg); - -+/* Unmask a specific virq */ -+extern void mpic_unmask_irq(unsigned int irq); -+/* Mask a specific virq */ -+extern void mpic_mask_irq(unsigned int irq); -+/* EOI a specific virq */ -+extern void mpic_end_irq(unsigned int irq); -+ - /* Fetch interrupt from a given mpic */ - extern unsigned int mpic_get_one_irq(struct mpic *mpic); --/* This one gets to the primary mpic */ -+/* This one gets from the primary mpic */ - extern unsigned int mpic_get_irq(void); -+/* Fetch Machine Check interrupt from primary mpic */ -+extern unsigned int mpic_get_mcirq(void); - - /* Set the EPIC clock ratio */ - void mpic_set_clk_ratio(struct mpic *mpic, u32 clock_ratio); ---- a/include/asm-powerpc/nvram.h -+++ b/include/asm-powerpc/nvram.h -@@ -10,6 +10,8 @@ - #ifndef _ASM_POWERPC_NVRAM_H - #define _ASM_POWERPC_NVRAM_H - -+#include -+ - #define NVRW_CNT 0x20 - #define NVRAM_HEADER_LEN 16 /* sizeof(struct nvram_header) */ - #define NVRAM_BLOCK_LEN 16 -@@ -71,7 +73,16 @@ extern int nvram_clear_error_log(void); - extern struct nvram_partition *nvram_find_partition(int sig, const char *name); - - extern int pSeries_nvram_init(void); -+ -+#ifdef CONFIG_MMIO_NVRAM - extern int mmio_nvram_init(void); -+#else -+static inline int mmio_nvram_init(void) -+{ -+ return -ENODEV; -+} -+#endif -+ - #endif /* __KERNEL__ */ - - /* PowerMac specific nvram stuffs */ ---- a/include/asm-powerpc/of_platform.h -+++ b/include/asm-powerpc/of_platform.h -@@ -15,8 +15,14 @@ - #include - - /* Platform drivers register/unregister */ --extern int of_register_platform_driver(struct of_platform_driver *drv); --extern void of_unregister_platform_driver(struct of_platform_driver *drv); -+static inline int of_register_platform_driver(struct of_platform_driver *drv) -+{ -+ return of_register_driver(drv, &of_platform_bus_type); -+} -+static inline void of_unregister_platform_driver(struct of_platform_driver *drv) -+{ -+ of_unregister_driver(drv); -+} - - /* Platform devices and busses creation */ - extern struct of_device *of_platform_device_create(struct device_node *np, -@@ -26,9 +32,11 @@ extern struct of_device *of_platform_dev - #define OF_NO_DEEP_PROBE ((struct of_device_id *)-1) - - extern int of_platform_bus_probe(struct device_node *root, -- struct of_device_id *matches, -+ const struct of_device_id *matches, - struct device *parent); - - extern struct of_device *of_find_device_by_phandle(phandle ph); - -+extern void of_instantiate_rtc(void); -+ - #endif /* _ASM_POWERPC_OF_PLATFORM_H */ ---- a/include/asm-powerpc/pci-bridge.h -+++ b/include/asm-powerpc/pci-bridge.h -@@ -1,15 +1,42 @@ - #ifndef _ASM_POWERPC_PCI_BRIDGE_H - #define _ASM_POWERPC_PCI_BRIDGE_H - #ifdef __KERNEL__ -- -+/* -+ * 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 - --#ifndef CONFIG_PPC64 -- - struct device_node; --struct pci_controller; -+ -+extern unsigned int ppc_pci_flags; -+enum { -+ /* Force re-assigning all resources (ignore firmware -+ * setup completely) -+ */ -+ PPC_PCI_REASSIGN_ALL_RSRC = 0x00000001, -+ -+ /* Re-assign all bus numbers */ -+ PPC_PCI_REASSIGN_ALL_BUS = 0x00000002, -+ -+ /* Do not try to assign, just use existing setup */ -+ PPC_PCI_PROBE_ONLY = 0x00000004, -+ -+ /* Don't bother with ISA alignment unless the bridge has -+ * ISA forwarding enabled -+ */ -+ PPC_PCI_CAN_SKIP_ISA_ALIGN = 0x00000008, -+ -+ /* Enable domain numbers in /proc */ -+ PPC_PCI_ENABLE_PROC_DOMAINS = 0x00000010, -+ /* ... except for domain 0 */ -+ PPC_PCI_COMPAT_DOMAIN_0 = 0x00000020, -+}; -+ - - /* - * Structure of a PCI controller (host bridge) -@@ -17,26 +44,41 @@ struct pci_controller; - struct pci_controller { - struct pci_bus *bus; - char is_dynamic; -- void *arch_data; -+#ifdef CONFIG_PPC64 -+ int node; -+#endif -+ struct device_node *dn; - struct list_head list_node; - struct device *parent; - - int first_busno; - int last_busno; -+#ifndef CONFIG_PPC64 - int self_busno; -+#endif - - void __iomem *io_base_virt; -+#ifdef CONFIG_PPC64 -+ void *io_base_alloc; -+#endif - resource_size_t io_base_phys; -+#ifndef CONFIG_PPC64 -+ resource_size_t pci_io_size; -+#endif - - /* Some machines (PReP) have a non 1:1 mapping of - * the PCI memory space in the CPU bus space - */ - resource_size_t pci_mem_offset; -+#ifdef CONFIG_PPC64 -+ unsigned long pci_io_size; -+#endif - - struct pci_ops *ops; -- volatile unsigned int __iomem *cfg_addr; -- volatile void __iomem *cfg_data; -+ unsigned int __iomem *cfg_addr; -+ void __iomem *cfg_data; - -+#ifndef CONFIG_PPC64 - /* - * Used for variants of PCI indirect handling and possible quirks: - * SET_CFG_TYPE - used on 4xx or any PHB that does explicit type0/1 -@@ -51,21 +93,30 @@ struct pci_controller { - * set. - * BIG_ENDIAN - cfg_addr is a big endian register - */ --#define PPC_INDIRECT_TYPE_SET_CFG_TYPE (0x00000001) --#define PPC_INDIRECT_TYPE_EXT_REG (0x00000002) --#define PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS (0x00000004) --#define PPC_INDIRECT_TYPE_NO_PCIE_LINK (0x00000008) --#define PPC_INDIRECT_TYPE_BIG_ENDIAN (0x00000010) -+#define PPC_INDIRECT_TYPE_SET_CFG_TYPE 0x00000001 -+#define PPC_INDIRECT_TYPE_EXT_REG 0x00000002 -+#define PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS 0x00000004 -+#define PPC_INDIRECT_TYPE_NO_PCIE_LINK 0x00000008 -+#define PPC_INDIRECT_TYPE_BIG_ENDIAN 0x00000010 - u32 indirect_type; -- -+#endif /* !CONFIG_PPC64 */ - /* Currently, we limit ourselves to 1 IO range and 3 mem - * ranges since the common pci_bus structure can't handle more - */ - struct resource io_resource; - struct resource mem_resources[3]; - int global_number; /* PCI domain number */ -+#ifdef CONFIG_PPC64 -+ unsigned long buid; -+ unsigned long dma_window_base_cur; -+ unsigned long dma_window_size; -+ -+ void *private_data; -+#endif /* CONFIG_PPC64 */ - }; - -+#ifndef CONFIG_PPC64 -+ - static inline struct pci_controller *pci_bus_to_host(struct pci_bus *bus) - { - return bus->sysdata; -@@ -81,18 +132,18 @@ static inline int isa_vaddr_is_ioport(vo - - /* These are used for config access before all the PCI probing - has been done. */ --int early_read_config_byte(struct pci_controller *hose, int bus, int dev_fn, -- int where, u8 *val); --int early_read_config_word(struct pci_controller *hose, int bus, int dev_fn, -- int where, u16 *val); --int early_read_config_dword(struct pci_controller *hose, int bus, int dev_fn, -- int where, u32 *val); --int early_write_config_byte(struct pci_controller *hose, int bus, int dev_fn, -- int where, u8 val); --int early_write_config_word(struct pci_controller *hose, int bus, int dev_fn, -- int where, u16 val); --int early_write_config_dword(struct pci_controller *hose, int bus, int dev_fn, -- int where, u32 val); -+extern int early_read_config_byte(struct pci_controller *hose, int bus, -+ int dev_fn, int where, u8 *val); -+extern int early_read_config_word(struct pci_controller *hose, int bus, -+ int dev_fn, int where, u16 *val); -+extern int early_read_config_dword(struct pci_controller *hose, int bus, -+ int dev_fn, int where, u32 *val); -+extern int early_write_config_byte(struct pci_controller *hose, int bus, -+ int dev_fn, int where, u8 val); -+extern int early_write_config_word(struct pci_controller *hose, int bus, -+ int dev_fn, int where, u16 val); -+extern int early_write_config_dword(struct pci_controller *hose, int bus, -+ int dev_fn, int where, u32 val); - - extern int early_find_capability(struct pci_controller *hose, int bus, - int dev_fn, int cap); -@@ -101,87 +152,33 @@ extern void setup_indirect_pci(struct pc - resource_size_t cfg_addr, - resource_size_t cfg_data, u32 flags); - extern void setup_grackle(struct pci_controller *hose); --extern void __init update_bridge_resource(struct pci_dev *dev, -- struct resource *res); -- --#else -- -- --/* -- * 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. -- */ -- --/* -- * Structure of a PCI controller (host bridge) -- */ --struct pci_controller { -- struct pci_bus *bus; -- char is_dynamic; -- int node; -- void *arch_data; -- struct list_head list_node; -- struct device *parent; -- -- int first_busno; -- int last_busno; -- -- void __iomem *io_base_virt; -- void *io_base_alloc; -- resource_size_t io_base_phys; -- -- /* Some machines have a non 1:1 mapping of -- * the PCI memory space in the CPU bus space -- */ -- resource_size_t pci_mem_offset; -- unsigned long pci_io_size; -- -- struct pci_ops *ops; -- volatile unsigned int __iomem *cfg_addr; -- volatile void __iomem *cfg_data; -- -- /* Currently, we limit ourselves to 1 IO range and 3 mem -- * ranges since the common pci_bus structure can't handle more -- */ -- struct resource io_resource; -- struct resource mem_resources[3]; -- int global_number; -- unsigned long buid; -- unsigned long dma_window_base_cur; -- unsigned long dma_window_size; -- -- void *private_data; --}; -+#else /* CONFIG_PPC64 */ - - /* - * PCI stuff, for nodes representing PCI devices, pointed to - * by device_node->data. - */ --struct pci_controller; - struct iommu_table; - - struct pci_dn { - int busno; /* pci bus number */ -- int bussubno; /* pci subordinate bus number */ - int devfn; /* pci device and function number */ -- int class_code; /* pci device class */ - - struct pci_controller *phb; /* for pci devices */ - struct iommu_table *iommu_table; /* for phb's or bridges */ -- struct pci_dev *pcidev; /* back-pointer to the pci device */ - struct device_node *node; /* back-pointer to the device_node */ - - int pci_ext_config_space; /* for pci devices */ - - #ifdef CONFIG_EEH -+ struct pci_dev *pcidev; /* back-pointer to the pci device */ -+ int class_code; /* pci device class */ - int eeh_mode; /* See eeh.h for possible EEH_MODEs */ - int eeh_config_addr; - int eeh_pe_config_addr; /* new-style partition endpoint address */ -- int eeh_check_count; /* # times driver ignored error */ -- int eeh_freeze_count; /* # times this device froze up. */ -- int eeh_false_positives; /* # times this device reported #ff's */ -+ int eeh_check_count; /* # times driver ignored error */ -+ int eeh_freeze_count; /* # times this device froze up. */ -+ int eeh_false_positives; /* # times this device reported #ff's */ - u32 config_space[16]; /* saved PCI config space */ - #endif - }; -@@ -189,7 +186,7 @@ struct pci_dn { - /* Get the pointer to a device_node's pci_dn */ - #define PCI_DN(dn) ((struct pci_dn *) (dn)->data) - --struct device_node *fetch_dev_dn(struct pci_dev *dev); -+extern struct device_node *fetch_dev_dn(struct pci_dev *dev); - - /* Get a device_node from a pci_dev. This code must be fast except - * in the case where the sysdata is incorrect and needs to be fixed -@@ -227,14 +224,14 @@ static inline struct device_node *pci_bu - } - - /** Find the bus corresponding to the indicated device node */ --struct pci_bus * pcibios_find_pci_bus(struct device_node *dn); -+extern struct pci_bus *pcibios_find_pci_bus(struct device_node *dn); - - /** Remove all of the PCI devices under this bus */ --void pcibios_remove_pci_devices(struct pci_bus *bus); -+extern void pcibios_remove_pci_devices(struct pci_bus *bus); - - /** Discover new pci devices under this bus, and add them */ --void pcibios_add_pci_devices(struct pci_bus * bus); --void pcibios_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus); -+extern void pcibios_add_pci_devices(struct pci_bus *bus); -+extern void pcibios_fixup_new_pci_devices(struct pci_bus *bus); - - extern int pcibios_remove_root_bus(struct pci_controller *phb); - -@@ -270,20 +267,18 @@ extern int pcibios_map_io_space(struct p - #define PHB_SET_NODE(PHB, NODE) ((PHB)->node = -1) - #endif - --#endif /* CONFIG_PPC64 */ -+#endif /* CONFIG_PPC64 */ - - /* Get the PCI host controller for an OF device */ --extern struct pci_controller* --pci_find_hose_for_OF_device(struct device_node* node); -+extern struct pci_controller *pci_find_hose_for_OF_device( -+ struct device_node* node); - - /* Fill up host controller resources from the OF node */ --extern void --pci_process_bridge_OF_ranges(struct pci_controller *hose, -- struct device_node *dev, int primary); -+extern void pci_process_bridge_OF_ranges(struct pci_controller *hose, -+ struct device_node *dev, int primary); - - /* Allocate & free a PCI host bridge structure */ --extern struct pci_controller * --pcibios_alloc_controller(struct device_node *dev); -+extern struct pci_controller *pcibios_alloc_controller(struct device_node *dev); - extern void pcibios_free_controller(struct pci_controller *phb); - - #ifdef CONFIG_PCI -@@ -298,9 +293,7 @@ static inline int pcibios_vaddr_is_iopor - { - return 0; - } --#endif -- -+#endif /* CONFIG_PCI */ - -- --#endif /* __KERNEL__ */ --#endif -+#endif /* __KERNEL__ */ -+#endif /* _ASM_POWERPC_PCI_BRIDGE_H */ ---- a/include/asm-powerpc/pci.h -+++ b/include/asm-powerpc/pci.h -@@ -36,11 +36,10 @@ struct pci_dev; - - /* - * Set this to 1 if you want the kernel to re-assign all PCI -- * bus numbers -+ * bus numbers (don't do that on ppc64 yet !) - */ --extern int pci_assign_all_buses; --#define pcibios_assign_all_busses() (pci_assign_all_buses) -- -+#define pcibios_assign_all_busses() (ppc_pci_flags & \ -+ PPC_PCI_REASSIGN_ALL_BUS) - #define pcibios_scan_all_fns(a, b) 0 - - static inline void pcibios_set_master(struct pci_dev *dev) -@@ -95,9 +94,6 @@ static inline void pci_dma_burst_advice( - #define get_pci_dma_ops() NULL - #endif - --/* Decide whether to display the domain number in /proc */ --extern int pci_proc_domain(struct pci_bus *bus); -- - #else /* 32-bit */ - - #ifdef CONFIG_PCI -@@ -109,17 +105,14 @@ static inline void pci_dma_burst_advice( - *strategy_parameter = ~0UL; - } - #endif -- --/* Set the name of the bus as it appears in /proc/bus/pci */ --static inline int pci_proc_domain(struct pci_bus *bus) --{ -- return 0; --} -- - #endif /* CONFIG_PPC64 */ - - extern int pci_domain_nr(struct pci_bus *bus); - -+/* Decide whether to display the domain number in /proc */ -+extern int pci_proc_domain(struct pci_bus *bus); -+ -+ - struct vm_area_struct; - /* Map a range of PCI memory or I/O space for a device into user space */ - int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma, -@@ -199,13 +192,12 @@ static inline struct resource *pcibios_s - return root; - } - --extern void pcibios_fixup_device_resources(struct pci_dev *dev, -- struct pci_bus *bus); -- - extern void pcibios_setup_new_device(struct pci_dev *dev); - - extern void pcibios_claim_one_bus(struct pci_bus *b); - -+extern void pcibios_resource_survey(void); -+ - extern struct pci_controller *init_phb_dynamic(struct device_node *dn); - - extern struct pci_dev *of_create_pci_dev(struct device_node *node, -@@ -229,5 +221,8 @@ extern void pci_resource_to_user(const s - const struct resource *rsrc, - resource_size_t *start, resource_size_t *end); - -+extern void pcibios_do_bus_setup(struct pci_bus *bus); -+extern void pcibios_fixup_of_probed_bus(struct pci_bus *bus); -+ - #endif /* __KERNEL__ */ - #endif /* __ASM_POWERPC_PCI_H */ ---- a/include/asm-powerpc/ppc-pci.h -+++ b/include/asm-powerpc/ppc-pci.h -@@ -22,7 +22,6 @@ extern void pci_setup_phb_io_dynamic(str - - - extern struct list_head hose_list; --extern int global_phb_number; - - extern void find_and_init_phbs(void); - -@@ -47,9 +46,6 @@ extern void init_pci_config_tokens (void - extern unsigned long get_phb_buid (struct device_node *); - extern int rtas_setup_phb(struct pci_controller *phb); - --/* From iSeries PCI */ --extern void iSeries_pcibios_init(void); -- - extern unsigned long pci_probe_only; - - /* ---- EEH internal-use-only related routines ---- */ ---- a/include/asm-powerpc/prom.h -+++ b/include/asm-powerpc/prom.h -@@ -202,6 +202,10 @@ static inline unsigned long of_read_ulon - */ - extern u64 of_translate_address(struct device_node *np, const u32 *addr); - -+/* Translate a DMA address from device space to CPU space */ -+extern u64 of_translate_dma_address(struct device_node *dev, -+ const u32 *in_addr); -+ - /* Extract an address from a device, returns the region size and - * the address space flags too. The PCI version uses a BAR number - * instead of an absolute index ---- a/include/asm-powerpc/ps3.h -+++ b/include/asm-powerpc/ps3.h -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include "cell-pmu.h" - - union ps3_firmware_version { - u64 raw; -@@ -317,6 +318,7 @@ enum ps3_match_id { - PS3_MATCH_ID_STOR_FLASH = 8, - PS3_MATCH_ID_SOUND = 9, - PS3_MATCH_ID_GRAPHICS = 10, -+ PS3_MATCH_ID_LPM = 11, - }; - - #define PS3_MODULE_ALIAS_EHCI "ps3:1" -@@ -329,11 +331,13 @@ enum ps3_match_id { - #define PS3_MODULE_ALIAS_STOR_FLASH "ps3:8" - #define PS3_MODULE_ALIAS_SOUND "ps3:9" - #define PS3_MODULE_ALIAS_GRAPHICS "ps3:10" -+#define PS3_MODULE_ALIAS_LPM "ps3:11" - - enum ps3_system_bus_device_type { - PS3_DEVICE_TYPE_IOC0 = 1, - PS3_DEVICE_TYPE_SB, - PS3_DEVICE_TYPE_VUART, -+ PS3_DEVICE_TYPE_LPM, - }; - - /** -@@ -344,12 +348,17 @@ struct ps3_system_bus_device { - enum ps3_match_id match_id; - enum ps3_system_bus_device_type dev_type; - -- unsigned int bus_id; /* SB */ -- unsigned int dev_id; /* SB */ -+ u64 bus_id; /* SB */ -+ u64 dev_id; /* SB */ - unsigned int interrupt_id; /* SB */ - struct ps3_dma_region *d_region; /* SB, IOC0 */ - struct ps3_mmio_region *m_region; /* SB, IOC0*/ - unsigned int port_number; /* VUART */ -+ struct { /* LPM */ -+ u64 node_id; -+ u64 pu_id; -+ u64 rights; -+ } lpm; - - /* struct iommu_table *iommu_table; -- waiting for BenH's cleanups */ - struct device core; -@@ -438,5 +447,66 @@ struct ps3_prealloc { - extern struct ps3_prealloc ps3fb_videomemory; - extern struct ps3_prealloc ps3flash_bounce_buffer; - -+/* logical performance monitor */ -+ -+/** -+ * enum ps3_lpm_rights - Rigths granted by the system policy module. -+ * -+ * @PS3_LPM_RIGHTS_USE_LPM: The right to use the lpm. -+ * @PS3_LPM_RIGHTS_USE_TB: The right to use the internal trace buffer. -+ */ -+ -+enum ps3_lpm_rights { -+ PS3_LPM_RIGHTS_USE_LPM = 0x001, -+ PS3_LPM_RIGHTS_USE_TB = 0x100, -+}; -+ -+/** -+ * enum ps3_lpm_tb_type - Type of trace buffer lv1 should use. -+ * -+ * @PS3_LPM_TB_TYPE_NONE: Do not use a trace buffer. -+ * @PS3_LPM_RIGHTS_USE_TB: Use the lv1 internal trace buffer. Must have -+ * rights @PS3_LPM_RIGHTS_USE_TB. -+ */ -+ -+enum ps3_lpm_tb_type { -+ PS3_LPM_TB_TYPE_NONE = 0, -+ PS3_LPM_TB_TYPE_INTERNAL = 1, -+}; -+ -+int ps3_lpm_open(enum ps3_lpm_tb_type tb_type, void *tb_cache, -+ u64 tb_cache_size); -+int ps3_lpm_close(void); -+int ps3_lpm_copy_tb(unsigned long offset, void *buf, unsigned long count, -+ unsigned long *bytes_copied); -+int ps3_lpm_copy_tb_to_user(unsigned long offset, void __user *buf, -+ unsigned long count, unsigned long *bytes_copied); -+void ps3_set_bookmark(u64 bookmark); -+void ps3_set_pm_bookmark(u64 tag, u64 incident, u64 th_id); -+int ps3_set_signal(u64 rtas_signal_group, u8 signal_bit, u16 sub_unit, -+ u8 bus_word); -+ -+u32 ps3_read_phys_ctr(u32 cpu, u32 phys_ctr); -+void ps3_write_phys_ctr(u32 cpu, u32 phys_ctr, u32 val); -+u32 ps3_read_ctr(u32 cpu, u32 ctr); -+void ps3_write_ctr(u32 cpu, u32 ctr, u32 val); -+ -+u32 ps3_read_pm07_control(u32 cpu, u32 ctr); -+void ps3_write_pm07_control(u32 cpu, u32 ctr, u32 val); -+u32 ps3_read_pm(u32 cpu, enum pm_reg_name reg); -+void ps3_write_pm(u32 cpu, enum pm_reg_name reg, u32 val); -+ -+u32 ps3_get_ctr_size(u32 cpu, u32 phys_ctr); -+void ps3_set_ctr_size(u32 cpu, u32 phys_ctr, u32 ctr_size); -+ -+void ps3_enable_pm(u32 cpu); -+void ps3_disable_pm(u32 cpu); -+void ps3_enable_pm_interrupts(u32 cpu, u32 thread, u32 mask); -+void ps3_disable_pm_interrupts(u32 cpu); -+ -+u32 ps3_get_and_clear_pm_interrupts(u32 cpu); -+void ps3_sync_irq(int node); -+u32 ps3_get_hw_thread_id(int cpu); -+u64 ps3_get_spe_id(void *arg); - - #endif ---- a/include/asm-powerpc/ptrace.h -+++ b/include/asm-powerpc/ptrace.h -@@ -106,7 +106,8 @@ extern int ptrace_put_reg(struct task_st - */ - #define FULL_REGS(regs) (((regs)->trap & 1) == 0) - #ifndef __powerpc64__ --#define IS_CRITICAL_EXC(regs) (((regs)->trap & 2) == 0) -+#define IS_CRITICAL_EXC(regs) (((regs)->trap & 2) != 0) -+#define IS_MCHECK_EXC(regs) (((regs)->trap & 4) != 0) - #endif /* ! __powerpc64__ */ - #define TRAP(regs) ((regs)->trap & ~0xF) - #ifdef __powerpc64__ ---- a/include/asm-powerpc/qe.h -+++ b/include/asm-powerpc/qe.h -@@ -28,6 +28,52 @@ - #define MEM_PART_SECONDARY 1 - #define MEM_PART_MURAM 2 - -+/* Clocks and BRGs */ -+enum qe_clock { -+ QE_CLK_NONE = 0, -+ QE_BRG1, /* Baud Rate Generator 1 */ -+ QE_BRG2, /* Baud Rate Generator 2 */ -+ QE_BRG3, /* Baud Rate Generator 3 */ -+ QE_BRG4, /* Baud Rate Generator 4 */ -+ QE_BRG5, /* Baud Rate Generator 5 */ -+ QE_BRG6, /* Baud Rate Generator 6 */ -+ QE_BRG7, /* Baud Rate Generator 7 */ -+ QE_BRG8, /* Baud Rate Generator 8 */ -+ QE_BRG9, /* Baud Rate Generator 9 */ -+ QE_BRG10, /* Baud Rate Generator 10 */ -+ QE_BRG11, /* Baud Rate Generator 11 */ -+ QE_BRG12, /* Baud Rate Generator 12 */ -+ QE_BRG13, /* Baud Rate Generator 13 */ -+ QE_BRG14, /* Baud Rate Generator 14 */ -+ QE_BRG15, /* Baud Rate Generator 15 */ -+ QE_BRG16, /* Baud Rate Generator 16 */ -+ QE_CLK1, /* Clock 1 */ -+ QE_CLK2, /* Clock 2 */ -+ QE_CLK3, /* Clock 3 */ -+ QE_CLK4, /* Clock 4 */ -+ QE_CLK5, /* Clock 5 */ -+ QE_CLK6, /* Clock 6 */ -+ QE_CLK7, /* Clock 7 */ -+ QE_CLK8, /* Clock 8 */ -+ QE_CLK9, /* Clock 9 */ -+ QE_CLK10, /* Clock 10 */ -+ QE_CLK11, /* Clock 11 */ -+ QE_CLK12, /* Clock 12 */ -+ QE_CLK13, /* Clock 13 */ -+ QE_CLK14, /* Clock 14 */ -+ QE_CLK15, /* Clock 15 */ -+ QE_CLK16, /* Clock 16 */ -+ QE_CLK17, /* Clock 17 */ -+ QE_CLK18, /* Clock 18 */ -+ QE_CLK19, /* Clock 19 */ -+ QE_CLK20, /* Clock 20 */ -+ QE_CLK21, /* Clock 21 */ -+ QE_CLK22, /* Clock 22 */ -+ QE_CLK23, /* Clock 23 */ -+ QE_CLK24, /* Clock 24 */ -+ QE_CLK_DUMMY -+}; -+ - /* Export QE common operations */ - extern void qe_reset(void); - extern int par_io_init(struct device_node *np); -@@ -38,7 +84,8 @@ extern int par_io_data_set(u8 port, u8 p - - /* QE internal API */ - int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol, u32 cmd_input); --void qe_setbrg(unsigned int brg, unsigned int rate, unsigned int multiplier); -+enum qe_clock qe_clock_source(const char *source); -+int qe_setbrg(enum qe_clock brg, unsigned int rate, unsigned int multiplier); - int qe_get_snum(void); - void qe_put_snum(u8 snum); - unsigned long qe_muram_alloc(int size, int align); -@@ -47,6 +94,58 @@ unsigned long qe_muram_alloc_fixed(unsig - void qe_muram_dump(void); - void *qe_muram_addr(unsigned long offset); - -+/* Structure that defines QE firmware binary files. -+ * -+ * See Documentation/powerpc/qe-firmware.txt for a description of these -+ * fields. -+ */ -+struct qe_firmware { -+ struct qe_header { -+ __be32 length; /* Length of the entire structure, in bytes */ -+ u8 magic[3]; /* Set to { 'Q', 'E', 'F' } */ -+ u8 version; /* Version of this layout. First ver is '1' */ -+ } header; -+ u8 id[62]; /* Null-terminated identifier string */ -+ u8 split; /* 0 = shared I-RAM, 1 = split I-RAM */ -+ u8 count; /* Number of microcode[] structures */ -+ struct { -+ __be16 model; /* The SOC model */ -+ u8 major; /* The SOC revision major */ -+ u8 minor; /* The SOC revision minor */ -+ } __attribute__ ((packed)) soc; -+ u8 padding[4]; /* Reserved, for alignment */ -+ __be64 extended_modes; /* Extended modes */ -+ __be32 vtraps[8]; /* Virtual trap addresses */ -+ u8 reserved[4]; /* Reserved, for future expansion */ -+ struct qe_microcode { -+ u8 id[32]; /* Null-terminated identifier */ -+ __be32 traps[16]; /* Trap addresses, 0 == ignore */ -+ __be32 eccr; /* The value for the ECCR register */ -+ __be32 iram_offset; /* Offset into I-RAM for the code */ -+ __be32 count; /* Number of 32-bit words of the code */ -+ __be32 code_offset; /* Offset of the actual microcode */ -+ u8 major; /* The microcode version major */ -+ u8 minor; /* The microcode version minor */ -+ u8 revision; /* The microcode version revision */ -+ u8 padding; /* Reserved, for alignment */ -+ u8 reserved[4]; /* Reserved, for future expansion */ -+ } __attribute__ ((packed)) microcode[1]; -+ /* All microcode binaries should be located here */ -+ /* CRC32 should be located here, after the microcode binaries */ -+} __attribute__ ((packed)); -+ -+struct qe_firmware_info { -+ char id[64]; /* Firmware name */ -+ u32 vtraps[8]; /* Virtual trap addresses */ -+ u64 extended_modes; /* Extended modes */ -+}; -+ -+/* Upload a firmware to the QE */ -+int qe_upload_firmware(const struct qe_firmware *firmware); -+ -+/* Obtain information on the uploaded firmware */ -+struct qe_firmware_info *qe_get_firmware_info(void); -+ - /* Buffer descriptors */ - struct qe_bd { - __be16 status; -@@ -129,52 +228,6 @@ enum comm_dir { - COMM_DIR_RX_AND_TX = 3 - }; - --/* Clocks and BRGs */ --enum qe_clock { -- QE_CLK_NONE = 0, -- QE_BRG1, /* Baud Rate Generator 1 */ -- QE_BRG2, /* Baud Rate Generator 2 */ -- QE_BRG3, /* Baud Rate Generator 3 */ -- QE_BRG4, /* Baud Rate Generator 4 */ -- QE_BRG5, /* Baud Rate Generator 5 */ -- QE_BRG6, /* Baud Rate Generator 6 */ -- QE_BRG7, /* Baud Rate Generator 7 */ -- QE_BRG8, /* Baud Rate Generator 8 */ -- QE_BRG9, /* Baud Rate Generator 9 */ -- QE_BRG10, /* Baud Rate Generator 10 */ -- QE_BRG11, /* Baud Rate Generator 11 */ -- QE_BRG12, /* Baud Rate Generator 12 */ -- QE_BRG13, /* Baud Rate Generator 13 */ -- QE_BRG14, /* Baud Rate Generator 14 */ -- QE_BRG15, /* Baud Rate Generator 15 */ -- QE_BRG16, /* Baud Rate Generator 16 */ -- QE_CLK1, /* Clock 1 */ -- QE_CLK2, /* Clock 2 */ -- QE_CLK3, /* Clock 3 */ -- QE_CLK4, /* Clock 4 */ -- QE_CLK5, /* Clock 5 */ -- QE_CLK6, /* Clock 6 */ -- QE_CLK7, /* Clock 7 */ -- QE_CLK8, /* Clock 8 */ -- QE_CLK9, /* Clock 9 */ -- QE_CLK10, /* Clock 10 */ -- QE_CLK11, /* Clock 11 */ -- QE_CLK12, /* Clock 12 */ -- QE_CLK13, /* Clock 13 */ -- QE_CLK14, /* Clock 14 */ -- QE_CLK15, /* Clock 15 */ -- QE_CLK16, /* Clock 16 */ -- QE_CLK17, /* Clock 17 */ -- QE_CLK18, /* Clock 18 */ -- QE_CLK19, /* Clock 19 */ -- QE_CLK20, /* Clock 20 */ -- QE_CLK21, /* Clock 21 */ -- QE_CLK22, /* Clock 22 */ -- QE_CLK23, /* Clock 23 */ -- QE_CLK24, /* Clock 24 */ -- QE_CLK_DUMMY, --}; -- - /* QE CMXUCR Registers. - * There are two UCCs represented in each of the four CMXUCR registers. - * These values are for the UCC in the LSBs -@@ -328,6 +381,15 @@ enum qe_clock { - - #define QE_SDEBCR_BA_MASK 0x01FFFFFF - -+/* Communication Processor */ -+#define QE_CP_CERCR_MEE 0x8000 /* Multi-user RAM ECC enable */ -+#define QE_CP_CERCR_IEE 0x4000 /* Instruction RAM ECC enable */ -+#define QE_CP_CERCR_CIR 0x0800 /* Common instruction RAM */ -+ -+/* I-RAM */ -+#define QE_IRAM_IADD_AIE 0x80000000 /* Auto Increment Enable */ -+#define QE_IRAM_IADD_BADDR 0x00080000 /* Base Address */ -+ - /* UPC */ - #define UPGCR_PROTOCOL 0x80000000 /* protocol ul2 or pl2 */ - #define UPGCR_TMS 0x40000000 /* Transmit master/slave mode */ ---- a/include/asm-powerpc/reg.h -+++ b/include/asm-powerpc/reg.h -@@ -553,6 +553,7 @@ - #define SPRN_PA6T_BTCR 978 /* Breakpoint and Tagging Control Register */ - #define SPRN_PA6T_IMAAT 979 /* Instruction Match Array Action Table */ - #define SPRN_PA6T_PCCR 1019 /* Power Counter Control Register */ -+#define SPRN_BKMK 1020 /* Cell Bookmark Register */ - #define SPRN_PA6T_RPCCR 1021 /* Retire PC Trace Control Register */ - - -@@ -691,12 +692,6 @@ - #define PV_BE 0x0070 - #define PV_PA6T 0x0090 - --/* -- * Number of entries in the SLB. If this ever changes we should handle -- * it with a use a cpu feature fixup. -- */ --#define SLB_NUM_ENTRIES 64 -- - /* Macros for setting and retrieving special purpose registers */ - #ifndef __ASSEMBLY__ - #define mfmsr() ({unsigned long rval; \ ---- a/include/asm-powerpc/reg_booke.h -+++ b/include/asm-powerpc/reg_booke.h -@@ -123,16 +123,23 @@ - #define SPRN_SPEFSCR 0x200 /* SPE & Embedded FP Status & Control */ - #define SPRN_BBEAR 0x201 /* Branch Buffer Entry Address Register */ - #define SPRN_BBTAR 0x202 /* Branch Buffer Target Address Register */ -+#define SPRN_ATB 0x20E /* Alternate Time Base */ -+#define SPRN_ATBL 0x20E /* Alternate Time Base Lower */ -+#define SPRN_ATBU 0x20F /* Alternate Time Base Upper */ - #define SPRN_IVOR32 0x210 /* Interrupt Vector Offset Register 32 */ - #define SPRN_IVOR33 0x211 /* Interrupt Vector Offset Register 33 */ - #define SPRN_IVOR34 0x212 /* Interrupt Vector Offset Register 34 */ - #define SPRN_IVOR35 0x213 /* Interrupt Vector Offset Register 35 */ -+#define SPRN_IVOR36 0x214 /* Interrupt Vector Offset Register 36 */ -+#define SPRN_IVOR37 0x215 /* Interrupt Vector Offset Register 37 */ - #define SPRN_MCSRR0 0x23A /* Machine Check Save and Restore Register 0 */ - #define SPRN_MCSRR1 0x23B /* Machine Check Save and Restore Register 1 */ - #define SPRN_MCSR 0x23C /* Machine Check Status Register */ - #define SPRN_MCAR 0x23D /* Machine Check Address Register */ - #define SPRN_DSRR0 0x23E /* Debug Save and Restore Register 0 */ - #define SPRN_DSRR1 0x23F /* Debug Save and Restore Register 1 */ -+#define SPRN_SPRG8 0x25C /* Special Purpose Register General 8 */ -+#define SPRN_SPRG9 0x25D /* Special Purpose Register General 9 */ - #define SPRN_MAS0 0x270 /* MMU Assist Register 0 */ - #define SPRN_MAS1 0x271 /* MMU Assist Register 1 */ - #define SPRN_MAS2 0x272 /* MMU Assist Register 2 */ -@@ -140,15 +147,18 @@ - #define SPRN_MAS4 0x274 /* MMU Assist Register 4 */ - #define SPRN_MAS5 0x275 /* MMU Assist Register 5 */ - #define SPRN_MAS6 0x276 /* MMU Assist Register 6 */ --#define SPRN_MAS7 0x3b0 /* MMU Assist Register 7 */ - #define SPRN_PID1 0x279 /* Process ID Register 1 */ - #define SPRN_PID2 0x27A /* Process ID Register 2 */ - #define SPRN_TLB0CFG 0x2B0 /* TLB 0 Config Register */ - #define SPRN_TLB1CFG 0x2B1 /* TLB 1 Config Register */ -+#define SPRN_EPR 0x2BE /* External Proxy Register */ - #define SPRN_CCR1 0x378 /* Core Configuration Register 1 */ - #define SPRN_ZPR 0x3B0 /* Zone Protection Register (40x) */ -+#define SPRN_MAS7 0x3B0 /* MMU Assist Register 7 */ - #define SPRN_MMUCR 0x3B2 /* MMU Control Register */ - #define SPRN_CCR0 0x3B3 /* Core Configuration Register 0 */ -+#define SPRN_EPLC 0x3B3 /* External Process ID Load Context */ -+#define SPRN_EPSC 0x3B4 /* External Process ID Store Context */ - #define SPRN_SGR 0x3B9 /* Storage Guarded Register */ - #define SPRN_DCWR 0x3BA /* Data Cache Write-thru Register */ - #define SPRN_SLER 0x3BB /* Little-endian real mode */ -@@ -159,6 +169,7 @@ - #define SPRN_L1CSR0 0x3F2 /* L1 Cache Control and Status Register 0 */ - #define SPRN_L1CSR1 0x3F3 /* L1 Cache Control and Status Register 1 */ - #define SPRN_PIT 0x3DB /* Programmable Interval Timer */ -+#define SPRN_BUCSR 0x3F5 /* Branch Unit Control and Status */ - #define SPRN_DCCR 0x3FA /* Data Cache Cacheability Register */ - #define SPRN_ICCR 0x3FB /* Instruction Cache Cacheability Register */ - #define SPRN_SVR 0x3FF /* System Version Register */ -@@ -207,7 +218,6 @@ - #define CCR1_TCS 0x00000080 /* Timer Clock Select */ - - /* Bit definitions for the MCSR. */ --#ifdef CONFIG_440A - #define MCSR_MCS 0x80000000 /* Machine Check Summary */ - #define MCSR_IB 0x40000000 /* Instruction PLB Error */ - #define MCSR_DRB 0x20000000 /* Data Read PLB Error */ -@@ -217,7 +227,7 @@ - #define MCSR_DCSP 0x02000000 /* D-Cache Search Parity Error */ - #define MCSR_DCFP 0x01000000 /* D-Cache Flush Parity Error */ - #define MCSR_IMPE 0x00800000 /* Imprecise Machine Check Exception */ --#endif -+ - #ifdef CONFIG_E500 - #define MCSR_MCP 0x80000000UL /* Machine Check Input Pin */ - #define MCSR_ICPERR 0x40000000UL /* I-Cache Parity Error */ -@@ -293,7 +303,7 @@ - #define ESR_IMCB 0x20000000 /* Instr. Machine Check - Bus error */ - #define ESR_IMCT 0x10000000 /* Instr. Machine Check - Timeout */ - #define ESR_PIL 0x08000000 /* Program Exception - Illegal */ --#define ESR_PPR 0x04000000 /* Program Exception - Priveleged */ -+#define ESR_PPR 0x04000000 /* Program Exception - Privileged */ - #define ESR_PTR 0x02000000 /* Program Exception - Trap */ - #define ESR_FP 0x01000000 /* Floating Point Operation */ - #define ESR_DST 0x00800000 /* Storage Exception - Data miss */ ---- /dev/null -+++ b/include/asm-powerpc/setjmp.h -@@ -0,0 +1,18 @@ -+/* -+ * Copyright © 2008 Michael Neuling IBM Corporation -+ * -+ * 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 _ASM_POWERPC_SETJMP_H -+#define _ASM_POWERPC_SETJMP_H -+ -+#define JMP_BUF_LEN 23 -+ -+extern long setjmp(long *); -+extern void longjmp(long *, long); -+ -+#endif /* _ASM_POWERPC_SETJMP_H */ ---- a/include/asm-powerpc/smu.h -+++ b/include/asm-powerpc/smu.h -@@ -22,7 +22,7 @@ - * Partition info commands - * - * These commands are used to retrieve the sdb-partition-XX datas from -- * the SMU. The lenght is always 2. First byte is the subcommand code -+ * the SMU. The length is always 2. First byte is the subcommand code - * and second byte is the partition ID. - * - * The reply is 6 bytes: -@@ -173,12 +173,12 @@ - * Power supply control - * - * The "sub" command is an ASCII string in the data, the -- * data lenght is that of the string. -+ * data length is that of the string. - * - * The VSLEW command can be used to get or set the voltage slewing. -- * - lenght 5 (only "VSLEW") : it returns "DONE" and 3 bytes of -+ * - length 5 (only "VSLEW") : it returns "DONE" and 3 bytes of - * reply at data offset 6, 7 and 8. -- * - lenght 8 ("VSLEWxyz") has 3 additional bytes appended, and is -+ * - length 8 ("VSLEWxyz") has 3 additional bytes appended, and is - * used to set the voltage slewing point. The SMU replies with "DONE" - * I yet have to figure out their exact meaning of those 3 bytes in - * both cases. They seem to be: -@@ -201,20 +201,90 @@ - */ - #define SMU_CMD_READ_ADC 0xd8 - -+ - /* Misc commands - * - * This command seem to be a grab bag of various things -+ * -+ * Parameters: -+ * 1: subcommand - */ - #define SMU_CMD_MISC_df_COMMAND 0xdf --#define SMU_CMD_MISC_df_SET_DISPLAY_LIT 0x02 /* i: 1 byte */ -+ -+/* -+ * Sets "system ready" status -+ * -+ * I did not yet understand how it exactly works or what it does. -+ * -+ * Guessing from OF code, 0x02 activates the display backlight. Apple uses/used -+ * the same codebase for all OF versions. On PowerBooks, this command would -+ * enable the backlight. For the G5s, it only activates the front LED. However, -+ * don't take this for granted. -+ * -+ * Parameters: -+ * 2: status [0x00, 0x01 or 0x02] -+ */ -+#define SMU_CMD_MISC_df_SET_DISPLAY_LIT 0x02 -+ -+/* -+ * Sets mode of power switch. -+ * -+ * What this actually does is not yet known. Maybe it enables some interrupt. -+ * -+ * Parameters: -+ * 2: enable power switch? [0x00 or 0x01] -+ * 3 (optional): enable nmi? [0x00 or 0x01] -+ * -+ * Returns: -+ * If parameter 2 is 0x00 and parameter 3 is not specified, returns wether -+ * NMI is enabled. Otherwise unknown. -+ */ - #define SMU_CMD_MISC_df_NMI_OPTION 0x04 - -+/* Sets LED dimm offset. -+ * -+ * The front LED dimms itself during sleep. Its brightness (or, well, the PWM -+ * frequency) depends on current time. Therefore, the SMU needs to know the -+ * timezone. -+ * -+ * Parameters: -+ * 2-8: unknown (BCD coding) -+ */ -+#define SMU_CMD_MISC_df_DIMM_OFFSET 0x99 -+ -+ - /* - * Version info commands - * -- * I haven't quite tried to figure out how these work -+ * Parameters: -+ * 1 (optional): Specifies version part to retrieve -+ * -+ * Returns: -+ * Version value - */ - #define SMU_CMD_VERSION_COMMAND 0xea -+#define SMU_VERSION_RUNNING 0x00 -+#define SMU_VERSION_BASE 0x01 -+#define SMU_VERSION_UPDATE 0x02 -+ -+ -+/* -+ * Switches -+ * -+ * These are switches whose status seems to be known to the SMU. -+ * -+ * Parameters: -+ * none -+ * -+ * Result: -+ * Switch bits (ORed, see below) -+ */ -+#define SMU_CMD_SWITCHES 0xdc -+ -+/* Switches bits */ -+#define SMU_SWITCH_CASE_CLOSED 0x01 -+#define SMU_SWITCH_AC_POWER 0x04 -+#define SMU_SWITCH_POWER_SWITCH 0x08 - - - /* -@@ -243,10 +313,64 @@ - */ - #define SMU_CMD_MISC_ee_COMMAND 0xee - #define SMU_CMD_MISC_ee_GET_DATABLOCK_REC 0x02 --#define SMU_CMD_MISC_ee_LEDS_CTRL 0x04 /* i: 00 (00,01) [00] */ -+ -+/* Retrieves currently used watts. -+ * -+ * Parameters: -+ * 1: 0x03 (Meaning unknown) -+ */ -+#define SMU_CMD_MISC_ee_GET_WATTS 0x03 -+ -+#define SMU_CMD_MISC_ee_LEDS_CTRL 0x04 /* i: 00 (00,01) [00] */ - #define SMU_CMD_MISC_ee_GET_DATA 0x05 /* i: 00 , o: ?? */ - - -+/* -+ * Power related commands -+ * -+ * Parameters: -+ * 1: subcommand -+ */ -+#define SMU_CMD_POWER_EVENTS_COMMAND 0x8f -+ -+/* SMU_POWER_EVENTS subcommands */ -+enum { -+ SMU_PWR_GET_POWERUP_EVENTS = 0x00, -+ SMU_PWR_SET_POWERUP_EVENTS = 0x01, -+ SMU_PWR_CLR_POWERUP_EVENTS = 0x02, -+ SMU_PWR_GET_WAKEUP_EVENTS = 0x03, -+ SMU_PWR_SET_WAKEUP_EVENTS = 0x04, -+ SMU_PWR_CLR_WAKEUP_EVENTS = 0x05, -+ -+ /* -+ * Get last shutdown cause -+ * -+ * Returns: -+ * 1 byte (signed char): Last shutdown cause. Exact meaning unknown. -+ */ -+ SMU_PWR_LAST_SHUTDOWN_CAUSE = 0x07, -+ -+ /* -+ * Sets or gets server ID. Meaning or use is unknown. -+ * -+ * Parameters: -+ * 2 (optional): Set server ID (1 byte) -+ * -+ * Returns: -+ * 1 byte (server ID?) -+ */ -+ SMU_PWR_SERVER_ID = 0x08, -+}; -+ -+/* Power events wakeup bits */ -+enum { -+ SMU_PWR_WAKEUP_KEY = 0x01, /* Wake on key press */ -+ SMU_PWR_WAKEUP_AC_INSERT = 0x02, /* Wake on AC adapter plug */ -+ SMU_PWR_WAKEUP_AC_CHANGE = 0x04, -+ SMU_PWR_WAKEUP_LID_OPEN = 0x08, -+ SMU_PWR_WAKEUP_RING = 0x10, -+}; -+ - - /* - * - Kernel side interface - -@@ -564,13 +688,13 @@ struct smu_user_cmd_hdr - - __u8 cmd; /* SMU command byte */ - __u8 pad[3]; /* padding */ -- __u32 data_len; /* Lenght of data following */ -+ __u32 data_len; /* Length of data following */ - }; - - struct smu_user_reply_hdr - { - __u32 status; /* Command status */ -- __u32 reply_len; /* Lenght of data follwing */ -+ __u32 reply_len; /* Length of data follwing */ - }; - - #endif /* _SMU_H */ ---- a/include/asm-powerpc/sparsemem.h -+++ b/include/asm-powerpc/sparsemem.h -@@ -10,13 +10,8 @@ - */ - #define SECTION_SIZE_BITS 24 - --#if defined(CONFIG_PS3_USE_LPAR_ADDR) --#define MAX_PHYSADDR_BITS 47 --#define MAX_PHYSMEM_BITS 47 --#else - #define MAX_PHYSADDR_BITS 44 - #define MAX_PHYSMEM_BITS 44 --#endif - - #ifdef CONFIG_MEMORY_HOTPLUG - extern void create_section_mapping(unsigned long start, unsigned long end); ---- a/include/asm-powerpc/spu.h -+++ b/include/asm-powerpc/spu.h -@@ -104,6 +104,7 @@ - - struct spu_context; - struct spu_runqueue; -+struct spu_lscsa; - struct device_node; - - enum spu_utilization_state { -@@ -145,7 +146,6 @@ struct spu { - void (* ibox_callback)(struct spu *spu); - void (* stop_callback)(struct spu *spu); - void (* mfc_callback)(struct spu *spu); -- void (* dma_callback)(struct spu *spu, int type); - - char irq_c0[8]; - char irq_c1[8]; -@@ -196,10 +196,11 @@ struct cbe_spu_info { - extern struct cbe_spu_info cbe_spu_info[]; - - void spu_init_channels(struct spu *spu); --int spu_irq_class_0_bottom(struct spu *spu); --int spu_irq_class_1_bottom(struct spu *spu); - void spu_irq_setaffinity(struct spu *spu, int cpu); - -+void spu_setup_kernel_slbs(struct spu *spu, struct spu_lscsa *lscsa, -+ void *code, int code_size); -+ - #ifdef CONFIG_KEXEC - void crash_register_spus(struct list_head *list); - #else -@@ -210,6 +211,7 @@ static inline void crash_register_spus(s - - extern void spu_invalidate_slbs(struct spu *spu); - extern void spu_associate_mm(struct spu *spu, struct mm_struct *mm); -+int spu_64k_pages_available(void); - - /* Calls from the memory management to the SPU */ - struct mm_struct; -@@ -279,6 +281,8 @@ void spu_remove_sysdev_attr(struct sysde - int spu_add_sysdev_attr_group(struct attribute_group *attrs); - void spu_remove_sysdev_attr_group(struct attribute_group *attrs); - -+int spu_handle_mm_fault(struct mm_struct *mm, unsigned long ea, -+ unsigned long dsisr, unsigned *flt); - - /* - * Notifier blocks: -@@ -303,7 +307,7 @@ extern void notify_spus_active(void); - extern void do_notify_spus_active(void); - - /* -- * This defines the Local Store, Problem Area and Privlege Area of an SPU. -+ * This defines the Local Store, Problem Area and Privilege Area of an SPU. - */ - - union mfc_tag_size_class_cmd { -@@ -524,8 +528,24 @@ struct spu_priv1 { - #define CLASS2_ENABLE_SPU_STOP_INTR 0x2L - #define CLASS2_ENABLE_SPU_HALT_INTR 0x4L - #define CLASS2_ENABLE_SPU_DMA_TAG_GROUP_COMPLETE_INTR 0x8L -+#define CLASS2_ENABLE_MAILBOX_THRESHOLD_INTR 0x10L - u8 pad_0x118_0x140[0x28]; /* 0x118 */ - u64 int_stat_RW[3]; /* 0x140 */ -+#define CLASS0_DMA_ALIGNMENT_INTR 0x1L -+#define CLASS0_INVALID_DMA_COMMAND_INTR 0x2L -+#define CLASS0_SPU_ERROR_INTR 0x4L -+#define CLASS0_INTR_MASK 0x7L -+#define CLASS1_SEGMENT_FAULT_INTR 0x1L -+#define CLASS1_STORAGE_FAULT_INTR 0x2L -+#define CLASS1_LS_COMPARE_SUSPEND_ON_GET_INTR 0x4L -+#define CLASS1_LS_COMPARE_SUSPEND_ON_PUT_INTR 0x8L -+#define CLASS1_INTR_MASK 0xfL -+#define CLASS2_MAILBOX_INTR 0x1L -+#define CLASS2_SPU_STOP_INTR 0x2L -+#define CLASS2_SPU_HALT_INTR 0x4L -+#define CLASS2_SPU_DMA_TAG_GROUP_COMPLETE_INTR 0x8L -+#define CLASS2_MAILBOX_THRESHOLD_INTR 0x10L -+#define CLASS2_INTR_MASK 0x1fL - u8 pad_0x158_0x180[0x28]; /* 0x158 */ - u64 int_route_RW; /* 0x180 */ - ---- a/include/asm-powerpc/spu_csa.h -+++ b/include/asm-powerpc/spu_csa.h -@@ -194,7 +194,7 @@ struct spu_priv1_collapsed { - }; - - /* -- * struct spu_priv2_collapsed - condensed priviliged 2 area, w/o pads. -+ * struct spu_priv2_collapsed - condensed privileged 2 area, w/o pads. - */ - struct spu_priv2_collapsed { - u64 slb_index_W; -@@ -254,20 +254,11 @@ struct spu_state { - u64 spu_chnldata_RW[32]; - u32 spu_mailbox_data[4]; - u32 pu_mailbox_data[1]; -- u64 dar, dsisr; -+ u64 dar, dsisr, class_0_pending; - unsigned long suspend_time; - spinlock_t register_lock; - }; - --extern int spu_init_csa(struct spu_state *csa); --extern void spu_fini_csa(struct spu_state *csa); --extern int spu_save(struct spu_state *prev, struct spu *spu); --extern int spu_restore(struct spu_state *new, struct spu *spu); --extern int spu_switch(struct spu_state *prev, struct spu_state *new, -- struct spu *spu); --extern int spu_alloc_lscsa(struct spu_state *csa); --extern void spu_free_lscsa(struct spu_state *csa); -- - #endif /* !__SPU__ */ - #endif /* __KERNEL__ */ - #endif /* !__ASSEMBLY__ */ ---- a/include/asm-powerpc/spu_priv1.h -+++ b/include/asm-powerpc/spu_priv1.h -@@ -24,6 +24,7 @@ - #include - - struct spu; -+struct spu_context; - - /* access to priv1 registers */ - -@@ -178,6 +179,8 @@ struct spu_management_ops { - int (*enumerate_spus)(int (*fn)(void *data)); - int (*create_spu)(struct spu *spu, void *data); - int (*destroy_spu)(struct spu *spu); -+ void (*enable_spu)(struct spu_context *ctx); -+ void (*disable_spu)(struct spu_context *ctx); - int (*init_affinity)(void); - }; - -@@ -207,6 +210,18 @@ spu_init_affinity (void) - return spu_management_ops->init_affinity(); - } - -+static inline void -+spu_enable_spu (struct spu_context *ctx) -+{ -+ spu_management_ops->enable_spu(ctx); -+} -+ -+static inline void -+spu_disable_spu (struct spu_context *ctx) -+{ -+ spu_management_ops->disable_spu(ctx); -+} -+ - /* - * The declarations folowing are put here for convenience - * and only intended to be used by the platform setup code. ---- a/include/asm-powerpc/system.h -+++ b/include/asm-powerpc/system.h -@@ -169,6 +169,8 @@ extern int do_page_fault(struct pt_regs - extern void bad_page_fault(struct pt_regs *, unsigned long, int); - extern int die(const char *, struct pt_regs *, long); - extern void _exception(int, struct pt_regs *, int, unsigned long); -+extern void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val); -+ - #ifdef CONFIG_BOOKE_WDT - extern u32 booke_wdt_enabled; - extern u32 booke_wdt_period; ---- a/include/asm-powerpc/udbg.h -+++ b/include/asm-powerpc/udbg.h -@@ -48,6 +48,7 @@ extern void __init udbg_init_rtas_consol - extern void __init udbg_init_debug_beat(void); - extern void __init udbg_init_btext(void); - extern void __init udbg_init_44x_as1(void); -+extern void __init udbg_init_40x_realmode(void); - extern void __init udbg_init_cpm(void); - - #endif /* __KERNEL__ */ ---- a/include/asm-ppc/8xx_immap.h -+++ b/include/asm-ppc/8xx_immap.h -@@ -123,7 +123,7 @@ typedef struct mem_ctlr { - #define OR_G5LA 0x00000400 /* Output #GPL5 on #GPL_A5 */ - #define OR_G5LS 0x00000200 /* Drive #GPL high on falling edge of...*/ - #define OR_BI 0x00000100 /* Burst inhibit */ --#define OR_SCY_MSK 0x000000f0 /* Cycle Lenght in Clocks */ -+#define OR_SCY_MSK 0x000000f0 /* Cycle Length in Clocks */ - #define OR_SCY_0_CLK 0x00000000 /* 0 clock cycles wait states */ - #define OR_SCY_1_CLK 0x00000010 /* 1 clock cycles wait states */ - #define OR_SCY_2_CLK 0x00000020 /* 2 clock cycles wait states */ ---- a/include/asm-ppc/commproc.h -+++ b/include/asm-ppc/commproc.h -@@ -681,7 +681,7 @@ typedef struct risc_timer_pram { - #define CICR_SCC_SCC3 ((uint)0x00200000) /* SCC3 @ SCCc */ - #define CICR_SCB_SCC2 ((uint)0x00040000) /* SCC2 @ SCCb */ - #define CICR_SCA_SCC1 ((uint)0x00000000) /* SCC1 @ SCCa */ --#define CICR_IRL_MASK ((uint)0x0000e000) /* Core interrrupt */ -+#define CICR_IRL_MASK ((uint)0x0000e000) /* Core interrupt */ - #define CICR_HP_MASK ((uint)0x00001f00) /* Hi-pri int. */ - #define CICR_IEN ((uint)0x00000080) /* Int. enable */ - #define CICR_SPS ((uint)0x00000001) /* SCC Spread */ ---- a/include/asm-ppc/mmu.h -+++ b/include/asm-ppc/mmu.h -@@ -383,6 +383,12 @@ typedef struct _P601_BAT { - #define BOOKE_PAGESZ_256GB 14 - #define BOOKE_PAGESZ_1TB 15 - -+#ifndef CONFIG_SERIAL_TEXT_DEBUG -+#define PPC44x_EARLY_TLBS 1 -+#else -+#define PPC44x_EARLY_TLBS 2 -+#endif -+ - /* - * Freescale Book-E MMU support - */ ---- a/include/asm-ppc/mpc52xx_psc.h -+++ b/include/asm-ppc/mpc52xx_psc.h -@@ -159,6 +159,9 @@ struct mpc52xx_psc { - u8 reserved16[3]; - u8 irfdr; /* PSC + 0x54 */ - u8 reserved17[3]; -+}; -+ -+struct mpc52xx_psc_fifo { - u16 rfnum; /* PSC + 0x58 */ - u16 reserved18; - u16 tfnum; /* PSC + 0x5c */ ---- a/include/asm-ppc/reg_booke.h -+++ b/include/asm-ppc/reg_booke.h -@@ -207,7 +207,7 @@ - #define CCR1_TCS 0x00000080 /* Timer Clock Select */ - - /* Bit definitions for the MCSR. */ --#ifdef CONFIG_440A -+#ifdef CONFIG_4xx - #define MCSR_MCS 0x80000000 /* Machine Check Summary */ - #define MCSR_IB 0x40000000 /* Instruction PLB Error */ - #define MCSR_DRB 0x20000000 /* Data Read PLB Error */ -@@ -283,7 +283,7 @@ - #define ESR_IMCB 0x20000000 /* Instr. Machine Check - Bus error */ - #define ESR_IMCT 0x10000000 /* Instr. Machine Check - Timeout */ - #define ESR_PIL 0x08000000 /* Program Exception - Illegal */ --#define ESR_PPR 0x04000000 /* Program Exception - Priveleged */ -+#define ESR_PPR 0x04000000 /* Program Exception - Privileged */ - #define ESR_PTR 0x02000000 /* Program Exception - Trap */ - #define ESR_FP 0x01000000 /* Floating Point Operation */ - #define ESR_DST 0x00800000 /* Storage Exception - Data miss */ ---- a/include/linux/of.h -+++ b/include/linux/of.h -@@ -17,6 +17,7 @@ - */ - #include - #include -+#include - - #include - -@@ -41,11 +42,20 @@ extern struct device_node *of_find_compa - #define for_each_compatible_node(dn, type, compatible) \ - for (dn = of_find_compatible_node(NULL, type, compatible); dn; \ - dn = of_find_compatible_node(dn, type, compatible)) -+extern struct device_node *of_find_matching_node(struct device_node *from, -+ const struct of_device_id *matches); -+#define for_each_matching_node(dn, matches) \ -+ for (dn = of_find_matching_node(NULL, matches); dn; \ -+ dn = of_find_matching_node(dn, matches)) - extern struct device_node *of_find_node_by_path(const char *path); - extern struct device_node *of_find_node_by_phandle(phandle handle); - extern struct device_node *of_get_parent(const struct device_node *node); - extern struct device_node *of_get_next_child(const struct device_node *node, - struct device_node *prev); -+#define for_each_child_of_node(parent, child) \ -+ for (child = of_get_next_child(parent, NULL); child != NULL; \ -+ child = of_get_next_child(parent, child)) -+ - extern struct property *of_find_property(const struct device_node *np, - const char *name, - int *lenp); -@@ -56,5 +66,7 @@ extern const void *of_get_property(const - int *lenp); - extern int of_n_addr_cells(struct device_node *np); - extern int of_n_size_cells(struct device_node *np); -+extern const struct of_device_id *of_match_node( -+ const struct of_device_id *matches, const struct device_node *node); - - #endif /* _LINUX_OF_H */ ---- a/include/linux/of_device.h -+++ b/include/linux/of_device.h -@@ -10,8 +10,6 @@ - - #define to_of_device(d) container_of(d, struct of_device, dev) - --extern const struct of_device_id *of_match_node( -- const struct of_device_id *matches, const struct device_node *node); - extern const struct of_device_id *of_match_device( - const struct of_device_id *matches, const struct of_device *dev); - ---- a/include/linux/pata_platform.h -+++ b/include/linux/pata_platform.h -@@ -15,4 +15,13 @@ struct pata_platform_info { - unsigned int irq_flags; - }; - -+extern int __devinit __pata_platform_probe(struct device *dev, -+ struct resource *io_res, -+ struct resource *ctl_res, -+ struct resource *irq_res, -+ unsigned int ioport_shift, -+ int __pio_mask); -+ -+extern int __devexit __pata_platform_remove(struct device *dev); -+ - #endif /* __LINUX_PATA_PLATFORM_H */ ---- a/include/linux/phy_fixed.h -+++ b/include/linux/phy_fixed.h -@@ -1,38 +1,31 @@ - #ifndef __PHY_FIXED_H - #define __PHY_FIXED_H - --#define MII_REGS_NUM 29 -- --/* max number of virtual phy stuff */ --#define MAX_PHY_AMNT 10 --/* -- The idea is to emulate normal phy behavior by responding with -- pre-defined values to mii BMCR read, so that read_status hook could -- take all the needed info. --*/ -- - struct fixed_phy_status { -- u8 link; -- u16 speed; -- u8 duplex; -+ int link; -+ int speed; -+ int duplex; -+ int pause; -+ int asym_pause; - }; - --/*----------------------------------------------------------------------------- -- * Private information hoder for mii_bus -- *-----------------------------------------------------------------------------*/ --struct fixed_info { -- u16 *regs; -- u8 regs_num; -- struct fixed_phy_status phy_status; -- struct phy_device *phydev; /* pointer to the container */ -- /* link & speed cb */ -- int (*link_update) (struct net_device *, struct fixed_phy_status *); -+#ifdef CONFIG_FIXED_PHY -+extern int fixed_phy_add(unsigned int irq, int phy_id, -+ struct fixed_phy_status *status); -+#else -+static inline int fixed_phy_add(unsigned int irq, int phy_id, -+ struct fixed_phy_status *status) -+{ -+ return -ENODEV; -+} -+#endif /* CONFIG_FIXED_PHY */ - --}; -- -- --int fixed_mdio_set_link_update(struct phy_device *, -- int (*link_update) (struct net_device *, struct fixed_phy_status *)); --struct fixed_info *fixed_mdio_get_phydev (int phydev_ind); -+/* -+ * This function issued only by fixed_phy-aware drivers, no need -+ * protect it with #ifdef -+ */ -+extern int fixed_phy_set_link_update(struct phy_device *phydev, -+ int (*link_update)(struct net_device *, -+ struct fixed_phy_status *)); - - #endif /* __PHY_FIXED_H */ ---- a/include/linux/pmu.h -+++ b/include/linux/pmu.h -@@ -159,41 +159,7 @@ extern void pmu_unlock(void); - extern int pmu_present(void); - extern int pmu_get_model(void); - --#ifdef CONFIG_PM --/* -- * Stuff for putting the powerbook to sleep and waking it again. -- * -- */ --#include -- --struct pmu_sleep_notifier --{ -- void (*notifier_call)(struct pmu_sleep_notifier *self, int when); -- int priority; -- struct list_head list; --}; -- --/* Code values for calling sleep/wakeup handlers -- */ --#define PBOOK_SLEEP_REQUEST 1 --#define PBOOK_SLEEP_NOW 2 --#define PBOOK_WAKE 3 -- --/* priority levels in notifiers */ --#define SLEEP_LEVEL_VIDEO 100 /* Video driver (first wake) */ --#define SLEEP_LEVEL_MEDIABAY 90 /* Media bay driver */ --#define SLEEP_LEVEL_BLOCK 80 /* IDE, SCSI */ --#define SLEEP_LEVEL_NET 70 /* bmac, gmac */ --#define SLEEP_LEVEL_MISC 60 /* Anything else */ --#define SLEEP_LEVEL_USERLAND 55 /* Reserved for apm_emu */ --#define SLEEP_LEVEL_ADB 50 /* ADB (async) */ --#define SLEEP_LEVEL_SOUND 40 /* Sound driver (blocking) */ -- --/* special register notifier functions */ --int pmu_register_sleep_notifier(struct pmu_sleep_notifier* notifier); --int pmu_unregister_sleep_notifier(struct pmu_sleep_notifier* notifier); -- --#endif /* CONFIG_PM */ -+extern void pmu_backlight_set_sleep(int sleep); - - #define PMU_MAX_BATTERIES 2 - diff --git a/target/linux/generic-2.6/patches-2.6.24/801-usb_serial_endpoint_size.patch b/target/linux/generic-2.6/patches-2.6.24/801-usb_serial_endpoint_size.patch deleted file mode 100644 index 1c777d21e2..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/801-usb_serial_endpoint_size.patch +++ /dev/null @@ -1,25 +0,0 @@ ---- a/drivers/usb/serial/usb-serial.c -+++ b/drivers/usb/serial/usb-serial.c -@@ -58,6 +58,7 @@ static struct usb_driver usb_serial_driv - drivers depend on it. - */ - -+static ushort maxSize = 0; - static int debug; - static struct usb_serial *serial_table[SERIAL_TTY_MINORS]; /* initially all NULL */ - static DEFINE_MUTEX(table_lock); -@@ -894,7 +895,7 @@ int usb_serial_probe(struct usb_interfac - dev_err(&interface->dev, "No free urbs available\n"); - goto probe_error; - } -- buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); -+ buffer_size = (endpoint->wMaxPacketSize > maxSize) ? endpoint->wMaxPacketSize : maxSize; - port->bulk_in_size = buffer_size; - port->bulk_in_endpointAddress = endpoint->bEndpointAddress; - port->bulk_in_buffer = kmalloc (buffer_size, GFP_KERNEL); -@@ -1306,3 +1307,5 @@ MODULE_LICENSE("GPL"); - - module_param(debug, bool, S_IRUGO | S_IWUSR); - MODULE_PARM_DESC(debug, "Debug enabled or not"); -+module_param(maxSize, ushort,0); -+MODULE_PARM_DESC(maxSize,"User specified USB endpoint size"); diff --git a/target/linux/generic-2.6/patches-2.6.24/840-unable_to_open_console.patch b/target/linux/generic-2.6/patches-2.6.24/840-unable_to_open_console.patch deleted file mode 100644 index dba2e27d7c..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/840-unable_to_open_console.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/init/main.c -+++ b/init/main.c -@@ -773,7 +773,7 @@ static int noinline init_post(void) - numa_default_policy(); - - if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0) -- printk(KERN_WARNING "Warning: unable to open an initial console.\n"); -+ printk(KERN_WARNING "Please be patient, while OpenWrt loads ...\n"); - - (void) sys_dup(0); - (void) sys_dup(0); diff --git a/target/linux/generic-2.6/patches-2.6.24/850-jffs2_erase_progress_indicator.patch b/target/linux/generic-2.6/patches-2.6.24/850-jffs2_erase_progress_indicator.patch deleted file mode 100644 index 20bf1efabc..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/850-jffs2_erase_progress_indicator.patch +++ /dev/null @@ -1,23 +0,0 @@ ---- a/fs/jffs2/erase.c -+++ b/fs/jffs2/erase.c -@@ -35,6 +35,8 @@ static void jffs2_erase_block(struct jff - { - int ret; - uint32_t bad_offset; -+ static char s[]="|/-\\", *p=s; -+ - #ifdef __ECOS - ret = jffs2_flash_erase(c, jeb); - if (!ret) { -@@ -47,6 +49,11 @@ static void jffs2_erase_block(struct jff - - D1(printk(KERN_DEBUG "jffs2_erase_block(): erase block %#08x (range %#08x-%#08x)\n", - jeb->offset, jeb->offset, jeb->offset + c->sector_size)); -+ -+ printk("%c\b", *p); -+ if (*++p==0) -+ p=s; -+ - 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"); diff --git a/target/linux/generic-2.6/patches-2.6.24/900-headers_type_and_time.patch b/target/linux/generic-2.6/patches-2.6.24/900-headers_type_and_time.patch deleted file mode 100644 index dc6e542f1c..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/900-headers_type_and_time.patch +++ /dev/null @@ -1,46 +0,0 @@ ---- a/include/linux/time.h -+++ b/include/linux/time.h -@@ -1,6 +1,10 @@ - #ifndef _LINUX_TIME_H - #define _LINUX_TIME_H - -+#ifndef __KERNEL__ -+#include -+#else -+ - #include - - #ifdef __KERNEL__ -@@ -231,4 +235,6 @@ struct itimerval { - */ - #define TIMER_ABSTIME 0x01 - -+#endif /* __KERNEL__ DEBIAN */ -+ - #endif ---- a/include/linux/types.h -+++ b/include/linux/types.h -@@ -1,6 +1,14 @@ - #ifndef _LINUX_TYPES_H - #define _LINUX_TYPES_H - -+/* Debian: Use userland types instead. */ -+#ifndef __KERNEL__ -+# include -+/* For other kernel headers. */ -+# include -+# include -+#else -+ - #ifdef __KERNEL__ - - #define DECLARE_BITMAP(name,bits) \ -@@ -161,6 +169,8 @@ typedef unsigned long blkcnt_t; - - #endif /* __KERNEL_STRICT_NAMES */ - -+#endif /* __KERNEL__ DEBIAN */ -+ - /* - * Below are truly Linux-specific types that should never collide with - * any application/library that wants linux/types.h. diff --git a/target/linux/generic-2.6/patches-2.6.24/902-darwin_scripts_include.patch b/target/linux/generic-2.6/patches-2.6.24/902-darwin_scripts_include.patch deleted file mode 100644 index 621831e1f5..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/902-darwin_scripts_include.patch +++ /dev/null @@ -1,102 +0,0 @@ ---- a/scripts/genksyms/parse.c_shipped -+++ b/scripts/genksyms/parse.c_shipped -@@ -160,7 +160,9 @@ - - - #include -+#ifndef __APPLE__ - #include -+#endif - #include "genksyms.h" - - static int is_typedef; ---- a/scripts/genksyms/parse.y -+++ b/scripts/genksyms/parse.y -@@ -24,7 +24,9 @@ - %{ - - #include -+#ifndef __APPLE__ - #include -+#endif - #include "genksyms.h" - - static int is_typedef; ---- a/scripts/kallsyms.c -+++ b/scripts/kallsyms.c -@@ -28,6 +28,35 @@ - #include - #include - #include -+#ifdef __APPLE__ -+/* Darwin has no memmem implementation, this one is ripped of the uClibc-0.9.28 source */ -+void *memmem (const void *haystack, size_t haystack_len, -+ const void *needle, size_t needle_len) -+{ -+ const char *begin; -+ const char *const last_possible -+ = (const char *) haystack + haystack_len - needle_len; -+ -+ if (needle_len == 0) -+ /* The first occurrence of the empty string is deemed to occur at -+ the beginning of the string. */ -+ return (void *) haystack; -+ -+ /* Sanity check, otherwise the loop might search through the whole -+ memory. */ -+ if (__builtin_expect (haystack_len < needle_len, 0)) -+ return NULL; -+ -+ for (begin = (const char *) haystack; begin <= last_possible; ++begin) -+ if (begin[0] == ((const char *) needle)[0] && -+ !memcmp ((const void *) &begin[1], -+ (const void *) ((const char *) needle + 1), -+ needle_len - 1)) -+ return (void *) begin; -+ -+ return NULL; -+} -+#endif - - #define KSYM_NAME_LEN 128 - ---- a/scripts/kconfig/Makefile -+++ b/scripts/kconfig/Makefile -@@ -90,6 +90,9 @@ check-lxdialog := $(srctree)/$(src)/lxd - # we really need to do so. (Do not call gcc as part of make mrproper) - HOST_EXTRACFLAGS = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags) - HOST_LOADLIBES = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC)) -+ifeq ($(shell uname -s),Darwin) -+HOST_LOADLIBES += -lncurses -+endif - - HOST_EXTRACFLAGS += -DLOCALE - ---- a/scripts/mod/mk_elfconfig.c -+++ b/scripts/mod/mk_elfconfig.c -@@ -1,7 +1,11 @@ - #include - #include - #include -+#ifndef __APPLE__ - #include -+#else -+#include "../../../../../tools/sstrip/include/elf.h" -+#endif - - int - main(int argc, char **argv) ---- a/scripts/mod/modpost.h -+++ b/scripts/mod/modpost.h -@@ -7,7 +7,11 @@ - #include - #include - #include -+#ifndef __APPLE__ - #include -+#else -+#include "../../../../../tools/sstrip/include/elf.h" -+#endif - - #include "elfconfig.h" - diff --git a/target/linux/generic-2.6/patches-2.6.24/903-hostap_txpower.patch b/target/linux/generic-2.6/patches-2.6.24/903-hostap_txpower.patch deleted file mode 100644 index 1cf439ee96..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/903-hostap_txpower.patch +++ /dev/null @@ -1,154 +0,0 @@ ---- a/drivers/net/wireless/hostap/hostap_ap.c -+++ b/drivers/net/wireless/hostap/hostap_ap.c -@@ -2358,13 +2358,13 @@ int prism2_ap_get_sta_qual(local_info_t - addr[count].sa_family = ARPHRD_ETHER; - memcpy(addr[count].sa_data, sta->addr, ETH_ALEN); - if (sta->last_rx_silence == 0) -- qual[count].qual = sta->last_rx_signal < 27 ? -- 0 : (sta->last_rx_signal - 27) * 92 / 127; -+ qual[count].qual = (sta->last_rx_signal - 156) == 0 ? -+ 0 : (sta->last_rx_signal - 156) * 92 / 64; - else -- qual[count].qual = sta->last_rx_signal - -- sta->last_rx_silence - 35; -- qual[count].level = HFA384X_LEVEL_TO_dBm(sta->last_rx_signal); -- qual[count].noise = HFA384X_LEVEL_TO_dBm(sta->last_rx_silence); -+ qual[count].qual = (sta->last_rx_signal - -+ sta->last_rx_silence) * 92 / 64; -+ qual[count].level = sta->last_rx_signal; -+ qual[count].noise = sta->last_rx_silence; - qual[count].updated = sta->last_rx_updated; - - sta->last_rx_updated = IW_QUAL_DBM; -@@ -2429,13 +2429,13 @@ int prism2_ap_translate_scan(struct net_ - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = IWEVQUAL; - if (sta->last_rx_silence == 0) -- iwe.u.qual.qual = sta->last_rx_signal < 27 ? -- 0 : (sta->last_rx_signal - 27) * 92 / 127; -+ iwe.u.qual.qual = (sta->last_rx_signal -156) == 0 ? -+ 0 : (sta->last_rx_signal - 156) * 92 / 64; - else -- iwe.u.qual.qual = sta->last_rx_signal - -- sta->last_rx_silence - 35; -- iwe.u.qual.level = HFA384X_LEVEL_TO_dBm(sta->last_rx_signal); -- iwe.u.qual.noise = HFA384X_LEVEL_TO_dBm(sta->last_rx_silence); -+ iwe.u.qual.qual = (sta->last_rx_signal - -+ sta->last_rx_silence) * 92 / 64; -+ iwe.u.qual.level = sta->last_rx_signal; -+ iwe.u.qual.noise = sta->last_rx_silence; - iwe.u.qual.updated = sta->last_rx_updated; - iwe.len = IW_EV_QUAL_LEN; - current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, ---- a/drivers/net/wireless/hostap/hostap_config.h -+++ b/drivers/net/wireless/hostap/hostap_config.h -@@ -45,4 +45,9 @@ - */ - /* #define PRISM2_NO_STATION_MODES */ - -+/* Enable TX power Setting functions -+ * (min att = -128 , max att = 127) -+ */ -+#define RAW_TXPOWER_SETTING -+ - #endif /* HOSTAP_CONFIG_H */ ---- a/drivers/net/wireless/hostap/hostap.h -+++ b/drivers/net/wireless/hostap/hostap.h -@@ -89,6 +89,7 @@ extern const struct iw_handler_def hosta - extern const struct ethtool_ops prism2_ethtool_ops; - - int hostap_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); -+int hostap_restore_power(struct net_device *dev); - - - #endif /* HOSTAP_H */ ---- a/drivers/net/wireless/hostap/hostap_hw.c -+++ b/drivers/net/wireless/hostap/hostap_hw.c -@@ -933,6 +933,7 @@ static int hfa384x_set_rid(struct net_de - prism2_hw_reset(dev); - } - -+ hostap_restore_power(dev); - return res; - } - ---- a/drivers/net/wireless/hostap/hostap_info.c -+++ b/drivers/net/wireless/hostap/hostap_info.c -@@ -433,6 +433,11 @@ static void handle_info_queue_linkstatus - } - - /* Get BSSID if we have a valid AP address */ -+ -+ if ( val == HFA384X_LINKSTATUS_CONNECTED || -+ val == HFA384X_LINKSTATUS_DISCONNECTED ) -+ hostap_restore_power(local->dev); -+ - if (connected) { - netif_carrier_on(local->dev); - netif_carrier_on(local->ddev); ---- a/drivers/net/wireless/hostap/hostap_ioctl.c -+++ b/drivers/net/wireless/hostap/hostap_ioctl.c -@@ -1501,23 +1501,20 @@ static int prism2_txpower_hfa386x_to_dBm - val = 255; - - tmp = val; -- tmp >>= 2; - -- return -12 - tmp; -+ return tmp; - } - - static u16 prism2_txpower_dBm_to_hfa386x(int val) - { - signed char tmp; - -- if (val > 20) -- return 128; -- else if (val < -43) -+ if (val > 127) - return 127; -+ else if (val < -128) -+ return 128; - - tmp = val; -- tmp = -12 - tmp; -- tmp <<= 2; - - return (unsigned char) tmp; - } -@@ -4077,3 +4074,35 @@ int hostap_ioctl(struct net_device *dev, - - return ret; - } -+ -+/* BUG FIX: Restore power setting value when lost due to F/W bug */ -+ -+int hostap_restore_power(struct net_device *dev) -+{ -+ struct hostap_interface *iface = dev->priv; -+ local_info_t *local = iface->local; -+ -+ u16 val; -+ int ret = 0; -+ -+ if (local->txpower_type == PRISM2_TXPOWER_OFF) { -+ val = 0xff; /* use all standby and sleep modes */ -+ ret = local->func->cmd(dev, HFA384X_CMDCODE_WRITEMIF, -+ HFA386X_CR_A_D_TEST_MODES2, -+ &val, NULL); -+ } -+ -+#ifdef RAW_TXPOWER_SETTING -+ if (local->txpower_type == PRISM2_TXPOWER_FIXED) { -+ val = HFA384X_TEST_CFG_BIT_ALC; -+ local->func->cmd(dev, HFA384X_CMDCODE_TEST | -+ (HFA384X_TEST_CFG_BITS << 8), 0, &val, NULL); -+ val = prism2_txpower_dBm_to_hfa386x(local->txpower); -+ ret = (local->func->cmd(dev, HFA384X_CMDCODE_WRITEMIF, -+ HFA386X_CR_MANUAL_TX_POWER, &val, NULL)); -+ } -+#endif /* RAW_TXPOWER_SETTING */ -+ return (ret ? -EOPNOTSUPP : 0); -+} -+ -+EXPORT_SYMBOL(hostap_restore_power); diff --git a/target/linux/generic-2.6/patches-2.6.24/903-stddef_include.patch b/target/linux/generic-2.6/patches-2.6.24/903-stddef_include.patch deleted file mode 100644 index 7fe248d8d3..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/903-stddef_include.patch +++ /dev/null @@ -1,17 +0,0 @@ ---- a/include/linux/stddef.h -+++ b/include/linux/stddef.h -@@ -16,6 +16,7 @@ enum { - false = 0, - true = 1 - }; -+#endif /* __KERNEL__ */ - - #undef offsetof - #ifdef __compiler_offsetof -@@ -23,6 +24,5 @@ enum { - #else - #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) - #endif --#endif /* __KERNEL__ */ - - #endif diff --git a/target/linux/generic-2.6/patches-2.6.24/904-ls_time_locale.patch b/target/linux/generic-2.6/patches-2.6.24/904-ls_time_locale.patch deleted file mode 100644 index 8fc9381a69..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/904-ls_time_locale.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- a/scripts/gen_initramfs_list.sh -+++ b/scripts/gen_initramfs_list.sh -@@ -125,7 +125,7 @@ parse() { - str="${ftype} ${name} ${location} ${str}" - ;; - "nod") -- local dev=`LC_ALL=C ls -l "${location}"` -+ local dev=`LC_ALL=C ls -l --time-style=locale "${location}"` - local maj=`field 5 ${dev}` - local min=`field 6 ${dev}` - maj=${maj%,} -@@ -135,7 +135,7 @@ parse() { - str="${ftype} ${name} ${str} ${dev} ${maj} ${min}" - ;; - "slink") -- local target=`field 11 $(LC_ALL=C ls -l "${location}")` -+ local target=`field 11 $(LC_ALL=C ls -l --time-style=locale "${location}")` - str="${ftype} ${name} ${target} ${str}" - ;; - *) diff --git a/target/linux/generic-2.6/patches-2.6.24/905-i386_build.patch b/target/linux/generic-2.6/patches-2.6.24/905-i386_build.patch deleted file mode 100644 index c701fdaa95..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/905-i386_build.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- a/arch/x86/boot/tools/build.c -+++ b/arch/x86/boot/tools/build.c -@@ -29,7 +29,6 @@ - #include - #include - #include --#include - #include - #include - #include diff --git a/target/linux/generic-2.6/patches-2.6.24/921-gpio_spi_driver.patch b/target/linux/generic-2.6/patches-2.6.24/921-gpio_spi_driver.patch deleted file mode 100644 index 1ad193249e..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/921-gpio_spi_driver.patch +++ /dev/null @@ -1,24 +0,0 @@ ---- a/drivers/spi/Kconfig -+++ b/drivers/spi/Kconfig -@@ -100,6 +100,11 @@ config SPI_BUTTERFLY - inexpensive battery powered microcontroller evaluation board. - This same cable can be used to flash new firmware. - -+config SPI_GPIO -+ tristate "GPIO API based bitbanging SPI controller" -+ depends on SPI_MASTER && GENERIC_GPIO && EXPERIMENTAL -+ select SPI_BITBANG -+ - config SPI_IMX - tristate "Freescale iMX SPI controller" - depends on SPI_MASTER && ARCH_IMX && EXPERIMENTAL ---- a/drivers/spi/Makefile -+++ b/drivers/spi/Makefile -@@ -16,6 +16,7 @@ obj-$(CONFIG_SPI_BFIN) += spi_bfin5xx. - obj-$(CONFIG_SPI_BITBANG) += spi_bitbang.o - obj-$(CONFIG_SPI_AU1550) += au1550_spi.o - obj-$(CONFIG_SPI_BUTTERFLY) += spi_butterfly.o -+obj-$(CONFIG_SPI_GPIO) += spi_gpio.o - obj-$(CONFIG_SPI_IMX) += spi_imx.o - obj-$(CONFIG_SPI_LM70_LLP) += spi_lm70llp.o - obj-$(CONFIG_SPI_PXA2XX) += pxa2xx_spi.o diff --git a/target/linux/generic-2.6/patches-2.6.24/922-w1_gpio_driver_backport.patch b/target/linux/generic-2.6/patches-2.6.24/922-w1_gpio_driver_backport.patch deleted file mode 100644 index dc5aadfbcf..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/922-w1_gpio_driver_backport.patch +++ /dev/null @@ -1,178 +0,0 @@ ---- a/drivers/w1/masters/Kconfig -+++ b/drivers/w1/masters/Kconfig -@@ -42,5 +42,15 @@ config W1_MASTER_DS1WM - in HP iPAQ devices like h5xxx, h2200, and ASIC3-based like - hx4700. - -+config W1_MASTER_GPIO -+ tristate "GPIO 1-wire busmaster" -+ depends on GENERIC_GPIO -+ help -+ Say Y here if you want to communicate with your 1-wire devices using -+ GPIO pins. This driver uses the GPIO API to control the wire. -+ -+ This support is also available as a module. If so, the module -+ will be called w1-gpio.ko. -+ - endmenu - ---- a/drivers/w1/masters/Makefile -+++ b/drivers/w1/masters/Makefile -@@ -6,3 +6,4 @@ obj-$(CONFIG_W1_MASTER_MATROX) += matro - obj-$(CONFIG_W1_MASTER_DS2490) += ds2490.o - obj-$(CONFIG_W1_MASTER_DS2482) += ds2482.o - obj-$(CONFIG_W1_MASTER_DS1WM) += ds1wm.o -+obj-$(CONFIG_W1_MASTER_GPIO) += w1-gpio.o ---- /dev/null -+++ b/drivers/w1/masters/w1-gpio.c -@@ -0,0 +1,124 @@ -+/* -+ * w1-gpio - GPIO w1 bus master driver -+ * -+ * Copyright (C) 2007 Ville Syrjala -+ * -+ * 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 "../w1.h" -+#include "../w1_int.h" -+ -+#include -+ -+static void w1_gpio_write_bit_dir(void *data, u8 bit) -+{ -+ struct w1_gpio_platform_data *pdata = data; -+ -+ if (bit) -+ gpio_direction_input(pdata->pin); -+ else -+ gpio_direction_output(pdata->pin, 0); -+} -+ -+static void w1_gpio_write_bit_val(void *data, u8 bit) -+{ -+ struct w1_gpio_platform_data *pdata = data; -+ -+ gpio_set_value(pdata->pin, bit); -+} -+ -+static u8 w1_gpio_read_bit(void *data) -+{ -+ struct w1_gpio_platform_data *pdata = data; -+ -+ return gpio_get_value(pdata->pin); -+} -+ -+static int __init w1_gpio_probe(struct platform_device *pdev) -+{ -+ struct w1_bus_master *master; -+ struct w1_gpio_platform_data *pdata = pdev->dev.platform_data; -+ int err; -+ -+ if (!pdata) -+ return -ENXIO; -+ -+ master = kzalloc(sizeof(struct w1_bus_master), GFP_KERNEL); -+ if (!master) -+ return -ENOMEM; -+ -+ err = gpio_request(pdata->pin, "w1"); -+ if (err) -+ goto free_master; -+ -+ master->data = pdata; -+ master->read_bit = w1_gpio_read_bit; -+ -+ if (pdata->is_open_drain) { -+ gpio_direction_output(pdata->pin, 1); -+ master->write_bit = w1_gpio_write_bit_val; -+ } else { -+ gpio_direction_input(pdata->pin); -+ master->write_bit = w1_gpio_write_bit_dir; -+ } -+ -+ err = w1_add_master_device(master); -+ if (err) -+ goto free_gpio; -+ -+ platform_set_drvdata(pdev, master); -+ -+ return 0; -+ -+ free_gpio: -+ gpio_free(pdata->pin); -+ free_master: -+ kfree(master); -+ -+ return err; -+} -+ -+static int __exit w1_gpio_remove(struct platform_device *pdev) -+{ -+ struct w1_bus_master *master = platform_get_drvdata(pdev); -+ struct w1_gpio_platform_data *pdata = pdev->dev.platform_data; -+ -+ w1_remove_master_device(master); -+ gpio_free(pdata->pin); -+ kfree(master); -+ -+ return 0; -+} -+ -+static struct platform_driver w1_gpio_driver = { -+ .driver = { -+ .name = "w1-gpio", -+ .owner = THIS_MODULE, -+ }, -+ .remove = __exit_p(w1_gpio_remove), -+}; -+ -+static int __init w1_gpio_init(void) -+{ -+ return platform_driver_probe(&w1_gpio_driver, w1_gpio_probe); -+} -+ -+static void __exit w1_gpio_exit(void) -+{ -+ platform_driver_unregister(&w1_gpio_driver); -+} -+ -+module_init(w1_gpio_init); -+module_exit(w1_gpio_exit); -+ -+MODULE_DESCRIPTION("GPIO w1 bus master driver"); -+MODULE_AUTHOR("Ville Syrjala "); -+MODULE_LICENSE("GPL"); ---- /dev/null -+++ b/include/linux/w1-gpio.h -@@ -0,0 +1,23 @@ -+/* -+ * w1-gpio interface to platform code -+ * -+ * Copyright (C) 2007 Ville Syrjala -+ * -+ * 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. -+ */ -+#ifndef _LINUX_W1_GPIO_H -+#define _LINUX_W1_GPIO_H -+ -+/** -+ * struct w1_gpio_platform_data - Platform-dependent data for w1-gpio -+ * @pin: GPIO pin to use -+ * @is_open_drain: GPIO pin is configured as open drain -+ */ -+struct w1_gpio_platform_data { -+ unsigned int pin; -+ unsigned int is_open_drain:1; -+}; -+ -+#endif /* _LINUX_W1_GPIO_H */ diff --git a/target/linux/generic-2.6/patches-2.6.24/930-ppc_big_endian_io_memory_accessors.patch b/target/linux/generic-2.6/patches-2.6.24/930-ppc_big_endian_io_memory_accessors.patch deleted file mode 100644 index 25abf821df..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/930-ppc_big_endian_io_memory_accessors.patch +++ /dev/null @@ -1,78 +0,0 @@ -From a.othieno@bluewin.ch Tue Oct 11 07:50:21 2005 -From: Arthur Othieno -Subject: Big-endian I/O memory accessors. -Date: Tue, 11 Oct 2005 07:50:21 +1000 -X-Patchwork-ID: 2759 - -From: Arthur Othieno - -I/O memory accessors. Big endian version. For those busses/devices -that do export big-endian I/O memory. - -Of notable relevance/reference: - - http://lwn.net/Articles/132804/ - http://ozlabs.org/pipermail/linuxppc-embedded/2005-August/019798.html - http://ozlabs.org/pipermail/linuxppc-embedded/2005-August/019752.html - -Signed-off-by: Arthur Othieno ---- - -Paulus, - -A similar patch for ppc64 made it upstream with your big ppc64 merge. -This one is still sitting in http://patchwork.ozlabs.org/linuxppc/ -and didn't make it with the ppc32 equivalent. Thanks. - - - include/asm-ppc/io.h | 20 ++++++++++++++++++++ - 1 file changed, 20 insertions(+) - - ---- ---- a/include/asm-ppc/io.h -+++ b/include/asm-ppc/io.h -@@ -413,11 +413,21 @@ static inline unsigned int ioread16(void - return readw(addr); - } - -+static inline unsigned int ioread16be(void __iomem *addr) -+{ -+ return in_be16(addr); -+} -+ - static inline unsigned int ioread32(void __iomem *addr) - { - return readl(addr); - } - -+static inline unsigned int ioread32be(void __iomem *addr) -+{ -+ return in_be32(addr); -+} -+ - static inline void iowrite8(u8 val, void __iomem *addr) - { - writeb(val, addr); -@@ -428,11 +438,21 @@ static inline void iowrite16(u16 val, vo - writew(val, addr); - } - -+static inline void iowrite16be(u16 val, void __iomem *addr) -+{ -+ out_be16(addr, val); -+} -+ - static inline void iowrite32(u32 val, void __iomem *addr) - { - writel(val, addr); - } - -+static inline void iowrite32be(u32 val, void __iomem *addr) -+{ -+ out_be32(addr, val); -+} -+ - static inline void ioread8_rep(void __iomem *addr, void *dst, unsigned long count) - { - _insb(addr, dst, count); diff --git a/target/linux/generic-2.6/patches-2.6.24/940-arm_mach_types.patch b/target/linux/generic-2.6/patches-2.6.24/940-arm_mach_types.patch deleted file mode 100644 index cfc8b6cf3c..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/940-arm_mach_types.patch +++ /dev/null @@ -1,426 +0,0 @@ ---- a/arch/arm/tools/mach-types -+++ b/arch/arm/tools/mach-types -@@ -12,7 +12,7 @@ - # - # http://www.arm.linux.org.uk/developer/machines/?action=new - # --# Last update: Fri May 11 19:53:41 2007 -+# Last update: Wed Apr 9 13:26:57 2008 - # - # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number - # -@@ -266,7 +266,7 @@ stork_egg ARCH_STORK_EGG STORK_EGG 24 - wismo SA1100_WISMO WISMO 249 - ezlinx ARCH_EZLINX EZLINX 250 - at91rm9200 ARCH_AT91RM9200 AT91RM9200 251 --orion ARCH_ORION ORION 252 -+adtech_orion ARCH_ADTECH_ORION ADTECH_ORION 252 - neptune ARCH_NEPTUNE NEPTUNE 253 - hackkit SA1100_HACKKIT HACKKIT 254 - pxa_wins30 ARCH_PXA_WINS30 PXA_WINS30 255 -@@ -381,13 +381,13 @@ ks8695p ARCH_KS8695P KS8695P 363 - se4000 ARCH_SE4000 SE4000 364 - quadriceps ARCH_QUADRICEPS QUADRICEPS 365 - bronco ARCH_BRONCO BRONCO 366 --esl_wireless_tab ARCH_ESL_WIRELESS_TABLETESL_WIRELESS_TABLET 367 -+esl_wireless_tab ARCH_ESL_WIRELESS_TAB ESL_WIRELESS_TAB 367 - esl_sofcomp ARCH_ESL_SOFCOMP ESL_SOFCOMP 368 - s5c7375 ARCH_S5C7375 S5C7375 369 - spearhead ARCH_SPEARHEAD SPEARHEAD 370 - pantera ARCH_PANTERA PANTERA 371 - prayoglite ARCH_PRAYOGLITE PRAYOGLITE 372 --gumstix ARCH_GUMSTIK GUMSTIK 373 -+gumstix ARCH_GUMSTIX GUMSTIX 373 - rcube ARCH_RCUBE RCUBE 374 - rea_olv ARCH_REA_OLV REA_OLV 375 - pxa_iphone ARCH_PXA_IPHONE PXA_IPHONE 376 -@@ -661,7 +661,6 @@ a9200ec MACH_A9200EC A9200EC 645 - pnx0105 MACH_PNX0105 PNX0105 646 - adcpoecpu MACH_ADCPOECPU ADCPOECPU 647 - csb637 MACH_CSB637 CSB637 648 --ml69q6203 MACH_ML69Q6203 ML69Q6203 649 - mb9200 MACH_MB9200 MB9200 650 - kulun MACH_KULUN KULUN 651 - snapper MACH_SNAPPER SNAPPER 652 -@@ -953,7 +952,6 @@ fred_jack MACH_FRED_JACK FRED_JACK 93 - ttg_color1 MACH_TTG_COLOR1 TTG_COLOR1 940 - nxeb500hmi MACH_NXEB500HMI NXEB500HMI 941 - netdcu8 MACH_NETDCU8 NETDCU8 942 --ml675050_cpu_boa MACH_ML675050_CPU_BOA ML675050_CPU_BOA 943 - ng_fvx538 MACH_NG_FVX538 NG_FVX538 944 - ng_fvs338 MACH_NG_FVS338 NG_FVS338 945 - pnx4103 MACH_PNX4103 PNX4103 946 -@@ -1148,7 +1146,7 @@ aidx270 MACH_AIDX270 AIDX270 1134 - rema MACH_REMA REMA 1135 - bps1000 MACH_BPS1000 BPS1000 1136 - hw90350 MACH_HW90350 HW90350 1137 --omap_sdp3430 MACH_OMAP_SDP3430 OMAP_SDP3430 1138 -+omap_3430sdp MACH_OMAP_3430SDP OMAP_3430SDP 1138 - bluetouch MACH_BLUETOUCH BLUETOUCH 1139 - vstms MACH_VSTMS VSTMS 1140 - xsbase270 MACH_XSBASE270 XSBASE270 1141 -@@ -1214,7 +1212,7 @@ osstbox MACH_OSSTBOX OSSTBOX 1203 - kbat9261 MACH_KBAT9261 KBAT9261 1204 - ct1100 MACH_CT1100 CT1100 1205 - akcppxa MACH_AKCPPXA AKCPPXA 1206 --zevio_1020 MACH_ZEVIO_1020 ZEVIO_1020 1207 -+ochaya1020 MACH_OCHAYA1020 OCHAYA1020 1207 - hitrack MACH_HITRACK HITRACK 1208 - syme1 MACH_SYME1 SYME1 1209 - syhl1 MACH_SYHL1 SYHL1 1210 -@@ -1299,7 +1297,7 @@ xp179 MACH_XP179 XP179 1290 - h4300 MACH_H4300 H4300 1291 - goramo_mlr MACH_GORAMO_MLR GORAMO_MLR 1292 - mxc30020evb MACH_MXC30020EVB MXC30020EVB 1293 --adsbitsymx MACH_ADSBITSIMX ADSBITSIMX 1294 -+adsbitsyg5 MACH_ADSBITSYG5 ADSBITSYG5 1294 - adsportalplus MACH_ADSPORTALPLUS ADSPORTALPLUS 1295 - mmsp2plus MACH_MMSP2PLUS MMSP2PLUS 1296 - em_x270 MACH_EM_X270 EM_X270 1297 -@@ -1367,3 +1365,346 @@ db88f5281 MACH_DB88F5281 DB88F5281 13 - csb726 MACH_CSB726 CSB726 1359 - tik27 MACH_TIK27 TIK27 1360 - mx_uc7420 MACH_MX_UC7420 MX_UC7420 1361 -+rirm3 MACH_RIRM3 RIRM3 1362 -+pelco_odyssey MACH_PELCO_ODYSSEY PELCO_ODYSSEY 1363 -+adx_abox MACH_ADX_ABOX ADX_ABOX 1365 -+adx_tpid MACH_ADX_TPID ADX_TPID 1366 -+minicheck MACH_MINICHECK MINICHECK 1367 -+idam MACH_IDAM IDAM 1368 -+mario_mx MACH_MARIO_MX MARIO_MX 1369 -+vi1888 MACH_VI1888 VI1888 1370 -+zr4230 MACH_ZR4230 ZR4230 1371 -+t1_ix_blue MACH_T1_IX_BLUE T1_IX_BLUE 1372 -+syhq2 MACH_SYHQ2 SYHQ2 1373 -+computime_r3 MACH_COMPUTIME_R3 COMPUTIME_R3 1374 -+oratis MACH_ORATIS ORATIS 1375 -+mikko MACH_MIKKO MIKKO 1376 -+holon MACH_HOLON HOLON 1377 -+olip8 MACH_OLIP8 OLIP8 1378 -+ghi270hg MACH_GHI270HG GHI270HG 1379 -+davinci_dm6467_evm MACH_DAVINCI_DM6467_EVM DAVINCI_DM6467_EVM 1380 -+davinci_dm355_evm MACH_DAVINCI_DM350_EVM DAVINCI_DM350_EVM 1381 -+ocearm MACH_OCEARMTEST OCEARMTEST 1382 -+blackriver MACH_BLACKRIVER BLACKRIVER 1383 -+sandgate_wp MACH_SANDGATEWP SANDGATEWP 1384 -+cdotbwsg MACH_CDOTBWSG CDOTBWSG 1385 -+quark963 MACH_QUARK963 QUARK963 1386 -+csb735 MACH_CSB735 CSB735 1387 -+littleton MACH_LITTLETON LITTLETON 1388 -+mio_p550 MACH_MIO_P550 MIO_P550 1389 -+motion2440 MACH_MOTION2440 MOTION2440 1390 -+imm500 MACH_IMM500 IMM500 1391 -+homematic MACH_HOMEMATIC HOMEMATIC 1392 -+ermine MACH_ERMINE ERMINE 1393 -+kb9202b MACH_KB9202B KB9202B 1394 -+hs1xx MACH_HS1XX HS1XX 1395 -+studentmate2440 MACH_STUDENTMATE2440 STUDENTMATE2440 1396 -+arvoo_l1_z1 MACH_ARVOO_L1_Z1 ARVOO_L1_Z1 1397 -+dep2410k MACH_DEP2410K DEP2410K 1398 -+xxsvideo MACH_XXSVIDEO XXSVIDEO 1399 -+im4004 MACH_IM4004 IM4004 1400 -+ochaya1050 MACH_OCHAYA1050 OCHAYA1050 1401 -+lep9261 MACH_LEP9261 LEP9261 1402 -+svenmeb MACH_SVENMEB SVENMEB 1403 -+fortunet2ne MACH_FORTUNET2NE FORTUNET2NE 1404 -+nxhx MACH_NXHX NXHX 1406 -+realview_pb11mp MACH_REALVIEW_PB11MP REALVIEW_PB11MP 1407 -+ids500 MACH_IDS500 IDS500 1408 -+ors_n725 MACH_ORS_N725 ORS_N725 1409 -+hsdarm MACH_HSDARM HSDARM 1410 -+sha_pon003 MACH_SHA_PON003 SHA_PON003 1411 -+sha_pon004 MACH_SHA_PON004 SHA_PON004 1412 -+sha_pon007 MACH_SHA_PON007 SHA_PON007 1413 -+sha_pon011 MACH_SHA_PON011 SHA_PON011 1414 -+h6042 MACH_H6042 H6042 1415 -+h6043 MACH_H6043 H6043 1416 -+looxc550 MACH_LOOXC550 LOOXC550 1417 -+cnty_titan MACH_CNTY_TITAN CNTY_TITAN 1418 -+app3xx MACH_APP3XX APP3XX 1419 -+sideoatsgrama MACH_SIDEOATSGRAMA SIDEOATSGRAMA 1420 -+xscale_palmt700p MACH_XSCALE_PALMT700P XSCALE_PALMT700P 1421 -+xscale_palmt700w MACH_XSCALE_PALMT700W XSCALE_PALMT700W 1422 -+xscale_palmt750 MACH_XSCALE_PALMT750 XSCALE_PALMT750 1423 -+xscale_palmt755p MACH_XSCALE_PALMT755P XSCALE_PALMT755P 1424 -+ezreganut9200 MACH_EZREGANUT9200 EZREGANUT9200 1425 -+sarge MACH_SARGE SARGE 1426 -+a696 MACH_A696 A696 1427 -+turtle1916 MACH_TURTLE TURTLE 1428 -+mx27_3ds MACH_MX27_3DS MX27_3DS 1430 -+bishop MACH_BISHOP BISHOP 1431 -+pxx MACH_PXX PXX 1432 -+redwood MACH_REDWOOD REDWOOD 1433 -+omap_2430dlp MACH_OMAP_2430DLP OMAP_2430DLP 1436 -+omap_2430osk MACH_OMAP_2430OSK OMAP_2430OSK 1437 -+sardine MACH_SARDINE SARDINE 1438 -+halibut MACH_HALIBUT HALIBUT 1439 -+trout MACH_TROUT TROUT 1440 -+goldfish MACH_GOLDFISH GOLDFISH 1441 -+gesbc2440 MACH_GESBC2440 GESBC2440 1442 -+nomad MACH_NOMAD NOMAD 1443 -+rosalind MACH_ROSALIND ROSALIND 1444 -+cc9p9215 MACH_CC9P9215 CC9P9215 1445 -+cc9p9210 MACH_CC9P9210 CC9P9210 1446 -+cc9p9215js MACH_CC9P9215JS CC9P9215JS 1447 -+cc9p9210js MACH_CC9P9210JS CC9P9210JS 1448 -+nasffe MACH_NASFFE NASFFE 1449 -+tn2x0bd MACH_TN2X0BD TN2X0BD 1450 -+gwmpxa MACH_GWMPXA GWMPXA 1451 -+exyplus MACH_EXYPLUS EXYPLUS 1452 -+jadoo21 MACH_JADOO21 JADOO21 1453 -+looxn560 MACH_LOOXN560 LOOXN560 1454 -+bonsai MACH_BONSAI BONSAI 1455 -+adsmilgato MACH_ADSMILGATO ADSMILGATO 1456 -+gba MACH_GBA GBA 1457 -+h6044 MACH_H6044 H6044 1458 -+app MACH_APP APP 1459 -+tct_hammer MACH_TCT_HAMMER TCT_HAMMER 1460 -+herald MACH_HERMES HERMES 1461 -+artemis MACH_ARTEMIS ARTEMIS 1462 -+htctitan MACH_HTCTITAN HTCTITAN 1463 -+qranium MACH_QRANIUM QRANIUM 1464 -+adx_wsc2 MACH_ADX_WSC2 ADX_WSC2 1465 -+adx_medcom MACH_ADX_MEDINET ADX_MEDINET 1466 -+bboard MACH_BBOARD BBOARD 1467 -+cambria MACH_CAMBRIA CAMBRIA 1468 -+mt7xxx MACH_MT7XXX MT7XXX 1469 -+matrix512 MACH_MATRIX512 MATRIX512 1470 -+matrix522 MACH_MATRIX522 MATRIX522 1471 -+ipac5010 MACH_IPAC5010 IPAC5010 1472 -+sakura MACH_SAKURA SAKURA 1473 -+grocx MACH_GROCX GROCX 1474 -+pm9263 MACH_PM9263 PM9263 1475 -+sim_one MACH_SIM_ONE SIM_ONE 1476 -+acq132 MACH_ACQ132 ACQ132 1477 -+datr MACH_DATR DATR 1478 -+actux1 MACH_ACTUX1 ACTUX1 1479 -+actux2 MACH_ACTUX2 ACTUX2 1480 -+actux3 MACH_ACTUX3 ACTUX3 1481 -+flexit MACH_FLEXIT FLEXIT 1482 -+bh2x0bd MACH_BH2X0BD BH2X0BD 1483 -+atb2002 MACH_ATB2002 ATB2002 1484 -+xenon MACH_XENON XENON 1485 -+fm607 MACH_FM607 FM607 1486 -+matrix514 MACH_MATRIX514 MATRIX514 1487 -+matrix524 MACH_MATRIX524 MATRIX524 1488 -+inpod MACH_INPOD INPOD 1489 -+jive MACH_JIVE JIVE 1490 -+tll_mx21 MACH_TLL_MX21 TLL_MX21 1491 -+sbc2800 MACH_SBC2800 SBC2800 1492 -+cc7ucamry MACH_CC7UCAMRY CC7UCAMRY 1493 -+ubisys_p9_sc15 MACH_UBISYS_P9_SC15 UBISYS_P9_SC15 1494 -+ubisys_p9_ssc2d10 MACH_UBISYS_P9_SSC2D10 UBISYS_P9_SSC2D10 1495 -+ubisys_p9_rcu3 MACH_UBISYS_P9_RCU3 UBISYS_P9_RCU3 1496 -+aml_m8000 MACH_AML_M8000 AML_M8000 1497 -+snapper_270 MACH_SNAPPER_270 SNAPPER_270 1498 -+omap_bbx MACH_OMAP_BBX OMAP_BBX 1499 -+ucn2410 MACH_UCN2410 UCN2410 1500 -+sam9_l9260 MACH_SAM9_L9260 SAM9_L9260 1501 -+eti_c2 MACH_ETI_C2 ETI_C2 1502 -+avalanche MACH_AVALANCHE AVALANCHE 1503 -+realview_pb1176 MACH_REALVIEW_PB1176 REALVIEW_PB1176 1504 -+dp1500 MACH_DP1500 DP1500 1505 -+apple_iphone MACH_APPLE_IPHONE APPLE_IPHONE 1506 -+yl9200 MACH_YL9200 YL9200 1507 -+rd88f5182 MACH_RD88F5182 RD88F5182 1508 -+kurobox_pro MACH_KUROBOX_PRO KUROBOX_PRO 1509 -+se_poet MACH_SE_POET SE_POET 1510 -+mx31_3ds MACH_MX31_3DS MX31_3DS 1511 -+r270 MACH_R270 R270 1512 -+armour21 MACH_ARMOUR21 ARMOUR21 1513 -+dt2 MACH_DT2 DT2 1514 -+vt4 MACH_VT4 VT4 1515 -+tyco320 MACH_TYCO320 TYCO320 1516 -+adma MACH_ADMA ADMA 1517 -+wp188 MACH_WP188 WP188 1518 -+corsica MACH_CORSICA CORSICA 1519 -+bigeye MACH_BIGEYE BIGEYE 1520 -+tll5000 MACH_TLL5000 TLL5000 1522 -+hni270 MACH_HNI_X270 HNI_X270 1523 -+qong MACH_QONG QONG 1524 -+tcompact MACH_TCOMPACT TCOMPACT 1525 -+puma5 MACH_PUMA5 PUMA5 1526 -+elara MACH_ELARA ELARA 1527 -+ellington MACH_ELLINGTON ELLINGTON 1528 -+xda_atom MACH_XDA_ATOM XDA_ATOM 1529 -+energizer2 MACH_ENERGIZER2 ENERGIZER2 1530 -+odin MACH_ODIN ODIN 1531 -+actux4 MACH_ACTUX4 ACTUX4 1532 -+esl_omap MACH_ESL_OMAP ESL_OMAP 1533 -+omap2evm MACH_OMAP2EVM OMAP2EVM 1534 -+omap3evm MACH_OMAP3EVM OMAP3EVM 1535 -+adx_pcu57 MACH_ADX_PCU57 ADX_PCU57 1536 -+monaco MACH_MONACO MONACO 1537 -+levante MACH_LEVANTE LEVANTE 1538 -+tmxipx425 MACH_TMXIPX425 TMXIPX425 1539 -+leep MACH_LEEP LEEP 1540 -+raad MACH_RAAD RAAD 1541 -+dns323 MACH_DNS323 DNS323 1542 -+ap1000 MACH_AP1000 AP1000 1543 -+a9sam6432 MACH_A9SAM6432 A9SAM6432 1544 -+shiny MACH_SHINY SHINY 1545 -+omap3_beagle MACH_OMAP3_BEAGLE OMAP3_BEAGLE 1546 -+csr_bdb2 MACH_CSR_BDB2 CSR_BDB2 1547 -+nokia_n810 MACH_NOKIA_N810 NOKIA_N810 1548 -+c270 MACH_C270 C270 1549 -+sentry MACH_SENTRY SENTRY 1550 -+pcm038 MACH_PCM038 PCM038 1551 -+anc300 MACH_ANC300 ANC300 1552 -+htckaiser MACH_HTCKAISER HTCKAISER 1553 -+sbat100 MACH_SBAT100 SBAT100 1554 -+modunorm MACH_MODUNORM MODUNORM 1555 -+pelos_twarm MACH_PELOS_TWARM PELOS_TWARM 1556 -+flank MACH_FLANK FLANK 1557 -+sirloin MACH_SIRLOIN SIRLOIN 1558 -+brisket MACH_BRISKET BRISKET 1559 -+chuck MACH_CHUCK CHUCK 1560 -+otter MACH_OTTER OTTER 1561 -+davinci_ldk MACH_DAVINCI_LDK DAVINCI_LDK 1562 -+phreedom MACH_PHREEDOM PHREEDOM 1563 -+sg310 MACH_SG310 SG310 1564 -+ts_x09 MACH_TS209 TS209 1565 -+at91cap9adk MACH_AT91CAP9ADK AT91CAP9ADK 1566 -+tion9315 MACH_TION9315 TION9315 1567 -+mast MACH_MAST MAST 1568 -+pfw MACH_PFW PFW 1569 -+yl_p2440 MACH_YL_P2440 YL_P2440 1570 -+zsbc32 MACH_ZSBC32 ZSBC32 1571 -+omap_pace2 MACH_OMAP_PACE2 OMAP_PACE2 1572 -+imx_pace2 MACH_IMX_PACE2 IMX_PACE2 1573 -+mx31moboard MACH_MX31MOBOARD MX31MOBOARD 1574 -+mx37_3ds MACH_MX37_3DS MX37_3DS 1575 -+rcc MACH_RCC RCC 1576 -+dmp MACH_ARM9 ARM9 1577 -+vision_ep9307 MACH_VISION_EP9307 VISION_EP9307 1578 -+scly1000 MACH_SCLY1000 SCLY1000 1579 -+fontel_ep MACH_FONTEL_EP FONTEL_EP 1580 -+voiceblue3g MACH_VOICEBLUE3G VOICEBLUE3G 1581 -+tt9200 MACH_TT9200 TT9200 1582 -+digi2410 MACH_DIGI2410 DIGI2410 1583 -+terastation_pro2 MACH_TERASTATION_PRO2 TERASTATION_PRO2 1584 -+linkstation_pro MACH_LINKSTATION_PRO LINKSTATION_PRO 1585 -+motorola_a780 MACH_MOTOROLA_A780 MOTOROLA_A780 1587 -+motorola_e6 MACH_MOTOROLA_E6 MOTOROLA_E6 1588 -+motorola_e2 MACH_MOTOROLA_E2 MOTOROLA_E2 1589 -+motorola_e680 MACH_MOTOROLA_E680 MOTOROLA_E680 1590 -+ur2410 MACH_UR2410 UR2410 1591 -+tas9261 MACH_TAS9261 TAS9261 1592 -+davinci_hermes_hd MACH_HERMES_HD HERMES_HD 1593 -+davinci_perseo_hd MACH_PERSEO_HD PERSEO_HD 1594 -+stargazer2 MACH_STARGAZER2 STARGAZER2 1595 -+e350 MACH_E350 E350 1596 -+wpcm450 MACH_WPCM450 WPCM450 1597 -+cartesio MACH_CARTESIO CARTESIO 1598 -+toybox MACH_TOYBOX TOYBOX 1599 -+tx27 MACH_TX27 TX27 1600 -+ts409 MACH_TS409 TS409 1601 -+p300 MACH_P300 P300 1602 -+xdacomet MACH_XDACOMET XDACOMET 1603 -+dexflex2 MACH_DEXFLEX2 DEXFLEX2 1604 -+ow MACH_OW OW 1605 -+armebs3 MACH_ARMEBS3 ARMEBS3 1606 -+u3 MACH_U3 U3 1607 -+smdk2450 MACH_SMDK2450 SMDK2450 1608 -+rsi_ews MACH_RSI_EWS RSI_EWS 1609 -+tnb MACH_TNB TNB 1610 -+toepath MACH_TOEPATH TOEPATH 1611 -+kb9263 MACH_KB9263 KB9263 1612 -+mt7108 MACH_MT7108 MT7108 1613 -+smtr2440 MACH_SMTR2440 SMTR2440 1614 -+manao MACH_MANAO MANAO 1615 -+cm_x300 MACH_CM_X300 CM_X300 1616 -+gulfstream_kp MACH_GULFSTREAM_KP GULFSTREAM_KP 1617 -+lanreadyfn522 MACH_LANREADYFN522 LANREADYFN522 1618 -+arma37 MACH_ARMA37 ARMA37 1619 -+mendel MACH_MENDEL MENDEL 1620 -+pelco_iliad MACH_PELCO_ILIAD PELCO_ILIAD 1621 -+unit2p MACH_UNIT2P UNIT2P 1622 -+inc20otter MACH_INC20OTTER INC20OTTER 1623 -+at91sam9g20ek MACH_AT91SAM9G20EK AT91SAM9G20EK 1624 -+sc_ge2 MACH_STORCENTER STORCENTER 1625 -+smdk6410 MACH_SMDK6410 SMDK6410 1626 -+u300 MACH_U300 U300 1627 -+u500 MACH_U500 U500 1628 -+ds9260 MACH_DS9260 DS9260 1629 -+riverrock MACH_RIVERROCK RIVERROCK 1630 -+scibath MACH_SCIBATH SCIBATH 1631 -+at91sam7se MACH_AT91SAM7SE512EK AT91SAM7SE512EK 1632 -+wrt350n_v2 MACH_WRT350N_V2 WRT350N_V2 1633 -+multimedia MACH_MULTIMEDIA MULTIMEDIA 1634 -+marvin MACH_MARVIN MARVIN 1635 -+x500 MACH_X500 X500 1636 -+awlug4lcu MACH_AWLUG4LCU AWLUG4LCU 1637 -+palermoc MACH_PALERMOC PALERMOC 1638 -+omap_zoom MACH_OMAP_3430LABRADOR OMAP_3430LABRADOR 1639 -+ip500 MACH_IP500 IP500 1640 -+mx35ads MACH_MACH_MX35ADS MACH_MX35ADS 1641 -+ase2 MACH_ASE2 ASE2 1642 -+mx35evb MACH_MX35EVB MX35EVB 1643 -+aml_m8050 MACH_AML_M8050 AML_M8050 1644 -+mx35_3ds MACH_MX35_3DS MX35_3DS 1645 -+mars MACH_MARS MARS 1646 -+ntosd_644xa MACH_NTOSD_644XA NTOSD_644XA 1647 -+badger MACH_BADGER BADGER 1648 -+trizeps4wl MACH_TRIZEPS4WL TRIZEPS4WL 1649 -+trizeps5 MACH_TRIZEPS5 TRIZEPS5 1650 -+marlin MACH_MARLIN MARLIN 1651 -+ts7800 MACH_TS7800 TS7800 1652 -+hpipaq214 MACH_HPIPAQ214 HPIPAQ214 1653 -+at572d940dcm MACH_AT572D940DCM AT572D940DCM 1654 -+ne1board MACH_NE1BOARD NE1BOARD 1655 -+zante MACH_ZANTE ZANTE 1656 -+sffsdr MACH_SFFSDR SFFSDR 1657 -+tw2662 MACH_TW2662 TW2662 1658 -+vf10xx MACH_VF10XX VF10XX 1659 -+zoran43xx MACH_ZORAN43XX ZORAN43XX 1660 -+sonix926 MACH_SONIX926 SONIX926 1661 -+celestialsemi MACH_CELESTIALSEMI CELESTIALSEMI 1662 -+cc9m2443 MACH_CC9M2443 CC9M2443 1663 -+tw5334 MACH_TW5334 TW5334 1664 -+omap_htcartemis MACH_HTCARTEMIS HTCARTEMIS 1665 -+nal_hlite MACH_NAL_HLITE NAL_HLITE 1666 -+htcvogue MACH_HTCVOGUE HTCVOGUE 1667 -+smartweb MACH_SMARTWEB SMARTWEB 1668 -+mv86xx MACH_MV86XX MV86XX 1669 -+mv87xx MACH_MV87XX MV87XX 1670 -+songyoungho MACH_SONGYOUNGHO SONGYOUNGHO 1671 -+younghotema MACH_YOUNGHOTEMA YOUNGHOTEMA 1672 -+pcm037 MACH_PCM037 PCM037 1673 -+mmvp MACH_MMVP MMVP 1674 -+mmap MACH_MMAP MMAP 1675 -+ptid2410 MACH_PTID2410 PTID2410 1676 -+james_926 MACH_JAMES_926 JAMES_926 1677 -+fm6000 MACH_FM6000 FM6000 1678 -+db88f6281_bp MACH_DB88F6281_BP DB88F6281_BP 1680 -+rd88f6192_nas MACH_RD88F6192_NAS RD88F6192_NAS 1681 -+rd88f6281 MACH_RD88F6281 RD88F6281 1682 -+db78x00_bp MACH_DB78X00_BP DB78X00_BP 1683 -+smdk2416 MACH_SMDK2416 SMDK2416 1685 -+oce_spider_si MACH_OCE_SPIDER_SI OCE_SPIDER_SI 1686 -+oce_spider_sk MACH_OCE_SPIDER_SK OCE_SPIDER_SK 1687 -+rovern6 MACH_ROVERN6 ROVERN6 1688 -+pelco_evolution MACH_PELCO_EVOLUTION PELCO_EVOLUTION 1689 -+wbd111 MACH_WBD111 WBD111 1690 -+elaracpe MACH_ELARACPE ELARACPE 1691 -+mabv3 MACH_MABV3 MABV3 1692 -+mv2120 MACH_MV2120 MV2120 1693 -+csb737 MACH_CSB737 CSB737 1695 -+mx51_3ds MACH_MX51_3DS MX51_3DS 1696 -+g900 MACH_G900 G900 1697 -+apf27 MACH_APF27 APF27 1698 -+ggus2000 MACH_GGUS2000 GGUS2000 1699 -+omap_2430_mimic MACH_OMAP_2430_MIMIC OMAP_2430_MIMIC 1700 -+imx27lite MACH_IMX27LITE IMX27LITE 1701 -+almex MACH_ALMEX ALMEX 1702 -+control MACH_CONTROL CONTROL 1703 -+mba2410 MACH_MBA2410 MBA2410 1704 -+volcano MACH_VOLCANO VOLCANO 1705 -+zenith MACH_ZENITH ZENITH 1706 -+muchip MACH_MUCHIP MUCHIP 1707 -+magellan MACH_MAGELLAN MAGELLAN 1708 -+usb_a9260 MACH_USB_A9260 USB_A9260 1709 -+usb_a9263 MACH_USB_A9263 USB_A9263 1710 -+qil_a9260 MACH_QIL_A9260 QIL_A9260 1711 -+cme9210 MACH_CME9210 CME9210 1712 -+hczh4 MACH_HCZH4 HCZH4 1713 -+spearbasic MACH_SPEARBASIC SPEARBASIC 1714 diff --git a/target/linux/generic-2.6/patches-2.6.24/950-mtd_cfi_intel_p33_compatbility.patch b/target/linux/generic-2.6/patches-2.6.24/950-mtd_cfi_intel_p33_compatbility.patch deleted file mode 100644 index 42e8927418..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/950-mtd_cfi_intel_p33_compatbility.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/drivers/mtd/chips/cfi_cmdset_0001.c -+++ b/drivers/mtd/chips/cfi_cmdset_0001.c -@@ -277,7 +277,7 @@ read_pri_intelext(struct map_info *map, - return NULL; - - if (extp->MajorVersion != '1' || -- (extp->MinorVersion < '0' || extp->MinorVersion > '4')) { -+ (extp->MinorVersion < '0' || extp->MinorVersion > '5')) { - printk(KERN_ERR " Unknown Intel/Sharp Extended Query " - "version %c.%c.\n", extp->MajorVersion, - extp->MinorVersion); diff --git a/target/linux/generic-2.6/patches-2.6.24/975-crypto_kconfig_hacks.patch b/target/linux/generic-2.6/patches-2.6.24/975-crypto_kconfig_hacks.patch deleted file mode 100644 index 86d6ecd7b9..0000000000 --- a/target/linux/generic-2.6/patches-2.6.24/975-crypto_kconfig_hacks.patch +++ /dev/null @@ -1,30 +0,0 @@ ---- a/crypto/Kconfig -+++ b/crypto/Kconfig -@@ -20,7 +20,7 @@ menuconfig CRYPTO - if CRYPTO - - config CRYPTO_ALGAPI -- tristate -+ tristate "ALG API" - help - This option provides the API for cryptographic algorithms. - -@@ -29,15 +29,15 @@ config CRYPTO_ABLKCIPHER - select CRYPTO_BLKCIPHER - - config CRYPTO_AEAD -- tristate -+ tristate "AEAD" - select CRYPTO_ALGAPI - - config CRYPTO_BLKCIPHER -- tristate -+ tristate "Block cipher" - select CRYPTO_ALGAPI - - config CRYPTO_HASH -- tristate -+ tristate "HASH" - select CRYPTO_ALGAPI - - config CRYPTO_MANAGER