enabled all DVB Devices and add some patches.
#
# Automatically generated file; DO NOT EDIT.
-# Linux/x86 3.10.9 Kernel Configuration
+# Linux/x86 3.10.10 Kernel Configuration
#
# CONFIG_64BIT is not set
CONFIG_X86_32=y
CONFIG_X86_INTERNODE_CACHE_SHIFT=6
CONFIG_X86_L1_CACHE_SHIFT=6
# CONFIG_X86_PPRO_FENCE is not set
+CONFIG_X86_F00F_BUG=y
CONFIG_X86_ALIGNMENT_16=y
CONFIG_X86_INTEL_USERCOPY=y
CONFIG_X86_TSC=y
CONFIG_EFI=y
CONFIG_EFI_STUB=y
CONFIG_SECCOMP=y
+CONFIG_CC_STACKPROTECTOR=y
# CONFIG_HZ_100 is not set
# CONFIG_HZ_250 is not set
CONFIG_HZ_300=y
# CONFIG_PCI_GOBIOS is not set
# CONFIG_PCI_GOMMCONFIG is not set
# CONFIG_PCI_GODIRECT is not set
-# CONFIG_PCI_GOOLPC is not set
CONFIG_PCI_GOANY=y
CONFIG_PCI_BIOS=y
CONFIG_PCI_DIRECT=y
CONFIG_PCI_MMCONFIG=y
-CONFIG_PCI_OLPC=y
CONFIG_PCI_DOMAINS=y
# CONFIG_PCI_CNB20LE_QUIRK is not set
CONFIG_PCIEPORTBUS=y
CONFIG_PCI_IOAPIC=y
CONFIG_PCI_LABEL=y
CONFIG_ISA_DMA_API=y
-# CONFIG_ISA is not set
-# CONFIG_SCx200 is not set
-CONFIG_OLPC=y
-CONFIG_OLPC_XO1_PM=y
-CONFIG_OLPC_XO1_RTC=y
-CONFIG_OLPC_XO1_SCI=y
-CONFIG_OLPC_XO15_SCI=y
-# CONFIG_ALIX is not set
-# CONFIG_NET5501 is not set
-# CONFIG_GEOS is not set
+CONFIG_ISA=y
+CONFIG_EISA=y
+# CONFIG_EISA_VLB_PRIMING is not set
+CONFIG_EISA_PCI_EISA=y
+CONFIG_EISA_VIRTUAL_ROOT=y
+CONFIG_EISA_NAMES=y
+CONFIG_SCx200=m
+CONFIG_SCx200HR_TIMER=m
+# CONFIG_OLPC is not set
+CONFIG_ALIX=y
+CONFIG_NET5501=y
+CONFIG_GEOS=y
CONFIG_AMD_NB=y
CONFIG_PCCARD=m
-# CONFIG_PCMCIA is not set
+CONFIG_PCMCIA=m
+CONFIG_PCMCIA_LOAD_CIS=y
CONFIG_CARDBUS=y
#
CONFIG_YENTA_TI=y
CONFIG_YENTA_ENE_TUNE=y
CONFIG_YENTA_TOSHIBA=y
+CONFIG_PD6729=m
+CONFIG_I82092=m
+CONFIG_I82365=m
+CONFIG_TCIC=m
+CONFIG_PCMCIA_PROBE=y
+CONFIG_PCCARD_NONSTATIC=y
CONFIG_HOTPLUG_PCI=y
# CONFIG_HOTPLUG_PCI_COMPAQ is not set
# CONFIG_HOTPLUG_PCI_IBM is not set
CONFIG_BT_HCIBCM203X=m
CONFIG_BT_HCIBPA10X=m
CONFIG_BT_HCIBFUSB=m
+# CONFIG_BT_HCIDTL1 is not set
+# CONFIG_BT_HCIBT3C is not set
+CONFIG_BT_HCIBLUECARD=m
+CONFIG_BT_HCIBTUART=m
CONFIG_BT_HCIVHCI=m
CONFIG_BT_MRVL=m
CONFIG_BT_MRVL_SDIO=m
CONFIG_CONNECTOR=y
CONFIG_PROC_EVENTS=y
# CONFIG_MTD is not set
-CONFIG_OF=y
-
-#
-# Device Tree and Open Firmware support
-#
-CONFIG_PROC_DEVICETREE=y
-# CONFIG_OF_SELFTEST is not set
-CONFIG_OF_PROMTREE=y
-CONFIG_OF_ADDRESS=y
-CONFIG_OF_IRQ=y
-CONFIG_OF_DEVICE=y
-CONFIG_OF_I2C=m
-CONFIG_OF_NET=y
-CONFIG_OF_MDIO=y
-CONFIG_OF_PCI=y
-CONFIG_OF_PCI_IRQ=y
CONFIG_PARPORT=m
CONFIG_PARPORT_PC=m
CONFIG_PARPORT_SERIAL=m
-# CONFIG_PARPORT_PC_FIFO is not set
-# CONFIG_PARPORT_PC_SUPERIO is not set
+CONFIG_PARPORT_PC_FIFO=y
+CONFIG_PARPORT_PC_SUPERIO=y
+CONFIG_PARPORT_PC_PCMCIA=m
# CONFIG_PARPORT_GSC is not set
-# CONFIG_PARPORT_AX88796 is not set
+CONFIG_PARPORT_AX88796=m
CONFIG_PARPORT_1284=y
CONFIG_PARPORT_NOT_PC=y
CONFIG_PNP=y
#
# Protocols
#
+CONFIG_ISAPNP=y
+CONFIG_PNPBIOS=y
+# CONFIG_PNPBIOS_PROC_FS is not set
CONFIG_PNPACPI=y
CONFIG_BLK_DEV=y
CONFIG_BLK_DEV_FD=m
CONFIG_SCSI_HPSA=m
CONFIG_SCSI_3W_9XXX=m
CONFIG_SCSI_3W_SAS=m
+CONFIG_SCSI_7000FASST=m
CONFIG_SCSI_ACARD=m
+CONFIG_SCSI_AHA152X=m
+CONFIG_SCSI_AHA1542=m
+CONFIG_SCSI_AHA1740=m
CONFIG_SCSI_AACRAID=m
CONFIG_SCSI_AIC7XXX=m
CONFIG_AIC7XXX_CMDS_PER_DEVICE=32
CONFIG_SCSI_MVSAS=m
# CONFIG_SCSI_MVSAS_DEBUG is not set
CONFIG_SCSI_MVSAS_TASKLET=y
-# CONFIG_SCSI_MVUMI is not set
+CONFIG_SCSI_MVUMI=m
CONFIG_SCSI_DPT_I2O=m
CONFIG_SCSI_ADVANSYS=m
+CONFIG_SCSI_IN2000=m
CONFIG_SCSI_ARCMSR=m
CONFIG_MEGARAID_NEWGEN=y
CONFIG_MEGARAID_MM=m
CONFIG_FCOE=m
CONFIG_FCOE_FNIC=m
CONFIG_SCSI_DMX3191D=m
+CONFIG_SCSI_DTC3280=m
CONFIG_SCSI_EATA=m
CONFIG_SCSI_EATA_TAGGED_QUEUE=y
# CONFIG_SCSI_EATA_LINKED_COMMANDS is not set
CONFIG_SCSI_FUTURE_DOMAIN=m
CONFIG_SCSI_GDTH=m
CONFIG_SCSI_ISCI=m
+CONFIG_SCSI_GENERIC_NCR5380=m
+CONFIG_SCSI_GENERIC_NCR5380_MMIO=m
+# CONFIG_SCSI_GENERIC_NCR53C400 is not set
CONFIG_SCSI_IPS=m
CONFIG_SCSI_INITIO=m
CONFIG_SCSI_INIA100=m
CONFIG_SCSI_IMM=m
# CONFIG_SCSI_IZIP_EPP16 is not set
# CONFIG_SCSI_IZIP_SLOW_CTR is not set
+CONFIG_SCSI_NCR53C406A=m
CONFIG_SCSI_STEX=m
CONFIG_SCSI_SYM53C8XX_2=m
CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
CONFIG_SCSI_IPR=m
CONFIG_SCSI_IPR_TRACE=y
CONFIG_SCSI_IPR_DUMP=y
+CONFIG_SCSI_PAS16=m
+CONFIG_SCSI_QLOGIC_FAS=m
CONFIG_SCSI_QLOGIC_1280=m
CONFIG_SCSI_QLA_FC=m
CONFIG_SCSI_QLA_ISCSI=m
CONFIG_SCSI_LPFC=m
# CONFIG_SCSI_LPFC_DEBUG_FS is not set
+CONFIG_SCSI_SIM710=m
+CONFIG_SCSI_SYM53C416=m
CONFIG_SCSI_DC395x=m
CONFIG_SCSI_DC390T=m
-# CONFIG_SCSI_NSP32 is not set
+CONFIG_SCSI_T128=m
+CONFIG_SCSI_U14_34F=m
+# CONFIG_SCSI_U14_34F_TAGGED_QUEUE is not set
+# CONFIG_SCSI_U14_34F_LINKED_COMMANDS is not set
+CONFIG_SCSI_U14_34F_MAX_TAGS=8
+CONFIG_SCSI_ULTRASTOR=m
+CONFIG_SCSI_NSP32=m
# CONFIG_SCSI_DEBUG is not set
CONFIG_SCSI_PMCRAID=m
CONFIG_SCSI_PM8001=m
CONFIG_SCSI_BFA_FC=m
CONFIG_SCSI_VIRTIO=m
CONFIG_SCSI_CHELSIO_FCOE=m
+CONFIG_SCSI_LOWLEVEL_PCMCIA=y
+CONFIG_PCMCIA_AHA152X=m
+CONFIG_PCMCIA_FDOMAIN=m
+CONFIG_PCMCIA_NINJA_SCSI=m
+CONFIG_PCMCIA_QLOGIC=m
+CONFIG_PCMCIA_SYM53C500=m
CONFIG_SCSI_DH=y
CONFIG_SCSI_DH_RDAC=m
CONFIG_SCSI_DH_HP_SW=m
# CONFIG_ATA_NONSTANDARD is not set
CONFIG_ATA_VERBOSE_ERROR=y
CONFIG_ATA_ACPI=y
-# CONFIG_SATA_ZPODD is not set
+CONFIG_SATA_ZPODD=y
CONFIG_SATA_PMP=y
#
CONFIG_PATA_OPTIDMA=m
CONFIG_PATA_PDC2027X=m
CONFIG_PATA_PDC_OLD=m
-# CONFIG_PATA_RADISYS is not set
+CONFIG_PATA_RADISYS=m
CONFIG_PATA_RDC=m
-# CONFIG_PATA_SC1200 is not set
+CONFIG_PATA_SC1200=m
CONFIG_PATA_SCH=m
CONFIG_PATA_SERVERWORKS=m
CONFIG_PATA_SIL680=m
# PIO-only SFF controllers
#
CONFIG_PATA_CMD640_PCI=m
+CONFIG_PATA_ISAPNP=m
CONFIG_PATA_MPIIX=m
CONFIG_PATA_NS87410=m
CONFIG_PATA_OPTI=m
-# CONFIG_PATA_PLATFORM is not set
+CONFIG_PATA_PCMCIA=m
+CONFIG_PATA_PLATFORM=m
+CONFIG_PATA_QDI=m
CONFIG_PATA_RZ1000=m
+CONFIG_PATA_WINBOND_VLB=m
#
# Generic fallback / legacy drivers
#
CONFIG_PATA_ACPI=m
CONFIG_ATA_GENERIC=m
-# CONFIG_PATA_LEGACY is not set
+CONFIG_PATA_LEGACY=m
CONFIG_MD=y
CONFIG_BLK_DEV_MD=y
CONFIG_MD_AUTODETECT=y
# CONFIG_ATM_ENI_DEBUG is not set
# CONFIG_ATM_ENI_TUNE_BURST is not set
CONFIG_ATM_FIRESTREAM=m
-# CONFIG_ATM_ZATM is not set
+CONFIG_ATM_ZATM=m
+# CONFIG_ATM_ZATM_DEBUG is not set
CONFIG_ATM_NICSTAR=m
# CONFIG_ATM_NICSTAR_USE_SUNI is not set
# CONFIG_ATM_NICSTAR_USE_IDT77105 is not set
# CONFIG_ATM_IDT77252_DEBUG is not set
# CONFIG_ATM_IDT77252_RCV_ALL is not set
CONFIG_ATM_IDT77252_USE_SUNI=y
-# CONFIG_ATM_AMBASSADOR is not set
-# CONFIG_ATM_HORIZON is not set
-# CONFIG_ATM_IA is not set
-# CONFIG_ATM_FORE200E is not set
+CONFIG_ATM_AMBASSADOR=m
+# CONFIG_ATM_AMBASSADOR_DEBUG is not set
+CONFIG_ATM_HORIZON=m
+# CONFIG_ATM_HORIZON_DEBUG is not set
+CONFIG_ATM_IA=m
+# CONFIG_ATM_IA_DEBUG is not set
+CONFIG_ATM_FORE200E=m
+# CONFIG_ATM_FORE200E_USE_TASKLET is not set
+CONFIG_ATM_FORE200E_TX_RETRY=16
+CONFIG_ATM_FORE200E_DEBUG=0
CONFIG_ATM_HE=m
# CONFIG_ATM_HE_USE_SUNI is not set
CONFIG_ATM_SOLOS=m
CONFIG_ETHERNET=y
CONFIG_MDIO=m
CONFIG_NET_VENDOR_3COM=y
+CONFIG_EL3=m
+CONFIG_3C515=m
+CONFIG_PCMCIA_3C574=m
+CONFIG_PCMCIA_3C589=m
CONFIG_VORTEX=m
CONFIG_TYPHOON=m
CONFIG_NET_VENDOR_ADAPTEC=y
# CONFIG_ACENIC_OMIT_TIGON_I is not set
CONFIG_NET_VENDOR_AMD=y
CONFIG_AMD8111_ETH=m
+CONFIG_LANCE=m
CONFIG_PCNET32=m
+CONFIG_PCMCIA_NMCLAN=m
+CONFIG_NI65=m
CONFIG_NET_VENDOR_ATHEROS=y
CONFIG_ATL2=m
CONFIG_ATL1=m
CONFIG_CHELSIO_T3=m
CONFIG_CHELSIO_T4=m
CONFIG_CHELSIO_T4VF=m
+CONFIG_NET_VENDOR_CIRRUS=y
+CONFIG_CS89x0=m
+# CONFIG_CS89x0_PLATFORM is not set
CONFIG_NET_VENDOR_CISCO=y
CONFIG_ENIC=m
CONFIG_DNET=m
CONFIG_S2IO=m
CONFIG_VXGE=m
# CONFIG_VXGE_DEBUG_TRACE_ALL is not set
+CONFIG_NET_VENDOR_FUJITSU=y
+CONFIG_PCMCIA_FMVJ18X=m
CONFIG_NET_VENDOR_HP=y
CONFIG_HP100=m
CONFIG_NET_VENDOR_INTEL=y
CONFIG_MLX4_CORE=m
CONFIG_MLX4_DEBUG=y
CONFIG_NET_VENDOR_MICREL=y
-# CONFIG_KS8842 is not set
-# CONFIG_KS8851_MLL is not set
+CONFIG_KS8842=m
+CONFIG_KS8851_MLL=m
CONFIG_KSZ884X_PCI=m
CONFIG_NET_VENDOR_MYRI=y
CONFIG_MYRI10GE=m
CONFIG_NATSEMI=m
CONFIG_NS83820=m
CONFIG_NET_VENDOR_8390=y
+CONFIG_PCMCIA_AXNET=m
+CONFIG_NE2000=m
CONFIG_NE2K_PCI=m
+CONFIG_PCMCIA_PCNET=m
+CONFIG_ULTRA=m
+CONFIG_WD80x3=m
CONFIG_NET_VENDOR_NVIDIA=y
CONFIG_FORCEDETH=m
CONFIG_NET_VENDOR_OKI=y
CONFIG_SFC_MCDI_MON=y
CONFIG_SFC_SRIOV=y
CONFIG_NET_VENDOR_SMSC=y
+CONFIG_SMC9194=m
+CONFIG_PCMCIA_SMC91C92=m
CONFIG_EPIC100=m
CONFIG_SMSC9420=m
CONFIG_NET_VENDOR_STMICRO=y
# CONFIG_WIZNET_BUS_DIRECT is not set
# CONFIG_WIZNET_BUS_INDIRECT is not set
CONFIG_WIZNET_BUS_ANY=y
+CONFIG_NET_VENDOR_XIRCOM=y
+CONFIG_PCMCIA_XIRC2PS=m
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
# CONFIG_NET_SB1000 is not set
CONFIG_FIXED_PHY=y
CONFIG_MDIO_BITBANG=m
# CONFIG_MDIO_GPIO is not set
-CONFIG_MDIO_BUS_MUX=m
-CONFIG_MDIO_BUS_MUX_GPIO=m
-CONFIG_MDIO_BUS_MUX_MMIOREG=m
# CONFIG_PLIP is not set
CONFIG_PPP=m
CONFIG_PPP_BSDCOMP=m
CONFIG_USB_SIERRA_NET=m
CONFIG_USB_VL600=m
CONFIG_WLAN=y
+# CONFIG_PCMCIA_RAYCS is not set
CONFIG_LIBERTAS_THINFIRM=m
# CONFIG_LIBERTAS_THINFIRM_DEBUG is not set
CONFIG_LIBERTAS_THINFIRM_USB=m
CONFIG_AIRO=m
CONFIG_ATMEL=m
CONFIG_PCI_ATMEL=m
+CONFIG_PCMCIA_ATMEL=m
CONFIG_AT76C50X_USB=m
+CONFIG_AIRO_CS=m
+CONFIG_PCMCIA_WL3501=m
# CONFIG_PRISM54 is not set
CONFIG_USB_ZD1201=m
CONFIG_USB_NET_RNDIS_WLAN=m
CONFIG_B43_SSB=y
CONFIG_B43_PCI_AUTOSELECT=y
CONFIG_B43_PCICORE_AUTOSELECT=y
+# CONFIG_B43_PCMCIA is not set
CONFIG_B43_SDIO=y
CONFIG_B43_PIO=y
CONFIG_B43_PHY_N=y
CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y
# CONFIG_B43LEGACY_DMA_MODE is not set
# CONFIG_B43LEGACY_PIO_MODE is not set
-# CONFIG_BRCMFMAC is not set
+CONFIG_BRCMUTIL=m
+CONFIG_BRCMFMAC=m
+CONFIG_BRCMFMAC_SDIO=y
+# CONFIG_BRCMFMAC_USB is not set
+# CONFIG_BRCM_TRACING is not set
+# CONFIG_BRCMDBG is not set
CONFIG_HOSTAP=m
CONFIG_HOSTAP_FIRMWARE=y
CONFIG_HOSTAP_FIRMWARE_NVRAM=y
CONFIG_HOSTAP_PLX=m
CONFIG_HOSTAP_PCI=m
+CONFIG_HOSTAP_CS=m
CONFIG_IPW2100=m
CONFIG_IPW2100_MONITOR=y
# CONFIG_IPW2100_DEBUG is not set
# CONFIG_IPW2200_DEBUG is not set
CONFIG_LIBIPW=m
# CONFIG_LIBIPW_DEBUG is not set
-# CONFIG_IWLWIFI is not set
+CONFIG_IWLWIFI=m
+CONFIG_IWLDVM=m
+CONFIG_IWLMVM=m
+CONFIG_IWLWIFI_OPMODE_MODULAR=y
+
+#
+# Debugging Options
+#
+# CONFIG_IWLWIFI_DEBUG is not set
+# CONFIG_IWLWIFI_DEVICE_TRACING is not set
+CONFIG_IWLWIFI_P2P=y
CONFIG_IWLEGACY=m
CONFIG_IWL4965=m
CONFIG_IWL3945=m
# CONFIG_IWLEGACY_DEBUG is not set
CONFIG_LIBERTAS=m
CONFIG_LIBERTAS_USB=m
+CONFIG_LIBERTAS_CS=m
CONFIG_LIBERTAS_SDIO=m
# CONFIG_LIBERTAS_DEBUG is not set
CONFIG_LIBERTAS_MESH=y
CONFIG_PLX_HERMES=m
CONFIG_TMD_HERMES=m
CONFIG_NORTEL_HERMES=m
+CONFIG_PCMCIA_HERMES=m
+CONFIG_PCMCIA_SPECTRUM=m
CONFIG_ORINOCO_USB=m
CONFIG_P54_COMMON=m
CONFIG_P54_USB=m
# CONFIG_ZD1211RW_DEBUG is not set
CONFIG_MWIFIEX=m
CONFIG_MWIFIEX_SDIO=m
-# CONFIG_MWIFIEX_PCIE is not set
+CONFIG_MWIFIEX_PCIE=m
CONFIG_MWIFIEX_USB=m
#
#
# HiSax supported cards
#
+# CONFIG_HISAX_16_0 is not set
CONFIG_HISAX_16_3=y
CONFIG_HISAX_TELESPCI=y
CONFIG_HISAX_S0BOX=y
+# CONFIG_HISAX_AVM_A1 is not set
CONFIG_HISAX_FRITZPCI=y
CONFIG_HISAX_AVM_A1_PCMCIA=y
CONFIG_HISAX_ELSA=y
+# CONFIG_HISAX_IX1MICROR2 is not set
CONFIG_HISAX_DIEHLDIVA=y
+# CONFIG_HISAX_ASUSCOM is not set
+# CONFIG_HISAX_TELEINT is not set
+# CONFIG_HISAX_HFCS is not set
CONFIG_HISAX_SEDLBAUER=y
+# CONFIG_HISAX_SPORTSTER is not set
+# CONFIG_HISAX_MIC is not set
CONFIG_HISAX_NETJET=y
CONFIG_HISAX_NETJET_U=y
CONFIG_HISAX_NICCY=y
+# CONFIG_HISAX_ISURF is not set
+# CONFIG_HISAX_HSTSAPHIR is not set
CONFIG_HISAX_BKM_A4T=y
CONFIG_HISAX_SCT_QUADRO=y
CONFIG_HISAX_GAZEL=y
#
# HiSax PCMCIA card service modules
#
+# CONFIG_HISAX_SEDLBAUER_CS is not set
+# CONFIG_HISAX_ELSA_CS is not set
+# CONFIG_HISAX_AVM_A1_CS is not set
+# CONFIG_HISAX_TELES_CS is not set
#
# HiSax sub driver modules
#
# Active cards
#
+# CONFIG_ISDN_DRV_ICN is not set
+# CONFIG_ISDN_DRV_PCBIT is not set
+# CONFIG_ISDN_DRV_SC is not set
+# CONFIG_ISDN_DRV_ACT2000 is not set
CONFIG_ISDN_CAPI=m
CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y
CONFIG_CAPI_TRACE=y
# CAPI hardware drivers
#
CONFIG_CAPI_AVM=y
+# CONFIG_ISDN_DRV_AVMB1_B1ISA is not set
CONFIG_ISDN_DRV_AVMB1_B1PCI=m
CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y
+# CONFIG_ISDN_DRV_AVMB1_T1ISA is not set
+# CONFIG_ISDN_DRV_AVMB1_B1PCMCIA is not set
CONFIG_ISDN_DRV_AVMB1_T1PCI=m
CONFIG_ISDN_DRV_AVMB1_C4=m
CONFIG_CAPI_EICON=y
CONFIG_MOUSE_PS2_ELANTECH=y
CONFIG_MOUSE_PS2_SENTELIC=y
CONFIG_MOUSE_PS2_TOUCHKIT=y
-CONFIG_MOUSE_PS2_OLPC=y
CONFIG_MOUSE_SERIAL=m
CONFIG_MOUSE_APPLETOUCH=m
CONFIG_MOUSE_BCM5974=m
CONFIG_MOUSE_CYAPA=m
+# CONFIG_MOUSE_INPORT is not set
+# CONFIG_MOUSE_LOGIBM is not set
+# CONFIG_MOUSE_PC110PAD is not set
CONFIG_MOUSE_VSXXXAA=m
# CONFIG_MOUSE_GPIO is not set
CONFIG_MOUSE_SYNAPTICS_I2C=m
CONFIG_INPUT_RETU_PWRBUTTON=m
CONFIG_INPUT_UINPUT=m
# CONFIG_INPUT_PCF8574 is not set
-CONFIG_INPUT_PWM_BEEPER=m
CONFIG_INPUT_GPIO_ROTARY_ENCODER=m
# CONFIG_INPUT_ADXL34X is not set
# CONFIG_INPUT_IMS_PCU is not set
CONFIG_SERIO_ALTERA_PS2=m
# CONFIG_SERIO_PS2MULT is not set
CONFIG_SERIO_ARC_PS2=m
-CONFIG_SERIO_APBPS2=m
# CONFIG_GAMEPORT is not set
#
CONFIG_FIX_EARLYCON_MEM=y
CONFIG_SERIAL_8250_DMA=y
CONFIG_SERIAL_8250_PCI=y
+# CONFIG_SERIAL_8250_CS is not set
CONFIG_SERIAL_8250_NR_UARTS=4
CONFIG_SERIAL_8250_RUNTIME_UARTS=4
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y
+# CONFIG_SERIAL_8250_FOURPORT is not set
+# CONFIG_SERIAL_8250_ACCENT is not set
+# CONFIG_SERIAL_8250_BOCA is not set
+# CONFIG_SERIAL_8250_EXAR_ST16C554 is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
CONFIG_SERIAL_8250_SHARE_IRQ=y
# CONFIG_SERIAL_8250_DETECT_IRQ is not set
CONFIG_SERIAL_8250_RSA=y
-# CONFIG_SERIAL_8250_DW is not set
+CONFIG_SERIAL_8250_DW=m
#
# Non-8250 serial port support
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_SERIAL_JSM=m
-CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_SERIAL_SCCNXP=m
# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_ALTERA_JTAGUART is not set
# CONFIG_SERIAL_ALTERA_UART is not set
# CONFIG_SERIAL_PCH_UART is not set
-# CONFIG_SERIAL_XILINX_PS_UART is not set
CONFIG_SERIAL_ARC=m
CONFIG_SERIAL_ARC_NR_PORTS=1
CONFIG_SERIAL_RP2=m
CONFIG_HW_RANDOM_VIRTIO=m
CONFIG_HW_RANDOM_EXYNOS=m
CONFIG_NVRAM=y
+# CONFIG_DTLK is not set
CONFIG_R3964=m
# CONFIG_APPLICOM is not set
CONFIG_SONYPI=m
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+# CONFIG_CARDMAN_4000 is not set
+# CONFIG_CARDMAN_4040 is not set
+# CONFIG_IPWIRELESS is not set
CONFIG_MWAVE=m
+# CONFIG_SCx200_GPIO is not set
CONFIG_PC8736x_GPIO=m
CONFIG_NSC_GPIO=m
CONFIG_RAW_DRIVER=y
# CONFIG_I2C_INTEL_MID is not set
# CONFIG_I2C_OCORES is not set
CONFIG_I2C_PCA_PLATFORM=m
-CONFIG_I2C_PXA=m
-CONFIG_I2C_PXA_PCI=y
+# CONFIG_I2C_PXA_PCI is not set
CONFIG_I2C_SIMTEC=m
# CONFIG_I2C_XILINX is not set
#
# Other I2C/SMBus bus drivers
#
+# CONFIG_I2C_PCA_ISA is not set
CONFIG_SCx200_ACB=m
CONFIG_I2C_STUB=m
# CONFIG_I2C_DEBUG_CORE is not set
CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
CONFIG_GPIO_DEVRES=y
CONFIG_GPIOLIB=y
-CONFIG_OF_GPIO=y
CONFIG_GPIO_ACPI=y
# CONFIG_DEBUG_GPIO is not set
CONFIG_GPIO_SYSFS=y
CONFIG_GPIO_ICH=m
# CONFIG_GPIO_VX855 is not set
# CONFIG_GPIO_LYNXPOINT is not set
-# CONFIG_GPIO_GRGPIO is not set
#
# I2C GPIO expanders:
# CONFIG_GPIO_PCA953X is not set
# CONFIG_GPIO_PCF857X is not set
# CONFIG_GPIO_ADP5588 is not set
-CONFIG_GPIO_ADNP=m
#
# PCI GPIO expanders:
#
-CONFIG_GPIO_CS5535=y
+# CONFIG_GPIO_CS5535 is not set
# CONFIG_GPIO_AMD8111 is not set
# CONFIG_GPIO_LANGWELL is not set
# CONFIG_GPIO_PCH is not set
# CONFIG_GPIO_ML_IOH is not set
-# CONFIG_GPIO_SODAVILLE is not set
# CONFIG_GPIO_RDC321X is not set
#
# CONFIG_BATTERY_DS2780 is not set
# CONFIG_BATTERY_DS2781 is not set
# CONFIG_BATTERY_DS2782 is not set
-CONFIG_BATTERY_OLPC=y
# CONFIG_BATTERY_SBS is not set
# CONFIG_BATTERY_BQ27x00 is not set
# CONFIG_BATTERY_MAX17040 is not set
# CONFIG_CHARGER_SMB347 is not set
# CONFIG_BATTERY_GOLDFISH is not set
CONFIG_POWER_RESET=y
-CONFIG_POWER_RESET_GPIO=y
CONFIG_POWER_AVS=y
CONFIG_HWMON=y
CONFIG_HWMON_VID=m
CONFIG_HP_WATCHDOG=m
CONFIG_HPWDT_NMI_DECODING=y
# CONFIG_SC1200_WDT is not set
+# CONFIG_SCx200_WDT is not set
# CONFIG_PC87413_WDT is not set
CONFIG_NV_TCO=m
# CONFIG_60XX_WDT is not set
CONFIG_MACHZ_WDT=m
# CONFIG_SBC_EPX_C3_WATCHDOG is not set
+#
+# ISA-based Watchdog Cards
+#
+# CONFIG_PCWATCHDOG is not set
+# CONFIG_MIXCOMWD is not set
+# CONFIG_WDT is not set
+
#
# PCI-based Watchdog Cards
#
CONFIG_SSB_PCIHOST_POSSIBLE=y
CONFIG_SSB_PCIHOST=y
CONFIG_SSB_B43_PCI_BRIDGE=y
+CONFIG_SSB_PCMCIAHOST_POSSIBLE=y
+CONFIG_SSB_PCMCIAHOST=y
CONFIG_SSB_SDIOHOST_POSSIBLE=y
CONFIG_SSB_SDIOHOST=y
-# CONFIG_SSB_SILENT is not set
-# CONFIG_SSB_DEBUG is not set
+CONFIG_SSB_SILENT=y
CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y
CONFIG_SSB_DRIVER_PCICORE=y
CONFIG_SSB_DRIVER_GPIO=y
#
# Multifunction device drivers
#
-CONFIG_MFD_CORE=y
+CONFIG_MFD_CORE=m
CONFIG_MFD_CS5535=m
# CONFIG_MFD_CROS_EC is not set
# CONFIG_MFD_MC13XXX_I2C is not set
# Media drivers
#
CONFIG_RC_CORE=y
-# CONFIG_RC_MAP is not set
+CONFIG_RC_MAP=m
CONFIG_RC_DECODERS=y
CONFIG_LIRC=m
CONFIG_IR_LIRC_CODEC=m
CONFIG_IR_SANYO_DECODER=m
CONFIG_IR_MCE_KBD_DECODER=m
CONFIG_RC_DEVICES=y
-# CONFIG_RC_ATI_REMOTE is not set
+CONFIG_RC_ATI_REMOTE=m
CONFIG_IR_ENE=m
CONFIG_IR_IMON=m
CONFIG_IR_MCEUSB=m
CONFIG_USB_GSPCA_STV0680=m
CONFIG_USB_GSPCA_SUNPLUS=m
CONFIG_USB_GSPCA_T613=m
-# CONFIG_USB_GSPCA_TOPRO is not set
+CONFIG_USB_GSPCA_TOPRO=m
CONFIG_USB_GSPCA_TV8532=m
CONFIG_USB_GSPCA_VC032X=m
CONFIG_USB_GSPCA_VICAM=m
CONFIG_USB_ZR364XX=m
CONFIG_USB_STKWEBCAM=m
CONFIG_USB_S2255=m
-# CONFIG_USB_SN9C102 is not set
+CONFIG_USB_SN9C102=m
#
# Analog TV USB devices
#
-# CONFIG_VIDEO_PVRUSB2 is not set
-# CONFIG_VIDEO_HDPVR is not set
-# CONFIG_VIDEO_TLG2300 is not set
-# CONFIG_VIDEO_USBVISION is not set
-# CONFIG_VIDEO_STK1160 is not set
+CONFIG_VIDEO_PVRUSB2=m
+CONFIG_VIDEO_PVRUSB2_SYSFS=y
+CONFIG_VIDEO_PVRUSB2_DVB=y
+# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set
+CONFIG_VIDEO_HDPVR=m
+CONFIG_VIDEO_TLG2300=m
+CONFIG_VIDEO_USBVISION=m
+CONFIG_VIDEO_STK1160=m
+CONFIG_VIDEO_STK1160_AC97=y
#
# Analog/digital TV USB devices
CONFIG_DVB_USB_OPERA1=m
CONFIG_DVB_USB_AF9005=m
CONFIG_DVB_USB_AF9005_REMOTE=m
-# CONFIG_DVB_USB_PCTV452E is not set
+CONFIG_DVB_USB_PCTV452E=m
CONFIG_DVB_USB_DW2102=m
CONFIG_DVB_USB_CINERGY_T2=m
CONFIG_DVB_USB_DTV5100=m
CONFIG_DVB_USB_CE6230=m
CONFIG_DVB_USB_EC168=m
CONFIG_DVB_USB_GL861=m
-# CONFIG_DVB_USB_IT913X is not set
+CONFIG_DVB_USB_IT913X=m
CONFIG_DVB_USB_LME2510=m
-# CONFIG_DVB_USB_MXL111SF is not set
+CONFIG_DVB_USB_MXL111SF=m
CONFIG_DVB_USB_RTL28XXU=m
+CONFIG_DVB_USB_DVBSKY=m
CONFIG_DVB_TTUSB_BUDGET=m
CONFIG_DVB_TTUSB_DEC=m
CONFIG_SMS_USB_DRV=m
#
# Media capture/analog TV support
#
-# CONFIG_VIDEO_IVTV is not set
-# CONFIG_VIDEO_ZORAN is not set
-# CONFIG_VIDEO_HEXIUM_GEMINI is not set
-# CONFIG_VIDEO_HEXIUM_ORION is not set
-# CONFIG_VIDEO_MXB is not set
+CONFIG_VIDEO_IVTV=m
+CONFIG_VIDEO_IVTV_ALSA=m
+CONFIG_VIDEO_FB_IVTV=m
+CONFIG_VIDEO_ZORAN=m
+CONFIG_VIDEO_ZORAN_DC30=m
+CONFIG_VIDEO_ZORAN_ZR36060=m
+CONFIG_VIDEO_ZORAN_BUZ=m
+CONFIG_VIDEO_ZORAN_DC10=m
+CONFIG_VIDEO_ZORAN_LML33=m
+CONFIG_VIDEO_ZORAN_LML33R10=m
+CONFIG_VIDEO_ZORAN_AVS6EYES=m
+CONFIG_VIDEO_HEXIUM_GEMINI=m
+CONFIG_VIDEO_HEXIUM_ORION=m
+CONFIG_VIDEO_MXB=m
#
# Media capture/analog/hybrid TV support
CONFIG_DVB_MANTIS=m
CONFIG_DVB_HOPPER=m
CONFIG_DVB_NGENE=m
-# CONFIG_DVB_DDBRIDGE is not set
+CONFIG_DVB_DDBRIDGE=m
CONFIG_V4L_PLATFORM_DRIVERS=y
CONFIG_VIDEO_CAFE_CCIC=m
CONFIG_VIDEO_TIMBERDALE=m
#
CONFIG_VIDEO_TVAUDIO=m
CONFIG_VIDEO_TDA7432=m
+CONFIG_VIDEO_TDA9840=m
+CONFIG_VIDEO_TEA6415C=m
+CONFIG_VIDEO_TEA6420=m
CONFIG_VIDEO_MSP3400=m
CONFIG_VIDEO_CS5345=m
+CONFIG_VIDEO_CS53L32A=m
CONFIG_VIDEO_WM8775=m
+CONFIG_VIDEO_WM8739=m
+CONFIG_VIDEO_VP27SMPX=m
#
# RDS decoders
# Video decoders
#
CONFIG_VIDEO_ADV7180=m
+CONFIG_VIDEO_BT819=m
+CONFIG_VIDEO_BT856=m
+CONFIG_VIDEO_BT866=m
+CONFIG_VIDEO_KS0127=m
+CONFIG_VIDEO_SAA7110=m
CONFIG_VIDEO_SAA711X=m
CONFIG_VIDEO_TVP5150=m
+CONFIG_VIDEO_VPX3220=m
#
# Video and audio decoders
#
+CONFIG_VIDEO_SAA717X=m
CONFIG_VIDEO_CX25840=m
#
# Video encoders
#
+CONFIG_VIDEO_SAA7127=m
+CONFIG_VIDEO_SAA7185=m
+CONFIG_VIDEO_ADV7170=m
+CONFIG_VIDEO_ADV7175=m
#
# Camera sensor devices
#
# Video improvement chips
#
+CONFIG_VIDEO_UPD64031A=m
+CONFIG_VIDEO_UPD64083=m
#
# Miscelaneous helper chips
#
+CONFIG_VIDEO_M52790=m
#
# Sensors used on soc_camera driver
CONFIG_DVB_TDA826X=m
CONFIG_DVB_TUA6100=m
CONFIG_DVB_CX24116=m
+CONFIG_DVB_M88DS3103=m
+CONFIG_DVB_M88DC2800=m
CONFIG_DVB_SI21XX=m
CONFIG_DVB_TS2020=m
CONFIG_DVB_DS3000=m
CONFIG_DVB_BCM3510=m
CONFIG_DVB_LGDT330X=m
CONFIG_DVB_LGDT3305=m
+CONFIG_DVB_LG2160=m
CONFIG_DVB_S5H1409=m
CONFIG_DVB_AU8522=m
CONFIG_DVB_AU8522_DTV=m
# SEC control devices for DVB-S
#
CONFIG_DVB_LNBP21=m
+CONFIG_DVB_LNBP22=m
CONFIG_DVB_ISL6405=m
CONFIG_DVB_ISL6421=m
CONFIG_DVB_ISL6423=m
CONFIG_DVB_ATBM8830=m
CONFIG_DVB_TDA665x=m
CONFIG_DVB_IX2505V=m
+CONFIG_DVB_IT913X_FE=m
CONFIG_DVB_M88RS2000=m
CONFIG_DVB_AF9033=m
CONFIG_BACKLIGHT_CLASS_DEVICE=y
# CONFIG_BACKLIGHT_GENERIC is not set
# CONFIG_BACKLIGHT_LM3533 is not set
-CONFIG_BACKLIGHT_PWM=m
CONFIG_BACKLIGHT_APPLE=m
# CONFIG_BACKLIGHT_SAHARA is not set
# CONFIG_BACKLIGHT_ADP8860 is not set
# CONFIG_BACKLIGHT_LM3630 is not set
# CONFIG_BACKLIGHT_LM3639 is not set
# CONFIG_BACKLIGHT_LP855X is not set
-# CONFIG_BACKLIGHT_OT200 is not set
#
# Console display driver support
#
CONFIG_VGA_CONSOLE=y
# CONFIG_VGACON_SOFT_SCROLLBACK is not set
+# CONFIG_MDA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE=m
CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
# CONFIG_LOGO_LINUX_MONO is not set
# CONFIG_LOGO_LINUX_VGA16 is not set
CONFIG_LOGO_LINUX_CLUT224=y
-# CONFIG_FB_SSD1307 is not set
CONFIG_SOUND=m
CONFIG_SOUND_OSS_CORE=y
CONFIG_SOUND_OSS_CORE_PRECLAIM=y
CONFIG_SND_DMA_SGBUF=y
CONFIG_SND_RAWMIDI_SEQ=m
CONFIG_SND_OPL3_LIB_SEQ=m
-# CONFIG_SND_OPL4_LIB_SEQ is not set
-# CONFIG_SND_SBAWE_SEQ is not set
+CONFIG_SND_OPL4_LIB_SEQ=m
+CONFIG_SND_SBAWE_SEQ=m
CONFIG_SND_EMU10K1_SEQ=m
CONFIG_SND_MPU401_UART=m
CONFIG_SND_OPL3_LIB=m
+CONFIG_SND_OPL4_LIB=m
CONFIG_SND_VX_LIB=m
CONFIG_SND_AC97_CODEC=m
CONFIG_SND_DRIVERS=y
CONFIG_SND_PORTMAN2X4=m
CONFIG_SND_AC97_POWER_SAVE=y
CONFIG_SND_AC97_POWER_SAVE_DEFAULT=0
+CONFIG_SND_WSS_LIB=m
CONFIG_SND_SB_COMMON=m
+CONFIG_SND_SB8_DSP=m
CONFIG_SND_SB16_DSP=m
+CONFIG_SND_ISA=y
+CONFIG_SND_ADLIB=m
+CONFIG_SND_AD1816A=m
+CONFIG_SND_AD1848=m
+CONFIG_SND_ALS100=m
+CONFIG_SND_AZT1605=m
+CONFIG_SND_AZT2316=m
+CONFIG_SND_AZT2320=m
+CONFIG_SND_CMI8328=m
+CONFIG_SND_CMI8330=m
+CONFIG_SND_CS4231=m
+CONFIG_SND_CS4236=m
+CONFIG_SND_ES1688=m
+CONFIG_SND_ES18XX=m
+CONFIG_SND_SC6000=m
+CONFIG_SND_GUSCLASSIC=m
+CONFIG_SND_GUSEXTREME=m
+CONFIG_SND_GUSMAX=m
+CONFIG_SND_INTERWAVE=m
+CONFIG_SND_INTERWAVE_STB=m
+CONFIG_SND_JAZZ16=m
+CONFIG_SND_OPL3SA2=m
+CONFIG_SND_OPTI92X_AD1848=m
+CONFIG_SND_OPTI92X_CS4231=m
+CONFIG_SND_OPTI93X=m
+CONFIG_SND_MIRO=m
+CONFIG_SND_SB8=m
+CONFIG_SND_SB16=m
+CONFIG_SND_SBAWE=m
+CONFIG_SND_SB16_CSP=y
+CONFIG_SND_SSCAPE=m
+CONFIG_SND_WAVEFRONT=m
+CONFIG_SND_MSND_PINNACLE=m
+CONFIG_SND_MSND_CLASSIC=m
CONFIG_SND_TEA575X=m
CONFIG_SND_PCI=y
CONFIG_SND_AD1889=m
CONFIG_SND_FIREWIRE_SPEAKERS=m
# CONFIG_SND_ISIGHT is not set
# CONFIG_SND_SCS1X is not set
+CONFIG_SND_PCMCIA=y
+# CONFIG_SND_VXPOCKET is not set
+# CONFIG_SND_PDAUDIOCF is not set
# CONFIG_SND_SOC is not set
# CONFIG_SOUND_PRIME is not set
CONFIG_AC97_BUS=m
# CONFIG_USB_U132_HCD is not set
CONFIG_USB_SL811_HCD=m
CONFIG_USB_SL811_HCD_ISO=y
+# CONFIG_USB_SL811_CS is not set
# CONFIG_USB_R8A66597_HCD is not set
CONFIG_USB_WHCI_HCD=m
CONFIG_USB_HWA_HCD=m
CONFIG_MMC_SDHCI_PXAV2=m
CONFIG_MMC_WBSD=m
CONFIG_MMC_TIFM_SD=m
+# CONFIG_MMC_SDRICOH_CS is not set
CONFIG_MMC_CB710=m
CONFIG_MMC_VIA_SDMMC=m
CONFIG_MMC_VUB300=m
CONFIG_LEDS_CLEVO_MAIL=m
# CONFIG_LEDS_PCA955X is not set
CONFIG_LEDS_PCA9633=m
-CONFIG_LEDS_PWM=m
# CONFIG_LEDS_BD2802 is not set
CONFIG_LEDS_INTEL_SS4200=m
CONFIG_LEDS_LT3593=m
CONFIG_LEDS_TRIGGER_ONESHOT=m
CONFIG_LEDS_TRIGGER_HEARTBEAT=m
CONFIG_LEDS_TRIGGER_BACKLIGHT=m
-# CONFIG_LEDS_TRIGGER_CPU is not set
+CONFIG_LEDS_TRIGGER_CPU=y
CONFIG_LEDS_TRIGGER_GPIO=m
CONFIG_LEDS_TRIGGER_DEFAULT_ON=m
#
CONFIG_LEDS_TRIGGER_TRANSIENT=m
CONFIG_LEDS_TRIGGER_CAMERA=m
+CONFIG_LEDS_TRIGGER_NETDEV=m
# CONFIG_ACCESSIBILITY is not set
# CONFIG_INFINIBAND is not set
CONFIG_EDAC=y
#
# on-CPU RTC drivers
#
-CONFIG_RTC_DRV_SNVS=m
#
# HID Sensor RTC drivers
CONFIG_PCH_DMA=m
CONFIG_DMA_ENGINE=y
CONFIG_DMA_ACPI=y
-CONFIG_DMA_OF=y
#
# DMA Clients
# CONFIG_PRISM2_USB is not set
# CONFIG_ECHO is not set
# CONFIG_COMEDI is not set
-# CONFIG_FB_OLPC_DCON is not set
# CONFIG_ASUS_OLED is not set
# CONFIG_PANEL is not set
# CONFIG_R8187SE is not set
# CONFIG_IIO_SYSFS_TRIGGER is not set
# CONFIG_IIO_SIMPLE_DUMMY is not set
# CONFIG_ZSMALLOC is not set
+# CONFIG_WLAGS49_H2 is not set
+# CONFIG_WLAGS49_H25 is not set
# CONFIG_FB_SM7XX is not set
# CONFIG_CRYSTALHD is not set
# CONFIG_FB_XGI is not set
CONFIG_ACPI_CMPC=m
CONFIG_INTEL_IPS=m
# CONFIG_IBM_RTL is not set
-CONFIG_XO1_RFKILL=m
# CONFIG_XO15_EBOOK is not set
CONFIG_SAMSUNG_LAPTOP=m
CONFIG_MXM_WMI=m
# Common Clock Framework
#
# CONFIG_COMMON_CLK_DEBUG is not set
-# CONFIG_COMMON_CLK_SI5351 is not set
#
# Hardware Spinlock drivers
CONFIG_MAILBOX=y
CONFIG_IOMMU_API=y
CONFIG_IOMMU_SUPPORT=y
-CONFIG_OF_IOMMU=y
CONFIG_DMAR_TABLE=y
CONFIG_INTEL_IOMMU=y
# CONFIG_INTEL_IOMMU_DEFAULT_ON is not set
#
# Analog to digital converters
#
-# CONFIG_EXYNOS_ADC is not set
# CONFIG_MAX1363 is not set
# CONFIG_TI_ADC081C is not set
# CONFIG_VIPERBOARD_ADC is not set
# CONFIG_HID_SENSOR_MAGNETOMETER_3D is not set
# CONFIG_IIO_ST_MAGN_3AXIS is not set
# CONFIG_VME_BUS is not set
-CONFIG_PWM=y
-CONFIG_IRQCHIP=y
+# CONFIG_PWM is not set
# CONFIG_IPACK_BUS is not set
# CONFIG_RESET_CONTROLLER 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_ATOMIC_SLEEP is not set
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
CONFIG_STACKTRACE=y
CONFIG_PAX_MPROTECT=y
# CONFIG_PAX_MPROTECT_COMPAT is not set
CONFIG_PAX_ELFRELOCS=y
-CONFIG_PAX_KERNEXEC=y
+# CONFIG_PAX_KERNEXEC is not set
CONFIG_PAX_KERNEXEC_PLUGIN_METHOD=""
-CONFIG_PAX_KERNEXEC_MODULE_TEXT=4
#
# Address Space Layout Randomization
#
CONFIG_PAX_MEMORY_STACKLEAK=y
CONFIG_PAX_MEMORY_STRUCTLEAK=y
-CONFIG_PAX_MEMORY_UDEREF=y
+# CONFIG_PAX_MEMORY_UDEREF is not set
CONFIG_PAX_REFCOUNT=y
-CONFIG_PAX_CONSTIFY_PLUGIN=y
CONFIG_PAX_USERCOPY=y
# CONFIG_PAX_USERCOPY_DEBUG is not set
# CONFIG_PAX_SIZE_OVERFLOW is not set
# CONFIG_GRKERNSEC_ROFS is not set
CONFIG_GRKERNSEC_DEVICE_SIDECHANNEL=y
CONFIG_GRKERNSEC_CHROOT=y
-CONFIG_GRKERNSEC_CHROOT_MOUNT=y
+# CONFIG_GRKERNSEC_CHROOT_MOUNT is not set
CONFIG_GRKERNSEC_CHROOT_DOUBLE=y
CONFIG_GRKERNSEC_CHROOT_PIVOT=y
CONFIG_GRKERNSEC_CHROOT_CHDIR=y
CONFIG_GRKERNSEC_NO_SIMULT_CONNECT=y
# CONFIG_GRKERNSEC_SOCKET is not set
+#
+# Physical Protections
+#
+# CONFIG_GRKERNSEC_DENYUSB is not set
+
#
# Sysctl Support
#
CONFIG_CRYPTO_DEV_PADLOCK_AES=m
CONFIG_CRYPTO_DEV_PADLOCK_SHA=m
CONFIG_CRYPTO_DEV_GEODE=m
-# CONFIG_CRYPTO_DEV_HIFN_795X is not set
+CONFIG_CRYPTO_DEV_HIFN_795X=m
+CONFIG_CRYPTO_DEV_HIFN_795X_RNG=y
CONFIG_ASYMMETRIC_KEY_TYPE=m
CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=m
CONFIG_PUBLIC_KEY_ALGO_RSA=m
#
# Automatically generated file; DO NOT EDIT.
-# Linux/x86 3.10.9 Kernel Configuration
+# Linux/x86 3.10.10 Kernel Configuration
#
# CONFIG_64BIT is not set
CONFIG_X86_32=y
CONFIG_PCI_IOAPIC=y
CONFIG_PCI_LABEL=y
CONFIG_ISA_DMA_API=y
-# CONFIG_ISA is not set
+CONFIG_ISA=y
+CONFIG_EISA=y
+# CONFIG_EISA_VLB_PRIMING is not set
+CONFIG_EISA_PCI_EISA=y
+CONFIG_EISA_VIRTUAL_ROOT=y
+CONFIG_EISA_NAMES=y
# CONFIG_SCx200 is not set
# CONFIG_ALIX is not set
# CONFIG_NET5501 is not set
# CONFIG_GEOS is not set
CONFIG_AMD_NB=y
CONFIG_PCCARD=m
-# CONFIG_PCMCIA is not set
+CONFIG_PCMCIA=m
+CONFIG_PCMCIA_LOAD_CIS=y
CONFIG_CARDBUS=y
#
CONFIG_YENTA_TI=y
CONFIG_YENTA_ENE_TUNE=y
CONFIG_YENTA_TOSHIBA=y
+CONFIG_PD6729=m
+CONFIG_I82092=m
+CONFIG_I82365=m
+CONFIG_TCIC=m
+CONFIG_PCMCIA_PROBE=y
+CONFIG_PCCARD_NONSTATIC=y
CONFIG_HOTPLUG_PCI=y
# CONFIG_HOTPLUG_PCI_COMPAQ is not set
# CONFIG_HOTPLUG_PCI_IBM is not set
CONFIG_BT_HCIBCM203X=m
CONFIG_BT_HCIBPA10X=m
CONFIG_BT_HCIBFUSB=m
+# CONFIG_BT_HCIDTL1 is not set
+# CONFIG_BT_HCIBT3C is not set
+CONFIG_BT_HCIBLUECARD=m
+CONFIG_BT_HCIBTUART=m
CONFIG_BT_HCIVHCI=m
CONFIG_BT_MRVL=m
CONFIG_BT_MRVL_SDIO=m
CONFIG_PARPORT=m
CONFIG_PARPORT_PC=m
CONFIG_PARPORT_SERIAL=m
-# CONFIG_PARPORT_PC_FIFO is not set
-# CONFIG_PARPORT_PC_SUPERIO is not set
+CONFIG_PARPORT_PC_FIFO=y
+CONFIG_PARPORT_PC_SUPERIO=y
+CONFIG_PARPORT_PC_PCMCIA=m
# CONFIG_PARPORT_GSC is not set
-# CONFIG_PARPORT_AX88796 is not set
+CONFIG_PARPORT_AX88796=m
CONFIG_PARPORT_1284=y
CONFIG_PARPORT_NOT_PC=y
CONFIG_PNP=y
#
# Protocols
#
+CONFIG_ISAPNP=y
+CONFIG_PNPBIOS=y
+# CONFIG_PNPBIOS_PROC_FS is not set
CONFIG_PNPACPI=y
CONFIG_BLK_DEV=y
CONFIG_BLK_DEV_FD=m
CONFIG_SCSI_HPSA=m
CONFIG_SCSI_3W_9XXX=m
CONFIG_SCSI_3W_SAS=m
+CONFIG_SCSI_7000FASST=m
CONFIG_SCSI_ACARD=m
+CONFIG_SCSI_AHA152X=m
+CONFIG_SCSI_AHA1542=m
+CONFIG_SCSI_AHA1740=m
CONFIG_SCSI_AACRAID=m
CONFIG_SCSI_AIC7XXX=m
CONFIG_AIC7XXX_CMDS_PER_DEVICE=32
CONFIG_SCSI_MVSAS=m
# CONFIG_SCSI_MVSAS_DEBUG is not set
CONFIG_SCSI_MVSAS_TASKLET=y
-# CONFIG_SCSI_MVUMI is not set
+CONFIG_SCSI_MVUMI=m
CONFIG_SCSI_DPT_I2O=m
CONFIG_SCSI_ADVANSYS=m
+CONFIG_SCSI_IN2000=m
CONFIG_SCSI_ARCMSR=m
CONFIG_MEGARAID_NEWGEN=y
CONFIG_MEGARAID_MM=m
CONFIG_FCOE=m
CONFIG_FCOE_FNIC=m
CONFIG_SCSI_DMX3191D=m
+CONFIG_SCSI_DTC3280=m
CONFIG_SCSI_EATA=m
CONFIG_SCSI_EATA_TAGGED_QUEUE=y
# CONFIG_SCSI_EATA_LINKED_COMMANDS is not set
CONFIG_SCSI_FUTURE_DOMAIN=m
CONFIG_SCSI_GDTH=m
CONFIG_SCSI_ISCI=m
+CONFIG_SCSI_GENERIC_NCR5380=m
+CONFIG_SCSI_GENERIC_NCR5380_MMIO=m
+# CONFIG_SCSI_GENERIC_NCR53C400 is not set
CONFIG_SCSI_IPS=m
CONFIG_SCSI_INITIO=m
CONFIG_SCSI_INIA100=m
CONFIG_SCSI_IMM=m
# CONFIG_SCSI_IZIP_EPP16 is not set
# CONFIG_SCSI_IZIP_SLOW_CTR is not set
+CONFIG_SCSI_NCR53C406A=m
CONFIG_SCSI_STEX=m
CONFIG_SCSI_SYM53C8XX_2=m
CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
CONFIG_SCSI_IPR=m
CONFIG_SCSI_IPR_TRACE=y
CONFIG_SCSI_IPR_DUMP=y
+CONFIG_SCSI_PAS16=m
+CONFIG_SCSI_QLOGIC_FAS=m
CONFIG_SCSI_QLOGIC_1280=m
CONFIG_SCSI_QLA_FC=m
CONFIG_SCSI_QLA_ISCSI=m
CONFIG_SCSI_LPFC=m
# CONFIG_SCSI_LPFC_DEBUG_FS is not set
+CONFIG_SCSI_SIM710=m
+CONFIG_SCSI_SYM53C416=m
CONFIG_SCSI_DC395x=m
CONFIG_SCSI_DC390T=m
-# CONFIG_SCSI_NSP32 is not set
+CONFIG_SCSI_T128=m
+CONFIG_SCSI_U14_34F=m
+# CONFIG_SCSI_U14_34F_TAGGED_QUEUE is not set
+# CONFIG_SCSI_U14_34F_LINKED_COMMANDS is not set
+CONFIG_SCSI_U14_34F_MAX_TAGS=8
+CONFIG_SCSI_ULTRASTOR=m
+CONFIG_SCSI_NSP32=m
# CONFIG_SCSI_DEBUG is not set
CONFIG_SCSI_PMCRAID=m
CONFIG_SCSI_PM8001=m
CONFIG_SCSI_BFA_FC=m
CONFIG_SCSI_VIRTIO=m
CONFIG_SCSI_CHELSIO_FCOE=m
+CONFIG_SCSI_LOWLEVEL_PCMCIA=y
+CONFIG_PCMCIA_AHA152X=m
+CONFIG_PCMCIA_FDOMAIN=m
+CONFIG_PCMCIA_NINJA_SCSI=m
+CONFIG_PCMCIA_QLOGIC=m
+CONFIG_PCMCIA_SYM53C500=m
CONFIG_SCSI_DH=y
CONFIG_SCSI_DH_RDAC=m
CONFIG_SCSI_DH_HP_SW=m
# CONFIG_ATA_NONSTANDARD is not set
CONFIG_ATA_VERBOSE_ERROR=y
CONFIG_ATA_ACPI=y
-# CONFIG_SATA_ZPODD is not set
+CONFIG_SATA_ZPODD=y
CONFIG_SATA_PMP=y
#
CONFIG_PATA_OPTIDMA=m
CONFIG_PATA_PDC2027X=m
CONFIG_PATA_PDC_OLD=m
-# CONFIG_PATA_RADISYS is not set
+CONFIG_PATA_RADISYS=m
CONFIG_PATA_RDC=m
-# CONFIG_PATA_SC1200 is not set
+CONFIG_PATA_SC1200=m
CONFIG_PATA_SCH=m
CONFIG_PATA_SERVERWORKS=m
CONFIG_PATA_SIL680=m
# PIO-only SFF controllers
#
CONFIG_PATA_CMD640_PCI=m
+CONFIG_PATA_ISAPNP=m
CONFIG_PATA_MPIIX=m
CONFIG_PATA_NS87410=m
CONFIG_PATA_OPTI=m
-# CONFIG_PATA_PLATFORM is not set
+CONFIG_PATA_PCMCIA=m
+CONFIG_PATA_PLATFORM=m
+CONFIG_PATA_QDI=m
CONFIG_PATA_RZ1000=m
+CONFIG_PATA_WINBOND_VLB=m
#
# Generic fallback / legacy drivers
#
CONFIG_PATA_ACPI=m
CONFIG_ATA_GENERIC=m
-# CONFIG_PATA_LEGACY is not set
+CONFIG_PATA_LEGACY=m
CONFIG_MD=y
CONFIG_BLK_DEV_MD=y
CONFIG_MD_AUTODETECT=y
# CONFIG_ATM_ENI_DEBUG is not set
# CONFIG_ATM_ENI_TUNE_BURST is not set
CONFIG_ATM_FIRESTREAM=m
-# CONFIG_ATM_ZATM is not set
+CONFIG_ATM_ZATM=m
+# CONFIG_ATM_ZATM_DEBUG is not set
CONFIG_ATM_NICSTAR=m
# CONFIG_ATM_NICSTAR_USE_SUNI is not set
# CONFIG_ATM_NICSTAR_USE_IDT77105 is not set
# CONFIG_ATM_IDT77252_DEBUG is not set
# CONFIG_ATM_IDT77252_RCV_ALL is not set
CONFIG_ATM_IDT77252_USE_SUNI=y
-# CONFIG_ATM_AMBASSADOR is not set
-# CONFIG_ATM_HORIZON is not set
-# CONFIG_ATM_IA is not set
-# CONFIG_ATM_FORE200E is not set
+CONFIG_ATM_AMBASSADOR=m
+# CONFIG_ATM_AMBASSADOR_DEBUG is not set
+CONFIG_ATM_HORIZON=m
+# CONFIG_ATM_HORIZON_DEBUG is not set
+CONFIG_ATM_IA=m
+# CONFIG_ATM_IA_DEBUG is not set
+CONFIG_ATM_FORE200E=m
+# CONFIG_ATM_FORE200E_USE_TASKLET is not set
+CONFIG_ATM_FORE200E_TX_RETRY=16
+CONFIG_ATM_FORE200E_DEBUG=0
CONFIG_ATM_HE=m
# CONFIG_ATM_HE_USE_SUNI is not set
CONFIG_ATM_SOLOS=m
CONFIG_ETHERNET=y
CONFIG_MDIO=m
CONFIG_NET_VENDOR_3COM=y
+CONFIG_EL3=m
+CONFIG_3C515=m
+CONFIG_PCMCIA_3C574=m
+CONFIG_PCMCIA_3C589=m
CONFIG_VORTEX=m
CONFIG_TYPHOON=m
CONFIG_NET_VENDOR_ADAPTEC=y
# CONFIG_ACENIC_OMIT_TIGON_I is not set
CONFIG_NET_VENDOR_AMD=y
CONFIG_AMD8111_ETH=m
+CONFIG_LANCE=m
CONFIG_PCNET32=m
+CONFIG_PCMCIA_NMCLAN=m
+CONFIG_NI65=m
CONFIG_NET_VENDOR_ATHEROS=y
CONFIG_ATL2=m
CONFIG_ATL1=m
CONFIG_CHELSIO_T3=m
CONFIG_CHELSIO_T4=m
CONFIG_CHELSIO_T4VF=m
+CONFIG_NET_VENDOR_CIRRUS=y
+CONFIG_CS89x0=m
+# CONFIG_CS89x0_PLATFORM is not set
CONFIG_NET_VENDOR_CISCO=y
CONFIG_ENIC=m
CONFIG_DNET=m
CONFIG_S2IO=m
CONFIG_VXGE=m
# CONFIG_VXGE_DEBUG_TRACE_ALL is not set
+CONFIG_NET_VENDOR_FUJITSU=y
+CONFIG_PCMCIA_FMVJ18X=m
CONFIG_NET_VENDOR_HP=y
CONFIG_HP100=m
CONFIG_NET_VENDOR_INTEL=y
CONFIG_MLX4_CORE=m
CONFIG_MLX4_DEBUG=y
CONFIG_NET_VENDOR_MICREL=y
-# CONFIG_KS8842 is not set
-# CONFIG_KS8851_MLL is not set
+CONFIG_KS8842=m
+CONFIG_KS8851_MLL=m
CONFIG_KSZ884X_PCI=m
CONFIG_NET_VENDOR_MYRI=y
CONFIG_MYRI10GE=m
CONFIG_NATSEMI=m
CONFIG_NS83820=m
CONFIG_NET_VENDOR_8390=y
+CONFIG_PCMCIA_AXNET=m
+CONFIG_NE2000=m
CONFIG_NE2K_PCI=m
+CONFIG_PCMCIA_PCNET=m
+CONFIG_ULTRA=m
+CONFIG_WD80x3=m
CONFIG_NET_VENDOR_NVIDIA=y
CONFIG_FORCEDETH=m
CONFIG_NET_VENDOR_OKI=y
CONFIG_SFC_MCDI_MON=y
CONFIG_SFC_SRIOV=y
CONFIG_NET_VENDOR_SMSC=y
+CONFIG_SMC9194=m
+CONFIG_PCMCIA_SMC91C92=m
CONFIG_EPIC100=m
CONFIG_SMSC9420=m
CONFIG_NET_VENDOR_STMICRO=y
# CONFIG_WIZNET_BUS_DIRECT is not set
# CONFIG_WIZNET_BUS_INDIRECT is not set
CONFIG_WIZNET_BUS_ANY=y
+CONFIG_NET_VENDOR_XIRCOM=y
+CONFIG_PCMCIA_XIRC2PS=m
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
# CONFIG_NET_SB1000 is not set
CONFIG_USB_SIERRA_NET=m
CONFIG_USB_VL600=m
CONFIG_WLAN=y
+# CONFIG_PCMCIA_RAYCS is not set
CONFIG_LIBERTAS_THINFIRM=m
# CONFIG_LIBERTAS_THINFIRM_DEBUG is not set
CONFIG_LIBERTAS_THINFIRM_USB=m
CONFIG_AIRO=m
CONFIG_ATMEL=m
CONFIG_PCI_ATMEL=m
+CONFIG_PCMCIA_ATMEL=m
CONFIG_AT76C50X_USB=m
+CONFIG_AIRO_CS=m
+CONFIG_PCMCIA_WL3501=m
# CONFIG_PRISM54 is not set
CONFIG_USB_ZD1201=m
CONFIG_USB_NET_RNDIS_WLAN=m
CONFIG_B43_SSB=y
CONFIG_B43_PCI_AUTOSELECT=y
CONFIG_B43_PCICORE_AUTOSELECT=y
+# CONFIG_B43_PCMCIA is not set
CONFIG_B43_SDIO=y
CONFIG_B43_PIO=y
CONFIG_B43_PHY_N=y
CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y
# CONFIG_B43LEGACY_DMA_MODE is not set
# CONFIG_B43LEGACY_PIO_MODE is not set
-# CONFIG_BRCMFMAC is not set
+CONFIG_BRCMUTIL=m
+CONFIG_BRCMFMAC=m
+CONFIG_BRCMFMAC_SDIO=y
+# CONFIG_BRCMFMAC_USB is not set
+# CONFIG_BRCM_TRACING is not set
+# CONFIG_BRCMDBG is not set
CONFIG_HOSTAP=m
CONFIG_HOSTAP_FIRMWARE=y
CONFIG_HOSTAP_FIRMWARE_NVRAM=y
CONFIG_HOSTAP_PLX=m
CONFIG_HOSTAP_PCI=m
+CONFIG_HOSTAP_CS=m
CONFIG_IPW2100=m
CONFIG_IPW2100_MONITOR=y
# CONFIG_IPW2100_DEBUG is not set
# CONFIG_IPW2200_DEBUG is not set
CONFIG_LIBIPW=m
# CONFIG_LIBIPW_DEBUG is not set
-# CONFIG_IWLWIFI is not set
+CONFIG_IWLWIFI=m
+CONFIG_IWLDVM=m
+CONFIG_IWLMVM=m
+CONFIG_IWLWIFI_OPMODE_MODULAR=y
+
+#
+# Debugging Options
+#
+# CONFIG_IWLWIFI_DEBUG is not set
+# CONFIG_IWLWIFI_DEVICE_TRACING is not set
+CONFIG_IWLWIFI_P2P=y
CONFIG_IWLEGACY=m
CONFIG_IWL4965=m
CONFIG_IWL3945=m
# CONFIG_IWLEGACY_DEBUG is not set
CONFIG_LIBERTAS=m
CONFIG_LIBERTAS_USB=m
+CONFIG_LIBERTAS_CS=m
CONFIG_LIBERTAS_SDIO=m
# CONFIG_LIBERTAS_DEBUG is not set
CONFIG_LIBERTAS_MESH=y
CONFIG_PLX_HERMES=m
CONFIG_TMD_HERMES=m
CONFIG_NORTEL_HERMES=m
+CONFIG_PCMCIA_HERMES=m
+CONFIG_PCMCIA_SPECTRUM=m
CONFIG_ORINOCO_USB=m
CONFIG_P54_COMMON=m
CONFIG_P54_USB=m
# CONFIG_ZD1211RW_DEBUG is not set
CONFIG_MWIFIEX=m
CONFIG_MWIFIEX_SDIO=m
-# CONFIG_MWIFIEX_PCIE is not set
+CONFIG_MWIFIEX_PCIE=m
CONFIG_MWIFIEX_USB=m
#
#
# HiSax supported cards
#
+# CONFIG_HISAX_16_0 is not set
CONFIG_HISAX_16_3=y
CONFIG_HISAX_TELESPCI=y
CONFIG_HISAX_S0BOX=y
+# CONFIG_HISAX_AVM_A1 is not set
CONFIG_HISAX_FRITZPCI=y
CONFIG_HISAX_AVM_A1_PCMCIA=y
CONFIG_HISAX_ELSA=y
+# CONFIG_HISAX_IX1MICROR2 is not set
CONFIG_HISAX_DIEHLDIVA=y
+# CONFIG_HISAX_ASUSCOM is not set
+# CONFIG_HISAX_TELEINT is not set
+# CONFIG_HISAX_HFCS is not set
CONFIG_HISAX_SEDLBAUER=y
+# CONFIG_HISAX_SPORTSTER is not set
+# CONFIG_HISAX_MIC is not set
CONFIG_HISAX_NETJET=y
CONFIG_HISAX_NETJET_U=y
CONFIG_HISAX_NICCY=y
+# CONFIG_HISAX_ISURF is not set
+# CONFIG_HISAX_HSTSAPHIR is not set
CONFIG_HISAX_BKM_A4T=y
CONFIG_HISAX_SCT_QUADRO=y
CONFIG_HISAX_GAZEL=y
#
# HiSax PCMCIA card service modules
#
+# CONFIG_HISAX_SEDLBAUER_CS is not set
+# CONFIG_HISAX_ELSA_CS is not set
+# CONFIG_HISAX_AVM_A1_CS is not set
+# CONFIG_HISAX_TELES_CS is not set
#
# HiSax sub driver modules
#
# Active cards
#
+# CONFIG_ISDN_DRV_ICN is not set
+# CONFIG_ISDN_DRV_PCBIT is not set
+# CONFIG_ISDN_DRV_SC is not set
+# CONFIG_ISDN_DRV_ACT2000 is not set
CONFIG_ISDN_CAPI=m
CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y
CONFIG_CAPI_TRACE=y
# CAPI hardware drivers
#
CONFIG_CAPI_AVM=y
+# CONFIG_ISDN_DRV_AVMB1_B1ISA is not set
CONFIG_ISDN_DRV_AVMB1_B1PCI=m
CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y
+# CONFIG_ISDN_DRV_AVMB1_T1ISA is not set
+# CONFIG_ISDN_DRV_AVMB1_B1PCMCIA is not set
CONFIG_ISDN_DRV_AVMB1_T1PCI=m
CONFIG_ISDN_DRV_AVMB1_C4=m
CONFIG_CAPI_EICON=y
CONFIG_MOUSE_APPLETOUCH=m
CONFIG_MOUSE_BCM5974=m
CONFIG_MOUSE_CYAPA=m
+# CONFIG_MOUSE_INPORT is not set
+# CONFIG_MOUSE_LOGIBM is not set
+# CONFIG_MOUSE_PC110PAD is not set
CONFIG_MOUSE_VSXXXAA=m
# CONFIG_MOUSE_GPIO is not set
CONFIG_MOUSE_SYNAPTICS_I2C=m
CONFIG_FIX_EARLYCON_MEM=y
CONFIG_SERIAL_8250_DMA=y
CONFIG_SERIAL_8250_PCI=y
+# CONFIG_SERIAL_8250_CS is not set
CONFIG_SERIAL_8250_NR_UARTS=4
CONFIG_SERIAL_8250_RUNTIME_UARTS=4
CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y
+# CONFIG_SERIAL_8250_FOURPORT is not set
+# CONFIG_SERIAL_8250_ACCENT is not set
+# CONFIG_SERIAL_8250_BOCA is not set
+# CONFIG_SERIAL_8250_EXAR_ST16C554 is not set
+# CONFIG_SERIAL_8250_HUB6 is not set
CONFIG_SERIAL_8250_SHARE_IRQ=y
# CONFIG_SERIAL_8250_DETECT_IRQ is not set
CONFIG_SERIAL_8250_RSA=y
CONFIG_HW_RANDOM_VIRTIO=m
CONFIG_HW_RANDOM_EXYNOS=m
CONFIG_NVRAM=y
+# CONFIG_DTLK is not set
CONFIG_R3964=m
# CONFIG_APPLICOM is not set
CONFIG_SONYPI=m
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+# CONFIG_CARDMAN_4000 is not set
+# CONFIG_CARDMAN_4040 is not set
+# CONFIG_IPWIRELESS is not set
CONFIG_MWAVE=m
CONFIG_PC8736x_GPIO=m
CONFIG_NSC_GPIO=m
#
# Other I2C/SMBus bus drivers
#
+# CONFIG_I2C_PCA_ISA is not set
CONFIG_SCx200_ACB=m
CONFIG_I2C_STUB=m
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_SBC_EPX_C3_WATCHDOG is not set
CONFIG_XEN_WDT=m
+#
+# ISA-based Watchdog Cards
+#
+# CONFIG_PCWATCHDOG is not set
+# CONFIG_MIXCOMWD is not set
+# CONFIG_WDT is not set
+
#
# PCI-based Watchdog Cards
#
CONFIG_SSB_PCIHOST_POSSIBLE=y
CONFIG_SSB_PCIHOST=y
CONFIG_SSB_B43_PCI_BRIDGE=y
+CONFIG_SSB_PCMCIAHOST_POSSIBLE=y
+CONFIG_SSB_PCMCIAHOST=y
CONFIG_SSB_SDIOHOST_POSSIBLE=y
CONFIG_SSB_SDIOHOST=y
-# CONFIG_SSB_SILENT is not set
-# CONFIG_SSB_DEBUG is not set
+CONFIG_SSB_SILENT=y
CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y
CONFIG_SSB_DRIVER_PCICORE=y
CONFIG_SSB_DRIVER_GPIO=y
# Media drivers
#
CONFIG_RC_CORE=y
-# CONFIG_RC_MAP is not set
+CONFIG_RC_MAP=m
CONFIG_RC_DECODERS=y
CONFIG_LIRC=m
CONFIG_IR_LIRC_CODEC=m
CONFIG_IR_SANYO_DECODER=m
CONFIG_IR_MCE_KBD_DECODER=m
CONFIG_RC_DEVICES=y
-# CONFIG_RC_ATI_REMOTE is not set
+CONFIG_RC_ATI_REMOTE=m
CONFIG_IR_ENE=m
CONFIG_IR_IMON=m
CONFIG_IR_MCEUSB=m
CONFIG_USB_GSPCA_STV0680=m
CONFIG_USB_GSPCA_SUNPLUS=m
CONFIG_USB_GSPCA_T613=m
-# CONFIG_USB_GSPCA_TOPRO is not set
+CONFIG_USB_GSPCA_TOPRO=m
CONFIG_USB_GSPCA_TV8532=m
CONFIG_USB_GSPCA_VC032X=m
CONFIG_USB_GSPCA_VICAM=m
CONFIG_USB_ZR364XX=m
CONFIG_USB_STKWEBCAM=m
CONFIG_USB_S2255=m
-# CONFIG_USB_SN9C102 is not set
+CONFIG_USB_SN9C102=m
#
# Analog TV USB devices
#
-# CONFIG_VIDEO_PVRUSB2 is not set
-# CONFIG_VIDEO_HDPVR is not set
-# CONFIG_VIDEO_TLG2300 is not set
-# CONFIG_VIDEO_USBVISION is not set
-# CONFIG_VIDEO_STK1160 is not set
+CONFIG_VIDEO_PVRUSB2=m
+CONFIG_VIDEO_PVRUSB2_SYSFS=y
+CONFIG_VIDEO_PVRUSB2_DVB=y
+# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set
+CONFIG_VIDEO_HDPVR=m
+CONFIG_VIDEO_TLG2300=m
+CONFIG_VIDEO_USBVISION=m
+CONFIG_VIDEO_STK1160=m
+CONFIG_VIDEO_STK1160_AC97=y
#
# Analog/digital TV USB devices
CONFIG_DVB_USB_OPERA1=m
CONFIG_DVB_USB_AF9005=m
CONFIG_DVB_USB_AF9005_REMOTE=m
-# CONFIG_DVB_USB_PCTV452E is not set
+CONFIG_DVB_USB_PCTV452E=m
CONFIG_DVB_USB_DW2102=m
CONFIG_DVB_USB_CINERGY_T2=m
CONFIG_DVB_USB_DTV5100=m
CONFIG_DVB_USB_CE6230=m
CONFIG_DVB_USB_EC168=m
CONFIG_DVB_USB_GL861=m
-# CONFIG_DVB_USB_IT913X is not set
+CONFIG_DVB_USB_IT913X=m
CONFIG_DVB_USB_LME2510=m
-# CONFIG_DVB_USB_MXL111SF is not set
+CONFIG_DVB_USB_MXL111SF=m
CONFIG_DVB_USB_RTL28XXU=m
+CONFIG_DVB_USB_DVBSKY=m
CONFIG_DVB_TTUSB_BUDGET=m
CONFIG_DVB_TTUSB_DEC=m
CONFIG_SMS_USB_DRV=m
#
# Media capture/analog TV support
#
-# CONFIG_VIDEO_IVTV is not set
-# CONFIG_VIDEO_ZORAN is not set
-# CONFIG_VIDEO_HEXIUM_GEMINI is not set
-# CONFIG_VIDEO_HEXIUM_ORION is not set
-# CONFIG_VIDEO_MXB is not set
+CONFIG_VIDEO_IVTV=m
+CONFIG_VIDEO_IVTV_ALSA=m
+CONFIG_VIDEO_FB_IVTV=m
+CONFIG_VIDEO_ZORAN=m
+CONFIG_VIDEO_ZORAN_DC30=m
+CONFIG_VIDEO_ZORAN_ZR36060=m
+CONFIG_VIDEO_ZORAN_BUZ=m
+CONFIG_VIDEO_ZORAN_DC10=m
+CONFIG_VIDEO_ZORAN_LML33=m
+CONFIG_VIDEO_ZORAN_LML33R10=m
+CONFIG_VIDEO_ZORAN_AVS6EYES=m
+CONFIG_VIDEO_HEXIUM_GEMINI=m
+CONFIG_VIDEO_HEXIUM_ORION=m
+CONFIG_VIDEO_MXB=m
#
# Media capture/analog/hybrid TV support
CONFIG_DVB_MANTIS=m
CONFIG_DVB_HOPPER=m
CONFIG_DVB_NGENE=m
-# CONFIG_DVB_DDBRIDGE is not set
+CONFIG_DVB_DDBRIDGE=m
CONFIG_V4L_PLATFORM_DRIVERS=y
CONFIG_VIDEO_CAFE_CCIC=m
CONFIG_VIDEO_TIMBERDALE=m
#
CONFIG_VIDEO_TVAUDIO=m
CONFIG_VIDEO_TDA7432=m
+CONFIG_VIDEO_TDA9840=m
+CONFIG_VIDEO_TEA6415C=m
+CONFIG_VIDEO_TEA6420=m
CONFIG_VIDEO_MSP3400=m
CONFIG_VIDEO_CS5345=m
+CONFIG_VIDEO_CS53L32A=m
CONFIG_VIDEO_WM8775=m
+CONFIG_VIDEO_WM8739=m
+CONFIG_VIDEO_VP27SMPX=m
#
# RDS decoders
# Video decoders
#
CONFIG_VIDEO_ADV7180=m
+CONFIG_VIDEO_BT819=m
+CONFIG_VIDEO_BT856=m
+CONFIG_VIDEO_BT866=m
+CONFIG_VIDEO_KS0127=m
+CONFIG_VIDEO_SAA7110=m
CONFIG_VIDEO_SAA711X=m
CONFIG_VIDEO_TVP5150=m
+CONFIG_VIDEO_VPX3220=m
#
# Video and audio decoders
#
+CONFIG_VIDEO_SAA717X=m
CONFIG_VIDEO_CX25840=m
#
# Video encoders
#
+CONFIG_VIDEO_SAA7127=m
+CONFIG_VIDEO_SAA7185=m
+CONFIG_VIDEO_ADV7170=m
+CONFIG_VIDEO_ADV7175=m
#
# Camera sensor devices
#
# Video improvement chips
#
+CONFIG_VIDEO_UPD64031A=m
+CONFIG_VIDEO_UPD64083=m
#
# Miscelaneous helper chips
#
+CONFIG_VIDEO_M52790=m
#
# Sensors used on soc_camera driver
CONFIG_DVB_TDA826X=m
CONFIG_DVB_TUA6100=m
CONFIG_DVB_CX24116=m
+CONFIG_DVB_M88DS3103=m
+CONFIG_DVB_M88DC2800=m
CONFIG_DVB_SI21XX=m
CONFIG_DVB_TS2020=m
CONFIG_DVB_DS3000=m
CONFIG_DVB_BCM3510=m
CONFIG_DVB_LGDT330X=m
CONFIG_DVB_LGDT3305=m
+CONFIG_DVB_LG2160=m
CONFIG_DVB_S5H1409=m
CONFIG_DVB_AU8522=m
CONFIG_DVB_AU8522_DTV=m
# SEC control devices for DVB-S
#
CONFIG_DVB_LNBP21=m
+CONFIG_DVB_LNBP22=m
CONFIG_DVB_ISL6405=m
CONFIG_DVB_ISL6421=m
CONFIG_DVB_ISL6423=m
CONFIG_DVB_ATBM8830=m
CONFIG_DVB_TDA665x=m
CONFIG_DVB_IX2505V=m
+CONFIG_DVB_IT913X_FE=m
CONFIG_DVB_M88RS2000=m
CONFIG_DVB_AF9033=m
#
CONFIG_VGA_CONSOLE=y
# CONFIG_VGACON_SOFT_SCROLLBACK is not set
+# CONFIG_MDA_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE=m
CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
CONFIG_SND_DMA_SGBUF=y
CONFIG_SND_RAWMIDI_SEQ=m
CONFIG_SND_OPL3_LIB_SEQ=m
-# CONFIG_SND_OPL4_LIB_SEQ is not set
-# CONFIG_SND_SBAWE_SEQ is not set
+CONFIG_SND_OPL4_LIB_SEQ=m
+CONFIG_SND_SBAWE_SEQ=m
CONFIG_SND_EMU10K1_SEQ=m
CONFIG_SND_MPU401_UART=m
CONFIG_SND_OPL3_LIB=m
+CONFIG_SND_OPL4_LIB=m
CONFIG_SND_VX_LIB=m
CONFIG_SND_AC97_CODEC=m
CONFIG_SND_DRIVERS=y
CONFIG_SND_PORTMAN2X4=m
CONFIG_SND_AC97_POWER_SAVE=y
CONFIG_SND_AC97_POWER_SAVE_DEFAULT=0
+CONFIG_SND_WSS_LIB=m
CONFIG_SND_SB_COMMON=m
+CONFIG_SND_SB8_DSP=m
CONFIG_SND_SB16_DSP=m
+CONFIG_SND_ISA=y
+CONFIG_SND_ADLIB=m
+CONFIG_SND_AD1816A=m
+CONFIG_SND_AD1848=m
+CONFIG_SND_ALS100=m
+CONFIG_SND_AZT1605=m
+CONFIG_SND_AZT2316=m
+CONFIG_SND_AZT2320=m
+CONFIG_SND_CMI8328=m
+CONFIG_SND_CMI8330=m
+CONFIG_SND_CS4231=m
+CONFIG_SND_CS4236=m
+CONFIG_SND_ES1688=m
+CONFIG_SND_ES18XX=m
+CONFIG_SND_SC6000=m
+CONFIG_SND_GUSCLASSIC=m
+CONFIG_SND_GUSEXTREME=m
+CONFIG_SND_GUSMAX=m
+CONFIG_SND_INTERWAVE=m
+CONFIG_SND_INTERWAVE_STB=m
+CONFIG_SND_JAZZ16=m
+CONFIG_SND_OPL3SA2=m
+CONFIG_SND_OPTI92X_AD1848=m
+CONFIG_SND_OPTI92X_CS4231=m
+CONFIG_SND_OPTI93X=m
+CONFIG_SND_MIRO=m
+CONFIG_SND_SB8=m
+CONFIG_SND_SB16=m
+CONFIG_SND_SBAWE=m
+CONFIG_SND_SB16_CSP=y
+CONFIG_SND_SSCAPE=m
+CONFIG_SND_WAVEFRONT=m
+CONFIG_SND_MSND_PINNACLE=m
+CONFIG_SND_MSND_CLASSIC=m
CONFIG_SND_TEA575X=m
CONFIG_SND_PCI=y
CONFIG_SND_AD1889=m
CONFIG_SND_FIREWIRE_SPEAKERS=m
# CONFIG_SND_ISIGHT is not set
# CONFIG_SND_SCS1X is not set
+CONFIG_SND_PCMCIA=y
+# CONFIG_SND_VXPOCKET is not set
+# CONFIG_SND_PDAUDIOCF is not set
# CONFIG_SND_SOC is not set
# CONFIG_SOUND_PRIME is not set
CONFIG_AC97_BUS=m
# CONFIG_USB_U132_HCD is not set
CONFIG_USB_SL811_HCD=m
CONFIG_USB_SL811_HCD_ISO=y
+# CONFIG_USB_SL811_CS is not set
# CONFIG_USB_R8A66597_HCD is not set
CONFIG_USB_WHCI_HCD=m
CONFIG_USB_HWA_HCD=m
CONFIG_MMC_SDHCI_PXAV2=m
CONFIG_MMC_WBSD=m
CONFIG_MMC_TIFM_SD=m
+# CONFIG_MMC_SDRICOH_CS is not set
CONFIG_MMC_CB710=m
CONFIG_MMC_VIA_SDMMC=m
CONFIG_MMC_VUB300=m
CONFIG_LEDS_TRIGGER_ONESHOT=m
CONFIG_LEDS_TRIGGER_HEARTBEAT=m
CONFIG_LEDS_TRIGGER_BACKLIGHT=m
-# CONFIG_LEDS_TRIGGER_CPU is not set
+CONFIG_LEDS_TRIGGER_CPU=y
CONFIG_LEDS_TRIGGER_GPIO=m
CONFIG_LEDS_TRIGGER_DEFAULT_ON=m
#
CONFIG_LEDS_TRIGGER_TRANSIENT=m
CONFIG_LEDS_TRIGGER_CAMERA=m
+CONFIG_LEDS_TRIGGER_NETDEV=m
# CONFIG_ACCESSIBILITY is not set
# CONFIG_INFINIBAND is not set
CONFIG_EDAC=y
# CONFIG_IIO_SYSFS_TRIGGER is not set
# CONFIG_IIO_SIMPLE_DUMMY is not set
# CONFIG_ZSMALLOC is not set
+# CONFIG_WLAGS49_H2 is not set
+# CONFIG_WLAGS49_H25 is not set
# CONFIG_FB_SM7XX is not set
# CONFIG_CRYSTALHD is not set
# CONFIG_FB_XGI is not set
# CONFIG_GRKERNSEC_ROFS is not set
CONFIG_GRKERNSEC_DEVICE_SIDECHANNEL=y
CONFIG_GRKERNSEC_CHROOT=y
-CONFIG_GRKERNSEC_CHROOT_MOUNT=y
+# CONFIG_GRKERNSEC_CHROOT_MOUNT is not set
CONFIG_GRKERNSEC_CHROOT_DOUBLE=y
CONFIG_GRKERNSEC_CHROOT_PIVOT=y
CONFIG_GRKERNSEC_CHROOT_CHDIR=y
CONFIG_GRKERNSEC_NO_SIMULT_CONNECT=y
# CONFIG_GRKERNSEC_SOCKET is not set
+#
+# Physical Protections
+#
+# CONFIG_GRKERNSEC_DENYUSB is not set
+
#
# Sysctl Support
#
include Config
-VER = 3.10.9
+VER = 3.10.10
RPI_PATCHES = linux-3.2.27-ada8b44
$(DL_FILE) = $(URL_IPFIRE)/$(DL_FILE)
rpi-patches-$(RPI_PATCHES).patch.xz = $(URL_IPFIRE)/rpi-patches-$(RPI_PATCHES).patch.xz
-$(DL_FILE)_MD5 = 28d1e1117c30fdd861f70ac0f9b677aa
+$(DL_FILE)_MD5 = 647f76225dd6bc112369ba573ba3de18
rpi-patches-$(RPI_PATCHES).patch.xz_MD5 = 966687ff27e450e04ff50e0da829dc00
# Grsecurity-patches
ifneq "$(KCFG)" "-headers"
- cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/grsecurity-2.9.1-3.10.9-201308202015.patch
+ cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/grsecurity-2.9.1-3.10.10-201308292131.patch
cd $(DIR_APP) && rm localversion-grsec
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/linux-3.7-disable-compat_vdso.patch
endif
# Remove ACPI Blacklist message
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/linux-2.6-silence-acpi-blacklist.patch
+ # DVB Patches
+ cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/linux-3.9-dvbsky-wot2.patch
+ cd $(DIR_APP) && patch -Np2 < $(DIR_SRC)/src/patches/v4l-dvb_fix_tua6034_pll.patch
+
# Add LED trigger
-# cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/linux-3.2.33-ledtrig-netdev-1.patch
+ cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/linux-3.10.9-ledtrig-netdev-1.patch
# Fix uevent PHYSDEVDRIVER
cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/linux-3.2.33_ipg-fix-driver-name.patch
pcd. [PARIDE]
diff --git a/Makefile b/Makefile
-index 4b31d62..ac99d49 100644
+index b119684..13ac256 100644
--- a/Makefile
+++ b/Makefile
@@ -241,8 +241,9 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
#define L_PTE_DIRTY_HIGH (1 << (55 - 32))
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
-index 9bcd262..fba731c 100644
+index 9bcd262..1ff999b 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -30,6 +30,9 @@
extern void __pte_error(const char *file, int line, pte_t);
extern void __pmd_error(const char *file, int line, pmd_t);
extern void __pgd_error(const char *file, int line, pgd_t);
-@@ -53,6 +59,50 @@ extern void __pgd_error(const char *file, int line, pgd_t);
+@@ -53,6 +59,48 @@ extern void __pgd_error(const char *file, int line, pgd_t);
#define pmd_ERROR(pmd) __pmd_error(__FILE__, __LINE__, pmd)
#define pgd_ERROR(pgd) __pgd_error(__FILE__, __LINE__, pgd)
+#define __HAVE_ARCH_PAX_OPEN_KERNEL
+#define __HAVE_ARCH_PAX_CLOSE_KERNEL
+
-+#ifdef CONFIG_PAX_KERNEXEC
++#if defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
+#include <asm/domain.h>
+#include <linux/thread_info.h>
+#include <linux/preempt.h>
-+#endif
+
-+#if defined(CONFIG_PAX_KERNEXEC) || defined(CONFIG_PAX_MEMORY_UDEREF)
+static inline int test_domain(int domain, int domaintype)
+{
+ return ((current_thread_info()->cpu_domain) & domain_val(domain, 3)) == domain_val(domain, domaintype);
/*
* This is the lowest virtual address we can permit any user space
* mapping to be mapped at. This is particularly important for
-@@ -72,8 +122,8 @@ extern void __pgd_error(const char *file, int line, pgd_t);
+@@ -72,8 +120,8 @@ extern void __pgd_error(const char *file, int line, pgd_t);
/*
* The pgprot_* and protection_map entries will be fixed up in runtime
* to include the cachable and bufferable bits based on memory policy,
*/
#define _L_PTE_DEFAULT L_PTE_PRESENT | L_PTE_YOUNG
-@@ -257,7 +307,7 @@ static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
+@@ -257,7 +305,7 @@ static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
{
const pteval_t mask = L_PTE_XN | L_PTE_RDONLY | L_PTE_USER |
extern void ux500_cpu_die(unsigned int cpu);
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
-index 2950082..d0f0782 100644
+index 08c9fe9..191320c 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -436,7 +436,7 @@ config CPU_32v5
help
Warning: disabling this option may break user programs.
-@@ -790,7 +792,7 @@ config KUSER_HELPERS
- run on ARMv4 through to ARMv7 without modification.
+@@ -792,7 +794,7 @@ config KUSER_HELPERS
+ See Documentation/arm/kernel_user_helpers.txt for details.
However, the fixed address nature of these helpers can be used
- by ROP (return orientated programming) authors when creating
goto fault; \
} while (0)
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
-index 5dbf13f..ee1ec24 100644
+index 5dbf13f..a2d1876 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -25,6 +25,7 @@
printk(KERN_ALERT "Unhandled fault: %s (0x%03x) at 0x%08lx\n",
inf->name, fsr, addr);
-@@ -569,15 +631,67 @@ hook_ifault_code(int nr, int (*fn)(unsigned long, unsigned int, struct pt_regs *
+@@ -569,15 +631,68 @@ hook_ifault_code(int nr, int (*fn)(unsigned long, unsigned int, struct pt_regs *
ifsr_info[nr].name = name;
}
{
const struct fsr_info *inf = ifsr_info + fsr_fs(ifsr);
struct siginfo info;
-
++ unsigned long pc = instruction_pointer(regs);
++
+ if (user_mode(regs)) {
+ unsigned long sigpage = current->mm->context.sigpage;
+
-+ if (sigpage <= addr && addr < sigpage + 7*4) {
-+ if (addr < sigpage + 3*4)
++ if (sigpage <= pc && pc < sigpage + 7*4) {
++ if (pc < sigpage + 3*4)
+ sys_sigreturn(regs);
+ else
+ sys_rt_sigreturn(regs);
+ return;
+ }
-+ if (addr == 0xffff0fe0UL) {
++ if (pc == 0xffff0fe0UL) {
+ /*
+ * PaX: __kuser_get_tls emulation
+ */
+ if (current->signal->curr_ip)
+ printk(KERN_ERR "PAX: From %pI4: %s:%d, uid/euid: %u/%u, attempted to execute %s memory at %08lx\n", ¤t->signal->curr_ip, current->comm, task_pid_nr(current),
+ from_kuid_munged(&init_user_ns, current_uid()), from_kuid_munged(&init_user_ns, current_euid()),
-+ addr >= TASK_SIZE ? "non-executable kernel" : "userland", addr);
++ pc >= TASK_SIZE ? "non-executable kernel" : "userland", pc);
+ else
+ printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to execute %s memory at %08lx\n", current->comm, task_pid_nr(current),
+ from_kuid_munged(&init_user_ns, current_uid()), from_kuid_munged(&init_user_ns, current_euid()),
-+ addr >= TASK_SIZE ? "non-executable kernel" : "userland", addr);
++ pc >= TASK_SIZE ? "non-executable kernel" : "userland", pc);
+ goto die;
+ }
+#endif
+ if (fsr_fs(ifsr) == FAULT_CODE_DEBUG) {
+ unsigned int bkpt;
+
-+ if (!probe_kernel_address((unsigned int *)addr, bkpt) && bkpt == 0xe12f1073) {
++ if (!probe_kernel_address((unsigned int *)pc, bkpt) && cpu_to_le32(bkpt) == 0xe12f1073) {
+ current->thread.error_code = ifsr;
+ current->thread.trap_no = 0;
+ pax_report_refcount_overflow(regs);
+ }
+ }
+#endif
-+
+
if (!inf->fn(addr, ifsr | FSR_LNX_PF, regs))
return;
#define SMP_CACHE_BYTES L1_CACHE_BYTES
diff --git a/arch/mips/include/asm/atomic.h b/arch/mips/include/asm/atomic.h
-index 08b6079..eb272cf 100644
+index 08b6079..e94e6da 100644
--- a/arch/mips/include/asm/atomic.h
+++ b/arch/mips/include/asm/atomic.h
-@@ -21,6 +21,10 @@
+@@ -21,15 +21,39 @@
#include <asm/cmpxchg.h>
#include <asm/war.h>
+
#define ATOMIC_INIT(i) { (i) }
++#ifdef CONFIG_64BIT
++#define _ASM_EXTABLE(from, to) \
++" .section __ex_table,\"a\"\n" \
++" .dword " #from ", " #to"\n" \
++" .previous\n"
++#else
++#define _ASM_EXTABLE(from, to) \
++" .section __ex_table,\"a\"\n" \
++" .word " #from ", " #to"\n" \
++" .previous\n"
++#endif
++
/*
-@@ -759,6 +763,16 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
+ * atomic_read - read atomic variable
+ * @v: pointer of type atomic_t
+ *
+ * Atomically reads the value of @v.
*/
- #define atomic64_add_negative(i, v) (atomic64_add_return(i, (v)) < 0)
+-#define atomic_read(v) (*(volatile int *)&(v)->counter)
++static inline int atomic_read(const atomic_t *v)
++{
++ return (*(volatile const int *) &v->counter);
++}
++
++static inline int atomic_read_unchecked(const atomic_unchecked_t *v)
++{
++ return (*(volatile const int *) &v->counter);
++}
-+#define atomic64_read_unchecked(v) atomic64_read(v)
-+#define atomic64_set_unchecked(v, i) atomic64_set((v), (i))
-+#define atomic64_add_unchecked(a, v) atomic64_add((a), (v))
-+#define atomic64_add_return_unchecked(a, v) atomic64_add_return((a), (v))
-+#define atomic64_sub_unchecked(a, v) atomic64_sub((a), (v))
-+#define atomic64_inc_unchecked(v) atomic64_inc(v)
-+#define atomic64_inc_return_unchecked(v) atomic64_inc_return(v)
-+#define atomic64_dec_unchecked(v) atomic64_dec(v)
-+#define atomic64_cmpxchg_unchecked(v, o, n) atomic64_cmpxchg((v), (o), (n))
+ /*
+ * atomic_set - set atomic variable
+@@ -38,7 +62,15 @@
+ *
+ * Atomically sets the value of @v to @i.
+ */
+-#define atomic_set(v, i) ((v)->counter = (i))
++static inline void atomic_set(atomic_t *v, int i)
++{
++ v->counter = i;
++}
+
- #endif /* CONFIG_64BIT */
++static inline void atomic_set_unchecked(atomic_unchecked_t *v, int i)
++{
++ v->counter = i;
++}
+
+ /*
+ * atomic_add - add integer to atomic variable
+@@ -47,7 +79,67 @@
+ *
+ * Atomically adds @i to @v.
+ */
+-static __inline__ void atomic_add(int i, atomic_t * v)
++static __inline__ void atomic_add(int i, atomic_t *v)
++{
++ int temp;
++
++ if (kernel_uses_llsc && R10000_LLSC_WAR) {
++ __asm__ __volatile__(
++ " .set mips3 \n"
++ "1: ll %0, %1 # atomic_add \n"
++#ifdef CONFIG_PAX_REFCOUNT
++ /* Exception on overflow. */
++ "2: add %0, %2 \n"
++#else
++ " addu %0, %2 \n"
++#endif
++ " sc %0, %1 \n"
++ " beqzl %0, 1b \n"
++#ifdef CONFIG_PAX_REFCOUNT
++ "3: \n"
++ _ASM_EXTABLE(2b, 3b)
++#endif
++ " .set mips0 \n"
++ : "=&r" (temp), "+m" (v->counter)
++ : "Ir" (i));
++ } else if (kernel_uses_llsc) {
++ __asm__ __volatile__(
++ " .set mips3 \n"
++ "1: ll %0, %1 # atomic_add \n"
++#ifdef CONFIG_PAX_REFCOUNT
++ /* Exception on overflow. */
++ "2: add %0, %2 \n"
++#else
++ " addu %0, %2 \n"
++#endif
++ " sc %0, %1 \n"
++ " beqz %0, 1b \n"
++#ifdef CONFIG_PAX_REFCOUNT
++ "3: \n"
++ _ASM_EXTABLE(2b, 3b)
++#endif
++ " .set mips0 \n"
++ : "=&r" (temp), "+m" (v->counter)
++ : "Ir" (i));
++ } else {
++ unsigned long flags;
++
++ raw_local_irq_save(flags);
++ __asm__ __volatile__(
++#ifdef CONFIG_PAX_REFCOUNT
++ /* Exception on overflow. */
++ "1: add %0, %1 \n"
++ "2: \n"
++ _ASM_EXTABLE(1b, 2b)
++#else
++ " addu %0, %1 \n"
++#endif
++ : "+r" (v->counter) : "Ir" (i));
++ raw_local_irq_restore(flags);
++ }
++}
++
++static __inline__ void atomic_add_unchecked(int i, atomic_unchecked_t *v)
+ {
+ if (kernel_uses_llsc && R10000_LLSC_WAR) {
+ int temp;
+@@ -90,7 +182,67 @@ static __inline__ void atomic_add(int i, atomic_t * v)
+ *
+ * Atomically subtracts @i from @v.
+ */
+-static __inline__ void atomic_sub(int i, atomic_t * v)
++static __inline__ void atomic_sub(int i, atomic_t *v)
++{
++ int temp;
++
++ if (kernel_uses_llsc && R10000_LLSC_WAR) {
++ __asm__ __volatile__(
++ " .set mips3 \n"
++ "1: ll %0, %1 # atomic64_sub \n"
++#ifdef CONFIG_PAX_REFCOUNT
++ /* Exception on overflow. */
++ "2: sub %0, %2 \n"
++#else
++ " subu %0, %2 \n"
++#endif
++ " sc %0, %1 \n"
++ " beqzl %0, 1b \n"
++#ifdef CONFIG_PAX_REFCOUNT
++ "3: \n"
++ _ASM_EXTABLE(2b, 3b)
++#endif
++ " .set mips0 \n"
++ : "=&r" (temp), "+m" (v->counter)
++ : "Ir" (i));
++ } else if (kernel_uses_llsc) {
++ __asm__ __volatile__(
++ " .set mips3 \n"
++ "1: ll %0, %1 # atomic64_sub \n"
++#ifdef CONFIG_PAX_REFCOUNT
++ /* Exception on overflow. */
++ "2: sub %0, %2 \n"
++#else
++ " subu %0, %2 \n"
++#endif
++ " sc %0, %1 \n"
++ " beqz %0, 1b \n"
++#ifdef CONFIG_PAX_REFCOUNT
++ "3: \n"
++ _ASM_EXTABLE(2b, 3b)
++#endif
++ " .set mips0 \n"
++ : "=&r" (temp), "+m" (v->counter)
++ : "Ir" (i));
++ } else {
++ unsigned long flags;
++
++ raw_local_irq_save(flags);
++ __asm__ __volatile__(
++#ifdef CONFIG_PAX_REFCOUNT
++ /* Exception on overflow. */
++ "1: sub %0, %1 \n"
++ "2: \n"
++ _ASM_EXTABLE(1b, 2b)
++#else
++ " subu %0, %1 \n"
++#endif
++ : "+r" (v->counter) : "Ir" (i));
++ raw_local_irq_restore(flags);
++ }
++}
++
++static __inline__ void atomic_sub_unchecked(long i, atomic_unchecked_t *v)
+ {
+ if (kernel_uses_llsc && R10000_LLSC_WAR) {
+ int temp;
+@@ -129,7 +281,93 @@ static __inline__ void atomic_sub(int i, atomic_t * v)
+ /*
+ * Same as above, but return the result value
+ */
+-static __inline__ int atomic_add_return(int i, atomic_t * v)
++static __inline__ int atomic_add_return(int i, atomic_t *v)
++{
++ int result;
++ int temp;
++
++ smp_mb__before_llsc();
++
++ if (kernel_uses_llsc && R10000_LLSC_WAR) {
++ __asm__ __volatile__(
++ " .set mips3 \n"
++ "1: ll %1, %2 # atomic_add_return \n"
++#ifdef CONFIG_PAX_REFCOUNT
++ "2: add %0, %1, %3 \n"
++#else
++ " addu %0, %1, %3 \n"
++#endif
++ " sc %0, %2 \n"
++ " beqzl %0, 1b \n"
++#ifdef CONFIG_PAX_REFCOUNT
++ " b 4f \n"
++ " .set noreorder \n"
++ "3: b 5f \n"
++ " move %0, %1 \n"
++ " .set reorder \n"
++ _ASM_EXTABLE(2b, 3b)
++#endif
++ "4: addu %0, %1, %3 \n"
++#ifdef CONFIG_PAX_REFCOUNT
++ "5: \n"
++#endif
++ " .set mips0 \n"
++ : "=&r" (result), "=&r" (temp), "+m" (v->counter)
++ : "Ir" (i));
++ } else if (kernel_uses_llsc) {
++ __asm__ __volatile__(
++ " .set mips3 \n"
++ "1: ll %1, %2 # atomic_add_return \n"
++#ifdef CONFIG_PAX_REFCOUNT
++ "2: add %0, %1, %3 \n"
++#else
++ " addu %0, %1, %3 \n"
++#endif
++ " sc %0, %2 \n"
++ " bnez %0, 4f \n"
++ " b 1b \n"
++#ifdef CONFIG_PAX_REFCOUNT
++ " .set noreorder \n"
++ "3: b 5f \n"
++ " move %0, %1 \n"
++ " .set reorder \n"
++ _ASM_EXTABLE(2b, 3b)
++#endif
++ "4: addu %0, %1, %3 \n"
++#ifdef CONFIG_PAX_REFCOUNT
++ "5: \n"
++#endif
++ " .set mips0 \n"
++ : "=&r" (result), "=&r" (temp), "+m" (v->counter)
++ : "Ir" (i));
++ } else {
++ unsigned long flags;
++
++ raw_local_irq_save(flags);
++ __asm__ __volatile__(
++ " lw %0, %1 \n"
++#ifdef CONFIG_PAX_REFCOUNT
++ /* Exception on overflow. */
++ "1: add %0, %2 \n"
++#else
++ " addu %0, %2 \n"
++#endif
++ " sw %0, %1 \n"
++#ifdef CONFIG_PAX_REFCOUNT
++ /* Note: Dest reg is not modified on overflow */
++ "2: \n"
++ _ASM_EXTABLE(1b, 2b)
++#endif
++ : "=&r" (result), "+m" (v->counter) : "Ir" (i));
++ raw_local_irq_restore(flags);
++ }
++
++ smp_llsc_mb();
++
++ return result;
++}
++
++static __inline__ int atomic_add_return_unchecked(int i, atomic_unchecked_t *v)
+ {
+ int result;
+
+@@ -178,7 +416,93 @@ static __inline__ int atomic_add_return(int i, atomic_t * v)
+ return result;
+ }
+
+-static __inline__ int atomic_sub_return(int i, atomic_t * v)
++static __inline__ int atomic_sub_return(int i, atomic_t *v)
++{
++ int result;
++ int temp;
++
++ smp_mb__before_llsc();
++
++ if (kernel_uses_llsc && R10000_LLSC_WAR) {
++ __asm__ __volatile__(
++ " .set mips3 \n"
++ "1: ll %1, %2 # atomic_sub_return \n"
++#ifdef CONFIG_PAX_REFCOUNT
++ "2: sub %0, %1, %3 \n"
++#else
++ " subu %0, %1, %3 \n"
++#endif
++ " sc %0, %2 \n"
++ " beqzl %0, 1b \n"
++#ifdef CONFIG_PAX_REFCOUNT
++ " b 4f \n"
++ " .set noreorder \n"
++ "3: b 5f \n"
++ " move %0, %1 \n"
++ " .set reorder \n"
++ _ASM_EXTABLE(2b, 3b)
++#endif
++ "4: subu %0, %1, %3 \n"
++#ifdef CONFIG_PAX_REFCOUNT
++ "5: \n"
++#endif
++ " .set mips0 \n"
++ : "=&r" (result), "=&r" (temp), "=m" (v->counter)
++ : "Ir" (i), "m" (v->counter)
++ : "memory");
++ } else if (kernel_uses_llsc) {
++ __asm__ __volatile__(
++ " .set mips3 \n"
++ "1: ll %1, %2 # atomic_sub_return \n"
++#ifdef CONFIG_PAX_REFCOUNT
++ "2: sub %0, %1, %3 \n"
++#else
++ " subu %0, %1, %3 \n"
++#endif
++ " sc %0, %2 \n"
++ " bnez %0, 4f \n"
++ " b 1b \n"
++#ifdef CONFIG_PAX_REFCOUNT
++ " .set noreorder \n"
++ "3: b 5f \n"
++ " move %0, %1 \n"
++ " .set reorder \n"
++ _ASM_EXTABLE(2b, 3b)
++#endif
++ "4: subu %0, %1, %3 \n"
++#ifdef CONFIG_PAX_REFCOUNT
++ "5: \n"
++#endif
++ " .set mips0 \n"
++ : "=&r" (result), "=&r" (temp), "+m" (v->counter)
++ : "Ir" (i));
++ } else {
++ unsigned long flags;
++
++ raw_local_irq_save(flags);
++ __asm__ __volatile__(
++ " lw %0, %1 \n"
++#ifdef CONFIG_PAX_REFCOUNT
++ /* Exception on overflow. */
++ "1: sub %0, %2 \n"
++#else
++ " subu %0, %2 \n"
++#endif
++ " sw %0, %1 \n"
++#ifdef CONFIG_PAX_REFCOUNT
++ /* Note: Dest reg is not modified on overflow */
++ "2: \n"
++ _ASM_EXTABLE(1b, 2b)
++#endif
++ : "=&r" (result), "+m" (v->counter) : "Ir" (i));
++ raw_local_irq_restore(flags);
++ }
++
++ smp_llsc_mb();
++
++ return result;
++}
++static __inline__ int atomic_sub_return_unchecked(int i, atomic_unchecked_t *v)
+ {
+ int result;
+
+@@ -238,7 +562,7 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v)
+ * Atomically test @v and subtract @i if @v is greater or equal than @i.
+ * The function returns the old value of @v minus @i.
+ */
+-static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
++static __inline__ int atomic_sub_if_positive(int i, atomic_t *v)
+ {
+ int result;
+
+@@ -295,8 +619,26 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
+ return result;
+ }
+
+-#define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n)))
+-#define atomic_xchg(v, new) (xchg(&((v)->counter), (new)))
++static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
++{
++ return cmpxchg(&v->counter, old, new);
++}
++
++static inline int atomic_cmpxchg_unchecked(atomic_unchecked_t *v, int old,
++ int new)
++{
++ return cmpxchg(&(v->counter), old, new);
++}
++
++static inline int atomic_xchg(atomic_t *v, int new)
++{
++ return xchg(&v->counter, new);
++}
++
++static inline int atomic_xchg_unchecked(atomic_unchecked_t *v, int new)
++{
++ return xchg(&(v->counter), new);
++}
+
+ /**
+ * __atomic_add_unless - add unless the number is a given value
+@@ -324,6 +666,7 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u)
+
+ #define atomic_dec_return(v) atomic_sub_return(1, (v))
+ #define atomic_inc_return(v) atomic_add_return(1, (v))
++#define atomic_inc_return_unchecked(v) atomic_add_return_unchecked(1, (v))
+
+ /*
+ * atomic_sub_and_test - subtract value from variable and test result
+@@ -345,6 +688,7 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u)
+ * other cases.
+ */
+ #define atomic_inc_and_test(v) (atomic_inc_return(v) == 0)
++#define atomic_inc_and_test_unchecked(v) (atomic_add_return_unchecked(1, (v)) == 0)
+
+ /*
+ * atomic_dec_and_test - decrement by 1 and test
+@@ -369,6 +713,7 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u)
+ * Atomically increments @v by 1.
+ */
+ #define atomic_inc(v) atomic_add(1, (v))
++#define atomic_inc_unchecked(v) atomic_add_unchecked(1, (v))
+
+ /*
+ * atomic_dec - decrement and test
+@@ -377,6 +722,7 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u)
+ * Atomically decrements @v by 1.
+ */
+ #define atomic_dec(v) atomic_sub(1, (v))
++#define atomic_dec_unchecked(v) atomic_sub_return_unchecked(1, (v))
+
+ /*
+ * atomic_add_negative - add and test if negative
+@@ -398,14 +744,30 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u)
+ * @v: pointer of type atomic64_t
+ *
+ */
+-#define atomic64_read(v) (*(volatile long *)&(v)->counter)
++static inline long atomic64_read(const atomic64_t *v)
++{
++ return (*(volatile const long *) &v->counter);
++}
++
++static inline long atomic64_read_unchecked(const atomic64_unchecked_t *v)
++{
++ return (*(volatile const long *) &v->counter);
++}
+
+ /*
+ * atomic64_set - set atomic variable
+ * @v: pointer of type atomic64_t
+ * @i: required value
+ */
+-#define atomic64_set(v, i) ((v)->counter = (i))
++static inline void atomic64_set(atomic64_t *v, long i)
++{
++ v->counter = i;
++}
++
++static inline void atomic64_set_unchecked(atomic64_unchecked_t *v, long i)
++{
++ v->counter = i;
++}
+
+ /*
+ * atomic64_add - add integer to atomic variable
+@@ -414,7 +776,66 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u)
+ *
+ * Atomically adds @i to @v.
+ */
+-static __inline__ void atomic64_add(long i, atomic64_t * v)
++static __inline__ void atomic64_add(long i, atomic64_t *v)
++{
++ long temp;
++
++ if (kernel_uses_llsc && R10000_LLSC_WAR) {
++ __asm__ __volatile__(
++ " .set mips3 \n"
++ "1: lld %0, %1 # atomic64_add \n"
++#ifdef CONFIG_PAX_REFCOUNT
++ /* Exception on overflow. */
++ "2: dadd %0, %2 \n"
++#else
++ " daddu %0, %2 \n"
++#endif
++ " scd %0, %1 \n"
++ " beqzl %0, 1b \n"
++#ifdef CONFIG_PAX_REFCOUNT
++ "3: \n"
++ _ASM_EXTABLE(2b, 3b)
++#endif
++ " .set mips0 \n"
++ : "=&r" (temp), "+m" (v->counter)
++ : "Ir" (i));
++ } else if (kernel_uses_llsc) {
++ __asm__ __volatile__(
++ " .set mips3 \n"
++ "1: lld %0, %1 # atomic64_add \n"
++#ifdef CONFIG_PAX_REFCOUNT
++ /* Exception on overflow. */
++ "2: dadd %0, %2 \n"
++#else
++ " daddu %0, %2 \n"
++#endif
++ " scd %0, %1 \n"
++ " beqz %0, 1b \n"
++#ifdef CONFIG_PAX_REFCOUNT
++ "3: \n"
++ _ASM_EXTABLE(2b, 3b)
++#endif
++ " .set mips0 \n"
++ : "=&r" (temp), "+m" (v->counter)
++ : "Ir" (i));
++ } else {
++ unsigned long flags;
++
++ raw_local_irq_save(flags);
++ __asm__ __volatile__(
++#ifdef CONFIG_PAX_REFCOUNT
++ /* Exception on overflow. */
++ "1: dadd %0, %1 \n"
++ "2: \n"
++ _ASM_EXTABLE(1b, 2b)
++#else
++ " daddu %0, %1 \n"
++#endif
++ : "+r" (v->counter) : "Ir" (i));
++ raw_local_irq_restore(flags);
++ }
++}
++static __inline__ void atomic64_add_unchecked(long i, atomic64_unchecked_t *v)
+ {
+ if (kernel_uses_llsc && R10000_LLSC_WAR) {
+ long temp;
+@@ -457,7 +878,67 @@ static __inline__ void atomic64_add(long i, atomic64_t * v)
+ *
+ * Atomically subtracts @i from @v.
+ */
+-static __inline__ void atomic64_sub(long i, atomic64_t * v)
++static __inline__ void atomic64_sub(long i, atomic64_t *v)
++{
++ long temp;
++
++ if (kernel_uses_llsc && R10000_LLSC_WAR) {
++ __asm__ __volatile__(
++ " .set mips3 \n"
++ "1: lld %0, %1 # atomic64_sub \n"
++#ifdef CONFIG_PAX_REFCOUNT
++ /* Exception on overflow. */
++ "2: dsub %0, %2 \n"
++#else
++ " dsubu %0, %2 \n"
++#endif
++ " scd %0, %1 \n"
++ " beqzl %0, 1b \n"
++#ifdef CONFIG_PAX_REFCOUNT
++ "3: \n"
++ _ASM_EXTABLE(2b, 3b)
++#endif
++ " .set mips0 \n"
++ : "=&r" (temp), "+m" (v->counter)
++ : "Ir" (i));
++ } else if (kernel_uses_llsc) {
++ __asm__ __volatile__(
++ " .set mips3 \n"
++ "1: lld %0, %1 # atomic64_sub \n"
++#ifdef CONFIG_PAX_REFCOUNT
++ /* Exception on overflow. */
++ "2: dsub %0, %2 \n"
++#else
++ " dsubu %0, %2 \n"
++#endif
++ " scd %0, %1 \n"
++ " beqz %0, 1b \n"
++#ifdef CONFIG_PAX_REFCOUNT
++ "3: \n"
++ _ASM_EXTABLE(2b, 3b)
++#endif
++ " .set mips0 \n"
++ : "=&r" (temp), "+m" (v->counter)
++ : "Ir" (i));
++ } else {
++ unsigned long flags;
++
++ raw_local_irq_save(flags);
++ __asm__ __volatile__(
++#ifdef CONFIG_PAX_REFCOUNT
++ /* Exception on overflow. */
++ "1: dsub %0, %1 \n"
++ "2: \n"
++ _ASM_EXTABLE(1b, 2b)
++#else
++ " dsubu %0, %1 \n"
++#endif
++ : "+r" (v->counter) : "Ir" (i));
++ raw_local_irq_restore(flags);
++ }
++}
++
++static __inline__ void atomic64_sub_unchecked(long i, atomic64_unchecked_t *v)
+ {
+ if (kernel_uses_llsc && R10000_LLSC_WAR) {
+ long temp;
+@@ -496,7 +977,93 @@ static __inline__ void atomic64_sub(long i, atomic64_t * v)
+ /*
+ * Same as above, but return the result value
+ */
+-static __inline__ long atomic64_add_return(long i, atomic64_t * v)
++static __inline__ long atomic64_add_return(long i, atomic64_t *v)
++{
++ long result;
++ long temp;
++
++ smp_mb__before_llsc();
++
++ if (kernel_uses_llsc && R10000_LLSC_WAR) {
++ __asm__ __volatile__(
++ " .set mips3 \n"
++ "1: lld %1, %2 # atomic64_add_return \n"
++#ifdef CONFIG_PAX_REFCOUNT
++ "2: dadd %0, %1, %3 \n"
++#else
++ " daddu %0, %1, %3 \n"
++#endif
++ " scd %0, %2 \n"
++ " beqzl %0, 1b \n"
++#ifdef CONFIG_PAX_REFCOUNT
++ " b 4f \n"
++ " .set noreorder \n"
++ "3: b 5f \n"
++ " move %0, %1 \n"
++ " .set reorder \n"
++ _ASM_EXTABLE(2b, 3b)
++#endif
++ "4: daddu %0, %1, %3 \n"
++#ifdef CONFIG_PAX_REFCOUNT
++ "5: \n"
++#endif
++ " .set mips0 \n"
++ : "=&r" (result), "=&r" (temp), "+m" (v->counter)
++ : "Ir" (i));
++ } else if (kernel_uses_llsc) {
++ __asm__ __volatile__(
++ " .set mips3 \n"
++ "1: lld %1, %2 # atomic64_add_return \n"
++#ifdef CONFIG_PAX_REFCOUNT
++ "2: dadd %0, %1, %3 \n"
++#else
++ " daddu %0, %1, %3 \n"
++#endif
++ " scd %0, %2 \n"
++ " bnez %0, 4f \n"
++ " b 1b \n"
++#ifdef CONFIG_PAX_REFCOUNT
++ " .set noreorder \n"
++ "3: b 5f \n"
++ " move %0, %1 \n"
++ " .set reorder \n"
++ _ASM_EXTABLE(2b, 3b)
++#endif
++ "4: daddu %0, %1, %3 \n"
++#ifdef CONFIG_PAX_REFCOUNT
++ "5: \n"
++#endif
++ " .set mips0 \n"
++ : "=&r" (result), "=&r" (temp), "=m" (v->counter)
++ : "Ir" (i), "m" (v->counter)
++ : "memory");
++ } else {
++ unsigned long flags;
++
++ raw_local_irq_save(flags);
++ __asm__ __volatile__(
++ " ld %0, %1 \n"
++#ifdef CONFIG_PAX_REFCOUNT
++ /* Exception on overflow. */
++ "1: dadd %0, %2 \n"
++#else
++ " daddu %0, %2 \n"
++#endif
++ " sd %0, %1 \n"
++#ifdef CONFIG_PAX_REFCOUNT
++ /* Note: Dest reg is not modified on overflow */
++ "2: \n"
++ _ASM_EXTABLE(1b, 2b)
++#endif
++ : "=&r" (result), "+m" (v->counter) : "Ir" (i));
++ raw_local_irq_restore(flags);
++ }
++
++ smp_llsc_mb();
++
++ return result;
++}
++static __inline__ long atomic64_add_return_unchecked(long i, atomic64_unchecked_t *v)
+ {
+ long result;
+
+@@ -546,7 +1113,97 @@ static __inline__ long atomic64_add_return(long i, atomic64_t * v)
+ return result;
+ }
+
+-static __inline__ long atomic64_sub_return(long i, atomic64_t * v)
++static __inline__ long atomic64_sub_return(long i, atomic64_t *v)
++{
++ long result;
++ long temp;
++
++ smp_mb__before_llsc();
++
++ if (kernel_uses_llsc && R10000_LLSC_WAR) {
++ long temp;
++
++ __asm__ __volatile__(
++ " .set mips3 \n"
++ "1: lld %1, %2 # atomic64_sub_return \n"
++#ifdef CONFIG_PAX_REFCOUNT
++ "2: dsub %0, %1, %3 \n"
++#else
++ " dsubu %0, %1, %3 \n"
++#endif
++ " scd %0, %2 \n"
++ " beqzl %0, 1b \n"
++#ifdef CONFIG_PAX_REFCOUNT
++ " b 4f \n"
++ " .set noreorder \n"
++ "3: b 5f \n"
++ " move %0, %1 \n"
++ " .set reorder \n"
++ _ASM_EXTABLE(2b, 3b)
++#endif
++ "4: dsubu %0, %1, %3 \n"
++#ifdef CONFIG_PAX_REFCOUNT
++ "5: \n"
++#endif
++ " .set mips0 \n"
++ : "=&r" (result), "=&r" (temp), "=m" (v->counter)
++ : "Ir" (i), "m" (v->counter)
++ : "memory");
++ } else if (kernel_uses_llsc) {
++ __asm__ __volatile__(
++ " .set mips3 \n"
++ "1: lld %1, %2 # atomic64_sub_return \n"
++#ifdef CONFIG_PAX_REFCOUNT
++ "2: dsub %0, %1, %3 \n"
++#else
++ " dsubu %0, %1, %3 \n"
++#endif
++ " scd %0, %2 \n"
++ " bnez %0, 4f \n"
++ " b 1b \n"
++#ifdef CONFIG_PAX_REFCOUNT
++ " .set noreorder \n"
++ "3: b 5f \n"
++ " move %0, %1 \n"
++ " .set reorder \n"
++ _ASM_EXTABLE(2b, 3b)
++#endif
++ "4: dsubu %0, %1, %3 \n"
++#ifdef CONFIG_PAX_REFCOUNT
++ "5: \n"
++#endif
++ " .set mips0 \n"
++ : "=&r" (result), "=&r" (temp), "=m" (v->counter)
++ : "Ir" (i), "m" (v->counter)
++ : "memory");
++ } else {
++ unsigned long flags;
++
++ raw_local_irq_save(flags);
++ __asm__ __volatile__(
++ " ld %0, %1 \n"
++#ifdef CONFIG_PAX_REFCOUNT
++ /* Exception on overflow. */
++ "1: dsub %0, %2 \n"
++#else
++ " dsubu %0, %2 \n"
++#endif
++ " sd %0, %1 \n"
++#ifdef CONFIG_PAX_REFCOUNT
++ /* Note: Dest reg is not modified on overflow */
++ "2: \n"
++ _ASM_EXTABLE(1b, 2b)
++#endif
++ : "=&r" (result), "+m" (v->counter) : "Ir" (i));
++ raw_local_irq_restore(flags);
++ }
++
++ smp_llsc_mb();
++
++ return result;
++}
++
++static __inline__ long atomic64_sub_return_unchecked(long i, atomic64_unchecked_t *v)
+ {
+ long result;
+
+@@ -605,7 +1262,7 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v)
+ * Atomically test @v and subtract @i if @v is greater or equal than @i.
+ * The function returns the old value of @v minus @i.
+ */
+-static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
++static __inline__ long atomic64_sub_if_positive(long i, atomic64_t *v)
+ {
+ long result;
+
+@@ -662,9 +1319,26 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
+ return result;
+ }
+
+-#define atomic64_cmpxchg(v, o, n) \
+- ((__typeof__((v)->counter))cmpxchg(&((v)->counter), (o), (n)))
+-#define atomic64_xchg(v, new) (xchg(&((v)->counter), (new)))
++static inline long atomic64_cmpxchg(atomic64_t *v, long old, long new)
++{
++ return cmpxchg(&v->counter, old, new);
++}
++
++static inline long atomic64_cmpxchg_unchecked(atomic64_unchecked_t *v, long old,
++ long new)
++{
++ return cmpxchg(&(v->counter), old, new);
++}
++
++static inline long atomic64_xchg(atomic64_t *v, long new)
++{
++ return xchg(&v->counter, new);
++}
++
++static inline long atomic64_xchg_unchecked(atomic64_unchecked_t *v, long new)
++{
++ return xchg(&(v->counter), new);
++}
+
+ /**
+ * atomic64_add_unless - add unless the number is a given value
+@@ -694,6 +1368,7 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
+
+ #define atomic64_dec_return(v) atomic64_sub_return(1, (v))
+ #define atomic64_inc_return(v) atomic64_add_return(1, (v))
++#define atomic64_inc_return_unchecked(v) atomic64_add_return_unchecked(1, (v))
+
+ /*
+ * atomic64_sub_and_test - subtract value from variable and test result
+@@ -715,6 +1390,7 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
+ * other cases.
+ */
+ #define atomic64_inc_and_test(v) (atomic64_inc_return(v) == 0)
++#define atomic64_inc_and_test_unchecked(v) atomic64_add_return_unchecked(1, (v)) == 0)
+
+ /*
+ * atomic64_dec_and_test - decrement by 1 and test
+@@ -739,6 +1415,7 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
+ * Atomically increments @v by 1.
+ */
+ #define atomic64_inc(v) atomic64_add(1, (v))
++#define atomic64_inc_unchecked(v) atomic64_add_unchecked(1, (v))
+
+ /*
+ * atomic64_dec - decrement and test
+@@ -747,6 +1424,7 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
+ * Atomically decrements @v by 1.
+ */
+ #define atomic64_dec(v) atomic64_sub(1, (v))
++#define atomic64_dec_unchecked(v) atomic64_sub_unchecked(1, (v))
/*
+ * atomic64_add_negative - add and test if negative
diff --git a/arch/mips/include/asm/cache.h b/arch/mips/include/asm/cache.h
index b4db69f..8f3b093 100644
--- a/arch/mips/include/asm/cache.h
LONG_L t0, TI_FLAGS($28) # syscall tracing enabled?
and t0, t1, t0
bnez t0, trace_a_syscall
+diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
+index a75ae40..0d0f56a 100644
+--- a/arch/mips/kernel/traps.c
++++ b/arch/mips/kernel/traps.c
+@@ -675,7 +675,17 @@ asmlinkage void do_ov(struct pt_regs *regs)
+ {
+ siginfo_t info;
+
+- die_if_kernel("Integer overflow", regs);
++ if (unlikely(!user_mode(regs))) {
++
++#ifdef CONFIG_PAX_REFCOUNT
++ if (fixup_exception(regs)) {
++ pax_report_refcount_overflow(regs);
++ return;
++ }
++#endif
++
++ die("Integer overflow", regs);
++ }
+
+ info.si_code = FPE_INTOVF;
+ info.si_signo = SIGFPE;
diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
index 0fead53..eeb00a6 100644
--- a/arch/mips/mm/fault.c
#endif
#endif /* _ASM_X86_THREAD_INFO_H */
diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h
-index 50a7fc0..7c437a7 100644
+index 50a7fc0..45844c0 100644
--- a/arch/x86/include/asm/tlbflush.h
+++ b/arch/x86/include/asm/tlbflush.h
-@@ -17,18 +17,40 @@
+@@ -17,18 +17,44 @@
static inline void __native_flush_tlb(void)
{
+ if (static_cpu_has(X86_FEATURE_INVPCID)) {
+ unsigned long descriptor[2];
++
++ descriptor[0] = PCID_KERNEL;
+ asm volatile(__ASM_INVPCID : : "d"(&descriptor), "a"(INVPCID_ALL_MONGLOBAL) : "memory");
+ return;
+ }
- unsigned long cr4;
+ if (static_cpu_has(X86_FEATURE_INVPCID)) {
+ unsigned long descriptor[2];
-+ asm volatile(__ASM_INVPCID : : "d"(&descriptor), "a"(INVPCID_ALL_GLOBAL) : "memory");
-+ } else {
-+ unsigned long cr4;
- cr4 = native_read_cr4();
- /* clear PGE */
- native_write_cr4(cr4 & ~X86_CR4_PGE);
- /* write old PGE again and flush TLBs */
- native_write_cr4(cr4);
++ descriptor[0] = PCID_KERNEL;
++ asm volatile(__ASM_INVPCID : : "d"(&descriptor), "a"(INVPCID_ALL_GLOBAL) : "memory");
++ } else {
++ unsigned long cr4;
++
+ cr4 = native_read_cr4();
+ /* clear PGE */
+ native_write_cr4(cr4 & ~X86_CR4_PGE);
}
static inline void __native_flush_tlb_global(void)
-@@ -49,6 +71,42 @@ static inline void __native_flush_tlb_global(void)
+@@ -49,6 +75,42 @@ static inline void __native_flush_tlb_global(void)
static inline void __native_flush_tlb_single(unsigned long addr)
{
}
diff --git a/arch/x86/include/asm/uaccess_64.h b/arch/x86/include/asm/uaccess_64.h
-index 142810c..1f2a0a7 100644
+index 142810c..1dbe82f 100644
--- a/arch/x86/include/asm/uaccess_64.h
+++ b/arch/x86/include/asm/uaccess_64.h
@@ -10,6 +10,9 @@
}
}
- static __must_check __always_inline int
+-static __must_check __always_inline int
-__copy_from_user_inatomic(void *dst, const void __user *src, unsigned size)
++static __must_check __always_inline unsigned long
+__copy_from_user_inatomic(void *dst, const void __user *src, unsigned long size)
{
- return copy_user_generic(dst, (__force const void *)src, size);
+ return arch_get_unmapped_area(filp, addr0, len, pgoff, flags);
+}
diff --git a/arch/x86/kernel/sys_x86_64.c b/arch/x86/kernel/sys_x86_64.c
-index 48f8375..ace2781 100644
+index 30277e2..5664a29 100644
--- a/arch/x86/kernel/sys_x86_64.c
+++ b/arch/x86/kernel/sys_x86_64.c
@@ -81,8 +81,8 @@ out:
*begin = new_begin;
}
} else {
-- *begin = mmap_legacy_base();
-+ *begin = mm->mmap_base;
+- *begin = current->mm->mmap_legacy_base;
++ *begin = mm->mmap_legacy_base;
*end = TASK_SIZE;
}
}
pte = kmemcheck_pte_lookup(address);
diff --git a/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c
-index c1af323..4758dad 100644
+index 5c1ae28..45f4ac9 100644
--- a/arch/x86/mm/mmap.c
+++ b/arch/x86/mm/mmap.c
@@ -52,7 +52,7 @@ static unsigned int stack_maxrandom_size(void)
* Bottom-up (legacy) layout on X86_32 did not support randomization, X86_64
* does, but not when emulating X86_32
*/
--unsigned long mmap_legacy_base(void)
-+unsigned long mmap_legacy_base(struct mm_struct *mm)
+-static unsigned long mmap_legacy_base(void)
++static unsigned long mmap_legacy_base(struct mm_struct *mm)
{
- if (mmap_is_ia32())
+ if (mmap_is_ia32()) {
return TASK_UNMAPPED_BASE + mmap_rnd();
}
-@@ -113,11 +126,23 @@ unsigned long mmap_legacy_base(void)
+@@ -112,8 +125,15 @@ static unsigned long mmap_legacy_base(void)
+ */
void arch_pick_mmap_layout(struct mm_struct *mm)
{
- if (mmap_is_legacy()) {
-- mm->mmap_base = mmap_legacy_base();
-+ mm->mmap_base = mmap_legacy_base(mm);
+- mm->mmap_legacy_base = mmap_legacy_base();
+- mm->mmap_base = mmap_base();
++ mm->mmap_legacy_base = mmap_legacy_base(mm);
++ mm->mmap_base = mmap_base(mm);
+
+#ifdef CONFIG_PAX_RANDMMAP
-+ if (mm->pax_flags & MF_PAX_RANDMMAP)
-+ mm->mmap_base += mm->delta_mmap;
-+#endif
-+
- mm->get_unmapped_area = arch_get_unmapped_area;
- mm->unmap_area = arch_unmap_area;
- } else {
-- mm->mmap_base = mmap_base();
-+ mm->mmap_base = mmap_base(mm);
-+
-+#ifdef CONFIG_PAX_RANDMMAP
-+ if (mm->pax_flags & MF_PAX_RANDMMAP)
-+ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
++ if (mm->pax_flags & MF_PAX_RANDMMAP) {
++ mm->mmap_legacy_base += mm->delta_mmap;
++ mm->mmap_base -= mm->delta_mmap + mm->delta_stack;
++ }
+#endif
-+
- mm->get_unmapped_area = arch_get_unmapped_area_topdown;
- mm->unmap_area = arch_unmap_area_topdown;
- }
+
+ if (mmap_is_legacy()) {
+ mm->mmap_base = mm->mmap_legacy_base;
diff --git a/arch/x86/mm/mmio-mod.c b/arch/x86/mm/mmio-mod.c
index dc0b727..f612039 100644
--- a/arch/x86/mm/mmio-mod.c
.alloc_pud = xen_alloc_pmd_init,
.release_pud = xen_release_pmd_init,
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
-index d99cae8..18401e1 100644
+index a1e58e1..9392ad8 100644
--- a/arch/x86/xen/smp.c
+++ b/arch/x86/xen/smp.c
@@ -240,11 +240,6 @@ static void __init xen_smp_prepare_boot_cpu(void)
err = drm_debugfs_create_files(dc->debugfs_files,
ARRAY_SIZE(debugfs_files),
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
-index 402f486..f862d7e 100644
+index 402f486..5340852 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
-@@ -2275,7 +2275,7 @@ EXPORT_SYMBOL_GPL(hid_ignore);
+@@ -63,6 +63,8 @@ struct hid_report *hid_register_report(struct hid_device *device, unsigned type,
+ struct hid_report_enum *report_enum = device->report_enum + type;
+ struct hid_report *report;
+
++ if (id >= HID_MAX_IDS)
++ return NULL;
+ if (report_enum->report_id_hash[id])
+ return report_enum->report_id_hash[id];
+
+@@ -404,8 +406,10 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item)
+
+ case HID_GLOBAL_ITEM_TAG_REPORT_ID:
+ parser->global.report_id = item_udata(item);
+- if (parser->global.report_id == 0) {
+- hid_err(parser->device, "report_id 0 is invalid\n");
++ if (parser->global.report_id == 0 ||
++ parser->global.report_id >= HID_MAX_IDS) {
++ hid_err(parser->device, "report_id %u is invalid\n",
++ parser->global.report_id);
+ return -1;
+ }
+ return 0;
+@@ -575,7 +579,7 @@ static void hid_close_report(struct hid_device *device)
+ for (i = 0; i < HID_REPORT_TYPES; i++) {
+ struct hid_report_enum *report_enum = device->report_enum + i;
+
+- for (j = 0; j < 256; j++) {
++ for (j = 0; j < HID_MAX_IDS; j++) {
+ struct hid_report *report = report_enum->report_id_hash[j];
+ if (report)
+ hid_free_report(report);
+@@ -755,6 +759,56 @@ int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size)
+ }
+ EXPORT_SYMBOL_GPL(hid_parse_report);
+
++static const char * const hid_report_names[] = {
++ "HID_INPUT_REPORT",
++ "HID_OUTPUT_REPORT",
++ "HID_FEATURE_REPORT",
++};
++/**
++ * hid_validate_report - validate existing device report
++ *
++ * @device: hid device
++ * @type: which report type to examine
++ * @id: which report ID to examine (0 for first)
++ * @fields: expected number of fields
++ * @report_counts: expected number of values per field
++ *
++ * Validate the report details after parsing.
++ */
++struct hid_report *hid_validate_report(struct hid_device *hid,
++ unsigned int type, unsigned int id,
++ unsigned int fields,
++ unsigned int report_counts)
++{
++ struct hid_report *report;
++ unsigned int i;
++
++ if (type > HID_FEATURE_REPORT) {
++ hid_err(hid, "invalid HID report %u\n", type);
++ return NULL;
++ }
++
++ report = hid->report_enum[type].report_id_hash[id];
++ if (!report) {
++ hid_err(hid, "missing %s %u\n", hid_report_names[type], id);
++ return NULL;
++ }
++ if (report->maxfield < fields) {
++ hid_err(hid, "not enough fields in %s %u\n",
++ hid_report_names[type], id);
++ return NULL;
++ }
++ for (i = 0; i < fields; i++) {
++ if (report->field[i]->report_count < report_counts) {
++ hid_err(hid, "not enough values in %s %u fields\n",
++ hid_report_names[type], id);
++ return NULL;
++ }
++ }
++ return report;
++}
++EXPORT_SYMBOL_GPL(hid_validate_report);
++
+ /**
+ * hid_open_report - open a driver-specific device report
+ *
+@@ -1152,7 +1206,12 @@ EXPORT_SYMBOL_GPL(hid_output_report);
+
+ int hid_set_field(struct hid_field *field, unsigned offset, __s32 value)
+ {
+- unsigned size = field->report_size;
++ unsigned size;
++
++ if (!field)
++ return -1;
++
++ size = field->report_size;
+
+ hid_dump_input(field->report->device, field->usage + offset, value);
+
+@@ -2275,7 +2334,7 @@ EXPORT_SYMBOL_GPL(hid_ignore);
int hid_add_device(struct hid_device *hdev)
{
int ret;
if (WARN_ON(hdev->status & HID_STAT_ADDED))
-@@ -2309,7 +2309,7 @@ int hid_add_device(struct hid_device *hdev)
+@@ -2309,7 +2368,7 @@ int hid_add_device(struct hid_device *hdev)
/* XXX hack, any other cleaner solution after the driver core
* is converted to allow more than 20 bytes as the device name? */
dev_set_name(&hdev->dev, "%04X:%04X:%04X.%04X", hdev->bus,
hid_debug_register(hdev, dev_name(&hdev->dev));
ret = device_add(&hdev->dev);
+diff --git a/drivers/hid/hid-lenovo-tpkbd.c b/drivers/hid/hid-lenovo-tpkbd.c
+index 07837f5..b697ada 100644
+--- a/drivers/hid/hid-lenovo-tpkbd.c
++++ b/drivers/hid/hid-lenovo-tpkbd.c
+@@ -341,6 +341,11 @@ static int tpkbd_probe_tp(struct hid_device *hdev)
+ char *name_mute, *name_micmute;
+ int ret;
+
++ /* Validate required reports. */
++ if (!hid_validate_report(hdev, HID_OUTPUT_REPORT, 4, 4, 1) ||
++ !hid_validate_report(hdev, HID_OUTPUT_REPORT, 3, 1, 2))
++ return -ENODEV;
++
+ if (sysfs_create_group(&hdev->dev.kobj,
+ &tpkbd_attr_group_pointer)) {
+ hid_warn(hdev, "Could not create sysfs group\n");
+diff --git a/drivers/hid/hid-lg2ff.c b/drivers/hid/hid-lg2ff.c
+index b3cd150..9805197 100644
+--- a/drivers/hid/hid-lg2ff.c
++++ b/drivers/hid/hid-lg2ff.c
+@@ -64,26 +64,13 @@ int lg2ff_init(struct hid_device *hid)
+ struct hid_report *report;
+ struct hid_input *hidinput = list_entry(hid->inputs.next,
+ struct hid_input, list);
+- struct list_head *report_list =
+- &hid->report_enum[HID_OUTPUT_REPORT].report_list;
+ struct input_dev *dev = hidinput->input;
+ int error;
+
+- if (list_empty(report_list)) {
+- hid_err(hid, "no output report found\n");
++ /* Check that the report looks ok */
++ report = hid_validate_report(hid, HID_OUTPUT_REPORT, 0, 1, 7);
++ if (!report)
+ return -ENODEV;
+- }
+-
+- report = list_entry(report_list->next, struct hid_report, list);
+-
+- if (report->maxfield < 1) {
+- hid_err(hid, "output report is empty\n");
+- return -ENODEV;
+- }
+- if (report->field[0]->report_count < 7) {
+- hid_err(hid, "not enough values in the field\n");
+- return -ENODEV;
+- }
+
+ lg2ff = kmalloc(sizeof(struct lg2ff_device), GFP_KERNEL);
+ if (!lg2ff)
+diff --git a/drivers/hid/hid-lg3ff.c b/drivers/hid/hid-lg3ff.c
+index e52f181..53ac79b 100644
+--- a/drivers/hid/hid-lg3ff.c
++++ b/drivers/hid/hid-lg3ff.c
+@@ -66,10 +66,11 @@ static int hid_lg3ff_play(struct input_dev *dev, void *data,
+ int x, y;
+
+ /*
+- * Maxusage should always be 63 (maximum fields)
+- * likely a better way to ensure this data is clean
++ * Available values in the field should always be 63, but we only use up to
++ * 35. Instead, clear the entire area, however big it is.
+ */
+- memset(report->field[0]->value, 0, sizeof(__s32)*report->field[0]->maxusage);
++ memset(report->field[0]->value, 0,
++ sizeof(__s32) * report->field[0]->report_count);
+
+ switch (effect->type) {
+ case FF_CONSTANT:
+@@ -129,32 +130,14 @@ static const signed short ff3_joystick_ac[] = {
+ int lg3ff_init(struct hid_device *hid)
+ {
+ struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
+- struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
+ struct input_dev *dev = hidinput->input;
+- struct hid_report *report;
+- struct hid_field *field;
+ const signed short *ff_bits = ff3_joystick_ac;
+ int error;
+ int i;
+
+- /* Find the report to use */
+- if (list_empty(report_list)) {
+- hid_err(hid, "No output report found\n");
+- return -1;
+- }
+-
+ /* Check that the report looks ok */
+- report = list_entry(report_list->next, struct hid_report, list);
+- if (!report) {
+- hid_err(hid, "NULL output report\n");
+- return -1;
+- }
+-
+- field = report->field[0];
+- if (!field) {
+- hid_err(hid, "NULL field\n");
+- return -1;
+- }
++ if (!hid_validate_report(hid, HID_OUTPUT_REPORT, 0, 1, 35))
++ return -ENODEV;
+
+ /* Assume single fixed device G940 */
+ for (i = 0; ff_bits[i] >= 0; i++)
+diff --git a/drivers/hid/hid-lg4ff.c b/drivers/hid/hid-lg4ff.c
+index 0ddae2a..8b89f0f 100644
+--- a/drivers/hid/hid-lg4ff.c
++++ b/drivers/hid/hid-lg4ff.c
+@@ -484,34 +484,16 @@ static enum led_brightness lg4ff_led_get_brightness(struct led_classdev *led_cde
+ int lg4ff_init(struct hid_device *hid)
+ {
+ struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
+- struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
+ struct input_dev *dev = hidinput->input;
+- struct hid_report *report;
+- struct hid_field *field;
+ struct lg4ff_device_entry *entry;
+ struct lg_drv_data *drv_data;
+ struct usb_device_descriptor *udesc;
+ int error, i, j;
+ __u16 bcdDevice, rev_maj, rev_min;
+
+- /* Find the report to use */
+- if (list_empty(report_list)) {
+- hid_err(hid, "No output report found\n");
+- return -1;
+- }
+-
+ /* Check that the report looks ok */
+- report = list_entry(report_list->next, struct hid_report, list);
+- if (!report) {
+- hid_err(hid, "NULL output report\n");
++ if (!hid_validate_report(hid, HID_OUTPUT_REPORT, 0, 1, 7))
+ return -1;
+- }
+-
+- field = report->field[0];
+- if (!field) {
+- hid_err(hid, "NULL field\n");
+- return -1;
+- }
+
+ /* Check what wheel has been connected */
+ for (i = 0; i < ARRAY_SIZE(lg4ff_devices); i++) {
+diff --git a/drivers/hid/hid-lgff.c b/drivers/hid/hid-lgff.c
+index d7ea8c8..a84fb40 100644
+--- a/drivers/hid/hid-lgff.c
++++ b/drivers/hid/hid-lgff.c
+@@ -128,27 +128,14 @@ static void hid_lgff_set_autocenter(struct input_dev *dev, u16 magnitude)
+ int lgff_init(struct hid_device* hid)
+ {
+ struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
+- struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
+ struct input_dev *dev = hidinput->input;
+- struct hid_report *report;
+- struct hid_field *field;
+ const signed short *ff_bits = ff_joystick;
+ int error;
+ int i;
+
+- /* Find the report to use */
+- if (list_empty(report_list)) {
+- hid_err(hid, "No output report found\n");
+- return -1;
+- }
+-
+ /* Check that the report looks ok */
+- report = list_entry(report_list->next, struct hid_report, list);
+- field = report->field[0];
+- if (!field) {
+- hid_err(hid, "NULL field\n");
+- return -1;
+- }
++ if (!hid_validate_report(hid, HID_OUTPUT_REPORT, 0, 1, 7))
++ return -ENODEV;
+
+ for (i = 0; i < ARRAY_SIZE(devices); i++) {
+ if (dev->id.vendor == devices[i].idVendor &&
+diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c
+index 5207591a..6c9197f 100644
+--- a/drivers/hid/hid-logitech-dj.c
++++ b/drivers/hid/hid-logitech-dj.c
+@@ -421,7 +421,7 @@ static int logi_dj_recv_send_report(struct dj_receiver_dev *djrcv_dev,
+ struct hid_report *report;
+ struct hid_report_enum *output_report_enum;
+ u8 *data = (u8 *)(&dj_report->device_index);
+- int i;
++ unsigned int i, length;
+
+ output_report_enum = &hdev->report_enum[HID_OUTPUT_REPORT];
+ report = output_report_enum->report_id_hash[REPORT_ID_DJ_SHORT];
+@@ -431,7 +431,9 @@ static int logi_dj_recv_send_report(struct dj_receiver_dev *djrcv_dev,
+ return -ENODEV;
+ }
+
+- for (i = 0; i < report->field[0]->report_count; i++)
++ length = min_t(size_t, sizeof(*dj_report) - 1,
++ report->field[0]->report_count);
++ for (i = 0; i < length; i++)
+ report->field[0]->value[i] = data[i];
+
+ hid_hw_request(hdev, report, HID_REQ_SET_REPORT);
+@@ -738,6 +740,12 @@ static int logi_dj_probe(struct hid_device *hdev,
+ goto hid_parse_fail;
+ }
+
++ if (!hid_validate_report(hdev, HID_OUTPUT_REPORT, REPORT_ID_DJ_SHORT,
++ 1, 3)) {
++ retval = -ENODEV;
++ goto hid_parse_fail;
++ }
++
+ /* Starts the usb device and connects to upper interfaces hiddev and
+ * hidraw */
+ retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
+diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
+index d39a5ce..4892dfc 100644
+--- a/drivers/hid/hid-multitouch.c
++++ b/drivers/hid/hid-multitouch.c
+@@ -330,9 +330,18 @@ static void mt_feature_mapping(struct hid_device *hdev,
+ break;
+ }
+ }
++ /* Ignore if value index is out of bounds. */
++ if (td->inputmode_index < 0 ||
++ td->inputmode_index >= field->report_count) {
++ dev_err(&hdev->dev, "HID_DG_INPUTMODE out of range\n");
++ td->inputmode = -1;
++ }
+
+ break;
+ case HID_DG_CONTACTMAX:
++ /* Ignore if value count is out of bounds. */
++ if (field->report_count < 1)
++ break;
+ td->maxcontact_report_id = field->report->id;
+ td->maxcontacts = field->value[0];
+ if (!td->maxcontacts &&
+@@ -743,15 +752,21 @@ static void mt_touch_report(struct hid_device *hid, struct hid_report *report)
+ unsigned count;
+ int r, n;
+
++ if (report->maxfield == 0)
++ return;
++
+ /*
+ * Includes multi-packet support where subsequent
+ * packets are sent with zero contactcount.
+ */
+- if (td->cc_index >= 0) {
+- struct hid_field *field = report->field[td->cc_index];
+- int value = field->value[td->cc_value_index];
+- if (value)
+- td->num_expected = value;
++ if (td->cc_index >= 0 && td->cc_index < report->maxfield) {
++ field = report->field[td->cc_index];
++ if (td->cc_value_index >= 0 &&
++ td->cc_value_index < field->report_count) {
++ int value = field->value[td->cc_value_index];
++ if (value)
++ td->num_expected = value;
++ }
+ }
+
+ for (r = 0; r < report->maxfield; r++) {
+diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c
+index ef95102..5482156 100644
+--- a/drivers/hid/hid-ntrig.c
++++ b/drivers/hid/hid-ntrig.c
+@@ -115,7 +115,8 @@ static inline int ntrig_get_mode(struct hid_device *hdev)
+ struct hid_report *report = hdev->report_enum[HID_FEATURE_REPORT].
+ report_id_hash[0x0d];
+
+- if (!report)
++ if (!report || report->maxfield < 1 ||
++ report->field[0]->report_count < 1)
+ return -EINVAL;
+
+ hid_hw_request(hdev, report, HID_REQ_GET_REPORT);
+diff --git a/drivers/hid/hid-picolcd_core.c b/drivers/hid/hid-picolcd_core.c
+index b48092d..72bba1e 100644
+--- a/drivers/hid/hid-picolcd_core.c
++++ b/drivers/hid/hid-picolcd_core.c
+@@ -290,7 +290,7 @@ static ssize_t picolcd_operation_mode_store(struct device *dev,
+ buf += 10;
+ cnt -= 10;
+ }
+- if (!report)
++ if (!report || report->maxfield < 1)
+ return -EINVAL;
+
+ while (cnt > 0 && (buf[cnt-1] == '\n' || buf[cnt-1] == '\r'))
+diff --git a/drivers/hid/hid-pl.c b/drivers/hid/hid-pl.c
+index d29112f..2dcd7d9 100644
+--- a/drivers/hid/hid-pl.c
++++ b/drivers/hid/hid-pl.c
+@@ -132,8 +132,14 @@ static int plff_init(struct hid_device *hid)
+ strong = &report->field[0]->value[2];
+ weak = &report->field[0]->value[3];
+ debug("detected single-field device");
+- } else if (report->maxfield >= 4 && report->field[0]->maxusage == 1 &&
+- report->field[0]->usage[0].hid == (HID_UP_LED | 0x43)) {
++ } else if (report->field[0]->maxusage == 1 &&
++ report->field[0]->usage[0].hid ==
++ (HID_UP_LED | 0x43) &&
++ report->maxfield >= 4 &&
++ report->field[0]->report_count >= 1 &&
++ report->field[1]->report_count >= 1 &&
++ report->field[2]->report_count >= 1 &&
++ report->field[3]->report_count >= 1) {
+ report->field[0]->value[0] = 0x00;
+ report->field[1]->value[0] = 0x00;
+ strong = &report->field[2]->value[0];
+diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c
+index ca749810..aa34755 100644
+--- a/drivers/hid/hid-sensor-hub.c
++++ b/drivers/hid/hid-sensor-hub.c
+@@ -221,7 +221,8 @@ int sensor_hub_get_feature(struct hid_sensor_hub_device *hsdev, u32 report_id,
+
+ mutex_lock(&data->mutex);
+ report = sensor_hub_report(report_id, hsdev->hdev, HID_FEATURE_REPORT);
+- if (!report || (field_index >= report->maxfield)) {
++ if (!report || (field_index >= report->maxfield) ||
++ report->field[field_index]->report_count < 1) {
+ ret = -EINVAL;
+ goto done_proc;
+ }
+diff --git a/drivers/hid/hid-steelseries.c b/drivers/hid/hid-steelseries.c
+index d164911..ef42e86 100644
+--- a/drivers/hid/hid-steelseries.c
++++ b/drivers/hid/hid-steelseries.c
+@@ -249,6 +249,11 @@ static int steelseries_srws1_probe(struct hid_device *hdev,
+ goto err_free;
+ }
+
++ if (!hid_validate_report(hdev, HID_OUTPUT_REPORT, 0, 1, 16)) {
++ ret = -ENODEV;
++ goto err_free;
++ }
++
+ ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
+ if (ret) {
+ hid_err(hdev, "hw start failed\n");
diff --git a/drivers/hid/hid-wiimote-debug.c b/drivers/hid/hid-wiimote-debug.c
index 90124ff..3761764 100644
--- a/drivers/hid/hid-wiimote-debug.c
return -EFAULT;
*off += size;
+diff --git a/drivers/hid/hid-zpff.c b/drivers/hid/hid-zpff.c
+index 6ec28a3..b124991 100644
+--- a/drivers/hid/hid-zpff.c
++++ b/drivers/hid/hid-zpff.c
+@@ -68,22 +68,12 @@ static int zpff_init(struct hid_device *hid)
+ struct hid_report *report;
+ struct hid_input *hidinput = list_entry(hid->inputs.next,
+ struct hid_input, list);
+- struct list_head *report_list =
+- &hid->report_enum[HID_OUTPUT_REPORT].report_list;
+ struct input_dev *dev = hidinput->input;
+ int error;
+
+- if (list_empty(report_list)) {
+- hid_err(hid, "no output report found\n");
++ report = hid_validate_report(hid, HID_OUTPUT_REPORT, 0, 4, 1);
++ if (!report)
+ return -ENODEV;
+- }
+-
+- report = list_entry(report_list->next, struct hid_report, list);
+-
+- if (report->maxfield < 4) {
+- hid_err(hid, "not enough fields in report\n");
+- return -ENODEV;
+- }
+
+ zpff = kzalloc(sizeof(struct zpff_device), GFP_KERNEL);
+ if (!zpff)
+diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c
+index fc307e0..2b255e8 100644
+--- a/drivers/hid/uhid.c
++++ b/drivers/hid/uhid.c
+@@ -47,7 +47,7 @@ struct uhid_device {
+ struct mutex report_lock;
+ wait_queue_head_t report_wait;
+ atomic_t report_done;
+- atomic_t report_id;
++ atomic_unchecked_t report_id;
+ struct uhid_event report_buf;
+ };
+
+@@ -187,7 +187,7 @@ static int uhid_hid_get_raw(struct hid_device *hid, unsigned char rnum,
+
+ spin_lock_irqsave(&uhid->qlock, flags);
+ ev->type = UHID_FEATURE;
+- ev->u.feature.id = atomic_inc_return(&uhid->report_id);
++ ev->u.feature.id = atomic_inc_return_unchecked(&uhid->report_id);
+ ev->u.feature.rnum = rnum;
+ ev->u.feature.rtype = report_type;
+
+@@ -471,7 +471,7 @@ static int uhid_dev_feature_answer(struct uhid_device *uhid,
+ spin_lock_irqsave(&uhid->qlock, flags);
+
+ /* id for old report; drop it silently */
+- if (atomic_read(&uhid->report_id) != ev->u.feature_answer.id)
++ if (atomic_read_unchecked(&uhid->report_id) != ev->u.feature_answer.id)
+ goto unlock;
+ if (atomic_read(&uhid->report_done))
+ goto unlock;
diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c
index 0b122f8..b1d8160 100644
--- a/drivers/hv/channel.c
tty_port_tty_set(&cs->port, NULL);
mutex_unlock(&cs->mutex);
+diff --git a/drivers/isdn/gigaset/usb-gigaset.c b/drivers/isdn/gigaset/usb-gigaset.c
+index d0a41cb..f0cdb8c 100644
+--- a/drivers/isdn/gigaset/usb-gigaset.c
++++ b/drivers/isdn/gigaset/usb-gigaset.c
+@@ -547,7 +547,7 @@ static int gigaset_brkchars(struct cardstate *cs, const unsigned char buf[6])
+ gigaset_dbg_buffer(DEBUG_USBREQ, "brkchars", 6, buf);
+ memcpy(cs->hw.usb->bchars, buf, 6);
+ return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x19, 0x41,
+- 0, 0, &buf, 6, 2000);
++ 0, 0, buf, 6, 2000);
+ }
+
+ static void gigaset_freebcshw(struct bc_state *bcs)
diff --git a/drivers/isdn/hardware/avm/b1.c b/drivers/isdn/hardware/avm/b1.c
index 4d9b195..455075c 100644
--- a/drivers/isdn/hardware/avm/b1.c
return -EFAULT;
} else {
memcpy(buf, dp, left);
+diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c
+index 9bb12ba..d4262f7 100644
+--- a/drivers/isdn/i4l/isdn_common.c
++++ b/drivers/isdn/i4l/isdn_common.c
+@@ -1651,6 +1651,8 @@ isdn_ioctl(struct file *file, uint cmd, ulong arg)
+ } else
+ return -EINVAL;
+ case IIOCDBGVAR:
++ if (!capable(CAP_SYS_RAWIO))
++ return -EPERM;
+ if (arg) {
+ if (copy_to_user(argp, &dev, sizeof(ulong)))
+ return -EFAULT;
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c
index 3c5f249..5fac4d0 100644
--- a/drivers/isdn/i4l/isdn_tty.c
memset(buf, 0, sizeof(buf));
buf_size = min(count, sizeof(buf) - 1);
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c
-index 50ba0a4..29424e7 100644
+index aeb70e1..d7b5bb5 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -1329,7 +1329,7 @@ static ssize_t iwl_dbgfs_interrupt_write(struct file *file,
if (atomic_read(&urb->reject))
wake_up(&usb_kill_urb_queue);
usb_put_urb(urb);
+diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
+index da2905a..834a569 100644
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -27,6 +27,7 @@
+ #include <linux/freezer.h>
+ #include <linux/random.h>
+ #include <linux/pm_qos.h>
++#include <linux/grsecurity.h>
+
+ #include <asm/uaccess.h>
+ #include <asm/byteorder.h>
+@@ -4424,6 +4425,10 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
+ goto done;
+ return;
+ }
++
++ if (gr_handle_new_usb())
++ goto done;
++
+ if (hub_is_superspeed(hub->hdev))
+ unit_load = 150;
+ else
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index 444d30e..f15c850 100644
--- a/drivers/usb/core/message.c
INIT_LIST_HEAD(&dev->ep0.urb_list);
dev->ep0.desc.bLength = USB_DT_ENDPOINT_SIZE;
+diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
+index f77083f..f3e2e34 100644
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -550,8 +550,6 @@ static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep,
+ if (!usb_endpoint_xfer_isoc(desc))
+ return 0;
+
+- memset(&trb_link, 0, sizeof(trb_link));
+-
+ /* Link TRB for ISOC. The HWO bit is never reset */
+ trb_st_hw = &dep->trb_pool[0];
+
diff --git a/drivers/usb/early/ehci-dbgp.c b/drivers/usb/early/ehci-dbgp.c
index 5e29dde..eca992f 100644
--- a/drivers/usb/early/ehci-dbgp.c
goto err;
}
diff --git a/fs/bio.c b/fs/bio.c
-index 94bbc04..6fe78a4 100644
+index c5eae72..599e3cf 100644
--- a/fs/bio.c
+++ b/fs/bio.c
-@@ -1096,7 +1096,7 @@ struct bio *bio_copy_user_iov(struct request_queue *q,
+@@ -1106,7 +1106,7 @@ struct bio *bio_copy_user_iov(struct request_queue *q,
/*
* Overflow, abort
*/
return ERR_PTR(-EINVAL);
nr_pages += end - start;
-@@ -1230,7 +1230,7 @@ static struct bio *__bio_map_user_iov(struct request_queue *q,
+@@ -1240,7 +1240,7 @@ static struct bio *__bio_map_user_iov(struct request_queue *q,
/*
* Overflow, abort
*/
return ERR_PTR(-EINVAL);
nr_pages += end - start;
-@@ -1492,7 +1492,7 @@ static void bio_copy_kern_endio(struct bio *bio, int err)
+@@ -1502,7 +1502,7 @@ static void bio_copy_kern_endio(struct bio *bio, int err)
const int read = bio_data_dir(bio) == READ;
struct bio_map_data *bmd = bio->bi_private;
int i;
out:
return len;
diff --git a/fs/namespace.c b/fs/namespace.c
-index 7b1ca9b..6faeccf 100644
+index a45ba4f..e7dc489 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -1265,6 +1265,9 @@ static int do_umount(struct mount *mnt, int flags)
"inode 0x%lx or driver bug.", vdir->i_ino);
goto err_out;
diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c
-index c5670b8..01a3656 100644
+index c5670b8..2b43d9b 100644
--- a/fs/ntfs/file.c
+++ b/fs/ntfs/file.c
+@@ -1282,7 +1282,7 @@ static inline size_t ntfs_copy_from_user(struct page **pages,
+ char *addr;
+ size_t total = 0;
+ unsigned len;
+- int left;
++ unsigned left;
+
+ do {
+ len = PAGE_CACHE_SIZE - ofs;
@@ -2241,6 +2241,6 @@ const struct inode_operations ntfs_file_inode_ops = {
#endif /* NTFS_RW */
};
kfree(s);
diff --git a/grsecurity/Kconfig b/grsecurity/Kconfig
new file mode 100644
-index 0000000..712a85d
+index 0000000..76e84b9
--- /dev/null
+++ b/grsecurity/Kconfig
-@@ -0,0 +1,1043 @@
+@@ -0,0 +1,1063 @@
+#
+# grecurity configuration
+#
+ option with name "socket_server_gid" is created.
+
+endmenu
++
++menu "Physical Protections"
++depends on GRKERNSEC
++
++config GRKERNSEC_DENYUSB
++ bool "Deny new USB connections after toggle"
++ default y if GRKERNSEC_CONFIG_AUTO
++ help
++ If you say Y here, a new sysctl option with name "deny_new_usb"
++ will be created. Setting its value to 1 will prevent any new
++ USB devices from being recognized by the OS. Any attempted USB
++ device insertion will be logged. This option is intended to be
++ used against custom USB devices designed to exploit vulnerabilities
++ in various USB device drivers.
++
++ For greatest effectiveness, this sysctl should be set after any
++ relevant init scripts. Once set, it cannot be unset.
++
++endmenu
++
+menu "Sysctl Support"
+depends on GRKERNSEC && SYSCTL
+
+endmenu
diff --git a/grsecurity/Makefile b/grsecurity/Makefile
new file mode 100644
-index 0000000..36845aa
+index 0000000..b0b77d5
--- /dev/null
+++ b/grsecurity/Makefile
-@@ -0,0 +1,42 @@
+@@ -0,0 +1,43 @@
+# grsecurity's ACL system was originally written in 2001 by Michael Dalton
+# during 2001-2009 it has been completely redesigned by Brad Spengler
+# into an RBAC system
+
+obj-y = grsec_chdir.o grsec_chroot.o grsec_exec.o grsec_fifo.o grsec_fork.o \
+ grsec_mount.o grsec_sig.o grsec_sysctl.o \
-+ grsec_time.o grsec_tpe.o grsec_link.o grsec_pax.o grsec_ptrace.o
++ grsec_time.o grsec_tpe.o grsec_link.o grsec_pax.o grsec_ptrace.o \
++ grsec_usb.o
+
+obj-$(CONFIG_GRKERNSEC) += grsec_init.o grsum.o gracl.o gracl_segv.o \
+ gracl_cap.o gracl_alloc.o gracl_shm.o grsec_mem.o gracl_fs.o \
+}
diff --git a/grsecurity/grsec_init.c b/grsecurity/grsec_init.c
new file mode 100644
-index 0000000..ab2d875
+index 0000000..836f38f
--- /dev/null
+++ b/grsecurity/grsec_init.c
-@@ -0,0 +1,279 @@
+@@ -0,0 +1,280 @@
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+int grsec_enable_chdir;
+int grsec_enable_mount;
+int grsec_enable_rofs;
++int grsec_deny_new_usb;
+int grsec_enable_chroot_findtask;
+int grsec_enable_chroot_mount;
+int grsec_enable_chroot_shmat;
+}
diff --git a/grsecurity/grsec_sysctl.c b/grsecurity/grsec_sysctl.c
new file mode 100644
-index 0000000..7624d1c
+index 0000000..301c665
--- /dev/null
+++ b/grsecurity/grsec_sysctl.c
-@@ -0,0 +1,460 @@
+@@ -0,0 +1,471 @@
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/sysctl.h>
+ .extra2 = &one,
+ },
+#endif
++#ifdef CONFIG_GRKERNSEC_DENYUSB
++ {
++ .procname = "deny_new_usb",
++ .data = &grsec_deny_new_usb,
++ .maxlen = sizeof(int),
++ .mode = 0600,
++ .proc_handler = &proc_dointvec_minmax,
++ .extra1 = &one,
++ .extra2 = &one,
++ },
++#endif
+ { }
+};
+#endif
+#endif
+ return 1;
+}
+diff --git a/grsecurity/grsec_usb.c b/grsecurity/grsec_usb.c
+new file mode 100644
+index 0000000..ae02d8e
+--- /dev/null
++++ b/grsecurity/grsec_usb.c
+@@ -0,0 +1,15 @@
++#include <linux/kernel.h>
++#include <linux/grinternal.h>
++#include <linux/module.h>
++
++int gr_handle_new_usb(void)
++{
++#ifdef CONFIG_GRKERNSEC_DENYUSB
++ if (grsec_deny_new_usb) {
++ printk(KERN_ALERT "grsec: denied insert of new USB device\n");
++ return 1;
++ }
++#endif
++ return 0;
++}
++EXPORT_SYMBOL_GPL(gr_handle_new_usb);
diff --git a/grsecurity/grsum.c b/grsecurity/grsum.c
new file mode 100644
index 0000000..9f7b1ac
+#endif
diff --git a/include/linux/grinternal.h b/include/linux/grinternal.h
new file mode 100644
-index 0000000..fd8598b
+index 0000000..e337683
--- /dev/null
+++ b/include/linux/grinternal.h
-@@ -0,0 +1,228 @@
+@@ -0,0 +1,229 @@
+#ifndef __GRINTERNAL_H
+#define __GRINTERNAL_H
+
+extern int grsec_enable_forkfail;
+extern int grsec_enable_time;
+extern int grsec_enable_rofs;
++extern int grsec_deny_new_usb;
+extern int grsec_enable_chroot_shmat;
+extern int grsec_enable_chroot_mount;
+extern int grsec_enable_chroot_double;
+#define GR_BRUTE_SUID_MSG "bruteforce prevention initiated due to crash of %.950s against uid %u, banning suid/sgid execs for %u minutes. Please investigate the crash report for "
diff --git a/include/linux/grsecurity.h b/include/linux/grsecurity.h
new file mode 100644
-index 0000000..3676b0b
+index 0000000..d6f5a21
--- /dev/null
+++ b/include/linux/grsecurity.h
-@@ -0,0 +1,242 @@
+@@ -0,0 +1,244 @@
+#ifndef GR_SECURITY_H
+#define GR_SECURITY_H
+#include <linux/fs.h>
+#error "CONFIG_PAX enabled, but no PaX options are enabled."
+#endif
+
++int gr_handle_new_usb(void);
++
+void gr_handle_brute_attach(unsigned long mm_flags);
+void gr_handle_brute_check(void);
+void gr_handle_kernel_exploit(void);
+ const int protocol);
+
+#endif
+diff --git a/include/linux/hid.h b/include/linux/hid.h
+index 0c48991..76e41d8 100644
+--- a/include/linux/hid.h
++++ b/include/linux/hid.h
+@@ -393,10 +393,12 @@ struct hid_report {
+ struct hid_device *device; /* associated device */
+ };
+
++#define HID_MAX_IDS 256
++
+ struct hid_report_enum {
+ unsigned numbered;
+ struct list_head report_list;
+- struct hid_report *report_id_hash[256];
++ struct hid_report *report_id_hash[HID_MAX_IDS];
+ };
+
+ #define HID_REPORT_TYPES 3
+@@ -747,6 +749,10 @@ void hid_output_report(struct hid_report *report, __u8 *data);
+ struct hid_device *hid_allocate_device(void);
+ struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id);
+ int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size);
++struct hid_report *hid_validate_report(struct hid_device *hid,
++ unsigned int type, unsigned int id,
++ unsigned int fields,
++ unsigned int report_counts);
+ int hid_open_report(struct hid_device *device);
+ int hid_check_keys_pressed(struct hid_device *hid);
+ int hid_connect(struct hid_device *hid, unsigned int connect_mask);
diff --git a/include/linux/highmem.h b/include/linux/highmem.h
index 7fb31da..08b5114 100644
--- a/include/linux/highmem.h
#endif /* __KERNEL__ */
#endif /* _LINUX_MM_H */
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
-index ace9a5f..81bdb59 100644
+index 4a189ba..04101d6 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -289,6 +289,8 @@ struct vm_area_struct {
};
struct core_thread {
-@@ -437,6 +439,24 @@ struct mm_struct {
+@@ -438,6 +440,24 @@ struct mm_struct {
int first_nid;
#endif
struct uprobes_state uprobes_state;
static inline void anon_vma_merge(struct vm_area_struct *vma,
struct vm_area_struct *next)
diff --git a/include/linux/sched.h b/include/linux/sched.h
-index 3aeb14b..73816a6 100644
+index 178a8d9..918ea01 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -62,6 +62,7 @@ struct bio_list;
extern signed long schedule_timeout_interruptible(signed long timeout);
extern signed long schedule_timeout_killable(signed long timeout);
extern signed long schedule_timeout_uninterruptible(signed long timeout);
-@@ -314,7 +315,19 @@ struct nsproxy;
+@@ -314,6 +315,18 @@ struct nsproxy;
struct user_namespace;
#ifdef CONFIG_MMU
--extern unsigned long mmap_legacy_base(void);
+
+#ifdef CONFIG_GRKERNSEC_RAND_THREADSTACK
+extern unsigned long gr_rand_threadstack_offset(const struct mm_struct *mm, const struct file *filp, unsigned long flags);
+
+extern bool check_heap_stack_gap(const struct vm_area_struct *vma, unsigned long addr, unsigned long len, unsigned long offset);
+extern unsigned long skip_heap_stack_gap(const struct vm_area_struct *vma, unsigned long len, unsigned long offset);
-+extern unsigned long mmap_legacy_base(struct mm_struct *mm);
extern void arch_pick_mmap_layout(struct mm_struct *mm);
extern unsigned long
arch_get_unmapped_area(struct file *, unsigned long, unsigned long,
-@@ -592,6 +605,17 @@ struct signal_struct {
+@@ -591,6 +604,17 @@ struct signal_struct {
#ifdef CONFIG_TASKSTATS
struct taskstats *stats;
#endif
#ifdef CONFIG_AUDIT
unsigned audit_tty;
unsigned audit_tty_log_passwd;
-@@ -672,6 +696,14 @@ struct user_struct {
+@@ -671,6 +695,14 @@ struct user_struct {
struct key *session_keyring; /* UID's default session keyring */
#endif
/* Hash table maintenance information */
struct hlist_node uidhash_node;
kuid_t uid;
-@@ -1159,8 +1191,8 @@ struct task_struct {
+@@ -1158,8 +1190,8 @@ struct task_struct {
struct list_head thread_group;
struct completion *vfork_done; /* for vfork() */
cputime_t utime, stime, utimescaled, stimescaled;
cputime_t gtime;
-@@ -1185,11 +1217,6 @@ struct task_struct {
+@@ -1184,11 +1216,6 @@ struct task_struct {
struct task_cputime cputime_expires;
struct list_head cpu_timers[3];
char comm[TASK_COMM_LEN]; /* executable name excluding path
- access with [gs]et_task_comm (which lock
it with task_lock())
-@@ -1206,6 +1233,10 @@ struct task_struct {
+@@ -1205,6 +1232,10 @@ struct task_struct {
#endif
/* CPU-specific state of this task */
struct thread_struct thread;
/* filesystem information */
struct fs_struct *fs;
/* open file information */
-@@ -1279,6 +1310,10 @@ struct task_struct {
+@@ -1278,6 +1309,10 @@ struct task_struct {
gfp_t lockdep_reclaim_gfp;
#endif
/* journalling filesystem info */
void *journal_info;
-@@ -1317,6 +1352,10 @@ struct task_struct {
+@@ -1316,6 +1351,10 @@ struct task_struct {
/* cg_list protected by css_set_lock and tsk->alloc_lock */
struct list_head cg_list;
#endif
#ifdef CONFIG_FUTEX
struct robust_list_head __user *robust_list;
#ifdef CONFIG_COMPAT
-@@ -1417,8 +1456,76 @@ struct task_struct {
+@@ -1416,8 +1455,76 @@ struct task_struct {
unsigned int sequential_io;
unsigned int sequential_io_avg;
#endif
/* Future-safe accessor for struct task_struct's cpus_allowed. */
#define tsk_cpus_allowed(tsk) (&(tsk)->cpus_allowed)
-@@ -1477,7 +1584,7 @@ struct pid_namespace;
+@@ -1476,7 +1583,7 @@ struct pid_namespace;
pid_t __task_pid_nr_ns(struct task_struct *task, enum pid_type type,
struct pid_namespace *ns);
{
return tsk->pid;
}
-@@ -1920,7 +2027,9 @@ void yield(void);
+@@ -1919,7 +2026,9 @@ void yield(void);
extern struct exec_domain default_exec_domain;
union thread_union {
unsigned long stack[THREAD_SIZE/sizeof(long)];
};
-@@ -1953,6 +2062,7 @@ extern struct pid_namespace init_pid_ns;
+@@ -1952,6 +2061,7 @@ extern struct pid_namespace init_pid_ns;
*/
extern struct task_struct *find_task_by_vpid(pid_t nr);
extern struct task_struct *find_task_by_pid_ns(pid_t nr,
struct pid_namespace *ns);
-@@ -2119,7 +2229,7 @@ extern void __cleanup_sighand(struct sighand_struct *);
+@@ -2118,7 +2228,7 @@ extern void __cleanup_sighand(struct sighand_struct *);
extern void exit_itimers(struct signal_struct *);
extern void flush_itimer_signals(void);
extern int allow_signal(int);
extern int disallow_signal(int);
-@@ -2310,9 +2420,9 @@ static inline unsigned long *end_of_stack(struct task_struct *p)
+@@ -2309,9 +2419,9 @@ static inline unsigned long *end_of_stack(struct task_struct *p)
#endif
/*
diff --git a/kernel/events/internal.h b/kernel/events/internal.h
-index ca65997..cc8cee4 100644
+index ca65997..60df03d 100644
--- a/kernel/events/internal.h
+++ b/kernel/events/internal.h
@@ -81,10 +81,10 @@ static inline unsigned long perf_data_size(struct ring_buffer *rb)
}
-#define DEFINE_OUTPUT_COPY(func_name, memcpy_func) \
+-static inline unsigned int \
+#define DEFINE_OUTPUT_COPY(func_name, memcpy_func, user) \
- static inline unsigned int \
++static inline unsigned long \
func_name(struct perf_output_handle *handle, \
- const void *buf, unsigned int len) \
-+ const void user *buf, unsigned int len) \
++ const void user *buf, unsigned long len) \
{ \
unsigned long size, written; \
\
/* Callchain handling */
extern struct perf_callchain_entry *
+diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
+index f356974..cb8c570 100644
+--- a/kernel/events/uprobes.c
++++ b/kernel/events/uprobes.c
+@@ -1556,7 +1556,7 @@ static int is_trap_at_addr(struct mm_struct *mm, unsigned long vaddr)
+ {
+ struct page *page;
+ uprobe_opcode_t opcode;
+- int result;
++ long result;
+
+ pagefault_disable();
+ result = __copy_from_user_inatomic(&opcode, (void __user*)vaddr,
diff --git a/kernel/exit.c b/kernel/exit.c
index 7bb73f9..d7978ed 100644
--- a/kernel/exit.c
else
new_fs = fs;
diff --git a/kernel/futex.c b/kernel/futex.c
-index 49dacfb..5c6b450 100644
+index 49dacfb..2ac4526 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -54,6 +54,7 @@
/*
* The futex address must be "naturally" aligned.
*/
+@@ -440,7 +446,7 @@ static int cmpxchg_futex_value_locked(u32 *curval, u32 __user *uaddr,
+
+ static int get_futex_value_locked(u32 *dest, u32 __user *from)
+ {
+- int ret;
++ unsigned long ret;
+
+ pagefault_disable();
+ ret = __copy_from_user_inatomic(dest, from, sizeof(u32));
@@ -2733,6 +2739,7 @@ static int __init futex_init(void)
{
u32 curval;
ret = -EIO;
bt->dropped_file = debugfs_create_file("dropped", 0444, dir, bt,
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
-index 6c508ff..ee55a13 100644
+index f23449d..b8cc3a1 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
-@@ -1915,12 +1915,17 @@ ftrace_code_disable(struct module *mod, struct dyn_ftrace *rec)
+@@ -1925,12 +1925,17 @@ ftrace_code_disable(struct module *mod, struct dyn_ftrace *rec)
if (unlikely(ftrace_disabled))
return 0;
}
/*
-@@ -3931,8 +3936,10 @@ static int ftrace_process_locs(struct module *mod,
+@@ -3994,8 +3999,10 @@ static int ftrace_process_locs(struct module *mod,
if (!count)
return 0;
start_pg = ftrace_allocate_pages(count);
if (!start_pg)
-@@ -4655,8 +4662,6 @@ ftrace_enable_sysctl(struct ctl_table *table, int write,
+@@ -4718,8 +4725,6 @@ ftrace_enable_sysctl(struct ctl_table *table, int write,
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
static int ftrace_graph_active;
int ftrace_graph_entry_stub(struct ftrace_graph_ent *trace)
{
return 0;
-@@ -4800,6 +4805,10 @@ ftrace_suspend_notifier_call(struct notifier_block *bl, unsigned long state,
+@@ -4863,6 +4868,10 @@ ftrace_suspend_notifier_call(struct notifier_block *bl, unsigned long state,
return NOTIFY_DONE;
}
int register_ftrace_graph(trace_func_graph_ret_t retfunc,
trace_func_graph_ent_t entryfunc)
{
-@@ -4813,7 +4822,6 @@ int register_ftrace_graph(trace_func_graph_ret_t retfunc,
+@@ -4876,7 +4885,6 @@ int register_ftrace_graph(trace_func_graph_ret_t retfunc,
goto out;
}
*data_page = bpage;
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
-index 06a5bce..53ad6e7 100644
+index 0582a01..310bed1 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
-@@ -3347,7 +3347,7 @@ int trace_keep_overwrite(struct tracer *tracer, u32 mask, int set)
+@@ -3327,7 +3327,7 @@ int trace_keep_overwrite(struct tracer *tracer, u32 mask, int set)
return 0;
}
/*
* Normal trace_printk() and friends allocates special buffers
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
-index 6953263..2004e16 100644
+index 3d18aad..d1be0eb 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
-@@ -1748,10 +1748,6 @@ static LIST_HEAD(ftrace_module_file_list);
+@@ -1794,10 +1794,6 @@ static LIST_HEAD(ftrace_module_file_list);
struct ftrace_module_file_ops {
struct list_head list;
struct module *mod;
};
static struct ftrace_module_file_ops *
-@@ -1792,17 +1788,12 @@ trace_create_file_ops(struct module *mod)
+@@ -1838,17 +1834,12 @@ trace_create_file_ops(struct module *mod)
file_ops->mod = mod;
list_add(&file_ops->list, &ftrace_module_file_list);
-@@ -1895,8 +1886,8 @@ __trace_add_new_mod_event(struct ftrace_event_call *call,
+@@ -1941,8 +1932,8 @@ __trace_add_new_mod_event(struct ftrace_event_call *call,
struct ftrace_module_file_ops *file_ops)
{
return __trace_add_new_event(call, tr,
bdi_destroy(bdi);
return err;
diff --git a/mm/filemap.c b/mm/filemap.c
-index 7905fe7..e60faa8 100644
+index 7905fe7..f59502b 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1766,7 +1766,7 @@ int generic_file_mmap(struct file * file, struct vm_area_struct * vma)
file_accessed(file);
vma->vm_ops = &generic_file_vm_ops;
return 0;
+@@ -1948,7 +1948,7 @@ static size_t __iovec_copy_from_user_inatomic(char *vaddr,
+
+ while (bytes) {
+ char __user *buf = iov->iov_base + base;
+- int copy = min(bytes, iov->iov_len - base);
++ size_t copy = min(bytes, iov->iov_len - base);
+
+ base = 0;
+ left = __copy_from_user_inatomic(vaddr, buf, copy);
+@@ -1977,7 +1977,7 @@ size_t iov_iter_copy_from_user_atomic(struct page *page,
+ BUG_ON(!in_atomic());
+ kaddr = kmap_atomic(page);
+ if (likely(i->nr_segs == 1)) {
+- int left;
++ size_t left;
+ char __user *buf = i->iov->iov_base + i->iov_offset;
+ left = __copy_from_user_inatomic(kaddr + offset, buf, bytes);
+ copied = bytes - left;
+@@ -2005,7 +2005,7 @@ size_t iov_iter_copy_from_user(struct page *page,
+
+ kaddr = kmap(page);
+ if (likely(i->nr_segs == 1)) {
+- int left;
++ size_t left;
+ char __user *buf = i->iov->iov_base + i->iov_offset;
+ left = __copy_from_user(kaddr + offset, buf, bytes);
+ copied = bytes - left;
+@@ -2035,7 +2035,7 @@ void iov_iter_advance(struct iov_iter *i, size_t bytes)
+ * zero-length segments (without overruning the iovec).
+ */
+ while (bytes || unlikely(i->count && !iov->iov_len)) {
+- int copy;
++ size_t copy;
+
+ copy = min(bytes, iov->iov_len - base);
+ BUG_ON(!i->count || i->count < copy);
@@ -2106,6 +2106,7 @@ inline int generic_write_checks(struct file *file, loff_t *pos, size_t *count, i
*pos = i_size_read(inode);
if (extfilt)
filter_mask = nla_get_u32(extfilt);
diff --git a/net/core/scm.c b/net/core/scm.c
-index 03795d0..eaf7368 100644
+index 03795d0..98d6bdb 100644
--- a/net/core/scm.c
+++ b/net/core/scm.c
+@@ -54,7 +54,7 @@ static __inline__ int scm_check_creds(struct ucred *creds)
+ return -EINVAL;
+
+ if ((creds->pid == task_tgid_vnr(current) ||
+- ns_capable(current->nsproxy->pid_ns->user_ns, CAP_SYS_ADMIN)) &&
++ ns_capable(task_active_pid_ns(current)->user_ns, CAP_SYS_ADMIN)) &&
+ ((uid_eq(uid, cred->uid) || uid_eq(uid, cred->euid) ||
+ uid_eq(uid, cred->suid)) || nsown_capable(CAP_SETUID)) &&
+ ((gid_eq(gid, cred->gid) || gid_eq(gid, cred->egid) ||
@@ -210,7 +210,7 @@ EXPORT_SYMBOL(__scm_send);
int put_cmsg(struct msghdr * msg, int level, int type, int len, void *data)
{
return -EFAULT;
*lenp = len;
+diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c
+index 55e1fd5..fd602b8 100644
+--- a/net/ieee802154/6lowpan.c
++++ b/net/ieee802154/6lowpan.c
+@@ -459,7 +459,7 @@ static int lowpan_header_create(struct sk_buff *skb,
+ hc06_ptr += 3;
+ } else {
+ /* compress nothing */
+- memcpy(hc06_ptr, &hdr, 4);
++ memcpy(hc06_ptr, hdr, 4);
+ /* replace the top byte with new ECN | DSCP format */
+ *hc06_ptr = tmp;
+ hc06_ptr += 4;
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index d01be2a..8976537 100644
--- a/net/ipv4/af_inet.c
return -ENOMEM;
}
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
-index fb8c94c..fb18024 100644
+index fb8c94c..80a31d8 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -621,7 +621,7 @@ static int inet6_netconf_dump_devconf(struct sk_buff *skb,
net->dev_base_seq;
hlist_for_each_entry_rcu(dev, head, index_hlist) {
if (idx < s_idx)
-@@ -2380,7 +2380,7 @@ int addrconf_set_dstaddr(struct net *net, void __user *arg)
+@@ -1124,12 +1124,10 @@ retry:
+ if (ifp->flags & IFA_F_OPTIMISTIC)
+ addr_flags |= IFA_F_OPTIMISTIC;
+
+- ift = !max_addresses ||
+- ipv6_count_addresses(idev) < max_addresses ?
+- ipv6_add_addr(idev, &addr, tmp_plen,
+- ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK,
+- addr_flags) : NULL;
+- if (IS_ERR_OR_NULL(ift)) {
++ ift = ipv6_add_addr(idev, &addr, tmp_plen,
++ ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK,
++ addr_flags);
++ if (IS_ERR(ift)) {
+ in6_ifa_put(ifp);
+ in6_dev_put(idev);
+ pr_info("%s: retry temporary address regeneration\n", __func__);
+@@ -2380,7 +2378,7 @@ int addrconf_set_dstaddr(struct net *net, void __user *arg)
p.iph.ihl = 5;
p.iph.protocol = IPPROTO_IPV6;
p.iph.ttl = 64;
if (ops->ndo_do_ioctl) {
mm_segment_t oldfs = get_fs();
-@@ -4002,7 +4002,7 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb,
+@@ -4002,7 +4000,7 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb,
s_ip_idx = ip_idx = cb->args[2];
rcu_read_lock();
for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
idx = 0;
head = &net->dev_index_head[h];
-@@ -4587,7 +4587,7 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
+@@ -4587,7 +4585,7 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
dst_free(&ifp->rt->dst);
break;
}
}
static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
-@@ -4607,7 +4607,7 @@ int addrconf_sysctl_forward(ctl_table *ctl, int write,
+@@ -4607,7 +4605,7 @@ int addrconf_sysctl_forward(ctl_table *ctl, int write,
int *valp = ctl->data;
int val = *valp;
loff_t pos = *ppos;
int ret;
/*
-@@ -4689,7 +4689,7 @@ int addrconf_sysctl_disable(ctl_table *ctl, int write,
+@@ -4689,7 +4687,7 @@ int addrconf_sysctl_disable(ctl_table *ctl, int write,
int *valp = ctl->data;
int val = *valp;
loff_t pos = *ppos;
return -ENOMEM;
}
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
-index eedff8c..6e13a47 100644
+index eedff8c..7d7e24a 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
+@@ -108,7 +108,7 @@ found:
+ */
+ static int icmpv6_filter(const struct sock *sk, const struct sk_buff *skb)
+ {
+- struct icmp6hdr *_hdr;
++ struct icmp6hdr _hdr;
+ const struct icmp6hdr *hdr;
+
+ hdr = skb_header_pointer(skb, skb_transport_offset(skb),
@@ -378,7 +378,7 @@ static inline int rawv6_rcv_skb(struct sock *sk, struct sk_buff *skb)
{
if ((raw6_sk(sk)->checksum || rcu_access_pointer(sk->sk_filter)) &&
{
if (users > 0)
diff --git a/net/netfilter/nf_conntrack_proto_dccp.c b/net/netfilter/nf_conntrack_proto_dccp.c
-index a99b6c3..3841268 100644
+index a99b6c3..cb372f9 100644
--- a/net/netfilter/nf_conntrack_proto_dccp.c
+++ b/net/netfilter/nf_conntrack_proto_dccp.c
+@@ -428,7 +428,7 @@ static bool dccp_new(struct nf_conn *ct, const struct sk_buff *skb,
+ const char *msg;
+ u_int8_t state;
+
+- dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &dh);
++ dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &_dh);
+ BUG_ON(dh == NULL);
+
+ state = dccp_state_table[CT_DCCP_ROLE_CLIENT][dh->dccph_type][CT_DCCP_NONE];
@@ -457,7 +457,7 @@ static bool dccp_new(struct nf_conn *ct, const struct sk_buff *skb,
out_invalid:
if (LOG_INVALID(net, IPPROTO_DCCP))
return false;
}
+@@ -486,7 +486,7 @@ static int dccp_packet(struct nf_conn *ct, const struct sk_buff *skb,
+ u_int8_t type, old_state, new_state;
+ enum ct_dccp_roles role;
+
+- dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &dh);
++ dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &_dh);
+ BUG_ON(dh == NULL);
+ type = dh->dccph_type;
+
+@@ -577,7 +577,7 @@ static int dccp_error(struct net *net, struct nf_conn *tmpl,
+ unsigned int cscov;
+ const char *msg;
+
+- dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &dh);
++ dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &_dh);
+ if (dh == NULL) {
+ msg = "nf_ct_dccp: short packet ";
+ goto out_invalid;
@@ -614,7 +614,7 @@ static int dccp_error(struct net *net, struct nf_conn *tmpl,
out_invalid:
shdr = (Elf_Shdr *)((char *)ehdr + _r(&ehdr->e_shoff));
shstrtab_sec = shdr + r2(&ehdr->e_shstrndx);
diff --git a/security/Kconfig b/security/Kconfig
-index e9c6ac7..3e3f362 100644
+index e9c6ac7..c5d45c8 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -4,6 +4,959 @@
+config PAX_REFCOUNT
+ bool "Prevent various kernel object reference counter overflows"
+ default y if GRKERNSEC_CONFIG_AUTO
-+ depends on GRKERNSEC && ((ARM && (CPU_V6 || CPU_V6K || CPU_V7)) || SPARC64 || X86)
++ depends on GRKERNSEC && ((ARM && (CPU_V6 || CPU_V6K || CPU_V7)) || MIPS || SPARC64 || X86)
+ help
+ By saying Y here the kernel will detect and prevent overflowing
+ various (but not all) kinds of object reference counters. Such
+}
diff --git a/tools/gcc/kernexec_plugin.c b/tools/gcc/kernexec_plugin.c
new file mode 100644
-index 0000000..0408e06
+index 0000000..257529f
--- /dev/null
+++ b/tools/gcc/kernexec_plugin.c
-@@ -0,0 +1,465 @@
+@@ -0,0 +1,471 @@
+/*
+ * Copyright 2011-2013 by the PaX Team <pageexec@freemail.hu>
+ * Licensed under the GPL v2
+int plugin_is_GPL_compatible;
+
+static struct plugin_info kernexec_plugin_info = {
-+ .version = "201302112000",
++ .version = "201308230150",
+ .help = "method=[bts|or]\tinstrumentation method\n"
+};
+
+static void kernexec_instrument_fptr_bts(gimple_stmt_iterator *gsi)
+{
+ gimple assign_intptr, assign_new_fptr, call_stmt;
-+ tree intptr, old_fptr, new_fptr, kernexec_mask;
++ tree intptr, orptr, old_fptr, new_fptr, kernexec_mask;
+
+ call_stmt = gsi_stmt(*gsi);
+ old_fptr = gimple_call_fn(call_stmt);
+ intptr = create_tmp_var(long_unsigned_type_node, "kernexec_bts");
+#if BUILDING_GCC_VERSION <= 4007
+ add_referenced_var(intptr);
-+ mark_sym_for_renaming(intptr);
+#endif
++ intptr = make_ssa_name(intptr, NULL);
+ assign_intptr = gimple_build_assign(intptr, fold_convert(long_unsigned_type_node, old_fptr));
++ SSA_NAME_DEF_STMT(intptr) = assign_intptr;
+ gsi_insert_before(gsi, assign_intptr, GSI_SAME_STMT);
+ update_stmt(assign_intptr);
+
+ // apply logical or to temporary unsigned long and bitmask
+ kernexec_mask = build_int_cstu(long_long_unsigned_type_node, 0x8000000000000000LL);
+// kernexec_mask = build_int_cstu(long_long_unsigned_type_node, 0xffffffff80000000LL);
-+ assign_intptr = gimple_build_assign(intptr, fold_build2(BIT_IOR_EXPR, long_long_unsigned_type_node, intptr, kernexec_mask));
++ orptr = fold_build2(BIT_IOR_EXPR, long_long_unsigned_type_node, intptr, kernexec_mask);
++ intptr = make_ssa_name(SSA_NAME_VAR(intptr), NULL);
++ assign_intptr = gimple_build_assign(intptr, orptr);
++ SSA_NAME_DEF_STMT(intptr) = assign_intptr;
+ gsi_insert_before(gsi, assign_intptr, GSI_SAME_STMT);
+ update_stmt(assign_intptr);
+
+ new_fptr = create_tmp_var(TREE_TYPE(old_fptr), "kernexec_fptr");
+#if BUILDING_GCC_VERSION <= 4007
+ add_referenced_var(new_fptr);
-+ mark_sym_for_renaming(new_fptr);
+#endif
++ new_fptr = make_ssa_name(new_fptr, NULL);
+ assign_new_fptr = gimple_build_assign(new_fptr, fold_convert(TREE_TYPE(old_fptr), intptr));
++ SSA_NAME_DEF_STMT(new_fptr) = assign_new_fptr;
+ gsi_insert_before(gsi, assign_new_fptr, GSI_SAME_STMT);
+ update_stmt(assign_new_fptr);
+
+ new_fptr = create_tmp_var(TREE_TYPE(old_fptr), "kernexec_or");
+#if BUILDING_GCC_VERSION <= 4007
+ add_referenced_var(new_fptr);
-+ mark_sym_for_renaming(new_fptr);
+#endif
++ new_fptr = make_ssa_name(new_fptr, NULL);
+
+ // build asm volatile("orq %%r10, %0\n\t" : "=r"(new_fptr) : "0"(old_fptr));
+ input = build_tree_list(NULL_TREE, build_string(2, "0"));
+ vec_safe_push(outputs, output);
+#endif
+ asm_or_stmt = gimple_build_asm_vec("orq %%r10, %0\n\t", inputs, outputs, NULL, NULL);
++ SSA_NAME_DEF_STMT(new_fptr) = asm_or_stmt;
+ gimple_asm_set_volatile(asm_or_stmt, true);
+ gsi_insert_before(gsi, asm_or_stmt, GSI_SAME_STMT);
+ update_stmt(asm_or_stmt);
+}
diff --git a/tools/gcc/latent_entropy_plugin.c b/tools/gcc/latent_entropy_plugin.c
new file mode 100644
-index 0000000..b5395ba
+index 0000000..2ef6fd9
--- /dev/null
+++ b/tools/gcc/latent_entropy_plugin.c
-@@ -0,0 +1,327 @@
+@@ -0,0 +1,321 @@
+/*
+ * Copyright 2012-2013 by the PaX Team <pageexec@freemail.hu>
+ * Licensed under the GPL v2
+static tree latent_entropy_decl;
+
+static struct plugin_info latent_entropy_plugin_info = {
-+ .version = "201303102320",
++ .version = "201308230230",
+ .help = NULL
+};
+
+ op = get_op(&rhs);
+ addxorrol = fold_build2_loc(UNKNOWN_LOCATION, op, unsigned_intDI_type_node, local_entropy, rhs);
+ assign = gimple_build_assign(local_entropy, addxorrol);
-+#if BUILDING_GCC_VERSION <= 4007
-+ find_referenced_vars_in(assign);
-+#endif
-+//debug_bb(bb);
+ gsi = gsi_after_labels(bb);
+ gsi_insert_before(&gsi, assign, GSI_NEW_STMT);
+ update_stmt(assign);
++//debug_bb(bb);
+}
+
+static void perturb_latent_entropy(basic_block bb, tree rhs)
+ temp = create_tmp_var(unsigned_intDI_type_node, "temp_latent_entropy");
+#if BUILDING_GCC_VERSION <= 4007
+ add_referenced_var(temp);
-+ mark_sym_for_renaming(temp);
+#endif
+
+ // 2. read...
++ temp = make_ssa_name(temp, NULL);
+ assign = gimple_build_assign(temp, latent_entropy_decl);
++ SSA_NAME_DEF_STMT(temp) = assign;
+#if BUILDING_GCC_VERSION <= 4007
-+ find_referenced_vars_in(assign);
++ add_referenced_var(latent_entropy_decl);
+#endif
+ gsi = gsi_after_labels(bb);
+ gsi_insert_after(&gsi, assign, GSI_NEW_STMT);
+
+ // 3. ...modify...
+ addxorrol = fold_build2_loc(UNKNOWN_LOCATION, get_op(NULL), unsigned_intDI_type_node, temp, rhs);
++ temp = make_ssa_name(SSA_NAME_VAR(temp), NULL);
+ assign = gimple_build_assign(temp, addxorrol);
-+#if BUILDING_GCC_VERSION <= 4007
-+ find_referenced_vars_in(assign);
-+#endif
++ SSA_NAME_DEF_STMT(temp) = assign;
+ gsi_insert_after(&gsi, assign, GSI_NEW_STMT);
+ update_stmt(assign);
+
+ // 4. ...write latent_entropy
+ assign = gimple_build_assign(latent_entropy_decl, temp);
-+#if BUILDING_GCC_VERSION <= 4007
-+ find_referenced_vars_in(assign);
-+#endif
+ gsi_insert_after(&gsi, assign, GSI_NEW_STMT);
+ update_stmt(assign);
+}
+
+ assign = gimple_build_assign(local_entropy, build_int_cstu(unsigned_intDI_type_node, get_random_const()));
+// gimple_set_location(assign, loc);
-+#if BUILDING_GCC_VERSION <= 4007
-+ find_referenced_vars_in(assign);
-+#endif
+ gsi_insert_after(&gsi, assign, GSI_NEW_STMT);
+ update_stmt(assign);
++//debug_bb(bb);
+ bb = bb->next_bb;
+
+ // 3. instrument each BB with an operation on the local entropy variable
+ while (bb != EXIT_BLOCK_PTR) {
+ perturb_local_entropy(bb, local_entropy);
++//debug_bb(bb);
+ bb = bb->next_bb;
+ };
+
+ // 4. mix local entropy into the global entropy variable
+ perturb_latent_entropy(EXIT_BLOCK_PTR->prev_bb, local_entropy);
++//debug_bb(EXIT_BLOCK_PTR->prev_bb);
+ return 0;
+}
+
+alloc_dr_65495 alloc_dr 2 65495 NULL
diff --git a/tools/gcc/size_overflow_plugin.c b/tools/gcc/size_overflow_plugin.c
new file mode 100644
-index 0000000..9db0d0e
+index 0000000..03d0c84
--- /dev/null
+++ b/tools/gcc/size_overflow_plugin.c
-@@ -0,0 +1,2114 @@
+@@ -0,0 +1,2113 @@
+/*
+ * Copyright 2011, 2012, 2013 by Emese Revfy <re.emese@gmail.com>
+ * Licensed under the GPL v2, or (at your option) v3
+static void print_missing_msg(tree func, unsigned int argnum);
+
+static struct plugin_info size_overflow_plugin_info = {
-+ .version = "20130410beta",
++ .version = "20130822beta",
+ .help = "no-size-overflow\tturn off size overflow checking\n",
+};
+
+
+#if BUILDING_GCC_VERSION <= 4007
+ add_referenced_var(new_var);
-+ mark_sym_for_renaming(new_var);
+#endif
+ return new_var;
+}
--- /dev/null
+diff -Naur linux-3.10.9.org/drivers/leds/trigger/Kconfig linux-3.10.9/drivers/leds/trigger/Kconfig
+--- linux-3.10.9.org/drivers/leds/trigger/Kconfig 2013-08-21 00:40:47.000000000 +0200
++++ linux-3.10.9/drivers/leds/trigger/Kconfig 2013-08-30 20:43:19.064025933 +0200
+@@ -108,4 +108,11 @@
+ This enables direct flash/torch on/off by the driver, kernel space.
+ If unsure, say Y.
+
++config LEDS_TRIGGER_NETDEV
++ tristate "LED Netdev Trigger"
++ depends on LEDS_TRIGGERS
++ help
++ This allows LEDs to be controlled by network device activity.
++ If unsure, say Y.
++
+ endif # LEDS_TRIGGERS
+diff -Naur linux-3.10.9.org/drivers/leds/trigger/ledtrig-netdev.c linux-3.10.9/drivers/leds/trigger/ledtrig-netdev.c
+--- linux-3.10.9.org/drivers/leds/trigger/ledtrig-netdev.c 1970-01-01 01:00:00.000000000 +0100
++++ linux-3.10.9/drivers/leds/trigger/ledtrig-netdev.c 2013-08-30 20:44:17.857339974 +0200
+@@ -0,0 +1,451 @@
++/*
++ * LED Kernel Netdev Trigger
++ *
++ * Toggles the LED to reflect the link and traffic state of a named net device
++ *
++ * Copyright 2007 Oliver Jowett <oliver@opencloud.com>
++ *
++ * Derived from ledtrig-timer.c which is:
++ * Copyright 2005-2006 Openedhand Ltd.
++ * Author: Richard Purdie <rpurdie@openedhand.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ *
++ */
++
++#include <linux/module.h>
++#include <linux/jiffies.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/list.h>
++#include <linux/spinlock.h>
++#include <linux/device.h>
++#include <linux/netdevice.h>
++#include <linux/timer.h>
++#include <linux/ctype.h>
++#include <linux/leds.h>
++#include <linux/version.h>
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
++#include <net/net_namespace.h>
++#endif
++
++#include "../leds.h"
++
++/*
++ * Configurable sysfs attributes:
++ *
++ * device_name - network device name to monitor
++ *
++ * interval - duration of LED blink, in milliseconds
++ *
++ * mode - either "none" (LED is off) or a space separated list of one or more of:
++ * link: LED's normal state reflects whether the link is up (has carrier) or not
++ * tx: LED blinks on transmitted data
++ * rx: LED blinks on receive data
++ *
++ * Some suggestions:
++ *
++ * Simple link status LED:
++ * $ echo netdev >someled/trigger
++ * $ echo eth0 >someled/device_name
++ * $ echo link >someled/mode
++ *
++ * Ethernet-style link/activity LED:
++ * $ echo netdev >someled/trigger
++ * $ echo eth0 >someled/device_name
++ * $ echo "link tx rx" >someled/mode
++ *
++ * Modem-style tx/rx LEDs:
++ * $ echo netdev >led1/trigger
++ * $ echo ppp0 >led1/device_name
++ * $ echo tx >led1/mode
++ * $ echo netdev >led2/trigger
++ * $ echo ppp0 >led2/device_name
++ * $ echo rx >led2/mode
++ *
++ */
++
++#define MODE_LINK 1
++#define MODE_TX 2
++#define MODE_RX 4
++
++struct led_netdev_data {
++ rwlock_t lock;
++
++ struct timer_list timer;
++ struct notifier_block notifier;
++
++ struct led_classdev *led_cdev;
++ struct net_device *net_dev;
++
++ char device_name[IFNAMSIZ];
++ unsigned interval;
++ unsigned mode;
++ unsigned link_up;
++ unsigned last_activity;
++};
++
++static void set_baseline_state(struct led_netdev_data *trigger_data)
++{
++ if ((trigger_data->mode & MODE_LINK) != 0 && trigger_data->link_up)
++ led_set_brightness(trigger_data->led_cdev, LED_FULL);
++ else
++ led_set_brightness(trigger_data->led_cdev, LED_OFF);
++
++ if ((trigger_data->mode & (MODE_TX | MODE_RX)) != 0 && trigger_data->link_up)
++ mod_timer(&trigger_data->timer, jiffies + trigger_data->interval);
++ else
++ del_timer(&trigger_data->timer);
++}
++
++static ssize_t led_device_name_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct led_classdev *led_cdev = dev_get_drvdata(dev);
++ struct led_netdev_data *trigger_data = led_cdev->trigger_data;
++
++ read_lock(&trigger_data->lock);
++ sprintf(buf, "%s\n", trigger_data->device_name);
++ read_unlock(&trigger_data->lock);
++
++ return strlen(buf) + 1;
++}
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)
++extern struct net init_net;
++#endif
++
++static ssize_t led_device_name_store(struct device *dev,
++ struct device_attribute *attr, const char *buf, size_t size)
++{
++ struct led_classdev *led_cdev = dev_get_drvdata(dev);
++ struct led_netdev_data *trigger_data = led_cdev->trigger_data;
++
++ if (size < 0 || size >= IFNAMSIZ)
++ return -EINVAL;
++
++ write_lock(&trigger_data->lock);
++
++ strcpy(trigger_data->device_name, buf);
++ if (size > 0 && trigger_data->device_name[size-1] == '\n')
++ trigger_data->device_name[size-1] = 0;
++
++ if (trigger_data->device_name[0] != 0) {
++ /* check for existing device to update from */
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
++ trigger_data->net_dev = dev_get_by_name(&init_net, trigger_data->device_name);
++#else
++ trigger_data->net_dev = dev_get_by_name(trigger_data->device_name);
++#endif
++ if (trigger_data->net_dev != NULL)
++ trigger_data->link_up = (dev_get_flags(trigger_data->net_dev) & IFF_LOWER_UP) != 0;
++ set_baseline_state(trigger_data); /* updates LEDs, may start timers */
++ }
++
++ write_unlock(&trigger_data->lock);
++ return size;
++}
++
++static DEVICE_ATTR(device_name, 0644, led_device_name_show, led_device_name_store);
++
++static ssize_t led_mode_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct led_classdev *led_cdev = dev_get_drvdata(dev);
++ struct led_netdev_data *trigger_data = led_cdev->trigger_data;
++
++ read_lock(&trigger_data->lock);
++
++ if (trigger_data->mode == 0) {
++ strcpy(buf, "none\n");
++ } else {
++ if (trigger_data->mode & MODE_LINK)
++ strcat(buf, "link ");
++ if (trigger_data->mode & MODE_TX)
++ strcat(buf, "tx ");
++ if (trigger_data->mode & MODE_RX)
++ strcat(buf, "rx ");
++ strcat(buf, "\n");
++ }
++
++ read_unlock(&trigger_data->lock);
++
++ return strlen(buf)+1;
++}
++
++static ssize_t led_mode_store(struct device *dev,
++ struct device_attribute *attr, const char *buf, size_t size)
++{
++ struct led_classdev *led_cdev = dev_get_drvdata(dev);
++ struct led_netdev_data *trigger_data = led_cdev->trigger_data;
++ char copybuf[1024];
++ int new_mode = -1;
++ char *p, *token;
++
++ /* take a copy since we don't want to trash the inbound buffer when using strsep */
++ strncpy(copybuf, buf, sizeof(copybuf));
++ copybuf[1023] = 0;
++ p = copybuf;
++
++ while ((token = strsep(&p, " \t\n")) != NULL) {
++ if (!*token)
++ continue;
++
++ if (new_mode == -1)
++ new_mode = 0;
++
++ if (!strcmp(token, "none"))
++ new_mode = 0;
++ else if (!strcmp(token, "tx"))
++ new_mode |= MODE_TX;
++ else if (!strcmp(token, "rx"))
++ new_mode |= MODE_RX;
++ else if (!strcmp(token, "link"))
++ new_mode |= MODE_LINK;
++ else
++ return -EINVAL;
++ }
++
++ if (new_mode == -1)
++ return -EINVAL;
++
++ write_lock(&trigger_data->lock);
++ trigger_data->mode = new_mode;
++ set_baseline_state(trigger_data);
++ write_unlock(&trigger_data->lock);
++
++ return size;
++}
++
++static DEVICE_ATTR(mode, 0644, led_mode_show, led_mode_store);
++
++static ssize_t led_interval_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct led_classdev *led_cdev = dev_get_drvdata(dev);
++ struct led_netdev_data *trigger_data = led_cdev->trigger_data;
++
++ read_lock(&trigger_data->lock);
++ sprintf(buf, "%u\n", jiffies_to_msecs(trigger_data->interval));
++ read_unlock(&trigger_data->lock);
++
++ return strlen(buf) + 1;
++}
++
++static ssize_t led_interval_store(struct device *dev,
++ struct device_attribute *attr, const char *buf, size_t size)
++{
++ struct led_classdev *led_cdev = dev_get_drvdata(dev);
++ struct led_netdev_data *trigger_data = led_cdev->trigger_data;
++ int ret = -EINVAL;
++ char *after;
++ unsigned long value = simple_strtoul(buf, &after, 10);
++ size_t count = after - buf;
++
++ if (*after && isspace(*after))
++ count++;
++
++ /* impose some basic bounds on the timer interval */
++ if (count == size && value >= 5 && value <= 10000) {
++ write_lock(&trigger_data->lock);
++ trigger_data->interval = msecs_to_jiffies(value);
++ set_baseline_state(trigger_data); // resets timer
++ write_unlock(&trigger_data->lock);
++ ret = count;
++ }
++
++ return ret;
++}
++
++static DEVICE_ATTR(interval, 0644, led_interval_show, led_interval_store);
++
++static int netdev_trig_notify(struct notifier_block *nb,
++ unsigned long evt,
++ void *dv)
++{
++ struct net_device *dev = dv;
++ struct led_netdev_data *trigger_data = container_of(nb, struct led_netdev_data, notifier);
++
++ if (evt != NETDEV_UP && evt != NETDEV_DOWN && evt != NETDEV_CHANGE && evt != NETDEV_REGISTER && evt != NETDEV_UNREGISTER)
++ return NOTIFY_DONE;
++
++ write_lock(&trigger_data->lock);
++
++ if (strcmp(dev->name, trigger_data->device_name))
++ goto done;
++
++ if (evt == NETDEV_REGISTER) {
++ if (trigger_data->net_dev != NULL)
++ dev_put(trigger_data->net_dev);
++ dev_hold(dev);
++ trigger_data->net_dev = dev;
++ trigger_data->link_up = 0;
++ goto done;
++ }
++
++ if (evt == NETDEV_UNREGISTER && trigger_data->net_dev != NULL) {
++ dev_put(trigger_data->net_dev);
++ trigger_data->net_dev = NULL;
++ goto done;
++ }
++
++ /* UP / DOWN / CHANGE */
++
++ trigger_data->link_up = (evt != NETDEV_DOWN && netif_carrier_ok(dev));
++ set_baseline_state(trigger_data);
++
++done:
++ write_unlock(&trigger_data->lock);
++ return NOTIFY_DONE;
++}
++
++/* here's the real work! */
++static void netdev_trig_timer(unsigned long arg)
++{
++ struct led_netdev_data *trigger_data = (struct led_netdev_data *)arg;
++ struct rtnl_link_stats64 *dev_stats;
++ unsigned new_activity;
++ struct rtnl_link_stats64 temp;
++
++ write_lock(&trigger_data->lock);
++
++ if (!trigger_data->link_up || !trigger_data->net_dev || (trigger_data->mode & (MODE_TX | MODE_RX)) == 0) {
++ /* we don't need to do timer work, just reflect link state. */
++ led_set_brightness(trigger_data->led_cdev, ((trigger_data->mode & MODE_LINK) != 0 && trigger_data->link_up) ? LED_FULL : LED_OFF);
++ goto no_restart;
++ }
++
++ dev_stats = dev_get_stats(trigger_data->net_dev, &temp);
++ new_activity =
++ ((trigger_data->mode & MODE_TX) ? dev_stats->tx_packets : 0) +
++ ((trigger_data->mode & MODE_RX) ? dev_stats->rx_packets : 0);
++
++ if (trigger_data->mode & MODE_LINK) {
++ /* base state is ON (link present) */
++ /* if there's no link, we don't get this far and the LED is off */
++
++ /* OFF -> ON always */
++ /* ON -> OFF on activity */
++ if (trigger_data->led_cdev->brightness == LED_OFF) {
++ led_set_brightness(trigger_data->led_cdev, LED_FULL);
++ } else if (trigger_data->last_activity != new_activity) {
++ led_set_brightness(trigger_data->led_cdev, LED_OFF);
++ }
++ } else {
++ /* base state is OFF */
++ /* ON -> OFF always */
++ /* OFF -> ON on activity */
++ if (trigger_data->led_cdev->brightness == LED_FULL) {
++ led_set_brightness(trigger_data->led_cdev, LED_OFF);
++ } else if (trigger_data->last_activity != new_activity) {
++ led_set_brightness(trigger_data->led_cdev, LED_FULL);
++ }
++ }
++
++ trigger_data->last_activity = new_activity;
++ mod_timer(&trigger_data->timer, jiffies + trigger_data->interval);
++
++no_restart:
++ write_unlock(&trigger_data->lock);
++}
++
++static void netdev_trig_activate(struct led_classdev *led_cdev)
++{
++ struct led_netdev_data *trigger_data;
++ int rc;
++
++ trigger_data = kzalloc(sizeof(struct led_netdev_data), GFP_KERNEL);
++ if (!trigger_data)
++ return;
++
++ rwlock_init(&trigger_data->lock);
++
++ trigger_data->notifier.notifier_call = netdev_trig_notify;
++ trigger_data->notifier.priority = 10;
++
++ setup_timer(&trigger_data->timer, netdev_trig_timer, (unsigned long) trigger_data);
++
++ trigger_data->led_cdev = led_cdev;
++ trigger_data->net_dev = NULL;
++ trigger_data->device_name[0] = 0;
++
++ trigger_data->mode = 0;
++ trigger_data->interval = msecs_to_jiffies(50);
++ trigger_data->link_up = 0;
++ trigger_data->last_activity = 0;
++
++ led_cdev->trigger_data = trigger_data;
++
++ rc = device_create_file(led_cdev->dev, &dev_attr_device_name);
++ if (rc)
++ goto err_out;
++ rc = device_create_file(led_cdev->dev, &dev_attr_mode);
++ if (rc)
++ goto err_out_device_name;
++ rc = device_create_file(led_cdev->dev, &dev_attr_interval);
++ if (rc)
++ goto err_out_mode;
++
++ register_netdevice_notifier(&trigger_data->notifier);
++ return;
++
++err_out_mode:
++ device_remove_file(led_cdev->dev, &dev_attr_mode);
++err_out_device_name:
++ device_remove_file(led_cdev->dev, &dev_attr_device_name);
++err_out:
++ led_cdev->trigger_data = NULL;
++ kfree(trigger_data);
++}
++
++static void netdev_trig_deactivate(struct led_classdev *led_cdev)
++{
++ struct led_netdev_data *trigger_data = led_cdev->trigger_data;
++
++ if (trigger_data) {
++ unregister_netdevice_notifier(&trigger_data->notifier);
++
++ device_remove_file(led_cdev->dev, &dev_attr_device_name);
++ device_remove_file(led_cdev->dev, &dev_attr_mode);
++ device_remove_file(led_cdev->dev, &dev_attr_interval);
++
++ write_lock(&trigger_data->lock);
++
++ if (trigger_data->net_dev) {
++ dev_put(trigger_data->net_dev);
++ trigger_data->net_dev = NULL;
++ }
++
++ write_unlock(&trigger_data->lock);
++
++ del_timer_sync(&trigger_data->timer);
++
++ kfree(trigger_data);
++ }
++}
++
++static struct led_trigger netdev_led_trigger = {
++ .name = "netdev",
++ .activate = netdev_trig_activate,
++ .deactivate = netdev_trig_deactivate,
++};
++
++static int __init netdev_trig_init(void)
++{
++ return led_trigger_register(&netdev_led_trigger);
++}
++
++static void __exit netdev_trig_exit(void)
++{
++ led_trigger_unregister(&netdev_led_trigger);
++}
++
++module_init(netdev_trig_init);
++module_exit(netdev_trig_exit);
++
++MODULE_AUTHOR("Oliver Jowett <oliver@opencloud.com>");
++MODULE_DESCRIPTION("Netdev LED trigger");
++MODULE_LICENSE("GPL");
+diff -Naur linux-3.10.9.org/drivers/leds/trigger/Makefile linux-3.10.9/drivers/leds/trigger/Makefile
+--- linux-3.10.9.org/drivers/leds/trigger/Makefile 2013-08-21 00:40:47.000000000 +0200
++++ linux-3.10.9/drivers/leds/trigger/Makefile 2013-08-30 20:43:56.414009853 +0200
+@@ -8,3 +8,4 @@
+ obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON) += ledtrig-default-on.o
+ obj-$(CONFIG_LEDS_TRIGGER_TRANSIENT) += ledtrig-transient.o
+ obj-$(CONFIG_LEDS_TRIGGER_CAMERA) += ledtrig-camera.o
++obj-$(CONFIG_LEDS_TRIGGER_NETDEV) += ledtrig-netdev.o
--- /dev/null
+diff -urN a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig
+--- a/drivers/media/dvb-frontends/Kconfig 2013-04-29 08:36:01.000000000 +0800
++++ b/drivers/media/dvb-frontends/Kconfig 2013-05-03 17:03:57.000000000 +0800
+@@ -200,6 +200,20 @@
+ help
+ A DVB-S/S2 tuner module. Say Y when you want to support this frontend.
+
++config DVB_M88DS3103
++ tristate "Montage M88DS3103 based"
++ depends on DVB_CORE && I2C
++ default m if !MEDIA_SUBDRV_AUTOSELECT
++ help
++ A DVB-S/S2 tuner module. Say Y when you want to support this frontend.
++
++config DVB_M88DC2800
++ tristate "Montage M88DC2800 based"
++ depends on DVB_CORE && I2C
++ default m if !MEDIA_SUBDRV_AUTOSELECT
++ help
++ A DVB-C tuner module. Say Y when you want to support this frontend.
++
+ config DVB_SI21XX
+ tristate "Silicon Labs SI21XX based"
+ depends on DVB_CORE && I2C
+diff -urN a/drivers/media/dvb-frontends/m88dc2800.c b/drivers/media/dvb-frontends/m88dc2800.c
+--- a/drivers/media/dvb-frontends/m88dc2800.c 1970-01-01 08:00:00.000000000 +0800
++++ b/drivers/media/dvb-frontends/m88dc2800.c 2013-01-26 16:03:21.000000000 +0800
+@@ -0,0 +1,2124 @@
++/*
++ M88DC2800/M88TC2800 - DVB-C demodulator and tuner from Montage
++
++ Copyright (C) 2012 Max nibble<nibble.max@gmail.com>
++ Copyright (C) 2011 Montage Technology / www.montage-tech.com
++
++ This program is free software; you can redistribute it and/or modify
++ it under the terms of the GNU General Public License as published by
++ the Free Software Foundation; either version 2 of the License, or
++ (at your option) any later version.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ GNU General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; if not, write to the Free Software
++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++*/
++
++#include <linux/delay.h>
++#include <linux/errno.h>
++#include <linux/init.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/string.h>
++#include <linux/slab.h>
++#include <asm/div64.h>
++#include "dvb_frontend.h"
++#include "m88dc2800.h"
++
++struct m88dc2800_state {
++ struct i2c_adapter *i2c;
++ const struct m88dc2800_config *config;
++ struct dvb_frontend frontend;
++ u32 freq;
++ u32 ber;
++ u32 sym;
++ u16 qam;
++ u8 inverted;
++ u32 xtal;
++ /* tuner state */
++ u8 tuner_init_OK; /* Tuner initialize status */
++ u8 tuner_dev_addr; /* Tuner device address */
++ u32 tuner_freq; /* RF frequency to be set, unit: KHz */
++ u16 tuner_qam; /* Reserved */
++ u16 tuner_mode;
++ u8 tuner_bandwidth; /* Bandwidth of the channel, unit: MHz, 6/7/8 */
++ u8 tuner_loopthrough; /* Tuner loop through switch, 0/1 */
++ u32 tuner_crystal; /* Tuner crystal frequency, unit: KHz */
++ u32 tuner_dac; /* Tuner DAC frequency, unit: KHz */
++ u16 tuner_mtt; /* Tuner chip version, D1: 0x0d, E0: 0x0e, E1: 0x8e */
++ u16 tuner_custom_cfg;
++ u32 tuner_version; /* Tuner driver version number */
++ u32 tuner_time;
++};
++
++static int debug;
++module_param(debug, int, 0644);
++MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
++
++#define dprintk(args...) \
++ do { \
++ if (debug) \
++ printk(KERN_INFO "m88dc2800: " args); \
++ } while (0)
++
++
++static int m88dc2800_i2c_write(struct m88dc2800_state *state, u8 addr,
++ u8 * p_data, u8 len)
++{
++ struct i2c_msg msg = { .flags = 0 };
++
++ msg.addr = addr;
++ msg.buf = p_data;
++ msg.len = len;
++
++ return i2c_transfer(state->i2c, &msg, 1);
++}
++
++static int m88dc2800_i2c_read(struct m88dc2800_state *state, u8 addr,
++ u8 * p_data, u8 len)
++{
++ struct i2c_msg msg = { .flags = I2C_M_RD };
++
++ msg.addr = addr;
++ msg.buf = p_data;
++ msg.len = len;
++
++ return i2c_transfer(state->i2c, &msg, 1);
++}
++
++/*demod register operations.*/
++static int WriteReg(struct m88dc2800_state *state, u8 reg, u8 data)
++{
++ u8 buf[] = { reg, data };
++ u8 addr = state->config->demod_address;
++ int err;
++
++ dprintk("%s: write reg 0x%02x, value 0x%02x\n", __func__, reg, data);
++
++ err = m88dc2800_i2c_write(state, addr, buf, 2);
++
++ if (err != 1) {
++ printk(KERN_ERR
++ "%s: writereg error(err == %i, reg == 0x%02x,"
++ " value == 0x%02x)\n", __func__, err, reg, data);
++ return -EIO;
++ }
++ return 0;
++}
++
++static int ReadReg(struct m88dc2800_state *state, u8 reg)
++{
++ int ret;
++ u8 b0[] = { reg };
++ u8 b1[] = { 0 };
++ u8 addr = state->config->demod_address;
++
++ ret = m88dc2800_i2c_write(state, addr, b0, 1);
++
++ if (ret != 1) {
++ printk(KERN_ERR "%s: reg=0x%x (error=%d)\n",
++ __func__, reg, ret);
++ return -EIO;
++ }
++
++ ret = m88dc2800_i2c_read(state, addr, b1, 1);
++
++ dprintk("%s: read reg 0x%02x, value 0x%02x\n", __func__, reg, b1[0]);
++ return b1[0];
++}
++
++static int _mt_fe_tn_set_reg(struct m88dc2800_state *state, u8 reg,
++ u8 data)
++{
++ int ret;
++ u8 buf[2];
++ u8 addr = state->tuner_dev_addr;
++
++ buf[1] = ReadReg(state, 0x86);
++ buf[1] |= 0x80;
++ ret = WriteReg(state, 0x86, buf[1]);
++
++ buf[0] = reg;
++ buf[1] = data;
++
++ ret = m88dc2800_i2c_write(state, addr, buf, 2);
++ if (ret != 1)
++ return -EIO;
++ return 0;
++}
++
++static int _mt_fe_tn_get_reg(struct m88dc2800_state *state, u8 reg,
++ u8 * p_data)
++{
++ int ret;
++ u8 buf[2];
++ u8 addr = state->tuner_dev_addr;
++
++ buf[1] = ReadReg(state, 0x86);
++ buf[1] |= 0x80;
++ ret = WriteReg(state, 0x86, buf[1]);
++
++ buf[0] = reg;
++ ret = m88dc2800_i2c_write(state, addr, buf, 1);
++
++ msleep(1);
++
++ buf[1] = ReadReg(state, 0x86);
++ buf[1] |= 0x80;
++ ret = WriteReg(state, 0x86, buf[1]);
++
++ return m88dc2800_i2c_read(state, addr, p_data, 1);
++}
++
++/* Tuner operation functions.*/
++static int _mt_fe_tn_set_RF_front_tc2800(struct m88dc2800_state *state)
++{
++ u32 freq_KHz = state->tuner_freq;
++ u8 a, b, c;
++ if (state->tuner_mtt == 0xD1) { /* D1 */
++ if (freq_KHz <= 123000) {
++ if (freq_KHz <= 56000) {
++ a = 0x00; b = 0x00; c = 0x00;
++ } else if (freq_KHz <= 64000) {
++ a = 0x10; b = 0x01; c = 0x08;
++ } else if (freq_KHz <= 72000) {
++ a = 0x20; b = 0x02; c = 0x10;
++ } else if (freq_KHz <= 80000) {
++ a = 0x30; b = 0x03; c = 0x18;
++ } else if (freq_KHz <= 88000) {
++ a = 0x40; b = 0x04; c = 0x20;
++ } else if (freq_KHz <= 96000) {
++ a = 0x50; b = 0x05; c = 0x28;
++ } else if (freq_KHz <= 104000) {
++ a = 0x60; b = 0x06; c = 0x30;
++ } else {
++ a = 0x70; b = 0x07; c = 0x38;
++ }
++ _mt_fe_tn_set_reg(state, 0x58, 0x9b);
++ _mt_fe_tn_set_reg(state, 0x59, a);
++ _mt_fe_tn_set_reg(state, 0x5d, b);
++ _mt_fe_tn_set_reg(state, 0x5e, c);
++ _mt_fe_tn_set_reg(state, 0x5a, 0x75);
++ _mt_fe_tn_set_reg(state, 0x73, 0x0c);
++ } else { /* if (freq_KHz > 112000) */
++ _mt_fe_tn_set_reg(state, 0x58, 0x7b);
++ if (freq_KHz <= 304000) {
++ if (freq_KHz <= 136000) {
++ _mt_fe_tn_set_reg(state, 0x5e, 0x40);
++ } else if (freq_KHz <= 160000) {
++ _mt_fe_tn_set_reg(state, 0x5e, 0x48);
++ } else if (freq_KHz <= 184000) {
++ _mt_fe_tn_set_reg(state, 0x5e, 0x50);
++ } else if (freq_KHz <= 208000) {
++ _mt_fe_tn_set_reg(state, 0x5e, 0x58);
++ } else if (freq_KHz <= 232000) {
++ _mt_fe_tn_set_reg(state, 0x5e, 0x60);
++ } else if (freq_KHz <= 256000) {
++ _mt_fe_tn_set_reg(state, 0x5e, 0x68);
++ } else if (freq_KHz <= 280000) {
++ _mt_fe_tn_set_reg(state, 0x5e, 0x70);
++ } else { /* if (freq_KHz <= 304000) */
++ _mt_fe_tn_set_reg(state, 0x5e, 0x78);
++ }
++ if (freq_KHz <= 171000) {
++ _mt_fe_tn_set_reg(state, 0x73, 0x08);
++ } else if (freq_KHz <= 211000) {
++ _mt_fe_tn_set_reg(state, 0x73, 0x0a);
++ } else {
++ _mt_fe_tn_set_reg(state, 0x73, 0x0e);
++ }
++ } else { /* if (freq_KHz > 304000) */
++ _mt_fe_tn_set_reg(state, 0x5e, 0x88);
++ if (freq_KHz <= 400000) {
++ _mt_fe_tn_set_reg(state, 0x73, 0x0c);
++ } else if (freq_KHz <= 450000) {
++ _mt_fe_tn_set_reg(state, 0x73, 0x09);
++ } else if (freq_KHz <= 550000) {
++ _mt_fe_tn_set_reg(state, 0x73, 0x0e);
++ } else if (freq_KHz <= 650000) {
++ _mt_fe_tn_set_reg(state, 0x73, 0x0d);
++ } else { /*if (freq_KHz > 650000) */
++ _mt_fe_tn_set_reg(state, 0x73, 0x0e);
++ }
++ }
++ }
++ if (freq_KHz > 800000)
++ _mt_fe_tn_set_reg(state, 0x87, 0x24);
++ else if (freq_KHz > 700000)
++ _mt_fe_tn_set_reg(state, 0x87, 0x34);
++ else if (freq_KHz > 500000)
++ _mt_fe_tn_set_reg(state, 0x87, 0x44);
++ else if (freq_KHz > 300000)
++ _mt_fe_tn_set_reg(state, 0x87, 0x43);
++ else if (freq_KHz > 220000)
++ _mt_fe_tn_set_reg(state, 0x87, 0x54);
++ else if (freq_KHz > 110000)
++ _mt_fe_tn_set_reg(state, 0x87, 0x14);
++ else
++ _mt_fe_tn_set_reg(state, 0x87, 0x54);
++ if (freq_KHz > 600000)
++ _mt_fe_tn_set_reg(state, 0x6a, 0x53);
++ else if (freq_KHz > 500000)
++ _mt_fe_tn_set_reg(state, 0x6a, 0x57);
++ else
++ _mt_fe_tn_set_reg(state, 0x6a, 0x59);
++ if (freq_KHz < 200000) {
++ _mt_fe_tn_set_reg(state, 0x20, 0x5d);
++ } else if (freq_KHz < 500000) {
++ _mt_fe_tn_set_reg(state, 0x20, 0x7d);
++ } else {
++ _mt_fe_tn_set_reg(state, 0x20, 0xfd);
++ } /* end of 0xD1 */
++ } else if (state->tuner_mtt == 0xE1) { /* E1 */
++ if (freq_KHz <= 112000) { /* 123MHz */
++ if (freq_KHz <= 56000) {
++ _mt_fe_tn_set_reg(state, 0x5c, 0x01);
++ } else if (freq_KHz <= 64000) {
++ _mt_fe_tn_set_reg(state, 0x5c, 0x09);
++ } else if (freq_KHz <= 72000) {
++ _mt_fe_tn_set_reg(state, 0x5c, 0x11);
++ } else if (freq_KHz <= 80000) {
++ _mt_fe_tn_set_reg(state, 0x5c, 0x19);
++ } else if (freq_KHz <= 88000) {
++ _mt_fe_tn_set_reg(state, 0x5c, 0x21);
++ } else if (freq_KHz <= 96000) {
++ _mt_fe_tn_set_reg(state, 0x5c, 0x29);
++ } else if (freq_KHz <= 104000) {
++ _mt_fe_tn_set_reg(state, 0x5c, 0x31);
++ } else { /* if (freq_KHz <= 112000) */
++ _mt_fe_tn_set_reg(state, 0x5c, 0x39);
++ }
++ _mt_fe_tn_set_reg(state, 0x5b, 0x30);
++ } else { /* if (freq_KHz > 112000) */
++ if (freq_KHz <= 304000) {
++ if (freq_KHz <= 136000) {
++ _mt_fe_tn_set_reg(state, 0x5c, 0x41);
++ } else if (freq_KHz <= 160000) {
++ _mt_fe_tn_set_reg(state, 0x5c, 0x49);
++ } else if (freq_KHz <= 184000) {
++ _mt_fe_tn_set_reg(state, 0x5c, 0x51);
++ } else if (freq_KHz <= 208000) {
++ _mt_fe_tn_set_reg(state, 0x5c, 0x59);
++ } else if (freq_KHz <= 232000) {
++ _mt_fe_tn_set_reg(state, 0x5c, 0x61);
++ } else if (freq_KHz <= 256000) {
++ _mt_fe_tn_set_reg(state, 0x5c, 0x69);
++ } else if (freq_KHz <= 280000) {
++ _mt_fe_tn_set_reg(state, 0x5c, 0x71);
++ } else { /* if (freq_KHz <= 304000) */
++ _mt_fe_tn_set_reg(state, 0x5c, 0x79);
++ }
++ if (freq_KHz <= 150000) {
++ _mt_fe_tn_set_reg(state, 0x5b, 0x28);
++ } else if (freq_KHz <= 256000) {
++ _mt_fe_tn_set_reg(state, 0x5b, 0x29);
++ } else {
++ _mt_fe_tn_set_reg(state, 0x5b, 0x2a);
++ }
++ } else { /* if (freq_KHz > 304000) */
++ if (freq_KHz <= 400000) {
++ _mt_fe_tn_set_reg(state, 0x5c, 0x89);
++ } else if (freq_KHz <= 450000) {
++ _mt_fe_tn_set_reg(state, 0x5c, 0x91);
++ } else if (freq_KHz <= 650000) {
++ _mt_fe_tn_set_reg(state, 0x5c, 0x98);
++ } else if (freq_KHz <= 850000) {
++ _mt_fe_tn_set_reg(state, 0x5c, 0xa0);
++ } else {
++ _mt_fe_tn_set_reg(state, 0x5c, 0xa8);
++ }
++ _mt_fe_tn_set_reg(state, 0x5b, 0x08);
++ }
++ }
++ } /* end of 0xE1 */
++ return 0;
++}
++
++static int _mt_fe_tn_cali_PLL_tc2800(struct m88dc2800_state *state,
++ u32 freq_KHz,
++ u32 cali_freq_thres_div2,
++ u32 cali_freq_thres_div3r,
++ u32 cali_freq_thres_div3)
++{
++ s32 N, F, MUL;
++ u8 buf, tmp, tmp2;
++ s32 M;
++ const s32 crystal_KHz = state->tuner_crystal;
++ if (state->tuner_mtt == 0xD1) {
++ M = state->tuner_crystal / 4000;
++ if (freq_KHz > cali_freq_thres_div2) {
++ MUL = 4;
++ tmp = 2;
++ } else if (freq_KHz > 300000) {
++ MUL = 8;
++ tmp = 3;
++ } else if (freq_KHz > (cali_freq_thres_div2 / 2)) {
++ MUL = 8;
++ tmp = 4;
++ } else if (freq_KHz > (cali_freq_thres_div2 / 4)) {
++ MUL = 16;
++ tmp = 5;
++ } else if (freq_KHz > (cali_freq_thres_div2 / 8)) {
++ MUL = 32;
++ tmp = 6;
++ } else if (freq_KHz > (cali_freq_thres_div2 / 16)) {
++ MUL = 64;
++ tmp = 7;
++ } else { /* invalid */
++ MUL = 0;
++ tmp = 0;
++ return 1;
++ }
++ } else if (state->tuner_mtt == 0xE1) {
++ M = state->tuner_crystal / 1000;
++ _mt_fe_tn_set_reg(state, 0x30, 0xff);
++ _mt_fe_tn_set_reg(state, 0x32, 0xe0);
++ _mt_fe_tn_set_reg(state, 0x33, 0x86);
++ _mt_fe_tn_set_reg(state, 0x37, 0x70);
++ _mt_fe_tn_set_reg(state, 0x38, 0x20);
++ _mt_fe_tn_set_reg(state, 0x39, 0x18);
++ _mt_fe_tn_set_reg(state, 0x89, 0x83);
++ if (freq_KHz > cali_freq_thres_div2) {
++ M = M / 4;
++ MUL = 4;
++ tmp = 2;
++ tmp2 = M + 16; /* 48 */
++ } else if (freq_KHz > cali_freq_thres_div3r) {
++ M = M / 3;
++ MUL = 6;
++ tmp = 2;
++ tmp2 = M + 32; /* 32 */
++ } else if (freq_KHz > cali_freq_thres_div3) {
++ M = M / 3;
++ MUL = 6;
++ tmp = 2;
++ tmp2 = M; /* 16 */
++ } else if (freq_KHz > 304000) {
++ M = M / 4;
++ MUL = 8;
++ tmp = 3;
++ tmp2 = M + 16; /* 48 */
++ } else if (freq_KHz > (cali_freq_thres_div2 / 2)) {
++ M = M / 4;
++ MUL = 8;
++ tmp = 4;
++ tmp2 = M + 16; /* 48 */
++ } else if (freq_KHz > (cali_freq_thres_div3r / 2)) {
++ M = M / 3;
++ MUL = 12;
++ tmp = 4;
++ tmp2 = M + 32; /* 32 */
++ } else if (freq_KHz > (cali_freq_thres_div3 / 2)) {
++ M = M / 3;
++ MUL = 12;
++ tmp = 4;
++ tmp2 = M; /* 16 */
++ } else if (freq_KHz > (cali_freq_thres_div2 / 4)) {
++ M = M / 4;
++ MUL = 16;
++ tmp = 5;
++ tmp2 = M + 16; /* 48 */
++ } else if (freq_KHz > (cali_freq_thres_div3r / 4)) {
++ M = M / 3;
++ MUL = 24;
++ tmp = 5;
++ tmp2 = M + 32; /* 32 */
++ } else if (freq_KHz > (cali_freq_thres_div3 / 4)) {
++ M = M / 3;
++ MUL = 24;
++ tmp = 5;
++ tmp2 = M; /* 16 */
++ } else if (freq_KHz > (cali_freq_thres_div2 / 8)) {
++ M = M / 4;
++ MUL = 32;
++ tmp = 6;
++ tmp2 = M + 16; /* 48 */
++ } else if (freq_KHz > (cali_freq_thres_div3r / 8)) {
++ M = M / 3;
++ MUL = 48;
++ tmp = 6;
++ tmp2 = M + 32; /* 32 */
++ } else if (freq_KHz > (cali_freq_thres_div3 / 8)) {
++ M = M / 3;
++ MUL = 48;
++ tmp = 6;
++ tmp2 = M; /* 16 */
++ } else if (freq_KHz > (cali_freq_thres_div2 / 16)) {
++ M = M / 4;
++ MUL = 64;
++ tmp = 7;
++ tmp2 = M + 16; /* 48 */
++ } else if (freq_KHz > (cali_freq_thres_div3r / 16)) {
++ M = M / 3;
++ MUL = 96;
++ tmp = 7;
++ tmp2 = M + 32; /* 32 */
++ } else if (freq_KHz > (cali_freq_thres_div3 / 16)) {
++ M = M / 3;
++ MUL = 96;
++ tmp = 7;
++ tmp2 = M; /* 16 */
++ } else { /* invalid */
++ M = M / 4;
++ MUL = 0;
++ tmp = 0;
++ tmp2 = 48;
++ return 1;
++ }
++ if (freq_KHz == 291000) {
++ M = state->tuner_crystal / 1000 / 3;
++ MUL = 12;
++ tmp = 4;
++ tmp2 = M + 32; /* 32 */
++ }
++ /*
++ if (freq_KHz == 578000) {
++ M = state->tuner_crystal / 1000 / 4;
++ MUL = 4;
++ tmp = 2;
++ tmp2 = M + 16; // 48
++ }
++ */
++ if (freq_KHz == 690000) {
++ M = state->tuner_crystal / 1000 / 3;
++ MUL = 4;
++ tmp = 2;
++ tmp2 = M + 16; /* 48 */
++ }
++ _mt_fe_tn_get_reg(state, 0x33, &buf);
++ buf &= 0xc0;
++ buf += tmp2;
++ _mt_fe_tn_set_reg(state, 0x33, buf);
++ } else {
++ return 1;
++ }
++ _mt_fe_tn_get_reg(state, 0x39, &buf);
++ buf &= 0xf8;
++ buf += tmp;
++ _mt_fe_tn_set_reg(state, 0x39, buf);
++ N = (freq_KHz * MUL * M / crystal_KHz) / 2 * 2 - 256;
++ buf = (N >> 8) & 0xcf;
++ if (state->tuner_mtt == 0xE1) {
++ buf |= 0x30;
++ }
++ _mt_fe_tn_set_reg(state, 0x34, buf);
++ buf = N & 0xff;
++ _mt_fe_tn_set_reg(state, 0x35, buf);
++ F = ((freq_KHz * MUL * M / (crystal_KHz / 1000) / 2) -
++ (freq_KHz * MUL * M / crystal_KHz / 2 * 1000)) * 64 / 1000;
++ buf = F & 0xff;
++ _mt_fe_tn_set_reg(state, 0x36, buf);
++ if (F == 0) {
++ if (state->tuner_mtt == 0xD1) {
++ _mt_fe_tn_set_reg(state, 0x3d, 0xca);
++ } else if (state->tuner_mtt == 0xE1) {
++ _mt_fe_tn_set_reg(state, 0x3d, 0xfe);
++ } else {
++ return 1;
++ }
++ _mt_fe_tn_set_reg(state, 0x3e, 0x9c);
++ _mt_fe_tn_set_reg(state, 0x3f, 0x34);
++ }
++ if (F > 0) {
++ if (state->tuner_mtt == 0xD1) {
++ if ((F == 32) || (F == 16) || (F == 48)) {
++ _mt_fe_tn_set_reg(state, 0x3e, 0xa4);
++ _mt_fe_tn_set_reg(state, 0x3d, 0x4a);
++ _mt_fe_tn_set_reg(state, 0x3f, 0x36);
++ } else {
++ _mt_fe_tn_set_reg(state, 0x3e, 0xa4);
++ _mt_fe_tn_set_reg(state, 0x3d, 0x4a);
++ _mt_fe_tn_set_reg(state, 0x3f, 0x36);
++ }
++ } else if (state->tuner_mtt == 0xE1) {
++ _mt_fe_tn_set_reg(state, 0x3e, 0xa4);
++ _mt_fe_tn_set_reg(state, 0x3d, 0x7e);
++ _mt_fe_tn_set_reg(state, 0x3f, 0x36);
++ _mt_fe_tn_set_reg(state, 0x89, 0x84);
++ _mt_fe_tn_get_reg(state, 0x39, &buf);
++ buf = buf & 0x1f;
++ _mt_fe_tn_set_reg(state, 0x39, buf);
++ _mt_fe_tn_get_reg(state, 0x32, &buf);
++ buf = buf | 0x02;
++ _mt_fe_tn_set_reg(state, 0x32, buf);
++ } else {
++ return 1;
++ }
++ }
++ _mt_fe_tn_set_reg(state, 0x41, 0x00);
++ if (state->tuner_mtt == 0xD1) {
++ msleep(5);
++ } else if (state->tuner_mtt == 0xE1) {
++ msleep(2);
++ } else {
++ return 1;
++ }
++ _mt_fe_tn_set_reg(state, 0x41, 0x02);
++ _mt_fe_tn_set_reg(state, 0x30, 0x7f);
++ _mt_fe_tn_set_reg(state, 0x30, 0xff);
++ _mt_fe_tn_set_reg(state, 0x31, 0x80);
++ _mt_fe_tn_set_reg(state, 0x31, 0x00);
++
++ return 0;
++}
++
++static int _mt_fe_tn_set_PLL_freq_tc2800(struct m88dc2800_state *state)
++{
++ u8 buf, buf1;
++ u32 freq_thres_div2_KHz, freq_thres_div3r_KHz,
++ freq_thres_div3_KHz;
++ const u32 freq_KHz = state->tuner_freq;
++ if (state->tuner_mtt == 0xD1) {
++ _mt_fe_tn_set_reg(state, 0x32, 0xe1);
++ _mt_fe_tn_set_reg(state, 0x33, 0xa6);
++ _mt_fe_tn_set_reg(state, 0x37, 0x7f);
++ _mt_fe_tn_set_reg(state, 0x38, 0x20);
++ _mt_fe_tn_set_reg(state, 0x39, 0x18);
++ _mt_fe_tn_set_reg(state, 0x40, 0x40);
++ freq_thres_div2_KHz = 520000;
++ _mt_fe_tn_cali_PLL_tc2800(state, freq_KHz,
++ freq_thres_div2_KHz, 0, 0);
++ msleep(5);
++ _mt_fe_tn_get_reg(state, 0x3a, &buf);
++ buf1 = buf;
++ buf = buf & 0x03;
++ buf1 = buf1 & 0x01;
++ if ((buf1 == 0) || (buf == 3)) {
++ freq_thres_div2_KHz = 420000;
++ _mt_fe_tn_cali_PLL_tc2800(state, freq_KHz,
++ freq_thres_div2_KHz, 0,
++ 0);
++ msleep(5);
++ _mt_fe_tn_get_reg(state, 0x3a, &buf);
++ buf = buf & 0x07;
++ if (buf == 5) {
++ freq_thres_div2_KHz = 520000;
++ _mt_fe_tn_cali_PLL_tc2800(state, freq_KHz,
++ freq_thres_div2_KHz,
++ 0, 0);
++ msleep(5);
++ }
++ }
++ _mt_fe_tn_get_reg(state, 0x38, &buf);
++ _mt_fe_tn_set_reg(state, 0x38, buf);
++ _mt_fe_tn_get_reg(state, 0x32, &buf);
++ buf = buf | 0x10;
++ _mt_fe_tn_set_reg(state, 0x32, buf);
++ _mt_fe_tn_set_reg(state, 0x30, 0x7f);
++ _mt_fe_tn_set_reg(state, 0x30, 0xff);
++ _mt_fe_tn_get_reg(state, 0x32, &buf);
++ buf = buf & 0xdf;
++ _mt_fe_tn_set_reg(state, 0x32, buf);
++ _mt_fe_tn_set_reg(state, 0x40, 0x0);
++ _mt_fe_tn_set_reg(state, 0x30, 0x7f);
++ _mt_fe_tn_set_reg(state, 0x30, 0xff);
++ _mt_fe_tn_set_reg(state, 0x31, 0x80);
++ _mt_fe_tn_set_reg(state, 0x31, 0x00);
++ msleep(5);
++ _mt_fe_tn_get_reg(state, 0x39, &buf);
++ buf = buf >> 5;
++ if (buf < 5) {
++ _mt_fe_tn_get_reg(state, 0x39, &buf);
++ buf = buf | 0xa0;
++ buf = buf & 0xbf;
++ _mt_fe_tn_set_reg(state, 0x39, buf);
++ _mt_fe_tn_get_reg(state, 0x32, &buf);
++ buf = buf | 0x02;
++ _mt_fe_tn_set_reg(state, 0x32, buf);
++ }
++ _mt_fe_tn_get_reg(state, 0x37, &buf);
++ if (buf > 0x70) {
++ buf = 0x7f;
++ _mt_fe_tn_set_reg(state, 0x40, 0x40);
++ }
++ _mt_fe_tn_set_reg(state, 0x37, buf);
++ _mt_fe_tn_get_reg(state, 0x38, &buf);
++ if (buf < 0x0f) {
++ buf = (buf & 0x0f) << 2;
++ buf = buf + 0x0f;
++ _mt_fe_tn_set_reg(state, 0x37, buf);
++ } else if (buf < 0x1f) {
++ buf = buf + 0x0f;
++ _mt_fe_tn_set_reg(state, 0x37, buf);
++ }
++ _mt_fe_tn_get_reg(state, 0x32, &buf);
++ buf = (buf | 0x20) & 0xef;
++ _mt_fe_tn_set_reg(state, 0x32, buf);
++ _mt_fe_tn_set_reg(state, 0x41, 0x00);
++ msleep(5);
++ _mt_fe_tn_set_reg(state, 0x41, 0x02);
++ } else if (state->tuner_mtt == 0xE1) {
++ freq_thres_div2_KHz = 580000;
++ freq_thres_div3r_KHz = 500000;
++ freq_thres_div3_KHz = 440000;
++ _mt_fe_tn_cali_PLL_tc2800(state, freq_KHz,
++ freq_thres_div2_KHz,
++ freq_thres_div3r_KHz,
++ freq_thres_div3_KHz);
++ msleep(3);
++ _mt_fe_tn_get_reg(state, 0x38, &buf);
++ _mt_fe_tn_set_reg(state, 0x38, buf);
++ _mt_fe_tn_set_reg(state, 0x30, 0x7f);
++ _mt_fe_tn_set_reg(state, 0x30, 0xff);
++ _mt_fe_tn_set_reg(state, 0x31, 0x80);
++ _mt_fe_tn_set_reg(state, 0x31, 0x00);
++ msleep(3);
++ _mt_fe_tn_get_reg(state, 0x38, &buf);
++ _mt_fe_tn_set_reg(state, 0x38, buf);
++ _mt_fe_tn_get_reg(state, 0x32, &buf);
++ buf = buf | 0x10;
++ _mt_fe_tn_set_reg(state, 0x32, buf);
++ _mt_fe_tn_set_reg(state, 0x30, 0x7f);
++ _mt_fe_tn_set_reg(state, 0x30, 0xff);
++ _mt_fe_tn_get_reg(state, 0x32, &buf);
++ buf = buf & 0xdf;
++ _mt_fe_tn_set_reg(state, 0x32, buf);
++ _mt_fe_tn_set_reg(state, 0x31, 0x80);
++ _mt_fe_tn_set_reg(state, 0x31, 0x00);
++ msleep(3);
++ _mt_fe_tn_get_reg(state, 0x37, &buf);
++ _mt_fe_tn_set_reg(state, 0x37, buf);
++ /*
++ if ((freq_KHz == 802000) || (freq_KHz == 826000)) {
++ _mt_fe_tn_set_reg(state, 0x37, 0x5e);
++ }
++ */
++ _mt_fe_tn_get_reg(state, 0x32, &buf);
++ buf = (buf & 0xef) | 0x30;
++ _mt_fe_tn_set_reg(state, 0x32, buf);
++ _mt_fe_tn_set_reg(state, 0x41, 0x00);
++ msleep(2);
++ _mt_fe_tn_set_reg(state, 0x41, 0x02);
++ } else {
++ return 1;
++ }
++ return 0;
++}
++
++static int _mt_fe_tn_set_BB_tc2800(struct m88dc2800_state *state)
++{
++ return 0;
++}
++
++ static int _mt_fe_tn_set_appendix_tc2800(struct m88dc2800_state *state)
++
++{
++ u8 buf;
++ const u32 freq_KHz = state->tuner_freq;
++ if (state->tuner_mtt == 0xD1) {
++ if ((freq_KHz == 123000) || (freq_KHz == 147000) ||
++ (freq_KHz == 171000) || (freq_KHz == 195000)) {
++ _mt_fe_tn_set_reg(state, 0x20, 0x1b);
++ }
++ if ((freq_KHz == 371000) || (freq_KHz == 419000) ||
++ (freq_KHz == 610000) || (freq_KHz == 730000) ||
++ (freq_KHz == 754000) || (freq_KHz == 826000)) {
++ _mt_fe_tn_get_reg(state, 0x0d, &buf);
++ _mt_fe_tn_set_reg(state, 0x0d, (u8) (buf + 1));
++ }
++ if ((freq_KHz == 522000) || (freq_KHz == 578000) ||
++ (freq_KHz == 634000) || (freq_KHz == 690000) ||
++ (freq_KHz == 834000)) {
++ _mt_fe_tn_get_reg(state, 0x0d, &buf);
++ _mt_fe_tn_set_reg(state, 0x0d, (u8) (buf - 1));
++ }
++ } else if (state->tuner_mtt == 0xE1) {
++ _mt_fe_tn_set_reg(state, 0x20, 0xfc);
++ if (freq_KHz == 123000 || freq_KHz == 147000 ||
++ freq_KHz == 171000 || freq_KHz == 195000 ||
++ freq_KHz == 219000 || freq_KHz == 267000 ||
++ freq_KHz == 291000 || freq_KHz == 339000 ||
++ freq_KHz == 387000 || freq_KHz == 435000 ||
++ freq_KHz == 482000 || freq_KHz == 530000 ||
++ freq_KHz == 722000 ||
++ (state->tuner_custom_cfg == 1 && freq_KHz == 315000)) {
++ _mt_fe_tn_set_reg(state, 0x20, 0x5c);
++ }
++ }
++ return 0;
++}
++
++ static int _mt_fe_tn_set_DAC_tc2800(struct m88dc2800_state *state)
++{
++ u8 buf, tempnumber;
++ s32 N;
++ s32 f1f2number, f1, f2, delta1, Totalnum1;
++ s32 cntT, cntin, NCOI, z0, z1, z2, tmp;
++ u32 fc, fadc, fsd, f2d;
++ u32 FreqTrue108_Hz;
++ s32 M = state->tuner_crystal / 4000;
++ /* const u8 bandwidth = state->tuner_bandwidth; */
++ const u16 DAC_fre = 108;
++ const u32 crystal_KHz = state->tuner_crystal;
++ const u32 DACFreq_KHz = state->tuner_dac;
++ const u32 freq_KHz = state->tuner_freq;
++
++ if (state->tuner_mtt == 0xE1) {
++ _mt_fe_tn_get_reg(state, 0x33, &buf);
++ M = buf & 0x0f;
++ if (M == 0)
++ M = 6;
++ }
++ _mt_fe_tn_get_reg(state, 0x34, &buf);
++ N = buf & 0x07;
++ _mt_fe_tn_get_reg(state, 0x35, &buf);
++ N = (N << 8) + buf;
++ buf = ((N + 256) * crystal_KHz / M / DAC_fre + 500) / 1000;
++ if (state->tuner_mtt == 0xE1) {
++ _mt_fe_tn_set_appendix_tc2800(state);
++ if (freq_KHz == 187000 || freq_KHz == 195000 ||
++ freq_KHz == 131000 || freq_KHz == 211000 ||
++ freq_KHz == 219000 || freq_KHz == 227000 ||
++ freq_KHz == 267000 || freq_KHz == 299000 ||
++ freq_KHz == 347000 || freq_KHz == 363000 ||
++ freq_KHz == 395000 || freq_KHz == 403000 ||
++ freq_KHz == 435000 || freq_KHz == 482000 ||
++ freq_KHz == 474000 || freq_KHz == 490000 ||
++ freq_KHz == 610000 || freq_KHz == 642000 ||
++ freq_KHz == 666000 || freq_KHz == 722000 ||
++ freq_KHz == 754000 ||
++ ((freq_KHz == 379000 || freq_KHz == 467000 ||
++ freq_KHz == 762000) && state->tuner_custom_cfg != 1)) {
++ buf = buf + 1;
++ }
++ if (freq_KHz == 123000 || freq_KHz == 139000 ||
++ freq_KHz == 147000 || freq_KHz == 171000 ||
++ freq_KHz == 179000 || freq_KHz == 203000 ||
++ freq_KHz == 235000 || freq_KHz == 251000 ||
++ freq_KHz == 259000 || freq_KHz == 283000 ||
++ freq_KHz == 331000 || freq_KHz == 363000 ||
++ freq_KHz == 371000 || freq_KHz == 387000 ||
++ freq_KHz == 411000 || freq_KHz == 427000 ||
++ freq_KHz == 443000 || freq_KHz == 451000 ||
++ freq_KHz == 459000 || freq_KHz == 506000 ||
++ freq_KHz == 514000 || freq_KHz == 538000 ||
++ freq_KHz == 546000 || freq_KHz == 554000 ||
++ freq_KHz == 562000 || freq_KHz == 570000 ||
++ freq_KHz == 578000 || freq_KHz == 602000 ||
++ freq_KHz == 626000 || freq_KHz == 658000 ||
++ freq_KHz == 690000 || freq_KHz == 714000 ||
++ freq_KHz == 746000 || freq_KHz == 522000 ||
++ freq_KHz == 826000 || freq_KHz == 155000 ||
++ freq_KHz == 530000 ||
++ ((freq_KHz == 275000 || freq_KHz == 355000) &&
++ state->tuner_custom_cfg != 1) ||
++ ((freq_KHz == 467000 || freq_KHz == 762000 ||
++ freq_KHz == 778000 || freq_KHz == 818000) &&
++ state->tuner_custom_cfg == 1)) {
++ buf = buf - 1;
++ }
++ }
++ _mt_fe_tn_set_reg(state, 0x0e, buf);
++ _mt_fe_tn_set_reg(state, 0x0d, buf);
++ f1f2number =
++ (((DACFreq_KHz * M * buf) / crystal_KHz) << 16) / (N + 256) +
++ (((DACFreq_KHz * M * buf) % crystal_KHz) << 16) / ((N + 256) *
++ crystal_KHz);
++ _mt_fe_tn_set_reg(state, 0xf1, (f1f2number & 0xff00) >> 8);
++ _mt_fe_tn_set_reg(state, 0xf2, f1f2number & 0x00ff);
++ FreqTrue108_Hz =
++ (N + 256) * crystal_KHz / (M * buf) * 1000 +
++ (((N + 256) * crystal_KHz) % (M * buf)) * 1000 / (M * buf);
++ f1 = 4096;
++ fc = FreqTrue108_Hz;
++ fadc = fc / 4;
++ fsd = 27000000;
++ f2d = state->tuner_bandwidth * 1000 / 2 - 150;
++ f2 = (fsd / 250) * f2d / ((fc + 500) / 1000);
++ delta1 = ((f1 - f2) << 15) / f2;
++ Totalnum1 = ((f1 - f2) << 15) - delta1 * f2;
++ cntT = f2;
++ cntin = Totalnum1;
++ NCOI = delta1;
++ z0 = cntin;
++ z1 = cntT;
++ z2 = NCOI;
++ tempnumber = (z0 & 0xff00) >> 8;
++ _mt_fe_tn_set_reg(state, 0xc9, (u8) (tempnumber & 0x0f));
++ tempnumber = (z0 & 0xff);
++ _mt_fe_tn_set_reg(state, 0xca, tempnumber);
++ tempnumber = (z1 & 0xff00) >> 8;
++ _mt_fe_tn_set_reg(state, 0xcb, tempnumber);
++ tempnumber = (z1 & 0xff);
++ _mt_fe_tn_set_reg(state, 0xcc, tempnumber);
++ tempnumber = (z2 & 0xff00) >> 8;
++ _mt_fe_tn_set_reg(state, 0xcd, tempnumber);
++ tempnumber = (z2 & 0xff);
++ _mt_fe_tn_set_reg(state, 0xce, tempnumber);
++ tmp = f1;
++ f1 = f2;
++ f2 = tmp / 2;
++ delta1 = ((f1 - f2) << 15) / f2;
++ Totalnum1 = ((f1 - f2) << 15) - delta1 * f2;
++ NCOI = (f1 << 15) / f2 - (1 << 15);
++ cntT = f2;
++ cntin = Totalnum1;
++ z0 = cntin;
++ z1 = cntT;
++ z2 = NCOI;
++ tempnumber = (z0 & 0xff00) >> 8;
++ _mt_fe_tn_set_reg(state, 0xd9, (u8) (tempnumber & 0x0f));
++ tempnumber = (z0 & 0xff);
++ _mt_fe_tn_set_reg(state, 0xda, tempnumber);
++ tempnumber = (z1 & 0xff00) >> 8;
++ _mt_fe_tn_set_reg(state, 0xdb, tempnumber);
++ tempnumber = (z1 & 0xff);
++ _mt_fe_tn_set_reg(state, 0xdc, tempnumber);
++ tempnumber = (z2 & 0xff00) >> 8;
++ _mt_fe_tn_set_reg(state, 0xdd, tempnumber);
++ tempnumber = (z2 & 0xff);
++ _mt_fe_tn_set_reg(state, 0xde, tempnumber);
++
++ return 0;
++}
++
++static int _mt_fe_tn_preset_tc2800(struct m88dc2800_state *state)
++{
++ if (state->tuner_mtt == 0xD1) {
++ _mt_fe_tn_set_reg(state, 0x19, 0x4a);
++ _mt_fe_tn_set_reg(state, 0x1b, 0x4b);
++ _mt_fe_tn_set_reg(state, 0x04, 0x04);
++ _mt_fe_tn_set_reg(state, 0x17, 0x0d);
++ _mt_fe_tn_set_reg(state, 0x62, 0x6c);
++ _mt_fe_tn_set_reg(state, 0x63, 0xf4);
++ _mt_fe_tn_set_reg(state, 0x1f, 0x0e);
++ _mt_fe_tn_set_reg(state, 0x6b, 0xf4);
++ _mt_fe_tn_set_reg(state, 0x14, 0x01);
++ _mt_fe_tn_set_reg(state, 0x5a, 0x75);
++ _mt_fe_tn_set_reg(state, 0x66, 0x74);
++ _mt_fe_tn_set_reg(state, 0x72, 0xe0);
++ _mt_fe_tn_set_reg(state, 0x70, 0x07);
++ _mt_fe_tn_set_reg(state, 0x15, 0x7b);
++ _mt_fe_tn_set_reg(state, 0x55, 0x71);
++ _mt_fe_tn_set_reg(state, 0x75, 0x55);
++ _mt_fe_tn_set_reg(state, 0x76, 0xac);
++ _mt_fe_tn_set_reg(state, 0x77, 0x6c);
++ _mt_fe_tn_set_reg(state, 0x78, 0x8b);
++ _mt_fe_tn_set_reg(state, 0x79, 0x42);
++ _mt_fe_tn_set_reg(state, 0x7a, 0xd2);
++ _mt_fe_tn_set_reg(state, 0x81, 0x01);
++ _mt_fe_tn_set_reg(state, 0x82, 0x00);
++ _mt_fe_tn_set_reg(state, 0x82, 0x02);
++ _mt_fe_tn_set_reg(state, 0x82, 0x04);
++ _mt_fe_tn_set_reg(state, 0x82, 0x06);
++ _mt_fe_tn_set_reg(state, 0x82, 0x08);
++ _mt_fe_tn_set_reg(state, 0x82, 0x09);
++ _mt_fe_tn_set_reg(state, 0x82, 0x29);
++ _mt_fe_tn_set_reg(state, 0x82, 0x49);
++ _mt_fe_tn_set_reg(state, 0x82, 0x58);
++ _mt_fe_tn_set_reg(state, 0x82, 0x59);
++ _mt_fe_tn_set_reg(state, 0x82, 0x98);
++ _mt_fe_tn_set_reg(state, 0x82, 0x99);
++ _mt_fe_tn_set_reg(state, 0x10, 0x05);
++ _mt_fe_tn_set_reg(state, 0x10, 0x0d);
++ _mt_fe_tn_set_reg(state, 0x11, 0x95);
++ _mt_fe_tn_set_reg(state, 0x11, 0x9d);
++ if (state->tuner_loopthrough != 0) {
++ _mt_fe_tn_set_reg(state, 0x67, 0x25);
++ } else {
++ _mt_fe_tn_set_reg(state, 0x67, 0x05);
++ }
++ } else if (state->tuner_mtt == 0xE1) {
++ _mt_fe_tn_set_reg(state, 0x1b, 0x47);
++ if (state->tuner_mode == 0) { /* DVB-C */
++ _mt_fe_tn_set_reg(state, 0x66, 0x74);
++ _mt_fe_tn_set_reg(state, 0x62, 0x2c);
++ _mt_fe_tn_set_reg(state, 0x63, 0x54);
++ _mt_fe_tn_set_reg(state, 0x68, 0x0b);
++ _mt_fe_tn_set_reg(state, 0x14, 0x00);
++ } else { /* CTTB */
++ _mt_fe_tn_set_reg(state, 0x66, 0x74);
++ _mt_fe_tn_set_reg(state, 0x62, 0x0c);
++ _mt_fe_tn_set_reg(state, 0x63, 0x54);
++ _mt_fe_tn_set_reg(state, 0x68, 0x0b);
++ _mt_fe_tn_set_reg(state, 0x14, 0x05);
++ }
++ _mt_fe_tn_set_reg(state, 0x6f, 0x00);
++ _mt_fe_tn_set_reg(state, 0x84, 0x04);
++ _mt_fe_tn_set_reg(state, 0x5e, 0xbe);
++ _mt_fe_tn_set_reg(state, 0x87, 0x07);
++ _mt_fe_tn_set_reg(state, 0x8a, 0x1f);
++ _mt_fe_tn_set_reg(state, 0x8b, 0x1f);
++ _mt_fe_tn_set_reg(state, 0x88, 0x30);
++ _mt_fe_tn_set_reg(state, 0x58, 0x34);
++ _mt_fe_tn_set_reg(state, 0x61, 0x8c);
++ _mt_fe_tn_set_reg(state, 0x6a, 0x42);
++ }
++ return 0;
++}
++
++static int mt_fe_tn_wakeup_tc2800(struct m88dc2800_state *state)
++{
++ _mt_fe_tn_set_reg(state, 0x16, 0xb1);
++ _mt_fe_tn_set_reg(state, 0x09, 0x7d);
++ return 0;
++}
++
++ static int mt_fe_tn_sleep_tc2800(struct m88dc2800_state *state)
++{
++ _mt_fe_tn_set_reg(state, 0x16, 0xb0);
++ _mt_fe_tn_set_reg(state, 0x09, 0x6d);
++ return 0;
++}
++
++ static int mt_fe_tn_init_tc2800(struct m88dc2800_state *state)
++{
++ if (state->tuner_init_OK != 1) {
++ state->tuner_dev_addr = 0x61; /* TUNER_I2C_ADDR_TC2800 */
++ state->tuner_freq = 650000;
++ state->tuner_qam = 0;
++ state->tuner_mode = 0; // 0: DVB-C, 1: CTTB
++ state->tuner_bandwidth = 8;
++ state->tuner_loopthrough = 0;
++ state->tuner_crystal = 24000;
++ state->tuner_dac = 7200;
++ state->tuner_mtt = 0x00;
++ state->tuner_custom_cfg = 0;
++ state->tuner_version = 30022; /* Driver version number */
++ state->tuner_time = 12092611;
++ state->tuner_init_OK = 1;
++ }
++ _mt_fe_tn_set_reg(state, 0x2b, 0x46);
++ _mt_fe_tn_set_reg(state, 0x2c, 0x75);
++ if (state->tuner_mtt == 0x00) {
++ u8 tmp = 0;
++ _mt_fe_tn_get_reg(state, 0x01, &tmp);
++ printk(KERN_INFO "m88dc2800: tuner id = 0x%02x ", tmp);
++ switch (tmp) {
++ case 0x0d:
++ state->tuner_mtt = 0xD1;
++ break;
++ case 0x8e:
++ default:
++ state->tuner_mtt = 0xE1;
++ break;
++ }
++ }
++ return 0;
++}
++
++ static int mt_fe_tn_set_freq_tc2800(struct m88dc2800_state *state,
++ u32 freq_KHz)
++{
++ u8 buf;
++ u8 buf1;
++
++ mt_fe_tn_init_tc2800(state);
++ state->tuner_freq = freq_KHz;
++ _mt_fe_tn_set_reg(state, 0x21, freq_KHz > 500000 ? 0xb9 : 0x99);
++ mt_fe_tn_wakeup_tc2800(state);
++ _mt_fe_tn_set_reg(state, 0x05, 0x7f);
++ _mt_fe_tn_set_reg(state, 0x06, 0xf8);
++ _mt_fe_tn_set_RF_front_tc2800(state);
++ _mt_fe_tn_set_PLL_freq_tc2800(state);
++ _mt_fe_tn_set_DAC_tc2800(state);
++ _mt_fe_tn_set_BB_tc2800(state);
++ _mt_fe_tn_preset_tc2800(state);
++ _mt_fe_tn_set_reg(state, 0x05, 0x00);
++ _mt_fe_tn_set_reg(state, 0x06, 0x00);
++ if (state->tuner_mtt == 0xD1) {
++ _mt_fe_tn_set_reg(state, 0x00, 0x01);
++ _mt_fe_tn_set_reg(state, 0x00, 0x00);
++ msleep(5);
++ _mt_fe_tn_set_reg(state, 0x41, 0x00);
++ msleep(5);
++ _mt_fe_tn_set_reg(state, 0x41, 0x02);
++
++ _mt_fe_tn_get_reg(state, 0x69, &buf1);
++ buf1 = buf1 & 0x0f;
++ _mt_fe_tn_get_reg(state, 0x61, &buf);
++ buf = buf & 0x0f;
++ if (buf == 0x0c)
++ _mt_fe_tn_set_reg(state, 0x6a, 0x59);
++ if (buf1 > 0x02) {
++ if (freq_KHz > 600000)
++ _mt_fe_tn_set_reg(state, 0x66, 0x44);
++ else if (freq_KHz > 500000)
++ _mt_fe_tn_set_reg(state, 0x66, 0x64);
++ else
++ _mt_fe_tn_set_reg(state, 0x66, 0x74);
++ }
++ if (buf1 < 0x03) {
++ if (freq_KHz > 800000)
++ _mt_fe_tn_set_reg(state, 0x87, 0x64);
++ else if (freq_KHz > 600000)
++ _mt_fe_tn_set_reg(state, 0x87, 0x54);
++ else if (freq_KHz > 500000)
++ _mt_fe_tn_set_reg(state, 0x87, 0x54);
++ else if (freq_KHz > 300000)
++ _mt_fe_tn_set_reg(state, 0x87, 0x43);
++ else if (freq_KHz > 220000)
++ _mt_fe_tn_set_reg(state, 0x87, 0x54);
++ else if (freq_KHz > 110000)
++ _mt_fe_tn_set_reg(state, 0x87, 0x14);
++ else
++ _mt_fe_tn_set_reg(state, 0x87, 0x54);
++ msleep(5);
++ } else if (buf < 0x0c) {
++ if (freq_KHz > 800000)
++ _mt_fe_tn_set_reg(state, 0x87, 0x14);
++ else if (freq_KHz > 600000)
++ _mt_fe_tn_set_reg(state, 0x87, 0x14);
++ else if (freq_KHz > 500000)
++ _mt_fe_tn_set_reg(state, 0x87, 0x34);
++ else if (freq_KHz > 300000)
++ _mt_fe_tn_set_reg(state, 0x87, 0x43);
++ else if (freq_KHz > 220000)
++ _mt_fe_tn_set_reg(state, 0x87, 0x54);
++ else if (freq_KHz > 110000)
++ _mt_fe_tn_set_reg(state, 0x87, 0x14);
++ else
++ _mt_fe_tn_set_reg(state, 0x87, 0x54);
++ msleep(5);
++ }
++ } else if ((state->tuner_mtt == 0xE1)) {
++ _mt_fe_tn_set_reg(state, 0x00, 0x01);
++ _mt_fe_tn_set_reg(state, 0x00, 0x00);
++ msleep(20);
++ _mt_fe_tn_get_reg(state, 0x32, &buf);
++ buf = (buf & 0xef) | 0x28;
++ _mt_fe_tn_set_reg(state, 0x32, buf);
++ msleep(50);
++ _mt_fe_tn_get_reg(state, 0x38, &buf);
++ _mt_fe_tn_set_reg(state, 0x38, buf);
++ _mt_fe_tn_get_reg(state, 0x32, &buf);
++ buf = (buf & 0xf7) | 0x10;
++ _mt_fe_tn_set_reg(state, 0x32, buf);
++ msleep(10);
++ _mt_fe_tn_get_reg(state, 0x69, &buf);
++ buf = buf & 0x03;
++ _mt_fe_tn_set_reg(state, 0x2a, buf);
++ if (buf > 0) {
++ msleep(20);
++ _mt_fe_tn_get_reg(state, 0x84, &buf);
++ buf = buf & 0x1f;
++ _mt_fe_tn_set_reg(state, 0x68, 0x0a);
++ _mt_fe_tn_get_reg(state, 0x88, &buf1);
++ buf1 = buf1 & 0x1f;
++ if (buf <= buf1)
++ _mt_fe_tn_set_reg(state, 0x66, 0x44);
++ else
++ _mt_fe_tn_set_reg(state, 0x66, 0x74);
++ } else {
++ if (freq_KHz <= 600000)
++ _mt_fe_tn_set_reg(state, 0x68, 0x0c);
++ else
++ _mt_fe_tn_set_reg(state, 0x68, 0x0e);
++ _mt_fe_tn_set_reg(state, 0x30, 0xfb);
++ _mt_fe_tn_set_reg(state, 0x30, 0xff);
++ _mt_fe_tn_set_reg(state, 0x31, 0x04);
++ _mt_fe_tn_set_reg(state, 0x31, 0x00);
++ }
++ if (state->tuner_loopthrough != 0) {
++ _mt_fe_tn_get_reg(state, 0x28, &buf);
++ if (buf == 0) {
++ _mt_fe_tn_set_reg(state, 0x28, 0xff);
++ _mt_fe_tn_get_reg(state, 0x61, &buf);
++ buf = buf & 0x0f;
++ if (buf > 9)
++ _mt_fe_tn_set_reg(state, 0x67, 0x74);
++ else if (buf > 6)
++ _mt_fe_tn_set_reg(state, 0x67, 0x64);
++ else if (buf > 3)
++ _mt_fe_tn_set_reg(state, 0x67, 0x54);
++ else
++ _mt_fe_tn_set_reg(state, 0x67, 0x44);
++ }
++ } else {
++ _mt_fe_tn_set_reg(state, 0x67, 0x34);
++ }
++ } else {
++ return 1;
++ }
++ return 0;
++}
++
++
++/*
++static int mt_fe_tn_set_BB_filter_band_tc2800(struct m88dc2800_state *state,
++ u8 bandwidth)
++{
++ u8 buf, tmp;
++
++ _mt_fe_tn_get_reg(state, 0x53, &tmp);
++
++ if (bandwidth == 6)
++ buf = 0x01 << 1;
++ else if (bandwidth == 7)
++ buf = 0x02 << 1;
++ else if (bandwidth == 8)
++ buf = 0x04 << 1;
++ else
++ buf = 0x04 << 1;
++
++ tmp &= 0xf1;
++ tmp |= buf;
++ _mt_fe_tn_set_reg(state, 0x53, tmp);
++ state->tuner_bandwidth = bandwidth;
++ return 0;
++}
++*/
++
++static s32 mt_fe_tn_get_signal_strength_tc2800(struct m88dc2800_state
++ *state)
++{
++ s32 level = -107;
++ s32 tmp1, tmp2, tmp3, tmp4, tmp5, tmp6;
++ s32 val1, val2, val;
++ s32 result2, result3, result4, result5, result6;
++ s32 append;
++ u8 tmp;
++ s32 freq_KHz = (s32) state->tuner_freq;
++ if (state->tuner_mtt == 0xD1) {
++ _mt_fe_tn_get_reg(state, 0x61, &tmp);
++ tmp1 = tmp & 0x0f;
++ _mt_fe_tn_get_reg(state, 0x69, &tmp);
++ tmp2 = tmp & 0x0f;
++ _mt_fe_tn_get_reg(state, 0x73, &tmp);
++ tmp3 = tmp & 0x07;
++ _mt_fe_tn_get_reg(state, 0x7c, &tmp);
++ tmp4 = (tmp >> 4) & 0x0f;
++ _mt_fe_tn_get_reg(state, 0x7b, &tmp);
++ tmp5 = tmp & 0x0f;
++ _mt_fe_tn_get_reg(state, 0x7f, &tmp);
++ tmp6 = (tmp >> 5) & 0x01;
++ if (tmp1 > 6) {
++ val1 = 0;
++ if (freq_KHz <= 200000) {
++ val2 = (tmp1 - 6) * 267;
++ } else if (freq_KHz <= 600000) {
++ val2 = (tmp1 - 6) * 280;
++ } else {
++ val2 = (tmp1 - 6) * 290;
++ }
++ val = val1 + val2;
++ } else {
++ if (tmp1 == 0) {
++ val1 = -550;
++ } else {
++ val1 = 0;
++ }
++ if ((tmp1 < 4) && (freq_KHz >= 506000)) {
++ val1 = -850;
++ }
++ val2 = 0;
++ val = val1 + val2;
++ }
++ if (freq_KHz <= 95000) {
++ result2 = tmp2 * 289;
++ } else if (freq_KHz <= 155000) {
++ result2 = tmp2 * 278;
++ } else if (freq_KHz <= 245000) {
++ result2 = tmp2 * 267;
++ } else if (freq_KHz <= 305000) {
++ result2 = tmp2 * 256;
++ } else if (freq_KHz <= 335000) {
++ result2 = tmp2 * 244;
++ } else if (freq_KHz <= 425000) {
++ result2 = tmp2 * 233;
++ } else if (freq_KHz <= 575000) {
++ result2 = tmp2 * 222;
++ } else if (freq_KHz <= 665000) {
++ result2 = tmp2 * 211;
++ } else {
++ result2 = tmp2 * 200;
++ }
++ result3 = (6 - tmp3) * 100;
++ result4 = 300 * tmp4;
++ result5 = 50 * tmp5;
++ result6 = 300 * tmp6;
++ if (freq_KHz < 105000) {
++ append = -450;
++ } else if (freq_KHz <= 227000) {
++ append = -4 * (freq_KHz / 1000 - 100) + 150;
++ } else if (freq_KHz <= 305000) {
++ append = -4 * (freq_KHz / 1000 - 100);
++ } else if (freq_KHz <= 419000) {
++ append = 500 - 40 * (freq_KHz / 1000 - 300) / 17 + 130;
++ } else if (freq_KHz <= 640000) {
++ append = 500 - 40 * (freq_KHz / 1000 - 300) / 17;
++ } else {
++ append = -500;
++ }
++ level = append - (val + result2 + result3 + result4 +
++ result5 + result6);
++ level /= 100;
++ } else if (state->tuner_mtt == 0xE1) {
++ _mt_fe_tn_get_reg(state, 0x61, &tmp);
++ tmp1 = tmp & 0x0f;
++ _mt_fe_tn_get_reg(state, 0x84, &tmp);
++ tmp2 = tmp & 0x1f;
++ _mt_fe_tn_get_reg(state, 0x69, &tmp);
++ tmp3 = tmp & 0x03;
++ _mt_fe_tn_get_reg(state, 0x73, &tmp);
++ tmp4 = tmp & 0x0f;
++ _mt_fe_tn_get_reg(state, 0x7c, &tmp);
++ tmp5 = (tmp >> 4) & 0x0f;
++ _mt_fe_tn_get_reg(state, 0x7b, &tmp);
++ tmp6 = tmp & 0x0f;
++ if (freq_KHz < 151000) {
++ result2 = (1150 - freq_KHz / 100) * 163 / 33 + 4230;
++ result3 = (1150 - freq_KHz / 100) * 115 / 33 + 1850;
++ result4 = -3676 * (freq_KHz / 1000) / 100 + 6115;
++ } else if (freq_KHz < 257000) {
++ result2 = (1540 - freq_KHz / 100) * 11 / 4 + 3870;
++ result3 = (1540 - freq_KHz / 100) * 205 / 96 + 2100;
++ result4 = -21 * freq_KHz / 1000 + 5084;
++ } else if (freq_KHz < 305000) {
++ result2 = (2620 - freq_KHz / 100) * 5 / 3 + 2770;
++ result3 = (2620 - freq_KHz / 100) * 10 / 7 + 1700;
++ result4 = 650;
++ } else if (freq_KHz < 449000) {
++ result2 = (307 - freq_KHz / 1000) * 82 / 27 + 11270;
++ result3 = (3100 - freq_KHz / 100) * 5 / 3 + 10000;
++ result4 = 134 * freq_KHz / 10000 + 11875;
++ } else {
++ result2 = (307 - freq_KHz / 1000) * 82 / 27 + 11270;
++ result3 = 8400;
++ result4 = 5300;
++ }
++ if (tmp1 > 6) {
++ val1 = result2;
++ val2 = 2900;
++ val = 500;
++ } else if (tmp1 > 0) {
++ val1 = result3;
++ val2 = 2700;
++ val = 500;
++ } else {
++ val1 = result4;
++ val2 = 2700;
++ val = 400;
++ }
++ level = val1 - (val2 * tmp1 + 500 * tmp2 + 3000 * tmp3 -
++ 500 * tmp4 + 3000 * tmp5 + val * tmp6) - 1000;
++ level /= 1000;
++ }
++ return level;
++}
++
++
++/* m88dc2800 operation functions */
++u8 M88DC2000GetLock(struct m88dc2800_state * state)
++{
++ u8 u8ret = 0;
++ if (ReadReg(state, 0x80) < 0x06) {
++ if ((ReadReg(state, 0xdf) & 0x80) == 0x80
++ &&(ReadReg(state, 0x91) & 0x23) == 0x03
++ &&(ReadReg(state, 0x43) & 0x08) == 0x08)
++ u8ret = 1;
++ else
++ u8ret = 0;
++ } else {
++ if ((ReadReg(state, 0x85) & 0x08) == 0x08)
++ u8ret = 1;
++ else
++ u8ret = 0;
++ }
++ dprintk("%s, lock=%d\n", __func__, u8ret);
++ return u8ret;
++}
++
++static int M88DC2000SetTsType(struct m88dc2800_state *state, u8 type)
++{
++ u8 regC2H;
++
++ if (type == 3) {
++ WriteReg(state, 0x84, 0x6A);
++ WriteReg(state, 0xC0, 0x43);
++ WriteReg(state, 0xE2, 0x06);
++ regC2H = ReadReg(state, 0xC2);
++ regC2H &= 0xC0;
++ regC2H |= 0x1B;
++ WriteReg(state, 0xC2, regC2H);
++ WriteReg(state, 0xC1, 0x60); /* common interface */
++ } else if (type == 1) {
++ WriteReg(state, 0x84, 0x6A);
++ WriteReg(state, 0xC0, 0x47); /* serial format */
++ WriteReg(state, 0xE2, 0x02);
++ regC2H = ReadReg(state, 0xC2);
++ regC2H &= 0xC7;
++ WriteReg(state, 0xC2, regC2H);
++ WriteReg(state, 0xC1, 0x00);
++ } else {
++ WriteReg(state, 0x84, 0x6C);
++ WriteReg(state, 0xC0, 0x43); /* parallel format */
++ WriteReg(state, 0xE2, 0x06);
++ regC2H = ReadReg(state, 0xC2);
++ regC2H &= 0xC7;
++ WriteReg(state, 0xC2, regC2H);
++ WriteReg(state, 0xC1, 0x00);
++ }
++ return 0;
++}
++
++static int M88DC2000RegInitial_TC2800(struct m88dc2800_state *state)
++{
++ u8 RegE3H, RegE4H;
++
++ WriteReg(state, 0x00, 0x48);
++ WriteReg(state, 0x01, 0x09);
++ WriteReg(state, 0xFB, 0x0A);
++ WriteReg(state, 0xFC, 0x0B);
++ WriteReg(state, 0x02, 0x0B);
++ WriteReg(state, 0x03, 0x18);
++ WriteReg(state, 0x05, 0x0D);
++ WriteReg(state, 0x36, 0x80);
++ WriteReg(state, 0x43, 0x40);
++ WriteReg(state, 0x55, 0x7A);
++ WriteReg(state, 0x56, 0xD9);
++ WriteReg(state, 0x57, 0xDF);
++ WriteReg(state, 0x58, 0x39);
++ WriteReg(state, 0x5A, 0x00);
++ WriteReg(state, 0x5C, 0x71);
++ WriteReg(state, 0x5D, 0x23);
++ WriteReg(state, 0x86, 0x40);
++ WriteReg(state, 0xF9, 0x08);
++ WriteReg(state, 0x61, 0x40);
++ WriteReg(state, 0x62, 0x0A);
++ WriteReg(state, 0x90, 0x06);
++ WriteReg(state, 0xDE, 0x00);
++ WriteReg(state, 0xA0, 0x03);
++ WriteReg(state, 0xDF, 0x81);
++ WriteReg(state, 0xFA, 0x40);
++ WriteReg(state, 0x37, 0x10);
++ WriteReg(state, 0xF0, 0x40);
++ WriteReg(state, 0xF2, 0x9C);
++ WriteReg(state, 0xF3, 0x40);
++ RegE3H = ReadReg(state, 0xE3);
++ RegE4H = ReadReg(state, 0xE4);
++ if (((RegE3H & 0xC0) == 0x00) && ((RegE4H & 0xC0) == 0x00)) {
++ WriteReg(state, 0x30, 0xFF);
++ WriteReg(state, 0x31, 0x00);
++ WriteReg(state, 0x32, 0x00);
++ WriteReg(state, 0x33, 0x00);
++ WriteReg(state, 0x35, 0x32);
++ WriteReg(state, 0x40, 0x00);
++ WriteReg(state, 0x41, 0x10);
++ WriteReg(state, 0xF1, 0x02);
++ WriteReg(state, 0xF4, 0x04);
++ WriteReg(state, 0xF5, 0x00);
++ WriteReg(state, 0x42, 0x14);
++ WriteReg(state, 0xE1, 0x25);
++ } else if (((RegE3H & 0xC0) == 0x80) && ((RegE4H & 0xC0) == 0x40)) {
++ WriteReg(state, 0x30, 0xFF);
++ WriteReg(state, 0x31, 0x00);
++ WriteReg(state, 0x32, 0x00);
++ WriteReg(state, 0x33, 0x00);
++ WriteReg(state, 0x35, 0x32);
++ WriteReg(state, 0x39, 0x00);
++ WriteReg(state, 0x3A, 0x00);
++ WriteReg(state, 0x40, 0x00);
++ WriteReg(state, 0x41, 0x10);
++ WriteReg(state, 0xF1, 0x00);
++ WriteReg(state, 0xF4, 0x00);
++ WriteReg(state, 0xF5, 0x40);
++ WriteReg(state, 0x42, 0x14);
++ WriteReg(state, 0xE1, 0x25);
++ } else if ((RegE3H == 0x80 || RegE3H == 0x81)
++ && (RegE4H == 0x80 || RegE4H == 0x81)) {
++ WriteReg(state, 0x30, 0xFF);
++ WriteReg(state, 0x31, 0x00);
++ WriteReg(state, 0x32, 0x00);
++ WriteReg(state, 0x33, 0x00);
++ WriteReg(state, 0x35, 0x32);
++ WriteReg(state, 0x39, 0x00);
++ WriteReg(state, 0x3A, 0x00);
++ WriteReg(state, 0xF1, 0x00);
++ WriteReg(state, 0xF4, 0x00);
++ WriteReg(state, 0xF5, 0x40);
++ WriteReg(state, 0x42, 0x24);
++ WriteReg(state, 0xE1, 0x25);
++ WriteReg(state, 0x92, 0x7F);
++ WriteReg(state, 0x93, 0x91);
++ WriteReg(state, 0x95, 0x00);
++ WriteReg(state, 0x2B, 0x33);
++ WriteReg(state, 0x2A, 0x2A);
++ WriteReg(state, 0x2E, 0x80);
++ WriteReg(state, 0x25, 0x25);
++ WriteReg(state, 0x2D, 0xFF);
++ WriteReg(state, 0x26, 0xFF);
++ WriteReg(state, 0x27, 0x00);
++ WriteReg(state, 0x24, 0x25);
++ WriteReg(state, 0xA4, 0xFF);
++ WriteReg(state, 0xA3, 0x0D);
++ } else {
++ WriteReg(state, 0x30, 0xFF);
++ WriteReg(state, 0x31, 0x00);
++ WriteReg(state, 0x32, 0x00);
++ WriteReg(state, 0x33, 0x00);
++ WriteReg(state, 0x35, 0x32);
++ WriteReg(state, 0x39, 0x00);
++ WriteReg(state, 0x3A, 0x00);
++ WriteReg(state, 0xF1, 0x00);
++ WriteReg(state, 0xF4, 0x00);
++ WriteReg(state, 0xF5, 0x40);
++ WriteReg(state, 0x42, 0x24);
++ WriteReg(state, 0xE1, 0x27);
++ WriteReg(state, 0x92, 0x7F);
++ WriteReg(state, 0x93, 0x91);
++ WriteReg(state, 0x95, 0x00);
++ WriteReg(state, 0x2B, 0x33);
++ WriteReg(state, 0x2A, 0x2A);
++ WriteReg(state, 0x2E, 0x80);
++ WriteReg(state, 0x25, 0x25);
++ WriteReg(state, 0x2D, 0xFF);
++ WriteReg(state, 0x26, 0xFF);
++ WriteReg(state, 0x27, 0x00);
++ WriteReg(state, 0x24, 0x25);
++ WriteReg(state, 0xA4, 0xFF);
++ WriteReg(state, 0xA3, 0x10);
++ }
++ WriteReg(state, 0xF6, 0x4E);
++ WriteReg(state, 0xF7, 0x20);
++ WriteReg(state, 0x89, 0x02);
++ WriteReg(state, 0x14, 0x08);
++ WriteReg(state, 0x6F, 0x0D);
++ WriteReg(state, 0x10, 0xFF);
++ WriteReg(state, 0x11, 0x00);
++ WriteReg(state, 0x12, 0x30);
++ WriteReg(state, 0x13, 0x23);
++ WriteReg(state, 0x60, 0x00);
++ WriteReg(state, 0x69, 0x00);
++ WriteReg(state, 0x6A, 0x03);
++ WriteReg(state, 0xE0, 0x75);
++ WriteReg(state, 0x8D, 0x29);
++ WriteReg(state, 0x4E, 0xD8);
++ WriteReg(state, 0x88, 0x80);
++ WriteReg(state, 0x52, 0x79);
++ WriteReg(state, 0x53, 0x03);
++ WriteReg(state, 0x59, 0x30);
++ WriteReg(state, 0x5E, 0x02);
++ WriteReg(state, 0x5F, 0x0F);
++ WriteReg(state, 0x71, 0x03);
++ WriteReg(state, 0x72, 0x12);
++ WriteReg(state, 0x73, 0x12);
++
++ return 0;
++}
++
++static int M88DC2000AutoTSClock_P(struct m88dc2800_state *state, u32 sym,
++ u16 qam)
++{
++ u32 dataRate;
++ u8 clk_div, value;
++ printk(KERN_INFO
++ "m88dc2800: M88DC2000AutoTSClock_P, symrate=%d qam=%d\n",
++ sym, qam);
++ switch (qam) {
++ case 16:
++ dataRate = 4;
++ break;
++ case 32:
++ dataRate = 5;
++ break;
++ case 128:
++ dataRate = 7;
++ break;
++ case 256:
++ dataRate = 8;
++ break;
++ case 64:
++ default:
++ dataRate = 6;
++ break;
++ }
++ dataRate *= sym * 105;
++ dataRate /= 800;
++ if (dataRate <= 4115)
++ clk_div = 0x05;
++ else if (dataRate <= 4800)
++ clk_div = 0x04;
++ else if (dataRate <= 5760)
++ clk_div = 0x03;
++ else if (dataRate <= 7200)
++ clk_div = 0x02;
++ else if (dataRate <= 9600)
++ clk_div = 0x01;
++ else
++ clk_div = 0x00;
++ value = ReadReg(state, 0xC2);
++ value &= 0xc0;
++ value |= clk_div;
++ WriteReg(state, 0xC2, value);
++ return 0;
++}
++
++static int M88DC2000AutoTSClock_C(struct m88dc2800_state *state, u32 sym,
++ u16 qam)
++{
++ u32 dataRate;
++ u8 clk_div, value;
++ printk(KERN_INFO
++ "m88dc2800: M88DC2000AutoTSClock_C, symrate=%d qam=%d\n",
++ sym, qam);
++ switch (qam) {
++ case 16:
++ dataRate = 4;
++ break;
++ case 32:
++ dataRate = 5;
++ break;
++ case 128:
++ dataRate = 7;
++ break;
++ case 256:
++ dataRate = 8;
++ break;
++ case 64:
++ default:
++ dataRate = 6;
++ break;
++ }
++ dataRate *= sym * 105;
++ dataRate /= 800;
++ if (dataRate <= 4115)
++ clk_div = 0x3F;
++ else if (dataRate <= 4800)
++ clk_div = 0x36;
++ else if (dataRate <= 5760)
++ clk_div = 0x2D;
++ else if (dataRate <= 7200)
++ clk_div = 0x24;
++ else if (dataRate <= 9600)
++ clk_div = 0x1B;
++ else
++ clk_div = 0x12;
++ value = ReadReg(state, 0xC2);
++ value &= 0xc0;
++ value |= clk_div;
++ WriteReg(state, 0xC2, value);
++ return 0;
++}
++
++static int M88DC2000SetTxMode(struct m88dc2800_state *state, u8 inverted,
++ u8 j83)
++{
++ u8 value = 0;
++ if (inverted)
++ value |= 0x08; /* spectrum inverted */
++ if (j83)
++ value |= 0x01; /* J83C */
++ WriteReg(state, 0x83, value);
++ return 0;
++}
++
++static int M88DC2000SoftReset(struct m88dc2800_state *state)
++{
++ WriteReg(state, 0x80, 0x01);
++ WriteReg(state, 0x82, 0x00);
++ msleep(1);
++ WriteReg(state, 0x80, 0x00);
++ return 0;
++}
++
++static int M88DC2000SetSym(struct m88dc2800_state *state, u32 sym, u32 xtal)
++{
++ u8 value;
++ u8 reg6FH, reg12H;
++ u64 fValue;
++ u32 dwValue;
++
++ printk(KERN_INFO "%s, sym=%d, xtal=%d\n", __func__, sym, xtal);
++ fValue = 4294967296 * (sym + 10);
++ do_div(fValue, xtal);
++
++ /* fValue = 4294967296 * (sym + 10) / xtal; */
++ dwValue = (u32) fValue;
++ printk(KERN_INFO "%s, fvalue1=%x\n", __func__, dwValue);
++ WriteReg(state, 0x58, (u8) ((dwValue >> 24) & 0xff));
++ WriteReg(state, 0x57, (u8) ((dwValue >> 16) & 0xff));
++ WriteReg(state, 0x56, (u8) ((dwValue >> 8) & 0xff));
++ WriteReg(state, 0x55, (u8) ((dwValue >> 0) & 0xff));
++
++ /* fValue = 2048 * xtal / sym; */
++ fValue = 2048 * xtal;
++ do_div(fValue, sym);
++ dwValue = (u32) fValue;
++ printk(KERN_INFO "%s, fvalue2=%x\n", __func__, dwValue);
++ WriteReg(state, 0x5D, (u8) ((dwValue >> 8) & 0xff));
++ WriteReg(state, 0x5C, (u8) ((dwValue >> 0) & 0xff));
++ value = ReadReg(state, 0x5A);
++ if (((dwValue >> 16) & 0x0001) == 0)
++ value &= 0x7F;
++ else
++ value |= 0x80;
++ WriteReg(state, 0x5A, value);
++ value = ReadReg(state, 0x89);
++ if (sym <= 1800)
++ value |= 0x01;
++ else
++ value &= 0xFE;
++ WriteReg(state, 0x89, value);
++ if (sym >= 6700) {
++ reg6FH = 0x0D;
++ reg12H = 0x30;
++ } else if (sym >= 4000) {
++ fValue = 22 * 4096 / sym;
++ reg6FH = (u8) fValue;
++ reg12H = 0x30;
++ } else if (sym >= 2000) {
++ fValue = 14 * 4096 / sym;
++ reg6FH = (u8) fValue;
++ reg12H = 0x20;
++ } else {
++ fValue = 7 * 4096 / sym;
++ reg6FH = (u8) fValue;
++ reg12H = 0x10;
++ }
++ WriteReg(state, 0x6F, reg6FH);
++ WriteReg(state, 0x12, reg12H);
++ if (((ReadReg(state, 0xE3) & 0x80) == 0x80)
++ && ((ReadReg(state, 0xE4) & 0x80) == 0x80)) {
++ if (sym < 3000) {
++ WriteReg(state, 0x6C, 0x16);
++ WriteReg(state, 0x6D, 0x10);
++ WriteReg(state, 0x6E, 0x18);
++ } else {
++ WriteReg(state, 0x6C, 0x14);
++ WriteReg(state, 0x6D, 0x0E);
++ WriteReg(state, 0x6E, 0x36);
++ }
++ } else {
++ WriteReg(state, 0x6C, 0x16);
++ WriteReg(state, 0x6D, 0x10);
++ WriteReg(state, 0x6E, 0x18);
++ }
++ return 0;
++}
++
++static int M88DC2000SetQAM(struct m88dc2800_state *state, u16 qam)
++{
++ u8 reg00H, reg4AH, regC2H, reg44H, reg4CH, reg4DH, reg74H, value;
++ u8 reg8BH, reg8EH;
++ printk(KERN_INFO "%s, qam=%d\n", __func__, qam);
++ regC2H = ReadReg(state, 0xC2);
++ regC2H &= 0xF8;
++ switch (qam) {
++ case 16: /* 16 QAM */
++ reg00H = 0x08;
++ reg4AH = 0x0F;
++ regC2H |= 0x02;
++ reg44H = 0xAA;
++ reg4CH = 0x0C;
++ reg4DH = 0xF7;
++ reg74H = 0x0E;
++ if (((ReadReg(state, 0xE3) & 0x80) == 0x80)
++ && ((ReadReg(state, 0xE4) & 0x80) == 0x80)) {
++ reg8BH = 0x5A;
++ reg8EH = 0xBD;
++ } else {
++ reg8BH = 0x5B;
++ reg8EH = 0x9D;
++ }
++ WriteReg(state, 0x6E, 0x18);
++ break;
++ case 32: /* 32 QAM */
++ reg00H = 0x18;
++ reg4AH = 0xFB;
++ regC2H |= 0x02;
++ reg44H = 0xAA;
++ reg4CH = 0x0C;
++ reg4DH = 0xF7;
++ reg74H = 0x0E;
++ if (((ReadReg(state, 0xE3) & 0x80) == 0x80)
++ && ((ReadReg(state, 0xE4) & 0x80) == 0x80)) {
++ reg8BH = 0x5A;
++ reg8EH = 0xBD;
++ } else {
++ reg8BH = 0x5B;
++ reg8EH = 0x9D;
++ }
++ WriteReg(state, 0x6E, 0x18);
++ break;
++ case 64: /* 64 QAM */
++ reg00H = 0x48;
++ reg4AH = 0xCD;
++ regC2H |= 0x02;
++ reg44H = 0xAA;
++ reg4CH = 0x0C;
++ reg4DH = 0xF7;
++ reg74H = 0x0E;
++ if (((ReadReg(state, 0xE3) & 0x80) == 0x80)
++ && ((ReadReg(state, 0xE4) & 0x80) == 0x80)) {
++ reg8BH = 0x5A;
++ reg8EH = 0xBD;
++ } else {
++ reg8BH = 0x5B;
++ reg8EH = 0x9D;
++ }
++ break;
++ case 128: /* 128 QAM */
++ reg00H = 0x28;
++ reg4AH = 0xFF;
++ regC2H |= 0x02;
++ reg44H = 0xA9;
++ reg4CH = 0x08;
++ reg4DH = 0xF5;
++ reg74H = 0x0E;
++ reg8BH = 0x5B;
++ reg8EH = 0x9D;
++ break;
++ case 256: /* 256 QAM */
++ reg00H = 0x38;
++ reg4AH = 0xCD;
++ if (((ReadReg(state, 0xE3) & 0x80) == 0x80)
++ && ((ReadReg(state, 0xE4) & 0x80) == 0x80)) {
++ regC2H |= 0x02;
++ } else {
++ regC2H |= 0x01;
++ }
++ reg44H = 0xA9;
++ reg4CH = 0x08;
++ reg4DH = 0xF5;
++ reg74H = 0x0E;
++ reg8BH = 0x5B;
++ reg8EH = 0x9D;
++ break;
++ default: /* 64 QAM */
++ reg00H = 0x48;
++ reg4AH = 0xCD;
++ regC2H |= 0x02;
++ reg44H = 0xAA;
++ reg4CH = 0x0C;
++ reg4DH = 0xF7;
++ reg74H = 0x0E;
++ if (((ReadReg(state, 0xE3) & 0x80) == 0x80)
++ && ((ReadReg(state, 0xE4) & 0x80) == 0x80)) {
++ reg8BH = 0x5A;
++ reg8EH = 0xBD;
++ } else {
++ reg8BH = 0x5B;
++ reg8EH = 0x9D;
++ }
++ break;
++ }
++ WriteReg(state, 0x00, reg00H);
++ value = ReadReg(state, 0x88);
++ value |= 0x08;
++ WriteReg(state, 0x88, value);
++ WriteReg(state, 0x4B, 0xFF);
++ WriteReg(state, 0x4A, reg4AH);
++ value &= 0xF7;
++ WriteReg(state, 0x88, value);
++ WriteReg(state, 0xC2, regC2H);
++ WriteReg(state, 0x44, reg44H);
++ WriteReg(state, 0x4C, reg4CH);
++ WriteReg(state, 0x4D, reg4DH);
++ WriteReg(state, 0x74, reg74H);
++ WriteReg(state, 0x8B, reg8BH);
++ WriteReg(state, 0x8E, reg8EH);
++ return 0;
++}
++
++static int M88DC2000WriteTuner_TC2800(struct m88dc2800_state *state,
++ u32 freq_KHz)
++{
++ printk(KERN_INFO "%s, freq=%d KHz\n", __func__, freq_KHz);
++ return mt_fe_tn_set_freq_tc2800(state, freq_KHz);
++}
++
++static int m88dc2800_init(struct dvb_frontend *fe)
++{
++ dprintk("%s()\n", __func__);
++ return 0;
++}
++
++static int m88dc2800_set_parameters(struct dvb_frontend *fe)
++{
++ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
++ u8 is_annex_c, is_update;
++ u16 temp_qam;
++ s32 waiting_time;
++ struct m88dc2800_state *state = fe->demodulator_priv;
++
++ is_annex_c = c->delivery_system == SYS_DVBC_ANNEX_C ? 1 : 0;
++
++ switch (c->modulation) {
++ case QAM_16:
++ temp_qam = 16;
++ break;
++ case QAM_32:
++ temp_qam = 32;
++ break;
++ case QAM_128:
++ temp_qam = 128;
++ break;
++ case QAM_256:
++ temp_qam = 256;
++ break;
++ default: /* QAM_64 */
++ temp_qam = 64;
++ break;
++ }
++
++ state->inverted = c->inversion == INVERSION_ON ? 1 : 0;
++
++ printk(KERN_INFO
++ "m88dc2800: state, freq=%d qam=%d sym=%d inverted=%d xtal=%d\n",
++ state->freq, state->qam, state->sym, state->inverted,
++ state->xtal);
++ printk(KERN_INFO
++ "m88dc2800: set frequency to %d qam=%d symrate=%d annex-c=%d\n",
++ c->frequency, temp_qam, c->symbol_rate, is_annex_c);
++
++ is_update = 0;
++ WriteReg(state, 0x80, 0x01);
++ if (c->frequency != state->freq) {
++ M88DC2000WriteTuner_TC2800(state, c->frequency / 1000);
++ state->freq = c->frequency;
++ }
++ if (c->symbol_rate != state->sym) {
++ M88DC2000SetSym(state, c->symbol_rate / 1000, state->xtal);
++ state->sym = c->symbol_rate;
++ is_update = 1;
++ }
++ if (temp_qam != state->qam) {
++ M88DC2000SetQAM(state, temp_qam);
++ state->qam = temp_qam;
++ is_update = 1;
++ }
++
++ if (is_update != 0) {
++ if (state->config->ts_mode == 3)
++ M88DC2000AutoTSClock_C(state, state->sym / 1000,
++ temp_qam);
++ else
++ M88DC2000AutoTSClock_P(state, state->sym / 1000,
++ temp_qam);
++ }
++
++ M88DC2000SetTxMode(state, state->inverted, is_annex_c);
++ M88DC2000SoftReset(state);
++ if (((ReadReg(state, 0xE3) & 0x80) == 0x80)
++ && ((ReadReg(state, 0xE4) & 0x80) == 0x80))
++ waiting_time = 800;
++ else
++ waiting_time = 500;
++ while (waiting_time > 0) {
++ msleep(50);
++ waiting_time -= 50;
++ if (M88DC2000GetLock(state))
++ return 0;
++ }
++
++ state->inverted = (state->inverted != 0) ? 0 : 1;
++ M88DC2000SetTxMode(state, state->inverted, is_annex_c);
++ M88DC2000SoftReset(state);
++ if (((ReadReg(state, 0xE3) & 0x80) == 0x80) &&
++ ((ReadReg(state, 0xE4) & 0x80) == 0x80))
++ waiting_time = 800;
++ else
++ waiting_time = 500;
++ while (waiting_time > 0) {
++ msleep(50);
++ waiting_time -= 50;
++ if (M88DC2000GetLock(state))
++ return 0;
++ }
++ return 0;
++}
++
++static int m88dc2800_read_status(struct dvb_frontend *fe,
++ fe_status_t * status)
++{
++ struct m88dc2800_state *state = fe->demodulator_priv;
++ *status = 0;
++
++ if (M88DC2000GetLock(state)) {
++ *status = FE_HAS_SIGNAL | FE_HAS_CARRIER
++ |FE_HAS_SYNC | FE_HAS_VITERBI | FE_HAS_LOCK;
++ }
++ return 0;
++}
++
++static int m88dc2800_read_ber(struct dvb_frontend *fe, u32 * ber)
++{
++ struct m88dc2800_state *state = fe->demodulator_priv;
++ u16 tmp;
++
++ if (M88DC2000GetLock(state) == 0) {
++ state->ber = 0;
++ } else if ((ReadReg(state, 0xA0) & 0x80) != 0x80) {
++ tmp = ReadReg(state, 0xA2) << 8;
++ tmp += ReadReg(state, 0xA1);
++ state->ber = tmp;
++ WriteReg(state, 0xA0, 0x05);
++ WriteReg(state, 0xA0, 0x85);
++ }
++ *ber = state->ber;
++ return 0;
++}
++
++static int m88dc2800_read_signal_strength(struct dvb_frontend *fe,
++ u16 * strength)
++{
++ struct m88dc2800_state *state = fe->demodulator_priv;
++ s16 tuner_strength;
++
++ tuner_strength = mt_fe_tn_get_signal_strength_tc2800(state);
++ *strength = tuner_strength < -107 ? 0 : tuner_strength + 107;
++
++ return 0;
++}
++
++static int m88dc2800_read_snr(struct dvb_frontend *fe, u16 * snr)
++{
++ static const u32 mes_log[] = {
++ 0, 3010, 4771, 6021, 6990, 7781, 8451, 9031, 9542, 10000,
++ 10414, 10792, 11139, 11461, 11761, 12041, 12304, 12553, 12788,
++ 13010, 13222, 13424, 13617, 13802, 13979, 14150, 14314, 14472,
++ 14624, 14771, 14914, 15052, 15185, 15315, 15441, 15563, 15682,
++ 15798, 15911, 16021, 16128, 16232, 16335, 16435, 16532, 16628,
++ 16721, 16812, 16902, 16990, 17076, 17160, 17243, 17324, 17404,
++ 17482, 17559, 17634, 17709, 17782, 17853, 17924, 17993, 18062,
++ 18129, 18195, 18261, 18325, 18388, 18451, 18513, 18573, 18633,
++ 18692, 18751, 18808, 18865, 18921, 18976, 19031
++ };
++ struct m88dc2800_state *state = fe->demodulator_priv;
++ u8 i;
++ u32 _snr, mse;
++
++ if ((ReadReg(state, 0x91) & 0x23) != 0x03) {
++ *snr = 0;
++ return 0;
++ }
++ mse = 0;
++ for (i = 0; i < 30; i++) {
++ mse += (ReadReg(state, 0x08) << 8) + ReadReg(state, 0x07);
++ }
++ mse /= 30;
++ if (mse > 80)
++ mse = 80;
++ switch (state->qam) {
++ case 16:
++ _snr = 34080;
++ break; /* 16QAM */
++ case 32:
++ _snr = 37600;
++ break; /* 32QAM */
++ case 64:
++ _snr = 40310;
++ break; /* 64QAM */
++ case 128:
++ _snr = 43720;
++ break; /* 128QAM */
++ case 256:
++ _snr = 46390;
++ break; /* 256QAM */
++ default:
++ _snr = 40310;
++ break;
++ }
++ _snr -= mes_log[mse - 1]; /* C - 10*log10(MSE) */
++ _snr /= 1000;
++ if (_snr > 0xff)
++ _snr = 0xff;
++ *snr = _snr;
++ return 0;
++}
++
++static int m88dc2800_read_ucblocks(struct dvb_frontend *fe, u32 * ucblocks)
++{
++ struct m88dc2800_state *state = fe->demodulator_priv;
++ u8 u8Value;
++
++ u8Value = ReadReg(state, 0xdf);
++ u8Value |= 0x02; /* Hold */
++ WriteReg(state, 0xdf, u8Value);
++
++ *ucblocks = ReadReg(state, 0xd5);
++ *ucblocks = (*ucblocks << 8) | ReadReg(state, 0xd4);
++
++ u8Value &= 0xfe; /* Clear */
++ WriteReg(state, 0xdf, u8Value);
++ u8Value &= 0xfc; /* Update */
++ u8Value |= 0x01;
++ WriteReg(state, 0xdf, u8Value);
++
++ return 0;
++}
++
++static int m88dc2800_sleep(struct dvb_frontend *fe)
++{
++ struct m88dc2800_state *state = fe->demodulator_priv;
++
++ mt_fe_tn_sleep_tc2800(state);
++ state->freq = 0;
++
++ return 0;
++}
++
++static void m88dc2800_release(struct dvb_frontend *fe)
++{
++ struct m88dc2800_state *state = fe->demodulator_priv;
++ kfree(state);
++}
++
++static struct dvb_frontend_ops m88dc2800_ops;
++
++struct dvb_frontend *m88dc2800_attach(const struct m88dc2800_config
++ *config, struct i2c_adapter *i2c)
++{
++ struct m88dc2800_state *state = NULL;
++
++ /* allocate memory for the internal state */
++ state = kzalloc(sizeof(struct m88dc2800_state), GFP_KERNEL);
++ if (state == NULL)
++ goto error;
++
++ /* setup the state */
++ state->config = config;
++ state->i2c = i2c;
++ state->xtal = 28800;
++
++ WriteReg(state, 0x80, 0x01);
++ M88DC2000RegInitial_TC2800(state);
++ M88DC2000SetTsType(state, state->config->ts_mode);
++ mt_fe_tn_init_tc2800(state);
++
++ /* create dvb_frontend */
++ memcpy(&state->frontend.ops, &m88dc2800_ops,
++ sizeof(struct dvb_frontend_ops));
++ state->frontend.demodulator_priv = state;
++ return &state->frontend;
++
++ error:
++ kfree(state);
++ return NULL;
++}
++
++EXPORT_SYMBOL(m88dc2800_attach);
++
++static struct dvb_frontend_ops m88dc2800_ops = {
++ .delsys = {SYS_DVBC_ANNEX_A, SYS_DVBC_ANNEX_C},
++ .info = {
++ .name = "Montage M88DC2800 DVB-C",
++ .frequency_stepsize = 62500,
++ .frequency_min = 48000000,
++ .frequency_max = 870000000,
++ .symbol_rate_min = 870000,
++ .symbol_rate_max = 9000000,
++ .caps = FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
++ FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_FEC_AUTO
++ },
++ .release = m88dc2800_release,
++ .init = m88dc2800_init,
++ .sleep = m88dc2800_sleep,
++ .set_frontend = m88dc2800_set_parameters,
++ .read_status = m88dc2800_read_status,
++ .read_ber = m88dc2800_read_ber,
++ .read_signal_strength = m88dc2800_read_signal_strength,
++ .read_snr = m88dc2800_read_snr,
++ .read_ucblocks = m88dc2800_read_ucblocks,
++};
++
++MODULE_DESCRIPTION("Montage DVB-C demodulator driver");
++MODULE_AUTHOR("Max Nibble <nibble.max@gmail.com>");
++MODULE_LICENSE("GPL");
++MODULE_VERSION("1.00");
+diff -urN a/drivers/media/dvb-frontends/m88dc2800.h b/drivers/media/dvb-frontends/m88dc2800.h
+--- a/drivers/media/dvb-frontends/m88dc2800.h 1970-01-01 08:00:00.000000000 +0800
++++ b/drivers/media/dvb-frontends/m88dc2800.h 2013-01-26 14:57:32.000000000 +0800
+@@ -0,0 +1,43 @@
++/*
++ M88DC2800/M88TC2800 - DVB-C demodulator and tuner from Montage
++
++ Copyright (C) 2012 Max Nibble <nibble.max@gmail.com>
++ Copyright (C) 2011 Montage Technology - www.montage-tech.com
++
++ This program is free software; you can redistribute it and/or modify
++ it under the terms of the GNU General Public License as published by
++ the Free Software Foundation; either version 2 of the License, or
++ (at your option) any later version.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ GNU General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; if not, write to the Free Software
++ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++*/
++
++#ifndef M88DC2800_H
++#define M88DC2800_H
++
++#include <linux/dvb/frontend.h>
++
++struct m88dc2800_config {
++ u8 demod_address;
++ u8 ts_mode;
++};
++
++#if defined(CONFIG_DVB_M88DC2800) || (defined(CONFIG_DVB_M88DC2800_MODULE) && defined(MODULE))
++extern struct dvb_frontend* m88dc2800_attach(const struct m88dc2800_config* config,
++ struct i2c_adapter* i2c);
++#else
++static inline struct dvb_frontend* m88dc2800_attach(const struct m88dc2800_config* config,
++ struct i2c_adapter* i2c)
++{
++ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
++ return NULL;
++}
++#endif /* CONFIG_DVB_M88DC2800 */
++#endif /* M88DC2800_H */
+diff -urN a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c
+--- a/drivers/media/dvb-frontends/m88ds3103.c 1970-01-01 08:00:00.000000000 +0800
++++ b/drivers/media/dvb-frontends/m88ds3103.c 2013-01-30 12:33:47.000000000 +0800
+@@ -0,0 +1,1710 @@
++/*
++ Montage Technology M88DS3103/M88TS2022 - DVBS/S2 Satellite demod/tuner driver
++
++ Copyright (C) 2011 Max nibble<nibble.max@gmail.com>
++ Copyright (C) 2010 Montage Technology<www.montage-tech.com>
++ Copyright (C) 2009 Konstantin Dimitrov.
++
++ This program is free software; you can redistribute it and/or modify
++ it under the terms of the GNU General Public License as published by
++ the Free Software Foundation; either version 2 of the License, or
++ (at your option) any later version.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ GNU General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; if not,&