diff options
author | Jamie Lenehan <lenehan@twibble.org> | 2006-06-28 01:40:03 +0000 |
---|---|---|
committer | OpenEmbedded Project <openembedded-devel@lists.openembedded.org> | 2006-06-28 01:40:03 +0000 |
commit | a4ec0922c99c486493b1a5bb224f315ac7ab9a26 (patch) | |
tree | 9b5d4dfac23ce267de959ddc026177773db8144d | |
parent | d0b038d42a9b6cc23f98e974ef4b7e4397073dfd (diff) |
linux/linux-titan-sh4-2.6.16: Add a 2.6.16 kernel for the sh4 based "titan"
board. This is the only sh4 compatible kernel in OE.
-rw-r--r-- | packages/linux/linux-titan-sh4-2.6.16/.mtn2git_empty | 0 | ||||
-rw-r--r-- | packages/linux/linux-titan-sh4-2.6.16/titan-config | 1468 | ||||
-rw-r--r-- | packages/linux/linux-titan-sh4-2.6.16/titan-flash.patch | 3153 | ||||
-rw-r--r-- | packages/linux/linux-titan-sh4_2.6.16.bb | 49 |
4 files changed, 4670 insertions, 0 deletions
diff --git a/packages/linux/linux-titan-sh4-2.6.16/.mtn2git_empty b/packages/linux/linux-titan-sh4-2.6.16/.mtn2git_empty new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/packages/linux/linux-titan-sh4-2.6.16/.mtn2git_empty diff --git a/packages/linux/linux-titan-sh4-2.6.16/titan-config b/packages/linux/linux-titan-sh4-2.6.16/titan-config new file mode 100644 index 0000000000..4b74c91411 --- /dev/null +++ b/packages/linux/linux-titan-sh4-2.6.16/titan-config @@ -0,0 +1,1468 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.14-sh +# Sat Nov 12 22:58:44 2005 +# +CONFIG_SUPERH=y +CONFIG_UID16=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_IOMAP=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_CLEAN_COMPILE=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +CONFIG_HOTPLUG=y +CONFIG_KOBJECT_UEVENT=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_EMBEDDED is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y + +# +# System type +# +# CONFIG_SH_SOLUTION_ENGINE is not set +# CONFIG_SH_7751_SOLUTION_ENGINE is not set +# CONFIG_SH_7300_SOLUTION_ENGINE is not set +# CONFIG_SH_73180_SOLUTION_ENGINE is not set +# CONFIG_SH_7751_SYSTEMH is not set +# CONFIG_SH_STB1_HARP is not set +# CONFIG_SH_STB1_OVERDRIVE is not set +# CONFIG_SH_HP6XX is not set +# CONFIG_SH_CQREEK is not set +# CONFIG_SH_DMIDA is not set +# CONFIG_SH_EC3104 is not set +# CONFIG_SH_SATURN is not set +# CONFIG_SH_DREAMCAST is not set +# CONFIG_SH_CAT68701 is not set +# CONFIG_SH_BIGSUR is not set +# CONFIG_SH_SH2000 is not set +# CONFIG_SH_ADX is not set +# CONFIG_SH_MPC1211 is not set +# CONFIG_SH_SH03 is not set +# CONFIG_SH_SECUREEDGE5410 is not set +# CONFIG_SH_HS7751RVOIP is not set +# CONFIG_SH_RTS7751R2D is not set +# CONFIG_SH_EDOSK7705 is not set +# CONFIG_SH_SH4202_MICRODEV is not set +# CONFIG_SH_LANDISK is not set +CONFIG_SH_TITAN=y +# CONFIG_SH_UNKNOWN is not set + +# +# Processor selection +# +CONFIG_CPU_SH4=y + +# +# SH-2 Processor Support +# +# CONFIG_CPU_SUBTYPE_SH7604 is not set + +# +# SH-3 Processor Support +# +# CONFIG_CPU_SUBTYPE_SH7300 is not set +# CONFIG_CPU_SUBTYPE_SH7705 is not set +# CONFIG_CPU_SUBTYPE_SH7707 is not set +# CONFIG_CPU_SUBTYPE_SH7708 is not set +# CONFIG_CPU_SUBTYPE_SH7709 is not set + +# +# SH-4 Processor Support +# +# CONFIG_CPU_SUBTYPE_SH7750 is not set +# CONFIG_CPU_SUBTYPE_SH7091 is not set +# CONFIG_CPU_SUBTYPE_SH7750R is not set +# CONFIG_CPU_SUBTYPE_SH7750S is not set +CONFIG_CPU_SUBTYPE_SH7751=y +CONFIG_CPU_SUBTYPE_SH7751R=y +# CONFIG_CPU_SUBTYPE_SH7760 is not set +# CONFIG_CPU_SUBTYPE_SH4_202 is not set + +# +# ST40 Processor Support +# +# CONFIG_CPU_SUBTYPE_ST40STB1 is not set +# CONFIG_CPU_SUBTYPE_ST40GX1 is not set + +# +# SH-4A Processor Support +# +# CONFIG_CPU_SUBTYPE_SH73180 is not set +# CONFIG_CPU_SUBTYPE_SH7770 is not set +# CONFIG_CPU_SUBTYPE_SH7780 is not set + +# +# Memory management options +# +CONFIG_MMU=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 + +# +# Cache configuration +# +# CONFIG_SH_DIRECT_MAPPED is not set +# CONFIG_SH_WRITETHROUGH is not set +# CONFIG_SH_OCRAM is not set +CONFIG_MEMORY_START=0x08030000 +CONFIG_MEMORY_SIZE=0x7fd0000 + +# +# Processor features +# +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_SH_RTC=y +CONFIG_SH_FPU=y +# CONFIG_SH_STORE_QUEUES is not set + +# +# Timer support +# +CONFIG_SH_TMU=y +CONFIG_SH_PCLK_FREQ_BOOL=y +CONFIG_SH_PCLK_FREQ=30000000 + +# +# CPU Frequency scaling +# +# CONFIG_CPU_FREQ is not set + +# +# DMA support +# +CONFIG_SH_DMA=y +CONFIG_NR_ONCHIP_DMA_CHANNELS=8 +# CONFIG_NR_DMA_CHANNELS_BOOL is not set + +# +# Companion Chips +# +# CONFIG_HD6446X_SERIES is not set + +# +# Kernel features +# +# CONFIG_KEXEC is not set +# CONFIG_PREEMPT is not set +# CONFIG_SMP is not set + +# +# Boot options +# +CONFIG_ZERO_PAGE_OFFSET=0x00001000 +CONFIG_BOOT_LINK_OFFSET=0x009e0000 +# CONFIG_UBC_WAKEUP is not set +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="console=ttySC1,38400N81 root=/dev/nfs ip=:::::eth1:autoconf" + +# +# Bus options +# +CONFIG_PCI=y +CONFIG_SH_PCIDMA_NONCOHERENT=y +CONFIG_PCI_AUTO=y +CONFIG_PCI_AUTO_UPDATE_RESOURCES=y +CONFIG_PCI_LEGACY_PROC=y +# CONFIG_PCI_DEBUG is not set + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# PCI Hotplug Support +# +CONFIG_HOTPLUG_PCI=y +# CONFIG_HOTPLUG_PCI_FAKE is not set +# CONFIG_HOTPLUG_PCI_CPCI is not set +# CONFIG_HOTPLUG_PCI_SHPC is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_FLAT is not set +# CONFIG_BINFMT_MISC is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +CONFIG_NET_KEY=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_ASK_IP_FIB_HASH=y +# CONFIG_IP_FIB_TRIE is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_MULTIPLE_TABLES=y +# CONFIG_IP_ROUTE_FWMARK is not set +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_MULTIPATH_CACHED=y +CONFIG_IP_ROUTE_MULTIPATH_RR=m +CONFIG_IP_ROUTE_MULTIPATH_RANDOM=m +CONFIG_IP_ROUTE_MULTIPATH_WRANDOM=m +CONFIG_IP_ROUTE_MULTIPATH_DRR=m +# CONFIG_IP_ROUTE_VERBOSE is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +CONFIG_NET_IPIP=y +CONFIG_NET_IPGRE=y +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_IP_MROUTE=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +CONFIG_INET_AH=y +CONFIG_INET_ESP=y +CONFIG_INET_IPCOMP=y +CONFIG_INET_TUNNEL=y +CONFIG_INET_DIAG=m +CONFIG_INET_TCP_DIAG=m +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_BIC=y + +# +# IP: Virtual Server Configuration +# +# CONFIG_IP_VS is not set +CONFIG_IPV6=y +CONFIG_IPV6_PRIVACY=y +CONFIG_INET6_AH=y +CONFIG_INET6_ESP=y +CONFIG_INET6_IPCOMP=y +CONFIG_INET6_TUNNEL=y +CONFIG_IPV6_TUNNEL=y +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_BRIDGE_NETFILTER=y +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_NETLINK_LOG=m + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +CONFIG_IP_NF_CT_ACCT=y +CONFIG_IP_NF_CONNTRACK_MARK=y +CONFIG_IP_NF_CONNTRACK_EVENTS=y +CONFIG_IP_NF_CONNTRACK_NETLINK=m +# CONFIG_IP_NF_CT_PROTO_SCTP is not set +CONFIG_IP_NF_FTP=m +CONFIG_IP_NF_IRC=m +CONFIG_IP_NF_NETBIOS_NS=m +CONFIG_IP_NF_TFTP=m +# CONFIG_IP_NF_AMANDA is not set +CONFIG_IP_NF_PPTP=m +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_MATCH_IPRANGE=m +CONFIG_IP_NF_MATCH_MAC=m +CONFIG_IP_NF_MATCH_PKTTYPE=m +CONFIG_IP_NF_MATCH_MARK=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_RECENT=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_DSCP=m +CONFIG_IP_NF_MATCH_AH_ESP=m +CONFIG_IP_NF_MATCH_LENGTH=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_MATCH_TCPMSS=m +CONFIG_IP_NF_MATCH_HELPER=m +CONFIG_IP_NF_MATCH_STATE=m +CONFIG_IP_NF_MATCH_CONNTRACK=m +CONFIG_IP_NF_MATCH_OWNER=m +# CONFIG_IP_NF_MATCH_PHYSDEV is not set +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_MATCH_REALM=m +# CONFIG_IP_NF_MATCH_SCTP is not set +# CONFIG_IP_NF_MATCH_DCCP is not set +CONFIG_IP_NF_MATCH_COMMENT=m +CONFIG_IP_NF_MATCH_CONNMARK=m +CONFIG_IP_NF_MATCH_CONNBYTES=m +CONFIG_IP_NF_MATCH_HASHLIMIT=m +CONFIG_IP_NF_MATCH_STRING=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_NF_TARGET_TCPMSS=m +CONFIG_IP_NF_TARGET_NFQUEUE=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_SAME=m +CONFIG_IP_NF_NAT_SNMP_BASIC=m +CONFIG_IP_NF_NAT_IRC=m +CONFIG_IP_NF_NAT_FTP=m +CONFIG_IP_NF_NAT_TFTP=m +CONFIG_IP_NF_NAT_PPTP=m +CONFIG_IP_NF_MANGLE=m +CONFIG_IP_NF_TARGET_TOS=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_DSCP=m +CONFIG_IP_NF_TARGET_MARK=m +CONFIG_IP_NF_TARGET_CLASSIFY=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_TARGET_CONNMARK=m +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_TARGET_NOTRACK=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m + +# +# IPv6: Netfilter Configuration (EXPERIMENTAL) +# +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_LIMIT=m +CONFIG_IP6_NF_MATCH_MAC=m +CONFIG_IP6_NF_MATCH_RT=m +CONFIG_IP6_NF_MATCH_OPTS=m +CONFIG_IP6_NF_MATCH_FRAG=m +CONFIG_IP6_NF_MATCH_HL=m +CONFIG_IP6_NF_MATCH_MULTIPORT=m +CONFIG_IP6_NF_MATCH_OWNER=m +CONFIG_IP6_NF_MATCH_MARK=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_MATCH_AHESP=m +CONFIG_IP6_NF_MATCH_LENGTH=m +CONFIG_IP6_NF_MATCH_EUI64=m +# CONFIG_IP6_NF_MATCH_PHYSDEV is not set +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_TARGET_NFQUEUE=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_TARGET_MARK=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_RAW=m + +# +# Bridge: Netfilter Configuration +# +# CONFIG_BRIDGE_NF_EBTABLES is not set + +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +CONFIG_BRIDGE=y +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_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_CLK_JIFFIES=y +# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set +# CONFIG_NET_SCH_CLK_CPU is not set +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_QOS=y +CONFIG_NET_ESTIMATOR=y +CONFIG_NET_CLS=y +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_U32=m +CONFIG_CLS_U32_PERF=y +CONFIG_NET_CLS_IND=y +CONFIG_CLS_U32_MARK=y +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_STACK=32 +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_EMATCH_NBYTE=m +CONFIG_NET_EMATCH_U32=m +CONFIG_NET_EMATCH_META=m +CONFIG_NET_EMATCH_TEXT=m +CONFIG_NET_CLS_ACT=y +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_GACT=m +CONFIG_GACT_PROB=y +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_PEDIT=m +# CONFIG_NET_ACT_SIMP is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_IEEE80211=y +# CONFIG_IEEE80211_DEBUG is not set +CONFIG_IEEE80211_CRYPT_WEP=y +CONFIG_IEEE80211_CRYPT_CCMP=y +CONFIG_IEEE80211_CRYPT_TKIP=y + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=m +# CONFIG_DEBUG_DRIVER is not set + +# +# Connector - unified userspace <-> kernelspace linker +# +CONFIG_CONNECTOR=m + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=m +CONFIG_MTD_DEBUG=y +CONFIG_MTD_DEBUG_VERBOSE=0 +# CONFIG_MTD_CONCAT is not set +# CONFIG_MTD_PARTITIONS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=m +CONFIG_MTD_BLOCK=m +# CONFIG_MTD_BLOCK_RO is not set +CONFIG_FTL=m +CONFIG_NFTL=m +# CONFIG_NFTL_RW is not set +CONFIG_INFTL=m + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=m +CONFIG_MTD_JEDECPROBE=m +CONFIG_MTD_GEN_PROBE=m +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +# CONFIG_MTD_CFI_INTELEXT is not set +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +# 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_SOLUTIONENGINE 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_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +CONFIG_MTD_NAND=m +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +CONFIG_MTD_NAND_IDS=m +# CONFIG_MTD_NAND_DISKONCHIP is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +CONFIG_BLK_SSFDC=y +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=m +CONFIG_BLK_DEV_CRYPTOLOOP=m +# CONFIG_BLK_DEV_NBD 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=4096 +CONFIG_BLK_DEV_INITRD=y +# CONFIG_LBD is not set +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_ATA_OVER_ETH=m + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=m +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=m +# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_CHR_DEV_SG=m +# 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 + +# +# SCSI Transport Attributes +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set + +# +# SCSI low-level drivers +# +# 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_DPT_I2O is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_SAS is not set +# CONFIG_SCSI_SATA is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_QLOGIC_FC is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +CONFIG_SCSI_QLA2XXX=y +# CONFIG_SCSI_QLA21XX is not set +# CONFIG_SCSI_QLA22XX is not set +# CONFIG_SCSI_QLA2300 is not set +# CONFIG_SCSI_QLA2322 is not set +# CONFIG_SCSI_QLA6312 is not set +# CONFIG_SCSI_QLA24XX 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 + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_SPI is not set +# CONFIG_FUSION_FC is not set +# CONFIG_FUSION_SAS is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +CONFIG_TUN=m + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# PHY device support +# +CONFIG_PHYLIB=m +CONFIG_PHYCONTROL=y + +# +# MII PHY device drivers +# +CONFIG_MARVELL_PHY=m +CONFIG_DAVICOM_PHY=m +CONFIG_QSEMI_PHY=m +CONFIG_LXT_PHY=m +CONFIG_CICADA_PHY=m + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_STNIC 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_SMC91X is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +# CONFIG_NE2000 is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set +# CONFIG_DGRS is not set +# CONFIG_EEPRO100 is not set +# CONFIG_E100 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_8139CP is not set +CONFIG_8139TOO=y +# CONFIG_8139TOO_PIO is not set +CONFIG_8139TOO_TUNE_TWISTER=y +# CONFIG_8139TOO_8129 is not set +CONFIG_8139_OLD_RX_RESET=y +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SIS190 is not set +# CONFIG_SKGE is not set +# CONFIG_SK98LIN is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_CHELSIO_T1 is not set +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +CONFIG_NET_RADIO=y + +# +# Obsolete Wireless cards support (pre-802.11) +# +# CONFIG_STRIP is not set + +# +# Wireless 802.11b ISA/PCI cards support +# +# CONFIG_IPW2100 is not set +# CONFIG_IPW2200 is not set +# CONFIG_HERMES is not set +# CONFIG_ATMEL is not set + +# +# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support +# +CONFIG_PRISM54=m +# CONFIG_HOSTAP is not set +CONFIG_NET_WIRELESS=y + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +CONFIG_PPP=m +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_FILTER=y +CONFIG_PPP_ASYNC=m +CONFIG_PPP_SYNC_TTY=m +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPPOE=m +CONFIG_SLIP=m +CONFIG_SLIP_COMPRESSED=y +CONFIG_SLIP_SMART=y +# CONFIG_SLIP_MODE_SLIP6 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 + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +CONFIG_INPUT_MOUSEDEV=y +# CONFIG_INPUT_MOUSEDEV_PSAUX is not set +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_SH_SCI=y +CONFIG_SERIAL_SH_SCI_CONSOLE=y +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_SH_WDT=m + +# +# PCI-based Watchdog Cards +# +# CONFIG_PCIPCWATCHDOG is not set +# CONFIG_WDTPCI is not set + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set +# CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Hardware Monitoring support +# +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Misc devices +# + +# +# Multimedia Capabilities Port drivers +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Console display driver support +# +CONFIG_DUMMY_CONSOLE=y + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB=y +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_BANDWIDTH is not set +# 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_ISP116X_HCD is not set +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_UHCI_HCD is not set +# CONFIG_USB_SL811_HCD is not set + +# +# USB Device Class drivers +# +CONFIG_USB_BLUETOOTH_TTY=m +CONFIG_USB_ACM=m +CONFIG_USB_PRINTER=m + +# +# 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_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 + +# +# USB Input Devices +# +# CONFIG_USB_HID is not set + +# +# USB HID Boot Protocol drivers +# +# CONFIG_USB_KBD is not set +# CONFIG_USB_MOUSE is not set +# CONFIG_USB_AIPTEK is not set +# CONFIG_USB_WACOM is not set +# CONFIG_USB_ACECAD is not set +# CONFIG_USB_KBTAB is not set +# CONFIG_USB_POWERMATE is not set +# CONFIG_USB_MTOUCH is not set +# CONFIG_USB_ITMTOUCH is not set +# CONFIG_USB_EGALAX is not set +# CONFIG_USB_YEALINK is not set +# CONFIG_USB_XPAD is not set +# CONFIG_USB_ATI_REMOTE is not set +# CONFIG_USB_KEYSPAN_REMOTE is not set +# CONFIG_USB_APPLETOUCH is not set + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB Multimedia devices +# +# CONFIG_USB_DABUSB is not set + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# 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_USB_ZD1201 is not set +CONFIG_USB_MON=y + +# +# USB port drivers +# + +# +# USB Serial Converter support +# +CONFIG_USB_SERIAL=m +CONFIG_USB_SERIAL_GENERIC=y +# CONFIG_USB_SERIAL_AIRPRIME is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# CONFIG_USB_SERIAL_CP2101 is not set +# CONFIG_USB_SERIAL_CYPRESS_M8 is not set +# CONFIG_USB_SERIAL_EMPEG is not set +# CONFIG_USB_SERIAL_FTDI_SIO is not set +# CONFIG_USB_SERIAL_VISOR is not set +# CONFIG_USB_SERIAL_IPAQ is not set +# CONFIG_USB_SERIAL_IR is not set +# CONFIG_USB_SERIAL_EDGEPORT is not set +# CONFIG_USB_SERIAL_EDGEPORT_TI is not set +# CONFIG_USB_SERIAL_GARMIN is not set +# CONFIG_USB_SERIAL_IPW is not set +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +# 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_PL2303=m +# CONFIG_USB_SERIAL_HP4X is not set +# CONFIG_USB_SERIAL_SAFE is not set +# CONFIG_USB_SERIAL_TI is not set +# CONFIG_USB_SERIAL_CYBERJACK is not set +# CONFIG_USB_SERIAL_XIRCOM is not set +# CONFIG_USB_SERIAL_OMNINET is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 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_LED is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGETKIT is not set +# CONFIG_USB_PHIDGETSERVO is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TEST is not set + +# +# USB DSL modem support +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# InfiniBand support +# +# CONFIG_INFINIBAND is not set + +# +# SN Devices +# + +# +# 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_JBD_DEBUG is not set +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_REISERFS_FS_XATTR is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +CONFIG_XFS_FS=m +CONFIG_XFS_EXPORT=y +# 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_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +CONFIG_FUSE_FS=m + +# +# CD-ROM/DVD Filesystems +# +CONFIG_ISO9660_FS=m +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_ZISOFS_FS=m +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_HUGETLBFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y +CONFIG_RELAYFS_FS=m + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_JFFS2_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 is not set +# CONFIG_NFS_DIRECTIO is not set +CONFIG_NFSD=y +CONFIG_NFSD_V3=y +# CONFIG_NFSD_V3_ACL is not set +# CONFIG_NFSD_V4 is not set +CONFIG_NFSD_TCP=y +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +CONFIG_9P_FS=m + +# +# 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_EFI_PARTITION is not set + +# +# Native Language Support +# +CONFIG_NLS=m +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=m +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +CONFIG_NLS_ASCII=m +CONFIG_NLS_ISO8859_1=m +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=m + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +CONFIG_DEBUG_KERNEL=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_LOG_BUF_SHIFT=16 +# CONFIG_DETECT_SOFTLOCKUP is not set +# CONFIG_SCHEDSTATS is not set +# CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set +# CONFIG_DEBUG_KOBJECT is not set +# CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_FRAME_POINTER is not set +# CONFIG_SH_STANDARD_BIOS is not set +CONFIG_EARLY_SCIF_CONSOLE=y +# CONFIG_EARLY_PRINTK is not set +# CONFIG_KGDB is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_DES=y +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_SERPENT=m +CONFIG_CRYPTO_AES=y +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_TEA=m +CONFIG_CRYPTO_ARC4=y +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_DEFLATE=y +CONFIG_CRYPTO_MICHAEL_MIC=y +CONFIG_CRYPTO_CRC32C=m +# CONFIG_CRYPTO_TEST is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +CONFIG_CRC_CCITT=m +CONFIG_CRC16=m +CONFIG_CRC32=y +CONFIG_LIBCRC32C=m +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m diff --git a/packages/linux/linux-titan-sh4-2.6.16/titan-flash.patch b/packages/linux/linux-titan-sh4-2.6.16/titan-flash.patch new file mode 100644 index 0000000000..5a68c4ebed --- /dev/null +++ b/packages/linux/linux-titan-sh4-2.6.16/titan-flash.patch @@ -0,0 +1,3153 @@ + +Add the driver for onboard flash. +The quality of this driver means that it has not been included in the +upstream CVS. +This implements the block device translation layer to match what the +onboard firmware implements. + +diff -durN -X ../diff.ignore linux/drivers/block/Kconfig gcc3.4.4/drivers/block/Kconfig +--- linux/drivers/block/Kconfig 2005-11-09 13:53:31.000000000 +1100 ++++ gcc3.4.4/drivers/block/Kconfig 2005-11-09 14:00:47.000000000 +1100 +@@ -190,6 +190,13 @@ + To compile this driver as a module, choose M here: the + module will be called DAC960. + ++config BLK_SSFDC ++ tristate "SmartMedia(TM) Driver (sm)" ++ depends on SH_TITAN ++ help ++ Say Y here if you want the SmartMedia chip enabled. ++ Otherwise say N. ++ + config BLK_DEV_UMEM + tristate "Micro Memory MM5415 Battery Backed RAM support (EXPERIMENTAL)" + depends on PCI && EXPERIMENTAL +diff -durN -X ../diff.ignore linux/drivers/block/Makefile gcc3.4.4/drivers/block/Makefile +--- linux/drivers/block/Makefile 2004-12-25 08:35:24.000000000 +1100 ++++ gcc3.4.4/drivers/block/Makefile 2005-11-09 14:00:47.000000000 +1100 +@@ -35,6 +35,7 @@ + obj-$(CONFIG_BLK_CPQ_DA) += cpqarray.o + obj-$(CONFIG_BLK_CPQ_CISS_DA) += cciss.o + obj-$(CONFIG_BLK_DEV_DAC960) += DAC960.o ++obj-$(CONFIG_BLK_SSFDC) += ssfdc.o + obj-$(CONFIG_CDROM_PKTCDVD) += pktcdvd.o + + obj-$(CONFIG_BLK_DEV_UMEM) += umem.o +diff -durN -X ../diff.ignore linux/drivers/block/ssfdc.c gcc3.4.4/drivers/block/ssfdc.c +--- linux/drivers/block/ssfdc.c 1970-01-01 10:00:00.000000000 +1000 ++++ gcc3.4.4/drivers/block/ssfdc.c 2005-11-09 14:00:47.000000000 +1100 +@@ -0,0 +1,2738 @@ ++/* $id: $ ++ssfdc.c - Solid State Flopyy Disk Card ++ ++Original source curtesy of Toshiba Corporation. ++ ++Modification for use by Linux provided by Nimble Microsystems Inc. ++ ++TODO: ++ ++Modification History: ++ ++ March 2001 - Initial port of Toshiba sources by Bill Mann ++ May 2001 - Debug of staticly linked ssfdc driver, Bill Mann ++ Nov 2001 - Reimplementation using tasklets and timers. ++ May 2002 - Partition support added. ++ Oct 2003 - Port to kernel 2.6.0 ++ Mar 2004 - Stabilization refinements... ++ ++Overview: The kernel interfaces to the device via the "block_device_operations ++ ssfdc_fops", the device's request handling function ++ "do_ssfdc_request(request_queue_t * q)", or by the ioctl interface ssfdc_ioctl(). ++ ++ do_ssfdc_request() purpose is to kickstart ssfdc_thread via a wake_up call. ssfdc_thread ++ then processes requests from the queue. ++ ++ Blocks are mapped logically. So a sector read/write results in the determination ++ of the logical block address of the block containing the desired sector and the ++ corresponding physical block being accessed. Note the use of ReadBlock, WriteBlock, ++ and PhyBlock, Log2Phy[] etc. ++ ++ This driver implements a wear leveling strategy where sector writes to the ++ SmartMedia causes the block which is the target of the write to be copied into a ++ new block, the new data written and the old block erased. This makes the driver ++ more complicated than a straightforward sector read/write. ++ ++*/ ++ ++/* Section device headers */ ++#define DEBUG_SSFDC 0 ++#define DEBUG_SSFDC_STRUCT 0 ++#define DEBUG_SSFDC_REQUEST 0 ++#define DEBUG_SSFDC_READREDT 0 ++#define DEBUG_SSFDC_WRITE 0 ++#define DEBUG_SSFDC_WRITESECT 0 ++#define DEBUG_SSFDC_WRITEBLKS 0 ++#define DEBUG_SSFDC_READ 0 ++#define DEBUG_SSFDC_ADDR 0 ++#define DEBUG_SSFDC_ASSIGNRELEASE 0 ++#define SSFDC_READINGTASKLET 0 ++/* Edition Compilation Mode */ ++ ++#include <linux/module.h> ++ ++#include <asm/delay.h> ++#include <linux/sched.h> ++#include <linux/interrupt.h> ++ ++#include <linux/fs.h> ++#include <linux/hdreg.h> ++#include <linux/file.h> ++#include <linux/stat.h> ++#include <linux/time.h> ++#include <linux/errno.h> ++#include <linux/major.h> ++#include <linux/init.h> ++#include <linux/devfs_fs_kernel.h> ++#include <asm/uaccess.h> ++#include <asm/hardirq.h> ++#include <linux/bio.h> ++#include <linux/blkdev.h> ++#include <linux/slab.h> ++#include <linux/highmem.h> ++ ++#include "ssfdc.h" ++ ++#define SSFDC_MAJOR 240 ++ ++static int static_ssfdc_debug = 0; ++ ++static DECLARE_WAIT_QUEUE_HEAD(ssfdc_wait); ++ ++static struct gendisk *disks[MAX_SSFDC]; ++static ssfdc_dev *ssfdc[MAX_SSFDC]; ++ ++static int ssfdc_open(struct inode *i_node, struct file *fptr); ++static int ssfdc_release(struct inode *i_node, struct file *fptr); ++static int ssfdc_ioctl(struct inode *i_node, struct file *fptr, unsigned cmd, unsigned long arg); ++static int ssfdc_revalidate(struct gendisk *disk); ++void do_ssfdc_request(request_queue_t * q); ++ ++static struct block_device_operations ssfdc_fops = { ++ .owner = THIS_MODULE, ++ .open = ssfdc_open, ++ .release = ssfdc_release, ++ .ioctl = ssfdc_ioctl, ++ // bjm out .revalidate_disk = ssfdc_revalidate, ++}; ++ ++ ++/*************************************************************************** ++ BIT Control Macro ++ ***************************************************************************/ ++static char BitData[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80 }; ++#define SetBit(a,b) (a[(unsigned char)((b)/8)]|= BitData[(b)%8]) ++#define ClrBit(a,b) (a[(unsigned char)((b)/8)]&=~BitData[(b)%8]) ++#define ChkBit(a,b) (a[(unsigned char)((b)/8)] & BitData[(b)%8]) ++ ++/***************************************************************************/ ++static int MediaReadSector(ssfdc_dev *, struct request *, char *, long,int); ++static int MediaWriteSector(ssfdc_dev *, struct request *, char *, long,int); ++ ++/***************************************************************************/ ++static int CheckLogCHS(ssfdc_dev *,unsigned int *,unsigned char *,unsigned char *); ++static int CheckMediaWP(ssfdc_dev *); ++static int ConvMediaAddr(ssfdc_dev *,long); ++static int IncMediaAddr(ssfdc_dev *); ++static int WriteReqInCurrBlk(ssfdc_dev *, long, int *); ++/******************************************/ ++/******************************************/ ++static int AssignWriteBlock(ssfdc_dev *, int); ++/******************************************/ ++/******************************************/ ++static int SetPhyFmtValue(ssfdc_dev *); ++static int SearchCIS(ssfdc_dev *,unsigned int *); ++static int MakeLogTable(ssfdc_dev *,unsigned int); ++/******************************************/ ++static int MarkFailPhyOneBlock(ssfdc_dev *); ++ ++static void _ReadSsfdcBuf(ssfdc_dev *, unsigned char *databuf,unsigned char *redundant); ++static void _WriteSsfdcBuf(ssfdc_dev *,unsigned char *,unsigned char *); ++static void _ReadSsfdcWord(ssfdc_dev *,unsigned int *); ++static void _ReadRedtSsfdcBuf(ssfdc_dev *, unsigned char *redundant); ++static void _WriteRedtSsfdcBuf(ssfdc_dev*, unsigned char *redundant); ++ ++/***************************************************************************/ ++static void _SetSsfdcCmd(ssfdc_dev *, unsigned char); ++static void _SetSsfdcAddr(ssfdc_dev *, unsigned char); ++static void _SetSsfdcBlock(ssfdc_dev *); ++static void _SetSsfdcChip(ssfdc_dev *); ++static void _SetSsfdcStandby(ssfdc_dev *); ++static int _CheckSsfdcBusy(ssfdc_dev *, unsigned int); ++static int _CheckSsfdcStatus(ssfdc_dev *); ++static void _ResetSsfdcErr(ssfdc_dev *psm); ++static unsigned char _CheckDevCode(unsigned char); ++void SsfdcReset(ssfdc_dev *); ++void CntReset(ssfdc_dev *); ++ ++static char BitCount(unsigned char); ++static char BitCountWord(unsigned int); ++ ++static void _WaitTimer(long int); ++typedef void (*timeout_fn)(unsigned long); ++static void ssfdc_rw_request(ssfdc_dev *psm, struct request *req); ++static int ssfdc_end_request(ssfdc_dev *psm, struct request *req, int status); ++static void ssfdc_terminate_request(ssfdc_dev *psm, struct request *req); ++static struct request *ssfdc_get_request(ssfdc_dev *psm); ++ ++/* debugging utils etc. */ ++ ++#if DEBUG_SSFDC ++static void dump_ssfdc_state(ssfdc_dev * psm); ++#endif ++ ++/* end of debugging utils etc. */ ++ ++/* our tasklets */ ++/* top level R/W initiation tasklet */ ++static void initxfer(unsigned long); ++#if 0 // use thread and not a tasklet ++DECLARE_TASKLET(initxfer_tasklet0, initxfer, 0); ++#ifdef CONFIG_SH_NIMBLE_MINI ++DECLARE_TASKLET(initxfer_tasklet1, initxfer, 1); ++#endif ++#endif ++ ++/* Sector Write Tasklets, This group includes a readcopy tasklet for block copies...*/ ++ ++/* Tasklet to read a sector into a temporary buffer for later write */ ++ ++/* power is turned on, and then left on for TIMER_ON_TIMEOUT */ ++// bjm debug struct timer_list mediachange_timer; ++// bjm debug static void mediachangetest(unsigned long); ++ ++// bjm out ++// bjm out struct timer_list waiting_timer; ++static void waiting_timeout(unsigned long); ++ ++/******************************************************************************/ ++static void trans_result \ ++ (unsigned char,unsigned char,unsigned char *,unsigned char *); ++static void calculate_ecc \ ++ (unsigned char *,unsigned char *,unsigned char *,unsigned char *,unsigned char *); ++static unsigned char correct_data \ ++ (unsigned char *,unsigned char *,unsigned char,unsigned char,unsigned char); ++ ++ /* CP0-CP5 code table */ ++static unsigned char ecctable[256] = { ++ 0x00,0x55,0x56,0x03,0x59,0x0C,0x0F,0x5A,0x5A,0x0F,0x0C,0x59,0x03,0x56,0x55,0x00, ++ 0x65,0x30,0x33,0x66,0x3C,0x69,0x6A,0x3F,0x3F,0x6A,0x69,0x3C,0x66,0x33,0x30,0x65, ++ 0x66,0x33,0x30,0x65,0x3F,0x6A,0x69,0x3C,0x3C,0x69,0x6A,0x3F,0x65,0x30,0x33,0x66, ++ 0x03,0x56,0x55,0x00,0x5A,0x0F,0x0C,0x59,0x59,0x0C,0x0F,0x5A,0x00,0x55,0x56,0x03, ++ 0x69,0x3C,0x3F,0x6A,0x30,0x65,0x66,0x33,0x33,0x66,0x65,0x30,0x6A,0x3F,0x3C,0x69, ++ 0x0C,0x59,0x5A,0x0F,0x55,0x00,0x03,0x56,0x56,0x03,0x00,0x55,0x0F,0x5A,0x59,0x0C, ++ 0x0F,0x5A,0x59,0x0C,0x56,0x03,0x00,0x55,0x55,0x00,0x03,0x56,0x0C,0x59,0x5A,0x0F, ++ 0x6A,0x3F,0x3C,0x69,0x33,0x66,0x65,0x30,0x30,0x65,0x66,0x33,0x69,0x3C,0x3F,0x6A, ++ 0x6A,0x3F,0x3C,0x69,0x33,0x66,0x65,0x30,0x30,0x65,0x66,0x33,0x69,0x3C,0x3F,0x6A, ++ 0x0F,0x5A,0x59,0x0C,0x56,0x03,0x00,0x55,0x55,0x00,0x03,0x56,0x0C,0x59,0x5A,0x0F, ++ 0x0C,0x59,0x5A,0x0F,0x55,0x00,0x03,0x56,0x56,0x03,0x00,0x55,0x0F,0x5A,0x59,0x0C, ++ 0x69,0x3C,0x3F,0x6A,0x30,0x65,0x66,0x33,0x33,0x66,0x65,0x30,0x6A,0x3F,0x3C,0x69, ++ 0x03,0x56,0x55,0x00,0x5A,0x0F,0x0C,0x59,0x59,0x0C,0x0F,0x5A,0x00,0x55,0x56,0x03, ++ 0x66,0x33,0x30,0x65,0x3F,0x6A,0x69,0x3C,0x3C,0x69,0x6A,0x3F,0x65,0x30,0x33,0x66, ++ 0x65,0x30,0x33,0x66,0x3C,0x69,0x6A,0x3F,0x3F,0x6A,0x69,0x3C,0x66,0x33,0x30,0x65, ++ 0x00,0x55,0x56,0x03,0x59,0x0C,0x0F,0x5A,0x5A,0x0F,0x0C,0x59,0x03,0x56,0x55,0x00 ++}; ++ ++#define BIT7 0x80 ++#define BIT6 0x40 ++#define BIT5 0x20 ++#define BIT4 0x10 ++#define BIT3 0x08 ++#define BIT2 0x04 ++#define BIT1 0x02 ++#define BIT0 0x01 ++ ++#define BIT1BIT0 0x03 ++#define BIT23 0x00800000L ++#define MASK_CPS 0x3f ++#define CORRECTABLE 0x00555554L ++ ++/* ++ Transfer result ++ LP14,12,10,... & LP15,13,11,... -> LP15,14,13,... & LP7,6,5,.. ++*/ ++static void trans_result(reg2,reg3,ecc1,ecc2) ++unsigned char reg2; /* LP14,LP12,LP10,... */ ++unsigned char reg3; /* LP15,LP13,LP11,... */ ++unsigned char *ecc1; /* LP15,LP14,LP13,... */ ++unsigned char *ecc2; /* LP07,LP06,LP05,... */ ++{ ++ unsigned char a; /* Working for reg2,reg3 */ ++ unsigned char b; /* Working for ecc1,ecc2 */ ++ unsigned char i; /* For counting */ ++ ++ a=BIT7; b=BIT7; /* 80h=10000000b */ ++ *ecc1=*ecc2=0; /* Clear ecc1,ecc2 */ ++ for(i=0; i<4; ++i) { ++ if ((reg3&a)!=0) *ecc1|=b; /* LP15,13,11,9 -> ecc1 */ ++ b=b>>1; /* Right shift */ ++ if ((reg2&a)!=0) *ecc1|=b; /* LP14,12,10,8 -> ecc1 */ ++ b=b>>1; /* Right shift */ ++ a=a>>1; /* Right shift */ ++ } ++ b=BIT7; /* 80h=10000000b */ ++ for(i=0; i<4; ++i) { ++ if ((reg3&a)!=0) *ecc2|=b; /* LP7,5,3,1 -> ecc2 */ ++ b=b>>1; /* Right shift */ ++ if ((reg2&a)!=0) *ecc2|=b; /* LP6,4,2,0 -> ecc2 */ ++ b=b>>1; /* Right shift */ ++ a=a>>1; /* Right shift */ ++ } ++} ++ ++ ++/* ++ Calculating ECC ++ data[0-255] -> ecc1,ecc2,ecc3 using CP0-CP5 code table[0-255] ++*/ ++static void calculate_ecc(table,data,ecc1,ecc2,ecc3) ++unsigned char *table; /* CP0-CP5 code table */ ++unsigned char *data; /* DATA */ ++unsigned char *ecc1; /* LP15,LP14,LP13,... */ ++unsigned char *ecc2; /* LP07,LP06,LP05,... */ ++unsigned char *ecc3; /* CP5,CP4,CP3,...,"1","1" */ ++{ ++ unsigned int i; /* For counting */ ++ unsigned char a; /* Working for table */ ++ unsigned char reg1; /* D-all,CP5,CP4,CP3,... */ ++ unsigned char reg2; /* LP14,LP12,L10,... */ ++ unsigned char reg3; /* LP15,LP13,L11,... */ ++ ++ reg1=reg2=reg3=0; /* Clear parameter */ ++ ++ for(i=0; i<256; ++i) { ++ a=table[data[i]]; /* Get CP0-CP5 code from table */ ++ reg1^=(a&MASK_CPS); /* XOR with a */ ++ if ((a&BIT6)!=0) { /* If D_all(all bit XOR) = 1 */ ++ reg3^=(unsigned char)i; /* XOR with counter */ ++ reg2^=~((unsigned char)i); /* XOR with inv. of counter */ ++ } ++ } ++ ++ /* Trans LP14,12,10,... & LP15,13,11,... -> LP15,14,13,... & LP7,6,5,.. */ ++ trans_result(reg2,reg3,ecc1,ecc2); ++ ++ *ecc1=~(*ecc1); *ecc2=~(*ecc2); /* Inv. ecc2 & ecc3 */ ++ *ecc3=((~reg1)<<2)|BIT1BIT0; /* Make TEL format */ ++} ++ ++static unsigned char correct_data(data,eccdata,ecc1,ecc2,ecc3) ++unsigned char *data; /* DATA */ ++unsigned char *eccdata; /* ECC DATA */ ++unsigned char ecc1; /* LP15,LP14,LP13,... */ ++unsigned char ecc2; /* LP07,LP06,LP05,... */ ++unsigned char ecc3; /* CP5,CP4,CP3,...,"1","1" */ ++{ ++ unsigned long l; /* Working to check d */ ++ unsigned long d; /* Result of comparison */ ++ unsigned int i; /* For counting */ ++ unsigned char d1,d2,d3; /* Result of comparison */ ++ unsigned char a; /* Working for add */ ++ unsigned char add; /* Byte address of cor. DATA */ ++ unsigned char b; /* Working for bit */ ++ unsigned char bit; /* Bit address of cor. DATA */ ++ ++ d1=ecc1^eccdata[1]; d2=ecc2^eccdata[0]; /* Compare LP's */ ++ d3=ecc3^eccdata[2]; /* Comapre CP's */ ++ d=((unsigned long)d1<<16) /* Result of comparison */ ++ +((unsigned long)d2<<8) ++ +(unsigned long)d3; ++ ++ if (d==0) return(0); /* If No error, return */ ++ if (((d^(d>>1))&CORRECTABLE)==CORRECTABLE) { /* If correctable */ ++ l=BIT23; ++ add=0; /* Clear parameter */ ++ a=BIT7; ++ for(i=0; i<8; ++i) { /* Checking 8 bit */ ++ if ((d&l)!=0) add|=a; /* Make byte address from LP's */ ++ l>>=2; a>>=1; /* Right Shift */ ++ } ++ bit=0; /* Clear parameter */ ++ b=BIT2; ++ for(i=0; i<3; ++i) { /* Checking 3 bit */ ++ if ((d&l)!=0) bit|=b; /* Make bit address from CP's */ ++ l>>=2; b>>=1; /* Right shift */ ++ } ++ b=BIT0; ++ data[add]^=(b<<bit); /* Put corrected data */ ++ return(1); ++ } ++ i=0; /* Clear count */ ++ d&=0x00ffffffL; /* Masking */ ++ while(d) { /* If d=0 finish counting */ ++ if (d&BIT0) ++i; /* Count number of 1 bit */ ++ d>>=1; /* Right shift */ ++ } ++ if (i==1) { /* If ECC error */ ++ eccdata[1]=ecc1; eccdata[0]=ecc2; /* Put right ECC code */ ++ eccdata[2]=ecc3; ++ return(2); ++ } ++ return(3); /* Uncorrectable error */ ++} ++/*************************************************************************** ++ Common Subroutine ++ ***************************************************************************/ ++char BitCount(unsigned char cdata) ++{ ++ char bitcount=0; ++ while(cdata) { ++ bitcount+=(cdata &0x01); ++ cdata /=2; ++ } ++ return(bitcount); ++} ++ ++char BitCountWord(unsigned int cdata) ++{ ++ char bitcount=0; ++ while(cdata) { ++ bitcount+=(cdata &0x01); ++ cdata /=2; ++ } ++ return(bitcount); ++} ++ ++/***************************************************************************/ ++void StringCopy(char *stringA, char *stringB, int count) ++{ ++ int i; ++ for(i=0; i<count; i++) ++ *stringA++ = *stringB++; ++} ++ ++int StringCmp(char *stringA, char *stringB, int count) ++{ ++ int i; ++ for (i=0;i<count;i++) ++ if (*stringA++ != *stringB++) return(ERROR); ++ return(SUCCESS); ++} ++/***************************************************************************/ ++int CheckDataBlank(unsigned char *redundant) ++{ ++ char i; ++ for(i=0; i<REDTSIZE; i++) ++ if(*redundant++!=0xFF) return(ERROR); ++ return(SUCCESS); ++} ++ ++int CheckFailBlock(unsigned char *redundant) ++{ ++ redundant+=REDT_BLOCK; ++ if(*redundant==0xFF) return(SUCCESS); ++ if(! *redundant) return(ERROR); ++ if(BitCount(*redundant)<7) return(ERROR); ++ return(SUCCESS); ++} ++ ++int CheckCisBlock(unsigned char *redundant) ++{ ++ if(! (*(redundant+REDT_ADDR1H)|*(redundant+REDT_ADDR1L))) ++ return(SUCCESS); ++ if(! (*(redundant+REDT_ADDR2H)|*(redundant+REDT_ADDR2L))) ++ return(SUCCESS); ++ return(ERROR); ++} ++ ++int CheckDataStatus(unsigned char *redundant) ++{ ++ redundant+=REDT_DATA; ++ if(*redundant==0xFF) return(SUCCESS); ++ if(! *redundant) return(ERROR); ++ if(BitCount(*redundant)<5) return(ERROR); ++ return(SUCCESS); ++} ++ ++int LoadLogBlockAddr(ssfdc_dev *psm) ++{ ++ unsigned int addr1,addr2; ++ addr1=*(psm->Redundant+REDT_ADDR1H)*0x100+*(psm->Redundant+REDT_ADDR1L); ++ addr2=*(psm->Redundant+REDT_ADDR2H)*0x100+*(psm->Redundant+REDT_ADDR2L); ++ if(addr1==addr2) ++ if((addr1 &0xF000)==0x1000) ++ { psm->LogBlock=(addr1 &0x0FFF)/2; return(SUCCESS); } ++ if(BitCountWord(addr1^addr2)>1) return(ERROR); ++ if((addr1 &0xF000)==0x1000) ++ if(! (BitCountWord(addr1) &0x0001)) ++ { psm->LogBlock=(addr1 &0x0FFF)/2; return(SUCCESS); } ++ if((addr2 &0xF000)==0x1000) ++ if(! (BitCountWord(addr2) &0x0001)) ++ { psm->LogBlock=(addr2 &0x0FFF)/2; return(SUCCESS); } ++ return(ERROR); ++} ++/***************************************************************************/ ++void ClrRedundantData(unsigned char *redundant) ++{ ++ char i; ++ for(i=0; i<REDTSIZE; i++) *(redundant+i)=0xFF; ++} ++ ++/***************************************************************************/ ++void SetLogBlockAddr(ssfdc_dev *psm, unsigned char *redundant) ++{ ++ unsigned int addr; ++ *(redundant+REDT_BLOCK)=0xFF; ++ *(redundant+REDT_DATA) =0xFF; ++ addr=psm->LogBlock*2+0x1000; ++ if((BitCountWord(addr)%2)) addr++; ++ *(redundant+REDT_ADDR1H)=*(redundant+REDT_ADDR2H)=addr/0x100; ++ *(redundant+REDT_ADDR1L)=*(redundant+REDT_ADDR2L)=(unsigned char)addr; ++} ++ ++void SetFailBlock(unsigned char *redundant) ++{ ++ char i; ++ for(i=0; i<REDTSIZE; i++) ++ *redundant++=((i==REDT_BLOCK)?0xF0:0xFF); ++} ++ ++void SetDataStatus(unsigned char *redundant) ++{ ++ redundant+=REDT_DATA; ++ *redundant=0x00; ++} ++ ++ ++/*************************************************************************** ++ NAND Memory (SmartMedia) Control Subroutine ++ ***************************************************************************/ ++static void _SetSsfdcCmd(ssfdc_dev *psm, unsigned char cmd) ++{ ++ _HwSetCmd(psm); ++ _HwOutData(psm,cmd); ++ _HwSetData(psm); ++} ++ ++static void _SetSsfdcAddr(ssfdc_dev *psm, unsigned char add) ++{ ++ unsigned int addr; ++ ++#if DEBUG_SSFDC_ADDR ++ printk(KERN_DEBUG "_SetSsfdcAddr() Zone %d LogBlock %d PhyBlock %d Sector %d\n", ++ psm->Zone,psm->LogBlock,psm->PhyBlock,psm->Sector); ++#endif ++ addr=(unsigned int)psm->Zone*psm->MaxBlocks+psm->PhyBlock; ++ addr=addr*(unsigned int)psm->MaxSectors+psm->Sector; ++ if((psm->Attribute &MPS)==PS256) /* for 256byte/page */ ++ addr=addr*2+(unsigned int)add; ++/*-----------------------------------------------*/ ++ _HwSetAddr(psm); ++ _HwOutData(psm,0x00); ++ _HwOutData(psm,(unsigned char)addr); ++ _HwOutData(psm,(unsigned char)(addr/0x0100)); ++ if((psm->Attribute &MADC)==AD4CYC) ++ _HwOutData(psm,(unsigned char)(psm->Zone/2)); /* Patch */ ++ _HwSetData(psm); ++} ++ ++static void _SetSsfdcBlock(ssfdc_dev *psm) ++{ ++ unsigned int addr; ++#if DEBUG_SSFDC_ASSIGNRELEASE ++ printk(KERN_DEBUG "_SetSsfdcBlock() set card addr to PhyBlock %d\n", psm->PhyBlock); ++#endif ++ addr=(unsigned int)psm->Zone*psm->MaxBlocks+psm->PhyBlock; ++ addr=addr*(unsigned int)psm->MaxSectors; ++ if((psm->Attribute &MPS)==PS256) /* for 256byte/page */ ++ addr=addr*2; ++/*-----------------------------------------------*/ ++ _HwSetAddr(psm); ++ _HwOutData(psm,(unsigned char)addr); ++ _HwOutData(psm,(unsigned char)(addr/0x0100)); ++ if((psm->Attribute &MADC)==AD4CYC) ++ _HwOutData(psm,(unsigned char)(psm->Zone/2)); /* Patch */ ++ _HwSetData(psm); ++} ++ ++static inline void _SetSsfdcStandby(ssfdc_dev *psm) ++{ ++ _HwSetStandby(psm); ++} ++ ++static int _CheckSsfdcStatus(ssfdc_dev *psm) ++{ ++ int status; ++ if((status=_HwInData(psm)) & WR_FAIL) { ++ printk(KERN_DEBUG "_CheckSsfdcStatus() error %x\n", status); ++ return(ERROR); ++ } ++ return(SUCCESS); ++} ++ ++static void _ResetSsfdcErr(ssfdc_dev *psm) ++{ ++ _HwSetCmd(psm); ++ _HwOutData(psm,SSFDC_RST_CHIP); ++ _HwSetData(psm); ++ while(1) { ++ udelay(30); ++ if(! _HwChkBusy(psm)) break; ++ } ++ _HwSetStandby(psm); ++} ++ ++static void waiting_timeout(unsigned long psm) ++{ ++ // enable the wakeup signal! ++ wake_up(&((ssfdc_dev *)psm)->thread_wq); ++} ++ ++/* ++ _CheckSsfdcBusy() ++ ++ set a timer in jiffies from int time x .1ms ++*/ ++ ++static int _CheckSsfdcBusy(ssfdc_dev *psm, unsigned int time) ++{ ++ unsigned long incr_div = 4; ++ unsigned long incr_us = time / incr_div, ++ jticks=time/(MSEC * JIFFY_TICK_MS); ++ unsigned long tick_retried=0, wrap_flag, expires; ++ ++ if (!jticks) { ++ // small delay first to test completion ++ do { ++ udelay(incr_us); ++ if (!_HwChkBusy(psm)) ++ return(SUCCESS); ++ } while (incr_div--); ++ return(ERROR); ++ } ++ ++ // Block the wakeup signal? ++ ++one_more_time: ++ expires = jiffies + jticks; ++ wrap_flag = ( expires < jiffies); ++ ++ do { ++ wait_event_interruptible_timeout(psm->thread_wq, 0, jticks); ++ if (!_HwChkBusy(psm)) { ++ return(SUCCESS); ++ } ++ } while (wrap_flag ? expires <= jiffies : expires >= jiffies); ++ ++#if 1 ++ // Is the chip not busy? If so its an ERROR ++ if (!_HwChkBusy(psm)) { ++ return(SUCCESS); ++ } ++ else { ++ // if we came back, give us one more tick/time ++ if (! tick_retried ) { ++ tick_retried = 1; ++ jticks = 0; ++ printk("."); ++ goto one_more_time; ++ } ++ return(ERROR); ++ } ++#endif ++} ++ ++static void _SetSsfdcChip(ssfdc_dev *psm) ++{ ++ _HwSetAddr(psm); ++ _HwOutData(psm,0x00); ++ _HwSetData(psm); ++} ++/*************************************************************************** ++ NAND Memory (SmartMedia) Buffer Data Xfer Subroutine ++ ***************************************************************************/ ++static void _ReadSsfdcBuf(ssfdc_dev *psm,unsigned char *databuf,unsigned char *redundant) ++{ ++ int i; ++ for(i=0x00;i<(((psm->Attribute &MPS)==PS256)?0x100:0x200);i++) ++ *databuf++ =_HwInData(psm); ++ for(i=0x00;i<(((psm->Attribute &MPS)==PS256)?0x08:0x10);i++) ++ *redundant++ =_HwInData(psm); ++} ++ ++static void _WriteSsfdcBuf(ssfdc_dev *psm, unsigned char *databuf,unsigned char *redundant) ++{ ++ int i; ++ for(i=0x00;i<(((psm->Attribute &MPS)==PS256)?0x100:0x200);i++) ++ _HwOutData(psm,*databuf++); ++ for(i=0x00;i<(((psm->Attribute &MPS)==PS256)?0x08:0x10);i++) ++ _HwOutData(psm,*redundant++); ++} ++ ++static void _ReadSsfdcWord(ssfdc_dev *psm, unsigned int *pdata) ++{ ++ *pdata =_HwInData(psm)*0x100; ++ *pdata|=(unsigned char)_HwInData(psm); ++} ++ ++static void _ReadRedtSsfdcBuf(ssfdc_dev *psm,unsigned char *redundant) ++{ ++ int i; ++ for(i=0x00;i<(((psm->Attribute &MPS)==PS256)?0x08:0x10);i++) ++ redundant[i] =_HwInData(psm); ++} ++ ++static void _WriteRedtSsfdcBuf(ssfdc_dev *psm, unsigned char *redundant) ++{ ++ char i; ++ for(i=0x00;i<(((psm->Attribute &MPS)==PS256)?0x08:0x10);i++) ++ _HwOutData(psm,*redundant++); ++} ++ ++/*************************************************************************** ++ Timer Control Subroutine ++ ***************************************************************************/ ++#define SHORT_DELAY 1 ++ ++ ++ ++ ++void _GetDateTime(char *date) ++{ ++} ++ ++/* ++_WaitTimer(long time) time is in ticks. ++*/ ++ ++static inline void _WaitTimer(long time) ++{ ++} ++ ++/*************************************************************************** ++ SmartMedia Function Command Subroutine ++ ***************************************************************************/ ++void SsfdcReset(ssfdc_dev *psm) ++{ ++ _SetSsfdcCmd(psm, SSFDC_RST_CHIP); ++ _CheckSsfdcBusy(psm,BUSY_RESET); ++ _SetSsfdcCmd(psm,SSFDC_READ); ++ _CheckSsfdcBusy(psm,BUSY_READ); ++ _SetSsfdcStandby(psm); ++} ++ ++void SsfdcWriteRedtMode(ssfdc_dev *psm) ++{ ++ _SetSsfdcCmd(psm,SSFDC_RST_CHIP); ++ _CheckSsfdcBusy(psm,BUSY_RESET); ++ _SetSsfdcCmd(psm,SSFDC_READ_REDT); ++ _CheckSsfdcBusy(psm,BUSY_READ); ++ _SetSsfdcStandby(psm); ++} ++ ++void SsfdcReadID(ssfdc_dev *psm, unsigned int *pid) ++{ ++ _SetSsfdcCmd(psm,SSFDC_READ_ID); ++ _SetSsfdcChip(psm); ++ _ReadSsfdcWord(psm,pid); ++ _SetSsfdcStandby(psm); ++} ++ ++int SsfdcCheckStatus(ssfdc_dev *psm) ++{ ++ _SetSsfdcCmd(psm,SSFDC_RDSTATUS); ++ if(_CheckSsfdcStatus(psm)) ++ { _SetSsfdcStandby(psm); return(ERROR); } ++ _SetSsfdcStandby(psm); ++ return(SUCCESS); ++} ++ ++int SsfdcReadSect(ssfdc_dev *psm, unsigned char *buf,unsigned char *redundant) ++{ ++#if DEBUG_SSFDC_READ ++ printk(KERN_DEBUG "SsfdcReadSect() - Zone %d LogBlock %d, PhyBlock %d, Sector %d\n", ++ psm->Zone, psm->LogBlock, psm->PhyBlock, psm->Sector); ++#endif ++ _SetSsfdcCmd(psm,SSFDC_READ); ++ _SetSsfdcAddr(psm, EVEN); ++ if(_CheckSsfdcBusy(psm,BUSY_READ)) ++ { _ResetSsfdcErr(psm); return(ERROR); } ++ _ReadSsfdcBuf(psm,buf,redundant); ++ if(_CheckSsfdcBusy(psm,BUSY_READ)) ++ { _ResetSsfdcErr(psm); return(ERROR); } ++ if((psm->Attribute &MPS)==PS256) { ++ _SetSsfdcCmd(psm,SSFDC_READ); ++ _SetSsfdcAddr(psm, ODD); ++ if(_CheckSsfdcBusy(psm,BUSY_READ)) ++ { _ResetSsfdcErr(psm); return(ERROR); } ++ _ReadSsfdcBuf(psm,buf+0x100,redundant+0x08); ++ if(_CheckSsfdcBusy(psm,BUSY_READ)) ++ { _ResetSsfdcErr(psm); return(ERROR); } ++ } ++ _SetSsfdcStandby(psm); ++ return(SUCCESS); ++} ++ ++int SsfdcWriteSect(ssfdc_dev *psm, unsigned char *buf, unsigned char *redundant) ++{ ++#if DEBUG_SSFDC_WRITESECT ++ printk(KERN_DEBUG "SsfdcWriteSect() - Zone %d LogBlock %d, PhyBlock %d, Sector %d\n", \ ++ psm->Zone, psm->LogBlock, psm->PhyBlock, psm->Sector); ++#endif ++ _SetSsfdcCmd(psm,SSFDC_WRDATA); ++ _SetSsfdcAddr(psm,EVEN); ++ _WriteSsfdcBuf(psm,buf,redundant); ++ _SetSsfdcCmd(psm,SSFDC_WRITE); ++ if(_CheckSsfdcBusy(psm,BUSY_PROG)) ++ { _ResetSsfdcErr(psm); ++#if DEBUG_SSFDC_WRITESECT ++ printk(KERN_DEBUG "SsfdcWriteSect() e 1\n"); ++#endif ++ return(ERROR); } ++ if((psm->Attribute &MPS)==PS256) { ++ _SetSsfdcCmd(psm,SSFDC_RDSTATUS); ++ if(_CheckSsfdcStatus(psm)) ++ { _SetSsfdcStandby(psm); return(SUCCESS); } ++ _SetSsfdcCmd(psm,SSFDC_WRDATA); ++ _SetSsfdcAddr(psm,ODD); ++ _WriteSsfdcBuf(psm,buf+0x100,redundant+0x08); ++ _SetSsfdcCmd(psm,SSFDC_WRITE); ++ if(_CheckSsfdcBusy(psm,BUSY_PROG)) ++ { _ResetSsfdcErr(psm); ++#if DEBUG_SSFDC_WRITESECT ++ printk(KERN_DEBUG "SsfdcWriteSect() e 2\n"); ++#endif ++ return(ERROR); } ++ } ++ _SetSsfdcStandby(psm); ++ return(SUCCESS); ++} ++ ++int SsfdcEraseBlock(ssfdc_dev *psm) ++{ ++ _SetSsfdcCmd(psm,SSFDC_ERASE1); ++ _SetSsfdcBlock(psm); ++ _SetSsfdcCmd(psm,SSFDC_ERASE2); ++ if(_CheckSsfdcBusy(psm,BUSY_ERASE) || SsfdcCheckStatus(psm)) { ++ _ResetSsfdcErr(psm); ++ return(ERROR); ++ } ++ _SetSsfdcStandby(psm); ++ return(SUCCESS); ++} ++ ++int SsfdcReadRedtData(ssfdc_dev *psm, unsigned char *redundant) ++{ ++#if DEBUG_SSFDC_READREDT ++ printk(KERN_DEBUG " +"); ++#endif ++ _SetSsfdcCmd(psm,SSFDC_READ_REDT); ++ _SetSsfdcAddr(psm,EVEN); ++ if(_CheckSsfdcBusy(psm,BUSY_READ)) ++ { _ResetSsfdcErr(psm); ++#if DEBUG_SSFDC_READREDT ++ printk(KERN_DEBUG " e 1\n"); ++#endif ++ return(ERROR); } ++ _ReadRedtSsfdcBuf(psm, redundant); ++ if(_CheckSsfdcBusy(psm,BUSY_READ)) ++ { _ResetSsfdcErr(psm); ++#if DEBUG_SSFDC_READREDT ++ printk(KERN_DEBUG " e 2\n"); ++#endif ++ return(ERROR); } ++ if((psm->Attribute &MPS)==PS256) { ++ _SetSsfdcCmd(psm,SSFDC_READ_REDT); ++ _SetSsfdcAddr(psm,ODD); ++ if(_CheckSsfdcBusy(psm,BUSY_READ)) ++ { _ResetSsfdcErr(psm); ++#if DEBUG_SSFDC_READREDT ++ printk(KERN_DEBUG " e 3\n"); ++#endif ++ ++ return(ERROR); } ++ _ReadRedtSsfdcBuf(psm, redundant+0x08); ++ if(_CheckSsfdcBusy(psm,BUSY_READ)) ++ { _ResetSsfdcErr(psm); ++#if DEBUG_SSFDC_READREDT ++ printk(KERN_DEBUG " e 4\n"); ++#endif ++ return(ERROR); } ++ } ++ _SetSsfdcStandby(psm); ++#if DEBUG_SSFDC_READREDT ++ printk(KERN_DEBUG " -\n"); ++#endif ++ return(SUCCESS); ++} ++ ++int SsfdcWriteRedtData(ssfdc_dev *psm, unsigned char *redundant) ++{ ++ _SetSsfdcCmd(psm,SSFDC_WRDATA); ++ _SetSsfdcAddr(psm,EVEN); ++ _WriteRedtSsfdcBuf(psm,redundant); ++ _SetSsfdcCmd(psm,SSFDC_WRITE); ++ if(_CheckSsfdcBusy(psm,BUSY_PROG)) ++ { _ResetSsfdcErr(psm); return(ERROR); } ++ if((psm->Attribute &MPS)==PS256) { ++ _SetSsfdcCmd(psm,SSFDC_RDSTATUS); ++ if(_CheckSsfdcStatus(psm)) ++ { _SetSsfdcStandby(psm); return(SUCCESS); } ++ _SetSsfdcCmd(psm,SSFDC_WRDATA); ++ _SetSsfdcAddr(psm,ODD); ++ _WriteRedtSsfdcBuf(psm,redundant+0x08); ++ _SetSsfdcCmd(psm,SSFDC_WRITE); ++ if(_CheckSsfdcBusy(psm,BUSY_PROG)) ++ { _ResetSsfdcErr(psm); return(ERROR); } ++ } ++ _SetSsfdcStandby(psm); ++ return(SUCCESS); ++} ++ ++/*************************************************************************** ++ SmartMedia ID Code Check & Mode Set Subroutine ++ ***************************************************************************/ ++int SetSsfdcModel(ssfdc_dev *psm, unsigned char dcode) ++{ ++ switch(_CheckDevCode(dcode)) { ++ case SSFDC1MB: ++ psm->Model = SSFDC1MB; ++ psm->Attribute = FLASH | AD3CYC | BS16 | PS256; ++ psm->MaxZones = 1; ++ psm->MaxBlocks = 256; ++ psm->MaxLogBlocks = 250; ++ psm->MaxSectors = 8; ++ break; ++ case SSFDC2MB: ++ psm->Model = SSFDC2MB; ++ psm->Attribute = FLASH | AD3CYC | BS16 | PS256; ++ psm->MaxZones = 1; ++ psm->MaxBlocks = 512; ++ psm->MaxLogBlocks = 500; ++ psm->MaxSectors = 8; ++ break; ++ case SSFDC4MB: ++ psm->Model = SSFDC4MB; ++ psm->Attribute = FLASH | AD3CYC | BS16 | PS512; ++ psm->MaxZones = 1; ++ psm->MaxBlocks = 512; ++ psm->MaxLogBlocks = 500; ++ psm->MaxSectors = 16; ++ break; ++ case SSFDC8MB: ++ psm->Model = SSFDC8MB; ++ psm->Attribute = FLASH | AD3CYC | BS16 | PS512; ++ psm->MaxZones = 1; ++ psm->MaxBlocks = 1024; ++ psm->MaxLogBlocks = 1000; ++ psm->MaxSectors = 16; ++ break; ++ case SSFDC16MB: ++ psm->Model = SSFDC16MB; ++ psm->Attribute = FLASH | AD3CYC | BS32 | PS512; ++ psm->MaxZones = 1; ++ psm->MaxBlocks = 1024; ++ psm->MaxLogBlocks = 1000; ++ psm->MaxSectors = 32; ++ break; ++ case SSFDC32MB: ++ psm->Model = SSFDC32MB; ++ psm->Attribute = FLASH | AD3CYC | BS32 | PS512; ++ psm->MaxZones = 2; ++ psm->MaxBlocks = 1024; ++ psm->MaxLogBlocks = 1000; ++ psm->MaxSectors = 32; ++ break; ++ case SSFDC64MB: ++ psm->Model = SSFDC64MB; ++ psm->Attribute = FLASH | AD4CYC | BS32 | PS512; ++ psm->MaxZones = 4; ++ psm->MaxBlocks = 1024; ++ psm->MaxLogBlocks = 1000; ++ psm->MaxSectors = 32; ++ break; ++ case SSFDC128MB: ++ psm->Model = SSFDC128MB; ++ psm->Attribute = FLASH | AD4CYC | BS32 | PS512; ++ psm->MaxZones = 8; ++ psm->MaxBlocks = 1024; ++ psm->MaxLogBlocks = 1000; ++ psm->MaxSectors = 32; ++ break; ++ default: ++ psm->Model = NOSSFDC; ++ return(ERROR); ++ } ++ return(SUCCESS); ++} ++ ++/***************************************************************************/ ++static unsigned char _CheckDevCode(unsigned char dcode) ++{ ++ switch(dcode){ ++ case 0x6E: ++ case 0xE8: ++ case 0xEC: return(SSFDC1MB); /* 8Mbit (1M) NAND */ ++ case 0x64: ++ case 0xEA: return(SSFDC2MB); /* 16Mbit (2M) NAND */ ++ case 0x6B: ++ case 0xE3: ++ case 0xE5: return(SSFDC4MB); /* 32Mbit (4M) NAND */ ++ case 0xE6: return(SSFDC8MB); /* 64Mbit (8M) NAND */ ++ case 0x73: return(SSFDC16MB); /*128Mbit (16M)NAND */ ++ case 0x75: return(SSFDC32MB); /*256Mbit (32M)NAND */ ++ case 0x76: return(SSFDC64MB); /*512Mbit (64M)NAND */ ++ case 0x79: return(SSFDC128MB); /* 1Gbit(128M)NAND */ ++ default: return(ERROR); ++ } ++} ++/*************************************************************************** ++ SmartMedia Power Control Subroutine ++ ***************************************************************************/ ++void CntReset(ssfdc_dev *psm) ++{ ++ _HwSetStandby(psm); ++ _HwVccOff(psm); ++} ++ ++int CntPowerOn(ssfdc_dev *psm) ++{ ++ _HwVccOn(psm); ++ _WaitTimer(TIME_PON); ++ if(_HwChkPower(psm)) ++ return(SUCCESS); ++ _HwVccOff(psm); ++ return(ERROR); ++} ++ ++#if 0 // remove for now ++static void mediachangetest(unsigned long dev_idx) ++{ ++ ssfdc_dev *psm = ssfdc[dev_idx]; ++ unsigned int cardpresent; ++ unsigned long flags; ++ ++ spin_lock_irqsave( &psm->req_queue_lock, flags ); ++ // bjm spin_lock( &psm->req_queue_lock); ++ ++ del_timer(&mediachange_timer); ++ ++ // check current card presence ++ if ( ! (cardpresent = CntPowerOn(psm)) && psm->CardPresent ) { ++ psm->MediaChange = 1; ++ psm->DataBuf_Valid = 0; ++ } ++ psm->CardPresent = cardpresent; ++ ++ // set up to run again... ++ mediachange_timer.function = mediachangetest; ++ mediachange_timer.expires = jiffies + (HZ / 2); ++ mediachange_timer.data = dev_idx; ++ add_timer(&mediachange_timer); ++ ++ spin_unlock_irqrestore( &psm->req_queue_lock, flags ); ++ // bjm spin_unlock( &psm->req_queue_lock); ++} ++#endif ++ ++int CheckCardExist(ssfdc_dev *psm) ++{ ++ char i,j,k; ++ if(! _HwChkStatus(psm)) /***** Not Status Change *****/ ++ if(_HwChkCardIn(psm)) return(SUCCESS); /* Card exist in Slot */ ++ for(i=0,j=0,k=0; i<0x10; i++) { ++ if(_HwChkCardIn(psm)) /***** Status Change *****/ ++ { j++; k=0; } ++ else { j=0; k++; } ++ if(j>3) return(SUCCESS); /* Card exist in Slot */ ++ if(k>3) return(ERROR); /* NO Card exist in Slot */ ++ _WaitTimer(TIME_CDCHK); ++ } ++ return(ERROR); ++} ++ ++int CheckSsfdcWP(ssfdc_dev *psm) ++{ /* ERROR: WP, SUCCESS: Not WP */ ++ char i; ++ for(i=0; i<0x08; i++) { ++ if(_HwChkWP(psm)) ++ return(ERROR); ++ _WaitTimer(TIME_WPCHK); ++ } ++ return(SUCCESS); ++} ++ ++/******************************************/ ++int CheckCISdata(unsigned char *buf,unsigned char *redundant) ++{ ++ static unsigned char cis[]={ 0x01,0x03,0xD9,0x01,0xFF,0x18,0x02,0xDF,0x01,0x20 }; ++ unsigned char ecc1,ecc2,ecc3; ++ unsigned int err; ++ calculate_ecc(ecctable,buf,&ecc1,&ecc2,&ecc3); ++ err=correct_data(buf,redundant+0x0D,ecc1,ecc2,ecc3); ++ if(err==0 || err==1 || err==2) ++ return(StringCmp(buf,cis,10)); ++ buf+=0x100; ++ calculate_ecc(ecctable,buf,&ecc1,&ecc2,&ecc3); ++ err=correct_data(buf,redundant+0x08,ecc1,ecc2,ecc3); ++ if(err==0 || err==1 || err==2) ++ return(StringCmp(buf,cis,10)); ++ return(ERROR); ++} ++ ++int CheckECCdata(unsigned char *buf,unsigned char *redundant) ++{ ++ unsigned char ecc1,ecc2,ecc3; ++ unsigned int err, corr=SUCCESS; ++ calculate_ecc(ecctable,buf,&ecc1,&ecc2,&ecc3); ++ err=correct_data(buf,redundant+0x0D,ecc1,ecc2,ecc3); ++ if(err==1 || err==2) corr=CORRECT; ++ else if(err) return(ERROR); ++ buf+=0x100; ++ calculate_ecc(ecctable,buf,&ecc1,&ecc2,&ecc3); ++ err=correct_data(buf,redundant+0x08,ecc1,ecc2,ecc3); ++ if(err==1 || err==2) corr=CORRECT; ++ else if(err) return(ERROR); ++ return(corr); ++} ++ ++void SetECCdata(unsigned char *buf,unsigned char *redundant) ++{ ++ calculate_ecc(ecctable,buf,redundant+0x0E,redundant+0x0D,redundant+0x0F); ++ buf+=0x100; ++ calculate_ecc(ecctable,buf,redundant+0x09,redundant+0x08,redundant+0x0A); ++} ++ ++/*************************************************************************** ++ Power Control & Media Exist Check Function ++ ***************************************************************************/ ++ ++/*************************************************************************** ++ SmartMedia Read/Write/Erase Function ++ ***************************************************************************/ ++static int MediaReadSector(ssfdc_dev *psm, struct request *req, ++ char * bbuf, long start,int count) ++{ ++ char *buf; ++ int i, err, request_complete, ++ PrevBlock = NO_ASSIGN; ++ int read_status=0; ++ ++ if (ConvMediaAddr(psm, start)) { ++ printk(KERN_ERR "MediaReadSector() - bad address conversion\n"); ++ goto read_exit; ++ } ++ ++ psm->ReqSectorSize = count; ++ psm->BufIndex = 0; ++ psm->RetryCount = 0; ++ ++#if DEBUG_SSFDC_READ ++ printk(KERN_DEBUG "MediaReadSector() - read %d sectors @ %d\n", psm->ReqSectorSize, start); ++#endif ++ while (psm->ReqSectorSize) { ++ // if this PhyBlock is not assigned, fill with dummy data and return ++ // An assigned block results in a card access and readsector schedule... ++ if (psm->PhyBlock == NO_ASSIGN) { ++#if DEBUG_SSFDC_READ ++ printk(KERN_DEBUG "Read NO_ASSIGN block %x\n", psm->PhyBlock); ++#endif ++ buf = bbuf + psm->BufIndex; ++ for(i=0; i<SSFDC_SECTSIZE; i++) ++ *buf++=DUMMY_DATA; ++ } ++ else { ++ // send our command ++ if (PrevBlock != psm->PhyBlock) { ++#if DEBUG_SSFDC_READ ++ printk(KERN_DEBUG "Read block %x\n", psm->PhyBlock); ++#endif ++ PrevBlock = psm->PhyBlock; ++ _SetSsfdcCmd(psm,SSFDC_READ); ++ _SetSsfdcAddr(psm, EVEN); ++ for (i=0; i<5; ++i) { ++ if (!_HwChkBusy(psm)) ++ break; ++ udelay(10); ++ } ++ } ++ ++ ++ if ( _HwChkBusy(psm) ) { ++ ++psm->Sect_rd_errs_ttl; ++#if DEBUG_SSFDC_READ ++ printk(KERN_DEBUG "MediaReadSector() - Hardware busy!\n"); ++#endif ++ } ++ else { ++ ++psm->Sector_reads; ++ _ReadSsfdcBuf( psm, psm->SectBuf, psm->Redundant); ++ ++ // verify the integrity of what was read ++ if (CheckDataStatus(psm->Redundant)) { ++#if DEBUG_SSFDC_READ ++ printk(KERN_DEBUG "Bad Data Status\n"); ++#endif ++ goto error_state; ++ } ++ ++ switch (err = CheckECCdata(psm->SectBuf,psm->Redundant)) ++ { ++ case CORRECT: ++ // Correctable data, fix and copy like SUCCESS ++ SetECCdata(psm->SectBuf,psm->Redundant); ++ case SUCCESS: ++ memcpy(bbuf + psm->BufIndex, psm->SectBuf, SSFDC_SECTSIZE); ++ break; ++ ++ case ERROR: ++error_state: ++ ++psm->Sect_rd_errs_ttl; ++#if DEBUG_SSFDC_READ ++ printk(KERN_DEBUG "readsector() - err == ERROR\n"); ++#endif ++ _ResetSsfdcErr(psm); ++ if (++psm->RetryCount < RD_RETRY_LIMIT) { ++ continue; ++ } ++ break; ++ default: ++ ssfdc_terminate_request( psm, req); ++ break; ++ } ++ ++ } // if ( _HwChkBusy(psm) ) ++ } // if (psm->PhyBlock == NO_ASSIGN) ++ ++ // common req/buffer management code for either unassigned or assigned ++ // block from /dev/ssfdc ++ psm->RetryCount = 0; ++ psm->BufIndex += SSFDC_SECTSIZE; ++ request_complete = (--psm->ReqSectorSize == 0); ++ if (request_complete) { ++ // completed the read, req->buffer now has requested sector(s). ++ // End the request waking sleeping process and reschedule initxfer(). ++#if DEBUG_SSFDC_READ ++ printk(KERN_DEBUG "readsector() - req %x complete\n", req); ++#endif ++ read_status = 1; ++ } ++ else if (IncMediaAddr(psm)) { ++ printk(KERN_DEBUG "readsector() - IncMediaAddr() error.\n"); ++ goto read_exit; ++ } ++ } // while (psm->ReqSectorSize) ++ ++read_exit: ++ psm->XferState = xfer_idle; ++ ++ return read_status; ++ ++} ++ ++/* ++ ReadBlkCopy(ssfdc_dev *psm, unsigned char *buf) ++*/ ++int ReadBlkCopy(ssfdc_dev *psm, unsigned char *buf, char *rd_sector_status) ++{ ++ int err, read_error=0, rw_retry=0; ++ unsigned long PrevBlock=NO_ASSIGN; ++ ++ if ( ! buf ) { ++ printk(KERN_ERR "NULL buffer pointer\n"); ++ return ERROR; ++ } ++ ++ if (psm->PhyBlock == NO_ASSIGN) { ++ memset(buf, 0xff, psm->MaxSectors * SSFDC_SECTSIZE); ++ memset(rd_sector_status, 1, sizeof(char) * MAX_SECTNUM); ++ return SUCCESS; ++ } ++ ++#if 0 ++ printk(KERN_ERR "ReadBlkCopy() - LogBlk %d\n", psm->LogBlock); ++#endif ++ ++ for (psm->Sector = 0; ++ psm->PhyBlock != NO_ASSIGN && psm->Sector < psm->MaxSectors; ++ ++psm->Sector) ++ { ++ if (PrevBlock != psm->PhyBlock) { ++ _SetSsfdcCmd(psm,SSFDC_READ); ++ _SetSsfdcAddr(psm, EVEN); ++ PrevBlock = psm->PhyBlock; ++ _CheckSsfdcBusy(psm, BUSY_ADDR_SET); ++ } ++ ++ if ( _HwChkBusy(psm) ) { ++ printk(KERN_ERR "%s: HW busy during block copy!\n", MAJOR_NAME); ++ goto error_state; ++ } ++ ++ _ReadSsfdcBuf( psm, psm->SectBuf, psm->Redundant); ++ if (CheckDataStatus(psm->Redundant)) { ++ printk("KERN_ERR reading Block %d, sector %d\n", psm->PhyBlock, psm->Sector); ++ goto error_state; ++ } ++ ++ // Attempt to correct ++ switch (err = CheckECCdata(psm->SectBuf,psm->Redundant)) ++ { ++ case CORRECT: ++#if DEBUG_SSFDC_WRITE ++ printk(KERN_DEBUG "ReadBlkCopy() - err == CORRECT\n"); ++#endif ++ SetECCdata(psm->SectBuf,psm->Redundant); ++ case SUCCESS: ++ read_error = 0; ++ rw_retry = 0; ++ memcpy(buf + (psm->Sector * SSFDC_SECTSIZE), psm->SectBuf, SSFDC_SECTSIZE); ++ rd_sector_status[psm->Sector] = 1; ++ read_error = 0; ++ break; ++ ++ case ERROR: ++error_state: ++/*bjm*/ printk("ERR - ECC error reading Block %d, Sector %d\n", psm->PhyBlock,psm->Sector); ++#if DEBUG_SSFDC_WRITE ++ printk(KERN_DEBUG "ReadBlkCopy() - err == ERROR\n"); ++ printk("_ResetSsfdcErr(psm)\n"); ++#endif ++ _ResetSsfdcErr(psm); ++ PrevBlock = NO_ASSIGN; ++ if (++rw_retry < RD_RETRY_LIMIT) { ++ // retry current Sector/loop counter on next loop iteration. ++ --psm->Sector; ++ } ++ else { ++ // set sector data in copy buf to the unassigned value 0xFF ++ // next loop iteration will read next Sector, zero RetryCount ++ // for next sectors read ++ // map bad sector... ++ memset(buf + psm->Sector * SSFDC_SECTSIZE, 0xFF, SSFDC_SECTSIZE); ++ rw_retry = 0; ++ rd_sector_status[psm->Sector] = 0; ++ ++psm->Sect_rd_errs_ttl; ++ read_error = 1; ++ } ++#if DEBUG_SSFDC_WRITE ++ printk(KERN_DEBUG "Unable to read Blk %d Sector %d\n", psm->PhyBlock, psm->Sector); ++#endif ++ break; ++ } ++ } ++ if (!read_error) { ++ if (SsfdcEraseBlock(psm)) { ++ MarkFailPhyOneBlock(psm); ++ ++psm->Bad_blks_erase; ++ } ++ else { ++ ClrBit(psm->Assign[psm->Zone], psm->PhyBlock); ++ } ++ } ++ else { ++ printk("Read error block %d\n", psm->PhyBlock); ++ MarkFailPhyOneBlock(psm); ++ } ++ psm->Sector = 0; ++ return read_error ? ERROR : SUCCESS; ++} ++ ++/* ++ WriteBlock() ++*/ ++int WriteBlock(ssfdc_dev *psm, char *buf, char *wr_sector_status) ++{ ++ int write_error=0, reassign_retry=0; ++ ++ for ( reassign_retry = 0; reassign_retry < REASSIGN_RETRY_LIMIT; ++reassign_retry) ++ { ++ /* ++ assign new write block for write req ++ - set new write address ++ - write buffer to new block ++ */ ++#if DEBUG_SSFDC_WRITE ++ if (AssignWriteBlock(psm,1)) { ++#else ++ if (AssignWriteBlock(psm,0)) { ++#endif ++ write_error = 1; ++ printk(KERN_ERR "sm%dd Unable to assign new write block.\n", psm->sm_minor); ++ memset(wr_sector_status, 1, sizeof(char) * MAX_SECTNUM); ++ // ssfdc_terminate_request(psm, req); ++ return ERROR; ++ } ++ ++#if 0 ++ printk(KERN_ERR "WriteBlock() - LogBlock %d\n", psm->LogBlock); ++#endif ++ ++ for (psm->Sector = 0; psm->Sector < psm->MaxSectors; ++psm->Sector) ++ { ++ memcpy(psm->SectBuf,buf+psm->Sector*SSFDC_SECTSIZE,SSFDC_SECTSIZE); ++ ++ _SetSsfdcCmd(psm,SSFDC_WRDATA); ++ _SetSsfdcAddr(psm,EVEN); ++ ClrRedundantData(psm->Redundant); ++ SetLogBlockAddr(psm,psm->Redundant); ++ SetECCdata(psm->SectBuf,psm->Redundant); ++ _WriteSsfdcBuf(psm,psm->SectBuf,psm->Redundant); ++ ++#if DEBUG_SSFDC_WRITE ++ printk("%d ", psm->Sector); ++#endif ++ ++ _SetSsfdcCmd(psm, SSFDC_WRITE); ++ if ( ! _CheckSsfdcBusy(psm, BUSY_PROG) && !SsfdcCheckStatus(psm)) { ++#if DEBUG_SSFDC_WRITE ++ printk("\nMulti-Sector write OK!\n"); ++#endif ++ _SetSsfdcStandby(psm); ++ // mark status a success ++ wr_sector_status[psm->Sector] = 1; ++ ++#if 0 // bjm removed ++ { unsigned char parbuf[SSFDC_SECTSIZE]; ++ unsigned char redtpar[REDTSIZE]; ++ ++ _SetSsfdcCmd(psm,SSFDC_READ); ++ _SetSsfdcAddr(psm, EVEN); ++ ++ udelay(30); ++ if ( _HwChkBusy(psm) ) { ++ _ResetSsfdcErr(psm); ++ printk("paranoid read failure\n"); ++ } ++ else { ++ _ReadSsfdcBuf(psm, parbuf, redtpar); ++ if (CheckDataStatus(redtpar)) { ++ printk("paranoid read, bad data status\n"); ++ } ++ else { ++ switch( err = CheckECCdata(parbuf,redtpar)) ++ { ++ case CORRECT: ++ printk("paranoid correctable\n"); ++ SetECCdata(parbuf,redtpar); ++ case SUCCESS: ++ if (memcmp(parbuf,psm->SectBuf, SSFDC_SECTSIZE)) ++ write_error = 1; ++ else ++ write_error = 0; ++ break; ++ case ERROR: ++ MarkFailPhyOneBlock(psm); ++ write_error=1; ++ break; ++ } ++ } ++ } ++ } // bjm end of paranoid read back test... ++#endif ++ } ++ else { ++#if DEBUG_SSFDC_WRITE ++ printk("\nMulti-Sector write FAILED!\n"); ++#endif ++ // mark status a failure ++ wr_sector_status[psm->Sector] = 0; ++ _ResetSsfdcErr(psm); ++ write_error = 1; ++ break; ++ } // for (psm->Sector ...) ++ if (write_error) ++ break; ++ } ++ if ( ! write_error ) { ++ psm->Log2Phy[psm->Zone][psm->LogBlock] = psm->WriteBlock; ++ break; ++ } ++ } ++ psm->Sector = 0; ++ return write_error ? ERROR : SUCCESS; ++} ++ ++/* ++ MediaWriteSector() ++ ++*/ ++static int MediaWriteSector(ssfdc_dev *psm, struct request *req, char * bbuf, long start, int count) ++{ ++ int write_error=0, unwritten_block=0; ++ char *buf; ++ unsigned long curr_sector, blksize, PrevBlock; ++ unsigned long writebuf_index, readbio_index; ++ int i, sector, rw_retry=0; ++ int sectors_in_block; ++ char rd_sector_status[MAX_SECTNUM]; ++ char wr_sector_status[MAX_SECTNUM]; ++ ++ // optimized write, new vars ++ int bio_endios=0; ++ int bio_bvecs=0; ++ struct bio *bio; ++ // optimized for write ++ ++#if DEBUG_SSFDC_WRITE ++ printk(KERN_DEBUG "+MediaWriteSector()\n"); ++#endif ++ ++ if (!count) { ++ printk("MediaWriteSector() count == 0!\n"); ++ ssfdc_end_request(psm, req, 0); ++ return 1; ++ } ++ ++ if (CheckMediaWP(psm)) { ++ printk(KERN_DEBUG "%s: write protected media.\n", MAJOR_NAME); ++ ssfdc_terminate_request( psm, req); ++ psm->XferState = xfer_idle; ++ return -EIO; ++ } ++ ++ // allocate block size buffer ++ blksize = psm->MaxSectors * SSFDC_SECTSIZE; ++#if DEBUG_SSFDC_WRITE ++ printk(KERN_DEBUG "%s: Allocate %d sized block.\n", MAJOR_NAME, blksize); ++#endif ++ if ((buf = kmalloc(blksize, GFP_ATOMIC)) == NULL) { ++ printk(KERN_ERR "%s: Null buffer allocated!\n", MAJOR_NAME); ++ ssfdc_terminate_request( psm, req); ++ goto the_exit; ++ } ++ ++ /* ++ Loop to handle a request at the curr_sector of count sectors. ++ The write operation my encompas more than one phys block. ++ */ ++ curr_sector = start; ++ sectors_in_block = 0; ++ // zero out our sector R/W status array ++ memset(rd_sector_status, 1, sizeof(char) * MAX_SECTNUM); ++ memset(wr_sector_status, 1, sizeof(char) * MAX_SECTNUM); ++ ++ // rangecheck this sector within the device. ++ if (ConvMediaAddr(psm, curr_sector)) { ++ ssfdc_terminate_request(psm, req); ++ printk(KERN_ERR "WriteSector: ConvMediaAddr() error\n"); ++#if DEBUG_SSFDC_WRITE ++ printk(KERN_DEBUG "-MediaWriteSector()\n"); ++#endif ++ return 0; ++ } ++ ++#if DEBUG_SSFDC_WRITE ++ printk(KERN_DEBUG "MediaWriteSector() Zone %d, LogBlock %d PhyBlock %d, Sector %d\n", ++ psm->Zone,psm->LogBlock, psm->PhyBlock,psm->Sector); ++#endif ++ ++ PrevBlock = NO_ASSIGN; ++ rw_retry = 0; ++ ++#if DEBUG_SSFDC_WRITE ++ printk(KERN_DEBUG "Copy Zone %d, Phys %d\n", psm->Zone, psm->PhyBlock); ++#endif ++ // As a technique for wear leveling, a write to the SM results in the contents ++ // of the block to be copied into a blocksize buffer, the write data of the ++ // write request being overlayed onto the buffer containing the copied block, ++ // a new logical to physical mapping defined, and the buffer written into this ++ // newly mapped (logically) physical block. ++ ++ // read the physical block into the buffer. ++#if DEBUG_SSFDC_WRITE ++ printk(KERN_DEBUG "ReadBlock = %d LogBlock %d\n", psm->PhyBlock, psm->LogBlock); ++#endif ++ if (ReadBlkCopy(psm, buf, rd_sector_status) != SUCCESS) { ++ printk(KERN_ERR "Unable to read block.\n"); ++ goto the_exit; ++ } ++ ++#if DEBUG_SSFDC_WRITE ++ printk(KERN_DEBUG "Read from pending write request "); ++#endif ++ ++#if 0 ++ int bio_idx=0; ++#endif ++ rq_for_each_bio(bio, req) { ++ struct bio_vec *bvec; ++ int i, break_flag=0; ++#if 0 ++ int segment_idx; ++ printk(KERN_ERR "bio %d\n", bio_idx++); ++ ++ segment_idx = 0; ++#endif ++ // bio_bvecs = 0; ++ bio_for_each_segment(bvec, bio, i) { ++#if 0 ++ printk(KERN_ERR "segment %d\n", segment_idx++); ++#endif ++ // The conditions... ++ // bio fits within block ++ if (WriteReqInCurrBlk(psm,curr_sector + (bvec->bv_len >> 9) - 1,§or) ++ && WriteReqInCurrBlk(psm,curr_sector, §or)) ++ { ++#if 0 ++ printk(KERN_ERR "LogBlk %d: write at %d, %d sectors\n", ++ psm->LogBlock, curr_sector % psm->MaxSectors, bio_cur_sectors(bio)); ++#endif ++ // write bio into copied block ++ ++bio_bvecs; ++ writebuf_index = sector * SSFDC_SECTSIZE; ++#if 0 ++ printk(KERN_ERR "memcpy buf at 0x%x, 0x%x bytes\n", ++ writebuf_index, bvec->bv_len); ++#endif ++ memcpy(buf + writebuf_index, ++ page_address(bvec->bv_page) + bvec->bv_offset, bvec->bv_len); ++ unwritten_block = 1; ++ curr_sector += bvec->bv_len >> 9; ++ } ++ // bio fits partially within block ++ else if (WriteReqInCurrBlk(psm,curr_sector, §or)) ++ { ++ // put portion of bio in block ++ ++bio_bvecs; ++ writebuf_index = sector * SSFDC_SECTSIZE; ++ sectors_in_block = psm->MaxSectors - sector; ++ readbio_index = sectors_in_block * SSFDC_SECTSIZE; ++#if 0 ++ printk(KERN_ERR "memcpy buf at %x, %x bytes\n", ++ writebuf_index, readbio_index); ++#endif ++ memcpy(buf + writebuf_index, ++ page_address(bvec->bv_page) + bvec->bv_offset, readbio_index); ++#if 0 ++ printk(KERN_ERR "LogBlk %d: partial-write at %d, %d sectors first\n", ++ psm->LogBlock, curr_sector % psm->MaxSectors, sectors_in_block); ++#endif ++ // write block ++ unwritten_block = 0; ++ if (WriteBlock(psm, buf, wr_sector_status) != SUCCESS) { ++ printk(KERN_ERR "Unable to write block %d\n", psm->LogBlock); ++ // write_error - writing this block failed ++ break_flag = 1; ++ break; ++ } ++ // incr addr & read next block, ++ curr_sector += sectors_in_block; ++ if (ConvMediaAddr(psm,curr_sector) != SUCCESS) { ++ printk(KERN_ERR "MediaWriteSector() IncMediaAddr() error!\n"); ++ // write_error - address into next block is bogus ++ write_error = 1; ++ break_flag = 1; ++ break; ++ } ++ if (ReadBlkCopy(psm, buf, rd_sector_status) != SUCCESS) { ++ printk(KERN_ERR "MediaWriteSector() ReadBlkCopy() error!\n"); ++ // write error - next block read error ++ write_error = 1; ++ break_flag =1; ++ break; ++ } ++ // write remainder of bio into block ++#if 0 ++ printk(KERN_ERR "LogBlk %d: partial-write at %d, %d sectors, second write\n", ++ psm->LogBlock, curr_sector % psm->MaxSectors, (bvec->bv_len >> 9) - sectors_in_block); ++#endif ++#if 0 ++ printk(KERN_ERR "memcpy buf at 0x%x, from bio 0x%x, for 0x%x bytes\n", ++ 0, readbio_index, ((bvec->bv_len >> 9) - sectors_in_block) * SSFDC_SECTSIZE); ++#endif ++ memcpy(buf, (page_address(bvec->bv_page) + bvec->bv_offset) + readbio_index, ++ ((bvec->bv_len >> 9) - sectors_in_block) * SSFDC_SECTSIZE); ++ writebuf_index = ((bvec->bv_len >> 9) - sectors_in_block) * SSFDC_SECTSIZE; ++ unwritten_block = 1; ++ curr_sector += (bvec->bv_len >> 9) - sectors_in_block; ++ } ++ // bio is not in block at all. coplete unwritten block and exit loop. ++ else { ++ // write current block ++#if 0 ++ printk(KERN_ERR "bio no longer in block\n"); ++#endif ++ if (unwritten_block) { ++ if (WriteBlock(psm, buf, wr_sector_status) != SUCCESS) { ++ printk(KERN_ERR "MediaWriteSector() WriteBlock() error!\n"); ++ // write_error ++ } ++ unwritten_block = 0; ++ } ++ break_flag = 1; ++ break; ++ } ++ } ++ // bjm if (bio_bvecs) +bio_bvecs; ++ ++ if (break_flag) ++ break; ++ } ++ ++ if (unwritten_block) { ++ if (WriteBlock(psm, buf, wr_sector_status) != SUCCESS) { ++ printk(KERN_ERR "MediaWriteSector() WriteBlock() error!\n"); ++ write_error = 1; ++ } ++ } ++ ++ if (!(bio_endios=bio_bvecs)) { ++ if (static_ssfdc_debug) ++ printk("no bios from request!\n"); ++ ++bio_endios; ++ write_error = 0; ++ } ++ ++the_exit: ++ // log sector status for the copied/unmodified Sectors and flag any that have cpy errors ++ for (sector = 0; sector < psm->MaxSectors; ++sector) { ++ if ( ! rd_sector_status[sector] ) ++ printk(KERN_ERR "%s: READ sector %d invalid for block %d!\n", \ ++ MAJOR_NAME, sector, psm->LogBlock); ++ if ( ! wr_sector_status[sector]) ++ printk(KERN_ERR "%s: WRITTEN sector %d invalid for block %d!\n", \ ++ MAJOR_NAME, sector, psm->LogBlock); ++ } ++ ++ // free our prev allocated block for copy... ++ if (buf) ++ kfree(buf); ++ ++ psm->XferState = xfer_idle; ++ ++#if DEBUG_SSFDC_WRITE ++ printk(KERN_DEBUG "-MediaWriteSector()\n"); ++#endif ++ if (static_ssfdc_debug) ++ printk("end_request(%d) ", ! write_error); ++ for (i = 0; i < bio_endios; ++i) { ++ if (static_ssfdc_debug) ++ printk("%d ", i); ++ ssfdc_end_request(psm, req, ! write_error); ++ } ++ if (static_ssfdc_debug) ++ printk("\n"); ++ ++ return ! write_error; ++ ++} ++ ++ ++/*************************************************************************** ++ SmartMedia Logical Format Subroutine ++ ***************************************************************************/ ++int CheckLogCHS(ssfdc_dev *psm, unsigned int *c,unsigned char *h,unsigned char *s) ++{ ++ switch(psm->Model) { ++ case SSFDC1MB: *c=125; *h= 4; *s= 4; break; ++ case SSFDC2MB: *c=125; *h= 4; *s= 8; break; ++ case SSFDC4MB: *c=250; *h= 4; *s= 8; break; ++ case SSFDC8MB: *c=250; *h= 4; *s=16; break; ++ case SSFDC16MB: *c=500; *h= 4; *s=16; break; ++ case SSFDC32MB: *c=500; *h= 8; *s=16; break; ++ case SSFDC64MB: *c=500; *h= 8; *s=32; break; ++ case SSFDC128MB: *c=500; *h=16; *s=32; break; ++ default: ++ *c= 0; *h= 0; *s= 0; ++ psm->ErrCode=ERR_NoSmartMedia; ++ return(ERROR); ++ } ++ return(SUCCESS); ++} ++/*************************************************************************** ++ Power Control & Media Exist Check Subroutine ++ ***************************************************************************/ ++ ++int CheckMediaWP(ssfdc_dev *psm) ++{ ++ if(psm->Attribute &MWP) ++ { psm->ErrCode=ERR_WrtProtect; return(ERROR); } ++ return(SUCCESS); ++} ++ ++/*************************************************************************** ++ SmartMedia Physical Address Control Subroutine ++ ***************************************************************************/ ++int ConvMediaAddr(ssfdc_dev *psm, long addr) ++{ ++ long temp; ++ temp =addr/psm->MaxSectors; ++ psm->Sector =addr%psm->MaxSectors; ++ psm->LogBlock=temp%psm->MaxLogBlocks; ++ psm->Zone =temp/psm->MaxLogBlocks; ++ if(psm->Zone<psm->MaxZones) { ++ ClrRedundantData(psm->Redundant); ++ SetLogBlockAddr(psm,psm->Redundant); ++ psm->PhyBlock=psm->Log2Phy[psm->Zone][psm->LogBlock]; ++#if DEBUG_SSFDC_ASSIGNRELEASE ++ printk(KERN_DEBUG "ConvMediaAddr() LogBlock %d -> PhyBlock %d\n", ++ psm->LogBlock, psm->PhyBlock); ++#endif ++ return(SUCCESS); ++ } ++ psm->ErrCode=ERR_OutOfLBA; ++ return(ERROR); ++} ++ ++int IncMediaAddr(ssfdc_dev *psm) ++{ ++ if(++psm->Sector<psm->MaxSectors) ++ return(SUCCESS); ++ psm->Sector=0; ++ if(++psm->LogBlock<psm->MaxLogBlocks) { ++ ClrRedundantData(psm->Redundant); ++ SetLogBlockAddr(psm,psm->Redundant); ++ psm->PhyBlock=psm->Log2Phy[psm->Zone][psm->LogBlock]; ++#if DEBUG_SSFDC_ASSIGNRELEASE ++ printk(KERN_DEBUG "IncMediaAddr() PhyBlock %d <- LogBlock %d\n", ++ psm->PhyBlock, psm->LogBlock); ++#endif ++ return(SUCCESS); ++ } ++ psm->LogBlock=0; ++ if(++psm->Zone<psm->MaxZones) { ++ ClrRedundantData(psm->Redundant); ++ SetLogBlockAddr(psm,psm->Redundant); ++ psm->PhyBlock=psm->Log2Phy[psm->Zone][psm->LogBlock]; ++#if DEBUG_SSFDC_ASSIGNRELEASE ++ printk(KERN_DEBUG "IncMediaAddr() PhyBlock %d <- LogBlock %d\n", ++ psm->PhyBlock, psm->LogBlock); ++#endif ++ return(SUCCESS); ++ } ++ psm->Zone=0; ++ psm->ErrCode=ERR_OutOfLBA; ++ return(ERROR); ++} ++ ++/***************************************************************************/ ++ ++ ++static int WriteReqInCurrBlk(ssfdc_dev *psm, long sector, int *blksector) ++{ ++ long temp; ++ unsigned char Zone; /* Zone Number */ ++ unsigned int LogBlock; /* Logical Block Number of Zone */ ++ ++ if (!psm) ++ return 0; ++ ++ temp = sector / psm->MaxSectors; ++ *blksector = sector % psm->MaxSectors; ++ LogBlock = temp % psm->MaxLogBlocks; ++ Zone = temp / psm->MaxLogBlocks; ++ ++ return (psm->LogBlock == LogBlock && psm->Zone == Zone); ++} ++ ++/*************************************************************************** ++ SmartMedia Read/Write Subroutine with Retry ++ ***************************************************************************/ ++ ++/*************************************************************************** ++ SmartMedia Physical Block Assign/Release Subroutine ++ ***************************************************************************/ ++int AssignWriteBlock(ssfdc_dev *psm, int verbose_flag) ++{ ++ psm->ReadBlock=psm->PhyBlock; ++#if DEBUG_SSFDC_WRITE ++ int Zonesave=psm->Zone, ZoneIndex; ++#endif ++ ++#if DEBUG_SSFDC_WRITE ++ if (verbose_flag) { ++ printk("AssignWriteBlock() verbose mode. psm->Zone %d\n",psm->Zone); ++ for (psm->Zone = 0; psm->Zone < psm->MaxZones; psm->Zone++) { ++ int free_blk=0; ++ printk("\tZone %d, AssignStart %d and ", psm->Zone, psm->AssignStart[psm->Zone]); ++ for (psm->WriteBlock=0; psm->WriteBlock < psm->MaxLogBlocks; psm->WriteBlock++) ++ if (! ChkBit(psm->Assign[psm->Zone],psm->WriteBlock)) ++free_blk; ++ printk("%d free blocks.\n", free_blk); ++ } ++ psm->Zone = Zonesave; ++ } ++#endif ++ for(psm->WriteBlock=psm->AssignStart[psm->Zone]; psm->WriteBlock<psm->MaxBlocks; psm->WriteBlock++) ++ if(! ChkBit(psm->Assign[psm->Zone],psm->WriteBlock)) { ++ SetBit(psm->Assign[psm->Zone],psm->WriteBlock); ++ psm->AssignStart[psm->Zone]=psm->WriteBlock+1; ++ psm->PhyBlock=psm->WriteBlock; ++ psm->SectCopyMode=REQ_ERASE; ++#if DEBUG_SSFDC_ASSIGNRELEASE ++ printk(KERN_DEBUG "AssignWriteBlock() - WriteBlock %d ReadBlock %d LogBlock %d\n", ++ psm->WriteBlock, psm->ReadBlock, psm->LogBlock); ++#endif ++ return(SUCCESS); ++ } ++ for(psm->WriteBlock=0; psm->WriteBlock<psm->AssignStart[psm->Zone]; psm->WriteBlock++) ++ if(! ChkBit(psm->Assign[psm->Zone],psm->WriteBlock)) { ++ SetBit(psm->Assign[psm->Zone],psm->WriteBlock); ++ psm->AssignStart[psm->Zone]=psm->WriteBlock+1; ++ psm->PhyBlock=psm->WriteBlock; ++ psm->SectCopyMode=REQ_ERASE; ++#if DEBUG_SSFDC_ASSIGNRELEASE ++ printk(KERN_DEBUG "AssignWriteBlock() - WriteBlock %d PhyBlock %d LogBlock %d\n", ++ psm->WriteBlock, psm->PhyBlock, psm->LogBlock); ++#endif ++ return(SUCCESS); ++ } ++ psm->WriteBlock=NO_ASSIGN; ++ psm->ErrCode=ERR_WriteFault; ++ return(ERROR); ++} ++ ++/*************************************************************************** ++ SmartMedia Physical Format Check Local Subroutine ++ ***************************************************************************/ ++static int SetPhyFmtValue(ssfdc_dev *psm) ++{ ++ unsigned int idcode; ++ SsfdcReadID(psm, &idcode); ++ if(SetSsfdcModel(psm,(unsigned char)idcode)) ++ return(ERROR); ++ if(CheckSsfdcWP(psm)) ++ psm->Attribute|=WP; ++ return(SUCCESS); ++} ++ ++static int SearchCIS(ssfdc_dev *psm, unsigned int *pcis) ++{ ++ psm->Zone=0; psm->Sector=0; ++ for(psm->PhyBlock=0; psm->PhyBlock<(psm->MaxBlocks-psm->MaxLogBlocks-1); psm->PhyBlock++) { ++ if(SsfdcReadRedtData(psm, psm->Redundant)) ++ { SsfdcReset(psm); return(ERROR); } ++ if(! CheckFailBlock(psm->Redundant)) { ++ if(CheckCisBlock(psm->Redundant)) ++ { SsfdcReset(psm); return(ERROR); } ++ break; ++ } ++ } ++ while(psm->Sector<psm->MaxSectors) { ++ if(psm->Sector) ++ if(SsfdcReadRedtData(psm, psm->Redundant)) ++ { SsfdcReset(psm); return(ERROR); } ++ if(! CheckDataStatus(psm->Redundant)) { ++ if(SsfdcReadSect(psm,psm->WorkBuf,psm->Redundant)) ++ { SsfdcReset(psm); return(ERROR); } ++ if(CheckCISdata(psm->WorkBuf,psm->Redundant)) ++ { SsfdcReset(psm); return(ERROR); } ++ *pcis=psm->PhyBlock; ++ SsfdcReset(psm); ++ return(SUCCESS); ++ } ++ psm->Sector++; ++ } ++ SsfdcReset(psm); ++ return(ERROR); ++} ++ ++/***************************************************************************/ ++static int MakeLogTable(ssfdc_dev *psm, unsigned int start) ++{ ++ unsigned int block; ++ unsigned int blk_total=0, blk_blank=0, blk_nologaddr=0, ++ blk_fail=0, blk_assigned=0; ++ ++#if DEBUG_SSFDC ++ printk(KERN_DEBUG "MakeLogTable()\n"); ++#endif ++ psm->DataBuf_Valid = 1; ++ psm->Sector=0; ++ for(psm->Zone=0; psm->Zone<psm->MaxZones; psm->Zone++) { ++ /* set all LogBlocks to NO_ASSIGN */ ++ for(psm->LogBlock=0; psm->LogBlock<psm->MaxLogBlocks; psm->LogBlock++) ++ psm->Log2Phy[psm->Zone][psm->LogBlock]=NO_ASSIGN; ++ /* for all Assigns[zone][PhyBlock] = 0x00 */ ++ for(psm->PhyBlock=0; psm->PhyBlock<(MAX_BLOCKNUM/8); psm->PhyBlock++) ++ psm->Assign[psm->Zone][psm->PhyBlock]=0x00; ++ /*******************************************************************/ ++ for(psm->PhyBlock=0; psm->PhyBlock<psm->MaxBlocks; psm->PhyBlock++) { ++ if((! psm->Zone) && (psm->PhyBlock<start)) { ++ SetBit(psm->Assign[psm->Zone],psm->PhyBlock); ++ continue; ++ } ++ ++blk_total; ++ if(SsfdcReadRedtData(psm,psm->Redundant)) { ++ SsfdcReset(psm); ++#if 0 ++ printk(KERN_ERR "error 1 PhyBlock %d\n", psm->PhyBlock); ++#endif ++ return(ERROR); ++ } ++ if(! CheckDataBlank(psm->Redundant)) { ++ ++blk_blank; ++ continue; ++ } ++ SetBit(psm->Assign[psm->Zone],psm->PhyBlock); ++ if(CheckFailBlock(psm->Redundant)) { ++#if 0 ++ printk("Zone %d, Block %d failed\n", psm->Zone, psm->PhyBlock); ++#endif ++ ++blk_fail; ++ continue; ++ } ++ if(LoadLogBlockAddr(psm)) { ++ ++blk_nologaddr; ++ continue; ++ } ++ if(psm->LogBlock>=psm->MaxLogBlocks) ++ continue; ++ ++blk_assigned; ++ if(psm->Log2Phy[psm->Zone][psm->LogBlock]==NO_ASSIGN) { ++#if DEBUG_SSFDC_ASSIGNRELEASE ++ if (psm->LogBlock == 0) ++ printk(KERN_DEBUG "MakeLogTable() LogBlock %d = PhyBlock %d\n", ++ psm->LogBlock, psm->PhyBlock); ++#endif ++ psm->Log2Phy[psm->Zone][psm->LogBlock]=psm->PhyBlock; ++ continue; ++ } ++ psm->Sector=psm->MaxSectors-1; ++ if(SsfdcReadRedtData(psm,psm->Redundant)) { ++ SsfdcReset(psm); ++#if 0 ++ printk(KERN_ERR "error 2\n"); ++#endif ++ return(ERROR); ++ } ++ psm->Sector=0; ++ block=psm->LogBlock; ++ if(! LoadLogBlockAddr(psm)) ++ if(psm->LogBlock==block) { ++#ifdef L2P_ERR_ERASE /***************************************************/ ++ block=psm->Log2Phy[psm->Zone][psm->LogBlock]; ++ psm->Log2Phy[psm->Zone][psm->LogBlock]=psm->PhyBlock; ++ psm->PhyBlock=block; ++ if(!(psm->Attribute &MWP)) { ++ SsfdcReset(psm); ++ if(SsfdcEraseBlock(psm)) { ++ printk(KERN_ERR "error 3\n"); ++ return(ERROR); ++ } ++ if(SsfdcCheckStatus(psm)) { ++ if(MarkFailPhyOneBlock(psm)) { ++ printk(KERN_ERR "error 4\n"); ++ return(ERROR); ++ } ++ } ++ else ClrBit(psm->Assign[psm->Zone],psm->PhyBlock); ++ } ++ psm->PhyBlock=psm->Log2Phy[psm->Zone][psm->LogBlock]; ++#else /*******************************************************************/ ++ psm->Log2Phy[psm->Zone][psm->LogBlock]=psm->PhyBlock; ++#endif /*******************************************************************/ ++ continue; ++ } ++#ifdef L2P_ERR_ERASE /***************************************************/ ++ if(!(psm->Attribute &MWP)) { ++ SsfdcReset(psm); ++ if(SsfdcEraseBlock(psm)) { ++ printk(KERN_ERR "error 5\n"); ++ return(ERROR); ++ } ++ if(SsfdcCheckStatus(psm)) { ++ if(MarkFailPhyOneBlock(psm)) { ++ printk(KERN_ERR "error 6\n"); ++ return(ERROR); ++ } ++ } ++ else ClrBit(psm->Assign[psm->Zone],psm->PhyBlock); ++ } ++#endif /*******************************************************************/ ++ } ++ psm->AssignStart[psm->Zone]=0; ++ } ++ SsfdcReset(psm); ++#if 0 ++ printk("MakeLogTable()\n"); ++ printk("\t%d failed\n", blk_fail); ++ printk("\t%d blank\n", blk_blank); ++ printk("\t%d assigned\n", blk_assigned); ++ printk("\t%d no logical addr\n", blk_nologaddr); ++ printk("\n\t%d total\n", blk_total); ++ printk("\t%d sum total\n", blk_fail + blk_blank + blk_assigned + blk_nologaddr); ++#endif ++ return(SUCCESS); ++} ++ ++/***************************************************************************/ ++static int MarkFailPhyOneBlock(ssfdc_dev *psm) ++{ ++ unsigned char sect; ++ sect=psm->Sector; ++ SetFailBlock(psm->WorkRedund); ++ SsfdcWriteRedtMode(psm); ++ for(psm->Sector=0; psm->Sector<psm->MaxSectors; psm->Sector++) ++ if(SsfdcWriteRedtData(psm,psm->WorkRedund)) { ++ SsfdcReset(psm); ++ psm->Sector=sect; ++ psm->ErrCode=ERR_HwError; ++ return(ERROR); ++ } /* NO Status Check */ ++ SsfdcReset(psm); ++ psm->Sector=sect; ++ return(SUCCESS); ++} ++ ++/*************************************************************************** ++ SmartMedia Control subroutine ++ Rev 0.30('98-06-30) ***** BETA RELEASE ***** ++ Copyright (c) 1997-98, Toshiba Corporation. All rights reserved. ++ ***************************************************************************/ ++ ++ ++/* Linux Driver Modifications */ ++/* ++dump_ssfdc_state ++*/ ++#if DEBUG_SSFDC ++void dump_ssfdc_state(ssfdc_dev * psm) ++{ ++#if DEBUG_SSFDC_STRUCT ++ // misc structure dump information ++ printk(KERN_DEBUG "psm->\n"); ++ /* unsigned long */ printk(KERN_DEBUG "\t address %x\n", psm->address); ++ /* int */ printk(KERN_DEBUG "\t sm_minor %d\n",psm->sm_minor); ++ /* struct dentry printk(KERN_DEBUG "\t *sm_dentry %x\n",psm->sm_dentry );*/ ++ /* kdev_t */ printk(KERN_DEBUG "\t sm_device %x\n",psm->sm_device); ++ /* int */ printk(KERN_DEBUG "\t sm_flags %x\n",psm->sm_flags); ++ /* unsigned int */ printk(KERN_DEBUG "\t UseCount %d\n",psm->UseCount); ++ /* unsigned int */ printk(KERN_DEBUG "\t ErrCode %d\n",psm->ErrCode); ++ /* unsigned int */ printk(KERN_DEBUG "\t MediaChange %d\n",psm->MediaChange); ++ /* unsigned int */ printk(KERN_DEBUG "\t SectCopyMode %d\n",psm->SectCopyMode); ++ /* unsigned int */ printk(KERN_DEBUG "\t HostCyl %d\n",psm->HostCyl ); ++ /* unsigned char */ printk(KERN_DEBUG "\t HostHead %d\n",psm->HostHead ); ++ /* unsigned char */ printk(KERN_DEBUG "\t HostSect %d\n",psm->HostSect ); ++ /* unsigned int */ printk(KERN_DEBUG "\t ReadBlock %d\n",psm->ReadBlock ); ++ /* unsigned int */ printk(KERN_DEBUG "\t WriteBlock %d\n",psm->WriteBlock ); ++ ++ /* Card attributes */ ++ /* unsigned char */ printk(KERN_DEBUG "\t Model %d\n",psm->Model ); ++ /* unsigned char */ printk(KERN_DEBUG "\t Attribute %x\n",psm->Attribute ); ++ /* unsigned char */ printk(KERN_DEBUG "\t MaxZones %d\n",psm->MaxZones ); ++ /* unsigned char */ printk(KERN_DEBUG "\t MaxSectors %d\n",psm->MaxSectors ); ++ /* unsigned int */ printk(KERN_DEBUG "\t MaxBlocks %d\n",psm->MaxBlocks ); ++ /* unsigned int */ printk(KERN_DEBUG "\t MaxLogBlocks %d\n",psm->MaxLogBlocks ); ++ /* unsigned char */ printk(KERN_DEBUG "\t Zone %d\n",psm->Zone ); ++ /* unsigned char */ printk(KERN_DEBUG "\t Sector %d\n",psm->Sector ); ++ /* unsigned int */ printk(KERN_DEBUG "\t PhyBlock %d\n",psm->PhyBlock ); ++ /* unsigned int */ printk(KERN_DEBUG "\t LogBlock %d\n",psm->LogBlock ); ++#endif ++} ++#endif ++ ++typedef struct { ++ int sm_error; ++ int lnx_error; ++ char *smerrstr; ++} errmap; ++ ++static errmap error_map_table [] = { ++ { NO_ERROR, 0x0000, ""}, ++ { ERR_WriteFault, EIO, "Peripheral Device Write Fault "}, ++ { ERR_HwError, EIO, "Hardware Error"}, ++ { ERR_DataStatus, EIO, "DataStatus Error"}, ++ { ERR_EccReadErr, EIO, "Unrecovered Read Error" }, ++ { ERR_CorReadErr, EIO, "Recovered Read Data with ECC" }, ++ { ERR_OutOfLBA, EIO, "Illegal Logical Block Address" }, ++ { ERR_WrtProtect, EROFS, "Write Protected" }, ++ { ERR_ChangedMedia, EIO, "Medium Changed" }, ++ { ERR_UnknownMedia, EIO, "Incompatible Medium Installed" }, ++ { ERR_IllegalFmt, EIO, "Medium Format Corrupted" }, ++ { ERR_NoSmartMedia, EIO, "Medium Not Present" } ++}; ++ ++static int ssfdc_maperror(int ssfdc_error) { ++ int loopus=0; ++ ++ if (!ssfdc_error) return 0; ++ ++ do { ++ if (error_map_table[loopus].sm_error == ssfdc_error) { ++ printk("%s\n", error_map_table[loopus].smerrstr); ++ return -error_map_table[loopus].lnx_error; ++ } ++ } while (++loopus < (sizeof(error_map_table) / (sizeof(errmap)))); ++ ++ printk(KERN_ERR "%s: error code %d is not mapped, EIO\n", MAJOR_NAME, ssfdc_error); ++ return -EIO; ++} ++ ++static int ssfdc_thread(void * arg) ++{ ++ ssfdc_dev *psm = arg; ++ unsigned long flags; ++ ++ daemonize("sm%dd",psm->sm_minor); ++ ++ spin_lock_irqsave(¤t->sighand->siglock,flags); // _irq ++ sigfillset(¤t->blocked); ++ recalc_sigpending(); ++ spin_unlock_irqrestore(¤t->sighand->siglock,flags); // _irq ++ ++ while (!psm->exiting) { ++ if ( ssfdc_get_request(psm) ) ++ initxfer(psm->sm_minor); ++ ++ spin_lock_irqsave(&psm->req_queue_lock,flags); // _irq ++ // bjm spin_lock(&psm->req_queue_lock); // _irq ++ psm->waiting = 0; ++ spin_unlock_irqrestore(&psm->req_queue_lock,flags); // _irq ++ // bjm spin_unlock(&psm->req_queue_lock); // _irq ++ if (wait_event_interruptible(psm->thread_wq,ssfdc_get_request(psm))) ++ printk("ssfdc_thread() interrupted\n"); ++ // wait_event(psm->thread_wq,ssfdc_get_request(psm)); ++ spin_lock_irqsave(&psm->req_queue_lock,flags); // _irq ++ // bjm spin_lock(&psm->req_queue_lock); // _irq ++ psm->waiting = 1; ++ spin_unlock_irqrestore(&psm->req_queue_lock,flags); // _irq ++ // bjm spin_unlock(&psm->req_queue_lock); // _irq ++ } ++ ++ printk("ssfdcd Exiting!\n"); ++ ++ complete_and_exit(&psm->thread_dead, 0); ++ ++} ++ ++/* ++ssfdc_init_device(ssfdc_dev *, int minor, unsigned long baseaddr, int removable) ++ reset and initialize the ssfdc_dev structure ++*/ ++static int ssfdc_init_device(ssfdc_dev *psm, int minor, unsigned long baseaddr) ++{ ++ int pid; ++ ++ // Establish ssfdc state ++ psm->XferState = xfer_idle; ++ psm->ErrCode = NO_ERROR; ++ psm->MediaChange = SUCCESS; ++ psm->SectCopyMode = COMPLETED; ++ psm->UseCount = 0; ++ psm->DataBuf_Valid = 0; ++ ++ // set minor number ++ psm->sm_minor = minor; ++ // io address ++ psm->address = baseaddr; ++ if (!request_region(psm->address, 3, "sm")) { ++ printk(KERN_ERR "sm: memory already in use!\n"); ++ return ERROR; ++ } ++ spin_lock_init(&psm->req_queue_lock); ++ ++ // thread related inititializations... ++ init_completion(&psm->thread_dead); ++ init_waitqueue_head(&psm->thread_wq); ++ ++ pid = kernel_thread(ssfdc_thread, psm, CLONE_KERNEL); ++ if (pid < 0) ++ printk("ssfdc: ERROR starting thread!\n"); ++ else ++ printk("ssfdc: started kernel thread sm%dd pid %d\n", psm->sm_minor, pid); ++ ++ // switch on power to device, and set basic attributes of card (no logical to phys mapping) ++ if ( ! CntPowerOn(psm) && ! CheckCardExist(psm) ) { ++ SetPhyFmtValue(psm); ++ } ++ else { ++ printk(KERN_ERR "ssfdc_init_device() unable to SetPhyFmtValue()\n"); ++ } ++ ++#if DEBUG_SSFDC ++ dump_ssfdc_state(psm); ++#endif ++ ++ return SUCCESS; ++} ++ ++static int ssfdc_dev_blk_size(ssfdc_dev *psm) ++{ ++ if (!psm) ++ return 0; ++ ++ // because of the physical to logical block mapping, not as many blocks ++ // as expected... ++ switch(psm->Model) { ++ case SSFDC1MB: ++ return (250 * 8 * 512) / SSFDC_BLKSIZE; ++ case SSFDC2MB: ++ return (500 * 8 * 512) / SSFDC_BLKSIZE; ++ case SSFDC4MB: ++ return (500 * 16 * 512) / SSFDC_BLKSIZE; ++ case SSFDC8MB: ++ return (1000 * 16 * 512) / SSFDC_BLKSIZE; ++ case SSFDC16MB: ++ return (1000 * 32 * 512) / SSFDC_BLKSIZE; ++ case SSFDC32MB: ++ return (2000 * 32 * 512) / SSFDC_BLKSIZE; ++ case SSFDC64MB: ++ return (4000 * 32 * 512) / SSFDC_BLKSIZE; ++ case SSFDC128MB: ++ return (8000 * 32 * 512) / SSFDC_BLKSIZE; ++ default: ++ return 0; ++ } ++} ++ ++inline int ssfdc_dev_sectors(ssfdc_dev *psm) { ++ return ssfdc_dev_blk_size(psm) * (SSFDC_BLKSIZE/SSFDC_SECTSIZE); ++} ++ ++static int ssfdc_open(struct inode *in, struct file *fptr) ++{ ++ int error_code=NO_ERROR; ++ ssfdc_dev *psm = in->i_bdev->bd_disk->private_data; ++ unsigned long flags; ++ ++#if DEBUG_SSFDC ++ printk(KERN_DEBUG "+ssfdc_open()\n"); ++#endif ++ ++ if (!fptr) { ++ return -EIO; ++ } ++ ++ spin_lock_irqsave(&psm->req_queue_lock,flags); ++ // bjm spin_lock(&psm->req_queue_lock); ++ // Power up smartmedia device, check for card, check media ++ if ((error_code=CntPowerOn(psm))) { ++ printk(KERN_ERR "%s PowerUP error\n", MAJOR_NAME); ++ } ++ else if ((error_code=CheckCardExist(psm))) {// Check the existence of a card ++ printk(KERN_ERR "%s No Card!\n", MAJOR_NAME); ++ } ++ else if ( ! psm->UseCount++ ) { ++ spin_unlock_irqrestore(&psm->req_queue_lock,flags); ++ // bjm spin_unlock(&psm->req_queue_lock); ++ check_disk_change(in->i_bdev); ++ spin_lock_irqsave(&psm->req_queue_lock,flags); ++ // bjm spin_lock(&psm->req_queue_lock); ++ } ++ ++ if ( ! psm->ErrCode ) { ++ // check our open mode against that of removable media's ++ if (WRITE_PROTECTED(psm)) { ++ printk(KERN_ERR "mount read only detected.\n"); ++ } ++ } ++ ++#if DEBUG_SSFDC ++ dump_ssfdc_state(psm); ++ printk(KERN_DEBUG "-ssfdc_open() error_code %d\n", error_code); ++#endif ++ ++ spin_unlock_irqrestore(&psm->req_queue_lock,flags); ++ ++#if DEBUG_SSFDC ++ printk("-ssfdc_open()\n"); ++#endif ++ ++ return ssfdc_maperror(error_code); ++} ++ ++static int ssfdc_release(struct inode *i_node, struct file *fptr) ++{ ++ int drive; ++ ssfdc_dev *psm=NULL; ++ unsigned long flags; ++ ++#if DEBUG_SSFDC ++ printk(KERN_DEBUG "+ssfdc_release("); ++#endif ++ ++ psm = (ssfdc_dev *) i_node->i_bdev->bd_disk->private_data; ++ drive = psm->sm_minor; ++ ++#if DEBUG_SSFDC ++ printk(KERN_DEBUG "%d)\n", drive); ++#endif ++ if (drive < 0 || drive >= MAX_SSFDC) ++ return -ENODEV; ++ ++ spin_lock_irqsave(&psm->req_queue_lock,flags); ++ // bjm spin_lock(&psm->req_queue_lock); ++ ++ if (!psm->UseCount) ++ printk(KERN_ERR "sm: Zero use count!\n"); ++ else { ++ --psm->UseCount; ++ } ++ ++#if DEBUG_SSFDC ++ dump_ssfdc_state(psm); ++#endif ++ ++#if DEBUG_SSFDC ++ printk(KERN_DEBUG "-ssfdc_release()\n"); ++#endif ++ ++ spin_unlock_irqrestore(&psm->req_queue_lock,flags); ++ // bjm spin_unlock(&psm->req_queue_lock); ++ ++ return 0; ++} ++ ++static int ssfdc_ioctl(struct inode *i_node, struct file *fptr, unsigned cmd, unsigned long arg) ++{ ++ int err, drive, int_val; ++ unsigned char heads, sectors; ++ unsigned int cylinders; ++ struct hd_geometry geo; ++ ssfdc_dev *psm; ++ ++#if DEBUG_SSFDC ++ printk(KERN_DEBUG "ssfdc_ioctl(%d)", cmd); ++#endif ++ ++ if (i_node == NULL) ++ return -EINVAL; ++ ++ psm = (ssfdc_dev *) i_node->i_bdev->bd_disk->private_data; ++ drive = psm->sm_minor; ++ ++ if (drive < 0 || drive >= MAX_SSFDC) ++ return -ENODEV; ++ switch(cmd) { ++ case BLKROSET: /* set device read-only (0 = read-write) */ ++ if (!capable(CAP_SYS_ADMIN)) ++ return -EACCES; ++ if (copy_from_user((void *) &int_val, (int *)arg, sizeof(int_val))) ++ return -EFAULT; ++ if (int_val) ++ psm->Attribute |= MWP; ++ else ++ psm->Attribute &= ~MWP; ++ return 0; ++ ++ case BLKROGET:/* get read-only status (0 = read_write) */ ++ int_val = psm->Attribute & MWP; ++ copy_to_user(arg, (void *) &int_val, sizeof(int_val)); ++ return 0; ++ ++ /* case BLKRRPART: */ /* re-read partition table */ ++ ++ case BLKGETSIZE: ++#if DEBUG_SSFDC ++ printk(KERN_DEBUG "BLKGETSIZE"); ++#else ++ printk(KERN_DEBUG "ssfdc_ioctl(BLKGETSIZE) not handled.\n"); ++#endif ++ break; ++ ++ case HDIO_GETGEO: ++ if ((void *) arg == NULL) return -EINVAL; ++ if (!access_ok(VERIFY_WRITE, arg, sizeof(geo))) ++ return -EFAULT; ++ if ((err=CheckLogCHS( psm, &cylinders, &heads, §ors))) ++ return ssfdc_maperror(err); ++ memset(&geo, 0, sizeof(geo)); ++ geo.cylinders = cylinders; ++ geo.heads = heads; ++ geo.sectors = sectors; ++ geo.start = get_start_sect(i_node->i_bdev); ++ if (copy_to_user((void *) arg, &geo, sizeof(geo))) ++ return -EFAULT; ++ if (copy_to_user((void *) arg, &geo, sizeof(geo))) ++ return -EFAULT; ++ return 0; ++ } ++ return -EINVAL; ++} ++ ++ ++ ++static int ssfdc_revalidate(struct gendisk *disk) ++{ ++ unsigned int cis; ++ ssfdc_dev *psm=NULL; ++ int error_code=NO_ERROR; ++ unsigned long flags; ++ ++#if DEBUG_SSFDC ++ printk(KERN_DEBUG "ssfdc_revalidate()\n"); ++#endif ++ ++ psm = disk->private_data; ++ ++ spin_lock_irqsave(&psm->req_queue_lock,flags); ++ // bjm spin_lock(&psm->req_queue_lock); ++ ++ if ( ! psm->DataBuf_Valid ) { ++ if ((error_code=SetPhyFmtValue(psm))) ++ printk(KERN_ERR "ssfdc_revalidate() SetPhyFmtValue error\n"); ++ else if ((error_code=SearchCIS(psm,&cis))) ++ printk(KERN_ERR "ssfdc_revalidate() SearchCIS error\n"); ++ else if ((error_code=MakeLogTable(psm,cis+1))) ++ printk(KERN_ERR "ssfdc_revalidate() MakeLogTable error\n"); ++ } ++ spin_unlock_irqrestore(&psm->req_queue_lock,flags); ++ // bjm spin_unlock(&psm->req_queue_lock); ++ ++ return ssfdc_maperror(error_code); ++} ++ ++int __init ssfdc_init(void) ++{ ++ int i; ++ int err = 0; ++ ++#if DEBUG_SSFDC ++ printk(KERN_DEBUG "+ssfdc_init()\n"); ++#endif ++ ++ memset(disks, 0, sizeof(struct gendisk *) * MAX_SSFDC); ++ memset(ssfdc, 0, sizeof(struct ssfdc_dev *) * MAX_SSFDC); ++ for (i=0; i<MAX_SSFDC; ++i) { ++ disks[i] = alloc_disk(1 << SSFDC_PARTN_BITS); ++ ssfdc[i] = kmalloc(sizeof(ssfdc_dev), GFP_KERNEL); ++ if (!disks[i] || !ssfdc[i]) { ++ err = -ENOMEM; ++ goto no_memory_error; ++ } ++ memset( ssfdc[i], 0, sizeof(ssfdc_dev)); ++ } ++ ++ if (register_blkdev(SSFDC_MAJOR, "smartmedia")) { ++ printk(KERN_ERR "Unable to get major number %d for ssfdc device\n", ++ SSFDC_MAJOR); ++ err = -EBUSY; ++ goto busy_error; ++ } ++ ++ devfs_mk_dir("sm"); ++ ++ for ( i=0; i < MAX_SSFDC; ++i) { ++ disks[i]->major = SSFDC_MAJOR; ++ disks[i]->first_minor = i << SSFDC_PARTN_BITS; ++ disks[i]->fops = &ssfdc_fops; ++ sprintf(disks[i]->disk_name, "sm%d", i); ++ sprintf(disks[i]->devfs_name, "sm/%d", i); ++ disks[i]->private_data = ssfdc[i]; ++ ssfdc_init_device(ssfdc[i], i << SSFDC_PARTN_BITS, ++ CPLD_BASE_ADDRESS + SMART_MEDIA_ONE_OFFSET); ++ ++ disks[i]->queue = ssfdc[i]->req_queue = ++ blk_init_queue(do_ssfdc_request, &ssfdc[i]->req_queue_lock); ++ ssfdc[i]->req_queue->queuedata = ssfdc[i]; ++ ++ set_capacity(disks[i], ssfdc_dev_sectors(ssfdc[i])); ++ // bjm blk_queue_max_sectors(disks[i]->queue, 32); ++ // bjm blk_queue_max_phys_segments(disks[i]->queue, 4); ++ blk_queue_max_segment_size(disks[i]->queue, (ssfdc[i]->MaxSectors / 2) * K_BYTE); ++ add_disk(disks[i]); ++ } ++ ++#if 0 // bjm debug ++#ifndef CONFIG_SH_NIMBLE_MINI ++ mediachangetest(0L); ++#else ++ mediachangetest(1L); ++#endif ++#endif // bjm debug ++ ++#if DEBUG_SSFDC ++ printk(KERN_DEBUG "-ssfdc_init(0)\n"); ++#endif ++ return 0; ++ ++busy_error: ++no_memory_error: ++ for (i=0; i < MAX_SSFDC; ++i) { ++ if (disks[i] && disks[i]->queue) ++ kfree(disks[i]->queue); ++ put_disk(disks[i]); ++ if (ssfdc[i]) ++ kfree(ssfdc[i]); ++ } ++#if DEBUG_SSFDC ++ printk(KERN_DEBUG "-ssfdc_init(%d)\n", -ENOMEM); ++#endif ++ return -ENOMEM; ++} ++ ++void __init ssfdc_clean(void) ++{ ++ int i; ++ ++ printk(KERN_DEBUG "SSFDC exit code\n"); ++ ++ for (i=0; i < MAX_SSFDC; ++i) { ++ if (disks[i] != NULL) { ++ blk_cleanup_queue(disks[i]->queue); ++ del_gendisk(disks[i]); ++ put_disk(disks[i]); ++ } ++ ++ if (ssfdc[i]) { ++ // signal thread to exit... ++ ssfdc[i]->exiting = 1; ++ wake_up(&ssfdc[i]->thread_wq); ++ wait_for_completion(&ssfdc[i]->thread_dead); ++ ++ if (ssfdc[i]->address) ++ release_region(ssfdc[i]->address, 3); ++ kfree(ssfdc[i]); ++ } ++ } ++ ++ if (unregister_blkdev(SSFDC_MAJOR, "smartmedia")) ++ printk(KERN_WARNING "smartmedia: cannot unregister blkdev\n"); ++ devfs_remove("sm"); ++} ++ ++#if DEBUG_SSFDC ++void dump_request(struct request *req) ++{ ++#if DEBUG_SSFDC_REQUEST && DEBUG_SSFDC_REQUEST ++ printk(KERN_DEBUG "req->\n"); ++ /* int */ printk(KERN_DEBUG "\t req->cmd %x\n", req->cmd); /* READ or WRITE */ ++ /* int errors */ printk(KERN_DEBUG "\t req->errors %d\n", req->errors); ++ /* unsigned long */ printk(KERN_DEBUG "\t req->sector %d\n", req->sector); ++ /* unsigned long */ printk(KERN_DEBUG "\t req->nr_sectors %d\n",req->nr_sectors); ++ /* unsigned long */ printk(KERN_DEBUG "\t req->hard_sector %d\n", req->hard_sector); ++ /* unsigned int */ printk(KERN_DEBUG "\t req->nr_hw_segments %d\n",req->nr_hw_segments); ++ /* unsigned long */ printk(KERN_DEBUG "\t req->current_nr_sectors %d\n",req->current_nr_sectors); ++ ++#endif ++} ++#endif ++ ++void do_ssfdc_request(request_queue_t * rq) ++{ ++ ssfdc_dev *psm = rq->queuedata; ++ ++ if ( ! psm->waiting ) ++ wake_up(&psm->thread_wq); ++} ++ ++static struct request * ssfdc_get_request(ssfdc_dev *psm) ++{ ++ struct request *treq; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&psm->req_queue_lock, flags); ++ // bjm spin_lock(&psm->req_queue_lock); ++ treq = elv_next_request(psm->req_queue); ++ spin_unlock_irqrestore(&psm->req_queue_lock, flags); ++ // bjm spin_unlock(&psm->req_queue_lock); ++ ++ return treq; ++} ++ ++static void ssfdc_terminate_request(ssfdc_dev *psm, struct request *req) ++{ ++ unsigned long flags; ++ ++ if (psm && req) { ++ spin_lock_irqsave(&psm->req_queue_lock, flags); ++ // bjm spin_lock(&psm->req_queue_lock); ++ end_request(req,0); ++ spin_unlock_irqrestore(&psm->req_queue_lock, flags); ++ // bjm spin_unlock(&psm->req_queue_lock); ++ } ++} ++ ++ ++static int ssfdc_end_request(ssfdc_dev *psm, struct request *req, int status) ++{ ++ unsigned long flags; ++ ++ if (!psm || !req) { ++ printk(KERN_DEBUG "ssfdc_end_request() NULL psm or req!\n"); ++ return 0; ++ } ++ ++#if DEBUG_SSFDC_REQUEST ++ printk("ssfdc_end_request(%p)\n", req); ++#endif ++ ++ spin_lock_irqsave(&psm->req_queue_lock,flags); ++ // bjm spin_lock(&psm->req_queue_lock); ++ end_request(req,status); ++ spin_unlock_irqrestore(&psm->req_queue_lock,flags); ++ // bjm spin_unlock(&psm->req_queue_lock); ++ return 0; ++} ++ ++void initxfer(unsigned long dev_idx) ++{ ++ ssfdc_dev *psm = ssfdc[dev_idx]; ++ struct request *req; ++ int error_code; ++ unsigned int cis; ++ ++#if DEBUG_SSFDC ++ // printk(KERN_DEBUG "+initxfer(%d)", dev_idx); ++#endif ++ // get device lock, and check idle flag, setting if not busy ++ ++ req = ssfdc_get_request(psm); ++ ++ // if the device is idle, setup a read or write operation ++ if (psm->XferState == xfer_idle) { ++ // get the current request from our device's request list. ++ if (!req) { ++#if DEBUG_SSFDC ++// printk(KERN_DEBUG "initxfer() terminate, no schedule.\n"); ++#endif ++ } ++ // Absence of power indicates absence of card. ++ // terminate request and exit... ++ if ( ! _HwChkPower(psm) ) { ++ printk(KERN_DEBUG "initxfer() - Media power NOT!\n"); ++ ssfdc_terminate_request(psm,req); ++ return; ++ } ++ ++ // We have a request and we have a card. Is the Log2Phys mapping still valid? ++ if ( ! psm->DataBuf_Valid ) { ++ if ((error_code = SetPhyFmtValue(psm))) ++ printk(KERN_DEBUG "%s SetPhyFmtValue error\n", MAJOR_NAME); ++ else if ((error_code = SearchCIS(psm,&cis))) ++ printk(KERN_DEBUG "%s SearchCIS error\n", MAJOR_NAME); ++ else if ((error_code = MakeLogTable(psm,cis+1))) ++ printk(KERN_DEBUG "%s MakeLogTable error\n", MAJOR_NAME); ++ if (error_code) { ++ printk(KERN_DEBUG "%s error %d\n", MAJOR_NAME, error_code); ++ ssfdc_terminate_request(psm,req); ++ return; ++ } ++ } ++ ++ psm->XferState = xfer_busy; ++#if DEBUG_SSFDC ++ printk(KERN_DEBUG " initxfer() - do the request %x\n", req); ++#endif ++ ssfdc_rw_request(psm, req); ++ } ++#if DEBUG_SSFDC ++ else { ++ printk(KERN_DEBUG "initxfer(%d) dev is busy, no reschedule.\n", dev_idx); ++ } ++#endif ++ ++} ++ ++ ++void ssfdc_rw_request(ssfdc_dev *psm, struct request *req) ++{ ++ int (*rwsector)(ssfdc_dev *, struct request *, char *, long, int); ++ unsigned sector, count; ++ int rw_return=1; ++ ++ if (rq_data_dir(req) == WRITE) ++ rwsector = MediaWriteSector; ++ else if (rq_data_dir(req) == READ) ++ rwsector = MediaReadSector; ++ else { ++ printk(KERN_DEBUG "%s: command %d not implemented!\n", MAJOR_NAME, (int) rq_data_dir(req)); ++ goto terminal_error; ++ } ++ ++ /* ++ */ ++ sector = req->sector; ++ count = req->nr_sectors; ++ ++ // check that the request does not extend past ssfdc's max size ++ if ( (sector + count) > ssfdc_dev_sectors(psm) ) { ++ printk(KERN_ERR "Attempt to read past end of device!"); ++ goto terminal_error; ++ } ++ else { ++ ++ // for each segment in each bio_vec R/W from/to device. ++ ++ count = req->current_nr_sectors; ++ rw_return = rwsector(psm, req, req->buffer, sector, count); ++ ++ if (rq_data_dir(req) == READ) ++ ssfdc_end_request(psm, req, rw_return); ++ } ++ ++ // things appear OK... ++ return; ++ ++terminal_error: ++ ssfdc_terminate_request( psm, req); ++ psm->XferState = xfer_idle; ++} ++ ++module_init(ssfdc_init); ++module_exit(ssfdc_clean); ++ ++MODULE_LICENSE("GPL"); ++ ++/* End of Linux Driver Modifications */ +diff -durN -X ../diff.ignore linux/drivers/block/ssfdc.h gcc3.4.4/drivers/block/ssfdc.h +--- linux/drivers/block/ssfdc.h 1970-01-01 10:00:00.000000000 +1000 ++++ gcc3.4.4/drivers/block/ssfdc.h 2005-11-09 14:00:47.000000000 +1100 +@@ -0,0 +1,372 @@ ++/* $id: $ */ ++#ifndef _SSFDC_H ++#define _SSFDC_H ++ ++/* ++ Linux related defines ++*/ ++ ++#ifdef CONFIG_SH_NIMBLE_MINI ++#define MAX_SSFDC 2 /* two drives */ ++#else ++#define MAX_SSFDC 1 /* only one drive */ ++#endif ++ ++#define SSFDC_MAJOR_NAME "sm" ++#define MAJOR_NAME SSFDC_MAJOR_NAME ++#define SSFDC_PARTN_BITS 4 /* number of minor dev bits for partitions */ ++#define PARTN_MASK ((1<<SSFDC_PARTN_BITS)-1) /* a useful bit mask */ ++#define MAX_DRIVES MAX_SSFDC ++ ++/*************************************************************************** ++ SmartMedia Controll Header ++ Rev 0.30('98-06-30) ***** BETA RELEASE ***** ++ Copyright (c) 1997-98, Toshiba Corporation. All rights reserved. ++ ***************************************************************************/ ++ ++/*************************************************************************** ++ Define Difinetion ++ ***************************************************************************/ ++#define SUCCESS 0 /* SUCCESS */ ++#define ERROR -1 /* ERROR */ ++#define CORRECT 1 /* CORRECTABLE */ ++ ++/***************************************************************************/ ++#define NO_ERROR 0x0000 /* NO ERROR */ ++#define ERR_WriteFault 0x0003 /* Peripheral Device Write Fault */ ++#define ERR_HwError 0x0004 /* Hardware Error */ ++#define ERR_DataStatus 0x0010 /* DataStatus Error */ ++#define ERR_EccReadErr 0x0011 /* Unrecovered Read Error */ ++#define ERR_CorReadErr 0x0018 /* Recovered Read Data with ECC */ ++#define ERR_OutOfLBA 0x0021 /* Illegal Logical Block Address */ ++#define ERR_WrtProtect 0x0027 /* Write Protected */ ++#define ERR_ChangedMedia 0x0028 /* Medium Changed */ ++#define ERR_UnknownMedia 0x0030 /* Incompatible Medium Installed */ ++#define ERR_IllegalFmt 0x0031 /* Medium Format Corrupted */ ++#define ERR_NoSmartMedia 0x003A /* Medium Not Present */ ++ ++/*************************************************************************** ++ Common Controll Header ++ Rev 1.30('98-06-30) ***** BETA RELEASE ***** ++ Copyright (c) 1997-98, Toshiba Corporation. All rights reserved. ++ ***************************************************************************/ ++ ++/*************************************************************************** ++ SmartMedia Controller Definition ++ ***************************************************************************/ ++/* I/O Mode Address */ ++#define DATA(p) (p->address+0x00) /* R/W Data Reg */ ++#define STATUS(p) (p->address+0x02) /* R/- Status Reg */ ++#define MODE(p) (p->address+0x02) /* -/W Mode Reg */ ++ ++/* Controller Status Reg (Read Only) */ ++#define STS_BUSY 0x80 ++#define STS_VCC 0x10 ++#define STS_SCHG 0x08 ++#define STS_WP 0x01 ++#define STS_CENB 0x04 ++ ++#ifdef CONFIG_SH_TITAN ++/* Controller Mode Reg (Write Only) */ ++/* keep PCI clock running on bit 3 */ ++/* CE# on bit 2, CLE on bit 1 and ALE on bit 0 */ ++#define STANDBY (0x00 | 0x00 | 0x08) ++#define WR_DATA (0x00 | 0x04 | 0x08) ++#define WR_CMD (0x02 | 0x04 | 0x08) ++#define WR_ADR (0x01 | 0x04 | 0x08) ++#else ++/* Controller Mode Reg (Write Only) */ ++#define STANDBY 0x00 ++#define WR_DATA 0x10 ++#define WR_CMD 0x11 ++#define WR_ADR 0x12 ++#define PW_OFF 0x80 ++#define PW_ON 0x88 ++#endif ++ ++/***************************************************************************/ ++#define _HwSetData(p) ctrl_outb(WR_DATA,MODE(p)) ++#define _HwSetCmd(p) ctrl_outb(WR_CMD,MODE(p)) ++#define _HwSetAddr(p) ctrl_outb(WR_ADR,MODE(p)) ++#define _HwSetStandby(p) ctrl_outb(STANDBY,MODE(p)) ++ ++#define _HwInData(p) ctrl_inb(DATA(p)) ++#define _HwOutData(p,a) ctrl_outb((a),DATA(p)) ++ ++#ifdef CONFIG_SH_TITAN ++#define _HwVccOn(p) ++#define _HwVccOff(p) ++#else ++#define _HwVccOn(p) ctrl_outb(PW_ON,MODE(p)) ++#define _HwVccOff(p) ctrl_outb(PW_OFF,MODE(p)) ++#endif ++ ++#ifdef CONFIG_SH_TITAN ++#define _HwChkCardIn(p) (1) ++#define _HwChkStatus(p) (0) ++#define _HwChkWP(p) (0) ++#define _HwChkPower(p) (1) ++#define _HwChkBusy(p) (ctrl_inb(STATUS(p))&STS_BUSY) ++ ++#else ++ ++#define _HwChkCardIn(p) (ctrl_inb(STATUS(p))&STS_CENB) ++#define _HwChkStatus(p) (ctrl_inb(STATUS(p))&(STS_SCHG)) ++#define _HwChkWP(p) (ctrl_inb(STATUS(p))&(STS_WP)) ++#define _HwChkPower(p) (ctrl_inb(STATUS(p))&(STS_VCC)) ++#define _HwChkBusy(p) (ctrl_inb(STATUS(p))&STS_BUSY) ++ ++#endif ++ ++#define _HwRdStatus(p) (ctrl_inb(STATUS(p))) ++/***************************************************************************/ ++#ifdef CONFIG_SH_NIMBLE_MINI ++#define CPLD_BASE_ADDRESS 0xB4030000L ++#define SMART_MEDIA_ONE_OFFSET 0x08 // The "built-in" SmartMedia ++#define SMART_MEDIA_TWO_OFFSET 0x00 // The "removable" SmartMedia ++#elif CONFIG_SH_TITAN ++#define CPLD_BASE_ADDRESS 0xA4000000L ++#define SMART_MEDIA_ONE_OFFSET 0x00 ++#else ++#define CPLD_BASE_ADDRESS 0xB8030000L ++#define SMART_MEDIA_ONE_OFFSET 0x00 // The "built-in" SmartMedia ++#endif ++ ++/*************************************************************************** ++ Program & Macro for SmartMedia Controller ++ Rev 0.30('98-06-30) ***** BETA RELEASE ***** ++ Copyright (c) 1997-98, Toshiba Corporation. All rights reserved. ++ ***************************************************************************/ ++/*************************************************************************** ++ Define Definition ++ ***************************************************************************/ ++#define K_BYTE 1024 /* Kilo Byte */ ++#define SSFDC_SECTSIZE 512 /* Sector buffer size */ ++#define SSFDC_BLKSIZE (K_BYTE * 4) ++#define REDTSIZE 16 /* Redundant buffer size */ ++ ++/***************************************************************************/ ++#define DUMMY_DATA 0xFF /* No Assign Sector Read Data */ ++ ++/*************************************************************************** ++ Max Zone/Block/Sectors Data Definition ++ ***************************************************************************/ ++#define MAX_ZONENUM 0x08 /* Max Zone Numbers in a SmartMedia */ ++#define MAX_BLOCKNUM 0x0400 /* Max Block Numbers in a Zone */ ++#define MAX_SECTNUM 0x20 /* Max Sector Numbers in a Block */ ++#define MAX_LOGBLOCK 1000 /* Max Logical Block Numbers in a Zone */ ++ ++/*************************************************************************** ++ Logical to Physical Block Table Data Definition ++ ***************************************************************************/ ++#define NO_ASSIGN 0xFFFF /* No Assign Logical Block Address */ ++ ++/*************************************************************************** ++ 'SectCopyMode' Data ++ ***************************************************************************/ ++#define COMPLETED 0 /* Sector Copy Completed */ ++#define REQ_ERASE 1 /* Request Read Block Erase */ ++#define REQ_FAIL 2 /* Request Read Block Failed */ ++ ++/*************************************************************************** ++ Retry Counter Definition ++ ***************************************************************************/ ++#define RDERR_REASSIGN 1 /* Reassign with Read Error */ ++#define L2P_ERR_ERASE 1 /* BlockErase for Contradicted L2P Table */ ++ ++/*************************************************************************** ++ SmartMedia Command & Status Definition ++ ***************************************************************************/ ++/* SmartMedia Command */ ++#define SSFDC_WRDATA 0x80 ++#define SSFDC_READ 0x00 ++#define SSFDC_READ_REDT 0x50 ++#define SSFDC_READ1 0x00 ++#define SSFDC_READ2 0x01 ++#define SSFDC_READ3 0x50 ++#define SSFDC_RST_CHIP 0xFF ++#define SSFDC_WRITE 0x10 ++#define SSFDC_DUMMY_WRITE 0x11 ++#define SSFDC_MULTI_WRITE 0x15 ++#define SSFDC_ERASE1 0x60 ++#define SSFDC_ERASE2 0xD0 ++#define SSFDC_RDSTATUS 0x70 ++#define SSFDC_READ_ID 0x90 ++ ++/* SmartMedia Status */ ++#define WR_FAIL 0x01 /* 0:Pass, 1:Fail */ ++#define SUSPENDED 0x20 /* 0:Not Suspended, 1:Suspended */ ++#define READY 0x40 /* 0:Busy, 1:Ready */ ++#define WR_PRTCT 0x80 /* 0:Protect, 1:Not Protect */ ++ ++#define USEC 1 ++#define MSEC 1000 * USEC ++#define JIFFY_TICK_MS (MSEC / HZ) ++ ++// #define BUSY_PROG 20 * MSEC /* 200-1000us ----- Program Time */ ++#define BUSY_PROG 1000 * USEC /* 200-1000us ----- Program Time */ ++#define BUSY_DUMMY_WRITE 10 * USEC /* 2-10us dummy write */ ++#define BUSY_MULTI_WRITE 1000 * USEC /* 200 - 1000 usec */ ++#define BUSY_ERASE 10 * MSEC /* 2-10ms ----- Block Erase Time */ ++#define BUSY_READ 100 * USEC /* tR : 100us ----- Data transfer Time */ ++#define BUSY_RESET 10 * USEC /* tRST : 10us ----- Device Resetting Time */ ++#define BUSY_ADDR_SET 25 * USEC ++ ++#define TIME_PON 30 /* 300ms ------ Power On Wait Time */ ++#define TIME_CDCHK 2 /* 20ms ------ Card Check Interval Timer */ ++#define TIME_WPCHK 1 /* 5ms ------ WP Check Interval Timer */ ++ ++/* Power On Timeout */ ++#define POWER_ON_TIMEOUT (HZ*2) ++ ++/* Default retry limit for Read/Write */ ++#define RD_RETRY_LIMIT 3 ++#define WR_RETRY_LIMIT 4 ++#define BLOCK_READ_RETRY_LIMIT 2 ++#define BLOCK_WRITE_RETRY_LIMIT 3 ++#define REASSIGN_RETRY_LIMIT 4 ++ ++/*************************************************************************** ++ Redundant Data ++ ***************************************************************************/ ++#define REDT_DATA 0x04 ++#define REDT_BLOCK 0x05 ++ ++#define REDT_ADDR1H 0x06 ++#define REDT_ADDR1L 0x07 ++#define REDT_ADDR2H 0x0B ++#define REDT_ADDR2L 0x0C ++ ++#define REDT_ECC10 0x0D ++#define REDT_ECC11 0x0E ++#define REDT_ECC12 0x0F ++ ++#define REDT_ECC20 0x08 ++#define REDT_ECC21 0x09 ++#define REDT_ECC22 0x0A ++ ++/*************************************************************************** ++ SmartMedia Model & Attribute ++ ***************************************************************************/ ++/* SmartMedia Attribute */ ++#define NOWP 0x00 /* 0... .... No Write Protect */ ++#define WP 0x80 /* 1... .... Write Protected */ ++#define MASK 0x00 /* .00. .... NAND MASK ROM Model */ ++#define FLASH 0x20 /* .01. .... NAND Flash ROM Model */ ++#define AD3CYC 0x00 /* ...0 .... Address 3-cycle */ ++#define AD4CYC 0x10 /* ...1 .... Address 4-cycle */ ++#define BS16 0x00 /* .... 00.. 16page/block */ ++#define BS32 0x04 /* .... 01.. 32page/block */ ++#define PS256 0x00 /* .... ..00 256byte/page */ ++#define PS512 0x01 /* .... ..01 512byte/page */ ++ ++#define MWP 0x80 /* WriteProtect mask */ ++#define MFLASH 0x60 /* Flash Rom mask */ ++#define MADC 0x10 /* Address Cycle */ ++#define MBS 0x0C /* BlockSize mask */ ++#define MPS 0x03 /* PageSize mask */ ++ ++/* SmartMedia Model */ ++#define NOSSFDC 0x00 /* NO SmartMedia */ ++#define SSFDC1MB 0x01 /* 1MB SmartMedia */ ++#define SSFDC2MB 0x02 /* 2MB SmartMedia */ ++#define SSFDC4MB 0x03 /* 4MB SmartMedia */ ++#define SSFDC8MB 0x04 /* 8MB SmartMedia */ ++#define SSFDC16MB 0x05 /* 16MB SmartMedia */ ++#define SSFDC32MB 0x06 /* 32MB SmartMedia */ ++#define SSFDC64MB 0x07 /* 64MB SmartMedia */ ++#define SSFDC128MB 0x08 /*128MB SmartMedia */ ++ ++#define EVEN 0 /* Even Page for 256byte/page */ ++#define ODD 1 /* Odd Page for 256byte/page */ ++ ++/*************************************************************************** ++ Struct Definition ++ ***************************************************************************/ ++/* Linux kernel additions */ ++ ++/* device buffer xfer status */ ++typedef enum { xfer_idle, xfer_busy} xfer_states; ++ ++/* Smartmedia device structure */ ++typedef struct { ++ unsigned long address; ++ int sm_minor; ++ int sm_flags; ++ int busy; ++ int waiting; ++ ++ /* queue of io requests for the device */ ++ spinlock_t req_queue_lock; ++ request_queue_t *req_queue; ++ ++ /* our thread related parameters */ ++ struct completion thread_dead; ++ int exiting; ++ wait_queue_head_t thread_wq; ++ ++ /* accounting variables for each buffer io operation ++ each request may have a chain of buffers, each of ++ which may require I/O of multiple sectors */ ++ unsigned int ReqSectorSize; ++ unsigned int BufIndex; ++ unsigned int SectorWriteIndex; ++ ++ /* CHS parameters */ ++ unsigned int HostCyl; ++ unsigned char HostHead; ++ unsigned char HostSect; ++ ++ /* State Information */ ++ xfer_states XferState; ++ unsigned int UseCount; ++ unsigned int RetryCount; ++ unsigned int ErrCode; ++ unsigned int MediaChange; ++ unsigned int CardPresent; ++ unsigned int SectCopyMode; ++ ++ /* Working Databuf Area */ ++ unsigned char SectBuf[SSFDC_SECTSIZE]; ++ unsigned char WorkBuf[SSFDC_SECTSIZE]; ++ unsigned char Redundant[REDTSIZE]; ++ unsigned char WorkRedund[REDTSIZE]; ++ unsigned int DataBuf_Valid; ++ unsigned int Log2Phy[MAX_ZONENUM][MAX_LOGBLOCK]; ++ unsigned char Assign[MAX_ZONENUM][MAX_BLOCKNUM/8]; ++ unsigned int AssignStart[MAX_ZONENUM]; ++ unsigned int ReadBlock; ++ unsigned int WriteBlock; ++ ++ /* Card attributes */ ++ unsigned char Model; ++ unsigned char Attribute; ++ unsigned char MaxZones; ++ unsigned char MaxSectors; ++ unsigned int MaxBlocks; ++ unsigned int MaxLogBlocks; ++ ++ /* Address of current access (Media) */ ++ unsigned char Zone; /* Zone Number */ ++ unsigned char Sector; /* Sector(512byte) Number on Block */ ++ unsigned int PhyBlock; /* Physical Block Number on Zone */ ++ unsigned int LogBlock; /* Logical Block Number of Zone */ ++ ++ /* device statistics */ ++ unsigned int Sector_reads; ++ unsigned int Sector_writes; ++ unsigned int Sect_rd_errs_ttl; ++ unsigned int Sect_wr_errs_ttl; ++ unsigned int Bad_blks_rd; ++ unsigned int Bad_blks_wr; ++ unsigned int Bad_blks_erase; ++} ssfdc_dev; ++ ++ ++/****************************************************************************/ ++/* Handy defines */ ++/****************************************************************************/ ++#define WRITE_PROTECTED(p) (p->Attribute & WP) ++ ++/* End of Linux kernel additions */ ++#endif /* #ifndef _SSFDC_H */ diff --git a/packages/linux/linux-titan-sh4_2.6.16.bb b/packages/linux/linux-titan-sh4_2.6.16.bb new file mode 100644 index 0000000000..2c4316aea0 --- /dev/null +++ b/packages/linux/linux-titan-sh4_2.6.16.bb @@ -0,0 +1,49 @@ +SECTION = "kernel" +DESCRIPTION = "Linux kernel for SH4 based TITAN router appliance" +LICENSE = "GPL" +MAINTAINER = "Jamie Lenehan <lenehan@twibble.org> +PR = "r0" + +# The "date=20060328" should be changed to "tag=linux-2_6_16" - but the +# tag won't exit till 2.6.17 is released +SRC_URI = "ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-${PV}.tar.bz2 \ +cvs://anonymous@linuxsh.cvs.sourceforge.net/cvsroot/linuxsh;module=linux;data=20060331 \ + file://titan-flash.patch;patch=1 \ + file://titan-config" +S = "${WORKDIR}/linux-${PV}" + +COMPATIBLE_HOST = 'sh4.*-linux' + +inherit kernel + +ARCH = "sh" +KERNEL_IMAGETYPE = "vmlinux" +KERNEL_OUTPUT = "${KERNEL_IMAGETYPE}" + +# +# The linux-sh cvs tree is a "drop in source tree" and needs to be copied +# over the top of the normal linux source since it only includes modified +# files. +# +do_unpack_extra(){ + cp -pPR ${WORKDIR}/linux/* ${S} +} +addtask unpack_extra after do_unpack before do_patch + +# +# Use an updated defconfig which includes the flash driver +# The flash driver quality doesn't allow it to be a part of the main kernel +# +do_configure_prepend() { + install -m 0644 ${WORKDIR}/titan-config ${S}/arch/sh/configs/titan_defconfig + yes '' | oe_runmake titan_defconfig +} + +# +# Should I make the nfs boot image? +# +#do_deploy_titan() { +# To NFS boot you need to objcopy the image... +# ${HOST_PREFIX}objcopy -O binary -R .note -R .comment -S arch/sh/boot/compressed/vmlinux ${DEPLOY_DIR}/linux.bin +#} +#addtask deploy before do_build after do_compile |