aboutsummaryrefslogblamecommitdiffstats
path: root/arch/arm/configs/mv78xx0_defconfig
blob: 398274b0771aa3538987eafad9143b063f34fc30 (plain) (tree)
1
2
3
4
5
6
7
8

                                                 

                                  


                                   
                     















                                      
                                    


















                                                           








                                     

                            
                               
                           






                                  
                    


                       


                                       
                                  



                 

                  




                 
            
                          
                   
                              
                   



                        
                    






                           

                                  
                   






                                         

                       
                               
                                     












                                    
                           








                                   
                                 

                                
                               



















                                   
                            


                                
                                



                                

                                




                                 
                          
























                                      
                                                  








                                     

                            








                                  



                              



                    



                                            





                                       

                             

                                     

                    


                              











                              




                            














                                         

                                                 







                               


































                                      
                 













                                     
                           








                              
                          
                             
                       





                                
                                    




                            

                            













                                         

                                      







                                  
                             




















































                                         
                                      























                                       
                                 









                                       




                             



















                                      

                             
                              
                                      









                                 
























































                                                           
                                
                               


                           

















                                      

                                      

































































                                    



                                                                       



                            
                           






                             



















                                   








                                   



                            





                                      


                                                  





                                    








                            
                            



                             
                        




                          

                          
                         












                                


                         







                                 



                                                            











































































                                        
                                             



                                







                              
                        



                          



                                  





                               
                            

                               


                               

                              


















                                                           
                               



                             
                                    
                            




                                

                                   
                                   










                                   
                                  






                                   
                                   

                                   
                                   





                                    
                                 













                                   


                                   



                                   

                                   


















                                      

                                 
                            
                     



                          




                              
                            
                             
                              





                                  





























                                         









                             
                           
                              



























                                   
















                                            


                                 







                                  
                                    





                                    

                                






                           
                           

 
                                                      


 
                                                    





                                      














                                             











                              
                              






                                      








                                      
                           
                              






                                 
                       

                                 





                   




                                






                               
                                          
                                           



                                                         





























                                         

                                  








                                
                                  




                                    
                                  
                                  
                                  




                                 


                              
                       
                           







                                 
                                            
                                 




                                     
            



                              


                                
                     

                            
                            








                              




                           






















                                        
                          




                                   
                         


















                                             
                            

                            
                           




                             
                             




                              
                 
                        



                   















































































                                         
                 



                                 




                                              













                                               
                   
                                 
                                 



                                    
                                     

                              
                                   

                                     
                                          

                                       
                                        


                                   
























                                          
                           


                        










                                     
                              





                                              
                               
                      

                       
                         



                          
                       
                        

                                   
                         


































                                               



                                 




























                                   
                               
                              




                                     

                                        
                      




                   
                              
                             

                              





                             


                   
               
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.30-rc4
# Mon May  4 14:22:12 2009
#
CONFIG_ARM=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
CONFIG_GENERIC_GPIO=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_MMU=y
# CONFIG_NO_IOPORT is not set
CONFIG_GENERIC_HARDIRQS=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_HAVE_LATENCYTOP_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
CONFIG_VECTORS_BASE=0xffff0000
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"

#
# General setup
#
CONFIG_EXPERIMENTAL=y
CONFIG_BROKEN_ON_SMP=y
CONFIG_LOCK_KERNEL=y
CONFIG_INIT_ENV_ARG_LIMIT=32
CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set

#
# RCU Subsystem
#
CONFIG_CLASSIC_RCU=y
# CONFIG_TREE_RCU is not set
# CONFIG_PREEMPT_RCU is not set
# CONFIG_TREE_RCU_TRACE is not set
# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_GROUP_SCHED is not set
# CONFIG_CGROUPS is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
# CONFIG_BLK_DEV_INITRD is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
CONFIG_ANON_INODES=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
# CONFIG_KALLSYMS_EXTRA_PASS is not set
# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
# CONFIG_SLUB_DEBUG is not set
CONFIG_COMPAT_BRK=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
CONFIG_PROFILING=y
CONFIG_TRACEPOINTS=y
# CONFIG_MARKERS is not set
CONFIG_OPROFILE=y
CONFIG_HAVE_OPROFILE=y
CONFIG_KPROBES=y
CONFIG_KRETPROBES=y
CONFIG_HAVE_KPROBES=y
CONFIG_HAVE_KRETPROBES=y
# CONFIG_SLOW_WORK is not set
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_RT_MUTEXES=y
CONFIG_BASE_SMALL=0
CONFIG_MODULES=y
# CONFIG_MODULE_FORCE_LOAD is not set
CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_FORCE_UNLOAD is not set
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_BLOCK=y
# CONFIG_LBD is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set

#
# IO Schedulers
#
CONFIG_IOSCHED_NOOP=y
CONFIG_IOSCHED_AS=y
CONFIG_IOSCHED_DEADLINE=y
CONFIG_IOSCHED_CFQ=y
# CONFIG_DEFAULT_AS is not set
# CONFIG_DEFAULT_DEADLINE is not set
CONFIG_DEFAULT_CFQ=y
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="cfq"
# CONFIG_FREEZER is not set

#
# System Type
#
# CONFIG_ARCH_AAEC2000 is not set
# CONFIG_ARCH_INTEGRATOR is not set
# CONFIG_ARCH_REALVIEW is not set
# CONFIG_ARCH_VERSATILE is not set
# CONFIG_ARCH_AT91 is not set
# CONFIG_ARCH_CLPS711X is not set
# CONFIG_ARCH_EBSA110 is not set
# CONFIG_ARCH_EP93XX is not set
# CONFIG_ARCH_GEMINI is not set
# CONFIG_ARCH_FOOTBRIDGE is not set
# CONFIG_ARCH_NETX is not set
# CONFIG_ARCH_H720X is not set
# CONFIG_ARCH_IMX is not set
# CONFIG_ARCH_IOP13XX is not set
# CONFIG_ARCH_IOP32X is not set
# CONFIG_ARCH_IOP33X is not set
# CONFIG_ARCH_IXP23XX is not set
# CONFIG_ARCH_IXP2000 is not set
# CONFIG_ARCH_IXP4XX is not set
# CONFIG_ARCH_L7200 is not set
# CONFIG_ARCH_KIRKWOOD is not set
# CONFIG_ARCH_KS8695 is not set
# CONFIG_ARCH_NS9XXX is not set
# CONFIG_ARCH_LOKI is not set
CONFIG_ARCH_MV78XX0=y
# CONFIG_ARCH_MXC is not set
# CONFIG_ARCH_ORION5X is not set
# CONFIG_ARCH_PNX4008 is not set
# CONFIG_ARCH_PXA is not set
# CONFIG_ARCH_MMP is not set
# CONFIG_ARCH_RPC is not set
# CONFIG_ARCH_SA1100 is not set
# CONFIG_ARCH_S3C2410 is not set
# CONFIG_ARCH_S3C64XX is not set
# CONFIG_ARCH_SHARK is not set
# CONFIG_ARCH_LH7A40X is not set
# CONFIG_ARCH_DAVINCI is not set
# CONFIG_ARCH_OMAP is not set
# CONFIG_ARCH_MSM is not set
# CONFIG_ARCH_W90X900 is not set

#
# Marvell MV78xx0 Implementations
#
CONFIG_MACH_DB78X00_BP=y
CONFIG_MACH_RD78X00_MASA=y
CONFIG_PLAT_ORION=y

#
# Processor Type
#
CONFIG_CPU_32=y
CONFIG_CPU_FEROCEON=y
CONFIG_CPU_FEROCEON_OLD_ID=y
CONFIG_CPU_32v5=y
CONFIG_CPU_ABRT_EV5T=y
CONFIG_CPU_PABRT_NOIFAR=y
CONFIG_CPU_CACHE_VIVT=y
CONFIG_CPU_COPY_FEROCEON=y
CONFIG_CPU_TLB_FEROCEON=y
CONFIG_CPU_CP15=y
CONFIG_CPU_CP15_MMU=y

#
# Processor Features
#
CONFIG_ARM_THUMB=y
# CONFIG_CPU_ICACHE_DISABLE is not set
# CONFIG_CPU_DCACHE_DISABLE is not set
CONFIG_OUTER_CACHE=y
CONFIG_CACHE_FEROCEON_L2=y
# CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH is not set

#
# Bus support
#
CONFIG_PCI=y
CONFIG_PCI_SYSCALL=y
# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_PCI_LEGACY=y
# CONFIG_PCI_DEBUG is not set
# CONFIG_PCI_STUB is not set
# CONFIG_PCI_IOV is not set
# CONFIG_PCCARD is not set

#
# Kernel Features
#
CONFIG_TICK_ONESHOT=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
CONFIG_VMSPLIT_3G=y
# CONFIG_VMSPLIT_2G is not set
# CONFIG_VMSPLIT_1G is not set
CONFIG_PAGE_OFFSET=0xC0000000
CONFIG_PREEMPT=y
CONFIG_HZ=100
CONFIG_AEABI=y
CONFIG_OABI_COMPAT=y
CONFIG_ARCH_FLATMEM_HAS_HOLES=y
# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
CONFIG_HIGHMEM=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_PAGEFLAGS_EXTENDED=y
CONFIG_SPLIT_PTLOCK_CPUS=4096
# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=0
CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
CONFIG_UNEVICTABLE_LRU=y
CONFIG_HAVE_MLOCK=y
CONFIG_HAVE_MLOCKED_PAGE_BIT=y
CONFIG_ALIGNMENT_TRAP=y

#
# Boot options
#
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
CONFIG_CMDLINE=""
# CONFIG_XIP_KERNEL is not set
# CONFIG_KEXEC is not set

#
# CPU Power Management
#
# CONFIG_CPU_IDLE is not set

#
# Floating point emulation
#

#
# At least one emulation must be selected
#
CONFIG_FPE_NWFPE=y
# CONFIG_FPE_NWFPE_XP is not set
# CONFIG_FPE_FASTFPE is not set
CONFIG_VFP=y

#
# Userspace binary formats
#
CONFIG_BINFMT_ELF=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
CONFIG_HAVE_AOUT=y
# CONFIG_BINFMT_AOUT is not set
# CONFIG_BINFMT_MISC is not set

#
# Power management options
#
# CONFIG_PM is not set
CONFIG_ARCH_SUSPEND_POSSIBLE=y
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_XFRM_SUB_POLICY is not set
# CONFIG_XFRM_MIGRATE is not set
# CONFIG_XFRM_STATISTICS is not set
# CONFIG_NET_KEY is not set
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
# CONFIG_IP_ADVANCED_ROUTER is not set
CONFIG_IP_FIB_HASH=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
CONFIG_IP_PNP_BOOTP=y
# CONFIG_IP_PNP_RARP is not set
# CONFIG_NET_IPIP is not set
# CONFIG_NET_IPGRE is not set
# CONFIG_IP_MROUTE is not set
# CONFIG_ARPD is not set
# CONFIG_SYN_COOKIES is not set
# CONFIG_INET_AH is not set
# CONFIG_INET_ESP is not set
# CONFIG_INET_IPCOMP is not set
# CONFIG_INET_XFRM_TUNNEL is not set
# CONFIG_INET_TUNNEL is not set
CONFIG_INET_XFRM_MODE_TRANSPORT=y
CONFIG_INET_XFRM_MODE_TUNNEL=y
CONFIG_INET_XFRM_MODE_BEET=y
CONFIG_INET_LRO=y
CONFIG_INET_DIAG=y
CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_CUBIC=y
CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_TCP_MD5SIG is not set
# CONFIG_IPV6 is not set
# CONFIG_NETWORK_SECMARK is not set
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
# CONFIG_NET_DSA is not set
# CONFIG_VLAN_8021Q is not set
# CONFIG_DECNET is not set
# CONFIG_LLC2 is not set
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
# CONFIG_PHONET is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set

#
# Network testing
#
CONFIG_NET_PKTGEN=m
# CONFIG_NET_TCPPROBE is not set
# CONFIG_NET_DROP_MONITOR is not set
# CONFIG_HAMRADIO is not set
# CONFIG_CAN is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
# CONFIG_WIRELESS is not set
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set

#
# Device Drivers
#

#
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=y
# CONFIG_FIRMWARE_IN_KERNEL is not set
CONFIG_EXTRA_FIRMWARE=""
# CONFIG_DEBUG_DRIVER is not set
# CONFIG_DEBUG_DEVRES is not set
# CONFIG_SYS_HYPERVISOR is not set
# CONFIG_CONNECTOR is not set
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
CONFIG_MTD_CMDLINE_PARTS=y
# CONFIG_MTD_AFS_PARTS is not set
# CONFIG_MTD_AR7_PARTS is not set

#
# User Modules And Translation Layers
#
CONFIG_MTD_CHAR=y
CONFIG_MTD_BLKDEVS=y
CONFIG_MTD_BLOCK=y
# CONFIG_FTL is not set
# CONFIG_NFTL is not set
# CONFIG_INFTL is not set
# CONFIG_RFD_FTL is not set
# CONFIG_SSFDC is not set
# CONFIG_MTD_OOPS is not set

#
# RAM/ROM/Flash chip drivers
#
CONFIG_MTD_CFI=y
CONFIG_MTD_JEDECPROBE=y
CONFIG_MTD_GEN_PROBE=y
CONFIG_MTD_CFI_ADV_OPTIONS=y
CONFIG_MTD_CFI_NOSWAP=y
# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
CONFIG_MTD_CFI_GEOMETRY=y
CONFIG_MTD_MAP_BANK_WIDTH_1=y
CONFIG_MTD_MAP_BANK_WIDTH_2=y
CONFIG_MTD_MAP_BANK_WIDTH_4=y
# CONFIG_MTD_MAP_BANK_WIDTH_8 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_OTP is not set
CONFIG_MTD_CFI_INTELEXT=y
CONFIG_MTD_CFI_AMDSTD=y
# CONFIG_MTD_CFI_STAA is not set
CONFIG_MTD_CFI_UTIL=y
# CONFIG_MTD_RAM is not set
# CONFIG_MTD_ROM is not set
# CONFIG_MTD_ABSENT is not set

#
# Mapping drivers for chip access
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
CONFIG_MTD_PHYSMAP=y
# CONFIG_MTD_PHYSMAP_COMPAT is not set
# CONFIG_MTD_ARM_INTEGRATOR is not set
# CONFIG_MTD_IMPA7 is not set
# CONFIG_MTD_INTEL_VR_NOR is not set
# CONFIG_MTD_PLATRAM is not set

#
# Self-contained MTD device drivers
#
# CONFIG_MTD_PMC551 is not set
# CONFIG_MTD_SLRAM is not set
# CONFIG_MTD_PHRAM is not set
# CONFIG_MTD_MTDRAM is not set
# CONFIG_MTD_BLOCK2MTD is not set

#
# Disk-On-Chip Device Drivers
#
# CONFIG_MTD_DOC2000 is not set
# CONFIG_MTD_DOC2001 is not set
# CONFIG_MTD_DOC2001PLUS is not set
CONFIG_MTD_NAND=y
CONFIG_MTD_NAND_VERIFY_WRITE=y
# CONFIG_MTD_NAND_ECC_SMC is not set
# CONFIG_MTD_NAND_MUSEUM_IDS is not set
# CONFIG_MTD_NAND_GPIO is not set
CONFIG_MTD_NAND_IDS=y
# CONFIG_MTD_NAND_DISKONCHIP is not set
# CONFIG_MTD_NAND_CAFE is not set
# CONFIG_MTD_NAND_NANDSIM is not set
# CONFIG_MTD_NAND_PLATFORM is not set
# CONFIG_MTD_ALAUDA is not set
CONFIG_MTD_NAND_ORION=y
# CONFIG_MTD_ONENAND is not set

#
# LPDDR flash memory drivers
#
# CONFIG_MTD_LPDDR is not set

#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
# CONFIG_PARPORT is not set
CONFIG_BLK_DEV=y
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
# CONFIG_BLK_DEV_UMEM is not set
# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_UB is not set
# CONFIG_BLK_DEV_RAM is not set
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
CONFIG_MISC_DEVICES=y
# CONFIG_PHANTOM is not set
# CONFIG_SGI_IOC4 is not set
# CONFIG_TIFM_CORE is not set
# CONFIG_ICS932S401 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_HP_ILO is not set
# CONFIG_ISL29003 is not set
# CONFIG_C2PORT is not set

#
# EEPROM support
#
# CONFIG_EEPROM_AT24 is not set
# CONFIG_EEPROM_LEGACY is not set
# CONFIG_EEPROM_93CX6 is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set

#
# SCSI device support
#
# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
CONFIG_SCSI_DMA=y
# CONFIG_SCSI_TGT is not set
# CONFIG_SCSI_NETLINK is not set
# CONFIG_SCSI_PROC_FS is not set

#
# SCSI support type (disk, tape, CD-ROM)
#
CONFIG_BLK_DEV_SD=y
# 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
# CONFIG_SCSI_SCAN_ASYNC is not set
CONFIG_SCSI_WAIT_SCAN=m

#
# SCSI Transports
#
# CONFIG_SCSI_SPI_ATTRS is not set
# CONFIG_SCSI_FC_ATTRS is not set
# CONFIG_SCSI_ISCSI_ATTRS is not set
# CONFIG_SCSI_SAS_LIBSAS is not set
# CONFIG_SCSI_SRP_ATTRS is not set
CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_ACARD is not set
# CONFIG_SCSI_AACRAID is not set
# CONFIG_SCSI_AIC7XXX is not set
# CONFIG_SCSI_AIC7XXX_OLD is not set
# CONFIG_SCSI_AIC79XX is not set
# CONFIG_SCSI_AIC94XX is not set
# CONFIG_SCSI_DPT_I2O is not set
# CONFIG_SCSI_ADVANSYS is not set
# CONFIG_SCSI_ARCMSR is not set
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
# CONFIG_SCSI_MPT2SAS is not set
# CONFIG_SCSI_HPTIOP is not set
# CONFIG_LIBFC is not set
# CONFIG_LIBFCOE is not set
# CONFIG_FCOE 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_MVSAS is not set
# CONFIG_SCSI_STEX is not set
# CONFIG_SCSI_SYM53C8XX_2 is not set
# CONFIG_SCSI_IPR is not set
# CONFIG_SCSI_QLOGIC_1280 is not set
# CONFIG_SCSI_QLA_FC is not set
# CONFIG_SCSI_QLA_ISCSI is not set
# CONFIG_SCSI_LPFC is not set
# CONFIG_SCSI_DC395x is not set
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_NSP32 is not set
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_SRP is not set
# CONFIG_SCSI_DH is not set
# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
CONFIG_SATA_PMP=y
# CONFIG_SATA_AHCI is not set
# CONFIG_SATA_SIL24 is not set
CONFIG_ATA_SFF=y
# CONFIG_SATA_SVW is not set
# CONFIG_ATA_PIIX is not set
CONFIG_SATA_MV=y
# CONFIG_SATA_NV is not set
# CONFIG_PDC_ADMA is not set
# CONFIG_SATA_QSTOR is not set
# CONFIG_SATA_PROMISE is not set
# CONFIG_SATA_SX4 is not set
# CONFIG_SATA_SIL is not set
# CONFIG_SATA_SIS is not set
# CONFIG_SATA_ULI is not set
# CONFIG_SATA_VIA is not set
# CONFIG_SATA_VITESSE is not set
# CONFIG_SATA_INIC162X is not set
# CONFIG_PATA_ALI is not set
# CONFIG_PATA_AMD is not set
# CONFIG_PATA_ARTOP is not set
# CONFIG_PATA_ATIIXP is not set
# CONFIG_PATA_CMD640_PCI is not set
# CONFIG_PATA_CMD64X is not set
# CONFIG_PATA_CS5520 is not set
# CONFIG_PATA_CS5530 is not set
# CONFIG_PATA_CYPRESS is not set
# CONFIG_PATA_EFAR is not set
# CONFIG_ATA_GENERIC is not set
# CONFIG_PATA_HPT366 is not set
# CONFIG_PATA_HPT37X is not set
# CONFIG_PATA_HPT3X2N is not set
# CONFIG_PATA_HPT3X3 is not set
# CONFIG_PATA_IT821X is not set
# CONFIG_PATA_IT8213 is not set
# CONFIG_PATA_JMICRON is not set
# CONFIG_PATA_TRIFLEX is not set
# CONFIG_PATA_MARVELL is not set
# CONFIG_PATA_MPIIX is not set
# CONFIG_PATA_OLDPIIX is not set
# CONFIG_PATA_NETCELL is not set
# CONFIG_PATA_NINJA32 is not set
# CONFIG_PATA_NS87410 is not set
# CONFIG_PATA_NS87415 is not set
# CONFIG_PATA_OPTI is not set
# CONFIG_PATA_OPTIDMA is not set
# CONFIG_PATA_PDC_OLD is not set
# CONFIG_PATA_RADISYS is not set
# CONFIG_PATA_RZ1000 is not set
# CONFIG_PATA_SC1200 is not set
# CONFIG_PATA_SERVERWORKS is not set
# CONFIG_PATA_PDC2027X is not set
# CONFIG_PATA_SIL680 is not set
# CONFIG_PATA_SIS is not set
# CONFIG_PATA_VIA is not set
# CONFIG_PATA_WINBOND is not set
# CONFIG_PATA_PLATFORM is not set
# CONFIG_PATA_SCH is not set
# CONFIG_MD is not set
# CONFIG_FUSION is not set

#
# IEEE 1394 (FireWire) support
#

#
# Enable only one of the two stacks, unless you know what you are doing
#
# CONFIG_FIREWIRE is not set
# CONFIG_IEEE1394 is not set
# CONFIG_I2O is not set
CONFIG_NETDEVICES=y
CONFIG_COMPAT_NET_DEV_OPS=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
# CONFIG_VETH is not set
# CONFIG_ARCNET is not set
CONFIG_PHYLIB=y

#
# MII PHY device drivers
#
CONFIG_MARVELL_PHY=y
# CONFIG_DAVICOM_PHY is not set
# CONFIG_QSEMI_PHY is not set
# CONFIG_LXT_PHY is not set
# CONFIG_CICADA_PHY is not set
# CONFIG_VITESSE_PHY is not set
# CONFIG_SMSC_PHY is not set
# CONFIG_BROADCOM_PHY is not set
# CONFIG_ICPLUS_PHY is not set
# CONFIG_REALTEK_PHY is not set
# CONFIG_NATIONAL_PHY is not set
# CONFIG_STE10XP is not set
# CONFIG_LSI_ET1011C_PHY is not set
# CONFIG_FIXED_PHY is not set
# CONFIG_MDIO_BITBANG is not set
CONFIG_NET_ETHERNET=y
CONFIG_MII=y
# CONFIG_AX88796 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
# CONFIG_DM9000 is not set
# CONFIG_ETHOC is not set
# CONFIG_SMC911X is not set
# CONFIG_SMSC911X is not set
# CONFIG_DNET is not set
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR 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_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 is not set
# CONFIG_R6040 is not set
# CONFIG_SIS900 is not set
# CONFIG_EPIC100 is not set
# CONFIG_SMSC9420 is not set
# CONFIG_SUNDANCE is not set
# CONFIG_TLAN is not set
# CONFIG_VIA_RHINE is not set
# CONFIG_SC92031 is not set
# CONFIG_ATL2 is not set
CONFIG_NETDEV_1000=y
# CONFIG_ACENIC is not set
# CONFIG_DL2K is not set
# CONFIG_E1000 is not set
# CONFIG_E1000E is not set
# CONFIG_IP1000 is not set
# CONFIG_IGB is not set
# CONFIG_IGBVF is not set
# CONFIG_NS83820 is not set
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
# CONFIG_SIS190 is not set
# CONFIG_SKGE is not set
# CONFIG_SKY2 is not set
# CONFIG_VIA_VELOCITY is not set
# CONFIG_TIGON3 is not set
# CONFIG_BNX2 is not set
CONFIG_MV643XX_ETH=y
# CONFIG_QLA3XXX is not set
# CONFIG_ATL1 is not set
# CONFIG_ATL1E is not set
# CONFIG_ATL1C is not set
# CONFIG_JME is not set
# CONFIG_NETDEV_10000 is not set
# CONFIG_TR is not set

#
# Wireless LAN
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set

#
# Enable WiMAX (Networking options) to see the WiMAX drivers
#

#
# USB Network Adapters
#
# CONFIG_USB_CATC is not set
# CONFIG_USB_KAWETH is not set
# CONFIG_USB_PEGASUS is not set
# CONFIG_USB_RTL8150 is not set
# CONFIG_USB_USBNET is not set
# CONFIG_WAN is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
# CONFIG_NET_FC is not set
# CONFIG_NETCONSOLE is not set
# CONFIG_NETPOLL is not set
# CONFIG_NET_POLL_CONTROLLER is not set
# CONFIG_ISDN is not set

#
# Input device support
#
CONFIG_INPUT=y
# CONFIG_INPUT_FF_MEMLESS is not set
# CONFIG_INPUT_POLLDEV is not set

#
# Userland interfaces
#
# CONFIG_INPUT_MOUSEDEV is not set
# CONFIG_INPUT_JOYDEV is not set
CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_EVBUG is not set

#
# Input Device Drivers
#
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_INPUT_JOYSTICK is not set
# CONFIG_INPUT_TABLET is not set
# CONFIG_INPUT_TOUCHSCREEN is not set
# CONFIG_INPUT_MISC is not set

#
# Hardware I/O ports
#
# CONFIG_SERIO is not set
# CONFIG_GAMEPORT is not set

#
# Character devices
#
# CONFIG_VT is not set
CONFIG_DEVKMEM=y
# CONFIG_SERIAL_NONSTANDARD is not set
# CONFIG_NOZOMI is not set

#
# Serial drivers
#
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
# CONFIG_SERIAL_8250_PCI is not set
CONFIG_SERIAL_8250_NR_UARTS=4
CONFIG_SERIAL_8250_RUNTIME_UARTS=2
# CONFIG_SERIAL_8250_EXTENDED is not set

#
# Non-8250 serial port support
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=16
# CONFIG_IPMI_HANDLER is not set
# CONFIG_HW_RANDOM is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
CONFIG_DEVPORT=y
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_HELPER_AUTO=y

#
# I2C Hardware Bus support
#

#
# PC SMBus host controller drivers
#
# CONFIG_I2C_ALI1535 is not set
# CONFIG_I2C_ALI1563 is not set
# CONFIG_I2C_ALI15X3 is not set
# CONFIG_I2C_AMD756 is not set
# CONFIG_I2C_AMD8111 is not set
# CONFIG_I2C_I801 is not set
# CONFIG_I2C_ISCH is not set
# CONFIG_I2C_PIIX4 is not set
# CONFIG_I2C_NFORCE2 is not set
# CONFIG_I2C_SIS5595 is not set
# CONFIG_I2C_SIS630 is not set
# CONFIG_I2C_SIS96X is not set
# CONFIG_I2C_VIA is not set
# CONFIG_I2C_VIAPRO is not set

#
# I2C system bus drivers (mostly embedded / system-on-chip)
#
# CONFIG_I2C_GPIO is not set
CONFIG_I2C_MV64XXX=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_SIMTEC is not set

#
# External I2C/SMBus adapter drivers
#
# CONFIG_I2C_PARPORT_LIGHT is not set
# CONFIG_I2C_TAOS_EVM is not set
# CONFIG_I2C_TINY_USB is not set

#
# Graphics adapter I2C/DDC channel drivers
#
# CONFIG_I2C_VOODOO3 is not set

#
# Other I2C/SMBus bus drivers
#
# CONFIG_I2C_PCA_PLATFORM is not set
# CONFIG_I2C_STUB is not set

#
# Miscellaneous I2C Chip support
#
# CONFIG_DS1682 is not set
# CONFIG_SENSORS_PCF8574 is not set
# CONFIG_PCF8575 is not set
# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_MAX6875 is not set
# CONFIG_SENSORS_TSL2550 is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
# CONFIG_I2C_DEBUG_BUS is not set
# CONFIG_I2C_DEBUG_CHIP is not set
# CONFIG_SPI is not set
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
# CONFIG_HWMON_VID is not set
# CONFIG_SENSORS_AD7414 is not set
# CONFIG_SENSORS_AD7418 is not set
# CONFIG_SENSORS_ADM1021 is not set
# CONFIG_SENSORS_ADM1025 is not set
# CONFIG_SENSORS_ADM1026 is not set
# CONFIG_SENSORS_ADM1029 is not set
# CONFIG_SENSORS_ADM1031 is not set
# CONFIG_SENSORS_ADM9240 is not set
# CONFIG_SENSORS_ADT7462 is not set
# CONFIG_SENSORS_ADT7470 is not set
# CONFIG_SENSORS_ADT7473 is not set
# CONFIG_SENSORS_ADT7475 is not set
# CONFIG_SENSORS_ATXP1 is not set
# CONFIG_SENSORS_DS1621 is not set
# CONFIG_SENSORS_I5K_AMB is not set
# CONFIG_SENSORS_F71805F is not set
# CONFIG_SENSORS_F71882FG is not set
# CONFIG_SENSORS_F75375S is not set
# CONFIG_SENSORS_G760A is not set
# CONFIG_SENSORS_GL518SM is not set
# CONFIG_SENSORS_GL520SM is not set
# CONFIG_SENSORS_IT87 is not set
# CONFIG_SENSORS_LM63 is not set
# CONFIG_SENSORS_LM75 is not set
# CONFIG_SENSORS_LM77 is not set
# CONFIG_SENSORS_LM78 is not set
# CONFIG_SENSORS_LM80 is not set
# CONFIG_SENSORS_LM83 is not set
# CONFIG_SENSORS_LM85 is not set
# CONFIG_SENSORS_LM87 is not set
# CONFIG_SENSORS_LM90 is not set
# CONFIG_SENSORS_LM92 is not set
# CONFIG_SENSORS_LM93 is not set
# CONFIG_SENSORS_LTC4215 is not set
# CONFIG_SENSORS_LTC4245 is not set
# CONFIG_SENSORS_LM95241 is not set
# CONFIG_SENSORS_MAX1619 is not set
# CONFIG_SENSORS_MAX6650 is not set
# CONFIG_SENSORS_PC87360 is not set
# CONFIG_SENSORS_PC87427 is not set
# CONFIG_SENSORS_PCF8591 is not set
# CONFIG_SENSORS_SHT15 is not set
# CONFIG_SENSORS_SIS5595 is not set
# CONFIG_SENSORS_DME1737 is not set
# CONFIG_SENSORS_SMSC47M1 is not set
# CONFIG_SENSORS_SMSC47M192 is not set
# CONFIG_SENSORS_SMSC47B397 is not set
# CONFIG_SENSORS_ADS7828 is not set
# CONFIG_SENSORS_THMC50 is not set
# CONFIG_SENSORS_VIA686A is not set
# CONFIG_SENSORS_VT1211 is not set
# CONFIG_SENSORS_VT8231 is not set
# CONFIG_SENSORS_W83781D is not set
# CONFIG_SENSORS_W83791D is not set
# CONFIG_SENSORS_W83792D is not set
# CONFIG_SENSORS_W83793 is not set
# CONFIG_SENSORS_W83L785TS is not set
# CONFIG_SENSORS_W83L786NG is not set
# CONFIG_SENSORS_W83627HF is not set
# CONFIG_SENSORS_W83627EHF is not set
# CONFIG_HWMON_DEBUG_CHIP is not set
# CONFIG_THERMAL is not set
# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y

#
# Sonics Silicon Backplane
#
# CONFIG_SSB is not set

#
# Multifunction device drivers
#
# CONFIG_MFD_CORE is not set
# CONFIG_MFD_SM501 is not set
# CONFIG_HTC_PASIC3 is not set
# CONFIG_TWL4030_CORE is not set
# CONFIG_MFD_TMIO is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set

#
# Multimedia devices
#

#
# Multimedia core support
#
# CONFIG_VIDEO_DEV is not set
# CONFIG_DVB_CORE is not set
# CONFIG_VIDEO_MEDIA is not set

#
# Multimedia drivers
#
# CONFIG_DAB is not set

#
# Graphics support
#
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
# CONFIG_VIDEO_OUTPUT_CONTROL is not set
# CONFIG_FB is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set

#
# Display device support
#
# CONFIG_DISPLAY_SUPPORT is not set
# CONFIG_SOUND is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set

#
# USB Input Devices
#
CONFIG_USB_HID=y
# CONFIG_HID_PID is not set
# CONFIG_USB_HIDDEV is not set

#
# Special HID drivers
#
# CONFIG_HID_A4TECH is not set
# CONFIG_HID_APPLE is not set
# CONFIG_HID_BELKIN is not set
# CONFIG_HID_CHERRY is not set
# CONFIG_HID_CHICONY is not set
# CONFIG_HID_CYPRESS is not set
# CONFIG_DRAGONRISE_FF is not set
# CONFIG_HID_EZKEY is not set
# CONFIG_HID_KYE is not set
# CONFIG_HID_GYRATION is not set
# CONFIG_HID_KENSINGTON is not set
# CONFIG_HID_LOGITECH is not set
# CONFIG_HID_MICROSOFT is not set
# CONFIG_HID_MONTEREY is not set
# CONFIG_HID_NTRIG is not set
# CONFIG_HID_PANTHERLORD is not set
# CONFIG_HID_PETALYNX is not set
# CONFIG_HID_SAMSUNG is not set
# CONFIG_HID_SONY is not set
# CONFIG_HID_SUNPLUS is not set
# CONFIG_GREENASIA_FF is not set
# CONFIG_HID_TOPSEED is not set
# CONFIG_THRUSTMASTER_FF is not set
# CONFIG_ZEROPLUS_FF is not set
CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
CONFIG_USB_ARCH_HAS_EHCI=y
CONFIG_USB=y
# CONFIG_USB_DEBUG is not set
# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set

#
# Miscellaneous USB options
#
CONFIG_USB_DEVICEFS=y
CONFIG_USB_DEVICE_CLASS=y
# CONFIG_USB_DYNAMIC_MINORS is not set
# CONFIG_USB_OTG is not set
# CONFIG_USB_OTG_WHITELIST is not set
# CONFIG_USB_OTG_BLACKLIST_HUB is not set
# CONFIG_USB_MON is not set
# CONFIG_USB_WUSB is not set
# CONFIG_USB_WUSB_CBAF is not set

#
# USB Host Controller Drivers
#
# CONFIG_USB_C67X00_HCD is not set
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_ROOT_HUB_TT=y
CONFIG_USB_EHCI_TT_NEWSCHED=y
# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
# CONFIG_USB_OHCI_HCD is not set
# CONFIG_USB_UHCI_HCD is not set
# CONFIG_USB_SL811_HCD is not set
# CONFIG_USB_R8A66597_HCD is not set
# CONFIG_USB_WHCI_HCD is not set
# CONFIG_USB_HWA_HCD is not set

#
# USB Device Class drivers
#
# CONFIG_USB_ACM is not set
CONFIG_USB_PRINTER=y
# CONFIG_USB_WDM is not set
# CONFIG_USB_TMC is not set

#
# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
#

#
# also be needed; see USB_STORAGE Help for more info
#
CONFIG_USB_STORAGE=y
# CONFIG_USB_STORAGE_DEBUG is not set
CONFIG_USB_STORAGE_DATAFAB=y
CONFIG_USB_STORAGE_FREECOM=y
# CONFIG_USB_STORAGE_ISD200 is not set
# CONFIG_USB_STORAGE_USBAT is not set
CONFIG_USB_STORAGE_SDDR09=y
CONFIG_USB_STORAGE_SDDR55=y
CONFIG_USB_STORAGE_JUMPSHOT=y
# CONFIG_USB_STORAGE_ALAUDA is not set
# CONFIG_USB_STORAGE_ONETOUCH is not set
# CONFIG_USB_STORAGE_KARMA is not set
# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
# CONFIG_USB_LIBUSUAL is not set

#
# USB Imaging devices
#
# CONFIG_USB_MDC800 is not set
# CONFIG_USB_MICROTEK is not set

#
# USB port drivers
#
# CONFIG_USB_SERIAL is not set

#
# USB Miscellaneous drivers
#
# CONFIG_USB_EMI62 is not set
# CONFIG_USB_EMI26 is not set
# CONFIG_USB_ADUTUX is not set
# CONFIG_USB_SEVSEG is not set
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_LCD is not set
# CONFIG_USB_BERRY_CHARGE is not set
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
# CONFIG_USB_IDMOUSE is not set
# CONFIG_USB_FTDI_ELAN is not set
# CONFIG_USB_APPLEDISPLAY is not set
# CONFIG_USB_SISUSBVGA is not set
# CONFIG_USB_LD is not set
# CONFIG_USB_TRANCEVIBRATOR is not set
# CONFIG_USB_IOWARRIOR is not set
# CONFIG_USB_TEST is not set
# CONFIG_USB_ISIGHTFW is not set
# CONFIG_USB_VST is not set
# CONFIG_USB_GADGET is not set

#
# OTG and related infrastructure
#
# CONFIG_USB_GPIO_VBUS is not set
# CONFIG_NOP_USB_XCEIV is not set
# CONFIG_UWB is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
# CONFIG_ACCESSIBILITY is not set
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y

#
# LED drivers
#
# CONFIG_LEDS_PCA9532 is not set
# CONFIG_LEDS_GPIO is not set
# CONFIG_LEDS_LP5521 is not set
# CONFIG_LEDS_PCA955X is not set
# CONFIG_LEDS_BD2802 is not set

#
# LED Triggers
#
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_TIMER=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set

#
# iptables trigger is under Netfilter config (LED target)
#
CONFIG_RTC_LIB=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_HCTOSYS=y
CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
# CONFIG_RTC_DEBUG is not set

#
# RTC interfaces
#
CONFIG_RTC_INTF_SYSFS=y
CONFIG_RTC_INTF_PROC=y
CONFIG_RTC_INTF_DEV=y
# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
# CONFIG_RTC_DRV_TEST is not set

#
# I2C RTC drivers
#
CONFIG_RTC_DRV_DS1307=y
# CONFIG_RTC_DRV_DS1374 is not set
# CONFIG_RTC_DRV_DS1672 is not set
# CONFIG_RTC_DRV_MAX6900 is not set
CONFIG_RTC_DRV_RS5C372=y
# CONFIG_RTC_DRV_ISL1208 is not set
# CONFIG_RTC_DRV_X1205 is not set
# CONFIG_RTC_DRV_PCF8563 is not set
# CONFIG_RTC_DRV_PCF8583 is not set
CONFIG_RTC_DRV_M41T80=y
# CONFIG_RTC_DRV_M41T80_WDT is not set
# CONFIG_RTC_DRV_S35390A is not set
# CONFIG_RTC_DRV_FM3130 is not set
# CONFIG_RTC_DRV_RX8581 is not set

#
# SPI RTC drivers
#

#
# Platform RTC drivers
#
# CONFIG_RTC_DRV_CMOS is not set
# CONFIG_RTC_DRV_DS1286 is not set
# CONFIG_RTC_DRV_DS1511 is not set
# CONFIG_RTC_DRV_DS1553 is not set
# CONFIG_RTC_DRV_DS1742 is not set
# CONFIG_RTC_DRV_STK17TA8 is not set
# CONFIG_RTC_DRV_M48T86 is not set
# CONFIG_RTC_DRV_M48T35 is not set
# CONFIG_RTC_DRV_M48T59 is not set
# CONFIG_RTC_DRV_BQ4802 is not set
# CONFIG_RTC_DRV_V3020 is not set

#
# on-CPU RTC drivers
#
# CONFIG_DMADEVICES is not set
# CONFIG_AUXDISPLAY is not set
# CONFIG_REGULATOR is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set

#
# File systems
#
CONFIG_EXT2_FS=y
# CONFIG_EXT2_FS_XATTR is not set
# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
# CONFIG_EXT3_FS_XATTR is not set
CONFIG_EXT4_FS=m
# CONFIG_EXT4DEV_COMPAT is not set
CONFIG_EXT4_FS_XATTR=y
# CONFIG_EXT4_FS_POSIX_ACL is not set
# CONFIG_EXT4_FS_SECURITY is not set
CONFIG_JBD=y
# CONFIG_JBD_DEBUG is not set
CONFIG_JBD2=m
# CONFIG_JBD2_DEBUG is not set
CONFIG_FS_MBCACHE=m
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_FS_POSIX_ACL is not set
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
# CONFIG_FUSE_FS is not set

#
# Caches
#
# CONFIG_FSCACHE is not set

#
# CD-ROM/DVD Filesystems
#
CONFIG_ISO9660_FS=m
CONFIG_JOLIET=y
# CONFIG_ZISOFS is not set
CONFIG_UDF_FS=m
CONFIG_UDF_NLS=y

#
# DOS/FAT/NT Filesystems
#
CONFIG_FAT_FS=y
CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y
CONFIG_FAT_DEFAULT_CODEPAGE=437
CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
# CONFIG_NTFS_FS is not set

#
# Pseudo filesystems
#
CONFIG_PROC_FS=y
CONFIG_PROC_SYSCTL=y
CONFIG_PROC_PAGE_MONITOR=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
# CONFIG_TMPFS_POSIX_ACL is not set
# CONFIG_HUGETLB_PAGE is not set
# CONFIG_CONFIGFS_FS is not set
CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
# CONFIG_HFS_FS is not set
# CONFIG_HFSPLUS_FS is not set
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
CONFIG_JFFS2_FS=y
CONFIG_JFFS2_FS_DEBUG=0
CONFIG_JFFS2_FS_WRITEBUFFER=y
# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
# CONFIG_JFFS2_SUMMARY is not set
# CONFIG_JFFS2_FS_XATTR is not set
# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
CONFIG_JFFS2_ZLIB=y
# CONFIG_JFFS2_LZO is not set
CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
CONFIG_CRAMFS=y
# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
# CONFIG_NFS_V3_ACL is not set
# CONFIG_NFS_V4 is not set
CONFIG_ROOT_NFS=y
# CONFIG_NFSD is not set
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
# CONFIG_CIFS is not set
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
# CONFIG_AFS_FS is not set

#
# 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=y
# CONFIG_MINIX_SUBPARTITION is not set
# CONFIG_SOLARIS_X86_PARTITION is not set
# CONFIG_UNIXWARE_DISKLABEL is not set
# CONFIG_LDM_PARTITION is not set
# CONFIG_SGI_PARTITION is not set
# CONFIG_ULTRIX_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
# CONFIG_KARMA_PARTITION is not set
# CONFIG_EFI_PARTITION is not set
# CONFIG_SYSV68_PARTITION is not set
CONFIG_NLS=y
CONFIG_NLS_DEFAULT="iso8859-1"
CONFIG_NLS_CODEPAGE_437=y
# CONFIG_NLS_CODEPAGE_737 is not set
# CONFIG_NLS_CODEPAGE_775 is not set
CONFIG_NLS_CODEPAGE_850=y
# CONFIG_NLS_CODEPAGE_852 is not set
# CONFIG_NLS_CODEPAGE_855 is not set
# CONFIG_NLS_CODEPAGE_857 is not set
# CONFIG_NLS_CODEPAGE_860 is not set
# CONFIG_NLS_CODEPAGE_861 is not set
# CONFIG_NLS_CODEPAGE_862 is not set
# CONFIG_NLS_CODEPAGE_863 is not set
# CONFIG_NLS_CODEPAGE_864 is not set
# CONFIG_NLS_CODEPAGE_865 is not set
# CONFIG_NLS_CODEPAGE_866 is not set
# CONFIG_NLS_CODEPAGE_869 is not set
# CONFIG_NLS_CODEPAGE_936 is not set
# CONFIG_NLS_CODEPAGE_950 is not set
# CONFIG_NLS_CODEPAGE_932 is not set
# CONFIG_NLS_CODEPAGE_949 is not set
# CONFIG_NLS_CODEPAGE_874 is not set
# CONFIG_NLS_ISO8859_8 is not set
# CONFIG_NLS_CODEPAGE_1250 is not set
# CONFIG_NLS_CODEPAGE_1251 is not set
# CONFIG_NLS_ASCII is not set
CONFIG_NLS_ISO8859_1=y
CONFIG_NLS_ISO8859_2=y
# CONFIG_NLS_ISO8859_3 is not set
# CONFIG_NLS_ISO8859_4 is not set
# CONFIG_NLS_ISO8859_5 is not set
# CONFIG_NLS_ISO8859_6 is not set
# CONFIG_NLS_ISO8859_7 is not set
# CONFIG_NLS_ISO8859_9 is not set
# CONFIG_NLS_ISO8859_13 is not set
# CONFIG_NLS_ISO8859_14 is not set
# CONFIG_NLS_ISO8859_15 is not set
# CONFIG_NLS_KOI8_R is not set
# CONFIG_NLS_KOI8_U is not set
# CONFIG_NLS_UTF8 is not set
# CONFIG_DLM is not set

#
# Kernel hacking
#
# CONFIG_PRINTK_TIME is not set
CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
CONFIG_MAGIC_SYSRQ=y
# CONFIG_UNUSED_SYMBOLS is not set
CONFIG_DEBUG_FS=y
# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_SHIRQ is not set
CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
CONFIG_DETECT_HUNG_TASK=y
# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
CONFIG_SCHED_DEBUG=y
CONFIG_SCHEDSTATS=y
# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_OBJECTS is not set
CONFIG_DEBUG_PREEMPT=y
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
# CONFIG_DEBUG_MUTEXES is not set
# CONFIG_DEBUG_LOCK_ALLOC is not set
# CONFIG_PROVE_LOCKING is not set
# CONFIG_LOCK_STAT is not set
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
CONFIG_STACKTRACE=y
# CONFIG_DEBUG_KOBJECT is not set
# CONFIG_DEBUG_HIGHMEM is not set
# CONFIG_DEBUG_BUGVERBOSE is not set
CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_VM is not set
# CONFIG_DEBUG_WRITECOUNT is not set
# CONFIG_DEBUG_MEMORY_INIT is not set
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_DEBUG_NOTIFIERS is not set
# CONFIG_BOOT_PRINTK_DELAY is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_KPROBES_SANITY_TEST is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
# CONFIG_LKDTM is not set
# CONFIG_FAULT_INJECTION is not set
# CONFIG_LATENCYTOP is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
# CONFIG_PAGE_POISONING is not set
CONFIG_NOP_TRACER=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_RING_BUFFER=y
CONFIG_TRACING=y
CONFIG_TRACING_SUPPORT=y

#
# Tracers
#
# CONFIG_FUNCTION_TRACER is not set
# CONFIG_IRQSOFF_TRACER is not set
# CONFIG_PREEMPT_TRACER is not set
# CONFIG_SCHED_TRACER is not set
# CONFIG_CONTEXT_SWITCH_TRACER is not set
# CONFIG_EVENT_TRACER is not set
# CONFIG_BOOT_TRACER is not set
# CONFIG_TRACE_BRANCH_PROFILING is not set
# CONFIG_STACK_TRACER is not set
# CONFIG_KMEMTRACE is not set
# CONFIG_WORKQUEUE_TRACER is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_FTRACE_STARTUP_TEST is not set
# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
CONFIG_ARM_UNWIND=y
CONFIG_DEBUG_USER=y
CONFIG_DEBUG_ERRORS=y
# CONFIG_DEBUG_STACK_USAGE is not set
CONFIG_DEBUG_LL=y
# CONFIG_DEBUG_ICEDCC is not set

#
# Security options
#
# CONFIG_KEYS is not set
# CONFIG_SECURITY is not set
# CONFIG_SECURITYFS is not set
# CONFIG_SECURITY_FILE_CAPABILITIES is not set
CONFIG_CRYPTO=y

#
# Crypto core or helper
#
# CONFIG_CRYPTO_FIPS is not set
CONFIG_CRYPTO_ALGAPI=m
CONFIG_CRYPTO_ALGAPI2=m
CONFIG_CRYPTO_AEAD2=m
CONFIG_CRYPTO_BLKCIPHER=m
CONFIG_CRYPTO_BLKCIPHER2=m
CONFIG_CRYPTO_HASH2=m
CONFIG_CRYPTO_RNG2=m
CONFIG_CRYPTO_PCOMP=m
CONFIG_CRYPTO_MANAGER=m
CONFIG_CRYPTO_MANAGER2=m
# CONFIG_CRYPTO_GF128MUL is not set
# CONFIG_CRYPTO_NULL is not set
CONFIG_CRYPTO_WORKQUEUE=m
# CONFIG_CRYPTO_CRYPTD is not set
# CONFIG_CRYPTO_AUTHENC is not set
# CONFIG_CRYPTO_TEST is not set

#
# Authenticated Encryption with Associated Data
#
# CONFIG_CRYPTO_CCM is not set
# CONFIG_CRYPTO_GCM is not set
# CONFIG_CRYPTO_SEQIV is not set

#
# Block modes
#
CONFIG_CRYPTO_CBC=m
# CONFIG_CRYPTO_CTR is not set
# CONFIG_CRYPTO_CTS is not set
CONFIG_CRYPTO_ECB=m
# CONFIG_CRYPTO_LRW is not set
CONFIG_CRYPTO_PCBC=m
# CONFIG_CRYPTO_XTS is not set

#
# Hash modes
#
# CONFIG_CRYPTO_HMAC is not set
# CONFIG_CRYPTO_XCBC is not set

#
# Digest
#
# CONFIG_CRYPTO_CRC32C is not set
# CONFIG_CRYPTO_MD4 is not set
# CONFIG_CRYPTO_MD5 is not set
# CONFIG_CRYPTO_MICHAEL_MIC is not set
# CONFIG_CRYPTO_RMD128 is not set
# CONFIG_CRYPTO_RMD160 is not set
# CONFIG_CRYPTO_RMD256 is not set
# CONFIG_CRYPTO_RMD320 is not set
# CONFIG_CRYPTO_SHA1 is not set
# CONFIG_CRYPTO_SHA256 is not set
# CONFIG_CRYPTO_SHA512 is not set
# CONFIG_CRYPTO_TGR192 is not set
# CONFIG_CRYPTO_WP512 is not set

#
# Ciphers
#
# CONFIG_CRYPTO_AES is not set
# CONFIG_CRYPTO_ANUBIS is not set
# CONFIG_CRYPTO_ARC4 is not set
# CONFIG_CRYPTO_BLOWFISH is not set
# CONFIG_CRYPTO_CAMELLIA is not set
# CONFIG_CRYPTO_CAST5 is not set
# CONFIG_CRYPTO_CAST6 is not set
# CONFIG_CRYPTO_DES is not set
# CONFIG_CRYPTO_FCRYPT is not set
# CONFIG_CRYPTO_KHAZAD is not set
# CONFIG_CRYPTO_SALSA20 is not set
# CONFIG_CRYPTO_SEED is not set
# CONFIG_CRYPTO_SERPENT is not set
# CONFIG_CRYPTO_TEA is not set
# CONFIG_CRYPTO_TWOFISH is not set

#
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
# CONFIG_CRYPTO_ZLIB is not set
# CONFIG_CRYPTO_LZO is not set

#
# Random Number Generation
#
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRYPTO_HW=y
# CONFIG_CRYPTO_DEV_HIFN_795X is not set
CONFIG_BINARY_PRINTF=y

#
# Library routines
#
CONFIG_BITREVERSE=y
CONFIG_GENERIC_FIND_LAST_BIT=y
# CONFIG_CRC_CCITT is not set
CONFIG_CRC16=m
# CONFIG_CRC_T10DIF is not set
CONFIG_CRC_ITU_T=m
CONFIG_CRC32=y
# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
CONFIG_NLATTR=y
>) { while (len>>2) { writel(cpu_to_le32(*(u32 *)data), hc->pci_membase + A_FIFO_DATA0); data += 4; len -= 4; } while (len>>1) { writew(cpu_to_le16(*(u16 *)data), hc->pci_membase + A_FIFO_DATA0); data += 2; len -= 2; } while (len) { writeb(*data, hc->pci_membase + A_FIFO_DATA0); data++; len--; } } /* read fifo data (REGIO) */ static void read_fifo_regio(struct hfc_multi *hc, u_char *data, int len) { outb(A_FIFO_DATA0, (hc->pci_iobase)+4); while (len>>2) { *(u32 *)data = le32_to_cpu(inl(hc->pci_iobase)); data += 4; len -= 4; } while (len>>1) { *(u16 *)data = le16_to_cpu(inw(hc->pci_iobase)); data += 2; len -= 2; } while (len) { *data = inb(hc->pci_iobase); data++; len--; } } /* read fifo data (PCIMEM) */ static void read_fifo_pcimem(struct hfc_multi *hc, u_char *data, int len) { while (len>>2) { *(u32 *)data = le32_to_cpu(readl(hc->pci_membase + A_FIFO_DATA0)); data += 4; len -= 4; } while (len>>1) { *(u16 *)data = le16_to_cpu(readw(hc->pci_membase + A_FIFO_DATA0)); data += 2; len -= 2; } while (len) { *data = readb(hc->pci_membase + A_FIFO_DATA0); data++; len--; } } static void enable_hwirq(struct hfc_multi *hc) { hc->hw.r_irq_ctrl |= V_GLOB_IRQ_EN; HFC_outb(hc, R_IRQ_CTRL, hc->hw.r_irq_ctrl); } static void disable_hwirq(struct hfc_multi *hc) { hc->hw.r_irq_ctrl &= ~((u_char)V_GLOB_IRQ_EN); HFC_outb(hc, R_IRQ_CTRL, hc->hw.r_irq_ctrl); } #define NUM_EC 2 #define MAX_TDM_CHAN 32 inline void enablepcibridge(struct hfc_multi *c) { HFC_outb(c, R_BRG_PCM_CFG, (0x0 << 6) | 0x3); /* was _io before */ } inline void disablepcibridge(struct hfc_multi *c) { HFC_outb(c, R_BRG_PCM_CFG, (0x0 << 6) | 0x2); /* was _io before */ } inline unsigned char readpcibridge(struct hfc_multi *hc, unsigned char address) { unsigned short cipv; unsigned char data; if (!hc->pci_iobase) return 0; /* slow down a PCI read access by 1 PCI clock cycle */ HFC_outb(hc, R_CTRL, 0x4); /*was _io before*/ if (address == 0) cipv = 0x4000; else cipv = 0x5800; /* select local bridge port address by writing to CIP port */ /* data = HFC_inb(c, cipv); * was _io before */ outw(cipv, hc->pci_iobase + 4); data = inb(hc->pci_iobase); /* restore R_CTRL for normal PCI read cycle speed */ HFC_outb(hc, R_CTRL, 0x0); /* was _io before */ return data; } inline void writepcibridge(struct hfc_multi *hc, unsigned char address, unsigned char data) { unsigned short cipv; unsigned int datav; if (!hc->pci_iobase) return; if (address == 0) cipv = 0x4000; else cipv = 0x5800; /* select local bridge port address by writing to CIP port */ outw(cipv, hc->pci_iobase + 4); /* define a 32 bit dword with 4 identical bytes for write sequence */ datav = data | ((__u32) data << 8) | ((__u32) data << 16) | ((__u32) data << 24); /* * write this 32 bit dword to the bridge data port * this will initiate a write sequence of up to 4 writes to the same * address on the local bus interface the number of write accesses * is undefined but >=1 and depends on the next PCI transaction * during write sequence on the local bus */ outl(datav, hc->pci_iobase); } inline void cpld_set_reg(struct hfc_multi *hc, unsigned char reg) { /* Do data pin read low byte */ HFC_outb(hc, R_GPIO_OUT1, reg); } inline void cpld_write_reg(struct hfc_multi *hc, unsigned char reg, unsigned char val) { cpld_set_reg(hc, reg); enablepcibridge(hc); writepcibridge(hc, 1, val); disablepcibridge(hc); return; } inline unsigned char cpld_read_reg(struct hfc_multi *hc, unsigned char reg) { unsigned char bytein; cpld_set_reg(hc, reg); /* Do data pin read low byte */ HFC_outb(hc, R_GPIO_OUT1, reg); enablepcibridge(hc); bytein = readpcibridge(hc, 1); disablepcibridge(hc); return bytein; } inline void vpm_write_address(struct hfc_multi *hc, unsigned short addr) { cpld_write_reg(hc, 0, 0xff & addr); cpld_write_reg(hc, 1, 0x01 & (addr >> 8)); } inline unsigned short vpm_read_address(struct hfc_multi *c) { unsigned short addr; unsigned short highbit; addr = cpld_read_reg(c, 0); highbit = cpld_read_reg(c, 1); addr = addr | (highbit << 8); return addr & 0x1ff; } inline unsigned char vpm_in(struct hfc_multi *c, int which, unsigned short addr) { unsigned char res; vpm_write_address(c, addr); if (!which) cpld_set_reg(c, 2); else cpld_set_reg(c, 3); enablepcibridge(c); res = readpcibridge(c, 1); disablepcibridge(c); cpld_set_reg(c, 0); return res; } inline void vpm_out(struct hfc_multi *c, int which, unsigned short addr, unsigned char data) { vpm_write_address(c, addr); enablepcibridge(c); if (!which) cpld_set_reg(c, 2); else cpld_set_reg(c, 3); writepcibridge(c, 1, data); cpld_set_reg(c, 0); disablepcibridge(c); { unsigned char regin; regin = vpm_in(c, which, addr); if (regin != data) printk(KERN_DEBUG "Wrote 0x%x to register 0x%x but got back " "0x%x\n", data, addr, regin); } } static void vpm_init(struct hfc_multi *wc) { unsigned char reg; unsigned int mask; unsigned int i, x, y; unsigned int ver; for (x = 0; x < NUM_EC; x++) { /* Setup GPIO's */ if (!x) { ver = vpm_in(wc, x, 0x1a0); printk(KERN_DEBUG "VPM: Chip %d: ver %02x\n", x, ver); } for (y = 0; y < 4; y++) { vpm_out(wc, x, 0x1a8 + y, 0x00); /* GPIO out */ vpm_out(wc, x, 0x1ac + y, 0x00); /* GPIO dir */ vpm_out(wc, x, 0x1b0 + y, 0x00); /* GPIO sel */ } /* Setup TDM path - sets fsync and tdm_clk as inputs */ reg = vpm_in(wc, x, 0x1a3); /* misc_con */ vpm_out(wc, x, 0x1a3, reg & ~2); /* Setup Echo length (256 taps) */ vpm_out(wc, x, 0x022, 1); vpm_out(wc, x, 0x023, 0xff); /* Setup timeslots */ vpm_out(wc, x, 0x02f, 0x00); mask = 0x02020202 << (x * 4); /* Setup the tdm channel masks for all chips */ for (i = 0; i < 4; i++) vpm_out(wc, x, 0x33 - i, (mask >> (i << 3)) & 0xff); /* Setup convergence rate */ printk(KERN_DEBUG "VPM: A-law mode\n"); reg = 0x00 | 0x10 | 0x01; vpm_out(wc, x, 0x20, reg); printk(KERN_DEBUG "VPM reg 0x20 is %x\n", reg); /*vpm_out(wc, x, 0x20, (0x00 | 0x08 | 0x20 | 0x10)); */ vpm_out(wc, x, 0x24, 0x02); reg = vpm_in(wc, x, 0x24); printk(KERN_DEBUG "NLP Thresh is set to %d (0x%x)\n", reg, reg); /* Initialize echo cans */ for (i = 0; i < MAX_TDM_CHAN; i++) { if (mask & (0x00000001 << i)) vpm_out(wc, x, i, 0x00); } /* * ARM arch at least disallows a udelay of * more than 2ms... it gives a fake "__bad_udelay" * reference at link-time. * long delays in kernel code are pretty sucky anyway * for now work around it using 5 x 2ms instead of 1 x 10ms */ udelay(2000); udelay(2000); udelay(2000); udelay(2000); udelay(2000); /* Put in bypass mode */ for (i = 0; i < MAX_TDM_CHAN; i++) { if (mask & (0x00000001 << i)) vpm_out(wc, x, i, 0x01); } /* Enable bypass */ for (i = 0; i < MAX_TDM_CHAN; i++) { if (mask & (0x00000001 << i)) vpm_out(wc, x, 0x78 + i, 0x01); } } } #ifdef UNUSED static void vpm_check(struct hfc_multi *hctmp) { unsigned char gpi2; gpi2 = HFC_inb(hctmp, R_GPI_IN2); if ((gpi2 & 0x3) != 0x3) printk(KERN_DEBUG "Got interrupt 0x%x from VPM!\n", gpi2); } #endif /* UNUSED */ /* * Interface to enable/disable the HW Echocan * * these functions are called within a spin_lock_irqsave on * the channel instance lock, so we are not disturbed by irqs * * we can later easily change the interface to make other * things configurable, for now we configure the taps * */ static void vpm_echocan_on(struct hfc_multi *hc, int ch, int taps) { unsigned int timeslot; unsigned int unit; struct bchannel *bch = hc->chan[ch].bch; #ifdef TXADJ int txadj = -4; struct sk_buff *skb; #endif if (hc->chan[ch].protocol != ISDN_P_B_RAW) return; if (!bch) return; #ifdef TXADJ skb = _alloc_mISDN_skb(PH_CONTROL_IND, HFC_VOL_CHANGE_TX, sizeof(int), &txadj, GFP_ATOMIC); if (skb) recv_Bchannel_skb(bch, skb); #endif timeslot = ((ch/4)*8) + ((ch%4)*4) + 1; unit = ch % 4; printk(KERN_NOTICE "vpm_echocan_on called taps [%d] on timeslot %d\n", taps, timeslot); vpm_out(hc, unit, timeslot, 0x7e); } static void vpm_echocan_off(struct hfc_multi *hc, int ch) { unsigned int timeslot; unsigned int unit; struct bchannel *bch = hc->chan[ch].bch; #ifdef TXADJ int txadj = 0; struct sk_buff *skb; #endif if (hc->chan[ch].protocol != ISDN_P_B_RAW) return; if (!bch) return; #ifdef TXADJ skb = _alloc_mISDN_skb(PH_CONTROL_IND, HFC_VOL_CHANGE_TX, sizeof(int), &txadj, GFP_ATOMIC); if (skb) recv_Bchannel_skb(bch, skb); #endif timeslot = ((ch/4)*8) + ((ch%4)*4) + 1; unit = ch % 4; printk(KERN_NOTICE "vpm_echocan_off called on timeslot %d\n", timeslot); /* FILLME */ vpm_out(hc, unit, timeslot, 0x01); } /* * Speech Design resync feature * NOTE: This is called sometimes outside interrupt handler. * We must lock irqsave, so no other interrupt (other card) will occurr! * Also multiple interrupts may nest, so must lock each access (lists, card)! */ static inline void hfcmulti_resync(struct hfc_multi *locked, struct hfc_multi *newmaster, int rm) { struct hfc_multi *hc, *next, *pcmmaster = NULL; void __iomem *plx_acc_32; u_int pv; u_long flags; spin_lock_irqsave(&HFClock, flags); spin_lock(&plx_lock); /* must be locked inside other locks */ if (debug & DEBUG_HFCMULTI_PLXSD) printk(KERN_DEBUG "%s: RESYNC(syncmaster=0x%p)\n", __func__, syncmaster); /* select new master */ if (newmaster) { if (debug & DEBUG_HFCMULTI_PLXSD) printk(KERN_DEBUG "using provided controller\n"); } else { list_for_each_entry_safe(hc, next, &HFClist, list) { if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { if (hc->syncronized) { newmaster = hc; break; } } } } /* Disable sync of all cards */ list_for_each_entry_safe(hc, next, &HFClist, list) { if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { plx_acc_32 = hc->plx_membase + PLX_GPIOC; pv = readl(plx_acc_32); pv &= ~PLX_SYNC_O_EN; writel(pv, plx_acc_32); if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip)) { pcmmaster = hc; if (hc->type == 1) { if (debug & DEBUG_HFCMULTI_PLXSD) printk(KERN_DEBUG "Schedule SYNC_I\n"); hc->e1_resync |= 1; /* get SYNC_I */ } } } } if (newmaster) { hc = newmaster; if (debug & DEBUG_HFCMULTI_PLXSD) printk(KERN_DEBUG "id=%d (0x%p) = syncronized with " "interface.\n", hc->id, hc); /* Enable new sync master */ plx_acc_32 = hc->plx_membase + PLX_GPIOC; pv = readl(plx_acc_32); pv |= PLX_SYNC_O_EN; writel(pv, plx_acc_32); /* switch to jatt PLL, if not disabled by RX_SYNC */ if (hc->type == 1 && !test_bit(HFC_CHIP_RX_SYNC, &hc->chip)) { if (debug & DEBUG_HFCMULTI_PLXSD) printk(KERN_DEBUG "Schedule jatt PLL\n"); hc->e1_resync |= 2; /* switch to jatt */ } } else { if (pcmmaster) { hc = pcmmaster; if (debug & DEBUG_HFCMULTI_PLXSD) printk(KERN_DEBUG "id=%d (0x%p) = PCM master syncronized " "with QUARTZ\n", hc->id, hc); if (hc->type == 1) { /* Use the crystal clock for the PCM master card */ if (debug & DEBUG_HFCMULTI_PLXSD) printk(KERN_DEBUG "Schedule QUARTZ for HFC-E1\n"); hc->e1_resync |= 4; /* switch quartz */ } else { if (debug & DEBUG_HFCMULTI_PLXSD) printk(KERN_DEBUG "QUARTZ is automatically " "enabled by HFC-%dS\n", hc->type); } plx_acc_32 = hc->plx_membase + PLX_GPIOC; pv = readl(plx_acc_32); pv |= PLX_SYNC_O_EN; writel(pv, plx_acc_32); } else if (!rm) printk(KERN_ERR "%s no pcm master, this MUST " "not happen!\n", __func__); } syncmaster = newmaster; spin_unlock(&plx_lock); spin_unlock_irqrestore(&HFClock, flags); } /* This must be called AND hc must be locked irqsave!!! */ inline void plxsd_checksync(struct hfc_multi *hc, int rm) { if (hc->syncronized) { if (syncmaster == NULL) { if (debug & DEBUG_HFCMULTI_PLXSD) printk(KERN_WARNING "%s: GOT sync on card %d" " (id=%d)\n", __func__, hc->id + 1, hc->id); hfcmulti_resync(hc, hc, rm); } } else { if (syncmaster == hc) { if (debug & DEBUG_HFCMULTI_PLXSD) printk(KERN_WARNING "%s: LOST sync on card %d" " (id=%d)\n", __func__, hc->id + 1, hc->id); hfcmulti_resync(hc, NULL, rm); } } } /* * free hardware resources used by driver */ static void release_io_hfcmulti(struct hfc_multi *hc) { void __iomem *plx_acc_32; u_int pv; u_long plx_flags; if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: entered\n", __func__); /* soft reset also masks all interrupts */ hc->hw.r_cirm |= V_SRES; HFC_outb(hc, R_CIRM, hc->hw.r_cirm); udelay(1000); hc->hw.r_cirm &= ~V_SRES; HFC_outb(hc, R_CIRM, hc->hw.r_cirm); udelay(1000); /* instead of 'wait' that may cause locking */ /* release Speech Design card, if PLX was initialized */ if (test_bit(HFC_CHIP_PLXSD, &hc->chip) && hc->plx_membase) { if (debug & DEBUG_HFCMULTI_PLXSD) printk(KERN_DEBUG "%s: release PLXSD card %d\n", __func__, hc->id + 1); spin_lock_irqsave(&plx_lock, plx_flags); plx_acc_32 = hc->plx_membase + PLX_GPIOC; writel(PLX_GPIOC_INIT, plx_acc_32); pv = readl(plx_acc_32); /* Termination off */ pv &= ~PLX_TERM_ON; /* Disconnect the PCM */ pv |= PLX_SLAVE_EN_N; pv &= ~PLX_MASTER_EN; pv &= ~PLX_SYNC_O_EN; /* Put the DSP in Reset */ pv &= ~PLX_DSP_RES_N; writel(pv, plx_acc_32); if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_WARNING "%s: PCM off: PLX_GPIO=%x\n", __func__, pv); spin_unlock_irqrestore(&plx_lock, plx_flags); } /* disable memory mapped ports / io ports */ test_and_clear_bit(HFC_CHIP_PLXSD, &hc->chip); /* prevent resync */ pci_write_config_word(hc->pci_dev, PCI_COMMAND, 0); if (hc->pci_membase) iounmap(hc->pci_membase); if (hc->plx_membase) iounmap(hc->plx_membase); if (hc->pci_iobase) release_region(hc->pci_iobase, 8); if (hc->pci_dev) { pci_disable_device(hc->pci_dev); pci_set_drvdata(hc->pci_dev, NULL); } if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: done\n", __func__); } /* * function called to reset the HFC chip. A complete software reset of chip * and fifos is done. All configuration of the chip is done. */ static int init_chip(struct hfc_multi *hc) { u_long flags, val, val2 = 0, rev; int i, err = 0; u_char r_conf_en, rval; void __iomem *plx_acc_32; u_int pv; u_long plx_flags, hfc_flags; int plx_count; struct hfc_multi *pos, *next, *plx_last_hc; spin_lock_irqsave(&hc->lock, flags); /* reset all registers */ memset(&hc->hw, 0, sizeof(struct hfcm_hw)); /* revision check */ if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: entered\n", __func__); val = HFC_inb(hc, R_CHIP_ID)>>4; if (val != 0x8 && val != 0xc && val != 0xe) { printk(KERN_INFO "HFC_multi: unknown CHIP_ID:%x\n", (u_int)val); err = -EIO; goto out; } rev = HFC_inb(hc, R_CHIP_RV); printk(KERN_INFO "HFC_multi: detected HFC with chip ID=0x%lx revision=%ld%s\n", val, rev, (rev == 0) ? " (old FIFO handling)" : ""); if (rev == 0) { test_and_set_bit(HFC_CHIP_REVISION0, &hc->chip); printk(KERN_WARNING "HFC_multi: NOTE: Your chip is revision 0, " "ask Cologne Chip for update. Newer chips " "have a better FIFO handling. Old chips " "still work but may have slightly lower " "HDLC transmit performance.\n"); } if (rev > 1) { printk(KERN_WARNING "HFC_multi: WARNING: This driver doesn't " "consider chip revision = %ld. The chip / " "bridge may not work.\n", rev); } /* set s-ram size */ hc->Flen = 0x10; hc->Zmin = 0x80; hc->Zlen = 384; hc->DTMFbase = 0x1000; if (test_bit(HFC_CHIP_EXRAM_128, &hc->chip)) { if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: changing to 128K extenal RAM\n", __func__); hc->hw.r_ctrl |= V_EXT_RAM; hc->hw.r_ram_sz = 1; hc->Flen = 0x20; hc->Zmin = 0xc0; hc->Zlen = 1856; hc->DTMFbase = 0x2000; } if (test_bit(HFC_CHIP_EXRAM_512, &hc->chip)) { if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: changing to 512K extenal RAM\n", __func__); hc->hw.r_ctrl |= V_EXT_RAM; hc->hw.r_ram_sz = 2; hc->Flen = 0x20; hc->Zmin = 0xc0; hc->Zlen = 8000; hc->DTMFbase = 0x2000; } hc->max_trans = poll << 1; if (hc->max_trans > hc->Zlen) hc->max_trans = hc->Zlen; /* Speech Design PLX bridge */ if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { if (debug & DEBUG_HFCMULTI_PLXSD) printk(KERN_DEBUG "%s: initializing PLXSD card %d\n", __func__, hc->id + 1); spin_lock_irqsave(&plx_lock, plx_flags); plx_acc_32 = hc->plx_membase + PLX_GPIOC; writel(PLX_GPIOC_INIT, plx_acc_32); pv = readl(plx_acc_32); /* The first and the last cards are terminating the PCM bus */ pv |= PLX_TERM_ON; /* hc is currently the last */ /* Disconnect the PCM */ pv |= PLX_SLAVE_EN_N; pv &= ~PLX_MASTER_EN; pv &= ~PLX_SYNC_O_EN; /* Put the DSP in Reset */ pv &= ~PLX_DSP_RES_N; writel(pv, plx_acc_32); spin_unlock_irqrestore(&plx_lock, plx_flags); if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_WARNING "%s: slave/term: PLX_GPIO=%x\n", __func__, pv); /* * If we are the 3rd PLXSD card or higher, we must turn * termination of last PLXSD card off. */ spin_lock_irqsave(&HFClock, hfc_flags); plx_count = 0; plx_last_hc = NULL; list_for_each_entry_safe(pos, next, &HFClist, list) { if (test_bit(HFC_CHIP_PLXSD, &pos->chip)) { plx_count++; if (pos != hc) plx_last_hc = pos; } } if (plx_count >= 3) { if (debug & DEBUG_HFCMULTI_PLXSD) printk(KERN_DEBUG "%s: card %d is between, so " "we disable termination\n", __func__, plx_last_hc->id + 1); spin_lock_irqsave(&plx_lock, plx_flags); plx_acc_32 = plx_last_hc->plx_membase + PLX_GPIOC; pv = readl(plx_acc_32); pv &= ~PLX_TERM_ON; writel(pv, plx_acc_32); spin_unlock_irqrestore(&plx_lock, plx_flags); if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_WARNING "%s: term off: PLX_GPIO=%x\n", __func__, pv); } spin_unlock_irqrestore(&HFClock, hfc_flags); hc->hw.r_pcm_md0 = V_F0_LEN; /* shift clock for DSP */ } /* we only want the real Z2 read-pointer for revision > 0 */ if (!test_bit(HFC_CHIP_REVISION0, &hc->chip)) hc->hw.r_ram_sz |= V_FZ_MD; /* select pcm mode */ if (test_bit(HFC_CHIP_PCM_SLAVE, &hc->chip)) { if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: setting PCM into slave mode\n", __func__); } else if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip) && !plxsd_master) { if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: setting PCM into master mode\n", __func__); hc->hw.r_pcm_md0 |= V_PCM_MD; } else { if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: performing PCM auto detect\n", __func__); } /* soft reset */ HFC_outb(hc, R_CTRL, hc->hw.r_ctrl); HFC_outb(hc, R_RAM_SZ, hc->hw.r_ram_sz); HFC_outb(hc, R_FIFO_MD, 0); hc->hw.r_cirm = V_SRES | V_HFCRES | V_PCMRES | V_STRES | V_RLD_EPR; HFC_outb(hc, R_CIRM, hc->hw.r_cirm); udelay(100); hc->hw.r_cirm = 0; HFC_outb(hc, R_CIRM, hc->hw.r_cirm); udelay(100); HFC_outb(hc, R_RAM_SZ, hc->hw.r_ram_sz); /* Speech Design PLX bridge pcm and sync mode */ if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { spin_lock_irqsave(&plx_lock, plx_flags); plx_acc_32 = hc->plx_membase + PLX_GPIOC; pv = readl(plx_acc_32); /* Connect PCM */ if (hc->hw.r_pcm_md0 & V_PCM_MD) { pv |= PLX_MASTER_EN | PLX_SLAVE_EN_N; pv |= PLX_SYNC_O_EN; if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_WARNING "%s: master: PLX_GPIO=%x\n", __func__, pv); } else { pv &= ~(PLX_MASTER_EN | PLX_SLAVE_EN_N); pv &= ~PLX_SYNC_O_EN; if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_WARNING "%s: slave: PLX_GPIO=%x\n", __func__, pv); } writel(pv, plx_acc_32); spin_unlock_irqrestore(&plx_lock, plx_flags); } /* PCM setup */ HFC_outb(hc, R_PCM_MD0, hc->hw.r_pcm_md0 | 0x90); if (hc->slots == 32) HFC_outb(hc, R_PCM_MD1, 0x00); if (hc->slots == 64) HFC_outb(hc, R_PCM_MD1, 0x10); if (hc->slots == 128) HFC_outb(hc, R_PCM_MD1, 0x20); HFC_outb(hc, R_PCM_MD0, hc->hw.r_pcm_md0 | 0xa0); if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) HFC_outb(hc, R_PCM_MD2, V_SYNC_SRC); /* sync via SYNC_I / O */ else HFC_outb(hc, R_PCM_MD2, 0x00); /* sync from interface */ HFC_outb(hc, R_PCM_MD0, hc->hw.r_pcm_md0 | 0x00); for (i = 0; i < 256; i++) { HFC_outb_nodebug(hc, R_SLOT, i); HFC_outb_nodebug(hc, A_SL_CFG, 0); HFC_outb_nodebug(hc, A_CONF, 0); hc->slot_owner[i] = -1; } /* set clock speed */ if (test_bit(HFC_CHIP_CLOCK2, &hc->chip)) { if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: setting double clock\n", __func__); HFC_outb(hc, R_BRG_PCM_CFG, V_PCM_CLK); } /* B410P GPIO */ if (test_bit(HFC_CHIP_B410P, &hc->chip)) { printk(KERN_NOTICE "Setting GPIOs\n"); HFC_outb(hc, R_GPIO_SEL, 0x30); HFC_outb(hc, R_GPIO_EN1, 0x3); udelay(1000); printk(KERN_NOTICE "calling vpm_init\n"); vpm_init(hc); } /* check if R_F0_CNT counts (8 kHz frame count) */ val = HFC_inb(hc, R_F0_CNTL); val += HFC_inb(hc, R_F0_CNTH) << 8; if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "HFC_multi F0_CNT %ld after reset\n", val); spin_unlock_irqrestore(&hc->lock, flags); set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout((HZ/100)?:1); /* Timeout minimum 10ms */ spin_lock_irqsave(&hc->lock, flags); val2 = HFC_inb(hc, R_F0_CNTL); val2 += HFC_inb(hc, R_F0_CNTH) << 8; if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "HFC_multi F0_CNT %ld after 10 ms (1st try)\n", val2); if (val2 >= val+8) { /* 1 ms */ /* it counts, so we keep the pcm mode */ if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip)) printk(KERN_INFO "controller is PCM bus MASTER\n"); else if (test_bit(HFC_CHIP_PCM_SLAVE, &hc->chip)) printk(KERN_INFO "controller is PCM bus SLAVE\n"); else { test_and_set_bit(HFC_CHIP_PCM_SLAVE, &hc->chip); printk(KERN_INFO "controller is PCM bus SLAVE " "(auto detected)\n"); } } else { /* does not count */ if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip)) { controller_fail: printk(KERN_ERR "HFC_multi ERROR, getting no 125us " "pulse. Seems that controller fails.\n"); err = -EIO; goto out; } if (test_bit(HFC_CHIP_PCM_SLAVE, &hc->chip)) { printk(KERN_INFO "controller is PCM bus SLAVE " "(ignoring missing PCM clock)\n"); } else { /* only one pcm master */ if (test_bit(HFC_CHIP_PLXSD, &hc->chip) && plxsd_master) { printk(KERN_ERR "HFC_multi ERROR, no clock " "on another Speech Design card found. " "Please be sure to connect PCM cable.\n"); err = -EIO; goto out; } /* retry with master clock */ if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { spin_lock_irqsave(&plx_lock, plx_flags); plx_acc_32 = hc->plx_membase + PLX_GPIOC; pv = readl(plx_acc_32); pv |= PLX_MASTER_EN | PLX_SLAVE_EN_N; pv |= PLX_SYNC_O_EN; writel(pv, plx_acc_32); spin_unlock_irqrestore(&plx_lock, plx_flags); if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_WARNING "%s: master: PLX_GPIO" "=%x\n", __func__, pv); } hc->hw.r_pcm_md0 |= V_PCM_MD; HFC_outb(hc, R_PCM_MD0, hc->hw.r_pcm_md0 | 0x00); spin_unlock_irqrestore(&hc->lock, flags); set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout((HZ/100)?:1); /* Timeout min. 10ms */ spin_lock_irqsave(&hc->lock, flags); val2 = HFC_inb(hc, R_F0_CNTL); val2 += HFC_inb(hc, R_F0_CNTH) << 8; if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "HFC_multi F0_CNT %ld after " "10 ms (2nd try)\n", val2); if (val2 >= val+8) { /* 1 ms */ test_and_set_bit(HFC_CHIP_PCM_MASTER, &hc->chip); printk(KERN_INFO "controller is PCM bus MASTER " "(auto detected)\n"); } else goto controller_fail; } } /* Release the DSP Reset */ if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip)) plxsd_master = 1; spin_lock_irqsave(&plx_lock, plx_flags); plx_acc_32 = hc->plx_membase + PLX_GPIOC; pv = readl(plx_acc_32); pv |= PLX_DSP_RES_N; writel(pv, plx_acc_32); spin_unlock_irqrestore(&plx_lock, plx_flags); if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_WARNING "%s: reset off: PLX_GPIO=%x\n", __func__, pv); } /* pcm id */ if (hc->pcm) printk(KERN_INFO "controller has given PCM BUS ID %d\n", hc->pcm); else { if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip) || test_bit(HFC_CHIP_PLXSD, &hc->chip)) { PCM_cnt++; /* SD has proprietary bridging */ } hc->pcm = PCM_cnt; printk(KERN_INFO "controller has PCM BUS ID %d " "(auto selected)\n", hc->pcm); } /* set up timer */ HFC_outb(hc, R_TI_WD, poll_timer); hc->hw.r_irqmsk_misc |= V_TI_IRQMSK; /* set E1 state machine IRQ */ if (hc->type == 1) hc->hw.r_irqmsk_misc |= V_STA_IRQMSK; /* set DTMF detection */ if (test_bit(HFC_CHIP_DTMF, &hc->chip)) { if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: enabling DTMF detection " "for all B-channel\n", __func__); hc->hw.r_dtmf = V_DTMF_EN | V_DTMF_STOP; if (test_bit(HFC_CHIP_ULAW, &hc->chip)) hc->hw.r_dtmf |= V_ULAW_SEL; HFC_outb(hc, R_DTMF_N, 102 - 1); hc->hw.r_irqmsk_misc |= V_DTMF_IRQMSK; } /* conference engine */ if (test_bit(HFC_CHIP_ULAW, &hc->chip)) r_conf_en = V_CONF_EN | V_ULAW; else r_conf_en = V_CONF_EN; HFC_outb(hc, R_CONF_EN, r_conf_en); /* setting leds */ switch (hc->leds) { case 1: /* HFC-E1 OEM */ if (test_bit(HFC_CHIP_WATCHDOG, &hc->chip)) HFC_outb(hc, R_GPIO_SEL, 0x32); else HFC_outb(hc, R_GPIO_SEL, 0x30); HFC_outb(hc, R_GPIO_EN1, 0x0f); HFC_outb(hc, R_GPIO_OUT1, 0x00); HFC_outb(hc, R_GPIO_EN0, V_GPIO_EN2 | V_GPIO_EN3); break; case 2: /* HFC-4S OEM */ case 3: HFC_outb(hc, R_GPIO_SEL, 0xf0); HFC_outb(hc, R_GPIO_EN1, 0xff); HFC_outb(hc, R_GPIO_OUT1, 0x00); break; } /* set master clock */ if (hc->masterclk >= 0) { if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: setting ST master clock " "to port %d (0..%d)\n", __func__, hc->masterclk, hc->ports-1); hc->hw.r_st_sync = hc->masterclk | V_AUTO_SYNC; HFC_outb(hc, R_ST_SYNC, hc->hw.r_st_sync); } /* setting misc irq */ HFC_outb(hc, R_IRQMSK_MISC, hc->hw.r_irqmsk_misc); if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "r_irqmsk_misc.2: 0x%x\n", hc->hw.r_irqmsk_misc); /* RAM access test */ HFC_outb(hc, R_RAM_ADDR0, 0); HFC_outb(hc, R_RAM_ADDR1, 0); HFC_outb(hc, R_RAM_ADDR2, 0); for (i = 0; i < 256; i++) { HFC_outb_nodebug(hc, R_RAM_ADDR0, i); HFC_outb_nodebug(hc, R_RAM_DATA, ((i*3)&0xff)); } for (i = 0; i < 256; i++) { HFC_outb_nodebug(hc, R_RAM_ADDR0, i); HFC_inb_nodebug(hc, R_RAM_DATA); rval = HFC_inb_nodebug(hc, R_INT_DATA); if (rval != ((i * 3) & 0xff)) { printk(KERN_DEBUG "addr:%x val:%x should:%x\n", i, rval, (i * 3) & 0xff); err++; } } if (err) { printk(KERN_DEBUG "aborting - %d RAM access errors\n", err); err = -EIO; goto out; } if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: done\n", __func__); out: spin_unlock_irqrestore(&hc->lock, flags); return err; } /* * control the watchdog */ static void hfcmulti_watchdog(struct hfc_multi *hc) { hc->wdcount++; if (hc->wdcount > 10) { hc->wdcount = 0; hc->wdbyte = hc->wdbyte == V_GPIO_OUT2 ? V_GPIO_OUT3 : V_GPIO_OUT2; /* printk("Sending Watchdog Kill %x\n",hc->wdbyte); */ HFC_outb(hc, R_GPIO_EN0, V_GPIO_EN2 | V_GPIO_EN3); HFC_outb(hc, R_GPIO_OUT0, hc->wdbyte); } } /* * output leds */ static void hfcmulti_leds(struct hfc_multi *hc) { unsigned long lled; unsigned long leddw; int i, state, active, leds; struct dchannel *dch; int led[4]; hc->ledcount += poll; if (hc->ledcount > 4096) { hc->ledcount -= 4096; hc->ledstate = 0xAFFEAFFE; } switch (hc->leds) { case 1: /* HFC-E1 OEM */ /* 2 red blinking: NT mode deactivate * 2 red steady: TE mode deactivate * left green: L1 active * left red: frame sync, but no L1 * right green: L2 active */ if (hc->chan[hc->dslot].sync != 2) { /* no frame sync */ if (hc->chan[hc->dslot].dch->dev.D.protocol != ISDN_P_NT_E1) { led[0] = 1; led[1] = 1; } else if (hc->ledcount>>11) { led[0] = 1; led[1] = 1; } else { led[0] = 0; led[1] = 0; } led[2] = 0; led[3] = 0; } else { /* with frame sync */ /* TODO make it work */ led[0] = 0; led[1] = 0; led[2] = 0; led[3] = 1; } leds = (led[0] | (led[1]<<2) | (led[2]<<1) | (led[3]<<3))^0xF; /* leds are inverted */ if (leds != (int)hc->ledstate) { HFC_outb_nodebug(hc, R_GPIO_OUT1, leds); hc->ledstate = leds; } break; case 2: /* HFC-4S OEM */ /* red blinking = PH_DEACTIVATE NT Mode * red steady = PH_DEACTIVATE TE Mode * green steady = PH_ACTIVATE */ for (i = 0; i < 4; i++) { state = 0; active = -1; dch = hc->chan[(i << 2) | 2].dch; if (dch) { state = dch->state; if (dch->dev.D.protocol == ISDN_P_NT_S0) active = 3; else active = 7; } if (state) { if (state == active) { led[i] = 1; /* led green */ } else if (dch->dev.D.protocol == ISDN_P_TE_S0) /* TE mode: led red */ led[i] = 2; else if (hc->ledcount>>11) /* led red */ led[i] = 2; else /* led off */ led[i] = 0; } else led[i] = 0; /* led off */ } if (test_bit(HFC_CHIP_B410P, &hc->chip)) { leds = 0; for (i = 0; i < 4; i++) { if (led[i] == 1) { /*green*/ leds |= (0x2 << (i * 2)); } else if (led[i] == 2) { /*red*/ leds |= (0x1 << (i * 2)); } } if (leds != (int)hc->ledstate) { vpm_out(hc, 0, 0x1a8 + 3, leds); hc->ledstate = leds; } } else { leds = ((led[3] > 0) << 0) | ((led[1] > 0) << 1) | ((led[0] > 0) << 2) | ((led[2] > 0) << 3) | ((led[3] & 1) << 4) | ((led[1] & 1) << 5) | ((led[0] & 1) << 6) | ((led[2] & 1) << 7); if (leds != (int)hc->ledstate) { HFC_outb_nodebug(hc, R_GPIO_EN1, leds & 0x0F); HFC_outb_nodebug(hc, R_GPIO_OUT1, leds >> 4); hc->ledstate = leds; } } break; case 3: /* HFC 1S/2S Beronet */ /* red blinking = PH_DEACTIVATE NT Mode * red steady = PH_DEACTIVATE TE Mode * green steady = PH_ACTIVATE */ for (i = 0; i < 2; i++) { state = 0; active = -1; dch = hc->chan[(i << 2) | 2].dch; if (dch) { state = dch->state; if (dch->dev.D.protocol == ISDN_P_NT_S0) active = 3; else active = 7; } if (state) { if (state == active) { led[i] = 1; /* led green */ } else if (dch->dev.D.protocol == ISDN_P_TE_S0) /* TE mode: led red */ led[i] = 2; else if (hc->ledcount >> 11) /* led red */ led[i] = 2; else /* led off */ led[i] = 0; } else led[i] = 0; /* led off */ } leds = (led[0] > 0) | ((led[1] > 0)<<1) | ((led[0]&1)<<2) | ((led[1]&1)<<3); if (leds != (int)hc->ledstate) { HFC_outb_nodebug(hc, R_GPIO_EN1, ((led[0] > 0) << 2) | ((led[1] > 0) << 3)); HFC_outb_nodebug(hc, R_GPIO_OUT1, ((led[0] & 1) << 2) | ((led[1] & 1) << 3)); hc->ledstate = leds; } break; case 8: /* HFC 8S+ Beronet */ lled = 0; for (i = 0; i < 8; i++) { state = 0; active = -1; dch = hc->chan[(i << 2) | 2].dch; if (dch) { state = dch->state; if (dch->dev.D.protocol == ISDN_P_NT_S0) active = 3; else active = 7; } if (state) { if (state == active) { lled |= 0 << i; } else if (hc->ledcount >> 11) lled |= 0 << i; else lled |= 1 << i; } else lled |= 1 << i; } leddw = lled << 24 | lled << 16 | lled << 8 | lled; if (leddw != hc->ledstate) { /* HFC_outb(hc, R_BRG_PCM_CFG, 1); HFC_outb(c, R_BRG_PCM_CFG, (0x0 << 6) | 0x3); */ /* was _io before */ HFC_outb_nodebug(hc, R_BRG_PCM_CFG, 1 | V_PCM_CLK); outw(0x4000, hc->pci_iobase + 4); outl(leddw, hc->pci_iobase); HFC_outb_nodebug(hc, R_BRG_PCM_CFG, V_PCM_CLK); hc->ledstate = leddw; } break; } } /* * read dtmf coefficients */ static void hfcmulti_dtmf(struct hfc_multi *hc) { s32 *coeff; u_int mantissa; int co, ch; struct bchannel *bch = NULL; u8 exponent; int dtmf = 0; int addr; u16 w_float; struct sk_buff *skb; struct mISDNhead *hh; if (debug & DEBUG_HFCMULTI_DTMF) printk(KERN_DEBUG "%s: dtmf detection irq\n", __func__); for (ch = 0; ch <= 31; ch++) { /* only process enabled B-channels */ bch = hc->chan[ch].bch; if (!bch) continue; if (!hc->created[hc->chan[ch].port]) continue; if (!test_bit(FLG_TRANSPARENT, &bch->Flags)) continue; if (debug & DEBUG_HFCMULTI_DTMF) printk(KERN_DEBUG "%s: dtmf channel %d:", __func__, ch); coeff = &(hc->chan[ch].coeff[hc->chan[ch].coeff_count * 16]); dtmf = 1; for (co = 0; co < 8; co++) { /* read W(n-1) coefficient */ addr = hc->DTMFbase + ((co<<7) | (ch<<2)); HFC_outb_nodebug(hc, R_RAM_ADDR0, addr); HFC_outb_nodebug(hc, R_RAM_ADDR1, addr>>8); HFC_outb_nodebug(hc, R_RAM_ADDR2, (addr>>16) | V_ADDR_INC); w_float = HFC_inb_nodebug(hc, R_RAM_DATA); w_float |= (HFC_inb_nodebug(hc, R_RAM_DATA) << 8); if (debug & DEBUG_HFCMULTI_DTMF) printk(" %04x", w_float); /* decode float (see chip doc) */ mantissa = w_float & 0x0fff; if (w_float & 0x8000) mantissa |= 0xfffff000; exponent = (w_float>>12) & 0x7; if (exponent) { mantissa ^= 0x1000; mantissa <<= (exponent-1); } /* store coefficient */ coeff[co<<1] = mantissa; /* read W(n) coefficient */ w_float = HFC_inb_nodebug(hc, R_RAM_DATA); w_float |= (HFC_inb_nodebug(hc, R_RAM_DATA) << 8); if (debug & DEBUG_HFCMULTI_DTMF) printk(" %04x", w_float); /* decode float (see chip doc) */ mantissa = w_float & 0x0fff; if (w_float & 0x8000) mantissa |= 0xfffff000; exponent = (w_float>>12) & 0x7; if (exponent) { mantissa ^= 0x1000; mantissa <<= (exponent-1); } /* store coefficient */ coeff[(co<<1)|1] = mantissa; } if (debug & DEBUG_HFCMULTI_DTMF) printk("%s: DTMF ready %08x %08x %08x %08x " "%08x %08x %08x %08x\n", __func__, coeff[0], coeff[1], coeff[2], coeff[3], coeff[4], coeff[5], coeff[6], coeff[7]); hc->chan[ch].coeff_count++; if (hc->chan[ch].coeff_count == 8) { hc->chan[ch].coeff_count = 0; skb = mI_alloc_skb(512, GFP_ATOMIC); if (!skb) { printk(KERN_WARNING "%s: No memory for skb\n", __func__); continue; } hh = mISDN_HEAD_P(skb); hh->prim = PH_CONTROL_IND; hh->id = DTMF_HFC_COEF; memcpy(skb_put(skb, 512), hc->chan[ch].coeff, 512); recv_Bchannel_skb(bch, skb); } } /* restart DTMF processing */ hc->dtmf = dtmf; if (dtmf) HFC_outb_nodebug(hc, R_DTMF, hc->hw.r_dtmf | V_RST_DTMF); } /* * fill fifo as much as possible */ static void hfcmulti_tx(struct hfc_multi *hc, int ch) { int i, ii, temp, len = 0; int Zspace, z1, z2; /* must be int for calculation */ int Fspace, f1, f2; u_char *d; int *txpending, slot_tx; struct bchannel *bch; struct dchannel *dch; struct sk_buff **sp = NULL; int *idxp; bch = hc->chan[ch].bch; dch = hc->chan[ch].dch; if ((!dch) && (!bch)) return; txpending = &hc->chan[ch].txpending; slot_tx = hc->chan[ch].slot_tx; if (dch) { if (!test_bit(FLG_ACTIVE, &dch->Flags)) return; sp = &dch->tx_skb; idxp = &dch->tx_idx; } else { if (!test_bit(FLG_ACTIVE, &bch->Flags)) return; sp = &bch->tx_skb; idxp = &bch->tx_idx; } if (*sp) len = (*sp)->len; if ((!len) && *txpending != 1) return; /* no data */ if (test_bit(HFC_CHIP_B410P, &hc->chip) && (hc->chan[ch].protocol == ISDN_P_B_RAW) && (hc->chan[ch].slot_rx < 0) && (hc->chan[ch].slot_tx < 0)) HFC_outb_nodebug(hc, R_FIFO, 0x20 | (ch << 1)); else HFC_outb_nodebug(hc, R_FIFO, ch << 1); HFC_wait_nodebug(hc); if (*txpending == 2) { /* reset fifo */ HFC_outb_nodebug(hc, R_INC_RES_FIFO, V_RES_F); HFC_wait_nodebug(hc); HFC_outb(hc, A_SUBCH_CFG, 0); *txpending = 1; } next_frame: if (dch || test_bit(FLG_HDLC, &bch->Flags)) { f1 = HFC_inb_nodebug(hc, A_F1); f2 = HFC_inb_nodebug(hc, A_F2); while (f2 != (temp = HFC_inb_nodebug(hc, A_F2))) { if (debug & DEBUG_HFCMULTI_FIFO) printk(KERN_DEBUG "%s(card %d): reread f2 because %d!=%d\n", __func__, hc->id + 1, temp, f2); f2 = temp; /* repeat until F2 is equal */ } Fspace = f2 - f1 - 1; if (Fspace < 0) Fspace += hc->Flen; /* * Old FIFO handling doesn't give us the current Z2 read * pointer, so we cannot send the next frame before the fifo * is empty. It makes no difference except for a slightly * lower performance. */ if (test_bit(HFC_CHIP_REVISION0, &hc->chip)) { if (f1 != f2) Fspace = 0; else Fspace = 1; } /* one frame only for ST D-channels, to allow resending */ if (hc->type != 1 && dch) { if (f1 != f2) Fspace = 0; } /* F-counter full condition */ if (Fspace == 0) return; } z1 = HFC_inw_nodebug(hc, A_Z1) - hc->Zmin; z2 = HFC_inw_nodebug(hc, A_Z2) - hc->Zmin; while (z2 != (temp = (HFC_inw_nodebug(hc, A_Z2) - hc->Zmin))) { if (debug & DEBUG_HFCMULTI_FIFO) printk(KERN_DEBUG "%s(card %d): reread z2 because " "%d!=%d\n", __func__, hc->id + 1, temp, z2); z2 = temp; /* repeat unti Z2 is equal */ } Zspace = z2 - z1; if (Zspace <= 0) Zspace += hc->Zlen; Zspace -= 4; /* keep not too full, so pointers will not overrun */ /* fill transparent data only to maxinum transparent load (minus 4) */ if (bch && test_bit(FLG_TRANSPARENT, &bch->Flags)) Zspace = Zspace - hc->Zlen + hc->max_trans; if (Zspace <= 0) /* no space of 4 bytes */ return; /* if no data */ if (!len) { if (z1 == z2) { /* empty */ /* if done with FIFO audio data during PCM connection */ if (bch && (!test_bit(FLG_HDLC, &bch->Flags)) && *txpending && slot_tx >= 0) { if (debug & DEBUG_HFCMULTI_MODE) printk(KERN_DEBUG "%s: reconnecting PCM due to no " "more FIFO data: channel %d " "slot_tx %d\n", __func__, ch, slot_tx); /* connect slot */ HFC_outb(hc, A_CON_HDLC, 0xc0 | 0x00 | V_HDLC_TRP | V_IFF); HFC_outb_nodebug(hc, R_FIFO, ch<<1 | 1); HFC_wait_nodebug(hc); HFC_outb(hc, A_CON_HDLC, 0xc0 | 0x00 | V_HDLC_TRP | V_IFF); HFC_outb_nodebug(hc, R_FIFO, ch<<1); HFC_wait_nodebug(hc); } *txpending = 0; } return; /* no data */ } /* "fill fifo if empty" feature */ if (bch && test_bit(FLG_FILLEMPTY, &bch->Flags) && !test_bit(FLG_HDLC, &bch->Flags) && z2 == z1) { if (debug & DEBUG_HFCMULTI_FILL) printk(KERN_DEBUG "%s: buffer empty, so we have " "underrun\n", __func__); /* fill buffer, to prevent future underrun */ hc->write_fifo(hc, hc->silence_data, poll >> 1); Zspace -= (poll >> 1); } /* if audio data and connected slot */ if (bch && (!test_bit(FLG_HDLC, &bch->Flags)) && (!*txpending) && slot_tx >= 0) { if (debug & DEBUG_HFCMULTI_MODE) printk(KERN_DEBUG "%s: disconnecting PCM due to " "FIFO data: channel %d slot_tx %d\n", __func__, ch, slot_tx); /* disconnect slot */ HFC_outb(hc, A_CON_HDLC, 0x80 | 0x00 | V_HDLC_TRP | V_IFF); HFC_outb_nodebug(hc, R_FIFO, ch<<1 | 1); HFC_wait_nodebug(hc); HFC_outb(hc, A_CON_HDLC, 0x80 | 0x00 | V_HDLC_TRP | V_IFF); HFC_outb_nodebug(hc, R_FIFO, ch<<1); HFC_wait_nodebug(hc); } *txpending = 1; /* show activity */ hc->activity[hc->chan[ch].port] = 1; /* fill fifo to what we have left */ ii = len; if (dch || test_bit(FLG_HDLC, &bch->Flags)) temp = 1; else temp = 0; i = *idxp; d = (*sp)->data + i; if (ii - i > Zspace) ii = Zspace + i; if (debug & DEBUG_HFCMULTI_FIFO) printk(KERN_DEBUG "%s(card %d): fifo(%d) has %d bytes space " "left (z1=%04x, z2=%04x) sending %d of %d bytes %s\n", __func__, hc->id + 1, ch, Zspace, z1, z2, ii-i, len-i, temp ? "HDLC":"TRANS"); /* Have to prep the audio data */ hc->write_fifo(hc, d, ii - i); *idxp = ii; /* if not all data has been written */ if (ii != len) { /* NOTE: fifo is started by the calling function */ return; } /* if all data has been written, terminate frame */ if (dch || test_bit(FLG_HDLC, &bch->Flags)) { /* increment f-counter */ HFC_outb_nodebug(hc, R_INC_RES_FIFO, V_INC_F); HFC_wait_nodebug(hc); } /* send confirm, since get_net_bframe will not do it with trans */ if (bch && test_bit(FLG_TRANSPARENT, &bch->Flags)) confirm_Bsend(bch); /* check for next frame */ dev_kfree_skb(*sp); if (bch && get_next_bframe(bch)) { /* hdlc is confirmed here */ len = (*sp)->len; goto next_frame; } if (dch && get_next_dframe(dch)) { len = (*sp)->len; goto next_frame; } /* * now we have no more data, so in case of transparent, * we set the last byte in fifo to 'silence' in case we will get * no more data at all. this prevents sending an undefined value. */ if (bch && test_bit(FLG_TRANSPARENT, &bch->Flags)) HFC_outb_nodebug(hc, A_FIFO_DATA0_NOINC, hc->silence); } /* NOTE: only called if E1 card is in active state */ static void hfcmulti_rx(struct hfc_multi *hc, int ch) { int temp; int Zsize, z1, z2 = 0; /* = 0, to make GCC happy */ int f1 = 0, f2 = 0; /* = 0, to make GCC happy */ int again = 0; struct bchannel *bch; struct dchannel *dch; struct sk_buff *skb, **sp = NULL; int maxlen; bch = hc->chan[ch].bch; dch = hc->chan[ch].dch; if ((!dch) && (!bch)) return; if (dch) { if (!test_bit(FLG_ACTIVE, &dch->Flags)) return; sp = &dch->rx_skb; maxlen = dch->maxlen; } else { if (!test_bit(FLG_ACTIVE, &bch->Flags)) return; sp = &bch->rx_skb; maxlen = bch->maxlen; } next_frame: /* on first AND before getting next valid frame, R_FIFO must be written to. */ if (test_bit(HFC_CHIP_B410P, &hc->chip) && (hc->chan[ch].protocol == ISDN_P_B_RAW) && (hc->chan[ch].slot_rx < 0) && (hc->chan[ch].slot_tx < 0)) HFC_outb_nodebug(hc, R_FIFO, 0x20 | (ch<<1) | 1); else HFC_outb_nodebug(hc, R_FIFO, (ch<<1)|1); HFC_wait_nodebug(hc); /* ignore if rx is off BUT change fifo (above) to start pending TX */ if (hc->chan[ch].rx_off) return; if (dch || test_bit(FLG_HDLC, &bch->Flags)) { f1 = HFC_inb_nodebug(hc, A_F1); while (f1 != (temp = HFC_inb_nodebug(hc, A_F1))) { if (debug & DEBUG_HFCMULTI_FIFO) printk(KERN_DEBUG "%s(card %d): reread f1 because %d!=%d\n", __func__, hc->id + 1, temp, f1); f1 = temp; /* repeat until F1 is equal */ } f2 = HFC_inb_nodebug(hc, A_F2); } z1 = HFC_inw_nodebug(hc, A_Z1) - hc->Zmin; while (z1 != (temp = (HFC_inw_nodebug(hc, A_Z1) - hc->Zmin))) { if (debug & DEBUG_HFCMULTI_FIFO) printk(KERN_DEBUG "%s(card %d): reread z2 because " "%d!=%d\n", __func__, hc->id + 1, temp, z2); z1 = temp; /* repeat until Z1 is equal */ } z2 = HFC_inw_nodebug(hc, A_Z2) - hc->Zmin; Zsize = z1 - z2; if ((dch || test_bit(FLG_HDLC, &bch->Flags)) && f1 != f2) /* complete hdlc frame */ Zsize++; if (Zsize < 0) Zsize += hc->Zlen; /* if buffer is empty */ if (Zsize <= 0) return; if (*sp == NULL) { *sp = mI_alloc_skb(maxlen + 3, GFP_ATOMIC); if (*sp == NULL) { printk(KERN_DEBUG "%s: No mem for rx_skb\n", __func__); return; } } /* show activity */ hc->activity[hc->chan[ch].port] = 1; /* empty fifo with what we have */ if (dch || test_bit(FLG_HDLC, &bch->Flags)) { if (debug & DEBUG_HFCMULTI_FIFO) printk(KERN_DEBUG "%s(card %d): fifo(%d) reading %d " "bytes (z1=%04x, z2=%04x) HDLC %s (f1=%d, f2=%d) " "got=%d (again %d)\n", __func__, hc->id + 1, ch, Zsize, z1, z2, (f1 == f2) ? "fragment" : "COMPLETE", f1, f2, Zsize + (*sp)->len, again); /* HDLC */ if ((Zsize + (*sp)->len) > (maxlen + 3)) { if (debug & DEBUG_HFCMULTI_FIFO) printk(KERN_DEBUG "%s(card %d): hdlc-frame too large.\n", __func__, hc->id + 1); skb_trim(*sp, 0); HFC_outb_nodebug(hc, R_INC_RES_FIFO, V_RES_F); HFC_wait_nodebug(hc); return; } hc->read_fifo(hc, skb_put(*sp, Zsize), Zsize); if (f1 != f2) { /* increment Z2,F2-counter */ HFC_outb_nodebug(hc, R_INC_RES_FIFO, V_INC_F); HFC_wait_nodebug(hc); /* check size */ if ((*sp)->len < 4) { if (debug & DEBUG_HFCMULTI_FIFO) printk(KERN_DEBUG "%s(card %d): Frame below minimum " "size\n", __func__, hc->id + 1); skb_trim(*sp, 0); goto next_frame; } /* there is at least one complete frame, check crc */ if ((*sp)->data[(*sp)->len - 1]) { if (debug & DEBUG_HFCMULTI_CRC) printk(KERN_DEBUG "%s: CRC-error\n", __func__); skb_trim(*sp, 0); goto next_frame; } skb_trim(*sp, (*sp)->len - 3); if ((*sp)->len < MISDN_COPY_SIZE) { skb = *sp; *sp = mI_alloc_skb(skb->len, GFP_ATOMIC); if (*sp) { memcpy(skb_put(*sp, skb->len), skb->data, skb->len); skb_trim(skb, 0); } else { printk(KERN_DEBUG "%s: No mem\n", __func__); *sp = skb; skb = NULL; } } else { skb = NULL; } if (debug & DEBUG_HFCMULTI_FIFO) { printk(KERN_DEBUG "%s(card %d):", __func__, hc->id + 1); temp = 0; while (temp < (*sp)->len) printk(" %02x", (*sp)->data[temp++]); printk("\n"); } if (dch) recv_Dchannel(dch); else recv_Bchannel(bch); *sp = skb; again++; goto next_frame; } /* there is an incomplete frame */ } else { /* transparent */ if (Zsize > skb_tailroom(*sp)) Zsize = skb_tailroom(*sp); hc->read_fifo(hc, skb_put(*sp, Zsize), Zsize); if (((*sp)->len) < MISDN_COPY_SIZE) { skb = *sp; *sp = mI_alloc_skb(skb->len, GFP_ATOMIC); if (*sp) { memcpy(skb_put(*sp, skb->len), skb->data, skb->len); skb_trim(skb, 0); } else { printk(KERN_DEBUG "%s: No mem\n", __func__); *sp = skb; skb = NULL; } } else { skb = NULL; } if (debug & DEBUG_HFCMULTI_FIFO) printk(KERN_DEBUG "%s(card %d): fifo(%d) reading %d bytes " "(z1=%04x, z2=%04x) TRANS\n", __func__, hc->id + 1, ch, Zsize, z1, z2); /* only bch is transparent */ recv_Bchannel(bch); *sp = skb; } } /* * Interrupt handler */ static void signal_state_up(struct dchannel *dch, int info, char *msg) { struct sk_buff *skb; int id, data = info; if (debug & DEBUG_HFCMULTI_STATE) printk(KERN_DEBUG "%s: %s\n", __func__, msg); id = TEI_SAPI | (GROUP_TEI << 8); /* manager address */ skb = _alloc_mISDN_skb(MPH_INFORMATION_IND, id, sizeof(data), &data, GFP_ATOMIC); if (!skb) return; recv_Dchannel_skb(dch, skb); } static inline void handle_timer_irq(struct hfc_multi *hc) { int ch, temp; struct dchannel *dch; u_long flags; /* process queued resync jobs */ if (hc->e1_resync) { /* lock, so e1_resync gets not changed */ spin_lock_irqsave(&HFClock, flags); if (hc->e1_resync & 1) { if (debug & DEBUG_HFCMULTI_PLXSD) printk(KERN_DEBUG "Enable SYNC_I\n"); HFC_outb(hc, R_SYNC_CTRL, V_EXT_CLK_SYNC); /* disable JATT, if RX_SYNC is set */ if (test_bit(HFC_CHIP_RX_SYNC, &hc->chip)) HFC_outb(hc, R_SYNC_OUT, V_SYNC_E1_RX); } if (hc->e1_resync & 2) { if (debug & DEBUG_HFCMULTI_PLXSD) printk(KERN_DEBUG "Enable jatt PLL\n"); HFC_outb(hc, R_SYNC_CTRL, V_SYNC_OFFS); } if (hc->e1_resync & 4) { if (debug & DEBUG_HFCMULTI_PLXSD) printk(KERN_DEBUG "Enable QUARTZ for HFC-E1\n"); /* set jatt to quartz */ HFC_outb(hc, R_SYNC_CTRL, V_EXT_CLK_SYNC | V_JATT_OFF); /* switch to JATT, in case it is not already */ HFC_outb(hc, R_SYNC_OUT, 0); } hc->e1_resync = 0; spin_unlock_irqrestore(&HFClock, flags); } if (hc->type != 1 || hc->e1_state == 1) for (ch = 0; ch <= 31; ch++) { if (hc->created[hc->chan[ch].port]) { hfcmulti_tx(hc, ch); /* fifo is started when switching to rx-fifo */ hfcmulti_rx(hc, ch); if (hc->chan[ch].dch && hc->chan[ch].nt_timer > -1) { dch = hc->chan[ch].dch; if (!(--hc->chan[ch].nt_timer)) { schedule_event(dch, FLG_PHCHANGE); if (debug & DEBUG_HFCMULTI_STATE) printk(KERN_DEBUG "%s: nt_timer at " "state %x\n", __func__, dch->state); } } } } if (hc->type == 1 && hc->created[0]) { dch = hc->chan[hc->dslot].dch; if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dslot].cfg)) { /* LOS */ temp = HFC_inb_nodebug(hc, R_SYNC_STA) & V_SIG_LOS; if (!temp && hc->chan[hc->dslot].los) signal_state_up(dch, L1_SIGNAL_LOS_ON, "LOS detected"); if (temp && !hc->chan[hc->dslot].los) signal_state_up(dch, L1_SIGNAL_LOS_OFF, "LOS gone"); hc->chan[hc->dslot].los = temp; } if (test_bit(HFC_CFG_REPORT_AIS, &hc->chan[hc->dslot].cfg)) { /* AIS */ temp = HFC_inb_nodebug(hc, R_SYNC_STA) & V_AIS; if (!temp && hc->chan[hc->dslot].ais) signal_state_up(dch, L1_SIGNAL_AIS_ON, "AIS detected"); if (temp && !hc->chan[hc->dslot].ais) signal_state_up(dch, L1_SIGNAL_AIS_OFF, "AIS gone"); hc->chan[hc->dslot].ais = temp; } if (test_bit(HFC_CFG_REPORT_SLIP, &hc->chan[hc->dslot].cfg)) { /* SLIP */ temp = HFC_inb_nodebug(hc, R_SLIP) & V_FOSLIP_RX; if (!temp && hc->chan[hc->dslot].slip_rx) signal_state_up(dch, L1_SIGNAL_SLIP_RX, " bit SLIP detected RX"); hc->chan[hc->dslot].slip_rx = temp; temp = HFC_inb_nodebug(hc, R_SLIP) & V_FOSLIP_TX; if (!temp && hc->chan[hc->dslot].slip_tx) signal_state_up(dch, L1_SIGNAL_SLIP_TX, " bit SLIP detected TX"); hc->chan[hc->dslot].slip_tx = temp; } if (test_bit(HFC_CFG_REPORT_RDI, &hc->chan[hc->dslot].cfg)) { /* RDI */ temp = HFC_inb_nodebug(hc, R_RX_SL0_0) & V_A; if (!temp && hc->chan[hc->dslot].rdi) signal_state_up(dch, L1_SIGNAL_RDI_ON, "RDI detected"); if (temp && !hc->chan[hc->dslot].rdi) signal_state_up(dch, L1_SIGNAL_RDI_OFF, "RDI gone"); hc->chan[hc->dslot].rdi = temp; } temp = HFC_inb_nodebug(hc, R_JATT_DIR); switch (hc->chan[hc->dslot].sync) { case 0: if ((temp & 0x60) == 0x60) { if (debug & DEBUG_HFCMULTI_SYNC) printk(KERN_DEBUG "%s: (id=%d) E1 now " "in clock sync\n", __func__, hc->id); HFC_outb(hc, R_RX_OFF, hc->chan[hc->dslot].jitter | V_RX_INIT); HFC_outb(hc, R_TX_OFF, hc->chan[hc->dslot].jitter | V_RX_INIT); hc->chan[hc->dslot].sync = 1; goto check_framesync; } break; case 1: if ((temp & 0x60) != 0x60) { if (debug & DEBUG_HFCMULTI_SYNC) printk(KERN_DEBUG "%s: (id=%d) E1 " "lost clock sync\n", __func__, hc->id); hc->chan[hc->dslot].sync = 0; break; } check_framesync: temp = HFC_inb_nodebug(hc, R_SYNC_STA); if (temp == 0x27) { if (debug & DEBUG_HFCMULTI_SYNC) printk(KERN_DEBUG "%s: (id=%d) E1 " "now in frame sync\n", __func__, hc->id); hc->chan[hc->dslot].sync = 2; } break; case 2: if ((temp & 0x60) != 0x60) { if (debug & DEBUG_HFCMULTI_SYNC) printk(KERN_DEBUG "%s: (id=%d) E1 lost " "clock & frame sync\n", __func__, hc->id); hc->chan[hc->dslot].sync = 0; break; } temp = HFC_inb_nodebug(hc, R_SYNC_STA); if (temp != 0x27) { if (debug & DEBUG_HFCMULTI_SYNC) printk(KERN_DEBUG "%s: (id=%d) E1 " "lost frame sync\n", __func__, hc->id); hc->chan[hc->dslot].sync = 1; } break; } } if (test_bit(HFC_CHIP_WATCHDOG, &hc->chip)) hfcmulti_watchdog(hc); if (hc->leds) hfcmulti_leds(hc); } static void ph_state_irq(struct hfc_multi *hc, u_char r_irq_statech) { struct dchannel *dch; int ch; int active; u_char st_status, temp; /* state machine */ for (ch = 0; ch <= 31; ch++) { if (hc->chan[ch].dch) { dch = hc->chan[ch].dch; if (r_irq_statech & 1) { HFC_outb_nodebug(hc, R_ST_SEL, hc->chan[ch].port); /* undocumented: delay after R_ST_SEL */ udelay(1); /* undocumented: status changes during read */ st_status = HFC_inb_nodebug(hc, A_ST_RD_STATE); while (st_status != (temp = HFC_inb_nodebug(hc, A_ST_RD_STATE))) { if (debug & DEBUG_HFCMULTI_STATE) printk(KERN_DEBUG "%s: reread " "STATE because %d!=%d\n", __func__, temp, st_status); st_status = temp; /* repeat */ } /* Speech Design TE-sync indication */ if (test_bit(HFC_CHIP_PLXSD, &hc->chip) && dch->dev.D.protocol == ISDN_P_TE_S0) { if (st_status & V_FR_SYNC_ST) hc->syncronized |= (1 << hc->chan[ch].port); else hc->syncronized &= ~(1 << hc->chan[ch].port); } dch->state = st_status & 0x0f; if (dch->dev.D.protocol == ISDN_P_NT_S0) active = 3; else active = 7; if (dch->state == active) { HFC_outb_nodebug(hc, R_FIFO, (ch << 1) | 1); HFC_wait_nodebug(hc); HFC_outb_nodebug(hc, R_INC_RES_FIFO, V_RES_F); HFC_wait_nodebug(hc); dch->tx_idx = 0; } schedule_event(dch, FLG_PHCHANGE); if (debug & DEBUG_HFCMULTI_STATE) printk(KERN_DEBUG "%s: S/T newstate %x port %d\n", __func__, dch->state, hc->chan[ch].port); } r_irq_statech >>= 1; } } if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) plxsd_checksync(hc, 0); } static void fifo_irq(struct hfc_multi *hc, int block) { int ch, j; struct dchannel *dch; struct bchannel *bch; u_char r_irq_fifo_bl; r_irq_fifo_bl = HFC_inb_nodebug(hc, R_IRQ_FIFO_BL0 + block); j = 0; while (j < 8) { ch = (block << 2) + (j >> 1); dch = hc->chan[ch].dch; bch = hc->chan[ch].bch; if (((!dch) && (!bch)) || (!hc->created[hc->chan[ch].port])) { j += 2; continue; } if (dch && (r_irq_fifo_bl & (1 << j)) && test_bit(FLG_ACTIVE, &dch->Flags)) { hfcmulti_tx(hc, ch); /* start fifo */ HFC_outb_nodebug(hc, R_FIFO, 0); HFC_wait_nodebug(hc); } if (bch && (r_irq_fifo_bl & (1 << j)) && test_bit(FLG_ACTIVE, &bch->Flags)) { hfcmulti_tx(hc, ch); /* start fifo */ HFC_outb_nodebug(hc, R_FIFO, 0); HFC_wait_nodebug(hc); } j++; if (dch && (r_irq_fifo_bl & (1 << j)) && test_bit(FLG_ACTIVE, &dch->Flags)) { hfcmulti_rx(hc, ch); } if (bch && (r_irq_fifo_bl & (1 << j)) && test_bit(FLG_ACTIVE, &bch->Flags)) { hfcmulti_rx(hc, ch); } j++; } } #ifdef IRQ_DEBUG int irqsem; #endif static irqreturn_t hfcmulti_interrupt(int intno, void *dev_id) { #ifdef IRQCOUNT_DEBUG static int iq1 = 0, iq2 = 0, iq3 = 0, iq4 = 0, iq5 = 0, iq6 = 0, iqcnt = 0; #endif struct hfc_multi *hc = dev_id; struct dchannel *dch; u_char r_irq_statech, status, r_irq_misc, r_irq_oview; int i; void __iomem *plx_acc; u_short wval; u_char e1_syncsta, temp; u_long flags; if (!hc) { printk(KERN_ERR "HFC-multi: Spurious interrupt!\n"); return IRQ_NONE; } spin_lock(&hc->lock); #ifdef IRQ_DEBUG if (irqsem) printk(KERN_ERR "irq for card %d during irq from " "card %d, this is no bug.\n", hc->id + 1, irqsem); irqsem = hc->id + 1; #endif if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { spin_lock_irqsave(&plx_lock, flags); plx_acc = hc->plx_membase + PLX_INTCSR; wval = readw(plx_acc); spin_unlock_irqrestore(&plx_lock, flags); if (!(wval & PLX_INTCSR_LINTI1_STATUS)) goto irq_notforus; } status = HFC_inb_nodebug(hc, R_STATUS); r_irq_statech = HFC_inb_nodebug(hc, R_IRQ_STATECH); #ifdef IRQCOUNT_DEBUG if (r_irq_statech) iq1++; if (status & V_DTMF_STA) iq2++; if (status & V_LOST_STA) iq3++; if (status & V_EXT_IRQSTA) iq4++; if (status & V_MISC_IRQSTA) iq5++; if (status & V_FR_IRQSTA) iq6++; if (iqcnt++ > 5000) { printk(KERN_ERR "iq1:%x iq2:%x iq3:%x iq4:%x iq5:%x iq6:%x\n", iq1, iq2, iq3, iq4, iq5, iq6); iqcnt = 0; } #endif if (!r_irq_statech && !(status & (V_DTMF_STA | V_LOST_STA | V_EXT_IRQSTA | V_MISC_IRQSTA | V_FR_IRQSTA))) { /* irq is not for us */ goto irq_notforus; } hc->irqcnt++; if (r_irq_statech) { if (hc->type != 1) ph_state_irq(hc, r_irq_statech); } if (status & V_EXT_IRQSTA) ; /* external IRQ */ if (status & V_LOST_STA) { /* LOST IRQ */ HFC_outb(hc, R_INC_RES_FIFO, V_RES_LOST); /* clear irq! */ } if (status & V_MISC_IRQSTA) { /* misc IRQ */ r_irq_misc = HFC_inb_nodebug(hc, R_IRQ_MISC); r_irq_misc &= hc->hw.r_irqmsk_misc; /* ignore disabled irqs */ if (r_irq_misc & V_STA_IRQ) { if (hc->type == 1) { /* state machine */ dch = hc->chan[hc->dslot].dch; e1_syncsta = HFC_inb_nodebug(hc, R_SYNC_STA); if (test_bit(HFC_CHIP_PLXSD, &hc->chip) && hc->e1_getclock) { if (e1_syncsta & V_FR_SYNC_E1) hc->syncronized = 1; else hc->syncronized = 0; } /* undocumented: status changes during read */ dch->state = HFC_inb_nodebug(hc, R_E1_RD_STA); while (dch->state != (temp = HFC_inb_nodebug(hc, R_E1_RD_STA))) { if (debug & DEBUG_HFCMULTI_STATE) printk(KERN_DEBUG "%s: reread " "STATE because %d!=%d\n", __func__, temp, dch->state); dch->state = temp; /* repeat */ } dch->state = HFC_inb_nodebug(hc, R_E1_RD_STA) & 0x7; schedule_event(dch, FLG_PHCHANGE); if (debug & DEBUG_HFCMULTI_STATE) printk(KERN_DEBUG "%s: E1 (id=%d) newstate %x\n", __func__, hc->id, dch->state); if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) plxsd_checksync(hc, 0); } } if (r_irq_misc & V_TI_IRQ) { if (hc->iclock_on) mISDN_clock_update(hc->iclock, poll, NULL); handle_timer_irq(hc); } if (r_irq_misc & V_DTMF_IRQ) { hfcmulti_dtmf(hc); } if (r_irq_misc & V_IRQ_PROC) { static int irq_proc_cnt; if (!irq_proc_cnt++) printk(KERN_WARNING "%s: got V_IRQ_PROC -" " this should not happen\n", __func__); } } if (status & V_FR_IRQSTA) { /* FIFO IRQ */ r_irq_oview = HFC_inb_nodebug(hc, R_IRQ_OVIEW); for (i = 0; i < 8; i++) { if (r_irq_oview & (1 << i)) fifo_irq(hc, i); } } #ifdef IRQ_DEBUG irqsem = 0; #endif spin_unlock(&hc->lock); return IRQ_HANDLED; irq_notforus: #ifdef IRQ_DEBUG irqsem = 0; #endif spin_unlock(&hc->lock); return IRQ_NONE; } /* * timer callback for D-chan busy resolution. Currently no function */ static void hfcmulti_dbusy_timer(struct hfc_multi *hc) { } /* * activate/deactivate hardware for selected channels and mode * * configure B-channel with the given protocol * ch eqals to the HFC-channel (0-31) * ch is the number of channel (0-4,4-7,8-11,12-15,16-19,20-23,24-27,28-31 * for S/T, 1-31 for E1) * the hdlc interrupts will be set/unset */ static int mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx, int bank_tx, int slot_rx, int bank_rx) { int flow_tx = 0, flow_rx = 0, routing = 0; int oslot_tx, oslot_rx; int conf; if (ch < 0 || ch > 31) return EINVAL; oslot_tx = hc->chan[ch].slot_tx; oslot_rx = hc->chan[ch].slot_rx; conf = hc->chan[ch].conf; if (debug & DEBUG_HFCMULTI_MODE) printk(KERN_DEBUG "%s: card %d channel %d protocol %x slot old=%d new=%d " "bank new=%d (TX) slot old=%d new=%d bank new=%d (RX)\n", __func__, hc->id, ch, protocol, oslot_tx, slot_tx, bank_tx, oslot_rx, slot_rx, bank_rx); if (oslot_tx >= 0 && slot_tx != oslot_tx) { /* remove from slot */ if (debug & DEBUG_HFCMULTI_MODE) printk(KERN_DEBUG "%s: remove from slot %d (TX)\n", __func__, oslot_tx); if (hc->slot_owner[oslot_tx<<1] == ch) { HFC_outb(hc, R_SLOT, oslot_tx << 1); HFC_outb(hc, A_SL_CFG, 0); HFC_outb(hc, A_CONF, 0); hc->slot_owner[oslot_tx<<1] = -1; } else { if (debug & DEBUG_HFCMULTI_MODE) printk(KERN_DEBUG "%s: we are not owner of this tx slot " "anymore, channel %d is.\n", __func__, hc->slot_owner[oslot_tx<<1]); } } if (oslot_rx >= 0 && slot_rx != oslot_rx) { /* remove from slot */ if (debug & DEBUG_HFCMULTI_MODE) printk(KERN_DEBUG "%s: remove from slot %d (RX)\n", __func__, oslot_rx); if (hc->slot_owner[(oslot_rx << 1) | 1] == ch) { HFC_outb(hc, R_SLOT, (oslot_rx << 1) | V_SL_DIR); HFC_outb(hc, A_SL_CFG, 0); hc->slot_owner[(oslot_rx << 1) | 1] = -1; } else { if (debug & DEBUG_HFCMULTI_MODE) printk(KERN_DEBUG "%s: we are not owner of this rx slot " "anymore, channel %d is.\n", __func__, hc->slot_owner[(oslot_rx << 1) | 1]); } } if (slot_tx < 0) { flow_tx = 0x80; /* FIFO->ST */ /* disable pcm slot */ hc->chan[ch].slot_tx = -1; hc->chan[ch].bank_tx = 0; } else { /* set pcm slot */ if (hc->chan[ch].txpending) flow_tx = 0x80; /* FIFO->ST */ else flow_tx = 0xc0; /* PCM->ST */ /* put on slot */ routing = bank_tx ? 0xc0 : 0x80; if (conf >= 0 || bank_tx > 1) routing = 0x40; /* loop */ if (debug & DEBUG_HFCMULTI_MODE) printk(KERN_DEBUG "%s: put channel %d to slot %d bank" " %d flow %02x routing %02x conf %d (TX)\n", __func__, ch, slot_tx, bank_tx, flow_tx, routing, conf); HFC_outb(hc, R_SLOT, slot_tx << 1); HFC_outb(hc, A_SL_CFG, (ch<<1) | routing); HFC_outb(hc, A_CONF, (conf < 0) ? 0 : (conf | V_CONF_SL)); hc->slot_owner[slot_tx << 1] = ch; hc->chan[ch].slot_tx = slot_tx; hc->chan[ch].bank_tx = bank_tx; } if (slot_rx < 0) { /* disable pcm slot */ flow_rx = 0x80; /* ST->FIFO */ hc->chan[ch].slot_rx = -1; hc->chan[ch].bank_rx = 0; } else { /* set pcm slot */ if (hc->chan[ch].txpending) flow_rx = 0x80; /* ST->FIFO */ else flow_rx = 0xc0; /* ST->(FIFO,PCM) */ /* put on slot */ routing = bank_rx?0x80:0xc0; /* reversed */ if (conf >= 0 || bank_rx > 1) routing = 0x40; /* loop */ if (debug & DEBUG_HFCMULTI_MODE) printk(KERN_DEBUG "%s: put channel %d to slot %d bank" " %d flow %02x routing %02x conf %d (RX)\n", __func__, ch, slot_rx, bank_rx, flow_rx, routing, conf); HFC_outb(hc, R_SLOT, (slot_rx<<1) | V_SL_DIR); HFC_outb(hc, A_SL_CFG, (ch<<1) | V_CH_DIR | routing); hc->slot_owner[(slot_rx<<1)|1] = ch; hc->chan[ch].slot_rx = slot_rx; hc->chan[ch].bank_rx = bank_rx; } switch (protocol) { case (ISDN_P_NONE): /* disable TX fifo */ HFC_outb(hc, R_FIFO, ch << 1); HFC_wait(hc); HFC_outb(hc, A_CON_HDLC, flow_tx | 0x00 | V_IFF); HFC_outb(hc, A_SUBCH_CFG, 0); HFC_outb(hc, A_IRQ_MSK, 0); HFC_outb(hc, R_INC_RES_FIFO, V_RES_F); HFC_wait(hc); /* disable RX fifo */ HFC_outb(hc, R_FIFO, (ch<<1)|1); HFC_wait(hc); HFC_outb(hc, A_CON_HDLC, flow_rx | 0x00); HFC_outb(hc, A_SUBCH_CFG, 0); HFC_outb(hc, A_IRQ_MSK, 0); HFC_outb(hc, R_INC_RES_FIFO, V_RES_F); HFC_wait(hc); if (hc->chan[ch].bch && hc->type != 1) { hc->hw.a_st_ctrl0[hc->chan[ch].port] &= ((ch & 0x3) == 0)? ~V_B1_EN: ~V_B2_EN; HFC_outb(hc, R_ST_SEL, hc->chan[ch].port); /* undocumented: delay after R_ST_SEL */ udelay(1); HFC_outb(hc, A_ST_CTRL0, hc->hw.a_st_ctrl0[hc->chan[ch].port]); } if (hc->chan[ch].bch) { test_and_clear_bit(FLG_HDLC, &hc->chan[ch].bch->Flags); test_and_clear_bit(FLG_TRANSPARENT, &hc->chan[ch].bch->Flags); } break; case (ISDN_P_B_RAW): /* B-channel */ if (test_bit(HFC_CHIP_B410P, &hc->chip) && (hc->chan[ch].slot_rx < 0) && (hc->chan[ch].slot_tx < 0)) { printk(KERN_DEBUG "Setting B-channel %d to echo cancelable " "state on PCM slot %d\n", ch, ((ch / 4) * 8) + ((ch % 4) * 4) + 1); printk(KERN_DEBUG "Enabling pass through for channel\n"); vpm_out(hc, ch, ((ch / 4) * 8) + ((ch % 4) * 4) + 1, 0x01); /* rx path */ /* S/T -> PCM */ HFC_outb(hc, R_FIFO, (ch << 1)); HFC_wait(hc); HFC_outb(hc, A_CON_HDLC, 0xc0 | V_HDLC_TRP | V_IFF); HFC_outb(hc, R_SLOT, (((ch / 4) * 8) + ((ch % 4) * 4) + 1) << 1); HFC_outb(hc, A_SL_CFG, 0x80 | (ch << 1)); /* PCM -> FIFO */ HFC_outb(hc, R_FIFO, 0x20 | (ch << 1) | 1); HFC_wait(hc); HFC_outb(hc, A_CON_HDLC, 0x20 | V_HDLC_TRP | V_IFF); HFC_outb(hc, A_SUBCH_CFG, 0); HFC_outb(hc, A_IRQ_MSK, 0); HFC_outb(hc, R_INC_RES_FIFO, V_RES_F); HFC_wait(hc); HFC_outb(hc, R_SLOT, ((((ch / 4) * 8) + ((ch % 4) * 4) + 1) << 1) | 1); HFC_outb(hc, A_SL_CFG, 0x80 | 0x20 | (ch << 1) | 1); /* tx path */ /* PCM -> S/T */ HFC_outb(hc, R_FIFO, (ch << 1) | 1); HFC_wait(hc); HFC_outb(hc, A_CON_HDLC, 0xc0 | V_HDLC_TRP | V_IFF); HFC_outb(hc, R_SLOT, ((((ch / 4) * 8) + ((ch % 4) * 4)) << 1) | 1); HFC_outb(hc, A_SL_CFG, 0x80 | 0x40 | (ch << 1) | 1); /* FIFO -> PCM */ HFC_outb(hc, R_FIFO, 0x20 | (ch << 1)); HFC_wait(hc); HFC_outb(hc, A_CON_HDLC, 0x20 | V_HDLC_TRP | V_IFF); HFC_outb(hc, A_SUBCH_CFG, 0); HFC_outb(hc, A_IRQ_MSK, 0); HFC_outb(hc, R_INC_RES_FIFO, V_RES_F); HFC_wait(hc); /* tx silence */ HFC_outb_nodebug(hc, A_FIFO_DATA0_NOINC, hc->silence); HFC_outb(hc, R_SLOT, (((ch / 4) * 8) + ((ch % 4) * 4)) << 1); HFC_outb(hc, A_SL_CFG, 0x80 | 0x20 | (ch << 1)); } else { /* enable TX fifo */ HFC_outb(hc, R_FIFO, ch << 1); HFC_wait(hc); HFC_outb(hc, A_CON_HDLC, flow_tx | 0x00 | V_HDLC_TRP | V_IFF); HFC_outb(hc, A_SUBCH_CFG, 0); HFC_outb(hc, A_IRQ_MSK, 0); HFC_outb(hc, R_INC_RES_FIFO, V_RES_F); HFC_wait(hc); /* tx silence */ HFC_outb_nodebug(hc, A_FIFO_DATA0_NOINC, hc->silence); /* enable RX fifo */ HFC_outb(hc, R_FIFO, (ch<<1)|1); HFC_wait(hc); HFC_outb(hc, A_CON_HDLC, flow_rx | 0x00 | V_HDLC_TRP); HFC_outb(hc, A_SUBCH_CFG, 0); HFC_outb(hc, A_IRQ_MSK, 0); HFC_outb(hc, R_INC_RES_FIFO, V_RES_F); HFC_wait(hc); } if (hc->type != 1) { hc->hw.a_st_ctrl0[hc->chan[ch].port] |= ((ch & 0x3) == 0) ? V_B1_EN : V_B2_EN; HFC_outb(hc, R_ST_SEL, hc->chan[ch].port); /* undocumented: delay after R_ST_SEL */ udelay(1); HFC_outb(hc, A_ST_CTRL0, hc->hw.a_st_ctrl0[hc->chan[ch].port]); } if (hc->chan[ch].bch) test_and_set_bit(FLG_TRANSPARENT, &hc->chan[ch].bch->Flags); break; case (ISDN_P_B_HDLC): /* B-channel */ case (ISDN_P_TE_S0): /* D-channel */ case (ISDN_P_NT_S0): case (ISDN_P_TE_E1): case (ISDN_P_NT_E1): /* enable TX fifo */ HFC_outb(hc, R_FIFO, ch<<1); HFC_wait(hc); if (hc->type == 1 || hc->chan[ch].bch) { /* E1 or B-channel */ HFC_outb(hc, A_CON_HDLC, flow_tx | 0x04); HFC_outb(hc, A_SUBCH_CFG, 0); } else { /* D-Channel without HDLC fill flags */ HFC_outb(hc, A_CON_HDLC, flow_tx | 0x04 | V_IFF); HFC_outb(hc, A_SUBCH_CFG, 2); } HFC_outb(hc, A_IRQ_MSK, V_IRQ); HFC_outb(hc, R_INC_RES_FIFO, V_RES_F); HFC_wait(hc); /* enable RX fifo */ HFC_outb(hc, R_FIFO, (ch<<1)|1); HFC_wait(hc); HFC_outb(hc, A_CON_HDLC, flow_rx | 0x04); if (hc->type == 1 || hc->chan[ch].bch) HFC_outb(hc, A_SUBCH_CFG, 0); /* full 8 bits */ else HFC_outb(hc, A_SUBCH_CFG, 2); /* 2 bits dchannel */ HFC_outb(hc, A_IRQ_MSK, V_IRQ); HFC_outb(hc, R_INC_RES_FIFO, V_RES_F); HFC_wait(hc); if (hc->chan[ch].bch) { test_and_set_bit(FLG_HDLC, &hc->chan[ch].bch->Flags); if (hc->type != 1) { hc->hw.a_st_ctrl0[hc->chan[ch].port] |= ((ch&0x3) == 0) ? V_B1_EN : V_B2_EN; HFC_outb(hc, R_ST_SEL, hc->chan[ch].port); /* undocumented: delay after R_ST_SEL */ udelay(1); HFC_outb(hc, A_ST_CTRL0, hc->hw.a_st_ctrl0[hc->chan[ch].port]); } } break; default: printk(KERN_DEBUG "%s: protocol not known %x\n", __func__, protocol); hc->chan[ch].protocol = ISDN_P_NONE; return -ENOPROTOOPT; } hc->chan[ch].protocol = protocol; return 0; } /* * connect/disconnect PCM */ static void hfcmulti_pcm(struct hfc_multi *hc, int ch, int slot_tx, int bank_tx, int slot_rx, int bank_rx) { if (slot_rx < 0 || slot_rx < 0 || bank_tx < 0 || bank_rx < 0) { /* disable PCM */ mode_hfcmulti(hc, ch, hc->chan[ch].protocol, -1, 0, -1, 0); return; } /* enable pcm */ mode_hfcmulti(hc, ch, hc->chan[ch].protocol, slot_tx, bank_tx, slot_rx, bank_rx); } /* * set/disable conference */ static void hfcmulti_conf(struct hfc_multi *hc, int ch, int num) { if (num >= 0 && num <= 7) hc->chan[ch].conf = num; else hc->chan[ch].conf = -1; mode_hfcmulti(hc, ch, hc->chan[ch].protocol, hc->chan[ch].slot_tx, hc->chan[ch].bank_tx, hc->chan[ch].slot_rx, hc->chan[ch].bank_rx); } /* * set/disable sample loop */ /* NOTE: this function is experimental and therefore disabled */ /* * Layer 1 callback function */ static int hfcm_l1callback(struct dchannel *dch, u_int cmd) { struct hfc_multi *hc = dch->hw; u_long flags; switch (cmd) { case INFO3_P8: case INFO3_P10: break; case HW_RESET_REQ: /* start activation */ spin_lock_irqsave(&hc->lock, flags); if (hc->type == 1) { if (debug & DEBUG_HFCMULTI_MSG) printk(KERN_DEBUG "%s: HW_RESET_REQ no BRI\n", __func__); } else { HFC_outb(hc, R_ST_SEL, hc->chan[dch->slot].port); /* undocumented: delay after R_ST_SEL */ udelay(1); HFC_outb(hc, A_ST_WR_STATE, V_ST_LD_STA | 3); /* F3 */ udelay(6); /* wait at least 5,21us */ HFC_outb(hc, A_ST_WR_STATE, 3); HFC_outb(hc, A_ST_WR_STATE, 3 | (V_ST_ACT*3)); /* activate */ } spin_unlock_irqrestore(&hc->lock, flags); l1_event(dch->l1, HW_POWERUP_IND); break; case HW_DEACT_REQ: /* start deactivation */ spin_lock_irqsave(&hc->lock, flags); if (hc->type == 1) { if (debug & DEBUG_HFCMULTI_MSG) printk(KERN_DEBUG "%s: HW_DEACT_REQ no BRI\n", __func__); } else { HFC_outb(hc, R_ST_SEL, hc->chan[dch->slot].port); /* undocumented: delay after R_ST_SEL */ udelay(1); HFC_outb(hc, A_ST_WR_STATE, V_ST_ACT*2); /* deactivate */ if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { hc->syncronized &= ~(1 << hc->chan[dch->slot].port); plxsd_checksync(hc, 0); } } skb_queue_purge(&dch->squeue); if (dch->tx_skb) { dev_kfree_skb(dch->tx_skb); dch->tx_skb = NULL; } dch->tx_idx = 0; if (dch->rx_skb) { dev_kfree_skb(dch->rx_skb); dch->rx_skb = NULL; } test_and_clear_bit(FLG_TX_BUSY, &dch->Flags); if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags)) del_timer(&dch->timer); spin_unlock_irqrestore(&hc->lock, flags); break; case HW_POWERUP_REQ: spin_lock_irqsave(&hc->lock, flags); if (hc->type == 1) { if (debug & DEBUG_HFCMULTI_MSG) printk(KERN_DEBUG "%s: HW_POWERUP_REQ no BRI\n", __func__); } else { HFC_outb(hc, R_ST_SEL, hc->chan[dch->slot].port); /* undocumented: delay after R_ST_SEL */ udelay(1); HFC_outb(hc, A_ST_WR_STATE, 3 | 0x10); /* activate */ udelay(6); /* wait at least 5,21us */ HFC_outb(hc, A_ST_WR_STATE, 3); /* activate */ } spin_unlock_irqrestore(&hc->lock, flags); break; case PH_ACTIVATE_IND: test_and_set_bit(FLG_ACTIVE, &dch->Flags); _queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL, GFP_ATOMIC); break; case PH_DEACTIVATE_IND: test_and_clear_bit(FLG_ACTIVE, &dch->Flags); _queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL, GFP_ATOMIC); break; default: if (dch->debug & DEBUG_HW) printk(KERN_DEBUG "%s: unknown command %x\n", __func__, cmd); return -1; } return 0; } /* * Layer2 -> Layer 1 Transfer */ static int handle_dmsg(struct mISDNchannel *ch, struct sk_buff *skb) { struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D); struct dchannel *dch = container_of(dev, struct dchannel, dev); struct hfc_multi *hc = dch->hw; struct mISDNhead *hh = mISDN_HEAD_P(skb); int ret = -EINVAL; unsigned int id; u_long flags; switch (hh->prim) { case PH_DATA_REQ: if (skb->len < 1) break; spin_lock_irqsave(&hc->lock, flags); ret = dchannel_senddata(dch, skb); if (ret > 0) { /* direct TX */ id = hh->id; /* skb can be freed */ hfcmulti_tx(hc, dch->slot); ret = 0; /* start fifo */ HFC_outb(hc, R_FIFO, 0); HFC_wait(hc); spin_unlock_irqrestore(&hc->lock, flags); queue_ch_frame(ch, PH_DATA_CNF, id, NULL); } else spin_unlock_irqrestore(&hc->lock, flags); return ret; case PH_ACTIVATE_REQ: if (dch->dev.D.protocol != ISDN_P_TE_S0) { spin_lock_irqsave(&hc->lock, flags); ret = 0; if (debug & DEBUG_HFCMULTI_MSG) printk(KERN_DEBUG "%s: PH_ACTIVATE port %d (0..%d)\n", __func__, hc->chan[dch->slot].port, hc->ports-1); /* start activation */ if (hc->type == 1) { ph_state_change(dch); if (debug & DEBUG_HFCMULTI_STATE) printk(KERN_DEBUG "%s: E1 report state %x \n", __func__, dch->state); } else { HFC_outb(hc, R_ST_SEL, hc->chan[dch->slot].port); /* undocumented: delay after R_ST_SEL */ udelay(1); HFC_outb(hc, A_ST_WR_STATE, V_ST_LD_STA | 1); /* G1 */ udelay(6); /* wait at least 5,21us */ HFC_outb(hc, A_ST_WR_STATE, 1); HFC_outb(hc, A_ST_WR_STATE, 1 | (V_ST_ACT*3)); /* activate */ dch->state = 1; } spin_unlock_irqrestore(&hc->lock, flags); } else ret = l1_event(dch->l1, hh->prim); break; case PH_DEACTIVATE_REQ: test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags); if (dch->dev.D.protocol != ISDN_P_TE_S0) { spin_lock_irqsave(&hc->lock, flags); if (debug & DEBUG_HFCMULTI_MSG) printk(KERN_DEBUG "%s: PH_DEACTIVATE port %d (0..%d)\n", __func__, hc->chan[dch->slot].port, hc->ports-1); /* start deactivation */ if (hc->type == 1) { if (debug & DEBUG_HFCMULTI_MSG) printk(KERN_DEBUG "%s: PH_DEACTIVATE no BRI\n", __func__); } else { HFC_outb(hc, R_ST_SEL, hc->chan[dch->slot].port); /* undocumented: delay after R_ST_SEL */ udelay(1); HFC_outb(hc, A_ST_WR_STATE, V_ST_ACT * 2); /* deactivate */ dch->state = 1; } skb_queue_purge(&dch->squeue); if (dch->tx_skb) { dev_kfree_skb(dch->tx_skb); dch->tx_skb = NULL; } dch->tx_idx = 0; if (dch->rx_skb) { dev_kfree_skb(dch->rx_skb); dch->rx_skb = NULL; } test_and_clear_bit(FLG_TX_BUSY, &dch->Flags); if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags)) del_timer(&dch->timer); #ifdef FIXME if (test_and_clear_bit(FLG_L1_BUSY, &dch->Flags)) dchannel_sched_event(&hc->dch, D_CLEARBUSY); #endif ret = 0; spin_unlock_irqrestore(&hc->lock, flags); } else ret = l1_event(dch->l1, hh->prim); break; } if (!ret) dev_kfree_skb(skb); return ret; } static void deactivate_bchannel(struct bchannel *bch) { struct hfc_multi *hc = bch->hw; u_long flags; spin_lock_irqsave(&hc->lock, flags); if (test_and_clear_bit(FLG_TX_NEXT, &bch->Flags)) { dev_kfree_skb(bch->next_skb); bch->next_skb = NULL; } if (bch->tx_skb) { dev_kfree_skb(bch->tx_skb); bch->tx_skb = NULL; } bch->tx_idx = 0; if (bch->rx_skb) { dev_kfree_skb(bch->rx_skb); bch->rx_skb = NULL; } hc->chan[bch->slot].coeff_count = 0; test_and_clear_bit(FLG_ACTIVE, &bch->Flags); test_and_clear_bit(FLG_TX_BUSY, &bch->Flags); hc->chan[bch->slot].rx_off = 0; hc->chan[bch->slot].conf = -1; mode_hfcmulti(hc, bch->slot, ISDN_P_NONE, -1, 0, -1, 0); spin_unlock_irqrestore(&hc->lock, flags); } static int handle_bmsg(struct mISDNchannel *ch, struct sk_buff *skb) { struct bchannel *bch = container_of(ch, struct bchannel, ch); struct hfc_multi *hc = bch->hw; int ret = -EINVAL; struct mISDNhead *hh = mISDN_HEAD_P(skb); unsigned int id; u_long flags; switch (hh->prim) { case PH_DATA_REQ: if (!skb->len) break; spin_lock_irqsave(&hc->lock, flags); ret = bchannel_senddata(bch, skb); if (ret > 0) { /* direct TX */ id = hh->id; /* skb can be freed */ hfcmulti_tx(hc, bch->slot); ret = 0; /* start fifo */ HFC_outb_nodebug(hc, R_FIFO, 0); HFC_wait_nodebug(hc); if (!test_bit(FLG_TRANSPARENT, &bch->Flags)) { spin_unlock_irqrestore(&hc->lock, flags); queue_ch_frame(ch, PH_DATA_CNF, id, NULL); } else spin_unlock_irqrestore(&hc->lock, flags); } else spin_unlock_irqrestore(&hc->lock, flags); return ret; case PH_ACTIVATE_REQ: if (debug & DEBUG_HFCMULTI_MSG) printk(KERN_DEBUG "%s: PH_ACTIVATE ch %d (0..32)\n", __func__, bch->slot); spin_lock_irqsave(&hc->lock, flags); /* activate B-channel if not already activated */ if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags)) { hc->chan[bch->slot].txpending = 0; ret = mode_hfcmulti(hc, bch->slot, ch->protocol, hc->chan[bch->slot].slot_tx, hc->chan[bch->slot].bank_tx, hc->chan[bch->slot].slot_rx, hc->chan[bch->slot].bank_rx); if (!ret) { if (ch->protocol == ISDN_P_B_RAW && !hc->dtmf && test_bit(HFC_CHIP_DTMF, &hc->chip)) { /* start decoder */ hc->dtmf = 1; if (debug & DEBUG_HFCMULTI_DTMF) printk(KERN_DEBUG "%s: start dtmf decoder\n", __func__); HFC_outb(hc, R_DTMF, hc->hw.r_dtmf | V_RST_DTMF); } } } else ret = 0; spin_unlock_irqrestore(&hc->lock, flags); if (!ret) _queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0, NULL, GFP_KERNEL); break; case PH_CONTROL_REQ: spin_lock_irqsave(&hc->lock, flags); switch (hh->id) { case HFC_SPL_LOOP_ON: /* set sample loop */ if (debug & DEBUG_HFCMULTI_MSG) printk(KERN_DEBUG "%s: HFC_SPL_LOOP_ON (len = %d)\n", __func__, skb->len); ret = 0; break; case HFC_SPL_LOOP_OFF: /* set silence */ if (debug & DEBUG_HFCMULTI_MSG) printk(KERN_DEBUG "%s: HFC_SPL_LOOP_OFF\n", __func__); ret = 0; break; default: printk(KERN_ERR "%s: unknown PH_CONTROL_REQ info %x\n", __func__, hh->id); ret = -EINVAL; } spin_unlock_irqrestore(&hc->lock, flags); break; case PH_DEACTIVATE_REQ: deactivate_bchannel(bch); /* locked there */ _queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0, NULL, GFP_KERNEL); ret = 0; break; } if (!ret) dev_kfree_skb(skb); return ret; } /* * bchannel control function */ static int channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq) { int ret = 0; struct dsp_features *features = (struct dsp_features *)(*((u_long *)&cq->p1)); struct hfc_multi *hc = bch->hw; int slot_tx; int bank_tx; int slot_rx; int bank_rx; int num; switch (cq->op) { case MISDN_CTRL_GETOP: cq->op = MISDN_CTRL_HFC_OP | MISDN_CTRL_HW_FEATURES_OP | MISDN_CTRL_RX_OFF | MISDN_CTRL_FILL_EMPTY; break; case MISDN_CTRL_RX_OFF: /* turn off / on rx stream */ hc->chan[bch->slot].rx_off = !!cq->p1; if (!hc->chan[bch->slot].rx_off) { /* reset fifo on rx on */ HFC_outb_nodebug(hc, R_FIFO, (bch->slot << 1) | 1); HFC_wait_nodebug(hc); HFC_outb_nodebug(hc, R_INC_RES_FIFO, V_RES_F); HFC_wait_nodebug(hc); } if (debug & DEBUG_HFCMULTI_MSG) printk(KERN_DEBUG "%s: RX_OFF request (nr=%d off=%d)\n", __func__, bch->nr, hc->chan[bch->slot].rx_off); break; case MISDN_CTRL_FILL_EMPTY: /* fill fifo, if empty */ test_and_set_bit(FLG_FILLEMPTY, &bch->Flags); if (debug & DEBUG_HFCMULTI_MSG) printk(KERN_DEBUG "%s: FILL_EMPTY request (nr=%d " "off=%d)\n", __func__, bch->nr, !!cq->p1); break; case MISDN_CTRL_HW_FEATURES: /* fill features structure */ if (debug & DEBUG_HFCMULTI_MSG) printk(KERN_DEBUG "%s: HW_FEATURE request\n", __func__); /* create confirm */ features->hfc_id = hc->id; if (test_bit(HFC_CHIP_DTMF, &hc->chip)) features->hfc_dtmf = 1; features->hfc_loops = 0; if (test_bit(HFC_CHIP_B410P, &hc->chip)) { features->hfc_echocanhw = 1; } else { features->pcm_id = hc->pcm; features->pcm_slots = hc->slots; features->pcm_banks = 2; } break; case MISDN_CTRL_HFC_PCM_CONN: /* connect to pcm timeslot (0..N) */ slot_tx = cq->p1 & 0xff; bank_tx = cq->p1 >> 8; slot_rx = cq->p2 & 0xff; bank_rx = cq->p2 >> 8; if (debug & DEBUG_HFCMULTI_MSG) printk(KERN_DEBUG "%s: HFC_PCM_CONN slot %d bank %d (TX) " "slot %d bank %d (RX)\n", __func__, slot_tx, bank_tx, slot_rx, bank_rx); if (slot_tx < hc->slots && bank_tx <= 2 && slot_rx < hc->slots && bank_rx <= 2) hfcmulti_pcm(hc, bch->slot, slot_tx, bank_tx, slot_rx, bank_rx); else { printk(KERN_WARNING "%s: HFC_PCM_CONN slot %d bank %d (TX) " "slot %d bank %d (RX) out of range\n", __func__, slot_tx, bank_tx, slot_rx, bank_rx); ret = -EINVAL; } break; case MISDN_CTRL_HFC_PCM_DISC: /* release interface from pcm timeslot */ if (debug & DEBUG_HFCMULTI_MSG) printk(KERN_DEBUG "%s: HFC_PCM_DISC\n", __func__); hfcmulti_pcm(hc, bch->slot, -1, 0, -1, 0); break; case MISDN_CTRL_HFC_CONF_JOIN: /* join conference (0..7) */ num = cq->p1 & 0xff; if (debug & DEBUG_HFCMULTI_MSG) printk(KERN_DEBUG "%s: HFC_CONF_JOIN conf %d\n", __func__, num); if (num <= 7) hfcmulti_conf(hc, bch->slot, num); else { printk(KERN_WARNING "%s: HW_CONF_JOIN conf %d out of range\n", __func__, num); ret = -EINVAL; } break; case MISDN_CTRL_HFC_CONF_SPLIT: /* split conference */ if (debug & DEBUG_HFCMULTI_MSG) printk(KERN_DEBUG "%s: HFC_CONF_SPLIT\n", __func__); hfcmulti_conf(hc, bch->slot, -1); break; case MISDN_CTRL_HFC_ECHOCAN_ON: if (debug & DEBUG_HFCMULTI_MSG) printk(KERN_DEBUG "%s: HFC_ECHOCAN_ON\n", __func__); if (test_bit(HFC_CHIP_B410P, &hc->chip)) vpm_echocan_on(hc, bch->slot, cq->p1); else ret = -EINVAL; break; case MISDN_CTRL_HFC_ECHOCAN_OFF: if (debug & DEBUG_HFCMULTI_MSG) printk(KERN_DEBUG "%s: HFC_ECHOCAN_OFF\n", __func__); if (test_bit(HFC_CHIP_B410P, &hc->chip)) vpm_echocan_off(hc, bch->slot); else ret = -EINVAL; break; default: printk(KERN_WARNING "%s: unknown Op %x\n", __func__, cq->op); ret = -EINVAL; break; } return ret; } static int hfcm_bctrl(struct mISDNchannel *ch, u_int cmd, void *arg) { struct bchannel *bch = container_of(ch, struct bchannel, ch); struct hfc_multi *hc = bch->hw; int err = -EINVAL; u_long flags; if (bch->debug & DEBUG_HW) printk(KERN_DEBUG "%s: cmd:%x %p\n", __func__, cmd, arg); switch (cmd) { case CLOSE_CHANNEL: test_and_clear_bit(FLG_OPEN, &bch->Flags); if (test_bit(FLG_ACTIVE, &bch->Flags)) deactivate_bchannel(bch); /* locked there */ ch->protocol = ISDN_P_NONE; ch->peer = NULL; module_put(THIS_MODULE); err = 0; break; case CONTROL_CHANNEL: spin_lock_irqsave(&hc->lock, flags); err = channel_bctrl(bch, arg); spin_unlock_irqrestore(&hc->lock, flags); break; default: printk(KERN_WARNING "%s: unknown prim(%x)\n", __func__, cmd); } return err; } /* * handle D-channel events * * handle state change event */ static void ph_state_change(struct dchannel *dch) { struct hfc_multi *hc; int ch, i; if (!dch) { printk(KERN_WARNING "%s: ERROR given dch is NULL\n", __func__); return; } hc = dch->hw; ch = dch->slot; if (hc->type == 1) { if (dch->dev.D.protocol == ISDN_P_TE_E1) { if (debug & DEBUG_HFCMULTI_STATE) printk(KERN_DEBUG "%s: E1 TE (id=%d) newstate %x\n", __func__, hc->id, dch->state); } else { if (debug & DEBUG_HFCMULTI_STATE) printk(KERN_DEBUG "%s: E1 NT (id=%d) newstate %x\n", __func__, hc->id, dch->state); } switch (dch->state) { case (1): if (hc->e1_state != 1) { for (i = 1; i <= 31; i++) { /* reset fifos on e1 activation */ HFC_outb_nodebug(hc, R_FIFO, (i << 1) | 1); HFC_wait_nodebug(hc); HFC_outb_nodebug(hc, R_INC_RES_FIFO, V_RES_F); HFC_wait_nodebug(hc); } } test_and_set_bit(FLG_ACTIVE, &dch->Flags); _queue_data(&dch->dev.D, PH_ACTIVATE_IND, MISDN_ID_ANY, 0, NULL, GFP_ATOMIC); break; default: if (hc->e1_state != 1) return; test_and_clear_bit(FLG_ACTIVE, &dch->Flags); _queue_data(&dch->dev.D, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0, NULL, GFP_ATOMIC); } hc->e1_state = dch->state; } else { if (dch->dev.D.protocol == ISDN_P_TE_S0) { if (debug & DEBUG_HFCMULTI_STATE) printk(KERN_DEBUG "%s: S/T TE newstate %x\n", __func__, dch->state); switch (dch->state) { case (0): l1_event(dch->l1, HW_RESET_IND); break; case (3): l1_event(dch->l1, HW_DEACT_IND); break; case (5): case (8): l1_event(dch->l1, ANYSIGNAL); break; case (6): l1_event(dch->l1, INFO2); break; case (7): l1_event(dch->l1, INFO4_P8); break; } } else { if (debug & DEBUG_HFCMULTI_STATE) printk(KERN_DEBUG "%s: S/T NT newstate %x\n", __func__, dch->state); switch (dch->state) { case (2): if (hc->chan[ch].nt_timer == 0) { hc->chan[ch].nt_timer = -1; HFC_outb(hc, R_ST_SEL, hc->chan[ch].port); /* undocumented: delay after R_ST_SEL */ udelay(1); HFC_outb(hc, A_ST_WR_STATE, 4 | V_ST_LD_STA); /* G4 */ udelay(6); /* wait at least 5,21us */ HFC_outb(hc, A_ST_WR_STATE, 4); dch->state = 4; } else { /* one extra count for the next event */ hc->chan[ch].nt_timer = nt_t1_count[poll_timer] + 1; HFC_outb(hc, R_ST_SEL, hc->chan[ch].port); /* undocumented: delay after R_ST_SEL */ udelay(1); /* allow G2 -> G3 transition */ HFC_outb(hc, A_ST_WR_STATE, 2 | V_SET_G2_G3); } break; case (1): hc->chan[ch].nt_timer = -1; test_and_clear_bit(FLG_ACTIVE, &dch->Flags); _queue_data(&dch->dev.D, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0, NULL, GFP_ATOMIC); break; case (4): hc->chan[ch].nt_timer = -1; break; case (3): hc->chan[ch].nt_timer = -1; test_and_set_bit(FLG_ACTIVE, &dch->Flags); _queue_data(&dch->dev.D, PH_ACTIVATE_IND, MISDN_ID_ANY, 0, NULL, GFP_ATOMIC); break; } } } } /* * called for card mode init message */ static void hfcmulti_initmode(struct dchannel *dch) { struct hfc_multi *hc = dch->hw; u_char a_st_wr_state, r_e1_wr_sta; int i, pt; if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: entered\n", __func__); if (hc->type == 1) { hc->chan[hc->dslot].slot_tx = -1; hc->chan[hc->dslot].slot_rx = -1; hc->chan[hc->dslot].conf = -1; if (hc->dslot) { mode_hfcmulti(hc, hc->dslot, dch->dev.D.protocol, -1, 0, -1, 0); dch->timer.function = (void *) hfcmulti_dbusy_timer; dch->timer.data = (long) dch; init_timer(&dch->timer); } for (i = 1; i <= 31; i++) { if (i == hc->dslot) continue; hc->chan[i].slot_tx = -1; hc->chan[i].slot_rx = -1; hc->chan[i].conf = -1; mode_hfcmulti(hc, i, ISDN_P_NONE, -1, 0, -1, 0); } /* E1 */ if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dslot].cfg)) { HFC_outb(hc, R_LOS0, 255); /* 2 ms */ HFC_outb(hc, R_LOS1, 255); /* 512 ms */ } if (test_bit(HFC_CFG_OPTICAL, &hc->chan[hc->dslot].cfg)) { HFC_outb(hc, R_RX0, 0); hc->hw.r_tx0 = 0 | V_OUT_EN; } else { HFC_outb(hc, R_RX0, 1); hc->hw.r_tx0 = 1 | V_OUT_EN; } hc->hw.r_tx1 = V_ATX | V_NTRI; HFC_outb(hc, R_TX0, hc->hw.r_tx0); HFC_outb(hc, R_TX1, hc->hw.r_tx1); HFC_outb(hc, R_TX_FR0, 0x00); HFC_outb(hc, R_TX_FR1, 0xf8); if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dslot].cfg)) HFC_outb(hc, R_TX_FR2, V_TX_MF | V_TX_E | V_NEG_E); HFC_outb(hc, R_RX_FR0, V_AUTO_RESYNC | V_AUTO_RECO | 0); if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dslot].cfg)) HFC_outb(hc, R_RX_FR1, V_RX_MF | V_RX_MF_SYNC); if (dch->dev.D.protocol == ISDN_P_NT_E1) { if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: E1 port is NT-mode\n", __func__); r_e1_wr_sta = 0; /* G0 */ hc->e1_getclock = 0; } else { if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: E1 port is TE-mode\n", __func__); r_e1_wr_sta = 0; /* F0 */ hc->e1_getclock = 1; } if (test_bit(HFC_CHIP_RX_SYNC, &hc->chip)) HFC_outb(hc, R_SYNC_OUT, V_SYNC_E1_RX); else HFC_outb(hc, R_SYNC_OUT, 0); if (test_bit(HFC_CHIP_E1CLOCK_GET, &hc->chip)) hc->e1_getclock = 1; if (test_bit(HFC_CHIP_E1CLOCK_PUT, &hc->chip)) hc->e1_getclock = 0; if (test_bit(HFC_CHIP_PCM_SLAVE, &hc->chip)) { /* SLAVE (clock master) */ if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: E1 port is clock master " "(clock from PCM)\n", __func__); HFC_outb(hc, R_SYNC_CTRL, V_EXT_CLK_SYNC | V_PCM_SYNC); } else { if (hc->e1_getclock) { /* MASTER (clock slave) */ if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: E1 port is clock slave " "(clock to PCM)\n", __func__); HFC_outb(hc, R_SYNC_CTRL, V_SYNC_OFFS); } else { /* MASTER (clock master) */ if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: E1 port is " "clock master " "(clock from QUARTZ)\n", __func__); HFC_outb(hc, R_SYNC_CTRL, V_EXT_CLK_SYNC | V_PCM_SYNC | V_JATT_OFF); HFC_outb(hc, R_SYNC_OUT, 0); } } HFC_outb(hc, R_JATT_ATT, 0x9c); /* undoc register */ HFC_outb(hc, R_PWM_MD, V_PWM0_MD); HFC_outb(hc, R_PWM0, 0x50); HFC_outb(hc, R_PWM1, 0xff); /* state machine setup */ HFC_outb(hc, R_E1_WR_STA, r_e1_wr_sta | V_E1_LD_STA); udelay(6); /* wait at least 5,21us */ HFC_outb(hc, R_E1_WR_STA, r_e1_wr_sta); if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { hc->syncronized = 0; plxsd_checksync(hc, 0); } } else { i = dch->slot; hc->chan[i].slot_tx = -1; hc->chan[i].slot_rx = -1; hc->chan[i].conf = -1; mode_hfcmulti(hc, i, dch->dev.D.protocol, -1, 0, -1, 0); dch->timer.function = (void *)hfcmulti_dbusy_timer; dch->timer.data = (long) dch; init_timer(&dch->timer); hc->chan[i - 2].slot_tx = -1; hc->chan[i - 2].slot_rx = -1; hc->chan[i - 2].conf = -1; mode_hfcmulti(hc, i - 2, ISDN_P_NONE, -1, 0, -1, 0); hc->chan[i - 1].slot_tx = -1; hc->chan[i - 1].slot_rx = -1; hc->chan[i - 1].conf = -1; mode_hfcmulti(hc, i - 1, ISDN_P_NONE, -1, 0, -1, 0); /* ST */ pt = hc->chan[i].port; /* select interface */ HFC_outb(hc, R_ST_SEL, pt); /* undocumented: delay after R_ST_SEL */ udelay(1); if (dch->dev.D.protocol == ISDN_P_NT_S0) { if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: ST port %d is NT-mode\n", __func__, pt); /* clock delay */ HFC_outb(hc, A_ST_CLK_DLY, clockdelay_nt); a_st_wr_state = 1; /* G1 */ hc->hw.a_st_ctrl0[pt] = V_ST_MD; } else { if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: ST port %d is TE-mode\n", __func__, pt); /* clock delay */ HFC_outb(hc, A_ST_CLK_DLY, clockdelay_te); a_st_wr_state = 2; /* F2 */ hc->hw.a_st_ctrl0[pt] = 0; } if (!test_bit(HFC_CFG_NONCAP_TX, &hc->chan[i].cfg)) hc->hw.a_st_ctrl0[pt] |= V_TX_LI; /* line setup */ HFC_outb(hc, A_ST_CTRL0, hc->hw.a_st_ctrl0[pt]); /* disable E-channel */ if ((dch->dev.D.protocol == ISDN_P_NT_S0) || test_bit(HFC_CFG_DIS_ECHANNEL, &hc->chan[i].cfg)) HFC_outb(hc, A_ST_CTRL1, V_E_IGNO); else HFC_outb(hc, A_ST_CTRL1, 0); /* enable B-channel receive */ HFC_outb(hc, A_ST_CTRL2, V_B1_RX_EN | V_B2_RX_EN); /* state machine setup */ HFC_outb(hc, A_ST_WR_STATE, a_st_wr_state | V_ST_LD_STA); udelay(6); /* wait at least 5,21us */ HFC_outb(hc, A_ST_WR_STATE, a_st_wr_state); hc->hw.r_sci_msk |= 1 << pt; /* state machine interrupts */ HFC_outb(hc, R_SCI_MSK, hc->hw.r_sci_msk); /* unset sync on port */ if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { hc->syncronized &= ~(1 << hc->chan[dch->slot].port); plxsd_checksync(hc, 0); } } if (debug & DEBUG_HFCMULTI_INIT) printk("%s: done\n", __func__); } static int open_dchannel(struct hfc_multi *hc, struct dchannel *dch, struct channel_req *rq) { int err = 0; u_long flags; if (debug & DEBUG_HW_OPEN) printk(KERN_DEBUG "%s: dev(%d) open from %p\n", __func__, dch->dev.id, __builtin_return_address(0)); if (rq->protocol == ISDN_P_NONE) return -EINVAL; if ((dch->dev.D.protocol != ISDN_P_NONE) && (dch->dev.D.protocol != rq->protocol)) { if (debug & DEBUG_HFCMULTI_MODE) printk(KERN_WARNING "%s: change protocol %x to %x\n", __func__, dch->dev.D.protocol, rq->protocol); } if ((dch->dev.D.protocol == ISDN_P_TE_S0) && (rq->protocol != ISDN_P_TE_S0)) l1_event(dch->l1, CLOSE_CHANNEL); if (dch->dev.D.protocol != rq->protocol) { if (rq->protocol == ISDN_P_TE_S0) { err = create_l1(dch, hfcm_l1callback); if (err) return err; } dch->dev.D.protocol = rq->protocol; spin_lock_irqsave(&hc->lock, flags); hfcmulti_initmode(dch); spin_unlock_irqrestore(&hc->lock, flags); } if (((rq->protocol == ISDN_P_NT_S0) && (dch->state == 3)) || ((rq->protocol == ISDN_P_TE_S0) && (dch->state == 7)) || ((rq->protocol == ISDN_P_NT_E1) && (dch->state == 1)) || ((rq->protocol == ISDN_P_TE_E1) && (dch->state == 1))) { _queue_data(&dch->dev.D, PH_ACTIVATE_IND, MISDN_ID_ANY, 0, NULL, GFP_KERNEL); } rq->ch = &dch->dev.D; if (!try_module_get(THIS_MODULE)) printk(KERN_WARNING "%s:cannot get module\n", __func__); return 0; } static int open_bchannel(struct hfc_multi *hc, struct dchannel *dch, struct channel_req *rq) { struct bchannel *bch; int ch; if (!test_channelmap(rq->adr.channel, dch->dev.channelmap)) return -EINVAL; if (rq->protocol == ISDN_P_NONE) return -EINVAL; if (hc->type == 1) ch = rq->adr.channel; else ch = (rq->adr.channel - 1) + (dch->slot - 2); bch = hc->chan[ch].bch; if (!bch) { printk(KERN_ERR "%s:internal error ch %d has no bch\n", __func__, ch); return -EINVAL; } if (test_and_set_bit(FLG_OPEN, &bch->Flags)) return -EBUSY; /* b-channel can be only open once */ test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags); bch->ch.protocol = rq->protocol; hc->chan[ch].rx_off = 0; rq->ch = &bch->ch; if (!try_module_get(THIS_MODULE)) printk(KERN_WARNING "%s:cannot get module\n", __func__); return 0; } /* * device control function */ static int channel_dctrl(struct dchannel *dch, struct mISDN_ctrl_req *cq) { int ret = 0; switch (cq->op) { case MISDN_CTRL_GETOP: cq->op = 0; break; default: printk(KERN_WARNING "%s: unknown Op %x\n", __func__, cq->op); ret = -EINVAL; break; } return ret; } static int hfcm_dctrl(struct mISDNchannel *ch, u_int cmd, void *arg) { struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D); struct dchannel *dch = container_of(dev, struct dchannel, dev); struct hfc_multi *hc = dch->hw; struct channel_req *rq; int err = 0; u_long flags; if (dch->debug & DEBUG_HW) printk(KERN_DEBUG "%s: cmd:%x %p\n", __func__, cmd, arg); switch (cmd) { case OPEN_CHANNEL: rq = arg; switch (rq->protocol) { case ISDN_P_TE_S0: case ISDN_P_NT_S0: if (hc->type == 1) { err = -EINVAL; break; } err = open_dchannel(hc, dch, rq); /* locked there */ break; case ISDN_P_TE_E1: case ISDN_P_NT_E1: if (hc->type != 1) { err = -EINVAL; break; } err = open_dchannel(hc, dch, rq); /* locked there */ break; default: spin_lock_irqsave(&hc->lock, flags); err = open_bchannel(hc, dch, rq); spin_unlock_irqrestore(&hc->lock, flags); } break; case CLOSE_CHANNEL: if (debug & DEBUG_HW_OPEN) printk(KERN_DEBUG "%s: dev(%d) close from %p\n", __func__, dch->dev.id, __builtin_return_address(0)); module_put(THIS_MODULE); break; case CONTROL_CHANNEL: spin_lock_irqsave(&hc->lock, flags); err = channel_dctrl(dch, arg); spin_unlock_irqrestore(&hc->lock, flags); break; default: if (dch->debug & DEBUG_HW) printk(KERN_DEBUG "%s: unknown command %x\n", __func__, cmd); err = -EINVAL; } return err; } static int clockctl(void *priv, int enable) { struct hfc_multi *hc = priv; hc->iclock_on = enable; return 0; } /* * initialize the card */ /* * start timer irq, wait some time and check if we have interrupts. * if not, reset chip and try again. */ static int init_card(struct hfc_multi *hc) { int err = -EIO; u_long flags; void __iomem *plx_acc; u_long plx_flags; if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: entered\n", __func__); spin_lock_irqsave(&hc->lock, flags); /* set interrupts but leave global interrupt disabled */ hc->hw.r_irq_ctrl = V_FIFO_IRQ; disable_hwirq(hc); spin_unlock_irqrestore(&hc->lock, flags); if (request_irq(hc->pci_dev->irq, hfcmulti_interrupt, IRQF_SHARED, "HFC-multi", hc)) { printk(KERN_WARNING "mISDN: Could not get interrupt %d.\n", hc->pci_dev->irq); return -EIO; } hc->irq = hc->pci_dev->irq; if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { spin_lock_irqsave(&plx_lock, plx_flags); plx_acc = hc->plx_membase + PLX_INTCSR; writew((PLX_INTCSR_PCIINT_ENABLE | PLX_INTCSR_LINTI1_ENABLE), plx_acc); /* enable PCI & LINT1 irq */ spin_unlock_irqrestore(&plx_lock, plx_flags); } if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: IRQ %d count %d\n", __func__, hc->irq, hc->irqcnt); err = init_chip(hc); if (err) goto error; /* * Finally enable IRQ output * this is only allowed, if an IRQ routine is allready * established for this HFC, so don't do that earlier */ spin_lock_irqsave(&hc->lock, flags); enable_hwirq(hc); spin_unlock_irqrestore(&hc->lock, flags); /* printk(KERN_DEBUG "no master irq set!!!\n"); */ set_current_state(TASK_UNINTERRUPTIBLE); schedule_timeout((100*HZ)/1000); /* Timeout 100ms */ /* turn IRQ off until chip is completely initialized */ spin_lock_irqsave(&hc->lock, flags); disable_hwirq(hc); spin_unlock_irqrestore(&hc->lock, flags); if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: IRQ %d count %d\n", __func__, hc->irq, hc->irqcnt); if (hc->irqcnt) { if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: done\n", __func__); return 0; } if (test_bit(HFC_CHIP_PCM_SLAVE, &hc->chip)) { printk(KERN_INFO "ignoring missing interrupts\n"); return 0; } printk(KERN_ERR "HFC PCI: IRQ(%d) getting no interrupts during init.\n", hc->irq); err = -EIO; error: if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { spin_lock_irqsave(&plx_lock, plx_flags); plx_acc = hc->plx_membase + PLX_INTCSR; writew(0x00, plx_acc); /*disable IRQs*/ spin_unlock_irqrestore(&plx_lock, plx_flags); } if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_WARNING "%s: free irq %d\n", __func__, hc->irq); if (hc->irq) { free_irq(hc->irq, hc); hc->irq = 0; } if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: done (err=%d)\n", __func__, err); return err; } /* * find pci device and set it up */ static int setup_pci(struct hfc_multi *hc, struct pci_dev *pdev, const struct pci_device_id *ent) { struct hm_map *m = (struct hm_map *)ent->driver_data; printk(KERN_INFO "HFC-multi: card manufacturer: '%s' card name: '%s' clock: %s\n", m->vendor_name, m->card_name, m->clock2 ? "double" : "normal"); hc->pci_dev = pdev; if (m->clock2) test_and_set_bit(HFC_CHIP_CLOCK2, &hc->chip); if (ent->device == 0xB410) { test_and_set_bit(HFC_CHIP_B410P, &hc->chip); test_and_set_bit(HFC_CHIP_PCM_MASTER, &hc->chip); test_and_clear_bit(HFC_CHIP_PCM_SLAVE, &hc->chip); hc->slots = 32; } if (hc->pci_dev->irq <= 0) { printk(KERN_WARNING "HFC-multi: No IRQ for PCI card found.\n"); return -EIO; } if (pci_enable_device(hc->pci_dev)) { printk(KERN_WARNING "HFC-multi: Error enabling PCI card.\n"); return -EIO; } hc->leds = m->leds; hc->ledstate = 0xAFFEAFFE; hc->opticalsupport = m->opticalsupport; /* set memory access methods */ if (m->io_mode) /* use mode from card config */ hc->io_mode = m->io_mode; switch (hc->io_mode) { case HFC_IO_MODE_PLXSD: test_and_set_bit(HFC_CHIP_PLXSD, &hc->chip); hc->slots = 128; /* required */ /* fall through */ case HFC_IO_MODE_PCIMEM: hc->HFC_outb = HFC_outb_pcimem; hc->HFC_inb = HFC_inb_pcimem; hc->HFC_inw = HFC_inw_pcimem; hc->HFC_wait = HFC_wait_pcimem; hc->read_fifo = read_fifo_pcimem; hc->write_fifo = write_fifo_pcimem; break; case HFC_IO_MODE_REGIO: hc->HFC_outb = HFC_outb_regio; hc->HFC_inb = HFC_inb_regio; hc->HFC_inw = HFC_inw_regio; hc->HFC_wait = HFC_wait_regio; hc->read_fifo = read_fifo_regio; hc->write_fifo = write_fifo_regio; break; default: printk(KERN_WARNING "HFC-multi: Invalid IO mode.\n"); pci_disable_device(hc->pci_dev); return -EIO; } hc->HFC_outb_nodebug = hc->HFC_outb; hc->HFC_inb_nodebug = hc->HFC_inb; hc->HFC_inw_nodebug = hc->HFC_inw; hc->HFC_wait_nodebug = hc->HFC_wait; #ifdef HFC_REGISTER_DEBUG hc->HFC_outb = HFC_outb_debug; hc->HFC_inb = HFC_inb_debug; hc->HFC_inw = HFC_inw_debug; hc->HFC_wait = HFC_wait_debug; #endif hc->pci_iobase = 0; hc->pci_membase = NULL; hc->plx_membase = NULL; switch (hc->io_mode) { case HFC_IO_MODE_PLXSD: hc->plx_origmembase = hc->pci_dev->resource[0].start; /* MEMBASE 1 is PLX PCI Bridge */ if (!hc->plx_origmembase) { printk(KERN_WARNING "HFC-multi: No IO-Memory for PCI PLX bridge found\n"); pci_disable_device(hc->pci_dev); return -EIO; } hc->plx_membase = ioremap(hc->plx_origmembase, 0x80); if (!hc->plx_membase) { printk(KERN_WARNING "HFC-multi: failed to remap plx address space. " "(internal error)\n"); pci_disable_device(hc->pci_dev); return -EIO; } printk(KERN_INFO "HFC-multi: plx_membase:%#lx plx_origmembase:%#lx\n", (u_long)hc->plx_membase, hc->plx_origmembase); hc->pci_origmembase = hc->pci_dev->resource[2].start; /* MEMBASE 1 is PLX PCI Bridge */ if (!hc->pci_origmembase) { printk(KERN_WARNING "HFC-multi: No IO-Memory for PCI card found\n"); pci_disable_device(hc->pci_dev); return -EIO; } hc->pci_membase = ioremap(hc->pci_origmembase, 0x400); if (!hc->pci_membase) { printk(KERN_WARNING "HFC-multi: failed to remap io " "address space. (internal error)\n"); pci_disable_device(hc->pci_dev); return -EIO; } printk(KERN_INFO "card %d: defined at MEMBASE %#lx (%#lx) IRQ %d HZ %d " "leds-type %d\n", hc->id, (u_long)hc->pci_membase, hc->pci_origmembase, hc->pci_dev->irq, HZ, hc->leds); pci_write_config_word(hc->pci_dev, PCI_COMMAND, PCI_ENA_MEMIO); break; case HFC_IO_MODE_PCIMEM: hc->pci_origmembase = hc->pci_dev->resource[1].start; if (!hc->pci_origmembase) { printk(KERN_WARNING "HFC-multi: No IO-Memory for PCI card found\n"); pci_disable_device(hc->pci_dev); return -EIO; } hc->pci_membase = ioremap(hc->pci_origmembase, 256); if (!hc->pci_membase) { printk(KERN_WARNING "HFC-multi: failed to remap io address space. " "(internal error)\n"); pci_disable_device(hc->pci_dev); return -EIO; } printk(KERN_INFO "card %d: defined at MEMBASE %#lx (%#lx) IRQ %d " "HZ %d leds-type %d\n", hc->id, (u_long)hc->pci_membase, hc->pci_origmembase, hc->pci_dev->irq, HZ, hc->leds); pci_write_config_word(hc->pci_dev, PCI_COMMAND, PCI_ENA_MEMIO); break; case HFC_IO_MODE_REGIO: hc->pci_iobase = (u_int) hc->pci_dev->resource[0].start; if (!hc->pci_iobase) { printk(KERN_WARNING "HFC-multi: No IO for PCI card found\n"); pci_disable_device(hc->pci_dev); return -EIO; } if (!request_region(hc->pci_iobase, 8, "hfcmulti")) { printk(KERN_WARNING "HFC-multi: failed to request " "address space at 0x%08lx (internal error)\n", hc->pci_iobase); pci_disable_device(hc->pci_dev); return -EIO; } printk(KERN_INFO "%s %s: defined at IOBASE %#x IRQ %d HZ %d leds-type %d\n", m->vendor_name, m->card_name, (u_int) hc->pci_iobase, hc->pci_dev->irq, HZ, hc->leds); pci_write_config_word(hc->pci_dev, PCI_COMMAND, PCI_ENA_REGIO); break; default: printk(KERN_WARNING "HFC-multi: Invalid IO mode.\n"); pci_disable_device(hc->pci_dev); return -EIO; } pci_set_drvdata(hc->pci_dev, hc); /* At this point the needed PCI config is done */ /* fifos are still not enabled */ return 0; } /* * remove port */ static void release_port(struct hfc_multi *hc, struct dchannel *dch) { int pt, ci, i = 0; u_long flags; struct bchannel *pb; ci = dch->slot; pt = hc->chan[ci].port; if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: entered for port %d\n", __func__, pt + 1); if (pt >= hc->ports) { printk(KERN_WARNING "%s: ERROR port out of range (%d).\n", __func__, pt + 1); return; } if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: releasing port=%d\n", __func__, pt + 1); if (dch->dev.D.protocol == ISDN_P_TE_S0) l1_event(dch->l1, CLOSE_CHANNEL); hc->chan[ci].dch = NULL; if (hc->created[pt]) { hc->created[pt] = 0; mISDN_unregister_device(&dch->dev); } spin_lock_irqsave(&hc->lock, flags); if (dch->timer.function) { del_timer(&dch->timer); dch->timer.function = NULL; } if (hc->type == 1) { /* E1 */ /* remove sync */ if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { hc->syncronized = 0; plxsd_checksync(hc, 1); } /* free channels */ for (i = 0; i <= 31; i++) { if (hc->chan[i].bch) { if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: free port %d channel %d\n", __func__, hc->chan[i].port+1, i); pb = hc->chan[i].bch; hc->chan[i].bch = NULL; spin_unlock_irqrestore(&hc->lock, flags); mISDN_freebchannel(pb); kfree(pb); kfree(hc->chan[i].coeff); spin_lock_irqsave(&hc->lock, flags); } } } else { /* remove sync */ if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) { hc->syncronized &= ~(1 << hc->chan[ci].port); plxsd_checksync(hc, 1); } /* free channels */ if (hc->chan[ci - 2].bch) { if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: free port %d channel %d\n", __func__, hc->chan[ci - 2].port+1, ci - 2); pb = hc->chan[ci - 2].bch; hc->chan[ci - 2].bch = NULL; spin_unlock_irqrestore(&hc->lock, flags); mISDN_freebchannel(pb); kfree(pb); kfree(hc->chan[ci - 2].coeff); spin_lock_irqsave(&hc->lock, flags); } if (hc->chan[ci - 1].bch) { if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: free port %d channel %d\n", __func__, hc->chan[ci - 1].port+1, ci - 1); pb = hc->chan[ci - 1].bch; hc->chan[ci - 1].bch = NULL; spin_unlock_irqrestore(&hc->lock, flags); mISDN_freebchannel(pb); kfree(pb); kfree(hc->chan[ci - 1].coeff); spin_lock_irqsave(&hc->lock, flags); } } spin_unlock_irqrestore(&hc->lock, flags); if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: free port %d channel D\n", __func__, pt); mISDN_freedchannel(dch); kfree(dch); if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: done!\n", __func__); } static void release_card(struct hfc_multi *hc) { u_long flags; int ch; if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_WARNING "%s: release card (%d) entered\n", __func__, hc->id); /* unregister clock source */ if (hc->iclock) mISDN_unregister_clock(hc->iclock); /* disable irq */ spin_lock_irqsave(&hc->lock, flags); disable_hwirq(hc); spin_unlock_irqrestore(&hc->lock, flags); udelay(1000); /* dimm leds */ if (hc->leds) hfcmulti_leds(hc); /* disable D-channels & B-channels */ if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: disable all channels (d and b)\n", __func__); for (ch = 0; ch <= 31; ch++) { if (hc->chan[ch].dch) release_port(hc, hc->chan[ch].dch); } /* release hardware & irq */ if (hc->irq) { if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_WARNING "%s: free irq %d\n", __func__, hc->irq); free_irq(hc->irq, hc); hc->irq = 0; } release_io_hfcmulti(hc); if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_WARNING "%s: remove instance from list\n", __func__); list_del(&hc->list); if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_WARNING "%s: delete instance\n", __func__); if (hc == syncmaster) syncmaster = NULL; kfree(hc); if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_WARNING "%s: card successfully removed\n", __func__); } static int init_e1_port(struct hfc_multi *hc, struct hm_map *m) { struct dchannel *dch; struct bchannel *bch; int ch, ret = 0; char name[MISDN_MAX_IDLEN]; dch = kzalloc(sizeof(struct dchannel), GFP_KERNEL); if (!dch) return -ENOMEM; dch->debug = debug; mISDN_initdchannel(dch, MAX_DFRAME_LEN_L1, ph_state_change); dch->hw = hc; dch->dev.Dprotocols = (1 << ISDN_P_TE_E1) | (1 << ISDN_P_NT_E1); dch->dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) | (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK)); dch->dev.D.send = handle_dmsg; dch->dev.D.ctrl = hfcm_dctrl; dch->dev.nrbchan = (hc->dslot)?30:31; dch->slot = hc->dslot; hc->chan[hc->dslot].dch = dch; hc->chan[hc->dslot].port = 0; hc->chan[hc->dslot].nt_timer = -1; for (ch = 1; ch <= 31; ch++) { if (ch == hc->dslot) /* skip dchannel */ continue; bch = kzalloc(sizeof(struct bchannel), GFP_KERNEL); if (!bch) { printk(KERN_ERR "%s: no memory for bchannel\n", __func__); ret = -ENOMEM; goto free_chan; } hc->chan[ch].coeff = kzalloc(512, GFP_KERNEL); if (!hc->chan[ch].coeff) { printk(KERN_ERR "%s: no memory for coeffs\n", __func__); ret = -ENOMEM; kfree(bch); goto free_chan; } bch->nr = ch; bch->slot = ch; bch->debug = debug; mISDN_initbchannel(bch, MAX_DATA_MEM); bch->hw = hc; bch->ch.send = handle_bmsg; bch->ch.ctrl = hfcm_bctrl; bch->ch.nr = ch; list_add(&bch->ch.list, &dch->dev.bchannels); hc->chan[ch].bch = bch; hc->chan[ch].port = 0; set_channelmap(bch->nr, dch->dev.channelmap); } /* set optical line type */ if (port[Port_cnt] & 0x001) { if (!m->opticalsupport) { printk(KERN_INFO "This board has no optical " "support\n"); } else { if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: PORT set optical " "interfacs: card(%d) " "port(%d)\n", __func__, HFC_cnt + 1, 1); test_and_set_bit(HFC_CFG_OPTICAL, &hc->chan[hc->dslot].cfg); } } /* set LOS report */ if (port[Port_cnt] & 0x004) { if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: PORT set " "LOS report: card(%d) port(%d)\n", __func__, HFC_cnt + 1, 1); test_and_set_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dslot].cfg); } /* set AIS report */ if (port[Port_cnt] & 0x008) { if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: PORT set " "AIS report: card(%d) port(%d)\n", __func__, HFC_cnt + 1, 1); test_and_set_bit(HFC_CFG_REPORT_AIS, &hc->chan[hc->dslot].cfg); } /* set SLIP report */ if (port[Port_cnt] & 0x010) { if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: PORT set SLIP report: " "card(%d) port(%d)\n", __func__, HFC_cnt + 1, 1); test_and_set_bit(HFC_CFG_REPORT_SLIP, &hc->chan[hc->dslot].cfg); } /* set RDI report */ if (port[Port_cnt] & 0x020) { if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: PORT set RDI report: " "card(%d) port(%d)\n", __func__, HFC_cnt + 1, 1); test_and_set_bit(HFC_CFG_REPORT_RDI, &hc->chan[hc->dslot].cfg); } /* set CRC-4 Mode */ if (!(port[Port_cnt] & 0x100)) { if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: PORT turn on CRC4 report:" " card(%d) port(%d)\n", __func__, HFC_cnt + 1, 1); test_and_set_bit(HFC_CFG_CRC4, &hc->chan[hc->dslot].cfg); } else { if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: PORT turn off CRC4" " report: card(%d) port(%d)\n", __func__, HFC_cnt + 1, 1); } /* set forced clock */ if (port[Port_cnt] & 0x0200) { if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: PORT force getting clock from " "E1: card(%d) port(%d)\n", __func__, HFC_cnt + 1, 1); test_and_set_bit(HFC_CHIP_E1CLOCK_GET, &hc->chip); } else if (port[Port_cnt] & 0x0400) { if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: PORT force putting clock to " "E1: card(%d) port(%d)\n", __func__, HFC_cnt + 1, 1); test_and_set_bit(HFC_CHIP_E1CLOCK_PUT, &hc->chip); } /* set JATT PLL */ if (port[Port_cnt] & 0x0800) { if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: PORT disable JATT PLL on " "E1: card(%d) port(%d)\n", __func__, HFC_cnt + 1, 1); test_and_set_bit(HFC_CHIP_RX_SYNC, &hc->chip); } /* set elastic jitter buffer */ if (port[Port_cnt] & 0x3000) { hc->chan[hc->dslot].jitter = (port[Port_cnt]>>12) & 0x3; if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: PORT set elastic " "buffer to %d: card(%d) port(%d)\n", __func__, hc->chan[hc->dslot].jitter, HFC_cnt + 1, 1); } else hc->chan[hc->dslot].jitter = 2; /* default */ snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-e1.%d", HFC_cnt + 1); ret = mISDN_register_device(&dch->dev, &hc->pci_dev->dev, name); if (ret) goto free_chan; hc->created[0] = 1; return ret; free_chan: release_port(hc, dch); return ret; } static int init_multi_port(struct hfc_multi *hc, int pt) { struct dchannel *dch; struct bchannel *bch; int ch, i, ret = 0; char name[MISDN_MAX_IDLEN]; dch = kzalloc(sizeof(struct dchannel), GFP_KERNEL); if (!dch) return -ENOMEM; dch->debug = debug; mISDN_initdchannel(dch, MAX_DFRAME_LEN_L1, ph_state_change); dch->hw = hc; dch->dev.Dprotocols = (1 << ISDN_P_TE_S0) | (1 << ISDN_P_NT_S0); dch->dev.Bprotocols = (1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) | (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK)); dch->dev.D.send = handle_dmsg; dch->dev.D.ctrl = hfcm_dctrl; dch->dev.nrbchan = 2; i = pt << 2; dch->slot = i + 2; hc->chan[i + 2].dch = dch; hc->chan[i + 2].port = pt; hc->chan[i + 2].nt_timer = -1; for (ch = 0; ch < dch->dev.nrbchan; ch++) { bch = kzalloc(sizeof(struct bchannel), GFP_KERNEL); if (!bch) { printk(KERN_ERR "%s: no memory for bchannel\n", __func__); ret = -ENOMEM; goto free_chan; } hc->chan[i + ch].coeff = kzalloc(512, GFP_KERNEL); if (!hc->chan[i + ch].coeff) { printk(KERN_ERR "%s: no memory for coeffs\n", __func__); ret = -ENOMEM; kfree(bch); goto free_chan; } bch->nr = ch + 1; bch->slot = i + ch; bch->debug = debug; mISDN_initbchannel(bch, MAX_DATA_MEM); bch->hw = hc; bch->ch.send = handle_bmsg; bch->ch.ctrl = hfcm_bctrl; bch->ch.nr = ch + 1; list_add(&bch->ch.list, &dch->dev.bchannels); hc->chan[i + ch].bch = bch; hc->chan[i + ch].port = pt; set_channelmap(bch->nr, dch->dev.channelmap); } /* set master clock */ if (port[Port_cnt] & 0x001) { if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: PROTOCOL set master clock: " "card(%d) port(%d)\n", __func__, HFC_cnt + 1, pt + 1); if (dch->dev.D.protocol != ISDN_P_TE_S0) { printk(KERN_ERR "Error: Master clock " "for port(%d) of card(%d) is only" " possible with TE-mode\n", pt + 1, HFC_cnt + 1); ret = -EINVAL; goto free_chan; } if (hc->masterclk >= 0) { printk(KERN_ERR "Error: Master clock " "for port(%d) of card(%d) already " "defined for port(%d)\n", pt + 1, HFC_cnt + 1, hc->masterclk+1); ret = -EINVAL; goto free_chan; } hc->masterclk = pt; } /* set transmitter line to non capacitive */ if (port[Port_cnt] & 0x002) { if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: PROTOCOL set non capacitive " "transmitter: card(%d) port(%d)\n", __func__, HFC_cnt + 1, pt + 1); test_and_set_bit(HFC_CFG_NONCAP_TX, &hc->chan[i + 2].cfg); } /* disable E-channel */ if (port[Port_cnt] & 0x004) { if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: PROTOCOL disable E-channel: " "card(%d) port(%d)\n", __func__, HFC_cnt + 1, pt + 1); test_and_set_bit(HFC_CFG_DIS_ECHANNEL, &hc->chan[i + 2].cfg); } snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-%ds.%d-%d", hc->type, HFC_cnt + 1, pt + 1); ret = mISDN_register_device(&dch->dev, &hc->pci_dev->dev, name); if (ret) goto free_chan; hc->created[pt] = 1; return ret; free_chan: release_port(hc, dch); return ret; } static int hfcmulti_init(struct pci_dev *pdev, const struct pci_device_id *ent) { struct hm_map *m = (struct hm_map *)ent->driver_data; int ret_err = 0; int pt; struct hfc_multi *hc; u_long flags; u_char dips = 0, pmj = 0; /* dip settings, port mode Jumpers */ int i; if (HFC_cnt >= MAX_CARDS) { printk(KERN_ERR "too many cards (max=%d).\n", MAX_CARDS); return -EINVAL; } if ((type[HFC_cnt] & 0xff) && (type[HFC_cnt] & 0xff) != m->type) { printk(KERN_WARNING "HFC-MULTI: Card '%s:%s' type %d found but " "type[%d] %d was supplied as module parameter\n", m->vendor_name, m->card_name, m->type, HFC_cnt, type[HFC_cnt] & 0xff); printk(KERN_WARNING "HFC-MULTI: Load module without parameters " "first, to see cards and their types."); return -EINVAL; } if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: Registering %s:%s chip type %d (0x%x)\n", __func__, m->vendor_name, m->card_name, m->type, type[HFC_cnt]); /* allocate card+fifo structure */ hc = kzalloc(sizeof(struct hfc_multi), GFP_KERNEL); if (!hc) { printk(KERN_ERR "No kmem for HFC-Multi card\n"); return -ENOMEM; } spin_lock_init(&hc->lock); hc->mtyp = m; hc->type = m->type; hc->ports = m->ports; hc->id = HFC_cnt; hc->pcm = pcm[HFC_cnt]; hc->io_mode = iomode[HFC_cnt]; if (dslot[HFC_cnt] < 0 && hc->type == 1) { hc->dslot = 0; printk(KERN_INFO "HFC-E1 card has disabled D-channel, but " "31 B-channels\n"); } if (dslot[HFC_cnt] > 0 && dslot[HFC_cnt] < 32 && hc->type == 1) { hc->dslot = dslot[HFC_cnt]; printk(KERN_INFO "HFC-E1 card has alternating D-channel on " "time slot %d\n", dslot[HFC_cnt]); } else hc->dslot = 16; /* set chip specific features */ hc->masterclk = -1; if (type[HFC_cnt] & 0x100) { test_and_set_bit(HFC_CHIP_ULAW, &hc->chip); hc->silence = 0xff; /* ulaw silence */ } else hc->silence = 0x2a; /* alaw silence */ if ((poll >> 1) > sizeof(hc->silence_data)) { printk(KERN_ERR "HFCMULTI error: silence_data too small, " "please fix\n"); return -EINVAL; } for (i = 0; i < (poll >> 1); i++) hc->silence_data[i] = hc->silence; if (!(type[HFC_cnt] & 0x200)) test_and_set_bit(HFC_CHIP_DTMF, &hc->chip); if (type[HFC_cnt] & 0x800) test_and_set_bit(HFC_CHIP_PCM_SLAVE, &hc->chip); if (type[HFC_cnt] & 0x1000) { test_and_set_bit(HFC_CHIP_PCM_MASTER, &hc->chip); test_and_clear_bit(HFC_CHIP_PCM_SLAVE, &hc->chip); } if (type[HFC_cnt] & 0x4000) test_and_set_bit(HFC_CHIP_EXRAM_128, &hc->chip); if (type[HFC_cnt] & 0x8000) test_and_set_bit(HFC_CHIP_EXRAM_512, &hc->chip); hc->slots = 32; if (type[HFC_cnt] & 0x10000) hc->slots = 64; if (type[HFC_cnt] & 0x20000) hc->slots = 128; if (type[HFC_cnt] & 0x80000) { test_and_set_bit(HFC_CHIP_WATCHDOG, &hc->chip); hc->wdcount = 0; hc->wdbyte = V_GPIO_OUT2; printk(KERN_NOTICE "Watchdog enabled\n"); } /* setup pci, hc->slots may change due to PLXSD */ ret_err = setup_pci(hc, pdev, ent); if (ret_err) { if (hc == syncmaster) syncmaster = NULL; kfree(hc); return ret_err; } /* crate channels */ for (pt = 0; pt < hc->ports; pt++) { if (Port_cnt >= MAX_PORTS) { printk(KERN_ERR "too many ports (max=%d).\n", MAX_PORTS); ret_err = -EINVAL; goto free_card; } if (hc->type == 1) ret_err = init_e1_port(hc, m); else ret_err = init_multi_port(hc, pt); if (debug & DEBUG_HFCMULTI_INIT) printk(KERN_DEBUG "%s: Registering D-channel, card(%d) port(%d)" "result %d\n", __func__, HFC_cnt + 1, pt, ret_err); if (ret_err) { while (pt) { /* release already registered ports */ pt--; release_port(hc, hc->chan[(pt << 2) + 2].dch); } goto free_card; } Port_cnt++; } /* disp switches */ switch (m->dip_type) { case DIP_4S: /* * Get DIP setting for beroNet 1S/2S/4S cards * DIP Setting: (collect GPIO 13/14/15 (R_GPIO_IN1) + * GPI 19/23 (R_GPI_IN2)) */ dips = ((~HFC_inb(hc, R_GPIO_IN1) & 0xE0) >> 5) | ((~HFC_inb(hc, R_GPI_IN2) & 0x80) >> 3) | (~HFC_inb(hc, R_GPI_IN2) & 0x08); /* Port mode (TE/NT) jumpers */ pmj = ((HFC_inb(hc, R_GPI_IN3) >> 4) & 0xf); if (test_bit(HFC_CHIP_B410P, &hc->chip)) pmj = ~pmj & 0xf; printk(KERN_INFO "%s: %s DIPs(0x%x) jumpers(0x%x)\n", m->vendor_name, m->card_name, dips, pmj); break; case DIP_8S: /* * Get DIP Setting for beroNet 8S0+ cards * Enable PCI auxbridge function */ HFC_outb(hc, R_BRG_PCM_CFG, 1 | V_PCM_CLK); /* prepare access to auxport */ outw(0x4000, hc->pci_iobase + 4); /* * some dummy reads are required to * read valid DIP switch data */ dips = inb(hc->pci_iobase); dips = inb(hc->pci_iobase); dips = inb(hc->pci_iobase); dips = ~inb(hc->pci_iobase) & 0x3F; outw(0x0, hc->pci_iobase + 4); /* disable PCI auxbridge function */ HFC_outb(hc, R_BRG_PCM_CFG, V_PCM_CLK); printk(KERN_INFO "%s: %s DIPs(0x%x)\n", m->vendor_name, m->card_name, dips); break; case DIP_E1: /* * get DIP Setting for beroNet E1 cards * DIP Setting: collect GPI 4/5/6/7 (R_GPI_IN0) */ dips = (~HFC_inb(hc, R_GPI_IN0) & 0xF0)>>4; printk(KERN_INFO "%s: %s DIPs(0x%x)\n", m->vendor_name, m->card_name, dips); break; } /* add to list */ spin_lock_irqsave(&HFClock, flags); list_add_tail(&hc->list, &HFClist); spin_unlock_irqrestore(&HFClock, flags); /* use as clock source */ if (clock == HFC_cnt + 1) hc->iclock = mISDN_register_clock("HFCMulti", 0, clockctl, hc); /* initialize hardware */ ret_err = init_card(hc); if (ret_err) { printk(KERN_ERR "init card returns %d\n", ret_err); release_card(hc); return ret_err; } /* start IRQ and return */ spin_lock_irqsave(&hc->lock, flags); enable_hwirq(hc); spin_unlock_irqrestore(&hc->lock, flags); return 0; free_card: release_io_hfcmulti(hc); if (hc == syncmaster) syncmaster = NULL; kfree(hc); return ret_err; } static void __devexit hfc_remove_pci(struct pci_dev *pdev)