From 03f66a9e0b843ace99e730f69ebd0065dd2fbaa8 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Wed, 17 Oct 2007 23:30:14 +0200 Subject: [PATCH] --- yaml --- r: 71655 b: refs/heads/master c: fc333b2df388d6e8791b3ee59c0679e4a131555a h: refs/heads/master i: 71653: f2c6cb20a7623ecf2e86c3cbc93091e8d00e83aa 71651: 953948a57fefb92a90e433399d9189ccc3019c69 71647: df8799facd02f2135bce3e409d545362ffe0064b v: v3 --- [refs] | 2 +- trunk/Documentation/DocBook/kernel-api.tmpl | 2 +- trunk/Documentation/IPMI.txt | 25 +- .../Documentation/accounting/cgroupstats.txt | 27 - trunk/Documentation/atomic_ops.txt | 14 - trunk/Documentation/cachetlb.txt | 27 +- trunk/Documentation/cgroups.txt | 545 -- trunk/Documentation/cpu-hotplug.txt | 4 +- trunk/Documentation/cpusets.txt | 226 +- .../feature-removal-schedule.txt | 42 +- .../Documentation/input/input-programming.txt | 15 +- trunk/Documentation/kdump/kdump.txt | 26 - trunk/Documentation/kernel-parameters.txt | 17 - trunk/Documentation/markers.txt | 81 - trunk/Documentation/memory-barriers.txt | 14 +- trunk/Documentation/mips/00-INDEX | 2 + trunk/Documentation/mips/time.README | 173 + trunk/Documentation/parport-lowlevel.txt | 29 +- .../power/basic-pm-debugging.txt | 4 +- .../Documentation/power/freezing-of-tasks.txt | 44 +- trunk/Documentation/power/interface.txt | 2 +- trunk/Documentation/sound/oss/es1371 | 64 + trunk/Documentation/thinkpad-acpi.txt | 25 +- trunk/MAINTAINERS | 9 +- trunk/Makefile | 29 +- trunk/arch/alpha/Kconfig | 2 +- trunk/arch/alpha/kernel/semaphore.c | 16 +- trunk/arch/alpha/kernel/traps.c | 6 +- trunk/arch/alpha/lib/fls.c | 2 +- trunk/arch/alpha/mm/fault.c | 4 +- trunk/arch/alpha/oprofile/Kconfig | 23 + trunk/arch/arm/Kconfig | 2 +- trunk/arch/arm/common/sharpsl_pm.c | 9 +- trunk/arch/arm/kernel/process.c | 2 +- trunk/arch/arm/kernel/ptrace.c | 8 +- trunk/arch/arm/kernel/traps.c | 10 +- trunk/arch/arm/mach-at91/pm.c | 7 +- trunk/arch/arm/mach-omap1/pm.c | 29 +- trunk/arch/arm/mach-omap2/pm.c | 35 +- trunk/arch/arm/mach-pnx4008/pm.c | 6 +- trunk/arch/arm/mach-pxa/pm.c | 4 +- trunk/arch/arm/mach-pxa/pxa25x.c | 4 +- trunk/arch/arm/mach-pxa/pxa27x.c | 2 +- trunk/arch/arm/mach-sa1100/pm.c | 6 +- trunk/arch/arm/mm/alignment.c | 2 +- trunk/arch/arm/mm/fault.c | 2 +- trunk/arch/arm/nwfpe/fpopcode.h | 6 +- trunk/arch/arm/oprofile/Kconfig | 42 + trunk/arch/arm/plat-s3c24xx/pm.c | 6 +- trunk/arch/avr32/kernel/traps.c | 2 +- trunk/arch/avr32/mm/fault.c | 6 +- trunk/arch/blackfin/Kconfig | 2 +- trunk/arch/blackfin/mach-common/pm.c | 59 +- trunk/arch/blackfin/oprofile/Kconfig | 29 + trunk/arch/cris/Kconfig | 2 - trunk/arch/frv/Kconfig | 2 - trunk/arch/frv/kernel/irq-mb93091.c | 2 +- trunk/arch/frv/kernel/irq-mb93093.c | 2 +- trunk/arch/frv/kernel/irq-mb93493.c | 2 +- trunk/arch/frv/kernel/irq.c | 2 +- trunk/arch/h8300/Kconfig | 2 - trunk/arch/i386/Kconfig | 27 +- trunk/arch/ia64/Kconfig | 15 +- trunk/arch/ia64/configs/sn2_defconfig | 1 - trunk/arch/ia64/ia32/sys_ia32.c | 6 +- trunk/arch/ia64/kernel/efi.c | 4 +- trunk/arch/ia64/kernel/perfmon.c | 161 +- trunk/arch/ia64/kernel/perfmon_default_smpl.c | 8 +- trunk/arch/ia64/kernel/process.c | 3 +- trunk/arch/ia64/kernel/setup.c | 88 +- trunk/arch/ia64/kernel/signal.c | 4 +- trunk/arch/ia64/kernel/time.c | 5 - trunk/arch/ia64/kernel/traps.c | 6 +- trunk/arch/ia64/kernel/unaligned.c | 5 +- trunk/arch/ia64/mm/fault.c | 2 +- trunk/arch/ia64/mm/init.c | 2 +- trunk/arch/ia64/oprofile/Kconfig | 20 + trunk/arch/ia64/sn/kernel/xpnet.c | 13 +- trunk/arch/m32r/Kconfig | 2 +- trunk/arch/m32r/kernel/traps.c | 2 +- trunk/arch/m32r/mm/fault.c | 2 +- trunk/arch/m32r/oprofile/Kconfig | 23 + trunk/arch/m68k/Kconfig | 2 - trunk/arch/m68k/kernel/traps.c | 4 +- trunk/arch/m68k/mm/fault.c | 2 +- trunk/arch/m68knommu/Kconfig | 2 - trunk/arch/mips/Kconfig | 26 +- trunk/arch/mips/au1000/Kconfig | 1 - trunk/arch/mips/au1000/pb1200/irqmap.c | 2 +- trunk/arch/mips/basler/excite/excite_irq.c | 2 +- trunk/arch/mips/bcm47xx/time.c | 7 + trunk/arch/mips/configs/ip27_defconfig | 1 - trunk/arch/mips/configs/mipssim_defconfig | 532 +- .../arch/mips/configs/sb1250-swarm_defconfig | 1 - trunk/arch/mips/emma2rh/markeins/setup.c | 6 + trunk/arch/mips/jazz/irq.c | 6 +- trunk/arch/mips/jazz/setup.c | 8 +- trunk/arch/mips/jmr3927/rbhma3100/setup.c | 66 +- trunk/arch/mips/kernel/Makefile | 2 - trunk/arch/mips/kernel/cevt-r4k.c | 273 - trunk/arch/mips/kernel/head.S | 16 +- trunk/arch/mips/kernel/irixelf.c | 4 +- trunk/arch/mips/kernel/irixsig.c | 2 +- trunk/arch/mips/kernel/sysirix.c | 4 +- trunk/arch/mips/kernel/time.c | 348 +- trunk/arch/mips/kernel/traps.c | 13 +- trunk/arch/mips/lemote/lm2e/setup.c | 5 + trunk/arch/mips/mm/fault.c | 2 +- trunk/arch/mips/oprofile/Kconfig | 23 + trunk/arch/mips/pmc-sierra/Kconfig | 2 - trunk/arch/mips/pmc-sierra/msp71xx/msp_time.c | 3 + trunk/arch/mips/pmc-sierra/yosemite/setup.c | 5 + trunk/arch/mips/sgi-ip27/ip27-irq.c | 5 +- trunk/arch/mips/sgi-ip27/ip27-timer.c | 155 +- trunk/arch/mips/sgi-ip32/ip32-setup.c | 6 + trunk/arch/mips/sibyte/bcm1480/smp.c | 5 +- trunk/arch/mips/sibyte/bcm1480/time.c | 74 +- trunk/arch/mips/sibyte/sb1250/irq.c | 36 +- trunk/arch/mips/sibyte/sb1250/smp.c | 5 +- trunk/arch/mips/sibyte/sb1250/time.c | 104 +- trunk/arch/mips/sibyte/swarm/setup.c | 25 + trunk/arch/mips/sni/time.c | 18 + trunk/arch/mips/tx4927/common/tx4927_setup.c | 16 + .../toshiba_rbtx4927/toshiba_rbtx4927_setup.c | 10 + trunk/arch/mips/tx4938/common/setup.c | 7 +- trunk/arch/mips/vr41xx/Kconfig | 6 - trunk/arch/mips/vr41xx/common/init.c | 5 + trunk/arch/parisc/Kconfig | 2 +- trunk/arch/parisc/kernel/signal.c | 2 +- trunk/arch/parisc/kernel/traps.c | 10 +- trunk/arch/parisc/kernel/unaligned.c | 2 +- trunk/arch/parisc/mm/fault.c | 2 +- trunk/arch/parisc/oprofile/Kconfig | 23 + trunk/arch/powerpc/Kconfig | 15 +- trunk/arch/powerpc/configs/cell_defconfig | 1 - trunk/arch/powerpc/configs/pmac32_defconfig | 1 + trunk/arch/powerpc/configs/ppc64_defconfig | 1 - trunk/arch/powerpc/configs/pseries_defconfig | 1 - trunk/arch/powerpc/kernel/asm-offsets.c | 1 - trunk/arch/powerpc/kernel/machine_kexec.c | 54 +- trunk/arch/powerpc/kernel/process.c | 2 +- trunk/arch/powerpc/kernel/time.c | 32 +- trunk/arch/powerpc/kernel/traps.c | 4 +- trunk/arch/powerpc/mm/fault.c | 2 +- trunk/arch/powerpc/oprofile/Kconfig | 24 + .../arch/powerpc/platforms/52xx/lite5200_pm.c | 34 +- .../arch/powerpc/platforms/52xx/mpc52xx_pm.c | 15 +- trunk/arch/powerpc/platforms/maple/setup.c | 2 +- trunk/arch/powerpc/platforms/pseries/ras.c | 2 +- trunk/arch/ppc/Kconfig | 2 +- trunk/arch/ppc/kernel/traps.c | 2 +- trunk/arch/ppc/mm/fault.c | 2 +- trunk/arch/ppc/platforms/chestnut.c | 1 + trunk/arch/s390/Kconfig | 16 +- trunk/arch/s390/kernel/process.c | 2 +- trunk/arch/s390/lib/uaccess_pt.c | 2 +- trunk/arch/s390/mm/fault.c | 2 +- trunk/arch/s390/oprofile/Kconfig | 22 + trunk/arch/sh/Kconfig | 2 +- trunk/arch/sh/boards/hp6xx/pm.c | 6 +- trunk/arch/sh/kernel/machine_kexec.c | 21 + trunk/arch/sh/kernel/process.c | 2 +- trunk/arch/sh/kernel/setup.c | 38 +- trunk/arch/sh/kernel/signal.c | 4 +- trunk/arch/sh/kernel/traps.c | 7 +- trunk/arch/sh/mm/fault.c | 2 +- trunk/arch/sh/oprofile/Kconfig | 23 + trunk/arch/sh64/Kconfig | 2 +- trunk/arch/sh64/kernel/traps.c | 4 +- trunk/arch/sh64/mm/fault.c | 10 +- trunk/arch/sh64/oprofile/Kconfig | 23 + trunk/arch/sparc/Kconfig | 6 +- trunk/arch/sparc/kernel/of_device.c | 20 + trunk/arch/sparc/kernel/ptrace.c | 4 +- trunk/arch/sparc/kernel/sys_sparc.c | 2 +- trunk/arch/sparc/kernel/sys_sunos.c | 2 +- trunk/arch/sparc/kernel/traps.c | 4 +- trunk/arch/sparc/oprofile/Kconfig | 17 + trunk/arch/sparc64/Kconfig | 15 +- trunk/arch/sparc64/kernel/irq.c | 8 +- trunk/arch/sparc64/kernel/of_device.c | 20 + trunk/arch/sparc64/kernel/pci_common.c | 7 - trunk/arch/sparc64/kernel/sys_sunos32.c | 2 +- trunk/arch/sparc64/kernel/traps.c | 2 +- trunk/arch/sparc64/lib/atomic.S | 38 +- trunk/arch/sparc64/lib/bitops.S | 30 +- trunk/arch/sparc64/oprofile/Kconfig | 17 + trunk/arch/sparc64/solaris/misc.c | 4 +- trunk/arch/um/Kconfig | 2 - trunk/arch/um/drivers/slip_kern.c | 4 +- trunk/arch/um/drivers/slirp_kern.c | 4 +- trunk/arch/um/kernel/trap.c | 2 +- trunk/arch/um/sys-x86_64/sysrq.c | 4 +- trunk/arch/v850/Kconfig | 2 - trunk/arch/x86/ia32/ia32_binfmt.c | 1 + trunk/arch/x86/kernel/acpi/wakeup_32.S | 12 +- trunk/arch/x86/kernel/acpi/wakeup_64.S | 32 + trunk/arch/x86/kernel/cpu/intel_cacheinfo.c | 66 +- .../arch/x86/kernel/cpu/mcheck/therm_throt.c | 10 +- trunk/arch/x86/kernel/crash_dump_32.c | 1 - trunk/arch/x86/kernel/e820_32.c | 3 +- trunk/arch/x86/kernel/e820_64.c | 3 +- trunk/arch/x86/kernel/machine_kexec_32.c | 22 + trunk/arch/x86/kernel/machine_kexec_64.c | 27 + trunk/arch/x86/kernel/mce_64.c | 39 +- trunk/arch/x86/kernel/msr.c | 35 +- trunk/arch/x86/kernel/process_32.c | 2 +- trunk/arch/x86/kernel/setup_32.c | 49 +- trunk/arch/x86/kernel/setup_64.c | 39 +- trunk/arch/x86/kernel/signal_32.c | 4 +- trunk/arch/x86/kernel/suspend_64.c | 101 +- trunk/arch/x86/kernel/suspend_asm_64.S | 49 +- trunk/arch/x86/kernel/traps_32.c | 4 +- trunk/arch/x86/kernel/vsyscall_64.c | 23 +- trunk/arch/x86/lib/usercopy_32.c | 2 +- trunk/arch/x86/mm/fault_32.c | 6 +- trunk/arch/x86/mm/fault_64.c | 2 +- trunk/arch/x86/mm/pageattr_64.c | 9 +- trunk/arch/x86_64/Kconfig | 22 +- trunk/arch/xtensa/Kconfig | 2 - trunk/arch/xtensa/kernel/traps.c | 6 +- trunk/arch/xtensa/mm/fault.c | 2 +- trunk/block/ll_rw_blk.c | 4 +- trunk/drivers/Kconfig | 2 - trunk/drivers/Makefile | 3 +- trunk/drivers/acpi/Kconfig | 14 +- trunk/drivers/acpi/Makefile | 1 - trunk/drivers/acpi/ac.c | 33 +- trunk/drivers/acpi/battery.c | 1038 ++- trunk/drivers/acpi/bus.c | 23 +- trunk/drivers/acpi/button.c | 6 +- trunk/drivers/acpi/ec.c | 93 +- trunk/drivers/acpi/events/evevent.c | 6 +- trunk/drivers/acpi/hardware/hwregs.c | 89 +- trunk/drivers/acpi/hardware/hwsleep.c | 40 +- trunk/drivers/acpi/osl.c | 8 + trunk/drivers/acpi/processor_core.c | 22 +- trunk/drivers/acpi/processor_idle.c | 488 +- trunk/drivers/acpi/sbs.c | 1869 ++-- trunk/drivers/acpi/sbshc.c | 309 - trunk/drivers/acpi/sbshc.h | 27 - trunk/drivers/acpi/sleep/main.c | 43 +- trunk/drivers/acpi/sleep/sleep.h | 1 + trunk/drivers/acpi/sleep/wakeup.c | 117 +- trunk/drivers/acpi/tables/tbutils.c | 2 +- trunk/drivers/acpi/thermal.c | 28 +- trunk/drivers/acpi/video.c | 30 +- trunk/drivers/ata/Kconfig | 16 +- trunk/drivers/ata/Makefile | 1 - trunk/drivers/ata/libata-sff.c | 4 +- trunk/drivers/ata/pata_acpi.c | 2 - trunk/drivers/ata/pata_bf54x.c | 77 +- trunk/drivers/ata/pdc_adma.c | 9 +- trunk/drivers/ata/sata_fsl.c | 1490 ---- trunk/drivers/ata/sata_mv.c | 26 +- trunk/drivers/ata/sata_sil24.c | 11 +- trunk/drivers/base/dmapool.c | 2 +- trunk/drivers/base/power/trace.c | 2 +- trunk/drivers/base/topology.c | 11 +- trunk/drivers/block/nbd.c | 2 +- trunk/drivers/block/xsysace.c | 4 +- trunk/drivers/cdrom/cdrom.c | 48 +- trunk/drivers/char/Kconfig | 19 + trunk/drivers/char/apm-emulation.c | 2 +- trunk/drivers/char/cyclades.c | 767 +- trunk/drivers/char/drm/drm_bufs.c | 2 +- trunk/drivers/char/drm/drm_drv.c | 2 +- trunk/drivers/char/drm/drm_fops.c | 7 +- trunk/drivers/char/drm/drm_lock.c | 6 +- trunk/drivers/char/drm/drm_os_linux.h | 2 +- trunk/drivers/char/drm/i810_dma.c | 2 +- trunk/drivers/char/drm/i830_dma.c | 2 +- trunk/drivers/char/esp.c | 2 +- trunk/drivers/char/ipmi/ipmi_msghandler.c | 25 +- trunk/drivers/char/ipmi/ipmi_si_intf.c | 29 +- trunk/drivers/char/ipmi/ipmi_watchdog.c | 268 +- trunk/drivers/char/isicom.c | 10 +- trunk/drivers/char/keyboard.c | 48 +- trunk/drivers/char/moxa.c | 148 +- trunk/drivers/char/mxser.c | 25 +- trunk/drivers/char/mxser_new.c | 122 +- trunk/drivers/char/pty.c | 24 +- trunk/drivers/char/random.c | 2 +- trunk/drivers/char/rocket.c | 91 +- trunk/drivers/char/rocket_int.h | 7 +- trunk/drivers/char/sonypi.c | 8 +- trunk/drivers/char/sx.c | 2 +- trunk/drivers/char/sysrq.c | 2 +- trunk/drivers/char/tty_io.c | 17 +- trunk/drivers/char/tty_ioctl.c | 11 +- trunk/drivers/char/vt.c | 51 +- trunk/drivers/{ => char}/watchdog/Kconfig | 0 trunk/drivers/{ => char}/watchdog/Makefile | 0 .../drivers/{ => char}/watchdog/acquirewdt.c | 0 .../{ => char}/watchdog/advantechwdt.c | 0 .../{ => char}/watchdog/alim1535_wdt.c | 0 .../{ => char}/watchdog/alim7101_wdt.c | 0 .../{ => char}/watchdog/at32ap700x_wdt.c | 0 .../{ => char}/watchdog/at91rm9200_wdt.c | 2 +- trunk/drivers/{ => char}/watchdog/bfin_wdt.c | 0 trunk/drivers/{ => char}/watchdog/booke_wdt.c | 0 trunk/drivers/{ => char}/watchdog/cpu5wdt.c | 0 .../drivers/{ => char}/watchdog/davinci_wdt.c | 0 .../drivers/{ => char}/watchdog/ep93xx_wdt.c | 0 .../drivers/{ => char}/watchdog/eurotechwdt.c | 0 trunk/drivers/{ => char}/watchdog/i6300esb.c | 0 .../{ => char}/watchdog/iTCO_vendor_support.c | 0 trunk/drivers/{ => char}/watchdog/iTCO_wdt.c | 0 trunk/drivers/{ => char}/watchdog/ib700wdt.c | 0 trunk/drivers/{ => char}/watchdog/ibmasr.c | 0 trunk/drivers/{ => char}/watchdog/indydog.c | 0 trunk/drivers/{ => char}/watchdog/iop_wdt.c | 0 .../drivers/{ => char}/watchdog/ixp2000_wdt.c | 0 .../drivers/{ => char}/watchdog/ixp4xx_wdt.c | 0 .../drivers/{ => char}/watchdog/ks8695_wdt.c | 2 +- trunk/drivers/{ => char}/watchdog/machzwd.c | 0 trunk/drivers/{ => char}/watchdog/mixcomwd.c | 0 .../drivers/{ => char}/watchdog/mpc5200_wdt.c | 0 .../drivers/{ => char}/watchdog/mpc83xx_wdt.c | 0 .../drivers/{ => char}/watchdog/mpc8xx_wdt.c | 0 .../drivers/{ => char}/watchdog/mpcore_wdt.c | 0 trunk/drivers/{ => char}/watchdog/mtx-1_wdt.c | 0 .../drivers/{ => char}/watchdog/mv64x60_wdt.c | 0 trunk/drivers/{ => char}/watchdog/omap_wdt.c | 2 +- trunk/drivers/{ => char}/watchdog/omap_wdt.h | 0 .../drivers/{ => char}/watchdog/pc87413_wdt.c | 0 trunk/drivers/{ => char}/watchdog/pcwd.c | 0 trunk/drivers/{ => char}/watchdog/pcwd_pci.c | 0 trunk/drivers/{ => char}/watchdog/pcwd_usb.c | 0 .../drivers/{ => char}/watchdog/pnx4008_wdt.c | 0 trunk/drivers/{ => char}/watchdog/rm9k_wdt.c | 0 .../drivers/{ => char}/watchdog/s3c2410_wdt.c | 0 .../drivers/{ => char}/watchdog/sa1100_wdt.c | 2 +- .../drivers/{ => char}/watchdog/sbc60xxwdt.c | 0 trunk/drivers/{ => char}/watchdog/sbc8360.c | 0 .../drivers/{ => char}/watchdog/sbc_epx_c3.c | 0 trunk/drivers/{ => char}/watchdog/sc1200wdt.c | 0 trunk/drivers/{ => char}/watchdog/sc520_wdt.c | 0 .../drivers/{ => char}/watchdog/scx200_wdt.c | 0 trunk/drivers/{ => char}/watchdog/shwdt.c | 0 .../{ => char}/watchdog/smsc37b787_wdt.c | 0 trunk/drivers/{ => char}/watchdog/softdog.c | 0 .../{ => char}/watchdog/w83627hf_wdt.c | 0 .../{ => char}/watchdog/w83697hf_wdt.c | 0 .../drivers/{ => char}/watchdog/w83877f_wdt.c | 0 .../drivers/{ => char}/watchdog/w83977f_wdt.c | 0 .../{ => char}/watchdog/wafer5823wdt.c | 0 trunk/drivers/{ => char}/watchdog/wd501p.h | 0 trunk/drivers/{ => char}/watchdog/wdrtas.c | 0 trunk/drivers/{ => char}/watchdog/wdt.c | 0 trunk/drivers/{ => char}/watchdog/wdt285.c | 0 trunk/drivers/{ => char}/watchdog/wdt977.c | 0 trunk/drivers/{ => char}/watchdog/wdt_pci.c | 0 trunk/drivers/cpuidle/Kconfig | 20 - trunk/drivers/cpuidle/Makefile | 5 - trunk/drivers/cpuidle/cpuidle.c | 295 - trunk/drivers/cpuidle/cpuidle.h | 33 - trunk/drivers/cpuidle/driver.c | 56 - trunk/drivers/cpuidle/governor.c | 141 - trunk/drivers/cpuidle/governors/Makefile | 6 - trunk/drivers/cpuidle/governors/ladder.c | 166 - trunk/drivers/cpuidle/governors/menu.c | 137 - trunk/drivers/cpuidle/sysfs.c | 361 - trunk/drivers/dma/ioat.c | 37 +- trunk/drivers/dma/ioat_dca.c | 12 +- trunk/drivers/dma/ioat_dma.c | 239 +- trunk/drivers/dma/ioatdma.h | 8 +- trunk/drivers/edac/edac_core.h | 2 + trunk/drivers/edac/pasemi_edac.c | 1 - trunk/drivers/firmware/dcdbas.h | 1 + trunk/drivers/hid/hidraw.c | 4 +- trunk/drivers/hid/usbhid/usbkbd.c | 7 +- trunk/drivers/hid/usbhid/usbmouse.c | 12 +- trunk/drivers/hwmon/adm1026.c | 2 +- trunk/drivers/hwmon/applesmc.c | 2 +- trunk/drivers/hwmon/hdaps.c | 2 +- trunk/drivers/hwmon/lm63.c | 2 +- trunk/drivers/hwmon/vt1211.c | 2 +- trunk/drivers/hwmon/w83791d.c | 2 +- trunk/drivers/hwmon/w83792d.c | 4 +- trunk/drivers/i2c/busses/i2c-pmcmsp.c | 8 +- trunk/drivers/i2c/busses/i2c-pnx.c | 2 +- trunk/drivers/i2c/busses/i2c-pxa.c | 54 +- trunk/drivers/i2c/chips/menelaus.c | 2 +- trunk/drivers/ide/arm/icside.c | 1 + trunk/drivers/ide/cris/ide-cris.c | 1 - trunk/drivers/ide/ide-disk.c | 8 +- trunk/drivers/ide/ide-dma.c | 12 +- trunk/drivers/ide/ide-io.c | 5 +- trunk/drivers/ide/ide-probe.c | 3 +- trunk/drivers/ide/ide.c | 4 + trunk/drivers/ide/mips/au1xxx-ide.c | 3 + trunk/drivers/ide/pci/aec62xx.c | 97 +- trunk/drivers/ide/pci/alim15x3.c | 30 +- trunk/drivers/ide/pci/amd74xx.c | 31 +- trunk/drivers/ide/pci/atiixp.c | 21 +- trunk/drivers/ide/pci/cmd64x.c | 85 +- trunk/drivers/ide/pci/cs5520.c | 31 +- trunk/drivers/ide/pci/cs5530.c | 18 +- trunk/drivers/ide/pci/cs5535.c | 15 +- trunk/drivers/ide/pci/cy82c693.c | 18 +- trunk/drivers/ide/pci/generic.c | 148 +- trunk/drivers/ide/pci/hpt34x.c | 56 +- trunk/drivers/ide/pci/hpt366.c | 376 +- trunk/drivers/ide/pci/it8213.c | 16 +- trunk/drivers/ide/pci/it821x.c | 22 +- trunk/drivers/ide/pci/jmicron.c | 12 +- trunk/drivers/ide/pci/ns87415.c | 6 +- trunk/drivers/ide/pci/opti621.c | 26 +- trunk/drivers/ide/pci/pdc202xx_new.c | 201 +- trunk/drivers/ide/pci/pdc202xx_old.c | 135 +- trunk/drivers/ide/pci/piix.c | 167 +- trunk/drivers/ide/pci/rz1000.c | 3 +- trunk/drivers/ide/pci/sc1200.c | 19 +- trunk/drivers/ide/pci/scc_pata.c | 26 +- trunk/drivers/ide/pci/serverworks.c | 86 +- trunk/drivers/ide/pci/sgiioc4.c | 11 +- trunk/drivers/ide/pci/siimage.c | 35 +- trunk/drivers/ide/pci/sis5513.c | 14 +- trunk/drivers/ide/pci/sl82c105.c | 12 +- trunk/drivers/ide/pci/slc90e66.c | 17 +- trunk/drivers/ide/pci/tc86c001.c | 26 +- trunk/drivers/ide/pci/triflex.c | 12 +- trunk/drivers/ide/pci/trm290.c | 9 +- trunk/drivers/ide/pci/via82cxxx.c | 28 +- trunk/drivers/ide/ppc/pmac.c | 1 + trunk/drivers/ide/setup-pci.c | 68 +- trunk/drivers/infiniband/core/cma.c | 5 +- trunk/drivers/infiniband/hw/ehca/ehca_main.c | 4 +- trunk/drivers/input/evdev.c | 12 +- trunk/drivers/input/gameport/gameport.c | 3 +- trunk/drivers/input/input.c | 10 +- trunk/drivers/input/joydev.c | 16 +- trunk/drivers/input/joystick/a3d.c | 28 +- trunk/drivers/input/joystick/adi.c | 2 +- trunk/drivers/input/joystick/amijoy.c | 7 +- trunk/drivers/input/joystick/analog.c | 2 +- trunk/drivers/input/joystick/cobra.c | 2 +- trunk/drivers/input/joystick/db9.c | 2 +- trunk/drivers/input/joystick/gamecon.c | 4 +- trunk/drivers/input/joystick/gf2k.c | 2 +- trunk/drivers/input/joystick/grip.c | 2 +- trunk/drivers/input/joystick/grip_mp.c | 2 +- trunk/drivers/input/joystick/guillemot.c | 2 +- .../input/joystick/iforce/iforce-main.c | 3 +- trunk/drivers/input/joystick/iforce/iforce.h | 4 +- trunk/drivers/input/joystick/interact.c | 2 +- trunk/drivers/input/joystick/magellan.c | 2 +- trunk/drivers/input/joystick/sidewinder.c | 2 +- trunk/drivers/input/joystick/spaceball.c | 17 +- trunk/drivers/input/joystick/spaceorb.c | 2 +- trunk/drivers/input/joystick/stinger.c | 9 +- trunk/drivers/input/joystick/tmdc.c | 2 +- trunk/drivers/input/joystick/turbografx.c | 2 +- trunk/drivers/input/joystick/twidjoy.c | 2 +- trunk/drivers/input/joystick/warrior.c | 8 +- trunk/drivers/input/joystick/xpad.c | 2 +- trunk/drivers/input/keyboard/aaed2000_kbd.c | 2 +- trunk/drivers/input/keyboard/amikbd.c | 2 +- trunk/drivers/input/keyboard/atakbd.c | 2 +- trunk/drivers/input/keyboard/atkbd.c | 21 +- trunk/drivers/input/keyboard/corgikbd.c | 3 +- trunk/drivers/input/keyboard/gpio_keys.c | 2 +- trunk/drivers/input/keyboard/hil_kbd.c | 5 +- trunk/drivers/input/keyboard/hilkbd.c | 5 +- trunk/drivers/input/keyboard/locomokbd.c | 2 +- trunk/drivers/input/keyboard/newtonkbd.c | 2 +- .../drivers/input/keyboard/pxa27x_keyboard.c | 5 +- trunk/drivers/input/keyboard/spitzkbd.c | 3 +- trunk/drivers/input/keyboard/stowaway.c | 2 +- trunk/drivers/input/keyboard/sunkbd.c | 8 +- trunk/drivers/input/keyboard/xtkbd.c | 2 +- trunk/drivers/input/misc/ati_remote.c | 8 +- trunk/drivers/input/misc/ati_remote2.c | 7 +- trunk/drivers/input/misc/atlas_btns.c | 2 +- trunk/drivers/input/misc/cobalt_btns.c | 2 +- trunk/drivers/input/misc/ixp4xx-beeper.c | 4 +- trunk/drivers/input/misc/keyspan_remote.c | 2 +- trunk/drivers/input/misc/m68kspkr.c | 4 +- trunk/drivers/input/misc/pcspkr.c | 4 +- trunk/drivers/input/misc/powermate.c | 9 +- trunk/drivers/input/misc/sparcspkr.c | 4 +- trunk/drivers/input/misc/yealink.c | 2 +- trunk/drivers/input/mouse/alps.c | 26 +- trunk/drivers/input/mouse/amimouse.c | 7 +- trunk/drivers/input/mouse/atarimouse.c | 7 +- trunk/drivers/input/mouse/hil_ptr.c | 6 +- trunk/drivers/input/mouse/inport.c | 7 +- trunk/drivers/input/mouse/lifebook.c | 11 +- trunk/drivers/input/mouse/logibm.c | 7 +- trunk/drivers/input/mouse/pc110pad.c | 6 +- trunk/drivers/input/mouse/psmouse-base.c | 7 +- trunk/drivers/input/mouse/rpcmouse.c | 7 +- trunk/drivers/input/mouse/sermouse.c | 7 +- trunk/drivers/input/mouse/touchkit_ps2.c | 2 +- trunk/drivers/input/mousedev.c | 26 +- trunk/drivers/input/serio/serio.c | 3 +- trunk/drivers/input/tablet/acecad.c | 12 +- trunk/drivers/input/tablet/gtco.c | 6 +- trunk/drivers/input/tablet/kbtab.c | 11 +- trunk/drivers/input/tablet/wacom_sys.c | 58 +- trunk/drivers/input/touchscreen/ads7846.c | 4 +- trunk/drivers/input/touchscreen/corgi_ts.c | 4 +- trunk/drivers/input/touchscreen/elo.c | 4 +- trunk/drivers/input/touchscreen/fujitsu_ts.c | 4 +- trunk/drivers/input/touchscreen/gunze.c | 4 +- .../input/touchscreen/h3600_ts_input.c | 5 +- .../input/touchscreen/hp680_ts_input.c | 4 +- trunk/drivers/input/touchscreen/mk712.c | 4 +- trunk/drivers/input/touchscreen/mtouch.c | 4 +- trunk/drivers/input/touchscreen/penmount.c | 4 +- trunk/drivers/input/touchscreen/touchright.c | 4 +- trunk/drivers/input/touchscreen/touchwin.c | 4 +- trunk/drivers/input/touchscreen/ucb1400_ts.c | 5 +- .../input/touchscreen/usbtouchscreen.c | 4 +- trunk/drivers/isdn/gigaset/common.c | 3 +- trunk/drivers/isdn/hardware/avm/b1.c | 28 +- trunk/drivers/isdn/hardware/avm/b1dma.c | 28 +- trunk/drivers/isdn/hardware/avm/c4.c | 16 +- trunk/drivers/isdn/hardware/avm/t1isa.c | 28 +- trunk/drivers/isdn/sc/debug.h | 19 + trunk/drivers/isdn/sc/includes.h | 1 + trunk/drivers/isdn/sc/init.c | 2 +- trunk/drivers/macintosh/adbhid.c | 19 +- trunk/drivers/macintosh/mac_hid.c | 7 +- trunk/drivers/md/md.c | 2 +- trunk/drivers/media/dvb/cinergyT2/cinergyT2.c | 2 +- .../drivers/media/dvb/dvb-core/dvb_frontend.c | 3 +- .../media/dvb/dvb-usb/dvb-usb-remote.c | 2 +- trunk/drivers/media/dvb/ttpci/av7110_ir.c | 2 +- trunk/drivers/media/dvb/ttusb-dec/ttusb_dec.c | 2 +- trunk/drivers/media/video/usbvideo/konicawc.c | 4 +- .../media/video/usbvideo/quickcam_messenger.c | 4 +- trunk/drivers/media/video/v4l1-compat.c | 2 +- trunk/drivers/media/video/zoran_driver.c | 4 +- trunk/drivers/misc/Kconfig | 17 - trunk/drivers/misc/Makefile | 1 - trunk/drivers/misc/fujitsu-laptop.c | 358 - trunk/drivers/misc/ibmasm/remote.c | 8 +- trunk/drivers/misc/phantom.c | 97 +- trunk/drivers/misc/sony-laptop.c | 210 +- trunk/drivers/misc/thinkpad_acpi.c | 207 +- trunk/drivers/misc/thinkpad_acpi.h | 37 +- trunk/drivers/mtd/nand/s3c2410.c | 2 +- trunk/drivers/mtd/ubi/wl.c | 2 +- trunk/drivers/net/3c59x.c | 2 +- trunk/drivers/net/ax88796.c | 2 +- trunk/drivers/net/bnx2.c | 36 +- trunk/drivers/net/bnx2_fw2.h | 7833 ++++++++--------- trunk/drivers/net/bonding/bond_3ad.c | 32 +- trunk/drivers/net/bonding/bond_3ad.h | 12 +- trunk/drivers/net/cris/eth_v10.c | 2 +- trunk/drivers/net/cxgb3/adapter.h | 2 +- trunk/drivers/net/ehea/ehea_main.c | 8 +- trunk/drivers/net/eth16i.c | 1 + trunk/drivers/net/forcedeth.c | 27 +- trunk/drivers/net/fs_enet/fs_enet-main.c | 28 +- trunk/drivers/net/fs_enet/fs_enet.h | 1 - trunk/drivers/net/gianfar.c | 4 +- trunk/drivers/net/gianfar.h | 1 + trunk/drivers/net/hamradio/dmascc.c | 2 +- trunk/drivers/net/ibm_newemac/mal.c | 2 +- trunk/drivers/net/mac89x0.c | 2 +- trunk/drivers/net/meth.h | 3 + trunk/drivers/net/myri10ge/myri10ge.c | 3 +- trunk/drivers/net/netxen/netxen_nic_main.c | 3 + trunk/drivers/net/pcnet32.c | 58 +- trunk/drivers/net/s2io-regs.h | 632 +- trunk/drivers/net/s2io.c | 16 +- trunk/drivers/net/s2io.h | 84 +- trunk/drivers/net/sky2.c | 48 +- trunk/drivers/net/spider_net.c | 2 +- trunk/drivers/net/tulip/uli526x.c | 2 +- trunk/drivers/net/usb/mcs7830.c | 16 +- .../net/wireless/bcm43xx/bcm43xx_leds.c | 2 +- .../net/wireless/hostap/hostap_common.h | 3 + .../net/wireless/hostap/hostap_ioctl.c | 2 +- trunk/drivers/net/wireless/ipw2100.c | 29 + trunk/drivers/net/wireless/ipw2100.h | 2 + trunk/drivers/net/xen-netfront.c | 2 +- trunk/drivers/of/platform.c | 21 - trunk/drivers/parport/daisy.c | 29 + trunk/drivers/parport/procfs.c | 38 +- trunk/drivers/pcmcia/m32r_pcc.c | 2 +- trunk/drivers/pcmcia/m8xx_pcmcia.c | 2 +- trunk/drivers/power/ds2760_battery.c | 2 +- trunk/drivers/ps3/ps3av.c | 6 +- trunk/drivers/ps3/ps3stor_lib.c | 2 +- trunk/drivers/ps3/vuart.c | 2 +- trunk/drivers/rtc/rtc-pl031.c | 2 +- trunk/drivers/rtc/rtc-sa1100.c | 2 +- trunk/drivers/rtc/rtc-sysfs.c | 5 +- trunk/drivers/s390/cio/idset.c | 2 +- trunk/drivers/s390/net/claw.c | 2 +- trunk/drivers/sbus/char/vfc.h | 2 +- trunk/drivers/sbus/char/vfc_dev.c | 5 +- trunk/drivers/scsi/FlashPoint.c | 83 +- trunk/drivers/scsi/Kconfig | 2 +- trunk/drivers/scsi/ide-scsi.c | 2 +- trunk/drivers/scsi/ipr.c | 11 +- trunk/drivers/scsi/libsas/sas_discover.c | 8 +- trunk/drivers/scsi/lpfc/lpfc_sli.c | 8 +- trunk/drivers/scsi/nsp32.h | 5 + trunk/drivers/scsi/pcmcia/nsp_cs.h | 1 + trunk/drivers/scsi/qla4xxx/ql4_fw.h | 2 +- trunk/drivers/scsi/qla4xxx/ql4_iocb.c | 2 +- trunk/drivers/scsi/qla4xxx/ql4_os.c | 2 +- trunk/drivers/serial/amba-pl011.c | 26 +- trunk/drivers/serial/crisv10.c | 2 +- trunk/drivers/serial/serial_core.c | 10 +- trunk/drivers/spi/spi_bfin5xx.c | 2 +- trunk/drivers/spi/spi_imx.c | 4 +- trunk/drivers/ssb/Kconfig | 4 +- trunk/drivers/ssb/driver_mipscore.c | 3 +- trunk/drivers/usb/class/cdc-acm.c | 34 +- trunk/drivers/usb/core/devio.c | 2 +- trunk/drivers/usb/core/endpoint.c | 2 +- trunk/drivers/usb/core/hub.c | 3 +- trunk/drivers/usb/core/message.c | 4 +- trunk/drivers/usb/gadget/file_storage.c | 2 +- trunk/drivers/usb/host/ohci-s3c2410.c | 2 +- trunk/drivers/usb/misc/adutux.c | 4 +- trunk/drivers/usb/misc/iowarrior.c | 8 +- trunk/drivers/usb/misc/phidgetmotorcontrol.c | 2 +- trunk/drivers/usb/serial/ftdi_sio.c | 4 +- trunk/drivers/usb/serial/io_edgeport.c | 2 +- trunk/drivers/usb/serial/ipw.c | 18 +- trunk/drivers/usb/serial/mos7720.c | 4 +- trunk/drivers/usb/serial/oti6858.c | 2 +- trunk/drivers/usb/serial/sierra.c | 10 +- trunk/drivers/usb/storage/usb.c | 5 +- trunk/drivers/video/au1100fb.c | 2 +- trunk/drivers/video/console/newport_con.c | 6 +- trunk/drivers/video/cyber2000fb.c | 236 +- trunk/drivers/video/gxt4500.c | 2 +- trunk/drivers/video/logo/logo.c | 10 +- trunk/drivers/video/modedb.c | 4 +- trunk/drivers/video/omap/blizzard.c | 2 +- trunk/drivers/video/omap/dispc.c | 6 +- trunk/drivers/video/omap/hwa742.c | 2 +- trunk/drivers/video/omap/rfbi.c | 4 +- trunk/drivers/video/pnx4008/sdum.h | 3 + trunk/drivers/w1/masters/ds1wm.c | 2 +- trunk/drivers/xen/xenbus/xenbus_probe.c | 5 +- trunk/fs/Kconfig | 11 +- trunk/fs/aio.c | 16 +- trunk/fs/attr.c | 26 +- trunk/fs/autofs/inode.c | 2 +- trunk/fs/autofs/root.c | 6 +- trunk/fs/autofs/waitq.c | 2 +- trunk/fs/autofs4/autofs_i.h | 2 +- trunk/fs/autofs4/inode.c | 4 +- trunk/fs/autofs4/root.c | 4 +- trunk/fs/autofs4/waitq.c | 2 +- trunk/fs/binfmt_elf.c | 16 +- trunk/fs/binfmt_elf_fdpic.c | 16 +- trunk/fs/cifs/CHANGES | 21 +- trunk/fs/cifs/Makefile | 2 +- trunk/fs/cifs/asn1.c | 10 +- trunk/fs/cifs/cifs_debug.c | 28 +- trunk/fs/cifs/cifsacl.c | 333 - trunk/fs/cifs/cifsacl.h | 64 +- trunk/fs/cifs/cifsencrypt.c | 5 +- trunk/fs/cifs/cifsfs.c | 38 +- trunk/fs/cifs/cifsfs.h | 11 +- trunk/fs/cifs/cifsglob.h | 31 +- trunk/fs/cifs/cifspdu.h | 20 +- trunk/fs/cifs/cifsproto.h | 8 +- trunk/fs/cifs/cifssmb.c | 158 +- trunk/fs/cifs/connect.c | 264 +- trunk/fs/cifs/dir.c | 9 +- trunk/fs/cifs/export.c | 1 - trunk/fs/cifs/file.c | 86 +- trunk/fs/cifs/inode.c | 57 +- trunk/fs/cifs/link.c | 2 +- trunk/fs/cifs/misc.c | 1 + trunk/fs/cifs/netmisc.c | 33 +- trunk/fs/cifs/readdir.c | 8 +- trunk/fs/cifs/sess.c | 103 +- trunk/fs/cifs/smberr.h | 5 +- trunk/fs/cifs/transport.c | 34 +- trunk/fs/cifs/xattr.c | 19 +- trunk/fs/coda/upcall.c | 2 +- trunk/fs/compat_ioctl.c | 2 +- trunk/fs/cramfs/inode.c | 9 +- trunk/fs/dlm/user.c | 2 +- trunk/fs/ecryptfs/inode.c | 8 - trunk/fs/eventpoll.c | 7 +- trunk/fs/exec.c | 16 +- trunk/fs/ext3/fsync.c | 2 +- trunk/fs/ext3/inode.c | 4 +- trunk/fs/ext3/resize.c | 6 +- trunk/fs/ext3/super.c | 6 +- trunk/fs/ext3/xattr.c | 3 +- trunk/fs/ext4/balloc.c | 112 +- trunk/fs/ext4/dir.c | 7 + trunk/fs/ext4/extents.c | 14 +- trunk/fs/ext4/fsync.c | 2 +- trunk/fs/ext4/group.h | 27 - trunk/fs/ext4/ialloc.c | 151 +- trunk/fs/ext4/inode.c | 18 +- trunk/fs/ext4/namei.c | 20 + trunk/fs/ext4/resize.c | 59 +- trunk/fs/ext4/super.c | 97 +- trunk/fs/ext4/xattr.c | 7 +- trunk/fs/fcntl.c | 5 +- trunk/fs/file_table.c | 5 +- trunk/fs/fs-writeback.c | 2 +- trunk/fs/fuse/dir.c | 241 +- trunk/fs/fuse/file.c | 111 +- trunk/fs/fuse/fuse_i.h | 32 +- trunk/fs/fuse/inode.c | 39 +- trunk/fs/ioprio.c | 9 +- trunk/fs/jbd/commit.c | 14 +- trunk/fs/jbd/journal.c | 173 +- trunk/fs/jbd/recovery.c | 6 +- trunk/fs/jbd/transaction.c | 25 +- trunk/fs/jbd2/commit.c | 16 +- trunk/fs/jbd2/journal.c | 128 +- trunk/fs/jbd2/recovery.c | 2 +- trunk/fs/jbd2/revoke.c | 4 +- trunk/fs/jbd2/transaction.c | 19 +- trunk/fs/jffs2/debug.h | 8 +- trunk/fs/namei.c | 6 +- trunk/fs/namespace.c | 2 +- trunk/fs/nfs/inode.c | 4 - trunk/fs/nfsd/vfs.c | 27 +- trunk/fs/nls/nls_base.c | 2 +- trunk/fs/ocfs2/cluster/heartbeat.c | 2 +- trunk/fs/ocfs2/cluster/masklog.h | 2 +- trunk/fs/ocfs2/dlm/dlmrecovery.c | 10 +- trunk/fs/proc/array.c | 32 +- trunk/fs/proc/base.c | 202 +- trunk/fs/proc/inode.c | 2 +- trunk/fs/proc/proc_misc.c | 3 +- trunk/fs/proc/root.c | 83 +- trunk/fs/reiserfs/bitmap.c | 111 +- trunk/fs/reiserfs/inode.c | 14 +- trunk/fs/reiserfs/journal.c | 24 +- trunk/fs/reiserfs/prints.c | 10 +- trunk/fs/reiserfs/resize.c | 15 +- trunk/fs/reiserfs/stree.c | 6 +- trunk/fs/reiserfs/super.c | 15 - trunk/fs/reiserfs/xattr.c | 5 +- trunk/fs/select.c | 5 + trunk/fs/super.c | 32 +- trunk/fs/xfs/linux-2.6/xfs_export.c | 6 +- trunk/fs/xfs/linux-2.6/xfs_export.h | 6 +- trunk/fs/xfs/linux-2.6/xfs_ioctl.c | 24 +- trunk/fs/xfs/xfs_dmops.c | 21 +- trunk/fs/xfs/xfs_fs.h | 29 +- trunk/fs/xfs/xfs_qmops.c | 22 +- trunk/fs/xfs/xfs_vfsops.c | 9 +- trunk/fs/xfs/xfs_vfsops.h | 4 +- trunk/fs/xfs/xfs_vnodeops.c | 13 +- trunk/fs/xfs/xfs_vnodeops.h | 2 +- trunk/include/acpi/achware.h | 4 +- trunk/include/acpi/acpi_bus.h | 2 +- trunk/include/acpi/acpixf.h | 2 - trunk/include/acpi/processor.h | 5 - trunk/include/asm-alpha/bitops.h | 55 - trunk/include/asm-alpha/tlbflush.h | 11 + trunk/include/asm-arm/arch-ixp4xx/io.h | 3 + trunk/include/asm-arm/arch-pxa/pm.h | 2 - trunk/include/asm-arm/bitops.h | 5 - trunk/include/asm-arm/tlbflush.h | 5 + trunk/include/asm-avr32/bitops.h | 5 - trunk/include/asm-avr32/tlbflush.h | 7 + trunk/include/asm-blackfin/bitops.h | 5 - trunk/include/asm-blackfin/processor.h | 4 +- trunk/include/asm-blackfin/tlbflush.h | 6 + trunk/include/asm-cris/bitops.h | 5 - trunk/include/asm-cris/posix_types.h | 2 +- trunk/include/asm-cris/tlbflush.h | 7 + trunk/include/asm-frv/bitops.h | 5 - trunk/include/asm-frv/tlbflush.h | 2 + trunk/include/asm-generic/bitops.h | 5 - trunk/include/asm-generic/bitops/atomic.h | 27 +- trunk/include/asm-generic/bitops/lock.h | 45 - trunk/include/asm-generic/bitops/non-atomic.h | 29 +- trunk/include/asm-generic/vmlinux.lds.h | 7 +- trunk/include/asm-h8300/bitops.h | 6 - trunk/include/asm-h8300/tlbflush.h | 6 + trunk/include/asm-ia64/bitops.h | 45 - trunk/include/asm-ia64/cacheflush.h | 2 +- trunk/include/asm-ia64/meminit.h | 2 +- trunk/include/asm-ia64/pgtable.h | 2 +- trunk/include/asm-ia64/smp.h | 2 +- trunk/include/asm-ia64/spinlock.h | 2 +- trunk/include/asm-ia64/tlbflush.h | 13 + trunk/include/asm-m32r/bitops.h | 5 - trunk/include/asm-m32r/pgtable.h | 2 +- trunk/include/asm-m32r/tlbflush.h | 3 + trunk/include/asm-m68k/bitops.h | 5 - trunk/include/asm-m68k/tlbflush.h | 10 + trunk/include/asm-m68knommu/bitops.h | 5 - trunk/include/asm-m68knommu/tlbflush.h | 6 + trunk/include/asm-mips/bitops.h | 106 - trunk/include/asm-mips/fpu.h | 2 +- trunk/include/asm-mips/ip32/crime.h | 3 + trunk/include/asm-mips/ip32/mace.h | 3 + .../asm-mips/mach-ip27/kernel-entry-init.h | 9 +- trunk/include/asm-mips/sni.h | 2 + trunk/include/asm-mips/time.h | 12 +- trunk/include/asm-mips/tlbflush.h | 7 + trunk/include/asm-parisc/bitops.h | 5 - trunk/include/asm-parisc/pgtable.h | 2 +- trunk/include/asm-parisc/tlbflush.h | 4 + trunk/include/asm-powerpc/bitops.h | 49 - trunk/include/asm-powerpc/iommu.h | 2 +- trunk/include/asm-powerpc/mmu_context.h | 2 +- trunk/include/asm-powerpc/mpc52xx.h | 6 +- trunk/include/asm-powerpc/paca.h | 3 - trunk/include/asm-powerpc/tlbflush.h | 11 + trunk/include/asm-ppc/mmu_context.h | 3 +- trunk/include/asm-ppc/time.h | 2 +- trunk/include/asm-s390/bitops.h | 5 - trunk/include/asm-s390/tlbflush.h | 7 + trunk/include/asm-sh/bitops.h | 6 - trunk/include/asm-sh/tlbflush.h | 6 + trunk/include/asm-sh64/bitops.h | 6 - trunk/include/asm-sh64/tlbflush.h | 4 + trunk/include/asm-sparc/bitops.h | 5 - trunk/include/asm-sparc/ioctls.h | 4 - trunk/include/asm-sparc/of_platform.h | 5 +- trunk/include/asm-sparc/termbits.h | 15 - trunk/include/asm-sparc/termios.h | 48 +- trunk/include/asm-sparc/tlbflush.h | 6 + trunk/include/asm-sparc64/backoff.h | 28 - trunk/include/asm-sparc64/bitops.h | 5 - trunk/include/asm-sparc64/ioctls.h | 4 - trunk/include/asm-sparc64/of_platform.h | 5 +- trunk/include/asm-sparc64/smp.h | 2 +- trunk/include/asm-sparc64/termbits.h | 17 +- trunk/include/asm-sparc64/termios.h | 42 - trunk/include/asm-sparc64/tlbflush.h | 7 + trunk/include/asm-um/bitops.h | 4 - trunk/include/asm-um/tlbflush.h | 6 + trunk/include/asm-v850/bitops.h | 4 - trunk/include/asm-v850/tlbflush.h | 6 + trunk/include/asm-x86/bitops_32.h | 5 - trunk/include/asm-x86/bitops_64.h | 5 - trunk/include/asm-x86/pgtable_32.h | 5 +- trunk/include/asm-x86/pgtable_64.h | 2 +- trunk/include/asm-x86/smp_32.h | 2 +- trunk/include/asm-x86/suspend_64.h | 2 - trunk/include/asm-x86/tlbflush_32.h | 7 + trunk/include/asm-x86/tlbflush_64.h | 9 + trunk/include/asm-x86/topology_64.h | 2 +- trunk/include/asm-xtensa/bitops.h | 5 - trunk/include/asm-xtensa/tlbflush.h | 11 + trunk/include/linux/Kbuild | 1 - trunk/include/linux/acpi.h | 26 + trunk/include/linux/aio.h | 12 + trunk/include/linux/bit_spinlock.h | 26 +- trunk/include/linux/bitmap.h | 1 - trunk/include/linux/bitops.h | 8 - trunk/include/linux/capability.h | 4 + trunk/include/linux/cgroup.h | 327 - trunk/include/linux/cgroup_subsys.h | 38 - trunk/include/linux/cgroupstats.h | 70 - trunk/include/linux/clocksource.h | 5 - trunk/include/linux/compiler-gcc.h | 12 +- trunk/include/linux/compiler.h | 14 + trunk/include/linux/console.h | 7 +- trunk/include/linux/cpu.h | 5 +- trunk/include/linux/cpu_acct.h | 14 - trunk/include/linux/cpuidle.h | 180 - trunk/include/linux/cpuset.h | 17 +- trunk/include/linux/cyclades.h | 27 +- trunk/include/linux/delayacct.h | 13 - trunk/include/linux/dma-mapping.h | 30 +- trunk/include/linux/ext3_fs.h | 4 +- trunk/include/linux/ext4_fs.h | 103 +- trunk/include/linux/ext4_fs_extents.h | 4 +- trunk/include/linux/ext4_fs_i.h | 5 + trunk/include/linux/ext4_fs_sb.h | 3 + trunk/include/linux/ext4_jbd2.h | 6 +- trunk/include/linux/filter.h | 1 - trunk/include/linux/freezer.h | 38 - trunk/include/linux/fs.h | 7 +- trunk/include/linux/fuse.h | 65 +- trunk/include/linux/hid.h | 4 +- trunk/include/linux/hrtimer.h | 2 +- trunk/include/linux/ide.h | 58 +- trunk/include/linux/init_task.h | 12 +- trunk/include/linux/input.h | 47 +- trunk/include/linux/ipc.h | 3 - trunk/include/linux/ipmi.h | 10 - trunk/include/linux/ipmi_smi.h | 36 +- trunk/include/linux/jbd.h | 33 +- trunk/include/linux/jbd2.h | 49 +- trunk/include/linux/kernel_stat.h | 2 - trunk/include/linux/kexec.h | 2 - trunk/include/linux/keyboard.h | 11 - trunk/include/linux/libata.h | 12 + trunk/include/linux/list.h | 3 +- trunk/include/linux/lockdep.h | 8 - trunk/include/linux/magic.h | 1 - trunk/include/linux/marker.h | 129 - trunk/include/linux/mempolicy.h | 12 + trunk/include/linux/module.h | 12 - trunk/include/linux/msg.h | 1 + trunk/include/linux/netdevice.h | 20 +- trunk/include/linux/netfilter/xt_sctp.h | 13 +- trunk/include/linux/notifier.h | 17 - trunk/include/linux/nsproxy.h | 50 +- trunk/include/linux/of.h | 2 +- trunk/include/linux/of_platform.h | 4 - trunk/include/linux/parport.h | 1 + trunk/include/linux/phantom.h | 6 +- trunk/include/linux/pid.h | 61 +- trunk/include/linux/pid_namespace.h | 26 +- trunk/include/linux/pm.h | 98 + trunk/include/linux/poison.h | 3 +- trunk/include/linux/prio_heap.h | 58 - trunk/include/linux/proc_fs.h | 19 +- trunk/include/linux/reiserfs_fs.h | 28 +- trunk/include/linux/reiserfs_fs_sb.h | 4 +- trunk/include/linux/sched.h | 222 +- trunk/include/linux/security.h | 7 - trunk/include/linux/sem.h | 1 + trunk/include/linux/shm.h | 1 + trunk/include/linux/suspend.h | 169 +- trunk/include/linux/sysctl.h | 58 +- trunk/include/linux/taskstats.h | 7 +- trunk/include/linux/tick.h | 9 - trunk/include/linux/types.h | 3 + trunk/include/linux/uinput.h | 4 + trunk/include/linux/vt.h | 12 - trunk/include/linux/workqueue.h | 49 +- trunk/include/net/9p/9p.h | 4 +- trunk/include/net/inet_frag.h | 7 - trunk/include/net/ipv6.h | 11 - trunk/include/net/scm.h | 4 +- trunk/include/net/sock.h | 22 +- trunk/include/net/xfrm.h | 33 +- trunk/include/video/sstfb.h | 1 + trunk/include/video/tdfx.h | 2 + trunk/init/Kconfig | 51 +- trunk/init/do_mounts_rd.c | 6 +- trunk/init/main.c | 3 - trunk/ipc/mqueue.c | 17 +- trunk/ipc/msg.c | 253 +- trunk/ipc/sem.c | 308 +- trunk/ipc/shm.c | 316 +- trunk/ipc/util.c | 506 +- trunk/ipc/util.h | 168 +- trunk/kernel/Kconfig.instrumentation | 49 - trunk/kernel/Makefile | 9 +- trunk/kernel/acct.c | 66 +- trunk/kernel/audit.c | 14 +- trunk/kernel/auditfilter.c | 4 +- trunk/kernel/auditsc.c | 10 +- trunk/kernel/capability.c | 200 +- trunk/kernel/cgroup.c | 2805 ------ trunk/kernel/cgroup_debug.c | 97 - trunk/kernel/compat.c | 117 +- trunk/kernel/cpu.c | 14 +- trunk/kernel/cpu_acct.c | 186 - trunk/kernel/cpuset.c | 1613 ++-- trunk/kernel/delayacct.c | 6 - trunk/kernel/die_notifier.c | 38 + trunk/kernel/dma.c | 8 +- trunk/kernel/exec_domain.c | 2 +- trunk/kernel/exit.c | 157 +- trunk/kernel/fork.c | 157 +- trunk/kernel/futex.c | 30 +- trunk/kernel/futex_compat.c | 3 +- trunk/kernel/hrtimer.c | 29 +- trunk/kernel/itimer.c | 4 +- trunk/kernel/kexec.c | 172 +- trunk/kernel/lockdep.c | 24 +- trunk/kernel/marker.c | 525 -- trunk/kernel/module.c | 68 +- trunk/kernel/notifier.c | 539 -- trunk/kernel/ns_cgroup.c | 100 - trunk/kernel/nsproxy.c | 62 +- trunk/kernel/panic.c | 10 +- trunk/kernel/params.c | 8 +- trunk/kernel/pid.c | 353 +- trunk/kernel/posix-cpu-timers.c | 12 +- trunk/kernel/posix-timers.c | 21 +- trunk/kernel/power/Kconfig | 11 + trunk/kernel/power/disk.c | 156 +- trunk/kernel/power/main.c | 48 +- trunk/kernel/power/power.h | 21 +- trunk/kernel/power/process.c | 141 +- trunk/kernel/power/snapshot.c | 53 +- trunk/kernel/power/swsusp.c | 33 + trunk/kernel/power/user.c | 4 - trunk/kernel/printk.c | 16 +- trunk/kernel/ptrace.c | 5 +- trunk/kernel/relay.c | 6 +- trunk/kernel/rtmutex-debug.c | 15 +- trunk/kernel/rtmutex.c | 2 +- trunk/kernel/sched.c | 361 +- trunk/kernel/sched_debug.c | 2 +- trunk/kernel/sched_stats.h | 8 +- trunk/kernel/signal.c | 67 +- trunk/kernel/softlockup.c | 2 +- trunk/kernel/sys.c | 587 +- trunk/kernel/sysctl.c | 280 +- trunk/kernel/sysctl_check.c | 1588 ---- trunk/kernel/taskstats.c | 67 - trunk/kernel/time.c | 14 +- trunk/kernel/time/clocksource.c | 22 +- trunk/kernel/time/tick-sched.c | 16 - trunk/kernel/timer.c | 16 +- trunk/kernel/tsacct.c | 4 - trunk/kernel/workqueue.c | 38 +- trunk/lib/Kconfig.debug | 2 - trunk/lib/Makefile | 2 +- trunk/lib/crc32.c | 12 +- trunk/lib/hweight.c | 2 +- trunk/lib/libcrc32c.c | 6 +- trunk/lib/percpu_counter.c | 5 +- trunk/lib/prio_heap.c | 70 - trunk/lib/spinlock_debug.c | 8 +- trunk/mm/filemap.c | 3 +- trunk/mm/hugetlb.c | 2 +- trunk/mm/memory.c | 3 + trunk/mm/mempolicy.c | 5 +- trunk/mm/migrate.c | 3 +- trunk/mm/mmap.c | 11 +- trunk/mm/mprotect.c | 6 +- trunk/mm/mremap.c | 4 +- trunk/mm/oom_kill.c | 15 +- trunk/mm/slab.c | 307 +- trunk/mm/vmscan.c | 2 +- trunk/net/atm/br2684.c | 121 + trunk/net/bluetooth/hidp/core.c | 12 +- trunk/net/core/filter.c | 59 +- trunk/net/core/gen_estimator.c | 2 +- trunk/net/core/neighbour.c | 75 +- trunk/net/core/pktgen.c | 6 +- trunk/net/core/rtnetlink.c | 8 +- trunk/net/core/scm.c | 4 +- trunk/net/core/sock.c | 16 +- trunk/net/dccp/input.c | 3 - trunk/net/dccp/sysctl.c | 3 + trunk/net/ieee80211/ieee80211_crypt_tkip.c | 2 +- trunk/net/ipv4/fib_trie.c | 2 +- trunk/net/ipv4/inet_connection_sock.c | 2 +- trunk/net/ipv4/inet_fragment.c | 89 +- trunk/net/ipv4/inet_hashtables.c | 2 +- trunk/net/ipv4/ip_fragment.c | 159 +- trunk/net/ipv4/ipvs/ip_vs_sync.c | 6 +- .../ipv4/netfilter/nf_conntrack_proto_icmp.c | 2 + trunk/net/ipv4/sysctl_net_ipv4.c | 6 +- trunk/net/ipv4/tcp.c | 2 +- trunk/net/ipv4/tcp_input.c | 6 +- trunk/net/ipv4/udp.c | 5 +- trunk/net/ipv4/xfrm4_input.c | 40 +- trunk/net/ipv4/xfrm4_mode_beet.c | 1 - trunk/net/ipv4/xfrm4_mode_tunnel.c | 1 - trunk/net/ipv4/xfrm4_output.c | 2 +- trunk/net/ipv4/xfrm4_policy.c | 27 +- trunk/net/ipv4/xfrm4_state.c | 1 - trunk/net/ipv4/xfrm4_tunnel.c | 11 +- trunk/net/ipv6/addrconf.c | 10 +- trunk/net/ipv6/af_inet6.c | 1 - trunk/net/ipv6/ah6.c | 11 +- trunk/net/ipv6/esp6.c | 9 +- trunk/net/ipv6/inet6_hashtables.c | 2 +- trunk/net/ipv6/ip6_flowlabel.c | 57 +- trunk/net/ipv6/ipcomp6.c | 9 +- trunk/net/ipv6/ndisc.c | 24 +- .../netfilter/nf_conntrack_l3proto_ipv6.c | 1 + .../netfilter/nf_conntrack_proto_icmpv6.c | 1 + trunk/net/ipv6/netfilter/nf_conntrack_reasm.c | 112 +- trunk/net/ipv6/reassembly.c | 131 +- trunk/net/ipv6/route.c | 1 + trunk/net/ipv6/xfrm6_input.c | 14 +- trunk/net/ipv6/xfrm6_mode_beet.c | 1 - trunk/net/ipv6/xfrm6_mode_ro.c | 9 + trunk/net/ipv6/xfrm6_mode_tunnel.c | 1 - trunk/net/ipv6/xfrm6_output.c | 2 +- trunk/net/ipv6/xfrm6_policy.c | 17 +- trunk/net/ipv6/xfrm6_state.c | 7 +- trunk/net/ipv6/xfrm6_tunnel.c | 4 +- trunk/net/irda/ircomm/ircomm_tty_attach.c | 15 +- trunk/net/irda/irsysctl.c | 34 +- trunk/net/llc/af_llc.c | 2 +- trunk/net/mac80211/ieee80211_i.h | 2 + trunk/net/mac80211/ieee80211_ioctl.c | 16 +- trunk/net/mac80211/ieee80211_sta.c | 126 +- .../netfilter/nf_conntrack_proto_generic.c | 2 + trunk/net/netfilter/nf_conntrack_proto_sctp.c | 14 + trunk/net/netfilter/nf_conntrack_proto_tcp.c | 29 +- trunk/net/netfilter/nf_conntrack_proto_udp.c | 4 + trunk/net/netfilter/xt_connbytes.c | 2 +- trunk/net/netfilter/xt_sctp.c | 18 +- trunk/net/packet/af_packet.c | 5 + trunk/net/rfkill/rfkill-input.c | 12 +- trunk/net/sched/Kconfig | 10 +- trunk/net/sched/sch_generic.c | 33 +- trunk/net/sunrpc/sched.c | 2 +- trunk/net/sunrpc/sysctl.c | 4 + trunk/net/unix/af_unix.c | 6 +- trunk/net/xfrm/xfrm_input.c | 5 +- trunk/net/xfrm/xfrm_output.c | 4 +- trunk/net/xfrm/xfrm_policy.c | 179 +- trunk/net/xfrm/xfrm_state.c | 206 +- trunk/samples/Kconfig | 16 - trunk/samples/Makefile | 3 - trunk/samples/markers/Makefile | 4 - trunk/samples/markers/marker-example.c | 54 - trunk/samples/markers/probe-example.c | 98 - trunk/scripts/checkpatch.pl | 514 +- trunk/scripts/checkstack.pl | 2 +- trunk/security/commoncap.c | 62 +- trunk/security/dummy.c | 16 +- trunk/security/selinux/xfrm.c | 2 +- trunk/sound/arm/aaci.c | 4 +- trunk/sound/oss/Makefile | 1 + trunk/sound/oss/dmasound/Makefile | 6 + trunk/sound/oss/dmasound/awacs_defs.h | 251 + trunk/sound/oss/dmasound/dac3550a.c | 209 + trunk/sound/oss/dmasound/dmasound.h | 13 + trunk/sound/oss/dmasound/dmasound_awacs.c | 3215 +++++++ trunk/sound/oss/dmasound/dmasound_core.c | 287 + trunk/sound/oss/dmasound/tas3001c.c | 849 ++ trunk/sound/oss/dmasound/tas3001c.h | 64 + trunk/sound/oss/dmasound/tas3001c_tables.c | 375 + trunk/sound/oss/dmasound/tas3004.c | 1138 +++ trunk/sound/oss/dmasound/tas3004.h | 77 + trunk/sound/oss/dmasound/tas3004_tables.c | 301 + trunk/sound/oss/dmasound/tas_common.c | 214 + trunk/sound/oss/dmasound/tas_common.h | 284 + trunk/sound/oss/dmasound/tas_eq_prefs.h | 24 + trunk/sound/oss/dmasound/tas_ioctl.h | 23 + trunk/sound/oss/dmasound/trans_16.c | 898 ++ trunk/sound/oss/es1371.c | 3131 +++++++ trunk/sound/ppc/beep.c | 4 +- trunk/sound/usb/caiaq/caiaq-input.c | 9 +- 1136 files changed, 30572 insertions(+), 31459 deletions(-) delete mode 100644 trunk/Documentation/accounting/cgroupstats.txt delete mode 100644 trunk/Documentation/cgroups.txt delete mode 100644 trunk/Documentation/markers.txt create mode 100644 trunk/Documentation/mips/time.README create mode 100644 trunk/Documentation/sound/oss/es1371 create mode 100644 trunk/arch/alpha/oprofile/Kconfig create mode 100644 trunk/arch/arm/oprofile/Kconfig create mode 100644 trunk/arch/blackfin/oprofile/Kconfig create mode 100644 trunk/arch/ia64/oprofile/Kconfig create mode 100644 trunk/arch/m32r/oprofile/Kconfig delete mode 100644 trunk/arch/mips/kernel/cevt-r4k.c create mode 100644 trunk/arch/mips/oprofile/Kconfig create mode 100644 trunk/arch/parisc/oprofile/Kconfig create mode 100644 trunk/arch/powerpc/oprofile/Kconfig create mode 100644 trunk/arch/s390/oprofile/Kconfig create mode 100644 trunk/arch/sh/oprofile/Kconfig create mode 100644 trunk/arch/sh64/oprofile/Kconfig create mode 100644 trunk/arch/sparc/oprofile/Kconfig create mode 100644 trunk/arch/sparc64/oprofile/Kconfig delete mode 100644 trunk/drivers/acpi/sbshc.c delete mode 100644 trunk/drivers/acpi/sbshc.h delete mode 100644 trunk/drivers/ata/sata_fsl.c rename trunk/drivers/{ => char}/watchdog/Kconfig (100%) rename trunk/drivers/{ => char}/watchdog/Makefile (100%) rename trunk/drivers/{ => char}/watchdog/acquirewdt.c (100%) rename trunk/drivers/{ => char}/watchdog/advantechwdt.c (100%) rename trunk/drivers/{ => char}/watchdog/alim1535_wdt.c (100%) rename trunk/drivers/{ => char}/watchdog/alim7101_wdt.c (100%) rename trunk/drivers/{ => char}/watchdog/at32ap700x_wdt.c (100%) rename trunk/drivers/{ => char}/watchdog/at91rm9200_wdt.c (99%) rename trunk/drivers/{ => char}/watchdog/bfin_wdt.c (100%) rename trunk/drivers/{ => char}/watchdog/booke_wdt.c (100%) rename trunk/drivers/{ => char}/watchdog/cpu5wdt.c (100%) rename trunk/drivers/{ => char}/watchdog/davinci_wdt.c (100%) rename trunk/drivers/{ => char}/watchdog/ep93xx_wdt.c (100%) rename trunk/drivers/{ => char}/watchdog/eurotechwdt.c (100%) rename trunk/drivers/{ => char}/watchdog/i6300esb.c (100%) rename trunk/drivers/{ => char}/watchdog/iTCO_vendor_support.c (100%) rename trunk/drivers/{ => char}/watchdog/iTCO_wdt.c (100%) rename trunk/drivers/{ => char}/watchdog/ib700wdt.c (100%) rename trunk/drivers/{ => char}/watchdog/ibmasr.c (100%) rename trunk/drivers/{ => char}/watchdog/indydog.c (100%) rename trunk/drivers/{ => char}/watchdog/iop_wdt.c (100%) rename trunk/drivers/{ => char}/watchdog/ixp2000_wdt.c (100%) rename trunk/drivers/{ => char}/watchdog/ixp4xx_wdt.c (100%) rename trunk/drivers/{ => char}/watchdog/ks8695_wdt.c (99%) rename trunk/drivers/{ => char}/watchdog/machzwd.c (100%) rename trunk/drivers/{ => char}/watchdog/mixcomwd.c (100%) rename trunk/drivers/{ => char}/watchdog/mpc5200_wdt.c (100%) rename trunk/drivers/{ => char}/watchdog/mpc83xx_wdt.c (100%) rename trunk/drivers/{ => char}/watchdog/mpc8xx_wdt.c (100%) rename trunk/drivers/{ => char}/watchdog/mpcore_wdt.c (100%) rename trunk/drivers/{ => char}/watchdog/mtx-1_wdt.c (100%) rename trunk/drivers/{ => char}/watchdog/mv64x60_wdt.c (100%) rename trunk/drivers/{ => char}/watchdog/omap_wdt.c (99%) rename trunk/drivers/{ => char}/watchdog/omap_wdt.h (100%) rename trunk/drivers/{ => char}/watchdog/pc87413_wdt.c (100%) rename trunk/drivers/{ => char}/watchdog/pcwd.c (100%) rename trunk/drivers/{ => char}/watchdog/pcwd_pci.c (100%) rename trunk/drivers/{ => char}/watchdog/pcwd_usb.c (100%) rename trunk/drivers/{ => char}/watchdog/pnx4008_wdt.c (100%) rename trunk/drivers/{ => char}/watchdog/rm9k_wdt.c (100%) rename trunk/drivers/{ => char}/watchdog/s3c2410_wdt.c (100%) rename trunk/drivers/{ => char}/watchdog/sa1100_wdt.c (99%) rename trunk/drivers/{ => char}/watchdog/sbc60xxwdt.c (100%) rename trunk/drivers/{ => char}/watchdog/sbc8360.c (100%) rename trunk/drivers/{ => char}/watchdog/sbc_epx_c3.c (100%) rename trunk/drivers/{ => char}/watchdog/sc1200wdt.c (100%) rename trunk/drivers/{ => char}/watchdog/sc520_wdt.c (100%) rename trunk/drivers/{ => char}/watchdog/scx200_wdt.c (100%) rename trunk/drivers/{ => char}/watchdog/shwdt.c (100%) rename trunk/drivers/{ => char}/watchdog/smsc37b787_wdt.c (100%) rename trunk/drivers/{ => char}/watchdog/softdog.c (100%) rename trunk/drivers/{ => char}/watchdog/w83627hf_wdt.c (100%) rename trunk/drivers/{ => char}/watchdog/w83697hf_wdt.c (100%) rename trunk/drivers/{ => char}/watchdog/w83877f_wdt.c (100%) rename trunk/drivers/{ => char}/watchdog/w83977f_wdt.c (100%) rename trunk/drivers/{ => char}/watchdog/wafer5823wdt.c (100%) rename trunk/drivers/{ => char}/watchdog/wd501p.h (100%) rename trunk/drivers/{ => char}/watchdog/wdrtas.c (100%) rename trunk/drivers/{ => char}/watchdog/wdt.c (100%) rename trunk/drivers/{ => char}/watchdog/wdt285.c (100%) rename trunk/drivers/{ => char}/watchdog/wdt977.c (100%) rename trunk/drivers/{ => char}/watchdog/wdt_pci.c (100%) delete mode 100644 trunk/drivers/cpuidle/Kconfig delete mode 100644 trunk/drivers/cpuidle/Makefile delete mode 100644 trunk/drivers/cpuidle/cpuidle.c delete mode 100644 trunk/drivers/cpuidle/cpuidle.h delete mode 100644 trunk/drivers/cpuidle/driver.c delete mode 100644 trunk/drivers/cpuidle/governor.c delete mode 100644 trunk/drivers/cpuidle/governors/Makefile delete mode 100644 trunk/drivers/cpuidle/governors/ladder.c delete mode 100644 trunk/drivers/cpuidle/governors/menu.c delete mode 100644 trunk/drivers/cpuidle/sysfs.c create mode 100644 trunk/drivers/isdn/sc/debug.h delete mode 100644 trunk/drivers/misc/fujitsu-laptop.c delete mode 100644 trunk/fs/cifs/cifsacl.c delete mode 100644 trunk/fs/ext4/group.h delete mode 100644 trunk/include/asm-generic/bitops/lock.h delete mode 100644 trunk/include/asm-sparc64/backoff.h delete mode 100644 trunk/include/linux/cgroup.h delete mode 100644 trunk/include/linux/cgroup_subsys.h delete mode 100644 trunk/include/linux/cgroupstats.h delete mode 100644 trunk/include/linux/cpu_acct.h delete mode 100644 trunk/include/linux/cpuidle.h delete mode 100644 trunk/include/linux/marker.h delete mode 100644 trunk/include/linux/prio_heap.h delete mode 100644 trunk/kernel/Kconfig.instrumentation delete mode 100644 trunk/kernel/cgroup.c delete mode 100644 trunk/kernel/cgroup_debug.c delete mode 100644 trunk/kernel/cpu_acct.c create mode 100644 trunk/kernel/die_notifier.c delete mode 100644 trunk/kernel/marker.c delete mode 100644 trunk/kernel/notifier.c delete mode 100644 trunk/kernel/ns_cgroup.c delete mode 100644 trunk/kernel/sysctl_check.c delete mode 100644 trunk/lib/prio_heap.c delete mode 100644 trunk/samples/Kconfig delete mode 100644 trunk/samples/Makefile delete mode 100644 trunk/samples/markers/Makefile delete mode 100644 trunk/samples/markers/marker-example.c delete mode 100644 trunk/samples/markers/probe-example.c create mode 100644 trunk/sound/oss/dmasound/awacs_defs.h create mode 100644 trunk/sound/oss/dmasound/dac3550a.c create mode 100644 trunk/sound/oss/dmasound/dmasound_awacs.c create mode 100644 trunk/sound/oss/dmasound/tas3001c.c create mode 100644 trunk/sound/oss/dmasound/tas3001c.h create mode 100644 trunk/sound/oss/dmasound/tas3001c_tables.c create mode 100644 trunk/sound/oss/dmasound/tas3004.c create mode 100644 trunk/sound/oss/dmasound/tas3004.h create mode 100644 trunk/sound/oss/dmasound/tas3004_tables.c create mode 100644 trunk/sound/oss/dmasound/tas_common.c create mode 100644 trunk/sound/oss/dmasound/tas_common.h create mode 100644 trunk/sound/oss/dmasound/tas_eq_prefs.h create mode 100644 trunk/sound/oss/dmasound/tas_ioctl.h create mode 100644 trunk/sound/oss/dmasound/trans_16.c create mode 100644 trunk/sound/oss/es1371.c diff --git a/[refs] b/[refs] index 2f91b4c72e50..f6a794cd4f58 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: c4ec20717313daafba59225f812db89595952b83 +refs/heads/master: fc333b2df388d6e8791b3ee59c0679e4a131555a diff --git a/trunk/Documentation/DocBook/kernel-api.tmpl b/trunk/Documentation/DocBook/kernel-api.tmpl index aa38cc5692a0..d3290c46af51 100644 --- a/trunk/Documentation/DocBook/kernel-api.tmpl +++ b/trunk/Documentation/DocBook/kernel-api.tmpl @@ -46,7 +46,7 @@ Atomic and pointer manipulation !Iinclude/asm-x86/atomic_32.h -!Iinclude/asm-x86/unaligned.h +!Iinclude/asm-x86/unaligned_32.h Delaying, scheduling, and timer routines diff --git a/trunk/Documentation/IPMI.txt b/trunk/Documentation/IPMI.txt index bc38283379f0..24dc3fcf1594 100644 --- a/trunk/Documentation/IPMI.txt +++ b/trunk/Documentation/IPMI.txt @@ -441,20 +441,17 @@ ACPI, and if none of those then a KCS device at the spec-specified 0xca2. If you want to turn this off, set the "trydefaults" option to false. -If your IPMI interface does not support interrupts and is a KCS or -SMIC interface, the IPMI driver will start a kernel thread for the -interface to help speed things up. This is a low-priority kernel -thread that constantly polls the IPMI driver while an IPMI operation -is in progress. The force_kipmid module parameter will all the user to -force this thread on or off. If you force it off and don't have -interrupts, the driver will run VERY slowly. Don't blame me, +If you have high-res timers compiled into the kernel, the driver will +use them to provide much better performance. Note that if you do not +have high-res timers enabled in the kernel and you don't have +interrupts enabled, the driver will run VERY slowly. Don't blame me, these interfaces suck. The driver supports a hot add and remove of interfaces. This way, interfaces can be added or removed after the kernel is up and running. -This is done using /sys/modules/ipmi_si/parameters/hotmod, which is a -write-only parameter. You write a string to this interface. The string -has the format: +This is done using /sys/modules/ipmi_si/hotmod, which is a write-only +parameter. You write a string to this interface. The string has the +format: [:op2[:op3...]] The "op"s are: add|remove,kcs|bt|smic,mem|i/o,
[,[,[,...]]] @@ -584,11 +581,9 @@ The watchdog will panic and start a 120 second reset timeout if it gets a pre-action. During a panic or a reboot, the watchdog will start a 120 timer if it is running to make sure the reboot occurs. -Note that if you use the NMI preaction for the watchdog, you MUST NOT -use the nmi watchdog. There is no reasonable way to tell if an NMI -comes from the IPMI controller, so it must assume that if it gets an -otherwise unhandled NMI, it must be from IPMI and it will panic -immediately. +Note that if you use the NMI preaction for the watchdog, you MUST +NOT use nmi watchdog mode 1. If you use the NMI watchdog, you +must use mode 2. Once you open the watchdog timer, you must write a 'V' character to the device to close it, or the timer will not stop. This is a new semantic diff --git a/trunk/Documentation/accounting/cgroupstats.txt b/trunk/Documentation/accounting/cgroupstats.txt deleted file mode 100644 index eda40fd39cad..000000000000 --- a/trunk/Documentation/accounting/cgroupstats.txt +++ /dev/null @@ -1,27 +0,0 @@ -Control Groupstats is inspired by the discussion at -http://lkml.org/lkml/2007/4/11/187 and implements per cgroup statistics as -suggested by Andrew Morton in http://lkml.org/lkml/2007/4/11/263. - -Per cgroup statistics infrastructure re-uses code from the taskstats -interface. A new set of cgroup operations are registered with commands -and attributes specific to cgroups. It should be very easy to -extend per cgroup statistics, by adding members to the cgroupstats -structure. - -The current model for cgroupstats is a pull, a push model (to post -statistics on interesting events), should be very easy to add. Currently -user space requests for statistics by passing the cgroup path. -Statistics about the state of all the tasks in the cgroup is returned to -user space. - -NOTE: We currently rely on delay accounting for extracting information -about tasks blocked on I/O. If CONFIG_TASK_DELAY_ACCT is disabled, this -information will not be available. - -To extract cgroup statistics a utility very similar to getdelays.c -has been developed, the sample output of the utility is shown below - -~/balbir/cgroupstats # ./getdelays -C "/cgroup/a" -sleeping 1, blocked 0, running 1, stopped 0, uninterruptible 0 -~/balbir/cgroupstats # ./getdelays -C "/cgroup" -sleeping 155, blocked 0, running 1, stopped 0, uninterruptible 2 diff --git a/trunk/Documentation/atomic_ops.txt b/trunk/Documentation/atomic_ops.txt index f20c10c2858f..d46306fea230 100644 --- a/trunk/Documentation/atomic_ops.txt +++ b/trunk/Documentation/atomic_ops.txt @@ -418,20 +418,6 @@ brothers: */ smp_mb__after_clear_bit(); -There are two special bitops with lock barrier semantics (acquire/release, -same as spinlocks). These operate in the same way as their non-_lock/unlock -postfixed variants, except that they are to provide acquire/release semantics, -respectively. This means they can be used for bit_spin_trylock and -bit_spin_unlock type operations without specifying any more barriers. - - int test_and_set_bit_lock(unsigned long nr, unsigned long *addr); - void clear_bit_unlock(unsigned long nr, unsigned long *addr); - void __clear_bit_unlock(unsigned long nr, unsigned long *addr); - -The __clear_bit_unlock version is non-atomic, however it still implements -unlock barrier semantics. This can be useful if the lock itself is protecting -the other bits in the word. - Finally, there are non-atomic versions of the bitmask operations provided. They are used in contexts where some other higher-level SMP locking scheme is being used to protect the bitmask, and thus less diff --git a/trunk/Documentation/cachetlb.txt b/trunk/Documentation/cachetlb.txt index da42ab414c48..552cabac0608 100644 --- a/trunk/Documentation/cachetlb.txt +++ b/trunk/Documentation/cachetlb.txt @@ -87,7 +87,30 @@ changes occur: This is used primarily during fault processing. -5) void update_mmu_cache(struct vm_area_struct *vma, +5) void flush_tlb_pgtables(struct mm_struct *mm, + unsigned long start, unsigned long end) + + The software page tables for address space 'mm' for virtual + addresses in the range 'start' to 'end-1' are being torn down. + + Some platforms cache the lowest level of the software page tables + in a linear virtually mapped array, to make TLB miss processing + more efficient. On such platforms, since the TLB is caching the + software page table structure, it needs to be flushed when parts + of the software page table tree are unlinked/freed. + + Sparc64 is one example of a platform which does this. + + Usually, when munmap()'ing an area of user virtual address + space, the kernel leaves the page table parts around and just + marks the individual pte's as invalid. However, if very large + portions of the address space are unmapped, the kernel frees up + those portions of the software page tables to prevent potential + excessive kernel memory usage caused by erratic mmap/mmunmap + sequences. It is at these times that flush_tlb_pgtables will + be invoked. + +6) void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte) At the end of every page fault, this routine is invoked to @@ -100,7 +123,7 @@ changes occur: translations for software managed TLB configurations. The sparc64 port currently does this. -6) void tlb_migrate_finish(struct mm_struct *mm) +7) void tlb_migrate_finish(struct mm_struct *mm) This interface is called at the end of an explicit process migration. This interface provides a hook diff --git a/trunk/Documentation/cgroups.txt b/trunk/Documentation/cgroups.txt deleted file mode 100644 index 98a26f81fa75..000000000000 --- a/trunk/Documentation/cgroups.txt +++ /dev/null @@ -1,545 +0,0 @@ - CGROUPS - ------- - -Written by Paul Menage based on Documentation/cpusets.txt - -Original copyright statements from cpusets.txt: -Portions Copyright (C) 2004 BULL SA. -Portions Copyright (c) 2004-2006 Silicon Graphics, Inc. -Modified by Paul Jackson -Modified by Christoph Lameter - -CONTENTS: -========= - -1. Control Groups - 1.1 What are cgroups ? - 1.2 Why are cgroups needed ? - 1.3 How are cgroups implemented ? - 1.4 What does notify_on_release do ? - 1.5 How do I use cgroups ? -2. Usage Examples and Syntax - 2.1 Basic Usage - 2.2 Attaching processes -3. Kernel API - 3.1 Overview - 3.2 Synchronization - 3.3 Subsystem API -4. Questions - -1. Control Groups -========== - -1.1 What are cgroups ? ----------------------- - -Control Groups provide a mechanism for aggregating/partitioning sets of -tasks, and all their future children, into hierarchical groups with -specialized behaviour. - -Definitions: - -A *cgroup* associates a set of tasks with a set of parameters for one -or more subsystems. - -A *subsystem* is a module that makes use of the task grouping -facilities provided by cgroups to treat groups of tasks in -particular ways. A subsystem is typically a "resource controller" that -schedules a resource or applies per-cgroup limits, but it may be -anything that wants to act on a group of processes, e.g. a -virtualization subsystem. - -A *hierarchy* is a set of cgroups arranged in a tree, such that -every task in the system is in exactly one of the cgroups in the -hierarchy, and a set of subsystems; each subsystem has system-specific -state attached to each cgroup in the hierarchy. Each hierarchy has -an instance of the cgroup virtual filesystem associated with it. - -At any one time there may be multiple active hierachies of task -cgroups. Each hierarchy is a partition of all tasks in the system. - -User level code may create and destroy cgroups by name in an -instance of the cgroup virtual file system, specify and query to -which cgroup a task is assigned, and list the task pids assigned to -a cgroup. Those creations and assignments only affect the hierarchy -associated with that instance of the cgroup file system. - -On their own, the only use for cgroups is for simple job -tracking. The intention is that other subsystems hook into the generic -cgroup support to provide new attributes for cgroups, such as -accounting/limiting the resources which processes in a cgroup can -access. For example, cpusets (see Documentation/cpusets.txt) allows -you to associate a set of CPUs and a set of memory nodes with the -tasks in each cgroup. - -1.2 Why are cgroups needed ? ----------------------------- - -There are multiple efforts to provide process aggregations in the -Linux kernel, mainly for resource tracking purposes. Such efforts -include cpusets, CKRM/ResGroups, UserBeanCounters, and virtual server -namespaces. These all require the basic notion of a -grouping/partitioning of processes, with newly forked processes ending -in the same group (cgroup) as their parent process. - -The kernel cgroup patch provides the minimum essential kernel -mechanisms required to efficiently implement such groups. It has -minimal impact on the system fast paths, and provides hooks for -specific subsystems such as cpusets to provide additional behaviour as -desired. - -Multiple hierarchy support is provided to allow for situations where -the division of tasks into cgroups is distinctly different for -different subsystems - having parallel hierarchies allows each -hierarchy to be a natural division of tasks, without having to handle -complex combinations of tasks that would be present if several -unrelated subsystems needed to be forced into the same tree of -cgroups. - -At one extreme, each resource controller or subsystem could be in a -separate hierarchy; at the other extreme, all subsystems -would be attached to the same hierarchy. - -As an example of a scenario (originally proposed by vatsa@in.ibm.com) -that can benefit from multiple hierarchies, consider a large -university server with various users - students, professors, system -tasks etc. The resource planning for this server could be along the -following lines: - - CPU : Top cpuset - / \ - CPUSet1 CPUSet2 - | | - (Profs) (Students) - - In addition (system tasks) are attached to topcpuset (so - that they can run anywhere) with a limit of 20% - - Memory : Professors (50%), students (30%), system (20%) - - Disk : Prof (50%), students (30%), system (20%) - - Network : WWW browsing (20%), Network File System (60%), others (20%) - / \ - Prof (15%) students (5%) - -Browsers like firefox/lynx go into the WWW network class, while (k)nfsd go -into NFS network class. - -At the same time firefox/lynx will share an appropriate CPU/Memory class -depending on who launched it (prof/student). - -With the ability to classify tasks differently for different resources -(by putting those resource subsystems in different hierarchies) then -the admin can easily set up a script which receives exec notifications -and depending on who is launching the browser he can - - # echo browser_pid > /mnt///tasks - -With only a single hierarchy, he now would potentially have to create -a separate cgroup for every browser launched and associate it with -approp network and other resource class. This may lead to -proliferation of such cgroups. - -Also lets say that the administrator would like to give enhanced network -access temporarily to a student's browser (since it is night and the user -wants to do online gaming :) OR give one of the students simulation -apps enhanced CPU power, - -With ability to write pids directly to resource classes, its just a -matter of : - - # echo pid > /mnt/network//tasks - (after some time) - # echo pid > /mnt/network//tasks - -Without this ability, he would have to split the cgroup into -multiple separate ones and then associate the new cgroups with the -new resource classes. - - - -1.3 How are cgroups implemented ? ---------------------------------- - -Control Groups extends the kernel as follows: - - - Each task in the system has a reference-counted pointer to a - css_set. - - - A css_set contains a set of reference-counted pointers to - cgroup_subsys_state objects, one for each cgroup subsystem - registered in the system. There is no direct link from a task to - the cgroup of which it's a member in each hierarchy, but this - can be determined by following pointers through the - cgroup_subsys_state objects. This is because accessing the - subsystem state is something that's expected to happen frequently - and in performance-critical code, whereas operations that require a - task's actual cgroup assignments (in particular, moving between - cgroups) are less common. A linked list runs through the cg_list - field of each task_struct using the css_set, anchored at - css_set->tasks. - - - A cgroup hierarchy filesystem can be mounted for browsing and - manipulation from user space. - - - You can list all the tasks (by pid) attached to any cgroup. - -The implementation of cgroups requires a few, simple hooks -into the rest of the kernel, none in performance critical paths: - - - in init/main.c, to initialize the root cgroups and initial - css_set at system boot. - - - in fork and exit, to attach and detach a task from its css_set. - -In addition a new file system, of type "cgroup" may be mounted, to -enable browsing and modifying the cgroups presently known to the -kernel. When mounting a cgroup hierarchy, you may specify a -comma-separated list of subsystems to mount as the filesystem mount -options. By default, mounting the cgroup filesystem attempts to -mount a hierarchy containing all registered subsystems. - -If an active hierarchy with exactly the same set of subsystems already -exists, it will be reused for the new mount. If no existing hierarchy -matches, and any of the requested subsystems are in use in an existing -hierarchy, the mount will fail with -EBUSY. Otherwise, a new hierarchy -is activated, associated with the requested subsystems. - -It's not currently possible to bind a new subsystem to an active -cgroup hierarchy, or to unbind a subsystem from an active cgroup -hierarchy. This may be possible in future, but is fraught with nasty -error-recovery issues. - -When a cgroup filesystem is unmounted, if there are any -child cgroups created below the top-level cgroup, that hierarchy -will remain active even though unmounted; if there are no -child cgroups then the hierarchy will be deactivated. - -No new system calls are added for cgroups - all support for -querying and modifying cgroups is via this cgroup file system. - -Each task under /proc has an added file named 'cgroup' displaying, -for each active hierarchy, the subsystem names and the cgroup name -as the path relative to the root of the cgroup file system. - -Each cgroup is represented by a directory in the cgroup file system -containing the following files describing that cgroup: - - - tasks: list of tasks (by pid) attached to that cgroup - - notify_on_release flag: run /sbin/cgroup_release_agent on exit? - -Other subsystems such as cpusets may add additional files in each -cgroup dir - -New cgroups are created using the mkdir system call or shell -command. The properties of a cgroup, such as its flags, are -modified by writing to the appropriate file in that cgroups -directory, as listed above. - -The named hierarchical structure of nested cgroups allows partitioning -a large system into nested, dynamically changeable, "soft-partitions". - -The attachment of each task, automatically inherited at fork by any -children of that task, to a cgroup allows organizing the work load -on a system into related sets of tasks. A task may be re-attached to -any other cgroup, if allowed by the permissions on the necessary -cgroup file system directories. - -When a task is moved from one cgroup to another, it gets a new -css_set pointer - if there's an already existing css_set with the -desired collection of cgroups then that group is reused, else a new -css_set is allocated. Note that the current implementation uses a -linear search to locate an appropriate existing css_set, so isn't -very efficient. A future version will use a hash table for better -performance. - -To allow access from a cgroup to the css_sets (and hence tasks) -that comprise it, a set of cg_cgroup_link objects form a lattice; -each cg_cgroup_link is linked into a list of cg_cgroup_links for -a single cgroup on its cont_link_list field, and a list of -cg_cgroup_links for a single css_set on its cg_link_list. - -Thus the set of tasks in a cgroup can be listed by iterating over -each css_set that references the cgroup, and sub-iterating over -each css_set's task set. - -The use of a Linux virtual file system (vfs) to represent the -cgroup hierarchy provides for a familiar permission and name space -for cgroups, with a minimum of additional kernel code. - -1.4 What does notify_on_release do ? ------------------------------------- - -*** notify_on_release is disabled in the current patch set. It will be -*** reactivated in a future patch in a less-intrusive manner - -If the notify_on_release flag is enabled (1) in a cgroup, then -whenever the last task in the cgroup leaves (exits or attaches to -some other cgroup) and the last child cgroup of that cgroup -is removed, then the kernel runs the command specified by the contents -of the "release_agent" file in that hierarchy's root directory, -supplying the pathname (relative to the mount point of the cgroup -file system) of the abandoned cgroup. This enables automatic -removal of abandoned cgroups. The default value of -notify_on_release in the root cgroup at system boot is disabled -(0). The default value of other cgroups at creation is the current -value of their parents notify_on_release setting. The default value of -a cgroup hierarchy's release_agent path is empty. - -1.5 How do I use cgroups ? --------------------------- - -To start a new job that is to be contained within a cgroup, using -the "cpuset" cgroup subsystem, the steps are something like: - - 1) mkdir /dev/cgroup - 2) mount -t cgroup -ocpuset cpuset /dev/cgroup - 3) Create the new cgroup by doing mkdir's and write's (or echo's) in - the /dev/cgroup virtual file system. - 4) Start a task that will be the "founding father" of the new job. - 5) Attach that task to the new cgroup by writing its pid to the - /dev/cgroup tasks file for that cgroup. - 6) fork, exec or clone the job tasks from this founding father task. - -For example, the following sequence of commands will setup a cgroup -named "Charlie", containing just CPUs 2 and 3, and Memory Node 1, -and then start a subshell 'sh' in that cgroup: - - mount -t cgroup cpuset -ocpuset /dev/cgroup - cd /dev/cgroup - mkdir Charlie - cd Charlie - /bin/echo 2-3 > cpus - /bin/echo 1 > mems - /bin/echo $$ > tasks - sh - # The subshell 'sh' is now running in cgroup Charlie - # The next line should display '/Charlie' - cat /proc/self/cgroup - -2. Usage Examples and Syntax -============================ - -2.1 Basic Usage ---------------- - -Creating, modifying, using the cgroups can be done through the cgroup -virtual filesystem. - -To mount a cgroup hierarchy will all available subsystems, type: -# mount -t cgroup xxx /dev/cgroup - -The "xxx" is not interpreted by the cgroup code, but will appear in -/proc/mounts so may be any useful identifying string that you like. - -To mount a cgroup hierarchy with just the cpuset and numtasks -subsystems, type: -# mount -t cgroup -o cpuset,numtasks hier1 /dev/cgroup - -To change the set of subsystems bound to a mounted hierarchy, just -remount with different options: - -# mount -o remount,cpuset,ns /dev/cgroup - -Note that changing the set of subsystems is currently only supported -when the hierarchy consists of a single (root) cgroup. Supporting -the ability to arbitrarily bind/unbind subsystems from an existing -cgroup hierarchy is intended to be implemented in the future. - -Then under /dev/cgroup you can find a tree that corresponds to the -tree of the cgroups in the system. For instance, /dev/cgroup -is the cgroup that holds the whole system. - -If you want to create a new cgroup under /dev/cgroup: -# cd /dev/cgroup -# mkdir my_cgroup - -Now you want to do something with this cgroup. -# cd my_cgroup - -In this directory you can find several files: -# ls -notify_on_release release_agent tasks -(plus whatever files are added by the attached subsystems) - -Now attach your shell to this cgroup: -# /bin/echo $$ > tasks - -You can also create cgroups inside your cgroup by using mkdir in this -directory. -# mkdir my_sub_cs - -To remove a cgroup, just use rmdir: -# rmdir my_sub_cs - -This will fail if the cgroup is in use (has cgroups inside, or -has processes attached, or is held alive by other subsystem-specific -reference). - -2.2 Attaching processes ------------------------ - -# /bin/echo PID > tasks - -Note that it is PID, not PIDs. You can only attach ONE task at a time. -If you have several tasks to attach, you have to do it one after another: - -# /bin/echo PID1 > tasks -# /bin/echo PID2 > tasks - ... -# /bin/echo PIDn > tasks - -3. Kernel API -============= - -3.1 Overview ------------- - -Each kernel subsystem that wants to hook into the generic cgroup -system needs to create a cgroup_subsys object. This contains -various methods, which are callbacks from the cgroup system, along -with a subsystem id which will be assigned by the cgroup system. - -Other fields in the cgroup_subsys object include: - -- subsys_id: a unique array index for the subsystem, indicating which - entry in cgroup->subsys[] this subsystem should be - managing. Initialized by cgroup_register_subsys(); prior to this - it should be initialized to -1 - -- hierarchy: an index indicating which hierarchy, if any, this - subsystem is currently attached to. If this is -1, then the - subsystem is not attached to any hierarchy, and all tasks should be - considered to be members of the subsystem's top_cgroup. It should - be initialized to -1. - -- name: should be initialized to a unique subsystem name prior to - calling cgroup_register_subsystem. Should be no longer than - MAX_CGROUP_TYPE_NAMELEN - -Each cgroup object created by the system has an array of pointers, -indexed by subsystem id; this pointer is entirely managed by the -subsystem; the generic cgroup code will never touch this pointer. - -3.2 Synchronization -------------------- - -There is a global mutex, cgroup_mutex, used by the cgroup -system. This should be taken by anything that wants to modify a -cgroup. It may also be taken to prevent cgroups from being -modified, but more specific locks may be more appropriate in that -situation. - -See kernel/cgroup.c for more details. - -Subsystems can take/release the cgroup_mutex via the functions -cgroup_lock()/cgroup_unlock(), and can -take/release the callback_mutex via the functions -cgroup_lock()/cgroup_unlock(). - -Accessing a task's cgroup pointer may be done in the following ways: -- while holding cgroup_mutex -- while holding the task's alloc_lock (via task_lock()) -- inside an rcu_read_lock() section via rcu_dereference() - -3.3 Subsystem API --------------------------- - -Each subsystem should: - -- add an entry in linux/cgroup_subsys.h -- define a cgroup_subsys object called _subsys - -Each subsystem may export the following methods. The only mandatory -methods are create/destroy. Any others that are null are presumed to -be successful no-ops. - -struct cgroup_subsys_state *create(struct cgroup *cont) -LL=cgroup_mutex - -Called to create a subsystem state object for a cgroup. The -subsystem should allocate its subsystem state object for the passed -cgroup, returning a pointer to the new object on success or a -negative error code. On success, the subsystem pointer should point to -a structure of type cgroup_subsys_state (typically embedded in a -larger subsystem-specific object), which will be initialized by the -cgroup system. Note that this will be called at initialization to -create the root subsystem state for this subsystem; this case can be -identified by the passed cgroup object having a NULL parent (since -it's the root of the hierarchy) and may be an appropriate place for -initialization code. - -void destroy(struct cgroup *cont) -LL=cgroup_mutex - -The cgroup system is about to destroy the passed cgroup; the -subsystem should do any necessary cleanup - -int can_attach(struct cgroup_subsys *ss, struct cgroup *cont, - struct task_struct *task) -LL=cgroup_mutex - -Called prior to moving a task into a cgroup; if the subsystem -returns an error, this will abort the attach operation. If a NULL -task is passed, then a successful result indicates that *any* -unspecified task can be moved into the cgroup. Note that this isn't -called on a fork. If this method returns 0 (success) then this should -remain valid while the caller holds cgroup_mutex. - -void attach(struct cgroup_subsys *ss, struct cgroup *cont, - struct cgroup *old_cont, struct task_struct *task) -LL=cgroup_mutex - - -Called after the task has been attached to the cgroup, to allow any -post-attachment activity that requires memory allocations or blocking. - -void fork(struct cgroup_subsy *ss, struct task_struct *task) -LL=callback_mutex, maybe read_lock(tasklist_lock) - -Called when a task is forked into a cgroup. Also called during -registration for all existing tasks. - -void exit(struct cgroup_subsys *ss, struct task_struct *task) -LL=callback_mutex - -Called during task exit - -int populate(struct cgroup_subsys *ss, struct cgroup *cont) -LL=none - -Called after creation of a cgroup to allow a subsystem to populate -the cgroup directory with file entries. The subsystem should make -calls to cgroup_add_file() with objects of type cftype (see -include/linux/cgroup.h for details). Note that although this -method can return an error code, the error code is currently not -always handled well. - -void post_clone(struct cgroup_subsys *ss, struct cgroup *cont) - -Called at the end of cgroup_clone() to do any paramater -initialization which might be required before a task could attach. For -example in cpusets, no task may attach before 'cpus' and 'mems' are set -up. - -void bind(struct cgroup_subsys *ss, struct cgroup *root) -LL=callback_mutex - -Called when a cgroup subsystem is rebound to a different hierarchy -and root cgroup. Currently this will only involve movement between -the default hierarchy (which never has sub-cgroups) and a hierarchy -that is being created/destroyed (and hence has no sub-cgroups). - -4. Questions -============ - -Q: what's up with this '/bin/echo' ? -A: bash's builtin 'echo' command does not check calls to write() against - errors. If you use it in the cgroup file system, you won't be - able to tell whether a command succeeded or failed. - -Q: When I attach processes, only the first of the line gets really attached ! -A: We can only return one error code per call to write(). So you should also - put only ONE pid. - diff --git a/trunk/Documentation/cpu-hotplug.txt b/trunk/Documentation/cpu-hotplug.txt index a741f658a3c9..b6d24c22274b 100644 --- a/trunk/Documentation/cpu-hotplug.txt +++ b/trunk/Documentation/cpu-hotplug.txt @@ -220,9 +220,7 @@ A: The following happen, listed in no particular order :-) CPU_DOWN_PREPARE or CPU_DOWN_PREPARE_FROZEN, depending on whether or not the CPU is being offlined while tasks are frozen due to a suspend operation in progress -- All processes are migrated away from this outgoing CPU to new CPUs. - The new CPU is chosen from each process' current cpuset, which may be - a subset of all online CPUs. +- All process is migrated away from this outgoing CPU to a new CPU - All interrupts targeted to this CPU is migrated to a new CPU - timers/bottom half/task lets are also migrated to a new CPU - Once all services are migrated, kernel calls an arch specific routine diff --git a/trunk/Documentation/cpusets.txt b/trunk/Documentation/cpusets.txt index 141bef1c8599..ec9de6917f01 100644 --- a/trunk/Documentation/cpusets.txt +++ b/trunk/Documentation/cpusets.txt @@ -7,7 +7,6 @@ Written by Simon.Derr@bull.net Portions Copyright (c) 2004-2006 Silicon Graphics, Inc. Modified by Paul Jackson Modified by Christoph Lameter -Modified by Paul Menage CONTENTS: ========= @@ -17,9 +16,9 @@ CONTENTS: 1.2 Why are cpusets needed ? 1.3 How are cpusets implemented ? 1.4 What are exclusive cpusets ? - 1.5 What is memory_pressure ? - 1.6 What is memory spread ? - 1.7 What is sched_load_balance ? + 1.5 What does notify_on_release do ? + 1.6 What is memory_pressure ? + 1.7 What is memory spread ? 1.8 How do I use cpusets ? 2. Usage Examples and Syntax 2.1 Basic Usage @@ -45,19 +44,18 @@ hierarchy visible in a virtual file system. These are the essential hooks, beyond what is already present, required to manage dynamic job placement on large systems. -Cpusets use the generic cgroup subsystem described in -Documentation/cgroup.txt. - -Requests by a task, using the sched_setaffinity(2) system call to -include CPUs in its CPU affinity mask, and using the mbind(2) and -set_mempolicy(2) system calls to include Memory Nodes in its memory -policy, are both filtered through that tasks cpuset, filtering out any -CPUs or Memory Nodes not in that cpuset. The scheduler will not -schedule a task on a CPU that is not allowed in its cpus_allowed -vector, and the kernel page allocator will not allocate a page on a -node that is not allowed in the requesting tasks mems_allowed vector. - -User level code may create and destroy cpusets by name in the cgroup +Each task has a pointer to a cpuset. Multiple tasks may reference +the same cpuset. Requests by a task, using the sched_setaffinity(2) +system call to include CPUs in its CPU affinity mask, and using the +mbind(2) and set_mempolicy(2) system calls to include Memory Nodes +in its memory policy, are both filtered through that tasks cpuset, +filtering out any CPUs or Memory Nodes not in that cpuset. The +scheduler will not schedule a task on a CPU that is not allowed in +its cpus_allowed vector, and the kernel page allocator will not +allocate a page on a node that is not allowed in the requesting tasks +mems_allowed vector. + +User level code may create and destroy cpusets by name in the cpuset virtual file system, manage the attributes and permissions of these cpusets and which CPUs and Memory Nodes are assigned to each cpuset, specify and query to which cpuset a task is assigned, and list the @@ -117,7 +115,7 @@ Cpusets extends these two mechanisms as follows: - Cpusets are sets of allowed CPUs and Memory Nodes, known to the kernel. - Each task in the system is attached to a cpuset, via a pointer - in the task structure to a reference counted cgroup structure. + in the task structure to a reference counted cpuset structure. - Calls to sched_setaffinity are filtered to just those CPUs allowed in that tasks cpuset. - Calls to mbind and set_mempolicy are filtered to just @@ -147,10 +145,15 @@ into the rest of the kernel, none in performance critical paths: - in page_alloc.c, to restrict memory to allowed nodes. - in vmscan.c, to restrict page recovery to the current cpuset. -You should mount the "cgroup" filesystem type in order to enable -browsing and modifying the cpusets presently known to the kernel. No -new system calls are added for cpusets - all support for querying and -modifying cpusets is via this cpuset file system. +In addition a new file system, of type "cpuset" may be mounted, +typically at /dev/cpuset, to enable browsing and modifying the cpusets +presently known to the kernel. No new system calls are added for +cpusets - all support for querying and modifying cpusets is via +this cpuset file system. + +Each task under /proc has an added file named 'cpuset', displaying +the cpuset name, as the path relative to the root of the cpuset file +system. The /proc//status file for each task has two added lines, displaying the tasks cpus_allowed (on which CPUs it may be scheduled) @@ -160,15 +163,16 @@ in the format seen in the following example: Cpus_allowed: ffffffff,ffffffff,ffffffff,ffffffff Mems_allowed: ffffffff,ffffffff -Each cpuset is represented by a directory in the cgroup file system -containing (on top of the standard cgroup files) the following -files describing that cpuset: +Each cpuset is represented by a directory in the cpuset file system +containing the following files describing that cpuset: - cpus: list of CPUs in that cpuset - mems: list of Memory Nodes in that cpuset - memory_migrate flag: if set, move pages to cpusets nodes - cpu_exclusive flag: is cpu placement exclusive? - mem_exclusive flag: is memory placement exclusive? + - tasks: list of tasks (by pid) attached to that cpuset + - notify_on_release flag: run /sbin/cpuset_release_agent on exit? - memory_pressure: measure of how much paging pressure in cpuset In addition, the root cpuset only has the following file: @@ -233,7 +237,21 @@ such as requests from interrupt handlers, is allowed to be taken outside even a mem_exclusive cpuset. -1.5 What is memory_pressure ? +1.5 What does notify_on_release do ? +------------------------------------ + +If the notify_on_release flag is enabled (1) in a cpuset, then whenever +the last task in the cpuset leaves (exits or attaches to some other +cpuset) and the last child cpuset of that cpuset is removed, then +the kernel runs the command /sbin/cpuset_release_agent, supplying the +pathname (relative to the mount point of the cpuset file system) of the +abandoned cpuset. This enables automatic removal of abandoned cpusets. +The default value of notify_on_release in the root cpuset at system +boot is disabled (0). The default value of other cpusets at creation +is the current value of their parents notify_on_release setting. + + +1.6 What is memory_pressure ? ----------------------------- The memory_pressure of a cpuset provides a simple per-cpuset metric of the rate that the tasks in a cpuset are attempting to free up in @@ -290,7 +308,7 @@ the tasks in the cpuset, in units of reclaims attempted per second, times 1000. -1.6 What is memory spread ? +1.7 What is memory spread ? --------------------------- There are two boolean flag files per cpuset that control where the kernel allocates pages for the file system buffers and related in @@ -360,142 +378,6 @@ policy, especially for jobs that might have one thread reading in the data set, the memory allocation across the nodes in the jobs cpuset can become very uneven. -1.7 What is sched_load_balance ? --------------------------------- - -The kernel scheduler (kernel/sched.c) automatically load balances -tasks. If one CPU is underutilized, kernel code running on that -CPU will look for tasks on other more overloaded CPUs and move those -tasks to itself, within the constraints of such placement mechanisms -as cpusets and sched_setaffinity. - -The algorithmic cost of load balancing and its impact on key shared -kernel data structures such as the task list increases more than -linearly with the number of CPUs being balanced. So the scheduler -has support to partition the systems CPUs into a number of sched -domains such that it only load balances within each sched domain. -Each sched domain covers some subset of the CPUs in the system; -no two sched domains overlap; some CPUs might not be in any sched -domain and hence won't be load balanced. - -Put simply, it costs less to balance between two smaller sched domains -than one big one, but doing so means that overloads in one of the -two domains won't be load balanced to the other one. - -By default, there is one sched domain covering all CPUs, except those -marked isolated using the kernel boot time "isolcpus=" argument. - -This default load balancing across all CPUs is not well suited for -the following two situations: - 1) On large systems, load balancing across many CPUs is expensive. - If the system is managed using cpusets to place independent jobs - on separate sets of CPUs, full load balancing is unnecessary. - 2) Systems supporting realtime on some CPUs need to minimize - system overhead on those CPUs, including avoiding task load - balancing if that is not needed. - -When the per-cpuset flag "sched_load_balance" is enabled (the default -setting), it requests that all the CPUs in that cpusets allowed 'cpus' -be contained in a single sched domain, ensuring that load balancing -can move a task (not otherwised pinned, as by sched_setaffinity) -from any CPU in that cpuset to any other. - -When the per-cpuset flag "sched_load_balance" is disabled, then the -scheduler will avoid load balancing across the CPUs in that cpuset, ---except-- in so far as is necessary because some overlapping cpuset -has "sched_load_balance" enabled. - -So, for example, if the top cpuset has the flag "sched_load_balance" -enabled, then the scheduler will have one sched domain covering all -CPUs, and the setting of the "sched_load_balance" flag in any other -cpusets won't matter, as we're already fully load balancing. - -Therefore in the above two situations, the top cpuset flag -"sched_load_balance" should be disabled, and only some of the smaller, -child cpusets have this flag enabled. - -When doing this, you don't usually want to leave any unpinned tasks in -the top cpuset that might use non-trivial amounts of CPU, as such tasks -may be artificially constrained to some subset of CPUs, depending on -the particulars of this flag setting in descendent cpusets. Even if -such a task could use spare CPU cycles in some other CPUs, the kernel -scheduler might not consider the possibility of load balancing that -task to that underused CPU. - -Of course, tasks pinned to a particular CPU can be left in a cpuset -that disables "sched_load_balance" as those tasks aren't going anywhere -else anyway. - -There is an impedance mismatch here, between cpusets and sched domains. -Cpusets are hierarchical and nest. Sched domains are flat; they don't -overlap and each CPU is in at most one sched domain. - -It is necessary for sched domains to be flat because load balancing -across partially overlapping sets of CPUs would risk unstable dynamics -that would be beyond our understanding. So if each of two partially -overlapping cpusets enables the flag 'sched_load_balance', then we -form a single sched domain that is a superset of both. We won't move -a task to a CPU outside it cpuset, but the scheduler load balancing -code might waste some compute cycles considering that possibility. - -This mismatch is why there is not a simple one-to-one relation -between which cpusets have the flag "sched_load_balance" enabled, -and the sched domain configuration. If a cpuset enables the flag, it -will get balancing across all its CPUs, but if it disables the flag, -it will only be assured of no load balancing if no other overlapping -cpuset enables the flag. - -If two cpusets have partially overlapping 'cpus' allowed, and only -one of them has this flag enabled, then the other may find its -tasks only partially load balanced, just on the overlapping CPUs. -This is just the general case of the top_cpuset example given a few -paragraphs above. In the general case, as in the top cpuset case, -don't leave tasks that might use non-trivial amounts of CPU in -such partially load balanced cpusets, as they may be artificially -constrained to some subset of the CPUs allowed to them, for lack of -load balancing to the other CPUs. - -1.7.1 sched_load_balance implementation details. ------------------------------------------------- - -The per-cpuset flag 'sched_load_balance' defaults to enabled (contrary -to most cpuset flags.) When enabled for a cpuset, the kernel will -ensure that it can load balance across all the CPUs in that cpuset -(makes sure that all the CPUs in the cpus_allowed of that cpuset are -in the same sched domain.) - -If two overlapping cpusets both have 'sched_load_balance' enabled, -then they will be (must be) both in the same sched domain. - -If, as is the default, the top cpuset has 'sched_load_balance' enabled, -then by the above that means there is a single sched domain covering -the whole system, regardless of any other cpuset settings. - -The kernel commits to user space that it will avoid load balancing -where it can. It will pick as fine a granularity partition of sched -domains as it can while still providing load balancing for any set -of CPUs allowed to a cpuset having 'sched_load_balance' enabled. - -The internal kernel cpuset to scheduler interface passes from the -cpuset code to the scheduler code a partition of the load balanced -CPUs in the system. This partition is a set of subsets (represented -as an array of cpumask_t) of CPUs, pairwise disjoint, that cover all -the CPUs that must be load balanced. - -Whenever the 'sched_load_balance' flag changes, or CPUs come or go -from a cpuset with this flag enabled, or a cpuset with this flag -enabled is removed, the cpuset code builds a new such partition and -passes it to the scheduler sched domain setup code, to have the sched -domains rebuilt as necessary. - -This partition exactly defines what sched domains the scheduler should -setup - one sched domain for each element (cpumask_t) in the partition. - -The scheduler remembers the currently active sched domain partitions. -When the scheduler routine partition_sched_domains() is invoked from -the cpuset code to update these sched domains, it compares the new -partition requested with the current, and updates its sched domains, -removing the old and adding the new, for each change. 1.8 How do I use cpusets ? -------------------------- @@ -587,7 +469,7 @@ than stress the kernel. To start a new job that is to be contained within a cpuset, the steps are: 1) mkdir /dev/cpuset - 2) mount -t cgroup -ocpuset cpuset /dev/cpuset + 2) mount -t cpuset none /dev/cpuset 3) Create the new cpuset by doing mkdir's and write's (or echo's) in the /dev/cpuset virtual file system. 4) Start a task that will be the "founding father" of the new job. @@ -599,7 +481,7 @@ For example, the following sequence of commands will setup a cpuset named "Charlie", containing just CPUs 2 and 3, and Memory Node 1, and then start a subshell 'sh' in that cpuset: - mount -t cgroup -ocpuset cpuset /dev/cpuset + mount -t cpuset none /dev/cpuset cd /dev/cpuset mkdir Charlie cd Charlie @@ -631,7 +513,7 @@ Creating, modifying, using the cpusets can be done through the cpuset virtual filesystem. To mount it, type: -# mount -t cgroup -o cpuset cpuset /dev/cpuset +# mount -t cpuset none /dev/cpuset Then under /dev/cpuset you can find a tree that corresponds to the tree of the cpusets in the system. For instance, /dev/cpuset @@ -674,18 +556,6 @@ To remove a cpuset, just use rmdir: This will fail if the cpuset is in use (has cpusets inside, or has processes attached). -Note that for legacy reasons, the "cpuset" filesystem exists as a -wrapper around the cgroup filesystem. - -The command - -mount -t cpuset X /dev/cpuset - -is equivalent to - -mount -t cgroup -ocpuset X /dev/cpuset -echo "/sbin/cpuset_release_agent" > /dev/cpuset/release_agent - 2.2 Adding/removing cpus ------------------------ diff --git a/trunk/Documentation/feature-removal-schedule.txt b/trunk/Documentation/feature-removal-schedule.txt index 6b0f963f5379..280ec06573e6 100644 --- a/trunk/Documentation/feature-removal-schedule.txt +++ b/trunk/Documentation/feature-removal-schedule.txt @@ -82,41 +82,6 @@ Who: Dominik Brodowski --------------------------- -What: sys_sysctl -When: September 2010 -Option: CONFIG_SYSCTL_SYSCALL -Why: The same information is available in a more convenient from - /proc/sys, and none of the sysctl variables appear to be - important performance wise. - - Binary sysctls are a long standing source of subtle kernel - bugs and security issues. - - When I looked several months ago all I could find after - searching several distributions were 5 user space programs and - glibc (which falls back to /proc/sys) using this syscall. - - The man page for sysctl(2) documents it as unusable for user - space programs. - - sysctl(2) is not generally ABI compatible to a 32bit user - space application on a 64bit and a 32bit kernel. - - For the last several months the policy has been no new binary - sysctls and no one has put forward an argument to use them. - - Binary sysctls issues seem to keep happening appearing so - properly deprecating them (with a warning to user space) and a - 2 year grace warning period will mean eventually we can kill - them and end the pain. - - In the mean time individual binary sysctls can be dealt with - in a piecewise fashion. - -Who: Eric Biederman - ---------------------------- - What: a.out interpreter support for ELF executables When: 2.6.25 Files: fs/binfmt_elf.c @@ -219,6 +184,13 @@ Who: Jean Delvare , --------------------------- +What: drivers depending on OBSOLETE_OSS +When: options in 2.6.22, code in 2.6.24 +Why: OSS drivers with ALSA replacements +Who: Adrian Bunk + +--------------------------- + What: ACPI procfs interface When: July 2008 Why: ACPI sysfs conversion should be finished by January 2008. diff --git a/trunk/Documentation/input/input-programming.txt b/trunk/Documentation/input/input-programming.txt index 4d932dc66098..d9d523099bb7 100644 --- a/trunk/Documentation/input/input-programming.txt +++ b/trunk/Documentation/input/input-programming.txt @@ -42,8 +42,8 @@ static int __init button_init(void) goto err_free_irq; } - button_dev->evbit[0] = BIT_MASK(EV_KEY); - button_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0); + button_dev->evbit[0] = BIT(EV_KEY); + button_dev->keybit[LONG(BTN_0)] = BIT(BTN_0); error = input_register_device(button_dev); if (error) { @@ -217,15 +217,14 @@ If you don't need absfuzz and absflat, you can set them to zero, which mean that the thing is precise and always returns to exactly the center position (if it has any). -1.4 BITS_TO_LONGS(), BIT_WORD(), BIT_MASK() +1.4 NBITS(), LONG(), BIT() ~~~~~~~~~~~~~~~~~~~~~~~~~~ -These three macros from bitops.h help some bitfield computations: +These three macros from input.h help some bitfield computations: - BITS_TO_LONGS(x) - returns the length of a bitfield array in longs for - x bits - BIT_WORD(x) - returns the index in the array in longs for bit x - BIT_MASK(x) - returns the index in a long for bit x + NBITS(x) - returns the length of a bitfield array in longs for x bits + LONG(x) - returns the index in the array in longs for bit x + BIT(x) - returns the index in a long for bit x 1.5 The id* and name fields ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/trunk/Documentation/kdump/kdump.txt b/trunk/Documentation/kdump/kdump.txt index d0ac72cc19ff..1b37b28cc234 100644 --- a/trunk/Documentation/kdump/kdump.txt +++ b/trunk/Documentation/kdump/kdump.txt @@ -231,32 +231,6 @@ Dump-capture kernel config options (Arch Dependent, ia64) any space below the alignment point will be wasted. -Extended crashkernel syntax -=========================== - -While the "crashkernel=size[@offset]" syntax is sufficient for most -configurations, sometimes it's handy to have the reserved memory dependent -on the value of System RAM -- that's mostly for distributors that pre-setup -the kernel command line to avoid a unbootable system after some memory has -been removed from the machine. - -The syntax is: - - crashkernel=:[,:,...][@offset] - range=start-[end] - -For example: - - crashkernel=512M-2G:64M,2G-:128M - -This would mean: - - 1) if the RAM is smaller than 512M, then don't reserve anything - (this is the "rescue" case) - 2) if the RAM size is between 512M and 2G, then reserve 64M - 3) if the RAM size is larger than 2G, then reserve 128M - - Boot into System Kernel ======================= diff --git a/trunk/Documentation/kernel-parameters.txt b/trunk/Documentation/kernel-parameters.txt index 0a3fed445249..98cf90f2631d 100644 --- a/trunk/Documentation/kernel-parameters.txt +++ b/trunk/Documentation/kernel-parameters.txt @@ -479,16 +479,6 @@ and is between 256 and 4096 characters. It is defined in the file UART at the specified I/O port or MMIO address. The options are the same as for ttyS, above. - no_console_suspend - [HW] Never suspend the console - Disable suspending of consoles during suspend and - hibernate operations. Once disabled, debugging - messages can reach various consoles while the rest - of the system is being put to sleep (ie, while - debugging driver suspend/resume hooks). This may - not work reliably with all consoles, but is known - to work with serial and VGA consoles. - cpcihp_generic= [HW,PCI] Generic port I/O CompactPCI driver Format: ,,,[,] @@ -497,13 +487,6 @@ and is between 256 and 4096 characters. It is defined in the file [KNL] Reserve a chunk of physical memory to hold a kernel to switch to with kexec on panic. - crashkernel=range1:size1[,range2:size2,...][@offset] - [KNL] Same as above, but depends on the memory - in the running system. The syntax of range is - start-[end] where start and end are both - a memory unit (amount[KMG]). See also - Documentation/kdump/kdump.txt for a example. - cs4232= [HW,OSS] Format: ,,,,, diff --git a/trunk/Documentation/markers.txt b/trunk/Documentation/markers.txt deleted file mode 100644 index 295a71bc301e..000000000000 --- a/trunk/Documentation/markers.txt +++ /dev/null @@ -1,81 +0,0 @@ - Using the Linux Kernel Markers - - Mathieu Desnoyers - - -This document introduces Linux Kernel Markers and their use. It provides -examples of how to insert markers in the kernel and connect probe functions to -them and provides some examples of probe functions. - - -* Purpose of markers - -A marker placed in code provides a hook to call a function (probe) that you can -provide at runtime. A marker can be "on" (a probe is connected to it) or "off" -(no probe is attached). When a marker is "off" it has no effect, except for -adding a tiny time penalty (checking a condition for a branch) and space -penalty (adding a few bytes for the function call at the end of the -instrumented function and adds a data structure in a separate section). When a -marker is "on", the function you provide is called each time the marker is -executed, in the execution context of the caller. When the function provided -ends its execution, it returns to the caller (continuing from the marker site). - -You can put markers at important locations in the code. Markers are -lightweight hooks that can pass an arbitrary number of parameters, -described in a printk-like format string, to the attached probe function. - -They can be used for tracing and performance accounting. - - -* Usage - -In order to use the macro trace_mark, you should include linux/marker.h. - -#include - -And, - -trace_mark(subsystem_event, "%d %s", someint, somestring); -Where : -- subsystem_event is an identifier unique to your event - - subsystem is the name of your subsystem. - - event is the name of the event to mark. -- "%d %s" is the formatted string for the serializer. -- someint is an integer. -- somestring is a char pointer. - -Connecting a function (probe) to a marker is done by providing a probe (function -to call) for the specific marker through marker_probe_register() and can be -activated by calling marker_arm(). Marker deactivation can be done by calling -marker_disarm() as many times as marker_arm() has been called. Removing a probe -is done through marker_probe_unregister(); it will disarm the probe and make -sure there is no caller left using the probe when it returns. Probe removal is -preempt-safe because preemption is disabled around the probe call. See the -"Probe example" section below for a sample probe module. - -The marker mechanism supports inserting multiple instances of the same marker. -Markers can be put in inline functions, inlined static functions, and -unrolled loops as well as regular functions. - -The naming scheme "subsystem_event" is suggested here as a convention intended -to limit collisions. Marker names are global to the kernel: they are considered -as being the same whether they are in the core kernel image or in modules. -Conflicting format strings for markers with the same name will cause the markers -to be detected to have a different format string not to be armed and will output -a printk warning which identifies the inconsistency: - -"Format mismatch for probe probe_name (format), marker (format)" - - -* Probe / marker example - -See the example provided in samples/markers/src - -Compile them with your kernel. - -Run, as root : -modprobe marker-example (insmod order is not important) -modprobe probe-example -cat /proc/marker-example (returns an expected error) -rmmod marker-example probe-example -dmesg diff --git a/trunk/Documentation/memory-barriers.txt b/trunk/Documentation/memory-barriers.txt index 4e17beba2379..650657c54733 100644 --- a/trunk/Documentation/memory-barriers.txt +++ b/trunk/Documentation/memory-barriers.txt @@ -1479,8 +1479,7 @@ kernel. Any atomic operation that modifies some state in memory and returns information about the state (old or new) implies an SMP-conditional general memory barrier -(smp_mb()) on each side of the actual operation (with the exception of -explicit lock operations, described later). These include: +(smp_mb()) on each side of the actual operation. These include: xchg(); cmpxchg(); @@ -1537,19 +1536,10 @@ If they're used for constructing a lock of some description, then they probably do need memory barriers as a lock primitive generally has to do things in a specific order. + Basically, each usage case has to be carefully considered as to whether memory barriers are needed or not. -The following operations are special locking primitives: - - test_and_set_bit_lock(); - clear_bit_unlock(); - __clear_bit_unlock(); - -These implement LOCK-class and UNLOCK-class operations. These should be used in -preference to other operations when implementing locking primitives, because -their implementations can be optimised on many architectures. - [!] Note that special memory barrier primitives are available for these situations because on some CPUs the atomic instructions used imply full memory barriers, and so barrier instructions are superfluous in conjunction with them, diff --git a/trunk/Documentation/mips/00-INDEX b/trunk/Documentation/mips/00-INDEX index 3f13bf8043d2..9df8a2eac7b4 100644 --- a/trunk/Documentation/mips/00-INDEX +++ b/trunk/Documentation/mips/00-INDEX @@ -4,3 +4,5 @@ AU1xxx_IDE.README - README for MIPS AU1XXX IDE driver. GT64120.README - README for dir with info on MIPS boards using GT-64120 or GT-64120A. +time.README + - README for MIPS time services. diff --git a/trunk/Documentation/mips/time.README b/trunk/Documentation/mips/time.README new file mode 100644 index 000000000000..a4ce603ed3b3 --- /dev/null +++ b/trunk/Documentation/mips/time.README @@ -0,0 +1,173 @@ +README for MIPS time services + +Jun Sun +jsun@mvista.com or jsun@junsun.net + + +ABOUT +----- +This file describes the new arch/mips/kernel/time.c, related files and the +services they provide. + +If you are short in patience and just want to know how to use time.c for a +new board or convert an existing board, go to the last section. + + +FILES, COMPATABILITY AND CONFIGS +--------------------------------- + +The old arch/mips/kernel/time.c is renamed to old-time.c. + +A new time.c is put there, together with include/asm-mips/time.h. + +Two configs variables are introduced, CONFIG_OLD_TIME_C and CONFIG_NEW_TIME_C. +So we allow boards using + + 1) old time.c (CONFIG_OLD_TIME_C) + 2) new time.c (CONFIG_NEW_TIME_C) + 3) neither (their own private time.c) + +However, it is expected every board will move to the new time.c in the near +future. + + +WHAT THE NEW CODE PROVIDES? +--------------------------- + +The new time code provide the following services: + + a) Implements functions required by Linux common code: + time_init + + b) provides an abstraction of RTC and null RTC implementation as default. + extern unsigned long (*rtc_get_time)(void); + extern int (*rtc_set_time)(unsigned long); + + c) high-level and low-level timer interrupt routines where the timer + interrupt source may or may not be the CPU timer. The high-level + routine is dispatched through do_IRQ() while the low-level is + dispatched in assemably code (usually int-handler.S) + + +WHAT THE NEW CODE REQUIRES? +--------------------------- + +For the new code to work properly, each board implementation needs to supply +the following functions or values: + + a) board_time_init - a function pointer. Invoked at the beginnig of + time_init(). It is optional. + 1. (optional) set up RTC routines + 2. (optional) calibrate and set the mips_hpt_frequency + + b) plat_timer_setup - a function pointer. Invoked at the end of time_init() + 1. (optional) over-ride any decisions made in time_init() + 2. set up the irqaction for timer interrupt. + 3. enable the timer interrupt + + c) (optional) board-specific RTC routines. + + d) (optional) mips_hpt_frequency - It must be definied if the board + is using CPU counter for timer interrupt. + + +PORTING GUIDE +------------- + +Step 1: decide how you like to implement the time services. + + a) does this board have a RTC? If yes, implement the two RTC funcs. + + b) does the CPU have counter/compare registers? + + If the answer is no, you need a timer to provide the timer interrupt + at 100 HZ speed. + + c) The following sub steps assume your CPU has counter register. + Do you plan to use the CPU counter register as the timer interrupt + or use an exnternal timer? + + In order to use CPU counter register as the timer interrupt source, you + must know the counter speed (mips_hpt_frequency). It is usually the + same as the CPU speed or an integral divisor of it. + + d) decide on whether you want to use high-level or low-level timer + interrupt routines. The low-level one is presumably faster, but should + not make too mcuh difference. + + +Step 2: the machine setup() function + + If you supply board_time_init(), set the function poointer. + + +Step 3: implement rtc routines, board_time_init() and plat_timer_setup() + if needed. + + board_time_init() - + a) (optional) set up RTC routines, + b) (optional) calibrate and set the mips_hpt_frequency + (only needed if you intended to use cpu counter as timer interrupt + source) + + plat_timer_setup() - + a) (optional) over-write any choices made above by time_init(). + b) machine specific code should setup the timer irqaction. + c) enable the timer interrupt + + + If the RTC chip is a common chip, I suggest the routines are put under + arch/mips/libs. For example, for DS1386 chip, one would create + rtc-ds1386.c under arch/mips/lib directory. Add the following line to + the arch/mips/lib/Makefile: + + obj-$(CONFIG_DDB5476) += rtc-ds1386.o + +Step 4: if you are using low-level timer interrupt, change your interrupt + dispathcing code to check for timer interrupt and jump to + ll_timer_interrupt() directly if one is detected. + +Step 5: Modify arch/mips/config.in and add CONFIG_NEW_TIME_C to your machine. + Modify the appropriate defconfig if applicable. + +Final notes: + +For some tricky cases, you may need to add your own wrapper functions +for some of the functions in time.c. + +For example, you may define your own timer interrupt routine, which does +some of its own processing and then calls timer_interrupt(). + +You can also over-ride any of the built-in functions (RTC routines +and/or timer interrupt routine). + + +PORTING NOTES FOR SMP +---------------------- + +If you have a SMP box, things are slightly more complicated. + +The time service running every jiffy is logically divided into two parts: + + 1) the one for the whole system (defined in timer_interrupt()) + 2) the one that should run for each CPU (defined in local_timer_interrupt()) + +You need to decide on your timer interrupt sources. + + case 1) - whole system has only one timer interrupt delivered to one CPU + + In this case, you set up timer interrupt as in UP systems. In addtion, + you need to set emulate_local_timer_interrupt to 1 so that other + CPUs get to call local_timer_interrupt(). + + THIS IS CURRENTLY NOT IMPLEMNETED. However, it is rather easy to write + one should such a need arise. You simply make a IPI call. + + case 2) - each CPU has a separate timer interrupt + + In this case, you need to set up IRQ such that each of them will + call local_timer_interrupt(). In addition, you need to arrange + one and only one of them to call timer_interrupt(). + + You can also do the low-level version of those interrupt routines, + following similar dispatching routes described above. diff --git a/trunk/Documentation/parport-lowlevel.txt b/trunk/Documentation/parport-lowlevel.txt index 265fcdcb8e5f..8f2302415eff 100644 --- a/trunk/Documentation/parport-lowlevel.txt +++ b/trunk/Documentation/parport-lowlevel.txt @@ -25,6 +25,7 @@ Global functions: parport_open parport_close parport_device_id + parport_device_num parport_device_coords parport_find_class parport_find_device @@ -734,7 +735,7 @@ NULL is returned. SEE ALSO -parport_register_device +parport_register_device, parport_device_num parport_close - unregister device for particular device number ------------- @@ -786,7 +787,29 @@ Many devices have ill-formed IEEE 1284 Device IDs. SEE ALSO -parport_find_class, parport_find_device +parport_find_class, parport_find_device, parport_device_num + +parport_device_num - convert device coordinates to device number +------------------ + +SYNOPSIS + +#include + +int parport_device_num (int parport, int mux, int daisy); + +DESCRIPTION + +Convert between device coordinates (port, multiplexor, daisy chain +address) and device number (zero-based). + +RETURN VALUE + +Device number, or -1 if no device at given coordinates. + +SEE ALSO + +parport_device_coords, parport_open, parport_device_id parport_device_coords - convert device number to device coordinates ------------------ @@ -810,7 +833,7 @@ Zero on success, in which case the coordinates are (*parport, *mux, SEE ALSO -parport_open, parport_device_id +parport_device_num, parport_open, parport_device_id parport_find_class - find a device by its class ------------------ diff --git a/trunk/Documentation/power/basic-pm-debugging.txt b/trunk/Documentation/power/basic-pm-debugging.txt index 57aef2f6e0de..1a85e2b964dc 100644 --- a/trunk/Documentation/power/basic-pm-debugging.txt +++ b/trunk/Documentation/power/basic-pm-debugging.txt @@ -78,8 +78,8 @@ c) Advanced debugging In case the STD does not work on your system even in the minimal configuration and compiling more drivers as modules is not practical or some modules cannot be unloaded, you can use one of the more advanced debugging techniques to find -the problem. First, if there is a serial port in your box, you can boot the -kernel with the 'no_console_suspend' parameter and try to log kernel +the problem. First, if there is a serial port in your box, you can set the +CONFIG_DISABLE_CONSOLE_SUSPEND kernel configuration option and try to log kernel messages using the serial console. This may provide you with some information about the reasons of the suspend (resume) failure. Alternatively, it may be possible to use a FireWire port for debugging with firescope diff --git a/trunk/Documentation/power/freezing-of-tasks.txt b/trunk/Documentation/power/freezing-of-tasks.txt index 38b57248fd61..04dc1cf9d215 100644 --- a/trunk/Documentation/power/freezing-of-tasks.txt +++ b/trunk/Documentation/power/freezing-of-tasks.txt @@ -19,13 +19,12 @@ we only consider hibernation, but the description also applies to suspend). Namely, as the first step of the hibernation procedure the function freeze_processes() (defined in kernel/power/process.c) is called. It executes try_to_freeze_tasks() that sets TIF_FREEZE for all of the freezable tasks and -either wakes them up, if they are kernel threads, or sends fake signals to them, -if they are user space processes. A task that has TIF_FREEZE set, should react -to it by calling the function called refrigerator() (defined in -kernel/power/process.c), which sets the task's PF_FROZEN flag, changes its state -to TASK_UNINTERRUPTIBLE and makes it loop until PF_FROZEN is cleared for it. -Then, we say that the task is 'frozen' and therefore the set of functions -handling this mechanism is referred to as 'the freezer' (these functions are +sends a fake signal to each of them. A task that receives such a signal and has +TIF_FREEZE set, should react to it by calling the refrigerator() function +(defined in kernel/power/process.c), which sets the task's PF_FROZEN flag, +changes its state to TASK_UNINTERRUPTIBLE and makes it loop until PF_FROZEN is +cleared for it. Then, we say that the task is 'frozen' and therefore the set of +functions handling this mechanism is called 'the freezer' (these functions are defined in kernel/power/process.c and include/linux/freezer.h). User space processes are generally frozen before kernel threads. @@ -36,27 +35,21 @@ task enter refrigerator() if the flag is set. For user space processes try_to_freeze() is called automatically from the signal-handling code, but the freezable kernel threads need to call it -explicitly in suitable places or use the wait_event_freezable() or -wait_event_freezable_timeout() macros (defined in include/linux/freezer.h) -that combine interruptible sleep with checking if TIF_FREEZE is set and calling -try_to_freeze(). The main loop of a freezable kernel thread may look like the -following one: +explicitly in suitable places. The code to do this may look like the following: - set_freezable(); do { hub_events(); - wait_event_freezable(khubd_wait, - !list_empty(&hub_event_list) || - kthread_should_stop()); - } while (!kthread_should_stop() || !list_empty(&hub_event_list)); + wait_event_interruptible(khubd_wait, + !list_empty(&hub_event_list)); + try_to_freeze(); + } while (!signal_pending(current)); (from drivers/usb/core/hub.c::hub_thread()). If a freezable kernel thread fails to call try_to_freeze() after the freezer has set TIF_FREEZE for it, the freezing of tasks will fail and the entire hibernation operation will be cancelled. For this reason, freezable kernel -threads must call try_to_freeze() somewhere or use one of the -wait_event_freezable() and wait_event_freezable_timeout() macros. +threads must call try_to_freeze() somewhere. After the system memory state has been restored from a hibernation image and devices have been reinitialized, the function thaw_processes() is called in @@ -88,16 +81,7 @@ hibernation image has been created and before the system is finally powered off. The majority of these are user space processes, but if any of the kernel threads may cause something like this to happen, they have to be freezable. -2. Next, to create the hibernation image we need to free a sufficient amount of -memory (approximately 50% of available RAM) and we need to do that before -devices are deactivated, because we generally need them for swapping out. Then, -after the memory for the image has been freed, we don't want tasks to allocate -additional memory and we prevent them from doing that by freezing them earlier. -[Of course, this also means that device drivers should not allocate substantial -amounts of memory from their .suspend() callbacks before hibernation, but this -is e separate issue.] - -3. The third reason is to prevent user space processes and some kernel threads +2. The second reason is to prevent user space processes and some kernel threads from interfering with the suspending and resuming of devices. A user space process running on a second CPU while we are suspending devices may, for example, be troublesome and without the freezing of tasks we would need some @@ -127,7 +111,7 @@ frozen before the driver's .suspend() callback is executed and it will be thawed after the driver's .resume() callback has run, so it won't be accessing the device while it's suspended. -4. Another reason for freezing tasks is to prevent user space processes from +3. Another reason for freezing tasks is to prevent user space processes from realizing that hibernation (or suspend) operation takes place. Ideally, user space processes should not notice that such a system-wide operation has occurred and should continue running without any problems after the restore (or resume diff --git a/trunk/Documentation/power/interface.txt b/trunk/Documentation/power/interface.txt index e67211fe0ee2..fd5192a8fa8a 100644 --- a/trunk/Documentation/power/interface.txt +++ b/trunk/Documentation/power/interface.txt @@ -20,7 +20,7 @@ states. /sys/power/disk controls the operating mode of the suspend-to-disk mechanism. Suspend-to-disk can be handled in several ways. We have a few options for putting the system to sleep - using the platform driver -(e.g. ACPI or other suspend_ops), powering off the system or rebooting the +(e.g. ACPI or other pm_ops), powering off the system or rebooting the system (for testing). Additionally, /sys/power/disk can be used to turn on one of the two testing diff --git a/trunk/Documentation/sound/oss/es1371 b/trunk/Documentation/sound/oss/es1371 new file mode 100644 index 000000000000..c3151266771c --- /dev/null +++ b/trunk/Documentation/sound/oss/es1371 @@ -0,0 +1,64 @@ +/proc/sound, /dev/sndstat +------------------------- + +/proc/sound and /dev/sndstat is not supported by the +driver. To find out whether the driver succeeded loading, +check the kernel log (dmesg). + + +ALaw/uLaw sample formats +------------------------ + +This driver does not support the ALaw/uLaw sample formats. +ALaw is the default mode when opening a sound device +using OSS/Free. The reason for the lack of support is +that the hardware does not support these formats, and adding +conversion routines to the kernel would lead to very ugly +code in the presence of the mmap interface to the driver. +And since xquake uses mmap, mmap is considered important :-) +and no sane application uses ALaw/uLaw these days anyway. +In short, playing a Sun .au file as follows: + +cat my_file.au > /dev/dsp + +does not work. Instead, you may use the play script from +Chris Bagwell's sox-12.14 package (available from the URL +below) to play many different audio file formats. +The script automatically determines the audio format +and does do audio conversions if necessary. +http://home.sprynet.com/sprynet/cbagwell/projects.html + + +Blocking vs. nonblocking IO +--------------------------- + +Unlike OSS/Free this driver honours the O_NONBLOCK file flag +not only during open, but also during read and write. +This is an effort to make the sound driver interface more +regular. Timidity has problems with this; a patch +is available from http://www.ife.ee.ethz.ch/~sailer/linux/pciaudio.html. +(Timidity patched will also run on OSS/Free). + + +MIDI UART +--------- + +The driver supports a simple MIDI UART interface, with +no ioctl's supported. + + +MIDI synthesizer +---------------- + +This soundcard does not have any hardware MIDI synthesizer; +MIDI synthesis has to be done in software. To allow this +the driver/soundcard supports two PCM (/dev/dsp) interfaces. + +There is a freely available software package that allows +MIDI file playback on this soundcard called Timidity. +See http://www.cgs.fi/~tt/timidity/. + + + +Thomas Sailer +t.sailer@alumni.ethz.ch diff --git a/trunk/Documentation/thinkpad-acpi.txt b/trunk/Documentation/thinkpad-acpi.txt index 3b95bbacc775..60953d6c919d 100644 --- a/trunk/Documentation/thinkpad-acpi.txt +++ b/trunk/Documentation/thinkpad-acpi.txt @@ -105,15 +105,10 @@ The version of thinkpad-acpi's sysfs interface is exported by the driver as a driver attribute (see below). Sysfs driver attributes are on the driver's sysfs attribute space, -for 2.6.23 this is /sys/bus/platform/drivers/thinkpad_acpi/ and -/sys/bus/platform/drivers/thinkpad_hwmon/ +for 2.6.20 this is /sys/bus/platform/drivers/thinkpad_acpi/. -Sysfs device attributes are on the thinkpad_acpi device sysfs attribute -space, for 2.6.23 this is /sys/devices/platform/thinkpad_acpi/. - -Sysfs device attributes for the sensors and fan are on the -thinkpad_hwmon device's sysfs attribute space, but you should locate it -looking for a hwmon device with the name attribute of "thinkpad". +Sysfs device attributes are on the driver's sysfs attribute space, +for 2.6.20 this is /sys/devices/platform/thinkpad_acpi/. Driver version -------------- @@ -771,7 +766,7 @@ Temperature sensors ------------------- procfs: /proc/acpi/ibm/thermal -sysfs device attributes: (hwmon "thinkpad") temp*_input +sysfs device attributes: (hwmon) temp*_input Most ThinkPads include six or more separate temperature sensors but only expose the CPU temperature through the standard ACPI methods. This @@ -994,9 +989,7 @@ Fan control and monitoring: fan speed, fan enable/disable --------------------------------------------------------- procfs: /proc/acpi/ibm/fan -sysfs device attributes: (hwmon "thinkpad") fan1_input, pwm1, - pwm1_enable -sysfs hwmon driver attributes: fan_watchdog +sysfs device attributes: (hwmon) fan_input, pwm1, pwm1_enable NOTE NOTE NOTE: fan control operations are disabled by default for safety reasons. To enable them, the module parameter "fan_control=1" @@ -1138,7 +1131,7 @@ hwmon device attribute fan1_input: which can take up to two minutes. May return rubbish on older ThinkPads. -hwmon driver attribute fan_watchdog: +driver attribute fan_watchdog: Fan safety watchdog timer interval, in seconds. Minimum is 1 second, maximum is 120 seconds. 0 disables the watchdog. @@ -1240,9 +1233,3 @@ Sysfs interface changelog: layer, the radio switch generates input event EV_RADIO, and the driver enables hot key handling by default in the firmware. - -0x020000: ABI fix: added a separate hwmon platform device and - driver, which must be located by name (thinkpad) - and the hwmon class for libsensors4 (lm-sensors 3) - compatibility. Moved all hwmon attributes to this - new platform device. diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 2534dc4aa95a..10deabeb3929 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -2234,7 +2234,7 @@ S: Supported KEXEC P: Eric Biederman M: ebiederm@xmission.com -W: http://ftp.kernel.org/pub/linux/kernel/people/horms/kexec-tools/ +W: http://www.xmission.com/~ebiederm/files/kexec/ L: linux-kernel@vger.kernel.org L: kexec@lists.infradead.org S: Maintained @@ -2940,6 +2940,13 @@ L: linux-kernel@vger.kernel.org L: linux-pci@atrey.karlin.mff.cuni.cz S: Supported +PCI SOUND DRIVERS (ES1370, ES1371 and SONICVIBES) +P: Thomas Sailer +M: sailer@ife.ee.ethz.ch +L: linux-sound@vger.kernel.org +W: http://www.ife.ee.ethz.ch/~sailer/linux/pciaudio.html +S: Maintained + PCI SUBSYSTEM P: Greg Kroah-Hartman M: gregkh@suse.de diff --git a/trunk/Makefile b/trunk/Makefile index 68ef80b30340..feca34c26145 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -773,9 +773,6 @@ endef vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o) vmlinux.o FORCE ifdef CONFIG_HEADERS_CHECK $(Q)$(MAKE) -f $(srctree)/Makefile headers_check -endif -ifdef CONFIG_SAMPLES - $(Q)$(MAKE) $(build)=samples endif $(call vmlinux-modpost) $(call if_changed_rule,vmlinux__) @@ -906,14 +903,24 @@ prepare: prepare0 export CPPFLAGS_vmlinux.lds += -P -C -U$(ARCH) -# FIXME: The asm symlink changes when $(ARCH) changes. That's -# hard to detect, but I suppose "make mrproper" is a good idea -# before switching between archs anyway. - -include/asm: - @echo ' SYMLINK $@ -> include/asm-$(SRCARCH)' - $(Q)if [ ! -d include ]; then mkdir -p include; fi; - @ln -fsn asm-$(SRCARCH) $@ +# The asm symlink changes when $(ARCH) changes. +# Detect this and ask user to run make mrproper + +include/asm: FORCE + $(Q)set -e; asmlink=`readlink include/asm | cut -d '-' -f 2`; \ + if [ -L include/asm ]; then \ + if [ "$$asmlink" != "$(SRCARCH)" ]; then \ + echo "ERROR: the symlink $@ points to asm-$$asmlink but asm-$(SRCARCH) was expected"; \ + echo " set ARCH or save .config and run 'make mrproper' to fix it"; \ + exit 1; \ + fi; \ + else \ + echo ' SYMLINK $@ -> include/asm-$(SRCARCH)'; \ + if [ ! -d include ]; then \ + mkdir -p include; \ + fi; \ + ln -fsn asm-$(SRCARCH) $@; \ + fi # Generate some files # --------------------------------------------------------------------------- diff --git a/trunk/arch/alpha/Kconfig b/trunk/arch/alpha/Kconfig index 4c002ba37e50..2a85dc33907c 100644 --- a/trunk/arch/alpha/Kconfig +++ b/trunk/arch/alpha/Kconfig @@ -654,7 +654,7 @@ source "drivers/Kconfig" source "fs/Kconfig" -source "kernel/Kconfig.instrumentation" +source "arch/alpha/oprofile/Kconfig" source "arch/alpha/Kconfig.debug" diff --git a/trunk/arch/alpha/kernel/semaphore.c b/trunk/arch/alpha/kernel/semaphore.c index 8d2982aa1b8d..8c8aaa205eae 100644 --- a/trunk/arch/alpha/kernel/semaphore.c +++ b/trunk/arch/alpha/kernel/semaphore.c @@ -69,7 +69,7 @@ __down_failed(struct semaphore *sem) #ifdef CONFIG_DEBUG_SEMAPHORE printk("%s(%d): down failed(%p)\n", - tsk->comm, task_pid_nr(tsk), sem); + tsk->comm, tsk->pid, sem); #endif tsk->state = TASK_UNINTERRUPTIBLE; @@ -98,7 +98,7 @@ __down_failed(struct semaphore *sem) #ifdef CONFIG_DEBUG_SEMAPHORE printk("%s(%d): down acquired(%p)\n", - tsk->comm, task_pid_nr(tsk), sem); + tsk->comm, tsk->pid, sem); #endif } @@ -111,7 +111,7 @@ __down_failed_interruptible(struct semaphore *sem) #ifdef CONFIG_DEBUG_SEMAPHORE printk("%s(%d): down failed(%p)\n", - tsk->comm, task_pid_nr(tsk), sem); + tsk->comm, tsk->pid, sem); #endif tsk->state = TASK_INTERRUPTIBLE; @@ -139,7 +139,7 @@ __down_failed_interruptible(struct semaphore *sem) #ifdef CONFIG_DEBUG_SEMAPHORE printk("%s(%d): down %s(%p)\n", - current->comm, task_pid_nr(current), + current->comm, current->pid, (ret < 0 ? "interrupted" : "acquired"), sem); #endif return ret; @@ -168,7 +168,7 @@ down(struct semaphore *sem) #endif #ifdef CONFIG_DEBUG_SEMAPHORE printk("%s(%d): down(%p) from %p\n", - current->comm, task_pid_nr(current), sem, + current->comm, current->pid, sem, atomic_read(&sem->count), __builtin_return_address(0)); #endif __down(sem); @@ -182,7 +182,7 @@ down_interruptible(struct semaphore *sem) #endif #ifdef CONFIG_DEBUG_SEMAPHORE printk("%s(%d): down(%p) from %p\n", - current->comm, task_pid_nr(current), sem, + current->comm, current->pid, sem, atomic_read(&sem->count), __builtin_return_address(0)); #endif return __down_interruptible(sem); @@ -201,7 +201,7 @@ down_trylock(struct semaphore *sem) #ifdef CONFIG_DEBUG_SEMAPHORE printk("%s(%d): down_trylock %s from %p\n", - current->comm, task_pid_nr(current), + current->comm, current->pid, ret ? "failed" : "acquired", __builtin_return_address(0)); #endif @@ -217,7 +217,7 @@ up(struct semaphore *sem) #endif #ifdef CONFIG_DEBUG_SEMAPHORE printk("%s(%d): up(%p) from %p\n", - current->comm, task_pid_nr(current), sem, + current->comm, current->pid, sem, atomic_read(&sem->count), __builtin_return_address(0)); #endif __up(sem); diff --git a/trunk/arch/alpha/kernel/traps.c b/trunk/arch/alpha/kernel/traps.c index 2dc7f9fed213..ec0f05e0d8ff 100644 --- a/trunk/arch/alpha/kernel/traps.c +++ b/trunk/arch/alpha/kernel/traps.c @@ -182,7 +182,7 @@ die_if_kernel(char * str, struct pt_regs *regs, long err, unsigned long *r9_15) #ifdef CONFIG_SMP printk("CPU %d ", hard_smp_processor_id()); #endif - printk("%s(%d): %s %ld\n", current->comm, task_pid_nr(current), str, err); + printk("%s(%d): %s %ld\n", current->comm, current->pid, str, err); dik_show_regs(regs, r9_15); add_taint(TAINT_DIE); dik_show_trace((unsigned long *)(regs+1)); @@ -646,7 +646,7 @@ do_entUna(void * va, unsigned long opcode, unsigned long reg, lock_kernel(); printk("%s(%d): unhandled unaligned exception\n", - current->comm, task_pid_nr(current)); + current->comm, current->pid); printk("pc = [<%016lx>] ra = [<%016lx>] ps = %04lx\n", pc, una_reg(26), regs->ps); @@ -786,7 +786,7 @@ do_entUnaUser(void __user * va, unsigned long opcode, } if (++cnt < 5) { printk("%s(%d): unaligned trap at %016lx: %p %lx %ld\n", - current->comm, task_pid_nr(current), + current->comm, current->pid, regs->pc - 4, va, opcode, reg); } last_time = jiffies; diff --git a/trunk/arch/alpha/lib/fls.c b/trunk/arch/alpha/lib/fls.c index 32afaa3fa686..7ad84ea0acf8 100644 --- a/trunk/arch/alpha/lib/fls.c +++ b/trunk/arch/alpha/lib/fls.c @@ -3,7 +3,7 @@ */ #include -#include +#include /* This is fls(x)-1, except zero is held to zero. This allows most efficent input into extbl, plus it allows easy handling of fls(0)=0. */ diff --git a/trunk/arch/alpha/mm/fault.c b/trunk/arch/alpha/mm/fault.c index 4829f96585b1..25154df3055a 100644 --- a/trunk/arch/alpha/mm/fault.c +++ b/trunk/arch/alpha/mm/fault.c @@ -188,13 +188,13 @@ do_page_fault(unsigned long address, unsigned long mmcsr, /* We ran out of memory, or some other thing happened to us that made us unable to handle the page fault gracefully. */ out_of_memory: - if (is_global_init(current)) { + if (is_init(current)) { yield(); down_read(&mm->mmap_sem); goto survive; } printk(KERN_ALERT "VM: killing process %s(%d)\n", - current->comm, task_pid_nr(current)); + current->comm, current->pid); if (!user_mode(regs)) goto no_context; do_group_exit(SIGKILL); diff --git a/trunk/arch/alpha/oprofile/Kconfig b/trunk/arch/alpha/oprofile/Kconfig new file mode 100644 index 000000000000..5ade19801b97 --- /dev/null +++ b/trunk/arch/alpha/oprofile/Kconfig @@ -0,0 +1,23 @@ + +menu "Profiling support" + depends on EXPERIMENTAL + +config PROFILING + bool "Profiling support (EXPERIMENTAL)" + help + Say Y here to enable the extended profiling support mechanisms used + by profilers such as OProfile. + + +config OPROFILE + tristate "OProfile system profiling (EXPERIMENTAL)" + depends on PROFILING + help + OProfile is a profiling system capable of profiling the + whole system, include the kernel, kernel modules, libraries, + and applications. + + If unsure, say N. + +endmenu + diff --git a/trunk/arch/arm/Kconfig b/trunk/arch/arm/Kconfig index 4cee938df01e..0a0c88d0039c 100644 --- a/trunk/arch/arm/Kconfig +++ b/trunk/arch/arm/Kconfig @@ -1068,7 +1068,7 @@ endmenu source "fs/Kconfig" -source "kernel/Kconfig.instrumentation" +source "arch/arm/oprofile/Kconfig" source "arch/arm/Kconfig.debug" diff --git a/trunk/arch/arm/common/sharpsl_pm.c b/trunk/arch/arm/common/sharpsl_pm.c index 5bba5255b119..111a7fa5debe 100644 --- a/trunk/arch/arm/common/sharpsl_pm.c +++ b/trunk/arch/arm/common/sharpsl_pm.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include @@ -766,9 +765,9 @@ static void sharpsl_apm_get_power_status(struct apm_power_info *info) info->battery_life = sharpsl_pm.battstat.mainbat_percent; } -static struct platform_suspend_ops sharpsl_pm_ops = { +static struct pm_ops sharpsl_pm_ops = { .enter = corgi_pxa_pm_enter, - .valid = suspend_valid_only_mem, + .valid = pm_valid_only_mem, }; static int __init sharpsl_pm_probe(struct platform_device *pdev) @@ -800,7 +799,7 @@ static int __init sharpsl_pm_probe(struct platform_device *pdev) apm_get_power_status = sharpsl_apm_get_power_status; - suspend_set_ops(&sharpsl_pm_ops); + pm_set_ops(&sharpsl_pm_ops); mod_timer(&sharpsl_pm.ac_timer, jiffies + msecs_to_jiffies(250)); @@ -809,7 +808,7 @@ static int __init sharpsl_pm_probe(struct platform_device *pdev) static int sharpsl_pm_remove(struct platform_device *pdev) { - suspend_set_ops(NULL); + pm_set_ops(NULL); device_remove_file(&pdev->dev, &dev_attr_battery_percentage); device_remove_file(&pdev->dev, &dev_attr_battery_voltage); diff --git a/trunk/arch/arm/kernel/process.c b/trunk/arch/arm/kernel/process.c index 4f1a03124a74..93b7f8e22dcc 100644 --- a/trunk/arch/arm/kernel/process.c +++ b/trunk/arch/arm/kernel/process.c @@ -265,7 +265,7 @@ void __show_regs(struct pt_regs *regs) void show_regs(struct pt_regs * regs) { printk("\n"); - printk("Pid: %d, comm: %20s\n", task_pid_nr(current), current->comm); + printk("Pid: %d, comm: %20s\n", current->pid, current->comm); __show_regs(regs); __backtrace(); } diff --git a/trunk/arch/arm/kernel/ptrace.c b/trunk/arch/arm/kernel/ptrace.c index 4b05dc5c1023..5feee722ea98 100644 --- a/trunk/arch/arm/kernel/ptrace.c +++ b/trunk/arch/arm/kernel/ptrace.c @@ -382,16 +382,16 @@ static void clear_breakpoint(struct task_struct *task, struct debug_entry *bp) if (ret != 2 || old_insn.thumb != BREAKINST_THUMB) printk(KERN_ERR "%s:%d: corrupted Thumb breakpoint at " - "0x%08lx (0x%04x)\n", task->comm, - task_pid_nr(task), addr, old_insn.thumb); + "0x%08lx (0x%04x)\n", task->comm, task->pid, + addr, old_insn.thumb); } else { ret = swap_insn(task, addr & ~3, &old_insn.arm, &bp->insn.arm, 4); if (ret != 4 || old_insn.arm != BREAKINST_ARM) printk(KERN_ERR "%s:%d: corrupted ARM breakpoint at " - "0x%08lx (0x%08x)\n", task->comm, - task_pid_nr(task), addr, old_insn.arm); + "0x%08lx (0x%08x)\n", task->comm, task->pid, + addr, old_insn.arm); } } diff --git a/trunk/arch/arm/kernel/traps.c b/trunk/arch/arm/kernel/traps.c index 4764bd9ccee8..8ad47619c079 100644 --- a/trunk/arch/arm/kernel/traps.c +++ b/trunk/arch/arm/kernel/traps.c @@ -223,7 +223,7 @@ static void __die(const char *str, int err, struct thread_info *thread, struct p print_modules(); __show_regs(regs); printk("Process %s (pid: %d, stack limit = 0x%p)\n", - tsk->comm, task_pid_nr(tsk), thread + 1); + tsk->comm, tsk->pid, thread + 1); if (!user_mode(regs) || in_interrupt()) { dump_mem("Stack: ", regs->ARM_sp, @@ -337,7 +337,7 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs) #ifdef CONFIG_DEBUG_USER if (user_debug & UDBG_UNDEFINED) { printk(KERN_INFO "%s (%d): undefined instruction: pc=%p\n", - current->comm, task_pid_nr(current), pc); + current->comm, current->pid, pc); dump_instr(regs); } #endif @@ -388,7 +388,7 @@ static int bad_syscall(int n, struct pt_regs *regs) #ifdef CONFIG_DEBUG_USER if (user_debug & UDBG_SYSCALL) { printk(KERN_ERR "[%d] %s: obsolete system call %08x.\n", - task_pid_nr(current), current->comm, n); + current->pid, current->comm, n); dump_instr(regs); } #endif @@ -565,7 +565,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs) */ if (user_debug & UDBG_SYSCALL) { printk("[%d] %s: arm syscall %d\n", - task_pid_nr(current), current->comm, no); + current->pid, current->comm, no); dump_instr(regs); if (user_mode(regs)) { __show_regs(regs); @@ -642,7 +642,7 @@ baddataabort(int code, unsigned long instr, struct pt_regs *regs) #ifdef CONFIG_DEBUG_USER if (user_debug & UDBG_BADABORT) { printk(KERN_ERR "[%d] %s: bad data abort: code %d instr 0x%08lx\n", - task_pid_nr(current), current->comm, code, instr); + current->pid, current->comm, code, instr); dump_instr(regs); show_pte(current->mm, addr); } diff --git a/trunk/arch/arm/mach-at91/pm.c b/trunk/arch/arm/mach-at91/pm.c index 98cb61482917..ddf9184d561d 100644 --- a/trunk/arch/arm/mach-at91/pm.c +++ b/trunk/arch/arm/mach-at91/pm.c @@ -10,9 +10,10 @@ * (at your option) any later version. */ -#include +#include #include #include +#include #include #include #include @@ -198,7 +199,7 @@ static int at91_pm_enter(suspend_state_t state) } -static struct platform_suspend_ops at91_pm_ops ={ +static struct pm_ops at91_pm_ops ={ .valid = at91_pm_valid_state, .set_target = at91_pm_set_target, .enter = at91_pm_enter, @@ -219,7 +220,7 @@ static int __init at91_pm_init(void) /* Disable SDRAM low-power mode. Cannot be used with self-refresh. */ at91_sys_write(AT91_SDRAMC_LPR, 0); - suspend_set_ops(&at91_pm_ops); + pm_set_ops(&at91_pm_ops); return 0; } diff --git a/trunk/arch/arm/mach-omap1/pm.c b/trunk/arch/arm/mach-omap1/pm.c index 3bf01e28df33..089b8208de0e 100644 --- a/trunk/arch/arm/mach-omap1/pm.c +++ b/trunk/arch/arm/mach-omap1/pm.c @@ -35,9 +35,10 @@ * 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include +#include #include #include +#include #include #include #include @@ -599,15 +600,27 @@ static void (*saved_idle)(void) = NULL; /* * omap_pm_prepare - Do preliminary suspend work. + * @state: suspend state we're entering. * */ -static int omap_pm_prepare(void) +static int omap_pm_prepare(suspend_state_t state) { + int error = 0; + /* We cannot sleep in idle until we have resumed */ saved_idle = pm_idle; pm_idle = NULL; - return 0; + switch (state) + { + case PM_SUSPEND_STANDBY: + case PM_SUSPEND_MEM: + break; + default: + return -EINVAL; + } + + return error; } @@ -635,14 +648,16 @@ static int omap_pm_enter(suspend_state_t state) /** * omap_pm_finish - Finish up suspend sequence. + * @state: State we're coming out of. * * This is called after we wake back up (or if entering the sleep state * failed). */ -static void omap_pm_finish(void) +static int omap_pm_finish(suspend_state_t state) { pm_idle = saved_idle; + return 0; } @@ -659,11 +674,11 @@ static struct irqaction omap_wakeup_irq = { -static struct platform_suspend_ops omap_pm_ops ={ +static struct pm_ops omap_pm_ops ={ .prepare = omap_pm_prepare, .enter = omap_pm_enter, .finish = omap_pm_finish, - .valid = suspend_valid_only_mem, + .valid = pm_valid_only_mem, }; static int __init omap_pm_init(void) @@ -720,7 +735,7 @@ static int __init omap_pm_init(void) else if (cpu_is_omap16xx()) omap_writel(OMAP1610_IDLECT3_VAL, OMAP1610_IDLECT3); - suspend_set_ops(&omap_pm_ops); + pm_set_ops(&omap_pm_ops); #if defined(DEBUG) && defined(CONFIG_PROC_FS) omap_pm_init_proc(); diff --git a/trunk/arch/arm/mach-omap2/pm.c b/trunk/arch/arm/mach-omap2/pm.c index baf7d82b458b..6f4a5436d0ce 100644 --- a/trunk/arch/arm/mach-omap2/pm.c +++ b/trunk/arch/arm/mach-omap2/pm.c @@ -16,9 +16,10 @@ * published by the Free Software Foundation. */ -#include +#include #include #include +#include #include #include #include @@ -70,12 +71,28 @@ void omap2_pm_idle(void) local_irq_enable(); } -static int omap2_pm_prepare(void) +static int omap2_pm_prepare(suspend_state_t state) { + int error = 0; + /* We cannot sleep in idle until we have resumed */ saved_idle = pm_idle; pm_idle = NULL; - return 0; + + switch (state) + { + case PM_SUSPEND_STANDBY: + case PM_SUSPEND_MEM: + break; + + case PM_SUSPEND_DISK: + return -ENOTSUPP; + + default: + return -EINVAL; + } + + return error; } #define INT0_WAKE_MASK (OMAP_IRQ_BIT(INT_24XX_GPIO_BANK1) | \ @@ -336,6 +353,9 @@ static int omap2_pm_enter(suspend_state_t state) case PM_SUSPEND_MEM: ret = omap2_pm_suspend(); break; + case PM_SUSPEND_DISK: + ret = -ENOTSUPP; + break; default: ret = -EINVAL; } @@ -343,16 +363,17 @@ static int omap2_pm_enter(suspend_state_t state) return ret; } -static void omap2_pm_finish(void) +static int omap2_pm_finish(suspend_state_t state) { pm_idle = saved_idle; + return 0; } -static struct platform_suspend_ops omap_pm_ops = { +static struct pm_ops omap_pm_ops = { .prepare = omap2_pm_prepare, .enter = omap2_pm_enter, .finish = omap2_pm_finish, - .valid = suspend_valid_only_mem, + .valid = pm_valid_only_mem, }; int __init omap2_pm_init(void) @@ -376,7 +397,7 @@ int __init omap2_pm_init(void) omap2_sram_suspend = omap_sram_push(omap24xx_cpu_suspend, omap24xx_cpu_suspend_sz); - suspend_set_ops(&omap_pm_ops); + pm_set_ops(&omap_pm_ops); pm_idle = omap2_pm_idle; pmdomain_init(); diff --git a/trunk/arch/arm/mach-pnx4008/pm.c b/trunk/arch/arm/mach-pnx4008/pm.c index 40116d254349..2a137f33f752 100644 --- a/trunk/arch/arm/mach-pnx4008/pm.c +++ b/trunk/arch/arm/mach-pnx4008/pm.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include @@ -117,7 +117,7 @@ static int pnx4008_pm_valid(suspend_state_t state) (state == PM_SUSPEND_MEM); } -static struct platform_suspend_ops pnx4008_pm_ops = { +static struct pm_ops pnx4008_pm_ops = { .enter = pnx4008_pm_enter, .valid = pnx4008_pm_valid, }; @@ -146,7 +146,7 @@ static int __init pnx4008_pm_init(void) return -ENOMEM; } - suspend_set_ops(&pnx4008_pm_ops); + pm_set_ops(&pnx4008_pm_ops); return 0; } diff --git a/trunk/arch/arm/mach-pxa/pm.c b/trunk/arch/arm/mach-pxa/pm.c index a941c71c7d06..b59a81a8e7d3 100644 --- a/trunk/arch/arm/mach-pxa/pm.c +++ b/trunk/arch/arm/mach-pxa/pm.c @@ -86,7 +86,7 @@ static int pxa_pm_valid(suspend_state_t state) return -EINVAL; } -static struct platform_suspend_ops pxa_pm_ops = { +static struct pm_ops pxa_pm_ops = { .valid = pxa_pm_valid, .enter = pxa_pm_enter, }; @@ -104,7 +104,7 @@ static int __init pxa_pm_init(void) return -ENOMEM; } - suspend_set_ops(&pxa_pm_ops); + pm_set_ops(&pxa_pm_ops); return 0; } diff --git a/trunk/arch/arm/mach-pxa/pxa25x.c b/trunk/arch/arm/mach-pxa/pxa25x.c index dcd81f8d0833..0d6a72504caa 100644 --- a/trunk/arch/arm/mach-pxa/pxa25x.c +++ b/trunk/arch/arm/mach-pxa/pxa25x.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include @@ -215,7 +215,7 @@ static void pxa25x_cpu_pm_enter(suspend_state_t state) static struct pxa_cpu_pm_fns pxa25x_cpu_pm_fns = { .save_size = SLEEP_SAVE_SIZE, - .valid = suspend_valid_only_mem, + .valid = pm_valid_only_mem, .save = pxa25x_cpu_pm_save, .restore = pxa25x_cpu_pm_restore, .enter = pxa25x_cpu_pm_enter, diff --git a/trunk/arch/arm/mach-pxa/pxa27x.c b/trunk/arch/arm/mach-pxa/pxa27x.c index d0f2b597db12..2d7fc39732e4 100644 --- a/trunk/arch/arm/mach-pxa/pxa27x.c +++ b/trunk/arch/arm/mach-pxa/pxa27x.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include diff --git a/trunk/arch/arm/mach-sa1100/pm.c b/trunk/arch/arm/mach-sa1100/pm.c index 246c573e7252..01a37d3c0727 100644 --- a/trunk/arch/arm/mach-sa1100/pm.c +++ b/trunk/arch/arm/mach-sa1100/pm.c @@ -122,14 +122,14 @@ unsigned long sleep_phys_sp(void *sp) return virt_to_phys(sp); } -static struct platform_suspend_ops sa11x0_pm_ops = { +static struct pm_ops sa11x0_pm_ops = { .enter = sa11x0_pm_enter, - .valid = suspend_valid_only_mem, + .valid = pm_valid_only_mem, }; static int __init sa11x0_pm_init(void) { - suspend_set_ops(&sa11x0_pm_ops); + pm_set_ops(&sa11x0_pm_ops); return 0; } diff --git a/trunk/arch/arm/mm/alignment.c b/trunk/arch/arm/mm/alignment.c index e162cca5917f..074b7cb07743 100644 --- a/trunk/arch/arm/mm/alignment.c +++ b/trunk/arch/arm/mm/alignment.c @@ -757,7 +757,7 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) if (ai_usermode & 1) printk("Alignment trap: %s (%d) PC=0x%08lx Instr=0x%0*lx " "Address=0x%08lx FSR 0x%03x\n", current->comm, - task_pid_nr(current), instrptr, + current->pid, instrptr, thumb_mode(regs) ? 4 : 8, thumb_mode(regs) ? tinstr : instr, addr, fsr); diff --git a/trunk/arch/arm/mm/fault.c b/trunk/arch/arm/mm/fault.c index a8a7dab757eb..59ed1d05b71b 100644 --- a/trunk/arch/arm/mm/fault.c +++ b/trunk/arch/arm/mm/fault.c @@ -197,7 +197,7 @@ __do_page_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr, return fault; out_of_memory: - if (!is_global_init(tsk)) + if (!is_init(tsk)) goto out; /* diff --git a/trunk/arch/arm/nwfpe/fpopcode.h b/trunk/arch/arm/nwfpe/fpopcode.h index 0090b19bbe61..ec78e3517fc9 100644 --- a/trunk/arch/arm/nwfpe/fpopcode.h +++ b/trunk/arch/arm/nwfpe/fpopcode.h @@ -369,20 +369,20 @@ TABLE 5 #define getRoundingMode(opcode) ((opcode & MASK_ROUNDING_MODE) >> 5) #ifdef CONFIG_FPE_NWFPE_XP -static inline floatx80 __pure getExtendedConstant(const unsigned int nIndex) +static inline __attribute_pure__ floatx80 getExtendedConstant(const unsigned int nIndex) { extern const floatx80 floatx80Constant[]; return floatx80Constant[nIndex]; } #endif -static inline float64 __pure getDoubleConstant(const unsigned int nIndex) +static inline __attribute_pure__ float64 getDoubleConstant(const unsigned int nIndex) { extern const float64 float64Constant[]; return float64Constant[nIndex]; } -static inline float32 __pure getSingleConstant(const unsigned int nIndex) +static inline __attribute_pure__ float32 getSingleConstant(const unsigned int nIndex) { extern const float32 float32Constant[]; return float32Constant[nIndex]; diff --git a/trunk/arch/arm/oprofile/Kconfig b/trunk/arch/arm/oprofile/Kconfig new file mode 100644 index 000000000000..afd93ad02feb --- /dev/null +++ b/trunk/arch/arm/oprofile/Kconfig @@ -0,0 +1,42 @@ + +menu "Profiling support" + depends on EXPERIMENTAL + +config PROFILING + bool "Profiling support (EXPERIMENTAL)" + help + Say Y here to enable the extended profiling support mechanisms used + by profilers such as OProfile. + + +config OPROFILE + tristate "OProfile system profiling (EXPERIMENTAL)" + depends on PROFILING + help + OProfile is a profiling system capable of profiling the + whole system, include the kernel, kernel modules, libraries, + and applications. + + If unsure, say N. + +if OPROFILE + +config OPROFILE_ARMV6 + bool + depends on CPU_V6 && !SMP + default y + select OPROFILE_ARM11_CORE + +config OPROFILE_MPCORE + bool + depends on CPU_V6 && SMP + default y + select OPROFILE_ARM11_CORE + +config OPROFILE_ARM11_CORE + bool + +endif + +endmenu + diff --git a/trunk/arch/arm/plat-s3c24xx/pm.c b/trunk/arch/arm/plat-s3c24xx/pm.c index 4fdb3117744f..eab1850616d8 100644 --- a/trunk/arch/arm/plat-s3c24xx/pm.c +++ b/trunk/arch/arm/plat-s3c24xx/pm.c @@ -612,9 +612,9 @@ static int s3c2410_pm_enter(suspend_state_t state) return 0; } -static struct platform_suspend_ops s3c2410_pm_ops = { +static struct pm_ops s3c2410_pm_ops = { .enter = s3c2410_pm_enter, - .valid = suspend_valid_only_mem, + .valid = pm_valid_only_mem, }; /* s3c2410_pm_init @@ -628,6 +628,6 @@ int __init s3c2410_pm_init(void) { printk("S3C2410 Power Management, (c) 2004 Simtec Electronics\n"); - suspend_set_ops(&s3c2410_pm_ops); + pm_set_ops(&s3c2410_pm_ops); return 0; } diff --git a/trunk/arch/avr32/kernel/traps.c b/trunk/arch/avr32/kernel/traps.c index 8a7caf8e7b45..9a73ce7eb50f 100644 --- a/trunk/arch/avr32/kernel/traps.c +++ b/trunk/arch/avr32/kernel/traps.c @@ -89,7 +89,7 @@ void _exception(long signr, struct pt_regs *regs, int code, * generate the same exception over and over again and we get * nowhere. Better to kill it and let the kernel panic. */ - if (is_global_init(current)) { + if (is_init(current)) { __sighandler_t handler; spin_lock_irq(¤t->sighand->siglock); diff --git a/trunk/arch/avr32/mm/fault.c b/trunk/arch/avr32/mm/fault.c index 6560cb18b4e3..11472f8701bd 100644 --- a/trunk/arch/avr32/mm/fault.c +++ b/trunk/arch/avr32/mm/fault.c @@ -160,7 +160,7 @@ asmlinkage void do_page_fault(unsigned long ecr, struct pt_regs *regs) if (exception_trace && printk_ratelimit()) printk("%s%s[%d]: segfault at %08lx pc %08lx " "sp %08lx ecr %lu\n", - is_global_init(tsk) ? KERN_EMERG : KERN_INFO, + is_init(tsk) ? KERN_EMERG : KERN_INFO, tsk->comm, tsk->pid, address, regs->pc, regs->sp, ecr); _exception(SIGSEGV, regs, code, address); @@ -209,7 +209,7 @@ asmlinkage void do_page_fault(unsigned long ecr, struct pt_regs *regs) */ out_of_memory: up_read(&mm->mmap_sem); - if (is_global_init(current)) { + if (is_init(current)) { yield(); down_read(&mm->mmap_sem); goto survive; @@ -231,7 +231,7 @@ asmlinkage void do_page_fault(unsigned long ecr, struct pt_regs *regs) if (exception_trace) printk("%s%s[%d]: bus error at %08lx pc %08lx " "sp %08lx ecr %lu\n", - is_global_init(tsk) ? KERN_EMERG : KERN_INFO, + is_init(tsk) ? KERN_EMERG : KERN_INFO, tsk->comm, tsk->pid, address, regs->pc, regs->sp, ecr); diff --git a/trunk/arch/blackfin/Kconfig b/trunk/arch/blackfin/Kconfig index 4c5ca9d5e40f..aa9db3073312 100644 --- a/trunk/arch/blackfin/Kconfig +++ b/trunk/arch/blackfin/Kconfig @@ -1012,7 +1012,7 @@ source "drivers/Kconfig" source "fs/Kconfig" -source "kernel/Kconfig.instrumentation" +source "arch/blackfin/oprofile/Kconfig" menu "Kernel hacking" diff --git a/trunk/arch/blackfin/mach-common/pm.c b/trunk/arch/blackfin/mach-common/pm.c index dac51fb06f22..b10302722202 100644 --- a/trunk/arch/blackfin/mach-common/pm.c +++ b/trunk/arch/blackfin/mach-common/pm.c @@ -32,7 +32,7 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include +#include #include #include #include @@ -89,15 +89,28 @@ void bfin_pm_suspend_standby_enter(void) #endif /* CONFIG_PM_WAKEUP_GPIO_BY_SIC_IWR */ } + /* - * bfin_pm_valid - Tell the PM core that we only support the standby sleep - * state - * @state: suspend state we're checking. + * bfin_pm_prepare - Do preliminary suspend work. + * @state: suspend state we're entering. * */ -static int bfin_pm_valid(suspend_state_t state) +static int bfin_pm_prepare(suspend_state_t state) { - return (state == PM_SUSPEND_STANDBY); + int error = 0; + + switch (state) { + case PM_SUSPEND_STANDBY: + break; + + case PM_SUSPEND_MEM: + return -ENOTSUPP; + + default: + return -EINVAL; + } + + return error; } /* @@ -122,14 +135,44 @@ static int bfin_pm_enter(suspend_state_t state) return 0; } -struct platform_suspend_ops bfin_pm_ops = { +/* + * bfin_pm_finish - Finish up suspend sequence. + * @state: State we're coming out of. + * + * This is called after we wake back up (or if entering the sleep state + * failed). + */ +static int bfin_pm_finish(suspend_state_t state) +{ + switch (state) { + case PM_SUSPEND_STANDBY: + break; + + case PM_SUSPEND_MEM: + return -ENOTSUPP; + + default: + return -EINVAL; + } + + return 0; +} + +static int bfin_pm_valid(suspend_state_t state) +{ + return (state == PM_SUSPEND_STANDBY); +} + +struct pm_ops bfin_pm_ops = { + .prepare = bfin_pm_prepare, .enter = bfin_pm_enter, + .finish = bfin_pm_finish, .valid = bfin_pm_valid, }; static int __init bfin_pm_init(void) { - suspend_set_ops(&bfin_pm_ops); + pm_set_ops(&bfin_pm_ops); return 0; } diff --git a/trunk/arch/blackfin/oprofile/Kconfig b/trunk/arch/blackfin/oprofile/Kconfig new file mode 100644 index 000000000000..0a2fd999c941 --- /dev/null +++ b/trunk/arch/blackfin/oprofile/Kconfig @@ -0,0 +1,29 @@ +menu "Profiling support" +depends on EXPERIMENTAL + +config PROFILING + bool "Profiling support (EXPERIMENTAL)" + help + Say Y here to enable the extended profiling support mechanisms used + by profilers such as OProfile. + +config OPROFILE + tristate "OProfile system profiling (EXPERIMENTAL)" + depends on PROFILING + help + OProfile is a profiling system capable of profiling the + whole system, include the kernel, kernel modules, libraries, + and applications. + + If unsure, say N. + +config HARDWARE_PM + tristate "Hardware Performance Monitor Profiling" + depends on PROFILING + help + take use of hardware performance monitor to profiling the kernel + and application. + + If unsure, say N. + +endmenu diff --git a/trunk/arch/cris/Kconfig b/trunk/arch/cris/Kconfig index 21900a9378bb..6b4d026a00a1 100644 --- a/trunk/arch/cris/Kconfig +++ b/trunk/arch/cris/Kconfig @@ -196,8 +196,6 @@ source "sound/Kconfig" source "drivers/usb/Kconfig" -source "kernel/Kconfig.instrumentation" - source "arch/cris/Kconfig.debug" source "security/Kconfig" diff --git a/trunk/arch/frv/Kconfig b/trunk/arch/frv/Kconfig index 43153e767bb1..74eef7111f2b 100644 --- a/trunk/arch/frv/Kconfig +++ b/trunk/arch/frv/Kconfig @@ -375,8 +375,6 @@ source "drivers/Kconfig" source "fs/Kconfig" -source "kernel/Kconfig.instrumentation" - source "arch/frv/Kconfig.debug" source "security/Kconfig" diff --git a/trunk/arch/frv/kernel/irq-mb93091.c b/trunk/arch/frv/kernel/irq-mb93091.c index 9e38f99bbab8..ad753c1e9b8f 100644 --- a/trunk/arch/frv/kernel/irq-mb93091.c +++ b/trunk/arch/frv/kernel/irq-mb93091.c @@ -17,10 +17,10 @@ #include #include #include -#include #include #include +#include #include #include #include diff --git a/trunk/arch/frv/kernel/irq-mb93093.c b/trunk/arch/frv/kernel/irq-mb93093.c index 3c2752ca9775..e0983f6926ed 100644 --- a/trunk/arch/frv/kernel/irq-mb93093.c +++ b/trunk/arch/frv/kernel/irq-mb93093.c @@ -17,10 +17,10 @@ #include #include #include -#include #include #include +#include #include #include #include diff --git a/trunk/arch/frv/kernel/irq-mb93493.c b/trunk/arch/frv/kernel/irq-mb93493.c index 7754c7338e4b..c157eeff871d 100644 --- a/trunk/arch/frv/kernel/irq-mb93493.c +++ b/trunk/arch/frv/kernel/irq-mb93493.c @@ -17,10 +17,10 @@ #include #include #include -#include #include #include +#include #include #include #include diff --git a/trunk/arch/frv/kernel/irq.c b/trunk/arch/frv/kernel/irq.c index 7ddb69089ed4..c7e59dcadee4 100644 --- a/trunk/arch/frv/kernel/irq.c +++ b/trunk/arch/frv/kernel/irq.c @@ -24,12 +24,12 @@ #include #include #include -#include #include #include #include #include +#include #include #include #include diff --git a/trunk/arch/h8300/Kconfig b/trunk/arch/h8300/Kconfig index e2e9f57abe2e..e35f74e6e505 100644 --- a/trunk/arch/h8300/Kconfig +++ b/trunk/arch/h8300/Kconfig @@ -223,8 +223,6 @@ endmenu source "fs/Kconfig" -source "kernel/Kconfig.instrumentation" - source "arch/h8300/Kconfig.debug" source "security/Kconfig" diff --git a/trunk/arch/i386/Kconfig b/trunk/arch/i386/Kconfig index d0a4ea1ba14d..b84d5050e92e 100644 --- a/trunk/arch/i386/Kconfig +++ b/trunk/arch/i386/Kconfig @@ -1082,8 +1082,6 @@ endif # APM source "arch/x86/kernel/cpu/cpufreq/Kconfig" -source "drivers/cpuidle/Kconfig" - endmenu menu "Bus options (PCI, PCMCIA, EISA, MCA, ISA)" @@ -1258,6 +1256,31 @@ source "drivers/Kconfig" source "fs/Kconfig" +menuconfig INSTRUMENTATION + bool "Instrumentation Support" + default y + ---help--- + Say Y here to get to see options related to performance measurement, + debugging, and testing. This option alone does not add any kernel code. + + If you say N, all options in this submenu will be skipped and disabled. + +if INSTRUMENTATION + +source "arch/x86/oprofile/Kconfig" + +config KPROBES + bool "Kprobes" + depends on KALLSYMS && MODULES + help + Kprobes allows you to trap at almost any kernel address and + execute a callback function. register_kprobe() establishes + a probepoint and specifies the callback. Kprobes is useful + for kernel debugging, non-intrusive instrumentation and testing. + If in doubt, say "N". + +endif # INSTRUMENTATION + source "arch/i386/Kconfig.debug" source "security/Kconfig" diff --git a/trunk/arch/ia64/Kconfig b/trunk/arch/ia64/Kconfig index c89108e9770d..c60532d93c54 100644 --- a/trunk/arch/ia64/Kconfig +++ b/trunk/arch/ia64/Kconfig @@ -592,7 +592,20 @@ config IRQ_PER_CPU source "arch/ia64/hp/sim/Kconfig" -source "kernel/Kconfig.instrumentation" +menu "Instrumentation Support" + +source "arch/ia64/oprofile/Kconfig" + +config KPROBES + bool "Kprobes" + depends on KALLSYMS && MODULES + help + Kprobes allows you to trap at almost any kernel address and + execute a callback function. register_kprobe() establishes + a probepoint and specifies the callback. Kprobes is useful + for kernel debugging, non-intrusive instrumentation and testing. + If in doubt, say "N". +endmenu source "arch/ia64/Kconfig.debug" diff --git a/trunk/arch/ia64/configs/sn2_defconfig b/trunk/arch/ia64/configs/sn2_defconfig index 75fd90dc76a3..449d3e75bfc2 100644 --- a/trunk/arch/ia64/configs/sn2_defconfig +++ b/trunk/arch/ia64/configs/sn2_defconfig @@ -26,7 +26,6 @@ CONFIG_TASK_IO_ACCOUNTING=y # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=20 -CONFIG_CGROUPS=y CONFIG_CPUSETS=y CONFIG_SYSFS_DEPRECATED=y CONFIG_RELAY=y diff --git a/trunk/arch/ia64/ia32/sys_ia32.c b/trunk/arch/ia64/ia32/sys_ia32.c index d025a22eb225..a3405b3c1eef 100644 --- a/trunk/arch/ia64/ia32/sys_ia32.c +++ b/trunk/arch/ia64/ia32/sys_ia32.c @@ -773,7 +773,7 @@ emulate_mmap (struct file *file, unsigned long start, unsigned long len, int pro if (flags & MAP_SHARED) printk(KERN_INFO "%s(%d): emulate_mmap() can't share head (addr=0x%lx)\n", - current->comm, task_pid_nr(current), start); + current->comm, current->pid, start); ret = mmap_subpage(file, start, min(PAGE_ALIGN(start), end), prot, flags, off); if (IS_ERR((void *) ret)) @@ -786,7 +786,7 @@ emulate_mmap (struct file *file, unsigned long start, unsigned long len, int pro if (flags & MAP_SHARED) printk(KERN_INFO "%s(%d): emulate_mmap() can't share tail (end=0x%lx)\n", - current->comm, task_pid_nr(current), end); + current->comm, current->pid, end); ret = mmap_subpage(file, max(start, PAGE_START(end)), end, prot, flags, (off + len) - offset_in_page(end)); if (IS_ERR((void *) ret)) @@ -816,7 +816,7 @@ emulate_mmap (struct file *file, unsigned long start, unsigned long len, int pro if ((flags & MAP_SHARED) && !is_congruent) printk(KERN_INFO "%s(%d): emulate_mmap() can't share contents of incongruent mmap " - "(addr=0x%lx,off=0x%llx)\n", current->comm, task_pid_nr(current), start, off); + "(addr=0x%lx,off=0x%llx)\n", current->comm, current->pid, start, off); DBG("mmap_body: mapping [0x%lx-0x%lx) %s with poff 0x%llx\n", pstart, pend, is_congruent ? "congruent" : "not congruent", poff); diff --git a/trunk/arch/ia64/kernel/efi.c b/trunk/arch/ia64/kernel/efi.c index 8e4894b205e2..73ca86d03810 100644 --- a/trunk/arch/ia64/kernel/efi.c +++ b/trunk/arch/ia64/kernel/efi.c @@ -967,7 +967,7 @@ find_memmap_space (void) * to use. We can allocate partial granules only if the unavailable * parts exist, and are WB. */ -unsigned long +void efi_memmap_init(unsigned long *s, unsigned long *e) { struct kern_memdesc *k, *prev = NULL; @@ -1084,8 +1084,6 @@ efi_memmap_init(unsigned long *s, unsigned long *e) /* reserve the memory we are using for kern_memmap */ *s = (u64)kern_memmap; *e = (u64)++k; - - return total_mem; } void diff --git a/trunk/arch/ia64/kernel/perfmon.c b/trunk/arch/ia64/kernel/perfmon.c index 59169bf7145f..f55fa07849c4 100644 --- a/trunk/arch/ia64/kernel/perfmon.c +++ b/trunk/arch/ia64/kernel/perfmon.c @@ -158,14 +158,14 @@ */ #define PROTECT_CTX(c, f) \ do { \ - DPRINT(("spinlock_irq_save ctx %p by [%d]\n", c, task_pid_nr(current))); \ + DPRINT(("spinlock_irq_save ctx %p by [%d]\n", c, current->pid)); \ spin_lock_irqsave(&(c)->ctx_lock, f); \ - DPRINT(("spinlocked ctx %p by [%d]\n", c, task_pid_nr(current))); \ + DPRINT(("spinlocked ctx %p by [%d]\n", c, current->pid)); \ } while(0) #define UNPROTECT_CTX(c, f) \ do { \ - DPRINT(("spinlock_irq_restore ctx %p by [%d]\n", c, task_pid_nr(current))); \ + DPRINT(("spinlock_irq_restore ctx %p by [%d]\n", c, current->pid)); \ spin_unlock_irqrestore(&(c)->ctx_lock, f); \ } while(0) @@ -227,12 +227,12 @@ #ifdef PFM_DEBUGGING #define DPRINT(a) \ do { \ - if (unlikely(pfm_sysctl.debug >0)) { printk("%s.%d: CPU%d [%d] ", __FUNCTION__, __LINE__, smp_processor_id(), task_pid_nr(current)); printk a; } \ + if (unlikely(pfm_sysctl.debug >0)) { printk("%s.%d: CPU%d [%d] ", __FUNCTION__, __LINE__, smp_processor_id(), current->pid); printk a; } \ } while (0) #define DPRINT_ovfl(a) \ do { \ - if (unlikely(pfm_sysctl.debug > 0 && pfm_sysctl.debug_ovfl >0)) { printk("%s.%d: CPU%d [%d] ", __FUNCTION__, __LINE__, smp_processor_id(), task_pid_nr(current)); printk a; } \ + if (unlikely(pfm_sysctl.debug > 0 && pfm_sysctl.debug_ovfl >0)) { printk("%s.%d: CPU%d [%d] ", __FUNCTION__, __LINE__, smp_processor_id(), current->pid); printk a; } \ } while (0) #endif @@ -913,7 +913,7 @@ pfm_mask_monitoring(struct task_struct *task) unsigned long mask, val, ovfl_mask; int i; - DPRINT_ovfl(("masking monitoring for [%d]\n", task_pid_nr(task))); + DPRINT_ovfl(("masking monitoring for [%d]\n", task->pid)); ovfl_mask = pmu_conf->ovfl_val; /* @@ -992,12 +992,12 @@ pfm_restore_monitoring(struct task_struct *task) ovfl_mask = pmu_conf->ovfl_val; if (task != current) { - printk(KERN_ERR "perfmon.%d: invalid task[%d] current[%d]\n", __LINE__, task_pid_nr(task), task_pid_nr(current)); + printk(KERN_ERR "perfmon.%d: invalid task[%d] current[%d]\n", __LINE__, task->pid, current->pid); return; } if (ctx->ctx_state != PFM_CTX_MASKED) { printk(KERN_ERR "perfmon.%d: task[%d] current[%d] invalid state=%d\n", __LINE__, - task_pid_nr(task), task_pid_nr(current), ctx->ctx_state); + task->pid, current->pid, ctx->ctx_state); return; } psr = pfm_get_psr(); @@ -1051,8 +1051,7 @@ pfm_restore_monitoring(struct task_struct *task) if ((mask & 0x1) == 0UL) continue; ctx->th_pmcs[i] = ctx->ctx_pmcs[i]; ia64_set_pmc(i, ctx->th_pmcs[i]); - DPRINT(("[%d] pmc[%d]=0x%lx\n", - task_pid_nr(task), i, ctx->th_pmcs[i])); + DPRINT(("[%d] pmc[%d]=0x%lx\n", task->pid, i, ctx->th_pmcs[i])); } ia64_srlz_d(); @@ -1371,7 +1370,7 @@ pfm_reserve_session(struct task_struct *task, int is_syswide, unsigned int cpu) error_conflict: DPRINT(("system wide not possible, conflicting session [%d] on CPU%d\n", - task_pid_nr(pfm_sessions.pfs_sys_session[cpu]), + pfm_sessions.pfs_sys_session[cpu]->pid, cpu)); abort: UNLOCK_PFS(flags); @@ -1443,7 +1442,7 @@ pfm_remove_smpl_mapping(struct task_struct *task, void *vaddr, unsigned long siz /* sanity checks */ if (task->mm == NULL || size == 0UL || vaddr == NULL) { - printk(KERN_ERR "perfmon: pfm_remove_smpl_mapping [%d] invalid context mm=%p\n", task_pid_nr(task), task->mm); + printk(KERN_ERR "perfmon: pfm_remove_smpl_mapping [%d] invalid context mm=%p\n", task->pid, task->mm); return -EINVAL; } @@ -1460,7 +1459,7 @@ pfm_remove_smpl_mapping(struct task_struct *task, void *vaddr, unsigned long siz up_write(&task->mm->mmap_sem); if (r !=0) { - printk(KERN_ERR "perfmon: [%d] unable to unmap sampling buffer @%p size=%lu\n", task_pid_nr(task), vaddr, size); + printk(KERN_ERR "perfmon: [%d] unable to unmap sampling buffer @%p size=%lu\n", task->pid, vaddr, size); } DPRINT(("do_unmap(%p, %lu)=%d\n", vaddr, size, r)); @@ -1502,7 +1501,7 @@ pfm_free_smpl_buffer(pfm_context_t *ctx) return 0; invalid_free: - printk(KERN_ERR "perfmon: pfm_free_smpl_buffer [%d] no buffer\n", task_pid_nr(current)); + printk(KERN_ERR "perfmon: pfm_free_smpl_buffer [%d] no buffer\n", current->pid); return -EINVAL; } #endif @@ -1548,13 +1547,13 @@ pfm_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos) unsigned long flags; DECLARE_WAITQUEUE(wait, current); if (PFM_IS_FILE(filp) == 0) { - printk(KERN_ERR "perfmon: pfm_poll: bad magic [%d]\n", task_pid_nr(current)); + printk(KERN_ERR "perfmon: pfm_poll: bad magic [%d]\n", current->pid); return -EINVAL; } ctx = (pfm_context_t *)filp->private_data; if (ctx == NULL) { - printk(KERN_ERR "perfmon: pfm_read: NULL ctx [%d]\n", task_pid_nr(current)); + printk(KERN_ERR "perfmon: pfm_read: NULL ctx [%d]\n", current->pid); return -EINVAL; } @@ -1608,7 +1607,7 @@ pfm_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos) PROTECT_CTX(ctx, flags); } - DPRINT(("[%d] back to running ret=%ld\n", task_pid_nr(current), ret)); + DPRINT(("[%d] back to running ret=%ld\n", current->pid, ret)); set_current_state(TASK_RUNNING); remove_wait_queue(&ctx->ctx_msgq_wait, &wait); @@ -1617,7 +1616,7 @@ pfm_read(struct file *filp, char __user *buf, size_t size, loff_t *ppos) ret = -EINVAL; msg = pfm_get_next_msg(ctx); if (msg == NULL) { - printk(KERN_ERR "perfmon: pfm_read no msg for ctx=%p [%d]\n", ctx, task_pid_nr(current)); + printk(KERN_ERR "perfmon: pfm_read no msg for ctx=%p [%d]\n", ctx, current->pid); goto abort_locked; } @@ -1648,13 +1647,13 @@ pfm_poll(struct file *filp, poll_table * wait) unsigned int mask = 0; if (PFM_IS_FILE(filp) == 0) { - printk(KERN_ERR "perfmon: pfm_poll: bad magic [%d]\n", task_pid_nr(current)); + printk(KERN_ERR "perfmon: pfm_poll: bad magic [%d]\n", current->pid); return 0; } ctx = (pfm_context_t *)filp->private_data; if (ctx == NULL) { - printk(KERN_ERR "perfmon: pfm_poll: NULL ctx [%d]\n", task_pid_nr(current)); + printk(KERN_ERR "perfmon: pfm_poll: NULL ctx [%d]\n", current->pid); return 0; } @@ -1693,7 +1692,7 @@ pfm_do_fasync(int fd, struct file *filp, pfm_context_t *ctx, int on) ret = fasync_helper (fd, filp, on, &ctx->ctx_async_queue); DPRINT(("pfm_fasync called by [%d] on ctx_fd=%d on=%d async_queue=%p ret=%d\n", - task_pid_nr(current), + current->pid, fd, on, ctx->ctx_async_queue, ret)); @@ -1708,13 +1707,13 @@ pfm_fasync(int fd, struct file *filp, int on) int ret; if (PFM_IS_FILE(filp) == 0) { - printk(KERN_ERR "perfmon: pfm_fasync bad magic [%d]\n", task_pid_nr(current)); + printk(KERN_ERR "perfmon: pfm_fasync bad magic [%d]\n", current->pid); return -EBADF; } ctx = (pfm_context_t *)filp->private_data; if (ctx == NULL) { - printk(KERN_ERR "perfmon: pfm_fasync NULL ctx [%d]\n", task_pid_nr(current)); + printk(KERN_ERR "perfmon: pfm_fasync NULL ctx [%d]\n", current->pid); return -EBADF; } /* @@ -1760,7 +1759,7 @@ pfm_syswide_force_stop(void *info) if (owner != ctx->ctx_task) { printk(KERN_ERR "perfmon: pfm_syswide_force_stop CPU%d unexpected owner [%d] instead of [%d]\n", smp_processor_id(), - task_pid_nr(owner), task_pid_nr(ctx->ctx_task)); + owner->pid, ctx->ctx_task->pid); return; } if (GET_PMU_CTX() != ctx) { @@ -1770,7 +1769,7 @@ pfm_syswide_force_stop(void *info) return; } - DPRINT(("on CPU%d forcing system wide stop for [%d]\n", smp_processor_id(), task_pid_nr(ctx->ctx_task))); + DPRINT(("on CPU%d forcing system wide stop for [%d]\n", smp_processor_id(), ctx->ctx_task->pid)); /* * the context is already protected in pfm_close(), we simply * need to mask interrupts to avoid a PMU interrupt race on @@ -1822,7 +1821,7 @@ pfm_flush(struct file *filp, fl_owner_t id) ctx = (pfm_context_t *)filp->private_data; if (ctx == NULL) { - printk(KERN_ERR "perfmon: pfm_flush: NULL ctx [%d]\n", task_pid_nr(current)); + printk(KERN_ERR "perfmon: pfm_flush: NULL ctx [%d]\n", current->pid); return -EBADF; } @@ -1970,7 +1969,7 @@ pfm_close(struct inode *inode, struct file *filp) ctx = (pfm_context_t *)filp->private_data; if (ctx == NULL) { - printk(KERN_ERR "perfmon: pfm_close: NULL ctx [%d]\n", task_pid_nr(current)); + printk(KERN_ERR "perfmon: pfm_close: NULL ctx [%d]\n", current->pid); return -EBADF; } @@ -2067,7 +2066,7 @@ pfm_close(struct inode *inode, struct file *filp) */ ctx->ctx_state = PFM_CTX_ZOMBIE; - DPRINT(("zombie ctx for [%d]\n", task_pid_nr(task))); + DPRINT(("zombie ctx for [%d]\n", task->pid)); /* * cannot free the context on the spot. deferred until * the task notices the ZOMBIE state @@ -2473,7 +2472,7 @@ pfm_setup_buffer_fmt(struct task_struct *task, struct file *filp, pfm_context_t /* invoke and lock buffer format, if found */ fmt = pfm_find_buffer_fmt(arg->ctx_smpl_buf_id); if (fmt == NULL) { - DPRINT(("[%d] cannot find buffer format\n", task_pid_nr(task))); + DPRINT(("[%d] cannot find buffer format\n", task->pid)); return -EINVAL; } @@ -2484,7 +2483,7 @@ pfm_setup_buffer_fmt(struct task_struct *task, struct file *filp, pfm_context_t ret = pfm_buf_fmt_validate(fmt, task, ctx_flags, cpu, fmt_arg); - DPRINT(("[%d] after validate(0x%x,%d,%p)=%d\n", task_pid_nr(task), ctx_flags, cpu, fmt_arg, ret)); + DPRINT(("[%d] after validate(0x%x,%d,%p)=%d\n", task->pid, ctx_flags, cpu, fmt_arg, ret)); if (ret) goto error; @@ -2606,23 +2605,23 @@ pfm_task_incompatible(pfm_context_t *ctx, struct task_struct *task) * no kernel task or task not owner by caller */ if (task->mm == NULL) { - DPRINT(("task [%d] has not memory context (kernel thread)\n", task_pid_nr(task))); + DPRINT(("task [%d] has not memory context (kernel thread)\n", task->pid)); return -EPERM; } if (pfm_bad_permissions(task)) { - DPRINT(("no permission to attach to [%d]\n", task_pid_nr(task))); + DPRINT(("no permission to attach to [%d]\n", task->pid)); return -EPERM; } /* * cannot block in self-monitoring mode */ if (CTX_OVFL_NOBLOCK(ctx) == 0 && task == current) { - DPRINT(("cannot load a blocking context on self for [%d]\n", task_pid_nr(task))); + DPRINT(("cannot load a blocking context on self for [%d]\n", task->pid)); return -EINVAL; } if (task->exit_state == EXIT_ZOMBIE) { - DPRINT(("cannot attach to zombie task [%d]\n", task_pid_nr(task))); + DPRINT(("cannot attach to zombie task [%d]\n", task->pid)); return -EBUSY; } @@ -2632,7 +2631,7 @@ pfm_task_incompatible(pfm_context_t *ctx, struct task_struct *task) if (task == current) return 0; if ((task->state != TASK_STOPPED) && (task->state != TASK_TRACED)) { - DPRINT(("cannot attach to non-stopped task [%d] state=%ld\n", task_pid_nr(task), task->state)); + DPRINT(("cannot attach to non-stopped task [%d] state=%ld\n", task->pid, task->state)); return -EBUSY; } /* @@ -3513,7 +3512,7 @@ pfm_use_debug_registers(struct task_struct *task) if (pmu_conf->use_rr_dbregs == 0) return 0; - DPRINT(("called for [%d]\n", task_pid_nr(task))); + DPRINT(("called for [%d]\n", task->pid)); /* * do it only once @@ -3544,7 +3543,7 @@ pfm_use_debug_registers(struct task_struct *task) DPRINT(("ptrace_use_dbregs=%u sys_use_dbregs=%u by [%d] ret = %d\n", pfm_sessions.pfs_ptrace_use_dbregs, pfm_sessions.pfs_sys_use_dbregs, - task_pid_nr(task), ret)); + task->pid, ret)); UNLOCK_PFS(flags); @@ -3569,7 +3568,7 @@ pfm_release_debug_registers(struct task_struct *task) LOCK_PFS(flags); if (pfm_sessions.pfs_ptrace_use_dbregs == 0) { - printk(KERN_ERR "perfmon: invalid release for [%d] ptrace_use_dbregs=0\n", task_pid_nr(task)); + printk(KERN_ERR "perfmon: invalid release for [%d] ptrace_use_dbregs=0\n", task->pid); ret = -1; } else { pfm_sessions.pfs_ptrace_use_dbregs--; @@ -3621,7 +3620,7 @@ pfm_restart(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) /* sanity check */ if (unlikely(task == NULL)) { - printk(KERN_ERR "perfmon: [%d] pfm_restart no task\n", task_pid_nr(current)); + printk(KERN_ERR "perfmon: [%d] pfm_restart no task\n", current->pid); return -EINVAL; } @@ -3630,7 +3629,7 @@ pfm_restart(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) fmt = ctx->ctx_buf_fmt; DPRINT(("restarting self %d ovfl=0x%lx\n", - task_pid_nr(task), + task->pid, ctx->ctx_ovfl_regs[0])); if (CTX_HAS_SMPL(ctx)) { @@ -3654,11 +3653,11 @@ pfm_restart(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) pfm_reset_regs(ctx, ctx->ctx_ovfl_regs, PFM_PMD_LONG_RESET); if (rst_ctrl.bits.mask_monitoring == 0) { - DPRINT(("resuming monitoring for [%d]\n", task_pid_nr(task))); + DPRINT(("resuming monitoring for [%d]\n", task->pid)); if (state == PFM_CTX_MASKED) pfm_restore_monitoring(task); } else { - DPRINT(("keeping monitoring stopped for [%d]\n", task_pid_nr(task))); + DPRINT(("keeping monitoring stopped for [%d]\n", task->pid)); // cannot use pfm_stop_monitoring(task, regs); } @@ -3715,10 +3714,10 @@ pfm_restart(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) * "self-monitoring". */ if (CTX_OVFL_NOBLOCK(ctx) == 0 && state == PFM_CTX_MASKED) { - DPRINT(("unblocking [%d] \n", task_pid_nr(task))); + DPRINT(("unblocking [%d] \n", task->pid)); complete(&ctx->ctx_restart_done); } else { - DPRINT(("[%d] armed exit trap\n", task_pid_nr(task))); + DPRINT(("[%d] armed exit trap\n", task->pid)); ctx->ctx_fl_trap_reason = PFM_TRAP_REASON_RESET; @@ -3806,7 +3805,7 @@ pfm_write_ibr_dbr(int mode, pfm_context_t *ctx, void *arg, int count, struct pt_ * don't bother if we are loaded and task is being debugged */ if (is_loaded && (thread->flags & IA64_THREAD_DBG_VALID) != 0) { - DPRINT(("debug registers already in use for [%d]\n", task_pid_nr(task))); + DPRINT(("debug registers already in use for [%d]\n", task->pid)); return -EBUSY; } @@ -3847,7 +3846,7 @@ pfm_write_ibr_dbr(int mode, pfm_context_t *ctx, void *arg, int count, struct pt_ * is shared by all processes running on it */ if (first_time && can_access_pmu) { - DPRINT(("[%d] clearing ibrs, dbrs\n", task_pid_nr(task))); + DPRINT(("[%d] clearing ibrs, dbrs\n", task->pid)); for (i=0; i < pmu_conf->num_ibrs; i++) { ia64_set_ibr(i, 0UL); ia64_dv_serialize_instruction(); @@ -4036,7 +4035,7 @@ pfm_stop(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) return -EBUSY; } DPRINT(("task [%d] ctx_state=%d is_system=%d\n", - task_pid_nr(PFM_CTX_TASK(ctx)), + PFM_CTX_TASK(ctx)->pid, state, is_system)); /* @@ -4094,7 +4093,7 @@ pfm_stop(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) * monitoring disabled in kernel at next reschedule */ ctx->ctx_saved_psr_up = 0; - DPRINT(("task=[%d]\n", task_pid_nr(task))); + DPRINT(("task=[%d]\n", task->pid)); } return 0; } @@ -4299,12 +4298,11 @@ pfm_context_load(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) if (is_system) { if (pfm_sessions.pfs_ptrace_use_dbregs) { - DPRINT(("cannot load [%d] dbregs in use\n", - task_pid_nr(task))); + DPRINT(("cannot load [%d] dbregs in use\n", task->pid)); ret = -EBUSY; } else { pfm_sessions.pfs_sys_use_dbregs++; - DPRINT(("load [%d] increased sys_use_dbreg=%u\n", task_pid_nr(task), pfm_sessions.pfs_sys_use_dbregs)); + DPRINT(("load [%d] increased sys_use_dbreg=%u\n", task->pid, pfm_sessions.pfs_sys_use_dbregs)); set_dbregs = 1; } } @@ -4396,7 +4394,7 @@ pfm_context_load(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) /* allow user level control */ ia64_psr(regs)->sp = 0; - DPRINT(("clearing psr.sp for [%d]\n", task_pid_nr(task))); + DPRINT(("clearing psr.sp for [%d]\n", task->pid)); SET_LAST_CPU(ctx, smp_processor_id()); INC_ACTIVATION(); @@ -4431,7 +4429,7 @@ pfm_context_load(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) */ SET_PMU_OWNER(task, ctx); - DPRINT(("context loaded on PMU for [%d]\n", task_pid_nr(task))); + DPRINT(("context loaded on PMU for [%d]\n", task->pid)); } else { /* * when not current, task MUST be stopped, so this is safe @@ -4495,7 +4493,7 @@ pfm_context_unload(pfm_context_t *ctx, void *arg, int count, struct pt_regs *reg int prev_state, is_system; int ret; - DPRINT(("ctx_state=%d task [%d]\n", ctx->ctx_state, task ? task_pid_nr(task) : -1)); + DPRINT(("ctx_state=%d task [%d]\n", ctx->ctx_state, task ? task->pid : -1)); prev_state = ctx->ctx_state; is_system = ctx->ctx_fl_system; @@ -4570,7 +4568,7 @@ pfm_context_unload(pfm_context_t *ctx, void *arg, int count, struct pt_regs *reg */ ia64_psr(regs)->sp = 1; - DPRINT(("setting psr.sp for [%d]\n", task_pid_nr(task))); + DPRINT(("setting psr.sp for [%d]\n", task->pid)); } /* * save PMDs to context @@ -4610,7 +4608,7 @@ pfm_context_unload(pfm_context_t *ctx, void *arg, int count, struct pt_regs *reg ctx->ctx_fl_can_restart = 0; ctx->ctx_fl_going_zombie = 0; - DPRINT(("disconnected [%d] from context\n", task_pid_nr(task))); + DPRINT(("disconnected [%d] from context\n", task->pid)); return 0; } @@ -4633,7 +4631,7 @@ pfm_exit_thread(struct task_struct *task) PROTECT_CTX(ctx, flags); - DPRINT(("state=%d task [%d]\n", ctx->ctx_state, task_pid_nr(task))); + DPRINT(("state=%d task [%d]\n", ctx->ctx_state, task->pid)); state = ctx->ctx_state; switch(state) { @@ -4642,13 +4640,13 @@ pfm_exit_thread(struct task_struct *task) * only comes to this function if pfm_context is not NULL, i.e., cannot * be in unloaded state */ - printk(KERN_ERR "perfmon: pfm_exit_thread [%d] ctx unloaded\n", task_pid_nr(task)); + printk(KERN_ERR "perfmon: pfm_exit_thread [%d] ctx unloaded\n", task->pid); break; case PFM_CTX_LOADED: case PFM_CTX_MASKED: ret = pfm_context_unload(ctx, NULL, 0, regs); if (ret) { - printk(KERN_ERR "perfmon: pfm_exit_thread [%d] state=%d unload failed %d\n", task_pid_nr(task), state, ret); + printk(KERN_ERR "perfmon: pfm_exit_thread [%d] state=%d unload failed %d\n", task->pid, state, ret); } DPRINT(("ctx unloaded for current state was %d\n", state)); @@ -4657,12 +4655,12 @@ pfm_exit_thread(struct task_struct *task) case PFM_CTX_ZOMBIE: ret = pfm_context_unload(ctx, NULL, 0, regs); if (ret) { - printk(KERN_ERR "perfmon: pfm_exit_thread [%d] state=%d unload failed %d\n", task_pid_nr(task), state, ret); + printk(KERN_ERR "perfmon: pfm_exit_thread [%d] state=%d unload failed %d\n", task->pid, state, ret); } free_ok = 1; break; default: - printk(KERN_ERR "perfmon: pfm_exit_thread [%d] unexpected state=%d\n", task_pid_nr(task), state); + printk(KERN_ERR "perfmon: pfm_exit_thread [%d] unexpected state=%d\n", task->pid, state); break; } UNPROTECT_CTX(ctx, flags); @@ -4746,7 +4744,7 @@ pfm_check_task_state(pfm_context_t *ctx, int cmd, unsigned long flags) DPRINT(("context %d state=%d [%d] task_state=%ld must_stop=%d\n", ctx->ctx_fd, state, - task_pid_nr(task), + task->pid, task->state, PFM_CMD_STOPPED(cmd))); /* @@ -4793,7 +4791,7 @@ pfm_check_task_state(pfm_context_t *ctx, int cmd, unsigned long flags) */ if (PFM_CMD_STOPPED(cmd)) { if ((task->state != TASK_STOPPED) && (task->state != TASK_TRACED)) { - DPRINT(("[%d] task not in stopped state\n", task_pid_nr(task))); + DPRINT(("[%d] task not in stopped state\n", task->pid)); return -EBUSY; } /* @@ -4886,7 +4884,7 @@ sys_perfmonctl (int fd, int cmd, void __user *arg, int count) * limit abuse to min page size */ if (unlikely(sz > PFM_MAX_ARGSIZE)) { - printk(KERN_ERR "perfmon: [%d] argument too big %lu\n", task_pid_nr(current), sz); + printk(KERN_ERR "perfmon: [%d] argument too big %lu\n", current->pid, sz); return -E2BIG; } @@ -5033,11 +5031,11 @@ pfm_context_force_terminate(pfm_context_t *ctx, struct pt_regs *regs) { int ret; - DPRINT(("entering for [%d]\n", task_pid_nr(current))); + DPRINT(("entering for [%d]\n", current->pid)); ret = pfm_context_unload(ctx, NULL, 0, regs); if (ret) { - printk(KERN_ERR "pfm_context_force_terminate: [%d] unloaded failed with %d\n", task_pid_nr(current), ret); + printk(KERN_ERR "pfm_context_force_terminate: [%d] unloaded failed with %d\n", current->pid, ret); } /* @@ -5074,7 +5072,7 @@ pfm_handle_work(void) ctx = PFM_GET_CTX(current); if (ctx == NULL) { - printk(KERN_ERR "perfmon: [%d] has no PFM context\n", task_pid_nr(current)); + printk(KERN_ERR "perfmon: [%d] has no PFM context\n", current->pid); return; } @@ -5271,7 +5269,7 @@ pfm_overflow_handler(struct task_struct *task, pfm_context_t *ctx, u64 pmc0, str DPRINT_ovfl(("pmc0=0x%lx pid=%d iip=0x%lx, %s " "used_pmds=0x%lx\n", pmc0, - task ? task_pid_nr(task): -1, + task ? task->pid: -1, (regs ? regs->cr_iip : 0), CTX_OVFL_NOBLOCK(ctx) ? "nonblocking" : "blocking", ctx->ctx_used_pmds[0])); @@ -5460,7 +5458,7 @@ pfm_overflow_handler(struct task_struct *task, pfm_context_t *ctx, u64 pmc0, str } DPRINT_ovfl(("owner [%d] pending=%ld reason=%u ovfl_pmds=0x%lx ovfl_notify=0x%lx masked=%d\n", - GET_PMU_OWNER() ? task_pid_nr(GET_PMU_OWNER()) : -1, + GET_PMU_OWNER() ? GET_PMU_OWNER()->pid : -1, PFM_GET_WORK_PENDING(task), ctx->ctx_fl_trap_reason, ovfl_pmds, @@ -5485,7 +5483,7 @@ pfm_overflow_handler(struct task_struct *task, pfm_context_t *ctx, u64 pmc0, str sanity_check: printk(KERN_ERR "perfmon: CPU%d overflow handler [%d] pmc0=0x%lx\n", smp_processor_id(), - task ? task_pid_nr(task) : -1, + task ? task->pid : -1, pmc0); return; @@ -5518,7 +5516,7 @@ pfm_overflow_handler(struct task_struct *task, pfm_context_t *ctx, u64 pmc0, str * * Overall pretty hairy stuff.... */ - DPRINT(("ctx is zombie for [%d], converted to spurious\n", task ? task_pid_nr(task): -1)); + DPRINT(("ctx is zombie for [%d], converted to spurious\n", task ? task->pid: -1)); pfm_clear_psr_up(); ia64_psr(regs)->up = 0; ia64_psr(regs)->sp = 1; @@ -5579,13 +5577,13 @@ pfm_do_interrupt_handler(int irq, void *arg, struct pt_regs *regs) report_spurious1: printk(KERN_INFO "perfmon: spurious overflow interrupt on CPU%d: process %d has no PFM context\n", - this_cpu, task_pid_nr(task)); + this_cpu, task->pid); pfm_unfreeze_pmu(); return -1; report_spurious2: printk(KERN_INFO "perfmon: spurious overflow interrupt on CPU%d: process %d, invalid flag\n", this_cpu, - task_pid_nr(task)); + task->pid); pfm_unfreeze_pmu(); return -1; } @@ -5872,8 +5870,7 @@ pfm_force_cleanup(pfm_context_t *ctx, struct pt_regs *regs) ia64_psr(regs)->sp = 1; if (GET_PMU_OWNER() == task) { - DPRINT(("cleared ownership for [%d]\n", - task_pid_nr(ctx->ctx_task))); + DPRINT(("cleared ownership for [%d]\n", ctx->ctx_task->pid)); SET_PMU_OWNER(NULL, NULL); } @@ -5885,7 +5882,7 @@ pfm_force_cleanup(pfm_context_t *ctx, struct pt_regs *regs) task->thread.pfm_context = NULL; task->thread.flags &= ~IA64_THREAD_PM_VALID; - DPRINT(("force cleanup for [%d]\n", task_pid_nr(task))); + DPRINT(("force cleanup for [%d]\n", task->pid)); } @@ -6429,7 +6426,7 @@ pfm_flush_pmds(struct task_struct *task, pfm_context_t *ctx) if (PMD_IS_COUNTING(i)) { DPRINT(("[%d] pmd[%d] ctx_pmd=0x%lx hw_pmd=0x%lx\n", - task_pid_nr(task), + task->pid, i, ctx->ctx_pmds[i].val, val & ovfl_val)); @@ -6451,11 +6448,11 @@ pfm_flush_pmds(struct task_struct *task, pfm_context_t *ctx) */ if (pmc0 & (1UL << i)) { val += 1 + ovfl_val; - DPRINT(("[%d] pmd[%d] overflowed\n", task_pid_nr(task), i)); + DPRINT(("[%d] pmd[%d] overflowed\n", task->pid, i)); } } - DPRINT(("[%d] ctx_pmd[%d]=0x%lx pmd_val=0x%lx\n", task_pid_nr(task), i, val, pmd_val)); + DPRINT(("[%d] ctx_pmd[%d]=0x%lx pmd_val=0x%lx\n", task->pid, i, val, pmd_val)); if (is_self) ctx->th_pmds[i] = pmd_val; @@ -6796,14 +6793,14 @@ dump_pmu_state(const char *from) printk("CPU%d from %s() current [%d] iip=0x%lx %s\n", this_cpu, from, - task_pid_nr(current), + current->pid, regs->cr_iip, current->comm); task = GET_PMU_OWNER(); ctx = GET_PMU_CTX(); - printk("->CPU%d owner [%d] ctx=%p\n", this_cpu, task ? task_pid_nr(task) : -1, ctx); + printk("->CPU%d owner [%d] ctx=%p\n", this_cpu, task ? task->pid : -1, ctx); psr = pfm_get_psr(); @@ -6851,7 +6848,7 @@ pfm_inherit(struct task_struct *task, struct pt_regs *regs) { struct thread_struct *thread; - DPRINT(("perfmon: pfm_inherit clearing state for [%d]\n", task_pid_nr(task))); + DPRINT(("perfmon: pfm_inherit clearing state for [%d]\n", task->pid)); thread = &task->thread; diff --git a/trunk/arch/ia64/kernel/perfmon_default_smpl.c b/trunk/arch/ia64/kernel/perfmon_default_smpl.c index a7af1cb419f9..ff80eab83b38 100644 --- a/trunk/arch/ia64/kernel/perfmon_default_smpl.c +++ b/trunk/arch/ia64/kernel/perfmon_default_smpl.c @@ -44,11 +44,11 @@ default_validate(struct task_struct *task, unsigned int flags, int cpu, void *da int ret = 0; if (data == NULL) { - DPRINT(("[%d] no argument passed\n", task_pid_nr(task))); + DPRINT(("[%d] no argument passed\n", task->pid)); return -EINVAL; } - DPRINT(("[%d] validate flags=0x%x CPU%d\n", task_pid_nr(task), flags, cpu)); + DPRINT(("[%d] validate flags=0x%x CPU%d\n", task->pid, flags, cpu)); /* * must hold at least the buffer header + one minimally sized entry @@ -88,7 +88,7 @@ default_init(struct task_struct *task, void *buf, unsigned int flags, int cpu, v hdr->hdr_count = 0UL; DPRINT(("[%d] buffer=%p buf_size=%lu hdr_size=%lu hdr_version=%u cur_offs=%lu\n", - task_pid_nr(task), + task->pid, buf, hdr->hdr_buf_size, sizeof(*hdr), @@ -245,7 +245,7 @@ default_restart(struct task_struct *task, pfm_ovfl_ctrl_t *ctrl, void *buf, stru static int default_exit(struct task_struct *task, void *buf, struct pt_regs *regs) { - DPRINT(("[%d] exit(%p)\n", task_pid_nr(task), buf)); + DPRINT(("[%d] exit(%p)\n", task->pid, buf)); return 0; } diff --git a/trunk/arch/ia64/kernel/process.c b/trunk/arch/ia64/kernel/process.c index 2418289ee5ca..c613fc0e91cc 100644 --- a/trunk/arch/ia64/kernel/process.c +++ b/trunk/arch/ia64/kernel/process.c @@ -105,8 +105,7 @@ show_regs (struct pt_regs *regs) unsigned long ip = regs->cr_iip + ia64_psr(regs)->ri; print_modules(); - printk("\nPid: %d, CPU %d, comm: %20s\n", task_pid_nr(current), - smp_processor_id(), current->comm); + printk("\nPid: %d, CPU %d, comm: %20s\n", current->pid, smp_processor_id(), current->comm); printk("psr : %016lx ifs : %016lx ip : [<%016lx>] %s\n", regs->cr_ipsr, regs->cr_ifs, ip, print_tainted()); print_symbol("ip is at %s\n", ip); diff --git a/trunk/arch/ia64/kernel/setup.c b/trunk/arch/ia64/kernel/setup.c index cbf67f1aa291..c5cfcfa4c87c 100644 --- a/trunk/arch/ia64/kernel/setup.c +++ b/trunk/arch/ia64/kernel/setup.c @@ -208,48 +208,6 @@ static int __init register_memory(void) __initcall(register_memory); - -#ifdef CONFIG_KEXEC -static void __init setup_crashkernel(unsigned long total, int *n) -{ - unsigned long long base = 0, size = 0; - int ret; - - ret = parse_crashkernel(boot_command_line, total, - &size, &base); - if (ret == 0 && size > 0) { - if (!base) { - sort_regions(rsvd_region, *n); - base = kdump_find_rsvd_region(size, - rsvd_region, *n); - } - if (base != ~0UL) { - printk(KERN_INFO "Reserving %ldMB of memory at %ldMB " - "for crashkernel (System RAM: %ldMB)\n", - (unsigned long)(size >> 20), - (unsigned long)(base >> 20), - (unsigned long)(total >> 20)); - rsvd_region[*n].start = - (unsigned long)__va(base); - rsvd_region[*n].end = - (unsigned long)__va(base + size); - (*n)++; - crashk_res.start = base; - crashk_res.end = base + size - 1; - } - } - efi_memmap_res.start = ia64_boot_param->efi_memmap; - efi_memmap_res.end = efi_memmap_res.start + - ia64_boot_param->efi_memmap_size; - boot_param_res.start = __pa(ia64_boot_param); - boot_param_res.end = boot_param_res.start + - sizeof(*ia64_boot_param); -} -#else -static inline void __init setup_crashkernel(unsigned long total, int *n) -{} -#endif - /** * reserve_memory - setup reserved memory areas * @@ -261,7 +219,6 @@ void __init reserve_memory (void) { int n = 0; - unsigned long total_memory; /* * none of the entries in this table overlap @@ -297,11 +254,50 @@ reserve_memory (void) n++; #endif - total_memory = efi_memmap_init(&rsvd_region[n].start, &rsvd_region[n].end); + efi_memmap_init(&rsvd_region[n].start, &rsvd_region[n].end); n++; - setup_crashkernel(total_memory, &n); - +#ifdef CONFIG_KEXEC + /* crashkernel=size@offset specifies the size to reserve for a crash + * kernel. If offset is 0, then it is determined automatically. + * By reserving this memory we guarantee that linux never set's it + * up as a DMA target.Useful for holding code to do something + * appropriate after a kernel panic. + */ + { + char *from = strstr(boot_command_line, "crashkernel="); + unsigned long base, size; + if (from) { + size = memparse(from + 12, &from); + if (*from == '@') + base = memparse(from+1, &from); + else + base = 0; + if (size) { + if (!base) { + sort_regions(rsvd_region, n); + base = kdump_find_rsvd_region(size, + rsvd_region, n); + } + if (base != ~0UL) { + rsvd_region[n].start = + (unsigned long)__va(base); + rsvd_region[n].end = + (unsigned long)__va(base + size); + n++; + crashk_res.start = base; + crashk_res.end = base + size - 1; + } + } + } + efi_memmap_res.start = ia64_boot_param->efi_memmap; + efi_memmap_res.end = efi_memmap_res.start + + ia64_boot_param->efi_memmap_size; + boot_param_res.start = __pa(ia64_boot_param); + boot_param_res.end = boot_param_res.start + + sizeof(*ia64_boot_param); + } +#endif /* end of memory marker */ rsvd_region[n].start = ~0UL; rsvd_region[n].end = ~0UL; diff --git a/trunk/arch/ia64/kernel/signal.c b/trunk/arch/ia64/kernel/signal.c index cdb64cc4d9c8..aeec8184e862 100644 --- a/trunk/arch/ia64/kernel/signal.c +++ b/trunk/arch/ia64/kernel/signal.c @@ -227,7 +227,7 @@ ia64_rt_sigreturn (struct sigscratch *scr) si.si_signo = SIGSEGV; si.si_errno = 0; si.si_code = SI_KERNEL; - si.si_pid = task_pid_vnr(current); + si.si_pid = current->pid; si.si_uid = current->uid; si.si_addr = sc; force_sig_info(SIGSEGV, &si, current); @@ -332,7 +332,7 @@ force_sigsegv_info (int sig, void __user *addr) si.si_signo = SIGSEGV; si.si_errno = 0; si.si_code = SI_KERNEL; - si.si_pid = task_pid_vnr(current); + si.si_pid = current->pid; si.si_uid = current->uid; si.si_addr = addr; force_sig_info(SIGSEGV, &si, current); diff --git a/trunk/arch/ia64/kernel/time.c b/trunk/arch/ia64/kernel/time.c index 2bb84214e5f1..98cfc90cab1d 100644 --- a/trunk/arch/ia64/kernel/time.c +++ b/trunk/arch/ia64/kernel/time.c @@ -371,11 +371,6 @@ ia64_setup_printk_clock(void) ia64_printk_clock = ia64_itc_printk_clock; } -/* IA64 doesn't cache the timezone */ -void update_vsyscall_tz(void) -{ -} - void update_vsyscall(struct timespec *wall, struct clocksource *c) { unsigned long flags; diff --git a/trunk/arch/ia64/kernel/traps.c b/trunk/arch/ia64/kernel/traps.c index 78d65cb947d2..3aeaf15e468b 100644 --- a/trunk/arch/ia64/kernel/traps.c +++ b/trunk/arch/ia64/kernel/traps.c @@ -61,7 +61,7 @@ die (const char *str, struct pt_regs *regs, long err) if (++die.lock_owner_depth < 3) { printk("%s[%d]: %s %ld [%d]\n", - current->comm, task_pid_nr(current), str, err, ++die_counter); + current->comm, current->pid, str, err, ++die_counter); (void) notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV); show_regs(regs); } else @@ -315,7 +315,7 @@ handle_fpu_swa (int fp_fault, struct pt_regs *regs, unsigned long isr) last.time = current_jiffies + 5 * HZ; printk(KERN_WARNING "%s(%d): floating-point assist fault at ip %016lx, isr %016lx\n", - current->comm, task_pid_nr(current), regs->cr_iip + ia64_psr(regs)->ri, isr); + current->comm, current->pid, regs->cr_iip + ia64_psr(regs)->ri, isr); } } } @@ -453,7 +453,7 @@ ia64_fault (unsigned long vector, unsigned long isr, unsigned long ifa, if (code == 8) { # ifdef CONFIG_IA64_PRINT_HAZARDS printk("%s[%d]: possible hazard @ ip=%016lx (pr = %016lx)\n", - current->comm, task_pid_nr(current), + current->comm, current->pid, regs.cr_iip + ia64_psr(®s)->ri, regs.pr); # endif return; diff --git a/trunk/arch/ia64/kernel/unaligned.c b/trunk/arch/ia64/kernel/unaligned.c index 2173de9fe917..fe6aa5a9f8fa 100644 --- a/trunk/arch/ia64/kernel/unaligned.c +++ b/trunk/arch/ia64/kernel/unaligned.c @@ -1340,8 +1340,7 @@ ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs) size_t len; len = sprintf(buf, "%s(%d): unaligned access to 0x%016lx, " - "ip=0x%016lx\n\r", current->comm, - task_pid_nr(current), + "ip=0x%016lx\n\r", current->comm, current->pid, ifa, regs->cr_iip + ipsr->ri); /* * Don't call tty_write_message() if we're in the kernel; we might @@ -1364,7 +1363,7 @@ ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs) "administrator\n" "echo 0 > /proc/sys/kernel/ignore-" "unaligned-usertrap to re-enable\n", - current->comm, task_pid_nr(current)); + current->comm, current->pid); } } } else { diff --git a/trunk/arch/ia64/mm/fault.c b/trunk/arch/ia64/mm/fault.c index 7571076a16a1..32f26253c4e8 100644 --- a/trunk/arch/ia64/mm/fault.c +++ b/trunk/arch/ia64/mm/fault.c @@ -274,7 +274,7 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re out_of_memory: up_read(&mm->mmap_sem); - if (is_global_init(current)) { + if (is_init(current)) { yield(); down_read(&mm->mmap_sem); goto survive; diff --git a/trunk/arch/ia64/mm/init.c b/trunk/arch/ia64/mm/init.c index c6c19bf11bec..3e10152abbf0 100644 --- a/trunk/arch/ia64/mm/init.c +++ b/trunk/arch/ia64/mm/init.c @@ -127,8 +127,8 @@ ia64_init_addr_space (void) vma->vm_mm = current->mm; vma->vm_start = current->thread.rbs_bot & PAGE_MASK; vma->vm_end = vma->vm_start + PAGE_SIZE; + vma->vm_page_prot = protection_map[VM_DATA_DEFAULT_FLAGS & 0x7]; vma->vm_flags = VM_DATA_DEFAULT_FLAGS|VM_GROWSUP|VM_ACCOUNT; - vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); down_write(¤t->mm->mmap_sem); if (insert_vm_struct(current->mm, vma)) { up_write(¤t->mm->mmap_sem); diff --git a/trunk/arch/ia64/oprofile/Kconfig b/trunk/arch/ia64/oprofile/Kconfig new file mode 100644 index 000000000000..97271ab484dc --- /dev/null +++ b/trunk/arch/ia64/oprofile/Kconfig @@ -0,0 +1,20 @@ +config PROFILING + bool "Profiling support (EXPERIMENTAL)" + help + Say Y here to enable the extended profiling support mechanisms used + by profilers such as OProfile. + +config OPROFILE + tristate "OProfile system profiling (EXPERIMENTAL)" + depends on PROFILING + help + OProfile is a profiling system capable of profiling the + whole system, include the kernel, kernel modules, libraries, + and applications. + + Due to firmware bugs, you may need to use the "nohalt" boot + option if you're using OProfile with the hardware performance + counters. + + If unsure, say N. + diff --git a/trunk/arch/ia64/sn/kernel/xpnet.c b/trunk/arch/ia64/sn/kernel/xpnet.c index a5df672d8392..e58fcadff2e9 100644 --- a/trunk/arch/ia64/sn/kernel/xpnet.c +++ b/trunk/arch/ia64/sn/kernel/xpnet.c @@ -269,9 +269,8 @@ xpnet_receive(partid_t partid, int channel, struct xpnet_message *msg) skb->protocol = eth_type_trans(skb, xpnet_device); skb->ip_summed = CHECKSUM_UNNECESSARY; - dev_dbg(xpnet, "passing skb to network layer\n" - KERN_DEBUG "\tskb->head=0x%p skb->data=0x%p skb->tail=0x%p " - "skb->end=0x%p skb->len=%d\n", + dev_dbg(xpnet, "passing skb to network layer; \n\tskb->head=0x%p " + "skb->data=0x%p skb->tail=0x%p skb->end=0x%p skb->len=%d\n", (void *)skb->head, (void *)skb->data, skb_tail_pointer(skb), skb_end_pointer(skb), skb->len); @@ -577,10 +576,10 @@ xpnet_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) msg->tailout_ignore = end_addr - (u64)skb_tail_pointer(skb); msg->buf_pa = __pa(start_addr); - dev_dbg(xpnet, "sending XPC message to %d:%d\n" - KERN_DEBUG "msg->buf_pa=0x%lx, msg->size=%u, " - "msg->leadin_ignore=%u, msg->tailout_ignore=%u\n", - dest_partid, XPC_NET_CHANNEL, msg->buf_pa, msg->size, + dev_dbg(xpnet, "sending XPC message to %d:%d\nmsg->buf_pa=" + "0x%lx, msg->size=%u, msg->leadin_ignore=%u, " + "msg->tailout_ignore=%u\n", dest_partid, + XPC_NET_CHANNEL, msg->buf_pa, msg->size, msg->leadin_ignore, msg->tailout_ignore); diff --git a/trunk/arch/m32r/Kconfig b/trunk/arch/m32r/Kconfig index ab9a264cb194..bd5fe76401f1 100644 --- a/trunk/arch/m32r/Kconfig +++ b/trunk/arch/m32r/Kconfig @@ -426,7 +426,7 @@ source "drivers/Kconfig" source "fs/Kconfig" -source "kernel/Kconfig.instrumentation" +source "arch/m32r/oprofile/Kconfig" source "arch/m32r/Kconfig.debug" diff --git a/trunk/arch/m32r/kernel/traps.c b/trunk/arch/m32r/kernel/traps.c index 89ba4a0b5d51..97e0b1c0830e 100644 --- a/trunk/arch/m32r/kernel/traps.c +++ b/trunk/arch/m32r/kernel/traps.c @@ -196,7 +196,7 @@ static void show_registers(struct pt_regs *regs) printk("SPI: %08lx\n", sp); } printk("Process %s (pid: %d, process nr: %d, stackpage=%08lx)", - current->comm, task_pid_nr(current), 0xffff & i, 4096+(unsigned long)current); + current->comm, current->pid, 0xffff & i, 4096+(unsigned long)current); /* * When in-kernel, we also print out the stack and code at the diff --git a/trunk/arch/m32r/mm/fault.c b/trunk/arch/m32r/mm/fault.c index 4a71df4c1b30..70a766aad3e0 100644 --- a/trunk/arch/m32r/mm/fault.c +++ b/trunk/arch/m32r/mm/fault.c @@ -271,7 +271,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code, */ out_of_memory: up_read(&mm->mmap_sem); - if (is_global_init(tsk)) { + if (is_init(tsk)) { yield(); down_read(&mm->mmap_sem); goto survive; diff --git a/trunk/arch/m32r/oprofile/Kconfig b/trunk/arch/m32r/oprofile/Kconfig new file mode 100644 index 000000000000..19d37730b664 --- /dev/null +++ b/trunk/arch/m32r/oprofile/Kconfig @@ -0,0 +1,23 @@ + +menu "Profiling support" + depends on EXPERIMENTAL + +config PROFILING + bool "Profiling support (EXPERIMENTAL)" + help + Say Y here to enable the extended profiling support mechanisms used + by profilers such as OProfile. + + +config OPROFILE + tristate "OProfile system profiling (EXPERIMENTAL)" + depends on PROFILING + help + OProfile is a profiling system capable of profiling the + whole system, include the kernel, kernel modules, libraries, + and applications. + + If unsure, say N. + +endmenu + diff --git a/trunk/arch/m68k/Kconfig b/trunk/arch/m68k/Kconfig index 01dee84f840a..20a9c08e59c3 100644 --- a/trunk/arch/m68k/Kconfig +++ b/trunk/arch/m68k/Kconfig @@ -683,8 +683,6 @@ endmenu source "fs/Kconfig" -source "kernel/Kconfig.instrumentation" - source "arch/m68k/Kconfig.debug" source "security/Kconfig" diff --git a/trunk/arch/m68k/kernel/traps.c b/trunk/arch/m68k/kernel/traps.c index 97f556fa4932..4e2752a0e89b 100644 --- a/trunk/arch/m68k/kernel/traps.c +++ b/trunk/arch/m68k/kernel/traps.c @@ -900,7 +900,7 @@ void show_registers(struct pt_regs *regs) regs->d4, regs->d5, regs->a0, regs->a1); printk("Process %s (pid: %d, task=%p)\n", - current->comm, task_pid_nr(current), current); + current->comm, current->pid, current); addr = (unsigned long)&fp->un; printk("Frame format=%X ", regs->format); switch (regs->format) { @@ -1038,7 +1038,7 @@ void bad_super_trap (struct frame *fp) fp->un.fmtb.daddr, space_names[ssw & DFC], fp->ptregs.pc); } - printk ("Current process id is %d\n", task_pid_nr(current)); + printk ("Current process id is %d\n", current->pid); die_if_kernel("BAD KERNEL TRAP", &fp->ptregs, 0); } diff --git a/trunk/arch/m68k/mm/fault.c b/trunk/arch/m68k/mm/fault.c index f493f03231d5..eaa618681159 100644 --- a/trunk/arch/m68k/mm/fault.c +++ b/trunk/arch/m68k/mm/fault.c @@ -180,7 +180,7 @@ int do_page_fault(struct pt_regs *regs, unsigned long address, */ out_of_memory: up_read(&mm->mmap_sem); - if (is_global_init(current)) { + if (is_init(current)) { yield(); down_read(&mm->mmap_sem); goto survive; diff --git a/trunk/arch/m68knommu/Kconfig b/trunk/arch/m68knommu/Kconfig index f52c627bdadd..185906b54cb0 100644 --- a/trunk/arch/m68knommu/Kconfig +++ b/trunk/arch/m68knommu/Kconfig @@ -696,8 +696,6 @@ source "drivers/Kconfig" source "fs/Kconfig" -source "kernel/Kconfig.instrumentation" - source "arch/m68knommu/Kconfig.debug" source "security/Kconfig" diff --git a/trunk/arch/mips/Kconfig b/trunk/arch/mips/Kconfig index 4dc142d394a3..235d4514e0a9 100644 --- a/trunk/arch/mips/Kconfig +++ b/trunk/arch/mips/Kconfig @@ -21,7 +21,6 @@ config MACH_ALCHEMY config BASLER_EXCITE bool "Basler eXcite smart camera" - select CEVT_R4K select DMA_COHERENT select HW_HAS_PCI select IRQ_CPU @@ -48,7 +47,6 @@ config BASLER_EXCITE_PROTOTYPE config BCM47XX bool "BCM47XX based boards" - select CEVT_R4K select DMA_NONCOHERENT select HW_HAS_PCI select IRQ_CPU @@ -65,7 +63,6 @@ config BCM47XX config MIPS_COBALT bool "Cobalt Server" - select CEVT_R4K select DMA_NONCOHERENT select HW_HAS_PCI select I8253 @@ -83,7 +80,6 @@ config MIPS_COBALT config MACH_DECSTATION bool "DECstations" select BOOT_ELF32 - select CEVT_R4K select DMA_NONCOHERENT select NO_IOPORT select IRQ_CPU @@ -115,7 +111,6 @@ config MACH_JAZZ select ARC select ARC32 select ARCH_MAY_HAVE_PC_FDC - select CEVT_R4K select GENERIC_ISA_DMA select IRQ_CPU select I8253 @@ -135,7 +130,6 @@ config MACH_JAZZ config LASAT bool "LASAT Networks platforms" - select CEVT_R4K select DMA_NONCOHERENT select SYS_HAS_EARLY_PRINTK select HW_HAS_PCI @@ -152,7 +146,6 @@ config LASAT config LEMOTE_FULONG bool "Lemote Fulong mini-PC" select ARCH_SPARSEMEM_ENABLE - select CEVT_R4K select SYS_HAS_CPU_LOONGSON2 select DMA_NONCOHERENT select BOOT_ELF32 @@ -177,7 +170,6 @@ config LEMOTE_FULONG config MIPS_ATLAS bool "MIPS Atlas board" select BOOT_ELF32 - select CEVT_R4K select DMA_NONCOHERENT select SYS_HAS_EARLY_PRINTK select IRQ_CPU @@ -208,7 +200,6 @@ config MIPS_MALTA bool "MIPS Malta board" select ARCH_MAY_HAVE_PC_FDC select BOOT_ELF32 - select CEVT_R4K select DMA_NONCOHERENT select GENERIC_ISA_DMA select IRQ_CPU @@ -239,7 +230,6 @@ config MIPS_MALTA config MIPS_SEAD bool "MIPS SEAD board" - select CEVT_R4K select IRQ_CPU select DMA_NONCOHERENT select SYS_HAS_EARLY_PRINTK @@ -258,7 +248,6 @@ config MIPS_SEAD config MIPS_SIM bool 'MIPS simulator (MIPSsim)' - select CEVT_R4K select DMA_NONCOHERENT select SYS_HAS_EARLY_PRINTK select IRQ_CPU @@ -276,7 +265,6 @@ config MIPS_SIM config MARKEINS bool "NEC EMMA2RH Mark-eins" - select CEVT_R4K select DMA_NONCOHERENT select HW_HAS_PCI select IRQ_CPU @@ -291,7 +279,6 @@ config MARKEINS config MACH_VR41XX bool "NEC VR4100 series based machines" - select CEVT_R4K select SYS_HAS_CPU_VR41XX select GENERIC_HARDIRQS_NO__DO_IRQ @@ -328,7 +315,6 @@ config PMC_MSP config PMC_YOSEMITE bool "PMC-Sierra Yosemite eval board" - select CEVT_R4K select DMA_COHERENT select HW_HAS_PCI select IRQ_CPU @@ -349,7 +335,6 @@ config PMC_YOSEMITE config QEMU bool "Qemu" - select CEVT_R4K select DMA_COHERENT select GENERIC_ISA_DMA select HAVE_STD_PC_SERIAL_PORT @@ -380,7 +365,6 @@ config SGI_IP22 select ARC select ARC32 select BOOT_ELF32 - select CEVT_R4K select DMA_NONCOHERENT select HW_HAS_EISA select I8253 @@ -425,7 +409,6 @@ config SGI_IP32 select ARC select ARC32 select BOOT_ELF32 - select CEVT_R4K select DMA_NONCOHERENT select HW_HAS_PCI select IRQ_CPU @@ -553,7 +536,6 @@ config SNI_RM select ARC32 if CPU_LITTLE_ENDIAN select ARCH_MAY_HAVE_PC_FDC select BOOT_ELF32 - select CEVT_R4K select DMA_NONCOHERENT select GENERIC_ISA_DMA select HW_HAS_EISA @@ -595,7 +577,6 @@ config TOSHIBA_JMR3927 config TOSHIBA_RBTX4927 bool "Toshiba RBTX49[23]7 board" - select CEVT_R4K select DMA_NONCOHERENT select HAS_TXX9_SERIAL select HW_HAS_PCI @@ -616,7 +597,6 @@ config TOSHIBA_RBTX4927 config TOSHIBA_RBTX4938 bool "Toshiba RBTX4938 board" - select CEVT_R4K select DMA_NONCOHERENT select HAS_TXX9_SERIAL select HW_HAS_PCI @@ -636,7 +616,6 @@ config TOSHIBA_RBTX4938 config WR_PPMC bool "Wind River PPMC board" - select CEVT_R4K select IRQ_CPU select BOOT_ELF32 select DMA_NONCOHERENT @@ -729,9 +708,6 @@ config ARCH_MAY_HAVE_PC_FDC config BOOT_RAW bool -config CEVT_R4K - bool - config CFE bool @@ -2005,7 +1981,7 @@ source "drivers/Kconfig" source "fs/Kconfig" -source "kernel/Kconfig.instrumentation" +source "arch/mips/oprofile/Kconfig" source "arch/mips/Kconfig.debug" diff --git a/trunk/arch/mips/au1000/Kconfig b/trunk/arch/mips/au1000/Kconfig index b36cec58a9a8..a23d4154da01 100644 --- a/trunk/arch/mips/au1000/Kconfig +++ b/trunk/arch/mips/au1000/Kconfig @@ -137,7 +137,6 @@ config SOC_AU1200 config SOC_AU1X00 bool select 64BIT_PHYS_ADDR - select CEVT_R4K select IRQ_CPU select SYS_HAS_CPU_MIPS32_R1 select SYS_SUPPORTS_32BIT_KERNEL diff --git a/trunk/arch/mips/au1000/pb1200/irqmap.c b/trunk/arch/mips/au1000/pb1200/irqmap.c index bdf00e2a35e4..5f48b0603796 100644 --- a/trunk/arch/mips/au1000/pb1200/irqmap.c +++ b/trunk/arch/mips/au1000/pb1200/irqmap.c @@ -36,8 +36,8 @@ #include #include #include -#include +#include #include #include #include diff --git a/trunk/arch/mips/basler/excite/excite_irq.c b/trunk/arch/mips/basler/excite/excite_irq.c index 4903e067916b..1ecab6350421 100644 --- a/trunk/arch/mips/basler/excite/excite_irq.c +++ b/trunk/arch/mips/basler/excite/excite_irq.c @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/trunk/arch/mips/bcm47xx/time.c b/trunk/arch/mips/bcm47xx/time.c index 0c6f47b3fd94..0ab4676c8bd3 100644 --- a/trunk/arch/mips/bcm47xx/time.c +++ b/trunk/arch/mips/bcm47xx/time.c @@ -46,3 +46,10 @@ void __init plat_time_init(void) /* Set MIPS counter frequency for fixed_rate_gettimeoffset() */ mips_hpt_frequency = hz; } + +void __init +plat_timer_setup(struct irqaction *irq) +{ + /* Enable the timer interrupt */ + setup_irq(7, irq); +} diff --git a/trunk/arch/mips/configs/ip27_defconfig b/trunk/arch/mips/configs/ip27_defconfig index 892d4c38fd0d..49bcc58929ba 100644 --- a/trunk/arch/mips/configs/ip27_defconfig +++ b/trunk/arch/mips/configs/ip27_defconfig @@ -175,7 +175,6 @@ CONFIG_POSIX_MQUEUE=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=15 -CONFIG_CGROUPS=y CONFIG_CPUSETS=y CONFIG_SYSFS_DEPRECATED=y CONFIG_RELAY=y diff --git a/trunk/arch/mips/configs/mipssim_defconfig b/trunk/arch/mips/configs/mipssim_defconfig index 61b72f5a953e..86dcb7464353 100644 --- a/trunk/arch/mips/configs/mipssim_defconfig +++ b/trunk/arch/mips/configs/mipssim_defconfig @@ -1,68 +1,71 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.23 -# Thu Oct 18 22:45:52 2007 +# Linux kernel version: 2.6.20 +# Tue Feb 20 21:47:35 2007 # CONFIG_MIPS=y # # Machine selection # -# CONFIG_MACH_ALCHEMY is not set +CONFIG_ZONE_DMA=y +# CONFIG_MIPS_MTX1 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_PB1550 is not set +# CONFIG_MIPS_PB1200 is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_DB1550 is not set +# CONFIG_MIPS_DB1200 is not set +# CONFIG_MIPS_MIRAGE is not set # CONFIG_BASLER_EXCITE is not set -# CONFIG_BCM47XX is not set # CONFIG_MIPS_COBALT is not set # CONFIG_MACH_DECSTATION is not set # CONFIG_MACH_JAZZ is not set -# CONFIG_LASAT is not set -# CONFIG_LEMOTE_FULONG is not set # CONFIG_MIPS_ATLAS is not set # CONFIG_MIPS_MALTA is not set # CONFIG_MIPS_SEAD is not set +# CONFIG_WR_PPMC is not set CONFIG_MIPS_SIM=y -# CONFIG_MARKEINS is not set -# CONFIG_MACH_VR41XX is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_MIPS_XXS1500 is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set -# CONFIG_PMC_MSP is not set +# CONFIG_MACH_VR41XX is not set # CONFIG_PMC_YOSEMITE is not set # CONFIG_QEMU is not set +# CONFIG_MARKEINS is not set # CONFIG_SGI_IP22 is not set # CONFIG_SGI_IP27 is not set # CONFIG_SGI_IP32 is not set -# CONFIG_SIBYTE_CRHINE is not set -# CONFIG_SIBYTE_CARMEL is not set -# CONFIG_SIBYTE_CRHONE is not set -# CONFIG_SIBYTE_RHONE is not set +# CONFIG_SIBYTE_BIGSUR is not set # CONFIG_SIBYTE_SWARM is not set -# CONFIG_SIBYTE_LITTLESUR is not set # CONFIG_SIBYTE_SENTOSA is not set +# CONFIG_SIBYTE_RHONE is not set +# CONFIG_SIBYTE_CARMEL is not set # CONFIG_SIBYTE_PTSWARM is not set -# CONFIG_SIBYTE_BIGSUR is not set +# CONFIG_SIBYTE_LITTLESUR is not set +# CONFIG_SIBYTE_CRHINE is not set +# CONFIG_SIBYTE_CRHONE is not set # CONFIG_SNI_RM is not set # CONFIG_TOSHIBA_JMR3927 is not set # CONFIG_TOSHIBA_RBTX4927 is not set # CONFIG_TOSHIBA_RBTX4938 is not set -# CONFIG_WR_PPMC is not set CONFIG_RWSEM_GENERIC_SPINLOCK=y # CONFIG_ARCH_HAS_ILOG2_U32 is not set # CONFIG_ARCH_HAS_ILOG2_U64 is not set CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_GENERIC_TIME=y -CONFIG_GENERIC_CMOS_UPDATE=y CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y # CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set -CONFIG_BOOT_RAW=y -CONFIG_CEVT_R4K=y CONFIG_DMA_NONCOHERENT=y CONFIG_DMA_NEED_PCI_MAP_STATE=y -CONFIG_EARLY_PRINTK=y -CONFIG_SYS_HAS_EARLY_PRINTK=y -# CONFIG_HOTPLUG_CPU is not set -# CONFIG_NO_IOPORT is not set # CONFIG_CPU_BIG_ENDIAN is not set CONFIG_CPU_LITTLE_ENDIAN=y CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y @@ -73,11 +76,6 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5 # # CPU selection # -# CONFIG_TICK_ONESHOT is not set -# CONFIG_NO_HZ is not set -# CONFIG_HIGH_RES_TIMERS is not set -CONFIG_GENERIC_CLOCKEVENTS_BUILD=y -# CONFIG_CPU_LOONGSON2 is not set CONFIG_CPU_MIPS32_R1=y # CONFIG_CPU_MIPS32_R2 is not set # CONFIG_CPU_MIPS64_R1 is not set @@ -117,8 +115,8 @@ CONFIG_CPU_HAS_PREFETCH=y CONFIG_MIPS_MT_DISABLED=y # CONFIG_MIPS_MT_SMP is not set # CONFIG_MIPS_MT_SMTC is not set -CONFIG_SYS_SUPPORTS_MULTITHREADING=y # CONFIG_MIPS_VPE_LOADER is not set +# CONFIG_64BIT_PHYS_ADDR is not set CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_SYNC=y CONFIG_GENERIC_HARDIRQS=y @@ -132,52 +130,50 @@ CONFIG_FLATMEM_MANUAL=y CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set -# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set -CONFIG_ZONE_DMA_FLAG=0 -CONFIG_VIRT_TO_BUS=y +CONFIG_ZONE_DMA_FLAG=1 # CONFIG_HZ_48 is not set -CONFIG_HZ_100=y +# CONFIG_HZ_100 is not set # CONFIG_HZ_128 is not set # CONFIG_HZ_250 is not set # CONFIG_HZ_256 is not set -# CONFIG_HZ_1000 is not set +CONFIG_HZ_1000=y # CONFIG_HZ_1024 is not set CONFIG_SYS_SUPPORTS_ARBIT_HZ=y -CONFIG_HZ=100 +CONFIG_HZ=1000 CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set # CONFIG_KEXEC is not set -# CONFIG_SECCOMP is not set CONFIG_LOCKDEP_SUPPORT=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # -# General setup +# Code maturity level options # CONFIG_EXPERIMENTAL=y CONFIG_BROKEN_ON_SMP=y CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# CONFIG_LOCALVERSION="" CONFIG_LOCALVERSION_AUTO=y -# CONFIG_SWAP is not set +CONFIG_SWAP=y CONFIG_SYSVIPC=y +# CONFIG_IPC_NS is not set CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set -# CONFIG_USER_NS is not set +# CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_FAIR_GROUP_SCHED=y -CONFIG_FAIR_USER_SCHED=y CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set -# CONFIG_BLK_DEV_INITRD is not set # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y CONFIG_EMBEDDED=y @@ -191,29 +187,31 @@ CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y -CONFIG_ANON_INODES=y CONFIG_EPOLL=y -CONFIG_SIGNALFD=y -CONFIG_EVENTFD=y CONFIG_SHMEM=y -CONFIG_VM_EVENT_COUNTERS=y CONFIG_SLAB=y -# CONFIG_SLUB is not set -# CONFIG_SLOB is not set +CONFIG_VM_EVENT_COUNTERS=y CONFIG_RT_MUTEXES=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 +# CONFIG_SLOB is not set + +# +# Loadable module support +# CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set CONFIG_MODVERSIONS=y CONFIG_MODULE_SRCVERSION_ALL=y CONFIG_KMOD=y + +# +# Block layer +# CONFIG_BLOCK=y # CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_LSF is not set -# CONFIG_BLK_DEV_BSG is not set # # IO Schedulers @@ -231,10 +229,17 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # # Bus options (PCI, PCMCIA, EISA, ISA, TC) # -# CONFIG_ARCH_SUPPORTS_MSI is not set CONFIG_MMU=y + +# +# PCCARD (PCMCIA/CardBus) support +# # CONFIG_PCCARD is not set +# +# PCI Hotplug Support +# + # # Executable file formats # @@ -245,8 +250,9 @@ CONFIG_TRAD_SIGNALS=y # # Power management options # -# CONFIG_PM is not set -CONFIG_SUSPEND_UP_POSSIBLE=y +CONFIG_PM=y +# CONFIG_PM_LEGACY is not set +# CONFIG_PM_DEBUG is not set # # Networking @@ -256,50 +262,75 @@ CONFIG_NET=y # # Networking options # +# CONFIG_NETDEBUG is not set CONFIG_PACKET=y CONFIG_PACKET_MMAP=y CONFIG_UNIX=y -# CONFIG_NET_KEY is not set +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_XFRM_SUB_POLICY is not set +CONFIG_XFRM_MIGRATE=y +CONFIG_NET_KEY=y +CONFIG_NET_KEY_MIGRATE=y CONFIG_INET=y CONFIG_IP_MULTICAST=y CONFIG_IP_ADVANCED_ROUTER=y CONFIG_ASK_IP_FIB_HASH=y # CONFIG_IP_FIB_TRIE is not set CONFIG_IP_FIB_HASH=y -# CONFIG_IP_MULTIPLE_TABLES is not set -# CONFIG_IP_ROUTE_MULTIPATH is not set -# CONFIG_IP_ROUTE_VERBOSE is not set +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_MULTIPATH=y +# CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set +CONFIG_IP_ROUTE_VERBOSE=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y # CONFIG_IP_PNP_RARP is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set +CONFIG_IP_MROUTE=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y # CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set +CONFIG_SYN_COOKIES=y # CONFIG_INET_AH is not set # CONFIG_INET_ESP is not set # CONFIG_INET_IPCOMP is not set # CONFIG_INET_XFRM_TUNNEL is not set # CONFIG_INET_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET_XFRM_MODE_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=m +CONFIG_INET_XFRM_MODE_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=m CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_TCP_MD5SIG is not set +CONFIG_TCP_MD5SIG=y # CONFIG_IPV6 is not set # CONFIG_INET6_XFRM_TUNNEL is not set # CONFIG_INET6_TUNNEL is not set -# CONFIG_NETWORK_SECMARK is not set +CONFIG_NETWORK_SECMARK=y # CONFIG_NETFILTER is not set + +# +# DCCP Configuration (EXPERIMENTAL) +# # CONFIG_IP_DCCP is not set -# CONFIG_IP_SCTP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +CONFIG_IP_SCTP=m +# CONFIG_SCTP_DBG_MSG is not set +# CONFIG_SCTP_DBG_OBJCNT is not set +# CONFIG_SCTP_HMAC_NONE is not set +# CONFIG_SCTP_HMAC_SHA1 is not set +CONFIG_SCTP_HMAC_MD5=y + +# +# TIPC Configuration (EXPERIMENTAL) +# # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set @@ -316,7 +347,44 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # # QoS and/or fair queueing # -# CONFIG_NET_SCHED is not set +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_FIFO=y +CONFIG_NET_SCH_CLK_JIFFIES=y +# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set +# CONFIG_NET_SCH_CLK_CPU is not set + +# +# Queueing/Scheduling +# +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_NETEM=m +CONFIG_NET_SCH_INGRESS=m + +# +# Classification +# +CONFIG_NET_CLS=y +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_ROUTE=y +# CONFIG_NET_CLS_FW is not set +# CONFIG_NET_CLS_U32 is not set +# CONFIG_NET_CLS_RSVP is not set +# CONFIG_NET_CLS_RSVP6 is not set +# CONFIG_NET_EMATCH is not set +# CONFIG_NET_CLS_ACT is not set +# CONFIG_NET_CLS_POLICE is not set +CONFIG_NET_ESTIMATOR=y # # Network testing @@ -325,17 +393,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set # CONFIG_BT is not set -# CONFIG_AF_RXRPC is not set - -# -# Wireless -# -# CONFIG_CFG80211 is not set -# CONFIG_WIRELESS_EXT is not set -# CONFIG_MAC80211 is not set # CONFIG_IEEE80211 is not set -# CONFIG_RFKILL is not set -# CONFIG_NET_9P is not set +CONFIG_FIB_RULES=y # # Device Drivers @@ -344,25 +403,52 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # # Generic Driver Options # -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_STANDALONE is not set # CONFIG_PREVENT_FIRMWARE_BUILD is not set # CONFIG_FW_LOADER is not set # CONFIG_DEBUG_DRIVER is not set # CONFIG_DEBUG_DEVRES is not set # CONFIG_SYS_HYPERVISOR is not set + +# +# Connector - unified userspace <-> kernelspace linker +# # CONFIG_CONNECTOR is not set + +# +# Memory Technology Devices (MTD) +# # CONFIG_MTD is not set + +# +# Parallel port support +# # CONFIG_PARPORT is not set -CONFIG_BLK_DEV=y + +# +# Plug and Play support +# +# CONFIG_PNPACPI is not set + +# +# Block devices +# # CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_CRYPTOLOOP is not set CONFIG_BLK_DEV_NBD=y # CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set -# CONFIG_MISC_DEVICES is not set + +# +# Misc devices +# + +# +# ATA/ATAPI/MFM/RLL support +# # CONFIG_IDE is not set # @@ -370,29 +456,48 @@ CONFIG_BLK_DEV_NBD=y # # CONFIG_RAID_ATTRS is not set # CONFIG_SCSI is not set -# CONFIG_SCSI_DMA is not set # CONFIG_SCSI_NETLINK is not set + +# +# Serial ATA (prod) and Parallel ATA (experimental) drivers +# # CONFIG_ATA is not set + +# +# Multi-device support (RAID and LVM) +# # CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# + +# +# I2O device support +# + +# +# Network device support +# CONFIG_NETDEVICES=y -# CONFIG_NETDEVICES_MULTIQUEUE is not set # CONFIG_DUMMY is not set # CONFIG_BONDING is not set -# CONFIG_MACVLAN is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set -# CONFIG_VETH is not set # CONFIG_PHYLIB is not set + +# +# Ethernet (10 or 100Mbit) +# CONFIG_NET_ETHERNET=y # CONFIG_MII is not set -# CONFIG_AX88796 is not set CONFIG_MIPS_SIM_NET=y # CONFIG_DM9000 is not set -# CONFIG_IBM_NEW_EMAC_ZMII is not set -# CONFIG_IBM_NEW_EMAC_RGMII is not set -# CONFIG_IBM_NEW_EMAC_TAH is not set -# CONFIG_IBM_NEW_EMAC_EMAC4 is not set -# CONFIG_B44 is not set # CONFIG_NETDEV_1000 is not set # CONFIG_NETDEV_10000 is not set @@ -408,18 +513,49 @@ CONFIG_MIPS_SIM_NET=y # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set + +# +# ISDN subsystem +# # CONFIG_ISDN is not set + +# +# Telephony Support +# # CONFIG_PHONE is not set # # Input device support # -# CONFIG_INPUT is not set +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set # # Hardware I/O ports # -# CONFIG_SERIO is not set +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_LIBPS2 is not set +# CONFIG_SERIO_RAW is not set # CONFIG_GAMEPORT is not set # @@ -445,13 +581,31 @@ CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# # CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# # CONFIG_WATCHDOG is not set # CONFIG_HW_RANDOM is not set # CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set +# CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# # CONFIG_TCG_TPM is not set + +# +# I2C support +# # CONFIG_I2C is not set # @@ -459,60 +613,118 @@ CONFIG_LEGACY_PTY_COUNT=256 # # CONFIG_SPI is not set # CONFIG_SPI_MASTER is not set -# CONFIG_W1 is not set -# CONFIG_POWER_SUPPLY is not set -# CONFIG_HWMON is not set # -# Sonics Silicon Backplane +# Dallas's 1-wire bus # -CONFIG_SSB_POSSIBLE=y -# CONFIG_SSB is not set +# CONFIG_W1 is not set # -# Multifunction device drivers +# Hardware Monitoring support # -# CONFIG_MFD_SM501 is not set +# CONFIG_HWMON is not set +# CONFIG_HWMON_VID is not set # # Multimedia devices # # CONFIG_VIDEO_DEV is not set -# CONFIG_DVB_CORE is not set -# CONFIG_DAB is not set # -# Graphics support +# Digital Video Broadcasting Devices # -# CONFIG_VGASTATE is not set -# CONFIG_VIDEO_OUTPUT_CONTROL is not set -# CONFIG_FB is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +# CONFIG_DVB is not set # -# Display device support +# Graphics support # -# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_FIRMWARE_EDID is not set +# CONFIG_FB is not set # # Sound # # CONFIG_SOUND is not set -# CONFIG_USB_SUPPORT is not set + +# +# HID Devices +# +# CONFIG_HID is not set + +# +# USB support +# +# CONFIG_USB_ARCH_HAS_HCD is not set +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB_ARCH_HAS_EHCI is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# # CONFIG_MMC is not set + +# +# LED devices +# # CONFIG_NEW_LEDS is not set -CONFIG_RTC_LIB=y + +# +# LED drivers +# + +# +# LED Triggers +# + +# +# InfiniBand support +# + +# +# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) +# + +# +# Real Time Clock +# # CONFIG_RTC_CLASS is not set # -# Userspace I/O +# DMA Engine support +# +# CONFIG_DMA_ENGINE is not set + +# +# DMA Clients +# + +# +# DMA Devices +# + +# +# Auxiliary Display support +# + +# +# Virtualization # -# CONFIG_UIO is not set # # File systems # -# CONFIG_EXT2_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set # CONFIG_EXT3_FS is not set # CONFIG_EXT4DEV_FS is not set # CONFIG_REISERFS_FS is not set @@ -520,7 +732,6 @@ CONFIG_RTC_LIB=y # CONFIG_FS_POSIX_ACL is not set # CONFIG_XFS_FS is not set # CONFIG_GFS2_FS is not set -# CONFIG_OCFS2_FS is not set # CONFIG_MINIX_FS is not set CONFIG_ROMFS_FS=y # CONFIG_INOTIFY is not set @@ -549,11 +760,10 @@ CONFIG_ROMFS_FS=y CONFIG_PROC_FS=y # CONFIG_PROC_KCORE is not set CONFIG_PROC_SYSCTL=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_SYSFS is not set +# CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set -# CONFIG_CONFIGFS_FS is not set +CONFIG_RAMFS=y # # Miscellaneous filesystems @@ -571,7 +781,10 @@ CONFIG_TMPFS=y # CONFIG_QNX4FS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set -CONFIG_NETWORK_FILESYSTEMS=y + +# +# Network File Systems +# CONFIG_NFS_FS=y CONFIG_NFS_V3=y # CONFIG_NFS_V3_ACL is not set @@ -583,7 +796,6 @@ CONFIG_LOCKD=y CONFIG_LOCKD_V4=y CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y -# CONFIG_SUNRPC_BIND34 is not set # CONFIG_RPCSEC_GSS_KRB5 is not set # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set @@ -591,14 +803,22 @@ CONFIG_SUNRPC=y # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set # # Partition Types # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# # CONFIG_NLS is not set -# CONFIG_DLM is not set + +# +# Distributed Lock Manager +# # # Profiling support @@ -613,22 +833,20 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y CONFIG_ENABLE_MUST_CHECK=y # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_DEBUG_FS is not set # CONFIG_HEADERS_CHECK is not set CONFIG_DEBUG_KERNEL=y # CONFIG_DEBUG_SHIRQ is not set +CONFIG_LOG_BUF_SHIFT=14 # CONFIG_DETECT_SOFTLOCKUP is not set -# CONFIG_SCHED_DEBUG is not set # CONFIG_SCHEDSTATS is not set # CONFIG_TIMER_STATS is not set # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_RT_MUTEXES is not set # CONFIG_RT_MUTEX_TESTER is not set # CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_DEBUG_MUTEXES is not set +CONFIG_DEBUG_MUTEXES=y # CONFIG_DEBUG_LOCK_ALLOC is not set # CONFIG_PROVE_LOCKING is not set -# CONFIG_LOCK_STAT is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set @@ -636,9 +854,7 @@ CONFIG_DEBUG_INFO=y # CONFIG_DEBUG_VM is not set # CONFIG_DEBUG_LIST is not set CONFIG_FORCED_INLINING=y -# CONFIG_BOOT_PRINTK_DELAY is not set # CONFIG_RCU_TORTURE_TEST is not set -# CONFIG_FAULT_INJECTION is not set CONFIG_CROSSCOMPILE=y CONFIG_CMDLINE="nfsroot=192.168.192.169:/u1/mipsel,timeo=20 ip=dhcp" # CONFIG_DEBUG_STACK_USAGE is not set @@ -649,20 +865,60 @@ CONFIG_CMDLINE="nfsroot=192.168.192.169:/u1/mipsel,timeo=20 ip=dhcp" # Security options # # CONFIG_KEYS is not set -# CONFIG_SECURITY is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set -# CONFIG_CRYPTO is not set + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_BLKCIPHER=m +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_XCBC=m +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_CBC=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_LRW=m +# CONFIG_CRYPTO_DES is not set +CONFIG_CRYPTO_FCRYPT=m +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_CRC32C is not set +CONFIG_CRYPTO_CAMELLIA=m +# CONFIG_CRYPTO_TEST is not set + +# +# Hardware crypto devices +# # # Library routines # +CONFIG_BITREVERSE=y # CONFIG_CRC_CCITT is not set -# CONFIG_CRC16 is not set -# CONFIG_CRC_ITU_T is not set -# CONFIG_CRC32 is not set -# CONFIG_CRC7 is not set +CONFIG_CRC16=y +CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set CONFIG_PLIST=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y -CONFIG_HAS_DMA=y diff --git a/trunk/arch/mips/configs/sb1250-swarm_defconfig b/trunk/arch/mips/configs/sb1250-swarm_defconfig index 49dfcef2518c..3ed991ae0ebe 100644 --- a/trunk/arch/mips/configs/sb1250-swarm_defconfig +++ b/trunk/arch/mips/configs/sb1250-swarm_defconfig @@ -196,7 +196,6 @@ CONFIG_SYSVIPC_SYSCTL=y # CONFIG_UTS_NS is not set # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set -CONFIG_CGROUPS=y CONFIG_CPUSETS=y CONFIG_SYSFS_DEPRECATED=y CONFIG_RELAY=y diff --git a/trunk/arch/mips/emma2rh/markeins/setup.c b/trunk/arch/mips/emma2rh/markeins/setup.c index 82f9e9013e70..5e1da53b04a7 100644 --- a/trunk/arch/mips/emma2rh/markeins/setup.c +++ b/trunk/arch/mips/emma2rh/markeins/setup.c @@ -104,6 +104,12 @@ void __init plat_time_init(void) mips_hpt_frequency = (bus_frequency * (4 + reg)) / 4 / 2; } +void __init plat_timer_setup(struct irqaction *irq) +{ + /* we are using the cpu counter for timer interrupts */ + setup_irq(CPU_IRQ_BASE + 7, irq); +} + static void markeins_board_init(void); extern void markeins_irq_setup(void); diff --git a/trunk/arch/mips/jazz/irq.c b/trunk/arch/mips/jazz/irq.c index ae25b480723e..835b056cea36 100644 --- a/trunk/arch/mips/jazz/irq.c +++ b/trunk/arch/mips/jazz/irq.c @@ -4,7 +4,7 @@ * for more details. * * Copyright (C) 1992 Linus Torvalds - * Copyright (C) 1994 - 2001, 2003, 07 Ralf Baechle + * Copyright (C) 1994 - 2001, 2003 Ralf Baechle */ #include #include @@ -13,7 +13,6 @@ #include #include -#include #include #include #include @@ -137,7 +136,7 @@ static struct irqaction r4030_timer_irqaction = { .name = "timer", }; -void __init plat_time_init(void) +void __init plat_timer_setup(struct irqaction *ignored) { struct irqaction *irq = &r4030_timer_irqaction; @@ -153,5 +152,4 @@ void __init plat_time_init(void) setup_irq(JAZZ_TIMER_IRQ, irq); clockevents_register_device(&r4030_clockevent); - setup_pit_timer(); } diff --git a/trunk/arch/mips/jazz/setup.c b/trunk/arch/mips/jazz/setup.c index a7857973ca03..cfc7dce78dab 100644 --- a/trunk/arch/mips/jazz/setup.c +++ b/trunk/arch/mips/jazz/setup.c @@ -5,7 +5,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1996, 1997, 1998, 2001, 07 by Ralf Baechle + * Copyright (C) 1996, 1997, 1998, 2001 by Ralf Baechle * Copyright (C) 2001 MIPS Technologies, Inc. * Copyright (C) 2007 by Thomas Bogendoerfer */ @@ -25,6 +25,7 @@ #include #include +#include #include #include #include @@ -63,6 +64,11 @@ static struct resource jazz_io_resources[] = { } }; +void __init plat_time_init(void) +{ + setup_pit_timer(); +} + void __init plat_mem_setup(void) { int i; diff --git a/trunk/arch/mips/jmr3927/rbhma3100/setup.c b/trunk/arch/mips/jmr3927/rbhma3100/setup.c index edb9e59248ec..0c7aee1682cd 100644 --- a/trunk/arch/mips/jmr3927/rbhma3100/setup.c +++ b/trunk/arch/mips/jmr3927/rbhma3100/setup.c @@ -1,4 +1,15 @@ -/* +/*********************************************************************** + * + * Copyright 2001 MontaVista Software Inc. + * Author: MontaVista Software, Inc. + * ahennessy@mvista.com + * + * Based on arch/mips/ddb5xxx/ddb5477/setup.c + * + * Setup file for JMR3927. + * + * Copyright (C) 2000-2001 Toshiba Corporation + * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your @@ -19,15 +30,9 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. * - * Copyright 2001 MontaVista Software Inc. - * Author: MontaVista Software, Inc. - * ahennessy@mvista.com - * - * Copyright (C) 2000-2001 Toshiba Corporation - * Copyright (C) 2007 Ralf Baechle (ralf@linux-mips.org) + *********************************************************************** */ -#include #include #include #include @@ -99,60 +104,27 @@ static cycle_t jmr3927_hpt_read(void) return jiffies * (JMR3927_TIMER_CLK / HZ) + jmr3927_tmrptr->trr; } -static void jmr3927_set_mode(enum clock_event_mode mode, - struct clock_event_device *evt) -{ - /* Nothing to do here */ -} - -struct clock_event_device jmr3927_clock_event_device = { - .name = "MIPS", - .features = CLOCK_EVT_FEAT_PERIODIC, - .shift = 32, - .rating = 300, - .cpumask = CPU_MASK_CPU0, - .irq = JMR3927_IRQ_TICK, - .set_mode = jmr3927_set_mode, -}; - -static irqreturn_t jmr3927_timer_interrupt(int irq, void *dev_id) +static void jmr3927_timer_ack(void) { - struct clock_event_device *cd = &jmr3927_clock_event_device; - jmr3927_tmrptr->tisr = 0; /* ack interrupt */ - - cd->event_handler(cd); - - return IRQ_HANDLED; } -static struct irqaction jmr3927_timer_irqaction = { - .handler = jmr3927_timer_interrupt, - .flags = IRQF_DISABLED | IRQF_PERCPU, - .name = "jmr3927-timer", -}; - void __init plat_time_init(void) { - struct clock_event_device *cd; - clocksource_mips.read = jmr3927_hpt_read; + mips_timer_ack = jmr3927_timer_ack; mips_hpt_frequency = JMR3927_TIMER_CLK; +} +void __init plat_timer_setup(struct irqaction *irq) +{ jmr3927_tmrptr->cpra = JMR3927_TIMER_CLK / HZ; jmr3927_tmrptr->itmr = TXx927_TMTITMR_TIIE | TXx927_TMTITMR_TZCE; jmr3927_tmrptr->ccdr = JMR3927_TIMER_CCD; jmr3927_tmrptr->tcr = TXx927_TMTCR_TCE | TXx927_TMTCR_CCDE | TXx927_TMTCR_TMODE_ITVL; - cd = &jmr3927_clock_event_device; - /* Calculate the min / max delta */ - cd->mult = div_sc((unsigned long) JMR3927_IMCLK, NSEC_PER_SEC, 32); - cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); - cd->min_delta_ns = clockevent_delta2ns(0x300, cd); - clockevents_register_device(cd); - - setup_irq(JMR3927_IRQ_TICK, &jmr3927_timer_irqaction); + setup_irq(JMR3927_IRQ_TICK, irq); } #define DO_WRITE_THROUGH diff --git a/trunk/arch/mips/kernel/Makefile b/trunk/arch/mips/kernel/Makefile index a3afa39faae5..95a356ef3910 100644 --- a/trunk/arch/mips/kernel/Makefile +++ b/trunk/arch/mips/kernel/Makefile @@ -8,8 +8,6 @@ obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \ ptrace.o reset.o semaphore.o setup.o signal.o syscall.o \ time.o topology.o traps.o unaligned.o -obj-$(CONFIG_CEVT_R4K) += cevt-r4k.o - binfmt_irix-objs := irixelf.o irixinv.o irixioctl.o irixsig.o \ irix5sys.o sysirix.o diff --git a/trunk/arch/mips/kernel/cevt-r4k.c b/trunk/arch/mips/kernel/cevt-r4k.c deleted file mode 100644 index a915e5693421..000000000000 --- a/trunk/arch/mips/kernel/cevt-r4k.c +++ /dev/null @@ -1,273 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2007 MIPS Technologies, Inc. - * Copyright (C) 2007 Ralf Baechle - */ -#include -#include -#include - -#include -#include - -static int mips_next_event(unsigned long delta, - struct clock_event_device *evt) -{ - unsigned int cnt; - int res; - -#ifdef CONFIG_MIPS_MT_SMTC - { - unsigned long flags, vpflags; - local_irq_save(flags); - vpflags = dvpe(); -#endif - cnt = read_c0_count(); - cnt += delta; - write_c0_compare(cnt); - res = ((long)(read_c0_count() - cnt ) > 0) ? -ETIME : 0; -#ifdef CONFIG_MIPS_MT_SMTC - evpe(vpflags); - local_irq_restore(flags); - } -#endif - return res; -} - -static void mips_set_mode(enum clock_event_mode mode, - struct clock_event_device *evt) -{ - /* Nothing to do ... */ -} - -static DEFINE_PER_CPU(struct clock_event_device, mips_clockevent_device); -static int cp0_timer_irq_installed; - -/* - * Timer ack for an R4k-compatible timer of a known frequency. - */ -static void c0_timer_ack(void) -{ - write_c0_compare(read_c0_compare()); -} - -/* - * Possibly handle a performance counter interrupt. - * Return true if the timer interrupt should not be checked - */ -static inline int handle_perf_irq(int r2) -{ - /* - * The performance counter overflow interrupt may be shared with the - * timer interrupt (cp0_perfcount_irq < 0). If it is and a - * performance counter has overflowed (perf_irq() == IRQ_HANDLED) - * and we can't reliably determine if a counter interrupt has also - * happened (!r2) then don't check for a timer interrupt. - */ - return (cp0_perfcount_irq < 0) && - perf_irq() == IRQ_HANDLED && - !r2; -} - -static irqreturn_t c0_compare_interrupt(int irq, void *dev_id) -{ - const int r2 = cpu_has_mips_r2; - struct clock_event_device *cd; - int cpu = smp_processor_id(); - - /* - * Suckage alert: - * Before R2 of the architecture there was no way to see if a - * performance counter interrupt was pending, so we have to run - * the performance counter interrupt handler anyway. - */ - if (handle_perf_irq(r2)) - goto out; - - /* - * The same applies to performance counter interrupts. But with the - * above we now know that the reason we got here must be a timer - * interrupt. Being the paranoiacs we are we check anyway. - */ - if (!r2 || (read_c0_cause() & (1 << 30))) { - c0_timer_ack(); -#ifdef CONFIG_MIPS_MT_SMTC - if (cpu_data[cpu].vpe_id) - goto out; - cpu = 0; -#endif - cd = &per_cpu(mips_clockevent_device, cpu); - cd->event_handler(cd); - } - -out: - return IRQ_HANDLED; -} - -static struct irqaction c0_compare_irqaction = { - .handler = c0_compare_interrupt, -#ifdef CONFIG_MIPS_MT_SMTC - .flags = IRQF_DISABLED, -#else - .flags = IRQF_DISABLED | IRQF_PERCPU, -#endif - .name = "timer", -}; - -#ifdef CONFIG_MIPS_MT_SMTC -DEFINE_PER_CPU(struct clock_event_device, smtc_dummy_clockevent_device); - -static void smtc_set_mode(enum clock_event_mode mode, - struct clock_event_device *evt) -{ -} - -static void mips_broadcast(cpumask_t mask) -{ - unsigned int cpu; - - for_each_cpu_mask(cpu, mask) - smtc_send_ipi(cpu, SMTC_CLOCK_TICK, 0); -} - -static void setup_smtc_dummy_clockevent_device(void) -{ - //uint64_t mips_freq = mips_hpt_^frequency; - unsigned int cpu = smp_processor_id(); - struct clock_event_device *cd; - - cd = &per_cpu(smtc_dummy_clockevent_device, cpu); - - cd->name = "SMTC"; - cd->features = CLOCK_EVT_FEAT_DUMMY; - - /* Calculate the min / max delta */ - cd->mult = 0; //div_sc((unsigned long) mips_freq, NSEC_PER_SEC, 32); - cd->shift = 0; //32; - cd->max_delta_ns = 0; //clockevent_delta2ns(0x7fffffff, cd); - cd->min_delta_ns = 0; //clockevent_delta2ns(0x30, cd); - - cd->rating = 200; - cd->irq = 17; //-1; -// if (cpu) -// cd->cpumask = CPU_MASK_ALL; // cpumask_of_cpu(cpu); -// else - cd->cpumask = cpumask_of_cpu(cpu); - - cd->set_mode = smtc_set_mode; - - cd->broadcast = mips_broadcast; - - clockevents_register_device(cd); -} -#endif - -static void mips_event_handler(struct clock_event_device *dev) -{ -} - -/* - * FIXME: This doesn't hold for the relocated E9000 compare interrupt. - */ -static int c0_compare_int_pending(void) -{ - return (read_c0_cause() >> cp0_compare_irq) & 0x100; -} - -static int c0_compare_int_usable(void) -{ - const unsigned int delta = 0x300000; - unsigned int cnt; - - /* - * IP7 already pending? Try to clear it by acking the timer. - */ - if (c0_compare_int_pending()) { - write_c0_compare(read_c0_compare()); - irq_disable_hazard(); - if (c0_compare_int_pending()) - return 0; - } - - cnt = read_c0_count(); - cnt += delta; - write_c0_compare(cnt); - - while ((long)(read_c0_count() - cnt) <= 0) - ; /* Wait for expiry */ - - if (!c0_compare_int_pending()) - return 0; - - write_c0_compare(read_c0_compare()); - irq_disable_hazard(); - if (c0_compare_int_pending()) - return 0; - - /* - * Feels like a real count / compare timer. - */ - return 1; -} - -void __cpuinit mips_clockevent_init(void) -{ - uint64_t mips_freq = mips_hpt_frequency; - unsigned int cpu = smp_processor_id(); - struct clock_event_device *cd; - unsigned int irq = MIPS_CPU_IRQ_BASE + 7; - - if (!cpu_has_counter) - return; - -#ifdef CONFIG_MIPS_MT_SMTC - setup_smtc_dummy_clockevent_device(); - - /* - * On SMTC we only register VPE0's compare interrupt as clockevent - * device. - */ - if (cpu) - return; -#endif - - if (!c0_compare_int_usable()) - return; - - cd = &per_cpu(mips_clockevent_device, cpu); - - cd->name = "MIPS"; - cd->features = CLOCK_EVT_FEAT_ONESHOT; - - /* Calculate the min / max delta */ - cd->mult = div_sc((unsigned long) mips_freq, NSEC_PER_SEC, 32); - cd->shift = 32; - cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); - cd->min_delta_ns = clockevent_delta2ns(0x300, cd); - - cd->rating = 300; - cd->irq = irq; -#ifdef CONFIG_MIPS_MT_SMTC - cd->cpumask = CPU_MASK_ALL; -#else - cd->cpumask = cpumask_of_cpu(cpu); -#endif - cd->set_next_event = mips_next_event; - cd->set_mode = mips_set_mode; - cd->event_handler = mips_event_handler; - - clockevents_register_device(cd); - - if (!cp0_timer_irq_installed) { -#ifdef CONFIG_MIPS_MT_SMTC -#define CPUCTR_IMASKBIT (0x100 << cp0_compare_irq) - setup_irq_smtc(irq, &c0_compare_irqaction, CPUCTR_IMASKBIT); -#else - setup_irq(irq, &c0_compare_irqaction); -#endif /* CONFIG_MIPS_MT_SMTC */ - cp0_timer_irq_installed = 1; - } -} diff --git a/trunk/arch/mips/kernel/head.S b/trunk/arch/mips/kernel/head.S index 236768731063..bf164a562acb 100644 --- a/trunk/arch/mips/kernel/head.S +++ b/trunk/arch/mips/kernel/head.S @@ -27,6 +27,16 @@ #include + .macro ARC64_TWIDDLE_PC +#if defined(CONFIG_ARC64) || defined(CONFIG_MAPPED_KERNEL) + /* We get launched at a XKPHYS address but the kernel is linked to + run at a KSEG0 address, so jump there. */ + PTR_LA t0, \@f + jr t0 +\@: +#endif + .endm + /* * inputs are the text nasid in t1, data nasid in t2. */ @@ -147,11 +157,7 @@ NESTED(kernel_entry, 16, sp) # kernel entry point setup_c0_status_pri - /* We might not get launched at the address the kernel is linked to, - so we jump there. */ - PTR_LA t0, 0f - jr t0 -0: + ARC64_TWIDDLE_PC #ifdef CONFIG_MIPS_MT_SMTC /* diff --git a/trunk/arch/mips/kernel/irixelf.c b/trunk/arch/mips/kernel/irixelf.c index 7852c7cdf29e..b997af713eb3 100644 --- a/trunk/arch/mips/kernel/irixelf.c +++ b/trunk/arch/mips/kernel/irixelf.c @@ -1172,8 +1172,8 @@ static int irix_core_dump(long signr, struct pt_regs *regs, struct file *file, u prstatus.pr_sighold = current->blocked.sig[0]; psinfo.pr_pid = prstatus.pr_pid = current->pid; psinfo.pr_ppid = prstatus.pr_ppid = current->parent->pid; - psinfo.pr_pgrp = prstatus.pr_pgrp = task_pgrp_nr(current); - psinfo.pr_sid = prstatus.pr_sid = task_session_nr(current); + psinfo.pr_pgrp = prstatus.pr_pgrp = process_group(current); + psinfo.pr_sid = prstatus.pr_sid = process_session(current); if (current->pid == current->tgid) { /* * This is the record for the group leader. Add in the diff --git a/trunk/arch/mips/kernel/irixsig.c b/trunk/arch/mips/kernel/irixsig.c index a0a91056fda7..85c2e389edd6 100644 --- a/trunk/arch/mips/kernel/irixsig.c +++ b/trunk/arch/mips/kernel/irixsig.c @@ -609,7 +609,7 @@ asmlinkage int irix_waitsys(int type, int pid, p = list_entry(_p, struct task_struct, sibling); if ((type == IRIX_P_PID) && p->pid != pid) continue; - if ((type == IRIX_P_PGID) && task_pgrp_nr(p) != pid) + if ((type == IRIX_P_PGID) && process_group(p) != pid) continue; if ((p->exit_signal != SIGCHLD)) continue; diff --git a/trunk/arch/mips/kernel/sysirix.c b/trunk/arch/mips/kernel/sysirix.c index 4c477c7ff74a..ee7790d9debe 100644 --- a/trunk/arch/mips/kernel/sysirix.c +++ b/trunk/arch/mips/kernel/sysirix.c @@ -763,11 +763,11 @@ asmlinkage int irix_setpgrp(int flags) printk("[%s:%d] setpgrp(%d) ", current->comm, current->pid, flags); #endif if(!flags) - error = task_pgrp_nr(current); + error = process_group(current); else error = sys_setsid(); #ifdef DEBUG_PROCGRPS - printk("returning %d\n", task_pgrp_nr(current)); + printk("returning %d\n", process_group(current)); #endif return error; diff --git a/trunk/arch/mips/kernel/time.c b/trunk/arch/mips/kernel/time.c index c4e6866d5cbc..e4b5e647b142 100644 --- a/trunk/arch/mips/kernel/time.c +++ b/trunk/arch/mips/kernel/time.c @@ -39,6 +39,17 @@ #include +/* + * The integer part of the number of usecs per jiffy is taken from tick, + * but the fractional part is not recorded, so we calculate it using the + * initial value of HZ. This aids systems where tick isn't really an + * integer (e.g. for HZ = 128). + */ +#define USECS_PER_JIFFY TICK_SIZE +#define USECS_PER_JIFFY_FRAC ((unsigned long)(u32)((1000000ULL << 32) / HZ)) + +#define TICK_SIZE (tick_nsec / 1000) + /* * forward reference */ @@ -61,6 +72,14 @@ int update_persistent_clock(struct timespec now) return rtc_mips_set_mmss(now.tv_sec); } +/* how many counter cycles in a jiffy */ +static unsigned long cycles_per_jiffy __read_mostly; + +/* + * Null timer ack for systems not needing one (e.g. i8254). + */ +static void null_timer_ack(void) { /* nothing */ } + /* * Null high precision timer functions for systems lacking one. */ @@ -69,6 +88,14 @@ static cycle_t null_hpt_read(void) return 0; } +/* + * Timer ack for an R4k-compatible timer of a known frequency. + */ +static void c0_timer_ack(void) +{ + write_c0_compare(read_c0_compare()); +} + /* * High precision timer functions for a R4k-compatible timer. */ @@ -78,6 +105,7 @@ static cycle_t c0_hpt_read(void) } int (*mips_timer_state)(void); +void (*mips_timer_ack)(void); /* * local_timer_interrupt() does profiling and process accounting @@ -106,6 +134,35 @@ int (*perf_irq)(void) = null_perf_irq; EXPORT_SYMBOL(perf_irq); +/* + * Timer interrupt + */ +int cp0_compare_irq; + +/* + * Performance counter IRQ or -1 if shared with timer + */ +int cp0_perfcount_irq; +EXPORT_SYMBOL_GPL(cp0_perfcount_irq); + +/* + * Possibly handle a performance counter interrupt. + * Return true if the timer interrupt should not be checked + */ +static inline int handle_perf_irq(int r2) +{ + /* + * The performance counter overflow interrupt may be shared with the + * timer interrupt (cp0_perfcount_irq < 0). If it is and a + * performance counter has overflowed (perf_irq() == IRQ_HANDLED) + * and we can't reliably determine if a counter interrupt has also + * happened (!r2) then don't check for a timer interrupt. + */ + return (cp0_perfcount_irq < 0) && + perf_irq() == IRQ_HANDLED && + !r2; +} + /* * time_init() - it does the following things. * @@ -171,60 +228,272 @@ struct clocksource clocksource_mips = { .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; -void __init clocksource_set_clock(struct clocksource *cs, unsigned int clock) +static int mips_next_event(unsigned long delta, + struct clock_event_device *evt) { - u64 temp; - u32 shift; + unsigned int cnt; + int res; + +#ifdef CONFIG_MIPS_MT_SMTC + { + unsigned long flags, vpflags; + local_irq_save(flags); + vpflags = dvpe(); +#endif + cnt = read_c0_count(); + cnt += delta; + write_c0_compare(cnt); + res = ((long)(read_c0_count() - cnt ) > 0) ? -ETIME : 0; +#ifdef CONFIG_MIPS_MT_SMTC + evpe(vpflags); + local_irq_restore(flags); + } +#endif + return res; +} - /* Find a shift value */ - for (shift = 32; shift > 0; shift--) { - temp = (u64) NSEC_PER_SEC << shift; - do_div(temp, clock); - if ((temp >> 32) == 0) - break; +static void mips_set_mode(enum clock_event_mode mode, + struct clock_event_device *evt) +{ + /* Nothing to do ... */ +} + +static DEFINE_PER_CPU(struct clock_event_device, mips_clockevent_device); +static int cp0_timer_irq_installed; + +static irqreturn_t timer_interrupt(int irq, void *dev_id) +{ + const int r2 = cpu_has_mips_r2; + struct clock_event_device *cd; + int cpu = smp_processor_id(); + + /* + * Suckage alert: + * Before R2 of the architecture there was no way to see if a + * performance counter interrupt was pending, so we have to run + * the performance counter interrupt handler anyway. + */ + if (handle_perf_irq(r2)) + goto out; + + /* + * The same applies to performance counter interrupts. But with the + * above we now know that the reason we got here must be a timer + * interrupt. Being the paranoiacs we are we check anyway. + */ + if (!r2 || (read_c0_cause() & (1 << 30))) { + c0_timer_ack(); +#ifdef CONFIG_MIPS_MT_SMTC + if (cpu_data[cpu].vpe_id) + goto out; + cpu = 0; +#endif + cd = &per_cpu(mips_clockevent_device, cpu); + cd->event_handler(cd); } - cs->shift = shift; - cs->mult = (u32) temp; + +out: + return IRQ_HANDLED; } -void __cpuinit clockevent_set_clock(struct clock_event_device *cd, - unsigned int clock) +static struct irqaction timer_irqaction = { + .handler = timer_interrupt, +#ifdef CONFIG_MIPS_MT_SMTC + .flags = IRQF_DISABLED, +#else + .flags = IRQF_DISABLED | IRQF_PERCPU, +#endif + .name = "timer", +}; + +static void __init init_mips_clocksource(void) { u64 temp; u32 shift; + if (!mips_hpt_frequency || clocksource_mips.read == null_hpt_read) + return; + + /* Calclate a somewhat reasonable rating value */ + clocksource_mips.rating = 200 + mips_hpt_frequency / 10000000; /* Find a shift value */ for (shift = 32; shift > 0; shift--) { temp = (u64) NSEC_PER_SEC << shift; - do_div(temp, clock); + do_div(temp, mips_hpt_frequency); if ((temp >> 32) == 0) break; } - cd->shift = shift; - cd->mult = (u32) temp; + clocksource_mips.shift = shift; + clocksource_mips.mult = (u32)temp; + + clocksource_register(&clocksource_mips); } -static void __init init_mips_clocksource(void) +void __init __weak plat_time_init(void) { - if (!mips_hpt_frequency || clocksource_mips.read == null_hpt_read) - return; +} - /* Calclate a somewhat reasonable rating value */ - clocksource_mips.rating = 200 + mips_hpt_frequency / 10000000; +void __init __weak plat_timer_setup(struct irqaction *irq) +{ +} - clocksource_set_clock(&clocksource_mips, mips_hpt_frequency); +#ifdef CONFIG_MIPS_MT_SMTC +DEFINE_PER_CPU(struct clock_event_device, smtc_dummy_clockevent_device); - clocksource_register(&clocksource_mips); +static void smtc_set_mode(enum clock_event_mode mode, + struct clock_event_device *evt) +{ } -void __init __weak plat_time_init(void) +int dummycnt[NR_CPUS]; + +static void mips_broadcast(cpumask_t mask) { + unsigned int cpu; + + for_each_cpu_mask(cpu, mask) + smtc_send_ipi(cpu, SMTC_CLOCK_TICK, 0); } -void __init __weak plat_timer_setup(struct irqaction *irq) +static void setup_smtc_dummy_clockevent_device(void) +{ + //uint64_t mips_freq = mips_hpt_^frequency; + unsigned int cpu = smp_processor_id(); + struct clock_event_device *cd; + + cd = &per_cpu(smtc_dummy_clockevent_device, cpu); + + cd->name = "SMTC"; + cd->features = CLOCK_EVT_FEAT_DUMMY; + + /* Calculate the min / max delta */ + cd->mult = 0; //div_sc((unsigned long) mips_freq, NSEC_PER_SEC, 32); + cd->shift = 0; //32; + cd->max_delta_ns = 0; //clockevent_delta2ns(0x7fffffff, cd); + cd->min_delta_ns = 0; //clockevent_delta2ns(0x30, cd); + + cd->rating = 200; + cd->irq = 17; //-1; +// if (cpu) +// cd->cpumask = CPU_MASK_ALL; // cpumask_of_cpu(cpu); +// else + cd->cpumask = cpumask_of_cpu(cpu); + + cd->set_mode = smtc_set_mode; + + cd->broadcast = mips_broadcast; + + clockevents_register_device(cd); +} +#endif + +static void mips_event_handler(struct clock_event_device *dev) { } +/* + * FIXME: This doesn't hold for the relocated E9000 compare interrupt. + */ +static int c0_compare_int_pending(void) +{ + return (read_c0_cause() >> cp0_compare_irq) & 0x100; +} + +static int c0_compare_int_usable(void) +{ + const unsigned int delta = 0x300000; + unsigned int cnt; + + /* + * IP7 already pending? Try to clear it by acking the timer. + */ + if (c0_compare_int_pending()) { + write_c0_compare(read_c0_compare()); + irq_disable_hazard(); + if (c0_compare_int_pending()) + return 0; + } + + cnt = read_c0_count(); + cnt += delta; + write_c0_compare(cnt); + + while ((long)(read_c0_count() - cnt) <= 0) + ; /* Wait for expiry */ + + if (!c0_compare_int_pending()) + return 0; + + write_c0_compare(read_c0_compare()); + irq_disable_hazard(); + if (c0_compare_int_pending()) + return 0; + + /* + * Feels like a real count / compare timer. + */ + return 1; +} + +void __cpuinit mips_clockevent_init(void) +{ + uint64_t mips_freq = mips_hpt_frequency; + unsigned int cpu = smp_processor_id(); + struct clock_event_device *cd; + unsigned int irq = MIPS_CPU_IRQ_BASE + 7; + + if (!cpu_has_counter) + return; + +#ifdef CONFIG_MIPS_MT_SMTC + setup_smtc_dummy_clockevent_device(); + + /* + * On SMTC we only register VPE0's compare interrupt as clockevent + * device. + */ + if (cpu) + return; +#endif + + if (!c0_compare_int_usable()) + return; + + cd = &per_cpu(mips_clockevent_device, cpu); + + cd->name = "MIPS"; + cd->features = CLOCK_EVT_FEAT_ONESHOT; + + /* Calculate the min / max delta */ + cd->mult = div_sc((unsigned long) mips_freq, NSEC_PER_SEC, 32); + cd->shift = 32; + cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); + cd->min_delta_ns = clockevent_delta2ns(0x300, cd); + + cd->rating = 300; + cd->irq = irq; +#ifdef CONFIG_MIPS_MT_SMTC + cd->cpumask = CPU_MASK_ALL; +#else + cd->cpumask = cpumask_of_cpu(cpu); +#endif + cd->set_next_event = mips_next_event; + cd->set_mode = mips_set_mode; + cd->event_handler = mips_event_handler; + + clockevents_register_device(cd); + + if (!cp0_timer_irq_installed) { +#ifdef CONFIG_MIPS_MT_SMTC +#define CPUCTR_IMASKBIT (0x100 << cp0_compare_irq) + setup_irq_smtc(irq, &timer_irqaction, CPUCTR_IMASKBIT); +#else + setup_irq(irq, &timer_irqaction); +#endif /* CONFIG_MIPS_MT_SMTC */ + cp0_timer_irq_installed = 1; + } +} + void __init time_init(void) { plat_time_init(); @@ -243,6 +512,14 @@ void __init time_init(void) if (!clocksource_mips.read) { /* No external high precision timer -- use R4k. */ clocksource_mips.read = c0_hpt_read; + + if (!mips_timer_state) { + /* No external timer interrupt -- use R4k. */ + mips_timer_ack = c0_timer_ack; + /* Calculate cache parameters. */ + cycles_per_jiffy = + (mips_hpt_frequency + HZ / 2) / HZ; + } } if (!mips_hpt_frequency) mips_hpt_frequency = calibrate_hpt(); @@ -251,8 +528,29 @@ void __init time_init(void) printk("Using %u.%03u MHz high precision timer.\n", ((mips_hpt_frequency + 500) / 1000) / 1000, ((mips_hpt_frequency + 500) / 1000) % 1000); + +#ifdef CONFIG_IRQ_CPU + setup_irq(MIPS_CPU_IRQ_BASE + 7, &timer_irqaction); +#endif } + if (!mips_timer_ack) + /* No timer interrupt ack (e.g. i8254). */ + mips_timer_ack = null_timer_ack; + + /* + * Call board specific timer interrupt setup. + * + * this pointer must be setup in machine setup routine. + * + * Even if a machine chooses to use a low-level timer interrupt, + * it still needs to setup the timer_irqaction. + * In that case, it might be better to set timer_irqaction.handler + * to be NULL function so that we are sure the high-level code + * is not invoked accidentally. + */ + plat_timer_setup(&timer_irqaction); + init_mips_clocksource(); mips_clockevent_init(); } diff --git a/trunk/arch/mips/kernel/traps.c b/trunk/arch/mips/kernel/traps.c index fa500787152d..bbf01b81a4ff 100644 --- a/trunk/arch/mips/kernel/traps.c +++ b/trunk/arch/mips/kernel/traps.c @@ -314,7 +314,7 @@ void show_registers(const struct pt_regs *regs) __show_regs(regs); print_modules(); printk("Process %s (pid: %d, threadinfo=%p, task=%p)\n", - current->comm, task_pid_nr(current), current_thread_info(), current); + current->comm, current->pid, current_thread_info(), current); show_stacktrace(current, regs); show_code((unsigned int __user *) regs->cp0_epc); printk("\n"); @@ -1336,17 +1336,6 @@ extern void cpu_cache_init(void); extern void tlb_init(void); extern void flush_tlb_handlers(void); -/* - * Timer interrupt - */ -int cp0_compare_irq; - -/* - * Performance counter IRQ or -1 if shared with timer - */ -int cp0_perfcount_irq; -EXPORT_SYMBOL_GPL(cp0_perfcount_irq); - void __init per_cpu_trap_init(void) { unsigned int cpu = smp_processor_id(); diff --git a/trunk/arch/mips/lemote/lm2e/setup.c b/trunk/arch/mips/lemote/lm2e/setup.c index 2cc6745991ab..09314a20f9fb 100644 --- a/trunk/arch/mips/lemote/lm2e/setup.c +++ b/trunk/arch/mips/lemote/lm2e/setup.c @@ -53,6 +53,11 @@ unsigned long bus_clock; unsigned int memsize; unsigned int highmemsize = 0; +void __init plat_timer_setup(struct irqaction *irq) +{ + setup_irq(MIPS_CPU_IRQ_BASE + 7, irq); +} + void __init plat_time_init(void) { /* setup mips r4k timer */ diff --git a/trunk/arch/mips/mm/fault.c b/trunk/arch/mips/mm/fault.c index fa636fc6b7b9..5699c7713e2f 100644 --- a/trunk/arch/mips/mm/fault.c +++ b/trunk/arch/mips/mm/fault.c @@ -173,7 +173,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write, */ out_of_memory: up_read(&mm->mmap_sem); - if (is_global_init(tsk)) { + if (is_init(tsk)) { yield(); down_read(&mm->mmap_sem); goto survive; diff --git a/trunk/arch/mips/oprofile/Kconfig b/trunk/arch/mips/oprofile/Kconfig new file mode 100644 index 000000000000..fb6f235348b0 --- /dev/null +++ b/trunk/arch/mips/oprofile/Kconfig @@ -0,0 +1,23 @@ + +menu "Profiling support" + depends on EXPERIMENTAL + +config PROFILING + bool "Profiling support (EXPERIMENTAL)" + help + Say Y here to enable the extended profiling support mechanisms used + by profilers such as OProfile. + + +config OPROFILE + tristate "OProfile system profiling (EXPERIMENTAL)" + depends on PROFILING && !MIPS_MT_SMTC && EXPERIMENTAL + help + OProfile is a profiling system capable of profiling the + whole system, include the kernel, kernel modules, libraries, + and applications. + + If unsure, say N. + +endmenu + diff --git a/trunk/arch/mips/pmc-sierra/Kconfig b/trunk/arch/mips/pmc-sierra/Kconfig index 6b293ce0935f..abbd0bbfabd7 100644 --- a/trunk/arch/mips/pmc-sierra/Kconfig +++ b/trunk/arch/mips/pmc-sierra/Kconfig @@ -4,13 +4,11 @@ choice config PMC_MSP4200_EVAL bool "PMC-Sierra MSP4200 Eval Board" - select CEVT_R4K select IRQ_MSP_SLP select HW_HAS_PCI config PMC_MSP4200_GW bool "PMC-Sierra MSP4200 VoIP Gateway" - select CEVT_R4K select IRQ_MSP_SLP select HW_HAS_PCI diff --git a/trunk/arch/mips/pmc-sierra/msp71xx/msp_time.c b/trunk/arch/mips/pmc-sierra/msp71xx/msp_time.c index 7cfeda5a651b..f221d4763625 100644 --- a/trunk/arch/mips/pmc-sierra/msp71xx/msp_time.c +++ b/trunk/arch/mips/pmc-sierra/msp71xx/msp_time.c @@ -86,5 +86,8 @@ void __init plat_timer_setup(struct irqaction *irq) #ifdef CONFIG_IRQ_MSP_CIC /* we are using the vpe0 counter for timer interrupts */ setup_irq(MSP_INT_VPE0_TIMER, irq); +#else + /* we are using the mips counter for timer interrupts */ + setup_irq(MSP_INT_TIMER, irq); #endif } diff --git a/trunk/arch/mips/pmc-sierra/yosemite/setup.c b/trunk/arch/mips/pmc-sierra/yosemite/setup.c index 855977ca51cd..015fcc363dc0 100644 --- a/trunk/arch/mips/pmc-sierra/yosemite/setup.c +++ b/trunk/arch/mips/pmc-sierra/yosemite/setup.c @@ -137,6 +137,11 @@ int rtc_mips_set_time(unsigned long tim) return 0; } +void __init plat_timer_setup(struct irqaction *irq) +{ + setup_irq(7, irq); +} + void __init plat_time_init(void) { mips_hpt_frequency = cpu_clock_freq / 2; diff --git a/trunk/arch/mips/sgi-ip27/ip27-irq.c b/trunk/arch/mips/sgi-ip27/ip27-irq.c index 1bb692a3b319..856649cf9f1e 100644 --- a/trunk/arch/mips/sgi-ip27/ip27-irq.c +++ b/trunk/arch/mips/sgi-ip27/ip27-irq.c @@ -374,13 +374,14 @@ int __devinit request_bridge_irq(struct bridge_controller *bc) return irq; } +extern void ip27_rt_timer_interrupt(void); + asmlinkage void plat_irq_dispatch(void) { unsigned long pending = read_c0_cause() & read_c0_status(); - extern unsigned int rt_timer_irq; if (pending & CAUSEF_IP4) - do_IRQ(rt_timer_irq); + ip27_rt_timer_interrupt(); else if (pending & CAUSEF_IP2) /* PI_INT_PEND_0 or CC_PEND_{A|B} */ ip27_do_irq_mask0(); else if (pending & CAUSEF_IP3) /* PI_INT_PEND_1 */ diff --git a/trunk/arch/mips/sgi-ip27/ip27-timer.c b/trunk/arch/mips/sgi-ip27/ip27-timer.c index d467bf4f6c3f..b7b3479b6bce 100644 --- a/trunk/arch/mips/sgi-ip27/ip27-timer.c +++ b/trunk/arch/mips/sgi-ip27/ip27-timer.c @@ -3,7 +3,6 @@ * Copytight (C) 1999, 2000 Silicon Graphics, Inc. */ #include -#include #include #include #include @@ -26,8 +25,22 @@ #include #include +/* + * This is a hack; we really need to figure these values out dynamically + * + * Since 800 ns works very well with various HUB frequencies, such as + * 360, 380, 390 and 400 MHZ, we use 800 ns rtc cycle time. + * + * Ralf: which clock rate is used to feed the counter? + */ +#define NSEC_PER_CYCLE 800 +#define CYCLES_PER_SEC (NSEC_PER_SEC/NSEC_PER_CYCLE) +#define CYCLES_PER_JIFFY (CYCLES_PER_SEC/HZ) + #define TICK_SIZE (tick_nsec / 1000) +static unsigned long ct_cur[NR_CPUS]; /* What counter should be at next timer irq */ + #if 0 static int set_rtc_mmss(unsigned long nowtime) { @@ -73,6 +86,36 @@ static int set_rtc_mmss(unsigned long nowtime) } #endif +static unsigned int rt_timer_irq; + +void ip27_rt_timer_interrupt(void) +{ + int cpu = smp_processor_id(); + int cpuA = cputoslice(cpu) == 0; + unsigned int irq = rt_timer_irq; + + irq_enter(); + write_seqlock(&xtime_lock); + +again: + LOCAL_HUB_S(cpuA ? PI_RT_PEND_A : PI_RT_PEND_B, 0); /* Ack */ + ct_cur[cpu] += CYCLES_PER_JIFFY; + LOCAL_HUB_S(cpuA ? PI_RT_COMPARE_A : PI_RT_COMPARE_B, ct_cur[cpu]); + + if (LOCAL_HUB_L(PI_RT_COUNT) >= ct_cur[cpu]) + goto again; + + kstat_this_cpu.irqs[irq]++; /* kstat only for bootcpu? */ + + if (cpu == 0) + do_timer(1); + + update_process_times(user_mode(get_irq_regs())); + + write_sequnlock(&xtime_lock); + irq_exit(); +} + /* Includes for ioc3_init(). */ #include #include @@ -111,46 +154,6 @@ unsigned long read_persistent_clock(void) return mktime(year, month, date, hour, min, sec); } -static int rt_set_next_event(unsigned long delta, - struct clock_event_device *evt) -{ - unsigned int cpu = smp_processor_id(); - int slice = cputoslice(cpu) == 0; - unsigned long cnt; - - cnt = LOCAL_HUB_L(PI_RT_COUNT); - cnt += delta; - LOCAL_HUB_S(slice ? PI_RT_COMPARE_A : PI_RT_COMPARE_B, cnt); - - return LOCAL_HUB_L(PI_RT_COUNT) >= cnt ? -ETIME : 0; -} - -static void rt_set_mode(enum clock_event_mode mode, - struct clock_event_device *evt) -{ - switch (mode) { - case CLOCK_EVT_MODE_PERIODIC: - /* The only mode supported */ - break; - - case CLOCK_EVT_MODE_UNUSED: - case CLOCK_EVT_MODE_SHUTDOWN: - case CLOCK_EVT_MODE_ONESHOT: - case CLOCK_EVT_MODE_RESUME: - /* Nothing to do */ - break; - } -} - -struct clock_event_device rt_clock_event_device = { - .name = "HUB-RT", - .features = CLOCK_EVT_FEAT_ONESHOT, - - .rating = 300, - .set_next_event = rt_set_next_event, - .set_mode = rt_set_mode, -}; - static void enable_rt_irq(unsigned int irq) { } @@ -168,20 +171,6 @@ static struct irq_chip rt_irq_type = { .eoi = enable_rt_irq, }; -unsigned int rt_timer_irq; - -static irqreturn_t ip27_rt_timer_interrupt(int irq, void *dev_id) -{ - struct clock_event_device *cd = &rt_clock_event_device; - unsigned int cpu = smp_processor_id(); - int slice = cputoslice(cpu) == 0; - - LOCAL_HUB_S(slice ? PI_RT_PEND_A : PI_RT_PEND_B, 0); /* Ack */ - cd->event_handler(cd); - - return IRQ_HANDLED; -} - static struct irqaction rt_irqaction = { .handler = (irq_handler_t) ip27_rt_timer_interrupt, .flags = IRQF_DISABLED, @@ -189,43 +178,26 @@ static struct irqaction rt_irqaction = { .name = "timer" }; -/* - * This is a hack; we really need to figure these values out dynamically - * - * Since 800 ns works very well with various HUB frequencies, such as - * 360, 380, 390 and 400 MHZ, we use 800 ns rtc cycle time. - * - * Ralf: which clock rate is used to feed the counter? - */ -#define NSEC_PER_CYCLE 800 -#define CYCLES_PER_SEC (NSEC_PER_SEC / NSEC_PER_CYCLE) - -static void __init ip27_rt_clock_event_init(void) +void __init plat_timer_setup(struct irqaction *irq) { - struct clock_event_device *cd = &rt_clock_event_device; - unsigned int cpu = smp_processor_id(); - int irq = allocate_irqno(); + int irqno = allocate_irqno(); - if (irq < 0) + if (irqno < 0) panic("Can't allocate interrupt number for timer interrupt"); - rt_timer_irq = irq; + set_irq_chip_and_handler(irqno, &rt_irq_type, handle_percpu_irq); - cd->irq = irq, - cd->cpumask = cpumask_of_cpu(cpu), + /* over-write the handler, we use our own way */ + irq->handler = no_action; + /* setup irqaction */ + irq_desc[irqno].status |= IRQ_PER_CPU; + + rt_timer_irq = irqno; /* - * Calculate the min / max delta + * Only needed to get /proc/interrupt to display timer irq stats */ - cd->mult = - div_sc((unsigned long) CYCLES_PER_SEC, NSEC_PER_SEC, 32); - cd->shift = 32; - cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); - cd->min_delta_ns = clockevent_delta2ns(0x300, cd); - clockevents_register_device(cd); - - set_irq_chip_and_handler(irq, &rt_irq_type, handle_percpu_irq); - setup_irq(irq, &rt_irqaction); + setup_irq(irqno, &rt_irqaction); } static cycle_t hub_rt_read(void) @@ -234,7 +206,7 @@ static cycle_t hub_rt_read(void) } struct clocksource ht_rt_clocksource = { - .name = "HUB-RT", + .name = "HUB", .rating = 200, .read = hub_rt_read, .mask = CLOCKSOURCE_MASK(52), @@ -242,15 +214,9 @@ struct clocksource ht_rt_clocksource = { .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; -static void __init ip27_rt_clocksource_init(void) -{ - clocksource_register(&ht_rt_clocksource); -} - void __init plat_time_init(void) { - ip27_rt_clock_event_init(); - ip27_rt_clocksource_init(); + clocksource_register(&ht_rt_clocksource); } void __init cpu_time_init(void) @@ -282,12 +248,17 @@ void __init hub_rtc_init(cnodeid_t cnode) * node and timeouts will not happen there. */ if (get_compact_nodeid() == cnode) { + int cpu = smp_processor_id(); LOCAL_HUB_S(PI_RT_EN_A, 1); LOCAL_HUB_S(PI_RT_EN_B, 1); LOCAL_HUB_S(PI_PROF_EN_A, 0); LOCAL_HUB_S(PI_PROF_EN_B, 0); + ct_cur[cpu] = CYCLES_PER_JIFFY; + LOCAL_HUB_S(PI_RT_COMPARE_A, ct_cur[cpu]); LOCAL_HUB_S(PI_RT_COUNT, 0); LOCAL_HUB_S(PI_RT_PEND_A, 0); + LOCAL_HUB_S(PI_RT_COMPARE_B, ct_cur[cpu]); + LOCAL_HUB_S(PI_RT_COUNT, 0); LOCAL_HUB_S(PI_RT_PEND_B, 0); } } diff --git a/trunk/arch/mips/sgi-ip32/ip32-setup.c b/trunk/arch/mips/sgi-ip32/ip32-setup.c index 1024bf40bd9e..fc75bfcb0c0e 100644 --- a/trunk/arch/mips/sgi-ip32/ip32-setup.c +++ b/trunk/arch/mips/sgi-ip32/ip32-setup.c @@ -80,6 +80,12 @@ void __init plat_time_init(void) printk("%d MHz CPU detected\n", mips_hpt_frequency * 2 / 1000000); } +void __init plat_timer_setup(struct irqaction *irq) +{ + irq->handler = no_action; + setup_irq(MIPS_CPU_IRQ_BASE + 7, irq); +} + void __init plat_mem_setup(void) { board_be_init = ip32_be_init; diff --git a/trunk/arch/mips/sibyte/bcm1480/smp.c b/trunk/arch/mips/sibyte/bcm1480/smp.c index 02b266a31c46..6eac36d1b8c8 100644 --- a/trunk/arch/mips/sibyte/bcm1480/smp.c +++ b/trunk/arch/mips/sibyte/bcm1480/smp.c @@ -69,9 +69,8 @@ void bcm1480_smp_init(void) void bcm1480_smp_finish(void) { - extern void sb1480_clockevent_init(void); - - sb1480_clockevent_init(); + extern void bcm1480_time_init(void); + bcm1480_time_init(); local_irq_enable(); } diff --git a/trunk/arch/mips/sibyte/bcm1480/time.c b/trunk/arch/mips/sibyte/bcm1480/time.c index c730744aa474..5b4bfbbb5a24 100644 --- a/trunk/arch/mips/sibyte/bcm1480/time.c +++ b/trunk/arch/mips/sibyte/bcm1480/time.c @@ -27,8 +27,9 @@ */ #include #include -#include +#include #include +#include #include #include @@ -100,36 +101,25 @@ static void sibyte_set_mode(enum clock_event_mode mode, break; case CLOCK_EVT_MODE_UNUSED: /* shuddup gcc */ - case CLOCK_EVT_MODE_RESUME: ; } } -static int sibyte_next_event(unsigned long delta, struct clock_event_device *cd) -{ - unsigned int cpu = smp_processor_id(); - void __iomem *timer_init; - unsigned int cnt; - int res; - - timer_init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT)); - cnt = __raw_readq(timer_init); - cnt += delta; - __raw_writeq(cnt, timer_init); - res = ((long)(__raw_readq(timer_init) - cnt ) > 0) ? -ETIME : 0; - - return res; -} - -static DEFINE_PER_CPU(struct clock_event_device, sibyte_hpt_clockevent); +struct clock_event_device sibyte_hpt_clockevent = { + .name = "bcm1480-counter", + .features = CLOCK_EVT_FEAT_PERIODIC, + .set_mode = sibyte_set_mode, + .shift = 32, + .irq = 0, +}; static irqreturn_t sibyte_counter_handler(int irq, void *dev_id) { + struct clock_event_device *cd = &sibyte_hpt_clockevent; unsigned int cpu = smp_processor_id(); - struct clock_event_device *cd = &per_cpu(sibyte_hpt_clockevent, cpu); /* Reset the timer */ - __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS, + __raw_writeq(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS, IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG))); cd->event_handler(cd); @@ -150,23 +140,26 @@ static struct irqaction sibyte_counter_irqaction = { * called directly from irq_handler.S when IP[4] is set during an * interrupt */ -void __cpuinit sb1480_clockevent_init(void) +static void __init sb1480_clockevent_init(void) { unsigned int cpu = smp_processor_id(); unsigned int irq = K_BCM1480_INT_TIMER_0 + cpu; - struct clock_event_device *cd = &per_cpu(sibyte_hpt_clockevent, cpu); - - cd->name = "bcm1480-counter"; - cd->features = CLOCK_EVT_FEAT_PERIODIC | - CLOCK_EVT_MODE_ONESHOT; - cd->set_next_event = sibyte_next_event; - cd->set_mode = sibyte_set_mode; - cd->irq = irq; - clockevent_set_clock(cd, BCM1480_HPT_VALUE); setup_irq(irq, &sibyte_counter_irqaction); } +void bcm1480_timer_interrupt(void) +{ + int cpu = smp_processor_id(); + int irq = K_BCM1480_INT_TIMER_0 + cpu; + + /* Reset the timer */ + __raw_writeq(M_SCD_TIMER_ENABLE|M_SCD_TIMER_MODE_CONTINUOUS, + IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG))); + + ll_timer_interrupt(irq); +} + static cycle_t bcm1480_hpt_read(void) { /* We assume this function is called xtime_lock held. */ @@ -175,26 +168,9 @@ static cycle_t bcm1480_hpt_read(void) return (jiffies + 1) * (BCM1480_HPT_VALUE / HZ) - count; } -struct clocksource bcm1480_clocksource = { - .name = "MIPS", - .rating = 200, - .read = bcm1480_hpt_read, - .mask = CLOCKSOURCE_MASK(32), - .shift = 32, - .flags = CLOCK_SOURCE_IS_CONTINUOUS, -}; - -void __init sb1480_clocksource_init(void) -{ - struct clocksource *cs = &bcm1480_clocksource; - - clocksource_set_clock(cs, BCM1480_HPT_VALUE); - clocksource_register(cs); -} - void __init bcm1480_hpt_setup(void) { + clocksource_mips.read = bcm1480_hpt_read; mips_hpt_frequency = BCM1480_HPT_VALUE; - sb1480_clocksource_init(); sb1480_clockevent_init(); } diff --git a/trunk/arch/mips/sibyte/sb1250/irq.c b/trunk/arch/mips/sibyte/sb1250/irq.c index 500d17e84c09..7659174819c6 100644 --- a/trunk/arch/mips/sibyte/sb1250/irq.c +++ b/trunk/arch/mips/sibyte/sb1250/irq.c @@ -400,11 +400,43 @@ static void sb1250_kgdb_interrupt(void) #endif /* CONFIG_KGDB */ +static inline void sb1250_timer_interrupt(void) +{ + int cpu = smp_processor_id(); + int irq = K_INT_TIMER_0 + cpu; + + irq_enter(); + kstat_this_cpu.irqs[irq]++; + + write_seqlock(&xtime_lock); + + /* ACK interrupt */ + ____raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS, + IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG))); + + /* + * call the generic timer interrupt handling + */ + do_timer(1); + + write_sequnlock(&xtime_lock); + + /* + * In UP mode, we call local_timer_interrupt() to do profiling + * and process accouting. + * + * In SMP mode, local_timer_interrupt() is invoked by appropriate + * low-level local timer interrupt handler. + */ + local_timer_interrupt(irq); + + irq_exit(); +} + extern void sb1250_mailbox_interrupt(void); asmlinkage void plat_irq_dispatch(void) { - unsigned int cpu = smp_processor_id(); unsigned int pending; /* @@ -422,7 +454,7 @@ asmlinkage void plat_irq_dispatch(void) if (pending & CAUSEF_IP7) /* CPU performance counter interrupt */ do_IRQ(MIPS_CPU_IRQ_BASE + 7); else if (pending & CAUSEF_IP4) - do_IRQ(K_INT_TIMER_0 + cpu); /* sb1250_timer_interrupt() */ + sb1250_timer_interrupt(); #ifdef CONFIG_SMP else if (pending & CAUSEF_IP3) diff --git a/trunk/arch/mips/sibyte/sb1250/smp.c b/trunk/arch/mips/sibyte/sb1250/smp.c index aaa4f30dda79..c38e1f34460d 100644 --- a/trunk/arch/mips/sibyte/sb1250/smp.c +++ b/trunk/arch/mips/sibyte/sb1250/smp.c @@ -57,9 +57,8 @@ void sb1250_smp_init(void) void sb1250_smp_finish(void) { - extern void sb1250_clockevent_init(void); - - sb1250_clockevent_init(); + extern void sb1250_time_init(void); + sb1250_time_init(); local_irq_enable(); } diff --git a/trunk/arch/mips/sibyte/sb1250/time.c b/trunk/arch/mips/sibyte/sb1250/time.c index 9ef54628bc9c..fe11fed8e0d7 100644 --- a/trunk/arch/mips/sibyte/sb1250/time.c +++ b/trunk/arch/mips/sibyte/sb1250/time.c @@ -100,7 +100,6 @@ static void sibyte_set_mode(enum clock_event_mode mode, break; case CLOCK_EVT_MODE_UNUSED: /* shuddup gcc */ - case CLOCK_EVT_MODE_RESUME: ; } } @@ -145,7 +144,79 @@ static struct irqaction sibyte_irqaction = { .name = "timer", }; -void __cpuinit sb1250_clockevent_init(void) +/* + * The general purpose timer ticks at 1 Mhz independent if + * the rest of the system + */ +static void sibyte_set_mode(enum clock_event_mode mode, + struct clock_event_device *evt) +{ + unsigned int cpu = smp_processor_id(); + void __iomem *timer_cfg, *timer_init; + + timer_cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)); + timer_init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT)); + + switch (mode) { + case CLOCK_EVT_MODE_PERIODIC: + __raw_writeq(0, timer_cfg); + __raw_writeq((V_SCD_TIMER_FREQ / HZ) - 1, timer_init); + __raw_writeq(M_SCD_TIMER_ENABLE | M_SCD_TIMER_MODE_CONTINUOUS, + timer_cfg); + break; + + case CLOCK_EVT_MODE_ONESHOT: + /* Stop the timer until we actually program a shot */ + case CLOCK_EVT_MODE_SHUTDOWN: + __raw_writeq(0, timer_cfg); + break; + + case CLOCK_EVT_MODE_UNUSED: /* shuddup gcc */ + ; + } +} + +static int +sibyte_next_event(unsigned long delta, struct clock_event_device *evt) +{ + unsigned int cpu = smp_processor_id(); + void __iomem *timer_cfg, *timer_init; + + timer_cfg = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_CFG)); + timer_init = IOADDR(A_SCD_TIMER_REGISTER(cpu, R_SCD_TIMER_INIT)); + + __raw_writeq(0, timer_cfg); + __raw_writeq(delta, timer_init); + __raw_writeq(M_SCD_TIMER_ENABLE, timer_cfg); + + return 0; +} + +struct clock_event_device sibyte_hpt_clockevent = { + .name = "sb1250-counter", + .features = CLOCK_EVT_FEAT_PERIODIC, + .set_mode = sibyte_set_mode, + .set_next_event = sibyte_next_event, + .shift = 32, + .irq = 0, +}; + +static irqreturn_t sibyte_counter_handler(int irq, void *dev_id) +{ + struct clock_event_device *cd = &sibyte_hpt_clockevent; + + cd->event_handler(cd); + + return IRQ_HANDLED; +} + +static struct irqaction sibyte_irqaction = { + .handler = sibyte_counter_handler, + .flags = IRQF_DISABLED | IRQF_PERCPU, + .name = "timer", +}; + +static void __init sb1250_clockevent_init(void) { struct clock_event_device *cd = &sibyte_hpt_clockevent; unsigned int cpu = smp_processor_id(); @@ -178,6 +249,12 @@ void __cpuinit sb1250_clockevent_init(void) clockevents_register_device(cd); } +void __init plat_time_init(void) +{ + sb1250_clocksource_init(); + sb1250_clockevent_init(); +} + /* * The HPT is free running from SB1250_HPT_VALUE down to 0 then starts over * again. @@ -190,26 +267,3 @@ static cycle_t sb1250_hpt_read(void) return SB1250_HPT_VALUE - count; } - -struct clocksource bcm1250_clocksource = { - .name = "MIPS", - .rating = 200, - .read = sb1250_hpt_read, - .mask = CLOCKSOURCE_MASK(32), - .shift = 32, - .flags = CLOCK_SOURCE_IS_CONTINUOUS, -}; - -void __init sb1250_clocksource_init(void) -{ - struct clocksource *cs = &bcm1250_clocksource; - - clocksource_set_clock(cs, V_SCD_TIMER_FREQ); - clocksource_register(cs); -} - -void __init plat_time_init(void) -{ - sb1250_clocksource_init(); - sb1250_clockevent_init(); -} diff --git a/trunk/arch/mips/sibyte/swarm/setup.c b/trunk/arch/mips/sibyte/swarm/setup.c index 080c966263b7..8b3ef0e4cd55 100644 --- a/trunk/arch/mips/sibyte/swarm/setup.c +++ b/trunk/arch/mips/sibyte/swarm/setup.c @@ -69,6 +69,31 @@ const char *get_system_type(void) return "SiByte " SIBYTE_BOARD_NAME; } +void __init plat_time_init(void) +{ +#if defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X) + /* Setup HPT */ + sb1250_hpt_setup(); +#endif +} + +void __init plat_timer_setup(struct irqaction *irq) +{ + /* + * we don't set up irqaction, because we will deliver timer + * interrupts through low-level (direct) meachanism. + */ + + /* We only need to setup the generic timer */ +#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80) + bcm1480_time_init(); +#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X) + sb1250_time_init(); +#else +#error invalid SiByte board configuration +#endif +} + int swarm_be_handler(struct pt_regs *regs, int is_fixup) { if (!is_fixup && (regs->cp0_cause & 4)) { diff --git a/trunk/arch/mips/sni/time.c b/trunk/arch/mips/sni/time.c index 0910b35cb71f..b80877349d38 100644 --- a/trunk/arch/mips/sni/time.c +++ b/trunk/arch/mips/sni/time.c @@ -121,6 +121,15 @@ void __init plat_time_init(void) setup_pit_timer(); } +/* + * R4k counter based timer interrupt. Works on RM200-225 and possibly + * others but not on RM400 + */ +static void __init sni_cpu_timer_setup(struct irqaction *irq) +{ + setup_irq(SNI_MIPS_IRQ_CPU_TIMER, irq); +} + void __init plat_timer_setup(struct irqaction *irq) { switch (sni_brd_type) { @@ -130,6 +139,15 @@ void __init plat_timer_setup(struct irqaction *irq) case SNI_BRD_MINITOWER: sni_a20r_timer_setup(irq); break; + + case SNI_BRD_PCI_TOWER: + case SNI_BRD_RM200: + case SNI_BRD_PCI_MTOWER: + case SNI_BRD_PCI_DESKTOP: + case SNI_BRD_PCI_TOWER_CPLUS: + case SNI_BRD_PCI_MTOWER_CPLUS: + sni_cpu_timer_setup(irq); + break; } } diff --git a/trunk/arch/mips/tx4927/common/tx4927_setup.c b/trunk/arch/mips/tx4927/common/tx4927_setup.c index 36c5f200eb3d..8ce0989671d8 100644 --- a/trunk/arch/mips/tx4927/common/tx4927_setup.c +++ b/trunk/arch/mips/tx4927/common/tx4927_setup.c @@ -72,6 +72,22 @@ void __init plat_time_init(void) #endif } +void __init plat_timer_setup(struct irqaction *irq) +{ + setup_irq(TX4927_IRQ_CPU_TIMER, irq); + +#ifdef CONFIG_TOSHIBA_RBTX4927 + { + extern void toshiba_rbtx4927_timer_setup(struct irqaction + *irq); + toshiba_rbtx4927_timer_setup(irq); + } +#endif + + return; +} + + #ifdef DEBUG void print_cp0(char *key, int num, char *name, u32 val) { diff --git a/trunk/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c b/trunk/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c index c7470fba6180..b97102a1c635 100644 --- a/trunk/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c +++ b/trunk/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c @@ -94,6 +94,7 @@ #define TOSHIBA_RBTX4927_SETUP_EFWFU ( 1 << 3 ) #define TOSHIBA_RBTX4927_SETUP_SETUP ( 1 << 4 ) #define TOSHIBA_RBTX4927_SETUP_TIME_INIT ( 1 << 5 ) +#define TOSHIBA_RBTX4927_SETUP_TIMER_SETUP ( 1 << 6 ) #define TOSHIBA_RBTX4927_SETUP_PCIBIOS ( 1 << 7 ) #define TOSHIBA_RBTX4927_SETUP_PCI1 ( 1 << 8 ) #define TOSHIBA_RBTX4927_SETUP_PCI2 ( 1 << 9 ) @@ -107,6 +108,7 @@ static const u32 toshiba_rbtx4927_setup_debug_flag = (TOSHIBA_RBTX4927_SETUP_NONE | TOSHIBA_RBTX4927_SETUP_INFO | TOSHIBA_RBTX4927_SETUP_WARN | TOSHIBA_RBTX4927_SETUP_EROR | TOSHIBA_RBTX4927_SETUP_EFWFU | TOSHIBA_RBTX4927_SETUP_SETUP | + TOSHIBA_RBTX4927_SETUP_TIME_INIT | TOSHIBA_RBTX4927_SETUP_TIMER_SETUP | TOSHIBA_RBTX4927_SETUP_PCIBIOS | TOSHIBA_RBTX4927_SETUP_PCI1 | TOSHIBA_RBTX4927_SETUP_PCI2 | TOSHIBA_RBTX4927_SETUP_PCI66); #endif @@ -945,6 +947,14 @@ toshiba_rbtx4927_time_init(void) } +void __init toshiba_rbtx4927_timer_setup(struct irqaction *irq) +{ + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIMER_SETUP, + "-\n"); + TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_TIMER_SETUP, + "+\n"); +} + static int __init toshiba_rbtx4927_rtc_init(void) { static struct resource __initdata res = { diff --git a/trunk/arch/mips/tx4938/common/setup.c b/trunk/arch/mips/tx4938/common/setup.c index 3ba4101d141e..ab4082267553 100644 --- a/trunk/arch/mips/tx4938/common/setup.c +++ b/trunk/arch/mips/tx4938/common/setup.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include #include @@ -43,3 +43,8 @@ plat_mem_setup(void) { toshiba_rbtx4938_setup(); } + +void __init plat_timer_setup(struct irqaction *irq) +{ + setup_irq(TX4938_IRQ_CPU_TIMER, irq); +} diff --git a/trunk/arch/mips/vr41xx/Kconfig b/trunk/arch/mips/vr41xx/Kconfig index eeb089f20c0d..8f4d3e74c230 100644 --- a/trunk/arch/mips/vr41xx/Kconfig +++ b/trunk/arch/mips/vr41xx/Kconfig @@ -5,7 +5,6 @@ choice config CASIO_E55 bool "CASIO CASSIOPEIA E-10/15/55/65" - select CEVT_R4K select DMA_NONCOHERENT select IRQ_CPU select ISA @@ -14,7 +13,6 @@ config CASIO_E55 config IBM_WORKPAD bool "IBM WorkPad z50" - select CEVT_R4K select DMA_NONCOHERENT select IRQ_CPU select ISA @@ -23,7 +21,6 @@ config IBM_WORKPAD config NEC_CMBVR4133 bool "NEC CMB-VR4133" - select CEVT_R4K select DMA_NONCOHERENT select IRQ_CPU select HW_HAS_PCI @@ -32,7 +29,6 @@ config NEC_CMBVR4133 config TANBAC_TB022X bool "TANBAC VR4131 multichip module and TANBAC VR4131DIMM" - select CEVT_R4K select DMA_NONCOHERENT select IRQ_CPU select HW_HAS_PCI @@ -47,7 +43,6 @@ config TANBAC_TB022X config VICTOR_MPC30X bool "Victor MP-C303/304" - select CEVT_R4K select DMA_NONCOHERENT select IRQ_CPU select HW_HAS_PCI @@ -57,7 +52,6 @@ config VICTOR_MPC30X config ZAO_CAPCELLA bool "ZAO Networks Capcella" - select CEVT_R4K select DMA_NONCOHERENT select IRQ_CPU select HW_HAS_PCI diff --git a/trunk/arch/mips/vr41xx/common/init.c b/trunk/arch/mips/vr41xx/common/init.c index 8d760df686c4..407cec203b29 100644 --- a/trunk/arch/mips/vr41xx/common/init.c +++ b/trunk/arch/mips/vr41xx/common/init.c @@ -48,6 +48,11 @@ void __init plat_time_init(void) mips_hpt_frequency = tclock / 4; } +void __init plat_timer_setup(struct irqaction *irq) +{ + setup_irq(TIMER_IRQ, irq); +} + void __init plat_mem_setup(void) { vr41xx_calculate_clock_frequency(); diff --git a/trunk/arch/parisc/Kconfig b/trunk/arch/parisc/Kconfig index b8ef1787a191..3d73545e8c48 100644 --- a/trunk/arch/parisc/Kconfig +++ b/trunk/arch/parisc/Kconfig @@ -267,7 +267,7 @@ source "drivers/Kconfig" source "fs/Kconfig" -source "kernel/Kconfig.instrumentation" +source "arch/parisc/oprofile/Kconfig" source "arch/parisc/Kconfig.debug" diff --git a/trunk/arch/parisc/kernel/signal.c b/trunk/arch/parisc/kernel/signal.c index 2ce3806f02e1..fb35ebc0c4da 100644 --- a/trunk/arch/parisc/kernel/signal.c +++ b/trunk/arch/parisc/kernel/signal.c @@ -181,7 +181,7 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall) si.si_signo = SIGSEGV; si.si_errno = 0; si.si_code = SI_KERNEL; - si.si_pid = task_pid_vnr(current); + si.si_pid = current->pid; si.si_uid = current->uid; si.si_addr = &frame->uc; force_sig_info(SIGSEGV, &si, current); diff --git a/trunk/arch/parisc/kernel/traps.c b/trunk/arch/parisc/kernel/traps.c index 99fd56939afa..bbf029a184ac 100644 --- a/trunk/arch/parisc/kernel/traps.c +++ b/trunk/arch/parisc/kernel/traps.c @@ -219,7 +219,7 @@ void die_if_kernel(char *str, struct pt_regs *regs, long err) return; /* STFU */ printk(KERN_CRIT "%s (pid %d): %s (code %ld) at " RFMT "\n", - current->comm, task_pid_nr(current), str, err, regs->iaoq[0]); + current->comm, current->pid, str, err, regs->iaoq[0]); #ifdef PRINT_USER_FAULTS /* XXX for debugging only */ show_regs(regs); @@ -252,7 +252,7 @@ KERN_CRIT " || ||\n"); if (err) printk(KERN_CRIT "%s (pid %d): %s (code %ld)\n", - current->comm, task_pid_nr(current), str, err); + current->comm, current->pid, str, err); /* Wot's wrong wif bein' racy? */ if (current->thread.flags & PARISC_KERNEL_DEATH) { @@ -317,7 +317,7 @@ static void handle_break(struct pt_regs *regs) if (unlikely(iir != GDB_BREAK_INSN)) { printk(KERN_DEBUG "break %d,%d: pid=%d command='%s'\n", iir & 31, (iir>>13) & ((1<<13)-1), - task_pid_nr(current), current->comm); + current->pid, current->comm); show_regs(regs); } #endif @@ -747,7 +747,7 @@ void handle_interruption(int code, struct pt_regs *regs) if (user_mode(regs)) { #ifdef PRINT_USER_FAULTS printk(KERN_DEBUG "\nhandle_interruption() pid=%d command='%s'\n", - task_pid_nr(current), current->comm); + current->pid, current->comm); show_regs(regs); #endif /* SIGBUS, for lack of a better one. */ @@ -772,7 +772,7 @@ void handle_interruption(int code, struct pt_regs *regs) else printk(KERN_DEBUG "User Fault (long pointer) (fault %d) ", code); - printk("pid=%d command='%s'\n", task_pid_nr(current), current->comm); + printk("pid=%d command='%s'\n", current->pid, current->comm); show_regs(regs); #endif si.si_signo = SIGSEGV; diff --git a/trunk/arch/parisc/kernel/unaligned.c b/trunk/arch/parisc/kernel/unaligned.c index aebf3c168871..347bb922e6d0 100644 --- a/trunk/arch/parisc/kernel/unaligned.c +++ b/trunk/arch/parisc/kernel/unaligned.c @@ -469,7 +469,7 @@ void handle_unaligned(struct pt_regs *regs) && ++unaligned_count < 5) { char buf[256]; sprintf(buf, "%s(%d): unaligned access to 0x" RFMT " at ip=0x" RFMT "\n", - current->comm, task_pid_nr(current), regs->ior, regs->iaoq[0]); + current->comm, current->pid, regs->ior, regs->iaoq[0]); printk(KERN_WARNING "%s", buf); #ifdef DEBUG_UNALIGNED show_regs(regs); diff --git a/trunk/arch/parisc/mm/fault.c b/trunk/arch/parisc/mm/fault.c index b2e3e9a8cece..1c091b415cd9 100644 --- a/trunk/arch/parisc/mm/fault.c +++ b/trunk/arch/parisc/mm/fault.c @@ -211,7 +211,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long code, #ifdef PRINT_USER_FAULTS printk(KERN_DEBUG "\n"); printk(KERN_DEBUG "do_page_fault() pid=%d command='%s' type=%lu address=0x%08lx\n", - task_pid_nr(tsk), tsk->comm, code, address); + tsk->pid, tsk->comm, code, address); if (vma) { printk(KERN_DEBUG "vm_start = 0x%08lx, vm_end = 0x%08lx\n", vma->vm_start, vma->vm_end); diff --git a/trunk/arch/parisc/oprofile/Kconfig b/trunk/arch/parisc/oprofile/Kconfig new file mode 100644 index 000000000000..5ade19801b97 --- /dev/null +++ b/trunk/arch/parisc/oprofile/Kconfig @@ -0,0 +1,23 @@ + +menu "Profiling support" + depends on EXPERIMENTAL + +config PROFILING + bool "Profiling support (EXPERIMENTAL)" + help + Say Y here to enable the extended profiling support mechanisms used + by profilers such as OProfile. + + +config OPROFILE + tristate "OProfile system profiling (EXPERIMENTAL)" + depends on PROFILING + help + OProfile is a profiling system capable of profiling the + whole system, include the kernel, kernel modules, libraries, + and applications. + + If unsure, say N. + +endmenu + diff --git a/trunk/arch/powerpc/Kconfig b/trunk/arch/powerpc/Kconfig index 18f397ca05ef..3763f681ce4c 100644 --- a/trunk/arch/powerpc/Kconfig +++ b/trunk/arch/powerpc/Kconfig @@ -669,7 +669,20 @@ source "arch/powerpc/sysdev/qe_lib/Kconfig" source "lib/Kconfig" -source "kernel/Kconfig.instrumentation" +menu "Instrumentation Support" + +source "arch/powerpc/oprofile/Kconfig" + +config KPROBES + bool "Kprobes" + depends on !BOOKE && !4xx && KALLSYMS && MODULES + help + Kprobes allows you to trap at almost any kernel address and + execute a callback function. register_kprobe() establishes + a probepoint and specifies the callback. Kprobes is useful + for kernel debugging, non-intrusive instrumentation and testing. + If in doubt, say "N". +endmenu source "arch/powerpc/Kconfig.debug" diff --git a/trunk/arch/powerpc/configs/cell_defconfig b/trunk/arch/powerpc/configs/cell_defconfig index dcd7c02727c2..8b47c846421c 100644 --- a/trunk/arch/powerpc/configs/cell_defconfig +++ b/trunk/arch/powerpc/configs/cell_defconfig @@ -68,7 +68,6 @@ CONFIG_SYSVIPC_SYSCTL=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=15 -CONFIG_CGROUPS=y CONFIG_CPUSETS=y CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set diff --git a/trunk/arch/powerpc/configs/pmac32_defconfig b/trunk/arch/powerpc/configs/pmac32_defconfig index 8e5988c4a164..95b823b60c97 100644 --- a/trunk/arch/powerpc/configs/pmac32_defconfig +++ b/trunk/arch/powerpc/configs/pmac32_defconfig @@ -209,6 +209,7 @@ CONFIG_PM=y # CONFIG_PM_LEGACY is not set CONFIG_PM_DEBUG=y # CONFIG_PM_VERBOSE is not set +# CONFIG_DISABLE_CONSOLE_SUSPEND is not set CONFIG_PM_SLEEP=y CONFIG_SUSPEND=y CONFIG_HIBERNATION=y diff --git a/trunk/arch/powerpc/configs/ppc64_defconfig b/trunk/arch/powerpc/configs/ppc64_defconfig index 05582af50c5b..bb8d4e46f0c5 100644 --- a/trunk/arch/powerpc/configs/ppc64_defconfig +++ b/trunk/arch/powerpc/configs/ppc64_defconfig @@ -71,7 +71,6 @@ CONFIG_TASK_DELAY_ACCT=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=17 -CONFIG_CGROUPS=y CONFIG_CPUSETS=y CONFIG_SYSFS_DEPRECATED=y CONFIG_RELAY=y diff --git a/trunk/arch/powerpc/configs/pseries_defconfig b/trunk/arch/powerpc/configs/pseries_defconfig index 62a38406b62f..c09eb8cfbe71 100644 --- a/trunk/arch/powerpc/configs/pseries_defconfig +++ b/trunk/arch/powerpc/configs/pseries_defconfig @@ -71,7 +71,6 @@ CONFIG_AUDITSYSCALL=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=17 -CONFIG_CGROUPS=y CONFIG_CPUSETS=y CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set diff --git a/trunk/arch/powerpc/kernel/asm-offsets.c b/trunk/arch/powerpc/kernel/asm-offsets.c index 2c8e756d19a3..0ae5d57b9368 100644 --- a/trunk/arch/powerpc/kernel/asm-offsets.c +++ b/trunk/arch/powerpc/kernel/asm-offsets.c @@ -141,7 +141,6 @@ int main(void) DEFINE(PACALPPACAPTR, offsetof(struct paca_struct, lppaca_ptr)); DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id)); DEFINE(PACA_STARTPURR, offsetof(struct paca_struct, startpurr)); - DEFINE(PACA_STARTSPURR, offsetof(struct paca_struct, startspurr)); DEFINE(PACA_USER_TIME, offsetof(struct paca_struct, user_time)); DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time)); DEFINE(PACA_SLBSHADOWPTR, offsetof(struct paca_struct, slb_shadow_ptr)); diff --git a/trunk/arch/powerpc/kernel/machine_kexec.c b/trunk/arch/powerpc/kernel/machine_kexec.c index c0c8e8c3ced9..e60a0c544d63 100644 --- a/trunk/arch/powerpc/kernel/machine_kexec.c +++ b/trunk/arch/powerpc/kernel/machine_kexec.c @@ -61,39 +61,45 @@ NORET_TYPE void machine_kexec(struct kimage *image) for(;;); } +static int __init early_parse_crashk(char *p) +{ + unsigned long size; + + if (!p) + return 1; + + size = memparse(p, &p); + + if (*p == '@') + crashk_res.start = memparse(p + 1, &p); + else + crashk_res.start = KDUMP_KERNELBASE; + + crashk_res.end = crashk_res.start + size - 1; + + return 0; +} +early_param("crashkernel", early_parse_crashk); + void __init reserve_crashkernel(void) { - unsigned long long crash_size, crash_base; - int ret; - - /* this is necessary because of lmb_phys_mem_size() */ - lmb_analyze(); - - /* use common parsing */ - ret = parse_crashkernel(boot_command_line, lmb_phys_mem_size(), - &crash_size, &crash_base); - if (ret == 0 && crash_size > 0) { - if (crash_base == 0) - crash_base = KDUMP_KERNELBASE; - crashk_res.start = crash_base; - } else { - /* handle the device tree */ - crash_size = crashk_res.end - crashk_res.start + 1; - } + unsigned long size; - if (crash_size == 0) + if (crashk_res.start == 0) return; /* We might have got these values via the command line or the * device tree, either way sanitise them now. */ + size = crashk_res.end - crashk_res.start + 1; + if (crashk_res.start != KDUMP_KERNELBASE) printk("Crash kernel location must be 0x%x\n", KDUMP_KERNELBASE); crashk_res.start = KDUMP_KERNELBASE; - crash_size = PAGE_ALIGN(crash_size); - crashk_res.end = crashk_res.start + crash_size - 1; + size = PAGE_ALIGN(size); + crashk_res.end = crashk_res.start + size - 1; /* Crash kernel trumps memory limit */ if (memory_limit && memory_limit <= crashk_res.end) { @@ -102,13 +108,7 @@ void __init reserve_crashkernel(void) memory_limit); } - printk(KERN_INFO "Reserving %ldMB of memory at %ldMB " - "for crashkernel (System RAM: %ldMB)\n", - (unsigned long)(crash_size >> 20), - (unsigned long)(crashk_res.start >> 20), - (unsigned long)(lmb_phys_mem_size() >> 20)); - - lmb_reserve(crashk_res.start, crash_size); + lmb_reserve(crashk_res.start, size); } int overlaps_crashkernel(unsigned long start, unsigned long size) diff --git a/trunk/arch/powerpc/kernel/process.c b/trunk/arch/powerpc/kernel/process.c index b9d88374f14f..ea6ad7a2a7e3 100644 --- a/trunk/arch/powerpc/kernel/process.c +++ b/trunk/arch/powerpc/kernel/process.c @@ -459,7 +459,7 @@ void show_regs(struct pt_regs * regs) printk("DAR: "REG", DSISR: "REG"\n", regs->dar, regs->dsisr); #endif printk("TASK = %p[%d] '%s' THREAD: %p", - current, task_pid_nr(current), current->comm, task_thread_info(current)); + current, current->pid, current->comm, task_thread_info(current)); #ifdef CONFIG_SMP printk(" CPU: %d", smp_processor_id()); diff --git a/trunk/arch/powerpc/kernel/time.c b/trunk/arch/powerpc/kernel/time.c index 9eb3284deac4..863a5d6d9b18 100644 --- a/trunk/arch/powerpc/kernel/time.c +++ b/trunk/arch/powerpc/kernel/time.c @@ -211,45 +211,24 @@ static u64 read_purr(void) return mftb(); } -/* - * Read the SPURR on systems that have it, otherwise the purr - */ -static u64 read_spurr(u64 purr) -{ - if (cpu_has_feature(CPU_FTR_SPURR)) - return mfspr(SPRN_SPURR); - return purr; -} - /* * Account time for a transition between system, hard irq * or soft irq state. */ void account_system_vtime(struct task_struct *tsk) { - u64 now, nowscaled, delta, deltascaled; + u64 now, delta; unsigned long flags; local_irq_save(flags); now = read_purr(); delta = now - get_paca()->startpurr; get_paca()->startpurr = now; - nowscaled = read_spurr(now); - deltascaled = nowscaled - get_paca()->startspurr; - get_paca()->startspurr = nowscaled; if (!in_interrupt()) { - /* deltascaled includes both user and system time. - * Hence scale it based on the purr ratio to estimate - * the system time */ - deltascaled = deltascaled * get_paca()->system_time / - (get_paca()->system_time + get_paca()->user_time); delta += get_paca()->system_time; get_paca()->system_time = 0; } account_system_time(tsk, 0, delta); - get_paca()->purrdelta = delta; - account_system_time_scaled(tsk, deltascaled); - get_paca()->spurrdelta = deltascaled; local_irq_restore(flags); } @@ -261,17 +240,11 @@ void account_system_vtime(struct task_struct *tsk) */ void account_process_vtime(struct task_struct *tsk) { - cputime_t utime, utimescaled; + cputime_t utime; utime = get_paca()->user_time; get_paca()->user_time = 0; account_user_time(tsk, utime); - - /* Estimate the scaled utime by scaling the real utime based - * on the last spurr to purr ratio */ - utimescaled = utime * get_paca()->spurrdelta / get_paca()->purrdelta; - get_paca()->spurrdelta = get_paca()->purrdelta = 0; - account_user_time_scaled(tsk, utimescaled); } static void account_process_time(struct pt_regs *regs) @@ -293,7 +266,6 @@ struct cpu_purr_data { int initialized; /* thread is running */ u64 tb; /* last TB value read */ u64 purr; /* last PURR value read */ - u64 spurr; /* last SPURR value read */ }; /* diff --git a/trunk/arch/powerpc/kernel/traps.c b/trunk/arch/powerpc/kernel/traps.c index 59c464e26f38..bf9e39c6e296 100644 --- a/trunk/arch/powerpc/kernel/traps.c +++ b/trunk/arch/powerpc/kernel/traps.c @@ -201,7 +201,7 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr) * generate the same exception over and over again and we get * nowhere. Better to kill it and let the kernel panic. */ - if (is_global_init(current)) { + if (is_init(current)) { __sighandler_t handler; spin_lock_irq(¤t->sighand->siglock); @@ -881,7 +881,7 @@ void nonrecoverable_exception(struct pt_regs *regs) void trace_syscall(struct pt_regs *regs) { printk("Task: %p(%d), PC: %08lX/%08lX, Syscall: %3ld, Result: %s%ld %s\n", - current, task_pid_nr(current), regs->nip, regs->link, regs->gpr[0], + current, current->pid, regs->nip, regs->link, regs->gpr[0], regs->ccr&0x10000000?"Error=":"", regs->gpr[3], print_tainted()); } diff --git a/trunk/arch/powerpc/mm/fault.c b/trunk/arch/powerpc/mm/fault.c index a18fda361cc0..ab3546c5ac3a 100644 --- a/trunk/arch/powerpc/mm/fault.c +++ b/trunk/arch/powerpc/mm/fault.c @@ -375,7 +375,7 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address, */ out_of_memory: up_read(&mm->mmap_sem); - if (is_global_init(current)) { + if (is_init(current)) { yield(); down_read(&mm->mmap_sem); goto survive; diff --git a/trunk/arch/powerpc/oprofile/Kconfig b/trunk/arch/powerpc/oprofile/Kconfig new file mode 100644 index 000000000000..7089e79689b9 --- /dev/null +++ b/trunk/arch/powerpc/oprofile/Kconfig @@ -0,0 +1,24 @@ +config PROFILING + bool "Profiling support (EXPERIMENTAL)" + help + Say Y here to enable the extended profiling support mechanisms used + by profilers such as OProfile. + + +config OPROFILE + tristate "OProfile system profiling (EXPERIMENTAL)" + depends on PROFILING + help + OProfile is a profiling system capable of profiling the + whole system, include the kernel, kernel modules, libraries, + and applications. + + If unsure, say N. + +config OPROFILE_CELL + bool "OProfile for Cell Broadband Engine" + depends on (SPU_FS = y && OPROFILE = m) || (SPU_FS = y && OPROFILE = y) || (SPU_FS = m && OPROFILE = m) + default y + help + Profiling of Cell BE SPUs requires special support enabled + by this option. diff --git a/trunk/arch/powerpc/platforms/52xx/lite5200_pm.c b/trunk/arch/powerpc/platforms/52xx/lite5200_pm.c index ffa14aff5248..f26afcd41757 100644 --- a/trunk/arch/powerpc/platforms/52xx/lite5200_pm.c +++ b/trunk/arch/powerpc/platforms/52xx/lite5200_pm.c @@ -1,5 +1,5 @@ #include -#include +#include #include #include #include @@ -18,8 +18,6 @@ static void __iomem *sram; static const int sram_size = 0x4000; /* 16 kBytes */ static void __iomem *mbar; -static suspend_state_t lite5200_pm_target_state; - static int lite5200_pm_valid(suspend_state_t state) { switch (state) { @@ -31,22 +29,13 @@ static int lite5200_pm_valid(suspend_state_t state) } } -static int lite5200_pm_set_target(suspend_state_t state) -{ - if (lite5200_pm_valid(state)) { - lite5200_pm_target_state = state; - return 0; - } - return -EINVAL; -} - -static int lite5200_pm_prepare(void) +static int lite5200_pm_prepare(suspend_state_t state) { /* deep sleep? let mpc52xx code handle that */ - if (lite5200_pm_target_state == PM_SUSPEND_STANDBY) - return mpc52xx_pm_prepare(); + if (state == PM_SUSPEND_STANDBY) + return mpc52xx_pm_prepare(state); - if (lite5200_pm_target_state != PM_SUSPEND_MEM) + if (state != PM_SUSPEND_MEM) return -EINVAL; /* map registers */ @@ -201,16 +190,17 @@ static int lite5200_pm_enter(suspend_state_t state) return 0; } -static void lite5200_pm_finish(void) +static int lite5200_pm_finish(suspend_state_t state) { /* deep sleep? let mpc52xx code handle that */ - if (lite5200_pm_target_state == PM_SUSPEND_STANDBY) - mpc52xx_pm_finish(); + if (state == PM_SUSPEND_STANDBY) { + return mpc52xx_pm_finish(state); + } + return 0; } -static struct platform_suspend_ops lite5200_pm_ops = { +static struct pm_ops lite5200_pm_ops = { .valid = lite5200_pm_valid, - .set_target = lite5200_pm_set_target, .prepare = lite5200_pm_prepare, .enter = lite5200_pm_enter, .finish = lite5200_pm_finish, @@ -218,6 +208,6 @@ static struct platform_suspend_ops lite5200_pm_ops = { int __init lite5200_pm_init(void) { - suspend_set_ops(&lite5200_pm_ops); + pm_set_ops(&lite5200_pm_ops); return 0; } diff --git a/trunk/arch/powerpc/platforms/52xx/mpc52xx_pm.c b/trunk/arch/powerpc/platforms/52xx/mpc52xx_pm.c index 7ffa7babf254..ee2e7639c63e 100644 --- a/trunk/arch/powerpc/platforms/52xx/mpc52xx_pm.c +++ b/trunk/arch/powerpc/platforms/52xx/mpc52xx_pm.c @@ -1,5 +1,5 @@ #include -#include +#include #include #include #include @@ -57,8 +57,11 @@ int mpc52xx_set_wakeup_gpio(u8 pin, u8 level) return 0; } -int mpc52xx_pm_prepare(void) +int mpc52xx_pm_prepare(suspend_state_t state) { + if (state != PM_SUSPEND_STANDBY) + return -EINVAL; + /* map the whole register space */ mbar = mpc52xx_find_and_map("mpc5200"); if (!mbar) { @@ -163,16 +166,18 @@ int mpc52xx_pm_enter(suspend_state_t state) return 0; } -void mpc52xx_pm_finish(void) +int mpc52xx_pm_finish(suspend_state_t state) { /* call board resume code */ if (mpc52xx_suspend.board_resume_finish) mpc52xx_suspend.board_resume_finish(mbar); iounmap(mbar); + + return 0; } -static struct platform_suspend_ops mpc52xx_pm_ops = { +static struct pm_ops mpc52xx_pm_ops = { .valid = mpc52xx_pm_valid, .prepare = mpc52xx_pm_prepare, .enter = mpc52xx_pm_enter, @@ -181,6 +186,6 @@ static struct platform_suspend_ops mpc52xx_pm_ops = { int __init mpc52xx_pm_init(void) { - suspend_set_ops(&mpc52xx_pm_ops); + pm_set_ops(&mpc52xx_pm_ops); return 0; } diff --git a/trunk/arch/powerpc/platforms/maple/setup.c b/trunk/arch/powerpc/platforms/maple/setup.c index 144177d77cf1..354c05861629 100644 --- a/trunk/arch/powerpc/platforms/maple/setup.c +++ b/trunk/arch/powerpc/platforms/maple/setup.c @@ -41,13 +41,13 @@ #include #include #include -#include #include #include #include #include #include +#include #include #include #include diff --git a/trunk/arch/powerpc/platforms/pseries/ras.c b/trunk/arch/powerpc/platforms/pseries/ras.c index a1ab25c7082f..3a393c7f390e 100644 --- a/trunk/arch/powerpc/platforms/pseries/ras.c +++ b/trunk/arch/powerpc/platforms/pseries/ras.c @@ -332,7 +332,7 @@ static int recover_mce(struct pt_regs *regs, struct rtas_error_log * err) err->disposition == RTAS_DISP_NOT_RECOVERED && err->target == RTAS_TARGET_MEMORY && err->type == RTAS_TYPE_ECC_UNCORR && - !(current->pid == 0 || is_global_init(current))) { + !(current->pid == 0 || is_init(current))) { /* Kill off a user process with an ECC error */ printk(KERN_ERR "MCE: uncorrectable ecc error for pid %d\n", current->pid); diff --git a/trunk/arch/ppc/Kconfig b/trunk/arch/ppc/Kconfig index 6473fa7cb4b9..607925c8a99e 100644 --- a/trunk/arch/ppc/Kconfig +++ b/trunk/arch/ppc/Kconfig @@ -1317,7 +1317,7 @@ endmenu source "lib/Kconfig" -source "kernel/Kconfig.instrumentation" +source "arch/powerpc/oprofile/Kconfig" source "arch/ppc/Kconfig.debug" diff --git a/trunk/arch/ppc/kernel/traps.c b/trunk/arch/ppc/kernel/traps.c index c78568905c3b..3f3b292eb773 100644 --- a/trunk/arch/ppc/kernel/traps.c +++ b/trunk/arch/ppc/kernel/traps.c @@ -121,7 +121,7 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr) * generate the same exception over and over again and we get * nowhere. Better to kill it and let the kernel panic. */ - if (is_global_init(current)) { + if (is_init(current)) { __sighandler_t handler; spin_lock_irq(¤t->sighand->siglock); diff --git a/trunk/arch/ppc/mm/fault.c b/trunk/arch/ppc/mm/fault.c index 254c23b755e6..94913ddcf76e 100644 --- a/trunk/arch/ppc/mm/fault.c +++ b/trunk/arch/ppc/mm/fault.c @@ -290,7 +290,7 @@ int do_page_fault(struct pt_regs *regs, unsigned long address, */ out_of_memory: up_read(&mm->mmap_sem); - if (is_global_init(current)) { + if (is_init(current)) { yield(); down_read(&mm->mmap_sem); goto survive; diff --git a/trunk/arch/ppc/platforms/chestnut.c b/trunk/arch/ppc/platforms/chestnut.c index dcd6070b85eb..248684f50dd9 100644 --- a/trunk/arch/ppc/platforms/chestnut.c +++ b/trunk/arch/ppc/platforms/chestnut.c @@ -49,6 +49,7 @@ extern void gen550_progress(char *, unsigned short); extern void gen550_init(int, struct uart_port *); extern void mv64360_pcibios_fixup(mv64x60_handle_t *bh); +#define BIT(x) (1<cpu, print_tainted()); printk("Process %s (pid: %d, task: %p, ksp: %p)\n", - current->comm, task_pid_nr(current), (void *) tsk, + current->comm, current->pid, (void *) tsk, (void *) tsk->thread.ksp); show_registers(regs); diff --git a/trunk/arch/s390/lib/uaccess_pt.c b/trunk/arch/s390/lib/uaccess_pt.c index b159a9d65680..60604b2819b2 100644 --- a/trunk/arch/s390/lib/uaccess_pt.c +++ b/trunk/arch/s390/lib/uaccess_pt.c @@ -64,7 +64,7 @@ static int __handle_fault(struct mm_struct *mm, unsigned long address, out_of_memory: up_read(&mm->mmap_sem); - if (is_global_init(current)) { + if (is_init(current)) { yield(); down_read(&mm->mmap_sem); goto survive; diff --git a/trunk/arch/s390/mm/fault.c b/trunk/arch/s390/mm/fault.c index 2456b52ed068..14c241ccdd4d 100644 --- a/trunk/arch/s390/mm/fault.c +++ b/trunk/arch/s390/mm/fault.c @@ -211,7 +211,7 @@ static int do_out_of_memory(struct pt_regs *regs, unsigned long error_code, struct mm_struct *mm = tsk->mm; up_read(&mm->mmap_sem); - if (is_global_init(tsk)) { + if (is_init(tsk)) { yield(); down_read(&mm->mmap_sem); return 1; diff --git a/trunk/arch/s390/oprofile/Kconfig b/trunk/arch/s390/oprofile/Kconfig new file mode 100644 index 000000000000..208220a5f23f --- /dev/null +++ b/trunk/arch/s390/oprofile/Kconfig @@ -0,0 +1,22 @@ + +menu "Profiling support" + +config PROFILING + bool "Profiling support" + help + Say Y here to enable profiling support mechanisms used by + profilers such as readprofile or OProfile. + + +config OPROFILE + tristate "OProfile system profiling" + depends on PROFILING + help + OProfile is a profiling system capable of profiling the + whole system, include the kernel, kernel modules, libraries, + and applications. + + If unsure, say N. + +endmenu + diff --git a/trunk/arch/sh/Kconfig b/trunk/arch/sh/Kconfig index 247f8a65e733..44982c1dfa23 100644 --- a/trunk/arch/sh/Kconfig +++ b/trunk/arch/sh/Kconfig @@ -758,7 +758,7 @@ source "drivers/Kconfig" source "fs/Kconfig" -source "kernel/Kconfig.instrumentation" +source "arch/sh/oprofile/Kconfig" source "arch/sh/Kconfig.debug" diff --git a/trunk/arch/sh/boards/hp6xx/pm.c b/trunk/arch/sh/boards/hp6xx/pm.c index d22f6eac9cca..8143d1b948e7 100644 --- a/trunk/arch/sh/boards/hp6xx/pm.c +++ b/trunk/arch/sh/boards/hp6xx/pm.c @@ -67,14 +67,14 @@ static int hp6x0_pm_enter(suspend_state_t state) return 0; } -static struct platform_suspend_ops hp6x0_pm_ops = { +static struct pm_ops hp6x0_pm_ops = { .enter = hp6x0_pm_enter, - .valid = suspend_valid_only_mem, + .valid = pm_valid_only_mem, }; static int __init hp6x0_pm_init(void) { - suspend_set_ops(&hp6x0_pm_ops); + pm_set_ops(&hp6x0_pm_ops); return 0; } diff --git a/trunk/arch/sh/kernel/machine_kexec.c b/trunk/arch/sh/kernel/machine_kexec.c index 5c17de51987e..790ed69b8666 100644 --- a/trunk/arch/sh/kernel/machine_kexec.c +++ b/trunk/arch/sh/kernel/machine_kexec.c @@ -104,3 +104,24 @@ NORET_TYPE void machine_kexec(struct kimage *image) (*rnk)(page_list, reboot_code_buffer, image->start, vbr_reg); } +/* crashkernel=size@addr specifies the location to reserve for + * a crash kernel. By reserving this memory we guarantee + * that linux never sets it up as a DMA target. + * Useful for holding code to do something appropriate + * after a kernel panic. + */ +static int __init parse_crashkernel(char *arg) +{ + unsigned long size, base; + size = memparse(arg, &arg); + if (*arg == '@') { + base = memparse(arg+1, &arg); + /* FIXME: Do I want a sanity check + * to validate the memory range? + */ + crashk_res.start = base; + crashk_res.end = base + size - 1; + } + return 0; +} +early_param("crashkernel", parse_crashkernel); diff --git a/trunk/arch/sh/kernel/process.c b/trunk/arch/sh/kernel/process.c index 6d7f2b07e491..b4469992d6b2 100644 --- a/trunk/arch/sh/kernel/process.c +++ b/trunk/arch/sh/kernel/process.c @@ -121,7 +121,7 @@ void machine_power_off(void) void show_regs(struct pt_regs * regs) { printk("\n"); - printk("Pid : %d, Comm: %20s\n", task_pid_nr(current), current->comm); + printk("Pid : %d, Comm: %20s\n", current->pid, current->comm); print_symbol("PC is at %s\n", instruction_pointer(regs)); printk("PC : %08lx SP : %08lx SR : %08lx ", regs->pc, regs->regs[15], regs->sr); diff --git a/trunk/arch/sh/kernel/setup.c b/trunk/arch/sh/kernel/setup.c index b749403f6b38..b3027a6775b9 100644 --- a/trunk/arch/sh/kernel/setup.c +++ b/trunk/arch/sh/kernel/setup.c @@ -128,37 +128,6 @@ static void __init register_bootmem_low_pages(void) free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(pages)); } -#ifdef CONFIG_KEXEC -static void __init reserve_crashkernel(void) -{ - unsigned long long free_mem; - unsigned long long crash_size, crash_base; - int ret; - - free_mem = ((unsigned long long)max_low_pfn - min_low_pfn) << PAGE_SHIFT; - - ret = parse_crashkernel(boot_command_line, free_mem, - &crash_size, &crash_base); - if (ret == 0 && crash_size) { - if (crash_base > 0) { - printk(KERN_INFO "Reserving %ldMB of memory at %ldMB " - "for crashkernel (System RAM: %ldMB)\n", - (unsigned long)(crash_size >> 20), - (unsigned long)(crash_base >> 20), - (unsigned long)(free_mem >> 20)); - crashk_res.start = crash_base; - crashk_res.end = crash_base + crash_size - 1; - reserve_bootmem(crash_base, crash_size); - } else - printk(KERN_INFO "crashkernel reservation failed - " - "you have to specify a base address\n"); - } -} -#else -static inline void __init reserve_crashkernel(void) -{} -#endif - void __init setup_bootmem_allocator(unsigned long free_pfn) { unsigned long bootmap_size; @@ -220,8 +189,11 @@ void __init setup_bootmem_allocator(unsigned long free_pfn) } } #endif - - reserve_crashkernel(); +#ifdef CONFIG_KEXEC + if (crashk_res.start != crashk_res.end) + reserve_bootmem(crashk_res.start, + crashk_res.end - crashk_res.start + 1); +#endif } #ifndef CONFIG_NEED_MULTIPLE_NODES diff --git a/trunk/arch/sh/kernel/signal.c b/trunk/arch/sh/kernel/signal.c index ca754fd42437..2f42442cf164 100644 --- a/trunk/arch/sh/kernel/signal.c +++ b/trunk/arch/sh/kernel/signal.c @@ -382,7 +382,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, set_fs(USER_DS); pr_debug("SIG deliver (%s:%d): sp=%p pc=%08lx pr=%08lx\n", - current->comm, task_pid_nr(current), frame, regs->pc, regs->pr); + current->comm, current->pid, frame, regs->pc, regs->pr); flush_cache_sigtramp(regs->pr); @@ -462,7 +462,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, set_fs(USER_DS); pr_debug("SIG deliver (%s:%d): sp=%p pc=%08lx pr=%08lx\n", - current->comm, task_pid_nr(current), frame, regs->pc, regs->pr); + current->comm, current->pid, frame, regs->pc, regs->pr); flush_cache_sigtramp(regs->pr); diff --git a/trunk/arch/sh/kernel/traps.c b/trunk/arch/sh/kernel/traps.c index cf99111cb33f..dcb46e71da1c 100644 --- a/trunk/arch/sh/kernel/traps.c +++ b/trunk/arch/sh/kernel/traps.c @@ -95,8 +95,8 @@ void die(const char * str, struct pt_regs * regs, long err) print_modules(); show_regs(regs); - printk("Process: %s (pid: %d, stack limit = %p)\n", current->comm, - task_pid_nr(current), task_stack_page(current) + 1); + printk("Process: %s (pid: %d, stack limit = %p)\n", + current->comm, current->pid, task_stack_page(current) + 1); if (!user_mode(regs) || in_interrupt()) dump_mem("Stack: ", regs->regs[15], THREAD_SIZE + @@ -386,8 +386,7 @@ static int handle_unaligned_access(u16 instruction, struct pt_regs *regs) printk(KERN_NOTICE "Fixing up unaligned userspace access " "in \"%s\" pid=%d pc=0x%p ins=0x%04hx\n", - current->comm, task_pid_nr(current), - (u16 *)regs->pc, instruction); + current->comm,current->pid,(u16*)regs->pc,instruction); } ret = -EFAULT; diff --git a/trunk/arch/sh/mm/fault.c b/trunk/arch/sh/mm/fault.c index f33cedb353fc..4729668ce5bf 100644 --- a/trunk/arch/sh/mm/fault.c +++ b/trunk/arch/sh/mm/fault.c @@ -207,7 +207,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, */ out_of_memory: up_read(&mm->mmap_sem); - if (is_global_init(current)) { + if (is_init(current)) { yield(); down_read(&mm->mmap_sem); goto survive; diff --git a/trunk/arch/sh/oprofile/Kconfig b/trunk/arch/sh/oprofile/Kconfig new file mode 100644 index 000000000000..5ade19801b97 --- /dev/null +++ b/trunk/arch/sh/oprofile/Kconfig @@ -0,0 +1,23 @@ + +menu "Profiling support" + depends on EXPERIMENTAL + +config PROFILING + bool "Profiling support (EXPERIMENTAL)" + help + Say Y here to enable the extended profiling support mechanisms used + by profilers such as OProfile. + + +config OPROFILE + tristate "OProfile system profiling (EXPERIMENTAL)" + depends on PROFILING + help + OProfile is a profiling system capable of profiling the + whole system, include the kernel, kernel modules, libraries, + and applications. + + If unsure, say N. + +endmenu + diff --git a/trunk/arch/sh64/Kconfig b/trunk/arch/sh64/Kconfig index ba204bac49df..b3327ce8e82f 100644 --- a/trunk/arch/sh64/Kconfig +++ b/trunk/arch/sh64/Kconfig @@ -284,7 +284,7 @@ source "drivers/Kconfig" source "fs/Kconfig" -source "kernel/Kconfig.instrumentation" +source "arch/sh64/oprofile/Kconfig" source "arch/sh64/Kconfig.debug" diff --git a/trunk/arch/sh64/kernel/traps.c b/trunk/arch/sh64/kernel/traps.c index c03101fab467..9d0d58fb29fa 100644 --- a/trunk/arch/sh64/kernel/traps.c +++ b/trunk/arch/sh64/kernel/traps.c @@ -764,7 +764,7 @@ static int misaligned_fixup(struct pt_regs *regs) --user_mode_unaligned_fixup_count; /* Only do 'count' worth of these reports, to remove a potential DoS against syslog */ printk("Fixing up unaligned userspace access in \"%s\" pid=%d pc=0x%08x ins=0x%08lx\n", - current->comm, task_pid_nr(current), (__u32)regs->pc, opcode); + current->comm, current->pid, (__u32)regs->pc, opcode); } else #endif if (!user_mode(regs) && (kernel_mode_unaligned_fixup_count > 0)) { @@ -774,7 +774,7 @@ static int misaligned_fixup(struct pt_regs *regs) (__u32)regs->pc, opcode); } else { printk("Fixing up unaligned kernelspace access in \"%s\" pid=%d pc=0x%08x ins=0x%08lx\n", - current->comm, task_pid_nr(current), (__u32)regs->pc, opcode); + current->comm, current->pid, (__u32)regs->pc, opcode); } } diff --git a/trunk/arch/sh64/mm/fault.c b/trunk/arch/sh64/mm/fault.c index 7c79a1ba8059..dd81c669c79b 100644 --- a/trunk/arch/sh64/mm/fault.c +++ b/trunk/arch/sh64/mm/fault.c @@ -81,7 +81,7 @@ static inline void print_vma(struct vm_area_struct *vma) static inline void print_task(struct task_struct *tsk) { - printk("Task pid %d\n", task_pid_nr(tsk)); + printk("Task pid %d\n", tsk->pid); } static pte_t *lookup_pte(struct mm_struct *mm, unsigned long address) @@ -272,13 +272,13 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess, * usermode, so only need a few */ count++; printk("user mode bad_area address=%08lx pid=%d (%s) pc=%08lx\n", - address, task_pid_nr(current), current->comm, + address, current->pid, current->comm, (unsigned long) regs->pc); #if 0 show_regs(regs); #endif } - if (is_global_init(tsk)) { + if (is_init(tsk)) { panic("INIT had user mode bad_area\n"); } tsk->thread.address = address; @@ -320,14 +320,14 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess, * us unable to handle the page fault gracefully. */ out_of_memory: - if (is_global_init(current)) { + if (is_init(current)) { panic("INIT out of memory\n"); yield(); goto survive; } printk("fault:Out of memory\n"); up_read(&mm->mmap_sem); - if (is_global_init(current)) { + if (is_init(current)) { yield(); down_read(&mm->mmap_sem); goto survive; diff --git a/trunk/arch/sh64/oprofile/Kconfig b/trunk/arch/sh64/oprofile/Kconfig new file mode 100644 index 000000000000..19d37730b664 --- /dev/null +++ b/trunk/arch/sh64/oprofile/Kconfig @@ -0,0 +1,23 @@ + +menu "Profiling support" + depends on EXPERIMENTAL + +config PROFILING + bool "Profiling support (EXPERIMENTAL)" + help + Say Y here to enable the extended profiling support mechanisms used + by profilers such as OProfile. + + +config OPROFILE + tristate "OProfile system profiling (EXPERIMENTAL)" + depends on PROFILING + help + OProfile is a profiling system capable of profiling the + whole system, include the kernel, kernel modules, libraries, + and applications. + + If unsure, say N. + +endmenu + diff --git a/trunk/arch/sparc/Kconfig b/trunk/arch/sparc/Kconfig index 527adc808ad6..c0f4ba109daa 100644 --- a/trunk/arch/sparc/Kconfig +++ b/trunk/arch/sparc/Kconfig @@ -320,7 +320,11 @@ endmenu source "fs/Kconfig" -source "kernel/Kconfig.instrumentation" +menu "Instrumentation Support" + +source "arch/sparc/oprofile/Kconfig" + +endmenu source "arch/sparc/Kconfig.debug" diff --git a/trunk/arch/sparc/kernel/of_device.c b/trunk/arch/sparc/kernel/of_device.c index 3ea000d15e3a..fb2caef79cec 100644 --- a/trunk/arch/sparc/kernel/of_device.c +++ b/trunk/arch/sparc/kernel/of_device.c @@ -585,6 +585,24 @@ static int __init of_debug(char *str) __setup("of_debug=", of_debug); +int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus) +{ + /* initialize common driver fields */ + if (!drv->driver.name) + drv->driver.name = drv->name; + if (!drv->driver.owner) + drv->driver.owner = drv->owner; + drv->driver.bus = bus; + + /* register with core */ + return driver_register(&drv->driver); +} + +void of_unregister_driver(struct of_platform_driver *drv) +{ + driver_unregister(&drv->driver); +} + struct of_device* of_platform_device_create(struct device_node *np, const char *bus_id, struct device *parent, @@ -610,4 +628,6 @@ struct of_device* of_platform_device_create(struct device_node *np, return dev; } +EXPORT_SYMBOL(of_register_driver); +EXPORT_SYMBOL(of_unregister_driver); EXPORT_SYMBOL(of_platform_device_create); diff --git a/trunk/arch/sparc/kernel/ptrace.c b/trunk/arch/sparc/kernel/ptrace.c index fe562db475e9..003f8eed32f4 100644 --- a/trunk/arch/sparc/kernel/ptrace.c +++ b/trunk/arch/sparc/kernel/ptrace.c @@ -155,7 +155,7 @@ static inline void read_sunos_user(struct pt_regs *regs, unsigned long offset, /* Rest of them are completely unsupported. */ default: printk("%s [%d]: Wants to read user offset %ld\n", - current->comm, task_pid_nr(current), offset); + current->comm, current->pid, offset); pt_error_return(regs, EIO); return; } @@ -222,7 +222,7 @@ static inline void write_sunos_user(struct pt_regs *regs, unsigned long offset, /* Rest of them are completely unsupported or "no-touch". */ default: printk("%s [%d]: Wants to write user offset %ld\n", - current->comm, task_pid_nr(current), offset); + current->comm, current->pid, offset); goto failure; } success: diff --git a/trunk/arch/sparc/kernel/sys_sparc.c b/trunk/arch/sparc/kernel/sys_sparc.c index 42bf09db9a81..6c0221e9a9f5 100644 --- a/trunk/arch/sparc/kernel/sys_sparc.c +++ b/trunk/arch/sparc/kernel/sys_sparc.c @@ -357,7 +357,7 @@ c_sys_nis_syscall (struct pt_regs *regs) if (count++ > 5) return -ENOSYS; printk ("%s[%d]: Unimplemented SPARC system call %d\n", - current->comm, task_pid_nr(current), (int)regs->u_regs[1]); + current->comm, current->pid, (int)regs->u_regs[1]); #ifdef DEBUG_UNIMP_SYSCALL show_regs (regs); #endif diff --git a/trunk/arch/sparc/kernel/sys_sunos.c b/trunk/arch/sparc/kernel/sys_sunos.c index 28c187c5d9fd..f807172cab0e 100644 --- a/trunk/arch/sparc/kernel/sys_sunos.c +++ b/trunk/arch/sparc/kernel/sys_sunos.c @@ -866,7 +866,7 @@ asmlinkage int sunos_killpg(int pgrp, int sig) rcu_read_lock(); ret = -EINVAL; if (pgrp > 0) - ret = kill_pgrp(find_vpid(pgrp), sig, 0); + ret = kill_pgrp(find_pid(pgrp), sig, 0); rcu_read_unlock(); return ret; diff --git a/trunk/arch/sparc/kernel/traps.c b/trunk/arch/sparc/kernel/traps.c index d404e7994527..3bc3bff51e08 100644 --- a/trunk/arch/sparc/kernel/traps.c +++ b/trunk/arch/sparc/kernel/traps.c @@ -38,7 +38,7 @@ struct trap_trace_entry trapbuf[1024]; void syscall_trace_entry(struct pt_regs *regs) { - printk("%s[%d]: ", current->comm, task_pid_nr(current)); + printk("%s[%d]: ", current->comm, current->pid); printk("scall<%d> (could be %d)\n", (int) regs->u_regs[UREG_G1], (int) regs->u_regs[UREG_I0]); } @@ -99,7 +99,7 @@ void die_if_kernel(char *str, struct pt_regs *regs) " /_| \\__/ |_\\\n" " \\__U_/\n"); - printk("%s(%d): %s [#%d]\n", current->comm, task_pid_nr(current), str, ++die_counter); + printk("%s(%d): %s [#%d]\n", current->comm, current->pid, str, ++die_counter); show_regs(regs); add_taint(TAINT_DIE); diff --git a/trunk/arch/sparc/oprofile/Kconfig b/trunk/arch/sparc/oprofile/Kconfig new file mode 100644 index 000000000000..d8a84088471a --- /dev/null +++ b/trunk/arch/sparc/oprofile/Kconfig @@ -0,0 +1,17 @@ +config PROFILING + bool "Profiling support (EXPERIMENTAL)" + help + Say Y here to enable the extended profiling support mechanisms used + by profilers such as OProfile. + + +config OPROFILE + tristate "OProfile system profiling (EXPERIMENTAL)" + depends on PROFILING + help + OProfile is a profiling system capable of profiling the + whole system, include the kernel, kernel modules, libraries, + and applications. + + If unsure, say N. + diff --git a/trunk/arch/sparc64/Kconfig b/trunk/arch/sparc64/Kconfig index c7a74e376985..59c4d752d286 100644 --- a/trunk/arch/sparc64/Kconfig +++ b/trunk/arch/sparc64/Kconfig @@ -460,7 +460,20 @@ source "drivers/fc4/Kconfig" source "fs/Kconfig" -source "kernel/Kconfig.instrumentation" +menu "Instrumentation Support" + +source "arch/sparc64/oprofile/Kconfig" + +config KPROBES + bool "Kprobes (EXPERIMENTAL)" + depends on KALLSYMS && EXPERIMENTAL && MODULES + help + Kprobes allows you to trap at almost any kernel address and + execute a callback function. register_kprobe() establishes + a probepoint and specifies the callback. Kprobes is useful + for kernel debugging, non-intrusive instrumentation and testing. + If in doubt, say "N". +endmenu source "arch/sparc64/Kconfig.debug" diff --git a/trunk/arch/sparc64/kernel/irq.c b/trunk/arch/sparc64/kernel/irq.c index 2c3bea228159..f3922e5a89f6 100644 --- a/trunk/arch/sparc64/kernel/irq.c +++ b/trunk/arch/sparc64/kernel/irq.c @@ -877,7 +877,7 @@ void __cpuinit sun4v_register_mondo_queues(int this_cpu) static void __init alloc_one_mondo(unsigned long *pa_ptr, unsigned long qmask) { unsigned long size = PAGE_ALIGN(qmask + 1); - void *p = __alloc_bootmem(size, size, 0); + void *p = __alloc_bootmem_low(size, size, 0); if (!p) { prom_printf("SUN4V: Error, cannot allocate mondo queue.\n"); prom_halt(); @@ -889,7 +889,7 @@ static void __init alloc_one_mondo(unsigned long *pa_ptr, unsigned long qmask) static void __init alloc_one_kbuf(unsigned long *pa_ptr, unsigned long qmask) { unsigned long size = PAGE_ALIGN(qmask + 1); - void *p = __alloc_bootmem(size, size, 0); + void *p = __alloc_bootmem_low(size, size, 0); if (!p) { prom_printf("SUN4V: Error, cannot allocate kbuf page.\n"); @@ -906,7 +906,7 @@ static void __init init_cpu_send_mondo_info(struct trap_per_cpu *tb) BUILD_BUG_ON((NR_CPUS * sizeof(u16)) > (PAGE_SIZE - 64)); - page = alloc_bootmem_pages(PAGE_SIZE); + page = alloc_bootmem_low_pages(PAGE_SIZE); if (!page) { prom_printf("SUN4V: Error, cannot allocate cpu mondo page.\n"); prom_halt(); @@ -953,7 +953,7 @@ void __init init_IRQ(void) kill_prom_timer(); size = sizeof(struct ino_bucket) * NUM_IVECS; - ivector_table = alloc_bootmem(size); + ivector_table = alloc_bootmem_low(size); if (!ivector_table) { prom_printf("Fatal error, cannot allocate ivector_table\n"); prom_halt(); diff --git a/trunk/arch/sparc64/kernel/of_device.c b/trunk/arch/sparc64/kernel/of_device.c index fc5c0cc793b8..42d779866fba 100644 --- a/trunk/arch/sparc64/kernel/of_device.c +++ b/trunk/arch/sparc64/kernel/of_device.c @@ -869,6 +869,26 @@ static int __init of_debug(char *str) __setup("of_debug=", of_debug); +int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus) +{ + /* initialize common driver fields */ + if (!drv->driver.name) + drv->driver.name = drv->name; + if (!drv->driver.owner) + drv->driver.owner = drv->owner; + drv->driver.bus = bus; + + /* register with core */ + return driver_register(&drv->driver); +} +EXPORT_SYMBOL(of_register_driver); + +void of_unregister_driver(struct of_platform_driver *drv) +{ + driver_unregister(&drv->driver); +} +EXPORT_SYMBOL(of_unregister_driver); + struct of_device* of_platform_device_create(struct device_node *np, const char *bus_id, struct device *parent, diff --git a/trunk/arch/sparc64/kernel/pci_common.c b/trunk/arch/sparc64/kernel/pci_common.c index 923e0bcc3bfd..c76bfbb7da08 100644 --- a/trunk/arch/sparc64/kernel/pci_common.c +++ b/trunk/arch/sparc64/kernel/pci_common.c @@ -396,13 +396,6 @@ void pci_determine_mem_io_space(struct pci_pbm_info *pbm) saw_mem = saw_io = 0; pbm_ranges = of_get_property(pbm->prom_node, "ranges", &i); - if (!pbm_ranges) { - prom_printf("PCI: Fatal error, missing PBM ranges property " - " for %s\n", - pbm->name); - prom_halt(); - } - num_pbm_ranges = i / sizeof(*pbm_ranges); for (i = 0; i < num_pbm_ranges; i++) { diff --git a/trunk/arch/sparc64/kernel/sys_sunos32.c b/trunk/arch/sparc64/kernel/sys_sunos32.c index 170d6ca8de6f..8f7a06e2c7e7 100644 --- a/trunk/arch/sparc64/kernel/sys_sunos32.c +++ b/trunk/arch/sparc64/kernel/sys_sunos32.c @@ -831,7 +831,7 @@ asmlinkage int sunos_killpg(int pgrp, int sig) rcu_read_lock(); ret = -EINVAL; if (pgrp > 0) - ret = kill_pgrp(find_vpid(pgrp), sig, 0); + ret = kill_pgrp(find_pid(pgrp), sig, 0); rcu_read_unlock(); return ret; diff --git a/trunk/arch/sparc64/kernel/traps.c b/trunk/arch/sparc64/kernel/traps.c index e9c7e4f07abf..34573a55b6e5 100644 --- a/trunk/arch/sparc64/kernel/traps.c +++ b/trunk/arch/sparc64/kernel/traps.c @@ -2225,7 +2225,7 @@ void die_if_kernel(char *str, struct pt_regs *regs) " /_| \\__/ |_\\\n" " \\__U_/\n"); - printk("%s(%d): %s [#%d]\n", current->comm, task_pid_nr(current), str, ++die_counter); + printk("%s(%d): %s [#%d]\n", current->comm, current->pid, str, ++die_counter); notify_die(DIE_OOPS, str, regs, 0, 255, SIGSEGV); __asm__ __volatile__("flushw"); __show_regs(regs); diff --git a/trunk/arch/sparc64/lib/atomic.S b/trunk/arch/sparc64/lib/atomic.S index 70ac4186f62b..9633750167d0 100644 --- a/trunk/arch/sparc64/lib/atomic.S +++ b/trunk/arch/sparc64/lib/atomic.S @@ -1,10 +1,10 @@ -/* atomic.S: These things are too big to do inline. +/* $Id: atomic.S,v 1.4 2001/11/18 00:12:56 davem Exp $ + * atomic.S: These things are too big to do inline. * - * Copyright (C) 1999, 2007 David S. Miller (davem@davemloft.net) + * Copyright (C) 1999 David S. Miller (davem@redhat.com) */ #include -#include .text @@ -16,31 +16,27 @@ .globl atomic_add .type atomic_add,#function atomic_add: /* %o0 = increment, %o1 = atomic_ptr */ - BACKOFF_SETUP(%o2) 1: lduw [%o1], %g1 add %g1, %o0, %g7 cas [%o1], %g1, %g7 cmp %g1, %g7 - bne,pn %icc, 2f + bne,pn %icc, 1b nop retl nop -2: BACKOFF_SPIN(%o2, %o3, 1b) .size atomic_add, .-atomic_add .globl atomic_sub .type atomic_sub,#function atomic_sub: /* %o0 = decrement, %o1 = atomic_ptr */ - BACKOFF_SETUP(%o2) 1: lduw [%o1], %g1 sub %g1, %o0, %g7 cas [%o1], %g1, %g7 cmp %g1, %g7 - bne,pn %icc, 2f + bne,pn %icc, 1b nop retl nop -2: BACKOFF_SPIN(%o2, %o3, 1b) .size atomic_sub, .-atomic_sub /* On SMP we need to use memory barriers to ensure @@ -64,101 +60,89 @@ atomic_sub: /* %o0 = decrement, %o1 = atomic_ptr */ .globl atomic_add_ret .type atomic_add_ret,#function atomic_add_ret: /* %o0 = increment, %o1 = atomic_ptr */ - BACKOFF_SETUP(%o2) ATOMIC_PRE_BARRIER 1: lduw [%o1], %g1 add %g1, %o0, %g7 cas [%o1], %g1, %g7 cmp %g1, %g7 - bne,pn %icc, 2f + bne,pn %icc, 1b add %g7, %o0, %g7 sra %g7, 0, %o0 ATOMIC_POST_BARRIER retl nop -2: BACKOFF_SPIN(%o2, %o3, 1b) .size atomic_add_ret, .-atomic_add_ret .globl atomic_sub_ret .type atomic_sub_ret,#function atomic_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */ - BACKOFF_SETUP(%o2) ATOMIC_PRE_BARRIER 1: lduw [%o1], %g1 sub %g1, %o0, %g7 cas [%o1], %g1, %g7 cmp %g1, %g7 - bne,pn %icc, 2f + bne,pn %icc, 1b sub %g7, %o0, %g7 sra %g7, 0, %o0 ATOMIC_POST_BARRIER retl nop -2: BACKOFF_SPIN(%o2, %o3, 1b) .size atomic_sub_ret, .-atomic_sub_ret .globl atomic64_add .type atomic64_add,#function atomic64_add: /* %o0 = increment, %o1 = atomic_ptr */ - BACKOFF_SETUP(%o2) 1: ldx [%o1], %g1 add %g1, %o0, %g7 casx [%o1], %g1, %g7 cmp %g1, %g7 - bne,pn %xcc, 2f + bne,pn %xcc, 1b nop retl nop -2: BACKOFF_SPIN(%o2, %o3, 1b) .size atomic64_add, .-atomic64_add .globl atomic64_sub .type atomic64_sub,#function atomic64_sub: /* %o0 = decrement, %o1 = atomic_ptr */ - BACKOFF_SETUP(%o2) 1: ldx [%o1], %g1 sub %g1, %o0, %g7 casx [%o1], %g1, %g7 cmp %g1, %g7 - bne,pn %xcc, 2f + bne,pn %xcc, 1b nop retl nop -2: BACKOFF_SPIN(%o2, %o3, 1b) .size atomic64_sub, .-atomic64_sub .globl atomic64_add_ret .type atomic64_add_ret,#function atomic64_add_ret: /* %o0 = increment, %o1 = atomic_ptr */ - BACKOFF_SETUP(%o2) ATOMIC_PRE_BARRIER 1: ldx [%o1], %g1 add %g1, %o0, %g7 casx [%o1], %g1, %g7 cmp %g1, %g7 - bne,pn %xcc, 2f + bne,pn %xcc, 1b add %g7, %o0, %g7 mov %g7, %o0 ATOMIC_POST_BARRIER retl nop -2: BACKOFF_SPIN(%o2, %o3, 1b) .size atomic64_add_ret, .-atomic64_add_ret .globl atomic64_sub_ret .type atomic64_sub_ret,#function atomic64_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */ - BACKOFF_SETUP(%o2) ATOMIC_PRE_BARRIER 1: ldx [%o1], %g1 sub %g1, %o0, %g7 casx [%o1], %g1, %g7 cmp %g1, %g7 - bne,pn %xcc, 2f + bne,pn %xcc, 1b sub %g7, %o0, %g7 mov %g7, %o0 ATOMIC_POST_BARRIER retl nop -2: BACKOFF_SPIN(%o2, %o3, 1b) .size atomic64_sub_ret, .-atomic64_sub_ret diff --git a/trunk/arch/sparc64/lib/bitops.S b/trunk/arch/sparc64/lib/bitops.S index 6b015a6eefb5..892431a82131 100644 --- a/trunk/arch/sparc64/lib/bitops.S +++ b/trunk/arch/sparc64/lib/bitops.S @@ -1,10 +1,10 @@ -/* bitops.S: Sparc64 atomic bit operations. +/* $Id: bitops.S,v 1.3 2001/11/18 00:12:56 davem Exp $ + * bitops.S: Sparc64 atomic bit operations. * - * Copyright (C) 2000, 2007 David S. Miller (davem@davemloft.net) + * Copyright (C) 2000 David S. Miller (davem@redhat.com) */ #include -#include .text @@ -29,7 +29,6 @@ .globl test_and_set_bit .type test_and_set_bit,#function test_and_set_bit: /* %o0=nr, %o1=addr */ - BACKOFF_SETUP(%o3) BITOP_PRE_BARRIER srlx %o0, 6, %g1 mov 1, %o2 @@ -41,20 +40,18 @@ test_and_set_bit: /* %o0=nr, %o1=addr */ or %g7, %o2, %g1 casx [%o1], %g7, %g1 cmp %g7, %g1 - bne,pn %xcc, 2f + bne,pn %xcc, 1b and %g7, %o2, %g2 clr %o0 movrne %g2, 1, %o0 BITOP_POST_BARRIER retl nop -2: BACKOFF_SPIN(%o3, %o4, 1b) .size test_and_set_bit, .-test_and_set_bit .globl test_and_clear_bit .type test_and_clear_bit,#function test_and_clear_bit: /* %o0=nr, %o1=addr */ - BACKOFF_SETUP(%o3) BITOP_PRE_BARRIER srlx %o0, 6, %g1 mov 1, %o2 @@ -66,20 +63,18 @@ test_and_clear_bit: /* %o0=nr, %o1=addr */ andn %g7, %o2, %g1 casx [%o1], %g7, %g1 cmp %g7, %g1 - bne,pn %xcc, 2f + bne,pn %xcc, 1b and %g7, %o2, %g2 clr %o0 movrne %g2, 1, %o0 BITOP_POST_BARRIER retl nop -2: BACKOFF_SPIN(%o3, %o4, 1b) .size test_and_clear_bit, .-test_and_clear_bit .globl test_and_change_bit .type test_and_change_bit,#function test_and_change_bit: /* %o0=nr, %o1=addr */ - BACKOFF_SETUP(%o3) BITOP_PRE_BARRIER srlx %o0, 6, %g1 mov 1, %o2 @@ -91,20 +86,18 @@ test_and_change_bit: /* %o0=nr, %o1=addr */ xor %g7, %o2, %g1 casx [%o1], %g7, %g1 cmp %g7, %g1 - bne,pn %xcc, 2f + bne,pn %xcc, 1b and %g7, %o2, %g2 clr %o0 movrne %g2, 1, %o0 BITOP_POST_BARRIER retl nop -2: BACKOFF_SPIN(%o3, %o4, 1b) .size test_and_change_bit, .-test_and_change_bit .globl set_bit .type set_bit,#function set_bit: /* %o0=nr, %o1=addr */ - BACKOFF_SETUP(%o3) srlx %o0, 6, %g1 mov 1, %o2 sllx %g1, 3, %g3 @@ -115,17 +108,15 @@ set_bit: /* %o0=nr, %o1=addr */ or %g7, %o2, %g1 casx [%o1], %g7, %g1 cmp %g7, %g1 - bne,pn %xcc, 2f + bne,pn %xcc, 1b nop retl nop -2: BACKOFF_SPIN(%o3, %o4, 1b) .size set_bit, .-set_bit .globl clear_bit .type clear_bit,#function clear_bit: /* %o0=nr, %o1=addr */ - BACKOFF_SETUP(%o3) srlx %o0, 6, %g1 mov 1, %o2 sllx %g1, 3, %g3 @@ -136,17 +127,15 @@ clear_bit: /* %o0=nr, %o1=addr */ andn %g7, %o2, %g1 casx [%o1], %g7, %g1 cmp %g7, %g1 - bne,pn %xcc, 2f + bne,pn %xcc, 1b nop retl nop -2: BACKOFF_SPIN(%o3, %o4, 1b) .size clear_bit, .-clear_bit .globl change_bit .type change_bit,#function change_bit: /* %o0=nr, %o1=addr */ - BACKOFF_SETUP(%o3) srlx %o0, 6, %g1 mov 1, %o2 sllx %g1, 3, %g3 @@ -157,9 +146,8 @@ change_bit: /* %o0=nr, %o1=addr */ xor %g7, %o2, %g1 casx [%o1], %g7, %g1 cmp %g7, %g1 - bne,pn %xcc, 2f + bne,pn %xcc, 1b nop retl nop -2: BACKOFF_SPIN(%o3, %o4, 1b) .size change_bit, .-change_bit diff --git a/trunk/arch/sparc64/oprofile/Kconfig b/trunk/arch/sparc64/oprofile/Kconfig new file mode 100644 index 000000000000..d8a84088471a --- /dev/null +++ b/trunk/arch/sparc64/oprofile/Kconfig @@ -0,0 +1,17 @@ +config PROFILING + bool "Profiling support (EXPERIMENTAL)" + help + Say Y here to enable the extended profiling support mechanisms used + by profilers such as OProfile. + + +config OPROFILE + tristate "OProfile system profiling (EXPERIMENTAL)" + depends on PROFILING + help + OProfile is a profiling system capable of profiling the + whole system, include the kernel, kernel modules, libraries, + and applications. + + If unsure, say N. + diff --git a/trunk/arch/sparc64/solaris/misc.c b/trunk/arch/sparc64/solaris/misc.c index c86cb3091a8e..3b67de7455f1 100644 --- a/trunk/arch/sparc64/solaris/misc.c +++ b/trunk/arch/sparc64/solaris/misc.c @@ -415,7 +415,7 @@ asmlinkage int solaris_procids(int cmd, s32 pid, s32 pgid) switch (cmd) { case 0: /* getpgrp */ - return task_pgrp_nr(current); + return process_group(current); case 1: /* setpgrp */ { int (*sys_setpgid)(pid_t,pid_t) = @@ -426,7 +426,7 @@ asmlinkage int solaris_procids(int cmd, s32 pid, s32 pgid) ret = sys_setpgid(0, 0); if (ret) return ret; proc_clear_tty(current); - return task_pgrp_nr(current); + return process_group(current); } case 2: /* getsid */ { diff --git a/trunk/arch/um/Kconfig b/trunk/arch/um/Kconfig index d8925d285573..740d8a922e48 100644 --- a/trunk/arch/um/Kconfig +++ b/trunk/arch/um/Kconfig @@ -289,6 +289,4 @@ config INPUT bool default n -source "kernel/Kconfig.instrumentation" - source "arch/um/Kconfig.debug" diff --git a/trunk/arch/um/drivers/slip_kern.c b/trunk/arch/um/drivers/slip_kern.c index 6b4a0f9e38de..ae67e7158e71 100644 --- a/trunk/arch/um/drivers/slip_kern.c +++ b/trunk/arch/um/drivers/slip_kern.c @@ -31,8 +31,10 @@ void slip_init(struct net_device *dev, void *data) slip_proto_init(&spri->slip); dev->init = NULL; + dev->header_cache_update = NULL; + dev->hard_header_cache = NULL; + dev->hard_header = NULL; dev->hard_header_len = 0; - dev->header_ops = NULL; dev->addr_len = 0; dev->type = ARPHRD_SLIP; dev->tx_queue_len = 256; diff --git a/trunk/arch/um/drivers/slirp_kern.c b/trunk/arch/um/drivers/slirp_kern.c index d987af277db9..240ee650865d 100644 --- a/trunk/arch/um/drivers/slirp_kern.c +++ b/trunk/arch/um/drivers/slirp_kern.c @@ -34,7 +34,9 @@ void slirp_init(struct net_device *dev, void *data) dev->init = NULL; dev->hard_header_len = 0; - dev->header_ops = NULL; + dev->header_cache_update = NULL; + dev->hard_header_cache = NULL; + dev->hard_header = NULL; dev->addr_len = 0; dev->type = ARPHRD_SLIP; dev->tx_queue_len = 256; diff --git a/trunk/arch/um/kernel/trap.c b/trunk/arch/um/kernel/trap.c index cb3321f8e0a9..bd060551e619 100644 --- a/trunk/arch/um/kernel/trap.c +++ b/trunk/arch/um/kernel/trap.c @@ -108,7 +108,7 @@ int handle_page_fault(unsigned long address, unsigned long ip, * us unable to handle the page fault gracefully. */ out_of_memory: - if (is_global_init(current)) { + if (is_init(current)) { up_read(&mm->mmap_sem); yield(); down_read(&mm->mmap_sem); diff --git a/trunk/arch/um/sys-x86_64/sysrq.c b/trunk/arch/um/sys-x86_64/sysrq.c index 765444031819..ce3e07fcf283 100644 --- a/trunk/arch/um/sys-x86_64/sysrq.c +++ b/trunk/arch/um/sys-x86_64/sysrq.c @@ -15,8 +15,8 @@ void __show_regs(struct pt_regs * regs) { printk("\n"); print_modules(); - printk("Pid: %d, comm: %.20s %s %s\n", task_pid_nr(current), - current->comm, print_tainted(), init_utsname()->release); + printk("Pid: %d, comm: %.20s %s %s\n", + current->pid, current->comm, print_tainted(), init_utsname()->release); printk("RIP: %04lx:[<%016lx>] ", PT_REGS_CS(regs) & 0xffff, PT_REGS_RIP(regs)); printk("\nRSP: %016lx EFLAGS: %08lx\n", PT_REGS_RSP(regs), diff --git a/trunk/arch/v850/Kconfig b/trunk/arch/v850/Kconfig index b6a50b8b38de..ace479ab273f 100644 --- a/trunk/arch/v850/Kconfig +++ b/trunk/arch/v850/Kconfig @@ -331,8 +331,6 @@ source "sound/Kconfig" source "drivers/usb/Kconfig" -source "kernel/Kconfig.instrumentation" - source "arch/v850/Kconfig.debug" source "security/Kconfig" diff --git a/trunk/arch/x86/ia32/ia32_binfmt.c b/trunk/arch/x86/ia32/ia32_binfmt.c index 5027650eb273..118b9f9ff499 100644 --- a/trunk/arch/x86/ia32/ia32_binfmt.c +++ b/trunk/arch/x86/ia32/ia32_binfmt.c @@ -289,6 +289,7 @@ static void elf32_init(struct pt_regs *regs) static ctl_table abi_table2[] = { { + .ctl_name = 99, .procname = "vsyscall32", .data = &sysctl_vsyscall32, .maxlen = sizeof(int), diff --git a/trunk/arch/x86/kernel/acpi/wakeup_32.S b/trunk/arch/x86/kernel/acpi/wakeup_32.S index a97313b1270e..f22ba8534d26 100644 --- a/trunk/arch/x86/kernel/acpi/wakeup_32.S +++ b/trunk/arch/x86/kernel/acpi/wakeup_32.S @@ -11,7 +11,7 @@ # # If physical address of wakeup_code is 0x12345, BIOS should call us with # cs = 0x1234, eip = 0x05 -# +# #define BEEP \ inb $97, %al; \ @@ -52,6 +52,7 @@ wakeup_code: BEEP 1: mov $(wakeup_stack - wakeup_code), %sp # Private stack is needed for ASUS board + movw $0x0e00 + 'S', %fs:(0x12) pushl $0 # Kill any dangerous flags popfl @@ -89,6 +90,9 @@ wakeup_code: # make sure %cr4 is set correctly (features, etc) movl real_save_cr4 - wakeup_code, %eax movl %eax, %cr4 + movw $0xb800, %ax + movw %ax,%fs + movw $0x0e00 + 'i', %fs:(0x12) # need a gdt -- use lgdtl to force 32-bit operands, in case # the GDT is located past 16 megabytes. @@ -98,6 +102,8 @@ wakeup_code: movl %eax, %cr0 jmp 1f 1: + movw $0x0e00 + 'n', %fs:(0x14) + movl real_magic - wakeup_code, %eax cmpl $0x12345678, %eax jne bogus_real_magic @@ -116,11 +122,13 @@ real_save_cr4: .long 0 real_magic: .long 0 video_mode: .long 0 realmode_flags: .long 0 +beep_flags: .long 0 real_efer_save_restore: .long 0 real_save_efer_edx: .long 0 real_save_efer_eax: .long 0 bogus_real_magic: + movw $0x0e00 + 'B', %fs:(0x12) jmp bogus_real_magic /* This code uses an extended set of video mode numbers. These include: @@ -186,6 +194,7 @@ wakeup_pmode_return: movw %ax, %es movw %ax, %fs movw %ax, %gs + movw $0x0e00 + 'u', 0xb8016 # reload the gdt, as we need the full 32 bit address lgdt saved_gdt @@ -209,6 +218,7 @@ wakeup_pmode_return: jmp *%eax bogus_magic: + movw $0x0e00 + 'B', 0xb8018 jmp bogus_magic diff --git a/trunk/arch/x86/kernel/acpi/wakeup_64.S b/trunk/arch/x86/kernel/acpi/wakeup_64.S index 55608ec2ed72..8b4357e1efe0 100644 --- a/trunk/arch/x86/kernel/acpi/wakeup_64.S +++ b/trunk/arch/x86/kernel/acpi/wakeup_64.S @@ -41,6 +41,7 @@ wakeup_code: # Running in *copy* of this code, somewhere in low 1MB. + movb $0xa1, %al ; outb %al, $0x80 cli cld # setup data segment @@ -64,6 +65,11 @@ wakeup_code: cmpl $0x12345678, %eax jne bogus_real_magic + call verify_cpu # Verify the cpu supports long + # mode + testl %eax, %eax + jnz no_longmode + testl $1, realmode_flags - wakeup_code jz 1f lcall $0xc000,$3 @@ -78,6 +84,12 @@ wakeup_code: call mode_set 1: + movw $0xb800, %ax + movw %ax,%fs + movw $0x0e00 + 'L', %fs:(0x10) + + movb $0xa2, %al ; outb %al, $0x80 + mov %ds, %ax # Find 32bit wakeup_code addr movzx %ax, %esi # (Convert %ds:gdt to a liner ptr) shll $4, %esi @@ -105,10 +117,14 @@ wakeup_32_vector: .code32 wakeup_32: # Running in this code, but at low address; paging is not yet turned on. + movb $0xa5, %al ; outb %al, $0x80 movl $__KERNEL_DS, %eax movl %eax, %ds + movw $0x0e00 + 'i', %ds:(0xb8012) + movb $0xa8, %al ; outb %al, $0x80; + /* * Prepare for entering 64bits mode */ @@ -184,11 +200,16 @@ wakeup_long64: */ lgdt cpu_gdt_descr + movw $0x0e00 + 'n', %ds:(0xb8014) + movb $0xa9, %al ; outb %al, $0x80 + movq saved_magic, %rax movq $0x123456789abcdef0, %rdx cmpq %rdx, %rax jne bogus_64_magic + movw $0x0e00 + 'u', %ds:(0xb8016) + nop nop movw $__KERNEL_DS, %ax @@ -199,11 +220,13 @@ wakeup_long64: movw %ax, %gs movq saved_rsp, %rsp + movw $0x0e00 + 'x', %ds:(0xb8018) movq saved_rbx, %rbx movq saved_rdi, %rdi movq saved_rsi, %rsi movq saved_rbp, %rbp + movw $0x0e00 + '!', %ds:(0xb801a) movq saved_rip, %rax jmp *%rax @@ -233,12 +256,21 @@ realmode_flags: .quad 0 .code16 bogus_real_magic: + movb $0xba,%al ; outb %al,$0x80 jmp bogus_real_magic .code64 bogus_64_magic: + movb $0xb3,%al ; outb %al,$0x80 jmp bogus_64_magic +.code16 +no_longmode: + movb $0xbc,%al ; outb %al,$0x80 + jmp no_longmode + +#include "../verify_cpu_64.S" + /* This code uses an extended set of video mode numbers. These include: * Aliases for standard modes * NORMAL_VGA (-1) diff --git a/trunk/arch/x86/kernel/cpu/intel_cacheinfo.c b/trunk/arch/x86/kernel/cpu/intel_cacheinfo.c index 297a24116949..1826395ebeeb 100644 --- a/trunk/arch/x86/kernel/cpu/intel_cacheinfo.c +++ b/trunk/arch/x86/kernel/cpu/intel_cacheinfo.c @@ -499,11 +499,6 @@ static void __cpuinit cache_remove_shared_cpu_map(unsigned int cpu, int index) { static void free_cache_attributes(unsigned int cpu) { - int i; - - for (i = 0; i < num_cache_leaves; i++) - cache_remove_shared_cpu_map(cpu, i); - kfree(cpuid4_info[cpu]); cpuid4_info[cpu] = NULL; } @@ -511,8 +506,8 @@ static void free_cache_attributes(unsigned int cpu) static int __cpuinit detect_cache_attributes(unsigned int cpu) { struct _cpuid4_info *this_leaf; - unsigned long j; - int retval; + unsigned long j; + int retval; cpumask_t oldmask; if (num_cache_leaves == 0) @@ -529,26 +524,19 @@ static int __cpuinit detect_cache_attributes(unsigned int cpu) goto out; /* Do cpuid and store the results */ + retval = 0; for (j = 0; j < num_cache_leaves; j++) { this_leaf = CPUID4_INFO_IDX(cpu, j); retval = cpuid4_cache_lookup(j, this_leaf); - if (unlikely(retval < 0)) { - int i; - - for (i = 0; i < j; i++) - cache_remove_shared_cpu_map(cpu, i); + if (unlikely(retval < 0)) break; - } cache_shared_cpu_map_setup(cpu, j); } set_cpus_allowed(current, oldmask); out: - if (retval) { - kfree(cpuid4_info[cpu]); - cpuid4_info[cpu] = NULL; - } - + if (retval) + free_cache_attributes(cpu); return retval; } @@ -681,7 +669,7 @@ static struct kobj_type ktype_percpu_entry = { .sysfs_ops = &sysfs_ops, }; -static void __cpuinit cpuid4_cache_sysfs_exit(unsigned int cpu) +static void cpuid4_cache_sysfs_exit(unsigned int cpu) { kfree(cache_kobject[cpu]); kfree(index_kobject[cpu]); @@ -692,14 +680,13 @@ static void __cpuinit cpuid4_cache_sysfs_exit(unsigned int cpu) static int __cpuinit cpuid4_cache_sysfs_init(unsigned int cpu) { - int err; if (num_cache_leaves == 0) return -ENOENT; - err = detect_cache_attributes(cpu); - if (err) - return err; + detect_cache_attributes(cpu); + if (cpuid4_info[cpu] == NULL) + return -ENOENT; /* Allocate all required memory */ cache_kobject[cpu] = kzalloc(sizeof(struct kobject), GFP_KERNEL); @@ -718,15 +705,13 @@ static int __cpuinit cpuid4_cache_sysfs_init(unsigned int cpu) return -ENOMEM; } -static cpumask_t cache_dev_map = CPU_MASK_NONE; - /* Add/Remove cache interface for CPU device */ static int __cpuinit cache_add_dev(struct sys_device * sys_dev) { unsigned int cpu = sys_dev->id; unsigned long i, j; struct _index_kobject *this_object; - int retval; + int retval = 0; retval = cpuid4_cache_sysfs_init(cpu); if (unlikely(retval < 0)) @@ -736,10 +721,6 @@ static int __cpuinit cache_add_dev(struct sys_device * sys_dev) kobject_set_name(cache_kobject[cpu], "%s", "cache"); cache_kobject[cpu]->ktype = &ktype_percpu_entry; retval = kobject_register(cache_kobject[cpu]); - if (retval < 0) { - cpuid4_cache_sysfs_exit(cpu); - return retval; - } for (i = 0; i < num_cache_leaves; i++) { this_object = INDEX_KOBJECT_PTR(cpu,i); @@ -759,9 +740,6 @@ static int __cpuinit cache_add_dev(struct sys_device * sys_dev) break; } } - if (!retval) - cpu_set(cpu, cache_dev_map); - return retval; } @@ -772,14 +750,13 @@ static void __cpuinit cache_remove_dev(struct sys_device * sys_dev) if (cpuid4_info[cpu] == NULL) return; - if (!cpu_isset(cpu, cache_dev_map)) - return; - cpu_clear(cpu, cache_dev_map); - - for (i = 0; i < num_cache_leaves; i++) + for (i = 0; i < num_cache_leaves; i++) { + cache_remove_shared_cpu_map(cpu, i); kobject_unregister(&(INDEX_KOBJECT_PTR(cpu,i)->kobj)); + } kobject_unregister(cache_kobject[cpu]); cpuid4_cache_sysfs_exit(cpu); + return; } static int __cpuinit cacheinfo_cpu_callback(struct notifier_block *nfb, @@ -804,7 +781,7 @@ static int __cpuinit cacheinfo_cpu_callback(struct notifier_block *nfb, static struct notifier_block __cpuinitdata cacheinfo_cpu_notifier = { - .notifier_call = cacheinfo_cpu_callback, + .notifier_call = cacheinfo_cpu_callback, }; static int __cpuinit cache_sysfs_init(void) @@ -814,15 +791,14 @@ static int __cpuinit cache_sysfs_init(void) if (num_cache_leaves == 0) return 0; + register_hotcpu_notifier(&cacheinfo_cpu_notifier); + for_each_online_cpu(i) { - int err; - struct sys_device *sys_dev = get_cpu_sysdev(i); + struct sys_device *sys_dev = get_cpu_sysdev((unsigned int)i); - err = cache_add_dev(sys_dev); - if (err) - return err; + cache_add_dev(sys_dev); } - register_hotcpu_notifier(&cacheinfo_cpu_notifier); + return 0; } diff --git a/trunk/arch/x86/kernel/cpu/mcheck/therm_throt.c b/trunk/arch/x86/kernel/cpu/mcheck/therm_throt.c index 24885be5c48c..494d320d909b 100644 --- a/trunk/arch/x86/kernel/cpu/mcheck/therm_throt.c +++ b/trunk/arch/x86/kernel/cpu/mcheck/therm_throt.c @@ -131,19 +131,17 @@ static __cpuinit int thermal_throttle_cpu_callback(struct notifier_block *nfb, { unsigned int cpu = (unsigned long)hcpu; struct sys_device *sys_dev; - int err = 0; + int err; sys_dev = get_cpu_sysdev(cpu); switch (action) { - case CPU_UP_PREPARE: - case CPU_UP_PREPARE_FROZEN: + case CPU_ONLINE: + case CPU_ONLINE_FROZEN: mutex_lock(&therm_cpu_lock); err = thermal_throttle_add_dev(sys_dev); mutex_unlock(&therm_cpu_lock); WARN_ON(err); break; - case CPU_UP_CANCELED: - case CPU_UP_CANCELED_FROZEN: case CPU_DEAD: case CPU_DEAD_FROZEN: mutex_lock(&therm_cpu_lock); @@ -151,7 +149,7 @@ static __cpuinit int thermal_throttle_cpu_callback(struct notifier_block *nfb, mutex_unlock(&therm_cpu_lock); break; } - return err ? NOTIFY_BAD : NOTIFY_OK; + return NOTIFY_OK; } static struct notifier_block thermal_throttle_cpu_notifier __cpuinitdata = diff --git a/trunk/arch/x86/kernel/crash_dump_32.c b/trunk/arch/x86/kernel/crash_dump_32.c index 72d0c56c1b48..32e75d0731a9 100644 --- a/trunk/arch/x86/kernel/crash_dump_32.c +++ b/trunk/arch/x86/kernel/crash_dump_32.c @@ -47,7 +47,6 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf, if (!kdump_buf_page) { printk(KERN_WARNING "Kdump: Kdump buffer page not" " allocated\n"); - kunmap_atomic(vaddr, KM_PTE0); return -EFAULT; } copy_page(kdump_buf_page, vaddr); diff --git a/trunk/arch/x86/kernel/e820_32.c b/trunk/arch/x86/kernel/e820_32.c index d58039e8de74..3c86b979a40a 100644 --- a/trunk/arch/x86/kernel/e820_32.c +++ b/trunk/arch/x86/kernel/e820_32.c @@ -288,8 +288,7 @@ legacy_init_iomem_resources(struct resource *code_resource, struct resource *dat request_resource(res, code_resource); request_resource(res, data_resource); #ifdef CONFIG_KEXEC - if (crashk_res.start != crashk_res.end) - request_resource(res, &crashk_res); + request_resource(res, &crashk_res); #endif } } diff --git a/trunk/arch/x86/kernel/e820_64.c b/trunk/arch/x86/kernel/e820_64.c index 57616865d8a0..e422b8159f69 100644 --- a/trunk/arch/x86/kernel/e820_64.c +++ b/trunk/arch/x86/kernel/e820_64.c @@ -226,8 +226,7 @@ void __init e820_reserve_resources(void) request_resource(res, &code_resource); request_resource(res, &data_resource); #ifdef CONFIG_KEXEC - if (crashk_res.start != crashk_res.end) - request_resource(res, &crashk_res); + request_resource(res, &crashk_res); #endif } } diff --git a/trunk/arch/x86/kernel/machine_kexec_32.c b/trunk/arch/x86/kernel/machine_kexec_32.c index 11b935f4f886..8459ca64bc2f 100644 --- a/trunk/arch/x86/kernel/machine_kexec_32.c +++ b/trunk/arch/x86/kernel/machine_kexec_32.c @@ -149,6 +149,28 @@ NORET_TYPE void machine_kexec(struct kimage *image) image->start, cpu_has_pae); } +/* crashkernel=size@addr specifies the location to reserve for + * a crash kernel. By reserving this memory we guarantee + * that linux never sets it up as a DMA target. + * Useful for holding code to do something appropriate + * after a kernel panic. + */ +static int __init parse_crashkernel(char *arg) +{ + unsigned long size, base; + size = memparse(arg, &arg); + if (*arg == '@') { + base = memparse(arg+1, &arg); + /* FIXME: Do I want a sanity check + * to validate the memory range? + */ + crashk_res.start = base; + crashk_res.end = base + size - 1; + } + return 0; +} +early_param("crashkernel", parse_crashkernel); + void arch_crash_save_vmcoreinfo(void) { #ifdef CONFIG_ARCH_DISCONTIGMEM_ENABLE diff --git a/trunk/arch/x86/kernel/machine_kexec_64.c b/trunk/arch/x86/kernel/machine_kexec_64.c index 0d8577f05422..7450b69710b5 100644 --- a/trunk/arch/x86/kernel/machine_kexec_64.c +++ b/trunk/arch/x86/kernel/machine_kexec_64.c @@ -231,6 +231,33 @@ NORET_TYPE void machine_kexec(struct kimage *image) image->start); } +/* crashkernel=size@addr specifies the location to reserve for + * a crash kernel. By reserving this memory we guarantee + * that linux never set's it up as a DMA target. + * Useful for holding code to do something appropriate + * after a kernel panic. + */ +static int __init setup_crashkernel(char *arg) +{ + unsigned long size, base; + char *p; + if (!arg) + return -EINVAL; + size = memparse(arg, &p); + if (arg == p) + return -EINVAL; + if (*p == '@') { + base = memparse(p+1, &p); + /* FIXME: Do I want a sanity check to validate the + * memory range? Yes you do, but it's too early for + * e820 -AK */ + crashk_res.start = base; + crashk_res.end = base + size - 1; + } + return 0; +} +early_param("crashkernel", setup_crashkernel); + void arch_crash_save_vmcoreinfo(void) { #ifdef CONFIG_ARCH_DISCONTIGMEM_ENABLE diff --git a/trunk/arch/x86/kernel/mce_64.c b/trunk/arch/x86/kernel/mce_64.c index 66e6b797b2cb..8ca8f8648969 100644 --- a/trunk/arch/x86/kernel/mce_64.c +++ b/trunk/arch/x86/kernel/mce_64.c @@ -802,29 +802,16 @@ static __cpuinit int mce_create_device(unsigned int cpu) if (!mce_available(&cpu_data[cpu])) return -EIO; - memset(&per_cpu(device_mce, cpu).kobj, 0, sizeof(struct kobject)); per_cpu(device_mce,cpu).id = cpu; per_cpu(device_mce,cpu).cls = &mce_sysclass; err = sysdev_register(&per_cpu(device_mce,cpu)); - if (err) - return err; - - for (i = 0; mce_attributes[i]; i++) { - err = sysdev_create_file(&per_cpu(device_mce,cpu), - mce_attributes[i]); - if (err) - goto error; - } - return 0; -error: - while (i--) { - sysdev_remove_file(&per_cpu(device_mce,cpu), - mce_attributes[i]); + if (!err) { + for (i = 0; mce_attributes[i]; i++) + sysdev_create_file(&per_cpu(device_mce,cpu), + mce_attributes[i]); } - sysdev_unregister(&per_cpu(device_mce,cpu)); - return err; } @@ -836,6 +823,7 @@ static void mce_remove_device(unsigned int cpu) sysdev_remove_file(&per_cpu(device_mce,cpu), mce_attributes[i]); sysdev_unregister(&per_cpu(device_mce,cpu)); + memset(&per_cpu(device_mce, cpu).kobj, 0, sizeof(struct kobject)); } /* Get notified when a cpu comes on/off. Be hotplug friendly. */ @@ -843,21 +831,18 @@ static int mce_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { unsigned int cpu = (unsigned long)hcpu; - int err = 0; switch (action) { - case CPU_UP_PREPARE: - case CPU_UP_PREPARE_FROZEN: - err = mce_create_device(cpu); + case CPU_ONLINE: + case CPU_ONLINE_FROZEN: + mce_create_device(cpu); break; - case CPU_UP_CANCELED: - case CPU_UP_CANCELED_FROZEN: case CPU_DEAD: case CPU_DEAD_FROZEN: mce_remove_device(cpu); break; } - return err ? NOTIFY_BAD : NOTIFY_OK; + return NOTIFY_OK; } static struct notifier_block mce_cpu_notifier = { @@ -872,13 +857,9 @@ static __init int mce_init_device(void) if (!mce_available(&boot_cpu_data)) return -EIO; err = sysdev_class_register(&mce_sysclass); - if (err) - return err; for_each_online_cpu(i) { - err = mce_create_device(i); - if (err) - return err; + mce_create_device(i); } register_hotcpu_notifier(&mce_cpu_notifier); diff --git a/trunk/arch/x86/kernel/msr.c b/trunk/arch/x86/kernel/msr.c index e18e516cf549..df85c9c13601 100644 --- a/trunk/arch/x86/kernel/msr.c +++ b/trunk/arch/x86/kernel/msr.c @@ -133,42 +133,37 @@ static const struct file_operations msr_fops = { .open = msr_open, }; -static int __cpuinit msr_device_create(int cpu) +static int __cpuinit msr_device_create(int i) { + int err = 0; struct device *dev; - dev = device_create(msr_class, NULL, MKDEV(MSR_MAJOR, cpu), - "msr%d", cpu); - return IS_ERR(dev) ? PTR_ERR(dev) : 0; -} - -static void msr_device_destroy(int cpu) -{ - device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu)); + dev = device_create(msr_class, NULL, MKDEV(MSR_MAJOR, i), "msr%d",i); + if (IS_ERR(dev)) + err = PTR_ERR(dev); + return err; } static int __cpuinit msr_class_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { unsigned int cpu = (unsigned long)hcpu; - int err = 0; switch (action) { - case CPU_UP_PREPARE: - case CPU_UP_PREPARE_FROZEN: - err = msr_device_create(cpu); + case CPU_ONLINE: + case CPU_ONLINE_FROZEN: + msr_device_create(cpu); break; - case CPU_UP_CANCELED: - case CPU_UP_CANCELED_FROZEN: case CPU_DEAD: case CPU_DEAD_FROZEN: - msr_device_destroy(cpu); + device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu)); break; } - return err ? NOTIFY_BAD : NOTIFY_OK; + return NOTIFY_OK; } -static struct notifier_block __cpuinitdata msr_class_cpu_notifier = { +static struct notifier_block __cpuinitdata msr_class_cpu_notifier = +{ .notifier_call = msr_class_cpu_callback, }; @@ -201,7 +196,7 @@ static int __init msr_init(void) out_class: i = 0; for_each_online_cpu(i) - msr_device_destroy(i); + device_destroy(msr_class, MKDEV(MSR_MAJOR, i)); class_destroy(msr_class); out_chrdev: unregister_chrdev(MSR_MAJOR, "cpu/msr"); @@ -213,7 +208,7 @@ static void __exit msr_exit(void) { int cpu = 0; for_each_online_cpu(cpu) - msr_device_destroy(cpu); + device_destroy(msr_class, MKDEV(MSR_MAJOR, cpu)); class_destroy(msr_class); unregister_chrdev(MSR_MAJOR, "cpu/msr"); unregister_hotcpu_notifier(&msr_class_cpu_notifier); diff --git a/trunk/arch/x86/kernel/process_32.c b/trunk/arch/x86/kernel/process_32.c index 044a47745a5c..097aeafce5ff 100644 --- a/trunk/arch/x86/kernel/process_32.c +++ b/trunk/arch/x86/kernel/process_32.c @@ -301,7 +301,7 @@ void show_regs(struct pt_regs * regs) unsigned long d0, d1, d2, d3, d6, d7; printk("\n"); - printk("Pid: %d, comm: %20s\n", task_pid_nr(current), current->comm); + printk("Pid: %d, comm: %20s\n", current->pid, current->comm); printk("EIP: %04x:[<%08lx>] CPU: %d\n",0xffff & regs->xcs,regs->eip, smp_processor_id()); print_symbol("EIP is at %s\n", regs->eip); diff --git a/trunk/arch/x86/kernel/setup_32.c b/trunk/arch/x86/kernel/setup_32.c index 978dc0196a0f..b87a6fd5ba48 100644 --- a/trunk/arch/x86/kernel/setup_32.c +++ b/trunk/arch/x86/kernel/setup_32.c @@ -378,49 +378,6 @@ extern unsigned long __init setup_memory(void); extern void zone_sizes_init(void); #endif /* !CONFIG_NEED_MULTIPLE_NODES */ -static inline unsigned long long get_total_mem(void) -{ - unsigned long long total; - - total = max_low_pfn - min_low_pfn; -#ifdef CONFIG_HIGHMEM - total += highend_pfn - highstart_pfn; -#endif - - return total << PAGE_SHIFT; -} - -#ifdef CONFIG_KEXEC -static void __init reserve_crashkernel(void) -{ - unsigned long long total_mem; - unsigned long long crash_size, crash_base; - int ret; - - total_mem = get_total_mem(); - - ret = parse_crashkernel(boot_command_line, total_mem, - &crash_size, &crash_base); - if (ret == 0 && crash_size > 0) { - if (crash_base > 0) { - printk(KERN_INFO "Reserving %ldMB of memory at %ldMB " - "for crashkernel (System RAM: %ldMB)\n", - (unsigned long)(crash_size >> 20), - (unsigned long)(crash_base >> 20), - (unsigned long)(total_mem >> 20)); - crashk_res.start = crash_base; - crashk_res.end = crash_base + crash_size - 1; - reserve_bootmem(crash_base, crash_size); - } else - printk(KERN_INFO "crashkernel reservation failed - " - "you have to specify a base address\n"); - } -} -#else -static inline void __init reserve_crashkernel(void) -{} -#endif - void __init setup_bootmem_allocator(void) { unsigned long bootmap_size; @@ -496,7 +453,11 @@ void __init setup_bootmem_allocator(void) } } #endif - reserve_crashkernel(); +#ifdef CONFIG_KEXEC + if (crashk_res.start != crashk_res.end) + reserve_bootmem(crashk_res.start, + crashk_res.end - crashk_res.start + 1); +#endif } /* diff --git a/trunk/arch/x86/kernel/setup_64.c b/trunk/arch/x86/kernel/setup_64.c index cdcba6975226..5a19f0cc5b67 100644 --- a/trunk/arch/x86/kernel/setup_64.c +++ b/trunk/arch/x86/kernel/setup_64.c @@ -191,37 +191,6 @@ static inline void copy_edd(void) } #endif -#ifdef CONFIG_KEXEC -static void __init reserve_crashkernel(void) -{ - unsigned long long free_mem; - unsigned long long crash_size, crash_base; - int ret; - - free_mem = ((unsigned long long)max_low_pfn - min_low_pfn) << PAGE_SHIFT; - - ret = parse_crashkernel(boot_command_line, free_mem, - &crash_size, &crash_base); - if (ret == 0 && crash_size) { - if (crash_base > 0) { - printk(KERN_INFO "Reserving %ldMB of memory at %ldMB " - "for crashkernel (System RAM: %ldMB)\n", - (unsigned long)(crash_size >> 20), - (unsigned long)(crash_base >> 20), - (unsigned long)(free_mem >> 20)); - crashk_res.start = crash_base; - crashk_res.end = crash_base + crash_size - 1; - reserve_bootmem(crash_base, crash_size); - } else - printk(KERN_INFO "crashkernel reservation failed - " - "you have to specify a base address\n"); - } -} -#else -static inline void __init reserve_crashkernel(void) -{} -#endif - #define EBDA_ADDR_POINTER 0x40E unsigned __initdata ebda_addr; @@ -388,7 +357,13 @@ void __init setup_arch(char **cmdline_p) } } #endif - reserve_crashkernel(); +#ifdef CONFIG_KEXEC + if (crashk_res.start != crashk_res.end) { + reserve_bootmem_generic(crashk_res.start, + crashk_res.end - crashk_res.start + 1); + } +#endif + paging_init(); #ifdef CONFIG_PCI diff --git a/trunk/arch/x86/kernel/signal_32.c b/trunk/arch/x86/kernel/signal_32.c index 6dc394b87255..0d79df3c5631 100644 --- a/trunk/arch/x86/kernel/signal_32.c +++ b/trunk/arch/x86/kernel/signal_32.c @@ -200,8 +200,8 @@ asmlinkage int sys_sigreturn(unsigned long __unused) if (show_unhandled_signals && printk_ratelimit()) printk("%s%s[%d] bad frame in sigreturn frame:%p eip:%lx" " esp:%lx oeax:%lx\n", - task_pid_nr(current) > 1 ? KERN_INFO : KERN_EMERG, - current->comm, task_pid_nr(current), frame, regs->eip, + current->pid > 1 ? KERN_INFO : KERN_EMERG, + current->comm, current->pid, frame, regs->eip, regs->esp, regs->orig_eax); force_sig(SIGSEGV, current); diff --git a/trunk/arch/x86/kernel/suspend_64.c b/trunk/arch/x86/kernel/suspend_64.c index f8fafe527ff1..573c0a6e0ac6 100644 --- a/trunk/arch/x86/kernel/suspend_64.c +++ b/trunk/arch/x86/kernel/suspend_64.c @@ -150,22 +150,8 @@ void fix_processor_context(void) /* Defined in arch/x86_64/kernel/suspend_asm.S */ extern int restore_image(void); -/* - * Address to jump to in the last phase of restore in order to get to the image - * kernel's text (this value is passed in the image header). - */ -unsigned long restore_jump_address; - -/* - * Value of the cr3 register from before the hibernation (this value is passed - * in the image header). - */ -unsigned long restore_cr3; - pgd_t *temp_level4_pgt; -void *relocated_restore_code; - static int res_phys_pud_init(pud_t *pud, unsigned long address, unsigned long end) { long i, j; @@ -189,7 +175,7 @@ static int res_phys_pud_init(pud_t *pud, unsigned long address, unsigned long en if (paddr >= end) break; - pe = __PAGE_KERNEL_LARGE_EXEC | paddr; + pe = _PAGE_NX | _PAGE_PSE | _KERNPG_TABLE | paddr; pe &= __supported_pte_mask; set_pmd(pmd, __pmd(pe)); } @@ -197,42 +183,25 @@ static int res_phys_pud_init(pud_t *pud, unsigned long address, unsigned long en return 0; } -static int res_kernel_text_pud_init(pud_t *pud, unsigned long start) -{ - pmd_t *pmd; - unsigned long paddr; - - pmd = (pmd_t *)get_safe_page(GFP_ATOMIC); - if (!pmd) - return -ENOMEM; - set_pud(pud + pud_index(start), __pud(__pa(pmd) | _KERNPG_TABLE)); - for (paddr = 0; paddr < KERNEL_TEXT_SIZE; pmd++, paddr += PMD_SIZE) { - unsigned long pe; - - pe = __PAGE_KERNEL_LARGE_EXEC | _PAGE_GLOBAL | paddr; - pe &= __supported_pte_mask; - set_pmd(pmd, __pmd(pe)); - } - - return 0; -} - static int set_up_temporary_mappings(void) { unsigned long start, end, next; - pud_t *pud; int error; temp_level4_pgt = (pgd_t *)get_safe_page(GFP_ATOMIC); if (!temp_level4_pgt) return -ENOMEM; + /* It is safe to reuse the original kernel mapping */ + set_pgd(temp_level4_pgt + pgd_index(__START_KERNEL_map), + init_level4_pgt[pgd_index(__START_KERNEL_map)]); + /* Set up the direct mapping from scratch */ start = (unsigned long)pfn_to_kaddr(0); end = (unsigned long)pfn_to_kaddr(end_pfn); for (; start < end; start = next) { - pud = (pud_t *)get_safe_page(GFP_ATOMIC); + pud_t *pud = (pud_t *)get_safe_page(GFP_ATOMIC); if (!pud) return -ENOMEM; next = start + PGDIR_SIZE; @@ -243,17 +212,7 @@ static int set_up_temporary_mappings(void) set_pgd(temp_level4_pgt + pgd_index(start), mk_kernel_pgd(__pa(pud))); } - - /* Set up the kernel text mapping from scratch */ - pud = (pud_t *)get_safe_page(GFP_ATOMIC); - if (!pud) - return -ENOMEM; - error = res_kernel_text_pud_init(pud, __START_KERNEL_map); - if (!error) - set_pgd(temp_level4_pgt + pgd_index(__START_KERNEL_map), - __pgd(__pa(pud) | _PAGE_TABLE)); - - return error; + return 0; } int swsusp_arch_resume(void) @@ -263,13 +222,6 @@ int swsusp_arch_resume(void) /* We have got enough memory and from now on we cannot recover */ if ((error = set_up_temporary_mappings())) return error; - - relocated_restore_code = (void *)get_safe_page(GFP_ATOMIC); - if (!relocated_restore_code) - return -ENOMEM; - memcpy(relocated_restore_code, &core_restore_code, - &restore_registers - &core_restore_code); - restore_image(); return 0; } @@ -284,43 +236,4 @@ int pfn_is_nosave(unsigned long pfn) unsigned long nosave_end_pfn = PAGE_ALIGN(__pa_symbol(&__nosave_end)) >> PAGE_SHIFT; return (pfn >= nosave_begin_pfn) && (pfn < nosave_end_pfn); } - -struct restore_data_record { - unsigned long jump_address; - unsigned long cr3; - unsigned long magic; -}; - -#define RESTORE_MAGIC 0x0123456789ABCDEFUL - -/** - * arch_hibernation_header_save - populate the architecture specific part - * of a hibernation image header - * @addr: address to save the data at - */ -int arch_hibernation_header_save(void *addr, unsigned int max_size) -{ - struct restore_data_record *rdr = addr; - - if (max_size < sizeof(struct restore_data_record)) - return -EOVERFLOW; - rdr->jump_address = restore_jump_address; - rdr->cr3 = restore_cr3; - rdr->magic = RESTORE_MAGIC; - return 0; -} - -/** - * arch_hibernation_header_restore - read the architecture specific data - * from the hibernation image header - * @addr: address to read the data from - */ -int arch_hibernation_header_restore(void *addr) -{ - struct restore_data_record *rdr = addr; - - restore_jump_address = rdr->jump_address; - restore_cr3 = rdr->cr3; - return (rdr->magic == RESTORE_MAGIC) ? 0 : -EINVAL; -} #endif /* CONFIG_HIBERNATION */ diff --git a/trunk/arch/x86/kernel/suspend_asm_64.S b/trunk/arch/x86/kernel/suspend_asm_64.S index 48344b666d2c..16d183f67bc1 100644 --- a/trunk/arch/x86/kernel/suspend_asm_64.S +++ b/trunk/arch/x86/kernel/suspend_asm_64.S @@ -2,8 +2,8 @@ * * Distribute under GPLv2. * - * swsusp_arch_resume must not use any stack or any nonlocal variables while - * copying pages: + * swsusp_arch_resume may not use any stack, nor any variable that is + * not "NoSave" during copying pages: * * Its rewriting one kernel image with another. What is stack in "old" * image could very well be data page in "new" image, and overwriting @@ -36,13 +36,6 @@ ENTRY(swsusp_arch_suspend) movq %r15, saved_context_r15(%rip) pushfq ; popq saved_context_eflags(%rip) - /* save the address of restore_registers */ - movq $restore_registers, %rax - movq %rax, restore_jump_address(%rip) - /* save cr3 */ - movq %cr3, %rax - movq %rax, restore_cr3(%rip) - call swsusp_save ret @@ -61,17 +54,7 @@ ENTRY(restore_image) movq %rcx, %cr3; movq %rax, %cr4; # turn PGE back on - /* prepare to jump to the image kernel */ - movq restore_jump_address(%rip), %rax - movq restore_cr3(%rip), %rbx - - /* prepare to copy image data to their original locations */ movq restore_pblist(%rip), %rdx - movq relocated_restore_code(%rip), %rcx - jmpq *%rcx - - /* code below has been relocated to a safe page */ -ENTRY(core_restore_code) loop: testq %rdx, %rdx jz done @@ -79,7 +62,7 @@ loop: /* get addresses from the pbe and copy the page */ movq pbe_address(%rdx), %rsi movq pbe_orig_address(%rdx), %rdi - movq $(PAGE_SIZE >> 3), %rcx + movq $512, %rcx rep movsq @@ -87,22 +70,10 @@ loop: movq pbe_next(%rdx), %rdx jmp loop done: - /* jump to the restore_registers address from the image header */ - jmpq *%rax - /* - * NOTE: This assumes that the boot kernel's text mapping covers the - * image kernel's page containing restore_registers and the address of - * this page is the same as in the image kernel's text mapping (it - * should always be true, because the text mapping is linear, starting - * from 0, and is supposed to cover the entire kernel text for every - * kernel). - * - * code below belongs to the image kernel - */ - -ENTRY(restore_registers) /* go back to the original page tables */ - movq %rbx, %cr3 + movq $(init_level4_pgt - __START_KERNEL_map), %rax + addq phys_base(%rip), %rax + movq %rax, %cr3 /* Flush TLB, including "global" things (vmalloc) */ movq mmu_cr4_features(%rip), %rax @@ -113,9 +84,12 @@ ENTRY(restore_registers) movq %rcx, %cr3 movq %rax, %cr4; # turn PGE back on + movl $24, %eax + movl %eax, %ds + movq saved_context_esp(%rip), %rsp movq saved_context_ebp(%rip), %rbp - /* restore GPRs (we don't restore %rax, it must be 0 anyway) */ + /* Don't restore %rax, it must be 0 anyway */ movq saved_context_ebx(%rip), %rbx movq saved_context_ecx(%rip), %rcx movq saved_context_edx(%rip), %rdx @@ -133,7 +107,4 @@ ENTRY(restore_registers) xorq %rax, %rax - /* tell the hibernation core that we've just restored the memory */ - movq %rax, in_suspend(%rip) - ret diff --git a/trunk/arch/x86/kernel/traps_32.c b/trunk/arch/x86/kernel/traps_32.c index 1e9d57256eb1..b132d3957dfc 100644 --- a/trunk/arch/x86/kernel/traps_32.c +++ b/trunk/arch/x86/kernel/traps_32.c @@ -316,7 +316,7 @@ void show_registers(struct pt_regs *regs) printk(KERN_EMERG "ds: %04x es: %04x fs: %04x gs: %04x ss: %04x\n", regs->xds & 0xffff, regs->xes & 0xffff, regs->xfs & 0xffff, gs, ss); printk(KERN_EMERG "Process %.*s (pid: %d, ti=%p task=%p task.ti=%p)", - TASK_COMM_LEN, current->comm, task_pid_nr(current), + TASK_COMM_LEN, current->comm, current->pid, current_thread_info(), current, task_thread_info(current)); /* * When in-kernel, we also print out the stack and code at the @@ -622,7 +622,7 @@ fastcall void __kprobes do_general_protection(struct pt_regs * regs, printk_ratelimit()) printk(KERN_INFO "%s[%d] general protection eip:%lx esp:%lx error:%lx\n", - current->comm, task_pid_nr(current), + current->comm, current->pid, regs->eip, regs->esp, error_code); force_sig(SIGSEGV, current); diff --git a/trunk/arch/x86/kernel/vsyscall_64.c b/trunk/arch/x86/kernel/vsyscall_64.c index 585541ca1a7e..8a67e282cb5e 100644 --- a/trunk/arch/x86/kernel/vsyscall_64.c +++ b/trunk/arch/x86/kernel/vsyscall_64.c @@ -64,16 +64,6 @@ struct vsyscall_gtod_data __vsyscall_gtod_data __section_vsyscall_gtod_data = .sysctl_enabled = 1, }; -void update_vsyscall_tz(void) -{ - unsigned long flags; - - write_seqlock_irqsave(&vsyscall_gtod_data.lock, flags); - /* sys_tz has changed */ - vsyscall_gtod_data.sys_tz = sys_tz; - write_sequnlock_irqrestore(&vsyscall_gtod_data.lock, flags); -} - void update_vsyscall(struct timespec *wall_time, struct clocksource *clock) { unsigned long flags; @@ -87,6 +77,7 @@ void update_vsyscall(struct timespec *wall_time, struct clocksource *clock) vsyscall_gtod_data.clock.shift = clock->shift; vsyscall_gtod_data.wall_time_sec = wall_time->tv_sec; vsyscall_gtod_data.wall_time_nsec = wall_time->tv_nsec; + vsyscall_gtod_data.sys_tz = sys_tz; vsyscall_gtod_data.wall_to_monotonic = wall_to_monotonic; write_sequnlock_irqrestore(&vsyscall_gtod_data.lock, flags); } @@ -172,7 +163,7 @@ time_t __vsyscall(1) vtime(time_t *t) if (unlikely(!__vsyscall_gtod_data.sysctl_enabled)) return time_syscall(t); - vgettimeofday(&tv, NULL); + vgettimeofday(&tv, 0); result = tv.tv_sec; if (t) *t = result; @@ -266,10 +257,18 @@ static int vsyscall_sysctl_change(ctl_table *ctl, int write, struct file * filp, return ret; } +static int vsyscall_sysctl_nostrat(ctl_table *t, int __user *name, int nlen, + void __user *oldval, size_t __user *oldlenp, + void __user *newval, size_t newlen) +{ + return -ENOSYS; +} + static ctl_table kernel_table2[] = { - { .procname = "vsyscall64", + { .ctl_name = 99, .procname = "vsyscall64", .data = &vsyscall_gtod_data.sysctl_enabled, .maxlen = sizeof(int), .mode = 0644, + .strategy = vsyscall_sysctl_nostrat, .proc_handler = vsyscall_sysctl_change }, {} }; diff --git a/trunk/arch/x86/lib/usercopy_32.c b/trunk/arch/x86/lib/usercopy_32.c index 8bab2b2efaff..9f38b12b4af1 100644 --- a/trunk/arch/x86/lib/usercopy_32.c +++ b/trunk/arch/x86/lib/usercopy_32.c @@ -748,7 +748,7 @@ unsigned long __copy_to_user_ll(void __user *to, const void *from, retval = get_user_pages(current, current->mm, (unsigned long )to, 1, 1, 0, &pg, NULL); - if (retval == -ENOMEM && is_global_init(current)) { + if (retval == -ENOMEM && is_init(current)) { up_read(¤t->mm->mmap_sem); congestion_wait(WRITE, HZ/50); goto survive; diff --git a/trunk/arch/x86/mm/fault_32.c b/trunk/arch/x86/mm/fault_32.c index 4d3e538c57ab..6555c3d14371 100644 --- a/trunk/arch/x86/mm/fault_32.c +++ b/trunk/arch/x86/mm/fault_32.c @@ -471,8 +471,8 @@ fastcall void __kprobes do_page_fault(struct pt_regs *regs, printk_ratelimit()) { printk("%s%s[%d]: segfault at %08lx eip %08lx " "esp %08lx error %lx\n", - task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG, - tsk->comm, task_pid_nr(tsk), address, regs->eip, + tsk->pid > 1 ? KERN_INFO : KERN_EMERG, + tsk->comm, tsk->pid, address, regs->eip, regs->esp, error_code); } tsk->thread.cr2 = address; @@ -587,7 +587,7 @@ fastcall void __kprobes do_page_fault(struct pt_regs *regs, */ out_of_memory: up_read(&mm->mmap_sem); - if (is_global_init(tsk)) { + if (is_init(tsk)) { yield(); down_read(&mm->mmap_sem); goto survive; diff --git a/trunk/arch/x86/mm/fault_64.c b/trunk/arch/x86/mm/fault_64.c index 5149ac136a5d..5e0e54906c48 100644 --- a/trunk/arch/x86/mm/fault_64.c +++ b/trunk/arch/x86/mm/fault_64.c @@ -554,7 +554,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, */ out_of_memory: up_read(&mm->mmap_sem); - if (is_global_init(current)) { + if (is_init(current)) { yield(); goto again; } diff --git a/trunk/arch/x86/mm/pageattr_64.c b/trunk/arch/x86/mm/pageattr_64.c index c7b7dfe1d405..8a4f65bf956e 100644 --- a/trunk/arch/x86/mm/pageattr_64.c +++ b/trunk/arch/x86/mm/pageattr_64.c @@ -230,14 +230,9 @@ void global_flush_tlb(void) struct page *pg, *next; struct list_head l; - /* - * Write-protect the semaphore, to exclude two contexts - * doing a list_replace_init() call in parallel and to - * exclude new additions to the deferred_pages list: - */ - down_write(&init_mm.mmap_sem); + down_read(&init_mm.mmap_sem); list_replace_init(&deferred_pages, &l); - up_write(&init_mm.mmap_sem); + up_read(&init_mm.mmap_sem); flush_map(&l); diff --git a/trunk/arch/x86_64/Kconfig b/trunk/arch/x86_64/Kconfig index 25785b23df87..43fafe9e9c08 100644 --- a/trunk/arch/x86_64/Kconfig +++ b/trunk/arch/x86_64/Kconfig @@ -716,17 +716,10 @@ menu "Power management options" source kernel/power/Kconfig -config ARCH_HIBERNATION_HEADER - bool - depends on HIBERNATION - default y - source "drivers/acpi/Kconfig" source "arch/x86/kernel/cpufreq/Kconfig" -source "drivers/cpuidle/Kconfig" - endmenu menu "Bus options (PCI etc.)" @@ -801,6 +794,21 @@ source "drivers/firmware/Kconfig" source fs/Kconfig +menu "Instrumentation Support" + +source "arch/x86/oprofile/Kconfig" + +config KPROBES + bool "Kprobes" + depends on KALLSYMS && MODULES + help + Kprobes allows you to trap at almost any kernel address and + execute a callback function. register_kprobe() establishes + a probepoint and specifies the callback. Kprobes is useful + for kernel debugging, non-intrusive instrumentation and testing. + If in doubt, say "N". +endmenu + source "arch/x86_64/Kconfig.debug" source "security/Kconfig" diff --git a/trunk/arch/xtensa/Kconfig b/trunk/arch/xtensa/Kconfig index 85ffbb491490..7fbb44bea37f 100644 --- a/trunk/arch/xtensa/Kconfig +++ b/trunk/arch/xtensa/Kconfig @@ -251,8 +251,6 @@ config EMBEDDED_RAMDISK_IMAGE provide one yourself. endmenu -source "kernel/Kconfig.instrumentation" - source "arch/xtensa/Kconfig.debug" source "security/Kconfig" diff --git a/trunk/arch/xtensa/kernel/traps.c b/trunk/arch/xtensa/kernel/traps.c index 397bcd6ad08d..8be99c777d9d 100644 --- a/trunk/arch/xtensa/kernel/traps.c +++ b/trunk/arch/xtensa/kernel/traps.c @@ -176,7 +176,7 @@ void do_unhandled(struct pt_regs *regs, unsigned long exccause) printk("Caught unhandled exception in '%s' " "(pid = %d, pc = %#010lx) - should not happen\n" "\tEXCCAUSE is %ld\n", - current->comm, task_pid_nr(current), regs->pc, exccause); + current->comm, current->pid, regs->pc, exccause); force_sig(SIGILL, current); } @@ -228,7 +228,7 @@ do_illegal_instruction(struct pt_regs *regs) /* If in user mode, send SIGILL signal to current process. */ printk("Illegal Instruction in '%s' (pid = %d, pc = %#010lx)\n", - current->comm, task_pid_nr(current), regs->pc); + current->comm, current->pid, regs->pc); force_sig(SIGILL, current); } @@ -254,7 +254,7 @@ do_unaligned_user (struct pt_regs *regs) current->thread.error_code = -3; printk("Unaligned memory access to %08lx in '%s' " "(pid = %d, pc = %#010lx)\n", - regs->excvaddr, current->comm, task_pid_nr(current), regs->pc); + regs->excvaddr, current->comm, current->pid, regs->pc); info.si_signo = SIGBUS; info.si_errno = 0; info.si_code = BUS_ADRALN; diff --git a/trunk/arch/xtensa/mm/fault.c b/trunk/arch/xtensa/mm/fault.c index 33f366be323f..2f842859948f 100644 --- a/trunk/arch/xtensa/mm/fault.c +++ b/trunk/arch/xtensa/mm/fault.c @@ -145,7 +145,7 @@ void do_page_fault(struct pt_regs *regs) */ out_of_memory: up_read(&mm->mmap_sem); - if (is_global_init(current)) { + if (is_init(current)) { yield(); down_read(&mm->mmap_sem); goto survive; diff --git a/trunk/block/ll_rw_blk.c b/trunk/block/ll_rw_blk.c index 8025d646ab30..3935469e3662 100644 --- a/trunk/block/ll_rw_blk.c +++ b/trunk/block/ll_rw_blk.c @@ -3367,7 +3367,7 @@ void submit_bio(int rw, struct bio *bio) if (unlikely(block_dump)) { char b[BDEVNAME_SIZE]; printk(KERN_DEBUG "%s(%d): %s block %Lu on %s\n", - current->comm, task_pid_nr(current), + current->comm, current->pid, (rw & WRITE) ? "WRITE" : "READ", (unsigned long long)bio->bi_sector, bdevname(bio->bi_bdev,b)); @@ -3739,7 +3739,7 @@ EXPORT_SYMBOL(end_dequeued_request); /** * end_request - end I/O on the current segment of the request - * @req: the request being processed + * @rq: the request being processed * @uptodate: error value or 0/1 uptodate flag * * Description: diff --git a/trunk/drivers/Kconfig b/trunk/drivers/Kconfig index 34f40ea0ba60..4fb134d50da7 100644 --- a/trunk/drivers/Kconfig +++ b/trunk/drivers/Kconfig @@ -58,8 +58,6 @@ source "drivers/power/Kconfig" source "drivers/hwmon/Kconfig" -source "drivers/watchdog/Kconfig" - source "drivers/ssb/Kconfig" source "drivers/mfd/Kconfig" diff --git a/trunk/drivers/Makefile b/trunk/drivers/Makefile index cfe38ffff28a..174c27eb4430 100644 --- a/trunk/drivers/Makefile +++ b/trunk/drivers/Makefile @@ -66,7 +66,7 @@ obj-y += i2c/ obj-$(CONFIG_W1) += w1/ obj-$(CONFIG_POWER_SUPPLY) += power/ obj-$(CONFIG_HWMON) += hwmon/ -obj-$(CONFIG_WATCHDOG) += watchdog/ +obj-$(CONFIG_WATCHDOG) += char/watchdog/ obj-$(CONFIG_PHONE) += telephony/ obj-$(CONFIG_MD) += md/ obj-$(CONFIG_BT) += bluetooth/ @@ -76,7 +76,6 @@ obj-$(CONFIG_MCA) += mca/ obj-$(CONFIG_EISA) += eisa/ obj-$(CONFIG_LGUEST_GUEST) += lguest/ obj-$(CONFIG_CPU_FREQ) += cpufreq/ -obj-$(CONFIG_CPU_IDLE) += cpuidle/ obj-$(CONFIG_MMC) += mmc/ obj-$(CONFIG_NEW_LEDS) += leds/ obj-$(CONFIG_INFINIBAND) += infiniband/ diff --git a/trunk/drivers/acpi/Kconfig b/trunk/drivers/acpi/Kconfig index b83389145f28..4875f0149eb4 100644 --- a/trunk/drivers/acpi/Kconfig +++ b/trunk/drivers/acpi/Kconfig @@ -88,7 +88,7 @@ config ACPI_PROC_EVENT config ACPI_AC tristate "AC Adapter" - depends on X86 && POWER_SUPPLY + depends on X86 default y help This driver adds support for the AC Adapter object, which indicates @@ -97,7 +97,7 @@ config ACPI_AC config ACPI_BATTERY tristate "Battery" - depends on X86 && POWER_SUPPLY + depends on X86 default y help This driver adds support for battery information through @@ -117,7 +117,6 @@ config ACPI_BUTTON config ACPI_VIDEO tristate "Video" depends on X86 && BACKLIGHT_CLASS_DEVICE && VIDEO_OUTPUT_CONTROL - depends on INPUT help This driver implement the ACPI Extensions For Display Adapters for integrated graphics devices on motherboard, as specified in @@ -350,11 +349,12 @@ config ACPI_HOTPLUG_MEMORY $>modprobe acpi_memhotplug config ACPI_SBS - tristate "Smart Battery System" + tristate "Smart Battery System (EXPERIMENTAL)" depends on X86 - depends on POWER_SUPPLY + depends on EXPERIMENTAL help - This driver adds support for the Smart Battery System, another - type of access to battery information, found on some laptops. + This driver adds support for the Smart Battery System. + A "Smart Battery" is quite old and quite rare compared + to today's ACPI "Control Method" battery. endif # ACPI diff --git a/trunk/drivers/acpi/Makefile b/trunk/drivers/acpi/Makefile index 54e3ab0e5fc0..d4336f1730e9 100644 --- a/trunk/drivers/acpi/Makefile +++ b/trunk/drivers/acpi/Makefile @@ -60,4 +60,3 @@ obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o obj-y += cm_sbs.o obj-$(CONFIG_ACPI_SBS) += sbs.o -obj-$(CONFIG_ACPI_SBS) += sbshc.o diff --git a/trunk/drivers/acpi/ac.c b/trunk/drivers/acpi/ac.c index e03de37a750d..26d70702b313 100644 --- a/trunk/drivers/acpi/ac.c +++ b/trunk/drivers/acpi/ac.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include @@ -73,37 +72,16 @@ static struct acpi_driver acpi_ac_driver = { }; struct acpi_ac { - struct power_supply charger; struct acpi_device * device; unsigned long state; }; -#define to_acpi_ac(x) container_of(x, struct acpi_ac, charger); - static const struct file_operations acpi_ac_fops = { .open = acpi_ac_open_fs, .read = seq_read, .llseek = seq_lseek, .release = single_release, }; -static int get_ac_property(struct power_supply *psy, - enum power_supply_property psp, - union power_supply_propval *val) -{ - struct acpi_ac *ac = to_acpi_ac(psy); - switch (psp) { - case POWER_SUPPLY_PROP_ONLINE: - val->intval = ac->state; - break; - default: - return -EINVAL; - } - return 0; -} - -static enum power_supply_property ac_props[] = { - POWER_SUPPLY_PROP_ONLINE, -}; /* -------------------------------------------------------------------------- AC Adapter Management @@ -230,7 +208,6 @@ static void acpi_ac_notify(acpi_handle handle, u32 event, void *data) acpi_bus_generate_netlink_event(device->pnp.device_class, device->dev.bus_id, event, (u32) ac->state); - kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE); break; default: ACPI_DEBUG_PRINT((ACPI_DB_INFO, @@ -267,12 +244,7 @@ static int acpi_ac_add(struct acpi_device *device) result = acpi_ac_add_fs(device); if (result) goto end; - ac->charger.name = acpi_device_bid(device); - ac->charger.type = POWER_SUPPLY_TYPE_MAINS; - ac->charger.properties = ac_props; - ac->charger.num_properties = ARRAY_SIZE(ac_props); - ac->charger.get_property = get_ac_property; - power_supply_register(&ac->device->dev, &ac->charger); + status = acpi_install_notify_handler(device->handle, ACPI_ALL_NOTIFY, acpi_ac_notify, ac); @@ -307,8 +279,7 @@ static int acpi_ac_remove(struct acpi_device *device, int type) status = acpi_remove_notify_handler(device->handle, ACPI_ALL_NOTIFY, acpi_ac_notify); - if (ac->charger.dev) - power_supply_unregister(&ac->charger); + acpi_ac_remove_fs(device); kfree(ac); diff --git a/trunk/drivers/acpi/battery.c b/trunk/drivers/acpi/battery.c index 681e26b56b11..9b2c0f74f869 100644 --- a/trunk/drivers/acpi/battery.c +++ b/trunk/drivers/acpi/battery.c @@ -1,8 +1,6 @@ /* - * battery.c - ACPI Battery Driver (Revision: 2.0) + * acpi_battery.c - ACPI Battery Driver ($Revision: 37 $) * - * Copyright (C) 2007 Alexey Starikovskiy - * Copyright (C) 2004-2007 Vladimir Lebedev * Copyright (C) 2001, 2002 Andy Grover * Copyright (C) 2001, 2002 Paul Diefenbaugh * @@ -29,288 +27,244 @@ #include #include #include -#include - -#ifdef CONFIG_ACPI_PROCFS #include #include #include -#endif #include #include -#include - #define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF +#define ACPI_BATTERY_FORMAT_BIF "NNNNNNNNNSSSS" +#define ACPI_BATTERY_FORMAT_BST "NNNN" + #define ACPI_BATTERY_COMPONENT 0x00040000 #define ACPI_BATTERY_CLASS "battery" #define ACPI_BATTERY_DEVICE_NAME "Battery" #define ACPI_BATTERY_NOTIFY_STATUS 0x80 #define ACPI_BATTERY_NOTIFY_INFO 0x81 +#define ACPI_BATTERY_UNITS_WATTS "mW" +#define ACPI_BATTERY_UNITS_AMPS "mA" #define _COMPONENT ACPI_BATTERY_COMPONENT +#define ACPI_BATTERY_UPDATE_TIME 0 + +#define ACPI_BATTERY_NONE_UPDATE 0 +#define ACPI_BATTERY_EASY_UPDATE 1 +#define ACPI_BATTERY_INIT_UPDATE 2 + ACPI_MODULE_NAME("battery"); MODULE_AUTHOR("Paul Diefenbaugh"); -MODULE_AUTHOR("Alexey Starikovskiy "); MODULE_DESCRIPTION("ACPI Battery Driver"); MODULE_LICENSE("GPL"); -static unsigned int cache_time = 1000; -module_param(cache_time, uint, 0644); -MODULE_PARM_DESC(cache_time, "cache time in milliseconds"); +static unsigned int update_time = ACPI_BATTERY_UPDATE_TIME; + +/* 0 - every time, > 0 - by update_time */ +module_param(update_time, uint, 0644); -#ifdef CONFIG_ACPI_PROCFS extern struct proc_dir_entry *acpi_lock_battery_dir(void); extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir); -enum acpi_battery_files { - info_tag = 0, - state_tag, - alarm_tag, - ACPI_BATTERY_NUMFILES, -}; - -#endif +static int acpi_battery_add(struct acpi_device *device); +static int acpi_battery_remove(struct acpi_device *device, int type); +static int acpi_battery_resume(struct acpi_device *device); static const struct acpi_device_id battery_device_ids[] = { {"PNP0C0A", 0}, {"", 0}, }; - MODULE_DEVICE_TABLE(acpi, battery_device_ids); +static struct acpi_driver acpi_battery_driver = { + .name = "battery", + .class = ACPI_BATTERY_CLASS, + .ids = battery_device_ids, + .ops = { + .add = acpi_battery_add, + .resume = acpi_battery_resume, + .remove = acpi_battery_remove, + }, +}; -struct acpi_battery { - struct mutex lock; - struct power_supply bat; - struct acpi_device *device; - unsigned long update_time; - int current_now; - int capacity_now; - int voltage_now; - int design_capacity; - int full_charge_capacity; - int technology; - int design_voltage; - int design_capacity_warning; - int design_capacity_low; - int capacity_granularity_1; - int capacity_granularity_2; - int alarm; - char model_number[32]; - char serial_number[32]; - char type[32]; - char oem_info[32]; - int state; - int power_unit; +struct acpi_battery_state { + acpi_integer state; + acpi_integer present_rate; + acpi_integer remaining_capacity; + acpi_integer present_voltage; +}; + +struct acpi_battery_info { + acpi_integer power_unit; + acpi_integer design_capacity; + acpi_integer last_full_capacity; + acpi_integer battery_technology; + acpi_integer design_voltage; + acpi_integer design_capacity_warning; + acpi_integer design_capacity_low; + acpi_integer battery_capacity_granularity_1; + acpi_integer battery_capacity_granularity_2; + acpi_string model_number; + acpi_string serial_number; + acpi_string battery_type; + acpi_string oem_info; +}; + +enum acpi_battery_files{ + ACPI_BATTERY_INFO = 0, + ACPI_BATTERY_STATE, + ACPI_BATTERY_ALARM, + ACPI_BATTERY_NUMFILES, +}; + +struct acpi_battery_flags { + u8 battery_present_prev; u8 alarm_present; + u8 init_update; + u8 update[ACPI_BATTERY_NUMFILES]; + u8 power_unit; }; -#define to_acpi_battery(x) container_of(x, struct acpi_battery, bat); +struct acpi_battery { + struct mutex mutex; + struct acpi_device *device; + struct acpi_battery_flags flags; + struct acpi_buffer bif_data; + struct acpi_buffer bst_data; + unsigned long alarm; + unsigned long update_time[ACPI_BATTERY_NUMFILES]; +}; inline int acpi_battery_present(struct acpi_battery *battery) { return battery->device->status.battery_present; } - -static int acpi_battery_technology(struct acpi_battery *battery) +inline char *acpi_battery_power_units(struct acpi_battery *battery) { - if (!strcasecmp("NiCd", battery->type)) - return POWER_SUPPLY_TECHNOLOGY_NiCd; - if (!strcasecmp("NiMH", battery->type)) - return POWER_SUPPLY_TECHNOLOGY_NiMH; - if (!strcasecmp("LION", battery->type)) - return POWER_SUPPLY_TECHNOLOGY_LION; - if (!strcasecmp("LiP", battery->type)) - return POWER_SUPPLY_TECHNOLOGY_LIPO; - return POWER_SUPPLY_TECHNOLOGY_UNKNOWN; -} - -static int acpi_battery_get_property(struct power_supply *psy, - enum power_supply_property psp, - union power_supply_propval *val) -{ - struct acpi_battery *battery = to_acpi_battery(psy); - - if ((!acpi_battery_present(battery)) && - psp != POWER_SUPPLY_PROP_PRESENT) - return -ENODEV; - switch (psp) { - case POWER_SUPPLY_PROP_STATUS: - if (battery->state & 0x01) - val->intval = POWER_SUPPLY_STATUS_DISCHARGING; - else if (battery->state & 0x02) - val->intval = POWER_SUPPLY_STATUS_CHARGING; - else if (battery->state == 0) - val->intval = POWER_SUPPLY_STATUS_FULL; - break; - case POWER_SUPPLY_PROP_PRESENT: - val->intval = acpi_battery_present(battery); - break; - case POWER_SUPPLY_PROP_TECHNOLOGY: - val->intval = acpi_battery_technology(battery); - break; - case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: - val->intval = battery->design_voltage * 1000; - break; - case POWER_SUPPLY_PROP_VOLTAGE_NOW: - val->intval = battery->voltage_now * 1000; - break; - case POWER_SUPPLY_PROP_CURRENT_NOW: - val->intval = battery->current_now * 1000; - break; - case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: - case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN: - val->intval = battery->design_capacity * 1000; - break; - case POWER_SUPPLY_PROP_CHARGE_FULL: - case POWER_SUPPLY_PROP_ENERGY_FULL: - val->intval = battery->full_charge_capacity * 1000; - break; - case POWER_SUPPLY_PROP_CHARGE_NOW: - case POWER_SUPPLY_PROP_ENERGY_NOW: - val->intval = battery->capacity_now * 1000; - break; - case POWER_SUPPLY_PROP_MODEL_NAME: - val->strval = battery->model_number; - break; - case POWER_SUPPLY_PROP_MANUFACTURER: - val->strval = battery->oem_info; - break; - default: - return -EINVAL; - } - return 0; + if (battery->flags.power_unit) + return ACPI_BATTERY_UNITS_AMPS; + else + return ACPI_BATTERY_UNITS_WATTS; } -static enum power_supply_property charge_battery_props[] = { - POWER_SUPPLY_PROP_STATUS, - POWER_SUPPLY_PROP_PRESENT, - POWER_SUPPLY_PROP_TECHNOLOGY, - POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, - POWER_SUPPLY_PROP_VOLTAGE_NOW, - POWER_SUPPLY_PROP_CURRENT_NOW, - POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, - POWER_SUPPLY_PROP_CHARGE_FULL, - POWER_SUPPLY_PROP_CHARGE_NOW, - POWER_SUPPLY_PROP_MODEL_NAME, - POWER_SUPPLY_PROP_MANUFACTURER, -}; - -static enum power_supply_property energy_battery_props[] = { - POWER_SUPPLY_PROP_STATUS, - POWER_SUPPLY_PROP_PRESENT, - POWER_SUPPLY_PROP_TECHNOLOGY, - POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, - POWER_SUPPLY_PROP_VOLTAGE_NOW, - POWER_SUPPLY_PROP_CURRENT_NOW, - POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN, - POWER_SUPPLY_PROP_ENERGY_FULL, - POWER_SUPPLY_PROP_ENERGY_NOW, - POWER_SUPPLY_PROP_MODEL_NAME, - POWER_SUPPLY_PROP_MANUFACTURER, -}; - -#ifdef CONFIG_ACPI_PROCFS -inline char *acpi_battery_units(struct acpi_battery *battery) +inline acpi_handle acpi_battery_handle(struct acpi_battery *battery) { - return (battery->power_unit)?"mA":"mW"; + return battery->device->handle; } -#endif /* -------------------------------------------------------------------------- Battery Management -------------------------------------------------------------------------- */ -struct acpi_offsets { - size_t offset; /* offset inside struct acpi_sbs_battery */ - u8 mode; /* int or string? */ -}; -static struct acpi_offsets state_offsets[] = { - {offsetof(struct acpi_battery, state), 0}, - {offsetof(struct acpi_battery, current_now), 0}, - {offsetof(struct acpi_battery, capacity_now), 0}, - {offsetof(struct acpi_battery, voltage_now), 0}, -}; +static void acpi_battery_check_result(struct acpi_battery *battery, int result) +{ + if (!battery) + return; -static struct acpi_offsets info_offsets[] = { - {offsetof(struct acpi_battery, power_unit), 0}, - {offsetof(struct acpi_battery, design_capacity), 0}, - {offsetof(struct acpi_battery, full_charge_capacity), 0}, - {offsetof(struct acpi_battery, technology), 0}, - {offsetof(struct acpi_battery, design_voltage), 0}, - {offsetof(struct acpi_battery, design_capacity_warning), 0}, - {offsetof(struct acpi_battery, design_capacity_low), 0}, - {offsetof(struct acpi_battery, capacity_granularity_1), 0}, - {offsetof(struct acpi_battery, capacity_granularity_2), 0}, - {offsetof(struct acpi_battery, model_number), 1}, - {offsetof(struct acpi_battery, serial_number), 1}, - {offsetof(struct acpi_battery, type), 1}, - {offsetof(struct acpi_battery, oem_info), 1}, -}; + if (result) { + battery->flags.init_update = 1; + } +} -static int extract_package(struct acpi_battery *battery, - union acpi_object *package, - struct acpi_offsets *offsets, int num) -{ - int i, *x; - union acpi_object *element; - if (package->type != ACPI_TYPE_PACKAGE) - return -EFAULT; - for (i = 0; i < num; ++i) { - if (package->package.count <= i) - return -EFAULT; - element = &package->package.elements[i]; - if (offsets[i].mode) { - if (element->type != ACPI_TYPE_STRING && - element->type != ACPI_TYPE_BUFFER) - return -EFAULT; - strncpy((u8 *)battery + offsets[i].offset, - element->string.pointer, 32); - } else { - if (element->type != ACPI_TYPE_INTEGER) - return -EFAULT; - x = (int *)((u8 *)battery + offsets[i].offset); - *x = element->integer.value; +static int acpi_battery_extract_package(struct acpi_battery *battery, + union acpi_object *package, + struct acpi_buffer *format, + struct acpi_buffer *data, + char *package_name) +{ + acpi_status status = AE_OK; + struct acpi_buffer data_null = { 0, NULL }; + + status = acpi_extract_package(package, format, &data_null); + if (status != AE_BUFFER_OVERFLOW) { + ACPI_EXCEPTION((AE_INFO, status, "Extracting size %s", + package_name)); + return -ENODEV; + } + + if (data_null.length != data->length) { + kfree(data->pointer); + data->pointer = kzalloc(data_null.length, GFP_KERNEL); + if (!data->pointer) { + ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY, "kzalloc()")); + return -ENOMEM; } + data->length = data_null.length; } + + status = acpi_extract_package(package, format, data); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, status, "Extracting %s", + package_name)); + return -ENODEV; + } + return 0; } static int acpi_battery_get_status(struct acpi_battery *battery) { - if (acpi_bus_get_status(battery->device)) { + int result = 0; + + result = acpi_bus_get_status(battery->device); + if (result) { ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Evaluating _STA")); return -ENODEV; } - return 0; + return result; } static int acpi_battery_get_info(struct acpi_battery *battery) { - int result = -EFAULT; + int result = 0; acpi_status status = 0; struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + struct acpi_buffer format = { sizeof(ACPI_BATTERY_FORMAT_BIF), + ACPI_BATTERY_FORMAT_BIF + }; + union acpi_object *package = NULL; + struct acpi_buffer *data = NULL; + struct acpi_battery_info *bif = NULL; + + battery->update_time[ACPI_BATTERY_INFO] = get_seconds(); if (!acpi_battery_present(battery)) return 0; - mutex_lock(&battery->lock); - status = acpi_evaluate_object(battery->device->handle, "_BIF", - NULL, &buffer); - mutex_unlock(&battery->lock); + /* Evaluate _BIF */ + + status = + acpi_evaluate_object(acpi_battery_handle(battery), "_BIF", NULL, + &buffer); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF")); return -ENODEV; } - result = extract_package(battery, buffer.pointer, - info_offsets, ARRAY_SIZE(info_offsets)); + package = buffer.pointer; + + data = &battery->bif_data; + + /* Extract Package Data */ + + result = + acpi_battery_extract_package(battery, package, &format, data, + "_BIF"); + if (result) + goto end; + + end: + kfree(buffer.pointer); + + if (!result) { + bif = data->pointer; + battery->flags.power_unit = bif->power_unit; + } + return result; } @@ -319,203 +273,342 @@ static int acpi_battery_get_state(struct acpi_battery *battery) int result = 0; acpi_status status = 0; struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + struct acpi_buffer format = { sizeof(ACPI_BATTERY_FORMAT_BST), + ACPI_BATTERY_FORMAT_BST + }; + union acpi_object *package = NULL; + struct acpi_buffer *data = NULL; - if (!acpi_battery_present(battery)) - return 0; + battery->update_time[ACPI_BATTERY_STATE] = get_seconds(); - if (battery->update_time && - time_before(jiffies, battery->update_time + - msecs_to_jiffies(cache_time))) + if (!acpi_battery_present(battery)) return 0; - mutex_lock(&battery->lock); - status = acpi_evaluate_object(battery->device->handle, "_BST", - NULL, &buffer); - mutex_unlock(&battery->lock); + /* Evaluate _BST */ + status = + acpi_evaluate_object(acpi_battery_handle(battery), "_BST", NULL, + &buffer); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST")); return -ENODEV; } - result = extract_package(battery, buffer.pointer, - state_offsets, ARRAY_SIZE(state_offsets)); - battery->update_time = jiffies; + package = buffer.pointer; + + data = &battery->bst_data; + + /* Extract Package Data */ + + result = + acpi_battery_extract_package(battery, package, &format, data, + "_BST"); + if (result) + goto end; + + end: kfree(buffer.pointer); + return result; } -static int acpi_battery_set_alarm(struct acpi_battery *battery) +static int acpi_battery_get_alarm(struct acpi_battery *battery) +{ + battery->update_time[ACPI_BATTERY_ALARM] = get_seconds(); + + return 0; +} + +static int acpi_battery_set_alarm(struct acpi_battery *battery, + unsigned long alarm) { acpi_status status = 0; - union acpi_object arg0 = { .type = ACPI_TYPE_INTEGER }; + union acpi_object arg0 = { ACPI_TYPE_INTEGER }; struct acpi_object_list arg_list = { 1, &arg0 }; - if (!acpi_battery_present(battery)|| !battery->alarm_present) + battery->update_time[ACPI_BATTERY_ALARM] = get_seconds(); + + if (!acpi_battery_present(battery)) return -ENODEV; - arg0.integer.value = battery->alarm; + if (!battery->flags.alarm_present) + return -ENODEV; - mutex_lock(&battery->lock); - status = acpi_evaluate_object(battery->device->handle, "_BTP", - &arg_list, NULL); - mutex_unlock(&battery->lock); + arg0.integer.value = alarm; + status = + acpi_evaluate_object(acpi_battery_handle(battery), "_BTP", + &arg_list, NULL); if (ACPI_FAILURE(status)) return -ENODEV; - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Alarm set to %d\n", battery->alarm)); + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Alarm set to %d\n", (u32) alarm)); + + battery->alarm = alarm; + return 0; } static int acpi_battery_init_alarm(struct acpi_battery *battery) { + int result = 0; acpi_status status = AE_OK; acpi_handle handle = NULL; + struct acpi_battery_info *bif = battery->bif_data.pointer; + unsigned long alarm = battery->alarm; /* See if alarms are supported, and if so, set default */ - status = acpi_get_handle(battery->device->handle, "_BTP", &handle); - if (ACPI_FAILURE(status)) { - battery->alarm_present = 0; - return 0; + + status = acpi_get_handle(acpi_battery_handle(battery), "_BTP", &handle); + if (ACPI_SUCCESS(status)) { + battery->flags.alarm_present = 1; + if (!alarm && bif) { + alarm = bif->design_capacity_warning; + } + result = acpi_battery_set_alarm(battery, alarm); + if (result) + goto end; + } else { + battery->flags.alarm_present = 0; } - battery->alarm_present = 1; - if (!battery->alarm) - battery->alarm = battery->design_capacity_warning; - return acpi_battery_set_alarm(battery); + + end: + + return result; } -static int acpi_battery_update(struct acpi_battery *battery) +static int acpi_battery_init_update(struct acpi_battery *battery) { - int saved_present = acpi_battery_present(battery); - int result = acpi_battery_get_status(battery); - if (result || !acpi_battery_present(battery)) + int result = 0; + + result = acpi_battery_get_status(battery); + if (result) return result; - if (saved_present != acpi_battery_present(battery) || - !battery->update_time) { - battery->update_time = 0; + + battery->flags.battery_present_prev = acpi_battery_present(battery); + + if (acpi_battery_present(battery)) { result = acpi_battery_get_info(battery); if (result) return result; - if (battery->power_unit) { - battery->bat.properties = charge_battery_props; - battery->bat.num_properties = - ARRAY_SIZE(charge_battery_props); + result = acpi_battery_get_state(battery); + if (result) + return result; + + acpi_battery_init_alarm(battery); + } + + return result; +} + +static int acpi_battery_update(struct acpi_battery *battery, + int update, int *update_result_ptr) +{ + int result = 0; + int update_result = ACPI_BATTERY_NONE_UPDATE; + + if (!acpi_battery_present(battery)) { + update = 1; + } + + if (battery->flags.init_update) { + result = acpi_battery_init_update(battery); + if (result) + goto end; + update_result = ACPI_BATTERY_INIT_UPDATE; + } else if (update) { + result = acpi_battery_get_status(battery); + if (result) + goto end; + if ((!battery->flags.battery_present_prev & acpi_battery_present(battery)) + || (battery->flags.battery_present_prev & !acpi_battery_present(battery))) { + result = acpi_battery_init_update(battery); + if (result) + goto end; + update_result = ACPI_BATTERY_INIT_UPDATE; } else { - battery->bat.properties = energy_battery_props; - battery->bat.num_properties = - ARRAY_SIZE(energy_battery_props); + update_result = ACPI_BATTERY_EASY_UPDATE; } - acpi_battery_init_alarm(battery); } - return acpi_battery_get_state(battery); + + end: + + battery->flags.init_update = (result != 0); + + *update_result_ptr = update_result; + + return result; +} + +static void acpi_battery_notify_update(struct acpi_battery *battery) +{ + acpi_battery_get_status(battery); + + if (battery->flags.init_update) { + return; + } + + if ((!battery->flags.battery_present_prev & + acpi_battery_present(battery)) || + (battery->flags.battery_present_prev & + !acpi_battery_present(battery))) { + battery->flags.init_update = 1; + } else { + battery->flags.update[ACPI_BATTERY_INFO] = 1; + battery->flags.update[ACPI_BATTERY_STATE] = 1; + battery->flags.update[ACPI_BATTERY_ALARM] = 1; + } } /* -------------------------------------------------------------------------- FS Interface (/proc) -------------------------------------------------------------------------- */ -#ifdef CONFIG_ACPI_PROCFS static struct proc_dir_entry *acpi_battery_dir; static int acpi_battery_print_info(struct seq_file *seq, int result) { struct acpi_battery *battery = seq->private; + struct acpi_battery_info *bif = NULL; + char *units = "?"; if (result) goto end; - seq_printf(seq, "present: %s\n", - acpi_battery_present(battery)?"yes":"no"); - if (!acpi_battery_present(battery)) + if (acpi_battery_present(battery)) + seq_printf(seq, "present: yes\n"); + else { + seq_printf(seq, "present: no\n"); goto end; - if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN) + } + + bif = battery->bif_data.pointer; + if (!bif) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, "BIF buffer is NULL")); + result = -ENODEV; + goto end; + } + + /* Battery Units */ + + units = acpi_battery_power_units(battery); + + if (bif->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN) seq_printf(seq, "design capacity: unknown\n"); else seq_printf(seq, "design capacity: %d %sh\n", - battery->design_capacity, - acpi_battery_units(battery)); + (u32) bif->design_capacity, units); - if (battery->full_charge_capacity == ACPI_BATTERY_VALUE_UNKNOWN) + if (bif->last_full_capacity == ACPI_BATTERY_VALUE_UNKNOWN) seq_printf(seq, "last full capacity: unknown\n"); else seq_printf(seq, "last full capacity: %d %sh\n", - battery->full_charge_capacity, - acpi_battery_units(battery)); + (u32) bif->last_full_capacity, units); - seq_printf(seq, "battery technology: %srechargeable\n", - (!battery->technology)?"non-":""); + switch ((u32) bif->battery_technology) { + case 0: + seq_printf(seq, "battery technology: non-rechargeable\n"); + break; + case 1: + seq_printf(seq, "battery technology: rechargeable\n"); + break; + default: + seq_printf(seq, "battery technology: unknown\n"); + break; + } - if (battery->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN) + if (bif->design_voltage == ACPI_BATTERY_VALUE_UNKNOWN) seq_printf(seq, "design voltage: unknown\n"); else seq_printf(seq, "design voltage: %d mV\n", - battery->design_voltage); + (u32) bif->design_voltage); seq_printf(seq, "design capacity warning: %d %sh\n", - battery->design_capacity_warning, - acpi_battery_units(battery)); + (u32) bif->design_capacity_warning, units); seq_printf(seq, "design capacity low: %d %sh\n", - battery->design_capacity_low, - acpi_battery_units(battery)); + (u32) bif->design_capacity_low, units); seq_printf(seq, "capacity granularity 1: %d %sh\n", - battery->capacity_granularity_1, - acpi_battery_units(battery)); + (u32) bif->battery_capacity_granularity_1, units); seq_printf(seq, "capacity granularity 2: %d %sh\n", - battery->capacity_granularity_2, - acpi_battery_units(battery)); - seq_printf(seq, "model number: %s\n", battery->model_number); - seq_printf(seq, "serial number: %s\n", battery->serial_number); - seq_printf(seq, "battery type: %s\n", battery->type); - seq_printf(seq, "OEM info: %s\n", battery->oem_info); + (u32) bif->battery_capacity_granularity_2, units); + seq_printf(seq, "model number: %s\n", bif->model_number); + seq_printf(seq, "serial number: %s\n", bif->serial_number); + seq_printf(seq, "battery type: %s\n", bif->battery_type); + seq_printf(seq, "OEM info: %s\n", bif->oem_info); + end: + if (result) seq_printf(seq, "ERROR: Unable to read battery info\n"); + return result; } static int acpi_battery_print_state(struct seq_file *seq, int result) { struct acpi_battery *battery = seq->private; + struct acpi_battery_state *bst = NULL; + char *units = "?"; if (result) goto end; - seq_printf(seq, "present: %s\n", - acpi_battery_present(battery)?"yes":"no"); - if (!acpi_battery_present(battery)) + if (acpi_battery_present(battery)) + seq_printf(seq, "present: yes\n"); + else { + seq_printf(seq, "present: no\n"); + goto end; + } + + bst = battery->bst_data.pointer; + if (!bst) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, "BST buffer is NULL")); + result = -ENODEV; goto end; + } + + /* Battery Units */ + + units = acpi_battery_power_units(battery); + + if (!(bst->state & 0x04)) + seq_printf(seq, "capacity state: ok\n"); + else + seq_printf(seq, "capacity state: critical\n"); - seq_printf(seq, "capacity state: %s\n", - (battery->state & 0x04)?"critical":"ok"); - if ((battery->state & 0x01) && (battery->state & 0x02)) + if ((bst->state & 0x01) && (bst->state & 0x02)) { seq_printf(seq, "charging state: charging/discharging\n"); - else if (battery->state & 0x01) + } else if (bst->state & 0x01) seq_printf(seq, "charging state: discharging\n"); - else if (battery->state & 0x02) + else if (bst->state & 0x02) seq_printf(seq, "charging state: charging\n"); - else + else { seq_printf(seq, "charging state: charged\n"); + } - if (battery->current_now == ACPI_BATTERY_VALUE_UNKNOWN) + if (bst->present_rate == ACPI_BATTERY_VALUE_UNKNOWN) seq_printf(seq, "present rate: unknown\n"); else seq_printf(seq, "present rate: %d %s\n", - battery->current_now, acpi_battery_units(battery)); + (u32) bst->present_rate, units); - if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN) + if (bst->remaining_capacity == ACPI_BATTERY_VALUE_UNKNOWN) seq_printf(seq, "remaining capacity: unknown\n"); else seq_printf(seq, "remaining capacity: %d %sh\n", - battery->capacity_now, acpi_battery_units(battery)); - if (battery->voltage_now == ACPI_BATTERY_VALUE_UNKNOWN) + (u32) bst->remaining_capacity, units); + + if (bst->present_voltage == ACPI_BATTERY_VALUE_UNKNOWN) seq_printf(seq, "present voltage: unknown\n"); else seq_printf(seq, "present voltage: %d mV\n", - battery->voltage_now); + (u32) bst->present_voltage); + end: - if (result) + + if (result) { seq_printf(seq, "ERROR: Unable to read battery state\n"); + } return result; } @@ -523,6 +616,7 @@ static int acpi_battery_print_state(struct seq_file *seq, int result) static int acpi_battery_print_alarm(struct seq_file *seq, int result) { struct acpi_battery *battery = seq->private; + char *units = "?"; if (result) goto end; @@ -531,121 +625,189 @@ static int acpi_battery_print_alarm(struct seq_file *seq, int result) seq_printf(seq, "present: no\n"); goto end; } + + /* Battery Units */ + + units = acpi_battery_power_units(battery); + seq_printf(seq, "alarm: "); if (!battery->alarm) seq_printf(seq, "unsupported\n"); else - seq_printf(seq, "%u %sh\n", battery->alarm, - acpi_battery_units(battery)); + seq_printf(seq, "%lu %sh\n", battery->alarm, units); + end: + if (result) seq_printf(seq, "ERROR: Unable to read battery alarm\n"); + return result; } -static ssize_t acpi_battery_write_alarm(struct file *file, - const char __user * buffer, - size_t count, loff_t * ppos) +static ssize_t +acpi_battery_write_alarm(struct file *file, + const char __user * buffer, + size_t count, loff_t * ppos) { int result = 0; char alarm_string[12] = { '\0' }; struct seq_file *m = file->private_data; struct acpi_battery *battery = m->private; + int update_result = ACPI_BATTERY_NONE_UPDATE; if (!battery || (count > sizeof(alarm_string) - 1)) return -EINVAL; + + mutex_lock(&battery->mutex); + + result = acpi_battery_update(battery, 1, &update_result); if (result) { result = -ENODEV; goto end; } + if (!acpi_battery_present(battery)) { result = -ENODEV; goto end; } + if (copy_from_user(alarm_string, buffer, count)) { result = -EFAULT; goto end; } + alarm_string[count] = '\0'; - battery->alarm = simple_strtol(alarm_string, NULL, 0); - result = acpi_battery_set_alarm(battery); + + result = acpi_battery_set_alarm(battery, + simple_strtoul(alarm_string, NULL, 0)); + if (result) + goto end; + end: + + acpi_battery_check_result(battery, result); + if (!result) - return count; + result = count; + + mutex_unlock(&battery->mutex); + return result; } typedef int(*print_func)(struct seq_file *seq, int result); - -static print_func acpi_print_funcs[ACPI_BATTERY_NUMFILES] = { - acpi_battery_print_info, - acpi_battery_print_state, - acpi_battery_print_alarm, +typedef int(*get_func)(struct acpi_battery *battery); + +static struct acpi_read_mux { + print_func print; + get_func get; +} acpi_read_funcs[ACPI_BATTERY_NUMFILES] = { + {.get = acpi_battery_get_info, .print = acpi_battery_print_info}, + {.get = acpi_battery_get_state, .print = acpi_battery_print_state}, + {.get = acpi_battery_get_alarm, .print = acpi_battery_print_alarm}, }; static int acpi_battery_read(int fid, struct seq_file *seq) { struct acpi_battery *battery = seq->private; - int result = acpi_battery_update(battery); - return acpi_print_funcs[fid](seq, result); -} - -#define DECLARE_FILE_FUNCTIONS(_name) \ -static int acpi_battery_read_##_name(struct seq_file *seq, void *offset) \ -{ \ - return acpi_battery_read(_name##_tag, seq); \ -} \ -static int acpi_battery_##_name##_open_fs(struct inode *inode, struct file *file) \ -{ \ - return single_open(file, acpi_battery_read_##_name, PDE(inode)->data); \ -} - -DECLARE_FILE_FUNCTIONS(info); -DECLARE_FILE_FUNCTIONS(state); -DECLARE_FILE_FUNCTIONS(alarm); - -#undef DECLARE_FILE_FUNCTIONS - -#define FILE_DESCRIPTION_RO(_name) \ - { \ - .name = __stringify(_name), \ - .mode = S_IRUGO, \ - .ops = { \ - .open = acpi_battery_##_name##_open_fs, \ - .read = seq_read, \ - .llseek = seq_lseek, \ - .release = single_release, \ - .owner = THIS_MODULE, \ - }, \ - } - -#define FILE_DESCRIPTION_RW(_name) \ - { \ - .name = __stringify(_name), \ - .mode = S_IFREG | S_IRUGO | S_IWUSR, \ - .ops = { \ - .open = acpi_battery_##_name##_open_fs, \ - .read = seq_read, \ - .llseek = seq_lseek, \ - .write = acpi_battery_write_##_name, \ - .release = single_release, \ - .owner = THIS_MODULE, \ - }, \ + int result = 0; + int update_result = ACPI_BATTERY_NONE_UPDATE; + int update = 0; + + mutex_lock(&battery->mutex); + + update = (get_seconds() - battery->update_time[fid] >= update_time); + update = (update | battery->flags.update[fid]); + + result = acpi_battery_update(battery, update, &update_result); + if (result) + goto end; + + if (update_result == ACPI_BATTERY_EASY_UPDATE) { + result = acpi_read_funcs[fid].get(battery); + if (result) + goto end; } + end: + result = acpi_read_funcs[fid].print(seq, result); + acpi_battery_check_result(battery, result); + battery->flags.update[fid] = result; + mutex_unlock(&battery->mutex); + return result; +} + +static int acpi_battery_read_info(struct seq_file *seq, void *offset) +{ + return acpi_battery_read(ACPI_BATTERY_INFO, seq); +} + +static int acpi_battery_read_state(struct seq_file *seq, void *offset) +{ + return acpi_battery_read(ACPI_BATTERY_STATE, seq); +} + +static int acpi_battery_read_alarm(struct seq_file *seq, void *offset) +{ + return acpi_battery_read(ACPI_BATTERY_ALARM, seq); +} + +static int acpi_battery_info_open_fs(struct inode *inode, struct file *file) +{ + return single_open(file, acpi_battery_read_info, PDE(inode)->data); +} + +static int acpi_battery_state_open_fs(struct inode *inode, struct file *file) +{ + return single_open(file, acpi_battery_read_state, PDE(inode)->data); +} + +static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file) +{ + return single_open(file, acpi_battery_read_alarm, PDE(inode)->data); +} + static struct battery_file { struct file_operations ops; mode_t mode; char *name; } acpi_battery_file[] = { - FILE_DESCRIPTION_RO(info), - FILE_DESCRIPTION_RO(state), - FILE_DESCRIPTION_RW(alarm), + { + .name = "info", + .mode = S_IRUGO, + .ops = { + .open = acpi_battery_info_open_fs, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, + }, + }, + { + .name = "state", + .mode = S_IRUGO, + .ops = { + .open = acpi_battery_state_open_fs, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, + }, + }, + { + .name = "alarm", + .mode = S_IFREG | S_IRUGO | S_IWUSR, + .ops = { + .open = acpi_battery_alarm_open_fs, + .read = seq_read, + .write = acpi_battery_write_alarm, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, + }, + }, }; -#undef FILE_DESCRIPTION_RO -#undef FILE_DESCRIPTION_RW - static int acpi_battery_add_fs(struct acpi_device *device) { struct proc_dir_entry *entry = NULL; @@ -670,51 +832,25 @@ static int acpi_battery_add_fs(struct acpi_device *device) entry->owner = THIS_MODULE; } } + return 0; } -static void acpi_battery_remove_fs(struct acpi_device *device) +static int acpi_battery_remove_fs(struct acpi_device *device) { int i; - if (!acpi_device_dir(device)) - return; - for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) - remove_proc_entry(acpi_battery_file[i].name, + if (acpi_device_dir(device)) { + for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) { + remove_proc_entry(acpi_battery_file[i].name, acpi_device_dir(device)); + } + remove_proc_entry(acpi_device_bid(device), acpi_battery_dir); + acpi_device_dir(device) = NULL; + } - remove_proc_entry(acpi_device_bid(device), acpi_battery_dir); - acpi_device_dir(device) = NULL; -} - -#endif - -static ssize_t acpi_battery_alarm_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev)); - return sprintf(buf, "%d\n", battery->alarm * 1000); -} - -static ssize_t acpi_battery_alarm_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - unsigned long x; - struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev)); - if (sscanf(buf, "%ld\n", &x) == 1) - battery->alarm = x/1000; - if (acpi_battery_present(battery)) - acpi_battery_set_alarm(battery); - return count; + return 0; } -static struct device_attribute alarm_attr = { - .attr = {.name = "alarm", .mode = 0644, .owner = THIS_MODULE}, - .show = acpi_battery_alarm_show, - .store = acpi_battery_alarm_store, -}; - /* -------------------------------------------------------------------------- Driver Interface -------------------------------------------------------------------------- */ @@ -722,17 +858,33 @@ static struct device_attribute alarm_attr = { static void acpi_battery_notify(acpi_handle handle, u32 event, void *data) { struct acpi_battery *battery = data; - struct acpi_device *device; + struct acpi_device *device = NULL; + if (!battery) return; + device = battery->device; - acpi_battery_update(battery); - acpi_bus_generate_proc_event(device, event, - acpi_battery_present(battery)); - acpi_bus_generate_netlink_event(device->pnp.device_class, - device->dev.bus_id, event, + + switch (event) { + case ACPI_BATTERY_NOTIFY_STATUS: + case ACPI_BATTERY_NOTIFY_INFO: + case ACPI_NOTIFY_BUS_CHECK: + case ACPI_NOTIFY_DEVICE_CHECK: + device = battery->device; + acpi_battery_notify_update(battery); + acpi_bus_generate_proc_event(device, event, acpi_battery_present(battery)); - kobject_uevent(&battery->bat.dev->kobj, KOBJ_CHANGE); + acpi_bus_generate_netlink_event(device->pnp.device_class, + device->dev.bus_id, event, + acpi_battery_present(battery)); + break; + default: + ACPI_DEBUG_PRINT((ACPI_DB_INFO, + "Unsupported event [0x%x]\n", event)); + break; + } + + return; } static int acpi_battery_add(struct acpi_device *device) @@ -740,27 +892,33 @@ static int acpi_battery_add(struct acpi_device *device) int result = 0; acpi_status status = 0; struct acpi_battery *battery = NULL; + if (!device) return -EINVAL; + battery = kzalloc(sizeof(struct acpi_battery), GFP_KERNEL); if (!battery) return -ENOMEM; + + mutex_init(&battery->mutex); + + mutex_lock(&battery->mutex); + battery->device = device; strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME); strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS); acpi_driver_data(device) = battery; - mutex_init(&battery->lock); - acpi_battery_update(battery); -#ifdef CONFIG_ACPI_PROCFS + + result = acpi_battery_get_status(battery); + if (result) + goto end; + + battery->flags.init_update = 1; + result = acpi_battery_add_fs(device); if (result) goto end; -#endif - battery->bat.name = acpi_device_bid(device); - battery->bat.type = POWER_SUPPLY_TYPE_BATTERY; - battery->bat.get_property = acpi_battery_get_property; - result = power_supply_register(&battery->device->dev, &battery->bat); - result = device_create_file(battery->bat.dev, &alarm_attr); + status = acpi_install_notify_handler(device->handle, ACPI_ALL_NOTIFY, acpi_battery_notify, battery); @@ -769,16 +927,20 @@ static int acpi_battery_add(struct acpi_device *device) result = -ENODEV; goto end; } + printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n", ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device), device->status.battery_present ? "present" : "absent"); + end: + if (result) { -#ifdef CONFIG_ACPI_PROCFS acpi_battery_remove_fs(device); -#endif kfree(battery); } + + mutex_unlock(&battery->mutex); + return result; } @@ -789,19 +951,27 @@ static int acpi_battery_remove(struct acpi_device *device, int type) if (!device || !acpi_driver_data(device)) return -EINVAL; + battery = acpi_driver_data(device); + + mutex_lock(&battery->mutex); + status = acpi_remove_notify_handler(device->handle, ACPI_ALL_NOTIFY, acpi_battery_notify); -#ifdef CONFIG_ACPI_PROCFS + acpi_battery_remove_fs(device); -#endif - if (battery->bat.dev) { - device_remove_file(battery->bat.dev, &alarm_attr); - power_supply_unregister(&battery->bat); - } - mutex_destroy(&battery->lock); + + kfree(battery->bif_data.pointer); + + kfree(battery->bst_data.pointer); + + mutex_unlock(&battery->mutex); + + mutex_destroy(&battery->mutex); + kfree(battery); + return 0; } @@ -809,48 +979,44 @@ static int acpi_battery_remove(struct acpi_device *device, int type) static int acpi_battery_resume(struct acpi_device *device) { struct acpi_battery *battery; + if (!device) return -EINVAL; - battery = acpi_driver_data(device); - battery->update_time = 0; + + battery = device->driver_data; + + battery->flags.init_update = 1; + return 0; } -static struct acpi_driver acpi_battery_driver = { - .name = "battery", - .class = ACPI_BATTERY_CLASS, - .ids = battery_device_ids, - .ops = { - .add = acpi_battery_add, - .resume = acpi_battery_resume, - .remove = acpi_battery_remove, - }, -}; - static int __init acpi_battery_init(void) { + int result; + if (acpi_disabled) return -ENODEV; -#ifdef CONFIG_ACPI_PROCFS + acpi_battery_dir = acpi_lock_battery_dir(); if (!acpi_battery_dir) return -ENODEV; -#endif - if (acpi_bus_register_driver(&acpi_battery_driver) < 0) { -#ifdef CONFIG_ACPI_PROCFS + + result = acpi_bus_register_driver(&acpi_battery_driver); + if (result < 0) { acpi_unlock_battery_dir(acpi_battery_dir); -#endif return -ENODEV; } + return 0; } static void __exit acpi_battery_exit(void) { acpi_bus_unregister_driver(&acpi_battery_driver); -#ifdef CONFIG_ACPI_PROCFS + acpi_unlock_battery_dir(acpi_battery_dir); -#endif + + return; } module_init(acpi_battery_init); diff --git a/trunk/drivers/acpi/bus.c b/trunk/drivers/acpi/bus.c index fb2cff9a2d24..cbfc81579c9a 100644 --- a/trunk/drivers/acpi/bus.c +++ b/trunk/drivers/acpi/bus.c @@ -286,11 +286,15 @@ DECLARE_WAIT_QUEUE_HEAD(acpi_bus_event_queue); extern int event_is_open; -int acpi_bus_generate_proc_event4(const char *device_class, const char *bus_id, u8 type, int data) +int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data) { - struct acpi_bus_event *event; + struct acpi_bus_event *event = NULL; unsigned long flags = 0; + + if (!device) + return -EINVAL; + /* drop event on the floor if no one's listening */ if (!event_is_open) return 0; @@ -299,8 +303,8 @@ int acpi_bus_generate_proc_event4(const char *device_class, const char *bus_id, if (!event) return -ENOMEM; - strcpy(event->device_class, device_class); - strcpy(event->bus_id, bus_id); + strcpy(event->device_class, device->pnp.device_class); + strcpy(event->bus_id, device->pnp.bus_id); event->type = type; event->data = data; @@ -311,17 +315,6 @@ int acpi_bus_generate_proc_event4(const char *device_class, const char *bus_id, wake_up_interruptible(&acpi_bus_event_queue); return 0; - -} - -EXPORT_SYMBOL_GPL(acpi_bus_generate_proc_event4); - -int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data) -{ - if (!device) - return -EINVAL; - return acpi_bus_generate_proc_event4(device->pnp.device_class, - device->pnp.bus_id, type, data); } EXPORT_SYMBOL(acpi_bus_generate_proc_event); diff --git a/trunk/drivers/acpi/button.c b/trunk/drivers/acpi/button.c index 301e832e6961..2e79a3395ecf 100644 --- a/trunk/drivers/acpi/button.c +++ b/trunk/drivers/acpi/button.c @@ -434,18 +434,18 @@ static int acpi_button_add(struct acpi_device *device) switch (button->type) { case ACPI_BUTTON_TYPE_POWER: case ACPI_BUTTON_TYPE_POWERF: - input->evbit[0] = BIT_MASK(EV_KEY); + input->evbit[0] = BIT(EV_KEY); set_bit(KEY_POWER, input->keybit); break; case ACPI_BUTTON_TYPE_SLEEP: case ACPI_BUTTON_TYPE_SLEEPF: - input->evbit[0] = BIT_MASK(EV_KEY); + input->evbit[0] = BIT(EV_KEY); set_bit(KEY_SLEEP, input->keybit); break; case ACPI_BUTTON_TYPE_LID: - input->evbit[0] = BIT_MASK(EV_SW); + input->evbit[0] = BIT(EV_SW); set_bit(SW_LID, input->swbit); break; } diff --git a/trunk/drivers/acpi/ec.c b/trunk/drivers/acpi/ec.c index 7b4178393e34..3f7935ab0cf5 100644 --- a/trunk/drivers/acpi/ec.c +++ b/trunk/drivers/acpi/ec.c @@ -121,7 +121,6 @@ static struct acpi_ec { atomic_t event_count; wait_queue_head_t wait; struct list_head list; - u8 handlers_installed; } *boot_ec, *first_ec; /* -------------------------------------------------------------------------- @@ -426,7 +425,7 @@ int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit, handler->func = func; handler->data = data; mutex_lock(&ec->lock); - list_add(&handler->node, &ec->list); + list_add_tail(&handler->node, &ec->list); mutex_unlock(&ec->lock); return 0; } @@ -441,6 +440,7 @@ void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit) if (query_bit == handler->query_bit) { list_del(&handler->node); kfree(handler); + break; } } mutex_unlock(&ec->lock); @@ -680,24 +680,20 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval) status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec->gpe); if (ACPI_FAILURE(status)) return status; + /* Find and register all query methods */ acpi_walk_namespace(ACPI_TYPE_METHOD, handle, 1, acpi_ec_register_query_methods, ec, NULL); + /* Use the global lock for all EC transactions? */ acpi_evaluate_integer(handle, "_GLK", NULL, &ec->global_lock); + ec->handle = handle; - return AE_CTRL_TERMINATE; -} -static void ec_remove_handlers(struct acpi_ec *ec) -{ - if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle, - ACPI_ADR_SPACE_EC, &acpi_ec_space_handler))) - printk(KERN_ERR PREFIX "failed to remove space handler\n"); - if (ACPI_FAILURE(acpi_remove_gpe_handler(NULL, ec->gpe, - &acpi_ec_gpe_handler))) - printk(KERN_ERR PREFIX "failed to remove gpe handler\n"); - ec->handlers_installed = 0; + printk(KERN_INFO PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n", + ec->gpe, ec->command_addr, ec->data_addr); + + return AE_CTRL_TERMINATE; } static int acpi_ec_add(struct acpi_device *device) @@ -706,24 +702,10 @@ static int acpi_ec_add(struct acpi_device *device) if (!device) return -EINVAL; + strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME); strcpy(acpi_device_class(device), ACPI_EC_CLASS); - /* Check for boot EC */ - if (boot_ec) { - if (boot_ec->handle == device->handle) { - /* Pre-loaded EC from DSDT, just move pointer */ - ec = boot_ec; - boot_ec = NULL; - goto end; - } else if (boot_ec->handle == ACPI_ROOT_OBJECT) { - /* ECDT-based EC, time to shut it down */ - ec_remove_handlers(boot_ec); - kfree(boot_ec); - first_ec = boot_ec = NULL; - } - } - ec = make_acpi_ec(); if (!ec) return -ENOMEM; @@ -733,14 +715,25 @@ static int acpi_ec_add(struct acpi_device *device) kfree(ec); return -EINVAL; } - ec->handle = device->handle; - end: - if (!first_ec) + + /* Check if we found the boot EC */ + if (boot_ec) { + if (boot_ec->gpe == ec->gpe) { + /* We might have incorrect info for GL at boot time */ + mutex_lock(&boot_ec->lock); + boot_ec->global_lock = ec->global_lock; + /* Copy handlers from new ec into boot ec */ + list_splice(&ec->list, &boot_ec->list); + mutex_unlock(&boot_ec->lock); + kfree(ec); + ec = boot_ec; + } + } else first_ec = ec; + ec->handle = device->handle; acpi_driver_data(device) = ec; + acpi_ec_add_fs(device); - printk(KERN_INFO PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n", - ec->gpe, ec->command_addr, ec->data_addr); return 0; } @@ -763,7 +756,10 @@ static int acpi_ec_remove(struct acpi_device *device, int type) acpi_driver_data(device) = NULL; if (ec == first_ec) first_ec = NULL; - kfree(ec); + + /* Don't touch boot EC */ + if (boot_ec != ec) + kfree(ec); return 0; } @@ -793,8 +789,6 @@ ec_parse_io_ports(struct acpi_resource *resource, void *context) static int ec_install_handlers(struct acpi_ec *ec) { acpi_status status; - if (ec->handlers_installed) - return 0; status = acpi_install_gpe_handler(NULL, ec->gpe, ACPI_GPE_EDGE_TRIGGERED, &acpi_ec_gpe_handler, ec); @@ -813,7 +807,6 @@ static int ec_install_handlers(struct acpi_ec *ec) return -ENODEV; } - ec->handlers_installed = 1; return 0; } @@ -830,22 +823,41 @@ static int acpi_ec_start(struct acpi_device *device) if (!ec) return -EINVAL; - ret = ec_install_handlers(ec); + /* Boot EC is already working */ + if (ec != boot_ec) + ret = ec_install_handlers(ec); /* EC is fully operational, allow queries */ atomic_set(&ec->query_pending, 0); + return ret; } static int acpi_ec_stop(struct acpi_device *device, int type) { + acpi_status status; struct acpi_ec *ec; + if (!device) return -EINVAL; + ec = acpi_driver_data(device); if (!ec) return -EINVAL; - ec_remove_handlers(ec); + + /* Don't touch boot EC */ + if (ec == boot_ec) + return 0; + + status = acpi_remove_address_space_handler(ec->handle, + ACPI_ADR_SPACE_EC, + &acpi_ec_space_handler); + if (ACPI_FAILURE(status)) + return -ENODEV; + + status = acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler); + if (ACPI_FAILURE(status)) + return -ENODEV; return 0; } @@ -865,7 +877,7 @@ int __init acpi_ec_ecdt_probe(void) status = acpi_get_table(ACPI_SIG_ECDT, 1, (struct acpi_table_header **)&ecdt_ptr); if (ACPI_SUCCESS(status)) { - printk(KERN_INFO PREFIX "EC description table is found, configuring boot EC\n"); + printk(KERN_INFO PREFIX "EC description table is found, configuring boot EC\n\n"); boot_ec->command_addr = ecdt_ptr->control.address; boot_ec->data_addr = ecdt_ptr->data.address; boot_ec->gpe = ecdt_ptr->gpe; @@ -887,6 +899,7 @@ int __init acpi_ec_ecdt_probe(void) error: kfree(boot_ec); boot_ec = NULL; + return -ENODEV; } diff --git a/trunk/drivers/acpi/events/evevent.c b/trunk/drivers/acpi/events/evevent.c index e41287815ea1..a1f87b5def2a 100644 --- a/trunk/drivers/acpi/events/evevent.c +++ b/trunk/drivers/acpi/events/evevent.c @@ -239,8 +239,10 @@ u32 acpi_ev_fixed_event_detect(void) * Read the fixed feature status and enable registers, as all the cases * depend on their values. Ignore errors here. */ - (void)acpi_hw_register_read(ACPI_REGISTER_PM1_STATUS, &fixed_status); - (void)acpi_hw_register_read(ACPI_REGISTER_PM1_ENABLE, &fixed_enable); + (void)acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK, + ACPI_REGISTER_PM1_STATUS, &fixed_status); + (void)acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK, + ACPI_REGISTER_PM1_ENABLE, &fixed_enable); ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS, "Fixed Event Block: Enable %08X Status %08X\n", diff --git a/trunk/drivers/acpi/hardware/hwregs.c b/trunk/drivers/acpi/hardware/hwregs.c index 73f9c5fb1ba7..1d371fa663f2 100644 --- a/trunk/drivers/acpi/hardware/hwregs.c +++ b/trunk/drivers/acpi/hardware/hwregs.c @@ -75,7 +75,8 @@ acpi_status acpi_hw_clear_acpi_status(void) lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); - status = acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS, + status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, + ACPI_REGISTER_PM1_STATUS, ACPI_BITMASK_ALL_FIXED_STATUS); if (ACPI_FAILURE(status)) { goto unlock_and_exit; @@ -258,7 +259,7 @@ struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id) * ******************************************************************************/ -acpi_status acpi_get_register_unlocked(u32 register_id, u32 * return_value) +acpi_status acpi_get_register(u32 register_id, u32 * return_value) { u32 register_value = 0; struct acpi_bit_register_info *bit_reg_info; @@ -275,7 +276,8 @@ acpi_status acpi_get_register_unlocked(u32 register_id, u32 * return_value) /* Read from the register */ - status = acpi_hw_register_read(bit_reg_info->parent_register, + status = acpi_hw_register_read(ACPI_MTX_LOCK, + bit_reg_info->parent_register, ®ister_value); if (ACPI_SUCCESS(status)) { @@ -296,16 +298,6 @@ acpi_status acpi_get_register_unlocked(u32 register_id, u32 * return_value) return_ACPI_STATUS(status); } -acpi_status acpi_get_register(u32 register_id, u32 * return_value) -{ - acpi_status status; - acpi_cpu_flags flags; - flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); - status = acpi_get_register_unlocked(register_id, return_value); - acpi_os_release_lock(acpi_gbl_hardware_lock, flags); - return status; -} - ACPI_EXPORT_SYMBOL(acpi_get_register) /******************************************************************************* @@ -343,7 +335,8 @@ acpi_status acpi_set_register(u32 register_id, u32 value) /* Always do a register read first so we can insert the new bits */ - status = acpi_hw_register_read(bit_reg_info->parent_register, + status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK, + bit_reg_info->parent_register, ®ister_value); if (ACPI_FAILURE(status)) { goto unlock_and_exit; @@ -370,7 +363,8 @@ acpi_status acpi_set_register(u32 register_id, u32 value) bit_reg_info-> access_bit_mask); if (value) { - status = acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS, + status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, + ACPI_REGISTER_PM1_STATUS, (u16) value); register_value = 0; } @@ -383,7 +377,8 @@ acpi_status acpi_set_register(u32 register_id, u32 value) bit_reg_info->access_bit_mask, value); - status = acpi_hw_register_write(ACPI_REGISTER_PM1_ENABLE, + status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, + ACPI_REGISTER_PM1_ENABLE, (u16) register_value); break; @@ -402,13 +397,15 @@ acpi_status acpi_set_register(u32 register_id, u32 value) bit_reg_info->access_bit_mask, value); - status = acpi_hw_register_write(ACPI_REGISTER_PM1_CONTROL, + status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, + ACPI_REGISTER_PM1_CONTROL, (u16) register_value); break; case ACPI_REGISTER_PM2_CONTROL: - status = acpi_hw_register_read(ACPI_REGISTER_PM2_CONTROL, + status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK, + ACPI_REGISTER_PM2_CONTROL, ®ister_value); if (ACPI_FAILURE(status)) { goto unlock_and_exit; @@ -433,7 +430,8 @@ acpi_status acpi_set_register(u32 register_id, u32 value) xpm2_control_block. address))); - status = acpi_hw_register_write(ACPI_REGISTER_PM2_CONTROL, + status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, + ACPI_REGISTER_PM2_CONTROL, (u8) (register_value)); break; @@ -463,7 +461,8 @@ ACPI_EXPORT_SYMBOL(acpi_set_register) * * FUNCTION: acpi_hw_register_read * - * PARAMETERS: register_id - ACPI Register ID + * PARAMETERS: use_lock - Lock hardware? True/False + * register_id - ACPI Register ID * return_value - Where the register value is returned * * RETURN: Status and the value read. @@ -472,14 +471,19 @@ ACPI_EXPORT_SYMBOL(acpi_set_register) * ******************************************************************************/ acpi_status -acpi_hw_register_read(u32 register_id, u32 * return_value) +acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value) { u32 value1 = 0; u32 value2 = 0; acpi_status status; + acpi_cpu_flags lock_flags = 0; ACPI_FUNCTION_TRACE(hw_register_read); + if (ACPI_MTX_LOCK == use_lock) { + lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); + } + switch (register_id) { case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */ @@ -487,7 +491,7 @@ acpi_hw_register_read(u32 register_id, u32 * return_value) acpi_hw_low_level_read(16, &value1, &acpi_gbl_FADT.xpm1a_event_block); if (ACPI_FAILURE(status)) { - goto exit; + goto unlock_and_exit; } /* PM1B is optional */ @@ -503,7 +507,7 @@ acpi_hw_register_read(u32 register_id, u32 * return_value) status = acpi_hw_low_level_read(16, &value1, &acpi_gbl_xpm1a_enable); if (ACPI_FAILURE(status)) { - goto exit; + goto unlock_and_exit; } /* PM1B is optional */ @@ -519,7 +523,7 @@ acpi_hw_register_read(u32 register_id, u32 * return_value) acpi_hw_low_level_read(16, &value1, &acpi_gbl_FADT.xpm1a_control_block); if (ACPI_FAILURE(status)) { - goto exit; + goto unlock_and_exit; } status = @@ -554,7 +558,10 @@ acpi_hw_register_read(u32 register_id, u32 * return_value) break; } - exit: + unlock_and_exit: + if (ACPI_MTX_LOCK == use_lock) { + acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags); + } if (ACPI_SUCCESS(status)) { *return_value = value1; @@ -567,7 +574,8 @@ acpi_hw_register_read(u32 register_id, u32 * return_value) * * FUNCTION: acpi_hw_register_write * - * PARAMETERS: register_id - ACPI Register ID + * PARAMETERS: use_lock - Lock hardware? True/False + * register_id - ACPI Register ID * Value - The value to write * * RETURN: Status @@ -589,22 +597,28 @@ acpi_hw_register_read(u32 register_id, u32 * return_value) * ******************************************************************************/ -acpi_status acpi_hw_register_write(u32 register_id, u32 value) +acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value) { acpi_status status; + acpi_cpu_flags lock_flags = 0; u32 read_value; ACPI_FUNCTION_TRACE(hw_register_write); + if (ACPI_MTX_LOCK == use_lock) { + lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); + } + switch (register_id) { case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */ /* Perform a read first to preserve certain bits (per ACPI spec) */ - status = acpi_hw_register_read(ACPI_REGISTER_PM1_STATUS, + status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK, + ACPI_REGISTER_PM1_STATUS, &read_value); if (ACPI_FAILURE(status)) { - goto exit; + goto unlock_and_exit; } /* Insert the bits to be preserved */ @@ -618,7 +632,7 @@ acpi_status acpi_hw_register_write(u32 register_id, u32 value) acpi_hw_low_level_write(16, value, &acpi_gbl_FADT.xpm1a_event_block); if (ACPI_FAILURE(status)) { - goto exit; + goto unlock_and_exit; } /* PM1B is optional */ @@ -633,7 +647,7 @@ acpi_status acpi_hw_register_write(u32 register_id, u32 value) status = acpi_hw_low_level_write(16, value, &acpi_gbl_xpm1a_enable); if (ACPI_FAILURE(status)) { - goto exit; + goto unlock_and_exit; } /* PM1B is optional */ @@ -647,10 +661,11 @@ acpi_status acpi_hw_register_write(u32 register_id, u32 value) /* * Perform a read first to preserve certain bits (per ACPI spec) */ - status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL, + status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK, + ACPI_REGISTER_PM1_CONTROL, &read_value); if (ACPI_FAILURE(status)) { - goto exit; + goto unlock_and_exit; } /* Insert the bits to be preserved */ @@ -664,7 +679,7 @@ acpi_status acpi_hw_register_write(u32 register_id, u32 value) acpi_hw_low_level_write(16, value, &acpi_gbl_FADT.xpm1a_control_block); if (ACPI_FAILURE(status)) { - goto exit; + goto unlock_and_exit; } status = @@ -713,7 +728,11 @@ acpi_status acpi_hw_register_write(u32 register_id, u32 value) break; } - exit: + unlock_and_exit: + if (ACPI_MTX_LOCK == use_lock) { + acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags); + } + return_ACPI_STATUS(status); } diff --git a/trunk/drivers/acpi/hardware/hwsleep.c b/trunk/drivers/acpi/hardware/hwsleep.c index 81b248429703..cf69c0040a39 100644 --- a/trunk/drivers/acpi/hardware/hwsleep.c +++ b/trunk/drivers/acpi/hardware/hwsleep.c @@ -234,11 +234,15 @@ acpi_status acpi_enter_sleep_state_prep(u8 sleep_state) "While executing method _SST")); } - /* Disable/Clear all GPEs */ - + /* + * 1) Disable/Clear all GPEs + */ status = acpi_hw_disable_all_gpes(); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } - return_ACPI_STATUS(status); + return_ACPI_STATUS(AE_OK); } ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep) @@ -309,7 +313,8 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) /* Get current value of PM1A control */ - status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol); + status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK, + ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } @@ -336,13 +341,15 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) /* Write #1: fill in SLP_TYP data */ - status = acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL, + status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, + ACPI_REGISTER_PM1A_CONTROL, PM1Acontrol); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } - status = acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL, + status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, + ACPI_REGISTER_PM1B_CONTROL, PM1Bcontrol); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); @@ -357,13 +364,15 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) ACPI_FLUSH_CPU_CACHE(); - status = acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL, + status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, + ACPI_REGISTER_PM1A_CONTROL, PM1Acontrol); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } - status = acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL, + status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, + ACPI_REGISTER_PM1B_CONTROL, PM1Bcontrol); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); @@ -383,7 +392,8 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) */ acpi_os_stall(10000000); - status = acpi_hw_register_write(ACPI_REGISTER_PM1_CONTROL, + status = acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, + ACPI_REGISTER_PM1_CONTROL, sleep_enable_reg_info-> access_bit_mask); if (ACPI_FAILURE(status)) { @@ -394,8 +404,7 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) /* Wait until we enter sleep state */ do { - status = acpi_get_register_unlocked(ACPI_BITREG_WAKE_STATUS, - &in_value); + status = acpi_get_register(ACPI_BITREG_WAKE_STATUS, &in_value); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } @@ -511,7 +520,8 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state) /* Get current value of PM1A control */ - status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL, + status = acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK, + ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol); if (ACPI_SUCCESS(status)) { @@ -533,9 +543,11 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state) /* Just ignore any errors */ - (void)acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL, + (void)acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, + ACPI_REGISTER_PM1A_CONTROL, PM1Acontrol); - (void)acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL, + (void)acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK, + ACPI_REGISTER_PM1B_CONTROL, PM1Bcontrol); } } diff --git a/trunk/drivers/acpi/osl.c b/trunk/drivers/acpi/osl.c index aabc6ca4a81c..352cf81af581 100644 --- a/trunk/drivers/acpi/osl.c +++ b/trunk/drivers/acpi/osl.c @@ -1042,6 +1042,14 @@ static int __init acpi_wake_gpes_always_on_setup(char *str) __setup("acpi_wake_gpes_always_on", acpi_wake_gpes_always_on_setup); +/* + * max_cstate is defined in the base kernel so modules can + * change it w/o depending on the state of the processor module. + */ +unsigned int max_cstate = ACPI_PROCESSOR_MAX_POWER; + +EXPORT_SYMBOL(max_cstate); + /* * Acquire a spinlock. * diff --git a/trunk/drivers/acpi/processor_core.c b/trunk/drivers/acpi/processor_core.c index a7351084f2f8..9f11dc296cdd 100644 --- a/trunk/drivers/acpi/processor_core.c +++ b/trunk/drivers/acpi/processor_core.c @@ -44,7 +44,6 @@ #include #include #include -#include #include #include @@ -1050,13 +1049,11 @@ static int __init acpi_processor_init(void) return -ENOMEM; acpi_processor_dir->owner = THIS_MODULE; - result = cpuidle_register_driver(&acpi_idle_driver); - if (result < 0) - goto out_proc; - result = acpi_bus_register_driver(&acpi_processor_driver); - if (result < 0) - goto out_cpuidle; + if (result < 0) { + remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); + return result; + } acpi_processor_install_hotplug_notify(); @@ -1065,18 +1062,11 @@ static int __init acpi_processor_init(void) acpi_processor_ppc_init(); return 0; - -out_cpuidle: - cpuidle_unregister_driver(&acpi_idle_driver); - -out_proc: - remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); - - return result; } static void __exit acpi_processor_exit(void) { + acpi_processor_ppc_exit(); acpi_thermal_cpufreq_exit(); @@ -1085,8 +1075,6 @@ static void __exit acpi_processor_exit(void) acpi_bus_unregister_driver(&acpi_processor_driver); - cpuidle_unregister_driver(&acpi_idle_driver); - remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); return; diff --git a/trunk/drivers/acpi/processor_idle.c b/trunk/drivers/acpi/processor_idle.c index f996d0e37689..1f6fb38de017 100644 --- a/trunk/drivers/acpi/processor_idle.c +++ b/trunk/drivers/acpi/processor_idle.c @@ -40,7 +40,6 @@ #include /* need_resched() */ #include #include -#include /* * Include the apic definitions for x86 to have the APIC timer related defines @@ -65,22 +64,14 @@ ACPI_MODULE_NAME("processor_idle"); #define ACPI_PROCESSOR_FILE_POWER "power" #define US_TO_PM_TIMER_TICKS(t) ((t * (PM_TIMER_FREQUENCY/1000)) / 1000) #define PM_TIMER_TICK_NS (1000000000ULL/PM_TIMER_FREQUENCY) -#ifndef CONFIG_CPU_IDLE #define C2_OVERHEAD 4 /* 1us (3.579 ticks per us) */ #define C3_OVERHEAD 4 /* 1us (3.579 ticks per us) */ static void (*pm_idle_save) (void) __read_mostly; -#else -#define C2_OVERHEAD 1 /* 1us */ -#define C3_OVERHEAD 1 /* 1us */ -#endif -#define PM_TIMER_TICKS_TO_US(p) (((p) * 1000)/(PM_TIMER_FREQUENCY/1000)) +module_param(max_cstate, uint, 0644); -static unsigned int max_cstate __read_mostly = ACPI_PROCESSOR_MAX_POWER; -module_param(max_cstate, uint, 0000); static unsigned int nocst __read_mostly; module_param(nocst, uint, 0000); -#ifndef CONFIG_CPU_IDLE /* * bm_history -- bit-mask with a bit per jiffy of bus-master activity * 1000 HZ: 0xFFFFFFFF: 32 jiffies = 32ms @@ -91,10 +82,9 @@ module_param(nocst, uint, 0000); static unsigned int bm_history __read_mostly = (HZ >= 800 ? 0xFFFFFFFF : ((1U << (HZ / 25)) - 1)); module_param(bm_history, uint, 0644); - -static int acpi_processor_set_power_policy(struct acpi_processor *pr); - -#endif +/* -------------------------------------------------------------------------- + Power Management + -------------------------------------------------------------------------- */ /* * IBM ThinkPad R40e crashes mysteriously when going into C2 or C3. @@ -187,18 +177,6 @@ static inline u32 ticks_elapsed(u32 t1, u32 t2) return ((0xFFFFFFFF - t1) + t2); } -static inline u32 ticks_elapsed_in_us(u32 t1, u32 t2) -{ - if (t2 >= t1) - return PM_TIMER_TICKS_TO_US(t2 - t1); - else if (!(acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER)) - return PM_TIMER_TICKS_TO_US(((0x00FFFFFF - t1) + t2) & 0x00FFFFFF); - else - return PM_TIMER_TICKS_TO_US((0xFFFFFFFF - t1) + t2); -} - -#ifndef CONFIG_CPU_IDLE - static void acpi_processor_power_activate(struct acpi_processor *pr, struct acpi_processor_cx *new) @@ -270,7 +248,6 @@ static void acpi_cstate_enter(struct acpi_processor_cx *cstate) unused = inl(acpi_gbl_FADT.xpm_timer_block.address); } } -#endif /* !CONFIG_CPU_IDLE */ #ifdef ARCH_APICTIMER_STOPS_ON_C3 @@ -353,7 +330,6 @@ int acpi_processor_resume(struct acpi_device * device) return 0; } -#ifndef CONFIG_CPU_IDLE static void acpi_processor_idle(void) { struct acpi_processor *pr = NULL; @@ -451,7 +427,7 @@ static void acpi_processor_idle(void) * an SMP system. We do it here instead of doing it at _CST/P_LVL * detection phase, to work cleanly with logical CPU hotplug. */ - if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) && + if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) && !pr->flags.has_cst && !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED)) cx = &pr->power.states[ACPI_STATE_C1]; #endif @@ -751,7 +727,6 @@ static int acpi_processor_set_power_policy(struct acpi_processor *pr) return 0; } -#endif /* !CONFIG_CPU_IDLE */ static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr) { @@ -769,7 +744,7 @@ static int acpi_processor_get_power_info_fadt(struct acpi_processor *pr) #ifndef CONFIG_HOTPLUG_CPU /* * Check for P_LVL2_UP flag before entering C2 and above on - * an SMP system. + * an SMP system. */ if ((num_online_cpus() > 1) && !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED)) @@ -970,12 +945,7 @@ static void acpi_processor_power_verify_c2(struct acpi_processor_cx *cx) * Normalize the C2 latency to expidite policy */ cx->valid = 1; - -#ifndef CONFIG_CPU_IDLE cx->latency_ticks = US_TO_PM_TIMER_TICKS(cx->latency); -#else - cx->latency_ticks = cx->latency; -#endif return; } @@ -1055,12 +1025,7 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr, * use this in our C3 policy */ cx->valid = 1; - -#ifndef CONFIG_CPU_IDLE cx->latency_ticks = US_TO_PM_TIMER_TICKS(cx->latency); -#else - cx->latency_ticks = cx->latency; -#endif return; } @@ -1125,7 +1090,6 @@ static int acpi_processor_get_power_info(struct acpi_processor *pr) pr->power.count = acpi_processor_power_verify(pr); -#ifndef CONFIG_CPU_IDLE /* * Set Default Policy * ------------------ @@ -1137,7 +1101,6 @@ static int acpi_processor_get_power_info(struct acpi_processor *pr) result = acpi_processor_set_power_policy(pr); if (result) return result; -#endif /* * if one state of type C2 or C3 is available, mark this @@ -1154,6 +1117,35 @@ static int acpi_processor_get_power_info(struct acpi_processor *pr) return 0; } +int acpi_processor_cst_has_changed(struct acpi_processor *pr) +{ + int result = 0; + + + if (!pr) + return -EINVAL; + + if (nocst) { + return -ENODEV; + } + + if (!pr->flags.power_setup_done) + return -ENODEV; + + /* Fall back to the default idle loop */ + pm_idle = pm_idle_save; + synchronize_sched(); /* Relies on interrupts forcing exit from idle. */ + + pr->flags.power = 0; + result = acpi_processor_get_power_info(pr); + if ((pr->flags.power == 1) && (pr->flags.power_setup_done)) + pm_idle = acpi_processor_idle; + + return result; +} + +/* proc interface */ + static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset) { struct acpi_processor *pr = seq->private; @@ -1235,35 +1227,6 @@ static const struct file_operations acpi_processor_power_fops = { .release = single_release, }; -#ifndef CONFIG_CPU_IDLE - -int acpi_processor_cst_has_changed(struct acpi_processor *pr) -{ - int result = 0; - - - if (!pr) - return -EINVAL; - - if (nocst) { - return -ENODEV; - } - - if (!pr->flags.power_setup_done) - return -ENODEV; - - /* Fall back to the default idle loop */ - pm_idle = pm_idle_save; - synchronize_sched(); /* Relies on interrupts forcing exit from idle. */ - - pr->flags.power = 0; - result = acpi_processor_get_power_info(pr); - if ((pr->flags.power == 1) && (pr->flags.power_setup_done)) - pm_idle = acpi_processor_idle; - - return result; -} - #ifdef CONFIG_SMP static void smp_callback(void *v) { @@ -1286,366 +1249,7 @@ static int acpi_processor_latency_notify(struct notifier_block *b, static struct notifier_block acpi_processor_latency_notifier = { .notifier_call = acpi_processor_latency_notify, }; - -#endif - -#else /* CONFIG_CPU_IDLE */ - -/** - * acpi_idle_bm_check - checks if bus master activity was detected - */ -static int acpi_idle_bm_check(void) -{ - u32 bm_status = 0; - - acpi_get_register(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status); - if (bm_status) - acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS, 1); - /* - * PIIX4 Erratum #18: Note that BM_STS doesn't always reflect - * the true state of bus mastering activity; forcing us to - * manually check the BMIDEA bit of each IDE channel. - */ - else if (errata.piix4.bmisx) { - if ((inb_p(errata.piix4.bmisx + 0x02) & 0x01) - || (inb_p(errata.piix4.bmisx + 0x0A) & 0x01)) - bm_status = 1; - } - return bm_status; -} - -/** - * acpi_idle_update_bm_rld - updates the BM_RLD bit depending on target state - * @pr: the processor - * @target: the new target state - */ -static inline void acpi_idle_update_bm_rld(struct acpi_processor *pr, - struct acpi_processor_cx *target) -{ - if (pr->flags.bm_rld_set && target->type != ACPI_STATE_C3) { - acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0); - pr->flags.bm_rld_set = 0; - } - - if (!pr->flags.bm_rld_set && target->type == ACPI_STATE_C3) { - acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1); - pr->flags.bm_rld_set = 1; - } -} - -/** - * acpi_idle_do_entry - a helper function that does C2 and C3 type entry - * @cx: cstate data - */ -static inline void acpi_idle_do_entry(struct acpi_processor_cx *cx) -{ - if (cx->space_id == ACPI_CSTATE_FFH) { - /* Call into architectural FFH based C-state */ - acpi_processor_ffh_cstate_enter(cx); - } else { - int unused; - /* IO port based C-state */ - inb(cx->address); - /* Dummy wait op - must do something useless after P_LVL2 read - because chipsets cannot guarantee that STPCLK# signal - gets asserted in time to freeze execution properly. */ - unused = inl(acpi_gbl_FADT.xpm_timer_block.address); - } -} - -/** - * acpi_idle_enter_c1 - enters an ACPI C1 state-type - * @dev: the target CPU - * @state: the state data - * - * This is equivalent to the HALT instruction. - */ -static int acpi_idle_enter_c1(struct cpuidle_device *dev, - struct cpuidle_state *state) -{ - struct acpi_processor *pr; - struct acpi_processor_cx *cx = cpuidle_get_statedata(state); - pr = processors[smp_processor_id()]; - - if (unlikely(!pr)) - return 0; - - if (pr->flags.bm_check) - acpi_idle_update_bm_rld(pr, cx); - - current_thread_info()->status &= ~TS_POLLING; - /* - * TS_POLLING-cleared state must be visible before we test - * NEED_RESCHED: - */ - smp_mb(); - if (!need_resched()) - safe_halt(); - current_thread_info()->status |= TS_POLLING; - - cx->usage++; - - return 0; -} - -/** - * acpi_idle_enter_simple - enters an ACPI state without BM handling - * @dev: the target CPU - * @state: the state data - */ -static int acpi_idle_enter_simple(struct cpuidle_device *dev, - struct cpuidle_state *state) -{ - struct acpi_processor *pr; - struct acpi_processor_cx *cx = cpuidle_get_statedata(state); - u32 t1, t2; - pr = processors[smp_processor_id()]; - - if (unlikely(!pr)) - return 0; - - if (acpi_idle_suspend) - return(acpi_idle_enter_c1(dev, state)); - - if (pr->flags.bm_check) - acpi_idle_update_bm_rld(pr, cx); - - local_irq_disable(); - current_thread_info()->status &= ~TS_POLLING; - /* - * TS_POLLING-cleared state must be visible before we test - * NEED_RESCHED: - */ - smp_mb(); - - if (unlikely(need_resched())) { - current_thread_info()->status |= TS_POLLING; - local_irq_enable(); - return 0; - } - - if (cx->type == ACPI_STATE_C3) - ACPI_FLUSH_CPU_CACHE(); - - t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); - acpi_state_timer_broadcast(pr, cx, 1); - acpi_idle_do_entry(cx); - t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); - -#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC) - /* TSC could halt in idle, so notify users */ - mark_tsc_unstable("TSC halts in idle");; -#endif - - local_irq_enable(); - current_thread_info()->status |= TS_POLLING; - - cx->usage++; - - acpi_state_timer_broadcast(pr, cx, 0); - cx->time += ticks_elapsed(t1, t2); - return ticks_elapsed_in_us(t1, t2); -} - -static int c3_cpu_count; -static DEFINE_SPINLOCK(c3_lock); - -/** - * acpi_idle_enter_bm - enters C3 with proper BM handling - * @dev: the target CPU - * @state: the state data - * - * If BM is detected, the deepest non-C3 idle state is entered instead. - */ -static int acpi_idle_enter_bm(struct cpuidle_device *dev, - struct cpuidle_state *state) -{ - struct acpi_processor *pr; - struct acpi_processor_cx *cx = cpuidle_get_statedata(state); - u32 t1, t2; - pr = processors[smp_processor_id()]; - - if (unlikely(!pr)) - return 0; - - if (acpi_idle_suspend) - return(acpi_idle_enter_c1(dev, state)); - - local_irq_disable(); - current_thread_info()->status &= ~TS_POLLING; - /* - * TS_POLLING-cleared state must be visible before we test - * NEED_RESCHED: - */ - smp_mb(); - - if (unlikely(need_resched())) { - current_thread_info()->status |= TS_POLLING; - local_irq_enable(); - return 0; - } - - /* - * Must be done before busmaster disable as we might need to - * access HPET ! - */ - acpi_state_timer_broadcast(pr, cx, 1); - - if (acpi_idle_bm_check()) { - cx = pr->power.bm_state; - - acpi_idle_update_bm_rld(pr, cx); - - t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); - acpi_idle_do_entry(cx); - t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); - } else { - acpi_idle_update_bm_rld(pr, cx); - - spin_lock(&c3_lock); - c3_cpu_count++; - /* Disable bus master arbitration when all CPUs are in C3 */ - if (c3_cpu_count == num_online_cpus()) - acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1); - spin_unlock(&c3_lock); - - t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); - acpi_idle_do_entry(cx); - t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); - - spin_lock(&c3_lock); - /* Re-enable bus master arbitration */ - if (c3_cpu_count == num_online_cpus()) - acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0); - c3_cpu_count--; - spin_unlock(&c3_lock); - } - -#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC) - /* TSC could halt in idle, so notify users */ - mark_tsc_unstable("TSC halts in idle"); -#endif - - local_irq_enable(); - current_thread_info()->status |= TS_POLLING; - - cx->usage++; - - acpi_state_timer_broadcast(pr, cx, 0); - cx->time += ticks_elapsed(t1, t2); - return ticks_elapsed_in_us(t1, t2); -} - -struct cpuidle_driver acpi_idle_driver = { - .name = "acpi_idle", - .owner = THIS_MODULE, -}; - -/** - * acpi_processor_setup_cpuidle - prepares and configures CPUIDLE - * @pr: the ACPI processor - */ -static int acpi_processor_setup_cpuidle(struct acpi_processor *pr) -{ - int i, count = 0; - struct acpi_processor_cx *cx; - struct cpuidle_state *state; - struct cpuidle_device *dev = &pr->power.dev; - - if (!pr->flags.power_setup_done) - return -EINVAL; - - if (pr->flags.power == 0) { - return -EINVAL; - } - - for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++) { - cx = &pr->power.states[i]; - state = &dev->states[count]; - - if (!cx->valid) - continue; - -#ifdef CONFIG_HOTPLUG_CPU - if ((cx->type != ACPI_STATE_C1) && (num_online_cpus() > 1) && - !pr->flags.has_cst && - !(acpi_gbl_FADT.flags & ACPI_FADT_C2_MP_SUPPORTED)) - continue; #endif - cpuidle_set_statedata(state, cx); - - snprintf(state->name, CPUIDLE_NAME_LEN, "C%d", i); - state->exit_latency = cx->latency; - state->target_residency = cx->latency * 6; - state->power_usage = cx->power; - - state->flags = 0; - switch (cx->type) { - case ACPI_STATE_C1: - state->flags |= CPUIDLE_FLAG_SHALLOW; - state->enter = acpi_idle_enter_c1; - break; - - case ACPI_STATE_C2: - state->flags |= CPUIDLE_FLAG_BALANCED; - state->flags |= CPUIDLE_FLAG_TIME_VALID; - state->enter = acpi_idle_enter_simple; - break; - - case ACPI_STATE_C3: - state->flags |= CPUIDLE_FLAG_DEEP; - state->flags |= CPUIDLE_FLAG_TIME_VALID; - state->flags |= CPUIDLE_FLAG_CHECK_BM; - state->enter = pr->flags.bm_check ? - acpi_idle_enter_bm : - acpi_idle_enter_simple; - break; - } - - count++; - } - - dev->state_count = count; - - if (!count) - return -EINVAL; - - /* find the deepest state that can handle active BM */ - if (pr->flags.bm_check) { - for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++) - if (pr->power.states[i].type == ACPI_STATE_C3) - break; - pr->power.bm_state = &pr->power.states[i-1]; - } - - return 0; -} - -int acpi_processor_cst_has_changed(struct acpi_processor *pr) -{ - int ret; - - if (!pr) - return -EINVAL; - - if (nocst) { - return -ENODEV; - } - - if (!pr->flags.power_setup_done) - return -ENODEV; - - cpuidle_pause_and_lock(); - cpuidle_disable_device(&pr->power.dev); - acpi_processor_get_power_info(pr); - acpi_processor_setup_cpuidle(pr); - ret = cpuidle_enable_device(&pr->power.dev); - cpuidle_resume_and_unlock(); - - return ret; -} - -#endif /* CONFIG_CPU_IDLE */ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, struct acpi_device *device) @@ -1663,7 +1267,7 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, "ACPI: processor limited to max C-state %d\n", max_cstate); first_run++; -#if !defined (CONFIG_CPU_IDLE) && defined (CONFIG_SMP) +#ifdef CONFIG_SMP register_latency_notifier(&acpi_processor_latency_notifier); #endif } @@ -1681,7 +1285,6 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, } acpi_processor_get_power_info(pr); - pr->flags.power_setup_done = 1; /* * Install the idle handler if processor power management is supported. @@ -1689,13 +1292,6 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, * platforms that only support C1. */ if ((pr->flags.power) && (!boot_option_idle_override)) { -#ifdef CONFIG_CPU_IDLE - acpi_processor_setup_cpuidle(pr); - pr->power.dev.cpu = pr->id; - if (cpuidle_register_device(&pr->power.dev)) - return -EIO; -#endif - printk(KERN_INFO PREFIX "CPU%d (power states:", pr->id); for (i = 1; i <= pr->power.count; i++) if (pr->power.states[i].valid) @@ -1703,12 +1299,10 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, pr->power.states[i].type); printk(")\n"); -#ifndef CONFIG_CPU_IDLE if (pr->id == 0) { pm_idle_save = pm_idle; pm_idle = acpi_processor_idle; } -#endif } /* 'power' [R] */ @@ -1722,24 +1316,21 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, entry->owner = THIS_MODULE; } + pr->flags.power_setup_done = 1; + return 0; } int acpi_processor_power_exit(struct acpi_processor *pr, struct acpi_device *device) { -#ifdef CONFIG_CPU_IDLE - if ((pr->flags.power) && (!boot_option_idle_override)) - cpuidle_unregister_device(&pr->power.dev); -#endif + pr->flags.power_setup_done = 0; if (acpi_device_dir(device)) remove_proc_entry(ACPI_PROCESSOR_FILE_POWER, acpi_device_dir(device)); -#ifndef CONFIG_CPU_IDLE - /* Unregister the idle handler when processor #0 is removed. */ if (pr->id == 0) { pm_idle = pm_idle_save; @@ -1754,7 +1345,6 @@ int acpi_processor_power_exit(struct acpi_processor *pr, unregister_latency_notifier(&acpi_processor_latency_notifier); #endif } -#endif return 0; } diff --git a/trunk/drivers/acpi/sbs.c b/trunk/drivers/acpi/sbs.c index 90fd09c65f95..a578986e3214 100644 --- a/trunk/drivers/acpi/sbs.c +++ b/trunk/drivers/acpi/sbs.c @@ -1,8 +1,6 @@ /* - * sbs.c - ACPI Smart Battery System Driver ($Revision: 2.0 $) + * acpi_sbs.c - ACPI Smart Battery System Driver ($Revision: 1.16 $) * - * Copyright (c) 2007 Alexey Starikovskiy - * Copyright (c) 2005-2007 Vladimir Lebedev * Copyright (c) 2005 Rich Townsend * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -28,22 +26,15 @@ #include #include #include - -#ifdef CONFIG_ACPI_PROCFS #include #include #include -#endif - #include #include #include #include -#include - -#include "sbshc.h" - +#define ACPI_SBS_COMPONENT 0x00080000 #define ACPI_SBS_CLASS "sbs" #define ACPI_AC_CLASS "ac_adapter" #define ACPI_BATTERY_CLASS "battery" @@ -53,436 +44,836 @@ #define ACPI_SBS_FILE_ALARM "alarm" #define ACPI_BATTERY_DIR_NAME "BAT%i" #define ACPI_AC_DIR_NAME "AC0" +#define ACPI_SBC_SMBUS_ADDR 0x9 +#define ACPI_SBSM_SMBUS_ADDR 0xa +#define ACPI_SB_SMBUS_ADDR 0xb +#define ACPI_SBS_AC_NOTIFY_STATUS 0x80 +#define ACPI_SBS_BATTERY_NOTIFY_STATUS 0x80 +#define ACPI_SBS_BATTERY_NOTIFY_INFO 0x81 -enum acpi_sbs_device_addr { - ACPI_SBS_CHARGER = 0x9, - ACPI_SBS_MANAGER = 0xa, - ACPI_SBS_BATTERY = 0xb, -}; +#define _COMPONENT ACPI_SBS_COMPONENT -#define ACPI_SBS_NOTIFY_STATUS 0x80 -#define ACPI_SBS_NOTIFY_INFO 0x81 +ACPI_MODULE_NAME("sbs"); -MODULE_AUTHOR("Alexey Starikovskiy "); +MODULE_AUTHOR("Rich Townsend"); MODULE_DESCRIPTION("Smart Battery System ACPI interface driver"); MODULE_LICENSE("GPL"); -static unsigned int cache_time = 1000; -module_param(cache_time, uint, 0644); -MODULE_PARM_DESC(cache_time, "cache time in milliseconds"); +#define xmsleep(t) msleep(t) + +#define ACPI_EC_SMB_PRTCL 0x00 /* protocol, PEC */ + +#define ACPI_EC_SMB_STS 0x01 /* status */ +#define ACPI_EC_SMB_ADDR 0x02 /* address */ +#define ACPI_EC_SMB_CMD 0x03 /* command */ +#define ACPI_EC_SMB_DATA 0x04 /* 32 data registers */ +#define ACPI_EC_SMB_BCNT 0x24 /* number of data bytes */ + +#define ACPI_EC_SMB_STS_DONE 0x80 +#define ACPI_EC_SMB_STS_STATUS 0x1f + +#define ACPI_EC_SMB_PRTCL_WRITE 0x00 +#define ACPI_EC_SMB_PRTCL_READ 0x01 +#define ACPI_EC_SMB_PRTCL_WORD_DATA 0x08 +#define ACPI_EC_SMB_PRTCL_BLOCK_DATA 0x0a + +#define ACPI_EC_SMB_TRANSACTION_SLEEP 1 +#define ACPI_EC_SMB_ACCESS_SLEEP1 1 +#define ACPI_EC_SMB_ACCESS_SLEEP2 10 + +#define DEF_CAPACITY_UNIT 3 +#define MAH_CAPACITY_UNIT 1 +#define MWH_CAPACITY_UNIT 2 +#define CAPACITY_UNIT DEF_CAPACITY_UNIT + +#define REQUEST_UPDATE_MODE 1 +#define QUEUE_UPDATE_MODE 2 + +#define DATA_TYPE_COMMON 0 +#define DATA_TYPE_INFO 1 +#define DATA_TYPE_STATE 2 +#define DATA_TYPE_ALARM 3 +#define DATA_TYPE_AC_STATE 4 extern struct proc_dir_entry *acpi_lock_ac_dir(void); extern struct proc_dir_entry *acpi_lock_battery_dir(void); extern void acpi_unlock_ac_dir(struct proc_dir_entry *acpi_ac_dir); extern void acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir); -#define MAX_SBS_BAT 4 +#define MAX_SBS_BAT 4 #define ACPI_SBS_BLOCK_MAX 32 +#define ACPI_SBS_SMBUS_READ 1 +#define ACPI_SBS_SMBUS_WRITE 2 + +#define ACPI_SBS_WORD_DATA 1 +#define ACPI_SBS_BLOCK_DATA 2 + +#define UPDATE_DELAY 10 + +/* 0 - every time, > 0 - by update_time */ +static unsigned int update_time = 120; + +static unsigned int capacity_mode = CAPACITY_UNIT; + +module_param(update_time, uint, 0644); +module_param(capacity_mode, uint, 0444); + +static int acpi_sbs_add(struct acpi_device *device); +static int acpi_sbs_remove(struct acpi_device *device, int type); +static int acpi_sbs_resume(struct acpi_device *device); + static const struct acpi_device_id sbs_device_ids[] = { - {"ACPI0002", 0}, + {"ACPI0001", 0}, + {"ACPI0005", 0}, {"", 0}, }; MODULE_DEVICE_TABLE(acpi, sbs_device_ids); +static struct acpi_driver acpi_sbs_driver = { + .name = "sbs", + .class = ACPI_SBS_CLASS, + .ids = sbs_device_ids, + .ops = { + .add = acpi_sbs_add, + .remove = acpi_sbs_remove, + .resume = acpi_sbs_resume, + }, +}; + +struct acpi_ac { + int ac_present; +}; + +struct acpi_battery_info { + int capacity_mode; + s16 full_charge_capacity; + s16 design_capacity; + s16 design_voltage; + int vscale; + int ipscale; + s16 serial_number; + char manufacturer_name[ACPI_SBS_BLOCK_MAX + 3]; + char device_name[ACPI_SBS_BLOCK_MAX + 3]; + char device_chemistry[ACPI_SBS_BLOCK_MAX + 3]; +}; + +struct acpi_battery_state { + s16 voltage; + s16 amperage; + s16 remaining_capacity; + s16 battery_state; +}; + +struct acpi_battery_alarm { + s16 remaining_capacity; +}; + struct acpi_battery { - struct power_supply bat; + int alive; + int id; + int init_state; + int battery_present; struct acpi_sbs *sbs; -#ifdef CONFIG_ACPI_PROCFS - struct proc_dir_entry *proc_entry; -#endif - unsigned long update_time; - char name[8]; - char manufacturer_name[ACPI_SBS_BLOCK_MAX]; - char device_name[ACPI_SBS_BLOCK_MAX]; - char device_chemistry[ACPI_SBS_BLOCK_MAX]; - u16 alarm_capacity; - u16 full_charge_capacity; - u16 design_capacity; - u16 design_voltage; - u16 serial_number; - u16 cycle_count; - u16 temp_now; - u16 voltage_now; - s16 current_now; - s16 current_avg; - u16 capacity_now; - u16 state_of_charge; - u16 state; - u16 mode; - u16 spec; - u8 id; - u8 present:1; + struct acpi_battery_info info; + struct acpi_battery_state state; + struct acpi_battery_alarm alarm; + struct proc_dir_entry *battery_entry; }; -#define to_acpi_battery(x) container_of(x, struct acpi_battery, bat); - struct acpi_sbs { - struct power_supply charger; + int base; struct acpi_device *device; - struct acpi_smb_hc *hc; - struct mutex lock; -#ifdef CONFIG_ACPI_PROCFS - struct proc_dir_entry *charger_entry; -#endif + struct mutex mutex; + int sbsm_present; + int sbsm_batteries_supported; + struct proc_dir_entry *ac_entry; + struct acpi_ac ac; struct acpi_battery battery[MAX_SBS_BAT]; - u8 batteries_supported:4; - u8 manager_present:1; - u8 charger_present:1; + int zombie; + struct timer_list update_timer; + int run_cnt; + int update_proc_flg; }; -#define to_acpi_sbs(x) container_of(x, struct acpi_sbs, charger) +static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type); +static void acpi_sbs_update_time(void *data); -static inline int battery_scale(int log) +union sbs_rw_data { + u16 word; + u8 block[ACPI_SBS_BLOCK_MAX + 2]; +}; + +static int acpi_ec_sbs_access(struct acpi_sbs *sbs, u16 addr, + char read_write, u8 command, int size, + union sbs_rw_data *data); + +/* -------------------------------------------------------------------------- + SMBus Communication + -------------------------------------------------------------------------- */ + +static int acpi_ec_sbs_read(struct acpi_sbs *sbs, u8 address, u8 * data) +{ + u8 val; + int err; + + err = ec_read(sbs->base + address, &val); + if (!err) { + *data = val; + } + xmsleep(ACPI_EC_SMB_TRANSACTION_SLEEP); + return (err); +} + +static int acpi_ec_sbs_write(struct acpi_sbs *sbs, u8 address, u8 data) { - int scale = 1; - while (log--) - scale *= 10; - return scale; + int err; + + err = ec_write(sbs->base + address, data); + return (err); +} + +static int +acpi_ec_sbs_access(struct acpi_sbs *sbs, u16 addr, + char read_write, u8 command, int size, + union sbs_rw_data *data) +{ + unsigned char protocol, len = 0, temp[2] = { 0, 0 }; + int i; + + if (read_write == ACPI_SBS_SMBUS_READ) { + protocol = ACPI_EC_SMB_PRTCL_READ; + } else { + protocol = ACPI_EC_SMB_PRTCL_WRITE; + } + + switch (size) { + + case ACPI_SBS_WORD_DATA: + acpi_ec_sbs_write(sbs, ACPI_EC_SMB_CMD, command); + if (read_write == ACPI_SBS_SMBUS_WRITE) { + acpi_ec_sbs_write(sbs, ACPI_EC_SMB_DATA, data->word); + acpi_ec_sbs_write(sbs, ACPI_EC_SMB_DATA + 1, + data->word >> 8); + } + protocol |= ACPI_EC_SMB_PRTCL_WORD_DATA; + break; + case ACPI_SBS_BLOCK_DATA: + acpi_ec_sbs_write(sbs, ACPI_EC_SMB_CMD, command); + if (read_write == ACPI_SBS_SMBUS_WRITE) { + len = min_t(u8, data->block[0], 32); + acpi_ec_sbs_write(sbs, ACPI_EC_SMB_BCNT, len); + for (i = 0; i < len; i++) + acpi_ec_sbs_write(sbs, ACPI_EC_SMB_DATA + i, + data->block[i + 1]); + } + protocol |= ACPI_EC_SMB_PRTCL_BLOCK_DATA; + break; + default: + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "unsupported transaction %d", size)); + return (-1); + } + + acpi_ec_sbs_write(sbs, ACPI_EC_SMB_ADDR, addr << 1); + acpi_ec_sbs_write(sbs, ACPI_EC_SMB_PRTCL, protocol); + + acpi_ec_sbs_read(sbs, ACPI_EC_SMB_STS, temp); + + if (~temp[0] & ACPI_EC_SMB_STS_DONE) { + xmsleep(ACPI_EC_SMB_ACCESS_SLEEP1); + acpi_ec_sbs_read(sbs, ACPI_EC_SMB_STS, temp); + } + if (~temp[0] & ACPI_EC_SMB_STS_DONE) { + xmsleep(ACPI_EC_SMB_ACCESS_SLEEP2); + acpi_ec_sbs_read(sbs, ACPI_EC_SMB_STS, temp); + } + if ((~temp[0] & ACPI_EC_SMB_STS_DONE) + || (temp[0] & ACPI_EC_SMB_STS_STATUS)) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "transaction %d error", size)); + return (-1); + } + + if (read_write == ACPI_SBS_SMBUS_WRITE) { + return (0); + } + + switch (size) { + + case ACPI_SBS_WORD_DATA: + acpi_ec_sbs_read(sbs, ACPI_EC_SMB_DATA, temp); + acpi_ec_sbs_read(sbs, ACPI_EC_SMB_DATA + 1, temp + 1); + data->word = (temp[1] << 8) | temp[0]; + break; + + case ACPI_SBS_BLOCK_DATA: + len = 0; + acpi_ec_sbs_read(sbs, ACPI_EC_SMB_BCNT, &len); + len = min_t(u8, len, 32); + for (i = 0; i < len; i++) + acpi_ec_sbs_read(sbs, ACPI_EC_SMB_DATA + i, + data->block + i + 1); + data->block[0] = len; + break; + default: + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "unsupported transaction %d", size)); + return (-1); + } + + return (0); } -static inline int acpi_battery_vscale(struct acpi_battery *battery) +static int +acpi_sbs_read_word(struct acpi_sbs *sbs, int addr, int func, u16 * word) { - return battery_scale((battery->spec & 0x0f00) >> 8); + union sbs_rw_data data; + int result = 0; + + result = acpi_ec_sbs_access(sbs, addr, + ACPI_SBS_SMBUS_READ, func, + ACPI_SBS_WORD_DATA, &data); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_ec_sbs_access() failed")); + } else { + *word = data.word; + } + + return result; } -static inline int acpi_battery_ipscale(struct acpi_battery *battery) +static int +acpi_sbs_read_str(struct acpi_sbs *sbs, int addr, int func, char *str) { - return battery_scale((battery->spec & 0xf000) >> 12); + union sbs_rw_data data; + int result = 0; + + result = acpi_ec_sbs_access(sbs, addr, + ACPI_SBS_SMBUS_READ, func, + ACPI_SBS_BLOCK_DATA, &data); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_ec_sbs_access() failed")); + } else { + strncpy(str, (const char *)data.block + 1, data.block[0]); + str[data.block[0]] = 0; + } + + return result; } -static inline int acpi_battery_mode(struct acpi_battery *battery) +static int +acpi_sbs_write_word(struct acpi_sbs *sbs, int addr, int func, int word) { - return (battery->mode & 0x8000); + union sbs_rw_data data; + int result = 0; + + data.word = word; + + result = acpi_ec_sbs_access(sbs, addr, + ACPI_SBS_SMBUS_WRITE, func, + ACPI_SBS_WORD_DATA, &data); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_ec_sbs_access() failed")); + } + + return result; } -static inline int acpi_battery_scale(struct acpi_battery *battery) +static int sbs_zombie(struct acpi_sbs *sbs) { - return (acpi_battery_mode(battery) ? 10 : 1) * - acpi_battery_ipscale(battery); + return (sbs->zombie); } -static int sbs_get_ac_property(struct power_supply *psy, - enum power_supply_property psp, - union power_supply_propval *val) +static int sbs_mutex_lock(struct acpi_sbs *sbs) { - struct acpi_sbs *sbs = to_acpi_sbs(psy); - switch (psp) { - case POWER_SUPPLY_PROP_ONLINE: - val->intval = sbs->charger_present; - break; - default: - return -EINVAL; + if (sbs_zombie(sbs)) { + return -ENODEV; } + mutex_lock(&sbs->mutex); return 0; } -static int acpi_battery_technology(struct acpi_battery *battery) +static void sbs_mutex_unlock(struct acpi_sbs *sbs) { - if (!strcasecmp("NiCd", battery->device_chemistry)) - return POWER_SUPPLY_TECHNOLOGY_NiCd; - if (!strcasecmp("NiMH", battery->device_chemistry)) - return POWER_SUPPLY_TECHNOLOGY_NiMH; - if (!strcasecmp("LION", battery->device_chemistry)) - return POWER_SUPPLY_TECHNOLOGY_LION; - if (!strcasecmp("LiP", battery->device_chemistry)) - return POWER_SUPPLY_TECHNOLOGY_LIPO; - return POWER_SUPPLY_TECHNOLOGY_UNKNOWN; + mutex_unlock(&sbs->mutex); } -static int acpi_sbs_battery_get_property(struct power_supply *psy, - enum power_supply_property psp, - union power_supply_propval *val) +/* -------------------------------------------------------------------------- + Smart Battery System Management + -------------------------------------------------------------------------- */ + +static int acpi_check_update_proc(struct acpi_sbs *sbs) { - struct acpi_battery *battery = to_acpi_battery(psy); + acpi_status status = AE_OK; - if ((!battery->present) && psp != POWER_SUPPLY_PROP_PRESENT) - return -ENODEV; - switch (psp) { - case POWER_SUPPLY_PROP_STATUS: - if (battery->current_now < 0) - val->intval = POWER_SUPPLY_STATUS_DISCHARGING; - else if (battery->current_now > 0) - val->intval = POWER_SUPPLY_STATUS_CHARGING; - else - val->intval = POWER_SUPPLY_STATUS_FULL; - break; - case POWER_SUPPLY_PROP_PRESENT: - val->intval = battery->present; - break; - case POWER_SUPPLY_PROP_TECHNOLOGY: - val->intval = acpi_battery_technology(battery); - break; - case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: - val->intval = battery->design_voltage * - acpi_battery_vscale(battery) * 1000; - break; - case POWER_SUPPLY_PROP_VOLTAGE_NOW: - val->intval = battery->voltage_now * - acpi_battery_vscale(battery) * 1000; - break; - case POWER_SUPPLY_PROP_CURRENT_NOW: - val->intval = abs(battery->current_now) * - acpi_battery_ipscale(battery) * 1000; - break; - case POWER_SUPPLY_PROP_CURRENT_AVG: - val->intval = abs(battery->current_avg) * - acpi_battery_ipscale(battery) * 1000; - break; - case POWER_SUPPLY_PROP_CAPACITY: - val->intval = battery->state_of_charge; - break; - case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: - case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN: - val->intval = battery->design_capacity * - acpi_battery_scale(battery) * 1000; - break; - case POWER_SUPPLY_PROP_CHARGE_FULL: - case POWER_SUPPLY_PROP_ENERGY_FULL: - val->intval = battery->full_charge_capacity * - acpi_battery_scale(battery) * 1000; - break; - case POWER_SUPPLY_PROP_CHARGE_NOW: - case POWER_SUPPLY_PROP_ENERGY_NOW: - val->intval = battery->capacity_now * - acpi_battery_scale(battery) * 1000; - break; - case POWER_SUPPLY_PROP_TEMP: - val->intval = battery->temp_now - 2730; // dK -> dC - break; - case POWER_SUPPLY_PROP_MODEL_NAME: - val->strval = battery->device_name; - break; - case POWER_SUPPLY_PROP_MANUFACTURER: - val->strval = battery->manufacturer_name; - break; - default: - return -EINVAL; + if (update_time == 0) { + sbs->update_proc_flg = 0; + return 0; + } + if (sbs->update_proc_flg == 0) { + status = acpi_os_execute(OSL_GPE_HANDLER, + acpi_sbs_update_time, sbs); + if (status != AE_OK) { + ACPI_EXCEPTION((AE_INFO, status, + "acpi_os_execute() failed")); + return 1; + } + sbs->update_proc_flg = 1; } return 0; } -static enum power_supply_property sbs_ac_props[] = { - POWER_SUPPLY_PROP_ONLINE, -}; +static int acpi_sbs_generate_event(struct acpi_device *device, + int event, int state, char *bid, char *class) +{ + char bid_saved[5]; + char class_saved[20]; + int result = 0; -static enum power_supply_property sbs_charge_battery_props[] = { - POWER_SUPPLY_PROP_STATUS, - POWER_SUPPLY_PROP_PRESENT, - POWER_SUPPLY_PROP_TECHNOLOGY, - POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, - POWER_SUPPLY_PROP_VOLTAGE_NOW, - POWER_SUPPLY_PROP_CURRENT_NOW, - POWER_SUPPLY_PROP_CURRENT_AVG, - POWER_SUPPLY_PROP_CAPACITY, - POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, - POWER_SUPPLY_PROP_CHARGE_FULL, - POWER_SUPPLY_PROP_CHARGE_NOW, - POWER_SUPPLY_PROP_TEMP, - POWER_SUPPLY_PROP_MODEL_NAME, - POWER_SUPPLY_PROP_MANUFACTURER, -}; + strcpy(bid_saved, acpi_device_bid(device)); + strcpy(class_saved, acpi_device_class(device)); -static enum power_supply_property sbs_energy_battery_props[] = { - POWER_SUPPLY_PROP_STATUS, - POWER_SUPPLY_PROP_PRESENT, - POWER_SUPPLY_PROP_TECHNOLOGY, - POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, - POWER_SUPPLY_PROP_VOLTAGE_NOW, - POWER_SUPPLY_PROP_CURRENT_NOW, - POWER_SUPPLY_PROP_CURRENT_AVG, - POWER_SUPPLY_PROP_CAPACITY, - POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN, - POWER_SUPPLY_PROP_ENERGY_FULL, - POWER_SUPPLY_PROP_ENERGY_NOW, - POWER_SUPPLY_PROP_TEMP, - POWER_SUPPLY_PROP_MODEL_NAME, - POWER_SUPPLY_PROP_MANUFACTURER, -}; + strcpy(acpi_device_bid(device), bid); + strcpy(acpi_device_class(device), class); -/* -------------------------------------------------------------------------- - Smart Battery System Management - -------------------------------------------------------------------------- */ + result = acpi_bus_generate_proc_event(device, event, state); -struct acpi_battery_reader { - u8 command; /* command for battery */ - u8 mode; /* word or block? */ - size_t offset; /* offset inside struct acpi_sbs_battery */ -}; + strcpy(acpi_device_bid(device), bid_saved); + strcpy(acpi_device_class(device), class_saved); -static struct acpi_battery_reader info_readers[] = { - {0x01, SMBUS_READ_WORD, offsetof(struct acpi_battery, alarm_capacity)}, - {0x03, SMBUS_READ_WORD, offsetof(struct acpi_battery, mode)}, - {0x10, SMBUS_READ_WORD, offsetof(struct acpi_battery, full_charge_capacity)}, - {0x17, SMBUS_READ_WORD, offsetof(struct acpi_battery, cycle_count)}, - {0x18, SMBUS_READ_WORD, offsetof(struct acpi_battery, design_capacity)}, - {0x19, SMBUS_READ_WORD, offsetof(struct acpi_battery, design_voltage)}, - {0x1a, SMBUS_READ_WORD, offsetof(struct acpi_battery, spec)}, - {0x1c, SMBUS_READ_WORD, offsetof(struct acpi_battery, serial_number)}, - {0x20, SMBUS_READ_BLOCK, offsetof(struct acpi_battery, manufacturer_name)}, - {0x21, SMBUS_READ_BLOCK, offsetof(struct acpi_battery, device_name)}, - {0x22, SMBUS_READ_BLOCK, offsetof(struct acpi_battery, device_chemistry)}, -}; + acpi_bus_generate_netlink_event(class, bid, event, state); + return result; +} -static struct acpi_battery_reader state_readers[] = { - {0x08, SMBUS_READ_WORD, offsetof(struct acpi_battery, temp_now)}, - {0x09, SMBUS_READ_WORD, offsetof(struct acpi_battery, voltage_now)}, - {0x0a, SMBUS_READ_WORD, offsetof(struct acpi_battery, current_now)}, - {0x0b, SMBUS_READ_WORD, offsetof(struct acpi_battery, current_avg)}, - {0x0f, SMBUS_READ_WORD, offsetof(struct acpi_battery, capacity_now)}, - {0x0e, SMBUS_READ_WORD, offsetof(struct acpi_battery, state_of_charge)}, - {0x16, SMBUS_READ_WORD, offsetof(struct acpi_battery, state)}, -}; +static int acpi_battery_get_present(struct acpi_battery *battery) +{ + s16 state; + int result = 0; + int is_present = 0; + + result = acpi_sbs_read_word(battery->sbs, + ACPI_SBSM_SMBUS_ADDR, 0x01, &state); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_sbs_read_word() failed")); + } + if (!result) { + is_present = (state & 0x000f) & (1 << battery->id); + } + battery->battery_present = is_present; + + return result; +} + +static int acpi_battery_select(struct acpi_battery *battery) +{ + struct acpi_sbs *sbs = battery->sbs; + int result = 0; + s16 state; + int foo; + + if (sbs->sbsm_present) { + + /* Take special care not to knobble other nibbles of + * state (aka selector_state), since + * it causes charging to halt on SBSELs */ + + result = + acpi_sbs_read_word(sbs, ACPI_SBSM_SMBUS_ADDR, 0x01, &state); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_sbs_read_word() failed")); + goto end; + } + + foo = (state & 0x0fff) | (1 << (battery->id + 12)); + result = + acpi_sbs_write_word(sbs, ACPI_SBSM_SMBUS_ADDR, 0x01, foo); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_sbs_write_word() failed")); + goto end; + } + } + + end: + return result; +} -static int acpi_manager_get_info(struct acpi_sbs *sbs) +static int acpi_sbsm_get_info(struct acpi_sbs *sbs) { int result = 0; - u16 battery_system_info; + s16 battery_system_info; + + result = acpi_sbs_read_word(sbs, ACPI_SBSM_SMBUS_ADDR, 0x04, + &battery_system_info); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_sbs_read_word() failed")); + goto end; + } + sbs->sbsm_present = 1; + sbs->sbsm_batteries_supported = battery_system_info & 0x000f; + + end: - result = acpi_smbus_read(sbs->hc, SMBUS_READ_WORD, ACPI_SBS_MANAGER, - 0x04, (u8 *)&battery_system_info); - if (!result) - sbs->batteries_supported = battery_system_info & 0x000f; return result; } static int acpi_battery_get_info(struct acpi_battery *battery) { - int i, result = 0; - - for (i = 0; i < ARRAY_SIZE(info_readers); ++i) { - result = acpi_smbus_read(battery->sbs->hc, - info_readers[i].mode, - ACPI_SBS_BATTERY, - info_readers[i].command, - (u8 *) battery + - info_readers[i].offset); - if (result) - break; + struct acpi_sbs *sbs = battery->sbs; + int result = 0; + s16 battery_mode; + s16 specification_info; + + result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x03, + &battery_mode); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_sbs_read_word() failed")); + goto end; + } + battery->info.capacity_mode = (battery_mode & 0x8000) >> 15; + + result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x10, + &battery->info.full_charge_capacity); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_sbs_read_word() failed")); + goto end; + } + + result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x18, + &battery->info.design_capacity); + + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_sbs_read_word() failed")); + goto end; + } + + result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x19, + &battery->info.design_voltage); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_sbs_read_word() failed")); + goto end; + } + + result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x1a, + &specification_info); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_sbs_read_word() failed")); + goto end; + } + + switch ((specification_info & 0x0f00) >> 8) { + case 1: + battery->info.vscale = 10; + break; + case 2: + battery->info.vscale = 100; + break; + case 3: + battery->info.vscale = 1000; + break; + default: + battery->info.vscale = 1; + } + + switch ((specification_info & 0xf000) >> 12) { + case 1: + battery->info.ipscale = 10; + break; + case 2: + battery->info.ipscale = 100; + break; + case 3: + battery->info.ipscale = 1000; + break; + default: + battery->info.ipscale = 1; + } + + result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x1c, + &battery->info.serial_number); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_sbs_read_word() failed")); + goto end; + } + + result = acpi_sbs_read_str(sbs, ACPI_SB_SMBUS_ADDR, 0x20, + battery->info.manufacturer_name); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_sbs_read_str() failed")); + goto end; + } + + result = acpi_sbs_read_str(sbs, ACPI_SB_SMBUS_ADDR, 0x21, + battery->info.device_name); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_sbs_read_str() failed")); + goto end; } + + result = acpi_sbs_read_str(sbs, ACPI_SB_SMBUS_ADDR, 0x22, + battery->info.device_chemistry); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_sbs_read_str() failed")); + goto end; + } + + end: return result; } static int acpi_battery_get_state(struct acpi_battery *battery) { - int i, result = 0; + struct acpi_sbs *sbs = battery->sbs; + int result = 0; - if (battery->update_time && - time_before(jiffies, battery->update_time + - msecs_to_jiffies(cache_time))) - return 0; - for (i = 0; i < ARRAY_SIZE(state_readers); ++i) { - result = acpi_smbus_read(battery->sbs->hc, - state_readers[i].mode, - ACPI_SBS_BATTERY, - state_readers[i].command, - (u8 *)battery + - state_readers[i].offset); - if (result) - goto end; + result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x09, + &battery->state.voltage); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_sbs_read_word() failed")); + goto end; + } + + result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x0a, + &battery->state.amperage); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_sbs_read_word() failed")); + goto end; + } + + result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x0f, + &battery->state.remaining_capacity); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_sbs_read_word() failed")); + goto end; } + + result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x16, + &battery->state.battery_state); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_sbs_read_word() failed")); + goto end; + } + end: - battery->update_time = jiffies; return result; } static int acpi_battery_get_alarm(struct acpi_battery *battery) { - return acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, - ACPI_SBS_BATTERY, 0x01, - (u8 *)&battery->alarm_capacity); + struct acpi_sbs *sbs = battery->sbs; + int result = 0; + + result = acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x01, + &battery->alarm.remaining_capacity); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_sbs_read_word() failed")); + goto end; + } + + end: + + return result; } -static int acpi_battery_set_alarm(struct acpi_battery *battery) +static int acpi_battery_set_alarm(struct acpi_battery *battery, + unsigned long alarm) { struct acpi_sbs *sbs = battery->sbs; - u16 value, sel = 1 << (battery->id + 12); + int result = 0; + s16 battery_mode; + int foo; - int ret; + result = acpi_battery_select(battery); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_battery_select() failed")); + goto end; + } + /* If necessary, enable the alarm */ - if (sbs->manager_present) { - ret = acpi_smbus_read(sbs->hc, SMBUS_READ_WORD, ACPI_SBS_MANAGER, - 0x01, (u8 *)&value); - if (ret) + if (alarm > 0) { + result = + acpi_sbs_read_word(sbs, ACPI_SB_SMBUS_ADDR, 0x03, + &battery_mode); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_sbs_read_word() failed")); goto end; - if ((value & 0xf000) != sel) { - value &= 0x0fff; - value |= sel; - ret = acpi_smbus_write(sbs->hc, SMBUS_WRITE_WORD, - ACPI_SBS_MANAGER, - 0x01, (u8 *)&value, 2); - if (ret) + } + + result = + acpi_sbs_write_word(sbs, ACPI_SB_SMBUS_ADDR, 0x01, + battery_mode & 0xbfff); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_sbs_write_word() failed")); goto end; } } - ret = acpi_smbus_write(sbs->hc, SMBUS_WRITE_WORD, ACPI_SBS_BATTERY, - 0x01, (u8 *)&battery->alarm_capacity, 2); + + foo = alarm / (battery->info.capacity_mode ? 10 : 1); + result = acpi_sbs_write_word(sbs, ACPI_SB_SMBUS_ADDR, 0x01, foo); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_sbs_write_word() failed")); + goto end; + } + end: - return ret; + + return result; } -static int acpi_ac_get_present(struct acpi_sbs *sbs) +static int acpi_battery_set_mode(struct acpi_battery *battery) { - int result; - u16 status; + struct acpi_sbs *sbs = battery->sbs; + int result = 0; + s16 battery_mode; + + if (capacity_mode == DEF_CAPACITY_UNIT) { + goto end; + } + + result = acpi_sbs_read_word(sbs, + ACPI_SB_SMBUS_ADDR, 0x03, &battery_mode); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_sbs_read_word() failed")); + goto end; + } + + if (capacity_mode == MAH_CAPACITY_UNIT) { + battery_mode &= 0x7fff; + } else { + battery_mode |= 0x8000; + } + result = acpi_sbs_write_word(sbs, + ACPI_SB_SMBUS_ADDR, 0x03, battery_mode); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_sbs_write_word() failed")); + goto end; + } + + result = acpi_sbs_read_word(sbs, + ACPI_SB_SMBUS_ADDR, 0x03, &battery_mode); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_sbs_read_word() failed")); + goto end; + } - result = acpi_smbus_read(sbs->hc, SMBUS_READ_WORD, ACPI_SBS_CHARGER, - 0x13, (u8 *) & status); - if (!result) - sbs->charger_present = (status >> 15) & 0x1; + end: return result; } -static ssize_t acpi_battery_alarm_show(struct device *dev, - struct device_attribute *attr, - char *buf) +static int acpi_battery_init(struct acpi_battery *battery) { - struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev)); - acpi_battery_get_alarm(battery); - return sprintf(buf, "%d\n", battery->alarm_capacity * - acpi_battery_scale(battery) * 1000); + int result = 0; + + result = acpi_battery_select(battery); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_battery_select() failed")); + goto end; + } + + result = acpi_battery_set_mode(battery); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_battery_set_mode() failed")); + goto end; + } + + result = acpi_battery_get_info(battery); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_battery_get_info() failed")); + goto end; + } + + result = acpi_battery_get_state(battery); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_battery_get_state() failed")); + goto end; + } + + result = acpi_battery_get_alarm(battery); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_battery_get_alarm() failed")); + goto end; + } + + end: + return result; } -static ssize_t acpi_battery_alarm_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) +static int acpi_ac_get_present(struct acpi_sbs *sbs) { - unsigned long x; - struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev)); - if (sscanf(buf, "%ld\n", &x) == 1) - battery->alarm_capacity = x / - (1000 * acpi_battery_scale(battery)); - if (battery->present) - acpi_battery_set_alarm(battery); - return count; -} + int result = 0; + s16 charger_status; -static struct device_attribute alarm_attr = { - .attr = {.name = "alarm", .mode = 0644, .owner = THIS_MODULE}, - .show = acpi_battery_alarm_show, - .store = acpi_battery_alarm_store, -}; + result = acpi_sbs_read_word(sbs, ACPI_SBC_SMBUS_ADDR, 0x13, + &charger_status); + + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_sbs_read_word() failed")); + goto end; + } + + sbs->ac.ac_present = (charger_status & 0x8000) >> 15; + + end: + + return result; +} /* -------------------------------------------------------------------------- FS Interface (/proc/acpi) -------------------------------------------------------------------------- */ -#ifdef CONFIG_ACPI_PROCFS /* Generic Routines */ + static int -acpi_sbs_add_fs(struct proc_dir_entry **dir, - struct proc_dir_entry *parent_dir, - char *dir_name, - struct file_operations *info_fops, - struct file_operations *state_fops, - struct file_operations *alarm_fops, void *data) +acpi_sbs_generic_add_fs(struct proc_dir_entry **dir, + struct proc_dir_entry *parent_dir, + char *dir_name, + struct file_operations *info_fops, + struct file_operations *state_fops, + struct file_operations *alarm_fops, void *data) { struct proc_dir_entry *entry = NULL; if (!*dir) { *dir = proc_mkdir(dir_name, parent_dir); if (!*dir) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "proc_mkdir() failed")); return -ENODEV; } (*dir)->owner = THIS_MODULE; @@ -491,7 +882,10 @@ acpi_sbs_add_fs(struct proc_dir_entry **dir, /* 'info' [R] */ if (info_fops) { entry = create_proc_entry(ACPI_SBS_FILE_INFO, S_IRUGO, *dir); - if (entry) { + if (!entry) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "create_proc_entry() failed")); + } else { entry->proc_fops = info_fops; entry->data = data; entry->owner = THIS_MODULE; @@ -501,7 +895,10 @@ acpi_sbs_add_fs(struct proc_dir_entry **dir, /* 'state' [R] */ if (state_fops) { entry = create_proc_entry(ACPI_SBS_FILE_STATE, S_IRUGO, *dir); - if (entry) { + if (!entry) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "create_proc_entry() failed")); + } else { entry->proc_fops = state_fops; entry->data = data; entry->owner = THIS_MODULE; @@ -511,19 +908,24 @@ acpi_sbs_add_fs(struct proc_dir_entry **dir, /* 'alarm' [R/W] */ if (alarm_fops) { entry = create_proc_entry(ACPI_SBS_FILE_ALARM, S_IRUGO, *dir); - if (entry) { + if (!entry) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "create_proc_entry() failed")); + } else { entry->proc_fops = alarm_fops; entry->data = data; entry->owner = THIS_MODULE; } } + return 0; } static void -acpi_sbs_remove_fs(struct proc_dir_entry **dir, +acpi_sbs_generic_remove_fs(struct proc_dir_entry **dir, struct proc_dir_entry *parent_dir) { + if (*dir) { remove_proc_entry(ACPI_SBS_FILE_INFO, *dir); remove_proc_entry(ACPI_SBS_FILE_STATE, *dir); @@ -531,52 +933,82 @@ acpi_sbs_remove_fs(struct proc_dir_entry **dir, remove_proc_entry((*dir)->name, parent_dir); *dir = NULL; } + } /* Smart Battery Interface */ -static struct proc_dir_entry *acpi_battery_dir = NULL; - -static inline char *acpi_battery_units(struct acpi_battery *battery) -{ - return acpi_battery_mode(battery) ? " mWh" : " mAh"; -} +static struct proc_dir_entry *acpi_battery_dir = NULL; static int acpi_battery_read_info(struct seq_file *seq, void *offset) { struct acpi_battery *battery = seq->private; struct acpi_sbs *sbs = battery->sbs; + int cscale; int result = 0; - mutex_lock(&sbs->lock); + if (sbs_mutex_lock(sbs)) { + return -ENODEV; + } - seq_printf(seq, "present: %s\n", - (battery->present) ? "yes" : "no"); - if (!battery->present) + result = acpi_check_update_proc(sbs); + if (result) goto end; + if (update_time == 0) { + result = acpi_sbs_update_run(sbs, battery->id, DATA_TYPE_INFO); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_sbs_update_run() failed")); + } + } + + if (battery->battery_present) { + seq_printf(seq, "present: yes\n"); + } else { + seq_printf(seq, "present: no\n"); + goto end; + } + + if (battery->info.capacity_mode) { + cscale = battery->info.vscale * battery->info.ipscale; + } else { + cscale = battery->info.ipscale; + } seq_printf(seq, "design capacity: %i%s\n", - battery->design_capacity * acpi_battery_scale(battery), - acpi_battery_units(battery)); + battery->info.design_capacity * cscale, + battery->info.capacity_mode ? "0 mWh" : " mAh"); + seq_printf(seq, "last full capacity: %i%s\n", - battery->full_charge_capacity * acpi_battery_scale(battery), - acpi_battery_units(battery)); + battery->info.full_charge_capacity * cscale, + battery->info.capacity_mode ? "0 mWh" : " mAh"); + seq_printf(seq, "battery technology: rechargeable\n"); + seq_printf(seq, "design voltage: %i mV\n", - battery->design_voltage * acpi_battery_vscale(battery)); + battery->info.design_voltage * battery->info.vscale); + seq_printf(seq, "design capacity warning: unknown\n"); seq_printf(seq, "design capacity low: unknown\n"); seq_printf(seq, "capacity granularity 1: unknown\n"); seq_printf(seq, "capacity granularity 2: unknown\n"); - seq_printf(seq, "model number: %s\n", battery->device_name); + + seq_printf(seq, "model number: %s\n", + battery->info.device_name); + seq_printf(seq, "serial number: %i\n", - battery->serial_number); + battery->info.serial_number); + seq_printf(seq, "battery type: %s\n", - battery->device_chemistry); + battery->info.device_chemistry); + seq_printf(seq, "OEM info: %s\n", - battery->manufacturer_name); + battery->info.manufacturer_name); + end: - mutex_unlock(&sbs->lock); + + sbs_mutex_unlock(sbs); + return result; } @@ -590,29 +1022,73 @@ static int acpi_battery_read_state(struct seq_file *seq, void *offset) struct acpi_battery *battery = seq->private; struct acpi_sbs *sbs = battery->sbs; int result = 0; + int cscale; + int foo; + + if (sbs_mutex_lock(sbs)) { + return -ENODEV; + } + + result = acpi_check_update_proc(sbs); + if (result) + goto end; + + if (update_time == 0) { + result = acpi_sbs_update_run(sbs, battery->id, DATA_TYPE_STATE); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_sbs_update_run() failed")); + } + } - mutex_lock(&sbs->lock); - seq_printf(seq, "present: %s\n", - (battery->present) ? "yes" : "no"); - if (!battery->present) + if (battery->battery_present) { + seq_printf(seq, "present: yes\n"); + } else { + seq_printf(seq, "present: no\n"); goto end; + } + + if (battery->info.capacity_mode) { + cscale = battery->info.vscale * battery->info.ipscale; + } else { + cscale = battery->info.ipscale; + } + + if (battery->state.battery_state & 0x0010) { + seq_printf(seq, "capacity state: critical\n"); + } else { + seq_printf(seq, "capacity state: ok\n"); + } + + foo = (s16) battery->state.amperage * battery->info.ipscale; + if (battery->info.capacity_mode) { + foo = foo * battery->info.design_voltage / 1000; + } + if (battery->state.amperage < 0) { + seq_printf(seq, "charging state: discharging\n"); + seq_printf(seq, "present rate: %d %s\n", + -foo, battery->info.capacity_mode ? "mW" : "mA"); + } else if (battery->state.amperage > 0) { + seq_printf(seq, "charging state: charging\n"); + seq_printf(seq, "present rate: %d %s\n", + foo, battery->info.capacity_mode ? "mW" : "mA"); + } else { + seq_printf(seq, "charging state: charged\n"); + seq_printf(seq, "present rate: 0 %s\n", + battery->info.capacity_mode ? "mW" : "mA"); + } - acpi_battery_get_state(battery); - seq_printf(seq, "capacity state: %s\n", - (battery->state & 0x0010) ? "critical" : "ok"); - seq_printf(seq, "charging state: %s\n", - (battery->current_now < 0) ? "discharging" : - ((battery->current_now > 0) ? "charging" : "charged")); - seq_printf(seq, "present rate: %d mA\n", - abs(battery->current_now) * acpi_battery_ipscale(battery)); seq_printf(seq, "remaining capacity: %i%s\n", - battery->capacity_now * acpi_battery_scale(battery), - acpi_battery_units(battery)); + battery->state.remaining_capacity * cscale, + battery->info.capacity_mode ? "0 mWh" : " mAh"); + seq_printf(seq, "present voltage: %i mV\n", - battery->voltage_now * acpi_battery_vscale(battery)); + battery->state.voltage * battery->info.vscale); end: - mutex_unlock(&sbs->lock); + + sbs_mutex_unlock(sbs); + return result; } @@ -626,25 +1102,48 @@ static int acpi_battery_read_alarm(struct seq_file *seq, void *offset) struct acpi_battery *battery = seq->private; struct acpi_sbs *sbs = battery->sbs; int result = 0; + int cscale; + + if (sbs_mutex_lock(sbs)) { + return -ENODEV; + } - mutex_lock(&sbs->lock); + result = acpi_check_update_proc(sbs); + if (result) + goto end; + + if (update_time == 0) { + result = acpi_sbs_update_run(sbs, battery->id, DATA_TYPE_ALARM); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_sbs_update_run() failed")); + } + } - if (!battery->present) { + if (!battery->battery_present) { seq_printf(seq, "present: no\n"); goto end; } - acpi_battery_get_alarm(battery); + if (battery->info.capacity_mode) { + cscale = battery->info.vscale * battery->info.ipscale; + } else { + cscale = battery->info.ipscale; + } + seq_printf(seq, "alarm: "); - if (battery->alarm_capacity) + if (battery->alarm.remaining_capacity) { seq_printf(seq, "%i%s\n", - battery->alarm_capacity * - acpi_battery_scale(battery), - acpi_battery_units(battery)); - else + battery->alarm.remaining_capacity * cscale, + battery->info.capacity_mode ? "0 mWh" : " mAh"); + } else { seq_printf(seq, "disabled\n"); + } + end: - mutex_unlock(&sbs->lock); + + sbs_mutex_unlock(sbs); + return result; } @@ -656,29 +1155,59 @@ acpi_battery_write_alarm(struct file *file, const char __user * buffer, struct acpi_battery *battery = seq->private; struct acpi_sbs *sbs = battery->sbs; char alarm_string[12] = { '\0' }; - int result = 0; - mutex_lock(&sbs->lock); - if (!battery->present) { + int result, old_alarm, new_alarm; + + if (sbs_mutex_lock(sbs)) { + return -ENODEV; + } + + result = acpi_check_update_proc(sbs); + if (result) + goto end; + + if (!battery->battery_present) { result = -ENODEV; goto end; } + if (count > sizeof(alarm_string) - 1) { result = -EINVAL; goto end; } + if (copy_from_user(alarm_string, buffer, count)) { result = -EFAULT; goto end; } + alarm_string[count] = 0; - battery->alarm_capacity = simple_strtoul(alarm_string, NULL, 0) / - acpi_battery_scale(battery); - acpi_battery_set_alarm(battery); + + old_alarm = battery->alarm.remaining_capacity; + new_alarm = simple_strtoul(alarm_string, NULL, 0); + + result = acpi_battery_set_alarm(battery, new_alarm); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_battery_set_alarm() failed")); + acpi_battery_set_alarm(battery, old_alarm); + goto end; + } + result = acpi_battery_get_alarm(battery); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_battery_get_alarm() failed")); + acpi_battery_set_alarm(battery, old_alarm); + goto end; + } + end: - mutex_unlock(&sbs->lock); - if (result) + sbs_mutex_unlock(sbs); + + if (result) { return result; - return count; + } else { + return count; + } } static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file) @@ -717,15 +1246,26 @@ static struct proc_dir_entry *acpi_ac_dir = NULL; static int acpi_ac_read_state(struct seq_file *seq, void *offset) { - struct acpi_sbs *sbs = seq->private; + int result; + + if (sbs_mutex_lock(sbs)) { + return -ENODEV; + } - mutex_lock(&sbs->lock); + if (update_time == 0) { + result = acpi_sbs_update_run(sbs, -1, DATA_TYPE_AC_STATE); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_sbs_update_run() failed")); + } + } seq_printf(seq, "state: %s\n", - sbs->charger_present ? "on-line" : "off-line"); + sbs->ac.ac_present ? "on-line" : "off-line"); + + sbs_mutex_unlock(sbs); - mutex_unlock(&sbs->lock); return 0; } @@ -742,203 +1282,429 @@ static struct file_operations acpi_ac_state_fops = { .owner = THIS_MODULE, }; -#endif - /* -------------------------------------------------------------------------- Driver Interface -------------------------------------------------------------------------- */ -static int acpi_battery_read(struct acpi_battery *battery) -{ - int result = 0, saved_present = battery->present; - u16 state; - - if (battery->sbs->manager_present) { - result = acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD, - ACPI_SBS_MANAGER, 0x01, (u8 *)&state); - if (!result) - battery->present = state & (1 << battery->id); - state &= 0x0fff; - state |= 1 << (battery->id + 12); - acpi_smbus_write(battery->sbs->hc, SMBUS_WRITE_WORD, - ACPI_SBS_MANAGER, 0x01, (u8 *)&state, 2); - } else if (battery->id == 0) - battery->present = 1; - if (result || !battery->present) - return result; - - if (saved_present != battery->present) { - battery->update_time = 0; - result = acpi_battery_get_info(battery); - if (result) - return result; - } - result = acpi_battery_get_state(battery); - return result; -} /* Smart Battery */ + static int acpi_battery_add(struct acpi_sbs *sbs, int id) { - struct acpi_battery *battery = &sbs->battery[id]; + int is_present; int result; + char dir_name[32]; + struct acpi_battery *battery; + battery = &sbs->battery[id]; + + battery->alive = 0; + + battery->init_state = 0; battery->id = id; battery->sbs = sbs; - result = acpi_battery_read(battery); - if (result) - return result; - sprintf(battery->name, ACPI_BATTERY_DIR_NAME, id); -#ifdef CONFIG_ACPI_PROCFS - acpi_sbs_add_fs(&battery->proc_entry, acpi_battery_dir, - battery->name, &acpi_battery_info_fops, - &acpi_battery_state_fops, &acpi_battery_alarm_fops, - battery); -#endif - battery->bat.name = battery->name; - battery->bat.type = POWER_SUPPLY_TYPE_BATTERY; - if (!acpi_battery_mode(battery)) { - battery->bat.properties = sbs_charge_battery_props; - battery->bat.num_properties = - ARRAY_SIZE(sbs_charge_battery_props); - } else { - battery->bat.properties = sbs_energy_battery_props; - battery->bat.num_properties = - ARRAY_SIZE(sbs_energy_battery_props); + result = acpi_battery_select(battery); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_battery_select() failed")); + goto end; + } + + result = acpi_battery_get_present(battery); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_battery_get_present() failed")); + goto end; + } + + is_present = battery->battery_present; + + if (is_present) { + result = acpi_battery_init(battery); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_battery_init() failed")); + goto end; + } + battery->init_state = 1; + } + + sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id); + + result = acpi_sbs_generic_add_fs(&battery->battery_entry, + acpi_battery_dir, + dir_name, + &acpi_battery_info_fops, + &acpi_battery_state_fops, + &acpi_battery_alarm_fops, battery); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_sbs_generic_add_fs() failed")); + goto end; } - battery->bat.get_property = acpi_sbs_battery_get_property; - result = power_supply_register(&sbs->device->dev, &battery->bat); - device_create_file(battery->bat.dev, &alarm_attr); + battery->alive = 1; + printk(KERN_INFO PREFIX "%s [%s]: Battery Slot [%s] (battery %s)\n", - ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device), - battery->name, sbs->battery->present ? "present" : "absent"); + ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device), dir_name, + sbs->battery->battery_present ? "present" : "absent"); + + end: return result; } static void acpi_battery_remove(struct acpi_sbs *sbs, int id) { - if (sbs->battery[id].bat.dev) - device_remove_file(sbs->battery[id].bat.dev, &alarm_attr); - power_supply_unregister(&sbs->battery[id].bat); -#ifdef CONFIG_ACPI_PROCFS - if (sbs->battery[id].proc_entry) { - acpi_sbs_remove_fs(&(sbs->battery[id].proc_entry), - acpi_battery_dir); - } -#endif + + if (sbs->battery[id].battery_entry) { + acpi_sbs_generic_remove_fs(&(sbs->battery[id].battery_entry), + acpi_battery_dir); + } } -static int acpi_charger_add(struct acpi_sbs *sbs) +static int acpi_ac_add(struct acpi_sbs *sbs) { int result; result = acpi_ac_get_present(sbs); - if (result) + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_ac_get_present() failed")); goto end; -#ifdef CONFIG_ACPI_PROCFS - result = acpi_sbs_add_fs(&sbs->charger_entry, acpi_ac_dir, - ACPI_AC_DIR_NAME, NULL, - &acpi_ac_state_fops, NULL, sbs); - if (result) + } + + result = acpi_sbs_generic_add_fs(&sbs->ac_entry, + acpi_ac_dir, + ACPI_AC_DIR_NAME, + NULL, &acpi_ac_state_fops, NULL, sbs); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_sbs_generic_add_fs() failed")); goto end; -#endif - sbs->charger.name = "sbs-charger"; - sbs->charger.type = POWER_SUPPLY_TYPE_MAINS; - sbs->charger.properties = sbs_ac_props; - sbs->charger.num_properties = ARRAY_SIZE(sbs_ac_props); - sbs->charger.get_property = sbs_get_ac_property; - power_supply_register(&sbs->device->dev, &sbs->charger); + } + printk(KERN_INFO PREFIX "%s [%s]: AC Adapter [%s] (%s)\n", ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device), - ACPI_AC_DIR_NAME, sbs->charger_present ? "on-line" : "off-line"); + ACPI_AC_DIR_NAME, sbs->ac.ac_present ? "on-line" : "off-line"); + end: + return result; } -static void acpi_charger_remove(struct acpi_sbs *sbs) +static void acpi_ac_remove(struct acpi_sbs *sbs) { - if (sbs->charger.dev) - power_supply_unregister(&sbs->charger); -#ifdef CONFIG_ACPI_PROCFS - if (sbs->charger_entry) - acpi_sbs_remove_fs(&sbs->charger_entry, acpi_ac_dir); -#endif + + if (sbs->ac_entry) { + acpi_sbs_generic_remove_fs(&sbs->ac_entry, acpi_ac_dir); + } } -void acpi_sbs_callback(void *context) +static void acpi_sbs_update_time_run(unsigned long data) { - int id; - struct acpi_sbs *sbs = context; - struct acpi_battery *bat; - u8 saved_charger_state = sbs->charger_present; - u8 saved_battery_state; - acpi_ac_get_present(sbs); - if (sbs->charger_present != saved_charger_state) { -#ifdef CONFIG_ACPI_PROC_EVENT - acpi_bus_generate_proc_event4(ACPI_AC_CLASS, ACPI_AC_DIR_NAME, - ACPI_SBS_NOTIFY_STATUS, - sbs->charger_present); -#endif - kobject_uevent(&sbs->charger.dev->kobj, KOBJ_CHANGE); - } - if (sbs->manager_present) { - for (id = 0; id < MAX_SBS_BAT; ++id) { - if (!(sbs->batteries_supported & (1 << id))) - continue; - bat = &sbs->battery[id]; - saved_battery_state = bat->present; - acpi_battery_read(bat); - if (saved_battery_state == bat->present) - continue; -#ifdef CONFIG_ACPI_PROC_EVENT - acpi_bus_generate_proc_event4(ACPI_BATTERY_CLASS, - bat->name, - ACPI_SBS_NOTIFY_STATUS, - bat->present); -#endif - kobject_uevent(&bat->bat.dev->kobj, KOBJ_CHANGE); + acpi_os_execute(OSL_GPE_HANDLER, acpi_sbs_update_time, (void *)data); +} + +static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type) +{ + struct acpi_battery *battery; + int result = 0, cnt; + int old_ac_present = -1; + int old_battery_present = -1; + int new_ac_present = -1; + int new_battery_present = -1; + int id_min = 0, id_max = MAX_SBS_BAT - 1; + char dir_name[32]; + int do_battery_init = 0, do_ac_init = 0; + int old_remaining_capacity = 0; + int update_battery = 1; + int up_tm = update_time; + + if (sbs_zombie(sbs)) { + goto end; + } + + if (id >= 0) { + id_min = id_max = id; + } + + if (data_type == DATA_TYPE_COMMON && up_tm > 0) { + cnt = up_tm / (up_tm > UPDATE_DELAY ? UPDATE_DELAY : up_tm); + if (sbs->run_cnt % cnt != 0) { + update_battery = 0; + } + } + + sbs->run_cnt++; + + old_ac_present = sbs->ac.ac_present; + + result = acpi_ac_get_present(sbs); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_ac_get_present() failed")); + } + + new_ac_present = sbs->ac.ac_present; + + do_ac_init = (old_ac_present != new_ac_present); + if (sbs->run_cnt == 1 && data_type == DATA_TYPE_COMMON) { + do_ac_init = 1; + } + + if (do_ac_init) { + result = acpi_sbs_generate_event(sbs->device, + ACPI_SBS_AC_NOTIFY_STATUS, + new_ac_present, + ACPI_AC_DIR_NAME, + ACPI_AC_CLASS); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_sbs_generate_event() failed")); + } + } + + if (data_type == DATA_TYPE_COMMON) { + if (!do_ac_init && !update_battery) { + goto end; + } + } + + if (data_type == DATA_TYPE_AC_STATE && !do_ac_init) { + goto end; + } + + for (id = id_min; id <= id_max; id++) { + battery = &sbs->battery[id]; + if (battery->alive == 0) { + continue; + } + + old_remaining_capacity = battery->state.remaining_capacity; + + old_battery_present = battery->battery_present; + + result = acpi_battery_select(battery); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_battery_select() failed")); + } + + result = acpi_battery_get_present(battery); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_battery_get_present() failed")); + } + + new_battery_present = battery->battery_present; + + do_battery_init = ((old_battery_present != new_battery_present) + && new_battery_present); + if (!new_battery_present) + goto event; + if (do_ac_init || do_battery_init) { + result = acpi_battery_init(battery); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_battery_init() " + "failed")); + } + } + if (sbs_zombie(sbs)) { + goto end; + } + + if ((data_type == DATA_TYPE_COMMON + || data_type == DATA_TYPE_INFO) + && new_battery_present) { + result = acpi_battery_get_info(battery); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_battery_get_info() failed")); + } + } + if (data_type == DATA_TYPE_INFO) { + continue; + } + if (sbs_zombie(sbs)) { + goto end; + } + + if ((data_type == DATA_TYPE_COMMON + || data_type == DATA_TYPE_STATE) + && new_battery_present) { + result = acpi_battery_get_state(battery); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_battery_get_state() failed")); + } + } + if (data_type == DATA_TYPE_STATE) { + goto event; + } + if (sbs_zombie(sbs)) { + goto end; + } + + if ((data_type == DATA_TYPE_COMMON + || data_type == DATA_TYPE_ALARM) + && new_battery_present) { + result = acpi_battery_get_alarm(battery); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_battery_get_alarm() " + "failed")); + } + } + if (data_type == DATA_TYPE_ALARM) { + continue; + } + if (sbs_zombie(sbs)) { + goto end; + } + + event: + + if (old_battery_present != new_battery_present || do_ac_init || + old_remaining_capacity != + battery->state.remaining_capacity) { + sprintf(dir_name, ACPI_BATTERY_DIR_NAME, id); + result = acpi_sbs_generate_event(sbs->device, + ACPI_SBS_BATTERY_NOTIFY_STATUS, + new_battery_present, + dir_name, + ACPI_BATTERY_CLASS); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_sbs_generate_event() " + "failed")); + } } } + + end: + + return result; } -static int acpi_sbs_remove(struct acpi_device *device, int type); +static void acpi_sbs_update_time(void *data) +{ + struct acpi_sbs *sbs = data; + unsigned long delay = -1; + int result; + unsigned int up_tm = update_time; + + if (sbs_mutex_lock(sbs)) + return; + + result = acpi_sbs_update_run(sbs, -1, DATA_TYPE_COMMON); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_sbs_update_run() failed")); + } + + if (sbs_zombie(sbs)) { + goto end; + } + + if (!up_tm) { + if (timer_pending(&sbs->update_timer)) + del_timer(&sbs->update_timer); + } else { + delay = (up_tm > UPDATE_DELAY ? UPDATE_DELAY : up_tm); + delay = jiffies + HZ * delay; + if (timer_pending(&sbs->update_timer)) { + mod_timer(&sbs->update_timer, delay); + } else { + sbs->update_timer.data = (unsigned long)data; + sbs->update_timer.function = acpi_sbs_update_time_run; + sbs->update_timer.expires = delay; + add_timer(&sbs->update_timer); + } + } + + end: + + sbs_mutex_unlock(sbs); +} static int acpi_sbs_add(struct acpi_device *device) { - struct acpi_sbs *sbs; - int result = 0; + struct acpi_sbs *sbs = NULL; + int result = 0, remove_result = 0; int id; + acpi_status status = AE_OK; + unsigned long val; + + status = + acpi_evaluate_integer(device->handle, "_EC", NULL, &val); + if (ACPI_FAILURE(status)) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, "Error obtaining _EC")); + return -EIO; + } sbs = kzalloc(sizeof(struct acpi_sbs), GFP_KERNEL); if (!sbs) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, "kzalloc() failed")); result = -ENOMEM; goto end; } - mutex_init(&sbs->lock); + mutex_init(&sbs->mutex); - sbs->hc = acpi_driver_data(device->parent); + sbs_mutex_lock(sbs); + + sbs->base = 0xff & (val >> 8); sbs->device = device; + strcpy(acpi_device_name(device), ACPI_SBS_DEVICE_NAME); strcpy(acpi_device_class(device), ACPI_SBS_CLASS); acpi_driver_data(device) = sbs; - result = acpi_charger_add(sbs); + result = acpi_ac_add(sbs); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, "acpi_ac_add() failed")); + goto end; + } + + acpi_sbsm_get_info(sbs); + + if (!sbs->sbsm_present) { + result = acpi_battery_add(sbs, 0); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_battery_add() failed")); + goto end; + } + } else { + for (id = 0; id < MAX_SBS_BAT; id++) { + if ((sbs->sbsm_batteries_supported & (1 << id))) { + result = acpi_battery_add(sbs, id); + if (result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_battery_add() failed")); + goto end; + } + } + } + } + + init_timer(&sbs->update_timer); + result = acpi_check_update_proc(sbs); if (result) goto end; - result = acpi_manager_get_info(sbs); - if (!result) { - sbs->manager_present = 1; - for (id = 0; id < MAX_SBS_BAT; ++id) - if ((sbs->batteries_supported & (1 << id))) - acpi_battery_add(sbs, id); - } else - acpi_battery_add(sbs, 0); - acpi_smbus_register_callback(sbs->hc, acpi_sbs_callback, sbs); end: - if (result) - acpi_sbs_remove(device, 0); + + sbs_mutex_unlock(sbs); + + if (result) { + remove_result = acpi_sbs_remove(device, 0); + if (remove_result) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_sbs_remove() failed")); + } + } + return result; } @@ -947,25 +1713,39 @@ static int acpi_sbs_remove(struct acpi_device *device, int type) struct acpi_sbs *sbs; int id; - if (!device) + if (!device) { return -EINVAL; + } + sbs = acpi_driver_data(device); - if (!sbs) + if (!sbs) { return -EINVAL; - mutex_lock(&sbs->lock); - acpi_smbus_unregister_callback(sbs->hc); - for (id = 0; id < MAX_SBS_BAT; ++id) + } + + sbs_mutex_lock(sbs); + + sbs->zombie = 1; + del_timer_sync(&sbs->update_timer); + acpi_os_wait_events_complete(NULL); + del_timer_sync(&sbs->update_timer); + + for (id = 0; id < MAX_SBS_BAT; id++) { acpi_battery_remove(sbs, id); - acpi_charger_remove(sbs); - mutex_unlock(&sbs->lock); - mutex_destroy(&sbs->lock); + } + + acpi_ac_remove(sbs); + + sbs_mutex_unlock(sbs); + + mutex_destroy(&sbs->mutex); + kfree(sbs); + return 0; } static void acpi_sbs_rmdirs(void) { -#ifdef CONFIG_ACPI_PROCFS if (acpi_ac_dir) { acpi_unlock_ac_dir(acpi_ac_dir); acpi_ac_dir = NULL; @@ -974,58 +1754,69 @@ static void acpi_sbs_rmdirs(void) acpi_unlock_battery_dir(acpi_battery_dir); acpi_battery_dir = NULL; } -#endif } static int acpi_sbs_resume(struct acpi_device *device) { struct acpi_sbs *sbs; + if (!device) return -EINVAL; + sbs = device->driver_data; - acpi_sbs_callback(sbs); + + sbs->run_cnt = 0; + return 0; } -static struct acpi_driver acpi_sbs_driver = { - .name = "sbs", - .class = ACPI_SBS_CLASS, - .ids = sbs_device_ids, - .ops = { - .add = acpi_sbs_add, - .remove = acpi_sbs_remove, - .resume = acpi_sbs_resume, - }, -}; - static int __init acpi_sbs_init(void) { int result = 0; if (acpi_disabled) return -ENODEV; -#ifdef CONFIG_ACPI_PROCFS + + if (capacity_mode != DEF_CAPACITY_UNIT + && capacity_mode != MAH_CAPACITY_UNIT + && capacity_mode != MWH_CAPACITY_UNIT) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "invalid capacity_mode = %d", capacity_mode)); + return -EINVAL; + } + acpi_ac_dir = acpi_lock_ac_dir(); - if (!acpi_ac_dir) + if (!acpi_ac_dir) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_lock_ac_dir() failed")); return -ENODEV; + } + acpi_battery_dir = acpi_lock_battery_dir(); if (!acpi_battery_dir) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_lock_battery_dir() failed")); acpi_sbs_rmdirs(); return -ENODEV; } -#endif + result = acpi_bus_register_driver(&acpi_sbs_driver); if (result < 0) { + ACPI_EXCEPTION((AE_INFO, AE_ERROR, + "acpi_bus_register_driver() failed")); acpi_sbs_rmdirs(); return -ENODEV; } + return 0; } static void __exit acpi_sbs_exit(void) { acpi_bus_unregister_driver(&acpi_sbs_driver); + acpi_sbs_rmdirs(); + return; } diff --git a/trunk/drivers/acpi/sbshc.c b/trunk/drivers/acpi/sbshc.c deleted file mode 100644 index 046d7c3ed356..000000000000 --- a/trunk/drivers/acpi/sbshc.c +++ /dev/null @@ -1,309 +0,0 @@ -/* - * SMBus driver for ACPI Embedded Controller (v0.1) - * - * Copyright (c) 2007 Alexey Starikovskiy - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation version 2. - */ - -#include -#include -#include -#include -#include -#include -#include "sbshc.h" - -#define ACPI_SMB_HC_CLASS "smbus_host_controller" -#define ACPI_SMB_HC_DEVICE_NAME "ACPI SMBus HC" - -struct acpi_smb_hc { - struct acpi_ec *ec; - struct mutex lock; - wait_queue_head_t wait; - u8 offset; - u8 query_bit; - smbus_alarm_callback callback; - void *context; -}; - -static int acpi_smbus_hc_add(struct acpi_device *device); -static int acpi_smbus_hc_remove(struct acpi_device *device, int type); - -static const struct acpi_device_id sbs_device_ids[] = { - {"ACPI0001", 0}, - {"ACPI0005", 0}, - {"", 0}, -}; - -MODULE_DEVICE_TABLE(acpi, sbs_device_ids); - -static struct acpi_driver acpi_smb_hc_driver = { - .name = "smbus_hc", - .class = ACPI_SMB_HC_CLASS, - .ids = sbs_device_ids, - .ops = { - .add = acpi_smbus_hc_add, - .remove = acpi_smbus_hc_remove, - }, -}; - -union acpi_smb_status { - u8 raw; - struct { - u8 status:5; - u8 reserved:1; - u8 alarm:1; - u8 done:1; - } fields; -}; - -enum acpi_smb_status_codes { - SMBUS_OK = 0, - SMBUS_UNKNOWN_FAILURE = 0x07, - SMBUS_DEVICE_ADDRESS_NACK = 0x10, - SMBUS_DEVICE_ERROR = 0x11, - SMBUS_DEVICE_COMMAND_ACCESS_DENIED = 0x12, - SMBUS_UNKNOWN_ERROR = 0x13, - SMBUS_DEVICE_ACCESS_DENIED = 0x17, - SMBUS_TIMEOUT = 0x18, - SMBUS_HOST_UNSUPPORTED_PROTOCOL = 0x19, - SMBUS_BUSY = 0x1a, - SMBUS_PEC_ERROR = 0x1f, -}; - -enum acpi_smb_offset { - ACPI_SMB_PROTOCOL = 0, /* protocol, PEC */ - ACPI_SMB_STATUS = 1, /* status */ - ACPI_SMB_ADDRESS = 2, /* address */ - ACPI_SMB_COMMAND = 3, /* command */ - ACPI_SMB_DATA = 4, /* 32 data registers */ - ACPI_SMB_BLOCK_COUNT = 0x24, /* number of data bytes */ - ACPI_SMB_ALARM_ADDRESS = 0x25, /* alarm address */ - ACPI_SMB_ALARM_DATA = 0x26, /* 2 bytes alarm data */ -}; - -static inline int smb_hc_read(struct acpi_smb_hc *hc, u8 address, u8 *data) -{ - return ec_read(hc->offset + address, data); -} - -static inline int smb_hc_write(struct acpi_smb_hc *hc, u8 address, u8 data) -{ - return ec_write(hc->offset + address, data); -} - -static inline int smb_check_done(struct acpi_smb_hc *hc) -{ - union acpi_smb_status status = {.raw = 0}; - smb_hc_read(hc, ACPI_SMB_STATUS, &status.raw); - return status.fields.done && (status.fields.status == SMBUS_OK); -} - -static int wait_transaction_complete(struct acpi_smb_hc *hc, int timeout) -{ - if (wait_event_timeout(hc->wait, smb_check_done(hc), - msecs_to_jiffies(timeout))) - return 0; - else - return -ETIME; -} - -int acpi_smbus_transaction(struct acpi_smb_hc *hc, u8 protocol, u8 address, - u8 command, u8 *data, u8 length) -{ - int ret = -EFAULT, i; - u8 temp, sz = 0; - - mutex_lock(&hc->lock); - if (smb_hc_read(hc, ACPI_SMB_PROTOCOL, &temp)) - goto end; - if (temp) { - ret = -EBUSY; - goto end; - } - smb_hc_write(hc, ACPI_SMB_COMMAND, command); - smb_hc_write(hc, ACPI_SMB_COMMAND, command); - if (!(protocol & 0x01)) { - smb_hc_write(hc, ACPI_SMB_BLOCK_COUNT, length); - for (i = 0; i < length; ++i) - smb_hc_write(hc, ACPI_SMB_DATA + i, data[i]); - } - smb_hc_write(hc, ACPI_SMB_ADDRESS, address << 1); - smb_hc_write(hc, ACPI_SMB_PROTOCOL, protocol); - /* - * Wait for completion. Save the status code, data size, - * and data into the return package (if required by the protocol). - */ - ret = wait_transaction_complete(hc, 1000); - if (ret || !(protocol & 0x01)) - goto end; - switch (protocol) { - case SMBUS_RECEIVE_BYTE: - case SMBUS_READ_BYTE: - sz = 1; - break; - case SMBUS_READ_WORD: - sz = 2; - break; - case SMBUS_READ_BLOCK: - if (smb_hc_read(hc, ACPI_SMB_BLOCK_COUNT, &sz)) { - ret = -EFAULT; - goto end; - } - sz &= 0x1f; - break; - } - for (i = 0; i < sz; ++i) - smb_hc_read(hc, ACPI_SMB_DATA + i, &data[i]); - end: - mutex_unlock(&hc->lock); - return ret; -} - -int acpi_smbus_read(struct acpi_smb_hc *hc, u8 protocol, u8 address, - u8 command, u8 *data) -{ - return acpi_smbus_transaction(hc, protocol, address, command, data, 0); -} - -EXPORT_SYMBOL_GPL(acpi_smbus_read); - -int acpi_smbus_write(struct acpi_smb_hc *hc, u8 protocol, u8 address, - u8 command, u8 *data, u8 length) -{ - return acpi_smbus_transaction(hc, protocol, address, command, data, length); -} - -EXPORT_SYMBOL_GPL(acpi_smbus_write); - -int acpi_smbus_register_callback(struct acpi_smb_hc *hc, - smbus_alarm_callback callback, void *context) -{ - mutex_lock(&hc->lock); - hc->callback = callback; - hc->context = context; - mutex_unlock(&hc->lock); - return 0; -} - -EXPORT_SYMBOL_GPL(acpi_smbus_register_callback); - -int acpi_smbus_unregister_callback(struct acpi_smb_hc *hc) -{ - mutex_lock(&hc->lock); - hc->callback = NULL; - hc->context = NULL; - mutex_unlock(&hc->lock); - return 0; -} - -EXPORT_SYMBOL_GPL(acpi_smbus_unregister_callback); - -static void acpi_smbus_callback(void *context) -{ - struct acpi_smb_hc *hc = context; - - if (hc->callback) - hc->callback(hc->context); -} - -static int smbus_alarm(void *context) -{ - struct acpi_smb_hc *hc = context; - union acpi_smb_status status; - if (smb_hc_read(hc, ACPI_SMB_STATUS, &status.raw)) - return 0; - /* Check if it is only a completion notify */ - if (status.fields.done) - wake_up(&hc->wait); - if (!status.fields.alarm) - return 0; - mutex_lock(&hc->lock); - smb_hc_write(hc, ACPI_SMB_STATUS, status.raw); - if (hc->callback) - acpi_os_execute(OSL_GPE_HANDLER, acpi_smbus_callback, hc); - mutex_unlock(&hc->lock); - return 0; -} - -typedef int (*acpi_ec_query_func) (void *data); - -extern int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit, - acpi_handle handle, acpi_ec_query_func func, - void *data); - -static int acpi_smbus_hc_add(struct acpi_device *device) -{ - int status; - unsigned long val; - struct acpi_smb_hc *hc; - - if (!device) - return -EINVAL; - - status = acpi_evaluate_integer(device->handle, "_EC", NULL, &val); - if (ACPI_FAILURE(status)) { - printk(KERN_ERR PREFIX "error obtaining _EC.\n"); - return -EIO; - } - - strcpy(acpi_device_name(device), ACPI_SMB_HC_DEVICE_NAME); - strcpy(acpi_device_class(device), ACPI_SMB_HC_CLASS); - - hc = kzalloc(sizeof(struct acpi_smb_hc), GFP_KERNEL); - if (!hc) - return -ENOMEM; - mutex_init(&hc->lock); - init_waitqueue_head(&hc->wait); - - hc->ec = acpi_driver_data(device->parent); - hc->offset = (val >> 8) & 0xff; - hc->query_bit = val & 0xff; - acpi_driver_data(device) = hc; - - acpi_ec_add_query_handler(hc->ec, hc->query_bit, NULL, smbus_alarm, hc); - printk(KERN_INFO PREFIX "SBS HC: EC = 0x%p, offset = 0x%0x, query_bit = 0x%0x\n", - hc->ec, hc->offset, hc->query_bit); - - return 0; -} - -extern void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit); - -static int acpi_smbus_hc_remove(struct acpi_device *device, int type) -{ - struct acpi_smb_hc *hc; - - if (!device) - return -EINVAL; - - hc = acpi_driver_data(device); - acpi_ec_remove_query_handler(hc->ec, hc->query_bit); - kfree(hc); - return 0; -} - -static int __init acpi_smb_hc_init(void) -{ - int result; - - result = acpi_bus_register_driver(&acpi_smb_hc_driver); - if (result < 0) - return -ENODEV; - return 0; -} - -static void __exit acpi_smb_hc_exit(void) -{ - acpi_bus_unregister_driver(&acpi_smb_hc_driver); -} - -module_init(acpi_smb_hc_init); -module_exit(acpi_smb_hc_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Alexey Starikovskiy"); -MODULE_DESCRIPTION("ACPI SMBus HC driver"); diff --git a/trunk/drivers/acpi/sbshc.h b/trunk/drivers/acpi/sbshc.h deleted file mode 100644 index 3bda3491a97b..000000000000 --- a/trunk/drivers/acpi/sbshc.h +++ /dev/null @@ -1,27 +0,0 @@ -struct acpi_smb_hc; -enum acpi_smb_protocol { - SMBUS_WRITE_QUICK = 2, - SMBUS_READ_QUICK = 3, - SMBUS_SEND_BYTE = 4, - SMBUS_RECEIVE_BYTE = 5, - SMBUS_WRITE_BYTE = 6, - SMBUS_READ_BYTE = 7, - SMBUS_WRITE_WORD = 8, - SMBUS_READ_WORD = 9, - SMBUS_WRITE_BLOCK = 0xa, - SMBUS_READ_BLOCK = 0xb, - SMBUS_PROCESS_CALL = 0xc, - SMBUS_BLOCK_PROCESS_CALL = 0xd, -}; - -static const u8 SMBUS_PEC = 0x80; - -typedef void (*smbus_alarm_callback)(void *context); - -extern int acpi_smbus_read(struct acpi_smb_hc *hc, u8 protocol, u8 address, - u8 command, u8 * data); -extern int acpi_smbus_write(struct acpi_smb_hc *hc, u8 protocol, u8 slave_address, - u8 command, u8 * data, u8 length); -extern int acpi_smbus_register_callback(struct acpi_smb_hc *hc, - smbus_alarm_callback callback, void *context); -extern int acpi_smbus_unregister_callback(struct acpi_smb_hc *hc); diff --git a/trunk/drivers/acpi/sleep/main.c b/trunk/drivers/acpi/sleep/main.c index f3d3867303ec..5055acf2163c 100644 --- a/trunk/drivers/acpi/sleep/main.c +++ b/trunk/drivers/acpi/sleep/main.c @@ -44,12 +44,13 @@ int acpi_sleep_prepare(u32 acpi_state) ACPI_FLUSH_CPU_CACHE(); acpi_enable_wakeup_device_prep(acpi_state); #endif + acpi_gpe_sleep_prepare(acpi_state); acpi_enter_sleep_state_prep(acpi_state); return 0; } #ifdef CONFIG_SUSPEND -static struct platform_suspend_ops acpi_pm_ops; +static struct pm_ops acpi_pm_ops; extern void do_suspend_lowlevel(void); @@ -84,12 +85,13 @@ static int acpi_pm_set_target(suspend_state_t pm_state) /** * acpi_pm_prepare - Do preliminary suspend work. + * @pm_state: ignored * * If necessary, set the firmware waking vector and do arch-specific * nastiness to get the wakeup code to the waking vector. */ -static int acpi_pm_prepare(void) +static int acpi_pm_prepare(suspend_state_t pm_state) { int error = acpi_sleep_prepare(acpi_target_sleep_state); @@ -158,12 +160,13 @@ static int acpi_pm_enter(suspend_state_t pm_state) /** * acpi_pm_finish - Finish up suspend sequence. + * @pm_state: ignored * * This is called after we wake back up (or if entering the sleep state * failed). */ -static void acpi_pm_finish(void) +static int acpi_pm_finish(suspend_state_t pm_state) { u32 acpi_state = acpi_target_sleep_state; @@ -181,6 +184,7 @@ static void acpi_pm_finish(void) init_8259A(0); } #endif + return 0; } static int acpi_pm_state_valid(suspend_state_t pm_state) @@ -199,7 +203,7 @@ static int acpi_pm_state_valid(suspend_state_t pm_state) } } -static struct platform_suspend_ops acpi_pm_ops = { +static struct pm_ops acpi_pm_ops = { .valid = acpi_pm_state_valid, .set_target = acpi_pm_set_target, .prepare = acpi_pm_prepare, @@ -229,12 +233,6 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { #endif /* CONFIG_SUSPEND */ #ifdef CONFIG_HIBERNATION -static int acpi_hibernation_start(void) -{ - acpi_target_sleep_state = ACPI_STATE_S4; - return 0; -} - static int acpi_hibernation_prepare(void) { return acpi_sleep_prepare(ACPI_STATE_S4); @@ -256,29 +254,13 @@ static int acpi_hibernation_enter(void) return ACPI_SUCCESS(status) ? 0 : -EFAULT; } -static void acpi_hibernation_leave(void) -{ - /* - * If ACPI is not enabled by the BIOS and the boot kernel, we need to - * enable it here. - */ - acpi_enable(); -} - static void acpi_hibernation_finish(void) { - /* - * If ACPI is not enabled by the BIOS and the boot kernel, we need to - * enable it here. - */ - acpi_enable(); acpi_leave_sleep_state(ACPI_STATE_S4); acpi_disable_wakeup_device(ACPI_STATE_S4); /* reset firmware waking vector */ acpi_set_firmware_waking_vector((acpi_physical_address) 0); - - acpi_target_sleep_state = ACPI_STATE_S0; } static int acpi_hibernation_pre_restore(void) @@ -295,13 +277,10 @@ static void acpi_hibernation_restore_cleanup(void) acpi_hw_enable_all_runtime_gpes(); } -static struct platform_hibernation_ops acpi_hibernation_ops = { - .start = acpi_hibernation_start, - .pre_snapshot = acpi_hibernation_prepare, - .finish = acpi_hibernation_finish, +static struct hibernation_ops acpi_hibernation_ops = { .prepare = acpi_hibernation_prepare, .enter = acpi_hibernation_enter, - .leave = acpi_hibernation_leave, + .finish = acpi_hibernation_finish, .pre_restore = acpi_hibernation_pre_restore, .restore_cleanup = acpi_hibernation_restore_cleanup, }; @@ -438,7 +417,7 @@ int __init acpi_sleep_init(void) } } - suspend_set_ops(&acpi_pm_ops); + pm_set_ops(&acpi_pm_ops); #endif #ifdef CONFIG_HIBERNATION diff --git a/trunk/drivers/acpi/sleep/sleep.h b/trunk/drivers/acpi/sleep/sleep.h index a2ea125ae2d0..ff1f8504f497 100644 --- a/trunk/drivers/acpi/sleep/sleep.h +++ b/trunk/drivers/acpi/sleep/sleep.h @@ -5,5 +5,6 @@ extern int acpi_suspend (u32 state); extern void acpi_enable_wakeup_device_prep(u8 sleep_state); extern void acpi_enable_wakeup_device(u8 sleep_state); extern void acpi_disable_wakeup_device(u8 sleep_state); +extern void acpi_gpe_sleep_prepare(u32 sleep_state); extern int acpi_sleep_prepare(u32 acpi_state); diff --git a/trunk/drivers/acpi/sleep/wakeup.c b/trunk/drivers/acpi/sleep/wakeup.c index ed8e41becf0c..97c27ddb144d 100644 --- a/trunk/drivers/acpi/sleep/wakeup.c +++ b/trunk/drivers/acpi/sleep/wakeup.c @@ -64,29 +64,36 @@ void acpi_enable_wakeup_device(u8 sleep_state) ACPI_FUNCTION_TRACE("acpi_enable_wakeup_device"); spin_lock(&acpi_device_lock); list_for_each_safe(node, next, &acpi_wakeup_device_list) { - struct acpi_device *dev = - container_of(node, struct acpi_device, wakeup_list); - if (!dev->wakeup.flags.valid) - continue; + struct acpi_device *dev = container_of(node, + struct acpi_device, + wakeup_list); + /* If users want to disable run-wake GPE, * we only disable it for wake and leave it for runtime */ - if (!dev->wakeup.state.enabled || - sleep_state > (u32) dev->wakeup.sleep_state) { - if (dev->wakeup.flags.run_wake) { - spin_unlock(&acpi_device_lock); - /* set_gpe_type will disable GPE, leave it like that */ - acpi_set_gpe_type(dev->wakeup.gpe_device, - dev->wakeup.gpe_number, - ACPI_GPE_TYPE_RUNTIME); - spin_lock(&acpi_device_lock); - } + if (dev->wakeup.flags.run_wake && !dev->wakeup.state.enabled) { + spin_unlock(&acpi_device_lock); + acpi_set_gpe_type(dev->wakeup.gpe_device, + dev->wakeup.gpe_number, + ACPI_GPE_TYPE_RUNTIME); + /* Re-enable it, since set_gpe_type will disable it */ + acpi_enable_gpe(dev->wakeup.gpe_device, + dev->wakeup.gpe_number, ACPI_ISR); + spin_lock(&acpi_device_lock); continue; } + + if (!dev->wakeup.flags.valid || + !dev->wakeup.state.enabled || + (sleep_state > (u32) dev->wakeup.sleep_state)) + continue; + spin_unlock(&acpi_device_lock); + /* run-wake GPE has been enabled */ if (!dev->wakeup.flags.run_wake) acpi_enable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number, ACPI_ISR); + dev->wakeup.state.active = 1; spin_lock(&acpi_device_lock); } spin_unlock(&acpi_device_lock); @@ -105,26 +112,27 @@ void acpi_disable_wakeup_device(u8 sleep_state) spin_lock(&acpi_device_lock); list_for_each_safe(node, next, &acpi_wakeup_device_list) { - struct acpi_device *dev = - container_of(node, struct acpi_device, wakeup_list); + struct acpi_device *dev = container_of(node, + struct acpi_device, + wakeup_list); - if (!dev->wakeup.flags.valid) - continue; - if (!dev->wakeup.state.enabled || - sleep_state > (u32) dev->wakeup.sleep_state) { - if (dev->wakeup.flags.run_wake) { - spin_unlock(&acpi_device_lock); - acpi_set_gpe_type(dev->wakeup.gpe_device, - dev->wakeup.gpe_number, - ACPI_GPE_TYPE_WAKE_RUN); - /* Re-enable it, since set_gpe_type will disable it */ - acpi_enable_gpe(dev->wakeup.gpe_device, - dev->wakeup.gpe_number, ACPI_NOT_ISR); - spin_lock(&acpi_device_lock); - } + if (dev->wakeup.flags.run_wake && !dev->wakeup.state.enabled) { + spin_unlock(&acpi_device_lock); + acpi_set_gpe_type(dev->wakeup.gpe_device, + dev->wakeup.gpe_number, + ACPI_GPE_TYPE_WAKE_RUN); + /* Re-enable it, since set_gpe_type will disable it */ + acpi_enable_gpe(dev->wakeup.gpe_device, + dev->wakeup.gpe_number, ACPI_NOT_ISR); + spin_lock(&acpi_device_lock); continue; } + if (!dev->wakeup.flags.valid || + !dev->wakeup.state.active || + (sleep_state > (u32) dev->wakeup.sleep_state)) + continue; + spin_unlock(&acpi_device_lock); acpi_disable_wakeup_device_power(dev); /* Never disable run-wake GPE */ @@ -134,6 +142,7 @@ void acpi_disable_wakeup_device(u8 sleep_state) acpi_clear_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number, ACPI_NOT_ISR); } + dev->wakeup.state.active = 0; spin_lock(&acpi_device_lock); } spin_unlock(&acpi_device_lock); @@ -151,20 +160,48 @@ static int __init acpi_wakeup_device_init(void) struct acpi_device *dev = container_of(node, struct acpi_device, wakeup_list); + /* In case user doesn't load button driver */ - if (!dev->wakeup.flags.run_wake || dev->wakeup.state.enabled) - continue; - spin_unlock(&acpi_device_lock); - acpi_set_gpe_type(dev->wakeup.gpe_device, - dev->wakeup.gpe_number, - ACPI_GPE_TYPE_WAKE_RUN); - acpi_enable_gpe(dev->wakeup.gpe_device, - dev->wakeup.gpe_number, ACPI_NOT_ISR); - dev->wakeup.state.enabled = 1; - spin_lock(&acpi_device_lock); + if (dev->wakeup.flags.run_wake && !dev->wakeup.state.enabled) { + spin_unlock(&acpi_device_lock); + acpi_set_gpe_type(dev->wakeup.gpe_device, + dev->wakeup.gpe_number, + ACPI_GPE_TYPE_WAKE_RUN); + acpi_enable_gpe(dev->wakeup.gpe_device, + dev->wakeup.gpe_number, ACPI_NOT_ISR); + dev->wakeup.state.enabled = 1; + spin_lock(&acpi_device_lock); + } } spin_unlock(&acpi_device_lock); + return 0; } late_initcall(acpi_wakeup_device_init); + +/* + * Disable all wakeup GPEs before entering requested sleep state. + * @sleep_state: ACPI state + * Since acpi_enter_sleep_state() will disable all + * RUNTIME GPEs, we simply mark all GPES that + * are not enabled for wakeup from requested state as RUNTIME. + */ +void acpi_gpe_sleep_prepare(u32 sleep_state) +{ + struct list_head *node, *next; + + list_for_each_safe(node, next, &acpi_wakeup_device_list) { + struct acpi_device *dev = container_of(node, + struct acpi_device, + wakeup_list); + + /* The GPE can wakeup system from this state, don't touch it */ + if ((u32) dev->wakeup.sleep_state >= sleep_state) + continue; + /* acpi_set_gpe_type will automatically disable GPE */ + acpi_set_gpe_type(dev->wakeup.gpe_device, + dev->wakeup.gpe_number, + ACPI_GPE_TYPE_RUNTIME); + } +} diff --git a/trunk/drivers/acpi/tables/tbutils.c b/trunk/drivers/acpi/tables/tbutils.c index 5f1d85f2ffe4..8cc9492ffbf2 100644 --- a/trunk/drivers/acpi/tables/tbutils.c +++ b/trunk/drivers/acpi/tables/tbutils.c @@ -400,7 +400,7 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags) u32 table_count; struct acpi_table_header *table; acpi_physical_address address; - acpi_physical_address uninitialized_var(rsdt_address); + acpi_physical_address rsdt_address; u32 length; u8 *table_entry; acpi_status status; diff --git a/trunk/drivers/acpi/thermal.c b/trunk/drivers/acpi/thermal.c index 5f79b4451212..ad898e10c1a9 100644 --- a/trunk/drivers/acpi/thermal.c +++ b/trunk/drivers/acpi/thermal.c @@ -195,7 +195,6 @@ struct acpi_thermal { struct acpi_thermal_trips trips; struct acpi_handle_list devices; struct timer_list timer; - struct mutex lock; }; static const struct file_operations acpi_thermal_state_fops = { @@ -712,7 +711,6 @@ static void acpi_thermal_check(void *data) int result = 0; struct acpi_thermal *tz = data; unsigned long sleep_time = 0; - unsigned long timeout_jiffies = 0; int i = 0; struct acpi_thermal_state state; @@ -722,15 +720,11 @@ static void acpi_thermal_check(void *data) return; } - /* Check if someone else is already running */ - if (!mutex_trylock(&tz->lock)) - return; - state = tz->state; result = acpi_thermal_get_temperature(tz); if (result) - goto unlock; + return; memset(&tz->state, 0, sizeof(tz->state)); @@ -793,13 +787,10 @@ static void acpi_thermal_check(void *data) * a thermal event occurs). Note that _TSP and _TZD values are * given in 1/10th seconds (we must covert to milliseconds). */ - if (tz->state.passive) { + if (tz->state.passive) sleep_time = tz->trips.passive.tsp * 100; - timeout_jiffies = jiffies + (HZ * sleep_time) / 1000; - } else if (tz->polling_frequency > 0) { + else if (tz->polling_frequency > 0) sleep_time = tz->polling_frequency * 100; - timeout_jiffies = round_jiffies(jiffies + (HZ * sleep_time) / 1000); - } ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: temperature[%lu] sleep[%lu]\n", tz->name, tz->temperature, sleep_time)); @@ -813,16 +804,17 @@ static void acpi_thermal_check(void *data) del_timer(&(tz->timer)); } else { if (timer_pending(&(tz->timer))) - mod_timer(&(tz->timer), timeout_jiffies); + mod_timer(&(tz->timer), + jiffies + (HZ * sleep_time) / 1000); else { tz->timer.data = (unsigned long)tz; tz->timer.function = acpi_thermal_run; - tz->timer.expires = timeout_jiffies; + tz->timer.expires = jiffies + (HZ * sleep_time) / 1000; add_timer(&(tz->timer)); } } - unlock: - mutex_unlock(&tz->lock); + + return; } /* -------------------------------------------------------------------------- @@ -1259,7 +1251,7 @@ static int acpi_thermal_add(struct acpi_device *device) strcpy(acpi_device_name(device), ACPI_THERMAL_DEVICE_NAME); strcpy(acpi_device_class(device), ACPI_THERMAL_CLASS); acpi_driver_data(device) = tz; - mutex_init(&tz->lock); + result = acpi_thermal_get_info(tz); if (result) goto end; @@ -1329,7 +1321,7 @@ static int acpi_thermal_remove(struct acpi_device *device, int type) } acpi_thermal_remove_fs(device); - mutex_destroy(&tz->lock); + kfree(tz); return 0; } diff --git a/trunk/drivers/acpi/video.c b/trunk/drivers/acpi/video.c index bac956b30c57..b8a2095cb5ee 100644 --- a/trunk/drivers/acpi/video.c +++ b/trunk/drivers/acpi/video.c @@ -409,17 +409,14 @@ acpi_video_device_lcd_query_levels(struct acpi_video_device *device, static int acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level) { - int status = AE_OK; + int status; union acpi_object arg0 = { ACPI_TYPE_INTEGER }; struct acpi_object_list args = { 1, &arg0 }; arg0.integer.value = level; + status = acpi_evaluate_object(device->dev->handle, "_BCM", &args, NULL); - if (device->cap._BCM) - status = acpi_evaluate_object(device->dev->handle, "_BCM", - &args, NULL); - device->brightness->curr = level; return status; } @@ -427,11 +424,11 @@ static int acpi_video_device_lcd_get_level_current(struct acpi_video_device *device, unsigned long *level) { - if (device->cap._BQC) - return acpi_evaluate_integer(device->dev->handle, "_BQC", NULL, - level); - *level = device->brightness->curr; - return AE_OK; + int status; + + status = acpi_evaluate_integer(device->dev->handle, "_BQC", NULL, level); + + return status; } static int @@ -1636,20 +1633,9 @@ static int acpi_video_get_next_level(struct acpi_video_device *device, u32 level_current, u32 event) { - int min, max, min_above, max_below, i, l, delta = 255; + int min, max, min_above, max_below, i, l; max = max_below = 0; min = min_above = 255; - /* Find closest level to level_current */ - for (i = 0; i < device->brightness->count; i++) { - l = device->brightness->levels[i]; - if (abs(l - level_current) < abs(delta)) { - delta = l - level_current; - if (!delta) - break; - } - } - /* Ajust level_current to closest available level */ - level_current += delta; for (i = 0; i < device->brightness->count; i++) { l = device->brightness->levels[i]; if (l < min) diff --git a/trunk/drivers/ata/Kconfig b/trunk/drivers/ata/Kconfig index ba63619ae5df..33f5eb038773 100644 --- a/trunk/drivers/ata/Kconfig +++ b/trunk/drivers/ata/Kconfig @@ -182,15 +182,6 @@ config PATA_ACPI firmware in the BIOS. This driver can sometimes handle otherwise unsupported hardware. -config SATA_FSL - tristate "Freescale 3.0Gbps SATA support" - depends on PPC_MPC837x - help - This option enables support for Freescale 3.0Gbps SATA controller. - It can be found on MPC837x and MPC8315. - - If unsure, say N. - config PATA_ALI tristate "ALi PATA support (Experimental)" depends on PCI && EXPERIMENTAL @@ -650,4 +641,11 @@ config PATA_BF54X If unsure, say N. +config PATA_BF54X_DMA + bool "DMA mode" + depends on PATA_BF54X + default y + help + Enable DMA mode for Blackfin ATAPI controller. + endif # ATA diff --git a/trunk/drivers/ata/Makefile b/trunk/drivers/ata/Makefile index b13feb2c5dae..6bdc307649e6 100644 --- a/trunk/drivers/ata/Makefile +++ b/trunk/drivers/ata/Makefile @@ -17,7 +17,6 @@ obj-$(CONFIG_SATA_ULI) += sata_uli.o obj-$(CONFIG_SATA_MV) += sata_mv.o obj-$(CONFIG_SATA_INIC162X) += sata_inic162x.o obj-$(CONFIG_PDC_ADMA) += pdc_adma.o -obj-$(CONFIG_SATA_FSL) += sata_fsl.o obj-$(CONFIG_PATA_ALI) += pata_ali.o obj-$(CONFIG_PATA_AMD) += pata_amd.o diff --git a/trunk/drivers/ata/libata-sff.c b/trunk/drivers/ata/libata-sff.c index f9e4cd527942..026439e05afe 100644 --- a/trunk/drivers/ata/libata-sff.c +++ b/trunk/drivers/ata/libata-sff.c @@ -156,7 +156,7 @@ void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf) { struct ata_ioports *ioaddr = &ap->ioaddr; - tf->command = ata_chk_status(ap); + tf->command = ata_check_status(ap); tf->feature = ioread8(ioaddr->error_addr); tf->nsect = ioread8(ioaddr->nsect_addr); tf->lbal = ioread8(ioaddr->lbal_addr); @@ -882,7 +882,7 @@ unsigned long ata_pci_default_filter(struct ata_device *adev, unsigned long xfer /* Filter out DMA modes if the device has been configured by the BIOS as PIO only */ - if (adev->link->ap->ioaddr.bmdma_addr == NULL) + if (adev->link->ap->ioaddr.bmdma_addr == 0) xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA); return xfer_mask; } diff --git a/trunk/drivers/ata/pata_acpi.c b/trunk/drivers/ata/pata_acpi.c index 0f6f7bcc3def..5d3920f6fd69 100644 --- a/trunk/drivers/ata/pata_acpi.c +++ b/trunk/drivers/ata/pata_acpi.c @@ -370,10 +370,8 @@ static struct pci_driver pacpi_pci_driver = { .id_table = pacpi_pci_tbl, .probe = pacpi_init_one, .remove = ata_pci_remove_one, -#ifdef CONFIG_PM .suspend = ata_pci_device_suspend, .resume = ata_pci_device_resume, -#endif }; static int __init pacpi_init(void) diff --git a/trunk/drivers/ata/pata_bf54x.c b/trunk/drivers/ata/pata_bf54x.c index b5e38426b815..747549e4563a 100644 --- a/trunk/drivers/ata/pata_bf54x.c +++ b/trunk/drivers/ata/pata_bf54x.c @@ -1092,15 +1092,14 @@ static unsigned int bfin_bus_softreset(struct ata_port *ap, * Note: Original code is ata_std_softreset(). */ -static int bfin_std_softreset(struct ata_link *link, unsigned int *classes, +static int bfin_std_softreset(struct ata_port *ap, unsigned int *classes, unsigned long deadline) { - struct ata_port *ap = link->ap; unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS; unsigned int devmask = 0, err_mask; u8 err; - if (ata_link_offline(link)) { + if (ata_port_offline(ap)) { classes[0] = ATA_DEV_NONE; goto out; } @@ -1123,11 +1122,9 @@ static int bfin_std_softreset(struct ata_link *link, unsigned int *classes, } /* determine by signature whether we have ATA or ATAPI devices */ - classes[0] = ata_dev_try_classify(&ap->link.device[0], - devmask & (1 << 0), &err); + classes[0] = ata_dev_try_classify(ap, 0, &err); if (slave_possible && err != 0x81) - classes[1] = ata_dev_try_classify(&ap->link.device[1], - devmask & (1 << 1), &err); + classes[1] = ata_dev_try_classify(ap, 1, &err); out: return 0; @@ -1170,7 +1167,7 @@ static unsigned char bfin_bmdma_status(struct ata_port *ap) static void bfin_data_xfer(struct ata_device *adev, unsigned char *buf, unsigned int buflen, int write_data) { - struct ata_port *ap = adev->link->ap; + struct ata_port *ap = adev->ap; unsigned int words = buflen >> 1; unsigned short *buf16 = (u16 *) buf; void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr; @@ -1209,10 +1206,7 @@ static void bfin_irq_clear(struct ata_port *ap) void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr; pr_debug("in atapi irq clear\n"); - - ATAPI_SET_INT_STATUS(base, ATAPI_GET_INT_STATUS(base)|ATAPI_DEV_INT - | MULTI_DONE_INT | UDMAIN_DONE_INT | UDMAOUT_DONE_INT - | MULTI_TERM_INT | UDMAIN_TERM_INT | UDMAOUT_TERM_INT); + ATAPI_SET_INT_STATUS(base, 0x1FF); } /** @@ -1239,6 +1233,33 @@ static unsigned char bfin_irq_on(struct ata_port *ap) return tmp; } +/** + * bfin_irq_ack - Acknowledge a device interrupt. + * @ap: Port on which interrupts are enabled. + * + * Note: Original code is ata_irq_ack(). + */ + +static unsigned char bfin_irq_ack(struct ata_port *ap, unsigned int chk_drq) +{ + void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr; + unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY; + unsigned char status; + + pr_debug("in atapi irq ack\n"); + status = ata_busy_wait(ap, bits, 1000); + if (status & bits) + if (ata_msg_err(ap)) + dev_err(ap->dev, "abnormal status 0x%X\n", status); + + /* get controller status; clear intr, err bits */ + ATAPI_SET_INT_STATUS(base, ATAPI_GET_INT_STATUS(base)|ATAPI_DEV_INT + | MULTI_DONE_INT | UDMAIN_DONE_INT | UDMAOUT_DONE_INT + | MULTI_TERM_INT | UDMAIN_TERM_INT | UDMAOUT_TERM_INT); + + return bfin_bmdma_status(ap); +} + /** * bfin_bmdma_freeze - Freeze DMA controller port * @ap: port to freeze @@ -1287,9 +1308,8 @@ void bfin_bmdma_thaw(struct ata_port *ap) * Note: Original code is ata_std_postreset(). */ -static void bfin_std_postreset(struct ata_link *link, unsigned int *classes) +static void bfin_std_postreset(struct ata_port *ap, unsigned int *classes) { - struct ata_port *ap = link->ap; void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr; /* re-enable interrupts */ @@ -1375,6 +1395,7 @@ static struct scsi_host_template bfin_sht = { }; static const struct ata_port_operations bfin_pata_ops = { + .port_disable = ata_port_disable, .set_piomode = bfin_set_piomode, .set_dmamode = bfin_set_dmamode, @@ -1402,6 +1423,7 @@ static const struct ata_port_operations bfin_pata_ops = { .irq_handler = ata_interrupt, .irq_clear = bfin_irq_clear, .irq_on = bfin_irq_on, + .irq_ack = bfin_irq_ack, .port_start = bfin_port_start, .port_stop = bfin_port_stop, @@ -1415,7 +1437,11 @@ static struct ata_port_info bfin_port_info[] = { | ATA_FLAG_NO_LEGACY, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0, +#ifdef CONFIG_PATA_BF54X_DMA + .udma_mask = ATA_UDMA5, +#else .udma_mask = 0, +#endif .port_ops = &bfin_pata_ops, }, }; @@ -1581,25 +1607,9 @@ static struct platform_driver bfin_atapi_driver = { }, }; -#define ATAPI_MODE_SIZE 10 -static char bfin_atapi_mode[ATAPI_MODE_SIZE]; - static int __init bfin_atapi_init(void) { pr_info("register bfin atapi driver\n"); - - switch(bfin_atapi_mode[0]) { - case 'p': - case 'P': - break; - case 'm': - case 'M': - bfin_port_info[0].mwdma_mask = ATA_MWDMA2; - break; - default: - bfin_port_info[0].udma_mask = ATA_UDMA5; - }; - return platform_driver_register(&bfin_atapi_driver); } @@ -1610,13 +1620,6 @@ static void __exit bfin_atapi_exit(void) module_init(bfin_atapi_init); module_exit(bfin_atapi_exit); -/* - * ATAPI mode: - * pio/PIO - * udma/UDMA (default) - * mwdma/MWDMA - */ -module_param_string(bfin_atapi_mode, bfin_atapi_mode, ATAPI_MODE_SIZE, 0); MODULE_AUTHOR("Sonic Zhang "); MODULE_DESCRIPTION("PATA driver for blackfin 54x ATAPI controller"); diff --git a/trunk/drivers/ata/pdc_adma.c b/trunk/drivers/ata/pdc_adma.c index 199f7e150eb3..8d1b03d5bcb1 100644 --- a/trunk/drivers/ata/pdc_adma.c +++ b/trunk/drivers/ata/pdc_adma.c @@ -318,7 +318,7 @@ static int adma_fill_sg(struct ata_queued_cmd *qc) struct scatterlist *sg; struct ata_port *ap = qc->ap; struct adma_port_priv *pp = ap->private_data; - u8 *buf = pp->pkt, *last_buf = NULL; + u8 *buf = pp->pkt; int i = (2 + buf[3]) * 8; u8 pFLAGS = pORD | ((qc->tf.flags & ATA_TFLAG_WRITE) ? pDIRO : 0); @@ -334,7 +334,8 @@ static int adma_fill_sg(struct ata_queued_cmd *qc) *(__le32 *)(buf + i) = cpu_to_le32(len); i += 4; - last_buf = &buf[i]; + if (ata_sg_is_last(sg, qc)) + pFLAGS |= pEND; buf[i++] = pFLAGS; buf[i++] = qc->dev->dma_mode & 0xf; buf[i++] = 0; /* pPKLW */ @@ -347,10 +348,6 @@ static int adma_fill_sg(struct ata_queued_cmd *qc) VPRINTK("PRD[%u] = (0x%lX, 0x%X)\n", i/4, (unsigned long)addr, len); } - - if (likely(last_buf)) - *last_buf |= pEND; - return i; } diff --git a/trunk/drivers/ata/sata_fsl.c b/trunk/drivers/ata/sata_fsl.c deleted file mode 100644 index b4c37b9e413c..000000000000 --- a/trunk/drivers/ata/sata_fsl.c +++ /dev/null @@ -1,1490 +0,0 @@ -/* - * drivers/ata/sata_fsl.c - * - * Freescale 3.0Gbps SATA device driver - * - * Author: Ashish Kalra - * Li Yang - * - * Copyright (c) 2006-2007 Freescale Semiconductor, Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ - -#include -#include -#include - -#include -#include -#include -#include -#include - -/* Controller information */ -enum { - SATA_FSL_QUEUE_DEPTH = 16, - SATA_FSL_MAX_PRD = 63, - SATA_FSL_MAX_PRD_USABLE = SATA_FSL_MAX_PRD - 1, - SATA_FSL_MAX_PRD_DIRECT = 16, /* Direct PRDT entries */ - - SATA_FSL_HOST_FLAGS = (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | - ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | - ATA_FLAG_NCQ | ATA_FLAG_SKIP_D2H_BSY), - - SATA_FSL_MAX_CMDS = SATA_FSL_QUEUE_DEPTH, - SATA_FSL_CMD_HDR_SIZE = 16, /* 4 DWORDS */ - SATA_FSL_CMD_SLOT_SIZE = (SATA_FSL_MAX_CMDS * SATA_FSL_CMD_HDR_SIZE), - - /* - * SATA-FSL host controller supports a max. of (15+1) direct PRDEs, and - * chained indirect PRDEs upto a max count of 63. - * We are allocating an array of 63 PRDEs contigiously, but PRDE#15 will - * be setup as an indirect descriptor, pointing to it's next - * (contigious) PRDE. Though chained indirect PRDE arrays are - * supported,it will be more efficient to use a direct PRDT and - * a single chain/link to indirect PRDE array/PRDT. - */ - - SATA_FSL_CMD_DESC_CFIS_SZ = 32, - SATA_FSL_CMD_DESC_SFIS_SZ = 32, - SATA_FSL_CMD_DESC_ACMD_SZ = 16, - SATA_FSL_CMD_DESC_RSRVD = 16, - - SATA_FSL_CMD_DESC_SIZE = (SATA_FSL_CMD_DESC_CFIS_SZ + - SATA_FSL_CMD_DESC_SFIS_SZ + - SATA_FSL_CMD_DESC_ACMD_SZ + - SATA_FSL_CMD_DESC_RSRVD + - SATA_FSL_MAX_PRD * 16), - - SATA_FSL_CMD_DESC_OFFSET_TO_PRDT = - (SATA_FSL_CMD_DESC_CFIS_SZ + - SATA_FSL_CMD_DESC_SFIS_SZ + - SATA_FSL_CMD_DESC_ACMD_SZ + - SATA_FSL_CMD_DESC_RSRVD), - - SATA_FSL_CMD_DESC_AR_SZ = (SATA_FSL_CMD_DESC_SIZE * SATA_FSL_MAX_CMDS), - SATA_FSL_PORT_PRIV_DMA_SZ = (SATA_FSL_CMD_SLOT_SIZE + - SATA_FSL_CMD_DESC_AR_SZ), - - /* - * MPC8315 has two SATA controllers, SATA1 & SATA2 - * (one port per controller) - * MPC837x has 2/4 controllers, one port per controller - */ - - SATA_FSL_MAX_PORTS = 1, - - SATA_FSL_IRQ_FLAG = IRQF_SHARED, -}; - -/* -* Host Controller command register set - per port -*/ -enum { - CQ = 0, - CA = 8, - CC = 0x10, - CE = 0x18, - DE = 0x20, - CHBA = 0x24, - HSTATUS = 0x28, - HCONTROL = 0x2C, - CQPMP = 0x30, - SIGNATURE = 0x34, - ICC = 0x38, - - /* - * Host Status Register (HStatus) bitdefs - */ - ONLINE = (1 << 31), - GOING_OFFLINE = (1 << 30), - BIST_ERR = (1 << 29), - - FATAL_ERR_HC_MASTER_ERR = (1 << 18), - FATAL_ERR_PARITY_ERR_TX = (1 << 17), - FATAL_ERR_PARITY_ERR_RX = (1 << 16), - FATAL_ERR_DATA_UNDERRUN = (1 << 13), - FATAL_ERR_DATA_OVERRUN = (1 << 12), - FATAL_ERR_CRC_ERR_TX = (1 << 11), - FATAL_ERR_CRC_ERR_RX = (1 << 10), - FATAL_ERR_FIFO_OVRFL_TX = (1 << 9), - FATAL_ERR_FIFO_OVRFL_RX = (1 << 8), - - FATAL_ERROR_DECODE = FATAL_ERR_HC_MASTER_ERR | - FATAL_ERR_PARITY_ERR_TX | - FATAL_ERR_PARITY_ERR_RX | - FATAL_ERR_DATA_UNDERRUN | - FATAL_ERR_DATA_OVERRUN | - FATAL_ERR_CRC_ERR_TX | - FATAL_ERR_CRC_ERR_RX | - FATAL_ERR_FIFO_OVRFL_TX | FATAL_ERR_FIFO_OVRFL_RX, - - INT_ON_FATAL_ERR = (1 << 5), - INT_ON_PHYRDY_CHG = (1 << 4), - - INT_ON_SIGNATURE_UPDATE = (1 << 3), - INT_ON_SNOTIFY_UPDATE = (1 << 2), - INT_ON_SINGL_DEVICE_ERR = (1 << 1), - INT_ON_CMD_COMPLETE = 1, - - INT_ON_ERROR = INT_ON_FATAL_ERR | - INT_ON_PHYRDY_CHG | INT_ON_SINGL_DEVICE_ERR, - - /* - * Host Control Register (HControl) bitdefs - */ - HCONTROL_ONLINE_PHY_RST = (1 << 31), - HCONTROL_FORCE_OFFLINE = (1 << 30), - HCONTROL_PARITY_PROT_MOD = (1 << 14), - HCONTROL_DPATH_PARITY = (1 << 12), - HCONTROL_SNOOP_ENABLE = (1 << 10), - HCONTROL_PMP_ATTACHED = (1 << 9), - HCONTROL_COPYOUT_STATFIS = (1 << 8), - IE_ON_FATAL_ERR = (1 << 5), - IE_ON_PHYRDY_CHG = (1 << 4), - IE_ON_SIGNATURE_UPDATE = (1 << 3), - IE_ON_SNOTIFY_UPDATE = (1 << 2), - IE_ON_SINGL_DEVICE_ERR = (1 << 1), - IE_ON_CMD_COMPLETE = 1, - - DEFAULT_PORT_IRQ_ENABLE_MASK = IE_ON_FATAL_ERR | IE_ON_PHYRDY_CHG | - IE_ON_SIGNATURE_UPDATE | - IE_ON_SINGL_DEVICE_ERR | IE_ON_CMD_COMPLETE, - - EXT_INDIRECT_SEG_PRD_FLAG = (1 << 31), - DATA_SNOOP_ENABLE = (1 << 22), -}; - -/* - * SATA Superset Registers - */ -enum { - SSTATUS = 0, - SERROR = 4, - SCONTROL = 8, - SNOTIFY = 0xC, -}; - -/* - * Control Status Register Set - */ -enum { - TRANSCFG = 0, - TRANSSTATUS = 4, - LINKCFG = 8, - LINKCFG1 = 0xC, - LINKCFG2 = 0x10, - LINKSTATUS = 0x14, - LINKSTATUS1 = 0x18, - PHYCTRLCFG = 0x1C, - COMMANDSTAT = 0x20, -}; - -/* PHY (link-layer) configuration control */ -enum { - PHY_BIST_ENABLE = 0x01, -}; - -/* - * Command Header Table entry, i.e, command slot - * 4 Dwords per command slot, command header size == 64 Dwords. - */ -struct cmdhdr_tbl_entry { - u32 cda; - u32 prde_fis_len; - u32 ttl; - u32 desc_info; -}; - -/* - * Description information bitdefs - */ -enum { - VENDOR_SPECIFIC_BIST = (1 << 10), - CMD_DESC_SNOOP_ENABLE = (1 << 9), - FPDMA_QUEUED_CMD = (1 << 8), - SRST_CMD = (1 << 7), - BIST = (1 << 6), - ATAPI_CMD = (1 << 5), -}; - -/* - * Command Descriptor - */ -struct command_desc { - u8 cfis[8 * 4]; - u8 sfis[8 * 4]; - u8 acmd[4 * 4]; - u8 fill[4 * 4]; - u32 prdt[SATA_FSL_MAX_PRD_DIRECT * 4]; - u32 prdt_indirect[(SATA_FSL_MAX_PRD - SATA_FSL_MAX_PRD_DIRECT) * 4]; -}; - -/* - * Physical region table descriptor(PRD) - */ - -struct prde { - u32 dba; - u8 fill[2 * 4]; - u32 ddc_and_ext; -}; - -/* - * ata_port private data - * This is our per-port instance data. - */ -struct sata_fsl_port_priv { - struct cmdhdr_tbl_entry *cmdslot; - dma_addr_t cmdslot_paddr; - struct command_desc *cmdentry; - dma_addr_t cmdentry_paddr; - - /* - * SATA FSL controller has a Status FIS which should contain the - * received D2H FIS & taskfile registers. This SFIS is present in - * the command descriptor, and to have a ready reference to it, - * we are caching it here, quite similar to what is done in H/W on - * AHCI compliant devices by copying taskfile fields to a 32-bit - * register. - */ - - struct ata_taskfile tf; -}; - -/* - * ata_port->host_set private data - */ -struct sata_fsl_host_priv { - void __iomem *hcr_base; - void __iomem *ssr_base; - void __iomem *csr_base; -}; - -static inline unsigned int sata_fsl_tag(unsigned int tag, - void __iomem * hcr_base) -{ - /* We let libATA core do actual (queue) tag allocation */ - - /* all non NCQ/queued commands should have tag#0 */ - if (ata_tag_internal(tag)) { - DPRINTK("mapping internal cmds to tag#0\n"); - return 0; - } - - if (unlikely(tag >= SATA_FSL_QUEUE_DEPTH)) { - DPRINTK("tag %d invalid : out of range\n", tag); - return 0; - } - - if (unlikely((ioread32(hcr_base + CQ)) & (1 << tag))) { - DPRINTK("tag %d invalid : in use!!\n", tag); - return 0; - } - - return tag; -} - -static void sata_fsl_setup_cmd_hdr_entry(struct sata_fsl_port_priv *pp, - unsigned int tag, u32 desc_info, - u32 data_xfer_len, u8 num_prde, - u8 fis_len) -{ - dma_addr_t cmd_descriptor_address; - - cmd_descriptor_address = pp->cmdentry_paddr + - tag * SATA_FSL_CMD_DESC_SIZE; - - /* NOTE: both data_xfer_len & fis_len are Dword counts */ - - pp->cmdslot[tag].cda = cpu_to_le32(cmd_descriptor_address); - pp->cmdslot[tag].prde_fis_len = - cpu_to_le32((num_prde << 16) | (fis_len << 2)); - pp->cmdslot[tag].ttl = cpu_to_le32(data_xfer_len & ~0x03); - pp->cmdslot[tag].desc_info = cpu_to_le32((desc_info | (tag & 0x1F))); - - VPRINTK("cda=0x%x, prde_fis_len=0x%x, ttl=0x%x, di=0x%x\n", - pp->cmdslot[tag].cda, - pp->cmdslot[tag].prde_fis_len, - pp->cmdslot[tag].ttl, pp->cmdslot[tag].desc_info); - -} - -static unsigned int sata_fsl_fill_sg(struct ata_queued_cmd *qc, void *cmd_desc, - u32 * ttl, dma_addr_t cmd_desc_paddr) -{ - struct scatterlist *sg; - unsigned int num_prde = 0; - u32 ttl_dwords = 0; - - /* - * NOTE : direct & indirect prdt's are contigiously allocated - */ - struct prde *prd = (struct prde *)&((struct command_desc *) - cmd_desc)->prdt; - - struct prde *prd_ptr_to_indirect_ext = NULL; - unsigned indirect_ext_segment_sz = 0; - dma_addr_t indirect_ext_segment_paddr; - - VPRINTK("SATA FSL : cd = 0x%x, prd = 0x%x\n", cmd_desc, prd); - - indirect_ext_segment_paddr = cmd_desc_paddr + - SATA_FSL_CMD_DESC_OFFSET_TO_PRDT + SATA_FSL_MAX_PRD_DIRECT * 16; - - ata_for_each_sg(sg, qc) { - dma_addr_t sg_addr = sg_dma_address(sg); - u32 sg_len = sg_dma_len(sg); - - VPRINTK("SATA FSL : fill_sg, sg_addr = 0x%x, sg_len = %d\n", - sg_addr, sg_len); - - /* warn if each s/g element is not dword aligned */ - if (sg_addr & 0x03) - ata_port_printk(qc->ap, KERN_ERR, - "s/g addr unaligned : 0x%x\n", sg_addr); - if (sg_len & 0x03) - ata_port_printk(qc->ap, KERN_ERR, - "s/g len unaligned : 0x%x\n", sg_len); - - if ((num_prde == (SATA_FSL_MAX_PRD_DIRECT - 1)) && - !ata_sg_is_last(sg, qc)) { - VPRINTK("setting indirect prde\n"); - prd_ptr_to_indirect_ext = prd; - prd->dba = cpu_to_le32(indirect_ext_segment_paddr); - indirect_ext_segment_sz = 0; - ++prd; - ++num_prde; - } - - ttl_dwords += sg_len; - prd->dba = cpu_to_le32(sg_addr); - prd->ddc_and_ext = - cpu_to_le32(DATA_SNOOP_ENABLE | (sg_len & ~0x03)); - - VPRINTK("sg_fill, ttl=%d, dba=0x%x, ddc=0x%x\n", - ttl_dwords, prd->dba, prd->ddc_and_ext); - - ++num_prde; - ++prd; - if (prd_ptr_to_indirect_ext) - indirect_ext_segment_sz += sg_len; - } - - if (prd_ptr_to_indirect_ext) { - /* set indirect extension flag along with indirect ext. size */ - prd_ptr_to_indirect_ext->ddc_and_ext = - cpu_to_le32((EXT_INDIRECT_SEG_PRD_FLAG | - DATA_SNOOP_ENABLE | - (indirect_ext_segment_sz & ~0x03))); - } - - *ttl = ttl_dwords; - return num_prde; -} - -static void sata_fsl_qc_prep(struct ata_queued_cmd *qc) -{ - struct ata_port *ap = qc->ap; - struct sata_fsl_port_priv *pp = ap->private_data; - struct sata_fsl_host_priv *host_priv = ap->host->private_data; - void __iomem *hcr_base = host_priv->hcr_base; - unsigned int tag = sata_fsl_tag(qc->tag, hcr_base); - struct command_desc *cd; - u32 desc_info = CMD_DESC_SNOOP_ENABLE; - u32 num_prde = 0; - u32 ttl_dwords = 0; - dma_addr_t cd_paddr; - - cd = (struct command_desc *)pp->cmdentry + tag; - cd_paddr = pp->cmdentry_paddr + tag * SATA_FSL_CMD_DESC_SIZE; - - ata_tf_to_fis(&qc->tf, 0, 1, (u8 *) & cd->cfis); - - VPRINTK("Dumping cfis : 0x%x, 0x%x, 0x%x\n", - cd->cfis[0], cd->cfis[1], cd->cfis[2]); - - if (qc->tf.protocol == ATA_PROT_NCQ) { - VPRINTK("FPDMA xfer,Sctor cnt[0:7],[8:15] = %d,%d\n", - cd->cfis[3], cd->cfis[11]); - } - - /* setup "ACMD - atapi command" in cmd. desc. if this is ATAPI cmd */ - if (is_atapi_taskfile(&qc->tf)) { - desc_info |= ATAPI_CMD; - memset((void *)&cd->acmd, 0, 32); - memcpy((void *)&cd->acmd, qc->cdb, qc->dev->cdb_len); - } - - if (qc->flags & ATA_QCFLAG_DMAMAP) - num_prde = sata_fsl_fill_sg(qc, (void *)cd, - &ttl_dwords, cd_paddr); - - if (qc->tf.protocol == ATA_PROT_NCQ) - desc_info |= FPDMA_QUEUED_CMD; - - sata_fsl_setup_cmd_hdr_entry(pp, tag, desc_info, ttl_dwords, - num_prde, 5); - - VPRINTK("SATA FSL : xx_qc_prep, di = 0x%x, ttl = %d, num_prde = %d\n", - desc_info, ttl_dwords, num_prde); -} - -static unsigned int sata_fsl_qc_issue(struct ata_queued_cmd *qc) -{ - struct ata_port *ap = qc->ap; - struct sata_fsl_host_priv *host_priv = ap->host->private_data; - void __iomem *hcr_base = host_priv->hcr_base; - unsigned int tag = sata_fsl_tag(qc->tag, hcr_base); - - VPRINTK("xx_qc_issue called,CQ=0x%x,CA=0x%x,CE=0x%x,CC=0x%x\n", - ioread32(CQ + hcr_base), - ioread32(CA + hcr_base), - ioread32(CE + hcr_base), ioread32(CC + hcr_base)); - - /* Simply queue command to the controller/device */ - iowrite32(1 << tag, CQ + hcr_base); - - VPRINTK("xx_qc_issue called, tag=%d, CQ=0x%x, CA=0x%x\n", - tag, ioread32(CQ + hcr_base), ioread32(CA + hcr_base)); - - VPRINTK("CE=0x%x, DE=0x%x, CC=0x%x, CmdStat = 0x%x\n", - ioread32(CE + hcr_base), - ioread32(DE + hcr_base), - ioread32(CC + hcr_base), ioread32(COMMANDSTAT + csr_base)); - - return 0; -} - -static int sata_fsl_scr_write(struct ata_port *ap, unsigned int sc_reg_in, - u32 val) -{ - struct sata_fsl_host_priv *host_priv = ap->host->private_data; - void __iomem *ssr_base = host_priv->ssr_base; - unsigned int sc_reg; - - switch (sc_reg_in) { - case SCR_STATUS: - sc_reg = 0; - break; - case SCR_ERROR: - sc_reg = 1; - break; - case SCR_CONTROL: - sc_reg = 2; - break; - case SCR_ACTIVE: - sc_reg = 3; - break; - default: - return -EINVAL; - } - - VPRINTK("xx_scr_write, reg_in = %d\n", sc_reg); - - iowrite32(val, (void __iomem *)ssr_base + (sc_reg * 4)); - return 0; -} - -static int sata_fsl_scr_read(struct ata_port *ap, unsigned int sc_reg_in, - u32 *val) -{ - struct sata_fsl_host_priv *host_priv = ap->host->private_data; - void __iomem *ssr_base = host_priv->ssr_base; - unsigned int sc_reg; - - switch (sc_reg_in) { - case SCR_STATUS: - sc_reg = 0; - break; - case SCR_ERROR: - sc_reg = 1; - break; - case SCR_CONTROL: - sc_reg = 2; - break; - case SCR_ACTIVE: - sc_reg = 3; - break; - default: - return -EINVAL; - } - - VPRINTK("xx_scr_read, reg_in = %d\n", sc_reg); - - *val = ioread32((void __iomem *)ssr_base + (sc_reg * 4)); - return 0; -} - -static void sata_fsl_freeze(struct ata_port *ap) -{ - struct sata_fsl_host_priv *host_priv = ap->host->private_data; - void __iomem *hcr_base = host_priv->hcr_base; - u32 temp; - - VPRINTK("xx_freeze, CQ=0x%x, CA=0x%x, CE=0x%x, DE=0x%x\n", - ioread32(CQ + hcr_base), - ioread32(CA + hcr_base), - ioread32(CE + hcr_base), ioread32(DE + hcr_base)); - VPRINTK("CmdStat = 0x%x\n", ioread32(csr_base + COMMANDSTAT)); - - /* disable interrupts on the controller/port */ - temp = ioread32(hcr_base + HCONTROL); - iowrite32((temp & ~0x3F), hcr_base + HCONTROL); - - VPRINTK("in xx_freeze : HControl = 0x%x, HStatus = 0x%x\n", - ioread32(hcr_base + HCONTROL), ioread32(hcr_base + HSTATUS)); -} - -static void sata_fsl_thaw(struct ata_port *ap) -{ - struct sata_fsl_host_priv *host_priv = ap->host->private_data; - void __iomem *hcr_base = host_priv->hcr_base; - u32 temp; - - /* ack. any pending IRQs for this controller/port */ - temp = ioread32(hcr_base + HSTATUS); - - VPRINTK("xx_thaw, pending IRQs = 0x%x\n", (temp & 0x3F)); - - if (temp & 0x3F) - iowrite32((temp & 0x3F), hcr_base + HSTATUS); - - /* enable interrupts on the controller/port */ - temp = ioread32(hcr_base + HCONTROL); - iowrite32((temp | DEFAULT_PORT_IRQ_ENABLE_MASK), hcr_base + HCONTROL); - - VPRINTK("xx_thaw : HControl = 0x%x, HStatus = 0x%x\n", - ioread32(hcr_base + HCONTROL), ioread32(hcr_base + HSTATUS)); -} - -/* - * NOTE : 1st D2H FIS from device does not update sfis in command descriptor. - */ -static inline void sata_fsl_cache_taskfile_from_d2h_fis(struct ata_queued_cmd - *qc, - struct ata_port *ap) -{ - struct sata_fsl_port_priv *pp = ap->private_data; - u8 fis[6 * 4]; - struct sata_fsl_host_priv *host_priv = ap->host->private_data; - void __iomem *hcr_base = host_priv->hcr_base; - unsigned int tag = sata_fsl_tag(qc->tag, hcr_base); - struct command_desc *cd; - - cd = pp->cmdentry + tag; - - memcpy(fis, &cd->sfis, 6 * 4); /* should we use memcpy_from_io() */ - ata_tf_from_fis(fis, &pp->tf); -} - -static u8 sata_fsl_check_status(struct ata_port *ap) -{ - struct sata_fsl_port_priv *pp = ap->private_data; - - return pp->tf.command; -} - -static void sata_fsl_tf_read(struct ata_port *ap, struct ata_taskfile *tf) -{ - struct sata_fsl_port_priv *pp = ap->private_data; - - *tf = pp->tf; -} - -static int sata_fsl_port_start(struct ata_port *ap) -{ - struct device *dev = ap->host->dev; - struct sata_fsl_port_priv *pp; - int retval; - void *mem; - dma_addr_t mem_dma; - struct sata_fsl_host_priv *host_priv = ap->host->private_data; - void __iomem *hcr_base = host_priv->hcr_base; - u32 temp; - - pp = kzalloc(sizeof(*pp), GFP_KERNEL); - if (!pp) - return -ENOMEM; - - /* - * allocate per command dma alignment pad buffer, which is used - * internally by libATA to ensure that all transfers ending on - * unaligned boundaries are padded, to align on Dword boundaries - */ - retval = ata_pad_alloc(ap, dev); - if (retval) { - kfree(pp); - return retval; - } - - mem = dma_alloc_coherent(dev, SATA_FSL_PORT_PRIV_DMA_SZ, &mem_dma, - GFP_KERNEL); - if (!mem) { - ata_pad_free(ap, dev); - kfree(pp); - return -ENOMEM; - } - memset(mem, 0, SATA_FSL_PORT_PRIV_DMA_SZ); - - pp->cmdslot = mem; - pp->cmdslot_paddr = mem_dma; - - mem += SATA_FSL_CMD_SLOT_SIZE; - mem_dma += SATA_FSL_CMD_SLOT_SIZE; - - pp->cmdentry = mem; - pp->cmdentry_paddr = mem_dma; - - ap->private_data = pp; - - VPRINTK("CHBA = 0x%x, cmdentry_phys = 0x%x\n", - pp->cmdslot_paddr, pp->cmdentry_paddr); - - /* Now, update the CHBA register in host controller cmd register set */ - iowrite32(pp->cmdslot_paddr & 0xffffffff, hcr_base + CHBA); - - /* - * Now, we can bring the controller on-line & also initiate - * the COMINIT sequence, we simply return here and the boot-probing - * & device discovery process is re-initiated by libATA using a - * Softreset EH (dummy) session. Hence, boot probing and device - * discovey will be part of sata_fsl_softreset() callback. - */ - - temp = ioread32(hcr_base + HCONTROL); - iowrite32((temp | HCONTROL_ONLINE_PHY_RST), hcr_base + HCONTROL); - - VPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS)); - VPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL)); - VPRINTK("CHBA = 0x%x\n", ioread32(hcr_base + CHBA)); - - /* - * Workaround for 8315DS board 3gbps link-up issue, - * currently limit SATA port to GEN1 speed - */ - sata_fsl_scr_read(ap, SCR_CONTROL, &temp); - temp &= ~(0xF << 4); - temp |= (0x1 << 4); - sata_fsl_scr_write(ap, SCR_CONTROL, temp); - - sata_fsl_scr_read(ap, SCR_CONTROL, &temp); - dev_printk(KERN_WARNING, dev, "scr_control, speed limited to %x\n", - temp); - - return 0; -} - -static void sata_fsl_port_stop(struct ata_port *ap) -{ - struct device *dev = ap->host->dev; - struct sata_fsl_port_priv *pp = ap->private_data; - struct sata_fsl_host_priv *host_priv = ap->host->private_data; - void __iomem *hcr_base = host_priv->hcr_base; - u32 temp; - - /* - * Force host controller to go off-line, aborting current operations - */ - temp = ioread32(hcr_base + HCONTROL); - temp &= ~HCONTROL_ONLINE_PHY_RST; - temp |= HCONTROL_FORCE_OFFLINE; - iowrite32(temp, hcr_base + HCONTROL); - - /* Poll for controller to go offline - should happen immediately */ - ata_wait_register(hcr_base + HSTATUS, ONLINE, ONLINE, 1, 1); - - ap->private_data = NULL; - dma_free_coherent(dev, SATA_FSL_PORT_PRIV_DMA_SZ, - pp->cmdslot, pp->cmdslot_paddr); - - ata_pad_free(ap, dev); - kfree(pp); -} - -static unsigned int sata_fsl_dev_classify(struct ata_port *ap) -{ - struct sata_fsl_host_priv *host_priv = ap->host->private_data; - void __iomem *hcr_base = host_priv->hcr_base; - struct ata_taskfile tf; - u32 temp; - - temp = ioread32(hcr_base + SIGNATURE); - - VPRINTK("raw sig = 0x%x\n", temp); - VPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS)); - VPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL)); - - tf.lbah = (temp >> 24) & 0xff; - tf.lbam = (temp >> 16) & 0xff; - tf.lbal = (temp >> 8) & 0xff; - tf.nsect = temp & 0xff; - - return ata_dev_classify(&tf); -} - -static int sata_fsl_softreset(struct ata_port *ap, unsigned int *class, - unsigned long deadline) -{ - struct sata_fsl_port_priv *pp = ap->private_data; - struct sata_fsl_host_priv *host_priv = ap->host->private_data; - void __iomem *hcr_base = host_priv->hcr_base; - u32 temp; - struct ata_taskfile tf; - u8 *cfis; - u32 Serror; - int i = 0; - struct ata_queued_cmd qc; - u8 *buf; - dma_addr_t dma_address; - struct scatterlist *sg; - unsigned long start_jiffies; - - DPRINTK("in xx_softreset\n"); - -try_offline_again: - /* - * Force host controller to go off-line, aborting current operations - */ - temp = ioread32(hcr_base + HCONTROL); - temp &= ~HCONTROL_ONLINE_PHY_RST; - iowrite32(temp, hcr_base + HCONTROL); - - /* Poll for controller to go offline */ - temp = ata_wait_register(hcr_base + HSTATUS, ONLINE, ONLINE, 1, 500); - - if (temp & ONLINE) { - ata_port_printk(ap, KERN_ERR, - "Softreset failed, not off-lined %d\n", i); - - /* - * Try to offline controller atleast twice - */ - i++; - if (i == 2) - goto err; - else - goto try_offline_again; - } - - DPRINTK("softreset, controller off-lined\n"); - VPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS)); - VPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL)); - - /* - * PHY reset should remain asserted for atleast 1ms - */ - msleep(1); - - /* - * Now, bring the host controller online again, this can take time - * as PHY reset and communication establishment, 1st D2H FIS and - * device signature update is done, on safe side assume 500ms - * NOTE : Host online status may be indicated immediately!! - */ - - temp = ioread32(hcr_base + HCONTROL); - temp |= (HCONTROL_ONLINE_PHY_RST | HCONTROL_SNOOP_ENABLE); - iowrite32(temp, hcr_base + HCONTROL); - - temp = ata_wait_register(hcr_base + HSTATUS, ONLINE, 0, 1, 500); - - if (!(temp & ONLINE)) { - ata_port_printk(ap, KERN_ERR, - "Softreset failed, not on-lined\n"); - goto err; - } - - DPRINTK("softreset, controller off-lined & on-lined\n"); - VPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS)); - VPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL)); - - /* - * First, wait for the PHYRDY change to occur before waiting for - * the signature, and also verify if SStatus indicates device - * presence - */ - - temp = ata_wait_register(hcr_base + HSTATUS, 0xFF, 0, 1, 500); - if ((!(temp & 0x10)) || ata_port_offline(ap)) { - ata_port_printk(ap, KERN_WARNING, - "No Device OR PHYRDY change,Hstatus = 0x%x\n", - ioread32(hcr_base + HSTATUS)); - goto err; - } - - /* - * Wait for the first D2H from device,i.e,signature update notification - */ - start_jiffies = jiffies; - temp = ata_wait_register(hcr_base + HSTATUS, 0xFF, 0x10, - 500, jiffies_to_msecs(deadline - start_jiffies)); - - if ((temp & 0xFF) != 0x18) { - ata_port_printk(ap, KERN_WARNING, "No Signature Update\n"); - goto err; - } else { - ata_port_printk(ap, KERN_INFO, - "Signature Update detected @ %d msecs\n", - jiffies_to_msecs(jiffies - start_jiffies)); - } - - /* - * Send a device reset (SRST) explicitly on command slot #0 - * Check : will the command queue (reg) be cleared during offlining ?? - * Also we will be online only if Phy commn. has been established - * and device presence has been detected, therefore if we have - * reached here, we can send a command to the target device - */ - - if (ap->sactive) - goto skip_srst_do_ncq_error_handling; - - DPRINTK("Sending SRST/device reset\n"); - - ata_tf_init(ap->device, &tf); - cfis = (u8 *) & pp->cmdentry->cfis; - - /* device reset/SRST is a control register update FIS, uses tag0 */ - sata_fsl_setup_cmd_hdr_entry(pp, 0, - SRST_CMD | CMD_DESC_SNOOP_ENABLE, 0, 0, 5); - - tf.ctl |= ATA_SRST; /* setup SRST bit in taskfile control reg */ - ata_tf_to_fis(&tf, 0, 0, cfis); - - DPRINTK("Dumping cfis : 0x%x, 0x%x, 0x%x, 0x%x\n", - cfis[0], cfis[1], cfis[2], cfis[3]); - - /* - * Queue SRST command to the controller/device, ensure that no - * other commands are active on the controller/device - */ - - DPRINTK("@Softreset, CQ = 0x%x, CA = 0x%x, CC = 0x%x\n", - ioread32(CQ + hcr_base), - ioread32(CA + hcr_base), ioread32(CC + hcr_base)); - - iowrite32(0xFFFF, CC + hcr_base); - iowrite32(1, CQ + hcr_base); - - temp = ata_wait_register(CQ + hcr_base, 0x1, 0x1, 1, 5000); - if (temp & 0x1) { - ata_port_printk(ap, KERN_WARNING, "ATA_SRST issue failed\n"); - - DPRINTK("Softreset@5000,CQ=0x%x,CA=0x%x,CC=0x%x\n", - ioread32(CQ + hcr_base), - ioread32(CA + hcr_base), ioread32(CC + hcr_base)); - - sata_fsl_scr_read(ap, SCR_ERROR, &Serror); - - DPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS)); - DPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL)); - DPRINTK("Serror = 0x%x\n", Serror); - goto err; - } - - msleep(1); - - /* - * SATA device enters reset state after receving a Control register - * FIS with SRST bit asserted and it awaits another H2D Control reg. - * FIS with SRST bit cleared, then the device does internal diags & - * initialization, followed by indicating it's initialization status - * using ATA signature D2H register FIS to the host controller. - */ - - sata_fsl_setup_cmd_hdr_entry(pp, 0, CMD_DESC_SNOOP_ENABLE, 0, 0, 5); - - tf.ctl &= ~ATA_SRST; /* 2nd H2D Ctl. register FIS */ - ata_tf_to_fis(&tf, 0, 0, cfis); - - iowrite32(1, CQ + hcr_base); - msleep(150); /* ?? */ - - /* - * The above command would have signalled an interrupt on command - * complete, which needs special handling, by clearing the Nth - * command bit of the CCreg - */ - iowrite32(0x01, CC + hcr_base); /* We know it will be cmd#0 always */ - goto check_device_signature; - -skip_srst_do_ncq_error_handling: - - VPRINTK("Sending read log ext(10h) command\n"); - - memset(&qc, 0, sizeof(struct ata_queued_cmd)); - ata_tf_init(ap->device, &tf); - - tf.command = ATA_CMD_READ_LOG_EXT; - tf.lbal = ATA_LOG_SATA_NCQ; - tf.nsect = 1; - tf.hob_nsect = 0; - tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_LBA48 | ATA_TFLAG_DEVICE; - tf.protocol = ATA_PROT_PIO; - - qc.tag = ATA_TAG_INTERNAL; - qc.scsicmd = NULL; - qc.ap = ap; - qc.dev = ap->device; - - qc.tf = tf; - qc.flags |= ATA_QCFLAG_RESULT_TF; - qc.dma_dir = DMA_FROM_DEVICE; - - buf = ap->sector_buf; - ata_sg_init_one(&qc, buf, 1 * ATA_SECT_SIZE); - - /* - * Need to DMA-map the memory buffer associated with the command - */ - - sg = qc.__sg; - dma_address = dma_map_single(ap->dev, qc.buf_virt, - sg->length, DMA_FROM_DEVICE); - - sg_dma_address(sg) = dma_address; - sg_dma_len(sg) = sg->length; - - VPRINTK("EH, addr = 0x%x, len = 0x%x\n", dma_address, sg->length); - - sata_fsl_qc_prep(&qc); - sata_fsl_qc_issue(&qc); - - temp = ata_wait_register(CQ + hcr_base, 0x1, 0x1, 1, 5000); - if (temp & 0x1) { - VPRINTK("READ_LOG_EXT_10H issue failed\n"); - - VPRINTK("READ_LOG@5000,CQ=0x%x,CA=0x%x,CC=0x%x\n", - ioread32(CQ + hcr_base), - ioread32(CA + hcr_base), ioread32(CC + hcr_base)); - - sata_fsl_scr_read(ap, SCR_ERROR, &Serror); - - VPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS)); - VPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL)); - VPRINTK("Serror = 0x%x\n", Serror); - goto err; - } - - iowrite32(0x01, CC + hcr_base); /* We know it will be cmd#0 always */ - - check_device_signature: - - DPRINTK("SATA FSL : Now checking device signature\n"); - - *class = ATA_DEV_NONE; - - /* Verify if SStatus indicates device presence */ - if (ata_port_online(ap)) { - /* - * if we are here, device presence has been detected, - * 1st D2H FIS would have been received, but sfis in - * command desc. is not updated, but signature register - * would have been updated - */ - - *class = sata_fsl_dev_classify(ap); - - DPRINTK("class = %d\n", *class); - VPRINTK("ccreg = 0x%x\n", ioread32(hcr_base + CC)); - VPRINTK("cereg = 0x%x\n", ioread32(hcr_base + CE)); - } - - return 0; - -err: - return -EIO; -} - -static int sata_fsl_hardreset(struct ata_port *ap, unsigned int *class, - unsigned long deadline) -{ - int retval; - - retval = sata_std_hardreset(ap, class, deadline); - - DPRINTK("SATA FSL : in xx_hardreset, retval = 0x%d\n", retval); - - return retval; -} - -static void sata_fsl_error_handler(struct ata_port *ap) -{ - - DPRINTK("in xx_error_handler\n"); - - /* perform recovery */ - ata_do_eh(ap, ata_std_prereset, sata_fsl_softreset, sata_fsl_hardreset, - ata_std_postreset); -} - -static void sata_fsl_post_internal_cmd(struct ata_queued_cmd *qc) -{ - if (qc->flags & ATA_QCFLAG_FAILED) - qc->err_mask |= AC_ERR_OTHER; - - if (qc->err_mask) { - /* make DMA engine forget about the failed command */ - - } -} - -static void sata_fsl_irq_clear(struct ata_port *ap) -{ - /* unused */ -} - -static void sata_fsl_error_intr(struct ata_port *ap) -{ - struct ata_eh_info *ehi = &ap->eh_info; - struct sata_fsl_host_priv *host_priv = ap->host->private_data; - void __iomem *hcr_base = host_priv->hcr_base; - u32 hstatus, dereg, cereg = 0, SError = 0; - unsigned int err_mask = 0, action = 0; - struct ata_queued_cmd *qc; - int freeze = 0; - - hstatus = ioread32(hcr_base + HSTATUS); - cereg = ioread32(hcr_base + CE); - - ata_ehi_clear_desc(ehi); - - /* - * Handle & Clear SError - */ - - sata_fsl_scr_read(ap, SCR_ERROR, &SError); - if (unlikely(SError & 0xFFFF0000)) { - sata_fsl_scr_write(ap, SCR_ERROR, SError); - err_mask |= AC_ERR_ATA_BUS; - } - - DPRINTK("error_intr,hStat=0x%x,CE=0x%x,DE =0x%x,SErr=0x%x\n", - hstatus, cereg, ioread32(hcr_base + DE), SError); - - /* handle single device errors */ - if (cereg) { - /* - * clear the command error, also clears queue to the device - * in error, and we can (re)issue commands to this device. - * When a device is in error all commands queued into the - * host controller and at the device are considered aborted - * and the queue for that device is stopped. Now, after - * clearing the device error, we can issue commands to the - * device to interrogate it to find the source of the error. - */ - dereg = ioread32(hcr_base + DE); - iowrite32(dereg, hcr_base + DE); - iowrite32(cereg, hcr_base + CE); - - DPRINTK("single device error, CE=0x%x, DE=0x%x\n", - ioread32(hcr_base + CE), ioread32(hcr_base + DE)); - /* - * We should consider this as non fatal error, and TF must - * be updated as done below. - */ - - err_mask |= AC_ERR_DEV; - } - - /* handle fatal errors */ - if (hstatus & FATAL_ERROR_DECODE) { - err_mask |= AC_ERR_ATA_BUS; - action |= ATA_EH_SOFTRESET; - /* how will fatal error interrupts be completed ?? */ - freeze = 1; - } - - /* Handle PHYRDY change notification */ - if (hstatus & INT_ON_PHYRDY_CHG) { - DPRINTK("SATA FSL: PHYRDY change indication\n"); - - /* Setup a soft-reset EH action */ - ata_ehi_hotplugged(ehi); - freeze = 1; - } - - /* record error info */ - qc = ata_qc_from_tag(ap, ap->active_tag); - - if (qc) { - sata_fsl_cache_taskfile_from_d2h_fis(qc, qc->ap); - qc->err_mask |= err_mask; - } else - ehi->err_mask |= err_mask; - - ehi->action |= action; - ehi->serror |= SError; - - /* freeze or abort */ - if (freeze) - ata_port_freeze(ap); - else - ata_port_abort(ap); -} - -static void sata_fsl_qc_complete(struct ata_queued_cmd *qc) -{ - if (qc->flags & ATA_QCFLAG_RESULT_TF) { - DPRINTK("xx_qc_complete called\n"); - sata_fsl_cache_taskfile_from_d2h_fis(qc, qc->ap); - } -} - -static void sata_fsl_host_intr(struct ata_port *ap) -{ - struct sata_fsl_host_priv *host_priv = ap->host->private_data; - void __iomem *hcr_base = host_priv->hcr_base; - u32 hstatus, qc_active = 0; - struct ata_queued_cmd *qc; - u32 SError; - - hstatus = ioread32(hcr_base + HSTATUS); - - sata_fsl_scr_read(ap, SCR_ERROR, &SError); - - if (unlikely(SError & 0xFFFF0000)) { - DPRINTK("serror @host_intr : 0x%x\n", SError); - sata_fsl_error_intr(ap); - - } - - if (unlikely(hstatus & INT_ON_ERROR)) { - DPRINTK("error interrupt!!\n"); - sata_fsl_error_intr(ap); - return; - } - - if (ap->sactive) { /* only true for NCQ commands */ - int i; - /* Read command completed register */ - qc_active = ioread32(hcr_base + CC); - /* clear CC bit, this will also complete the interrupt */ - iowrite32(qc_active, hcr_base + CC); - - DPRINTK("Status of all queues :\n"); - DPRINTK("qc_active/CC = 0x%x, CA = 0x%x, CE=0x%x\n", - qc_active, ioread32(hcr_base + CA), - ioread32(hcr_base + CE)); - - for (i = 0; i < SATA_FSL_QUEUE_DEPTH; i++) { - if (qc_active & (1 << i)) { - qc = ata_qc_from_tag(ap, i); - if (qc) { - sata_fsl_qc_complete(qc); - ata_qc_complete(qc); - } - DPRINTK - ("completing ncq cmd,tag=%d,CC=0x%x,CA=0x%x\n", - i, ioread32(hcr_base + CC), - ioread32(hcr_base + CA)); - } - } - return; - - } else if (ap->qc_active) { - iowrite32(1, hcr_base + CC); - qc = ata_qc_from_tag(ap, ap->active_tag); - - DPRINTK("completing non-ncq cmd, tag=%d,CC=0x%x\n", - ap->active_tag, ioread32(hcr_base + CC)); - - if (qc) { - sata_fsl_qc_complete(qc); - ata_qc_complete(qc); - } - } else { - /* Spurious Interrupt!! */ - DPRINTK("spurious interrupt!!, CC = 0x%x\n", - ioread32(hcr_base + CC)); - return; - } -} - -static irqreturn_t sata_fsl_interrupt(int irq, void *dev_instance) -{ - struct ata_host *host = dev_instance; - struct sata_fsl_host_priv *host_priv = host->private_data; - void __iomem *hcr_base = host_priv->hcr_base; - u32 interrupt_enables; - unsigned handled = 0; - struct ata_port *ap; - - /* ack. any pending IRQs for this controller/port */ - interrupt_enables = ioread32(hcr_base + HSTATUS); - interrupt_enables &= 0x3F; - - DPRINTK("interrupt status 0x%x\n", interrupt_enables); - - if (!interrupt_enables) - return IRQ_NONE; - - spin_lock(&host->lock); - - /* Assuming one port per host controller */ - - ap = host->ports[0]; - if (ap) { - sata_fsl_host_intr(ap); - } else { - dev_printk(KERN_WARNING, host->dev, - "interrupt on disabled port 0\n"); - } - - iowrite32(interrupt_enables, hcr_base + HSTATUS); - handled = 1; - - spin_unlock(&host->lock); - - return IRQ_RETVAL(handled); -} - -/* - * Multiple ports are represented by multiple SATA controllers with - * one port per controller - */ -static int sata_fsl_init_controller(struct ata_host *host) -{ - struct sata_fsl_host_priv *host_priv = host->private_data; - void __iomem *hcr_base = host_priv->hcr_base; - u32 temp; - - /* - * NOTE : We cannot bring the controller online before setting - * the CHBA, hence main controller initialization is done as - * part of the port_start() callback - */ - - /* ack. any pending IRQs for this controller/port */ - temp = ioread32(hcr_base + HSTATUS); - if (temp & 0x3F) - iowrite32((temp & 0x3F), hcr_base + HSTATUS); - - /* Keep interrupts disabled on the controller */ - temp = ioread32(hcr_base + HCONTROL); - iowrite32((temp & ~0x3F), hcr_base + HCONTROL); - - /* Disable interrupt coalescing control(icc), for the moment */ - DPRINTK("icc = 0x%x\n", ioread32(hcr_base + ICC)); - iowrite32(0x01000000, hcr_base + ICC); - - /* clear error registers, SError is cleared by libATA */ - iowrite32(0x00000FFFF, hcr_base + CE); - iowrite32(0x00000FFFF, hcr_base + DE); - - /* initially assuming no Port multiplier, set CQPMP to 0 */ - iowrite32(0x0, hcr_base + CQPMP); - - /* - * host controller will be brought on-line, during xx_port_start() - * callback, that should also initiate the OOB, COMINIT sequence - */ - - DPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS)); - DPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL)); - - return 0; -} - -/* - * scsi mid-layer and libata interface structures - */ -static struct scsi_host_template sata_fsl_sht = { - .module = THIS_MODULE, - .name = "sata_fsl", - .ioctl = ata_scsi_ioctl, - .queuecommand = ata_scsi_queuecmd, - .change_queue_depth = ata_scsi_change_queue_depth, - .can_queue = SATA_FSL_QUEUE_DEPTH, - .this_id = ATA_SHT_THIS_ID, - .sg_tablesize = SATA_FSL_MAX_PRD_USABLE, - .cmd_per_lun = ATA_SHT_CMD_PER_LUN, - .emulated = ATA_SHT_EMULATED, - .use_clustering = ATA_SHT_USE_CLUSTERING, - .proc_name = "sata_fsl", - .dma_boundary = ATA_DMA_BOUNDARY, - .slave_configure = ata_scsi_slave_config, - .slave_destroy = ata_scsi_slave_destroy, - .bios_param = ata_std_bios_param, -#ifdef CONFIG_PM - .suspend = ata_scsi_device_suspend, - .resume = ata_scsi_device_resume, -#endif -}; - -static const struct ata_port_operations sata_fsl_ops = { - .port_disable = ata_port_disable, - - .check_status = sata_fsl_check_status, - .check_altstatus = sata_fsl_check_status, - .dev_select = ata_noop_dev_select, - - .tf_read = sata_fsl_tf_read, - - .qc_prep = sata_fsl_qc_prep, - .qc_issue = sata_fsl_qc_issue, - .irq_clear = sata_fsl_irq_clear, - .irq_on = ata_dummy_irq_on, - .irq_ack = ata_dummy_irq_ack, - - .scr_read = sata_fsl_scr_read, - .scr_write = sata_fsl_scr_write, - - .freeze = sata_fsl_freeze, - .thaw = sata_fsl_thaw, - .error_handler = sata_fsl_error_handler, - .post_internal_cmd = sata_fsl_post_internal_cmd, - - .port_start = sata_fsl_port_start, - .port_stop = sata_fsl_port_stop, -}; - -static const struct ata_port_info sata_fsl_port_info[] = { - { - .flags = SATA_FSL_HOST_FLAGS, - .pio_mask = 0x1f, /* pio 0-4 */ - .udma_mask = 0x7f, /* udma 0-6 */ - .port_ops = &sata_fsl_ops, - }, -}; - -static int sata_fsl_probe(struct of_device *ofdev, - const struct of_device_id *match) -{ - int retval = 0; - void __iomem *hcr_base = NULL; - void __iomem *ssr_base = NULL; - void __iomem *csr_base = NULL; - struct sata_fsl_host_priv *host_priv = NULL; - struct resource *r; - int irq; - struct ata_host *host; - - struct ata_port_info pi = sata_fsl_port_info[0]; - const struct ata_port_info *ppi[] = { &pi, NULL }; - - dev_printk(KERN_INFO, &ofdev->dev, - "Sata FSL Platform/CSB Driver init\n"); - - r = kmalloc(sizeof(struct resource), GFP_KERNEL); - - hcr_base = of_iomap(ofdev->node, 0); - if (!hcr_base) - goto error_exit_with_cleanup; - - ssr_base = hcr_base + 0x100; - csr_base = hcr_base + 0x140; - - DPRINTK("@reset i/o = 0x%x\n", ioread32(csr_base + TRANSCFG)); - DPRINTK("sizeof(cmd_desc) = %d\n", sizeof(struct command_desc)); - DPRINTK("sizeof(#define cmd_desc) = %d\n", SATA_FSL_CMD_DESC_SIZE); - - host_priv = kzalloc(sizeof(struct sata_fsl_host_priv), GFP_KERNEL); - if (!host_priv) - goto error_exit_with_cleanup; - - host_priv->hcr_base = hcr_base; - host_priv->ssr_base = ssr_base; - host_priv->csr_base = csr_base; - - irq = irq_of_parse_and_map(ofdev->node, 0); - if (irq < 0) { - dev_printk(KERN_ERR, &ofdev->dev, "invalid irq from platform\n"); - goto error_exit_with_cleanup; - } - - /* allocate host structure */ - host = ata_host_alloc_pinfo(&ofdev->dev, ppi, SATA_FSL_MAX_PORTS); - - /* host->iomap is not used currently */ - host->private_data = host_priv; - - /* setup port(s) */ - - host->ports[0]->ioaddr.cmd_addr = host_priv->hcr_base; - host->ports[0]->ioaddr.scr_addr = host_priv->ssr_base; - - /* initialize host controller */ - sata_fsl_init_controller(host); - - /* - * Now, register with libATA core, this will also initiate the - * device discovery process, invoking our port_start() handler & - * error_handler() to execute a dummy Softreset EH session - */ - ata_host_activate(host, irq, sata_fsl_interrupt, SATA_FSL_IRQ_FLAG, - &sata_fsl_sht); - - dev_set_drvdata(&ofdev->dev, host); - - return 0; - -error_exit_with_cleanup: - - if (hcr_base) - iounmap(hcr_base); - if (host_priv) - kfree(host_priv); - - return retval; -} - -static int sata_fsl_remove(struct of_device *ofdev) -{ - struct ata_host *host = dev_get_drvdata(&ofdev->dev); - struct sata_fsl_host_priv *host_priv = host->private_data; - - ata_host_detach(host); - - dev_set_drvdata(&ofdev->dev, NULL); - - irq_dispose_mapping(host->irq); - iounmap(host_priv->hcr_base); - kfree(host_priv); - - return 0; -} - -static struct of_device_id fsl_sata_match[] = { - { - .compatible = "fsl,mpc8315-sata", - }, - { - .compatible = "fsl,mpc8379-sata", - }, - {}, -}; - -MODULE_DEVICE_TABLE(of, fsl_sata_match); - -static struct of_platform_driver fsl_sata_driver = { - .name = "fsl-sata", - .match_table = fsl_sata_match, - .probe = sata_fsl_probe, - .remove = sata_fsl_remove, -}; - -static int __init sata_fsl_init(void) -{ - of_register_platform_driver(&fsl_sata_driver); - return 0; -} - -static void __exit sata_fsl_exit(void) -{ - of_unregister_platform_driver(&fsl_sata_driver); -} - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Ashish Kalra, Freescale Semiconductor"); -MODULE_DESCRIPTION("Freescale 3.0Gbps SATA controller low level driver"); -MODULE_VERSION("1.10"); - -module_init(sata_fsl_init); -module_exit(sata_fsl_exit); diff --git a/trunk/drivers/ata/sata_mv.c b/trunk/drivers/ata/sata_mv.c index 7f1b13e89cf7..4df8311968e9 100644 --- a/trunk/drivers/ata/sata_mv.c +++ b/trunk/drivers/ata/sata_mv.c @@ -421,6 +421,7 @@ static void mv_error_handler(struct ata_port *ap); static void mv_post_int_cmd(struct ata_queued_cmd *qc); static void mv_eh_freeze(struct ata_port *ap); static void mv_eh_thaw(struct ata_port *ap); +static int mv_slave_config(struct scsi_device *sdev); static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); static void mv5_phy_errata(struct mv_host_priv *hpriv, void __iomem *mmio, @@ -458,7 +459,7 @@ static struct scsi_host_template mv5_sht = { .use_clustering = 1, .proc_name = DRV_NAME, .dma_boundary = MV_DMA_BOUNDARY, - .slave_configure = ata_scsi_slave_config, + .slave_configure = mv_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, }; @@ -476,7 +477,7 @@ static struct scsi_host_template mv6_sht = { .use_clustering = 1, .proc_name = DRV_NAME, .dma_boundary = MV_DMA_BOUNDARY, - .slave_configure = ata_scsi_slave_config, + .slave_configure = mv_slave_config, .slave_destroy = ata_scsi_slave_destroy, .bios_param = ata_std_bios_param, }; @@ -755,6 +756,17 @@ static void mv_irq_clear(struct ata_port *ap) { } +static int mv_slave_config(struct scsi_device *sdev) +{ + int rc = ata_scsi_slave_config(sdev); + if (rc) + return rc; + + blk_queue_max_phys_segments(sdev->request_queue, MV_MAX_SG_CT / 2); + + return 0; /* scsi layer doesn't check return value, sigh */ +} + static void mv_set_edma_ptrs(void __iomem *port_mmio, struct mv_host_priv *hpriv, struct mv_port_priv *pp) @@ -1126,7 +1138,7 @@ static void mv_fill_sg(struct ata_queued_cmd *qc) { struct mv_port_priv *pp = qc->ap->private_data; struct scatterlist *sg; - struct mv_sg *mv_sg, *last_sg = NULL; + struct mv_sg *mv_sg; mv_sg = pp->sg_tbl; ata_for_each_sg(sg, qc) { @@ -1147,13 +1159,13 @@ static void mv_fill_sg(struct ata_queued_cmd *qc) sg_len -= len; addr += len; - last_sg = mv_sg; + if (!sg_len && ata_sg_is_last(sg, qc)) + mv_sg->flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL); + mv_sg++; } - } - if (likely(last_sg)) - last_sg->flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL); + } } static inline void mv_crqb_pack_cmd(__le16 *cmdw, u8 data, u8 addr, unsigned last) diff --git a/trunk/drivers/ata/sata_sil24.c b/trunk/drivers/ata/sata_sil24.c index 26ebffc10f3e..b0619278454a 100644 --- a/trunk/drivers/ata/sata_sil24.c +++ b/trunk/drivers/ata/sata_sil24.c @@ -796,19 +796,16 @@ static inline void sil24_fill_sg(struct ata_queued_cmd *qc, struct sil24_sge *sge) { struct scatterlist *sg; - struct sil24_sge *last_sge = NULL; ata_for_each_sg(sg, qc) { sge->addr = cpu_to_le64(sg_dma_address(sg)); sge->cnt = cpu_to_le32(sg_dma_len(sg)); - sge->flags = 0; - - last_sge = sge; + if (ata_sg_is_last(sg, qc)) + sge->flags = cpu_to_le32(SGE_TRM); + else + sge->flags = 0; sge++; } - - if (likely(last_sge)) - last_sge->flags = cpu_to_le32(SGE_TRM); } static int sil24_qc_defer(struct ata_queued_cmd *qc) diff --git a/trunk/drivers/base/dmapool.c b/trunk/drivers/base/dmapool.c index 5beddc322e6f..fbae8674e491 100644 --- a/trunk/drivers/base/dmapool.c +++ b/trunk/drivers/base/dmapool.c @@ -366,7 +366,7 @@ dma_pool_free (struct dma_pool *pool, void *vaddr, dma_addr_t dma) unsigned long flags; int map, block; - if ((page = pool_find_page(pool, dma)) == NULL) { + if ((page = pool_find_page (pool, dma)) == 0) { if (pool->dev) dev_err(pool->dev, "dma_pool_free %s, %p/%lx (bad dma)\n", pool->name, vaddr, (unsigned long) dma); diff --git a/trunk/drivers/base/power/trace.c b/trunk/drivers/base/power/trace.c index 2b4b392dcbc1..2b0c601e422e 100644 --- a/trunk/drivers/base/power/trace.c +++ b/trunk/drivers/base/power/trace.c @@ -114,7 +114,7 @@ static unsigned int read_magic_time(void) get_rtc_time(&time); printk("Time: %2d:%02d:%02d Date: %02d/%02d/%02d\n", time.tm_hour, time.tm_min, time.tm_sec, - time.tm_mon + 1, time.tm_mday, time.tm_year % 100); + time.tm_mon, time.tm_mday, time.tm_year); val = time.tm_year; /* 100 years */ if (val > 100) val -= 100; diff --git a/trunk/drivers/base/topology.c b/trunk/drivers/base/topology.c index e1d3ad4db2f0..8d8cdfec6529 100644 --- a/trunk/drivers/base/topology.c +++ b/trunk/drivers/base/topology.c @@ -94,18 +94,27 @@ static struct attribute_group topology_attr_group = { .name = "topology" }; +static cpumask_t topology_dev_map = CPU_MASK_NONE; + /* Add/Remove cpu_topology interface for CPU device */ static int __cpuinit topology_add_dev(unsigned int cpu) { + int rc; struct sys_device *sys_dev = get_cpu_sysdev(cpu); - return sysfs_create_group(&sys_dev->kobj, &topology_attr_group); + rc = sysfs_create_group(&sys_dev->kobj, &topology_attr_group); + if (!rc) + cpu_set(cpu, topology_dev_map); + return rc; } static void __cpuinit topology_remove_dev(unsigned int cpu) { struct sys_device *sys_dev = get_cpu_sysdev(cpu); + if (!cpu_isset(cpu, topology_dev_map)) + return; + cpu_clear(cpu, topology_dev_map); sysfs_remove_group(&sys_dev->kobj, &topology_attr_group); } diff --git a/trunk/drivers/block/nbd.c b/trunk/drivers/block/nbd.c index ac4a0cb217ab..cb136a919f2a 100644 --- a/trunk/drivers/block/nbd.c +++ b/trunk/drivers/block/nbd.c @@ -188,7 +188,7 @@ static int sock_xmit(struct nbd_device *lo, int send, void *buf, int size, if (signal_pending(current)) { siginfo_t info; printk(KERN_WARNING "nbd (pid %d: %s) got signal %d\n", - task_pid_nr(current), current->comm, + current->pid, current->comm, dequeue_signal_lock(current, ¤t->blocked, &info)); result = -EINTR; sock_shutdown(lo, !send); diff --git a/trunk/drivers/block/xsysace.c b/trunk/drivers/block/xsysace.c index 82effce97c51..9e7652dcde6c 100644 --- a/trunk/drivers/block/xsysace.c +++ b/trunk/drivers/block/xsysace.c @@ -390,8 +390,8 @@ static inline void ace_dump_mem(void *base, int len) static void ace_dump_regs(struct ace_device *ace) { dev_info(ace->dev, " ctrl: %.8x seccnt/cmd: %.4x ver:%.4x\n" - KERN_INFO " status:%.8x mpu_lba:%.8x busmode:%4x\n" - KERN_INFO " error: %.8x cfg_lba:%.8x fatstat:%.4x\n", + " status:%.8x mpu_lba:%.8x busmode:%4x\n" + " error: %.8x cfg_lba:%.8x fatstat:%.4x\n", ace_in32(ace, ACE_CTRL), ace_in(ace, ACE_SECCNTCMD), ace_in(ace, ACE_VERSION), diff --git a/trunk/drivers/cdrom/cdrom.c b/trunk/drivers/cdrom/cdrom.c index af0561053167..79245714f0a7 100644 --- a/trunk/drivers/cdrom/cdrom.c +++ b/trunk/drivers/cdrom/cdrom.c @@ -1107,7 +1107,7 @@ int open_for_data(struct cdrom_device_info * cdi) is the default case! */ cdinfo(CD_OPEN, "bummer. wrong media type.\n"); cdinfo(CD_WARNING, "pid %d must open device O_NONBLOCK!\n", - (unsigned int)task_pid_nr(current)); + (unsigned int)current->pid); ret=-EMEDIUMTYPE; goto clean_up_and_return; } @@ -3458,19 +3458,47 @@ static void cdrom_update_settings(void) static int cdrom_sysctl_handler(ctl_table *ctl, int write, struct file * filp, void __user *buffer, size_t *lenp, loff_t *ppos) { + int *valp = ctl->data; + int val = *valp; int ret; ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos); - if (write) { + if (write && *valp != val) { /* we only care for 1 or 0. */ - autoclose = !!cdrom_sysctl_settings.autoclose; - autoeject = !!cdrom_sysctl_settings.autoeject; - debug = !!cdrom_sysctl_settings.debug; - lockdoor = !!cdrom_sysctl_settings.lock; - check_media_type = !!cdrom_sysctl_settings.check; + if (*valp) + *valp = 1; + else + *valp = 0; + switch (ctl->ctl_name) { + case DEV_CDROM_AUTOCLOSE: { + if (valp == &cdrom_sysctl_settings.autoclose) + autoclose = cdrom_sysctl_settings.autoclose; + break; + } + case DEV_CDROM_AUTOEJECT: { + if (valp == &cdrom_sysctl_settings.autoeject) + autoeject = cdrom_sysctl_settings.autoeject; + break; + } + case DEV_CDROM_DEBUG: { + if (valp == &cdrom_sysctl_settings.debug) + debug = cdrom_sysctl_settings.debug; + break; + } + case DEV_CDROM_LOCK: { + if (valp == &cdrom_sysctl_settings.lock) + lockdoor = cdrom_sysctl_settings.lock; + break; + } + case DEV_CDROM_CHECK_MEDIA: { + if (valp == &cdrom_sysctl_settings.check) + check_media_type = cdrom_sysctl_settings.check; + break; + } + } /* update the option flags according to the changes. we don't have per device options through sysctl yet, but we will have and then this will disappear. */ @@ -3483,6 +3511,7 @@ static int cdrom_sysctl_handler(ctl_table *ctl, int write, struct file * filp, /* Place files in /proc/sys/dev/cdrom */ static ctl_table cdrom_table[] = { { + .ctl_name = DEV_CDROM_INFO, .procname = "info", .data = &cdrom_sysctl_settings.info, .maxlen = CDROM_STR_SIZE, @@ -3490,6 +3519,7 @@ static ctl_table cdrom_table[] = { .proc_handler = &cdrom_sysctl_info, }, { + .ctl_name = DEV_CDROM_AUTOCLOSE, .procname = "autoclose", .data = &cdrom_sysctl_settings.autoclose, .maxlen = sizeof(int), @@ -3497,6 +3527,7 @@ static ctl_table cdrom_table[] = { .proc_handler = &cdrom_sysctl_handler, }, { + .ctl_name = DEV_CDROM_AUTOEJECT, .procname = "autoeject", .data = &cdrom_sysctl_settings.autoeject, .maxlen = sizeof(int), @@ -3504,6 +3535,7 @@ static ctl_table cdrom_table[] = { .proc_handler = &cdrom_sysctl_handler, }, { + .ctl_name = DEV_CDROM_DEBUG, .procname = "debug", .data = &cdrom_sysctl_settings.debug, .maxlen = sizeof(int), @@ -3511,6 +3543,7 @@ static ctl_table cdrom_table[] = { .proc_handler = &cdrom_sysctl_handler, }, { + .ctl_name = DEV_CDROM_LOCK, .procname = "lock", .data = &cdrom_sysctl_settings.lock, .maxlen = sizeof(int), @@ -3518,6 +3551,7 @@ static ctl_table cdrom_table[] = { .proc_handler = &cdrom_sysctl_handler, }, { + .ctl_name = DEV_CDROM_CHECK_MEDIA, .procname = "check_media", .data = &cdrom_sysctl_settings.check, .maxlen = sizeof(int), diff --git a/trunk/drivers/char/Kconfig b/trunk/drivers/char/Kconfig index 65491103e0fb..204d53e506de 100644 --- a/trunk/drivers/char/Kconfig +++ b/trunk/drivers/char/Kconfig @@ -36,6 +36,23 @@ config VT If unsure, say Y, or else you won't be able to do much with your new shiny Linux system :-) +config VT_UNICODE + bool "Virtual console is Unicode by default" + depends on VT + default n + ---help--- + If you say Y here, the virtual terminal will be in UTF-8 by default, + and the keyboard will run in unicode mode. + + If you say N here, the virtual terminal will not be in UTF-8 by + default, and the keyboard will run in XLATE mode. + + This can also be changed by passing 'default_utf8=<0|1>' on the + kernel command line. + + Historically, the kernel has defaulted to non-UTF8 and XLATE mode. + If unsure, say N here. + config VT_CONSOLE bool "Support for console on virtual terminal" if EMBEDDED depends on VT @@ -632,6 +649,8 @@ config HVCS source "drivers/char/ipmi/Kconfig" +source "drivers/char/watchdog/Kconfig" + config DS1620 tristate "NetWinder thermometer support" depends on ARCH_NETWINDER diff --git a/trunk/drivers/char/apm-emulation.c b/trunk/drivers/char/apm-emulation.c index c99e43b837f5..ec116df919d9 100644 --- a/trunk/drivers/char/apm-emulation.c +++ b/trunk/drivers/char/apm-emulation.c @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/trunk/drivers/char/cyclades.c b/trunk/drivers/char/cyclades.c index d15234c5965e..9e0adfe27c12 100644 --- a/trunk/drivers/char/cyclades.c +++ b/trunk/drivers/char/cyclades.c @@ -662,7 +662,7 @@ static void cy_throttle(struct tty_struct *tty); static void cy_send_xchar(struct tty_struct *tty, char ch); -#define IS_CYC_Z(card) ((card).num_chips == (unsigned int)-1) +#define IS_CYC_Z(card) ((card).num_chips == -1) #define Z_FPGA_CHECK(card) \ ((readl(&((struct RUNTIME_9060 __iomem *) \ @@ -897,6 +897,71 @@ static inline int serial_paranoia_check(struct cyclades_port *info, return 0; } /* serial_paranoia_check */ +/* + * This routine is used by the interrupt handler to schedule + * processing in the software interrupt portion of the driver + * (also known as the "bottom half"). This can be called any + * number of times for any channel without harm. + */ +static inline void cy_sched_event(struct cyclades_port *info, int event) +{ + info->event |= 1 << event; /* remember what kind of event and who */ + schedule_work(&info->tqueue); +} /* cy_sched_event */ + +/* + * This routine is used to handle the "bottom half" processing for the + * serial driver, known also the "software interrupt" processing. + * This processing is done at the kernel interrupt level, after the + * cy#/_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON. This + * is where time-consuming activities which can not be done in the + * interrupt driver proper are done; the interrupt driver schedules + * them using cy_sched_event(), and they get done here. + * + * This is done through one level of indirection--the task queue. + * When a hardware interrupt service routine wants service by the + * driver's bottom half, it enqueues the appropriate tq_struct (one + * per port) to the keventd work queue and sets a request flag + * that the work queue be processed. + * + * Although this may seem unwieldy, it gives the system a way to + * pass an argument (in this case the pointer to the cyclades_port + * structure) to the bottom half of the driver. Previous kernels + * had to poll every port to see if that port needed servicing. + */ +static void +do_softint(struct work_struct *work) +{ + struct cyclades_port *info = + container_of(work, struct cyclades_port, tqueue); + struct tty_struct *tty; + + tty = info->tty; + if (!tty) + return; + + if (test_and_clear_bit(Cy_EVENT_HANGUP, &info->event)) { + tty_hangup(info->tty); + wake_up_interruptible(&info->open_wait); + info->flags &= ~ASYNC_NORMAL_ACTIVE; + } + if (test_and_clear_bit(Cy_EVENT_OPEN_WAKEUP, &info->event)) + wake_up_interruptible(&info->open_wait); +#ifdef CONFIG_CYZ_INTR + if (test_and_clear_bit(Cy_EVENT_Z_RX_FULL, &info->event) && + !timer_pending(&cyz_rx_full_timer[info->line])) + mod_timer(&cyz_rx_full_timer[info->line], jiffies + 1); +#endif + if (test_and_clear_bit(Cy_EVENT_DELTA_WAKEUP, &info->event)) + wake_up_interruptible(&info->delta_msr_wait); + tty_wakeup(tty); +#ifdef Z_WAKE + if (test_and_clear_bit(Cy_EVENT_SHUTDOWN_WAKEUP, &info->event)) + complete(&info->shutdown_wait); +#endif +} /* do_softint */ + + /***********************************************************/ /********* Start of block of Cyclom-Y specific code ********/ @@ -980,332 +1045,382 @@ static unsigned detect_isa_irq(void __iomem * address) } #endif /* CONFIG_ISA */ -static void cyy_chip_rx(struct cyclades_card *cinfo, int chip, - void __iomem *base_addr) +static void cyy_intr_chip(struct cyclades_card *cinfo, int chip, + void __iomem * base_addr, int status, int index) { struct cyclades_port *info; struct tty_struct *tty; - int len, index = cinfo->bus_index; - u8 save_xir, channel, save_car, data, char_count; + int char_count; + int j, len, mdm_change, mdm_status, outch; + int save_xir, channel, save_car; + char data; + if (status & CySRReceive) { /* reception interrupt */ #ifdef CY_DEBUG_INTERRUPTS - printk(KERN_DEBUG "cyy_interrupt: rcvd intr, chip %d\n", chip); + printk(KERN_DEBUG "cyy_interrupt: rcvd intr, chip %d\n", chip); #endif - /* determine the channel & change to that context */ - save_xir = readb(base_addr + (CyRIR << index)); - channel = save_xir & CyIRChannel; - info = &cinfo->ports[channel + chip * 4]; - save_car = readb(base_addr + (CyCAR << index)); - cy_writeb(base_addr + (CyCAR << index), save_xir); - - /* if there is nowhere to put the data, discard it */ - if (info->tty == NULL) { - if ((readb(base_addr + (CyRIVR << index)) & CyIVRMask) == - CyIVRRxEx) { /* exception */ - data = readb(base_addr + (CyRDSR << index)); - } else { /* normal character reception */ - char_count = readb(base_addr + (CyRDCR << index)); - while (char_count--) + /* determine the channel & change to that context */ + spin_lock(&cinfo->card_lock); + save_xir = (u_char) readb(base_addr + (CyRIR << index)); + channel = (u_short) (save_xir & CyIRChannel); + info = &cinfo->ports[channel + chip * 4]; + save_car = readb(base_addr + (CyCAR << index)); + cy_writeb(base_addr + (CyCAR << index), save_xir); + + /* if there is nowhere to put the data, discard it */ + if (info->tty == NULL) { + j = (readb(base_addr + (CyRIVR << index)) & + CyIVRMask); + if (j == CyIVRRxEx) { /* exception */ data = readb(base_addr + (CyRDSR << index)); - } - goto end; - } - /* there is an open port for this data */ - tty = info->tty; - if ((readb(base_addr + (CyRIVR << index)) & CyIVRMask) == - CyIVRRxEx) { /* exception */ - data = readb(base_addr + (CyRDSR << index)); - - /* For statistics only */ - if (data & CyBREAK) - info->icount.brk++; - else if (data & CyFRAME) - info->icount.frame++; - else if (data & CyPARITY) - info->icount.parity++; - else if (data & CyOVERRUN) - info->icount.overrun++; - - if (data & info->ignore_status_mask) { - info->icount.rx++; - return; - } - if (tty_buffer_request_room(tty, 1)) { - if (data & info->read_status_mask) { - if (data & CyBREAK) { - tty_insert_flip_char(tty, - readb(base_addr + (CyRDSR << - index)), TTY_BREAK); - info->icount.rx++; - if (info->flags & ASYNC_SAK) - do_SAK(tty); - } else if (data & CyFRAME) { - tty_insert_flip_char( tty, - readb(base_addr + (CyRDSR << - index)), TTY_FRAME); - info->icount.rx++; - info->idle_stats.frame_errs++; - } else if (data & CyPARITY) { - /* Pieces of seven... */ - tty_insert_flip_char(tty, - readb(base_addr + (CyRDSR << - index)), TTY_PARITY); - info->icount.rx++; - info->idle_stats.parity_errs++; - } else if (data & CyOVERRUN) { - tty_insert_flip_char(tty, 0, - TTY_OVERRUN); - info->icount.rx++; - /* If the flip buffer itself is - overflowing, we still lose - the next incoming character. - */ - tty_insert_flip_char(tty, - readb(base_addr + (CyRDSR << - index)), TTY_FRAME); + } else { /* normal character reception */ + char_count = readb(base_addr + + (CyRDCR << index)); + while (char_count--) { + data = readb(base_addr + + (CyRDSR << index)); + } + } + } else { /* there is an open port for this data */ + tty = info->tty; + j = (readb(base_addr + (CyRIVR << index)) & + CyIVRMask); + if (j == CyIVRRxEx) { /* exception */ + data = readb(base_addr + (CyRDSR << index)); + + /* For statistics only */ + if (data & CyBREAK) + info->icount.brk++; + else if (data & CyFRAME) + info->icount.frame++; + else if (data & CyPARITY) + info->icount.parity++; + else if (data & CyOVERRUN) + info->icount.overrun++; + + if (data & info->ignore_status_mask) { info->icount.rx++; - info->idle_stats.overruns++; - /* These two conditions may imply */ - /* a normal read should be done. */ - /* } else if(data & CyTIMEOUT) { */ - /* } else if(data & CySPECHAR) { */ + spin_unlock(&cinfo->card_lock); + return; + } + if (tty_buffer_request_room(tty, 1)) { + if (data & info->read_status_mask) { + if (data & CyBREAK) { + tty_insert_flip_char( + tty, + readb( + base_addr + + (CyRDSR << + index)), + TTY_BREAK); + info->icount.rx++; + if (info->flags & + ASYNC_SAK) { + do_SAK(tty); + } + } else if (data & CyFRAME) { + tty_insert_flip_char( + tty, + readb( + base_addr + + (CyRDSR << + index)), + TTY_FRAME); + info->icount.rx++; + info->idle_stats. + frame_errs++; + } else if (data & CyPARITY) { + /* Pieces of seven... */ + tty_insert_flip_char( + tty, + readb( + base_addr + + (CyRDSR << + index)), + TTY_PARITY); + info->icount.rx++; + info->idle_stats. + parity_errs++; + } else if (data & CyOVERRUN) { + tty_insert_flip_char( + tty, 0, + TTY_OVERRUN); + info->icount.rx++; + /* If the flip buffer itself is + overflowing, we still lose + the next incoming character. + */ + tty_insert_flip_char( + tty, + readb( + base_addr + + (CyRDSR << + index)), + TTY_FRAME); + info->icount.rx++; + info->idle_stats. + overruns++; + /* These two conditions may imply */ + /* a normal read should be done. */ + /* }else if(data & CyTIMEOUT){ */ + /* }else if(data & CySPECHAR){ */ + } else { + tty_insert_flip_char( + tty, 0, + TTY_NORMAL); + info->icount.rx++; + } + } else { + tty_insert_flip_char(tty, 0, + TTY_NORMAL); + info->icount.rx++; + } } else { - tty_insert_flip_char(tty, 0, - TTY_NORMAL); - info->icount.rx++; + /* there was a software buffer + overrun and nothing could be + done about it!!! */ + info->icount.buf_overrun++; + info->idle_stats.overruns++; } - } else { - tty_insert_flip_char(tty, 0, TTY_NORMAL); - info->icount.rx++; - } - } else { - /* there was a software buffer overrun and nothing - * could be done about it!!! */ - info->icount.buf_overrun++; - info->idle_stats.overruns++; - } - } else { /* normal character reception */ - /* load # chars available from the chip */ - char_count = readb(base_addr + (CyRDCR << index)); + } else { /* normal character reception */ + /* load # chars available from the chip */ + char_count = readb(base_addr + + (CyRDCR << index)); #ifdef CY_ENABLE_MONITORING - ++info->mon.int_count; - info->mon.char_count += char_count; - if (char_count > info->mon.char_max) - info->mon.char_max = char_count; - info->mon.char_last = char_count; + ++info->mon.int_count; + info->mon.char_count += char_count; + if (char_count > info->mon.char_max) + info->mon.char_max = char_count; + info->mon.char_last = char_count; #endif - len = tty_buffer_request_room(tty, char_count); - while (len--) { - data = readb(base_addr + (CyRDSR << index)); - tty_insert_flip_char(tty, data, TTY_NORMAL); - info->idle_stats.recv_bytes++; - info->icount.rx++; + len = tty_buffer_request_room(tty, char_count); + while (len--) { + data = readb(base_addr + + (CyRDSR << index)); + tty_insert_flip_char(tty, data, + TTY_NORMAL); + info->idle_stats.recv_bytes++; + info->icount.rx++; #ifdef CY_16Y_HACK - udelay(10L); + udelay(10L); #endif + } + info->idle_stats.recv_idle = jiffies; + } + tty_schedule_flip(tty); } - info->idle_stats.recv_idle = jiffies; + /* end of service */ + cy_writeb(base_addr + (CyRIR << index), (save_xir & 0x3f)); + cy_writeb(base_addr + (CyCAR << index), (save_car)); + spin_unlock(&cinfo->card_lock); } - tty_schedule_flip(tty); -end: - /* end of service */ - cy_writeb(base_addr + (CyRIR << index), save_xir & 0x3f); - cy_writeb(base_addr + (CyCAR << index), save_car); -} - -static void cyy_chip_tx(struct cyclades_card *cinfo, unsigned int chip, - void __iomem *base_addr) -{ - struct cyclades_port *info; - int char_count, index = cinfo->bus_index; - u8 save_xir, channel, save_car, outch; - /* Since we only get here when the transmit buffer - is empty, we know we can always stuff a dozen - characters. */ + if (status & CySRTransmit) { /* transmission interrupt */ + /* Since we only get here when the transmit buffer + is empty, we know we can always stuff a dozen + characters. */ #ifdef CY_DEBUG_INTERRUPTS - printk(KERN_DEBUG "cyy_interrupt: xmit intr, chip %d\n", chip); + printk(KERN_DEBUG "cyy_interrupt: xmit intr, chip %d\n", chip); #endif - /* determine the channel & change to that context */ - save_xir = readb(base_addr + (CyTIR << index)); - channel = save_xir & CyIRChannel; - save_car = readb(base_addr + (CyCAR << index)); - cy_writeb(base_addr + (CyCAR << index), save_xir); + /* determine the channel & change to that context */ + spin_lock(&cinfo->card_lock); + save_xir = (u_char) readb(base_addr + (CyTIR << index)); + channel = (u_short) (save_xir & CyIRChannel); + save_car = readb(base_addr + (CyCAR << index)); + cy_writeb(base_addr + (CyCAR << index), save_xir); - /* validate the port# (as configured and open) */ - if (channel + chip * 4 >= cinfo->nports) { - cy_writeb(base_addr + (CySRER << index), - readb(base_addr + (CySRER << index)) & ~CyTxRdy); - goto end; - } - info = &cinfo->ports[channel + chip * 4]; - if (info->tty == NULL) { - cy_writeb(base_addr + (CySRER << index), - readb(base_addr + (CySRER << index)) & ~CyTxRdy); - goto end; - } - - /* load the on-chip space for outbound data */ - char_count = info->xmit_fifo_size; + /* validate the port# (as configured and open) */ + if (channel + chip * 4 >= cinfo->nports) { + cy_writeb(base_addr + (CySRER << index), + readb(base_addr + (CySRER << index)) & + ~CyTxRdy); + goto txend; + } + info = &cinfo->ports[channel + chip * 4]; + if (info->tty == NULL) { + cy_writeb(base_addr + (CySRER << index), + readb(base_addr + (CySRER << index)) & + ~CyTxRdy); + goto txdone; + } - if (info->x_char) { /* send special char */ - outch = info->x_char; - cy_writeb(base_addr + (CyTDR << index), outch); - char_count--; - info->icount.tx++; - info->x_char = 0; - } + /* load the on-chip space for outbound data */ + char_count = info->xmit_fifo_size; - if (info->breakon || info->breakoff) { - if (info->breakon) { - cy_writeb(base_addr + (CyTDR << index), 0); - cy_writeb(base_addr + (CyTDR << index), 0x81); - info->breakon = 0; - char_count -= 2; + if (info->x_char) { /* send special char */ + outch = info->x_char; + cy_writeb(base_addr + (CyTDR << index), outch); + char_count--; + info->icount.tx++; + info->x_char = 0; } - if (info->breakoff) { - cy_writeb(base_addr + (CyTDR << index), 0); - cy_writeb(base_addr + (CyTDR << index), 0x83); - info->breakoff = 0; - char_count -= 2; + + if (info->breakon || info->breakoff) { + if (info->breakon) { + cy_writeb(base_addr + (CyTDR << index), 0); + cy_writeb(base_addr + (CyTDR << index), 0x81); + info->breakon = 0; + char_count -= 2; + } + if (info->breakoff) { + cy_writeb(base_addr + (CyTDR << index), 0); + cy_writeb(base_addr + (CyTDR << index), 0x83); + info->breakoff = 0; + char_count -= 2; + } } - } - while (char_count-- > 0) { - if (!info->xmit_cnt) { - if (readb(base_addr + (CySRER << index)) & CyTxMpty) { - cy_writeb(base_addr + (CySRER << index), - readb(base_addr + (CySRER << index)) & + while (char_count-- > 0) { + if (!info->xmit_cnt) { + if (readb(base_addr + (CySRER << index)) & + CyTxMpty) { + cy_writeb(base_addr + (CySRER << index), + readb(base_addr + + (CySRER << index)) & ~CyTxMpty); - } else { - cy_writeb(base_addr + (CySRER << index), - (readb(base_addr + (CySRER << index)) & + } else { + cy_writeb(base_addr + (CySRER << index), + (readb(base_addr + + (CySRER << index)) & ~CyTxRdy) | CyTxMpty); + } + goto txdone; } - goto done; - } - if (info->xmit_buf == NULL) { - cy_writeb(base_addr + (CySRER << index), - readb(base_addr + (CySRER << index)) & + if (info->xmit_buf == NULL) { + cy_writeb(base_addr + (CySRER << index), + readb(base_addr + (CySRER << index)) & ~CyTxRdy); - goto done; - } - if (info->tty->stopped || info->tty->hw_stopped) { - cy_writeb(base_addr + (CySRER << index), - readb(base_addr + (CySRER << index)) & + goto txdone; + } + if (info->tty->stopped || info->tty->hw_stopped) { + cy_writeb(base_addr + (CySRER << index), + readb(base_addr + (CySRER << index)) & ~CyTxRdy); - goto done; - } - /* Because the Embedded Transmit Commands have been enabled, - * we must check to see if the escape character, NULL, is being - * sent. If it is, we must ensure that there is room for it to - * be doubled in the output stream. Therefore we no longer - * advance the pointer when the character is fetched, but - * rather wait until after the check for a NULL output - * character. This is necessary because there may not be room - * for the two chars needed to send a NULL.) - */ - outch = info->xmit_buf[info->xmit_tail]; - if (outch) { - info->xmit_cnt--; - info->xmit_tail = (info->xmit_tail + 1) & - (SERIAL_XMIT_SIZE - 1); - cy_writeb(base_addr + (CyTDR << index), outch); - info->icount.tx++; - } else { - if (char_count > 1) { + goto txdone; + } + /* Because the Embedded Transmit Commands have + been enabled, we must check to see if the + escape character, NULL, is being sent. If it + is, we must ensure that there is room for it + to be doubled in the output stream. Therefore + we no longer advance the pointer when the + character is fetched, but rather wait until + after the check for a NULL output character. + This is necessary because there may not be + room for the two chars needed to send a NULL.) + */ + outch = info->xmit_buf[info->xmit_tail]; + if (outch) { info->xmit_cnt--; info->xmit_tail = (info->xmit_tail + 1) & - (SERIAL_XMIT_SIZE - 1); + (SERIAL_XMIT_SIZE - 1); cy_writeb(base_addr + (CyTDR << index), outch); - cy_writeb(base_addr + (CyTDR << index), 0); info->icount.tx++; - char_count--; + } else { + if (char_count > 1) { + info->xmit_cnt--; + info->xmit_tail = (info->xmit_tail + 1)& + (SERIAL_XMIT_SIZE - 1); + cy_writeb(base_addr + (CyTDR << index), + outch); + cy_writeb(base_addr + (CyTDR << index), + 0); + info->icount.tx++; + char_count--; + } } } - } -done: - tty_wakeup(info->tty); -end: - /* end of service */ - cy_writeb(base_addr + (CyTIR << index), save_xir & 0x3f); - cy_writeb(base_addr + (CyCAR << index), save_car); -} - -static void cyy_chip_modem(struct cyclades_card *cinfo, int chip, - void __iomem *base_addr) -{ - struct cyclades_port *info; - int index = cinfo->bus_index; - u8 save_xir, channel, save_car, mdm_change, mdm_status; - - /* determine the channel & change to that context */ - save_xir = readb(base_addr + (CyMIR << index)); - channel = save_xir & CyIRChannel; - info = &cinfo->ports[channel + chip * 4]; - save_car = readb(base_addr + (CyCAR << index)); - cy_writeb(base_addr + (CyCAR << index), save_xir); +txdone: + if (info->xmit_cnt < WAKEUP_CHARS) { + cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP); + } +txend: + /* end of service */ + cy_writeb(base_addr + (CyTIR << index), (save_xir & 0x3f)); + cy_writeb(base_addr + (CyCAR << index), (save_car)); + spin_unlock(&cinfo->card_lock); + } - mdm_change = readb(base_addr + (CyMISR << index)); - mdm_status = readb(base_addr + (CyMSVR1 << index)); + if (status & CySRModem) { /* modem interrupt */ - if (!info->tty) - goto end; + /* determine the channel & change to that context */ + spin_lock(&cinfo->card_lock); + save_xir = (u_char) readb(base_addr + (CyMIR << index)); + channel = (u_short) (save_xir & CyIRChannel); + info = &cinfo->ports[channel + chip * 4]; + save_car = readb(base_addr + (CyCAR << index)); + cy_writeb(base_addr + (CyCAR << index), save_xir); - if (mdm_change & CyANY_DELTA) { - /* For statistics only */ - if (mdm_change & CyDCD) - info->icount.dcd++; - if (mdm_change & CyCTS) - info->icount.cts++; - if (mdm_change & CyDSR) - info->icount.dsr++; - if (mdm_change & CyRI) - info->icount.rng++; + mdm_change = readb(base_addr + (CyMISR << index)); + mdm_status = readb(base_addr + (CyMSVR1 << index)); - wake_up_interruptible(&info->delta_msr_wait); - } + if (info->tty) { + if (mdm_change & CyANY_DELTA) { + /* For statistics only */ + if (mdm_change & CyDCD) + info->icount.dcd++; + if (mdm_change & CyCTS) + info->icount.cts++; + if (mdm_change & CyDSR) + info->icount.dsr++; + if (mdm_change & CyRI) + info->icount.rng++; + + cy_sched_event(info, Cy_EVENT_DELTA_WAKEUP); + } - if ((mdm_change & CyDCD) && (info->flags & ASYNC_CHECK_CD)) { - if (!(mdm_status & CyDCD)) { - tty_hangup(info->tty); - info->flags &= ~ASYNC_NORMAL_ACTIVE; - } - wake_up_interruptible(&info->open_wait); - } - if ((mdm_change & CyCTS) && (info->flags & ASYNC_CTS_FLOW)) { - if (info->tty->hw_stopped) { - if (mdm_status & CyCTS) { - /* cy_start isn't used - because... !!! */ - info->tty->hw_stopped = 0; - cy_writeb(base_addr + (CySRER << index), - readb(base_addr + (CySRER << index)) | - CyTxRdy); - tty_wakeup(info->tty); + if ((mdm_change & CyDCD) && + (info->flags & ASYNC_CHECK_CD)) { + if (mdm_status & CyDCD) { + cy_sched_event(info, + Cy_EVENT_OPEN_WAKEUP); + } else { + cy_sched_event(info, Cy_EVENT_HANGUP); + } } - } else { - if (!(mdm_status & CyCTS)) { - /* cy_stop isn't used - because ... !!! */ - info->tty->hw_stopped = 1; - cy_writeb(base_addr + (CySRER << index), - readb(base_addr + (CySRER << index)) & - ~CyTxRdy); + if ((mdm_change & CyCTS) && + (info->flags & ASYNC_CTS_FLOW)) { + if (info->tty->hw_stopped) { + if (mdm_status & CyCTS) { + /* cy_start isn't used + because... !!! */ + info->tty->hw_stopped = 0; + cy_writeb(base_addr + + (CySRER << index), + readb(base_addr + + (CySRER << + index))| + CyTxRdy); + cy_sched_event(info, + Cy_EVENT_WRITE_WAKEUP); + } + } else { + if (!(mdm_status & CyCTS)) { + /* cy_stop isn't used + because ... !!! */ + info->tty->hw_stopped = 1; + cy_writeb(base_addr + + (CySRER << index), + readb(base_addr + + (CySRER << + index)) & + ~CyTxRdy); + } + } + } +/* if (mdm_change & CyDSR) { } + if (mdm_change & CyRI) { + }*/ } + /* end of service */ + cy_writeb(base_addr + (CyMIR << index), (save_xir & 0x3f)); + cy_writeb(base_addr + (CyCAR << index), save_car); + spin_unlock(&cinfo->card_lock); } -/* if (mdm_change & CyDSR) { - } - if (mdm_change & CyRI) { - }*/ -end: - /* end of service */ - cy_writeb(base_addr + (CyMIR << index), save_xir & 0x3f); - cy_writeb(base_addr + (CyCAR << index), save_car); } /* The real interrupt service routine is called @@ -1317,8 +1432,10 @@ static irqreturn_t cyy_interrupt(int irq, void *dev_id) int status; struct cyclades_card *cinfo = dev_id; void __iomem *base_addr, *card_base_addr; - unsigned int chip, too_many, had_work; + int chip; int index; + int too_many; + int had_work; if (unlikely(cinfo == NULL)) { #ifdef CY_DEBUG_INTERRUPTS @@ -1353,16 +1470,11 @@ static irqreturn_t cyy_interrupt(int irq, void *dev_id) chips to be checked in a round-robin fashion (after draining each of a bunch (1000) of characters). */ - if (1000 < too_many++) + if (1000 < too_many++) { break; - spin_lock(&cinfo->card_lock); - if (status & CySRReceive) /* rx intr */ - cyy_chip_rx(cinfo, chip, base_addr); - if (status & CySRTransmit) /* tx intr */ - cyy_chip_tx(cinfo, chip, base_addr); - if (status & CySRModem) /* modem intr */ - cyy_chip_modem(cinfo, chip, base_addr); - spin_unlock(&cinfo->card_lock); + } + cyy_intr_chip(cinfo, chip, base_addr, status, + index); } } } while (had_work); @@ -1417,7 +1529,7 @@ cyz_issue_cmd(struct cyclades_card *cinfo, struct ZFW_CTRL __iomem *zfw_ctrl; struct BOARD_CTRL __iomem *board_ctrl; __u32 __iomem *pci_doorbell; - unsigned int index; + int index; firm_id = cinfo->base_addr + ID_ADDRESS; if (!ISZLOADED(*cinfo)) { @@ -1442,12 +1554,13 @@ cyz_issue_cmd(struct cyclades_card *cinfo, return 0; } /* cyz_issue_cmd */ -static void cyz_handle_rx(struct cyclades_port *info, +static void +cyz_handle_rx(struct cyclades_port *info, struct CH_CTRL __iomem *ch_ctrl, struct BUF_CTRL __iomem *buf_ctrl) { struct cyclades_card *cinfo = info->card; struct tty_struct *tty = info->tty; - unsigned int char_count; + int char_count; int len; #ifdef BLOCKMOVE unsigned char *buf; @@ -1520,11 +1633,9 @@ static void cyz_handle_rx(struct cyclades_port *info, char_count = rx_put - rx_get; else char_count = rx_put - rx_get + rx_bufsize; - if (char_count >= readl(&buf_ctrl->rx_threshold) && - !timer_pending(&cyz_rx_full_timer[ - info->line])) - mod_timer(&cyz_rx_full_timer[info->line], - jiffies + 1); + if (char_count >= (int)readl(&buf_ctrl->rx_threshold)) { + cy_sched_event(info, Cy_EVENT_Z_RX_FULL); + } #endif info->idle_stats.recv_idle = jiffies; tty_schedule_flip(tty); @@ -1534,13 +1645,14 @@ static void cyz_handle_rx(struct cyclades_port *info, } } -static void cyz_handle_tx(struct cyclades_port *info, +static void +cyz_handle_tx(struct cyclades_port *info, struct CH_CTRL __iomem *ch_ctrl, struct BUF_CTRL __iomem *buf_ctrl) { struct cyclades_card *cinfo = info->card; struct tty_struct *tty = info->tty; - u8 data; - unsigned int char_count; + char data; + int char_count; #ifdef BLOCKMOVE int small_count; #endif @@ -1605,7 +1717,9 @@ static void cyz_handle_tx(struct cyclades_port *info, } #endif ztxdone: - tty_wakeup(tty); + if (info->xmit_cnt < WAKEUP_CHARS) { + cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP); + } /* Update tx_put */ cy_writel(&buf_ctrl->tx_put, tx_put); } @@ -1667,11 +1781,10 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) if ((fw_ver > 241 ? ((u_long) param) : readl(&ch_ctrl->rs_status)) & C_RS_DCD) { - wake_up_interruptible(&info->open_wait); + cy_sched_event(info, + Cy_EVENT_OPEN_WAKEUP); } else { - tty_hangup(info->tty); - wake_up_interruptible(&info->open_wait); - info->flags &= ~ASYNC_NORMAL_ACTIVE; + cy_sched_event(info, Cy_EVENT_HANGUP); } } break; @@ -1689,7 +1802,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) break; #ifdef Z_WAKE case C_CM_IOCTLW: - complete(&info->shutdown_wait); + cy_sched_event(info, Cy_EVENT_SHUTDOWN_WAKEUP); break; #endif #ifdef CONFIG_CYZ_INTR @@ -1701,7 +1814,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) printk(KERN_DEBUG "cyz_interrupt: rcvd intr, card %d, " "port %ld\n", info->card, channel); #endif - cyz_handle_rx(info, buf_ctrl); + cyz_handle_rx(info, ch_ctrl, buf_ctrl); break; case C_CM_TXBEMPTY: case C_CM_TXLOWWM: @@ -1711,7 +1824,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) printk(KERN_DEBUG "cyz_interrupt: xmit intr, card %d, " "port %ld\n", info->card, channel); #endif - cyz_handle_tx(info, buf_ctrl); + cyz_handle_tx(info, ch_ctrl, buf_ctrl); break; #endif /* CONFIG_CYZ_INTR */ case C_CM_FATAL: @@ -1721,7 +1834,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo) break; } if (delta_count) - wake_up_interruptible(&info->delta_msr_wait); + cy_sched_event(info, Cy_EVENT_DELTA_WAKEUP); if (special_count) tty_schedule_flip(tty); } @@ -1780,9 +1893,10 @@ static void cyz_poll(unsigned long arg) struct FIRM_ID __iomem *firm_id; struct ZFW_CTRL __iomem *zfw_ctrl; struct BOARD_CTRL __iomem *board_ctrl; + struct CH_CTRL __iomem *ch_ctrl; struct BUF_CTRL __iomem *buf_ctrl; unsigned long expires = jiffies + HZ; - unsigned int port, card; + int card, port; for (card = 0; card < NR_CARDS; card++) { cinfo = &cy_card[card]; @@ -1809,11 +1923,12 @@ static void cyz_poll(unsigned long arg) for (port = 0; port < cinfo->nports; port++) { info = &cinfo->ports[port]; tty = info->tty; + ch_ctrl = &(zfw_ctrl->ch_ctrl[port]); buf_ctrl = &(zfw_ctrl->buf_ctrl[port]); if (!info->throttle) - cyz_handle_rx(info, buf_ctrl); - cyz_handle_tx(info, buf_ctrl); + cyz_handle_rx(info, ch_ctrl, buf_ctrl); + cyz_handle_tx(info, ch_ctrl, buf_ctrl); } /* poll every 'cyz_polling_cycle' period */ expires = jiffies + cyz_polling_cycle; @@ -2376,11 +2491,11 @@ block_til_ready(struct tty_struct *tty, struct file *filp, static int cy_open(struct tty_struct *tty, struct file *filp) { struct cyclades_port *info; - unsigned int i, line; - int retval; + unsigned int i; + int retval, line; line = tty->index; - if ((tty->index < 0) || (NR_PORTS <= line)) { + if ((line < 0) || (NR_PORTS <= line)) { return -ENODEV; } for (i = 0; i < NR_CARDS; i++) @@ -2697,6 +2812,7 @@ static void cy_close(struct tty_struct *tty, struct file *filp) spin_lock_irqsave(&card->card_lock, flags); tty->closing = 0; + info->event = 0; info->tty = NULL; if (info->blocked_open) { spin_unlock_irqrestore(&card->card_lock, flags); @@ -4328,6 +4444,7 @@ static void cy_hangup(struct tty_struct *tty) cy_flush_buffer(tty); shutdown(info); + info->event = 0; info->count = 0; #ifdef CY_DEBUG_COUNT printk(KERN_DEBUG "cyc:cy_hangup (%d): setting count to 0\n", @@ -4350,9 +4467,9 @@ static int __devinit cy_init_card(struct cyclades_card *cinfo) { struct cyclades_port *info; u32 uninitialized_var(mailbox); - unsigned int nports, port; + unsigned int nports; unsigned short chip_number; - int uninitialized_var(index); + int uninitialized_var(index), port; spin_lock_init(&cinfo->card_lock); @@ -4385,6 +4502,7 @@ static int __devinit cy_init_card(struct cyclades_card *cinfo) info->closing_wait = CLOSING_WAIT_DELAY; info->close_delay = 5 * HZ / 10; + INIT_WORK(&info->tqueue, do_softint); init_waitqueue_head(&info->open_wait); init_waitqueue_head(&info->close_wait); init_completion(&info->shutdown_wait); @@ -5118,7 +5236,7 @@ static int __devinit cy_pci_probe(struct pci_dev *pdev, } } #endif /* CONFIG_CYZ_INTR */ - cy_card[card_no].num_chips = (unsigned int)-1; + cy_card[card_no].num_chips = -1; } /* set cy_card */ @@ -5362,13 +5480,13 @@ static int __init cy_init(void) #ifdef CONFIG_PCI /* look for pci boards */ retval = pci_register_driver(&cy_pci_driver); - if (retval && !nboards) { - tty_unregister_driver(cy_serial_driver); - goto err_frtty; - } + if (retval && !nboards) + goto err_unr; #endif return 0; +err_unr: + tty_unregister_driver(cy_serial_driver); err_frtty: put_tty_driver(cy_serial_driver); err: @@ -5378,7 +5496,7 @@ static int __init cy_init(void) static void __exit cy_cleanup_module(void) { struct cyclades_card *card; - unsigned int i, e1; + int i, e1; #ifndef CONFIG_CYZ_INTR del_timer_sync(&cyz_timerlist); @@ -5406,7 +5524,8 @@ static void __exit cy_cleanup_module(void) #endif /* CONFIG_CYZ_INTR */ ) free_irq(card->irq, card); - for (e1 = card->first_line; e1 < card->first_line + + for (e1 = card->first_line; + e1 < card->first_line + card->nports; e1++) tty_unregister_device(cy_serial_driver, e1); kfree(card->ports); diff --git a/trunk/drivers/char/drm/drm_bufs.c b/trunk/drivers/char/drm/drm_bufs.c index d24a6c2c2c24..856774fbe025 100644 --- a/trunk/drivers/char/drm/drm_bufs.c +++ b/trunk/drivers/char/drm/drm_bufs.c @@ -1456,7 +1456,7 @@ int drm_freebufs(struct drm_device *dev, void *data, buf = dma->buflist[idx]; if (buf->file_priv != file_priv) { DRM_ERROR("Process %d freeing buffer not owned\n", - task_pid_nr(current)); + current->pid); return -EINVAL; } drm_free_buffer(dev, buf); diff --git a/trunk/drivers/char/drm/drm_drv.c b/trunk/drivers/char/drm/drm_drv.c index 44a46268b02b..72668b15e5ce 100644 --- a/trunk/drivers/char/drm/drm_drv.c +++ b/trunk/drivers/char/drm/drm_drv.c @@ -463,7 +463,7 @@ int drm_ioctl(struct inode *inode, struct file *filp, ++file_priv->ioctl_count; DRM_DEBUG("pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n", - task_pid_nr(current), cmd, nr, + current->pid, cmd, nr, (long)old_encode_dev(file_priv->head->device), file_priv->authenticated); diff --git a/trunk/drivers/char/drm/drm_fops.c b/trunk/drivers/char/drm/drm_fops.c index 3992f73299cc..f383fc37190c 100644 --- a/trunk/drivers/char/drm/drm_fops.c +++ b/trunk/drivers/char/drm/drm_fops.c @@ -234,7 +234,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp, if (!drm_cpu_valid()) return -EINVAL; - DRM_DEBUG("pid = %d, minor = %d\n", task_pid_nr(current), minor); + DRM_DEBUG("pid = %d, minor = %d\n", current->pid, minor); priv = drm_alloc(sizeof(*priv), DRM_MEM_FILES); if (!priv) @@ -244,7 +244,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp, filp->private_data = priv; priv->filp = filp; priv->uid = current->euid; - priv->pid = task_pid_nr(current); + priv->pid = current->pid; priv->minor = minor; priv->head = drm_heads[minor]; priv->ioctl_count = 0; @@ -339,8 +339,7 @@ int drm_release(struct inode *inode, struct file *filp) */ DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n", - task_pid_nr(current), - (long)old_encode_dev(file_priv->head->device), + current->pid, (long)old_encode_dev(file_priv->head->device), dev->open_count); if (dev->driver->reclaim_buffers_locked && dev->lock.hw_lock) { diff --git a/trunk/drivers/char/drm/drm_lock.c b/trunk/drivers/char/drm/drm_lock.c index bea2a7d5b2b2..c6b73e744d67 100644 --- a/trunk/drivers/char/drm/drm_lock.c +++ b/trunk/drivers/char/drm/drm_lock.c @@ -58,12 +58,12 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv) if (lock->context == DRM_KERNEL_CONTEXT) { DRM_ERROR("Process %d using kernel context %d\n", - task_pid_nr(current), lock->context); + current->pid, lock->context); return -EINVAL; } DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n", - lock->context, task_pid_nr(current), + lock->context, current->pid, dev->lock.hw_lock->lock, lock->flags); if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE)) @@ -153,7 +153,7 @@ int drm_unlock(struct drm_device *dev, void *data, struct drm_file *file_priv) if (lock->context == DRM_KERNEL_CONTEXT) { DRM_ERROR("Process %d using kernel context %d\n", - task_pid_nr(current), lock->context); + current->pid, lock->context); return -EINVAL; } diff --git a/trunk/drivers/char/drm/drm_os_linux.h b/trunk/drivers/char/drm/drm_os_linux.h index 76e44ac94fb5..114e54e0f61b 100644 --- a/trunk/drivers/char/drm/drm_os_linux.h +++ b/trunk/drivers/char/drm/drm_os_linux.h @@ -7,7 +7,7 @@ #include /** Current process ID */ -#define DRM_CURRENTPID task_pid_nr(current) +#define DRM_CURRENTPID current->pid #define DRM_SUSER(p) capable(CAP_SYS_ADMIN) #define DRM_UDELAY(d) udelay(d) /** Read a byte from a MMIO region */ diff --git a/trunk/drivers/char/drm/i810_dma.c b/trunk/drivers/char/drm/i810_dma.c index eb381a7c5bee..8e841bdee6dc 100644 --- a/trunk/drivers/char/drm/i810_dma.c +++ b/trunk/drivers/char/drm/i810_dma.c @@ -1024,7 +1024,7 @@ static int i810_getbuf(struct drm_device *dev, void *data, retcode = i810_dma_get_buffer(dev, d, file_priv); DRM_DEBUG("i810_dma: %d returning %d, granted = %d\n", - task_pid_nr(current), retcode, d->granted); + current->pid, retcode, d->granted); sarea_priv->last_dispatch = (int)hw_status[5]; diff --git a/trunk/drivers/char/drm/i830_dma.c b/trunk/drivers/char/drm/i830_dma.c index 69a363edb0d2..43a1f78712d6 100644 --- a/trunk/drivers/char/drm/i830_dma.c +++ b/trunk/drivers/char/drm/i830_dma.c @@ -1409,7 +1409,7 @@ static int i830_getbuf(struct drm_device *dev, void *data, retcode = i830_dma_get_buffer(dev, d, file_priv); DRM_DEBUG("i830_dma: %d returning %d, granted = %d\n", - task_pid_nr(current), retcode, d->granted); + current->pid, retcode, d->granted); sarea_priv->last_dispatch = (int)hw_status[5]; diff --git a/trunk/drivers/char/esp.c b/trunk/drivers/char/esp.c index 0f8fb135da53..2e7ae42a5503 100644 --- a/trunk/drivers/char/esp.c +++ b/trunk/drivers/char/esp.c @@ -58,10 +58,10 @@ #include #include #include -#include #include #include +#include #include #include diff --git a/trunk/drivers/char/ipmi/ipmi_msghandler.c b/trunk/drivers/char/ipmi/ipmi_msghandler.c index 5dc1265ce1d5..8435fba73daf 100644 --- a/trunk/drivers/char/ipmi/ipmi_msghandler.c +++ b/trunk/drivers/char/ipmi/ipmi_msghandler.c @@ -221,8 +221,10 @@ struct ipmi_smi void *send_info; #ifdef CONFIG_PROC_FS - /* A list of proc entries for this interface. */ - struct mutex proc_entry_lock; + /* A list of proc entries for this interface. This does not + need a lock, only one thread creates it and only one thread + destroys it. */ + spinlock_t proc_entry_lock; struct ipmi_proc_entry *proc_entries; #endif @@ -1889,11 +1891,11 @@ int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name, file->write_proc = write_proc; file->owner = owner; - mutex_lock(&smi->proc_entry_lock); + spin_lock(&smi->proc_entry_lock); /* Stick it on the list. */ entry->next = smi->proc_entries; smi->proc_entries = entry; - mutex_unlock(&smi->proc_entry_lock); + spin_unlock(&smi->proc_entry_lock); } #endif /* CONFIG_PROC_FS */ @@ -1937,7 +1939,7 @@ static void remove_proc_entries(ipmi_smi_t smi) #ifdef CONFIG_PROC_FS struct ipmi_proc_entry *entry; - mutex_lock(&smi->proc_entry_lock); + spin_lock(&smi->proc_entry_lock); while (smi->proc_entries) { entry = smi->proc_entries; smi->proc_entries = entry->next; @@ -1946,7 +1948,7 @@ static void remove_proc_entries(ipmi_smi_t smi) kfree(entry->name); kfree(entry); } - mutex_unlock(&smi->proc_entry_lock); + spin_unlock(&smi->proc_entry_lock); remove_proc_entry(smi->proc_dir_name, proc_ipmi_root); #endif /* CONFIG_PROC_FS */ } @@ -2612,14 +2614,6 @@ channel_handler(ipmi_smi_t intf, struct ipmi_recv_msg *msg) return; } -void ipmi_poll_interface(ipmi_user_t user) -{ - ipmi_smi_t intf = user->intf; - - if (intf->handlers->poll) - intf->handlers->poll(intf->send_info); -} - int ipmi_register_smi(struct ipmi_smi_handlers *handlers, void *send_info, struct ipmi_device_id *device_id, @@ -2677,7 +2671,7 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers, } intf->curr_seq = 0; #ifdef CONFIG_PROC_FS - mutex_init(&intf->proc_entry_lock); + spin_lock_init(&intf->proc_entry_lock); #endif spin_lock_init(&intf->waiting_msgs_lock); INIT_LIST_HEAD(&intf->waiting_msgs); @@ -4172,7 +4166,6 @@ EXPORT_SYMBOL(ipmi_destroy_user); EXPORT_SYMBOL(ipmi_get_version); EXPORT_SYMBOL(ipmi_request_settime); EXPORT_SYMBOL(ipmi_request_supply_msgs); -EXPORT_SYMBOL(ipmi_poll_interface); EXPORT_SYMBOL(ipmi_register_smi); EXPORT_SYMBOL(ipmi_unregister_smi); EXPORT_SYMBOL(ipmi_register_for_cmd); diff --git a/trunk/drivers/char/ipmi/ipmi_si_intf.c b/trunk/drivers/char/ipmi/ipmi_si_intf.c index 4f560d0bb808..c1222e98525d 100644 --- a/trunk/drivers/char/ipmi/ipmi_si_intf.c +++ b/trunk/drivers/char/ipmi/ipmi_si_intf.c @@ -675,8 +675,7 @@ static void handle_transaction_done(struct smi_info *smi_info) } /* Called on timeouts and events. Timeouts should pass the elapsed - time, interrupts should pass in zero. Must be called with - si_lock held and interrupts disabled. */ + time, interrupts should pass in zero. */ static enum si_sm_result smi_event_handler(struct smi_info *smi_info, int time) { @@ -893,16 +892,13 @@ static int ipmi_thread(void *data) static void poll(void *send_info) { struct smi_info *smi_info = send_info; - unsigned long flags; /* * Make sure there is some delay in the poll loop so we can * drive time forward and timeout things. */ udelay(10); - spin_lock_irqsave(&smi_info->si_lock, flags); smi_event_handler(smi_info, 10); - spin_unlock_irqrestore(&smi_info->si_lock, flags); } static void request_events(void *send_info) @@ -1010,10 +1006,6 @@ static int smi_start_processing(void *send_info, new_smi->intf = intf; - /* Try to claim any interrupts. */ - if (new_smi->irq_setup) - new_smi->irq_setup(new_smi); - /* Set up the timer that drives the interface. */ setup_timer(&new_smi->si_timer, smi_timeout, (long)new_smi); new_smi->last_timeout_jiffies = jiffies; @@ -2380,9 +2372,20 @@ static int try_get_dev_id(struct smi_info *smi_info) /* Otherwise, we got some data. */ resp_len = smi_info->handlers->get_result(smi_info->si_sm, resp, IPMI_MAX_MSG_LENGTH); + if (resp_len < 14) { + /* That's odd, it should be longer. */ + rv = -EINVAL; + goto out; + } - /* Check and record info from the get device id, in case we need it. */ - rv = ipmi_demangle_device_id(resp, resp_len, &smi_info->device_id); + if ((resp[1] != IPMI_GET_DEVICE_ID_CMD) || (resp[2] != 0)) { + /* That's odd, it shouldn't be able to fail. */ + rv = -EINVAL; + goto out; + } + + /* Record info from the get device id, in case we need it. */ + ipmi_demangle_device_id(resp+3, resp_len-3, &smi_info->device_id); out: kfree(resp); @@ -2762,6 +2765,10 @@ static int try_smi_init(struct smi_info *new_smi) setup_oem_data_handler(new_smi); setup_xaction_handlers(new_smi); + /* Try to claim any interrupts. */ + if (new_smi->irq_setup) + new_smi->irq_setup(new_smi); + INIT_LIST_HEAD(&(new_smi->xmit_msgs)); INIT_LIST_HEAD(&(new_smi->hp_xmit_msgs)); new_smi->curr_msg = NULL; diff --git a/trunk/drivers/char/ipmi/ipmi_watchdog.c b/trunk/drivers/char/ipmi/ipmi_watchdog.c index e686fc925168..41f78e2c158f 100644 --- a/trunk/drivers/char/ipmi/ipmi_watchdog.c +++ b/trunk/drivers/char/ipmi/ipmi_watchdog.c @@ -50,19 +50,10 @@ #include #include #include -#include #include -#ifdef CONFIG_X86 -/* This is ugly, but I've determined that x86 is the only architecture - that can reasonably support the IPMI NMI watchdog timeout at this - time. If another architecture adds this capability somehow, it - will have to be a somewhat different mechanism and I have no idea - how it will work. So in the unlikely event that another - architecture supports this, we can figure out a good generic - mechanism for it at that time. */ -#include -#define HAVE_DIE_NMI +#ifdef CONFIG_X86_LOCAL_APIC +#include #endif #define PFX "IPMI Watchdog: " @@ -175,6 +166,8 @@ static char expect_close; static int ifnum_to_use = -1; +static DECLARE_RWSEM(register_sem); + /* Parameters to ipmi_set_timeout */ #define IPMI_SET_TIMEOUT_NO_HB 0 #define IPMI_SET_TIMEOUT_HB_IF_NECESSARY 1 @@ -200,9 +193,11 @@ static int set_param_int(const char *val, struct kernel_param *kp) if (endp == val) return -EINVAL; + down_read(®ister_sem); *((int *)kp->arg) = l; if (watchdog_user) rv = ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY); + up_read(®ister_sem); return rv; } @@ -231,15 +226,17 @@ static int set_param_str(const char *val, struct kernel_param *kp) s = strstrip(valcp); + down_read(®ister_sem); rv = fn(s, NULL); if (rv) - goto out; + goto out_unlock; check_parms(); if (watchdog_user) rv = ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY); - out: + out_unlock: + up_read(®ister_sem); return rv; } @@ -322,12 +319,9 @@ static unsigned char ipmi_version_minor; /* If a pretimeout occurs, this is used to allow only one panic to happen. */ static atomic_t preop_panic_excl = ATOMIC_INIT(-1); -#ifdef HAVE_DIE_NMI -static int testing_nmi; -static int nmi_handler_registered; -#endif - static int ipmi_heartbeat(void); +static void panic_halt_ipmi_heartbeat(void); + /* We use a mutex to make sure that only one thing can send a set timeout at one time, because we only have one copy of the data. @@ -366,9 +360,6 @@ static int i_ipmi_set_timeout(struct ipmi_smi_msg *smi_msg, int hbnow = 0; - /* These can be cleared as we are setting the timeout. */ - pretimeout_since_last_heartbeat = 0; - data[0] = 0; WDOG_SET_TIMER_USE(data[0], WDOG_TIMER_USE_SMS_OS); @@ -443,75 +434,31 @@ static int ipmi_set_timeout(int do_heartbeat) wait_for_completion(&set_timeout_wait); - mutex_unlock(&set_timeout_lock); - if ((do_heartbeat == IPMI_SET_TIMEOUT_FORCE_HB) || ((send_heartbeat_now) && (do_heartbeat == IPMI_SET_TIMEOUT_HB_IF_NECESSARY))) + { rv = ipmi_heartbeat(); + } + mutex_unlock(&set_timeout_lock); out: return rv; } -static atomic_t panic_done_count = ATOMIC_INIT(0); - -static void panic_smi_free(struct ipmi_smi_msg *msg) +static void dummy_smi_free(struct ipmi_smi_msg *msg) { - atomic_dec(&panic_done_count); } -static void panic_recv_free(struct ipmi_recv_msg *msg) +static void dummy_recv_free(struct ipmi_recv_msg *msg) { - atomic_dec(&panic_done_count); -} - -static struct ipmi_smi_msg panic_halt_heartbeat_smi_msg = -{ - .done = panic_smi_free -}; -static struct ipmi_recv_msg panic_halt_heartbeat_recv_msg = -{ - .done = panic_recv_free -}; - -static void panic_halt_ipmi_heartbeat(void) -{ - struct kernel_ipmi_msg msg; - struct ipmi_system_interface_addr addr; - int rv; - - /* Don't reset the timer if we have the timer turned off, that - re-enables the watchdog. */ - if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) - return; - - addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; - addr.channel = IPMI_BMC_CHANNEL; - addr.lun = 0; - - msg.netfn = 0x06; - msg.cmd = IPMI_WDOG_RESET_TIMER; - msg.data = NULL; - msg.data_len = 0; - rv = ipmi_request_supply_msgs(watchdog_user, - (struct ipmi_addr *) &addr, - 0, - &msg, - NULL, - &panic_halt_heartbeat_smi_msg, - &panic_halt_heartbeat_recv_msg, - 1); - if (!rv) - atomic_add(2, &panic_done_count); } - static struct ipmi_smi_msg panic_halt_smi_msg = { - .done = panic_smi_free + .done = dummy_smi_free }; static struct ipmi_recv_msg panic_halt_recv_msg = { - .done = panic_recv_free + .done = dummy_recv_free }; /* Special call, doesn't claim any locks. This is only to be called @@ -523,21 +470,13 @@ static void panic_halt_ipmi_set_timeout(void) int send_heartbeat_now; int rv; - /* Wait for the messages to be free. */ - while (atomic_read(&panic_done_count) != 0) - ipmi_poll_interface(watchdog_user); rv = i_ipmi_set_timeout(&panic_halt_smi_msg, &panic_halt_recv_msg, &send_heartbeat_now); if (!rv) { - atomic_add(2, &panic_done_count); if (send_heartbeat_now) panic_halt_ipmi_heartbeat(); - } else - printk(KERN_WARNING PFX - "Unable to extend the watchdog timeout."); - while (atomic_read(&panic_done_count) != 0) - ipmi_poll_interface(watchdog_user); + } } /* We use a semaphore to make sure that only one thing can send a @@ -566,14 +505,24 @@ static struct ipmi_recv_msg heartbeat_recv_msg = .done = heartbeat_free_recv }; +static struct ipmi_smi_msg panic_halt_heartbeat_smi_msg = +{ + .done = dummy_smi_free +}; +static struct ipmi_recv_msg panic_halt_heartbeat_recv_msg = +{ + .done = dummy_recv_free +}; + static int ipmi_heartbeat(void) { struct kernel_ipmi_msg msg; int rv; struct ipmi_system_interface_addr addr; - if (ipmi_ignore_heartbeat) + if (ipmi_ignore_heartbeat) { return 0; + } if (ipmi_start_timer_on_heartbeat) { ipmi_start_timer_on_heartbeat = 0; @@ -584,6 +533,7 @@ static int ipmi_heartbeat(void) We don't want to set the action, though, we want to leave that alone (thus it can't be combined with the above operation. */ + pretimeout_since_last_heartbeat = 0; return ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY); } @@ -636,6 +586,35 @@ static int ipmi_heartbeat(void) return rv; } +static void panic_halt_ipmi_heartbeat(void) +{ + struct kernel_ipmi_msg msg; + struct ipmi_system_interface_addr addr; + + + /* Don't reset the timer if we have the timer turned off, that + re-enables the watchdog. */ + if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) + return; + + addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; + addr.channel = IPMI_BMC_CHANNEL; + addr.lun = 0; + + msg.netfn = 0x06; + msg.cmd = IPMI_WDOG_RESET_TIMER; + msg.data = NULL; + msg.data_len = 0; + ipmi_request_supply_msgs(watchdog_user, + (struct ipmi_addr *) &addr, + 0, + &msg, + NULL, + &panic_halt_heartbeat_smi_msg, + &panic_halt_heartbeat_recv_msg, + 1); +} + static struct watchdog_info ident = { .options = 0, /* WDIOF_SETTIMEOUT, */ @@ -916,6 +895,7 @@ static void ipmi_register_watchdog(int ipmi_intf) { int rv = -EBUSY; + down_write(®ister_sem); if (watchdog_user) goto out; @@ -941,56 +921,15 @@ static void ipmi_register_watchdog(int ipmi_intf) printk(KERN_CRIT PFX "Unable to register misc device\n"); } -#ifdef HAVE_DIE_NMI - if (nmi_handler_registered) { - int old_pretimeout = pretimeout; - int old_timeout = timeout; - int old_preop_val = preop_val; - - /* Set the pretimeout to go off in a second and give - ourselves plenty of time to stop the timer. */ - ipmi_watchdog_state = WDOG_TIMEOUT_RESET; - preop_val = WDOG_PREOP_NONE; /* Make sure nothing happens */ - pretimeout = 99; - timeout = 100; - - testing_nmi = 1; - - rv = ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB); - if (rv) { - printk(KERN_WARNING PFX "Error starting timer to" - " test NMI: 0x%x. The NMI pretimeout will" - " likely not work\n", rv); - rv = 0; - goto out_restore; - } - - msleep(1500); - - if (testing_nmi != 2) { - printk(KERN_WARNING PFX "IPMI NMI didn't seem to" - " occur. The NMI pretimeout will" - " likely not work\n"); - } - out_restore: - testing_nmi = 0; - preop_val = old_preop_val; - pretimeout = old_pretimeout; - timeout = old_timeout; - } -#endif - out: + up_write(®ister_sem); + if ((start_now) && (rv == 0)) { /* Run from startup, so start the timer now. */ start_now = 0; /* Disable this function after first startup. */ ipmi_watchdog_state = action_val; ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB); printk(KERN_INFO PFX "Starting now!\n"); - } else { - /* Stop the timer now. */ - ipmi_watchdog_state = WDOG_TIMEOUT_NONE; - ipmi_set_timeout(IPMI_SET_TIMEOUT_NO_HB); } } @@ -998,6 +937,8 @@ static void ipmi_unregister_watchdog(int ipmi_intf) { int rv; + down_write(®ister_sem); + if (!watchdog_user) goto out; @@ -1022,44 +963,20 @@ static void ipmi_unregister_watchdog(int ipmi_intf) watchdog_user = NULL; out: - return; + up_write(®ister_sem); } -#ifdef HAVE_DIE_NMI +#ifdef HAVE_NMI_HANDLER static int -ipmi_nmi(struct notifier_block *self, unsigned long val, void *data) +ipmi_nmi(void *dev_id, int cpu, int handled) { - struct die_args *args = data; - - if (val != DIE_NMI) - return NOTIFY_OK; - - /* Hack, if it's a memory or I/O error, ignore it. */ - if (args->err & 0xc0) - return NOTIFY_OK; - - /* - * If we get here, it's an NMI that's not a memory or I/O - * error. We can't truly tell if it's from IPMI or not - * without sending a message, and sending a message is almost - * impossible because of locking. - */ - - if (testing_nmi) { - testing_nmi = 2; - return NOTIFY_STOP; - } - /* If we are not expecting a timeout, ignore it. */ if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) - return NOTIFY_OK; - - if (preaction_val != WDOG_PRETIMEOUT_NMI) - return NOTIFY_OK; + return NOTIFY_DONE; /* If no one else handled the NMI, we assume it was the IPMI watchdog. */ - if (preop_val == WDOG_PREOP_PANIC) { + if ((!handled) && (preop_val == WDOG_PREOP_PANIC)) { /* On some machines, the heartbeat will give an error and not work unless we re-enable the timer. So do so. */ @@ -1068,12 +985,18 @@ ipmi_nmi(struct notifier_block *self, unsigned long val, void *data) panic(PFX "pre-timeout"); } - return NOTIFY_STOP; + return NOTIFY_DONE; } -static struct notifier_block ipmi_nmi_handler = { - .notifier_call = ipmi_nmi +static struct nmi_handler ipmi_nmi_handler = +{ + .link = LIST_HEAD_INIT(ipmi_nmi_handler.link), + .dev_name = "ipmi_watchdog", + .dev_id = NULL, + .handler = ipmi_nmi, + .priority = 0, /* Call us last. */ }; +int nmi_handler_registered; #endif static int wdog_reboot_handler(struct notifier_block *this, @@ -1086,7 +1009,7 @@ static int wdog_reboot_handler(struct notifier_block *this, /* Make sure we only do this once. */ reboot_event_handled = 1; - if (code == SYS_POWER_OFF || code == SYS_HALT) { + if (code == SYS_DOWN || code == SYS_HALT) { /* Disable the WDT if we are shutting down. */ ipmi_watchdog_state = WDOG_TIMEOUT_NONE; panic_halt_ipmi_set_timeout(); @@ -1190,7 +1113,7 @@ static int preaction_op(const char *inval, char *outval) preaction_val = WDOG_PRETIMEOUT_NONE; else if (strcmp(inval, "pre_smi") == 0) preaction_val = WDOG_PRETIMEOUT_SMI; -#ifdef HAVE_DIE_NMI +#ifdef HAVE_NMI_HANDLER else if (strcmp(inval, "pre_nmi") == 0) preaction_val = WDOG_PRETIMEOUT_NMI; #endif @@ -1224,7 +1147,7 @@ static int preop_op(const char *inval, char *outval) static void check_parms(void) { -#ifdef HAVE_DIE_NMI +#ifdef HAVE_NMI_HANDLER int do_nmi = 0; int rv; @@ -1237,9 +1160,20 @@ static void check_parms(void) preop_op("preop_none", NULL); do_nmi = 0; } +#ifdef CONFIG_X86_LOCAL_APIC + if (nmi_watchdog == NMI_IO_APIC) { + printk(KERN_WARNING PFX "nmi_watchdog is set to IO APIC" + " mode (value is %d), that is incompatible" + " with using NMI in the IPMI watchdog." + " Disabling IPMI nmi pretimeout.\n", + nmi_watchdog); + preaction_val = WDOG_PRETIMEOUT_NONE; + do_nmi = 0; + } +#endif } if (do_nmi && !nmi_handler_registered) { - rv = register_die_notifier(&ipmi_nmi_handler); + rv = request_nmi(&ipmi_nmi_handler); if (rv) { printk(KERN_WARNING PFX "Can't register nmi handler\n"); @@ -1247,7 +1181,7 @@ static void check_parms(void) } else nmi_handler_registered = 1; } else if (!do_nmi && nmi_handler_registered) { - unregister_die_notifier(&ipmi_nmi_handler); + release_nmi(&ipmi_nmi_handler); nmi_handler_registered = 0; } #endif @@ -1283,9 +1217,9 @@ static int __init ipmi_wdog_init(void) rv = ipmi_smi_watcher_register(&smi_watcher); if (rv) { -#ifdef HAVE_DIE_NMI - if (nmi_handler_registered) - unregister_die_notifier(&ipmi_nmi_handler); +#ifdef HAVE_NMI_HANDLER + if (preaction_val == WDOG_PRETIMEOUT_NMI) + release_nmi(&ipmi_nmi_handler); #endif atomic_notifier_chain_unregister(&panic_notifier_list, &wdog_panic_notifier); @@ -1304,9 +1238,9 @@ static void __exit ipmi_wdog_exit(void) ipmi_smi_watcher_unregister(&smi_watcher); ipmi_unregister_watchdog(watchdog_ifnum); -#ifdef HAVE_DIE_NMI +#ifdef HAVE_NMI_HANDLER if (nmi_handler_registered) - unregister_die_notifier(&ipmi_nmi_handler); + release_nmi(&ipmi_nmi_handler); #endif atomic_notifier_chain_unregister(&panic_notifier_list, diff --git a/trunk/drivers/char/isicom.c b/trunk/drivers/char/isicom.c index 85d596a3c18c..77a7a4a06620 100644 --- a/trunk/drivers/char/isicom.c +++ b/trunk/drivers/char/isicom.c @@ -1529,7 +1529,7 @@ static int __devinit reset_card(struct pci_dev *pdev, portcount = inw(base + 0x2); if (!inw(base + 0xe) & 0x1 || (portcount != 0 && portcount != 4 && portcount != 8 && portcount != 16)) { - dev_err(&pdev->dev, "ISILoad:PCI Card%d reset failure.\n", + dev_err(&pdev->dev, "ISILoad:PCI Card%d reset failure.", card + 1); retval = -EIO; goto end; @@ -1622,9 +1622,7 @@ static int __devinit load_firmware(struct pci_dev *pdev, if ((status = inw(base + 0x4)) != 0) { dev_warn(&pdev->dev, "Card%d rejected load header:\n" - KERN_WARNING "Address:0x%x\n" - KERN_WARNING "Count:0x%x\n" - KERN_WARNING "Status:0x%x\n", + "Address:0x%x\nCount:0x%x\nStatus:0x%x\n", index + 1, frame->addr, frame->count, status); goto errrelfw; } @@ -1668,9 +1666,7 @@ static int __devinit load_firmware(struct pci_dev *pdev, if ((status = inw(base + 0x4)) != 0) { dev_warn(&pdev->dev, "Card%d rejected verify header:\n" - KERN_WARNING "Address:0x%x\n" - KERN_WARNING "Count:0x%x\n" - KERN_WARNING "Status: 0x%x\n", + "Address:0x%x\nCount:0x%x\nStatus: 0x%x\n", index + 1, frame->addr, frame->count, status); goto errrelfw; } diff --git a/trunk/drivers/char/keyboard.c b/trunk/drivers/char/keyboard.c index fc54d234507a..212276affa1f 100644 --- a/trunk/drivers/char/keyboard.c +++ b/trunk/drivers/char/keyboard.c @@ -42,7 +42,6 @@ #include #include #include -#include extern void ctrl_alt_del(void); @@ -82,8 +81,7 @@ void compute_shiftstate(void); typedef void (k_handler_fn)(struct vc_data *vc, unsigned char value, char up_flag); static k_handler_fn K_HANDLERS; -k_handler_fn *k_handler[16] = { K_HANDLERS }; -EXPORT_SYMBOL_GPL(k_handler); +static k_handler_fn *k_handler[16] = { K_HANDLERS }; #define FN_HANDLERS\ fn_null, fn_enter, fn_show_ptregs, fn_show_mem,\ @@ -129,7 +127,7 @@ int shift_state = 0; */ static struct input_handler kbd_handler; -static unsigned long key_down[BITS_TO_LONGS(KEY_CNT)]; /* keyboard key bitmap */ +static unsigned long key_down[NBITS(KEY_MAX)]; /* keyboard key bitmap */ static unsigned char shift_down[NR_SHIFT]; /* shift state counters.. */ static int dead_key_next; static int npadch = -1; /* -1 or number assembled on pad */ @@ -161,23 +159,6 @@ static int sysrq_alt_use; #endif static int sysrq_alt; -/* - * Notifier list for console keyboard events - */ -static ATOMIC_NOTIFIER_HEAD(keyboard_notifier_list); - -int register_keyboard_notifier(struct notifier_block *nb) -{ - return atomic_notifier_chain_register(&keyboard_notifier_list, nb); -} -EXPORT_SYMBOL_GPL(register_keyboard_notifier); - -int unregister_keyboard_notifier(struct notifier_block *nb) -{ - return atomic_notifier_chain_unregister(&keyboard_notifier_list, nb); -} -EXPORT_SYMBOL_GPL(unregister_keyboard_notifier); - /* * Translation of scancodes to keycodes. We set them on only the first * keyboard in the list that accepts the scancode and keycode. @@ -1149,7 +1130,6 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) unsigned char type, raw_mode; struct tty_struct *tty; int shift_final; - struct keyboard_notifier_param param = { .vc = vc, .value = keycode, .down = down }; tty = vc->vc_tty; @@ -1237,11 +1217,10 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) return; } - param.shift = shift_final = (shift_state | kbd->slockstate) ^ kbd->lockstate; + shift_final = (shift_state | kbd->slockstate) ^ kbd->lockstate; key_map = key_maps[shift_final]; - if (atomic_notifier_call_chain(&keyboard_notifier_list, KBD_KEYCODE, ¶m) == NOTIFY_STOP || !key_map) { - atomic_notifier_call_chain(&keyboard_notifier_list, KBD_UNBOUND_KEYCODE, ¶m); + if (!key_map) { compute_shiftstate(); kbd->slockstate = 0; return; @@ -1258,9 +1237,6 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) type = KTYP(keysym); if (type < 0xf0) { - param.value = keysym; - if (atomic_notifier_call_chain(&keyboard_notifier_list, KBD_UNICODE, ¶m) == NOTIFY_STOP) - return; if (down && !raw_mode) to_utf8(vc, keysym); return; @@ -1268,6 +1244,9 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) type -= 0xf0; + if (raw_mode && type != KT_SPEC && type != KT_SHIFT) + return; + if (type == KT_LETTER) { type = KT_LATIN; if (vc_kbd_led(kbd, VC_CAPSLOCK)) { @@ -1276,18 +1255,9 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) keysym = key_map[keycode]; } } - param.value = keysym; - - if (atomic_notifier_call_chain(&keyboard_notifier_list, KBD_KEYSYM, ¶m) == NOTIFY_STOP) - return; - - if (raw_mode && type != KT_SPEC && type != KT_SHIFT) - return; (*k_handler[type])(vc, keysym & 0xff, !down); - atomic_notifier_call_chain(&keyboard_notifier_list, KBD_POST_KEYSYM, ¶m); - if (type != KT_SLOCK) kbd->slockstate = 0; } @@ -1377,12 +1347,12 @@ static void kbd_start(struct input_handle *handle) static const struct input_device_id kbd_ids[] = { { .flags = INPUT_DEVICE_ID_MATCH_EVBIT, - .evbit = { BIT_MASK(EV_KEY) }, + .evbit = { BIT(EV_KEY) }, }, { .flags = INPUT_DEVICE_ID_MATCH_EVBIT, - .evbit = { BIT_MASK(EV_SND) }, + .evbit = { BIT(EV_SND) }, }, { }, /* Terminating entry */ diff --git a/trunk/drivers/char/moxa.c b/trunk/drivers/char/moxa.c index 2fc255a21486..ed76f0a127fd 100644 --- a/trunk/drivers/char/moxa.c +++ b/trunk/drivers/char/moxa.c @@ -41,7 +41,6 @@ #include #include #include -#include #include #include @@ -143,7 +142,7 @@ struct moxa_port { struct tty_struct *tty; int cflag; wait_queue_head_t open_wait; - struct completion close_wait; + wait_queue_head_t close_wait; struct timer_list emptyTimer; @@ -167,6 +166,7 @@ struct moxa_port { #define WAKEUP_CHARS 256 +static int verbose = 0; static int ttymajor = MOXAMAJOR; /* Variables for insmod */ #ifdef MODULE @@ -184,6 +184,7 @@ module_param_array(baseaddr, int, NULL, 0); module_param_array(numports, int, NULL, 0); #endif module_param(ttymajor, int, 0); +module_param(verbose, bool, 0644); /* * static functions: @@ -207,13 +208,13 @@ static int moxa_tiocmget(struct tty_struct *tty, struct file *file); static int moxa_tiocmset(struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear); static void moxa_poll(unsigned long); -static void moxa_set_tty_param(struct tty_struct *); -static int moxa_block_till_ready(struct tty_struct *, struct file *, +static void set_tty_param(struct tty_struct *); +static int block_till_ready(struct tty_struct *, struct file *, struct moxa_port *); -static void moxa_setup_empty_event(struct tty_struct *); -static void moxa_check_xmit_empty(unsigned long); -static void moxa_shut_down(struct moxa_port *); -static void moxa_receive_data(struct moxa_port *); +static void setup_empty_event(struct tty_struct *); +static void check_xmit_empty(unsigned long); +static void shut_down(struct moxa_port *); +static void receive_data(struct moxa_port *); /* * moxa board interface functions: */ @@ -282,10 +283,8 @@ static int __devinit moxa_pci_probe(struct pci_dev *pdev, int retval; retval = pci_enable_device(pdev); - if (retval) { - dev_err(&pdev->dev, "can't enable pci device\n"); + if (retval) goto err; - } for (i = 0; i < MAX_BOARDS; i++) if (moxa_boards[i].basemem == NULL) @@ -293,17 +292,16 @@ static int __devinit moxa_pci_probe(struct pci_dev *pdev, retval = -ENODEV; if (i >= MAX_BOARDS) { - dev_warn(&pdev->dev, "more than %u MOXA Intellio family boards " + if (verbose) + printk("More than %d MOXA Intellio family boards " "found. Board is ignored.\n", MAX_BOARDS); goto err; } board = &moxa_boards[i]; board->basemem = pci_iomap(pdev, 2, 0x4000); - if (board->basemem == NULL) { - dev_err(&pdev->dev, "can't remap io space 2\n"); + if (board->basemem == NULL) goto err; - } board->boardType = board_type; switch (board_type) { @@ -349,8 +347,7 @@ static int __init moxa_init(void) int i, numBoards, retval = 0; struct moxa_port *ch; - printk(KERN_INFO "MOXA Intellio family driver version %s\n", - MOXA_VERSION); + printk(KERN_INFO "MOXA Intellio family driver version %s\n", MOXA_VERSION); moxaDriver = alloc_tty_driver(MAX_PORTS + 1); if (!moxaDriver) return -ENOMEM; @@ -375,13 +372,13 @@ static int __init moxa_init(void) ch->closing_wait = 30 * HZ; ch->cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL; init_waitqueue_head(&ch->open_wait); - init_completion(&ch->close_wait); + init_waitqueue_head(&ch->close_wait); - setup_timer(&ch->emptyTimer, moxa_check_xmit_empty, + setup_timer(&ch->emptyTimer, check_xmit_empty, (unsigned long)ch); } - pr_debug("Moxa tty devices major number = %d\n", ttymajor); + printk("Tty devices major number = %d\n", ttymajor); if (tty_register_driver(moxaDriver)) { printk(KERN_ERR "Couldn't install MOXA Smartio family driver !\n"); @@ -403,10 +400,11 @@ static int __init moxa_init(void) moxa_boards[numBoards].numPorts = moxa_isa_boards[i].numPorts; moxa_boards[numBoards].busType = MOXA_BUS_TYPE_ISA; moxa_boards[numBoards].baseAddr = moxa_isa_boards[i].baseAddr; - pr_debug("Moxa board %2d: %s board(baseAddr=%lx)\n", - numBoards + 1, - moxa_brdname[moxa_boards[numBoards].boardType-1], - moxa_boards[numBoards].baseAddr); + if (verbose) + printk("Board %2d: %s board(baseAddr=%lx)\n", + numBoards + 1, + moxa_brdname[moxa_boards[numBoards].boardType - 1], + moxa_boards[numBoards].baseAddr); numBoards++; } } @@ -415,13 +413,14 @@ static int __init moxa_init(void) for (i = 0; i < MAX_BOARDS; i++) { if ((type[i] == MOXA_BOARD_C218_ISA) || (type[i] == MOXA_BOARD_C320_ISA)) { - pr_debug("Moxa board %2d: %s board(baseAddr=%lx)\n", - numBoards + 1, moxa_brdname[type[i] - 1], - (unsigned long)baseaddr[i]); + if (verbose) + printk("Board %2d: %s board(baseAddr=%lx)\n", + numBoards + 1, + moxa_brdname[type[i] - 1], + (unsigned long) baseaddr[i]); if (numBoards >= MAX_BOARDS) { - printk(KERN_WARNING "More than %d MOXA " - "Intellio family boards found. Board " - "is ignored.\n", MAX_BOARDS); + if (verbose) + printk("More than %d MOXA Intellio family boards found. Board is ignored.", MAX_BOARDS); continue; } moxa_boards[numBoards].boardType = type[i]; @@ -457,14 +456,16 @@ static void __exit moxa_exit(void) { int i; + if (verbose) + printk("Unloading module moxa ...\n"); + del_timer_sync(&moxaTimer); for (i = 0; i < MAX_PORTS; i++) del_timer_sync(&moxa_ports[i].emptyTimer); if (tty_unregister_driver(moxaDriver)) - printk(KERN_ERR "Couldn't unregister MOXA Intellio family " - "serial driver\n"); + printk("Couldn't unregister MOXA Intellio family serial driver\n"); put_tty_driver(moxaDriver); #ifdef CONFIG_PCI @@ -474,6 +475,9 @@ static void __exit moxa_exit(void) for (i = 0; i < MAX_BOARDS; i++) if (moxa_boards[i].basemem) iounmap(moxa_boards[i].basemem); + + if (verbose) + printk("Done\n"); } module_init(moxa_init); @@ -500,12 +504,12 @@ static int moxa_open(struct tty_struct *tty, struct file *filp) ch->tty = tty; if (!(ch->asyncflags & ASYNC_INITIALIZED)) { ch->statusflags = 0; - moxa_set_tty_param(tty); + set_tty_param(tty); MoxaPortLineCtrl(ch->port, 1, 1); MoxaPortEnable(ch->port); ch->asyncflags |= ASYNC_INITIALIZED; } - retval = moxa_block_till_ready(tty, filp, ch); + retval = block_till_ready(tty, filp, ch); moxa_unthrottle(tty); @@ -528,7 +532,9 @@ static void moxa_close(struct tty_struct *tty, struct file *filp) return; } if (!MoxaPortIsValid(port)) { - pr_debug("Invalid portno in moxa_close\n"); +#ifdef SERIAL_DEBUG_CLOSE + printk("Invalid portno in moxa_close\n"); +#endif tty->driver_data = NULL; return; } @@ -541,13 +547,13 @@ static void moxa_close(struct tty_struct *tty, struct file *filp) ch = (struct moxa_port *) tty->driver_data; if ((tty->count == 1) && (ch->count != 1)) { - printk(KERN_WARNING "moxa_close: bad serial port count; " - "tty->count is 1, ch->count is %d\n", ch->count); + printk("moxa_close: bad serial port count; tty->count is 1, " + "ch->count is %d\n", ch->count); ch->count = 1; } if (--ch->count < 0) { - printk(KERN_WARNING "moxa_close: bad serial port count, " - "device=%s\n", tty->name); + printk("moxa_close: bad serial port count, device=%s\n", + tty->name); ch->count = 0; } if (ch->count) { @@ -557,11 +563,11 @@ static void moxa_close(struct tty_struct *tty, struct file *filp) ch->cflag = tty->termios->c_cflag; if (ch->asyncflags & ASYNC_INITIALIZED) { - moxa_setup_empty_event(tty); + setup_empty_event(tty); tty_wait_until_sent(tty, 30 * HZ); /* 30 seconds timeout */ del_timer_sync(&moxa_ports[ch->port].emptyTimer); } - moxa_shut_down(ch); + shut_down(ch); MoxaPortFlushData(port, 2); if (tty->driver->flush_buffer) @@ -578,7 +584,7 @@ static void moxa_close(struct tty_struct *tty, struct file *filp) wake_up_interruptible(&ch->open_wait); } ch->asyncflags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING); - complete_all(&ch->close_wait); + wake_up_interruptible(&ch->close_wait); } static int moxa_write(struct tty_struct *tty, @@ -647,7 +653,7 @@ static int moxa_chars_in_buffer(struct tty_struct *tty) * in tty_ioctl.c, etc. */ if (!(ch->statusflags & EMPTYWAIT)) - moxa_setup_empty_event(tty); + setup_empty_event(tty); } return (chars); } @@ -745,7 +751,7 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file, retval = tty_check_change(tty); if (retval) return (retval); - moxa_setup_empty_event(tty); + setup_empty_event(tty); tty_wait_until_sent(tty, 0); if (!arg) MoxaPortSendBreak(ch->port, 0); @@ -754,7 +760,7 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file, retval = tty_check_change(tty); if (retval) return (retval); - moxa_setup_empty_event(tty); + setup_empty_event(tty); tty_wait_until_sent(tty, 0); MoxaPortSendBreak(ch->port, arg); return (0); @@ -803,7 +809,7 @@ static void moxa_set_termios(struct tty_struct *tty, if (ch == NULL) return; - moxa_set_tty_param(tty); + set_tty_param(tty); if (!(old_termios->c_cflag & CLOCAL) && (tty->termios->c_cflag & CLOCAL)) wake_up_interruptible(&ch->open_wait); @@ -839,7 +845,7 @@ static void moxa_hangup(struct tty_struct *tty) struct moxa_port *ch = (struct moxa_port *) tty->driver_data; moxa_flush_buffer(tty); - moxa_shut_down(ch); + shut_down(ch); ch->event = 0; ch->count = 0; ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE; @@ -869,7 +875,7 @@ static void moxa_poll(unsigned long ignored) continue; if (!(ch->statusflags & THROTTLE) && (MoxaPortRxQueue(ch->port) > 0)) - moxa_receive_data(ch); + receive_data(ch); if ((tp = ch->tty) == 0) continue; if (ch->statusflags & LOWWAIT) { @@ -903,7 +909,7 @@ static void moxa_poll(unsigned long ignored) /******************************************************************************/ -static void moxa_set_tty_param(struct tty_struct *tty) +static void set_tty_param(struct tty_struct *tty) { register struct ktermios *ts; struct moxa_port *ch; @@ -928,7 +934,7 @@ static void moxa_set_tty_param(struct tty_struct *tty) MoxaPortSetTermio(ch->port, ts, tty_get_baud_rate(tty)); } -static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp, +static int block_till_ready(struct tty_struct *tty, struct file *filp, struct moxa_port *ch) { DECLARE_WAITQUEUE(wait,current); @@ -942,7 +948,7 @@ static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp, */ if (tty_hung_up_p(filp) || (ch->asyncflags & ASYNC_CLOSING)) { if (ch->asyncflags & ASYNC_CLOSING) - wait_for_completion_interruptible(&ch->close_wait); + interruptible_sleep_on(&ch->close_wait); #ifdef SERIAL_DO_RESTART if (ch->asyncflags & ASYNC_HUP_NOTIFY) return (-EAGAIN); @@ -965,8 +971,10 @@ static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp, */ retval = 0; add_wait_queue(&ch->open_wait, &wait); - pr_debug("block_til_ready before block: ttys%d, count = %d\n", - ch->port, ch->count); +#ifdef SERIAL_DEBUG_OPEN + printk("block_til_ready before block: ttys%d, count = %d\n", + ch->line, ch->count); +#endif spin_lock_irqsave(&moxa_lock, flags); if (!tty_hung_up_p(filp)) ch->count--; @@ -1005,8 +1013,10 @@ static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp, ch->count++; ch->blocked_open--; spin_unlock_irqrestore(&moxa_lock, flags); - pr_debug("block_til_ready after blocking: ttys%d, count = %d\n", - ch->port, ch->count); +#ifdef SERIAL_DEBUG_OPEN + printk("block_til_ready after blocking: ttys%d, count = %d\n", + ch->line, ch->count); +#endif if (retval) return (retval); /* FIXME: review to see if we need to use set_bit on these */ @@ -1014,7 +1024,7 @@ static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp, return 0; } -static void moxa_setup_empty_event(struct tty_struct *tty) +static void setup_empty_event(struct tty_struct *tty) { struct moxa_port *ch = tty->driver_data; unsigned long flags; @@ -1025,24 +1035,24 @@ static void moxa_setup_empty_event(struct tty_struct *tty) spin_unlock_irqrestore(&moxa_lock, flags); } -static void moxa_check_xmit_empty(unsigned long data) +static void check_xmit_empty(unsigned long data) { struct moxa_port *ch; ch = (struct moxa_port *) data; + del_timer_sync(&moxa_ports[ch->port].emptyTimer); if (ch->tty && (ch->statusflags & EMPTYWAIT)) { if (MoxaPortTxQueue(ch->port) == 0) { ch->statusflags &= ~EMPTYWAIT; tty_wakeup(ch->tty); return; } - mod_timer(&moxa_ports[ch->port].emptyTimer, - round_jiffies(jiffies + HZ)); + mod_timer(&moxa_ports[ch->port].emptyTimer, jiffies + HZ); } else ch->statusflags &= ~EMPTYWAIT; } -static void moxa_shut_down(struct moxa_port *ch) +static void shut_down(struct moxa_port *ch) { struct tty_struct *tp; @@ -1062,7 +1072,7 @@ static void moxa_shut_down(struct moxa_port *ch) ch->asyncflags &= ~ASYNC_INITIALIZED; } -static void moxa_receive_data(struct moxa_port *ch) +static void receive_data(struct moxa_port *ch) { struct tty_struct *tp; struct ktermios *ts; @@ -1396,8 +1406,8 @@ static struct mon_str moxaLog; static int moxaFuncTout = HZ / 2; static void moxafunc(void __iomem *, int, ushort); -static void moxa_wait_finish(void __iomem *); -static void moxa_low_water_check(void __iomem *); +static void wait_finish(void __iomem *); +static void low_water_check(void __iomem *); static int moxaloadbios(int, unsigned char __user *, int); static int moxafindcard(int); static int moxaload320b(int, unsigned char __user *, int); @@ -1463,7 +1473,7 @@ void MoxaPortFlushData(int port, int mode) moxafunc(ofsAddr, FC_FlushQueue, mode); if (mode != 1) { moxa_ports[port].lowChkFlag = 0; - moxa_low_water_check(ofsAddr); + low_water_check(ofsAddr); } } @@ -1644,7 +1654,7 @@ int MoxaDriverPoll(void) if (moxa_ports[p].lowChkFlag) { moxa_ports[p].lowChkFlag = 0; ofsAddr = moxa_ports[p].tableAddr; - moxa_low_water_check(ofsAddr); + low_water_check(ofsAddr); } } } @@ -2071,7 +2081,7 @@ int MoxaPortSetTermio(int port, struct ktermios *termio, speed_t baud) writeb(termio->c_cc[VSTART], ofsAddr + FuncArg); writeb(termio->c_cc[VSTOP], ofsAddr + FuncArg1); writeb(FC_SetXonXoff, ofsAddr + FuncCode); - moxa_wait_finish(ofsAddr); + wait_finish(ofsAddr); } return (0); @@ -2470,10 +2480,10 @@ static void moxafunc(void __iomem *ofsAddr, int cmd, ushort arg) writew(arg, ofsAddr + FuncArg); writew(cmd, ofsAddr + FuncCode); - moxa_wait_finish(ofsAddr); + wait_finish(ofsAddr); } -static void moxa_wait_finish(void __iomem *ofsAddr) +static void wait_finish(void __iomem *ofsAddr) { unsigned long i, j; @@ -2486,7 +2496,7 @@ static void moxa_wait_finish(void __iomem *ofsAddr) } } -static void moxa_low_water_check(void __iomem *ofsAddr) +static void low_water_check(void __iomem *ofsAddr) { int len; ushort rptr, wptr, mask; diff --git a/trunk/drivers/char/mxser.c b/trunk/drivers/char/mxser.c index fd0abef7ee08..2aee3fef0416 100644 --- a/trunk/drivers/char/mxser.c +++ b/trunk/drivers/char/mxser.c @@ -56,11 +56,11 @@ #include #include #include -#include #include #include #include +#include #include #include "mxser.h" @@ -383,6 +383,7 @@ static int mxser_init(void); /* static void mxser_poll(unsigned long); */ static int mxser_get_ISA_conf(int, struct mxser_hwconf *); +static int mxser_get_PCI_conf(int, int, int, struct mxser_hwconf *); static void mxser_do_softint(struct work_struct *); static int mxser_open(struct tty_struct *, struct file *); static void mxser_close(struct tty_struct *, struct file *); @@ -421,7 +422,7 @@ static void mxser_wait_until_sent(struct tty_struct *tty, int timeout); static void mxser_startrx(struct tty_struct *tty); static void mxser_stoprx(struct tty_struct *tty); -#ifdef CONFIG_PCI + static int CheckIsMoxaMust(int io) { u8 oldmcr, hwid; @@ -444,7 +445,6 @@ static int CheckIsMoxaMust(int io) } return MOXA_OTHER_UART; } -#endif /* above is modified by Victor Yu. 08-15-2002 */ @@ -1938,6 +1938,14 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id) inb(info->base + UART_MSR); continue; } + /* above add by Victor Yu. 09-13-2002 */ + /* + if (info->tty->flip.count < TTY_FLIPBUF_SIZE / 4) { + info->IER |= MOXA_MUST_RECV_ISR; + outb(info->IER, info->base + UART_IER); + } + */ + /* mask by Victor Yu. 09-13-2002 if ( !info->tty || @@ -2591,8 +2599,19 @@ static int mxser_change_speed(struct mxser_struct *info, struct ktermios *old_te info->IER |= UART_IER_MSI; if ((info->type == PORT_16550A) || (info->IsMoxaMustChipFlag)) { info->MCR |= UART_MCR_AFE; + /* status = mxser_get_msr(info->base, 0, info->port); */ +/* + save_flags(flags); + cli(); + status = inb(baseaddr + UART_MSR); + restore_flags(flags); +*/ + /* mxser_check_modem_status(info, status); */ } else { + /* status = mxser_get_msr(info->base, 0, info->port); */ + /* MX_LOCK(&info->slock); */ status = inb(info->base + UART_MSR); + /* MX_UNLOCK(&info->slock); */ if (info->tty->hw_stopped) { if (status & UART_MSR_CTS) { info->tty->hw_stopped = 0; diff --git a/trunk/drivers/char/mxser_new.c b/trunk/drivers/char/mxser_new.c index 081c84c7b548..6a563932ba19 100644 --- a/trunk/drivers/char/mxser_new.c +++ b/trunk/drivers/char/mxser_new.c @@ -2,7 +2,7 @@ * mxser.c -- MOXA Smartio/Industio family multiport serial driver. * * Copyright (C) 1999-2006 Moxa Technologies (support@moxa.com.tw). - * Copyright (C) 2006-2007 Jiri Slaby + * Copyright (C) 2006 Jiri Slaby * * This code is loosely based on the 1.8 moxa driver which is based on * Linux serial driver, written by Linus Torvalds, Theodore T'so and @@ -39,16 +39,16 @@ #include #include #include -#include #include #include #include +#include #include #include "mxser_new.h" -#define MXSER_VERSION "2.0.2" /* 1.10 */ +#define MXSER_VERSION "2.0.1" /* 1.9.15 */ #define MXSERMAJOR 174 #define MXSERCUMAJOR 175 @@ -72,12 +72,6 @@ #define UART_MCR_AFE 0x20 #define UART_LSR_SPECIAL 0x1E -#define PCI_DEVICE_ID_CB108 0x1080 -#define PCI_DEVICE_ID_CB114 0x1142 -#define PCI_DEVICE_ID_CB134I 0x1341 -#define PCI_DEVICE_ID_CP138U 0x1380 -#define PCI_DEVICE_ID_POS104UL 0x1044 - #define C168_ASIC_ID 1 #define C104_ASIC_ID 2 @@ -113,63 +107,71 @@ struct mxser_cardinfo { }; static const struct mxser_cardinfo mxser_cards[] = { -/* 0*/ { 8, "C168 series", }, - { 4, "C104 series", }, - { 4, "CI-104J series", }, - { 8, "C168H/PCI series", }, - { 4, "C104H/PCI series", }, -/* 5*/ { 4, "C102 series", MXSER_HAS2 }, /* C102-ISA */ - { 4, "CI-132 series", MXSER_HAS2 }, - { 4, "CI-134 series", }, - { 2, "CP-132 series", }, - { 4, "CP-114 series", }, -/*10*/ { 4, "CT-114 series", }, - { 2, "CP-102 series", MXSER_HIGHBAUD }, - { 4, "CP-104U series", }, - { 8, "CP-168U series", }, - { 2, "CP-132U series", }, -/*15*/ { 4, "CP-134U series", }, - { 4, "CP-104JU series", }, + { 8, "C168 series", }, /* C168-ISA */ + { 4, "C104 series", }, /* C104-ISA */ + { 4, "CI-104J series", }, /* CI104J */ + { 8, "C168H/PCI series", }, /* C168-PCI */ + { 4, "C104H/PCI series", }, /* C104-PCI */ + { 4, "C102 series", MXSER_HAS2 }, /* C102-ISA */ + { 4, "CI-132 series", MXSER_HAS2 }, /* CI132 */ + { 4, "CI-134 series", }, /* CI134 */ + { 2, "CP-132 series", }, /* CP132 */ + { 4, "CP-114 series", }, /* CP114 */ + { 4, "CT-114 series", }, /* CT114 */ + { 2, "CP-102 series", MXSER_HIGHBAUD }, /* CP102 */ + { 4, "CP-104U series", }, /* CP104U */ + { 8, "CP-168U series", }, /* CP168U */ + { 2, "CP-132U series", }, /* CP132U */ + { 4, "CP-134U series", }, /* CP134U */ + { 4, "CP-104JU series", }, /* CP104JU */ { 8, "Moxa UC7000 Serial", }, /* RC7000 */ - { 8, "CP-118U series", }, - { 2, "CP-102UL series", }, -/*20*/ { 2, "CP-102U series", }, - { 8, "CP-118EL series", }, - { 8, "CP-168EL series", }, - { 4, "CP-104EL series", }, - { 8, "CB-108 series", }, -/*25*/ { 4, "CB-114 series", }, - { 4, "CB-134I series", }, - { 8, "CP-138U series", }, - { 4, "POS-104UL series", } + { 8, "CP-118U series", }, /* CP118U */ + { 2, "CP-102UL series", }, /* CP102UL */ + { 2, "CP-102U series", }, /* CP102U */ + { 8, "CP-118EL series", }, /* CP118EL */ + { 8, "CP-168EL series", }, /* CP168EL */ + { 4, "CP-104EL series", } /* CP104EL */ }; /* driver_data correspond to the lines in the structure above see also ISA probe function before you change something */ static struct pci_device_id mxser_pcibrds[] = { - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_C168), .driver_data = 3 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_C104), .driver_data = 4 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP132), .driver_data = 8 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP114), .driver_data = 9 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CT114), .driver_data = 10 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP102), .driver_data = 11 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP104U), .driver_data = 12 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP168U), .driver_data = 13 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP132U), .driver_data = 14 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP134U), .driver_data = 15 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP104JU),.driver_data = 16 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_RC7000), .driver_data = 17 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP118U), .driver_data = 18 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP102UL),.driver_data = 19 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP102U), .driver_data = 20 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP118EL),.driver_data = 21 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP168EL),.driver_data = 22 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_MOXA_CP104EL),.driver_data = 23 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CB108), .driver_data = 24 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CB114), .driver_data = 25 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CB134I), .driver_data = 26 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_CP138U), .driver_data = 27 }, - { PCI_VDEVICE(MOXA, PCI_DEVICE_ID_POS104UL), .driver_data = 28 }, + { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_C168), + .driver_data = 3 }, + { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_C104), + .driver_data = 4 }, + { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP132), + .driver_data = 8 }, + { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP114), + .driver_data = 9 }, + { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CT114), + .driver_data = 10 }, + { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP102), + .driver_data = 11 }, + { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP104U), + .driver_data = 12 }, + { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP168U), + .driver_data = 13 }, + { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP132U), + .driver_data = 14 }, + { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP134U), + .driver_data = 15 }, + { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP104JU), + .driver_data = 16 }, + { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_RC7000), + .driver_data = 17 }, + { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP118U), + .driver_data = 18 }, + { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP102UL), + .driver_data = 19 }, + { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP102U), + .driver_data = 20 }, + { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP118EL), + .driver_data = 21 }, + { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP168EL), + .driver_data = 22 }, + { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP104EL), + .driver_data = 23 }, { } }; MODULE_DEVICE_TABLE(pci, mxser_pcibrds); diff --git a/trunk/drivers/char/pty.c b/trunk/drivers/char/pty.c index 706ff34728f1..73de77105fea 100644 --- a/trunk/drivers/char/pty.c +++ b/trunk/drivers/char/pty.c @@ -318,7 +318,7 @@ int pty_limit = NR_UNIX98_PTY_DEFAULT; static int pty_limit_min = 0; static int pty_limit_max = NR_UNIX98_PTY_MAX; -static struct ctl_table pty_table[] = { +ctl_table pty_table[] = { { .ctl_name = PTY_MAX, .procname = "max", @@ -340,27 +340,6 @@ static struct ctl_table pty_table[] = { } }; -static struct ctl_table pty_kern_table[] = { - { - .ctl_name = KERN_PTY, - .procname = "pty", - .mode = 0555, - .child = pty_table, - }, - {} -}; - -static struct ctl_table pty_root_table[] = { - { - .ctl_name = CTL_KERN, - .procname = "kernel", - .mode = 0555, - .child = pty_kern_table, - }, - {} -}; - - static int pty_unix98_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) { @@ -425,7 +404,6 @@ static void __init unix98_pty_init(void) panic("Couldn't register Unix98 pts driver"); pty_table[1].data = &ptm_driver->refcount; - register_sysctl_table(pty_root_table); } #else static inline void unix98_pty_init(void) { } diff --git a/trunk/drivers/char/random.c b/trunk/drivers/char/random.c index 1756b1f7cb72..af274e5a25ee 100644 --- a/trunk/drivers/char/random.c +++ b/trunk/drivers/char/random.c @@ -649,7 +649,7 @@ EXPORT_SYMBOL_GPL(add_input_randomness); void add_interrupt_randomness(int irq) { - if (irq >= NR_IRQS || irq_timer_state[irq] == NULL) + if (irq >= NR_IRQS || irq_timer_state[irq] == 0) return; DEBUG_ENT("irq event %d\n", irq); diff --git a/trunk/drivers/char/rocket.c b/trunk/drivers/char/rocket.c index 7e6a3a413bb2..56cbba7b6ec0 100644 --- a/trunk/drivers/char/rocket.c +++ b/trunk/drivers/char/rocket.c @@ -84,7 +84,6 @@ #include #include #include -#include #include #include #include @@ -549,8 +548,8 @@ static void rp_handle_port(struct r_port *info) static void rp_do_poll(unsigned long dummy) { CONTROLLER_t *ctlp; - int ctrl, aiop, ch, line; - unsigned int xmitmask, i; + int ctrl, aiop, ch, line, i; + unsigned int xmitmask; unsigned int CtlMask; unsigned char AiopMask; Word_t bit; @@ -651,7 +650,7 @@ static void init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev) info->closing_wait = 3000; info->close_delay = 50; init_waitqueue_head(&info->open_wait); - init_completion(&info->close_wait); + init_waitqueue_head(&info->close_wait); info->flags &= ~ROCKET_MODE_MASK; switch (pc104[board][line]) { case 422: @@ -700,8 +699,8 @@ static void init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev) spin_lock_init(&info->slock); mutex_init(&info->write_mtx); rp_table[line] = info; - tty_register_device(rocket_driver, line, pci_dev ? &pci_dev->dev : - NULL); + if (pci_dev) + tty_register_device(rocket_driver, line, &pci_dev->dev); } /* @@ -879,8 +878,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, if (tty_hung_up_p(filp)) return ((info->flags & ROCKET_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS); if (info->flags & ROCKET_CLOSING) { - if (wait_for_completion_interruptible(&info->close_wait)) - return -ERESTARTSYS; + interruptible_sleep_on(&info->close_wait); return ((info->flags & ROCKET_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS); } @@ -985,10 +983,8 @@ static int rp_open(struct tty_struct *tty, struct file *filp) return -ENOMEM; if (info->flags & ROCKET_CLOSING) { - retval = wait_for_completion_interruptible(&info->close_wait); + interruptible_sleep_on(&info->close_wait); free_page(page); - if (retval) - return retval; return ((info->flags & ROCKET_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS); } @@ -1180,7 +1176,7 @@ static void rp_close(struct tty_struct *tty, struct file *filp) } info->flags &= ~(ROCKET_INITIALIZED | ROCKET_CLOSING | ROCKET_NORMAL_ACTIVE); tty->closing = 0; - complete_all(&info->close_wait); + wake_up_interruptible(&info->close_wait); atomic_dec(&rp_num_ports_open); #ifdef ROCKET_DEBUG_OPEN @@ -1873,6 +1869,8 @@ static __init int register_PCI(int i, struct pci_dev *dev) int fast_clock = 0; int altChanRingIndicator = 0; int ports_per_aiop = 8; + int ret; + unsigned int class_rev; WordIO_t ConfigIO = 0; ByteIO_t UPCIRingInd = 0; @@ -1880,6 +1878,12 @@ static __init int register_PCI(int i, struct pci_dev *dev) return 0; rcktpt_io_addr[i] = pci_resource_start(dev, 0); + ret = pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); + + if (ret) { + printk(KERN_INFO " Error during register_PCI(), unable to read config dword \n"); + return 0; + } rcktpt_type[i] = ROCKET_TYPE_NORMAL; rocketModel[i].loadrm2 = 0; @@ -2033,9 +2037,8 @@ static __init int register_PCI(int i, struct pci_dev *dev) ports_per_aiop = 6; str = "6-port"; - /* If revision is 1, the rocketmodem flash must be loaded. - * If it is 2 it is a "socketed" version. */ - if (dev->revision == 1) { + /* If class_rev is 1, the rocketmodem flash must be loaded. If it is 2 it is a "socketed" version. */ + if ((class_rev & 0xFF) == 1) { rcktpt_type[i] = ROCKET_TYPE_MODEMII; rocketModel[i].loadrm2 = 1; } else { @@ -2050,7 +2053,7 @@ static __init int register_PCI(int i, struct pci_dev *dev) max_num_aiops = 1; ports_per_aiop = 4; str = "4-port"; - if (dev->revision == 1) { + if ((class_rev & 0xFF) == 1) { rcktpt_type[i] = ROCKET_TYPE_MODEMII; rocketModel[i].loadrm2 = 1; } else { @@ -2359,14 +2362,26 @@ static const struct tty_operations rocket_ops = { */ static int __init rp_init(void) { - int ret = -ENOMEM, pci_boards_found, isa_boards_found, i; + int retval, pci_boards_found, isa_boards_found, i; printk(KERN_INFO "RocketPort device driver module, version %s, %s\n", ROCKET_VERSION, ROCKET_DATE); rocket_driver = alloc_tty_driver(MAX_RP_PORTS); if (!rocket_driver) - goto err; + return -ENOMEM; + + /* + * Initialize the array of pointers to our own internal state + * structures. + */ + memset(rp_table, 0, sizeof (rp_table)); + memset(xmit_flags, 0, sizeof (xmit_flags)); + + for (i = 0; i < MAX_RP_PORTS; i++) + lineNumbers[i] = 0; + nextLineNumber = 0; + memset(rocketModel, 0, sizeof (rocketModel)); /* * If board 1 is non-zero, there is at least one ISA configured. If controller is @@ -2381,11 +2396,8 @@ static int __init rp_init(void) /* If an ISA card is configured, reserve the 4 byte IO space for the Mudbac controller */ if (controller && (!request_region(controller, 4, "Comtrol RocketPort"))) { - printk(KERN_ERR "Unable to reserve IO region for first " - "configured ISA RocketPort controller 0x%lx. " - "Driver exiting\n", controller); - ret = -EBUSY; - goto err_tty; + printk(KERN_INFO "Unable to reserve IO region for first configured ISA RocketPort controller 0x%lx. Driver exiting \n", controller); + return -EBUSY; } /* Store ISA variable retrieved from command line or .conf file. */ @@ -2422,14 +2434,15 @@ static int __init rp_init(void) rocket_driver->init_termios.c_ispeed = 9600; rocket_driver->init_termios.c_ospeed = 9600; #ifdef ROCKET_SOFT_FLOW - rocket_driver->flags |= TTY_DRIVER_REAL_RAW; + rocket_driver->flags |= TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; #endif tty_set_operations(rocket_driver, &rocket_ops); - ret = tty_register_driver(rocket_driver); - if (ret < 0) { - printk(KERN_ERR "Couldn't install tty RocketPort driver\n"); - goto err_tty; + retval = tty_register_driver(rocket_driver); + if (retval < 0) { + printk(KERN_INFO "Couldn't install tty RocketPort driver (error %d)\n", -retval); + put_tty_driver(rocket_driver); + return -1; } #ifdef ROCKET_DEBUG_OPEN @@ -2456,18 +2469,14 @@ static int __init rp_init(void) max_board = pci_boards_found + isa_boards_found; if (max_board == 0) { - printk(KERN_ERR "No rocketport ports found; unloading driver\n"); - ret = -ENXIO; - goto err_ttyu; + printk(KERN_INFO "No rocketport ports found; unloading driver.\n"); + del_timer_sync(&rocket_timer); + tty_unregister_driver(rocket_driver); + put_tty_driver(rocket_driver); + return -ENXIO; } return 0; -err_ttyu: - tty_unregister_driver(rocket_driver); -err_tty: - put_tty_driver(rocket_driver); -err: - return ret; } @@ -2482,14 +2491,10 @@ static void rp_cleanup_module(void) if (retval) printk(KERN_INFO "Error %d while trying to unregister " "rocketport driver\n", -retval); + put_tty_driver(rocket_driver); for (i = 0; i < MAX_RP_PORTS; i++) - if (rp_table[i]) { - tty_unregister_device(rocket_driver, i); - kfree(rp_table[i]); - } - - put_tty_driver(rocket_driver); + kfree(rp_table[i]); for (i = 0; i < NUM_BOARDS; i++) { if (rcktpt_io_addr[i] <= 0 || is_PCI[i]) diff --git a/trunk/drivers/char/rocket_int.h b/trunk/drivers/char/rocket_int.h index 55b8f2d71a96..b4c53dfa7951 100644 --- a/trunk/drivers/char/rocket_int.h +++ b/trunk/drivers/char/rocket_int.h @@ -1163,8 +1163,13 @@ struct r_port { int read_status_mask; int cps; +#ifdef DECLARE_WAITQUEUE wait_queue_head_t open_wait; - struct completion close_wait; + wait_queue_head_t close_wait; +#else + struct wait_queue *open_wait; + struct wait_queue *close_wait; +#endif spinlock_t slock; struct mutex write_mtx; }; diff --git a/trunk/drivers/char/sonypi.c b/trunk/drivers/char/sonypi.c index 9782cb4d30dc..859858561ab6 100644 --- a/trunk/drivers/char/sonypi.c +++ b/trunk/drivers/char/sonypi.c @@ -1178,9 +1178,9 @@ static int __devinit sonypi_create_input_devices(void) jog_dev->id.bustype = BUS_ISA; jog_dev->id.vendor = PCI_VENDOR_ID_SONY; - jog_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); - jog_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_MIDDLE); - jog_dev->relbit[0] = BIT_MASK(REL_WHEEL); + jog_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); + jog_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_MIDDLE); + jog_dev->relbit[0] = BIT(REL_WHEEL); sonypi_device.input_key_dev = key_dev = input_allocate_device(); if (!key_dev) { @@ -1193,7 +1193,7 @@ static int __devinit sonypi_create_input_devices(void) key_dev->id.vendor = PCI_VENDOR_ID_SONY; /* Initialize the Input Drivers: special keys */ - key_dev->evbit[0] = BIT_MASK(EV_KEY); + key_dev->evbit[0] = BIT(EV_KEY); for (i = 0; sonypi_inputkeys[i].sonypiev; i++) if (sonypi_inputkeys[i].inputev) set_bit(sonypi_inputkeys[i].inputev, key_dev->keybit); diff --git a/trunk/drivers/char/sx.c b/trunk/drivers/char/sx.c index a6e1c9ba1217..85a23283dff5 100644 --- a/trunk/drivers/char/sx.c +++ b/trunk/drivers/char/sx.c @@ -1467,7 +1467,7 @@ static int sx_open(struct tty_struct *tty, struct file *filp) line = tty->index; sx_dprintk(SX_DEBUG_OPEN, "%d: opening line %d. tty=%p ctty=%p, " - "np=%d)\n", task_pid_nr(current), line, tty, + "np=%d)\n", current->pid, line, tty, current->signal->tty, sx_nports); if ((line < 0) || (line >= SX_NPORTS) || (line >= sx_nports)) diff --git a/trunk/drivers/char/sysrq.c b/trunk/drivers/char/sysrq.c index de60e1ea4fb3..78d14935f2b8 100644 --- a/trunk/drivers/char/sysrq.c +++ b/trunk/drivers/char/sysrq.c @@ -251,7 +251,7 @@ static void send_sig_all(int sig) struct task_struct *p; for_each_process(p) { - if (p->mm && !is_global_init(p)) + if (p->mm && !is_init(p)) /* Not swapper, init nor kernel thread */ force_sig(sig, p); } diff --git a/trunk/drivers/char/tty_io.c b/trunk/drivers/char/tty_io.c index 13a53575a016..9c867cf6de64 100644 --- a/trunk/drivers/char/tty_io.c +++ b/trunk/drivers/char/tty_io.c @@ -103,7 +103,6 @@ #include #include -#include #undef TTY_DEBUG_HANGUP @@ -3108,7 +3107,7 @@ static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t */ if (tty == real_tty && current->signal->tty != real_tty) return -ENOTTY; - return put_user(pid_vnr(real_tty->pgrp), p); + return put_user(pid_nr(real_tty->pgrp), p); } /** @@ -3142,7 +3141,7 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t if (pgrp_nr < 0) return -EINVAL; rcu_read_lock(); - pgrp = find_vpid(pgrp_nr); + pgrp = find_pid(pgrp_nr); retval = -ESRCH; if (!pgrp) goto out_unlock; @@ -3179,7 +3178,7 @@ static int tiocgsid(struct tty_struct *tty, struct tty_struct *real_tty, pid_t _ return -ENOTTY; if (!real_tty->session) return -ENOTTY; - return put_user(pid_vnr(real_tty->session), p); + return put_user(pid_nr(real_tty->session), p); } /** @@ -3529,8 +3528,8 @@ void __do_SAK(struct tty_struct *tty) /* Kill the entire session */ do_each_pid_task(session, PIDTYPE_SID, p) { printk(KERN_NOTICE "SAK: killed process %d" - " (%s): task_session_nr(p)==tty->session\n", - task_pid_nr(p), p->comm); + " (%s): process_session(p)==tty->session\n", + p->pid, p->comm); send_sig(SIGKILL, p, 1); } while_each_pid_task(session, PIDTYPE_SID, p); /* Now kill any processes that happen to have the @@ -3539,8 +3538,8 @@ void __do_SAK(struct tty_struct *tty) do_each_thread(g, p) { if (p->signal->tty == tty) { printk(KERN_NOTICE "SAK: killed process %d" - " (%s): task_session_nr(p)==tty->session\n", - task_pid_nr(p), p->comm); + " (%s): process_session(p)==tty->session\n", + p->pid, p->comm); send_sig(SIGKILL, p, 1); continue; } @@ -3560,7 +3559,7 @@ void __do_SAK(struct tty_struct *tty) filp->private_data == tty) { printk(KERN_NOTICE "SAK: killed process %d" " (%s): fd#%d opened to the tty\n", - task_pid_nr(p), p->comm, i); + p->pid, p->comm, i); force_sig(SIGKILL, p); break; } diff --git a/trunk/drivers/char/tty_ioctl.c b/trunk/drivers/char/tty_ioctl.c index 0def089cc1f2..745d552620bf 100644 --- a/trunk/drivers/char/tty_ioctl.c +++ b/trunk/drivers/char/tty_ioctl.c @@ -228,8 +228,7 @@ EXPORT_SYMBOL(tty_termios_input_baud_rate); * and will all go away once this is done. */ -void tty_termios_encode_baud_rate(struct ktermios *termios, - speed_t ibaud, speed_t obaud) +void tty_termios_encode_baud_rate(struct ktermios *termios, speed_t ibaud, speed_t obaud) { int i = 0; int ifound = -1, ofound = -1; @@ -264,15 +263,11 @@ void tty_termios_encode_baud_rate(struct ktermios *termios, */ do { - if (obaud - oclose <= baud_table[i] && - obaud + oclose >= baud_table[i]) { + if (obaud - oclose >= baud_table[i] && obaud + oclose <= baud_table[i]) { termios->c_cflag |= baud_bits[i]; ofound = i; } - if (ibaud - iclose <= baud_table[i] && - ibaud + iclose >= baud_table[i]) { - /* For the case input == output don't set IBAUD bits - if the user didn't do so */ + if (ibaud - iclose >= baud_table[i] && ibaud + iclose <= baud_table[i]) { if (ofound == i && !ibinput) ifound = i; #ifdef IBSHIFT diff --git a/trunk/drivers/char/vt.c b/trunk/drivers/char/vt.c index 7a5badfb7d84..645ad9808982 100644 --- a/trunk/drivers/char/vt.c +++ b/trunk/drivers/char/vt.c @@ -99,7 +99,6 @@ #include #include #include -#include #include #include @@ -159,7 +158,11 @@ static void blank_screen_t(unsigned long dummy); static void set_palette(struct vc_data *vc); static int printable; /* Is console ready for printing? */ -int default_utf8 = true; +#ifdef CONFIG_VT_UNICODE +int default_utf8 = 1; +#else +int default_utf8; +#endif module_param(default_utf8, int, S_IRUGO | S_IWUSR); /* @@ -223,35 +226,6 @@ enum { blank_vesa_wait, }; -/* - * Notifier list for console events. - */ -static ATOMIC_NOTIFIER_HEAD(vt_notifier_list); - -int register_vt_notifier(struct notifier_block *nb) -{ - return atomic_notifier_chain_register(&vt_notifier_list, nb); -} -EXPORT_SYMBOL_GPL(register_vt_notifier); - -int unregister_vt_notifier(struct notifier_block *nb) -{ - return atomic_notifier_chain_unregister(&vt_notifier_list, nb); -} -EXPORT_SYMBOL_GPL(unregister_vt_notifier); - -static void notify_write(struct vc_data *vc, unsigned int unicode) -{ - struct vt_notifier_param param = { .vc = vc, unicode = unicode }; - atomic_notifier_call_chain(&vt_notifier_list, VT_WRITE, ¶m); -} - -static void notify_update(struct vc_data *vc) -{ - struct vt_notifier_param param = { .vc = vc }; - atomic_notifier_call_chain(&vt_notifier_list, VT_UPDATE, ¶m); -} - /* * Low-Level Functions */ @@ -748,7 +722,6 @@ int vc_allocate(unsigned int currcons) /* return 0 on success */ return -ENXIO; if (!vc_cons[currcons].d) { struct vc_data *vc; - struct vt_notifier_param param; /* prevent users from taking too much memory */ if (currcons >= MAX_NR_USER_CONSOLES && !capable(CAP_SYS_RESOURCE)) @@ -760,7 +733,7 @@ int vc_allocate(unsigned int currcons) /* return 0 on success */ /* although the numbers above are not valid since long ago, the point is still up-to-date and the comment still has its value even if only as a historical artifact. --mj, July 1998 */ - param.vc = vc = kzalloc(sizeof(struct vc_data), GFP_KERNEL); + vc = kzalloc(sizeof(struct vc_data), GFP_KERNEL); if (!vc) return -ENOMEM; vc_cons[currcons].d = vc; @@ -777,7 +750,6 @@ int vc_allocate(unsigned int currcons) /* return 0 on success */ } vc->vc_kmalloced = 1; vc_init(vc, vc->vc_rows, vc->vc_cols, 1); - atomic_notifier_call_chain(&vt_notifier_list, VT_ALLOCATE, ¶m); } return 0; } @@ -939,8 +911,6 @@ void vc_deallocate(unsigned int currcons) if (vc_cons_allocated(currcons)) { struct vc_data *vc = vc_cons[currcons].d; - struct vt_notifier_param param = { .vc = vc }; - atomic_notifier_call_chain(&vt_notifier_list, VT_DEALLOCATE, ¶m); vc->vc_sw->con_deinit(vc); put_pid(vc->vt_pid); module_put(vc->vc_sw->owner); @@ -1053,7 +1023,6 @@ static void lf(struct vc_data *vc) vc->vc_pos += vc->vc_size_row; } vc->vc_need_wrap = 0; - notify_write(vc, '\n'); } static void ri(struct vc_data *vc) @@ -1074,7 +1043,6 @@ static inline void cr(struct vc_data *vc) { vc->vc_pos -= vc->vc_x << 1; vc->vc_need_wrap = vc->vc_x = 0; - notify_write(vc, '\r'); } static inline void bs(struct vc_data *vc) @@ -1083,7 +1051,6 @@ static inline void bs(struct vc_data *vc) vc->vc_pos -= 2; vc->vc_x--; vc->vc_need_wrap = 0; - notify_write(vc, '\b'); } } @@ -1630,7 +1597,6 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c) break; } vc->vc_pos += (vc->vc_x << 1); - notify_write(vc, '\t'); return; case 10: case 11: case 12: lf(vc); @@ -2290,7 +2256,6 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co tc = conv_uni_to_pc(vc, ' '); /* A space is printed in the second column */ if (tc < 0) tc = ' '; } - notify_write(vc, c); if (inverse) { FLUSH @@ -2313,7 +2278,6 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co release_console_sem(); out: - notify_update(vc); return n; #undef FLUSH } @@ -2357,7 +2321,6 @@ static void console_callback(struct work_struct *ignored) do_blank_screen(0); blank_timer_expired = 0; } - notify_update(vc_cons[fg_console].d); release_console_sem(); } @@ -2459,7 +2422,6 @@ static void vt_console_print(struct console *co, const char *b, unsigned count) continue; } scr_writew((vc->vc_attr << 8) + c, (unsigned short *)vc->vc_pos); - notify_write(vc, c); cnt++; if (myx == vc->vc_cols - 1) { vc->vc_need_wrap = 1; @@ -2478,7 +2440,6 @@ static void vt_console_print(struct console *co, const char *b, unsigned count) } } set_cursor(vc); - notify_update(vc); quit: clear_bit(0, &printing); diff --git a/trunk/drivers/watchdog/Kconfig b/trunk/drivers/char/watchdog/Kconfig similarity index 100% rename from trunk/drivers/watchdog/Kconfig rename to trunk/drivers/char/watchdog/Kconfig diff --git a/trunk/drivers/watchdog/Makefile b/trunk/drivers/char/watchdog/Makefile similarity index 100% rename from trunk/drivers/watchdog/Makefile rename to trunk/drivers/char/watchdog/Makefile diff --git a/trunk/drivers/watchdog/acquirewdt.c b/trunk/drivers/char/watchdog/acquirewdt.c similarity index 100% rename from trunk/drivers/watchdog/acquirewdt.c rename to trunk/drivers/char/watchdog/acquirewdt.c diff --git a/trunk/drivers/watchdog/advantechwdt.c b/trunk/drivers/char/watchdog/advantechwdt.c similarity index 100% rename from trunk/drivers/watchdog/advantechwdt.c rename to trunk/drivers/char/watchdog/advantechwdt.c diff --git a/trunk/drivers/watchdog/alim1535_wdt.c b/trunk/drivers/char/watchdog/alim1535_wdt.c similarity index 100% rename from trunk/drivers/watchdog/alim1535_wdt.c rename to trunk/drivers/char/watchdog/alim1535_wdt.c diff --git a/trunk/drivers/watchdog/alim7101_wdt.c b/trunk/drivers/char/watchdog/alim7101_wdt.c similarity index 100% rename from trunk/drivers/watchdog/alim7101_wdt.c rename to trunk/drivers/char/watchdog/alim7101_wdt.c diff --git a/trunk/drivers/watchdog/at32ap700x_wdt.c b/trunk/drivers/char/watchdog/at32ap700x_wdt.c similarity index 100% rename from trunk/drivers/watchdog/at32ap700x_wdt.c rename to trunk/drivers/char/watchdog/at32ap700x_wdt.c diff --git a/trunk/drivers/watchdog/at91rm9200_wdt.c b/trunk/drivers/char/watchdog/at91rm9200_wdt.c similarity index 99% rename from trunk/drivers/watchdog/at91rm9200_wdt.c rename to trunk/drivers/char/watchdog/at91rm9200_wdt.c index a684b1e87372..38bd37372599 100644 --- a/trunk/drivers/watchdog/at91rm9200_wdt.c +++ b/trunk/drivers/char/watchdog/at91rm9200_wdt.c @@ -9,7 +9,6 @@ * 2 of the License, or (at your option) any later version. */ -#include #include #include #include @@ -20,6 +19,7 @@ #include #include #include +#include #include #include diff --git a/trunk/drivers/watchdog/bfin_wdt.c b/trunk/drivers/char/watchdog/bfin_wdt.c similarity index 100% rename from trunk/drivers/watchdog/bfin_wdt.c rename to trunk/drivers/char/watchdog/bfin_wdt.c diff --git a/trunk/drivers/watchdog/booke_wdt.c b/trunk/drivers/char/watchdog/booke_wdt.c similarity index 100% rename from trunk/drivers/watchdog/booke_wdt.c rename to trunk/drivers/char/watchdog/booke_wdt.c diff --git a/trunk/drivers/watchdog/cpu5wdt.c b/trunk/drivers/char/watchdog/cpu5wdt.c similarity index 100% rename from trunk/drivers/watchdog/cpu5wdt.c rename to trunk/drivers/char/watchdog/cpu5wdt.c diff --git a/trunk/drivers/watchdog/davinci_wdt.c b/trunk/drivers/char/watchdog/davinci_wdt.c similarity index 100% rename from trunk/drivers/watchdog/davinci_wdt.c rename to trunk/drivers/char/watchdog/davinci_wdt.c diff --git a/trunk/drivers/watchdog/ep93xx_wdt.c b/trunk/drivers/char/watchdog/ep93xx_wdt.c similarity index 100% rename from trunk/drivers/watchdog/ep93xx_wdt.c rename to trunk/drivers/char/watchdog/ep93xx_wdt.c diff --git a/trunk/drivers/watchdog/eurotechwdt.c b/trunk/drivers/char/watchdog/eurotechwdt.c similarity index 100% rename from trunk/drivers/watchdog/eurotechwdt.c rename to trunk/drivers/char/watchdog/eurotechwdt.c diff --git a/trunk/drivers/watchdog/i6300esb.c b/trunk/drivers/char/watchdog/i6300esb.c similarity index 100% rename from trunk/drivers/watchdog/i6300esb.c rename to trunk/drivers/char/watchdog/i6300esb.c diff --git a/trunk/drivers/watchdog/iTCO_vendor_support.c b/trunk/drivers/char/watchdog/iTCO_vendor_support.c similarity index 100% rename from trunk/drivers/watchdog/iTCO_vendor_support.c rename to trunk/drivers/char/watchdog/iTCO_vendor_support.c diff --git a/trunk/drivers/watchdog/iTCO_wdt.c b/trunk/drivers/char/watchdog/iTCO_wdt.c similarity index 100% rename from trunk/drivers/watchdog/iTCO_wdt.c rename to trunk/drivers/char/watchdog/iTCO_wdt.c diff --git a/trunk/drivers/watchdog/ib700wdt.c b/trunk/drivers/char/watchdog/ib700wdt.c similarity index 100% rename from trunk/drivers/watchdog/ib700wdt.c rename to trunk/drivers/char/watchdog/ib700wdt.c diff --git a/trunk/drivers/watchdog/ibmasr.c b/trunk/drivers/char/watchdog/ibmasr.c similarity index 100% rename from trunk/drivers/watchdog/ibmasr.c rename to trunk/drivers/char/watchdog/ibmasr.c diff --git a/trunk/drivers/watchdog/indydog.c b/trunk/drivers/char/watchdog/indydog.c similarity index 100% rename from trunk/drivers/watchdog/indydog.c rename to trunk/drivers/char/watchdog/indydog.c diff --git a/trunk/drivers/watchdog/iop_wdt.c b/trunk/drivers/char/watchdog/iop_wdt.c similarity index 100% rename from trunk/drivers/watchdog/iop_wdt.c rename to trunk/drivers/char/watchdog/iop_wdt.c diff --git a/trunk/drivers/watchdog/ixp2000_wdt.c b/trunk/drivers/char/watchdog/ixp2000_wdt.c similarity index 100% rename from trunk/drivers/watchdog/ixp2000_wdt.c rename to trunk/drivers/char/watchdog/ixp2000_wdt.c diff --git a/trunk/drivers/watchdog/ixp4xx_wdt.c b/trunk/drivers/char/watchdog/ixp4xx_wdt.c similarity index 100% rename from trunk/drivers/watchdog/ixp4xx_wdt.c rename to trunk/drivers/char/watchdog/ixp4xx_wdt.c diff --git a/trunk/drivers/watchdog/ks8695_wdt.c b/trunk/drivers/char/watchdog/ks8695_wdt.c similarity index 99% rename from trunk/drivers/watchdog/ks8695_wdt.c rename to trunk/drivers/char/watchdog/ks8695_wdt.c index e3a29c302309..7150fb945eaf 100644 --- a/trunk/drivers/watchdog/ks8695_wdt.c +++ b/trunk/drivers/char/watchdog/ks8695_wdt.c @@ -8,7 +8,6 @@ * published by the Free Software Foundation. */ -#include #include #include #include @@ -19,6 +18,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/watchdog/machzwd.c b/trunk/drivers/char/watchdog/machzwd.c similarity index 100% rename from trunk/drivers/watchdog/machzwd.c rename to trunk/drivers/char/watchdog/machzwd.c diff --git a/trunk/drivers/watchdog/mixcomwd.c b/trunk/drivers/char/watchdog/mixcomwd.c similarity index 100% rename from trunk/drivers/watchdog/mixcomwd.c rename to trunk/drivers/char/watchdog/mixcomwd.c diff --git a/trunk/drivers/watchdog/mpc5200_wdt.c b/trunk/drivers/char/watchdog/mpc5200_wdt.c similarity index 100% rename from trunk/drivers/watchdog/mpc5200_wdt.c rename to trunk/drivers/char/watchdog/mpc5200_wdt.c diff --git a/trunk/drivers/watchdog/mpc83xx_wdt.c b/trunk/drivers/char/watchdog/mpc83xx_wdt.c similarity index 100% rename from trunk/drivers/watchdog/mpc83xx_wdt.c rename to trunk/drivers/char/watchdog/mpc83xx_wdt.c diff --git a/trunk/drivers/watchdog/mpc8xx_wdt.c b/trunk/drivers/char/watchdog/mpc8xx_wdt.c similarity index 100% rename from trunk/drivers/watchdog/mpc8xx_wdt.c rename to trunk/drivers/char/watchdog/mpc8xx_wdt.c diff --git a/trunk/drivers/watchdog/mpcore_wdt.c b/trunk/drivers/char/watchdog/mpcore_wdt.c similarity index 100% rename from trunk/drivers/watchdog/mpcore_wdt.c rename to trunk/drivers/char/watchdog/mpcore_wdt.c diff --git a/trunk/drivers/watchdog/mtx-1_wdt.c b/trunk/drivers/char/watchdog/mtx-1_wdt.c similarity index 100% rename from trunk/drivers/watchdog/mtx-1_wdt.c rename to trunk/drivers/char/watchdog/mtx-1_wdt.c diff --git a/trunk/drivers/watchdog/mv64x60_wdt.c b/trunk/drivers/char/watchdog/mv64x60_wdt.c similarity index 100% rename from trunk/drivers/watchdog/mv64x60_wdt.c rename to trunk/drivers/char/watchdog/mv64x60_wdt.c diff --git a/trunk/drivers/watchdog/omap_wdt.c b/trunk/drivers/char/watchdog/omap_wdt.c similarity index 99% rename from trunk/drivers/watchdog/omap_wdt.c rename to trunk/drivers/char/watchdog/omap_wdt.c index 635ca454f56b..719b066f73c4 100644 --- a/trunk/drivers/watchdog/omap_wdt.c +++ b/trunk/drivers/char/watchdog/omap_wdt.c @@ -39,11 +39,11 @@ #include #include #include -#include #include #include #include +#include #include diff --git a/trunk/drivers/watchdog/omap_wdt.h b/trunk/drivers/char/watchdog/omap_wdt.h similarity index 100% rename from trunk/drivers/watchdog/omap_wdt.h rename to trunk/drivers/char/watchdog/omap_wdt.h diff --git a/trunk/drivers/watchdog/pc87413_wdt.c b/trunk/drivers/char/watchdog/pc87413_wdt.c similarity index 100% rename from trunk/drivers/watchdog/pc87413_wdt.c rename to trunk/drivers/char/watchdog/pc87413_wdt.c diff --git a/trunk/drivers/watchdog/pcwd.c b/trunk/drivers/char/watchdog/pcwd.c similarity index 100% rename from trunk/drivers/watchdog/pcwd.c rename to trunk/drivers/char/watchdog/pcwd.c diff --git a/trunk/drivers/watchdog/pcwd_pci.c b/trunk/drivers/char/watchdog/pcwd_pci.c similarity index 100% rename from trunk/drivers/watchdog/pcwd_pci.c rename to trunk/drivers/char/watchdog/pcwd_pci.c diff --git a/trunk/drivers/watchdog/pcwd_usb.c b/trunk/drivers/char/watchdog/pcwd_usb.c similarity index 100% rename from trunk/drivers/watchdog/pcwd_usb.c rename to trunk/drivers/char/watchdog/pcwd_usb.c diff --git a/trunk/drivers/watchdog/pnx4008_wdt.c b/trunk/drivers/char/watchdog/pnx4008_wdt.c similarity index 100% rename from trunk/drivers/watchdog/pnx4008_wdt.c rename to trunk/drivers/char/watchdog/pnx4008_wdt.c diff --git a/trunk/drivers/watchdog/rm9k_wdt.c b/trunk/drivers/char/watchdog/rm9k_wdt.c similarity index 100% rename from trunk/drivers/watchdog/rm9k_wdt.c rename to trunk/drivers/char/watchdog/rm9k_wdt.c diff --git a/trunk/drivers/watchdog/s3c2410_wdt.c b/trunk/drivers/char/watchdog/s3c2410_wdt.c similarity index 100% rename from trunk/drivers/watchdog/s3c2410_wdt.c rename to trunk/drivers/char/watchdog/s3c2410_wdt.c diff --git a/trunk/drivers/watchdog/sa1100_wdt.c b/trunk/drivers/char/watchdog/sa1100_wdt.c similarity index 99% rename from trunk/drivers/watchdog/sa1100_wdt.c rename to trunk/drivers/char/watchdog/sa1100_wdt.c index 34a2b3b81800..3475f47aaa45 100644 --- a/trunk/drivers/watchdog/sa1100_wdt.c +++ b/trunk/drivers/char/watchdog/sa1100_wdt.c @@ -25,13 +25,13 @@ #include #include #include -#include #ifdef CONFIG_ARCH_PXA #include #endif #include +#include #include #define OSCR_FREQ CLOCK_TICK_RATE diff --git a/trunk/drivers/watchdog/sbc60xxwdt.c b/trunk/drivers/char/watchdog/sbc60xxwdt.c similarity index 100% rename from trunk/drivers/watchdog/sbc60xxwdt.c rename to trunk/drivers/char/watchdog/sbc60xxwdt.c diff --git a/trunk/drivers/watchdog/sbc8360.c b/trunk/drivers/char/watchdog/sbc8360.c similarity index 100% rename from trunk/drivers/watchdog/sbc8360.c rename to trunk/drivers/char/watchdog/sbc8360.c diff --git a/trunk/drivers/watchdog/sbc_epx_c3.c b/trunk/drivers/char/watchdog/sbc_epx_c3.c similarity index 100% rename from trunk/drivers/watchdog/sbc_epx_c3.c rename to trunk/drivers/char/watchdog/sbc_epx_c3.c diff --git a/trunk/drivers/watchdog/sc1200wdt.c b/trunk/drivers/char/watchdog/sc1200wdt.c similarity index 100% rename from trunk/drivers/watchdog/sc1200wdt.c rename to trunk/drivers/char/watchdog/sc1200wdt.c diff --git a/trunk/drivers/watchdog/sc520_wdt.c b/trunk/drivers/char/watchdog/sc520_wdt.c similarity index 100% rename from trunk/drivers/watchdog/sc520_wdt.c rename to trunk/drivers/char/watchdog/sc520_wdt.c diff --git a/trunk/drivers/watchdog/scx200_wdt.c b/trunk/drivers/char/watchdog/scx200_wdt.c similarity index 100% rename from trunk/drivers/watchdog/scx200_wdt.c rename to trunk/drivers/char/watchdog/scx200_wdt.c diff --git a/trunk/drivers/watchdog/shwdt.c b/trunk/drivers/char/watchdog/shwdt.c similarity index 100% rename from trunk/drivers/watchdog/shwdt.c rename to trunk/drivers/char/watchdog/shwdt.c diff --git a/trunk/drivers/watchdog/smsc37b787_wdt.c b/trunk/drivers/char/watchdog/smsc37b787_wdt.c similarity index 100% rename from trunk/drivers/watchdog/smsc37b787_wdt.c rename to trunk/drivers/char/watchdog/smsc37b787_wdt.c diff --git a/trunk/drivers/watchdog/softdog.c b/trunk/drivers/char/watchdog/softdog.c similarity index 100% rename from trunk/drivers/watchdog/softdog.c rename to trunk/drivers/char/watchdog/softdog.c diff --git a/trunk/drivers/watchdog/w83627hf_wdt.c b/trunk/drivers/char/watchdog/w83627hf_wdt.c similarity index 100% rename from trunk/drivers/watchdog/w83627hf_wdt.c rename to trunk/drivers/char/watchdog/w83627hf_wdt.c diff --git a/trunk/drivers/watchdog/w83697hf_wdt.c b/trunk/drivers/char/watchdog/w83697hf_wdt.c similarity index 100% rename from trunk/drivers/watchdog/w83697hf_wdt.c rename to trunk/drivers/char/watchdog/w83697hf_wdt.c diff --git a/trunk/drivers/watchdog/w83877f_wdt.c b/trunk/drivers/char/watchdog/w83877f_wdt.c similarity index 100% rename from trunk/drivers/watchdog/w83877f_wdt.c rename to trunk/drivers/char/watchdog/w83877f_wdt.c diff --git a/trunk/drivers/watchdog/w83977f_wdt.c b/trunk/drivers/char/watchdog/w83977f_wdt.c similarity index 100% rename from trunk/drivers/watchdog/w83977f_wdt.c rename to trunk/drivers/char/watchdog/w83977f_wdt.c diff --git a/trunk/drivers/watchdog/wafer5823wdt.c b/trunk/drivers/char/watchdog/wafer5823wdt.c similarity index 100% rename from trunk/drivers/watchdog/wafer5823wdt.c rename to trunk/drivers/char/watchdog/wafer5823wdt.c diff --git a/trunk/drivers/watchdog/wd501p.h b/trunk/drivers/char/watchdog/wd501p.h similarity index 100% rename from trunk/drivers/watchdog/wd501p.h rename to trunk/drivers/char/watchdog/wd501p.h diff --git a/trunk/drivers/watchdog/wdrtas.c b/trunk/drivers/char/watchdog/wdrtas.c similarity index 100% rename from trunk/drivers/watchdog/wdrtas.c rename to trunk/drivers/char/watchdog/wdrtas.c diff --git a/trunk/drivers/watchdog/wdt.c b/trunk/drivers/char/watchdog/wdt.c similarity index 100% rename from trunk/drivers/watchdog/wdt.c rename to trunk/drivers/char/watchdog/wdt.c diff --git a/trunk/drivers/watchdog/wdt285.c b/trunk/drivers/char/watchdog/wdt285.c similarity index 100% rename from trunk/drivers/watchdog/wdt285.c rename to trunk/drivers/char/watchdog/wdt285.c diff --git a/trunk/drivers/watchdog/wdt977.c b/trunk/drivers/char/watchdog/wdt977.c similarity index 100% rename from trunk/drivers/watchdog/wdt977.c rename to trunk/drivers/char/watchdog/wdt977.c diff --git a/trunk/drivers/watchdog/wdt_pci.c b/trunk/drivers/char/watchdog/wdt_pci.c similarity index 100% rename from trunk/drivers/watchdog/wdt_pci.c rename to trunk/drivers/char/watchdog/wdt_pci.c diff --git a/trunk/drivers/cpuidle/Kconfig b/trunk/drivers/cpuidle/Kconfig deleted file mode 100644 index 3bed4127d4ad..000000000000 --- a/trunk/drivers/cpuidle/Kconfig +++ /dev/null @@ -1,20 +0,0 @@ - -config CPU_IDLE - bool "CPU idle PM support" - help - CPU idle is a generic framework for supporting software-controlled - idle processor power management. It includes modular cross-platform - governors that can be swapped during runtime. - - If you're using a mobile platform that supports CPU idle PM (e.g. - an ACPI-capable notebook), you should say Y here. - -config CPU_IDLE_GOV_LADDER - bool - depends on CPU_IDLE - default y - -config CPU_IDLE_GOV_MENU - bool - depends on CPU_IDLE && NO_HZ - default y diff --git a/trunk/drivers/cpuidle/Makefile b/trunk/drivers/cpuidle/Makefile deleted file mode 100644 index 5634f88379df..000000000000 --- a/trunk/drivers/cpuidle/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# -# Makefile for cpuidle. -# - -obj-y += cpuidle.o driver.o governor.o sysfs.o governors/ diff --git a/trunk/drivers/cpuidle/cpuidle.c b/trunk/drivers/cpuidle/cpuidle.c deleted file mode 100644 index fdf4106b817b..000000000000 --- a/trunk/drivers/cpuidle/cpuidle.c +++ /dev/null @@ -1,295 +0,0 @@ -/* - * cpuidle.c - core cpuidle infrastructure - * - * (C) 2006-2007 Venkatesh Pallipadi - * Shaohua Li - * Adam Belay - * - * This code is licenced under the GPL. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "cpuidle.h" - -DEFINE_PER_CPU(struct cpuidle_device *, cpuidle_devices); -EXPORT_PER_CPU_SYMBOL_GPL(cpuidle_devices); - -DEFINE_MUTEX(cpuidle_lock); -LIST_HEAD(cpuidle_detected_devices); -static void (*pm_idle_old)(void); - -static int enabled_devices; - -/** - * cpuidle_idle_call - the main idle loop - * - * NOTE: no locks or semaphores should be used here - */ -static void cpuidle_idle_call(void) -{ - struct cpuidle_device *dev = __get_cpu_var(cpuidle_devices); - struct cpuidle_state *target_state; - int next_state; - - /* check if the device is ready */ - if (!dev || !dev->enabled) { - if (pm_idle_old) - pm_idle_old(); - else - local_irq_enable(); - return; - } - - /* ask the governor for the next state */ - next_state = cpuidle_curr_governor->select(dev); - if (need_resched()) - return; - target_state = &dev->states[next_state]; - - /* enter the state and update stats */ - dev->last_residency = target_state->enter(dev, target_state); - dev->last_state = target_state; - target_state->time += dev->last_residency; - target_state->usage++; - - /* give the governor an opportunity to reflect on the outcome */ - if (cpuidle_curr_governor->reflect) - cpuidle_curr_governor->reflect(dev); -} - -/** - * cpuidle_install_idle_handler - installs the cpuidle idle loop handler - */ -void cpuidle_install_idle_handler(void) -{ - if (enabled_devices && (pm_idle != cpuidle_idle_call)) { - /* Make sure all changes finished before we switch to new idle */ - smp_wmb(); - pm_idle = cpuidle_idle_call; - } -} - -/** - * cpuidle_uninstall_idle_handler - uninstalls the cpuidle idle loop handler - */ -void cpuidle_uninstall_idle_handler(void) -{ - if (enabled_devices && (pm_idle != pm_idle_old)) { - pm_idle = pm_idle_old; - cpu_idle_wait(); - } -} - -/** - * cpuidle_pause_and_lock - temporarily disables CPUIDLE - */ -void cpuidle_pause_and_lock(void) -{ - mutex_lock(&cpuidle_lock); - cpuidle_uninstall_idle_handler(); -} - -EXPORT_SYMBOL_GPL(cpuidle_pause_and_lock); - -/** - * cpuidle_resume_and_unlock - resumes CPUIDLE operation - */ -void cpuidle_resume_and_unlock(void) -{ - cpuidle_install_idle_handler(); - mutex_unlock(&cpuidle_lock); -} - -EXPORT_SYMBOL_GPL(cpuidle_resume_and_unlock); - -/** - * cpuidle_enable_device - enables idle PM for a CPU - * @dev: the CPU - * - * This function must be called between cpuidle_pause_and_lock and - * cpuidle_resume_and_unlock when used externally. - */ -int cpuidle_enable_device(struct cpuidle_device *dev) -{ - int ret, i; - - if (dev->enabled) - return 0; - if (!cpuidle_curr_driver || !cpuidle_curr_governor) - return -EIO; - if (!dev->state_count) - return -EINVAL; - - if ((ret = cpuidle_add_state_sysfs(dev))) - return ret; - - if (cpuidle_curr_governor->enable && - (ret = cpuidle_curr_governor->enable(dev))) - goto fail_sysfs; - - for (i = 0; i < dev->state_count; i++) { - dev->states[i].usage = 0; - dev->states[i].time = 0; - } - dev->last_residency = 0; - dev->last_state = NULL; - - smp_wmb(); - - dev->enabled = 1; - - enabled_devices++; - return 0; - -fail_sysfs: - cpuidle_remove_state_sysfs(dev); - - return ret; -} - -EXPORT_SYMBOL_GPL(cpuidle_enable_device); - -/** - * cpuidle_disable_device - disables idle PM for a CPU - * @dev: the CPU - * - * This function must be called between cpuidle_pause_and_lock and - * cpuidle_resume_and_unlock when used externally. - */ -void cpuidle_disable_device(struct cpuidle_device *dev) -{ - if (!dev->enabled) - return; - if (!cpuidle_curr_driver || !cpuidle_curr_governor) - return; - - dev->enabled = 0; - - if (cpuidle_curr_governor->disable) - cpuidle_curr_governor->disable(dev); - - cpuidle_remove_state_sysfs(dev); - enabled_devices--; -} - -EXPORT_SYMBOL_GPL(cpuidle_disable_device); - -/** - * cpuidle_register_device - registers a CPU's idle PM feature - * @dev: the cpu - */ -int cpuidle_register_device(struct cpuidle_device *dev) -{ - int ret; - struct sys_device *sys_dev = get_cpu_sysdev((unsigned long)dev->cpu); - - if (!sys_dev) - return -EINVAL; - if (!try_module_get(cpuidle_curr_driver->owner)) - return -EINVAL; - - init_completion(&dev->kobj_unregister); - - mutex_lock(&cpuidle_lock); - - per_cpu(cpuidle_devices, dev->cpu) = dev; - list_add(&dev->device_list, &cpuidle_detected_devices); - if ((ret = cpuidle_add_sysfs(sys_dev))) { - mutex_unlock(&cpuidle_lock); - module_put(cpuidle_curr_driver->owner); - return ret; - } - - cpuidle_enable_device(dev); - cpuidle_install_idle_handler(); - - mutex_unlock(&cpuidle_lock); - - return 0; - -} - -EXPORT_SYMBOL_GPL(cpuidle_register_device); - -/** - * cpuidle_unregister_device - unregisters a CPU's idle PM feature - * @dev: the cpu - */ -void cpuidle_unregister_device(struct cpuidle_device *dev) -{ - struct sys_device *sys_dev = get_cpu_sysdev((unsigned long)dev->cpu); - - cpuidle_pause_and_lock(); - - cpuidle_disable_device(dev); - - cpuidle_remove_sysfs(sys_dev); - list_del(&dev->device_list); - wait_for_completion(&dev->kobj_unregister); - per_cpu(cpuidle_devices, dev->cpu) = NULL; - - cpuidle_resume_and_unlock(); - - module_put(cpuidle_curr_driver->owner); -} - -EXPORT_SYMBOL_GPL(cpuidle_unregister_device); - -#ifdef CONFIG_SMP - -static void smp_callback(void *v) -{ - /* we already woke the CPU up, nothing more to do */ -} - -/* - * This function gets called when a part of the kernel has a new latency - * requirement. This means we need to get all processors out of their C-state, - * and then recalculate a new suitable C-state. Just do a cross-cpu IPI; that - * wakes them all right up. - */ -static int cpuidle_latency_notify(struct notifier_block *b, - unsigned long l, void *v) -{ - smp_call_function(smp_callback, NULL, 0, 1); - return NOTIFY_OK; -} - -static struct notifier_block cpuidle_latency_notifier = { - .notifier_call = cpuidle_latency_notify, -}; - -#define latency_notifier_init(x) do { register_latency_notifier(x); } while (0) - -#else /* CONFIG_SMP */ - -#define latency_notifier_init(x) do { } while (0) - -#endif /* CONFIG_SMP */ - -/** - * cpuidle_init - core initializer - */ -static int __init cpuidle_init(void) -{ - int ret; - - pm_idle_old = pm_idle; - - ret = cpuidle_add_class_sysfs(&cpu_sysdev_class); - if (ret) - return ret; - - latency_notifier_init(&cpuidle_latency_notifier); - - return 0; -} - -core_initcall(cpuidle_init); diff --git a/trunk/drivers/cpuidle/cpuidle.h b/trunk/drivers/cpuidle/cpuidle.h deleted file mode 100644 index 9476ba33ee2c..000000000000 --- a/trunk/drivers/cpuidle/cpuidle.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * cpuidle.h - The internal header file - */ - -#ifndef __DRIVER_CPUIDLE_H -#define __DRIVER_CPUIDLE_H - -#include - -/* For internal use only */ -extern struct cpuidle_governor *cpuidle_curr_governor; -extern struct cpuidle_driver *cpuidle_curr_driver; -extern struct list_head cpuidle_governors; -extern struct list_head cpuidle_detected_devices; -extern struct mutex cpuidle_lock; -extern spinlock_t cpuidle_driver_lock; - -/* idle loop */ -extern void cpuidle_install_idle_handler(void); -extern void cpuidle_uninstall_idle_handler(void); - -/* governors */ -extern int cpuidle_switch_governor(struct cpuidle_governor *gov); - -/* sysfs */ -extern int cpuidle_add_class_sysfs(struct sysdev_class *cls); -extern void cpuidle_remove_class_sysfs(struct sysdev_class *cls); -extern int cpuidle_add_state_sysfs(struct cpuidle_device *device); -extern void cpuidle_remove_state_sysfs(struct cpuidle_device *device); -extern int cpuidle_add_sysfs(struct sys_device *sysdev); -extern void cpuidle_remove_sysfs(struct sys_device *sysdev); - -#endif /* __DRIVER_CPUIDLE_H */ diff --git a/trunk/drivers/cpuidle/driver.c b/trunk/drivers/cpuidle/driver.c deleted file mode 100644 index 2257004fe33d..000000000000 --- a/trunk/drivers/cpuidle/driver.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * driver.c - driver support - * - * (C) 2006-2007 Venkatesh Pallipadi - * Shaohua Li - * Adam Belay - * - * This code is licenced under the GPL. - */ - -#include -#include -#include - -#include "cpuidle.h" - -struct cpuidle_driver *cpuidle_curr_driver; -DEFINE_SPINLOCK(cpuidle_driver_lock); - -/** - * cpuidle_register_driver - registers a driver - * @drv: the driver - */ -int cpuidle_register_driver(struct cpuidle_driver *drv) -{ - if (!drv) - return -EINVAL; - - spin_lock(&cpuidle_driver_lock); - if (cpuidle_curr_driver) { - spin_unlock(&cpuidle_driver_lock); - return -EBUSY; - } - cpuidle_curr_driver = drv; - spin_unlock(&cpuidle_driver_lock); - - return 0; -} - -EXPORT_SYMBOL_GPL(cpuidle_register_driver); - -/** - * cpuidle_unregister_driver - unregisters a driver - * @drv: the driver - */ -void cpuidle_unregister_driver(struct cpuidle_driver *drv) -{ - if (!drv) - return; - - spin_lock(&cpuidle_driver_lock); - cpuidle_curr_driver = NULL; - spin_unlock(&cpuidle_driver_lock); -} - -EXPORT_SYMBOL_GPL(cpuidle_unregister_driver); diff --git a/trunk/drivers/cpuidle/governor.c b/trunk/drivers/cpuidle/governor.c deleted file mode 100644 index bb699cb2dc5a..000000000000 --- a/trunk/drivers/cpuidle/governor.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - * governor.c - governor support - * - * (C) 2006-2007 Venkatesh Pallipadi - * Shaohua Li - * Adam Belay - * - * This code is licenced under the GPL. - */ - -#include -#include -#include - -#include "cpuidle.h" - -LIST_HEAD(cpuidle_governors); -struct cpuidle_governor *cpuidle_curr_governor; - -/** - * __cpuidle_find_governor - finds a governor of the specified name - * @str: the name - * - * Must be called with cpuidle_lock aquired. - */ -static struct cpuidle_governor * __cpuidle_find_governor(const char *str) -{ - struct cpuidle_governor *gov; - - list_for_each_entry(gov, &cpuidle_governors, governor_list) - if (!strnicmp(str, gov->name, CPUIDLE_NAME_LEN)) - return gov; - - return NULL; -} - -/** - * cpuidle_switch_governor - changes the governor - * @gov: the new target governor - * - * NOTE: "gov" can be NULL to specify disabled - * Must be called with cpuidle_lock aquired. - */ -int cpuidle_switch_governor(struct cpuidle_governor *gov) -{ - struct cpuidle_device *dev; - - if (gov == cpuidle_curr_governor) - return 0; - - cpuidle_uninstall_idle_handler(); - - if (cpuidle_curr_governor) { - list_for_each_entry(dev, &cpuidle_detected_devices, device_list) - cpuidle_disable_device(dev); - module_put(cpuidle_curr_governor->owner); - } - - cpuidle_curr_governor = gov; - - if (gov) { - if (!try_module_get(cpuidle_curr_governor->owner)) - return -EINVAL; - list_for_each_entry(dev, &cpuidle_detected_devices, device_list) - cpuidle_enable_device(dev); - cpuidle_install_idle_handler(); - printk(KERN_INFO "cpuidle: using governor %s\n", gov->name); - } - - return 0; -} - -/** - * cpuidle_register_governor - registers a governor - * @gov: the governor - */ -int cpuidle_register_governor(struct cpuidle_governor *gov) -{ - int ret = -EEXIST; - - if (!gov || !gov->select) - return -EINVAL; - - mutex_lock(&cpuidle_lock); - if (__cpuidle_find_governor(gov->name) == NULL) { - ret = 0; - list_add_tail(&gov->governor_list, &cpuidle_governors); - if (!cpuidle_curr_governor || - cpuidle_curr_governor->rating < gov->rating) - cpuidle_switch_governor(gov); - } - mutex_unlock(&cpuidle_lock); - - return ret; -} - -EXPORT_SYMBOL_GPL(cpuidle_register_governor); - -/** - * cpuidle_replace_governor - find a replacement governor - * @exclude_rating: the rating that will be skipped while looking for - * new governor. - */ -static struct cpuidle_governor *cpuidle_replace_governor(int exclude_rating) -{ - struct cpuidle_governor *gov; - struct cpuidle_governor *ret_gov = NULL; - unsigned int max_rating = 0; - - list_for_each_entry(gov, &cpuidle_governors, governor_list) { - if (gov->rating == exclude_rating) - continue; - if (gov->rating > max_rating) { - max_rating = gov->rating; - ret_gov = gov; - } - } - - return ret_gov; -} - -/** - * cpuidle_unregister_governor - unregisters a governor - * @gov: the governor - */ -void cpuidle_unregister_governor(struct cpuidle_governor *gov) -{ - if (!gov) - return; - - mutex_lock(&cpuidle_lock); - if (gov == cpuidle_curr_governor) { - struct cpuidle_governor *new_gov; - new_gov = cpuidle_replace_governor(gov->rating); - cpuidle_switch_governor(new_gov); - } - list_del(&gov->governor_list); - mutex_unlock(&cpuidle_lock); -} - -EXPORT_SYMBOL_GPL(cpuidle_unregister_governor); diff --git a/trunk/drivers/cpuidle/governors/Makefile b/trunk/drivers/cpuidle/governors/Makefile deleted file mode 100644 index 1b512722689f..000000000000 --- a/trunk/drivers/cpuidle/governors/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# -# Makefile for cpuidle governors. -# - -obj-$(CONFIG_CPU_IDLE_GOV_LADDER) += ladder.o -obj-$(CONFIG_CPU_IDLE_GOV_MENU) += menu.o diff --git a/trunk/drivers/cpuidle/governors/ladder.c b/trunk/drivers/cpuidle/governors/ladder.c deleted file mode 100644 index eb666ecae7c9..000000000000 --- a/trunk/drivers/cpuidle/governors/ladder.c +++ /dev/null @@ -1,166 +0,0 @@ -/* - * ladder.c - the residency ladder algorithm - * - * Copyright (C) 2001, 2002 Andy Grover - * Copyright (C) 2001, 2002 Paul Diefenbaugh - * Copyright (C) 2004, 2005 Dominik Brodowski - * - * (C) 2006-2007 Venkatesh Pallipadi - * Shaohua Li - * Adam Belay - * - * This code is licenced under the GPL. - */ - -#include -#include -#include -#include -#include - -#include -#include - -#define PROMOTION_COUNT 4 -#define DEMOTION_COUNT 1 - -struct ladder_device_state { - struct { - u32 promotion_count; - u32 demotion_count; - u32 promotion_time; - u32 demotion_time; - } threshold; - struct { - int promotion_count; - int demotion_count; - } stats; -}; - -struct ladder_device { - struct ladder_device_state states[CPUIDLE_STATE_MAX]; - int last_state_idx; -}; - -static DEFINE_PER_CPU(struct ladder_device, ladder_devices); - -/** - * ladder_do_selection - prepares private data for a state change - * @ldev: the ladder device - * @old_idx: the current state index - * @new_idx: the new target state index - */ -static inline void ladder_do_selection(struct ladder_device *ldev, - int old_idx, int new_idx) -{ - ldev->states[old_idx].stats.promotion_count = 0; - ldev->states[old_idx].stats.demotion_count = 0; - ldev->last_state_idx = new_idx; -} - -/** - * ladder_select_state - selects the next state to enter - * @dev: the CPU - */ -static int ladder_select_state(struct cpuidle_device *dev) -{ - struct ladder_device *ldev = &__get_cpu_var(ladder_devices); - struct ladder_device_state *last_state; - int last_residency, last_idx = ldev->last_state_idx; - - if (unlikely(!ldev)) - return 0; - - last_state = &ldev->states[last_idx]; - - if (dev->states[last_idx].flags & CPUIDLE_FLAG_TIME_VALID) - last_residency = cpuidle_get_last_residency(dev) - dev->states[last_idx].exit_latency; - else - last_residency = last_state->threshold.promotion_time + 1; - - /* consider promotion */ - if (last_idx < dev->state_count - 1 && - last_residency > last_state->threshold.promotion_time && - dev->states[last_idx + 1].exit_latency <= system_latency_constraint()) { - last_state->stats.promotion_count++; - last_state->stats.demotion_count = 0; - if (last_state->stats.promotion_count >= last_state->threshold.promotion_count) { - ladder_do_selection(ldev, last_idx, last_idx + 1); - return last_idx + 1; - } - } - - /* consider demotion */ - if (last_idx > 0 && - last_residency < last_state->threshold.demotion_time) { - last_state->stats.demotion_count++; - last_state->stats.promotion_count = 0; - if (last_state->stats.demotion_count >= last_state->threshold.demotion_count) { - ladder_do_selection(ldev, last_idx, last_idx - 1); - return last_idx - 1; - } - } - - /* otherwise remain at the current state */ - return last_idx; -} - -/** - * ladder_enable_device - setup for the governor - * @dev: the CPU - */ -static int ladder_enable_device(struct cpuidle_device *dev) -{ - int i; - struct ladder_device *ldev = &per_cpu(ladder_devices, dev->cpu); - struct ladder_device_state *lstate; - struct cpuidle_state *state; - - ldev->last_state_idx = 0; - - for (i = 0; i < dev->state_count; i++) { - state = &dev->states[i]; - lstate = &ldev->states[i]; - - lstate->stats.promotion_count = 0; - lstate->stats.demotion_count = 0; - - lstate->threshold.promotion_count = PROMOTION_COUNT; - lstate->threshold.demotion_count = DEMOTION_COUNT; - - if (i < dev->state_count - 1) - lstate->threshold.promotion_time = state->exit_latency; - if (i > 0) - lstate->threshold.demotion_time = state->exit_latency; - } - - return 0; -} - -static struct cpuidle_governor ladder_governor = { - .name = "ladder", - .rating = 10, - .enable = ladder_enable_device, - .select = ladder_select_state, - .owner = THIS_MODULE, -}; - -/** - * init_ladder - initializes the governor - */ -static int __init init_ladder(void) -{ - return cpuidle_register_governor(&ladder_governor); -} - -/** - * exit_ladder - exits the governor - */ -static void __exit exit_ladder(void) -{ - cpuidle_unregister_governor(&ladder_governor); -} - -MODULE_LICENSE("GPL"); -module_init(init_ladder); -module_exit(exit_ladder); diff --git a/trunk/drivers/cpuidle/governors/menu.c b/trunk/drivers/cpuidle/governors/menu.c deleted file mode 100644 index 299d45c3bdd2..000000000000 --- a/trunk/drivers/cpuidle/governors/menu.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * menu.c - the menu idle governor - * - * Copyright (C) 2006-2007 Adam Belay - * - * This code is licenced under the GPL. - */ - -#include -#include -#include -#include -#include -#include -#include - -#define BREAK_FUZZ 4 /* 4 us */ - -struct menu_device { - int last_state_idx; - - unsigned int expected_us; - unsigned int predicted_us; - unsigned int last_measured_us; - unsigned int elapsed_us; -}; - -static DEFINE_PER_CPU(struct menu_device, menu_devices); - -/** - * menu_select - selects the next idle state to enter - * @dev: the CPU - */ -static int menu_select(struct cpuidle_device *dev) -{ - struct menu_device *data = &__get_cpu_var(menu_devices); - int i; - - /* determine the expected residency time */ - data->expected_us = - (u32) ktime_to_ns(tick_nohz_get_sleep_length()) / 1000; - - /* find the deepest idle state that satisfies our constraints */ - for (i = 1; i < dev->state_count; i++) { - struct cpuidle_state *s = &dev->states[i]; - - if (s->target_residency > data->expected_us) - break; - if (s->target_residency > data->predicted_us) - break; - if (s->exit_latency > system_latency_constraint()) - break; - } - - data->last_state_idx = i - 1; - return i - 1; -} - -/** - * menu_reflect - attempts to guess what happened after entry - * @dev: the CPU - * - * NOTE: it's important to be fast here because this operation will add to - * the overall exit latency. - */ -static void menu_reflect(struct cpuidle_device *dev) -{ - struct menu_device *data = &__get_cpu_var(menu_devices); - int last_idx = data->last_state_idx; - unsigned int measured_us = - cpuidle_get_last_residency(dev) + data->elapsed_us; - struct cpuidle_state *target = &dev->states[last_idx]; - - /* - * Ugh, this idle state doesn't support residency measurements, so we - * are basically lost in the dark. As a compromise, assume we slept - * for one full standard timer tick. However, be aware that this - * could potentially result in a suboptimal state transition. - */ - if (!(target->flags & CPUIDLE_FLAG_TIME_VALID)) - measured_us = USEC_PER_SEC / HZ; - - /* Predict time remaining until next break event */ - if (measured_us + BREAK_FUZZ < data->expected_us - target->exit_latency) { - data->predicted_us = max(measured_us, data->last_measured_us); - data->last_measured_us = measured_us; - data->elapsed_us = 0; - } else { - if (data->elapsed_us < data->elapsed_us + measured_us) - data->elapsed_us = measured_us; - else - data->elapsed_us = -1; - data->predicted_us = max(measured_us, data->last_measured_us); - } -} - -/** - * menu_enable_device - scans a CPU's states and does setup - * @dev: the CPU - */ -static int menu_enable_device(struct cpuidle_device *dev) -{ - struct menu_device *data = &per_cpu(menu_devices, dev->cpu); - - memset(data, 0, sizeof(struct menu_device)); - - return 0; -} - -static struct cpuidle_governor menu_governor = { - .name = "menu", - .rating = 20, - .enable = menu_enable_device, - .select = menu_select, - .reflect = menu_reflect, - .owner = THIS_MODULE, -}; - -/** - * init_menu - initializes the governor - */ -static int __init init_menu(void) -{ - return cpuidle_register_governor(&menu_governor); -} - -/** - * exit_menu - exits the governor - */ -static void __exit exit_menu(void) -{ - cpuidle_unregister_governor(&menu_governor); -} - -MODULE_LICENSE("GPL"); -module_init(init_menu); -module_exit(exit_menu); diff --git a/trunk/drivers/cpuidle/sysfs.c b/trunk/drivers/cpuidle/sysfs.c deleted file mode 100644 index 0f3515e77d4b..000000000000 --- a/trunk/drivers/cpuidle/sysfs.c +++ /dev/null @@ -1,361 +0,0 @@ -/* - * sysfs.c - sysfs support - * - * (C) 2006-2007 Shaohua Li - * - * This code is licenced under the GPL. - */ - -#include -#include -#include -#include - -#include "cpuidle.h" - -static unsigned int sysfs_switch; -static int __init cpuidle_sysfs_setup(char *unused) -{ - sysfs_switch = 1; - return 1; -} -__setup("cpuidle_sysfs_switch", cpuidle_sysfs_setup); - -static ssize_t show_available_governors(struct sys_device *dev, char *buf) -{ - ssize_t i = 0; - struct cpuidle_governor *tmp; - - mutex_lock(&cpuidle_lock); - list_for_each_entry(tmp, &cpuidle_governors, governor_list) { - if (i >= (ssize_t) ((PAGE_SIZE/sizeof(char)) - CPUIDLE_NAME_LEN - 2)) - goto out; - i += scnprintf(&buf[i], CPUIDLE_NAME_LEN, "%s ", tmp->name); - } - -out: - i+= sprintf(&buf[i], "\n"); - mutex_unlock(&cpuidle_lock); - return i; -} - -static ssize_t show_current_driver(struct sys_device *dev, char *buf) -{ - ssize_t ret; - - spin_lock(&cpuidle_driver_lock); - if (cpuidle_curr_driver) - ret = sprintf(buf, "%s\n", cpuidle_curr_driver->name); - else - ret = sprintf(buf, "none\n"); - spin_unlock(&cpuidle_driver_lock); - - return ret; -} - -static ssize_t show_current_governor(struct sys_device *dev, char *buf) -{ - ssize_t ret; - - mutex_lock(&cpuidle_lock); - if (cpuidle_curr_governor) - ret = sprintf(buf, "%s\n", cpuidle_curr_governor->name); - else - ret = sprintf(buf, "none\n"); - mutex_unlock(&cpuidle_lock); - - return ret; -} - -static ssize_t store_current_governor(struct sys_device *dev, - const char *buf, size_t count) -{ - char gov_name[CPUIDLE_NAME_LEN]; - int ret = -EINVAL; - size_t len = count; - struct cpuidle_governor *gov; - - if (!len || len >= sizeof(gov_name)) - return -EINVAL; - - memcpy(gov_name, buf, len); - gov_name[len] = '\0'; - if (gov_name[len - 1] == '\n') - gov_name[--len] = '\0'; - - mutex_lock(&cpuidle_lock); - - list_for_each_entry(gov, &cpuidle_governors, governor_list) { - if (strlen(gov->name) == len && !strcmp(gov->name, gov_name)) { - ret = cpuidle_switch_governor(gov); - break; - } - } - - mutex_unlock(&cpuidle_lock); - - if (ret) - return ret; - else - return count; -} - -static SYSDEV_ATTR(current_driver, 0444, show_current_driver, NULL); -static SYSDEV_ATTR(current_governor_ro, 0444, show_current_governor, NULL); - -static struct attribute *cpuclass_default_attrs[] = { - &attr_current_driver.attr, - &attr_current_governor_ro.attr, - NULL -}; - -static SYSDEV_ATTR(available_governors, 0444, show_available_governors, NULL); -static SYSDEV_ATTR(current_governor, 0644, show_current_governor, - store_current_governor); - -static struct attribute *cpuclass_switch_attrs[] = { - &attr_available_governors.attr, - &attr_current_driver.attr, - &attr_current_governor.attr, - NULL -}; - -static struct attribute_group cpuclass_attr_group = { - .attrs = cpuclass_default_attrs, - .name = "cpuidle", -}; - -/** - * cpuidle_add_class_sysfs - add CPU global sysfs attributes - */ -int cpuidle_add_class_sysfs(struct sysdev_class *cls) -{ - if (sysfs_switch) - cpuclass_attr_group.attrs = cpuclass_switch_attrs; - - return sysfs_create_group(&cls->kset.kobj, &cpuclass_attr_group); -} - -/** - * cpuidle_remove_class_sysfs - remove CPU global sysfs attributes - */ -void cpuidle_remove_class_sysfs(struct sysdev_class *cls) -{ - sysfs_remove_group(&cls->kset.kobj, &cpuclass_attr_group); -} - -struct cpuidle_attr { - struct attribute attr; - ssize_t (*show)(struct cpuidle_device *, char *); - ssize_t (*store)(struct cpuidle_device *, const char *, size_t count); -}; - -#define define_one_ro(_name, show) \ - static struct cpuidle_attr attr_##_name = __ATTR(_name, 0444, show, NULL) -#define define_one_rw(_name, show, store) \ - static struct cpuidle_attr attr_##_name = __ATTR(_name, 0644, show, store) - -#define kobj_to_cpuidledev(k) container_of(k, struct cpuidle_device, kobj) -#define attr_to_cpuidleattr(a) container_of(a, struct cpuidle_attr, attr) -static ssize_t cpuidle_show(struct kobject * kobj, struct attribute * attr ,char * buf) -{ - int ret = -EIO; - struct cpuidle_device *dev = kobj_to_cpuidledev(kobj); - struct cpuidle_attr * cattr = attr_to_cpuidleattr(attr); - - if (cattr->show) { - mutex_lock(&cpuidle_lock); - ret = cattr->show(dev, buf); - mutex_unlock(&cpuidle_lock); - } - return ret; -} - -static ssize_t cpuidle_store(struct kobject * kobj, struct attribute * attr, - const char * buf, size_t count) -{ - int ret = -EIO; - struct cpuidle_device *dev = kobj_to_cpuidledev(kobj); - struct cpuidle_attr * cattr = attr_to_cpuidleattr(attr); - - if (cattr->store) { - mutex_lock(&cpuidle_lock); - ret = cattr->store(dev, buf, count); - mutex_unlock(&cpuidle_lock); - } - return ret; -} - -static struct sysfs_ops cpuidle_sysfs_ops = { - .show = cpuidle_show, - .store = cpuidle_store, -}; - -static void cpuidle_sysfs_release(struct kobject *kobj) -{ - struct cpuidle_device *dev = kobj_to_cpuidledev(kobj); - - complete(&dev->kobj_unregister); -} - -static struct kobj_type ktype_cpuidle = { - .sysfs_ops = &cpuidle_sysfs_ops, - .release = cpuidle_sysfs_release, -}; - -struct cpuidle_state_attr { - struct attribute attr; - ssize_t (*show)(struct cpuidle_state *, char *); - ssize_t (*store)(struct cpuidle_state *, const char *, size_t); -}; - -#define define_one_state_ro(_name, show) \ -static struct cpuidle_state_attr attr_##_name = __ATTR(_name, 0444, show, NULL) - -#define define_show_state_function(_name) \ -static ssize_t show_state_##_name(struct cpuidle_state *state, char *buf) \ -{ \ - return sprintf(buf, "%u\n", state->_name);\ -} - -static ssize_t show_state_name(struct cpuidle_state *state, char *buf) -{ - return sprintf(buf, "%s\n", state->name); -} - -define_show_state_function(exit_latency) -define_show_state_function(power_usage) -define_show_state_function(usage) -define_show_state_function(time) -define_one_state_ro(name, show_state_name); -define_one_state_ro(latency, show_state_exit_latency); -define_one_state_ro(power, show_state_power_usage); -define_one_state_ro(usage, show_state_usage); -define_one_state_ro(time, show_state_time); - -static struct attribute *cpuidle_state_default_attrs[] = { - &attr_name.attr, - &attr_latency.attr, - &attr_power.attr, - &attr_usage.attr, - &attr_time.attr, - NULL -}; - -#define kobj_to_state_obj(k) container_of(k, struct cpuidle_state_kobj, kobj) -#define kobj_to_state(k) (kobj_to_state_obj(k)->state) -#define attr_to_stateattr(a) container_of(a, struct cpuidle_state_attr, attr) -static ssize_t cpuidle_state_show(struct kobject * kobj, - struct attribute * attr ,char * buf) -{ - int ret = -EIO; - struct cpuidle_state *state = kobj_to_state(kobj); - struct cpuidle_state_attr * cattr = attr_to_stateattr(attr); - - if (cattr->show) - ret = cattr->show(state, buf); - - return ret; -} - -static struct sysfs_ops cpuidle_state_sysfs_ops = { - .show = cpuidle_state_show, -}; - -static void cpuidle_state_sysfs_release(struct kobject *kobj) -{ - struct cpuidle_state_kobj *state_obj = kobj_to_state_obj(kobj); - - complete(&state_obj->kobj_unregister); -} - -static struct kobj_type ktype_state_cpuidle = { - .sysfs_ops = &cpuidle_state_sysfs_ops, - .default_attrs = cpuidle_state_default_attrs, - .release = cpuidle_state_sysfs_release, -}; - -static void inline cpuidle_free_state_kobj(struct cpuidle_device *device, int i) -{ - kobject_unregister(&device->kobjs[i]->kobj); - wait_for_completion(&device->kobjs[i]->kobj_unregister); - kfree(device->kobjs[i]); - device->kobjs[i] = NULL; -} - -/** - * cpuidle_add_driver_sysfs - adds driver-specific sysfs attributes - * @device: the target device - */ -int cpuidle_add_state_sysfs(struct cpuidle_device *device) -{ - int i, ret = -ENOMEM; - struct cpuidle_state_kobj *kobj; - - /* state statistics */ - for (i = 0; i < device->state_count; i++) { - kobj = kzalloc(sizeof(struct cpuidle_state_kobj), GFP_KERNEL); - if (!kobj) - goto error_state; - kobj->state = &device->states[i]; - init_completion(&kobj->kobj_unregister); - - kobj->kobj.parent = &device->kobj; - kobj->kobj.ktype = &ktype_state_cpuidle; - kobject_set_name(&kobj->kobj, "state%d", i); - ret = kobject_register(&kobj->kobj); - if (ret) { - kfree(kobj); - goto error_state; - } - device->kobjs[i] = kobj; - } - - return 0; - -error_state: - for (i = i - 1; i >= 0; i--) - cpuidle_free_state_kobj(device, i); - return ret; -} - -/** - * cpuidle_remove_driver_sysfs - removes driver-specific sysfs attributes - * @device: the target device - */ -void cpuidle_remove_state_sysfs(struct cpuidle_device *device) -{ - int i; - - for (i = 0; i < device->state_count; i++) - cpuidle_free_state_kobj(device, i); -} - -/** - * cpuidle_add_sysfs - creates a sysfs instance for the target device - * @sysdev: the target device - */ -int cpuidle_add_sysfs(struct sys_device *sysdev) -{ - int cpu = sysdev->id; - struct cpuidle_device *dev; - - dev = per_cpu(cpuidle_devices, cpu); - dev->kobj.parent = &sysdev->kobj; - dev->kobj.ktype = &ktype_cpuidle; - kobject_set_name(&dev->kobj, "%s", "cpuidle"); - return kobject_register(&dev->kobj); -} - -/** - * cpuidle_remove_sysfs - deletes a sysfs instance on the target device - * @sysdev: the target device - */ -void cpuidle_remove_sysfs(struct sys_device *sysdev) -{ - int cpu = sysdev->id; - struct cpuidle_device *dev; - - dev = per_cpu(cpuidle_devices, cpu); - kobject_unregister(&dev->kobj); -} diff --git a/trunk/drivers/dma/ioat.c b/trunk/drivers/dma/ioat.c index f204c39fb412..f7276bf2fe7e 100644 --- a/trunk/drivers/dma/ioat.c +++ b/trunk/drivers/dma/ioat.c @@ -34,7 +34,7 @@ #include "ioatdma_registers.h" #include "ioatdma_hw.h" -MODULE_VERSION(IOAT_DMA_VERSION); +MODULE_VERSION("1.24"); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Intel Corporation"); @@ -55,7 +55,9 @@ struct ioat_device { static int __devinit ioat_probe(struct pci_dev *pdev, const struct pci_device_id *id); +#ifdef IOAT_DMA_REMOVE static void __devexit ioat_remove(struct pci_dev *pdev); +#endif static int ioat_dca_enabled = 1; module_param(ioat_dca_enabled, int, 0644); @@ -71,7 +73,7 @@ static int ioat_setup_functionality(struct pci_dev *pdev, void __iomem *iobase) switch (version) { case IOAT_VER_1_2: device->dma = ioat_dma_probe(pdev, iobase); - if (device->dma && ioat_dca_enabled) + if (ioat_dca_enabled) device->dca = ioat_dca_init(pdev, iobase); break; default: @@ -85,25 +87,27 @@ static void ioat_shutdown_functionality(struct pci_dev *pdev) { struct ioat_device *device = pci_get_drvdata(pdev); - dev_err(&pdev->dev, "Removing dma and dca services\n"); + if (device->dma) { + ioat_dma_remove(device->dma); + device->dma = NULL; + } + if (device->dca) { unregister_dca_provider(device->dca); free_dca_provider(device->dca); device->dca = NULL; } - if (device->dma) { - ioat_dma_remove(device->dma); - device->dma = NULL; - } } -static struct pci_driver ioat_pci_driver = { +static struct pci_driver ioat_pci_drv = { .name = "ioatdma", .id_table = ioat_pci_tbl, .probe = ioat_probe, .shutdown = ioat_shutdown_functionality, +#ifdef IOAT_DMA_REMOVE .remove = __devexit_p(ioat_remove), +#endif }; static int __devinit ioat_probe(struct pci_dev *pdev, @@ -118,7 +122,7 @@ static int __devinit ioat_probe(struct pci_dev *pdev, if (err) goto err_enable_device; - err = pci_request_regions(pdev, ioat_pci_driver.name); + err = pci_request_regions(pdev, ioat_pci_drv.name); if (err) goto err_request_regions; @@ -172,11 +176,13 @@ static int __devinit ioat_probe(struct pci_dev *pdev, return err; } +#ifdef IOAT_DMA_REMOVE /* * It is unsafe to remove this module: if removed while a requested * dma is outstanding, esp. from tcp, it is possible to hang while - * waiting for something that will never finish. However, if you're - * feeling lucky, this usually works just fine. + * waiting for something that will never finish, thus hanging at + * least one cpu. However, if you're feeling lucky and need to do + * some testing, this usually works just fine. */ static void __devexit ioat_remove(struct pci_dev *pdev) { @@ -185,16 +191,21 @@ static void __devexit ioat_remove(struct pci_dev *pdev) ioat_shutdown_functionality(pdev); kfree(device); + + iounmap(device->iobase); + pci_release_regions(pdev); + pci_disable_device(pdev); } +#endif static int __init ioat_init_module(void) { - return pci_register_driver(&ioat_pci_driver); + return pci_register_driver(&ioat_pci_drv); } module_init(ioat_init_module); static void __exit ioat_exit_module(void) { - pci_unregister_driver(&ioat_pci_driver); + pci_unregister_driver(&ioat_pci_drv); } module_exit(ioat_exit_module); diff --git a/trunk/drivers/dma/ioat_dca.c b/trunk/drivers/dma/ioat_dca.c index ba985715b803..2ae04c30edeb 100644 --- a/trunk/drivers/dma/ioat_dca.c +++ b/trunk/drivers/dma/ioat_dca.c @@ -65,7 +65,7 @@ static inline u16 dcaid_from_pcidev(struct pci_dev *pci) return (pci->bus->number << 8) | pci->devfn; } -static int dca_enabled_in_bios(struct pci_dev *pdev) +static int dca_enabled_in_bios(void) { /* CPUID level 9 returns DCA configuration */ /* Bit 0 indicates DCA enabled by the BIOS */ @@ -75,17 +75,17 @@ static int dca_enabled_in_bios(struct pci_dev *pdev) cpuid_level_9 = cpuid_eax(9); res = test_bit(0, &cpuid_level_9); if (!res) - dev_err(&pdev->dev, "DCA is disabled in BIOS\n"); + printk(KERN_ERR "ioat dma: DCA is disabled in BIOS\n"); return res; } -static int system_has_dca_enabled(struct pci_dev *pdev) +static int system_has_dca_enabled(void) { if (boot_cpu_has(X86_FEATURE_DCA)) - return dca_enabled_in_bios(pdev); + return dca_enabled_in_bios(); - dev_err(&pdev->dev, "boot cpu doesn't have X86_FEATURE_DCA\n"); + printk(KERN_ERR "ioat dma: boot cpu doesn't have X86_FEATURE_DCA\n"); return 0; } @@ -208,7 +208,7 @@ struct dca_provider *ioat_dca_init(struct pci_dev *pdev, void __iomem *iobase) int i; int err; - if (!system_has_dca_enabled(pdev)) + if (!system_has_dca_enabled()) return NULL; /* I/OAT v1 systems must have a known tag_map to support DCA */ diff --git a/trunk/drivers/dma/ioat_dma.c b/trunk/drivers/dma/ioat_dma.c index 7e4a785c2dff..66c5bb53211b 100644 --- a/trunk/drivers/dma/ioat_dma.c +++ b/trunk/drivers/dma/ioat_dma.c @@ -46,12 +46,9 @@ /* internal functions */ static void ioat_dma_start_null_desc(struct ioat_dma_chan *ioat_chan); static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *ioat_chan); -static struct ioat_desc_sw * -ioat_dma_get_next_descriptor(struct ioat_dma_chan *ioat_chan); -static inline struct ioat_dma_chan *ioat_lookup_chan_by_index( - struct ioatdma_device *device, - int index) +static struct ioat_dma_chan *ioat_lookup_chan_by_index(struct ioatdma_device *device, + int index) { return device->idx[index]; } @@ -151,102 +148,57 @@ static void ioat_set_src(dma_addr_t addr, struct dma_async_tx_descriptor *tx, int index) { - tx_to_ioat_desc(tx)->src = addr; + struct ioat_desc_sw *iter, *desc = tx_to_ioat_desc(tx); + struct ioat_dma_chan *ioat_chan = to_ioat_chan(tx->chan); + + pci_unmap_addr_set(desc, src, addr); + + list_for_each_entry(iter, &desc->async_tx.tx_list, node) { + iter->hw->src_addr = addr; + addr += ioat_chan->xfercap; + } + } static void ioat_set_dest(dma_addr_t addr, struct dma_async_tx_descriptor *tx, int index) { - tx_to_ioat_desc(tx)->dst = addr; + struct ioat_desc_sw *iter, *desc = tx_to_ioat_desc(tx); + struct ioat_dma_chan *ioat_chan = to_ioat_chan(tx->chan); + + pci_unmap_addr_set(desc, dst, addr); + + list_for_each_entry(iter, &desc->async_tx.tx_list, node) { + iter->hw->dst_addr = addr; + addr += ioat_chan->xfercap; + } } static dma_cookie_t ioat_tx_submit(struct dma_async_tx_descriptor *tx) { struct ioat_dma_chan *ioat_chan = to_ioat_chan(tx->chan); - struct ioat_desc_sw *first = tx_to_ioat_desc(tx); - struct ioat_desc_sw *prev, *new; - struct ioat_dma_descriptor *hw; + struct ioat_desc_sw *desc = tx_to_ioat_desc(tx); int append = 0; dma_cookie_t cookie; - LIST_HEAD(new_chain); - u32 copy; - size_t len; - dma_addr_t src, dst; - int orig_ack; - unsigned int desc_count = 0; - - /* src and dest and len are stored in the initial descriptor */ - len = first->len; - src = first->src; - dst = first->dst; - orig_ack = first->async_tx.ack; - new = first; + struct ioat_desc_sw *group_start; + group_start = list_entry(desc->async_tx.tx_list.next, + struct ioat_desc_sw, node); spin_lock_bh(&ioat_chan->desc_lock); - prev = to_ioat_desc(ioat_chan->used_desc.prev); - prefetch(prev->hw); - do { - copy = min((u32) len, ioat_chan->xfercap); - - new->async_tx.ack = 1; - - hw = new->hw; - hw->size = copy; - hw->ctl = 0; - hw->src_addr = src; - hw->dst_addr = dst; - hw->next = 0; - - /* chain together the physical address list for the HW */ - wmb(); - prev->hw->next = (u64) new->async_tx.phys; - - len -= copy; - dst += copy; - src += copy; - - list_add_tail(&new->node, &new_chain); - desc_count++; - prev = new; - } while (len && (new = ioat_dma_get_next_descriptor(ioat_chan))); - - hw->ctl = IOAT_DMA_DESCRIPTOR_CTL_CP_STS; - if (new->async_tx.callback) { - hw->ctl |= IOAT_DMA_DESCRIPTOR_CTL_INT_GN; - if (first != new) { - /* move callback into to last desc */ - new->async_tx.callback = first->async_tx.callback; - new->async_tx.callback_param - = first->async_tx.callback_param; - first->async_tx.callback = NULL; - first->async_tx.callback_param = NULL; - } - } - - new->tx_cnt = desc_count; - new->async_tx.ack = orig_ack; /* client is in control of this ack */ - - /* store the original values for use in later cleanup */ - if (new != first) { - new->src = first->src; - new->dst = first->dst; - new->len = first->len; - } - /* cookie incr and addition to used_list must be atomic */ cookie = ioat_chan->common.cookie; cookie++; if (cookie < 0) cookie = 1; - ioat_chan->common.cookie = new->async_tx.cookie = cookie; + ioat_chan->common.cookie = desc->async_tx.cookie = cookie; /* write address into NextDescriptor field of last desc in chain */ to_ioat_desc(ioat_chan->used_desc.prev)->hw->next = - first->async_tx.phys; - __list_splice(&new_chain, ioat_chan->used_desc.prev); + group_start->async_tx.phys; + list_splice_init(&desc->async_tx.tx_list, ioat_chan->used_desc.prev); - ioat_chan->pending += desc_count; + ioat_chan->pending += desc->tx_cnt; if (ioat_chan->pending >= 4) { append = 1; ioat_chan->pending = 0; @@ -315,7 +267,7 @@ static int ioat_dma_alloc_chan_resources(struct dma_chan *chan) chanerr = readl(ioat_chan->reg_base + IOAT_CHANERR_OFFSET); if (chanerr) { dev_err(&ioat_chan->device->pdev->dev, - "CHANERR = %x, clearing\n", chanerr); + "ioatdma: CHANERR = %x, clearing\n", chanerr); writel(chanerr, ioat_chan->reg_base + IOAT_CHANERR_OFFSET); } @@ -324,7 +276,7 @@ static int ioat_dma_alloc_chan_resources(struct dma_chan *chan) desc = ioat_dma_alloc_descriptor(ioat_chan, GFP_KERNEL); if (!desc) { dev_err(&ioat_chan->device->pdev->dev, - "Only %d initial descriptors\n", i); + "ioatdma: Only %d initial descriptors\n", i); break; } list_add_tail(&desc->node, &tmp_list); @@ -390,13 +342,12 @@ static void ioat_dma_free_chan_resources(struct dma_chan *chan) /* one is ok since we left it on there on purpose */ if (in_use_descs > 1) dev_err(&ioat_chan->device->pdev->dev, - "Freeing %d in use descriptors!\n", + "ioatdma: Freeing %d in use descriptors!\n", in_use_descs - 1); ioat_chan->last_completion = ioat_chan->completion_addr = 0; ioat_chan->pending = 0; } - /** * ioat_dma_get_next_descriptor - return the next available descriptor * @ioat_chan: IOAT DMA channel handle @@ -405,8 +356,8 @@ static void ioat_dma_free_chan_resources(struct dma_chan *chan) * channel's desc_lock held. Allocates more descriptors if the channel * has run out. */ -static struct ioat_desc_sw * -ioat_dma_get_next_descriptor(struct ioat_dma_chan *ioat_chan) +static struct ioat_desc_sw *ioat_dma_get_next_descriptor( + struct ioat_dma_chan *ioat_chan) { struct ioat_desc_sw *new = NULL; @@ -431,11 +382,51 @@ static struct dma_async_tx_descriptor *ioat_dma_prep_memcpy( int int_en) { struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan); - struct ioat_desc_sw *new; + struct ioat_desc_sw *first, *prev, *new; + LIST_HEAD(new_chain); + u32 copy; + size_t orig_len; + int desc_count = 0; + + if (!len) + return NULL; + + orig_len = len; + + first = NULL; + prev = NULL; spin_lock_bh(&ioat_chan->desc_lock); - new = ioat_dma_get_next_descriptor(ioat_chan); - new->len = len; + while (len) { + new = ioat_dma_get_next_descriptor(ioat_chan); + copy = min((u32) len, ioat_chan->xfercap); + + new->hw->size = copy; + new->hw->ctl = 0; + new->async_tx.cookie = 0; + new->async_tx.ack = 1; + + /* chain together the physical address list for the HW */ + if (!first) + first = new; + else + prev->hw->next = (u64) new->async_tx.phys; + + prev = new; + len -= copy; + list_add_tail(&new->node, &new_chain); + desc_count++; + } + + list_splice(&new_chain, &new->async_tx.tx_list); + + new->hw->ctl = IOAT_DMA_DESCRIPTOR_CTL_CP_STS; + new->hw->next = 0; + new->tx_cnt = desc_count; + new->async_tx.ack = 0; /* client is in control of this ack */ + new->async_tx.cookie = -EBUSY; + + pci_unmap_len_set(new, len, orig_len); spin_unlock_bh(&ioat_chan->desc_lock); return new ? &new->async_tx : NULL; @@ -473,7 +464,7 @@ static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *ioat_chan) prefetch(ioat_chan->completion_virt); - if (!spin_trylock_bh(&ioat_chan->cleanup_lock)) + if (!spin_trylock(&ioat_chan->cleanup_lock)) return; /* The completion writeback can happen at any time, @@ -483,25 +474,22 @@ static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *ioat_chan) #if (BITS_PER_LONG == 64) phys_complete = - ioat_chan->completion_virt->full - & IOAT_CHANSTS_COMPLETED_DESCRIPTOR_ADDR; + ioat_chan->completion_virt->full & IOAT_CHANSTS_COMPLETED_DESCRIPTOR_ADDR; #else - phys_complete = - ioat_chan->completion_virt->low & IOAT_LOW_COMPLETION_MASK; + phys_complete = ioat_chan->completion_virt->low & IOAT_LOW_COMPLETION_MASK; #endif - if ((ioat_chan->completion_virt->full - & IOAT_CHANSTS_DMA_TRANSFER_STATUS) == + if ((ioat_chan->completion_virt->full & IOAT_CHANSTS_DMA_TRANSFER_STATUS) == IOAT_CHANSTS_DMA_TRANSFER_STATUS_HALTED) { dev_err(&ioat_chan->device->pdev->dev, - "Channel halted, chanerr = %x\n", + "ioatdma: Channel halted, chanerr = %x\n", readl(ioat_chan->reg_base + IOAT_CHANERR_OFFSET)); /* TODO do something to salvage the situation */ } if (phys_complete == ioat_chan->last_completion) { - spin_unlock_bh(&ioat_chan->cleanup_lock); + spin_unlock(&ioat_chan->cleanup_lock); return; } @@ -529,11 +517,6 @@ static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *ioat_chan) pci_unmap_addr(desc, src), pci_unmap_len(desc, len), PCI_DMA_TODEVICE); - if (desc->async_tx.callback) { - desc->async_tx.callback( - desc->async_tx.callback_param); - desc->async_tx.callback = NULL; - } } if (desc->async_tx.phys != phys_complete) { @@ -565,7 +548,7 @@ static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *ioat_chan) if (cookie != 0) ioat_chan->completed_cookie = cookie; - spin_unlock_bh(&ioat_chan->cleanup_lock); + spin_unlock(&ioat_chan->cleanup_lock); } static void ioat_dma_dependency_added(struct dma_chan *chan) @@ -630,13 +613,8 @@ static void ioat_dma_start_null_desc(struct ioat_dma_chan *ioat_chan) spin_lock_bh(&ioat_chan->desc_lock); desc = ioat_dma_get_next_descriptor(ioat_chan); - desc->hw->ctl = IOAT_DMA_DESCRIPTOR_NUL - | IOAT_DMA_DESCRIPTOR_CTL_INT_GN - | IOAT_DMA_DESCRIPTOR_CTL_CP_STS; + desc->hw->ctl = IOAT_DMA_DESCRIPTOR_NUL; desc->hw->next = 0; - desc->hw->size = 0; - desc->hw->src_addr = 0; - desc->hw->dst_addr = 0; desc->async_tx.ack = 1; list_add_tail(&desc->node, &ioat_chan->used_desc); @@ -655,12 +633,6 @@ static void ioat_dma_start_null_desc(struct ioat_dma_chan *ioat_chan) */ #define IOAT_TEST_SIZE 2000 -static void ioat_dma_test_callback(void *dma_async_param) -{ - printk(KERN_ERR "ioatdma: ioat_dma_test_callback(%p)\n", - dma_async_param); -} - /** * ioat_dma_self_test - Perform a IOAT transaction to verify the HW works. * @device: device to be tested @@ -671,7 +643,7 @@ static int ioat_dma_self_test(struct ioatdma_device *device) u8 *src; u8 *dest; struct dma_chan *dma_chan; - struct dma_async_tx_descriptor *tx = NULL; + struct dma_async_tx_descriptor *tx; dma_addr_t addr; dma_cookie_t cookie; int err = 0; @@ -701,13 +673,6 @@ static int ioat_dma_self_test(struct ioatdma_device *device) } tx = ioat_dma_prep_memcpy(dma_chan, IOAT_TEST_SIZE, 0); - if (!tx) { - dev_err(&device->pdev->dev, - "Self-test prep failed, disabling\n"); - err = -ENODEV; - goto free_resources; - } - async_tx_ack(tx); addr = dma_map_single(dma_chan->device->dev, src, IOAT_TEST_SIZE, DMA_TO_DEVICE); @@ -715,27 +680,19 @@ static int ioat_dma_self_test(struct ioatdma_device *device) addr = dma_map_single(dma_chan->device->dev, dest, IOAT_TEST_SIZE, DMA_FROM_DEVICE); ioat_set_dest(addr, tx, 0); - tx->callback = ioat_dma_test_callback; - tx->callback_param = (void *)0x8086; cookie = ioat_tx_submit(tx); - if (cookie < 0) { - dev_err(&device->pdev->dev, - "Self-test setup failed, disabling\n"); - err = -ENODEV; - goto free_resources; - } ioat_dma_memcpy_issue_pending(dma_chan); msleep(1); if (ioat_dma_is_complete(dma_chan, cookie, NULL, NULL) != DMA_SUCCESS) { dev_err(&device->pdev->dev, - "Self-test copy timed out, disabling\n"); + "ioatdma: Self-test copy timed out, disabling\n"); err = -ENODEV; goto free_resources; } if (memcmp(src, dest, IOAT_TEST_SIZE)) { dev_err(&device->pdev->dev, - "Self-test copy failed compare, disabling\n"); + "ioatdma: Self-test copy failed compare, disabling\n"); err = -ENODEV; goto free_resources; } @@ -773,9 +730,6 @@ static int ioat_dma_setup_interrupts(struct ioatdma_device *device) goto msi; if (!strcmp(ioat_interrupt_style, "intx")) goto intx; - dev_err(&device->pdev->dev, "invalid ioat_interrupt_style %s\n", - ioat_interrupt_style); - goto err_no_irq; msix: /* The number of MSI-X vectors should equal the number of channels */ @@ -952,9 +906,9 @@ struct ioatdma_device *ioat_dma_probe(struct pci_dev *pdev, device->common.device_dependency_added = ioat_dma_dependency_added; device->common.dev = &pdev->dev; dev_err(&device->pdev->dev, - "Intel(R) I/OAT DMA Engine found," - " %d channels, device version 0x%02x, driver version %s\n", - device->common.chancnt, device->version, IOAT_DMA_VERSION); + "ioatdma: Intel(R) I/OAT DMA Engine found," + " %d channels, device version 0x%02x\n", + device->common.chancnt, device->version); err = ioat_dma_setup_interrupts(device); if (err) @@ -977,8 +931,9 @@ struct ioatdma_device *ioat_dma_probe(struct pci_dev *pdev, err_dma_pool: kfree(device); err_kzalloc: + iounmap(iobase); dev_err(&device->pdev->dev, - "Intel(R) I/OAT DMA Engine initialization failed\n"); + "ioatdma: Intel(R) I/OAT DMA Engine initialization failed\n"); return NULL; } @@ -987,17 +942,13 @@ void ioat_dma_remove(struct ioatdma_device *device) struct dma_chan *chan, *_chan; struct ioat_dma_chan *ioat_chan; - ioat_dma_remove_interrupts(device); - dma_async_device_unregister(&device->common); + ioat_dma_remove_interrupts(device); + pci_pool_destroy(device->dma_pool); pci_pool_destroy(device->completion_pool); - iounmap(device->reg_base); - pci_release_regions(device->pdev); - pci_disable_device(device->pdev); - list_for_each_entry_safe(chan, _chan, &device->common.channels, device_node) { ioat_chan = to_ioat_chan(chan); diff --git a/trunk/drivers/dma/ioatdma.h b/trunk/drivers/dma/ioatdma.h index 5f9881e7b0ed..2a319e124ece 100644 --- a/trunk/drivers/dma/ioatdma.h +++ b/trunk/drivers/dma/ioatdma.h @@ -28,8 +28,6 @@ #include #include -#define IOAT_DMA_VERSION "1.26" - enum ioat_interrupt { none = 0, msix_multi_vector = 1, @@ -124,9 +122,9 @@ struct ioat_desc_sw { struct ioat_dma_descriptor *hw; struct list_head node; int tx_cnt; - size_t len; - dma_addr_t src; - dma_addr_t dst; + DECLARE_PCI_UNMAP_LEN(len) + DECLARE_PCI_UNMAP_ADDR(src) + DECLARE_PCI_UNMAP_ADDR(dst) struct dma_async_tx_descriptor async_tx; }; diff --git a/trunk/drivers/edac/edac_core.h b/trunk/drivers/edac/edac_core.h index 2d23e304f5ec..e80af67664cc 100644 --- a/trunk/drivers/edac/edac_core.h +++ b/trunk/drivers/edac/edac_core.h @@ -94,6 +94,8 @@ extern int edac_debug_level; #endif /* !CONFIG_EDAC_DEBUG */ +#define BIT(x) (1 << (x)) + #define PCI_VEND_DEV(vend, dev) PCI_VENDOR_ID_ ## vend, \ PCI_DEVICE_ID_ ## vend ## _ ## dev diff --git a/trunk/drivers/edac/pasemi_edac.c b/trunk/drivers/edac/pasemi_edac.c index 9007d0677220..e66cdd42a392 100644 --- a/trunk/drivers/edac/pasemi_edac.c +++ b/trunk/drivers/edac/pasemi_edac.c @@ -270,7 +270,6 @@ static void __devexit pasemi_edac_remove(struct pci_dev *pdev) static const struct pci_device_id pasemi_edac_pci_tbl[] = { { PCI_DEVICE(PCI_VENDOR_ID_PASEMI, 0xa00a) }, - { } }; MODULE_DEVICE_TABLE(pci, pasemi_edac_pci_tbl); diff --git a/trunk/drivers/firmware/dcdbas.h b/trunk/drivers/firmware/dcdbas.h index 87bc3417de27..dcdba0f1b32c 100644 --- a/trunk/drivers/firmware/dcdbas.h +++ b/trunk/drivers/firmware/dcdbas.h @@ -17,6 +17,7 @@ #define _DCDBAS_H_ #include +#include #include #include diff --git a/trunk/drivers/hid/hidraw.c b/trunk/drivers/hid/hidraw.c index 1ca6f4635eeb..a702e2f6da7d 100644 --- a/trunk/drivers/hid/hidraw.c +++ b/trunk/drivers/hid/hidraw.c @@ -113,13 +113,13 @@ static ssize_t hidraw_write(struct file *file, const char __user *buffer, size_t if (count > HID_MIN_BUFFER_SIZE) { printk(KERN_WARNING "hidraw: pid %d passed too large report\n", - task_pid_nr(current)); + current->pid); return -EINVAL; } if (count < 2) { printk(KERN_WARNING "hidraw: pid %d passed too short report\n", - task_pid_nr(current)); + current->pid); return -EINVAL; } diff --git a/trunk/drivers/hid/usbhid/usbkbd.c b/trunk/drivers/hid/usbhid/usbkbd.c index 775a1ef28a29..b76b02f7b52d 100644 --- a/trunk/drivers/hid/usbhid/usbkbd.c +++ b/trunk/drivers/hid/usbhid/usbkbd.c @@ -274,11 +274,8 @@ static int usb_kbd_probe(struct usb_interface *iface, input_set_drvdata(input_dev, kbd); - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_LED) | - BIT_MASK(EV_REP); - input_dev->ledbit[0] = BIT_MASK(LED_NUML) | BIT_MASK(LED_CAPSL) | - BIT_MASK(LED_SCROLLL) | BIT_MASK(LED_COMPOSE) | - BIT_MASK(LED_KANA); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP); + input_dev->ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL) | BIT(LED_COMPOSE) | BIT(LED_KANA); for (i = 0; i < 255; i++) set_bit(usb_kbd_keycode[i], input_dev->keybit); diff --git a/trunk/drivers/hid/usbhid/usbmouse.c b/trunk/drivers/hid/usbhid/usbmouse.c index f8ad6910d3d9..5345c73bcf62 100644 --- a/trunk/drivers/hid/usbhid/usbmouse.c +++ b/trunk/drivers/hid/usbhid/usbmouse.c @@ -173,13 +173,11 @@ static int usb_mouse_probe(struct usb_interface *intf, const struct usb_device_i usb_to_input_id(dev, &input_dev->id); input_dev->dev.parent = &intf->dev; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); - input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) | - BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE); - input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); - input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_SIDE) | - BIT_MASK(BTN_EXTRA); - input_dev->relbit[0] |= BIT_MASK(REL_WHEEL); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); + input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE); + input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y); + input_dev->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_SIDE) | BIT(BTN_EXTRA); + input_dev->relbit[0] |= BIT(REL_WHEEL); input_set_drvdata(input_dev, mouse); diff --git a/trunk/drivers/hwmon/adm1026.c b/trunk/drivers/hwmon/adm1026.c index 3e63c1486770..aa875ca50d9b 100644 --- a/trunk/drivers/hwmon/adm1026.c +++ b/trunk/drivers/hwmon/adm1026.c @@ -1651,7 +1651,7 @@ static int adm1026_detect(struct i2c_adapter *adapter, int address, break; default : dev_err(&adapter->dev, ": Internal error, invalid " - "kind (%d)!\n", kind); + "kind (%d)!", kind); err = -EFAULT; goto exitfree; } diff --git a/trunk/drivers/hwmon/applesmc.c b/trunk/drivers/hwmon/applesmc.c index 1001d2e122a2..4879125b4cdc 100644 --- a/trunk/drivers/hwmon/applesmc.c +++ b/trunk/drivers/hwmon/applesmc.c @@ -1099,7 +1099,7 @@ static int applesmc_create_accelerometer(void) idev->name = "applesmc"; idev->id.bustype = BUS_HOST; idev->dev.parent = &pdev->dev; - idev->evbit[0] = BIT_MASK(EV_ABS); + idev->evbit[0] = BIT(EV_ABS); input_set_abs_params(idev, ABS_X, -256, 256, APPLESMC_INPUT_FUZZ, APPLESMC_INPUT_FLAT); input_set_abs_params(idev, ABS_Y, diff --git a/trunk/drivers/hwmon/hdaps.c b/trunk/drivers/hwmon/hdaps.c index bab5fd2e4dfd..8a7ae03aeee4 100644 --- a/trunk/drivers/hwmon/hdaps.c +++ b/trunk/drivers/hwmon/hdaps.c @@ -574,7 +574,7 @@ static int __init hdaps_init(void) idev = hdaps_idev->input; idev->name = "hdaps"; idev->dev.parent = &pdev->dev; - idev->evbit[0] = BIT_MASK(EV_ABS); + idev->evbit[0] = BIT(EV_ABS); input_set_abs_params(idev, ABS_X, -256, 256, HDAPS_INPUT_FUZZ, HDAPS_INPUT_FLAT); input_set_abs_params(idev, ABS_Y, diff --git a/trunk/drivers/hwmon/lm63.c b/trunk/drivers/hwmon/lm63.c index 650b07d5b902..f207434730de 100644 --- a/trunk/drivers/hwmon/lm63.c +++ b/trunk/drivers/hwmon/lm63.c @@ -533,7 +533,7 @@ static void lm63_init_client(struct i2c_client *client) /* Start converting if needed */ if (data->config & 0x40) { /* standby */ - dev_dbg(&client->dev, "Switching to operational mode\n"); + dev_dbg(&client->dev, "Switching to operational mode"); data->config &= 0xA7; i2c_smbus_write_byte_data(client, LM63_REG_CONFIG1, data->config); diff --git a/trunk/drivers/hwmon/vt1211.c b/trunk/drivers/hwmon/vt1211.c index 7dfcc8dd316d..e69416465e6d 100644 --- a/trunk/drivers/hwmon/vt1211.c +++ b/trunk/drivers/hwmon/vt1211.c @@ -795,7 +795,7 @@ static ssize_t set_pwm_auto_point_pwm(struct device *dev, if ((val < 0) || (val > 255)) { dev_err(dev, "pwm value %ld is out of range. " - "Choose a value between 0 and 255.\n" , val); + "Choose a value between 0 and 255." , val); return -EINVAL; } diff --git a/trunk/drivers/hwmon/w83791d.c b/trunk/drivers/hwmon/w83791d.c index a9c01a6f0057..b6f2ebf9f9cf 100644 --- a/trunk/drivers/hwmon/w83791d.c +++ b/trunk/drivers/hwmon/w83791d.c @@ -1096,7 +1096,7 @@ static int w83791d_detect(struct i2c_adapter *adapter, int address, int kind) if (kind == w83791d) { client_name = "w83791d"; } else { - dev_err(dev, "w83791d: Internal error: unknown kind (%d)?!?\n", + dev_err(dev, "w83791d: Internal error: unknown kind (%d)?!?", kind); goto error1; } diff --git a/trunk/drivers/hwmon/w83792d.c b/trunk/drivers/hwmon/w83792d.c index 007449d3e16e..f836198b705c 100644 --- a/trunk/drivers/hwmon/w83792d.c +++ b/trunk/drivers/hwmon/w83792d.c @@ -1385,8 +1385,8 @@ w83792d_detect(struct i2c_adapter *adapter, int address, int kind) if (kind == w83792d) { client_name = "w83792d"; } else { - dev_err(dev, "w83792d: Internal error: unknown kind (%d)?!?\n", - kind); + dev_err(dev, "w83792d: Internal error: unknown" + " kind (%d)?!?", kind); goto ERROR1; } diff --git a/trunk/drivers/i2c/busses/i2c-pmcmsp.c b/trunk/drivers/i2c/busses/i2c-pmcmsp.c index be99c02ecac5..17cecf1ea797 100644 --- a/trunk/drivers/i2c/busses/i2c-pmcmsp.c +++ b/trunk/drivers/i2c/busses/i2c-pmcmsp.c @@ -591,18 +591,18 @@ static int pmcmsptwi_master_xfer(struct i2c_adapter *adap, if (msg->flags & I2C_M_TEN) pmcmsptwi_set_twi_config(&oldcfg, data); - dev_dbg(&adap->dev, "I2C %s of %d bytes %s\n", - (msg->flags & I2C_M_RD) ? "read" : "write", msg->len, - (ret == MSP_TWI_XFER_OK) ? "succeeded" : "failed"); - + dev_dbg(&adap->dev, "I2C %s of %d bytes ", + (msg->flags & I2C_M_RD) ? "read" : "write", msg->len); if (ret != MSP_TWI_XFER_OK) { /* * TODO: We could potentially loop and retry in the case * of MSP_TWI_XFER_TIMEOUT. */ + dev_dbg(&adap->dev, "failed\n"); return -1; } + dev_dbg(&adap->dev, "succeeded\n"); return 0; } diff --git a/trunk/drivers/i2c/busses/i2c-pnx.c b/trunk/drivers/i2c/busses/i2c-pnx.c index f8d0dff0de7e..17376feb1acc 100644 --- a/trunk/drivers/i2c/busses/i2c-pnx.c +++ b/trunk/drivers/i2c/busses/i2c-pnx.c @@ -575,7 +575,7 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) else { freq_mhz = PNX_DEFAULT_FREQ; dev_info(&pdev->dev, "Setting bus frequency to default value: " - "%d MHz\n", freq_mhz); + "%d MHz", freq_mhz); } i2c_pnx->adapter->algo = &pnx_algorithm; diff --git a/trunk/drivers/i2c/busses/i2c-pxa.c b/trunk/drivers/i2c/busses/i2c-pxa.c index 6426a61f8d4d..00fad11733ad 100644 --- a/trunk/drivers/i2c/busses/i2c-pxa.c +++ b/trunk/drivers/i2c/busses/i2c-pxa.c @@ -85,7 +85,7 @@ struct bits { const char *set; const char *unset; }; -#define PXA_BIT(m, s, u) { .mask = m, .set = s, .unset = u } +#define BIT(m, s, u) { .mask = m, .set = s, .unset = u } static inline void decode_bits(const char *prefix, const struct bits *bits, int num, u32 val) @@ -100,17 +100,17 @@ decode_bits(const char *prefix, const struct bits *bits, int num, u32 val) } static const struct bits isr_bits[] = { - PXA_BIT(ISR_RWM, "RX", "TX"), - PXA_BIT(ISR_ACKNAK, "NAK", "ACK"), - PXA_BIT(ISR_UB, "Bsy", "Rdy"), - PXA_BIT(ISR_IBB, "BusBsy", "BusRdy"), - PXA_BIT(ISR_SSD, "SlaveStop", NULL), - PXA_BIT(ISR_ALD, "ALD", NULL), - PXA_BIT(ISR_ITE, "TxEmpty", NULL), - PXA_BIT(ISR_IRF, "RxFull", NULL), - PXA_BIT(ISR_GCAD, "GenCall", NULL), - PXA_BIT(ISR_SAD, "SlaveAddr", NULL), - PXA_BIT(ISR_BED, "BusErr", NULL), + BIT(ISR_RWM, "RX", "TX"), + BIT(ISR_ACKNAK, "NAK", "ACK"), + BIT(ISR_UB, "Bsy", "Rdy"), + BIT(ISR_IBB, "BusBsy", "BusRdy"), + BIT(ISR_SSD, "SlaveStop", NULL), + BIT(ISR_ALD, "ALD", NULL), + BIT(ISR_ITE, "TxEmpty", NULL), + BIT(ISR_IRF, "RxFull", NULL), + BIT(ISR_GCAD, "GenCall", NULL), + BIT(ISR_SAD, "SlaveAddr", NULL), + BIT(ISR_BED, "BusErr", NULL), }; static void decode_ISR(unsigned int val) @@ -120,21 +120,21 @@ static void decode_ISR(unsigned int val) } static const struct bits icr_bits[] = { - PXA_BIT(ICR_START, "START", NULL), - PXA_BIT(ICR_STOP, "STOP", NULL), - PXA_BIT(ICR_ACKNAK, "ACKNAK", NULL), - PXA_BIT(ICR_TB, "TB", NULL), - PXA_BIT(ICR_MA, "MA", NULL), - PXA_BIT(ICR_SCLE, "SCLE", "scle"), - PXA_BIT(ICR_IUE, "IUE", "iue"), - PXA_BIT(ICR_GCD, "GCD", NULL), - PXA_BIT(ICR_ITEIE, "ITEIE", NULL), - PXA_BIT(ICR_IRFIE, "IRFIE", NULL), - PXA_BIT(ICR_BEIE, "BEIE", NULL), - PXA_BIT(ICR_SSDIE, "SSDIE", NULL), - PXA_BIT(ICR_ALDIE, "ALDIE", NULL), - PXA_BIT(ICR_SADIE, "SADIE", NULL), - PXA_BIT(ICR_UR, "UR", "ur"), + BIT(ICR_START, "START", NULL), + BIT(ICR_STOP, "STOP", NULL), + BIT(ICR_ACKNAK, "ACKNAK", NULL), + BIT(ICR_TB, "TB", NULL), + BIT(ICR_MA, "MA", NULL), + BIT(ICR_SCLE, "SCLE", "scle"), + BIT(ICR_IUE, "IUE", "iue"), + BIT(ICR_GCD, "GCD", NULL), + BIT(ICR_ITEIE, "ITEIE", NULL), + BIT(ICR_IRFIE, "IRFIE", NULL), + BIT(ICR_BEIE, "BEIE", NULL), + BIT(ICR_SSDIE, "SSDIE", NULL), + BIT(ICR_ALDIE, "ALDIE", NULL), + BIT(ICR_SADIE, "SADIE", NULL), + BIT(ICR_UR, "UR", "ur"), }; static void decode_ICR(unsigned int val) diff --git a/trunk/drivers/i2c/chips/menelaus.c b/trunk/drivers/i2c/chips/menelaus.c index 2dea0123a958..66436bae11ac 100644 --- a/trunk/drivers/i2c/chips/menelaus.c +++ b/trunk/drivers/i2c/chips/menelaus.c @@ -1195,7 +1195,7 @@ static int menelaus_probe(struct i2c_client *client) err = request_irq(client->irq, menelaus_irq, IRQF_DISABLED, DRIVER_NAME, menelaus); if (err) { - dev_dbg(&client->dev, "can't get IRQ %d, err %d\n", + dev_dbg(&client->dev, "can't get IRQ %d, err %d", client->irq, err); goto fail1; } diff --git a/trunk/drivers/ide/arm/icside.c b/trunk/drivers/ide/arm/icside.c index 3af33fbf1f88..e4875cef78bb 100644 --- a/trunk/drivers/ide/arm/icside.c +++ b/trunk/drivers/ide/arm/icside.c @@ -415,6 +415,7 @@ static void icside_dma_lost_irq(ide_drive_t *drive) static void icside_dma_init(ide_hwif_t *hwif) { + hwif->atapi_dma = 1; hwif->mwdma_mask = 7; /* MW0..2 */ hwif->swdma_mask = 7; /* SW0..2 */ diff --git a/trunk/drivers/ide/cris/ide-cris.c b/trunk/drivers/ide/cris/ide-cris.c index 9a96a10ba9d3..06c75f18eb88 100644 --- a/trunk/drivers/ide/cris/ide-cris.c +++ b/trunk/drivers/ide/cris/ide-cris.c @@ -805,7 +805,6 @@ init_e100_ide (void) hwif->dma_host_on = &cris_dma_on; hwif->dma_off_quietly = &cris_dma_off; hwif->cbl = ATA_CBL_PATA40; - hwif->host_flags |= IDE_HFLAG_NO_ATAPI_DMA; hwif->pio_mask = ATA_PIO4, hwif->drives[0].autotune = 1; hwif->drives[1].autotune = 1; diff --git a/trunk/drivers/ide/ide-disk.c b/trunk/drivers/ide/ide-disk.c index 2722d9165b6b..92177ca48b4d 100644 --- a/trunk/drivers/ide/ide-disk.c +++ b/trunk/drivers/ide/ide-disk.c @@ -169,7 +169,7 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, nsectors.all = (u16) rq->nr_sectors; - if ((hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) && lba48 && dma) { + if (hwif->no_lba48_dma && lba48 && dma) { if (block + rq->nr_sectors > 1ULL << 28) dma = 0; else @@ -856,7 +856,7 @@ static int set_lba_addressing(ide_drive_t *drive, int arg) drive->addressing = 0; - if (drive->hwif->host_flags & IDE_HFLAG_NO_LBA48) + if (HWIF(drive)->no_lba48) return 0; if (!idedisk_supports_lba48(drive->id)) @@ -889,7 +889,6 @@ static inline void idedisk_add_settings(ide_drive_t *drive) { ; } static void idedisk_setup (ide_drive_t *drive) { - ide_hwif_t *hwif = drive->hwif; struct hd_driveid *id = drive->id; unsigned long long capacity; @@ -910,6 +909,7 @@ static void idedisk_setup (ide_drive_t *drive) (void)set_lba_addressing(drive, 1); if (drive->addressing == 1) { + ide_hwif_t *hwif = HWIF(drive); int max_s = 2048; if (max_s > hwif->rqsize) @@ -932,7 +932,7 @@ static void idedisk_setup (ide_drive_t *drive) drive->capacity64 = 1ULL << 28; } - if ((hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) && drive->addressing) { + if (drive->hwif->no_lba48_dma && drive->addressing) { if (drive->capacity64 > 1ULL << 28) { printk(KERN_INFO "%s: cannot use LBA48 DMA - PIO mode will" " be used for accessing sectors > %u\n", diff --git a/trunk/drivers/ide/ide-dma.c b/trunk/drivers/ide/ide-dma.c index 80b4f17f3941..bc57ce6bf0b3 100644 --- a/trunk/drivers/ide/ide-dma.c +++ b/trunk/drivers/ide/ide-dma.c @@ -338,10 +338,8 @@ static int config_drive_for_dma (ide_drive_t *drive) ide_hwif_t *hwif = drive->hwif; struct hd_driveid *id = drive->id; - if (drive->media != ide_disk) { - if (hwif->host_flags & IDE_HFLAG_NO_ATAPI_DMA) - return -1; - } + if (drive->media != ide_disk && hwif->atapi_dma == 0) + return 0; /* * Enable DMA on any drive that has @@ -728,10 +726,8 @@ u8 ide_find_dma_mode(ide_drive_t *drive, u8 req_mode) int x, i; u8 mode = 0; - if (drive->media != ide_disk) { - if (hwif->host_flags & IDE_HFLAG_NO_ATAPI_DMA) - return 0; - } + if (drive->media != ide_disk && hwif->atapi_dma == 0) + return 0; for (i = 0; i < ARRAY_SIZE(xfer_mode_bases); i++) { if (req_mode < xfer_mode_bases[i]) diff --git a/trunk/drivers/ide/ide-io.c b/trunk/drivers/ide/ide-io.c index 32eaa3f80515..ec835e37e729 100644 --- a/trunk/drivers/ide/ide-io.c +++ b/trunk/drivers/ide/ide-io.c @@ -47,12 +47,12 @@ #include #include #include -#include #include #include #include #include +#include static int __ide_end_request(ide_drive_t *drive, struct request *rq, int uptodate, unsigned int nr_bytes) @@ -484,8 +484,7 @@ static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq, u8 } } - if ((stat & DRQ_STAT) && rq_data_dir(rq) == READ && - (hwif->host_flags & IDE_HFLAG_ERROR_STOPS_FIFO) == 0) + if ((stat & DRQ_STAT) && rq_data_dir(rq) == READ && hwif->err_stops_fifo == 0) try_to_flush_leftover_data(drive); if (rq->errors >= ERROR_MAX || blk_noretry_request(rq)) { diff --git a/trunk/drivers/ide/ide-probe.c b/trunk/drivers/ide/ide-probe.c index e294c7415c27..3c945d64d845 100644 --- a/trunk/drivers/ide/ide-probe.c +++ b/trunk/drivers/ide/ide-probe.c @@ -951,8 +951,7 @@ static int ide_init_queue(ide_drive_t *drive) blk_queue_segment_boundary(q, 0xffff); if (!hwif->rqsize) { - if ((hwif->host_flags & IDE_HFLAG_NO_LBA48) || - (hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA)) + if (hwif->no_lba48 || hwif->no_lba48_dma) hwif->rqsize = 256; else hwif->rqsize = 65536; diff --git a/trunk/drivers/ide/ide.c b/trunk/drivers/ide/ide.c index 961e6c897286..5b090662683e 100644 --- a/trunk/drivers/ide/ide.c +++ b/trunk/drivers/ide/ide.c @@ -134,6 +134,8 @@ static void init_hwif_data(ide_hwif_t *hwif, unsigned int index) hwif->bus_state = BUSSTATE_ON; + hwif->atapi_dma = 0; /* disable all atapi dma */ + init_completion(&hwif->gendev_rel_comp); default_hwif_iops(hwif); @@ -377,6 +379,7 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif) hwif->pio_mask = tmp_hwif->pio_mask; + hwif->atapi_dma = tmp_hwif->atapi_dma; hwif->ultra_mask = tmp_hwif->ultra_mask; hwif->mwdma_mask = tmp_hwif->mwdma_mask; hwif->swdma_mask = tmp_hwif->swdma_mask; @@ -437,6 +440,7 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif) hwif->mmio = tmp_hwif->mmio; hwif->rqsize = tmp_hwif->rqsize; + hwif->no_lba48 = tmp_hwif->no_lba48; #ifndef CONFIG_BLK_DEV_IDECS hwif->irq = tmp_hwif->irq; diff --git a/trunk/drivers/ide/mips/au1xxx-ide.c b/trunk/drivers/ide/mips/au1xxx-ide.c index 2f322d7e881b..47c035a550e3 100644 --- a/trunk/drivers/ide/mips/au1xxx-ide.c +++ b/trunk/drivers/ide/mips/au1xxx-ide.c @@ -699,6 +699,9 @@ static int au_ide_probe(struct device *dev) hwif->dma_host_on = &auide_dma_host_on; hwif->dma_lost_irq = &auide_dma_lost_irq; hwif->ide_dma_on = &auide_dma_on; + + hwif->atapi_dma = 1; + #else /* !CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */ hwif->channel = 0; hwif->hold = 1; diff --git a/trunk/drivers/ide/pci/aec62xx.c b/trunk/drivers/ide/pci/aec62xx.c index b3dc12a70d51..3a4c2c26a77e 100644 --- a/trunk/drivers/ide/pci/aec62xx.c +++ b/trunk/drivers/ide/pci/aec62xx.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/aec62xx.c Version 0.26 Sep 1, 2007 + * linux/drivers/ide/pci/aec62xx.c Version 0.25 Aug 1, 2007 * * Copyright (C) 1999-2002 Andre Hedrick * Copyright (C) 2007 MontaVista Software, Inc. @@ -184,23 +184,34 @@ static unsigned int __devinit init_chipset_aec62xx(struct pci_dev *dev, const ch static void __devinit init_hwif_aec62xx(ide_hwif_t *hwif) { struct pci_dev *dev = hwif->pci_dev; + u8 reg54 = 0, mask = hwif->channel ? 0xf0 : 0x0f; + unsigned long flags; hwif->set_pio_mode = &aec_set_pio_mode; - if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF) + if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF) { + if(hwif->mate) + hwif->mate->serialized = hwif->serialized = 1; hwif->set_dma_mode = &aec6210_set_mode; - else + } else hwif->set_dma_mode = &aec6260_set_mode; + hwif->drives[0].autotune = hwif->drives[1].autotune = 1; + if (hwif->dma_base == 0) return; - hwif->dma_lost_irq = &aec62xx_dma_lost_irq; + hwif->ultra_mask = hwif->cds->udma_mask; + hwif->mwdma_mask = 0x07; - if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF) - return; + hwif->dma_lost_irq = &aec62xx_dma_lost_irq; - if (hwif->cbl != ATA_CBL_PATA40_SHORT) { + if (dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF) { + spin_lock_irqsave(&ide_lock, flags); + pci_read_config_byte (dev, 0x54, ®54); + pci_write_config_byte(dev, 0x54, (reg54 & ~mask)); + spin_unlock_irqrestore(&ide_lock, flags); + } else if (hwif->cbl != ATA_CBL_PATA40_SHORT) { u8 ata66 = 0, mask = hwif->channel ? 0x02 : 0x01; pci_read_config_byte(hwif->pci_dev, 0x49, &ata66); @@ -209,53 +220,73 @@ static void __devinit init_hwif_aec62xx(ide_hwif_t *hwif) } } +static int __devinit init_setup_aec62xx(struct pci_dev *dev, ide_pci_device_t *d) +{ + return ide_setup_pci_device(dev, d); +} + +static int __devinit init_setup_aec6x80(struct pci_dev *dev, ide_pci_device_t *d) +{ + unsigned long dma_base = pci_resource_start(dev, 4); + + if (inb(dma_base + 2) & 0x10) { + d->name = (dev->device == PCI_DEVICE_ID_ARTOP_ATP865R) ? + "AEC6880R" : "AEC6880"; + d->udma_mask = 0x7f; /* udma0-6 */ + } + + return ide_setup_pci_device(dev, d); +} + static ide_pci_device_t aec62xx_chipsets[] __devinitdata = { { /* 0 */ .name = "AEC6210", + .init_setup = init_setup_aec62xx, .init_chipset = init_chipset_aec62xx, .init_hwif = init_hwif_aec62xx, + .autodma = AUTODMA, .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, - .host_flags = IDE_HFLAG_SERIALIZE | - IDE_HFLAG_NO_ATAPI_DMA | - IDE_HFLAG_OFF_BOARD, + .bootable = OFF_BOARD, .pio_mask = ATA_PIO4, - .mwdma_mask = ATA_MWDMA2, - .udma_mask = ATA_UDMA2, + .udma_mask = 0x07, /* udma0-2 */ },{ /* 1 */ .name = "AEC6260", + .init_setup = init_setup_aec62xx, .init_chipset = init_chipset_aec62xx, .init_hwif = init_hwif_aec62xx, - .host_flags = IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_NO_AUTODMA | - IDE_HFLAG_OFF_BOARD, + .autodma = NOAUTODMA, + .bootable = OFF_BOARD, .pio_mask = ATA_PIO4, - .mwdma_mask = ATA_MWDMA2, - .udma_mask = ATA_UDMA4, + .udma_mask = 0x1f, /* udma0-4 */ },{ /* 2 */ .name = "AEC6260R", + .init_setup = init_setup_aec62xx, .init_chipset = init_chipset_aec62xx, .init_hwif = init_hwif_aec62xx, + .autodma = AUTODMA, .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, - .host_flags = IDE_HFLAG_NO_ATAPI_DMA, + .bootable = NEVER_BOARD, .pio_mask = ATA_PIO4, - .mwdma_mask = ATA_MWDMA2, - .udma_mask = ATA_UDMA4, + .udma_mask = 0x1f, /* udma0-4 */ },{ /* 3 */ .name = "AEC6280", + .init_setup = init_setup_aec6x80, .init_chipset = init_chipset_aec62xx, .init_hwif = init_hwif_aec62xx, - .host_flags = IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_OFF_BOARD, + .autodma = AUTODMA, + .bootable = OFF_BOARD, .pio_mask = ATA_PIO4, - .mwdma_mask = ATA_MWDMA2, - .udma_mask = ATA_UDMA5, + .udma_mask = 0x3f, /* udma0-5 */ },{ /* 4 */ .name = "AEC6280R", + .init_setup = init_setup_aec6x80, .init_chipset = init_chipset_aec62xx, .init_hwif = init_hwif_aec62xx, + .autodma = AUTODMA, .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, - .host_flags = IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_OFF_BOARD, + .bootable = OFF_BOARD, .pio_mask = ATA_PIO4, - .mwdma_mask = ATA_MWDMA2, - .udma_mask = ATA_UDMA5, + .udma_mask = 0x3f, /* udma0-5 */ } }; @@ -273,21 +304,9 @@ static ide_pci_device_t aec62xx_chipsets[] __devinitdata = { static int __devinit aec62xx_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - ide_pci_device_t d; - u8 idx = id->driver_data; - - d = aec62xx_chipsets[idx]; - - if (idx == 3 || idx == 4) { - unsigned long dma_base = pci_resource_start(dev, 4); - - if (inb(dma_base + 2) & 0x10) { - d.name = (idx == 4) ? "AEC6880R" : "AEC6880"; - d.udma_mask = ATA_UDMA6; - } - } + ide_pci_device_t d = aec62xx_chipsets[id->driver_data]; - return ide_setup_pci_device(dev, &d); + return d.init_setup(dev, &d); } static const struct pci_device_id aec62xx_pci_tbl[] = { diff --git a/trunk/drivers/ide/pci/alim15x3.c b/trunk/drivers/ide/pci/alim15x3.c index 8ee2b48d105d..31d4e50647d5 100644 --- a/trunk/drivers/ide/pci/alim15x3.c +++ b/trunk/drivers/ide/pci/alim15x3.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/alim15x3.c Version 0.27 Aug 27 2007 + * linux/drivers/ide/pci/alim15x3.c Version 0.26 Jul 14 2007 * * Copyright (C) 1998-2000 Michel Aubry, Maintainer * Copyright (C) 1998-2000 Andrzej Krzysztofowicz, Maintainer @@ -665,29 +665,34 @@ static void __devinit init_hwif_common_ali15x3 (ide_hwif_t *hwif) hwif->udma_filter = &ali_udma_filter; /* don't use LBA48 DMA on ALi devices before rev 0xC5 */ - if (m5229_revision <= 0xC4) - hwif->host_flags |= IDE_HFLAG_NO_LBA48_DMA; + hwif->no_lba48_dma = (m5229_revision <= 0xC4) ? 1 : 0; - if (hwif->dma_base == 0) + if (!hwif->dma_base) { + hwif->drives[0].autotune = 1; + hwif->drives[1].autotune = 1; return; + } /* * check in ->init_dma guarantees m5229_revision >= 0x20 here */ - if (m5229_revision == 0x20) - hwif->host_flags |= IDE_HFLAG_NO_ATAPI_DMA; + if (m5229_revision > 0x20) + hwif->atapi_dma = 1; if (m5229_revision <= 0x20) hwif->ultra_mask = 0x00; /* no udma */ else if (m5229_revision < 0xC2) - hwif->ultra_mask = ATA_UDMA2; + hwif->ultra_mask = 0x07; /* udma0-2 */ else if (m5229_revision == 0xC2 || m5229_revision == 0xC3) - hwif->ultra_mask = ATA_UDMA4; + hwif->ultra_mask = 0x1f; /* udma0-4 */ else if (m5229_revision == 0xC4) - hwif->ultra_mask = ATA_UDMA5; + hwif->ultra_mask = 0x3f; /* udma0-5 */ else - hwif->ultra_mask = ATA_UDMA6; + hwif->ultra_mask = 0x7f; /* udma0-6 */ + + hwif->mwdma_mask = 0x07; + hwif->swdma_mask = 0x07; hwif->dma_setup = &ali15x3_dma_setup; @@ -771,10 +776,9 @@ static ide_pci_device_t ali15x3_chipset __devinitdata = { .init_chipset = init_chipset_ali15x3, .init_hwif = init_hwif_ali15x3, .init_dma = init_dma_ali15x3, - .host_flags = IDE_HFLAG_BOOTABLE, + .autodma = AUTODMA, + .bootable = ON_BOARD, .pio_mask = ATA_PIO5, - .swdma_mask = ATA_SWDMA2, - .mwdma_mask = ATA_MWDMA2, }; /** diff --git a/trunk/drivers/ide/pci/amd74xx.c b/trunk/drivers/ide/pci/amd74xx.c index 7cafefbf6c1b..3bf3d931eea1 100644 --- a/trunk/drivers/ide/pci/amd74xx.c +++ b/trunk/drivers/ide/pci/amd74xx.c @@ -233,6 +233,7 @@ static unsigned int __devinit init_chipset_amd74xx(struct pci_dev *dev, const ch * Print the boot message. */ + pci_read_config_byte(dev, PCI_REVISION_ID, &t); printk(KERN_INFO "%s: %s (rev %02x) UDMA%s controller\n", amd_chipset->name, pci_name(dev), dev->revision, amd_dma[fls(amd_config->udma_mask) - 1]); @@ -253,14 +254,18 @@ static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif) for (i = 0; i < 2; i++) { hwif->drives[i].io_32bit = 1; hwif->drives[i].unmask = 1; + hwif->drives[i].autotune = 1; } if (!hwif->dma_base) return; + hwif->atapi_dma = 1; + hwif->ultra_mask = amd_config->udma_mask; - if (amd_config->flags & AMD_BAD_SWDMA) - hwif->swdma_mask = 0x00; + hwif->mwdma_mask = 0x07; + if ((amd_config->flags & AMD_BAD_SWDMA) == 0) + hwif->swdma_mask = 0x07; if (hwif->cbl != ATA_CBL_PATA40_SHORT) { if ((amd_80w >> hwif->channel) & 1) @@ -275,14 +280,13 @@ static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif) .name = name_str, \ .init_chipset = init_chipset_amd74xx, \ .init_hwif = init_hwif_amd74xx, \ + .autodma = AUTODMA, \ .enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, \ - .host_flags = IDE_HFLAG_PIO_NO_BLACKLIST | \ - IDE_HFLAG_PIO_NO_DOWNGRADE | \ - IDE_HFLAG_POST_SET_MODE | \ - IDE_HFLAG_BOOTABLE, \ + .bootable = ON_BOARD, \ + .host_flags = IDE_HFLAG_PIO_NO_BLACKLIST \ + | IDE_HFLAG_PIO_NO_DOWNGRADE \ + | IDE_HFLAG_POST_SET_MODE, \ .pio_mask = ATA_PIO5, \ - .swdma_mask = ATA_SWDMA2, \ - .mwdma_mask = ATA_MWDMA2, \ } #define DECLARE_NV_DEV(name_str) \ @@ -290,14 +294,13 @@ static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif) .name = name_str, \ .init_chipset = init_chipset_amd74xx, \ .init_hwif = init_hwif_amd74xx, \ + .autodma = AUTODMA, \ .enablebits = {{0x50,0x02,0x02}, {0x50,0x01,0x01}}, \ - .host_flags = IDE_HFLAG_PIO_NO_BLACKLIST | \ - IDE_HFLAG_PIO_NO_DOWNGRADE | \ - IDE_HFLAG_POST_SET_MODE | \ - IDE_HFLAG_BOOTABLE, \ + .bootable = ON_BOARD, \ + .host_flags = IDE_HFLAG_PIO_NO_BLACKLIST \ + | IDE_HFLAG_PIO_NO_DOWNGRADE \ + | IDE_HFLAG_POST_SET_MODE, \ .pio_mask = ATA_PIO5, \ - .swdma_mask = ATA_SWDMA2, \ - .mwdma_mask = ATA_MWDMA2, \ } static ide_pci_device_t amd74xx_chipsets[] __devinitdata = { diff --git a/trunk/drivers/ide/pci/atiixp.c b/trunk/drivers/ide/pci/atiixp.c index 307843053078..446900da1329 100644 --- a/trunk/drivers/ide/pci/atiixp.c +++ b/trunk/drivers/ide/pci/atiixp.c @@ -172,12 +172,21 @@ static void __devinit init_hwif_atiixp(ide_hwif_t *hwif) u8 ch = hwif->channel; struct pci_dev *pdev = hwif->pci_dev; + if (!hwif->irq) + hwif->irq = ch ? 15 : 14; + hwif->set_pio_mode = &atiixp_set_pio_mode; hwif->set_dma_mode = &atiixp_set_dma_mode; + hwif->drives[0].autotune = 1; + hwif->drives[1].autotune = 1; if (!hwif->dma_base) return; + hwif->atapi_dma = 1; + hwif->ultra_mask = 0x3f; + hwif->mwdma_mask = 0x07; + pci_read_config_byte(pdev, ATIIXP_IDE_UDMA_MODE + ch, &udma_mode); if ((udma_mode & 0x07) >= 0x04 || (udma_mode & 0x70) >= 0x40) @@ -194,20 +203,18 @@ static ide_pci_device_t atiixp_pci_info[] __devinitdata = { { /* 0 */ .name = "ATIIXP", .init_hwif = init_hwif_atiixp, + .autodma = AUTODMA, .enablebits = {{0x48,0x01,0x00}, {0x48,0x08,0x00}}, - .host_flags = IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_BOOTABLE, + .bootable = ON_BOARD, .pio_mask = ATA_PIO4, - .mwdma_mask = ATA_MWDMA2, - .udma_mask = ATA_UDMA5, },{ /* 1 */ .name = "SB600_PATA", .init_hwif = init_hwif_atiixp, + .autodma = AUTODMA, .enablebits = {{0x48,0x01,0x00}, {0x00,0x00,0x00}}, - .host_flags = IDE_HFLAG_SINGLE | IDE_HFLAG_LEGACY_IRQS | - IDE_HFLAG_BOOTABLE, + .bootable = ON_BOARD, + .host_flags = IDE_HFLAG_SINGLE, .pio_mask = ATA_PIO4, - .mwdma_mask = ATA_MWDMA2, - .udma_mask = ATA_UDMA5, }, }; diff --git a/trunk/drivers/ide/pci/cmd64x.c b/trunk/drivers/ide/pci/cmd64x.c index adee2ef6fd71..f3d3bde8daba 100644 --- a/trunk/drivers/ide/pci/cmd64x.c +++ b/trunk/drivers/ide/pci/cmd64x.c @@ -439,8 +439,11 @@ static unsigned int __devinit init_chipset_cmd64x(struct pci_dev *dev, const cha u8 mrdmode = 0; if (dev->device == PCI_DEVICE_ID_CMD_646) { + u8 rev = 0; - switch (dev->revision) { + pci_read_config_byte(dev, PCI_REVISION_ID, &rev); + + switch (rev) { case 0x07: case 0x05: printk("%s: UltraDMA capable\n", name); @@ -502,13 +505,22 @@ static u8 __devinit ata66_cmd64x(ide_hwif_t *hwif) static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif) { struct pci_dev *dev = hwif->pci_dev; + u8 rev = 0; + + pci_read_config_byte(dev, PCI_REVISION_ID, &rev); hwif->set_pio_mode = &cmd64x_set_pio_mode; hwif->set_dma_mode = &cmd64x_set_dma_mode; + hwif->drives[0].autotune = hwif->drives[1].autotune = 1; + if (!hwif->dma_base) return; + hwif->atapi_dma = 1; + hwif->mwdma_mask = 0x07; + hwif->ultra_mask = hwif->cds->udma_mask; + /* * UltraDMA only supported on PCI646U and PCI646U2, which * correspond to revisions 0x03, 0x05 and 0x07 respectively. @@ -521,7 +533,7 @@ static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif) * * So we only do UltraDMA on revision 0x05 and 0x07 chipsets. */ - if (dev->device == PCI_DEVICE_ID_CMD_646 && dev->revision < 5) + if (dev->device == PCI_DEVICE_ID_CMD_646 && rev < 5) hwif->ultra_mask = 0x00; if (hwif->cbl != ATA_CBL_PATA40_SHORT) @@ -536,10 +548,10 @@ static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif) break; case PCI_DEVICE_ID_CMD_646: hwif->chipset = ide_cmd646; - if (dev->revision == 0x01) { + if (rev == 0x01) { hwif->ide_dma_end = &cmd646_1_ide_dma_end; break; - } else if (dev->revision >= 0x03) + } else if (rev >= 0x03) goto alt_irq_bits; /* fall thru */ default: @@ -549,61 +561,80 @@ static void __devinit init_hwif_cmd64x(ide_hwif_t *hwif) } } +static int __devinit init_setup_cmd64x(struct pci_dev *dev, ide_pci_device_t *d) +{ + return ide_setup_pci_device(dev, d); +} + +static int __devinit init_setup_cmd646(struct pci_dev *dev, ide_pci_device_t *d) +{ + /* + * The original PCI0646 didn't have the primary channel enable bit, + * it appeared starting with PCI0646U (i.e. revision ID 3). + */ + if (dev->revision < 3) + d->enablebits[0].reg = 0; + + return ide_setup_pci_device(dev, d); +} + static ide_pci_device_t cmd64x_chipsets[] __devinitdata = { { /* 0 */ .name = "CMD643", + .init_setup = init_setup_cmd64x, .init_chipset = init_chipset_cmd64x, .init_hwif = init_hwif_cmd64x, + .autodma = AUTODMA, .enablebits = {{0x00,0x00,0x00}, {0x51,0x08,0x08}}, - .host_flags = IDE_HFLAG_ABUSE_PREFETCH | IDE_HFLAG_BOOTABLE, + .bootable = ON_BOARD, + .host_flags = IDE_HFLAG_ABUSE_PREFETCH, .pio_mask = ATA_PIO5, - .mwdma_mask = ATA_MWDMA2, .udma_mask = 0x00, /* no udma */ },{ /* 1 */ .name = "CMD646", + .init_setup = init_setup_cmd646, .init_chipset = init_chipset_cmd64x, .init_hwif = init_hwif_cmd64x, + .autodma = AUTODMA, .enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}}, - .host_flags = IDE_HFLAG_ABUSE_PREFETCH | IDE_HFLAG_BOOTABLE, + .bootable = ON_BOARD, + .host_flags = IDE_HFLAG_ABUSE_PREFETCH, .pio_mask = ATA_PIO5, - .mwdma_mask = ATA_MWDMA2, - .udma_mask = ATA_UDMA2, + .udma_mask = 0x07, /* udma0-2 */ },{ /* 2 */ .name = "CMD648", + .init_setup = init_setup_cmd64x, .init_chipset = init_chipset_cmd64x, .init_hwif = init_hwif_cmd64x, + .autodma = AUTODMA, .enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}}, - .host_flags = IDE_HFLAG_ABUSE_PREFETCH | IDE_HFLAG_BOOTABLE, + .bootable = ON_BOARD, + .host_flags = IDE_HFLAG_ABUSE_PREFETCH, .pio_mask = ATA_PIO5, - .mwdma_mask = ATA_MWDMA2, - .udma_mask = ATA_UDMA4, + .udma_mask = 0x1f, /* udma0-4 */ },{ /* 3 */ .name = "CMD649", + .init_setup = init_setup_cmd64x, .init_chipset = init_chipset_cmd64x, .init_hwif = init_hwif_cmd64x, + .autodma = AUTODMA, .enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}}, - .host_flags = IDE_HFLAG_ABUSE_PREFETCH | IDE_HFLAG_BOOTABLE, + .bootable = ON_BOARD, + .host_flags = IDE_HFLAG_ABUSE_PREFETCH, .pio_mask = ATA_PIO5, - .mwdma_mask = ATA_MWDMA2, - .udma_mask = ATA_UDMA5, + .udma_mask = 0x3f, /* udma0-5 */ } }; +/* + * We may have to modify enablebits for PCI0646, so we'd better pass + * a local copy of the ide_pci_device_t structure down the call chain... + */ static int __devinit cmd64x_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - ide_pci_device_t d; - u8 idx = id->driver_data; - - d = cmd64x_chipsets[idx]; - - /* - * The original PCI0646 didn't have the primary channel enable bit, - * it appeared starting with PCI0646U (i.e. revision ID 3). - */ - if (idx == 1 && dev->revision < 3) - d.enablebits[0].reg = 0; + ide_pci_device_t d = cmd64x_chipsets[id->driver_data]; - return ide_setup_pci_device(dev, &d); + return d.init_setup(dev, &d); } static const struct pci_device_id cmd64x_pci_tbl[] = { diff --git a/trunk/drivers/ide/pci/cs5520.c b/trunk/drivers/ide/pci/cs5520.c index aa98e817d385..a8bf4940ca9c 100644 --- a/trunk/drivers/ide/pci/cs5520.c +++ b/trunk/drivers/ide/pci/cs5520.c @@ -105,6 +105,18 @@ static void cs5520_set_dma_mode(ide_drive_t *drive, const u8 speed) cs5520_set_pio_mode(drive, 0); } +/* + * We provide a callback for our nonstandard DMA location + */ + +static void __devinit cs5520_init_setup_dma(struct pci_dev *dev, ide_pci_device_t *d, ide_hwif_t *hwif) +{ + unsigned long bmide = pci_resource_start(dev, 2); /* Not the usual 4 */ + if(hwif->mate && hwif->mate->dma_base) /* Second channel at primary + 8 */ + bmide += 8; + ide_setup_dma(hwif, bmide, 8); +} + /* * We wrap the DMA activate to set the vdma flag. This is needed * so that the IDE DMA layer issues PIO not DMA commands over the @@ -113,7 +125,6 @@ static void cs5520_set_dma_mode(ide_drive_t *drive, const u8 speed) static int cs5520_dma_on(ide_drive_t *drive) { - /* ATAPI is harder so leave it for now */ drive->vdma = 1; return 0; } @@ -123,21 +134,29 @@ static void __devinit init_hwif_cs5520(ide_hwif_t *hwif) hwif->set_pio_mode = &cs5520_set_pio_mode; hwif->set_dma_mode = &cs5520_set_dma_mode; - if (hwif->dma_base == 0) + if (hwif->dma_base == 0) { + hwif->drives[1].autotune = hwif->drives[0].autotune = 1; return; + } hwif->ide_dma_on = &cs5520_dma_on; + + /* ATAPI is harder so leave it for now */ + hwif->atapi_dma = 0; + hwif->ultra_mask = 0; + hwif->swdma_mask = 0; + hwif->mwdma_mask = 0; } #define DECLARE_CS_DEV(name_str) \ { \ .name = name_str, \ + .init_setup_dma = cs5520_init_setup_dma, \ .init_hwif = init_hwif_cs5520, \ + .autodma = AUTODMA, \ + .bootable = ON_BOARD, \ .host_flags = IDE_HFLAG_ISA_PORTS | \ - IDE_HFLAG_CS5520 | \ - IDE_HFLAG_VDMA | \ - IDE_HFLAG_NO_ATAPI_DMA | \ - IDE_HFLAG_BOOTABLE, \ + IDE_HFLAG_VDMA, \ .pio_mask = ATA_PIO4, \ } diff --git a/trunk/drivers/ide/pci/cs5530.c b/trunk/drivers/ide/pci/cs5530.c index ba0c6eba024b..0d23b8aabe9c 100644 --- a/trunk/drivers/ide/pci/cs5530.c +++ b/trunk/drivers/ide/pci/cs5530.c @@ -245,6 +245,9 @@ static void __devinit init_hwif_cs5530 (ide_hwif_t *hwif) unsigned long basereg; u32 d0_timings; + if (hwif->mate) + hwif->serialized = hwif->mate->serialized = 1; + hwif->set_pio_mode = &cs5530_set_pio_mode; hwif->set_dma_mode = &cs5530_set_dma_mode; @@ -255,9 +258,16 @@ static void __devinit init_hwif_cs5530 (ide_hwif_t *hwif) if (CS5530_BAD_PIO(inl(basereg + 8))) outl(cs5530_pio_timings[(d0_timings >> 31) & 1][0], basereg + 8); + hwif->drives[0].autotune = 1; + hwif->drives[1].autotune = 1; + if (hwif->dma_base == 0) return; + hwif->atapi_dma = 1; + hwif->ultra_mask = 0x07; + hwif->mwdma_mask = 0x07; + hwif->udma_filter = cs5530_udma_filter; } @@ -265,12 +275,10 @@ static ide_pci_device_t cs5530_chipset __devinitdata = { .name = "CS5530", .init_chipset = init_chipset_cs5530, .init_hwif = init_hwif_cs5530, - .host_flags = IDE_HFLAG_SERIALIZE | - IDE_HFLAG_POST_SET_MODE | - IDE_HFLAG_BOOTABLE, + .autodma = AUTODMA, + .bootable = ON_BOARD, .pio_mask = ATA_PIO4, - .mwdma_mask = ATA_MWDMA2, - .udma_mask = ATA_UDMA2, + .host_flags = IDE_HFLAG_POST_SET_MODE, }; static int __devinit cs5530_init_one(struct pci_dev *dev, const struct pci_device_id *id) diff --git a/trunk/drivers/ide/pci/cs5535.c b/trunk/drivers/ide/pci/cs5535.c index 5ac82ffa5c09..e4891a16afef 100644 --- a/trunk/drivers/ide/pci/cs5535.c +++ b/trunk/drivers/ide/pci/cs5535.c @@ -84,7 +84,7 @@ static void cs5535_set_speed(ide_drive_t *drive, const u8 speed) /* Set the PIO timings */ if ((speed & XFER_MODE) == XFER_PIO) { - ide_drive_t *pair = ide_get_paired_drive(drive); + ide_drive_t *pair = &drive->hwif->drives[drive->dn ^ 1]; u8 cmd, pioa; cmd = pioa = speed - XFER_PIO_0; @@ -180,20 +180,25 @@ static void __devinit init_hwif_cs5535(ide_hwif_t *hwif) hwif->set_pio_mode = &cs5535_set_pio_mode; hwif->set_dma_mode = &cs5535_set_dma_mode; + hwif->drives[1].autotune = hwif->drives[0].autotune = 1; + if (hwif->dma_base == 0) return; + hwif->atapi_dma = 1; + hwif->ultra_mask = 0x1F; + hwif->mwdma_mask = 0x07; + hwif->cbl = cs5535_cable_detect(hwif->pci_dev); } static ide_pci_device_t cs5535_chipset __devinitdata = { .name = "CS5535", .init_hwif = init_hwif_cs5535, - .host_flags = IDE_HFLAG_SINGLE | IDE_HFLAG_POST_SET_MODE | - IDE_HFLAG_BOOTABLE, + .autodma = AUTODMA, + .bootable = ON_BOARD, + .host_flags = IDE_HFLAG_SINGLE | IDE_HFLAG_POST_SET_MODE, .pio_mask = ATA_PIO4, - .mwdma_mask = ATA_MWDMA2, - .udma_mask = ATA_UDMA4, }; static int __devinit cs5535_init_one(struct pci_dev *dev, diff --git a/trunk/drivers/ide/pci/cy82c693.c b/trunk/drivers/ide/pci/cy82c693.c index efc20bd97fd5..c498ecfd7fcb 100644 --- a/trunk/drivers/ide/pci/cy82c693.c +++ b/trunk/drivers/ide/pci/cy82c693.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/cy82c693.c Version 0.41 Aug 27, 2007 + * linux/drivers/ide/pci/cy82c693.c Version 0.40 Sep. 10, 2002 * * Copyright (C) 1998-2000 Andreas S. Krebs (akrebs@altavista.net), Maintainer * Copyright (C) 1998-2002 Andre Hedrick , Integrator @@ -431,8 +431,15 @@ static void __devinit init_hwif_cy82c693(ide_hwif_t *hwif) hwif->chipset = ide_cy82c693; hwif->set_pio_mode = &cy82c693_set_pio_mode; - if (hwif->dma_base == 0) + if (!hwif->dma_base) { + hwif->drives[0].autotune = 1; + hwif->drives[1].autotune = 1; return; + } + + hwif->atapi_dma = 1; + hwif->mwdma_mask = 0x04; + hwif->swdma_mask = 0x04; hwif->ide_dma_on = &cy82c693_ide_dma_on; } @@ -454,11 +461,10 @@ static ide_pci_device_t cy82c693_chipset __devinitdata = { .init_chipset = init_chipset_cy82c693, .init_iops = init_iops_cy82c693, .init_hwif = init_hwif_cy82c693, - .host_flags = IDE_HFLAG_SINGLE | IDE_HFLAG_TRUST_BIOS_FOR_DMA | - IDE_HFLAG_BOOTABLE, + .autodma = AUTODMA, + .bootable = ON_BOARD, + .host_flags = IDE_HFLAG_SINGLE | IDE_HFLAG_TRUST_BIOS_FOR_DMA, .pio_mask = ATA_PIO4, - .swdma_mask = ATA_SWDMA2_ONLY, - .mwdma_mask = ATA_MWDMA2_ONLY, }; static int __devinit cy82c693_init_one(struct pci_dev *dev, const struct pci_device_id *id) diff --git a/trunk/drivers/ide/pci/generic.c b/trunk/drivers/ide/pci/generic.c index 51165832e7f2..cce6311b02df 100644 --- a/trunk/drivers/ide/pci/generic.c +++ b/trunk/drivers/ide/pci/generic.c @@ -65,65 +65,119 @@ static void __devinit init_hwif_generic (ide_hwif_t *hwif) default: break; } + + if (!(hwif->dma_base)) + return; + + hwif->atapi_dma = 1; + hwif->ultra_mask = 0x7f; + hwif->mwdma_mask = 0x07; + hwif->swdma_mask = 0x07; } -#define DECLARE_GENERIC_PCI_DEV(name_str, dma_setting) \ - { \ - .name = name_str, \ - .init_hwif = init_hwif_generic, \ - .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA | \ - dma_setting | \ - IDE_HFLAG_BOOTABLE, \ - .swdma_mask = ATA_SWDMA2, \ - .mwdma_mask = ATA_MWDMA2, \ - .udma_mask = ATA_UDMA6, \ +#if 0 + /* Logic to add back later on */ + + if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE) { + ide_pci_device_t *unknown = unknown_chipset; + init_setup_unknown(dev, unknown); + return 1; } + return 0; +#endif static ide_pci_device_t generic_chipsets[] __devinitdata = { - /* 0 */ DECLARE_GENERIC_PCI_DEV("Unknown", 0), - - { /* 1 */ + { /* 0 */ + .name = "Unknown", + .init_hwif = init_hwif_generic, + .autodma = AUTODMA, + .bootable = ON_BOARD, + .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA, + },{ /* 1 */ .name = "NS87410", .init_hwif = init_hwif_generic, + .autodma = AUTODMA, .enablebits = {{0x43,0x08,0x08}, {0x47,0x08,0x08}}, - .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA | - IDE_HFLAG_BOOTABLE, - .swdma_mask = ATA_SWDMA2, - .mwdma_mask = ATA_MWDMA2, - .udma_mask = ATA_UDMA6, - }, - - /* 2 */ DECLARE_GENERIC_PCI_DEV("SAMURAI", 0), - /* 3 */ DECLARE_GENERIC_PCI_DEV("HT6565", 0), - /* 4 */ DECLARE_GENERIC_PCI_DEV("UM8673F", IDE_HFLAG_NO_DMA), - /* 5 */ DECLARE_GENERIC_PCI_DEV("UM8886A", IDE_HFLAG_NO_DMA), - /* 6 */ DECLARE_GENERIC_PCI_DEV("UM8886BF", IDE_HFLAG_NO_DMA), - /* 7 */ DECLARE_GENERIC_PCI_DEV("HINT_IDE", 0), - /* 8 */ DECLARE_GENERIC_PCI_DEV("VIA_IDE", IDE_HFLAG_NO_AUTODMA), - /* 9 */ DECLARE_GENERIC_PCI_DEV("OPTI621V", IDE_HFLAG_NO_AUTODMA), - - { /* 10 */ + .bootable = ON_BOARD, + .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA, + },{ /* 2 */ + .name = "SAMURAI", + .init_hwif = init_hwif_generic, + .autodma = AUTODMA, + .bootable = ON_BOARD, + .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA, + },{ /* 3 */ + .name = "HT6565", + .init_hwif = init_hwif_generic, + .autodma = AUTODMA, + .bootable = ON_BOARD, + .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA, + },{ /* 4 */ + .name = "UM8673F", + .init_hwif = init_hwif_generic, + .autodma = NODMA, + .bootable = ON_BOARD, + .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA, + },{ /* 5 */ + .name = "UM8886A", + .init_hwif = init_hwif_generic, + .autodma = NODMA, + .bootable = ON_BOARD, + .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA, + },{ /* 6 */ + .name = "UM8886BF", + .init_hwif = init_hwif_generic, + .autodma = NODMA, + .bootable = ON_BOARD, + .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA, + },{ /* 7 */ + .name = "HINT_IDE", + .init_hwif = init_hwif_generic, + .autodma = AUTODMA, + .bootable = ON_BOARD, + .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA, + },{ /* 8 */ + .name = "VIA_IDE", + .init_hwif = init_hwif_generic, + .autodma = NOAUTODMA, + .bootable = ON_BOARD, + .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA, + },{ /* 9 */ + .name = "OPTI621V", + .init_hwif = init_hwif_generic, + .autodma = NOAUTODMA, + .bootable = ON_BOARD, + .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA, + },{ /* 10 */ .name = "VIA8237SATA", .init_hwif = init_hwif_generic, - .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA | - IDE_HFLAG_OFF_BOARD, - .swdma_mask = ATA_SWDMA2, - .mwdma_mask = ATA_MWDMA2, - .udma_mask = ATA_UDMA6, - }, - - /* 11 */ DECLARE_GENERIC_PCI_DEV("Piccolo0102", IDE_HFLAG_NO_AUTODMA), - /* 12 */ DECLARE_GENERIC_PCI_DEV("Piccolo0103", IDE_HFLAG_NO_AUTODMA), - /* 13 */ DECLARE_GENERIC_PCI_DEV("Piccolo0105", IDE_HFLAG_NO_AUTODMA), - - { /* 14 */ + .autodma = AUTODMA, + .bootable = OFF_BOARD, + .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA, + },{ /* 11 */ + .name = "Piccolo0102", + .init_hwif = init_hwif_generic, + .autodma = NOAUTODMA, + .bootable = ON_BOARD, + .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA, + },{ /* 12 */ + .name = "Piccolo0103", + .init_hwif = init_hwif_generic, + .autodma = NOAUTODMA, + .bootable = ON_BOARD, + .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA, + },{ /* 13 */ + .name = "Piccolo0105", + .init_hwif = init_hwif_generic, + .autodma = NOAUTODMA, + .bootable = ON_BOARD, + .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA, + },{ /* 14 */ .name = "Revolution", .init_hwif = init_hwif_generic, - .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA | - IDE_HFLAG_OFF_BOARD, - .swdma_mask = ATA_SWDMA2, - .mwdma_mask = ATA_MWDMA2, - .udma_mask = ATA_UDMA6, + .autodma = AUTODMA, + .bootable = OFF_BOARD, + .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA, } }; diff --git a/trunk/drivers/ide/pci/hpt34x.c b/trunk/drivers/ide/pci/hpt34x.c index 67af1a7dde30..44ac0e2f7a09 100644 --- a/trunk/drivers/ide/pci/hpt34x.c +++ b/trunk/drivers/ide/pci/hpt34x.c @@ -125,45 +125,49 @@ static unsigned int __devinit init_chipset_hpt34x(struct pci_dev *dev, const cha static void __devinit init_hwif_hpt34x(ide_hwif_t *hwif) { + u16 pcicmd = 0; + hwif->set_pio_mode = &hpt34x_set_pio_mode; hwif->set_dma_mode = &hpt34x_set_mode; -} -static ide_pci_device_t hpt34x_chipsets[] __devinitdata = { - { /* 0 */ - .name = "HPT343", - .init_chipset = init_chipset_hpt34x, - .init_hwif = init_hwif_hpt34x, - .extra = 16, - .host_flags = IDE_HFLAG_NO_ATAPI_DMA | - IDE_HFLAG_NO_AUTODMA, - .pio_mask = ATA_PIO5, - }, - { /* 1 */ - .name = "HPT345", - .init_chipset = init_chipset_hpt34x, - .init_hwif = init_hwif_hpt34x, - .extra = 16, - .host_flags = IDE_HFLAG_NO_ATAPI_DMA | - IDE_HFLAG_NO_AUTODMA | - IDE_HFLAG_OFF_BOARD, - .pio_mask = ATA_PIO5, + hwif->drives[0].autotune = 1; + hwif->drives[1].autotune = 1; + + pci_read_config_word(hwif->pci_dev, PCI_COMMAND, &pcicmd); + + if (!hwif->dma_base) + return; + #ifdef CONFIG_HPT34X_AUTODMA - .swdma_mask = ATA_SWDMA2, - .mwdma_mask = ATA_MWDMA2, - .udma_mask = ATA_UDMA2, + if ((pcicmd & PCI_COMMAND_MEMORY) == 0) + return; + + hwif->ultra_mask = 0x07; + hwif->mwdma_mask = 0x07; + hwif->swdma_mask = 0x07; #endif - } +} + +static ide_pci_device_t hpt34x_chipset __devinitdata = { + .name = "HPT34X", + .init_chipset = init_chipset_hpt34x, + .init_hwif = init_hwif_hpt34x, + .autodma = NOAUTODMA, + .bootable = NEVER_BOARD, + .extra = 16, + .pio_mask = ATA_PIO5, }; static int __devinit hpt34x_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - ide_pci_device_t *d; + ide_pci_device_t *d = &hpt34x_chipset; + static char *chipset_names[] = {"HPT343", "HPT345"}; u16 pcicmd = 0; pci_read_config_word(dev, PCI_COMMAND, &pcicmd); - d = &hpt34x_chipsets[(pcicmd & PCI_COMMAND_MEMORY) ? 1 : 0]; + d->name = chipset_names[(pcicmd & PCI_COMMAND_MEMORY) ? 1 : 0]; + d->bootable = (pcicmd & PCI_COMMAND_MEMORY) ? OFF_BOARD : NEVER_BOARD; return ide_setup_pci_device(dev, d); } diff --git a/trunk/drivers/ide/pci/hpt366.c b/trunk/drivers/ide/pci/hpt366.c index 18f5b7ddaee6..fcb21ddab2cc 100644 --- a/trunk/drivers/ide/pci/hpt366.c +++ b/trunk/drivers/ide/pci/hpt366.c @@ -1,10 +1,9 @@ /* - * linux/drivers/ide/pci/hpt366.c Version 1.20 Oct 1, 2007 + * linux/drivers/ide/pci/hpt366.c Version 1.14 Oct 1, 2007 * * Copyright (C) 1999-2003 Andre Hedrick * Portions Copyright (C) 2001 Sun Microsystems, Inc. * Portions Copyright (C) 2003 Red Hat Inc - * Portions Copyright (C) 2007 Bartlomiej Zolnierkiewicz * Portions Copyright (C) 2005-2007 MontaVista Software, Inc. * * Thanks to HighPoint Technologies for their assistance, and hardware. @@ -394,9 +393,8 @@ enum ata_clock { */ struct hpt_info { - char *chip_name; /* Chip name */ u8 chip_type; /* Chip type */ - u8 udma_mask; /* Allowed UltraDMA modes mask. */ + u8 max_ultra; /* Max. UltraDMA mode allowed */ u8 dpll_clk; /* DPLL clock in MHz */ u8 pci_clk; /* PCI clock in MHz */ u32 **settings; /* Chipset settings table */ @@ -434,89 +432,78 @@ static u32 *hpt37x_settings[NUM_ATA_CLOCKS] = { }; static struct hpt_info hpt36x __devinitdata = { - .chip_name = "HPT36x", .chip_type = HPT36x, - .udma_mask = HPT366_ALLOW_ATA66_3 ? (HPT366_ALLOW_ATA66_4 ? ATA_UDMA4 : ATA_UDMA3) : ATA_UDMA2, + .max_ultra = HPT366_ALLOW_ATA66_3 ? (HPT366_ALLOW_ATA66_4 ? 4 : 3) : 2, .dpll_clk = 0, /* no DPLL */ .settings = hpt36x_settings }; static struct hpt_info hpt370 __devinitdata = { - .chip_name = "HPT370", .chip_type = HPT370, - .udma_mask = HPT370_ALLOW_ATA100_5 ? ATA_UDMA5 : ATA_UDMA4, + .max_ultra = HPT370_ALLOW_ATA100_5 ? 5 : 4, .dpll_clk = 48, .settings = hpt37x_settings }; static struct hpt_info hpt370a __devinitdata = { - .chip_name = "HPT370A", .chip_type = HPT370A, - .udma_mask = HPT370_ALLOW_ATA100_5 ? ATA_UDMA5 : ATA_UDMA4, + .max_ultra = HPT370_ALLOW_ATA100_5 ? 5 : 4, .dpll_clk = 48, .settings = hpt37x_settings }; static struct hpt_info hpt374 __devinitdata = { - .chip_name = "HPT374", .chip_type = HPT374, - .udma_mask = ATA_UDMA5, + .max_ultra = 5, .dpll_clk = 48, .settings = hpt37x_settings }; static struct hpt_info hpt372 __devinitdata = { - .chip_name = "HPT372", .chip_type = HPT372, - .udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, + .max_ultra = HPT372_ALLOW_ATA133_6 ? 6 : 5, .dpll_clk = 55, .settings = hpt37x_settings }; static struct hpt_info hpt372a __devinitdata = { - .chip_name = "HPT372A", .chip_type = HPT372A, - .udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, + .max_ultra = HPT372_ALLOW_ATA133_6 ? 6 : 5, .dpll_clk = 66, .settings = hpt37x_settings }; static struct hpt_info hpt302 __devinitdata = { - .chip_name = "HPT302", .chip_type = HPT302, - .udma_mask = HPT302_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, + .max_ultra = HPT372_ALLOW_ATA133_6 ? 6 : 5, .dpll_clk = 66, .settings = hpt37x_settings }; static struct hpt_info hpt371 __devinitdata = { - .chip_name = "HPT371", .chip_type = HPT371, - .udma_mask = HPT371_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, + .max_ultra = HPT371_ALLOW_ATA133_6 ? 6 : 5, .dpll_clk = 66, .settings = hpt37x_settings }; static struct hpt_info hpt372n __devinitdata = { - .chip_name = "HPT372N", .chip_type = HPT372N, - .udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, + .max_ultra = HPT372_ALLOW_ATA133_6 ? 6 : 5, .dpll_clk = 77, .settings = hpt37x_settings }; static struct hpt_info hpt302n __devinitdata = { - .chip_name = "HPT302N", .chip_type = HPT302N, - .udma_mask = HPT302_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, + .max_ultra = HPT302_ALLOW_ATA133_6 ? 6 : 5, .dpll_clk = 77, .settings = hpt37x_settings }; static struct hpt_info hpt371n __devinitdata = { - .chip_name = "HPT371N", .chip_type = HPT371N, - .udma_mask = HPT371_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, + .max_ultra = HPT371_ALLOW_ATA133_6 ? 6 : 5, .dpll_clk = 77, .settings = hpt37x_settings }; @@ -689,11 +676,12 @@ static int hpt3xx_quirkproc(ide_drive_t *drive) static void hpt3xx_intrproc(ide_drive_t *drive) { + ide_hwif_t *hwif = HWIF(drive); + if (drive->quirk_list) return; - /* drives in the quirk_list may not like intr setups/cleanups */ - outb(drive->ctl | 2, IDE_CONTROL_REG); + hwif->OUTB(drive->ctl | 2, IDE_CONTROL_REG); } static void hpt3xx_maskproc(ide_drive_t *drive, int mask) @@ -721,8 +709,8 @@ static void hpt3xx_maskproc(ide_drive_t *drive, int mask) enable_irq (hwif->irq); } } else - outb(mask ? (drive->ctl | 2) : (drive->ctl & ~2), - IDE_CONTROL_REG); + hwif->OUTB(mask ? (drive->ctl | 2) : (drive->ctl & ~2), + IDE_CONTROL_REG); } /* @@ -762,9 +750,9 @@ static void hpt370_irq_timeout(ide_drive_t *drive) printk(KERN_DEBUG "%s: %d bytes in FIFO\n", drive->name, bfifo & 0x1ff); /* get DMA command mode */ - dma_cmd = inb(hwif->dma_command); + dma_cmd = hwif->INB(hwif->dma_command); /* stop DMA */ - outb(dma_cmd & ~0x1, hwif->dma_command); + hwif->OUTB(dma_cmd & ~0x1, hwif->dma_command); hpt370_clear_engine(drive); } @@ -779,12 +767,12 @@ static void hpt370_ide_dma_start(ide_drive_t *drive) static int hpt370_ide_dma_end(ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); - u8 dma_stat = inb(hwif->dma_status); + u8 dma_stat = hwif->INB(hwif->dma_status); if (dma_stat & 0x01) { /* wait a little */ udelay(20); - dma_stat = inb(hwif->dma_status); + dma_stat = hwif->INB(hwif->dma_status); if (dma_stat & 0x01) hpt370_irq_timeout(drive); } @@ -845,32 +833,34 @@ static int hpt374_ide_dma_end(ide_drive_t *drive) static void hpt3xxn_set_clock(ide_hwif_t *hwif, u8 mode) { - u8 scr2 = inb(hwif->dma_master + 0x7b); + u8 scr2 = hwif->INB(hwif->dma_master + 0x7b); if ((scr2 & 0x7f) == mode) return; /* Tristate the bus */ - outb(0x80, hwif->dma_master + 0x73); - outb(0x80, hwif->dma_master + 0x77); + hwif->OUTB(0x80, hwif->dma_master + 0x73); + hwif->OUTB(0x80, hwif->dma_master + 0x77); /* Switch clock and reset channels */ - outb(mode, hwif->dma_master + 0x7b); - outb(0xc0, hwif->dma_master + 0x79); + hwif->OUTB(mode, hwif->dma_master + 0x7b); + hwif->OUTB(0xc0, hwif->dma_master + 0x79); /* * Reset the state machines. * NOTE: avoid accidentally enabling the disabled channels. */ - outb(inb(hwif->dma_master + 0x70) | 0x32, hwif->dma_master + 0x70); - outb(inb(hwif->dma_master + 0x74) | 0x32, hwif->dma_master + 0x74); + hwif->OUTB(hwif->INB(hwif->dma_master + 0x70) | 0x32, + hwif->dma_master + 0x70); + hwif->OUTB(hwif->INB(hwif->dma_master + 0x74) | 0x32, + hwif->dma_master + 0x74); /* Complete reset */ - outb(0x00, hwif->dma_master + 0x79); + hwif->OUTB(0x00, hwif->dma_master + 0x79); /* Reconnect channels to bus */ - outb(0x00, hwif->dma_master + 0x73); - outb(0x00, hwif->dma_master + 0x77); + hwif->OUTB(0x00, hwif->dma_master + 0x73); + hwif->OUTB(0x00, hwif->dma_master + 0x77); } /** @@ -1149,7 +1139,7 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev, const cha * Select 66 MHz DPLL clock only if UltraATA/133 mode is * supported/enabled, use 50 MHz DPLL clock otherwise... */ - if (info->udma_mask == ATA_UDMA6) { + if (info->max_ultra == 6) { dpll_clk = 66; clock = ATA_CLOCK_66MHZ; } else if (dpll_clk) { /* HPT36x chips don't have DPLL */ @@ -1301,9 +1291,14 @@ static void __devinit init_hwif_hpt366(ide_hwif_t *hwif) if (new_mcr != old_mcr) pci_write_config_byte(dev, hwif->select_data + 1, new_mcr); + hwif->drives[0].autotune = hwif->drives[1].autotune = 1; + if (hwif->dma_base == 0) return; + hwif->ultra_mask = hwif->cds->udma_mask; + hwif->mwdma_mask = 0x07; + /* * The HPT37x uses the CBLID pins as outputs for MA15/MA16 * address lines to access an external EEPROM. To read valid @@ -1359,7 +1354,7 @@ static void __devinit init_dma_hpt366(ide_hwif_t *hwif, unsigned long dmabase) u8 dma_new = 0, dma_old = 0; unsigned long flags; - dma_old = inb(dmabase + 2); + dma_old = hwif->INB(dmabase + 2); local_irq_save(flags); @@ -1370,26 +1365,60 @@ static void __devinit init_dma_hpt366(ide_hwif_t *hwif, unsigned long dmabase) if (masterdma & 0x30) dma_new |= 0x20; if ( slavedma & 0x30) dma_new |= 0x40; if (dma_new != dma_old) - outb(dma_new, dmabase + 2); + hwif->OUTB(dma_new, dmabase + 2); local_irq_restore(flags); ide_setup_dma(hwif, dmabase, 8); } -static void __devinit hpt374_init(struct pci_dev *dev, struct pci_dev *dev2) +static int __devinit init_setup_hpt374(struct pci_dev *dev, ide_pci_device_t *d) { - if (dev2->irq != dev->irq) { - /* FIXME: we need a core pci_set_interrupt() */ - dev2->irq = dev->irq; - printk(KERN_INFO "HPT374: PCI config space interrupt fixed\n"); + struct pci_dev *dev2; + + if (PCI_FUNC(dev->devfn) & 1) + return -ENODEV; + + pci_set_drvdata(dev, &hpt374); + + if ((dev2 = pci_get_slot(dev->bus, dev->devfn + 1)) != NULL) { + int ret; + + pci_set_drvdata(dev2, &hpt374); + + if (dev2->irq != dev->irq) { + /* FIXME: we need a core pci_set_interrupt() */ + dev2->irq = dev->irq; + printk(KERN_WARNING "%s: PCI config space interrupt " + "fixed.\n", d->name); + } + ret = ide_setup_pci_devices(dev, dev2, d); + if (ret < 0) + pci_dev_put(dev2); + return ret; } + return ide_setup_pci_device(dev, d); +} + +static int __devinit init_setup_hpt372n(struct pci_dev *dev, ide_pci_device_t *d) +{ + pci_set_drvdata(dev, &hpt372n); + + return ide_setup_pci_device(dev, d); } -static void __devinit hpt371_init(struct pci_dev *dev) +static int __devinit init_setup_hpt371(struct pci_dev *dev, ide_pci_device_t *d) { + struct hpt_info *info; u8 mcr1 = 0; + if (dev->revision > 1) { + d->name = "HPT371N"; + + info = &hpt371n; + } else + info = &hpt371; + /* * HPT371 chips physically have only one channel, the secondary one, * but the primary channel registers do exist! Go figure... @@ -1399,102 +1428,194 @@ static void __devinit hpt371_init(struct pci_dev *dev) pci_read_config_byte(dev, 0x50, &mcr1); if (mcr1 & 0x04) pci_write_config_byte(dev, 0x50, mcr1 & ~0x04); + + pci_set_drvdata(dev, info); + + return ide_setup_pci_device(dev, d); } -static int __devinit hpt36x_init(struct pci_dev *dev, struct pci_dev *dev2) +static int __devinit init_setup_hpt372a(struct pci_dev *dev, ide_pci_device_t *d) { - u8 mcr1 = 0, pin1 = 0, pin2 = 0; + struct hpt_info *info; - /* - * Now we'll have to force both channels enabled if - * at least one of them has been enabled by BIOS... - */ - pci_read_config_byte(dev, 0x50, &mcr1); - if (mcr1 & 0x30) - pci_write_config_byte(dev, 0x50, mcr1 | 0x30); + if (dev->revision > 1) { + d->name = "HPT372N"; + + info = &hpt372n; + } else + info = &hpt372a; + pci_set_drvdata(dev, info); - pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin1); - pci_read_config_byte(dev2, PCI_INTERRUPT_PIN, &pin2); + return ide_setup_pci_device(dev, d); +} - if (pin1 != pin2 && dev->irq == dev2->irq) { - printk(KERN_INFO "HPT36x: onboard version of chipset, " - "pin1=%d pin2=%d\n", pin1, pin2); - return 1; - } +static int __devinit init_setup_hpt302(struct pci_dev *dev, ide_pci_device_t *d) +{ + struct hpt_info *info; - return 0; + if (dev->revision > 1) { + d->name = "HPT302N"; + + info = &hpt302n; + } else + info = &hpt302; + pci_set_drvdata(dev, info); + + return ide_setup_pci_device(dev, d); } -static ide_pci_device_t hpt366_chipsets[] __devinitdata = { - { /* 0 */ - .name = "HPT36x", - .init_chipset = init_chipset_hpt366, - .init_hwif = init_hwif_hpt366, - .init_dma = init_dma_hpt366, +static int __devinit init_setup_hpt366(struct pci_dev *dev, ide_pci_device_t *d) +{ + struct pci_dev *dev2; + u8 rev = dev->revision; + static char *chipset_names[] = { "HPT366", "HPT366", "HPT368", + "HPT370", "HPT370A", "HPT372", + "HPT372N" }; + static struct hpt_info *info[] = { &hpt36x, &hpt36x, &hpt36x, + &hpt370, &hpt370a, &hpt372, + &hpt372n }; + + if (PCI_FUNC(dev->devfn) & 1) + return -ENODEV; + + switch (rev) { + case 0: + case 1: + case 2: /* * HPT36x chips have one channel per function and have * both channel enable bits located differently and visible * to both functions -- really stupid design decision... :-( * Bit 4 is for the primary channel, bit 5 for the secondary. */ - .enablebits = {{0x50,0x10,0x10}, {0x54,0x04,0x04}}, + d->host_flags |= IDE_HFLAG_SINGLE; + d->enablebits[0].mask = d->enablebits[0].val = 0x10; + + d->udma_mask = HPT366_ALLOW_ATA66_3 ? (HPT366_ALLOW_ATA66_4 ? + ATA_UDMA4 : ATA_UDMA3) : ATA_UDMA2; + break; + case 3: + case 4: + d->udma_mask = HPT370_ALLOW_ATA100_5 ? ATA_UDMA5 : ATA_UDMA4; + break; + default: + rev = 6; + /* fall thru */ + case 5: + case 6: + d->udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5; + break; + } + + d->name = chipset_names[rev]; + + pci_set_drvdata(dev, info[rev]); + + if (rev > 2) + goto init_single; + + if ((dev2 = pci_get_slot(dev->bus, dev->devfn + 1)) != NULL) { + u8 mcr1 = 0, pin1 = 0, pin2 = 0; + int ret; + + pci_set_drvdata(dev2, info[rev]); + + /* + * Now we'll have to force both channels enabled if + * at least one of them has been enabled by BIOS... + */ + pci_read_config_byte(dev, 0x50, &mcr1); + if (mcr1 & 0x30) + pci_write_config_byte(dev, 0x50, mcr1 | 0x30); + + pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin1); + pci_read_config_byte(dev2, PCI_INTERRUPT_PIN, &pin2); + if (pin1 != pin2 && dev->irq == dev2->irq) { + d->bootable = ON_BOARD; + printk("%s: onboard version of chipset, pin1=%d pin2=%d\n", + d->name, pin1, pin2); + } + ret = ide_setup_pci_devices(dev, dev2, d); + if (ret < 0) + pci_dev_put(dev2); + return ret; + } +init_single: + return ide_setup_pci_device(dev, d); +} + +static ide_pci_device_t hpt366_chipsets[] __devinitdata = { + { /* 0 */ + .name = "HPT366", + .init_setup = init_setup_hpt366, + .init_chipset = init_chipset_hpt366, + .init_hwif = init_hwif_hpt366, + .init_dma = init_dma_hpt366, + .autodma = AUTODMA, + .enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}}, + .bootable = OFF_BOARD, .extra = 240, - .host_flags = IDE_HFLAG_SINGLE | - IDE_HFLAG_NO_ATAPI_DMA | - IDE_HFLAG_OFF_BOARD, .pio_mask = ATA_PIO4, - .mwdma_mask = ATA_MWDMA2, },{ /* 1 */ .name = "HPT372A", + .init_setup = init_setup_hpt372a, .init_chipset = init_chipset_hpt366, .init_hwif = init_hwif_hpt366, .init_dma = init_dma_hpt366, + .autodma = AUTODMA, .enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}}, + .udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, + .bootable = OFF_BOARD, .extra = 240, - .host_flags = IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_OFF_BOARD, .pio_mask = ATA_PIO4, - .mwdma_mask = ATA_MWDMA2, },{ /* 2 */ .name = "HPT302", + .init_setup = init_setup_hpt302, .init_chipset = init_chipset_hpt366, .init_hwif = init_hwif_hpt366, .init_dma = init_dma_hpt366, + .autodma = AUTODMA, .enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}}, + .udma_mask = HPT302_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, + .bootable = OFF_BOARD, .extra = 240, - .host_flags = IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_OFF_BOARD, .pio_mask = ATA_PIO4, - .mwdma_mask = ATA_MWDMA2, },{ /* 3 */ .name = "HPT371", + .init_setup = init_setup_hpt371, .init_chipset = init_chipset_hpt366, .init_hwif = init_hwif_hpt366, .init_dma = init_dma_hpt366, + .autodma = AUTODMA, .enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}}, + .udma_mask = HPT371_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, + .bootable = OFF_BOARD, .extra = 240, - .host_flags = IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_OFF_BOARD, .pio_mask = ATA_PIO4, - .mwdma_mask = ATA_MWDMA2, },{ /* 4 */ .name = "HPT374", + .init_setup = init_setup_hpt374, .init_chipset = init_chipset_hpt366, .init_hwif = init_hwif_hpt366, .init_dma = init_dma_hpt366, + .autodma = AUTODMA, .enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}}, .udma_mask = ATA_UDMA5, + .bootable = OFF_BOARD, .extra = 240, - .host_flags = IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_OFF_BOARD, .pio_mask = ATA_PIO4, - .mwdma_mask = ATA_MWDMA2, },{ /* 5 */ .name = "HPT372N", + .init_setup = init_setup_hpt372n, .init_chipset = init_chipset_hpt366, .init_hwif = init_hwif_hpt366, .init_dma = init_dma_hpt366, + .autodma = AUTODMA, .enablebits = {{0x50,0x04,0x04}, {0x54,0x04,0x04}}, + .udma_mask = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5, + .bootable = OFF_BOARD, .extra = 240, - .host_flags = IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_OFF_BOARD, .pio_mask = ATA_PIO4, - .mwdma_mask = ATA_MWDMA2, } }; @@ -1505,77 +1626,16 @@ static ide_pci_device_t hpt366_chipsets[] __devinitdata = { * * Called when the PCI registration layer (or the IDE initialization) * finds a device matching our IDE device tables. + * + * NOTE: since we'll have to modify some fields of the ide_pci_device_t + * structure depending on the chip's revision, we'd better pass a local + * copy down the call chain... */ static int __devinit hpt366_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - struct hpt_info *info = NULL; - struct pci_dev *dev2 = NULL; - ide_pci_device_t d; - u8 idx = id->driver_data; - u8 rev = dev->revision; - - if ((idx == 0 || idx == 4) && (PCI_FUNC(dev->devfn) & 1)) - return -ENODEV; - - switch (idx) { - case 0: - if (rev < 3) - info = &hpt36x; - else { - static struct hpt_info *hpt37x_info[] = - { &hpt370, &hpt370a, &hpt372, &hpt372n }; - - info = hpt37x_info[min_t(u8, rev, 6) - 3]; - idx++; - } - break; - case 1: - info = (rev > 1) ? &hpt372n : &hpt372a; - break; - case 2: - info = (rev > 1) ? &hpt302n : &hpt302; - break; - case 3: - hpt371_init(dev); - info = (rev > 1) ? &hpt371n : &hpt371; - break; - case 4: - info = &hpt374; - break; - case 5: - info = &hpt372n; - break; - } - - d = hpt366_chipsets[idx]; - - d.name = info->chip_name; - d.udma_mask = info->udma_mask; - - pci_set_drvdata(dev, info); - - if (info == &hpt36x || info == &hpt374) - dev2 = pci_get_slot(dev->bus, dev->devfn + 1); - - if (dev2) { - int ret; - - pci_set_drvdata(dev2, info); - - if (info == &hpt374) - hpt374_init(dev, dev2); - else { - if (hpt36x_init(dev, dev2)) - d.host_flags |= IDE_HFLAG_BOOTABLE; - } - - ret = ide_setup_pci_devices(dev, dev2, &d); - if (ret < 0) - pci_dev_put(dev2); - return ret; - } + ide_pci_device_t d = hpt366_chipsets[id->driver_data]; - return ide_setup_pci_device(dev, &d); + return d.init_setup(dev, &d); } static const struct pci_device_id hpt366_pci_tbl[] = { diff --git a/trunk/drivers/ide/pci/it8213.c b/trunk/drivers/ide/pci/it8213.c index dfbe605120cb..24a71d03744a 100644 --- a/trunk/drivers/ide/pci/it8213.c +++ b/trunk/drivers/ide/pci/it8213.c @@ -170,9 +170,17 @@ static void __devinit init_hwif_it8213(ide_hwif_t *hwif) hwif->set_dma_mode = &it8213_set_dma_mode; hwif->set_pio_mode = &it8213_set_pio_mode; + hwif->drives[0].autotune = 1; + hwif->drives[1].autotune = 1; + if (!hwif->dma_base) return; + hwif->atapi_dma = 1; + hwif->ultra_mask = 0x7f; + hwif->mwdma_mask = 0x06; + hwif->swdma_mask = 0x04; + pci_read_config_byte(hwif->pci_dev, 0x42, ®42h); if (hwif->cbl != ATA_CBL_PATA40_SHORT) @@ -184,13 +192,11 @@ static void __devinit init_hwif_it8213(ide_hwif_t *hwif) { \ .name = name_str, \ .init_hwif = init_hwif_it8213, \ + .autodma = AUTODMA, \ .enablebits = {{0x41,0x80,0x80}}, \ - .host_flags = IDE_HFLAG_SINGLE | \ - IDE_HFLAG_BOOTABLE, \ + .bootable = ON_BOARD, \ + .host_flags = IDE_HFLAG_SINGLE, \ .pio_mask = ATA_PIO4, \ - .swdma_mask = ATA_SWDMA2_ONLY, \ - .mwdma_mask = ATA_MWDMA12_ONLY, \ - .udma_mask = ATA_UDMA6, \ } static ide_pci_device_t it8213_chipsets[] __devinitdata = { diff --git a/trunk/drivers/ide/pci/it821x.c b/trunk/drivers/ide/pci/it821x.c index ec45b7247209..f3391a8698ac 100644 --- a/trunk/drivers/ide/pci/it821x.c +++ b/trunk/drivers/ide/pci/it821x.c @@ -544,10 +544,12 @@ static void __devinit init_hwif_it821x(ide_hwif_t *hwif) ide_set_hwifdata(hwif, idev); + hwif->atapi_dma = 1; + pci_read_config_byte(hwif->pci_dev, 0x50, &conf); - if (conf & 1) { + if(conf & 1) { idev->smart = 1; - hwif->host_flags |= IDE_HFLAG_NO_ATAPI_DMA; + hwif->atapi_dma = 0; /* Long I/O's although allowed in LBA48 space cause the onboard firmware to enter the twighlight zone */ hwif->rqsize = 256; @@ -568,10 +570,10 @@ static void __devinit init_hwif_it821x(ide_hwif_t *hwif) */ pci_read_config_byte(hwif->pci_dev, 0x08, &conf); - if (conf == 0x10) { + if(conf == 0x10) { idev->timing10 = 1; - hwif->host_flags |= IDE_HFLAG_NO_ATAPI_DMA; - if (idev->smart == 0) + hwif->atapi_dma = 0; + if(!idev->smart) printk(KERN_WARNING "it821x: Revision 0x10, workarounds activated.\n"); } @@ -585,11 +587,14 @@ static void __devinit init_hwif_it821x(ide_hwif_t *hwif) } else hwif->host_flags |= IDE_HFLAG_NO_SET_MODE; + hwif->drives[0].autotune = 1; + hwif->drives[1].autotune = 1; + if (hwif->dma_base == 0) return; - hwif->ultra_mask = ATA_UDMA6; - hwif->mwdma_mask = ATA_MWDMA2; + hwif->ultra_mask = 0x7f; + hwif->mwdma_mask = 0x07; if (hwif->cbl != ATA_CBL_PATA40_SHORT) hwif->cbl = ata66_it821x(hwif); @@ -633,8 +638,9 @@ static unsigned int __devinit init_chipset_it821x(struct pci_dev *dev, const cha .name = name_str, \ .init_chipset = init_chipset_it821x, \ .init_hwif = init_hwif_it821x, \ + .autodma = AUTODMA, \ + .bootable = ON_BOARD, \ .fixup = it821x_fixups, \ - .host_flags = IDE_HFLAG_BOOTABLE, \ .pio_mask = ATA_PIO4, \ } diff --git a/trunk/drivers/ide/pci/jmicron.c b/trunk/drivers/ide/pci/jmicron.c index 2eeff670d9a6..bb893ffcc987 100644 --- a/trunk/drivers/ide/pci/jmicron.c +++ b/trunk/drivers/ide/pci/jmicron.c @@ -111,9 +111,16 @@ static void __devinit init_hwif_jmicron(ide_hwif_t *hwif) hwif->set_pio_mode = &jmicron_set_pio_mode; hwif->set_dma_mode = &jmicron_set_dma_mode; + hwif->drives[0].autotune = 1; + hwif->drives[1].autotune = 1; + if (hwif->dma_base == 0) return; + hwif->atapi_dma = 1; + hwif->ultra_mask = 0x7f; + hwif->mwdma_mask = 0x07; + if (hwif->cbl != ATA_CBL_PATA40_SHORT) hwif->cbl = ata66_jmicron(hwif); } @@ -121,11 +128,10 @@ static void __devinit init_hwif_jmicron(ide_hwif_t *hwif) static ide_pci_device_t jmicron_chipset __devinitdata = { .name = "JMB", .init_hwif = init_hwif_jmicron, - .host_flags = IDE_HFLAG_BOOTABLE, + .autodma = AUTODMA, + .bootable = ON_BOARD, .enablebits = { { 0x40, 0x01, 0x01 }, { 0x40, 0x10, 0x10 } }, .pio_mask = ATA_PIO5, - .mwdma_mask = ATA_MWDMA2, - .udma_mask = ATA_UDMA6, }; /** diff --git a/trunk/drivers/ide/pci/ns87415.c b/trunk/drivers/ide/pci/ns87415.c index d21b58923829..a8cd50ab62fb 100644 --- a/trunk/drivers/ide/pci/ns87415.c +++ b/trunk/drivers/ide/pci/ns87415.c @@ -266,9 +266,9 @@ static ide_pci_device_t ns87415_chipset __devinitdata = { .init_iops = init_iops_ns87415, #endif .init_hwif = init_hwif_ns87415, - .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA | - IDE_HFLAG_NO_ATAPI_DMA | - IDE_HFLAG_BOOTABLE, + .autodma = AUTODMA, + .bootable = ON_BOARD, + .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA, }; static int __devinit ns87415_init_one(struct pci_dev *dev, const struct pci_device_id *id) diff --git a/trunk/drivers/ide/pci/opti621.c b/trunk/drivers/ide/pci/opti621.c index 3573ffeaaa34..250662ea18ad 100644 --- a/trunk/drivers/ide/pci/opti621.c +++ b/trunk/drivers/ide/pci/opti621.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/opti621.c Version 0.8 Aug 27, 2007 + * linux/drivers/ide/pci/opti621.c Version 0.7 Sept 10, 2002 * * Copyright (C) 1996-1998 Linus Torvalds & authors (see below) */ @@ -57,6 +57,9 @@ * There is a 25/33MHz switch in configuration * register, but driver is written for use at any frequency which get * (use idebus=xx to select PCI bus speed). + * Use hda=autotune and hdb=autotune for automatical tune of the PIO modes. + * If you get strange results, do not use this and set PIO manually + * by hdparm. * * Version 0.1, Nov 8, 1996 * by Jaromir Koutek, for 2.1.8. @@ -329,27 +332,32 @@ static void __devinit init_hwif_opti621 (ide_hwif_t *hwif) hwif->drives[1].drive_data = PIO_DONT_KNOW; hwif->set_pio_mode = &opti621_set_pio_mode; + + if (!(hwif->dma_base)) + return; + + hwif->atapi_dma = 1; + hwif->mwdma_mask = 0x07; + hwif->swdma_mask = 0x07; } static ide_pci_device_t opti621_chipsets[] __devinitdata = { { /* 0 */ .name = "OPTI621", .init_hwif = init_hwif_opti621, + .autodma = AUTODMA, .enablebits = {{0x45,0x80,0x00}, {0x40,0x08,0x00}}, - .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA | - IDE_HFLAG_BOOTABLE, + .bootable = ON_BOARD, .pio_mask = ATA_PIO3, - .swdma_mask = ATA_SWDMA2, - .mwdma_mask = ATA_MWDMA2, + .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA, },{ /* 1 */ .name = "OPTI621X", .init_hwif = init_hwif_opti621, + .autodma = AUTODMA, .enablebits = {{0x45,0x80,0x00}, {0x40,0x08,0x00}}, - .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA | - IDE_HFLAG_BOOTABLE, + .bootable = ON_BOARD, .pio_mask = ATA_PIO3, - .swdma_mask = ATA_SWDMA2, - .mwdma_mask = ATA_MWDMA2, + .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA, } }; diff --git a/trunk/drivers/ide/pci/pdc202xx_new.c b/trunk/drivers/ide/pci/pdc202xx_new.c index d1e7823454f3..8704b6f33312 100644 --- a/trunk/drivers/ide/pci/pdc202xx_new.c +++ b/trunk/drivers/ide/pci/pdc202xx_new.c @@ -332,12 +332,16 @@ static long __devinit detect_pll_input_clock(unsigned long dma_base) static void __devinit apple_kiwi_init(struct pci_dev *pdev) { struct device_node *np = pci_device_to_OF_node(pdev); + unsigned int class_rev = 0; u8 conf; if (np == NULL || !of_device_is_compatible(np, "kiwi-root")) return; - if (pdev->revision >= 0x03) { + pci_read_config_dword(pdev, PCI_CLASS_REVISION, &class_rev); + class_rev &= 0xff; + + if (class_rev >= 0x03) { /* Setup chip magic config stuff (from darwin) */ pci_read_config_byte (pdev, 0x40, &conf); pci_write_config_byte(pdev, 0x40, (conf | 0x01)); @@ -471,76 +475,32 @@ static void __devinit init_hwif_pdc202new(ide_hwif_t *hwif) hwif->quirkproc = &pdcnew_quirkproc; hwif->resetproc = &pdcnew_reset; + hwif->err_stops_fifo = 1; + + hwif->drives[0].autotune = hwif->drives[1].autotune = 1; + if (hwif->dma_base == 0) return; + hwif->atapi_dma = 1; + + hwif->ultra_mask = hwif->cds->udma_mask; + hwif->mwdma_mask = 0x07; + if (hwif->cbl != ATA_CBL_PATA40_SHORT) hwif->cbl = pdcnew_cable_detect(hwif); } -static struct pci_dev * __devinit pdc20270_get_dev2(struct pci_dev *dev) +static int __devinit init_setup_pdcnew(struct pci_dev *dev, ide_pci_device_t *d) { - struct pci_dev *dev2; - - dev2 = pci_get_slot(dev->bus, PCI_DEVFN(PCI_SLOT(dev->devfn) + 2, - PCI_FUNC(dev->devfn))); - if (dev2 && - dev2->vendor == dev->vendor && - dev2->device == dev->device) { - - if (dev2->irq != dev->irq) { - dev2->irq = dev->irq; - printk(KERN_INFO "PDC20270: PCI config space " - "interrupt fixed\n"); - } - - return dev2; - } - - return NULL; + return ide_setup_pci_device(dev, d); } -#define DECLARE_PDCNEW_DEV(name_str, udma) \ - { \ - .name = name_str, \ - .init_chipset = init_chipset_pdcnew, \ - .init_hwif = init_hwif_pdc202new, \ - .host_flags = IDE_HFLAG_POST_SET_MODE | \ - IDE_HFLAG_ERROR_STOPS_FIFO | \ - IDE_HFLAG_OFF_BOARD, \ - .pio_mask = ATA_PIO4, \ - .mwdma_mask = ATA_MWDMA2, \ - .udma_mask = udma, \ - } - -static ide_pci_device_t pdcnew_chipsets[] __devinitdata = { - /* 0 */ DECLARE_PDCNEW_DEV("PDC20268", ATA_UDMA5), - /* 1 */ DECLARE_PDCNEW_DEV("PDC20269", ATA_UDMA6), - /* 2 */ DECLARE_PDCNEW_DEV("PDC20270", ATA_UDMA5), - /* 3 */ DECLARE_PDCNEW_DEV("PDC20271", ATA_UDMA6), - /* 4 */ DECLARE_PDCNEW_DEV("PDC20275", ATA_UDMA6), - /* 5 */ DECLARE_PDCNEW_DEV("PDC20276", ATA_UDMA6), - /* 6 */ DECLARE_PDCNEW_DEV("PDC20277", ATA_UDMA6), -}; - -/** - * pdc202new_init_one - called when a pdc202xx is found - * @dev: the pdc202new device - * @id: the matching pci id - * - * Called when the PCI registration layer (or the IDE initialization) - * finds a device matching our IDE device tables. - */ - -static int __devinit pdc202new_init_one(struct pci_dev *dev, const struct pci_device_id *id) +static int __devinit init_setup_pdc20270(struct pci_dev *dev, ide_pci_device_t *d) { - ide_pci_device_t *d; struct pci_dev *bridge = dev->bus->self; - u8 idx = id->driver_data; - - d = &pdcnew_chipsets[idx]; - if (idx == 2 && bridge && + if (bridge != NULL && bridge->vendor == PCI_VENDOR_ID_DEC && bridge->device == PCI_DEVICE_ID_DEC_21150) { struct pci_dev *dev2; @@ -548,28 +508,135 @@ static int __devinit pdc202new_init_one(struct pci_dev *dev, const struct pci_de if (PCI_SLOT(dev->devfn) & 2) return -ENODEV; - dev2 = pdc20270_get_dev2(dev); + dev2 = pci_get_slot(dev->bus, PCI_DEVFN(PCI_SLOT(dev->devfn) + 2, + PCI_FUNC(dev->devfn))); + if (dev2 != NULL && + dev2->vendor == dev->vendor && + dev2->device == dev->device) { + int ret; + + if (dev2->irq != dev->irq) { + dev2->irq = dev->irq; - if (dev2) { - int ret = ide_setup_pci_devices(dev, dev2, d); + printk(KERN_WARNING "%s: PCI config space " + "interrupt fixed.\n", d->name); + } + + ret = ide_setup_pci_devices(dev, dev2, d); if (ret < 0) pci_dev_put(dev2); return ret; } } + return ide_setup_pci_device(dev, d); +} - if (idx == 5 && bridge && +static int __devinit init_setup_pdc20276(struct pci_dev *dev, ide_pci_device_t *d) +{ + struct pci_dev *bridge = dev->bus->self; + + if (bridge != NULL && bridge->vendor == PCI_VENDOR_ID_INTEL && - (bridge->device == PCI_DEVICE_ID_INTEL_I960 || - bridge->device == PCI_DEVICE_ID_INTEL_I960RM)) { - printk(KERN_INFO "PDC20276: attached to I2O RAID controller, " - "skipping\n"); + (bridge->device == PCI_DEVICE_ID_INTEL_I960 || + bridge->device == PCI_DEVICE_ID_INTEL_I960RM)) { + + printk(KERN_INFO "%s: attached to I2O RAID controller, " + "skipping.\n", d->name); return -ENODEV; } - return ide_setup_pci_device(dev, d); } +static ide_pci_device_t pdcnew_chipsets[] __devinitdata = { + { /* 0 */ + .name = "PDC20268", + .init_setup = init_setup_pdcnew, + .init_chipset = init_chipset_pdcnew, + .init_hwif = init_hwif_pdc202new, + .autodma = AUTODMA, + .bootable = OFF_BOARD, + .pio_mask = ATA_PIO4, + .udma_mask = 0x3f, /* udma0-5 */ + .host_flags = IDE_HFLAG_POST_SET_MODE, + },{ /* 1 */ + .name = "PDC20269", + .init_setup = init_setup_pdcnew, + .init_chipset = init_chipset_pdcnew, + .init_hwif = init_hwif_pdc202new, + .autodma = AUTODMA, + .bootable = OFF_BOARD, + .pio_mask = ATA_PIO4, + .udma_mask = 0x7f, /* udma0-6*/ + .host_flags = IDE_HFLAG_POST_SET_MODE, + },{ /* 2 */ + .name = "PDC20270", + .init_setup = init_setup_pdc20270, + .init_chipset = init_chipset_pdcnew, + .init_hwif = init_hwif_pdc202new, + .autodma = AUTODMA, + .bootable = OFF_BOARD, + .pio_mask = ATA_PIO4, + .udma_mask = 0x3f, /* udma0-5 */ + .host_flags = IDE_HFLAG_POST_SET_MODE, + },{ /* 3 */ + .name = "PDC20271", + .init_setup = init_setup_pdcnew, + .init_chipset = init_chipset_pdcnew, + .init_hwif = init_hwif_pdc202new, + .autodma = AUTODMA, + .bootable = OFF_BOARD, + .pio_mask = ATA_PIO4, + .udma_mask = 0x7f, /* udma0-6*/ + .host_flags = IDE_HFLAG_POST_SET_MODE, + },{ /* 4 */ + .name = "PDC20275", + .init_setup = init_setup_pdcnew, + .init_chipset = init_chipset_pdcnew, + .init_hwif = init_hwif_pdc202new, + .autodma = AUTODMA, + .bootable = OFF_BOARD, + .pio_mask = ATA_PIO4, + .udma_mask = 0x7f, /* udma0-6*/ + .host_flags = IDE_HFLAG_POST_SET_MODE, + },{ /* 5 */ + .name = "PDC20276", + .init_setup = init_setup_pdc20276, + .init_chipset = init_chipset_pdcnew, + .init_hwif = init_hwif_pdc202new, + .autodma = AUTODMA, + .bootable = OFF_BOARD, + .pio_mask = ATA_PIO4, + .udma_mask = 0x7f, /* udma0-6*/ + .host_flags = IDE_HFLAG_POST_SET_MODE, + },{ /* 6 */ + .name = "PDC20277", + .init_setup = init_setup_pdcnew, + .init_chipset = init_chipset_pdcnew, + .init_hwif = init_hwif_pdc202new, + .autodma = AUTODMA, + .bootable = OFF_BOARD, + .pio_mask = ATA_PIO4, + .udma_mask = 0x7f, /* udma0-6*/ + .host_flags = IDE_HFLAG_POST_SET_MODE, + } +}; + +/** + * pdc202new_init_one - called when a pdc202xx is found + * @dev: the pdc202new device + * @id: the matching pci id + * + * Called when the PCI registration layer (or the IDE initialization) + * finds a device matching our IDE device tables. + */ + +static int __devinit pdc202new_init_one(struct pci_dev *dev, const struct pci_device_id *id) +{ + ide_pci_device_t *d = &pdcnew_chipsets[id->driver_data]; + + return d->init_setup(dev, d); +} + static const struct pci_device_id pdc202new_pci_tbl[] = { { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20268), 0 }, { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20269), 1 }, diff --git a/trunk/drivers/ide/pci/pdc202xx_old.c b/trunk/drivers/ide/pci/pdc202xx_old.c index 29306121dc4a..e1d2337a9f1d 100644 --- a/trunk/drivers/ide/pci/pdc202xx_old.c +++ b/trunk/drivers/ide/pci/pdc202xx_old.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/pdc202xx_old.c Version 0.52 Aug 27, 2007 + * linux/drivers/ide/pci/pdc202xx_old.c Version 0.51 Jul 27, 2007 * * Copyright (C) 1998-2002 Andre Hedrick * Copyright (C) 2006-2007 MontaVista Software, Inc. @@ -97,6 +97,9 @@ static void pdc202xx_set_mode(ide_drive_t *drive, const u8 speed) case XFER_MW_DMA_2: TB = 0x60; TC = 0x03; break; case XFER_MW_DMA_1: TB = 0x60; TC = 0x04; break; case XFER_MW_DMA_0: TB = 0xE0; TC = 0x0F; break; + case XFER_SW_DMA_2: TB = 0x60; TC = 0x05; break; + case XFER_SW_DMA_1: TB = 0x80; TC = 0x06; break; + case XFER_SW_DMA_0: TB = 0xC0; TC = 0x0B; break; case XFER_PIO_4: TA = 0x01; TB = 0x04; break; case XFER_PIO_3: TA = 0x02; TB = 0x06; break; case XFER_PIO_2: TA = 0x03; TB = 0x08; break; @@ -317,9 +320,18 @@ static void __devinit init_hwif_pdc202xx(ide_hwif_t *hwif) if (hwif->pci_dev->device != PCI_DEVICE_ID_PROMISE_20246) hwif->resetproc = &pdc202xx_reset; + hwif->err_stops_fifo = 1; + + hwif->drives[0].autotune = hwif->drives[1].autotune = 1; + if (hwif->dma_base == 0) return; + hwif->ultra_mask = hwif->cds->udma_mask; + hwif->mwdma_mask = 0x07; + hwif->swdma_mask = 0x07; + hwif->atapi_dma = 1; + hwif->dma_lost_irq = &pdc202xx_dma_lost_irq; hwif->dma_timeout = &pdc202xx_dma_timeout; @@ -365,8 +377,8 @@ static void __devinit init_dma_pdc202xx(ide_hwif_t *hwif, unsigned long dmabase) ide_setup_dma(hwif, dmabase, 8); } -static void __devinit pdc202ata4_fixup_irq(struct pci_dev *dev, - const char *name) +static int __devinit init_setup_pdc202ata4(struct pci_dev *dev, + ide_pci_device_t *d) { if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE) { u8 irq = 0, irq2 = 0; @@ -376,44 +388,90 @@ static void __devinit pdc202ata4_fixup_irq(struct pci_dev *dev, if (irq != irq2) { pci_write_config_byte(dev, (PCI_INTERRUPT_LINE)|0x80, irq); /* 0xbc */ - printk(KERN_INFO "%s: PCI config space interrupt " - "mirror fixed\n", name); + printk(KERN_INFO "%s: pci-config space interrupt " + "mirror fixed.\n", d->name); } } + return ide_setup_pci_device(dev, d); } -#define DECLARE_PDC2026X_DEV(name_str, udma) \ - { \ - .name = name_str, \ - .init_chipset = init_chipset_pdc202xx, \ - .init_hwif = init_hwif_pdc202xx, \ - .init_dma = init_dma_pdc202xx, \ - .extra = 48, \ - .host_flags = IDE_HFLAG_ERROR_STOPS_FIFO | \ - IDE_HFLAG_OFF_BOARD, \ - .pio_mask = ATA_PIO4, \ - .mwdma_mask = ATA_MWDMA2, \ - .udma_mask = udma, \ +static int __devinit init_setup_pdc20265(struct pci_dev *dev, + ide_pci_device_t *d) +{ + if ((dev->bus->self) && + (dev->bus->self->vendor == PCI_VENDOR_ID_INTEL) && + ((dev->bus->self->device == PCI_DEVICE_ID_INTEL_I960) || + (dev->bus->self->device == PCI_DEVICE_ID_INTEL_I960RM))) { + printk(KERN_INFO "ide: Skipping Promise PDC20265 " + "attached to I2O RAID controller.\n"); + return -ENODEV; } + return ide_setup_pci_device(dev, d); +} + +static int __devinit init_setup_pdc202xx(struct pci_dev *dev, + ide_pci_device_t *d) +{ + return ide_setup_pci_device(dev, d); +} static ide_pci_device_t pdc202xx_chipsets[] __devinitdata = { { /* 0 */ .name = "PDC20246", + .init_setup = init_setup_pdc202ata4, .init_chipset = init_chipset_pdc202xx, .init_hwif = init_hwif_pdc202xx, .init_dma = init_dma_pdc202xx, + .autodma = AUTODMA, + .bootable = OFF_BOARD, .extra = 16, - .host_flags = IDE_HFLAG_ERROR_STOPS_FIFO | - IDE_HFLAG_OFF_BOARD, .pio_mask = ATA_PIO4, - .mwdma_mask = ATA_MWDMA2, - .udma_mask = ATA_UDMA2, - }, - - /* 1 */ DECLARE_PDC2026X_DEV("PDC20262", ATA_UDMA4), - /* 2 */ DECLARE_PDC2026X_DEV("PDC20263", ATA_UDMA4), - /* 3 */ DECLARE_PDC2026X_DEV("PDC20265", ATA_UDMA5), - /* 4 */ DECLARE_PDC2026X_DEV("PDC20267", ATA_UDMA5), + .udma_mask = 0x07, /* udma0-2 */ + },{ /* 1 */ + .name = "PDC20262", + .init_setup = init_setup_pdc202ata4, + .init_chipset = init_chipset_pdc202xx, + .init_hwif = init_hwif_pdc202xx, + .init_dma = init_dma_pdc202xx, + .autodma = AUTODMA, + .bootable = OFF_BOARD, + .extra = 48, + .pio_mask = ATA_PIO4, + .udma_mask = 0x1f, /* udma0-4 */ + },{ /* 2 */ + .name = "PDC20263", + .init_setup = init_setup_pdc202ata4, + .init_chipset = init_chipset_pdc202xx, + .init_hwif = init_hwif_pdc202xx, + .init_dma = init_dma_pdc202xx, + .autodma = AUTODMA, + .bootable = OFF_BOARD, + .extra = 48, + .pio_mask = ATA_PIO4, + .udma_mask = 0x1f, /* udma0-4 */ + },{ /* 3 */ + .name = "PDC20265", + .init_setup = init_setup_pdc20265, + .init_chipset = init_chipset_pdc202xx, + .init_hwif = init_hwif_pdc202xx, + .init_dma = init_dma_pdc202xx, + .autodma = AUTODMA, + .bootable = OFF_BOARD, + .extra = 48, + .pio_mask = ATA_PIO4, + .udma_mask = 0x3f, /* udma0-5 */ + },{ /* 4 */ + .name = "PDC20267", + .init_setup = init_setup_pdc202xx, + .init_chipset = init_chipset_pdc202xx, + .init_hwif = init_hwif_pdc202xx, + .init_dma = init_dma_pdc202xx, + .autodma = AUTODMA, + .bootable = OFF_BOARD, + .extra = 48, + .pio_mask = ATA_PIO4, + .udma_mask = 0x3f, /* udma0-5 */ + } }; /** @@ -427,28 +485,9 @@ static ide_pci_device_t pdc202xx_chipsets[] __devinitdata = { static int __devinit pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - ide_pci_device_t *d; - u8 idx = id->driver_data; - - d = &pdc202xx_chipsets[idx]; - - if (idx < 3) - pdc202ata4_fixup_irq(dev, d->name); - - if (idx == 3) { - struct pci_dev *bridge = dev->bus->self; + ide_pci_device_t *d = &pdc202xx_chipsets[id->driver_data]; - if (bridge && - bridge->vendor == PCI_VENDOR_ID_INTEL && - (bridge->device == PCI_DEVICE_ID_INTEL_I960 || - bridge->device == PCI_DEVICE_ID_INTEL_I960RM)) { - printk(KERN_INFO "ide: Skipping Promise PDC20265 " - "attached to I2O RAID controller\n"); - return -ENODEV; - } - } - - return ide_setup_pci_device(dev, d); + return d->init_setup(dev, d); } static const struct pci_device_id pdc202xx_pci_tbl[] = { diff --git a/trunk/drivers/ide/pci/piix.c b/trunk/drivers/ide/pci/piix.c index ec0c6e96a213..a8dd0c0add35 100644 --- a/trunk/drivers/ide/pci/piix.c +++ b/trunk/drivers/ide/pci/piix.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/piix.c Version 0.54 Sep 5, 2007 + * linux/drivers/ide/pci/piix.c Version 0.53 Aug 9, 2007 * * Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer * Copyright (C) 1998-2000 Andre Hedrick @@ -254,20 +254,53 @@ static void piix_set_dma_mode(ide_drive_t *drive, const u8 speed) } /** - * init_chipset_ich - set up the ICH chipset + * piix_is_ichx - check if ICHx + * @dev: PCI device to check + * + * returns 1 if ICHx, 0 otherwise. + */ +static int piix_is_ichx(struct pci_dev *dev) +{ + switch (dev->device) { + case PCI_DEVICE_ID_INTEL_82801EB_1: + case PCI_DEVICE_ID_INTEL_82801AA_1: + case PCI_DEVICE_ID_INTEL_82801AB_1: + case PCI_DEVICE_ID_INTEL_82801BA_8: + case PCI_DEVICE_ID_INTEL_82801BA_9: + case PCI_DEVICE_ID_INTEL_82801CA_10: + case PCI_DEVICE_ID_INTEL_82801CA_11: + case PCI_DEVICE_ID_INTEL_82801DB_1: + case PCI_DEVICE_ID_INTEL_82801DB_10: + case PCI_DEVICE_ID_INTEL_82801DB_11: + case PCI_DEVICE_ID_INTEL_82801EB_11: + case PCI_DEVICE_ID_INTEL_82801E_11: + case PCI_DEVICE_ID_INTEL_ESB_2: + case PCI_DEVICE_ID_INTEL_ICH6_19: + case PCI_DEVICE_ID_INTEL_ICH7_21: + case PCI_DEVICE_ID_INTEL_ESB2_18: + case PCI_DEVICE_ID_INTEL_ICH8_6: + return 1; + } + + return 0; +} + +/** + * init_chipset_piix - set up the PIIX chipset * @dev: PCI device to set up * @name: Name of the device * - * Initialize the PCI device as required. For the ICH this turns - * out to be nice and simple. + * Initialize the PCI device as required. For the PIIX this turns + * out to be nice and simple */ -static unsigned int __devinit init_chipset_ich(struct pci_dev *dev, const char *name) +static unsigned int __devinit init_chipset_piix (struct pci_dev *dev, const char *name) { - u32 extra = 0; - - pci_read_config_dword(dev, 0x54, &extra); - pci_write_config_dword(dev, 0x54, extra | 0x400); + if (piix_is_ichx(dev)) { + unsigned int extra = 0; + pci_read_config_dword(dev, 0x54, &extra); + pci_write_config_dword(dev, 0x54, extra|0x400); + } return 0; } @@ -285,9 +318,9 @@ static void piix_dma_clear_irq(ide_drive_t *drive) u8 dma_stat; /* clear the INTR & ERROR bits */ - dma_stat = inb(hwif->dma_status); + dma_stat = hwif->INB(hwif->dma_status); /* Should we force the bit as well ? */ - outb(dma_stat, hwif->dma_status); + hwif->OUTB(dma_stat, hwif->dma_status); } struct ich_laptop { @@ -341,12 +374,35 @@ static u8 __devinit piix_cable_detect(ide_hwif_t *hwif) static void __devinit init_hwif_piix(ide_hwif_t *hwif) { +#ifndef CONFIG_IA64 + if (!hwif->irq) + hwif->irq = hwif->channel ? 15 : 14; +#endif /* CONFIG_IA64 */ + + if (hwif->pci_dev->device == PCI_DEVICE_ID_INTEL_82371MX) { + /* This is a painful system best to let it self tune for now */ + return; + } + hwif->set_pio_mode = &piix_set_pio_mode; hwif->set_dma_mode = &piix_set_dma_mode; + hwif->drives[0].autotune = 1; + hwif->drives[1].autotune = 1; + if (!hwif->dma_base) return; + /* ICHx need to clear the bmdma status for all interrupts */ + if (piix_is_ichx(hwif->pci_dev)) + hwif->ide_dma_clear_irq = &piix_dma_clear_irq; + + hwif->atapi_dma = 1; + + hwif->ultra_mask = hwif->cds->udma_mask; + hwif->mwdma_mask = 0x06; + hwif->swdma_mask = 0x04; + if (hwif->ultra_mask & 0x78) { if (hwif->cbl != ATA_CBL_PATA40_SHORT) hwif->cbl = piix_cable_detect(hwif); @@ -356,49 +412,21 @@ static void __devinit init_hwif_piix(ide_hwif_t *hwif) hwif->ultra_mask = hwif->mwdma_mask = hwif->swdma_mask = 0; } -static void __devinit init_hwif_ich(ide_hwif_t *hwif) -{ - init_hwif_piix(hwif); - - /* ICHx need to clear the BMDMA status for all interrupts */ - if (hwif->dma_base) - hwif->ide_dma_clear_irq = &piix_dma_clear_irq; -} - -#ifndef CONFIG_IA64 - #define IDE_HFLAGS_PIIX (IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_BOOTABLE) -#else - #define IDE_HFLAGS_PIIX IDE_HFLAG_BOOTABLE -#endif - #define DECLARE_PIIX_DEV(name_str, udma) \ { \ .name = name_str, \ + .init_chipset = init_chipset_piix, \ .init_hwif = init_hwif_piix, \ + .autodma = AUTODMA, \ .enablebits = {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, \ - .host_flags = IDE_HFLAGS_PIIX, \ + .bootable = ON_BOARD, \ .pio_mask = ATA_PIO4, \ - .swdma_mask = ATA_SWDMA2_ONLY, \ - .mwdma_mask = ATA_MWDMA12_ONLY, \ .udma_mask = udma, \ } -#define DECLARE_ICH_DEV(name_str, udma) \ - { \ - .name = name_str, \ - .init_chipset = init_chipset_ich, \ - .init_hwif = init_hwif_ich, \ - .enablebits = {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, \ - .host_flags = IDE_HFLAGS_PIIX, \ - .pio_mask = ATA_PIO4, \ - .swdma_mask = ATA_SWDMA2_ONLY, \ - .mwdma_mask = ATA_MWDMA12_ONLY, \ - .udma_mask = udma, \ - } - static ide_pci_device_t piix_pci_info[] __devinitdata = { - /* 0 */ DECLARE_PIIX_DEV("PIIXa", 0x00), /* no udma */ - /* 1 */ DECLARE_PIIX_DEV("PIIXb", 0x00), /* no udma */ + /* 0 */ DECLARE_PIIX_DEV("PIIXa", 0x00), /* no udma */ + /* 1 */ DECLARE_PIIX_DEV("PIIXb", 0x00), /* no udma */ /* 2 */ { /* @@ -407,35 +435,36 @@ static ide_pci_device_t piix_pci_info[] __devinitdata = { * of the bit 14 of the IDETIM register at offset 0x6c */ .name = "MPIIX", + .init_hwif = init_hwif_piix, + .autodma = NODMA, .enablebits = {{0x6d,0xc0,0x80}, {0x6d,0xc0,0xc0}}, - .host_flags = IDE_HFLAG_ISA_PORTS | IDE_HFLAG_NO_DMA | - IDE_HFLAGS_PIIX, + .bootable = ON_BOARD, + .host_flags = IDE_HFLAG_ISA_PORTS, .pio_mask = ATA_PIO4, - /* This is a painful system best to let it self tune for now */ }, - /* 3 */ DECLARE_PIIX_DEV("PIIX3", 0x00), /* no udma */ - /* 4 */ DECLARE_PIIX_DEV("PIIX4", ATA_UDMA2), - /* 5 */ DECLARE_ICH_DEV("ICH0", ATA_UDMA2), - /* 6 */ DECLARE_PIIX_DEV("PIIX4", ATA_UDMA2), - /* 7 */ DECLARE_ICH_DEV("ICH", ATA_UDMA4), - /* 8 */ DECLARE_PIIX_DEV("PIIX4", ATA_UDMA4), - /* 9 */ DECLARE_PIIX_DEV("PIIX4", ATA_UDMA2), - /* 10 */ DECLARE_ICH_DEV("ICH2", ATA_UDMA5), - /* 11 */ DECLARE_ICH_DEV("ICH2M", ATA_UDMA5), - /* 12 */ DECLARE_ICH_DEV("ICH3M", ATA_UDMA5), - /* 13 */ DECLARE_ICH_DEV("ICH3", ATA_UDMA5), - /* 14 */ DECLARE_ICH_DEV("ICH4", ATA_UDMA5), - /* 15 */ DECLARE_ICH_DEV("ICH5", ATA_UDMA5), - /* 16 */ DECLARE_ICH_DEV("C-ICH", ATA_UDMA5), - /* 17 */ DECLARE_ICH_DEV("ICH4", ATA_UDMA5), - /* 18 */ DECLARE_ICH_DEV("ICH5-SATA", ATA_UDMA5), - /* 19 */ DECLARE_ICH_DEV("ICH5", ATA_UDMA5), - /* 20 */ DECLARE_ICH_DEV("ICH6", ATA_UDMA5), - /* 21 */ DECLARE_ICH_DEV("ICH7", ATA_UDMA5), - /* 22 */ DECLARE_ICH_DEV("ICH4", ATA_UDMA5), - /* 23 */ DECLARE_ICH_DEV("ESB2", ATA_UDMA5), - /* 24 */ DECLARE_ICH_DEV("ICH8M", ATA_UDMA5), + /* 3 */ DECLARE_PIIX_DEV("PIIX3", 0x00), /* no udma */ + /* 4 */ DECLARE_PIIX_DEV("PIIX4", 0x07), /* udma0-2 */ + /* 5 */ DECLARE_PIIX_DEV("ICH0", 0x07), /* udma0-2 */ + /* 6 */ DECLARE_PIIX_DEV("PIIX4", 0x07), /* udma0-2 */ + /* 7 */ DECLARE_PIIX_DEV("ICH", 0x1f), /* udma0-4 */ + /* 8 */ DECLARE_PIIX_DEV("PIIX4", 0x1f), /* udma0-4 */ + /* 9 */ DECLARE_PIIX_DEV("PIIX4", 0x07), /* udma0-2 */ + /* 10 */ DECLARE_PIIX_DEV("ICH2", 0x3f), /* udma0-5 */ + /* 11 */ DECLARE_PIIX_DEV("ICH2M", 0x3f), /* udma0-5 */ + /* 12 */ DECLARE_PIIX_DEV("ICH3M", 0x3f), /* udma0-5 */ + /* 13 */ DECLARE_PIIX_DEV("ICH3", 0x3f), /* udma0-5 */ + /* 14 */ DECLARE_PIIX_DEV("ICH4", 0x3f), /* udma0-5 */ + /* 15 */ DECLARE_PIIX_DEV("ICH5", 0x3f), /* udma0-5 */ + /* 16 */ DECLARE_PIIX_DEV("C-ICH", 0x3f), /* udma0-5 */ + /* 17 */ DECLARE_PIIX_DEV("ICH4", 0x3f), /* udma0-5 */ + /* 18 */ DECLARE_PIIX_DEV("ICH5-SATA", 0x3f), /* udma0-5 */ + /* 19 */ DECLARE_PIIX_DEV("ICH5", 0x3f), /* udma0-5 */ + /* 20 */ DECLARE_PIIX_DEV("ICH6", 0x3f), /* udma0-5 */ + /* 21 */ DECLARE_PIIX_DEV("ICH7", 0x3f), /* udma0-5 */ + /* 22 */ DECLARE_PIIX_DEV("ICH4", 0x3f), /* udma0-5 */ + /* 23 */ DECLARE_PIIX_DEV("ESB2", 0x3f), /* udma0-5 */ + /* 24 */ DECLARE_PIIX_DEV("ICH8M", 0x3f), /* udma0-5 */ }; /** diff --git a/trunk/drivers/ide/pci/rz1000.c b/trunk/drivers/ide/pci/rz1000.c index dd2583ef1ad7..3f506e8d44e3 100644 --- a/trunk/drivers/ide/pci/rz1000.c +++ b/trunk/drivers/ide/pci/rz1000.c @@ -52,7 +52,8 @@ static void __devinit init_hwif_rz1000 (ide_hwif_t *hwif) static ide_pci_device_t rz1000_chipset __devinitdata = { .name = "RZ100x", .init_hwif = init_hwif_rz1000, - .host_flags = IDE_HFLAG_NO_DMA | IDE_HFLAG_BOOTABLE, + .autodma = NODMA, + .bootable = ON_BOARD, }; static int __devinit rz1000_init_one(struct pci_dev *dev, const struct pci_device_id *id) diff --git a/trunk/drivers/ide/pci/sc1200.c b/trunk/drivers/ide/pci/sc1200.c index b2423e03bf36..54c5c98a2e26 100644 --- a/trunk/drivers/ide/pci/sc1200.c +++ b/trunk/drivers/ide/pci/sc1200.c @@ -362,26 +362,33 @@ static int sc1200_resume (struct pci_dev *dev) */ static void __devinit init_hwif_sc1200 (ide_hwif_t *hwif) { + if (hwif->mate) + hwif->serialized = hwif->mate->serialized = 1; + hwif->set_pio_mode = &sc1200_set_pio_mode; hwif->set_dma_mode = &sc1200_set_dma_mode; + hwif->drives[0].autotune = 1; + hwif->drives[1].autotune = 1; + if (hwif->dma_base == 0) return; hwif->udma_filter = sc1200_udma_filter; hwif->ide_dma_end = &sc1200_ide_dma_end; + + hwif->atapi_dma = 1; + hwif->ultra_mask = 0x07; + hwif->mwdma_mask = 0x07; } static ide_pci_device_t sc1200_chipset __devinitdata = { .name = "SC1200", .init_hwif = init_hwif_sc1200, - .host_flags = IDE_HFLAG_SERIALIZE | - IDE_HFLAG_POST_SET_MODE | - IDE_HFLAG_ABUSE_DMA_MODES | - IDE_HFLAG_BOOTABLE, + .autodma = AUTODMA, + .bootable = ON_BOARD, + .host_flags = IDE_HFLAG_ABUSE_DMA_MODES | IDE_HFLAG_POST_SET_MODE, .pio_mask = ATA_PIO4, - .mwdma_mask = ATA_MWDMA2, - .udma_mask = ATA_UDMA2, }; static int __devinit sc1200_init_one(struct pci_dev *dev, const struct pci_device_id *id) diff --git a/trunk/drivers/ide/pci/scc_pata.c b/trunk/drivers/ide/pci/scc_pata.c index ae9b50331d2a..bd4c1d3070e4 100644 --- a/trunk/drivers/ide/pci/scc_pata.c +++ b/trunk/drivers/ide/pci/scc_pata.c @@ -472,7 +472,7 @@ static u8 scc_udma_filter(ide_drive_t *drive) if ((drive->media != ide_disk) && (mask & 0xE0)) { printk(KERN_INFO "%s: limit %s to UDMA4\n", SCC_PATA_NAME, drive->name); - mask = ATA_UDMA4; + mask = 0x1F; } return mask; @@ -683,10 +683,17 @@ static void __devinit init_hwif_scc(ide_hwif_t *hwif) hwif->ide_dma_test_irq = scc_dma_test_irq; hwif->udma_filter = scc_udma_filter; - if (in_be32((void __iomem *)(hwif->config_data + 0xff0)) & CCKCTRL_ATACLKOEN) - hwif->ultra_mask = ATA_UDMA6; /* 133MHz */ - else - hwif->ultra_mask = ATA_UDMA5; /* 100MHz */ + hwif->drives[0].autotune = IDE_TUNE_AUTO; + hwif->drives[1].autotune = IDE_TUNE_AUTO; + + if (in_be32((void __iomem *)(hwif->config_data + 0xff0)) & CCKCTRL_ATACLKOEN) { + hwif->ultra_mask = 0x7f; /* 133MHz */ + } else { + hwif->ultra_mask = 0x3f; /* 100MHz */ + } + hwif->mwdma_mask = 0x00; + hwif->swdma_mask = 0x00; + hwif->atapi_dma = 1; /* we support 80c cable only. */ hwif->cbl = ATA_CBL_PATA80; @@ -695,10 +702,12 @@ static void __devinit init_hwif_scc(ide_hwif_t *hwif) #define DECLARE_SCC_DEV(name_str) \ { \ .name = name_str, \ + .init_setup = init_setup_scc, \ .init_iops = init_iops_scc, \ .init_hwif = init_hwif_scc, \ - .host_flags = IDE_HFLAG_SINGLE | \ - IDE_HFLAG_BOOTABLE, \ + .autodma = AUTODMA, \ + .bootable = ON_BOARD, \ + .host_flags = IDE_HFLAG_SINGLE, \ .pio_mask = ATA_PIO4, \ } @@ -718,8 +727,7 @@ static ide_pci_device_t scc_chipsets[] __devinitdata = { static int __devinit scc_init_one(struct pci_dev *dev, const struct pci_device_id *id) { ide_pci_device_t *d = &scc_chipsets[id->driver_data]; - - return init_setup_scc(dev, d); + return d->init_setup(dev, d); } /** diff --git a/trunk/drivers/ide/pci/serverworks.c b/trunk/drivers/ide/pci/serverworks.c index a3d880e21d0b..d3ffc52e22af 100644 --- a/trunk/drivers/ide/pci/serverworks.c +++ b/trunk/drivers/ide/pci/serverworks.c @@ -360,10 +360,23 @@ static u8 __devinit ata66_svwks(ide_hwif_t *hwif) static void __devinit init_hwif_svwks (ide_hwif_t *hwif) { + if (!hwif->irq) + hwif->irq = hwif->channel ? 15 : 14; + hwif->set_pio_mode = &svwks_set_pio_mode; hwif->set_dma_mode = &svwks_set_dma_mode; hwif->udma_filter = &svwks_udma_filter; + hwif->atapi_dma = 1; + + if (hwif->pci_dev->device != PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) + hwif->ultra_mask = 0x3f; + + hwif->mwdma_mask = 0x07; + + hwif->drives[0].autotune = 1; + hwif->drives[1].autotune = 1; + if (!hwif->dma_base) return; @@ -373,49 +386,72 @@ static void __devinit init_hwif_svwks (ide_hwif_t *hwif) } } +static int __devinit init_setup_svwks (struct pci_dev *dev, ide_pci_device_t *d) +{ + return ide_setup_pci_device(dev, d); +} + +static int __devinit init_setup_csb6 (struct pci_dev *dev, ide_pci_device_t *d) +{ + if (!(PCI_FUNC(dev->devfn) & 1)) { + d->bootable = NEVER_BOARD; + if (dev->resource[0].start == 0x01f1) + d->bootable = ON_BOARD; + } + + if ((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE || + dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2) && + (!(PCI_FUNC(dev->devfn) & 1))) + d->host_flags |= IDE_HFLAG_SINGLE; + else + d->host_flags &= ~IDE_HFLAG_SINGLE; + + return ide_setup_pci_device(dev, d); +} + static ide_pci_device_t serverworks_chipsets[] __devinitdata = { { /* 0 */ .name = "SvrWks OSB4", + .init_setup = init_setup_svwks, .init_chipset = init_chipset_svwks, .init_hwif = init_hwif_svwks, - .host_flags = IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_BOOTABLE, + .autodma = AUTODMA, + .bootable = ON_BOARD, .pio_mask = ATA_PIO4, - .mwdma_mask = ATA_MWDMA2, - .udma_mask = 0x00, /* UDMA is problematic on OSB4 */ },{ /* 1 */ .name = "SvrWks CSB5", + .init_setup = init_setup_svwks, .init_chipset = init_chipset_svwks, .init_hwif = init_hwif_svwks, - .host_flags = IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_BOOTABLE, + .autodma = AUTODMA, + .bootable = ON_BOARD, .pio_mask = ATA_PIO4, - .mwdma_mask = ATA_MWDMA2, - .udma_mask = ATA_UDMA5, },{ /* 2 */ .name = "SvrWks CSB6", + .init_setup = init_setup_csb6, .init_chipset = init_chipset_svwks, .init_hwif = init_hwif_svwks, - .host_flags = IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_BOOTABLE, + .autodma = AUTODMA, + .bootable = ON_BOARD, .pio_mask = ATA_PIO4, - .mwdma_mask = ATA_MWDMA2, - .udma_mask = ATA_UDMA5, },{ /* 3 */ .name = "SvrWks CSB6", + .init_setup = init_setup_csb6, .init_chipset = init_chipset_svwks, .init_hwif = init_hwif_svwks, - .host_flags = IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_SINGLE | - IDE_HFLAG_BOOTABLE, + .autodma = AUTODMA, + .bootable = ON_BOARD, + .host_flags = IDE_HFLAG_SINGLE, .pio_mask = ATA_PIO4, - .mwdma_mask = ATA_MWDMA2, - .udma_mask = ATA_UDMA5, },{ /* 4 */ .name = "SvrWks HT1000", + .init_setup = init_setup_svwks, .init_chipset = init_chipset_svwks, .init_hwif = init_hwif_svwks, - .host_flags = IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_SINGLE | - IDE_HFLAG_BOOTABLE, + .autodma = AUTODMA, + .bootable = ON_BOARD, + .host_flags = IDE_HFLAG_SINGLE, .pio_mask = ATA_PIO4, - .mwdma_mask = ATA_MWDMA2, - .udma_mask = ATA_UDMA5, } }; @@ -430,21 +466,9 @@ static ide_pci_device_t serverworks_chipsets[] __devinitdata = { static int __devinit svwks_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - ide_pci_device_t d; - u8 idx = id->driver_data; - - d = serverworks_chipsets[idx]; - - if (idx == 2 || idx == 3) { - if ((PCI_FUNC(dev->devfn) & 1) == 0) { - if (pci_resource_start(dev, 0) != 0x01f1) - d.host_flags &= ~IDE_HFLAG_BOOTABLE; - d.host_flags |= IDE_HFLAG_SINGLE; - } else - d.host_flags &= ~IDE_HFLAG_SINGLE; - } + ide_pci_device_t *d = &serverworks_chipsets[id->driver_data]; - return ide_setup_pci_device(dev, &d); + return d->init_setup(dev, d); } static const struct pci_device_id svwks_pci_tbl[] = { diff --git a/trunk/drivers/ide/pci/sgiioc4.c b/trunk/drivers/ide/pci/sgiioc4.c index 5af74ea1d46e..9a9474f534e5 100644 --- a/trunk/drivers/ide/pci/sgiioc4.c +++ b/trunk/drivers/ide/pci/sgiioc4.c @@ -592,7 +592,8 @@ ide_init_sgiioc4(ide_hwif_t * hwif) if (hwif->dma_base == 0) return; - hwif->mwdma_mask = ATA_MWDMA2_ONLY; + hwif->atapi_dma = 1; + hwif->mwdma_mask = 0x04; hwif->dma_setup = &sgiioc4_ide_dma_setup; hwif->dma_start = &sgiioc4_ide_dma_start; @@ -691,12 +692,14 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev) static unsigned int __devinit pci_init_sgiioc4(struct pci_dev *dev) { + unsigned int class_rev; int ret; + pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); + class_rev &= 0xff; printk(KERN_INFO "%s: IDE controller at PCI slot %s, revision %d\n", - DRV_NAME, pci_name(dev), dev->revision); - - if (dev->revision < IOC4_SUPPORTED_FIRMWARE_REV) { + DRV_NAME, pci_name(dev), class_rev); + if (class_rev < IOC4_SUPPORTED_FIRMWARE_REV) { printk(KERN_ERR "Skipping %s IDE controller in slot %s: " "firmware is obsolete - please upgrade to " "revision46 or higher\n", diff --git a/trunk/drivers/ide/pci/siimage.c b/trunk/drivers/ide/pci/siimage.c index 689786df1ede..85d0afd00e66 100644 --- a/trunk/drivers/ide/pci/siimage.c +++ b/trunk/drivers/ide/pci/siimage.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/siimage.c Version 1.17 Oct 18 2007 + * linux/drivers/ide/pci/siimage.c Version 1.16 Jul 13 2007 * * Copyright (C) 2001-2002 Andre Hedrick * Copyright (C) 2003 Red Hat @@ -180,7 +180,7 @@ static void sil_set_pio_mode(ide_drive_t *drive, u8 pio) const u16 data_speed[] = { 0x328a, 0x2283, 0x1104, 0x10c3, 0x10c1 }; ide_hwif_t *hwif = HWIF(drive); - ide_drive_t *pair = ide_get_paired_drive(drive); + ide_drive_t *pair = &hwif->drives[drive->dn ^ 1]; u32 speedt = 0; u16 speedp = 0; unsigned long addr = siimage_seldev(drive, 0x04); @@ -640,9 +640,13 @@ static unsigned int setup_mmio_siimage (struct pci_dev *dev, const char *name) static unsigned int __devinit init_chipset_siimage(struct pci_dev *dev, const char *name) { - u8 rev = dev->revision, tmpbyte = 0, BA5_EN = 0; + u32 class_rev = 0; + u8 tmpbyte = 0; + u8 BA5_EN = 0; - pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, rev ? 1 : 255); + pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); + class_rev &= 0xff; + pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (class_rev) ? 1 : 255); pci_read_config_byte(dev, 0x8A, &BA5_EN); if ((BA5_EN & 0x01) || (pci_resource_start(dev, 5))) { @@ -821,14 +825,19 @@ static void __devinit siimage_fixup(ide_hwif_t *hwif) static void __devinit init_iops_siimage(ide_hwif_t *hwif) { + struct pci_dev *dev = hwif->pci_dev; + u32 class_rev = 0; + + pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); + class_rev &= 0xff; + hwif->hwif_data = NULL; /* Pessimal until we finish probing */ hwif->rqsize = 15; - if (pci_get_drvdata(hwif->pci_dev) == NULL) + if (pci_get_drvdata(dev) == NULL) return; - init_mmio_iops_siimage(hwif); } @@ -882,11 +891,16 @@ static void __devinit init_hwif_siimage(ide_hwif_t *hwif) } } + hwif->drives[0].autotune = hwif->drives[1].autotune = 1; + if (hwif->dma_base == 0) return; - if (is_sata(hwif)) - hwif->host_flags |= IDE_HFLAG_NO_ATAPI_DMA; + hwif->ultra_mask = 0x7f; + hwif->mwdma_mask = 0x07; + + if (!is_sata(hwif)) + hwif->atapi_dma = 1; if (hwif->cbl != ATA_CBL_PATA40_SHORT) hwif->cbl = ata66_siimage(hwif); @@ -905,10 +919,9 @@ static void __devinit init_hwif_siimage(ide_hwif_t *hwif) .init_iops = init_iops_siimage, \ .init_hwif = init_hwif_siimage, \ .fixup = siimage_fixup, \ - .host_flags = IDE_HFLAG_BOOTABLE, \ + .autodma = AUTODMA, \ + .bootable = ON_BOARD, \ .pio_mask = ATA_PIO4, \ - .mwdma_mask = ATA_MWDMA2, \ - .udma_mask = ATA_UDMA6, \ } static ide_pci_device_t siimage_chipsets[] __devinitdata = { diff --git a/trunk/drivers/ide/pci/sis5513.c b/trunk/drivers/ide/pci/sis5513.c index c1d280b06391..5a54e2e20b3c 100644 --- a/trunk/drivers/ide/pci/sis5513.c +++ b/trunk/drivers/ide/pci/sis5513.c @@ -564,16 +564,25 @@ static void __devinit init_hwif_sis5513 (ide_hwif_t *hwif) { u8 udma_rates[] = { 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x7f, 0x7f }; + if (!hwif->irq) + hwif->irq = hwif->channel ? 15 : 14; + hwif->set_pio_mode = &sis_set_pio_mode; hwif->set_dma_mode = &sis_set_dma_mode; if (chipset_family >= ATA_133) hwif->udma_filter = sis5513_ata133_udma_filter; + hwif->drives[0].autotune = 1; + hwif->drives[1].autotune = 1; + if (hwif->dma_base == 0) return; + hwif->atapi_dma = 1; + hwif->ultra_mask = udma_rates[chipset_family]; + hwif->mwdma_mask = 0x07; if (hwif->cbl != ATA_CBL_PATA40_SHORT) hwif->cbl = ata66_sis5513(hwif); @@ -583,11 +592,10 @@ static ide_pci_device_t sis5513_chipset __devinitdata = { .name = "SIS5513", .init_chipset = init_chipset_sis5513, .init_hwif = init_hwif_sis5513, + .autodma = NOAUTODMA, .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, - .host_flags = IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_NO_AUTODMA | - IDE_HFLAG_BOOTABLE, + .bootable = ON_BOARD, .pio_mask = ATA_PIO4, - .mwdma_mask = ATA_MWDMA2, }; static int __devinit sis5513_init_one(struct pci_dev *dev, const struct pci_device_id *id) diff --git a/trunk/drivers/ide/pci/sl82c105.c b/trunk/drivers/ide/pci/sl82c105.c index 0dce459b1269..771efb8884c8 100644 --- a/trunk/drivers/ide/pci/sl82c105.c +++ b/trunk/drivers/ide/pci/sl82c105.c @@ -368,6 +368,12 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) hwif->drives[0].io_32bit = hwif->drives[1].io_32bit = 1; hwif->drives[0].unmask = hwif->drives[1].unmask = 1; + /* + * We always autotune PIO, this is done before DMA is checked, + * so there's no risk of accidentally disabling DMA + */ + hwif->drives[0].autotune = hwif->drives[1].autotune = 1; + if (!hwif->dma_base) return; @@ -382,7 +388,8 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) return; } - hwif->mwdma_mask = ATA_MWDMA2; + hwif->atapi_dma = 1; + hwif->mwdma_mask = 0x07; hwif->ide_dma_on = &sl82c105_ide_dma_on; hwif->dma_off_quietly = &sl82c105_dma_off_quietly; @@ -398,8 +405,9 @@ static ide_pci_device_t sl82c105_chipset __devinitdata = { .name = "W82C105", .init_chipset = init_chipset_sl82c105, .init_hwif = init_hwif_sl82c105, + .autodma = NOAUTODMA, .enablebits = {{0x40,0x01,0x01}, {0x40,0x10,0x10}}, - .host_flags = IDE_HFLAG_NO_AUTODMA | IDE_HFLAG_BOOTABLE, + .bootable = ON_BOARD, .pio_mask = ATA_PIO5, }; diff --git a/trunk/drivers/ide/pci/slc90e66.c b/trunk/drivers/ide/pci/slc90e66.c index 4f22dffdf8ef..fa8df6d43832 100644 --- a/trunk/drivers/ide/pci/slc90e66.c +++ b/trunk/drivers/ide/pci/slc90e66.c @@ -133,14 +133,25 @@ static void __devinit init_hwif_slc90e66 (ide_hwif_t *hwif) u8 reg47 = 0; u8 mask = hwif->channel ? 0x01 : 0x02; /* bit0:Primary */ + if (!hwif->irq) + hwif->irq = hwif->channel ? 15 : 14; + hwif->set_pio_mode = &slc90e66_set_pio_mode; hwif->set_dma_mode = &slc90e66_set_dma_mode; pci_read_config_byte(hwif->pci_dev, 0x47, ®47); + hwif->drives[0].autotune = 1; + hwif->drives[1].autotune = 1; + if (hwif->dma_base == 0) return; + hwif->atapi_dma = 1; + hwif->ultra_mask = 0x1f; + hwif->mwdma_mask = 0x06; + hwif->swdma_mask = 0x04; + if (hwif->cbl != ATA_CBL_PATA40_SHORT) /* bit[0(1)]: 0:80, 1:40 */ hwif->cbl = (reg47 & mask) ? ATA_CBL_PATA40 : ATA_CBL_PATA80; @@ -149,12 +160,10 @@ static void __devinit init_hwif_slc90e66 (ide_hwif_t *hwif) static ide_pci_device_t slc90e66_chipset __devinitdata = { .name = "SLC90E66", .init_hwif = init_hwif_slc90e66, + .autodma = AUTODMA, .enablebits = {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, - .host_flags = IDE_HFLAG_LEGACY_IRQS | IDE_HFLAG_BOOTABLE, + .bootable = ON_BOARD, .pio_mask = ATA_PIO4, - .swdma_mask = ATA_SWDMA2_ONLY, - .mwdma_mask = ATA_MWDMA12_ONLY, - .udma_mask = ATA_UDMA4, }; static int __devinit slc90e66_init_one(struct pci_dev *dev, const struct pci_device_id *id) diff --git a/trunk/drivers/ide/pci/tc86c001.c b/trunk/drivers/ide/pci/tc86c001.c index 631506e9b5d2..de62db576adc 100644 --- a/trunk/drivers/ide/pci/tc86c001.c +++ b/trunk/drivers/ide/pci/tc86c001.c @@ -1,5 +1,5 @@ /* - * drivers/ide/pci/tc86c001.c Version 1.01 Sep 5, 2007 + * drivers/ide/pci/tc86c001.c Version 1.00 Dec 12, 2006 * * Copyright (C) 2002 Toshiba Corporation * Copyright (C) 2005-2006 MontaVista Software, Inc. @@ -17,7 +17,7 @@ static void tc86c001_set_mode(ide_drive_t *drive, const u8 speed) { ide_hwif_t *hwif = HWIF(drive); unsigned long scr_port = hwif->config_data + (drive->dn ? 0x02 : 0x00); - u16 mode, scr = inw(scr_port); + u16 mode, scr = hwif->INW(scr_port); switch (speed) { case XFER_UDMA_4: mode = 0x00c0; break; @@ -65,7 +65,7 @@ static int tc86c001_timer_expiry(ide_drive_t *drive) ide_hwif_t *hwif = HWIF(drive); ide_expiry_t *expiry = ide_get_hwifdata(hwif); ide_hwgroup_t *hwgroup = HWGROUP(drive); - u8 dma_stat = inb(hwif->dma_status); + u8 dma_stat = hwif->INB(hwif->dma_status); /* Restore a higher level driver's expiry handler first. */ hwgroup->expiry = expiry; @@ -73,7 +73,7 @@ static int tc86c001_timer_expiry(ide_drive_t *drive) if ((dma_stat & 5) == 1) { /* DMA active and no interrupt */ unsigned long sc_base = hwif->config_data; unsigned long twcr_port = sc_base + (drive->dn ? 0x06 : 0x04); - u8 dma_cmd = inb(hwif->dma_command); + u8 dma_cmd = hwif->INB(hwif->dma_command); printk(KERN_WARNING "%s: DMA interrupt possibly stuck, " "attempting recovery...\n", drive->name); @@ -135,7 +135,7 @@ static int tc86c001_busproc(ide_drive_t *drive, int state) u16 scr1; /* System Control 1 Register bit 11 (ATA Hard Reset) read */ - scr1 = inw(sc_base + 0x00); + scr1 = hwif->INW(sc_base + 0x00); switch (state) { case BUSSTATE_ON: @@ -165,7 +165,7 @@ static int tc86c001_busproc(ide_drive_t *drive, int state) static void __devinit init_hwif_tc86c001(ide_hwif_t *hwif) { unsigned long sc_base = pci_resource_start(hwif->pci_dev, 5); - u16 scr1 = inw(sc_base + 0x00); + u16 scr1 = hwif->INW(sc_base + 0x00);; /* System Control 1 Register bit 15 (Soft Reset) set */ outw(scr1 | 0x8000, sc_base + 0x00); @@ -184,6 +184,8 @@ static void __devinit init_hwif_tc86c001(ide_hwif_t *hwif) hwif->busproc = &tc86c001_busproc; + hwif->drives[0].autotune = hwif->drives[1].autotune = 1; + if (!hwif->dma_base) return; @@ -196,6 +198,10 @@ static void __devinit init_hwif_tc86c001(ide_hwif_t *hwif) /* Sector Count Register limit */ hwif->rqsize = 0xffff; + hwif->atapi_dma = 1; + hwif->ultra_mask = 0x1f; + hwif->mwdma_mask = 0x07; + hwif->dma_start = &tc86c001_dma_start; if (hwif->cbl != ATA_CBL_PATA40_SHORT) { @@ -203,7 +209,7 @@ static void __devinit init_hwif_tc86c001(ide_hwif_t *hwif) * System Control 1 Register bit 13 (PDIAGN): * 0=80-pin cable, 1=40-pin cable */ - scr1 = inw(sc_base + 0x00); + scr1 = hwif->INW(sc_base + 0x00); hwif->cbl = (scr1 & 0x2000) ? ATA_CBL_PATA40 : ATA_CBL_PATA80; } } @@ -222,10 +228,10 @@ static ide_pci_device_t tc86c001_chipset __devinitdata = { .name = "TC86C001", .init_chipset = init_chipset_tc86c001, .init_hwif = init_hwif_tc86c001, - .host_flags = IDE_HFLAG_SINGLE | IDE_HFLAG_OFF_BOARD, + .autodma = AUTODMA, + .bootable = OFF_BOARD, + .host_flags = IDE_HFLAG_SINGLE, .pio_mask = ATA_PIO4, - .mwdma_mask = ATA_MWDMA2, - .udma_mask = ATA_UDMA4, }; static int __devinit tc86c001_init_one(struct pci_dev *dev, diff --git a/trunk/drivers/ide/pci/triflex.c b/trunk/drivers/ide/pci/triflex.c index 30b52f62699a..4075c907f05c 100644 --- a/trunk/drivers/ide/pci/triflex.c +++ b/trunk/drivers/ide/pci/triflex.c @@ -100,16 +100,22 @@ static void __devinit init_hwif_triflex(ide_hwif_t *hwif) { hwif->set_pio_mode = &triflex_set_pio_mode; hwif->set_dma_mode = &triflex_set_mode; + + if (hwif->dma_base == 0) + return; + + hwif->atapi_dma = 1; + hwif->mwdma_mask = 0x07; + hwif->swdma_mask = 0x07; } static ide_pci_device_t triflex_device __devinitdata = { .name = "TRIFLEX", .init_hwif = init_hwif_triflex, + .autodma = AUTODMA, .enablebits = {{0x80, 0x01, 0x01}, {0x80, 0x02, 0x02}}, - .host_flags = IDE_HFLAG_BOOTABLE, + .bootable = ON_BOARD, .pio_mask = ATA_PIO4, - .swdma_mask = ATA_SWDMA2, - .mwdma_mask = ATA_MWDMA2, }; static int __devinit triflex_init_one(struct pci_dev *dev, diff --git a/trunk/drivers/ide/pci/trm290.c b/trunk/drivers/ide/pci/trm290.c index 140d486f6237..e3d943ada7b0 100644 --- a/trunk/drivers/ide/pci/trm290.c +++ b/trunk/drivers/ide/pci/trm290.c @@ -250,6 +250,7 @@ static void __devinit init_hwif_trm290(ide_hwif_t *hwif) u8 reg = 0; struct pci_dev *dev = hwif->pci_dev; + hwif->no_lba48 = 1; hwif->chipset = ide_trm290; cfgbase = pci_resource_start(dev, 4); if ((dev->class & 5) && cfgbase) { @@ -323,13 +324,11 @@ static void __devinit init_hwif_trm290(ide_hwif_t *hwif) static ide_pci_device_t trm290_chipset __devinitdata = { .name = "TRM290", .init_hwif = init_hwif_trm290, - .host_flags = IDE_HFLAG_NO_ATAPI_DMA | + .autodma = NOAUTODMA, + .bootable = ON_BOARD, #if 0 /* play it safe for now */ - IDE_HFLAG_TRUST_BIOS_FOR_DMA | + .host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA, #endif - IDE_HFLAG_NO_AUTODMA | - IDE_HFLAG_BOOTABLE | - IDE_HFLAG_NO_LBA48, }; static int __devinit trm290_init_one(struct pci_dev *dev, const struct pci_device_id *id) diff --git a/trunk/drivers/ide/pci/via82cxxx.c b/trunk/drivers/ide/pci/via82cxxx.c index c8022a92a0e3..b25fb65b240e 100644 --- a/trunk/drivers/ide/pci/via82cxxx.c +++ b/trunk/drivers/ide/pci/via82cxxx.c @@ -437,12 +437,17 @@ static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif) for (i = 0; i < 2; i++) { hwif->drives[i].io_32bit = 1; hwif->drives[i].unmask = (vdev->via_config->flags & VIA_NO_UNMASK) ? 0 : 1; + hwif->drives[i].autotune = 1; } if (!hwif->dma_base) return; + hwif->atapi_dma = 1; + hwif->ultra_mask = vdev->via_config->udma_mask; + hwif->mwdma_mask = 0x07; + hwif->swdma_mask = 0x07; if (hwif->cbl != ATA_CBL_PATA40_SHORT) hwif->cbl = via82cxxx_cable_detect(hwif); @@ -453,27 +458,24 @@ static ide_pci_device_t via82cxxx_chipsets[] __devinitdata = { .name = "VP_IDE", .init_chipset = init_chipset_via82cxxx, .init_hwif = init_hwif_via82cxxx, + .autodma = NOAUTODMA, .enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, - .host_flags = IDE_HFLAG_PIO_NO_BLACKLIST | - IDE_HFLAG_PIO_NO_DOWNGRADE | - IDE_HFLAG_POST_SET_MODE | - IDE_HFLAG_NO_AUTODMA | - IDE_HFLAG_BOOTABLE, + .bootable = ON_BOARD, + .host_flags = IDE_HFLAG_PIO_NO_BLACKLIST + | IDE_HFLAG_PIO_NO_DOWNGRADE + | IDE_HFLAG_POST_SET_MODE, .pio_mask = ATA_PIO5, - .swdma_mask = ATA_SWDMA2, - .mwdma_mask = ATA_MWDMA2, },{ /* 1 */ .name = "VP_IDE", .init_chipset = init_chipset_via82cxxx, .init_hwif = init_hwif_via82cxxx, + .autodma = AUTODMA, .enablebits = {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, - .host_flags = IDE_HFLAG_PIO_NO_BLACKLIST | - IDE_HFLAG_PIO_NO_DOWNGRADE | - IDE_HFLAG_POST_SET_MODE | - IDE_HFLAG_BOOTABLE, + .bootable = ON_BOARD, + .host_flags = IDE_HFLAG_PIO_NO_BLACKLIST + | IDE_HFLAG_PIO_NO_DOWNGRADE + | IDE_HFLAG_POST_SET_MODE, .pio_mask = ATA_PIO5, - .swdma_mask = ATA_SWDMA2, - .mwdma_mask = ATA_MWDMA2, } }; diff --git a/trunk/drivers/ide/ppc/pmac.c b/trunk/drivers/ide/ppc/pmac.c index c55479356768..1d25a3433008 100644 --- a/trunk/drivers/ide/ppc/pmac.c +++ b/trunk/drivers/ide/ppc/pmac.c @@ -1780,6 +1780,7 @@ pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif) hwif->dma_timeout = &ide_dma_timeout; hwif->dma_lost_irq = &pmac_ide_dma_lost_irq; + hwif->atapi_dma = 1; switch(pmif->kind) { case controller_sh_ata6: hwif->ultra_mask = pmif->cable_80 ? 0x7f : 0x07; diff --git a/trunk/drivers/ide/setup-pci.c b/trunk/drivers/ide/setup-pci.c index fff567bcedbe..3d101f73f910 100644 --- a/trunk/drivers/ide/setup-pci.c +++ b/trunk/drivers/ide/setup-pci.c @@ -147,7 +147,6 @@ static int ide_setup_pci_baseregs (struct pci_dev *dev, const char *name) #ifdef CONFIG_BLK_DEV_IDEDMA_PCI /** * ide_get_or_set_dma_base - setup BMIBA - * @d: IDE pci device data * @hwif: Interface * * Fetch the DMA Bus-Master-I/O-Base-Address (BMIBA) from PCI space. @@ -155,7 +154,7 @@ static int ide_setup_pci_baseregs (struct pci_dev *dev, const char *name) * and enforce IDE simplex rules. */ -static unsigned long ide_get_or_set_dma_base(ide_pci_device_t *d, ide_hwif_t *hwif) +static unsigned long ide_get_or_set_dma_base (ide_hwif_t *hwif) { unsigned long dma_base = 0; struct pci_dev *dev = hwif->pci_dev; @@ -166,15 +165,14 @@ static unsigned long ide_get_or_set_dma_base(ide_pci_device_t *d, ide_hwif_t *hw if (hwif->mate && hwif->mate->dma_base) { dma_base = hwif->mate->dma_base - (hwif->channel ? 0 : 8); } else { - u8 baridx = (d->host_flags & IDE_HFLAG_CS5520) ? 2 : 4; - - dma_base = pci_resource_start(dev, baridx); - - if (dma_base == 0) - printk(KERN_ERR "%s: DMA base is invalid\n", d->name); + dma_base = pci_resource_start(dev, 4); + if (!dma_base) { + printk(KERN_ERR "%s: dma_base is invalid\n", + hwif->cds->name); + } } - if ((d->host_flags & IDE_HFLAG_CS5520) == 0 && dma_base) { + if (dma_base) { u8 simplex_stat = 0; dma_base += hwif->channel ? 8 : 0; @@ -185,13 +183,13 @@ static unsigned long ide_get_or_set_dma_base(ide_pci_device_t *d, ide_hwif_t *hw case PCI_DEVICE_ID_CMD_643: case PCI_DEVICE_ID_SERVERWORKS_CSB5IDE: case PCI_DEVICE_ID_REVOLUTION: - simplex_stat = inb(dma_base + 2); - outb(simplex_stat & 0x60, dma_base + 2); - simplex_stat = inb(dma_base + 2); + simplex_stat = hwif->INB(dma_base + 2); + hwif->OUTB((simplex_stat&0x60),(dma_base + 2)); + simplex_stat = hwif->INB(dma_base + 2); if (simplex_stat & 0x80) { printk(KERN_INFO "%s: simplex device: " - "DMA forced\n", - d->name); + "DMA forced\n", + hwif->cds->name); } break; default: @@ -214,8 +212,8 @@ static unsigned long ide_get_or_set_dma_base(ide_pci_device_t *d, ide_hwif_t *hw */ if (hwif->mate && hwif->mate->dma_base) { printk(KERN_INFO "%s: simplex device: " - "DMA disabled\n", - d->name); + "DMA disabled\n", + hwif->cds->name); dma_base = 0; } } @@ -362,7 +360,6 @@ static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev, ide_pci_device_t *d, { unsigned long ctl = 0, base = 0; ide_hwif_t *hwif; - u8 bootable = (d->host_flags & IDE_HFLAG_BOOTABLE) ? 1 : 0; if ((d->host_flags & IDE_HFLAG_ISA_PORTS) == 0) { /* Possibly we should fail if these checks report true */ @@ -383,7 +380,7 @@ static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev, ide_pci_device_t *d, ctl = port ? 0x374 : 0x3f4; base = port ? 0x170 : 0x1f0; } - if ((hwif = ide_match_hwif(base, bootable, d->name)) == NULL) + if ((hwif = ide_match_hwif(base, d->bootable, d->name)) == NULL) return NULL; /* no room in ide_hwifs[] */ if (hwif->io_ports[IDE_DATA_OFFSET] != base || hwif->io_ports[IDE_CONTROL_OFFSET] != (ctl | 2)) { @@ -430,13 +427,12 @@ static void ide_hwif_setup_dma(struct pci_dev *dev, ide_pci_device_t *d, ide_hwi static void ide_hwif_setup_dma(struct pci_dev *dev, ide_pci_device_t *d, ide_hwif_t *hwif) { u16 pcicmd; - pci_read_config_word(dev, PCI_COMMAND, &pcicmd); - if ((d->host_flags & IDE_HFLAG_NO_AUTODMA) == 0 || + if ((d->autodma == AUTODMA) || ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE && (dev->class & 0x80))) { - unsigned long dma_base = ide_get_or_set_dma_base(d, hwif); + unsigned long dma_base = ide_get_or_set_dma_base(hwif); if (dma_base && !(pcicmd & PCI_COMMAND_MASTER)) { /* * Set up BM-DMA capability @@ -478,6 +474,7 @@ static void ide_hwif_setup_dma(struct pci_dev *dev, ide_pci_device_t *d, ide_hwi static int ide_setup_pci_controller(struct pci_dev *dev, ide_pci_device_t *d, int noisy, int *config) { int ret; + u32 class_rev; u16 pcicmd; if (noisy) @@ -500,9 +497,10 @@ static int ide_setup_pci_controller(struct pci_dev *dev, ide_pci_device_t *d, in printk(KERN_INFO "%s: device enabled (Linux)\n", d->name); } + pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); + class_rev &= 0xff; if (noisy) - printk(KERN_INFO "%s: chipset revision %d\n", - d->name, dev->revision); + printk(KERN_INFO "%s: chipset revision %d\n", d->name, class_rev); out: return ret; } @@ -559,27 +557,17 @@ void ide_pci_setup_ports(struct pci_dev *dev, ide_pci_device_t *d, int pciirq, a if (d->init_iops) d->init_iops(hwif); - if ((d->host_flags & IDE_HFLAG_NO_DMA) == 0) - ide_hwif_setup_dma(dev, d, hwif); - - if ((d->host_flags & IDE_HFLAG_LEGACY_IRQS) && hwif->irq == 0) - hwif->irq = port ? 15 : 14; + if (d->autodma == NODMA) + goto bypass_legacy_dma; + if(d->init_setup_dma) + d->init_setup_dma(dev, d, hwif); + else + ide_hwif_setup_dma(dev, d, hwif); +bypass_legacy_dma: hwif->host_flags = d->host_flags; hwif->pio_mask = d->pio_mask; - if ((d->host_flags & IDE_HFLAG_SERIALIZE) && hwif->mate) - hwif->mate->serialized = hwif->serialized = 1; - - if (hwif->dma_base) { - hwif->swdma_mask = d->swdma_mask; - hwif->mwdma_mask = d->mwdma_mask; - hwif->ultra_mask = d->udma_mask; - } - - hwif->drives[0].autotune = 1; - hwif->drives[1].autotune = 1; - if (d->init_hwif) /* Call chipset-specific routine * for each enabled hwif diff --git a/trunk/drivers/infiniband/core/cma.c b/trunk/drivers/infiniband/core/cma.c index d08fb30768bc..93644f82592c 100644 --- a/trunk/drivers/infiniband/core/cma.c +++ b/trunk/drivers/infiniband/core/cma.c @@ -2797,12 +2797,11 @@ static void cma_remove_one(struct ib_device *device) static int cma_init(void) { - int ret, low, high, remaining; + int ret, low, high; get_random_bytes(&next_port, sizeof next_port); inet_get_local_port_range(&low, &high); - remaining = (high - low) + 1; - next_port = ((unsigned int) next_port % remaining) + low; + next_port = ((unsigned int) next_port % (high - low)) + low; cma_wq = create_singlethread_workqueue("rdma_cm"); if (!cma_wq) diff --git a/trunk/drivers/infiniband/hw/ehca/ehca_main.c b/trunk/drivers/infiniband/hw/ehca/ehca_main.c index 7a7dab890f6d..a3409fdb307c 100644 --- a/trunk/drivers/infiniband/hw/ehca/ehca_main.c +++ b/trunk/drivers/infiniband/hw/ehca/ehca_main.c @@ -579,12 +579,12 @@ static ssize_t ehca_show_##name(struct device *dev, \ \ rblock = ehca_alloc_fw_ctrlblock(GFP_KERNEL); \ if (!rblock) { \ - dev_err(dev, "Can't allocate rblock memory.\n"); \ + dev_err(dev, "Can't allocate rblock memory."); \ return 0; \ } \ \ if (hipz_h_query_hca(shca->ipz_hca_handle, rblock) != H_SUCCESS) { \ - dev_err(dev, "Can't query device properties\n"); \ + dev_err(dev, "Can't query device properties"); \ ehca_free_fw_ctrlblock(rblock); \ return 0; \ } \ diff --git a/trunk/drivers/input/evdev.c b/trunk/drivers/input/evdev.c index e5b4e9bfbdc5..1d62c8b88e12 100644 --- a/trunk/drivers/input/evdev.c +++ b/trunk/drivers/input/evdev.c @@ -495,7 +495,7 @@ static unsigned int evdev_poll(struct file *file, poll_table *wait) #ifdef CONFIG_COMPAT #define BITS_PER_LONG_COMPAT (sizeof(compat_long_t) * 8) -#define BITS_TO_LONGS_COMPAT(x) ((((x) - 1) / BITS_PER_LONG_COMPAT) + 1) +#define NBITS_COMPAT(x) ((((x) - 1) / BITS_PER_LONG_COMPAT) + 1) #ifdef __BIG_ENDIAN static int bits_to_user(unsigned long *bits, unsigned int maxbit, @@ -504,7 +504,7 @@ static int bits_to_user(unsigned long *bits, unsigned int maxbit, int len, i; if (compat) { - len = BITS_TO_LONGS_COMPAT(maxbit) * sizeof(compat_long_t); + len = NBITS_COMPAT(maxbit) * sizeof(compat_long_t); if (len > maxlen) len = maxlen; @@ -515,7 +515,7 @@ static int bits_to_user(unsigned long *bits, unsigned int maxbit, sizeof(compat_long_t))) return -EFAULT; } else { - len = BITS_TO_LONGS(maxbit) * sizeof(long); + len = NBITS(maxbit) * sizeof(long); if (len > maxlen) len = maxlen; @@ -530,8 +530,8 @@ static int bits_to_user(unsigned long *bits, unsigned int maxbit, unsigned int maxlen, void __user *p, int compat) { int len = compat ? - BITS_TO_LONGS_COMPAT(maxbit) * sizeof(compat_long_t) : - BITS_TO_LONGS(maxbit) * sizeof(long); + NBITS_COMPAT(maxbit) * sizeof(compat_long_t) : + NBITS(maxbit) * sizeof(long); if (len > maxlen) len = maxlen; @@ -545,7 +545,7 @@ static int bits_to_user(unsigned long *bits, unsigned int maxbit, static int bits_to_user(unsigned long *bits, unsigned int maxbit, unsigned int maxlen, void __user *p, int compat) { - int len = BITS_TO_LONGS(maxbit) * sizeof(long); + int len = NBITS(maxbit) * sizeof(long); if (len > maxlen) len = maxlen; diff --git a/trunk/drivers/input/gameport/gameport.c b/trunk/drivers/input/gameport/gameport.c index ec1b6cfefcd3..20896d5e5f0e 100644 --- a/trunk/drivers/input/gameport/gameport.c +++ b/trunk/drivers/input/gameport/gameport.c @@ -448,8 +448,9 @@ static int gameport_thread(void *nothing) set_freezable(); do { gameport_handle_event(); - wait_event_freezable(gameport_wait, + wait_event_interruptible(gameport_wait, kthread_should_stop() || !list_empty(&gameport_event_list)); + try_to_freeze(); } while (!kthread_should_stop()); printk(KERN_DEBUG "gameport: kgameportd exiting\n"); diff --git a/trunk/drivers/input/input.c b/trunk/drivers/input/input.c index 307c7b5c2b33..2f2b020cd629 100644 --- a/trunk/drivers/input/input.c +++ b/trunk/drivers/input/input.c @@ -584,10 +584,10 @@ static int input_default_setkeycode(struct input_dev *dev, #define MATCH_BIT(bit, max) \ - for (i = 0; i < BITS_TO_LONGS(max); i++) \ + for (i = 0; i < NBITS(max); i++) \ if ((id->bit[i] & dev->bit[i]) != id->bit[i]) \ break; \ - if (i != BITS_TO_LONGS(max)) \ + if (i != NBITS(max)) \ continue; static const struct input_device_id *input_match_device(const struct input_device_id *id, @@ -698,7 +698,7 @@ static void input_seq_print_bitmap(struct seq_file *seq, const char *name, { int i; - for (i = BITS_TO_LONGS(max) - 1; i > 0; i--) + for (i = NBITS(max) - 1; i > 0; i--) if (bitmap[i]) break; @@ -892,7 +892,7 @@ static int input_print_modalias_bits(char *buf, int size, len += snprintf(buf, max(size, 0), "%c", name); for (i = min_bit; i < max_bit; i++) - if (bm[BIT_WORD(i)] & BIT_MASK(i)) + if (bm[LONG(i)] & BIT(i)) len += snprintf(buf + len, max(size - len, 0), "%X,", i); return len; } @@ -991,7 +991,7 @@ static int input_print_bitmap(char *buf, int buf_size, unsigned long *bitmap, int i; int len = 0; - for (i = BITS_TO_LONGS(max) - 1; i > 0; i--) + for (i = NBITS(max) - 1; i > 0; i--) if (bitmap[i]) break; diff --git a/trunk/drivers/input/joydev.c b/trunk/drivers/input/joydev.c index 22b2789ef58a..2b201f9aa024 100644 --- a/trunk/drivers/input/joydev.c +++ b/trunk/drivers/input/joydev.c @@ -844,8 +844,8 @@ static const struct input_device_id joydev_blacklist[] = { { .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT, - .evbit = { BIT_MASK(EV_KEY) }, - .keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) }, + .evbit = { BIT(EV_KEY) }, + .keybit = { [LONG(BTN_TOUCH)] = BIT(BTN_TOUCH) }, }, /* Avoid itouchpads, touchscreens and tablets */ { } /* Terminating entry */ }; @@ -854,20 +854,20 @@ static const struct input_device_id joydev_ids[] = { { .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT, - .evbit = { BIT_MASK(EV_ABS) }, - .absbit = { BIT_MASK(ABS_X) }, + .evbit = { BIT(EV_ABS) }, + .absbit = { BIT(ABS_X) }, }, { .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT, - .evbit = { BIT_MASK(EV_ABS) }, - .absbit = { BIT_MASK(ABS_WHEEL) }, + .evbit = { BIT(EV_ABS) }, + .absbit = { BIT(ABS_WHEEL) }, }, { .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_ABSBIT, - .evbit = { BIT_MASK(EV_ABS) }, - .absbit = { BIT_MASK(ABS_THROTTLE) }, + .evbit = { BIT(EV_ABS) }, + .absbit = { BIT(ABS_THROTTLE) }, }, { } /* Terminating entry */ }; diff --git a/trunk/drivers/input/joystick/a3d.c b/trunk/drivers/input/joystick/a3d.c index 52ba16f487c7..ff701ab10d74 100644 --- a/trunk/drivers/input/joystick/a3d.c +++ b/trunk/drivers/input/joystick/a3d.c @@ -326,19 +326,14 @@ static int a3d_connect(struct gameport *gameport, struct gameport_driver *drv) a3d->length = 33; - input_dev->evbit[0] |= BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY) | - BIT_MASK(EV_REL); - input_dev->relbit[0] |= BIT_MASK(REL_X) | BIT_MASK(REL_Y); - input_dev->absbit[0] |= BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) | - BIT_MASK(ABS_THROTTLE) | BIT_MASK(ABS_RUDDER) | - BIT_MASK(ABS_HAT0X) | BIT_MASK(ABS_HAT0Y) | - BIT_MASK(ABS_HAT1X) | BIT_MASK(ABS_HAT1Y); - input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_RIGHT) | - BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_MIDDLE) | - BIT_MASK(BTN_SIDE) | BIT_MASK(BTN_EXTRA); - input_dev->keybit[BIT_WORD(BTN_JOYSTICK)] |= - BIT_MASK(BTN_TRIGGER) | BIT_MASK(BTN_THUMB) | - BIT_MASK(BTN_TOP) | BIT_MASK(BTN_PINKIE); + input_dev->evbit[0] |= BIT(EV_ABS) | BIT(EV_KEY) | BIT(EV_REL); + input_dev->relbit[0] |= BIT(REL_X) | BIT(REL_Y); + input_dev->absbit[0] |= BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_THROTTLE) | BIT(ABS_RUDDER) + | BIT(ABS_HAT0X) | BIT(ABS_HAT0Y) | BIT(ABS_HAT1X) | BIT(ABS_HAT1Y); + input_dev->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_RIGHT) | BIT(BTN_LEFT) | BIT(BTN_MIDDLE) + | BIT(BTN_SIDE) | BIT(BTN_EXTRA); + input_dev->keybit[LONG(BTN_JOYSTICK)] |= BIT(BTN_TRIGGER) | BIT(BTN_THUMB) | BIT(BTN_TOP) + | BIT(BTN_PINKIE); a3d_read(a3d, data); @@ -353,10 +348,9 @@ static int a3d_connect(struct gameport *gameport, struct gameport_driver *drv) } else { a3d->length = 29; - input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); - input_dev->relbit[0] |= BIT_MASK(REL_X) | BIT_MASK(REL_Y); - input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_RIGHT) | - BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_MIDDLE); + input_dev->evbit[0] |= BIT(EV_KEY) | BIT(EV_REL); + input_dev->relbit[0] |= BIT(REL_X) | BIT(REL_Y); + input_dev->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_RIGHT) | BIT(BTN_LEFT) | BIT(BTN_MIDDLE); a3d_read(a3d, data); diff --git a/trunk/drivers/input/joystick/adi.c b/trunk/drivers/input/joystick/adi.c index d1ca8a14950f..28140c4a110d 100644 --- a/trunk/drivers/input/joystick/adi.c +++ b/trunk/drivers/input/joystick/adi.c @@ -431,7 +431,7 @@ static int adi_init_input(struct adi *adi, struct adi_port *port, int half) input_dev->open = adi_open; input_dev->close = adi_close; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); for (i = 0; i < adi->axes10 + adi->axes8 + (adi->hats + (adi->pad != -1)) * 2; i++) set_bit(adi->abs[i], input_dev->absbit); diff --git a/trunk/drivers/input/joystick/amijoy.c b/trunk/drivers/input/joystick/amijoy.c index 5cf9f3610e67..b0f5541ec3e6 100644 --- a/trunk/drivers/input/joystick/amijoy.c +++ b/trunk/drivers/input/joystick/amijoy.c @@ -137,10 +137,9 @@ static int __init amijoy_init(void) amijoy_dev[i]->open = amijoy_open; amijoy_dev[i]->close = amijoy_close; - amijoy_dev[i]->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); - amijoy_dev[i]->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y); - amijoy_dev[i]->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) | - BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT); + amijoy_dev[i]->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + amijoy_dev[i]->absbit[0] = BIT(ABS_X) | BIT(ABS_Y); + amijoy_dev[i]->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); for (j = 0; j < 2; j++) { amijoy_dev[i]->absmin[ABS_X + j] = -1; amijoy_dev[i]->absmax[ABS_X + j] = 1; diff --git a/trunk/drivers/input/joystick/analog.c b/trunk/drivers/input/joystick/analog.c index 15739880afc6..bdd157c1ebf8 100644 --- a/trunk/drivers/input/joystick/analog.c +++ b/trunk/drivers/input/joystick/analog.c @@ -456,7 +456,7 @@ static int analog_init_device(struct analog_port *port, struct analog *analog, i input_dev->open = analog_open; input_dev->close = analog_close; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); for (i = j = 0; i < 4; i++) if (analog->mask & (1 << i)) { diff --git a/trunk/drivers/input/joystick/cobra.c b/trunk/drivers/input/joystick/cobra.c index 55646a6d89f5..d3352a849b85 100644 --- a/trunk/drivers/input/joystick/cobra.c +++ b/trunk/drivers/input/joystick/cobra.c @@ -218,7 +218,7 @@ static int cobra_connect(struct gameport *gameport, struct gameport_driver *drv) input_dev->open = cobra_open; input_dev->close = cobra_close; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); input_set_abs_params(input_dev, ABS_X, -1, 1, 0, 0); input_set_abs_params(input_dev, ABS_Y, -1, 1, 0, 0); for (j = 0; cobra_btn[j]; j++) diff --git a/trunk/drivers/input/joystick/db9.c b/trunk/drivers/input/joystick/db9.c index 27fc475bd3a1..b069ee18e353 100644 --- a/trunk/drivers/input/joystick/db9.c +++ b/trunk/drivers/input/joystick/db9.c @@ -631,7 +631,7 @@ static struct db9 __init *db9_probe(int parport, int mode) input_dev->open = db9_open; input_dev->close = db9_close; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); for (j = 0; j < db9_mode->n_buttons; j++) set_bit(db9_mode->buttons[j], input_dev->keybit); for (j = 0; j < db9_mode->n_axis; j++) { diff --git a/trunk/drivers/input/joystick/gamecon.c b/trunk/drivers/input/joystick/gamecon.c index df2a9d02ca6c..1a452e0e5f25 100644 --- a/trunk/drivers/input/joystick/gamecon.c +++ b/trunk/drivers/input/joystick/gamecon.c @@ -653,12 +653,12 @@ static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type) input_dev->close = gc_close; if (pad_type != GC_SNESMOUSE) { - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); for (i = 0; i < 2; i++) input_set_abs_params(input_dev, ABS_X + i, -1, 1, 0, 0); } else - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); gc->pads[0] |= gc_status_bit[idx]; gc->pads[pad_type] |= gc_status_bit[idx]; diff --git a/trunk/drivers/input/joystick/gf2k.c b/trunk/drivers/input/joystick/gf2k.c index 1f6302c0eb3f..d514aebf7554 100644 --- a/trunk/drivers/input/joystick/gf2k.c +++ b/trunk/drivers/input/joystick/gf2k.c @@ -315,7 +315,7 @@ static int gf2k_connect(struct gameport *gameport, struct gameport_driver *drv) input_dev->open = gf2k_open; input_dev->close = gf2k_close; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); for (i = 0; i < gf2k_axes[gf2k->id]; i++) set_bit(gf2k_abs[i], input_dev->absbit); diff --git a/trunk/drivers/input/joystick/grip.c b/trunk/drivers/input/joystick/grip.c index fd3853ab1aad..73eb5ab6f140 100644 --- a/trunk/drivers/input/joystick/grip.c +++ b/trunk/drivers/input/joystick/grip.c @@ -370,7 +370,7 @@ static int grip_connect(struct gameport *gameport, struct gameport_driver *drv) input_dev->open = grip_open; input_dev->close = grip_close; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); for (j = 0; (t = grip_abs[grip->mode[i]][j]) >= 0; j++) { diff --git a/trunk/drivers/input/joystick/grip_mp.c b/trunk/drivers/input/joystick/grip_mp.c index c57e21d68c00..4ed3a3eadf19 100644 --- a/trunk/drivers/input/joystick/grip_mp.c +++ b/trunk/drivers/input/joystick/grip_mp.c @@ -606,7 +606,7 @@ static int register_slot(int slot, struct grip_mp *grip) input_dev->open = grip_open; input_dev->close = grip_close; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); for (j = 0; (t = grip_abs[port->mode][j]) >= 0; j++) input_set_abs_params(input_dev, t, -1, 1, 0, 0); diff --git a/trunk/drivers/input/joystick/guillemot.c b/trunk/drivers/input/joystick/guillemot.c index aa6bfb3fb8cd..d4e8073caf27 100644 --- a/trunk/drivers/input/joystick/guillemot.c +++ b/trunk/drivers/input/joystick/guillemot.c @@ -238,7 +238,7 @@ static int guillemot_connect(struct gameport *gameport, struct gameport_driver * input_dev->open = guillemot_open; input_dev->close = guillemot_close; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); for (i = 0; (t = guillemot->type->abs[i]) >= 0; i++) input_set_abs_params(input_dev, t, 0, 255, 0, 0); diff --git a/trunk/drivers/input/joystick/iforce/iforce-main.c b/trunk/drivers/input/joystick/iforce/iforce-main.c index 6f826b37d9aa..682244b1c042 100644 --- a/trunk/drivers/input/joystick/iforce/iforce-main.c +++ b/trunk/drivers/input/joystick/iforce/iforce-main.c @@ -389,8 +389,7 @@ int iforce_init_device(struct iforce *iforce) * Set input device bitfields and ranges. */ - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) | - BIT_MASK(EV_FF_STATUS); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_FF_STATUS); for (i = 0; iforce->type->btn[i] >= 0; i++) set_bit(iforce->type->btn[i], input_dev->keybit); diff --git a/trunk/drivers/input/joystick/iforce/iforce.h b/trunk/drivers/input/joystick/iforce/iforce.h index a964a7cfd210..40a853ac21c7 100644 --- a/trunk/drivers/input/joystick/iforce/iforce.h +++ b/trunk/drivers/input/joystick/iforce/iforce.h @@ -62,13 +62,13 @@ #define FF_CORE_IS_PLAYED 3 /* Effect is currently being played */ #define FF_CORE_SHOULD_PLAY 4 /* User wants the effect to be played */ #define FF_CORE_UPDATE 5 /* Effect is being updated */ -#define FF_MODCORE_CNT 6 +#define FF_MODCORE_MAX 5 struct iforce_core_effect { /* Information about where modifiers are stored in the device's memory */ struct resource mod1_chunk; struct resource mod2_chunk; - unsigned long flags[BITS_TO_LONGS(FF_MODCORE_CNT)]; + unsigned long flags[NBITS(FF_MODCORE_MAX)]; }; #define FF_CMD_EFFECT 0x010e diff --git a/trunk/drivers/input/joystick/interact.c b/trunk/drivers/input/joystick/interact.c index bc8ea95dfd0e..1aec1e9d7c59 100644 --- a/trunk/drivers/input/joystick/interact.c +++ b/trunk/drivers/input/joystick/interact.c @@ -269,7 +269,7 @@ static int interact_connect(struct gameport *gameport, struct gameport_driver *d input_dev->open = interact_open; input_dev->close = interact_close; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); for (i = 0; (t = interact_type[interact->type].abs[i]) >= 0; i++) { set_bit(t, input_dev->absbit); diff --git a/trunk/drivers/input/joystick/magellan.c b/trunk/drivers/input/joystick/magellan.c index 54e676948ebb..b35604ee43ae 100644 --- a/trunk/drivers/input/joystick/magellan.c +++ b/trunk/drivers/input/joystick/magellan.c @@ -170,7 +170,7 @@ static int magellan_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.version = 0x0100; input_dev->dev.parent = &serio->dev; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); for (i = 0; i < 9; i++) set_bit(magellan_buttons[i], input_dev->keybit); diff --git a/trunk/drivers/input/joystick/sidewinder.c b/trunk/drivers/input/joystick/sidewinder.c index 7b4865fdee54..2adf73f63c94 100644 --- a/trunk/drivers/input/joystick/sidewinder.c +++ b/trunk/drivers/input/joystick/sidewinder.c @@ -758,7 +758,7 @@ static int sw_connect(struct gameport *gameport, struct gameport_driver *drv) input_dev->open = sw_open; input_dev->close = sw_close; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); for (j = 0; (bits = sw_bit[sw->type][j]); j++) { code = sw_abs[sw->type][j]; diff --git a/trunk/drivers/input/joystick/spaceball.c b/trunk/drivers/input/joystick/spaceball.c index d4087fd49656..abb7c4cf54ad 100644 --- a/trunk/drivers/input/joystick/spaceball.c +++ b/trunk/drivers/input/joystick/spaceball.c @@ -228,23 +228,18 @@ static int spaceball_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.version = 0x0100; input_dev->dev.parent = &serio->dev; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); switch (id) { case SPACEBALL_4000FLX: case SPACEBALL_4000FLX_L: - input_dev->keybit[BIT_WORD(BTN_0)] |= BIT_MASK(BTN_9); - input_dev->keybit[BIT_WORD(BTN_A)] |= BIT_MASK(BTN_A) | - BIT_MASK(BTN_B) | BIT_MASK(BTN_C) | - BIT_MASK(BTN_MODE); + input_dev->keybit[LONG(BTN_0)] |= BIT(BTN_9); + input_dev->keybit[LONG(BTN_A)] |= BIT(BTN_A) | BIT(BTN_B) | BIT(BTN_C) | BIT(BTN_MODE); default: - input_dev->keybit[BIT_WORD(BTN_0)] |= BIT_MASK(BTN_2) | - BIT_MASK(BTN_3) | BIT_MASK(BTN_4) | - BIT_MASK(BTN_5) | BIT_MASK(BTN_6) | - BIT_MASK(BTN_7) | BIT_MASK(BTN_8); + input_dev->keybit[LONG(BTN_0)] |= BIT(BTN_2) | BIT(BTN_3) | BIT(BTN_4) + | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7) | BIT(BTN_8); case SPACEBALL_3003C: - input_dev->keybit[BIT_WORD(BTN_0)] |= BIT_MASK(BTN_1) | - BIT_MASK(BTN_8); + input_dev->keybit[LONG(BTN_0)] |= BIT(BTN_1) | BIT(BTN_8); } for (i = 0; i < 3; i++) { diff --git a/trunk/drivers/input/joystick/spaceorb.c b/trunk/drivers/input/joystick/spaceorb.c index f7ce4004f4ba..c4937f1e837c 100644 --- a/trunk/drivers/input/joystick/spaceorb.c +++ b/trunk/drivers/input/joystick/spaceorb.c @@ -185,7 +185,7 @@ static int spaceorb_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.version = 0x0100; input_dev->dev.parent = &serio->dev; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); for (i = 0; i < 6; i++) set_bit(spaceorb_buttons[i], input_dev->keybit); diff --git a/trunk/drivers/input/joystick/stinger.c b/trunk/drivers/input/joystick/stinger.c index baa10b2f7ba1..8581ee991d4e 100644 --- a/trunk/drivers/input/joystick/stinger.c +++ b/trunk/drivers/input/joystick/stinger.c @@ -156,11 +156,10 @@ static int stinger_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.version = 0x0100; input_dev->dev.parent = &serio->dev; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); - input_dev->keybit[BIT_WORD(BTN_A)] = BIT_MASK(BTN_A) | BIT_MASK(BTN_B) | - BIT_MASK(BTN_C) | BIT_MASK(BTN_X) | BIT_MASK(BTN_Y) | - BIT_MASK(BTN_Z) | BIT_MASK(BTN_TL) | BIT_MASK(BTN_TR) | - BIT_MASK(BTN_START) | BIT_MASK(BTN_SELECT); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + input_dev->keybit[LONG(BTN_A)] = BIT(BTN_A) | BIT(BTN_B) | BIT(BTN_C) | BIT(BTN_X) | + BIT(BTN_Y) | BIT(BTN_Z) | BIT(BTN_TL) | BIT(BTN_TR) | + BIT(BTN_START) | BIT(BTN_SELECT); input_set_abs_params(input_dev, ABS_X, -64, 64, 0, 4); input_set_abs_params(input_dev, ABS_Y, -64, 64, 0, 4); diff --git a/trunk/drivers/input/joystick/tmdc.c b/trunk/drivers/input/joystick/tmdc.c index 0feeb8acb532..3b36ee04f726 100644 --- a/trunk/drivers/input/joystick/tmdc.c +++ b/trunk/drivers/input/joystick/tmdc.c @@ -333,7 +333,7 @@ static int tmdc_setup_port(struct tmdc *tmdc, int idx, unsigned char *data) input_dev->open = tmdc_open; input_dev->close = tmdc_close; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); for (i = 0; i < port->absc && i < TMDC_ABS; i++) if (port->abs[i] >= 0) diff --git a/trunk/drivers/input/joystick/turbografx.c b/trunk/drivers/input/joystick/turbografx.c index bbebd4e2ad7f..8381c6f14373 100644 --- a/trunk/drivers/input/joystick/turbografx.c +++ b/trunk/drivers/input/joystick/turbografx.c @@ -229,7 +229,7 @@ static struct tgfx __init *tgfx_probe(int parport, int *n_buttons, int n_devs) input_dev->open = tgfx_open; input_dev->close = tgfx_close; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); input_set_abs_params(input_dev, ABS_X, -1, 1, 0, 0); input_set_abs_params(input_dev, ABS_Y, -1, 1, 0, 0); diff --git a/trunk/drivers/input/joystick/twidjoy.c b/trunk/drivers/input/joystick/twidjoy.c index 1085c841fec4..c91504ec38eb 100644 --- a/trunk/drivers/input/joystick/twidjoy.c +++ b/trunk/drivers/input/joystick/twidjoy.c @@ -207,7 +207,7 @@ static int twidjoy_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.version = 0x0100; input_dev->dev.parent = &serio->dev; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); input_set_abs_params(input_dev, ABS_X, -50, 50, 4, 4); input_set_abs_params(input_dev, ABS_Y, -50, 50, 4, 4); diff --git a/trunk/drivers/input/joystick/warrior.c b/trunk/drivers/input/joystick/warrior.c index e928b6e3724a..4e85f72eefd7 100644 --- a/trunk/drivers/input/joystick/warrior.c +++ b/trunk/drivers/input/joystick/warrior.c @@ -162,11 +162,9 @@ static int warrior_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.version = 0x0100; input_dev->dev.parent = &serio->dev; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL) | - BIT_MASK(EV_ABS); - input_dev->keybit[BIT_WORD(BTN_TRIGGER)] = BIT_MASK(BTN_TRIGGER) | - BIT_MASK(BTN_THUMB) | BIT_MASK(BTN_TOP) | BIT_MASK(BTN_TOP2); - input_dev->relbit[0] = BIT_MASK(REL_DIAL); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_ABS); + input_dev->keybit[LONG(BTN_TRIGGER)] = BIT(BTN_TRIGGER) | BIT(BTN_THUMB) | BIT(BTN_TOP) | BIT(BTN_TOP2); + input_dev->relbit[0] = BIT(REL_DIAL); input_set_abs_params(input_dev, ABS_X, -64, 64, 0, 8); input_set_abs_params(input_dev, ABS_Y, -64, 64, 0, 8); input_set_abs_params(input_dev, ABS_THROTTLE, -112, 112, 0, 0); diff --git a/trunk/drivers/input/joystick/xpad.c b/trunk/drivers/input/joystick/xpad.c index 6dd375825a14..623629a69b03 100644 --- a/trunk/drivers/input/joystick/xpad.c +++ b/trunk/drivers/input/joystick/xpad.c @@ -658,7 +658,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id input_dev->open = xpad_open; input_dev->close = xpad_close; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); /* set up buttons */ for (i = 0; xpad_btn[i] >= 0; i++) diff --git a/trunk/drivers/input/keyboard/aaed2000_kbd.c b/trunk/drivers/input/keyboard/aaed2000_kbd.c index 72abc196ce66..63d6ead6b877 100644 --- a/trunk/drivers/input/keyboard/aaed2000_kbd.c +++ b/trunk/drivers/input/keyboard/aaed2000_kbd.c @@ -125,7 +125,7 @@ static int __devinit aaedkbd_probe(struct platform_device *pdev) input_dev->id.version = 0x0100; input_dev->dev.parent = &pdev->dev; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); input_dev->keycode = aaedkbd->keycode; input_dev->keycodesize = sizeof(unsigned char); input_dev->keycodemax = ARRAY_SIZE(aaedkbd_keycode); diff --git a/trunk/drivers/input/keyboard/amikbd.c b/trunk/drivers/input/keyboard/amikbd.c index 81bf7562aca0..c67e84ec2d6a 100644 --- a/trunk/drivers/input/keyboard/amikbd.c +++ b/trunk/drivers/input/keyboard/amikbd.c @@ -209,7 +209,7 @@ static int __init amikbd_init(void) amikbd_dev->id.product = 0x0001; amikbd_dev->id.version = 0x0100; - amikbd_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); + amikbd_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); for (i = 0; i < 0x78; i++) set_bit(i, amikbd_dev->keybit); diff --git a/trunk/drivers/input/keyboard/atakbd.c b/trunk/drivers/input/keyboard/atakbd.c index 4e92100c56a8..a1800151b6ce 100644 --- a/trunk/drivers/input/keyboard/atakbd.c +++ b/trunk/drivers/input/keyboard/atakbd.c @@ -237,7 +237,7 @@ static int __init atakbd_init(void) atakbd_dev->id.product = 0x0001; atakbd_dev->id.version = 0x0100; - atakbd_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); + atakbd_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); atakbd_dev->keycode = atakbd_keycode; atakbd_dev->keycodesize = sizeof(unsigned char); atakbd_dev->keycodemax = ARRAY_SIZE(atakbd_keycode); diff --git a/trunk/drivers/input/keyboard/atkbd.c b/trunk/drivers/input/keyboard/atkbd.c index b39c5b31e620..41fc3d03b6eb 100644 --- a/trunk/drivers/input/keyboard/atkbd.c +++ b/trunk/drivers/input/keyboard/atkbd.c @@ -900,32 +900,27 @@ static void atkbd_set_device_attrs(struct atkbd *atkbd) input_set_drvdata(input_dev, atkbd); - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) | - BIT_MASK(EV_MSC); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_MSC); if (atkbd->write) { - input_dev->evbit[0] |= BIT_MASK(EV_LED); - input_dev->ledbit[0] = BIT_MASK(LED_NUML) | - BIT_MASK(LED_CAPSL) | BIT_MASK(LED_SCROLLL); + input_dev->evbit[0] |= BIT(EV_LED); + input_dev->ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL); } if (atkbd->extra) - input_dev->ledbit[0] |= BIT_MASK(LED_COMPOSE) | - BIT_MASK(LED_SUSPEND) | BIT_MASK(LED_SLEEP) | - BIT_MASK(LED_MUTE) | BIT_MASK(LED_MISC); + input_dev->ledbit[0] |= BIT(LED_COMPOSE) | BIT(LED_SUSPEND) | + BIT(LED_SLEEP) | BIT(LED_MUTE) | BIT(LED_MISC); if (!atkbd->softrepeat) { input_dev->rep[REP_DELAY] = 250; input_dev->rep[REP_PERIOD] = 33; } - input_dev->mscbit[0] = atkbd->softraw ? BIT_MASK(MSC_SCAN) : - BIT_MASK(MSC_RAW) | BIT_MASK(MSC_SCAN); + input_dev->mscbit[0] = atkbd->softraw ? BIT(MSC_SCAN) : BIT(MSC_RAW) | BIT(MSC_SCAN); if (atkbd->scroll) { - input_dev->evbit[0] |= BIT_MASK(EV_REL); - input_dev->relbit[0] = BIT_MASK(REL_WHEEL) | - BIT_MASK(REL_HWHEEL); + input_dev->evbit[0] |= BIT(EV_REL); + input_dev->relbit[0] = BIT(REL_WHEEL) | BIT(REL_HWHEEL); set_bit(BTN_MIDDLE, input_dev->keybit); } diff --git a/trunk/drivers/input/keyboard/corgikbd.c b/trunk/drivers/input/keyboard/corgikbd.c index 790fed368aae..6578bfff644b 100644 --- a/trunk/drivers/input/keyboard/corgikbd.c +++ b/trunk/drivers/input/keyboard/corgikbd.c @@ -325,8 +325,7 @@ static int __init corgikbd_probe(struct platform_device *pdev) input_dev->id.version = 0x0100; input_dev->dev.parent = &pdev->dev; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) | - BIT_MASK(EV_PWR) | BIT_MASK(EV_SW); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_PWR) | BIT(EV_SW); input_dev->keycode = corgikbd->keycode; input_dev->keycodesize = sizeof(unsigned char); input_dev->keycodemax = ARRAY_SIZE(corgikbd_keycode); diff --git a/trunk/drivers/input/keyboard/gpio_keys.c b/trunk/drivers/input/keyboard/gpio_keys.c index 3eddf52a0bba..e2a3293bc67e 100644 --- a/trunk/drivers/input/keyboard/gpio_keys.c +++ b/trunk/drivers/input/keyboard/gpio_keys.c @@ -62,7 +62,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) platform_set_drvdata(pdev, input); - input->evbit[0] = BIT_MASK(EV_KEY); + input->evbit[0] = BIT(EV_KEY); input->name = pdev->name; input->phys = "gpio-keys/input0"; diff --git a/trunk/drivers/input/keyboard/hil_kbd.c b/trunk/drivers/input/keyboard/hil_kbd.c index adbf29f0169d..cdd254f2e6c7 100644 --- a/trunk/drivers/input/keyboard/hil_kbd.c +++ b/trunk/drivers/input/keyboard/hil_kbd.c @@ -323,9 +323,8 @@ static int hil_kbd_connect(struct serio *serio, struct serio_driver *drv) goto bail2; } - kbd->dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); - kbd->dev->ledbit[0] = BIT_MASK(LED_NUML) | BIT_MASK(LED_CAPSL) | - BIT_MASK(LED_SCROLLL); + kbd->dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); + kbd->dev->ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL); kbd->dev->keycodemax = HIL_KEYCODES_SET1_TBLSIZE; kbd->dev->keycodesize = sizeof(hil_kbd_set1[0]); kbd->dev->keycode = hil_kbd_set1; diff --git a/trunk/drivers/input/keyboard/hilkbd.c b/trunk/drivers/input/keyboard/hilkbd.c index 50d80ecf0b80..499b6974457f 100644 --- a/trunk/drivers/input/keyboard/hilkbd.c +++ b/trunk/drivers/input/keyboard/hilkbd.c @@ -266,9 +266,8 @@ hil_keyb_init(void) if (hphilkeyb_keycode[i] != KEY_RESERVED) set_bit(hphilkeyb_keycode[i], hil_dev.dev->keybit); - hil_dev.dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); - hil_dev.dev->ledbit[0] = BIT_MASK(LED_NUML) | BIT_MASK(LED_CAPSL) | - BIT_MASK(LED_SCROLLL); + hil_dev.dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); + hil_dev.dev->ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL); hil_dev.dev->keycodemax = HIL_KEYCODES_SET1_TBLSIZE; hil_dev.dev->keycodesize= sizeof(hphilkeyb_keycode[0]); hil_dev.dev->keycode = hphilkeyb_keycode; diff --git a/trunk/drivers/input/keyboard/locomokbd.c b/trunk/drivers/input/keyboard/locomokbd.c index 5a0ca18d6755..7a41b271f222 100644 --- a/trunk/drivers/input/keyboard/locomokbd.c +++ b/trunk/drivers/input/keyboard/locomokbd.c @@ -233,7 +233,7 @@ static int locomokbd_probe(struct locomo_dev *dev) input_dev->id.version = 0x0100; input_dev->dev.parent = &dev->dev; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); input_dev->keycode = locomokbd->keycode; input_dev->keycodesize = sizeof(unsigned char); input_dev->keycodemax = ARRAY_SIZE(locomokbd_keycode); diff --git a/trunk/drivers/input/keyboard/newtonkbd.c b/trunk/drivers/input/keyboard/newtonkbd.c index 48d1cab0aa1c..b97a41e3ee56 100644 --- a/trunk/drivers/input/keyboard/newtonkbd.c +++ b/trunk/drivers/input/keyboard/newtonkbd.c @@ -106,7 +106,7 @@ static int nkbd_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.version = 0x0100; input_dev->dev.parent = &serio->dev; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); input_dev->keycode = nkbd->keycode; input_dev->keycodesize = sizeof(unsigned char); input_dev->keycodemax = ARRAY_SIZE(nkbd_keycode); diff --git a/trunk/drivers/input/keyboard/pxa27x_keyboard.c b/trunk/drivers/input/keyboard/pxa27x_keyboard.c index bdd64ee4c5c8..b7061aa38816 100644 --- a/trunk/drivers/input/keyboard/pxa27x_keyboard.c +++ b/trunk/drivers/input/keyboard/pxa27x_keyboard.c @@ -183,9 +183,8 @@ static int __devinit pxakbd_probe(struct platform_device *pdev) input_dev->close = pxakbd_close; input_dev->dev.parent = &pdev->dev; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) | - BIT_MASK(EV_REL); - input_dev->relbit[BIT_WORD(REL_WHEEL)] = BIT_MASK(REL_WHEEL); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_REL); + input_dev->relbit[LONG(REL_WHEEL)] = BIT(REL_WHEEL); for (row = 0; row < pdata->nr_rows; row++) { for (col = 0; col < pdata->nr_cols; col++) { int code = pdata->keycodes[row][col]; diff --git a/trunk/drivers/input/keyboard/spitzkbd.c b/trunk/drivers/input/keyboard/spitzkbd.c index 410d78a774d0..41b80385476c 100644 --- a/trunk/drivers/input/keyboard/spitzkbd.c +++ b/trunk/drivers/input/keyboard/spitzkbd.c @@ -381,8 +381,7 @@ static int __init spitzkbd_probe(struct platform_device *dev) input_dev->id.product = 0x0001; input_dev->id.version = 0x0100; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) | - BIT_MASK(EV_PWR) | BIT_MASK(EV_SW); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_PWR) | BIT(EV_SW); input_dev->keycode = spitzkbd->keycode; input_dev->keycodesize = sizeof(unsigned char); input_dev->keycodemax = ARRAY_SIZE(spitzkbd_keycode); diff --git a/trunk/drivers/input/keyboard/stowaway.c b/trunk/drivers/input/keyboard/stowaway.c index 7437219370b1..b44b0684d543 100644 --- a/trunk/drivers/input/keyboard/stowaway.c +++ b/trunk/drivers/input/keyboard/stowaway.c @@ -110,7 +110,7 @@ static int skbd_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.version = 0x0100; input_dev->dev.parent = &serio->dev; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); input_dev->keycode = skbd->keycode; input_dev->keycodesize = sizeof(unsigned char); input_dev->keycodemax = ARRAY_SIZE(skbd_keycode); diff --git a/trunk/drivers/input/keyboard/sunkbd.c b/trunk/drivers/input/keyboard/sunkbd.c index be0f5d19d023..1d4e39624cfe 100644 --- a/trunk/drivers/input/keyboard/sunkbd.c +++ b/trunk/drivers/input/keyboard/sunkbd.c @@ -277,11 +277,9 @@ static int sunkbd_connect(struct serio *serio, struct serio_driver *drv) input_dev->event = sunkbd_event; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_LED) | - BIT_MASK(EV_SND) | BIT_MASK(EV_REP); - input_dev->ledbit[0] = BIT_MASK(LED_CAPSL) | BIT_MASK(LED_COMPOSE) | - BIT_MASK(LED_SCROLLL) | BIT_MASK(LED_NUML); - input_dev->sndbit[0] = BIT_MASK(SND_CLICK) | BIT_MASK(SND_BELL); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_SND) | BIT(EV_REP); + input_dev->ledbit[0] = BIT(LED_CAPSL) | BIT(LED_COMPOSE) | BIT(LED_SCROLLL) | BIT(LED_NUML); + input_dev->sndbit[0] = BIT(SND_CLICK) | BIT(SND_BELL); input_dev->keycode = sunkbd->keycode; input_dev->keycodesize = sizeof(unsigned char); diff --git a/trunk/drivers/input/keyboard/xtkbd.c b/trunk/drivers/input/keyboard/xtkbd.c index 152a2c070508..f3a56eb58ed1 100644 --- a/trunk/drivers/input/keyboard/xtkbd.c +++ b/trunk/drivers/input/keyboard/xtkbd.c @@ -110,7 +110,7 @@ static int xtkbd_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.version = 0x0100; input_dev->dev.parent = &serio->dev; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); input_dev->keycode = xtkbd->keycode; input_dev->keycodesize = sizeof(unsigned char); input_dev->keycodemax = ARRAY_SIZE(xtkbd_keycode); diff --git a/trunk/drivers/input/misc/ati_remote.c b/trunk/drivers/input/misc/ati_remote.c index 3a7937481ad8..471aab206443 100644 --- a/trunk/drivers/input/misc/ati_remote.c +++ b/trunk/drivers/input/misc/ati_remote.c @@ -662,10 +662,10 @@ static void ati_remote_input_init(struct ati_remote *ati_remote) struct input_dev *idev = ati_remote->idev; int i; - idev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); - idev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) | - BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_SIDE) | BIT_MASK(BTN_EXTRA); - idev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); + idev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); + idev->keybit[LONG(BTN_MOUSE)] = ( BIT(BTN_LEFT) | BIT(BTN_RIGHT) | + BIT(BTN_SIDE) | BIT(BTN_EXTRA) ); + idev->relbit[0] = BIT(REL_X) | BIT(REL_Y); for (i = 0; ati_remote_tbl[i].kind != KIND_END; i++) if (ati_remote_tbl[i].type == EV_KEY) set_bit(ati_remote_tbl[i].code, idev->keybit); diff --git a/trunk/drivers/input/misc/ati_remote2.c b/trunk/drivers/input/misc/ati_remote2.c index f2709b82485c..1031543e5c3f 100644 --- a/trunk/drivers/input/misc/ati_remote2.c +++ b/trunk/drivers/input/misc/ati_remote2.c @@ -346,10 +346,9 @@ static int ati_remote2_input_init(struct ati_remote2 *ar2) ar2->idev = idev; input_set_drvdata(idev, ar2); - idev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) | BIT_MASK(EV_REL); - idev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) | - BIT_MASK(BTN_RIGHT); - idev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); + idev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_REL); + idev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT); + idev->relbit[0] = BIT(REL_X) | BIT(REL_Y); for (i = 0; ati_remote2_key_table[i].key_code != KEY_RESERVED; i++) set_bit(ati_remote2_key_table[i].key_code, idev->keybit); diff --git a/trunk/drivers/input/misc/atlas_btns.c b/trunk/drivers/input/misc/atlas_btns.c index 4e3ad657ed80..e43e92fd9e23 100644 --- a/trunk/drivers/input/misc/atlas_btns.c +++ b/trunk/drivers/input/misc/atlas_btns.c @@ -81,7 +81,7 @@ static int atlas_acpi_button_add(struct acpi_device *device) input_dev->name = "Atlas ACPI button driver"; input_dev->phys = "ASIM0000/atlas/input0"; input_dev->id.bustype = BUS_HOST; - input_dev->evbit[BIT_WORD(EV_KEY)] = BIT_MASK(EV_KEY); + input_dev->evbit[LONG(EV_KEY)] = BIT(EV_KEY); set_bit(KEY_F1, input_dev->keybit); set_bit(KEY_F2, input_dev->keybit); diff --git a/trunk/drivers/input/misc/cobalt_btns.c b/trunk/drivers/input/misc/cobalt_btns.c index 1aef97ed5e84..064b07936019 100644 --- a/trunk/drivers/input/misc/cobalt_btns.c +++ b/trunk/drivers/input/misc/cobalt_btns.c @@ -104,7 +104,7 @@ static int __devinit cobalt_buttons_probe(struct platform_device *pdev) input->id.bustype = BUS_HOST; input->cdev.dev = &pdev->dev; - input->evbit[0] = BIT_MASK(EV_KEY); + input->evbit[0] = BIT(EV_KEY); for (i = 0; i < ARRAY_SIZE(buttons_map); i++) { set_bit(buttons_map[i].keycode, input->keybit); buttons_map[i].count = 0; diff --git a/trunk/drivers/input/misc/ixp4xx-beeper.c b/trunk/drivers/input/misc/ixp4xx-beeper.c index d2ade7443b7d..e759944041ab 100644 --- a/trunk/drivers/input/misc/ixp4xx-beeper.c +++ b/trunk/drivers/input/misc/ixp4xx-beeper.c @@ -109,8 +109,8 @@ static int __devinit ixp4xx_spkr_probe(struct platform_device *dev) input_dev->id.version = 0x0100; input_dev->dev.parent = &dev->dev; - input_dev->evbit[0] = BIT_MASK(EV_SND); - input_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE); + input_dev->evbit[0] = BIT(EV_SND); + input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); input_dev->event = ixp4xx_spkr_event; err = request_irq(IRQ_IXP4XX_TIMER2, &ixp4xx_spkr_interrupt, diff --git a/trunk/drivers/input/misc/keyspan_remote.c b/trunk/drivers/input/misc/keyspan_remote.c index fd74347047dd..1bffc9fa98c2 100644 --- a/trunk/drivers/input/misc/keyspan_remote.c +++ b/trunk/drivers/input/misc/keyspan_remote.c @@ -497,7 +497,7 @@ static int keyspan_probe(struct usb_interface *interface, const struct usb_devic usb_to_input_id(udev, &input_dev->id); input_dev->dev.parent = &interface->dev; - input_dev->evbit[0] = BIT_MASK(EV_KEY); /* We will only report KEY events. */ + input_dev->evbit[0] = BIT(EV_KEY); /* We will only report KEY events. */ for (i = 0; i < ARRAY_SIZE(keyspan_key_table); i++) if (keyspan_key_table[i] != KEY_RESERVED) set_bit(keyspan_key_table[i], input_dev->keybit); diff --git a/trunk/drivers/input/misc/m68kspkr.c b/trunk/drivers/input/misc/m68kspkr.c index 0c64d9bb718e..e9f26e766b4d 100644 --- a/trunk/drivers/input/misc/m68kspkr.c +++ b/trunk/drivers/input/misc/m68kspkr.c @@ -65,8 +65,8 @@ static int __devinit m68kspkr_probe(struct platform_device *dev) input_dev->id.version = 0x0100; input_dev->dev.parent = &dev->dev; - input_dev->evbit[0] = BIT_MASK(EV_SND); - input_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE); + input_dev->evbit[0] = BIT(EV_SND); + input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); input_dev->event = m68kspkr_event; err = input_register_device(input_dev); diff --git a/trunk/drivers/input/misc/pcspkr.c b/trunk/drivers/input/misc/pcspkr.c index 4941a9e61e90..c19f77fbaf2a 100644 --- a/trunk/drivers/input/misc/pcspkr.c +++ b/trunk/drivers/input/misc/pcspkr.c @@ -86,8 +86,8 @@ static int __devinit pcspkr_probe(struct platform_device *dev) pcspkr_dev->id.version = 0x0100; pcspkr_dev->dev.parent = &dev->dev; - pcspkr_dev->evbit[0] = BIT_MASK(EV_SND); - pcspkr_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE); + pcspkr_dev->evbit[0] = BIT(EV_SND); + pcspkr_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); pcspkr_dev->event = pcspkr_event; err = input_register_device(pcspkr_dev); diff --git a/trunk/drivers/input/misc/powermate.c b/trunk/drivers/input/misc/powermate.c index 7a7b8c7b9633..448a470d28f2 100644 --- a/trunk/drivers/input/misc/powermate.c +++ b/trunk/drivers/input/misc/powermate.c @@ -363,11 +363,10 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i input_dev->event = powermate_input_event; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL) | - BIT_MASK(EV_MSC); - input_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0); - input_dev->relbit[BIT_WORD(REL_DIAL)] = BIT_MASK(REL_DIAL); - input_dev->mscbit[BIT_WORD(MSC_PULSELED)] = BIT_MASK(MSC_PULSELED); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_MSC); + input_dev->keybit[LONG(BTN_0)] = BIT(BTN_0); + input_dev->relbit[LONG(REL_DIAL)] = BIT(REL_DIAL); + input_dev->mscbit[LONG(MSC_PULSELED)] = BIT(MSC_PULSELED); /* get a handle to the interrupt data pipe */ pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress); diff --git a/trunk/drivers/input/misc/sparcspkr.c b/trunk/drivers/input/misc/sparcspkr.c index a3637d870880..e36ec1d92be8 100644 --- a/trunk/drivers/input/misc/sparcspkr.c +++ b/trunk/drivers/input/misc/sparcspkr.c @@ -115,8 +115,8 @@ static int __devinit sparcspkr_probe(struct device *dev) input_dev->id.version = 0x0100; input_dev->dev.parent = dev; - input_dev->evbit[0] = BIT_MASK(EV_SND); - input_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE); + input_dev->evbit[0] = BIT(EV_SND); + input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); input_dev->event = state->event; diff --git a/trunk/drivers/input/misc/yealink.c b/trunk/drivers/input/misc/yealink.c index 46279ef2b649..ab15880fd566 100644 --- a/trunk/drivers/input/misc/yealink.c +++ b/trunk/drivers/input/misc/yealink.c @@ -945,7 +945,7 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id) /* input_dev->event = input_ev; TODO */ /* register available key events */ - input_dev->evbit[0] = BIT_MASK(EV_KEY); + input_dev->evbit[0] = BIT(EV_KEY); for (i = 0; i < 256; i++) { int k = map_p1k_to_key(i); if (k >= 0) { diff --git a/trunk/drivers/input/mouse/alps.c b/trunk/drivers/input/mouse/alps.c index 2b5ed119c9a9..64d70a9b714c 100644 --- a/trunk/drivers/input/mouse/alps.c +++ b/trunk/drivers/input/mouse/alps.c @@ -455,25 +455,24 @@ int alps_init(struct psmouse *psmouse) if (alps_hw_init(psmouse, &version)) goto init_fail; - dev1->evbit[BIT_WORD(EV_KEY)] |= BIT_MASK(EV_KEY); - dev1->keybit[BIT_WORD(BTN_TOUCH)] |= BIT_MASK(BTN_TOUCH); - dev1->keybit[BIT_WORD(BTN_TOOL_FINGER)] |= BIT_MASK(BTN_TOOL_FINGER); - dev1->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_LEFT) | - BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT); + dev1->evbit[LONG(EV_KEY)] |= BIT(EV_KEY); + dev1->keybit[LONG(BTN_TOUCH)] |= BIT(BTN_TOUCH); + dev1->keybit[LONG(BTN_TOOL_FINGER)] |= BIT(BTN_TOOL_FINGER); + dev1->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); - dev1->evbit[BIT_WORD(EV_ABS)] |= BIT_MASK(EV_ABS); + dev1->evbit[LONG(EV_ABS)] |= BIT(EV_ABS); input_set_abs_params(dev1, ABS_X, 0, 1023, 0, 0); input_set_abs_params(dev1, ABS_Y, 0, 767, 0, 0); input_set_abs_params(dev1, ABS_PRESSURE, 0, 127, 0, 0); if (priv->i->flags & ALPS_WHEEL) { - dev1->evbit[BIT_WORD(EV_REL)] |= BIT_MASK(EV_REL); - dev1->relbit[BIT_WORD(REL_WHEEL)] |= BIT_MASK(REL_WHEEL); + dev1->evbit[LONG(EV_REL)] |= BIT(EV_REL); + dev1->relbit[LONG(REL_WHEEL)] |= BIT(REL_WHEEL); } if (priv->i->flags & (ALPS_FW_BK_1 | ALPS_FW_BK_2)) { - dev1->keybit[BIT_WORD(BTN_FORWARD)] |= BIT_MASK(BTN_FORWARD); - dev1->keybit[BIT_WORD(BTN_BACK)] |= BIT_MASK(BTN_BACK); + dev1->keybit[LONG(BTN_FORWARD)] |= BIT(BTN_FORWARD); + dev1->keybit[LONG(BTN_BACK)] |= BIT(BTN_BACK); } snprintf(priv->phys, sizeof(priv->phys), "%s/input1", psmouse->ps2dev.serio->phys); @@ -484,10 +483,9 @@ int alps_init(struct psmouse *psmouse) dev2->id.product = PSMOUSE_ALPS; dev2->id.version = 0x0000; - dev2->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); - dev2->relbit[BIT_WORD(REL_X)] |= BIT_MASK(REL_X) | BIT_MASK(REL_Y); - dev2->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_LEFT) | - BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT); + dev2->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); + dev2->relbit[LONG(REL_X)] |= BIT(REL_X) | BIT(REL_Y); + dev2->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); if (input_register_device(priv->dev2)) goto init_fail; diff --git a/trunk/drivers/input/mouse/amimouse.c b/trunk/drivers/input/mouse/amimouse.c index a185ac78a42c..239a0e16d91a 100644 --- a/trunk/drivers/input/mouse/amimouse.c +++ b/trunk/drivers/input/mouse/amimouse.c @@ -111,10 +111,9 @@ static int __init amimouse_init(void) amimouse_dev->id.product = 0x0002; amimouse_dev->id.version = 0x0100; - amimouse_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); - amimouse_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); - amimouse_dev->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) | - BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT); + amimouse_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); + amimouse_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y); + amimouse_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); amimouse_dev->open = amimouse_open; amimouse_dev->close = amimouse_close; diff --git a/trunk/drivers/input/mouse/atarimouse.c b/trunk/drivers/input/mouse/atarimouse.c index 98a3561d4b05..c8c7244b48a1 100644 --- a/trunk/drivers/input/mouse/atarimouse.c +++ b/trunk/drivers/input/mouse/atarimouse.c @@ -137,10 +137,9 @@ static int __init atamouse_init(void) atamouse_dev->id.product = 0x0002; atamouse_dev->id.version = 0x0100; - atamouse_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); - atamouse_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); - atamouse_dev->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) | - BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT); + atamouse_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); + atamouse_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y); + atamouse_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); atamouse_dev->open = atamouse_open; atamouse_dev->close = atamouse_close; diff --git a/trunk/drivers/input/mouse/hil_ptr.c b/trunk/drivers/input/mouse/hil_ptr.c index 27f88fbb7136..449bf4dcbbcc 100644 --- a/trunk/drivers/input/mouse/hil_ptr.c +++ b/trunk/drivers/input/mouse/hil_ptr.c @@ -298,12 +298,12 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) idd = ptr->idd + 1; txt = "unknown"; if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_REL) { - ptr->dev->evbit[0] = BIT_MASK(EV_REL); + ptr->dev->evbit[0] = BIT(EV_REL); txt = "relative"; } if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_ABS) { - ptr->dev->evbit[0] = BIT_MASK(EV_ABS); + ptr->dev->evbit[0] = BIT(EV_ABS); txt = "absolute"; } if (!ptr->dev->evbit[0]) @@ -311,7 +311,7 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) ptr->nbtn = HIL_IDD_NUM_BUTTONS(idd); if (ptr->nbtn) - ptr->dev->evbit[0] |= BIT_MASK(EV_KEY); + ptr->dev->evbit[0] |= BIT(EV_KEY); naxsets = HIL_IDD_NUM_AXSETS(*idd); ptr->naxes = HIL_IDD_NUM_AXES_PER_SET(*idd); diff --git a/trunk/drivers/input/mouse/inport.c b/trunk/drivers/input/mouse/inport.c index 655a39217432..79b624fe8994 100644 --- a/trunk/drivers/input/mouse/inport.c +++ b/trunk/drivers/input/mouse/inport.c @@ -163,10 +163,9 @@ static int __init inport_init(void) inport_dev->id.product = 0x0001; inport_dev->id.version = 0x0100; - inport_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); - inport_dev->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) | - BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT); - inport_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); + inport_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); + inport_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); + inport_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y); inport_dev->open = inport_open; inport_dev->close = inport_close; diff --git a/trunk/drivers/input/mouse/lifebook.c b/trunk/drivers/input/mouse/lifebook.c index 9ec57d80186e..d7de4c53b3d8 100644 --- a/trunk/drivers/input/mouse/lifebook.c +++ b/trunk/drivers/input/mouse/lifebook.c @@ -270,10 +270,9 @@ static int lifebook_create_relative_device(struct psmouse *psmouse) dev2->id.version = 0x0000; dev2->dev.parent = &psmouse->ps2dev.serio->dev; - dev2->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); - dev2->relbit[BIT_WORD(REL_X)] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); - dev2->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) | - BIT_MASK(BTN_RIGHT); + dev2->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); + dev2->relbit[LONG(REL_X)] = BIT(REL_X) | BIT(REL_Y); + dev2->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT); error = input_register_device(priv->dev2); if (error) @@ -296,9 +295,9 @@ int lifebook_init(struct psmouse *psmouse) if (lifebook_absolute_mode(psmouse)) return -1; - dev1->evbit[0] = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY); + dev1->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY); dev1->relbit[0] = 0; - dev1->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); + dev1->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); input_set_abs_params(dev1, ABS_X, 0, max_coord, 0, 0); input_set_abs_params(dev1, ABS_Y, 0, max_coord, 0, 0); diff --git a/trunk/drivers/input/mouse/logibm.c b/trunk/drivers/input/mouse/logibm.c index b23a4f3ea5cd..26c3b2e2ca94 100644 --- a/trunk/drivers/input/mouse/logibm.c +++ b/trunk/drivers/input/mouse/logibm.c @@ -156,10 +156,9 @@ static int __init logibm_init(void) logibm_dev->id.product = 0x0001; logibm_dev->id.version = 0x0100; - logibm_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); - logibm_dev->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) | - BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT); - logibm_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); + logibm_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); + logibm_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); + logibm_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y); logibm_dev->open = logibm_open; logibm_dev->close = logibm_close; diff --git a/trunk/drivers/input/mouse/pc110pad.c b/trunk/drivers/input/mouse/pc110pad.c index 8991ab0b4fe3..05d992e514f0 100644 --- a/trunk/drivers/input/mouse/pc110pad.c +++ b/trunk/drivers/input/mouse/pc110pad.c @@ -144,9 +144,9 @@ static int __init pc110pad_init(void) pc110pad_dev->id.product = 0x0001; pc110pad_dev->id.version = 0x0100; - pc110pad_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); - pc110pad_dev->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y); - pc110pad_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); + pc110pad_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + pc110pad_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y); + pc110pad_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); pc110pad_dev->absmax[ABS_X] = 0x1ff; pc110pad_dev->absmax[ABS_Y] = 0x0ff; diff --git a/trunk/drivers/input/mouse/psmouse-base.c b/trunk/drivers/input/mouse/psmouse-base.c index da316d13d7f5..073525756532 100644 --- a/trunk/drivers/input/mouse/psmouse-base.c +++ b/trunk/drivers/input/mouse/psmouse-base.c @@ -1115,10 +1115,9 @@ static int psmouse_switch_protocol(struct psmouse *psmouse, const struct psmouse input_dev->dev.parent = &psmouse->ps2dev.serio->dev; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); - input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) | - BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT); - input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); + input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); + input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y); psmouse->set_rate = psmouse_set_rate; psmouse->set_resolution = psmouse_set_resolution; diff --git a/trunk/drivers/input/mouse/rpcmouse.c b/trunk/drivers/input/mouse/rpcmouse.c index 18a48636ba4a..355efd0423e7 100644 --- a/trunk/drivers/input/mouse/rpcmouse.c +++ b/trunk/drivers/input/mouse/rpcmouse.c @@ -78,10 +78,9 @@ static int __init rpcmouse_init(void) rpcmouse_dev->id.product = 0x0001; rpcmouse_dev->id.version = 0x0100; - rpcmouse_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); - rpcmouse_dev->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) | - BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT); - rpcmouse_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); + rpcmouse_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); + rpcmouse_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); + rpcmouse_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y); rpcmouse_lastx = (short) iomd_readl(IOMD_MOUSEX); rpcmouse_lasty = (short) iomd_readl(IOMD_MOUSEY); diff --git a/trunk/drivers/input/mouse/sermouse.c b/trunk/drivers/input/mouse/sermouse.c index ed917bfd086a..77b8ee2b9651 100644 --- a/trunk/drivers/input/mouse/sermouse.c +++ b/trunk/drivers/input/mouse/sermouse.c @@ -268,10 +268,9 @@ static int sermouse_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.version = 0x0100; input_dev->dev.parent = &serio->dev; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); - input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) | - BIT_MASK(BTN_RIGHT); - input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); + input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT); + input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y); if (c & 0x01) set_bit(BTN_MIDDLE, input_dev->keybit); if (c & 0x02) set_bit(BTN_SIDE, input_dev->keybit); diff --git a/trunk/drivers/input/mouse/touchkit_ps2.c b/trunk/drivers/input/mouse/touchkit_ps2.c index 3fadb2accac0..7b977fd23571 100644 --- a/trunk/drivers/input/mouse/touchkit_ps2.c +++ b/trunk/drivers/input/mouse/touchkit_ps2.c @@ -85,7 +85,7 @@ int touchkit_ps2_detect(struct psmouse *psmouse, int set_properties) return -ENODEV; if (set_properties) { - dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); + dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); set_bit(BTN_TOUCH, dev->keybit); input_set_abs_params(dev, ABS_X, 0, TOUCHKIT_MAX_XC, 0, 0); input_set_abs_params(dev, ABS_Y, 0, TOUCHKIT_MAX_YC, 0, 0); diff --git a/trunk/drivers/input/mousedev.c b/trunk/drivers/input/mousedev.c index 78c3ea75da2a..79146d6ed2ab 100644 --- a/trunk/drivers/input/mousedev.c +++ b/trunk/drivers/input/mousedev.c @@ -998,36 +998,34 @@ static const struct input_device_id mousedev_ids[] = { .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT | INPUT_DEVICE_ID_MATCH_RELBIT, - .evbit = { BIT_MASK(EV_KEY) | BIT_MASK(EV_REL) }, - .keybit = { [BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) }, - .relbit = { BIT_MASK(REL_X) | BIT_MASK(REL_Y) }, + .evbit = { BIT(EV_KEY) | BIT(EV_REL) }, + .keybit = { [LONG(BTN_LEFT)] = BIT(BTN_LEFT) }, + .relbit = { BIT(REL_X) | BIT(REL_Y) }, }, /* A mouse like device, at least one button, two relative axes */ { .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_RELBIT, - .evbit = { BIT_MASK(EV_KEY) | BIT_MASK(EV_REL) }, - .relbit = { BIT_MASK(REL_WHEEL) }, + .evbit = { BIT(EV_KEY) | BIT(EV_REL) }, + .relbit = { BIT(REL_WHEEL) }, }, /* A separate scrollwheel */ { .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT | INPUT_DEVICE_ID_MATCH_ABSBIT, - .evbit = { BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) }, - .keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) }, - .absbit = { BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) }, + .evbit = { BIT(EV_KEY) | BIT(EV_ABS) }, + .keybit = { [LONG(BTN_TOUCH)] = BIT(BTN_TOUCH) }, + .absbit = { BIT(ABS_X) | BIT(ABS_Y) }, }, /* A tablet like device, at least touch detection, two absolute axes */ { .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT | INPUT_DEVICE_ID_MATCH_ABSBIT, - .evbit = { BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) }, - .keybit = { [BIT_WORD(BTN_TOOL_FINGER)] = - BIT_MASK(BTN_TOOL_FINGER) }, - .absbit = { BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) | - BIT_MASK(ABS_PRESSURE) | - BIT_MASK(ABS_TOOL_WIDTH) }, + .evbit = { BIT(EV_KEY) | BIT(EV_ABS) }, + .keybit = { [LONG(BTN_TOOL_FINGER)] = BIT(BTN_TOOL_FINGER) }, + .absbit = { BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE) | + BIT(ABS_TOOL_WIDTH) }, }, /* A touchpad */ { }, /* Terminating entry */ diff --git a/trunk/drivers/input/serio/serio.c b/trunk/drivers/input/serio/serio.c index 7f5293828fbf..b3bc15acd3f5 100644 --- a/trunk/drivers/input/serio/serio.c +++ b/trunk/drivers/input/serio/serio.c @@ -387,8 +387,9 @@ static int serio_thread(void *nothing) set_freezable(); do { serio_handle_event(); - wait_event_freezable(serio_wait, + wait_event_interruptible(serio_wait, kthread_should_stop() || !list_empty(&serio_event_list)); + try_to_freeze(); } while (!kthread_should_stop()); printk(KERN_DEBUG "serio: kseriod exiting\n"); diff --git a/trunk/drivers/input/tablet/acecad.c b/trunk/drivers/input/tablet/acecad.c index b973d0ef6d16..dd2310458c46 100644 --- a/trunk/drivers/input/tablet/acecad.c +++ b/trunk/drivers/input/tablet/acecad.c @@ -192,14 +192,10 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_ input_dev->open = usb_acecad_open; input_dev->close = usb_acecad_close; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); - input_dev->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) | - BIT_MASK(ABS_PRESSURE); - input_dev->keybit[BIT_WORD(BTN_LEFT)] = BIT_MASK(BTN_LEFT) | - BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE); - input_dev->keybit[BIT_WORD(BTN_DIGI)] = BIT_MASK(BTN_TOOL_PEN) | - BIT_MASK(BTN_TOUCH) | BIT_MASK(BTN_STYLUS) | - BIT_MASK(BTN_STYLUS2); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + input_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE); + input_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE); + input_dev->keybit[LONG(BTN_DIGI)] = BIT(BTN_TOOL_PEN) |BIT(BTN_TOUCH) | BIT(BTN_STYLUS) | BIT(BTN_STYLUS2); switch (id->driver_info) { case 0: diff --git a/trunk/drivers/input/tablet/gtco.c b/trunk/drivers/input/tablet/gtco.c index d2c6da264722..b2ca10f2fe0e 100644 --- a/trunk/drivers/input/tablet/gtco.c +++ b/trunk/drivers/input/tablet/gtco.c @@ -573,12 +573,10 @@ static void gtco_setup_caps(struct input_dev *inputdev) struct gtco *device = input_get_drvdata(inputdev); /* Which events */ - inputdev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) | - BIT_MASK(EV_MSC); + inputdev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_MSC); /* Misc event menu block */ - inputdev->mscbit[0] = BIT_MASK(MSC_SCAN) | BIT_MASK(MSC_SERIAL) | - BIT_MASK(MSC_RAW); + inputdev->mscbit[0] = BIT(MSC_SCAN)|BIT(MSC_SERIAL)|BIT(MSC_RAW) ; /* Absolute values based on HID report info */ input_set_abs_params(inputdev, ABS_X, device->min_X, device->max_X, diff --git a/trunk/drivers/input/tablet/kbtab.c b/trunk/drivers/input/tablet/kbtab.c index 1182fc133167..91e6d00d4a43 100644 --- a/trunk/drivers/input/tablet/kbtab.c +++ b/trunk/drivers/input/tablet/kbtab.c @@ -153,13 +153,10 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i input_dev->open = kbtab_open; input_dev->close = kbtab_close; - input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) | - BIT_MASK(EV_MSC); - input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_LEFT) | - BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE); - input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_PEN) | - BIT_MASK(BTN_TOUCH); - input_dev->mscbit[0] |= BIT_MASK(MSC_SERIAL); + input_dev->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_MSC); + input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE); + input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH); + input_dev->mscbit[0] |= BIT(MSC_SERIAL); input_set_abs_params(input_dev, ABS_X, 0, 0x2000, 4, 0); input_set_abs_params(input_dev, ABS_Y, 0, 0x1750, 4, 0); input_set_abs_params(input_dev, ABS_PRESSURE, 0, 0xff, 0, 0); diff --git a/trunk/drivers/input/tablet/wacom_sys.c b/trunk/drivers/input/tablet/wacom_sys.c index d64b1ea136b3..064e123c9b76 100644 --- a/trunk/drivers/input/tablet/wacom_sys.c +++ b/trunk/drivers/input/tablet/wacom_sys.c @@ -140,58 +140,48 @@ static void wacom_close(struct input_dev *dev) void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac) { - input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_1) | - BIT_MASK(BTN_5); + input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_1) | BIT(BTN_5); input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0); } void input_dev_g4(struct input_dev *input_dev, struct wacom_wac *wacom_wac) { - input_dev->evbit[0] |= BIT_MASK(EV_MSC); - input_dev->mscbit[0] |= BIT_MASK(MSC_SERIAL); - input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_FINGER); - input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_0) | - BIT_MASK(BTN_4); + input_dev->evbit[0] |= BIT(EV_MSC); + input_dev->mscbit[0] |= BIT(MSC_SERIAL); + input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); + input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_4); } void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac) { - input_dev->evbit[0] |= BIT_MASK(EV_REL); - input_dev->relbit[0] |= BIT_MASK(REL_WHEEL); - input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_LEFT) | - BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE); - input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) | - BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_STYLUS2); + input_dev->evbit[0] |= BIT(EV_REL); + input_dev->relbit[0] |= BIT(REL_WHEEL); + input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE); + input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_STYLUS2); input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0); } void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac) { - input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_FINGER); - input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_0) | - BIT_MASK(BTN_1) | BIT_MASK(BTN_2) | BIT_MASK(BTN_3); + input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); + input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3); input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0); } void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac) { - input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_4) | - BIT_MASK(BTN_5) | BIT_MASK(BTN_6) | BIT_MASK(BTN_7); + input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7); input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0); } void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac) { - input_dev->evbit[0] |= BIT_MASK(EV_MSC) | BIT_MASK(EV_REL); - input_dev->mscbit[0] |= BIT_MASK(MSC_SERIAL); - input_dev->relbit[0] |= BIT_MASK(REL_WHEEL); - input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_LEFT) | - BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE) | - BIT_MASK(BTN_SIDE) | BIT_MASK(BTN_EXTRA); - input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) | - BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_TOOL_BRUSH) | - BIT_MASK(BTN_TOOL_PENCIL) | BIT_MASK(BTN_TOOL_AIRBRUSH) | - BIT_MASK(BTN_TOOL_LENS) | BIT_MASK(BTN_STYLUS2); + input_dev->evbit[0] |= BIT(EV_MSC) | BIT(EV_REL); + input_dev->mscbit[0] |= BIT(MSC_SERIAL); + input_dev->relbit[0] |= BIT(REL_WHEEL); + input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE) | BIT(BTN_SIDE) | BIT(BTN_EXTRA); + input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_TOOL_BRUSH) + | BIT(BTN_TOOL_PENCIL) | BIT(BTN_TOOL_AIRBRUSH) | BIT(BTN_TOOL_LENS) | BIT(BTN_STYLUS2); input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom_wac->features->distance_max, 0, 0); input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0); input_set_abs_params(input_dev, ABS_TILT_X, 0, 127, 0, 0); @@ -202,13 +192,12 @@ void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac) void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac) { - input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_STYLUS2) | - BIT_MASK(BTN_TOOL_RUBBER); + input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_STYLUS2) | BIT(BTN_TOOL_RUBBER); } void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac) { - input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER); + input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER); } static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id) @@ -254,13 +243,12 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i input_dev->open = wacom_open; input_dev->close = wacom_close; - input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); - input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_PEN) | - BIT_MASK(BTN_TOUCH) | BIT_MASK(BTN_STYLUS); + input_dev->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS); + input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH) | BIT(BTN_STYLUS); input_set_abs_params(input_dev, ABS_X, 0, wacom_wac->features->x_max, 4, 0); input_set_abs_params(input_dev, ABS_Y, 0, wacom_wac->features->y_max, 4, 0); input_set_abs_params(input_dev, ABS_PRESSURE, 0, wacom_wac->features->pressure_max, 0, 0); - input_dev->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC); + input_dev->absbit[LONG(ABS_MISC)] |= BIT(ABS_MISC); wacom_init_input_dev(input_dev, wacom_wac); diff --git a/trunk/drivers/input/touchscreen/ads7846.c b/trunk/drivers/input/touchscreen/ads7846.c index f59aecf5ec15..51ae4fb7d123 100644 --- a/trunk/drivers/input/touchscreen/ads7846.c +++ b/trunk/drivers/input/touchscreen/ads7846.c @@ -917,8 +917,8 @@ static int __devinit ads7846_probe(struct spi_device *spi) input_dev->phys = ts->phys; input_dev->dev.parent = &spi->dev; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); - input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); input_set_abs_params(input_dev, ABS_X, pdata->x_min ? : 0, pdata->x_max ? : MAX_12BIT, diff --git a/trunk/drivers/input/touchscreen/corgi_ts.c b/trunk/drivers/input/touchscreen/corgi_ts.c index b1b2e07bf080..e6a31d118786 100644 --- a/trunk/drivers/input/touchscreen/corgi_ts.c +++ b/trunk/drivers/input/touchscreen/corgi_ts.c @@ -302,8 +302,8 @@ static int __init corgits_probe(struct platform_device *pdev) input_dev->id.version = 0x0100; input_dev->dev.parent = &pdev->dev; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); - input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); input_set_abs_params(input_dev, ABS_X, X_AXIS_MIN, X_AXIS_MAX, 0, 0); input_set_abs_params(input_dev, ABS_Y, Y_AXIS_MIN, Y_AXIS_MAX, 0, 0); input_set_abs_params(input_dev, ABS_PRESSURE, PRESSURE_MIN, PRESSURE_MAX, 0, 0); diff --git a/trunk/drivers/input/touchscreen/elo.c b/trunk/drivers/input/touchscreen/elo.c index d20689cdbd5d..557d781719f1 100644 --- a/trunk/drivers/input/touchscreen/elo.c +++ b/trunk/drivers/input/touchscreen/elo.c @@ -320,8 +320,8 @@ static int elo_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.version = 0x0100; input_dev->dev.parent = &serio->dev; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); - input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); serio_set_drvdata(serio, elo); err = serio_open(serio, drv); diff --git a/trunk/drivers/input/touchscreen/fujitsu_ts.c b/trunk/drivers/input/touchscreen/fujitsu_ts.c index 80b21800355f..daf7a4afc935 100644 --- a/trunk/drivers/input/touchscreen/fujitsu_ts.c +++ b/trunk/drivers/input/touchscreen/fujitsu_ts.c @@ -122,8 +122,8 @@ static int fujitsu_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.vendor = SERIO_FUJITSU; input_dev->id.product = 0; input_dev->id.version = 0x0100; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); - input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); input_set_abs_params(input_dev, ABS_X, 0, 4096, 0, 0); input_set_abs_params(input_dev, ABS_Y, 0, 4096, 0, 0); diff --git a/trunk/drivers/input/touchscreen/gunze.c b/trunk/drivers/input/touchscreen/gunze.c index a48a15868c4a..39d602600d7c 100644 --- a/trunk/drivers/input/touchscreen/gunze.c +++ b/trunk/drivers/input/touchscreen/gunze.c @@ -137,8 +137,8 @@ static int gunze_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.product = 0x0051; input_dev->id.version = 0x0100; input_dev->dev.parent = &serio->dev; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); - input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); input_set_abs_params(input_dev, ABS_X, 24, 1000, 0, 0); input_set_abs_params(input_dev, ABS_Y, 24, 1000, 0, 0); diff --git a/trunk/drivers/input/touchscreen/h3600_ts_input.c b/trunk/drivers/input/touchscreen/h3600_ts_input.c index 2ae6c6016a86..09ed7803cb8f 100644 --- a/trunk/drivers/input/touchscreen/h3600_ts_input.c +++ b/trunk/drivers/input/touchscreen/h3600_ts_input.c @@ -373,9 +373,8 @@ static int h3600ts_connect(struct serio *serio, struct serio_driver *drv) input_dev->event = h3600ts_event; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) | - BIT_MASK(EV_LED) | BIT_MASK(EV_PWR); - input_dev->ledbit[0] = BIT_MASK(LED_SLEEP); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_LED) | BIT(EV_PWR); + input_dev->ledbit[0] = BIT(LED_SLEEP); input_set_abs_params(input_dev, ABS_X, 60, 985, 0, 0); input_set_abs_params(input_dev, ABS_Y, 35, 1024, 0, 0); diff --git a/trunk/drivers/input/touchscreen/hp680_ts_input.c b/trunk/drivers/input/touchscreen/hp680_ts_input.c index c38d4e0f95c6..1a15475aedfc 100644 --- a/trunk/drivers/input/touchscreen/hp680_ts_input.c +++ b/trunk/drivers/input/touchscreen/hp680_ts_input.c @@ -81,8 +81,8 @@ static int __init hp680_ts_init(void) if (!hp680_ts_dev) return -ENOMEM; - hp680_ts_dev->evbit[0] = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY); - hp680_ts_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); + hp680_ts_dev->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY); + hp680_ts_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); input_set_abs_params(hp680_ts_dev, ABS_X, HP680_TS_ABS_X_MIN, HP680_TS_ABS_X_MAX, 0, 0); diff --git a/trunk/drivers/input/touchscreen/mk712.c b/trunk/drivers/input/touchscreen/mk712.c index 80a658868706..44140feeffc5 100644 --- a/trunk/drivers/input/touchscreen/mk712.c +++ b/trunk/drivers/input/touchscreen/mk712.c @@ -186,8 +186,8 @@ static int __init mk712_init(void) mk712_dev->open = mk712_open; mk712_dev->close = mk712_close; - mk712_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); - mk712_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); + mk712_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + mk712_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); input_set_abs_params(mk712_dev, ABS_X, 0, 0xfff, 88, 0); input_set_abs_params(mk712_dev, ABS_Y, 0, 0xfff, 88, 0); diff --git a/trunk/drivers/input/touchscreen/mtouch.c b/trunk/drivers/input/touchscreen/mtouch.c index 9077228418b7..4ec3b1f940c8 100644 --- a/trunk/drivers/input/touchscreen/mtouch.c +++ b/trunk/drivers/input/touchscreen/mtouch.c @@ -151,8 +151,8 @@ static int mtouch_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.product = 0; input_dev->id.version = 0x0100; input_dev->dev.parent = &serio->dev; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); - input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); input_set_abs_params(mtouch->dev, ABS_X, MTOUCH_MIN_XC, MTOUCH_MAX_XC, 0, 0); input_set_abs_params(mtouch->dev, ABS_Y, MTOUCH_MIN_YC, MTOUCH_MAX_YC, 0, 0); diff --git a/trunk/drivers/input/touchscreen/penmount.c b/trunk/drivers/input/touchscreen/penmount.c index c7f9cebebbb6..f2c0d3c7149c 100644 --- a/trunk/drivers/input/touchscreen/penmount.c +++ b/trunk/drivers/input/touchscreen/penmount.c @@ -113,8 +113,8 @@ static int pm_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.version = 0x0100; input_dev->dev.parent = &serio->dev; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); - input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); input_set_abs_params(pm->dev, ABS_X, 0, 0x3ff, 0, 0); input_set_abs_params(pm->dev, ABS_Y, 0, 0x3ff, 0, 0); diff --git a/trunk/drivers/input/touchscreen/touchright.c b/trunk/drivers/input/touchscreen/touchright.c index 3a5c142c2a78..3def7bb1df44 100644 --- a/trunk/drivers/input/touchscreen/touchright.c +++ b/trunk/drivers/input/touchscreen/touchright.c @@ -125,8 +125,8 @@ static int tr_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.product = 0; input_dev->id.version = 0x0100; input_dev->dev.parent = &serio->dev; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); - input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); input_set_abs_params(tr->dev, ABS_X, TR_MIN_XC, TR_MAX_XC, 0, 0); input_set_abs_params(tr->dev, ABS_Y, TR_MIN_YC, TR_MAX_YC, 0, 0); diff --git a/trunk/drivers/input/touchscreen/touchwin.c b/trunk/drivers/input/touchscreen/touchwin.c index 763a656a59f8..ac4bdcf18666 100644 --- a/trunk/drivers/input/touchscreen/touchwin.c +++ b/trunk/drivers/input/touchscreen/touchwin.c @@ -132,8 +132,8 @@ static int tw_connect(struct serio *serio, struct serio_driver *drv) input_dev->id.product = 0; input_dev->id.version = 0x0100; input_dev->dev.parent = &serio->dev; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); - input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); input_set_abs_params(tw->dev, ABS_X, TW_MIN_XC, TW_MAX_XC, 0, 0); input_set_abs_params(tw->dev, ABS_Y, TW_MIN_YC, TW_MAX_YC, 0, 0); diff --git a/trunk/drivers/input/touchscreen/ucb1400_ts.c b/trunk/drivers/input/touchscreen/ucb1400_ts.c index 7549939b9535..86aed64ec0fb 100644 --- a/trunk/drivers/input/touchscreen/ucb1400_ts.c +++ b/trunk/drivers/input/touchscreen/ucb1400_ts.c @@ -333,9 +333,10 @@ static int ucb1400_ts_thread(void *_ucb) timeout = msecs_to_jiffies(10); } - wait_event_freezable_timeout(ucb->ts_wait, + wait_event_interruptible_timeout(ucb->ts_wait, ucb->irq_pending || ucb->ts_restart || kthread_should_stop(), timeout); + try_to_freeze(); } /* Send the "pen off" if we are stopping with the pen still active */ @@ -517,7 +518,7 @@ static int ucb1400_ts_probe(struct device *dev) idev->id.product = id; idev->open = ucb1400_ts_open; idev->close = ucb1400_ts_close; - idev->evbit[0] = BIT_MASK(EV_ABS); + idev->evbit[0] = BIT(EV_ABS); ucb1400_adc_enable(ucb); x_res = ucb1400_ts_read_xres(ucb); diff --git a/trunk/drivers/input/touchscreen/usbtouchscreen.c b/trunk/drivers/input/touchscreen/usbtouchscreen.c index 5f34b78d5ddb..9fb3d5c30999 100644 --- a/trunk/drivers/input/touchscreen/usbtouchscreen.c +++ b/trunk/drivers/input/touchscreen/usbtouchscreen.c @@ -868,8 +868,8 @@ static int usbtouch_probe(struct usb_interface *intf, input_dev->open = usbtouch_open; input_dev->close = usbtouch_close; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); - input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); input_set_abs_params(input_dev, ABS_X, type->min_xc, type->max_xc, 0, 0); input_set_abs_params(input_dev, ABS_Y, type->min_yc, type->max_yc, 0, 0); if (type->max_press) diff --git a/trunk/drivers/isdn/gigaset/common.c b/trunk/drivers/isdn/gigaset/common.c index acd417197d03..6df336bdd571 100644 --- a/trunk/drivers/isdn/gigaset/common.c +++ b/trunk/drivers/isdn/gigaset/common.c @@ -534,8 +534,7 @@ int gigaset_fill_inbuf(struct inbuf_t *inbuf, const unsigned char *src, n = RBUFSIZE - tail; if (!n) { dev_err(inbuf->cs->dev, - "buffer overflow (%u bytes lost)\n", - bytesleft); + "buffer overflow (%u bytes lost)", bytesleft); break; } if (n > bytesleft) diff --git a/trunk/drivers/isdn/hardware/avm/b1.c b/trunk/drivers/isdn/hardware/avm/b1.c index 4484a6417235..7a69a18d07e2 100644 --- a/trunk/drivers/isdn/hardware/avm/b1.c +++ b/trunk/drivers/isdn/hardware/avm/b1.c @@ -321,15 +321,12 @@ void b1_reset_ctr(struct capi_ctr *ctrl) avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); avmcard *card = cinfo->card; unsigned int port = card->port; - unsigned long flags; b1_reset(port); b1_reset(port); memset(cinfo->version, 0, sizeof(cinfo->version)); - spin_lock_irqsave(&card->lock, flags); capilib_release(&cinfo->ncci_head); - spin_unlock_irqrestore(&card->lock, flags); capi_ctr_reseted(ctrl); } @@ -364,8 +361,9 @@ void b1_release_appl(struct capi_ctr *ctrl, u16 appl) unsigned int port = card->port; unsigned long flags; - spin_lock_irqsave(&card->lock, flags); capilib_release_appl(&cinfo->ncci_head, appl); + + spin_lock_irqsave(&card->lock, flags); b1_put_byte(port, SEND_RELEASE); b1_put_word(port, appl); spin_unlock_irqrestore(&card->lock, flags); @@ -382,27 +380,27 @@ u16 b1_send_message(struct capi_ctr *ctrl, struct sk_buff *skb) u8 subcmd = CAPIMSG_SUBCOMMAND(skb->data); u16 dlen, retval; - spin_lock_irqsave(&card->lock, flags); if (CAPICMD(cmd, subcmd) == CAPI_DATA_B3_REQ) { retval = capilib_data_b3_req(&cinfo->ncci_head, CAPIMSG_APPID(skb->data), CAPIMSG_NCCI(skb->data), CAPIMSG_MSGID(skb->data)); - if (retval != CAPI_NOERROR) { - spin_unlock_irqrestore(&card->lock, flags); + if (retval != CAPI_NOERROR) return retval; - } dlen = CAPIMSG_DATALEN(skb->data); + spin_lock_irqsave(&card->lock, flags); b1_put_byte(port, SEND_DATA_B3_REQ); b1_put_slice(port, skb->data, len); b1_put_slice(port, skb->data + len, dlen); + spin_unlock_irqrestore(&card->lock, flags); } else { + spin_lock_irqsave(&card->lock, flags); b1_put_byte(port, SEND_MESSAGE); b1_put_slice(port, skb->data, len); + spin_unlock_irqrestore(&card->lock, flags); } - spin_unlock_irqrestore(&card->lock, flags); dev_kfree_skb_any(skb); return CAPI_NOERROR; @@ -536,17 +534,17 @@ irqreturn_t b1_interrupt(int interrupt, void *devptr) ApplId = (unsigned) b1_get_word(card->port); MsgLen = b1_get_slice(card->port, card->msgbuf); + spin_unlock_irqrestore(&card->lock, flags); if (!(skb = alloc_skb(MsgLen, GFP_ATOMIC))) { printk(KERN_ERR "%s: incoming packet dropped\n", card->name); - spin_unlock_irqrestore(&card->lock, flags); } else { memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen); if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_CONF) capilib_data_b3_conf(&cinfo->ncci_head, ApplId, CAPIMSG_NCCI(skb->data), CAPIMSG_MSGID(skb->data)); - spin_unlock_irqrestore(&card->lock, flags); + capi_ctr_handle_message(ctrl, ApplId, skb); } break; @@ -556,17 +554,21 @@ irqreturn_t b1_interrupt(int interrupt, void *devptr) ApplId = b1_get_word(card->port); NCCI = b1_get_word(card->port); WindowSize = b1_get_word(card->port); - capilib_new_ncci(&cinfo->ncci_head, ApplId, NCCI, WindowSize); spin_unlock_irqrestore(&card->lock, flags); + + capilib_new_ncci(&cinfo->ncci_head, ApplId, NCCI, WindowSize); + break; case RECEIVE_FREE_NCCI: ApplId = b1_get_word(card->port); NCCI = b1_get_word(card->port); + spin_unlock_irqrestore(&card->lock, flags); + if (NCCI != 0xffffffff) capilib_free_ncci(&cinfo->ncci_head, ApplId, NCCI); - spin_unlock_irqrestore(&card->lock, flags); + break; case RECEIVE_START: diff --git a/trunk/drivers/isdn/hardware/avm/b1dma.c b/trunk/drivers/isdn/hardware/avm/b1dma.c index 669f6f67449c..428872b653e9 100644 --- a/trunk/drivers/isdn/hardware/avm/b1dma.c +++ b/trunk/drivers/isdn/hardware/avm/b1dma.c @@ -486,13 +486,11 @@ static void b1dma_handle_rx(avmcard *card) card->name); } else { memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen); - if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_CONF) { - spin_lock(&card->lock); + if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_CONF) capilib_data_b3_conf(&cinfo->ncci_head, ApplId, - CAPIMSG_NCCI(skb->data), - CAPIMSG_MSGID(skb->data)); - spin_unlock(&card->lock); - } + CAPIMSG_NCCI(skb->data), + CAPIMSG_MSGID(skb->data)); + capi_ctr_handle_message(ctrl, ApplId, skb); } break; @@ -502,9 +500,9 @@ static void b1dma_handle_rx(avmcard *card) ApplId = _get_word(&p); NCCI = _get_word(&p); WindowSize = _get_word(&p); - spin_lock(&card->lock); + capilib_new_ncci(&cinfo->ncci_head, ApplId, NCCI, WindowSize); - spin_unlock(&card->lock); + break; case RECEIVE_FREE_NCCI: @@ -512,11 +510,9 @@ static void b1dma_handle_rx(avmcard *card) ApplId = _get_word(&p); NCCI = _get_word(&p); - if (NCCI != 0xffffffff) { - spin_lock(&card->lock); + if (NCCI != 0xffffffff) capilib_free_ncci(&cinfo->ncci_head, ApplId, NCCI); - spin_unlock(&card->lock); - } + break; case RECEIVE_START: @@ -755,10 +751,10 @@ void b1dma_reset_ctr(struct capi_ctr *ctrl) spin_lock_irqsave(&card->lock, flags); b1dma_reset(card); + spin_unlock_irqrestore(&card->lock, flags); memset(cinfo->version, 0, sizeof(cinfo->version)); capilib_release(&cinfo->ncci_head); - spin_unlock_irqrestore(&card->lock, flags); capi_ctr_reseted(ctrl); } @@ -807,11 +803,8 @@ void b1dma_release_appl(struct capi_ctr *ctrl, u16 appl) avmcard *card = cinfo->card; struct sk_buff *skb; void *p; - unsigned long flags; - spin_lock_irqsave(&card->lock, flags); capilib_release_appl(&cinfo->ncci_head, appl); - spin_unlock_irqrestore(&card->lock, flags); skb = alloc_skb(7, GFP_ATOMIC); if (!skb) { @@ -839,13 +832,10 @@ u16 b1dma_send_message(struct capi_ctr *ctrl, struct sk_buff *skb) u16 retval = CAPI_NOERROR; if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) { - unsigned long flags; - spin_lock_irqsave(&card->lock, flags); retval = capilib_data_b3_req(&cinfo->ncci_head, CAPIMSG_APPID(skb->data), CAPIMSG_NCCI(skb->data), CAPIMSG_MSGID(skb->data)); - spin_unlock_irqrestore(&card->lock, flags); } if (retval == CAPI_NOERROR) b1dma_queue_tx(card, skb); diff --git a/trunk/drivers/isdn/hardware/avm/c4.c b/trunk/drivers/isdn/hardware/avm/c4.c index 4bbbbe688077..d58f927e766a 100644 --- a/trunk/drivers/isdn/hardware/avm/c4.c +++ b/trunk/drivers/isdn/hardware/avm/c4.c @@ -678,9 +678,7 @@ static irqreturn_t c4_handle_interrupt(avmcard *card) for (i=0; i < card->nr_controllers; i++) { avmctrl_info *cinfo = &card->ctrlinfo[i]; memset(cinfo->version, 0, sizeof(cinfo->version)); - spin_lock_irqsave(&card->lock, flags); capilib_release(&cinfo->ncci_head); - spin_unlock_irqrestore(&card->lock, flags); capi_ctr_reseted(&cinfo->capi_ctrl); } card->nlogcontr = 0; @@ -729,7 +727,6 @@ static void c4_send_init(avmcard *card) { struct sk_buff *skb; void *p; - unsigned long flags; skb = alloc_skb(15, GFP_ATOMIC); if (!skb) { @@ -747,15 +744,12 @@ static void c4_send_init(avmcard *card) skb_put(skb, (u8 *)p - (u8 *)skb->data); skb_queue_tail(&card->dma->send_queue, skb); - spin_lock_irqsave(&card->lock, flags); c4_dispatch_tx(card); - spin_unlock_irqrestore(&card->lock, flags); } static int queue_sendconfigword(avmcard *card, u32 val) { struct sk_buff *skb; - unsigned long flags; void *p; skb = alloc_skb(3+4, GFP_ATOMIC); @@ -772,9 +766,7 @@ static int queue_sendconfigword(avmcard *card, u32 val) skb_put(skb, (u8 *)p - (u8 *)skb->data); skb_queue_tail(&card->dma->send_queue, skb); - spin_lock_irqsave(&card->lock, flags); c4_dispatch_tx(card); - spin_unlock_irqrestore(&card->lock, flags); return 0; } @@ -994,9 +986,7 @@ static void c4_release_appl(struct capi_ctr *ctrl, u16 appl) struct sk_buff *skb; void *p; - spin_lock_irqsave(&card->lock, flags); capilib_release_appl(&cinfo->ncci_head, appl); - spin_unlock_irqrestore(&card->lock, flags); if (ctrl->cnr == card->cardnr) { skb = alloc_skb(7, GFP_ATOMIC); @@ -1029,8 +1019,7 @@ static u16 c4_send_message(struct capi_ctr *ctrl, struct sk_buff *skb) u16 retval = CAPI_NOERROR; unsigned long flags; - spin_lock_irqsave(&card->lock, flags); - if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) { + if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) { retval = capilib_data_b3_req(&cinfo->ncci_head, CAPIMSG_APPID(skb->data), CAPIMSG_NCCI(skb->data), @@ -1038,9 +1027,10 @@ static u16 c4_send_message(struct capi_ctr *ctrl, struct sk_buff *skb) } if (retval == CAPI_NOERROR) { skb_queue_tail(&card->dma->send_queue, skb); + spin_lock_irqsave(&card->lock, flags); c4_dispatch_tx(card); + spin_unlock_irqrestore(&card->lock, flags); } - spin_unlock_irqrestore(&card->lock, flags); return retval; } diff --git a/trunk/drivers/isdn/hardware/avm/t1isa.c b/trunk/drivers/isdn/hardware/avm/t1isa.c index 6130724e46e7..c925020fe9b7 100644 --- a/trunk/drivers/isdn/hardware/avm/t1isa.c +++ b/trunk/drivers/isdn/hardware/avm/t1isa.c @@ -180,8 +180,8 @@ static irqreturn_t t1isa_interrupt(int interrupt, void *devptr) ApplId = (unsigned) b1_get_word(card->port); MsgLen = t1_get_slice(card->port, card->msgbuf); + spin_unlock_irqrestore(&card->lock, flags); if (!(skb = alloc_skb(MsgLen, GFP_ATOMIC))) { - spin_unlock_irqrestore(&card->lock, flags); printk(KERN_ERR "%s: incoming packet dropped\n", card->name); } else { @@ -190,7 +190,7 @@ static irqreturn_t t1isa_interrupt(int interrupt, void *devptr) capilib_data_b3_conf(&cinfo->ncci_head, ApplId, CAPIMSG_NCCI(skb->data), CAPIMSG_MSGID(skb->data)); - spin_unlock_irqrestore(&card->lock, flags); + capi_ctr_handle_message(ctrl, ApplId, skb); } break; @@ -200,17 +200,21 @@ static irqreturn_t t1isa_interrupt(int interrupt, void *devptr) ApplId = b1_get_word(card->port); NCCI = b1_get_word(card->port); WindowSize = b1_get_word(card->port); - capilib_new_ncci(&cinfo->ncci_head, ApplId, NCCI, WindowSize); spin_unlock_irqrestore(&card->lock, flags); + + capilib_new_ncci(&cinfo->ncci_head, ApplId, NCCI, WindowSize); + break; case RECEIVE_FREE_NCCI: ApplId = b1_get_word(card->port); NCCI = b1_get_word(card->port); + spin_unlock_irqrestore(&card->lock, flags); + if (NCCI != 0xffffffff) capilib_free_ncci(&cinfo->ncci_head, ApplId, NCCI); - spin_unlock_irqrestore(&card->lock, flags); + break; case RECEIVE_START: @@ -329,16 +333,13 @@ static void t1isa_reset_ctr(struct capi_ctr *ctrl) avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); avmcard *card = cinfo->card; unsigned int port = card->port; - unsigned long flags; t1_disable_irq(port); b1_reset(port); b1_reset(port); memset(cinfo->version, 0, sizeof(cinfo->version)); - spin_lock_irqsave(&card->lock, flags); capilib_release(&cinfo->ncci_head); - spin_unlock_irqrestore(&card->lock, flags); capi_ctr_reseted(ctrl); } @@ -465,26 +466,29 @@ static u16 t1isa_send_message(struct capi_ctr *ctrl, struct sk_buff *skb) u8 subcmd = CAPIMSG_SUBCOMMAND(skb->data); u16 dlen, retval; - spin_lock_irqsave(&card->lock, flags); if (CAPICMD(cmd, subcmd) == CAPI_DATA_B3_REQ) { retval = capilib_data_b3_req(&cinfo->ncci_head, CAPIMSG_APPID(skb->data), CAPIMSG_NCCI(skb->data), CAPIMSG_MSGID(skb->data)); - if (retval != CAPI_NOERROR) { - spin_unlock_irqrestore(&card->lock, flags); + if (retval != CAPI_NOERROR) return retval; - } + dlen = CAPIMSG_DATALEN(skb->data); + spin_lock_irqsave(&card->lock, flags); b1_put_byte(port, SEND_DATA_B3_REQ); t1_put_slice(port, skb->data, len); t1_put_slice(port, skb->data + len, dlen); + spin_unlock_irqrestore(&card->lock, flags); } else { + + spin_lock_irqsave(&card->lock, flags); b1_put_byte(port, SEND_MESSAGE); t1_put_slice(port, skb->data, len); + spin_unlock_irqrestore(&card->lock, flags); } - spin_unlock_irqrestore(&card->lock, flags); + dev_kfree_skb_any(skb); return CAPI_NOERROR; } diff --git a/trunk/drivers/isdn/sc/debug.h b/trunk/drivers/isdn/sc/debug.h new file mode 100644 index 000000000000..e9db96ede4b2 --- /dev/null +++ b/trunk/drivers/isdn/sc/debug.h @@ -0,0 +1,19 @@ +/* $Id: debug.h,v 1.2.8.1 2001/09/23 22:24:59 kai Exp $ + * + * Copyright (C) 1996 SpellCaster Telecommunications Inc. + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * + * For more information, please contact gpl-info@spellcast.com or write: + * + * SpellCaster Telecommunications Inc. + * 5621 Finch Avenue East, Unit #3 + * Scarborough, Ontario Canada + * M1B 2T9 + * +1 (416) 297-8565 + * +1 (416) 297-6433 Facsimile + */ + +#define REQUEST_IRQ(a,b,c,d,e) request_irq(a,b,c,d,e) +#define FREE_IRQ(a,b) free_irq(a,b) diff --git a/trunk/drivers/isdn/sc/includes.h b/trunk/drivers/isdn/sc/includes.h index 4766e5b77378..5286e0c810a9 100644 --- a/trunk/drivers/isdn/sc/includes.h +++ b/trunk/drivers/isdn/sc/includes.h @@ -14,3 +14,4 @@ #include #include #include +#include "debug.h" diff --git a/trunk/drivers/isdn/sc/init.c b/trunk/drivers/isdn/sc/init.c index d09c854cfac7..0bf76344a0d5 100644 --- a/trunk/drivers/isdn/sc/init.c +++ b/trunk/drivers/isdn/sc/init.c @@ -404,7 +404,7 @@ static void __exit sc_exit(void) /* * Release the IRQ */ - free_irq(sc_adapter[i]->interrupt, NULL); + FREE_IRQ(sc_adapter[i]->interrupt, NULL); /* * Reset for a clean start diff --git a/trunk/drivers/macintosh/adbhid.c b/trunk/drivers/macintosh/adbhid.c index 883da72b5368..2766e4fc4ea8 100644 --- a/trunk/drivers/macintosh/adbhid.c +++ b/trunk/drivers/macintosh/adbhid.c @@ -791,10 +791,8 @@ adbhid_input_register(int id, int default_id, int original_handler_id, if (hid->keycode[i]) set_bit(hid->keycode[i], input_dev->keybit); - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_LED) | - BIT_MASK(EV_REP); - input_dev->ledbit[0] = BIT_MASK(LED_SCROLLL) | - BIT_MASK(LED_CAPSL) | BIT_MASK(LED_NUML); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP); + input_dev->ledbit[0] = BIT(LED_SCROLLL) | BIT(LED_CAPSL) | BIT(LED_NUML); input_dev->event = adbhid_kbd_event; input_dev->keycodemax = KEY_FN; input_dev->keycodesize = sizeof(hid->keycode[0]); @@ -803,18 +801,16 @@ adbhid_input_register(int id, int default_id, int original_handler_id, case ADB_MOUSE: sprintf(hid->name, "ADB mouse"); - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); - input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) | - BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT); - input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); + input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); + input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y); break; case ADB_MISC: switch (original_handler_id) { case 0x02: /* Adjustable keyboard button device */ sprintf(hid->name, "ADB adjustable keyboard buttons"); - input_dev->evbit[0] = BIT_MASK(EV_KEY) | - BIT_MASK(EV_REP); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); set_bit(KEY_SOUND, input_dev->keybit); set_bit(KEY_MUTE, input_dev->keybit); set_bit(KEY_VOLUMEUP, input_dev->keybit); @@ -822,8 +818,7 @@ adbhid_input_register(int id, int default_id, int original_handler_id, break; case 0x1f: /* Powerbook button device */ sprintf(hid->name, "ADB Powerbook buttons"); - input_dev->evbit[0] = BIT_MASK(EV_KEY) | - BIT_MASK(EV_REP); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); set_bit(KEY_MUTE, input_dev->keybit); set_bit(KEY_VOLUMEUP, input_dev->keybit); set_bit(KEY_VOLUMEDOWN, input_dev->keybit); diff --git a/trunk/drivers/macintosh/mac_hid.c b/trunk/drivers/macintosh/mac_hid.c index 89302309da92..33dee3a773ed 100644 --- a/trunk/drivers/macintosh/mac_hid.c +++ b/trunk/drivers/macintosh/mac_hid.c @@ -117,10 +117,9 @@ static int emumousebtn_input_register(void) emumousebtn->id.product = 0x0001; emumousebtn->id.version = 0x0100; - emumousebtn->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); - emumousebtn->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) | - BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT); - emumousebtn->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); + emumousebtn->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); + emumousebtn->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); + emumousebtn->relbit[0] = BIT(REL_X) | BIT(REL_Y); ret = input_register_device(emumousebtn); if (ret) diff --git a/trunk/drivers/md/md.c b/trunk/drivers/md/md.c index 808cd9549456..c059ae6f37e5 100644 --- a/trunk/drivers/md/md.c +++ b/trunk/drivers/md/md.c @@ -4717,7 +4717,7 @@ mdk_thread_t *md_register_thread(void (*run) (mddev_t *), mddev_t *mddev, void md_unregister_thread(mdk_thread_t *thread) { - dprintk("interrupting MD-thread pid %d\n", task_pid_nr(thread->tsk)); + dprintk("interrupting MD-thread pid %d\n", thread->tsk->pid); kthread_stop(thread->tsk); kfree(thread); diff --git a/trunk/drivers/media/dvb/cinergyT2/cinergyT2.c b/trunk/drivers/media/dvb/cinergyT2/cinergyT2.c index 154a7ce7cb82..5a12b5679556 100644 --- a/trunk/drivers/media/dvb/cinergyT2/cinergyT2.c +++ b/trunk/drivers/media/dvb/cinergyT2/cinergyT2.c @@ -820,7 +820,7 @@ static int cinergyt2_register_rc(struct cinergyt2 *cinergyt2) input_dev->name = DRIVER_NAME " remote control"; input_dev->phys = cinergyt2->phys; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); + input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); for (i = 0; i < ARRAY_SIZE(rc_keys); i += 3) set_bit(rc_keys[i + 2], input_dev->keybit); input_dev->keycodesize = 0; diff --git a/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c b/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c index 445f02665577..b203640ef1c5 100644 --- a/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/trunk/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -527,8 +527,7 @@ static int dvb_frontend_thread(void *data) up(&fepriv->sem); /* is locked when we enter the thread... */ restart: timeout = wait_event_interruptible_timeout(fepriv->wait_queue, - dvb_frontend_should_wakeup(fe) || kthread_should_stop() - || freezing(current), + dvb_frontend_should_wakeup(fe) || kthread_should_stop(), fepriv->delay); if (kthread_should_stop() || dvb_frontend_is_exiting(fe)) { diff --git a/trunk/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/trunk/drivers/media/dvb/dvb-usb/dvb-usb-remote.c index c0c2c22ddd83..7b9f35bfb4f0 100644 --- a/trunk/drivers/media/dvb/dvb-usb/dvb-usb-remote.c +++ b/trunk/drivers/media/dvb/dvb-usb/dvb-usb-remote.c @@ -106,7 +106,7 @@ int dvb_usb_remote_init(struct dvb_usb_device *d) if (!input_dev) return -ENOMEM; - input_dev->evbit[0] = BIT_MASK(EV_KEY); + input_dev->evbit[0] = BIT(EV_KEY); input_dev->name = "IR-receiver inside an USB DVB receiver"; input_dev->phys = d->rc_phys; usb_to_input_id(d->udev, &input_dev->id); diff --git a/trunk/drivers/media/dvb/ttpci/av7110_ir.c b/trunk/drivers/media/dvb/ttpci/av7110_ir.c index a283e1de83fa..5d19c402dad1 100644 --- a/trunk/drivers/media/dvb/ttpci/av7110_ir.c +++ b/trunk/drivers/media/dvb/ttpci/av7110_ir.c @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include "av7110.h" #include "av7110_hw.h" diff --git a/trunk/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/trunk/drivers/media/dvb/ttusb-dec/ttusb_dec.c index 1ec981d98b91..5e691fd79904 100644 --- a/trunk/drivers/media/dvb/ttusb-dec/ttusb_dec.c +++ b/trunk/drivers/media/dvb/ttusb-dec/ttusb_dec.c @@ -1198,7 +1198,7 @@ static int ttusb_init_rc( struct ttusb_dec *dec) input_dev->name = "ttusb_dec remote control"; input_dev->phys = dec->rc_phys; - input_dev->evbit[0] = BIT_MASK(EV_KEY); + input_dev->evbit[0] = BIT(EV_KEY); input_dev->keycodesize = sizeof(u16); input_dev->keycodemax = 0x1a; input_dev->keycode = rc_keys; diff --git a/trunk/drivers/media/video/usbvideo/konicawc.c b/trunk/drivers/media/video/usbvideo/konicawc.c index 3e93f8058770..491505d6fdee 100644 --- a/trunk/drivers/media/video/usbvideo/konicawc.c +++ b/trunk/drivers/media/video/usbvideo/konicawc.c @@ -238,8 +238,8 @@ static void konicawc_register_input(struct konicawc *cam, struct usb_device *dev usb_to_input_id(dev, &input_dev->id); input_dev->dev.parent = &dev->dev; - input_dev->evbit[0] = BIT_MASK(EV_KEY); - input_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0); + input_dev->evbit[0] = BIT(EV_KEY); + input_dev->keybit[LONG(BTN_0)] = BIT(BTN_0); input_dev->private = cam; diff --git a/trunk/drivers/media/video/usbvideo/quickcam_messenger.c b/trunk/drivers/media/video/usbvideo/quickcam_messenger.c index d847273eeba0..dd1a6d6bbc9e 100644 --- a/trunk/drivers/media/video/usbvideo/quickcam_messenger.c +++ b/trunk/drivers/media/video/usbvideo/quickcam_messenger.c @@ -102,8 +102,8 @@ static void qcm_register_input(struct qcm *cam, struct usb_device *dev) usb_to_input_id(dev, &input_dev->id); input_dev->dev.parent = &dev->dev; - input_dev->evbit[0] = BIT_MASK(EV_KEY); - input_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0); + input_dev->evbit[0] = BIT(EV_KEY); + input_dev->keybit[LONG(BTN_0)] = BIT(BTN_0); input_dev->private = cam; diff --git a/trunk/drivers/media/video/v4l1-compat.c b/trunk/drivers/media/video/v4l1-compat.c index dcf22a3b672a..9eac65f34bff 100644 --- a/trunk/drivers/media/video/v4l1-compat.c +++ b/trunk/drivers/media/video/v4l1-compat.c @@ -144,7 +144,7 @@ const static unsigned int palette2pixelformat[] = { [VIDEO_PALETTE_YUV422P] = V4L2_PIX_FMT_YUV422P, }; -static unsigned int __pure +static unsigned int __attribute_pure__ palette_to_pixelformat(unsigned int palette) { if (palette < ARRAY_SIZE(palette2pixelformat)) diff --git a/trunk/drivers/media/video/zoran_driver.c b/trunk/drivers/media/video/zoran_driver.c index 419e5af78533..1c14fa2bd411 100644 --- a/trunk/drivers/media/video/zoran_driver.c +++ b/trunk/drivers/media/video/zoran_driver.c @@ -1285,7 +1285,7 @@ zoran_open (struct inode *inode, } dprintk(1, KERN_INFO "%s: zoran_open(%s, pid=[%d]), users(-)=%d\n", - ZR_DEVNAME(zr), current->comm, task_pid_nr(current), zr->user); + ZR_DEVNAME(zr), current->comm, current->pid, zr->user); /* now, create the open()-specific file_ops struct */ fh = kzalloc(sizeof(struct zoran_fh), GFP_KERNEL); @@ -1358,7 +1358,7 @@ zoran_close (struct inode *inode, struct zoran *zr = fh->zr; dprintk(1, KERN_INFO "%s: zoran_close(%s, pid=[%d]), users(+)=%d\n", - ZR_DEVNAME(zr), current->comm, task_pid_nr(current), zr->user); + ZR_DEVNAME(zr), current->comm, current->pid, zr->user); /* kernel locks (fs/device.c), so don't do that ourselves * (prevents deadlocks) */ diff --git a/trunk/drivers/misc/Kconfig b/trunk/drivers/misc/Kconfig index cf02ddc3436f..346c44eff95e 100644 --- a/trunk/drivers/misc/Kconfig +++ b/trunk/drivers/misc/Kconfig @@ -111,21 +111,6 @@ config ASUS_LAPTOP If you have an ACPI-compatible ASUS laptop, say Y or M here. -config FUJITSU_LAPTOP - tristate "Fujitsu Laptop Extras" - depends on X86 - depends on ACPI - depends on BACKLIGHT_CLASS_DEVICE - ---help--- - This is a driver for laptops built by Fujitsu: - - * P2xxx/P5xxx/S6xxx/S7xxx series Lifebooks - * Possibly other Fujitsu laptop models - - It adds support for LCD brightness control. - - If you have a Fujitsu laptop, say Y or M here. - config MSI_LAPTOP tristate "MSI Laptop Extras" depends on X86 @@ -149,7 +134,6 @@ config SONY_LAPTOP tristate "Sony Laptop Extras" depends on X86 && ACPI select BACKLIGHT_CLASS_DEVICE - depends on INPUT ---help--- This mini-driver drives the SNC and SPIC devices present in the ACPI BIOS of the Sony Vaio laptops. @@ -172,7 +156,6 @@ config THINKPAD_ACPI select BACKLIGHT_CLASS_DEVICE select HWMON select NVRAM - depends on INPUT ---help--- This is a driver for the IBM and Lenovo ThinkPad laptops. It adds support for Fn-Fx key combinations, Bluetooth control, video diff --git a/trunk/drivers/misc/Makefile b/trunk/drivers/misc/Makefile index 87f2685d728f..a24c61475c2f 100644 --- a/trunk/drivers/misc/Makefile +++ b/trunk/drivers/misc/Makefile @@ -15,5 +15,4 @@ obj-$(CONFIG_PHANTOM) += phantom.o obj-$(CONFIG_SGI_IOC4) += ioc4.o obj-$(CONFIG_SONY_LAPTOP) += sony-laptop.o obj-$(CONFIG_THINKPAD_ACPI) += thinkpad_acpi.o -obj-$(CONFIG_FUJITSU_LAPTOP) += fujitsu-laptop.o obj-$(CONFIG_EEPROM_93CX6) += eeprom_93cx6.o diff --git a/trunk/drivers/misc/fujitsu-laptop.c b/trunk/drivers/misc/fujitsu-laptop.c deleted file mode 100644 index d366a6cc1fd9..000000000000 --- a/trunk/drivers/misc/fujitsu-laptop.c +++ /dev/null @@ -1,358 +0,0 @@ -/*-*-linux-c-*-*/ - -/* - Copyright (C) 2007 Jonathan Woithe - Based on earlier work: - Copyright (C) 2003 Shane Spencer - Adrian Yee - - Templated from msi-laptop.c which is copyright by its respective authors. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. - */ - -/* - * fujitsu-laptop.c - Fujitsu laptop support, providing access to additional - * features made available on a range of Fujitsu laptops including the - * P2xxx/P5xxx/S6xxx/S7xxx series. - * - * This driver exports a few files in /sys/devices/platform/fujitsu-laptop/; - * others may be added at a later date. - * - * lcd_level - Screen brightness: contains a single integer in the - * range 0..7. (rw) - * - * In addition to these platform device attributes the driver - * registers itself in the Linux backlight control subsystem and is - * available to userspace under /sys/class/backlight/fujitsu-laptop/. - * - * This driver has been tested on a Fujitsu Lifebook S7020. It should - * work on most P-series and S-series Lifebooks, but YMMV. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#define FUJITSU_DRIVER_VERSION "0.3" - -#define FUJITSU_LCD_N_LEVELS 8 - -#define ACPI_FUJITSU_CLASS "fujitsu" -#define ACPI_FUJITSU_HID "FUJ02B1" -#define ACPI_FUJITSU_DRIVER_NAME "Fujitsu laptop FUJ02B1 ACPI extras driver" -#define ACPI_FUJITSU_DEVICE_NAME "Fujitsu FUJ02B1" - -struct fujitsu_t { - acpi_handle acpi_handle; - struct backlight_device *bl_device; - struct platform_device *pf_device; - - unsigned long fuj02b1_state; - unsigned int brightness_changed; - unsigned int brightness_level; -}; - -static struct fujitsu_t *fujitsu; - -/* Hardware access */ - -static int set_lcd_level(int level) -{ - acpi_status status = AE_OK; - union acpi_object arg0 = { ACPI_TYPE_INTEGER }; - struct acpi_object_list arg_list = { 1, &arg0 }; - acpi_handle handle = NULL; - - if (level < 0 || level >= FUJITSU_LCD_N_LEVELS) - return -EINVAL; - - if (!fujitsu) - return -EINVAL; - - status = acpi_get_handle(fujitsu->acpi_handle, "SBLL", &handle); - if (ACPI_FAILURE(status)) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "SBLL not present\n")); - return -ENODEV; - } - - arg0.integer.value = level; - - status = acpi_evaluate_object(handle, NULL, &arg_list, NULL); - if (ACPI_FAILURE(status)) - return -ENODEV; - - return 0; -} - -static int get_lcd_level(void) -{ - unsigned long state = 0; - acpi_status status = AE_OK; - - // Get the Brightness - status = - acpi_evaluate_integer(fujitsu->acpi_handle, "GBLL", NULL, &state); - if (status < 0) - return status; - - fujitsu->fuj02b1_state = state; - fujitsu->brightness_level = state & 0x0fffffff; - - if (state & 0x80000000) - fujitsu->brightness_changed = 1; - else - fujitsu->brightness_changed = 0; - - if (status < 0) - return status; - - return fujitsu->brightness_level; -} - -/* Backlight device stuff */ - -static int bl_get_brightness(struct backlight_device *b) -{ - return get_lcd_level(); -} - -static int bl_update_status(struct backlight_device *b) -{ - return set_lcd_level(b->props.brightness); -} - -static struct backlight_ops fujitsubl_ops = { - .get_brightness = bl_get_brightness, - .update_status = bl_update_status, -}; - -/* Platform device */ - -static ssize_t show_lcd_level(struct device *dev, - struct device_attribute *attr, char *buf) -{ - - int ret; - - ret = get_lcd_level(); - if (ret < 0) - return ret; - - return sprintf(buf, "%i\n", ret); -} - -static ssize_t store_lcd_level(struct device *dev, - struct device_attribute *attr, const char *buf, - size_t count) -{ - - int level, ret; - - if (sscanf(buf, "%i", &level) != 1 - || (level < 0 || level >= FUJITSU_LCD_N_LEVELS)) - return -EINVAL; - - ret = set_lcd_level(level); - if (ret < 0) - return ret; - - return count; -} - -static DEVICE_ATTR(lcd_level, 0644, show_lcd_level, store_lcd_level); - -static struct attribute *fujitsupf_attributes[] = { - &dev_attr_lcd_level.attr, - NULL -}; - -static struct attribute_group fujitsupf_attribute_group = { - .attrs = fujitsupf_attributes -}; - -static struct platform_driver fujitsupf_driver = { - .driver = { - .name = "fujitsu-laptop", - .owner = THIS_MODULE, - } -}; - -/* ACPI device */ - -int acpi_fujitsu_add(struct acpi_device *device) -{ - int result = 0; - int state = 0; - - ACPI_FUNCTION_TRACE("acpi_fujitsu_add"); - - if (!device) - return -EINVAL; - - fujitsu->acpi_handle = device->handle; - sprintf(acpi_device_name(device), "%s", ACPI_FUJITSU_DEVICE_NAME); - sprintf(acpi_device_class(device), "%s", ACPI_FUJITSU_CLASS); - acpi_driver_data(device) = fujitsu; - - result = acpi_bus_get_power(fujitsu->acpi_handle, &state); - if (result) { - ACPI_DEBUG_PRINT((ACPI_DB_ERROR, - "Error reading power state\n")); - goto end; - } - - printk(KERN_INFO PREFIX "%s [%s] (%s)\n", - acpi_device_name(device), acpi_device_bid(device), - !device->power.state ? "on" : "off"); - - end: - - return result; -} - -int acpi_fujitsu_remove(struct acpi_device *device, int type) -{ - ACPI_FUNCTION_TRACE("acpi_fujitsu_remove"); - - if (!device || !acpi_driver_data(device)) - return -EINVAL; - fujitsu->acpi_handle = 0; - - return 0; -} - -static const struct acpi_device_id fujitsu_device_ids[] = { - {ACPI_FUJITSU_HID, 0}, - {"", 0}, -}; - -static struct acpi_driver acpi_fujitsu_driver = { - .name = ACPI_FUJITSU_DRIVER_NAME, - .class = ACPI_FUJITSU_CLASS, - .ids = fujitsu_device_ids, - .ops = { - .add = acpi_fujitsu_add, - .remove = acpi_fujitsu_remove, - }, -}; - -/* Initialization */ - -static int __init fujitsu_init(void) -{ - int ret, result; - - if (acpi_disabled) - return -ENODEV; - - fujitsu = kmalloc(sizeof(struct fujitsu_t), GFP_KERNEL); - if (!fujitsu) - return -ENOMEM; - memset(fujitsu, 0, sizeof(struct fujitsu_t)); - - result = acpi_bus_register_driver(&acpi_fujitsu_driver); - if (result < 0) { - ret = -ENODEV; - goto fail_acpi; - } - - /* Register backlight stuff */ - - fujitsu->bl_device = - backlight_device_register("fujitsu-laptop", NULL, NULL, - &fujitsubl_ops); - if (IS_ERR(fujitsu->bl_device)) - return PTR_ERR(fujitsu->bl_device); - - fujitsu->bl_device->props.max_brightness = FUJITSU_LCD_N_LEVELS - 1; - ret = platform_driver_register(&fujitsupf_driver); - if (ret) - goto fail_backlight; - - /* Register platform stuff */ - - fujitsu->pf_device = platform_device_alloc("fujitsu-laptop", -1); - if (!fujitsu->pf_device) { - ret = -ENOMEM; - goto fail_platform_driver; - } - - ret = platform_device_add(fujitsu->pf_device); - if (ret) - goto fail_platform_device1; - - ret = - sysfs_create_group(&fujitsu->pf_device->dev.kobj, - &fujitsupf_attribute_group); - if (ret) - goto fail_platform_device2; - - printk(KERN_INFO "fujitsu-laptop: driver " FUJITSU_DRIVER_VERSION - " successfully loaded.\n"); - - return 0; - - fail_platform_device2: - - platform_device_del(fujitsu->pf_device); - - fail_platform_device1: - - platform_device_put(fujitsu->pf_device); - - fail_platform_driver: - - platform_driver_unregister(&fujitsupf_driver); - - fail_backlight: - - backlight_device_unregister(fujitsu->bl_device); - - fail_acpi: - - kfree(fujitsu); - - return ret; -} - -static void __exit fujitsu_cleanup(void) -{ - sysfs_remove_group(&fujitsu->pf_device->dev.kobj, - &fujitsupf_attribute_group); - platform_device_unregister(fujitsu->pf_device); - platform_driver_unregister(&fujitsupf_driver); - backlight_device_unregister(fujitsu->bl_device); - - acpi_bus_unregister_driver(&acpi_fujitsu_driver); - - kfree(fujitsu); - - printk(KERN_INFO "fujitsu-laptop: driver unloaded.\n"); -} - -module_init(fujitsu_init); -module_exit(fujitsu_cleanup); - -MODULE_AUTHOR("Jonathan Woithe"); -MODULE_DESCRIPTION("Fujitsu laptop extras support"); -MODULE_VERSION(FUJITSU_DRIVER_VERSION); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/misc/ibmasm/remote.c b/trunk/drivers/misc/ibmasm/remote.c index 1d9defb1a10c..0550ce075fc4 100644 --- a/trunk/drivers/misc/ibmasm/remote.c +++ b/trunk/drivers/misc/ibmasm/remote.c @@ -226,9 +226,9 @@ int ibmasm_init_remote_input_dev(struct service_processor *sp) mouse_dev->id.product = pdev->device; mouse_dev->id.version = 1; mouse_dev->dev.parent = sp->dev; - mouse_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); - mouse_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) | - BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE); + mouse_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + mouse_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | + BIT(BTN_RIGHT) | BIT(BTN_MIDDLE); set_bit(BTN_TOUCH, mouse_dev->keybit); mouse_dev->name = "ibmasm RSA I remote mouse"; input_set_abs_params(mouse_dev, ABS_X, 0, MOUSE_X_MAX, 0, 0); @@ -239,7 +239,7 @@ int ibmasm_init_remote_input_dev(struct service_processor *sp) keybd_dev->id.product = pdev->device; keybd_dev->id.version = 2; keybd_dev->dev.parent = sp->dev; - keybd_dev->evbit[0] = BIT_MASK(EV_KEY); + keybd_dev->evbit[0] = BIT(EV_KEY); keybd_dev->name = "ibmasm RSA I remote keyboard"; for (i = 0; i < XLATE_SIZE; i++) { diff --git a/trunk/drivers/misc/phantom.c b/trunk/drivers/misc/phantom.c index cd221fd0fb94..5108b7c576df 100644 --- a/trunk/drivers/misc/phantom.c +++ b/trunk/drivers/misc/phantom.c @@ -9,7 +9,6 @@ * You need an userspace library to cooperate with this driver. It (and other * info) may be obtained here: * http://www.fi.muni.cz/~xslaby/phantom.html - * or alternatively, you might use OpenHaptics provided by Sensable. */ #include @@ -25,14 +24,13 @@ #include #include -#define PHANTOM_VERSION "n0.9.7" +#define PHANTOM_VERSION "n0.9.5" #define PHANTOM_MAX_MINORS 8 #define PHN_IRQCTL 0x4c /* irq control in caddr space */ #define PHB_RUNNING 1 -#define PHB_NOT_OH 2 static struct class *phantom_class; static int phantom_major; @@ -49,11 +47,7 @@ struct phantom_device { struct cdev cdev; struct mutex open_lock; - spinlock_t regs_lock; - - /* used in NOT_OH mode */ - struct phm_regs oregs; - u32 ctl_reg; + spinlock_t ioctl_lock; }; static unsigned char phantom_devices[PHANTOM_MAX_MINORS]; @@ -88,7 +82,6 @@ static long phantom_ioctl(struct file *file, unsigned int cmd, struct phm_regs rs; struct phm_reg r; void __user *argp = (void __user *)arg; - unsigned long flags; unsigned int i; if (_IOC_TYPE(cmd) != PH_IOC_MAGIC || @@ -103,45 +96,32 @@ static long phantom_ioctl(struct file *file, unsigned int cmd, if (r.reg > 7) return -EINVAL; - spin_lock_irqsave(&dev->regs_lock, flags); + spin_lock(&dev->ioctl_lock); if (r.reg == PHN_CONTROL && (r.value & PHN_CTL_IRQ) && phantom_status(dev, dev->status | PHB_RUNNING)){ - spin_unlock_irqrestore(&dev->regs_lock, flags); + spin_unlock(&dev->ioctl_lock); return -ENODEV; } pr_debug("phantom: writing %x to %u\n", r.value, r.reg); - - /* preserve amp bit (don't allow to change it when in NOT_OH) */ - if (r.reg == PHN_CONTROL && (dev->status & PHB_NOT_OH)) { - r.value &= ~PHN_CTL_AMP; - r.value |= dev->ctl_reg & PHN_CTL_AMP; - dev->ctl_reg = r.value; - } - iowrite32(r.value, dev->iaddr + r.reg); ioread32(dev->iaddr); /* PCI posting */ if (r.reg == PHN_CONTROL && !(r.value & PHN_CTL_IRQ)) phantom_status(dev, dev->status & ~PHB_RUNNING); - spin_unlock_irqrestore(&dev->regs_lock, flags); + spin_unlock(&dev->ioctl_lock); break; case PHN_SET_REGS: if (copy_from_user(&rs, argp, sizeof(rs))) return -EFAULT; pr_debug("phantom: SRS %u regs %x\n", rs.count, rs.mask); - spin_lock_irqsave(&dev->regs_lock, flags); - if (dev->status & PHB_NOT_OH) - memcpy(&dev->oregs, &rs, sizeof(rs)); - else { - u32 m = min(rs.count, 8U); - for (i = 0; i < m; i++) - if (rs.mask & BIT(i)) - iowrite32(rs.values[i], dev->oaddr + i); - ioread32(dev->iaddr); /* PCI posting */ - } - spin_unlock_irqrestore(&dev->regs_lock, flags); + spin_lock(&dev->ioctl_lock); + for (i = 0; i < min(rs.count, 8U); i++) + if ((1 << i) & rs.mask) + iowrite32(rs.values[i], dev->oaddr + i); + ioread32(dev->iaddr); /* PCI posting */ + spin_unlock(&dev->ioctl_lock); break; case PHN_GET_REG: if (copy_from_user(&r, argp, sizeof(r))) @@ -155,35 +135,20 @@ static long phantom_ioctl(struct file *file, unsigned int cmd, if (copy_to_user(argp, &r, sizeof(r))) return -EFAULT; break; - case PHN_GET_REGS: { - u32 m; - + case PHN_GET_REGS: if (copy_from_user(&rs, argp, sizeof(rs))) return -EFAULT; - m = min(rs.count, 8U); - pr_debug("phantom: GRS %u regs %x\n", rs.count, rs.mask); - spin_lock_irqsave(&dev->regs_lock, flags); - for (i = 0; i < m; i++) - if (rs.mask & BIT(i)) + spin_lock(&dev->ioctl_lock); + for (i = 0; i < min(rs.count, 8U); i++) + if ((1 << i) & rs.mask) rs.values[i] = ioread32(dev->iaddr + i); - spin_unlock_irqrestore(&dev->regs_lock, flags); + spin_unlock(&dev->ioctl_lock); if (copy_to_user(argp, &rs, sizeof(rs))) return -EFAULT; break; - } case PHN_NOT_OH: - spin_lock_irqsave(&dev->regs_lock, flags); - if (dev->status & PHB_RUNNING) { - printk(KERN_ERR "phantom: you need to set NOT_OH " - "before you start the device!\n"); - spin_unlock_irqrestore(&dev->regs_lock, flags); - return -EINVAL; - } - dev->status |= PHB_NOT_OH; - spin_unlock_irqrestore(&dev->regs_lock, flags); - break; default: return -ENOTTY; } @@ -206,11 +171,8 @@ static int phantom_open(struct inode *inode, struct file *file) return -EINVAL; } - WARN_ON(dev->status & PHB_NOT_OH); - file->private_data = dev; - atomic_set(&dev->counter, 0); dev->opened++; mutex_unlock(&dev->open_lock); @@ -225,7 +187,6 @@ static int phantom_release(struct inode *inode, struct file *file) dev->opened = 0; phantom_status(dev, dev->status & ~PHB_RUNNING); - dev->status &= ~PHB_NOT_OH; mutex_unlock(&dev->open_lock); @@ -259,32 +220,12 @@ static struct file_operations phantom_file_ops = { static irqreturn_t phantom_isr(int irq, void *data) { struct phantom_device *dev = data; - unsigned int i; - u32 ctl; - spin_lock(&dev->regs_lock); - ctl = ioread32(dev->iaddr + PHN_CONTROL); - if (!(ctl & PHN_CTL_IRQ)) { - spin_unlock(&dev->regs_lock); + if (!(ioread32(dev->iaddr + PHN_CONTROL) & PHN_CTL_IRQ)) return IRQ_NONE; - } iowrite32(0, dev->iaddr); iowrite32(0xc0, dev->iaddr); - - if (dev->status & PHB_NOT_OH) { - struct phm_regs *r = &dev->oregs; - u32 m = min(r->count, 8U); - - for (i = 0; i < m; i++) - if (r->mask & BIT(i)) - iowrite32(r->values[i], dev->oaddr + i); - - dev->ctl_reg ^= PHN_CTL_AMP; - iowrite32(dev->ctl_reg, dev->iaddr + PHN_CONTROL); - } - spin_unlock(&dev->regs_lock); - ioread32(dev->iaddr); /* PCI posting */ atomic_inc(&dev->counter); @@ -356,7 +297,7 @@ static int __devinit phantom_probe(struct pci_dev *pdev, } mutex_init(&pht->open_lock); - spin_lock_init(&pht->regs_lock); + spin_lock_init(&pht->ioctl_lock); init_waitqueue_head(&pht->wait); cdev_init(&pht->cdev, &phantom_file_ops); pht->cdev.owner = THIS_MODULE; @@ -437,8 +378,6 @@ static int phantom_suspend(struct pci_dev *pdev, pm_message_t state) iowrite32(0, dev->caddr + PHN_IRQCTL); ioread32(dev->caddr + PHN_IRQCTL); /* PCI posting */ - synchronize_irq(pdev->irq); - return 0; } diff --git a/trunk/drivers/misc/sony-laptop.c b/trunk/drivers/misc/sony-laptop.c index 1bfbb87e5793..e73a71f04bb4 100644 --- a/trunk/drivers/misc/sony-laptop.c +++ b/trunk/drivers/misc/sony-laptop.c @@ -411,9 +411,9 @@ static int sony_laptop_setup_input(void) jog_dev->id.bustype = BUS_ISA; jog_dev->id.vendor = PCI_VENDOR_ID_SONY; - jog_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); - jog_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_MIDDLE); - jog_dev->relbit[0] = BIT_MASK(REL_WHEEL); + jog_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); + jog_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_MIDDLE); + jog_dev->relbit[0] = BIT(REL_WHEEL); error = input_register_device(jog_dev); if (error) @@ -1173,8 +1173,7 @@ static struct acpi_driver sony_nc_driver = { #define SONYPI_TYPE3_OFFSET 0x12 struct sony_pic_ioport { - struct acpi_resource_io io1; - struct acpi_resource_io io2; + struct acpi_resource_io io; struct list_head list; }; @@ -1444,11 +1443,11 @@ static u8 sony_pic_call1(u8 dev) { u8 v1, v2; - wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2, + wait_on_command(inb_p(spic_dev.cur_ioport->io.minimum + 4) & 2, ITERATIONS_LONG); - outb(dev, spic_dev.cur_ioport->io1.minimum + 4); - v1 = inb_p(spic_dev.cur_ioport->io1.minimum + 4); - v2 = inb_p(spic_dev.cur_ioport->io1.minimum); + outb(dev, spic_dev.cur_ioport->io.minimum + 4); + v1 = inb_p(spic_dev.cur_ioport->io.minimum + 4); + v2 = inb_p(spic_dev.cur_ioport->io.minimum); dprintk("sony_pic_call1: 0x%.4x\n", (v2 << 8) | v1); return v2; } @@ -1457,13 +1456,13 @@ static u8 sony_pic_call2(u8 dev, u8 fn) { u8 v1; - wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2, + wait_on_command(inb_p(spic_dev.cur_ioport->io.minimum + 4) & 2, ITERATIONS_LONG); - outb(dev, spic_dev.cur_ioport->io1.minimum + 4); - wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2, + outb(dev, spic_dev.cur_ioport->io.minimum + 4); + wait_on_command(inb_p(spic_dev.cur_ioport->io.minimum + 4) & 2, ITERATIONS_LONG); - outb(fn, spic_dev.cur_ioport->io1.minimum); - v1 = inb_p(spic_dev.cur_ioport->io1.minimum); + outb(fn, spic_dev.cur_ioport->io.minimum); + v1 = inb_p(spic_dev.cur_ioport->io.minimum); dprintk("sony_pic_call2: 0x%.4x\n", v1); return v1; } @@ -1472,13 +1471,13 @@ static u8 sony_pic_call3(u8 dev, u8 fn, u8 v) { u8 v1; - wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2, ITERATIONS_LONG); - outb(dev, spic_dev.cur_ioport->io1.minimum + 4); - wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2, ITERATIONS_LONG); - outb(fn, spic_dev.cur_ioport->io1.minimum); - wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2, ITERATIONS_LONG); - outb(v, spic_dev.cur_ioport->io1.minimum); - v1 = inb_p(spic_dev.cur_ioport->io1.minimum); + wait_on_command(inb_p(spic_dev.cur_ioport->io.minimum + 4) & 2, ITERATIONS_LONG); + outb(dev, spic_dev.cur_ioport->io.minimum + 4); + wait_on_command(inb_p(spic_dev.cur_ioport->io.minimum + 4) & 2, ITERATIONS_LONG); + outb(fn, spic_dev.cur_ioport->io.minimum); + wait_on_command(inb_p(spic_dev.cur_ioport->io.minimum + 4) & 2, ITERATIONS_LONG); + outb(v, spic_dev.cur_ioport->io.minimum); + v1 = inb_p(spic_dev.cur_ioport->io.minimum); dprintk("sony_pic_call3: 0x%.4x\n", v1); return v1; } @@ -2075,18 +2074,7 @@ sony_pic_read_possible_resource(struct acpi_resource *resource, void *context) switch (resource->type) { case ACPI_RESOURCE_TYPE_START_DEPENDENT: - { - /* start IO enumeration */ - struct sony_pic_ioport *ioport = kzalloc(sizeof(*ioport), GFP_KERNEL); - if (!ioport) - return AE_ERROR; - - list_add(&ioport->list, &dev->ioports); - return AE_OK; - } - case ACPI_RESOURCE_TYPE_END_DEPENDENT: - /* end IO enumeration */ return AE_OK; case ACPI_RESOURCE_TYPE_IRQ: @@ -2113,7 +2101,7 @@ sony_pic_read_possible_resource(struct acpi_resource *resource, void *context) if (!interrupt) return AE_ERROR; - list_add(&interrupt->list, &dev->interrupts); + list_add_tail(&interrupt->list, &dev->interrupts); interrupt->irq.triggering = p->triggering; interrupt->irq.polarity = p->polarity; interrupt->irq.sharable = p->sharable; @@ -2125,27 +2113,18 @@ sony_pic_read_possible_resource(struct acpi_resource *resource, void *context) case ACPI_RESOURCE_TYPE_IO: { struct acpi_resource_io *io = &resource->data.io; - struct sony_pic_ioport *ioport = - list_first_entry(&dev->ioports, struct sony_pic_ioport, list); + struct sony_pic_ioport *ioport = NULL; if (!io) { dprintk("Blank IO resource\n"); return AE_OK; } - if (!ioport->io1.minimum) { - memcpy(&ioport->io1, io, sizeof(*io)); - dprintk("IO1 at 0x%.4x (0x%.2x)\n", ioport->io1.minimum, - ioport->io1.address_length); - } - else if (!ioport->io2.minimum) { - memcpy(&ioport->io2, io, sizeof(*io)); - dprintk("IO2 at 0x%.4x (0x%.2x)\n", ioport->io2.minimum, - ioport->io2.address_length); - } - else { - printk(KERN_ERR DRV_PFX "Unknown SPIC Type, more than 2 IO Ports\n"); + ioport = kzalloc(sizeof(*ioport), GFP_KERNEL); + if (!ioport) return AE_ERROR; - } + + list_add_tail(&ioport->list, &dev->ioports); + memcpy(&ioport->io, io, sizeof(*io)); return AE_OK; } default: @@ -2220,22 +2199,10 @@ static int sony_pic_enable(struct acpi_device *device, { acpi_status status; int result = 0; - /* Type 1 resource layout is: - * IO - * IO - * IRQNoFlags - * End - * - * Type 2 and 3 resource layout is: - * IO - * IRQNoFlags - * End - */ struct { - struct acpi_resource res1; - struct acpi_resource res2; - struct acpi_resource res3; - struct acpi_resource res4; + struct acpi_resource io_res; + struct acpi_resource irq_res; + struct acpi_resource end; } *resource; struct acpi_buffer buffer = { 0, NULL }; @@ -2250,49 +2217,21 @@ static int sony_pic_enable(struct acpi_device *device, buffer.length = sizeof(*resource) + 1; buffer.pointer = resource; - /* setup Type 1 resources */ - if (spic_dev.model == SONYPI_DEVICE_TYPE1) { + /* setup io resource */ + resource->io_res.type = ACPI_RESOURCE_TYPE_IO; + resource->io_res.length = sizeof(struct acpi_resource); + memcpy(&resource->io_res.data.io, &ioport->io, + sizeof(struct acpi_resource_io)); - /* setup io resources */ - resource->res1.type = ACPI_RESOURCE_TYPE_IO; - resource->res1.length = sizeof(struct acpi_resource); - memcpy(&resource->res1.data.io, &ioport->io1, - sizeof(struct acpi_resource_io)); + /* setup irq resource */ + resource->irq_res.type = ACPI_RESOURCE_TYPE_IRQ; + resource->irq_res.length = sizeof(struct acpi_resource); + memcpy(&resource->irq_res.data.irq, &irq->irq, + sizeof(struct acpi_resource_irq)); + /* we requested a shared irq */ + resource->irq_res.data.irq.sharable = ACPI_SHARED; - resource->res2.type = ACPI_RESOURCE_TYPE_IO; - resource->res2.length = sizeof(struct acpi_resource); - memcpy(&resource->res2.data.io, &ioport->io2, - sizeof(struct acpi_resource_io)); - - /* setup irq resource */ - resource->res3.type = ACPI_RESOURCE_TYPE_IRQ; - resource->res3.length = sizeof(struct acpi_resource); - memcpy(&resource->res3.data.irq, &irq->irq, - sizeof(struct acpi_resource_irq)); - /* we requested a shared irq */ - resource->res3.data.irq.sharable = ACPI_SHARED; - - resource->res4.type = ACPI_RESOURCE_TYPE_END_TAG; - - } - /* setup Type 2/3 resources */ - else { - /* setup io resource */ - resource->res1.type = ACPI_RESOURCE_TYPE_IO; - resource->res1.length = sizeof(struct acpi_resource); - memcpy(&resource->res1.data.io, &ioport->io1, - sizeof(struct acpi_resource_io)); - - /* setup irq resource */ - resource->res2.type = ACPI_RESOURCE_TYPE_IRQ; - resource->res2.length = sizeof(struct acpi_resource); - memcpy(&resource->res2.data.irq, &irq->irq, - sizeof(struct acpi_resource_irq)); - /* we requested a shared irq */ - resource->res2.data.irq.sharable = ACPI_SHARED; - - resource->res3.type = ACPI_RESOURCE_TYPE_END_TAG; - } + resource->end.type = ACPI_RESOURCE_TYPE_END_TAG; /* Attempt to set the resource */ dprintk("Evaluating _SRS\n"); @@ -2300,7 +2239,7 @@ static int sony_pic_enable(struct acpi_device *device, /* check for total failure */ if (ACPI_FAILURE(status)) { - printk(KERN_ERR DRV_PFX "Error evaluating _SRS\n"); + printk(KERN_ERR DRV_PFX "Error evaluating _SRS"); result = -ENODEV; goto end; } @@ -2329,14 +2268,11 @@ static irqreturn_t sony_pic_irq(int irq, void *dev_id) struct sony_pic_dev *dev = (struct sony_pic_dev *) dev_id; - ev = inb_p(dev->cur_ioport->io1.minimum); - if (dev->cur_ioport->io2.minimum) - data_mask = inb_p(dev->cur_ioport->io2.minimum); - else - data_mask = inb_p(dev->cur_ioport->io1.minimum + dev->evport_offset); + ev = inb_p(dev->cur_ioport->io.minimum); + data_mask = inb_p(dev->cur_ioport->io.minimum + dev->evport_offset); dprintk("event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n", - ev, data_mask, dev->cur_ioport->io1.minimum, dev->evport_offset); + ev, data_mask, dev->cur_ioport->io.minimum, dev->evport_offset); if (ev == 0x00 || ev == 0xff) return IRQ_HANDLED; @@ -2387,11 +2323,8 @@ static int sony_pic_remove(struct acpi_device *device, int type) } free_irq(spic_dev.cur_irq->irq.interrupts[0], &spic_dev); - release_region(spic_dev.cur_ioport->io1.minimum, - spic_dev.cur_ioport->io1.address_length); - if (spic_dev.cur_ioport->io2.minimum) - release_region(spic_dev.cur_ioport->io2.minimum, - spic_dev.cur_ioport->io2.address_length); + release_region(spic_dev.cur_ioport->io.minimum, + spic_dev.cur_ioport->io.address_length); sonypi_compat_exit(); @@ -2464,36 +2397,14 @@ static int sony_pic_add(struct acpi_device *device) goto err_remove_input; /* request io port */ - list_for_each_entry_reverse(io, &spic_dev.ioports, list) { - if (request_region(io->io1.minimum, io->io1.address_length, + list_for_each_entry(io, &spic_dev.ioports, list) { + if (request_region(io->io.minimum, io->io.address_length, "Sony Programable I/O Device")) { - dprintk("I/O port1: 0x%.4x (0x%.4x) + 0x%.2x\n", - io->io1.minimum, io->io1.maximum, - io->io1.address_length); - /* Type 1 have 2 ioports */ - if (io->io2.minimum) { - if (request_region(io->io2.minimum, - io->io2.address_length, - "Sony Programable I/O Device")) { - dprintk("I/O port2: 0x%.4x (0x%.4x) + 0x%.2x\n", - io->io2.minimum, io->io2.maximum, - io->io2.address_length); - spic_dev.cur_ioport = io; - break; - } - else { - dprintk("Unable to get I/O port2: " - "0x%.4x (0x%.4x) + 0x%.2x\n", - io->io2.minimum, io->io2.maximum, - io->io2.address_length); - release_region(io->io1.minimum, - io->io1.address_length); - } - } - else { - spic_dev.cur_ioport = io; - break; - } + dprintk("I/O port: 0x%.4x (0x%.4x) + 0x%.2x\n", + io->io.minimum, io->io.maximum, + io->io.address_length); + spic_dev.cur_ioport = io; + break; } } if (!spic_dev.cur_ioport) { @@ -2503,7 +2414,7 @@ static int sony_pic_add(struct acpi_device *device) } /* request IRQ */ - list_for_each_entry_reverse(irq, &spic_dev.interrupts, list) { + list_for_each_entry(irq, &spic_dev.interrupts, list) { if (!request_irq(irq->irq.interrupts[0], sony_pic_irq, IRQF_SHARED, "sony-laptop", &spic_dev)) { dprintk("IRQ: %d - triggering: %d - " @@ -2551,11 +2462,8 @@ static int sony_pic_add(struct acpi_device *device) free_irq(spic_dev.cur_irq->irq.interrupts[0], &spic_dev); err_release_region: - release_region(spic_dev.cur_ioport->io1.minimum, - spic_dev.cur_ioport->io1.address_length); - if (spic_dev.cur_ioport->io2.minimum) - release_region(spic_dev.cur_ioport->io2.minimum, - spic_dev.cur_ioport->io2.address_length); + release_region(spic_dev.cur_ioport->io.minimum, + spic_dev.cur_ioport->io.address_length); err_remove_compat: sonypi_compat_exit(); diff --git a/trunk/drivers/misc/thinkpad_acpi.c b/trunk/drivers/misc/thinkpad_acpi.c index e953276664a0..81e068fa7ac5 100644 --- a/trunk/drivers/misc/thinkpad_acpi.c +++ b/trunk/drivers/misc/thinkpad_acpi.c @@ -22,7 +22,7 @@ */ #define IBM_VERSION "0.16" -#define TPACPI_SYSFS_VERSION 0x020000 +#define TPACPI_SYSFS_VERSION 0x010000 /* * Changelog: @@ -117,12 +117,6 @@ IBM_BIOS_MODULE_ALIAS("K[U,X-Z]"); #define __unused __attribute__ ((unused)) -static enum { - TPACPI_LIFE_INIT = 0, - TPACPI_LIFE_RUNNING, - TPACPI_LIFE_EXITING, -} tpacpi_lifecycle; - /**************************************************************************** **************************************************************************** * @@ -348,9 +342,6 @@ static void dispatch_acpi_notify(acpi_handle handle, u32 event, void *data) { struct ibm_struct *ibm = data; - if (tpacpi_lifecycle != TPACPI_LIFE_RUNNING) - return; - if (!ibm || !ibm->acpi || !ibm->acpi->notify) return; @@ -526,10 +517,8 @@ static char *next_cmd(char **cmds) ****************************************************************************/ static struct platform_device *tpacpi_pdev; -static struct platform_device *tpacpi_sensors_pdev; static struct device *tpacpi_hwmon; static struct input_dev *tpacpi_inputdev; -static struct mutex tpacpi_inputdev_send_mutex; static int tpacpi_resume_handler(struct platform_device *pdev) @@ -554,12 +543,6 @@ static struct platform_driver tpacpi_pdriver = { .resume = tpacpi_resume_handler, }; -static struct platform_driver tpacpi_hwmon_pdriver = { - .driver = { - .name = IBM_HWMON_DRVR_NAME, - .owner = THIS_MODULE, - }, -}; /************************************************************************* * thinkpad-acpi driver attributes @@ -709,8 +692,6 @@ static int parse_strtoul(const char *buf, { char *endp; - while (*buf && isspace(*buf)) - buf++; *value = simple_strtoul(buf, &endp, 0); while (*endp && isspace(*endp)) endp++; @@ -1008,7 +989,6 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) int res, i; int status; - int hkeyv; vdbg_printk(TPACPI_DBG_INIT, "initializing hotkey subdriver\n"); @@ -1034,35 +1014,18 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) return res; /* mask not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p, - A30, R30, R31, T20-22, X20-21, X22-24. Detected by checking - for HKEY interface version 0x100 */ - if (acpi_evalf(hkey_handle, &hkeyv, "MHKV", "qd")) { - if ((hkeyv >> 8) != 1) { - printk(IBM_ERR "unknown version of the " - "HKEY interface: 0x%x\n", hkeyv); - printk(IBM_ERR "please report this to %s\n", - IBM_MAIL); - } else { - /* - * MHKV 0x100 in A31, R40, R40e, - * T4x, X31, and later - * */ - tp_features.hotkey_mask = 1; - } - } + A30, R30, R31, T20-22, X20-21, X22-24 */ + tp_features.hotkey_mask = + acpi_evalf(hkey_handle, NULL, "DHKN", "qv"); vdbg_printk(TPACPI_DBG_INIT, "hotkey masks are %s\n", str_supported(tp_features.hotkey_mask)); if (tp_features.hotkey_mask) { + /* MHKA available in A31, R40, R40e, T4x, X31, and later */ if (!acpi_evalf(hkey_handle, &hotkey_all_mask, - "MHKA", "qd")) { - printk(IBM_ERR - "missing MHKA handler, " - "please report this to %s\n", - IBM_MAIL); + "MHKA", "qd")) hotkey_all_mask = 0x080cU; /* FN+F12, FN+F4, FN+F3 */ - } } res = hotkey_get(&hotkey_orig_status, &hotkey_orig_mask); @@ -1168,8 +1131,6 @@ static void tpacpi_input_send_key(unsigned int scancode, unsigned int keycode) { if (keycode != KEY_RESERVED) { - mutex_lock(&tpacpi_inputdev_send_mutex); - input_report_key(tpacpi_inputdev, keycode, 1); if (keycode == KEY_UNKNOWN) input_event(tpacpi_inputdev, EV_MSC, MSC_SCAN, @@ -1181,8 +1142,6 @@ static void tpacpi_input_send_key(unsigned int scancode, input_event(tpacpi_inputdev, EV_MSC, MSC_SCAN, scancode); input_sync(tpacpi_inputdev); - - mutex_unlock(&tpacpi_inputdev_send_mutex); } } @@ -1190,47 +1149,18 @@ static void tpacpi_input_send_radiosw(void) { int wlsw; - mutex_lock(&tpacpi_inputdev_send_mutex); - - if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&wlsw)) { + if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&wlsw)) input_report_switch(tpacpi_inputdev, SW_RADIO, !!wlsw); - input_sync(tpacpi_inputdev); - } - - mutex_unlock(&tpacpi_inputdev_send_mutex); } static void hotkey_notify(struct ibm_struct *ibm, u32 event) { u32 hkey; unsigned int keycode, scancode; - int send_acpi_ev; - int ignore_acpi_ev; - - if (event != 0x80) { - printk(IBM_ERR "unknown HKEY notification event %d\n", event); - /* forward it to userspace, maybe it knows how to handle it */ - acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class, - ibm->acpi->device->dev.bus_id, - event, 0); - return; - } - - while (1) { - if (!acpi_evalf(hkey_handle, &hkey, "MHKP", "d")) { - printk(IBM_ERR "failed to retrieve HKEY event\n"); - return; - } - - if (hkey == 0) { - /* queue empty */ - return; - } - - send_acpi_ev = 0; - ignore_acpi_ev = 0; + int send_acpi_ev = 0; + if (event == 0x80 && acpi_evalf(hkey_handle, &hkey, "MHKP", "d")) { switch (hkey >> 12) { case 1: /* 0x1000-0x1FFF: key presses */ @@ -1252,11 +1182,9 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event) * eat up known LID events */ if (hkey != 0x5001 && hkey != 0x5002) { printk(IBM_ERR - "unknown LID-related HKEY event: 0x%04x\n", - hkey); + "unknown LID-related hotkey event: 0x%04x\n", + hkey); send_acpi_ev = 1; - } else { - ignore_acpi_ev = 1; } break; case 7: @@ -1274,18 +1202,21 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event) printk(IBM_NOTICE "unhandled HKEY event 0x%04x\n", hkey); send_acpi_ev = 1; } + } else { + printk(IBM_ERR "unknown hotkey notification event %d\n", event); + hkey = 0; + send_acpi_ev = 1; + } - /* Legacy events */ - if (!ignore_acpi_ev && (send_acpi_ev || hotkey_report_mode < 2)) { - acpi_bus_generate_proc_event(ibm->acpi->device, event, hkey); - } + /* Legacy events */ + if (send_acpi_ev || hotkey_report_mode < 2) + acpi_bus_generate_proc_event(ibm->acpi->device, event, hkey); - /* netlink events */ - if (!ignore_acpi_ev && send_acpi_ev) { - acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class, - ibm->acpi->device->dev.bus_id, - event, hkey); - } + /* netlink events */ + if (send_acpi_ev) { + acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class, + ibm->acpi->device->dev.bus_id, + event, hkey); } } @@ -2881,7 +2812,7 @@ static int __init thermal_init(struct ibm_init_struct *iibm) switch(thermal_read_mode) { case TPACPI_THERMAL_TPEC_16: - res = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj, + res = sysfs_create_group(&tpacpi_pdev->dev.kobj, &thermal_temp_input16_group); if (res) return res; @@ -2889,7 +2820,7 @@ static int __init thermal_init(struct ibm_init_struct *iibm) case TPACPI_THERMAL_TPEC_8: case TPACPI_THERMAL_ACPI_TMP07: case TPACPI_THERMAL_ACPI_UPDT: - res = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj, + res = sysfs_create_group(&tpacpi_pdev->dev.kobj, &thermal_temp_input8_group); if (res) return res; @@ -2906,13 +2837,13 @@ static void thermal_exit(void) { switch(thermal_read_mode) { case TPACPI_THERMAL_TPEC_16: - sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj, + sysfs_remove_group(&tpacpi_pdev->dev.kobj, &thermal_temp_input16_group); break; case TPACPI_THERMAL_TPEC_8: case TPACPI_THERMAL_ACPI_TMP07: case TPACPI_THERMAL_ACPI_UPDT: - sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj, + sysfs_remove_group(&tpacpi_pdev->dev.kobj, &thermal_temp_input16_group); break; case TPACPI_THERMAL_NONE: @@ -3695,7 +3626,7 @@ static struct device_attribute dev_attr_fan_fan1_input = __ATTR(fan1_input, S_IRUGO, fan_fan1_input_show, NULL); -/* sysfs fan fan_watchdog (hwmon driver) ------------------------------- */ +/* sysfs fan fan_watchdog (driver) ------------------------------------- */ static ssize_t fan_fan_watchdog_show(struct device_driver *drv, char *buf) { @@ -3837,10 +3768,10 @@ static int __init fan_init(struct ibm_init_struct *iibm) if (fan_status_access_mode != TPACPI_FAN_NONE || fan_control_access_mode != TPACPI_FAN_WR_NONE) { - rc = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj, + rc = sysfs_create_group(&tpacpi_pdev->dev.kobj, &fan_attr_group); if (!(rc < 0)) - rc = driver_create_file(&tpacpi_hwmon_pdriver.driver, + rc = driver_create_file(&tpacpi_pdriver.driver, &driver_attr_fan_watchdog); if (rc < 0) return rc; @@ -3923,8 +3854,8 @@ static void fan_exit(void) vdbg_printk(TPACPI_DBG_EXIT, "cancelling any pending fan watchdog tasks\n"); /* FIXME: can we really do this unconditionally? */ - sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj, &fan_attr_group); - driver_remove_file(&tpacpi_hwmon_pdriver.driver, &driver_attr_fan_watchdog); + sysfs_remove_group(&tpacpi_pdev->dev.kobj, &fan_attr_group); + driver_remove_file(&tpacpi_pdriver.driver, &driver_attr_fan_watchdog); cancel_delayed_work(&fan_watchdog_task); flush_scheduled_work(); @@ -3957,9 +3888,6 @@ static void fan_watchdog_fire(struct work_struct *ignored) { int rc; - if (tpacpi_lifecycle != TPACPI_LIFE_RUNNING) - return; - printk(IBM_NOTICE "fan watchdog: enabling fan\n"); rc = fan_set_enable(); if (rc < 0) { @@ -3980,8 +3908,7 @@ static void fan_watchdog_reset(void) if (fan_watchdog_active) cancel_delayed_work(&fan_watchdog_task); - if (fan_watchdog_maxinterval > 0 && - tpacpi_lifecycle != TPACPI_LIFE_EXITING) { + if (fan_watchdog_maxinterval > 0) { fan_watchdog_active = 1; if (!schedule_delayed_work(&fan_watchdog_task, msecs_to_jiffies(fan_watchdog_maxinterval @@ -4375,19 +4302,6 @@ static struct ibm_struct fan_driver_data = { **************************************************************************** ****************************************************************************/ -/* sysfs name ---------------------------------------------------------- */ -static ssize_t thinkpad_acpi_pdev_name_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%s\n", IBM_NAME); -} - -static struct device_attribute dev_attr_thinkpad_acpi_pdev_name = - __ATTR(name, S_IRUGO, thinkpad_acpi_pdev_name_show, NULL); - -/* --------------------------------------------------------------------- */ - /* /proc support */ static struct proc_dir_entry *proc_dir; @@ -4760,8 +4674,6 @@ static int __init thinkpad_acpi_module_init(void) { int ret, i; - tpacpi_lifecycle = TPACPI_LIFE_INIT; - /* Parameter checking */ if (hotkey_report_mode > 2) return -EINVAL; @@ -4790,31 +4702,19 @@ static int __init thinkpad_acpi_module_init(void) ret = platform_driver_register(&tpacpi_pdriver); if (ret) { - printk(IBM_ERR "unable to register main platform driver\n"); + printk(IBM_ERR "unable to register platform driver\n"); thinkpad_acpi_module_exit(); return ret; } tp_features.platform_drv_registered = 1; - ret = platform_driver_register(&tpacpi_hwmon_pdriver); - if (ret) { - printk(IBM_ERR "unable to register hwmon platform driver\n"); - thinkpad_acpi_module_exit(); - return ret; - } - tp_features.sensors_pdrv_registered = 1; - ret = tpacpi_create_driver_attributes(&tpacpi_pdriver.driver); - if (!ret) { - tp_features.platform_drv_attrs_registered = 1; - ret = tpacpi_create_driver_attributes(&tpacpi_hwmon_pdriver.driver); - } if (ret) { printk(IBM_ERR "unable to create sysfs driver attributes\n"); thinkpad_acpi_module_exit(); return ret; } - tp_features.sensors_pdrv_attrs_registered = 1; + tp_features.platform_drv_attrs_registered = 1; /* Device initialization */ @@ -4827,26 +4727,7 @@ static int __init thinkpad_acpi_module_init(void) thinkpad_acpi_module_exit(); return ret; } - tpacpi_sensors_pdev = platform_device_register_simple( - IBM_HWMON_DRVR_NAME, - -1, NULL, 0); - if (IS_ERR(tpacpi_sensors_pdev)) { - ret = PTR_ERR(tpacpi_sensors_pdev); - tpacpi_sensors_pdev = NULL; - printk(IBM_ERR "unable to register hwmon platform device\n"); - thinkpad_acpi_module_exit(); - return ret; - } - ret = device_create_file(&tpacpi_sensors_pdev->dev, - &dev_attr_thinkpad_acpi_pdev_name); - if (ret) { - printk(IBM_ERR - "unable to create sysfs hwmon device attributes\n"); - thinkpad_acpi_module_exit(); - return ret; - } - tp_features.sensors_pdev_attrs_registered = 1; - tpacpi_hwmon = hwmon_device_register(&tpacpi_sensors_pdev->dev); + tpacpi_hwmon = hwmon_device_register(&tpacpi_pdev->dev); if (IS_ERR(tpacpi_hwmon)) { ret = PTR_ERR(tpacpi_hwmon); tpacpi_hwmon = NULL; @@ -4854,7 +4735,6 @@ static int __init thinkpad_acpi_module_init(void) thinkpad_acpi_module_exit(); return ret; } - mutex_init(&tpacpi_inputdev_send_mutex); tpacpi_inputdev = input_allocate_device(); if (!tpacpi_inputdev) { printk(IBM_ERR "unable to allocate input device\n"); @@ -4889,7 +4769,6 @@ static int __init thinkpad_acpi_module_init(void) tp_features.input_device_registered = 1; } - tpacpi_lifecycle = TPACPI_LIFE_RUNNING; return 0; } @@ -4897,8 +4776,6 @@ static void thinkpad_acpi_module_exit(void) { struct ibm_struct *ibm, *itmp; - tpacpi_lifecycle = TPACPI_LIFE_EXITING; - list_for_each_entry_safe_reverse(ibm, itmp, &tpacpi_all_drivers, all_drivers) { @@ -4917,22 +4794,12 @@ static void thinkpad_acpi_module_exit(void) if (tpacpi_hwmon) hwmon_device_unregister(tpacpi_hwmon); - if (tp_features.sensors_pdev_attrs_registered) - device_remove_file(&tpacpi_sensors_pdev->dev, - &dev_attr_thinkpad_acpi_pdev_name); - if (tpacpi_sensors_pdev) - platform_device_unregister(tpacpi_sensors_pdev); if (tpacpi_pdev) platform_device_unregister(tpacpi_pdev); - if (tp_features.sensors_pdrv_attrs_registered) - tpacpi_remove_driver_attributes(&tpacpi_hwmon_pdriver.driver); if (tp_features.platform_drv_attrs_registered) tpacpi_remove_driver_attributes(&tpacpi_pdriver.driver); - if (tp_features.sensors_pdrv_registered) - platform_driver_unregister(&tpacpi_hwmon_pdriver); - if (tp_features.platform_drv_registered) platform_driver_unregister(&tpacpi_pdriver); diff --git a/trunk/drivers/misc/thinkpad_acpi.h b/trunk/drivers/misc/thinkpad_acpi.h index 3abcc8120634..acd5835ec889 100644 --- a/trunk/drivers/misc/thinkpad_acpi.h +++ b/trunk/drivers/misc/thinkpad_acpi.h @@ -58,14 +58,13 @@ #define IBM_NAME "thinkpad" #define IBM_DESC "ThinkPad ACPI Extras" -#define IBM_FILE IBM_NAME "_acpi" +#define IBM_FILE "thinkpad_acpi" #define IBM_URL "http://ibm-acpi.sf.net/" #define IBM_MAIL "ibm-acpi-devel@lists.sourceforge.net" #define IBM_PROC_DIR "ibm" #define IBM_ACPI_EVENT_PREFIX "ibm" #define IBM_DRVR_NAME IBM_FILE -#define IBM_HWMON_DRVR_NAME IBM_NAME "_hwmon" #define IBM_LOG IBM_FILE ": " #define IBM_ERR KERN_ERR IBM_LOG @@ -172,7 +171,6 @@ static int parse_strtoul(const char *buf, unsigned long max, /* Device model */ static struct platform_device *tpacpi_pdev; -static struct platform_device *tpacpi_sensors_pdev; static struct device *tpacpi_hwmon; static struct platform_driver tpacpi_pdriver; static struct input_dev *tpacpi_inputdev; @@ -235,25 +233,22 @@ struct ibm_init_struct { static struct { #ifdef CONFIG_THINKPAD_ACPI_BAY - u32 bay_status:1; - u32 bay_eject:1; - u32 bay_status2:1; - u32 bay_eject2:1; + u16 bay_status:1; + u16 bay_eject:1; + u16 bay_status2:1; + u16 bay_eject2:1; #endif - u32 bluetooth:1; - u32 hotkey:1; - u32 hotkey_mask:1; - u32 hotkey_wlsw:1; - u32 light:1; - u32 light_status:1; - u32 wan:1; - u32 fan_ctrl_status_undef:1; - u32 input_device_registered:1; - u32 platform_drv_registered:1; - u32 platform_drv_attrs_registered:1; - u32 sensors_pdrv_registered:1; - u32 sensors_pdrv_attrs_registered:1; - u32 sensors_pdev_attrs_registered:1; + u16 bluetooth:1; + u16 hotkey:1; + u16 hotkey_mask:1; + u16 hotkey_wlsw:1; + u16 light:1; + u16 light_status:1; + u16 wan:1; + u16 fan_ctrl_status_undef:1; + u16 input_device_registered:1; + u16 platform_drv_registered:1; + u16 platform_drv_attrs_registered:1; } tp_features; struct thinkpad_id_data { diff --git a/trunk/drivers/mtd/nand/s3c2410.c b/trunk/drivers/mtd/nand/s3c2410.c index 21b921dd6aab..b79a9cf2d162 100644 --- a/trunk/drivers/mtd/nand/s3c2410.c +++ b/trunk/drivers/mtd/nand/s3c2410.c @@ -696,7 +696,7 @@ static int s3c24xx_nand_probe(struct platform_device *pdev, info->clk = clk_get(&pdev->dev, "nand"); if (IS_ERR(info->clk)) { - dev_err(&pdev->dev, "failed to get clock\n"); + dev_err(&pdev->dev, "failed to get clock"); err = -ENOENT; goto exit_error; } diff --git a/trunk/drivers/mtd/ubi/wl.c b/trunk/drivers/mtd/ubi/wl.c index 6330c8cc72b5..a4f1bf33164a 100644 --- a/trunk/drivers/mtd/ubi/wl.c +++ b/trunk/drivers/mtd/ubi/wl.c @@ -1309,7 +1309,7 @@ static int ubi_thread(void *u) struct ubi_device *ubi = u; ubi_msg("background thread \"%s\" started, PID %d", - ubi->bgt_name, task_pid_nr(current)); + ubi->bgt_name, current->pid); set_freezable(); for (;;) { diff --git a/trunk/drivers/net/3c59x.c b/trunk/drivers/net/3c59x.c index 6f8e7d4cf74d..862f47223fdc 100644 --- a/trunk/drivers/net/3c59x.c +++ b/trunk/drivers/net/3c59x.c @@ -1491,7 +1491,7 @@ vortex_up(struct net_device *dev) struct vortex_private *vp = netdev_priv(dev); void __iomem *ioaddr = vp->ioaddr; unsigned int config; - int i, mii_reg1, mii_reg5, err = 0; + int i, mii_reg1, mii_reg5, err; if (VORTEX_PCI(vp)) { pci_set_power_state(VORTEX_PCI(vp), PCI_D0); /* Go active */ diff --git a/trunk/drivers/net/ax88796.c b/trunk/drivers/net/ax88796.c index 7495a9ee8f4b..9fe0517cf893 100644 --- a/trunk/drivers/net/ax88796.c +++ b/trunk/drivers/net/ax88796.c @@ -900,7 +900,7 @@ static int ax_probe(struct platform_device *pdev) ax->map2 = ioremap(res->start, size); if (ax->map2 == NULL) { - dev_err(&pdev->dev, "cannot map reset register\n"); + dev_err(&pdev->dev, "cannot map reset register"); ret = -ENXIO; goto exit_mem2; } diff --git a/trunk/drivers/net/bnx2.c b/trunk/drivers/net/bnx2.c index da767d3d5af5..78ed633ceb82 100644 --- a/trunk/drivers/net/bnx2.c +++ b/trunk/drivers/net/bnx2.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include #include @@ -56,8 +56,8 @@ #define DRV_MODULE_NAME "bnx2" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "1.6.8" -#define DRV_MODULE_RELDATE "October 17, 2007" +#define DRV_MODULE_VERSION "1.6.7" +#define DRV_MODULE_RELDATE "October 10, 2007" #define RUN_AT(x) (jiffies + (x)) @@ -3079,18 +3079,14 @@ bnx2_set_power_state(struct bnx2 *bp, pci_power_t state) autoneg = bp->autoneg; advertising = bp->advertising; - if (bp->phy_port == PORT_TP) { - bp->autoneg = AUTONEG_SPEED; - bp->advertising = ADVERTISED_10baseT_Half | - ADVERTISED_10baseT_Full | - ADVERTISED_100baseT_Half | - ADVERTISED_100baseT_Full | - ADVERTISED_Autoneg; - } + bp->autoneg = AUTONEG_SPEED; + bp->advertising = ADVERTISED_10baseT_Half | + ADVERTISED_10baseT_Full | + ADVERTISED_100baseT_Half | + ADVERTISED_100baseT_Full | + ADVERTISED_Autoneg; - spin_lock_bh(&bp->phy_lock); - bnx2_setup_phy(bp, bp->phy_port); - spin_unlock_bh(&bp->phy_lock); + bnx2_setup_copper_phy(bp); bp->autoneg = autoneg; bp->advertising = advertising; @@ -3101,16 +3097,10 @@ bnx2_set_power_state(struct bnx2 *bp, pci_power_t state) /* Enable port mode. */ val &= ~BNX2_EMAC_MODE_PORT; - val |= BNX2_EMAC_MODE_MPKT_RCVD | + val |= BNX2_EMAC_MODE_PORT_MII | + BNX2_EMAC_MODE_MPKT_RCVD | BNX2_EMAC_MODE_ACPI_RCVD | BNX2_EMAC_MODE_MPKT; - if (bp->phy_port == PORT_TP) - val |= BNX2_EMAC_MODE_PORT_MII; - else { - val |= BNX2_EMAC_MODE_PORT_GMII; - if (bp->line_speed == SPEED_2500) - val |= BNX2_EMAC_MODE_25G_MODE; - } REG_WR(bp, BNX2_EMAC_MODE, val); @@ -6438,7 +6428,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) /* enable device (incl. PCI PM wakeup), and bus-mastering */ rc = pci_enable_device(pdev); if (rc) { - dev_err(&pdev->dev, "Cannot enable PCI device, aborting.\n"); + dev_err(&pdev->dev, "Cannot enable PCI device, aborting."); goto err_out; } diff --git a/trunk/drivers/net/bnx2_fw2.h b/trunk/drivers/net/bnx2_fw2.h index 4b129b7cbfad..5bd52bead9bf 100644 --- a/trunk/drivers/net/bnx2_fw2.h +++ b/trunk/drivers/net/bnx2_fw2.h @@ -15,3270 +15,3248 @@ */ static u8 bnx2_COM_b09FwText[] = { - 0xdc, 0x5b, 0x6b, 0x6c, 0x1c, 0xd7, 0x75, 0x3e, 0x33, 0x3b, 0x4b, 0xae, - 0xc8, 0x15, 0x35, 0x22, 0x57, 0xd4, 0x9a, 0xa2, 0xed, 0x5d, 0x72, 0x28, - 0xb2, 0x96, 0xea, 0xae, 0x29, 0xa6, 0x62, 0xd3, 0x4d, 0xb4, 0xd9, 0xa5, - 0x5c, 0xb5, 0x75, 0x5a, 0x4a, 0x26, 0xfc, 0x48, 0x55, 0x83, 0xde, 0xa5, - 0x9c, 0xa0, 0xa8, 0x53, 0xc9, 0x76, 0x85, 0x20, 0x05, 0xaa, 0x05, 0x1f, - 0x89, 0x52, 0xb0, 0x1c, 0xc5, 0x92, 0x29, 0xb5, 0x71, 0x6b, 0x96, 0xb4, - 0x6c, 0x15, 0xd8, 0x6a, 0x65, 0xc7, 0x6d, 0x68, 0x54, 0x2e, 0x65, 0xca, - 0x69, 0x95, 0x26, 0x48, 0x8d, 0xa0, 0x42, 0x95, 0x3f, 0x8e, 0xe1, 0xf4, - 0x87, 0x5b, 0xf4, 0x87, 0xd1, 0x07, 0x22, 0xd7, 0x8f, 0xed, 0xf7, 0xdd, - 0xb9, 0x43, 0x0e, 0x97, 0x14, 0x45, 0xf9, 0xf5, 0xa3, 0x04, 0x56, 0x33, - 0xf7, 0x7d, 0xee, 0xb9, 0xe7, 0x7c, 0xe7, 0x31, 0x57, 0x3f, 0x2f, 0x52, - 0x27, 0xfa, 0x6f, 0x3d, 0x7e, 0x89, 0x87, 0x7f, 0xaf, 0x70, 0xfb, 0xce, - 0xdb, 0x77, 0xe0, 0xf5, 0x0e, 0xd3, 0xa8, 0x0d, 0xb1, 0x9e, 0xff, 0xc4, - 0xf0, 0xeb, 0xd6, 0xef, 0x2b, 0xfd, 0xd9, 0xf8, 0xbd, 0x89, 0xc6, 0xc1, - 0x7f, 0x17, 0x31, 0xae, 0xd1, 0x27, 0xf8, 0x57, 0xa9, 0xac, 0xde, 0x6e, - 0x92, 0x96, 0x55, 0xda, 0x43, 0xde, 0x92, 0x8a, 0x66, 0xfe, 0x24, 0x62, - 0xa6, 0x33, 0x47, 0xb2, 0x8e, 0x11, 0x09, 0xa5, 0xbb, 0x8a, 0x05, 0x47, - 0x24, 0x53, 0xda, 0x96, 0xc8, 0xc9, 0x7b, 0x95, 0x62, 0xcc, 0x92, 0xac, - 0x23, 0x91, 0x9b, 0xd3, 0xef, 0x3e, 0xf5, 0xd2, 0xce, 0xe4, 0x5b, 0x53, - 0x21, 0x89, 0xd8, 0xe9, 0x17, 0xc4, 0xde, 0x2a, 0x91, 0x56, 0x8c, 0x79, - 0xb2, 0x33, 0x63, 0x48, 0x83, 0x3f, 0xd7, 0x9b, 0x95, 0x97, 0x3a, 0xa5, - 0xd8, 0x92, 0x8e, 0x88, 0x99, 0xee, 0xb8, 0x92, 0x0d, 0xd9, 0x83, 0xa1, - 0xb4, 0x2d, 0x73, 0x65, 0xe9, 0x3f, 0x30, 0x2e, 0x91, 0x48, 0xfa, 0x4b, - 0x91, 0xda, 0x0e, 0x89, 0x58, 0xe9, 0xa9, 0x23, 0x5f, 0x73, 0x8e, 0x54, - 0x4c, 0xc7, 0xe9, 0x9a, 0x96, 0x68, 0xef, 0xe9, 0x1e, 0xb4, 0x97, 0x92, - 0x5d, 0x22, 0x3b, 0xc5, 0x74, 0x8a, 0xd1, 0x90, 0x13, 0x91, 0x6c, 0xd9, - 0x91, 0x5c, 0x59, 0xe4, 0x1f, 0x4a, 0x86, 0x9c, 0x76, 0x9a, 0x65, 0x7a, - 0xfb, 0xbb, 0x95, 0x0c, 0x68, 0xf9, 0x7b, 0x67, 0xea, 0xc8, 0xa8, 0x43, - 0x7a, 0x1f, 0x8b, 0x90, 0xae, 0x50, 0x7a, 0xa8, 0xb6, 0xe0, 0x58, 0x32, - 0x5c, 0x62, 0xdd, 0x80, 0xc9, 0xba, 0x70, 0x3a, 0x52, 0x77, 0xda, 0x89, - 0xea, 0xba, 0x52, 0x26, 0x8b, 0xf9, 0x46, 0x4a, 0xec, 0x1b, 0xe9, 0x2e, - 0x38, 0x31, 0x5d, 0x3f, 0xba, 0x33, 0xeb, 0xc4, 0x51, 0xdf, 0xaa, 0xdb, - 0x7a, 0xbe, 0x5c, 0x70, 0x1c, 0xdd, 0x76, 0x35, 0x94, 0x75, 0xba, 0x74, - 0xfd, 0xab, 0xbb, 0x0a, 0xce, 0x76, 0x5d, 0xff, 0xd6, 0xae, 0xac, 0x93, - 0xd2, 0xf5, 0xe3, 0xf7, 0x17, 0x9c, 0x1e, 0x5d, 0xdf, 0x8a, 0xfa, 0x5e, - 0x5d, 0xff, 0x83, 0xde, 0x82, 0x93, 0x46, 0xfd, 0x97, 0x22, 0x66, 0x87, - 0x2d, 0x63, 0xa5, 0x04, 0x7e, 0x19, 0xb4, 0xf5, 0xa1, 0x6e, 0x0f, 0x7e, - 0x77, 0xe1, 0x37, 0xbf, 0x41, 0x1a, 0xfa, 0xf1, 0x6c, 0x6b, 0xf5, 0x78, - 0x07, 0x1e, 0xb9, 0x11, 0x79, 0x3d, 0x14, 0x97, 0x97, 0x3a, 0x5f, 0x07, - 0x0f, 0x6d, 0x39, 0x57, 0x16, 0xa3, 0xbf, 0x33, 0x0e, 0xde, 0xc5, 0xe4, - 0xb9, 0x72, 0xbd, 0x84, 0x1e, 0x0f, 0x81, 0x37, 0x5f, 0x90, 0x7c, 0x2c, - 0x22, 0x1b, 0x27, 0x0d, 0x69, 0xeb, 0x8e, 0x48, 0xc6, 0xe6, 0xda, 0x38, - 0xed, 0x89, 0x98, 0x84, 0x26, 0x33, 0x4d, 0xa6, 0x74, 0xd8, 0x39, 0x29, - 0x82, 0x77, 0x57, 0x28, 0x97, 0x68, 0x4b, 0x48, 0x6e, 0xfc, 0x36, 0x19, - 0xb4, 0x49, 0xd7, 0xdc, 0xcd, 0xde, 0x5a, 0x11, 0x23, 0x7b, 0x72, 0x40, - 0xc6, 0xdc, 0xa8, 0x91, 0x3b, 0xf9, 0x59, 0xc9, 0xa6, 0x24, 0x86, 0x71, - 0xf1, 0x3c, 0x5a, 0x66, 0x4a, 0x03, 0x32, 0xea, 0x8a, 0x91, 0x75, 0xc9, - 0xcf, 0x66, 0xb4, 0x37, 0xa8, 0xbe, 0xa8, 0x6b, 0x0d, 0xa9, 0xb9, 0x23, - 0xa8, 0xb7, 0x51, 0xdf, 0x68, 0xf4, 0xa9, 0x39, 0x54, 0x7d, 0x62, 0x44, - 0xa2, 0xf2, 0x74, 0x29, 0xa6, 0xfb, 0x56, 0x2a, 0xd9, 0x94, 0x8d, 0x7e, - 0x03, 0x32, 0xe2, 0xc6, 0x64, 0x10, 0xcf, 0x61, 0x97, 0x72, 0x15, 0x87, - 0x4c, 0x35, 0x14, 0xf3, 0x27, 0xd4, 0x7c, 0x89, 0x50, 0x9a, 0xf3, 0xb5, - 0xa2, 0xdf, 0xdb, 0xa0, 0xcb, 0x10, 0x4b, 0x9d, 0x65, 0x46, 0xf2, 0xe3, - 0x06, 0xe4, 0x0d, 0x4f, 0xc5, 0xd7, 0x3e, 0xd0, 0x6f, 0x89, 0xd3, 0x6d, - 0x48, 0x01, 0x67, 0x55, 0xb4, 0x51, 0x2e, 0xcd, 0x9a, 0x59, 0xb7, 0x56, - 0x72, 0x56, 0x42, 0x42, 0x13, 0x94, 0xa5, 0x41, 0x19, 0xc1, 0x18, 0xd3, - 0x61, 0x9f, 0xb7, 0xb1, 0xef, 0x41, 0x75, 0x0e, 0x35, 0xe9, 0xa2, 0x99, - 0x2b, 0x37, 0x8b, 0x39, 0xb9, 0x5f, 0x5e, 0x19, 0x17, 0x3b, 0x94, 0x7e, - 0xb7, 0x92, 0x75, 0x46, 0xcd, 0xec, 0xb3, 0x96, 0x84, 0x27, 0x0c, 0x19, - 0x75, 0x92, 0xd0, 0x80, 0xa3, 0xe6, 0xee, 0xf2, 0x2c, 0xfa, 0x71, 0x1c, - 0xfa, 0x95, 0x4c, 0xf0, 0x95, 0xef, 0xdb, 0x6c, 0x53, 0xc9, 0x33, 0xfb, - 0xe0, 0x0c, 0xb0, 0x8f, 0xe7, 0x5c, 0x9c, 0x89, 0x3a, 0xa3, 0x04, 0xce, - 0x48, 0x8c, 0xbe, 0x4e, 0xc8, 0xd4, 0x09, 0x4b, 0xf2, 0x29, 0xec, 0x0b, - 0xbd, 0xf3, 0xa9, 0x45, 0xba, 0x46, 0xc6, 0xab, 0xe9, 0xe2, 0x38, 0xd2, - 0xe5, 0xd1, 0x34, 0x7c, 0x82, 0xf4, 0x2d, 0xd2, 0x33, 0x36, 0xee, 0xd3, - 0xc8, 0xf5, 0x48, 0x9b, 0x4f, 0x17, 0xc7, 0x91, 0xae, 0x26, 0x9e, 0x35, - 0xff, 0x8c, 0x3e, 0xd0, 0x31, 0xe2, 0x5a, 0x38, 0xa3, 0xa8, 0xe4, 0xed, - 0xa2, 0x31, 0xd2, 0xbb, 0x2d, 0x0e, 0x6d, 0x36, 0x86, 0x7b, 0x49, 0xb3, - 0x83, 0x73, 0xac, 0x51, 0xe7, 0x0d, 0xf9, 0x26, 0xef, 0xd0, 0x9f, 0xeb, - 0xe3, 0xbd, 0x64, 0xcb, 0xa8, 0x9a, 0x8f, 0x34, 0x7d, 0x14, 0xf3, 0x90, - 0xd6, 0x4b, 0x90, 0xd5, 0x1e, 0xc8, 0x68, 0x4a, 0xfe, 0xae, 0xbc, 0x5d, - 0xbe, 0x53, 0xee, 0x92, 0xbf, 0x81, 0xde, 0xfe, 0x75, 0x39, 0x21, 0x2f, - 0x94, 0x5b, 0xe5, 0xdb, 0xe5, 0xb8, 0x3c, 0xaf, 0xe4, 0xb7, 0x4f, 0xa4, - 0x81, 0x32, 0x9d, 0x90, 0x46, 0xe8, 0xcf, 0x46, 0xe8, 0xe6, 0x13, 0xe0, - 0xdf, 0x89, 0x4e, 0xc9, 0x34, 0xa5, 0x25, 0x72, 0x0b, 0x7e, 0x9b, 0xf1, - 0x6b, 0x4e, 0x43, 0xee, 0x5c, 0xf2, 0x8e, 0x3c, 0xb4, 0x24, 0xa7, 0xf6, - 0x6c, 0xc9, 0x48, 0x79, 0xfe, 0x16, 0x4f, 0x76, 0x45, 0xfa, 0xc1, 0x63, - 0xb3, 0xfb, 0x7f, 0x2a, 0x19, 0x1b, 0xfb, 0xe8, 0xde, 0xa6, 0x78, 0x6f, - 0x76, 0x53, 0x66, 0x13, 0x90, 0x7b, 0xcb, 0xc8, 0xb9, 0x67, 0x80, 0x1b, - 0xf5, 0x46, 0xf6, 0x78, 0x51, 0x0a, 0xc7, 0x2b, 0x52, 0x48, 0x85, 0xe5, - 0x11, 0xbb, 0x22, 0x7d, 0xa9, 0x1a, 0x39, 0x64, 0x83, 0xf7, 0xdb, 0x7f, - 0xdf, 0xf0, 0x31, 0xfb, 0x89, 0xf2, 0x61, 0xbc, 0xb3, 0x4e, 0xe4, 0x84, - 0x7a, 0xf7, 0xea, 0x8b, 0xe5, 0xb0, 0x64, 0x62, 0xc5, 0xb8, 0x25, 0x2d, - 0xa6, 0xb7, 0xee, 0xb0, 0xdf, 0x06, 0x7e, 0x4c, 0x01, 0x27, 0x93, 0x4a, - 0x5f, 0xf2, 0xe3, 0xeb, 0xae, 0x66, 0x54, 0x35, 0xfa, 0xdb, 0x3d, 0x32, - 0xaf, 0xf8, 0x99, 0x18, 0x34, 0xd2, 0x31, 0x69, 0x2b, 0xb1, 0xdc, 0x6b, - 0xdc, 0x5d, 0xa6, 0x3c, 0xe3, 0xbd, 0x4c, 0x3a, 0x6f, 0x42, 0x3f, 0x0b, - 0xcf, 0x8c, 0xa6, 0x37, 0x48, 0x23, 0xe7, 0x21, 0x8d, 0x7c, 0xfe, 0x79, - 0x80, 0xc6, 0xa7, 0x16, 0xde, 0x4f, 0x04, 0xde, 0x8b, 0xe5, 0x4b, 0x75, - 0x1e, 0x6d, 0xbd, 0xf2, 0xc6, 0xc4, 0x57, 0xf4, 0x3a, 0x78, 0x3f, 0xcb, - 0xf9, 0xff, 0xaa, 0xe2, 0xc9, 0x4b, 0xf1, 0x3a, 0xeb, 0xcc, 0x06, 0xd6, - 0x79, 0x31, 0xb0, 0xce, 0x8b, 0x81, 0x75, 0x8a, 0xe0, 0xa9, 0x6c, 0x30, - 0x21, 0xc3, 0x79, 0x9a, 0x31, 0x39, 0x8a, 0x39, 0x5f, 0x97, 0x50, 0x9a, - 0x7a, 0xee, 0xe3, 0xcd, 0x65, 0xf4, 0x4f, 0xcb, 0xfc, 0x44, 0x51, 0xf2, - 0xc7, 0xc3, 0xb2, 0x4f, 0xf5, 0xdb, 0xa5, 0xe9, 0x0b, 0xb6, 0x45, 0x64, - 0x6f, 0x8c, 0xef, 0x7e, 0x9b, 0x05, 0x3e, 0xb3, 0xfc, 0xc6, 0x4d, 0x5e, - 0x99, 0xef, 0xb3, 0x7a, 0x2f, 0x03, 0xde, 0xb8, 0xb3, 0x6f, 0x2a, 0x3c, - 0x9c, 0x2b, 0x13, 0xb7, 0x24, 0x15, 0x72, 0xe4, 0x60, 0x5f, 0xaa, 0x59, - 0x46, 0x6c, 0x23, 0x35, 0xdc, 0x55, 0x4b, 0xbd, 0xc8, 0x98, 0x4e, 0x3d, - 0xb0, 0x41, 0x12, 0x26, 0x31, 0x5f, 0xed, 0xcb, 0x30, 0x3d, 0xfa, 0x6d, - 0x96, 0xfb, 0x4d, 0xa7, 0xb1, 0xaa, 0x9e, 0xba, 0x1d, 0xc2, 0x3b, 0x65, - 0x78, 0xb7, 0x3e, 0x63, 0x0b, 0x65, 0xe2, 0xf0, 0xad, 0xba, 0xec, 0xb7, - 0xe3, 0xc0, 0x96, 0x94, 0x7f, 0xb6, 0x65, 0x69, 0xd9, 0xc7, 0x89, 0x20, - 0x86, 0x73, 0xaf, 0xc0, 0x27, 0x87, 0x72, 0x17, 0x06, 0xad, 0x29, 0xe8, - 0x5c, 0xad, 0xa6, 0x61, 0xb3, 0xa6, 0x01, 0xb4, 0x76, 0x42, 0xb2, 0x94, - 0x2e, 0x29, 0xd1, 0xaa, 0x2a, 0x93, 0xf7, 0xfe, 0xfb, 0x7a, 0xd5, 0xee, - 0xe9, 0x9c, 0xff, 0xf4, 0xf1, 0xfd, 0xcd, 0x80, 0xbd, 0x68, 0x85, 0xce, - 0xc6, 0xc0, 0x2b, 0x1f, 0xeb, 0x89, 0xc1, 0x71, 0xd8, 0x07, 0xc8, 0xaa, - 0xc2, 0xf6, 0x28, 0xf0, 0xd0, 0xd2, 0xd8, 0x1c, 0xd1, 0xd8, 0x1c, 0x05, - 0x2e, 0xb3, 0x6c, 0xeb, 0x72, 0x4c, 0x97, 0xe3, 0x28, 0xc3, 0x8e, 0x4f, - 0x12, 0xbb, 0x1b, 0x8a, 0x43, 0x27, 0x14, 0xde, 0xd3, 0x56, 0x00, 0x85, - 0x89, 0xd7, 0xc4, 0xed, 0x56, 0x99, 0x2e, 0x61, 0xbd, 0x05, 0x6c, 0xe4, - 0xde, 0x83, 0xf4, 0x90, 0x96, 0x75, 0x62, 0xc2, 0x76, 0x65, 0x62, 0xa4, - 0xf7, 0x61, 0xec, 0x9d, 0xf8, 0x43, 0xba, 0x6f, 0x06, 0xad, 0xdc, 0xc7, - 0x27, 0x49, 0x2b, 0xd7, 0xab, 0xa6, 0xf7, 0xc3, 0xe2, 0x20, 0x69, 0x3f, - 0x83, 0x3d, 0x67, 0x80, 0x79, 0x62, 0x0c, 0x74, 0x0e, 0x60, 0xcf, 0xfd, - 0xc0, 0xc3, 0xbb, 0x80, 0x87, 0x7b, 0x80, 0x87, 0x7d, 0xc0, 0xc3, 0x34, - 0xb0, 0xb0, 0x17, 0x58, 0xd8, 0x03, 0x2c, 0x4c, 0x81, 0x37, 0x31, 0x99, - 0x02, 0x36, 0x4e, 0x01, 0x23, 0xa7, 0x30, 0xc7, 0xf0, 0xa4, 0x18, 0x0f, - 0x60, 0x0f, 0xdf, 0x9c, 0x48, 0x9e, 0x82, 0x2c, 0xc5, 0x8b, 0x26, 0xe4, - 0x3f, 0xd5, 0x0b, 0xd9, 0xee, 0x92, 0x99, 0xb2, 0x25, 0x05, 0xd8, 0xd4, - 0xb6, 0xad, 0xed, 0xd0, 0x35, 0xc8, 0x7b, 0x5c, 0xf4, 0xdf, 0x7a, 0xfd, - 0xfc, 0xb1, 0x88, 0xf3, 0x4f, 0x94, 0xc5, 0x84, 0xc8, 0x79, 0xc9, 0xbb, - 0xed, 0x76, 0x9b, 0xd9, 0x85, 0x7e, 0x2c, 0xa7, 0xcc, 0x03, 0xc7, 0xef, - 0x30, 0x87, 0x8e, 0x2b, 0x7f, 0x05, 0x78, 0x55, 0x91, 0xd1, 0x14, 0x75, - 0xab, 0x22, 0xa7, 0x53, 0xc9, 0xde, 0xa2, 0xd4, 0xcb, 0x58, 0x6c, 0x5c, - 0xd9, 0x5a, 0x2b, 0x7d, 0x4c, 0xd9, 0xab, 0x82, 0x83, 0x67, 0xa9, 0xdb, - 0xcc, 0x1f, 0xe7, 0xfe, 0xdb, 0xf1, 0x0b, 0x83, 0x16, 0xce, 0x6f, 0x49, - 0x5f, 0x8f, 0x6d, 0x3e, 0xd4, 0x59, 0x84, 0x42, 0x24, 0xed, 0x79, 0xac, - 0x9c, 0x1b, 0x6f, 0x8f, 0xb7, 0x9b, 0x96, 0x0c, 0x5a, 0x86, 0x0c, 0x43, - 0xbe, 0xfb, 0x52, 0x6f, 0x57, 0xc6, 0x62, 0x6c, 0xaf, 0x95, 0xaf, 0x2b, - 0x9f, 0x03, 0x6b, 0xcf, 0x9c, 0xc0, 0xba, 0x61, 0x9c, 0x01, 0xd7, 0xe5, - 0x3c, 0x28, 0x97, 0x2c, 0x94, 0x93, 0xa7, 0x8a, 0x52, 0x86, 0x9e, 0x6c, - 0x90, 0xec, 0xf6, 0x1a, 0xc9, 0xf4, 0x27, 0x64, 0x78, 0xa2, 0x0c, 0x9c, - 0x8a, 0x28, 0x5d, 0xc9, 0x0f, 0x24, 0xe4, 0xf1, 0x09, 0xd6, 0x9d, 0xc3, - 0xfe, 0x93, 0xc7, 0x32, 0xc2, 0xfd, 0x1b, 0x92, 0xd9, 0x7f, 0x4e, 0x1e, - 0x71, 0xcf, 0xc9, 0x10, 0xce, 0xf0, 0xe9, 0xf2, 0xac, 0x1c, 0x70, 0x1d, - 0x39, 0x0d, 0xbc, 0xcf, 0x1d, 0x07, 0xee, 0x39, 0xeb, 0x81, 0x51, 0xc9, - 0x73, 0xb4, 0xa1, 0x26, 0xfc, 0xbc, 0x69, 0xf0, 0xf7, 0x89, 0x09, 0xf2, - 0xd7, 0x94, 0x47, 0x7f, 0xd1, 0x80, 0x3e, 0x26, 0xc0, 0xcf, 0x56, 0x39, - 0xec, 0x26, 0x67, 0x33, 0x26, 0x70, 0x31, 0x65, 0x87, 0xa4, 0x2e, 0x8e, - 0x7e, 0x5e, 0x9f, 0x5c, 0x2a, 0x84, 0xb3, 0x2e, 0xa2, 0xef, 0xdb, 0xa0, - 0x93, 0x63, 0x63, 0xf8, 0x65, 0xd0, 0x0f, 0xf2, 0x6b, 0x27, 0x67, 0xa7, - 0x4c, 0xf6, 0x4f, 0xe0, 0xcc, 0x80, 0x2b, 0x93, 0x00, 0x1e, 0x9b, 0xef, - 0x69, 0x33, 0x4f, 0x1a, 0x5c, 0xca, 0x59, 0x02, 0x34, 0x11, 0xd3, 0xda, - 0xcf, 0x7d, 0x47, 0xb8, 0xce, 0x46, 0xf4, 0x7f, 0x07, 0x7e, 0xae, 0x2d, - 0x33, 0x38, 0x97, 0x9f, 0x82, 0x57, 0x99, 0xb8, 0x57, 0x1e, 0x9e, 0x4c, - 0x9e, 0x9b, 0x37, 0xf9, 0xee, 0x14, 0xf3, 0xe6, 0x6d, 0x22, 0x8d, 0xe4, - 0x57, 0x0a, 0xbc, 0x72, 0x6c, 0xd3, 0xdc, 0xaa, 0x7d, 0x3b, 0xea, 0x89, - 0x03, 0x9a, 0xe0, 0x67, 0x74, 0x07, 0xf5, 0x84, 0xf6, 0xce, 0xd7, 0x93, - 0x64, 0x7c, 0xca, 0x84, 0xff, 0xd1, 0x6d, 0xc9, 0x31, 0x55, 0x06, 0x8f, - 0x06, 0x92, 0xf1, 0x8c, 0x49, 0x9f, 0xb7, 0x4b, 0x9e, 0x76, 0xd9, 0x1f, - 0x7c, 0x1c, 0x8f, 0xea, 0xfe, 0xe7, 0x20, 0x23, 0xf4, 0xcf, 0xba, 0x40, - 0xb3, 0xa7, 0x3b, 0xd3, 0xe3, 0x31, 0xd5, 0x36, 0xa6, 0xf6, 0x60, 0x60, - 0x5d, 0xc8, 0x26, 0x7c, 0xb5, 0x9c, 0xd2, 0x23, 0x3b, 0x03, 0x5f, 0x1e, - 0x7a, 0xe0, 0xe9, 0xd0, 0x4c, 0x89, 0xb4, 0xdc, 0x43, 0x7e, 0x14, 0x41, - 0xcc, 0x31, 0x33, 0x8d, 0x73, 0xed, 0x91, 0x22, 0xfd, 0xb9, 0xf9, 0xd0, - 0xd3, 0x32, 0x38, 0x43, 0x7b, 0x83, 0x9f, 0xeb, 0xd8, 0x8c, 0x1f, 0x32, - 0xca, 0x16, 0x6c, 0xc1, 0x39, 0xc3, 0x4e, 0xa4, 0x36, 0x6a, 0x3f, 0xe6, - 0x49, 0x9c, 0xdb, 0x79, 0x9c, 0x6b, 0x49, 0x86, 0x4e, 0x5e, 0xa2, 0xcc, - 0x76, 0xcd, 0x48, 0xb2, 0x6b, 0x4c, 0xb6, 0xd9, 0xd3, 0xd0, 0xb7, 0xcc, - 0x40, 0x65, 0x97, 0x99, 0xe6, 0x98, 0x23, 0x18, 0x83, 0xe7, 0xcc, 0x25, - 0x39, 0x54, 0x66, 0xdd, 0xef, 0x80, 0x9f, 0xb0, 0x3b, 0x3d, 0x4f, 0x6a, - 0x39, 0xc7, 0x7c, 0x96, 0x3f, 0xdf, 0x25, 0x3d, 0x1f, 0xfb, 0xb1, 0x0f, - 0xc7, 0x2c, 0xce, 0xbb, 0x9b, 0xb6, 0x06, 0x78, 0xd3, 0x61, 0x56, 0x76, - 0x85, 0xd1, 0x7e, 0xba, 0x87, 0xef, 0x98, 0x07, 0xb6, 0xc6, 0x76, 0xce, - 0xa3, 0x2f, 0xf6, 0xe5, 0xae, 0x93, 0xb6, 0x66, 0x9f, 0x5e, 0x9e, 0x3b, - 0xfd, 0x00, 0x96, 0x1f, 0x6e, 0xf2, 0x78, 0x3f, 0x12, 0xf2, 0xb0, 0xfb, - 0x2f, 0x51, 0xa6, 0x7e, 0x3d, 0x26, 0x39, 0x37, 0x89, 0x7d, 0x42, 0x87, - 0xca, 0x0d, 0x86, 0xb7, 0x47, 0xf0, 0xbf, 0xff, 0x32, 0xf8, 0x20, 0x45, - 0x8f, 0x37, 0xe4, 0x0b, 0x79, 0xd2, 0x00, 0xd9, 0xae, 0xc3, 0xbc, 0x58, - 0x47, 0xf1, 0xe0, 0x96, 0x26, 0xcf, 0xef, 0x4d, 0x16, 0x33, 0x8c, 0xd7, - 0x1a, 0x29, 0xb3, 0xc0, 0xa8, 0xf2, 0xfd, 0x36, 0xe7, 0x9e, 0x32, 0xd7, - 0x91, 0xde, 0xc4, 0x85, 0xd0, 0x7e, 0x96, 0xbb, 0xa6, 0x4c, 0xf0, 0x1e, - 0xe7, 0x93, 0xdd, 0xde, 0xae, 0x71, 0xe9, 0x99, 0x10, 0x65, 0x94, 0xf2, - 0x9c, 0x77, 0xb7, 0xd9, 0xf7, 0x08, 0x65, 0x34, 0x86, 0xf3, 0x26, 0x2e, - 0xf0, 0x69, 0xc1, 0x26, 0xc6, 0x71, 0xc6, 0x5b, 0x34, 0xed, 0x7c, 0xb7, - 0x64, 0xca, 0xc6, 0x1a, 0xee, 0x7f, 0x6f, 0xf0, 0xea, 0xf8, 0xde, 0xc2, - 0x33, 0x39, 0xb6, 0x94, 0x56, 0x9e, 0x67, 0xf5, 0x19, 0x9e, 0x06, 0xed, - 0xac, 0xc7, 0x73, 0xe6, 0x14, 0xf4, 0x0f, 0x58, 0xd1, 0xd3, 0x11, 0xbf, - 0x88, 0xfe, 0x39, 0x60, 0x7c, 0xd1, 0x62, 0xdb, 0x55, 0x63, 0x71, 0x8c, - 0x49, 0x3f, 0x13, 0x3e, 0xed, 0x05, 0xe3, 0x81, 0xf2, 0x2b, 0x46, 0x76, - 0xe6, 0xaa, 0x91, 0x83, 0x5c, 0xcc, 0xb8, 0x3b, 0x20, 0xcf, 0xd4, 0x17, - 0x1b, 0x6b, 0x27, 0xe3, 0xff, 0x62, 0xb6, 0x27, 0xa6, 0xa1, 0xdb, 0x07, - 0xc0, 0x58, 0xef, 0x2c, 0x5b, 0xd5, 0xd9, 0xce, 0x9b, 0x61, 0x8d, 0x75, - 0x2c, 0x27, 0xed, 0x7b, 0xe5, 0x35, 0xec, 0x77, 0x16, 0x7c, 0x9e, 0x95, - 0x42, 0xb9, 0x24, 0xf9, 0x93, 0xdb, 0xec, 0x61, 0xc4, 0xb8, 0x8b, 0xb4, - 0x13, 0xc3, 0x8a, 0xf4, 0xbd, 0x8d, 0xdd, 0xae, 0x14, 0x6b, 0xd2, 0xc4, - 0xb2, 0x0e, 0xc8, 0x13, 0xea, 0x4a, 0x8b, 0x32, 0x79, 0xe7, 0xb2, 0xfd, - 0x20, 0xbe, 0xed, 0x59, 0xba, 0xa7, 0x19, 0xb9, 0xfe, 0x9e, 0x76, 0x2f, - 0xec, 0x89, 0xd8, 0x01, 0xcc, 0x77, 0x81, 0xf9, 0x2e, 0x30, 0xdf, 0x05, - 0xe6, 0xbb, 0xc0, 0x7c, 0x17, 0xf6, 0xc0, 0x05, 0xee, 0xbb, 0xc0, 0x7d, - 0x17, 0xb8, 0xef, 0x02, 0xf7, 0xdd, 0x2c, 0xce, 0x8e, 0xd8, 0x4e, 0xbb, - 0x71, 0xdf, 0x82, 0xad, 0xf4, 0x7c, 0x9b, 0x9b, 0xb4, 0xbf, 0x00, 0x9d, - 0xb4, 0x5b, 0x64, 0xb8, 0x6b, 0x33, 0xf6, 0x56, 0x87, 0x67, 0x3d, 0x9e, - 0x58, 0xa3, 0xeb, 0x33, 0x5a, 0x77, 0xbe, 0x0a, 0xba, 0x4c, 0x94, 0x7f, - 0x09, 0xb2, 0x59, 0x03, 0x7a, 0x7e, 0x41, 0xfb, 0x15, 0xa7, 0x2c, 0x4f, - 0x36, 0xeb, 0x51, 0xf7, 0x69, 0xd4, 0xd5, 0xa3, 0xcf, 0x21, 0xf4, 0xa1, - 0x5f, 0xd2, 0xa0, 0xeb, 0x82, 0xfd, 0xe8, 0x9f, 0xfc, 0x26, 0xd6, 0x4a, - 0xa2, 0x5f, 0x03, 0xe6, 0x6e, 0x45, 0x9f, 0xcf, 0xa2, 0xcf, 0xcd, 0x28, - 0xd3, 0x9f, 0xdd, 0x82, 0xf2, 0xa7, 0xaa, 0xc6, 0xdc, 0x8a, 0xba, 0xcf, - 0x54, 0xd5, 0xcd, 0xa3, 0x0e, 0x71, 0xb0, 0x7d, 0x51, 0x8f, 0x2b, 0xa2, - 0xdc, 0x5c, 0xd5, 0xe7, 0x12, 0xea, 0x7a, 0x51, 0xf7, 0x3d, 0x3c, 0x11, - 0xff, 0xda, 0xa4, 0xc9, 0x6f, 0xa3, 0x6f, 0x9a, 0x40, 0x7d, 0x58, 0xfb, - 0x97, 0x4f, 0xd2, 0xdf, 0x82, 0x9d, 0xfd, 0x53, 0xcb, 0xf3, 0xc7, 0x9e, - 0xb1, 0x3d, 0x59, 0xf5, 0xcb, 0x3f, 0xaa, 0x2a, 0xb3, 0xef, 0xff, 0x56, - 0xd5, 0xed, 0xda, 0xb8, 0xb4, 0xfc, 0x7e, 0x78, 0xf9, 0x98, 0xe3, 0x55, - 0x7d, 0x5e, 0x6e, 0x5c, 0x5a, 0xfe, 0x7c, 0xcd, 0xf2, 0x31, 0xbf, 0xb5, - 0x61, 0x69, 0xdd, 0xe1, 0xa6, 0xa5, 0x65, 0xfa, 0x7d, 0x31, 0xc4, 0x2d, - 0x7e, 0xff, 0x07, 0x37, 0x79, 0xed, 0xe4, 0x6f, 0xb5, 0x2c, 0x29, 0xe3, - 0x8d, 0xb2, 0x89, 0x73, 0xb8, 0x60, 0x40, 0xe7, 0x6c, 0x33, 0xfd, 0x8a, - 0x91, 0x83, 0x4c, 0x65, 0xcb, 0xfe, 0x7c, 0xd4, 0xe5, 0xea, 0xdc, 0x80, - 0x9f, 0x13, 0xa0, 0x8f, 0x15, 0x85, 0xdc, 0x00, 0x8b, 0x63, 0xc9, 0xa3, - 0x45, 0x59, 0xd4, 0xe1, 0x36, 0xf3, 0x5a, 0x3a, 0x3c, 0xa9, 0x71, 0xeb, - 0x32, 0xe8, 0xac, 0x48, 0x7f, 0xaa, 0x96, 0x76, 0x47, 0xe3, 0x19, 0xb1, - 0xa8, 0x52, 0x09, 0x6d, 0xad, 0xc8, 0xc1, 0xd4, 0x3b, 0x15, 0x51, 0x38, - 0xf8, 0x4d, 0xcd, 0x57, 0xe2, 0xa1, 0x0d, 0xb9, 0x8d, 0x29, 0x3f, 0x2e, - 0x94, 0x3e, 0x45, 0x9f, 0xe4, 0x88, 0x87, 0xb3, 0xc4, 0x22, 0x94, 0xcb, - 0x63, 0xe8, 0xc3, 0xf5, 0xf1, 0x9c, 0x21, 0xb6, 0x5b, 0xca, 0xce, 0xe4, - 0x6d, 0xce, 0xbb, 0x12, 0x5e, 0xfe, 0xd8, 0xa2, 0x2f, 0x68, 0x39, 0x67, - 0x60, 0xf3, 0xd8, 0x46, 0xff, 0xe0, 0x0c, 0x7d, 0x91, 0x80, 0x6f, 0xd3, - 0x11, 0x12, 0x67, 0x11, 0x47, 0xbd, 0x7d, 0xb5, 0xd0, 0xd7, 0x5f, 0xc3, - 0x5e, 0x57, 0xc6, 0xab, 0x76, 0xf3, 0xfa, 0xba, 0xbd, 0x77, 0x41, 0xb7, - 0x7d, 0xd9, 0x5b, 0x29, 0x07, 0x70, 0x45, 0x9d, 0xc5, 0xf3, 0xe5, 0xe4, - 0xb1, 0x22, 0x74, 0x69, 0x4e, 0xc5, 0xbb, 0xfe, 0xb9, 0xd0, 0xaf, 0x49, - 0x9e, 0x9a, 0x82, 0x6c, 0x0f, 0xa9, 0x38, 0x80, 0x31, 0x40, 0x45, 0x76, - 0xa7, 0x86, 0x62, 0xe4, 0x43, 0xc6, 0xbc, 0x1a, 0xa6, 0x1f, 0x31, 0xe7, - 0x92, 0x67, 0x29, 0xb4, 0xa7, 0xc0, 0xdb, 0x7f, 0x95, 0x5c, 0x8c, 0x75, - 0xff, 0x55, 0x99, 0x86, 0xff, 0xa3, 0x7c, 0x22, 0xe5, 0x03, 0xd0, 0xa7, - 0x83, 0xad, 0x2f, 0x93, 0xa7, 0x17, 0xc0, 0x67, 0xdf, 0x2f, 0xb8, 0x4c, - 0xbf, 0x54, 0x96, 0xfa, 0xcf, 0x22, 0x8f, 0x94, 0xfe, 0x19, 0x76, 0xc8, - 0xc4, 0x7c, 0xb4, 0x77, 0xb4, 0x29, 0xac, 0xdf, 0x11, 0xa6, 0xff, 0xe6, - 0xd9, 0xff, 0x10, 0xd6, 0x43, 0x4c, 0x5d, 0xfa, 0x0f, 0x23, 0xef, 0xb6, - 0xd2, 0xb7, 0xc2, 0xfe, 0x89, 0xab, 0x6c, 0x63, 0x5d, 0x44, 0xfb, 0xdc, - 0x51, 0xed, 0x63, 0xdb, 0xda, 0xc7, 0x26, 0x1d, 0x46, 0xc4, 0x4e, 0xfb, - 0xbe, 0x02, 0xcf, 0x0c, 0x67, 0xb3, 0x55, 0xf9, 0x0a, 0xb2, 0xb2, 0xaf, - 0xe0, 0xd3, 0x74, 0x16, 0xfb, 0xa4, 0x6f, 0xa7, 0x72, 0x3f, 0x8d, 0x5e, - 0xbe, 0x89, 0x34, 0xf8, 0x36, 0x53, 0xd9, 0xe6, 0xa3, 0x30, 0x83, 0xd8, - 0xdb, 0x6f, 0x83, 0xd6, 0x3d, 0x92, 0x1d, 0x3f, 0xab, 0x6d, 0x30, 0x63, - 0x07, 0xfa, 0xed, 0x9e, 0xcc, 0x66, 0x53, 0x0d, 0x86, 0x9e, 0xa7, 0x19, - 0x56, 0x33, 0x90, 0x97, 0xe2, 0x5a, 0xf4, 0x6d, 0x7c, 0x3f, 0x67, 0x56, - 0xfb, 0x39, 0xe7, 0xe5, 0xa0, 0xeb, 0xc5, 0x0a, 0xfd, 0xa5, 0x0b, 0xa8, - 0x53, 0xb4, 0xc7, 0xe9, 0x4f, 0x9a, 0x26, 0xfd, 0xc9, 0x24, 0x82, 0x0e, - 0x6f, 0x2f, 0x6d, 0xd8, 0xcb, 0xcc, 0xc2, 0x5e, 0xea, 0x2f, 0x2c, 0xdd, - 0x0b, 0xe9, 0xb7, 0xc1, 0x4f, 0x4b, 0xe3, 0x14, 0xe7, 0xfc, 0x46, 0x98, - 0x18, 0xd6, 0x4f, 0x9f, 0xc8, 0xf5, 0x7c, 0xb1, 0xa5, 0xf3, 0xc2, 0x63, - 0x28, 0x4d, 0x5d, 0xa3, 0x8d, 0xfb, 0xf7, 0xf5, 0xca, 0xd2, 0xd8, 0xce, - 0x3d, 0xfc, 0x09, 0xe6, 0x8c, 0x19, 0x79, 0xe5, 0x9b, 0xd1, 0xcf, 0x41, - 0xdc, 0x5d, 0x7a, 0x05, 0x4f, 0xea, 0x8e, 0x9a, 0x07, 0xfb, 0x8d, 0xaa, - 0xfd, 0x8e, 0xb9, 0x97, 0xd4, 0x1e, 0xa7, 0x4b, 0x3f, 0x90, 0xc2, 0xc9, - 0x1f, 0xc2, 0x26, 0x06, 0x73, 0x75, 0xcc, 0x73, 0x92, 0x57, 0xc5, 0x00, - 0xb6, 0x92, 0x66, 0xe6, 0xe1, 0xbe, 0x17, 0xf6, 0xe2, 0x85, 0x71, 0x9c, - 0xbf, 0xe1, 0xb5, 0xab, 0xf5, 0x7d, 0x9e, 0xd7, 0x04, 0xe8, 0xa9, 0xc0, - 0x47, 0x8d, 0x83, 0x86, 0xe0, 0x98, 0xc7, 0xa4, 0xcf, 0xe5, 0x59, 0xb5, - 0xc7, 0x87, 0xc4, 0xb1, 0xf3, 0xe2, 0xfb, 0x25, 0x5c, 0x9f, 0x78, 0x90, - 0x43, 0x0c, 0xc5, 0xdc, 0xaa, 0xcf, 0x57, 0x9f, 0xa7, 0xd1, 0x0b, 0xd5, - 0xf2, 0x31, 0x8a, 0xd8, 0xab, 0xe0, 0x92, 0x4f, 0xbe, 0xdc, 0xfa, 0x6b, - 0x5f, 0x31, 0xb8, 0x9f, 0x11, 0x95, 0x4f, 0x7c, 0x6d, 0x41, 0x7e, 0x87, - 0x81, 0x2b, 0x9e, 0x3c, 0xbe, 0xaa, 0x79, 0xe3, 0xcb, 0x6d, 0x54, 0xcb, - 0x00, 0x63, 0x43, 0xea, 0x95, 0x2f, 0x23, 0x1d, 0xf6, 0xdd, 0x8a, 0x17, - 0x6c, 0x53, 0x79, 0x46, 0x75, 0xce, 0x83, 0x0b, 0xe7, 0xbc, 0xbe, 0x4a, - 0x66, 0x53, 0xb6, 0xa7, 0xa3, 0xd4, 0x45, 0xe8, 0x34, 0xf8, 0xf5, 0xfc, - 0x12, 0xdd, 0xef, 0xba, 0x46, 0x8e, 0x36, 0x2a, 0xa1, 0xc9, 0x97, 0xc1, - 0xcb, 0x5b, 0x11, 0xbb, 0x88, 0x58, 0x13, 0xc4, 0x28, 0xfa, 0x22, 0x8b, - 0xfe, 0xf1, 0xb4, 0xac, 0xe4, 0x1b, 0x5f, 0xcf, 0x0f, 0xb9, 0x7d, 0x8d, - 0x7e, 0xc8, 0xaf, 0xd6, 0x30, 0x96, 0x99, 0x83, 0x9e, 0x1e, 0xc0, 0xf8, - 0x1a, 0xe7, 0x47, 0xb0, 0x6f, 0xa7, 0xad, 0x5a, 0xc7, 0xc7, 0x8b, 0xa8, - 0x6c, 0x9c, 0xdc, 0xa2, 0x30, 0xc3, 0x9e, 0x58, 0xc4, 0x8c, 0x61, 0x97, - 0xf2, 0xab, 0xf4, 0x34, 0xb6, 0x51, 0x7c, 0x8c, 0x78, 0xd6, 0x62, 0xbe, - 0x67, 0x65, 0x1c, 0xf0, 0x72, 0xba, 0x2b, 0xc7, 0x0a, 0x37, 0x55, 0xf1, - 0x72, 0x25, 0xdc, 0x3c, 0x07, 0xde, 0xa5, 0x11, 0x13, 0x27, 0xcf, 0x88, - 0xec, 0x41, 0x9c, 0x9c, 0x7c, 0x4b, 0xa4, 0x0f, 0xb1, 0x72, 0x72, 0x56, - 0x24, 0x83, 0x78, 0x99, 0xf1, 0xdb, 0x5d, 0xe0, 0x69, 0x2f, 0xe2, 0xe9, - 0x1e, 0x60, 0x6a, 0x0a, 0x18, 0xbb, 0x1d, 0xfc, 0xed, 0x02, 0xbf, 0x6d, - 0xc4, 0x5b, 0x65, 0x39, 0x70, 0x5c, 0x8c, 0x7d, 0x2a, 0x7f, 0x4d, 0x7d, - 0x8f, 0xc1, 0xce, 0x56, 0x2a, 0x87, 0x52, 0xed, 0x88, 0xf5, 0x13, 0xf2, - 0x39, 0x8b, 0xb1, 0xad, 0x61, 0xb5, 0x75, 0x7f, 0x3f, 0x14, 0xf4, 0x6b, - 0xb3, 0xd7, 0xb5, 0x13, 0xcb, 0xf9, 0x9f, 0x53, 0xb6, 0xe2, 0xc5, 0xd0, - 0x6a, 0xfc, 0xdf, 0xb7, 0xc0, 0xff, 0x9e, 0x3a, 0xa9, 0xbb, 0x4b, 0xe5, - 0x16, 0xda, 0xba, 0x0f, 0x11, 0xcf, 0x52, 0xb0, 0xfb, 0xb0, 0xcf, 0x15, - 0xb9, 0x33, 0x75, 0xb5, 0x72, 0xd1, 0xd9, 0x20, 0xf9, 0xed, 0x0f, 0x6a, - 0x4c, 0x3f, 0xf5, 0x87, 0x59, 0xa7, 0x08, 0x1d, 0xf1, 0xf2, 0x88, 0x43, - 0xe3, 0x11, 0x58, 0x0a, 0xfe, 0x35, 0xca, 0x74, 0xef, 0x55, 0x9c, 0xe3, - 0xb6, 0x33, 0x4c, 0x42, 0x11, 0x6b, 0xa6, 0x63, 0x51, 0x95, 0x43, 0xde, - 0xe4, 0xb0, 0xde, 0xc6, 0xb9, 0x0e, 0xc8, 0x34, 0xfc, 0x8b, 0x99, 0x5e, - 0xd0, 0xb8, 0xbd, 0x19, 0xfd, 0xa9, 0x7b, 0xe4, 0xf9, 0x80, 0x0c, 0xc6, - 0xc8, 0xd3, 0x18, 0xfa, 0xef, 0x45, 0x9f, 0x46, 0x3c, 0xff, 0x28, 0x34, - 0x6d, 0x33, 0x9e, 0xfe, 0x3c, 0xca, 0x9c, 0x23, 0x68, 0x5b, 0x77, 0x85, - 0x45, 0xcd, 0xc9, 0x31, 0xcd, 0x0a, 0x03, 0x16, 0xd7, 0xe2, 0x3a, 0x6c, - 0x7b, 0xaf, 0x72, 0x47, 0x77, 0x6f, 0x60, 0xbd, 0x86, 0xc0, 0x7a, 0xbd, - 0x81, 0xf5, 0x48, 0x67, 0x63, 0x80, 0xce, 0x46, 0x8c, 0xff, 0x5d, 0xac, - 0x4d, 0x7e, 0x04, 0xd7, 0xcc, 0x07, 0xd6, 0xf4, 0xf7, 0xd7, 0x1c, 0x18, - 0xf7, 0x0e, 0xd6, 0x63, 0x5d, 0x2c, 0x50, 0x47, 0x1a, 0x9a, 0x50, 0xc7, - 0x72, 0x63, 0x80, 0xae, 0xa8, 0x8a, 0xf7, 0xa7, 0xd5, 0x19, 0x92, 0xcf, - 0x75, 0xb0, 0x6b, 0x26, 0x6c, 0x4b, 0x0d, 0xfc, 0xaf, 0xea, 0xbd, 0x7e, - 0x0d, 0xeb, 0xfa, 0xf3, 0xc5, 0x30, 0x07, 0xfb, 0xb3, 0x6f, 0x48, 0x8f, - 0x67, 0x3d, 0xdb, 0xff, 0xb6, 0xf2, 0x8c, 0xe2, 0x5b, 0x1a, 0xb4, 0x93, - 0xc6, 0x36, 0x99, 0x6a, 0xb4, 0x70, 0x9e, 0xa6, 0xb6, 0xa5, 0xc0, 0xda, - 0xb2, 0x69, 0xb4, 0x77, 0xf3, 0xfc, 0x37, 0x68, 0x4c, 0xad, 0x33, 0xb2, - 0xc7, 0x99, 0x4b, 0xa8, 0xd7, 0xb1, 0x22, 0xe2, 0x13, 0x65, 0x87, 0x7c, - 0x3b, 0x41, 0x3b, 0x44, 0xdf, 0x86, 0x36, 0xf6, 0x9c, 0x7e, 0xc7, 0x13, - 0x72, 0xfc, 0xd0, 0x4c, 0xa3, 0x5c, 0x54, 0x7c, 0xb5, 0x65, 0x7e, 0x81, - 0xaf, 0x61, 0xfd, 0xbd, 0xe6, 0x31, 0xfd, 0x2d, 0x64, 0x3f, 0x7c, 0x27, - 0xbc, 0x97, 0x32, 0xa0, 0x23, 0x21, 0xed, 0xdd, 0xcc, 0x61, 0x14, 0xf1, - 0x74, 0xf0, 0x34, 0xf0, 0x84, 0xcd, 0x42, 0x0c, 0xd2, 0xde, 0xcd, 0x58, - 0x50, 0x40, 0xdb, 0x15, 0x15, 0x07, 0xce, 0x94, 0x6d, 0xe3, 0x4e, 0xd7, - 0xcb, 0x1d, 0xcd, 0x3b, 0xab, 0xe5, 0x8e, 0x1e, 0xa8, 0xc5, 0x79, 0x9c, - 0xf2, 0x73, 0x47, 0xf3, 0xa2, 0x72, 0x47, 0xa7, 0xae, 0x93, 0x3b, 0xca, - 0xac, 0x3d, 0x77, 0xc4, 0xf9, 0x2d, 0xb9, 0xbb, 0xc7, 0x36, 0xbf, 0xa8, - 0x73, 0x47, 0x6f, 0x88, 0x97, 0x3b, 0xba, 0x28, 0x2b, 0xe7, 0x8e, 0x8e, - 0x56, 0xe5, 0x8e, 0x9a, 0x54, 0xee, 0x88, 0xf3, 0x78, 0xb9, 0x23, 0x96, - 0xf3, 0xdd, 0xbf, 0xac, 0x72, 0xe9, 0xf9, 0x6e, 0x60, 0xb0, 0xeb, 0x63, - 0x9c, 0x6d, 0x0c, 0xa8, 0xf8, 0xf2, 0x4a, 0xb8, 0xd9, 0xf1, 0x31, 0x8e, - 0xb6, 0x60, 0xf3, 0x82, 0x3d, 0xf3, 0xf1, 0x6e, 0x54, 0xd9, 0xbd, 0xe5, - 0xf9, 0xc5, 0x7b, 0xaa, 0xf2, 0x8b, 0x03, 0x9e, 0xdd, 0x50, 0x38, 0x37, - 0xa8, 0x71, 0x6e, 0x74, 0xc1, 0xcf, 0x39, 0x59, 0xcb, 0x18, 0x7c, 0xa4, - 0x14, 0xc4, 0x51, 0x4b, 0x8d, 0xf5, 0xf2, 0x2c, 0x8b, 0x18, 0x7a, 0xb8, - 0x0a, 0x43, 0x1f, 0x5b, 0xf1, 0xbb, 0x58, 0x3c, 0xb3, 0xfc, 0xbb, 0x98, - 0x21, 0xcd, 0xf4, 0x39, 0xba, 0xf3, 0xd8, 0x03, 0x63, 0xe6, 0xfd, 0x92, - 0x19, 0xb0, 0x81, 0x45, 0x7e, 0xfe, 0x85, 0xe7, 0xbc, 0x68, 0x63, 0xb2, - 0xe6, 0xc7, 0x97, 0x83, 0x79, 0x48, 0xe5, 0x60, 0xbe, 0x5f, 0x1b, 0xcc, - 0xc1, 0xcc, 0x03, 0xb3, 0x32, 0x16, 0xf3, 0x5b, 0x2b, 0xe7, 0x60, 0x1e, - 0x5a, 0x21, 0x07, 0xf3, 0x5d, 0x59, 0xcc, 0xc1, 0x7c, 0x57, 0xfc, 0x1c, - 0x0c, 0xe7, 0x08, 0x69, 0x9f, 0x56, 0x30, 0xee, 0x02, 0x7e, 0xe7, 0xf1, - 0xf3, 0xf2, 0x32, 0xf3, 0x0b, 0x7b, 0x58, 0x29, 0x2f, 0xf3, 0x6f, 0xb5, - 0x1f, 0x24, 0x2f, 0xe3, 0xd9, 0x04, 0x3f, 0x2f, 0x83, 0x9f, 0x0d, 0x1b, - 0x64, 0x06, 0xf3, 0x32, 0xef, 0x53, 0x37, 0x50, 0xc7, 0x32, 0xeb, 0xa1, - 0x23, 0xb0, 0x53, 0x19, 0xd8, 0x99, 0x69, 0xf7, 0xd7, 0xd5, 0x79, 0xcc, - 0xb8, 0x53, 0xd8, 0x77, 0x02, 0xe7, 0x41, 0x5e, 0xb6, 0x2b, 0x5f, 0x34, - 0x63, 0xc5, 0x8d, 0x6c, 0x27, 0xac, 0xda, 0x38, 0xbf, 0x9d, 0x5b, 0xc6, - 0x50, 0x99, 0xf2, 0x1e, 0x31, 0x0a, 0xd8, 0x4b, 0xdf, 0xf8, 0x94, 0x0c, - 0x95, 0x7d, 0x3f, 0xab, 0x5b, 0x9f, 0xc5, 0x94, 0xd2, 0xd3, 0x69, 0xf0, - 0x00, 0x98, 0xb1, 0x06, 0x9b, 0x75, 0x16, 0x34, 0x07, 0xf7, 0x81, 0x18, - 0xba, 0x07, 0x75, 0xea, 0xdc, 0xe9, 0x6f, 0xfa, 0xb4, 0x24, 0xa8, 0xf3, - 0x6b, 0x98, 0x8f, 0x75, 0x67, 0x55, 0xfc, 0x56, 0xe8, 0xe1, 0x5e, 0x69, - 0xfb, 0xe6, 0x40, 0x1f, 0xea, 0x66, 0x18, 0x33, 0xd2, 0x0e, 0xfa, 0x31, - 0x5d, 0x54, 0xc5, 0x74, 0x9b, 0x15, 0x3f, 0xc8, 0xeb, 0x5f, 0x8b, 0x10, - 0x3b, 0x37, 0x3b, 0xdc, 0xc3, 0x79, 0x8d, 0x7b, 0x2c, 0xfb, 0xb1, 0x23, - 0xdf, 0xc9, 0xa7, 0xa7, 0x54, 0xde, 0x67, 0xda, 0xf5, 0xcf, 0xf0, 0x5b, - 0xd8, 0x3b, 0xcb, 0xbd, 0x72, 0xa1, 0x59, 0x22, 0xb1, 0x34, 0x73, 0xbd, - 0xf4, 0xd5, 0x77, 0x30, 0xf7, 0x50, 0xd3, 0xb4, 0x8a, 0xfe, 0xee, 0x5b, - 0x45, 0x7f, 0xef, 0xae, 0xd2, 0xdf, 0xfe, 0x55, 0xf5, 0xf7, 0xeb, 0x91, - 0xa0, 0xfe, 0xee, 0x5b, 0x45, 0x7f, 0x1f, 0xad, 0xd2, 0xdf, 0x83, 0x37, - 0xa4, 0xbf, 0x3a, 0x36, 0x4e, 0xdd, 0xaa, 0x72, 0xc6, 0xc3, 0x13, 0xc4, - 0xac, 0x4f, 0xeb, 0xdc, 0xd5, 0x4a, 0xbe, 0x98, 0x4f, 0x43, 0x5b, 0xcd, - 0x47, 0xe3, 0x87, 0xfd, 0x23, 0xf6, 0xe9, 0xf9, 0xa3, 0xfd, 0xf0, 0x69, - 0xaf, 0xbd, 0xee, 0x1f, 0x8b, 0x99, 0xf6, 0x7d, 0xc0, 0xad, 0x1f, 0xd1, - 0xda, 0x6b, 0x91, 0x3f, 0xc6, 0x56, 0xf4, 0x07, 0xa2, 0xda, 0x66, 0x4e, - 0x6a, 0x1d, 0xf4, 0xf3, 0x12, 0x41, 0x7d, 0xa6, 0x9c, 0x52, 0x36, 0x7f, - 0x8a, 0x3d, 0x51, 0x3e, 0x7d, 0x0c, 0xd8, 0x52, 0xa5, 0x13, 0x73, 0x52, - 0x00, 0x6e, 0x79, 0x3a, 0x41, 0x39, 0xeb, 0xc4, 0xbe, 0x61, 0x2b, 0xdd, - 0xa7, 0xbd, 0xb3, 0x70, 0xf0, 0x9c, 0xf1, 0x75, 0x3f, 0x81, 0x75, 0xfd, - 0x36, 0xda, 0x1e, 0x07, 0x3e, 0xd9, 0x36, 0xf8, 0x93, 0x2d, 0xc0, 0x19, - 0xd6, 0x2f, 0xcd, 0x73, 0xaf, 0x8e, 0xb1, 0x52, 0x0c, 0xa3, 0xef, 0xe9, - 0x1e, 0x60, 0x4e, 0x0f, 0x71, 0xb3, 0x84, 0xd8, 0x8c, 0x7a, 0x41, 0x5d, - 0xe9, 0xe8, 0xda, 0x6d, 0xd2, 0xe7, 0x7b, 0x12, 0x71, 0xfc, 0x2d, 0x4a, - 0xaf, 0x76, 0x97, 0x3b, 0x66, 0xdf, 0x30, 0xb9, 0x46, 0xa5, 0x92, 0x57, - 0xdf, 0x19, 0xc4, 0x6c, 0xeb, 0xde, 0xb2, 0x8e, 0x36, 0xf3, 0x16, 0x27, - 0xa4, 0xe5, 0x3e, 0x83, 0x77, 0xea, 0xd1, 0xeb, 0xf0, 0x47, 0x78, 0x47, - 0xe1, 0x27, 0x2a, 0x5f, 0x37, 0xed, 0xd2, 0xf7, 0x60, 0xcc, 0xb4, 0x53, - 0xf7, 0xdb, 0xa2, 0xbe, 0xb1, 0x66, 0x53, 0x3b, 0xf4, 0xf7, 0x36, 0xda, - 0xc4, 0x24, 0x31, 0x75, 0xc9, 0x79, 0xf3, 0x8e, 0x47, 0x4e, 0xc5, 0x5c, - 0x1c, 0xaf, 0x7c, 0x7f, 0xc4, 0x49, 0x56, 0xe0, 0xfb, 0x40, 0x44, 0xc7, - 0x97, 0xd4, 0xf9, 0xa8, 0x8a, 0x7d, 0xbd, 0x78, 0x8a, 0xf1, 0xf7, 0xd2, - 0xbb, 0x1d, 0x2b, 0xcb, 0x40, 0xcb, 0x07, 0x90, 0x81, 0xea, 0xf3, 0x8b, - 0x00, 0x8b, 0xfc, 0xf3, 0xf3, 0x7d, 0xac, 0xbf, 0xd0, 0xfb, 0xde, 0xa2, - 0xf5, 0xe9, 0xff, 0xc3, 0x3e, 0x8d, 0xc0, 0x3e, 0x7d, 0x6c, 0xfc, 0xa2, - 0xde, 0xe7, 0xce, 0x2a, 0x6c, 0xec, 0x41, 0xfd, 0xe1, 0x9a, 0x8d, 0x1f, - 0x10, 0x1b, 0xf7, 0xde, 0x10, 0x36, 0xfe, 0x70, 0xdd, 0x5a, 0xb1, 0xf1, - 0xd0, 0x07, 0xc6, 0x46, 0xee, 0x6b, 0x65, 0x3c, 0xda, 0xb7, 0x0c, 0x8f, - 0xfe, 0xe0, 0x13, 0xc4, 0xa3, 0xd5, 0xb0, 0x84, 0xe7, 0xd2, 0xa0, 0x7c, - 0x6c, 0x4f, 0xff, 0xe0, 0x5f, 0xcc, 0x84, 0xe5, 0xc2, 0xbd, 0x11, 0x79, - 0x6d, 0x27, 0xfc, 0x6e, 0xf2, 0x48, 0x9d, 0x07, 0xcb, 0xd1, 0x3a, 0xcf, - 0x36, 0xc6, 0x1b, 0xbd, 0x9c, 0x02, 0xc7, 0xf8, 0x3a, 0x6d, 0xa3, 0x9d, - 0x6d, 0x5b, 0xe4, 0xf5, 0xc6, 0x1b, 0x89, 0x53, 0xf9, 0x8d, 0x66, 0xa5, - 0x38, 0x75, 0xf5, 0x9c, 0xe6, 0x62, 0x9c, 0x4a, 0xac, 0x6d, 0xd4, 0x79, - 0x2c, 0xc6, 0x67, 0xfb, 0x35, 0x7e, 0xf2, 0x1d, 0xf1, 0xb8, 0x8b, 0x58, - 0xdc, 0x45, 0x1c, 0xee, 0x22, 0x46, 0x87, 0x6d, 0x7e, 0x01, 0x32, 0xf7, - 0x6d, 0x17, 0x31, 0xb8, 0x8b, 0x18, 0xdc, 0xed, 0xd2, 0x71, 0x7c, 0xbf, - 0xfe, 0x76, 0xc1, 0xef, 0xfb, 0xcc, 0x83, 0x14, 0x61, 0x57, 0x46, 0x79, - 0x3f, 0xc3, 0xcc, 0xa6, 0xd6, 0xe9, 0xfd, 0xf9, 0x79, 0xfd, 0x56, 0x9d, - 0x5b, 0xda, 0xb4, 0x49, 0xf9, 0x0b, 0xe6, 0x2b, 0x75, 0xde, 0x1d, 0x00, - 0xde, 0x23, 0x79, 0x14, 0xbe, 0x92, 0xba, 0x87, 0x45, 0x3d, 0xad, 0x98, - 0x69, 0xe6, 0x8e, 0xc4, 0x34, 0xd3, 0x77, 0x60, 0xcc, 0x36, 0x2f, 0x66, - 0x89, 0x49, 0xc8, 0x4c, 0xd7, 0x93, 0xa7, 0x86, 0x99, 0x5e, 0xaf, 0xe7, - 0x9a, 0xaf, 0xf3, 0xfc, 0xbd, 0x4e, 0x96, 0x2d, 0x33, 0xfd, 0x59, 0x3e, - 0x71, 0xee, 0x7e, 0xfd, 0x3d, 0x8d, 0x4b, 0xd7, 0x1a, 0x53, 0x18, 0x9f, - 0x4d, 0xdd, 0x8b, 0xf9, 0xd4, 0xfd, 0xa7, 0x05, 0x7e, 0x9b, 0xd7, 0xe4, - 0xf7, 0x98, 0xe6, 0xb7, 0xc7, 0xe3, 0x10, 0xfb, 0xa9, 0xdc, 0x36, 0x79, - 0xed, 0xcf, 0xa7, 0x72, 0x93, 0x58, 0x47, 0xdd, 0x01, 0xc1, 0xb3, 0x62, - 0x49, 0xc3, 0xc0, 0x7d, 0x61, 0x27, 0xb8, 0xae, 0xff, 0x2d, 0x7f, 0x2d, - 0x6b, 0x6e, 0x51, 0xdf, 0x07, 0x3d, 0xbb, 0x31, 0xa6, 0x64, 0xd0, 0x4a, - 0x73, 0x5f, 0xef, 0x43, 0xfe, 0xc6, 0x94, 0xfc, 0xe5, 0x10, 0x67, 0x8d, - 0xf6, 0x74, 0x24, 0x2c, 0x73, 0xba, 0x8e, 0x39, 0xe4, 0xbe, 0xb2, 0x8f, - 0x7d, 0x5c, 0xaf, 0xda, 0xa6, 0x33, 0xff, 0xe7, 0x63, 0x9a, 0xb4, 0x78, - 0x79, 0xc1, 0xb5, 0xde, 0xa9, 0x58, 0xd4, 0xa5, 0xc1, 0x05, 0x5d, 0xaa, - 0xab, 0xd2, 0x25, 0x7f, 0x9f, 0xeb, 0xc5, 0xff, 0xe6, 0xbe, 0xd2, 0x5d, - 0x90, 0xb9, 0x72, 0xe0, 0x1b, 0xcf, 0x82, 0x6c, 0xf0, 0x4e, 0xcc, 0x3d, - 0x90, 0x41, 0x7e, 0xdf, 0xd8, 0x03, 0x3d, 0xaa, 0x54, 0xfa, 0x98, 0x27, - 0xdf, 0xde, 0xaf, 0xef, 0x5b, 0x5c, 0x51, 0x39, 0x12, 0x6b, 0x59, 0x8e, - 0xa4, 0x0f, 0xb2, 0x02, 0x3f, 0x00, 0x3a, 0x98, 0x57, 0x67, 0x49, 0x9f, - 0xa0, 0xfa, 0x1b, 0xd2, 0xc5, 0x7a, 0x8f, 0x0f, 0x9d, 0xf5, 0xde, 0x77, - 0x14, 0x73, 0xd3, 0xd2, 0x32, 0xc7, 0x27, 0xea, 0x3d, 0x59, 0x39, 0x06, - 0xfb, 0xdc, 0x07, 0x59, 0xac, 0x91, 0x9c, 0x9a, 0xef, 0x98, 0xe4, 0x9f, - 0xfd, 0xcf, 0xc6, 0xa5, 0xfd, 0x51, 0x77, 0xd2, 0xef, 0xff, 0x78, 0x55, - 0xff, 0xc7, 0xd1, 0xff, 0x67, 0x55, 0xfd, 0x1f, 0x0f, 0xf4, 0x3f, 0xa1, - 0xfb, 0xd7, 0xa2, 0xbf, 0xd2, 0x83, 0x26, 0xdf, 0x2f, 0x36, 0x1d, 0xc4, - 0xb3, 0xcf, 0xfa, 0x63, 0x4e, 0x04, 0xc6, 0x4c, 0x56, 0xad, 0x31, 0x89, - 0x7e, 0xf1, 0xa6, 0xa5, 0x6b, 0xa0, 0xee, 0x64, 0x8d, 0xfe, 0xbe, 0x47, - 0x9f, 0xe5, 0xa0, 0xce, 0x17, 0xe0, 0x59, 0x0a, 0x7e, 0x33, 0xe2, 0x77, - 0x0a, 0xca, 0x9e, 0xff, 0x8d, 0xc2, 0xbf, 0x93, 0x47, 0xbd, 0xcd, 0x40, - 0x6f, 0x17, 0xfd, 0x1a, 0x4f, 0x2e, 0x83, 0x32, 0x49, 0x9c, 0x28, 0x4a, - 0xc8, 0x29, 0xd3, 0x57, 0x32, 0x0a, 0x33, 0xbe, 0x7d, 0xe2, 0xbd, 0x2b, - 0xde, 0xd7, 0xf5, 0xec, 0x70, 0xd8, 0x99, 0xd3, 0x31, 0xe2, 0xaf, 0x90, - 0x7e, 0xe0, 0xa6, 0x8f, 0x9d, 0x72, 0xcc, 0xd3, 0x1f, 0xca, 0x31, 0xe7, - 0xd7, 0x7a, 0x44, 0x99, 0xd5, 0xeb, 0xf4, 0x2d, 0xc3, 0xb7, 0xc4, 0xb2, - 0x3c, 0x5c, 0x68, 0x0d, 0xf8, 0xd6, 0xbf, 0x80, 0x6f, 0xf7, 0xca, 0x94, - 0x9d, 0x50, 0x79, 0xd0, 0x43, 0x0b, 0x79, 0x81, 0xc3, 0x91, 0x46, 0x87, - 0x79, 0x81, 0xe4, 0xa9, 0x8c, 0x7c, 0xb0, 0xbc, 0xc0, 0xbe, 0x2a, 0x1d, - 0xd9, 0xbb, 0xaa, 0xed, 0xfc, 0xb3, 0xfa, 0xb5, 0xe6, 0x05, 0x1e, 0xa9, - 0xb2, 0x63, 0x87, 0x6e, 0xc0, 0x76, 0xe6, 0x95, 0xed, 0xe4, 0x5e, 0xaf, - 0xe7, 0xcb, 0x7f, 0x25, 0xf2, 0xd1, 0xd8, 0xce, 0xd5, 0x72, 0xe2, 0x41, - 0x7b, 0x40, 0xb9, 0xba, 0xac, 0xfd, 0x6c, 0x3c, 0x67, 0x2e, 0x43, 0x3f, - 0x4d, 0x19, 0x54, 0xb2, 0xcc, 0xb2, 0x1f, 0xff, 0xde, 0xb7, 0x10, 0xff, - 0x2e, 0xc6, 0xac, 0xf0, 0x67, 0xbb, 0xfc, 0xd8, 0x88, 0x7e, 0xb3, 0x6d, - 0x14, 0xdc, 0x3d, 0xe6, 0x90, 0x6a, 0x63, 0x8e, 0xf7, 0x36, 0xf9, 0x9c, - 0xba, 0x27, 0x70, 0x5e, 0xe7, 0xd2, 0xa6, 0x54, 0x4c, 0xc0, 0xef, 0x1c, - 0x85, 0xd4, 0x46, 0xed, 0x03, 0x5e, 0x0f, 0x67, 0x97, 0xc6, 0xcf, 0xa6, - 0x79, 0x04, 0x63, 0x19, 0x3f, 0x7f, 0x21, 0x4a, 0x4c, 0xcd, 0x96, 0x57, - 0x1d, 0x8f, 0x71, 0x1c, 0xcf, 0x3e, 0x2a, 0x56, 0x46, 0xbf, 0x39, 0x3d, - 0xde, 0x8b, 0x95, 0xb3, 0xe5, 0xad, 0x51, 0x0f, 0x17, 0x57, 0x8b, 0x63, - 0x8e, 0x44, 0x99, 0x8b, 0x9c, 0x73, 0xaf, 0x47, 0xeb, 0xf2, 0xd8, 0x3c, - 0xb4, 0x2c, 0x36, 0xb7, 0x74, 0xec, 0x7d, 0xbf, 0x8a, 0xcd, 0x3d, 0x1e, - 0x73, 0x2f, 0xc1, 0xd8, 0xca, 0x01, 0x36, 0xf2, 0x5b, 0x10, 0xb1, 0x82, - 0x3e, 0x0b, 0xe4, 0x67, 0xfc, 0x37, 0x94, 0x1f, 0xb3, 0x5c, 0x7e, 0x3e, - 0x6e, 0xbb, 0xe1, 0xef, 0xfd, 0xb2, 0x78, 0xf9, 0xc5, 0x3d, 0xa0, 0x85, - 0xf1, 0x56, 0x58, 0xcb, 0xc3, 0xcf, 0x69, 0xfc, 0xf6, 0xfb, 0xf9, 0xb9, - 0x86, 0x85, 0x6f, 0xc9, 0xc5, 0xcc, 0x92, 0x1c, 0xcf, 0x16, 0xa6, 0xce, - 0x71, 0xee, 0x99, 0x1b, 0xf8, 0xde, 0xf2, 0x61, 0xee, 0x7c, 0x54, 0xdb, - 0xb9, 0x57, 0x21, 0xfb, 0x09, 0x7d, 0xff, 0xaf, 0x0b, 0x3a, 0xc0, 0x3b, - 0xd0, 0xd5, 0x58, 0xab, 0xee, 0xf9, 0x45, 0x36, 0xa5, 0xf9, 0xed, 0x82, - 0x3e, 0xc1, 0x4f, 0xf4, 0x5e, 0xe3, 0x72, 0x6c, 0xc2, 0xcb, 0xd3, 0x9a, - 0xab, 0xde, 0xf1, 0xbb, 0x04, 0x5e, 0x24, 0x8f, 0xfa, 0x79, 0x5a, 0xd3, - 0xbb, 0xe3, 0x77, 0xf4, 0xa3, 0xbb, 0xe3, 0xc7, 0xf9, 0x2d, 0xd9, 0xbb, - 0xc2, 0x1d, 0xbf, 0xd0, 0x1a, 0xef, 0xf8, 0x6d, 0x54, 0x79, 0x5a, 0xce, - 0xe3, 0xe5, 0x69, 0x59, 0x6e, 0xeb, 0xfe, 0x94, 0xc2, 0xa8, 0xe9, 0x09, - 0xe6, 0x75, 0x1e, 0x5c, 0xf7, 0xc9, 0xe4, 0x75, 0xde, 0x8b, 0x7e, 0xfc, - 0x79, 0x1d, 0x7e, 0x17, 0xf8, 0xb2, 0xf7, 0xdd, 0x5a, 0x6e, 0x24, 0x3f, - 0xf0, 0xe1, 0x72, 0xb0, 0x07, 0x55, 0x0e, 0x76, 0xfb, 0xfa, 0x60, 0x0e, - 0xd6, 0xbc, 0xce, 0x3d, 0xb8, 0x83, 0x2b, 0xe4, 0x60, 0xc3, 0x81, 0x7b, - 0x70, 0x61, 0x7d, 0x0f, 0x6e, 0xa3, 0x83, 0x18, 0x53, 0xe7, 0x5b, 0xcd, - 0x55, 0xef, 0xc1, 0xed, 0x5e, 0xff, 0xe1, 0xf3, 0xad, 0xcb, 0xee, 0xc1, - 0x1d, 0xcd, 0x48, 0x8b, 0x24, 0x6e, 0x28, 0x16, 0xfa, 0x30, 0x71, 0x10, - 0xff, 0x8f, 0x40, 0x0d, 0xf6, 0x0c, 0x99, 0x8f, 0x51, 0x3e, 0x29, 0x77, - 0x69, 0x33, 0x5f, 0xe6, 0x7b, 0x17, 0xcf, 0xc7, 0xe8, 0xef, 0x5c, 0x7a, - 0xb7, 0x62, 0xf1, 0x6e, 0x72, 0x64, 0xe1, 0x6e, 0xf2, 0x18, 0x64, 0xc6, - 0x9c, 0x88, 0xc8, 0x74, 0xc0, 0xb6, 0x8e, 0xba, 0xf0, 0x9b, 0x26, 0x6d, - 0xdd, 0xce, 0xff, 0xa7, 0x82, 0xb8, 0xb0, 0xc4, 0xfb, 0xcc, 0x0d, 0x12, - 0x9a, 0x54, 0x98, 0x1a, 0xf3, 0xfe, 0xaf, 0x4e, 0x1c, 0x7d, 0x78, 0x77, - 0x35, 0x2c, 0x87, 0x62, 0x94, 0x65, 0x5f, 0x8e, 0xbf, 0x05, 0xfe, 0x36, - 0x65, 0x16, 0xcb, 0x31, 0x2d, 0xd7, 0x94, 0x69, 0x5f, 0xfe, 0x62, 0x32, - 0x32, 0x41, 0x59, 0xde, 0xa1, 0xff, 0x9f, 0xc4, 0x39, 0x29, 0x94, 0xcf, - 0xea, 0x78, 0x43, 0x7d, 0x8b, 0x02, 0x1f, 0x5b, 0xb4, 0x0d, 0xc6, 0x73, - 0xa6, 0x85, 0x36, 0x8f, 0xdf, 0x1e, 0xa5, 0x6f, 0x7c, 0x5b, 0x7c, 0x08, - 0x78, 0x37, 0xa8, 0x72, 0x27, 0x37, 0xc2, 0x6f, 0xe3, 0x1a, 0xdf, 0x48, - 0xd7, 0xca, 0x73, 0xdf, 0x5f, 0xbe, 0x8c, 0xfd, 0xb5, 0x40, 0x36, 0xbe, - 0x2a, 0xb9, 0x93, 0xb7, 0x49, 0xdf, 0x89, 0x24, 0xe8, 0x79, 0xbf, 0x52, - 0x48, 0xc1, 0xb7, 0x7e, 0x96, 0x77, 0xe1, 0x80, 0xa1, 0x2e, 0x30, 0x14, - 0xbc, 0x7b, 0x61, 0x99, 0xbf, 0x11, 0xbc, 0x43, 0x97, 0x5a, 0xb8, 0x13, - 0xf5, 0x7c, 0x59, 0x22, 0x8d, 0xa4, 0x7b, 0x62, 0xf1, 0x2e, 0xfc, 0x5c, - 0x39, 0xa7, 0xec, 0xdb, 0x73, 0xe5, 0x25, 0x39, 0x21, 0x75, 0x8e, 0xc3, - 0xa5, 0x97, 0x61, 0xe3, 0x2e, 0x1b, 0xb4, 0x71, 0x63, 0xae, 0xdc, 0x12, - 0x12, 0x9e, 0x89, 0x18, 0xe0, 0x83, 0xba, 0x9b, 0xe2, 0xdd, 0x4d, 0x68, - 0x55, 0x67, 0xfb, 0x7f, 0xd4, 0x5d, 0x7d, 0x6c, 0x5b, 0xd7, 0x75, 0x3f, - 0x7c, 0xa4, 0x3e, 0x4c, 0xcb, 0xd2, 0x93, 0x4c, 0xc9, 0xb4, 0x2d, 0xcb, - 0x8f, 0xd2, 0x93, 0xa5, 0xc4, 0x4a, 0xc1, 0x79, 0xda, 0xaa, 0x01, 0x5a, - 0xc7, 0x52, 0xf4, 0xc7, 0x82, 0x60, 0xa5, 0x65, 0x25, 0xf3, 0xd2, 0x2c, - 0x51, 0x29, 0xdb, 0xc9, 0xfe, 0x18, 0xe0, 0x25, 0xd9, 0x9a, 0xfd, 0x51, - 0xe4, 0x95, 0x94, 0x12, 0x63, 0x56, 0x4d, 0xc6, 0xe6, 0x84, 0x02, 0x0b, - 0x36, 0x56, 0x92, 0x9d, 0x14, 0x50, 0xc0, 0x24, 0x6d, 0x87, 0x2c, 0x6d, - 0x11, 0x55, 0x76, 0xda, 0x7f, 0x8d, 0x2d, 0xc0, 0xb2, 0x2e, 0x69, 0x14, - 0x3b, 0xc8, 0x02, 0x2c, 0x58, 0xbb, 0x6e, 0x28, 0xf6, 0x4f, 0xc7, 0x9d, - 0xdf, 0xfd, 0x20, 0x1f, 0xc9, 0x47, 0x7d, 0x24, 0x6e, 0x81, 0x09, 0x10, - 0xc8, 0xf7, 0xde, 0x7d, 0xef, 0xdd, 0x7b, 0xee, 0xf9, 0xf8, 0x9d, 0x73, - 0xcf, 0xb9, 0x94, 0xba, 0xe2, 0x35, 0x57, 0x6e, 0x49, 0x65, 0x7e, 0x65, - 0xce, 0x89, 0x9c, 0x0f, 0x95, 0x43, 0x0b, 0x9a, 0x3a, 0x27, 0x6d, 0x99, - 0x17, 0x33, 0xb0, 0x80, 0x73, 0x3d, 0x35, 0xf6, 0xaf, 0x95, 0xf9, 0xc0, - 0x14, 0x31, 0x85, 0x69, 0x13, 0x7d, 0xde, 0x2b, 0xf4, 0x81, 0xf7, 0xba, - 0x7c, 0x40, 0xe9, 0xbc, 0x56, 0xa5, 0xa3, 0x36, 0xc2, 0x6f, 0xf2, 0x9d, - 0xfd, 0xe2, 0x9d, 0xdd, 0x4a, 0x67, 0xe9, 0xdc, 0xf7, 0x71, 0x63, 0xba, - 0x08, 0x5f, 0x9b, 0xe9, 0x52, 0x87, 0xdf, 0xac, 0x4d, 0xe8, 0xf8, 0xb9, - 0x3a, 0x3a, 0x56, 0xcb, 0x03, 0xfb, 0xe6, 0x65, 0x9d, 0x2d, 0x69, 0x26, - 0xcf, 0x23, 0x9f, 0x5f, 0xe7, 0x65, 0x48, 0x9a, 0x95, 0xe5, 0xe7, 0x92, - 0x3b, 0x27, 0xa3, 0x42, 0xb3, 0xe9, 0x32, 0xcd, 0xf6, 0xfc, 0x3f, 0xa0, - 0xd9, 0x4d, 0x81, 0x79, 0x5f, 0x29, 0x22, 0xff, 0x6e, 0x58, 0xe4, 0x2e, - 0xac, 0xd2, 0x88, 0xb2, 0xff, 0xee, 0x1a, 0x28, 0xd0, 0x12, 0xba, 0x34, - 0x52, 0x58, 0xa7, 0x98, 0x8c, 0x43, 0x98, 0xa5, 0xd2, 0x77, 0xa2, 0x90, - 0x3f, 0xf8, 0x24, 0xf0, 0x51, 0x10, 0xdf, 0x3b, 0xc9, 0x63, 0xfb, 0x97, - 0x60, 0xd7, 0x06, 0x36, 0xf2, 0xe4, 0x36, 0x7c, 0x94, 0x8a, 0x8d, 0x04, - 0x5e, 0x22, 0x27, 0x6e, 0x57, 0xf2, 0x5e, 0x66, 0xb3, 0x3f, 0x6c, 0x67, - 0x3f, 0x92, 0x69, 0x5c, 0x79, 0xee, 0xd6, 0x7c, 0x14, 0x3c, 0x4f, 0xda, - 0xc9, 0xd9, 0x6c, 0xe5, 0xb9, 0x4e, 0xf9, 0xb9, 0x61, 0x0f, 0x5d, 0x65, - 0xd1, 0xcc, 0xa5, 0x7d, 0x75, 0xf9, 0x6a, 0x95, 0xf1, 0x48, 0x5f, 0x45, - 0x8f, 0xe7, 0xc9, 0x4d, 0xf1, 0xa5, 0xcc, 0x3b, 0xab, 0xe4, 0xf0, 0xd4, - 0xfa, 0x29, 0xfb, 0x5d, 0xf1, 0x19, 0xd0, 0xf8, 0x0f, 0x69, 0x75, 0x12, - 0x7a, 0xae, 0x96, 0xd6, 0xef, 0xff, 0x9a, 0x68, 0x1d, 0xe9, 0xf8, 0xf5, - 0xd2, 0x7a, 0x7f, 0x5d, 0x2c, 0xbc, 0x32, 0x1e, 0x0a, 0x75, 0x6f, 0x0b, - 0xcb, 0xd7, 0xd2, 0x7a, 0x7f, 0xc3, 0x78, 0x6a, 0xe3, 0x5c, 0xcc, 0xea, - 0x78, 0x6a, 0xbf, 0xc1, 0x32, 0x92, 0x65, 0x79, 0x69, 0xa8, 0xe3, 0xff, - 0xce, 0x15, 0x6f, 0x75, 0xeb, 0x79, 0xc8, 0x1a, 0xf9, 0x4e, 0x0e, 0xe9, - 0x77, 0x42, 0xae, 0x22, 0x8e, 0x43, 0xf0, 0x9f, 0xf0, 0x5e, 0xe4, 0x62, - 0xd5, 0xe1, 0x2e, 0x7e, 0x2f, 0xcb, 0xff, 0x0b, 0xcf, 0x0b, 0x9b, 0x25, - 0x63, 0x12, 0x68, 0x1f, 0xf2, 0x9d, 0x11, 0x6d, 0x65, 0x8e, 0x96, 0x8a, - 0x51, 0x28, 0x3f, 0xa0, 0x51, 0x6c, 0xa2, 0xde, 0xfe, 0x6d, 0xcf, 0x6f, - 0xd0, 0xf1, 0x88, 0x83, 0x3c, 0x3f, 0xe1, 0x2a, 0xbf, 0x0b, 0xfa, 0xf4, - 0x3c, 0x63, 0x84, 0xfe, 0x32, 0x3e, 0xa8, 0x9e, 0xa3, 0x59, 0xe1, 0xdf, - 0x69, 0x5d, 0xba, 0x2a, 0x73, 0x6b, 0xc5, 0x79, 0xe0, 0xb5, 0xb2, 0x2e, - 0xad, 0xc1, 0xc3, 0x07, 0x3d, 0xf8, 0xc3, 0xb3, 0x9e, 0x55, 0xcf, 0xa1, - 0x85, 0x9c, 0xfa, 0x84, 0xe7, 0x1c, 0x96, 0xeb, 0xd2, 0x9c, 0x4a, 0x5b, - 0x79, 0x7f, 0x42, 0x8c, 0x6b, 0xea, 0xde, 0x38, 0xea, 0xef, 0xca, 0x35, - 0x51, 0xb5, 0x75, 0x60, 0xb0, 0x0b, 0x5a, 0x1e, 0x75, 0xcd, 0x39, 0x68, - 0xd1, 0xe7, 0x51, 0x07, 0xe6, 0xb6, 0x2d, 0xb8, 0xaf, 0x96, 0x16, 0x15, - 0xbb, 0x32, 0xa7, 0xec, 0xca, 0xa2, 0x4b, 0xaf, 0xd7, 0xe3, 0xf7, 0x2e, - 0x0f, 0xfc, 0xee, 0x55, 0x0b, 0x86, 0x3e, 0x3d, 0xc5, 0x98, 0xe4, 0x33, - 0xc0, 0x24, 0x26, 0x6a, 0xb1, 0x24, 0x2e, 0xc1, 0xf5, 0x1c, 0x63, 0x93, - 0x30, 0xf3, 0xca, 0x6b, 0x74, 0x8e, 0x31, 0xf7, 0x35, 0xba, 0x4b, 0xf9, - 0x69, 0x90, 0x5f, 0x9d, 0x47, 0x8b, 0x5a, 0x06, 0x1f, 0x39, 0x0f, 0x45, - 0x86, 0x63, 0xf4, 0x1a, 0x9d, 0x15, 0xf9, 0x3e, 0x58, 0xff, 0x43, 0x9e, - 0xc4, 0xdd, 0xe2, 0xfd, 0x32, 0xae, 0x71, 0x27, 0xf2, 0x02, 0xb7, 0x5e, - 0x9f, 0xa0, 0xea, 0x05, 0xb9, 0x1d, 0xde, 0xb9, 0xac, 0x64, 0x4a, 0x9c, - 0xe3, 0xfb, 0x9f, 0x32, 0xea, 0xef, 0x8f, 0x19, 0x89, 0x62, 0xc2, 0x88, - 0x2f, 0xa1, 0xdd, 0x53, 0xc6, 0x44, 0x11, 0xbe, 0xa4, 0xe6, 0x91, 0x48, - 0x14, 0xf2, 0xb6, 0x46, 0x9b, 0xaf, 0x53, 0x2c, 0x52, 0x4d, 0xad, 0xc8, - 0x16, 0xfa, 0x7d, 0xac, 0xaa, 0xdf, 0x9a, 0xbe, 0xf8, 0x8e, 0xd8, 0xcf, - 0xcb, 0x4c, 0x53, 0x8d, 0x71, 0x83, 0x88, 0xbd, 0x0f, 0x3b, 0xb4, 0x11, - 0xc6, 0x8d, 0xd4, 0x61, 0xdc, 0xc5, 0x4d, 0xfb, 0xfd, 0x69, 0x65, 0x5c, - 0xd6, 0x7c, 0xfb, 0x6d, 0x81, 0x65, 0xb9, 0xdf, 0x55, 0x38, 0xb7, 0x86, - 0xa7, 0xd0, 0x46, 0xc7, 0xc8, 0x75, 0x4c, 0xac, 0x5d, 0xc5, 0x74, 0x75, - 0x3e, 0x45, 0x50, 0xc5, 0xb4, 0x71, 0x1d, 0xbe, 0xd6, 0x2a, 0xf7, 0x0f, - 0x7e, 0x17, 0xe2, 0x3f, 0x6e, 0xbf, 0xcb, 0x1d, 0xf3, 0xf5, 0xaa, 0x0d, - 0xed, 0xf7, 0xa8, 0x0d, 0x75, 0xcb, 0x59, 0xc0, 0x25, 0x67, 0x61, 0x17, - 0x86, 0xeb, 0x65, 0xff, 0xa5, 0x8d, 0xf5, 0x07, 0xfc, 0x97, 0x20, 0xf9, - 0x2f, 0xbb, 0xfd, 0x97, 0xda, 0x3a, 0x7f, 0xc8, 0x1c, 0x70, 0x9a, 0xf4, - 0x65, 0x12, 0xf9, 0xf2, 0x1e, 0x01, 0x3c, 0xe6, 0x4a, 0x1d, 0xe6, 0x52, - 0x5d, 0xcd, 0xa8, 0x57, 0x7f, 0xfb, 0xea, 0xfa, 0x0b, 0x1b, 0x16, 0x6b, - 0x88, 0xef, 0xbc, 0xfc, 0xab, 0x3b, 0xd5, 0xbf, 0x5a, 0x5d, 0x86, 0x77, - 0xf5, 0x8b, 0x18, 0xb8, 0x53, 0xd6, 0x63, 0x63, 0xb2, 0xbf, 0xd9, 0x6a, - 0x5f, 0xc3, 0x7f, 0x89, 0x14, 0xed, 0xbc, 0xf5, 0xfa, 0xf6, 0xe2, 0x68, - 0x3b, 0x6b, 0x6c, 0xef, 0x78, 0xa7, 0x8c, 0x8f, 0xcd, 0xa9, 0x3c, 0xf2, - 0x6e, 0xe5, 0xf7, 0x6d, 0xc6, 0xeb, 0x38, 0x37, 0xa7, 0x62, 0x8a, 0x11, - 0xab, 0x40, 0xe0, 0xf1, 0xc9, 0xd3, 0x4d, 0xb6, 0xa9, 0xd6, 0xb8, 0xb0, - 0x8e, 0x05, 0x9e, 0xd7, 0xcf, 0x97, 0x35, 0x65, 0x9b, 0xcf, 0x99, 0x55, - 0x37, 0x67, 0x92, 0xaf, 0xe0, 0x6f, 0x21, 0x3f, 0x7a, 0xa4, 0x26, 0x47, - 0xfd, 0xd3, 0xd0, 0xa2, 0xdd, 0x23, 0x6f, 0x1b, 0x79, 0xd7, 0x8d, 0xfa, - 0xb9, 0xee, 0xc2, 0xea, 0xb2, 0x6e, 0x63, 0x95, 0xd0, 0xef, 0x52, 0xe9, - 0xe5, 0x28, 0xb0, 0x69, 0x6f, 0x1d, 0xaf, 0x69, 0xbc, 0x64, 0xba, 0xfa, - 0xf9, 0xf8, 0xc6, 0xfd, 0xac, 0xb1, 0xbf, 0x7b, 0x3d, 0xec, 0x6f, 0x23, - 0x5f, 0x42, 0xec, 0x9d, 0xe2, 0x3b, 0x2a, 0x74, 0x41, 0x1b, 0x2d, 0xe5, - 0x91, 0x4b, 0xfe, 0x1b, 0xa8, 0x67, 0x65, 0x7d, 0xeb, 0xaa, 0xcf, 0xf3, - 0x9e, 0xd3, 0xf2, 0x7a, 0x4b, 0x60, 0x1c, 0xeb, 0x83, 0xc8, 0x41, 0xe9, - 0x62, 0x1d, 0x84, 0xf6, 0x83, 0xd6, 0x0d, 0xc4, 0x80, 0x55, 0x3c, 0x2a, - 0xa1, 0xec, 0xcc, 0xd1, 0x2d, 0xac, 0xbb, 0x6c, 0x4f, 0x5f, 0x47, 0xac, - 0x55, 0xc2, 0x9a, 0x10, 0xf2, 0x9e, 0x9d, 0x76, 0x6a, 0xbf, 0xbf, 0xa5, - 0xc5, 0xbe, 0xd9, 0x29, 0xd7, 0xaa, 0x70, 0xad, 0x8d, 0xae, 0xe6, 0x91, - 0x97, 0x8e, 0x6b, 0x0f, 0xf2, 0x35, 0x2f, 0x7d, 0xf5, 0xb6, 0xe2, 0x25, - 0x60, 0x3a, 0x39, 0x47, 0x05, 0x92, 0x73, 0xb6, 0x4e, 0xf0, 0xa5, 0x4a, - 0xf4, 0x4f, 0xd1, 0xdf, 0x14, 0xfe, 0x5f, 0x65, 0xae, 0xb6, 0xb7, 0x8e, - 0x53, 0x9b, 0x03, 0x31, 0xb9, 0x61, 0x1c, 0xb1, 0xa3, 0x6b, 0xab, 0xeb, - 0x38, 0xb5, 0x39, 0x10, 0x8f, 0x6f, 0x29, 0x8e, 0x18, 0xb1, 0xa6, 0x37, - 0xac, 0x33, 0x70, 0xaf, 0xa9, 0xe8, 0xb5, 0xe4, 0x51, 0x51, 0x7b, 0xeb, - 0xe6, 0x89, 0x3b, 0xb3, 0x9e, 0x0c, 0xde, 0xe8, 0xab, 0xd3, 0x61, 0x77, - 0x60, 0x3d, 0xa0, 0x86, 0xb6, 0x41, 0xcf, 0x58, 0x96, 0xf7, 0xba, 0x31, - 0x72, 0x04, 0x10, 0xc3, 0x2e, 0xd2, 0x99, 0x2b, 0xe0, 0x67, 0x83, 0x39, - 0x6f, 0x80, 0x32, 0x21, 0xd4, 0x52, 0x89, 0xba, 0x28, 0xbd, 0xbe, 0x28, - 0xea, 0xa3, 0xce, 0x88, 0xba, 0xcf, 0xc1, 0xf0, 0x6d, 0xb6, 0x91, 0x67, - 0x8a, 0x6f, 0xd1, 0xd9, 0xa5, 0x20, 0xff, 0x57, 0xf0, 0x7c, 0x7d, 0xed, - 0x67, 0x35, 0xbf, 0xdf, 0x16, 0xfc, 0xde, 0xbb, 0x21, 0xbf, 0x1f, 0x2f, - 0xf3, 0x3b, 0x77, 0x28, 0x28, 0x6b, 0x2b, 0x53, 0x57, 0xda, 0xe9, 0xa8, - 0x78, 0xee, 0x5b, 0xfc, 0x7d, 0x27, 0x1d, 0x35, 0xe5, 0xf7, 0xb3, 0x4b, - 0xac, 0xfb, 0xb3, 0x6f, 0xd1, 0xb9, 0x2b, 0x8e, 0x2f, 0x21, 0xea, 0x32, - 0xdc, 0x7b, 0x86, 0xe8, 0xfb, 0xd1, 0xce, 0x4b, 0x16, 0xea, 0xf5, 0x55, - 0x41, 0xea, 0x2b, 0xba, 0x29, 0x62, 0x20, 0xde, 0xfa, 0x0a, 0xfc, 0x79, - 0x5e, 0xd9, 0xc6, 0xc9, 0x0d, 0x62, 0x1f, 0xf5, 0xbc, 0xd9, 0xe9, 0x81, - 0x91, 0xbf, 0xdb, 0x25, 0xd7, 0xb1, 0x36, 0x8a, 0x81, 0x54, 0xe5, 0x81, - 0xb8, 0xd7, 0xf9, 0xd9, 0x1e, 0x4c, 0xaa, 0x75, 0xf7, 0x9f, 0x76, 0x49, - 0x3b, 0x82, 0x9a, 0xc8, 0x55, 0xa6, 0xc3, 0x3f, 0x30, 0x7e, 0xd9, 0x4f, - 0xcd, 0x97, 0xf5, 0x58, 0xf7, 0x0b, 0x7f, 0xc8, 0x1d, 0xcb, 0x99, 0x55, - 0x35, 0xee, 0x69, 0xd7, 0x98, 0x66, 0x85, 0xdf, 0xf3, 0x49, 0xd6, 0x31, - 0x7b, 0x6b, 0x6c, 0x45, 0x2d, 0xbf, 0x61, 0x3f, 0x16, 0xcc, 0x2f, 0x19, - 0x12, 0x1b, 0x8f, 0x31, 0xe6, 0xdd, 0xee, 0x7a, 0xd2, 0xa7, 0xc5, 0x8d, - 0xb5, 0x7b, 0x7d, 0xd4, 0x7e, 0xc7, 0x3c, 0x48, 0x3f, 0x24, 0xf5, 0x42, - 0x51, 0xe8, 0x82, 0xd9, 0x91, 0x12, 0x4d, 0x44, 0x77, 0x51, 0x6a, 0x84, - 0xdf, 0x3d, 0x66, 0xb3, 0x3f, 0xe6, 0x27, 0x87, 0xe5, 0x37, 0x35, 0xb2, - 0x43, 0xd5, 0xcc, 0xe9, 0x58, 0x7b, 0x8b, 0xc2, 0x90, 0xed, 0x62, 0xdd, - 0x52, 0xee, 0x49, 0xc4, 0xdf, 0x97, 0xf4, 0xb3, 0x71, 0x1e, 0xbc, 0xdb, - 0xac, 0xda, 0x5d, 0x74, 0xb5, 0x43, 0x9b, 0x8b, 0xaa, 0x2d, 0x9e, 0xa9, - 0xb1, 0x86, 0xae, 0xd3, 0x82, 0x1c, 0xae, 0xaa, 0xfa, 0x44, 0xf9, 0xbc, - 0x99, 0xe2, 0x45, 0x6e, 0xd3, 0xa5, 0xae, 0x5f, 0x64, 0xfc, 0x5b, 0x14, - 0x32, 0x22, 0xfb, 0xd2, 0x54, 0xee, 0x8b, 0xc4, 0xed, 0xb8, 0xa7, 0x5d, - 0xe5, 0x62, 0xbe, 0x25, 0xd7, 0x05, 0x54, 0x1f, 0xe4, 0x75, 0xfe, 0x5c, - 0xaa, 0xf6, 0x29, 0xdf, 0x28, 0xea, 0x75, 0x88, 0x8f, 0x7d, 0x33, 0xd9, - 0x77, 0x7c, 0x32, 0xe7, 0xd8, 0x14, 0x6b, 0xa9, 0x32, 0x7f, 0x43, 0x7f, - 0x47, 0xac, 0x19, 0x39, 0x16, 0xc8, 0x9f, 0x70, 0xeb, 0x16, 0x39, 0xb6, - 0x00, 0x6c, 0x50, 0x11, 0x6b, 0xa8, 0x1b, 0xe1, 0xe7, 0xbd, 0xcc, 0x9b, - 0xe6, 0x36, 0x70, 0xe8, 0x56, 0x64, 0xcd, 0xf2, 0x90, 0x35, 0xf7, 0xfb, - 0x51, 0xcb, 0x87, 0x9a, 0x3e, 0x67, 0xd8, 0xa0, 0x12, 0xfb, 0x0a, 0x06, - 0x15, 0x4c, 0x1f, 0x9d, 0xb3, 0x23, 0xd1, 0x25, 0x81, 0x37, 0xef, 0x43, - 0xce, 0xcf, 0xf0, 0x2a, 0x1d, 0x36, 0xcf, 0x92, 0xdc, 0xef, 0xa1, 0xc0, - 0xb6, 0x77, 0x9a, 0xf9, 0xed, 0x2c, 0xfb, 0x1f, 0xce, 0x14, 0xd6, 0x5d, - 0x34, 0xcd, 0xb0, 0x0f, 0x00, 0x3e, 0x2d, 0x9e, 0xa7, 0xe2, 0x6e, 0x0a, - 0xc6, 0xf8, 0x99, 0x16, 0x74, 0x11, 0x3f, 0x27, 0x49, 0x71, 0xf6, 0x93, - 0xe0, 0xb3, 0x4e, 0x4f, 0x45, 0xcc, 0x02, 0x19, 0xdc, 0x16, 0xbe, 0x2b, - 0x9e, 0x83, 0xfb, 0x63, 0x66, 0x13, 0xd5, 0xd6, 0x1c, 0xb7, 0x8b, 0x3a, - 0xcc, 0x9b, 0xd1, 0x7b, 0xc8, 0xe8, 0x81, 0x6e, 0xc2, 0x9c, 0xdd, 0xad, - 0xd6, 0x8b, 0x3a, 0xf8, 0xfb, 0x90, 0xfa, 0x2e, 0xe7, 0x5a, 0x7e, 0xd7, - 0xbc, 0x8c, 0xbf, 0x0f, 0x5b, 0xc8, 0xfe, 0x5d, 0x35, 0x7f, 0xd5, 0xeb, - 0x66, 0xfd, 0x46, 0x90, 0xce, 0x7b, 0xae, 0x9b, 0x6d, 0x54, 0xcb, 0xdb, - 0xb1, 0xc5, 0x5a, 0xde, 0x9f, 0xef, 0x96, 0xf5, 0x71, 0xee, 0xbe, 0xfc, - 0x9c, 0xfb, 0xe2, 0x15, 0x0f, 0x71, 0xeb, 0x5e, 0xad, 0x73, 0x4b, 0xf4, - 0x6f, 0xd1, 0xcf, 0xd2, 0x7a, 0x28, 0xac, 0xf2, 0x99, 0x90, 0xbf, 0x74, - 0x8f, 0xe2, 0x55, 0xad, 0xe7, 0xc9, 0x43, 0xcf, 0x3f, 0x20, 0xf2, 0x8e, - 0xa5, 0x9d, 0xd8, 0xaf, 0xe8, 0x01, 0x9a, 0x85, 0x5d, 0x34, 0xeb, 0x76, - 0xd1, 0xcc, 0x50, 0xdf, 0x77, 0x89, 0xe3, 0xf3, 0x4b, 0xaf, 0x76, 0xc8, - 0x7a, 0x78, 0xac, 0x29, 0x7e, 0x5f, 0x7d, 0xdf, 0x6c, 0xbc, 0x0f, 0x84, - 0x28, 0x28, 0xe2, 0x4d, 0xae, 0xb1, 0xbe, 0x44, 0x64, 0xb3, 0x37, 0x5c, - 0x47, 0x83, 0x6f, 0xb9, 0xce, 0xa3, 0x8f, 0x83, 0xae, 0x3e, 0xf6, 0xbb, - 0xfa, 0x78, 0xb0, 0x41, 0x1f, 0x59, 0x9f, 0xf3, 0x7b, 0xce, 0x16, 0x3f, - 0x69, 0x5f, 0xd1, 0x4f, 0xd4, 0x49, 0x83, 0x9e, 0x3b, 0x29, 0x1d, 0x0a, - 0x2b, 0x3b, 0x11, 0x55, 0xf5, 0x03, 0x5e, 0x7d, 0xfe, 0x31, 0x35, 0x9e, - 0x37, 0x37, 0xaf, 0xba, 0xeb, 0xab, 0x9f, 0xa3, 0x09, 0x59, 0x27, 0xaf, - 0x64, 0xfb, 0x62, 0x83, 0x78, 0x34, 0x72, 0x3b, 0x80, 0x37, 0x84, 0x6f, - 0xb8, 0x4f, 0xee, 0x6f, 0x17, 0xa0, 0xe5, 0x72, 0xad, 0xb2, 0x5f, 0xd5, - 0xf0, 0x3d, 0x1b, 0xba, 0xb3, 0x75, 0xca, 0x38, 0xff, 0x3d, 0x11, 0xcb, - 0x93, 0xeb, 0x48, 0xab, 0xaa, 0xde, 0x3a, 0x62, 0x21, 0x47, 0x60, 0x71, - 0x05, 0x71, 0xd8, 0x46, 0xb5, 0xc9, 0x52, 0x17, 0xa5, 0xca, 0x7b, 0xc2, - 0x14, 0x44, 0x1d, 0x86, 0x8c, 0x8f, 0xc9, 0x1a, 0xe2, 0xc5, 0x95, 0x1b, - 0xa2, 0x6e, 0x37, 0xae, 0x6a, 0x91, 0x53, 0xd4, 0x26, 0x70, 0xed, 0x27, - 0xaf, 0x21, 0xfe, 0x71, 0x68, 0xfb, 0x35, 0xc4, 0xee, 0x7b, 0xb6, 0x57, - 0x43, 0x6c, 0xf2, 0xd8, 0x8d, 0x05, 0x59, 0x43, 0x5c, 0xbd, 0x46, 0x23, - 0x6b, 0x88, 0x53, 0x2e, 0xac, 0x20, 0xf1, 0xf9, 0x4d, 0x57, 0x7e, 0xb7, - 0xac, 0x0f, 0x5e, 0x2c, 0xe3, 0x53, 0x59, 0x1f, 0x2c, 0xf3, 0xc1, 0xdd, - 0x7b, 0xdf, 0xc8, 0xb5, 0x20, 0xf9, 0x9e, 0x5d, 0x35, 0x6b, 0x41, 0xb2, - 0x2e, 0xd8, 0x32, 0xbc, 0xf8, 0x4e, 0xdb, 0x25, 0xec, 0xf7, 0x10, 0x63, - 0xde, 0xdd, 0xd9, 0x60, 0xbf, 0x87, 0x58, 0x83, 0xfd, 0x1e, 0xdc, 0xba, - 0xdf, 0x8d, 0xa7, 0x80, 0x7f, 0x61, 0x17, 0x81, 0x7b, 0xb1, 0x5f, 0x43, - 0x94, 0xce, 0x97, 0x71, 0xe6, 0x3d, 0x94, 0x54, 0x38, 0xf3, 0xfc, 0x92, - 0xd6, 0x47, 0xfd, 0x35, 0xfa, 0xc8, 0x0b, 0x77, 0x46, 0x54, 0xce, 0x8f, - 0x96, 0x57, 0xc7, 0x25, 0xaf, 0x8e, 0x87, 0xbc, 0xe2, 0x1e, 0xa7, 0x41, - 0xbf, 0x41, 0x13, 0xdc, 0x83, 0xff, 0x97, 0xc2, 0xd8, 0xa7, 0x86, 0xe8, - 0x0b, 0xdd, 0x0a, 0xeb, 0xb9, 0xe4, 0xf5, 0x2c, 0xcb, 0xab, 0x3e, 0x8f, - 0xfe, 0x36, 0xc2, 0xfb, 0x1a, 0x1f, 0xee, 0xf7, 0x1d, 0xbb, 0xf2, 0x0b, - 0x91, 0x17, 0x50, 0xed, 0x27, 0x6a, 0x0c, 0x71, 0x48, 0xc8, 0xd2, 0xba, - 0x1f, 0xf9, 0x2b, 0xfa, 0x1c, 0x6a, 0xa7, 0x20, 0x7f, 0x9a, 0x16, 0xcd, - 0x35, 0x38, 0xa3, 0x5d, 0xe1, 0x08, 0x91, 0xff, 0xeb, 0xea, 0xdb, 0x7f, - 0x72, 0xdf, 0xf4, 0x79, 0x6d, 0x33, 0xdf, 0xae, 0x8a, 0x69, 0x54, 0xe7, - 0x4d, 0x22, 0x7e, 0xb4, 0x2b, 0x69, 0xd8, 0x09, 0x91, 0x7f, 0xda, 0x69, - 0x23, 0x56, 0x16, 0x67, 0xd9, 0xef, 0x4c, 0x22, 0xd7, 0xb9, 0xf3, 0x92, - 0x45, 0xa7, 0xb2, 0x57, 0x0f, 0x48, 0x5e, 0x79, 0x5a, 0xec, 0xd3, 0x89, - 0x7d, 0x1d, 0x27, 0xd8, 0x3e, 0xc7, 0x19, 0x60, 0xce, 0x15, 0x5b, 0x68, - 0x91, 0x91, 0xbc, 0xdf, 0x2e, 0x88, 0x58, 0x1f, 0xeb, 0xa4, 0x1c, 0xf6, - 0x6b, 0x35, 0x16, 0x9a, 0xf9, 0xb9, 0x3d, 0xb4, 0x9c, 0x07, 0xcf, 0x35, - 0xa9, 0xfd, 0x53, 0xd0, 0xd6, 0x47, 0x5d, 0xf6, 0xdf, 0x32, 0xed, 0x1e, - 0x11, 0x79, 0x97, 0x8b, 0xb9, 0xa7, 0xe5, 0x67, 0xe1, 0x55, 0xf5, 0x0e, - 0x7e, 0x5f, 0xf1, 0x75, 0x8a, 0x75, 0xb9, 0xf3, 0x00, 0xdd, 0x7f, 0xde, - 0x78, 0xe5, 0xe4, 0xb6, 0xf0, 0x8a, 0x93, 0xac, 0xe0, 0x15, 0xf7, 0xb3, - 0x35, 0x76, 0xf9, 0xe3, 0x1e, 0xb9, 0x9f, 0x05, 0x68, 0xb0, 0x13, 0x58, - 0x2c, 0x09, 0x5a, 0x1a, 0xe3, 0x91, 0x70, 0xdc, 0x3f, 0x46, 0x99, 0xe2, - 0x35, 0x4a, 0xe5, 0x60, 0xe7, 0xf9, 0xb3, 0xf0, 0x37, 0x7b, 0x64, 0x9c, - 0x46, 0xdf, 0x03, 0xbd, 0xb2, 0x9b, 0xdb, 0x37, 0xef, 0x91, 0x39, 0xdb, - 0xee, 0xf3, 0xed, 0x7c, 0xfe, 0xc9, 0x70, 0xf5, 0xf9, 0x1d, 0x7c, 0xbe, - 0x2b, 0x89, 0x39, 0x34, 0x2e, 0x21, 0x36, 0x39, 0x4c, 0x69, 0x9e, 0x9f, - 0x4c, 0x91, 0x6d, 0xeb, 0x65, 0xd6, 0x57, 0x4b, 0xba, 0x5d, 0x37, 0xb7, - 0x0b, 0x89, 0x39, 0x31, 0xb8, 0xcd, 0x6c, 0x76, 0x84, 0xdb, 0xed, 0x27, - 0xff, 0x65, 0x8b, 0x32, 0x4b, 0x9a, 0x57, 0x75, 0x2e, 0xfe, 0x2f, 0xba, - 0x65, 0x6e, 0xd5, 0xae, 0xb0, 0xa4, 0xdf, 0xb0, 0x88, 0x7b, 0x22, 0xb7, - 0xe3, 0x19, 0xc1, 0x87, 0x91, 0x31, 0xab, 0xfc, 0x7e, 0xec, 0x31, 0x26, - 0xf6, 0x7c, 0xe5, 0x31, 0xb0, 0x5e, 0x1c, 0xb7, 0xcd, 0x74, 0x39, 0x6f, - 0x6d, 0x6d, 0x9f, 0xbc, 0x7f, 0x67, 0x8f, 0xdc, 0x7f, 0xb5, 0x53, 0xed, - 0x15, 0xa8, 0x6d, 0xce, 0x17, 0x90, 0xa7, 0x2d, 0x68, 0xe3, 0x5f, 0x80, - 0xbe, 0x34, 0xf8, 0x3b, 0x8f, 0x27, 0x89, 0x3e, 0xf6, 0xf6, 0xe8, 0x3d, - 0x17, 0xe5, 0xb8, 0x4e, 0x70, 0x7f, 0x13, 0x3c, 0x2e, 0x7d, 0x3e, 0xc6, - 0xc7, 0x5e, 0xf3, 0x8b, 0x67, 0x05, 0xf9, 0x39, 0x2c, 0x03, 0x53, 0xc1, - 0x64, 0x6a, 0x58, 0xce, 0x73, 0x25, 0xae, 0x1b, 0x2e, 0xc7, 0x75, 0xe7, - 0xb2, 0xc7, 0x7b, 0x10, 0xcf, 0x30, 0x2e, 0xf1, 0x7c, 0x87, 0x9e, 0xe1, - 0xb6, 0xa8, 0x63, 0x48, 0xf3, 0x67, 0x9b, 0xca, 0xef, 0xa9, 0xe7, 0x15, - 0x99, 0x2f, 0xa1, 0xed, 0x16, 0xee, 0xbd, 0x97, 0x9f, 0x21, 0x6d, 0x57, - 0xe3, 0xf7, 0x50, 0x5d, 0x4e, 0x4c, 0x3d, 0x8f, 0x6d, 0x14, 0x8b, 0x15, - 0xeb, 0x8a, 0x1e, 0x7c, 0xb6, 0x51, 0xac, 0x44, 0xe4, 0x39, 0xfb, 0x26, - 0xea, 0xe4, 0x15, 0x72, 0x1c, 0xa0, 0x27, 0xe6, 0x1d, 0xda, 0xc1, 0x73, - 0xf5, 0x27, 0x06, 0xea, 0x86, 0x4b, 0x24, 0x73, 0x9f, 0x98, 0xc6, 0x59, - 0x7b, 0xf8, 0xac, 0xc1, 0x74, 0xce, 0x3a, 0xa5, 0x80, 0xdd, 0x46, 0xcd, - 0x2c, 0xab, 0xbf, 0x4f, 0x03, 0xec, 0xeb, 0x41, 0x66, 0xed, 0x70, 0x82, - 0x20, 0x6f, 0x11, 0xf3, 0x18, 0xf3, 0xc4, 0x44, 0x11, 0xfc, 0x6c, 0xd0, - 0x63, 0x79, 0xa2, 0x47, 0xf3, 0x03, 0xe6, 0x37, 0xc9, 0xb6, 0x2a, 0xd7, - 0x23, 0x66, 0x9c, 0xfb, 0x91, 0x28, 0xfe, 0x25, 0x7d, 0x24, 0xf6, 0x71, - 0x01, 0x1d, 0xf5, 0xbc, 0xff, 0x39, 0x4d, 0x27, 0xd1, 0xef, 0xad, 0xcb, - 0xe7, 0xa9, 0x6d, 0xc9, 0x67, 0xd0, 0x43, 0x3e, 0x3f, 0x54, 0x7c, 0x53, - 0x62, 0x1e, 0x0d, 0xd2, 0x4c, 0x0e, 0xb9, 0x60, 0x9f, 0x47, 0x0d, 0x66, - 0x2e, 0xc5, 0x7a, 0x29, 0x55, 0xd1, 0x4b, 0x17, 0xe2, 0xfe, 0x18, 0x64, - 0x1c, 0x7b, 0xd1, 0xa9, 0x1c, 0x20, 0x8c, 0x63, 0x1f, 0x0d, 0x2c, 0xec, - 0xe4, 0x7b, 0x69, 0x35, 0x3e, 0x1a, 0x53, 0x7b, 0x15, 0x44, 0xac, 0x09, - 0xd6, 0x8f, 0x73, 0x2c, 0xcb, 0xe9, 0xdc, 0xdd, 0xb4, 0x18, 0xea, 0xa5, - 0xfe, 0x05, 0xbd, 0x7f, 0x0b, 0xc6, 0x3a, 0xd4, 0x2b, 0x75, 0x92, 0x1e, - 0xf7, 0x6f, 0x89, 0x38, 0x85, 0x75, 0xed, 0x57, 0x35, 0xee, 0x9d, 0x9b, - 0xe8, 0xa5, 0x92, 0x92, 0xd9, 0xd2, 0x1b, 0xf1, 0x28, 0x39, 0xf1, 0xd1, - 0xff, 0x15, 0xfc, 0xdf, 0x7f, 0x0d, 0xb5, 0x38, 0xd0, 0xd1, 0x16, 0x25, - 0xb3, 0xb5, 0xb4, 0xe8, 0xe5, 0x71, 0xe3, 0x7a, 0xe9, 0xa7, 0x33, 0xd1, - 0x57, 0x85, 0xed, 0x1f, 0xb8, 0xc6, 0xed, 0x84, 0x6d, 0xd2, 0x7a, 0xc3, - 0x8b, 0x0f, 0xf5, 0xde, 0x9c, 0x9a, 0x17, 0x65, 0xce, 0x27, 0xe3, 0x37, - 0x33, 0xe9, 0xaf, 0xe5, 0xc9, 0x8f, 0xe9, 0xe4, 0xbc, 0x45, 0x93, 0x59, - 0xec, 0x81, 0x38, 0xc6, 0x72, 0xed, 0xb6, 0x17, 0xdc, 0x9e, 0xc0, 0x67, - 0xe3, 0x2c, 0xfb, 0xec, 0xb7, 0xe7, 0x2c, 0x99, 0x7f, 0x27, 0xf6, 0xdb, - 0x6b, 0x11, 0x7a, 0xd4, 0xb4, 0xfb, 0xf7, 0x68, 0x7b, 0x90, 0xca, 0xa1, - 0xce, 0x90, 0x3f, 0x0b, 0xdc, 0x3e, 0xdb, 0x43, 0xa9, 0x3c, 0x9e, 0x03, - 0x7b, 0x87, 0xbe, 0xf3, 0xf1, 0xb2, 0x9c, 0xd7, 0x7e, 0x7e, 0x36, 0xf6, - 0x0e, 0x98, 0x2c, 0x8e, 0x88, 0x1c, 0x3c, 0xe8, 0x66, 0x39, 0x9f, 0xe3, - 0x34, 0xeb, 0xa9, 0x57, 0x14, 0xa6, 0x74, 0xc9, 0x77, 0x4a, 0xc8, 0xf7, - 0xb8, 0x98, 0x8f, 0x54, 0xde, 0x60, 0xbc, 0xa6, 0xe3, 0x0c, 0x5d, 0x7c, - 0x1c, 0x50, 0x3a, 0x04, 0xd7, 0xee, 0xdd, 0x23, 0xf2, 0x13, 0x6d, 0x9c, - 0xc7, 0xe7, 0x38, 0x3d, 0xc3, 0xb8, 0xf3, 0xd9, 0x6c, 0x0b, 0xdd, 0xc8, - 0xb5, 0xd0, 0x9b, 0xb9, 0x5e, 0xba, 0x3e, 0xdf, 0x41, 0xb3, 0x8c, 0x99, - 0x67, 0xed, 0x80, 0x95, 0x66, 0xff, 0xe2, 0x6a, 0x54, 0xe4, 0x10, 0xb1, - 0xdc, 0xa1, 0x3d, 0xf0, 0x5f, 0x7c, 0x2f, 0xf3, 0x1c, 0x63, 0xef, 0x56, - 0xfa, 0x80, 0xdf, 0x99, 0xce, 0xea, 0x9c, 0x07, 0xc4, 0xe3, 0x07, 0xcb, - 0xf8, 0x75, 0x73, 0x1e, 0x31, 0x37, 0xe1, 0x91, 0x71, 0xa1, 0xeb, 0x33, - 0xf3, 0x7c, 0x7d, 0x1e, 0x71, 0x73, 0x4b, 0xc4, 0x24, 0xbe, 0x14, 0x40, - 0x7b, 0x9c, 0xb3, 0x65, 0xce, 0xa4, 0x18, 0x5b, 0x98, 0x8f, 0x41, 0xdb, - 0xb0, 0xa2, 0x43, 0x2b, 0x8f, 0x4f, 0xc6, 0x30, 0x52, 0xcb, 0xad, 0x74, - 0x26, 0xcf, 0x18, 0x24, 0xef, 0x67, 0x1f, 0x06, 0x6d, 0x7f, 0xe7, 0xa0, - 0xde, 0xd3, 0x76, 0x96, 0xfb, 0x9e, 0xce, 0x4b, 0x0c, 0x92, 0x5e, 0x6e, - 0xa7, 0x4c, 0xbe, 0x4d, 0x1d, 0xdf, 0x2d, 0xf2, 0xdd, 0xe5, 0xde, 0x12, - 0xb8, 0xb6, 0x91, 0x7e, 0x43, 0xae, 0x11, 0x6c, 0xaa, 0xf4, 0x4b, 0xa1, - 0x6b, 0xbc, 0xf3, 0x8c, 0xc6, 0xe8, 0x39, 0xb6, 0xb7, 0xfd, 0x97, 0x11, - 0x2b, 0xfe, 0x22, 0xf8, 0xa6, 0x00, 0x1e, 0xeb, 0xbf, 0x8c, 0x7d, 0x9f, - 0xfc, 0x22, 0xf7, 0x68, 0x22, 0x34, 0x2c, 0x6a, 0x46, 0xa4, 0x8c, 0x4e, - 0x89, 0xba, 0xec, 0xef, 0x08, 0xdd, 0x14, 0x71, 0x2c, 0x03, 0x78, 0x24, - 0x12, 0x26, 0x92, 0x39, 0x59, 0xa7, 0xec, 0xce, 0x9b, 0xdd, 0xe3, 0x43, - 0x14, 0xeb, 0x01, 0xdf, 0x4b, 0x99, 0x95, 0x7b, 0x22, 0x90, 0xd0, 0xf7, - 0xe6, 0x21, 0x5d, 0x63, 0xa0, 0x8f, 0xb5, 0xad, 0xd0, 0xc7, 0x6d, 0x35, - 0xd7, 0xcd, 0x9a, 0xeb, 0x1a, 0x7f, 0x63, 0xad, 0x8c, 0xed, 0x3c, 0xc9, - 0x3d, 0x98, 0x52, 0x0b, 0x92, 0xff, 0xcc, 0x43, 0x83, 0xe6, 0xfd, 0x0a, - 0x83, 0xa7, 0x56, 0x06, 0xc2, 0x9d, 0x46, 0x9b, 0x3f, 0x35, 0xf2, 0xaf, - 0xa5, 0x58, 0x12, 0xb8, 0xe8, 0xf5, 0x3d, 0x52, 0xc7, 0xa1, 0x5f, 0x4e, - 0x14, 0xd0, 0x6d, 0x6a, 0xa5, 0x8d, 0x56, 0xc5, 0x9e, 0x63, 0xc0, 0x18, - 0xb8, 0x1f, 0xcf, 0x71, 0xcc, 0x26, 0xc2, 0x3e, 0xf2, 0x90, 0xf1, 0xc3, - 0xe1, 0x6b, 0x3c, 0x9f, 0x89, 0x95, 0xff, 0x29, 0x4d, 0x8b, 0x7d, 0x7a, - 0xd0, 0x96, 0x31, 0xa4, 0xc0, 0xfc, 0x8c, 0x5f, 0xaa, 0xfc, 0xaa, 0x31, - 0xf4, 0xd3, 0xc1, 0x9a, 0x8a, 0x61, 0xbf, 0xc0, 0x32, 0x26, 0xd7, 0xca, - 0x13, 0x35, 0x6b, 0xe5, 0x53, 0x62, 0xad, 0x1c, 0xeb, 0xe4, 0x1b, 0xe5, - 0x2d, 0xea, 0x3c, 0x16, 0x8b, 0x66, 0xaf, 0x08, 0x7d, 0x13, 0x9d, 0xf0, - 0xcb, 0x3c, 0xeb, 0x04, 0xbb, 0x37, 0x86, 0xa8, 0x6d, 0xc0, 0x67, 0xcc, - 0x88, 0xdb, 0x91, 0xe1, 0x35, 0xc6, 0x14, 0x4b, 0xb9, 0x1d, 0x74, 0xbd, - 0xd0, 0xc4, 0x98, 0xef, 0x9f, 0x69, 0xad, 0x40, 0x8c, 0x0d, 0x3b, 0x28, - 0x13, 0x65, 0x5e, 0x1b, 0x0e, 0xf2, 0xbc, 0x32, 0xbe, 0x1d, 0x66, 0xf9, - 0xe3, 0x31, 0x2c, 0xe5, 0x4b, 0xef, 0xa7, 0xa3, 0x31, 0x2b, 0x3e, 0xda, - 0xc6, 0xfe, 0x8b, 0xc9, 0xff, 0x36, 0xff, 0x9f, 0x0b, 0x83, 0x36, 0x8b, - 0xcb, 0xb8, 0xce, 0xd8, 0x27, 0x5b, 0x7a, 0x7f, 0x86, 0xdb, 0xcc, 0x8c, - 0xc2, 0x0f, 0x82, 0xbf, 0x67, 0xf3, 0xbf, 0x6c, 0xb3, 0xc4, 0x7c, 0x97, - 0xbe, 0xe2, 0x84, 0x0d, 0xa1, 0xe3, 0xb1, 0x2f, 0xcd, 0x80, 0xfa, 0x8c, - 0x19, 0x33, 0xdc, 0x97, 0xeb, 0x84, 0x67, 0x58, 0x94, 0x8a, 0x1e, 0x62, - 0x39, 0xe8, 0xe0, 0x4f, 0xd4, 0x6a, 0xed, 0xa4, 0xcc, 0xc8, 0xa0, 0xaa, - 0xd5, 0xfa, 0x59, 0x83, 0x5a, 0x2d, 0xdc, 0xc7, 0x38, 0x60, 0xbe, 0x74, - 0x7b, 0x26, 0xea, 0x7e, 0x2f, 0x19, 0xa9, 0xe8, 0x2e, 0x81, 0x99, 0x96, - 0x96, 0x1f, 0xe6, 0x3e, 0xc4, 0xac, 0xd4, 0x28, 0xf7, 0x35, 0xef, 0xee, - 0x7f, 0xe9, 0xf6, 0x44, 0x14, 0xed, 0xfc, 0x35, 0xed, 0x62, 0x24, 0xda, - 0x2e, 0xa3, 0x7d, 0xe9, 0x97, 0xf1, 0xa8, 0x1e, 0xa7, 0xfb, 0x5e, 0x8c, - 0x07, 0xf2, 0xc5, 0x9f, 0x4b, 0xef, 0xd0, 0xf5, 0x1c, 0xfc, 0x71, 0x43, - 0xd5, 0x5f, 0x59, 0xe4, 0x2c, 0x31, 0x06, 0xbc, 0x72, 0xd0, 0xb7, 0x96, - 0xfb, 0x41, 0x29, 0x55, 0x95, 0xdb, 0x52, 0x1d, 0x73, 0x97, 0x3e, 0x58, - 0x2f, 0xd9, 0x97, 0x60, 0x43, 0x61, 0x3f, 0x9d, 0x92, 0xdf, 0x06, 0xde, - 0x83, 0x6f, 0xf4, 0x34, 0xeb, 0x2f, 0x99, 0x9f, 0xc4, 0xba, 0x94, 0x75, - 0x98, 0x94, 0x9f, 0x44, 0xd5, 0x4f, 0x3c, 0x48, 0x1e, 0xee, 0xaf, 0xe4, - 0x49, 0xba, 0xd6, 0xd8, 0x03, 0xae, 0x35, 0x76, 0xd3, 0x95, 0x27, 0x19, - 0x12, 0xf8, 0xac, 0x82, 0xa9, 0x42, 0x0a, 0x53, 0x01, 0x7b, 0x49, 0xdd, - 0xb6, 0x58, 0xd6, 0x6d, 0xbb, 0x37, 0xd1, 0x6d, 0x5e, 0xbe, 0xea, 0xaa, - 0xd2, 0x23, 0x91, 0x28, 0x6c, 0x0c, 0xf6, 0x59, 0xfa, 0xfb, 0xe2, 0x28, - 0xeb, 0x91, 0x28, 0xeb, 0x91, 0x11, 0xd6, 0x23, 0xc3, 0xac, 0x47, 0x6c, - 0xa6, 0x81, 0xc5, 0x63, 0xff, 0x98, 0xf5, 0x34, 0xec, 0xc7, 0x18, 0x3d, - 0x53, 0x84, 0x4e, 0x1e, 0x61, 0x0c, 0xf4, 0x31, 0xad, 0xcd, 0xb7, 0x33, - 0xff, 0x4a, 0xdc, 0x53, 0xed, 0xd7, 0x60, 0xdf, 0x18, 0xc4, 0x86, 0x7f, - 0x08, 0xbd, 0xf3, 0xb2, 0x43, 0x7d, 0xbe, 0xeb, 0x39, 0xd0, 0x79, 0x0d, - 0x7b, 0x6b, 0xbc, 0x08, 0xd9, 0xc6, 0xbe, 0xc7, 0xdf, 0x1e, 0x1a, 0xe3, - 0xbe, 0xf7, 0xf9, 0x32, 0x3c, 0x2f, 0x8f, 0x47, 0x1d, 0xb3, 0x8b, 0x65, - 0x60, 0x52, 0xc9, 0xc0, 0x64, 0x45, 0x06, 0x9c, 0x34, 0x8f, 0xa4, 0x73, - 0xa1, 0x83, 0x06, 0x8f, 0xc4, 0xf7, 0x76, 0xb2, 0xfc, 0x22, 0x67, 0xa2, - 0xb2, 0xff, 0x90, 0x9f, 0xa6, 0x43, 0x41, 0xb5, 0x6f, 0x91, 0xc5, 0x76, - 0xf3, 0x27, 0x94, 0xc9, 0xbd, 0xcb, 0xb8, 0x84, 0xe5, 0xd4, 0xc4, 0xf1, - 0x45, 0xc4, 0x45, 0xd9, 0x6f, 0x68, 0x15, 0x71, 0xa5, 0x45, 0xd1, 0x16, - 0xc7, 0x91, 0x61, 0xd6, 0x71, 0xd1, 0x55, 0x23, 0x32, 0x16, 0x33, 0x2e, - 0xf7, 0x62, 0x5f, 0xfa, 0x6f, 0x17, 0x1f, 0xeb, 0x95, 0xf5, 0xb9, 0x4f, - 0xed, 0x95, 0xfa, 0x84, 0x79, 0x34, 0x14, 0x13, 0xbe, 0x5b, 0xd3, 0x25, - 0x69, 0x3f, 0x17, 0x79, 0xbe, 0x97, 0xa2, 0xc3, 0x3c, 0xdf, 0x6d, 0xca, - 0x76, 0x3a, 0x7c, 0x5d, 0xd8, 0x65, 0xb6, 0xa1, 0xbd, 0xd8, 0xd3, 0xdf, - 0x8c, 0x47, 0x9f, 0xe2, 0x77, 0x62, 0x1f, 0xa1, 0x2f, 0xe3, 0x79, 0xcc, - 0xbd, 0xd0, 0x1f, 0x3f, 0x61, 0x1b, 0x8d, 0xf7, 0x82, 0x1f, 0xf9, 0x7b, - 0x61, 0x8c, 0x2e, 0x64, 0x75, 0x1f, 0xde, 0x23, 0xe3, 0x39, 0xf4, 0xc3, - 0x47, 0xbb, 0xed, 0xf7, 0x44, 0x4d, 0x88, 0xf1, 0x8d, 0xda, 0x3e, 0x7d, - 0x45, 0xf5, 0x09, 0x7b, 0x79, 0xb6, 0xf0, 0x18, 0x76, 0x13, 0xf6, 0x74, - 0x5a, 0x14, 0x7b, 0x6d, 0x36, 0x0b, 0x9f, 0x75, 0x51, 0xf8, 0x1e, 0x0f, - 0xef, 0xad, 0xec, 0xff, 0x79, 0x57, 0xcd, 0xb9, 0x75, 0xb6, 0x5b, 0x47, - 0x05, 0x46, 0xeb, 0xc7, 0x1e, 0xf4, 0xa2, 0x66, 0xf5, 0x4f, 0xc5, 0x35, - 0x63, 0x01, 0xd7, 0x3e, 0xa7, 0xae, 0x7d, 0x56, 0x60, 0x63, 0x63, 0xbc, - 0x95, 0xf5, 0xa2, 0xe0, 0x77, 0x9e, 0x67, 0x7b, 0x98, 0xf9, 0x3d, 0xbc, - 0xc4, 0xcf, 0x9d, 0x16, 0xf4, 0xd4, 0xf4, 0x00, 0x2d, 0x20, 0x03, 0x6d, - 0x8a, 0xff, 0x23, 0x56, 0xc2, 0xaf, 0xc7, 0xdd, 0x88, 0xce, 0x63, 0xb0, - 0xcf, 0x3c, 0x56, 0x8c, 0xc9, 0xf2, 0xc5, 0x0a, 0x61, 0x5f, 0x7a, 0x1e, - 0xbe, 0x0e, 0xea, 0x5e, 0x0e, 0x20, 0x9f, 0x8a, 0xfb, 0xb0, 0x87, 0x62, - 0x49, 0xf4, 0x0b, 0xed, 0x34, 0x0d, 0xfe, 0xa8, 0x86, 0x16, 0xee, 0xfb, - 0x3a, 0xd4, 0x7d, 0xad, 0x62, 0x2e, 0xc8, 0xc0, 0x7b, 0xf4, 0xbb, 0xf1, - 0x5e, 0xbc, 0x1f, 0xf7, 0xe1, 0x79, 0xf2, 0xb9, 0xdd, 0xac, 0xb7, 0xe3, - 0xa3, 0xf2, 0x59, 0xc6, 0x35, 0x79, 0xad, 0xdb, 0xf6, 0xee, 0xaf, 0x9c, - 0x3f, 0x9f, 0xda, 0x83, 0x08, 0xf3, 0xd7, 0x41, 0x05, 0x11, 0xfb, 0xc4, - 0xb5, 0x3e, 0x9f, 0xf0, 0x6b, 0x6d, 0xfe, 0xe4, 0x79, 0x9d, 0xe3, 0xe3, - 0x33, 0xb9, 0x77, 0x84, 0xcf, 0x9e, 0x4e, 0xf6, 0xf9, 0x0a, 0x05, 0x8c, - 0xb7, 0xcf, 0x97, 0x60, 0x19, 0x98, 0xc8, 0xc5, 0x4b, 0x19, 0xa1, 0x6b, - 0x18, 0xeb, 0x76, 0x45, 0xcc, 0x69, 0xa3, 0x47, 0x60, 0x3e, 0x7e, 0x1f, - 0x7f, 0x67, 0x39, 0xcc, 0xb2, 0x1c, 0x66, 0x59, 0x0e, 0xb3, 0x2c, 0x87, - 0xec, 0xab, 0x7e, 0x2b, 0xcb, 0x72, 0xc8, 0xb6, 0xe4, 0x15, 0xb6, 0x25, - 0x52, 0x76, 0x63, 0x2a, 0xbe, 0xa9, 0x65, 0x17, 0xeb, 0x7f, 0x6e, 0x1f, - 0x47, 0xcb, 0x2a, 0xec, 0x37, 0xf9, 0x8e, 0x0f, 0x55, 0xcb, 0xec, 0x0d, - 0x96, 0xd9, 0xa6, 0xf1, 0x1e, 0xba, 0x95, 0xc7, 0x9c, 0x45, 0xac, 0x39, - 0xd6, 0xd5, 0x09, 0x3f, 0xb0, 0x56, 0x80, 0xe5, 0x09, 0x58, 0x33, 0xc2, - 0x74, 0xef, 0xa1, 0xdb, 0xac, 0xaf, 0x6f, 0xe5, 0x21, 0xc3, 0x07, 0xd4, - 0x71, 0x84, 0x65, 0x18, 0xf6, 0xcf, 0xf6, 0xdd, 0xc8, 0x19, 0x8c, 0xc9, - 0x02, 0x66, 0x8a, 0xa0, 0x4f, 0x05, 0x4e, 0xe3, 0x79, 0x5f, 0x65, 0xbd, - 0x8f, 0x18, 0x1e, 0xec, 0xc5, 0x19, 0x1f, 0xdb, 0x8b, 0xf0, 0x75, 0xd6, - 0xa7, 0xe7, 0xf3, 0x36, 0xcb, 0x7d, 0x17, 0xfd, 0x59, 0x1e, 0x76, 0x1a, - 0x34, 0xe2, 0xe3, 0x02, 0x89, 0xd8, 0x98, 0x31, 0x8e, 0xb1, 0x0f, 0x3a, - 0x86, 0xe0, 0x93, 0xdb, 0x98, 0x23, 0xa6, 0xfd, 0x3b, 0x7b, 0xb1, 0x9f, - 0x7e, 0xcc, 0x68, 0x56, 0xb1, 0x46, 0x7c, 0x47, 0xfb, 0x1e, 0x85, 0x4d, - 0x71, 0xdc, 0x68, 0x0d, 0x12, 0xbf, 0x43, 0x11, 0x65, 0x7a, 0xd4, 0xea, - 0xaf, 0x0b, 0x7c, 0xbf, 0xa0, 0xd7, 0x58, 0xdc, 0x8f, 0xfa, 0x72, 0xfa, - 0xaa, 0x7f, 0x7c, 0x8c, 0x9e, 0x2d, 0xa2, 0xdf, 0x97, 0x29, 0x13, 0x82, - 0x3e, 0x8a, 0x44, 0xd7, 0x49, 0xd2, 0xae, 0x95, 0x71, 0xe7, 0x63, 0xde, - 0x3a, 0xce, 0x8a, 0x0b, 0x9c, 0xdc, 0xc2, 0xfa, 0x05, 0xb4, 0xf9, 0x3e, - 0xf3, 0x5a, 0x14, 0x75, 0x69, 0x4a, 0xbf, 0xbd, 0xce, 0x3a, 0x07, 0x73, - 0x86, 0xe3, 0x8d, 0x75, 0xda, 0x9a, 0xd2, 0x69, 0xb6, 0x4b, 0xa7, 0xa5, - 0xcb, 0x3a, 0x8d, 0x79, 0x43, 0xe8, 0xb2, 0xa0, 0xa8, 0x8d, 0x4e, 0xab, - 0xef, 0xc0, 0x87, 0xbb, 0x85, 0xee, 0x62, 0xdd, 0x3f, 0x84, 0x3d, 0xc8, - 0x1c, 0xdf, 0x31, 0xa1, 0x43, 0x34, 0x7f, 0x3f, 0xbc, 0x4f, 0xca, 0x45, - 0xab, 0xd0, 0x07, 0xe9, 0x29, 0xe8, 0x2d, 0xaf, 0xf6, 0x0f, 0x72, 0x3b, - 0xb4, 0xb7, 0xc3, 0x2f, 0xb2, 0x3e, 0x5b, 0x8c, 0xc2, 0xa7, 0x6d, 0x53, - 0xbe, 0x0f, 0xf6, 0x14, 0xc3, 0x5a, 0x17, 0xc6, 0xaa, 0xf5, 0x59, 0xb7, - 0x8a, 0x6b, 0x20, 0x0e, 0x89, 0x39, 0x6f, 0x88, 0x11, 0x2c, 0x60, 0x04, - 0xbe, 0x27, 0xc0, 0xf4, 0x82, 0x7e, 0x61, 0x3b, 0xf0, 0x2e, 0xad, 0x09, - 0xd9, 0x78, 0x57, 0x60, 0x97, 0x0c, 0x5f, 0x9b, 0x19, 0x7d, 0x54, 0xf4, - 0x33, 0xb3, 0x5c, 0xd1, 0x8f, 0x73, 0xd9, 0xf7, 0x60, 0x37, 0x44, 0x5f, - 0x97, 0x86, 0xa4, 0x0e, 0x5c, 0x2c, 0x98, 0xd8, 0xe3, 0x0c, 0x7d, 0xe6, - 0xbe, 0xea, 0x71, 0xa2, 0x1f, 0x5a, 0x1f, 0x6c, 0x45, 0xf6, 0x18, 0xd7, - 0x76, 0x61, 0x8e, 0x1c, 0x17, 0x0f, 0x7d, 0x8f, 0xdf, 0x8f, 0x73, 0x9b, - 0x8f, 0xe7, 0x76, 0x79, 0x3c, 0x88, 0xed, 0xe1, 0x9e, 0x77, 0xe9, 0x96, - 0x1a, 0xcf, 0xad, 0xf2, 0x78, 0xbe, 0xab, 0xc6, 0x43, 0x69, 0x63, 0xbc, - 0x5b, 0xe1, 0xfe, 0x2d, 0x3f, 0xbb, 0x35, 0xce, 0x38, 0x26, 0xbd, 0x0c, - 0x3a, 0xdf, 0xa5, 0xf8, 0xc9, 0x1d, 0x47, 0x75, 0xf7, 0x35, 0x32, 0xbc, - 0xce, 0xfa, 0xf7, 0xb6, 0xc0, 0x31, 0x7d, 0x8c, 0x63, 0x70, 0x9e, 0x32, - 0xd0, 0xd3, 0xe9, 0x10, 0xf6, 0xe1, 0x1d, 0xe3, 0x71, 0xb3, 0x3f, 0x36, - 0xca, 0x9f, 0x22, 0xbe, 0x26, 0xe2, 0xbe, 0xea, 0xfe, 0xaf, 0xd3, 0xed, - 0x79, 0xe8, 0x72, 0xe0, 0x58, 0xb9, 0x57, 0xef, 0xed, 0x15, 0x19, 0xdf, - 0x4d, 0x78, 0xc6, 0x77, 0x11, 0xdb, 0x1d, 0x05, 0xce, 0x37, 0x11, 0x07, - 0x9e, 0x50, 0xbf, 0x5f, 0x92, 0x2e, 0xe2, 0x59, 0x5e, 0x7a, 0x69, 0xcc, - 0x95, 0x1f, 0x87, 0xbc, 0x14, 0x87, 0xf5, 0x8c, 0x6d, 0x36, 0x19, 0x47, - 0x65, 0x9c, 0xb9, 0xa8, 0xb1, 0xd3, 0x09, 0x9e, 0x33, 0x3b, 0x6a, 0x18, - 0x09, 0x11, 0x6b, 0x68, 0xb5, 0xdb, 0xa8, 0x85, 0xed, 0xe8, 0x59, 0xc2, - 0x3e, 0x70, 0x11, 0x0b, 0x6b, 0x00, 0x17, 0x98, 0x27, 0x33, 0xd1, 0x48, - 0xf8, 0x51, 0xe1, 0x97, 0xc2, 0xbe, 0x18, 0xa0, 0x13, 0xd3, 0x1a, 0x7d, - 0xe0, 0xef, 0xcb, 0xd8, 0x0b, 0x34, 0xca, 0xe3, 0x47, 0xfc, 0x78, 0xc0, - 0x7a, 0x93, 0xed, 0xd2, 0x05, 0x11, 0x97, 0x79, 0x9a, 0xd2, 0x2c, 0xa7, - 0xc7, 0x85, 0x9c, 0x1a, 0x7d, 0x2c, 0x45, 0x2c, 0x57, 0xc8, 0x43, 0x18, - 0x44, 0x0c, 0x50, 0xf9, 0x3a, 0x3c, 0xca, 0x15, 0xb5, 0x57, 0x42, 0x12, - 0xba, 0x63, 0xeb, 0x31, 0x89, 0xe4, 0xa7, 0x8e, 0xc5, 0xb8, 0x31, 0x59, - 0xa3, 0xda, 0x51, 0xf8, 0x69, 0x2a, 0x9e, 0x88, 0xfc, 0xf8, 0xf2, 0x6f, - 0xe9, 0xb8, 0xe3, 0x06, 0xe7, 0x44, 0x6e, 0xe8, 0xcb, 0x45, 0x69, 0x83, - 0xd3, 0xec, 0xd3, 0x67, 0x8e, 0xb8, 0x31, 0x49, 0x24, 0x37, 0x21, 0x62, - 0x39, 0xfb, 0x28, 0xbe, 0x30, 0x42, 0x0f, 0x64, 0xa1, 0xc3, 0x68, 0x3d, - 0x6e, 0xe3, 0x57, 0x72, 0x20, 0xe3, 0x23, 0x94, 0x28, 0x82, 0x46, 0x3e, - 0xc6, 0x4a, 0xcc, 0x7b, 0x39, 0xac, 0xef, 0xf3, 0xf7, 0x02, 0x7e, 0x1b, - 0xe6, 0x0f, 0x54, 0xbc, 0xbc, 0x97, 0x26, 0x16, 0xc8, 0x49, 0x45, 0xef, - 0x15, 0x7b, 0x79, 0xa7, 0xa2, 0x43, 0x2a, 0xb6, 0x13, 0xe6, 0xf3, 0x88, - 0x97, 0x59, 0x74, 0x7f, 0x36, 0xe2, 0xa4, 0x48, 0xc6, 0x2c, 0x88, 0xfb, - 0x60, 0xb0, 0xed, 0xdd, 0xcd, 0x3a, 0xe4, 0x94, 0x88, 0x5b, 0x30, 0x52, - 0x99, 0x47, 0x7b, 0xc4, 0x1c, 0xba, 0x08, 0x7e, 0x5a, 0x2a, 0xf7, 0xaa, - 0x6a, 0x5b, 0x22, 0x93, 0x79, 0xc1, 0xfc, 0x6d, 0xdb, 0x89, 0x1a, 0x95, - 0xfb, 0x11, 0xf3, 0x38, 0x25, 0x70, 0x64, 0x1f, 0xfb, 0x3c, 0xa2, 0x5d, - 0x69, 0x46, 0xc4, 0x2f, 0xf8, 0xb8, 0xf0, 0xc8, 0x7e, 0xa9, 0xdb, 0xe4, - 0x79, 0x19, 0xd7, 0xe0, 0x67, 0x16, 0xb8, 0x1f, 0x55, 0xf9, 0xf4, 0xbd, - 0x14, 0xdb, 0x46, 0x9c, 0x69, 0xea, 0x8e, 0xc6, 0x99, 0x98, 0xd6, 0xc5, - 0xcd, 0x6a, 0x1a, 0xb4, 0xff, 0xf7, 0x91, 0xb6, 0xe1, 0x4c, 0x2b, 0x53, - 0xfc, 0x16, 0x08, 0x30, 0x78, 0xa6, 0xf8, 0x3c, 0x7e, 0x03, 0xc7, 0x97, - 0x14, 0xd8, 0x38, 0xcc, 0xd8, 0x06, 0x18, 0x67, 0x40, 0xac, 0x8b, 0xc5, - 0x1e, 0x0a, 0xfb, 0x32, 0x2b, 0x3d, 0xe4, 0x47, 0x3c, 0xce, 0xd6, 0xb9, - 0x1c, 0xad, 0x22, 0xef, 0x5d, 0xae, 0x47, 0xc2, 0x3e, 0x43, 0x27, 0xae, - 0xb3, 0xdf, 0xf0, 0x90, 0xca, 0xb9, 0x41, 0xcd, 0xa6, 0xce, 0xb9, 0xd1, - 0x3a, 0x45, 0xf3, 0x9e, 0x5e, 0xeb, 0x70, 0xff, 0xde, 0x18, 0x64, 0xd7, - 0x8d, 0x29, 0x10, 0x9f, 0x12, 0x73, 0x74, 0x81, 0x48, 0xce, 0x71, 0x65, - 0x1d, 0xa3, 0x85, 0xe7, 0x09, 0xfe, 0x20, 0xe2, 0x7e, 0x8f, 0xf0, 0x27, - 0xd6, 0x23, 0x7e, 0xb4, 0x1f, 0x38, 0xaa, 0xd3, 0x66, 0x9e, 0x19, 0xc5, - 0x71, 0x0f, 0xfb, 0x67, 0x1a, 0xf7, 0xca, 0x58, 0x14, 0xfb, 0x6c, 0x6a, - 0xbe, 0x10, 0x87, 0xea, 0x97, 0x39, 0x4c, 0xd9, 0x08, 0x59, 0x5d, 0xa0, - 0xd3, 0xaf, 0x4a, 0x1e, 0x37, 0x5b, 0xbb, 0xd8, 0x4a, 0x5e, 0x13, 0x7e, - 0x0b, 0x0d, 0xfb, 0x8d, 0x1e, 0x04, 0xed, 0x79, 0x8e, 0xdc, 0x6b, 0x1b, - 0xcf, 0xef, 0xd5, 0xbf, 0xc3, 0x74, 0x67, 0xe6, 0x6d, 0x87, 0xc7, 0xbc, - 0x1d, 0xec, 0x95, 0x6b, 0x67, 0x7f, 0xa1, 0xda, 0x78, 0xe5, 0xb8, 0x3a, - 0x4f, 0x22, 0x0e, 0x55, 0xa9, 0xbf, 0x78, 0x5b, 0xe8, 0x95, 0xfa, 0x58, - 0x78, 0x98, 0xf5, 0xa9, 0x94, 0xe3, 0x53, 0x1e, 0x72, 0xdc, 0x35, 0x0e, - 0xdc, 0xf2, 0xc9, 0xe5, 0x78, 0xb2, 0xa1, 0x1c, 0x4f, 0xf6, 0xca, 0x58, - 0x6c, 0xbd, 0x1c, 0xbf, 0x81, 0xbe, 0x14, 0x37, 0xca, 0x81, 0x44, 0x4d, - 0xbb, 0x3b, 0x56, 0x02, 0x9a, 0xe9, 0x78, 0x09, 0xd6, 0x0d, 0xc1, 0x97, - 0x58, 0x7b, 0x99, 0x32, 0x12, 0xf3, 0xb5, 0x6b, 0xa9, 0x5b, 0xb9, 0x17, - 0xeb, 0x34, 0xb5, 0xf7, 0x02, 0xbb, 0x43, 0x36, 0x22, 0x61, 0x19, 0x0b, - 0xd0, 0xf4, 0xeb, 0xf5, 0x1d, 0xcb, 0x47, 0x9c, 0x02, 0x21, 0xd6, 0x1d, - 0xa2, 0x73, 0x58, 0x9f, 0x56, 0xb1, 0xe4, 0x93, 0x59, 0x49, 0x07, 0xf3, - 0x88, 0xe0, 0x0f, 0xe0, 0xdb, 0x70, 0xd2, 0x9f, 0xe4, 0x39, 0x96, 0x71, - 0xe4, 0xd4, 0x72, 0x58, 0xcd, 0x1b, 0xb7, 0xc5, 0xf3, 0xaa, 0xf6, 0x92, - 0xd7, 0x71, 0x07, 0xcc, 0x57, 0xe4, 0xeb, 0x95, 0xdc, 0x64, 0xd8, 0x86, - 0x12, 0xfd, 0x37, 0xdb, 0x3d, 0xff, 0x11, 0x53, 0xec, 0xe3, 0xf0, 0x46, - 0xf1, 0x08, 0xe3, 0x4d, 0xcc, 0x29, 0x62, 0x90, 0x3a, 0x46, 0xfc, 0xc4, - 0x41, 0x6a, 0x3f, 0xcc, 0x28, 0xc0, 0x20, 0x9b, 0xf1, 0xa5, 0x71, 0x04, - 0xb9, 0xe6, 0x16, 0xdf, 0x83, 0xfd, 0xa8, 0x06, 0xad, 0x04, 0xb5, 0x21, - 0x0e, 0x81, 0xfd, 0xb0, 0xad, 0x74, 0x95, 0x8c, 0x9d, 0x16, 0x32, 0x96, - 0x58, 0x39, 0xad, 0x64, 0xec, 0xb4, 0x8a, 0xc3, 0x9f, 0x56, 0x32, 0x76, - 0x5a, 0xc9, 0xd8, 0x69, 0x25, 0x63, 0xa7, 0x99, 0xcf, 0x07, 0x18, 0xdf, - 0x02, 0x8b, 0xe8, 0x38, 0x68, 0x3b, 0xa5, 0xf2, 0x38, 0x0f, 0xfb, 0x5c, - 0x2b, 0x67, 0xef, 0xf6, 0x49, 0x39, 0x63, 0x6c, 0x22, 0xeb, 0xc9, 0xf8, - 0x5d, 0x98, 0x83, 0x57, 0x98, 0xe6, 0x1f, 0xd3, 0x99, 0x79, 0xf4, 0xd5, - 0x47, 0x13, 0x62, 0x1f, 0xdc, 0x26, 0x8a, 0xbb, 0xb1, 0xb0, 0xc9, 0x63, - 0xcd, 0x4a, 0xdf, 0xcf, 0x31, 0x6c, 0xc1, 0x27, 0xde, 0x7a, 0x15, 0x7c, - 0x32, 0xae, 0xe6, 0xab, 0xd6, 0x2f, 0x6a, 0xa1, 0x64, 0x0e, 0x74, 0x45, - 0xfe, 0xa4, 0xc5, 0x73, 0x23, 0xe8, 0xe4, 0x98, 0x1e, 0x34, 0x38, 0xa9, - 0x68, 0xf0, 0xb8, 0x18, 0x23, 0xf2, 0x0f, 0x11, 0xcb, 0x6c, 0x4c, 0x87, - 0x74, 0x76, 0x80, 0x9f, 0xc3, 0xb2, 0x70, 0x24, 0xcc, 0x3a, 0x69, 0xeb, - 0x74, 0xa8, 0x8c, 0xbd, 0x91, 0xee, 0xd9, 0x6a, 0x5d, 0xce, 0xba, 0xcb, - 0x96, 0x84, 0x95, 0x1d, 0x91, 0xb8, 0x78, 0x87, 0x5d, 0xa2, 0x13, 0xd1, - 0x83, 0xfc, 0x3d, 0x92, 0x74, 0xe8, 0x30, 0x19, 0x9d, 0x25, 0xfa, 0x11, - 0xcb, 0x41, 0x2b, 0xcb, 0xc1, 0x09, 0xe5, 0x97, 0x9c, 0x28, 0xfb, 0x25, - 0x93, 0x07, 0x90, 0x97, 0x91, 0x12, 0xeb, 0x5e, 0x3b, 0xcb, 0xbf, 0xc3, - 0x02, 0x3d, 0xb6, 0x88, 0xfd, 0x28, 0x7a, 0x71, 0x6c, 0xd2, 0x55, 0xf6, - 0xab, 0x63, 0xbe, 0x07, 0x0f, 0x08, 0xec, 0xee, 0x7b, 0x00, 0xf7, 0x9c, - 0x90, 0x7a, 0xcf, 0x47, 0xfe, 0xc1, 0x77, 0x18, 0x4f, 0x94, 0xe8, 0x31, - 0x7e, 0x67, 0x26, 0x77, 0x88, 0x9f, 0xad, 0xf7, 0x96, 0xb0, 0x63, 0x86, - 0x6f, 0x27, 0xf9, 0x3b, 0x1b, 0xbd, 0x3b, 0x22, 0xf8, 0x91, 0xf1, 0xb4, - 0x31, 0x13, 0x7d, 0xaf, 0x34, 0x3d, 0x85, 0x18, 0x3b, 0xe4, 0x24, 0x62, - 0x5a, 0x3e, 0x2f, 0xf9, 0x90, 0x58, 0xa9, 0x92, 0x0b, 0x2b, 0xf3, 0xc2, - 0xff, 0x8b, 0xc7, 0x66, 0x12, 0xd6, 0x4e, 0xe4, 0xf3, 0x93, 0x04, 0x9f, - 0x00, 0xfb, 0x53, 0x58, 0x4c, 0x67, 0xfd, 0x2e, 0x5b, 0xf1, 0xc6, 0x67, - 0x90, 0xe7, 0x96, 0x5b, 0xa4, 0x8d, 0x6d, 0x0e, 0xe2, 0x75, 0x03, 0x0b, - 0x6b, 0x9d, 0x21, 0x51, 0x1b, 0xde, 0xc1, 0x18, 0x49, 0xe7, 0x3e, 0x0f, - 0xf2, 0xf3, 0x11, 0xc7, 0x0b, 0xd0, 0xc4, 0x25, 0xb4, 0x6b, 0xa6, 0xfe, - 0x85, 0xd2, 0xef, 0xf1, 0x75, 0xb1, 0x7e, 0x99, 0xa2, 0x56, 0xb5, 0x36, - 0xa1, 0xf7, 0xad, 0x08, 0xb3, 0xec, 0x55, 0x6a, 0x9f, 0xfb, 0xcb, 0x31, - 0x3d, 0x21, 0x13, 0x35, 0x31, 0xbd, 0xaf, 0x6e, 0x62, 0xaf, 0x36, 0x93, - 0x03, 0xe4, 0xd4, 0xb5, 0x90, 0x8a, 0x55, 0x5a, 0x19, 0xda, 0x6a, 0x4d, - 0xdf, 0x76, 0xef, 0xf1, 0xb5, 0x36, 0x8f, 0x93, 0xf3, 0xa6, 0x1d, 0x54, - 0xfc, 0xd7, 0x4c, 0x67, 0xf2, 0x41, 0xb6, 0xf9, 0xd0, 0xad, 0xa0, 0x97, - 0xbf, 0x17, 0xb5, 0x2e, 0x5f, 0x0a, 0x34, 0xd3, 0xf2, 0x32, 0x72, 0x2d, - 0xfe, 0xf1, 0x80, 0xcc, 0x25, 0x4e, 0x32, 0x5d, 0x0e, 0xb3, 0x7d, 0x34, - 0xd4, 0xda, 0x11, 0xce, 0x41, 0x97, 0x88, 0xdf, 0x21, 0x0a, 0xdc, 0x3b, - 0x14, 0x64, 0xbf, 0x40, 0xae, 0x3d, 0x1c, 0xe5, 0x67, 0x7f, 0x33, 0x9f, - 0x44, 0xbc, 0xcc, 0x3c, 0xce, 0xcf, 0x9f, 0x60, 0x3c, 0x11, 0xa3, 0x66, - 0x5a, 0x5a, 0x6e, 0x66, 0xbf, 0xa0, 0x99, 0xf1, 0xc4, 0x80, 0xd9, 0xef, - 0x13, 0xef, 0x12, 0x75, 0x35, 0x9f, 0x0f, 0x1c, 0x66, 0xbe, 0xc2, 0xbb, - 0xfe, 0x5d, 0xbd, 0xab, 0xf6, 0x1d, 0xff, 0x51, 0xc2, 0xf1, 0x71, 0x3f, - 0x39, 0x37, 0xf0, 0x1b, 0x5c, 0xf3, 0x63, 0x8c, 0x9d, 0x43, 0x94, 0x99, - 0x6f, 0xe2, 0x31, 0x8c, 0xb3, 0x1f, 0x11, 0xe5, 0xe3, 0xfb, 0xc8, 0x29, - 0x4e, 0xd1, 0x5f, 0x15, 0xdd, 0x31, 0xe1, 0xfb, 0xb8, 0xcf, 0xb2, 0xb6, - 0xbf, 0x85, 0xfb, 0xf5, 0x91, 0x5d, 0xab, 0x63, 0x82, 0xe4, 0xff, 0xeb, - 0x10, 0x35, 0x7f, 0x0d, 0xb1, 0x97, 0x12, 0xe5, 0xa2, 0xa8, 0x57, 0x90, - 0xf1, 0xe7, 0xab, 0x22, 0x87, 0x96, 0xef, 0xe7, 0x67, 0xce, 0xa1, 0xdd, - 0x55, 0x8b, 0xae, 0xdb, 0x92, 0xde, 0x3f, 0x08, 0x84, 0xc8, 0xff, 0x12, - 0x72, 0x9f, 0xc4, 0xfe, 0x1a, 0x8e, 0x7d, 0x88, 0xf5, 0xfb, 0xd7, 0x70, - 0x1f, 0x7f, 0xbe, 0x84, 0xe3, 0x20, 0x8f, 0x13, 0xf6, 0x1a, 0xf9, 0x2e, - 0xd0, 0x8b, 0x87, 0xc3, 0xa6, 0xe0, 0xbf, 0xfb, 0x98, 0xa7, 0x9a, 0x44, - 0xac, 0xb1, 0x0b, 0x6d, 0xed, 0xfd, 0xc0, 0x16, 0xce, 0xd0, 0x21, 0x1c, - 0xc7, 0x3a, 0xfd, 0x4c, 0x23, 0xc9, 0x43, 0x18, 0x4f, 0x15, 0x73, 0x07, - 0x8e, 0x0e, 0x11, 0xcf, 0x27, 0xf0, 0xc7, 0x2f, 0xf1, 0x1b, 0x91, 0x4e, - 0x3f, 0xbf, 0x23, 0xc1, 0xef, 0x98, 0xc8, 0xcb, 0x71, 0xcf, 0x15, 0xfd, - 0x24, 0xe3, 0x54, 0x5f, 0xe9, 0xd3, 0xbf, 0xd1, 0x48, 0x3d, 0x78, 0x76, - 0x59, 0x56, 0xf8, 0x7b, 0x3b, 0xdd, 0xca, 0xb7, 0xd1, 0x6d, 0xb5, 0xa6, - 0x75, 0x4b, 0xf8, 0x65, 0xac, 0xc3, 0x93, 0xed, 0xb4, 0xbe, 0xdc, 0x44, - 0xd4, 0x15, 0x14, 0x6b, 0xce, 0xb7, 0xf2, 0x05, 0x7e, 0xff, 0x97, 0xfb, - 0x64, 0x5c, 0xa7, 0xc2, 0x23, 0xb7, 0x3c, 0x78, 0xe4, 0x03, 0xc1, 0x23, - 0x5f, 0xec, 0xdb, 0x98, 0x47, 0x50, 0xf3, 0x0f, 0xde, 0x08, 0x52, 0xb3, - 0xe2, 0x8f, 0x17, 0x99, 0x3f, 0x9e, 0x65, 0xfe, 0x38, 0xd6, 0x80, 0x3f, - 0x8c, 0x1a, 0xfe, 0x38, 0x2e, 0xf8, 0xe3, 0x89, 0xbe, 0x8d, 0xf8, 0xe3, - 0x98, 0x7f, 0xa3, 0x58, 0x93, 0xaf, 0x35, 0xc0, 0xef, 0x9e, 0xb3, 0xf7, - 0x31, 0xaf, 0xdb, 0xb4, 0x34, 0x8f, 0xfa, 0x84, 0xd5, 0xa8, 0x41, 0x3f, - 0x13, 0x3e, 0xd9, 0x9a, 0xf0, 0xf9, 0xc7, 0x45, 0xcd, 0xc1, 0xa2, 0xe0, - 0x2f, 0xb6, 0xff, 0xe3, 0xa8, 0xab, 0xaa, 0x9d, 0x8b, 0x56, 0xba, 0x1e, - 0xc5, 0x5c, 0x58, 0x7a, 0x2e, 0x08, 0xeb, 0xbb, 0x6a, 0xef, 0xc8, 0x40, - 0x3c, 0x4b, 0xce, 0x07, 0xe0, 0xd1, 0x95, 0xb6, 0xc0, 0x44, 0xf6, 0x1b, - 0x7d, 0xc0, 0x7f, 0x99, 0x15, 0x72, 0x9d, 0x0f, 0xf0, 0xf9, 0x90, 0xf8, - 0x6d, 0x2b, 0xc8, 0xca, 0x87, 0xc8, 0x71, 0x64, 0x9e, 0xbc, 0x9e, 0xef, - 0xa5, 0x1b, 0xf9, 0x7d, 0xb4, 0x96, 0xef, 0xa3, 0x37, 0xc5, 0xbe, 0x1a, - 0xb2, 0x36, 0x72, 0x4d, 0xcc, 0x91, 0x41, 0x47, 0x43, 0xdc, 0x66, 0x79, - 0x1f, 0xad, 0x2e, 0x6b, 0xfe, 0x06, 0x6f, 0x83, 0x5f, 0x62, 0x9d, 0xb2, - 0x66, 0xae, 0x9e, 0x67, 0x26, 0xaa, 0x79, 0x46, 0xdc, 0x03, 0x5e, 0xc9, - 0xd4, 0xd5, 0xfa, 0x22, 0x5f, 0x11, 0xb9, 0x7a, 0x41, 0x6a, 0x42, 0xde, - 0xa2, 0x11, 0x19, 0x3e, 0xea, 0x07, 0x86, 0xce, 0xb1, 0xcd, 0xe5, 0x39, - 0xb3, 0x91, 0xe7, 0xd4, 0xc7, 0x78, 0xb8, 0x43, 0xe0, 0xdf, 0xb8, 0x1d, - 0x08, 0x4f, 0x50, 0xe9, 0x69, 0xc3, 0xc6, 0x5e, 0x8f, 0x49, 0x7e, 0x9e, - 0xa1, 0xe2, 0x4d, 0xbb, 0x5c, 0xfc, 0x57, 0x8b, 0x75, 0xb1, 0x96, 0xfc, - 0x10, 0xf7, 0x19, 0x76, 0xb8, 0xb2, 0x5e, 0x43, 0xe5, 0xf5, 0x9a, 0x56, - 0x1e, 0xb7, 0x94, 0xbd, 0x19, 0x9b, 0xdb, 0x15, 0xff, 0x6f, 0x40, 0x75, - 0xeb, 0x41, 0x73, 0x7f, 0x40, 0xf1, 0x25, 0xa0, 0x79, 0x67, 0x19, 0x86, - 0x43, 0x3d, 0xa0, 0x3c, 0x0a, 0x1a, 0x0f, 0x41, 0xcc, 0xf5, 0x1e, 0x5a, - 0x03, 0x12, 0x07, 0x8d, 0x89, 0x20, 0xe6, 0x7a, 0x0f, 0x41, 0xe7, 0x7a, - 0x0f, 0xad, 0xb1, 0x01, 0x97, 0xdb, 0xcd, 0x53, 0x80, 0xe1, 0x3e, 0x85, - 0x19, 0xba, 0xce, 0x51, 0x0d, 0x7a, 0x77, 0x52, 0x0c, 0x78, 0x4c, 0x5b, - 0x50, 0x05, 0x7f, 0x18, 0xba, 0x62, 0x84, 0xa1, 0x0d, 0xb8, 0x9d, 0xe5, - 0x02, 0x34, 0xd3, 0x79, 0x4a, 0x0c, 0x30, 0x3c, 0x23, 0x80, 0x79, 0x4f, - 0x18, 0x9a, 0xf7, 0x60, 0x73, 0xc7, 0xfc, 0x0c, 0x90, 0x7b, 0x98, 0x6c, - 0xc0, 0x7d, 0x0b, 0x48, 0x79, 0x25, 0x83, 0x56, 0x5e, 0x01, 0xd3, 0x84, - 0x3a, 0x44, 0x7f, 0xd3, 0x7a, 0x0d, 0x79, 0xd8, 0x38, 0x60, 0x13, 0xd0, - 0xdc, 0xe6, 0x29, 0xa4, 0xcc, 0x3d, 0x03, 0xeb, 0x5b, 0xac, 0x6b, 0x1b, - 0x6d, 0xc0, 0x7b, 0xac, 0x17, 0x4d, 0x61, 0x61, 0x58, 0xd2, 0xc3, 0x00, - 0xac, 0x1f, 0x40, 0x69, 0x1d, 0x54, 0x47, 0xc0, 0xd3, 0xbb, 0x40, 0x13, - 0xd0, 0x7d, 0x4e, 0xc0, 0xb6, 0xa8, 0x73, 0xbf, 0x32, 0x78, 0xad, 0x6c, - 0x03, 0xf4, 0xfc, 0xaa, 0x45, 0x3d, 0xde, 0xf2, 0xa0, 0x7c, 0xe6, 0xa4, - 0xc2, 0x40, 0x46, 0x5e, 0x60, 0x83, 0xe6, 0x05, 0x70, 0x38, 0x01, 0xd3, - 0x3a, 0xb0, 0x8c, 0x5a, 0x93, 0x04, 0x34, 0x8f, 0x87, 0xc5, 0xa5, 0x1f, - 0x24, 0xc6, 0x00, 0x15, 0x63, 0x01, 0xf2, 0x65, 0x80, 0x6d, 0x4a, 0x90, - 0x5f, 0x41, 0x79, 0x01, 0x64, 0x36, 0xc8, 0xef, 0xa0, 0xb2, 0x13, 0x94, - 0x17, 0x81, 0xec, 0x25, 0x42, 0x50, 0x3f, 0x03, 0x69, 0x20, 0xbb, 0x79, - 0x8a, 0x08, 0x98, 0x9f, 0x14, 0x20, 0xc4, 0xd0, 0x00, 0xcf, 0x07, 0xc4, - 0x86, 0x31, 0x4c, 0x7d, 0x0c, 0x19, 0xf9, 0x06, 0x62, 0x06, 0x22, 0xdf, - 0xb0, 0x33, 0x1c, 0x10, 0x80, 0x85, 0xd5, 0xff, 0xff, 0xc7, 0x54, 0x58, - 0x80, 0xe9, 0x14, 0xb4, 0x8e, 0xf5, 0xf7, 0xff, 0x03, 0x22, 0x2c, 0x0c, - 0x2d, 0xf0, 0xf5, 0x88, 0x0b, 0xe5, 0x41, 0x65, 0xe8, 0x02, 0x20, 0xab, - 0x0d, 0xde, 0x26, 0x60, 0x01, 0xdf, 0x61, 0xbd, 0x80, 0xe1, 0x17, 0xb0, - 0xcc, 0xfa, 0xff, 0x7f, 0x29, 0x5c, 0x2d, 0x08, 0x00, 0x00, 0xff, 0x88, - 0x78, 0xb5, 0x98, 0x7e, 0x00, 0x00, 0x00 }; +/* 0x1f, 0x8b, 0x08, 0x00, 0x0e, 0x34, 0xe7, 0x45, 0x00, 0x03, */ + 0xdc, 0x5b, + 0x6d, 0x70, 0x5c, 0xd5, 0x79, 0x7e, 0xef, 0xd9, 0xbb, 0xf2, 0x5a, 0x92, + 0xe5, 0x6b, 0x79, 0x23, 0x16, 0x4b, 0xc0, 0xae, 0x75, 0x6d, 0x69, 0xb0, + 0x43, 0x16, 0xa1, 0x80, 0x9a, 0xd9, 0xc0, 0xb2, 0x2b, 0x33, 0x9e, 0x0c, + 0x69, 0x64, 0x50, 0x80, 0xb6, 0x4c, 0x46, 0xec, 0x1a, 0x9a, 0x4e, 0x87, + 0xd6, 0xa6, 0x6e, 0x9b, 0xc9, 0x34, 0x78, 0x47, 0x1f, 0x8d, 0xa7, 0x15, + 0xba, 0x06, 0x1b, 0xd9, 0xd3, 0xd0, 0xa0, 0x6a, 0x71, 0xf1, 0x8f, 0x8d, + 0xaf, 0xf9, 0x48, 0xaa, 0x4c, 0x4d, 0xa5, 0x18, 0x48, 0x69, 0xa7, 0x4d, + 0xfb, 0xa3, 0x9e, 0xa1, 0x5f, 0x84, 0x32, 0xfd, 0xc1, 0x74, 0xda, 0x4e, + 0x3a, 0x24, 0x53, 0x08, 0x84, 0xed, 0xf3, 0x9c, 0x7b, 0xee, 0xea, 0x6a, + 0x25, 0x7f, 0xf1, 0x91, 0x1f, 0xd5, 0xcc, 0xfa, 0xde, 0xf3, 0xfd, 0x9e, + 0xf7, 0xbc, 0xef, 0xf3, 0x7e, 0xdc, 0xe3, 0x4f, 0x8a, 0xb4, 0x8a, 0xf9, + 0xdb, 0x80, 0x5f, 0xfa, 0xc1, 0xdf, 0x2c, 0x5f, 0x37, 0x78, 0xdd, 0x0d, + 0x78, 0xbd, 0x41, 0xc5, 0xec, 0x18, 0xeb, 0xf9, 0x4f, 0x12, 0xbf, 0x01, + 0xf3, 0xbe, 0xd6, 0x9f, 0x83, 0xdf, 0x9b, 0x68, 0x1c, 0xfb, 0x0f, 0x11, + 0xeb, 0x3c, 0x7d, 0xa2, 0x7f, 0xf5, 0xfa, 0x85, 0xdb, 0x15, 0x69, 0xb9, + 0x40, 0x7b, 0x2c, 0x58, 0x52, 0xd3, 0xcc, 0x9f, 0x24, 0x54, 0x6e, 0xec, + 0xe1, 0x82, 0x2b, 0x89, 0x58, 0x6e, 0xf7, 0xc1, 0xb2, 0x2b, 0x92, 0xaf, + 0xed, 0x48, 0x17, 0xe5, 0x67, 0xf5, 0x4a, 0xd2, 0x16, 0xd6, 0x5f, 0x95, + 0x7b, 0xef, 0xc9, 0x17, 0x6e, 0xca, 0xfc, 0x68, 0x2e, 0x26, 0x09, 0x27, + 0xf7, 0xbc, 0x38, 0xdb, 0x25, 0xd1, 0x83, 0x31, 0x4f, 0xf4, 0xe5, 0x2d, + 0xe9, 0x08, 0xe7, 0x7a, 0xb3, 0xfe, 0x42, 0x9f, 0x54, 0xb6, 0xe4, 0x12, + 0xa2, 0x72, 0xdb, 0x5e, 0x2d, 0xc4, 0x9c, 0xb1, 0x58, 0xce, 0x91, 0x45, + 0x5f, 0x46, 0xee, 0x9f, 0x96, 0x44, 0x22, 0xf7, 0xe5, 0xc4, 0xba, 0x6d, + 0x92, 0xb0, 0x73, 0x4b, 0x0f, 0xff, 0xbe, 0x7b, 0xb0, 0xae, 0x5c, 0xb7, + 0x7f, 0x5e, 0xda, 0x87, 0x4e, 0x0c, 0xa2, 0xbd, 0x96, 0xe9, 0x17, 0xb9, + 0x49, 0x94, 0x5b, 0x69, 0x8f, 0xb9, 0x09, 0x29, 0xf8, 0xae, 0x14, 0x7d, + 0x91, 0xbf, 0xac, 0x59, 0x72, 0xc2, 0xed, 0x92, 0xf9, 0x9d, 0xef, 0xd5, + 0xf3, 0xa0, 0xe5, 0xfb, 0xee, 0xd2, 0xc3, 0x93, 0x2e, 0xe9, 0x3d, 0x90, + 0x08, 0xe8, 0xdd, 0xbb, 0xae, 0xec, 0xda, 0x32, 0x5e, 0x63, 0xdd, 0xa8, + 0x62, 0x5d, 0x3c, 0x97, 0x68, 0x3d, 0xe1, 0xb6, 0x9b, 0xba, 0x57, 0x6f, + 0x29, 0x60, 0xbe, 0x89, 0x1a, 0xfb, 0xe6, 0xaf, 0x2f, 0xbb, 0x49, 0x53, + 0xbf, 0x70, 0x63, 0xc1, 0x4d, 0xa1, 0xbe, 0xc7, 0xb4, 0x8d, 0x3d, 0x58, + 0x76, 0x5d, 0xd3, 0xf6, 0x76, 0xac, 0xe0, 0xf6, 0x9b, 0xfa, 0xf7, 0x6e, + 0x2e, 0xbb, 0x3b, 0x4d, 0x7d, 0x0f, 0xe6, 0xca, 0x9a, 0xfa, 0x85, 0x7b, + 0xca, 0xee, 0xa0, 0xa9, 0xdf, 0x7d, 0x73, 0xc1, 0x1d, 0x32, 0xf5, 0x89, + 0xa1, 0xb2, 0x9b, 0x43, 0xfd, 0x97, 0x13, 0x6a, 0x9b, 0x23, 0x53, 0xb5, + 0x34, 0x7e, 0x79, 0xb4, 0x0d, 0xa3, 0x6e, 0x37, 0x7e, 0xb7, 0xe3, 0xf7, + 0xc8, 0x46, 0xe9, 0x18, 0xc1, 0xf3, 0xbf, 0xba, 0x03, 0xde, 0x81, 0x47, + 0x5e, 0x42, 0x5e, 0x8f, 0xa5, 0xe4, 0x85, 0xbe, 0xd7, 0xc1, 0x43, 0x47, + 0x4e, 0xfb, 0x62, 0x8d, 0xf4, 0xa5, 0xc0, 0xbb, 0xa4, 0x3c, 0xe3, 0xb7, + 0x49, 0xec, 0xb1, 0x18, 0x78, 0xf3, 0xcb, 0x52, 0x4a, 0x26, 0x64, 0xd3, + 0xac, 0x25, 0x5b, 0x07, 0x12, 0x92, 0x77, 0xb8, 0x36, 0x4e, 0x7b, 0x26, + 0x29, 0xb1, 0xd9, 0xfc, 0x66, 0x25, 0xdb, 0x9c, 0xa2, 0x54, 0xc0, 0xbb, + 0x57, 0x29, 0x97, 0x68, 0x4b, 0x4b, 0x71, 0xfa, 0x5a, 0x19, 0x73, 0x48, + 0xd7, 0x1f, 0x5c, 0x15, 0xac, 0x95, 0xb0, 0x0a, 0xc7, 0x46, 0x65, 0xca, + 0x6b, 0xb7, 0x8a, 0xc7, 0x6e, 0x96, 0x42, 0x56, 0x92, 0x18, 0x97, 0x2a, + 0xa1, 0xa5, 0x5a, 0x1b, 0x95, 0x49, 0x4f, 0xac, 0x82, 0x47, 0x7e, 0x76, + 0xa1, 0xbd, 0x43, 0xf7, 0x45, 0x5d, 0x4f, 0x4c, 0xcf, 0x9d, 0x40, 0xbd, + 0x83, 0xfa, 0x4e, 0x6b, 0x58, 0xcf, 0xa1, 0xeb, 0xd3, 0x13, 0xd2, 0x2e, + 0x4f, 0xd5, 0x92, 0xa6, 0x6f, 0xbd, 0x5e, 0xc8, 0x3a, 0xe8, 0x37, 0x2a, + 0x13, 0x5e, 0x52, 0xc6, 0xf0, 0x1c, 0xf7, 0xb8, 0x7e, 0x0a, 0x32, 0x75, + 0xdd, 0xc1, 0xd2, 0x51, 0x3d, 0x5f, 0x3a, 0x96, 0xe3, 0x7c, 0x3d, 0xe8, + 0xf7, 0x12, 0xe8, 0xb2, 0xc4, 0xd6, 0x67, 0x99, 0x97, 0xd2, 0xb4, 0x05, + 0x79, 0xc3, 0x53, 0xf3, 0x75, 0x18, 0xf4, 0xdb, 0xe2, 0x0e, 0x58, 0x52, + 0xc6, 0x59, 0x55, 0x1c, 0x94, 0x6b, 0x0b, 0xaa, 0xe0, 0xad, 0x93, 0xa2, + 0x9d, 0x96, 0xd8, 0x0c, 0x65, 0x69, 0x4c, 0x26, 0x30, 0x46, 0xb9, 0xec, + 0xf3, 0x0e, 0xf6, 0x3d, 0xa6, 0xcf, 0xa1, 0x25, 0x57, 0x51, 0x45, 0xbf, + 0x4b, 0xd4, 0xec, 0xbd, 0xf2, 0xd2, 0xb4, 0x38, 0x38, 0xc7, 0x7a, 0xc1, + 0x9d, 0x54, 0x85, 0xa7, 0x6d, 0x89, 0xcf, 0x58, 0x32, 0xe9, 0x66, 0xa0, + 0x01, 0x87, 0xd4, 0x2e, 0x7f, 0x01, 0xfd, 0x38, 0x0e, 0xfd, 0x6a, 0x0a, + 0x7c, 0xe5, 0xfb, 0x0e, 0x47, 0x69, 0x79, 0x66, 0x1f, 0x9c, 0x01, 0xf6, + 0xf1, 0x8c, 0x87, 0x33, 0xd1, 0x67, 0x94, 0xc6, 0x19, 0x89, 0x35, 0xdc, + 0x07, 0x99, 0x3a, 0x6a, 0x4b, 0x29, 0x8b, 0x7d, 0xa1, 0x77, 0x29, 0xbb, + 0x4c, 0xd7, 0xc4, 0x74, 0x33, 0x5d, 0x1c, 0x47, 0xba, 0x02, 0x9a, 0xc6, + 0x8f, 0x92, 0xbe, 0x65, 0x7a, 0xa6, 0xa6, 0x43, 0x1a, 0xb9, 0x1e, 0x69, + 0x0b, 0xe9, 0xe2, 0x38, 0xd2, 0xb5, 0x99, 0x67, 0xcd, 0x3f, 0x6b, 0x18, + 0x74, 0x4c, 0x78, 0x36, 0xce, 0xa8, 0x5d, 0x4a, 0x4e, 0xc5, 0x9a, 0x18, + 0xda, 0x91, 0x82, 0x36, 0x5b, 0xe3, 0x43, 0xa4, 0xd9, 0xc5, 0x39, 0xb6, + 0xe8, 0xf3, 0x56, 0xb9, 0x49, 0xf2, 0x0e, 0xfd, 0xb9, 0x3e, 0xde, 0x6b, + 0x8e, 0x4c, 0xea, 0xf9, 0x48, 0xd3, 0x47, 0x31, 0x0f, 0x69, 0x7d, 0x05, + 0xb2, 0x3a, 0x08, 0x19, 0xcd, 0xca, 0x5f, 0xf8, 0x3b, 0xe5, 0xcf, 0xfc, + 0x7e, 0xf9, 0x0e, 0xf4, 0xf6, 0xdb, 0x7e, 0x5a, 0x9e, 0xf7, 0x7b, 0xe4, + 0x39, 0x3f, 0x25, 0xcf, 0x6a, 0xf9, 0x1d, 0x16, 0xe9, 0xa0, 0x4c, 0xa7, + 0xa5, 0x13, 0xfa, 0xb3, 0x09, 0xba, 0xf9, 0x38, 0xf8, 0x77, 0xb4, 0x4f, + 0xf2, 0x9b, 0x73, 0x92, 0xb8, 0x1a, 0xbf, 0x2b, 0xf0, 0xeb, 0xca, 0xd9, + 0x5a, 0x56, 0xec, 0x1c, 0x79, 0x68, 0x4b, 0x51, 0xef, 0xd9, 0x96, 0x09, + 0xff, 0x91, 0xab, 0x03, 0xd9, 0x15, 0x19, 0x01, 0x8f, 0xd5, 0xc0, 0x4f, + 0xea, 0x79, 0x07, 0xfb, 0x18, 0xd8, 0xa1, 0x79, 0xaf, 0x06, 0x28, 0xb3, + 0x69, 0xc8, 0xbd, 0x6d, 0x15, 0xbd, 0x93, 0xc0, 0x8d, 0x36, 0xab, 0x70, + 0xa4, 0x22, 0xe5, 0x23, 0x75, 0x29, 0x67, 0xe3, 0xf2, 0x90, 0x53, 0x97, + 0xe1, 0x6c, 0x8b, 0xec, 0x77, 0xc0, 0xfb, 0x9d, 0xbf, 0x6d, 0x85, 0x98, + 0xfd, 0xb8, 0xff, 0x3b, 0x78, 0x67, 0x9d, 0xc8, 0x51, 0xfd, 0x1e, 0xd4, + 0x57, 0xfc, 0xb8, 0xe4, 0x93, 0x95, 0x94, 0x2d, 0x5b, 0x54, 0xb0, 0xee, + 0x78, 0xd8, 0x06, 0x7e, 0x2c, 0x01, 0x27, 0x33, 0x5a, 0x5f, 0x4a, 0xd3, + 0xeb, 0xdf, 0xce, 0xeb, 0x6a, 0xf4, 0x77, 0x06, 0xe5, 0xac, 0xe6, 0x67, + 0x7a, 0xcc, 0xca, 0x25, 0x65, 0x6b, 0x8d, 0xe5, 0x21, 0xeb, 0x4e, 0x9f, + 0xf2, 0x8c, 0x77, 0x9f, 0x74, 0x5e, 0x89, 0x7e, 0x36, 0x9e, 0x79, 0x43, + 0x6f, 0x94, 0x46, 0xce, 0x43, 0x1a, 0xf9, 0xfc, 0x66, 0x84, 0xc6, 0x27, + 0x1b, 0xef, 0x47, 0x23, 0xef, 0x15, 0xff, 0x8f, 0x5a, 0x03, 0xda, 0x86, + 0xe4, 0x8d, 0x99, 0xaf, 0x98, 0x75, 0xf0, 0x7e, 0x8a, 0xf3, 0x7f, 0xab, + 0x1e, 0xc8, 0x4b, 0xe5, 0x22, 0xeb, 0x2c, 0x44, 0xd6, 0xf9, 0x6e, 0x64, + 0x9d, 0xef, 0x46, 0xd6, 0xa9, 0x80, 0xa7, 0xb2, 0x51, 0x41, 0x86, 0x4b, + 0x34, 0x63, 0x72, 0x08, 0x73, 0xbe, 0x2e, 0xb1, 0x1c, 0xf5, 0x3c, 0xc4, + 0x9b, 0x73, 0xe8, 0x9f, 0x93, 0xb3, 0x33, 0x15, 0x29, 0x1d, 0x89, 0xcb, + 0x1d, 0xba, 0xdf, 0x26, 0x43, 0x5f, 0xb4, 0x2d, 0x21, 0x7b, 0x92, 0x7c, + 0x0f, 0xdb, 0x6c, 0xf0, 0x99, 0xe5, 0x6f, 0x5d, 0x19, 0x94, 0xf9, 0xbe, + 0x60, 0xf6, 0x32, 0x1a, 0x8c, 0x3b, 0xf5, 0xa6, 0xc6, 0xc3, 0x45, 0x9f, + 0xb8, 0x25, 0xd9, 0x98, 0x2b, 0xfb, 0x86, 0xb3, 0x5d, 0x32, 0xe1, 0x58, + 0xd9, 0xf1, 0xfe, 0x75, 0xd4, 0x8b, 0xbc, 0x72, 0xdb, 0x80, 0x0d, 0x92, + 0x56, 0xc4, 0x7c, 0xbd, 0x2f, 0x4b, 0x05, 0xf4, 0x3b, 0x2c, 0x8f, 0x28, + 0xb7, 0xb3, 0xa9, 0x9e, 0xba, 0x1d, 0xc3, 0x3b, 0x65, 0x78, 0x97, 0x39, + 0x63, 0x1b, 0x65, 0xe2, 0xf0, 0x35, 0xa6, 0x1c, 0xb6, 0x6f, 0xb6, 0x57, + 0x96, 0xcf, 0x76, 0xaf, 0x2c, 0x87, 0x38, 0x11, 0xc5, 0x70, 0xee, 0x15, + 0xf8, 0xe4, 0x52, 0xee, 0xe2, 0xa0, 0x35, 0x0b, 0x9d, 0x5b, 0x67, 0x68, + 0xb8, 0xc2, 0xd0, 0x00, 0x5a, 0xfb, 0x20, 0x59, 0x5a, 0x97, 0xb4, 0x68, + 0x35, 0x95, 0xc9, 0xfb, 0xf0, 0x7d, 0x83, 0x6e, 0x0f, 0x74, 0x2e, 0x7c, + 0x86, 0xf8, 0xfe, 0x66, 0xc4, 0x5e, 0xf4, 0x40, 0x67, 0x93, 0xe0, 0x55, + 0x88, 0xf5, 0xc4, 0xe0, 0x14, 0xec, 0x03, 0x64, 0x55, 0x63, 0x7b, 0x3b, + 0xf0, 0xd0, 0x36, 0xd8, 0x9c, 0x30, 0xd8, 0xdc, 0x0e, 0x5c, 0x66, 0xd9, + 0x31, 0xe5, 0xa4, 0x29, 0xa7, 0x50, 0x86, 0x1d, 0x9f, 0x25, 0x2e, 0x5f, + 0x77, 0x70, 0xef, 0x51, 0x8d, 0xf7, 0xb4, 0x15, 0x40, 0x61, 0xe2, 0x35, + 0x71, 0xbb, 0x47, 0xe6, 0x6b, 0x58, 0xaf, 0x81, 0x8d, 0xdc, 0x7b, 0x94, + 0x1e, 0xd2, 0xb2, 0x5e, 0x14, 0x6c, 0x57, 0x3e, 0x49, 0x7a, 0x1f, 0xc4, + 0xde, 0x89, 0x3f, 0xa4, 0xfb, 0x2a, 0xd0, 0xca, 0x7d, 0xfc, 0x3c, 0x69, + 0xe5, 0x7a, 0xcd, 0xf4, 0x7e, 0x58, 0x1c, 0x24, 0xed, 0x27, 0xb1, 0xe7, + 0x3c, 0x30, 0x4f, 0xac, 0xd1, 0xbe, 0x51, 0xec, 0x79, 0x04, 0x78, 0x78, + 0x3b, 0xf0, 0x70, 0x37, 0xf0, 0x70, 0x18, 0x78, 0x98, 0x03, 0x16, 0x0e, + 0x01, 0x0b, 0x07, 0x81, 0x85, 0x59, 0xf0, 0x26, 0x29, 0x73, 0xc0, 0xc6, + 0x39, 0x60, 0xe4, 0x1c, 0xe6, 0x18, 0x9f, 0x15, 0xeb, 0x4b, 0xd8, 0xc3, + 0x63, 0x33, 0x99, 0x93, 0x90, 0xa5, 0x54, 0x45, 0x41, 0xfe, 0xb3, 0x43, + 0x90, 0xed, 0x7e, 0xa9, 0xfa, 0xb6, 0x94, 0x69, 0x53, 0xb7, 0xf7, 0x42, + 0xd7, 0x20, 0xef, 0x29, 0x31, 0x7f, 0x1b, 0xcc, 0xf3, 0x1f, 0x45, 0xdc, + 0xbf, 0xa3, 0x2c, 0xa6, 0x45, 0xce, 0x48, 0xc9, 0xeb, 0x75, 0x0a, 0xaa, + 0x1f, 0xfd, 0x58, 0xce, 0xaa, 0xfb, 0x8f, 0x5c, 0xaf, 0xf6, 0x1e, 0x21, + 0x5f, 0xa6, 0x81, 0x57, 0x75, 0x99, 0xcc, 0x52, 0xb7, 0xea, 0x72, 0x22, + 0x9b, 0x19, 0xaa, 0x48, 0x9b, 0x4c, 0x25, 0xa7, 0xb5, 0xad, 0xb5, 0x73, + 0x87, 0xb5, 0xbd, 0x2a, 0xbb, 0x78, 0xd6, 0x06, 0x54, 0xe9, 0x08, 0xf7, + 0xdf, 0x8b, 0x5f, 0x1c, 0xb4, 0x70, 0x7e, 0x5b, 0x86, 0x07, 0x1d, 0xf5, + 0x40, 0x5f, 0x05, 0x08, 0x96, 0x71, 0xce, 0x62, 0xe5, 0xe2, 0x74, 0x6f, + 0xaa, 0xa8, 0x6c, 0x19, 0xb3, 0x2d, 0x19, 0x87, 0x7c, 0x0f, 0x67, 0xdf, + 0xa9, 0x4f, 0x25, 0xd9, 0xbe, 0x4e, 0xbe, 0xae, 0x7d, 0x0e, 0xac, 0x5d, + 0x3d, 0x8a, 0x75, 0xe3, 0x38, 0x03, 0xae, 0xcb, 0x79, 0x50, 0xae, 0xd9, + 0x28, 0x67, 0x4e, 0x56, 0xc4, 0x87, 0x9e, 0x6c, 0x94, 0xc2, 0xce, 0x16, + 0xc9, 0x8f, 0xa4, 0x65, 0x7c, 0xc6, 0x07, 0x4e, 0xe1, 0x1c, 0xdd, 0x56, + 0x29, 0x8d, 0xa6, 0xe5, 0xd1, 0x19, 0xd6, 0x9d, 0xc6, 0xfe, 0x33, 0x87, + 0xf2, 0xc2, 0xfd, 0xc7, 0xf5, 0xbe, 0xd2, 0xea, 0xb4, 0xec, 0xf7, 0xde, + 0x30, 0x7a, 0x14, 0x94, 0xef, 0xc7, 0x99, 0x9e, 0xf0, 0x17, 0xb0, 0x7f, + 0x57, 0xe6, 0x81, 0xff, 0xc5, 0x23, 0xc0, 0x41, 0xb7, 0x03, 0x98, 0x95, + 0x59, 0xa0, 0x4d, 0x8d, 0xc1, 0xef, 0xab, 0x6a, 0x5e, 0xf7, 0xc8, 0x91, + 0x19, 0x25, 0xdf, 0xbe, 0x31, 0x8d, 0x32, 0xb0, 0x31, 0x9b, 0x39, 0x3d, + 0xa6, 0x7a, 0xe4, 0x86, 0xce, 0x14, 0xc6, 0xe5, 0x54, 0xc9, 0xdb, 0x18, + 0x03, 0x2f, 0x8f, 0xa7, 0x15, 0xfb, 0x2a, 0x29, 0x66, 0x63, 0x38, 0xff, + 0x0a, 0xfa, 0xbf, 0x8f, 0xf5, 0x7a, 0x64, 0x16, 0xbe, 0xd6, 0xec, 0x4c, + 0x1e, 0xe3, 0x88, 0x5d, 0x99, 0xe3, 0x4b, 0x0a, 0x18, 0x33, 0x0b, 0xf9, + 0x1e, 0x85, 0x2f, 0x33, 0x03, 0xd1, 0x69, 0x4d, 0xe3, 0x4c, 0x7b, 0x9d, + 0x71, 0xe0, 0x41, 0xbe, 0x87, 0xef, 0x9c, 0xd3, 0x95, 0x13, 0x1e, 0xe5, + 0x30, 0x2d, 0x4f, 0xf9, 0x1c, 0xd7, 0xbb, 0xf0, 0x1c, 0x7c, 0x9f, 0xdf, + 0xf5, 0xae, 0x44, 0xff, 0x77, 0xe1, 0x07, 0x3b, 0x52, 0xc5, 0xb9, 0x95, + 0xc1, 0xcb, 0x7c, 0x2a, 0x28, 0x8f, 0xcf, 0x66, 0x16, 0xde, 0x50, 0x7c, + 0x77, 0x2b, 0xf3, 0xea, 0x5a, 0x91, 0x4e, 0xf2, 0x33, 0x0b, 0x5e, 0xba, + 0x8e, 0x52, 0xdb, 0x8d, 0xef, 0x47, 0x3d, 0x72, 0x41, 0x9f, 0x2d, 0xf3, + 0x03, 0x51, 0x3d, 0xa2, 0x3d, 0x0c, 0xf5, 0x28, 0x93, 0x5a, 0x52, 0x0a, + 0xed, 0xb6, 0x1c, 0xd6, 0x65, 0x0b, 0xb4, 0x66, 0x52, 0xdc, 0xdf, 0x44, + 0xad, 0x5f, 0x9e, 0xf2, 0xd8, 0x1f, 0x7c, 0x9e, 0x6e, 0x37, 0xfd, 0x4f, + 0x83, 0x87, 0xf4, 0xdf, 0xfa, 0x41, 0x73, 0xa0, 0x5b, 0xf3, 0xd3, 0x49, + 0xdd, 0x36, 0xe5, 0x05, 0x7e, 0x9a, 0x82, 0x2f, 0x37, 0x07, 0x5f, 0xae, + 0xa8, 0xf5, 0xcc, 0xc9, 0xc3, 0xd7, 0x87, 0x9e, 0x04, 0x3a, 0x56, 0xad, + 0x91, 0x96, 0xbb, 0x40, 0x5f, 0xa6, 0x02, 0x62, 0x0e, 0xab, 0x1c, 0xce, + 0x7d, 0x50, 0x2a, 0xf4, 0xf7, 0xce, 0xc6, 0x9e, 0x92, 0xb1, 0x2a, 0xed, + 0x11, 0x7e, 0x9e, 0xeb, 0x30, 0xbe, 0xc8, 0x6b, 0x5b, 0xd1, 0x0d, 0x39, + 0x80, 0x1d, 0xc9, 0x6e, 0x32, 0x7e, 0xce, 0x13, 0x38, 0xcf, 0x33, 0x38, + 0xf7, 0x9a, 0xec, 0x3d, 0xf6, 0x0a, 0x65, 0xba, 0xbf, 0x2a, 0x99, 0xfe, + 0x29, 0xd9, 0xe1, 0xcc, 0x43, 0x1f, 0xf3, 0xa3, 0xf5, 0x5b, 0x54, 0x8e, + 0x63, 0x0e, 0x62, 0x0c, 0x9e, 0xd5, 0x57, 0xe4, 0x21, 0x9f, 0x75, 0x0f, + 0x81, 0x9f, 0xd0, 0x95, 0xc1, 0x27, 0x8c, 0x1e, 0x60, 0x3e, 0x3b, 0x9c, + 0xef, 0x15, 0x33, 0x1f, 0xfb, 0xb1, 0x0f, 0xc7, 0x2c, 0xcf, 0xbb, 0x8b, + 0xb6, 0x08, 0x78, 0xb4, 0x4b, 0xd5, 0x6f, 0x89, 0xa3, 0xfd, 0xc4, 0x20, + 0xdf, 0x31, 0x0f, 0x6c, 0x91, 0xe3, 0x9e, 0x41, 0x5f, 0xf8, 0x7a, 0xde, + 0x7a, 0x29, 0x74, 0x85, 0xf4, 0x52, 0x06, 0xe8, 0x27, 0x68, 0x1b, 0xbc, + 0x39, 0xe0, 0xfd, 0x1f, 0xc6, 0x02, 0x99, 0x3c, 0x80, 0x32, 0xf5, 0xef, + 0x80, 0x14, 0xbd, 0x0c, 0xf6, 0x09, 0x1d, 0xf3, 0x3b, 0xac, 0x60, 0x8f, + 0xe0, 0xff, 0xc8, 0x39, 0xf0, 0x41, 0x2a, 0x01, 0x6f, 0xc8, 0x17, 0xf2, + 0xa4, 0x03, 0xb2, 0x0f, 0xb9, 0x87, 0xdc, 0x96, 0x34, 0x0f, 0xfe, 0xbd, + 0x33, 0xf0, 0x8b, 0x33, 0x95, 0x3c, 0xe3, 0xb9, 0x4e, 0xe2, 0x26, 0x30, + 0xcc, 0x87, 0x70, 0x60, 0xee, 0x25, 0xb5, 0x9e, 0xf4, 0xa6, 0x97, 0x62, + 0x7d, 0x2c, 0xf7, 0x2f, 0x41, 0x86, 0xab, 0x38, 0x9f, 0xc2, 0xce, 0x5e, + 0x83, 0x5b, 0xcf, 0xc6, 0x28, 0xaf, 0x55, 0x60, 0x4c, 0xc9, 0xdb, 0xe1, + 0xdc, 0x4d, 0xbe, 0x39, 0x8e, 0x3c, 0xe7, 0x45, 0xb1, 0x03, 0xb6, 0xcf, + 0xa5, 0x1c, 0x26, 0x21, 0x07, 0x36, 0x6c, 0x68, 0x0a, 0x67, 0xfe, 0x6f, + 0x9d, 0xc1, 0x5e, 0xf8, 0x6e, 0xcb, 0x9c, 0x83, 0x35, 0xbd, 0xc5, 0x8d, + 0x41, 0x1d, 0xdf, 0xb7, 0xf0, 0x8c, 0x0e, 0xaf, 0xa4, 0x9d, 0xe7, 0xdb, + 0x7c, 0xa6, 0x27, 0xb0, 0x17, 0xd6, 0xe3, 0x59, 0x3d, 0x2e, 0x7b, 0x89, + 0x9b, 0x83, 0xdb, 0x52, 0x2f, 0xa2, 0x7f, 0x11, 0x36, 0xa1, 0x62, 0xb3, + 0xed, 0x6d, 0x6b, 0x79, 0x8c, 0xa2, 0x5f, 0x0a, 0x1f, 0x78, 0xc9, 0xfa, + 0x92, 0xff, 0x92, 0x55, 0xa8, 0xbe, 0x6d, 0x15, 0x21, 0x27, 0x55, 0x8f, + 0xf1, 0x0b, 0xf5, 0xc7, 0xc1, 0xda, 0x99, 0xd4, 0x5b, 0xaa, 0x37, 0x3d, + 0x0f, 0x2c, 0xb8, 0x1f, 0x3a, 0x5d, 0xb4, 0x17, 0xa4, 0xec, 0xd7, 0xa4, + 0x74, 0x6c, 0x07, 0xf4, 0x2d, 0x1d, 0xa1, 0x8b, 0x78, 0x56, 0xa1, 0x1f, + 0x6e, 0xed, 0xf2, 0xa4, 0xd2, 0x92, 0x23, 0xae, 0x6d, 0x83, 0xec, 0xa0, + 0xae, 0xb6, 0x2c, 0x7f, 0xb7, 0xad, 0xa2, 0x15, 0xb1, 0xee, 0xe0, 0x4a, + 0x7a, 0xab, 0x72, 0x71, 0x7a, 0x77, 0x35, 0xe8, 0x25, 0x66, 0x00, 0xff, + 0x3d, 0xe0, 0xbf, 0x07, 0xfc, 0xf7, 0x80, 0xff, 0x1e, 0xf0, 0xdf, 0x83, + 0x6d, 0xf0, 0x60, 0x03, 0x3c, 0xd8, 0x00, 0x0f, 0x36, 0xc0, 0x83, 0x0d, + 0xf0, 0x0a, 0x38, 0x27, 0xe2, 0x3c, 0x6d, 0xc8, 0x3d, 0x0d, 0xbb, 0x19, + 0xf8, 0x39, 0x57, 0x1a, 0xdf, 0x01, 0xfa, 0xe7, 0x6c, 0x91, 0xf1, 0xfe, + 0x2b, 0xb0, 0xb7, 0x56, 0x3c, 0xdb, 0xf0, 0xc4, 0x1a, 0xfd, 0x9f, 0x35, + 0x7a, 0xf2, 0x55, 0xd0, 0xa5, 0x50, 0xfe, 0x05, 0xc8, 0x61, 0x0b, 0xe8, + 0xf9, 0x94, 0xf1, 0x31, 0xbe, 0x61, 0x07, 0x72, 0xd8, 0x86, 0xba, 0xcf, + 0xa0, 0xae, 0x0d, 0x7d, 0xf6, 0xa3, 0x0f, 0x7d, 0x94, 0x0e, 0x53, 0x17, + 0xed, 0x47, 0x5f, 0xe5, 0x0b, 0x58, 0x2b, 0x83, 0x7e, 0x1d, 0x98, 0xbb, + 0x07, 0x7d, 0x6e, 0x46, 0x9f, 0xab, 0x50, 0xa6, 0x6f, 0xdb, 0x8d, 0xf2, + 0xa7, 0x9b, 0xc6, 0x5c, 0x83, 0xba, 0xcf, 0x36, 0xd5, 0x9d, 0x45, 0x1d, + 0x62, 0x62, 0xe7, 0x45, 0x33, 0xae, 0x82, 0x72, 0x57, 0x53, 0x9f, 0x57, + 0x50, 0x37, 0x84, 0xba, 0xbf, 0xc2, 0x13, 0xb1, 0xb0, 0x43, 0x9a, 0xc2, + 0x36, 0xfa, 0xa9, 0x69, 0xd4, 0xc7, 0x8d, 0xaf, 0xf9, 0x24, 0x7d, 0x2f, + 0xd8, 0xdc, 0x3f, 0xb6, 0x03, 0xdf, 0x0c, 0xde, 0xab, 0x96, 0xc3, 0xb0, + 0xfc, 0xcd, 0xa6, 0x32, 0xfb, 0x7e, 0xbf, 0xa9, 0xae, 0x6d, 0xd3, 0xca, + 0xf2, 0x4f, 0xe3, 0xab, 0xc7, 0xdc, 0xdb, 0xd4, 0xe7, 0xeb, 0x9d, 0x2b, + 0xcb, 0xbb, 0x5b, 0x56, 0x8f, 0xd9, 0xbe, 0x71, 0x65, 0xdd, 0xad, 0x9b, + 0x57, 0x96, 0xe9, 0x03, 0x26, 0x11, 0xc3, 0x84, 0xfd, 0x77, 0x7e, 0x22, + 0x68, 0x27, 0x7f, 0x9b, 0x65, 0x49, 0x2b, 0x23, 0xca, 0x0a, 0xe7, 0xb0, + 0x64, 0x41, 0x9f, 0x1c, 0x95, 0x7b, 0xc9, 0x2a, 0x42, 0xa6, 0x0a, 0x7e, + 0x38, 0x1f, 0x75, 0xb6, 0x39, 0x4f, 0x10, 0xe6, 0x07, 0xe8, 0x6f, 0xb5, + 0x43, 0x6e, 0xee, 0xa2, 0x4d, 0x3a, 0x54, 0x91, 0x65, 0xfd, 0xdc, 0xaa, + 0xce, 0xa7, 0x9f, 0xf7, 0x19, 0x8c, 0x3a, 0x07, 0x3a, 0xeb, 0x32, 0x92, + 0x5d, 0x47, 0x1b, 0x63, 0xb0, 0x8b, 0xb8, 0x53, 0xaf, 0xc7, 0xb6, 0xd7, + 0x65, 0x5f, 0xf6, 0xdd, 0xba, 0x68, 0xcc, 0xbb, 0x57, 0xe3, 0x4e, 0x5a, + 0x75, 0xe3, 0x8c, 0x1c, 0xc4, 0x12, 0x88, 0xed, 0x93, 0xb4, 0x49, 0xc7, + 0xe9, 0x9f, 0x1c, 0x0c, 0x30, 0x95, 0xb8, 0x83, 0xb2, 0x3f, 0x85, 0x39, + 0xb9, 0x3e, 0x9e, 0x55, 0xe2, 0xb8, 0xad, 0x6d, 0x4a, 0xc9, 0xe1, 0xbc, + 0x6b, 0x61, 0xe3, 0xbf, 0xd8, 0xf4, 0x0b, 0x6d, 0xf7, 0x24, 0xec, 0x1b, + 0xdb, 0xe8, 0x2b, 0x9c, 0xa4, 0x5f, 0x12, 0xc1, 0xaa, 0x9b, 0x62, 0xe2, + 0x2e, 0x63, 0x66, 0xb0, 0xaf, 0x2d, 0xf4, 0xfb, 0x2f, 0x61, 0xaf, 0x6b, + 0x63, 0x51, 0xaf, 0xba, 0xb8, 0x6e, 0xef, 0x69, 0xe8, 0x76, 0x28, 0x7b, + 0x6b, 0xe5, 0x03, 0x5e, 0xd5, 0x67, 0xf1, 0xac, 0x9f, 0x39, 0x5c, 0x81, + 0x2e, 0x2d, 0xea, 0xd8, 0x37, 0x3c, 0x17, 0xfa, 0x38, 0x99, 0xe3, 0x73, + 0x90, 0xed, 0xbd, 0x3a, 0x26, 0x60, 0x3c, 0x50, 0x97, 0x5d, 0xd9, 0x4f, + 0x25, 0xc9, 0x87, 0xbc, 0xfa, 0x71, 0x9c, 0x3e, 0xc3, 0xa2, 0x47, 0x9e, + 0x65, 0xd1, 0x9e, 0x05, 0x26, 0xfc, 0xab, 0x14, 0x93, 0xac, 0x7b, 0xab, + 0x3e, 0x0f, 0xbf, 0x4a, 0xfb, 0x47, 0xda, 0xde, 0xd3, 0xbf, 0x83, 0x5d, + 0xf7, 0xc9, 0xd3, 0x25, 0xf0, 0x39, 0xf4, 0x01, 0x7e, 0x40, 0x1f, 0x55, + 0x56, 0xfa, 0xd2, 0x22, 0x0f, 0xd5, 0xfe, 0x01, 0x36, 0x47, 0x05, 0xbe, + 0x0a, 0xe3, 0x65, 0x97, 0xf5, 0x37, 0xc6, 0xe9, 0xcb, 0x05, 0xb6, 0x3e, + 0x86, 0xf5, 0x10, 0x5f, 0xd7, 0xfe, 0xd3, 0x2a, 0x79, 0x3d, 0xf4, 0xb3, + 0xb0, 0x7f, 0xf8, 0x50, 0x3e, 0xdb, 0x58, 0x97, 0x30, 0xfe, 0x77, 0xbb, + 0xf1, 0xb7, 0x1d, 0xe3, 0x6f, 0x6b, 0x3a, 0x12, 0x4e, 0x2e, 0xf4, 0x0b, + 0x78, 0x66, 0xe9, 0x83, 0x6a, 0x3b, 0xfd, 0x82, 0x0e, 0x59, 0xdb, 0x2f, + 0x08, 0x69, 0x3a, 0x85, 0x7d, 0xd2, 0xcf, 0xd3, 0x79, 0xa0, 0xce, 0x20, + 0xf7, 0x44, 0x1a, 0x42, 0xfb, 0xa8, 0xed, 0xf0, 0x21, 0x98, 0x3c, 0xe6, + 0x24, 0x41, 0xeb, 0x6e, 0x29, 0x4c, 0x9f, 0x32, 0xf6, 0x96, 0x71, 0x04, + 0x7d, 0xf8, 0x40, 0x66, 0x0b, 0xd9, 0x0e, 0xcb, 0xcc, 0xd3, 0x05, 0x0b, + 0x19, 0xc9, 0x51, 0x71, 0x2d, 0xfa, 0x31, 0xa1, 0x4f, 0xb3, 0x60, 0x7c, + 0x9a, 0x33, 0xb2, 0xcf, 0x0b, 0xe2, 0x86, 0x91, 0xda, 0x12, 0xea, 0x34, + 0xed, 0x29, 0xfa, 0x96, 0x0a, 0x3e, 0x77, 0xfe, 0xde, 0x0c, 0x02, 0x90, + 0x60, 0x2f, 0x5b, 0xb1, 0x97, 0x6a, 0x63, 0x2f, 0x6d, 0x4b, 0xcd, 0x3e, + 0x0e, 0xc7, 0x4e, 0xae, 0x1a, 0x2b, 0xd8, 0xc7, 0xdc, 0x79, 0xda, 0xb8, + 0x47, 0xfa, 0x0d, 0x8e, 0xd9, 0x63, 0x78, 0x4e, 0x8f, 0x63, 0x8f, 0x49, + 0xab, 0xa4, 0x7d, 0x2d, 0xfa, 0x2d, 0x88, 0xb3, 0x6b, 0x2f, 0xe1, 0x49, + 0xfd, 0xd0, 0xf3, 0x60, 0x4f, 0xed, 0x7a, 0x4f, 0x53, 0xde, 0x2b, 0x7a, + 0x1f, 0xf3, 0xb5, 0xbf, 0x91, 0xf2, 0xb1, 0x1f, 0xc0, 0xee, 0x45, 0x73, + 0x73, 0xcc, 0x6b, 0x92, 0x1f, 0x95, 0x08, 0x7e, 0x72, 0xaf, 0xcc, 0xbb, + 0xbd, 0x1c, 0x0f, 0xe2, 0x83, 0x69, 0x9c, 0xb1, 0x15, 0xb4, 0xeb, 0xf5, + 0x43, 0xbe, 0xb6, 0x44, 0xe8, 0xa9, 0xc3, 0xe7, 0x4c, 0x81, 0x86, 0xe8, + 0x98, 0x03, 0x32, 0xec, 0xf1, 0x3c, 0x7a, 0x53, 0x7b, 0xc5, 0x75, 0x4a, + 0x12, 0xfa, 0x19, 0x5c, 0x9f, 0x3a, 0x5f, 0x84, 0xe3, 0xcb, 0x5c, 0x6a, + 0xc8, 0xbb, 0x90, 0x6f, 0xed, 0x4b, 0xcd, 0x32, 0x30, 0x89, 0x58, 0xab, + 0xec, 0x91, 0x4f, 0xa1, 0x6c, 0x86, 0x6b, 0xbf, 0x6a, 0x71, 0x3f, 0x13, + 0x3a, 0x7f, 0xf8, 0x4f, 0x0d, 0x19, 0x1d, 0x07, 0x76, 0x04, 0x32, 0xf7, + 0xf7, 0x86, 0x37, 0xa1, 0x6c, 0xb6, 0x9b, 0x73, 0x66, 0x2c, 0x48, 0xdd, + 0x09, 0xe5, 0x60, 0x9b, 0x73, 0xa7, 0xe6, 0x05, 0xdb, 0xb4, 0xcf, 0xad, + 0xcf, 0x72, 0xac, 0x71, 0x96, 0x1b, 0x9a, 0xe4, 0xf2, 0xdd, 0x8d, 0x81, + 0x1e, 0x52, 0xdf, 0xa0, 0xb7, 0xe0, 0xd7, 0xb3, 0x2b, 0xf4, 0xbb, 0xff, + 0x3c, 0x39, 0xd9, 0x76, 0x89, 0xcd, 0x7e, 0x0f, 0xbc, 0xbc, 0x06, 0xb1, + 0x8a, 0x88, 0x3d, 0x43, 0x1c, 0xa2, 0xbf, 0xb1, 0xec, 0xef, 0xce, 0xcb, + 0x5a, 0xbe, 0xee, 0xc5, 0x7c, 0x8d, 0x4f, 0x5e, 0xa2, 0xaf, 0x31, 0xdc, + 0x22, 0xad, 0xc4, 0xa2, 0x33, 0xf0, 0x6d, 0x2d, 0x69, 0x71, 0xbf, 0x01, + 0x1b, 0x76, 0xda, 0x5e, 0xe7, 0x86, 0x98, 0xd0, 0x2e, 0x9b, 0x66, 0xb7, + 0x68, 0x5c, 0x70, 0x66, 0x96, 0x71, 0x61, 0x1c, 0xbc, 0x1f, 0x09, 0xf2, + 0xbc, 0xc9, 0x4d, 0x72, 0xa9, 0xf1, 0xf5, 0xb2, 0xdf, 0x3f, 0xd6, 0xf0, + 0xfb, 0xaf, 0x6c, 0xe2, 0xe3, 0x5a, 0xb8, 0x78, 0x1a, 0x7c, 0xcb, 0x21, + 0xfe, 0x65, 0x5c, 0x3b, 0x8c, 0x78, 0x98, 0xb1, 0x58, 0x1e, 0x31, 0x71, + 0xe6, 0xb4, 0xc8, 0x6e, 0xc4, 0xc8, 0x99, 0x1f, 0x31, 0x7f, 0xf5, 0xbc, + 0x9f, 0x99, 0x13, 0xb9, 0x1d, 0x7c, 0x1d, 0x04, 0x6e, 0x66, 0x81, 0xa3, + 0x3b, 0xc1, 0xdf, 0x7e, 0x8d, 0x9d, 0xf7, 0x1f, 0x11, 0xeb, 0x0e, 0x9d, + 0xab, 0xa6, 0x3e, 0x27, 0x61, 0x47, 0xeb, 0xf5, 0xfd, 0xd9, 0x5e, 0xc4, + 0xf5, 0x69, 0xb9, 0xd5, 0x66, 0x1c, 0x6b, 0xd9, 0x5b, 0x07, 0xe6, 0x63, + 0x51, 0x9f, 0xb4, 0x70, 0x51, 0x3b, 0xb0, 0x9a, 0xf7, 0x45, 0x6d, 0x0b, + 0x0e, 0xc7, 0x2e, 0xc4, 0xfb, 0x3b, 0x1a, 0xbc, 0x6f, 0x69, 0x95, 0xd6, + 0xdb, 0x75, 0x1e, 0x61, 0xeb, 0xc0, 0x7e, 0xe2, 0x55, 0x16, 0x76, 0x1d, + 0xf6, 0xb7, 0x2e, 0xb7, 0x65, 0xdf, 0xae, 0xbf, 0xe8, 0x6e, 0x94, 0xd2, + 0xce, 0xfb, 0x0c, 0x66, 0x2f, 0x7d, 0xad, 0xe0, 0x56, 0xa0, 0x1f, 0x41, + 0xce, 0x70, 0xef, 0x74, 0x02, 0x96, 0x80, 0x7f, 0x9d, 0x32, 0x3f, 0xf4, + 0x16, 0xce, 0x70, 0xc7, 0x49, 0x26, 0x9c, 0x14, 0x70, 0x78, 0x3e, 0xd9, + 0xae, 0xf3, 0xc5, 0x9f, 0x70, 0x59, 0xef, 0xe0, 0x4c, 0x47, 0x65, 0x1e, + 0xfe, 0x43, 0x75, 0x08, 0x34, 0xee, 0xec, 0x42, 0x7f, 0xea, 0x1d, 0x79, + 0x3e, 0x0a, 0xdb, 0x4b, 0x9e, 0x26, 0xd1, 0x7f, 0x0f, 0xfa, 0x74, 0xe2, + 0x79, 0x5f, 0x6c, 0xde, 0x61, 0xec, 0xfc, 0x79, 0x94, 0x39, 0x47, 0xd4, + 0x76, 0x7e, 0x2e, 0x2e, 0x7a, 0x4e, 0x8e, 0xe9, 0xd2, 0xfa, 0xbf, 0xbc, + 0x16, 0xd7, 0x61, 0xdb, 0xcf, 0xea, 0xd7, 0x0f, 0x0c, 0x45, 0xd6, 0xeb, + 0x88, 0xac, 0x37, 0x14, 0x59, 0x8f, 0x74, 0x76, 0x46, 0xe8, 0xec, 0xc4, + 0xf8, 0x22, 0xd6, 0x26, 0x3f, 0xa2, 0x6b, 0x3e, 0x18, 0x59, 0x33, 0xdc, + 0x5f, 0x57, 0x64, 0xdc, 0xbb, 0x58, 0x8f, 0x75, 0xc9, 0x48, 0x1d, 0x69, + 0xd8, 0x8c, 0x3a, 0x96, 0x3b, 0x23, 0x74, 0x91, 0xd6, 0x0d, 0xa8, 0xd7, + 0xfe, 0x13, 0xf8, 0xdc, 0x0a, 0xbb, 0xa5, 0x60, 0x3b, 0x5a, 0xe0, 0x5f, + 0x35, 0xef, 0xf5, 0x51, 0xac, 0x1b, 0xce, 0x97, 0xc4, 0x1c, 0xec, 0xcf, + 0xbe, 0x31, 0x33, 0x9e, 0xf5, 0x6c, 0xff, 0xf3, 0xfa, 0x9f, 0x6a, 0xbe, + 0x6d, 0x06, 0xed, 0x3a, 0xef, 0x22, 0x73, 0x9d, 0x36, 0xce, 0x93, 0xf1, + 0xb1, 0x25, 0x57, 0xbb, 0xca, 0xea, 0x1d, 0xe0, 0xd9, 0x6f, 0x34, 0x58, + 0xda, 0x6a, 0x15, 0x8e, 0x30, 0x5f, 0xd0, 0x66, 0x62, 0x3e, 0xc4, 0x1e, + 0xda, 0xc6, 0xd8, 0xa6, 0x9d, 0x36, 0x86, 0x7e, 0x0b, 0xed, 0xe7, 0x69, + 0xf3, 0x8e, 0x27, 0x64, 0xf8, 0x81, 0x6a, 0xa7, 0xbc, 0xa8, 0x79, 0xea, + 0xc8, 0xd9, 0x06, 0x4f, 0xe3, 0xe6, 0xbb, 0xcc, 0x01, 0xf3, 0xcd, 0xa3, + 0x0f, 0x7e, 0x11, 0xde, 0x6b, 0x79, 0xd0, 0x90, 0x96, 0xde, 0x01, 0xc6, + 0x6e, 0x15, 0x3c, 0x99, 0xa7, 0xb0, 0xf0, 0x0c, 0xf2, 0x17, 0xbd, 0x03, + 0xb0, 0x4b, 0xc0, 0xa1, 0xde, 0x81, 0x73, 0x3a, 0x9e, 0xab, 0xfa, 0x8e, + 0x75, 0x9b, 0x17, 0xe4, 0x88, 0xce, 0xba, 0x17, 0xca, 0x11, 0xdd, 0xb3, + 0x8e, 0x79, 0x8d, 0x30, 0x47, 0x74, 0x56, 0x74, 0x8e, 0xe8, 0xf8, 0x45, + 0x72, 0x44, 0xf9, 0x4b, 0xcf, 0x11, 0x71, 0x7e, 0x5b, 0xee, 0x1c, 0x74, + 0xd4, 0xaf, 0x9a, 0x1c, 0xd1, 0x1b, 0x12, 0xe4, 0x88, 0x5e, 0x94, 0xb5, + 0x73, 0x44, 0x87, 0x9a, 0x72, 0x44, 0x9b, 0x75, 0x8e, 0x88, 0xf3, 0x04, + 0x39, 0x22, 0x96, 0x4b, 0x03, 0x43, 0x91, 0x5c, 0x07, 0xf0, 0xd7, 0xbb, + 0x01, 0x7c, 0x73, 0xac, 0x51, 0x2f, 0xc4, 0x34, 0x62, 0xff, 0x15, 0x0d, + 0xfb, 0xb5, 0x8c, 0x6f, 0x96, 0x96, 0xb9, 0x8b, 0xe1, 0xdb, 0x68, 0xe0, + 0x97, 0xac, 0xc0, 0xb6, 0xc9, 0x86, 0xef, 0xe2, 0xad, 0x63, 0x0c, 0x3d, + 0x51, 0x5b, 0x9e, 0x77, 0x02, 0xbc, 0x1e, 0x6b, 0xe4, 0x49, 0xce, 0xe7, + 0x1f, 0x25, 0xe5, 0xc0, 0x9a, 0xdf, 0xbd, 0x52, 0xf9, 0xd5, 0xdf, 0xbd, + 0x2c, 0x49, 0x82, 0xce, 0xd2, 0x40, 0x49, 0xc7, 0x5d, 0xf3, 0xde, 0xaf, + 0xc8, 0xd2, 0xdd, 0x0e, 0xf0, 0x27, 0xcc, 0x9f, 0xf0, 0x7c, 0x97, 0x6d, + 0x4a, 0x41, 0x7d, 0x7c, 0x39, 0x94, 0x07, 0x74, 0x0e, 0xe5, 0xc5, 0x75, + 0xd1, 0x1c, 0xca, 0x59, 0xb9, 0x70, 0x0e, 0xe5, 0x81, 0x35, 0x72, 0x28, + 0x2f, 0xcb, 0x72, 0x0e, 0xe5, 0x65, 0x09, 0x73, 0x28, 0x31, 0x59, 0xda, + 0x1c, 0x48, 0xe3, 0x03, 0xfe, 0x12, 0x7e, 0x67, 0xf0, 0x0b, 0x72, 0x2a, + 0x67, 0x1b, 0xf4, 0xaf, 0x95, 0x53, 0x79, 0x7d, 0xdd, 0x07, 0xc9, 0xa9, + 0x04, 0x36, 0x20, 0xcc, 0xa9, 0xe0, 0xe7, 0xc0, 0xe6, 0xa8, 0x68, 0x4e, + 0xe5, 0x27, 0xd4, 0x07, 0xd4, 0xb1, 0xcc, 0x7a, 0xe8, 0x05, 0xec, 0x52, + 0x5e, 0xe7, 0x38, 0x3e, 0x67, 0x78, 0x38, 0x87, 0x3d, 0xa7, 0x71, 0x16, + 0xe4, 0x63, 0xaf, 0xf6, 0x2d, 0xf3, 0x76, 0xca, 0x2a, 0xf4, 0xc1, 0x9a, + 0x4d, 0xf3, 0xbb, 0xb8, 0x6d, 0xed, 0xf5, 0x29, 0xe3, 0x09, 0xab, 0x8c, + 0xbd, 0x0c, 0x4f, 0xcf, 0xc9, 0x5e, 0x3f, 0xf4, 0xa9, 0x06, 0x1a, 0x73, + 0x50, 0x37, 0xe7, 0x81, 0xb3, 0xc0, 0x89, 0x4b, 0xb0, 0x51, 0xa7, 0x40, + 0x73, 0x74, 0x1f, 0x88, 0x89, 0x07, 0x51, 0xa7, 0xcf, 0x9c, 0xbe, 0x65, + 0x48, 0x4b, 0x9a, 0x7a, 0x7e, 0x09, 0xf3, 0xb1, 0xee, 0x94, 0x8e, 0xc7, + 0xca, 0x83, 0xdc, 0x2b, 0x6d, 0xdd, 0x22, 0xe8, 0x43, 0x5d, 0x95, 0x31, + 0x20, 0xed, 0x5e, 0x18, 0xa3, 0xb5, 0xeb, 0x18, 0xad, 0x4b, 0xf3, 0x83, + 0xbc, 0xbe, 0x35, 0x41, 0xac, 0xec, 0x72, 0xb9, 0x87, 0x33, 0x06, 0xeb, + 0x58, 0x0e, 0x62, 0xc1, 0xbc, 0xe2, 0xfb, 0xef, 0xe1, 0x5c, 0x99, 0xa7, + 0x09, 0xcf, 0xef, 0x2b, 0x66, 0xdf, 0x43, 0x52, 0xe9, 0x92, 0xc4, 0x66, + 0xd0, 0x53, 0x9a, 0xa1, 0xdf, 0xfd, 0x69, 0x1d, 0x83, 0x24, 0xdd, 0xf3, + 0xeb, 0xed, 0x1d, 0x97, 0xa1, 0xb7, 0x23, 0x17, 0xd4, 0xdb, 0xaf, 0x25, + 0xa2, 0x7a, 0x7b, 0xc7, 0x65, 0xe8, 0xed, 0xbe, 0xcb, 0xd2, 0x5b, 0xee, + 0x8d, 0x98, 0x14, 0xe6, 0xc4, 0x56, 0xfb, 0x59, 0xe1, 0xba, 0xe3, 0x58, + 0x33, 0x7f, 0x9e, 0x35, 0xc7, 0xce, 0x9b, 0x5b, 0x6d, 0xf6, 0xb1, 0x2e, + 0xe5, 0xbc, 0x19, 0x5b, 0xd1, 0xde, 0xb6, 0x1b, 0xbb, 0x74, 0x9f, 0x89, + 0xe7, 0xc3, 0xb8, 0x3e, 0xaa, 0x3f, 0x94, 0x0b, 0xca, 0xc2, 0x77, 0xc0, + 0x2f, 0xca, 0x43, 0xa8, 0x73, 0xdd, 0x4d, 0x32, 0xb8, 0x88, 0x78, 0xbf, + 0xdb, 0xc8, 0x20, 0xcf, 0xba, 0x4f, 0x7f, 0x67, 0xaa, 0x7a, 0x4f, 0x05, + 0x71, 0xbe, 0x8b, 0x67, 0x35, 0xd4, 0x35, 0xf0, 0x24, 0x19, 0xb6, 0x91, + 0x8f, 0x2e, 0x7c, 0x9e, 0x1d, 0xf0, 0xd7, 0xc0, 0x23, 0x5d, 0xbf, 0x32, + 0x27, 0x7c, 0x61, 0x3c, 0x93, 0x4a, 0x1c, 0x7d, 0x4f, 0x0c, 0x42, 0xc7, + 0x07, 0x89, 0x51, 0x35, 0xc4, 0x3d, 0x94, 0x43, 0xca, 0xe6, 0xb6, 0xfe, + 0x5d, 0x8a, 0x3e, 0xd5, 0x13, 0x88, 0x83, 0x29, 0xaf, 0x69, 0xd9, 0xe5, + 0x6f, 0x3b, 0x7d, 0x56, 0x71, 0x8d, 0x7a, 0xbd, 0xc4, 0x58, 0xd1, 0x11, + 0xb5, 0x75, 0xe0, 0xbf, 0x13, 0xb4, 0x4b, 0x57, 0xb8, 0x31, 0x23, 0x6b, + 0x79, 0xbc, 0x53, 0x6e, 0x7f, 0x08, 0x7b, 0xcf, 0xef, 0xfd, 0xaf, 0xa1, + 0x3e, 0x05, 0x9d, 0xa7, 0x7d, 0x67, 0x3c, 0x72, 0x93, 0xe9, 0xd7, 0xad, + 0xbf, 0x57, 0x16, 0xb2, 0x37, 0x98, 0x6f, 0x57, 0xb4, 0x3f, 0x19, 0xda, + 0xec, 0x15, 0xe7, 0xcc, 0xfb, 0x12, 0x45, 0x1d, 0xcf, 0x70, 0xbc, 0x96, + 0x49, 0xc4, 0x20, 0x76, 0x24, 0x97, 0x9e, 0x30, 0xb1, 0x1b, 0x75, 0xac, + 0x1d, 0x67, 0xe8, 0x9b, 0x58, 0x85, 0xf1, 0xeb, 0xca, 0x7b, 0x12, 0x6b, + 0xcb, 0xc0, 0x96, 0x0f, 0x20, 0x03, 0xcd, 0xe7, 0x97, 0x80, 0xee, 0x87, + 0xe7, 0x17, 0xfa, 0x31, 0x73, 0x66, 0xdf, 0xdd, 0xc1, 0x19, 0xfe, 0xbf, + 0xd8, 0xa7, 0x15, 0xd9, 0x67, 0x88, 0x47, 0x0f, 0x98, 0x7d, 0xde, 0xd4, + 0x84, 0x47, 0x23, 0x4d, 0x3a, 0xfb, 0x71, 0xe2, 0xd1, 0x9f, 0xac, 0xff, + 0xf8, 0xf1, 0x88, 0xfb, 0xea, 0x5e, 0x13, 0x87, 0x82, 0x7d, 0x3c, 0x22, + 0x2a, 0xf7, 0x51, 0xc6, 0x7b, 0x1f, 0xe4, 0x7c, 0xa2, 0x38, 0xc2, 0x33, + 0xe9, 0xd0, 0x3e, 0x6c, 0xa0, 0x7b, 0xb0, 0xe5, 0xd5, 0xb8, 0xbc, 0x7e, + 0x57, 0x42, 0xfe, 0xf7, 0x46, 0x7e, 0x0f, 0xb3, 0x4d, 0x4e, 0x8b, 0xe5, + 0xd7, 0xd6, 0x07, 0x76, 0xe8, 0xb5, 0x4d, 0x81, 0xdd, 0xe1, 0x98, 0x50, + 0x9f, 0x1d, 0xb4, 0xb3, 0xad, 0x5b, 0x96, 0x3a, 0x2f, 0x27, 0x06, 0xdc, + 0xe6, 0xbc, 0xa1, 0xd6, 0x8a, 0x01, 0x2f, 0x9c, 0x0f, 0x5c, 0x8e, 0x01, + 0x89, 0xb3, 0x9d, 0x5a, 0x36, 0x4a, 0x49, 0xc6, 0x3e, 0x7d, 0x06, 0x3b, + 0xf9, 0x8e, 0xd8, 0xd6, 0x43, 0xbc, 0xeb, 0x21, 0xd6, 0xf5, 0x10, 0xff, + 0x7a, 0x88, 0x71, 0x3d, 0xc4, 0xb6, 0x1e, 0x62, 0x5b, 0x0f, 0xb1, 0xad, + 0xd7, 0x6f, 0x62, 0xe4, 0x11, 0x93, 0xf7, 0xe7, 0x77, 0x72, 0xe6, 0x17, + 0x2a, 0xb0, 0x25, 0x93, 0xbc, 0xe7, 0xa0, 0x0a, 0xd9, 0xf5, 0x66, 0x7f, + 0x61, 0x4e, 0xbc, 0xc7, 0xe4, 0x6c, 0x5e, 0xd7, 0x79, 0x43, 0x51, 0xb3, + 0xad, 0xc1, 0xb7, 0x74, 0xde, 0xc7, 0xf8, 0x2d, 0xf8, 0x25, 0xfa, 0x3e, + 0x13, 0x75, 0xb4, 0xae, 0x72, 0xcc, 0xc9, 0x88, 0x52, 0xb9, 0xeb, 0x31, + 0x66, 0x47, 0x10, 0x13, 0x24, 0x25, 0xa6, 0x72, 0x6d, 0xe4, 0xa9, 0xa5, + 0x72, 0x1b, 0xcc, 0x5c, 0x47, 0x5b, 0x03, 0xdf, 0xaa, 0x8f, 0x65, 0x5b, + 0xe5, 0x6e, 0xe6, 0x13, 0xe7, 0x1e, 0xd6, 0xf7, 0x74, 0xae, 0x5c, 0x6b, + 0x4a, 0xe3, 0x7b, 0x21, 0x7b, 0x37, 0xe6, 0xd3, 0xf7, 0x88, 0x1a, 0xfc, + 0x56, 0xe7, 0xe5, 0xf7, 0x94, 0xe1, 0x77, 0xc0, 0xe3, 0x18, 0xfb, 0xe9, + 0xbc, 0x30, 0x79, 0x1d, 0xce, 0xa7, 0xf3, 0x7a, 0x58, 0x47, 0xdf, 0xa5, + 0xc0, 0x53, 0xc5, 0xa5, 0x63, 0xf4, 0x9e, 0xb8, 0x1b, 0x5d, 0x37, 0xfc, + 0x26, 0x7e, 0x29, 0x6b, 0x76, 0xeb, 0xef, 0x68, 0x81, 0xcd, 0x98, 0xd2, + 0x32, 0x68, 0xe7, 0xb8, 0xaf, 0xf7, 0x21, 0x7f, 0x53, 0x5a, 0xfe, 0x8a, + 0x88, 0x63, 0x26, 0x07, 0xb7, 0xa5, 0x6d, 0x75, 0xa0, 0x95, 0xf9, 0xd7, + 0x61, 0x3f, 0xc4, 0x3d, 0xae, 0xd7, 0x6c, 0xc7, 0x99, 0x57, 0x0b, 0xf1, + 0x4c, 0xb6, 0x04, 0xf9, 0xb6, 0x0f, 0xa3, 0x4b, 0xad, 0x4d, 0xba, 0x14, + 0xee, 0x93, 0xfb, 0xe7, 0x73, 0xed, 0x3b, 0x15, 0x8b, 0x7e, 0xe4, 0xfb, + 0x48, 0x43, 0x36, 0x78, 0xb7, 0xe4, 0x8b, 0x90, 0x41, 0xfd, 0x9d, 0x02, + 0x7a, 0x54, 0xaf, 0x0f, 0x33, 0xc7, 0xbc, 0xf3, 0x0b, 0xe6, 0xde, 0x82, + 0x3c, 0xcc, 0xfc, 0x83, 0xbd, 0x2a, 0xff, 0x30, 0x0c, 0x59, 0x81, 0x0f, + 0xe0, 0x75, 0x68, 0x9f, 0x4e, 0xb9, 0xf4, 0x07, 0x9a, 0xbf, 0xbf, 0x3c, + 0xda, 0x16, 0xf0, 0xe1, 0xed, 0xd6, 0xe0, 0x1b, 0xc4, 0xdf, 0x26, 0x57, + 0x96, 0x39, 0xfe, 0x7f, 0x8c, 0xac, 0x1c, 0x86, 0x6d, 0x1e, 0x86, 0x2c, + 0x22, 0x26, 0xd7, 0xf3, 0x1d, 0x96, 0xd2, 0xd3, 0x0b, 0x9d, 0x2b, 0xfb, + 0xa3, 0xee, 0x58, 0xd8, 0xff, 0xb1, 0xa6, 0xfe, 0x8f, 0xa1, 0xff, 0x0b, + 0x4d, 0xfd, 0x1f, 0x8b, 0xf4, 0x3f, 0xda, 0xd4, 0x1f, 0x31, 0xe2, 0xd3, + 0xff, 0xdc, 0xd4, 0xff, 0x68, 0xa4, 0xff, 0x6c, 0x53, 0xff, 0x59, 0xf4, + 0x7f, 0xad, 0xa9, 0x3f, 0xea, 0x8e, 0xb5, 0x98, 0xef, 0x62, 0xc4, 0xd8, + 0x7d, 0x26, 0x16, 0xc7, 0xb3, 0xd6, 0xfc, 0xad, 0x85, 0x72, 0xd7, 0x83, + 0x33, 0x08, 0xef, 0xb4, 0x51, 0x5f, 0xf3, 0xd0, 0xd7, 0x65, 0x5f, 0x26, + 0x90, 0xc7, 0xa8, 0x2c, 0x12, 0x1f, 0x2a, 0x12, 0x73, 0x7d, 0xfa, 0x47, + 0x56, 0xb9, 0x1a, 0xda, 0x24, 0xde, 0x5b, 0xe2, 0x7d, 0xd7, 0xc0, 0xf6, + 0xc6, 0xdd, 0x45, 0x13, 0x83, 0x5d, 0xd1, 0x06, 0xda, 0x81, 0x97, 0x21, + 0x66, 0xca, 0xe1, 0x40, 0x6f, 0x28, 0xbf, 0x9c, 0xdf, 0xe8, 0x0f, 0x65, + 0xd5, 0xac, 0x33, 0xbc, 0x0a, 0xd7, 0xd2, 0xab, 0x72, 0x5b, 0xb1, 0x4b, + 0xc0, 0xb5, 0x91, 0x06, 0xae, 0x7d, 0x51, 0xe6, 0x1a, 0xf1, 0xf6, 0x19, + 0xd9, 0xef, 0xed, 0xe1, 0x3d, 0x9d, 0xc3, 0x79, 0xf9, 0x68, 0xe2, 0xed, + 0x3d, 0x0d, 0x3b, 0xc9, 0x3b, 0x1d, 0xe9, 0x83, 0xbc, 0x83, 0x1b, 0xe6, + 0x66, 0x27, 0xbd, 0x5f, 0xc7, 0xfe, 0x69, 0x33, 0x2f, 0x37, 0xde, 0xe6, + 0x7c, 0x49, 0xd9, 0x1f, 0xdc, 0x77, 0x68, 0xcc, 0x5b, 0x69, 0xcc, 0x9b, + 0x32, 0xfa, 0x46, 0x1b, 0xbc, 0x6c, 0x2f, 0x8b, 0xb0, 0x97, 0x63, 0x88, + 0xb9, 0x17, 0xbd, 0xb5, 0xf2, 0xa3, 0x97, 0x6b, 0x2f, 0x9b, 0xf3, 0xcc, + 0xcd, 0xf6, 0x92, 0xeb, 0x34, 0xe7, 0x96, 0xd3, 0x4d, 0xf8, 0x4f, 0x79, + 0x3a, 0x67, 0x7c, 0x6a, 0x3c, 0xab, 0xe7, 0xa0, 0x8f, 0x4a, 0xc6, 0xb4, + 0xfc, 0xb2, 0x1c, 0xc6, 0x96, 0xf7, 0x34, 0x62, 0xcb, 0xe5, 0x78, 0x10, + 0xbe, 0x6b, 0xff, 0x67, 0x0c, 0x3e, 0xd2, 0x47, 0x76, 0xac, 0xb2, 0xb7, + 0x5b, 0xed, 0xd5, 0x6d, 0xcc, 0x97, 0x5e, 0x2b, 0xb7, 0xea, 0x38, 0xfe, + 0x8c, 0xc9, 0x4d, 0xcd, 0x69, 0xff, 0x9f, 0xdf, 0x0b, 0xca, 0xd9, 0x4d, + 0xc6, 0xdf, 0xbb, 0x18, 0xae, 0xae, 0x8c, 0x4d, 0x95, 0x3a, 0x88, 0xb1, + 0x8c, 0x4d, 0xfb, 0xdb, 0x89, 0xa1, 0x05, 0xff, 0x82, 0xe3, 0x31, 0x8e, + 0xe3, 0xd9, 0x47, 0xc7, 0xa1, 0xe8, 0xb7, 0x68, 0xc6, 0x07, 0x71, 0x68, + 0xc1, 0xff, 0x71, 0x5b, 0x80, 0x83, 0x17, 0x8a, 0x59, 0x3e, 0xdf, 0xce, + 0xbc, 0xde, 0xa2, 0x77, 0x31, 0x5a, 0x57, 0xc7, 0xbd, 0xb1, 0x55, 0x71, + 0xaf, 0x6d, 0xe2, 0xda, 0x5f, 0xd2, 0x71, 0x6f, 0xc0, 0x63, 0xee, 0x25, + 0x1a, 0x47, 0xb9, 0xc0, 0x42, 0x7e, 0x53, 0x21, 0x3e, 0xd0, 0x47, 0x81, + 0x9f, 0x35, 0xfd, 0x8b, 0xe0, 0x73, 0x72, 0x0d, 0xb9, 0xf9, 0xb8, 0xed, + 0x44, 0xb8, 0xf7, 0x73, 0x12, 0xe4, 0xeb, 0x76, 0x83, 0x16, 0xc6, 0x56, + 0x71, 0x23, 0x0f, 0x3f, 0x35, 0xf7, 0x2a, 0xc3, 0x7e, 0x61, 0x1c, 0xdf, + 0xf8, 0xee, 0x5a, 0xc9, 0xaf, 0xc8, 0x9f, 0x74, 0x33, 0x0d, 0x8d, 0x73, + 0xcf, 0x5f, 0xc6, 0x77, 0x8b, 0x0f, 0x73, 0x3f, 0xa2, 0xd9, 0xae, 0xf1, + 0xbb, 0x29, 0xbf, 0x95, 0x8a, 0x75, 0x67, 0x9f, 0x0b, 0x1d, 0xe0, 0xbd, + 0xe1, 0x28, 0xbe, 0x26, 0xa4, 0x34, 0x2b, 0x89, 0x64, 0x8e, 0xdf, 0x00, + 0x68, 0xff, 0x7f, 0x68, 0xf6, 0x99, 0x92, 0x7d, 0x33, 0x41, 0xce, 0x53, + 0x5d, 0xf0, 0x5e, 0xdc, 0xe3, 0xe0, 0x43, 0xe6, 0x50, 0x98, 0xf3, 0x54, + 0xc1, 0xbd, 0xb8, 0x43, 0x1f, 0xdd, 0xbd, 0x38, 0xce, 0x6f, 0xcb, 0x9e, + 0x35, 0xee, 0xc5, 0xc5, 0x2e, 0xf1, 0x5e, 0xdc, 0x26, 0x9d, 0xf3, 0xe4, + 0x3c, 0x41, 0xce, 0x93, 0xe5, 0xad, 0x03, 0xcc, 0x95, 0xf0, 0xee, 0xdb, + 0xa0, 0xbe, 0x2f, 0xbc, 0x75, 0xe0, 0xe7, 0x11, 0xa3, 0xfc, 0x75, 0xfb, + 0xc7, 0x1f, 0xa3, 0x70, 0x2f, 0xbf, 0x11, 0x7c, 0xdf, 0x95, 0xcb, 0xc9, + 0x03, 0x7c, 0xb8, 0xbc, 0xe6, 0x3e, 0x9d, 0xd7, 0x7c, 0xa7, 0x3d, 0x9a, + 0xd7, 0x54, 0x17, 0xb9, 0x1b, 0xb6, 0x6f, 0x8d, 0xbc, 0x66, 0x3c, 0x72, + 0x37, 0x2c, 0x6e, 0xee, 0x86, 0x6d, 0x72, 0x11, 0x4b, 0x9a, 0x3c, 0xa6, + 0xba, 0xe0, 0xdd, 0xb0, 0xce, 0x0d, 0x1f, 0x3e, 0x8f, 0xb9, 0xea, 0x6e, + 0x18, 0x6c, 0xdd, 0x16, 0x49, 0x5f, 0x56, 0xdc, 0xf3, 0x61, 0x62, 0x1e, + 0xde, 0xab, 0x6f, 0xc1, 0x9e, 0xe3, 0xb2, 0x27, 0x49, 0xf9, 0xe4, 0xdd, + 0xc6, 0x3e, 0xe8, 0x02, 0x9e, 0x3e, 0xcb, 0xfd, 0x3c, 0x23, 0x6b, 0xa4, + 0x6f, 0xe5, 0x3d, 0x84, 0xe5, 0x3b, 0xbd, 0x89, 0xc6, 0x9d, 0xde, 0x29, + 0xc8, 0x8d, 0x9a, 0x49, 0xc8, 0x7c, 0x44, 0xa6, 0x26, 0x3d, 0xf8, 0x4b, + 0xb3, 0x8e, 0x69, 0xe7, 0xff, 0xef, 0x48, 0x02, 0xf3, 0x78, 0x0f, 0xb8, + 0x43, 0x62, 0xb3, 0xc1, 0x37, 0xcb, 0xe0, 0xff, 0xb8, 0xa4, 0xd0, 0x87, + 0x77, 0x3c, 0xe3, 0xb2, 0x5f, 0xe7, 0x2c, 0x42, 0x59, 0xfe, 0x35, 0xf0, + 0x78, 0x73, 0x7e, 0xb9, 0x9c, 0x5c, 0xc3, 0xee, 0x27, 0xa5, 0x3c, 0x43, + 0x79, 0xbe, 0xc1, 0xfc, 0xff, 0x82, 0xd3, 0x52, 0xf6, 0x4f, 0x99, 0xf8, + 0x42, 0x7f, 0xdb, 0x01, 0x2f, 0xb7, 0x18, 0x1b, 0x8c, 0x67, 0x75, 0x0b, + 0x6d, 0x1e, 0xd6, 0x38, 0x2e, 0xc3, 0xd3, 0x3b, 0x52, 0x7b, 0x81, 0x77, + 0x63, 0x7a, 0xcd, 0xcb, 0xe1, 0xb9, 0x75, 0x9e, 0xef, 0x8d, 0x97, 0xca, + 0xf7, 0xd0, 0x3f, 0xae, 0x62, 0x7f, 0x5b, 0x20, 0x1f, 0x5f, 0x95, 0xe2, + 0xb1, 0x6b, 0x65, 0xf8, 0x68, 0x06, 0xf4, 0xbc, 0x5f, 0x2f, 0x67, 0xe1, + 0x4b, 0x3f, 0xcd, 0x7b, 0x63, 0xc0, 0x50, 0xf0, 0xed, 0xf9, 0x55, 0xdf, + 0xb1, 0xa3, 0x77, 0xcd, 0xfa, 0x1b, 0x77, 0x87, 0x9e, 0xf5, 0x25, 0xd1, + 0x49, 0x9a, 0x67, 0x96, 0xef, 0x8f, 0x2f, 0xfa, 0xbb, 0xb4, 0x6d, 0x7b, + 0xc6, 0x5f, 0x91, 0xfb, 0xd1, 0x67, 0x38, 0x5e, 0xfb, 0x1e, 0xec, 0xdb, + 0x39, 0x8b, 0xf6, 0x6d, 0xca, 0x93, 0xab, 0x63, 0xc2, 0xf3, 0x10, 0x0b, + 0x3c, 0xd0, 0x77, 0x38, 0x82, 0xef, 0xfb, 0x3d, 0xfa, 0x5c, 0x03, 0xac, + 0x58, 0x88, 0xdc, 0xc1, 0x58, 0x3e, 0xdb, 0xe0, 0x6e, 0x46, 0x70, 0x16, + 0xc1, 0xfd, 0x11, 0xed, 0x6f, 0x1e, 0xdc, 0xe3, 0x06, 0xf7, 0x47, 0x7a, + 0x67, 0x59, 0xd7, 0xd5, 0x64, 0xfb, 0x12, 0x90, 0x01, 0xde, 0x3b, 0xe2, + 0xbd, 0x71, 0xd2, 0xac, 0x73, 0x1d, 0xff, 0x47, 0xdd, 0xd5, 0xc7, 0xb6, + 0x75, 0x5d, 0xf7, 0xc3, 0x47, 0xea, 0xc3, 0xb4, 0x2c, 0x53, 0x32, 0x25, + 0xd3, 0x96, 0x2c, 0xbf, 0x27, 0x3d, 0x59, 0x72, 0xac, 0x14, 0xac, 0xab, + 0xad, 0x02, 0x46, 0xa4, 0x0c, 0x49, 0x7f, 0xb4, 0x08, 0x06, 0xfa, 0xa3, + 0x99, 0x8b, 0x66, 0xab, 0x4b, 0xd9, 0x4e, 0x0a, 0xf4, 0x0f, 0xb7, 0xc5, + 0x80, 0x6c, 0x58, 0x60, 0x86, 0xb4, 0x12, 0x63, 0x56, 0x4c, 0xd6, 0x66, + 0x85, 0x0c, 0xd8, 0x30, 0x4e, 0x54, 0x9c, 0x14, 0x50, 0xc6, 0x04, 0x69, + 0x83, 0xa2, 0x58, 0x61, 0x45, 0x76, 0x36, 0x6c, 0x7f, 0x65, 0x43, 0xd0, + 0x05, 0x9b, 0xb3, 0x38, 0x76, 0xb0, 0x06, 0x45, 0xd6, 0x7d, 0x62, 0x18, + 0xd0, 0x0d, 0xdc, 0xf9, 0xdd, 0x0f, 0xf2, 0xf1, 0xf1, 0x51, 0x1f, 0x89, + 0x33, 0x60, 0x02, 0x04, 0xbe, 0xf7, 0x78, 0xdf, 0x7b, 0xf7, 0x9e, 0x7b, + 0xce, 0xb9, 0xbf, 0x73, 0xee, 0x39, 0x87, 0x9e, 0x7b, 0xdb, 0x9b, 0xf3, + 0xb9, 0xca, 0x77, 0x8e, 0x8a, 0x77, 0x0e, 0x28, 0x9d, 0xa5, 0xe3, 0xc5, + 0x63, 0xc6, 0x6c, 0x61, 0x22, 0xe2, 0x67, 0xfe, 0x9e, 0xad, 0xc2, 0xbe, + 0x6e, 0x87, 0xe1, 0xd6, 0xa2, 0x67, 0xbc, 0x85, 0x9e, 0xcd, 0x32, 0xc1, + 0xf6, 0x78, 0x5d, 0x77, 0x4b, 0xda, 0xc9, 0xeb, 0x88, 0x85, 0xd7, 0x31, + 0x0e, 0x92, 0x76, 0x75, 0x19, 0xba, 0xe2, 0x8c, 0x6f, 0x68, 0xd0, 0xee, + 0x74, 0x9d, 0x76, 0x3b, 0xff, 0x1f, 0xd1, 0xee, 0x1d, 0x81, 0x7f, 0x5f, + 0xad, 0x22, 0x6e, 0x4d, 0x63, 0x00, 0x9d, 0x3b, 0x04, 0x3a, 0x42, 0x9f, + 0x5a, 0xe5, 0x15, 0x82, 0x4e, 0x45, 0x5c, 0x71, 0xad, 0xf6, 0x5a, 0xb4, + 0xee, 0xa7, 0x64, 0xbb, 0x04, 0xf6, 0x09, 0xfc, 0x79, 0xed, 0xd7, 0xc8, + 0x63, 0x1f, 0x6b, 0x8d, 0x04, 0x56, 0x72, 0xdb, 0x27, 0x0c, 0x08, 0x1d, + 0xf6, 0xc9, 0xb1, 0x4d, 0xda, 0x27, 0xe7, 0xa5, 0x7d, 0x92, 0xdd, 0xb8, + 0x7d, 0xb2, 0xbb, 0x25, 0xae, 0xab, 0x31, 0x9e, 0xcd, 0xdb, 0x27, 0xc6, + 0x9a, 0xf6, 0xc9, 0x90, 0xc3, 0x17, 0x83, 0xfe, 0xfe, 0x06, 0x65, 0x8f, + 0x43, 0xc7, 0x69, 0x3a, 0x83, 0xc6, 0xc7, 0x5d, 0x7e, 0xe1, 0x4f, 0x93, + 0xd6, 0xbf, 0xf8, 0x3f, 0xa6, 0xf5, 0x50, 0x8b, 0xcf, 0xbb, 0x31, 0x1e, + 0x0a, 0xef, 0xd8, 0x14, 0x8e, 0x77, 0xd3, 0x7a, 0xa8, 0xad, 0xef, 0xb4, + 0x7d, 0xcc, 0x62, 0xb3, 0xef, 0x74, 0xd4, 0x68, 0xa7, 0xdb, 0xff, 0xd8, + 0xe1, 0x53, 0x75, 0xea, 0x77, 0xc8, 0x14, 0xf9, 0x8e, 0x4d, 0xe8, 0x77, + 0x41, 0x96, 0xac, 0x6c, 0x96, 0x60, 0x33, 0xe1, 0x7d, 0x11, 0x21, 0x6b, + 0x2e, 0xbc, 0xc5, 0xef, 0x63, 0x7a, 0xbe, 0xf8, 0x87, 0x62, 0x9d, 0x92, + 0xfe, 0x07, 0xb4, 0x0f, 0xfb, 0xce, 0x88, 0xb6, 0x32, 0xbe, 0x49, 0xf9, + 0x23, 0x14, 0xf6, 0x6f, 0xe7, 0x87, 0x68, 0x5d, 0xf3, 0x36, 0x67, 0x2b, + 0x68, 0x19, 0xdf, 0xcb, 0xf3, 0x12, 0x69, 0xb2, 0xb5, 0xa0, 0x3f, 0xcf, + 0x33, 0x2e, 0x18, 0xad, 0x63, 0x82, 0xe6, 0xb9, 0xb9, 0x28, 0x6c, 0x3a, + 0xad, 0x3b, 0x57, 0x64, 0xec, 0xa9, 0xb8, 0x0e, 0x9c, 0xa6, 0x75, 0xa7, + 0x1b, 0x07, 0xef, 0xf5, 0xe0, 0x0b, 0xcf, 0xdc, 0x4f, 0x3d, 0x77, 0x26, + 0x62, 0xce, 0x53, 0x9e, 0x73, 0x57, 0xcf, 0xe1, 0xca, 0x36, 0xda, 0xca, + 0xfb, 0x53, 0x62, 0x5c, 0xdf, 0xfc, 0x62, 0x02, 0xb9, 0x6a, 0xf5, 0xfc, + 0x21, 0x77, 0xce, 0x14, 0xd6, 0x01, 0x2d, 0x87, 0x3a, 0x3f, 0x1b, 0xb4, + 0x18, 0xf1, 0xc8, 0x99, 0x72, 0xae, 0x25, 0xb8, 0xcf, 0x4d, 0x8b, 0xc6, + 0x3a, 0x32, 0xa7, 0xd6, 0x91, 0x45, 0x87, 0x1e, 0x6f, 0xc5, 0xed, 0xfd, + 0x1e, 0xb8, 0xdd, 0x2b, 0x6f, 0x0a, 0x7d, 0x7a, 0x92, 0x71, 0xc8, 0x67, + 0x80, 0x43, 0x42, 0xc8, 0x5b, 0x92, 0x58, 0x04, 0xdf, 0x17, 0x19, 0x8f, + 0x44, 0x98, 0x57, 0x7e, 0x44, 0xe7, 0x18, 0x6b, 0x5f, 0xa7, 0xfd, 0xca, + 0x3e, 0x83, 0xdc, 0xea, 0x38, 0x53, 0xc4, 0xf1, 0xfb, 0x28, 0xfb, 0x98, + 0x35, 0x19, 0xa7, 0x1f, 0xd1, 0x59, 0x11, 0x33, 0x83, 0xfd, 0x3d, 0xc4, + 0x1c, 0x3c, 0x20, 0xde, 0x2f, 0x7d, 0x19, 0xf7, 0x23, 0xa6, 0x6e, 0xe3, + 0xf1, 0xfb, 0x2a, 0xb7, 0x8e, 0xdb, 0xe1, 0x9d, 0x4b, 0x4a, 0xa6, 0xc4, + 0x35, 0xbe, 0xff, 0x49, 0xa3, 0xf5, 0xfe, 0xb8, 0x91, 0xaa, 0xa6, 0x8c, + 0x44, 0x05, 0xed, 0x9e, 0x34, 0x92, 0x55, 0xd8, 0x90, 0x9a, 0x47, 0xac, + 0x28, 0xe4, 0x6d, 0x95, 0xd6, 0xdf, 0x8b, 0x58, 0x24, 0x57, 0x9e, 0xc4, + 0x06, 0xfa, 0x7d, 0xb8, 0xa9, 0xdf, 0x9a, 0xbe, 0x38, 0x86, 0xbf, 0xe7, + 0x15, 0xa6, 0xa9, 0xc6, 0xb5, 0x41, 0xf8, 0xd7, 0x27, 0xb3, 0xb4, 0x16, + 0xae, 0xb5, 0x5a, 0x70, 0xed, 0xe2, 0xba, 0xfd, 0xfe, 0xa4, 0x32, 0x2e, + 0xf3, 0xa3, 0xfd, 0xb6, 0xc0, 0xaf, 0xdc, 0xef, 0x26, 0x6c, 0xeb, 0xe2, + 0x29, 0xb4, 0xd1, 0x7e, 0x70, 0xed, 0x07, 0xeb, 0x55, 0xf1, 0xc0, 0x3a, + 0x3e, 0x21, 0x88, 0x7c, 0xaf, 0x90, 0x8c, 0x6b, 0x85, 0x8d, 0xb5, 0xc2, + 0xfd, 0x83, 0xbd, 0x05, 0x9f, 0x8f, 0xb0, 0xb7, 0xcc, 0x24, 0x49, 0x5f, + 0xf7, 0x99, 0xaa, 0xd3, 0xbf, 0xeb, 0x95, 0x4b, 0x39, 0xea, 0x91, 0x4b, + 0xe9, 0x94, 0xb5, 0x80, 0x43, 0xd6, 0x22, 0x0e, 0xdc, 0x36, 0xcc, 0x76, + 0x4b, 0x0f, 0xeb, 0x90, 0x1e, 0xb1, 0x6d, 0xe2, 0xbf, 0xea, 0xb4, 0x5b, + 0xdc, 0x79, 0xf1, 0x90, 0x3b, 0x60, 0x33, 0x69, 0xc3, 0xa4, 0x4a, 0xf5, + 0x9c, 0x7a, 0x1e, 0x77, 0x23, 0x6f, 0xb1, 0xd2, 0x92, 0x63, 0xe9, 0xd5, + 0xdf, 0x91, 0x96, 0xfe, 0x62, 0xfd, 0x8a, 0xb7, 0xc5, 0x74, 0x5e, 0x76, + 0xd5, 0xfd, 0xea, 0x9f, 0x5b, 0x9f, 0xe1, 0x5d, 0xa3, 0xc2, 0xe7, 0x9d, + 0xad, 0xeb, 0xb2, 0x19, 0xd9, 0xdf, 0x42, 0xb3, 0x9d, 0xe1, 0xbf, 0x42, + 0x8a, 0x76, 0xde, 0xba, 0x7d, 0x73, 0xfe, 0xb3, 0xad, 0x6e, 0x1c, 0xdc, + 0x27, 0xfd, 0x62, 0x73, 0x2a, 0x0e, 0x7b, 0x40, 0xd9, 0x7b, 0xeb, 0xf1, + 0x3b, 0xae, 0xcd, 0x29, 0x5f, 0xa2, 0x65, 0x96, 0x09, 0x7c, 0x7e, 0xfc, + 0x54, 0x87, 0x1d, 0x52, 0x7b, 0x59, 0xd8, 0xaf, 0x02, 0xdf, 0xeb, 0xe7, + 0x43, 0x67, 0x6f, 0x64, 0xce, 0xcc, 0x96, 0x39, 0x93, 0x7c, 0x05, 0x5b, + 0x0b, 0xf1, 0xc5, 0x53, 0xae, 0x18, 0xef, 0x4f, 0x42, 0x8b, 0x5e, 0x8f, + 0xb8, 0x67, 0xc4, 0x2d, 0xb7, 0xeb, 0xe7, 0x1d, 0x07, 0x2e, 0x47, 0x7f, + 0x6b, 0xb5, 0x57, 0xa2, 0xbb, 0xe5, 0x5a, 0x5c, 0xf5, 0xc6, 0x48, 0xa1, + 0x0d, 0xf7, 0xcf, 0xbd, 0xf6, 0xee, 0xda, 0xe0, 0xda, 0x2b, 0xea, 0x8b, + 0xf8, 0x0e, 0x09, 0x1d, 0xd0, 0x43, 0x95, 0x12, 0xe2, 0xaf, 0x3f, 0x0b, + 0x99, 0x67, 0x3d, 0xeb, 0xc8, 0x49, 0xf3, 0x9e, 0xc7, 0xfa, 0x9e, 0x4a, + 0x20, 0x86, 0xbd, 0x3f, 0xc4, 0x96, 0xf4, 0xb3, 0xee, 0x41, 0xfb, 0x71, + 0xf3, 0x16, 0xfc, 0xbd, 0xca, 0xff, 0x94, 0x52, 0xeb, 0xcb, 0xa1, 0x0d, + 0xec, 0xad, 0x6c, 0x4e, 0x4f, 0x5b, 0xe6, 0x0a, 0x61, 0xdf, 0x07, 0xf1, + 0xc2, 0xc7, 0x7a, 0xa9, 0xf7, 0x2b, 0x5d, 0x5d, 0xf6, 0x1f, 0xf4, 0xc9, + 0xbd, 0x28, 0x7c, 0xd7, 0x43, 0x2f, 0x94, 0x10, 0xcb, 0x8d, 0xef, 0x7e, + 0x8b, 0xbf, 0xf3, 0xd2, 0x51, 0x3a, 0x16, 0x1d, 0x58, 0x4e, 0xce, 0x4f, + 0x99, 0x60, 0x2b, 0xd5, 0xe8, 0x6f, 0xa2, 0x9f, 0x93, 0xfb, 0x19, 0xd5, + 0xfb, 0xbd, 0x57, 0xe3, 0xe5, 0x2f, 0xfc, 0x69, 0xdf, 0xc7, 0x8d, 0x8d, + 0xfc, 0xd6, 0x86, 0xfc, 0x85, 0xd8, 0xe7, 0xdf, 0xc8, 0x9e, 0x89, 0xde, + 0x1b, 0x9e, 0x16, 0x39, 0xa7, 0x4e, 0x3e, 0xb8, 0x3f, 0xfb, 0xc3, 0xe0, + 0x87, 0x91, 0x16, 0x5d, 0xf5, 0xc9, 0xfd, 0xfd, 0x6e, 0xba, 0x06, 0x3d, + 0x7d, 0x55, 0xde, 0xfb, 0xc0, 0xd8, 0xf3, 0x87, 0x9f, 0xba, 0x4a, 0x67, + 0xae, 0x81, 0x87, 0x0d, 0xe6, 0xb6, 0x31, 0xca, 0x87, 0x91, 0x57, 0x24, + 0x72, 0x73, 0xf4, 0xbe, 0xa1, 0xc8, 0x15, 0x3a, 0x23, 0x72, 0x20, 0xc7, + 0x23, 0xf7, 0x78, 0x3d, 0x3c, 0x53, 0x7d, 0x9b, 0xce, 0x56, 0x82, 0xfc, + 0xdf, 0xc0, 0xee, 0xad, 0x79, 0x90, 0xcd, 0x3c, 0x7e, 0x4f, 0xf0, 0xf8, + 0xf0, 0x9a, 0x3c, 0x7e, 0xa4, 0xce, 0xe3, 0x5f, 0xe9, 0x97, 0xfc, 0xdc, + 0xcb, 0xcf, 0xea, 0xa5, 0x43, 0xe2, 0xb9, 0x6f, 0xf3, 0xf1, 0x56, 0x3a, + 0x14, 0x92, 0xc7, 0x67, 0x2b, 0xac, 0xe3, 0x0b, 0x6f, 0xd3, 0xb9, 0x6b, + 0x59, 0x5f, 0x4a, 0xe4, 0x2f, 0x38, 0x6b, 0x69, 0xe8, 0xfb, 0xd1, 0xae, + 0x1d, 0xff, 0x6b, 0xbd, 0x24, 0x73, 0xae, 0xca, 0x52, 0x3f, 0xd1, 0x5b, + 0xd1, 0x21, 0x17, 0xff, 0x37, 0xdb, 0x8e, 0xe7, 0xd5, 0x1a, 0x78, 0x7c, + 0x0d, 0xbf, 0x46, 0x2b, 0x5f, 0xf6, 0x79, 0xe0, 0xe1, 0xa7, 0xfb, 0xe5, + 0x3e, 0xd5, 0x5a, 0x7e, 0x8d, 0xa6, 0xb8, 0x0e, 0xe7, 0xbe, 0x3d, 0xeb, + 0xfd, 0x3d, 0x2a, 0x17, 0xf0, 0x87, 0xfd, 0x72, 0xbd, 0x40, 0x7e, 0xe0, + 0x0a, 0xd3, 0xe1, 0x22, 0x63, 0x95, 0x21, 0xea, 0xbc, 0xaa, 0xc7, 0x3a, + 0x24, 0xf4, 0xad, 0xd3, 0x4f, 0x73, 0x51, 0xe5, 0x76, 0xe7, 0x1c, 0x63, + 0xba, 0x28, 0x6c, 0x9c, 0xf6, 0xf2, 0xd6, 0x3e, 0xe6, 0x6a, 0xd8, 0xb5, + 0x26, 0xb8, 0xf9, 0x0d, 0x75, 0x4a, 0x30, 0xbf, 0x64, 0x48, 0x1c, 0x3c, + 0xc3, 0xf8, 0x76, 0xb3, 0xfb, 0x45, 0x9f, 0x14, 0x23, 0xba, 0x6b, 0x60, + 0xb8, 0x8f, 0x31, 0x0f, 0xd2, 0xe6, 0xc8, 0xbc, 0x58, 0x15, 0xba, 0xe0, + 0xe2, 0x54, 0x8d, 0x92, 0xd1, 0x6d, 0x94, 0x99, 0xe2, 0x77, 0xcf, 0xd8, + 0x6c, 0x7b, 0xf9, 0x29, 0xcb, 0xf2, 0x9b, 0x99, 0xda, 0xa2, 0xf0, 0xa2, + 0xf6, 0xa7, 0x77, 0xa9, 0x38, 0x87, 0x5e, 0xb1, 0x2f, 0x29, 0x6b, 0xf5, + 0xf0, 0x71, 0x45, 0x3f, 0x1b, 0xd7, 0xc1, 0xbb, 0x9d, 0xaa, 0xdd, 0x65, + 0x47, 0x3b, 0xb4, 0xb9, 0xac, 0xda, 0xe2, 0x99, 0x1a, 0x53, 0x74, 0x2b, + 0x7d, 0x0b, 0x39, 0x5c, 0x51, 0xb9, 0x7a, 0xc2, 0x7e, 0xa0, 0xd9, 0xfa, + 0x58, 0x2e, 0x73, 0xdb, 0xff, 0xae, 0xc5, 0x85, 0x2d, 0x77, 0x99, 0x31, + 0x6f, 0x55, 0xc8, 0x8a, 0xbb, 0x4f, 0x18, 0x8b, 0x5f, 0xec, 0x0f, 0xf1, + 0xb1, 0x7a, 0xcf, 0xe9, 0x7a, 0x9f, 0x10, 0xa3, 0x61, 0x45, 0xe4, 0xb3, + 0x74, 0xbb, 0xcb, 0x8e, 0x76, 0x5a, 0x57, 0xe8, 0xfd, 0x87, 0x8f, 0x7c, + 0xb3, 0x85, 0xdb, 0x3e, 0x19, 0xc3, 0x1b, 0x12, 0xfb, 0xa7, 0x32, 0x46, + 0x43, 0x1f, 0xc3, 0xbf, 0x8c, 0x98, 0x0a, 0xc4, 0x49, 0x38, 0xf5, 0x8d, + 0x1c, 0x6f, 0x00, 0x6b, 0x51, 0x15, 0xfb, 0xa6, 0xd8, 0xaf, 0x68, 0x87, + 0x9d, 0x77, 0x21, 0x36, 0x7f, 0x13, 0x18, 0x74, 0x23, 0xf2, 0x67, 0x7a, + 0xc8, 0x9f, 0xf3, 0xfd, 0xc8, 0x83, 0x43, 0x3e, 0x5c, 0x76, 0xd2, 0xa0, + 0x1a, 0xdb, 0x0a, 0x06, 0x95, 0x43, 0x3e, 0x3a, 0x67, 0x5b, 0xd1, 0x8a, + 0xc0, 0x9a, 0x8f, 0xc0, 0x7f, 0x35, 0xb9, 0x42, 0x07, 0x44, 0xce, 0x38, + 0x6a, 0x1f, 0x94, 0x79, 0x0d, 0x3e, 0xcd, 0x3c, 0x78, 0x96, 0xed, 0x8f, + 0xec, 0x49, 0xec, 0xb7, 0xe8, 0x79, 0x41, 0x0e, 0x3c, 0x3e, 0x4d, 0x9e, + 0xbb, 0xdf, 0xdd, 0x41, 0xc1, 0x38, 0x3f, 0xd3, 0x84, 0x7e, 0xe2, 0xe7, + 0xa4, 0x29, 0xc1, 0x76, 0x12, 0x6c, 0xd6, 0xd3, 0x27, 0xad, 0x50, 0x99, + 0x0c, 0x6e, 0x0b, 0xdb, 0x15, 0xcf, 0xc1, 0xfd, 0xf1, 0x50, 0x07, 0xb9, + 0x73, 0x72, 0x7b, 0x45, 0x9e, 0xe2, 0x5b, 0xd1, 0x07, 0xc9, 0x18, 0x84, + 0xbe, 0xc2, 0xbc, 0x3d, 0xa0, 0xf6, 0x89, 0xb6, 0xf3, 0xf1, 0x84, 0x3a, + 0x0e, 0x8a, 0xf9, 0x94, 0xc7, 0x9a, 0xbf, 0xf1, 0xf7, 0xf3, 0x2e, 0xb2, + 0xfd, 0x6a, 0xfe, 0x9a, 0x62, 0x41, 0x22, 0x63, 0x46, 0x90, 0xce, 0x57, + 0xd6, 0xf2, 0xbf, 0x78, 0xe5, 0xba, 0x6e, 0xdf, 0x60, 0xae, 0xeb, 0x4f, + 0x76, 0xc8, 0xdc, 0x32, 0x67, 0x5f, 0xfe, 0x93, 0xfb, 0xe2, 0x85, 0xc9, + 0x5a, 0x70, 0x22, 0x8f, 0xb7, 0x46, 0x3f, 0x8b, 0x7e, 0x9e, 0xee, 0x84, + 0x23, 0x2a, 0x66, 0x09, 0x31, 0x4a, 0x0f, 0x2a, 0xbe, 0xd6, 0xba, 0x9f, + 0x3c, 0x74, 0xff, 0xa3, 0x22, 0x56, 0x53, 0xae, 0x1d, 0x43, 0x8a, 0x1e, + 0xa0, 0x59, 0xc4, 0x41, 0xb3, 0x01, 0x07, 0xcd, 0x0c, 0x75, 0xbc, 0x4d, + 0x9c, 0x9f, 0xaf, 0x3c, 0xb5, 0x5d, 0xe6, 0x8b, 0x63, 0x2f, 0xf1, 0x92, + 0x3a, 0x5e, 0x6f, 0xbc, 0x56, 0x98, 0x82, 0xc2, 0xdf, 0xe4, 0x18, 0xeb, + 0xcb, 0x44, 0xf6, 0x81, 0x70, 0x2b, 0x0d, 0x5e, 0x73, 0x5c, 0x47, 0x1f, + 0xc7, 0x1d, 0x7d, 0x1c, 0x75, 0xf4, 0x71, 0x6f, 0x9b, 0x3e, 0xb2, 0x8e, + 0xe7, 0xf7, 0x9c, 0xad, 0x7e, 0xdc, 0xbe, 0xa2, 0x9f, 0xc8, 0x23, 0x06, + 0x3d, 0xb7, 0x52, 0x2e, 0x1c, 0x51, 0x6b, 0xc7, 0x2f, 0x55, 0x2e, 0xba, + 0x57, 0x9f, 0xff, 0x8e, 0xda, 0xcf, 0x9b, 0x93, 0x57, 0x9d, 0xf9, 0xc7, + 0xdf, 0xa5, 0xa4, 0xcc, 0x23, 0x57, 0xb2, 0x7d, 0xb9, 0x8d, 0x1f, 0x1a, + 0xf1, 0x1c, 0xc0, 0x20, 0xc2, 0x2e, 0xdc, 0x2d, 0x6b, 0xc1, 0x05, 0x68, + 0xa9, 0x9e, 0xcb, 0xeb, 0x57, 0xb9, 0x3b, 0xc7, 0xc3, 0xf7, 0x37, 0x8f, + 0x17, 0xd7, 0xff, 0x4c, 0xf8, 0xf2, 0xe4, 0xfe, 0xd1, 0x8a, 0xca, 0x47, + 0xb6, 0x4c, 0xc4, 0x06, 0x2c, 0x2e, 0xc3, 0xff, 0xda, 0x2e, 0x77, 0x57, + 0xea, 0xa2, 0x4c, 0xbd, 0x3e, 0x4a, 0x59, 0xe4, 0x35, 0x48, 0xff, 0x98, + 0xcc, 0xbf, 0x5d, 0x5c, 0xbe, 0x25, 0x72, 0x5e, 0x13, 0x2a, 0x8f, 0x37, + 0x43, 0x3d, 0x02, 0xe7, 0x7e, 0xfc, 0xfc, 0xdb, 0x17, 0xc2, 0x9b, 0xcf, + 0xbf, 0x75, 0xde, 0xb3, 0xb9, 0xfc, 0xdb, 0x10, 0x8f, 0xdd, 0x58, 0x90, + 0xf9, 0xb7, 0xcd, 0x7b, 0x32, 0x32, 0xff, 0x36, 0xe3, 0xc0, 0x0f, 0x12, + 0xaf, 0xbf, 0xe5, 0x88, 0xdf, 0x96, 0xb9, 0xb5, 0x8b, 0x75, 0xcc, 0x2a, + 0x73, 0x6b, 0x65, 0xbc, 0xb7, 0xb3, 0x0e, 0x8c, 0xdc, 0xfb, 0x91, 0xef, + 0xd9, 0xe6, 0xda, 0xfb, 0x91, 0x39, 0xb5, 0xa6, 0xd1, 0xce, 0x86, 0xc3, + 0x1a, 0x81, 0x7a, 0x08, 0x71, 0xe6, 0xdd, 0xad, 0x6d, 0xea, 0x21, 0xc4, + 0xdb, 0xd4, 0x43, 0x70, 0xea, 0x7e, 0x27, 0xc6, 0x02, 0x26, 0xc6, 0xda, + 0x08, 0x2c, 0x8c, 0x7a, 0x06, 0x51, 0x3a, 0x5f, 0xc7, 0x9e, 0x0f, 0x52, + 0x5a, 0x61, 0xcf, 0xf3, 0x15, 0xad, 0x8f, 0x46, 0x5d, 0xfa, 0xc8, 0x0b, + 0x8b, 0x5a, 0x2a, 0xce, 0x47, 0xcb, 0x6b, 0xd6, 0x21, 0xaf, 0x59, 0x0f, + 0x79, 0xc5, 0x3d, 0xd9, 0x36, 0xfd, 0xfe, 0xa5, 0xba, 0x07, 0xff, 0x4f, + 0x46, 0x50, 0xb3, 0x85, 0x68, 0xf7, 0x80, 0xc2, 0x7f, 0x0e, 0x79, 0x3d, + 0xcb, 0xf2, 0xaa, 0xaf, 0xa3, 0xbf, 0xed, 0x6c, 0x00, 0x8d, 0x19, 0x87, + 0x7c, 0x87, 0xaf, 0xbd, 0x21, 0xe2, 0xa4, 0x9a, 0xed, 0x45, 0x8d, 0x27, + 0xf6, 0x09, 0x59, 0xba, 0xe3, 0x47, 0xdc, 0x8a, 0xbe, 0x16, 0x52, 0x7e, + 0x32, 0x4d, 0x8b, 0xce, 0x26, 0xcc, 0xd1, 0xc0, 0x1b, 0x22, 0xc6, 0xd7, + 0xd1, 0xb7, 0x7f, 0xe5, 0xbe, 0xe9, 0xeb, 0x7a, 0xcd, 0x7c, 0xa7, 0xc9, + 0x9f, 0x71, 0xa3, 0xa9, 0xee, 0x1f, 0x7c, 0x47, 0xdb, 0xd2, 0x86, 0x9d, + 0x12, 0x31, 0xa6, 0x7d, 0x36, 0xfc, 0x64, 0x09, 0x96, 0xfd, 0xbe, 0x34, + 0xe2, 0x99, 0xfb, 0xae, 0x98, 0x74, 0xa2, 0x70, 0x7e, 0x8f, 0xe4, 0x95, + 0x0b, 0xa2, 0xa6, 0x25, 0x6a, 0x20, 0x26, 0x79, 0x7d, 0x4e, 0x30, 0xe8, + 0x9c, 0xab, 0x76, 0xd1, 0x22, 0xa3, 0x7b, 0xbf, 0x5d, 0x16, 0xbe, 0x3e, + 0xd6, 0x49, 0x45, 0xd4, 0x36, 0x35, 0x16, 0x3a, 0xf9, 0xb9, 0x83, 0xb4, + 0x54, 0x1a, 0x17, 0x35, 0xa1, 0x64, 0x7d, 0x11, 0xb4, 0xf5, 0x51, 0xbf, + 0xfd, 0x0d, 0xa6, 0xdd, 0xd7, 0x44, 0x8c, 0xe5, 0x62, 0xf1, 0x82, 0xfc, + 0x2c, 0x3f, 0xa5, 0xde, 0xc1, 0xef, 0xab, 0xfe, 0x98, 0xe2, 0xfd, 0xa6, + 0xc3, 0x96, 0x73, 0xfe, 0x79, 0xe3, 0x95, 0x63, 0x9b, 0xc2, 0x2b, 0xd9, + 0x74, 0x03, 0xaf, 0x38, 0x9f, 0xad, 0xb1, 0xcb, 0xe4, 0xa0, 0xac, 0xf7, + 0x00, 0x1a, 0x6c, 0x05, 0x16, 0x4b, 0x83, 0x96, 0x46, 0xcc, 0x8a, 0x24, + 0xfc, 0x33, 0x94, 0xaf, 0x5e, 0xa7, 0x4c, 0x11, 0x98, 0x99, 0x3f, 0xcb, + 0xe7, 0x76, 0x4a, 0x1f, 0x8d, 0xbe, 0x07, 0x7a, 0x65, 0x07, 0xb7, 0xff, + 0xeb, 0x41, 0x19, 0x97, 0xed, 0xbc, 0xde, 0xcb, 0xd7, 0xbf, 0x10, 0x69, + 0xbe, 0xbe, 0x85, 0xaf, 0xf7, 0xa7, 0x31, 0x87, 0xc6, 0x15, 0xf8, 0x25, + 0x27, 0x29, 0xc7, 0xf3, 0x93, 0xaf, 0xf2, 0xda, 0x7a, 0x95, 0xf5, 0x55, + 0x45, 0xb7, 0x1b, 0x40, 0xce, 0x8e, 0x98, 0x13, 0x83, 0xdb, 0x5c, 0x2c, + 0x4c, 0x71, 0xbb, 0x21, 0xf2, 0x5f, 0x35, 0x29, 0x5f, 0xd1, 0xbc, 0xaa, + 0xe3, 0xed, 0xdf, 0x18, 0x90, 0x31, 0x55, 0xef, 0xec, 0x94, 0xf4, 0x9b, + 0x14, 0x3e, 0x4f, 0xc4, 0x73, 0x3c, 0x23, 0xf8, 0xd0, 0x9a, 0x31, 0xeb, + 0xef, 0xdf, 0x06, 0xbe, 0x42, 0xdd, 0x54, 0x1e, 0x03, 0xeb, 0xc5, 0x98, + 0x1d, 0xca, 0xd5, 0x63, 0xd5, 0x9e, 0xdb, 0x2d, 0xef, 0xff, 0xe9, 0x80, + 0xac, 0x55, 0x7a, 0x5b, 0x9d, 0xeb, 0x35, 0x07, 0xf1, 0xcb, 0x3e, 0x41, + 0x1b, 0xff, 0x02, 0xf4, 0xa5, 0xc1, 0xc7, 0x3c, 0x9e, 0x34, 0xfa, 0xf8, + 0xb3, 0x01, 0x5d, 0x9f, 0x50, 0x8e, 0xeb, 0x28, 0xf7, 0x37, 0xc5, 0xe3, + 0xd2, 0xd7, 0xe3, 0x7c, 0xee, 0x35, 0xbf, 0x78, 0x56, 0x30, 0x2d, 0xeb, + 0x8b, 0x05, 0xd3, 0x99, 0x49, 0x39, 0xcf, 0x0d, 0x9f, 0x6e, 0xa4, 0xee, + 0xd3, 0x9d, 0x2b, 0xf4, 0x0f, 0xc2, 0xbf, 0x61, 0x5c, 0xe1, 0xf9, 0x0e, + 0x3f, 0xc3, 0x6d, 0x91, 0xab, 0x90, 0xe3, 0xcf, 0x1e, 0x15, 0xd7, 0xd3, + 0xca, 0x2b, 0x32, 0x4e, 0x42, 0xaf, 0x5b, 0xb8, 0x77, 0x80, 0x9f, 0x21, + 0xd7, 0xae, 0xf6, 0xef, 0xa1, 0x96, 0x38, 0x98, 0x56, 0x1e, 0x5b, 0xcb, + 0x0f, 0x2b, 0xf6, 0x13, 0x3d, 0xf8, 0x6c, 0xad, 0x7a, 0x06, 0xef, 0x08, + 0x3f, 0x5a, 0xb2, 0x45, 0x5e, 0x21, 0xc7, 0x01, 0xfa, 0xce, 0x7c, 0x96, + 0xb6, 0xf0, 0x5c, 0x7d, 0xc3, 0xf8, 0x35, 0xec, 0xb7, 0x93, 0x8c, 0x79, + 0x62, 0x1a, 0x17, 0xec, 0xc9, 0xb3, 0x06, 0xd3, 0xb9, 0x90, 0xad, 0x05, + 0xec, 0x1e, 0xea, 0x64, 0x59, 0xfd, 0x22, 0x8d, 0xb1, 0xfd, 0x07, 0x99, + 0xb5, 0x23, 0x29, 0x82, 0xbc, 0x59, 0xa1, 0xc3, 0xcc, 0x13, 0xc9, 0x2a, + 0xf8, 0xd9, 0xa0, 0x27, 0x4a, 0x44, 0x8f, 0x97, 0xc6, 0x42, 0xdf, 0x27, + 0xdb, 0x6c, 0x7c, 0x6f, 0x85, 0x12, 0xdc, 0x8f, 0x54, 0xf5, 0x77, 0xe8, + 0x43, 0x51, 0xe7, 0x04, 0x74, 0xd4, 0xf3, 0xfe, 0xdb, 0x74, 0x3a, 0x8d, + 0x7e, 0x6f, 0x5c, 0x3e, 0x4f, 0x6c, 0x4a, 0x3e, 0x83, 0x1e, 0xf2, 0xf9, + 0xea, 0xa0, 0xe4, 0x9b, 0x1a, 0xf3, 0x68, 0x90, 0x66, 0x8b, 0x88, 0x01, + 0x7b, 0x18, 0x75, 0xa7, 0x8a, 0x19, 0xd6, 0x4b, 0x99, 0x86, 0x5e, 0xba, + 0x94, 0xf0, 0xc7, 0x21, 0xe3, 0xa8, 0xcb, 0xa6, 0xe2, 0x7e, 0x30, 0x8e, + 0xdd, 0x34, 0xb6, 0xb0, 0x95, 0xef, 0xa5, 0x95, 0xc4, 0x74, 0x5c, 0xe5, + 0xfa, 0x5b, 0x66, 0x92, 0xf5, 0xe3, 0x1c, 0xcb, 0x72, 0xae, 0xf8, 0x00, + 0x2d, 0x86, 0x87, 0x69, 0x74, 0x41, 0xd7, 0x37, 0xc1, 0x58, 0xff, 0x6d, + 0x48, 0xea, 0x24, 0x3d, 0xee, 0x5f, 0x11, 0xbe, 0x0b, 0xf3, 0xfa, 0xa7, + 0x35, 0xee, 0xad, 0xeb, 0xe8, 0xa5, 0xbf, 0x52, 0x32, 0x5b, 0xbb, 0x91, + 0x88, 0x52, 0x36, 0x31, 0xfd, 0x97, 0x82, 0xff, 0x47, 0xaf, 0xc3, 0x0f, + 0x07, 0x1d, 0x6d, 0x52, 0xba, 0xe0, 0xa6, 0xc5, 0x30, 0x8f, 0x1b, 0xdf, + 0xd7, 0xfe, 0x79, 0x36, 0xfa, 0x94, 0x58, 0xfb, 0xc7, 0xae, 0x73, 0x3b, + 0xb1, 0x36, 0x69, 0xbd, 0xe1, 0xc5, 0x87, 0xba, 0x8e, 0xa5, 0xe6, 0x45, + 0x19, 0xeb, 0xc9, 0xf8, 0x2d, 0x94, 0xf6, 0xbb, 0x79, 0xf2, 0x23, 0x3a, + 0x36, 0x6f, 0xd2, 0xf1, 0x82, 0xf5, 0x7c, 0x96, 0x66, 0x58, 0xae, 0x9d, + 0xeb, 0x05, 0xb7, 0x27, 0xf0, 0x59, 0x8c, 0x65, 0x9f, 0xed, 0xe6, 0xa2, + 0x29, 0xe3, 0xee, 0x44, 0xed, 0xb9, 0x2e, 0xa1, 0x47, 0x43, 0xf6, 0x3f, + 0x0d, 0xea, 0xf5, 0x20, 0x53, 0x44, 0x1e, 0x21, 0x7f, 0x96, 0xb9, 0x7d, + 0x61, 0x90, 0x32, 0x25, 0x3c, 0x07, 0xeb, 0x1d, 0xfa, 0xce, 0xe7, 0x4b, + 0x72, 0x5e, 0x47, 0xf9, 0xd9, 0xc8, 0xbb, 0x3f, 0x5e, 0x9d, 0x12, 0xb1, + 0x77, 0xd0, 0xcd, 0x72, 0x3e, 0x63, 0x74, 0xd1, 0x53, 0xaf, 0x28, 0x4c, + 0xe9, 0x90, 0xef, 0x8c, 0x90, 0xef, 0x98, 0x98, 0x8f, 0x4c, 0xc9, 0x60, + 0xbc, 0xa6, 0x7d, 0x0f, 0xfd, 0x7c, 0x1e, 0x50, 0x3a, 0x04, 0xdf, 0x0d, + 0xec, 0x14, 0x71, 0x89, 0x36, 0xae, 0xe3, 0x33, 0x46, 0xcf, 0x30, 0xee, + 0x7c, 0xb6, 0xd0, 0x45, 0xb7, 0x8a, 0x5d, 0xf4, 0x66, 0x71, 0x98, 0x6e, + 0xce, 0x6f, 0xa7, 0x8b, 0x8c, 0x99, 0x2f, 0xda, 0x01, 0x33, 0xc7, 0xf6, + 0xc5, 0x0b, 0x51, 0x11, 0x33, 0xc4, 0x72, 0x87, 0xf6, 0xc0, 0x7f, 0x89, + 0x5d, 0xcc, 0x73, 0x8c, 0xbd, 0xbb, 0xe9, 0x03, 0x7e, 0x67, 0xae, 0xa0, + 0x63, 0x1d, 0xe0, 0x93, 0x1f, 0xaf, 0xe3, 0xd7, 0xf5, 0x79, 0x24, 0xb4, + 0x0e, 0x8f, 0xc4, 0x84, 0xae, 0xcf, 0xcf, 0xf3, 0xf7, 0xf3, 0xf0, 0x9f, + 0x33, 0xbd, 0x59, 0x3f, 0x7f, 0x3d, 0x80, 0xf6, 0xb8, 0x66, 0xcb, 0x58, + 0x49, 0x31, 0xb6, 0x08, 0x9f, 0x83, 0xb6, 0x11, 0x45, 0x87, 0x6e, 0x1e, + 0x9f, 0x4f, 0xb4, 0xcf, 0x2c, 0x75, 0xd3, 0x99, 0x12, 0x63, 0x90, 0x92, + 0x9f, 0x6d, 0x18, 0xb4, 0x0d, 0xec, 0xd5, 0xf5, 0x5f, 0x2f, 0x72, 0xdf, + 0x73, 0x25, 0x89, 0x41, 0x72, 0x4b, 0xbd, 0x94, 0x2f, 0xf5, 0xa8, 0xf3, + 0x07, 0x44, 0x8c, 0xbb, 0xac, 0x63, 0x84, 0xef, 0xd6, 0xd2, 0x6f, 0x6f, + 0x31, 0x4f, 0x61, 0x4d, 0x95, 0x76, 0x29, 0x74, 0xcd, 0x8d, 0x96, 0xba, + 0xc4, 0xe0, 0xb9, 0x19, 0xfa, 0x2e, 0xaf, 0xb7, 0xa3, 0x57, 0xe1, 0x3f, + 0xfe, 0x2a, 0xf8, 0xa6, 0x0c, 0x1e, 0x1b, 0xbd, 0x8a, 0xba, 0x48, 0x7e, + 0x91, 0xe7, 0x94, 0x0c, 0x4f, 0x8a, 0xdc, 0x10, 0x29, 0xa3, 0x27, 0x45, + 0x2d, 0xba, 0x1f, 0x0a, 0xdd, 0x64, 0x65, 0x4d, 0x03, 0x78, 0x04, 0x3e, + 0x18, 0x19, 0x83, 0x75, 0xc2, 0xee, 0x7b, 0x6b, 0x20, 0x36, 0x41, 0xf1, + 0x41, 0xf0, 0xbd, 0x94, 0x59, 0x55, 0x5f, 0x40, 0xe8, 0xfb, 0xd0, 0x3e, + 0x9d, 0x2f, 0xa9, 0xcf, 0xf5, 0x5a, 0xa1, 0xcf, 0x7b, 0x5c, 0xdf, 0x87, + 0x5c, 0xdf, 0xd7, 0xe3, 0xe5, 0x78, 0xcd, 0xe3, 0x75, 0x9e, 0x64, 0x8d, + 0xa2, 0xcc, 0x82, 0xe4, 0xbf, 0xd0, 0xbe, 0xf1, 0xd0, 0x97, 0x15, 0x06, + 0xcf, 0x2c, 0x8f, 0x45, 0xfa, 0x8c, 0x1e, 0x7f, 0x66, 0xea, 0xef, 0x6b, + 0xf1, 0x34, 0x70, 0xd1, 0xdc, 0x4e, 0xa9, 0xe3, 0xd0, 0xaf, 0x6c, 0x14, + 0xd0, 0xed, 0xe4, 0x72, 0x0f, 0xad, 0x88, 0x9a, 0x5c, 0xc0, 0x18, 0xb8, + 0x1f, 0xcf, 0xc9, 0x86, 0x3a, 0x08, 0x35, 0xd7, 0x21, 0xe3, 0x07, 0x22, + 0xd7, 0x79, 0x3e, 0x53, 0xcb, 0xff, 0x55, 0x3b, 0x2d, 0x6a, 0xdc, 0xa0, + 0x2d, 0x63, 0x48, 0x81, 0xf9, 0x19, 0xbf, 0x34, 0xd9, 0x55, 0x33, 0xe8, + 0x67, 0x16, 0x7b, 0x2b, 0x86, 0xfd, 0x22, 0xcb, 0x98, 0xdc, 0x2b, 0x4f, + 0xb9, 0xf6, 0xca, 0x4f, 0x8a, 0xbd, 0x72, 0xec, 0x93, 0x83, 0xae, 0xa0, + 0xa5, 0x57, 0x4c, 0x0b, 0xe6, 0x31, 0xca, 0xf3, 0x68, 0xd2, 0xc5, 0x6b, + 0x42, 0xdf, 0x44, 0x93, 0x7e, 0x19, 0x5f, 0x9d, 0xa2, 0xac, 0x88, 0xbf, + 0x96, 0x9f, 0x71, 0x23, 0x61, 0x5b, 0x93, 0xab, 0x8c, 0x29, 0x2a, 0xc5, + 0x2d, 0x74, 0xb3, 0xdc, 0xc1, 0x98, 0xef, 0x6f, 0x69, 0xb5, 0x4c, 0x8c, + 0x0d, 0xb7, 0x53, 0x3e, 0xca, 0xbc, 0x36, 0x19, 0xe4, 0x79, 0x65, 0x7c, + 0x3b, 0xc9, 0xf2, 0xc7, 0x63, 0xa8, 0x94, 0x6a, 0xef, 0xe7, 0xa2, 0x71, + 0x33, 0x31, 0xdd, 0xc3, 0xf6, 0x4b, 0x88, 0xff, 0x6d, 0xfe, 0xff, 0x6c, + 0x04, 0xb4, 0x59, 0x5c, 0xc2, 0xf7, 0x8c, 0x7d, 0x0a, 0xb5, 0xf7, 0x67, + 0xb9, 0xcd, 0xec, 0x34, 0xec, 0x20, 0xd8, 0x7b, 0x36, 0xff, 0xcb, 0x36, + 0x15, 0xe6, 0xbb, 0xdc, 0xb5, 0x6c, 0xc4, 0x10, 0x3a, 0x1e, 0x75, 0x5d, + 0xc6, 0xd4, 0x67, 0xdc, 0x98, 0xe5, 0xbe, 0xdc, 0x24, 0x3c, 0xc3, 0xa4, + 0x4c, 0x74, 0x1f, 0xcb, 0xc1, 0x76, 0xfe, 0x44, 0x3e, 0xd6, 0x56, 0xca, + 0x4f, 0x8d, 0xab, 0x7c, 0xac, 0x48, 0x9b, 0x7c, 0x2c, 0xdc, 0xc7, 0x38, + 0x60, 0xbe, 0x76, 0x6f, 0x36, 0xea, 0x7c, 0x2f, 0x19, 0x99, 0xe8, 0x36, + 0x81, 0x99, 0x2a, 0x4b, 0xfb, 0xb9, 0x0f, 0x71, 0x33, 0x33, 0xcd, 0x7d, + 0x2d, 0x39, 0xfb, 0x5f, 0xbb, 0x97, 0x8c, 0xa2, 0x9d, 0xdf, 0xd5, 0x2e, + 0x4e, 0xa2, 0xed, 0x12, 0xda, 0xd7, 0xfe, 0x27, 0x11, 0xd5, 0xe3, 0x74, + 0xde, 0x8b, 0xf1, 0x40, 0xbe, 0xf8, 0xb3, 0x72, 0x9b, 0x6e, 0x16, 0x61, + 0x8f, 0x1b, 0xcc, 0xf7, 0xe8, 0x91, 0x49, 0xd9, 0x0a, 0x63, 0xc0, 0x6b, + 0x7b, 0x7d, 0xab, 0xc5, 0x37, 0x6a, 0x99, 0xa6, 0xd8, 0x96, 0x66, 0x3f, + 0xbc, 0xb4, 0xc1, 0x86, 0xc9, 0xbe, 0x82, 0x35, 0x14, 0xeb, 0x67, 0xb6, + 0xe6, 0xb7, 0x81, 0xf7, 0x60, 0x1b, 0x5d, 0x60, 0xfd, 0x25, 0xe3, 0x93, + 0x58, 0x97, 0xb2, 0x0e, 0x93, 0xf2, 0x93, 0x6a, 0xfa, 0x39, 0x04, 0xc9, + 0xc3, 0xa3, 0x8d, 0xb8, 0x48, 0xc7, 0xfe, 0x7a, 0xc0, 0xb1, 0xbf, 0x1e, + 0x72, 0xc4, 0x45, 0x86, 0x05, 0x3e, 0x6b, 0x60, 0xaa, 0xb0, 0xc2, 0x54, + 0xc0, 0x5e, 0x52, 0xb7, 0x2d, 0xd6, 0x75, 0xdb, 0x8e, 0x75, 0x74, 0x9b, + 0x97, 0xad, 0xba, 0xa2, 0xf4, 0x88, 0x15, 0xc5, 0x1a, 0x73, 0x83, 0xf5, + 0xc5, 0xeb, 0xd5, 0x69, 0xd6, 0x23, 0x51, 0xd6, 0x23, 0x53, 0xac, 0x47, + 0x26, 0x59, 0x8f, 0xd8, 0x4c, 0x03, 0x93, 0xc7, 0xfe, 0x11, 0xeb, 0x69, + 0xac, 0x1f, 0x33, 0xf4, 0x4c, 0x15, 0x3a, 0x79, 0x8a, 0x31, 0xd0, 0x47, + 0xb4, 0x3a, 0xdf, 0xcb, 0xfc, 0x2b, 0x71, 0x4f, 0xb3, 0x5d, 0x83, 0xda, + 0x2b, 0xf0, 0x17, 0xff, 0x39, 0xf4, 0xce, 0x2b, 0x59, 0x1a, 0xf1, 0xdd, + 0x2c, 0x82, 0xce, 0xab, 0xa8, 0x55, 0xf1, 0x12, 0x64, 0x1b, 0x35, 0x82, + 0x7f, 0x30, 0x31, 0xc3, 0x7d, 0x1f, 0xf1, 0xe5, 0x79, 0x5e, 0xbe, 0x1d, + 0xcd, 0x86, 0xfa, 0x59, 0x06, 0x8e, 0x2b, 0x19, 0x38, 0xde, 0x90, 0x81, + 0x6c, 0x8e, 0x47, 0xd2, 0xb7, 0xb0, 0x9d, 0xc6, 0x0f, 0x26, 0x76, 0xf5, + 0xb1, 0xfc, 0x22, 0x66, 0xa2, 0x51, 0xbf, 0xc7, 0x4f, 0xa7, 0xc3, 0x41, + 0x55, 0xf7, 0xc7, 0x14, 0x39, 0xef, 0xf9, 0xe2, 0xbb, 0x8c, 0x4b, 0x58, + 0x4e, 0x43, 0x38, 0xbf, 0x0c, 0xbf, 0x28, 0xdb, 0x0d, 0xdd, 0xc2, 0xaf, + 0xb4, 0x28, 0xda, 0xe2, 0xdc, 0x9a, 0x64, 0x1d, 0x17, 0x5d, 0x31, 0xac, + 0x99, 0xb8, 0xf1, 0x9b, 0xc3, 0xa8, 0xe1, 0xfe, 0x83, 0xea, 0xe7, 0x86, + 0xe5, 0xde, 0x5c, 0x72, 0x97, 0xd4, 0x27, 0xcc, 0xa3, 0xe1, 0xb8, 0xb0, + 0xdd, 0x3a, 0xae, 0xc8, 0xf5, 0x73, 0x91, 0xe7, 0xbb, 0x12, 0x9d, 0xe4, + 0xf9, 0xee, 0x51, 0x6b, 0x67, 0x96, 0xbf, 0x17, 0xeb, 0x32, 0xaf, 0xa1, + 0xc3, 0xa8, 0x7f, 0x1f, 0x12, 0x75, 0x22, 0x4e, 0xa2, 0x0e, 0x4f, 0x02, + 0xcf, 0x63, 0xee, 0x85, 0xfe, 0xf8, 0x07, 0x5e, 0xa3, 0xf1, 0x5e, 0xf0, + 0x23, 0x1f, 0x97, 0x67, 0xe8, 0x52, 0x41, 0xf7, 0xe1, 0x3d, 0x32, 0xbe, + 0x8b, 0x7e, 0xf8, 0x68, 0x87, 0xfd, 0x9e, 0xc8, 0x05, 0x31, 0xfe, 0xc4, + 0xdd, 0xa7, 0xa3, 0xaa, 0x4f, 0xa8, 0x75, 0xd9, 0x85, 0xda, 0x3e, 0x84, + 0x9a, 0x48, 0x8b, 0xa2, 0x16, 0x65, 0xa7, 0xb0, 0x59, 0x17, 0x85, 0xed, + 0xb1, 0x7f, 0x57, 0xa3, 0x3e, 0xe6, 0x7e, 0xd7, 0xb5, 0x3b, 0xbc, 0x6e, + 0x1d, 0x12, 0x18, 0x6d, 0x14, 0xf5, 0xda, 0x45, 0x5e, 0xea, 0x8c, 0xf8, + 0xce, 0x58, 0xc0, 0x77, 0x0f, 0xa9, 0xef, 0x3e, 0x2f, 0xb0, 0xb1, 0x11, + 0xeb, 0x66, 0xbd, 0x28, 0xf8, 0x9d, 0xe7, 0xd9, 0x9e, 0x64, 0x7e, 0x8f, + 0x54, 0xf8, 0xb9, 0xa7, 0x05, 0x3d, 0x35, 0x3d, 0x40, 0x0b, 0xc8, 0x40, + 0x8f, 0xe2, 0x7f, 0xcb, 0x4c, 0xf9, 0xf5, 0xb8, 0xdb, 0xd1, 0x99, 0xb1, + 0x4e, 0x01, 0x63, 0xc5, 0x98, 0x4c, 0x5f, 0xbc, 0x1c, 0xf1, 0xe5, 0xe6, + 0x61, 0xeb, 0x20, 0xdf, 0x65, 0x0f, 0xe2, 0xa9, 0xb8, 0x0f, 0x3b, 0x29, + 0x9e, 0x46, 0xbf, 0xd0, 0x4e, 0xd3, 0xc0, 0x76, 0xd1, 0xc2, 0x79, 0xdf, + 0x76, 0x75, 0x5f, 0xb7, 0x98, 0x0b, 0x32, 0xf0, 0x1e, 0xfd, 0x6e, 0xbc, + 0x17, 0xef, 0xc7, 0x7d, 0x78, 0x9e, 0x7c, 0xee, 0x00, 0xeb, 0xed, 0xc4, + 0xb4, 0x7c, 0x96, 0x71, 0x5d, 0x7e, 0x37, 0x60, 0x7b, 0xf7, 0x57, 0xce, + 0x9f, 0x4f, 0xd5, 0xf1, 0xc1, 0xfc, 0x6d, 0xa7, 0xb2, 0xf0, 0x7d, 0xe2, + 0xbb, 0x11, 0x9f, 0xb0, 0x6b, 0x6d, 0xfe, 0xe4, 0x79, 0x9d, 0xe3, 0xf3, + 0x33, 0xc5, 0xdb, 0xc2, 0x66, 0xcf, 0xa5, 0x47, 0x7c, 0xe5, 0x32, 0xc6, + 0x3b, 0xe2, 0x4b, 0xb1, 0x0c, 0x24, 0x8b, 0x89, 0x5a, 0x5e, 0xe2, 0x02, + 0x3a, 0xdd, 0x6f, 0x85, 0x4e, 0x1b, 0xef, 0x0f, 0xcb, 0x9a, 0xb7, 0x38, + 0x66, 0x39, 0x2c, 0xb0, 0x1c, 0x16, 0x58, 0x0e, 0x0b, 0x2c, 0x87, 0x6c, + 0xab, 0xbe, 0x56, 0x60, 0x39, 0xe4, 0xb5, 0xe4, 0x55, 0x5e, 0x4b, 0xa4, + 0xec, 0xc6, 0x95, 0x7f, 0x53, 0xcb, 0xae, 0x3b, 0x6f, 0x53, 0xcb, 0x2a, + 0xd6, 0x6f, 0xf2, 0x1d, 0x99, 0x68, 0x96, 0xd9, 0x5b, 0x2c, 0xb3, 0x1d, + 0xb1, 0x41, 0xba, 0x5b, 0xc2, 0x9c, 0x59, 0xe6, 0x1c, 0xeb, 0xea, 0x94, + 0x1f, 0x58, 0x2b, 0xc0, 0xf2, 0x04, 0xac, 0x69, 0x31, 0xdd, 0x07, 0xe9, + 0x1e, 0xeb, 0xeb, 0xbb, 0x25, 0xc8, 0xf0, 0x1e, 0x75, 0x6e, 0xb1, 0x0c, + 0x63, 0xfd, 0xb3, 0x7d, 0xb7, 0x8a, 0x06, 0x63, 0xb2, 0x40, 0x28, 0x43, + 0xd0, 0xa7, 0x02, 0xa7, 0xf1, 0xbc, 0xaf, 0xb0, 0xde, 0x87, 0x0f, 0x0f, + 0xeb, 0xc5, 0x19, 0x1f, 0xaf, 0x17, 0x91, 0x9b, 0xac, 0x4f, 0xcf, 0x97, + 0x6c, 0x96, 0xfb, 0x7e, 0xfa, 0x56, 0x09, 0xeb, 0x34, 0x68, 0xc4, 0xe7, + 0x65, 0x12, 0xbe, 0x31, 0x23, 0x86, 0xb1, 0x8f, 0x67, 0x0d, 0xc1, 0x27, + 0x7f, 0x0a, 0x3a, 0x30, 0xed, 0x5f, 0xdc, 0x85, 0xda, 0xf3, 0x71, 0xa3, + 0x53, 0xf9, 0x1a, 0x71, 0x8c, 0xf6, 0x68, 0x0b, 0xba, 0xe1, 0xbc, 0xdd, + 0xbe, 0x24, 0x7e, 0xb3, 0x21, 0x0a, 0xff, 0x9b, 0x4b, 0x7f, 0x5d, 0xe2, + 0xfb, 0x05, 0xbd, 0x66, 0x12, 0x7e, 0xe4, 0x90, 0xd3, 0xd3, 0xfe, 0xd8, + 0x0c, 0x3d, 0x5b, 0x45, 0xbf, 0xaf, 0x52, 0x3e, 0x0c, 0x7d, 0x64, 0x45, + 0xef, 0x90, 0xa4, 0x5d, 0x37, 0xe3, 0xce, 0x27, 0xbc, 0x75, 0x9c, 0x99, + 0x10, 0x38, 0xb9, 0x8b, 0xf5, 0x0b, 0x68, 0xf3, 0x13, 0xe6, 0x35, 0x7e, + 0x5f, 0x41, 0xeb, 0xb7, 0x1f, 0xb3, 0xce, 0xc1, 0x9c, 0xe1, 0x7c, 0x6d, + 0x9d, 0xb6, 0xaa, 0x74, 0x9a, 0xed, 0xd0, 0x69, 0xb9, 0xba, 0x4e, 0x63, + 0xde, 0x10, 0xba, 0x0c, 0xba, 0xea, 0x51, 0xc6, 0x91, 0xf2, 0x18, 0xf8, + 0x70, 0x87, 0xd0, 0x5d, 0xac, 0xfb, 0xd9, 0xae, 0x58, 0xac, 0x66, 0x7d, + 0x87, 0x85, 0x0e, 0xd1, 0xfc, 0xbd, 0x7f, 0xb7, 0x94, 0x8b, 0x6e, 0xa1, + 0x0f, 0x72, 0x27, 0xa1, 0xb7, 0xbc, 0xda, 0x8f, 0x73, 0x3b, 0xb4, 0xb7, + 0x23, 0x2f, 0xb1, 0x3e, 0x5b, 0x8c, 0xc2, 0xa6, 0xed, 0x51, 0xb6, 0x0f, + 0xea, 0x72, 0x61, 0xaf, 0x0b, 0x63, 0xd5, 0xfa, 0x6c, 0x40, 0xf9, 0x35, + 0xe0, 0x87, 0xc4, 0x9c, 0xb7, 0xc5, 0x08, 0x26, 0x30, 0x02, 0xdf, 0x13, + 0x60, 0x7a, 0x89, 0x1a, 0xe2, 0x44, 0xef, 0xd2, 0xaa, 0x90, 0x8d, 0x77, + 0x05, 0x76, 0xc9, 0xf3, 0x77, 0xb3, 0xd3, 0x07, 0x45, 0x3f, 0xf3, 0x4b, + 0x0d, 0xfd, 0x38, 0x57, 0x78, 0x0f, 0xeb, 0x86, 0xe8, 0x6b, 0x65, 0x42, + 0xea, 0xc0, 0xc5, 0x32, 0x6a, 0x80, 0x89, 0x3e, 0x73, 0x5f, 0xf5, 0x38, + 0xd1, 0x0f, 0xad, 0x0f, 0x36, 0x22, 0x7b, 0x8c, 0x6b, 0xfb, 0x31, 0x47, + 0x59, 0x07, 0x0f, 0x3d, 0xcb, 0xef, 0xc7, 0xb5, 0xf5, 0xc7, 0x73, 0xaf, + 0x3e, 0x1e, 0xf8, 0xf6, 0x70, 0xcf, 0xbb, 0x74, 0x57, 0x8d, 0xe7, 0x6e, + 0x7d, 0x3c, 0xcf, 0xa8, 0xf1, 0x50, 0xce, 0x88, 0x0d, 0x28, 0xdc, 0xbf, + 0xe1, 0x67, 0x77, 0x27, 0x18, 0xc7, 0xe4, 0x96, 0x40, 0xe7, 0xfd, 0x8a, + 0x9f, 0x9c, 0x7e, 0x54, 0x67, 0x5f, 0xad, 0xc9, 0x3b, 0xac, 0x7f, 0xef, + 0x09, 0x1c, 0x33, 0xc2, 0x38, 0x06, 0xd7, 0x29, 0x0f, 0x3d, 0x9d, 0x0b, + 0xa3, 0x4e, 0xed, 0x0c, 0x8f, 0x9b, 0xed, 0xb1, 0x69, 0xfe, 0x14, 0xfe, + 0x35, 0x3c, 0x47, 0xdf, 0xff, 0x3c, 0xdd, 0x9b, 0x87, 0x2e, 0x07, 0x8e, + 0x95, 0xb5, 0x6c, 0xef, 0x2d, 0x4b, 0xff, 0x6e, 0xca, 0xd3, 0xbf, 0x0b, + 0xdf, 0xee, 0x34, 0x70, 0x7e, 0x08, 0x7e, 0xe0, 0xa4, 0xfa, 0xad, 0x8f, + 0x5c, 0x15, 0xcf, 0xf2, 0xd2, 0x4b, 0x33, 0x8e, 0xd8, 0x38, 0xc4, 0xaa, + 0x64, 0x59, 0xcf, 0xd8, 0xa1, 0x0e, 0x43, 0xe6, 0xdc, 0xdc, 0xa8, 0x6a, + 0xec, 0x74, 0x94, 0xe7, 0xcc, 0x8e, 0x1a, 0x46, 0x4a, 0xf8, 0x1a, 0xba, + 0xed, 0x1e, 0xea, 0xe2, 0x75, 0xf4, 0x2c, 0xa1, 0x96, 0x9a, 0x65, 0x62, + 0x0f, 0xe0, 0x12, 0xf3, 0x64, 0x3e, 0x6a, 0x45, 0x1e, 0x17, 0x76, 0x29, + 0xd6, 0x17, 0x03, 0x74, 0x62, 0x5a, 0xa3, 0x0f, 0x7c, 0xbc, 0x84, 0x3a, + 0x9a, 0x51, 0x1e, 0x3f, 0xfc, 0xc7, 0x63, 0xe6, 0x9b, 0xbc, 0x2e, 0x5d, + 0x12, 0x7e, 0x99, 0x0b, 0x94, 0x63, 0x39, 0x3d, 0x22, 0xe4, 0xd4, 0x18, + 0x61, 0x29, 0x62, 0xb9, 0x42, 0x6c, 0xc2, 0xb8, 0xa8, 0xdb, 0x23, 0x6d, + 0x1d, 0x1e, 0xe5, 0xb2, 0xaa, 0x87, 0x90, 0x86, 0xee, 0xd8, 0xb8, 0x4f, + 0x22, 0xfd, 0x89, 0x7d, 0x31, 0x4e, 0x4c, 0xe6, 0xf6, 0x7d, 0xc3, 0xae, + 0x33, 0x45, 0xbd, 0x48, 0xd0, 0x4e, 0xf8, 0x13, 0x8d, 0x29, 0xa6, 0x9b, + 0xfe, 0xdd, 0x19, 0xa7, 0xdf, 0xe0, 0x9c, 0xc8, 0xeb, 0x7f, 0xa5, 0x2a, + 0xd7, 0xe0, 0x1c, 0xdb, 0xf4, 0xf9, 0x83, 0x4e, 0x4c, 0x62, 0x15, 0x93, + 0xc2, 0x97, 0xb3, 0x9b, 0x12, 0x0b, 0x53, 0xf4, 0x68, 0x01, 0x3a, 0x8c, + 0xee, 0x24, 0x6c, 0xfc, 0xa2, 0x0c, 0x64, 0x7c, 0x8a, 0x52, 0x55, 0xd0, + 0xc8, 0xc7, 0x58, 0x89, 0x79, 0xaf, 0x88, 0x3d, 0x7f, 0x3e, 0x2e, 0xe3, + 0x77, 0x54, 0x7e, 0x5d, 0xf9, 0xcb, 0x87, 0x29, 0xb9, 0x40, 0xd9, 0x4c, + 0xf4, 0x4b, 0xa2, 0xd6, 0x75, 0x26, 0x3a, 0xa1, 0x7c, 0x3b, 0x11, 0xbe, + 0x0e, 0x7f, 0x99, 0x49, 0x5f, 0x2e, 0x58, 0xd9, 0x0c, 0x49, 0x9f, 0x05, + 0x71, 0x1f, 0x0c, 0x5e, 0x7b, 0x77, 0xb0, 0x0e, 0x39, 0x21, 0xfc, 0x16, + 0x8c, 0x54, 0xe6, 0xd1, 0x1e, 0x3e, 0x87, 0x7e, 0x82, 0x9d, 0x96, 0x29, + 0x3e, 0xa5, 0xda, 0xd6, 0x28, 0xc4, 0xbc, 0x10, 0xfa, 0x55, 0x3b, 0x1b, + 0x35, 0x1a, 0xf7, 0xc3, 0xe7, 0x71, 0x42, 0xe0, 0xc8, 0x11, 0xb6, 0x79, + 0x44, 0xbb, 0xda, 0xac, 0xf0, 0x5f, 0xf0, 0x79, 0xf9, 0x81, 0x21, 0xfd, + 0x9b, 0x08, 0xb8, 0x2e, 0xfd, 0x1a, 0xfc, 0xcc, 0x32, 0xf7, 0xa3, 0x29, + 0x9e, 0x7e, 0x98, 0xe2, 0x9b, 0xf0, 0x33, 0x9d, 0xbc, 0xaf, 0x7e, 0x26, + 0xa6, 0x35, 0xaf, 0x3d, 0x37, 0x58, 0x36, 0x5e, 0x5f, 0xd7, 0xfe, 0xfb, + 0x50, 0xaf, 0xe1, 0x4c, 0xab, 0x90, 0xf8, 0xdd, 0x0c, 0x60, 0xf0, 0x7c, + 0xf5, 0x71, 0xfc, 0x5e, 0x8c, 0x2f, 0x2d, 0xb0, 0x71, 0x84, 0xb1, 0x0d, + 0x30, 0xce, 0x98, 0xd8, 0x17, 0x8b, 0x3f, 0x16, 0xf1, 0xe5, 0x97, 0x07, + 0xc9, 0x0f, 0x7f, 0x9c, 0xad, 0x63, 0x29, 0xba, 0x45, 0xdc, 0xbb, 0xdc, + 0x8f, 0xc4, 0xfa, 0x0c, 0x9d, 0x78, 0x87, 0xed, 0x86, 0x09, 0x15, 0x87, + 0xd3, 0x21, 0x6a, 0x53, 0xc9, 0xbd, 0x54, 0xad, 0x53, 0x34, 0xef, 0xe9, + 0xbd, 0x0e, 0xe7, 0x6f, 0x73, 0x41, 0x76, 0x9d, 0x98, 0x02, 0xfe, 0x29, + 0x31, 0x47, 0x97, 0x88, 0xe4, 0x1c, 0x37, 0xf6, 0x31, 0xba, 0x78, 0x9e, + 0x60, 0x0f, 0xc2, 0xef, 0xf7, 0x35, 0xfe, 0xc4, 0x7e, 0xc4, 0xd5, 0x21, + 0xe0, 0xa8, 0x3e, 0x9b, 0x79, 0x66, 0x1a, 0xe7, 0x83, 0x6c, 0x9f, 0x69, + 0xdc, 0x2b, 0x7d, 0x51, 0x6c, 0xb3, 0xa9, 0xf9, 0x82, 0x1f, 0x6a, 0x54, + 0xd5, 0x29, 0xb0, 0xc8, 0xec, 0x07, 0x9d, 0x3e, 0x2d, 0x79, 0x5c, 0x6f, + 0xef, 0x62, 0x23, 0xb1, 0x4e, 0xf8, 0xdd, 0x30, 0xd4, 0xeb, 0xdc, 0x0b, + 0xda, 0xf3, 0x1c, 0x39, 0xf7, 0x36, 0x1e, 0xdf, 0xa5, 0x7f, 0xb3, 0xe8, + 0xfe, 0xcc, 0xdb, 0x16, 0x8f, 0x79, 0xfb, 0xf9, 0x90, 0xdc, 0x3b, 0x7b, + 0x58, 0xb5, 0xf1, 0x8a, 0x6f, 0x5d, 0xfe, 0x0e, 0xfc, 0x50, 0x8d, 0xfc, + 0x8b, 0x77, 0x84, 0x5e, 0x69, 0xf5, 0x85, 0x47, 0x58, 0x9f, 0x4a, 0x39, + 0x3e, 0xe1, 0x21, 0xc7, 0xfd, 0x31, 0xe0, 0x96, 0x8f, 0x2f, 0xc7, 0xc7, + 0xdb, 0xca, 0xf1, 0x9e, 0x61, 0xe9, 0x8b, 0x6d, 0x95, 0x63, 0xe4, 0x00, + 0x9d, 0xa8, 0xb6, 0xf3, 0x7b, 0x61, 0x1e, 0x90, 0xcb, 0xee, 0xf4, 0x95, + 0x80, 0x66, 0xda, 0x5f, 0x82, 0x7d, 0x43, 0xf0, 0x25, 0xf6, 0x5e, 0x4e, + 0x1a, 0xa9, 0x79, 0xf7, 0x5e, 0xea, 0x46, 0xee, 0xbd, 0xed, 0x71, 0x2f, + 0xb0, 0x3b, 0x64, 0xc3, 0x8a, 0x48, 0x5f, 0x80, 0xa6, 0xdf, 0xb0, 0xef, + 0x70, 0xc9, 0xca, 0x96, 0x09, 0xbe, 0xee, 0x30, 0x9d, 0xc3, 0xfe, 0xb4, + 0xf2, 0x25, 0x1f, 0x2b, 0x48, 0x3a, 0x84, 0x0e, 0x0a, 0xfe, 0x00, 0xbe, + 0x8d, 0xa4, 0xfd, 0x69, 0x9e, 0x63, 0xe9, 0x47, 0xce, 0x2c, 0x45, 0xd4, + 0xbc, 0x71, 0x5b, 0x3c, 0xcf, 0x33, 0x5f, 0x10, 0xf3, 0x65, 0x3d, 0xbf, + 0x52, 0x8f, 0x4f, 0xc6, 0xda, 0x50, 0xa3, 0xff, 0xe0, 0x75, 0xcf, 0x7f, + 0x30, 0x24, 0x6a, 0x37, 0xdc, 0xa8, 0x1e, 0x64, 0xbc, 0x89, 0x39, 0x85, + 0x0f, 0x52, 0xfb, 0x88, 0x1f, 0xda, 0x4b, 0xbd, 0x07, 0x18, 0x05, 0x18, + 0x64, 0x33, 0xbe, 0x34, 0x0e, 0x22, 0xce, 0xdc, 0xe4, 0x7b, 0x50, 0x73, + 0x6a, 0xdc, 0x4c, 0x51, 0x0f, 0xfc, 0x10, 0xa8, 0x25, 0x6d, 0xe6, 0x9a, + 0x64, 0xec, 0x94, 0x90, 0xb1, 0xd4, 0xf2, 0x29, 0x25, 0x63, 0xa7, 0x94, + 0x1f, 0xfe, 0x94, 0x92, 0xb1, 0x53, 0x4a, 0xc6, 0x4e, 0x29, 0x19, 0x3b, + 0xc5, 0x7c, 0x3e, 0xc6, 0xf8, 0x16, 0x58, 0x44, 0xfb, 0x41, 0x7b, 0x29, + 0x53, 0xc2, 0x75, 0xac, 0xcf, 0x6e, 0x39, 0x7b, 0x69, 0x44, 0xca, 0x19, + 0x63, 0x13, 0x19, 0xaf, 0xc7, 0xef, 0xc2, 0x1c, 0xfc, 0x1e, 0xd3, 0xef, + 0x23, 0x3a, 0x33, 0x8f, 0xbe, 0xfa, 0x28, 0x29, 0x6a, 0xc9, 0x76, 0x50, + 0xc2, 0x89, 0x85, 0x43, 0xc8, 0x0f, 0x93, 0xb6, 0x5f, 0xb6, 0x6d, 0xae, + 0x98, 0xe6, 0x93, 0x98, 0x9a, 0x2f, 0xb7, 0x5d, 0xd4, 0x45, 0xe9, 0x22, + 0xe8, 0x8a, 0x98, 0x4a, 0x93, 0xe7, 0x46, 0xd0, 0x49, 0x86, 0x44, 0xb9, + 0x68, 0x70, 0x4c, 0xd1, 0xe0, 0xdb, 0x62, 0x8c, 0x88, 0x49, 0x84, 0x2f, + 0xb3, 0x3d, 0x1d, 0x72, 0x85, 0x31, 0x7e, 0x0e, 0xcb, 0xc2, 0xc1, 0x08, + 0xeb, 0xa4, 0x8d, 0xd3, 0xa1, 0x31, 0xf6, 0x76, 0xba, 0x67, 0xa3, 0x79, + 0x39, 0x77, 0x1c, 0x6b, 0x49, 0x44, 0xad, 0x23, 0x12, 0x17, 0x6f, 0xb1, + 0x6b, 0x74, 0x34, 0xba, 0x97, 0x8f, 0xad, 0x74, 0x96, 0x0e, 0x90, 0xd1, + 0x57, 0xa3, 0xbf, 0x60, 0x39, 0xe8, 0x66, 0x39, 0x38, 0xaa, 0xec, 0x92, + 0xa3, 0x75, 0xbb, 0x64, 0xcf, 0x1e, 0xc4, 0x65, 0x64, 0xc4, 0xbe, 0xd7, + 0x56, 0x55, 0x43, 0x00, 0xbe, 0x6f, 0x9c, 0x77, 0x51, 0x7c, 0x18, 0xe7, + 0xf8, 0x2d, 0x22, 0x6b, 0x32, 0xee, 0x1b, 0xdf, 0x23, 0xb0, 0xbb, 0xcf, + 0xc2, 0x3d, 0x47, 0xa5, 0xde, 0xf3, 0x91, 0x7f, 0xfc, 0x36, 0xe3, 0x89, + 0x1a, 0x3d, 0xc1, 0xef, 0xcc, 0x17, 0xf7, 0xf1, 0xb3, 0x75, 0x4d, 0x09, + 0x3b, 0x6e, 0xf8, 0xb6, 0x92, 0xbf, 0xaf, 0xdd, 0xbb, 0x2d, 0xc1, 0x8f, + 0x8c, 0xa7, 0x8d, 0xd9, 0xe8, 0x7b, 0xb5, 0xd3, 0x27, 0xe1, 0x63, 0x87, + 0x9c, 0x58, 0x21, 0xd3, 0xe7, 0x25, 0x1f, 0x12, 0x2b, 0x35, 0xe2, 0x63, + 0x21, 0x2f, 0x35, 0xfa, 0x77, 0x1e, 0x5b, 0x88, 0xb0, 0x77, 0x22, 0x9f, + 0x9f, 0xa6, 0x19, 0x91, 0x83, 0x8d, 0x38, 0xe9, 0x33, 0xf3, 0xfa, 0x5d, + 0xb6, 0xe2, 0x8d, 0xcf, 0x20, 0xce, 0xad, 0xb8, 0x48, 0x6b, 0xaf, 0x39, + 0xf0, 0xd7, 0x8d, 0x2d, 0xac, 0xf6, 0x85, 0x45, 0x4e, 0xf8, 0x76, 0xc6, + 0x48, 0x3a, 0x1e, 0x7a, 0x9c, 0x9f, 0x0f, 0x3f, 0x5e, 0x80, 0x92, 0x57, + 0xd0, 0xae, 0x93, 0x46, 0x17, 0x6a, 0x5f, 0xe0, 0xef, 0xc5, 0xfe, 0x65, + 0x86, 0xba, 0xd5, 0xde, 0x44, 0x8f, 0xda, 0xcf, 0x8a, 0xb0, 0xec, 0x35, + 0x72, 0x9d, 0x47, 0xeb, 0x3e, 0x3d, 0xc8, 0x84, 0xdb, 0xa7, 0xf7, 0xf4, + 0x3a, 0xeb, 0xd5, 0x7a, 0x72, 0x80, 0x58, 0xd6, 0x2e, 0x52, 0xbe, 0x4a, + 0x33, 0x4f, 0x1b, 0xcd, 0xe9, 0xdb, 0xf4, 0x3d, 0xdd, 0x9d, 0x31, 0xf3, + 0xc2, 0x9b, 0x76, 0x50, 0xf1, 0x5f, 0x27, 0x9d, 0x29, 0x05, 0x79, 0xcd, + 0x87, 0x6e, 0x05, 0xbd, 0xfc, 0xc3, 0xc8, 0x73, 0xf9, 0x7a, 0xa0, 0x93, + 0x96, 0x96, 0x10, 0x6b, 0xf1, 0x47, 0x7b, 0x64, 0x7c, 0x71, 0x9a, 0xe9, + 0x72, 0x80, 0xd7, 0x47, 0x43, 0xed, 0x1d, 0xe1, 0x1a, 0x74, 0x89, 0xa8, + 0x37, 0x1a, 0xf8, 0xd2, 0x44, 0x90, 0xed, 0x02, 0xb9, 0xf7, 0x70, 0x88, + 0x9f, 0xfd, 0xfd, 0x52, 0x1a, 0xfe, 0xb2, 0xd0, 0x11, 0x7e, 0x7e, 0x92, + 0xf1, 0x44, 0x9c, 0x3a, 0xa9, 0xb2, 0xd4, 0xc9, 0x76, 0x41, 0x27, 0xe3, + 0x89, 0xb1, 0xd0, 0xa8, 0x4f, 0xbc, 0x4b, 0xe4, 0xd4, 0x3c, 0x1c, 0x38, + 0xc0, 0x7c, 0x85, 0x77, 0xbd, 0xae, 0xde, 0xe5, 0x7e, 0xc7, 0x2f, 0x6a, + 0x38, 0x3f, 0xe2, 0x37, 0x2f, 0xdc, 0xc2, 0xef, 0x51, 0xcd, 0xcf, 0x30, + 0x76, 0x0e, 0x53, 0x7e, 0xbe, 0x83, 0xc7, 0x10, 0x63, 0x3b, 0x22, 0xca, + 0xe7, 0x8f, 0x50, 0xb6, 0x7a, 0x92, 0x7e, 0xbf, 0xea, 0xf4, 0x09, 0x3f, + 0xc2, 0x7d, 0x96, 0x39, 0xfd, 0x5d, 0xdc, 0xaf, 0x0f, 0x6d, 0xb7, 0x8e, + 0x09, 0x92, 0xff, 0x7b, 0x61, 0xea, 0x7c, 0x0e, 0xbe, 0x97, 0x1a, 0x15, + 0xa3, 0xd6, 0xa5, 0x3b, 0x24, 0xfd, 0xcf, 0x2f, 0x88, 0xb8, 0x5a, 0xbe, + 0x9f, 0x9f, 0x39, 0x87, 0x76, 0x2f, 0x98, 0x74, 0xd3, 0x96, 0xf4, 0x7e, + 0x23, 0x10, 0x26, 0xff, 0xcb, 0x88, 0x7d, 0x02, 0x56, 0x33, 0x2f, 0xd8, + 0xfb, 0x58, 0xbf, 0x3f, 0x87, 0xfb, 0xf8, 0xf3, 0x65, 0x9c, 0x07, 0x79, + 0x9c, 0x58, 0xaf, 0x11, 0xef, 0x02, 0xbd, 0x78, 0x20, 0x12, 0x12, 0xfc, + 0xf7, 0x08, 0xf3, 0x54, 0x87, 0xf0, 0x35, 0xf6, 0xa3, 0xad, 0x3d, 0xc4, + 0xd8, 0xc2, 0xbc, 0x30, 0xb1, 0x0f, 0xe7, 0xf1, 0x3e, 0x3f, 0xd3, 0x48, + 0xf2, 0x10, 0xc6, 0xd3, 0xc4, 0xdc, 0x81, 0x43, 0x13, 0xc4, 0xf3, 0x09, + 0xfc, 0xc1, 0xf3, 0x19, 0x42, 0x7d, 0xa7, 0x20, 0xa5, 0xf8, 0x1d, 0xc9, + 0x92, 0x1c, 0xf7, 0x5c, 0xd5, 0x4f, 0xd2, 0x4f, 0x75, 0x74, 0x44, 0xff, + 0x9e, 0x21, 0x0d, 0xe2, 0xd9, 0x5a, 0x56, 0x70, 0xdc, 0x4b, 0x77, 0x4b, + 0x3d, 0x74, 0x4f, 0xed, 0x69, 0xdd, 0x15, 0x76, 0x19, 0xeb, 0xf0, 0x74, + 0x2f, 0xdd, 0x59, 0xea, 0x20, 0xea, 0x0f, 0x8a, 0x3d, 0xe7, 0xbb, 0xa5, + 0x32, 0xbf, 0x3f, 0x31, 0x22, 0xfd, 0x3a, 0x0d, 0x1e, 0xb9, 0xeb, 0xc1, + 0x23, 0x1f, 0x08, 0x1e, 0xd9, 0x37, 0xb2, 0x36, 0x8f, 0xec, 0x52, 0xb6, + 0x48, 0x90, 0x3a, 0x15, 0x7f, 0xbc, 0xc4, 0xfc, 0xf1, 0x2c, 0xf3, 0xc7, + 0xe1, 0x36, 0xfc, 0x61, 0xb8, 0xf8, 0xe3, 0x88, 0xe0, 0x8f, 0x87, 0x46, + 0xd6, 0xe2, 0x8f, 0xc3, 0xfe, 0xb5, 0x7c, 0x4d, 0xe2, 0xb7, 0x3c, 0x2f, + 0xcc, 0xd9, 0xbb, 0x99, 0xd7, 0x6d, 0xaa, 0xcc, 0x23, 0x67, 0x61, 0x25, + 0x6a, 0xd0, 0xbf, 0x08, 0x9b, 0x6c, 0x55, 0xd8, 0xfc, 0x31, 0x11, 0xc3, + 0xba, 0x28, 0xf8, 0x8b, 0xd7, 0xff, 0x18, 0x72, 0xaa, 0xdc, 0x73, 0xd1, + 0x4d, 0x37, 0xa3, 0x98, 0x0b, 0x53, 0xcd, 0x05, 0xae, 0x75, 0xe9, 0xfa, + 0x90, 0x01, 0xbe, 0x7e, 0xe1, 0x03, 0xf0, 0xe8, 0x72, 0x4f, 0x20, 0x59, + 0xf8, 0xe6, 0x08, 0xf0, 0x5f, 0x7e, 0x99, 0x1c, 0xd7, 0x03, 0x7c, 0x3d, + 0x2c, 0x7e, 0xfb, 0x09, 0xb2, 0xf2, 0x8f, 0x88, 0x71, 0x64, 0x9e, 0xbc, + 0x59, 0x1a, 0xa6, 0x5b, 0xa5, 0xdd, 0xb4, 0x5a, 0x1a, 0xa1, 0x37, 0x45, + 0x2d, 0x0d, 0x99, 0x1b, 0xb9, 0x2a, 0xe6, 0xc8, 0xa0, 0x43, 0x61, 0x6e, + 0xb3, 0xb4, 0x9b, 0x56, 0x96, 0x34, 0x7f, 0x83, 0xb7, 0xc1, 0x2f, 0xf1, + 0x3e, 0x99, 0x2f, 0xd7, 0xca, 0x33, 0xc9, 0x26, 0x9e, 0x91, 0xf7, 0x80, + 0x57, 0xf2, 0xad, 0xb9, 0xbe, 0xdd, 0xa1, 0x18, 0x62, 0xf5, 0x82, 0xd4, + 0x81, 0xb8, 0x45, 0xc3, 0x9a, 0x3c, 0xe4, 0x07, 0x86, 0xfe, 0x2a, 0xaf, + 0xb9, 0x3c, 0x67, 0x36, 0xe2, 0x9c, 0x46, 0x18, 0x0f, 0x6f, 0x17, 0xf8, + 0x37, 0x61, 0x07, 0x22, 0x49, 0xaa, 0x5d, 0x30, 0x6c, 0xd4, 0x73, 0x4c, + 0xf3, 0xf3, 0x0c, 0xe5, 0x6f, 0xda, 0xe6, 0xe0, 0x3f, 0x37, 0xd6, 0xc5, + 0x5e, 0xf2, 0x63, 0xdc, 0x67, 0xac, 0xc3, 0x8d, 0xfd, 0x1a, 0xaa, 0xef, + 0xd7, 0x74, 0xf3, 0xb8, 0xa5, 0xec, 0xcd, 0xda, 0xdc, 0xae, 0xca, 0xed, + 0xaa, 0xd8, 0xfb, 0xe3, 0xeb, 0x4b, 0xd8, 0x77, 0x1e, 0xa6, 0xd5, 0x79, + 0xc8, 0x28, 0xfc, 0x21, 0x8d, 0xbd, 0xde, 0xd5, 0x65, 0x5c, 0x87, 0x4f, + 0xa4, 0xb1, 0xd7, 0xbb, 0xaa, 0xf6, 0x7a, 0x57, 0x97, 0x63, 0x42, 0x6f, + 0xe7, 0x4b, 0x4c, 0xf7, 0x92, 0x5f, 0xc5, 0x39, 0xee, 0x53, 0xbf, 0x2d, + 0xf4, 0x98, 0xf0, 0x69, 0xf7, 0xd9, 0x6b, 0xd3, 0xf0, 0x50, 0x0b, 0x0d, + 0x63, 0x02, 0x67, 0xa5, 0xf8, 0x99, 0xc9, 0xd2, 0x63, 0xff, 0x3b, 0x60, + 0x78, 0x46, 0x00, 0xf3, 0x9e, 0x30, 0x34, 0xef, 0xc1, 0xe6, 0x8e, 0xf9, + 0x19, 0x20, 0xf7, 0x14, 0xd9, 0x80, 0xfb, 0x16, 0x90, 0xf2, 0x4a, 0x06, + 0xad, 0xbc, 0x02, 0xa6, 0x09, 0x75, 0x88, 0xfe, 0xa6, 0xf5, 0x9f, 0xe5, + 0x60, 0xe3, 0x80, 0x4d, 0x40, 0x73, 0x9b, 0xa7, 0x90, 0x32, 0xf7, 0x0c, + 0xac, 0x6f, 0xb1, 0xae, 0x6d, 0xb4, 0x01, 0xef, 0xb1, 0x5e, 0x34, 0x85, + 0x85, 0x61, 0x49, 0x0f, 0x03, 0xb0, 0x7e, 0x00, 0xa5, 0x75, 0x50, 0x1d, + 0x01, 0x4f, 0xef, 0x02, 0x4d, 0x40, 0xf7, 0x39, 0x01, 0xdb, 0xa2, 0xce, + 0xfd, 0xca, 0xe0, 0xb5, 0xb2, 0x0d, 0xd0, 0x73, 0xab, 0x16, 0xf5, 0x88, + 0xc9, 0x83, 0xf2, 0x99, 0x93, 0x0a, 0x03, 0x19, 0x79, 0x81, 0x0d, 0x9a, + 0x17, 0xc0, 0xe1, 0x04, 0x4c, 0xeb, 0xc0, 0x32, 0x6a, 0x8d, 0x2e, 0xd0, + 0x3c, 0x1e, 0x16, 0x97, 0x7e, 0x90, 0x18, 0x03, 0x54, 0x8c, 0x05, 0xc8, + 0x97, 0x01, 0xb6, 0x29, 0x41, 0x7e, 0x05, 0xe5, 0x05, 0x90, 0xd9, 0x20, + 0xbf, 0x83, 0xca, 0x4e, 0x50, 0x5e, 0x04, 0xb2, 0x97, 0x08, 0x41, 0xfd, + 0x0c, 0xa4, 0x81, 0xec, 0xe6, 0x29, 0x22, 0x60, 0x7e, 0x52, 0x80, 0x10, + 0x43, 0x03, 0x3c, 0x1f, 0x10, 0x1b, 0xc6, 0x30, 0xf5, 0x31, 0x64, 0xe4, + 0x1b, 0x88, 0x19, 0x88, 0x7c, 0xc3, 0xce, 0x70, 0x40, 0x00, 0x16, 0x56, + 0xff, 0xff, 0x1f, 0x53, 0x61, 0x01, 0xa6, 0x53, 0xd0, 0x3a, 0xd6, 0xdf, + 0xff, 0x0f, 0x88, 0xb0, 0x30, 0xb4, 0xc0, 0xd7, 0x23, 0xe6, 0xc8, 0x83, + 0xca, 0xd0, 0x05, 0x40, 0x56, 0x1b, 0xbc, 0x4d, 0xc0, 0x02, 0xbe, 0xef, + 0x79, 0x01, 0xc3, 0x2f, 0x60, 0x99, 0xf5, 0xff, 0xff, 0x52, 0xb8, 0x5a, + 0x10, 0x00, 0x00, 0x19, 0x3f, 0x16, 0x21, 0xc4, 0x7d, 0x00, 0x00, 0x00 }; static const u32 bnx2_COM_b09FwData[(0x0/4) + 1] = { 0x0 }; static const u32 bnx2_COM_b09FwRodata[(0x88/4) + 1] = { - 0x08001b7c, 0x08001bb8, 0x08001bb8, 0x08001bb8, 0x08001bb8, 0x08001bb8, - 0x08001ac8, 0x08001bb8, 0x08001b3c, 0x08001bb8, 0x08001a50, 0x08001bb8, - 0x08001bb8, 0x08001bb8, 0x08001a5c, 0x00000000, 0x08002b74, 0x08002bc4, - 0x08002bf4, 0x08002c24, 0x08002c58, 0x00000000, 0x08006120, 0x08006120, - 0x08006120, 0x08006120, 0x08006120, 0x0800614c, 0x0800614c, 0x0800618c, - 0x08006198, 0x08006198, 0x08006120, 0x00000000, 0x00000000 }; + 0x08001b68, 0x08001ba4, 0x08001ba4, 0x08001ba4, 0x08001ba4, 0x08001ba4, + 0x08001ab4, 0x08001ba4, 0x08001b28, 0x08001ba4, 0x08001a3c, 0x08001ba4, + 0x08001ba4, 0x08001ba4, 0x08001a48, 0x00000000, 0x08002abc, 0x08002b0c, + 0x08002b3c, 0x08002b6c, 0x08002b9c, 0x00000000, 0x0800604c, 0x0800604c, + 0x0800604c, 0x0800604c, 0x0800604c, 0x08006078, 0x08006078, 0x080060b8, + 0x080060c4, 0x080060c4, 0x0800604c, 0x00000000, 0x00000000 }; static struct fw_info bnx2_com_fw_09 = { - /* Firmware version: 3.7.1 */ .ver_major = 0x3, - .ver_minor = 0x7, - .ver_fix = 0x1, + .ver_minor = 0x4, + .ver_fix = 0x3, .start_addr = 0x080000b4, .text_addr = 0x08000000, - .text_len = 0x7e94, + .text_len = 0x7dc0, .text_index = 0x0, .gz_text = bnx2_COM_b09FwText, .gz_text_len = sizeof(bnx2_COM_b09FwText), - .data_addr = 0x08007f40, + .data_addr = 0x08007e60, .data_len = 0x0, .data_index = 0x0, .data = bnx2_COM_b09FwData, - .sbss_addr = 0x08007f40, + .sbss_addr = 0x08007e60, .sbss_len = 0x60, .sbss_index = 0x0, - .bss_addr = 0x08007fa0, + .bss_addr = 0x08007ec0, .bss_len = 0x88, .bss_index = 0x0, - .rodata_addr = 0x08007e98, + .rodata_addr = 0x08007dc0, .rodata_len = 0x88, .rodata_index = 0x0, .rodata = bnx2_COM_b09FwRodata, }; static u8 bnx2_CP_b09FwText[] = { - 0xbd, 0x7d, 0x0d, 0x74, 0x5c, 0xd7, 0x5d, 0xe7, 0xff, 0xdd, 0x79, 0x92, - 0xc6, 0xb2, 0x6c, 0x3f, 0xcb, 0x13, 0x79, 0x62, 0xab, 0xf6, 0x8c, 0xf4, - 0x64, 0xab, 0x91, 0x08, 0x2f, 0xae, 0x28, 0x82, 0x9d, 0x84, 0xe9, 0x48, - 0xb2, 0x9d, 0x34, 0xed, 0xca, 0x8d, 0x5b, 0xb2, 0x9c, 0x02, 0x62, 0x24, - 0x27, 0xe9, 0x77, 0xd2, 0x04, 0xb6, 0xec, 0xc9, 0x6e, 0x26, 0x23, 0xf9, - 0x83, 0x74, 0xec, 0x51, 0x12, 0x25, 0xce, 0xa1, 0x3d, 0xbb, 0xaa, 0xa4, - 0xd8, 0x06, 0x06, 0x8f, 0x93, 0xb8, 0xa5, 0xec, 0xa6, 0x54, 0x28, 0xae, - 0x09, 0xa1, 0x07, 0x52, 0x48, 0xd9, 0x40, 0x53, 0x2a, 0xdc, 0xb4, 0xcd, - 0x9e, 0x53, 0xb6, 0x01, 0xca, 0x12, 0x68, 0xe8, 0xdb, 0xdf, 0xef, 0xde, - 0xfb, 0x34, 0xa3, 0x0f, 0xe7, 0xa3, 0xec, 0xe2, 0x73, 0x9e, 0xdf, 0xbc, - 0xfb, 0xee, 0xc7, 0xff, 0xfe, 0xef, 0xff, 0xfb, 0xfe, 0xef, 0xd3, 0x76, - 0x91, 0x66, 0xb1, 0xff, 0x36, 0xe0, 0x7a, 0x5b, 0xea, 0xf6, 0xd1, 0x6b, - 0xae, 0xfe, 0xc9, 0xab, 0xf9, 0xec, 0x3a, 0x4d, 0x31, 0x79, 0x13, 0xff, - 0x52, 0x6f, 0xa0, 0x0e, 0x3a, 0xf4, 0xa2, 0xb1, 0x78, 0x49, 0x5c, 0x65, - 0xdc, 0x3b, 0x72, 0xbe, 0xc4, 0x63, 0x99, 0x91, 0x5f, 0x1e, 0xf5, 0x45, - 0xb2, 0x95, 0x9e, 0xd4, 0x80, 0xfc, 0x4b, 0x58, 0x48, 0xb8, 0xc2, 0xf2, - 0xb7, 0x64, 0x5e, 0xfd, 0x6f, 0x5f, 0xf8, 0xc9, 0xf4, 0xcb, 0xd3, 0x31, - 0x89, 0x7b, 0x99, 0x0f, 0x8b, 0xb7, 0x4b, 0xe2, 0xed, 0x19, 0xb9, 0xe3, - 0xd3, 0xbb, 0xff, 0x46, 0x64, 0x63, 0xd4, 0xd7, 0x4b, 0xe1, 0x17, 0x76, - 0x4b, 0x61, 0x5b, 0x26, 0x39, 0xd2, 0x90, 0x49, 0xc8, 0x17, 0xab, 0x9e, - 0x9c, 0xab, 0xca, 0xf0, 0xa9, 0xd2, 0xcb, 0xa1, 0x9b, 0x09, 0x63, 0x13, - 0x7d, 0x8e, 0xc4, 0x32, 0x72, 0x61, 0xb4, 0xef, 0x9e, 0x50, 0xf9, 0x32, - 0xe2, 0x65, 0xfc, 0x60, 0x41, 0x5a, 0xfa, 0x2f, 0xf6, 0xa1, 0x4e, 0xe5, - 0xe0, 0xb5, 0x8d, 0x27, 0xe2, 0xa2, 0x32, 0x5d, 0xcf, 0xe7, 0x62, 0xd7, - 0x88, 0xf2, 0xfd, 0xe0, 0x82, 0x74, 0x05, 0x4f, 0x09, 0xca, 0xcf, 0xc6, - 0x25, 0x57, 0x95, 0x16, 0x94, 0xe1, 0xde, 0x8c, 0x3a, 0x69, 0x2f, 0x17, - 0x4b, 0x48, 0xb1, 0xfa, 0x63, 0xcd, 0x66, 0xec, 0xaf, 0xaf, 0x33, 0xf7, - 0xdd, 0xf6, 0xbe, 0xee, 0x67, 0xdd, 0x4c, 0x3c, 0xae, 0x4e, 0xc8, 0xcb, - 0x13, 0x7d, 0x2f, 0x87, 0x31, 0xdf, 0xf7, 0x06, 0xa4, 0x41, 0x06, 0x13, - 0x80, 0xa9, 0xec, 0xa0, 0xef, 0x14, 0xda, 0xfe, 0x12, 0x70, 0x0e, 0xf8, - 0xca, 0x29, 0x29, 0x10, 0xce, 0x72, 0x5c, 0x16, 0x63, 0x49, 0x01, 0xfc, - 0xc0, 0x45, 0xbb, 0x8c, 0xa3, 0x3c, 0x57, 0xe2, 0x7c, 0x5c, 0xc9, 0x7b, - 0x1e, 0xe6, 0xd2, 0x8e, 0x36, 0x3b, 0x1d, 0xd3, 0x3f, 0x9e, 0x97, 0xd5, - 0x67, 0xdd, 0xe7, 0x51, 0x37, 0xa5, 0xeb, 0x3d, 0x51, 0x4d, 0xca, 0xe3, - 0xd5, 0x84, 0x3c, 0x56, 0xfd, 0x98, 0x64, 0x3d, 0xe2, 0x00, 0xb0, 0x96, - 0x1b, 0x65, 0x60, 0xaa, 0x59, 0x72, 0x53, 0x9d, 0xc9, 0xbc, 0x84, 0xe1, - 0x9d, 0xc1, 0x07, 0x64, 0xa4, 0x15, 0xf5, 0xcb, 0x7c, 0x97, 0x5c, 0xf6, - 0x2e, 0x1f, 0xf4, 0x78, 0x79, 0xe5, 0x48, 0xf6, 0x60, 0x3a, 0x39, 0xa2, - 0xf8, 0xdc, 0x20, 0xb9, 0x5e, 0x3c, 0x0f, 0xbb, 0x12, 0xf3, 0xc3, 0xf0, - 0x8e, 0x60, 0x17, 0xe0, 0x48, 0xa7, 0x52, 0x8a, 0x6d, 0xd9, 0x2e, 0x5d, - 0x48, 0xa9, 0x24, 0xe6, 0x71, 0xb5, 0xa4, 0x5a, 0xc3, 0xf0, 0x3d, 0x81, - 0x8f, 0x72, 0x91, 0x81, 0x92, 0xdc, 0xae, 0x32, 0x3e, 0xfa, 0x94, 0x40, - 0x65, 0xb6, 0x60, 0x1e, 0x3d, 0xc0, 0x43, 0xa3, 0x64, 0x13, 0x92, 0x55, - 0x19, 0x49, 0xa9, 0xcc, 0x3a, 0x94, 0x39, 0xd2, 0xe0, 0xff, 0x77, 0x4b, - 0x7f, 0x9b, 0xf0, 0x2c, 0xc3, 0x2a, 0xd3, 0xba, 0xa2, 0x3c, 0x9d, 0x12, - 0xf5, 0xe3, 0x71, 0x8c, 0xd9, 0x9d, 0x55, 0x2c, 0xc3, 0x5d, 0x97, 0x15, - 0x9a, 0x56, 0x97, 0x4d, 0x3a, 0xcb, 0xcb, 0x4e, 0xb5, 0x10, 0x56, 0x51, - 0xfc, 0x9d, 0xd4, 0x73, 0xcd, 0x26, 0x3a, 0xbd, 0x06, 0xcc, 0x6b, 0x38, - 0x48, 0x7b, 0x43, 0xea, 0xb9, 0x50, 0xda, 0x08, 0x33, 0xdf, 0x29, 0xbc, - 0x43, 0xd5, 0x4c, 0x80, 0x75, 0x4e, 0xc8, 0x51, 0xcc, 0xed, 0xd2, 0x54, - 0xda, 0xeb, 0x50, 0xb8, 0xcf, 0xf1, 0x77, 0x18, 0xe6, 0x82, 0x82, 0xa6, - 0x81, 0x6f, 0x4e, 0x25, 0xf1, 0x0c, 0xf8, 0x13, 0xd9, 0xf4, 0x66, 0xb9, - 0xc9, 0xae, 0xcb, 0x37, 0x31, 0x66, 0xa7, 0x77, 0x87, 0xea, 0xf4, 0x02, - 0x95, 0xf6, 0x66, 0xe4, 0xf7, 0xf1, 0x1c, 0x86, 0x07, 0x82, 0x74, 0xb2, - 0x80, 0x35, 0x7b, 0xb1, 0x94, 0x90, 0x6f, 0x95, 0xd2, 0xa0, 0xfc, 0x74, - 0xf7, 0xac, 0xf4, 0x04, 0xb3, 0x80, 0xb7, 0x88, 0xeb, 0x08, 0xdf, 0x55, - 0xf0, 0xae, 0xc2, 0xb6, 0x61, 0x78, 0x53, 0xf0, 0xeb, 0xe1, 0x48, 0x9b, - 0xe1, 0xa5, 0x2f, 0x96, 0xb1, 0x9e, 0x80, 0xf9, 0x71, 0xac, 0xd3, 0x63, - 0xe5, 0x88, 0x4e, 0xba, 0xb1, 0xee, 0xa4, 0x0d, 0xd2, 0xc5, 0x1e, 0x4b, - 0xff, 0xa3, 0xf6, 0x2e, 0x92, 0x03, 0x8d, 0xe5, 0x82, 0x1f, 0x84, 0x59, - 0xcd, 0x63, 0xe2, 0x0c, 0x94, 0x49, 0xbb, 0x0d, 0x80, 0x95, 0x8f, 0x1f, - 0xb3, 0xf5, 0xda, 0x1d, 0xe0, 0x96, 0xeb, 0xc0, 0xf7, 0x71, 0xe5, 0x37, - 0xd9, 0xf7, 0x11, 0x2f, 0xf1, 0x1f, 0xe8, 0xcd, 0xaf, 0xd5, 0xcb, 0x91, - 0x26, 0xab, 0x05, 0xc9, 0x3f, 0x18, 0xca, 0x40, 0x00, 0x3c, 0xb1, 0x4f, - 0x2f, 0x10, 0xdd, 0xd6, 0x63, 0x1d, 0x5d, 0x17, 0xff, 0xae, 0x69, 0xc4, - 0x18, 0xce, 0x60, 0xb9, 0xd6, 0x76, 0xb0, 0xfc, 0xe4, 0x16, 0x0b, 0x1f, - 0x9e, 0xfb, 0x9d, 0x5c, 0xf5, 0x6f, 0xed, 0xda, 0x46, 0xf3, 0xb8, 0x69, - 0x0d, 0xda, 0x0e, 0xc3, 0x89, 0x40, 0x46, 0x54, 0x66, 0x31, 0x9e, 0x2b, - 0x89, 0xd3, 0x90, 0xf1, 0xbd, 0x21, 0x59, 0x27, 0x76, 0x5e, 0xb6, 0xdc, - 0x03, 0xaf, 0x74, 0xa1, 0xdc, 0x11, 0xc8, 0x8d, 0x11, 0x07, 0x65, 0x1d, - 0x15, 0x94, 0x61, 0xfd, 0xc6, 0x81, 0xaf, 0x7c, 0xa9, 0x5f, 0xaf, 0x65, - 0xbe, 0x34, 0x0c, 0xde, 0xcf, 0xe0, 0x77, 0x76, 0xb3, 0x2b, 0x5d, 0xa0, - 0x43, 0xae, 0xb1, 0xb8, 0xb9, 0xdd, 0xa0, 0xd5, 0xea, 0xeb, 0x4b, 0x2c, - 0x3d, 0xf7, 0xe0, 0x5f, 0x88, 0xd3, 0x25, 0x78, 0x62, 0x19, 0xf2, 0xf5, - 0xf3, 0x21, 0xe8, 0x19, 0x65, 0x84, 0x99, 0x35, 0x13, 0x32, 0x51, 0xde, - 0x26, 0xc5, 0x29, 0x5f, 0xc6, 0x4b, 0xf3, 0xdd, 0x4a, 0x5e, 0x86, 0xac, - 0xf1, 0x41, 0x0b, 0x69, 0xf0, 0x41, 0x46, 0x06, 0xaa, 0x18, 0xaf, 0x84, - 0x7b, 0xb9, 0x13, 0x6d, 0x5d, 0xc9, 0x26, 0xcd, 0x3a, 0x17, 0x4b, 0x63, - 0xc0, 0x15, 0xd6, 0x8d, 0xb2, 0x41, 0xc3, 0x3c, 0x0c, 0x3a, 0xf4, 0x24, - 0xd7, 0xa7, 0xe1, 0x7c, 0x13, 0xf0, 0xc5, 0x65, 0x26, 0x68, 0xb4, 0x38, - 0x22, 0x7f, 0xc6, 0xdd, 0x01, 0xe0, 0x61, 0xa0, 0x72, 0x0f, 0xfa, 0x6f, - 0xc1, 0x6f, 0x96, 0x89, 0x2d, 0x73, 0xf5, 0xf3, 0x40, 0x85, 0x30, 0x47, - 0x74, 0x0f, 0x3e, 0x98, 0x82, 0xfc, 0x01, 0xdd, 0x0f, 0x90, 0x5f, 0xe6, - 0x38, 0x17, 0xc2, 0xb5, 0x4d, 0xff, 0x1e, 0x9f, 0xda, 0xa1, 0x9f, 0xf3, - 0xc3, 0xdb, 0xa4, 0x30, 0x17, 0xcd, 0x99, 0xb2, 0x87, 0xf2, 0x26, 0x7d, - 0x0c, 0x74, 0x05, 0xf9, 0x13, 0x86, 0x0f, 0x06, 0x94, 0x41, 0x61, 0xf8, - 0x78, 0x40, 0x99, 0x74, 0x1e, 0xb2, 0x86, 0x72, 0x88, 0x72, 0x61, 0x50, - 0x71, 0xdd, 0x73, 0xa5, 0x00, 0xeb, 0xd3, 0x28, 0xf9, 0xde, 0x47, 0x08, - 0x2b, 0x64, 0xd8, 0xb3, 0x1f, 0xcb, 0xf9, 0x85, 0x64, 0x4c, 0xe3, 0x49, - 0xb0, 0x5e, 0x71, 0xc9, 0xea, 0x99, 0x75, 0x48, 0xb1, 0x77, 0xd2, 0xd6, - 0x79, 0x49, 0xd7, 0x71, 0x57, 0xd5, 0xf9, 0x75, 0x65, 0x78, 0x3c, 0xc0, - 0x5a, 0xfe, 0xb4, 0x22, 0x1e, 0x3b, 0x76, 0xf1, 0x59, 0xe2, 0x0d, 0x99, - 0xaf, 0xe1, 0xdd, 0xb9, 0x3b, 0x1f, 0xf5, 0xd7, 0x7a, 0xb7, 0xb5, 0x61, - 0xf5, 0xbb, 0x09, 0x71, 0xfd, 0x74, 0xf7, 0x01, 0xf5, 0x4f, 0x78, 0x17, - 0x86, 0x8f, 0x06, 0x51, 0x79, 0x6f, 0xc3, 0xea, 0x31, 0x7e, 0x76, 0x8d, - 0xb2, 0xf3, 0x6b, 0x94, 0xfd, 0xc9, 0x1a, 0x65, 0xef, 0x6d, 0x5c, 0x5d, - 0xf6, 0xc0, 0x1a, 0x65, 0x4f, 0xaf, 0x51, 0xe6, 0x37, 0xad, 0x2e, 0xdb, - 0xb5, 0x46, 0xd9, 0x5b, 0xd7, 0x28, 0x3b, 0xb0, 0x46, 0x99, 0x0b, 0x1e, - 0xde, 0x25, 0xc5, 0xc4, 0xbd, 0x9c, 0xbb, 0xc5, 0xcd, 0xe7, 0x62, 0xab, - 0x71, 0xd3, 0x80, 0x7a, 0xed, 0x2b, 0xea, 0x7d, 0x6d, 0x8d, 0x7a, 0x8d, - 0xa8, 0xd7, 0xba, 0xa2, 0xde, 0xcd, 0xee, 0xea, 0x7a, 0x4d, 0xa8, 0x17, - 0x5f, 0x51, 0xef, 0x77, 0xd7, 0xa8, 0xc7, 0xf2, 0x4f, 0xd9, 0x71, 0x7a, - 0xa0, 0xd1, 0x5e, 0x6b, 0xbd, 0x1a, 0x45, 0xda, 0x58, 0x1e, 0x40, 0x1f, - 0xfd, 0xb4, 0x32, 0x32, 0x86, 0xf2, 0x4c, 0xe3, 0x0d, 0x74, 0x9e, 0x04, - 0xdd, 0x51, 0x26, 0x83, 0xcf, 0x7c, 0xf2, 0xfe, 0x06, 0x19, 0x49, 0xf4, - 0x78, 0x6f, 0x53, 0x2d, 0xa0, 0xb1, 0xb4, 0x97, 0x52, 0xe4, 0x3f, 0x29, - 0x80, 0xb7, 0x0b, 0x03, 0xa2, 0x12, 0x4a, 0x42, 0x19, 0x0c, 0x54, 0xab, - 0x92, 0x7b, 0xc0, 0x5f, 0x59, 0xe8, 0xbf, 0x03, 0xe1, 0x80, 0xe6, 0x2d, - 0x53, 0xf7, 0xf2, 0xf2, 0xb9, 0x5f, 0x8e, 0x50, 0xae, 0x66, 0x82, 0x3b, - 0x73, 0xfe, 0x7c, 0x7f, 0x23, 0x68, 0xf6, 0x12, 0xda, 0xec, 0x43, 0xcb, - 0x43, 0x15, 0x57, 0x06, 0x2b, 0x19, 0xf0, 0x82, 0x23, 0x17, 0xfd, 0x4d, - 0x72, 0x31, 0x40, 0xdd, 0x6a, 0x4c, 0x16, 0x12, 0x8e, 0x2c, 0xe0, 0x39, - 0x17, 0xe0, 0x5d, 0x35, 0xe2, 0xad, 0x8c, 0x1c, 0x2e, 0xf7, 0xcb, 0xb1, - 0xf2, 0x87, 0x55, 0xa4, 0x23, 0x87, 0x82, 0xf5, 0x72, 0xc6, 0x33, 0x7d, - 0xef, 0xf3, 0xe7, 0xa1, 0x9d, 0x5d, 0xb9, 0xe4, 0xa7, 0x93, 0x0b, 0x9a, - 0x27, 0xfe, 0x31, 0x1c, 0x44, 0x3f, 0x33, 0x7e, 0xda, 0xfb, 0x03, 0x0a, - 0xc9, 0x0a, 0x6d, 0xa9, 0x5a, 0x5f, 0xe3, 0xe8, 0xeb, 0x68, 0x79, 0x83, - 0xdc, 0x6a, 0xdb, 0xef, 0xf5, 0xe7, 0xbb, 0xc1, 0x73, 0xde, 0x29, 0xca, - 0x90, 0x12, 0xe0, 0x3a, 0x08, 0xde, 0x46, 0xdb, 0x2f, 0x09, 0xdb, 0xc0, - 0xf6, 0x2a, 0x6d, 0x82, 0xac, 0xff, 0x87, 0xf0, 0xd6, 0x04, 0xeb, 0xb3, - 0x8c, 0xfa, 0x4b, 0x26, 0x55, 0x06, 0x32, 0xa1, 0xaf, 0x0b, 0xfa, 0x2b, - 0x25, 0x83, 0x55, 0xc8, 0x9e, 0xf2, 0x0f, 0xc3, 0xac, 0xcb, 0x31, 0xa2, - 0xb1, 0xa4, 0x50, 0xab, 0xc3, 0x32, 0xd6, 0x23, 0xff, 0x2f, 0x2e, 0xc9, - 0x8a, 0x02, 0xe4, 0x8b, 0xb1, 0xd1, 0xfe, 0x13, 0x78, 0xb4, 0x5d, 0x06, - 0x4b, 0xe9, 0x42, 0x56, 0x76, 0x61, 0xfd, 0x7e, 0x0d, 0x6b, 0xea, 0xe2, - 0xfa, 0x93, 0xf5, 0xb2, 0x31, 0x80, 0x1d, 0xc0, 0x72, 0x74, 0xda, 0x46, - 0xfb, 0xec, 0x19, 0xe0, 0x61, 0x9c, 0x6b, 0x9e, 0xcc, 0xc5, 0x9c, 0x61, - 0xda, 0x3e, 0xc3, 0x90, 0x8f, 0xf9, 0x0a, 0xfb, 0x26, 0xbc, 0x49, 0xfb, - 0x1b, 0x36, 0x5b, 0xa9, 0xdd, 0xfe, 0x6e, 0xc1, 0xef, 0x94, 0xfd, 0x0d, - 0x99, 0x5a, 0xf2, 0xed, 0xef, 0x04, 0x7e, 0x77, 0xdb, 0xdf, 0x49, 0xfc, - 0xee, 0xd5, 0xbf, 0x27, 0xca, 0x7b, 0xf7, 0x2a, 0xff, 0x6a, 0xc9, 0xcf, - 0xb5, 0xcb, 0xe1, 0xd2, 0x7b, 0xad, 0x6c, 0xc1, 0x25, 0x9f, 0x77, 0xcc, - 0x3c, 0x01, 0x77, 0x99, 0x6d, 0x0a, 0xce, 0xb0, 0xb6, 0xdd, 0xda, 0x61, - 0xeb, 0xf4, 0x78, 0x9b, 0x85, 0x34, 0x30, 0xe1, 0x0c, 0x54, 0x9d, 0x6c, - 0x2c, 0xd3, 0x95, 0x1c, 0x97, 0x63, 0xf8, 0x2d, 0x5e, 0x2c, 0xf3, 0x79, - 0xdc, 0x0d, 0x0e, 0xbe, 0x00, 0x7d, 0x33, 0x5e, 0xa6, 0xbc, 0xf4, 0x31, - 0xf7, 0x94, 0x9c, 0x5f, 0x66, 0xaf, 0x11, 0x17, 0x4a, 0xf2, 0x53, 0xe9, - 0x47, 0x0a, 0x92, 0x2e, 0x4c, 0x83, 0x21, 0x0e, 0x04, 0xae, 0xbc, 0x27, - 0x00, 0xed, 0x5e, 0xed, 0xc8, 0xde, 0xab, 0x5d, 0xd8, 0x57, 0xfe, 0xf4, - 0x5e, 0xc8, 0xd8, 0x7c, 0xe9, 0xea, 0x18, 0xe9, 0x41, 0x9d, 0x95, 0x11, - 0x37, 0x03, 0x6c, 0x9f, 0xed, 0x1d, 0x1c, 0x2f, 0xe5, 0x3f, 0xac, 0x32, - 0xb7, 0xff, 0x6a, 0xae, 0x6f, 0x17, 0x74, 0x79, 0x18, 0xc6, 0x32, 0x6d, - 0xd0, 0x4b, 0x5c, 0x57, 0xea, 0xa9, 0x9b, 0x6e, 0x8a, 0x65, 0x1a, 0x64, - 0xe0, 0x60, 0x1b, 0xea, 0xb3, 0x9c, 0xb8, 0x72, 0xd0, 0x47, 0x3a, 0x35, - 0x28, 0x72, 0xf7, 0x44, 0xdf, 0xa2, 0x33, 0x3e, 0xf9, 0x73, 0xe0, 0xc7, - 0x7e, 0xc9, 0x1f, 0x7c, 0x00, 0xf8, 0x7d, 0xd9, 0x29, 0x4e, 0xbd, 0xe2, - 0x8c, 0x4f, 0xfd, 0x9d, 0x33, 0x31, 0xb5, 0x63, 0xc7, 0x50, 0xff, 0x8e, - 0x1d, 0xa3, 0xfd, 0xae, 0xd5, 0x2d, 0x3b, 0x76, 0x4c, 0xf4, 0x67, 0x31, - 0xff, 0x1e, 0x6f, 0x50, 0x7c, 0x6f, 0x2f, 0x95, 0x7c, 0xc2, 0xac, 0xfd, - 0x4c, 0xd0, 0x8d, 0xf7, 0x6c, 0xdf, 0xab, 0xdf, 0x0f, 0x48, 0x4f, 0xb2, - 0x55, 0x38, 0x7e, 0x87, 0xd5, 0x49, 0x6c, 0x07, 0x7a, 0xe9, 0xa5, 0x1d, - 0xa8, 0x50, 0x2f, 0x05, 0x7c, 0xd0, 0x26, 0xde, 0x06, 0x1b, 0x82, 0xed, - 0x94, 0x5d, 0xf7, 0x92, 0x6a, 0xf0, 0x63, 0xba, 0x5f, 0x75, 0x36, 0x13, - 0x33, 0x6b, 0xde, 0x63, 0xed, 0xeb, 0x4d, 0x28, 0xe7, 0x33, 0x71, 0x49, - 0x7c, 0xd1, 0xde, 0x69, 0xd0, 0xf6, 0x69, 0xbe, 0x44, 0x5a, 0x72, 0x65, - 0xac, 0xd4, 0x8f, 0x36, 0xa0, 0x97, 0xb3, 0xf6, 0x3a, 0x81, 0xf1, 0x0e, - 0xa2, 0xaf, 0x13, 0x47, 0xd1, 0x8e, 0xb2, 0x24, 0xdd, 0x2d, 0xea, 0x41, - 0xd4, 0xe9, 0xf1, 0xb6, 0x08, 0xed, 0x9a, 0x47, 0x24, 0x5f, 0x26, 0xdf, - 0xd3, 0x36, 0x88, 0x4b, 0xaa, 0x0d, 0xcf, 0xd5, 0xc3, 0xb0, 0x75, 0x1a, - 0x22, 0x7b, 0x43, 0x6a, 0x76, 0xd1, 0xaf, 0x2a, 0xf1, 0x0f, 0xcb, 0xc8, - 0xec, 0x76, 0xd4, 0x33, 0xf6, 0xbc, 0xf2, 0x61, 0x17, 0xcd, 0x66, 0x25, - 0xb7, 0xeb, 0x5e, 0xdc, 0x3d, 0x3c, 0x17, 0x71, 0x7f, 0x0b, 0xee, 0xe3, - 0xb8, 0x47, 0x70, 0x02, 0xe7, 0x41, 0xcc, 0xea, 0xb2, 0x51, 0x8c, 0xfd, - 0xef, 0x25, 0x37, 0x09, 0x7a, 0x2d, 0x85, 0x9b, 0x72, 0x7e, 0xd6, 0x53, - 0xa2, 0xb6, 0x28, 0x99, 0x40, 0x7d, 0xf8, 0x29, 0xfe, 0x11, 0x19, 0x3d, - 0x8d, 0xdf, 0x0f, 0xd2, 0xee, 0x9e, 0x90, 0xd1, 0x59, 0x8e, 0x53, 0x02, - 0x4c, 0x93, 0x92, 0x3f, 0xfd, 0x00, 0xae, 0x29, 0x5c, 0x0f, 0xe3, 0xe2, - 0xdc, 0xd8, 0xff, 0xc2, 0x66, 0x25, 0x2d, 0xfa, 0x39, 0x4f, 0xfa, 0xae, - 0xe2, 0x37, 0x69, 0xbb, 0x4a, 0x1b, 0x08, 0x74, 0x5d, 0x8d, 0xe8, 0x3d, - 0xb0, 0xbf, 0x93, 0x9a, 0xdf, 0x0b, 0xad, 0xa0, 0xa5, 0x6a, 0x56, 0xcb, - 0x22, 0xc0, 0x00, 0xb9, 0x03, 0x9b, 0xa4, 0x95, 0x73, 0xec, 0xb5, 0x65, - 0xbd, 0xba, 0x2c, 0xa5, 0xcb, 0xfa, 0x6c, 0x19, 0xee, 0xd5, 0x06, 0x19, - 0x69, 0x03, 0xc4, 0x94, 0xdb, 0x12, 0xe1, 0x93, 0xb2, 0x01, 0x74, 0x8d, - 0xf5, 0x3d, 0x7f, 0x59, 0xb9, 0xb8, 0xa8, 0xed, 0xbd, 0x73, 0x55, 0xd2, - 0x37, 0x69, 0x3e, 0x0c, 0xef, 0x0f, 0x9a, 0xd0, 0x3f, 0x65, 0x81, 0x48, - 0xc3, 0x09, 0x57, 0xa6, 0x3d, 0xd2, 0xc0, 0xc7, 0x5a, 0x48, 0x03, 0x8d, - 0x3e, 0x69, 0xbb, 0x9e, 0xef, 0xb8, 0x86, 0xec, 0xaf, 0x00, 0x1b, 0x92, - 0xb6, 0x64, 0x17, 0xec, 0x73, 0x8e, 0x71, 0x8c, 0xcf, 0x9e, 0x02, 0xaf, - 0xe5, 0x96, 0x78, 0x4d, 0x64, 0xa6, 0x44, 0xdc, 0x44, 0x36, 0x26, 0xd7, - 0x99, 0xf8, 0x39, 0x87, 0x39, 0xf3, 0x7e, 0xde, 0xe2, 0xe9, 0xf3, 0x16, - 0x4f, 0x4f, 0xda, 0xbb, 0xe7, 0xe4, 0xb5, 0xcd, 0x38, 0x8f, 0x67, 0xae, - 0x0f, 0xe8, 0xaa, 0x4a, 0x9e, 0x9b, 0xc6, 0x1d, 0x75, 0xcb, 0xe7, 0x64, - 0x54, 0xdb, 0x6f, 0x31, 0x79, 0x87, 0x96, 0x79, 0x5f, 0xc5, 0x5a, 0x96, - 0x00, 0x73, 0x83, 0x14, 0x12, 0x31, 0xbd, 0xf6, 0xae, 0xff, 0x5b, 0xae, - 0xa1, 0x55, 0xe2, 0x64, 0x99, 0xbf, 0x56, 0x07, 0x53, 0xe4, 0xa3, 0x12, - 0x2e, 0xd2, 0xee, 0xa7, 0x35, 0x5c, 0xb7, 0x40, 0x0e, 0x16, 0x44, 0xb5, - 0x35, 0xca, 0x95, 0xa0, 0x05, 0x95, 0x80, 0x46, 0x0b, 0x9f, 0x82, 0x3d, - 0x95, 0x9f, 0xa5, 0x9d, 0xde, 0x41, 0xdf, 0x28, 0x9e, 0xef, 0xdd, 0x48, - 0x3a, 0x52, 0x86, 0x6f, 0x1c, 0x95, 0xef, 0xd5, 0x74, 0xea, 0x28, 0x3f, - 0xa1, 0x6d, 0x71, 0xd7, 0xdf, 0xea, 0x5a, 0x9f, 0xde, 0x55, 0xfe, 0x96, - 0x95, 0x65, 0x29, 0xea, 0x67, 0xb4, 0x4b, 0xe5, 0x7b, 0xdb, 0xc8, 0x63, - 0x1e, 0xfc, 0xe1, 0xac, 0xf2, 0xb5, 0xff, 0x55, 0x50, 0x7d, 0x9b, 0x56, - 0xd4, 0xd7, 0x77, 0xc7, 0x3e, 0xbb, 0xf6, 0xee, 0xd9, 0x7b, 0xca, 0xde, - 0x0b, 0x6e, 0x1f, 0xef, 0x8e, 0xb8, 0x19, 0xde, 0xb1, 0x86, 0x19, 0xf6, - 0xa1, 0xf9, 0x2a, 0x34, 0xb6, 0x72, 0x97, 0x57, 0x14, 0xf2, 0xd5, 0x57, - 0xe5, 0x96, 0x59, 0x23, 0x97, 0xf7, 0x96, 0xc2, 0x10, 0x3e, 0xa2, 0xb7, - 0x00, 0xff, 0x38, 0x7b, 0xb0, 0x22, 0xb7, 0x54, 0x89, 0xb7, 0x4f, 0x02, - 0x7f, 0x43, 0x2e, 0x79, 0xd3, 0x13, 0xca, 0xe3, 0xbb, 0x84, 0xf6, 0x6a, - 0xb1, 0x44, 0x9c, 0x5f, 0x10, 0xae, 0x4d, 0xb1, 0xf4, 0xb4, 0x5e, 0x9b, - 0x23, 0xa5, 0x05, 0xe0, 0xe7, 0xcb, 0xa0, 0xfb, 0x30, 0x5c, 0x08, 0x8a, - 0xa0, 0x9c, 0x3f, 0xc6, 0x6f, 0xd8, 0x28, 0xa5, 0x67, 0xf1, 0x7e, 0xa3, - 0x14, 0x27, 0xc9, 0x73, 0xae, 0xe5, 0xe1, 0xb3, 0xe0, 0xa7, 0x9f, 0x41, - 0xbf, 0x28, 0xeb, 0xe3, 0xef, 0x1f, 0xe0, 0x1d, 0xee, 0xb3, 0x58, 0xc4, - 0x36, 0xda, 0x40, 0x1c, 0x9b, 0x6b, 0xc7, 0x35, 0xa3, 0xaf, 0x5e, 0xef, - 0x97, 0x73, 0xbd, 0xd2, 0xdd, 0x05, 0x59, 0x8a, 0x2b, 0xc8, 0xb9, 0x12, - 0xeb, 0x93, 0xfe, 0xfb, 0xd6, 0x19, 0x1d, 0xb1, 0xa1, 0xd9, 0xdc, 0x57, - 0xb6, 0xe5, 0x9a, 0xd7, 0xd3, 0x20, 0x7d, 0xa8, 0x74, 0x7f, 0x01, 0x72, - 0xc7, 0xf5, 0x37, 0xca, 0xa0, 0x96, 0x9d, 0xa4, 0x09, 0xd2, 0xc0, 0xcd, - 0xca, 0xd0, 0xe6, 0xfb, 0x95, 0xa1, 0xcd, 0xa7, 0x41, 0x8b, 0xb8, 0xca, - 0x8b, 0x8e, 0xa1, 0xcd, 0x2f, 0xe3, 0x8e, 0xab, 0xfc, 0xa2, 0x13, 0xf1, - 0xf1, 0x00, 0xfc, 0xca, 0xbd, 0x25, 0xd7, 0x19, 0xad, 0x82, 0x7e, 0xcb, - 0x71, 0x94, 0xcf, 0x13, 0xe7, 0x98, 0x3f, 0xc7, 0xd9, 0x69, 0xfb, 0x3f, - 0x27, 0x63, 0xe5, 0x50, 0xdb, 0x5b, 0xf9, 0xd9, 0x7b, 0x71, 0x5f, 0xaf, - 0xe5, 0x8c, 0xf2, 0xb3, 0xca, 0xc8, 0xab, 0x77, 0xe0, 0xde, 0x99, 0x3c, - 0x22, 0x9d, 0x5e, 0x4c, 0x9e, 0x45, 0x5f, 0xdf, 0x75, 0xc6, 0xaa, 0x2f, - 0xe3, 0xfa, 0x3e, 0xae, 0x57, 0x71, 0xbd, 0x82, 0x7e, 0x5f, 0x40, 0xf9, - 0x7a, 0x99, 0xf7, 0x9a, 0x51, 0x5f, 0xd4, 0x68, 0xf5, 0x79, 0x67, 0xe4, - 0xf4, 0x4b, 0xb8, 0x5c, 0x35, 0x56, 0x7d, 0xce, 0xc9, 0xcf, 0x86, 0x9b, - 0x16, 0x7c, 0xca, 0xb0, 0xaf, 0x3a, 0xa6, 0xef, 0x0c, 0xe6, 0x00, 0x9a, - 0x2e, 0xcf, 0x63, 0xec, 0xa7, 0x35, 0xcf, 0x0c, 0x42, 0x1f, 0xe4, 0x61, - 0xaf, 0x8c, 0x68, 0x98, 0xb6, 0x03, 0x3e, 0xf8, 0xd3, 0x7d, 0xb8, 0xcf, - 0x36, 0xca, 0x62, 0x82, 0xf6, 0xe5, 0x93, 0xba, 0x7e, 0xbe, 0x7c, 0xbd, - 0xc6, 0xed, 0xf4, 0x2a, 0xfe, 0xa1, 0x4f, 0x18, 0xc9, 0x03, 0x23, 0x8d, - 0x67, 0x4a, 0x94, 0x05, 0xd0, 0x4d, 0xa5, 0x09, 0xdc, 0x1b, 0xb5, 0x4c, - 0x28, 0x4a, 0x24, 0x0f, 0xd8, 0x8e, 0x32, 0xa1, 0x5e, 0xee, 0x50, 0xd6, - 0x50, 0xf6, 0x50, 0x96, 0x98, 0xf5, 0x18, 0x7d, 0x90, 0x32, 0xfc, 0x3a, - 0xe8, 0x4d, 0xda, 0x25, 0xbe, 0xf1, 0x4d, 0xa6, 0x72, 0xca, 0xc8, 0xd3, - 0xfd, 0x7a, 0x2d, 0xc6, 0x4a, 0x2a, 0x01, 0xc8, 0x51, 0x86, 0xeb, 0xe4, - 0x41, 0xdc, 0xf3, 0x6a, 0x0c, 0x57, 0xfe, 0xe4, 0xfb, 0xf0, 0x9b, 0x6b, - 0x33, 0x86, 0x7a, 0xb8, 0xca, 0xc3, 0xb8, 0xe3, 0x2a, 0xdf, 0xa8, 0x8c, - 0x1c, 0xe1, 0x9a, 0x26, 0xed, 0x9a, 0x3e, 0x09, 0x3c, 0x70, 0x7e, 0x4a, - 0xc7, 0x38, 0x94, 0xbf, 0x07, 0x78, 0xaf, 0x5a, 0x9f, 0x7a, 0xa3, 0x18, - 0x1e, 0xc4, 0xd5, 0x4d, 0x7e, 0x6e, 0x31, 0xeb, 0xa5, 0x69, 0x77, 0x5d, - 0x83, 0xe1, 0xc5, 0x04, 0xca, 0x62, 0x28, 0x6b, 0x33, 0x3a, 0x73, 0x09, - 0x8f, 0x59, 0x8b, 0x47, 0xfe, 0x56, 0xf6, 0x37, 0xe8, 0x09, 0xb6, 0x2e, - 0xe4, 0x35, 0xc6, 0xc5, 0x5c, 0x4e, 0xee, 0x57, 0xa3, 0x65, 0xfa, 0xc9, - 0x94, 0xe1, 0x8c, 0x65, 0x70, 0x7e, 0xec, 0x17, 0xe5, 0x1a, 0x07, 0x81, - 0xd4, 0xe2, 0x04, 0x4f, 0x62, 0xcd, 0xce, 0xc9, 0xa1, 0xf2, 0x47, 0xb4, - 0xdf, 0xde, 0x78, 0xc2, 0xac, 0x87, 0xa8, 0xa8, 0x1e, 0xfa, 0x4e, 0xd0, - 0xe6, 0xf9, 0x75, 0xfd, 0xde, 0x3d, 0xc1, 0xdf, 0x49, 0x1d, 0x4f, 0xaa, - 0xc9, 0x7b, 0x63, 0xef, 0x14, 0x97, 0xc9, 0x3a, 0xda, 0x1d, 0x58, 0xb3, - 0x4a, 0x3d, 0xde, 0x19, 0x47, 0xa0, 0xcc, 0x23, 0x3f, 0x1d, 0x01, 0x4f, - 0x60, 0xf2, 0x9a, 0xf7, 0xe9, 0x83, 0xac, 0xc5, 0x4f, 0x3e, 0x6c, 0x62, - 0x57, 0x4e, 0xc1, 0xa6, 0xdb, 0xbb, 0xd4, 0x07, 0x64, 0x65, 0x22, 0x2e, - 0xa7, 0x4b, 0x2d, 0x32, 0x5b, 0x52, 0x6d, 0x31, 0x2b, 0x3b, 0x63, 0x92, - 0xd4, 0xfa, 0x97, 0x76, 0xdf, 0xc0, 0x54, 0xcc, 0xd2, 0xdd, 0x8d, 0xe8, - 0xff, 0x93, 0xd0, 0xb1, 0x15, 0xe8, 0xd8, 0x8d, 0xd0, 0xc1, 0x2b, 0x65, - 0xc4, 0xfe, 0x86, 0xd5, 0x32, 0x82, 0x6d, 0xd2, 0xf0, 0xd6, 0x8f, 0xa0, - 0x5d, 0x44, 0x7f, 0x71, 0x4d, 0x6b, 0x79, 0x29, 0x38, 0x7b, 0xab, 0x13, - 0xce, 0xbe, 0xea, 0x4a, 0x1d, 0xd4, 0xe3, 0xb9, 0x62, 0x60, 0x3d, 0x5d, - 0xa2, 0xed, 0x9a, 0x0e, 0x72, 0xc0, 0xc9, 0x3e, 0xd0, 0xdd, 0x53, 0x93, - 0xf0, 0xef, 0x29, 0x97, 0x01, 0xf3, 0x19, 0xc0, 0x3c, 0x33, 0xe9, 0x44, - 0xb6, 0x81, 0x30, 0x40, 0x33, 0x33, 0xd5, 0x2b, 0x0b, 0x73, 0xa4, 0x43, - 0xc8, 0x80, 0x49, 0xac, 0x67, 0xb0, 0x0e, 0x76, 0x00, 0xc7, 0x87, 0xdc, - 0x9e, 0xda, 0xa6, 0xdf, 0x19, 0x7d, 0xde, 0x2e, 0x0b, 0x95, 0x3b, 0x2d, - 0x6c, 0xc7, 0xea, 0x60, 0x5b, 0xb7, 0x04, 0xdb, 0x3e, 0xc0, 0xb6, 0x7f, - 0x4d, 0xd8, 0xd6, 0xd2, 0xc5, 0x1d, 0xb0, 0x69, 0xc8, 0x1f, 0x11, 0x5e, - 0xdb, 0x2c, 0x3d, 0x94, 0xac, 0x1d, 0x4c, 0x9b, 0xe8, 0x87, 0x80, 0x87, - 0x34, 0x86, 0xdf, 0xb3, 0x8f, 0x52, 0x96, 0xa1, 0x9c, 0xcf, 0x0f, 0xa1, - 0x0e, 0x9e, 0x67, 0x13, 0x56, 0x0e, 0x7e, 0xc2, 0xc2, 0x42, 0x3b, 0x21, - 0x0b, 0x5b, 0x79, 0xd0, 0xc9, 0xcd, 0x12, 0x86, 0x53, 0x80, 0x17, 0xef, - 0xaa, 0xf5, 0x7d, 0xf2, 0xce, 0x7e, 0xaf, 0xb2, 0xfd, 0xb0, 0xef, 0x68, - 0x2e, 0xeb, 0xad, 0x9e, 0x8f, 0xe8, 0x2b, 0xb2, 0xbb, 0x27, 0x9c, 0xec, - 0xaa, 0x79, 0xd5, 0xd3, 0x1c, 0xe5, 0xad, 0x2b, 0x43, 0xa0, 0x93, 0xa1, - 0x65, 0xb4, 0xa6, 0xdd, 0x13, 0x4b, 0xc7, 0xeb, 0xec, 0xfc, 0x0e, 0x1b, - 0xbe, 0x09, 0xe2, 0xd0, 0x87, 0x94, 0x37, 0xff, 0xc5, 0xf8, 0xec, 0xf2, - 0xe5, 0x06, 0xc6, 0x69, 0xcd, 0x33, 0x69, 0x93, 0xbf, 0x29, 0x93, 0x6a, - 0xb4, 0x68, 0x7c, 0x9a, 0x76, 0x8c, 0x55, 0x6f, 0xc7, 0xbb, 0x32, 0x6c, - 0xd6, 0xfc, 0x18, 0xd7, 0x9c, 0x3e, 0x4a, 0xe7, 0x03, 0xc3, 0x96, 0xbf, - 0xd2, 0x93, 0x05, 0xb9, 0xd5, 0xce, 0xfd, 0xd2, 0x1a, 0x6b, 0xb7, 0x71, - 0x69, 0xed, 0x86, 0xab, 0x2b, 0xe7, 0x28, 0xd2, 0xf1, 0x80, 0xab, 0x7d, - 0x5e, 0xfa, 0xf0, 0x8d, 0x3e, 0xe5, 0x27, 0x6d, 0x25, 0x94, 0xcf, 0xf4, - 0x78, 0xad, 0xf0, 0x0d, 0xbe, 0xb8, 0xca, 0xee, 0x4a, 0x59, 0xb9, 0x49, - 0xff, 0x38, 0x1a, 0xa3, 0x60, 0xe5, 0x64, 0x01, 0xfd, 0x4f, 0x38, 0x43, - 0xd5, 0xb5, 0xe4, 0x65, 0x24, 0x27, 0x39, 0x9f, 0x7b, 0xe5, 0x8e, 0x07, - 0xc9, 0xa3, 0x25, 0x6d, 0x5f, 0x5f, 0xb3, 0xe7, 0x30, 0xf0, 0x47, 0xf8, - 0x17, 0x36, 0xc3, 0x64, 0x80, 0xce, 0xcd, 0xca, 0xa8, 0x5d, 0xb7, 0xd1, - 0xa5, 0xf5, 0xe7, 0x35, 0x0c, 0xdd, 0xc8, 0x58, 0xae, 0xb2, 0x30, 0x6b, - 0x3b, 0x16, 0x76, 0xdd, 0x4a, 0x5b, 0x96, 0x73, 0xa0, 0x3d, 0xdb, 0x68, - 0x6c, 0xc1, 0x32, 0xed, 0x4f, 0xca, 0x2e, 0xda, 0x9f, 0x57, 0x37, 0x4a, - 0x33, 0xe7, 0x93, 0xb5, 0x65, 0xb4, 0x53, 0x57, 0xce, 0x6f, 0xa5, 0x5f, - 0x49, 0x38, 0x09, 0xb7, 0xa1, 0xad, 0x94, 0x22, 0x6c, 0xa1, 0x0c, 0x07, - 0xd7, 0xe9, 0x35, 0x50, 0xb4, 0x5d, 0xf7, 0x34, 0x34, 0x9a, 0x38, 0xf6, - 0x5e, 0xf4, 0xcf, 0x31, 0xc9, 0x7f, 0xbc, 0xd3, 0xce, 0x5f, 0x4b, 0x96, - 0xd5, 0xeb, 0x9e, 0x2b, 0x97, 0xf0, 0x37, 0xb4, 0x6c, 0x8d, 0x22, 0xfc, - 0x45, 0x74, 0x51, 0x8f, 0x43, 0xd2, 0x04, 0x69, 0x21, 0xa2, 0xc5, 0x9d, - 0x56, 0xdf, 0x44, 0xb4, 0xb7, 0x15, 0xb4, 0x77, 0x1f, 0xf0, 0x44, 0x19, - 0xce, 0x78, 0xde, 0x16, 0x3c, 0x1f, 0xc7, 0x73, 0xc4, 0x27, 0x91, 0x0c, - 0xa7, 0x4d, 0xb4, 0x52, 0x8e, 0x53, 0x86, 0xc7, 0x61, 0xf7, 0x50, 0xd6, - 0x6f, 0xb7, 0xfc, 0x94, 0xb3, 0xbc, 0x44, 0x5d, 0xf0, 0xfb, 0xe8, 0xe7, - 0x86, 0x46, 0x63, 0xa7, 0x17, 0x1b, 0x29, 0x5f, 0x37, 0xcb, 0x91, 0xba, - 0xb2, 0xcb, 0xc9, 0xef, 0xfa, 0x39, 0x6f, 0xff, 0x7f, 0x30, 0xe7, 0xe4, - 0x8a, 0x39, 0x7b, 0x76, 0xce, 0x55, 0xbc, 0x6f, 0xc5, 0xfb, 0x16, 0xea, - 0x82, 0x54, 0x4d, 0xde, 0x58, 0x5c, 0x68, 0x7d, 0x56, 0x2f, 0x27, 0x22, - 0x19, 0xc1, 0x79, 0x1d, 0xb5, 0x73, 0xf8, 0x7c, 0xdd, 0xbc, 0x8e, 0xbe, - 0x89, 0x79, 0xb5, 0x2f, 0x9b, 0xd7, 0xde, 0xcb, 0xce, 0x6b, 0x2d, 0x1e, - 0x27, 0x2f, 0x47, 0xf3, 0x8b, 0xcb, 0x81, 0x12, 0xe7, 0x38, 0x84, 0x39, - 0x12, 0x86, 0x68, 0x8e, 0x19, 0x3b, 0x47, 0x51, 0x1d, 0x7b, 0x7e, 0x0a, - 0xbf, 0xeb, 0xe7, 0x47, 0xdd, 0xff, 0xf7, 0xa0, 0xe9, 0x26, 0xf8, 0xc4, - 0x4d, 0x56, 0xfe, 0x3f, 0x29, 0xb7, 0x96, 0xb9, 0xd6, 0xe9, 0xac, 0xc8, - 0x7e, 0x75, 0xa8, 0xfc, 0x72, 0x23, 0xf7, 0x11, 0xf6, 0x06, 0x56, 0x8f, - 0x41, 0x5f, 0xec, 0x83, 0xcd, 0x37, 0x54, 0x52, 0x7d, 0x31, 0x09, 0xc3, - 0xdb, 0x82, 0x66, 0x8c, 0xbd, 0x49, 0xfb, 0xaa, 0xab, 0x63, 0xf8, 0xcf, - 0x36, 0x8a, 0x4f, 0x7b, 0x83, 0xfa, 0x1c, 0xfa, 0xee, 0x24, 0x6d, 0xb0, - 0x1c, 0xec, 0xe4, 0x6c, 0x32, 0xa6, 0x6d, 0x31, 0xea, 0xc4, 0x74, 0x32, - 0x2b, 0x15, 0xc9, 0x9f, 0xcc, 0x26, 0xe1, 0xd8, 0x62, 0x0c, 0xd8, 0x6a, - 0xb0, 0x21, 0x6f, 0x85, 0xac, 0xb9, 0xb5, 0x7a, 0x50, 0xdd, 0x02, 0x7b, - 0xe7, 0x96, 0xd3, 0xef, 0x53, 0xb7, 0xc1, 0xd6, 0xb9, 0xed, 0xf4, 0x8d, - 0xea, 0x10, 0x6c, 0x9b, 0x43, 0xb0, 0x73, 0x0e, 0x55, 0x69, 0x7b, 0xde, - 0x0c, 0xba, 0x6b, 0x87, 0x1e, 0xe2, 0x5c, 0xb8, 0x26, 0xb4, 0x71, 0x38, - 0x3f, 0xe2, 0xfe, 0x0b, 0x5c, 0x83, 0x20, 0xa5, 0x76, 0x34, 0x71, 0x5d, - 0x5a, 0x97, 0x95, 0xbd, 0x96, 0xac, 0x8a, 0xf4, 0xd3, 0x06, 0x1b, 0x4f, - 0x32, 0x7e, 0xe5, 0xe5, 0x69, 0x8b, 0x34, 0xe2, 0x01, 0xcf, 0xc4, 0x1f, - 0x69, 0xab, 0x7e, 0xfe, 0x57, 0x36, 0x89, 0x9f, 0xc3, 0xf8, 0xf7, 0x42, - 0xbe, 0xd6, 0xd3, 0x14, 0xef, 0x5e, 0x1d, 0x7f, 0x50, 0x06, 0x47, 0xf4, - 0xb0, 0xf3, 0x35, 0xe4, 0xef, 0x65, 0xe9, 0xe9, 0x9e, 0x58, 0x26, 0x0c, - 0x47, 0xfb, 0x64, 0x13, 0xe3, 0x01, 0xb9, 0x6a, 0x2d, 0x26, 0xa0, 0xfc, - 0xfa, 0x98, 0x00, 0xfd, 0xac, 0x4f, 0x03, 0xbf, 0xd3, 0xb8, 0x44, 0x46, - 0x18, 0x77, 0xa8, 0x46, 0x76, 0xf9, 0x57, 0xac, 0x5d, 0x1e, 0xc1, 0x91, - 0x02, 0x1c, 0x46, 0x3e, 0xaf, 0xd6, 0x73, 0xcb, 0xf5, 0x77, 0x61, 0xc9, - 0xa6, 0x4d, 0xc9, 0x81, 0xb2, 0xb6, 0x13, 0x21, 0x83, 0x89, 0x9b, 0x7a, - 0x19, 0x9c, 0xb4, 0x76, 0x14, 0xea, 0x68, 0xf9, 0xb9, 0x5a, 0x76, 0x52, - 0xee, 0x31, 0x6e, 0xff, 0x40, 0x40, 0x5a, 0x7f, 0x97, 0x64, 0x97, 0xe2, - 0xf6, 0x02, 0x7a, 0x93, 0x20, 0x96, 0xd1, 0x7b, 0x7a, 0xde, 0x8c, 0xec, - 0x93, 0x81, 0x04, 0x63, 0xa0, 0x8c, 0xf3, 0xf9, 0x85, 0x19, 0xe9, 0x66, - 0x8c, 0x03, 0x16, 0x7c, 0xa3, 0x8c, 0x78, 0xa1, 0xec, 0x0d, 0x1c, 0x1d, - 0x53, 0x36, 0xba, 0xf6, 0x62, 0x93, 0xb1, 0x5d, 0x1d, 0x1d, 0x17, 0x5e, - 0x00, 0xf5, 0x2d, 0x68, 0xfb, 0x56, 0x69, 0xfd, 0x3b, 0xaf, 0xeb, 0xfc, - 0x41, 0x53, 0x14, 0xdf, 0x5c, 0xf0, 0x62, 0xb6, 0x5e, 0x7d, 0xf9, 0xd7, - 0x6c, 0xdc, 0xba, 0x1b, 0xb2, 0x3f, 0x2a, 0xfb, 0xde, 0x1a, 0x65, 0xb1, - 0xf8, 0xea, 0xb2, 0xcd, 0x6b, 0x94, 0x99, 0x78, 0xe1, 0x50, 0x69, 0x27, - 0xde, 0x4d, 0x68, 0xdf, 0x5d, 0xf4, 0x9e, 0x5b, 0xb7, 0x14, 0x96, 0xea, - 0x6c, 0xb0, 0x7e, 0x19, 0x63, 0xc7, 0x26, 0x66, 0x9c, 0xd7, 0x31, 0xe3, - 0x1e, 0x6f, 0x8f, 0xd2, 0x7b, 0x2c, 0xb7, 0x33, 0xfe, 0x78, 0x48, 0xe3, - 0x85, 0x38, 0xf9, 0x02, 0x63, 0xc3, 0x05, 0xee, 0x0f, 0xa7, 0xd4, 0xe5, - 0x68, 0xbb, 0x66, 0x9b, 0x98, 0x75, 0xa3, 0x5d, 0xdc, 0x22, 0x83, 0xb0, - 0x15, 0x86, 0x4a, 0xad, 0xb2, 0x77, 0xea, 0xa3, 0xeb, 0xa8, 0xb7, 0xf6, - 0x4d, 0x19, 0x7f, 0xf0, 0x10, 0xf8, 0x2a, 0x2b, 0x84, 0x31, 0x1d, 0x88, - 0xd0, 0x26, 0x5e, 0x6d, 0x0b, 0xbf, 0x76, 0x7f, 0xf7, 0x5f, 0xa6, 0x3f, - 0x07, 0xb6, 0xc3, 0x1b, 0xed, 0xaf, 0x59, 0x06, 0xa7, 0x22, 0x5c, 0xa9, - 0x1f, 0xb1, 0x5d, 0xec, 0x32, 0xed, 0xb4, 0x5d, 0x22, 0x4f, 0x2d, 0xc9, - 0xe2, 0x9d, 0xb0, 0x99, 0x24, 0xcc, 0xf5, 0x49, 0x7b, 0x4c, 0x74, 0x8c, - 0x27, 0x30, 0xb2, 0xb9, 0x8b, 0x7b, 0x3e, 0xa0, 0x7f, 0x63, 0xab, 0x98, - 0x78, 0x6a, 0x64, 0xa7, 0xac, 0x45, 0xbb, 0xd7, 0x5b, 0xda, 0xe5, 0xbe, - 0xee, 0x3e, 0xca, 0x5c, 0xac, 0x89, 0xa1, 0xe3, 0xbd, 0x25, 0x49, 0x45, - 0x74, 0xbc, 0x20, 0xd9, 0x65, 0x74, 0xbc, 0x20, 0x83, 0x9a, 0x8e, 0x1b, - 0x97, 0xd1, 0x71, 0xbb, 0xa5, 0xe3, 0x8f, 0xc6, 0x0d, 0x5d, 0x28, 0xad, - 0xa7, 0x48, 0xa7, 0x86, 0x8e, 0x1d, 0x4d, 0xc7, 0x0b, 0xb8, 0xbb, 0xfe, - 0xc7, 0x6c, 0x9d, 0x98, 0x2d, 0xe3, 0xef, 0xa8, 0x8c, 0x72, 0x71, 0x2a, - 0x6e, 0xf4, 0xd2, 0x20, 0xe8, 0x28, 0x2a, 0xff, 0x4d, 0x4b, 0x9f, 0xf5, - 0x65, 0x26, 0x3e, 0x32, 0x54, 0x3a, 0xb2, 0x82, 0x3e, 0x07, 0x41, 0x9f, - 0x51, 0x9d, 0xd7, 0xa2, 0xcf, 0x66, 0xbb, 0x9f, 0x91, 0xd4, 0x7b, 0xff, - 0xd9, 0x84, 0xa1, 0xd5, 0x5b, 0xf4, 0xdc, 0x39, 0xef, 0x0b, 0x6f, 0x80, - 0x56, 0xcd, 0xda, 0x5c, 0xac, 0xf9, 0xdb, 0x8c, 0x45, 0xa5, 0x4c, 0x6c, - 0x9b, 0x71, 0xd2, 0xcb, 0xd9, 0x8e, 0x2f, 0xd5, 0xf9, 0x15, 0x1b, 0xa4, - 0xc0, 0xbc, 0x87, 0xea, 0x46, 0xc6, 0xa2, 0x47, 0xdc, 0x4c, 0x9f, 0x64, - 0x2b, 0xed, 0xa9, 0x62, 0x89, 0x7e, 0xd1, 0xab, 0x36, 0x37, 0x02, 0xcf, - 0x95, 0x16, 0x79, 0xb4, 0x44, 0xda, 0x3a, 0x62, 0x70, 0xb1, 0x26, 0xad, - 0x73, 0xad, 0xd9, 0x4f, 0xbd, 0x0e, 0xe8, 0x83, 0xee, 0xa1, 0xcd, 0xae, - 0xe5, 0x3e, 0xde, 0xb5, 0xa7, 0x72, 0xa5, 0xa8, 0x5f, 0xee, 0x3f, 0x70, - 0x4f, 0xb8, 0x3d, 0xd5, 0x51, 0xf1, 0x6d, 0x9c, 0x79, 0x23, 0x9e, 0xfb, - 0xa4, 0xa3, 0xa2, 0xe4, 0x03, 0x53, 0x2d, 0x72, 0x7b, 0xc9, 0x95, 0x0f, - 0xa1, 0xfd, 0x07, 0x4b, 0x1e, 0xfc, 0xfb, 0xff, 0x1d, 0xa7, 0x9d, 0x79, - 0xa8, 0xc4, 0x7d, 0x50, 0x47, 0xdb, 0x2a, 0xcb, 0xf7, 0x86, 0x63, 0xd2, - 0xd1, 0x55, 0x84, 0xe7, 0x23, 0xee, 0x7e, 0xc0, 0xd1, 0x94, 0xc9, 0xc8, - 0x77, 0xfa, 0x36, 0xa1, 0x2c, 0xca, 0xf1, 0x18, 0x76, 0x4c, 0xfc, 0xb8, - 0x5f, 0xde, 0x59, 0xcd, 0xc8, 0x0d, 0x55, 0xb3, 0x77, 0x5b, 0xdb, 0x9b, - 0x4d, 0x7b, 0xf3, 0xd0, 0x67, 0x59, 0x2f, 0x0c, 0x2f, 0xfa, 0xa0, 0xa2, - 0xe3, 0xae, 0xc4, 0xbb, 0xd2, 0xc9, 0x79, 0x31, 0xcf, 0x97, 0x2a, 0xff, - 0x1c, 0x8e, 0x24, 0x5c, 0xf9, 0x8e, 0xcf, 0x39, 0xf6, 0xcb, 0xf5, 0x95, - 0xfa, 0xb1, 0xb9, 0x3f, 0x1b, 0x5b, 0xc7, 0xfd, 0x90, 0x5c, 0xf5, 0x9f, - 0xe3, 0x8c, 0xdb, 0xd3, 0x87, 0xe9, 0xf8, 0x31, 0xee, 0x87, 0xbb, 0xb8, - 0x83, 0x0e, 0x13, 0xb0, 0x21, 0xae, 0x01, 0x8c, 0xd7, 0x30, 0x96, 0xc6, - 0x18, 0x1a, 0x9f, 0xbf, 0x8c, 0x71, 0xd9, 0xf6, 0x93, 0xd6, 0xfe, 0x3e, - 0xb2, 0xc4, 0x8b, 0x6b, 0xeb, 0xb1, 0x8d, 0x23, 0xf1, 0x8c, 0x38, 0xf1, - 0x9f, 0x48, 0xca, 0x3a, 0xbf, 0x7e, 0x7c, 0xee, 0x47, 0xc3, 0xa2, 0xec, - 0x13, 0x77, 0xdf, 0xee, 0x7e, 0x19, 0xc4, 0xfc, 0x86, 0x56, 0xcd, 0xef, - 0x1e, 0x61, 0xbc, 0xf6, 0x52, 0x89, 0x73, 0xa8, 0xcd, 0x4b, 0xfd, 0xb6, - 0x99, 0x57, 0xbc, 0x6b, 0xe5, 0x7c, 0x74, 0x7b, 0x75, 0x0a, 0xb0, 0x7c, - 0x49, 0xe7, 0x42, 0x84, 0xe1, 0x5b, 0xbb, 0x2e, 0x85, 0xa9, 0x2b, 0xd2, - 0xdd, 0xf3, 0xb5, 0x7d, 0xa4, 0x91, 0x58, 0x26, 0xab, 0xf5, 0x23, 0x9e, - 0x53, 0xf9, 0xca, 0x7e, 0xac, 0xa3, 0xb8, 0xf9, 0x5e, 0x57, 0xf3, 0x5d, - 0xde, 0xdf, 0x6f, 0xf7, 0xca, 0x22, 0x9f, 0x2c, 0x0c, 0x95, 0xbf, 0x52, - 0x0e, 0x51, 0xff, 0x61, 0xee, 0xf2, 0x98, 0xdd, 0x3f, 0xe8, 0x66, 0x7c, - 0x0c, 0xb4, 0x18, 0x07, 0xdd, 0xf9, 0xf8, 0xdd, 0x82, 0xfb, 0x1e, 0xd8, - 0x3f, 0x01, 0xec, 0x23, 0x49, 0x28, 0x23, 0x6b, 0xc0, 0x1b, 0x5d, 0x05, - 0xa5, 0xc8, 0xeb, 0x5e, 0x6a, 0xbc, 0x92, 0x48, 0x4d, 0x56, 0x9e, 0x60, - 0x7b, 0xd4, 0x5d, 0x2b, 0x36, 0x68, 0xf2, 0x6c, 0xbe, 0x58, 0xe5, 0x18, - 0xa4, 0xfb, 0x37, 0x32, 0x86, 0x6b, 0xfb, 0x66, 0x9f, 0x11, 0x5e, 0x5c, - 0xba, 0xf8, 0xf8, 0xb7, 0xdf, 0xfa, 0x3a, 0x9c, 0xdf, 0x13, 0x16, 0xee, - 0x95, 0xe3, 0x3e, 0xaf, 0xed, 0xa1, 0xc7, 0xab, 0xb4, 0x41, 0xb9, 0x8f, - 0x94, 0x7e, 0x64, 0x5a, 0x08, 0x47, 0x18, 0x3e, 0x1b, 0x18, 0x5b, 0xe0, - 0x8b, 0x55, 0xee, 0x99, 0x84, 0xe1, 0xdf, 0xd2, 0xce, 0x3e, 0x58, 0xc6, - 0x78, 0x11, 0x0e, 0x76, 0x16, 0x5c, 0xc8, 0xd9, 0x89, 0x3e, 0xe2, 0x57, - 0xe0, 0xf1, 0x76, 0x79, 0x07, 0x24, 0x9e, 0xfa, 0x78, 0xa5, 0x25, 0x75, - 0x67, 0xc5, 0x03, 0x9e, 0x39, 0xef, 0x44, 0x6a, 0xcc, 0xce, 0x39, 0x5f, - 0x21, 0x7e, 0x5f, 0x6b, 0xbf, 0xf3, 0xf9, 0x65, 0xfe, 0x17, 0x61, 0xaa, - 0xc1, 0x42, 0xd8, 0x52, 0x16, 0x37, 0x61, 0xf8, 0xf7, 0x01, 0xc7, 0xdc, - 0x0f, 0x1f, 0x46, 0x26, 0x30, 0x6e, 0x61, 0x8b, 0x22, 0x1e, 0xe2, 0xa9, - 0x3b, 0x30, 0xf6, 0xc7, 0x31, 0xf6, 0xed, 0x15, 0x8e, 0x07, 0xd9, 0x83, - 0xb9, 0x4f, 0x54, 0x23, 0x78, 0xd7, 0x1a, 0x3b, 0x5a, 0xf3, 0x6e, 0x6b, - 0x33, 0x46, 0xcf, 0x1a, 0x91, 0x6d, 0x0a, 0xbe, 0x63, 0xae, 0xba, 0xb0, - 0xd9, 0x95, 0x9f, 0x81, 0x1c, 0x0f, 0xe5, 0x51, 0xc8, 0xc7, 0x05, 0x4d, - 0x37, 0xb9, 0xed, 0xfc, 0x3f, 0x26, 0x4f, 0xad, 0x63, 0xbc, 0x7a, 0xc0, - 0xa7, 0x2d, 0xbc, 0x18, 0x2e, 0xf8, 0x94, 0xf7, 0x1b, 0x64, 0xda, 0x2b, - 0x74, 0x43, 0xf7, 0xa0, 0x6c, 0x23, 0xfd, 0xf7, 0x54, 0x2e, 0x96, 0x4e, - 0x8d, 0x0b, 0x73, 0xbe, 0x98, 0x13, 0xc1, 0xbc, 0x26, 0xca, 0x06, 0x17, - 0x32, 0x94, 0x6b, 0x68, 0xc6, 0x1b, 0xaf, 0xd4, 0xea, 0x1e, 0x16, 0xee, - 0x4d, 0xa6, 0x93, 0x87, 0xb4, 0xbd, 0x23, 0x32, 0x5a, 0x62, 0xdd, 0xdd, - 0xb0, 0x76, 0xfc, 0xba, 0xfa, 0x3a, 0x57, 0x0d, 0x7c, 0x1e, 0xc5, 0xc5, - 0xe2, 0xcc, 0x29, 0x79, 0x39, 0xd6, 0x27, 0x2f, 0xd3, 0x8e, 0x1d, 0x00, - 0x6d, 0x7b, 0xbe, 0xce, 0x2b, 0xd1, 0xe5, 0xb9, 0x40, 0x16, 0x73, 0xfd, - 0x3d, 0xb4, 0xdb, 0x0b, 0x4a, 0xf3, 0x84, 0x28, 0xb4, 0x8d, 0xe7, 0x2b, - 0x32, 0x98, 0x2f, 0xd9, 0xd8, 0xd1, 0x30, 0xe7, 0xbc, 0xa1, 0x6e, 0xee, - 0x1b, 0xc5, 0x05, 0x4c, 0x83, 0xb1, 0x94, 0xd3, 0xe0, 0x7f, 0xaa, 0xc5, - 0xd8, 0x10, 0xd0, 0x23, 0xad, 0xf7, 0xb7, 0x71, 0x6f, 0x56, 0xc1, 0x27, - 0x57, 0x6d, 0x1f, 0xbe, 0x56, 0x65, 0xfe, 0x32, 0x09, 0xbd, 0x6a, 0x65, - 0x65, 0x7c, 0xb0, 0x63, 0x89, 0xbe, 0x39, 0xbe, 0xb4, 0xc5, 0xfc, 0xd4, - 0xe0, 0x40, 0x45, 0x54, 0x2c, 0xe3, 0xc5, 0x07, 0x2a, 0xcb, 0x69, 0xfe, - 0x8b, 0xd5, 0xcf, 0x5a, 0xdb, 0xb2, 0x3e, 0x46, 0x5b, 0xff, 0x8e, 0x7c, - 0xb7, 0x6c, 0xff, 0x23, 0x05, 0xbe, 0xb2, 0xfb, 0xc6, 0x5c, 0x93, 0xec, - 0x5b, 0x19, 0xd8, 0x9c, 0xd6, 0x3e, 0x1f, 0x73, 0x3b, 0xe2, 0x36, 0xbf, - 0xce, 0xe0, 0x3a, 0x5b, 0x71, 0x64, 0x02, 0xf2, 0xe1, 0xb0, 0xfc, 0x53, - 0x98, 0x4d, 0x98, 0xf7, 0x66, 0x7d, 0x59, 0x9f, 0x7b, 0x1b, 0xcd, 0x52, - 0x3c, 0xed, 0x4a, 0xe1, 0x34, 0xf7, 0xd4, 0xce, 0xdd, 0x51, 0xcb, 0x0f, - 0xa1, 0x1c, 0xe0, 0xbe, 0xb0, 0x23, 0x45, 0xf8, 0xc8, 0x83, 0xdc, 0xef, - 0xef, 0xfd, 0x47, 0xe6, 0xea, 0xc4, 0xb9, 0x4e, 0xa6, 0x6d, 0x0b, 0xda, - 0x36, 0xda, 0xb6, 0xc1, 0xc7, 0xdf, 0x5c, 0xdb, 0x8d, 0x68, 0x1b, 0x8f, - 0xc6, 0x7d, 0x83, 0x6d, 0x35, 0x3e, 0xaf, 0x1d, 0x28, 0x95, 0x17, 0x5d, - 0xdf, 0x4f, 0x8e, 0x49, 0xd6, 0x19, 0xed, 0xd3, 0xf3, 0xb9, 0x76, 0xa0, - 0x02, 0x38, 0x12, 0x61, 0x58, 0x0c, 0x22, 0xbd, 0xce, 0x7f, 0x27, 0xa1, - 0xde, 0x59, 0xc6, 0x7d, 0x50, 0xfa, 0x27, 0x8c, 0xba, 0x7a, 0xcc, 0xc1, - 0x93, 0x22, 0xf7, 0x3b, 0x13, 0x9b, 0x70, 0x57, 0x1d, 0xc4, 0x49, 0xde, - 0x67, 0xfc, 0x78, 0x93, 0x2d, 0x8f, 0xb1, 0x3c, 0xed, 0x42, 0x96, 0x98, - 0xf2, 0x98, 0x2d, 0x07, 0x4c, 0x41, 0x31, 0x05, 0x6e, 0xb3, 0xe5, 0x7c, - 0x56, 0xba, 0xdc, 0x3c, 0x1b, 0x1e, 0x1a, 0x11, 0xc6, 0x89, 0x72, 0xd7, - 0x37, 0xc8, 0x4e, 0xac, 0x0f, 0x7d, 0x50, 0x47, 0x9a, 0x01, 0xc7, 0xc5, - 0xe0, 0xc7, 0x61, 0xab, 0x87, 0xf2, 0x9d, 0xc0, 0xd0, 0xff, 0x8c, 0x74, - 0x65, 0x95, 0xc3, 0x5c, 0x83, 0x50, 0x86, 0x82, 0x5d, 0xc9, 0xbd, 0xf8, - 0x3d, 0xda, 0x9b, 0x92, 0x99, 0x7e, 0xd0, 0x63, 0x2f, 0x79, 0x63, 0x27, - 0x6c, 0x28, 0xfc, 0xee, 0x6a, 0x91, 0x45, 0xaf, 0xe0, 0xad, 0x83, 0xff, - 0x37, 0x88, 0x59, 0xcd, 0x96, 0x7c, 0xef, 0x36, 0x08, 0xb9, 0xac, 0xd7, - 0x85, 0x7b, 0xfd, 0x7c, 0xbf, 0x8e, 0xf9, 0x9e, 0x6b, 0x96, 0x66, 0x96, - 0xd7, 0xd7, 0x6d, 0x94, 0xfd, 0xde, 0x6e, 0x2f, 0xbe, 0xac, 0xee, 0x25, - 0xd4, 0x65, 0x99, 0xef, 0x31, 0x17, 0x68, 0xa6, 0x42, 0x3a, 0x33, 0xb0, - 0x76, 0x74, 0x85, 0xe1, 0xf5, 0x01, 0xc7, 0x0d, 0xc3, 0x1b, 0x82, 0x1e, - 0xef, 0x19, 0x79, 0x2e, 0x34, 0x36, 0x5a, 0x44, 0x3b, 0xcf, 0x5a, 0x79, - 0x1d, 0x86, 0x2f, 0x07, 0xdd, 0xf2, 0xb9, 0x6a, 0xfa, 0x1c, 0x7d, 0xf8, - 0xf3, 0x78, 0x3e, 0x1f, 0x98, 0xfc, 0xa5, 0x3f, 0x43, 0xbb, 0x84, 0xea, - 0x05, 0x0d, 0xfb, 0xf2, 0x59, 0xed, 0xf3, 0x13, 0x7f, 0x66, 0xcf, 0xa0, - 0x06, 0x03, 0x26, 0xec, 0xe7, 0x36, 0x7b, 0xcc, 0x69, 0xd4, 0xf4, 0x5b, - 0xff, 0x4e, 0xe1, 0x1d, 0xcb, 0xc2, 0xf0, 0x8a, 0xbe, 0x96, 0xf5, 0xd0, - 0xd7, 0x93, 0xdc, 0x0b, 0x7c, 0x9f, 0xe6, 0x3f, 0x91, 0x03, 0xdc, 0xf7, - 0x02, 0x0e, 0x95, 0xf2, 0x8f, 0x75, 0xa8, 0x74, 0x41, 0xe4, 0x2d, 0x58, - 0x7f, 0xae, 0x31, 0x18, 0xa4, 0x15, 0xb0, 0xef, 0xfa, 0xa5, 0x66, 0x13, - 0x9b, 0xa2, 0x6f, 0x9e, 0xdd, 0x0c, 0xdf, 0x59, 0xdb, 0x33, 0xdc, 0x57, - 0x1f, 0x6b, 0x0d, 0xc3, 0xf7, 0x06, 0xd1, 0x9a, 0xd9, 0xd8, 0x37, 0x74, - 0x7c, 0xbe, 0x57, 0xd6, 0x1b, 0xbb, 0x90, 0xb9, 0x8d, 0x29, 0xbd, 0x4f, - 0xa0, 0xda, 0xa0, 0x43, 0x76, 0xfd, 0x00, 0x38, 0xe5, 0x18, 0xcc, 0x73, - 0x8c, 0x60, 0xaa, 0xb5, 0xcf, 0xf7, 0xae, 0xb3, 0x36, 0xac, 0x0b, 0x5c, - 0xfa, 0x5e, 0x87, 0xfa, 0x5e, 0x68, 0x74, 0x6b, 0x44, 0xc3, 0xff, 0x10, - 0x3e, 0x98, 0x30, 0xcf, 0xb9, 0x5d, 0xec, 0x63, 0xa7, 0x8c, 0xef, 0xc2, - 0xb3, 0x7b, 0x1d, 0xee, 0x03, 0x57, 0xc6, 0xe4, 0xaa, 0xe4, 0x80, 0xda, - 0xe5, 0x3d, 0x28, 0x3d, 0x56, 0xc6, 0x7d, 0x09, 0xfa, 0xbe, 0x00, 0xff, - 0xbe, 0x49, 0x1e, 0x04, 0x4d, 0xab, 0xbe, 0x74, 0x6a, 0x5e, 0xa5, 0xbb, - 0xa7, 0x55, 0x3a, 0x18, 0x51, 0x13, 0x9c, 0x57, 0x3f, 0x71, 0x31, 0x4d, - 0xfc, 0x96, 0x81, 0xff, 0x32, 0x70, 0x7c, 0xd9, 0x3d, 0xe3, 0xc0, 0xea, - 0x16, 0xa3, 0xdf, 0x0a, 0x9a, 0x36, 0x8d, 0x9d, 0xff, 0xa7, 0x41, 0xb4, - 0x86, 0x3d, 0x5e, 0x03, 0x73, 0x71, 0xd6, 0x5c, 0xa3, 0x3c, 0xd7, 0x08, - 0x8a, 0xa1, 0x00, 0xba, 0x4f, 0xa7, 0xc6, 0xd4, 0x62, 0xb8, 0x79, 0x4f, - 0x67, 0xf7, 0x63, 0xba, 0x9f, 0x74, 0x90, 0x55, 0x4f, 0x02, 0x9e, 0x9d, - 0xd2, 0xb4, 0x87, 0x78, 0x26, 0xac, 0x71, 0xc6, 0xa7, 0xbc, 0x3b, 0x50, - 0x77, 0x44, 0xe9, 0x3d, 0x6d, 0x5b, 0x87, 0x30, 0xbf, 0x1b, 0xf8, 0xa5, - 0x1e, 0x62, 0xcc, 0xed, 0xb5, 0x74, 0x21, 0x64, 0xd2, 0x49, 0xca, 0xc0, - 0x98, 0x89, 0x25, 0x57, 0xef, 0xe4, 0xfa, 0xd3, 0x13, 0x88, 0xbb, 0x90, - 0x51, 0x13, 0xe0, 0xe2, 0xa3, 0x27, 0xc5, 0x6d, 0xf0, 0xbb, 0xd7, 0x1b, - 0x3f, 0x8c, 0x3e, 0x19, 0xc7, 0x6e, 0x90, 0xe2, 0xaa, 0xf8, 0xcd, 0x24, - 0xe0, 0x6f, 0x96, 0xf1, 0x93, 0x5c, 0x0b, 0x17, 0x32, 0x87, 0x63, 0x8b, - 0x9b, 0xeb, 0x0d, 0xc3, 0x51, 0x96, 0x9f, 0x26, 0xff, 0x4a, 0x9a, 0xef, - 0x0a, 0xa7, 0xe7, 0x37, 0xab, 0x65, 0xb2, 0xb6, 0xc5, 0xc2, 0xa1, 0xf1, - 0x24, 0x93, 0x5a, 0x8e, 0x50, 0xdf, 0xcc, 0xd4, 0xc1, 0x13, 0x7c, 0x7c, - 0xc2, 0x6f, 0x7c, 0x13, 0xf0, 0xfc, 0x0f, 0xc0, 0xd3, 0x62, 0xe1, 0x69, - 0x5c, 0x01, 0x4f, 0x4b, 0x04, 0x0f, 0xe4, 0x1c, 0xe5, 0x6a, 0xfc, 0xda, - 0x6c, 0x45, 0x9c, 0xa2, 0x2f, 0xed, 0x4a, 0xfb, 0x43, 0xd4, 0x37, 0x8d, - 0xde, 0x68, 0x9f, 0x27, 0xa3, 0x5a, 0xd7, 0xb8, 0xd7, 0x76, 0x56, 0xe6, - 0x61, 0xbd, 0x8a, 0x93, 0xf3, 0x09, 0xfb, 0x5a, 0x76, 0xd5, 0x3d, 0x90, - 0xff, 0x0b, 0x69, 0xd7, 0xda, 0x12, 0x93, 0x01, 0xfd, 0xa0, 0x84, 0xce, - 0x15, 0xa8, 0xc1, 0xf4, 0x12, 0x60, 0x82, 0x3c, 0x3e, 0xd9, 0xe3, 0x0d, - 0xcb, 0x56, 0xed, 0xeb, 0x59, 0x5c, 0x63, 0x6e, 0xf1, 0xba, 0xb9, 0x41, - 0xff, 0xa9, 0x68, 0x6e, 0x90, 0x89, 0xa8, 0x37, 0x29, 0x7f, 0x64, 0x71, - 0xb1, 0x11, 0x73, 0x8a, 0xd7, 0xcd, 0xa7, 0x33, 0x79, 0x3b, 0xcb, 0xcc, - 0x7c, 0xba, 0x8a, 0x7e, 0xdc, 0xe2, 0x77, 0x2d, 0x9f, 0xc4, 0xd8, 0x3d, - 0xd3, 0x12, 0xca, 0x44, 0x80, 0x35, 0xea, 0xa6, 0x7f, 0x12, 0xb7, 0xb9, - 0xd7, 0x0a, 0xcf, 0x1b, 0x2c, 0x7f, 0x79, 0x52, 0xd4, 0xfe, 0xe0, 0xdf, - 0x59, 0x3e, 0x75, 0x6d, 0x9e, 0x1c, 0x7f, 0x1f, 0x5c, 0x6f, 0xf3, 0x05, - 0x0a, 0x59, 0x79, 0x65, 0x3d, 0xed, 0x92, 0x06, 0xff, 0x57, 0x56, 0x94, - 0xc5, 0x51, 0x76, 0x6a, 0xbd, 0x95, 0x0b, 0x28, 0xbb, 0x07, 0x7e, 0x1f, - 0xf3, 0x3e, 0xf8, 0x8e, 0x32, 0xb8, 0x1e, 0x27, 0x3d, 0x60, 0x45, 0xf2, - 0x3c, 0xe5, 0x22, 0x6d, 0x4a, 0xcc, 0x51, 0x6d, 0x8f, 0xe2, 0xf2, 0xf8, - 0xbd, 0x96, 0xed, 0x4f, 0x7c, 0x13, 0xd7, 0xf2, 0x8d, 0x09, 0xf0, 0xfd, - 0xe1, 0xc0, 0x71, 0x67, 0x98, 0x57, 0xa0, 0x69, 0xb8, 0xbe, 0xef, 0x1b, - 0x18, 0x26, 0xb4, 0xb4, 0x4c, 0x7a, 0x21, 0x4f, 0x3b, 0xd2, 0x44, 0x5d, - 0x7c, 0xd2, 0xd3, 0x39, 0xee, 0x39, 0xad, 0x97, 0xeb, 0xd7, 0xb1, 0x09, - 0xba, 0x26, 0x61, 0x78, 0xd4, 0x33, 0xfb, 0xe7, 0xb5, 0xfe, 0x46, 0xd0, - 0x1f, 0xed, 0x34, 0xf8, 0xfd, 0x3e, 0xa3, 0x43, 0x94, 0x5f, 0x8e, 0xab, - 0xae, 0xd6, 0x7e, 0x6b, 0x5c, 0xe7, 0x37, 0x2d, 0xd5, 0x1d, 0xb3, 0x63, - 0x93, 0x6e, 0xcd, 0x7e, 0x42, 0x6d, 0x7c, 0x71, 0xd4, 0x2e, 0x01, 0x95, - 0x35, 0xca, 0x44, 0x1f, 0x69, 0x94, 0x73, 0xd7, 0x36, 0xd4, 0xb5, 0xb4, - 0x23, 0x0c, 0x7d, 0xd2, 0x76, 0x72, 0xaf, 0xcd, 0x97, 0x1a, 0x8d, 0xcf, - 0x92, 0x90, 0x2d, 0x0d, 0x3a, 0x2f, 0x01, 0x65, 0x95, 0x48, 0x97, 0xb9, - 0x32, 0xd3, 0xfb, 0x7f, 0xc2, 0xec, 0x41, 0xd6, 0x5d, 0x33, 0x0f, 0x20, - 0x39, 0x2d, 0x1a, 0x4f, 0x5f, 0xab, 0xe1, 0xc9, 0xce, 0x2d, 0xb1, 0x72, - 0x6e, 0x70, 0x6a, 0xfd, 0x7b, 0x20, 0x3b, 0xb9, 0x4e, 0x26, 0xe7, 0xfc, - 0x9c, 0x38, 0x6e, 0xae, 0x7b, 0xad, 0xb9, 0x4d, 0x46, 0x78, 0xe5, 0xdc, - 0x40, 0xab, 0xd1, 0xbc, 0x48, 0xdb, 0x09, 0xbd, 0xef, 0xa4, 0x14, 0x61, - 0xd9, 0xb8, 0x02, 0xb7, 0x11, 0xdd, 0x19, 0x9a, 0xfb, 0xa2, 0xa6, 0xb9, - 0x16, 0x4b, 0x73, 0xa8, 0xeb, 0x71, 0x1f, 0xfd, 0xbe, 0x96, 0x1a, 0xcd, - 0x6d, 0xb0, 0x34, 0xa7, 0x5a, 0xcc, 0x1e, 0x7b, 0xb9, 0xc5, 0xec, 0x71, - 0x25, 0x57, 0x3c, 0xbf, 0x93, 0xcf, 0xf0, 0xc5, 0xa2, 0xe7, 0x7a, 0x58, - 0xcf, 0x03, 0xd6, 0x7a, 0x59, 0xd3, 0x64, 0xe3, 0x78, 0xdc, 0x8f, 0xa7, - 0xdf, 0xe7, 0xca, 0xa3, 0xb0, 0x83, 0x8a, 0x95, 0x1f, 0x84, 0xf3, 0xf0, - 0xfd, 0x26, 0x96, 0x74, 0xef, 0x4c, 0x0b, 0xf9, 0x6d, 0x1a, 0xbf, 0x8e, - 0xd4, 0xf9, 0x3c, 0x98, 0x2f, 0xca, 0xfe, 0x19, 0xeb, 0x01, 0xb9, 0xbc, - 0x54, 0x97, 0x31, 0x10, 0xe3, 0xe3, 0x9c, 0xab, 0xb6, 0xdb, 0xfd, 0x49, - 0xca, 0xf9, 0xbb, 0xe1, 0x13, 0xdd, 0x03, 0x3d, 0x49, 0xfa, 0xee, 0xd8, - 0x60, 0xf2, 0x89, 0x13, 0xd0, 0x63, 0x3f, 0x6f, 0x73, 0xab, 0x6e, 0xbf, - 0x7d, 0xed, 0x5c, 0x62, 0xd0, 0xbe, 0x43, 0x9a, 0x79, 0xdb, 0x06, 0x13, - 0x83, 0xde, 0xba, 0x81, 0x7c, 0xa6, 0x76, 0xed, 0xda, 0xa8, 0xf9, 0xc2, - 0x89, 0x9e, 0xab, 0x2b, 0x9e, 0xa3, 0x76, 0x7f, 0xb3, 0x71, 0x79, 0xbb, - 0xa8, 0xfc, 0xce, 0x4d, 0xcb, 0xcb, 0xff, 0xa3, 0xb7, 0xbc, 0x7d, 0xe3, - 0xe6, 0xe5, 0xcf, 0x7b, 0x57, 0x3c, 0x7f, 0x64, 0xc5, 0xf3, 0xef, 0xad, - 0x78, 0xde, 0xd1, 0xba, 0xfc, 0xf9, 0x43, 0x2b, 0x9e, 0x4f, 0xb5, 0xae, - 0x0d, 0xef, 0x42, 0xeb, 0x72, 0xb8, 0xee, 0xd6, 0xfb, 0x07, 0xd3, 0x55, - 0x57, 0xf6, 0x96, 0xf0, 0xde, 0x79, 0xdf, 0x16, 0xa3, 0xd7, 0xea, 0xdf, - 0x33, 0x5e, 0xb7, 0x7b, 0xcb, 0xf2, 0xfe, 0x6a, 0xed, 0xf6, 0xd5, 0xda, - 0x05, 0xb5, 0x76, 0x46, 0xb6, 0xcd, 0x54, 0xf9, 0x8e, 0xe5, 0x51, 0xbf, - 0xa6, 0xed, 0x44, 0xd9, 0xd7, 0x39, 0xb7, 0xc3, 0x3a, 0xe7, 0x36, 0x05, - 0x3e, 0xbc, 0x5b, 0xc7, 0xa8, 0x36, 0xc3, 0x50, 0x1e, 0xaf, 0x6e, 0xd4, - 0x71, 0x2a, 0xd1, 0x79, 0xb7, 0xc3, 0xb0, 0x6d, 0x99, 0x6b, 0x1b, 0xca, - 0xfe, 0xc0, 0xdc, 0x4d, 0xee, 0xed, 0xb1, 0x70, 0xc0, 0x0b, 0xc3, 0x71, - 0xff, 0x76, 0x9b, 0x7f, 0x86, 0x7b, 0xd5, 0xb4, 0xa1, 0x0e, 0x7e, 0x0c, - 0x3a, 0xb8, 0xa6, 0x7b, 0xef, 0xc6, 0x58, 0xf3, 0xa0, 0x99, 0x3e, 0xf9, - 0x9d, 0x6a, 0xfa, 0xf3, 0xa2, 0xcf, 0x16, 0xf5, 0xc2, 0x86, 0x9b, 0xbf, - 0xf3, 0xbd, 0x7e, 0x00, 0x5b, 0x2f, 0x94, 0x87, 0x83, 0x7e, 0xd0, 0x50, - 0x37, 0xec, 0x3d, 0x5f, 0xfb, 0xa5, 0x8f, 0x6b, 0xda, 0x22, 0x8d, 0x31, - 0xdf, 0x86, 0x76, 0x81, 0x13, 0xcf, 0xf5, 0xfe, 0xb1, 0x89, 0xd3, 0x04, - 0x9d, 0xde, 0x97, 0xc0, 0xb7, 0x43, 0xfe, 0x0e, 0xf8, 0x28, 0xa4, 0x21, - 0xc6, 0xd3, 0xb6, 0xdb, 0x7c, 0xc7, 0x36, 0x99, 0x76, 0x19, 0x77, 0x4c, - 0xf7, 0x8f, 0x08, 0xe7, 0x9d, 0x4e, 0xa6, 0x94, 0xb6, 0xab, 0xc2, 0x03, - 0x01, 0x73, 0x79, 0xb9, 0x67, 0x43, 0x7e, 0x1e, 0xbe, 0x6b, 0xc2, 0x2f, - 0x78, 0x31, 0x9b, 0xff, 0x9b, 0x2b, 0x19, 0xda, 0x1c, 0x23, 0x6d, 0xc2, - 0x9f, 0x5a, 0xe8, 0xfd, 0xbb, 0x90, 0xf6, 0x7d, 0x4a, 0x91, 0xf6, 0xbf, - 0x17, 0xce, 0xba, 0xec, 0x8b, 0x70, 0x0f, 0xdf, 0x95, 0xd3, 0xb8, 0xba, - 0x5b, 0x0e, 0x97, 0x69, 0x0b, 0xc7, 0x75, 0x7e, 0xc8, 0x68, 0x40, 0x3b, - 0x2d, 0x0e, 0x3c, 0x8e, 0x01, 0x7f, 0x2d, 0xb0, 0xb9, 0x6f, 0x44, 0x9d, - 0x98, 0x8c, 0x0c, 0xb7, 0x80, 0xf7, 0xc8, 0x9f, 0xbc, 0xbb, 0xa8, 0xef, - 0xc9, 0x5c, 0x69, 0x44, 0xe7, 0xef, 0x3d, 0x8e, 0xb6, 0x4f, 0xe0, 0x9a, - 0x29, 0x7d, 0x18, 0x6d, 0xde, 0xaf, 0xeb, 0xcf, 0x4c, 0x32, 0x17, 0x5a, - 0x20, 0x97, 0x3e, 0x21, 0xc5, 0xd9, 0x0e, 0x19, 0x49, 0xcc, 0x4f, 0xbb, - 0x4b, 0x71, 0x99, 0x47, 0x37, 0x70, 0xcf, 0xa4, 0x78, 0x35, 0xf7, 0x97, - 0xc5, 0x1d, 0xde, 0xad, 0xba, 0x5b, 0xb5, 0xcf, 0xd5, 0x2f, 0x43, 0xd5, - 0x8c, 0xdc, 0x54, 0x7d, 0x62, 0x8b, 0x89, 0x45, 0x2d, 0x8b, 0x6f, 0x1d, - 0xd3, 0x52, 0xe5, 0x84, 0xcb, 0xf3, 0x59, 0x32, 0x73, 0x56, 0x24, 0x76, - 0x22, 0x8a, 0x4d, 0xb2, 0xcc, 0x93, 0x8e, 0xab, 0x01, 0xd7, 0x59, 0xc8, - 0xd6, 0x44, 0x5c, 0x3e, 0xbb, 0x2b, 0x1a, 0xab, 0x10, 0x4e, 0xed, 0x2a, - 0xc8, 0x9d, 0xb8, 0xf2, 0x57, 0xa7, 0x27, 0x73, 0x8a, 0xe3, 0xfe, 0x75, - 0x48, 0x59, 0xa6, 0x32, 0xbe, 0x14, 0x5a, 0xa3, 0xb1, 0xe1, 0xdf, 0xec, - 0x89, 0xc6, 0xa7, 0xcd, 0x6d, 0xce, 0x56, 0x14, 0xb9, 0x8f, 0x03, 0xfa, - 0x8b, 0x65, 0x3e, 0xb7, 0x81, 0xbe, 0xc3, 0x80, 0xb0, 0x1d, 0x64, 0xba, - 0x62, 0xdf, 0x84, 0x93, 0xf0, 0xd7, 0xc3, 0xb9, 0x90, 0x4a, 0x00, 0x47, - 0x85, 0xd7, 0x85, 0xb7, 0xc7, 0xf3, 0xd5, 0x5a, 0xf0, 0xde, 0x6c, 0x63, - 0x89, 0x8c, 0x0f, 0xae, 0x03, 0xde, 0x5a, 0x50, 0x9e, 0x97, 0x89, 0x93, - 0xb7, 0x6e, 0xe1, 0xde, 0x78, 0x83, 0xef, 0xd8, 0x1c, 0x56, 0x9e, 0x39, - 0x9a, 0x40, 0x1d, 0xbe, 0x1f, 0x41, 0x9b, 0x74, 0x21, 0x17, 0xdb, 0x02, - 0x9f, 0x88, 0xe3, 0x86, 0xb1, 0x8e, 0x3d, 0xcd, 0x3a, 0x27, 0x55, 0xce, - 0x52, 0x9f, 0x47, 0x6d, 0x27, 0x74, 0xce, 0x07, 0xfc, 0xf6, 0xc2, 0x60, - 0x8c, 0xf2, 0xab, 0x5b, 0x06, 0xa8, 0x4f, 0xce, 0x8e, 0x68, 0xda, 0xef, - 0xdc, 0xc5, 0xf3, 0x57, 0x3d, 0xc6, 0x46, 0x4f, 0x10, 0xc6, 0x9b, 0x51, - 0x0e, 0xfb, 0xfd, 0x35, 0x61, 0x28, 0xbc, 0x49, 0x18, 0x0a, 0x6f, 0x12, - 0x06, 0xe2, 0x02, 0x70, 0x54, 0xaf, 0xd8, 0x18, 0xc5, 0xbe, 0xb7, 0x62, - 0x1e, 0x47, 0xca, 0x05, 0x39, 0x5a, 0x76, 0x74, 0xdc, 0x71, 0x5e, 0x51, - 0x26, 0x78, 0xe0, 0x49, 0xf0, 0x5e, 0x19, 0xbc, 0x59, 0x06, 0x2f, 0x96, - 0xc1, 0x97, 0xb0, 0xff, 0xcf, 0x43, 0x3e, 0x3c, 0x81, 0xb5, 0x79, 0x7c, - 0x19, 0x2f, 0x67, 0x35, 0x2f, 0x17, 0xcb, 0xf4, 0xd5, 0x7a, 0x2f, 0xc3, - 0xaf, 0xae, 0x0c, 0x94, 0xd2, 0x50, 0x25, 0x8e, 0x9b, 0xef, 0xfd, 0x28, - 0xf9, 0x55, 0x1e, 0x0c, 0x0e, 0xa2, 0xcd, 0x24, 0x68, 0x3c, 0x4d, 0x3b, - 0x90, 0xf6, 0x4f, 0x01, 0xbc, 0x79, 0x8c, 0xbe, 0x9a, 0xba, 0x7a, 0xb3, - 0x50, 0xbf, 0xb8, 0x7b, 0x98, 0xcb, 0xc8, 0xb9, 0xa6, 0x56, 0xe0, 0xc9, - 0xf0, 0xef, 0x98, 0x4f, 0x3d, 0x43, 0xbe, 0x7d, 0x96, 0x7c, 0x5b, 0xc7, - 0xab, 0x3f, 0xc5, 0xf9, 0x85, 0xde, 0xae, 0xb5, 0xda, 0xd6, 0xea, 0x6f, - 0x5e, 0xaa, 0xaf, 0xc7, 0x9f, 0x24, 0x3f, 0xaa, 0xcc, 0x24, 0x71, 0x9f, - 0xca, 0xc5, 0x76, 0x58, 0xdc, 0xc3, 0x76, 0xdb, 0x73, 0x05, 0x70, 0xdf, - 0x2e, 0x85, 0xb9, 0x50, 0xfc, 0x3d, 0x51, 0x9f, 0xb5, 0x7e, 0x3c, 0xdb, - 0xcf, 0x68, 0xc9, 0x91, 0xc1, 0x5d, 0xdc, 0xd7, 0x70, 0xa0, 0xe7, 0xa3, - 0xf5, 0x80, 0xbd, 0xaf, 0xd7, 0x9c, 0x32, 0x96, 0xb2, 0xb5, 0xc5, 0xc6, - 0x9f, 0xd8, 0xdf, 0xe4, 0x8a, 0x75, 0x7a, 0x31, 0xe4, 0xb9, 0xb6, 0x09, - 0xff, 0x60, 0x1d, 0xad, 0x3c, 0x60, 0x69, 0x45, 0xad, 0x98, 0xc7, 0x5d, - 0x96, 0x56, 0x22, 0x78, 0x13, 0x11, 0xad, 0x34, 0x45, 0xb4, 0x52, 0x98, - 0x8e, 0x68, 0x85, 0x6d, 0xef, 0x8a, 0x68, 0x25, 0x55, 0x4f, 0x2b, 0x85, - 0x69, 0x07, 0xd7, 0x4a, 0x38, 0x48, 0x2f, 0xec, 0x87, 0xf4, 0x02, 0x58, - 0xaa, 0x9f, 0x59, 0xa2, 0x97, 0x04, 0xfa, 0x39, 0x5a, 0x36, 0x39, 0x22, - 0xf0, 0xbb, 0xac, 0x0e, 0xf1, 0xb0, 0xe6, 0xc6, 0x47, 0x5c, 0x9b, 0x46, - 0x02, 0x4b, 0x23, 0xb5, 0x7c, 0xfa, 0x15, 0xb4, 0x01, 0xdc, 0x33, 0x37, - 0x76, 0xb7, 0xa6, 0x8d, 0xfb, 0x83, 0x12, 0xea, 0x0e, 0x83, 0x36, 0x22, - 0x1c, 0xbc, 0xc7, 0xe2, 0x60, 0xe5, 0x5a, 0xde, 0x66, 0x71, 0x30, 0x6c, - 0x71, 0xa0, 0xf9, 0xa5, 0xc0, 0x35, 0x53, 0x1a, 0x07, 0x4d, 0x1a, 0x07, - 0xa2, 0xa2, 0xb6, 0xb7, 0xad, 0x81, 0x03, 0xd6, 0x19, 0xd6, 0xf3, 0x8f, - 0x61, 0xfe, 0xb7, 0x63, 0xfe, 0x4a, 0xcf, 0x9f, 0xeb, 0x60, 0x72, 0xb9, - 0x8b, 0xd5, 0xbf, 0x5e, 0x9a, 0x7f, 0x2b, 0xfa, 0x38, 0x52, 0x8e, 0xe9, - 0xf9, 0xc3, 0xb6, 0xef, 0x8f, 0xe6, 0xff, 0x78, 0xd5, 0xe4, 0x53, 0x3f, - 0xbe, 0x4a, 0xcf, 0x95, 0x2c, 0x6f, 0xf8, 0xda, 0x2f, 0x66, 0x4c, 0xfb, - 0x3c, 0x74, 0xdb, 0x54, 0x90, 0xb2, 0xe7, 0xae, 0x8c, 0xbd, 0xf4, 0x95, - 0x80, 0xbc, 0xf3, 0x21, 0x9d, 0xd7, 0x72, 0x8e, 0x76, 0x53, 0xb9, 0x55, - 0x06, 0xa7, 0xea, 0xe1, 0x26, 0xbc, 0x05, 0x2d, 0x47, 0xf3, 0x98, 0xdf, - 0x68, 0xd0, 0x0d, 0xf9, 0xa6, 0x69, 0x09, 0xe5, 0xe9, 0xc2, 0x40, 0xac, - 0x49, 0xd4, 0x03, 0xef, 0xc7, 0x9c, 0x5d, 0xd9, 0xe2, 0x77, 0x7a, 0x7b, - 0x14, 0x75, 0xe1, 0x95, 0x75, 0xba, 0xb0, 0xcd, 0xea, 0xc2, 0xcd, 0xd4, - 0x85, 0x80, 0xfb, 0x6e, 0x39, 0x56, 0xe6, 0xfa, 0x15, 0x52, 0x4d, 0xd0, - 0xff, 0xdf, 0xf1, 0x79, 0xc6, 0x45, 0xc7, 0xcd, 0x92, 0xc7, 0x34, 0x2d, - 0x53, 0xa7, 0xa5, 0xf5, 0x99, 0x90, 0x05, 0xda, 0xd8, 0x09, 0xc6, 0x42, - 0xa9, 0xf7, 0xfe, 0x3e, 0xfc, 0xcc, 0x1a, 0x7a, 0x6f, 0xbc, 0x6c, 0xec, - 0xb7, 0x06, 0xd8, 0x84, 0x72, 0xaa, 0x0d, 0xd7, 0x26, 0x9e, 0x89, 0xe8, - 0xee, 0x52, 0xcd, 0xd2, 0x70, 0x6a, 0xa3, 0x8c, 0x4d, 0x19, 0x1b, 0x57, - 0x9d, 0x02, 0xfe, 0x4f, 0x31, 0x7f, 0x56, 0x74, 0xbe, 0x7f, 0x7e, 0x12, - 0x76, 0xee, 0xcc, 0xdd, 0xe6, 0x1c, 0xc8, 0x54, 0x83, 0xfe, 0x4d, 0x1b, - 0xa4, 0x18, 0x64, 0xa1, 0xef, 0xe2, 0x32, 0x86, 0x3e, 0x3b, 0x77, 0x35, - 0x62, 0xce, 0x09, 0xb4, 0xa5, 0xcf, 0xc7, 0x38, 0x5a, 0xa3, 0xb8, 0x33, - 0x49, 0x9d, 0xab, 0xcf, 0xf3, 0xae, 0xb9, 0xfe, 0x56, 0xbc, 0x63, 0x7e, - 0x84, 0x87, 0xb1, 0x22, 0xd9, 0x8f, 0x7e, 0x4f, 0x88, 0xdd, 0xef, 0xc9, - 0x68, 0xfd, 0x17, 0x3b, 0xe1, 0xd9, 0xb3, 0x7a, 0xfd, 0x58, 0xf7, 0xb5, - 0xf4, 0xa2, 0x31, 0x72, 0x73, 0x58, 0x3f, 0x75, 0xd6, 0xc5, 0xbd, 0x1d, - 0xf7, 0xa8, 0xbf, 0x48, 0x8f, 0x40, 0x37, 0xbe, 0xfd, 0xd0, 0x26, 0x69, - 0x06, 0xbe, 0x67, 0x14, 0x70, 0x6d, 0x72, 0xbc, 0x0a, 0x9a, 0x17, 0x6a, - 0xf4, 0xf0, 0xc4, 0xeb, 0xf2, 0x03, 0x69, 0x82, 0xb4, 0x40, 0xb9, 0x48, - 0xda, 0xa0, 0x4c, 0x24, 0x6d, 0x1b, 0x7a, 0x78, 0x2c, 0xf0, 0x63, 0xcc, - 0x03, 0x30, 0x71, 0x79, 0xd2, 0x06, 0x69, 0x3e, 0xa5, 0xe3, 0xf5, 0x59, - 0xf9, 0x96, 0x64, 0x5b, 0x3b, 0x61, 0x97, 0xfd, 0xdb, 0xae, 0xb1, 0x39, - 0x2b, 0xac, 0x69, 0x0e, 0xba, 0x89, 0x39, 0x79, 0xdd, 0xf2, 0x9e, 0x6a, - 0x01, 0x78, 0xb8, 0x17, 0x4a, 0xf9, 0x6e, 0x9d, 0xe7, 0xb8, 0xaf, 0xb4, - 0x49, 0x6e, 0x09, 0xe2, 0x36, 0xee, 0x7e, 0x04, 0x74, 0xb0, 0xe0, 0xc8, - 0xa9, 0x0b, 0xb8, 0x2e, 0x3a, 0x5c, 0xbf, 0x4b, 0x41, 0x36, 0xad, 0xc8, - 0xec, 0xbe, 0x9b, 0x5c, 0x90, 0x1e, 0x6f, 0x4c, 0x18, 0xeb, 0x98, 0x77, - 0x9a, 0x4e, 0xfd, 0xfe, 0x26, 0xe3, 0x4b, 0x03, 0x16, 0xbf, 0xd1, 0x1b, - 0xa4, 0x2d, 0x17, 0x84, 0x61, 0x9e, 0x76, 0x83, 0x28, 0xed, 0x23, 0xc1, - 0xe7, 0x43, 0x19, 0xe3, 0x13, 0x3b, 0x9d, 0xc6, 0xb3, 0x2f, 0x58, 0x5a, - 0x91, 0x98, 0xca, 0x3c, 0xed, 0x34, 0x9c, 0x7a, 0x84, 0x6b, 0xa6, 0xf3, - 0xae, 0x0d, 0x5d, 0x3d, 0xeb, 0xd4, 0xe8, 0xea, 0x2b, 0xf6, 0xb7, 0xca, - 0x34, 0x49, 0x36, 0xdd, 0x84, 0xf9, 0x0e, 0x94, 0x22, 0x18, 0xbf, 0x0d, - 0xb8, 0x08, 0x0f, 0xe8, 0x76, 0xe6, 0x7f, 0xe2, 0x5a, 0x04, 0x2c, 0xf7, - 0x01, 0xee, 0x4b, 0x80, 0xf9, 0x45, 0x5c, 0x6a, 0x5b, 0x4c, 0xfe, 0xd4, - 0x89, 0xcd, 0xd4, 0xc3, 0x4b, 0x18, 0xbf, 0x6b, 0xe1, 0x7d, 0x2d, 0x58, - 0x3d, 0x59, 0xe8, 0xeb, 0x00, 0x3c, 0x84, 0xf3, 0x25, 0xc0, 0x48, 0xbb, - 0xf5, 0x39, 0x3c, 0x7b, 0x80, 0xef, 0x79, 0x0b, 0x13, 0xe8, 0x71, 0xea, - 0x2f, 0x6a, 0xbf, 0x4b, 0xb4, 0xa3, 0xff, 0xd2, 0x3e, 0xb7, 0xaf, 0x90, - 0x01, 0x5d, 0x0e, 0xf1, 0x3c, 0x51, 0x5e, 0xa4, 0x1d, 0x00, 0xbe, 0xff, - 0xae, 0xc4, 0xce, 0x26, 0xe5, 0x68, 0x89, 0x7b, 0x40, 0xa7, 0x81, 0x0f, - 0x7d, 0xc6, 0x05, 0x75, 0xae, 0xc2, 0x05, 0x65, 0x3f, 0xb3, 0x1b, 0x57, - 0x37, 0xae, 0xb7, 0xe2, 0x02, 0x39, 0xcc, 0x9c, 0xc2, 0xd5, 0x83, 0xbe, - 0x55, 0xa2, 0x49, 0x98, 0x9b, 0xf5, 0x0d, 0xb4, 0xd1, 0xb6, 0x65, 0x41, - 0x65, 0xfa, 0x80, 0xbf, 0x3e, 0xc0, 0x96, 0xc4, 0xc5, 0x7c, 0xe6, 0xef, - 0x3a, 0x72, 0xf6, 0x65, 0x5c, 0x60, 0xb0, 0xb3, 0x20, 0xcc, 0xb3, 0xfd, - 0xb8, 0xa0, 0xc4, 0xce, 0x66, 0x71, 0x0d, 0xe2, 0xfa, 0x2b, 0xc7, 0xf0, - 0x5c, 0x3b, 0xf0, 0x15, 0xf1, 0x08, 0x70, 0xbe, 0x8c, 0xe7, 0xbe, 0xec, - 0xbc, 0x71, 0x9e, 0xfb, 0xbe, 0x63, 0x78, 0xee, 0x15, 0xa7, 0xc6, 0x73, - 0x17, 0x1c, 0xf5, 0xf0, 0xd3, 0x4e, 0xec, 0x61, 0xfa, 0x12, 0x17, 0x1c, - 0xc3, 0xff, 0x31, 0x19, 0x38, 0x08, 0x5a, 0x7a, 0x78, 0x1e, 0x17, 0xe9, - 0xea, 0x19, 0x94, 0x3f, 0xbf, 0x62, 0xdc, 0xe7, 0xde, 0xc4, 0xb8, 0xaf, - 0xda, 0x71, 0x45, 0xd5, 0xc6, 0x7d, 0x11, 0x7d, 0xbf, 0x64, 0xc7, 0x7d, - 0xb1, 0x6e, 0x5c, 0xd0, 0xca, 0xc3, 0x8b, 0xb8, 0x48, 0x17, 0x2f, 0xa0, - 0x3c, 0x92, 0x09, 0x1f, 0xf4, 0xa4, 0xb9, 0x01, 0xbc, 0x1b, 0x87, 0x7e, - 0x6c, 0x58, 0xd2, 0x8d, 0xd9, 0x3a, 0xfd, 0xf0, 0x46, 0xf4, 0xe3, 0x78, - 0x99, 0x36, 0xe2, 0x7c, 0x9d, 0x5c, 0xa0, 0x6f, 0x14, 0xca, 0x49, 0xed, - 0x07, 0xd1, 0x27, 0xa2, 0x7f, 0xb4, 0xd2, 0xb6, 0xfa, 0xa8, 0xce, 0x45, - 0xfb, 0x95, 0x52, 0xbb, 0xdc, 0x59, 0xa2, 0x4d, 0x48, 0x7a, 0x09, 0xc3, - 0xb1, 0x3d, 0xb4, 0x4f, 0x0b, 0xe1, 0x15, 0x3e, 0xe9, 0xc4, 0xf7, 0x7e, - 0x79, 0xb5, 0xce, 0x98, 0x1c, 0x80, 0xef, 0x9e, 0x3b, 0xf1, 0x8b, 0xd0, - 0x19, 0x0d, 0x80, 0x9b, 0xf4, 0xb6, 0x4d, 0x0e, 0x4c, 0xaa, 0x89, 0x2d, - 0x90, 0x25, 0x37, 0x95, 0x1a, 0x61, 0xf7, 0x30, 0x4f, 0xab, 0x59, 0x3a, - 0xf7, 0xc4, 0x4d, 0x1e, 0xb9, 0x97, 0xc0, 0x6f, 0xcf, 0xe4, 0xb5, 0x27, - 0x92, 0x78, 0xff, 0x0f, 0x1e, 0xe5, 0x60, 0xc2, 0xbf, 0x4e, 0xe7, 0x08, - 0x75, 0xec, 0xa1, 0xdd, 0x72, 0x83, 0xd6, 0xe1, 0xee, 0x2a, 0x3b, 0x49, - 0x6d, 0xf3, 0xa4, 0x66, 0xa3, 0x8d, 0x96, 0xd2, 0x29, 0xc2, 0xf5, 0x90, - 0x70, 0xff, 0xeb, 0x1e, 0x29, 0x06, 0x1b, 0xe1, 0x17, 0x30, 0x76, 0x9e, - 0xee, 0xa6, 0x6d, 0x34, 0x33, 0xe5, 0xd9, 0x3c, 0xeb, 0x4d, 0xf2, 0xac, - 0x1e, 0xa7, 0x51, 0xc3, 0x68, 0xce, 0x5e, 0x70, 0x1f, 0x21, 0xae, 0xcf, - 0xfb, 0xcc, 0x54, 0x5a, 0xb4, 0xde, 0x99, 0xa9, 0x30, 0xaf, 0x1f, 0xfe, - 0x54, 0x85, 0x79, 0xfc, 0x81, 0x78, 0x6f, 0x87, 0x9f, 0x5b, 0xd9, 0x21, - 0xa3, 0x53, 0xeb, 0xa4, 0xd1, 0x57, 0x89, 0x2d, 0xd0, 0x1f, 0x6c, 0xd3, - 0xb1, 0x07, 0xfe, 0xe1, 0xf4, 0x4e, 0x79, 0x62, 0x9a, 0x7d, 0x6f, 0x93, - 0xd9, 0x39, 0x71, 0xbc, 0xb7, 0xaf, 0x47, 0x1d, 0xc8, 0xf5, 0x3d, 0x2c, - 0x4b, 0xe1, 0x2e, 0xca, 0x7b, 0xbb, 0x2b, 0x17, 0xfb, 0xf8, 0xcc, 0xb3, - 0x04, 0xe2, 0xb2, 0xbf, 0x8b, 0x7d, 0xed, 0x72, 0x6e, 0x0e, 0x34, 0x01, - 0xb9, 0x3f, 0x78, 0x8a, 0x30, 0x89, 0xec, 0x9d, 0x61, 0x2c, 0xbd, 0xd3, - 0x63, 0xdc, 0x94, 0xfb, 0x34, 0xb7, 0xf4, 0x71, 0x2c, 0xe8, 0x25, 0xe8, - 0xb8, 0x8e, 0x3d, 0x46, 0x16, 0x64, 0x67, 0x1a, 0x50, 0xce, 0x7e, 0xe1, - 0x3f, 0x1e, 0x64, 0x3f, 0x51, 0x5b, 0x85, 0x39, 0x35, 0x6a, 0x7a, 0x59, - 0x5c, 0xa1, 0x3f, 0xce, 0xff, 0x48, 0xf6, 0x37, 0xfb, 0xe8, 0xd6, 0x7b, - 0x21, 0xdc, 0x53, 0x36, 0xb6, 0x15, 0xd7, 0x44, 0xef, 0x29, 0xc0, 0xae, - 0xba, 0x4a, 0xdb, 0x17, 0xb3, 0x55, 0xae, 0x20, 0x63, 0x51, 0xd1, 0x1a, - 0x25, 0xe5, 0xd1, 0xf2, 0xd2, 0x3a, 0xed, 0x68, 0x58, 0xbe, 0x4e, 0xa4, - 0x95, 0x60, 0xc4, 0xda, 0x1e, 0x0b, 0x72, 0x0c, 0x76, 0x59, 0xb7, 0x5e, - 0xb3, 0x05, 0xd8, 0xb2, 0x76, 0xcd, 0xb4, 0x3d, 0x5b, 0x8c, 0xd6, 0x6c, - 0x18, 0x1a, 0xa7, 0x92, 0xd9, 0xcc, 0x35, 0xf3, 0x18, 0xef, 0x06, 0xde, - 0x0b, 0x58, 0xa7, 0x02, 0xd6, 0xa8, 0x50, 0xd9, 0x26, 0x33, 0x27, 0x55, - 0x7b, 0x83, 0x48, 0x6a, 0xd4, 0xdf, 0x26, 0xe3, 0x73, 0x8c, 0x25, 0xec, - 0x80, 0x0d, 0xb6, 0x13, 0x57, 0x3b, 0x9e, 0xd9, 0x2e, 0x21, 0xc5, 0x8a, - 0x42, 0xdb, 0xa6, 0x55, 0x76, 0xd6, 0x39, 0x8c, 0xcd, 0x33, 0x9d, 0x8f, - 0x01, 0x0f, 0x35, 0xde, 0x29, 0xd5, 0xc5, 0x9f, 0x38, 0x57, 0xad, 0x43, - 0x31, 0xdf, 0x84, 0x5e, 0x4f, 0x1d, 0x87, 0x2a, 0x37, 0xbe, 0x19, 0x7b, - 0x2a, 0x49, 0x7b, 0x2a, 0x3f, 0xe9, 0x99, 0xf3, 0x06, 0xc3, 0xf0, 0x9d, - 0xfc, 0xfc, 0x66, 0xd2, 0xfa, 0xc8, 0x34, 0xe1, 0x8a, 0x47, 0x70, 0x2d, - 0x5b, 0x33, 0x9e, 0x0f, 0x5b, 0x1d, 0xe7, 0x28, 0x2d, 0xe5, 0x43, 0x9a, - 0xd8, 0x3e, 0xe3, 0x28, 0xed, 0x6b, 0xc0, 0x74, 0xb7, 0xb6, 0x61, 0x45, - 0xdd, 0x26, 0x87, 0xcb, 0x3c, 0x5b, 0xc6, 0x78, 0xe2, 0x27, 0x19, 0x5f, - 0xea, 0x9e, 0x91, 0x63, 0x18, 0x9b, 0xb9, 0x3f, 0xca, 0xc6, 0x6f, 0x36, - 0xd8, 0x1c, 0x91, 0xfa, 0x18, 0x8e, 0xc9, 0x0d, 0x5a, 0x9e, 0x67, 0x9d, - 0x1e, 0x5e, 0xc4, 0x3a, 0xff, 0x9a, 0xde, 0x1b, 0x94, 0xc9, 0x18, 0xb4, - 0xdf, 0x68, 0x5f, 0xba, 0xdf, 0x9c, 0xab, 0x49, 0xc9, 0x50, 0xd9, 0xcc, - 0xff, 0x92, 0xce, 0x11, 0x32, 0xb9, 0x90, 0x26, 0x7f, 0xe8, 0x1e, 0xb9, - 0x04, 0x1d, 0x5e, 0x5b, 0xdb, 0x26, 0x19, 0x07, 0x2e, 0xf2, 0x7a, 0x5f, - 0x22, 0x25, 0xf9, 0xbe, 0x47, 0x37, 0xf3, 0xdc, 0x45, 0x1c, 0xeb, 0x53, - 0x9c, 0xe6, 0x59, 0x4c, 0xf6, 0x7b, 0xb9, 0xbe, 0x28, 0x66, 0x99, 0xd7, - 0x0f, 0x59, 0xf9, 0x63, 0x3d, 0xc9, 0x66, 0xfd, 0x7e, 0x9d, 0xcd, 0xdf, - 0x76, 0x44, 0x0e, 0x84, 0xf2, 0x87, 0xd0, 0x93, 0x67, 0xec, 0x9c, 0x52, - 0x3a, 0x66, 0x25, 0xe1, 0xc5, 0x20, 0x69, 0x63, 0x96, 0x9c, 0xcb, 0x41, - 0x4b, 0xdf, 0xc6, 0xfe, 0xa9, 0xd9, 0xd0, 0x66, 0xdf, 0xef, 0x09, 0x2d, - 0x0b, 0x7b, 0xad, 0xed, 0xac, 0xe3, 0x3c, 0x8f, 0x88, 0xce, 0x09, 0x88, - 0x7c, 0xa3, 0xae, 0x3a, 0xbf, 0xc0, 0xf8, 0x72, 0xc5, 0xa9, 0xb5, 0x64, - 0x54, 0xcd, 0x27, 0xa4, 0x2f, 0x37, 0xb6, 0x8b, 0xdf, 0x47, 0x88, 0x7c, - 0xb9, 0x5e, 0xeb, 0xcb, 0x6d, 0xd4, 0xbe, 0x9c, 0x89, 0x3d, 0x6c, 0x5c, - 0xf2, 0xe5, 0x8a, 0x53, 0x05, 0xd0, 0x4a, 0xf4, 0x3d, 0x07, 0x63, 0x0b, - 0x8d, 0x97, 0x78, 0x86, 0xa6, 0x51, 0xf2, 0xc3, 0x0a, 0x7e, 0x83, 0xf1, - 0xb1, 0x18, 0xab, 0x50, 0xea, 0xeb, 0xd6, 0xbf, 0x68, 0x97, 0x6c, 0xdb, - 0x3a, 0xcc, 0xfb, 0x6e, 0xbd, 0xe6, 0xb3, 0x25, 0xb3, 0xf7, 0x99, 0x3f, - 0xc8, 0x98, 0x10, 0xcf, 0x49, 0x69, 0xfe, 0x4a, 0x0d, 0xc4, 0xba, 0x8d, - 0x3d, 0xeb, 0x7b, 0xad, 0xd2, 0x7c, 0x1a, 0x38, 0x8f, 0xdb, 0x71, 0x53, - 0x80, 0xe9, 0x30, 0xd6, 0xe6, 0x3a, 0x2b, 0x93, 0x39, 0xf6, 0x47, 0x9b, - 0x18, 0x1b, 0x98, 0x2b, 0x45, 0x31, 0xc2, 0x98, 0x3d, 0xa3, 0xe9, 0xc7, - 0x1a, 0xfd, 0x75, 0x6b, 0xda, 0xaa, 0x8f, 0xbf, 0xae, 0x6e, 0x22, 0x2d, - 0xdd, 0xad, 0xf3, 0x5c, 0xd6, 0xf7, 0xa5, 0xf7, 0xeb, 0x9c, 0x7b, 0x1d, - 0x63, 0x2c, 0x08, 0x73, 0xd4, 0xbe, 0x29, 0x3f, 0xa1, 0x65, 0xfe, 0xe1, - 0x80, 0xfa, 0x6b, 0x8f, 0xfe, 0xdd, 0x98, 0x09, 0xc3, 0x8b, 0x7d, 0x13, - 0x8c, 0x29, 0x7a, 0xdf, 0x96, 0xce, 0xe4, 0x80, 0xb6, 0x9d, 0xb0, 0x46, - 0x07, 0x9b, 0x65, 0x9d, 0x3f, 0x62, 0x73, 0x66, 0x0a, 0x90, 0x9b, 0x69, - 0xd8, 0x4c, 0x3c, 0x7f, 0xdc, 0x65, 0xdf, 0x15, 0xc2, 0x66, 0xd0, 0xd1, - 0x07, 0xc5, 0xc8, 0x98, 0x7c, 0x4d, 0xc6, 0x30, 0xd7, 0x20, 0x4b, 0x42, - 0x76, 0x8f, 0x4b, 0x9a, 0xdf, 0x2a, 0xe1, 0xd8, 0x45, 0xd9, 0x0a, 0xbd, - 0xcc, 0x76, 0xb4, 0x55, 0xf9, 0xcc, 0x3d, 0x1c, 0xdf, 0x3b, 0x02, 0xdd, - 0x72, 0xc3, 0x6a, 0xdd, 0x92, 0xa4, 0x5f, 0x9f, 0x9f, 0xa4, 0x6f, 0xb8, - 0x1e, 0x6d, 0xb6, 0xc9, 0x87, 0xa6, 0x7e, 0xbe, 0x95, 0xbc, 0x35, 0x02, - 0xb9, 0xae, 0xee, 0x8f, 0xce, 0x16, 0xb1, 0x8c, 0xef, 0xd9, 0x6f, 0x93, - 0xa4, 0xde, 0xeb, 0xc9, 0x6f, 0x54, 0xd3, 0xa9, 0x45, 0xe8, 0xa6, 0x11, - 0xe7, 0x57, 0xb7, 0x9b, 0x98, 0xea, 0x07, 0x5a, 0xcd, 0x59, 0x84, 0x66, - 0xe0, 0x34, 0x8a, 0xb3, 0xd6, 0xd3, 0xec, 0xa2, 0x95, 0xc7, 0x61, 0xd8, - 0xdc, 0xa7, 0x65, 0xf0, 0x7e, 0xca, 0xe0, 0xc3, 0x41, 0x97, 0xa1, 0x7d, - 0xed, 0x33, 0x85, 0x58, 0x47, 0xe0, 0xa1, 0xcf, 0x65, 0xbe, 0x9f, 0xe5, - 0x4f, 0x3f, 0xbb, 0x60, 0xe5, 0x92, 0x72, 0x56, 0xf3, 0xa5, 0xba, 0x26, - 0xbe, 0x4c, 0xe6, 0x1e, 0x9d, 0xa2, 0x3e, 0x0e, 0xe6, 0xbf, 0x09, 0x39, - 0x95, 0xd7, 0x78, 0xd8, 0x26, 0xf7, 0x4d, 0x49, 0xf6, 0x12, 0x74, 0x55, - 0x71, 0x6e, 0x39, 0x6f, 0xae, 0xee, 0x8f, 0x73, 0x7d, 0xa4, 0xd5, 0xf8, - 0xb6, 0xcb, 0xe7, 0x3a, 0x8f, 0xb9, 0x66, 0xf5, 0x5c, 0xb9, 0x6f, 0x33, - 0x67, 0xe7, 0xba, 0x3e, 0x9a, 0x6b, 0xff, 0xf2, 0xb9, 0x46, 0xbe, 0x7d, - 0x24, 0x77, 0x53, 0x3a, 0xff, 0x5e, 0xe7, 0x7d, 0x4f, 0xad, 0x97, 0x81, - 0xc9, 0x8d, 0x56, 0x5e, 0x7a, 0xd0, 0x3d, 0xcc, 0x89, 0x9f, 0xbf, 0xd7, - 0x13, 0x8b, 0x33, 0x45, 0x3c, 0x50, 0xd6, 0xb6, 0xea, 0x33, 0x3b, 0x33, - 0xf0, 0xaf, 0x6e, 0x2d, 0xb1, 0x6e, 0xf4, 0xfe, 0x72, 0xb1, 0xe3, 0xc8, - 0xa7, 0xa6, 0xdf, 0xd4, 0xbd, 0x2a, 0xa6, 0x60, 0xe2, 0xc3, 0x8c, 0x0b, - 0x9b, 0xb3, 0xc4, 0xcc, 0x45, 0xbc, 0x03, 0x3c, 0xf5, 0xf1, 0x52, 0xba, - 0x3f, 0x17, 0xa3, 0x1c, 0x9d, 0x96, 0xa3, 0xd5, 0x41, 0xe9, 0xd0, 0xe7, - 0x49, 0x5f, 0x37, 0x76, 0x9c, 0xad, 0x8f, 0x1d, 0x33, 0x9d, 0x80, 0xb1, - 0xe3, 0xfd, 0x3f, 0x42, 0xec, 0x58, 0x1c, 0x13, 0x3b, 0x5e, 0xcb, 0xbf, - 0x9a, 0x28, 0x4f, 0x63, 0x5e, 0xcd, 0x90, 0x25, 0x0b, 0x4e, 0x7e, 0xae, - 0x05, 0xf7, 0x0b, 0xb8, 0xc7, 0x71, 0xbf, 0x84, 0xbb, 0x87, 0xfb, 0x8b, - 0xb8, 0x27, 0x64, 0x62, 0x49, 0x67, 0x4c, 0x43, 0x6e, 0x50, 0x97, 0xb1, - 0xad, 0xf1, 0x07, 0x66, 0x2b, 0x6d, 0xfc, 0x2e, 0x8c, 0x33, 0x33, 0xc7, - 0x39, 0x6c, 0x94, 0xf1, 0x29, 0xca, 0xec, 0x56, 0x99, 0x9c, 0x8a, 0x6c, - 0xdb, 0xbb, 0xb6, 0x71, 0xcf, 0x60, 0x44, 0x22, 0xdb, 0xf5, 0x77, 0xb7, - 0xd9, 0x5c, 0xfb, 0x2d, 0xd2, 0xbc, 0x09, 0x6b, 0x70, 0x5a, 0x2e, 0x4d, - 0x6f, 0x5a, 0x66, 0xc3, 0xa6, 0x6c, 0x4c, 0x70, 0xda, 0xea, 0xde, 0xb5, - 0x65, 0x44, 0xfd, 0xfa, 0x27, 0x6d, 0x4e, 0x69, 0x94, 0x23, 0x94, 0xd2, - 0xeb, 0x33, 0x5c, 0x9d, 0xc6, 0x78, 0xfd, 0x92, 0x9d, 0xe6, 0x3c, 0x97, - 0xbe, 0x4d, 0x01, 0x79, 0x78, 0x0a, 0x7a, 0x75, 0x19, 0x5d, 0x82, 0x6e, - 0x39, 0x37, 0x07, 0xb4, 0xfb, 0xa8, 0xcc, 0x4c, 0x12, 0xbe, 0xae, 0x64, - 0x4c, 0x9f, 0x5d, 0xc3, 0xf3, 0xb4, 0xc9, 0x99, 0x1f, 0xa8, 0x46, 0xe7, - 0xd6, 0x36, 0xeb, 0xef, 0x11, 0x2c, 0x3f, 0xbb, 0x66, 0xf5, 0xb3, 0xb6, - 0x1d, 0x78, 0x86, 0x2d, 0x9a, 0xc3, 0x5a, 0xf4, 0x14, 0xca, 0xb8, 0xce, - 0x3b, 0xdb, 0x22, 0x67, 0x1e, 0x5c, 0xca, 0xa1, 0x6d, 0x85, 0x8d, 0xd2, - 0x0e, 0x13, 0x79, 0xd8, 0xcd, 0x74, 0xc1, 0xc7, 0x63, 0x9e, 0x4c, 0x57, - 0xf2, 0x36, 0x9d, 0xdb, 0x5c, 0x3b, 0x47, 0x58, 0xcb, 0x6f, 0x8e, 0xce, - 0x6d, 0x25, 0x65, 0x10, 0x74, 0x38, 0xa4, 0xcb, 0x13, 0x98, 0x0f, 0xf7, - 0xfd, 0x34, 0x1e, 0x20, 0x7b, 0xb8, 0xe7, 0x87, 0xb9, 0x57, 0xbf, 0x01, - 0x7a, 0x77, 0xec, 0x19, 0x36, 0xd2, 0x58, 0x9f, 0x8c, 0x55, 0x92, 0xce, - 0x58, 0xa5, 0xcf, 0x39, 0x54, 0xb1, 0xef, 0xfa, 0x8a, 0x58, 0x0f, 0xfc, - 0x9e, 0xee, 0x70, 0x46, 0x80, 0xaf, 0x62, 0xb9, 0xd3, 0xc9, 0xea, 0xbb, - 0x6f, 0xef, 0x90, 0x03, 0x58, 0xab, 0x81, 0xe9, 0xa4, 0x96, 0xf3, 0xb5, - 0xef, 0x61, 0x45, 0xeb, 0xfa, 0xa4, 0xde, 0x1b, 0x9a, 0x97, 0x69, 0xfd, - 0x7d, 0x25, 0x63, 0x3b, 0x9c, 0x46, 0x7f, 0xd3, 0x36, 0x26, 0xde, 0xe3, - 0xe4, 0x75, 0x3f, 0x66, 0x3d, 0x8a, 0xe5, 0x53, 0xb8, 0xaf, 0x3c, 0x43, - 0x1d, 0xe9, 0x19, 0xc2, 0xfd, 0x08, 0xf4, 0x59, 0x78, 0x8f, 0x91, 0x57, - 0xd3, 0x32, 0x51, 0x65, 0xfe, 0x08, 0xfb, 0x41, 0x79, 0xe5, 0x30, 0x74, - 0xd2, 0xf2, 0x33, 0x84, 0x43, 0xb5, 0x75, 0x48, 0x4d, 0x0b, 0x61, 0xe1, - 0x1a, 0x2c, 0x3f, 0x5f, 0x7f, 0xf9, 0x7f, 0xd1, 0xbe, 0xa2, 0x91, 0xa1, - 0x16, 0x8e, 0x2c, 0xe5, 0x9d, 0x91, 0x2b, 0x9f, 0x96, 0x23, 0xc0, 0xe3, - 0x31, 0xc0, 0xa4, 0xee, 0xe7, 0xf7, 0x5e, 0x2a, 0x52, 0x9c, 0xbd, 0x4f, - 0xd4, 0x43, 0x97, 0x1c, 0xf7, 0xa1, 0x23, 0x12, 0x7b, 0x68, 0xc1, 0x69, - 0x78, 0xa8, 0x53, 0xfb, 0xe5, 0xfb, 0x82, 0xce, 0xe4, 0x21, 0x39, 0x2d, - 0xee, 0xfd, 0x4a, 0x9f, 0x27, 0x2b, 0x7a, 0x8c, 0xf1, 0x9d, 0x96, 0xd8, - 0xfd, 0x71, 0x7b, 0x16, 0xd5, 0xc4, 0xf5, 0x16, 0x35, 0xdf, 0x3f, 0x97, - 0x20, 0xce, 0x16, 0x65, 0x5a, 0xf3, 0xce, 0x00, 0xf4, 0x44, 0x6e, 0x32, - 0xb5, 0x54, 0xc7, 0xe4, 0x7b, 0x6e, 0x4c, 0x18, 0x7e, 0x61, 0x9d, 0x2e, - 0x87, 0xdf, 0x85, 0xb0, 0x3a, 0xff, 0xca, 0x28, 0xf7, 0xd3, 0xac, 0x29, - 0xdf, 0xff, 0x10, 0x6b, 0xd8, 0x85, 0xf5, 0xe2, 0x78, 0x8e, 0xde, 0xcf, - 0xe5, 0x59, 0x5c, 0x4f, 0x7a, 0x92, 0x4d, 0x4b, 0x76, 0x10, 0xeb, 0xde, - 0x27, 0x4d, 0x80, 0x5b, 0x3d, 0x54, 0x34, 0x76, 0x9d, 0x90, 0x4e, 0x05, - 0x92, 0x9b, 0x34, 0xdb, 0xd5, 0xbf, 0x4f, 0xaf, 0xe1, 0xbd, 0x96, 0x66, - 0xd6, 0x19, 0xfb, 0x11, 0xcf, 0x86, 0x2e, 0x8a, 0xb2, 0x77, 0xea, 0xbb, - 0xd0, 0xf3, 0xdc, 0x77, 0xd1, 0xf6, 0xe2, 0x1a, 0xb6, 0x20, 0x79, 0xe9, - 0x69, 0xeb, 0x57, 0x86, 0xe1, 0x54, 0x10, 0x00, 0x8f, 0x6b, 0xf9, 0x92, - 0x3b, 0x9c, 0xd9, 0xc9, 0x9d, 0xce, 0xcc, 0x64, 0x28, 0x63, 0x01, 0xbf, - 0x19, 0xc2, 0x1c, 0x00, 0xda, 0x5b, 0x2c, 0xeb, 0x84, 0x6e, 0xdd, 0x9d, - 0xe0, 0xf9, 0xa6, 0x9b, 0xfc, 0x17, 0xc4, 0xd4, 0x23, 0x8e, 0xe9, 0x23, - 0x77, 0x3e, 0x92, 0x17, 0x7e, 0x9f, 0xa3, 0x27, 0x99, 0xd0, 0xdf, 0x10, - 0xf9, 0x0c, 0xda, 0x61, 0x8c, 0x32, 0xc7, 0x7d, 0xc6, 0x99, 0x81, 0x3c, - 0x9b, 0x9d, 0xe2, 0x37, 0x01, 0x98, 0x4f, 0x1b, 0x6b, 0x57, 0x72, 0x95, - 0x37, 0x6e, 0xbf, 0x5b, 0x57, 0x80, 0x0b, 0x14, 0xd3, 0x65, 0x3d, 0xde, - 0xe8, 0xd2, 0xb7, 0xec, 0xa2, 0xb2, 0xe8, 0x9b, 0x76, 0x4a, 0xe7, 0x4e, - 0xc3, 0x97, 0x3d, 0x33, 0x22, 0xdf, 0x77, 0xe6, 0x4a, 0xaf, 0x38, 0x8f, - 0x96, 0xb2, 0xd7, 0x5c, 0x01, 0xfa, 0xb8, 0x18, 0xe4, 0x29, 0xbf, 0x60, - 0xf3, 0x4d, 0x49, 0xa1, 0x3a, 0x26, 0xd3, 0xdb, 0x3a, 0xbd, 0xfb, 0xf5, - 0xda, 0x9c, 0x01, 0xce, 0xbe, 0x81, 0xf5, 0x3b, 0x93, 0xa0, 0x7e, 0x1b, - 0x2d, 0x29, 0xf0, 0xb2, 0xfa, 0x69, 0x5c, 0xb0, 0x6d, 0x1b, 0xb5, 0x8d, - 0x72, 0x28, 0x60, 0xbd, 0x9d, 0xce, 0xc0, 0xe4, 0x0e, 0xac, 0xe3, 0x41, - 0xe8, 0x4f, 0x07, 0x76, 0x1a, 0x68, 0x1b, 0x65, 0xe3, 0xc0, 0xc1, 0x68, - 0x60, 0xe4, 0xf9, 0x80, 0x14, 0xb4, 0x8f, 0x67, 0xee, 0x59, 0x65, 0x62, - 0x66, 0x61, 0x38, 0x0b, 0xfb, 0x80, 0xdf, 0xc5, 0x9a, 0xa8, 0xce, 0xe1, - 0xfa, 0x71, 0xbb, 0xa7, 0x3d, 0x7f, 0x99, 0x3d, 0x6d, 0x4f, 0x4e, 0x57, - 0xf5, 0x39, 0x79, 0x9d, 0x5f, 0x95, 0x52, 0xeb, 0xda, 0xf4, 0x5a, 0xa9, - 0x2e, 0x9d, 0x93, 0x96, 0x95, 0x47, 0x12, 0x46, 0x0f, 0x13, 0xa6, 0x14, - 0xe0, 0xd9, 0x09, 0x5c, 0x10, 0x1e, 0xd3, 0x46, 0xd4, 0x3b, 0xb7, 0x52, - 0x1f, 0x2e, 0xca, 0xa7, 0x12, 0xd1, 0x19, 0x05, 0xf4, 0x03, 0x19, 0x37, - 0xb7, 0xd5, 0xe8, 0xc9, 0x2d, 0x6b, 0xf4, 0x13, 0xcd, 0xcd, 0xb1, 0x73, - 0x23, 0xdd, 0x6e, 0xbe, 0x92, 0x3e, 0xc5, 0xa2, 0x34, 0xad, 0xa8, 0xcf, - 0x98, 0xfe, 0xbe, 0xed, 0xe6, 0xcc, 0x03, 0xeb, 0x7a, 0xb0, 0x4d, 0x69, - 0xe7, 0x12, 0x8f, 0x7a, 0xdd, 0x4a, 0x4a, 0x78, 0x6e, 0xe1, 0x0c, 0x64, - 0xcb, 0x55, 0xde, 0x4f, 0x28, 0xd2, 0x61, 0x84, 0xeb, 0x6f, 0x68, 0x3e, - 0x19, 0x2d, 0x31, 0xb6, 0xf2, 0x68, 0x98, 0x1d, 0x26, 0x8f, 0xb1, 0x0f, - 0xbe, 0x9f, 0xd2, 0xf1, 0xdc, 0x83, 0x01, 0x63, 0x45, 0x9d, 0x8f, 0xdc, - 0xa1, 0x22, 0x39, 0x05, 0xfd, 0x5b, 0x5e, 0x70, 0xf8, 0xdd, 0xbe, 0x03, - 0x82, 0xfb, 0xdc, 0x82, 0xf3, 0xcd, 0xa9, 0x67, 0xf0, 0xdc, 0x60, 0xbf, - 0xd5, 0x67, 0xf4, 0x94, 0xc8, 0x1f, 0x46, 0xf3, 0x4d, 0x16, 0xb0, 0xf6, - 0x2f, 0x62, 0xed, 0xd7, 0xfe, 0x36, 0x1f, 0xde, 0x55, 0xf0, 0xae, 0xf2, - 0x0b, 0x61, 0xb6, 0x95, 0xb4, 0x18, 0xe8, 0xb3, 0xa9, 0x97, 0xf7, 0x9b, - 0xfb, 0x35, 0x5f, 0x8c, 0x97, 0xcf, 0x81, 0x2f, 0xb2, 0xdc, 0x6f, 0x0e, - 0x1f, 0x0e, 0x6e, 0x04, 0x5f, 0xec, 0x97, 0xdf, 0x83, 0x5d, 0xf0, 0x3b, - 0xd5, 0x0c, 0xf8, 0xa3, 0x1f, 0xfc, 0xd2, 0x07, 0x1e, 0x09, 0xb4, 0x8d, - 0xfc, 0x18, 0xf4, 0x1f, 0xf4, 0x9a, 0x73, 0x68, 0xb2, 0xc3, 0xc9, 0x4f, - 0xfa, 0xce, 0xd8, 0x24, 0xbf, 0xff, 0xa2, 0xde, 0xda, 0x20, 0x6e, 0x72, - 0x56, 0xc8, 0x0b, 0x9d, 0xcc, 0x71, 0x6c, 0x03, 0xae, 0xce, 0x12, 0x57, - 0xb3, 0xd5, 0x1e, 0xef, 0x0a, 0xf0, 0x44, 0x9b, 0xe6, 0x89, 0x8d, 0x4e, - 0xd6, 0xbb, 0xd1, 0xf2, 0xc4, 0x0b, 0xe0, 0x89, 0x4b, 0xab, 0x78, 0xe2, - 0x29, 0x4b, 0xff, 0xf3, 0x75, 0x3c, 0x31, 0x6b, 0xcb, 0xa6, 0x2f, 0xc3, - 0x13, 0x5b, 0xfd, 0xf4, 0xe7, 0x47, 0xe4, 0x55, 0xf0, 0x84, 0x28, 0xf2, - 0xc4, 0x56, 0xcd, 0x13, 0x8c, 0x1d, 0x91, 0x2f, 0xda, 0x21, 0x47, 0xc8, - 0x17, 0x17, 0x64, 0x11, 0x7c, 0xf1, 0x9c, 0xe2, 0xd8, 0x67, 0x68, 0x2b, - 0x4c, 0xd2, 0x27, 0x3b, 0x55, 0xee, 0x00, 0xbf, 0x2b, 0xf9, 0xaf, 0x53, - 0x61, 0xb8, 0x00, 0x3f, 0xfd, 0x41, 0xd8, 0xf3, 0xae, 0xfe, 0x0e, 0xe4, - 0x3c, 0xe8, 0x3e, 0xa2, 0xf7, 0x31, 0x07, 0xf4, 0x7e, 0x6c, 0x06, 0x73, - 0x18, 0x53, 0x9f, 0x82, 0x2f, 0xec, 0x61, 0x5d, 0x69, 0xe7, 0x9f, 0xd4, - 0x3c, 0xd4, 0x00, 0x7d, 0xf0, 0x68, 0x1f, 0x63, 0x4d, 0xbe, 0x77, 0x48, - 0x75, 0x16, 0x06, 0x01, 0x73, 0x4c, 0xdd, 0x2f, 0x8c, 0x73, 0xb4, 0xae, - 0xb0, 0xf3, 0x29, 0x23, 0x86, 0x21, 0xeb, 0xcc, 0xbb, 0x42, 0xd8, 0x04, - 0x9b, 0xb4, 0x49, 0x19, 0x1b, 0x5d, 0xed, 0x49, 0x7b, 0x3f, 0x07, 0x01, - 0xda, 0x08, 0x7b, 0x61, 0x2f, 0x56, 0x7b, 0xb0, 0x54, 0x6f, 0xe3, 0xff, - 0x67, 0xd8, 0xf8, 0x6c, 0x23, 0xae, 0xb1, 0xf1, 0x7f, 0xc5, 0xf2, 0x1a, - 0x7f, 0x7b, 0xda, 0xde, 0x3f, 0x0c, 0xf8, 0xf6, 0x2d, 0xd9, 0xfb, 0xec, - 0x83, 0x76, 0x87, 0xc8, 0x0d, 0xb0, 0xf9, 0xde, 0x09, 0x1e, 0xbc, 0x11, - 0xbe, 0xd4, 0xbb, 0x4a, 0x9e, 0xec, 0x2f, 0xb5, 0xc1, 0xe7, 0x6e, 0x97, - 0x77, 0x4f, 0xed, 0x94, 0xa1, 0xc9, 0x0f, 0x5e, 0x21, 0xcd, 0xdb, 0x60, - 0xa3, 0x4e, 0x01, 0xce, 0x98, 0x95, 0xdb, 0x3f, 0x04, 0xde, 0x3a, 0x53, - 0xdf, 0x57, 0x6d, 0xdb, 0x8d, 0x9c, 0xe7, 0xd9, 0xc9, 0xb5, 0xfa, 0x49, - 0xa0, 0x3d, 0x63, 0x29, 0xdb, 0xe4, 0xec, 0x49, 0x7a, 0x5f, 0x29, 0xd8, - 0xe5, 0x01, 0x6c, 0x92, 0x1d, 0xe8, 0x8f, 0xf1, 0xe4, 0x4d, 0xf2, 0xd4, - 0x35, 0xee, 0x27, 0xf2, 0x9a, 0x0f, 0xdb, 0x9d, 0xdc, 0xd4, 0x8d, 0x52, - 0x3c, 0x18, 0xc7, 0x1c, 0x54, 0xdb, 0x16, 0xb9, 0x5e, 0x86, 0xf4, 0x7c, - 0xce, 0xc8, 0x11, 0xe8, 0xe6, 0x3f, 0x28, 0x0d, 0xc9, 0xe2, 0x70, 0x2b, - 0x9e, 0xe3, 0xf2, 0x54, 0xa9, 0x07, 0xbe, 0xcf, 0x3b, 0x80, 0xa3, 0x46, - 0x3c, 0x37, 0xca, 0xc0, 0x15, 0xe4, 0xd5, 0x16, 0x59, 0x40, 0xf9, 0x3b, - 0xe5, 0xdf, 0xd9, 0x72, 0x96, 0x91, 0x37, 0x5a, 0xd0, 0x36, 0x2e, 0x17, - 0x4b, 0xb4, 0x2b, 0x35, 0x4f, 0xf4, 0x7f, 0x4b, 0x7a, 0xb2, 0xdf, 0x82, - 0x9d, 0x7a, 0x01, 0xd7, 0xd3, 0x92, 0xde, 0x3f, 0xea, 0xf4, 0xa4, 0x3a, - 0x1d, 0xe8, 0x4e, 0x5c, 0xae, 0xd3, 0xe3, 0x35, 0x3a, 0x57, 0xd9, 0x3e, - 0x1a, 0xe4, 0xe9, 0x83, 0x2a, 0xd9, 0x82, 0x35, 0xd9, 0xed, 0x74, 0xd9, - 0x32, 0x3e, 0xeb, 0x9c, 0x3c, 0xe9, 0x3c, 0xab, 0x76, 0x6c, 0x10, 0xe9, - 0x68, 0x81, 0xcd, 0x33, 0x26, 0xaa, 0xad, 0x45, 0x5c, 0xe9, 0x9c, 0x51, - 0xed, 0x28, 0xf3, 0x6d, 0x59, 0xa2, 0x05, 0xfa, 0x01, 0x65, 0xdb, 0x50, - 0xb6, 0xcb, 0x96, 0xb5, 0xb6, 0x48, 0x23, 0xca, 0xce, 0x68, 0x9e, 0xbf, - 0xd4, 0xe5, 0x7b, 0x79, 0xa7, 0x59, 0x3a, 0x4e, 0xb5, 0x40, 0x36, 0x6c, - 0x92, 0x85, 0x6b, 0x9a, 0xa4, 0x03, 0xef, 0x18, 0xe7, 0x0e, 0x4e, 0xc5, - 0xe5, 0xba, 0x53, 0x9d, 0xc9, 0x0f, 0x61, 0x0e, 0x9d, 0x67, 0x19, 0xf7, - 0x7e, 0xf2, 0x0a, 0xc6, 0x7d, 0x3a, 0xce, 0xf2, 0xde, 0xa4, 0xe5, 0x0f, - 0xf1, 0x61, 0xbe, 0x71, 0x44, 0x99, 0x7c, 0x1a, 0x7e, 0x2e, 0x75, 0x78, - 0xa7, 0xfd, 0x1e, 0xc7, 0x9f, 0x5e, 0x41, 0xbf, 0x6d, 0x86, 0xf6, 0x54, - 0x99, 0xfc, 0x48, 0x3d, 0x84, 0xfb, 0xb4, 0x23, 0xc5, 0x9a, 0xcc, 0x9a, - 0x23, 0x5f, 0x9d, 0x54, 0xcc, 0x65, 0x41, 0x59, 0xf5, 0x67, 0x42, 0xb3, - 0xc6, 0xe4, 0x05, 0x23, 0x97, 0xde, 0x67, 0xe4, 0xd2, 0x99, 0xf3, 0xcb, - 0xe4, 0xd2, 0x25, 0x2d, 0x97, 0x0e, 0x0a, 0xee, 0x73, 0x97, 0x20, 0x97, - 0x5e, 0xc0, 0xb3, 0xa7, 0xe5, 0x52, 0x42, 0xac, 0xbd, 0x2c, 0x3f, 0xd0, - 0xe3, 0xcf, 0x96, 0x5d, 0x6d, 0x57, 0x15, 0xa7, 0x61, 0x93, 0x94, 0x27, - 0xac, 0xfe, 0x96, 0x4c, 0xab, 0x74, 0xf5, 0xff, 0x50, 0x22, 0x9b, 0xf3, - 0xcf, 0xae, 0xe0, 0xf7, 0x46, 0x9f, 0x53, 0x94, 0x61, 0xaf, 0x42, 0x86, - 0x89, 0x5a, 0x5b, 0x86, 0xe1, 0x5d, 0x05, 0xef, 0x2a, 0xec, 0xf7, 0x6f, - 0x7f, 0x38, 0xe2, 0x51, 0x7e, 0x50, 0x66, 0x40, 0x26, 0x95, 0x21, 0x93, - 0xca, 0x90, 0x53, 0x65, 0xc8, 0x25, 0xd8, 0x6c, 0xe7, 0xcb, 0x90, 0x4b, - 0x65, 0xc8, 0x25, 0xc8, 0xb8, 0xc7, 0x20, 0xe3, 0x8c, 0x4c, 0x1b, 0x86, - 0x4c, 0x3b, 0x23, 0xf7, 0x59, 0x5d, 0x6f, 0x62, 0x25, 0xbd, 0xd6, 0x47, - 0xea, 0xd3, 0x31, 0xe4, 0xf3, 0x75, 0xb1, 0xc1, 0x03, 0xc7, 0x35, 0xbf, - 0x7b, 0xbe, 0xba, 0xca, 0x61, 0x0e, 0xcd, 0xf7, 0xb5, 0xff, 0xbe, 0x9b, - 0xbf, 0xa5, 0x09, 0x7c, 0xfd, 0x1d, 0xcb, 0xd7, 0xbb, 0x97, 0xf8, 0x3a, - 0xed, 0x30, 0x56, 0xbc, 0x36, 0x5f, 0x6f, 0xb3, 0xef, 0x0a, 0xe1, 0x3a, - 0xf0, 0xf5, 0xba, 0x15, 0x7c, 0x1d, 0x07, 0x5f, 0xef, 0x5f, 0xc5, 0xd7, - 0x1b, 0x9c, 0x01, 0xdd, 0x86, 0x67, 0x24, 0xf8, 0xdc, 0xe8, 0xd4, 0xf8, - 0xfa, 0x1e, 0xcd, 0xd7, 0x47, 0xc1, 0xd7, 0xd7, 0xd7, 0xf1, 0xf5, 0x7e, - 0x49, 0xdf, 0x9c, 0x8b, 0xed, 0x94, 0xd1, 0xfb, 0x55, 0xdb, 0x66, 0xf9, - 0x17, 0x31, 0xed, 0x0d, 0x8f, 0x0d, 0x4c, 0xb5, 0x49, 0xfe, 0xa1, 0x57, - 0x50, 0x46, 0x3e, 0x4b, 0x8f, 0x64, 0x1d, 0x4f, 0x8e, 0x1c, 0xff, 0xbe, - 0xcc, 0x6b, 0xde, 0x12, 0x19, 0x3b, 0x1e, 0x97, 0xf1, 0xe3, 0x8c, 0x43, - 0x7c, 0xcf, 0xd2, 0x7b, 0x93, 0x8c, 0x1f, 0x64, 0xde, 0x9c, 0x2b, 0xa3, - 0xc7, 0xe1, 0x6f, 0x1d, 0x67, 0x1c, 0xe2, 0xa5, 0x25, 0x1e, 0x9b, 0x87, - 0x6c, 0x19, 0x3d, 0xce, 0xb5, 0x8e, 0xa3, 0x9f, 0x16, 0x39, 0x7a, 0x5c, - 0xe4, 0xb6, 0xe3, 0xae, 0x7c, 0xe0, 0xf8, 0x12, 0xaf, 0x0d, 0x47, 0xbc, - 0xf6, 0x0c, 0x78, 0xad, 0xd3, 0xf2, 0x9a, 0x5a, 0xe2, 0xb5, 0xaf, 0xd6, - 0xf1, 0x1a, 0xdb, 0x93, 0xd7, 0x9e, 0xb5, 0x65, 0x7c, 0x76, 0xe5, 0xd0, - 0xf1, 0x76, 0x19, 0x7d, 0xe8, 0x2d, 0x32, 0x76, 0x3f, 0x61, 0x35, 0xdf, - 0x85, 0xa2, 0x2d, 0x36, 0x5d, 0xed, 0x44, 0xff, 0x51, 0x0e, 0x11, 0x71, - 0xed, 0x77, 0xcf, 0x48, 0xba, 0xc0, 0xf1, 0x1a, 0xe1, 0x47, 0x9f, 0x82, - 0x7f, 0x71, 0x08, 0x30, 0xdd, 0x72, 0x5c, 0xd2, 0xae, 0xbc, 0x2c, 0x13, - 0xc1, 0xe9, 0xed, 0xc6, 0x9e, 0x80, 0x2d, 0xa2, 0x6d, 0x9f, 0xac, 0xe4, - 0xdf, 0x1e, 0x6a, 0x1f, 0x63, 0xb2, 0x22, 0x8c, 0x05, 0x30, 0x6e, 0x6e, - 0xbf, 0x85, 0xca, 0xfc, 0xc7, 0x06, 0x7d, 0xe6, 0x45, 0xc7, 0x6c, 0xfb, - 0xf8, 0x9e, 0xcf, 0xb0, 0x67, 0xf4, 0xd9, 0x45, 0xb6, 0x67, 0x3f, 0x09, - 0x1d, 0x53, 0x2f, 0x56, 0xf8, 0x4d, 0x1c, 0xf8, 0x9f, 0x15, 0x7e, 0x5b, - 0xeb, 0x37, 0xdb, 0x4c, 0x7c, 0x96, 0x7c, 0xf7, 0x5d, 0x27, 0x5f, 0x9a, - 0xd3, 0xdf, 0x38, 0xc8, 0xf9, 0xf8, 0x5d, 0xe1, 0x33, 0xeb, 0xcf, 0x31, - 0xde, 0x91, 0x4a, 0xa9, 0x63, 0xdb, 0x99, 0x7b, 0x70, 0x70, 0x8e, 0x75, - 0x77, 0x5a, 0x1e, 0xdd, 0xa9, 0xfd, 0x0e, 0xda, 0x58, 0xa3, 0x93, 0x2f, - 0x48, 0x91, 0xb6, 0xc9, 0xf0, 0x4e, 0xa7, 0x30, 0xfd, 0x73, 0xdb, 0x8d, - 0xfd, 0x3c, 0xb0, 0x95, 0x79, 0x87, 0x59, 0xb5, 0x5a, 0x26, 0x9f, 0x92, - 0x48, 0x26, 0xa7, 0x6f, 0xce, 0xc2, 0xce, 0xce, 0x1f, 0xd7, 0xdf, 0xab, - 0x4a, 0x75, 0x2a, 0xce, 0xe9, 0x4e, 0xc8, 0xd7, 0x88, 0x16, 0x92, 0xf2, - 0xd1, 0xe3, 0xa4, 0x07, 0x95, 0xd8, 0x28, 0x1f, 0xb1, 0xf4, 0x70, 0x46, - 0x4a, 0x90, 0x3b, 0xc7, 0x8f, 0x7f, 0x40, 0xa6, 0x0f, 0xac, 0xa4, 0x87, - 0xb1, 0x1a, 0x3d, 0x24, 0x60, 0x9f, 0x39, 0xf5, 0xf4, 0xf0, 0xf3, 0x4b, - 0xf4, 0x30, 0xed, 0xfc, 0x6b, 0xe9, 0xe1, 0x86, 0x65, 0xf4, 0x30, 0xa1, - 0xe9, 0x61, 0x68, 0x89, 0x1e, 0x26, 0x8e, 0x73, 0x5c, 0xbd, 0x37, 0xea, - 0x2d, 0x38, 0x5c, 0xf3, 0x25, 0x5a, 0x48, 0x8d, 0xeb, 0x7c, 0xfd, 0x74, - 0x81, 0xe7, 0x9b, 0x36, 0x28, 0xc6, 0x49, 0x6a, 0xeb, 0xbf, 0xf1, 0xdf, - 0x74, 0xfd, 0xaf, 0xda, 0xfa, 0xff, 0x77, 0xfd, 0x33, 0x5b, 0x99, 0xbb, - 0xcf, 0x33, 0xb0, 0x46, 0x1e, 0x47, 0xf4, 0x90, 0xdb, 0x6a, 0xf4, 0x02, - 0xd7, 0x98, 0xcf, 0x90, 0x67, 0x90, 0x7f, 0xe7, 0x21, 0xff, 0x9e, 0x80, - 0xfc, 0x7b, 0x7c, 0xd9, 0x9e, 0x40, 0xbf, 0x8d, 0x47, 0x84, 0x72, 0x24, - 0xa8, 0xe1, 0x63, 0xa1, 0x8f, 0xf8, 0x30, 0xf9, 0x27, 0xcc, 0xfd, 0x5d, - 0x8e, 0x13, 0x57, 0xe7, 0x1c, 0x3d, 0x1a, 0xd4, 0xe3, 0x84, 0x70, 0xbf, - 0x5c, 0x37, 0x47, 0xfc, 0xae, 0xf0, 0xf9, 0x8c, 0xce, 0x23, 0x29, 0xea, - 0x3d, 0x28, 0xe2, 0x85, 0x7b, 0x50, 0xc4, 0x89, 0xab, 0xed, 0xfd, 0x62, - 0xa5, 0x49, 0xe7, 0xd0, 0x1f, 0x9e, 0x4b, 0xc8, 0x42, 0x82, 0x31, 0x3e, - 0x7e, 0xe7, 0x90, 0x7e, 0xb3, 0x9f, 0x2c, 0x4a, 0x81, 0xb9, 0x72, 0xe0, - 0xe9, 0x0d, 0x96, 0xb6, 0x19, 0x1b, 0xe4, 0x19, 0xe0, 0x68, 0x2f, 0xa2, - 0xdb, 0xca, 0xba, 0x96, 0xba, 0x98, 0x25, 0xf0, 0x3e, 0x25, 0xa9, 0x5c, - 0x1f, 0xee, 0x73, 0x1c, 0xfb, 0x13, 0x32, 0xf1, 0xe0, 0x87, 0x61, 0xcb, - 0xbd, 0x1f, 0x3a, 0x87, 0xe7, 0xcf, 0xb8, 0xf7, 0xe0, 0x69, 0x18, 0x66, - 0xf4, 0x77, 0xac, 0xe8, 0x03, 0x92, 0x1e, 0x92, 0x78, 0x3e, 0x63, 0xe3, - 0x4a, 0x49, 0x29, 0x96, 0x5e, 0x94, 0x7c, 0x85, 0xdf, 0x5c, 0x7b, 0x09, - 0xf7, 0xd7, 0x5b, 0x0f, 0xe3, 0x87, 0x0c, 0xeb, 0x3b, 0xd7, 0x66, 0x51, - 0xb2, 0x15, 0x93, 0xe3, 0x52, 0x8b, 0x9b, 0x9c, 0x91, 0x63, 0xda, 0x7e, - 0xce, 0xd8, 0xdc, 0x96, 0xf4, 0x70, 0x41, 0x8c, 0x0d, 0xfd, 0x39, 0xd8, - 0xd0, 0x9f, 0xad, 0x66, 0xf5, 0x3e, 0xd6, 0xe3, 0xb0, 0xa1, 0x1f, 0x83, - 0xee, 0xa1, 0xce, 0x49, 0x58, 0x9d, 0x33, 0xa1, 0x0e, 0x68, 0x9d, 0xf3, - 0xe7, 0x5a, 0xe7, 0xbc, 0x7b, 0x95, 0xce, 0x39, 0xaa, 0x3a, 0x27, 0xa9, - 0x73, 0x06, 0xd4, 0x7e, 0x87, 0xf6, 0xe2, 0x96, 0x35, 0x74, 0xce, 0x7b, - 0xe4, 0x1d, 0xf6, 0xdd, 0x3d, 0xf2, 0xde, 0x3d, 0x7a, 0xef, 0xc6, 0x9b, - 0x51, 0xfc, 0x76, 0x93, 0xd1, 0x41, 0xd7, 0xab, 0x6e, 0xbd, 0xe7, 0xfb, - 0x95, 0x3a, 0x9d, 0xd3, 0xa1, 0xfa, 0x9c, 0x01, 0xdd, 0x86, 0xb1, 0x09, - 0x3e, 0x07, 0x4e, 0x76, 0xb8, 0x09, 0xcf, 0x49, 0x89, 0x1d, 0xc7, 0xdc, - 0xcd, 0xf7, 0xa5, 0x94, 0x79, 0xf7, 0x56, 0xfb, 0x4e, 0x45, 0xe5, 0xae, - 0x29, 0xef, 0xb4, 0xe5, 0x46, 0x57, 0x75, 0xa8, 0x76, 0xad, 0xab, 0x76, - 0x83, 0xa1, 0x66, 0xa0, 0x5f, 0x67, 0xca, 0x91, 0xce, 0xe2, 0x6f, 0xc6, - 0x9e, 0x19, 0xa3, 0x88, 0x62, 0xd8, 0x29, 0xd4, 0xc1, 0x55, 0x8e, 0x6c, - 0x4a, 0xfe, 0x86, 0xaf, 0x80, 0x6b, 0x0e, 0x78, 0xbd, 0x19, 0xfc, 0xf3, - 0x1f, 0x4a, 0x8c, 0x81, 0xb6, 0xc9, 0x89, 0xa9, 0xfa, 0x77, 0xed, 0xf2, - 0xae, 0xa9, 0x1d, 0x72, 0xfb, 0xe4, 0xd6, 0xa4, 0x34, 0xef, 0x94, 0x89, - 0xc9, 0x29, 0x7d, 0xfe, 0x7d, 0xb3, 0xfe, 0x2e, 0x08, 0xbf, 0x97, 0x63, - 0x64, 0xe4, 0x90, 0x63, 0x64, 0x64, 0x56, 0xd5, 0x6c, 0xd6, 0xa8, 0x4f, - 0x7e, 0x8b, 0x64, 0x70, 0x32, 0xa9, 0xbf, 0xa5, 0x3a, 0x53, 0xbd, 0x4a, - 0x7e, 0xfb, 0xa4, 0xba, 0x4b, 0xd5, 0xce, 0xf7, 0x6a, 0x9b, 0x75, 0x76, - 0x99, 0xcd, 0xfa, 0xbf, 0x64, 0xe1, 0xbd, 0x71, 0xcc, 0x13, 0x34, 0x7c, - 0xf5, 0xb7, 0xb8, 0x17, 0xda, 0x96, 0x90, 0x17, 0x65, 0x50, 0xe3, 0x8f, - 0xf2, 0xb4, 0x05, 0x72, 0x70, 0x51, 0xeb, 0xd7, 0x2d, 0xa0, 0x41, 0xca, - 0xd2, 0x0f, 0xca, 0x0b, 0x5a, 0x9e, 0x6d, 0xb1, 0xb6, 0xeb, 0x3c, 0xbf, - 0x6d, 0x7d, 0x9c, 0xb6, 0xeb, 0x9f, 0xdb, 0x72, 0x96, 0xa5, 0x93, 0x8b, - 0x42, 0x7d, 0x97, 0x80, 0x0c, 0xa5, 0x3c, 0x7d, 0xa3, 0xb6, 0xeb, 0x97, - 0x6c, 0x1f, 0x94, 0x9f, 0x46, 0x76, 0xef, 0x76, 0xe6, 0x6d, 0x19, 0x9f, - 0xa3, 0x78, 0xba, 0x9f, 0xcd, 0x5b, 0x3e, 0x53, 0xce, 0xe7, 0xf1, 0x7e, - 0x33, 0xde, 0x93, 0xcf, 0x1e, 0xd7, 0x7c, 0xa6, 0xed, 0x13, 0xa7, 0xd7, - 0xee, 0x2f, 0x2c, 0xed, 0x0d, 0x14, 0xc8, 0x67, 0xea, 0x84, 0x37, 0x6f, - 0xe4, 0x01, 0xf3, 0x54, 0x7f, 0x03, 0xba, 0x83, 0x6d, 0x51, 0xfe, 0x70, - 0x96, 0xbe, 0x2d, 0xfc, 0x9f, 0x8d, 0x78, 0x6e, 0xc3, 0xf3, 0x8c, 0xbc, - 0xfb, 0x60, 0x5c, 0xcf, 0x7b, 0x02, 0xf3, 0x38, 0x7c, 0x1c, 0x73, 0x72, - 0x8c, 0xed, 0xec, 0x9e, 0x75, 0xa5, 0xe1, 0x2c, 0xf9, 0x8e, 0x67, 0x6d, - 0xc2, 0xf0, 0x50, 0x2f, 0xe9, 0x36, 0xed, 0x0d, 0xe9, 0xb3, 0xa5, 0xbb, - 0x93, 0x31, 0xe0, 0xe4, 0x30, 0xd6, 0x63, 0xa2, 0xe4, 0x7b, 0x39, 0xc7, - 0x4f, 0x62, 0x9e, 0xb0, 0x01, 0x3b, 0x61, 0x0b, 0x76, 0xc2, 0x0e, 0xec, - 0x84, 0x1d, 0xb8, 0x49, 0x4e, 0x5d, 0xc3, 0x1c, 0x93, 0xc2, 0x75, 0xf0, - 0xca, 0xe5, 0xaf, 0x75, 0x9c, 0xbe, 0xf1, 0xe6, 0x41, 0xf8, 0xec, 0xe2, - 0xa5, 0x87, 0x99, 0x87, 0xbf, 0xe8, 0x35, 0xde, 0x3c, 0x24, 0x9d, 0xfd, - 0x78, 0xdf, 0xff, 0xa2, 0x74, 0xdd, 0x7c, 0xab, 0xd3, 0x38, 0x3c, 0x08, - 0x3c, 0x66, 0x9d, 0x74, 0x72, 0xc4, 0x99, 0xc7, 0x38, 0xb9, 0xdd, 0x31, - 0x61, 0xdc, 0x72, 0x9e, 0xb1, 0x88, 0x9b, 0x3b, 0x63, 0x3d, 0xa9, 0x51, - 0x27, 0x3d, 0xac, 0x62, 0xe9, 0xe1, 0x41, 0x27, 0xaa, 0xc7, 0x6f, 0xae, - 0x42, 0xce, 0x00, 0xd6, 0xc3, 0xe5, 0x4f, 0x83, 0x9e, 0x8e, 0x48, 0xf1, - 0x64, 0x8b, 0xcc, 0x95, 0x3a, 0xbd, 0x9c, 0x4a, 0xe8, 0xdc, 0x12, 0x75, - 0x0a, 0x44, 0x7f, 0x36, 0x2e, 0x33, 0x93, 0x3b, 0x45, 0x69, 0xdb, 0x7d, - 0x9b, 0xe4, 0xa6, 0x26, 0xe5, 0x62, 0x9f, 0xb4, 0x2a, 0xf4, 0xcf, 0x6f, - 0xdc, 0xaa, 0x53, 0xdc, 0x4b, 0x8c, 0x78, 0x61, 0x3b, 0xf9, 0x64, 0x12, - 0x38, 0x04, 0xdd, 0x32, 0xc6, 0xdb, 0x24, 0x94, 0x7b, 0x1f, 0xd0, 0xf1, - 0x53, 0xc6, 0x6c, 0xeb, 0xf7, 0x1e, 0xc8, 0x1f, 0xf1, 0x35, 0xf9, 0x63, - 0xb6, 0xcc, 0x7d, 0x1a, 0x29, 0xb8, 0x8c, 0x11, 0xfb, 0xf8, 0x3d, 0xcd, - 0xba, 0x4d, 0x32, 0xd1, 0x57, 0xb0, 0x79, 0x1e, 0x7f, 0x9e, 0x64, 0x0e, - 0x31, 0x71, 0x32, 0xda, 0x47, 0x5e, 0x5f, 0xb9, 0xb7, 0x11, 0xaf, 0x93, - 0x07, 0x8e, 0x2c, 0x4c, 0x46, 0x7b, 0x21, 0xec, 0x0f, 0xcf, 0xd3, 0x46, - 0xde, 0xe6, 0x56, 0xb5, 0x23, 0x5c, 0xdc, 0xaf, 0x5c, 0x2e, 0x63, 0x95, - 0x4f, 0x99, 0xea, 0x69, 0xf9, 0x7a, 0xa6, 0x6a, 0x64, 0xeb, 0x74, 0x35, - 0xd2, 0x2d, 0x71, 0xa3, 0x4b, 0x57, 0xe9, 0x13, 0x13, 0xcd, 0xac, 0xe9, - 0x13, 0xea, 0x45, 0x25, 0xef, 0x9b, 0xdb, 0x26, 0xee, 0xc3, 0xb2, 0x38, - 0xe1, 0x7f, 0x7a, 0x3b, 0x73, 0x35, 0x26, 0x82, 0x37, 0xa3, 0x1f, 0x9b, - 0xae, 0xa4, 0x3e, 0x1c, 0x51, 0x8d, 0xb8, 0x6f, 0xd6, 0xf4, 0x07, 0x9e, - 0xc2, 0xb3, 0xf1, 0x13, 0x3e, 0x07, 0x3f, 0xe1, 0xb3, 0xd0, 0x75, 0xe7, - 0xe1, 0x27, 0x3c, 0x01, 0x3f, 0xe1, 0x71, 0xf8, 0x09, 0x8f, 0x41, 0x4f, - 0xd6, 0xfb, 0x07, 0xe3, 0xcb, 0xfc, 0x83, 0x50, 0xf3, 0x3f, 0xe3, 0x81, - 0x4f, 0xd4, 0xf9, 0x06, 0x87, 0x8c, 0xbe, 0x82, 0xdf, 0x6f, 0xf8, 0xa8, - 0x43, 0xdd, 0xa4, 0xf5, 0xa3, 0xc9, 0xdb, 0x1d, 0x5e, 0xd2, 0x57, 0x1d, - 0xca, 0xe8, 0xab, 0x99, 0x9a, 0xbe, 0x32, 0x7c, 0xf4, 0xf0, 0xa4, 0xc4, - 0xfc, 0xc9, 0xf9, 0x5c, 0xb0, 0x57, 0xf3, 0x50, 0xab, 0xbf, 0x53, 0x62, - 0x0f, 0xa8, 0xb6, 0x06, 0xc9, 0xd9, 0x67, 0xd0, 0xd7, 0x89, 0x4f, 0xa3, - 0xaf, 0xeb, 0x24, 0xaf, 0xed, 0xb3, 0xcb, 0xe3, 0xfb, 0xb1, 0x15, 0xf8, - 0x2e, 0x96, 0x27, 0x34, 0xce, 0xef, 0xaf, 0x70, 0x9f, 0xa5, 0x45, 0xc6, - 0x2b, 0x11, 0xce, 0x79, 0x9e, 0x95, 0xb9, 0x18, 0xed, 0x12, 0x7b, 0x78, - 0x1b, 0xcf, 0x59, 0xa9, 0x7c, 0xb0, 0x5e, 0xe7, 0xb0, 0x9c, 0xea, 0x93, - 0x64, 0xbe, 0x8f, 0xb4, 0x7a, 0x9f, 0xcc, 0xe8, 0xb5, 0xd8, 0x26, 0x0d, - 0x0f, 0xd3, 0x46, 0x89, 0xf6, 0xf3, 0xde, 0x7f, 0xa5, 0xfd, 0xe6, 0x6a, - 0xdc, 0xd4, 0x13, 0x39, 0xa2, 0xd7, 0x6b, 0x5a, 0xe7, 0x19, 0xde, 0x34, - 0xc7, 0xb8, 0x3c, 0xbf, 0x6f, 0xc5, 0x98, 0xfc, 0xbf, 0x66, 0xfd, 0x7e, - 0xf9, 0x4a, 0x63, 0xcf, 0x6c, 0xb6, 0x76, 0x8c, 0x89, 0x53, 0xad, 0x6d, - 0xc3, 0xb0, 0x9f, 0xfa, 0x6f, 0x32, 0xee, 0x70, 0xc6, 0x27, 0x77, 0x3a, - 0xc5, 0x49, 0xee, 0x65, 0xdb, 0xbf, 0xd1, 0xe1, 0xed, 0x77, 0x0e, 0xfb, - 0x3b, 0x50, 0xc6, 0x98, 0x25, 0x63, 0x36, 0xf7, 0x5f, 0xc9, 0x18, 0x6d, - 0xce, 0xe7, 0xd8, 0x2c, 0xdb, 0xe1, 0x4c, 0x4c, 0x76, 0xc2, 0x37, 0xe7, - 0xb9, 0x2a, 0xbe, 0x1f, 0xe2, 0xda, 0x41, 0x07, 0x7b, 0xfa, 0xcc, 0xee, - 0x98, 0x5c, 0x65, 0x63, 0xd0, 0xd4, 0xc3, 0x3f, 0xbd, 0x6c, 0xef, 0xf6, - 0x28, 0xf4, 0xd8, 0x2d, 0x90, 0x47, 0xd4, 0xc3, 0x47, 0xe5, 0x6d, 0x96, - 0x9e, 0x97, 0xeb, 0xe1, 0x4b, 0xc2, 0x38, 0x71, 0x2f, 0xde, 0x15, 0xc2, - 0x38, 0xe8, 0xe1, 0x58, 0x9d, 0xaf, 0x46, 0xbf, 0xaf, 0x29, 0x63, 0xf6, - 0xc3, 0x96, 0xfb, 0x7d, 0x90, 0x03, 0x89, 0xc8, 0xcf, 0x6b, 0x5c, 0xda, - 0xaf, 0xdd, 0x6f, 0xdb, 0x4e, 0x04, 0x7f, 0x44, 0x1c, 0xa5, 0x8e, 0xca, - 0x2f, 0x42, 0xa7, 0x31, 0x07, 0xe4, 0x2f, 0x34, 0xce, 0x44, 0x91, 0xf6, - 0x36, 0x6b, 0x18, 0xad, 0x9c, 0x4f, 0x45, 0x39, 0x1c, 0x45, 0xdb, 0x76, - 0xcc, 0xee, 0xc9, 0x17, 0xe5, 0xeb, 0x8c, 0x73, 0xa6, 0x06, 0x63, 0xeb, - 0xf9, 0x3d, 0x46, 0xb4, 0xfd, 0x45, 0xed, 0xb7, 0x67, 0x25, 0xea, 0x8b, - 0xcf, 0x0d, 0x75, 0x7d, 0xd3, 0x8e, 0xe2, 0x7d, 0xe5, 0x39, 0xb2, 0xa7, - 0xf5, 0x3e, 0xa3, 0xf9, 0x5e, 0x42, 0xc4, 0x27, 0xe4, 0x9d, 0x94, 0x3e, - 0xeb, 0xe4, 0x3f, 0x4c, 0xbb, 0x87, 0x7b, 0xb0, 0xde, 0xfc, 0x78, 0xf0, - 0x11, 0xfd, 0xcd, 0xc0, 0x69, 0x11, 0xa7, 0x18, 0xdc, 0xa6, 0x73, 0x4f, - 0x8a, 0x3a, 0xd6, 0x5c, 0xc0, 0xbd, 0xe6, 0xa3, 0x76, 0x3c, 0xcc, 0xbf, - 0xc3, 0xc1, 0xb2, 0x3c, 0x60, 0xa3, 0x0e, 0xa1, 0xec, 0x4d, 0x48, 0xc7, - 0x89, 0x5f, 0xd0, 0xbc, 0xb0, 0x05, 0xbe, 0xc0, 0xc0, 0x09, 0xe8, 0xea, - 0x13, 0x49, 0x19, 0x3a, 0xa1, 0x75, 0x63, 0x76, 0x75, 0xac, 0xa0, 0xc7, - 0x73, 0x9d, 0x77, 0xe9, 0x73, 0x6c, 0x6f, 0x3d, 0x11, 0x93, 0x63, 0x89, - 0x1e, 0xaf, 0xcb, 0x79, 0xb7, 0xd5, 0x85, 0x51, 0x0c, 0xbb, 0x05, 0xed, - 0x5f, 0x2f, 0x8e, 0x1d, 0xc5, 0xaf, 0x63, 0x32, 0x7d, 0xb0, 0x1d, 0xb0, - 0x75, 0x6e, 0x33, 0x67, 0x90, 0xb1, 0x56, 0xfa, 0x1b, 0xf7, 0x6e, 0x92, - 0xb2, 0xac, 0x03, 0xb0, 0x0c, 0x9e, 0xa0, 0x3e, 0xf3, 0x35, 0x8f, 0x03, - 0x06, 0xaf, 0x41, 0xfb, 0x21, 0xe4, 0xcb, 0xb7, 0x88, 0xff, 0x00, 0x64, - 0xdc, 0x89, 0xb8, 0x74, 0x9d, 0x68, 0x91, 0x5d, 0x27, 0xe8, 0x87, 0xd4, - 0xfb, 0xa5, 0xb4, 0x4b, 0xe7, 0x30, 0xc7, 0x77, 0x6a, 0x39, 0xc9, 0x3d, - 0xcd, 0xdb, 0xc9, 0xbb, 0xa8, 0x9b, 0x87, 0xcd, 0x9c, 0x3b, 0xe1, 0xe9, - 0x3d, 0xd2, 0x1c, 0xe6, 0x9c, 0xaf, 0x78, 0x18, 0xc7, 0xc8, 0x9c, 0x22, - 0xfd, 0x94, 0xe1, 0x6d, 0xc0, 0xf1, 0x31, 0xcb, 0x3b, 0x43, 0xdb, 0x2c, - 0x8f, 0xfe, 0x88, 0xbc, 0x77, 0xf3, 0x36, 0x23, 0x3b, 0x7f, 0x76, 0x1b, - 0x73, 0x93, 0xb6, 0xf8, 0xbc, 0x37, 0x69, 0x7b, 0xc2, 0xc8, 0xd0, 0xd7, - 0xe2, 0x45, 0x01, 0x8e, 0xa2, 0x7d, 0x29, 0x7d, 0x96, 0x2f, 0xbc, 0x18, - 0xe8, 0xf3, 0x2b, 0xc1, 0x02, 0xf3, 0x08, 0xf5, 0x77, 0x14, 0x6a, 0xdf, - 0x5b, 0xd9, 0x5b, 0x65, 0x9c, 0xfc, 0x89, 0xe8, 0x6f, 0xa9, 0xd4, 0xe5, - 0x1d, 0xd6, 0xef, 0x81, 0x31, 0xd6, 0xb4, 0x94, 0x1b, 0x14, 0x4e, 0xea, - 0xef, 0x21, 0x3d, 0xeb, 0x5c, 0x2a, 0x5d, 0x70, 0xbe, 0x39, 0x25, 0xa1, - 0xeb, 0x7f, 0xdf, 0xf9, 0xb6, 0xcf, 0x3d, 0xf3, 0x2f, 0x3b, 0xdf, 0x2a, - 0xf9, 0xe0, 0xc3, 0x0b, 0x98, 0xc7, 0x2b, 0xce, 0x77, 0xb0, 0xbe, 0x47, - 0xca, 0xd9, 0xb4, 0x67, 0x63, 0xe2, 0x17, 0x4a, 0xaf, 0x38, 0x5f, 0xaa, - 0xc5, 0x93, 0xfa, 0x23, 0x1a, 0x39, 0xca, 0x77, 0x15, 0xbc, 0xab, 0xe8, - 0xfd, 0x1f, 0x67, 0x76, 0xca, 0xe6, 0x97, 0x68, 0x3e, 0x9e, 0x5f, 0xda, - 0x97, 0x19, 0xd6, 0x7b, 0x15, 0xcf, 0x38, 0xb3, 0x73, 0x9f, 0xdb, 0x66, - 0xf2, 0x8c, 0x2e, 0xe0, 0x9d, 0xc9, 0xb9, 0x9c, 0x99, 0xbb, 0x80, 0x3a, - 0x4f, 0x3b, 0x33, 0x3a, 0xfe, 0xc5, 0x76, 0x17, 0x9c, 0xe9, 0xb9, 0xa7, - 0x9d, 0x39, 0xbd, 0x07, 0x7d, 0xd1, 0x79, 0x74, 0x8a, 0x7d, 0x5f, 0x44, - 0x9d, 0x79, 0xe7, 0x14, 0xfa, 0x9b, 0x9b, 0xe2, 0x79, 0xdc, 0x4e, 0xd8, - 0x05, 0xfc, 0x1b, 0x45, 0xfc, 0x1e, 0xc7, 0x33, 0xce, 0xdc, 0x52, 0xbf, - 0x0b, 0xe8, 0x87, 0x75, 0x49, 0x8b, 0x1c, 0xf7, 0x19, 0xf4, 0xbf, 0x7a, - 0xaf, 0x6a, 0x35, 0x4e, 0x9e, 0x07, 0x4e, 0x5e, 0xb4, 0x38, 0x79, 0xd5, - 0xe2, 0xe4, 0xb9, 0x3a, 0x9c, 0x88, 0x5a, 0x8e, 0x93, 0x57, 0x81, 0x13, - 0x51, 0x6b, 0xe3, 0x04, 0xef, 0x2a, 0x78, 0xa7, 0x71, 0xf2, 0xd2, 0x0a, - 0x9c, 0x2c, 0x2e, 0xc5, 0xe5, 0x0d, 0x4e, 0x5e, 0x00, 0x4e, 0x7e, 0x60, - 0x61, 0x7f, 0xd1, 0xe2, 0x04, 0xf7, 0xb9, 0x17, 0x51, 0xe7, 0xa5, 0x3a, - 0x9c, 0xbc, 0x08, 0x9c, 0xbc, 0x64, 0x71, 0xf2, 0x6d, 0x8b, 0x93, 0x6f, - 0xa3, 0xce, 0x22, 0x70, 0x72, 0x69, 0x0d, 0x9c, 0xbc, 0x00, 0x9c, 0x44, - 0xfd, 0x5e, 0x42, 0x3f, 0xdf, 0xae, 0xc3, 0xc9, 0x0b, 0x6b, 0xe0, 0x84, - 0x7b, 0xb1, 0x51, 0x4e, 0xf7, 0x99, 0xd7, 0xc9, 0xe9, 0x5e, 0x7c, 0x03, - 0x39, 0xdd, 0xac, 0x73, 0x46, 0x6a, 0x7f, 0xbb, 0x62, 0xc2, 0xe6, 0xa8, - 0x99, 0x5c, 0xc0, 0xda, 0x37, 0x9b, 0x3a, 0xc1, 0xe7, 0xc5, 0x02, 0xbc, - 0x11, 0x9d, 0x53, 0xea, 0xee, 0x19, 0x03, 0xaf, 0xbd, 0x5b, 0x0e, 0x9f, - 0x6c, 0x3c, 0x96, 0xb7, 0x65, 0xfe, 0x9e, 0xce, 0x82, 0x52, 0x7c, 0x17, - 0xe5, 0x24, 0xd0, 0x2f, 0x69, 0xe0, 0xb7, 0x0a, 0xbb, 0xb3, 0x52, 0xbf, - 0x27, 0x3d, 0xc5, 0x6f, 0x34, 0x71, 0x7f, 0x8c, 0x7f, 0x67, 0x23, 0xc5, - 0x3c, 0xab, 0xa2, 0x86, 0x37, 0x0d, 0xfd, 0xd1, 0xaf, 0x73, 0xab, 0xf8, - 0x37, 0x82, 0x62, 0xf0, 0xfb, 0x47, 0xfb, 0x68, 0x2b, 0x67, 0xec, 0x99, - 0xb0, 0x40, 0x9f, 0x53, 0xa9, 0xf1, 0x4f, 0xfd, 0x79, 0x68, 0xf2, 0x5d, - 0x8d, 0x6e, 0x8e, 0x2c, 0x7d, 0x77, 0xf0, 0xb4, 0x3c, 0xa5, 0x63, 0xc5, - 0xcd, 0xfa, 0xef, 0x2b, 0x9c, 0x09, 0x4c, 0x8c, 0x76, 0x41, 0xc7, 0x68, - 0x05, 0xde, 0xf8, 0xb8, 0x8d, 0xd3, 0x76, 0xf5, 0xbf, 0xb4, 0x14, 0xa3, - 0xad, 0xcf, 0x67, 0x31, 0xfb, 0xeb, 0xb9, 0xc9, 0x39, 0x9d, 0xa3, 0x33, - 0xc8, 0xef, 0x6f, 0x40, 0x46, 0x8c, 0x4d, 0x57, 0x64, 0xfc, 0x41, 0x3e, - 0x53, 0xbf, 0xc5, 0xa0, 0xc3, 0x28, 0xc3, 0x0b, 0x92, 0xeb, 0x67, 0x99, - 0x69, 0x33, 0xa8, 0xfd, 0xe5, 0xd3, 0x32, 0xb0, 0x34, 0x3e, 0xf1, 0xfb, - 0x89, 0xba, 0xef, 0x60, 0xd3, 0xe6, 0xc9, 0x3a, 0xb9, 0x2a, 0xdf, 0x47, - 0x7b, 0xe4, 0x9f, 0xb0, 0xdf, 0x0a, 0xe4, 0xfb, 0xfa, 0x6f, 0xbf, 0x6a, - 0xd1, 0x81, 0xdf, 0xfc, 0xbe, 0xda, 0x84, 0x33, 0x88, 0x36, 0xf3, 0x5e, - 0xcb, 0xb0, 0xca, 0xdc, 0x38, 0xcc, 0x73, 0x73, 0x33, 0xab, 0xbe, 0x9d, - 0x5d, 0xd3, 0x8b, 0x45, 0xbd, 0xa6, 0xcc, 0xcf, 0x2a, 0x80, 0x16, 0x35, - 0x6d, 0x69, 0xfa, 0x3f, 0xbc, 0xa4, 0x2f, 0xa9, 0x67, 0xcd, 0xb7, 0x67, - 0x8c, 0xbe, 0x4c, 0x27, 0x07, 0x31, 0xbe, 0xfe, 0x1b, 0x0d, 0xf6, 0x5c, - 0x6f, 0x7e, 0xee, 0x2e, 0xad, 0xeb, 0x27, 0x82, 0x6c, 0xca, 0x95, 0x35, - 0xea, 0x4e, 0xd6, 0xd5, 0xd5, 0xf3, 0xf6, 0xe4, 0xb7, 0xb0, 0x36, 0xbf, - 0x51, 0xae, 0xc8, 0xc0, 0xd4, 0x5f, 0xc1, 0x7f, 0x4c, 0xca, 0x6f, 0x96, - 0x1f, 0x01, 0xbd, 0x16, 0xb6, 0xd8, 0x6f, 0x35, 0xe5, 0x00, 0x37, 0xbf, - 0xbd, 0xa2, 0xf3, 0x89, 0x63, 0xbf, 0x0d, 0xba, 0xf8, 0xcc, 0x23, 0x1c, - 0x03, 0xb0, 0xc4, 0x60, 0xdb, 0xc3, 0x4e, 0x98, 0x7e, 0x44, 0xe7, 0xce, - 0x5d, 0x5f, 0x79, 0x44, 0xc7, 0x2c, 0x86, 0x2a, 0xed, 0xb2, 0xb7, 0xd2, - 0x22, 0xfb, 0xa0, 0x17, 0xf6, 0x55, 0x7c, 0x5c, 0x71, 0x79, 0x67, 0xc5, - 0xac, 0xd3, 0x07, 0x2b, 0x5c, 0xef, 0x3d, 0x32, 0x73, 0x72, 0xe5, 0xf7, - 0x3e, 0xe7, 0x0b, 0xd1, 0xdf, 0x73, 0x52, 0x8a, 0xf9, 0x65, 0xa4, 0x25, - 0x5c, 0xe5, 0xf4, 0xb1, 0x79, 0x8d, 0x07, 0x66, 0xb8, 0xa6, 0x27, 0x17, - 0x85, 0x79, 0xfa, 0xfc, 0x1b, 0x4e, 0x7f, 0xb9, 0x9d, 0xe7, 0xa6, 0xf9, - 0x2d, 0xaf, 0xa1, 0x6a, 0x94, 0x37, 0xbe, 0x56, 0xce, 0x38, 0xec, 0xfc, - 0x3d, 0x51, 0x8e, 0x5f, 0x9c, 0x39, 0xe3, 0xd2, 0x71, 0xb6, 0x05, 0xf7, - 0xef, 0x6e, 0xd7, 0x67, 0x9b, 0xcf, 0x8a, 0x2d, 0xd3, 0xf9, 0xe4, 0x78, - 0x5e, 0xf9, 0xbd, 0xb6, 0x88, 0x1f, 0x6a, 0x7f, 0xf7, 0x40, 0xe4, 0xff, - 0x02, 0x06, 0x86, 0xe5, 0x0a, 0xd4, 0x6f, 0x00, 0x00, 0x00 }; +/* 0x1f, 0x8b, 0x08, 0x00, 0x0f, 0x34, 0xe7, 0x45, 0x00, 0x03, */ + 0xbd, 0x7d, + 0x0d, 0x74, 0x5c, 0x57, 0x7d, 0xe7, 0xff, 0xdd, 0x19, 0x49, 0x63, 0x59, + 0x96, 0x9f, 0xe5, 0x89, 0x32, 0x51, 0x84, 0x3d, 0x23, 0x3d, 0xd9, 0x22, + 0x12, 0xe1, 0xc5, 0x11, 0xac, 0xda, 0x2a, 0xe9, 0x30, 0x92, 0x3f, 0x12, + 0x02, 0xab, 0x10, 0x43, 0xb3, 0x1c, 0x4a, 0xc5, 0x48, 0x4e, 0x02, 0x04, + 0xea, 0x40, 0xe8, 0x86, 0xdd, 0xec, 0x66, 0x32, 0x92, 0x3f, 0x9a, 0x8e, + 0x3d, 0x93, 0x44, 0x89, 0xbd, 0xdd, 0x9c, 0xad, 0x90, 0x14, 0x3b, 0x74, + 0x07, 0x4f, 0xe2, 0x98, 0x96, 0x73, 0x0a, 0x8d, 0x50, 0x8c, 0x9b, 0xe6, + 0xb0, 0xdd, 0xd0, 0xa6, 0x34, 0xdb, 0x86, 0x22, 0x8c, 0x81, 0xf4, 0x2c, + 0xdd, 0x86, 0x42, 0x77, 0xd3, 0x36, 0xe5, 0xed, 0xef, 0x77, 0xef, 0x7d, + 0x9a, 0x91, 0x34, 0xce, 0x07, 0xdd, 0xad, 0xcf, 0x79, 0x7e, 0xf3, 0xee, + 0xbb, 0x1f, 0xff, 0xfb, 0xbf, 0xff, 0xef, 0xfb, 0xbf, 0x4f, 0x97, 0x8b, + 0x34, 0x8b, 0xfd, 0xb7, 0x01, 0xd7, 0xd5, 0xc9, 0xfd, 0xe3, 0x57, 0x5f, + 0x39, 0x70, 0x25, 0x9f, 0xa3, 0x91, 0x68, 0x44, 0xde, 0xc4, 0xbf, 0xe4, + 0x1b, 0xa8, 0x83, 0x0e, 0xdd, 0x70, 0x2c, 0x5e, 0x12, 0x53, 0x43, 0xde, + 0xfe, 0x8c, 0x27, 0xb1, 0xc8, 0x50, 0xee, 0xce, 0x71, 0x4f, 0x24, 0x5d, + 0xee, 0x4b, 0x0e, 0xcb, 0x3f, 0x05, 0xb9, 0x78, 0x54, 0x58, 0xfe, 0x96, + 0xa1, 0x57, 0x7f, 0xeb, 0x2b, 0xff, 0x2a, 0xf5, 0xf2, 0x4c, 0x44, 0x62, + 0xee, 0xd0, 0xed, 0xe2, 0x6e, 0x93, 0x58, 0xe7, 0x50, 0x72, 0xff, 0x23, + 0xdb, 0x97, 0x44, 0x5a, 0xc3, 0xbe, 0x5e, 0x0a, 0xbe, 0xb2, 0x5d, 0x72, + 0x1d, 0x43, 0x89, 0xb1, 0x86, 0x21, 0x57, 0x9e, 0xaa, 0xc8, 0xe8, 0x89, + 0xc2, 0xcb, 0x41, 0x74, 0x28, 0x88, 0x4c, 0x0d, 0x38, 0x12, 0x19, 0x92, + 0xb3, 0xe3, 0x03, 0xf7, 0x04, 0xca, 0xf3, 0xfc, 0x45, 0x69, 0x19, 0x3c, + 0x37, 0x80, 0xf7, 0x65, 0x41, 0xdd, 0xbd, 0xd7, 0x9c, 0x28, 0xc4, 0x44, + 0x0d, 0xf5, 0xbc, 0x90, 0x89, 0x5c, 0x25, 0x7c, 0x7f, 0x56, 0x7a, 0xfc, + 0xa7, 0x05, 0xe5, 0xe5, 0x98, 0x64, 0x2a, 0xd2, 0x82, 0x32, 0xdc, 0x9b, + 0x51, 0x27, 0xe5, 0x66, 0x22, 0xae, 0xe4, 0x2b, 0x3f, 0x5e, 0x67, 0xc6, + 0x9d, 0xb3, 0xf7, 0xbf, 0x8e, 0x99, 0x3b, 0xc6, 0x2d, 0xc6, 0x64, 0x29, + 0x92, 0x10, 0xc0, 0x82, 0x79, 0x25, 0x64, 0xb2, 0x98, 0x94, 0x4c, 0x81, + 0xb0, 0x45, 0x25, 0xeb, 0x12, 0xae, 0x04, 0xda, 0xb7, 0x39, 0xf5, 0xeb, + 0xb3, 0xee, 0x0b, 0xa8, 0x9b, 0x44, 0xbd, 0x4e, 0x79, 0x12, 0x75, 0x4f, + 0x57, 0xe2, 0xf2, 0x44, 0xe5, 0x57, 0x25, 0x8d, 0xb6, 0x8f, 0x57, 0x30, + 0x76, 0xb1, 0x51, 0x86, 0xa7, 0x9b, 0x25, 0x33, 0xdd, 0x9d, 0xc8, 0x4a, + 0x10, 0x7c, 0xda, 0xff, 0xa8, 0x8c, 0xb5, 0xa1, 0x7e, 0x91, 0xef, 0x12, + 0x2b, 0xde, 0x65, 0xfd, 0x3e, 0x37, 0xab, 0x1c, 0x49, 0xef, 0x4d, 0x25, + 0xc6, 0x14, 0x9f, 0x1b, 0x24, 0xd3, 0x8f, 0xe7, 0xd1, 0xa8, 0x44, 0xbc, + 0x20, 0xb8, 0xc3, 0xbf, 0x0c, 0x70, 0xa4, 0x92, 0x49, 0xc5, 0xb6, 0x6c, + 0x97, 0xca, 0x25, 0x55, 0x5c, 0x72, 0x95, 0x2b, 0x25, 0xd9, 0x16, 0x04, + 0xef, 0xf3, 0x3b, 0x51, 0x2e, 0x32, 0x5c, 0x90, 0xfd, 0x58, 0x23, 0xf4, + 0x29, 0xbe, 0x1a, 0xda, 0x8c, 0x79, 0xf4, 0xb9, 0xc3, 0xd2, 0x28, 0xe9, + 0xb8, 0xa4, 0xd5, 0x90, 0x24, 0xd5, 0xd0, 0x3a, 0x94, 0x39, 0xd2, 0xe0, + 0x7d, 0xc1, 0xd2, 0xd2, 0x46, 0x3c, 0xcb, 0xa8, 0x1a, 0x6a, 0x5b, 0x55, + 0x9e, 0x4a, 0x8a, 0x5a, 0x07, 0x5c, 0xa5, 0x7a, 0xd3, 0x8a, 0x65, 0xb8, + 0xeb, 0xb2, 0x0f, 0x36, 0xad, 0x2d, 0xdb, 0xef, 0xac, 0x2c, 0xbb, 0xbd, + 0x85, 0xb0, 0x8a, 0xe2, 0xef, 0xb8, 0x9e, 0x6b, 0x3a, 0xde, 0xed, 0x36, + 0x60, 0x5e, 0xa3, 0x7e, 0xca, 0xdd, 0xa9, 0x9e, 0x0f, 0xa4, 0x9d, 0x30, + 0xf3, 0x9d, 0xc2, 0x3b, 0x54, 0x1d, 0xf2, 0xb1, 0x6e, 0xae, 0x1c, 0xc2, + 0xdc, 0xce, 0x4f, 0xa7, 0xdc, 0x2e, 0x85, 0xfb, 0x3c, 0x7f, 0x07, 0x41, + 0xc6, 0xcf, 0xe9, 0x35, 0xfd, 0xee, 0x74, 0x02, 0xcf, 0x80, 0x3f, 0x9e, + 0x4e, 0x6d, 0x92, 0xab, 0xed, 0xba, 0x7c, 0x13, 0x63, 0x76, 0xbb, 0x77, + 0xa8, 0x6e, 0xd7, 0x57, 0x29, 0x77, 0x56, 0xce, 0xe0, 0x39, 0x08, 0x6e, + 0xf4, 0x53, 0x89, 0x1c, 0xd6, 0xec, 0x42, 0x21, 0x2e, 0xdf, 0x2b, 0xa4, + 0x40, 0xc5, 0xa9, 0xde, 0x39, 0xe9, 0xf3, 0xe7, 0x00, 0x6f, 0x1e, 0xd7, + 0x41, 0xbe, 0x2b, 0xe3, 0x5d, 0x99, 0x6d, 0x83, 0xe0, 0x26, 0xff, 0x37, + 0x83, 0xb1, 0x76, 0xc3, 0x17, 0x4f, 0x15, 0xb1, 0x9e, 0x80, 0xf9, 0x74, + 0x11, 0xeb, 0x89, 0xb5, 0x7a, 0x5c, 0xaf, 0x7b, 0x2f, 0xd6, 0x9d, 0xb4, + 0x41, 0xba, 0xd8, 0x61, 0x69, 0xf9, 0x03, 0xf6, 0x2e, 0x92, 0x29, 0x3a, + 0x92, 0xf1, 0xff, 0x31, 0x48, 0x6b, 0x7e, 0x11, 0x67, 0xb8, 0x48, 0x5a, + 0x6c, 0x00, 0xac, 0x7c, 0xcc, 0xda, 0x7a, 0x1b, 0x1d, 0xe0, 0x96, 0xeb, + 0xc0, 0xf7, 0x31, 0xe5, 0x35, 0xd9, 0xf7, 0x21, 0x5f, 0xf0, 0xdf, 0x26, + 0x47, 0xbc, 0x6a, 0xbd, 0x0c, 0x69, 0xb2, 0x92, 0x93, 0xec, 0x83, 0x81, + 0x0c, 0xfb, 0xc0, 0x13, 0xfb, 0x74, 0x7d, 0xd1, 0x6d, 0x5d, 0xd6, 0xd1, + 0x75, 0xf1, 0x6f, 0x7d, 0x23, 0xc6, 0x70, 0x46, 0x8a, 0xd5, 0xb6, 0x23, + 0xc5, 0xfc, 0x66, 0x0b, 0x1f, 0x9e, 0x07, 0x9d, 0x4c, 0xe5, 0x82, 0x5d, + 0xdb, 0x70, 0x1e, 0x57, 0xd7, 0xa1, 0x6d, 0x17, 0x7c, 0xe0, 0x4a, 0xb6, + 0x30, 0x88, 0x71, 0xe3, 0xb8, 0x07, 0xc1, 0x94, 0x9f, 0x4e, 0x45, 0x65, + 0x08, 0xcf, 0xa3, 0xe4, 0x3d, 0xe0, 0x4f, 0xa2, 0x99, 0xed, 0xbe, 0x8c, + 0x80, 0xee, 0xf3, 0x95, 0xd7, 0x97, 0x22, 0x7a, 0x0e, 0xfe, 0x3f, 0x59, + 0xdc, 0x70, 0x1c, 0x33, 0xe6, 0x54, 0xb1, 0x43, 0xf2, 0xd3, 0x9e, 0x4c, + 0x16, 0x16, 0x7a, 0x95, 0xbc, 0x4c, 0x7e, 0xc7, 0xfa, 0xa5, 0x40, 0xbb, + 0x43, 0x32, 0x5c, 0xf1, 0x24, 0x5f, 0xc0, 0xbd, 0xd8, 0x0d, 0xfa, 0x8d, + 0x4a, 0x3a, 0x61, 0xd6, 0x26, 0x5f, 0x18, 0xc1, 0xfc, 0x80, 0x6b, 0x8f, + 0xbf, 0x07, 0x2d, 0x4c, 0xae, 0x64, 0x06, 0x48, 0x3f, 0x6f, 0x06, 0x96, + 0x98, 0xcc, 0xfa, 0xe0, 0x0b, 0xd7, 0xc0, 0x92, 0x2f, 0xc6, 0xa2, 0xc3, + 0x98, 0xf7, 0x70, 0xf9, 0x57, 0xd0, 0x7f, 0x8b, 0xfe, 0x0d, 0x7e, 0xb2, + 0x65, 0x51, 0xdc, 0xe3, 0xb8, 0x13, 0xe6, 0x90, 0x56, 0x21, 0x1b, 0xa6, + 0x3b, 0x65, 0x12, 0xb4, 0x3a, 0x2c, 0xf8, 0x3d, 0xcf, 0xb9, 0x10, 0xae, + 0x0e, 0xfd, 0x7b, 0x72, 0x7a, 0x8b, 0x7e, 0xce, 0x8e, 0x76, 0x48, 0x6e, + 0x3e, 0x9c, 0x33, 0xe5, 0x05, 0x65, 0x44, 0xea, 0xb0, 0x08, 0x65, 0x46, + 0x10, 0x3c, 0xe8, 0x53, 0x6e, 0x04, 0xc1, 0x69, 0x9f, 0x72, 0xe4, 0x0c, + 0xe4, 0x03, 0x65, 0x07, 0x79, 0xd9, 0x53, 0x5c, 0xab, 0x4c, 0xa1, 0x17, + 0xeb, 0xd1, 0x28, 0xd9, 0xfe, 0xe3, 0x84, 0x15, 0x72, 0xe7, 0xa5, 0x4f, + 0x66, 0xbc, 0x5c, 0x22, 0xa2, 0xf1, 0x04, 0xca, 0x82, 0x3c, 0x4c, 0xeb, + 0x99, 0x75, 0x49, 0xbe, 0xbf, 0x64, 0xeb, 0xc8, 0xaf, 0xb2, 0x4e, 0x74, + 0x4d, 0x9d, 0x7f, 0xa7, 0x0c, 0x5f, 0xf6, 0x62, 0xdd, 0x3a, 0x14, 0xf1, + 0xd8, 0xb5, 0x8d, 0xcf, 0x12, 0x6b, 0x18, 0xfa, 0x3d, 0xbc, 0x7b, 0xee, + 0x53, 0x8f, 0x7a, 0xf5, 0xde, 0xfd, 0x28, 0xba, 0xf6, 0xdd, 0x94, 0x44, + 0xbd, 0x54, 0xef, 0x8d, 0xea, 0x4f, 0x1a, 0xa4, 0x35, 0x08, 0x1e, 0xf5, + 0xc3, 0xf2, 0xc6, 0x86, 0xb5, 0x63, 0x5c, 0x55, 0xa7, 0xec, 0x68, 0x9d, + 0xb2, 0xcf, 0xd7, 0x29, 0x7b, 0x7b, 0xe3, 0xda, 0xb2, 0xdb, 0xeb, 0x94, + 0xcd, 0xd6, 0x29, 0xfb, 0x69, 0x9d, 0x32, 0x69, 0x5a, 0x5b, 0x16, 0xa9, + 0x53, 0xd6, 0x57, 0xa7, 0x2c, 0x0a, 0xbe, 0xdb, 0x26, 0xf9, 0xf8, 0xbd, + 0x9c, 0xbb, 0xc5, 0x4d, 0x29, 0xb2, 0x16, 0x37, 0x0d, 0xa8, 0xd7, 0xb9, + 0xaa, 0xde, 0x17, 0xeb, 0xd4, 0x6b, 0x44, 0xbd, 0xb6, 0x55, 0xf5, 0x76, + 0xd4, 0xc1, 0x75, 0x13, 0xea, 0xc5, 0x56, 0xd5, 0x7b, 0xb0, 0x4e, 0x3d, + 0x96, 0x7f, 0xc6, 0x8e, 0xd3, 0x07, 0x2d, 0xf4, 0x5a, 0xeb, 0xd5, 0x28, + 0xd2, 0xce, 0xf2, 0x5e, 0xe8, 0x90, 0x0e, 0x65, 0xe4, 0x02, 0x65, 0x10, + 0xcb, 0x3a, 0x41, 0xe7, 0x71, 0xd0, 0x1d, 0xe5, 0x28, 0xf8, 0x8c, 0x73, + 0xa9, 0x6c, 0x90, 0xb1, 0x78, 0x9f, 0x7b, 0xb5, 0x6a, 0x01, 0x8d, 0xa5, + 0xdc, 0xa4, 0x22, 0xff, 0x49, 0x2e, 0x32, 0xe4, 0xe5, 0x86, 0x45, 0xc5, + 0x95, 0x04, 0x32, 0xe2, 0xab, 0x36, 0x25, 0xf7, 0x80, 0xbf, 0xd2, 0xd0, + 0x59, 0x37, 0x06, 0xc3, 0x9a, 0xb7, 0x4c, 0xdd, 0x8b, 0xcb, 0x54, 0x5f, + 0x0e, 0x52, 0x16, 0x0e, 0x8d, 0x7e, 0x2a, 0xe3, 0x2d, 0x0c, 0x36, 0x82, + 0x66, 0xcf, 0xa3, 0xcd, 0x6e, 0xb4, 0xdc, 0x57, 0x8e, 0xca, 0x48, 0x79, + 0x00, 0xbc, 0xe0, 0xc8, 0x39, 0x6f, 0xa3, 0x9c, 0xf3, 0x51, 0xb7, 0x12, + 0x91, 0xc5, 0xb8, 0x23, 0x8b, 0x78, 0xce, 0xf8, 0x78, 0x57, 0x09, 0x79, + 0x6b, 0x40, 0x0e, 0x14, 0x7d, 0x39, 0x5c, 0xbc, 0x41, 0x85, 0x7a, 0x6d, + 0xa7, 0xbf, 0x5e, 0x1e, 0x73, 0x4d, 0xdf, 0xbb, 0xbd, 0x05, 0x68, 0xd4, + 0xa8, 0x9c, 0xf7, 0x52, 0x89, 0x45, 0xcd, 0x13, 0xff, 0x27, 0x18, 0x41, + 0x3f, 0xb3, 0x5e, 0xca, 0xfd, 0x03, 0x3c, 0x8f, 0x95, 0x69, 0xcb, 0x54, + 0xfb, 0x9a, 0x44, 0x5f, 0x87, 0x8a, 0x1b, 0xe4, 0x56, 0xdb, 0x7e, 0x97, + 0xb7, 0xd0, 0x0b, 0x9e, 0x73, 0x4f, 0x50, 0x86, 0x14, 0x00, 0xd7, 0x5e, + 0xf0, 0x36, 0xda, 0x7e, 0x4d, 0xcb, 0x33, 0xd8, 0x3e, 0x85, 0x8d, 0x90, + 0xcf, 0x7f, 0x17, 0xdc, 0x1a, 0x67, 0x7d, 0x96, 0x51, 0xe7, 0x48, 0x49, + 0x0d, 0x41, 0x26, 0x0c, 0x50, 0x66, 0x26, 0x21, 0x2f, 0x21, 0x7b, 0x8a, + 0x3f, 0x0d, 0xd2, 0xd1, 0x5a, 0x39, 0x28, 0xb9, 0x6a, 0x1d, 0x96, 0x25, + 0x8d, 0x5c, 0x2d, 0x2e, 0x2d, 0xcb, 0x8a, 0x1c, 0xe4, 0xcb, 0x53, 0x15, + 0xca, 0x85, 0x0f, 0x82, 0x47, 0x3b, 0x65, 0xa4, 0x90, 0xca, 0xa5, 0x65, + 0x1b, 0xd6, 0xef, 0xd7, 0xb1, 0xa6, 0x51, 0x5c, 0x0f, 0xad, 0x97, 0x56, + 0x1f, 0xba, 0x9b, 0xe5, 0xe8, 0xb4, 0x9d, 0x36, 0xd2, 0x6f, 0x03, 0x0f, + 0x93, 0x5c, 0xf3, 0x44, 0x26, 0xe2, 0x8c, 0xd2, 0x5e, 0x19, 0x85, 0x7c, + 0xcc, 0x96, 0xd9, 0x37, 0xe1, 0x4d, 0xd8, 0xdf, 0xb0, 0x9b, 0x0a, 0x9d, + 0xf6, 0x77, 0x0b, 0x7e, 0x27, 0xed, 0x6f, 0xc8, 0xd4, 0x82, 0x67, 0x7f, + 0xc7, 0xb5, 0x1c, 0x32, 0xbf, 0x13, 0xf8, 0xdd, 0xaf, 0x7f, 0x4f, 0x15, + 0x77, 0xed, 0x52, 0xde, 0x95, 0x92, 0x9d, 0xef, 0x94, 0x03, 0x85, 0x77, + 0x58, 0xd9, 0x82, 0x4b, 0xbe, 0xe4, 0x98, 0x79, 0x26, 0xf4, 0xba, 0xe7, + 0x8b, 0x39, 0x67, 0x94, 0xf0, 0xe3, 0xf7, 0x70, 0xa1, 0xcf, 0xdd, 0x24, + 0xa4, 0x81, 0x29, 0x67, 0xb8, 0xe2, 0xa4, 0x23, 0x43, 0x3d, 0x89, 0x49, + 0x39, 0x8c, 0xdf, 0xe2, 0x46, 0x86, 0xbe, 0x84, 0xbb, 0xc1, 0xc1, 0x57, + 0xb6, 0x43, 0xb6, 0x16, 0x29, 0x2f, 0x3d, 0xcc, 0x3d, 0x29, 0x67, 0x56, + 0xd8, 0x58, 0xc4, 0x85, 0x92, 0xec, 0x74, 0xea, 0x78, 0x4e, 0x52, 0xb9, + 0x19, 0x30, 0xc4, 0x8d, 0x7e, 0x54, 0xde, 0xe7, 0x83, 0x76, 0xaf, 0x74, + 0x64, 0xd7, 0x95, 0x51, 0xd8, 0x44, 0xde, 0xcc, 0x2e, 0xc8, 0x58, 0xc8, + 0xbe, 0x08, 0xe9, 0x41, 0x9d, 0x92, 0xb1, 0xe8, 0x10, 0xb0, 0x7d, 0xaa, + 0x7f, 0x64, 0xb2, 0x90, 0xbd, 0x5d, 0x0d, 0xed, 0xff, 0x6c, 0x66, 0xe0, + 0xad, 0x92, 0xdd, 0xab, 0x80, 0xa3, 0xf6, 0x31, 0xc8, 0x4c, 0xcc, 0x2b, + 0x08, 0x40, 0xcf, 0x90, 0xe7, 0x37, 0xdd, 0x14, 0x19, 0x6a, 0x90, 0xe1, + 0xbd, 0xed, 0x68, 0xc3, 0x77, 0xc4, 0xd7, 0x79, 0xe0, 0x33, 0x95, 0x1c, + 0x11, 0xb9, 0x7b, 0x6a, 0x60, 0xc9, 0x99, 0x2c, 0x7d, 0x10, 0x3c, 0x79, + 0x15, 0xda, 0x3f, 0x80, 0xf6, 0x2f, 0x3b, 0xf9, 0xe9, 0x57, 0x9c, 0xc9, + 0xe9, 0xbf, 0x75, 0xa6, 0xa6, 0xb7, 0x6c, 0xd9, 0x39, 0xb8, 0x65, 0xcb, + 0xf8, 0x60, 0xd4, 0xea, 0x97, 0x2d, 0x5b, 0xa6, 0x06, 0x07, 0x81, 0x83, + 0x3e, 0x77, 0x44, 0x3c, 0x77, 0x97, 0x80, 0x7f, 0xe2, 0x1c, 0x93, 0xfa, + 0x27, 0x85, 0xf7, 0x6c, 0xef, 0xe9, 0xf7, 0xc3, 0xd2, 0x97, 0x68, 0x13, + 0x8e, 0x1f, 0xb1, 0x75, 0xda, 0x01, 0xfb, 0x03, 0x76, 0x7d, 0x0b, 0xaa, + 0xc1, 0x63, 0x39, 0xe7, 0xc2, 0x72, 0xae, 0xed, 0x8f, 0xac, 0x2d, 0xbb, + 0x11, 0xe5, 0x7c, 0x26, 0xce, 0x88, 0x17, 0xda, 0x22, 0x0d, 0xda, 0x76, + 0xcc, 0x16, 0x48, 0x33, 0x51, 0x99, 0x28, 0xb4, 0xa1, 0x0d, 0xe8, 0xe2, + 0x94, 0xbd, 0x8e, 0x02, 0xb6, 0xbd, 0xe8, 0xeb, 0xe8, 0x21, 0xb4, 0xa3, + 0xcc, 0x48, 0xf5, 0x8a, 0xfa, 0x04, 0xea, 0xf4, 0xb9, 0x9b, 0x85, 0x36, + 0xc7, 0x71, 0xc9, 0x16, 0xc9, 0xdf, 0x3d, 0x80, 0x27, 0x26, 0xc9, 0x76, + 0x3c, 0x57, 0x0e, 0xc0, 0x0e, 0x69, 0xb0, 0x3a, 0x33, 0x94, 0x17, 0xfc, + 0x77, 0x87, 0x12, 0xef, 0x80, 0x8c, 0xcd, 0x5d, 0x8e, 0x7a, 0x0e, 0xf0, + 0x42, 0x3b, 0x05, 0x36, 0xcb, 0x5c, 0x5a, 0x32, 0xdb, 0xee, 0xc5, 0xdd, + 0xc5, 0x73, 0x1e, 0xf7, 0xb7, 0xe0, 0x3e, 0x89, 0x7b, 0x08, 0x27, 0xf0, + 0xea, 0x47, 0xac, 0xce, 0xba, 0x06, 0x63, 0xff, 0x6b, 0xc9, 0x94, 0x12, + 0xb4, 0x39, 0x36, 0x66, 0xbc, 0xb4, 0xab, 0x44, 0x6d, 0x56, 0x32, 0x85, + 0xfa, 0xf0, 0x09, 0xbc, 0x83, 0x32, 0x7e, 0x12, 0xbf, 0x1f, 0xa4, 0x4d, + 0x3c, 0x25, 0xe3, 0x73, 0x1c, 0xa7, 0x00, 0x98, 0x4a, 0x92, 0x3d, 0xf9, + 0x00, 0xae, 0x69, 0x5c, 0x0f, 0xe3, 0xe2, 0xdc, 0xd8, 0xff, 0xe2, 0x26, + 0x05, 0x5c, 0xf3, 0x39, 0x4b, 0x3a, 0xae, 0xe0, 0x37, 0x69, 0xb8, 0x42, + 0xdb, 0x06, 0xf4, 0x5b, 0x09, 0xe9, 0xda, 0xb7, 0xbf, 0x13, 0x9a, 0xaf, + 0x73, 0x6d, 0xa0, 0x99, 0xca, 0xa0, 0x96, 0x39, 0x19, 0x0f, 0xf7, 0x0a, + 0x6c, 0x8f, 0x36, 0xce, 0xd1, 0xb3, 0x65, 0x9e, 0x2e, 0x4b, 0xea, 0xb2, + 0x7e, 0x5b, 0x86, 0x7b, 0xa5, 0x41, 0xc6, 0xda, 0x01, 0x31, 0xe5, 0xb3, + 0x84, 0xf8, 0xa4, 0x0c, 0x00, 0xfd, 0xc2, 0x66, 0x38, 0x73, 0x51, 0xf9, + 0xb7, 0xa4, 0x6d, 0xb1, 0xc7, 0x2b, 0xa4, 0x63, 0xd2, 0x76, 0x10, 0xdc, + 0xef, 0x37, 0xa1, 0x7f, 0xf2, 0xbc, 0x48, 0xc3, 0xd1, 0xa8, 0xcc, 0xb8, + 0xa4, 0x85, 0x77, 0xb4, 0x90, 0x06, 0x1a, 0x3d, 0xd2, 0x70, 0x2d, 0x7f, + 0x71, 0x0d, 0xd9, 0x5f, 0x0e, 0xf6, 0x1d, 0xed, 0xbc, 0x1e, 0xd8, 0xce, + 0x1c, 0xe3, 0x30, 0x9f, 0x5d, 0x05, 0x9e, 0xca, 0x2c, 0xf3, 0x94, 0xc8, + 0x6c, 0x81, 0xb8, 0x09, 0xed, 0x3f, 0xae, 0x33, 0xf1, 0xf3, 0x38, 0xe6, + 0xcc, 0xfb, 0x19, 0x8b, 0xa7, 0x2f, 0x59, 0x3c, 0x7d, 0xd9, 0xde, 0x5d, + 0x27, 0xab, 0x6d, 0xc1, 0x05, 0x3c, 0x73, 0x7d, 0xa2, 0x1a, 0x67, 0xd9, + 0xc2, 0x0c, 0xee, 0xa8, 0x5b, 0x7c, 0x5c, 0xc6, 0xb5, 0x9d, 0x16, 0x91, + 0x77, 0x69, 0xd9, 0x06, 0x21, 0xdd, 0x5c, 0x00, 0xcc, 0x0d, 0x92, 0x8b, + 0x47, 0xf4, 0xda, 0x47, 0xbd, 0x03, 0x51, 0x43, 0xab, 0xc4, 0xc9, 0x0a, + 0x5f, 0xaa, 0x06, 0xa6, 0xb8, 0x95, 0x73, 0x84, 0x8b, 0xb4, 0xfb, 0x88, + 0x86, 0xeb, 0x16, 0xc8, 0xbb, 0x9c, 0xa8, 0xf6, 0x46, 0xb9, 0x0c, 0xb4, + 0xa0, 0xe2, 0xd0, 0x5c, 0xc1, 0xd3, 0xb0, 0x9b, 0xb2, 0x73, 0xb4, 0xa1, + 0xbb, 0xe8, 0xb7, 0xc4, 0xb2, 0xfd, 0xad, 0xa4, 0x23, 0xa5, 0x60, 0x7f, + 0xe1, 0x59, 0x65, 0xfb, 0x35, 0x9d, 0x3a, 0xca, 0x8b, 0x6b, 0x3b, 0x19, + 0xbc, 0x12, 0xb1, 0xbe, 0x73, 0x54, 0x79, 0x9b, 0x57, 0x97, 0x25, 0xa9, + 0x87, 0xd1, 0x2e, 0x99, 0xed, 0x6f, 0x27, 0x8f, 0xb9, 0xca, 0x03, 0x2e, + 0x3d, 0xed, 0x1b, 0xe5, 0xd4, 0xc0, 0xc6, 0x55, 0xf5, 0xf5, 0xdd, 0xb1, + 0xcf, 0x51, 0x7b, 0x77, 0xed, 0x3d, 0x69, 0xef, 0xb9, 0xe8, 0x00, 0xef, + 0x8e, 0x44, 0x87, 0x78, 0xc7, 0x1a, 0x0e, 0xb1, 0x0f, 0xcd, 0x57, 0x56, + 0xce, 0xf4, 0xb8, 0x79, 0x21, 0x5f, 0xfd, 0xa9, 0xdc, 0x32, 0x67, 0xe4, + 0xef, 0x2e, 0xc8, 0x20, 0xf8, 0x6f, 0xee, 0xa2, 0x00, 0xfe, 0xbd, 0x65, + 0xb9, 0xa5, 0x42, 0xbc, 0xfd, 0x06, 0xf0, 0xb7, 0x35, 0x4a, 0xde, 0x74, + 0x85, 0x72, 0xf7, 0x4e, 0xd1, 0xf6, 0x69, 0x81, 0x38, 0x3f, 0x2b, 0x5c, + 0x9b, 0x7c, 0xe1, 0x19, 0xbd, 0x36, 0x07, 0x0b, 0x8b, 0xc0, 0xcf, 0xd7, + 0x41, 0xf7, 0x41, 0xb0, 0xe8, 0xe7, 0x41, 0x39, 0x7f, 0x84, 0xdf, 0xe8, + 0xbb, 0xf0, 0x1c, 0xde, 0xb7, 0x4a, 0xbe, 0x44, 0x9e, 0x8b, 0x5a, 0x1e, + 0x3e, 0x05, 0x7e, 0xba, 0x0c, 0xfd, 0xa2, 0x6c, 0x80, 0xbf, 0xff, 0x11, + 0xef, 0x70, 0x9f, 0xc3, 0x22, 0xb6, 0xd3, 0xd6, 0xe1, 0xd8, 0x5c, 0x3b, + 0xae, 0x59, 0x5c, 0xfb, 0xad, 0x8f, 0x2f, 0xaf, 0x1b, 0xd7, 0x2b, 0xd5, + 0x9b, 0x93, 0x70, 0xcd, 0x44, 0x1e, 0x2f, 0xb0, 0x3e, 0xe9, 0xff, 0x1f, + 0x62, 0x46, 0x17, 0xfc, 0xc9, 0x3a, 0x73, 0x5f, 0xdd, 0x96, 0x6b, 0x5e, + 0x4b, 0x83, 0xf4, 0x6f, 0x52, 0x83, 0x39, 0xc8, 0x9d, 0xa8, 0xd7, 0x2a, + 0x23, 0xda, 0x27, 0x22, 0x4d, 0x90, 0x06, 0x6e, 0x56, 0x86, 0x36, 0x3f, + 0xa4, 0x0c, 0x6d, 0x3e, 0x03, 0x5a, 0xc4, 0x55, 0x5c, 0x72, 0x0c, 0x6d, + 0x7e, 0x1d, 0x77, 0x5c, 0xc5, 0x0b, 0x4e, 0xc8, 0xc7, 0xc3, 0xf0, 0xf9, + 0x76, 0x15, 0xa2, 0xce, 0x78, 0x05, 0xf4, 0x5b, 0x8c, 0xa1, 0x7c, 0x81, + 0x38, 0xc7, 0xfc, 0x39, 0xce, 0x56, 0xdb, 0xff, 0xe3, 0x32, 0x51, 0x0c, + 0xb4, 0x5d, 0x95, 0x9d, 0xbb, 0x17, 0xf7, 0xf5, 0x5a, 0xce, 0x28, 0x2f, + 0xad, 0x8c, 0xbc, 0x7a, 0x17, 0xee, 0xdd, 0x89, 0x83, 0xd2, 0xed, 0x46, + 0xe4, 0x39, 0xf4, 0xf5, 0x43, 0x67, 0xa2, 0xf2, 0x32, 0xae, 0x9f, 0xe0, + 0x7a, 0x15, 0xd7, 0x2b, 0xe8, 0xf7, 0x45, 0x94, 0xaf, 0x97, 0x05, 0xb7, + 0x19, 0xf5, 0x45, 0x8d, 0x57, 0x5e, 0x70, 0xc6, 0x4e, 0xbe, 0x84, 0x2b, + 0xaa, 0x26, 0x2a, 0xcf, 0x3b, 0xd9, 0xb9, 0x60, 0xe3, 0xa2, 0x47, 0x19, + 0xf6, 0xa7, 0x8e, 0xe9, 0x7b, 0x08, 0x73, 0x00, 0x4d, 0x17, 0x17, 0x30, + 0xf6, 0x33, 0x9a, 0x67, 0x46, 0x20, 0xf3, 0xb3, 0xb0, 0x4b, 0xc6, 0x34, + 0x4c, 0x97, 0x03, 0x3e, 0xf8, 0xba, 0x03, 0xb8, 0xcf, 0x35, 0xca, 0x52, + 0x9c, 0x76, 0xe4, 0x97, 0x75, 0xfd, 0x6c, 0xb1, 0x5b, 0xe3, 0x76, 0x66, + 0x0d, 0xff, 0xd0, 0x3f, 0x0b, 0xe5, 0x81, 0x91, 0xc6, 0xb3, 0x05, 0xca, + 0x02, 0xe8, 0x9f, 0xc2, 0x14, 0xee, 0x8d, 0x5a, 0x26, 0xe4, 0x25, 0x94, + 0x07, 0x6c, 0x47, 0x99, 0x50, 0x2b, 0x77, 0x28, 0x6b, 0x28, 0x7b, 0x28, + 0x4b, 0xcc, 0x7a, 0x8c, 0x3f, 0x48, 0x19, 0x7e, 0x2d, 0xfc, 0x53, 0xda, + 0x1f, 0x9d, 0xc6, 0x07, 0x99, 0xce, 0x28, 0x23, 0x4f, 0xf7, 0xe8, 0xb5, + 0x98, 0x28, 0xa8, 0x38, 0x20, 0x47, 0x19, 0xae, 0x63, 0x7b, 0x71, 0xcf, + 0xaa, 0x09, 0x5c, 0xd9, 0x63, 0x1f, 0xc0, 0x6f, 0xae, 0xcd, 0x04, 0xea, + 0xe1, 0x2a, 0x8e, 0xe2, 0x8e, 0x0b, 0xb6, 0x99, 0x91, 0x23, 0x5c, 0xd3, + 0x84, 0x5d, 0xd3, 0x2f, 0x03, 0x0f, 0x9c, 0x9f, 0xd2, 0xf1, 0x07, 0xe5, + 0xed, 0x00, 0xde, 0x2b, 0xd6, 0xdf, 0x6d, 0x15, 0xc3, 0x83, 0xb8, 0x7a, + 0xc9, 0xcf, 0x2d, 0x66, 0xbd, 0x34, 0xed, 0x7e, 0x37, 0x6a, 0x78, 0x31, + 0x8e, 0xb2, 0x08, 0xca, 0xda, 0x45, 0xf3, 0xfe, 0x32, 0x1e, 0xd3, 0x16, + 0x8f, 0xfc, 0xad, 0xec, 0x6f, 0xd0, 0x13, 0x6c, 0xda, 0x8c, 0x37, 0x80, + 0x71, 0x31, 0x97, 0x63, 0x7b, 0xd4, 0x38, 0xe4, 0xf7, 0xb8, 0x47, 0x19, + 0xce, 0x38, 0x03, 0xe7, 0xc7, 0x7e, 0x51, 0xae, 0x71, 0xe0, 0x4b, 0xd5, + 0x87, 0xff, 0x32, 0xd6, 0xec, 0x71, 0xd9, 0x57, 0xbc, 0x5a, 0xfb, 0xd4, + 0x8d, 0x47, 0xcd, 0x7a, 0x88, 0x0a, 0xeb, 0xa1, 0xef, 0x38, 0x6d, 0x9b, + 0x31, 0xfd, 0x3e, 0x7a, 0x94, 0xbf, 0x29, 0x9f, 0x6b, 0xe5, 0xbd, 0xb1, + 0x6b, 0xf2, 0x2b, 0x64, 0x1d, 0x6d, 0x0b, 0xac, 0x59, 0xb9, 0x16, 0xef, + 0xf4, 0xf1, 0x29, 0xf3, 0xc8, 0x4f, 0x07, 0xc1, 0x13, 0xaa, 0xc1, 0xf0, + 0x3e, 0x7d, 0x8d, 0x7a, 0xfc, 0x04, 0xfb, 0x0b, 0xbc, 0x72, 0x02, 0xb6, + 0xdb, 0xae, 0xe5, 0x3e, 0x20, 0x2b, 0xe3, 0x31, 0x39, 0x59, 0x68, 0x91, + 0xb9, 0x82, 0x82, 0xc1, 0x60, 0x64, 0x67, 0x44, 0x12, 0x5a, 0xff, 0xd2, + 0xbe, 0x1b, 0x9e, 0x8e, 0x58, 0xba, 0x83, 0xc3, 0xd2, 0xfc, 0x1b, 0xd0, + 0xb1, 0x65, 0xe8, 0xd8, 0x56, 0xe8, 0xe0, 0xd5, 0x32, 0xa2, 0xab, 0x61, + 0xad, 0x8c, 0x60, 0x9b, 0x14, 0xbc, 0xf2, 0x83, 0x68, 0x17, 0xd2, 0x5f, + 0x4c, 0xd3, 0x5a, 0x56, 0x72, 0xce, 0xae, 0xca, 0x94, 0xb3, 0xbb, 0xb2, + 0x5a, 0x07, 0xf5, 0xb9, 0x51, 0x31, 0xb0, 0x9e, 0xd4, 0x71, 0xbc, 0x94, + 0x9f, 0x01, 0x4e, 0x76, 0x83, 0xee, 0x9e, 0x2e, 0xc1, 0x8f, 0xa7, 0x5c, + 0x06, 0xcc, 0x8f, 0x01, 0xe6, 0xd9, 0x92, 0x13, 0xda, 0x06, 0xc2, 0xe0, + 0xc9, 0xec, 0x74, 0xbf, 0x2c, 0xce, 0x93, 0x0e, 0x21, 0x03, 0x4a, 0x58, + 0x4f, 0x7f, 0x1d, 0xec, 0x00, 0x8e, 0x0f, 0xb9, 0x3d, 0xdd, 0xa1, 0xdf, + 0x19, 0x7d, 0xde, 0x29, 0x8b, 0xe5, 0xf7, 0x58, 0xd8, 0x0e, 0xd7, 0xc0, + 0xb6, 0x6e, 0x19, 0xb6, 0xdd, 0x80, 0x6d, 0x4f, 0x5d, 0xd8, 0xea, 0xe9, + 0xe2, 0x2e, 0xd8, 0x34, 0xe4, 0x8f, 0x10, 0xaf, 0xed, 0x96, 0x1e, 0x6e, + 0xb7, 0xf6, 0x2e, 0x6d, 0xa2, 0x9f, 0x02, 0x1e, 0xd2, 0x18, 0x7e, 0xcf, + 0x3d, 0x4a, 0x59, 0x86, 0x72, 0x3e, 0x7f, 0x06, 0x75, 0xf0, 0x3c, 0xf7, + 0xe7, 0x56, 0x0e, 0xde, 0x65, 0x61, 0xa1, 0x9d, 0x90, 0x86, 0x4d, 0x3c, + 0xe2, 0x64, 0xe6, 0x08, 0x43, 0x0e, 0xf0, 0xe2, 0x5d, 0xa5, 0xb6, 0x4f, + 0xde, 0xd9, 0xef, 0x15, 0xb6, 0x1f, 0xf6, 0x1d, 0xce, 0x65, 0xbd, 0xd5, + 0xf3, 0x21, 0x7d, 0x85, 0xf6, 0xf5, 0x94, 0x93, 0x5e, 0x33, 0xaf, 0x5a, + 0x9a, 0xa3, 0xbc, 0x8d, 0xca, 0x4e, 0xd0, 0xc9, 0xce, 0x15, 0xb4, 0xa6, + 0xdd, 0x10, 0x4b, 0xc7, 0xeb, 0xec, 0xfc, 0x0e, 0x18, 0xbe, 0xf1, 0x63, + 0xd0, 0x87, 0x94, 0x37, 0x37, 0x1b, 0xdf, 0x5c, 0x4e, 0x00, 0xd6, 0xf0, + 0x99, 0xb4, 0xc9, 0xdf, 0x94, 0x49, 0x55, 0x5a, 0x34, 0xbe, 0x4b, 0xa7, + 0x8e, 0x9f, 0x56, 0xed, 0xf5, 0xa8, 0x8c, 0x9a, 0x35, 0x3f, 0xcc, 0x35, + 0xa7, 0x2f, 0xd2, 0xfd, 0xc0, 0xa8, 0xe5, 0xaf, 0x54, 0x29, 0x27, 0xbb, + 0xed, 0xdc, 0xbf, 0x5c, 0x67, 0xed, 0x5a, 0x97, 0xd7, 0x6e, 0xb4, 0xb2, + 0x7a, 0x8e, 0x22, 0x5d, 0x0f, 0x44, 0xb5, 0x6f, 0x2b, 0xca, 0x97, 0x46, + 0x8f, 0xf2, 0x93, 0xb6, 0x12, 0xca, 0x67, 0xfb, 0xdc, 0x36, 0xd0, 0xdb, + 0x53, 0x6b, 0xec, 0xae, 0xa4, 0x95, 0x9b, 0xf4, 0x83, 0xc3, 0x31, 0x72, + 0x56, 0x4e, 0xe6, 0xd0, 0xff, 0x94, 0xb3, 0xb3, 0x52, 0x4f, 0x5e, 0x86, + 0x72, 0x92, 0xf3, 0xb9, 0x57, 0xee, 0x78, 0x90, 0x3c, 0x7a, 0xbb, 0xb6, + 0xaf, 0xaf, 0xda, 0x71, 0x00, 0xf8, 0x23, 0xfc, 0x8b, 0x9b, 0x60, 0x32, + 0x40, 0xe7, 0xa6, 0x65, 0xdc, 0xae, 0xdb, 0xf8, 0xf2, 0xfa, 0xf3, 0x6a, + 0xc7, 0x6f, 0xc6, 0x59, 0x95, 0x85, 0x59, 0xdb, 0xb1, 0xb0, 0xeb, 0x56, + 0xdb, 0xb2, 0x9c, 0x03, 0xed, 0xd9, 0x46, 0x63, 0x0b, 0x16, 0x69, 0x7f, + 0x52, 0x76, 0xd1, 0xfe, 0x8c, 0x35, 0x4a, 0x33, 0xe7, 0x33, 0x68, 0xcb, + 0x68, 0xa7, 0xae, 0x9e, 0xdf, 0x6a, 0xff, 0x91, 0x70, 0x12, 0x6e, 0x43, + 0x5b, 0x49, 0x45, 0xd8, 0x02, 0x19, 0xf5, 0xaf, 0xd5, 0x6b, 0xa0, 0x68, + 0xbb, 0xee, 0xf8, 0x76, 0x83, 0x89, 0x31, 0x27, 0xd1, 0x3f, 0xc7, 0x24, + 0xff, 0xf1, 0x4e, 0x3b, 0xbf, 0x9e, 0x2c, 0xab, 0xd5, 0x3d, 0x97, 0x2d, + 0xe3, 0x6f, 0xe7, 0x8a, 0x35, 0x0a, 0xf1, 0x17, 0xd2, 0x45, 0x2d, 0x0e, + 0x49, 0x13, 0xa4, 0x85, 0x90, 0x16, 0xb7, 0x5a, 0x7d, 0x13, 0xd2, 0xde, + 0xa5, 0xa0, 0xbd, 0xfb, 0x80, 0x27, 0xca, 0x70, 0xc6, 0xed, 0x36, 0xe3, + 0xf9, 0x08, 0x9e, 0x43, 0x3e, 0xb9, 0x98, 0x0c, 0xa7, 0xfc, 0x66, 0x9b, + 0x8c, 0x95, 0xfb, 0xa1, 0x9f, 0xcb, 0x36, 0x9c, 0x37, 0xe5, 0xff, 0x57, + 0xe9, 0x77, 0x35, 0x1a, 0x3b, 0xfd, 0x43, 0x8d, 0x94, 0xaf, 0x9b, 0xe4, + 0x60, 0x4d, 0xd9, 0xc5, 0xe4, 0x77, 0xed, 0x9c, 0x2f, 0xff, 0x7f, 0x30, + 0xe7, 0xc4, 0xaa, 0x39, 0xbb, 0x76, 0xce, 0x15, 0xbc, 0x6f, 0xc3, 0xfb, + 0x16, 0xea, 0x82, 0x64, 0x55, 0xde, 0x58, 0x5c, 0xe8, 0x79, 0xd5, 0xca, + 0x89, 0x50, 0x46, 0x70, 0x5e, 0x1f, 0xb1, 0x73, 0x78, 0xa0, 0x66, 0x5e, + 0x1f, 0x79, 0x13, 0xf3, 0xea, 0x5c, 0x31, 0xaf, 0x5d, 0x17, 0x9d, 0x57, + 0x3d, 0x1e, 0x27, 0x2f, 0x87, 0xf3, 0x8b, 0xc9, 0x8d, 0x05, 0xce, 0x71, + 0x27, 0xe6, 0x48, 0x18, 0xc2, 0x39, 0x0e, 0xd9, 0x39, 0x8a, 0xea, 0xda, + 0xf1, 0x73, 0xf8, 0x5d, 0x3b, 0x3f, 0xea, 0xfe, 0x1f, 0x83, 0xa6, 0x9b, + 0x24, 0xd3, 0xdf, 0x64, 0xe5, 0xff, 0x97, 0xe5, 0xd6, 0x22, 0xd7, 0x3a, + 0x95, 0x16, 0xd9, 0xa3, 0xf6, 0x15, 0x9f, 0x6d, 0x64, 0x8c, 0x7f, 0x97, + 0x6f, 0xf5, 0x18, 0xf4, 0xc5, 0x6e, 0xd8, 0x7c, 0x3b, 0x0b, 0x6a, 0x20, + 0x22, 0x41, 0x70, 0x9b, 0xdf, 0x8c, 0xb1, 0x37, 0x6a, 0x5f, 0x75, 0x6d, + 0x7c, 0xfd, 0x99, 0x46, 0xf1, 0x68, 0x6f, 0x50, 0x9f, 0x43, 0xdf, 0x1d, + 0xa3, 0x0d, 0x96, 0x81, 0x9d, 0x9c, 0x4e, 0x44, 0xb4, 0x2d, 0x46, 0x9d, + 0x98, 0x4a, 0xa4, 0xa5, 0x2c, 0xd9, 0x63, 0xe9, 0x84, 0x12, 0x8e, 0x01, + 0x5b, 0x0d, 0x36, 0xe4, 0xad, 0x90, 0x35, 0xb7, 0x56, 0xf6, 0xaa, 0x5b, + 0x60, 0xef, 0xdc, 0x72, 0xf2, 0x03, 0xea, 0x36, 0xd8, 0x3a, 0xb7, 0x9d, + 0xbc, 0x41, 0xed, 0x83, 0x6d, 0xb3, 0x0f, 0x76, 0xce, 0xbe, 0x0a, 0x6d, + 0xcf, 0x9b, 0x41, 0x7b, 0x9d, 0x35, 0xb4, 0x46, 0x1b, 0x87, 0xf3, 0x23, + 0xee, 0x8f, 0x71, 0x0d, 0xfc, 0xa4, 0x7a, 0x45, 0xaf, 0x4b, 0xdb, 0x8a, + 0xb2, 0xd7, 0x92, 0x55, 0xa1, 0x7e, 0xda, 0x60, 0xe3, 0x46, 0x94, 0xb7, + 0xaf, 0x45, 0x5b, 0xa4, 0x11, 0x17, 0x78, 0x26, 0xfe, 0x48, 0x5b, 0xb5, + 0xf3, 0xdf, 0xd4, 0x24, 0x5e, 0x67, 0x93, 0x34, 0xdf, 0x0b, 0xf9, 0x5a, + 0x4b, 0x53, 0xbc, 0xbb, 0x56, 0xd7, 0x90, 0xb6, 0x28, 0x83, 0x43, 0x7a, + 0xd8, 0xfa, 0x1a, 0xf2, 0xf7, 0xa2, 0xf4, 0x74, 0x4f, 0x64, 0x28, 0x08, + 0xc6, 0x07, 0x64, 0x23, 0xe3, 0x01, 0x99, 0x4a, 0x35, 0x26, 0xa0, 0xbc, + 0xda, 0x98, 0x00, 0xfd, 0xac, 0x47, 0x80, 0xdf, 0x19, 0x5c, 0x22, 0x63, + 0x8c, 0x3b, 0x54, 0x42, 0xbb, 0xfc, 0x1b, 0xd6, 0x2e, 0x0f, 0xe1, 0x48, + 0x02, 0x0e, 0x23, 0x9f, 0xd7, 0xea, 0xb9, 0x95, 0xfa, 0x3b, 0xb7, 0x6c, + 0xd3, 0x26, 0xe5, 0xc6, 0x22, 0xe7, 0x4d, 0x19, 0x4c, 0xdc, 0xd4, 0xca, + 0xe0, 0x84, 0xb5, 0xa3, 0x50, 0x47, 0xcb, 0xcf, 0xb5, 0xb2, 0x93, 0x72, + 0x8f, 0xf1, 0xf9, 0x07, 0x7c, 0xd2, 0xfa, 0x7b, 0x24, 0xbd, 0x1c, 0x9f, + 0x17, 0xd0, 0x9b, 0xf8, 0x91, 0x21, 0xbd, 0xdf, 0xe6, 0xce, 0xca, 0x6e, + 0x19, 0x8e, 0x33, 0xd6, 0xc9, 0x78, 0x9e, 0x97, 0x9b, 0x05, 0x0f, 0x4c, + 0x16, 0x15, 0x2c, 0xf8, 0x46, 0x19, 0x73, 0x03, 0xd9, 0xe5, 0x3b, 0x3a, + 0x76, 0x6c, 0x74, 0xed, 0x4c, 0x93, 0xb1, 0x5d, 0x1d, 0x1d, 0xff, 0x5d, + 0x04, 0xf5, 0x2d, 0x6a, 0xfb, 0x56, 0x69, 0xfd, 0xbb, 0xa0, 0xeb, 0x7c, + 0xae, 0x29, 0x8c, 0x63, 0x2e, 0xba, 0x11, 0x5b, 0xaf, 0xb6, 0xfc, 0x8b, + 0x36, 0x3e, 0x9d, 0x84, 0xec, 0x0f, 0xcb, 0xfe, 0xb0, 0x4e, 0xd9, 0xb7, + 0xea, 0x94, 0xfd, 0xcf, 0x3a, 0x65, 0x26, 0x2e, 0xb8, 0xb3, 0xf0, 0xf7, + 0x78, 0x37, 0xa5, 0x7d, 0x77, 0xb1, 0xfb, 0x61, 0xb9, 0xe5, 0x3a, 0x1b, + 0xac, 0x5f, 0xc6, 0x18, 0xb1, 0x89, 0x0d, 0x67, 0x75, 0x6c, 0xb8, 0xcf, + 0xdd, 0xa1, 0xf4, 0x5e, 0xca, 0x7e, 0xc6, 0x19, 0xf7, 0x69, 0xbc, 0x10, + 0x27, 0x5f, 0x61, 0x0c, 0x38, 0xc7, 0xbd, 0xd8, 0xa4, 0xba, 0x18, 0x6d, + 0x57, 0x6d, 0x13, 0xb3, 0x6e, 0xb4, 0x8b, 0x5b, 0x64, 0x04, 0xb6, 0xc2, + 0xce, 0x42, 0x9b, 0xec, 0x9a, 0x1e, 0x58, 0x47, 0xbd, 0xb5, 0x7b, 0xda, + 0xf8, 0x83, 0xfb, 0xc0, 0x57, 0x69, 0x21, 0x8c, 0x29, 0x5f, 0x84, 0x36, + 0xf1, 0x5a, 0x5b, 0xf8, 0xb5, 0xfb, 0xfb, 0xa5, 0x8b, 0xf4, 0xe7, 0xc0, + 0x76, 0x78, 0xa3, 0xfd, 0x35, 0xcb, 0xc8, 0x74, 0x88, 0x2b, 0xf5, 0x33, + 0xb6, 0x8b, 0x5c, 0xa4, 0x9d, 0xb6, 0x4b, 0xe4, 0xe9, 0x65, 0x59, 0xbc, + 0x15, 0x36, 0x93, 0x04, 0x99, 0x01, 0xe9, 0x8c, 0x88, 0x8e, 0xf1, 0xf8, + 0x46, 0x36, 0xf7, 0x70, 0x6f, 0x07, 0xf4, 0x6f, 0x6c, 0x15, 0x13, 0x37, + 0x0d, 0xed, 0x94, 0x7a, 0xb4, 0x7b, 0x9d, 0xa5, 0x5d, 0xee, 0xb9, 0xee, + 0xa6, 0xcc, 0xd5, 0x6b, 0x42, 0x3a, 0xde, 0x55, 0x90, 0x64, 0x48, 0xc7, + 0x8b, 0x92, 0x5e, 0x41, 0xc7, 0x8b, 0x32, 0xa4, 0xe9, 0xb8, 0x71, 0x05, + 0x1d, 0x77, 0x5a, 0x3a, 0xde, 0x13, 0x33, 0x74, 0xa1, 0xb4, 0x9e, 0x22, + 0x9d, 0x1a, 0x3a, 0x76, 0x34, 0x1d, 0x2f, 0xe2, 0x1e, 0xf5, 0xae, 0xb3, + 0x75, 0x22, 0xb6, 0x8c, 0xbf, 0xc3, 0x32, 0xca, 0xc5, 0x4f, 0xc6, 0x8c, + 0x5e, 0x1a, 0x02, 0x1d, 0x85, 0xe5, 0xfb, 0x6d, 0xfc, 0xa0, 0xb6, 0xcc, + 0xc4, 0x47, 0x76, 0x16, 0xc6, 0x62, 0x2b, 0xe9, 0x73, 0x08, 0xf4, 0x19, + 0xd6, 0x79, 0x2d, 0xfa, 0x6c, 0xb6, 0xfb, 0x16, 0x71, 0xbd, 0x2f, 0x9f, + 0x8e, 0x1b, 0x5a, 0xbd, 0x45, 0xcf, 0x9d, 0xf3, 0x3e, 0xfb, 0x06, 0x68, + 0xd5, 0xac, 0xcd, 0xb9, 0xaa, 0xbf, 0xcd, 0x58, 0x54, 0xd2, 0xc4, 0xb0, + 0x19, 0x27, 0xbd, 0x98, 0xed, 0x68, 0xe4, 0x53, 0x83, 0x96, 0x4f, 0xad, + 0x63, 0xcc, 0x35, 0xa8, 0xca, 0xec, 0x01, 0xe8, 0x0a, 0xda, 0xd8, 0x5a, + 0x4e, 0xe3, 0x5d, 0x67, 0x32, 0x53, 0x78, 0x35, 0x88, 0x78, 0x8c, 0x0f, + 0x71, 0x5f, 0x40, 0xc6, 0x1c, 0x94, 0x75, 0x95, 0xcd, 0xbc, 0x94, 0xd7, + 0x8a, 0xe7, 0x01, 0xe9, 0x2a, 0x2b, 0xf9, 0xe8, 0x74, 0x8b, 0xec, 0x2f, + 0x44, 0xe5, 0xe3, 0x68, 0xff, 0xb1, 0x82, 0x0b, 0x7f, 0xfc, 0x4c, 0x8c, + 0x76, 0xe1, 0xbe, 0x02, 0xf7, 0x27, 0x59, 0x37, 0xbe, 0x6a, 0x7f, 0x36, + 0x22, 0x5d, 0x3d, 0x79, 0x78, 0x2a, 0x12, 0xdd, 0x03, 0x38, 0x9a, 0x86, + 0x86, 0xe4, 0x07, 0x03, 0x1b, 0x51, 0xf6, 0xb2, 0x1d, 0x6f, 0xd4, 0x31, + 0xf1, 0xde, 0x41, 0x79, 0x77, 0x65, 0x48, 0xae, 0xaf, 0x98, 0x3d, 0xd5, + 0xea, 0x9e, 0x69, 0xca, 0x5d, 0x80, 0xfe, 0x49, 0xbb, 0x41, 0x70, 0xce, + 0xc3, 0xaa, 0x1f, 0x89, 0x4a, 0xac, 0x27, 0x95, 0x58, 0x10, 0xf3, 0x7c, + 0xbe, 0xfc, 0x0f, 0xc1, 0x58, 0x3c, 0x2a, 0x3f, 0xf0, 0x38, 0xc7, 0x41, + 0xb9, 0xae, 0x5c, 0x3b, 0x36, 0x97, 0xf3, 0x0f, 0x63, 0xdc, 0xa7, 0xc8, + 0x54, 0x16, 0x62, 0x8c, 0xa5, 0xd3, 0xe7, 0xe8, 0x7a, 0x1b, 0xfc, 0x38, + 0x48, 0xee, 0xae, 0xb7, 0x81, 0x6e, 0xe2, 0xd0, 0xf9, 0x57, 0x01, 0xc6, + 0xab, 0x18, 0xfb, 0x62, 0xcc, 0x8b, 0xcf, 0x5f, 0xc7, 0xb8, 0x6c, 0xfb, + 0x1b, 0xd6, 0x5e, 0xe6, 0xfa, 0x1b, 0xde, 0xa9, 0xaf, 0x77, 0x5a, 0xc7, + 0x62, 0x43, 0xe2, 0xc4, 0xde, 0x91, 0x90, 0x75, 0x5e, 0xed, 0xf8, 0xdc, + 0x27, 0x86, 0xc5, 0x38, 0x20, 0xd1, 0xdd, 0xdb, 0x07, 0x65, 0x04, 0xf3, + 0xdb, 0xb9, 0x66, 0x7e, 0xf7, 0x08, 0xe3, 0xab, 0xe7, 0x0b, 0x9c, 0x43, + 0x75, 0x5e, 0xea, 0x0b, 0x66, 0x5e, 0xb1, 0x9e, 0xd5, 0xf3, 0xd1, 0xed, + 0xd5, 0x09, 0xc0, 0xf2, 0x35, 0x9d, 0x57, 0x10, 0x04, 0x6f, 0xed, 0x39, + 0x1f, 0x24, 0x2f, 0x49, 0xf5, 0x2e, 0x54, 0xf7, 0x77, 0xc6, 0x22, 0x43, + 0x69, 0xad, 0xcf, 0xf0, 0x9c, 0xcc, 0x96, 0xd3, 0x58, 0x47, 0x89, 0x66, + 0xfb, 0xa3, 0x9a, 0x4f, 0xb2, 0x5e, 0xda, 0xee, 0x61, 0x85, 0x3e, 0x54, + 0x10, 0x28, 0x6f, 0xb5, 0xdc, 0xa0, 0xbe, 0xc2, 0xdc, 0xe5, 0xdf, 0xda, + 0x1c, 0x96, 0x5e, 0xc6, 0xb3, 0xc6, 0xa2, 0x43, 0xb1, 0x64, 0xbe, 0xec, + 0xe1, 0x77, 0x0b, 0xee, 0x3b, 0x60, 0xaf, 0xf8, 0xb0, 0x67, 0x24, 0xae, + 0x8c, 0x6c, 0x00, 0x2d, 0xf7, 0xe4, 0x94, 0x22, 0x6f, 0xba, 0xc9, 0xc9, + 0x72, 0x3c, 0x59, 0x2a, 0x7f, 0x96, 0xed, 0x51, 0xb7, 0x5e, 0x2c, 0xcf, + 0xc8, 0x86, 0xa7, 0x2a, 0x1c, 0x83, 0xfe, 0xef, 0x1b, 0x19, 0x23, 0x6a, + 0xfb, 0x66, 0x9f, 0x21, 0x5e, 0xa2, 0x74, 0xc9, 0xf1, 0x2f, 0x6d, 0x7d, + 0x13, 0xce, 0xef, 0xb3, 0x16, 0xee, 0xd5, 0xe3, 0xbe, 0xa0, 0xed, 0x97, + 0xd3, 0x15, 0xda, 0x8c, 0xdc, 0xdf, 0x49, 0x1d, 0x9f, 0x11, 0xc2, 0x11, + 0x04, 0xcf, 0xf9, 0x46, 0x77, 0x3f, 0x55, 0xe1, 0x1e, 0x47, 0x10, 0xfc, + 0x88, 0x76, 0xf1, 0xde, 0x22, 0xc6, 0x0b, 0x71, 0xb0, 0x35, 0x17, 0x85, + 0x5c, 0x9c, 0x1a, 0x20, 0x7e, 0x05, 0x1e, 0x6a, 0x8f, 0x7b, 0xa3, 0xc4, + 0x92, 0x9f, 0x2a, 0xb7, 0x24, 0x3f, 0x5d, 0x76, 0x81, 0x67, 0xce, 0x3b, + 0x9e, 0x9c, 0xb0, 0x73, 0xce, 0x96, 0x89, 0xdf, 0xd7, 0xda, 0x87, 0x7c, + 0x61, 0x85, 0xbf, 0x44, 0x98, 0xaa, 0xb0, 0x10, 0xb6, 0xa4, 0xc5, 0x4d, + 0x10, 0xfc, 0xd8, 0x37, 0x6b, 0x3a, 0x55, 0x94, 0x29, 0x8c, 0x9b, 0xdb, + 0xac, 0x88, 0x87, 0x58, 0xf2, 0x0e, 0x8c, 0xfd, 0x29, 0x8c, 0xbd, 0xbf, + 0xcc, 0xf1, 0x20, 0x2b, 0x30, 0xf7, 0xa9, 0x4a, 0x08, 0x6f, 0xbd, 0xb1, + 0xc3, 0x35, 0xef, 0xb5, 0x36, 0x5e, 0xf8, 0xac, 0x11, 0xd9, 0xae, 0xbc, + 0x7e, 0xd0, 0xd7, 0xe2, 0xa6, 0xa8, 0xfc, 0x22, 0xe4, 0x6e, 0x20, 0x8f, + 0x42, 0x9e, 0x2d, 0x6a, 0xba, 0xc9, 0x5c, 0xce, 0xff, 0x23, 0xf2, 0xeb, + 0xeb, 0x18, 0x5f, 0x1e, 0xf6, 0x68, 0xbb, 0x2e, 0x05, 0x8b, 0x1e, 0xe5, + 0xf3, 0x06, 0x99, 0x71, 0x73, 0xbd, 0xd0, 0x15, 0x28, 0x6b, 0xa5, 0xbf, + 0x9d, 0xcc, 0x44, 0x52, 0xc9, 0x49, 0x61, 0x3e, 0x14, 0x73, 0x15, 0x98, + 0x23, 0x44, 0xd9, 0x10, 0x85, 0xcc, 0xe3, 0x1a, 0x9a, 0xf1, 0x26, 0xcb, + 0xd5, 0xba, 0x07, 0x84, 0x7b, 0x86, 0xa9, 0xc4, 0x3e, 0x6d, 0x9f, 0x88, + 0x8c, 0x17, 0x58, 0x77, 0x3b, 0xac, 0x13, 0xaf, 0xa6, 0xbe, 0xce, 0xe1, + 0x02, 0x9f, 0x87, 0x71, 0xac, 0x58, 0x2c, 0x53, 0x90, 0x97, 0x23, 0x03, + 0xf2, 0x32, 0xed, 0xce, 0x61, 0xd0, 0xb6, 0xeb, 0xf1, 0xbd, 0x29, 0xcf, + 0xf8, 0xb2, 0x94, 0x19, 0xec, 0xa3, 0x9d, 0x9d, 0x53, 0x9a, 0x27, 0x44, + 0xa1, 0x6d, 0x2c, 0x5b, 0x96, 0x91, 0x6c, 0xc1, 0xc6, 0x7a, 0x46, 0x39, + 0xe7, 0x0d, 0x35, 0x73, 0x6f, 0x95, 0x28, 0x60, 0x1a, 0x89, 0x24, 0x9d, + 0x06, 0xef, 0x23, 0x2d, 0x46, 0xe7, 0x43, 0xee, 0xb7, 0xdd, 0xdf, 0xce, + 0x3d, 0x53, 0x05, 0x1f, 0x5a, 0xb5, 0xdf, 0x7e, 0x8d, 0x1a, 0xfa, 0xf3, + 0x04, 0xf4, 0xa0, 0x95, 0x95, 0xb1, 0x91, 0xae, 0x65, 0xfa, 0xe6, 0xf8, + 0xd2, 0x1e, 0xf1, 0x92, 0x23, 0xc3, 0x65, 0x51, 0x91, 0x21, 0x37, 0x36, + 0x5c, 0x5e, 0x49, 0xf3, 0x4f, 0x55, 0xfe, 0xbd, 0xb5, 0x05, 0x6b, 0x63, + 0xaa, 0xb5, 0xef, 0xc8, 0x77, 0x2b, 0xf6, 0x2b, 0x92, 0x26, 0x07, 0x86, + 0xfb, 0xb4, 0x5c, 0x93, 0xf4, 0x5b, 0x1b, 0xa0, 0x7c, 0x66, 0xb4, 0x8f, + 0xc6, 0x9c, 0x8b, 0x98, 0xcd, 0x3d, 0x33, 0xb8, 0x4e, 0x97, 0x1d, 0x99, + 0x82, 0x7c, 0x38, 0x20, 0x7f, 0x1f, 0xa4, 0xe3, 0xe6, 0xbd, 0x59, 0x5f, + 0xd6, 0xe7, 0x5e, 0x44, 0xb3, 0xe4, 0x4f, 0x46, 0x25, 0x77, 0x92, 0x7b, + 0x60, 0xcf, 0xed, 0xaf, 0xe6, 0x6d, 0x50, 0x0e, 0x70, 0xbf, 0xd6, 0x91, + 0x3c, 0xfc, 0xda, 0x11, 0xee, 0xc3, 0xf7, 0xff, 0x1f, 0xf4, 0xc1, 0x7a, + 0x61, 0xdb, 0x16, 0xb4, 0x6d, 0xb4, 0x6d, 0x47, 0xef, 0x78, 0x73, 0x6d, + 0x5b, 0xd1, 0x36, 0x16, 0x8e, 0xfb, 0x06, 0xdb, 0x6a, 0x7c, 0x5e, 0x33, + 0x5c, 0x28, 0x2e, 0xc1, 0x4f, 0x4e, 0x4c, 0x48, 0xda, 0x19, 0x1f, 0xd0, + 0xf3, 0xb9, 0x66, 0xb8, 0x0c, 0x38, 0xe2, 0x41, 0x90, 0xf7, 0x43, 0x3d, + 0xcc, 0x7f, 0xc7, 0x44, 0x3c, 0x96, 0x71, 0xdf, 0x92, 0xfe, 0x04, 0xa3, + 0xa4, 0x2e, 0xf3, 0xd9, 0x24, 0xcf, 0xfd, 0xc9, 0xf8, 0x46, 0xdc, 0x55, + 0x17, 0x71, 0x92, 0xf5, 0x18, 0xef, 0xdd, 0x68, 0xcb, 0x23, 0x2c, 0x4f, + 0x45, 0x21, 0x4b, 0x4c, 0x79, 0xc4, 0x96, 0x03, 0x26, 0x3f, 0x9f, 0x04, + 0xb7, 0xd9, 0x72, 0x3e, 0x2b, 0x5d, 0x6e, 0x9e, 0x0d, 0x0f, 0x8d, 0x09, + 0xe3, 0x3a, 0x99, 0xeb, 0x1a, 0x64, 0x2b, 0xd6, 0x87, 0x3e, 0xa3, 0x23, + 0xcd, 0x80, 0xe3, 0x9c, 0xff, 0x76, 0xd8, 0xd6, 0x81, 0xfc, 0xc0, 0x37, + 0xf4, 0x3f, 0x2b, 0x3d, 0x69, 0xe5, 0x30, 0x07, 0x20, 0x90, 0x9d, 0xfe, + 0xb6, 0xc4, 0x2e, 0xfc, 0x1e, 0xef, 0x4f, 0xca, 0xec, 0x20, 0xe8, 0xb1, + 0x9f, 0xbc, 0xb1, 0x15, 0x36, 0x0f, 0x7e, 0xf7, 0xb4, 0xc8, 0x92, 0x9b, + 0x73, 0xd7, 0xc1, 0x5f, 0x1b, 0xc1, 0xac, 0xe6, 0x0a, 0x9e, 0x7b, 0x1b, + 0x84, 0x5c, 0xda, 0xed, 0xc1, 0xbd, 0x76, 0xbe, 0xdf, 0xc2, 0x7c, 0x7f, + 0xad, 0x59, 0x9a, 0x59, 0x5e, 0x5b, 0xb7, 0x51, 0xf6, 0xb8, 0xdb, 0xdd, + 0xd8, 0x8a, 0xba, 0xe7, 0x51, 0x97, 0x65, 0x9e, 0xcb, 0x1c, 0x9d, 0xd9, + 0x32, 0xe9, 0xcc, 0xc0, 0xda, 0xd5, 0x13, 0x04, 0xd7, 0xf9, 0x1c, 0x37, + 0x08, 0xae, 0xf7, 0xfb, 0xdc, 0x67, 0xe5, 0xf9, 0xc0, 0xd8, 0x54, 0x21, + 0xed, 0x3c, 0x67, 0xe5, 0x75, 0x10, 0xbc, 0xec, 0xf7, 0xca, 0xef, 0x54, + 0x52, 0x8f, 0xd3, 0xe7, 0x3e, 0x83, 0xe7, 0x33, 0xbe, 0xc9, 0x2b, 0xfa, + 0x13, 0xb4, 0x8b, 0xab, 0x7e, 0xd0, 0xb0, 0x27, 0x5f, 0xd4, 0x3e, 0x3a, + 0xf1, 0x67, 0x62, 0xfc, 0x55, 0x18, 0x30, 0x61, 0x2f, 0xb3, 0xc9, 0x65, + 0x7e, 0xa0, 0xa6, 0xdf, 0xda, 0x77, 0x0a, 0xef, 0x58, 0x16, 0x04, 0x97, + 0x0c, 0xfc, 0x31, 0xe6, 0x94, 0x2a, 0x71, 0xef, 0xee, 0x03, 0x9a, 0xff, + 0x04, 0x7e, 0x3d, 0xe9, 0x24, 0xea, 0x2a, 0xe5, 0x1d, 0xee, 0x52, 0xa9, + 0x9c, 0xc8, 0x5b, 0xb0, 0xfe, 0x5c, 0x63, 0x30, 0x48, 0x1b, 0x60, 0xdf, + 0xb6, 0xbd, 0xd9, 0xc4, 0x92, 0xe8, 0x4b, 0xa7, 0x37, 0xc1, 0xd7, 0xd5, + 0xf6, 0x4c, 0x14, 0x7c, 0x3d, 0xd1, 0x16, 0x04, 0xef, 0xf7, 0xc3, 0x35, + 0xb3, 0xb1, 0x6a, 0xe8, 0xf8, 0x6c, 0xff, 0xb9, 0x66, 0x63, 0xc7, 0x31, + 0x4f, 0x30, 0xa9, 0xe3, 0xfa, 0xaa, 0x1d, 0x3a, 0x64, 0xdb, 0x57, 0x39, + 0x7e, 0x8e, 0xe5, 0xef, 0xf3, 0x43, 0x98, 0xaa, 0xed, 0xb3, 0xfd, 0xeb, + 0xac, 0xcd, 0x19, 0x05, 0x2e, 0x3d, 0xb7, 0x4b, 0xfd, 0x4d, 0x60, 0x74, + 0x6b, 0x48, 0xc3, 0x7f, 0x17, 0x3c, 0x18, 0x37, 0xcf, 0x99, 0x6d, 0xec, + 0x63, 0xab, 0x4c, 0x6e, 0xc3, 0x73, 0xf4, 0x5a, 0xdc, 0x87, 0x2f, 0x8b, + 0xc8, 0x15, 0x89, 0x61, 0xb5, 0xcd, 0x7d, 0x50, 0xfa, 0xac, 0x8c, 0xfb, + 0x1a, 0xf4, 0x7d, 0x0e, 0xfe, 0x78, 0x93, 0x3c, 0x08, 0x9a, 0x56, 0x03, + 0xa9, 0xe4, 0x82, 0x4a, 0xf5, 0xce, 0xa8, 0x94, 0x3f, 0xa6, 0xae, 0xe7, + 0xbc, 0x06, 0x89, 0x8b, 0x19, 0xe2, 0xb7, 0x08, 0xfc, 0x17, 0x81, 0xe3, + 0x8b, 0xee, 0xf1, 0xfa, 0x56, 0xb7, 0x18, 0xfd, 0x96, 0xd3, 0xb4, 0x69, + 0xec, 0xf2, 0x3f, 0xf6, 0xc3, 0x35, 0x84, 0x6d, 0xc8, 0x1c, 0x99, 0xba, + 0x6b, 0x94, 0xe5, 0x1a, 0x41, 0x31, 0xe4, 0x40, 0xf7, 0xa9, 0xe4, 0x84, + 0x5a, 0x0a, 0x36, 0xed, 0xe8, 0xee, 0x7d, 0x42, 0xf7, 0x93, 0xf2, 0xd3, + 0x2a, 0x0f, 0x78, 0xb6, 0x4a, 0xd3, 0x0e, 0xe2, 0x99, 0xb0, 0xc6, 0x18, + 0x4f, 0x72, 0xef, 0x40, 0xdd, 0x31, 0xa5, 0xf7, 0xa0, 0x6d, 0x1d, 0xc2, + 0x1c, 0x5f, 0x2f, 0xcd, 0xd4, 0x43, 0x8c, 0x93, 0xbd, 0x96, 0x2e, 0x84, + 0x4c, 0x3a, 0x46, 0x19, 0x18, 0x31, 0xb1, 0xdf, 0xca, 0xcf, 0xa1, 0x9d, + 0xce, 0x67, 0x89, 0x45, 0x21, 0xa3, 0xa6, 0xc0, 0xc5, 0x87, 0x8e, 0x49, + 0xb4, 0xc1, 0xfb, 0x5f, 0xcd, 0xc6, 0x6f, 0xa2, 0x0f, 0xc5, 0xb1, 0x1b, + 0x24, 0xbf, 0x26, 0xde, 0x52, 0x02, 0xfc, 0xcd, 0x32, 0x79, 0x8c, 0x6b, + 0x11, 0x85, 0xcc, 0xe1, 0xd8, 0x12, 0xcd, 0xf4, 0x07, 0xc1, 0x38, 0xcb, + 0x4f, 0x92, 0x7f, 0x25, 0xc5, 0x77, 0xb9, 0x93, 0x0b, 0x9b, 0xd4, 0x0a, + 0x59, 0xdb, 0x62, 0xe1, 0xd0, 0x78, 0x92, 0x92, 0x96, 0x23, 0xd4, 0x37, + 0xb7, 0xd5, 0xc0, 0x33, 0x7a, 0xc7, 0x94, 0xd7, 0xf8, 0x26, 0xe0, 0xf9, + 0x3d, 0xc0, 0xd3, 0x62, 0xe1, 0x69, 0x5c, 0x05, 0x4f, 0x4b, 0x08, 0x0f, + 0xe4, 0x1c, 0xe5, 0x6a, 0xec, 0x9a, 0x74, 0x59, 0x9c, 0xbc, 0x27, 0x9d, + 0x4a, 0xfb, 0x2f, 0xd4, 0x37, 0x8d, 0xee, 0xf8, 0x80, 0x2b, 0xe3, 0x5a, + 0xd7, 0x44, 0xaf, 0xe9, 0x2e, 0x2f, 0xc0, 0x7a, 0x15, 0x27, 0xe3, 0x11, + 0xf6, 0x7a, 0x76, 0xd5, 0x3d, 0x90, 0xff, 0x8b, 0xa9, 0xa8, 0xb5, 0x25, + 0x4a, 0x3e, 0xfd, 0x96, 0xb8, 0xde, 0xdb, 0xaf, 0xc2, 0xf4, 0x12, 0x60, + 0x82, 0x3c, 0x3e, 0xd6, 0xe7, 0x8e, 0xca, 0xa5, 0xda, 0x37, 0xb3, 0xb8, + 0xc6, 0xdc, 0x62, 0x35, 0x73, 0x83, 0xfe, 0x53, 0xe1, 0xdc, 0x20, 0x13, + 0x51, 0xaf, 0x24, 0xf7, 0x5b, 0x5c, 0xb4, 0x62, 0x4e, 0xb1, 0x9a, 0xf9, + 0x74, 0x27, 0xf6, 0xb3, 0xcc, 0xcc, 0xa7, 0x27, 0xef, 0xc5, 0x2c, 0x7e, + 0x57, 0xc3, 0x58, 0xf5, 0x17, 0x67, 0x24, 0x90, 0x29, 0x1f, 0x6b, 0xd4, + 0x4b, 0xff, 0x24, 0x66, 0xf3, 0x98, 0x15, 0x9e, 0x37, 0x58, 0xfe, 0x72, + 0x25, 0xaf, 0xfd, 0xb7, 0x2f, 0xad, 0x37, 0x7c, 0x1a, 0xb5, 0xf9, 0x6b, + 0xfc, 0xdd, 0xb1, 0xde, 0xee, 0xef, 0xe7, 0xd2, 0xf2, 0xfb, 0xeb, 0x69, + 0x97, 0x34, 0x78, 0x43, 0xab, 0xca, 0x62, 0x28, 0xbb, 0x7d, 0xbd, 0x95, + 0x0b, 0x28, 0xbb, 0x07, 0x7e, 0x1a, 0xf3, 0x34, 0xf8, 0x8e, 0x32, 0xb8, + 0x16, 0x27, 0x7d, 0x60, 0x45, 0xf2, 0x3c, 0xe5, 0x22, 0x6d, 0x4a, 0xcc, + 0x51, 0x7d, 0x27, 0x8c, 0xa3, 0xe3, 0x77, 0x3d, 0xdb, 0x9f, 0xf8, 0x26, + 0xae, 0xe5, 0xdb, 0x53, 0xe0, 0xfb, 0x03, 0xbe, 0x13, 0x9d, 0x65, 0x1e, + 0x80, 0xa6, 0xe1, 0xda, 0xbe, 0xaf, 0x47, 0xdf, 0x21, 0x2d, 0x93, 0x5e, + 0xae, 0xd7, 0x74, 0xd3, 0x44, 0x5d, 0x7c, 0x8c, 0xf4, 0xc7, 0x58, 0x72, + 0xb3, 0xd6, 0x8f, 0xd5, 0x75, 0x6c, 0x82, 0xae, 0x89, 0x1b, 0x1e, 0x75, + 0xcd, 0x7e, 0x77, 0xb5, 0xbf, 0x31, 0xf4, 0x47, 0x3b, 0x0d, 0x7e, 0xba, + 0xc7, 0x68, 0x0e, 0xe5, 0x97, 0x13, 0x55, 0x57, 0x6a, 0x3f, 0x33, 0xa6, + 0xf3, 0x8e, 0x96, 0xeb, 0x4e, 0xd8, 0xb1, 0x49, 0xb7, 0x26, 0xfe, 0x5f, + 0x1d, 0x5f, 0x1c, 0xb5, 0x4d, 0x40, 0x65, 0x8d, 0x32, 0x35, 0x40, 0x1a, + 0xe5, 0xdc, 0xb5, 0x0d, 0x75, 0x0d, 0xed, 0x08, 0x43, 0x9f, 0xb4, 0x9d, + 0xa2, 0xd7, 0x64, 0x0b, 0x8d, 0xc6, 0x67, 0x89, 0xcb, 0xe6, 0x06, 0x9d, + 0x47, 0x80, 0xb2, 0x72, 0xa8, 0xcb, 0xa2, 0x32, 0xdb, 0xff, 0xbf, 0x83, + 0xf4, 0x5e, 0xd6, 0xad, 0xbb, 0x6f, 0x9f, 0x98, 0x11, 0x8d, 0xa7, 0xbf, + 0xa8, 0xe2, 0xc9, 0xce, 0x2d, 0xbe, 0x7a, 0x6e, 0x05, 0xc0, 0x7b, 0x0f, + 0x64, 0x27, 0xd7, 0xc9, 0xe4, 0x6f, 0x3f, 0x2e, 0x4e, 0x34, 0xd3, 0x5b, + 0x6f, 0x6e, 0xa5, 0x10, 0xaf, 0x9c, 0x1b, 0x68, 0x35, 0x9c, 0x17, 0x69, + 0x3b, 0xae, 0xf7, 0x89, 0x94, 0x22, 0x2c, 0xad, 0xab, 0x70, 0x1b, 0xd2, + 0x9d, 0xa1, 0xb9, 0xa7, 0x34, 0xcd, 0xb5, 0x58, 0x9a, 0x43, 0x5d, 0x97, + 0xfb, 0xde, 0xa3, 0x2d, 0x55, 0x9a, 0xdb, 0x60, 0x69, 0xee, 0x99, 0xf5, + 0x66, 0x4f, 0xfc, 0xfd, 0x2d, 0x66, 0x4f, 0xea, 0x2f, 0x57, 0x3d, 0x6f, + 0xa2, 0xcd, 0x08, 0x5f, 0x2c, 0x7c, 0xae, 0x85, 0xf5, 0x0c, 0x60, 0xad, + 0x95, 0x35, 0x4d, 0x36, 0xee, 0xc6, 0xfd, 0x73, 0xfa, 0x7d, 0x51, 0x79, + 0x14, 0x76, 0x50, 0xbe, 0xfc, 0x8f, 0xc1, 0x02, 0x7c, 0xbf, 0xa9, 0x65, + 0xdd, 0x7b, 0x5b, 0x0b, 0xf9, 0x6d, 0x06, 0xbf, 0x0e, 0xd6, 0xf8, 0x3c, + 0x98, 0x2f, 0xca, 0xfe, 0x01, 0xeb, 0x01, 0xb9, 0xbc, 0x5c, 0x97, 0x31, + 0x0b, 0xe3, 0xe3, 0x30, 0x66, 0x68, 0xf6, 0x13, 0x29, 0xe7, 0xef, 0x84, + 0x4f, 0x74, 0x0f, 0xf4, 0x24, 0xe9, 0xfb, 0xa5, 0x16, 0x93, 0xe7, 0x1b, + 0x87, 0x1e, 0xfb, 0x65, 0x9b, 0x0b, 0x75, 0xf8, 0x57, 0xeb, 0xe7, 0xf8, + 0x82, 0xf6, 0x1d, 0xd2, 0xcc, 0xdf, 0xb7, 0x98, 0x98, 0xf1, 0xb7, 0x5a, + 0xc8, 0x67, 0x6a, 0xdb, 0x0f, 0x37, 0x68, 0xbe, 0x70, 0xc2, 0xe7, 0xcf, + 0xb4, 0xae, 0x7c, 0x0e, 0xdb, 0x3d, 0xd9, 0xba, 0xb2, 0x5d, 0x58, 0xfe, + 0x73, 0x1b, 0x57, 0x96, 0x5f, 0xe3, 0xae, 0x6c, 0xff, 0xf5, 0x55, 0xcf, + 0x2d, 0x9b, 0x56, 0x3e, 0x5f, 0xbd, 0xea, 0x79, 0x6a, 0xd5, 0xf3, 0x85, + 0x55, 0xcf, 0x57, 0xb5, 0xad, 0x7c, 0xbe, 0xbd, 0xad, 0x3e, 0xbc, 0x87, + 0xdb, 0x56, 0xc2, 0x75, 0xa7, 0x8e, 0xf7, 0xcf, 0x54, 0xa2, 0xb2, 0xab, + 0x80, 0xf7, 0x4e, 0xe7, 0x66, 0xa3, 0xd7, 0x6a, 0xdf, 0x33, 0xbe, 0xf6, + 0xd7, 0xab, 0xfa, 0xab, 0xb6, 0xdb, 0x5d, 0x6d, 0xe7, 0x57, 0xdb, 0x19, + 0xd9, 0x36, 0x5b, 0xe1, 0x3b, 0x96, 0x87, 0xfd, 0x9a, 0xb6, 0x53, 0xc5, + 0x4e, 0x9d, 0x0b, 0x3b, 0xaa, 0x73, 0x61, 0x93, 0xe0, 0xc3, 0x3b, 0x75, + 0x4c, 0x69, 0x93, 0x42, 0x79, 0xa5, 0x55, 0xc7, 0x95, 0x74, 0x2c, 0xb5, + 0x30, 0x0a, 0xdb, 0x96, 0x39, 0xb0, 0x81, 0xec, 0xf1, 0xcd, 0xdd, 0xe4, + 0xc4, 0x1e, 0x0e, 0x86, 0xdd, 0x20, 0x98, 0xf4, 0x6e, 0xb3, 0xf9, 0x62, + 0xb8, 0x57, 0x4c, 0x1b, 0xea, 0xe0, 0x27, 0xa0, 0x83, 0xab, 0xba, 0xf7, + 0x4e, 0x8c, 0xb5, 0x00, 0x9a, 0x19, 0x90, 0xdf, 0xad, 0xa4, 0xbe, 0x24, + 0xfa, 0xcc, 0x4d, 0x3f, 0x6c, 0xb8, 0xa5, 0x4f, 0xbd, 0xdf, 0xf3, 0x61, + 0xeb, 0x05, 0xf2, 0xb0, 0x3f, 0x08, 0x1a, 0xea, 0x85, 0xbd, 0xe7, 0x69, + 0xbf, 0xf4, 0xb4, 0xa6, 0x2d, 0xd2, 0x58, 0x8b, 0xce, 0xd7, 0x7f, 0xd4, + 0x77, 0x62, 0x99, 0xfe, 0x3f, 0x32, 0x71, 0x1a, 0xbf, 0xdb, 0xfd, 0x1a, + 0xf8, 0x76, 0xa7, 0xb7, 0x05, 0x3e, 0x0a, 0x69, 0x88, 0xf1, 0xaf, 0xcb, + 0x75, 0x1e, 0x21, 0x03, 0x68, 0x33, 0x51, 0xc6, 0x09, 0x53, 0x83, 0x63, + 0xc2, 0x79, 0xa7, 0x12, 0x49, 0xa5, 0xed, 0xaa, 0xe0, 0x46, 0x9f, 0x39, + 0xb6, 0xdc, 0x63, 0x21, 0x3f, 0xef, 0xff, 0xf4, 0x94, 0x97, 0x73, 0x23, + 0x36, 0x2f, 0x37, 0x53, 0x30, 0xb4, 0x39, 0x41, 0xda, 0x84, 0x3f, 0xb5, + 0xd8, 0xff, 0xb7, 0x01, 0xed, 0xfb, 0xa4, 0x22, 0xed, 0xff, 0x4d, 0x30, + 0x17, 0x65, 0x5f, 0x84, 0x7b, 0xff, 0xa7, 0x33, 0x1a, 0x57, 0x77, 0xca, + 0x81, 0x22, 0x6d, 0xe1, 0x98, 0xce, 0xe7, 0x18, 0xf7, 0x69, 0xa7, 0xc5, + 0x80, 0xc7, 0x0f, 0x01, 0x7f, 0x2d, 0xb0, 0xb9, 0x47, 0x50, 0x27, 0x22, + 0x63, 0x60, 0xf1, 0xd9, 0x02, 0xf9, 0x93, 0xf7, 0x28, 0xea, 0xbb, 0x32, + 0x5f, 0xb8, 0x59, 0xe7, 0xdb, 0x9d, 0x46, 0xdb, 0x27, 0x71, 0xcd, 0x16, + 0x26, 0xd0, 0x66, 0xaf, 0xae, 0x3f, 0x5b, 0x62, 0x8e, 0xb2, 0x40, 0x2e, + 0xed, 0x97, 0xfc, 0x5c, 0x97, 0x8c, 0xc5, 0x17, 0x66, 0xa2, 0xcb, 0x71, + 0x99, 0x8f, 0x6f, 0xe0, 0x1e, 0x47, 0xfe, 0x4a, 0xee, 0x07, 0x4b, 0x74, + 0x74, 0xbb, 0xea, 0x6d, 0xd3, 0x3e, 0xd7, 0xa0, 0xec, 0xac, 0x0c, 0xc9, + 0x4d, 0x95, 0xcf, 0x6e, 0x36, 0xb1, 0xa8, 0x15, 0xf1, 0xad, 0xc3, 0xc4, + 0x8a, 0x3a, 0x1a, 0xe5, 0xb9, 0x25, 0x99, 0x3d, 0x25, 0x12, 0x39, 0x1a, + 0xc6, 0x12, 0x59, 0xe6, 0x4a, 0xd7, 0x95, 0x80, 0xeb, 0x14, 0x64, 0x6b, + 0x3c, 0x26, 0x5f, 0xdc, 0x16, 0x8e, 0x95, 0x0b, 0xa6, 0xb7, 0xe5, 0xe4, + 0xd3, 0xb8, 0xb2, 0x57, 0xa6, 0x4a, 0x19, 0xc5, 0x71, 0xbf, 0x13, 0x50, + 0x96, 0xa9, 0x21, 0x4f, 0x72, 0x6d, 0xe1, 0xd8, 0xf0, 0x6f, 0x76, 0x84, + 0xe3, 0xd3, 0xe6, 0x36, 0x67, 0x1e, 0xf2, 0xdc, 0x77, 0x01, 0xfd, 0x45, + 0x86, 0xee, 0xde, 0x40, 0xdf, 0x61, 0x58, 0xd8, 0x0e, 0x32, 0x5d, 0xb1, + 0x6f, 0xc2, 0x49, 0xf8, 0x6b, 0xe1, 0x5c, 0x4c, 0xc6, 0x81, 0xa3, 0xdc, + 0xeb, 0xc2, 0xdb, 0xe7, 0x7a, 0xaa, 0x1e, 0xbc, 0xa3, 0x36, 0x96, 0xc8, + 0xf8, 0xe0, 0x3a, 0xe0, 0xad, 0x05, 0xe5, 0x1f, 0x94, 0xa9, 0x63, 0x6f, + 0xdb, 0xcc, 0xbd, 0xec, 0x06, 0xcf, 0xb1, 0x39, 0xa7, 0x3c, 0xbf, 0x73, + 0x37, 0xea, 0xf0, 0xfd, 0xcd, 0x68, 0x93, 0xca, 0x65, 0x22, 0x9b, 0xe1, + 0x13, 0x71, 0xdc, 0x20, 0xd2, 0xb5, 0xa3, 0x59, 0xe7, 0x90, 0xca, 0x29, + 0xea, 0xf3, 0xb0, 0xed, 0xdd, 0x3a, 0x47, 0x03, 0x7e, 0x7b, 0x6e, 0x24, + 0x42, 0xf9, 0xd5, 0x2b, 0xc3, 0xd4, 0x27, 0xa7, 0x6e, 0xd6, 0xb4, 0xdf, + 0xbd, 0x8d, 0x67, 0x99, 0xfa, 0x8c, 0x8d, 0x1e, 0x27, 0x8c, 0xa3, 0x28, + 0x87, 0xfd, 0xfe, 0x9a, 0x30, 0xdc, 0xf5, 0x26, 0x61, 0xb8, 0xeb, 0x4d, + 0xc2, 0x40, 0x5c, 0x00, 0x8e, 0xca, 0x5f, 0x6c, 0x08, 0x63, 0xd5, 0x97, + 0x62, 0x1e, 0x07, 0x8b, 0x77, 0xc9, 0xa1, 0xa2, 0xa3, 0xe3, 0x8e, 0x0b, + 0x8a, 0x32, 0xc1, 0x05, 0x4f, 0x82, 0xf7, 0x8a, 0xe0, 0xcd, 0x22, 0x78, + 0xb1, 0x08, 0xbe, 0x84, 0xfd, 0x7f, 0x06, 0xf6, 0xff, 0x93, 0x58, 0x9b, + 0xd3, 0x2b, 0x78, 0x39, 0xad, 0x79, 0x39, 0x5f, 0xa4, 0xaf, 0xd6, 0x7f, + 0x11, 0x7e, 0x8d, 0xca, 0x70, 0x21, 0x05, 0x55, 0xe2, 0x44, 0xb3, 0xfd, + 0x9f, 0x24, 0xbf, 0xca, 0x83, 0xfe, 0x0d, 0x68, 0x73, 0x18, 0x34, 0x9e, + 0xa2, 0x1d, 0x48, 0xfb, 0x27, 0x07, 0xde, 0x3c, 0x4c, 0x5f, 0x4d, 0x5d, + 0xb9, 0x49, 0xa8, 0x5f, 0xa2, 0x3b, 0x98, 0x7b, 0xc8, 0xb9, 0x26, 0x57, + 0xe1, 0xc9, 0xf0, 0xef, 0x84, 0x47, 0x3d, 0x43, 0xbe, 0x7d, 0x99, 0x7c, + 0x5b, 0xc3, 0xab, 0x01, 0xe7, 0x17, 0xb8, 0xdb, 0xea, 0xb5, 0xad, 0xd6, + 0xdf, 0xb4, 0x5c, 0x5f, 0x8f, 0x5f, 0x22, 0x3f, 0x42, 0x27, 0x11, 0xf7, + 0xc9, 0x4c, 0x64, 0x8b, 0xc5, 0x3d, 0x6c, 0xb7, 0x1d, 0x97, 0x00, 0xf7, + 0x9d, 0x92, 0x9b, 0x0f, 0xc4, 0xdb, 0x11, 0xf6, 0x59, 0xed, 0xc7, 0xb5, + 0xfd, 0x8c, 0x17, 0x1c, 0x19, 0xd9, 0xc6, 0x7d, 0x08, 0x07, 0x7a, 0x3e, + 0x5c, 0x0f, 0xd8, 0xfb, 0x7a, 0xcd, 0x29, 0x63, 0x29, 0x5b, 0x5b, 0x6c, + 0xfc, 0x89, 0xfd, 0x1d, 0x5e, 0xb5, 0x4e, 0x17, 0x02, 0x9e, 0x11, 0x9b, + 0xf2, 0x6e, 0xa8, 0xa1, 0x95, 0xfb, 0x2c, 0xad, 0xa8, 0x55, 0xf3, 0xb8, + 0xdd, 0xd2, 0x4a, 0x08, 0x6f, 0x3c, 0xa4, 0x95, 0xa6, 0x90, 0x56, 0x72, + 0x33, 0x21, 0xad, 0xb0, 0xed, 0xed, 0x21, 0xad, 0x24, 0x6b, 0x69, 0x25, + 0x37, 0xe3, 0xe0, 0x5a, 0x0d, 0x07, 0xe9, 0x85, 0xfd, 0x90, 0x5e, 0x00, + 0x4b, 0xe5, 0xd6, 0xd6, 0x90, 0x5e, 0xe2, 0xe8, 0xe7, 0x50, 0xd1, 0xe4, + 0x74, 0xc0, 0xef, 0xb2, 0x3a, 0xc4, 0xc5, 0x9a, 0x1b, 0x1f, 0xb1, 0x3e, + 0x8d, 0xf8, 0x96, 0x46, 0xaa, 0x79, 0xee, 0xab, 0x68, 0x03, 0xb8, 0x67, + 0x2e, 0xeb, 0x76, 0x4d, 0x1b, 0xf7, 0xfb, 0x53, 0xa8, 0xbb, 0x07, 0xb4, + 0x11, 0xe2, 0xe0, 0x7a, 0x8b, 0x83, 0xd5, 0x6b, 0x39, 0x66, 0x71, 0xb0, + 0xc7, 0xe2, 0x40, 0xf3, 0x4b, 0x8e, 0x6b, 0xa6, 0x34, 0x0e, 0x9a, 0x34, + 0x0e, 0x44, 0x85, 0x6d, 0xc7, 0xea, 0xe0, 0x80, 0x75, 0xf6, 0xe8, 0xf9, + 0x47, 0x30, 0xff, 0xfd, 0x98, 0xbf, 0xd2, 0xf3, 0xe7, 0x3a, 0x70, 0xfe, + 0x80, 0xa5, 0x72, 0x72, 0x79, 0xfe, 0x6d, 0xe8, 0xe3, 0x60, 0x31, 0xa2, + 0xe7, 0x0f, 0xdb, 0x7e, 0x30, 0x9c, 0xff, 0xe9, 0x8a, 0xc9, 0x7f, 0x3e, + 0xbd, 0x46, 0xcf, 0x4d, 0x59, 0xde, 0xf0, 0xb4, 0x5f, 0xcc, 0x98, 0xf6, + 0x19, 0xe8, 0xb6, 0x69, 0x3f, 0x69, 0xcf, 0x43, 0x19, 0x7b, 0xe9, 0x1b, + 0x3e, 0x79, 0xe7, 0xe3, 0x3a, 0x0f, 0xe5, 0x71, 0xda, 0x4d, 0xc5, 0x36, + 0x19, 0x99, 0xae, 0x85, 0x9b, 0xf0, 0xe6, 0xb4, 0x1c, 0xcd, 0x62, 0x7e, + 0xe3, 0x7e, 0x2f, 0xe4, 0x9b, 0xa6, 0x25, 0x94, 0xa7, 0x72, 0xc3, 0x91, + 0x26, 0x51, 0x0f, 0x7c, 0x08, 0x73, 0x8e, 0xca, 0x66, 0xaf, 0xdb, 0xdd, + 0xa1, 0xa8, 0x0b, 0x2f, 0xab, 0xd1, 0x85, 0xed, 0x56, 0x17, 0x6e, 0xa2, + 0x2e, 0x04, 0xdc, 0x77, 0xca, 0xe1, 0x22, 0xd7, 0x2f, 0x97, 0x6c, 0x82, + 0xfe, 0xff, 0x81, 0xc7, 0xb3, 0x27, 0x3a, 0x6e, 0x96, 0x38, 0xac, 0x69, + 0x99, 0x3a, 0x2d, 0xa5, 0xcf, 0x6a, 0x2c, 0xd2, 0xc6, 0x8e, 0x33, 0x16, + 0x4a, 0xbd, 0xf7, 0xe3, 0xe0, 0x73, 0x75, 0xf4, 0xde, 0x64, 0xd1, 0xd8, + 0x6f, 0x0d, 0xb0, 0x09, 0xe5, 0x44, 0x3b, 0xae, 0x8d, 0x3c, 0xab, 0xd0, + 0xdb, 0xa3, 0x9a, 0xa5, 0xe1, 0x44, 0xab, 0x4c, 0x4c, 0x1b, 0x1b, 0x57, + 0x9d, 0x00, 0xfe, 0x4f, 0x30, 0xdf, 0x55, 0x74, 0x7e, 0x7e, 0xb6, 0x04, + 0x3b, 0x77, 0xf6, 0x4e, 0x93, 0xb7, 0x32, 0xdd, 0xa0, 0x7f, 0xd3, 0x06, + 0xc9, 0xfb, 0x69, 0xe8, 0xbb, 0x98, 0x4c, 0xa0, 0xcf, 0xee, 0x6d, 0x8d, + 0x98, 0x73, 0x1c, 0x6d, 0xe9, 0xf3, 0x31, 0x8e, 0xd6, 0x28, 0xd1, 0xd9, + 0xb8, 0xce, 0xad, 0xe7, 0xd9, 0xd1, 0xcc, 0x60, 0x1b, 0xde, 0x31, 0x9f, + 0xc1, 0xc5, 0x58, 0xa1, 0xec, 0x47, 0xbf, 0x47, 0xc5, 0xee, 0xf7, 0x0c, + 0x69, 0xfd, 0x17, 0x39, 0xea, 0xda, 0x33, 0x74, 0x83, 0x58, 0xf7, 0x7a, + 0x7a, 0xd1, 0x18, 0xb9, 0x19, 0xac, 0x9f, 0x3a, 0x15, 0xc5, 0xbd, 0x13, + 0xf7, 0xb0, 0xbf, 0x50, 0x8f, 0x40, 0x37, 0xbe, 0xb3, 0x6f, 0xa3, 0x34, + 0x03, 0xdf, 0xb3, 0x0a, 0xb8, 0x36, 0x39, 0x59, 0x39, 0xcd, 0x0b, 0x55, + 0x7a, 0x78, 0xf2, 0x75, 0xf9, 0x81, 0x34, 0x41, 0x5a, 0xa0, 0x5c, 0x24, + 0x6d, 0x50, 0x26, 0x3a, 0xfa, 0x6c, 0x03, 0xe9, 0xe1, 0x09, 0xdf, 0x8b, + 0x70, 0xdf, 0xde, 0xc4, 0xe5, 0x49, 0x1b, 0xa4, 0xf9, 0xa4, 0x8e, 0xd7, + 0xa7, 0xe5, 0x7b, 0x92, 0x6e, 0xeb, 0x86, 0x5d, 0xf6, 0x2f, 0xbb, 0xc6, + 0xe6, 0xdc, 0xad, 0xa6, 0x39, 0xe8, 0x26, 0xe6, 0xd0, 0xf5, 0xca, 0xfb, + 0x2a, 0x39, 0xe0, 0xe1, 0x5e, 0x28, 0xe5, 0x3b, 0x75, 0x5e, 0xe2, 0xee, + 0xc2, 0x46, 0xb9, 0xc5, 0x8f, 0xd9, 0xb8, 0xfb, 0x41, 0xd0, 0xc1, 0xa2, + 0x23, 0x27, 0xce, 0xe2, 0x3a, 0xe7, 0x70, 0xfd, 0xce, 0xfb, 0xe9, 0x94, + 0x22, 0xb3, 0x7b, 0xd1, 0xc4, 0xa2, 0xf4, 0xb9, 0x13, 0xfa, 0x0c, 0xc8, + 0x82, 0xd3, 0x74, 0xe2, 0xd0, 0x46, 0xe3, 0x4b, 0x03, 0x16, 0xaf, 0xd1, + 0x1d, 0xa1, 0x2d, 0xe7, 0x07, 0x41, 0x96, 0x76, 0x83, 0x28, 0xed, 0x23, + 0xc1, 0xe7, 0x43, 0x19, 0xe3, 0x13, 0x5b, 0x9d, 0xc6, 0x53, 0x2f, 0x5a, + 0x5a, 0x91, 0x88, 0x1a, 0x7a, 0xc6, 0x69, 0x38, 0x71, 0x9c, 0x6b, 0xa6, + 0xf3, 0xa4, 0x0d, 0x5d, 0x3d, 0xe7, 0x54, 0xe9, 0xea, 0x1b, 0xf6, 0xb7, + 0x1a, 0x6a, 0x92, 0x74, 0xaa, 0x09, 0xf3, 0x1d, 0x2e, 0x84, 0x30, 0x7e, + 0x1f, 0x70, 0x11, 0x1e, 0xd0, 0xed, 0xec, 0x9f, 0xe1, 0x5a, 0x02, 0x2c, + 0xf7, 0x01, 0xee, 0xf3, 0x80, 0xf9, 0x02, 0x2e, 0xd5, 0x11, 0x91, 0x3f, + 0x76, 0x22, 0xb3, 0xb5, 0xf0, 0x12, 0xc6, 0xd3, 0x16, 0xde, 0xd7, 0x82, + 0xd5, 0x95, 0xc5, 0x81, 0x2e, 0xc0, 0x43, 0x38, 0x5f, 0x02, 0x8c, 0xb4, + 0x5b, 0x9f, 0xc7, 0xb3, 0x0b, 0xf8, 0x5e, 0xb0, 0x30, 0x81, 0x1e, 0xa7, + 0xff, 0x47, 0xf5, 0x77, 0x81, 0x76, 0xf4, 0x9f, 0xdb, 0xe7, 0xce, 0x55, + 0x32, 0xa0, 0xc7, 0x21, 0x9e, 0xa7, 0x8a, 0x4b, 0xb4, 0x03, 0xc0, 0xf7, + 0x3f, 0x94, 0xc8, 0xa9, 0x84, 0x1c, 0x2a, 0x70, 0x0f, 0xe8, 0x24, 0xf0, + 0xa1, 0xcf, 0xa4, 0xa0, 0xce, 0x15, 0xb8, 0xa0, 0xec, 0x67, 0xb7, 0xe3, + 0xea, 0xc5, 0xf5, 0x56, 0x5c, 0x20, 0x87, 0xd9, 0x13, 0xb8, 0xfa, 0xd0, + 0xb7, 0x8a, 0x37, 0x09, 0x73, 0xa9, 0xbe, 0x8d, 0x36, 0xda, 0xb6, 0xcc, + 0xa9, 0xa1, 0x01, 0xe0, 0x6f, 0x00, 0xb0, 0x25, 0x70, 0x31, 0xff, 0xf8, + 0x87, 0x8e, 0x9c, 0x7a, 0x19, 0x17, 0x18, 0xec, 0x14, 0x08, 0xf3, 0xd4, + 0x20, 0x2e, 0x28, 0xb1, 0x53, 0x69, 0x5c, 0x23, 0xb8, 0xfe, 0xd2, 0x31, + 0x3c, 0xd7, 0x09, 0x7c, 0x85, 0x3c, 0x02, 0x9c, 0xaf, 0xe0, 0xb9, 0xaf, + 0x3b, 0x6f, 0x9c, 0xe7, 0x7e, 0xe2, 0x18, 0x9e, 0x7b, 0xc5, 0xa9, 0xf2, + 0xdc, 0x59, 0x47, 0x3d, 0xfc, 0x8c, 0x13, 0x79, 0x98, 0xbe, 0xc4, 0x59, + 0xc7, 0xf0, 0x7f, 0x44, 0x86, 0xf7, 0x82, 0x96, 0x1e, 0x5e, 0xc0, 0x45, + 0xba, 0x7a, 0x16, 0xe5, 0x2f, 0xac, 0x1a, 0xf7, 0xf9, 0x37, 0x31, 0xee, + 0xab, 0x76, 0x5c, 0x51, 0xd5, 0x71, 0x2f, 0xa0, 0xef, 0x97, 0xec, 0xb8, + 0x17, 0x6a, 0xc6, 0x05, 0xad, 0x3c, 0xbc, 0x84, 0x8b, 0x74, 0xf1, 0x22, + 0xca, 0x43, 0x99, 0x80, 0x85, 0x6e, 0x6e, 0xd0, 0x67, 0x9d, 0xe2, 0x5e, + 0xc3, 0xb2, 0x6e, 0x4c, 0xd7, 0xe8, 0x87, 0x37, 0xa2, 0x1f, 0x27, 0x8b, + 0xb4, 0x11, 0x17, 0x6a, 0xe4, 0x02, 0x7d, 0xa3, 0x40, 0x8e, 0x69, 0x3f, + 0x88, 0x3e, 0x11, 0xfd, 0xa3, 0xd5, 0xb6, 0xd5, 0x27, 0x75, 0xee, 0xd8, + 0xaf, 0x15, 0x3a, 0xe5, 0xd3, 0x05, 0xda, 0x84, 0xa4, 0x97, 0x20, 0x98, + 0xd8, 0x41, 0xfb, 0x34, 0x17, 0x5c, 0xe2, 0x91, 0x4e, 0x3c, 0xf7, 0x33, + 0x6b, 0x75, 0x46, 0x69, 0x18, 0xbe, 0x7b, 0xe6, 0xe8, 0xaf, 0x40, 0x67, + 0x34, 0x00, 0x6e, 0xd2, 0x5b, 0x87, 0xdc, 0x58, 0x52, 0x53, 0x9b, 0x25, + 0x21, 0x37, 0x15, 0x1a, 0x61, 0xf7, 0x30, 0xaf, 0xaa, 0x59, 0xba, 0x77, + 0xc4, 0x4c, 0xde, 0xb7, 0x1b, 0xc7, 0x6f, 0xd7, 0xe4, 0xa1, 0xc7, 0x13, + 0x78, 0xff, 0x7b, 0x2e, 0xe5, 0x60, 0xdc, 0xbb, 0x56, 0xe7, 0xf4, 0x74, + 0xed, 0xa0, 0xdd, 0x72, 0xbd, 0xd6, 0xe1, 0xd1, 0x35, 0x76, 0x92, 0xea, + 0x70, 0xa5, 0x6a, 0xa3, 0x8d, 0x17, 0x52, 0x49, 0xc2, 0xf5, 0x90, 0x70, + 0xff, 0xeb, 0x1e, 0xc9, 0xfb, 0xad, 0xf0, 0x0b, 0x18, 0x3b, 0x4f, 0xf5, + 0xd2, 0x36, 0x9a, 0x9d, 0x76, 0x6d, 0x5e, 0xf4, 0x46, 0x79, 0x4e, 0x8f, + 0xd3, 0xa8, 0x61, 0x34, 0x67, 0x25, 0xb8, 0x8f, 0x10, 0xd3, 0xe7, 0x73, + 0x66, 0xcb, 0x2d, 0x5a, 0xef, 0xcc, 0x96, 0x99, 0x87, 0x0f, 0x7f, 0xaa, + 0xcc, 0xbc, 0x7b, 0x5f, 0xdc, 0x77, 0xc2, 0xcf, 0x2d, 0x6f, 0x91, 0xf1, + 0xe9, 0x75, 0xd2, 0xe8, 0xa9, 0xf8, 0x66, 0xc8, 0x47, 0xb6, 0xe9, 0xda, + 0x01, 0xff, 0x70, 0x66, 0xab, 0x3c, 0x39, 0xc3, 0xbe, 0x3b, 0x64, 0x6e, + 0x5e, 0x1c, 0xf7, 0x9d, 0xeb, 0x51, 0x07, 0x72, 0x7d, 0x07, 0xcb, 0x92, + 0xb8, 0x8b, 0x72, 0xdf, 0x19, 0x95, 0x73, 0x03, 0x7c, 0x66, 0xee, 0xbf, + 0x44, 0xd9, 0xdf, 0xb9, 0x81, 0x4e, 0x79, 0x7c, 0x1e, 0x34, 0x01, 0xb9, + 0x3f, 0x72, 0x82, 0x30, 0x89, 0xec, 0x9a, 0x65, 0x2c, 0xbd, 0xdb, 0x65, + 0xdc, 0x94, 0xfb, 0x34, 0xb7, 0x0c, 0x70, 0x2c, 0xe8, 0x25, 0xe8, 0xb8, + 0xae, 0x1d, 0x46, 0x16, 0xa4, 0x67, 0x1b, 0x50, 0xce, 0x7e, 0xe1, 0x3f, + 0xee, 0x65, 0x3f, 0x61, 0x5b, 0x85, 0x39, 0x35, 0x6a, 0x7a, 0x59, 0x5a, + 0xa5, 0x3f, 0xce, 0xfc, 0x4c, 0xf6, 0x37, 0xfb, 0xe8, 0xd5, 0x7b, 0x21, + 0xdc, 0x53, 0x36, 0xb6, 0x15, 0xd7, 0x44, 0xef, 0x29, 0xc0, 0xae, 0xba, + 0x42, 0xdb, 0x17, 0x73, 0x15, 0xae, 0x20, 0x63, 0x51, 0xe1, 0x1a, 0x25, + 0xe4, 0xd1, 0xe2, 0xf2, 0x3a, 0x6d, 0x69, 0x58, 0xb9, 0x4e, 0xa4, 0x15, + 0x7f, 0xcc, 0xda, 0x1e, 0x8b, 0x92, 0x83, 0x5d, 0xd6, 0xab, 0xd7, 0x6c, + 0x11, 0xb6, 0xac, 0x5d, 0x33, 0x6d, 0xcf, 0xe6, 0xc3, 0x35, 0x1b, 0x85, + 0xc6, 0x29, 0xab, 0x4d, 0x5c, 0x33, 0x97, 0xf1, 0x6e, 0xe0, 0x3d, 0x87, + 0x75, 0xca, 0x61, 0x8d, 0x72, 0xe5, 0x0e, 0x99, 0x3d, 0xa6, 0x3a, 0x1b, + 0x44, 0x92, 0xe3, 0x5e, 0x87, 0x4c, 0xce, 0x33, 0x96, 0xb0, 0x05, 0x36, + 0xd8, 0x56, 0x5c, 0x9d, 0x78, 0x66, 0x3b, 0xf0, 0x54, 0x59, 0xa1, 0x6d, + 0xd3, 0x1a, 0x3b, 0xeb, 0x71, 0x8c, 0xcd, 0x1c, 0xe1, 0x27, 0x80, 0x87, + 0x2a, 0xef, 0x4c, 0xd5, 0xc4, 0x9f, 0x38, 0x57, 0xad, 0x43, 0x31, 0xdf, + 0xb8, 0x5e, 0x4f, 0x1d, 0x87, 0x2a, 0x36, 0xbe, 0x19, 0x7b, 0x2a, 0x41, + 0x7b, 0x2a, 0x5b, 0x72, 0xcd, 0xf9, 0x80, 0x51, 0xf8, 0x4e, 0x5e, 0xef, + 0x26, 0xd2, 0xfa, 0xd8, 0x0c, 0xe1, 0x8a, 0x85, 0x70, 0xad, 0x58, 0x33, + 0x9e, 0xe7, 0x5a, 0x1b, 0xe7, 0x98, 0x5a, 0xce, 0x5f, 0x34, 0xb1, 0x7d, + 0xc6, 0x51, 0x3a, 0xeb, 0xc0, 0x74, 0xa7, 0xb6, 0x61, 0x45, 0x8d, 0xc9, + 0x81, 0x22, 0xcf, 0x82, 0x31, 0x9e, 0x78, 0x23, 0xe3, 0x49, 0xbd, 0xb3, + 0xf2, 0x5e, 0x8c, 0xcd, 0x5c, 0x1d, 0x65, 0xe3, 0x37, 0x1b, 0x6c, 0x8e, + 0x48, 0x6d, 0x0c, 0xc7, 0xe4, 0xf2, 0xac, 0xcc, 0x8b, 0x4e, 0x8d, 0x2e, + 0x61, 0x9d, 0x7f, 0x5d, 0xef, 0x0d, 0x4a, 0x29, 0x02, 0xed, 0x37, 0x3e, + 0x90, 0x1a, 0x34, 0xe7, 0x60, 0x92, 0xb2, 0xb3, 0x68, 0xe6, 0x7f, 0x5e, + 0xe7, 0xf4, 0x98, 0xdc, 0x45, 0x93, 0xef, 0x73, 0x8f, 0x9c, 0x87, 0x0e, + 0xaf, 0xae, 0x6d, 0x93, 0x4c, 0x02, 0x17, 0x59, 0xbd, 0x2f, 0x91, 0x94, + 0xec, 0xc0, 0xc7, 0x37, 0xf1, 0x9c, 0x44, 0x0c, 0xeb, 0x93, 0x9f, 0xe1, + 0xd9, 0x49, 0xf6, 0x7b, 0xb1, 0xbe, 0x28, 0x66, 0x99, 0x87, 0x0f, 0x59, + 0xf9, 0xb6, 0xbe, 0x44, 0xb3, 0x7e, 0xbf, 0xce, 0xe6, 0x5b, 0x3b, 0x22, + 0x37, 0x06, 0xf2, 0x87, 0x10, 0x9f, 0x8f, 0xd9, 0x39, 0x25, 0x75, 0xcc, + 0x4a, 0x82, 0x73, 0x7e, 0xc2, 0xc6, 0x2c, 0x39, 0x97, 0x1b, 0x2c, 0x7d, + 0x1b, 0xfb, 0xa7, 0x6a, 0x43, 0x9b, 0x7d, 0xbf, 0x27, 0xb5, 0x2c, 0xec, + 0xb7, 0xb6, 0xb3, 0x8e, 0xf3, 0x1c, 0x17, 0x9d, 0x13, 0x10, 0xfa, 0x46, + 0x3d, 0x35, 0x7e, 0x81, 0xf1, 0xe5, 0xf2, 0xd3, 0xf5, 0x64, 0x54, 0xd5, + 0x27, 0xa4, 0x2f, 0x37, 0xb1, 0x8d, 0xdf, 0x2d, 0x08, 0x7d, 0xb9, 0x7e, + 0xeb, 0xcb, 0xb5, 0x6a, 0x5f, 0xce, 0xc4, 0x1e, 0x5a, 0x97, 0x7d, 0xb9, + 0xfc, 0x74, 0x0e, 0xb4, 0x12, 0x7e, 0x67, 0xc1, 0xd8, 0x42, 0x93, 0x05, + 0x9e, 0x79, 0x69, 0x94, 0xec, 0xa8, 0x82, 0xdf, 0x60, 0x7c, 0x2c, 0xc6, + 0x2a, 0x94, 0xfa, 0x96, 0xf5, 0x2f, 0x3a, 0x25, 0xdd, 0xbe, 0x0e, 0xf3, + 0xbe, 0x53, 0xaf, 0xf9, 0x5c, 0xc1, 0xec, 0x7d, 0x66, 0xf7, 0x32, 0x26, + 0xc4, 0x73, 0x4d, 0x9a, 0xbf, 0x92, 0xc3, 0x91, 0x5e, 0x63, 0xcf, 0x7a, + 0xdf, 0x04, 0xde, 0x4f, 0x02, 0xe7, 0x31, 0x3b, 0x6e, 0x12, 0x30, 0x1d, + 0xc0, 0xda, 0x5c, 0x6b, 0x65, 0x32, 0xc7, 0xde, 0xd3, 0xc4, 0xd8, 0xc0, + 0x7c, 0x21, 0x8c, 0x11, 0x46, 0xec, 0x99, 0x4a, 0x2f, 0xd2, 0xe8, 0xad, + 0xab, 0x6b, 0xab, 0x9e, 0x7e, 0x5d, 0xdd, 0x44, 0x5a, 0xba, 0x53, 0xe7, + 0xb9, 0xac, 0x1f, 0x48, 0xed, 0xd1, 0x39, 0xf2, 0x3a, 0xc6, 0x98, 0x13, + 0xe6, 0x94, 0x7d, 0x57, 0xde, 0xa1, 0x65, 0xfe, 0x01, 0x9f, 0xfa, 0x6b, + 0x87, 0xfe, 0xdd, 0x38, 0x14, 0x04, 0xe7, 0x06, 0xee, 0x86, 0xad, 0xe2, + 0xb9, 0xdf, 0x97, 0xee, 0xc4, 0xb0, 0xb6, 0x9d, 0xb0, 0x46, 0x7b, 0x9b, + 0x65, 0x9d, 0x77, 0xb3, 0xcd, 0x99, 0xc9, 0x41, 0x6e, 0xa6, 0x60, 0x33, + 0xf1, 0x4c, 0x70, 0x8f, 0x7d, 0x97, 0x0b, 0x9a, 0x41, 0x47, 0x1f, 0x13, + 0x23, 0x63, 0xb2, 0x55, 0x19, 0xc3, 0x5c, 0x83, 0x34, 0x09, 0x39, 0x7a, + 0x44, 0x52, 0xfc, 0xee, 0x07, 0xc7, 0xce, 0xcb, 0xa5, 0xd0, 0xcb, 0x6c, + 0xa7, 0xbf, 0xd9, 0x83, 0x67, 0xee, 0xe1, 0x78, 0xee, 0x41, 0xe8, 0x96, + 0xeb, 0xd7, 0xea, 0x96, 0x04, 0xfd, 0xfa, 0x6c, 0x89, 0xbe, 0xe1, 0x7a, + 0xb4, 0xe9, 0x90, 0x8f, 0x4f, 0x77, 0xb7, 0x91, 0xb7, 0xc6, 0x20, 0xd7, + 0xd5, 0xfd, 0xe1, 0x59, 0x20, 0x96, 0xf1, 0x3d, 0xfb, 0x6d, 0x92, 0xe4, + 0xfb, 0x5d, 0xf9, 0x7c, 0x25, 0x95, 0x5c, 0x82, 0x6e, 0x1a, 0x73, 0x7e, + 0xf1, 0x72, 0x13, 0x53, 0x7d, 0x7b, 0x9b, 0x39, 0x3b, 0xd0, 0x4c, 0x9b, + 0xdd, 0xc6, 0x59, 0x6b, 0x69, 0x76, 0xc9, 0xca, 0xe3, 0x20, 0x68, 0x1e, + 0xd0, 0x32, 0x78, 0x0f, 0x65, 0xf0, 0x01, 0xbf, 0xc7, 0xd0, 0xbe, 0xf6, + 0x99, 0x02, 0xac, 0x23, 0xf0, 0x30, 0x10, 0x65, 0x7e, 0x9e, 0xe5, 0x4f, + 0x2f, 0xbd, 0x68, 0xe5, 0x92, 0x72, 0xd6, 0xf2, 0xa5, 0xba, 0x2a, 0xb6, + 0x42, 0xe6, 0x1e, 0x9a, 0xa6, 0x3e, 0xf6, 0x17, 0xbe, 0x0b, 0x39, 0x95, + 0xd5, 0x78, 0xe8, 0x90, 0xfb, 0xa6, 0x25, 0x7d, 0x1e, 0xba, 0x2a, 0x3f, + 0xbf, 0x92, 0x37, 0xd7, 0xf6, 0xc7, 0xb9, 0x7e, 0xb8, 0xcd, 0xf8, 0xb6, + 0x2b, 0xe7, 0xba, 0x80, 0xb9, 0xa6, 0xf5, 0x5c, 0xb9, 0x6f, 0xf3, 0x31, + 0x3b, 0xd7, 0xf5, 0xe1, 0x5c, 0x07, 0x57, 0xce, 0x35, 0xf4, 0xed, 0x43, + 0xb9, 0x9b, 0xd4, 0xf9, 0xf2, 0x3a, 0x4f, 0x7b, 0x7a, 0xbd, 0x0c, 0x97, + 0x5a, 0xad, 0xbc, 0x74, 0xa1, 0x7b, 0x98, 0xc3, 0xbe, 0x70, 0xaf, 0x2b, + 0x16, 0x67, 0x8a, 0x78, 0xa0, 0xac, 0x6d, 0xd3, 0x67, 0x6c, 0x66, 0xe1, + 0x5f, 0xdd, 0x5a, 0x60, 0xdd, 0xf0, 0xfd, 0xc5, 0x62, 0xc7, 0xa1, 0x4f, + 0x4d, 0xbf, 0xa9, 0x77, 0x4d, 0x4c, 0xc1, 0xc4, 0x87, 0x19, 0x17, 0x36, + 0x67, 0x7f, 0x99, 0x8b, 0x78, 0x07, 0x78, 0xea, 0x53, 0x85, 0xd4, 0x60, + 0x26, 0x42, 0x39, 0x7a, 0x5c, 0x0e, 0x55, 0x46, 0xa4, 0x4b, 0x9f, 0xff, + 0x7c, 0xdd, 0xd8, 0x71, 0xba, 0x36, 0x76, 0xcc, 0x74, 0x02, 0xc6, 0x8e, + 0xf7, 0xfc, 0x0c, 0xb1, 0x63, 0x71, 0x4c, 0xec, 0xb8, 0x9e, 0x7f, 0x35, + 0x55, 0x3c, 0x8e, 0x79, 0x35, 0x43, 0x96, 0x2c, 0x3a, 0xd9, 0xf9, 0x16, + 0xdc, 0xcf, 0xe2, 0x1e, 0xc3, 0xfd, 0x3c, 0xee, 0x2e, 0xee, 0x17, 0x70, + 0x8f, 0xcb, 0xd4, 0xb2, 0xce, 0x38, 0x0e, 0xb9, 0x41, 0x5d, 0xc6, 0xb6, + 0xc6, 0x1f, 0x98, 0x2b, 0xb7, 0xf3, 0x7b, 0x2d, 0xce, 0xec, 0x3c, 0xe7, + 0xd0, 0x2a, 0x93, 0xd3, 0x94, 0xd9, 0x6d, 0x52, 0x9a, 0x0e, 0x6d, 0xdb, + 0x9f, 0xef, 0xe0, 0x9e, 0xc1, 0x98, 0x84, 0xb6, 0xeb, 0x3d, 0x1d, 0x66, + 0xaf, 0xf1, 0x3b, 0x58, 0xe3, 0x8d, 0x58, 0x83, 0x93, 0x72, 0x7e, 0x66, + 0xe3, 0x0a, 0x1b, 0x36, 0x69, 0x63, 0x82, 0x33, 0x56, 0xf7, 0xd6, 0x97, + 0x11, 0xb5, 0xeb, 0x9f, 0xb0, 0x67, 0xcb, 0xc2, 0x1c, 0xa1, 0xa4, 0x5e, + 0x9f, 0xd1, 0xca, 0x71, 0x8c, 0x37, 0x28, 0xe9, 0x19, 0xce, 0x73, 0xf9, + 0x9b, 0x11, 0x90, 0x87, 0x27, 0xa0, 0x57, 0x57, 0xd0, 0x25, 0xe8, 0x96, + 0x73, 0x73, 0x40, 0xbb, 0x8f, 0xca, 0x6c, 0x89, 0xf0, 0xf5, 0x24, 0x22, + 0xfa, 0xac, 0x19, 0x9e, 0x67, 0x4c, 0x8e, 0xfb, 0x70, 0x25, 0x3c, 0x67, + 0xb6, 0x89, 0x67, 0x07, 0x57, 0x9d, 0x35, 0xb3, 0xfa, 0x59, 0xdb, 0x0e, + 0x3c, 0x73, 0x16, 0xce, 0xa1, 0x1e, 0x3d, 0x05, 0x32, 0xa9, 0xf3, 0xce, + 0x36, 0xcb, 0x63, 0x0f, 0x2e, 0xe7, 0xbc, 0xb6, 0xc1, 0x46, 0xe9, 0x84, + 0x89, 0x3c, 0x1a, 0x1d, 0xea, 0x81, 0x8f, 0xc7, 0x3c, 0x99, 0x9e, 0xc4, + 0x6d, 0x3a, 0x17, 0xb9, 0x7a, 0xee, 0xaf, 0x9a, 0x8f, 0x1c, 0x9e, 0xb3, + 0x4a, 0xe8, 0xef, 0x5a, 0xec, 0xd4, 0xe5, 0x71, 0xcc, 0x87, 0xfb, 0x7e, + 0x1a, 0x0f, 0x09, 0x7e, 0xa7, 0xeb, 0x29, 0xe0, 0x60, 0xb2, 0xf2, 0x6d, + 0xd0, 0xbb, 0x63, 0xcf, 0x9c, 0x91, 0xc6, 0x06, 0x64, 0xa2, 0x9c, 0x70, + 0x26, 0xca, 0x03, 0xce, 0xbe, 0xb2, 0x7d, 0x37, 0xb0, 0x67, 0xb3, 0x34, + 0xe3, 0xf7, 0x4c, 0x97, 0x33, 0x06, 0x7c, 0xe5, 0x8b, 0xdd, 0x4e, 0x5a, + 0xdf, 0x3d, 0x7b, 0x87, 0x1c, 0xc0, 0x5a, 0x0d, 0xcf, 0xc4, 0xb5, 0x9c, + 0xaf, 0x7e, 0x5b, 0x2a, 0x5c, 0x57, 0x7e, 0x13, 0x89, 0x7c, 0x7c, 0x5c, + 0x7f, 0xe7, 0xc8, 0xd8, 0x0e, 0x27, 0xd1, 0xdf, 0x71, 0x1b, 0x13, 0xef, + 0x73, 0xb2, 0xba, 0x1f, 0xb3, 0x1e, 0xf9, 0xe2, 0x09, 0xdc, 0x57, 0x9f, + 0x79, 0x0e, 0xf5, 0x8c, 0x85, 0xbb, 0x10, 0xdc, 0x63, 0xe4, 0xd5, 0x71, + 0x99, 0xaa, 0x30, 0x7f, 0xc4, 0xd1, 0x7c, 0x34, 0x59, 0x3e, 0x00, 0x9d, + 0xb4, 0xf2, 0xcc, 0xdf, 0xce, 0xea, 0x3a, 0x24, 0x67, 0x84, 0xb0, 0x70, + 0x0d, 0x56, 0x9e, 0x87, 0xbf, 0xf8, 0xbf, 0x70, 0x5f, 0xd1, 0xc8, 0x50, + 0x0b, 0x47, 0x9a, 0xf2, 0xce, 0xc8, 0x95, 0x69, 0x39, 0x08, 0x78, 0x0e, + 0xe3, 0x52, 0xf7, 0xf3, 0x3b, 0x2c, 0xf3, 0x92, 0x9f, 0xbb, 0x4f, 0xd4, + 0x43, 0xe7, 0x9d, 0xe8, 0x43, 0x07, 0x25, 0xf2, 0xd0, 0xa2, 0xd3, 0xf0, + 0x50, 0xb7, 0xf6, 0xcb, 0x77, 0xfb, 0xdd, 0x89, 0x7d, 0x72, 0x52, 0xa2, + 0xf7, 0x2b, 0x7d, 0xfe, 0x2b, 0xef, 0x32, 0xc6, 0x77, 0x52, 0x22, 0xf7, + 0xc7, 0xec, 0xd9, 0x51, 0x13, 0xd7, 0x5b, 0xd2, 0x7c, 0xff, 0x9b, 0x71, + 0xe2, 0x6c, 0x49, 0x8e, 0x6b, 0xde, 0x19, 0x86, 0x9e, 0xc8, 0x94, 0x92, + 0xcb, 0x75, 0x4c, 0xbe, 0xe7, 0xf3, 0x9b, 0x0d, 0xbf, 0xb0, 0x4e, 0x8f, + 0xc3, 0xef, 0x38, 0x18, 0x9d, 0x91, 0xb9, 0x2c, 0xcc, 0xfd, 0x34, 0x6b, + 0xca, 0xf7, 0x67, 0xb1, 0x86, 0x3d, 0x58, 0x2f, 0x8e, 0xe7, 0xe8, 0xfd, + 0x5c, 0x9e, 0x9d, 0x75, 0xa5, 0x2f, 0xd1, 0xb4, 0x6c, 0x07, 0xb1, 0xee, + 0x7d, 0xd2, 0x04, 0xb8, 0xd5, 0x43, 0x79, 0x63, 0xd7, 0x09, 0xe9, 0x54, + 0x20, 0xb9, 0x49, 0xb3, 0x3d, 0x83, 0xbb, 0xf5, 0x1a, 0xde, 0x6b, 0x69, + 0x66, 0x9d, 0xb1, 0x1f, 0xf1, 0x6c, 0xe8, 0x22, 0x2f, 0xbb, 0xa6, 0x7f, + 0x08, 0x3d, 0xcf, 0x7d, 0x17, 0x6d, 0x2f, 0xd6, 0xb1, 0x05, 0xc9, 0x4b, + 0xcf, 0x58, 0xbf, 0x32, 0x08, 0xa6, 0x7d, 0x1f, 0x78, 0xac, 0xe7, 0x4b, + 0x6e, 0x71, 0xe6, 0x4a, 0x5b, 0x9d, 0xd9, 0x52, 0x20, 0x13, 0x3e, 0xbf, + 0xe3, 0xc1, 0x1c, 0x00, 0xda, 0x5b, 0x2c, 0xeb, 0x86, 0x6e, 0xfd, 0xeb, + 0xcd, 0x3c, 0x8f, 0x74, 0x93, 0xf7, 0xa2, 0x98, 0x7a, 0xc4, 0x31, 0x7d, + 0xe4, 0xee, 0xe3, 0x59, 0xe1, 0xf7, 0x34, 0xfa, 0x12, 0x71, 0xfd, 0x5d, + 0x8f, 0xcf, 0xa1, 0x1d, 0xc6, 0x28, 0x72, 0xdc, 0x67, 0x9d, 0x59, 0xc8, + 0xb3, 0xb9, 0x69, 0x9e, 0xe1, 0x67, 0x3e, 0x6d, 0xa4, 0x53, 0xc9, 0x15, + 0xee, 0xa4, 0xfd, 0x06, 0x5c, 0x0e, 0x2e, 0x50, 0x44, 0x97, 0xf5, 0xb9, + 0xe3, 0xcb, 0xdf, 0x85, 0x0b, 0xcb, 0xc2, 0xef, 0xc3, 0x29, 0x9d, 0x3b, + 0x0d, 0x5f, 0xf6, 0xb1, 0x31, 0xf9, 0x89, 0x33, 0x5f, 0x78, 0xc5, 0x79, + 0xb4, 0x90, 0xbe, 0xea, 0x12, 0xd0, 0xc7, 0x39, 0xbf, 0x97, 0xf2, 0x0b, + 0x36, 0x5f, 0x41, 0x72, 0x95, 0x09, 0x99, 0xe9, 0xe8, 0x76, 0xef, 0xd7, + 0x6b, 0x33, 0x03, 0x9c, 0x7d, 0x1b, 0xeb, 0xf7, 0xc9, 0x38, 0xf5, 0xdb, + 0x78, 0x41, 0x81, 0x97, 0xd5, 0xcf, 0xe3, 0x82, 0x6d, 0xdb, 0xa8, 0x6d, + 0x94, 0x7d, 0x3e, 0xeb, 0x6d, 0x75, 0x86, 0x4b, 0x5b, 0xb0, 0x8e, 0x7b, + 0xa1, 0x3f, 0x1d, 0xd8, 0x69, 0xa0, 0x6d, 0x94, 0x4d, 0x02, 0x07, 0xe3, + 0xbe, 0x91, 0xe7, 0xc3, 0x92, 0xd3, 0x3e, 0x9e, 0xb9, 0xa7, 0x95, 0x89, + 0x99, 0x05, 0xc1, 0x1c, 0xec, 0x83, 0x6c, 0x7f, 0x09, 0xbc, 0xf0, 0x08, + 0xae, 0xb7, 0xdb, 0x3d, 0xed, 0x17, 0x2e, 0xb2, 0xa7, 0xed, 0xca, 0xc9, + 0x8a, 0x3e, 0xd7, 0xae, 0xf3, 0xab, 0x92, 0xea, 0xbf, 0x5f, 0xa2, 0xd7, + 0x4a, 0xf5, 0xe8, 0x9c, 0xb4, 0xb4, 0x7c, 0x38, 0x6e, 0xf4, 0x30, 0x61, + 0x4a, 0x02, 0x9e, 0xad, 0xc0, 0x05, 0xe1, 0x31, 0x6d, 0x44, 0x6d, 0xba, + 0x94, 0xfa, 0x70, 0x49, 0x3e, 0x12, 0x0f, 0xcf, 0x14, 0xa0, 0x1f, 0xc8, + 0xb8, 0x8f, 0x5d, 0x6a, 0xf4, 0xe4, 0xe6, 0x3a, 0xfd, 0x84, 0x73, 0x73, + 0xec, 0xdc, 0x48, 0xb7, 0x7f, 0x96, 0xa0, 0x4f, 0xb1, 0x24, 0x4d, 0xab, + 0xea, 0x33, 0xa6, 0xbf, 0xe1, 0x72, 0x73, 0x46, 0x81, 0x75, 0x5d, 0xd8, + 0xa6, 0xb4, 0x73, 0x89, 0x47, 0xbd, 0x6e, 0x05, 0x25, 0x3c, 0x67, 0x00, + 0x6e, 0xae, 0x5c, 0xe1, 0xbe, 0x43, 0x91, 0x0e, 0x43, 0x5c, 0x7f, 0x5b, + 0xf3, 0xc9, 0x78, 0x81, 0xb1, 0x95, 0x47, 0x83, 0xf4, 0x28, 0x79, 0x8c, + 0x7d, 0xf0, 0x7d, 0x41, 0xc7, 0x73, 0xf7, 0xfa, 0x8c, 0x15, 0x75, 0x1f, + 0xbf, 0x43, 0x85, 0x72, 0x0a, 0xfa, 0xb7, 0xb8, 0xe8, 0xf0, 0x1b, 0x78, + 0x37, 0x0a, 0xee, 0xf3, 0x8b, 0xce, 0x77, 0xa7, 0x9f, 0xc5, 0x73, 0x83, + 0xfd, 0xee, 0x9d, 0xd1, 0x53, 0x22, 0xc5, 0x70, 0xbe, 0x89, 0x1c, 0xd6, + 0xfe, 0x02, 0xd6, 0xbe, 0xfe, 0x77, 0xee, 0xf0, 0xae, 0x8c, 0x77, 0xe5, + 0x0f, 0x07, 0xe9, 0x36, 0xd2, 0x22, 0xe9, 0xef, 0xb5, 0xfc, 0xe6, 0x41, + 0xcd, 0x17, 0x93, 0xc5, 0xc7, 0xc1, 0x17, 0x69, 0xee, 0x37, 0x07, 0x0f, + 0xfb, 0x37, 0x80, 0x2f, 0xf6, 0xc8, 0xef, 0xc3, 0x2e, 0xf8, 0xdd, 0xca, + 0x10, 0xf8, 0x63, 0x10, 0xfc, 0x32, 0x00, 0x1e, 0xf1, 0xb5, 0x8d, 0xfc, + 0x04, 0xf4, 0x1f, 0xf4, 0x9a, 0xb3, 0xaf, 0xd4, 0xe5, 0x64, 0x4b, 0x9e, + 0x33, 0x51, 0xe2, 0xf7, 0x5a, 0xd4, 0x5b, 0x1b, 0x24, 0x9a, 0x98, 0x13, + 0xf2, 0x42, 0x37, 0x73, 0x1c, 0xdb, 0x81, 0xab, 0x53, 0xc4, 0xd5, 0x5c, + 0xa5, 0xcf, 0xbd, 0x04, 0x3c, 0xd1, 0xae, 0x79, 0xa2, 0xd5, 0x49, 0xbb, + 0x37, 0x58, 0x9e, 0x78, 0x11, 0x3c, 0x71, 0x7e, 0x0d, 0x4f, 0x3c, 0x6d, + 0xe9, 0x7f, 0xa1, 0x86, 0x27, 0xe6, 0x6c, 0xd9, 0xcc, 0x45, 0x78, 0xe2, + 0x52, 0x2f, 0xf5, 0xa5, 0x31, 0x79, 0x15, 0x3c, 0x21, 0x8a, 0x3c, 0x71, + 0xa9, 0xe6, 0x09, 0xc6, 0x8e, 0xc8, 0x17, 0x9d, 0x90, 0x23, 0xe4, 0x8b, + 0xb3, 0xb2, 0x04, 0xbe, 0x78, 0x5e, 0x71, 0xec, 0x19, 0xda, 0x0a, 0x25, + 0xfa, 0x64, 0x27, 0x8a, 0x5d, 0xe0, 0x77, 0x25, 0xff, 0x65, 0x3a, 0x08, + 0x16, 0xe1, 0xa7, 0x3f, 0x08, 0x7b, 0x3e, 0xaa, 0xbf, 0xa9, 0xb8, 0x00, + 0xba, 0x0f, 0xe9, 0x7d, 0xc2, 0x01, 0xbd, 0x1f, 0x9e, 0xc5, 0x1c, 0x26, + 0xd4, 0x7f, 0x86, 0x2f, 0xec, 0x62, 0x5d, 0x69, 0xe7, 0x1f, 0xd3, 0x3c, + 0xd4, 0x00, 0x7d, 0xf0, 0xe8, 0x00, 0x63, 0x4d, 0x9e, 0xbb, 0x4f, 0x75, + 0xe7, 0x46, 0x00, 0x73, 0x44, 0xdd, 0x2f, 0x8c, 0x73, 0xb4, 0xad, 0xb2, + 0xf3, 0x29, 0x23, 0x46, 0x21, 0xeb, 0xcc, 0xbb, 0x5c, 0xd0, 0x04, 0x9b, + 0xb4, 0x49, 0x19, 0x1b, 0x5d, 0xed, 0x48, 0xb9, 0x1f, 0x84, 0x00, 0x6d, + 0x84, 0xbd, 0xb0, 0x0b, 0xab, 0x3d, 0x52, 0xa8, 0xb5, 0xf1, 0xff, 0x03, + 0x6c, 0x7c, 0xb6, 0x91, 0xa8, 0xb1, 0xf1, 0x7f, 0xcd, 0xf2, 0x1a, 0x7f, + 0xbb, 0xda, 0xde, 0x3f, 0x00, 0xf8, 0x76, 0x2f, 0xdb, 0xfb, 0xec, 0x83, + 0x76, 0x87, 0xc8, 0xf5, 0xb0, 0xf9, 0xde, 0x0d, 0x1e, 0xbc, 0x01, 0xbe, + 0xd4, 0x7b, 0x0a, 0xae, 0xec, 0x29, 0xb4, 0xc3, 0xe7, 0xee, 0x94, 0xf7, + 0x4e, 0x6f, 0x95, 0x9d, 0x25, 0xff, 0x12, 0x69, 0xee, 0x80, 0x8d, 0x5a, + 0x00, 0x9c, 0x11, 0x2b, 0xb7, 0xcf, 0x02, 0x6f, 0xdd, 0xc9, 0x9f, 0xa8, + 0x17, 0xad, 0x5d, 0xc4, 0xb3, 0x8e, 0xf5, 0xfa, 0x89, 0xa3, 0x3d, 0x63, + 0x29, 0x1d, 0x72, 0xea, 0x18, 0xbd, 0xaf, 0x24, 0xec, 0x72, 0x1f, 0x36, + 0xc9, 0x16, 0xf4, 0xc7, 0x78, 0xf2, 0x46, 0x79, 0xfa, 0xaa, 0xe8, 0x5d, + 0x59, 0xcd, 0x87, 0x9d, 0x4e, 0x66, 0x1a, 0x3e, 0xc0, 0xde, 0x18, 0xe6, + 0xa0, 0xda, 0x37, 0xcb, 0x75, 0xb2, 0x53, 0xcf, 0x67, 0x46, 0x0e, 0x42, + 0x37, 0xff, 0x41, 0x61, 0xa7, 0x2c, 0x8d, 0xb6, 0xe1, 0x39, 0x26, 0x4f, + 0x17, 0xfa, 0xe0, 0xfb, 0xbc, 0x0b, 0x38, 0x6a, 0xc4, 0x73, 0xa3, 0x0c, + 0x5f, 0x42, 0x5e, 0x6d, 0x91, 0x45, 0x94, 0xbf, 0x5b, 0x7e, 0xc1, 0x96, + 0xb3, 0x8c, 0xbc, 0xd1, 0x82, 0xb6, 0x31, 0x39, 0x57, 0xa0, 0x5d, 0xa9, + 0x79, 0x62, 0xf0, 0x7b, 0xd2, 0x97, 0xfe, 0x1e, 0xec, 0xd4, 0xb3, 0xb8, + 0x9e, 0x91, 0xd4, 0x9e, 0x71, 0xa7, 0x2f, 0xd9, 0xed, 0x40, 0x77, 0xe2, + 0x8a, 0x3a, 0x7d, 0x6e, 0xa3, 0x73, 0x85, 0xed, 0xa3, 0x41, 0x9e, 0xd9, + 0xab, 0x12, 0x2d, 0x58, 0x93, 0xed, 0x4e, 0x8f, 0x2d, 0xe3, 0x73, 0xca, + 0x78, 0x40, 0xa7, 0xd4, 0x96, 0x0d, 0x22, 0x5d, 0x2d, 0xb0, 0x79, 0x26, + 0x44, 0xb5, 0xb7, 0x48, 0x54, 0xba, 0x67, 0x55, 0x27, 0xca, 0x3c, 0x5b, + 0x16, 0x6f, 0x81, 0x7e, 0x40, 0x59, 0x07, 0xca, 0xb6, 0xd9, 0xb2, 0xb6, + 0x16, 0x69, 0x44, 0xd9, 0x8c, 0xe6, 0xf9, 0xf3, 0x3d, 0x9e, 0x9b, 0x75, + 0x9a, 0xa5, 0xeb, 0x44, 0x0b, 0x64, 0xc3, 0x46, 0x59, 0xbc, 0xaa, 0x49, + 0xba, 0xf0, 0x8e, 0x71, 0x6e, 0xff, 0x44, 0x4c, 0xae, 0x3d, 0xd1, 0x9d, + 0xf8, 0x38, 0xe6, 0xd0, 0x7d, 0x8a, 0x71, 0xef, 0xfc, 0x25, 0x8c, 0xfb, + 0x74, 0x9d, 0xe2, 0xbd, 0x49, 0xcb, 0x1f, 0xe2, 0xc3, 0x7c, 0x93, 0x88, + 0x32, 0xf9, 0x24, 0xfc, 0x5c, 0xea, 0xf0, 0x6e, 0xfb, 0xfd, 0x8c, 0xe3, + 0x97, 0xd0, 0x6f, 0x9b, 0xa5, 0x5d, 0x52, 0x24, 0x3f, 0x52, 0x0f, 0xe1, + 0x3e, 0xe3, 0x48, 0xbe, 0x2a, 0xb3, 0xe6, 0xc9, 0x57, 0xc7, 0x14, 0x73, + 0x59, 0x50, 0x56, 0xf9, 0xc5, 0xc0, 0xac, 0x31, 0x79, 0xc1, 0xc8, 0xa5, + 0x0f, 0x18, 0xb9, 0xf4, 0xd8, 0x99, 0x15, 0x72, 0xe9, 0xbc, 0x96, 0x4b, + 0x7b, 0x05, 0xf7, 0xf9, 0xf3, 0x90, 0x4b, 0x2f, 0xe2, 0xd9, 0xd5, 0x72, + 0x29, 0x2e, 0xd6, 0x5e, 0x96, 0xaf, 0xea, 0xf1, 0xe7, 0x8a, 0x51, 0x6d, + 0x57, 0xe5, 0x67, 0x60, 0x93, 0x14, 0xa7, 0xac, 0xfe, 0x96, 0xa1, 0x36, + 0xe9, 0x19, 0xfc, 0xa9, 0x84, 0x36, 0xe7, 0x7f, 0xba, 0x84, 0xdf, 0xee, + 0x7c, 0x5e, 0x51, 0x86, 0xbd, 0x0a, 0x19, 0x26, 0xaa, 0xbe, 0x0c, 0xc3, + 0xbb, 0x32, 0xde, 0x95, 0xd9, 0xef, 0x8f, 0x7e, 0x3a, 0xe6, 0x52, 0x7e, + 0x50, 0x66, 0x40, 0x26, 0x15, 0x21, 0x93, 0x8a, 0x90, 0x53, 0x45, 0xc8, + 0x25, 0xd8, 0x6c, 0x67, 0x8a, 0x90, 0x4b, 0x45, 0xc8, 0x25, 0xc8, 0xb8, + 0x27, 0x20, 0xe3, 0x8c, 0x4c, 0x1b, 0x85, 0x4c, 0x9b, 0x91, 0xfb, 0xac, + 0xae, 0x37, 0xb1, 0x92, 0x7e, 0xeb, 0x23, 0x0d, 0xe8, 0x18, 0xf2, 0x99, + 0x9a, 0xd8, 0xe0, 0x8d, 0x47, 0x34, 0xbf, 0xbb, 0x9e, 0xba, 0xc2, 0x61, + 0x0e, 0xcd, 0x4f, 0xb4, 0xff, 0xbe, 0x9d, 0xbf, 0xa5, 0x09, 0x7c, 0xfd, + 0x03, 0xcb, 0xd7, 0xdb, 0x97, 0xf9, 0x3a, 0xe5, 0x30, 0x56, 0x5c, 0x9f, + 0xaf, 0x3b, 0xec, 0xbb, 0x5c, 0xb0, 0x0e, 0x7c, 0xbd, 0x6e, 0x15, 0x5f, + 0xc7, 0xc0, 0xd7, 0x7b, 0xd6, 0xf0, 0xf5, 0x06, 0x67, 0x58, 0xb7, 0xe1, + 0x19, 0x09, 0x3e, 0x37, 0x3a, 0x55, 0xbe, 0xbe, 0x47, 0xf3, 0xf5, 0x21, + 0xf0, 0xf5, 0x75, 0x35, 0x7c, 0xbd, 0x47, 0x52, 0x37, 0x67, 0x22, 0x5b, + 0x65, 0xfc, 0x7e, 0xd5, 0xbe, 0x49, 0xfe, 0x49, 0x4c, 0x7b, 0xc3, 0x63, + 0xc3, 0xd3, 0xed, 0x92, 0x7d, 0xe8, 0x15, 0x94, 0x91, 0xcf, 0x52, 0x63, + 0x69, 0xc7, 0x95, 0x83, 0x47, 0x7e, 0x22, 0x0b, 0x9a, 0xb7, 0x44, 0x26, + 0x8e, 0xc4, 0x64, 0xf2, 0x08, 0xe3, 0x10, 0x7f, 0x63, 0xe9, 0xbd, 0x49, + 0x26, 0xf7, 0x32, 0x6f, 0x2e, 0x2a, 0xe3, 0x47, 0xe0, 0x6f, 0x1d, 0x61, + 0x1c, 0xe2, 0xa5, 0x65, 0x1e, 0x5b, 0x80, 0x6c, 0x19, 0x3f, 0xc2, 0xb5, + 0x8e, 0xa1, 0x9f, 0x16, 0x39, 0x74, 0x44, 0xe4, 0xb6, 0x23, 0x51, 0xf9, + 0xe8, 0x91, 0x65, 0x5e, 0x1b, 0x0d, 0x79, 0xed, 0x59, 0xf0, 0x5a, 0xb7, + 0xe5, 0x35, 0xb5, 0xcc, 0x6b, 0x7f, 0x5a, 0xc3, 0x6b, 0x6c, 0x4f, 0x5e, + 0x7b, 0xce, 0x96, 0xf1, 0x39, 0x2a, 0xfb, 0x8e, 0x74, 0xca, 0xf8, 0x43, + 0x6f, 0x91, 0x89, 0xfb, 0x09, 0xab, 0xf9, 0x8e, 0x13, 0x6d, 0xb1, 0x99, + 0x4a, 0x37, 0xfa, 0x0f, 0x73, 0x88, 0xf4, 0xf7, 0x10, 0x7a, 0x67, 0x25, + 0x95, 0xe3, 0x78, 0x8d, 0xf0, 0xa3, 0x4f, 0xc0, 0xbf, 0xd8, 0x07, 0x98, + 0x6e, 0x39, 0x22, 0xa9, 0xa8, 0xbc, 0x2c, 0x53, 0xfe, 0x27, 0x2e, 0x37, + 0xf6, 0x04, 0x6c, 0x11, 0x6d, 0xfb, 0xa4, 0x25, 0xfb, 0xce, 0x40, 0xfb, + 0x18, 0xa5, 0xb2, 0x30, 0x16, 0xc0, 0xb8, 0xb9, 0x63, 0xbe, 0xc7, 0xc4, + 0xfc, 0xc7, 0x06, 0x7d, 0xe6, 0x45, 0xc7, 0x6c, 0x07, 0xf8, 0x9e, 0xcf, + 0xb0, 0x67, 0xf4, 0x59, 0x43, 0xb6, 0x7f, 0x44, 0x7f, 0x1b, 0x91, 0x31, + 0xf5, 0x7c, 0x99, 0xdf, 0xb0, 0x81, 0xff, 0x59, 0xe6, 0xb7, 0xb0, 0xf6, + 0xb7, 0x9b, 0xf8, 0x2c, 0xf9, 0xee, 0x87, 0x0e, 0xbf, 0x5d, 0x35, 0xa5, + 0x73, 0xbd, 0xf0, 0xbb, 0xcc, 0x67, 0xd6, 0x7f, 0x84, 0xf1, 0x8e, 0x64, + 0x52, 0xbd, 0xf7, 0x72, 0xe6, 0x1e, 0xec, 0x9d, 0x67, 0xdd, 0xad, 0x96, + 0x47, 0xb7, 0x6a, 0xbf, 0x83, 0x36, 0xd6, 0x78, 0xe9, 0x45, 0xc9, 0xd3, + 0x36, 0x19, 0xdd, 0xea, 0xe4, 0x66, 0x92, 0x97, 0x1b, 0xfb, 0x79, 0xdd, + 0xa5, 0xcc, 0x3b, 0x4c, 0xab, 0xb5, 0x32, 0xf9, 0x84, 0x84, 0x32, 0x39, + 0x75, 0x33, 0xbf, 0xb7, 0x9b, 0x3d, 0xa2, 0xbf, 0x2f, 0x95, 0xec, 0x56, + 0x9c, 0xd3, 0xa7, 0x21, 0x5f, 0x43, 0x5a, 0x48, 0xc8, 0x27, 0x8f, 0x90, + 0x1e, 0x54, 0xbc, 0x55, 0x3e, 0x61, 0xe9, 0x61, 0x46, 0x0a, 0x90, 0x3b, + 0x47, 0x8e, 0x7c, 0x54, 0x66, 0x6e, 0x5c, 0x4d, 0x0f, 0x13, 0x55, 0x7a, + 0x88, 0xc3, 0x3e, 0x73, 0x6a, 0xe9, 0xe1, 0x97, 0x97, 0xe9, 0x61, 0xc6, + 0xf9, 0xe7, 0xd2, 0xc3, 0xf5, 0x2b, 0xe8, 0x61, 0x4a, 0xd3, 0xc3, 0xce, + 0x65, 0x7a, 0x98, 0x3a, 0xc2, 0x71, 0xf5, 0xde, 0xa8, 0xbb, 0xe8, 0x70, + 0xcd, 0x97, 0x69, 0x21, 0x39, 0xa9, 0xf3, 0xf5, 0x53, 0x39, 0x9e, 0x6f, + 0xda, 0xa0, 0x18, 0x27, 0xa9, 0xae, 0x7f, 0xeb, 0xbf, 0xe8, 0xfa, 0xbf, + 0xfc, 0xff, 0x79, 0xfd, 0xd5, 0xa5, 0xcc, 0xdd, 0xe7, 0x99, 0x55, 0x23, + 0x8f, 0x43, 0x7a, 0x88, 0x5d, 0x6a, 0xf4, 0x02, 0xd7, 0x98, 0xcf, 0x90, + 0x67, 0x90, 0x7f, 0x67, 0x20, 0xff, 0x9e, 0x84, 0xfc, 0x3b, 0xbd, 0x62, + 0x4f, 0x60, 0xd0, 0xc6, 0x23, 0x02, 0x39, 0xe8, 0x57, 0xf1, 0xb1, 0x38, + 0x40, 0x7c, 0x98, 0xfc, 0x13, 0xe6, 0xfe, 0xae, 0xc4, 0x49, 0x54, 0xe7, + 0x1c, 0x3d, 0xea, 0xd7, 0xe2, 0x84, 0x70, 0xbf, 0x5c, 0x33, 0x47, 0xfc, + 0x2e, 0xf3, 0x79, 0x46, 0xe7, 0x91, 0xe4, 0xf5, 0x1e, 0x14, 0xf1, 0xc2, + 0x3d, 0x28, 0xe2, 0x24, 0xaa, 0xed, 0xfd, 0x7c, 0xb9, 0x49, 0xe7, 0xd0, + 0x1f, 0x98, 0x8f, 0xcb, 0x62, 0x9c, 0x31, 0x3e, 0x7e, 0x97, 0x90, 0x7e, + 0xb3, 0x97, 0xc8, 0x4b, 0x8e, 0xb9, 0x72, 0xe0, 0xe9, 0x0d, 0x96, 0xb6, + 0x19, 0x1b, 0xe4, 0x99, 0xdd, 0x70, 0x2f, 0xa2, 0xd7, 0xca, 0xba, 0x96, + 0x9a, 0x98, 0x25, 0xf0, 0x3e, 0x2d, 0xc9, 0xcc, 0x00, 0xee, 0xf3, 0x1c, + 0x7b, 0xbf, 0x4c, 0x3d, 0x38, 0x01, 0x5b, 0x6e, 0x2f, 0x74, 0x0e, 0xcf, + 0x9f, 0x99, 0xef, 0x70, 0x13, 0x86, 0x59, 0xfd, 0xdd, 0x29, 0xfa, 0x80, + 0xa4, 0x87, 0x04, 0x9e, 0x67, 0x6c, 0x5c, 0x29, 0x21, 0xf9, 0xc2, 0x05, + 0xf3, 0x6d, 0xcb, 0xc2, 0x4b, 0xb8, 0xbf, 0xde, 0x7a, 0x18, 0x3f, 0x64, + 0xd4, 0xdc, 0xd1, 0xd7, 0x92, 0xa4, 0xcb, 0x26, 0xc7, 0xa5, 0x1a, 0x37, + 0x99, 0x91, 0xc3, 0xda, 0x7e, 0x1e, 0xb2, 0xb9, 0x2d, 0xa9, 0xd1, 0x9c, + 0x18, 0x1b, 0xfa, 0x77, 0x60, 0x43, 0x7f, 0xb1, 0x92, 0xd6, 0xfb, 0x58, + 0xa7, 0x61, 0x43, 0x3f, 0x01, 0xdd, 0x43, 0x9d, 0x13, 0xb7, 0x3a, 0x67, + 0x4a, 0xdd, 0xa8, 0x75, 0xce, 0x37, 0xb5, 0xce, 0x79, 0xef, 0x1a, 0x9d, + 0x73, 0x48, 0x75, 0x97, 0xa8, 0x73, 0x86, 0xd5, 0x1e, 0x87, 0xf6, 0xe2, + 0xe6, 0x3a, 0x3a, 0xe7, 0x7d, 0xf2, 0x2e, 0xfb, 0xee, 0x1e, 0x79, 0xff, + 0x0e, 0xbd, 0x77, 0xe3, 0xce, 0x2a, 0x7e, 0x6b, 0xc9, 0xe8, 0xa0, 0xeb, + 0x54, 0xaf, 0xde, 0xf3, 0xfd, 0x46, 0x8d, 0xce, 0xe9, 0x52, 0x03, 0xce, + 0xb0, 0x6e, 0xc3, 0xd8, 0x04, 0x9f, 0x7d, 0x27, 0x3d, 0xda, 0x84, 0xe7, + 0x84, 0x44, 0x8e, 0x60, 0xee, 0xe6, 0x7b, 0x50, 0xca, 0xbc, 0x7b, 0xab, + 0x7d, 0xa7, 0xc2, 0xf2, 0xa8, 0x29, 0xef, 0xb6, 0xe5, 0x46, 0x57, 0x75, + 0xa9, 0x4e, 0xad, 0xab, 0xb6, 0x83, 0xa1, 0x66, 0xa1, 0x5f, 0x67, 0x8b, + 0xa1, 0xce, 0xe2, 0x6f, 0xc6, 0x9e, 0x19, 0xa3, 0x08, 0x63, 0xd8, 0x49, + 0xd4, 0xc1, 0x55, 0x0c, 0x6d, 0x4a, 0xfe, 0x86, 0xaf, 0x80, 0x6b, 0x1e, + 0x78, 0xbd, 0x19, 0xfc, 0xf3, 0x6f, 0x0a, 0x8c, 0x81, 0xb6, 0xcb, 0xd1, + 0xe9, 0xda, 0x77, 0x9d, 0xf2, 0x9e, 0xe9, 0x2d, 0xb2, 0xbf, 0xf4, 0x2d, + 0xf0, 0xc1, 0x56, 0x99, 0x2a, 0x15, 0xf4, 0x79, 0xf5, 0x4d, 0xfa, 0x3b, + 0x1e, 0xfc, 0xbe, 0x8d, 0x91, 0x91, 0x3b, 0x1d, 0x23, 0x23, 0xd3, 0xaa, + 0x6a, 0xb3, 0x86, 0x7d, 0xf2, 0xdb, 0x21, 0x23, 0xa5, 0x84, 0xfe, 0xc6, + 0xe9, 0x6c, 0xe5, 0x0a, 0xf9, 0xc2, 0x31, 0x75, 0xa7, 0xaa, 0x9e, 0xef, + 0xd5, 0x36, 0xeb, 0xdc, 0x0a, 0x9b, 0xf5, 0xaf, 0x64, 0xf1, 0xfd, 0x31, + 0xcc, 0x13, 0x34, 0x7c, 0xe5, 0xf7, 0xb8, 0x17, 0xda, 0x1e, 0x97, 0x0b, + 0x32, 0xa2, 0xf1, 0x47, 0x79, 0xda, 0x02, 0x39, 0xb8, 0xa4, 0xf5, 0xeb, + 0x66, 0xd0, 0x20, 0x65, 0xe9, 0xc7, 0xe4, 0x45, 0x2d, 0xcf, 0x36, 0x5b, + 0xdb, 0x75, 0x81, 0xb1, 0xd4, 0x23, 0xb4, 0x5d, 0xbf, 0x69, 0xcb, 0x59, + 0x96, 0x4a, 0x2c, 0x09, 0xf5, 0x5d, 0x1c, 0x32, 0x94, 0xf2, 0xf4, 0x8d, + 0xda, 0xae, 0x5f, 0xb3, 0x7d, 0x50, 0x7e, 0x1a, 0xd9, 0xbd, 0xdd, 0x59, + 0xb0, 0x65, 0x7c, 0x0e, 0xe3, 0xe9, 0x5e, 0x3a, 0x6b, 0xf9, 0x4c, 0x39, + 0x5f, 0xc2, 0xfb, 0x4d, 0x78, 0x4f, 0x3e, 0x3b, 0xad, 0xf9, 0x4c, 0xdb, + 0x27, 0x4e, 0xbf, 0xdd, 0x5f, 0x58, 0xde, 0x1b, 0xc8, 0x91, 0xcf, 0xd4, + 0x51, 0x77, 0xc1, 0xc8, 0x03, 0xe6, 0xa9, 0x7e, 0x1e, 0xba, 0x83, 0x6d, + 0x51, 0xfe, 0x70, 0x9a, 0xbe, 0x2d, 0xfc, 0x9f, 0x56, 0x3c, 0xb7, 0xe3, + 0x79, 0x56, 0xde, 0xbb, 0x37, 0xa6, 0xe7, 0x3d, 0x85, 0x79, 0x1c, 0x38, + 0x82, 0x39, 0x39, 0xc6, 0x76, 0x8e, 0x9e, 0x8a, 0x4a, 0xc3, 0x29, 0xf2, + 0x1d, 0xcf, 0xda, 0x04, 0xc1, 0xbe, 0x7e, 0xd2, 0x6d, 0xca, 0xdd, 0xa9, + 0xcf, 0x96, 0x6e, 0x4f, 0x44, 0x80, 0x93, 0x03, 0x58, 0x8f, 0xa9, 0x82, + 0xe7, 0x66, 0x1c, 0x2f, 0x81, 0x79, 0xc2, 0x06, 0xec, 0x86, 0x2d, 0xd8, + 0x0d, 0x3b, 0xb0, 0x1b, 0x76, 0xe0, 0x46, 0x39, 0x71, 0x15, 0x73, 0x4c, + 0x72, 0xd7, 0xc2, 0x2b, 0x97, 0xef, 0xe8, 0x38, 0x7d, 0xe3, 0xcd, 0x23, + 0xf0, 0xd9, 0xc5, 0x4d, 0x8d, 0x32, 0x0f, 0x7f, 0xc9, 0x6d, 0xbc, 0x79, + 0xa7, 0x74, 0x0f, 0xe2, 0xfd, 0xe0, 0x05, 0xe9, 0xb9, 0xf9, 0x56, 0xa7, + 0x71, 0x74, 0x04, 0x78, 0x4c, 0x3b, 0xa9, 0xc4, 0x98, 0xb3, 0x80, 0x71, + 0x32, 0xdb, 0x23, 0xc2, 0xb8, 0xe5, 0x02, 0x63, 0x11, 0x37, 0x77, 0x47, + 0xfa, 0x92, 0xe3, 0x4e, 0x6a, 0x54, 0x45, 0x52, 0xa3, 0x23, 0x4e, 0x58, + 0x8f, 0xdf, 0x48, 0x85, 0x9c, 0x01, 0xac, 0x07, 0x8a, 0xd3, 0xa0, 0xa7, + 0xff, 0x28, 0xf9, 0x63, 0x2d, 0x32, 0x5f, 0xe8, 0x76, 0x33, 0x2a, 0xae, + 0x73, 0x4b, 0xd4, 0x09, 0x10, 0xfd, 0xa9, 0x98, 0xcc, 0x96, 0xb6, 0x8a, + 0xd2, 0xb6, 0x7b, 0x87, 0x64, 0xa6, 0x4b, 0x72, 0x6e, 0x40, 0xda, 0x14, + 0xfa, 0xe7, 0xb7, 0x67, 0xd5, 0x09, 0xee, 0x25, 0x86, 0xbc, 0x70, 0x39, + 0xf9, 0xa4, 0x04, 0x1c, 0x82, 0x6e, 0x19, 0xe3, 0x6d, 0x12, 0xca, 0xbd, + 0x8f, 0xea, 0xf8, 0x29, 0x63, 0xb6, 0xb5, 0x7b, 0x0f, 0xe4, 0x8f, 0x58, + 0x5d, 0xfe, 0x98, 0x2b, 0x72, 0x9f, 0x46, 0x72, 0x51, 0xc6, 0x88, 0x3d, + 0xfc, 0x9e, 0x61, 0xdd, 0x26, 0x99, 0x1a, 0xc8, 0xd9, 0x3c, 0x8f, 0x47, + 0x12, 0xcc, 0x21, 0x26, 0x4e, 0xc6, 0x07, 0xc8, 0xeb, 0xab, 0xf7, 0x36, + 0x62, 0x35, 0xf2, 0xc0, 0x91, 0xc5, 0x52, 0xb8, 0x17, 0xc2, 0xfe, 0xf0, + 0x3c, 0x63, 0xe4, 0x6d, 0x66, 0x4d, 0x3b, 0xc2, 0xc5, 0xfd, 0xca, 0x95, + 0x32, 0x56, 0x79, 0x94, 0xa9, 0xae, 0x96, 0xaf, 0x8f, 0x55, 0x8c, 0x6c, + 0x9d, 0xa9, 0x84, 0xba, 0x25, 0x66, 0x74, 0xe9, 0x1a, 0x7d, 0x62, 0xa2, + 0x99, 0x55, 0x7d, 0x42, 0xbd, 0xa8, 0xe4, 0x03, 0xf3, 0x1d, 0x12, 0x7d, + 0x58, 0x96, 0xa6, 0xbc, 0xec, 0xe5, 0xcc, 0xd5, 0x98, 0xf2, 0xdf, 0x8c, + 0x7e, 0xfc, 0x6f, 0x09, 0xea, 0xc3, 0x31, 0xf5, 0x75, 0xdc, 0x37, 0x69, + 0xfa, 0x03, 0x4f, 0xe1, 0xd9, 0xf8, 0x09, 0xbf, 0x03, 0x3f, 0xe1, 0x8b, + 0xd0, 0x75, 0x67, 0xe0, 0x27, 0x3c, 0x09, 0x3f, 0xe1, 0x34, 0xfc, 0x84, + 0x27, 0xa0, 0x27, 0x6b, 0xfd, 0x83, 0xc9, 0x15, 0xfe, 0x41, 0xa0, 0xf9, + 0x9f, 0xf1, 0xc0, 0x27, 0x6b, 0x7c, 0x83, 0x7d, 0x46, 0x5f, 0xc1, 0xef, + 0x37, 0x7c, 0xd4, 0xa5, 0x6e, 0xd2, 0xfa, 0xd1, 0xe4, 0xed, 0x8e, 0x2e, + 0xeb, 0xab, 0x2e, 0x65, 0xf4, 0xd5, 0x6c, 0x55, 0x5f, 0x19, 0x3e, 0x7a, + 0xb8, 0x24, 0x11, 0xaf, 0xb4, 0x90, 0xf1, 0x77, 0x69, 0x1e, 0x6a, 0xf3, + 0xb6, 0x4a, 0xe4, 0x01, 0xd5, 0xde, 0x20, 0x19, 0xfb, 0x0c, 0xfa, 0x3a, + 0x3a, 0x8d, 0xbe, 0xae, 0x95, 0xac, 0xb6, 0xcf, 0x2e, 0x8e, 0xef, 0x27, + 0x56, 0xe1, 0x3b, 0x5f, 0xbc, 0x5b, 0xe3, 0xfc, 0xfe, 0x32, 0xf7, 0x59, + 0x5a, 0x64, 0xb2, 0x1c, 0xe2, 0x9c, 0xe7, 0x59, 0x99, 0x8b, 0xd1, 0x29, + 0x91, 0x87, 0x3b, 0x78, 0xce, 0x4a, 0x65, 0xfd, 0xf5, 0x3a, 0x87, 0xe5, + 0xc4, 0x80, 0x24, 0xb2, 0x03, 0xa4, 0xd5, 0xfb, 0x64, 0x56, 0xaf, 0x45, + 0x87, 0x34, 0x3c, 0x4c, 0x1b, 0x25, 0xdc, 0xcf, 0xeb, 0xba, 0xcc, 0x7e, + 0x23, 0x35, 0x66, 0xea, 0x89, 0x1c, 0xd4, 0xeb, 0x75, 0x5c, 0xe7, 0x19, + 0xde, 0x34, 0xcf, 0xb8, 0x3c, 0xbf, 0x47, 0xc5, 0x98, 0xfc, 0x3f, 0x67, + 0xfd, 0x7e, 0xe1, 0x32, 0x63, 0xcf, 0x6c, 0xb2, 0x76, 0x8c, 0x89, 0x53, + 0xd5, 0xb7, 0x61, 0xd8, 0x4f, 0xed, 0x37, 0x14, 0xb7, 0x38, 0x93, 0xa5, + 0xad, 0x4e, 0xbe, 0xc4, 0xbd, 0x6c, 0xfb, 0xf7, 0x2e, 0xdc, 0x3d, 0xce, + 0x01, 0x6f, 0x0b, 0xca, 0x18, 0xb3, 0x64, 0xcc, 0xe6, 0x97, 0x2e, 0x63, + 0x8c, 0x36, 0xe3, 0x71, 0x6c, 0x96, 0x6d, 0x71, 0xa6, 0x4a, 0xdd, 0xf0, + 0xcd, 0x79, 0xae, 0x8a, 0xef, 0x77, 0x72, 0xed, 0xa0, 0x83, 0x5d, 0x7d, + 0x66, 0x77, 0x42, 0xae, 0xb0, 0x31, 0x68, 0xea, 0xe1, 0x9f, 0x5f, 0xb1, + 0x77, 0x7b, 0x08, 0x7a, 0xec, 0x16, 0xc8, 0x23, 0xea, 0xe1, 0x43, 0x72, + 0xb5, 0xa5, 0xe7, 0x95, 0x7a, 0xf8, 0xbc, 0x30, 0x4e, 0xdc, 0x8f, 0x77, + 0xb9, 0x20, 0x06, 0x7a, 0x38, 0x5c, 0xe3, 0xab, 0xd1, 0xef, 0x6b, 0x1a, + 0x32, 0xfb, 0x61, 0x2b, 0xfd, 0x3e, 0xc8, 0x81, 0x78, 0xe8, 0xe7, 0x35, + 0x2e, 0xef, 0xd7, 0xee, 0xb1, 0x6d, 0xa7, 0xfc, 0xfb, 0x89, 0xa3, 0xe4, + 0x21, 0xe9, 0x81, 0x2e, 0x63, 0x0e, 0xc8, 0x6f, 0x69, 0x9c, 0x89, 0x22, + 0xed, 0x6d, 0xd2, 0x30, 0x5a, 0x39, 0x9f, 0x0c, 0x73, 0x38, 0xf2, 0xb6, + 0xed, 0x84, 0xdd, 0x93, 0xcf, 0xcb, 0xdc, 0x65, 0xd4, 0x83, 0x23, 0x91, + 0xf5, 0xfc, 0x7e, 0x22, 0xda, 0xf6, 0x18, 0xbd, 0x28, 0x61, 0x5f, 0x7c, + 0x6e, 0xa8, 0xe9, 0x9b, 0x76, 0x14, 0xef, 0xab, 0xcf, 0x91, 0x3d, 0xa3, + 0xf7, 0x19, 0xcd, 0xf7, 0x12, 0x42, 0x3e, 0x21, 0xef, 0x24, 0xf5, 0x59, + 0x27, 0xef, 0x61, 0xda, 0x3d, 0xdc, 0x83, 0x75, 0x17, 0x26, 0xfd, 0x4f, + 0xe8, 0x6f, 0xfc, 0xcd, 0x88, 0x38, 0x79, 0xff, 0x36, 0x9d, 0x7b, 0x92, + 0xd7, 0xb1, 0xe6, 0x1c, 0xee, 0x55, 0x1f, 0xb5, 0xeb, 0x61, 0xfe, 0x4d, + 0x0b, 0x96, 0x65, 0x01, 0x1b, 0x75, 0x08, 0x65, 0x6f, 0x5c, 0xba, 0x8e, + 0x7e, 0x58, 0xf3, 0xc2, 0x66, 0xf8, 0x02, 0xc3, 0x47, 0xa1, 0xab, 0x8f, + 0x26, 0x64, 0xe7, 0x51, 0xad, 0x1b, 0xd3, 0x6b, 0x63, 0x05, 0x7d, 0x6e, + 0xd4, 0x79, 0x8f, 0x3e, 0xc7, 0xf6, 0xd6, 0xa3, 0x11, 0x39, 0x1c, 0xef, + 0x73, 0x7b, 0x9c, 0xf7, 0x5a, 0x5d, 0x18, 0xc6, 0xb0, 0x5b, 0xd0, 0xfe, + 0xf5, 0xe2, 0xd8, 0x61, 0xfc, 0x3a, 0x22, 0x33, 0x7b, 0x3b, 0x01, 0xdb, + 0x5f, 0x5d, 0x66, 0xce, 0x20, 0x63, 0xad, 0xf4, 0xb7, 0xe7, 0xa3, 0x09, + 0xca, 0xb2, 0x2e, 0xc0, 0x32, 0x72, 0x94, 0xfa, 0xcc, 0xd3, 0x3c, 0x0e, + 0x18, 0xdc, 0x06, 0xed, 0x87, 0x90, 0x2f, 0xdf, 0x22, 0xde, 0x03, 0x90, + 0x71, 0x47, 0x63, 0xd2, 0x73, 0xb4, 0x45, 0xb6, 0x1d, 0xa5, 0x1f, 0x52, + 0xeb, 0x97, 0xd2, 0x2e, 0x7d, 0x04, 0x73, 0x7c, 0xb7, 0x96, 0x93, 0xdc, + 0xd3, 0xdc, 0x4f, 0xde, 0x45, 0xdd, 0x2c, 0x6c, 0xe6, 0xcc, 0x51, 0x57, + 0xef, 0x91, 0x66, 0x30, 0xe7, 0x6c, 0xd9, 0xc5, 0x38, 0x46, 0xe6, 0xe4, + 0xe9, 0xa7, 0x8c, 0x76, 0x00, 0xc7, 0xef, 0xb5, 0xbc, 0xb3, 0xbe, 0xc3, + 0xf2, 0xe8, 0xcf, 0xc8, 0x7b, 0x5b, 0x3a, 0x8c, 0xec, 0x7c, 0x4b, 0x07, + 0x73, 0x93, 0x36, 0x7b, 0xbc, 0x37, 0x69, 0x7b, 0xc2, 0xc8, 0xd0, 0xd7, + 0xe2, 0x45, 0x01, 0x8e, 0xc2, 0x7d, 0x29, 0x7d, 0x96, 0x2f, 0x38, 0xe7, + 0xeb, 0xf3, 0x2b, 0xfe, 0xa2, 0xfe, 0x3b, 0x21, 0xdc, 0x23, 0xab, 0x7e, + 0x6f, 0x65, 0x57, 0x85, 0x71, 0xf2, 0xcf, 0x86, 0x7f, 0x97, 0xa4, 0x26, + 0xef, 0xb0, 0x76, 0x0f, 0x8c, 0xb1, 0xa6, 0xe5, 0xdc, 0xa0, 0xa0, 0xa4, + 0xbf, 0x5f, 0xf4, 0x9c, 0x73, 0xbe, 0x70, 0xd6, 0xf9, 0xee, 0xb4, 0x04, + 0x51, 0xef, 0x27, 0xce, 0xf7, 0x3d, 0xee, 0x99, 0x7f, 0xdd, 0xf9, 0x5e, + 0xc1, 0x03, 0x1f, 0xde, 0x87, 0x79, 0xbc, 0xe2, 0xfc, 0x00, 0xeb, 0x7b, + 0xb0, 0x98, 0x4e, 0xb9, 0x36, 0x26, 0x7e, 0xb6, 0xf0, 0x8a, 0xf3, 0xb5, + 0x6a, 0x3c, 0x69, 0x30, 0xa4, 0x91, 0x43, 0x7c, 0x57, 0xc6, 0xbb, 0xb2, + 0xde, 0xff, 0x71, 0xe6, 0xa6, 0x6d, 0x7e, 0x89, 0xe6, 0xe3, 0x85, 0xe5, + 0x7d, 0x99, 0x51, 0xbd, 0x57, 0xf1, 0xac, 0x33, 0x37, 0x7f, 0x77, 0x87, + 0xc9, 0x33, 0x3a, 0x8b, 0x77, 0x26, 0xe7, 0x72, 0x76, 0xfe, 0x2c, 0xea, + 0x3c, 0xe3, 0xcc, 0xea, 0xf8, 0x97, 0xf6, 0xc5, 0x9d, 0x99, 0xf9, 0x67, + 0x9c, 0x79, 0xbd, 0x07, 0x7d, 0xce, 0x79, 0x74, 0x9a, 0x7d, 0x9f, 0x43, + 0x9d, 0x05, 0xe7, 0x04, 0xfa, 0x9b, 0x9f, 0xe6, 0x79, 0xdc, 0x6e, 0xd8, + 0x05, 0xfc, 0x7b, 0x3f, 0xfc, 0x1e, 0xc7, 0xb3, 0xce, 0xfc, 0x72, 0xbf, + 0x8b, 0xe8, 0x87, 0x75, 0x49, 0x8b, 0x1c, 0xf7, 0x59, 0xf4, 0xbf, 0x76, + 0xaf, 0x6a, 0x2d, 0x4e, 0x5e, 0x00, 0x4e, 0x2e, 0x58, 0x9c, 0xbc, 0x6a, + 0x71, 0xf2, 0x7c, 0x0d, 0x4e, 0x44, 0xad, 0xc4, 0xc9, 0xab, 0xc0, 0x89, + 0xa8, 0xfa, 0x38, 0xc1, 0xbb, 0x32, 0xde, 0x69, 0x9c, 0xbc, 0xb4, 0x0a, + 0x27, 0x4b, 0xcb, 0x71, 0x79, 0x83, 0x93, 0x17, 0x81, 0x93, 0xaf, 0x5a, + 0xd8, 0x2f, 0x58, 0x9c, 0xe0, 0x3e, 0x7f, 0x01, 0x75, 0x5e, 0xaa, 0xc1, + 0xc9, 0x05, 0xe0, 0xe4, 0x25, 0x8b, 0x93, 0xef, 0x5b, 0x9c, 0x7c, 0x1f, + 0x75, 0x96, 0x80, 0x93, 0xf3, 0x75, 0x70, 0xf2, 0x22, 0x70, 0x12, 0xf6, + 0x7b, 0x1e, 0xfd, 0x7c, 0xbf, 0x06, 0x27, 0x2f, 0xd6, 0xc1, 0x09, 0xf7, + 0x62, 0xc3, 0x9c, 0xee, 0x99, 0xd7, 0xc9, 0xe9, 0x96, 0x3b, 0x5f, 0x3f, + 0xa7, 0x9b, 0x75, 0x66, 0xa4, 0xfa, 0x37, 0x25, 0xee, 0xb6, 0x39, 0x6a, + 0x26, 0x17, 0xb0, 0xfa, 0xcd, 0xa6, 0x6e, 0xf0, 0x79, 0x3e, 0xe7, 0x8a, + 0xc9, 0x29, 0x8d, 0xee, 0xf8, 0x10, 0x78, 0x6d, 0x97, 0x1c, 0x38, 0xd6, + 0x78, 0x38, 0x6b, 0xcb, 0xbc, 0x1d, 0xdd, 0x39, 0xa5, 0xf8, 0x2e, 0xcc, + 0x49, 0xa0, 0x5f, 0xd2, 0xc0, 0x6f, 0x0b, 0xf6, 0xa6, 0xa5, 0x76, 0x4f, + 0xba, 0xc0, 0x6f, 0x34, 0x61, 0xec, 0x25, 0xfe, 0xfd, 0x8b, 0x24, 0xf3, + 0xac, 0xf2, 0x1a, 0xde, 0x14, 0xf4, 0xc7, 0xa0, 0xce, 0xad, 0xca, 0x14, + 0x68, 0x73, 0x27, 0x99, 0xa3, 0x06, 0x5b, 0x79, 0xc8, 0x9e, 0x09, 0xf3, + 0xf5, 0x39, 0x95, 0x2a, 0xff, 0xd4, 0x9e, 0x87, 0x26, 0xdf, 0x55, 0xe9, + 0xe6, 0xe0, 0xf2, 0x77, 0x02, 0x4f, 0xca, 0xd3, 0x3a, 0x56, 0xdc, 0x8c, + 0xf5, 0x09, 0x82, 0xc7, 0x7c, 0x13, 0xa3, 0x5d, 0xd4, 0x31, 0x5a, 0x81, + 0x37, 0x3e, 0x69, 0xe3, 0xb4, 0x3d, 0x83, 0x2f, 0x2d, 0xc7, 0x68, 0x6b, + 0xf3, 0x59, 0xcc, 0xfe, 0x7a, 0xa6, 0xf4, 0x88, 0xce, 0xd1, 0x19, 0xe1, + 0xf7, 0x37, 0x20, 0x23, 0x26, 0x66, 0xe6, 0x65, 0xf2, 0x41, 0x3e, 0x53, + 0xbf, 0x45, 0xa0, 0xc3, 0x28, 0xc3, 0x73, 0x92, 0x19, 0x64, 0x99, 0x69, + 0x33, 0xa2, 0xfd, 0xe5, 0x93, 0x32, 0xbc, 0x3c, 0x3e, 0xf1, 0x7b, 0x57, + 0xcd, 0x77, 0xab, 0x69, 0xf3, 0xa4, 0x9d, 0x4c, 0x85, 0xef, 0xc3, 0x3d, + 0xf2, 0xbb, 0xec, 0xb7, 0xb3, 0xf8, 0xbe, 0xf6, 0x5b, 0xad, 0x5a, 0x74, + 0xe0, 0x37, 0xbf, 0x87, 0x36, 0xe5, 0x8c, 0xa0, 0xcd, 0x82, 0xdb, 0x32, + 0xaa, 0x86, 0x6e, 0x18, 0xe5, 0xb9, 0xb9, 0xd9, 0x35, 0xdf, 0xba, 0xae, + 0xea, 0xc5, 0xbc, 0x5e, 0x53, 0xe6, 0x67, 0xdd, 0x05, 0x5a, 0xd4, 0xb4, + 0xa5, 0xe9, 0xff, 0xc0, 0xb2, 0xbe, 0xa4, 0x9e, 0x35, 0xdf, 0x9e, 0x31, + 0xfa, 0x32, 0x95, 0x18, 0xc1, 0xf8, 0xfa, 0x6f, 0x2a, 0xd8, 0x73, 0xbd, + 0xd9, 0xf9, 0xdb, 0xb5, 0xae, 0x9f, 0xf2, 0xd3, 0xc9, 0xa8, 0xd4, 0xa9, + 0x5b, 0xaa, 0xa9, 0xab, 0xe7, 0xed, 0xca, 0x7f, 0xc5, 0xda, 0x7c, 0xbe, + 0x58, 0x96, 0xe1, 0xe9, 0xbf, 0x84, 0xff, 0x98, 0x90, 0xdf, 0x2e, 0x96, + 0x40, 0xaf, 0xb9, 0xcd, 0xf6, 0x5b, 0x4d, 0x19, 0xc0, 0xcd, 0x6f, 0xaf, + 0xe8, 0x7c, 0xe2, 0xc8, 0x17, 0x40, 0x17, 0x9f, 0x2b, 0x71, 0x0c, 0xc0, + 0x12, 0x81, 0x6d, 0x0f, 0x3b, 0x61, 0xa6, 0xa4, 0x73, 0xe7, 0xae, 0x2b, + 0x97, 0x74, 0xcc, 0x62, 0x67, 0xb9, 0x53, 0x76, 0x95, 0x5b, 0x64, 0x37, + 0xf4, 0xc2, 0xee, 0xb2, 0x87, 0x2b, 0x26, 0xef, 0x2e, 0x9b, 0x75, 0xfa, + 0x58, 0x99, 0xeb, 0xbd, 0x43, 0x66, 0x8f, 0xad, 0xfe, 0x3e, 0xe7, 0x42, + 0x2e, 0xfc, 0x3b, 0x4b, 0x4a, 0x31, 0xbf, 0x8c, 0xb4, 0x84, 0xab, 0x98, + 0x3a, 0xbc, 0xa0, 0xf1, 0xc0, 0x0c, 0xd7, 0x54, 0x69, 0x49, 0x98, 0xa7, + 0xcf, 0xbf, 0xad, 0x34, 0x73, 0x39, 0xcf, 0x4d, 0xf3, 0x5b, 0x5e, 0x3b, + 0x2b, 0x61, 0xde, 0x78, 0xbd, 0x9c, 0x71, 0xd8, 0xf9, 0x3b, 0xc2, 0x1c, + 0xbf, 0x18, 0x73, 0xc6, 0xa5, 0xeb, 0x54, 0x0b, 0xee, 0xa7, 0x2f, 0xd7, + 0x67, 0x9b, 0x4f, 0x89, 0x2d, 0xd3, 0xf9, 0xe4, 0x78, 0x5e, 0xfd, 0x7d, + 0xb5, 0x90, 0x1f, 0xaa, 0x7f, 0xa7, 0x40, 0xe4, 0xff, 0x02, 0xfb, 0x2e, + 0x88, 0x71, 0xec, 0x6e, 0x00, 0x00, 0x00 }; static const u32 bnx2_CP_b09FwData[(0x0/4) + 1] = { 0x0 }; static const u32 bnx2_CP_b09FwRodata[(0x118/4) + 1] = { - 0x0800069c, 0x080008bc, 0x08000800, 0x08000828, 0x08000850, 0x08000878, - 0x080006d4, 0x080006c0, 0x080008e4, 0x080008e4, 0x080006f0, 0x0800070c, - 0x0800070c, 0x080008e4, 0x08000724, 0x08000738, 0x080008e4, 0x0800074c, - 0x080008e4, 0x080008e4, 0x08000760, 0x080008e4, 0x080008e4, 0x080008e4, - 0x080008e4, 0x080008e4, 0x080008e4, 0x080008e4, 0x080008e4, 0x080008e4, - 0x080008e4, 0x08000774, 0x080008e4, 0x08000788, 0x0800079c, 0x080007b0, - 0x080008e4, 0x080007c4, 0x080007d8, 0x080007ec, 0x080032e8, 0x08003300, - 0x08003310, 0x08003320, 0x08003338, 0x08003350, 0x08003360, 0x08003370, - 0x08003390, 0x080033a0, 0x080033b0, 0x08003440, 0x08003380, 0x080033c0, - 0x080033d0, 0x080033e8, 0x08003408, 0x08003440, 0x08003420, 0x08003420, - 0x080051bc, 0x080051bc, 0x080051bc, 0x080051bc, 0x080051bc, 0x080051e4, - 0x080051e4, 0x0800520c, 0x0800525c, 0x0800522c, 0x00000000 }; + 0x0800061c, 0x0800083c, 0x08000780, 0x080007a8, 0x080007d0, 0x080007f8, + 0x08000654, 0x08000640, 0x08000864, 0x08000864, 0x08000670, 0x0800068c, + 0x0800068c, 0x08000864, 0x080006a4, 0x080006b8, 0x08000864, 0x080006cc, + 0x08000864, 0x08000864, 0x080006e0, 0x08000864, 0x08000864, 0x08000864, + 0x08000864, 0x08000864, 0x08000864, 0x08000864, 0x08000864, 0x08000864, + 0x08000864, 0x080006f4, 0x08000864, 0x08000708, 0x0800071c, 0x08000730, + 0x08000864, 0x08000744, 0x08000758, 0x0800076c, 0x08003200, 0x08003218, + 0x08003228, 0x08003238, 0x08003250, 0x08003268, 0x08003278, 0x08003288, + 0x080032a8, 0x080032b8, 0x080032c8, 0x08003358, 0x08003298, 0x080032d8, + 0x080032e8, 0x08003300, 0x08003320, 0x08003358, 0x08003338, 0x08003338, + 0x080050d4, 0x080050d4, 0x080050d4, 0x080050d4, 0x080050d4, 0x080050fc, + 0x080050fc, 0x08005124, 0x08005174, 0x08005144, 0x00000000 }; static struct fw_info bnx2_cp_fw_09 = { - /* Firmware version: 3.7.1 */ .ver_major = 0x3, - .ver_minor = 0x7, - .ver_fix = 0x1, + .ver_minor = 0x4, + .ver_fix = 0x3, .start_addr = 0x0800006c, .text_addr = 0x08000000, - .text_len = 0x6fd0, + .text_len = 0x6ee8, .text_index = 0x0, .gz_text = bnx2_CP_b09FwText, .gz_text_len = sizeof(bnx2_CP_b09FwText), - .data_addr = 0x08007100, + .data_addr = 0x08007020, .data_len = 0x0, .data_index = 0x0, .data = bnx2_CP_b09FwData, - .sbss_addr = 0x08007104, - .sbss_len = 0xa9, + .sbss_addr = 0x08007024, + .sbss_len = 0xa1, .sbss_index = 0x0, - .bss_addr = 0x080071b0, + .bss_addr = 0x080070d0, .bss_len = 0x3b0, .bss_index = 0x0, - .rodata_addr = 0x08006fd0, + .rodata_addr = 0x08006ee8, .rodata_len = 0x118, .rodata_index = 0x0, .rodata = bnx2_CP_b09FwRodata, }; static u8 bnx2_RXP_b09FwText[] = { - 0xec, 0x5c, 0x7d, 0x6c, 0x1c, 0xc7, 0x75, 0x7f, 0x3b, 0xbb, 0xa4, 0x8e, - 0xd4, 0x91, 0x5c, 0x1e, 0x4f, 0xcc, 0x51, 0xa6, 0xed, 0x5b, 0x71, 0x25, - 0x9e, 0x4d, 0xc6, 0x59, 0xd1, 0x07, 0x9b, 0x28, 0x0e, 0xc9, 0x66, 0xef, - 0x24, 0xb1, 0x86, 0x5b, 0x53, 0x35, 0x1d, 0x1b, 0x6d, 0xea, 0xb2, 0x47, - 0xb5, 0x29, 0x8c, 0x06, 0x90, 0xbf, 0x00, 0x17, 0xa8, 0xe4, 0xcb, 0x91, - 0x8a, 0x55, 0xf7, 0xc0, 0xbd, 0xc8, 0x8c, 0x18, 0x20, 0x6e, 0x7d, 0x25, - 0x29, 0x4a, 0x08, 0x0e, 0x3a, 0xa6, 0x71, 0x1a, 0xfd, 0x61, 0xd7, 0x04, - 0x2b, 0x1b, 0x6e, 0x91, 0xd6, 0x72, 0xe3, 0xb6, 0x46, 0x50, 0x04, 0x84, - 0xec, 0x34, 0x6e, 0xd0, 0x0f, 0xa1, 0x2e, 0x6c, 0x03, 0x96, 0xbd, 0xfd, - 0xbd, 0xd9, 0x5d, 0xf2, 0x48, 0x5b, 0x76, 0xd0, 0x3f, 0xfa, 0x4f, 0x77, - 0x80, 0xc3, 0xce, 0xcc, 0xbe, 0xf7, 0xe6, 0xcd, 0x9b, 0xf7, 0x39, 0x4b, - 0xe9, 0xb7, 0xe3, 0xd4, 0x4e, 0x41, 0xeb, 0xc0, 0x2f, 0x7d, 0xf4, 0xb1, - 0x87, 0x6e, 0xb9, 0xfd, 0x96, 0x5b, 0xd1, 0xdd, 0xaf, 0x2a, 0x3b, 0xd4, - 0x70, 0x3e, 0x6a, 0x51, 0x8b, 0x5a, 0xd4, 0xa2, 0x16, 0xb5, 0xa8, 0x45, - 0x2d, 0x6a, 0x51, 0x8b, 0x5a, 0xd4, 0xa2, 0x16, 0xb5, 0xa8, 0x45, 0x2d, - 0x6a, 0x51, 0x8b, 0x5a, 0xd4, 0xa2, 0x16, 0xb5, 0xa8, 0x45, 0x2d, 0x6a, - 0x51, 0x8b, 0x5a, 0xd4, 0xa2, 0x16, 0xb5, 0xa8, 0x45, 0x2d, 0x6a, 0x51, - 0x8b, 0x5a, 0xd4, 0xa2, 0x16, 0xb5, 0xa8, 0x45, 0x2d, 0x6a, 0x51, 0x8b, - 0x5a, 0xd4, 0xa2, 0x16, 0xb5, 0xa8, 0x45, 0xed, 0xff, 0x7b, 0x53, 0x89, - 0x74, 0x7e, 0x76, 0x04, 0x3f, 0x8a, 0x89, 0x5c, 0xfa, 0x01, 0xc7, 0xa4, - 0x98, 0x9a, 0xeb, 0x3f, 0x3e, 0x65, 0x12, 0xd9, 0xf5, 0xa1, 0x74, 0x9e, - 0x3e, 0xf0, 0x4a, 0x49, 0x8d, 0x78, 0xfe, 0xfa, 0xdc, 0xd5, 0x67, 0x9e, - 0xbf, 0xdd, 0xb8, 0x52, 0x53, 0x29, 0xa6, 0xe7, 0x66, 0xf6, 0xeb, 0xfb, - 0x28, 0xd6, 0x0f, 0x9c, 0xa7, 0x07, 0xff, 0xb1, 0x93, 0x3a, 0x43, 0x5a, - 0x44, 0x0b, 0x15, 0xc3, 0x3a, 0x88, 0xe7, 0x72, 0x7d, 0xc8, 0x5a, 0x23, - 0x8d, 0x56, 0x75, 0x7f, 0xc5, 0x72, 0x45, 0x61, 0x3a, 0x54, 0xae, 0xc7, - 0x68, 0x5d, 0xfe, 0x3b, 0x0f, 0xac, 0x69, 0x72, 0xff, 0x82, 0xe2, 0x34, - 0x3c, 0xef, 0x8c, 0xe5, 0x79, 0x2f, 0xe1, 0xf7, 0x33, 0x0b, 0x63, 0xf7, - 0x43, 0xcf, 0xd6, 0x54, 0x12, 0xe6, 0x1f, 0x2b, 0xce, 0x62, 0x2b, 0x95, - 0xe7, 0x89, 0xa6, 0xdd, 0x18, 0x9d, 0x74, 0x4b, 0x4a, 0xa1, 0x51, 0x51, - 0x0e, 0x9c, 0x9d, 0x55, 0x0e, 0x9e, 0x3d, 0xa9, 0x1c, 0x3a, 0x5b, 0x55, - 0x9c, 0xb3, 0x54, 0x12, 0xfb, 0xe3, 0x64, 0xeb, 0xe7, 0x94, 0x7c, 0xa3, - 0x57, 0x71, 0xe6, 0xaf, 0x7a, 0x8e, 0x65, 0xe8, 0xbf, 0x4e, 0x9a, 0xcd, - 0xeb, 0x39, 0x15, 0x0f, 0x63, 0x8d, 0xec, 0xa4, 0xe7, 0x89, 0x9c, 0xf7, - 0xb8, 0x93, 0x35, 0x75, 0xa1, 0xc4, 0xa8, 0xdc, 0x68, 0x07, 0x5d, 0x4d, - 0xc9, 0xbb, 0xde, 0x0b, 0x8e, 0xb5, 0x0c, 0x3a, 0x75, 0xe0, 0x93, 0x2e, - 0x72, 0xcc, 0x4f, 0xc8, 0x63, 0x49, 0xc9, 0x0f, 0x86, 0xfc, 0x50, 0x9a, - 0xf9, 0x2d, 0x2e, 0x09, 0xf0, 0xb5, 0x93, 0x8a, 0x35, 0x9d, 0x26, 0x97, - 0xb6, 0xc3, 0xaf, 0x7b, 0xcf, 0x0f, 0xea, 0xb4, 0xd2, 0x30, 0x4a, 0x25, - 0xec, 0x7d, 0xc6, 0x4d, 0x93, 0xc8, 0x91, 0xed, 0x64, 0xfb, 0xe9, 0x85, - 0x46, 0x8a, 0xfe, 0xbc, 0x61, 0xa6, 0xca, 0xb4, 0x83, 0x8a, 0xc9, 0x24, - 0x7d, 0x17, 0x38, 0xd3, 0x58, 0x5b, 0x98, 0xa6, 0x5e, 0x06, 0x6c, 0xb9, - 0xf1, 0x23, 0xfe, 0xb7, 0x31, 0xfa, 0x54, 0x56, 0xe2, 0x94, 0xc0, 0x67, - 0x00, 0xcb, 0x7c, 0x4b, 0x58, 0xc9, 0xbb, 0x0f, 0x4b, 0xa5, 0xa9, 0x2c, - 0xe6, 0x1a, 0x4e, 0x20, 0xfb, 0x56, 0xec, 0x8f, 0x9f, 0x37, 0x28, 0xf9, - 0xf9, 0x1b, 0x20, 0x03, 0x4a, 0x0a, 0xda, 0x9b, 0x2a, 0x62, 0x66, 0xba, - 0x11, 0xc7, 0x98, 0x79, 0xf1, 0xbc, 0x43, 0x16, 0xe9, 0x65, 0xab, 0x0b, - 0xb2, 0x4a, 0x53, 0xd9, 0xea, 0x04, 0x4e, 0x0b, 0x75, 0x9b, 0xbc, 0x07, - 0xa6, 0xdb, 0x86, 0x79, 0xaf, 0x43, 0xcd, 0x79, 0xde, 0x54, 0x96, 0x3a, - 0xfd, 0xb9, 0x21, 0xd0, 0xd0, 0x68, 0x72, 0x5c, 0x01, 0xdc, 0xdb, 0xcc, - 0x5f, 0x2c, 0x91, 0xe3, 0x3e, 0x3f, 0xb3, 0xe4, 0xcc, 0xa6, 0x83, 0x75, - 0xe3, 0x54, 0x76, 0xaf, 0x0f, 0xfa, 0x90, 0xad, 0x8b, 0x3d, 0x5b, 0x7d, - 0x18, 0x2b, 0x37, 0x82, 0x8e, 0x55, 0x26, 0x5e, 0x63, 0x17, 0xad, 0x25, - 0x49, 0x5c, 0xb6, 0x7a, 0x02, 0xb8, 0x4e, 0xf0, 0x1a, 0x9e, 0x71, 0x3b, - 0xcd, 0xcc, 0xb7, 0xd2, 0x89, 0x79, 0x96, 0x6d, 0x05, 0x67, 0x21, 0x68, - 0xcf, 0x6d, 0x25, 0xc5, 0x6e, 0x9c, 0x44, 0x5f, 0xa3, 0x29, 0xd3, 0x7b, - 0x61, 0xc6, 0x9a, 0x55, 0xf2, 0x67, 0x97, 0x95, 0x02, 0xce, 0xfc, 0xc0, - 0xd9, 0x0b, 0xca, 0xc1, 0xc6, 0xcb, 0x1d, 0xd4, 0x6e, 0x40, 0xbb, 0x34, - 0x3a, 0xe1, 0x2a, 0xc4, 0xfc, 0x2e, 0x40, 0x5e, 0xb6, 0x0e, 0xc9, 0x9b, - 0x9d, 0xca, 0x41, 0xd0, 0x6a, 0x31, 0xbf, 0x1e, 0xa7, 0x4e, 0x95, 0x76, - 0x98, 0x21, 0x6c, 0x8c, 0xbe, 0x0e, 0xde, 0xd6, 0xac, 0x24, 0xe0, 0xa8, - 0xcb, 0xc7, 0xe9, 0x0e, 0xf8, 0x61, 0xdd, 0x61, 0xbd, 0x11, 0x76, 0x61, - 0xee, 0x8f, 0x7a, 0xca, 0xc3, 0x3b, 0x19, 0x06, 0xf6, 0x60, 0x3f, 0x30, - 0x65, 0x3a, 0xdd, 0x1a, 0x95, 0x74, 0x41, 0x86, 0x9e, 0xa7, 0x1b, 0x69, - 0xc6, 0x22, 0xca, 0x43, 0x9f, 0x85, 0xa9, 0x41, 0x46, 0x26, 0x64, 0xb4, - 0xb7, 0xa4, 0x8a, 0x7b, 0x41, 0xa2, 0xa4, 0x68, 0x81, 0x3c, 0x17, 0xe8, - 0x0e, 0x89, 0x2f, 0x72, 0x16, 0x74, 0xb0, 0x9d, 0xfb, 0x58, 0x37, 0x26, - 0xd7, 0x55, 0x73, 0x66, 0x6a, 0x91, 0x48, 0x11, 0xb9, 0x21, 0xd0, 0x63, - 0xdd, 0x64, 0x38, 0x17, 0x3c, 0x32, 0xef, 0xdc, 0x37, 0x81, 0x13, 0x23, - 0xc7, 0xea, 0x68, 0xe2, 0x13, 0xfc, 0x24, 0x59, 0xe6, 0x2c, 0x43, 0xb9, - 0x4f, 0x65, 0x73, 0x9f, 0xef, 0x7b, 0x83, 0x23, 0x1a, 0xbd, 0x24, 0xf7, - 0xcb, 0x76, 0xc4, 0x70, 0x72, 0x8f, 0xc4, 0xf2, 0x99, 0x76, 0x49, 0x29, - 0x5a, 0xfa, 0x06, 0x2d, 0xe8, 0x85, 0x50, 0x73, 0x71, 0xca, 0x4b, 0xfe, - 0x46, 0xb1, 0x16, 0xdb, 0x17, 0xec, 0xc4, 0xe4, 0xbd, 0xf0, 0x5c, 0x0e, - 0xb6, 0x6a, 0x48, 0xfd, 0x29, 0x56, 0xd9, 0xfe, 0x99, 0xb7, 0x55, 0x43, - 0x50, 0x48, 0x4f, 0xf4, 0xaa, 0xd4, 0x45, 0xe3, 0xd6, 0x55, 0x4f, 0xec, - 0xc3, 0xfb, 0xe1, 0x14, 0x78, 0x33, 0xd2, 0xb0, 0xb6, 0x84, 0x4a, 0xb0, - 0x73, 0x6b, 0x28, 0xa5, 0x93, 0x89, 0xbd, 0x25, 0xc8, 0x1e, 0x5f, 0x85, - 0xe0, 0xaf, 0xc5, 0xa7, 0x4f, 0x17, 0x6c, 0xda, 0x0e, 0x78, 0x74, 0xac, - 0x5b, 0xa5, 0xcc, 0x74, 0xec, 0x5f, 0x9d, 0x65, 0xf9, 0xb6, 0x43, 0xff, - 0x15, 0x2a, 0x5a, 0x4c, 0x3b, 0xa4, 0x21, 0x68, 0xf0, 0xb6, 0x66, 0x1a, - 0xe1, 0xd9, 0xb2, 0xfe, 0x6a, 0x34, 0x32, 0xc2, 0xb0, 0x0c, 0xc7, 0xf0, - 0xc6, 0x68, 0x5a, 0xbc, 0xef, 0xed, 0xdf, 0xb2, 0xa6, 0x49, 0x62, 0x16, - 0x3c, 0xfb, 0x67, 0x01, 0x19, 0x7e, 0x1a, 0x2c, 0x9f, 0xc3, 0x76, 0x79, - 0x33, 0x6c, 0x33, 0x1c, 0x74, 0xa8, 0x97, 0x79, 0xa8, 0xc7, 0x7d, 0x7b, - 0x0c, 0x79, 0x0a, 0xcf, 0x52, 0x09, 0x68, 0x7c, 0xd2, 0x3e, 0x18, 0x1e, - 0x7e, 0xc2, 0x85, 0x9f, 0x70, 0xe1, 0x1f, 0x5c, 0xf8, 0x11, 0x97, 0xfd, - 0x4a, 0x9a, 0x9e, 0x1f, 0x84, 0xdf, 0xdb, 0xf4, 0x43, 0x68, 0x63, 0xe8, - 0x0b, 0x52, 0xe1, 0x87, 0xa6, 0x6b, 0x02, 0xb6, 0x0e, 0x9b, 0x5b, 0xe2, - 0x39, 0x1d, 0xcf, 0x02, 0x9e, 0x26, 0xfc, 0x2c, 0xeb, 0x61, 0xe8, 0x5f, - 0xd9, 0x2f, 0xa5, 0xe0, 0x83, 0xd8, 0xef, 0xb0, 0x7f, 0x62, 0x58, 0xcf, - 0x2b, 0x58, 0x8c, 0xeb, 0xe1, 0x1c, 0xd9, 0xee, 0xe2, 0x24, 0x12, 0x25, - 0xe5, 0xf0, 0x20, 0x6c, 0xf2, 0xe6, 0x16, 0xf0, 0xca, 0xb6, 0x79, 0x1d, - 0xbb, 0x16, 0xb4, 0xf7, 0x3b, 0xfc, 0x7f, 0xb7, 0xb7, 0x03, 0x30, 0xd2, - 0xc6, 0x3b, 0xfd, 0x71, 0x77, 0xe0, 0x7f, 0xf8, 0xbd, 0x91, 0xb6, 0x69, - 0x5f, 0x30, 0xe6, 0xfe, 0x06, 0xbf, 0x96, 0xb8, 0x2d, 0x46, 0x7b, 0x96, - 0x7d, 0xbf, 0xb9, 0x67, 0x01, 0x9a, 0xb1, 0xec, 0xf3, 0xb8, 0xe7, 0x7c, - 0xe8, 0x3f, 0x3b, 0x40, 0x0f, 0xfc, 0xb9, 0x9b, 0x71, 0x84, 0xe8, 0xbf, - 0x14, 0x98, 0x16, 0xe6, 0xb6, 0xcb, 0xc2, 0xf3, 0x66, 0x2c, 0xb6, 0x4f, - 0xbd, 0xd9, 0x3e, 0xf7, 0xc3, 0x3e, 0xad, 0x56, 0x32, 0xac, 0xbf, 0x82, - 0x7d, 0x3e, 0x61, 0x29, 0x90, 0x0d, 0xd1, 0xc5, 0x4a, 0x1c, 0xbe, 0x41, - 0x4b, 0xbd, 0x41, 0x7b, 0xd3, 0xd3, 0xd0, 0xcb, 0x33, 0x3c, 0x87, 0x23, - 0x3a, 0x21, 0xfd, 0xb5, 0xef, 0x0f, 0xd6, 0xd5, 0x6f, 0x80, 0x2f, 0xcf, - 0x9b, 0x06, 0xcd, 0xe2, 0xb0, 0x1a, 0xd8, 0x62, 0x38, 0x6f, 0x23, 0x26, - 0x3a, 0x37, 0xa9, 0x54, 0xca, 0xb4, 0x90, 0x91, 0x59, 0x00, 0xed, 0x29, - 0xcb, 0xb7, 0x7b, 0xb6, 0x8d, 0x45, 0xd0, 0x9f, 0x71, 0x07, 0xe1, 0x17, - 0xd8, 0x6e, 0xc0, 0x17, 0xe8, 0x2f, 0x82, 0xfe, 0x4c, 0xa3, 0x85, 0xbe, - 0xa6, 0x85, 0xb1, 0x36, 0xdc, 0x0f, 0x44, 0x6d, 0x86, 0xeb, 0x1e, 0xa5, - 0x3b, 0xdc, 0x84, 0xe2, 0x3c, 0xc5, 0x7e, 0xb9, 0x9c, 0x81, 0x5d, 0x29, - 0x65, 0x8b, 0xd7, 0x56, 0x69, 0x71, 0x03, 0x86, 0xec, 0xb2, 0x6f, 0xb3, - 0xb6, 0x33, 0x58, 0x4a, 0xa9, 0xd2, 0xf7, 0x10, 0x1d, 0xac, 0x68, 0x80, - 0xe1, 0x31, 0xcf, 0xfb, 0x73, 0x63, 0x95, 0x5e, 0xf8, 0x52, 0x1e, 0x5f, - 0xf5, 0xa6, 0x2c, 0x7f, 0xee, 0x97, 0x2b, 0x0f, 0xf0, 0x19, 0x61, 0x2f, - 0x94, 0x2e, 0x5b, 0x3f, 0xf7, 0xa0, 0xbf, 0x5b, 0x70, 0x3e, 0x9e, 0x8e, - 0x31, 0xe6, 0xeb, 0x2c, 0x29, 0x87, 0x4c, 0xd1, 0xdb, 0x1a, 0xf8, 0xbc, - 0x43, 0x98, 0x3c, 0x50, 0x29, 0xf7, 0xb4, 0xd2, 0x55, 0x95, 0x63, 0xeb, - 0x65, 0x38, 0x01, 0xa7, 0xb2, 0x0f, 0xf2, 0x28, 0x77, 0x37, 0xcd, 0xc5, - 0x0a, 0x15, 0x8f, 0xd6, 0x2c, 0x1f, 0x07, 0xe3, 0x78, 0xbe, 0x22, 0x7a, - 0x63, 0xb4, 0x31, 0xd6, 0x19, 0x67, 0x89, 0xf6, 0x65, 0x16, 0x49, 0xe2, - 0xf6, 0xc4, 0x36, 0x71, 0x93, 0x85, 0x4a, 0xb9, 0xbb, 0x69, 0x9c, 0xca, - 0x83, 0x96, 0xd8, 0xbf, 0x81, 0xdb, 0xbf, 0x89, 0xbb, 0x8b, 0xd2, 0xdd, - 0x8c, 0x2f, 0x7a, 0xdb, 0x36, 0x69, 0xa7, 0x03, 0x7e, 0x7a, 0xda, 0x36, - 0x69, 0x98, 0x4c, 0xb3, 0x69, 0x9c, 0x61, 0x9a, 0x7b, 0x36, 0x69, 0x0e, - 0x6f, 0xe5, 0xe7, 0x28, 0xc1, 0x07, 0xc5, 0x5a, 0x73, 0xb4, 0xff, 0x62, - 0x65, 0x60, 0xfc, 0x0e, 0x42, 0x8c, 0x1c, 0xde, 0x11, 0xf8, 0x70, 0x6d, - 0xbf, 0x03, 0x59, 0x69, 0xc4, 0x3e, 0x51, 0xa1, 0x32, 0xce, 0xf9, 0x81, - 0x3a, 0xed, 0x5f, 0xab, 0x53, 0xa0, 0x4b, 0xac, 0x13, 0x6f, 0xc1, 0xc6, - 0xa8, 0xb4, 0x3b, 0x17, 0x9f, 0xd4, 0x72, 0x3a, 0x6c, 0x8d, 0xc6, 0xcb, - 0xf0, 0xe1, 0x6a, 0x6e, 0xef, 0xeb, 0x79, 0xf5, 0x71, 0x4f, 0x35, 0xd9, - 0x1f, 0xc6, 0x47, 0x9d, 0x2c, 0xe6, 0xeb, 0x6c, 0x5b, 0xf0, 0x2b, 0x0d, - 0xa6, 0xfd, 0x4c, 0x17, 0x75, 0x22, 0x8e, 0xd6, 0xcf, 0xec, 0xf2, 0x6d, - 0x87, 0x34, 0x0d, 0xbe, 0x79, 0x26, 0xcb, 0x71, 0xbf, 0x35, 0x06, 0xf8, - 0x49, 0x35, 0x37, 0xd6, 0x77, 0xa4, 0x7e, 0x67, 0x5f, 0xb1, 0x5e, 0xea, - 0x2b, 0x56, 0x74, 0xb6, 0x13, 0xe1, 0x64, 0xd1, 0x97, 0xb9, 0x54, 0x0a, - 0x36, 0xc1, 0x6b, 0x27, 0xb1, 0xe6, 0x0f, 0x60, 0x7f, 0x6c, 0xdf, 0x44, - 0xe3, 0x2e, 0xd6, 0x18, 0xf9, 0x00, 0xe7, 0x0e, 0xde, 0xe0, 0xd3, 0x6c, - 0xec, 0x5a, 0x8c, 0xfc, 0x6b, 0x60, 0x9f, 0xdc, 0x7f, 0xc7, 0xf3, 0xe3, - 0xc3, 0xdd, 0x5d, 0xfe, 0xdc, 0x8f, 0x03, 0x9b, 0x0e, 0x69, 0x31, 0x9d, - 0x8c, 0x32, 0x8e, 0x1c, 0x66, 0xbc, 0xa1, 0x29, 0xec, 0x9f, 0xf3, 0x2e, - 0xe7, 0x1e, 0x9c, 0x77, 0x4c, 0x07, 0x7e, 0x8e, 0x6c, 0xe4, 0x4f, 0x9e, - 0x40, 0x2e, 0x52, 0x84, 0xdd, 0x68, 0xb9, 0x2b, 0x34, 0x23, 0x7d, 0x24, - 0xc5, 0x5a, 0x72, 0x8f, 0x01, 0xe6, 0xdf, 0x60, 0x73, 0xdd, 0x5d, 0x81, - 0x1e, 0x06, 0x3e, 0x5e, 0xfa, 0x5d, 0xc0, 0xbe, 0xb5, 0x0d, 0xf6, 0xcd, - 0x66, 0x58, 0xbc, 0x5f, 0xdf, 0xf6, 0xfe, 0x9f, 0xd9, 0x7e, 0xf1, 0x6e, - 0x15, 0xfe, 0xb4, 0x35, 0xb0, 0xfd, 0x8b, 0x54, 0x84, 0x6f, 0xd5, 0x4c, - 0xce, 0x2d, 0x0f, 0x02, 0x17, 0xe3, 0x3a, 0x78, 0x84, 0xbf, 0x40, 0x8c, - 0x85, 0xbc, 0x11, 0x13, 0x92, 0x37, 0x72, 0x3e, 0x05, 0xd8, 0x34, 0x60, - 0xd9, 0xff, 0x32, 0xec, 0x85, 0x38, 0xcb, 0xbc, 0x58, 0x67, 0x1c, 0xf6, - 0x55, 0xe4, 0x39, 0xd9, 0x36, 0x68, 0x94, 0xf7, 0x82, 0x6a, 0x86, 0xb0, - 0x21, 0xdd, 0xed, 0xb0, 0x9c, 0xdf, 0x30, 0xed, 0xae, 0x20, 0x6f, 0x18, - 0x23, 0xbb, 0x61, 0xe3, 0x57, 0xa2, 0xa9, 0xa7, 0x90, 0xbb, 0x99, 0x2d, - 0x2c, 0x0b, 0x9e, 0xd7, 0x7d, 0x19, 0x85, 0x78, 0xa5, 0x9e, 0xad, 0xe3, - 0xdf, 0x4a, 0x6c, 0xfa, 0x4a, 0xb6, 0x34, 0xb2, 0x11, 0x2b, 0x20, 0xe3, - 0xf4, 0xa4, 0xc8, 0x25, 0x29, 0x5f, 0xf7, 0xe5, 0x8b, 0xf8, 0x0c, 0xff, - 0x28, 0xfd, 0x07, 0xce, 0x3d, 0xf4, 0x83, 0xe1, 0x99, 0xb3, 0x9e, 0xd9, - 0x38, 0x9b, 0x34, 0x74, 0x69, 0x0c, 0xb8, 0x74, 0x14, 0x34, 0x38, 0x6e, - 0x5b, 0x22, 0x97, 0xa0, 0xa2, 0xce, 0xf9, 0x85, 0xcc, 0x0d, 0x6d, 0xf6, - 0x03, 0x22, 0xd7, 0x86, 0x39, 0xee, 0xff, 0x41, 0x97, 0x7f, 0xd6, 0x1d, - 0x3c, 0x1e, 0x17, 0xb9, 0xae, 0x6d, 0xf3, 0x7f, 0xd7, 0xe1, 0xf3, 0x26, - 0xc7, 0x98, 0xff, 0xc9, 0xb6, 0xf1, 0xa3, 0x89, 0xad, 0xe3, 0xaf, 0xf6, - 0x85, 0xfa, 0x20, 0x72, 0x8f, 0x05, 0xfc, 0xb2, 0x9e, 0x6e, 0xe7, 0xf5, - 0x17, 0xd1, 0x97, 0x3f, 0x01, 0x4d, 0xa9, 0xe3, 0xbf, 0x80, 0xbe, 0x6c, - 0xc0, 0x5e, 0x43, 0x5f, 0x9a, 0x79, 0xd8, 0xa8, 0x3b, 0xaa, 0x02, 0x39, - 0xac, 0x93, 0xdd, 0x9b, 0x2e, 0xc3, 0xc6, 0x0b, 0x0d, 0xc8, 0x6e, 0x23, - 0xae, 0x6e, 0xc0, 0x94, 0x36, 0x61, 0xfc, 0xb8, 0x53, 0x68, 0x78, 0xc8, - 0xfb, 0x9a, 0x63, 0x70, 0x06, 0xfd, 0x12, 0xf6, 0xba, 0x42, 0x53, 0xee, - 0x9a, 0x2d, 0xcc, 0x93, 0x32, 0x6f, 0x15, 0xe6, 0x93, 0x4a, 0x61, 0x91, - 0x73, 0xda, 0x18, 0xfa, 0xb2, 0x3e, 0x41, 0x8c, 0x3b, 0xa5, 0xd8, 0x67, - 0xe7, 0x90, 0xcf, 0x2e, 0xe1, 0x77, 0x0e, 0xbf, 0x3a, 0x7e, 0x61, 0xdd, - 0xf0, 0x2d, 0xd4, 0x1d, 0xd2, 0xdf, 0x23, 0x36, 0xf9, 0xeb, 0xff, 0x74, - 0x09, 0xf9, 0xf4, 0x5c, 0x92, 0x9e, 0x30, 0x45, 0x8f, 0xf0, 0x7d, 0x9c, - 0x8d, 0x5c, 0x5c, 0x7f, 0x8b, 0x7e, 0x25, 0xc8, 0xe9, 0x88, 0xde, 0xa8, - 0xe2, 0x2c, 0x87, 0x0f, 0x05, 0xfe, 0xe9, 0xe4, 0x57, 0x1c, 0xe9, 0xcb, - 0x83, 0x9c, 0x0d, 0x7e, 0xc7, 0x96, 0x50, 0xaf, 0x40, 0x3e, 0x0a, 0xfd, - 0x0c, 0x7a, 0xfc, 0x46, 0xb5, 0x1d, 0xfc, 0x98, 0x54, 0x9c, 0x30, 0x46, - 0x49, 0x19, 0xd0, 0x77, 0x28, 0xed, 0xc8, 0xdb, 0xe0, 0x77, 0xe4, 0x98, - 0x65, 0x46, 0xc7, 0x17, 0x2a, 0x02, 0xb0, 0x90, 0x79, 0x16, 0x7d, 0xe8, - 0xdf, 0xe5, 0x2a, 0xe3, 0x09, 0x7a, 0xb3, 0xaa, 0xd2, 0xbf, 0x20, 0x0f, - 0xc4, 0xbb, 0xe3, 0xb0, 0xc1, 0x5e, 0xc4, 0xab, 0x7e, 0x95, 0xf6, 0x72, - 0xcc, 0xd8, 0xa3, 0xe1, 0x59, 0xc0, 0xef, 0x20, 0xf2, 0xc2, 0x6b, 0xe0, - 0x5c, 0x03, 0x9e, 0x79, 0x8b, 0x01, 0x87, 0xe1, 0x35, 0xf0, 0xd6, 0x09, - 0x1d, 0x34, 0xf4, 0x49, 0xfa, 0x8c, 0x2e, 0x73, 0x27, 0x85, 0xe7, 0x7d, - 0x3f, 0xf9, 0xd1, 0x79, 0x96, 0xb3, 0x0a, 0x1d, 0xe2, 0x31, 0xbf, 0x63, - 0x7f, 0xce, 0xf4, 0x8c, 0x51, 0x1b, 0x9b, 0xb9, 0x5c, 0xf5, 0xfb, 0xe1, - 0x1c, 0x29, 0x61, 0x4c, 0x65, 0x3f, 0x5d, 0x80, 0xad, 0xf2, 0x78, 0x9c, - 0xe4, 0x19, 0x6c, 0x39, 0x4f, 0xa9, 0x47, 0xc7, 0x66, 0x4c, 0x3e, 0x57, - 0x9d, 0xa6, 0x2b, 0xe1, 0xb9, 0xf2, 0x19, 0xa1, 0x0e, 0xad, 0x3e, 0x89, - 0x73, 0x15, 0x41, 0xcd, 0x02, 0x3f, 0x30, 0xc7, 0xe7, 0x8b, 0x3a, 0xb2, - 0x8a, 0x3c, 0xac, 0x4a, 0x09, 0xbf, 0xe6, 0x3a, 0x85, 0x3a, 0x05, 0xe7, - 0x57, 0x99, 0x03, 0x8d, 0x24, 0x9e, 0x4b, 0x78, 0xa6, 0xf0, 0x3c, 0x87, - 0x67, 0x3f, 0x9e, 0x75, 0xb6, 0x8f, 0x20, 0xef, 0xf9, 0x08, 0x3f, 0xb0, - 0x93, 0x02, 0xdb, 0x34, 0xfd, 0x65, 0x23, 0x47, 0x3f, 0x68, 0x8c, 0xd2, - 0x5f, 0x34, 0xb2, 0xf4, 0xfd, 0x86, 0x45, 0xcf, 0x36, 0x86, 0xe9, 0x7b, - 0x8d, 0x0c, 0xd7, 0x90, 0xc8, 0xe1, 0xd2, 0xf0, 0xcd, 0x17, 0xe8, 0x2b, - 0x6e, 0x03, 0x3e, 0x47, 0xfa, 0xcb, 0xe3, 0x76, 0xfd, 0x3a, 0x2a, 0x3e, - 0xa5, 0x23, 0xcf, 0x54, 0xb9, 0x8e, 0xa3, 0x47, 0xad, 0xbb, 0x13, 0x7c, - 0xf6, 0xc2, 0xe4, 0xba, 0xe6, 0x04, 0xc3, 0xa1, 0x1e, 0x56, 0x90, 0xbf, - 0xb4, 0xd0, 0x64, 0xd2, 0x58, 0x71, 0xd4, 0x74, 0xe0, 0x8f, 0x26, 0x00, - 0x87, 0x35, 0xdd, 0x38, 0xad, 0x9d, 0x86, 0x2d, 0x58, 0xa8, 0xa5, 0x93, - 0x31, 0xf8, 0x3e, 0x99, 0x9f, 0x48, 0xdf, 0xe2, 0xfb, 0xd2, 0xb0, 0xc6, - 0xe4, 0x39, 0x3b, 0x98, 0xe3, 0xf8, 0xa8, 0x03, 0xb6, 0x11, 0xc4, 0x90, - 0xed, 0x34, 0xd9, 0x37, 0x4e, 0x04, 0xfe, 0x71, 0x85, 0x1e, 0x76, 0x07, - 0xec, 0xb7, 0x11, 0x7b, 0x94, 0x96, 0x30, 0x2f, 0xda, 0x0d, 0xde, 0x3c, - 0xef, 0x30, 0xea, 0xf3, 0x74, 0x42, 0xa3, 0xbf, 0x9f, 0x35, 0xf4, 0xc3, - 0x02, 0x01, 0xae, 0xdd, 0xf3, 0xc6, 0x4d, 0xa3, 0x64, 0x8b, 0x0e, 0xfa, - 0xa7, 0x53, 0x1c, 0x93, 0xd7, 0x8f, 0xbd, 0x08, 0x3d, 0xa8, 0x2d, 0xb5, - 0x52, 0xad, 0xa6, 0xd1, 0xe5, 0x91, 0x01, 0xb9, 0x6e, 0xad, 0x9e, 0x40, - 0x9e, 0xd7, 0x46, 0x8b, 0xbd, 0x52, 0xd9, 0xe1, 0xb7, 0x33, 0xd2, 0x6f, - 0x3b, 0x26, 0x9e, 0xf5, 0xb4, 0xbe, 0x95, 0x97, 0x67, 0xa9, 0xe8, 0x76, - 0xa2, 0x42, 0xd9, 0x0d, 0x99, 0x70, 0x7f, 0x40, 0x77, 0x04, 0x62, 0xa0, - 0x36, 0xa0, 0x1f, 0x12, 0xff, 0xed, 0x7d, 0x51, 0x63, 0x39, 0xbe, 0x8e, - 0xd8, 0xc2, 0xb1, 0x52, 0x91, 0x7a, 0xb7, 0xb0, 0xf4, 0xa6, 0xce, 0xfe, - 0xe5, 0x7b, 0xf5, 0xdd, 0xc1, 0x98, 0xfd, 0x3b, 0x8f, 0xdb, 0xe9, 0xfb, - 0xb5, 0x9d, 0xb4, 0x58, 0xe3, 0xf7, 0xad, 0xb4, 0x50, 0x1b, 0xb8, 0xf2, - 0x90, 0xe8, 0xa5, 0xd5, 0xeb, 0x6e, 0xd6, 0x3f, 0x2f, 0x20, 0x93, 0x89, - 0x0f, 0xe9, 0xdd, 0x91, 0x2e, 0x7a, 0xf5, 0x5e, 0xa3, 0x7a, 0xbf, 0x80, - 0x3e, 0x8e, 0xc4, 0xd9, 0xce, 0xd0, 0xe7, 0x79, 0xe3, 0x4a, 0x5a, 0xb0, - 0x9e, 0xbd, 0x0c, 0xfd, 0x32, 0x4e, 0xfa, 0x3a, 0xc9, 0xb4, 0x99, 0x2e, - 0xce, 0xc7, 0x7c, 0x05, 0x34, 0xf1, 0xae, 0x3e, 0x00, 0x5a, 0xaf, 0x48, - 0x59, 0x1c, 0xb6, 0x8c, 0x2b, 0x08, 0x51, 0xde, 0x65, 0x73, 0x20, 0x23, - 0xc4, 0x6e, 0xaa, 0xa5, 0x6e, 0xd6, 0xbf, 0x8b, 0x78, 0x80, 0x9a, 0xab, - 0xb4, 0x4e, 0xeb, 0xc7, 0x2e, 0x9a, 0xac, 0x8b, 0x6c, 0xc3, 0x3f, 0x44, - 0x4e, 0xaa, 0xd3, 0x53, 0x75, 0xf6, 0x5d, 0x4c, 0x8b, 0xeb, 0x82, 0x7d, - 0xfa, 0xdd, 0xe0, 0xc1, 0x19, 0xc6, 0x3b, 0xcc, 0xab, 0x9f, 0xe5, 0x73, - 0x6b, 0x61, 0xdc, 0x4c, 0x9a, 0x37, 0xb3, 0x45, 0x46, 0x03, 0xfa, 0x5e, - 0xc1, 0xeb, 0xbd, 0x8b, 0x75, 0xdf, 0x01, 0xaf, 0x03, 0xc0, 0x45, 0x0c, - 0x4d, 0x35, 0xaf, 0xf1, 0x9a, 0x5c, 0xe3, 0x54, 0x1d, 0x39, 0xe0, 0xc6, - 0x1a, 0x98, 0xab, 0x0b, 0xec, 0xf3, 0x57, 0x65, 0xfe, 0xac, 0x22, 0xff, - 0xb9, 0x3c, 0xf2, 0x4c, 0x90, 0x5f, 0x3c, 0x07, 0x59, 0xc7, 0xe8, 0xb5, - 0x59, 0xae, 0x2f, 0x0f, 0x51, 0x39, 0xb1, 0x7e, 0x6c, 0xca, 0x44, 0x4d, - 0x8f, 0x38, 0x50, 0xde, 0x37, 0xe0, 0xeb, 0x55, 0x3f, 0xe3, 0x3c, 0x27, - 0xcf, 0xa4, 0x2c, 0x5a, 0xe9, 0x8b, 0x5a, 0x1a, 0xf8, 0x3c, 0x77, 0x29, - 0x38, 0xcf, 0x6f, 0x83, 0x1f, 0xf4, 0xeb, 0x3d, 0x81, 0xff, 0x4b, 0x40, - 0x57, 0x87, 0xf4, 0xc3, 0x14, 0x0b, 0xfc, 0x5f, 0x82, 0x5e, 0x3d, 0xad, - 0x42, 0x87, 0x58, 0x7f, 0xfa, 0xbb, 0x37, 0xf5, 0x87, 0xdf, 0xad, 0x1f, - 0x73, 0xc0, 0x63, 0x7e, 0xae, 0x95, 0x0a, 0xd5, 0x18, 0x4d, 0x65, 0x91, - 0x73, 0x23, 0xfe, 0xe4, 0xa1, 0x4b, 0x85, 0x1a, 0xeb, 0x72, 0x29, 0xd0, - 0xe5, 0x78, 0x40, 0xfb, 0x6f, 0xa0, 0xcb, 0x46, 0x7a, 0x55, 0x70, 0x7d, - 0xd5, 0x27, 0x6b, 0x64, 0x15, 0xf6, 0x55, 0xac, 0x70, 0x2c, 0x62, 0xdb, - 0xa2, 0xe3, 0xcc, 0x7f, 0xb1, 0x32, 0x2a, 0x8a, 0x8d, 0xac, 0x28, 0xba, - 0xcc, 0xdf, 0x3e, 0xf0, 0xad, 0xc8, 0x3a, 0x78, 0xa1, 0xf1, 0xae, 0xb7, - 0xb0, 0x6f, 0x07, 0xfa, 0xd0, 0xfd, 0x71, 0x3e, 0xdf, 0xeb, 0x99, 0xaf, - 0xb4, 0x2d, 0x58, 0xde, 0x49, 0x5a, 0x1e, 0x7c, 0xa9, 0x8b, 0x73, 0xb4, - 0xb3, 0x83, 0x4c, 0x1f, 0x7c, 0x24, 0x93, 0xb4, 0xe8, 0xf2, 0x1a, 0x2c, - 0x17, 0xf8, 0xba, 0x39, 0x9d, 0x1e, 0x96, 0xe7, 0xc7, 0xba, 0xc5, 0xf7, - 0x4d, 0x2a, 0xe5, 0x13, 0x03, 0xfa, 0x43, 0x64, 0x5c, 0x59, 0x53, 0x8d, - 0xea, 0x24, 0xe2, 0xea, 0xc2, 0xbc, 0x4a, 0x7b, 0x64, 0x1d, 0xc6, 0x67, - 0x64, 0x9c, 0x84, 0x35, 0x06, 0x7b, 0xff, 0x8d, 0xa6, 0xbd, 0x77, 0xd2, - 0xc5, 0xd3, 0x9f, 0x85, 0xdd, 0xb3, 0x5c, 0xb5, 0xf4, 0x11, 0xe4, 0x19, - 0x73, 0x04, 0xf9, 0x22, 0x7f, 0xb6, 0x53, 0xe1, 0xb9, 0xb0, 0xbc, 0x77, - 0x49, 0xf9, 0x0b, 0x29, 0xff, 0x1b, 0xa8, 0xdc, 0xeb, 0xdb, 0x38, 0xbf, - 0x13, 0xa0, 0xe1, 0xbf, 0xe3, 0xf1, 0x67, 0x90, 0x1f, 0xf1, 0xbb, 0x9a, - 0x8f, 0x47, 0x3d, 0x4c, 0x07, 0xef, 0xfe, 0x10, 0x6b, 0xb2, 0x8c, 0xc3, - 0xf9, 0x0e, 0xf2, 0x6d, 0x29, 0x94, 0x3b, 0x12, 0x8c, 0x7a, 0x92, 0x7e, - 0xad, 0x9e, 0xa2, 0x89, 0x7a, 0x3f, 0x15, 0xea, 0x69, 0x9c, 0xc1, 0x13, - 0xdd, 0xbc, 0xb7, 0xfc, 0x12, 0xf6, 0x23, 0x98, 0xd7, 0x1a, 0x1d, 0x71, - 0x43, 0x7e, 0xe2, 0x01, 0x7f, 0x5a, 0x30, 0x8e, 0x05, 0x3c, 0x34, 0xd3, - 0x8b, 0x83, 0x96, 0x0d, 0x3a, 0x67, 0x02, 0x3a, 0xec, 0x47, 0xc0, 0xeb, - 0x44, 0x8a, 0x96, 0x5c, 0xe6, 0x63, 0x27, 0x95, 0x93, 0xdc, 0x7f, 0x0e, - 0x7a, 0xc6, 0x74, 0x76, 0x70, 0x7e, 0xb3, 0x45, 0xc6, 0x47, 0xeb, 0x25, - 0xc8, 0x98, 0xe5, 0xcb, 0x70, 0x71, 0x5a, 0xf8, 0x25, 0x3e, 0xbf, 0x21, - 0xe4, 0xf8, 0xac, 0x0b, 0x3b, 0x03, 0xbd, 0xf2, 0xd7, 0x2c, 0xcc, 0x75, - 0xe2, 0xac, 0x78, 0xdd, 0x76, 0xba, 0x07, 0x76, 0x9f, 0xaf, 0xf1, 0xfa, - 0x13, 0xd0, 0xa3, 0x1f, 0xcb, 0xf5, 0x0b, 0x4b, 0xbd, 0x01, 0x3e, 0xe3, - 0x76, 0x6e, 0xc3, 0x6d, 0xa5, 0x03, 0x55, 0xfd, 0x63, 0xf0, 0x7f, 0x13, - 0xf8, 0x82, 0xce, 0x64, 0x19, 0x9f, 0xe9, 0x00, 0xae, 0x96, 0xfc, 0x04, - 0x3a, 0x09, 0x59, 0xef, 0xe7, 0x6b, 0xad, 0x94, 0xaf, 0x86, 0xb4, 0x98, - 0xce, 0x87, 0xa8, 0x87, 0xbf, 0x2c, 0x69, 0x4d, 0x49, 0x5a, 0x78, 0x5f, - 0x63, 0x9f, 0x73, 0x3b, 0xf0, 0xe3, 0xec, 0xff, 0x69, 0x21, 0xd1, 0x41, - 0x0b, 0xb2, 0xa6, 0x6f, 0xf7, 0x7d, 0x4d, 0xa2, 0x0d, 0xef, 0x77, 0xc1, - 0xe6, 0x87, 0x90, 0x5b, 0x74, 0x62, 0x2e, 0xbd, 0x6d, 0x6e, 0x3b, 0xff, - 0xb1, 0x6d, 0xfc, 0xeb, 0x80, 0xeb, 0xc1, 0x9a, 0x3e, 0x5c, 0x01, 0x70, - 0xd3, 0x73, 0x90, 0xb3, 0xc5, 0x7e, 0x85, 0xe3, 0xe4, 0x75, 0x92, 0x97, - 0xe9, 0x25, 0x05, 0x70, 0xbd, 0xc0, 0x0d, 0xc7, 0xbe, 0x1c, 0xaa, 0xa0, - 0xf3, 0xcd, 0x9a, 0xbc, 0xbb, 0xc0, 0x19, 0xf4, 0x24, 0x78, 0xef, 0xe5, - 0xda, 0xa7, 0xc9, 0xec, 0xba, 0x26, 0x79, 0xb1, 0xac, 0x98, 0x5f, 0xe6, - 0x15, 0x7a, 0x8a, 0x38, 0xe4, 0x58, 0xa8, 0x0b, 0x13, 0x2a, 0x15, 0xb2, - 0x3a, 0xf2, 0x73, 0xbe, 0xb7, 0x65, 0xbb, 0xd4, 0xf9, 0xae, 0x34, 0x26, - 0x4c, 0x8e, 0xb5, 0x9a, 0xdc, 0xfb, 0x91, 0x25, 0xbe, 0xbb, 0x4d, 0xf3, - 0x5d, 0x5f, 0x86, 0xb0, 0xf7, 0x07, 0x97, 0x4c, 0x7a, 0xa4, 0x9e, 0xa1, - 0x87, 0xea, 0x86, 0x7e, 0x3f, 0x7c, 0x40, 0x71, 0xe3, 0x4e, 0xf7, 0x73, - 0x09, 0xae, 0x45, 0x34, 0xe4, 0x81, 0x2d, 0xa6, 0x9f, 0x17, 0x94, 0xb9, - 0x66, 0x9b, 0x33, 0xf8, 0x1e, 0x47, 0xaf, 0xd1, 0xf6, 0xdc, 0xe1, 0xff, - 0x32, 0x6f, 0xe0, 0xf5, 0xd9, 0x5f, 0x23, 0x4f, 0x70, 0x91, 0x27, 0xb8, - 0xc8, 0x13, 0x5c, 0xe4, 0x09, 0x2e, 0xf2, 0x04, 0x17, 0x79, 0x82, 0x8b, - 0x3c, 0xc1, 0x45, 0x9e, 0x80, 0xd8, 0xed, 0xd7, 0x0b, 0x63, 0xc8, 0x7f, - 0xe1, 0xbf, 0xdc, 0xcf, 0x43, 0x4e, 0x7c, 0xdf, 0xc9, 0x31, 0x87, 0x63, - 0x33, 0xcf, 0xad, 0xee, 0x70, 0xf8, 0xdc, 0xa4, 0xef, 0xbb, 0x13, 0x73, - 0xe3, 0x41, 0x3e, 0xc2, 0x30, 0x61, 0xec, 0x66, 0x38, 0x1a, 0x75, 0x2c, - 0x05, 0x36, 0xc6, 0xf9, 0x8a, 0x1f, 0xb3, 0xfc, 0x5c, 0xf9, 0x75, 0xe4, - 0x2c, 0x69, 0xe4, 0x2c, 0xfd, 0xc8, 0x4f, 0xf8, 0x8e, 0x3b, 0xbc, 0x63, - 0xb2, 0x95, 0xc3, 0xee, 0x98, 0x72, 0xb7, 0xcb, 0xb9, 0xb4, 0x99, 0x2e, - 0x0a, 0x31, 0xd7, 0x43, 0x1e, 0xe5, 0x47, 0xbe, 0x86, 0xbc, 0xf5, 0x9b, - 0xf2, 0x3e, 0x6d, 0x7c, 0x90, 0xcf, 0x7c, 0xe5, 0x1a, 0xb9, 0x6b, 0x28, - 0x5f, 0xff, 0x1e, 0x50, 0x2c, 0xb0, 0xfc, 0x88, 0xba, 0xcf, 0x43, 0xe0, - 0xe7, 0x63, 0x94, 0x58, 0xde, 0x89, 0x39, 0x9d, 0x7a, 0xe4, 0x5d, 0x12, - 0x8e, 0xf2, 0xbc, 0xd6, 0x43, 0xed, 0x26, 0x89, 0xf3, 0x7c, 0xe3, 0xc0, - 0x74, 0xd9, 0xbf, 0x5e, 0x3a, 0x96, 0xaf, 0x5d, 0x92, 0x3a, 0x75, 0xb8, - 0x5e, 0x40, 0x7d, 0xd4, 0x07, 0x18, 0x0d, 0xb5, 0x55, 0x48, 0x9b, 0x69, - 0x5e, 0x4d, 0xc8, 0x9a, 0xe7, 0xfc, 0xc6, 0x79, 0xe2, 0xac, 0x79, 0x9d, - 0x4b, 0xc7, 0xca, 0x55, 0x23, 0xc5, 0xb5, 0xb2, 0xad, 0x5f, 0x3a, 0x76, - 0x02, 0x34, 0x16, 0x91, 0x1b, 0xa8, 0x72, 0xed, 0x4b, 0xc7, 0xa6, 0xab, - 0xfe, 0x7d, 0x96, 0xcf, 0x03, 0xe2, 0x60, 0xb6, 0x9d, 0xd4, 0x05, 0xff, - 0x5e, 0x4b, 0x48, 0x5c, 0xc6, 0x63, 0x7c, 0x0d, 0x78, 0x7c, 0x6e, 0x19, - 0xe0, 0xf2, 0xd9, 0x31, 0x0f, 0x97, 0x8e, 0x95, 0x6a, 0xcd, 0x3c, 0x30, - 0x1d, 0xa6, 0x1b, 0xee, 0x87, 0xf7, 0x92, 0x20, 0xb1, 0xec, 0x79, 0xc5, - 0x91, 0xfe, 0x20, 0xef, 0x3a, 0x81, 0xfc, 0x4e, 0x93, 0x7a, 0xee, 0x8f, - 0xff, 0x4c, 0xc6, 0xa9, 0xb4, 0xe0, 0x79, 0x7e, 0xe2, 0x5d, 0xf6, 0x3b, - 0x98, 0xc3, 0x78, 0x31, 0x84, 0x15, 0x01, 0x6c, 0x47, 0x93, 0x3c, 0x5b, - 0x82, 0xf5, 0x98, 0x27, 0xde, 0xe7, 0xcf, 0xb1, 0x7f, 0x79, 0x07, 0xc7, - 0xf9, 0x18, 0xd6, 0xc5, 0x59, 0xba, 0xff, 0x5b, 0xd9, 0x37, 0xef, 0x89, - 0x65, 0xaa, 0x01, 0x87, 0xe1, 0x99, 0x46, 0x88, 0x83, 0x17, 0xe7, 0x7d, - 0x3c, 0xb1, 0x71, 0xff, 0xf7, 0x49, 0xeb, 0x36, 0xf3, 0x1a, 0xae, 0x1f, - 0xd2, 0xc9, 0xf8, 0xe7, 0xb6, 0x81, 0x2f, 0xff, 0x4f, 0x31, 0x3c, 0xa1, - 0x8b, 0x1f, 0xb9, 0x47, 0xcd, 0x34, 0xd5, 0xa1, 0xe1, 0xfd, 0x05, 0xdf, - 0x07, 0x70, 0x7d, 0xcf, 0xdf, 0x1a, 0x9a, 0x6b, 0xc5, 0x67, 0x83, 0x58, - 0xd6, 0x47, 0xb6, 0xc6, 0x75, 0xc3, 0x85, 0x60, 0xbc, 0x0b, 0xb1, 0x8d, - 0xc7, 0x0d, 0xc8, 0x17, 0xba, 0x6c, 0xb5, 0x07, 0x75, 0x4b, 0xc2, 0xff, - 0x26, 0x94, 0x61, 0x3b, 0xe2, 0xba, 0xaf, 0x2d, 0x98, 0x0b, 0xed, 0x88, - 0xfd, 0xb0, 0x16, 0xcc, 0xb1, 0xbf, 0x15, 0xa8, 0x5d, 0xb8, 0x0f, 0x3a, - 0x8b, 0xcd, 0xb6, 0x14, 0x3e, 0x13, 0x74, 0x6e, 0x3e, 0xf4, 0x5b, 0xf0, - 0x29, 0x83, 0x5a, 0xe0, 0xfb, 0xe3, 0xf0, 0x7d, 0x9d, 0x74, 0x00, 0x3e, - 0xeb, 0x20, 0x7c, 0xd6, 0x21, 0xd4, 0x8b, 0x63, 0x4b, 0xcd, 0xf7, 0xbc, - 0x5c, 0xa3, 0x76, 0x2a, 0x47, 0xe4, 0xf9, 0x97, 0x3c, 0xd5, 0xfc, 0x10, - 0x3a, 0xc0, 0x75, 0x57, 0xa8, 0x13, 0xf0, 0xb7, 0x56, 0x02, 0x3a, 0xb1, - 0xfd, 0x3e, 0x39, 0x03, 0xdb, 0x68, 0xb7, 0x85, 0xcc, 0xe5, 0x7c, 0xd9, - 0x97, 0x6b, 0xbe, 0xec, 0xe1, 0x97, 0x41, 0x5f, 0xa3, 0x52, 0x5d, 0xa7, - 0x12, 0xd6, 0x2d, 0x61, 0xdd, 0x12, 0xea, 0xbc, 0xe9, 0x7a, 0xf3, 0x77, - 0xaf, 0x8e, 0x80, 0x77, 0xc6, 0x0d, 0xfb, 0x7a, 0xd3, 0xfe, 0xc3, 0xe7, - 0x49, 0xc8, 0xff, 0x11, 0xc8, 0xff, 0x28, 0xea, 0x9b, 0xdf, 0x47, 0x7d, - 0xf3, 0x7b, 0xa8, 0x6f, 0x8e, 0xa0, 0xbe, 0x99, 0x44, 0x7d, 0xf3, 0x65, - 0xf8, 0x8f, 0xfb, 0xe0, 0x3f, 0x26, 0xe0, 0x3f, 0xc6, 0xe5, 0xdd, 0xd3, - 0x61, 0x77, 0xfb, 0x9d, 0x4a, 0xb8, 0x16, 0xb7, 0x9f, 0x12, 0x99, 0x25, - 0xec, 0x69, 0x8c, 0x6a, 0x0d, 0xae, 0x6f, 0x2c, 0x72, 0x46, 0xb9, 0xbe, - 0x99, 0x50, 0x26, 0x91, 0xbf, 0xdf, 0x3f, 0xcc, 0x75, 0x4f, 0x42, 0xc9, - 0xcb, 0xba, 0xc7, 0xb8, 0xe0, 0x20, 0x75, 0x43, 0xee, 0x87, 0x3d, 0x1b, - 0xe7, 0xf2, 0xe0, 0xc5, 0xcf, 0xf9, 0xba, 0x03, 0xbf, 0x17, 0xa7, 0xc5, - 0x59, 0xd4, 0x0c, 0xee, 0x3f, 0x28, 0x45, 0xe9, 0x1b, 0x75, 0x8c, 0x51, - 0x2b, 0xbb, 0xaf, 0x06, 0xe3, 0x11, 0x9a, 0x9a, 0x47, 0x6d, 0x7b, 0xfa, - 0x6f, 0x95, 0xbc, 0x1c, 0x5b, 0x18, 0x23, 0xdf, 0x3d, 0xfd, 0xd7, 0xc1, - 0xb8, 0x14, 0xe8, 0x43, 0xc0, 0xab, 0x6e, 0xe1, 0xd9, 0x15, 0xe4, 0x1c, - 0x2f, 0xf6, 0x6c, 0xfd, 0x3f, 0xef, 0xb8, 0xb5, 0x28, 0x64, 0x1e, 0xdf, - 0xe5, 0xd7, 0x67, 0xcd, 0xf3, 0x9d, 0x4d, 0xf3, 0xba, 0xfc, 0x0e, 0x5b, - 0xac, 0xb4, 0xbd, 0x07, 0x0f, 0x4c, 0x4b, 0x83, 0x46, 0xd5, 0xa6, 0x0f, - 0x3d, 0xfe, 0x5e, 0xe8, 0x88, 0x76, 0xf9, 0x0d, 0xcf, 0x91, 0xf7, 0x7a, - 0xb0, 0xf3, 0x91, 0x27, 0x77, 0xf9, 0xbe, 0x80, 0xfb, 0x49, 0xc5, 0xf7, - 0xef, 0x8f, 0x83, 0x0e, 0x64, 0xed, 0x36, 0xd7, 0x70, 0x7a, 0x70, 0x97, - 0xa2, 0x1f, 0x9f, 0xe1, 0xb3, 0x96, 0xb4, 0xb9, 0xd6, 0xe3, 0xba, 0x2f, - 0x8c, 0x01, 0x21, 0xad, 0xff, 0x48, 0xfa, 0x7c, 0xdf, 0x87, 0x9a, 0x8e, - 0x61, 0xc2, 0x71, 0x73, 0xfd, 0x17, 0x0f, 0xee, 0xe1, 0x98, 0xd7, 0x58, - 0xc0, 0xab, 0x16, 0xd0, 0xfb, 0x77, 0xcf, 0xf7, 0x3d, 0x8c, 0xaf, 0x37, - 0xe1, 0x5f, 0x40, 0xae, 0xc7, 0x77, 0x26, 0xbb, 0xe5, 0x77, 0xc9, 0x77, - 0x66, 0x3b, 0xe8, 0xed, 0x53, 0xc8, 0x59, 0x2d, 0x23, 0x73, 0x09, 0xb5, - 0xc7, 0x32, 0xdb, 0xc9, 0x08, 0xf3, 0x39, 0x90, 0x9e, 0xa6, 0x9b, 0x7b, - 0xfc, 0x5c, 0xfc, 0xab, 0xca, 0x47, 0xf9, 0x16, 0xc1, 0x3a, 0x3f, 0x6a, - 0x5a, 0x27, 0xdd, 0xb4, 0xce, 0x0a, 0xdb, 0x6c, 0xed, 0x4b, 0xd8, 0x73, - 0x69, 0xf7, 0xcd, 0x7a, 0x32, 0xa8, 0xcb, 0x1e, 0x1e, 0x69, 0xa3, 0x6a, - 0xaf, 0xb1, 0xf2, 0x1a, 0xf2, 0xf5, 0xe2, 0x08, 0xe6, 0x92, 0x03, 0x78, - 0xc7, 0xf3, 0x46, 0x8d, 0x84, 0xb1, 0x52, 0xa3, 0xcf, 0x01, 0xdf, 0x28, - 0x11, 0xf1, 0x3c, 0xf7, 0x25, 0x6f, 0xb5, 0xc0, 0x07, 0xa4, 0xd6, 0xb0, - 0xe7, 0x49, 0xd4, 0x5f, 0x47, 0x37, 0xea, 0x61, 0x5e, 0xe7, 0x56, 0x65, - 0x4d, 0xe6, 0xc6, 0xfb, 0x95, 0x52, 0xd2, 0xdf, 0xe3, 0xef, 0xc2, 0x5f, - 0xa8, 0x82, 0x71, 0xdf, 0x01, 0x6d, 0x85, 0x16, 0x4e, 0xa9, 0xf2, 0x0e, - 0xb6, 0x38, 0xc2, 0x67, 0xcd, 0xcf, 0x8f, 0x93, 0x5d, 0xb8, 0xa7, 0x3f, - 0x0d, 0xf6, 0x34, 0x16, 0xd4, 0xd3, 0xe1, 0x9e, 0x62, 0xf4, 0xe6, 0xac, - 0x0e, 0xdc, 0x9b, 0x20, 0x8f, 0x02, 0x2d, 0x35, 0xd2, 0x9f, 0x42, 0xa7, - 0xd2, 0x24, 0x1b, 0x6d, 0xdb, 0x19, 0x96, 0x36, 0x6b, 0xf8, 0xf1, 0x14, - 0xec, 0xf0, 0x78, 0x4f, 0x78, 0x37, 0xac, 0x9a, 0x1e, 0xd7, 0x3d, 0x68, - 0x3c, 0xdf, 0x0f, 0x5b, 0x4c, 0xc3, 0x3e, 0x39, 0x67, 0x2a, 0x70, 0xad, - 0xc2, 0xf6, 0xa4, 0x3b, 0xaa, 0xa1, 0x4f, 0x50, 0x06, 0xf5, 0x0e, 0xef, - 0x3f, 0x47, 0x8b, 0x8d, 0x90, 0x87, 0x2c, 0xec, 0x71, 0x14, 0xbf, 0x61, - 0xbc, 0xb3, 0xf0, 0xe3, 0x5a, 0x69, 0x85, 0x1e, 0x95, 0xb9, 0x38, 0x72, - 0xed, 0x41, 0xe6, 0xef, 0x4e, 0xc0, 0xb3, 0x3e, 0xb3, 0x9e, 0xde, 0x49, - 0x4e, 0x2f, 0xfb, 0x8a, 0x14, 0x68, 0x03, 0xc7, 0x5d, 0x87, 0xad, 0xf7, - 0xe3, 0x69, 0xe8, 0x45, 0x96, 0xad, 0xa4, 0xef, 0x79, 0x6a, 0x96, 0xbf, - 0x51, 0x5c, 0x08, 0xc6, 0x03, 0xfa, 0x3d, 0xac, 0x7b, 0xa9, 0x1b, 0x68, - 0x65, 0x3e, 0x8c, 0x83, 0x67, 0x60, 0x83, 0x7c, 0x67, 0x3b, 0x06, 0xb9, - 0xf0, 0x58, 0x09, 0xe2, 0x21, 0xe6, 0x17, 0x91, 0x94, 0xb4, 0xe7, 0x68, - 0x19, 0xf5, 0x3f, 0xf5, 0xf2, 0x13, 0xf9, 0xae, 0xbb, 0x33, 0xd0, 0xf7, - 0xad, 0xf8, 0xaa, 0xc9, 0xfd, 0x31, 0xf0, 0xa7, 0x35, 0xe1, 0x33, 0x8e, - 0x5f, 0x9f, 0xac, 0x11, 0xe2, 0x71, 0xca, 0xfb, 0x82, 0xc8, 0x3d, 0x4d, - 0xbf, 0x23, 0xf7, 0x54, 0xa7, 0x23, 0xf3, 0xa8, 0x6d, 0xb3, 0x03, 0x99, - 0x45, 0x32, 0x32, 0x27, 0x68, 0x48, 0x3f, 0x40, 0xaa, 0xfc, 0xd6, 0x97, - 0x16, 0xde, 0x17, 0x5a, 0x72, 0x9e, 0x77, 0x06, 0xbc, 0xbf, 0x28, 0xd7, - 0x79, 0x1a, 0xfc, 0x43, 0x56, 0xb2, 0x26, 0x61, 0x5e, 0xf1, 0x4c, 0x32, - 0xbf, 0x15, 0x3a, 0xd2, 0xf8, 0x61, 0x70, 0x36, 0x8f, 0x90, 0xe3, 0xbe, - 0xa5, 0x3a, 0x66, 0x05, 0xb0, 0xdf, 0x09, 0x78, 0xcb, 0x81, 0x5f, 0xac, - 0xdf, 0x58, 0x4f, 0xb2, 0x6f, 0xe0, 0x33, 0x77, 0x90, 0x35, 0x3a, 0x23, - 0xc8, 0xa3, 0x92, 0xd7, 0xf2, 0x03, 0x09, 0xda, 0xea, 0x07, 0x18, 0x2f, - 0xf1, 0x31, 0xba, 0xc2, 0x7c, 0x94, 0xa4, 0xff, 0x94, 0x71, 0x4b, 0xd2, - 0x53, 0xb7, 0xf9, 0x82, 0x6f, 0xc9, 0xe7, 0xaa, 0xca, 0xbe, 0x89, 0xe3, - 0x1f, 0xeb, 0x70, 0x27, 0xfc, 0x1f, 0x74, 0x10, 0x76, 0x9c, 0x9f, 0xe7, - 0xfb, 0x89, 0x41, 0xbe, 0x57, 0x3a, 0x57, 0xc0, 0xd9, 0x2e, 0xf0, 0xf7, - 0xc7, 0xa4, 0x5f, 0x63, 0xfa, 0xf5, 0x57, 0x9a, 0x7d, 0x21, 0xda, 0x92, - 0xf4, 0x93, 0x05, 0xf9, 0xbd, 0x31, 0x01, 0x18, 0x8f, 0x7d, 0x67, 0xd3, - 0xdf, 0x58, 0xbc, 0x6c, 0xfb, 0x7f, 0x63, 0x11, 0x7c, 0xfb, 0xad, 0xf9, - 0x79, 0xc4, 0x83, 0x75, 0x8d, 0x26, 0xeb, 0xe1, 0xdf, 0x5c, 0xf0, 0x39, - 0xc0, 0x37, 0xd7, 0xc3, 0xdc, 0xc1, 0x93, 0xf1, 0xa5, 0xbc, 0xe5, 0x2c, - 0x97, 0x82, 0x9c, 0x88, 0x6b, 0x00, 0x96, 0x21, 0xc6, 0x8b, 0xfe, 0xf9, - 0x2d, 0x88, 0x3d, 0x38, 0x3f, 0xc8, 0x1c, 0x7c, 0xbd, 0x39, 0xeb, 0xd7, - 0xb9, 0x65, 0xf6, 0x8b, 0xfd, 0x61, 0xdd, 0xbb, 0x9b, 0xca, 0x13, 0xfc, - 0x3e, 0x46, 0x6f, 0xcc, 0xc6, 0xe4, 0xfb, 0x22, 0xc5, 0x82, 0xf7, 0x3c, - 0x4e, 0x50, 0x51, 0xbe, 0xaf, 0x05, 0xf4, 0x50, 0xa7, 0xdd, 0x17, 0x8e, - 0x35, 0xe5, 0x48, 0xc3, 0xc7, 0x9b, 0x6a, 0xd4, 0xe8, 0xd1, 0xc6, 0x2a, - 0xf6, 0xaf, 0x50, 0x7e, 0xbc, 0x44, 0x37, 0x98, 0xba, 0x8c, 0xfb, 0x4e, - 0x82, 0x75, 0x8c, 0xf5, 0x6b, 0x4c, 0xd6, 0x9d, 0x25, 0xe4, 0x0b, 0xc5, - 0x11, 0xfe, 0xc6, 0xf3, 0xde, 0x5d, 0xc5, 0x8a, 0xa1, 0xdb, 0xf4, 0x81, - 0xe7, 0x68, 0x3c, 0x26, 0x21, 0x72, 0xab, 0x77, 0x3d, 0x58, 0xbf, 0x78, - 0x97, 0xbf, 0x57, 0xbc, 0xaf, 0x33, 0xac, 0x2a, 0xbf, 0xcd, 0xfe, 0xe4, - 0x76, 0x8d, 0xd6, 0x6e, 0xf7, 0xbc, 0xfb, 0x2d, 0x9d, 0x9c, 0xa0, 0x76, - 0xf5, 0xbf, 0xb9, 0xb7, 0xcb, 0x1c, 0xc4, 0x19, 0x49, 0x2b, 0x05, 0xd8, - 0xeb, 0xb2, 0x8b, 0x3a, 0x47, 0x18, 0xa3, 0xab, 0x42, 0x47, 0xcc, 0xe5, - 0x3b, 0x80, 0x3b, 0x7a, 0xf8, 0x7b, 0xf3, 0x8c, 0xc5, 0x30, 0x7d, 0xfe, - 0x5d, 0xd7, 0x2d, 0xf7, 0x49, 0x3f, 0x4b, 0x14, 0xc4, 0x9e, 0x5b, 0x9a, - 0x6d, 0xa2, 0x39, 0xb7, 0x64, 0x5b, 0xa0, 0x49, 0x0d, 0xbc, 0x94, 0x2b, - 0x61, 0x9e, 0xc6, 0x7f, 0x4b, 0xb0, 0x7a, 0xd7, 0x37, 0xc0, 0xe7, 0x34, - 0xf8, 0xe4, 0x7d, 0x4c, 0xd7, 0x43, 0x9d, 0x0b, 0x6b, 0x05, 0xee, 0x23, - 0xe6, 0xbb, 0x88, 0xf9, 0x2e, 0x62, 0xbe, 0x8b, 0x98, 0xef, 0x22, 0xe6, - 0xbb, 0x88, 0xf9, 0x2e, 0x62, 0xbe, 0x8b, 0x98, 0xef, 0x8e, 0x07, 0x79, - 0xda, 0x63, 0x1b, 0x79, 0xda, 0x4a, 0x83, 0xbf, 0x43, 0x49, 0x5e, 0x4a, - 0x25, 0xf2, 0xf3, 0x5c, 0x12, 0x9c, 0xd3, 0x84, 0x79, 0xee, 0xc7, 0x7f, - 0x13, 0xf1, 0xf1, 0x38, 0xc7, 0x63, 0xbc, 0x92, 0x22, 0x4c, 0xc6, 0xf3, - 0xf3, 0x3c, 0xae, 0xad, 0xb6, 0xe2, 0x20, 0x5f, 0xcb, 0xb1, 0x3f, 0x63, - 0xbb, 0x48, 0xfa, 0xf5, 0x62, 0xee, 0xf5, 0x2f, 0xa1, 0x76, 0x3c, 0x5e, - 0xac, 0xcb, 0x18, 0x8c, 0xf1, 0x7b, 0x18, 0x6b, 0xac, 0x73, 0xfc, 0xee, - 0x5e, 0xae, 0x27, 0x8a, 0xf5, 0x14, 0x95, 0x16, 0xc3, 0xfc, 0x07, 0x78, - 0xee, 0x90, 0x52, 0xa8, 0xf2, 0xd9, 0x0a, 0x9a, 0x4e, 0x42, 0x28, 0x66, - 0x73, 0x5e, 0x77, 0x49, 0xd6, 0x48, 0xfe, 0xdf, 0x05, 0x0d, 0x83, 0xb7, - 0xf0, 0x1e, 0x97, 0x48, 0x9d, 0x4d, 0xca, 0xbf, 0x31, 0x48, 0x98, 0x83, - 0xf2, 0x6f, 0x1d, 0xba, 0xb1, 0x8e, 0x98, 0xdd, 0x13, 0xfe, 0xed, 0x06, - 0xd7, 0x5d, 0xf6, 0xe6, 0xfd, 0x2b, 0xef, 0x23, 0x09, 0x7b, 0xbd, 0xa7, - 0x0f, 0x7b, 0xc3, 0xb9, 0x5e, 0xd9, 0x25, 0xf3, 0x6e, 0xf8, 0xce, 0x33, - 0x83, 0x37, 0xf5, 0x52, 0xe7, 0x6e, 0x5a, 0x1e, 0xe4, 0x1a, 0xad, 0x0d, - 0xf4, 0x18, 0xd6, 0xc8, 0xd8, 0x62, 0x37, 0x9d, 0x9d, 0x87, 0x6f, 0x9d, - 0x37, 0x2c, 0xfe, 0xfb, 0x82, 0x85, 0xc1, 0x24, 0x7c, 0xf2, 0x78, 0x2f, - 0xc7, 0xe4, 0xc5, 0x06, 0xeb, 0x4a, 0x37, 0xf0, 0xfb, 0xa1, 0x8b, 0x3b, - 0x60, 0x43, 0x02, 0xeb, 0x87, 0xb4, 0xff, 0x53, 0xd2, 0xee, 0x36, 0xf3, - 0x7d, 0x52, 0x37, 0x84, 0xa1, 0xa7, 0x05, 0x78, 0xff, 0x48, 0x6d, 0x69, - 0x11, 0x7f, 0x2f, 0x9c, 0x76, 0x9b, 0xbf, 0x1b, 0x0e, 0x29, 0xc5, 0x2a, - 0xff, 0x8d, 0xc3, 0x20, 0xfd, 0x4f, 0xe1, 0x56, 0x17, 0xd3, 0xd6, 0x79, - 0x86, 0xdf, 0xcf, 0xe6, 0x2f, 0xc4, 0x81, 0x13, 0xe2, 0x80, 0x41, 0x54, - 0xf3, 0x31, 0x07, 0xe2, 0xca, 0x44, 0x3d, 0x20, 0x32, 0x59, 0x15, 0x52, - 0x2d, 0xdb, 0x50, 0xb7, 0x5d, 0x36, 0x77, 0xcb, 0xa6, 0x4c, 0xda, 0x22, - 0x06, 0x49, 0x9b, 0x6a, 0xd2, 0x2e, 0x76, 0x31, 0xed, 0x2e, 0x96, 0x81, - 0x34, 0xcd, 0xec, 0x1a, 0x56, 0x32, 0xa4, 0x5d, 0x4c, 0xae, 0x31, 0x04, - 0x88, 0x53, 0xab, 0x5b, 0x2f, 0x32, 0x4d, 0x53, 0x90, 0x57, 0x25, 0xdd, - 0x4d, 0x6f, 0x76, 0x3f, 0x55, 0x64, 0xad, 0x72, 0xd1, 0x25, 0x6a, 0xa7, - 0x6a, 0x7f, 0x17, 0x67, 0xcf, 0xf3, 0x9d, 0x63, 0x20, 0x6c, 0xd5, 0x90, - 0xac, 0xf3, 0x9d, 0xef, 0x7c, 0xff, 0xdf, 0xfb, 0x3e, 0xef, 0x2f, 0x53, - 0xa0, 0x2f, 0xc3, 0x8a, 0xa9, 0x4b, 0x65, 0xb6, 0xb1, 0x50, 0xa6, 0x1d, - 0x7e, 0x13, 0xbc, 0xdc, 0x23, 0x8b, 0xa0, 0xe3, 0xfc, 0x68, 0xab, 0xe7, - 0x6f, 0xed, 0xf4, 0x78, 0x38, 0xd2, 0xeb, 0xc9, 0x28, 0xad, 0x4b, 0xe6, - 0xb5, 0x3e, 0xdd, 0x7d, 0xe8, 0xdb, 0x0f, 0xb0, 0xa6, 0x10, 0xce, 0x61, - 0xb8, 0x57, 0xe3, 0x91, 0x8f, 0xef, 0x7d, 0x87, 0xde, 0x7b, 0x0f, 0xbd, - 0x9f, 0xfc, 0x1f, 0xed, 0x59, 0x3e, 0x4c, 0x0f, 0x5c, 0xa7, 0x19, 0xe7, - 0x2c, 0xf9, 0xc2, 0x84, 0x9a, 0x2b, 0x98, 0x09, 0xea, 0x02, 0x29, 0x71, - 0x54, 0xca, 0x6e, 0x03, 0xc6, 0xb5, 0xc9, 0xc2, 0x0a, 0x68, 0x1e, 0xfb, - 0x68, 0xb7, 0x18, 0x2f, 0x7f, 0xb6, 0x97, 0x3c, 0xd3, 0x81, 0x6b, 0xf0, - 0x59, 0x43, 0x21, 0xb4, 0x73, 0x5e, 0xb3, 0x63, 0xc6, 0x45, 0xed, 0xbf, - 0xa1, 0x0e, 0xe3, 0xa8, 0xbc, 0xce, 0xfd, 0x60, 0x9b, 0x16, 0x79, 0x60, - 0x25, 0x7b, 0xbc, 0x5c, 0x22, 0xd8, 0xbb, 0x2f, 0xf6, 0x52, 0xbf, 0x78, - 0xd5, 0xde, 0xab, 0x33, 0x76, 0x85, 0x79, 0x5a, 0x20, 0x9a, 0x97, 0x45, - 0xca, 0x55, 0x91, 0x9b, 0xf8, 0xfd, 0xb1, 0xea, 0xc5, 0x2f, 0x14, 0x6d, - 0xed, 0x49, 0xd9, 0x2e, 0x3d, 0x2b, 0x35, 0xc8, 0x9c, 0x2d, 0xdb, 0x71, - 0x1e, 0xda, 0x61, 0x7d, 0xe6, 0xaf, 0x17, 0x94, 0x44, 0xc6, 0x28, 0xd3, - 0xda, 0xe4, 0x67, 0x2b, 0xcc, 0xbb, 0x33, 0x8d, 0x87, 0xc2, 0xfc, 0xb7, - 0x90, 0x64, 0x82, 0x7e, 0xad, 0x97, 0xca, 0xb7, 0x45, 0x3e, 0xc1, 0xb7, - 0x4f, 0x56, 0x5e, 0xe9, 0xa5, 0xcf, 0xe5, 0xe3, 0x15, 0xbe, 0xfb, 0xf0, - 0xf4, 0x49, 0xc3, 0xf2, 0x43, 0x7f, 0x05, 0xf0, 0x18, 0x3c, 0x77, 0xee, - 0xf7, 0x47, 0x5c, 0x1b, 0xea, 0x68, 0xc3, 0xb6, 0x49, 0x7e, 0x18, 0x38, - 0xa8, 0x86, 0x74, 0xbe, 0x52, 0x23, 0xa8, 0x71, 0xd9, 0x5f, 0x61, 0x5e, - 0x9d, 0x71, 0x54, 0x63, 0x74, 0xf2, 0xf6, 0x82, 0xde, 0x0b, 0xca, 0xb9, - 0x8a, 0x4d, 0x5a, 0x35, 0x64, 0x0b, 0xbc, 0xb6, 0x59, 0xdf, 0xea, 0xe3, - 0x5d, 0x6d, 0xd7, 0x17, 0x7b, 0x5d, 0x1b, 0x8d, 0x75, 0xaf, 0xf7, 0xba, - 0x75, 0x61, 0xcf, 0xe6, 0xa2, 0x6d, 0x56, 0xc6, 0xde, 0x7e, 0x2c, 0xf5, - 0xd5, 0x9f, 0xca, 0x9d, 0xd2, 0x4f, 0xe4, 0xb7, 0xab, 0xe7, 0xa1, 0x73, - 0x98, 0xe5, 0x1c, 0xe4, 0xc9, 0xbb, 0x75, 0xc7, 0x79, 0xd7, 0x3e, 0x07, - 0xfb, 0xc0, 0x71, 0xfe, 0x64, 0xef, 0x48, 0x64, 0xfc, 0x7b, 0xd8, 0x73, - 0x16, 0x3c, 0x44, 0x2c, 0xcc, 0x80, 0xde, 0x52, 0x7d, 0xd2, 0x19, 0xd0, - 0x74, 0x32, 0x34, 0xde, 0x8a, 0x3d, 0xf8, 0x3c, 0x3d, 0x9c, 0x7b, 0x49, - 0xf7, 0x91, 0x66, 0x7c, 0xf5, 0x0a, 0xe6, 0x6f, 0x05, 0x5f, 0x1c, 0xc5, - 0x4f, 0xc9, 0xc3, 0x31, 0xac, 0x75, 0x8c, 0xb4, 0xd7, 0x2a, 0x91, 0x67, - 0xb0, 0x8f, 0x6c, 0x8b, 0x3c, 0x2a, 0xdc, 0xea, 0xa5, 0x3f, 0xef, 0x51, - 0x81, 0x65, 0xdf, 0x57, 0xbb, 0xc4, 0x91, 0x16, 0xc8, 0xef, 0x85, 0x09, - 0x57, 0x57, 0xfa, 0x83, 0x3a, 0x85, 0xf6, 0x56, 0xee, 0x7d, 0x45, 0xdd, - 0x2e, 0xe7, 0xb4, 0x42, 0x17, 0x9f, 0x82, 0x0e, 0x94, 0xac, 0x5f, 0x91, - 0xc6, 0x58, 0x00, 0x6d, 0xa8, 0xa3, 0x68, 0x2c, 0x91, 0x54, 0x81, 0xf9, - 0x5d, 0xcc, 0xb5, 0xc2, 0x1a, 0xcf, 0x11, 0x37, 0xb8, 0xc6, 0x36, 0xc6, - 0xe0, 0xbc, 0x3a, 0x0b, 0x34, 0xc2, 0x3a, 0xd2, 0x77, 0x02, 0x3c, 0x99, - 0xa0, 0xdc, 0xc4, 0x78, 0xa3, 0x18, 0x8f, 0xe5, 0x2e, 0x8c, 0x77, 0x45, - 0x92, 0x76, 0x73, 0xcc, 0x38, 0xda, 0x10, 0x67, 0xe2, 0xd0, 0x1f, 0x06, - 0x55, 0x7a, 0x25, 0x08, 0xf9, 0xdd, 0x2b, 0x69, 0xe3, 0xc8, 0x81, 0x3d, - 0xe6, 0xb4, 0x7d, 0xe0, 0xf3, 0x8d, 0x7a, 0x6b, 0xea, 0x3a, 0xb0, 0x26, - 0xf6, 0xc7, 0x0f, 0xb6, 0x71, 0x72, 0x65, 0x09, 0x38, 0xb5, 0xf4, 0x41, - 0xd2, 0xbe, 0x20, 0xa9, 0x20, 0xd7, 0xc4, 0xfa, 0x20, 0xd6, 0x4c, 0x3f, - 0xd6, 0x77, 0x81, 0x43, 0x47, 0xbc, 0x3a, 0xb6, 0x15, 0x5f, 0x12, 0x67, - 0xef, 0xda, 0xb5, 0xac, 0xfb, 0x8a, 0x24, 0x97, 0xb2, 0x32, 0xad, 0xfb, - 0xf1, 0x0c, 0x07, 0xb4, 0xee, 0x41, 0x5e, 0x8d, 0x9c, 0xc0, 0x59, 0xc6, - 0xf6, 0x6d, 0xe0, 0xf0, 0x09, 0x72, 0x91, 0xd1, 0xe7, 0xf2, 0x2c, 0xbe, - 0x9d, 0xe0, 0x1d, 0xb5, 0x49, 0xe4, 0x5b, 0x90, 0x91, 0x85, 0x66, 0x7d, - 0x40, 0x3e, 0x2d, 0xf4, 0xf4, 0x31, 0xce, 0xf2, 0xd7, 0x82, 0x21, 0x1f, - 0x17, 0x74, 0x2c, 0x74, 0xc6, 0x2f, 0xe6, 0x65, 0xd7, 0x3e, 0x1f, 0x9e, - 0x59, 0x50, 0xfc, 0x3e, 0x7c, 0x79, 0x5d, 0x75, 0xa0, 0x6d, 0x00, 0xed, - 0xb8, 0x0e, 0x43, 0xa6, 0x0a, 0x9f, 0x3b, 0xb3, 0x23, 0x8e, 0x33, 0xad, - 0xf3, 0xc3, 0x62, 0xc6, 0x82, 0x6a, 0xea, 0xe4, 0x51, 0x29, 0x04, 0xdb, - 0x31, 0x57, 0xcc, 0x58, 0x57, 0xc3, 0x58, 0x0f, 0xcb, 0x27, 0xc8, 0x13, - 0xa1, 0x1d, 0xe1, 0xf8, 0x66, 0x66, 0x4d, 0xc5, 0xc2, 0x43, 0xca, 0x4c, - 0xe4, 0xf1, 0x6b, 0x51, 0x3a, 0x8e, 0x18, 0x0a, 0x2b, 0xf0, 0x2e, 0xf6, - 0x64, 0x9d, 0x76, 0x9c, 0x8c, 0xc5, 0xfa, 0x98, 0x11, 0x50, 0xf4, 0xb7, - 0x74, 0xea, 0x78, 0xe3, 0xb5, 0x93, 0x31, 0xe3, 0xb4, 0x3a, 0xee, 0xbd, - 0xc7, 0x81, 0x99, 0x7b, 0xe3, 0x9d, 0x5f, 0x53, 0x86, 0xbc, 0x51, 0x88, - 0x85, 0xe7, 0x94, 0x99, 0xc5, 0x98, 0xd9, 0xb4, 0x22, 0x6e, 0xc4, 0x8c, - 0x4e, 0x45, 0x9f, 0x68, 0xbb, 0xde, 0x77, 0x06, 0xfd, 0x63, 0xaa, 0xc5, - 0x5b, 0x0f, 0xef, 0xeb, 0xed, 0x3e, 0x97, 0x67, 0x88, 0x39, 0x23, 0xc0, - 0x4c, 0xe6, 0x9a, 0xe9, 0xdc, 0x86, 0x44, 0x64, 0x7c, 0x44, 0x63, 0xe8, - 0xe3, 0x33, 0x7f, 0x47, 0x1d, 0xca, 0x65, 0xd6, 0x45, 0x3d, 0x7e, 0x1b, - 0xd1, 0x3a, 0xf3, 0xe3, 0x33, 0x39, 0x9d, 0xf7, 0xd8, 0x50, 0x11, 0x6f, - 0xdf, 0x7b, 0x77, 0x16, 0x4e, 0xda, 0x4f, 0x71, 0x9c, 0x25, 0xff, 0x64, - 0xbb, 0x30, 0xa7, 0x74, 0xaa, 0xd4, 0xa4, 0x0d, 0xfa, 0x03, 0x98, 0x2f, - 0xd0, 0x8c, 0x7b, 0x5f, 0x11, 0xdf, 0x78, 0xc7, 0x01, 0x3a, 0x81, 0xae, - 0x09, 0x1d, 0xb5, 0x8a, 0x71, 0xf2, 0x2b, 0x92, 0x73, 0xfb, 0x4b, 0x07, - 0x73, 0x58, 0xf3, 0xd5, 0x2f, 0x1b, 0x83, 0x73, 0x63, 0x0e, 0xbc, 0x3f, - 0x3e, 0x43, 0xfa, 0xe4, 0xd9, 0x84, 0xd5, 0xd4, 0x2a, 0xd7, 0x33, 0x20, - 0xd3, 0x2b, 0x83, 0x32, 0x87, 0xdf, 0xc2, 0x8a, 0x7b, 0x6f, 0x1b, 0xd0, - 0xad, 0xa7, 0x0b, 0x86, 0xe6, 0xd7, 0x39, 0x9b, 0x31, 0x13, 0xf0, 0x8a, - 0xce, 0xa9, 0x62, 0x5f, 0xc6, 0x89, 0x06, 0x29, 0x1f, 0xed, 0x06, 0xe4, - 0xea, 0x46, 0x9d, 0x7a, 0x2a, 0xeb, 0xcd, 0x78, 0xd8, 0xdf, 0x2d, 0x0b, - 0xc0, 0xbb, 0x0a, 0x64, 0x67, 0xfe, 0xcd, 0x80, 0xcc, 0x15, 0x74, 0x3c, - 0x39, 0xfc, 0x17, 0x65, 0x4b, 0xad, 0x3e, 0x21, 0xb7, 0xeb, 0x51, 0xfd, - 0x8d, 0x72, 0x2d, 0xff, 0x0b, 0x9f, 0xbc, 0x32, 0xa2, 0xf3, 0xea, 0xa2, - 0x15, 0x79, 0xaa, 0x9f, 0x3a, 0xcf, 0xba, 0xce, 0xb1, 0x03, 0x76, 0x40, - 0xe7, 0x78, 0x0f, 0x3a, 0xc7, 0x6f, 0xa0, 0x73, 0xfc, 0xba, 0x04, 0x7c, - 0x29, 0x65, 0x3c, 0xfc, 0x9f, 0x01, 0x0e, 0x51, 0x56, 0x9b, 0xe7, 0x71, - 0xa7, 0x33, 0x39, 0xd0, 0xe0, 0x47, 0x92, 0x01, 0xde, 0x26, 0x65, 0x73, - 0x75, 0x5a, 0xb6, 0x56, 0xdd, 0x3c, 0xe5, 0xfb, 0xcc, 0x01, 0x1b, 0xe3, - 0x3d, 0x45, 0x81, 0x43, 0x47, 0x24, 0x72, 0x9a, 0xf8, 0xd1, 0x21, 0x6b, - 0xc5, 0xdf, 0x69, 0x1c, 0x5a, 0x2b, 0xb2, 0xec, 0x17, 0x9d, 0x4f, 0x76, - 0x6e, 0x47, 0x2a, 0x76, 0x03, 0xf5, 0xc7, 0xb4, 0x0f, 0xc8, 0xf5, 0xc9, - 0x13, 0x2f, 0x3f, 0xf7, 0xee, 0x5e, 0xe9, 0x3c, 0xbb, 0x59, 0xa3, 0x1b, - 0xed, 0x9a, 0xd8, 0x35, 0xe4, 0xc6, 0xbc, 0xd5, 0xdf, 0xd0, 0x06, 0x73, - 0x94, 0xba, 0x65, 0x03, 0x32, 0xa4, 0x11, 0xed, 0xd6, 0xba, 0x5f, 0x23, - 0x3a, 0xa8, 0x73, 0x77, 0x39, 0x4e, 0xbe, 0x68, 0xc9, 0x7c, 0xd1, 0x0c, - 0xe7, 0x40, 0x7f, 0xb7, 0x61, 0xab, 0x6d, 0xe2, 0x0e, 0xb6, 0x70, 0x06, - 0xdb, 0x75, 0xca, 0xf9, 0x2f, 0x34, 0xf6, 0xae, 0xd5, 0x3f, 0xc3, 0x38, - 0xe6, 0xf9, 0x84, 0x3c, 0xee, 0x23, 0x06, 0xd2, 0x1f, 0x95, 0xd2, 0xfd, - 0xdd, 0x7e, 0x9b, 0x68, 0xbb, 0x55, 0x27, 0x1e, 0x8b, 0x5c, 0x2d, 0x58, - 0x90, 0x25, 0xbf, 0x0a, 0x51, 0x07, 0x28, 0xab, 0x66, 0x3f, 0xc7, 0x5b, - 0xb3, 0xe3, 0x1c, 0xb5, 0xb8, 0xae, 0xa8, 0x87, 0xdb, 0x94, 0xfd, 0x3b, - 0x5a, 0xee, 0x17, 0x4a, 0x17, 0xe4, 0x1d, 0xdc, 0xb7, 0xab, 0xe3, 0x64, - 0xe5, 0x16, 0x74, 0xbc, 0x7a, 0xa9, 0x99, 0xd7, 0x3d, 0x89, 0x73, 0x32, - 0xd5, 0xfc, 0xf2, 0x75, 0xb9, 0x76, 0x63, 0x57, 0xbd, 0x71, 0x23, 0xa2, - 0xae, 0x2f, 0x0f, 0xa9, 0xfc, 0xb2, 0xe3, 0xfc, 0xd3, 0x9e, 0x95, 0x3b, - 0xab, 0x8e, 0x9c, 0xb5, 0x7d, 0xfd, 0x7e, 0x69, 0xe6, 0xd6, 0x39, 0x4e, - 0x07, 0xb0, 0x79, 0xfb, 0xa4, 0xe3, 0x3c, 0x3d, 0x36, 0x26, 0xd1, 0x93, - 0xd4, 0x51, 0x9e, 0x0b, 0x31, 0x3f, 0x96, 0x98, 0x93, 0xb4, 0xac, 0xcb, - 0x15, 0xa5, 0x80, 0x6f, 0xdd, 0xae, 0xfe, 0xf2, 0xcc, 0x31, 0x2f, 0x56, - 0x72, 0xe7, 0x35, 0xfa, 0x92, 0x43, 0xff, 0xe5, 0x4b, 0x36, 0xe4, 0x62, - 0x71, 0x04, 0xfd, 0x83, 0xf2, 0xc3, 0x62, 0xe0, 0x50, 0xd9, 0xc0, 0x73, - 0x54, 0xe5, 0x8b, 0x8f, 0x9c, 0x21, 0x1d, 0x33, 0x80, 0x4e, 0x62, 0x38, - 0xce, 0x9c, 0xcd, 0xf9, 0xba, 0x31, 0xdf, 0x8e, 0x71, 0x0c, 0xf2, 0xff, - 0xac, 0x96, 0xcf, 0x17, 0x15, 0x6c, 0x5f, 0xf0, 0x77, 0x50, 0xd2, 0x45, - 0xc8, 0x78, 0xc5, 0x9c, 0x53, 0xea, 0x0a, 0x66, 0x68, 0x0e, 0xd8, 0x31, - 0x0b, 0xbc, 0x79, 0x49, 0xc7, 0x56, 0x4f, 0x68, 0xec, 0x99, 0x67, 0x39, - 0x2b, 0x89, 0x8a, 0xdd, 0xa3, 0xcf, 0x6f, 0xf7, 0xf6, 0x2f, 0x43, 0xee, - 0x9d, 0x83, 0x8f, 0xb3, 0x4a, 0xda, 0x60, 0x03, 0xa5, 0xd6, 0xcf, 0x81, - 0x27, 0x42, 0x38, 0xdb, 0x56, 0xcd, 0x0f, 0x0d, 0xc8, 0xef, 0x86, 0xf6, - 0x23, 0xba, 0xf1, 0x8a, 0x86, 0xc1, 0x76, 0x17, 0xd0, 0xaf, 0x5d, 0x92, - 0xcb, 0x6d, 0x1a, 0x57, 0x9f, 0xac, 0x4b, 0x40, 0x0f, 0xf9, 0x3e, 0xca, - 0x7e, 0xd4, 0x85, 0xbd, 0xb2, 0x0f, 0xe5, 0x19, 0x94, 0x5b, 0xf0, 0x64, - 0x9b, 0x61, 0xe8, 0x15, 0x78, 0xbe, 0x8d, 0xf1, 0xc6, 0xb0, 0xe6, 0xac, - 0x21, 0x1f, 0x9e, 0xa1, 0x2c, 0x19, 0x55, 0xcc, 0x63, 0x9e, 0xb3, 0xf0, - 0xac, 0x0d, 0xa9, 0xd4, 0x12, 0xcb, 0x78, 0x96, 0xdd, 0xef, 0x4f, 0x60, - 0x12, 0xfa, 0x24, 0x6f, 0xb8, 0x98, 0xf4, 0xe1, 0x1e, 0x26, 0xb1, 0xae, - 0x5d, 0xd2, 0xcb, 0xe4, 0x75, 0x03, 0xf4, 0xd6, 0x29, 0xa9, 0x1b, 0x41, - 0xad, 0x8f, 0x56, 0x40, 0x8b, 0x1b, 0xa0, 0xab, 0x35, 0xd0, 0x54, 0xb2, - 0x68, 0xc6, 0x67, 0x54, 0x58, 0xfb, 0x02, 0x5e, 0x00, 0xbd, 0x76, 0xbc, - 0x49, 0x5d, 0x94, 0xbc, 0x1c, 0x05, 0xed, 0x89, 0xd3, 0x61, 0x59, 0x99, - 0xa8, 0xb2, 0x40, 0x83, 0xa0, 0xcb, 0xa2, 0xcb, 0xd3, 0xef, 0x2b, 0x8d, - 0xab, 0xf1, 0x07, 0x12, 0x4b, 0x3c, 0x10, 0x13, 0x58, 0x60, 0xda, 0x1f, - 0x88, 0x8d, 0x31, 0x27, 0xe4, 0x26, 0xe6, 0xf1, 0x81, 0xbf, 0x47, 0x4e, - 0x69, 0xfe, 0x8e, 0x8b, 0xff, 0x30, 0x8f, 0x83, 0xde, 0x80, 0x41, 0x2e, - 0x4f, 0x27, 0x3c, 0x1a, 0xfd, 0x26, 0xf8, 0xd7, 0x84, 0x25, 0x16, 0x94, - 0x05, 0xf0, 0xff, 0x06, 0xbe, 0xdf, 0xad, 0x0f, 0xab, 0xf9, 0x25, 0xe5, - 0xe5, 0x92, 0x7c, 0x07, 0x7a, 0xf2, 0x43, 0x9c, 0x5d, 0x97, 0xd6, 0xdd, - 0x23, 0x63, 0x8c, 0x9f, 0x65, 0xd4, 0x35, 0xeb, 0xb4, 0xec, 0x8e, 0x4e, - 0xa0, 0x7c, 0x0c, 0x4f, 0x1f, 0xce, 0x21, 0xa0, 0xe3, 0xdf, 0x6b, 0x05, - 0x5b, 0xb9, 0xff, 0xd3, 0x30, 0x8e, 0xbe, 0xc4, 0xb2, 0x93, 0xf8, 0x4e, - 0x5f, 0x0c, 0xf7, 0x06, 0x9d, 0x49, 0x85, 0x74, 0xbe, 0x69, 0x05, 0xba, - 0xc4, 0x3a, 0xc6, 0xbb, 0x47, 0x5f, 0x5e, 0x0d, 0x3c, 0x3c, 0xfa, 0x2f, - 0x27, 0x11, 0x64, 0x4e, 0xfb, 0x17, 0x21, 0x57, 0xfe, 0x7d, 0xea, 0xec, - 0x5a, 0xf3, 0x71, 0x1f, 0x5e, 0x3e, 0x32, 0x82, 0x68, 0x0b, 0x59, 0x06, - 0x59, 0x54, 0xd6, 0xf4, 0xcb, 0x76, 0x6e, 0xdf, 0x7c, 0x2d, 0x66, 0xdc, - 0x17, 0xb7, 0xef, 0x82, 0x45, 0xb9, 0xd3, 0x0e, 0x7c, 0x09, 0x6b, 0xbd, - 0xf2, 0x9e, 0x95, 0x03, 0x2a, 0x98, 0xe1, 0x0c, 0x68, 0xb4, 0x4d, 0xcc, - 0xe8, 0x94, 0xec, 0xcf, 0x3b, 0xa7, 0xfb, 0xb2, 0x6d, 0xb3, 0x6f, 0x73, - 0x5e, 0xae, 0x9f, 0x7b, 0xe1, 0x1e, 0xe8, 0x9b, 0x36, 0x34, 0x8d, 0x36, - 0x6a, 0x03, 0xfd, 0x2e, 0x8d, 0x36, 0xf7, 0x11, 0xfc, 0x3f, 0xfb, 0x20, - 0x9d, 0xd8, 0xca, 0x8d, 0xd3, 0xe3, 0x59, 0xe3, 0x79, 0x0e, 0x83, 0x36, - 0x0e, 0xd2, 0x4f, 0xd3, 0xb7, 0xe8, 0xd2, 0xcf, 0xd3, 0x7b, 0xf4, 0x43, - 0xba, 0xe9, 0x94, 0xf4, 0x0d, 0x4b, 0xa6, 0x8b, 0xfa, 0xbe, 0xa1, 0x6b, - 0xd2, 0x67, 0x34, 0x01, 0xba, 0x21, 0xad, 0x93, 0xb7, 0x0c, 0x29, 0x83, - 0x8e, 0xca, 0xc0, 0xa7, 0x32, 0x68, 0xaa, 0x02, 0x7c, 0x2b, 0x03, 0xdf, - 0xca, 0x75, 0x33, 0x5a, 0xc5, 0x9e, 0x29, 0xb3, 0xd7, 0x41, 0x47, 0x1b, - 0x75, 0xde, 0xbf, 0x5e, 0xb3, 0x41, 0x39, 0x78, 0x77, 0xef, 0xee, 0xff, - 0x81, 0xbb, 0x1f, 0x94, 0xdb, 0xb0, 0x5b, 0xde, 0x29, 0x8d, 0x02, 0x93, - 0x04, 0x18, 0x65, 0x83, 0x36, 0xe2, 0xb2, 0x59, 0x9a, 0x94, 0x2d, 0xc8, - 0xa7, 0xed, 0xd5, 0x08, 0xf4, 0xe9, 0x90, 0xcc, 0xbf, 0x35, 0x22, 0xb7, - 0x56, 0x95, 0xcc, 0x82, 0x7e, 0xf3, 0x6b, 0xf4, 0xbb, 0x83, 0x9e, 0xcb, - 0x9d, 0x3a, 0x4e, 0x9f, 0xae, 0xba, 0xfe, 0xf7, 0xa9, 0x6a, 0x97, 0x4c, - 0x57, 0x0d, 0x79, 0xbe, 0xda, 0x23, 0x2f, 0x56, 0x83, 0x72, 0x16, 0x76, - 0xe0, 0xd7, 0xaa, 0x03, 0xf2, 0x52, 0x75, 0x50, 0xbe, 0x5e, 0x0b, 0xcb, - 0x37, 0x6a, 0x96, 0x64, 0x6b, 0x51, 0xc9, 0xd4, 0x46, 0xe5, 0x85, 0x1a, - 0xfd, 0xea, 0x98, 0x0f, 0xbf, 0xd4, 0x9e, 0xbf, 0x82, 0xeb, 0xea, 0xc0, - 0xba, 0xa2, 0x6a, 0x4a, 0xc7, 0x29, 0x25, 0xeb, 0xfa, 0x3c, 0x44, 0x2e, - 0x61, 0xac, 0xc5, 0xb7, 0x94, 0x54, 0xf4, 0xfc, 0xcd, 0xff, 0x33, 0x09, - 0x68, 0xdb, 0xe8, 0x52, 0x79, 0x00, 0x6d, 0x20, 0xf7, 0x0a, 0x4d, 0xdf, - 0x47, 0xd3, 0xe7, 0xdf, 0xb4, 0xbd, 0x7c, 0xda, 0x6f, 0x7d, 0x97, 0xb6, - 0x97, 0x3e, 0x7b, 0xe2, 0x07, 0xed, 0x9c, 0x9b, 0xda, 0x6f, 0xb2, 0x1f, - 0xdb, 0x68, 0xce, 0xbb, 0x98, 0x7d, 0xf2, 0xff, 0x59, 0xdc, 0x18, 0xd5, - 0xc5, 0xda, 0x00, 0xff, 0xaf, 0x05, 0x6b, 0xf9, 0xf2, 0xdc, 0xf1, 0xe9, - 0x52, 0x5a, 0x3d, 0x5f, 0xa2, 0x46, 0xe3, 0xc8, 0xe2, 0x5e, 0x4e, 0xdc, - 0x73, 0xb2, 0x66, 0x07, 0xf4, 0x1a, 0x5c, 0x5f, 0x7d, 0x42, 0xe7, 0xc7, - 0xa5, 0x4f, 0x91, 0xfe, 0x18, 0x7b, 0xeb, 0xf2, 0xe2, 0x09, 0xd0, 0x6d, - 0x6d, 0x43, 0xae, 0x56, 0x5d, 0x9f, 0xd5, 0xbc, 0xa6, 0x97, 0x7b, 0xa0, - 0x39, 0xc6, 0x1c, 0xdc, 0x67, 0xae, 0xec, 0xf6, 0x4d, 0xe1, 0xde, 0x60, - 0x8f, 0x63, 0xbf, 0xbe, 0x1e, 0xce, 0xc5, 0xff, 0xe3, 0x41, 0xd9, 0x5b, - 0x2f, 0x73, 0x8d, 0x2d, 0x4d, 0x8b, 0x6e, 0x5c, 0x37, 0x2a, 0xaf, 0xe2, - 0xfc, 0x2a, 0x06, 0xd7, 0xdf, 0x21, 0x95, 0x28, 0x6d, 0x5b, 0xe2, 0xf7, - 0x29, 0x29, 0x63, 0x9e, 0x4a, 0xb4, 0xe9, 0x0f, 0x73, 0x71, 0xb6, 0x62, - 0xec, 0xcf, 0x3b, 0x53, 0x3e, 0x8e, 0x77, 0xd4, 0x45, 0xa1, 0x33, 0x9d, - 0xe3, 0xfb, 0x22, 0xca, 0xf4, 0x8d, 0xcc, 0xe3, 0x19, 0xf2, 0xea, 0xde, - 0xeb, 0xd7, 0xba, 0xfa, 0xe4, 0x7e, 0xbf, 0xd9, 0xb2, 0x99, 0x4b, 0xfa, - 0x63, 0xca, 0xf7, 0xf3, 0xdf, 0xf7, 0x13, 0x73, 0x8f, 0x5b, 0xfc, 0x05, - 0xe4, 0x33, 0x43, 0xfb, 0x14, 0xbc, 0x6f, 0x47, 0xe4, 0x65, 0x83, 0x79, - 0xec, 0x09, 0x95, 0x2e, 0x5d, 0xf7, 0x72, 0x7c, 0x63, 0xea, 0x78, 0xe5, - 0x7e, 0xbf, 0x9b, 0xf3, 0xce, 0xb1, 0x0f, 0xe6, 0xb9, 0x1f, 0xa4, 0x13, - 0xe6, 0xbb, 0xb7, 0xef, 0xfd, 0x0f, 0x55, 0xa5, 0x00, 0xbc, 0xb3, 0x5a, - 0x34, 0x3f, 0xe6, 0x6b, 0xff, 0x76, 0x76, 0x34, 0x3f, 0x37, 0x7d, 0x0c, - 0x7f, 0xee, 0xa7, 0x6d, 0x4b, 0xdc, 0xb8, 0xea, 0xe6, 0x8e, 0x6a, 0x1b, - 0x1a, 0x58, 0x81, 0x3a, 0xf2, 0x2a, 0xf8, 0x64, 0xaf, 0x2d, 0xff, 0xfe, - 0x03, 0x9a, 0xb8, 0x8a, 0x6c, 0x8c, 0x67, 0x00, 0x00, 0x00 }; +/* 0x1f, 0x8b, 0x08, 0x00, 0x0e, 0x34, 0xe7, 0x45, 0x00, 0x03, */ + 0xec, 0x5c, + 0x5d, 0x6c, 0x1c, 0xd7, 0x75, 0x3e, 0xf3, 0x43, 0x6a, 0x49, 0xf1, 0x67, + 0xb8, 0x5c, 0xb1, 0x2b, 0x99, 0x96, 0x77, 0xc9, 0x91, 0xc8, 0x58, 0x8a, + 0x31, 0xa2, 0x09, 0x5b, 0x48, 0x17, 0xf6, 0x76, 0x76, 0x25, 0xb1, 0xb1, + 0x03, 0x53, 0xb6, 0x62, 0x07, 0x45, 0x6a, 0xb0, 0x4b, 0xb9, 0x0e, 0x8c, + 0x06, 0x90, 0xff, 0x52, 0xbf, 0xb0, 0xde, 0x2c, 0xa9, 0x58, 0x4d, 0x17, + 0x9c, 0xb5, 0x4d, 0x9b, 0x0e, 0x60, 0xb7, 0x0b, 0x92, 0x12, 0xf5, 0xb0, + 0xd0, 0xb2, 0xa9, 0xdb, 0xea, 0xc1, 0x8e, 0x09, 0x56, 0xb1, 0x53, 0xa0, + 0x2d, 0x5c, 0x27, 0x69, 0xfc, 0x10, 0x14, 0xaa, 0xec, 0xc4, 0x42, 0xd1, + 0xa2, 0x02, 0x12, 0xd8, 0x29, 0x22, 0x7b, 0xfa, 0x7d, 0x77, 0x66, 0xc8, + 0x25, 0x2d, 0xdb, 0x41, 0x1f, 0xfa, 0xd2, 0xbd, 0xc0, 0x62, 0xee, 0xbd, + 0x73, 0xee, 0xb9, 0xe7, 0x9e, 0xff, 0x73, 0x87, 0xd2, 0x1f, 0x74, 0x48, + 0xbb, 0x84, 0xad, 0x13, 0xbf, 0xd4, 0x89, 0x27, 0x1e, 0xb9, 0x69, 0xf4, + 0xa6, 0x9b, 0xd1, 0xbd, 0xd9, 0x30, 0x4c, 0x23, 0x9a, 0x6f, 0xb6, 0x66, + 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, + 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, + 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, + 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, + 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, + 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0x6b, 0xb6, 0x66, 0xfb, 0xff, 0xde, + 0x0c, 0x11, 0x8b, 0xcf, 0xce, 0xf0, 0x27, 0x31, 0x3d, 0x23, 0x0f, 0xb9, + 0xb6, 0xc4, 0x8c, 0xcc, 0xd5, 0xa9, 0x49, 0x5b, 0x24, 0x5b, 0xdb, 0x97, + 0xca, 0xc9, 0x87, 0x7e, 0x31, 0x61, 0x0a, 0xe7, 0xaf, 0xcf, 0x5c, 0xfd, + 0x8b, 0x57, 0x6f, 0x4d, 0x5f, 0xa9, 0x1a, 0x12, 0xb3, 0x32, 0x33, 0x07, + 0xac, 0xbd, 0x12, 0xeb, 0xc7, 0x9a, 0x17, 0x87, 0xfe, 0xa9, 0x4b, 0xba, + 0x22, 0x5c, 0x22, 0x0b, 0xe5, 0xb4, 0x73, 0x18, 0xcf, 0x33, 0xb5, 0x7d, + 0xce, 0x9a, 0x98, 0xb2, 0x6a, 0x05, 0x3b, 0x96, 0xca, 0x1a, 0xf1, 0x48, + 0xa9, 0x16, 0x93, 0x8b, 0xea, 0xdf, 0x79, 0x60, 0x4f, 0x9b, 0xfd, 0xf3, + 0x9a, 0x5b, 0xf7, 0xfd, 0xd3, 0x8e, 0xef, 0xbf, 0x8e, 0xdf, 0x7b, 0x0e, + 0xc6, 0xde, 0x47, 0x7e, 0xd6, 0x34, 0x44, 0xb7, 0xff, 0x4c, 0x73, 0x17, + 0x5b, 0xa5, 0x34, 0x2f, 0x32, 0xed, 0xc5, 0xe4, 0x94, 0x57, 0xd4, 0xf2, + 0xf5, 0xb2, 0x76, 0x68, 0x79, 0x56, 0x3b, 0xbc, 0x7c, 0x4a, 0x3b, 0xb2, + 0x5c, 0xd1, 0xdc, 0x65, 0x29, 0xea, 0x07, 0x3a, 0x24, 0x6b, 0x9d, 0xd5, + 0x72, 0xf5, 0x3e, 0xcd, 0x9d, 0xbf, 0xea, 0xbb, 0x4e, 0xda, 0xfa, 0x3d, + 0x31, 0xb3, 0xdc, 0xcf, 0x2d, 0xfb, 0x18, 0x9b, 0x92, 0x4d, 0xf8, 0xbe, + 0x9e, 0xf1, 0x9f, 0x74, 0x47, 0x6d, 0x4b, 0xd7, 0x62, 0x52, 0xaa, 0xb7, + 0x03, 0x6f, 0x87, 0x96, 0x9b, 0x37, 0xb5, 0xbc, 0xe7, 0xbf, 0xe6, 0x3a, + 0xd2, 0x6f, 0x88, 0xef, 0xcf, 0x38, 0x7b, 0x92, 0xc7, 0xe5, 0x0c, 0xf0, + 0xd6, 0x80, 0x4f, 0x2c, 0x3d, 0x43, 0xfa, 0x22, 0x9a, 0x8b, 0x5a, 0x6e, + 0x28, 0xa2, 0x4f, 0x52, 0xa4, 0xbf, 0xb0, 0xa4, 0x83, 0xce, 0xed, 0x52, + 0xa8, 0x5a, 0x32, 0xb1, 0xb4, 0x15, 0xfe, 0xa2, 0xff, 0xea, 0x50, 0x42, + 0xfe, 0xb2, 0x9e, 0x3e, 0x55, 0x04, 0x2f, 0x66, 0xbc, 0x94, 0x80, 0xcf, + 0x59, 0x77, 0xb4, 0x5f, 0x5e, 0xab, 0x27, 0xe5, 0xbb, 0x75, 0x3b, 0x59, + 0x92, 0x6d, 0x52, 0x48, 0x58, 0xb2, 0x82, 0x35, 0xd3, 0xa0, 0x43, 0xb7, + 0x6d, 0xab, 0x04, 0xd8, 0x52, 0xfd, 0x27, 0xfc, 0xb7, 0x32, 0xd6, 0xe4, + 0xa8, 0x5a, 0x53, 0x04, 0xdd, 0x21, 0x2c, 0xcf, 0xa1, 0x60, 0xd5, 0x59, + 0x02, 0x58, 0x29, 0x4e, 0x8e, 0x62, 0xae, 0xfe, 0x85, 0x50, 0x16, 0xad, + 0x38, 0x2f, 0x9f, 0xbb, 0x71, 0xbe, 0xdd, 0xe0, 0x89, 0x24, 0x74, 0xd9, + 0x93, 0x2c, 0x60, 0x66, 0xba, 0xde, 0x81, 0x31, 0x69, 0xf1, 0xfd, 0x23, + 0x8e, 0x58, 0x25, 0xa7, 0x1b, 0xbc, 0x4b, 0x49, 0xc9, 0xe9, 0xc2, 0x9a, + 0x16, 0xb1, 0x6c, 0x9e, 0x81, 0x78, 0xdb, 0x30, 0xef, 0x77, 0x1a, 0x19, + 0xdf, 0x9f, 0x1c, 0x95, 0xae, 0x60, 0x6e, 0x1f, 0x70, 0x98, 0x32, 0x31, + 0xae, 0x01, 0xee, 0x03, 0xd2, 0x17, 0x8b, 0x67, 0xd8, 0xe7, 0x73, 0x54, + 0xdc, 0xd9, 0x54, 0xb8, 0x6f, 0x87, 0x94, 0xbc, 0xeb, 0xc3, 0x3e, 0x78, + 0xed, 0xe1, 0xcc, 0xce, 0x4e, 0x8c, 0xb5, 0x1b, 0x80, 0xc7, 0x29, 0x09, + 0xf7, 0xd8, 0x21, 0x6b, 0x09, 0xd1, 0x2f, 0x39, 0xbd, 0x21, 0x5c, 0x17, + 0x68, 0x8d, 0x64, 0xde, 0x2e, 0x33, 0xf3, 0xad, 0x72, 0x72, 0x9e, 0xbc, + 0x2d, 0x43, 0x16, 0x78, 0xde, 0x52, 0xd4, 0xb2, 0xf5, 0x53, 0xe8, 0x9b, + 0x32, 0x69, 0xfb, 0xaf, 0xcd, 0x38, 0xb3, 0x5a, 0x6e, 0xf9, 0x8c, 0x96, + 0x87, 0x0e, 0x1c, 0x5a, 0x3e, 0xaf, 0x1d, 0xae, 0xaf, 0x76, 0x4a, 0x7b, + 0x1a, 0xda, 0x66, 0xca, 0x49, 0x4f, 0x13, 0xd2, 0xbb, 0x00, 0x7e, 0x65, + 0x2d, 0x70, 0xde, 0xee, 0xd2, 0x0e, 0x03, 0x57, 0x8b, 0xfd, 0xad, 0x0e, + 0xe9, 0x32, 0x64, 0x9b, 0x1d, 0xc1, 0xc6, 0xe4, 0x5b, 0xa0, 0x6d, 0xcd, + 0x49, 0x00, 0x4e, 0xba, 0x83, 0x35, 0x3d, 0x21, 0x3d, 0xd4, 0x25, 0xea, + 0x91, 0x9e, 0xcd, 0xcf, 0xfd, 0x69, 0x6f, 0x69, 0xff, 0x76, 0xc2, 0xc0, + 0x3e, 0x52, 0x0f, 0x4d, 0xda, 0x6e, 0x8f, 0x29, 0x45, 0x4b, 0x97, 0xb4, + 0x95, 0x93, 0x1b, 0x64, 0xc6, 0x11, 0xc9, 0x41, 0xbf, 0x75, 0xdb, 0x04, + 0x8f, 0x6c, 0xf0, 0x68, 0xcf, 0xa9, 0x41, 0xfd, 0x0e, 0x49, 0xf5, 0x15, + 0x35, 0x33, 0xe4, 0xe7, 0x82, 0xdc, 0xa6, 0xd6, 0xeb, 0x19, 0x07, 0x3a, + 0xd9, 0xce, 0x3e, 0xf6, 0x8d, 0xa9, 0x7d, 0x8d, 0x8c, 0x9d, 0x5c, 0x14, + 0xd1, 0xf4, 0xcc, 0x3e, 0xe0, 0xa3, 0xae, 0x12, 0xee, 0x29, 0xd0, 0x48, + 0xda, 0xd9, 0xb7, 0xb1, 0x26, 0x26, 0xae, 0xd3, 0xd9, 0x40, 0x27, 0xe8, + 0x49, 0x90, 0xe7, 0xe4, 0xa1, 0x3a, 0xa7, 0xb6, 0x71, 0xce, 0x5f, 0xfb, + 0xdb, 0x46, 0x4c, 0x79, 0x5d, 0x9d, 0x97, 0x76, 0x45, 0x38, 0x75, 0x46, + 0x21, 0x7f, 0xa6, 0x3d, 0xd1, 0x0a, 0x8e, 0xb5, 0x8e, 0x0b, 0x7a, 0xa1, + 0x1b, 0x99, 0x0e, 0xc9, 0x29, 0xfa, 0x0e, 0x62, 0x2f, 0xda, 0x1b, 0xec, + 0xc6, 0xe6, 0x59, 0x38, 0x97, 0x81, 0xed, 0xa6, 0x95, 0xfe, 0x14, 0x2a, + 0xf4, 0x07, 0xa4, 0x6d, 0x35, 0xad, 0x4b, 0x80, 0xaf, 0xf4, 0x6c, 0x37, + 0x68, 0xe3, 0x18, 0xb6, 0x67, 0xe3, 0xfd, 0x7e, 0xd8, 0xfa, 0xc1, 0x41, + 0xf0, 0x87, 0x70, 0x76, 0x0a, 0xf2, 0xce, 0xba, 0xd8, 0xd3, 0x75, 0x6e, + 0x56, 0x3c, 0xe8, 0xc1, 0x79, 0x06, 0x67, 0xc9, 0xaf, 0x76, 0xe8, 0xb3, + 0x26, 0x05, 0x27, 0x9d, 0xa2, 0xfc, 0x03, 0xda, 0x75, 0xd9, 0x76, 0x4b, + 0x23, 0xed, 0x91, 0xac, 0xa8, 0x8f, 0xa6, 0xc4, 0x47, 0x08, 0x4b, 0x38, + 0xc2, 0xa7, 0x0f, 0x8a, 0xfe, 0x6b, 0xdf, 0xda, 0x74, 0x56, 0x5b, 0x06, + 0x66, 0x41, 0x43, 0xc0, 0x5b, 0xf0, 0xe4, 0xb3, 0x60, 0xc9, 0xd7, 0xad, + 0xfc, 0x23, 0x6c, 0x23, 0x1c, 0x74, 0xa2, 0x8f, 0x34, 0xac, 0x74, 0x04, + 0xf6, 0x15, 0xd1, 0x14, 0xc9, 0x46, 0x0b, 0x71, 0x7c, 0xda, 0x39, 0x08, + 0x0f, 0xbb, 0xf7, 0x60, 0xf7, 0x1e, 0x7c, 0x82, 0x07, 0x9b, 0xf7, 0xe8, + 0x27, 0x52, 0xf2, 0xea, 0x10, 0xfc, 0xda, 0x86, 0x5f, 0x41, 0x1b, 0x43, + 0x5f, 0x17, 0x03, 0x7e, 0x65, 0xba, 0xaa, 0xc3, 0x76, 0x61, 0x43, 0x4b, + 0x9c, 0xb3, 0xf0, 0xcc, 0xe3, 0x69, 0xc3, 0x8f, 0x52, 0xaf, 0x22, 0xff, + 0x49, 0x3f, 0x93, 0x84, 0x4f, 0xa1, 0xaf, 0xa1, 0x2f, 0x21, 0xac, 0xef, + 0xe7, 0x1d, 0xae, 0xf5, 0x65, 0xdc, 0xa1, 0x1d, 0x75, 0x88, 0x1e, 0x2f, + 0x6a, 0x47, 0x87, 0x60, 0x63, 0x37, 0xb6, 0x80, 0x56, 0xda, 0xda, 0x75, + 0x74, 0x15, 0x68, 0xbf, 0xe8, 0x0c, 0xfe, 0x5d, 0xde, 0x36, 0xc0, 0x28, + 0xa1, 0x76, 0x05, 0xe3, 0xb6, 0xd0, 0x9f, 0xf0, 0x7d, 0x3a, 0x95, 0x95, + 0xdd, 0xe1, 0x98, 0xfd, 0x75, 0x7a, 0x1d, 0xfd, 0x96, 0x98, 0x0c, 0x9c, + 0x09, 0xfc, 0xe0, 0xc0, 0x82, 0x25, 0xf6, 0x99, 0x80, 0xc6, 0x81, 0x73, + 0x91, 0x3f, 0x6c, 0x01, 0x3e, 0xd0, 0xe7, 0x6d, 0xc4, 0x09, 0x91, 0xf7, + 0x34, 0x98, 0x0a, 0xe6, 0xb6, 0xf2, 0x82, 0x3e, 0x98, 0xf6, 0x66, 0x35, + 0xda, 0xdb, 0x01, 0xd8, 0x9b, 0xd3, 0x2a, 0x69, 0xe7, 0xef, 0x60, 0x6f, + 0x4f, 0x39, 0x1a, 0x78, 0x23, 0x72, 0xa1, 0xdc, 0x01, 0x5b, 0x37, 0x93, + 0xef, 0xc8, 0x9e, 0xd4, 0xb4, 0x68, 0x72, 0x9a, 0x73, 0x35, 0xcc, 0x29, + 0xff, 0x1b, 0xd8, 0xf7, 0x45, 0xe3, 0x69, 0xd0, 0xe5, 0xfb, 0xd3, 0xc0, + 0x59, 0xd8, 0x6f, 0x84, 0xb6, 0x15, 0xcd, 0xa7, 0x10, 0xf3, 0xdc, 0xcf, + 0x19, 0x52, 0x1c, 0x6e, 0x91, 0xf4, 0xf0, 0x02, 0x70, 0x4f, 0x3a, 0x81, + 0x1d, 0x53, 0xd7, 0x17, 0x81, 0x7f, 0xc6, 0x1b, 0x82, 0x1e, 0xd3, 0x0e, + 0x40, 0x17, 0xf0, 0x2f, 0x02, 0xff, 0x4c, 0xbd, 0x45, 0xbe, 0x69, 0x46, + 0xb1, 0x34, 0x3a, 0x4f, 0x1b, 0xc0, 0xa2, 0x7d, 0x4f, 0xc8, 0x17, 0xbd, + 0xb8, 0xe6, 0x3e, 0x4b, 0x3f, 0x5b, 0x1a, 0x86, 0x9d, 0x68, 0x25, 0x87, + 0x7b, 0x1b, 0xb2, 0xb8, 0x0e, 0x23, 0xd9, 0x52, 0x60, 0x83, 0x59, 0x77, + 0xa8, 0x98, 0x34, 0x94, 0x2f, 0x11, 0x39, 0x5c, 0x36, 0x01, 0xc3, 0x31, + 0xe7, 0x83, 0xb9, 0xb1, 0x72, 0x1f, 0x7c, 0x23, 0xc7, 0x57, 0xfd, 0x49, + 0x27, 0x98, 0xfb, 0xdd, 0x72, 0x81, 0x32, 0x62, 0xdc, 0x4e, 0x95, 0x9c, + 0x7f, 0xf7, 0xa1, 0xbf, 0x9b, 0xd6, 0x5c, 0x1b, 0x4f, 0x7a, 0x2c, 0x8c, + 0xf5, 0xda, 0x11, 0x5b, 0xef, 0x6b, 0x0d, 0x7d, 0xd8, 0x11, 0x4c, 0x1e, + 0x2a, 0x97, 0x7a, 0x5b, 0xe5, 0xaa, 0xc1, 0xd8, 0x79, 0x09, 0x46, 0xed, + 0x96, 0xf7, 0x82, 0x1f, 0xa5, 0x9e, 0x86, 0xb9, 0x58, 0xbe, 0xec, 0xcb, + 0x9a, 0x13, 0xac, 0xc1, 0xb8, 0x23, 0x57, 0xd6, 0xfb, 0x62, 0xb2, 0x3e, + 0xb6, 0xb8, 0x66, 0x49, 0xf6, 0x0e, 0x2f, 0x8a, 0x5a, 0xdb, 0x1b, 0xdb, + 0x58, 0x9b, 0xc8, 0x97, 0x4b, 0x3d, 0x0d, 0xe3, 0x64, 0x0e, 0xb8, 0xf4, + 0x03, 0xeb, 0x6b, 0xfb, 0x37, 0xd6, 0xee, 0x90, 0x54, 0x0f, 0xd7, 0xeb, + 0x7d, 0x6d, 0x1b, 0xb8, 0x53, 0x21, 0x3d, 0xbd, 0x6d, 0x1b, 0x38, 0x6c, + 0xe2, 0x6c, 0x18, 0x0f, 0x13, 0xe7, 0xc0, 0x06, 0xce, 0xfd, 0x9b, 0xe9, + 0x39, 0x21, 0xf0, 0x41, 0xb1, 0xd6, 0x8c, 0x1c, 0xb8, 0x50, 0x1e, 0x1c, + 0xff, 0xa2, 0x20, 0xe6, 0xed, 0xdf, 0x16, 0xfa, 0x64, 0xf3, 0x80, 0x0b, + 0x5e, 0x99, 0x42, 0x1f, 0xa7, 0x49, 0x09, 0x72, 0x7e, 0xa8, 0x26, 0x07, + 0xd6, 0x6a, 0x12, 0xea, 0x12, 0x75, 0xe2, 0x32, 0x6c, 0x4c, 0x8a, 0xbb, + 0x32, 0x1d, 0x13, 0x66, 0xc6, 0x82, 0xad, 0xc9, 0x78, 0x09, 0x3e, 0xd9, + 0xc8, 0xec, 0x79, 0x3b, 0x67, 0x3c, 0xe9, 0x1b, 0x88, 0xdb, 0x39, 0xe9, + 0x38, 0xe8, 0x8e, 0x62, 0xbe, 0x46, 0xdb, 0x82, 0x5f, 0xa9, 0x13, 0xf7, + 0x7c, 0xb7, 0x74, 0x21, 0x2e, 0xd6, 0x5e, 0xda, 0x11, 0xd8, 0x8e, 0x98, + 0x26, 0x7c, 0xed, 0xcc, 0x28, 0xe3, 0x78, 0x6b, 0x0c, 0xf0, 0x13, 0x46, + 0x66, 0x6c, 0xe7, 0xf1, 0xda, 0x9d, 0x3b, 0x0b, 0xb5, 0xe2, 0xce, 0x42, + 0xd9, 0xa2, 0x9d, 0xe8, 0xee, 0x28, 0xfa, 0x2a, 0x57, 0x4a, 0xc2, 0x26, + 0x2e, 0xab, 0x3c, 0xe2, 0xb5, 0x7a, 0x1d, 0xf6, 0x47, 0xfb, 0x16, 0x19, + 0xf7, 0xb0, 0xc7, 0xc8, 0x87, 0x90, 0x3b, 0x68, 0x83, 0x4f, 0xcb, 0xe2, + 0xd4, 0xfa, 0xc8, 0xbf, 0x85, 0xf6, 0xc9, 0xfe, 0xfb, 0x7e, 0xe0, 0xef, + 0xef, 0xe8, 0x0e, 0xe6, 0xde, 0x0a, 0x6d, 0x3a, 0xc2, 0x45, 0x3c, 0xc3, + 0xda, 0x38, 0x72, 0x92, 0xf1, 0xba, 0xa9, 0xd1, 0x3f, 0xe7, 0x3c, 0xe6, + 0x12, 0xcc, 0x23, 0xa6, 0x43, 0x3f, 0x27, 0xd9, 0x1c, 0xfc, 0x88, 0x8e, + 0xdc, 0xa2, 0x00, 0xbb, 0x31, 0x33, 0x57, 0x64, 0x46, 0xf9, 0x48, 0x89, + 0xb5, 0x64, 0x9e, 0x00, 0xcc, 0x7f, 0xc0, 0xe6, 0xda, 0xba, 0x43, 0x3d, + 0x0c, 0x7d, 0xbc, 0xf2, 0xbb, 0x80, 0xbd, 0xbc, 0x05, 0xf6, 0xdd, 0x46, + 0x58, 0xbc, 0xbf, 0xb8, 0xe5, 0xfd, 0x4f, 0x69, 0xbf, 0x78, 0xb7, 0x0a, + 0x7f, 0xda, 0x1a, 0xda, 0xfe, 0x05, 0x29, 0xc0, 0xb7, 0x9a, 0x36, 0x73, + 0xc7, 0xdb, 0xb0, 0x16, 0xe3, 0x1a, 0x68, 0x84, 0xbf, 0x40, 0xcc, 0x04, + 0xbf, 0x11, 0x13, 0x12, 0x37, 0x30, 0x3f, 0xa2, 0x9f, 0x00, 0x2c, 0xfd, + 0x2f, 0x61, 0x5f, 0xe9, 0x20, 0xcf, 0x0b, 0x35, 0xae, 0xa1, 0xaf, 0x12, + 0xdf, 0x1d, 0x6d, 0x83, 0x46, 0xf9, 0xaf, 0x19, 0x76, 0x04, 0x1b, 0xe1, + 0xdd, 0x0a, 0xcb, 0x7c, 0x85, 0xb8, 0xbb, 0xc3, 0x3c, 0x60, 0x4c, 0xb2, + 0xf5, 0x2c, 0x7e, 0x45, 0x99, 0x7c, 0x16, 0xb9, 0x98, 0xdd, 0x42, 0x5e, + 0x90, 0x35, 0x56, 0xc0, 0xa3, 0x68, 0xdd, 0x13, 0xbd, 0x9b, 0xc7, 0xf7, + 0xc5, 0x37, 0x7c, 0x25, 0x2d, 0x4d, 0xb2, 0x88, 0x15, 0xe0, 0x71, 0x6a, + 0x42, 0xcf, 0x24, 0x24, 0x57, 0x0b, 0xf8, 0x8b, 0x78, 0x0b, 0xff, 0xc8, + 0x2e, 0x64, 0xb2, 0xee, 0x07, 0x23, 0x99, 0x53, 0xcf, 0xb2, 0x90, 0x4d, + 0x0a, 0xba, 0x34, 0x86, 0xb5, 0x72, 0x02, 0x38, 0x18, 0x87, 0x1d, 0x3d, + 0x13, 0x97, 0x82, 0xc5, 0x7c, 0x41, 0xe5, 0x7a, 0x59, 0xfa, 0x01, 0x3d, + 0xd3, 0x86, 0x39, 0xf6, 0x1f, 0xee, 0x0e, 0x64, 0xdd, 0xc9, 0xf1, 0xb8, + 0x9e, 0xe9, 0xde, 0x32, 0xff, 0x7a, 0x67, 0x40, 0x9b, 0x1a, 0x63, 0xfe, + 0x5f, 0xb6, 0x8c, 0xbf, 0x1e, 0xdf, 0x3c, 0x7e, 0x60, 0x67, 0xa4, 0x0f, + 0x7a, 0xe6, 0x89, 0x90, 0x5e, 0xea, 0xe9, 0x56, 0x5a, 0x7f, 0x13, 0x7d, + 0x79, 0x0e, 0x38, 0x95, 0x8e, 0xff, 0x06, 0xfa, 0xb2, 0x0e, 0xfb, 0x09, + 0xfa, 0xd2, 0x48, 0xc3, 0x7a, 0x5d, 0x51, 0xd1, 0x91, 0x93, 0xba, 0xa3, + 0x7b, 0x90, 0x77, 0xa4, 0x24, 0x5f, 0x07, 0xef, 0xd6, 0xe3, 0xea, 0x3a, + 0x4c, 0x71, 0x03, 0x26, 0x88, 0x3b, 0xf9, 0xba, 0x8f, 0x3c, 0xae, 0x31, + 0x06, 0x0f, 0xa3, 0x5f, 0xc4, 0x59, 0x57, 0x64, 0xd2, 0x5b, 0xcb, 0xea, + 0xf6, 0xa9, 0x20, 0x0f, 0xb5, 0xbf, 0xad, 0xe5, 0x17, 0x99, 0xa3, 0xc6, + 0xd0, 0x57, 0xf5, 0x07, 0x62, 0xdc, 0x33, 0x5a, 0x76, 0x79, 0x0e, 0xf9, + 0xe9, 0x12, 0x7e, 0x67, 0xf1, 0xab, 0xe1, 0x17, 0xd5, 0x01, 0x2f, 0xa0, + 0x8e, 0x50, 0xfe, 0x1e, 0xb1, 0x29, 0xd8, 0xff, 0x67, 0x4b, 0xc8, 0x8f, + 0xe7, 0x12, 0xf2, 0x94, 0xad, 0xf7, 0xea, 0x81, 0x8f, 0xcb, 0x22, 0xb7, + 0xb6, 0x2e, 0xcb, 0x97, 0xc2, 0x1c, 0x4d, 0xe4, 0x9d, 0x0a, 0x64, 0xb9, + 0xff, 0x48, 0xe8, 0x9f, 0xbe, 0xf6, 0xa0, 0xab, 0x7c, 0x79, 0x98, 0x83, + 0xc1, 0xef, 0x64, 0x15, 0xd4, 0x1b, 0xe0, 0x8f, 0x26, 0xef, 0x41, 0x8f, + 0xdf, 0xa9, 0xb4, 0x83, 0x1e, 0x5b, 0x0a, 0xc7, 0x90, 0xbb, 0x68, 0x83, + 0xd6, 0x36, 0xad, 0x1d, 0x79, 0x18, 0xfc, 0x8e, 0x1a, 0x93, 0x67, 0x17, + 0xa7, 0x16, 0xca, 0x3a, 0x60, 0xc1, 0xf3, 0x51, 0xf4, 0xa1, 0x7f, 0x97, + 0x2a, 0x5c, 0xa7, 0xcb, 0xbb, 0x15, 0x43, 0x7e, 0x8e, 0xbc, 0xee, 0x3d, + 0xfb, 0xe2, 0x14, 0x6c, 0xb0, 0x0f, 0xf1, 0x0a, 0xb5, 0xd0, 0x1e, 0xc6, + 0x8c, 0x01, 0x13, 0xcf, 0x3c, 0x7e, 0x87, 0x91, 0xe7, 0x5d, 0x7b, 0xcd, + 0x27, 0xc1, 0x93, 0xb6, 0x18, 0xd6, 0x10, 0xde, 0x04, 0x6d, 0x5d, 0xd0, + 0xc1, 0xb4, 0x35, 0x21, 0xdd, 0x96, 0xca, 0x9d, 0x34, 0xce, 0x07, 0x7e, + 0xf2, 0xe3, 0xf3, 0xe4, 0xb3, 0x01, 0x1d, 0xe2, 0x98, 0xef, 0xe8, 0xcf, + 0x89, 0x2f, 0x7d, 0x30, 0x8b, 0xc3, 0x5c, 0xaa, 0x04, 0xfd, 0x68, 0x4e, + 0xb4, 0x28, 0xa6, 0xd2, 0x4f, 0xe7, 0x61, 0xab, 0x1c, 0x8f, 0x8b, 0x92, + 0xc1, 0x26, 0x79, 0x52, 0x8f, 0x56, 0xa7, 0x66, 0x6c, 0xca, 0xd5, 0x92, + 0xe9, 0x72, 0x24, 0x57, 0xca, 0x08, 0x75, 0x66, 0xe5, 0xdb, 0x90, 0xab, + 0x1e, 0xd6, 0x20, 0xf0, 0x03, 0x73, 0x94, 0x2f, 0xea, 0xc4, 0x0a, 0xf2, + 0xb0, 0x8a, 0xc4, 0x83, 0x1a, 0xea, 0x19, 0xd4, 0x1d, 0x90, 0x5f, 0x79, + 0x0e, 0x38, 0x12, 0x78, 0x2e, 0xe1, 0x99, 0xc4, 0xf3, 0x2c, 0x9e, 0xfd, + 0x78, 0xd6, 0x68, 0x1f, 0x61, 0xde, 0xf3, 0x31, 0x7a, 0x60, 0x27, 0x79, + 0xda, 0xb4, 0x7c, 0xaf, 0x9e, 0x91, 0xbf, 0xad, 0x1f, 0x94, 0xbf, 0xa9, + 0x8f, 0xca, 0x5f, 0xd7, 0x1d, 0x79, 0xb9, 0xbe, 0x5f, 0xfe, 0xaa, 0x3e, + 0xcc, 0x9a, 0x10, 0x39, 0x5c, 0x0a, 0xbe, 0xf9, 0xbc, 0x3c, 0xe8, 0xd5, + 0xe1, 0x73, 0x28, 0xff, 0x8b, 0x53, 0xd9, 0xda, 0x75, 0x52, 0x78, 0xd6, + 0x42, 0x9e, 0x69, 0xb0, 0x2e, 0x93, 0xc7, 0x9c, 0x3b, 0xe2, 0x94, 0xbd, + 0x6e, 0xb3, 0x4e, 0x39, 0x49, 0x38, 0xd4, 0xbb, 0x1a, 0xf2, 0x97, 0x16, + 0x99, 0x48, 0xa4, 0x57, 0x5c, 0x23, 0x19, 0xfa, 0xa3, 0x3b, 0x01, 0x87, + 0x3d, 0xbd, 0x0e, 0x59, 0x7b, 0x1e, 0xb6, 0xe0, 0xa0, 0x56, 0x4e, 0xc4, + 0xe0, 0xfb, 0x54, 0x7e, 0xa2, 0x7c, 0x4b, 0xe0, 0x4b, 0xa3, 0x9a, 0x91, + 0x73, 0xd9, 0x70, 0x8e, 0xf1, 0xd1, 0x02, 0xec, 0x72, 0x18, 0x43, 0xb6, + 0xe2, 0xa4, 0x6f, 0x3c, 0x16, 0xfa, 0xc7, 0x15, 0x39, 0xe1, 0x0d, 0x66, + 0xaf, 0x20, 0xf6, 0x68, 0x2d, 0x51, 0x5e, 0xb4, 0x0b, 0xb4, 0xf9, 0xfe, + 0xdd, 0xac, 0xbf, 0xe3, 0xa6, 0xfc, 0x70, 0x36, 0x6d, 0x3d, 0xa2, 0xcf, + 0x40, 0xce, 0xbe, 0x7f, 0xd4, 0x4e, 0x9f, 0x9a, 0xd0, 0x3b, 0xe5, 0x27, + 0xcf, 0x30, 0x26, 0xaf, 0x4e, 0x7d, 0x1f, 0x7a, 0x50, 0x5d, 0x6a, 0x95, + 0x6a, 0xd5, 0x94, 0x4b, 0x23, 0x83, 0x6a, 0xdf, 0x6a, 0x2d, 0x8e, 0x3c, + 0xaf, 0x4d, 0xa6, 0xfb, 0x94, 0xb2, 0xc3, 0x6f, 0x0f, 0x2b, 0xbf, 0xed, + 0xda, 0x78, 0xd6, 0x92, 0xd6, 0x66, 0x5a, 0x5e, 0x96, 0x82, 0x07, 0x1d, + 0x8b, 0xef, 0x02, 0x4f, 0xd8, 0x1f, 0xb4, 0x0a, 0x3a, 0x62, 0xa0, 0x39, + 0x68, 0x3d, 0xa8, 0xff, 0xd2, 0xff, 0x1d, 0x93, 0x7c, 0x7c, 0x1b, 0xb1, + 0x85, 0xb1, 0x52, 0x53, 0x7a, 0xb7, 0xb0, 0xf4, 0x53, 0x8b, 0xfe, 0x65, + 0xa5, 0xb6, 0x2b, 0x1c, 0xd3, 0xbf, 0x73, 0xdc, 0x2e, 0x2f, 0x57, 0xb7, + 0xcb, 0x62, 0x95, 0xef, 0x5b, 0x65, 0xa1, 0x3a, 0x78, 0xa5, 0x57, 0xef, + 0x93, 0xd5, 0xeb, 0x6e, 0xb4, 0xee, 0xd7, 0xc1, 0x93, 0x63, 0x1f, 0xc9, + 0x07, 0x23, 0xdd, 0xf2, 0xd6, 0x7d, 0xe9, 0x17, 0xfe, 0x44, 0x87, 0x3e, + 0x8e, 0x74, 0xd0, 0xce, 0xd0, 0xe7, 0x7c, 0xfa, 0x4a, 0x56, 0xa7, 0x9e, + 0xfd, 0x00, 0xfa, 0x95, 0xae, 0x04, 0x3a, 0x49, 0xdc, 0xc4, 0x0b, 0xf9, + 0xd8, 0x6f, 0x00, 0x27, 0xde, 0xd5, 0x06, 0x81, 0xeb, 0x0d, 0xc5, 0x8b, + 0xbb, 0x9d, 0xf4, 0x15, 0x84, 0x28, 0xff, 0x92, 0x3d, 0x38, 0x3c, 0xa0, + 0xef, 0x92, 0x6a, 0xf2, 0x46, 0xeb, 0xbb, 0x88, 0x07, 0xd9, 0x44, 0xfa, + 0xd4, 0x45, 0x59, 0x9d, 0xba, 0x60, 0x53, 0x17, 0x69, 0xc3, 0xff, 0x80, + 0x9c, 0xd4, 0x92, 0x4a, 0x8d, 0xbe, 0x8b, 0xb8, 0x58, 0x17, 0xec, 0xb5, + 0x4e, 0x80, 0x06, 0x77, 0x3f, 0xde, 0x61, 0xde, 0xf8, 0x3c, 0xe5, 0xd6, + 0xc2, 0xb5, 0xc3, 0x59, 0xbd, 0x7f, 0x0b, 0x8f, 0x06, 0xad, 0x43, 0x3a, + 0xf7, 0xfb, 0x2f, 0xec, 0xfb, 0x3e, 0x68, 0x1d, 0xc4, 0x5a, 0xc4, 0xd0, + 0x64, 0xe3, 0x1e, 0x3f, 0x52, 0x7b, 0x3c, 0x5b, 0x43, 0x0e, 0xb8, 0xbe, + 0x07, 0xe6, 0x6a, 0x3a, 0xce, 0x69, 0x2a, 0xb9, 0x5c, 0x1a, 0x21, 0x7f, + 0x6f, 0xef, 0x61, 0x2c, 0x37, 0x32, 0x2f, 0x85, 0x79, 0x46, 0x4c, 0x7e, + 0x8c, 0xba, 0x6b, 0x12, 0xfe, 0x7f, 0x61, 0xef, 0x20, 0x68, 0x40, 0x7d, + 0x9a, 0x54, 0xf1, 0x7c, 0xca, 0x05, 0x8e, 0x9c, 0xc2, 0xfd, 0xa6, 0x2c, + 0x01, 0xf7, 0x38, 0xf9, 0x00, 0xdc, 0x33, 0x9c, 0x57, 0x32, 0xc0, 0x7c, + 0x2d, 0x05, 0xbc, 0xbd, 0xa1, 0xff, 0x8b, 0x43, 0x57, 0xf7, 0x59, 0x77, + 0x4b, 0x2c, 0xf4, 0x7f, 0x71, 0x79, 0xeb, 0x79, 0xe8, 0x7d, 0x9c, 0xfa, + 0x93, 0xe8, 0xd9, 0xd0, 0x9f, 0x46, 0xfc, 0xad, 0x92, 0xaf, 0xc4, 0x80, + 0x17, 0x39, 0xf7, 0x28, 0xf1, 0x62, 0x5c, 0xa5, 0x2e, 0x17, 0x43, 0x5d, + 0xee, 0x08, 0x71, 0xaf, 0x41, 0x97, 0xd3, 0xa9, 0x55, 0x9d, 0xf5, 0xd5, + 0x4e, 0x55, 0xf3, 0x1a, 0xb0, 0xaf, 0x42, 0x99, 0xb1, 0x88, 0xb6, 0x75, + 0x71, 0x6a, 0x12, 0x35, 0x6c, 0xa1, 0x7c, 0x50, 0x2f, 0xd4, 0x47, 0xf5, + 0x82, 0x47, 0x7d, 0xdb, 0x6b, 0x2d, 0x28, 0x1e, 0x27, 0x65, 0xa1, 0xfe, + 0x81, 0x5f, 0xda, 0xbb, 0x0d, 0x7d, 0xe8, 0xfe, 0x38, 0xe5, 0x7b, 0x3d, + 0xe9, 0x42, 0x50, 0x27, 0xbf, 0x13, 0x72, 0x66, 0xe8, 0x7b, 0xdd, 0xcc, + 0xd1, 0x96, 0x87, 0x88, 0x1f, 0x74, 0x24, 0x12, 0xb2, 0xe8, 0x71, 0x8f, + 0xd5, 0x29, 0xf2, 0xb2, 0x30, 0x67, 0xc9, 0x09, 0x25, 0x3f, 0x9e, 0x9b, + 0xf7, 0x47, 0x86, 0x4c, 0xc6, 0x07, 0xad, 0x47, 0x25, 0x7d, 0x65, 0xcd, + 0x48, 0xbf, 0x30, 0x81, 0xb8, 0xba, 0x30, 0x6f, 0x88, 0xab, 0xea, 0x30, + 0xca, 0x28, 0x5d, 0x81, 0x35, 0x86, 0x67, 0xbf, 0xa7, 0xe1, 0xec, 0x5d, + 0x72, 0xe1, 0xf9, 0xcf, 0xc3, 0xee, 0x5f, 0x81, 0x2c, 0xcc, 0xd4, 0x71, + 0xe4, 0x19, 0xcf, 0xc9, 0xa0, 0x55, 0x42, 0xfe, 0x0c, 0xbe, 0xa3, 0xbd, + 0xa2, 0x6c, 0x60, 0x41, 0xc7, 0xb8, 0x9f, 0x7c, 0xe2, 0x78, 0xb7, 0x2c, + 0xf4, 0x05, 0x36, 0xce, 0x77, 0x03, 0xc0, 0x11, 0xbc, 0xe3, 0xf8, 0xb7, + 0x64, 0x40, 0xbd, 0xab, 0xaa, 0x75, 0x25, 0xe9, 0x0d, 0xe5, 0xf7, 0x18, + 0xf6, 0x24, 0x8f, 0xa3, 0xf9, 0x4e, 0x09, 0x6c, 0x29, 0xe2, 0xbb, 0x25, + 0x47, 0x6b, 0x09, 0xb9, 0xa7, 0x96, 0x94, 0x2f, 0xd7, 0xfa, 0x25, 0x0f, + 0x39, 0x4e, 0x8e, 0x3e, 0xd9, 0xc3, 0xb3, 0xe5, 0x96, 0xd2, 0x2f, 0x88, + 0x4e, 0x5a, 0xab, 0x72, 0xdc, 0x8b, 0xe8, 0xe9, 0x08, 0xe9, 0x33, 0xc3, + 0x71, 0x2c, 0xa4, 0xa1, 0x11, 0x5f, 0x07, 0x70, 0x65, 0x81, 0xe7, 0xa5, + 0x10, 0x0f, 0xfd, 0x08, 0x68, 0x3d, 0x96, 0x94, 0x25, 0x8f, 0x74, 0x6c, + 0x97, 0x52, 0x82, 0xfd, 0x57, 0xa0, 0x6f, 0xc4, 0xb3, 0x8d, 0xf9, 0xcd, + 0x26, 0x1e, 0x3f, 0x5c, 0x2b, 0x82, 0xc7, 0xe4, 0x2f, 0xe1, 0xe0, 0xaf, + 0xbf, 0x40, 0xf9, 0xed, 0x43, 0x8e, 0x6f, 0x07, 0xba, 0x69, 0x6d, 0xec, + 0x99, 0x9f, 0xeb, 0x82, 0xac, 0xb8, 0x6f, 0xbb, 0x1c, 0x83, 0xdd, 0xe7, + 0xaa, 0xdc, 0xff, 0x18, 0xf4, 0xe8, 0x2d, 0xb5, 0x7f, 0x7e, 0xa9, 0x2f, + 0x5c, 0xcf, 0xb5, 0x5d, 0x5b, 0xd6, 0xb6, 0xca, 0xa1, 0x8a, 0x75, 0x8d, + 0xf5, 0xbf, 0x8f, 0xf5, 0xba, 0x9c, 0x1e, 0xe5, 0x7a, 0xe2, 0x01, 0x5c, + 0x35, 0xf1, 0x29, 0x78, 0xe2, 0xaa, 0xde, 0xcf, 0x55, 0x5b, 0x25, 0x57, + 0x89, 0x70, 0x11, 0xcf, 0x47, 0xa8, 0x87, 0xbf, 0xaa, 0x70, 0x4d, 0x2a, + 0x5c, 0x78, 0x5f, 0xa5, 0xcf, 0xb9, 0x15, 0xeb, 0x3b, 0xe8, 0xff, 0xa5, + 0x14, 0xef, 0x94, 0x92, 0xaa, 0xe9, 0xdb, 0x95, 0xaf, 0x29, 0xc5, 0xdb, + 0xf0, 0xbe, 0x13, 0x36, 0xbf, 0x0f, 0xb9, 0x45, 0x17, 0xeb, 0xdc, 0x2d, + 0x73, 0x5b, 0xe9, 0x8f, 0x6d, 0xa1, 0x3f, 0x06, 0xb8, 0x5e, 0xec, 0x19, + 0xc0, 0xe5, 0x01, 0x37, 0x3d, 0x07, 0x3e, 0x3b, 0xf4, 0x2b, 0x8c, 0x93, + 0xd7, 0x29, 0x5a, 0xa6, 0x97, 0xfe, 0x1b, 0xe7, 0xea, 0xc3, 0xda, 0x68, + 0x1c, 0xf0, 0xe1, 0x69, 0xe0, 0x99, 0xab, 0xaa, 0xbb, 0x0b, 0xc8, 0x60, + 0x7b, 0x9c, 0x67, 0x2f, 0x55, 0x3f, 0x8b, 0x67, 0xd7, 0x35, 0xf0, 0x8b, + 0xbc, 0x22, 0xbd, 0xa4, 0x95, 0xf7, 0x48, 0xb0, 0x37, 0x07, 0x7a, 0x1c, + 0x37, 0x24, 0x3f, 0x6a, 0x21, 0x3f, 0xe7, 0x3d, 0x2c, 0xed, 0xd2, 0xe2, + 0xdd, 0x67, 0x4c, 0xb7, 0x19, 0x6b, 0x4d, 0x75, 0xf6, 0xe3, 0x4b, 0xbc, + 0x8b, 0x4d, 0xf1, 0xee, 0x6e, 0x98, 0xd7, 0x18, 0x8f, 0x2c, 0xd9, 0xf2, + 0x78, 0x6d, 0x58, 0x1e, 0xad, 0xa5, 0xad, 0xfb, 0xe1, 0x03, 0x0a, 0xeb, + 0x77, 0xb4, 0x43, 0x71, 0xfa, 0x2f, 0x13, 0x79, 0x60, 0x8b, 0x1d, 0xe4, + 0x05, 0x25, 0xd6, 0x6c, 0x73, 0x69, 0xde, 0xe3, 0x58, 0x55, 0xd9, 0x9a, + 0x3b, 0xfc, 0x5f, 0xe6, 0x0d, 0xdc, 0x9f, 0xfe, 0x1a, 0x79, 0x82, 0x87, + 0x3c, 0xc1, 0x43, 0x9e, 0xe0, 0x21, 0x4f, 0xf0, 0x90, 0x27, 0x78, 0xc8, + 0x13, 0x3c, 0xe4, 0x09, 0x1e, 0xf2, 0x04, 0xc4, 0xee, 0xa0, 0x5e, 0x18, + 0x43, 0xfe, 0x0b, 0xff, 0xe5, 0xdd, 0x06, 0x3e, 0xf1, 0xfe, 0x92, 0x31, + 0x87, 0xb1, 0x99, 0x73, 0xab, 0xdb, 0x5c, 0xca, 0x4d, 0xf9, 0xbe, 0x3b, + 0x31, 0x37, 0x1e, 0xe6, 0x23, 0x84, 0x89, 0x62, 0x37, 0xe1, 0xe4, 0xa0, + 0xeb, 0x68, 0xb0, 0x31, 0xe6, 0x2b, 0x41, 0xcc, 0x0a, 0x72, 0xe5, 0xb7, + 0x91, 0xb3, 0xa4, 0x90, 0xb3, 0xf4, 0x23, 0x3f, 0xe1, 0x9d, 0x75, 0x74, + 0xc7, 0x94, 0xd5, 0x8e, 0x7a, 0x63, 0xda, 0x3d, 0x1e, 0x73, 0x69, 0x3b, + 0x55, 0xd0, 0xf5, 0xb9, 0x5e, 0xf1, 0x25, 0x37, 0xf2, 0x4d, 0xe4, 0xad, + 0xcf, 0xa9, 0xfb, 0xb4, 0xf1, 0x21, 0xca, 0xbc, 0xf2, 0x09, 0xb9, 0x6b, + 0xc4, 0xdf, 0xe0, 0x1e, 0x50, 0x5f, 0x20, 0xff, 0x44, 0x7a, 0xce, 0x81, + 0xe1, 0xe7, 0x62, 0x12, 0x3f, 0xb3, 0x1d, 0x73, 0x96, 0xf4, 0xaa, 0xbb, + 0x24, 0x88, 0xf2, 0xdc, 0x55, 0xc8, 0xcb, 0x16, 0xfd, 0x1c, 0x6f, 0x1c, + 0x88, 0x97, 0xfe, 0x75, 0x65, 0x2a, 0x57, 0x5d, 0x51, 0x3a, 0x75, 0xb4, + 0x96, 0x47, 0x7d, 0xd4, 0xd3, 0x2b, 0xed, 0x26, 0x6a, 0xab, 0x08, 0x37, + 0x71, 0xfe, 0x32, 0xae, 0x6a, 0x9e, 0x73, 0xeb, 0xf2, 0x84, 0xac, 0xb9, + 0xcf, 0xca, 0x54, 0xa9, 0x92, 0x4e, 0xb2, 0x56, 0xce, 0x5a, 0x2b, 0x53, + 0x27, 0x81, 0x63, 0x11, 0xb9, 0x81, 0xa1, 0xf6, 0x5e, 0x99, 0x9a, 0xae, + 0x04, 0xf7, 0x59, 0x01, 0x0d, 0x8c, 0x57, 0xed, 0x62, 0x2c, 0x04, 0xf7, + 0x5a, 0xba, 0x5a, 0xcb, 0x75, 0x5c, 0x6f, 0x62, 0x1d, 0xe5, 0x36, 0x8c, + 0xb5, 0x94, 0x1d, 0x69, 0x58, 0x99, 0x2a, 0x56, 0x1b, 0x69, 0x20, 0x1e, + 0xe2, 0x8d, 0xce, 0xc3, 0xb3, 0xc4, 0x45, 0x3f, 0xe3, 0xfb, 0x85, 0x91, + 0xfe, 0x30, 0xef, 0x3a, 0x89, 0xfc, 0xce, 0x0c, 0xf4, 0x5c, 0x8d, 0xbf, + 0xa3, 0xe2, 0x54, 0x4a, 0xe7, 0x3c, 0x9f, 0x78, 0x37, 0xba, 0x80, 0x39, + 0x8c, 0x17, 0x23, 0x58, 0x3d, 0x84, 0xed, 0x6c, 0xe0, 0x67, 0x4b, 0xb8, + 0x1f, 0x69, 0xe2, 0x39, 0x2f, 0x61, 0x2f, 0xd2, 0x45, 0x98, 0x38, 0x68, + 0x83, 0x2c, 0xbd, 0xff, 0x2d, 0xef, 0x1b, 0xcf, 0x44, 0x9e, 0x9a, 0x58, + 0x43, 0x78, 0xe2, 0x88, 0xd6, 0xe0, 0xc5, 0xb9, 0x60, 0x9d, 0xbe, 0x7e, + 0xff, 0xf7, 0x69, 0xfb, 0x36, 0xd2, 0x1a, 0xed, 0x1f, 0xe1, 0x19, 0x0e, + 0xe4, 0xb6, 0xbe, 0x5e, 0xfd, 0x9f, 0x61, 0x78, 0x42, 0x17, 0x3f, 0x76, + 0x8f, 0x3a, 0xdc, 0x50, 0x87, 0x46, 0xf7, 0x17, 0xbc, 0x0f, 0x60, 0x7d, + 0xcf, 0x6f, 0x07, 0x8d, 0xb5, 0xe2, 0xcb, 0x61, 0x2c, 0xdb, 0x29, 0x59, + 0x93, 0x75, 0xc3, 0xf9, 0x70, 0xbc, 0x03, 0xb1, 0x8d, 0xe3, 0x3a, 0xf8, + 0x0b, 0x5d, 0x76, 0xda, 0xc3, 0xba, 0x25, 0x1e, 0x7c, 0xe3, 0x19, 0xa6, + 0x1d, 0xb1, 0xee, 0x6b, 0x0b, 0xe7, 0x22, 0x3b, 0xa2, 0x1f, 0x36, 0xc3, + 0x39, 0xfa, 0x5b, 0x1d, 0xb5, 0x0b, 0xfb, 0xc0, 0xb3, 0xd8, 0x68, 0x4b, + 0xd1, 0x33, 0x2e, 0x67, 0xe7, 0x23, 0xbf, 0x05, 0x9f, 0x32, 0x64, 0x86, + 0xbe, 0xbf, 0x03, 0xbe, 0xaf, 0x4b, 0x0e, 0xc1, 0x67, 0x1d, 0x86, 0xcf, + 0x3a, 0x82, 0x7a, 0x71, 0x6c, 0xa9, 0xf1, 0x9e, 0x97, 0x35, 0x6a, 0x97, + 0x76, 0x5c, 0xc9, 0xbf, 0xe8, 0x1b, 0xf6, 0x47, 0xd0, 0x01, 0xd6, 0x5d, + 0x91, 0x4e, 0xc0, 0xdf, 0x3a, 0x71, 0xe8, 0xc4, 0xd6, 0xfb, 0xe4, 0x61, + 0xd8, 0x46, 0x7b, 0x56, 0xc5, 0x86, 0xa5, 0x80, 0xf7, 0xa5, 0x6a, 0xc0, + 0x7b, 0xf8, 0x65, 0xe0, 0x37, 0xa5, 0x58, 0xb3, 0xa4, 0x88, 0x7d, 0x8b, + 0xd8, 0xb7, 0x88, 0x3a, 0x6f, 0xba, 0xd6, 0xf8, 0x1d, 0xab, 0x33, 0xa4, + 0x9d, 0x6b, 0xa3, 0xbe, 0xd5, 0x70, 0xfe, 0xe8, 0x79, 0x0a, 0xfc, 0x7f, + 0x0c, 0xfc, 0x3f, 0x81, 0xfa, 0xe6, 0x8f, 0x50, 0xdf, 0x7c, 0x0d, 0xf5, + 0xcd, 0x71, 0xd4, 0x37, 0x13, 0xa8, 0x6f, 0xbe, 0x0a, 0xff, 0xf1, 0x15, + 0xf8, 0x8f, 0x63, 0xf0, 0x1f, 0xe3, 0xea, 0xee, 0xe9, 0xa8, 0xb7, 0xf5, + 0x4e, 0x25, 0xda, 0x8b, 0xed, 0x67, 0x22, 0x76, 0x11, 0x67, 0x1a, 0x93, + 0x6a, 0x9d, 0xf5, 0x8d, 0x23, 0xee, 0x41, 0xd6, 0x37, 0xc7, 0xb4, 0x09, + 0xe4, 0xef, 0xf7, 0xef, 0x67, 0xdd, 0x13, 0xd7, 0x72, 0xaa, 0xee, 0x49, + 0x9f, 0x77, 0x91, 0x22, 0x21, 0xf7, 0xc3, 0x99, 0xd3, 0x67, 0x73, 0xa0, + 0x25, 0xc8, 0xf9, 0x7a, 0x42, 0xbf, 0xd7, 0x21, 0x8b, 0xb3, 0xa8, 0x19, + 0xbc, 0x1f, 0x6b, 0x05, 0xe5, 0x1b, 0x2d, 0x8c, 0x51, 0x2b, 0x7b, 0xff, + 0x1c, 0x8e, 0x47, 0x64, 0x72, 0x1e, 0xb5, 0xed, 0xf3, 0xff, 0xa8, 0xe5, + 0xd4, 0xd8, 0xc1, 0x18, 0xf9, 0xee, 0xf3, 0x7f, 0x1f, 0x8e, 0x8b, 0xa1, + 0x3e, 0x84, 0xb4, 0x5a, 0x0e, 0x9e, 0xdd, 0x61, 0xce, 0xf1, 0x6a, 0xef, + 0xe6, 0xff, 0xd3, 0x8e, 0xad, 0x45, 0x13, 0xfb, 0x1b, 0x3b, 0x82, 0xfa, + 0xac, 0x71, 0xbe, 0xab, 0x61, 0xfe, 0x8a, 0xfa, 0xce, 0x5a, 0x28, 0xb7, + 0xfd, 0x0a, 0x1e, 0x58, 0x96, 0x86, 0x98, 0xe7, 0x7d, 0xe4, 0xf3, 0xfb, + 0x9f, 0xab, 0xb7, 0xab, 0x6f, 0x72, 0xae, 0xca, 0xb7, 0x61, 0xe7, 0x23, + 0xa5, 0x1d, 0x81, 0x2f, 0x60, 0x3f, 0xa1, 0x05, 0xfe, 0xfd, 0x8f, 0x81, + 0x07, 0xbc, 0xf6, 0x1a, 0x6b, 0x38, 0x2b, 0xbc, 0x4b, 0xb9, 0x32, 0xc5, + 0xdc, 0xba, 0xa4, 0x70, 0xb3, 0xd6, 0x63, 0xdd, 0x17, 0xc5, 0x80, 0x08, + 0xd7, 0xcf, 0x13, 0x01, 0xdd, 0xe3, 0xa8, 0xe9, 0x08, 0x13, 0x8d, 0x1b, + 0xeb, 0xbf, 0x8e, 0xf0, 0x1e, 0xee, 0x4a, 0x90, 0x57, 0x29, 0x7c, 0x66, + 0x88, 0xef, 0x3f, 0xfd, 0xc0, 0xf7, 0x70, 0xbd, 0xd5, 0xb0, 0xfe, 0x3c, + 0x72, 0x3d, 0xde, 0x99, 0xec, 0x52, 0xdf, 0x19, 0xdf, 0x9f, 0xed, 0x94, + 0x5f, 0x3c, 0xe3, 0xfb, 0xe3, 0x4e, 0x7a, 0xf8, 0x4d, 0xd4, 0x1e, 0x67, + 0x68, 0x27, 0x23, 0xa4, 0x73, 0x30, 0x35, 0x2d, 0x03, 0xbd, 0x41, 0x2e, + 0xfe, 0x75, 0xed, 0xe3, 0x74, 0xeb, 0xe1, 0x3e, 0x3f, 0x6c, 0xd8, 0x27, + 0xd5, 0xb0, 0xcf, 0x0a, 0x6d, 0xb6, 0x7a, 0x2f, 0xce, 0x5c, 0xdc, 0x75, + 0xa3, 0x95, 0x08, 0xeb, 0xb2, 0x47, 0x47, 0xda, 0xa4, 0xd2, 0x97, 0x5e, + 0xf9, 0x11, 0xf2, 0xf5, 0xc2, 0x08, 0xe6, 0x12, 0x83, 0x78, 0xc7, 0xf9, + 0x74, 0x15, 0xb9, 0xe8, 0x4a, 0x55, 0x86, 0xb0, 0x3e, 0x5d, 0x14, 0xe1, + 0x3c, 0xfb, 0x8a, 0xb6, 0x6a, 0xe8, 0x03, 0x92, 0x6b, 0x38, 0xf3, 0x04, + 0xea, 0xaf, 0x13, 0xeb, 0xf5, 0x30, 0xf7, 0xb9, 0x59, 0x5b, 0x53, 0xb9, + 0xf1, 0x01, 0xad, 0x98, 0x08, 0xce, 0xf8, 0x87, 0xf0, 0x17, 0x86, 0xce, + 0xb5, 0xef, 0x03, 0xb7, 0x26, 0x0b, 0xcf, 0x18, 0xea, 0x0e, 0xb6, 0x30, + 0x42, 0x59, 0xf3, 0x79, 0x2d, 0xde, 0x45, 0x67, 0xfa, 0xf3, 0xf0, 0x4c, + 0xd9, 0xb0, 0x9e, 0x8e, 0xce, 0x14, 0x93, 0x77, 0x67, 0x2d, 0xac, 0xfd, + 0x1c, 0xf8, 0x91, 0x97, 0xa5, 0x7a, 0xea, 0x33, 0xf0, 0x94, 0x1b, 0x78, + 0x63, 0x6e, 0x91, 0x61, 0x71, 0xa3, 0x86, 0x1f, 0x4f, 0xc2, 0x0e, 0xbf, + 0xd1, 0x1b, 0xdd, 0x0d, 0x1b, 0xb6, 0xcf, 0xba, 0x07, 0x8d, 0xf3, 0xfd, + 0xb0, 0xc5, 0x14, 0xec, 0x93, 0x39, 0x53, 0x9e, 0xb5, 0x0a, 0xed, 0xc9, + 0x72, 0x8d, 0xb4, 0x75, 0x4c, 0x86, 0x51, 0xef, 0xf0, 0xfc, 0x19, 0x59, + 0xac, 0x47, 0x34, 0x8c, 0xc2, 0x1e, 0x0f, 0xe2, 0xb7, 0x1f, 0xef, 0x1c, + 0xfc, 0x58, 0x2b, 0xad, 0xc8, 0xe3, 0x2a, 0x17, 0x47, 0xae, 0x3d, 0x44, + 0xfa, 0xee, 0x04, 0x3c, 0xf5, 0x99, 0x7a, 0x7a, 0xa7, 0xb8, 0x7d, 0xf4, + 0x15, 0x49, 0xe0, 0xc6, 0x1a, 0xef, 0x22, 0x6c, 0xbd, 0x1f, 0xcf, 0xb4, + 0x55, 0x20, 0x6f, 0x15, 0x7e, 0xdf, 0x37, 0x46, 0xf9, 0x8d, 0xe2, 0x7c, + 0x38, 0x1e, 0xb4, 0xbe, 0x4c, 0xdd, 0x4b, 0xee, 0x96, 0x95, 0xf9, 0x28, + 0x0e, 0x9e, 0x86, 0x0d, 0xf2, 0xce, 0x76, 0x0c, 0x7c, 0xe1, 0x58, 0x0b, + 0xe3, 0x21, 0xe6, 0x17, 0x97, 0x71, 0xee, 0x8c, 0x9c, 0x41, 0xfd, 0x2f, + 0x7d, 0x7c, 0xa6, 0x80, 0x7f, 0x7b, 0xa8, 0xef, 0x9b, 0xd7, 0x1b, 0x36, + 0xfb, 0x63, 0xa0, 0xcf, 0x6c, 0x58, 0xcf, 0x35, 0x41, 0x7d, 0xb2, 0x26, + 0x88, 0xc7, 0x49, 0xff, 0x76, 0x3d, 0xf3, 0xa2, 0x3c, 0xa0, 0xce, 0x54, + 0x93, 0xe3, 0xf3, 0xbe, 0xef, 0x8e, 0x0e, 0x0e, 0x2f, 0x4a, 0x7a, 0xf8, + 0xa4, 0xec, 0xb3, 0x0e, 0xb1, 0x1e, 0xb3, 0x88, 0xc7, 0xbf, 0xbd, 0x25, + 0xe3, 0xfb, 0xa7, 0x41, 0xfb, 0xf7, 0xd5, 0x3e, 0x2f, 0x82, 0x7e, 0xf0, + 0x4a, 0xd5, 0x24, 0xa4, 0x15, 0xcf, 0x04, 0xe9, 0x2d, 0xcb, 0xf1, 0xfa, + 0x85, 0x50, 0x36, 0x8f, 0x89, 0xeb, 0x5d, 0x36, 0x5c, 0xbb, 0x0c, 0xd8, + 0x85, 0x90, 0xb6, 0x0c, 0xe8, 0xc5, 0xfe, 0xf5, 0xb7, 0x13, 0xf4, 0x0d, + 0x94, 0xb9, 0x8b, 0xac, 0xd1, 0x1d, 0x41, 0x1e, 0x95, 0xf8, 0x24, 0x3f, + 0x10, 0x97, 0xcd, 0x7e, 0x80, 0xeb, 0xe2, 0xd7, 0xd0, 0x15, 0xd2, 0x51, + 0x54, 0xfe, 0x53, 0xc5, 0x2d, 0x85, 0xcf, 0xd8, 0xe2, 0x0b, 0x2a, 0xea, + 0xb9, 0x6a, 0xd0, 0x37, 0x31, 0xfe, 0x51, 0x87, 0xbb, 0xe0, 0xff, 0xa0, + 0x83, 0xb0, 0xe3, 0xdc, 0x3c, 0xef, 0x27, 0x86, 0x78, 0xaf, 0x74, 0x36, + 0x0f, 0xd9, 0x2e, 0xf0, 0xfb, 0x63, 0x22, 0xa8, 0x31, 0x83, 0xfa, 0x2b, + 0x45, 0x5f, 0x88, 0xb6, 0xa4, 0xfc, 0x64, 0x5e, 0x7d, 0x6f, 0x8c, 0x03, + 0xc6, 0xa7, 0xef, 0x6c, 0xf8, 0x9b, 0x89, 0x1f, 0x64, 0x83, 0xbf, 0x99, + 0x08, 0xbf, 0xfd, 0x56, 0x83, 0x3c, 0xe2, 0xe1, 0x9a, 0x29, 0x13, 0xb5, + 0xe8, 0x6f, 0x28, 0x28, 0x07, 0xf8, 0xe6, 0x5a, 0x94, 0x3b, 0xf8, 0x41, + 0x4d, 0xb3, 0x49, 0x96, 0x4b, 0x61, 0x4e, 0xc4, 0x1a, 0x80, 0x3c, 0xc4, + 0x78, 0x31, 0xaa, 0x2f, 0x07, 0x20, 0x3f, 0xf0, 0x1c, 0x74, 0xbd, 0x3b, + 0x1b, 0xd4, 0xb9, 0x25, 0xfa, 0xc5, 0xfe, 0xa8, 0xee, 0xdd, 0x25, 0xa5, + 0x63, 0x7c, 0x1f, 0x93, 0x77, 0x66, 0x63, 0xea, 0x7d, 0x41, 0x62, 0xe1, + 0x7b, 0x8e, 0xe3, 0x52, 0x50, 0xef, 0xab, 0x21, 0x3e, 0xd4, 0x69, 0x5f, + 0x89, 0xc6, 0xa6, 0x76, 0xbc, 0x1e, 0xac, 0x9b, 0xac, 0x57, 0xe5, 0xf1, + 0xfa, 0x2a, 0xce, 0xaf, 0x49, 0x6e, 0xbc, 0x28, 0xbb, 0x6d, 0x4b, 0xc5, + 0x7d, 0x37, 0x4e, 0x1d, 0xa3, 0x7e, 0x8d, 0xa9, 0xba, 0xb3, 0x88, 0x7c, + 0xa1, 0x30, 0xc2, 0x6f, 0x3c, 0xbf, 0xba, 0xab, 0x50, 0x4e, 0x5b, 0x59, + 0xf9, 0xd0, 0x77, 0x4d, 0x8e, 0x45, 0x47, 0x3d, 0x74, 0xd7, 0xc3, 0xb5, + 0x0b, 0x77, 0x05, 0x67, 0xc5, 0xfb, 0x1a, 0x61, 0x0d, 0xf5, 0x6d, 0xf6, + 0x5f, 0x6f, 0x35, 0x65, 0xed, 0x56, 0xdf, 0xbf, 0xdf, 0xb1, 0xc4, 0x0d, + 0x6b, 0x57, 0x4b, 0xd5, 0xae, 0xed, 0x2a, 0x07, 0x71, 0x47, 0x52, 0x5a, + 0x1e, 0xf6, 0x7a, 0xc6, 0x43, 0x9d, 0xa3, 0xa7, 0x0f, 0xae, 0xea, 0x16, + 0x62, 0x6e, 0x3a, 0x35, 0x27, 0x6e, 0x2f, 0xbf, 0x37, 0xcf, 0x38, 0x84, + 0xd9, 0x19, 0xdc, 0x75, 0xdd, 0x34, 0xae, 0xfc, 0xac, 0x48, 0x18, 0x7b, + 0x6e, 0x6a, 0xb4, 0x89, 0xc6, 0xdc, 0x92, 0xb6, 0x20, 0x13, 0x26, 0x68, + 0x29, 0x95, 0xa3, 0x3c, 0x8d, 0x7f, 0x1b, 0xb0, 0x7a, 0xd7, 0xd3, 0xa0, + 0x73, 0x1a, 0x74, 0xf2, 0x1c, 0xd3, 0xb5, 0x48, 0xe7, 0xa2, 0x5a, 0x81, + 0x7d, 0xc4, 0x7c, 0x0f, 0x31, 0xdf, 0x43, 0xcc, 0xf7, 0x10, 0xf3, 0x3d, + 0xc4, 0x7c, 0x0f, 0x31, 0xdf, 0x43, 0xcc, 0xf7, 0x10, 0xf3, 0xbd, 0xf1, + 0x30, 0x4f, 0x7b, 0x62, 0x3d, 0x4f, 0x5b, 0xa9, 0xf3, 0x3b, 0x94, 0xa2, + 0xa5, 0x58, 0x94, 0x20, 0xcf, 0x15, 0x9d, 0x39, 0x4d, 0x94, 0xe7, 0x5e, + 0xfb, 0x9b, 0x48, 0xb0, 0x8e, 0x39, 0x1e, 0xd7, 0x15, 0x35, 0xdd, 0xe6, + 0xba, 0x20, 0xcf, 0x63, 0x6d, 0xb5, 0x79, 0x0d, 0xf2, 0xb5, 0x0c, 0xfd, + 0x19, 0xed, 0x22, 0x11, 0xd4, 0x8b, 0x99, 0xf3, 0xf7, 0xba, 0x88, 0xbf, + 0x85, 0x9a, 0x8a, 0xc1, 0xbc, 0x17, 0xbc, 0x97, 0x7f, 0xb7, 0x00, 0x39, + 0xf0, 0xdd, 0x7d, 0xac, 0x27, 0x0a, 0xb5, 0xa4, 0x14, 0x17, 0xa3, 0xfc, + 0x07, 0xeb, 0xbc, 0x7d, 0x5a, 0xbe, 0x42, 0xd9, 0xea, 0x32, 0x9d, 0x00, + 0x53, 0xec, 0xc6, 0xbc, 0xee, 0x4d, 0x55, 0x23, 0xad, 0xd4, 0x49, 0xcf, + 0x7e, 0xd0, 0x16, 0xdd, 0xe3, 0x8a, 0x18, 0xb3, 0x09, 0xd1, 0x67, 0x91, + 0xd3, 0xda, 0x43, 0xea, 0x6f, 0x1d, 0x7a, 0xb0, 0x8f, 0x3e, 0x3b, 0x10, + 0xfd, 0x2d, 0x06, 0xeb, 0xae, 0xec, 0xc6, 0xfd, 0x2b, 0xcf, 0x91, 0x80, + 0xbd, 0x7e, 0x69, 0x27, 0xce, 0x06, 0xb9, 0x5e, 0xde, 0xa1, 0xf2, 0x6e, + 0xf8, 0xce, 0xd3, 0x43, 0xe9, 0x3e, 0xe9, 0xda, 0x25, 0x67, 0x86, 0x58, + 0xa3, 0xb5, 0x01, 0x1f, 0x61, 0x79, 0xe7, 0xb4, 0x4b, 0x96, 0xe7, 0xe1, + 0x5b, 0xe7, 0xd3, 0x0e, 0xff, 0xbe, 0x60, 0x01, 0x21, 0x6d, 0xa1, 0x3e, + 0xd6, 0xc7, 0x98, 0xbc, 0x58, 0xa7, 0xae, 0xf4, 0x60, 0x7d, 0x3f, 0x74, + 0x71, 0x1b, 0x6c, 0x48, 0xc7, 0xfe, 0x11, 0xee, 0xf7, 0x14, 0xee, 0x1e, + 0xfb, 0xb7, 0x77, 0x2a, 0xdd, 0xd0, 0xd3, 0x56, 0x4a, 0x07, 0xed, 0x1f, + 0xab, 0x2d, 0x1d, 0xe1, 0xf7, 0xc2, 0x69, 0xaf, 0xf1, 0xbb, 0xe1, 0x3e, + 0xad, 0x50, 0xe1, 0xdf, 0x38, 0x0c, 0xc9, 0x21, 0x8b, 0x7f, 0xff, 0xb3, + 0x4f, 0x7b, 0xa0, 0x4a, 0x18, 0x1b, 0x7d, 0xd6, 0xe1, 0xcb, 0xb0, 0xe5, + 0xff, 0x29, 0xdc, 0xea, 0x62, 0xdb, 0x3a, 0xcb, 0xf0, 0xfb, 0x1d, 0xe7, + 0xc7, 0x4d, 0xdd, 0xe4, 0x34, 0x71, 0x12, 0x27, 0xca, 0xc0, 0xc7, 0x39, + 0x49, 0x3d, 0x39, 0xd5, 0x4e, 0xa2, 0x14, 0x22, 0x88, 0x84, 0xe5, 0xfc, + 0xcc, 0x63, 0x14, 0x3c, 0xc8, 0xa6, 0x4e, 0x42, 0x55, 0x94, 0x74, 0x5b, + 0x27, 0xee, 0xb8, 0x40, 0x5c, 0x80, 0x6a, 0x39, 0x69, 0xe9, 0x86, 0x3d, + 0xa7, 0x5b, 0xba, 0x00, 0x57, 0x9e, 0xe3, 0xa4, 0x4d, 0xe7, 0xcc, 0x1a, + 0x03, 0x69, 0x70, 0x41, 0x23, 0x33, 0x6d, 0xe3, 0x66, 0x37, 0x48, 0x5c, + 0x57, 0x29, 0x83, 0x02, 0x6b, 0x2b, 0xb8, 0xe1, 0xef, 0xe2, 0xf0, 0x3c, + 0xdf, 0x39, 0x76, 0xd3, 0xc0, 0x44, 0x24, 0xeb, 0x7c, 0xe7, 0x3b, 0xdf, + 0xff, 0xf7, 0xbe, 0xcf, 0xfb, 0x9b, 0x6e, 0xb9, 0x08, 0x3a, 0xce, 0x8d, + 0xb5, 0xfa, 0xfe, 0xd6, 0x0e, 0x9f, 0x87, 0x07, 0xfb, 0x7c, 0x19, 0xa5, + 0x75, 0xc9, 0x9c, 0xd6, 0xa7, 0xbb, 0x0e, 0x7d, 0x7b, 0x16, 0x6b, 0x8a, + 0xe0, 0x1c, 0x1e, 0xe9, 0xd3, 0x78, 0x64, 0xf0, 0xbd, 0xff, 0xd0, 0x7b, + 0xdf, 0xa1, 0xf7, 0xde, 0xff, 0xd1, 0x9e, 0xe5, 0xc3, 0xf4, 0xc0, 0x75, + 0x5a, 0x53, 0x1a, 0xfd, 0xf2, 0x93, 0x6a, 0x39, 0x6f, 0x25, 0xa9, 0x0b, + 0xcc, 0x88, 0xab, 0x66, 0x9c, 0x36, 0x60, 0x5c, 0x9b, 0xac, 0xae, 0x83, + 0xe6, 0xb1, 0x8f, 0x76, 0x9b, 0xf1, 0xf2, 0x89, 0x3e, 0xf2, 0x4c, 0x10, + 0xd7, 0x60, 0xd8, 0xc3, 0x11, 0xb4, 0x73, 0x5f, 0x74, 0x12, 0xe6, 0x39, + 0xed, 0xbf, 0xa1, 0x0e, 0xe3, 0xaa, 0x9c, 0xce, 0xfd, 0x60, 0x9b, 0x16, + 0xb9, 0x6d, 0xa7, 0xba, 0xfd, 0xdc, 0x20, 0xd8, 0xbb, 0xa9, 0x3e, 0xea, + 0x17, 0x2f, 0x38, 0xcd, 0x3a, 0x73, 0x5f, 0x98, 0x77, 0x05, 0xa2, 0x79, + 0x4a, 0xa4, 0x54, 0x11, 0xb9, 0x86, 0xdf, 0x6f, 0x2a, 0x7e, 0xfc, 0x42, + 0xd1, 0xd6, 0x9e, 0x96, 0x1b, 0xc5, 0x2f, 0x48, 0x15, 0x32, 0x67, 0xc7, + 0x71, 0xdd, 0x3b, 0x4e, 0x54, 0x9f, 0xf9, 0x0f, 0xf2, 0x4a, 0x62, 0xe3, + 0x94, 0x69, 0x6d, 0xf2, 0xc3, 0x75, 0xe6, 0xd5, 0x59, 0xe6, 0x1d, 0x61, + 0x7e, 0x5b, 0x44, 0xd2, 0xe1, 0x80, 0xd6, 0x4b, 0xe5, 0x69, 0x68, 0x12, + 0xf8, 0xf6, 0x87, 0xf5, 0xb3, 0x7d, 0xf4, 0xb9, 0x7c, 0xbc, 0xce, 0x77, + 0x03, 0x4f, 0x43, 0xea, 0x76, 0x00, 0xfa, 0x2b, 0x80, 0xc7, 0xe4, 0xb9, + 0x73, 0xbf, 0xcf, 0x73, 0x6d, 0xa8, 0xa3, 0x0d, 0xdb, 0x26, 0xb9, 0x11, + 0xe0, 0xa0, 0x1a, 0xd6, 0xf9, 0x47, 0xf5, 0xb0, 0xc6, 0xe5, 0x40, 0x99, + 0x7e, 0x7b, 0xf3, 0xa8, 0xc6, 0xe8, 0xd4, 0xee, 0xf7, 0xf4, 0x5e, 0x50, + 0xce, 0x96, 0x1d, 0xd2, 0xaa, 0x29, 0x3b, 0xe0, 0xb5, 0xeb, 0xb5, 0x37, + 0xfa, 0x79, 0x57, 0x37, 0x6a, 0xdf, 0xef, 0xf3, 0x6c, 0x34, 0xd6, 0x5d, + 0xe8, 0xf3, 0xea, 0xa2, 0xbe, 0xcd, 0x45, 0xdb, 0xac, 0x84, 0xbd, 0x7d, + 0x5b, 0x6a, 0x1b, 0xdf, 0x95, 0x77, 0x8b, 0xdf, 0x91, 0x5f, 0x6c, 0x9c, + 0x81, 0xce, 0x61, 0x95, 0xb2, 0x90, 0x27, 0x6f, 0xd7, 0x5c, 0xf7, 0x6d, + 0x67, 0x01, 0xf6, 0x81, 0xeb, 0xfe, 0xd6, 0xd9, 0x93, 0xd8, 0xc4, 0x37, + 0xb1, 0xe7, 0x0c, 0x78, 0x88, 0x58, 0x98, 0x06, 0xbd, 0x7d, 0xb1, 0x5f, + 0x3a, 0x42, 0x9a, 0x4e, 0x86, 0x27, 0x5a, 0xb1, 0x07, 0xc3, 0xd7, 0xc3, + 0xb9, 0x97, 0xe9, 0x7e, 0xd2, 0x8c, 0x51, 0xfb, 0x09, 0xe6, 0x6f, 0x05, + 0x5f, 0x1c, 0xc5, 0x4f, 0xc9, 0x9d, 0x71, 0xac, 0x75, 0x9c, 0xb4, 0xd7, + 0x2a, 0xb1, 0xc7, 0xb0, 0x8f, 0x4c, 0x8b, 0xdc, 0xcb, 0x6f, 0xf6, 0xd1, + 0x9f, 0x77, 0x2f, 0xcf, 0xb2, 0xf1, 0xb9, 0x4e, 0x71, 0xa5, 0x05, 0xf2, + 0x7b, 0x75, 0xd2, 0xd3, 0x95, 0x7e, 0xad, 0x4e, 0xa0, 0xbd, 0x9d, 0x7d, + 0x4f, 0x51, 0xb7, 0xcb, 0xba, 0xad, 0xd0, 0xc5, 0xe7, 0xa0, 0x03, 0xa5, + 0x6a, 0x17, 0xa4, 0x3e, 0x1e, 0x42, 0x1b, 0xea, 0x28, 0x1a, 0x4b, 0x64, + 0x26, 0xcf, 0x7c, 0x2d, 0xe6, 0x4e, 0x61, 0x8d, 0x0b, 0xc4, 0x0d, 0xae, + 0xb1, 0x8d, 0x31, 0x38, 0xbf, 0xce, 0x06, 0x8d, 0xb0, 0x8e, 0xf4, 0x9d, + 0x04, 0x4f, 0x26, 0x29, 0x37, 0x31, 0xde, 0x18, 0xc6, 0x63, 0xb9, 0x13, + 0xe3, 0x5d, 0x90, 0x94, 0xd3, 0x18, 0x73, 0x0a, 0x6d, 0x88, 0x33, 0x53, + 0xd0, 0x1f, 0x86, 0xd4, 0xec, 0x7a, 0x18, 0xf2, 0xbb, 0x4f, 0x66, 0xcd, + 0x23, 0x07, 0xf6, 0x98, 0xd5, 0xf6, 0x81, 0x61, 0x8c, 0xf9, 0x6b, 0xea, + 0x3c, 0xb0, 0x26, 0xf6, 0xc7, 0x0f, 0xb6, 0x71, 0x6a, 0x7d, 0x0d, 0x38, + 0xb5, 0xf6, 0x61, 0xca, 0x39, 0x2b, 0x33, 0x61, 0xae, 0x89, 0xf5, 0x61, + 0xac, 0x99, 0x7e, 0xac, 0x67, 0x81, 0x43, 0x47, 0xfc, 0x3a, 0xb6, 0x15, + 0x23, 0x85, 0xb3, 0xf7, 0xec, 0x5a, 0xd6, 0x7d, 0x56, 0x52, 0x6b, 0x19, + 0x99, 0xd7, 0xfd, 0x78, 0x86, 0x83, 0x5a, 0xf7, 0x20, 0xaf, 0xc6, 0x7a, + 0x70, 0x96, 0x89, 0x07, 0x36, 0x70, 0xb4, 0x47, 0xcb, 0xcc, 0x7e, 0x8f, + 0x67, 0xf1, 0xad, 0x87, 0x77, 0xd4, 0x26, 0xb1, 0x6f, 0x40, 0x46, 0xe6, + 0x1b, 0xf5, 0x21, 0xf9, 0x24, 0xdf, 0xd1, 0xcf, 0x38, 0xcb, 0xdd, 0xbc, + 0x29, 0x1f, 0xe7, 0x75, 0x2c, 0x74, 0x31, 0x20, 0xd6, 0x79, 0xcf, 0x3e, + 0x1f, 0x59, 0x5c, 0x55, 0xfc, 0x3e, 0x72, 0x7e, 0x4b, 0x05, 0xd1, 0x36, + 0x84, 0x76, 0x5c, 0x87, 0x29, 0x73, 0xf9, 0xbf, 0xb9, 0x4b, 0xa3, 0xae, + 0x3b, 0xaf, 0xf3, 0xc3, 0x12, 0xe6, 0xaa, 0x6a, 0xe8, 0xe4, 0x71, 0xc9, + 0x87, 0xdb, 0x31, 0x57, 0xc2, 0xdc, 0x52, 0x23, 0x58, 0x0f, 0xcb, 0x3d, + 0xe4, 0x89, 0xc8, 0x9e, 0x70, 0x7c, 0x2b, 0xbd, 0xa9, 0x12, 0xd1, 0x61, + 0x65, 0x25, 0x73, 0xf8, 0xb5, 0x28, 0x1d, 0x47, 0x8c, 0x44, 0x15, 0x78, + 0x17, 0x7b, 0xb2, 0x4f, 0xba, 0x6e, 0xda, 0x66, 0x7d, 0xc2, 0x0c, 0x29, + 0xfa, 0x5b, 0x3a, 0x74, 0xbc, 0xf1, 0x72, 0x6f, 0xc2, 0x3c, 0xa9, 0x8e, + 0xfb, 0xef, 0x53, 0xc0, 0xcc, 0xe6, 0x78, 0x67, 0x36, 0x95, 0x29, 0x2f, + 0xe5, 0x13, 0xd1, 0x65, 0x65, 0x65, 0x30, 0x66, 0x66, 0x56, 0x11, 0x37, + 0x12, 0x66, 0x87, 0xa2, 0x4f, 0xb4, 0x5d, 0xef, 0x3b, 0x8d, 0xfe, 0x09, + 0xd5, 0xe2, 0xaf, 0x87, 0xf7, 0xf5, 0xe3, 0x7e, 0x8f, 0x67, 0x88, 0x39, + 0xa3, 0xc0, 0x4c, 0xe6, 0x9a, 0xe9, 0xdc, 0x86, 0x64, 0x6c, 0x62, 0x54, + 0x63, 0xe8, 0xfd, 0x53, 0x7f, 0x47, 0x1d, 0xca, 0x25, 0xd6, 0xc5, 0x7d, + 0x7e, 0x1b, 0xd5, 0x3a, 0xf3, 0xfd, 0x53, 0x59, 0x9d, 0xc7, 0x58, 0x57, + 0x31, 0x7f, 0xdf, 0xcd, 0x3b, 0x8b, 0xa6, 0x9c, 0x47, 0x38, 0xce, 0x5a, + 0x60, 0xba, 0x5d, 0x98, 0x23, 0x3a, 0x57, 0x6c, 0xd0, 0x06, 0xfd, 0x01, + 0xcc, 0x17, 0x68, 0xc4, 0xbd, 0x2f, 0x88, 0x31, 0x11, 0x3c, 0x40, 0x27, + 0xd0, 0x35, 0xa1, 0xa3, 0x56, 0x30, 0x4e, 0x6e, 0x5d, 0xb2, 0x5e, 0x7f, + 0x09, 0x32, 0x27, 0x35, 0x57, 0xf9, 0xb4, 0x31, 0x38, 0x37, 0xe6, 0xc0, + 0xfb, 0xfd, 0x53, 0xa4, 0x4f, 0x9e, 0x4d, 0x54, 0xcd, 0x6d, 0x70, 0x3d, + 0x83, 0x32, 0xbf, 0x3e, 0x24, 0xcb, 0xf8, 0xad, 0xae, 0x7b, 0xf7, 0xb6, + 0x0d, 0xdd, 0x7a, 0x3e, 0x6f, 0x6a, 0x7e, 0x5d, 0x76, 0x18, 0x33, 0x01, + 0xaf, 0xe8, 0x9c, 0x2a, 0xf6, 0x65, 0x5e, 0xe1, 0x10, 0xe5, 0xa3, 0x53, + 0x87, 0x5c, 0xdd, 0xae, 0x51, 0x4f, 0x65, 0xbd, 0x35, 0x15, 0x0d, 0x74, + 0xc9, 0x2a, 0xf0, 0xae, 0x0c, 0xd9, 0x99, 0x7b, 0x25, 0x24, 0xcb, 0x79, + 0x1d, 0x4f, 0x8e, 0xfe, 0x5e, 0x39, 0x52, 0xad, 0x4d, 0xca, 0x6e, 0x2d, + 0xae, 0xbf, 0x51, 0xae, 0xe5, 0x5e, 0x37, 0xe4, 0xf9, 0x51, 0x9d, 0x57, + 0x17, 0x2f, 0x4b, 0xef, 0x00, 0x75, 0x9e, 0x2d, 0x9d, 0x63, 0x07, 0xec, + 0x80, 0xce, 0xf1, 0x33, 0xe8, 0x1c, 0xef, 0x40, 0xe7, 0xf8, 0x69, 0x11, + 0xf8, 0x52, 0x4c, 0xfb, 0xf8, 0xbf, 0x08, 0x1c, 0xa2, 0xac, 0xb6, 0xce, + 0xe0, 0x4e, 0x17, 0xb3, 0xa0, 0xc1, 0x5b, 0x92, 0x06, 0xde, 0xa6, 0xe4, + 0xfa, 0xc6, 0xbc, 0xec, 0x6c, 0x78, 0x79, 0xc8, 0x1f, 0x30, 0x07, 0x6c, + 0x9c, 0xf7, 0x14, 0x07, 0x0e, 0x1d, 0x91, 0xd8, 0x49, 0xe2, 0x47, 0x50, + 0x36, 0x0b, 0xef, 0x68, 0x1c, 0xda, 0x2c, 0xb0, 0x1c, 0x10, 0x9d, 0x4f, + 0xb6, 0xb0, 0x27, 0x65, 0xe7, 0x97, 0xa8, 0x3f, 0xa6, 0x7d, 0x40, 0x9e, + 0x4f, 0x9e, 0x78, 0xf9, 0x67, 0xff, 0xee, 0x95, 0xce, 0xb3, 0x5b, 0x32, + 0xbb, 0xd0, 0xae, 0x81, 0x5d, 0xc3, 0x5e, 0xcc, 0x5b, 0xfd, 0x05, 0x6d, + 0x30, 0x47, 0xb1, 0x4b, 0xb6, 0x21, 0x43, 0xea, 0xf1, 0x2e, 0xad, 0xfb, + 0xd5, 0xe3, 0x43, 0x3a, 0x17, 0x97, 0xe3, 0xe4, 0x0a, 0xb6, 0xac, 0x14, + 0xac, 0x68, 0x16, 0xf4, 0xb7, 0x0b, 0x5b, 0xed, 0x3a, 0xee, 0x60, 0x07, + 0x67, 0x70, 0xa3, 0x46, 0x39, 0x7f, 0x57, 0x63, 0xef, 0x66, 0xed, 0x4f, + 0x18, 0xc7, 0x3a, 0x93, 0x94, 0x3f, 0xf6, 0x13, 0x03, 0xe9, 0x8f, 0x9a, + 0xd1, 0xfd, 0xbd, 0x7e, 0xd7, 0xd1, 0x76, 0xa7, 0x46, 0x3c, 0x16, 0xb9, + 0x94, 0xb7, 0x21, 0x4b, 0x5e, 0x8f, 0x50, 0x07, 0x28, 0xa9, 0x46, 0x3f, + 0xd7, 0x5f, 0xb3, 0xeb, 0x1e, 0xb5, 0xb9, 0xae, 0xb8, 0x8f, 0xdb, 0x94, + 0xfd, 0x7b, 0x5a, 0xee, 0xe7, 0x8b, 0x67, 0xe5, 0x2d, 0xdc, 0xb7, 0xa7, + 0xe3, 0x64, 0xe4, 0x4d, 0xe8, 0x78, 0xb5, 0x62, 0x23, 0x6f, 0x7b, 0x1a, + 0xe7, 0x64, 0xa9, 0x95, 0x2b, 0x2f, 0xcb, 0xe5, 0xab, 0xfb, 0xea, 0xa5, + 0xab, 0x31, 0xf5, 0xf2, 0x95, 0x61, 0x95, 0xbb, 0xe2, 0xba, 0xff, 0x74, + 0x96, 0xe4, 0xdd, 0x0d, 0x57, 0x4e, 0x3b, 0xc6, 0x40, 0x40, 0x1a, 0xb9, + 0x75, 0xae, 0x1b, 0x04, 0x36, 0xdf, 0xe8, 0x75, 0xdd, 0x47, 0xc7, 0xc7, + 0x25, 0xde, 0x4b, 0x1d, 0xe5, 0xf3, 0x11, 0xe6, 0xbb, 0x12, 0x73, 0x52, + 0xb6, 0x7d, 0xbe, 0xac, 0x14, 0xf0, 0xad, 0xcb, 0xd3, 0x5f, 0x1e, 0x3b, + 0xe6, 0xc7, 0x4a, 0x7e, 0xf4, 0x22, 0x7d, 0xc9, 0x91, 0xff, 0xf2, 0x25, + 0x9b, 0x72, 0xae, 0xf0, 0x19, 0xf4, 0x0f, 0xcb, 0xb7, 0x0a, 0xa1, 0x43, + 0x65, 0x13, 0xcf, 0x31, 0x95, 0x2b, 0xdc, 0x73, 0x87, 0x75, 0xcc, 0x00, + 0x3a, 0x89, 0xe9, 0xba, 0xcb, 0x0e, 0xe7, 0xeb, 0xc2, 0x7c, 0x7b, 0xe6, + 0x31, 0xc8, 0xff, 0xd3, 0x5a, 0x3e, 0x9f, 0x53, 0xb0, 0x7d, 0xc1, 0xdf, + 0x61, 0x99, 0x2d, 0x40, 0xc6, 0x2b, 0xe6, 0x9c, 0x52, 0x57, 0xb0, 0x22, + 0xcb, 0xc0, 0x8e, 0x25, 0xe0, 0xcd, 0x93, 0x3a, 0xb6, 0xda, 0xa3, 0xb1, + 0x67, 0x85, 0xe5, 0x8c, 0x24, 0xcb, 0x4e, 0xb7, 0x3e, 0xbf, 0xfd, 0xdd, + 0x57, 0x23, 0xde, 0x9d, 0x83, 0x8f, 0x33, 0x4a, 0xda, 0x60, 0x03, 0xcd, + 0x6c, 0x2d, 0x80, 0x27, 0x22, 0x38, 0xdb, 0x56, 0xcd, 0x0f, 0x75, 0xc8, + 0xef, 0xba, 0xf6, 0x23, 0x7a, 0xf1, 0x8a, 0xba, 0xc9, 0x76, 0xcf, 0xa0, + 0x5f, 0xbb, 0xa4, 0xae, 0xb4, 0x69, 0x5c, 0x7d, 0xb8, 0x2e, 0x09, 0x3d, + 0xe4, 0x69, 0x94, 0x03, 0xa8, 0x8b, 0xfa, 0x65, 0x03, 0xe5, 0x45, 0x94, + 0x5b, 0xf0, 0x64, 0x9b, 0x11, 0xe8, 0x15, 0x78, 0xbe, 0x81, 0xf1, 0xc6, + 0xb1, 0xe6, 0x8c, 0x29, 0x1f, 0x9d, 0xa2, 0x2c, 0x19, 0x53, 0xcc, 0x4b, + 0x5e, 0xb6, 0xf1, 0xac, 0x0e, 0xab, 0x99, 0x35, 0x96, 0xf1, 0x2c, 0x79, + 0xdf, 0x1f, 0xc2, 0x24, 0xf4, 0x49, 0x5d, 0xf5, 0x30, 0xe9, 0xa3, 0x26, + 0x26, 0xb1, 0xae, 0x5d, 0x66, 0xaf, 0x90, 0xd7, 0x4d, 0xd0, 0x5b, 0x87, + 0xcc, 0x5c, 0x0d, 0x6b, 0x7d, 0xb4, 0x0c, 0x5a, 0xdc, 0x06, 0x5d, 0x6d, + 0x82, 0xa6, 0x52, 0x05, 0x6b, 0x6a, 0x51, 0x45, 0xb5, 0x2f, 0xe0, 0x09, + 0xd0, 0x6b, 0xf0, 0x15, 0xea, 0xa2, 0xe4, 0xe5, 0x38, 0x68, 0x4f, 0xdc, + 0xa0, 0x6d, 0xa7, 0xe3, 0xca, 0x06, 0x0d, 0x82, 0x2e, 0x0b, 0x1e, 0x4f, + 0xbf, 0xa7, 0x34, 0xae, 0x4e, 0xdd, 0x96, 0x44, 0xf2, 0xb6, 0x58, 0xc0, + 0x02, 0xcb, 0xf9, 0x50, 0x1c, 0x8c, 0x39, 0x29, 0xd7, 0x30, 0x8f, 0x01, + 0xfe, 0x1e, 0x3d, 0xa1, 0xf9, 0x7b, 0x4a, 0x02, 0x87, 0x79, 0x1c, 0xf4, + 0x06, 0x0c, 0xf2, 0x78, 0x3a, 0xe9, 0xd3, 0xe8, 0xd7, 0xc1, 0xbf, 0x16, + 0x2c, 0xb1, 0xb0, 0xac, 0x82, 0xff, 0xb7, 0xf1, 0xfd, 0x66, 0x6d, 0x44, + 0xad, 0xac, 0x29, 0x3f, 0x97, 0xe4, 0x19, 0xe8, 0xc9, 0xb7, 0x70, 0x76, + 0x9d, 0x5a, 0x77, 0x8f, 0x8d, 0x33, 0x7e, 0x96, 0x56, 0x97, 0xed, 0x93, + 0xb2, 0x3f, 0x36, 0x89, 0xf2, 0x31, 0x3c, 0x0d, 0x9c, 0x43, 0x48, 0xc7, + 0xbf, 0x37, 0xf3, 0x8e, 0xf2, 0xfe, 0x67, 0x61, 0x42, 0xe7, 0xe7, 0x1b, + 0x76, 0x2f, 0xbe, 0xd3, 0x17, 0xc3, 0xbd, 0x41, 0x67, 0x52, 0x11, 0x9d, + 0x6f, 0x5a, 0x86, 0x2e, 0xb1, 0x85, 0xf1, 0xde, 0xa7, 0x2f, 0xaf, 0x0a, + 0x1e, 0x1e, 0xfb, 0x97, 0x9b, 0x0c, 0x33, 0x47, 0xfd, 0x6e, 0xc4, 0x93, + 0x7f, 0x9f, 0xb8, 0xfb, 0xf6, 0xca, 0x94, 0x81, 0x97, 0x5b, 0x66, 0x18, + 0x6d, 0x21, 0xcb, 0x20, 0x8b, 0x4a, 0x9a, 0x7e, 0xd9, 0xce, 0xeb, 0x9b, + 0xab, 0x26, 0xcc, 0x0f, 0xc4, 0xeb, 0xbb, 0x6a, 0x53, 0xee, 0xb4, 0x03, + 0x5f, 0xa2, 0x5a, 0xaf, 0x7c, 0xdf, 0xce, 0x02, 0x15, 0xac, 0x68, 0x1a, + 0x34, 0xda, 0x26, 0x56, 0x7c, 0x4e, 0x1e, 0xcc, 0xbb, 0xac, 0xfb, 0xb2, + 0x6d, 0xa3, 0x6f, 0x63, 0x5e, 0xae, 0x9f, 0x7b, 0xe1, 0x1e, 0xe8, 0x9b, + 0x36, 0x35, 0x8d, 0xd6, 0xab, 0xdd, 0x03, 0x1e, 0x8d, 0x36, 0xf6, 0x11, + 0xfe, 0x3f, 0xfb, 0x20, 0x9d, 0x38, 0xca, 0xcb, 0xbb, 0xc0, 0xb3, 0xca, + 0xf3, 0x1c, 0x01, 0x6d, 0x1c, 0xa4, 0x9f, 0x86, 0x6f, 0xd1, 0xa3, 0x9f, + 0x47, 0x9b, 0xf4, 0x43, 0xba, 0xe9, 0x90, 0xd9, 0xab, 0xb6, 0xcc, 0x17, + 0xf4, 0x7d, 0x43, 0xd7, 0xa4, 0xcf, 0x68, 0x12, 0x74, 0x43, 0x5a, 0x27, + 0x6f, 0x99, 0x52, 0x02, 0x1d, 0x95, 0x80, 0x4f, 0x25, 0xd0, 0x54, 0x19, + 0xf8, 0x56, 0x02, 0xbe, 0x95, 0x6a, 0x56, 0xbc, 0x82, 0x3d, 0x53, 0x66, + 0x6f, 0x81, 0x8e, 0xb6, 0x6b, 0xbc, 0x7f, 0xbd, 0x66, 0x93, 0x72, 0xf0, + 0x66, 0xf3, 0xee, 0xff, 0x81, 0xbb, 0x1f, 0x92, 0x5d, 0xd8, 0x2d, 0x6f, + 0x15, 0xc7, 0x80, 0x49, 0x02, 0x8c, 0x72, 0x40, 0x1b, 0x53, 0x72, 0xbd, + 0x38, 0x2d, 0x3b, 0x90, 0x4f, 0x37, 0x36, 0x62, 0xd0, 0xa7, 0x23, 0xb2, + 0xf2, 0xda, 0xa8, 0xbc, 0xb9, 0xa1, 0x64, 0x09, 0xf4, 0x9b, 0xdb, 0xa4, + 0xdf, 0x1d, 0xf4, 0x5c, 0xea, 0xd0, 0x71, 0xfa, 0xd9, 0x8a, 0xe7, 0x7f, + 0x9f, 0xab, 0x74, 0xca, 0x7c, 0xc5, 0x94, 0xc7, 0x2b, 0xdd, 0xf2, 0xe5, + 0x4a, 0x58, 0x4e, 0xc3, 0x0e, 0xfc, 0x4a, 0x65, 0x50, 0x9e, 0xac, 0x0c, + 0xc9, 0x57, 0xab, 0x51, 0xf9, 0x5a, 0xd5, 0x96, 0x4c, 0x35, 0x2e, 0xe9, + 0xea, 0x98, 0x3c, 0x51, 0xa5, 0x5f, 0x1d, 0xf3, 0xe1, 0x37, 0xd3, 0xf4, + 0x57, 0x70, 0x5d, 0x41, 0xac, 0x2b, 0xae, 0xe6, 0x74, 0x9c, 0x52, 0x32, + 0x9e, 0xcf, 0x43, 0xe4, 0x39, 0x8c, 0x75, 0xf1, 0x35, 0x25, 0x65, 0x3d, + 0x7f, 0xe3, 0xff, 0x46, 0x42, 0xda, 0x36, 0x7a, 0xae, 0x34, 0x88, 0x36, + 0x90, 0x7b, 0xf9, 0x86, 0xef, 0xa3, 0xe1, 0xf3, 0x6f, 0xd8, 0x5e, 0x86, + 0xf6, 0x5b, 0xdf, 0xa4, 0xed, 0xa5, 0xcf, 0x9e, 0xf8, 0x41, 0x3b, 0xe7, + 0x9a, 0xf6, 0x9b, 0x3c, 0x88, 0x6d, 0x34, 0xe6, 0xbd, 0x98, 0x79, 0xf8, + 0xff, 0x53, 0xbc, 0x18, 0xd5, 0xb9, 0xea, 0x20, 0xff, 0x4f, 0x05, 0x6b, + 0xf9, 0xf4, 0xdc, 0xf1, 0xf9, 0xe2, 0xac, 0x7a, 0xbc, 0x48, 0x8d, 0xc6, + 0x95, 0x8b, 0xcd, 0x9c, 0xb8, 0x2f, 0xc9, 0xa6, 0x13, 0xd2, 0x6b, 0xf0, + 0xf3, 0x1f, 0x75, 0x7e, 0xdc, 0xec, 0x09, 0xd2, 0x1f, 0x63, 0x6f, 0x9d, + 0x7e, 0x3c, 0x01, 0xba, 0xad, 0x63, 0xca, 0xa5, 0x8a, 0xe7, 0xb3, 0x5a, + 0xd1, 0xf4, 0xf2, 0x2b, 0xd0, 0x1c, 0x63, 0x0e, 0xde, 0x33, 0x5b, 0xf2, + 0xfa, 0xce, 0xe0, 0xde, 0x60, 0x8f, 0x63, 0xbf, 0x46, 0x37, 0xe7, 0xe2, + 0xff, 0xe9, 0xa0, 0xec, 0xaf, 0x97, 0xb9, 0xc6, 0xb6, 0xa6, 0x45, 0x2f, + 0xae, 0x1b, 0x97, 0x17, 0x70, 0x7e, 0x65, 0x93, 0xeb, 0x0f, 0x4a, 0x39, + 0x4e, 0xdb, 0x96, 0xf8, 0x7d, 0x42, 0x4a, 0x98, 0xa7, 0x1c, 0x6f, 0xf8, + 0xc3, 0x3c, 0x9c, 0x2d, 0x9b, 0x0f, 0xe6, 0x5d, 0x2c, 0x1d, 0xc7, 0x3b, + 0xea, 0xe2, 0xd0, 0x99, 0x16, 0xf8, 0x7e, 0x11, 0x65, 0xfa, 0x46, 0x56, + 0xf0, 0x8c, 0xf8, 0x75, 0xd5, 0x01, 0xad, 0xab, 0x4f, 0x3f, 0xe8, 0xb7, + 0x54, 0xb2, 0xb2, 0xa9, 0x40, 0x42, 0x19, 0xaf, 0xfe, 0x7c, 0x80, 0x98, + 0x7b, 0xdc, 0xe6, 0x2f, 0x24, 0x7f, 0x35, 0xb5, 0x4f, 0xc1, 0xff, 0x76, + 0x44, 0x9e, 0x32, 0x99, 0xc7, 0x9e, 0x54, 0xb3, 0xc5, 0x9c, 0x9f, 0xe3, + 0x9b, 0x50, 0xc7, 0xcb, 0x37, 0x07, 0xbc, 0x9c, 0x77, 0x8e, 0x7d, 0x30, + 0xcf, 0xfd, 0x20, 0x9d, 0x30, 0xdf, 0xbd, 0xbd, 0xf9, 0x3f, 0x52, 0xe5, + 0x3c, 0xf0, 0xce, 0x6e, 0xd1, 0xfc, 0x98, 0xab, 0xfe, 0xdb, 0xdd, 0xd3, + 0xfc, 0xdc, 0xf0, 0x31, 0xfc, 0x6e, 0x80, 0xb6, 0x2d, 0x71, 0xe3, 0x92, + 0x97, 0x3b, 0xaa, 0x6d, 0x68, 0x60, 0x05, 0xea, 0xc8, 0xab, 0xe0, 0x93, + 0x66, 0x5b, 0xfe, 0xfd, 0x07, 0x69, 0x3f, 0x51, 0x42, 0x6c, 0x67, 0x00, + 0x00, 0x00 }; static const u32 bnx2_RXP_b09FwData[(0x0/4) + 1] = { 0x0 }; static const u32 bnx2_RXP_b09FwRodata[(0x278/4) + 1] = { - 0x08004070, 0x08003f70, 0x08004014, 0x0800402c, 0x08004044, 0x08004064, - 0x08004070, 0x08004070, 0x08003f78, 0x00000000, 0x08004a2c, 0x08004a64, - 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004a9c, 0x08004c60, - 0x08004ba8, 0x08004be0, 0x08004c60, 0x08004b30, 0x08004c60, 0x08004c60, - 0x08004be0, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, - 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c20, - 0x08004c60, 0x08004c20, 0x08004ba8, 0x08004c60, 0x08004c60, 0x08004c20, - 0x08004c20, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, - 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, - 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, - 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, - 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, - 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, - 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, - 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, - 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, - 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, - 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, - 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, - 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, - 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, - 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, - 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, 0x08004c60, - 0x08004b0c, 0x00000000, 0x08006078, 0x08006090, 0x08006090, 0x08006090, - 0x08006078, 0x08006090, 0x08006090, 0x08006090, 0x08006078, 0x08006090, - 0x08006090, 0x08006090, 0x08006078, 0x08006090, 0x08006090, 0x08006090, - 0x08006084, 0x00000000, 0x00000000 }; + 0x08004050, 0x08003f50, 0x08003ff4, 0x0800400c, 0x08004024, 0x08004044, + 0x08004050, 0x08004050, 0x08003f58, 0x00000000, 0x08004a0c, 0x08004a44, + 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004a7c, 0x08004c40, + 0x08004b88, 0x08004bc0, 0x08004c40, 0x08004b10, 0x08004c40, 0x08004c40, + 0x08004bc0, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, + 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c00, + 0x08004c40, 0x08004c00, 0x08004b88, 0x08004c40, 0x08004c40, 0x08004c00, + 0x08004c00, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, + 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, + 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, + 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, + 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, + 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, + 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, + 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, + 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, + 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, + 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, + 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, + 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, + 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, + 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, + 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, 0x08004c40, + 0x08004aec, 0x00000000, 0x08006058, 0x08006070, 0x08006070, 0x08006070, + 0x08006058, 0x08006070, 0x08006070, 0x08006070, 0x08006058, 0x08006070, + 0x08006070, 0x08006070, 0x08006058, 0x08006070, 0x08006070, 0x08006070, + 0x08006064, 0x00000000, 0x00000000 }; static struct fw_info bnx2_rxp_fw_09 = { - /* Firmware version: 3.7.1 */ .ver_major = 0x3, - .ver_minor = 0x7, - .ver_fix = 0x1, + .ver_minor = 0x4, + .ver_fix = 0x3, .start_addr = 0x08003184, .text_addr = 0x08000000, - .text_len = 0x6788, + .text_len = 0x6768, .text_index = 0x0, .gz_text = bnx2_RXP_b09FwText, .gz_text_len = sizeof(bnx2_RXP_b09FwText), - .data_addr = 0x08006a20, + .data_addr = 0x08006a00, .data_len = 0x0, .data_index = 0x0, .data = bnx2_RXP_b09FwData, - .sbss_addr = 0x08006a20, + .sbss_addr = 0x08006a00, .sbss_len = 0x20, .sbss_index = 0x0, - .bss_addr = 0x08006a40, + .bss_addr = 0x08006a20, .bss_len = 0x13dc, .bss_index = 0x0, - .rodata_addr = 0x08006788, + .rodata_addr = 0x08006768, .rodata_len = 0x278, .rodata_index = 0x0, .rodata = bnx2_RXP_b09FwRodata, }; static u8 bnx2_TPAT_b09FwText[] = { - 0xcd, 0x58, 0x5d, 0x6c, 0x1c, 0x57, 0x15, 0x3e, 0xf3, 0xb7, 0x3b, 0xde, - 0x38, 0xf1, 0x24, 0x19, 0xca, 0xa6, 0x72, 0xe9, 0x8c, 0x3d, 0x76, 0x8c, - 0x6c, 0x35, 0xd3, 0x76, 0xd5, 0x58, 0x68, 0xa4, 0x4e, 0x67, 0x76, 0x1d, - 0x2b, 0xf4, 0xc1, 0x85, 0x48, 0x3c, 0xf0, 0xe2, 0xae, 0x1d, 0x05, 0x78, - 0x2a, 0x28, 0x0f, 0x11, 0x2f, 0x59, 0x76, 0x37, 0xfd, 0x41, 0xdb, 0x2c, - 0x35, 0xc8, 0x41, 0x02, 0xa4, 0xb0, 0x69, 0xe2, 0x97, 0xad, 0x27, 0x2d, - 0x45, 0xea, 0x4b, 0x95, 0x28, 0x55, 0x2b, 0xc4, 0x13, 0x2f, 0x54, 0x79, - 0xac, 0x52, 0x5a, 0xf1, 0x00, 0x28, 0x42, 0x15, 0xaa, 0x68, 0xf0, 0xe5, - 0x3b, 0x77, 0x66, 0xdc, 0xdd, 0xc4, 0x49, 0xcb, 0x9f, 0x84, 0xa5, 0xf5, - 0x9d, 0xb9, 0xf7, 0x9e, 0x73, 0xcf, 0x3d, 0x3f, 0xdf, 0x39, 0x67, 0xca, - 0x2a, 0x95, 0x28, 0xfb, 0xdb, 0x8d, 0xdf, 0xc9, 0xa7, 0x9f, 0x39, 0x79, - 0xf8, 0xa1, 0x47, 0x1d, 0xa2, 0x87, 0x1f, 0x52, 0x94, 0xa2, 0x46, 0xff, - 0x85, 0x3f, 0x30, 0xb1, 0x72, 0xfe, 0xfc, 0x23, 0x53, 0x0d, 0x7e, 0xe3, - 0x44, 0x1e, 0x99, 0x5a, 0xb0, 0xf4, 0xe5, 0x15, 0x8f, 0x28, 0xec, 0xcf, - 0x3a, 0x31, 0xfd, 0x43, 0x34, 0x6c, 0x9d, 0x78, 0xfe, 0x81, 0xe0, 0xd6, - 0xa1, 0x37, 0x0f, 0xbb, 0x37, 0xcf, 0x6b, 0x64, 0x5a, 0xc1, 0xb2, 0x69, - 0x4d, 0x93, 0x39, 0x1e, 0x5c, 0x75, 0x7e, 0x7e, 0x30, 0x28, 0xd0, 0x9e, - 0x9c, 0x97, 0x4d, 0xcd, 0x2e, 0x35, 0xf4, 0xc0, 0xa4, 0x5a, 0xe7, 0x94, - 0x12, 0x75, 0x3d, 0xab, 0x0a, 0x1e, 0xa1, 0x0d, 0xfe, 0x1e, 0xde, 0x13, - 0x5d, 0xa9, 0x9e, 0x33, 0x49, 0x0d, 0x42, 0x3c, 0xcf, 0x51, 0xab, 0x2b, - 0xc4, 0x0f, 0x7d, 0x85, 0x56, 0x7c, 0x93, 0x96, 0x2d, 0x77, 0x31, 0x54, - 0xb6, 0x44, 0x3c, 0x25, 0xc4, 0xb7, 0x7d, 0x95, 0x54, 0x6f, 0x41, 0x89, - 0x36, 0x16, 0x95, 0x78, 0x63, 0x91, 0xf5, 0x01, 0xf9, 0x16, 0x94, 0x70, - 0x83, 0xc7, 0xc0, 0x8c, 0x3b, 0x7b, 0x68, 0xd9, 0xa6, 0x31, 0xd5, 0x9b, - 0xc3, 0x79, 0x65, 0xf0, 0x71, 0x28, 0xf2, 0x67, 0x2d, 0x95, 0x26, 0xf1, - 0x1b, 0xa1, 0x9a, 0x4f, 0x23, 0xaa, 0xa7, 0x52, 0xdd, 0x56, 0xe8, 0xe5, - 0x8a, 0x81, 0xdf, 0x51, 0xa5, 0xba, 0xf1, 0x9d, 0x8c, 0x0f, 0xef, 0x37, - 0xb1, 0xc6, 0x32, 0x33, 0xfd, 0x20, 0xed, 0x6e, 0x3c, 0x7f, 0x0b, 0xfb, - 0x0c, 0x8a, 0x2a, 0xb7, 0xaf, 0x8d, 0xe0, 0x59, 0xc1, 0xfc, 0x51, 0xc8, - 0xc5, 0x7c, 0x1c, 0xc8, 0x31, 0x4e, 0xed, 0xee, 0x22, 0xee, 0x53, 0xa0, - 0x86, 0x35, 0x35, 0x53, 0x27, 0x1d, 0x34, 0x1a, 0x85, 0xf6, 0x15, 0xa1, - 0x06, 0x42, 0x44, 0x15, 0x6f, 0xa6, 0x27, 0xcf, 0x50, 0x49, 0xf3, 0x0a, - 0x54, 0xf5, 0x77, 0x53, 0xcb, 0xd2, 0xa8, 0x39, 0x67, 0x50, 0xb8, 0xa4, - 0xe3, 0x8e, 0xfb, 0x40, 0xa7, 0x80, 0xfe, 0xa5, 0xcc, 0xe6, 0x45, 0x6a, - 0x5a, 0x05, 0xcc, 0x8f, 0x51, 0xd3, 0xde, 0xab, 0xa8, 0xc1, 0x0b, 0x98, - 0x9f, 0xb2, 0x7a, 0xf4, 0x3c, 0x46, 0x05, 0xef, 0x7b, 0xb1, 0x97, 0xdf, - 0x15, 0xf0, 0x23, 0x2b, 0x4a, 0x66, 0xa8, 0x95, 0xe4, 0xb4, 0x3c, 0x9f, - 0xce, 0x35, 0x92, 0xdb, 0xed, 0x8d, 0x7d, 0xdd, 0x1a, 0x74, 0xcc, 0xb6, - 0xc1, 0x9e, 0xdc, 0x2e, 0xd2, 0x07, 0x1e, 0xe7, 0x79, 0xfe, 0xc3, 0xbc, - 0x43, 0x5a, 0xe0, 0x59, 0x31, 0x7d, 0x85, 0xd2, 0xb5, 0x54, 0xf6, 0xc8, - 0x7f, 0x2c, 0x7b, 0xb7, 0xad, 0xe8, 0xdc, 0xa3, 0xb8, 0x9f, 0x74, 0x19, - 0x3c, 0xdb, 0xb8, 0x7f, 0x01, 0xfe, 0xd1, 0x0c, 0x55, 0x6a, 0x94, 0x4d, - 0x72, 0xe7, 0x57, 0xb1, 0xf2, 0x41, 0x47, 0xa3, 0x98, 0x75, 0xe5, 0xeb, - 0x19, 0x1d, 0xfb, 0xc6, 0xbb, 0x90, 0xb3, 0x61, 0x99, 0x70, 0xbc, 0xe5, - 0x63, 0x42, 0x5c, 0xf4, 0x85, 0x28, 0x04, 0xde, 0xcc, 0x25, 0x9a, 0x2d, - 0x1b, 0x34, 0x6d, 0x61, 0x84, 0x8e, 0xbd, 0x72, 0x9d, 0x8c, 0x5c, 0x9e, - 0xdc, 0x37, 0xf1, 0xd7, 0x57, 0x08, 0x3e, 0x79, 0xa3, 0xf3, 0x7b, 0xd6, - 0xc7, 0xcc, 0x82, 0xa4, 0x11, 0xa2, 0x37, 0x7f, 0x2f, 0x9a, 0x5f, 0x67, - 0x34, 0x42, 0xd4, 0x2a, 0x7c, 0xae, 0x8b, 0x3b, 0xb3, 0x7f, 0x13, 0xd5, - 0xfa, 0xbe, 0x59, 0xef, 0x40, 0x3e, 0x0f, 0x63, 0x9f, 0xa8, 0xde, 0xe5, - 0x7b, 0x98, 0xd4, 0x84, 0xde, 0x5a, 0xd8, 0xaf, 0x56, 0x76, 0xb1, 0x7f, - 0xc0, 0xc6, 0x4b, 0x66, 0xb5, 0xe3, 0x96, 0x5f, 0xa0, 0x25, 0x33, 0xee, - 0xcf, 0x96, 0x57, 0xe9, 0x01, 0x3e, 0xc7, 0x34, 0x82, 0x63, 0x66, 0x4f, - 0xd2, 0x1b, 0x1a, 0x95, 0xf0, 0x0c, 0x1e, 0xcd, 0x0e, 0x29, 0x91, 0xbf, - 0x8b, 0xef, 0x0b, 0xba, 0xc5, 0x8c, 0x6e, 0x31, 0xa3, 0x1b, 0xcb, 0xe8, - 0x9e, 0x1c, 0xa0, 0x7b, 0x92, 0xe9, 0xb0, 0x37, 0xcc, 0xf6, 0x86, 0xd9, - 0x5e, 0x3d, 0xdb, 0x5b, 0xcd, 0xf6, 0x62, 0xec, 0x3b, 0x90, 0xcf, 0x9d, - 0x09, 0x15, 0xc8, 0xe8, 0x89, 0x07, 0x23, 0x9f, 0xc2, 0xd8, 0x73, 0xaf, - 0xc7, 0xda, 0x18, 0x5d, 0xf0, 0x2d, 0x6a, 0x27, 0x0e, 0x64, 0x6f, 0x53, - 0x94, 0xa8, 0xa0, 0x1d, 0xa3, 0x9e, 0x77, 0x53, 0xd4, 0xfc, 0x0a, 0x6c, - 0x37, 0xca, 0x74, 0xe5, 0x1a, 0x14, 0xd1, 0x4c, 0x66, 0xad, 0x55, 0xaa, - 0xc0, 0x5f, 0x54, 0xd8, 0x6f, 0x52, 0x3e, 0x37, 0x93, 0x0a, 0xd6, 0xa9, - 0xa1, 0x56, 0x5c, 0xab, 0x49, 0x6e, 0x39, 0xd2, 0xc8, 0x52, 0x03, 0x1b, - 0x7b, 0x1a, 0x54, 0x4d, 0x4c, 0x7a, 0x4f, 0x3b, 0x25, 0xe3, 0xb4, 0xd9, - 0xbd, 0x2e, 0xde, 0x3c, 0xe8, 0xd0, 0x95, 0x64, 0x9c, 0x7e, 0x95, 0x94, - 0xe9, 0xb5, 0xc4, 0xa6, 0x57, 0x13, 0x52, 0x23, 0x1f, 0x7e, 0x6c, 0x5b, - 0x74, 0x39, 0x19, 0xd4, 0xfb, 0x07, 0xac, 0x77, 0x73, 0x7f, 0x40, 0xe6, - 0xbe, 0x80, 0x1a, 0x5a, 0x90, 0xe2, 0x40, 0x9c, 0xe2, 0x80, 0xf4, 0xa9, - 0x56, 0xb7, 0x79, 0xbf, 0x06, 0x0c, 0x5a, 0xf1, 0xc3, 0xbd, 0x1a, 0xec, - 0x12, 0x23, 0x0a, 0xd4, 0xed, 0x51, 0xda, 0xc8, 0x5d, 0xf1, 0xdc, 0xe7, - 0x63, 0xec, 0xf6, 0xce, 0x1a, 0x98, 0xbd, 0xdd, 0xb6, 0x7f, 0xc6, 0x19, - 0xa3, 0xb0, 0x9b, 0x46, 0x4f, 0xe8, 0x88, 0x1f, 0xef, 0x23, 0x8d, 0x63, - 0xc0, 0xd9, 0xb4, 0xe9, 0x4c, 0x97, 0x68, 0x62, 0xd3, 0xa4, 0x8d, 0x4e, - 0x91, 0x9c, 0xde, 0x28, 0xad, 0x74, 0x4b, 0x34, 0x79, 0x49, 0xc7, 0xde, - 0x5d, 0x34, 0xb9, 0xa6, 0xda, 0x1c, 0xcb, 0x31, 0x74, 0x3c, 0xd1, 0x13, - 0xf0, 0xd1, 0x12, 0x4d, 0xac, 0xbb, 0xd2, 0x7f, 0x56, 0xbc, 0x96, 0xaf, - 0xd1, 0x0f, 0xe8, 0xda, 0x5c, 0x01, 0x77, 0xb2, 0xc9, 0x9f, 0x1e, 0x3c, - 0xcf, 0x80, 0x9b, 0xf1, 0x1c, 0x98, 0xee, 0x71, 0x1d, 0x52, 0x99, 0x9f, - 0x49, 0x13, 0x97, 0x4c, 0x25, 0xee, 0xb2, 0xce, 0xd8, 0x07, 0xcd, 0xcc, - 0x07, 0x75, 0x25, 0x3a, 0x57, 0xc4, 0x59, 0x7f, 0x12, 0x91, 0x07, 0xdf, - 0x03, 0x96, 0xad, 0x54, 0xbe, 0x0f, 0xf9, 0x30, 0xd7, 0xe3, 0xb5, 0x9b, - 0xd9, 0x3c, 0xf3, 0x00, 0x46, 0xf8, 0xfb, 0x29, 0x62, 0x3c, 0x38, 0xc6, - 0x34, 0x45, 0x9a, 0x58, 0x63, 0x8c, 0xc1, 0xd8, 0xe3, 0x77, 0xbe, 0xdb, - 0x08, 0xd5, 0xa1, 0x95, 0xfa, 0x8c, 0x0d, 0xb9, 0x54, 0x89, 0x19, 0x75, - 0x60, 0x88, 0xea, 0x95, 0x30, 0xf2, 0x79, 0x3f, 0xd3, 0xd2, 0xf8, 0xb7, - 0xa5, 0xbd, 0x63, 0xf8, 0xaf, 0x0e, 0x79, 0x56, 0x69, 0xaa, 0x7c, 0x5c, - 0xae, 0x61, 0xae, 0xcf, 0x6b, 0xd6, 0x6d, 0x6b, 0x78, 0xef, 0xe7, 0x32, - 0x20, 0xc6, 0xbd, 0x16, 0x4e, 0x31, 0x32, 0xbd, 0xf0, 0xfe, 0x46, 0x19, - 0xb6, 0x01, 0xa6, 0x11, 0x74, 0x49, 0xd4, 0xeb, 0xe8, 0xc0, 0x1c, 0xf5, - 0x8b, 0x2a, 0xd3, 0xd9, 0xcc, 0x07, 0xf7, 0x5f, 0xd7, 0x95, 0xf8, 0x9c, - 0xe7, 0xfc, 0x81, 0x98, 0x7e, 0x12, 0x3a, 0x98, 0x9a, 0x6f, 0xf1, 0xfe, - 0xbe, 0x41, 0xde, 0x5a, 0xc3, 0xd2, 0x61, 0x53, 0x15, 0x06, 0x8d, 0x7f, - 0x34, 0x06, 0x5b, 0xbb, 0x4e, 0x8b, 0x7e, 0x07, 0x79, 0x0a, 0xe4, 0xf5, - 0x74, 0x7a, 0xb9, 0xc3, 0xba, 0x30, 0x69, 0x72, 0x5d, 0x88, 0xe7, 0x7c, - 0xb6, 0xc9, 0xbb, 0xd0, 0x0b, 0xe1, 0x86, 0x53, 0xf3, 0x37, 0x60, 0x9f, - 0x8d, 0x3e, 0xdb, 0xc6, 0x90, 0x3a, 0xf1, 0xd6, 0xe6, 0x60, 0xd7, 0x99, - 0x4c, 0x46, 0xb6, 0x97, 0x4e, 0xed, 0x8a, 0x4a, 0x17, 0x2b, 0x9f, 0x08, - 0xd5, 0x63, 0x8c, 0x2d, 0x40, 0xb7, 0xd8, 0xd7, 0xc3, 0xbe, 0xa4, 0x00, - 0x1d, 0xfe, 0x4d, 0x18, 0xc0, 0xdf, 0x8b, 0x15, 0xcc, 0xaf, 0x9d, 0x86, - 0xac, 0x1a, 0x68, 0x53, 0x1f, 0x63, 0x79, 0x16, 0x3a, 0xf9, 0xfd, 0xbc, - 0xf9, 0xb7, 0x25, 0xbf, 0x51, 0x9a, 0xde, 0x1c, 0xa5, 0x13, 0xfd, 0x51, - 0x9a, 0x38, 0xcb, 0x34, 0x42, 0xb4, 0x2b, 0x8c, 0x91, 0xf0, 0x51, 0x4f, - 0xea, 0xa1, 0xac, 0xa9, 0x7c, 0x4f, 0xac, 0x6f, 0x12, 0xad, 0xf6, 0xf9, - 0x0c, 0x7d, 0x80, 0xa7, 0x4a, 0x47, 0x7e, 0x42, 0x74, 0xa4, 0xcf, 0xb4, - 0xdb, 0xba, 0x03, 0x5f, 0x0b, 0x3c, 0x2d, 0xe2, 0x5c, 0xa4, 0x79, 0xc8, - 0x79, 0x1b, 0x11, 0x72, 0x58, 0x15, 0xbf, 0x05, 0xe4, 0x35, 0xbe, 0xff, - 0x1c, 0xe2, 0x8f, 0xb1, 0x7c, 0x0b, 0x77, 0x2f, 0x50, 0xdb, 0x5f, 0xc4, - 0x1e, 0xb6, 0xf1, 0x51, 0xac, 0xef, 0x46, 0x2e, 0xc8, 0x72, 0x85, 0xc5, - 0xb9, 0x62, 0x2f, 0xe2, 0x60, 0x04, 0xf8, 0x7f, 0xbf, 0x3e, 0x9c, 0x2b, - 0xb0, 0xcf, 0x3e, 0x80, 0xdc, 0x80, 0x44, 0x5d, 0x62, 0x5e, 0xfb, 0x31, - 0x8e, 0xe0, 0xfd, 0x00, 0xf6, 0x0e, 0xe6, 0x89, 0x9c, 0xee, 0x6e, 0x39, - 0x02, 0x31, 0xb1, 0x86, 0x58, 0x59, 0x9f, 0x61, 0xcc, 0x80, 0x3d, 0xd8, - 0xa6, 0x45, 0x60, 0xb8, 0x09, 0x1e, 0x6c, 0xdb, 0x22, 0x6c, 0xc8, 0x79, - 0xce, 0xa2, 0xc9, 0x4d, 0x8e, 0xeb, 0x34, 0x8f, 0xc4, 0xdb, 0x79, 0x84, - 0x64, 0x4c, 0x34, 0x13, 0xf6, 0x89, 0xd0, 0x8c, 0xce, 0x6e, 0x09, 0xc4, - 0x70, 0x39, 0x66, 0x5c, 0xdb, 0x9c, 0x05, 0xbd, 0x86, 0xf8, 0xa8, 0x9a, - 0xf5, 0xb3, 0x29, 0xa6, 0xd5, 0x37, 0x1d, 0xe9, 0x93, 0xcd, 0xc4, 0xc2, - 0x3b, 0x63, 0x5a, 0x8e, 0x61, 0x4c, 0x4f, 0x61, 0x04, 0x7c, 0x8b, 0x34, - 0x21, 0x56, 0xfc, 0x31, 0xaa, 0xc3, 0x3f, 0x43, 0xe0, 0x5a, 0x1d, 0xb8, - 0x16, 0x0f, 0xe0, 0x5a, 0xfc, 0x99, 0xb8, 0x06, 0xcc, 0xea, 0x02, 0xb3, - 0x50, 0x23, 0xbc, 0x06, 0x8c, 0x7f, 0x15, 0xe7, 0x5d, 0xee, 0xee, 0x84, - 0x75, 0x8c, 0x73, 0x8c, 0x77, 0x33, 0xf4, 0xe6, 0xc1, 0x7f, 0x15, 0xef, - 0xda, 0xc0, 0x06, 0x93, 0xbe, 0x7b, 0xf0, 0xde, 0x98, 0x77, 0x06, 0x98, - 0x67, 0x7c, 0x36, 0xe6, 0x35, 0x18, 0xf3, 0x74, 0xf8, 0x60, 0x03, 0x78, - 0xa0, 0xae, 0x0d, 0x9e, 0xd3, 0xc1, 0x39, 0x3c, 0xa7, 0x67, 0x79, 0x55, - 0xa5, 0x1e, 0xfc, 0x5f, 0xf3, 0xf8, 0x9c, 0x39, 0xd6, 0xbb, 0xd4, 0xff, - 0x13, 0xba, 0x4d, 0xc6, 0x34, 0xfc, 0x62, 0x6d, 0x94, 0xb4, 0xb3, 0x9f, - 0xfa, 0x3d, 0x6a, 0x03, 0xc4, 0x3b, 0xfe, 0x6d, 0xe6, 0x3c, 0x4a, 0xc0, - 0x1c, 0x9d, 0x0a, 0x6b, 0x06, 0xde, 0x95, 0xa1, 0x7d, 0x47, 0x90, 0x77, - 0xb4, 0xc0, 0x9d, 0x7f, 0x9f, 0x9f, 0xfb, 0xbc, 0xa7, 0x44, 0xea, 0xba, - 0xeb, 0x38, 0xaa, 0xeb, 0x5f, 0x03, 0x46, 0xbc, 0xe3, 0x31, 0x0e, 0x36, - 0xe1, 0x0d, 0x05, 0xd2, 0xd7, 0xc4, 0x69, 0x23, 0xe0, 0xb3, 0x1b, 0x0e, - 0xe2, 0xdd, 0x79, 0x09, 0x7e, 0xc4, 0x39, 0xf4, 0x22, 0xe2, 0xa7, 0x96, - 0xc5, 0x6a, 0xab, 0x9f, 0x9f, 0xb9, 0x0f, 0x72, 0x1b, 0xa0, 0x19, 0xdc, - 0xcb, 0x71, 0x20, 0xc4, 0x09, 0xdc, 0x49, 0xc3, 0x39, 0xc6, 0xba, 0x49, - 0x85, 0x75, 0xd6, 0x8b, 0x0b, 0xfa, 0x49, 0x6b, 0x81, 0xae, 0x0f, 0xe1, - 0xc2, 0x73, 0xfd, 0xeb, 0x3a, 0x63, 0xa9, 0x86, 0x18, 0x2d, 0xe2, 0x5c, - 0x63, 0x9b, 0x17, 0x65, 0xbc, 0x98, 0xde, 0x2b, 0x9f, 0xd8, 0xa6, 0x67, - 0x7c, 0x9b, 0x2a, 0x33, 0x8e, 0xb1, 0x1c, 0x9a, 0xc4, 0xd4, 0x52, 0x86, - 0xa9, 0x93, 0xb0, 0x67, 0x49, 0xc6, 0xa7, 0xea, 0x3d, 0x98, 0xe1, 0xea, - 0x5e, 0x8c, 0x3c, 0x27, 0xb2, 0x78, 0xd1, 0x21, 0x2f, 0xf3, 0x2d, 0x91, - 0xb6, 0xce, 0x35, 0x04, 0xdf, 0xe9, 0xaf, 0xf0, 0x6d, 0xc6, 0x0a, 0xf6, - 0x4f, 0x89, 0xa9, 0x98, 0x9f, 0x82, 0xcc, 0x8c, 0x0f, 0x4c, 0xc7, 0xf4, - 0x3b, 0xd1, 0xfd, 0x05, 0x74, 0xd6, 0x0e, 0x74, 0x98, 0xdb, 0x64, 0x1a, - 0xc6, 0x88, 0x7d, 0xd8, 0x1f, 0x31, 0x3e, 0x40, 0x67, 0x4c, 0x3b, 0x9e, - 0xc5, 0x63, 0x15, 0x6b, 0x5c, 0x03, 0xcb, 0xf8, 0x22, 0x23, 0xe0, 0x7b, - 0x70, 0x7d, 0xcc, 0xf9, 0x91, 0x6b, 0x52, 0xae, 0x3d, 0xf3, 0x5a, 0xd5, - 0x9b, 0xa9, 0xdd, 0xad, 0xee, 0xb4, 0x06, 0xeb, 0xce, 0x43, 0xc6, 0xce, - 0x75, 0xe7, 0x41, 0x23, 0xad, 0x3b, 0xa7, 0x8d, 0xbb, 0xd7, 0x9d, 0x39, - 0xed, 0xbd, 0xeb, 0xce, 0x66, 0x97, 0xcf, 0xdc, 0x19, 0x2f, 0x56, 0xe0, - 0xaf, 0xad, 0x24, 0xbf, 0x27, 0xf7, 0x06, 0xa1, 0x59, 0x3b, 0x9b, 0xda, - 0xbe, 0x29, 0x7d, 0x11, 0x38, 0xb2, 0x39, 0x0b, 0x3b, 0xa2, 0xa6, 0x1e, - 0xc2, 0x8e, 0x9c, 0x86, 0x75, 0x5a, 0x02, 0x46, 0xb3, 0x3e, 0x8b, 0x19, - 0x4e, 0x60, 0xf4, 0x3e, 0x06, 0x4e, 0xe4, 0xf8, 0xc2, 0xfc, 0xfe, 0x9f, - 0xf0, 0x85, 0xcc, 0x11, 0xe0, 0x84, 0x19, 0x30, 0x5e, 0x4a, 0x59, 0x50, - 0x93, 0x0b, 0xb1, 0xe0, 0x73, 0x0c, 0x0c, 0xf6, 0x4c, 0xec, 0x0f, 0x45, - 0x7a, 0xcb, 0x67, 0x9f, 0x40, 0xcf, 0xe4, 0x71, 0x8e, 0x64, 0x3c, 0xde, - 0x12, 0x6f, 0x79, 0x11, 0xe6, 0xaa, 0xb0, 0x3d, 0xfb, 0xc3, 0xa2, 0x72, - 0x64, 0xc3, 0x04, 0x1d, 0xfb, 0xc4, 0xf8, 0x1d, 0xbd, 0x50, 0xda, 0xb3, - 0x70, 0x7d, 0xfc, 0xef, 0xfa, 0xc8, 0x1b, 0x77, 0xf1, 0x91, 0xcb, 0x99, - 0x8f, 0x24, 0xf7, 0xf0, 0x91, 0x37, 0x3e, 0xa7, 0x8f, 0xb8, 0xe5, 0x0f, - 0x51, 0x3f, 0xbd, 0x0d, 0x39, 0x42, 0x4b, 0x88, 0x0f, 0xfd, 0x9d, 0xfa, - 0x94, 0xd0, 0xd4, 0x5f, 0x64, 0x9d, 0xa5, 0x79, 0xa5, 0x85, 0x77, 0xed, - 0x15, 0xae, 0x97, 0x39, 0xe7, 0xa4, 0xb9, 0x65, 0xe2, 0xc5, 0xd4, 0x3f, - 0x26, 0x5e, 0x11, 0xe2, 0xc2, 0x0e, 0xfe, 0xc0, 0x35, 0xf4, 0x55, 0xf8, - 0x55, 0x8b, 0xfe, 0x17, 0x35, 0x34, 0x63, 0x78, 0xc5, 0x3c, 0xde, 0xc9, - 0xed, 0x9f, 0xdb, 0xbe, 0x40, 0xe7, 0xad, 0x3d, 0xd0, 0xdb, 0xa3, 0xd4, - 0xfa, 0xb1, 0xce, 0x7d, 0x05, 0xfc, 0xe2, 0x71, 0x9d, 0x63, 0x17, 0x7d, - 0x24, 0x9e, 0x07, 0xeb, 0x6c, 0xf8, 0xa5, 0x5f, 0xc8, 0xe3, 0x65, 0x00, - 0xfb, 0x4f, 0xa1, 0x54, 0xb9, 0x23, 0xaf, 0x0c, 0xf5, 0xd4, 0x1a, 0x7a, - 0xea, 0x58, 0xf2, 0xe0, 0xbe, 0x2b, 0xd5, 0x63, 0x5b, 0xf6, 0xd1, 0x5b, - 0xa2, 0x25, 0x7b, 0xe9, 0x03, 0x05, 0x2a, 0x2d, 0x66, 0x3e, 0xe3, 0x20, - 0x1f, 0xb9, 0x7e, 0x03, 0xfc, 0xb9, 0xd6, 0x80, 0x1c, 0xb4, 0x8a, 0x58, - 0xbc, 0x80, 0x3c, 0xbc, 0x02, 0xbd, 0xd4, 0x65, 0x6c, 0x8c, 0xd1, 0x35, - 0xe4, 0xfe, 0x36, 0xf2, 0xf3, 0x19, 0xe8, 0xa6, 0x05, 0xdd, 0xc4, 0x49, - 0x1a, 0x27, 0xd7, 0xa0, 0x9b, 0x85, 0x01, 0xdd, 0x2c, 0xfc, 0x47, 0xfd, - 0xc5, 0x1f, 0x91, 0x6b, 0xcd, 0x65, 0x1d, 0xf3, 0x57, 0x12, 0x99, 0x5b, - 0x97, 0x5a, 0x1d, 0x6a, 0xdc, 0x1f, 0x9c, 0xe6, 0xda, 0x8e, 0x6b, 0xb3, - 0xf9, 0x95, 0x0a, 0xe6, 0xfa, 0x26, 0x45, 0xd0, 0xcf, 0x37, 0x0f, 0xd3, - 0xb2, 0x16, 0xb0, 0x4f, 0xe3, 0x3d, 0xa1, 0x46, 0x74, 0x18, 0xf5, 0x56, - 0x32, 0xbe, 0x8c, 0x7e, 0x1c, 0xbe, 0xd5, 0xa0, 0x10, 0x72, 0x86, 0xe0, - 0xbd, 0xd0, 0x31, 0xcd, 0xd5, 0x0e, 0xf7, 0x51, 0x0d, 0xe2, 0x5e, 0xbd, - 0xd7, 0xbf, 0x09, 0x7e, 0x23, 0xdf, 0x40, 0x7f, 0xeb, 0x34, 0x81, 0xd3, - 0xcf, 0xc2, 0x6d, 0x5b, 0x36, 0x7f, 0xcb, 0x60, 0x1c, 0x1d, 0x07, 0x8f, - 0xa7, 0x0b, 0xa9, 0xaf, 0x8e, 0x83, 0x0f, 0xc7, 0x11, 0xe1, 0x3c, 0xd6, - 0x65, 0xee, 0x7f, 0xe5, 0x81, 0xfa, 0xbe, 0x40, 0x39, 0x86, 0x35, 0xa1, - 0x37, 0xd6, 0x75, 0xe4, 0x9d, 0x2c, 0xe4, 0xdf, 0x6d, 0x5a, 0xc0, 0x81, - 0xfa, 0x1c, 0x63, 0x96, 0x02, 0xdf, 0xa3, 0xb4, 0xaf, 0x44, 0x1f, 0x52, - 0x9f, 0x43, 0xde, 0xb6, 0x8b, 0x72, 0x6c, 0x24, 0xa7, 0xb3, 0xfd, 0xaa, - 0xdc, 0xc7, 0xf9, 0xa2, 0x99, 0xc8, 0x7e, 0x42, 0xa9, 0x76, 0xc9, 0xa9, - 0xfb, 0xe8, 0x93, 0x50, 0x7b, 0xb4, 0x13, 0xce, 0xf5, 0x73, 0xa6, 0x2a, - 0xb1, 0xef, 0x06, 0x68, 0xf0, 0xbc, 0x49, 0x6a, 0xdd, 0xe7, 0xef, 0x0c, - 0xfc, 0x0d, 0x04, 0xf1, 0x63, 0xd3, 0x6e, 0xd0, 0x43, 0xae, 0x71, 0x96, - 0x2b, 0xac, 0xcb, 0x3a, 0x85, 0x79, 0x1f, 0x52, 0xd3, 0x6f, 0x33, 0xef, - 0x66, 0x67, 0x99, 0x88, 0x1f, 0xc6, 0x5d, 0x9f, 0x73, 0xde, 0x97, 0x34, - 0xba, 0x49, 0x12, 0x37, 0xad, 0x87, 0x91, 0x0b, 0x0f, 0x83, 0x26, 0x94, - 0x98, 0x93, 0xf6, 0x15, 0x39, 0x8d, 0xa7, 0x0d, 0xf3, 0x58, 0xd6, 0x87, - 0xdf, 0x43, 0xc4, 0x59, 0x25, 0x3b, 0x6f, 0xd0, 0x67, 0xdf, 0x87, 0xcf, - 0xde, 0xc8, 0xf6, 0x00, 0x87, 0xed, 0x02, 0xf6, 0xb1, 0x8c, 0x8c, 0x2f, - 0x4c, 0xb3, 0x65, 0x0c, 0xf3, 0x99, 0xdc, 0x81, 0xc7, 0x47, 0x03, 0x3c, - 0x6c, 0xbe, 0x9b, 0x55, 0x4f, 0x7b, 0x6c, 0xf9, 0x57, 0x87, 0x9e, 0xd1, - 0x93, 0xdc, 0xa7, 0xe2, 0x1e, 0x5c, 0x9b, 0xc5, 0x72, 0xfe, 0x97, 0xc5, - 0x61, 0xbe, 0xa7, 0xb2, 0x73, 0xfc, 0x34, 0x36, 0x3c, 0x8c, 0xc9, 0x8d, - 0x01, 0xd9, 0x8d, 0x1d, 0xce, 0xdd, 0xa5, 0xa3, 0x35, 0x50, 0xd8, 0xdf, - 0xb4, 0x80, 0xf3, 0x33, 0x9e, 0xb7, 0xfd, 0x83, 0x7d, 0xf5, 0xb3, 0x7d, - 0xd4, 0xf8, 0x9c, 0x3e, 0xfa, 0x72, 0x87, 0x71, 0x23, 0xf5, 0xd1, 0xfa, - 0x1d, 0x3e, 0x8a, 0xfa, 0xc8, 0xce, 0xfd, 0x93, 0xe3, 0x25, 0xf7, 0xcf, - 0xfc, 0x99, 0x63, 0x1c, 0xb8, 0x9c, 0xe1, 0x5c, 0x13, 0x38, 0x57, 0x95, - 0x79, 0xcf, 0x2d, 0x57, 0x29, 0x8d, 0xe5, 0x55, 0xc4, 0x72, 0x55, 0xe3, - 0x3c, 0xc8, 0x31, 0xcc, 0x74, 0x1c, 0xc7, 0x4c, 0x37, 0x96, 0xd1, 0x61, - 0x44, 0x3c, 0x57, 0xb3, 0x78, 0x6e, 0x75, 0x5d, 0xa7, 0x9a, 0xc5, 0x73, - 0x0b, 0x31, 0xdc, 0xce, 0xe2, 0xb9, 0x95, 0xc5, 0x33, 0x7f, 0xdf, 0xd3, - 0x2a, 0x9c, 0x1b, 0x5d, 0x27, 0x06, 0xc6, 0xb5, 0x25, 0xcf, 0x06, 0xee, - 0x09, 0x19, 0xbb, 0x79, 0x5c, 0xdc, 0xf1, 0x1d, 0x0c, 0xf7, 0xf9, 0x34, - 0xd7, 0xd4, 0x90, 0x6b, 0x2e, 0x20, 0xd7, 0xf4, 0x06, 0xbe, 0x83, 0x9d, - 0x97, 0xb9, 0xe6, 0xeb, 0xc5, 0x3c, 0xd7, 0xf4, 0xb2, 0x5c, 0xd3, 0x93, - 0xb9, 0xe6, 0xab, 0x45, 0xce, 0x35, 0x4d, 0x3a, 0x5a, 0x1c, 0xcc, 0x35, - 0xcd, 0xa1, 0x5c, 0x93, 0xd3, 0xf2, 0xfc, 0x4e, 0xb9, 0x26, 0xd7, 0xd9, - 0xbd, 0x6a, 0x92, 0x7c, 0x0f, 0xcb, 0xca, 0xb8, 0xc4, 0x78, 0x9c, 0xd6, - 0xfc, 0x57, 0x92, 0x3c, 0x96, 0x4e, 0xe3, 0x1c, 0xbc, 0x77, 0x77, 0x8a, - 0x25, 0x33, 0x8b, 0xa5, 0xdd, 0x29, 0x4d, 0x77, 0x30, 0x9e, 0x4e, 0x17, - 0x87, 0xe3, 0x29, 0xe7, 0x93, 0xc7, 0x53, 0xca, 0xf3, 0x3d, 0xad, 0xcc, - 0x35, 0x02, 0xfa, 0x6d, 0xd7, 0x5f, 0xc0, 0xec, 0xa5, 0xfe, 0x2c, 0x6a, - 0x6e, 0x9d, 0xae, 0xe6, 0x78, 0x23, 0xbf, 0x09, 0x61, 0xec, 0xe7, 0xb2, - 0x16, 0xb7, 0xd7, 0x7a, 0xa8, 0xbb, 0xdf, 0x01, 0x8e, 0x5c, 0x94, 0xeb, - 0x9f, 0x88, 0xab, 0x68, 0x09, 0xdb, 0x5e, 0xbe, 0xef, 0x17, 0x38, 0xcf, - 0xb5, 0xce, 0xe3, 0xe9, 0xd9, 0x7e, 0xae, 0x13, 0x5e, 0xe7, 0xb9, 0xbf, - 0x23, 0x9f, 0xa0, 0x66, 0xdf, 0xde, 0xcb, 0xfd, 0x8f, 0x87, 0x3b, 0x3b, - 0xf4, 0xfa, 0x50, 0x0f, 0x94, 0xf6, 0x3e, 0x75, 0xf9, 0x8d, 0x97, 0x6b, - 0x97, 0xe8, 0x0b, 0x2a, 0x9d, 0xa2, 0xaf, 0xf9, 0x3c, 0xa7, 0x52, 0xed, - 0x31, 0x21, 0x9e, 0x41, 0x1d, 0xf3, 0xd4, 0x50, 0x1d, 0x53, 0xa4, 0x89, - 0x47, 0x06, 0x7b, 0xc8, 0x2d, 0x31, 0x31, 0xed, 0x9e, 0x0f, 0x29, 0x54, - 0x6a, 0x1b, 0x5c, 0xe7, 0x6e, 0xd7, 0xb5, 0x44, 0xfb, 0x6e, 0x09, 0x75, - 0x9a, 0xf3, 0xe2, 0x6f, 0x33, 0x5d, 0x61, 0xed, 0xdc, 0x2d, 0x60, 0x6b, - 0x55, 0x7e, 0x0b, 0x0e, 0x37, 0xf8, 0x1c, 0x7e, 0xc7, 0x98, 0x70, 0xcd, - 0x73, 0xb7, 0xef, 0xb3, 0x3a, 0xec, 0xe2, 0x3a, 0xc7, 0x35, 0x92, 0xdf, - 0x37, 0x56, 0x7c, 0xf7, 0xa7, 0x2d, 0x4a, 0x71, 0xa2, 0xea, 0x2f, 0x41, - 0x16, 0xd4, 0x9d, 0xd6, 0x32, 0x6c, 0x33, 0x0d, 0x5c, 0x72, 0x9d, 0x47, - 0x54, 0x5b, 0xe2, 0xf8, 0x2a, 0x78, 0x6b, 0x8f, 0x70, 0x4d, 0xf9, 0xb1, - 0x58, 0xed, 0xcb, 0x7c, 0xec, 0xb3, 0x8f, 0xc4, 0xc9, 0x5e, 0x95, 0xc7, - 0x30, 0xe1, 0xe7, 0x02, 0x71, 0x2d, 0xb9, 0xb3, 0xff, 0xd8, 0x56, 0xf5, - 0x9c, 0x63, 0xd5, 0xba, 0x8e, 0xb5, 0xd0, 0x55, 0xe1, 0xdd, 0xfb, 0x4c, - 0xda, 0x03, 0x9b, 0x20, 0x1f, 0xd3, 0x7d, 0x90, 0xe5, 0x92, 0x63, 0xc5, - 0xa8, 0x0f, 0xbf, 0xa7, 0xb9, 0xd6, 0x53, 0xa4, 0x98, 0x54, 0xba, 0x25, - 0xd2, 0x6f, 0x33, 0x8e, 0x55, 0xdd, 0x3e, 0xfb, 0x16, 0xce, 0x66, 0x99, - 0x38, 0x46, 0x39, 0x5f, 0x2e, 0x2a, 0x4b, 0xd0, 0xd1, 0xb1, 0x8d, 0x5d, - 0xc0, 0x35, 0xce, 0x97, 0x07, 0xb2, 0x6f, 0x50, 0xb0, 0x0f, 0xee, 0xff, - 0xfa, 0x1d, 0xf5, 0x67, 0x5e, 0x67, 0x32, 0xbd, 0x10, 0xcd, 0x79, 0x3e, - 0x9f, 0x20, 0xcb, 0xd4, 0xcc, 0x25, 0xd9, 0x13, 0xcd, 0xa2, 0xee, 0xe3, - 0x51, 0xa0, 0x26, 0xe2, 0xef, 0x61, 0xae, 0x55, 0xc7, 0x73, 0x35, 0x7b, - 0x6e, 0x72, 0xbf, 0x34, 0xcf, 0x3c, 0xb8, 0x6f, 0xe2, 0xf8, 0xf9, 0x27, - 0x6e, 0xb7, 0x92, 0x82, 0x90, 0x18, 0x00, 0x00, 0x00 }; +/* 0x1f, 0x8b, 0x08, 0x00, 0x0e, 0x34, 0xe7, 0x45, 0x00, 0x03, */ + 0xcd, 0x58, + 0x5d, 0x68, 0x1c, 0xd7, 0x15, 0x3e, 0xf3, 0xb7, 0x3b, 0x52, 0x24, 0xeb, + 0x5a, 0xd9, 0xa6, 0xeb, 0xa0, 0x34, 0x33, 0xda, 0x91, 0xac, 0x22, 0x13, + 0x4f, 0x9d, 0x25, 0x16, 0x65, 0x21, 0x93, 0xd9, 0x91, 0xac, 0x98, 0x3c, + 0x28, 0xc5, 0x90, 0x87, 0x52, 0x50, 0x57, 0x32, 0x09, 0x79, 0x69, 0xda, + 0xc6, 0x90, 0x3e, 0x79, 0x3b, 0x2b, 0xc7, 0x0e, 0x6c, 0xbc, 0x8d, 0x52, + 0xe4, 0x52, 0xfa, 0x60, 0xd6, 0xb1, 0x05, 0xcd, 0x46, 0x93, 0xd4, 0x7e, + 0x35, 0x36, 0x4e, 0x93, 0xa7, 0x42, 0x9f, 0x52, 0xf4, 0x18, 0xd2, 0x12, + 0xda, 0x52, 0x8a, 0x69, 0xa1, 0x09, 0x8d, 0xeb, 0xdb, 0xef, 0xdc, 0x99, + 0x91, 0x57, 0xb6, 0xec, 0xa4, 0x25, 0x85, 0x0a, 0x56, 0x77, 0xe6, 0xce, + 0x3d, 0xe7, 0x9e, 0x7b, 0xee, 0x77, 0xbe, 0x73, 0xee, 0x2d, 0xeb, 0x34, + 0x48, 0xd9, 0xdf, 0x30, 0x7e, 0x2f, 0x7e, 0xf7, 0x85, 0x17, 0xab, 0x8f, + 0x3c, 0xea, 0x10, 0x3d, 0xfa, 0x88, 0x66, 0x98, 0x06, 0x7d, 0x09, 0x7f, + 0x50, 0x22, 0x72, 0xfd, 0xfc, 0x23, 0x5b, 0xaf, 0x9d, 0x72, 0x42, 0x8f, + 0x6c, 0xa3, 0x26, 0xbe, 0xbe, 0xe4, 0x11, 0x05, 0xbd, 0x69, 0xa7, 0x4e, + 0xff, 0x92, 0xcd, 0x92, 0x49, 0xdc, 0xff, 0x50, 0xed, 0xc6, 0xfe, 0xcb, + 0x07, 0xdd, 0xeb, 0x67, 0x0d, 0xb2, 0x45, 0x6d, 0xd1, 0x16, 0x93, 0x64, + 0x8f, 0xd5, 0x9a, 0xce, 0x2f, 0xf6, 0x1e, 0x28, 0xd0, 0xae, 0x5c, 0x97, + 0xa0, 0xb8, 0x43, 0x4d, 0xab, 0x66, 0x53, 0xd4, 0x7e, 0x49, 0x0b, 0x3b, + 0x9e, 0x98, 0x85, 0x8e, 0xa0, 0x04, 0xfd, 0x1e, 0xde, 0x13, 0x53, 0x8b, + 0xce, 0xd8, 0xa4, 0xd7, 0x02, 0x3c, 0x4f, 0x51, 0xab, 0x23, 0xe5, 0x2b, + 0xbe, 0x46, 0x4b, 0xbe, 0x4d, 0x8b, 0xc2, 0x0d, 0x1c, 0xed, 0xa6, 0xac, + 0x4c, 0x48, 0xf9, 0x9c, 0xaf, 0x93, 0xee, 0xcd, 0x69, 0xe1, 0xfa, 0xbc, + 0x56, 0x5f, 0x9f, 0x67, 0x7f, 0xc0, 0xbe, 0x39, 0x2d, 0x58, 0xe7, 0xb6, + 0x66, 0xd7, 0xdb, 0xbb, 0x68, 0xb1, 0x44, 0x23, 0xba, 0x37, 0x85, 0xf9, + 0x4a, 0xd0, 0xe3, 0x50, 0xe8, 0x4f, 0x0b, 0x9d, 0x2a, 0xf8, 0x0d, 0xd0, + 0xac, 0x4f, 0x03, 0xba, 0xa7, 0x53, 0xa3, 0xa4, 0xd1, 0x1b, 0x55, 0x0b, + 0xbf, 0xc3, 0x5a, 0xb4, 0xfe, 0x7c, 0xa6, 0x87, 0xc7, 0xdb, 0xf8, 0xc6, + 0x36, 0xb3, 0x7c, 0xbf, 0xec, 0x30, 0x9e, 0x9f, 0xc3, 0x38, 0x8b, 0xc2, + 0xea, 0xed, 0xdf, 0x06, 0xf0, 0xac, 0xa1, 0xff, 0x30, 0xec, 0x62, 0x3d, + 0x0e, 0xec, 0x28, 0xd3, 0x4a, 0x67, 0x1e, 0xeb, 0x29, 0x50, 0x53, 0x4c, + 0x4c, 0x35, 0xc8, 0x84, 0x8c, 0x41, 0x41, 0xe9, 0x8a, 0xd4, 0x6b, 0x52, + 0x86, 0x55, 0x6f, 0xaa, 0xab, 0xe6, 0xd0, 0xc9, 0xf0, 0x0a, 0x14, 0xf9, + 0xc3, 0xd4, 0x12, 0x06, 0xc5, 0xfb, 0x2c, 0x0a, 0x16, 0x4c, 0xac, 0x71, + 0x14, 0x72, 0x1a, 0xe4, 0x5f, 0xcb, 0xf6, 0xbc, 0x48, 0xb1, 0x28, 0xa0, + 0x7f, 0x84, 0xe2, 0xd2, 0x6e, 0x4d, 0xaf, 0xbd, 0x82, 0xfe, 0x09, 0xd1, + 0xa5, 0x53, 0x68, 0x35, 0xbc, 0xef, 0xc6, 0x58, 0x7e, 0xd7, 0xa0, 0x8f, + 0x44, 0x98, 0x78, 0xd4, 0x4a, 0x72, 0x59, 0xee, 0x4f, 0xfb, 0x9a, 0xc9, + 0xed, 0xfb, 0xed, 0xc1, 0x4e, 0x41, 0x27, 0x3a, 0xb3, 0x98, 0x8f, 0x9a, + 0x46, 0x0d, 0xe3, 0xb0, 0x37, 0xbc, 0xbf, 0x81, 0xc2, 0xc1, 0xe3, 0xdc, + 0xcf, 0x7f, 0xe8, 0x77, 0xc8, 0xa8, 0xf1, 0xb7, 0x6f, 0x52, 0xfa, 0x2d, + 0xb5, 0x3f, 0xf4, 0x1f, 0xcb, 0xde, 0x4b, 0x22, 0x3c, 0xf3, 0x28, 0xd6, + 0xa8, 0x60, 0x83, 0xe7, 0x02, 0xf0, 0x11, 0xcf, 0xe8, 0xd4, 0x2c, 0x17, + 0xc9, 0xf5, 0x8f, 0xa2, 0xf7, 0xd7, 0x6d, 0x83, 0xea, 0xec, 0x2b, 0xdf, + 0xcc, 0x64, 0x18, 0x1b, 0x1f, 0x64, 0x76, 0x0a, 0x5a, 0x3c, 0x22, 0xe5, + 0x8a, 0x2f, 0xa5, 0x55, 0xf3, 0x9c, 0x13, 0x34, 0x5d, 0x36, 0x69, 0x52, + 0xa0, 0x85, 0x8f, 0xbd, 0x72, 0x83, 0x2c, 0x60, 0xa1, 0x1f, 0xff, 0xfc, + 0xf7, 0xa6, 0x86, 0x25, 0xd0, 0xb5, 0x36, 0xeb, 0x98, 0x70, 0x66, 0x95, + 0x8c, 0x94, 0xf1, 0xcc, 0xbd, 0x64, 0x2e, 0x65, 0x32, 0x52, 0x46, 0x55, + 0x81, 0x3d, 0x6f, 0x0a, 0xd8, 0x87, 0x75, 0x31, 0xc6, 0x89, 0xa2, 0x9e, + 0x6f, 0x37, 0xda, 0xb0, 0xd1, 0x43, 0xdb, 0x13, 0xf0, 0x0f, 0x51, 0x0b, + 0x63, 0xf5, 0xea, 0x7d, 0x8c, 0x0d, 0xec, 0xef, 0x82, 0x1d, 0xb5, 0xdd, + 0xf2, 0x29, 0x5a, 0xb0, 0xeb, 0xbd, 0xe9, 0xf2, 0x32, 0x3d, 0xc4, 0x73, + 0xd8, 0x56, 0xed, 0x88, 0xdd, 0x55, 0x72, 0x88, 0xc4, 0x41, 0x3c, 0xf7, + 0x88, 0xe2, 0x36, 0x69, 0xa1, 0x7f, 0x1f, 0xaf, 0x15, 0x72, 0xf3, 0x99, + 0xdc, 0x7c, 0x26, 0x37, 0x92, 0xc9, 0x3d, 0xd5, 0x27, 0xf7, 0x14, 0xcb, + 0x61, 0x6c, 0x90, 0x8d, 0x0d, 0xb2, 0xb1, 0x66, 0x36, 0x36, 0xca, 0xc6, + 0xa2, 0xed, 0x8d, 0xc1, 0x36, 0x77, 0xca, 0xd1, 0x6c, 0x8a, 0x3d, 0xf9, + 0x70, 0xe8, 0x53, 0x50, 0xf7, 0xdc, 0xcd, 0xba, 0x31, 0x42, 0xe7, 0xfc, + 0x21, 0x5a, 0x49, 0xc6, 0x28, 0x4e, 0x56, 0x28, 0x4c, 0x74, 0xc8, 0x8e, + 0x50, 0xd7, 0xbb, 0x2e, 0x67, 0x7d, 0x1f, 0x7b, 0x66, 0xb3, 0x5c, 0x79, + 0x96, 0x1c, 0x7c, 0x9f, 0x16, 0xcb, 0xe4, 0x03, 0x2b, 0x3a, 0xf6, 0xad, + 0xa2, 0x9e, 0xe3, 0xc4, 0xe7, 0x35, 0x37, 0xf5, 0xaa, 0x2b, 0x62, 0x72, + 0xcb, 0xa1, 0x41, 0x42, 0xaf, 0xc1, 0x4f, 0x49, 0x93, 0xa2, 0xc4, 0xa6, + 0x0f, 0x8d, 0x97, 0x54, 0x8c, 0xc6, 0x9d, 0x4d, 0x79, 0x79, 0xaf, 0x43, + 0x57, 0x30, 0xcf, 0xc5, 0xa4, 0x4c, 0xbf, 0x4a, 0x4a, 0xf4, 0x4e, 0x42, + 0x7a, 0xe8, 0x03, 0xc3, 0x25, 0x41, 0x6f, 0x27, 0xfd, 0x3e, 0xff, 0x88, + 0x7d, 0x6e, 0xdf, 0x5f, 0x23, 0x7b, 0xb4, 0xc6, 0x38, 0x4b, 0x39, 0xa0, + 0x9e, 0x72, 0x80, 0xc2, 0x52, 0xab, 0x13, 0x3f, 0x68, 0x80, 0x7f, 0x96, + 0xfc, 0x60, 0xb7, 0xa1, 0xf6, 0xa3, 0x89, 0x3d, 0xcc, 0x5b, 0xde, 0x9b, + 0xab, 0xce, 0x92, 0xe7, 0x9e, 0xaa, 0x33, 0x6a, 0x4f, 0x5b, 0x39, 0x2e, + 0xfb, 0xe6, 0xf8, 0x33, 0xe6, 0x18, 0xa2, 0x06, 0xe2, 0xec, 0x09, 0x13, + 0xb1, 0xe3, 0xfd, 0xdd, 0x60, 0x5c, 0x39, 0x1b, 0x8c, 0x6f, 0xa2, 0xf1, + 0x0d, 0x9b, 0xd6, 0xdb, 0x45, 0x72, 0xba, 0x43, 0xb4, 0xd4, 0x19, 0xa4, + 0xca, 0x05, 0x13, 0x63, 0xef, 0xa3, 0xca, 0xaa, 0x5e, 0xe2, 0x38, 0xae, + 0xc3, 0xc7, 0xe3, 0x5d, 0x09, 0x7c, 0x0e, 0xd2, 0xf8, 0x9a, 0xab, 0xb0, + 0xb3, 0xe4, 0xb5, 0x7c, 0x83, 0x7e, 0x4c, 0xd7, 0xf6, 0x15, 0xb0, 0xa6, + 0x12, 0xf9, 0x93, 0xfd, 0xf3, 0xe9, 0x80, 0x18, 0xf7, 0xc5, 0x45, 0xda, + 0xe5, 0x3a, 0xa4, 0xb3, 0x3e, 0x9b, 0xc6, 0x2f, 0xd8, 0x5a, 0xbd, 0xc3, + 0x3e, 0x63, 0xfc, 0xd9, 0x19, 0xfe, 0x4c, 0x2d, 0x3c, 0x53, 0xc4, 0x5c, + 0x7f, 0x91, 0xa1, 0x27, 0xb1, 0x0f, 0x3a, 0x2d, 0x55, 0x7f, 0x04, 0xfb, + 0xd0, 0xd7, 0xe5, 0x6f, 0xd7, 0xb3, 0x7e, 0xd6, 0x01, 0x7e, 0xf0, 0xef, + 0xa7, 0x90, 0xb9, 0xe0, 0x08, 0xcb, 0x14, 0x69, 0x7c, 0x95, 0xf9, 0x05, + 0x6d, 0x97, 0xdf, 0x79, 0x6d, 0x03, 0xd4, 0x80, 0x57, 0x1a, 0x53, 0x25, + 0xd8, 0xa5, 0x2b, 0xbe, 0x68, 0x80, 0x3f, 0x74, 0x6f, 0x10, 0x2d, 0xcf, + 0xf7, 0x73, 0x23, 0x8f, 0xa9, 0xb8, 0x33, 0x44, 0x75, 0xe0, 0xd7, 0x84, + 0x3d, 0xcb, 0x34, 0x51, 0x3e, 0xaa, 0xbe, 0xa1, 0xaf, 0xc7, 0xdf, 0xc4, + 0x6d, 0xdf, 0xf0, 0xde, 0xcb, 0x6d, 0x40, 0x6c, 0x7b, 0x2d, 0xcc, 0x62, + 0x65, 0x7e, 0xe1, 0xf1, 0xcd, 0x32, 0xf6, 0x06, 0x7c, 0x46, 0xf0, 0x25, + 0x51, 0xb7, 0x6d, 0x82, 0x6f, 0xf4, 0xaf, 0xea, 0x2c, 0x57, 0x62, 0x3d, + 0x58, 0xff, 0x9a, 0xa9, 0xd5, 0xcf, 0x78, 0xce, 0x1f, 0x88, 0xe5, 0x2b, + 0xf0, 0xc1, 0xc4, 0x4c, 0x8b, 0xc7, 0xf7, 0x2c, 0xf2, 0x56, 0x9b, 0xc2, + 0xc4, 0x9e, 0xc2, 0x73, 0x54, 0xff, 0xc9, 0x08, 0xf6, 0xda, 0x75, 0x5a, + 0xf4, 0x5b, 0xd8, 0x53, 0x20, 0xaf, 0x6b, 0xd2, 0x1b, 0x6d, 0xf6, 0x85, + 0x4d, 0x95, 0x35, 0x29, 0x4f, 0xfa, 0xbc, 0x27, 0xbf, 0x83, 0x5f, 0x08, + 0x2b, 0x9c, 0x98, 0xf9, 0x08, 0xfb, 0xb3, 0xde, 0xe3, 0xbd, 0xb1, 0x94, + 0x4f, 0xbc, 0xd5, 0x29, 0xec, 0xeb, 0x54, 0x66, 0x23, 0xef, 0x97, 0x49, + 0x2b, 0x55, 0x9d, 0xce, 0x57, 0x3f, 0x93, 0xba, 0xc7, 0xfc, 0x5a, 0x80, + 0x6f, 0x31, 0xae, 0x8b, 0x71, 0x49, 0x01, 0x3e, 0xfc, 0x07, 0x78, 0x45, + 0xca, 0xf3, 0x55, 0xf4, 0xaf, 0x1e, 0x87, 0xad, 0x06, 0x64, 0x53, 0x8c, + 0xb1, 0x3d, 0x73, 0xed, 0x7c, 0x7d, 0xde, 0xcc, 0x7b, 0x4a, 0xdf, 0x10, + 0x4d, 0x6e, 0x0c, 0xd1, 0xb3, 0xbd, 0x21, 0x1a, 0x3f, 0xcd, 0x32, 0xe0, + 0xa6, 0xaa, 0x27, 0x22, 0xc6, 0xa8, 0xa7, 0xfc, 0x50, 0x36, 0x74, 0x5e, + 0x27, 0xbe, 0x6f, 0x10, 0x2d, 0xf7, 0x78, 0x0e, 0xb3, 0x4f, 0xa7, 0x4e, + 0x87, 0x7e, 0x4a, 0x74, 0xa8, 0xc7, 0xb2, 0x5b, 0xbe, 0x83, 0x5e, 0x01, + 0x9d, 0x82, 0x38, 0x0f, 0x19, 0x1e, 0xf2, 0xdd, 0x7a, 0x88, 0xfc, 0x15, + 0xe1, 0x37, 0x87, 0x9c, 0xc6, 0xeb, 0x9f, 0x42, 0xfc, 0x31, 0x8f, 0xdf, + 0xc4, 0xda, 0x0b, 0xb4, 0xe2, 0xcf, 0x63, 0x0c, 0xef, 0xf1, 0x61, 0x7c, + 0x1f, 0x46, 0x1e, 0xc8, 0xf2, 0x84, 0xe0, 0x3c, 0xb1, 0x1b, 0x71, 0x30, + 0x00, 0xee, 0xdf, 0x63, 0x6e, 0xcf, 0x13, 0x18, 0x57, 0xda, 0x83, 0xbc, + 0x70, 0x3f, 0xfa, 0x59, 0xd7, 0x28, 0xda, 0x01, 0xbc, 0xef, 0xc1, 0xd8, + 0xfe, 0x1c, 0x91, 0xcb, 0xdd, 0x2d, 0x3f, 0x20, 0x26, 0x56, 0x11, 0x2b, + 0x6b, 0x9c, 0x27, 0x38, 0x16, 0x79, 0x4f, 0x8b, 0xe0, 0x6f, 0x1b, 0x3a, + 0x78, 0x6f, 0x8b, 0xd8, 0x43, 0xce, 0x71, 0x82, 0x2a, 0x1b, 0x3b, 0xe5, + 0x0f, 0x5e, 0x0f, 0x38, 0xec, 0x34, 0xaf, 0xc5, 0x15, 0x0d, 0xf0, 0x59, + 0xb8, 0x31, 0x8d, 0xef, 0xc8, 0x85, 0x22, 0xb2, 0x1b, 0xa7, 0x53, 0x2e, + 0x6b, 0x6c, 0x8c, 0x29, 0x9c, 0xc6, 0x89, 0xc0, 0x3b, 0x73, 0x59, 0xce, + 0x5d, 0x8c, 0x25, 0x0a, 0x20, 0xbb, 0x19, 0x1a, 0x52, 0x2e, 0xf9, 0x23, + 0xd4, 0x00, 0x2e, 0x03, 0xf0, 0x59, 0x03, 0x7c, 0x56, 0xef, 0xe3, 0xb3, + 0xfa, 0xe7, 0xf2, 0x19, 0xb8, 0xaa, 0x03, 0xae, 0xea, 0x80, 0xab, 0x50, + 0x1b, 0xbc, 0x03, 0xec, 0xbf, 0xdd, 0xd9, 0x89, 0xe3, 0x98, 0xdf, 0x98, + 0xe7, 0xa6, 0xe8, 0xf2, 0xde, 0xff, 0x94, 0xe7, 0x8e, 0x83, 0x13, 0x6c, + 0xfa, 0xfe, 0xde, 0x7b, 0x73, 0xdd, 0x09, 0x70, 0x9d, 0xf5, 0xf9, 0x5c, + 0xd7, 0x64, 0xae, 0x33, 0x81, 0xbd, 0x26, 0x78, 0x40, 0x5f, 0xed, 0x9f, + 0xe7, 0x24, 0xe6, 0xe1, 0x3e, 0x33, 0xcb, 0xa5, 0x3a, 0x75, 0x81, 0x7b, + 0xc3, 0xe3, 0x79, 0x60, 0x73, 0x92, 0x72, 0xd1, 0x13, 0x66, 0x89, 0xac, + 0x49, 0xe0, 0x61, 0x75, 0x88, 0x8c, 0xd3, 0xb7, 0xf0, 0x8e, 0x7a, 0x00, + 0x71, 0x8e, 0x7f, 0x1b, 0xb9, 0x8e, 0x41, 0x70, 0x8d, 0x49, 0x85, 0x55, + 0x0b, 0xef, 0xda, 0xb6, 0x71, 0x87, 0x90, 0x6f, 0x8c, 0x9a, 0x3b, 0xf3, + 0x7b, 0x7e, 0xee, 0xf1, 0x98, 0x41, 0xd2, 0xd7, 0x5c, 0xc7, 0xd1, 0x5d, + 0xff, 0x1a, 0xb8, 0xe1, 0x7d, 0x8f, 0xf9, 0x2f, 0x06, 0x0a, 0x0a, 0x64, + 0xae, 0xca, 0xe3, 0x56, 0x8d, 0xe7, 0x6e, 0x3a, 0x88, 0x73, 0xe7, 0x35, + 0xe0, 0x87, 0x73, 0xe7, 0xf9, 0x2a, 0xd7, 0x7b, 0x69, 0x8c, 0xb6, 0x7a, + 0xf9, 0x9c, 0xa3, 0xb0, 0xdb, 0x82, 0x4c, 0xff, 0x58, 0xc6, 0x8b, 0x94, + 0xcf, 0x62, 0x4d, 0x06, 0xe6, 0xb1, 0xd6, 0x6c, 0x2a, 0xac, 0xb1, 0x5f, + 0x5c, 0xc8, 0x57, 0xc4, 0x1c, 0x6d, 0x6e, 0xe3, 0x83, 0x93, 0xbd, 0x0f, + 0x4c, 0xe6, 0x50, 0x03, 0xb1, 0x59, 0xc4, 0xbc, 0xd6, 0x96, 0x2e, 0xca, + 0x74, 0xb1, 0xbc, 0x57, 0x7e, 0x76, 0x4b, 0x9e, 0x79, 0x6d, 0xa2, 0xcc, + 0xfc, 0xc5, 0x76, 0x18, 0x8a, 0x4b, 0x07, 0x33, 0x2e, 0xad, 0x60, 0x3f, + 0x07, 0x55, 0x5c, 0xea, 0xde, 0xc3, 0x19, 0x9f, 0xee, 0x46, 0xcb, 0x7d, + 0x37, 0xb2, 0x38, 0x31, 0x61, 0x2f, 0xeb, 0x1d, 0x24, 0x03, 0x76, 0x45, + 0x6a, 0x4d, 0x7f, 0x93, 0x4b, 0x1e, 0x73, 0x04, 0xe3, 0x53, 0x71, 0x29, + 0xfa, 0x27, 0x60, 0x33, 0xf3, 0x02, 0xcb, 0xb1, 0xfc, 0x4e, 0x72, 0x7f, + 0x85, 0x9c, 0xd8, 0x41, 0x0e, 0x7d, 0x1b, 0x2c, 0xc3, 0xdc, 0x30, 0x8a, + 0xf1, 0x21, 0xf3, 0x02, 0x7c, 0xc6, 0xb2, 0xe5, 0x2c, 0x0e, 0x23, 0x7c, + 0xe3, 0xba, 0x97, 0xe3, 0x23, 0x20, 0xab, 0xc6, 0xeb, 0xe0, 0x9a, 0x98, + 0xf3, 0x22, 0xd7, 0xa1, 0x5c, 0x6f, 0xe6, 0xf5, 0xa9, 0x37, 0x35, 0x7b, + 0xb7, 0x5a, 0x53, 0xf4, 0xd7, 0x9a, 0xe8, 0xd8, 0xb1, 0xd6, 0xf4, 0xac, + 0xb4, 0xd6, 0xac, 0x58, 0x77, 0xaf, 0x35, 0x73, 0xd9, 0x7b, 0xd7, 0x9a, + 0x71, 0x87, 0xf7, 0x08, 0xb9, 0x54, 0xf0, 0x5a, 0xa8, 0x69, 0x66, 0x7c, + 0x11, 0xdd, 0xc6, 0x17, 0xd1, 0x69, 0xb7, 0x7c, 0x8e, 0x38, 0xa6, 0xdd, + 0x72, 0x8b, 0x6b, 0xa0, 0x0d, 0xae, 0x81, 0x0c, 0xe4, 0xd2, 0x7e, 0xce, + 0xc8, 0x7d, 0xc2, 0xbe, 0x1c, 0x04, 0x27, 0xb3, 0x1f, 0x8b, 0x19, 0x3f, + 0xa0, 0xf5, 0x3e, 0x05, 0x3f, 0xe4, 0xbc, 0xc2, 0x3e, 0xfb, 0x7f, 0xe2, + 0x15, 0xb2, 0x07, 0xc0, 0x0f, 0x36, 0xea, 0xcd, 0x46, 0x47, 0xd9, 0x02, + 0x5f, 0x48, 0x39, 0xe7, 0x33, 0xf6, 0x53, 0xbe, 0x50, 0x3e, 0x51, 0x78, + 0x2c, 0xd2, 0xbb, 0x3e, 0x63, 0x01, 0xe7, 0x23, 0x8f, 0x73, 0x22, 0xf3, + 0xef, 0x4d, 0xf9, 0xae, 0x17, 0xa2, 0x2f, 0xc2, 0x9e, 0x33, 0x0e, 0xe6, + 0xb5, 0x43, 0xeb, 0x36, 0xe4, 0x18, 0x0b, 0xe5, 0x3b, 0xce, 0x3d, 0xe9, + 0xf9, 0x84, 0x6b, 0xe1, 0xff, 0x16, 0x1b, 0x17, 0xef, 0x82, 0x8d, 0x37, + 0x33, 0x6c, 0xfc, 0xf2, 0x1e, 0xd8, 0xb8, 0xf8, 0x05, 0xb1, 0xe1, 0x3a, + 0x1f, 0xa3, 0x5e, 0x7a, 0xcf, 0x63, 0x7c, 0x48, 0xf9, 0xb1, 0xbf, 0x53, + 0x3e, 0x09, 0x6c, 0xe3, 0xd5, 0x9b, 0x32, 0xce, 0x72, 0x89, 0xfe, 0xd6, + 0xad, 0x5c, 0x32, 0xfe, 0x6a, 0x8a, 0x8b, 0xf1, 0xb7, 0xa4, 0x3c, 0xb7, + 0x03, 0x0e, 0xb8, 0x56, 0xbe, 0x0a, 0x1e, 0x68, 0xd1, 0xff, 0xa2, 0x56, + 0x66, 0xce, 0xae, 0xda, 0x47, 0xdb, 0xf9, 0xbe, 0xe7, 0x7b, 0x5e, 0xa0, + 0xb3, 0x62, 0x17, 0xfc, 0xb5, 0x9f, 0x5a, 0xaf, 0x9b, 0x7c, 0x7e, 0x00, + 0x1e, 0x1e, 0x37, 0x39, 0x56, 0x71, 0x56, 0xc4, 0x73, 0x7f, 0x3d, 0x0d, + 0x3c, 0xfa, 0xbc, 0x76, 0xb5, 0xee, 0x3e, 0xae, 0xff, 0x1e, 0x4a, 0x92, + 0x3b, 0xf2, 0xc8, 0xb6, 0x73, 0xb3, 0x81, 0x73, 0x73, 0x5d, 0xe9, 0xe0, + 0xb3, 0x55, 0xea, 0xbf, 0x13, 0xea, 0xac, 0x7c, 0x53, 0x9e, 0x53, 0xe7, + 0xe5, 0xd1, 0x02, 0x0d, 0xce, 0x67, 0x58, 0x61, 0x5f, 0x0c, 0xab, 0x7a, + 0x82, 0x31, 0xd5, 0x42, 0xbe, 0x5d, 0x82, 0x3f, 0x1a, 0x2a, 0x16, 0xb0, + 0xf6, 0xcc, 0x1f, 0x2d, 0xf8, 0xa3, 0x9e, 0xa4, 0x31, 0xf1, 0xe5, 0x9e, + 0x1d, 0xfe, 0x88, 0x7c, 0x6a, 0x2f, 0x9a, 0x38, 0x6f, 0x5f, 0x49, 0x54, + 0xfe, 0x5c, 0x68, 0xb5, 0xa9, 0xf9, 0x60, 0xed, 0x38, 0xd7, 0x6d, 0x5c, + 0x77, 0xcd, 0x2c, 0x55, 0xd1, 0xd7, 0xb3, 0x29, 0x84, 0x4f, 0xbe, 0x7d, + 0x90, 0x16, 0x8d, 0x1a, 0xe3, 0x17, 0xef, 0x09, 0x35, 0xc3, 0x83, 0xa8, + 0xa5, 0x92, 0xb1, 0x45, 0xbd, 0x36, 0x06, 0x1c, 0x35, 0x29, 0x80, 0x9d, + 0x01, 0x74, 0xcf, 0xb5, 0x6d, 0x7b, 0xb9, 0xcd, 0x67, 0xa4, 0x26, 0xf1, + 0x19, 0xbc, 0xdb, 0xbb, 0x0e, 0x7d, 0x03, 0xcf, 0xe0, 0xcc, 0xea, 0xc4, + 0xc0, 0xd5, 0xcb, 0x89, 0x45, 0xad, 0x12, 0xdf, 0x51, 0x30, 0x57, 0x96, + 0xa1, 0xe3, 0x99, 0x42, 0x8a, 0xcb, 0x32, 0xf4, 0x70, 0xcc, 0x10, 0xe6, + 0x63, 0xff, 0xe5, 0x58, 0x2b, 0xf7, 0xd5, 0xee, 0x85, 0xec, 0xbc, 0x4a, + 0xca, 0x07, 0xec, 0xdf, 0xd0, 0x7b, 0xbe, 0x90, 0xdf, 0xc7, 0xb4, 0x10, + 0xf3, 0x8d, 0x7d, 0x8c, 0x43, 0x0d, 0x78, 0xc3, 0x98, 0x84, 0xfb, 0x90, + 0x57, 0xf6, 0x21, 0x37, 0x97, 0x8a, 0xaa, 0x6d, 0x26, 0xc7, 0xb2, 0xf1, + 0xba, 0x1a, 0xc7, 0x39, 0x21, 0x4e, 0xd4, 0x59, 0x41, 0x8b, 0x3a, 0xe4, + 0x34, 0x7c, 0x9c, 0x81, 0x50, 0x5b, 0xac, 0x24, 0x9c, 0xcf, 0xf7, 0xd9, + 0xba, 0xe2, 0xb9, 0x4d, 0xc8, 0xe0, 0x79, 0x83, 0xf4, 0x86, 0xcf, 0xf7, + 0x07, 0xd9, 0xdd, 0x46, 0x89, 0x86, 0x21, 0x0f, 0xbb, 0xc6, 0xd8, 0xae, + 0xa0, 0xa1, 0x6a, 0x11, 0xd6, 0xbd, 0x5f, 0x4f, 0xef, 0x5c, 0x7e, 0x93, + 0xcd, 0x65, 0x83, 0x5f, 0x08, 0xe7, 0x1d, 0x9f, 0xf3, 0xda, 0xd7, 0x0c, + 0xba, 0x4e, 0x8a, 0x23, 0xc5, 0x37, 0x90, 0xef, 0x0e, 0x42, 0x26, 0x50, + 0xfc, 0x92, 0x9e, 0x19, 0x72, 0x99, 0x8a, 0xb1, 0x5d, 0xc7, 0x77, 0xcc, + 0xed, 0xef, 0x01, 0x62, 0xab, 0x9a, 0xcd, 0xd7, 0x8f, 0xd3, 0x4d, 0xe0, + 0x74, 0xb3, 0xb0, 0x75, 0xee, 0x28, 0x15, 0x30, 0x8e, 0x6d, 0x64, 0x2e, + 0x61, 0x99, 0x4f, 0xac, 0xed, 0x7a, 0x2a, 0x3b, 0xe8, 0xf8, 0x53, 0x9f, + 0x8e, 0x12, 0xaf, 0x4d, 0x34, 0xd2, 0xf3, 0xb3, 0xfa, 0x6b, 0xc0, 0xcf, + 0x38, 0x6f, 0x3c, 0xa0, 0x63, 0x1d, 0x5c, 0x7f, 0xd5, 0x55, 0x3f, 0x0e, + 0x56, 0xdb, 0xf4, 0xfe, 0x30, 0x9b, 0x67, 0x5f, 0x1a, 0x0f, 0x1e, 0xda, + 0x64, 0xb3, 0xcf, 0x76, 0x6b, 0x87, 0x79, 0x91, 0xd8, 0xbd, 0x19, 0x8d, + 0xf1, 0x66, 0xd4, 0x38, 0x07, 0xe3, 0x79, 0x0b, 0x1f, 0x8c, 0xd5, 0xcf, + 0xc7, 0xa8, 0xf5, 0x05, 0x31, 0xfa, 0x46, 0x9b, 0xb9, 0x22, 0xc5, 0x68, + 0xe3, 0x0e, 0x8c, 0xa2, 0x06, 0x2a, 0xe5, 0xf8, 0xe4, 0x78, 0xc9, 0xf1, + 0x99, 0x3f, 0xf3, 0xfd, 0x08, 0x38, 0x38, 0xe3, 0xb6, 0x18, 0xdc, 0x16, + 0xa9, 0x1c, 0xe7, 0x96, 0x23, 0x4a, 0xe3, 0x78, 0x19, 0x71, 0x1c, 0x19, + 0x9c, 0xf3, 0x38, 0x86, 0x59, 0x8e, 0xe3, 0x98, 0xe5, 0x46, 0x32, 0x39, + 0xb4, 0x88, 0xe7, 0x28, 0x8b, 0xe7, 0x16, 0x78, 0x37, 0xca, 0xe2, 0xb9, + 0x85, 0x18, 0x5e, 0xc9, 0xe2, 0xb9, 0x95, 0xc5, 0x33, 0xdf, 0xdb, 0x19, + 0x55, 0x95, 0x8b, 0x9d, 0x3a, 0x78, 0x6d, 0x45, 0xe9, 0x6c, 0x62, 0x9d, + 0xb0, 0xb1, 0x93, 0xc7, 0xc5, 0x1d, 0xf7, 0x5b, 0x58, 0xcf, 0xad, 0xbc, + 0x32, 0x8b, 0xbc, 0x72, 0x0e, 0x79, 0xa5, 0xdb, 0x77, 0xbf, 0x75, 0x56, + 0xe5, 0x95, 0x27, 0x8b, 0x79, 0x5e, 0xe9, 0x66, 0x79, 0xa5, 0xab, 0xf2, + 0xca, 0x13, 0x45, 0xce, 0x2b, 0x31, 0x05, 0xc5, 0xfe, 0xbc, 0x12, 0x6f, + 0xcb, 0x2b, 0xb9, 0x2c, 0xf7, 0xef, 0x94, 0x57, 0x72, 0x9f, 0x71, 0x6e, + 0xb1, 0x72, 0x5e, 0xbd, 0x2d, 0x9f, 0xe4, 0x63, 0xd8, 0x56, 0xe6, 0x25, + 0xe6, 0xe0, 0xb4, 0xae, 0xbf, 0x92, 0xe4, 0xb1, 0x74, 0x0c, 0xf3, 0xe0, + 0xbd, 0xb3, 0x53, 0x2c, 0xd9, 0x59, 0x2c, 0x0d, 0xa7, 0x32, 0x9d, 0xfe, + 0x78, 0x3a, 0x56, 0xdc, 0x1e, 0x4f, 0xb9, 0x9e, 0x3c, 0x9e, 0x52, 0x9d, + 0x1f, 0x1a, 0x65, 0xae, 0x07, 0x70, 0x96, 0x76, 0xfd, 0x39, 0xf4, 0x5e, + 0xe8, 0x4d, 0xa3, 0xae, 0x36, 0xe9, 0x6a, 0xce, 0x37, 0xea, 0xbe, 0x07, + 0x6d, 0x2f, 0xb7, 0xb5, 0xb8, 0xf5, 0xad, 0x8b, 0xda, 0xfa, 0x7d, 0xf0, + 0xc8, 0x79, 0xf5, 0xfd, 0x33, 0x79, 0xb5, 0x84, 0x33, 0xb0, 0x97, 0x8f, + 0x7b, 0x1d, 0xf3, 0xb9, 0xe2, 0x2c, 0x9e, 0x5e, 0xee, 0xdd, 0x82, 0xf9, + 0x8a, 0xc7, 0x7d, 0xff, 0x44, 0x0e, 0x41, 0x5d, 0xbe, 0x35, 0x96, 0xcf, + 0x38, 0x1e, 0xd6, 0xec, 0xd0, 0xa5, 0x6d, 0xe7, 0x9c, 0xf4, 0x7c, 0x83, + 0x75, 0xa3, 0x3e, 0xe1, 0x3a, 0x25, 0xfc, 0x8a, 0x4e, 0x2f, 0xd1, 0xb7, + 0x7c, 0xee, 0xd3, 0x69, 0xf6, 0x31, 0x29, 0x5f, 0x40, 0xcd, 0xf2, 0xf4, + 0xb6, 0x9a, 0xa5, 0x48, 0xe3, 0x07, 0xfa, 0xcf, 0x87, 0x37, 0xe5, 0xf8, + 0xa4, 0x7b, 0x36, 0xa0, 0x40, 0x9b, 0x5d, 0xe7, 0x5a, 0x76, 0xab, 0x76, + 0x25, 0x1a, 0xbd, 0x21, 0xf5, 0x49, 0xce, 0x85, 0x57, 0x33, 0x5f, 0xe1, + 0xdb, 0x99, 0x1b, 0xe0, 0xd6, 0x48, 0xdd, 0xf1, 0x06, 0xeb, 0x3c, 0x0f, + 0xbf, 0xa3, 0x4d, 0xb8, 0xbe, 0xb9, 0xdb, 0xbd, 0xab, 0x89, 0x7d, 0x71, + 0x9d, 0xa3, 0x06, 0xa9, 0xbb, 0x8b, 0x25, 0xdf, 0xfd, 0x59, 0x8b, 0x52, + 0x9e, 0x88, 0xfc, 0x05, 0xd8, 0x02, 0x9c, 0x8b, 0x45, 0xec, 0xcd, 0x24, + 0x78, 0xc9, 0x75, 0x0e, 0xe8, 0x42, 0x61, 0x7f, 0x19, 0xba, 0x8d, 0x03, + 0x5c, 0x3f, 0x7e, 0x2a, 0x97, 0x7b, 0x2a, 0x07, 0xfb, 0x8c, 0x91, 0x7a, + 0xb2, 0x5b, 0xe7, 0x36, 0x48, 0xf8, 0xb9, 0x80, 0x79, 0x9c, 0xbb, 0xe0, + 0xa7, 0x24, 0xa2, 0x33, 0x8e, 0x98, 0xed, 0x38, 0x62, 0xae, 0xa3, 0x03, + 0xdd, 0xb6, 0x4d, 0xbb, 0xb0, 0x27, 0xc8, 0xc1, 0xf4, 0x00, 0x6c, 0xb9, + 0xe0, 0x88, 0x3a, 0x6a, 0xc1, 0x1f, 0x18, 0xae, 0x78, 0x9a, 0x3e, 0xc1, + 0x1a, 0x6f, 0xc8, 0xf4, 0xde, 0xc5, 0x11, 0xd1, 0xd6, 0xdc, 0x37, 0x30, + 0x37, 0xdb, 0xc4, 0x31, 0xca, 0xf9, 0x72, 0x5e, 0x5b, 0x80, 0x8f, 0x8e, + 0xac, 0x6b, 0xe0, 0x35, 0xce, 0x97, 0x23, 0xd9, 0xfd, 0x12, 0xf6, 0x07, + 0xeb, 0xbf, 0x74, 0x47, 0xad, 0x99, 0xd7, 0x94, 0xe9, 0xdd, 0x69, 0x3c, + 0xc3, 0xf3, 0x13, 0x6c, 0x99, 0x98, 0xba, 0xa0, 0xce, 0x3d, 0xd3, 0xa8, + 0xf1, 0xb8, 0x95, 0xa8, 0x83, 0xf8, 0xae, 0x8b, 0x6b, 0x27, 0x89, 0xf8, + 0x4f, 0x9f, 0x63, 0x3e, 0x13, 0xcd, 0xb0, 0x0e, 0x3e, 0x1b, 0x71, 0xfc, + 0xfc, 0x1b, 0x2f, 0xf3, 0x0a, 0xbd, 0x68, 0x18, 0x00, 0x00, 0x00 }; static const u32 bnx2_TPAT_b09FwData[(0x0/4) + 1] = { 0x0 }; static const u32 bnx2_TPAT_b09FwRodata[(0x0/4) + 1] = { 0x0 }; static struct fw_info bnx2_tpat_fw_09 = { - /* Firmware version: 3.7.1 */ .ver_major = 0x3, - .ver_minor = 0x7, - .ver_fix = 0x1, + .ver_minor = 0x4, + .ver_fix = 0x3, .start_addr = 0x08000860, .text_addr = 0x08000800, - .text_len = 0x188c, + .text_len = 0x1864, .text_index = 0x0, .gz_text = bnx2_TPAT_b09FwText, .gz_text_len = sizeof(bnx2_TPAT_b09FwText), - .data_addr = 0x080020c0, + .data_addr = 0x08002080, .data_len = 0x0, .data_index = 0x0, .data = bnx2_TPAT_b09FwData, - .sbss_addr = 0x080020c8, - .sbss_len = 0x30, + .sbss_addr = 0x08002088, + .sbss_len = 0x2c, .sbss_index = 0x0, - .bss_addr = 0x08002100, + .bss_addr = 0x080020c0, .bss_len = 0x850, .bss_index = 0x0, @@ -3289,770 +3267,768 @@ static struct fw_info bnx2_tpat_fw_09 = { }; static u8 bnx2_TXP_b09FwText[] = { - 0xbd, 0x7c, 0x7d, 0x70, 0x1c, 0xe7, 0x79, 0xdf, 0xb3, 0xbb, 0x07, 0xe0, - 0x00, 0x82, 0xe0, 0x12, 0x39, 0x52, 0x27, 0x0a, 0xa6, 0x6e, 0x89, 0x3d, - 0x08, 0x32, 0x20, 0x71, 0xc5, 0x20, 0x36, 0x26, 0xb9, 0xca, 0xab, 0xbb, - 0x03, 0x78, 0x94, 0x31, 0x31, 0xc4, 0xc2, 0x16, 0xed, 0x70, 0xd4, 0xeb, - 0x01, 0xa4, 0x95, 0x54, 0x9e, 0xb2, 0xb6, 0xda, 0x72, 0x5a, 0x35, 0x3a, - 0x1f, 0xc0, 0x0f, 0x29, 0x47, 0x1c, 0x24, 0xc0, 0x84, 0xfe, 0x70, 0x93, - 0x13, 0x0e, 0x24, 0x64, 0xf7, 0x88, 0x93, 0xfc, 0xd9, 0x3f, 0x62, 0x0b, - 0x03, 0xd2, 0xb4, 0x5a, 0xbb, 0xb5, 0xda, 0x28, 0x13, 0xcf, 0xf4, 0x63, - 0x30, 0x14, 0xa5, 0x28, 0x71, 0xa7, 0x56, 0x9b, 0x4c, 0xa2, 0x36, 0x94, - 0xaf, 0xbf, 0xdf, 0xbb, 0xbb, 0xe0, 0x01, 0x22, 0x65, 0x51, 0x93, 0x14, - 0x33, 0x37, 0x77, 0xfb, 0xee, 0xbb, 0xef, 0xfb, 0x7c, 0xbd, 0xcf, 0xf3, - 0xfc, 0x9e, 0xf7, 0x5d, 0x44, 0x45, 0xda, 0xc4, 0xff, 0xdb, 0x8a, 0x4f, - 0xec, 0xd8, 0xf1, 0xc7, 0xef, 0xfd, 0xf8, 0xbd, 0xbf, 0x8a, 0x9f, 0xf7, - 0x89, 0xd6, 0x62, 0xf0, 0xe6, 0x5b, 0x86, 0x48, 0xf6, 0xcf, 0xe5, 0x43, - 0xff, 0xe1, 0x71, 0x33, 0x18, 0x9f, 0x1f, 0x09, 0xeb, 0x89, 0x57, 0x87, - 0x93, 0xb6, 0x84, 0x8d, 0x44, 0xfe, 0xa1, 0x71, 0x5b, 0xc4, 0xad, 0xf6, - 0xc5, 0x52, 0xf2, 0x6e, 0x3d, 0x1f, 0x09, 0x09, 0xdb, 0x3f, 0x92, 0xb8, - 0xf6, 0xe4, 0xf7, 0x3e, 0x6e, 0xbd, 0x5d, 0x36, 0x24, 0x6c, 0x26, 0xb2, - 0x62, 0xf6, 0x48, 0xb8, 0x0b, 0xcf, 0x7c, 0xf5, 0xae, 0x47, 0x0d, 0xe9, - 0x08, 0xc6, 0x7a, 0xab, 0xfe, 0xbd, 0xbb, 0x24, 0xbf, 0x2b, 0x51, 0x8f, - 0x85, 0x12, 0xef, 0xd6, 0xa7, 0x06, 0xc2, 0xa2, 0x27, 0xac, 0x68, 0xd2, - 0x88, 0xc8, 0xcb, 0x35, 0x53, 0x5e, 0xac, 0xc5, 0x64, 0xb2, 0x26, 0x1d, - 0xe9, 0xda, 0x8d, 0x68, 0xaa, 0xa3, 0xef, 0xbb, 0xf5, 0xe4, 0x40, 0x28, - 0x6b, 0x24, 0xa4, 0x23, 0x59, 0x93, 0xd1, 0x63, 0xc5, 0xd6, 0x87, 0x9b, - 0x12, 0x4f, 0xd6, 0x75, 0x5b, 0xb2, 0xa1, 0x84, 0x9d, 0xd7, 0xf5, 0xf6, - 0x41, 0xf3, 0x63, 0x68, 0xaf, 0x0e, 0x86, 0x26, 0x8b, 0xa6, 0x9c, 0x1b, - 0x68, 0x15, 0xdd, 0x0e, 0x4b, 0xb2, 0xd6, 0xfa, 0xb0, 0x9e, 0x88, 0x88, - 0x5b, 0xab, 0xd7, 0x8f, 0x39, 0xff, 0x64, 0xaf, 0xf9, 0xeb, 0xe1, 0xf0, - 0x64, 0x51, 0xde, 0x0e, 0xd9, 0x76, 0x74, 0x42, 0x7a, 0xcc, 0x9c, 0x68, - 0x92, 0xec, 0xef, 0x89, 0x1e, 0xc1, 0xf7, 0x78, 0x7f, 0xdc, 0x4c, 0xc9, - 0x16, 0x71, 0xcd, 0x6f, 0xae, 0x98, 0x3d, 0x5d, 0x59, 0x3d, 0x11, 0x96, - 0x74, 0x51, 0x13, 0xc3, 0x8e, 0xc8, 0x64, 0xc5, 0x96, 0xfc, 0x52, 0x87, - 0xe4, 0x2b, 0xf2, 0xc4, 0x94, 0xd3, 0x2e, 0x53, 0x4b, 0x47, 0x7d, 0x5d, - 0x44, 0xd0, 0xd6, 0x2b, 0xf9, 0x5a, 0x14, 0x9f, 0x9f, 0xf8, 0xfc, 0xea, - 0x22, 0x3b, 0x05, 0xcf, 0xf7, 0xa7, 0xdd, 0xea, 0xd7, 0xc2, 0x5e, 0xdb, - 0x7f, 0xd9, 0xe2, 0x7d, 0x83, 0xdf, 0x12, 0xf8, 0x2d, 0x85, 0x65, 0xcd, - 0x88, 0xca, 0xf7, 0xee, 0x8a, 0xc9, 0x54, 0x69, 0x0d, 0xb2, 0x89, 0xca, - 0x37, 0x6a, 0x11, 0x79, 0x49, 0xc9, 0x22, 0xa4, 0x0d, 0xa3, 0xcf, 0x64, - 0x69, 0x42, 0x3f, 0x51, 0xcc, 0x4b, 0xaa, 0x96, 0xd5, 0x0b, 0x73, 0x66, - 0x47, 0x72, 0x29, 0xa7, 0x4f, 0xce, 0x75, 0x76, 0xa4, 0x96, 0x26, 0xf4, - 0x42, 0x31, 0x0a, 0x39, 0x98, 0x1d, 0xa9, 0xf9, 0x08, 0xae, 0x3b, 0x3b, - 0x92, 0xf3, 0xd6, 0x0c, 0x26, 0x45, 0x9f, 0x68, 0x47, 0xaa, 0x64, 0x65, - 0x45, 0xba, 0x9d, 0x1f, 0x48, 0x57, 0x47, 0xaa, 0xf6, 0x5b, 0xfa, 0x8a, - 0xa9, 0x49, 0xe1, 0x1e, 0x31, 0xa3, 0x89, 0xb7, 0xeb, 0xb7, 0xdb, 0x9a, - 0x98, 0xf6, 0x3b, 0xf5, 0xed, 0x90, 0x4d, 0x6e, 0xb6, 0x15, 0xbc, 0x92, - 0x26, 0x53, 0x72, 0xf3, 0x7d, 0xe6, 0xaa, 0x34, 0x89, 0x1b, 0x09, 0xae, - 0xeb, 0xf5, 0xa4, 0xf3, 0x07, 0xe4, 0x91, 0xf2, 0xee, 0x18, 0x86, 0x5e, - 0x92, 0xa0, 0x39, 0xe9, 0xbc, 0x5b, 0xf7, 0x9e, 0x09, 0x63, 0xce, 0x50, - 0xc7, 0x50, 0xa9, 0x5e, 0x4f, 0x3b, 0x18, 0xdf, 0x09, 0x9e, 0x6d, 0x92, - 0x72, 0xc4, 0x2d, 0x4f, 0x3a, 0x96, 0xe1, 0xc9, 0x87, 0xba, 0xe7, 0xb5, - 0x0b, 0x7d, 0xe4, 0x25, 0x17, 0x91, 0x72, 0xc1, 0xf9, 0x98, 0x3c, 0xe5, - 0x44, 0xc1, 0x5f, 0x58, 0x4e, 0x39, 0xb0, 0x2f, 0xfb, 0xb8, 0x96, 0xac, - 0x59, 0xb1, 0xac, 0x3c, 0x2d, 0xc9, 0xf9, 0x6e, 0x33, 0x2d, 0x98, 0xdb, - 0xae, 0xdf, 0x99, 0x74, 0x30, 0x5f, 0xff, 0xff, 0xad, 0xbb, 0x11, 0x2b, - 0x5b, 0x96, 0x5e, 0x29, 0x94, 0xba, 0x9d, 0x1f, 0x43, 0x4f, 0x61, 0x5b, - 0xdc, 0x71, 0xdb, 0x84, 0xdc, 0xac, 0xde, 0x94, 0x51, 0x97, 0x07, 0x31, - 0x7f, 0xd2, 0xc6, 0xfd, 0x9a, 0x6c, 0xd3, 0xed, 0x66, 0x29, 0x98, 0x12, - 0x69, 0x93, 0xdd, 0x52, 0x98, 0x45, 0xbb, 0xe3, 0x76, 0xea, 0x78, 0x26, - 0x33, 0xc0, 0x36, 0xd1, 0x8c, 0x04, 0x75, 0x2c, 0xb2, 0x50, 0xed, 0xc5, - 0xfc, 0x71, 0xb7, 0x55, 0x33, 0x65, 0xcd, 0x0c, 0x49, 0xa5, 0x1a, 0x77, - 0xa3, 0x5a, 0xb3, 0x9c, 0x8a, 0xb7, 0x41, 0xa6, 0x51, 0x8c, 0x2d, 0x5f, - 0xd6, 0x13, 0xf1, 0x68, 0x0e, 0x4a, 0xa3, 0x1d, 0x4d, 0x81, 0x9e, 0x29, - 0x27, 0xab, 0xa5, 0x6a, 0x9f, 0xd3, 0x92, 0x4b, 0x87, 0xb4, 0xfd, 0x4b, - 0xe8, 0x53, 0xfb, 0x1f, 0xbe, 0x0d, 0x44, 0x41, 0x9b, 0x8e, 0x67, 0xd9, - 0x0e, 0x9a, 0x15, 0xed, 0x68, 0x83, 0x2e, 0x57, 0xc6, 0x22, 0x1d, 0x49, - 0xa5, 0x4b, 0xd2, 0xa6, 0x4b, 0x6e, 0x54, 0x93, 0x4e, 0xdb, 0x95, 0xf0, - 0xaf, 0x41, 0x9f, 0xf3, 0xd0, 0xe5, 0x7c, 0x4c, 0x4e, 0x94, 0x24, 0xa2, - 0x0b, 0xe7, 0xca, 0xea, 0x95, 0x2a, 0xed, 0x01, 0xba, 0x85, 0xee, 0x0b, - 0x55, 0x3e, 0x0b, 0x1d, 0x96, 0xd2, 0x90, 0x4f, 0x06, 0x73, 0x1f, 0xd4, - 0x1e, 0xac, 0x8c, 0x69, 0x19, 0xd8, 0x49, 0x61, 0xb6, 0x0f, 0xba, 0xb3, - 0x62, 0x6b, 0xb2, 0x4d, 0x0a, 0xb6, 0x1d, 0xfb, 0xac, 0xb4, 0xcb, 0xa9, - 0x79, 0x5b, 0x4e, 0xcc, 0xc3, 0x1e, 0x4d, 0xcb, 0x5c, 0x94, 0xae, 0xec, - 0x96, 0x44, 0x87, 0x3c, 0x3d, 0x6b, 0x65, 0xca, 0xd2, 0xed, 0xbe, 0x81, - 0xfb, 0xb9, 0x33, 0xd4, 0xa9, 0xe4, 0x53, 0x8e, 0x21, 0x59, 0x93, 0x76, - 0x7d, 0x9b, 0x26, 0x6d, 0xf5, 0x27, 0x93, 0x8e, 0x15, 0xa5, 0xcd, 0xa6, - 0x3e, 0xdd, 0x6d, 0x1e, 0x10, 0xcb, 0xcc, 0x50, 0xfe, 0x4e, 0x1f, 0xf4, - 0xf0, 0xbf, 0x29, 0x7b, 0x8c, 0x45, 0x1d, 0xf7, 0x45, 0x4f, 0x41, 0x97, - 0x59, 0xa5, 0xe3, 0x0e, 0xcc, 0x1f, 0xf2, 0x6d, 0x87, 0x6b, 0xe2, 0x6e, - 0xcd, 0x93, 0x43, 0x87, 0xcc, 0x54, 0xda, 0xa5, 0x00, 0x1d, 0x16, 0xc4, - 0x96, 0xc2, 0xd2, 0x5e, 0xbf, 0xdd, 0xc6, 0x7a, 0xf9, 0x53, 0x5d, 0xda, - 0x8e, 0x6b, 0x87, 0x6a, 0x3f, 0xd7, 0x7c, 0xfb, 0x81, 0xfd, 0x85, 0xc5, - 0x1d, 0x0d, 0xcb, 0xf9, 0x9a, 0x67, 0x7f, 0x0b, 0xf0, 0x3d, 0xae, 0xe9, - 0xc2, 0x96, 0xde, 0x5c, 0xef, 0x73, 0xbe, 0xd6, 0x85, 0x67, 0xc3, 0x72, - 0xa2, 0xc6, 0xfe, 0x79, 0xd8, 0x58, 0x58, 0x96, 0xef, 0x6a, 0x97, 0x2c, - 0xda, 0x0b, 0xf3, 0xe2, 0x26, 0x1d, 0x1d, 0xcf, 0x74, 0x80, 0x97, 0x9d, - 0xf8, 0xb4, 0xc9, 0x78, 0xa5, 0xc5, 0xe5, 0x7a, 0x1d, 0xaf, 0x51, 0xff, - 0xf8, 0x2e, 0x05, 0x36, 0x40, 0xf9, 0xb2, 0x9d, 0xcf, 0xb1, 0xdd, 0x44, - 0x7b, 0x63, 0x1b, 0x6d, 0x7b, 0x1b, 0x65, 0xda, 0xcb, 0x35, 0x9a, 0x2b, - 0xc5, 0xcd, 0x43, 0xfc, 0xae, 0xd1, 0x1e, 0x1a, 0x6d, 0x21, 0x84, 0xfe, - 0xd0, 0x63, 0x05, 0x73, 0xcd, 0x5e, 0xab, 0x37, 0x0d, 0xe0, 0xda, 0xfe, - 0x1d, 0xf0, 0xc9, 0xb9, 0x43, 0xa0, 0x4b, 0x97, 0x6c, 0x45, 0xd1, 0x16, - 0xa3, 0x0d, 0x78, 0x7c, 0x74, 0xc9, 0xe4, 0x7c, 0x7b, 0x47, 0x7a, 0x9e, - 0xed, 0xc9, 0xa8, 0x01, 0x3e, 0xc7, 0x1d, 0x59, 0x99, 0x72, 0xf4, 0xee, - 0x10, 0xe8, 0x9a, 0xc0, 0x82, 0x03, 0x1f, 0x3e, 0x8d, 0x2b, 0xb8, 0xdf, - 0x29, 0xe3, 0x4b, 0xec, 0xcb, 0x39, 0x0a, 0xdb, 0x75, 0x49, 0x80, 0x36, - 0x7c, 0x6c, 0x0b, 0xf7, 0x5b, 0x31, 0x4f, 0x3b, 0x6c, 0x67, 0x9a, 0xba, - 0xfb, 0x44, 0xd2, 0xe9, 0x94, 0xec, 0x7a, 0x5f, 0x81, 0xdd, 0xb1, 0x7f, - 0xef, 0xa6, 0xbe, 0x90, 0xef, 0x12, 0xc6, 0x9c, 0x6f, 0x85, 0x0c, 0xd9, - 0xae, 0x83, 0xe6, 0x16, 0xd0, 0x00, 0x1f, 0x6c, 0x77, 0x63, 0x3d, 0xb4, - 0x60, 0xfc, 0x2d, 0xe0, 0xa9, 0x55, 0x26, 0x66, 0x3b, 0xa1, 0x0b, 0x13, - 0x7d, 0xc3, 0xf2, 0x74, 0xc9, 0x82, 0x0d, 0xb0, 0x3f, 0x74, 0x30, 0x6f, - 0x45, 0x2b, 0xe2, 0xca, 0x94, 0xd3, 0x02, 0xfb, 0xaa, 0xd7, 0x8f, 0xc0, - 0x3e, 0xbe, 0xae, 0xfc, 0x45, 0x9f, 0x39, 0xa4, 0x49, 0xbe, 0x25, 0xf1, - 0x7d, 0xd0, 0x63, 0x3d, 0x2a, 0xc2, 0xeb, 0xbd, 0x1a, 0xd7, 0x2c, 0xe4, - 0xc8, 0xb9, 0xe1, 0x93, 0x76, 0x42, 0x86, 0xf4, 0x5b, 0x5d, 0xb0, 0xe7, - 0xa8, 0xf2, 0x27, 0x43, 0x37, 0xf4, 0x27, 0xd6, 0x68, 0x19, 0x73, 0x15, - 0x96, 0x42, 0xf4, 0x61, 0x83, 0x58, 0xae, 0xb2, 0x15, 0x6b, 0x6f, 0x52, - 0xd9, 0xc7, 0x4f, 0xc8, 0x6f, 0xfd, 0x53, 0x0e, 0xe9, 0x22, 0xbf, 0x2e, - 0x9e, 0xa5, 0x0d, 0x5a, 0xc7, 0x5d, 0x35, 0xff, 0x4f, 0xfc, 0xf9, 0x3d, - 0xda, 0x0b, 0xa5, 0x0e, 0x2d, 0xa5, 0x68, 0x08, 0xc6, 0x11, 0x59, 0x3d, - 0xd3, 0x6d, 0x3e, 0x08, 0x1b, 0xa6, 0x9f, 0x5a, 0xbd, 0x40, 0x1d, 0x63, - 0x8c, 0x01, 0xea, 0xd8, 0x54, 0xf4, 0x25, 0xe7, 0xb9, 0xf6, 0xa4, 0xcb, - 0x10, 0xfa, 0x08, 0xf8, 0x5c, 0xac, 0xc5, 0x49, 0x7f, 0x2d, 0xe6, 0xaa, - 0xb4, 0xbf, 0xc7, 0xf1, 0xac, 0x2e, 0x43, 0x71, 0xfa, 0x87, 0xa7, 0x25, - 0x05, 0x1f, 0x09, 0x3d, 0x4a, 0x05, 0xbc, 0x2c, 0x94, 0x1a, 0xfd, 0x16, - 0x6c, 0xab, 0xff, 0xaf, 0xeb, 0x9e, 0x3f, 0xa4, 0x6f, 0xa0, 0xaf, 0x29, - 0x98, 0x3a, 0x24, 0x87, 0xc8, 0xe0, 0x42, 0x37, 0x4e, 0xd2, 0xb0, 0x32, - 0x59, 0xc6, 0x1c, 0xbb, 0x2e, 0xf6, 0x7d, 0x82, 0x48, 0xda, 0xcb, 0xf8, - 0xb7, 0x2f, 0xf0, 0x4f, 0xab, 0xd5, 0x40, 0x17, 0xd4, 0x2b, 0xf5, 0x10, - 0xf8, 0x88, 0x90, 0x5c, 0x84, 0xef, 0x9a, 0x2a, 0xb5, 0xcb, 0x0a, 0x68, - 0xba, 0x54, 0x0d, 0x6c, 0xcd, 0xf0, 0x6d, 0x8d, 0xcf, 0xb4, 0xe3, 0xf9, - 0x10, 0xfc, 0x9a, 0xe4, 0x8d, 0x04, 0x7e, 0x17, 0x39, 0x26, 0xdb, 0x02, - 0x3b, 0xe7, 0x9a, 0xb1, 0xdc, 0xb2, 0x34, 0x4b, 0x26, 0x8e, 0xf8, 0x31, - 0xaf, 0x63, 0xae, 0x2e, 0xf8, 0xf2, 0x90, 0x1c, 0x2d, 0x45, 0xe4, 0xf3, - 0x25, 0xf2, 0x95, 0xd6, 0x52, 0xd0, 0x5b, 0x72, 0xbe, 0x0e, 0x9d, 0x0f, - 0xc3, 0xe7, 0x65, 0xb4, 0x21, 0xf8, 0x9f, 0x03, 0x95, 0xcf, 0x69, 0xe9, - 0xa5, 0xac, 0x36, 0x5c, 0x3b, 0xa4, 0x65, 0x96, 0xc6, 0xb4, 0xfd, 0x0d, - 0xbe, 0x48, 0xb4, 0xf7, 0xf7, 0x45, 0x4f, 0xcd, 0x72, 0xce, 0x6e, 0xe7, - 0xc6, 0xbe, 0xe8, 0xd7, 0xf5, 0x46, 0x5f, 0xd4, 0x0d, 0x5f, 0x94, 0x81, - 0x2f, 0x1a, 0xbe, 0x65, 0x5f, 0x34, 0xa2, 0xdf, 0xd8, 0x17, 0x1d, 0xd4, - 0xaf, 0xfb, 0x22, 0xc6, 0x9e, 0x15, 0x5c, 0x9b, 0xb2, 0x67, 0x5f, 0x20, - 0xe7, 0x28, 0xfc, 0xf0, 0x16, 0xc8, 0xba, 0x8d, 0x6b, 0x27, 0x56, 0x80, - 0xdd, 0x4f, 0x60, 0xae, 0xdf, 0x86, 0xbd, 0xef, 0x89, 0xdb, 0xe6, 0x43, - 0x6a, 0xde, 0xf7, 0xea, 0x7c, 0x68, 0x5d, 0xe7, 0xa4, 0xf1, 0x97, 0xea, - 0xdc, 0xf5, 0x74, 0x4e, 0x5d, 0xb7, 0xca, 0x11, 0x35, 0x6f, 0x5d, 0x42, - 0xf7, 0x09, 0xbc, 0x8a, 0x3c, 0x60, 0x24, 0x2c, 0x8c, 0xa7, 0x63, 0x7e, - 0xea, 0x2b, 0x0e, 0x1a, 0x04, 0xfa, 0x6d, 0x57, 0xbe, 0x68, 0x3f, 0xf4, - 0xbe, 0x5a, 0xbd, 0x35, 0x5d, 0x65, 0x1a, 0x74, 0xf5, 0xe0, 0x06, 0x5d, - 0xb5, 0x48, 0x7f, 0x3c, 0xd0, 0xd1, 0x36, 0x49, 0xc6, 0xa9, 0xb3, 0x5b, - 0xd1, 0xd5, 0xb9, 0xbf, 0x25, 0x5d, 0x7d, 0xf7, 0x26, 0xba, 0xfa, 0xde, - 0x26, 0x5d, 0xd9, 0xe6, 0x33, 0x1a, 0xc7, 0x66, 0xfc, 0xa0, 0x3f, 0xaa, - 0xdf, 0x39, 0xce, 0xfc, 0xa1, 0xc6, 0x35, 0x1d, 0xe4, 0x1d, 0x5c, 0xcf, - 0x2f, 0xd7, 0x0d, 0xdb, 0x86, 0xec, 0xb8, 0xa6, 0x29, 0x37, 0xcb, 0xfc, - 0x14, 0xe9, 0x47, 0xec, 0x18, 0x47, 0xac, 0xf1, 0x68, 0x68, 0x96, 0xf2, - 0x76, 0xaf, 0xff, 0x78, 0xa9, 0xfe, 0x73, 0x3d, 0xf1, 0x0b, 0xe4, 0x95, - 0xb6, 0x1f, 0x07, 0xc2, 0xf2, 0x85, 0x8a, 0x95, 0x75, 0xb5, 0x76, 0xc9, - 0xef, 0x40, 0xec, 0x29, 0xd1, 0x7f, 0xed, 0xbc, 0x49, 0x8c, 0xee, 0xf2, - 0x63, 0xf4, 0x9f, 0x81, 0x56, 0xe6, 0x57, 0xff, 0xe6, 0xdd, 0x95, 0x08, - 0xbf, 0xe3, 0xe6, 0x41, 0xf9, 0x2c, 0x79, 0x44, 0xbc, 0x67, 0xdc, 0xb7, - 0x99, 0xf3, 0xe4, 0x43, 0x89, 0x36, 0xc9, 0x6f, 0xe7, 0x7a, 0xa4, 0x9f, - 0xa3, 0xef, 0x6a, 0xf6, 0xe9, 0x0e, 0x72, 0x24, 0xfe, 0xb5, 0x18, 0x60, - 0x19, 0x7d, 0x90, 0x0f, 0x95, 0xc8, 0xc7, 0xbb, 0xbe, 0x3d, 0x31, 0x57, - 0x90, 0x26, 0xcf, 0x37, 0x8c, 0x20, 0x17, 0xa0, 0x1d, 0x04, 0x3a, 0xa7, - 0xbe, 0x99, 0x23, 0x48, 0x4c, 0xb7, 0x99, 0x23, 0x88, 0x69, 0x24, 0x0e, - 0x6a, 0x2e, 0x74, 0xef, 0x42, 0xf7, 0x2e, 0x74, 0xef, 0x42, 0xf7, 0xc9, - 0xda, 0x71, 0xdc, 0x53, 0x79, 0x08, 0x68, 0xf1, 0xc6, 0x4f, 0x7b, 0xe3, - 0x83, 0xce, 0x9d, 0x92, 0x53, 0x3a, 0x21, 0xbf, 0xc8, 0x35, 0x94, 0xbf, - 0x1e, 0xd6, 0x3c, 0x7f, 0xcd, 0xf1, 0x32, 0x78, 0xfe, 0x7e, 0xe4, 0x73, - 0xae, 0xae, 0xdb, 0xd7, 0x65, 0x32, 0xd5, 0x20, 0x93, 0xc9, 0x2a, 0x65, - 0xc4, 0xfe, 0xf4, 0xb9, 0x13, 0xfa, 0xc2, 0xba, 0x5c, 0x46, 0x40, 0x43, - 0x0b, 0x79, 0xf7, 0xf9, 0xe0, 0xf8, 0x9d, 0xfe, 0xf8, 0xbf, 0x81, 0x31, - 0xe9, 0x5f, 0x6f, 0x34, 0x2f, 0xe7, 0x64, 0xce, 0xf8, 0x7e, 0xfc, 0x20, - 0x67, 0xc6, 0x1a, 0x78, 0x69, 0x3d, 0x9f, 0x8e, 0x21, 0x9f, 0x7e, 0x07, - 0xb9, 0x74, 0xbd, 0xce, 0x38, 0x55, 0x40, 0x9e, 0x9b, 0x76, 0xb8, 0xae, - 0x6f, 0x65, 0xdd, 0x6e, 0x58, 0xb3, 0x66, 0xd2, 0xe0, 0xb8, 0x61, 0xf1, - 0xc6, 0xe4, 0xfd, 0x16, 0xe4, 0x82, 0xef, 0xe0, 0x37, 0x7d, 0x72, 0x90, - 0xe7, 0xb1, 0x0f, 0x9f, 0x7f, 0x15, 0x73, 0xf7, 0x03, 0xcf, 0xf4, 0xca, - 0x77, 0x6a, 0xb6, 0x7c, 0x1b, 0x98, 0xe6, 0x5b, 0xc8, 0x2d, 0xbe, 0x59, - 0x0b, 0x72, 0xfb, 0xbd, 0x30, 0x75, 0xe6, 0xf7, 0x12, 0xde, 0x69, 0x13, - 0x57, 0xe5, 0xf7, 0x7f, 0xda, 0x96, 0xad, 0x11, 0xfc, 0xfe, 0x95, 0x84, - 0x6c, 0xeb, 0xc4, 0xf7, 0xf6, 0x04, 0x4c, 0x27, 0xc1, 0xd8, 0xa8, 0x35, - 0xc4, 0x46, 0xd1, 0xd2, 0xe0, 0x71, 0x0a, 0xe3, 0xa5, 0xc1, 0xf7, 0x67, - 0x6a, 0x61, 0x2d, 0x35, 0xbb, 0x1b, 0x98, 0x24, 0xc8, 0x71, 0x91, 0x47, - 0x99, 0xab, 0xdb, 0x43, 0xf2, 0x36, 0x78, 0x4a, 0x82, 0x76, 0x17, 0x39, - 0xc0, 0x3f, 0xc5, 0x5c, 0xd6, 0x4f, 0x3f, 0x2d, 0xff, 0xda, 0xcf, 0xc3, - 0x9b, 0x64, 0x4e, 0xf1, 0xc8, 0x76, 0xc9, 0xfc, 0xcb, 0x9e, 0xeb, 0xed, - 0xcf, 0xae, 0xb7, 0xc7, 0x32, 0xbf, 0xb1, 0xde, 0x7e, 0x35, 0xe4, 0xe1, - 0x95, 0x41, 0x6d, 0xb4, 0xf6, 0x2f, 0x8c, 0x00, 0xeb, 0x14, 0x66, 0x7b, - 0x31, 0xd7, 0x36, 0x99, 0xb4, 0xdf, 0x06, 0xf6, 0xb2, 0x63, 0x39, 0xac, - 0xaf, 0xa7, 0x36, 0xf9, 0xfa, 0x36, 0xf8, 0x8f, 0xd3, 0xb3, 0xd6, 0x20, - 0xfd, 0x47, 0x1c, 0x6b, 0x29, 0xf9, 0x1e, 0xff, 0xf1, 0x6d, 0xa3, 0xd1, - 0x7f, 0x18, 0xf0, 0x1f, 0xfb, 0xdf, 0xc7, 0x7f, 0x3c, 0xf5, 0x1e, 0xff, - 0xa1, 0xc1, 0x2e, 0xe8, 0x3f, 0x7e, 0x68, 0x04, 0xfe, 0xa3, 0xb0, 0xc1, - 0x7f, 0x04, 0xfa, 0xb0, 0x55, 0xee, 0xe8, 0xfd, 0x26, 0xfe, 0x6c, 0xf3, - 0x31, 0xa7, 0x84, 0x43, 0x09, 0x37, 0x33, 0x65, 0xef, 0x92, 0x26, 0xac, - 0xd1, 0x97, 0x6b, 0x03, 0xf0, 0x25, 0xbf, 0x0f, 0x9c, 0x66, 0x39, 0x4c, - 0x44, 0x9a, 0x12, 0xd4, 0xcd, 0x48, 0x2c, 0x69, 0xbf, 0x90, 0x59, 0xa8, - 0xbe, 0x90, 0x39, 0xa7, 0x74, 0x35, 0x61, 0x79, 0x18, 0xf8, 0x09, 0x0b, - 0x18, 0x18, 0xcf, 0x87, 0x80, 0x21, 0xd8, 0xde, 0x6e, 0x26, 0x91, 0xa3, - 0x54, 0xaa, 0x2b, 0x99, 0x02, 0x3e, 0x53, 0xaa, 0xef, 0x58, 0x8c, 0x7d, - 0x5b, 0x12, 0xe5, 0xd8, 0x9f, 0xe2, 0xbb, 0x39, 0x31, 0x67, 0x5d, 0xb6, - 0x39, 0xee, 0x6b, 0xb1, 0x73, 0x6a, 0x8c, 0x90, 0x14, 0xd4, 0xb3, 0x5f, - 0xb5, 0xf8, 0xec, 0x29, 0xf8, 0xf8, 0x93, 0x55, 0x53, 0x4e, 0x54, 0xd7, - 0x32, 0x39, 0x7c, 0x88, 0x6d, 0x5e, 0x2e, 0xf1, 0xfe, 0xb7, 0x70, 0x3f, - 0x24, 0xcc, 0x3d, 0x3e, 0x8f, 0x3e, 0x47, 0xd1, 0xe7, 0x48, 0x35, 0xc0, - 0x8d, 0xbc, 0xef, 0x66, 0x52, 0xb8, 0x7f, 0xa4, 0xe8, 0x66, 0xd2, 0x45, - 0xe6, 0x39, 0x7d, 0xd1, 0x13, 0x90, 0x67, 0x16, 0xb1, 0xdd, 0x15, 0xab, - 0x37, 0x2f, 0x8f, 0xb5, 0x0e, 0x23, 0xaf, 0x3e, 0x8f, 0x98, 0xe3, 0x8e, - 0x59, 0x4e, 0x19, 0xcc, 0x4d, 0x95, 0xee, 0x90, 0xc2, 0x0c, 0x62, 0x8c, - 0x73, 0x0f, 0x73, 0xed, 0x8c, 0x1e, 0x77, 0xe0, 0x13, 0x06, 0x80, 0x27, - 0xbb, 0x81, 0x85, 0xef, 0x92, 0x15, 0xd3, 0x8a, 0x0e, 0x03, 0x03, 0xa7, - 0x42, 0xe8, 0xd3, 0x7b, 0x9b, 0x64, 0xa3, 0x94, 0xf5, 0x0e, 0xf8, 0x07, - 0x4d, 0x5a, 0xec, 0x46, 0x5f, 0xf5, 0x17, 0x10, 0x2f, 0x92, 0xdf, 0x36, - 0xb6, 0xb7, 0xfa, 0x3a, 0xd9, 0x22, 0xab, 0xef, 0xe9, 0xf7, 0x37, 0x0d, - 0xfd, 0x1a, 0xdb, 0x35, 0x4d, 0xd0, 0x7f, 0x0d, 0x34, 0x84, 0xe2, 0x90, - 0x3f, 0x78, 0x68, 0x82, 0x9d, 0x5c, 0x06, 0x3f, 0xf4, 0x9b, 0x85, 0x32, - 0xe3, 0xa4, 0x21, 0x65, 0x13, 0xf7, 0xaa, 0xf5, 0xfa, 0x82, 0x0d, 0x5a, - 0x2f, 0x90, 0xde, 0xb0, 0x0c, 0x57, 0x7b, 0xc4, 0x5d, 0xa4, 0x1c, 0x2c, - 0xac, 0x8e, 0x5d, 0x6d, 0xa9, 0x79, 0xcb, 0xcd, 0x63, 0x44, 0xe3, 0x42, - 0x57, 0x5b, 0x12, 0x71, 0x51, 0xbf, 0x10, 0x6b, 0x4b, 0xc1, 0x1f, 0x18, - 0x17, 0x6e, 0x6f, 0x4b, 0xcf, 0x92, 0x2e, 0x03, 0x71, 0xf1, 0x4e, 0xe0, - 0xc2, 0xba, 0x7c, 0x0d, 0xb9, 0x4f, 0xa1, 0x17, 0x31, 0x03, 0xab, 0x44, - 0x07, 0xdd, 0x79, 0x53, 0xc2, 0x6d, 0x89, 0x79, 0xd0, 0xd7, 0xdf, 0x9a, - 0x9c, 0xdd, 0x82, 0x3e, 0x06, 0xda, 0x7b, 0x88, 0x21, 0x1b, 0xda, 0xed, - 0x36, 0xf8, 0x5f, 0xf8, 0x3a, 0x09, 0x27, 0x07, 0xda, 0x31, 0xfe, 0xd9, - 0x10, 0x73, 0x87, 0x70, 0x7c, 0xbd, 0xfd, 0xcb, 0x5e, 0x7b, 0x2f, 0x68, - 0xe1, 0x73, 0xcc, 0x21, 0x25, 0x3c, 0x3e, 0x60, 0x82, 0x06, 0xf6, 0x8d, - 0xa8, 0xbe, 0xe9, 0x79, 0xda, 0x80, 0x9b, 0x59, 0xb0, 0x77, 0x4b, 0x6a, - 0x6e, 0xa7, 0x0c, 0xcf, 0x75, 0xca, 0xfe, 0x39, 0xe6, 0xbc, 0xc4, 0xc0, - 0x60, 0x05, 0x39, 0xa9, 0x7e, 0x81, 0xb9, 0x80, 0x15, 0x3d, 0x2a, 0xdd, - 0xd1, 0xcf, 0x63, 0x1d, 0x8c, 0xdb, 0xf1, 0xd8, 0x24, 0xd6, 0x58, 0x48, - 0x8d, 0x13, 0x0d, 0xe6, 0xa4, 0x8d, 0x6e, 0x98, 0x37, 0x3d, 0x7f, 0xb3, - 0x71, 0xb1, 0x70, 0x2e, 0x44, 0x37, 0x8d, 0xfb, 0x3f, 0xfd, 0x71, 0x4d, - 0x8c, 0xdb, 0x85, 0x31, 0xc9, 0xe3, 0xed, 0xad, 0x43, 0xb3, 0xe2, 0xb6, - 0x80, 0xbe, 0x74, 0x7c, 0x97, 0x4c, 0x62, 0x9c, 0x93, 0x73, 0xf4, 0x85, - 0xb2, 0x13, 0x9f, 0xfe, 0x26, 0x89, 0xf7, 0x2e, 0x21, 0x2f, 0x1e, 0x52, - 0x63, 0x78, 0x39, 0xaa, 0x7e, 0x21, 0x01, 0x5c, 0xf3, 0x51, 0xd0, 0xc3, - 0x98, 0x4c, 0x9e, 0x43, 0xe0, 0x37, 0x81, 0x75, 0x48, 0x3c, 0xce, 0xf5, - 0x8d, 0xdf, 0x4b, 0xd1, 0xd6, 0xd4, 0x6c, 0x33, 0xd6, 0x9d, 0xec, 0x36, - 0x54, 0xac, 0xa0, 0x5e, 0xec, 0xd6, 0x64, 0x49, 0xd1, 0xdd, 0x9a, 0x2a, - 0x51, 0x46, 0x4e, 0x6b, 0xba, 0x44, 0x19, 0x09, 0xe8, 0x71, 0xe0, 0x63, - 0x43, 0x12, 0xdb, 0x4e, 0x3d, 0x1e, 0x43, 0xbf, 0x95, 0x10, 0xf3, 0xfe, - 0xa4, 0xcd, 0xdf, 0xc0, 0x2b, 0x17, 0x8e, 0xa3, 0x2f, 0x7f, 0xdf, 0x8b, - 0x71, 0xbb, 0x7b, 0x0b, 0xd2, 0xdc, 0x7b, 0x04, 0x7e, 0x42, 0x1f, 0x00, - 0xee, 0x50, 0x76, 0x5e, 0x07, 0x26, 0xdb, 0x0b, 0x7e, 0xb0, 0x36, 0xe2, - 0xb6, 0x4c, 0xcc, 0x50, 0xae, 0x72, 0x1b, 0x78, 0x00, 0xff, 0x71, 0xf8, - 0x16, 0xf2, 0xc0, 0xb9, 0x05, 0x76, 0xbf, 0x2c, 0xb9, 0x99, 0xb0, 0xc2, - 0x3e, 0xae, 0xc9, 0xf9, 0x35, 0x4d, 0x4f, 0xb4, 0x41, 0xc7, 0xe4, 0x6d, - 0x0a, 0xb4, 0x3d, 0x0e, 0x3f, 0x6c, 0xa9, 0x9c, 0xdb, 0x40, 0xff, 0x42, - 0x69, 0x50, 0x4f, 0x15, 0x49, 0xbf, 0x6f, 0x7b, 0xda, 0x0a, 0x7c, 0x8a, - 0xaa, 0x63, 0x21, 0xb7, 0x4b, 0xc0, 0x8f, 0x0c, 0xca, 0xf7, 0xe1, 0x4b, - 0xbe, 0x5b, 0x73, 0xe0, 0xff, 0xfb, 0xe1, 0xff, 0x7b, 0xe1, 0xff, 0x6d, - 0xf8, 0xff, 0x18, 0xfc, 0x7f, 0x17, 0xfc, 0x7f, 0x94, 0xbe, 0x5f, 0x4e, - 0xd6, 0xf2, 0xb0, 0xb1, 0x15, 0xf8, 0x41, 0x33, 0xec, 0xd6, 0x22, 0xe1, - 0x64, 0x2d, 0x1a, 0x4e, 0xd5, 0x42, 0xe0, 0xe9, 0x30, 0xe7, 0x04, 0x7f, - 0xf9, 0xd6, 0xa1, 0x52, 0x3f, 0xe2, 0x8a, 0x0b, 0xbf, 0x94, 0x86, 0xdf, - 0x77, 0x80, 0x7f, 0xf3, 0xb2, 0x3a, 0x13, 0xc3, 0x33, 0x75, 0x49, 0x3b, - 0x4d, 0x32, 0x69, 0x3a, 0x18, 0x63, 0xbb, 0xb2, 0x53, 0x23, 0xb1, 0xab, - 0x09, 0x76, 0x2a, 0xb9, 0x22, 0xe3, 0x73, 0x17, 0xc6, 0x6b, 0x45, 0x7c, - 0xa0, 0x7f, 0xa0, 0x2f, 0x58, 0xc9, 0x3c, 0x6c, 0x73, 0xcd, 0xb5, 0x69, - 0x49, 0xe0, 0x67, 0x62, 0x13, 0xc4, 0x3a, 0xd8, 0x05, 0xdb, 0xf6, 0xe0, - 0x39, 0xfe, 0xfe, 0x6f, 0x7e, 0x8d, 0xea, 0xaf, 0x5a, 0x04, 0xc6, 0xfb, - 0x32, 0x63, 0x8f, 0x8d, 0xf1, 0xaa, 0x8d, 0xeb, 0x75, 0x49, 0x17, 0x3b, - 0xb8, 0xcf, 0x7a, 0x0d, 0x6b, 0x54, 0xaf, 0x80, 0xde, 0x7a, 0x7d, 0x55, - 0x61, 0x48, 0xe4, 0x33, 0x87, 0xd6, 0xc0, 0x43, 0xe3, 0x33, 0xdf, 0xc0, - 0x33, 0xaa, 0x2d, 0x6c, 0x26, 0x1c, 0xe6, 0x50, 0xf0, 0x9b, 0x2f, 0xc0, - 0x47, 0x1e, 0xcb, 0xe8, 0xcb, 0x57, 0xf1, 0x2c, 0x64, 0x5a, 0x3c, 0x96, - 0x09, 0xf5, 0xbc, 0x5a, 0x7f, 0x16, 0x39, 0xf1, 0xd0, 0xf2, 0x80, 0xa4, - 0x96, 0xbb, 0xa3, 0x17, 0xa5, 0xf5, 0x1d, 0x17, 0xb1, 0x74, 0xb2, 0x6a, - 0x9d, 0x76, 0x85, 0x39, 0xba, 0x29, 0x0b, 0xc0, 0xd5, 0x7b, 0xf6, 0x3d, - 0x0f, 0xda, 0xad, 0x17, 0x45, 0x8f, 0xe1, 0x37, 0x31, 0x0c, 0x79, 0x5c, - 0x03, 0x7f, 0x1a, 0xae, 0x5b, 0xd6, 0x6b, 0x57, 0x85, 0x12, 0xf8, 0xac, - 0x1d, 0xcb, 0x5c, 0x9c, 0x06, 0xae, 0x83, 0x3e, 0x92, 0xd3, 0xc4, 0x9c, - 0x5b, 0x20, 0x93, 0x21, 0xd8, 0x05, 0xf5, 0x1d, 0xc7, 0xb3, 0x75, 0xf9, - 0x92, 0x43, 0x1b, 0x78, 0x0e, 0x72, 0xc3, 0x58, 0xa1, 0x80, 0x6e, 0x60, - 0x80, 0x19, 0xca, 0x6a, 0x17, 0xf2, 0x36, 0x57, 0x06, 0xf6, 0x49, 0x78, - 0x47, 0x62, 0x73, 0x4e, 0x76, 0x2c, 0xb3, 0x3a, 0x8d, 0xf1, 0x7b, 0x80, - 0x79, 0x84, 0xb5, 0x19, 0xfa, 0x60, 0x81, 0xed, 0xec, 0x87, 0x7e, 0x98, - 0x7b, 0x33, 0x47, 0xa3, 0x6f, 0x3a, 0xa8, 0xa5, 0x2a, 0x65, 0x43, 0x3a, - 0x0e, 0x21, 0xb7, 0x71, 0x64, 0x71, 0x9a, 0x39, 0x1a, 0xf3, 0x99, 0x20, - 0x7f, 0xd1, 0x90, 0x4b, 0xa0, 0x7d, 0xf9, 0x25, 0xa5, 0x07, 0x03, 0xfa, - 0xca, 0xed, 0xbb, 0x9f, 0x7c, 0xcd, 0x18, 0x09, 0xf8, 0xbf, 0x01, 0xf2, - 0xa2, 0x68, 0x40, 0xce, 0xc6, 0x35, 0x17, 0x03, 0x5f, 0xf8, 0x5c, 0xcf, - 0xdd, 0xd4, 0xdf, 0x64, 0xe9, 0x04, 0xec, 0x58, 0xf2, 0x4d, 0x09, 0xf0, - 0x36, 0x80, 0xdf, 0x58, 0xf8, 0x27, 0xa1, 0xc3, 0x73, 0x03, 0xac, 0x91, - 0x3d, 0x07, 0xfc, 0x47, 0xfa, 0xe3, 0xb1, 0x13, 0x6a, 0xdd, 0xe2, 0xba, - 0xca, 0x3c, 0x62, 0x8b, 0x5c, 0x54, 0x7c, 0xde, 0xc1, 0xfc, 0x14, 0x7a, - 0xb9, 0x15, 0x3e, 0x87, 0x3f, 0x24, 0x9f, 0xde, 0x3c, 0x8c, 0x5b, 0x49, - 0x3b, 0x26, 0xa9, 0xe2, 0xcb, 0x75, 0xaf, 0x0e, 0xfb, 0x47, 0xb0, 0x2b, - 0x5c, 0x57, 0xc3, 0xa0, 0x87, 0x75, 0x99, 0x01, 0xa5, 0x5b, 0xd0, 0x43, - 0x9b, 0xc9, 0x87, 0x13, 0xdb, 0xe4, 0xfc, 0x4c, 0x87, 0x2c, 0xcc, 0xbc, - 0x26, 0x95, 0x99, 0x36, 0x59, 0x9a, 0xa9, 0xcb, 0x65, 0x47, 0xf9, 0x25, - 0xbb, 0x59, 0xad, 0x69, 0xd9, 0xe5, 0x61, 0xf6, 0xf8, 0xe0, 0x15, 0x79, - 0x5a, 0xce, 0x97, 0x3d, 0x1e, 0x32, 0x0d, 0x3c, 0xbc, 0x0a, 0x1b, 0xeb, - 0xec, 0x21, 0x0f, 0xb4, 0x07, 0xf2, 0xc3, 0xdc, 0x83, 0x39, 0xe6, 0x41, - 0xac, 0xa3, 0x11, 0x60, 0xa3, 0x83, 0x5a, 0xd2, 0xe7, 0x21, 0xe5, 0xf1, - 0x90, 0x7d, 0x2f, 0x0f, 0x2d, 0x92, 0xdd, 0x49, 0x3e, 0xa0, 0x83, 0x69, - 0xea, 0x25, 0xc0, 0x1b, 0x1e, 0xfd, 0xc9, 0xe5, 0x57, 0xeb, 0xfa, 0x74, - 0x93, 0xa2, 0xdd, 0x48, 0x0c, 0xc0, 0xae, 0x5e, 0xad, 0xcb, 0x32, 0xd7, - 0x12, 0x7e, 0x57, 0xff, 0x31, 0xfc, 0x55, 0xa7, 0xca, 0x5b, 0x72, 0x63, - 0xed, 0xad, 0xc9, 0xf9, 0x41, 0xe8, 0xba, 0x55, 0xad, 0x45, 0xb8, 0x0e, - 0xe8, 0xf0, 0x0f, 0xd1, 0xff, 0xab, 0x5c, 0x73, 0x4a, 0x3e, 0x69, 0xc8, - 0xa7, 0x50, 0xbc, 0xbd, 0x19, 0x39, 0x37, 0xe6, 0x71, 0x33, 0xd9, 0x2a, - 0x9f, 0xe9, 0x82, 0x7f, 0xe3, 0xf7, 0x07, 0xb6, 0x8f, 0x3c, 0xfc, 0x2e, - 0x6c, 0x00, 0xb9, 0x05, 0xd7, 0xf4, 0xc0, 0x0a, 0xe2, 0x6c, 0xbc, 0x77, - 0x41, 0xd5, 0xf4, 0x1d, 0x85, 0x9f, 0x26, 0xab, 0x5f, 0xc5, 0xc7, 0x9b, - 0x6f, 0xa8, 0xc6, 0x39, 0x37, 0xf2, 0x84, 0x9c, 0x06, 0xb9, 0xa4, 0x8d, - 0x71, 0x39, 0x6f, 0x5e, 0x8c, 0x84, 0x81, 0x79, 0xd9, 0xd6, 0x0e, 0x3f, - 0x13, 0x83, 0xdf, 0xea, 0x87, 0xff, 0xe7, 0x5a, 0xa6, 0xaf, 0x0f, 0x68, - 0xef, 0xc7, 0x98, 0xf4, 0xc1, 0xfd, 0xe0, 0x99, 0xb9, 0x34, 0x7d, 0x28, - 0x62, 0xca, 0x62, 0xb4, 0x2d, 0x39, 0xeb, 0xd5, 0x93, 0xbc, 0xdf, 0xbc, - 0x2f, 0xe1, 0xdd, 0x09, 0xab, 0x9c, 0x47, 0xfe, 0x97, 0xc2, 0xda, 0x4d, - 0xda, 0xc8, 0xa7, 0x17, 0xad, 0x17, 0x88, 0xd3, 0x74, 0xca, 0x60, 0x99, - 0x72, 0x62, 0x6d, 0xc3, 0x94, 0xfc, 0xc2, 0xef, 0x42, 0x1e, 0x61, 0xd9, - 0x6e, 0x67, 0xe1, 0x53, 0x98, 0xb7, 0xb8, 0xe0, 0x8d, 0xbe, 0xa7, 0x1b, - 0xb1, 0xcc, 0x80, 0x10, 0x90, 0x57, 0x2d, 0x1b, 0xf2, 0x40, 0xa8, 0x0f, - 0x79, 0xe0, 0xa7, 0xd0, 0x37, 0x24, 0xf9, 0x65, 0xc6, 0x84, 0x90, 0x4c, - 0x2d, 0x8b, 0x5c, 0x99, 0xa6, 0x5f, 0x51, 0x7f, 0x90, 0xb9, 0x9b, 0x99, - 0x20, 0x3e, 0x9b, 0xa1, 0x8f, 0xa1, 0xff, 0xd8, 0x01, 0x5d, 0xc4, 0x9f, - 0xfb, 0x12, 0xe2, 0xd3, 0x64, 0xb1, 0x1b, 0x7e, 0x53, 0x56, 0x74, 0xc8, - 0x14, 0x71, 0x8d, 0xf5, 0xaa, 0x1b, 0xd4, 0xaa, 0x82, 0x3a, 0x55, 0x58, - 0x0a, 0xd3, 0xac, 0x51, 0x85, 0x41, 0x0b, 0x73, 0x57, 0x43, 0xe5, 0x42, - 0x3b, 0x94, 0x7f, 0xe5, 0x77, 0xa8, 0x61, 0xde, 0xf8, 0xe9, 0x3d, 0x3a, - 0xfd, 0xd8, 0x6e, 0x71, 0x47, 0x8f, 0xb5, 0xee, 0x2f, 0x01, 0x8b, 0x76, - 0xd2, 0x3e, 0xa9, 0xff, 0xac, 0x4e, 0x7f, 0x3b, 0x55, 0x1a, 0xc0, 0x78, - 0xc4, 0x95, 0x21, 0xf4, 0x8b, 0xf8, 0xfd, 0x28, 0xd7, 0x7f, 0x25, 0xe3, - 0xfb, 0xfe, 0x1a, 0x74, 0x79, 0xfe, 0x8e, 0x75, 0xee, 0xdc, 0x67, 0x74, - 0xb9, 0xef, 0x63, 0x69, 0x3c, 0xcb, 0x78, 0xf8, 0xb6, 0x8f, 0xe1, 0xd8, - 0xc6, 0xba, 0x1e, 0x72, 0xf5, 0xf3, 0x26, 0xbe, 0x3b, 0x25, 0x7f, 0x3e, - 0x0c, 0x39, 0x20, 0x2f, 0x5e, 0xf0, 0xc6, 0x62, 0xee, 0x7b, 0x1a, 0x3a, - 0xd2, 0xcf, 0x84, 0xa5, 0xe9, 0x4c, 0xa7, 0x84, 0xbe, 0xd2, 0x26, 0xcd, - 0x5f, 0xe9, 0x11, 0xe3, 0x2b, 0xac, 0x3f, 0x58, 0xb1, 0x93, 0xaa, 0xf6, - 0x91, 0x96, 0x53, 0x88, 0x61, 0x3a, 0xe2, 0xb1, 0xb2, 0x53, 0x73, 0xa7, - 0x18, 0x48, 0x5e, 0xf5, 0x67, 0x5c, 0xf9, 0xe2, 0xbe, 0x9f, 0xab, 0xda, - 0x1b, 0x70, 0xb3, 0xe8, 0xcf, 0x67, 0xc4, 0xad, 0xbd, 0x46, 0x3b, 0xcd, - 0xbc, 0x7a, 0xd7, 0x1d, 0xd0, 0x39, 0x73, 0xcb, 0x5e, 0x55, 0xc7, 0xfd, - 0xe2, 0x3e, 0xc6, 0x4c, 0x2f, 0xbf, 0x4c, 0x23, 0xbf, 0x9c, 0x94, 0x6e, - 0xf8, 0x59, 0xf6, 0xdb, 0x29, 0x3a, 0xe6, 0xca, 0x09, 0xf3, 0xf5, 0x3b, - 0xc5, 0x3d, 0x8c, 0x75, 0x71, 0x56, 0x66, 0xf4, 0x84, 0xa6, 0xc6, 0x34, - 0x9e, 0xa1, 0xdf, 0xa2, 0x3f, 0xa3, 0x8d, 0xb3, 0x0e, 0x82, 0xb6, 0xe7, - 0xe9, 0xb3, 0x3c, 0xdb, 0x1e, 0x6a, 0xf0, 0x7d, 0x53, 0xa5, 0x1a, 0x74, - 0x88, 0xbc, 0xde, 0x6e, 0x02, 0xff, 0x88, 0xeb, 0x36, 0xaf, 0xc9, 0x3f, - 0x7c, 0x69, 0x24, 0xa2, 0xae, 0x0b, 0x65, 0x0f, 0xf7, 0x7a, 0xe3, 0x33, - 0x07, 0x81, 0xaf, 0xa9, 0x91, 0x0e, 0xce, 0xdb, 0x25, 0xc6, 0xd9, 0x88, - 0x84, 0xce, 0xd2, 0xfe, 0xac, 0x58, 0x1a, 0xf2, 0x9b, 0xb2, 0x89, 0xf5, - 0x0e, 0xc0, 0x17, 0xec, 0x16, 0xfd, 0x7c, 0x2f, 0xd6, 0x8e, 0x15, 0x2d, - 0x4b, 0x5c, 0x8c, 0x85, 0xb0, 0xbc, 0x09, 0xdf, 0x41, 0x7b, 0x39, 0x87, - 0x78, 0x75, 0xa2, 0xd6, 0xfa, 0xce, 0x8a, 0xa2, 0x82, 0x6d, 0x43, 0xc0, - 0x4b, 0x56, 0xaf, 0xab, 0xb7, 0xcb, 0xeb, 0xd0, 0x77, 0x56, 0xb5, 0xed, - 0xc6, 0xb8, 0xa0, 0xe1, 0x2c, 0xeb, 0x49, 0x1c, 0xf7, 0x1f, 0x60, 0x4c, - 0x8e, 0xed, 0x66, 0x56, 0x99, 0x9f, 0x4e, 0xd3, 0x76, 0x3b, 0x61, 0x77, - 0xb8, 0xae, 0x35, 0x4b, 0x76, 0x2c, 0x26, 0xfa, 0xf4, 0x83, 0xd2, 0xbd, - 0x4f, 0xf7, 0xf8, 0x51, 0x3c, 0xb2, 0x8d, 0x75, 0xca, 0x16, 0xb5, 0x1e, - 0xf5, 0x65, 0xd8, 0xcc, 0x41, 0xea, 0x18, 0xf1, 0x1f, 0xf1, 0x8d, 0xfe, - 0xcc, 0x40, 0x7c, 0x4b, 0xd5, 0x3c, 0xbd, 0x97, 0x0f, 0xee, 0x94, 0x53, - 0x67, 0x69, 0x4f, 0xb8, 0xb7, 0x6e, 0x53, 0xc1, 0x7e, 0x02, 0xef, 0xd9, - 0x72, 0xfa, 0x59, 0xe6, 0x1f, 0xcc, 0x3b, 0x98, 0x6b, 0x59, 0xd1, 0xfd, - 0xe0, 0x47, 0xbf, 0x8f, 0xfe, 0x40, 0x57, 0xb6, 0x9b, 0x83, 0xaf, 0x2e, - 0xd4, 0xa8, 0xb7, 0x7e, 0xee, 0xb9, 0x98, 0xcc, 0xd9, 0xdc, 0xa8, 0x27, - 0xef, 0x02, 0xda, 0x26, 0x11, 0x07, 0x52, 0xd5, 0x26, 0x59, 0x1b, 0x73, - 0xa1, 0xfb, 0x8f, 0x82, 0xae, 0xc3, 0xad, 0xc4, 0xab, 0x6b, 0x63, 0x69, - 0x5c, 0x1f, 0x56, 0x79, 0x9a, 0x71, 0x9f, 0x8b, 0x31, 0x76, 0x72, 0x1d, - 0xf9, 0x7a, 0x72, 0xf4, 0xc2, 0xcc, 0x7d, 0xfa, 0x24, 0x7c, 0xf7, 0xb0, - 0xc3, 0x18, 0xcf, 0xfa, 0x73, 0x0b, 0xe8, 0x68, 0x57, 0xd8, 0x42, 0xb7, - 0xf7, 0xe9, 0x85, 0x32, 0xfd, 0x7d, 0x3e, 0xda, 0x2c, 0x0e, 0x7d, 0x96, - 0xbe, 0x60, 0x53, 0x27, 0x9a, 0x5c, 0x54, 0xb5, 0x6a, 0x44, 0xa0, 0x6a, - 0x0a, 0x73, 0x39, 0x7a, 0xa5, 0xbc, 0x4f, 0xcf, 0xc3, 0x55, 0xaf, 0x45, - 0x48, 0x77, 0x4c, 0xe5, 0xf2, 0xfb, 0x94, 0xad, 0x15, 0x11, 0x53, 0x60, - 0x33, 0xce, 0x1d, 0x98, 0x57, 0xb5, 0xc1, 0xa6, 0xa8, 0x7b, 0xea, 0x5d, - 0xf9, 0x48, 0x5f, 0xf7, 0x37, 0x8a, 0xa1, 0x45, 0xf8, 0x5f, 0x62, 0xe9, - 0x16, 0xbf, 0x3e, 0xf5, 0xcf, 0xfd, 0x9c, 0xe8, 0x71, 0x61, 0x9e, 0x32, - 0x55, 0x22, 0x2d, 0x45, 0xf8, 0xc3, 0x1b, 0xd9, 0x12, 0xe5, 0xe8, 0xf9, - 0x94, 0x63, 0xb0, 0x0b, 0x7d, 0xd9, 0xf4, 0x6d, 0x40, 0xe1, 0x67, 0xdc, - 0x63, 0x0c, 0xc0, 0x77, 0xad, 0x09, 0xeb, 0x7d, 0x04, 0x32, 0xa2, 0x6e, - 0xa0, 0xbf, 0x65, 0xee, 0xd5, 0x41, 0x7f, 0xcb, 0x97, 0x7e, 0xe1, 0x76, - 0xd2, 0xe7, 0x0d, 0xc8, 0x29, 0xf8, 0xd1, 0x93, 0xf3, 0xa4, 0x27, 0xad, - 0xd6, 0xce, 0x14, 0xe4, 0x7d, 0x42, 0xf9, 0xf8, 0x7e, 0x79, 0x73, 0xf1, - 0x5b, 0x0a, 0x0b, 0xee, 0xd9, 0xb7, 0x22, 0x13, 0xf0, 0x0f, 0x47, 0xaa, - 0x90, 0xb7, 0x19, 0xc3, 0xfa, 0xdc, 0xa5, 0xfc, 0xe3, 0x17, 0x3f, 0x78, - 0xae, 0x12, 0xd2, 0x13, 0x0f, 0x7c, 0xc8, 0x18, 0xbe, 0x55, 0xdc, 0xce, - 0x0f, 0x3c, 0x8f, 0xa1, 0x27, 0xfe, 0x10, 0x3a, 0xfb, 0x4d, 0xcc, 0x15, - 0x06, 0x9d, 0x6a, 0x3f, 0xe4, 0x83, 0x3c, 0xa7, 0xeb, 0x89, 0x4f, 0x7e, - 0x48, 0xfa, 0x4c, 0x59, 0x04, 0x7e, 0xc8, 0xab, 0xb8, 0xca, 0xdc, 0xb1, - 0xc9, 0xd7, 0xe7, 0x0b, 0xc0, 0xd5, 0xc0, 0xd2, 0xc5, 0xc0, 0x17, 0xb7, - 0x48, 0xbe, 0x33, 0xc8, 0x47, 0xe1, 0xc3, 0xd7, 0xdb, 0x83, 0x1c, 0x97, - 0xcf, 0x67, 0x33, 0xc8, 0xa9, 0x61, 0x13, 0xb7, 0x61, 0x8d, 0xb2, 0x4d, - 0xe5, 0xb0, 0x37, 0xa1, 0xdf, 0xa3, 0x3d, 0x57, 0x6c, 0xcc, 0x2d, 0x0e, - 0xa8, 0xdc, 0x62, 0x68, 0x43, 0x6e, 0x11, 0xd4, 0xb4, 0x02, 0xba, 0x39, - 0x2e, 0x70, 0x03, 0xec, 0xe0, 0xbb, 0x18, 0xff, 0x3b, 0xd0, 0xf7, 0xb7, - 0x4b, 0xc0, 0x0d, 0x25, 0xe0, 0x86, 0x12, 0x70, 0x43, 0x09, 0xb8, 0xa1, - 0x14, 0xf5, 0xeb, 0x5b, 0x2e, 0x71, 0xff, 0x07, 0xb4, 0xe9, 0xa0, 0xee, - 0xb1, 0xd9, 0x5e, 0xbd, 0x3a, 0x59, 0xaa, 0x16, 0xe0, 0xe7, 0x30, 0xeb, - 0x76, 0xc0, 0x71, 0x41, 0x4d, 0xc4, 0x8f, 0x1d, 0x8b, 0xdc, 0x43, 0x41, - 0xec, 0x58, 0x74, 0xb1, 0x9e, 0xfa, 0xa2, 0x06, 0x70, 0xa3, 0x21, 0x51, - 0xfc, 0x36, 0xe1, 0x93, 0xb9, 0x67, 0xde, 0x8d, 0x15, 0xd6, 0xac, 0x6a, - 0x4f, 0x27, 0x54, 0x4d, 0xc2, 0x96, 0xc9, 0x72, 0x90, 0xdb, 0xc5, 0x65, - 0x68, 0x86, 0x58, 0x54, 0xb6, 0xeb, 0x09, 0xe8, 0xa2, 0x4a, 0xfc, 0xc8, - 0x3d, 0x27, 0xce, 0x1f, 0xef, 0xad, 0x60, 0xce, 0x82, 0xed, 0xd1, 0x77, - 0xa2, 0xaa, 0xce, 0x05, 0xf8, 0xcf, 0x05, 0x67, 0x01, 0xe2, 0xb2, 0x7f, - 0x86, 0x7b, 0xef, 0x31, 0x19, 0x2d, 0x3a, 0xc8, 0x65, 0x55, 0x8e, 0x84, - 0x78, 0xe0, 0xc9, 0x7d, 0xc8, 0x97, 0x7b, 0x0e, 0xd8, 0x61, 0xdc, 0x0e, - 0xe4, 0x4e, 0x79, 0x8f, 0x68, 0xc3, 0x90, 0xf5, 0x7e, 0x5f, 0xd6, 0xe9, - 0x25, 0x31, 0x91, 0xff, 0xc4, 0x8c, 0x7d, 0x63, 0xda, 0x68, 0x4d, 0x61, - 0x16, 0xfa, 0x23, 0x8c, 0xe5, 0x78, 0x6b, 0x1d, 0xf6, 0x92, 0xab, 0x6e, - 0xde, 0x8f, 0x6f, 0xc4, 0x2f, 0x9f, 0xd5, 0xc4, 0x0e, 0xe4, 0xd8, 0xd8, - 0x3e, 0xd1, 0xd0, 0xbe, 0x7e, 0xdf, 0xe7, 0x01, 0xbe, 0x72, 0xbd, 0x3e, - 0x41, 0xbf, 0x76, 0xbd, 0x1d, 0x78, 0x4f, 0x42, 0xea, 0x3e, 0x7c, 0xfe, - 0x62, 0x44, 0x52, 0x8b, 0xb6, 0xa4, 0xcb, 0xec, 0xc7, 0x9a, 0x07, 0xfd, - 0xd7, 0x1f, 0x4b, 0x0a, 0x79, 0x6e, 0x36, 0x62, 0x39, 0xae, 0xfc, 0x47, - 0x59, 0x9d, 0xcb, 0xc7, 0xb8, 0x77, 0x9d, 0x1f, 0xd5, 0xf0, 0xdc, 0x8f, - 0x71, 0x4d, 0xda, 0x6d, 0xac, 0x0f, 0xc6, 0xa9, 0xbe, 0xe8, 0x22, 0xee, - 0x65, 0xc7, 0x58, 0xe7, 0x79, 0x2a, 0x2c, 0x6d, 0x56, 0xac, 0x0c, 0x3b, - 0xb8, 0x54, 0xe4, 0x7c, 0xc0, 0x52, 0x45, 0xd6, 0x82, 0x82, 0xfb, 0x7f, - 0x0c, 0xec, 0xa8, 0x13, 0x3b, 0x79, 0x7d, 0x94, 0xbe, 0x5c, 0x33, 0x84, - 0x35, 0xb0, 0xe2, 0xfb, 0xe7, 0x85, 0xa2, 0x57, 0x7b, 0x39, 0x47, 0x3a, - 0xaa, 0x7f, 0x53, 0x5f, 0x89, 0x20, 0x67, 0x5a, 0xe7, 0xf1, 0x1c, 0xc7, - 0x37, 0xe1, 0x9e, 0xe5, 0x64, 0x35, 0x90, 0x05, 0xef, 0xb3, 0x8d, 0xfb, - 0xf3, 0xf5, 0xfa, 0x39, 0xfb, 0xc3, 0xd6, 0xd9, 0x9e, 0xbb, 0x27, 0x69, - 0xcb, 0x81, 0x85, 0xaa, 0x1c, 0xf0, 0xea, 0x6c, 0xd1, 0xbd, 0x5e, 0x9d, - 0x2d, 0xb6, 0x77, 0x63, 0x9d, 0xad, 0x7c, 0x8f, 0x57, 0x67, 0x33, 0x0f, - 0xc0, 0x07, 0x1f, 0xf0, 0xea, 0x6c, 0xff, 0xf5, 0x1e, 0xaf, 0xce, 0xd6, - 0x75, 0xaf, 0x57, 0x67, 0xeb, 0xdd, 0xeb, 0xd5, 0xd9, 0x46, 0xef, 0xdd, - 0x58, 0x67, 0x73, 0xf6, 0x6e, 0xac, 0xb3, 0x39, 0x07, 0x72, 0xf8, 0x5c, - 0xaf, 0xb3, 0x65, 0xf6, 0xde, 0xbc, 0xce, 0xf6, 0x4a, 0x80, 0xf1, 0xc1, - 0xcf, 0x00, 0x78, 0x70, 0x80, 0xf1, 0xfb, 0x81, 0xf1, 0x6f, 0x56, 0xe3, - 0x55, 0xe7, 0x37, 0xc0, 0xa7, 0xe6, 0xc7, 0x8f, 0x0f, 0x83, 0xf5, 0xb7, - 0xfa, 0xcf, 0xba, 0xc8, 0x8f, 0x63, 0x7e, 0x6e, 0x43, 0xbc, 0xbf, 0xcd, - 0xcf, 0xf1, 0xba, 0x5a, 0xaf, 0x9f, 0xad, 0x68, 0xfc, 0xbe, 0x0d, 0xa9, - 0x7a, 0x50, 0x03, 0x20, 0x5f, 0x72, 0xe0, 0x61, 0x25, 0x87, 0x3b, 0xd1, - 0xdf, 0x3c, 0xf0, 0x25, 0x9b, 0x75, 0x81, 0x27, 0xb1, 0x86, 0xdd, 0xed, - 0x86, 0xda, 0x67, 0x66, 0x4c, 0x3b, 0x2d, 0x29, 0xf4, 0x4f, 0xa9, 0xfe, - 0xa3, 0x0d, 0xfd, 0xb3, 0xe8, 0xcf, 0x71, 0xad, 0x7f, 0x8b, 0xcf, 0x73, - 0xca, 0xbe, 0x6d, 0x0f, 0xf7, 0xa7, 0x4b, 0x01, 0x4e, 0x0b, 0xf9, 0x18, - 0xdc, 0xcd, 0xb8, 0xd5, 0x7b, 0xf1, 0x8c, 0xf5, 0xa2, 0x2b, 0x57, 0x15, - 0xde, 0x37, 0x12, 0xd6, 0x8b, 0x59, 0x95, 0xdf, 0xb9, 0x99, 0x5c, 0x75, - 0x3d, 0x5f, 0x07, 0x0e, 0x63, 0xce, 0x03, 0x7b, 0x5f, 0xee, 0x45, 0xdc, - 0x6b, 0xcc, 0xc9, 0x99, 0x87, 0xeb, 0x7e, 0x1e, 0x6e, 0xca, 0xfd, 0xfb, - 0x1a, 0x31, 0xbe, 0x73, 0xe0, 0xef, 0x2b, 0x8c, 0xbf, 0x05, 0xb9, 0x3c, - 0x31, 0x3c, 0x71, 0x0f, 0x31, 0x07, 0x71, 0x3e, 0xeb, 0x0b, 0xcc, 0x7f, - 0x18, 0x4b, 0x99, 0x0f, 0x45, 0xf0, 0xe1, 0xb9, 0x97, 0x00, 0xeb, 0x37, - 0xfb, 0xfe, 0x9f, 0x79, 0x54, 0x80, 0x6d, 0xac, 0x2d, 0x5e, 0x2e, 0xb5, - 0x45, 0xf3, 0xf2, 0xd5, 0x98, 0xdf, 0x27, 0xb4, 0x8e, 0xa5, 0x43, 0xeb, - 0x58, 0x7a, 0xc3, 0x5e, 0x89, 0xa8, 0x33, 0x36, 0x6a, 0xcf, 0x85, 0x7b, - 0x30, 0x6e, 0xe6, 0x52, 0x0f, 0xf1, 0x30, 0xf7, 0x62, 0x80, 0x8d, 0xec, - 0xc6, 0x58, 0xc5, 0x38, 0x45, 0x3c, 0x15, 0xec, 0xb7, 0x06, 0x7a, 0xa2, - 0xec, 0xd8, 0xf6, 0x47, 0x1a, 0x72, 0x64, 0xa7, 0xd9, 0xde, 0x0f, 0x5a, - 0x32, 0xf8, 0x0e, 0x64, 0xfa, 0x80, 0x8a, 0x91, 0x2d, 0xb0, 0xdd, 0x13, - 0x25, 0x62, 0xde, 0x6d, 0xb2, 0xe8, 0xe3, 0xde, 0xf3, 0x33, 0x1e, 0xe6, - 0x0d, 0x6d, 0xc4, 0xbc, 0xce, 0xaa, 0x78, 0x34, 0xee, 0xbf, 0x21, 0x8d, - 0xc4, 0xb7, 0xa4, 0x8f, 0x31, 0x89, 0xfe, 0xd1, 0xcd, 0x5c, 0xee, 0x61, - 0x3c, 0x62, 0x2c, 0x8a, 0xc9, 0xea, 0x4d, 0xe9, 0x53, 0x6d, 0xc7, 0x5a, - 0xec, 0x30, 0x3e, 0x13, 0xf0, 0x1f, 0xa3, 0x78, 0x26, 0x23, 0x93, 0xb3, - 0x5f, 0x00, 0x6f, 0x13, 0x72, 0x69, 0x66, 0x0c, 0xf4, 0x3d, 0x29, 0x53, - 0x4e, 0x1e, 0x7e, 0x84, 0x7b, 0x21, 0xc4, 0x79, 0xdd, 0xfe, 0xf7, 0x84, - 0x7e, 0xce, 0xb6, 0x88, 0x33, 0xa5, 0x52, 0xa4, 0x0f, 0xe6, 0xbe, 0x14, - 0xf7, 0x1f, 0x69, 0x3f, 0xac, 0xc3, 0x20, 0xd7, 0x65, 0xce, 0x3b, 0xcd, - 0xf9, 0x37, 0xea, 0x64, 0xb5, 0x4a, 0xbc, 0xe6, 0x66, 0x56, 0x96, 0x89, - 0x37, 0x3f, 0x28, 0xf6, 0xa4, 0x1e, 0x88, 0x3f, 0x6f, 0x05, 0x77, 0x5a, - 0x33, 0xc0, 0x9c, 0x2f, 0xac, 0xe8, 0x8d, 0xb8, 0xd3, 0xc3, 0x9c, 0xc9, - 0xe5, 0x2c, 0xc6, 0x74, 0x14, 0xb6, 0x46, 0xde, 0x07, 0xb7, 0xd7, 0x8d, - 0x67, 0xbb, 0x91, 0xc3, 0x7b, 0x18, 0x33, 0x05, 0x8c, 0xf9, 0x0f, 0x81, - 0x31, 0x27, 0xe5, 0xad, 0x56, 0x62, 0x4c, 0xd7, 0xc7, 0x98, 0x69, 0xd8, - 0x73, 0x6e, 0x83, 0x3d, 0x6b, 0xaa, 0x76, 0xc5, 0x7b, 0x39, 0x60, 0xc4, - 0xd4, 0xb4, 0x75, 0x0b, 0xb8, 0x52, 0x93, 0x88, 0x3a, 0xfb, 0x10, 0x6a, - 0x18, 0x33, 0xc0, 0x8f, 0x7b, 0x14, 0x2e, 0x3c, 0x50, 0xda, 0x82, 0x1c, - 0x46, 0xe1, 0x44, 0x7f, 0x4f, 0x2e, 0xb4, 0x69, 0x9f, 0x32, 0xd4, 0xb0, - 0x4f, 0x79, 0x1d, 0x4f, 0xe2, 0x39, 0xbf, 0x3e, 0xd8, 0x04, 0x5f, 0xf0, - 0x7f, 0x40, 0x13, 0xd7, 0x17, 0xd7, 0x82, 0xe6, 0xad, 0x97, 0xd1, 0x46, - 0x5c, 0xf9, 0xbf, 0x36, 0xe1, 0x4a, 0xc4, 0xae, 0xf3, 0x11, 0x49, 0x02, - 0x53, 0xba, 0xcb, 0x1c, 0x8b, 0x6b, 0xba, 0x5f, 0x9a, 0xc1, 0x5f, 0xcb, - 0x74, 0x27, 0xb0, 0x54, 0x9b, 0x84, 0x81, 0xa9, 0x9a, 0x14, 0xa6, 0xea, - 0x21, 0xf6, 0xe9, 0x3d, 0x02, 0x2c, 0xb4, 0xb8, 0x8e, 0xab, 0x2c, 0xe7, - 0x87, 0xd0, 0xcb, 0xa3, 0xca, 0xf7, 0xa4, 0xe5, 0x29, 0xf8, 0xd2, 0xe6, - 0x65, 0xe0, 0xc1, 0xf3, 0x1e, 0xde, 0x6a, 0xda, 0x84, 0xb7, 0x8e, 0xde, - 0x10, 0x6f, 0xa9, 0x9a, 0xff, 0x20, 0x65, 0xf2, 0x7a, 0xd5, 0xab, 0xf9, - 0x5f, 0xa9, 0x7a, 0x35, 0xff, 0xd7, 0xab, 0x8d, 0x35, 0xff, 0x8f, 0x48, - 0xc1, 0xb4, 0xdc, 0x35, 0xd9, 0x54, 0xf3, 0x1f, 0x65, 0x0d, 0xfd, 0xf7, - 0xda, 0xbc, 0xda, 0x7e, 0x9b, 0x5f, 0xf3, 0xb7, 0xa4, 0xb0, 0xa1, 0xdd, - 0x94, 0xb7, 0xec, 0xa0, 0xe6, 0xff, 0x34, 0xda, 0xda, 0x31, 0xc7, 0xc6, - 0x7a, 0xff, 0x95, 0x2a, 0xeb, 0xfd, 0x11, 0xf6, 0xf3, 0xeb, 0xfd, 0xec, - 0x87, 0xdc, 0xbf, 0xca, 0x5a, 0xff, 0x6e, 0xc8, 0x62, 0x27, 0xe4, 0xd0, - 0x29, 0xcd, 0x67, 0xa3, 0xec, 0xa3, 0x6a, 0xfc, 0x6b, 0xc8, 0x37, 0xae, - 0x54, 0xbd, 0x5a, 0xfc, 0x11, 0xd8, 0xd5, 0xd1, 0xf5, 0x1a, 0xbf, 0x37, - 0xc7, 0xd5, 0xea, 0xc6, 0xf1, 0x37, 0x8e, 0xd3, 0xe5, 0x8f, 0x13, 0xc1, - 0x38, 0xd1, 0x4d, 0xe3, 0x5c, 0xaf, 0xe9, 0x5f, 0xad, 0x7a, 0xf5, 0xfc, - 0xf4, 0xac, 0xb8, 0xcd, 0xf0, 0xcd, 0x2f, 0xf6, 0xec, 0xf2, 0xc7, 0x58, - 0xaf, 0xe7, 0xd3, 0x87, 0x00, 0xe7, 0xc7, 0xd5, 0xf9, 0x9e, 0x23, 0xff, - 0x1f, 0xea, 0xf9, 0xac, 0xe5, 0x7b, 0x7b, 0x32, 0x5c, 0x9f, 0xc0, 0xf3, - 0xcf, 0x7a, 0x75, 0xfc, 0xa1, 0x52, 0x50, 0x9f, 0x67, 0x5e, 0x19, 0x9c, - 0xbd, 0xe9, 0x8e, 0x9d, 0x10, 0xda, 0x0a, 0xe9, 0xe3, 0xb8, 0xed, 0x32, - 0xae, 0xf0, 0x14, 0x6c, 0x2a, 0x7e, 0x73, 0x4c, 0xbd, 0x30, 0x1d, 0x60, - 0xea, 0x88, 0xc2, 0xd4, 0x0b, 0xcb, 0x01, 0xa6, 0x4e, 0xde, 0x04, 0x53, - 0xff, 0xf7, 0x36, 0x2f, 0x0e, 0x84, 0x25, 0xaf, 0x30, 0xf5, 0xcd, 0xce, - 0x2b, 0xf1, 0x5e, 0x1b, 0xf1, 0x82, 0x78, 0x7b, 0xd8, 0x9d, 0x37, 0x59, - 0x6b, 0x01, 0xce, 0x66, 0xec, 0xdf, 0x29, 0xa3, 0x67, 0xaf, 0xe3, 0x6c, - 0x0f, 0x4b, 0x5b, 0xb1, 0x63, 0x2a, 0x26, 0x02, 0xd7, 0xd5, 0x58, 0x2f, - 0x27, 0x56, 0x66, 0xcc, 0x09, 0x29, 0x3c, 0x97, 0x2b, 0x32, 0x0f, 0x60, - 0x1b, 0xb1, 0x73, 0x2b, 0x8f, 0xf2, 0xf8, 0x31, 0x29, 0xc0, 0xa6, 0xc1, - 0xd9, 0x09, 0xee, 0x4b, 0xbc, 0x65, 0x24, 0x6d, 0xb4, 0x57, 0x83, 0x5c, - 0xc1, 0x51, 0x67, 0x4e, 0x92, 0xc0, 0x3f, 0xe3, 0xeb, 0xd8, 0x93, 0xbe, - 0xe2, 0x47, 0xbf, 0x70, 0x4d, 0xfa, 0xb5, 0x00, 0x5b, 0x22, 0x27, 0x2a, - 0x71, 0x6d, 0x07, 0xd8, 0xd2, 0xc3, 0x95, 0xa9, 0xea, 0x0a, 0xf0, 0x75, - 0x48, 0x86, 0x80, 0xeb, 0x57, 0x1e, 0x66, 0xcd, 0x2a, 0xc0, 0x4e, 0x2e, - 0xbe, 0x1b, 0x6b, 0x58, 0xbc, 0x6e, 0x56, 0x7b, 0x87, 0x17, 0x7b, 0xc2, - 0x0d, 0xed, 0xbf, 0x05, 0xff, 0x8d, 0xfc, 0x08, 0x98, 0xc5, 0xc3, 0x4c, - 0x7b, 0xa1, 0x83, 0x01, 0x85, 0x99, 0xa6, 0xde, 0x83, 0x99, 0x36, 0xc7, - 0x28, 0xc6, 0xcc, 0xeb, 0x31, 0x2a, 0x5d, 0xa3, 0x3f, 0xbf, 0x1e, 0xa3, - 0x6e, 0x1e, 0x43, 0xd9, 0x06, 0xee, 0xec, 0x0c, 0x3e, 0x13, 0x52, 0xd8, - 0x14, 0xa3, 0xa6, 0x3e, 0x44, 0x8c, 0x1a, 0x56, 0x31, 0xca, 0xa3, 0xfb, - 0xfb, 0x90, 0xcd, 0x77, 0x21, 0xd3, 0xef, 0x00, 0x8b, 0x7d, 0x1b, 0x7c, - 0x7d, 0x0b, 0x38, 0xe9, 0x9b, 0xa5, 0xcd, 0x67, 0x0e, 0x06, 0x85, 0xf9, - 0xa1, 0x87, 0xa5, 0xbc, 0x1a, 0xc0, 0x11, 0xac, 0xae, 0xc5, 0xa2, 0x9b, - 0x19, 0x2f, 0xf6, 0x99, 0x13, 0xde, 0xde, 0x6b, 0x2c, 0x2b, 0x8f, 0xb5, - 0xa6, 0xe6, 0x19, 0x33, 0xd4, 0x75, 0x94, 0xf5, 0x4e, 0x62, 0x87, 0x8a, - 0xca, 0x33, 0x7b, 0xa4, 0xbc, 0xe8, 0xe1, 0xb0, 0xa9, 0x79, 0x6f, 0x8c, - 0x71, 0x1f, 0x87, 0xe5, 0x7c, 0x1c, 0x96, 0x5d, 0x5c, 0x8d, 0x85, 0xd0, - 0x7f, 0xca, 0xd9, 0x88, 0xbd, 0x8e, 0xf8, 0xd8, 0x6b, 0xe2, 0x43, 0x61, - 0x2f, 0x6f, 0xae, 0x1c, 0x9e, 0x19, 0x9e, 0x89, 0xc9, 0x7e, 0xc8, 0x79, - 0xa8, 0x48, 0x7d, 0xf1, 0x9c, 0xd2, 0x2f, 0xd3, 0x19, 0xf5, 0xe5, 0xe9, - 0x2a, 0x14, 0x3f, 0xa8, 0x0d, 0x43, 0x57, 0x43, 0xbf, 0x54, 0x57, 0x62, - 0xbe, 0x39, 0x10, 0xc6, 0xe7, 0x6f, 0x4b, 0x57, 0xe4, 0x83, 0xfa, 0xda, - 0x8c, 0xc5, 0x6e, 0x05, 0x93, 0x6d, 0xc4, 0x63, 0xae, 0xc2, 0x63, 0xcd, - 0x7e, 0x9f, 0xfc, 0x81, 0x61, 0xe8, 0xf2, 0x3f, 0xa0, 0xcf, 0x8f, 0xed, - 0x76, 0xf9, 0x11, 0xfc, 0xf7, 0xbf, 0x87, 0x4e, 0xfe, 0x1d, 0x72, 0x85, - 0x57, 0xec, 0x2e, 0xf9, 0x21, 0xda, 0xae, 0xe3, 0x1c, 0xf6, 0x9f, 0x72, - 0x92, 0xf6, 0x28, 0xf0, 0xc9, 0xa8, 0x8f, 0x4f, 0xde, 0x7a, 0x20, 0x69, - 0x8f, 0xb1, 0xce, 0x0e, 0x39, 0xff, 0x34, 0x39, 0xae, 0xb0, 0x49, 0x80, - 0x49, 0x1e, 0x4f, 0x73, 0xfe, 0xc9, 0x6a, 0x16, 0xd8, 0x27, 0xeb, 0x63, - 0x9f, 0x9f, 0xa6, 0x3d, 0xec, 0x33, 0xf5, 0xf7, 0xa8, 0x7f, 0x0f, 0xf7, - 0x1c, 0x76, 0x93, 0x98, 0x07, 0xb8, 0x07, 0xd7, 0x87, 0x25, 0x5f, 0x1b, - 0x51, 0x9f, 0x13, 0x25, 0xd7, 0x6a, 0x82, 0x9c, 0x58, 0xab, 0x3d, 0xc3, - 0x55, 0x59, 0xb5, 0xcc, 0x22, 0xbe, 0xb3, 0x55, 0x2b, 0xfa, 0x7b, 0xfe, - 0xf5, 0xd3, 0xfe, 0xf5, 0x53, 0xfe, 0xf5, 0x69, 0xc4, 0xe1, 0x53, 0x2a, - 0x96, 0xb2, 0x9d, 0x6d, 0x50, 0x72, 0x15, 0x63, 0x01, 0x7b, 0x9c, 0xeb, - 0xff, 0xf3, 0x7a, 0x59, 0xe9, 0x98, 0xe3, 0x8f, 0xe2, 0x73, 0x1a, 0x9f, - 0x09, 0x7c, 0x0e, 0xe1, 0x93, 0xc7, 0x67, 0x5d, 0xa6, 0x5a, 0xaa, 0x34, - 0x06, 0x1b, 0xe9, 0x95, 0x54, 0xed, 0x39, 0xe8, 0xf1, 0x49, 0xe8, 0xf6, - 0xb8, 0x14, 0x2a, 0x7f, 0x22, 0x93, 0x33, 0x9a, 0xb4, 0xd9, 0xd0, 0x69, - 0x05, 0xb6, 0x3c, 0xe3, 0xed, 0x41, 0xb6, 0x26, 0x46, 0xd0, 0xb7, 0x2e, - 0x8f, 0x3a, 0x4f, 0x8a, 0x7e, 0xdf, 0x14, 0xfa, 0x89, 0x5e, 0xe8, 0xbf, - 0x5b, 0xed, 0xbf, 0x55, 0x1c, 0x4f, 0xc6, 0xfb, 0x6d, 0xd7, 0x82, 0xce, - 0x7b, 0x4f, 0x61, 0xec, 0xa4, 0x3a, 0x7f, 0x99, 0x91, 0x93, 0xb3, 0xab, - 0xdb, 0x3d, 0xdf, 0x6a, 0x99, 0x57, 0xa9, 0x77, 0xf0, 0xe1, 0xc2, 0x17, - 0x66, 0x60, 0xef, 0x47, 0xab, 0x21, 0x6d, 0x08, 0xf1, 0x66, 0xa8, 0x7a, - 0x55, 0xc5, 0x9b, 0x54, 0xd5, 0xcd, 0xc4, 0xcf, 0x44, 0x70, 0xcd, 0x73, - 0x31, 0x88, 0x8b, 0xea, 0xfc, 0xde, 0x2a, 0xf0, 0x8d, 0xa6, 0xea, 0x86, - 0x93, 0xeb, 0xfb, 0x4a, 0xea, 0x7c, 0x71, 0x26, 0x1e, 0xd7, 0x25, 0x37, - 0x40, 0x9c, 0x3b, 0xa2, 0x62, 0x13, 0xd6, 0xea, 0xed, 0xcc, 0x15, 0x5f, - 0xe7, 0xbb, 0x00, 0xf6, 0x27, 0xd0, 0xaf, 0x0b, 0xfe, 0x18, 0xf7, 0x6a, - 0xb4, 0x4f, 0xf2, 0xca, 0x67, 0x26, 0xa4, 0x52, 0x1e, 0x04, 0xbf, 0x7e, - 0x8e, 0xa4, 0x72, 0x89, 0x18, 0xec, 0x31, 0xd8, 0xc3, 0xf2, 0xea, 0x2a, - 0x95, 0x6a, 0x80, 0x29, 0xda, 0xd1, 0x87, 0x79, 0x05, 0x64, 0xe4, 0xed, - 0xbf, 0xa9, 0xbd, 0xb7, 0x42, 0x75, 0x10, 0x72, 0x4a, 0xa2, 0x9d, 0xb5, - 0x6d, 0xfc, 0x2e, 0xeb, 0xaa, 0x26, 0xb0, 0x66, 0x1c, 0x91, 0xc5, 0x72, - 0x1d, 0xf4, 0x22, 0xe6, 0x6e, 0x3f, 0x22, 0x0b, 0xe5, 0x09, 0x79, 0xa1, - 0xfc, 0xcd, 0x76, 0x60, 0x2a, 0xc8, 0x94, 0xf4, 0xb7, 0xcb, 0xf5, 0x33, - 0x9e, 0x41, 0x3b, 0xe4, 0x39, 0x9b, 0x8f, 0x7a, 0x79, 0x6e, 0x5e, 0xd5, - 0x68, 0xbc, 0x6f, 0x57, 0x1f, 0xb7, 0xad, 0xe8, 0x24, 0x7a, 0x1e, 0x9d, - 0x53, 0xb6, 0x39, 0x3c, 0x65, 0xef, 0x95, 0xcb, 0xce, 0x36, 0x59, 0x75, - 0x54, 0x5e, 0x4c, 0xfc, 0x80, 0xb5, 0x6e, 0x99, 0x2b, 0xf2, 0xa0, 0x9c, - 0xc4, 0xba, 0xbd, 0xec, 0x3c, 0x06, 0x3b, 0x7d, 0x02, 0xb6, 0xc0, 0x1a, - 0xc0, 0x31, 0xe6, 0x5a, 0xb2, 0xa2, 0x6a, 0x68, 0xf5, 0xfa, 0xb0, 0x3a, - 0x27, 0xdc, 0x2c, 0xab, 0x0a, 0x8b, 0x79, 0xb5, 0xf6, 0xd5, 0x31, 0x6f, - 0x8d, 0x18, 0xca, 0xee, 0xbf, 0x01, 0x7a, 0x8a, 0xb0, 0xdd, 0x26, 0xd5, - 0xc7, 0x48, 0xb4, 0xf8, 0x7d, 0x14, 0x06, 0x6d, 0xe8, 0x63, 0x27, 0x92, - 0xf6, 0x6b, 0xfb, 0x92, 0xf6, 0xc4, 0x81, 0x5c, 0xd5, 0xf3, 0x99, 0xae, - 0xb6, 0xb6, 0x5e, 0xff, 0xc9, 0x60, 0x5d, 0xbd, 0xbc, 0x8e, 0xa1, 0x61, - 0xa4, 0xcf, 0x5f, 0x82, 0x7e, 0x43, 0xd2, 0x7c, 0xa6, 0xfe, 0x89, 0x71, - 0xa7, 0x2f, 0x76, 0x54, 0x78, 0x32, 0x8b, 0x79, 0xb5, 0xe5, 0x64, 0xe5, - 0x12, 0xe2, 0xe4, 0x35, 0x62, 0x87, 0xde, 0x8b, 0x72, 0xed, 0x13, 0x49, - 0x67, 0x50, 0x5b, 0x18, 0x43, 0xd6, 0xf2, 0xfc, 0x18, 0xe3, 0xec, 0x31, - 0x11, 0xe0, 0xcb, 0x33, 0x03, 0x92, 0x2e, 0xaa, 0x77, 0x21, 0x78, 0x96, - 0x53, 0x9b, 0x80, 0xfc, 0xf0, 0xfc, 0x28, 0x03, 0xa3, 0x6e, 0x77, 0xc7, - 0xd2, 0xf2, 0x18, 0x6b, 0x63, 0x92, 0x9b, 0x93, 0x3d, 0x49, 0xf8, 0x55, - 0x77, 0xb4, 0x59, 0x26, 0x16, 0xdd, 0x4c, 0xf7, 0xf4, 0x13, 0x18, 0x63, - 0x1c, 0x63, 0x8d, 0x20, 0x37, 0xc9, 0x22, 0x56, 0x53, 0xbe, 0xf4, 0xdd, - 0x8f, 0x43, 0x46, 0x1f, 0xe1, 0x59, 0xd7, 0xc1, 0xac, 0x58, 0xa3, 0x79, - 0x35, 0xee, 0xbb, 0x5a, 0xae, 0xff, 0x57, 0x10, 0xeb, 0x42, 0xb2, 0x3f, - 0x2e, 0xfa, 0x48, 0x3c, 0xf4, 0x8b, 0x71, 0x9b, 0x6d, 0x61, 0xb6, 0xe9, - 0x68, 0x0b, 0xfd, 0x66, 0x3c, 0xac, 0x27, 0xe3, 0xd6, 0x20, 0xcf, 0xe0, - 0x1a, 0xf6, 0xb8, 0x18, 0xcf, 0xd7, 0x21, 0x8b, 0x11, 0xe9, 0xb8, 0x60, - 0x0d, 0xbe, 0x0e, 0x5a, 0x42, 0xca, 0xd7, 0x8f, 0x8b, 0xee, 0xb7, 0xb7, - 0xaf, 0xb7, 0x87, 0xfc, 0xf6, 0x11, 0x69, 0xbb, 0xd0, 0x67, 0xbe, 0x21, - 0x47, 0x30, 0xa6, 0x21, 0x57, 0x90, 0xeb, 0xd8, 0x3d, 0xe3, 0xb0, 0xc5, - 0x47, 0x48, 0xcb, 0x21, 0xd6, 0x1b, 0x5d, 0xd8, 0x5f, 0x8b, 0x7d, 0x87, - 0x7c, 0xde, 0x6c, 0x95, 0x9c, 0xca, 0x75, 0x43, 0xea, 0xbd, 0x85, 0x1c, - 0xec, 0xfd, 0xae, 0x9e, 0xa1, 0x0e, 0xaf, 0x5e, 0xc0, 0xfd, 0x91, 0x7e, - 0xb4, 0x5d, 0xab, 0x9f, 0xb7, 0xd9, 0xc6, 0x7b, 0xd7, 0xea, 0x15, 0xbb, - 0xcf, 0x4c, 0x69, 0x61, 0x7f, 0xff, 0xfc, 0x98, 0xe2, 0x3d, 0x5f, 0xee, - 0x36, 0x17, 0xe4, 0x2e, 0x2d, 0xb5, 0x03, 0xf1, 0xa2, 0x9a, 0x42, 0xdf, - 0x6b, 0x3c, 0x83, 0xa1, 0xf6, 0x03, 0x16, 0x24, 0xb8, 0xe6, 0x38, 0x7d, - 0xe6, 0xb0, 0x7a, 0xb6, 0xcf, 0x3c, 0xa9, 0x35, 0x3e, 0x1b, 0xd5, 0x86, - 0x37, 0x3c, 0xdb, 0xa6, 0x64, 0x64, 0xd8, 0x5e, 0x9f, 0xc9, 0xf2, 0x88, - 0x3c, 0x5d, 0x65, 0xbf, 0x6b, 0xf5, 0x94, 0xbd, 0x55, 0x3b, 0xb9, 0x83, - 0xbe, 0x90, 0x7d, 0xdf, 0xd9, 0x34, 0x0f, 0xaf, 0x6f, 0x36, 0x47, 0x5d, - 0x36, 0xce, 0xb1, 0x45, 0xf5, 0xb9, 0xac, 0xfa, 0x84, 0x94, 0xac, 0x37, - 0xce, 0xf3, 0x17, 0xb2, 0x71, 0x9e, 0xb6, 0x75, 0x9e, 0x27, 0x31, 0xe6, - 0x29, 0xf4, 0x2d, 0x56, 0xbb, 0xa3, 0x15, 0x79, 0xa7, 0x9e, 0xb3, 0xdf, - 0x92, 0xcb, 0xeb, 0x63, 0xff, 0x25, 0xae, 0x1b, 0x69, 0xfa, 0x4b, 0x9f, - 0x46, 0xfe, 0x66, 0xdb, 0x3f, 0x53, 0xf2, 0xde, 0x6a, 0x77, 0x1f, 0x5a, - 0xd0, 0xac, 0xc1, 0x9f, 0x09, 0x75, 0xf5, 0x3b, 0xca, 0xd7, 0xdc, 0x0d, - 0x3d, 0xed, 0x79, 0x06, 0x6b, 0xb7, 0x3f, 0xa9, 0xfa, 0x5c, 0xb1, 0x47, - 0x64, 0xcf, 0x99, 0x6e, 0xf3, 0x8a, 0xdc, 0x2f, 0xe9, 0x08, 0xaf, 0x91, - 0x43, 0xd9, 0x7c, 0xf7, 0xe1, 0x57, 0x99, 0x17, 0x40, 0x97, 0xdd, 0xbd, - 0x3f, 0x93, 0x27, 0xe4, 0x64, 0x69, 0x0a, 0xbe, 0x67, 0x5c, 0x7a, 0x9f, - 0xa1, 0xff, 0xc9, 0x9b, 0x5e, 0xad, 0xc6, 0x8b, 0x89, 0x29, 0x3f, 0x26, - 0x4e, 0x29, 0x3f, 0xf7, 0x8a, 0x7f, 0x8e, 0xa2, 0xbb, 0xf7, 0x3c, 0x9e, - 0x7d, 0x41, 0xf9, 0x80, 0x6f, 0x48, 0x05, 0x6b, 0x21, 0xf6, 0xfc, 0x36, - 0xd9, 0xfa, 0x10, 0x6d, 0x12, 0x19, 0xc0, 0xdd, 0x4d, 0xea, 0x5d, 0x0b, - 0xdd, 0x6e, 0x11, 0xd9, 0x4e, 0xfb, 0x59, 0xd8, 0x2a, 0x6d, 0xe3, 0xde, - 0x5e, 0xd9, 0x86, 0x6b, 0x6b, 0x74, 0x4d, 0xca, 0x5b, 0x69, 0x87, 0x1f, - 0xbd, 0xe0, 0x7d, 0xf7, 0x5f, 0x40, 0xba, 0x1c, 0x1f, 0x91, 0x7b, 0x2f, - 0x78, 0x76, 0x37, 0x39, 0xf3, 0x84, 0x92, 0xef, 0xb8, 0x92, 0x6f, 0x5d, - 0x8e, 0x38, 0x94, 0x3d, 0x79, 0xe2, 0xb9, 0x4a, 0x4f, 0x26, 0x9f, 0xf4, - 0xed, 0xa8, 0xfb, 0x19, 0xbe, 0x23, 0x46, 0x19, 0x91, 0xee, 0x74, 0x07, - 0xf7, 0x6f, 0xf7, 0x5c, 0x20, 0xbf, 0x5d, 0x1b, 0xf8, 0x7d, 0x0a, 0x3e, - 0xb6, 0xa7, 0xc7, 0xe3, 0xf9, 0x95, 0x99, 0x0f, 0xce, 0xf3, 0xd7, 0xd6, - 0x79, 0x36, 0xa4, 0xa2, 0xf2, 0xdc, 0xd0, 0x36, 0x69, 0xcb, 0xc9, 0x0a, - 0xec, 0xe3, 0xcf, 0x84, 0xe7, 0x92, 0x49, 0x8b, 0x37, 0xef, 0x6a, 0x95, - 0x34, 0x05, 0x3c, 0x90, 0xae, 0xa4, 0xaf, 0x3f, 0xd2, 0xf1, 0xc4, 0x0d, - 0xef, 0x5d, 0x11, 0x37, 0xd3, 0x8b, 0x36, 0x5d, 0xe9, 0x70, 0xc8, 0x5f, - 0x6f, 0x23, 0xa2, 0x2b, 0x1d, 0x26, 0xd7, 0x75, 0xf8, 0x3a, 0x74, 0x58, - 0x91, 0x8f, 0x83, 0x27, 0xac, 0xef, 0x67, 0xfa, 0xcc, 0x23, 0xb2, 0x53, - 0xe9, 0xdf, 0xee, 0x81, 0x4f, 0xf5, 0x75, 0xd9, 0x7c, 0x0b, 0xba, 0x7c, - 0x43, 0x94, 0x3e, 0xd5, 0xd9, 0xa3, 0x8a, 0x1a, 0x87, 0xbe, 0x8d, 0xbc, - 0x35, 0x2b, 0x9f, 0x40, 0x1a, 0xd5, 0x59, 0x82, 0x51, 0x4f, 0xbf, 0x6a, - 0xcd, 0xfb, 0xfa, 0xcd, 0x8e, 0x52, 0x87, 0xd1, 0x0e, 0x4f, 0x9f, 0x2d, - 0xaa, 0xcf, 0x74, 0xfc, 0x36, 0xb5, 0xde, 0xed, 0x9e, 0x9d, 0x1d, 0xd4, - 0xe9, 0xd3, 0x55, 0xef, 0xbb, 0x88, 0x38, 0x37, 0x5d, 0xfd, 0x65, 0x7a, - 0xf5, 0x74, 0x3a, 0x24, 0xde, 0xba, 0xda, 0xac, 0x4f, 0xfd, 0x42, 0x48, - 0xd9, 0xf0, 0x10, 0x64, 0x78, 0xba, 0xb4, 0xc3, 0xb7, 0x7b, 0x8f, 0xe7, - 0x9e, 0x0f, 0xc8, 0xf3, 0x89, 0x62, 0xb7, 0xf9, 0x16, 0xee, 0x0d, 0x83, - 0xe7, 0x23, 0xd2, 0x24, 0x29, 0x9f, 0xe7, 0xd8, 0x3a, 0xcf, 0x01, 0x8d, - 0x5e, 0xbf, 0x14, 0xf3, 0xd8, 0x2a, 0xfd, 0xd7, 0xef, 0xaa, 0x77, 0x1a, - 0xae, 0x16, 0xe9, 0xb7, 0x81, 0x95, 0x22, 0x9d, 0x72, 0x65, 0x31, 0x26, - 0x57, 0x88, 0x41, 0x06, 0xf0, 0x5d, 0x9d, 0xf2, 0x63, 0x78, 0x58, 0xde, - 0x28, 0xde, 0x88, 0x8e, 0x7e, 0x79, 0xbd, 0x18, 0xd0, 0x42, 0x2c, 0xcc, - 0x7c, 0x61, 0x5c, 0xde, 0x9c, 0xe9, 0x96, 0x95, 0x51, 0xc4, 0xfd, 0x1e, - 0xca, 0xa4, 0xcf, 0x7c, 0x50, 0xbd, 0xeb, 0x72, 0xad, 0x7e, 0xd1, 0xc6, - 0xf8, 0x73, 0x75, 0x39, 0xca, 0xfd, 0x6f, 0xfe, 0x5e, 0xbc, 0x5d, 0x56, - 0x98, 0x53, 0xf4, 0x74, 0xca, 0xc2, 0x1c, 0xf2, 0xf9, 0x22, 0xc7, 0xa7, - 0xdc, 0x46, 0xd4, 0xef, 0x61, 0xcc, 0xf7, 0x49, 0x9e, 0x41, 0x8f, 0x50, - 0x37, 0xd7, 0xea, 0xab, 0x36, 0xf7, 0x3f, 0xc7, 0x65, 0x11, 0xfa, 0xfb, - 0x47, 0x71, 0xee, 0xcf, 0xe7, 0xd4, 0xfb, 0x85, 0x0b, 0x8b, 0xa3, 0xc8, - 0x1d, 0xae, 0xd5, 0xa7, 0xec, 0x29, 0xa5, 0xb7, 0xc5, 0xf2, 0x43, 0x7e, - 0x3b, 0xaf, 0x79, 0xcf, 0xcd, 0xec, 0xe9, 0x61, 0xbe, 0xfa, 0x10, 0xf2, - 0x05, 0xe6, 0xaa, 0xa3, 0xc0, 0x6b, 0x94, 0x49, 0x4c, 0x26, 0x8b, 0x1c, - 0x4b, 0x22, 0x5b, 0x90, 0xdf, 0xe7, 0x64, 0x18, 0xf4, 0xc4, 0x90, 0xdb, - 0x33, 0x3e, 0xdc, 0x25, 0xab, 0x11, 0x2f, 0x0e, 0xf0, 0xac, 0xd8, 0x2a, - 0x62, 0xc3, 0xea, 0x7a, 0x6c, 0xd8, 0x89, 0x6b, 0x37, 0xe3, 0xf4, 0xfc, - 0x67, 0x8c, 0xcf, 0xba, 0x0d, 0x63, 0xc3, 0x20, 0xfa, 0xb3, 0xad, 0x53, - 0x26, 0xe7, 0x90, 0x44, 0x20, 0x67, 0x59, 0x10, 0x9e, 0x01, 0xc9, 0xca, - 0xf4, 0x62, 0x77, 0xf4, 0xa2, 0x96, 0x56, 0x67, 0x45, 0xe2, 0x98, 0x73, - 0xa1, 0xd8, 0x29, 0x8b, 0x73, 0x12, 0x33, 0x12, 0x8f, 0x48, 0x75, 0xd1, - 0xc3, 0xec, 0x53, 0x1a, 0xda, 0xab, 0xae, 0x2c, 0x6e, 0xec, 0x63, 0x1a, - 0x89, 0xc3, 0xf2, 0x75, 0xbf, 0x4f, 0x5a, 0xf5, 0x79, 0xb5, 0x83, 0x7b, - 0x6c, 0x8b, 0xd5, 0x0e, 0xd0, 0x40, 0xda, 0x76, 0x35, 0xce, 0x1b, 0xbb, - 0x3e, 0x2f, 0xe7, 0x44, 0x36, 0xb3, 0xdd, 0xc5, 0xbc, 0x17, 0xf1, 0xcc, - 0x23, 0xa0, 0xe3, 0x9a, 0xa1, 0xdb, 0x8f, 0x48, 0x61, 0x71, 0xf3, 0x1c, - 0x8d, 0x34, 0xf0, 0x19, 0x8e, 0xcf, 0x79, 0x0e, 0x83, 0xbe, 0x6b, 0x9a, - 0x6e, 0x1f, 0x86, 0x2c, 0xbd, 0x39, 0x8c, 0xb3, 0x96, 0xf9, 0x23, 0xe9, - 0x11, 0xfd, 0xbc, 0xa6, 0xe4, 0xaf, 0x2f, 0xf4, 0x63, 0x81, 0x64, 0xa4, - 0x6d, 0x79, 0x4c, 0x8c, 0x65, 0xd6, 0x10, 0x5e, 0x69, 0x4d, 0xab, 0xfd, - 0xde, 0x2d, 0x58, 0xdf, 0xe2, 0x86, 0x6c, 0xd6, 0x0b, 0x58, 0x0f, 0xfe, - 0xfa, 0x36, 0xe9, 0x60, 0xbd, 0x80, 0x79, 0xc3, 0x21, 0x7c, 0x33, 0x77, - 0x78, 0xb9, 0x9e, 0x74, 0x7e, 0xa6, 0xe2, 0x6b, 0x6e, 0x91, 0xf7, 0xad, - 0x98, 0x08, 0xef, 0xd1, 0x6f, 0x74, 0x4a, 0xd3, 0x57, 0x7a, 0xe1, 0x2b, - 0x1e, 0x03, 0xf6, 0xc6, 0xb8, 0x67, 0x7a, 0x24, 0xe4, 0x9d, 0xb1, 0x50, - 0xf5, 0x96, 0x37, 0xe7, 0x2c, 0xff, 0x9d, 0x21, 0xd9, 0x73, 0xd1, 0x61, - 0x4d, 0xb4, 0x8b, 0x35, 0x1f, 0xf4, 0x13, 0x7d, 0x15, 0xf9, 0xe9, 0x95, - 0x45, 0x63, 0x1b, 0xcf, 0x7c, 0xbe, 0x5e, 0xc5, 0x35, 0xb1, 0x7f, 0x44, - 0x61, 0x4c, 0xff, 0x1e, 0x7f, 0x23, 0x5f, 0x7a, 0xcf, 0xf9, 0x77, 0xe6, - 0x53, 0x63, 0xfe, 0x59, 0x3b, 0x37, 0x73, 0x72, 0x43, 0x4e, 0xd5, 0xab, - 0xea, 0xbd, 0x2b, 0x55, 0x1b, 0xfe, 0x71, 0x00, 0xf6, 0xc9, 0x35, 0x50, - 0xd7, 0x1e, 0x02, 0x36, 0x8b, 0x75, 0xaa, 0x9c, 0xe8, 0xf4, 0x43, 0xe2, - 0xd9, 0x3b, 0xac, 0x4c, 0xf9, 0xb2, 0x95, 0xb2, 0x97, 0x83, 0xac, 0x96, - 0x33, 0xf2, 0x9f, 0xaa, 0x97, 0x54, 0xad, 0x75, 0x06, 0x79, 0x49, 0x68, - 0x5a, 0xe5, 0x64, 0x0d, 0xf8, 0x16, 0x7e, 0xef, 0xd9, 0x2f, 0x62, 0x2d, - 0x5a, 0xea, 0x4c, 0x83, 0x7e, 0xbe, 0x5e, 0x4f, 0xc1, 0x7f, 0xe8, 0xb6, - 0x6d, 0x16, 0x10, 0x0f, 0x53, 0xea, 0x5c, 0x0c, 0xd7, 0xf1, 0x61, 0xe5, - 0x9f, 0x65, 0x01, 0xb2, 0x39, 0x1b, 0xc3, 0x38, 0x9a, 0xb2, 0x4f, 0x43, - 0xe9, 0xe1, 0x21, 0x85, 0x79, 0x8d, 0xf3, 0x70, 0x58, 0xcb, 0x3d, 0x22, - 0xe7, 0x33, 0x32, 0x85, 0x35, 0x1c, 0x5a, 0xa6, 0x0e, 0x28, 0xdb, 0x31, - 0x69, 0x82, 0xec, 0x4f, 0x00, 0x7b, 0x18, 0xd3, 0x94, 0x71, 0x14, 0xeb, - 0xa2, 0x53, 0x42, 0x67, 0x21, 0xe3, 0x69, 0x60, 0x84, 0xb9, 0x66, 0x79, - 0x69, 0x31, 0x90, 0xe9, 0xcb, 0x3c, 0xef, 0xaf, 0x8f, 0x0f, 0x74, 0x11, - 0x47, 0x49, 0x65, 0x71, 0x4a, 0xa6, 0x66, 0x99, 0xb3, 0x8f, 0xa9, 0x33, - 0x06, 0x21, 0x75, 0xc6, 0xc5, 0xcb, 0x99, 0xbd, 0x6f, 0x0f, 0x63, 0x56, - 0x84, 0x7b, 0x6d, 0x02, 0xdb, 0xe9, 0xc7, 0xbc, 0x37, 0x92, 0xaf, 0x97, - 0xab, 0x0e, 0x83, 0xde, 0x8b, 0x33, 0x56, 0x26, 0x2f, 0x0e, 0xcf, 0x5b, - 0x8f, 0xba, 0xe0, 0x7f, 0x15, 0xfe, 0x73, 0xaa, 0x74, 0x2f, 0xf8, 0x2c, - 0x60, 0x85, 0x65, 0xe4, 0x62, 0x91, 0x39, 0xe3, 0x47, 0xa1, 0x37, 0x5e, - 0x17, 0x06, 0x0d, 0xf8, 0x81, 0x35, 0xf5, 0x7e, 0xa1, 0xe5, 0xae, 0x20, - 0x87, 0x8d, 0x69, 0x87, 0xa0, 0xeb, 0xbc, 0xd9, 0xe4, 0xdb, 0x03, 0xdf, - 0x35, 0x3e, 0x07, 0x3f, 0xba, 0x24, 0x7c, 0xef, 0xe7, 0x9d, 0x3a, 0xf3, - 0xa5, 0xcb, 0xf0, 0x7b, 0x99, 0x78, 0x06, 0x36, 0x94, 0x8f, 0xb6, 0x80, - 0xe6, 0xdf, 0xc6, 0xbd, 0x5c, 0x95, 0xf3, 0x58, 0xce, 0x9a, 0x14, 0x62, - 0x21, 0xe9, 0x8b, 0x5d, 0x92, 0x6d, 0xf0, 0x64, 0x9a, 0xbc, 0x61, 0x5b, - 0x83, 0xa2, 0xa9, 0xf1, 0x7a, 0x0f, 0xc0, 0x06, 0xaf, 0xc2, 0xdf, 0x35, - 0xfb, 0xb9, 0x7e, 0xaa, 0x48, 0x0c, 0xf5, 0x84, 0x3a, 0x8b, 0x70, 0xd9, - 0x66, 0x1d, 0x90, 0xef, 0xfb, 0xfe, 0x95, 0x9a, 0xe3, 0xfa, 0xde, 0x1d, - 0xeb, 0xd0, 0xa4, 0xcf, 0xe3, 0x71, 0xbf, 0xed, 0xd1, 0xc8, 0x71, 0x9a, - 0x1a, 0xc6, 0xb9, 0xe8, 0x8f, 0x73, 0xce, 0x1f, 0x67, 0xc1, 0x1f, 0xe7, - 0xf2, 0xfa, 0x38, 0x0f, 0xc2, 0x0e, 0xea, 0xf5, 0xa7, 0x80, 0x37, 0x92, - 0x4e, 0xbd, 0x9e, 0x46, 0x5e, 0x36, 0xd9, 0x3f, 0xa1, 0xf6, 0x5e, 0xf5, - 0xc4, 0x8b, 0x43, 0x49, 0xdb, 0x93, 0x3f, 0xac, 0x40, 0x26, 0x60, 0x8f, - 0x79, 0xf1, 0xb0, 0x3a, 0xf7, 0x03, 0xbd, 0xfd, 0xc2, 0x36, 0xf8, 0x81, - 0xc7, 0x10, 0x4b, 0x9c, 0xe1, 0x25, 0x5b, 0xf2, 0x7b, 0x7e, 0x4d, 0x87, - 0xbd, 0x77, 0x20, 0x2e, 0xbd, 0x09, 0xdb, 0x71, 0x86, 0x2b, 0x8b, 0x8f, - 0xa9, 0x3d, 0xe1, 0xa6, 0xc4, 0xbd, 0xd0, 0x67, 0x79, 0x78, 0x61, 0xb1, - 0x3c, 0x7c, 0x8e, 0xfb, 0x43, 0xe8, 0xb7, 0xb0, 0xd8, 0x0e, 0xb9, 0xb7, - 0xab, 0xba, 0xca, 0xa5, 0x62, 0x04, 0x7a, 0x34, 0x61, 0xf3, 0x11, 0xb4, - 0x45, 0x61, 0x07, 0x5d, 0x68, 0x7f, 0x0d, 0x6b, 0x3b, 0x86, 0xf6, 0xb5, - 0xd6, 0x61, 0x85, 0x63, 0x6d, 0x39, 0x5f, 0xbd, 0x8a, 0x98, 0xfb, 0x16, - 0xfc, 0x68, 0x2f, 0xfa, 0xf4, 0xa3, 0xcf, 0x0e, 0x13, 0xf8, 0x2a, 0x53, - 0xbe, 0x21, 0x4d, 0x2e, 0x68, 0xd2, 0x1b, 0x68, 0x72, 0x41, 0x0f, 0x7c, - 0xe7, 0x19, 0xd6, 0xa0, 0xfb, 0xe5, 0x64, 0x91, 0x67, 0xaa, 0xf8, 0xee, - 0xb5, 0x29, 0x21, 0x60, 0xd2, 0xa6, 0x33, 0x56, 0x74, 0x45, 0xd5, 0x7a, - 0x68, 0x5b, 0x7d, 0x4e, 0x45, 0x54, 0x9c, 0x89, 0x9d, 0x44, 0xfc, 0xba, - 0x5a, 0x6d, 0x97, 0x37, 0xfc, 0xb9, 0xd6, 0x84, 0xfb, 0x97, 0x1b, 0xe7, - 0x3a, 0x55, 0x1a, 0x1d, 0xfe, 0x81, 0x6d, 0xf8, 0x7c, 0x75, 0x62, 0xae, - 0x76, 0xf4, 0x1d, 0x1d, 0xbe, 0xb8, 0x78, 0xa3, 0xbe, 0x13, 0xe8, 0xdb, - 0xd4, 0xd0, 0x77, 0x02, 0xfd, 0xda, 0x11, 0x07, 0xdb, 0x15, 0x4f, 0x93, - 0xa0, 0xeb, 0x4a, 0x51, 0xbd, 0x0b, 0x0c, 0xb9, 0x73, 0x4e, 0x93, 0x98, - 0x3a, 0xe3, 0xd5, 0x4a, 0x2c, 0x33, 0xa6, 0xbd, 0xa7, 0xde, 0xa3, 0x6c, - 0x60, 0xc8, 0x06, 0xee, 0x9d, 0x19, 0xd5, 0x52, 0x95, 0x1c, 0x62, 0xd6, - 0x2e, 0xe2, 0x27, 0xc7, 0x45, 0xcc, 0x5c, 0xc0, 0x78, 0x8b, 0xc5, 0x15, - 0x9e, 0xc1, 0x86, 0x5d, 0xbc, 0x4d, 0x9c, 0xbd, 0xcb, 0x50, 0x67, 0x1e, - 0xd2, 0xaa, 0x66, 0xb7, 0x50, 0x14, 0x33, 0x39, 0xc0, 0x33, 0x0e, 0xf7, - 0x63, 0x5d, 0x7e, 0x0e, 0x6d, 0x49, 0xc4, 0xc7, 0xc3, 0x5a, 0x72, 0x69, - 0x18, 0xd7, 0x8f, 0xe0, 0x1a, 0xfe, 0x78, 0x2e, 0x8b, 0xfb, 0x8f, 0xe0, - 0x7a, 0x42, 0x4b, 0xd5, 0xb2, 0xb8, 0x7e, 0x14, 0xd7, 0x49, 0x93, 0x79, - 0xca, 0x0f, 0xec, 0x8c, 0xe6, 0x62, 0x2c, 0x77, 0x69, 0x18, 0x9f, 0xc6, - 0xf1, 0x78, 0x0f, 0x7a, 0x2a, 0x72, 0xaf, 0x2d, 0x0e, 0x9a, 0x0e, 0x6a, - 0xe9, 0x4a, 0x1b, 0xc6, 0xe8, 0xc1, 0xf3, 0xb4, 0xa9, 0x43, 0xfe, 0xfc, - 0xac, 0x39, 0xdd, 0xad, 0x6a, 0x4e, 0x46, 0x22, 0x03, 0x9c, 0x7c, 0x1c, - 0x79, 0x80, 0x26, 0x69, 0xfb, 0x49, 0x29, 0x38, 0xf0, 0x2b, 0x15, 0x43, - 0x52, 0x91, 0x3c, 0x7e, 0xe7, 0x25, 0x39, 0x88, 0xfb, 0x15, 0xda, 0x02, - 0xfb, 0xfd, 0x89, 0x14, 0xca, 0xc4, 0xfd, 0xac, 0x33, 0xb1, 0x36, 0xc5, - 0xfa, 0x52, 0x0e, 0x32, 0x88, 0xd0, 0x7e, 0x6f, 0x50, 0x13, 0xf3, 0xce, - 0x55, 0x23, 0x2e, 0x6b, 0xc9, 0x0a, 0xf7, 0xfd, 0xdc, 0xcc, 0x45, 0x9b, - 0xef, 0x28, 0x4d, 0x70, 0x1f, 0xb1, 0x60, 0x24, 0x58, 0x1f, 0x51, 0xf5, - 0x75, 0xc7, 0xdb, 0x1f, 0xe4, 0xb8, 0x63, 0xe0, 0xb7, 0xb1, 0x6e, 0xc5, - 0x79, 0xbf, 0x80, 0xe7, 0xbd, 0x7a, 0x56, 0xaa, 0xf6, 0x5e, 0x5d, 0xf0, - 0xbd, 0x81, 0xf3, 0xd0, 0xc5, 0x45, 0x95, 0x1b, 0x73, 0x0f, 0xf7, 0xfd, - 0x72, 0x2a, 0xe4, 0x30, 0x45, 0xd6, 0xc8, 0x82, 0x7d, 0xbb, 0x40, 0x8e, - 0x9b, 0x69, 0x25, 0x9d, 0x47, 0x30, 0xa6, 0x38, 0xf4, 0xbb, 0xd9, 0x08, - 0xf7, 0xdf, 0xf8, 0x8c, 0x7c, 0xf9, 0x3a, 0xdd, 0xa4, 0x99, 0xf2, 0x38, - 0x0e, 0xff, 0xc9, 0x77, 0x32, 0x9e, 0x94, 0x9c, 0xc3, 0x1a, 0x8f, 0x81, - 0xd8, 0x98, 0xc7, 0xef, 0xeb, 0xf2, 0x9b, 0xf4, 0xe5, 0x97, 0x2b, 0xbf, - 0xa4, 0x74, 0xb8, 0x60, 0x73, 0xbe, 0xa0, 0xf6, 0x31, 0xa2, 0x74, 0xb7, - 0xa0, 0xce, 0xfd, 0x06, 0x32, 0x08, 0xea, 0x77, 0x37, 0xb6, 0xbd, 0x61, - 0x9b, 0xb4, 0xdd, 0xce, 0xf3, 0x10, 0xbd, 0xae, 0x90, 0x7e, 0xf2, 0xc1, - 0x18, 0x16, 0xec, 0xb5, 0x06, 0x3c, 0x04, 0x7c, 0xde, 0xaa, 0x7c, 0x48, - 0x6f, 0x64, 0xbb, 0xb4, 0x65, 0x4c, 0xc3, 0x66, 0x6c, 0xf8, 0x84, 0xbf, - 0x3f, 0xf0, 0x77, 0x21, 0x67, 0x4f, 0x16, 0xa1, 0x84, 0x4c, 0xfa, 0xef, - 0xf8, 0xde, 0xc0, 0x1e, 0x36, 0xef, 0x35, 0xbb, 0x99, 0x73, 0xf6, 0x75, - 0xbe, 0x17, 0x6e, 0xc0, 0xf7, 0x82, 0xcf, 0x77, 0xe5, 0x16, 0xe9, 0x5d, - 0x98, 0x71, 0xc1, 0x33, 0x6d, 0xee, 0x46, 0xf6, 0x28, 0xea, 0x7f, 0x5f, - 0xac, 0x19, 0xe1, 0xb0, 0x5b, 0xbd, 0x59, 0x0d, 0x95, 0x79, 0xb5, 0x67, - 0x97, 0xe7, 0x10, 0x0b, 0xcb, 0x65, 0x2f, 0xc7, 0x2e, 0x57, 0x59, 0xcb, - 0x7e, 0x3f, 0x1a, 0xf8, 0xfe, 0xd7, 0x67, 0xd4, 0x79, 0x97, 0xc9, 0xaa, - 0x57, 0xf7, 0x2a, 0x97, 0x1b, 0x63, 0xea, 0x0e, 0xc6, 0xd3, 0xde, 0xbc, - 0x8c, 0xf2, 0xbd, 0x65, 0x5c, 0xef, 0x96, 0x4b, 0x73, 0x6a, 0xcf, 0xca, - 0xdf, 0x1b, 0xe2, 0x9e, 0x8f, 0xda, 0xff, 0x86, 0x5f, 0x1b, 0x53, 0x7e, - 0x7d, 0x75, 0x4e, 0xdd, 0xf3, 0xb0, 0x52, 0x75, 0x14, 0x7e, 0x1f, 0xb9, - 0x84, 0xbd, 0x55, 0x0a, 0xc8, 0xb9, 0xcf, 0xd9, 0x0f, 0x6f, 0x27, 0xce, - 0xe1, 0x58, 0xab, 0x18, 0xeb, 0xe2, 0x9c, 0x6c, 0xe7, 0x99, 0x92, 0xb2, - 0xda, 0x67, 0xf3, 0xea, 0xe2, 0x13, 0x12, 0xfc, 0x4f, 0x88, 0xb0, 0x1f, - 0x0b, 0x79, 0xae, 0x85, 0xef, 0xd2, 0xd2, 0x57, 0x20, 0x0f, 0x1a, 0xe5, - 0x3e, 0x4e, 0xbd, 0xee, 0xd5, 0xcd, 0xeb, 0x58, 0x17, 0x4d, 0x7c, 0xef, - 0x02, 0x7f, 0xc7, 0x61, 0x3f, 0x58, 0x27, 0xeb, 0xed, 0xbc, 0x66, 0xee, - 0x11, 0x5c, 0x33, 0xb0, 0xfd, 0x3f, 0xd4, 0x46, 0x90, 0x7c, 0xb4, 0x45, - 0x00, 0x00, 0x00 }; +/* 0x1f, 0x8b, 0x08, 0x00, 0x0e, 0x34, 0xe7, 0x45, 0x00, 0x03, */ + 0xcd, 0x7c, + 0x6f, 0x70, 0x5b, 0xd7, 0x95, 0xdf, 0x79, 0xef, 0x81, 0x24, 0x48, 0xd1, + 0xd4, 0x13, 0x17, 0x56, 0x60, 0x87, 0x71, 0x00, 0xf1, 0x81, 0x66, 0x42, + 0xae, 0x04, 0x2b, 0x4c, 0xc2, 0x6d, 0xd1, 0xf8, 0x05, 0x00, 0x29, 0x48, + 0xd1, 0x6c, 0x68, 0x95, 0x49, 0x94, 0x54, 0xe3, 0x62, 0x41, 0x52, 0xf1, + 0xb6, 0xce, 0x54, 0x9b, 0x78, 0x5a, 0x4d, 0xeb, 0xad, 0x11, 0x90, 0xfa, + 0xe7, 0x85, 0x04, 0xda, 0x62, 0x44, 0x7f, 0xc8, 0x07, 0x18, 0x80, 0x24, + 0x6f, 0xf2, 0x44, 0x28, 0x9b, 0x7f, 0xfd, 0xd0, 0xac, 0x50, 0x4a, 0xd6, + 0xba, 0x9b, 0xb4, 0xa3, 0xed, 0x66, 0x67, 0x3b, 0xd3, 0x2f, 0x1c, 0x49, + 0xf6, 0x7a, 0x77, 0x67, 0x36, 0xda, 0x6e, 0xb6, 0xab, 0xb6, 0xb2, 0xd1, + 0xdf, 0xef, 0xbe, 0xf7, 0x28, 0x90, 0xa6, 0x6c, 0xcb, 0xb3, 0xed, 0x94, + 0x33, 0x18, 0xe0, 0xdd, 0x77, 0xdf, 0xb9, 0xe7, 0x9e, 0x73, 0xee, 0x39, + 0xe7, 0x77, 0xee, 0x7d, 0x0c, 0x8b, 0x74, 0x89, 0xf7, 0xf7, 0x00, 0x3e, + 0x91, 0x43, 0x87, 0x9f, 0xd9, 0x3e, 0xb2, 0xfd, 0x13, 0xf8, 0xf9, 0x09, + 0x31, 0x02, 0x06, 0x6f, 0xbe, 0x69, 0x88, 0x64, 0xff, 0x42, 0x3e, 0xf0, + 0x1f, 0x1e, 0x37, 0x7d, 0xfa, 0xfc, 0x48, 0x50, 0x4f, 0x4c, 0xec, 0x4a, + 0x5a, 0x12, 0x34, 0x12, 0xb2, 0x6f, 0xca, 0x12, 0xb1, 0x9d, 0xa1, 0x48, + 0x4a, 0xde, 0x6a, 0xe6, 0x43, 0x01, 0x61, 0xfb, 0x47, 0x12, 0x77, 0x9e, + 0xfb, 0xc9, 0xa7, 0xa3, 0xb7, 0xca, 0x86, 0x04, 0xcd, 0x44, 0x56, 0xcc, + 0x01, 0x09, 0xf6, 0xe1, 0x99, 0x6f, 0x3f, 0x6a, 0x18, 0xd2, 0xb3, 0xca, + 0xab, 0xcc, 0x95, 0x56, 0x9a, 0x3f, 0x79, 0x34, 0x2c, 0xbf, 0x57, 0x0f, + 0xc9, 0xf7, 0xea, 0xa6, 0x5c, 0xac, 0x07, 0xb4, 0xf1, 0x92, 0x29, 0xb3, + 0xa5, 0x69, 0xfd, 0x48, 0x31, 0x2f, 0xa9, 0x7a, 0x56, 0x2f, 0x2c, 0x98, + 0x3d, 0xc9, 0xf3, 0x39, 0x7d, 0x76, 0xa1, 0xb7, 0x27, 0x75, 0x7e, 0x5a, + 0x2f, 0x14, 0xc3, 0x3d, 0xc9, 0xba, 0xd9, 0x93, 0x5a, 0x0c, 0xe1, 0xba, + 0xb7, 0x27, 0xb9, 0x18, 0x9d, 0x17, 0xd9, 0x8a, 0x3e, 0xe1, 0x9e, 0x54, + 0x29, 0x9a, 0x15, 0xe9, 0x8f, 0xbf, 0x2a, 0x7d, 0x3d, 0xa9, 0xfa, 0x3f, + 0xd1, 0x1b, 0xa6, 0x26, 0x85, 0x5f, 0x15, 0x33, 0x9c, 0xb8, 0xd5, 0x7c, + 0xc8, 0xd2, 0xc4, 0xb4, 0x6e, 0x37, 0xb7, 0x58, 0x41, 0xc9, 0x9d, 0xee, + 0x14, 0x5b, 0xcd, 0xc9, 0x94, 0xdc, 0xe2, 0x90, 0xb9, 0x2c, 0x6d, 0x62, + 0x87, 0xfc, 0xeb, 0x66, 0x33, 0x19, 0xff, 0x32, 0xe5, 0x8a, 0x71, 0xa4, + 0x67, 0xbc, 0x2e, 0x92, 0x2c, 0x05, 0x25, 0x19, 0x7f, 0xab, 0xe9, 0x3e, + 0x13, 0xc4, 0x98, 0x81, 0x9e, 0xb1, 0x52, 0xb3, 0x99, 0x8e, 0x83, 0x7e, + 0xdc, 0x7f, 0xb6, 0x4d, 0xca, 0x21, 0xbb, 0x3c, 0x1b, 0xff, 0x6f, 0xba, + 0xab, 0x13, 0xce, 0x91, 0xd7, 0xb6, 0xe8, 0x56, 0x5e, 0x72, 0x21, 0x29, + 0x17, 0xe2, 0x9f, 0x92, 0x13, 0xf1, 0x30, 0xe6, 0x17, 0x94, 0x63, 0x71, + 0xc8, 0xd1, 0x3a, 0xac, 0x25, 0xeb, 0xd1, 0x48, 0x56, 0x9e, 0x97, 0xe4, + 0x62, 0xbf, 0x99, 0x16, 0x8c, 0x6d, 0x35, 0x3f, 0x9a, 0x8c, 0x63, 0xbc, + 0xe1, 0xff, 0xd5, 0xb4, 0x43, 0xd1, 0x6c, 0x59, 0x06, 0xa5, 0x50, 0xea, + 0x8f, 0xff, 0x4c, 0x34, 0x09, 0x5a, 0x62, 0x4f, 0x59, 0x26, 0xe4, 0x16, + 0x1d, 0x4c, 0x19, 0x4d, 0xd9, 0x83, 0xf1, 0x93, 0x16, 0xee, 0xd7, 0x65, + 0xb3, 0x6e, 0xb5, 0x4b, 0xc1, 0x94, 0x50, 0x97, 0x3c, 0x22, 0x85, 0xd3, + 0x68, 0x8f, 0xdb, 0xbd, 0x3a, 0x9e, 0xc9, 0x8c, 0xb0, 0x4d, 0x34, 0x23, + 0x11, 0x33, 0x53, 0xe0, 0xa8, 0xe2, 0x0c, 0x62, 0xfc, 0x98, 0xdd, 0xa9, + 0x99, 0xb2, 0x62, 0x06, 0xa4, 0xea, 0xc4, 0xec, 0xb0, 0xd6, 0x2e, 0xc7, + 0x62, 0x5d, 0x90, 0x69, 0x18, 0xb4, 0xe5, 0x9b, 0x7a, 0x22, 0x16, 0xce, + 0x41, 0x51, 0x3a, 0x64, 0x35, 0x07, 0x7e, 0xe6, 0xe2, 0x59, 0x2d, 0x55, + 0xff, 0x8a, 0x96, 0x3c, 0xbf, 0x5f, 0xdb, 0x75, 0x1e, 0x7d, 0xea, 0xe7, + 0x3c, 0xbb, 0x0b, 0x83, 0x37, 0x1d, 0xcf, 0xb2, 0x1d, 0x3c, 0x2b, 0xde, + 0xd1, 0x06, 0x5d, 0x36, 0x26, 0x43, 0x3d, 0x49, 0xa5, 0x4b, 0xf2, 0xa6, + 0x4b, 0x6e, 0x42, 0x93, 0x5e, 0xcb, 0x96, 0xe0, 0x27, 0xa1, 0xcf, 0x45, + 0xe8, 0x72, 0x31, 0x22, 0x47, 0x4a, 0x12, 0xd2, 0x85, 0x63, 0x65, 0xf5, + 0xaa, 0x43, 0x7b, 0x80, 0x6e, 0xa1, 0xfb, 0x82, 0xc3, 0x67, 0xa1, 0xc3, + 0x52, 0x1a, 0xf2, 0xc9, 0x60, 0xec, 0x7d, 0xda, 0x9e, 0xea, 0xa4, 0x96, + 0x81, 0x9d, 0x14, 0x4e, 0x0f, 0x41, 0x77, 0xd1, 0xc8, 0x8a, 0x6c, 0x96, + 0x82, 0x65, 0x45, 0xbe, 0x2c, 0xdd, 0x72, 0x6c, 0xd1, 0x92, 0x23, 0x8b, + 0x21, 0xc9, 0x9b, 0x51, 0xb3, 0x26, 0x7d, 0xd9, 0x4d, 0x89, 0x1e, 0x79, + 0xfe, 0x74, 0x34, 0x53, 0x96, 0x7e, 0xfb, 0x75, 0xdc, 0xcf, 0x9d, 0xa4, + 0x4e, 0x25, 0x9f, 0x8a, 0x1b, 0x92, 0x85, 0x4d, 0x18, 0xd6, 0x1f, 0x81, + 0xff, 0xe6, 0x73, 0xc9, 0x78, 0x34, 0x2c, 0xa2, 0x4b, 0xea, 0x0b, 0xfd, + 0xe6, 0x6e, 0x89, 0x9a, 0x19, 0xca, 0x3f, 0x3e, 0x04, 0x3d, 0xfc, 0x77, + 0xca, 0x1e, 0xb4, 0xa8, 0xe3, 0xa1, 0xf0, 0x31, 0xe8, 0x32, 0xab, 0x74, + 0xdc, 0x83, 0xf1, 0x03, 0x9e, 0xed, 0xf4, 0x48, 0xbe, 0x7a, 0xc3, 0x93, + 0x43, 0x8f, 0xcc, 0x57, 0xbb, 0xa5, 0x00, 0x1d, 0x16, 0xc4, 0x92, 0xc2, + 0xf9, 0x3f, 0xf7, 0xda, 0x2d, 0x99, 0x3b, 0xff, 0x32, 0xec, 0xe1, 0xb0, + 0xb6, 0xbf, 0xfe, 0x0b, 0xcd, 0xb3, 0x1f, 0xd8, 0x5f, 0x50, 0xec, 0x89, + 0xa0, 0x9c, 0xab, 0xbb, 0xf6, 0x57, 0xc1, 0x1a, 0xb3, 0x4d, 0x1b, 0xb6, + 0xf4, 0xc6, 0x6a, 0x9f, 0x73, 0xf5, 0x3e, 0x3c, 0x1b, 0x94, 0x23, 0x75, + 0xf6, 0xcf, 0xc3, 0xc6, 0x82, 0xb2, 0xf4, 0x68, 0xb7, 0x64, 0xd1, 0x5e, + 0x58, 0x14, 0x3b, 0x19, 0xd7, 0xf1, 0x4c, 0x0f, 0xe6, 0xb2, 0x15, 0x9f, + 0x2e, 0x99, 0xaa, 0x76, 0xd8, 0x86, 0x15, 0x92, 0xa9, 0x3a, 0xf5, 0x8f, + 0xef, 0x92, 0x6f, 0x03, 0x94, 0x2f, 0xdb, 0xf9, 0x1c, 0xdb, 0x4d, 0xb4, + 0xb7, 0xb6, 0xd1, 0xb6, 0x37, 0x53, 0xa6, 0x83, 0x82, 0xb6, 0x5c, 0x29, + 0x66, 0xee, 0xe7, 0x77, 0x9d, 0xf6, 0xd0, 0x6a, 0x0b, 0x01, 0xf4, 0x87, + 0x1e, 0xab, 0x18, 0xeb, 0xf4, 0x9d, 0x66, 0xdb, 0x08, 0xae, 0x2d, 0x2c, + 0xaa, 0x2e, 0x8e, 0x1d, 0x00, 0x5f, 0xba, 0x64, 0xab, 0x8a, 0xb7, 0x08, + 0x6d, 0xc0, 0x9d, 0x47, 0x9f, 0xcc, 0x2e, 0x76, 0xf7, 0xa4, 0x17, 0xd9, + 0x9e, 0x0c, 0x1b, 0x98, 0xe7, 0x54, 0x5c, 0x1a, 0x73, 0x71, 0xbd, 0x3f, + 0x00, 0xbe, 0xa6, 0xb1, 0xe0, 0x30, 0x0f, 0x8f, 0xc7, 0x06, 0xee, 0xf7, + 0xca, 0xd4, 0x79, 0xf6, 0xe5, 0x18, 0x85, 0x2d, 0xba, 0x24, 0xc0, 0x1b, + 0x3e, 0x56, 0x14, 0xf7, 0x3b, 0x31, 0x4e, 0x37, 0x6c, 0x27, 0x83, 0x31, + 0x9b, 0x8f, 0x27, 0xe3, 0xbd, 0x92, 0x5d, 0xed, 0x2b, 0xb0, 0x3b, 0xf6, + 0x1f, 0x5c, 0xd7, 0x17, 0xf2, 0x3d, 0x0f, 0x9a, 0x8b, 0x9d, 0x90, 0x21, + 0xdb, 0x75, 0xf0, 0xdc, 0x01, 0x1e, 0x82, 0x98, 0x4f, 0x3f, 0xd6, 0x43, + 0x07, 0xe8, 0x6f, 0xc2, 0x9c, 0x3a, 0x65, 0xfa, 0x74, 0x2f, 0x74, 0x61, + 0xa2, 0x6f, 0x50, 0x9e, 0x2f, 0x45, 0x61, 0x03, 0xec, 0x0f, 0x1d, 0x2c, + 0x46, 0xc3, 0x55, 0xb1, 0x65, 0x2e, 0xde, 0x01, 0xfb, 0x6a, 0x36, 0x67, + 0x60, 0x1f, 0xdf, 0x51, 0xfe, 0x62, 0xc8, 0x1c, 0xd3, 0x24, 0xdf, 0x91, + 0x38, 0x0c, 0x7e, 0xa2, 0x4f, 0x89, 0xf0, 0x7a, 0x87, 0xc6, 0x35, 0x0b, + 0x39, 0x72, 0x6c, 0xf8, 0xa4, 0xad, 0x90, 0x21, 0xfd, 0x56, 0x1f, 0xec, + 0x39, 0xac, 0xfc, 0xc9, 0xd8, 0x86, 0xfe, 0x24, 0x3a, 0x51, 0xc6, 0x58, + 0x85, 0xf3, 0x01, 0xfa, 0xb0, 0x51, 0x2c, 0x57, 0x79, 0x00, 0x6b, 0x6f, + 0x56, 0xd9, 0xc7, 0x09, 0xce, 0xb7, 0xf9, 0xf9, 0x38, 0xf9, 0xe2, 0x7c, + 0x6d, 0x3c, 0x4b, 0x1b, 0x8c, 0x1e, 0xb6, 0xd5, 0xf8, 0x27, 0xbc, 0xf1, + 0x5d, 0xde, 0x0b, 0xa5, 0x1e, 0x2d, 0xa5, 0x78, 0xf0, 0xe9, 0x88, 0x2c, + 0x9f, 0xec, 0x37, 0xf7, 0xc0, 0x86, 0xe9, 0xa7, 0x96, 0x2f, 0x50, 0xc7, + 0xa0, 0x31, 0x42, 0x1d, 0x9b, 0x8a, 0xbf, 0xe4, 0x22, 0xd7, 0x9e, 0xf4, + 0x19, 0x42, 0x1f, 0x01, 0x9f, 0x8b, 0xb5, 0x38, 0xeb, 0xad, 0xc5, 0x9c, + 0x43, 0xfb, 0x7b, 0x06, 0xcf, 0xea, 0x32, 0x16, 0xa3, 0x7f, 0x78, 0x5e, + 0x52, 0xf0, 0x91, 0xd0, 0xa3, 0x54, 0x31, 0x97, 0x4a, 0xa9, 0xd5, 0x6f, + 0xc1, 0xb6, 0x86, 0xff, 0xae, 0xe9, 0xfa, 0x43, 0xfa, 0x06, 0xfa, 0x9a, + 0x82, 0xa9, 0x43, 0x72, 0x3a, 0x9c, 0x21, 0x74, 0x13, 0x4f, 0x1a, 0xd1, + 0x4c, 0x16, 0x7c, 0x4d, 0x59, 0x4d, 0xb1, 0x1e, 0x13, 0x44, 0x0c, 0xf4, + 0xa9, 0xcb, 0x4e, 0xdf, 0x3f, 0x2d, 0x3b, 0xbe, 0x2e, 0xa8, 0x57, 0xea, + 0xc1, 0xf7, 0x11, 0x01, 0xb9, 0x0c, 0xdf, 0x35, 0x57, 0xea, 0x96, 0x06, + 0x78, 0xba, 0xe2, 0xf8, 0xb6, 0x66, 0x78, 0xb6, 0xc6, 0x67, 0xba, 0xf1, + 0x7c, 0x00, 0x7e, 0x4d, 0xf2, 0x46, 0x02, 0xbf, 0x8b, 0xa4, 0xc9, 0x36, + 0xdf, 0xce, 0xb9, 0x66, 0xa2, 0x76, 0x59, 0xda, 0x25, 0x13, 0x43, 0xfc, + 0x58, 0xd4, 0x31, 0x56, 0x1f, 0x7c, 0x79, 0x40, 0x0e, 0x96, 0x42, 0xf2, + 0xd5, 0x12, 0xe7, 0x95, 0xd6, 0x52, 0xd0, 0x5b, 0x72, 0xb1, 0x09, 0x9d, + 0x8f, 0xc3, 0xe7, 0x65, 0xb4, 0x31, 0xf8, 0x9f, 0xdd, 0xd5, 0xaf, 0x68, + 0xe9, 0xf3, 0x59, 0x6d, 0xbc, 0xbe, 0x5f, 0xcb, 0x9c, 0x9f, 0xd4, 0x76, + 0xb5, 0xf8, 0x22, 0xd1, 0xde, 0xdd, 0x17, 0x9d, 0x38, 0xcd, 0x31, 0xfb, + 0xe3, 0x1b, 0xfb, 0xa2, 0x5f, 0x6a, 0xad, 0xbe, 0xa8, 0x1f, 0xbe, 0x28, + 0x03, 0x5f, 0x34, 0x7e, 0xdf, 0xbe, 0xa8, 0x5d, 0xdf, 0xd8, 0x17, 0x75, + 0xeb, 0x77, 0x7d, 0x11, 0x63, 0xcf, 0xbf, 0xc6, 0xb5, 0x29, 0xdb, 0x76, + 0xfa, 0x72, 0x0e, 0xc3, 0x0f, 0x6f, 0x82, 0xac, 0xbb, 0xb8, 0x76, 0x22, + 0x05, 0xd8, 0xfd, 0x34, 0xc6, 0xfa, 0x4d, 0xd8, 0xfb, 0xb6, 0x98, 0x65, + 0x3e, 0xa1, 0xc6, 0x7d, 0xa7, 0xce, 0xc7, 0x56, 0x75, 0x4e, 0x1e, 0xdf, + 0x53, 0xe7, 0xb6, 0xab, 0x73, 0xea, 0xba, 0x53, 0x66, 0xd4, 0xb8, 0x4d, + 0x09, 0x3c, 0x26, 0xf0, 0x2a, 0xf2, 0x59, 0x23, 0x11, 0x05, 0x3d, 0x1d, + 0xe3, 0x53, 0x5f, 0x31, 0xf0, 0x20, 0xd0, 0x6f, 0xb7, 0xf2, 0x45, 0xbb, + 0xa0, 0xf7, 0x65, 0xe7, 0xfe, 0x74, 0x95, 0x69, 0xd1, 0xd5, 0x9e, 0x35, + 0xba, 0xea, 0x90, 0xe1, 0x98, 0xaf, 0xa3, 0xcd, 0x92, 0x8c, 0x51, 0x67, + 0xf7, 0xa3, 0xab, 0x7f, 0xaa, 0xff, 0xfd, 0xe8, 0xea, 0xb7, 0xee, 0xa1, + 0xab, 0x7f, 0xb5, 0x4e, 0x57, 0x96, 0xf9, 0x82, 0x46, 0xda, 0x8c, 0x1f, + 0xf4, 0x47, 0xcd, 0x8f, 0x4e, 0x31, 0x7f, 0xa8, 0x73, 0x4d, 0xfb, 0x79, + 0x07, 0xd7, 0xf3, 0xa5, 0xa6, 0x61, 0x59, 0x90, 0x1d, 0xd7, 0x34, 0xe5, + 0x16, 0x35, 0x3f, 0x4f, 0xfe, 0x11, 0x3b, 0xa6, 0x10, 0x6b, 0x5c, 0x1e, + 0xda, 0xa5, 0xbc, 0xc5, 0xed, 0x3f, 0x55, 0x6a, 0xfe, 0x42, 0x4f, 0xbc, + 0xdd, 0x4c, 0x8e, 0x58, 0x5e, 0x1c, 0x08, 0xca, 0xd7, 0xaa, 0xd1, 0xac, + 0xad, 0x75, 0x4b, 0xfe, 0x41, 0xc4, 0x9e, 0x12, 0xfd, 0xd7, 0xd6, 0x7b, + 0xc4, 0xe8, 0x3e, 0x2f, 0x46, 0x57, 0xc1, 0x2b, 0xf3, 0xab, 0xef, 0xbe, + 0xd5, 0x08, 0xf1, 0x3b, 0x66, 0xee, 0x93, 0x2f, 0x73, 0x8e, 0x88, 0xf7, + 0x8c, 0xfb, 0x16, 0x73, 0x9e, 0x7c, 0x20, 0xd1, 0x25, 0xf9, 0x2d, 0x5c, + 0x8f, 0xf4, 0x73, 0xf4, 0x5d, 0xed, 0x1e, 0xdf, 0x7e, 0x8e, 0xa4, 0x78, + 0x33, 0x30, 0x65, 0xf4, 0x41, 0x3e, 0x54, 0xe2, 0x3c, 0xde, 0xf2, 0xec, + 0x89, 0xb9, 0x82, 0xb4, 0xb9, 0xbe, 0x61, 0x2f, 0x72, 0x01, 0xda, 0x81, + 0xaf, 0x73, 0xea, 0x9b, 0x39, 0x82, 0x44, 0x74, 0x8b, 0x39, 0x82, 0x98, + 0x46, 0x62, 0x9f, 0x66, 0x43, 0xf7, 0x36, 0x74, 0x6f, 0x43, 0xf7, 0x36, + 0x74, 0x9f, 0xac, 0x1f, 0xc6, 0x3d, 0x95, 0x87, 0x80, 0x17, 0x97, 0x7e, + 0xda, 0xa5, 0x0f, 0x3e, 0xb7, 0x4a, 0x4e, 0xe9, 0x84, 0xf3, 0x45, 0xae, + 0xa1, 0xfc, 0xf5, 0xb8, 0xe6, 0xfa, 0x6b, 0xd2, 0xcb, 0xe0, 0xf9, 0xdb, + 0x98, 0xa7, 0xad, 0xeb, 0xd6, 0x5d, 0x99, 0xcc, 0xb5, 0xc8, 0x64, 0xd6, + 0xa1, 0x8c, 0xd8, 0x9f, 0x3e, 0x77, 0x5a, 0xaf, 0xac, 0xca, 0x65, 0x2f, + 0x78, 0xe8, 0xe0, 0xdc, 0xbd, 0x79, 0x90, 0x7e, 0xaf, 0x47, 0xff, 0x6f, + 0xd1, 0x87, 0xfe, 0x75, 0xa3, 0x71, 0x39, 0x26, 0x73, 0xc6, 0x77, 0x9b, + 0x0f, 0x72, 0x66, 0xac, 0x81, 0xef, 0x21, 0x96, 0x5f, 0x44, 0x2c, 0x59, + 0x31, 0x22, 0xf2, 0x93, 0x47, 0xaf, 0x21, 0x97, 0x96, 0xfc, 0xc3, 0x89, + 0x66, 0x24, 0x90, 0x78, 0xab, 0x39, 0x37, 0x82, 0x18, 0x97, 0x88, 0x86, + 0x93, 0xc6, 0xb0, 0x5c, 0xaa, 0x0f, 0xca, 0x8f, 0xea, 0x96, 0xfc, 0xb0, + 0x1e, 0x91, 0x1f, 0x20, 0xe6, 0x7f, 0xbf, 0xde, 0x9a, 0x73, 0x47, 0x68, + 0x4f, 0x3d, 0xe9, 0xfa, 0x46, 0xb9, 0x7f, 0x13, 0x34, 0xde, 0x82, 0x9d, + 0x04, 0xb2, 0xc8, 0xf5, 0x19, 0xbf, 0x26, 0x0e, 0x15, 0x9f, 0x6b, 0x82, + 0xb7, 0x6c, 0x5b, 0xc2, 0xca, 0xeb, 0x7a, 0xf7, 0xa8, 0xf9, 0x29, 0xb4, + 0x39, 0xa3, 0x81, 0x6a, 0xb1, 0x53, 0xe5, 0x8b, 0xd0, 0x91, 0xd8, 0xf5, + 0x60, 0xb0, 0x56, 0xbc, 0x85, 0x7e, 0xcd, 0xe6, 0xa1, 0xf8, 0x6f, 0xed, + 0x30, 0xff, 0x81, 0x85, 0x35, 0xdd, 0xf9, 0x25, 0x23, 0xb1, 0x49, 0x66, + 0x43, 0xdf, 0x6f, 0x98, 0x03, 0x7d, 0x59, 0x3d, 0x11, 0x94, 0x74, 0x91, + 0x6b, 0x2a, 0x24, 0xb3, 0x55, 0x28, 0xff, 0x3c, 0xd7, 0x85, 0x3c, 0x3b, + 0x17, 0xef, 0x86, 0xed, 0xff, 0x9a, 0xe1, 0xae, 0x03, 0x18, 0x50, 0x75, + 0x50, 0xf2, 0xe0, 0x37, 0x5f, 0x7f, 0xcb, 0xc3, 0x0e, 0xf0, 0x2a, 0x5b, + 0x21, 0xf8, 0xc4, 0x70, 0xda, 0x76, 0xfe, 0x30, 0x88, 0xb6, 0xe0, 0x56, + 0xeb, 0xce, 0x26, 0x7c, 0x3f, 0x10, 0xb2, 0x88, 0x4d, 0x24, 0xf3, 0x05, + 0x7c, 0xff, 0x4a, 0x42, 0x36, 0xf7, 0xe2, 0x7b, 0x4b, 0x02, 0x26, 0x99, + 0x60, 0xcc, 0xd5, 0x5a, 0x62, 0xae, 0x68, 0x69, 0xc8, 0x6e, 0x0e, 0x73, + 0x4f, 0x43, 0x9e, 0x5f, 0xac, 0x07, 0xb5, 0xd4, 0xe9, 0x47, 0xc0, 0x87, + 0x9f, 0x3b, 0x23, 0x3f, 0x33, 0x97, 0xb7, 0x04, 0xe4, 0x16, 0x7c, 0x5c, + 0x12, 0x7e, 0xcc, 0x46, 0x6e, 0xb1, 0x03, 0xcb, 0x35, 0xfa, 0x5f, 0xbf, + 0x20, 0x5f, 0xf3, 0x78, 0x6b, 0x93, 0x05, 0x65, 0xa3, 0x6c, 0xcf, 0x67, + 0xfe, 0xcd, 0xc0, 0xdd, 0xf6, 0x17, 0x57, 0xdb, 0xcb, 0x99, 0x7f, 0xb8, + 0xda, 0xde, 0xdb, 0xe6, 0xf2, 0x3f, 0xaa, 0x4d, 0xd4, 0xf7, 0x78, 0x6d, + 0xb7, 0xa1, 0xb3, 0x66, 0x93, 0xb9, 0x45, 0x01, 0xd8, 0x24, 0x1d, 0xa7, + 0x2f, 0xbe, 0x1f, 0x5f, 0xbb, 0xc6, 0xcf, 0x9a, 0x49, 0x83, 0xb6, 0x10, + 0x14, 0x97, 0x26, 0xef, 0x77, 0x20, 0x7f, 0xbf, 0x8d, 0xdf, 0x8c, 0xa3, + 0x7e, 0x6e, 0xce, 0x3e, 0x7c, 0xfe, 0xcd, 0x7b, 0xd8, 0x4b, 0x08, 0xf6, + 0xf2, 0xff, 0xab, 0x5d, 0x5c, 0xba, 0x1f, 0xbb, 0xc0, 0x9f, 0xb2, 0x0b, + 0xd5, 0xff, 0xd2, 0xea, 0x5a, 0x09, 0x43, 0x3e, 0x8c, 0x07, 0x83, 0xd0, + 0xf1, 0x66, 0x99, 0xb5, 0xc8, 0x8f, 0x15, 0xc9, 0xc1, 0x5f, 0x9e, 0x58, + 0x17, 0xbb, 0xbb, 0x10, 0x0f, 0x8e, 0x9f, 0x8e, 0x8e, 0x32, 0x1e, 0xc4, + 0xe0, 0x1b, 0x93, 0xef, 0x88, 0x07, 0x37, 0x8c, 0xd6, 0x78, 0x60, 0x20, + 0x1e, 0xec, 0x7a, 0x97, 0x78, 0x70, 0xe2, 0x1d, 0xf1, 0x40, 0x83, 0x6c, + 0x38, 0xbf, 0xbf, 0x35, 0xfc, 0x78, 0x50, 0x58, 0x13, 0x0f, 0x7c, 0x5d, + 0x59, 0x0a, 0x0b, 0xdc, 0xd5, 0x5b, 0x97, 0xa7, 0x2b, 0x09, 0x06, 0x12, + 0x8d, 0xcc, 0x9c, 0xf5, 0xb0, 0xb4, 0xc1, 0xe7, 0x5e, 0xaa, 0x8f, 0x40, + 0x67, 0x97, 0x30, 0xf7, 0x68, 0x9c, 0x89, 0x65, 0x5b, 0x82, 0xeb, 0xe1, + 0xcd, 0x08, 0x30, 0xe2, 0x6e, 0xe0, 0xbe, 0xdd, 0x67, 0xd5, 0xfa, 0x78, + 0x33, 0xea, 0x61, 0xf7, 0x6d, 0xc0, 0xee, 0x78, 0x3e, 0x00, 0x4c, 0xc8, + 0xf6, 0x2b, 0x66, 0x12, 0x7a, 0xaa, 0x3a, 0xf6, 0xee, 0x02, 0x3e, 0x73, + 0xaa, 0xef, 0xad, 0x08, 0xfb, 0x76, 0x24, 0x12, 0xd1, 0x3f, 0xc3, 0x77, + 0x7b, 0x22, 0xbc, 0xed, 0xaa, 0x45, 0xba, 0x87, 0xa2, 0x67, 0x15, 0x8d, + 0x80, 0x14, 0xd4, 0xb3, 0x91, 0x6d, 0x7c, 0xf6, 0x18, 0x62, 0xf6, 0x51, + 0xc7, 0x94, 0x23, 0x4e, 0x76, 0x77, 0x0e, 0x1f, 0x62, 0xd5, 0x4b, 0x25, + 0xde, 0x1f, 0xc5, 0xfd, 0x80, 0x30, 0x97, 0xfc, 0x2a, 0xfa, 0x1c, 0x44, + 0x9f, 0x19, 0xc7, 0xd7, 0x05, 0xef, 0x37, 0x32, 0x29, 0xdc, 0x9f, 0x29, + 0x36, 0x32, 0xe9, 0x22, 0xf3, 0xd6, 0xa1, 0xf0, 0x11, 0xc8, 0x33, 0x8b, + 0x5c, 0xcd, 0x96, 0xe8, 0x60, 0x5e, 0x9e, 0xee, 0x1c, 0x07, 0x4e, 0x3a, + 0x87, 0x1c, 0xc2, 0x9e, 0x8c, 0xc6, 0xcb, 0xf2, 0xe1, 0xce, 0xe4, 0x69, + 0xe4, 0x0b, 0xf1, 0xed, 0x90, 0x61, 0x23, 0xa3, 0xc7, 0x04, 0xb6, 0x1e, + 0x87, 0x5f, 0x1e, 0xd1, 0x53, 0xc5, 0x7e, 0x73, 0x56, 0x1e, 0x95, 0x86, + 0x19, 0x0d, 0x8f, 0xcb, 0x26, 0x49, 0x05, 0xd0, 0x6f, 0xf0, 0x43, 0x92, + 0x0d, 0x53, 0xd6, 0x0f, 0xc2, 0xdf, 0x6b, 0xd2, 0x61, 0xb5, 0xc6, 0x9e, + 0x5b, 0x10, 0x6f, 0x2e, 0x40, 0x9f, 0xdd, 0x61, 0x75, 0x7a, 0x3a, 0xd9, + 0x24, 0xcb, 0xef, 0xe8, 0x77, 0xbb, 0xa5, 0x5f, 0x6b, 0xfb, 0xdb, 0x68, + 0xdf, 0x84, 0x9c, 0xb3, 0x91, 0x09, 0xc4, 0x20, 0x7f, 0xcc, 0xa1, 0x0d, + 0x76, 0x72, 0x15, 0xf3, 0x61, 0x1c, 0x2c, 0x94, 0x99, 0xf7, 0x18, 0x52, + 0x36, 0x71, 0xcf, 0x69, 0x36, 0x2b, 0x16, 0xf8, 0xbd, 0x40, 0x9e, 0x83, + 0x32, 0xee, 0x0c, 0x88, 0x5d, 0xa3, 0x1c, 0xa2, 0xf0, 0x4a, 0x0f, 0x77, + 0xa5, 0x16, 0xa3, 0x76, 0x1e, 0x14, 0x8d, 0x0b, 0x7d, 0x5d, 0x49, 0xe4, + 0x39, 0xfa, 0x85, 0x48, 0x57, 0x0a, 0x36, 0x6b, 0x5c, 0x78, 0xa8, 0x2b, + 0x7d, 0x9a, 0x7c, 0x19, 0xc8, 0x73, 0x3e, 0x0a, 0x9c, 0xdf, 0x94, 0xdf, + 0x45, 0x2e, 0x5b, 0x18, 0x44, 0x0e, 0x80, 0xd5, 0xaf, 0x83, 0xef, 0xbc, + 0x29, 0xc1, 0xae, 0xc4, 0xab, 0xe0, 0x6f, 0x18, 0xb2, 0xd9, 0x84, 0x3e, + 0x06, 0xda, 0x07, 0x58, 0x13, 0x68, 0x69, 0xb7, 0xba, 0x10, 0x4f, 0x11, + 0xbb, 0x24, 0x98, 0x1c, 0xe9, 0x06, 0xfd, 0x2b, 0x01, 0xe6, 0x82, 0xc1, + 0xd8, 0x6a, 0xfb, 0x37, 0xdd, 0xf6, 0x41, 0xf0, 0xc2, 0xe7, 0x88, 0x09, + 0x24, 0x38, 0x35, 0x62, 0x82, 0x07, 0xf6, 0x0d, 0xa9, 0xbe, 0xe9, 0x45, + 0xda, 0x40, 0x23, 0x53, 0xb1, 0x1e, 0x91, 0xd4, 0xc2, 0x56, 0x19, 0x5f, + 0xe8, 0x95, 0x5d, 0x0b, 0xc4, 0x30, 0xac, 0x69, 0x60, 0x2a, 0xc0, 0x18, + 0xfa, 0x05, 0xe6, 0x76, 0xd1, 0xf0, 0x41, 0xe9, 0x0f, 0x7f, 0x15, 0xeb, + 0x60, 0xca, 0x8a, 0x45, 0x66, 0xb1, 0xc6, 0x02, 0x8a, 0x4e, 0xd8, 0x1f, + 0x93, 0x36, 0xba, 0x66, 0xdc, 0xf4, 0xe2, 0xbd, 0xe8, 0x62, 0xe1, 0x5c, + 0x08, 0xaf, 0xa3, 0xfb, 0x57, 0x1e, 0x5d, 0x13, 0x74, 0xfb, 0x40, 0x93, + 0x73, 0x7c, 0xa8, 0x73, 0xec, 0xb4, 0xd8, 0x1d, 0xe0, 0x2f, 0x1d, 0x7b, + 0x58, 0x66, 0x41, 0xe7, 0xe8, 0x02, 0xfd, 0xa4, 0x6c, 0xc5, 0x67, 0xb8, + 0x4d, 0x62, 0x83, 0xe7, 0x81, 0x73, 0xc6, 0x14, 0x0d, 0x17, 0x73, 0xe8, + 0x17, 0x12, 0xc0, 0xa9, 0x1f, 0x07, 0x3f, 0xcc, 0xb1, 0x38, 0xe7, 0x00, + 0xe6, 0x9b, 0xc0, 0x3a, 0x64, 0x7d, 0x85, 0xeb, 0x1b, 0xbf, 0xcf, 0x87, + 0x3b, 0x53, 0xa7, 0xdb, 0xb1, 0xee, 0xe4, 0x11, 0x43, 0xc5, 0x7e, 0xea, + 0xc5, 0xea, 0x4c, 0x96, 0x14, 0xdf, 0x9d, 0xa9, 0x12, 0x65, 0x14, 0xef, + 0x4c, 0x97, 0x28, 0x23, 0x01, 0x3f, 0x71, 0xd8, 0x64, 0x40, 0x22, 0x5b, + 0xa8, 0xc7, 0x43, 0xe8, 0xf7, 0x57, 0x01, 0xe2, 0xb8, 0xa4, 0xc5, 0xdf, + 0xf0, 0xb5, 0x17, 0x0e, 0xa3, 0x2f, 0x7f, 0x6f, 0x07, 0xdd, 0xfe, 0xc1, + 0x82, 0xb4, 0x0f, 0xce, 0xc0, 0x4f, 0xe8, 0x23, 0xc0, 0x91, 0xca, 0xce, + 0x9b, 0xc0, 0xd8, 0x3b, 0x30, 0x1f, 0xac, 0x8d, 0x98, 0x25, 0xd3, 0xf3, + 0x94, 0xab, 0x7c, 0x08, 0x73, 0xc0, 0xfc, 0x63, 0xf0, 0x2d, 0x9c, 0x03, + 0xc7, 0x16, 0xe4, 0x36, 0x4b, 0x92, 0x9b, 0x0f, 0x2a, 0x2c, 0x6b, 0x9b, + 0x1c, 0x5f, 0xd3, 0xf4, 0x44, 0x17, 0x74, 0xcc, 0xb9, 0xcd, 0x81, 0xb7, + 0x67, 0x10, 0xff, 0xa2, 0x0a, 0x43, 0x19, 0x17, 0xb8, 0x56, 0x46, 0xb1, + 0x4e, 0xc8, 0xbf, 0x67, 0x7b, 0x5a, 0x03, 0x3e, 0x45, 0xf9, 0x7f, 0xe4, + 0xea, 0x09, 0xf8, 0x91, 0x51, 0xf9, 0x7d, 0xf8, 0x92, 0x1f, 0xd7, 0xe3, + 0xc8, 0x1b, 0x86, 0x91, 0x37, 0x0c, 0x22, 0x6f, 0xb0, 0x90, 0x37, 0x44, + 0x90, 0x37, 0xf4, 0x21, 0x6f, 0x08, 0x23, 0x3e, 0x88, 0x1c, 0xad, 0xe7, + 0x61, 0x63, 0x0d, 0xf8, 0x41, 0x33, 0x68, 0xd7, 0x43, 0xc1, 0x64, 0x3d, + 0x1c, 0x4c, 0xd5, 0x03, 0x98, 0xd3, 0x01, 0x8e, 0x89, 0xf9, 0xe5, 0x3b, + 0xc7, 0x4a, 0xc3, 0x88, 0x39, 0x36, 0xfc, 0x52, 0x1a, 0xf1, 0x36, 0x2e, + 0x47, 0xf0, 0xcc, 0xf2, 0x7c, 0x04, 0xcf, 0x34, 0x25, 0x1d, 0x6f, 0x93, + 0x59, 0x33, 0x0e, 0x1a, 0x5b, 0x94, 0x9d, 0x22, 0xdf, 0x6a, 0x83, 0x9d, + 0x4a, 0xae, 0xc8, 0x7c, 0xab, 0x0f, 0xf4, 0x3a, 0x11, 0x97, 0xe9, 0x1f, + 0xe8, 0x0b, 0xec, 0xdd, 0x5f, 0xb2, 0xb8, 0xe6, 0xba, 0xb4, 0xe4, 0xe9, + 0xbc, 0x10, 0x6b, 0x22, 0x0e, 0xc2, 0x2e, 0xd8, 0x36, 0x81, 0xe7, 0xf8, + 0xfb, 0x6d, 0xcf, 0xef, 0x7f, 0x24, 0x28, 0x30, 0xde, 0x4b, 0x8c, 0xf9, + 0x16, 0xe8, 0x39, 0xad, 0xeb, 0xb5, 0xa6, 0x8b, 0xe5, 0xdf, 0x67, 0xfd, + 0x8d, 0x35, 0xc7, 0xd7, 0xc0, 0x73, 0xbf, 0xb9, 0x8c, 0x1c, 0xd9, 0xde, + 0xbf, 0x82, 0xdf, 0xad, 0xfd, 0xeb, 0xe8, 0xaf, 0xda, 0x82, 0x66, 0x22, + 0xce, 0x7c, 0x18, 0x3e, 0x73, 0x10, 0xfe, 0xf1, 0x56, 0x46, 0x5f, 0xba, + 0x89, 0x79, 0x42, 0x9e, 0xc5, 0x5b, 0x99, 0xc0, 0xc0, 0xb5, 0xe6, 0x8b, + 0xc0, 0x37, 0x63, 0x4b, 0x23, 0x92, 0x5a, 0xea, 0x0f, 0x5f, 0x96, 0xce, + 0xdb, 0xb6, 0x5c, 0x6b, 0xce, 0x3a, 0xd1, 0xe3, 0xb6, 0x10, 0x6f, 0x99, + 0x52, 0x01, 0xa9, 0x6d, 0x3b, 0x3b, 0x88, 0x19, 0x2f, 0x8a, 0x1e, 0x91, + 0xe4, 0x29, 0x5b, 0x46, 0x76, 0xfa, 0xb9, 0xfb, 0x9d, 0x0e, 0xe9, 0x42, + 0xdb, 0x52, 0x04, 0x7d, 0x88, 0x53, 0x39, 0xef, 0x2c, 0xe6, 0xac, 0xb9, + 0xcf, 0x78, 0xf5, 0xc9, 0x42, 0x09, 0x73, 0xaf, 0xdf, 0xca, 0x5c, 0x3e, + 0x05, 0xec, 0x0e, 0x1d, 0x25, 0x4f, 0xb1, 0xae, 0xb0, 0x09, 0x72, 0x1a, + 0x83, 0xad, 0xd0, 0x06, 0xfa, 0xf1, 0x6c, 0x53, 0xbe, 0x11, 0xa7, 0x5d, + 0xbc, 0x04, 0x59, 0x82, 0x56, 0xc0, 0x9f, 0x0f, 0x70, 0xde, 0x3c, 0xe5, + 0x17, 0x46, 0x6e, 0xce, 0xb1, 0x25, 0xd8, 0x99, 0x58, 0x9f, 0x77, 0xdf, + 0xca, 0x2c, 0x9f, 0x02, 0xfd, 0x01, 0xd6, 0xde, 0xe0, 0xb3, 0x8b, 0xac, + 0x1d, 0x32, 0x27, 0xdd, 0x05, 0x3d, 0xed, 0x55, 0xb5, 0xb8, 0x64, 0x35, + 0x2e, 0xd6, 0x49, 0xfa, 0x2c, 0x89, 0x18, 0xd6, 0x7e, 0xe4, 0xaf, 0x62, + 0xea, 0x89, 0x49, 0xdc, 0xa3, 0x3c, 0x35, 0xe4, 0x1c, 0xb8, 0x7f, 0x61, + 0x45, 0xe9, 0xc4, 0x80, 0xee, 0x72, 0x3b, 0x99, 0x84, 0xc9, 0xbc, 0x91, + 0x80, 0x2f, 0x1c, 0xe1, 0x1c, 0xd4, 0xd8, 0xc8, 0xc7, 0xb9, 0xfe, 0x30, + 0x67, 0xd8, 0x55, 0x4b, 0x5e, 0xae, 0xfe, 0x66, 0x4b, 0x47, 0x60, 0xd3, + 0x92, 0x6f, 0x43, 0x3e, 0x90, 0x1c, 0xc1, 0x6f, 0x38, 0x81, 0xa3, 0xd0, + 0xe7, 0xd9, 0x11, 0xd6, 0x3f, 0x5f, 0x02, 0xb6, 0x27, 0xdf, 0xb1, 0xc8, + 0x11, 0xb5, 0x86, 0x71, 0xed, 0x30, 0x97, 0xdb, 0x24, 0x97, 0xd5, 0xfc, + 0x1e, 0x22, 0xf6, 0x80, 0x9e, 0xee, 0x67, 0x7e, 0xe3, 0xf7, 0x39, 0x3f, + 0x97, 0x3e, 0x63, 0x57, 0xd2, 0x8a, 0x48, 0xaa, 0x78, 0xa9, 0x19, 0xb0, + 0x2c, 0x60, 0x67, 0x57, 0x8f, 0x29, 0x27, 0x08, 0x3e, 0x58, 0x6b, 0xdb, + 0xa9, 0x74, 0x09, 0x3e, 0x68, 0x3b, 0xf9, 0x60, 0x62, 0xb3, 0x9c, 0x9b, + 0xef, 0x91, 0xca, 0xfc, 0xcf, 0xa5, 0x3a, 0xdf, 0x25, 0xe7, 0xe7, 0x9b, + 0x72, 0x35, 0xae, 0x7c, 0x93, 0xd5, 0xae, 0xd6, 0xb5, 0x3c, 0xec, 0xd6, + 0x61, 0x62, 0xa3, 0xd7, 0xe5, 0x79, 0x39, 0x57, 0x76, 0x79, 0xcf, 0xb4, + 0xf0, 0x7e, 0x15, 0xb6, 0xf6, 0xaa, 0x45, 0xfe, 0x47, 0xa4, 0x52, 0x24, + 0xef, 0xfb, 0x14, 0xef, 0xbb, 0x56, 0x79, 0x97, 0xac, 0x61, 0x91, 0xff, + 0x8d, 0x78, 0xef, 0x90, 0xec, 0x56, 0xf2, 0x1f, 0xc1, 0xb3, 0xef, 0xb4, + 0xbf, 0x8a, 0x73, 0xad, 0xb9, 0x5c, 0x6c, 0x53, 0x3c, 0x1b, 0x89, 0x11, + 0xc8, 0xe7, 0x5a, 0xb3, 0xe1, 0x70, 0x1d, 0xe1, 0xb7, 0xf3, 0x2f, 0xe0, + 0xab, 0x7a, 0x55, 0xce, 0x92, 0x9b, 0xec, 0xee, 0x4c, 0x2e, 0x8e, 0x42, + 0xb7, 0x9d, 0x6a, 0x1d, 0xc2, 0x6d, 0x40, 0x67, 0xff, 0x1e, 0xfd, 0xbf, + 0xcd, 0xf5, 0xa6, 0xe4, 0x92, 0x86, 0x5c, 0x0a, 0xc5, 0xf1, 0x76, 0xe0, + 0x27, 0x8c, 0xd3, 0xc8, 0x64, 0x1d, 0x3e, 0xd3, 0x07, 0xdf, 0xc6, 0xef, + 0xf7, 0x6d, 0x0f, 0x79, 0xf8, 0x5c, 0xe8, 0x1c, 0x79, 0x05, 0xd7, 0xf3, + 0x48, 0x03, 0x31, 0x36, 0x36, 0x58, 0x51, 0xfb, 0x10, 0x71, 0x85, 0x85, + 0x67, 0x9d, 0x6f, 0xe3, 0xe3, 0x8e, 0x37, 0x56, 0xe7, 0x98, 0x6b, 0xe7, + 0x54, 0x70, 0x1a, 0xc8, 0xdf, 0x2d, 0xd0, 0xe5, 0xb8, 0x79, 0x31, 0x12, + 0x06, 0xc6, 0x65, 0x5b, 0x37, 0x7c, 0x4c, 0x04, 0x3e, 0x6b, 0x18, 0xbe, + 0x9f, 0x6b, 0x99, 0x7e, 0xde, 0xe7, 0x7d, 0x18, 0x34, 0xe9, 0x7f, 0x87, + 0x31, 0x67, 0xe6, 0xd8, 0xf4, 0x9f, 0x88, 0x27, 0xb5, 0x70, 0x57, 0xf2, + 0xb4, 0x5b, 0x1b, 0x74, 0x7f, 0xf3, 0xbe, 0x04, 0x1f, 0x49, 0x44, 0xcb, + 0x79, 0xe4, 0x7e, 0x29, 0xac, 0xd1, 0xa4, 0x85, 0x3c, 0xbb, 0x16, 0x7d, + 0x85, 0x98, 0x5b, 0xa7, 0x0c, 0x96, 0x28, 0x27, 0xd6, 0xa9, 0x4c, 0xc9, + 0x57, 0xbe, 0x0b, 0x79, 0x04, 0x65, 0x8b, 0x95, 0x85, 0x4f, 0x01, 0xff, + 0x98, 0xfb, 0x5c, 0x89, 0xb5, 0xc8, 0x7e, 0xc4, 0x31, 0x03, 0x42, 0x40, + 0x4e, 0xb5, 0x64, 0xc8, 0x67, 0x03, 0x43, 0xc8, 0x01, 0x9f, 0x45, 0xdf, + 0x80, 0xe4, 0x97, 0x18, 0x0f, 0x02, 0x32, 0xb7, 0x24, 0x72, 0xfd, 0x14, + 0xfd, 0x8a, 0xfa, 0x83, 0xcc, 0x1b, 0x99, 0x69, 0x62, 0xed, 0x79, 0xfa, + 0x18, 0xfa, 0x89, 0x07, 0xa1, 0x8b, 0xd8, 0x4b, 0xdf, 0x40, 0x6c, 0x9a, + 0x2d, 0xf6, 0xc3, 0x67, 0x4a, 0x43, 0x87, 0x4c, 0x11, 0xd3, 0x98, 0xa3, + 0x6f, 0x50, 0x77, 0xf4, 0x6b, 0x8e, 0x41, 0x29, 0x9c, 0x62, 0xbd, 0x31, + 0x08, 0x5e, 0x98, 0xb7, 0x1a, 0x2a, 0x0f, 0x7a, 0x50, 0xf9, 0x56, 0x7e, + 0x07, 0x5a, 0xc6, 0x8d, 0x1d, 0xdf, 0xa6, 0xd3, 0x8f, 0x3d, 0x22, 0xf6, + 0xc4, 0xa1, 0xce, 0x5d, 0xa5, 0x76, 0x29, 0xf7, 0xd2, 0x2e, 0xa9, 0xff, + 0xac, 0x4e, 0x5f, 0x8b, 0x3c, 0x0c, 0xf4, 0x58, 0x23, 0x08, 0xa0, 0x5f, + 0xc8, 0xeb, 0x47, 0xb9, 0xfe, 0xb6, 0x4c, 0xed, 0xfc, 0x3b, 0xf0, 0xe5, + 0xfa, 0xb5, 0xdc, 0x4e, 0xf8, 0xdb, 0x09, 0x5d, 0x1e, 0xfb, 0x54, 0x1a, + 0xcf, 0x32, 0x16, 0xde, 0xf2, 0xf0, 0x38, 0xdb, 0x58, 0xa3, 0x45, 0x9e, + 0x7e, 0xce, 0xc4, 0x77, 0xaf, 0xe4, 0xcf, 0x05, 0x21, 0x07, 0xe4, 0xc4, + 0x15, 0x97, 0x16, 0xf3, 0xde, 0xe3, 0xd0, 0x91, 0x7e, 0x32, 0x28, 0x6d, + 0x27, 0x7b, 0x25, 0xf0, 0xad, 0x2e, 0x69, 0xff, 0xd6, 0x80, 0x18, 0xdf, + 0x62, 0x2d, 0x29, 0x1a, 0x39, 0xaa, 0xea, 0x58, 0x69, 0x39, 0x86, 0xf8, + 0xa5, 0x23, 0x16, 0x2b, 0x3b, 0x35, 0xb7, 0x8a, 0x81, 0xc4, 0x55, 0x7f, + 0xc1, 0x96, 0xaf, 0xef, 0xfc, 0x85, 0xaa, 0xa3, 0x26, 0x47, 0x70, 0xfd, + 0x72, 0x06, 0xd8, 0x44, 0x83, 0xad, 0x34, 0x32, 0xd7, 0x1e, 0xf5, 0x73, + 0xcb, 0x41, 0x55, 0x93, 0xff, 0xfa, 0x4e, 0x37, 0xb7, 0x9c, 0x45, 0x6e, + 0x99, 0x56, 0xb9, 0x25, 0xfc, 0x6b, 0x80, 0xfd, 0xb6, 0x8a, 0x8e, 0xb1, + 0x72, 0xc2, 0x5c, 0xfd, 0xa3, 0x62, 0x1f, 0xc0, 0xba, 0x38, 0x23, 0xf3, + 0x7a, 0x42, 0x53, 0x34, 0x8d, 0x17, 0xe8, 0xa7, 0xe8, 0xbf, 0x68, 0xe3, + 0xac, 0x69, 0xa1, 0xed, 0x65, 0xfa, 0x28, 0xd7, 0xb6, 0xc7, 0x5a, 0x7c, + 0xdd, 0x5c, 0xa9, 0x0e, 0x1d, 0x22, 0xa7, 0xb7, 0xda, 0x30, 0x7f, 0xc4, + 0x74, 0x8b, 0xd7, 0x9c, 0x3f, 0x7c, 0x67, 0x28, 0xa4, 0xae, 0x0b, 0x65, + 0xb7, 0x86, 0xe1, 0xd2, 0x67, 0xfe, 0x01, 0x1f, 0x53, 0x27, 0x1f, 0x1c, + 0xb7, 0x4f, 0x8c, 0x33, 0x21, 0x09, 0x9c, 0xa1, 0xfd, 0x45, 0x23, 0x69, + 0xc8, 0x6f, 0xce, 0x22, 0x06, 0x3c, 0x04, 0x6c, 0xf4, 0x88, 0xe8, 0xe7, + 0x06, 0xb1, 0x76, 0xa2, 0xe1, 0xb2, 0xc4, 0xc4, 0xa8, 0x04, 0xe5, 0x8d, + 0x53, 0xd1, 0x08, 0xed, 0xe5, 0x2c, 0xe2, 0xd5, 0x91, 0x7a, 0xe7, 0xed, + 0x86, 0xe2, 0x82, 0x6d, 0xdf, 0x08, 0x00, 0x3b, 0x0c, 0xda, 0x7a, 0xb7, + 0xdc, 0x80, 0xbe, 0xb3, 0xaa, 0xed, 0x11, 0xd0, 0x05, 0x0f, 0x67, 0x58, + 0x1b, 0x24, 0xdd, 0xa3, 0xa0, 0x49, 0xda, 0x8d, 0xcc, 0x32, 0x73, 0xd3, + 0x53, 0xb4, 0xdd, 0x5e, 0xd8, 0x1d, 0xae, 0xeb, 0xed, 0x92, 0x9d, 0x8c, + 0x88, 0x7e, 0x6a, 0x8f, 0xf4, 0xef, 0xd4, 0xdd, 0xf9, 0xa8, 0x39, 0xb2, + 0x8d, 0x35, 0xe7, 0x11, 0xb5, 0x1e, 0xf5, 0x25, 0xd8, 0xcc, 0x3e, 0xea, + 0x18, 0xb1, 0x1f, 0x71, 0x8c, 0x7e, 0xcc, 0x40, 0x1c, 0x4b, 0xd5, 0x5d, + 0xbd, 0x97, 0xf7, 0x6d, 0x95, 0x63, 0x67, 0x68, 0x4f, 0xb8, 0xb7, 0x6a, + 0x53, 0xfe, 0xde, 0x10, 0xef, 0x59, 0x72, 0xfc, 0x45, 0xe6, 0x1e, 0xcc, + 0x39, 0x98, 0x67, 0x45, 0xc3, 0xbb, 0x30, 0x1f, 0xfd, 0x31, 0xfa, 0x03, + 0x5d, 0xd9, 0x6e, 0x0e, 0x3e, 0xba, 0x50, 0xa7, 0xde, 0x86, 0xb9, 0x7f, + 0x66, 0x32, 0x5f, 0xb3, 0xc3, 0xae, 0xbc, 0x0b, 0x68, 0x9b, 0x85, 0xef, + 0x4f, 0x39, 0x6d, 0xb2, 0x32, 0x69, 0x43, 0xf7, 0x5f, 0x02, 0x5f, 0x07, + 0x3a, 0x59, 0x23, 0x58, 0x99, 0x4c, 0xe3, 0xfa, 0x80, 0xca, 0xd1, 0x8c, + 0xc7, 0x6c, 0xd0, 0xd8, 0xca, 0x75, 0xe4, 0xe9, 0x29, 0xae, 0x17, 0xe6, + 0x1f, 0xd3, 0x67, 0xe1, 0xb3, 0xc7, 0xe3, 0x8c, 0xf1, 0xdc, 0x4b, 0xe8, + 0x00, 0x1f, 0xdd, 0x0a, 0x57, 0xe8, 0xd6, 0x4e, 0xbd, 0x50, 0xa6, 0x9f, + 0xcf, 0x87, 0xdb, 0x85, 0x78, 0xc4, 0xd4, 0x2b, 0x16, 0x75, 0xa2, 0xc9, + 0x65, 0xb5, 0xef, 0x20, 0x92, 0x76, 0x0e, 0x61, 0xac, 0xb8, 0x5e, 0x2d, + 0xef, 0xd4, 0xf3, 0x65, 0x43, 0x56, 0x42, 0xe4, 0x3b, 0xa2, 0xf2, 0xf8, + 0x9d, 0xca, 0xd6, 0x8a, 0x88, 0x25, 0xb0, 0x99, 0xf8, 0x87, 0x31, 0xae, + 0x6a, 0x83, 0x4d, 0x51, 0xf7, 0xd4, 0xbb, 0xf2, 0x91, 0x9e, 0xee, 0x37, + 0x8a, 0x99, 0x45, 0xf8, 0x5f, 0xd6, 0x2f, 0x3a, 0xbc, 0x5a, 0xe3, 0x4b, + 0x5e, 0x3e, 0xf4, 0x8c, 0x30, 0x4f, 0x99, 0x2b, 0x91, 0x97, 0x22, 0xfc, + 0xe1, 0x46, 0xb6, 0x44, 0x39, 0xba, 0x3e, 0xe5, 0x10, 0xec, 0x42, 0x5f, + 0x32, 0x3d, 0x1b, 0xe0, 0xdf, 0x28, 0xee, 0x31, 0x06, 0xe0, 0xbb, 0xde, + 0x86, 0xf5, 0xbe, 0x17, 0x32, 0xa2, 0x6e, 0xa0, 0xbf, 0x25, 0xee, 0xbb, + 0x42, 0x7f, 0x4b, 0x57, 0xde, 0xb6, 0x7b, 0xe9, 0xf3, 0x46, 0xe4, 0x18, + 0xfc, 0xe8, 0xd1, 0x45, 0xf2, 0x93, 0xf6, 0x70, 0xd9, 0x30, 0x64, 0x42, + 0x1f, 0x3f, 0x2c, 0x6f, 0xd4, 0x7e, 0xa0, 0x70, 0xe0, 0xb6, 0x9d, 0x0d, + 0x99, 0x86, 0x7f, 0x98, 0x71, 0x20, 0x7f, 0x33, 0x82, 0xf5, 0x19, 0x56, + 0xfe, 0x71, 0xe6, 0xfd, 0xe5, 0x24, 0x01, 0x37, 0x66, 0x7f, 0xf6, 0x3e, + 0x63, 0xf6, 0x03, 0xc0, 0x61, 0xef, 0x8b, 0xbe, 0xe1, 0xd2, 0xff, 0x33, + 0xe8, 0xea, 0xd7, 0x55, 0xfd, 0x22, 0xb7, 0x73, 0x2b, 0x65, 0xfa, 0x5e, + 0xcf, 0xe9, 0xee, 0x73, 0x9f, 0xbb, 0x4f, 0xbe, 0x4c, 0xa9, 0x01, 0x2b, + 0xe4, 0x55, 0x1c, 0x65, 0xae, 0xd8, 0xe6, 0xe9, 0x6f, 0x10, 0x18, 0x9a, + 0x74, 0x7d, 0xdf, 0xdb, 0x21, 0xf9, 0x5e, 0x3f, 0xff, 0x84, 0xcf, 0x5e, + 0x6d, 0xf7, 0xf3, 0x59, 0x3e, 0xbf, 0x92, 0x41, 0xfe, 0x0c, 0x1b, 0x60, + 0x2c, 0x60, 0x5b, 0x5c, 0xf9, 0xa1, 0x77, 0xe7, 0x9b, 0xf5, 0x0b, 0xf2, + 0xbd, 0x5b, 0xf1, 0x9d, 0x56, 0x7c, 0xb3, 0x06, 0xb9, 0x5f, 0x4b, 0x9d, + 0x67, 0x1d, 0xd2, 0xaf, 0x3b, 0x92, 0x1e, 0xb0, 0x01, 0xf4, 0xfd, 0x63, + 0xd0, 0xfd, 0x11, 0xf4, 0xfa, 0xc3, 0x12, 0xb0, 0x41, 0x09, 0xd8, 0xa0, + 0x04, 0x6c, 0x50, 0x02, 0x36, 0x28, 0x85, 0xbd, 0x3a, 0x8b, 0x4d, 0x6c, + 0xff, 0x3e, 0x6d, 0xd7, 0xaf, 0x6d, 0xac, 0xb7, 0x4b, 0xb7, 0xb6, 0x99, + 0xaa, 0xfb, 0x18, 0x39, 0xc8, 0x5a, 0x2b, 0xb0, 0x9a, 0x5f, 0xf7, 0xf0, + 0x62, 0x44, 0x8d, 0xfb, 0x5e, 0x88, 0x11, 0x35, 0x1b, 0xeb, 0x66, 0x28, + 0x6c, 0x00, 0x1b, 0x1a, 0x12, 0xc6, 0x6f, 0x13, 0xbe, 0x17, 0xb4, 0x86, + 0xfb, 0xb1, 0x92, 0xda, 0x55, 0x5d, 0xef, 0x88, 0xaa, 0x3b, 0x58, 0x32, + 0x5b, 0xf6, 0x73, 0xb7, 0x98, 0x8c, 0xcd, 0x13, 0x6f, 0xca, 0x16, 0x3d, + 0x01, 0x1d, 0x38, 0xc4, 0x88, 0xdc, 0x27, 0xe4, 0xf8, 0xb1, 0xc1, 0x2a, + 0xc6, 0x2c, 0x58, 0x2e, 0x7f, 0x47, 0x9c, 0xbb, 0xcf, 0xec, 0x82, 0x7f, + 0xce, 0x14, 0x23, 0x32, 0x5e, 0x74, 0x31, 0x01, 0xf2, 0x9f, 0x75, 0xf5, + 0xe5, 0x5b, 0xd0, 0xc3, 0xad, 0xcc, 0x94, 0xb5, 0x6a, 0x1b, 0x91, 0xcb, + 0x71, 0xca, 0x98, 0xfa, 0xdf, 0xab, 0xf6, 0x29, 0x76, 0x55, 0xdd, 0xbd, + 0xa4, 0x71, 0x65, 0x0b, 0x01, 0xfa, 0x19, 0xd0, 0x89, 0xbb, 0x6b, 0x18, + 0x76, 0x91, 0x73, 0x7c, 0xb9, 0xb4, 0xe2, 0x91, 0x2f, 0x6a, 0x62, 0x6d, + 0xd4, 0xfe, 0x1b, 0x2d, 0xed, 0xab, 0xf7, 0x3d, 0x7e, 0xe1, 0xfb, 0x56, + 0x6b, 0x0d, 0xf4, 0x53, 0x77, 0xdb, 0x81, 0xdd, 0x24, 0xa0, 0xee, 0xc3, + 0x87, 0xd7, 0x42, 0x92, 0xaa, 0x59, 0x92, 0x2e, 0xb3, 0x1f, 0xeb, 0x17, + 0xf4, 0x47, 0x7f, 0x22, 0x29, 0xe4, 0xab, 0xd9, 0x50, 0x34, 0x6e, 0xcb, + 0x7f, 0x96, 0xe5, 0x85, 0x7c, 0x84, 0xe7, 0x0a, 0xf2, 0x13, 0x1a, 0x9e, + 0xfb, 0x19, 0xae, 0xc9, 0xb3, 0x25, 0x33, 0x45, 0xc6, 0x9d, 0xa1, 0x70, + 0x0d, 0xf7, 0xb2, 0x93, 0xac, 0xd9, 0x7c, 0x07, 0x36, 0x19, 0x8d, 0x94, + 0xa1, 0xef, 0x2b, 0x45, 0x8e, 0x07, 0x6c, 0x54, 0x64, 0x5d, 0xc7, 0xbf, + 0xff, 0x27, 0xc0, 0x81, 0xf0, 0xd5, 0x21, 0xaf, 0x8f, 0x9a, 0xab, 0x6d, + 0x06, 0x60, 0xe3, 0x0d, 0xcf, 0xdf, 0x56, 0x8a, 0x6e, 0x1d, 0xe5, 0x2c, + 0xf9, 0x70, 0xfe, 0x77, 0xb3, 0x11, 0x42, 0x0e, 0xb4, 0x3a, 0xc7, 0xab, + 0xa4, 0x6f, 0xc2, 0xdd, 0xca, 0x51, 0xc7, 0x97, 0x05, 0xef, 0xb3, 0x8d, + 0x67, 0x27, 0x9a, 0xcd, 0xb3, 0xd6, 0x07, 0xad, 0x99, 0xf5, 0x6d, 0x4f, + 0x5a, 0xf9, 0xdd, 0x15, 0x27, 0xef, 0xd5, 0xcc, 0xbe, 0xbd, 0xc3, 0xad, + 0x99, 0xd5, 0x76, 0xac, 0xad, 0x99, 0x59, 0xdb, 0xdd, 0x9a, 0xd9, 0xfc, + 0xee, 0x02, 0x3e, 0x6e, 0xcd, 0x2c, 0xbb, 0xdd, 0xad, 0x99, 0x95, 0xb7, + 0xbb, 0x35, 0x33, 0x67, 0x87, 0x5b, 0x33, 0xfb, 0xf9, 0xf6, 0xb5, 0x35, + 0xb3, 0x1f, 0xec, 0x58, 0x5b, 0x33, 0xbb, 0xb8, 0x3b, 0x87, 0xcf, 0xdd, + 0x9a, 0xd9, 0xcf, 0x76, 0xdc, 0xbb, 0x66, 0xf6, 0x9a, 0x8f, 0xd7, 0x31, + 0x9f, 0x11, 0xcc, 0x21, 0x0e, 0xbc, 0x3e, 0x0c, 0xbc, 0xfe, 0x6e, 0x75, + 0xfe, 0x00, 0xe6, 0x39, 0xe8, 0xc5, 0x83, 0x0f, 0x82, 0xdb, 0x47, 0xbc, + 0x67, 0x6d, 0xe4, 0xbb, 0x11, 0x2f, 0x57, 0x21, 0x76, 0xdf, 0xec, 0xe5, + 0x6c, 0xff, 0xa8, 0xf3, 0xee, 0xb9, 0x97, 0xd6, 0xef, 0x0f, 0x21, 0xf5, + 0xf6, 0xf1, 0x3c, 0xe7, 0x95, 0x47, 0xee, 0x47, 0x39, 0xd8, 0xe8, 0x3f, + 0xbf, 0xfb, 0x1b, 0x16, 0x31, 0xfe, 0x73, 0x58, 0xab, 0xf6, 0x16, 0x43, + 0x9d, 0x01, 0x60, 0x8c, 0x3a, 0x2e, 0x29, 0xf4, 0x4f, 0xa9, 0xfe, 0xd7, + 0x5a, 0xfa, 0xaf, 0xa0, 0x3f, 0xe9, 0x46, 0xff, 0x1d, 0x3e, 0x2f, 0x29, + 0xfb, 0xb6, 0x5c, 0x0c, 0x9f, 0x2e, 0xf9, 0x78, 0x2b, 0xe0, 0x61, 0xe7, + 0x46, 0xc6, 0x76, 0x3e, 0x8f, 0x67, 0xa2, 0x17, 0x6d, 0xb9, 0xa9, 0xf0, + 0xbb, 0x91, 0x88, 0x5e, 0xcc, 0xaa, 0x7c, 0xad, 0x91, 0xc9, 0x39, 0x7e, + 0xfe, 0x8d, 0x1c, 0x6a, 0x80, 0x39, 0x0c, 0xec, 0x7d, 0x69, 0x10, 0x71, + 0xac, 0x35, 0xc7, 0x66, 0x5e, 0xad, 0x7b, 0x79, 0xb5, 0x29, 0x9f, 0xd9, + 0xd9, 0x8a, 0xcd, 0x2f, 0xee, 0xfe, 0xc7, 0x0a, 0x9b, 0x6f, 0x42, 0x6e, + 0x4e, 0xec, 0x4d, 0x1c, 0x43, 0x0c, 0x41, 0x7c, 0xce, 0x7a, 0x01, 0xf3, + 0x19, 0xc6, 0x46, 0xe6, 0x37, 0x21, 0x7c, 0x78, 0x26, 0xc9, 0xc7, 0xe8, + 0xed, 0x9e, 0x7f, 0x67, 0x5e, 0xe4, 0x63, 0x95, 0xe4, 0x26, 0x37, 0x37, + 0xda, 0xa4, 0xb9, 0xf9, 0x67, 0xc4, 0xeb, 0x13, 0x58, 0xc5, 0xc2, 0x81, + 0x55, 0x2c, 0xbc, 0x66, 0x1f, 0x4b, 0xd4, 0xf9, 0x27, 0xb5, 0x1f, 0xc6, + 0xfd, 0xb1, 0x46, 0xe6, 0xca, 0x80, 0x68, 0x7a, 0x82, 0xfb, 0x64, 0xc0, + 0x3a, 0x16, 0xf7, 0xcd, 0xe8, 0x3b, 0xf7, 0x69, 0xa9, 0x2a, 0xe3, 0x0f, + 0xf1, 0x91, 0xbf, 0x17, 0xee, 0xeb, 0x89, 0xb2, 0x63, 0xdb, 0x1f, 0x6b, + 0xc8, 0x79, 0xe3, 0xed, 0xd6, 0x53, 0xe0, 0x25, 0x83, 0x6f, 0x5f, 0xa6, + 0x9f, 0x55, 0xb1, 0xaf, 0x03, 0xb6, 0x7b, 0xa4, 0x44, 0xec, 0xba, 0x59, + 0x6a, 0x1e, 0x7e, 0x3d, 0x37, 0xef, 0x62, 0xd7, 0xc0, 0x5a, 0xec, 0x1a, + 0x5f, 0x16, 0x97, 0xc7, 0x5d, 0x1b, 0xf2, 0x48, 0xbc, 0x4a, 0xfe, 0x18, + 0x77, 0xf6, 0xc2, 0xff, 0x35, 0x80, 0x69, 0x19, 0x73, 0x18, 0x6f, 0x22, + 0xc0, 0xf6, 0xf7, 0xe2, 0x4f, 0xb5, 0x1d, 0xea, 0xb0, 0x82, 0xf8, 0x4c, + 0xc3, 0x7f, 0x4c, 0xe0, 0x99, 0x8c, 0xcc, 0x9e, 0xfe, 0x1a, 0xe6, 0x36, + 0x2d, 0x57, 0xe6, 0x27, 0xc1, 0xdf, 0x73, 0x32, 0x17, 0xcf, 0xc3, 0x8f, + 0x70, 0xcf, 0x83, 0xb8, 0xad, 0xdf, 0xfb, 0x9e, 0xd6, 0xcf, 0x5a, 0x51, + 0xe2, 0x46, 0xa9, 0x16, 0xe9, 0x83, 0xb9, 0x67, 0xc8, 0xbd, 0x61, 0xda, + 0x0f, 0xeb, 0x27, 0xc8, 0x5d, 0x99, 0xc3, 0x9e, 0xe2, 0xf8, 0x6b, 0x75, + 0xb2, 0xec, 0x10, 0x7f, 0x35, 0x32, 0x8d, 0x25, 0xe2, 0xc7, 0xf7, 0x8b, + 0x25, 0xa9, 0x07, 0xe2, 0xc9, 0xfb, 0xc1, 0x91, 0xd1, 0x79, 0x60, 0xc8, + 0x57, 0x1a, 0x7a, 0x2b, 0x8e, 0x74, 0x31, 0x64, 0x72, 0x29, 0x0b, 0x9a, + 0x71, 0x85, 0x95, 0x91, 0xc7, 0xc1, 0xed, 0xf5, 0xe3, 0xd9, 0x7e, 0xe4, + 0xe4, 0x2e, 0x66, 0x4c, 0x01, 0x33, 0xfe, 0x06, 0x30, 0xe3, 0xac, 0x74, + 0x76, 0x11, 0x33, 0xda, 0x1e, 0x66, 0x4c, 0xc3, 0x9e, 0x73, 0x6b, 0xec, + 0x59, 0x53, 0xb5, 0x28, 0xde, 0xcb, 0x01, 0xf3, 0xa5, 0x4e, 0x45, 0xef, + 0x03, 0x27, 0x6a, 0x12, 0x52, 0xe7, 0x52, 0x02, 0x2d, 0x34, 0x7d, 0x3c, + 0xb8, 0x4d, 0xe1, 0xbc, 0xdd, 0xa5, 0x4d, 0xc8, 0x51, 0x14, 0xee, 0xf3, + 0xf6, 0x4b, 0x03, 0xeb, 0xf6, 0x90, 0x03, 0x2d, 0x7b, 0xc8, 0x77, 0xf1, + 0x21, 0x9e, 0xf3, 0x6a, 0x7d, 0x6d, 0xf0, 0x05, 0xff, 0x13, 0x3c, 0x71, + 0x7d, 0x71, 0x2d, 0x68, 0xee, 0x7a, 0x59, 0x83, 0x13, 0xff, 0x7a, 0x1d, + 0x4e, 0x44, 0xec, 0x3a, 0x17, 0x92, 0x24, 0x30, 0xa2, 0xbd, 0x44, 0x5a, + 0x5c, 0xd3, 0xc3, 0xd2, 0x8e, 0xf9, 0x75, 0x9c, 0xea, 0x05, 0x36, 0xea, + 0x92, 0x20, 0x30, 0x52, 0x9b, 0xc2, 0x48, 0x03, 0xc4, 0x32, 0x83, 0x33, + 0xc0, 0x36, 0xb5, 0x55, 0x9c, 0x14, 0x8d, 0xff, 0x01, 0xf4, 0xf2, 0x94, + 0xf2, 0x3d, 0x69, 0x39, 0x01, 0x5f, 0xda, 0xbe, 0x04, 0x7c, 0x77, 0xce, + 0xc5, 0x4f, 0x6d, 0xeb, 0xf0, 0xd3, 0xc1, 0x0d, 0xf1, 0x93, 0xaa, 0xdf, + 0x8f, 0x52, 0x26, 0x37, 0x1c, 0xb7, 0x7e, 0x7f, 0xdd, 0x71, 0xeb, 0xf7, + 0x37, 0x9c, 0xd6, 0xfa, 0xfd, 0x47, 0xa4, 0x60, 0x46, 0xed, 0x15, 0x59, + 0x57, 0xbf, 0x9f, 0x60, 0x3d, 0xdc, 0xe9, 0x72, 0xeb, 0xf4, 0x5d, 0x5e, + 0xfd, 0x3e, 0x2a, 0x85, 0x35, 0xed, 0xa6, 0xbc, 0x69, 0xf9, 0xf5, 0xfb, + 0xef, 0xa2, 0xad, 0x1b, 0x63, 0xac, 0xad, 0xdd, 0x5f, 0x77, 0x58, 0xbb, + 0x0f, 0xb1, 0x9f, 0x57, 0xbb, 0x67, 0x3f, 0xe4, 0xf2, 0x0e, 0xeb, 0xf6, + 0x8f, 0x40, 0x16, 0x5b, 0x21, 0x87, 0x5e, 0x69, 0x3f, 0x13, 0x66, 0x1f, + 0x55, 0xaf, 0x5f, 0x71, 0x42, 0x78, 0xce, 0xad, 0xab, 0xcf, 0xc0, 0xae, + 0x0e, 0xae, 0xd6, 0xeb, 0xdd, 0x31, 0x6e, 0x3a, 0x6b, 0xe9, 0xaf, 0xa5, + 0xd3, 0xe7, 0xd1, 0x09, 0x81, 0x4e, 0x78, 0x1d, 0x9d, 0xbb, 0xf5, 0xf9, + 0x9b, 0x8e, 0x5b, 0x9b, 0x4f, 0x9f, 0x16, 0xbb, 0x1d, 0xbe, 0xf9, 0xe2, + 0xc0, 0xc3, 0x1e, 0x8d, 0xd5, 0xda, 0x3c, 0x7d, 0x08, 0x70, 0x7b, 0x4c, + 0x9d, 0xbd, 0x9a, 0xf9, 0x7f, 0x50, 0x9b, 0x67, 0x5d, 0xde, 0xdd, 0x5f, + 0xe1, 0xfa, 0x04, 0x3e, 0x7f, 0xd1, 0xad, 0xc9, 0x8f, 0x95, 0xfc, 0x5a, + 0x3b, 0xf3, 0x47, 0xff, 0x5c, 0x54, 0x7f, 0xe4, 0x88, 0xd0, 0x56, 0xc8, + 0x1f, 0xe9, 0x76, 0xcb, 0x94, 0xc2, 0x47, 0xb0, 0xa9, 0xd8, 0xbd, 0x31, + 0x72, 0xe5, 0x94, 0x8f, 0x91, 0x43, 0x0a, 0x23, 0x57, 0x96, 0x7c, 0x8c, + 0x9c, 0xbc, 0x07, 0x46, 0x6e, 0x76, 0xb9, 0x71, 0x20, 0x28, 0x79, 0x85, + 0x91, 0xef, 0x75, 0x96, 0x8c, 0xf7, 0xba, 0x88, 0x07, 0xc4, 0x3d, 0x5f, + 0xd0, 0x7b, 0x8f, 0xb5, 0xe6, 0xe3, 0x66, 0xc6, 0xfe, 0xad, 0x32, 0x71, + 0xe6, 0x2e, 0x6e, 0x76, 0xb1, 0x71, 0x34, 0x72, 0x48, 0xc5, 0x44, 0xe0, + 0x84, 0x3a, 0xeb, 0xdf, 0xc4, 0xbe, 0x8c, 0x39, 0x01, 0x85, 0xcf, 0x72, + 0x45, 0xe6, 0x01, 0x6c, 0x23, 0x16, 0xee, 0xe4, 0x31, 0x2b, 0x2f, 0x26, + 0xf9, 0x58, 0xd3, 0x3f, 0xd7, 0xc2, 0x3d, 0x86, 0x37, 0x8d, 0xa4, 0x85, + 0x76, 0xc7, 0xcf, 0x15, 0xe2, 0xea, 0x3c, 0x50, 0x12, 0x58, 0x72, 0x6a, + 0x15, 0x4b, 0xd2, 0x57, 0xfc, 0xf4, 0x6d, 0xdb, 0xa4, 0x5f, 0xf3, 0xb1, + 0x22, 0x72, 0xa2, 0x12, 0xd7, 0xb6, 0x8f, 0x15, 0x5d, 0x9c, 0x98, 0x72, + 0x1a, 0xc0, 0xcb, 0x01, 0x19, 0x03, 0x4e, 0x6f, 0x7c, 0x89, 0x35, 0x28, + 0x1f, 0x1b, 0xd9, 0xf8, 0x6e, 0xad, 0x49, 0xf1, 0xba, 0x5d, 0xed, 0x05, + 0x5e, 0x1e, 0x08, 0xb6, 0xb4, 0x3f, 0x0b, 0xff, 0x8d, 0xfc, 0x08, 0xd8, + 0xc4, 0xc5, 0x44, 0x3b, 0xa0, 0x83, 0x91, 0x7b, 0x60, 0xa2, 0xf5, 0x31, + 0x8a, 0x31, 0xf3, 0x6e, 0x8c, 0x4a, 0xd7, 0xe9, 0xcf, 0xef, 0xc6, 0xa8, + 0x7b, 0xc7, 0x50, 0xb6, 0x61, 0x76, 0x56, 0x06, 0x9f, 0x69, 0x29, 0xac, + 0x8b, 0x51, 0x73, 0x1f, 0x20, 0x46, 0xb9, 0xf8, 0xc0, 0xe5, 0xfb, 0xf7, + 0x21, 0x9b, 0x1f, 0x43, 0xa6, 0x3f, 0x02, 0xe6, 0xfa, 0x21, 0xe6, 0xf5, + 0x03, 0xe0, 0xa1, 0xef, 0x97, 0xd6, 0x9f, 0x07, 0x19, 0x15, 0xe6, 0x87, + 0x2e, 0x66, 0x72, 0x31, 0xfd, 0x0c, 0x56, 0x57, 0xad, 0xd8, 0xc8, 0x4c, + 0x15, 0x87, 0xcc, 0x69, 0x77, 0x1f, 0x35, 0x92, 0x95, 0xa7, 0x3b, 0x53, + 0x8b, 0x8c, 0x19, 0xea, 0x3a, 0xcc, 0xfa, 0x25, 0xb1, 0x43, 0x55, 0xe5, + 0x99, 0x03, 0x52, 0xae, 0xb9, 0x78, 0x6b, 0x6e, 0xd1, 0xa5, 0x31, 0xe5, + 0xe1, 0xad, 0x9c, 0x87, 0xb7, 0xb2, 0xb5, 0xe5, 0x48, 0x00, 0xfd, 0xe7, + 0xe2, 0x6b, 0x31, 0xd6, 0x8c, 0x87, 0xb1, 0xa6, 0x3f, 0x20, 0xc6, 0xe2, + 0x58, 0x39, 0x3c, 0x33, 0x3e, 0x1f, 0x91, 0x5d, 0x90, 0xf3, 0x58, 0x91, + 0xfa, 0xe2, 0x19, 0xb2, 0xf7, 0xd2, 0x19, 0xf5, 0xe5, 0xea, 0x2a, 0x10, + 0xdb, 0xa7, 0x8d, 0x43, 0x57, 0x63, 0xef, 0xa9, 0x2b, 0x31, 0xdf, 0x18, + 0x09, 0xe2, 0xf3, 0xf7, 0xa5, 0x2b, 0xce, 0x83, 0xfa, 0x5a, 0x8f, 0xc5, + 0xee, 0x07, 0x93, 0xad, 0xc5, 0x63, 0xb6, 0xc2, 0x63, 0xed, 0x5e, 0x1f, + 0xd9, 0x33, 0x0e, 0x5d, 0xfe, 0x27, 0xf4, 0xf9, 0x99, 0xd5, 0x2d, 0x3f, + 0x85, 0xff, 0xfe, 0x43, 0xe8, 0xe4, 0x3f, 0x22, 0x57, 0x78, 0xcd, 0xea, + 0x93, 0x3f, 0x40, 0xdb, 0x5d, 0x9c, 0xc3, 0xfe, 0xc1, 0xc7, 0x92, 0xd6, + 0x35, 0xe0, 0x93, 0x6b, 0x1e, 0x3e, 0x79, 0x3a, 0x99, 0xb4, 0x26, 0x59, + 0x37, 0x87, 0x9c, 0x0f, 0xa4, 0xa6, 0x14, 0x36, 0xf1, 0x31, 0xc9, 0xed, + 0x34, 0xc7, 0x9f, 0x75, 0x56, 0x80, 0x7d, 0x56, 0x3c, 0xec, 0x73, 0x60, + 0xcc, 0xc5, 0x3e, 0xc1, 0xcf, 0x50, 0xff, 0x2e, 0xee, 0x59, 0xb1, 0x93, + 0x18, 0xa7, 0x0a, 0x4c, 0x52, 0x71, 0x0e, 0x48, 0xbe, 0xbe, 0x57, 0x7d, + 0x8e, 0x94, 0xec, 0x68, 0x1b, 0xe4, 0xc4, 0xda, 0xeb, 0x49, 0xae, 0x4a, + 0x27, 0x6a, 0x16, 0xf1, 0x9d, 0x75, 0xa2, 0xe1, 0xdf, 0xf1, 0xae, 0x9f, + 0xf7, 0xae, 0x4f, 0x78, 0xd7, 0xc7, 0x11, 0x87, 0x8f, 0xa9, 0x58, 0xca, + 0x76, 0xb6, 0x41, 0xc9, 0x0e, 0x68, 0x01, 0x7b, 0x9c, 0x1d, 0xfe, 0x8b, + 0x66, 0x59, 0xe9, 0x98, 0xf4, 0x27, 0xf0, 0x39, 0x8e, 0xcf, 0x34, 0x3e, + 0xfb, 0xf1, 0xc9, 0xe3, 0xb3, 0x2a, 0x53, 0x2d, 0x55, 0x9a, 0x84, 0x8d, + 0x0c, 0x4a, 0xaa, 0xfe, 0x12, 0xf4, 0xf8, 0x1c, 0x74, 0x7b, 0x58, 0x0a, + 0xd5, 0x3f, 0x95, 0xd9, 0x79, 0x4d, 0xba, 0x2c, 0xe8, 0xb4, 0x0a, 0x5b, + 0x9e, 0x77, 0xf7, 0x13, 0x3b, 0x13, 0x7b, 0xd1, 0xb7, 0x29, 0x4f, 0xc5, + 0x9f, 0x13, 0xfd, 0xb1, 0x39, 0xf4, 0x13, 0xbd, 0x30, 0xfc, 0x31, 0xb5, + 0x6f, 0x56, 0x8d, 0xbb, 0x32, 0xde, 0x65, 0xd9, 0x51, 0xe8, 0x7c, 0xf0, + 0x18, 0x68, 0x27, 0xd5, 0xd9, 0xd8, 0x8c, 0x1c, 0x3d, 0xbd, 0xbc, 0xc5, + 0xf5, 0xad, 0x51, 0xf3, 0x26, 0xf5, 0x8e, 0x79, 0xd8, 0xf0, 0x85, 0x19, + 0xd8, 0xfb, 0x41, 0x27, 0xa0, 0x8d, 0x21, 0xde, 0x8c, 0x39, 0x37, 0x55, + 0xbc, 0x81, 0xef, 0xca, 0xc4, 0x4e, 0x86, 0x70, 0xcd, 0xb3, 0x45, 0x88, + 0x8b, 0xea, 0x6c, 0xe5, 0x32, 0xf0, 0x8d, 0xa6, 0xea, 0x80, 0xb3, 0xab, + 0xfb, 0x43, 0x86, 0xf2, 0x5b, 0xb1, 0x98, 0x2e, 0xb9, 0x11, 0xe2, 0xdc, + 0xbd, 0x2a, 0x36, 0xd5, 0x8a, 0xf6, 0x43, 0xcc, 0x15, 0x6f, 0x08, 0xe3, + 0xdc, 0xe3, 0xe8, 0xd7, 0x07, 0x7f, 0x8c, 0x7b, 0x75, 0xda, 0x27, 0xe7, + 0xca, 0x67, 0xa6, 0xa5, 0x5a, 0x1e, 0xc5, 0x7c, 0xbd, 0x1c, 0x49, 0xe5, + 0x12, 0x11, 0xd8, 0xa3, 0xbf, 0x17, 0xe5, 0xd6, 0x4f, 0xaa, 0x8e, 0x8f, + 0x29, 0xba, 0xd1, 0x87, 0x79, 0x05, 0x64, 0xe4, 0xee, 0x9f, 0xa9, 0xbd, + 0xb3, 0x82, 0x33, 0x0a, 0x39, 0x25, 0xd1, 0xce, 0x5a, 0x35, 0x7e, 0x97, + 0x75, 0x55, 0x13, 0x58, 0x31, 0x66, 0xa4, 0x56, 0x6e, 0x82, 0x5f, 0xc4, + 0xdc, 0x2d, 0x33, 0x52, 0x29, 0x4f, 0xcb, 0x2b, 0xe5, 0x9f, 0x77, 0x03, + 0x53, 0x41, 0xa6, 0xe4, 0xbf, 0x5b, 0xee, 0x9e, 0xbf, 0xf5, 0xdb, 0x21, + 0xcf, 0xd3, 0xf9, 0xb0, 0x9b, 0xe7, 0xe6, 0x55, 0x2d, 0xc6, 0xfd, 0xb6, + 0xf5, 0x29, 0x2b, 0x1a, 0x9e, 0x45, 0xcf, 0x83, 0x0b, 0xb4, 0xcd, 0xfc, + 0xf8, 0x9c, 0xb5, 0x43, 0xae, 0xc6, 0x37, 0xcb, 0x72, 0x5c, 0xe5, 0xc5, + 0xc4, 0x0f, 0x58, 0xeb, 0x51, 0xb3, 0x21, 0x7b, 0xe4, 0x28, 0xd6, 0xed, + 0xd5, 0xf8, 0xd3, 0xb0, 0xd3, 0x67, 0x61, 0x0b, 0xac, 0x01, 0x1c, 0x62, + 0xae, 0x25, 0x0d, 0x55, 0x23, 0x6b, 0x36, 0xc7, 0xd5, 0x19, 0xee, 0x76, + 0x59, 0x56, 0x58, 0xcc, 0xad, 0x9d, 0x2f, 0x4f, 0xba, 0x6b, 0xc4, 0x50, + 0x76, 0xff, 0xc7, 0xe0, 0xc7, 0x84, 0xed, 0xb6, 0xa9, 0x3e, 0x46, 0xa2, + 0xc3, 0xeb, 0xa3, 0xf4, 0xdb, 0xd2, 0xe7, 0x95, 0x44, 0xd2, 0xda, 0xff, + 0x89, 0xa4, 0x75, 0x73, 0xb7, 0x5b, 0x6f, 0x89, 0x9a, 0xb6, 0xc6, 0xf7, + 0x52, 0xdc, 0xf5, 0x98, 0xc1, 0xba, 0xba, 0xb4, 0x8a, 0xa1, 0x61, 0xa4, + 0x2f, 0x5f, 0x81, 0x7e, 0x03, 0xd2, 0x7e, 0xb2, 0xf9, 0xf8, 0x54, 0x7c, + 0x28, 0x72, 0x50, 0x78, 0x02, 0x8b, 0x79, 0x75, 0x34, 0x9e, 0x95, 0x2b, + 0x88, 0x93, 0x77, 0x88, 0x1d, 0x06, 0x2f, 0xcb, 0x9d, 0xc7, 0x93, 0xf1, + 0x51, 0xad, 0x32, 0x89, 0xac, 0xe5, 0xe5, 0x49, 0xc6, 0xd9, 0x43, 0x22, + 0xc0, 0x97, 0x27, 0x47, 0x24, 0x5d, 0x54, 0xef, 0xa9, 0xf0, 0x9c, 0xad, + 0x36, 0x0d, 0xf9, 0xe1, 0xf9, 0x09, 0x06, 0x46, 0xdd, 0xea, 0x8f, 0xa4, + 0xe5, 0x69, 0xd6, 0xc0, 0x24, 0xb7, 0x20, 0xdb, 0x92, 0xf0, 0xab, 0xf6, + 0x44, 0xbb, 0x4c, 0xd7, 0x1a, 0x99, 0xfe, 0x53, 0xcf, 0x82, 0xc6, 0x14, + 0x68, 0xed, 0x45, 0x6e, 0x92, 0x45, 0xac, 0xa6, 0x7c, 0xe9, 0xbb, 0x9f, + 0x81, 0x8c, 0x3e, 0xc2, 0x3d, 0xe5, 0xd1, 0xac, 0x44, 0x27, 0xf2, 0x8a, + 0xee, 0x5b, 0x5a, 0x6e, 0xf8, 0x57, 0x10, 0xeb, 0x02, 0xb2, 0x2b, 0x26, + 0xfa, 0xde, 0x58, 0xe0, 0xed, 0x29, 0x8b, 0x6d, 0x41, 0xb6, 0xe9, 0x68, + 0x0b, 0xfc, 0x7a, 0x2c, 0xa8, 0x27, 0x63, 0xd1, 0x51, 0x9e, 0x8f, 0x36, + 0xac, 0x29, 0xee, 0x4d, 0x3c, 0x20, 0x5d, 0x7b, 0xa5, 0xe7, 0x42, 0x74, + 0xf4, 0x06, 0x78, 0x09, 0x28, 0x5f, 0x3f, 0x25, 0xba, 0xd7, 0xde, 0xbd, + 0xda, 0x1e, 0xf0, 0xda, 0xf7, 0x4a, 0xd7, 0x85, 0x21, 0xf3, 0x75, 0x99, + 0x01, 0x4d, 0x43, 0xae, 0x23, 0xd7, 0xb1, 0x06, 0xa6, 0x60, 0x8b, 0x4f, + 0x92, 0x97, 0xfd, 0xc0, 0x1a, 0x58, 0x1b, 0xc8, 0xbf, 0xad, 0x0f, 0xcb, + 0x57, 0xcd, 0x4e, 0xc9, 0xa9, 0x5c, 0x37, 0xe0, 0xd6, 0x52, 0x61, 0xef, + 0x8f, 0x0e, 0x1c, 0xec, 0x71, 0xeb, 0x05, 0xdc, 0xef, 0x18, 0x46, 0xdb, + 0x9d, 0xe6, 0x39, 0x8b, 0x6d, 0xbc, 0x77, 0xa7, 0x59, 0xb5, 0x86, 0xcc, + 0x94, 0x16, 0xf4, 0xf6, 0xbd, 0x0f, 0xa9, 0xb9, 0xe7, 0xcb, 0xfd, 0x66, + 0x45, 0x1e, 0xd5, 0x52, 0x0f, 0x22, 0x5e, 0x38, 0xd3, 0xe8, 0x7b, 0x87, + 0xe7, 0x29, 0x54, 0x7d, 0xbf, 0x22, 0xfe, 0x35, 0xe9, 0x0c, 0x99, 0xe3, + 0xea, 0xd9, 0x21, 0xf3, 0xa8, 0xd6, 0xfa, 0x6c, 0x58, 0x1b, 0x5f, 0xf3, + 0x6c, 0x97, 0x92, 0x91, 0x61, 0xb9, 0x7d, 0x66, 0xcb, 0x7b, 0xe5, 0x79, + 0x87, 0xfd, 0xee, 0x34, 0x53, 0xd6, 0x03, 0xda, 0xd1, 0x07, 0xe9, 0x0b, + 0xd9, 0xf7, 0xf6, 0xba, 0x71, 0x78, 0x7d, 0xaf, 0x31, 0x9a, 0xb2, 0x76, + 0x8c, 0x4d, 0xaa, 0xcf, 0x55, 0xd5, 0x27, 0xa0, 0x64, 0xbd, 0x76, 0x9c, + 0xbf, 0x91, 0xb5, 0xe3, 0x74, 0xad, 0xce, 0x79, 0x16, 0x34, 0x8f, 0xa1, + 0x6f, 0xd1, 0xe9, 0x0f, 0x57, 0xe5, 0x76, 0x33, 0x67, 0xbd, 0x29, 0x57, + 0x57, 0x69, 0xff, 0x12, 0xd7, 0xad, 0x3c, 0xfd, 0xd2, 0xe3, 0x91, 0xbf, + 0xd9, 0xf6, 0x2f, 0x95, 0xbc, 0x1f, 0xb0, 0xfa, 0xf7, 0x57, 0xb4, 0xe8, + 0xe8, 0x5f, 0x0a, 0x75, 0xf5, 0xcf, 0x94, 0xaf, 0xf9, 0x18, 0xf4, 0xb4, + 0xed, 0x05, 0xac, 0xdd, 0xe1, 0xa4, 0xea, 0x73, 0xdd, 0xda, 0x2b, 0xdb, + 0x4e, 0xf6, 0x9b, 0xd7, 0xe5, 0x33, 0x92, 0x0e, 0xf1, 0x1a, 0x39, 0x94, + 0xc5, 0xf7, 0x52, 0x3e, 0xc1, 0xbc, 0x00, 0xba, 0xec, 0x1f, 0xfc, 0x4b, + 0x79, 0x56, 0x8e, 0x96, 0xe6, 0xe0, 0x7b, 0xa6, 0x64, 0xf0, 0x05, 0xfa, + 0x9f, 0xbc, 0xe9, 0xd6, 0x6a, 0xdc, 0x98, 0x98, 0xf2, 0x62, 0xe2, 0x9c, + 0xf2, 0x73, 0xaf, 0x79, 0xe7, 0x22, 0xfa, 0x07, 0xcf, 0xe1, 0xd9, 0x57, + 0x94, 0x0f, 0xf8, 0x3d, 0xa9, 0x62, 0x2d, 0x44, 0x5e, 0xde, 0x2c, 0x0f, + 0x3c, 0x41, 0x9b, 0x44, 0x06, 0xf0, 0xb1, 0x36, 0xf5, 0x1e, 0x8c, 0x6e, + 0x75, 0x88, 0x6c, 0xa1, 0xfd, 0x5c, 0x86, 0xad, 0x4d, 0xb9, 0x7b, 0x5f, + 0x6b, 0xae, 0xa3, 0x13, 0x2b, 0xf2, 0x1f, 0x94, 0x1d, 0x7e, 0xfc, 0x82, + 0xfb, 0x3d, 0x7c, 0x01, 0xe9, 0x72, 0x6c, 0xaf, 0x6c, 0xbf, 0xe0, 0xda, + 0xdd, 0xec, 0xfc, 0xb3, 0x4a, 0xbe, 0x53, 0x4a, 0xbe, 0x4d, 0x99, 0x89, + 0x53, 0xf6, 0x9c, 0x13, 0xcf, 0x4f, 0xba, 0x32, 0xf9, 0x9c, 0x67, 0x47, + 0xfd, 0x2f, 0xf0, 0x3d, 0x35, 0xca, 0x88, 0x7c, 0xcf, 0xf4, 0x70, 0x3f, + 0x76, 0xdb, 0x05, 0xce, 0xb7, 0x6f, 0xcd, 0x7c, 0x4f, 0xc0, 0xc7, 0x0e, + 0x0c, 0xb8, 0x73, 0x7e, 0x6d, 0xfe, 0xfd, 0xcf, 0xf9, 0x77, 0x57, 0xe7, + 0x6c, 0x48, 0x55, 0xe5, 0xb9, 0xb1, 0xcd, 0xd2, 0x95, 0x93, 0x06, 0xec, + 0xe3, 0xcf, 0x85, 0x67, 0xc6, 0xc9, 0x8b, 0x3b, 0xee, 0xb2, 0x43, 0x9e, + 0xfc, 0x39, 0x90, 0xaf, 0x29, 0x4f, 0x7f, 0xe4, 0xe3, 0xd9, 0x0d, 0xef, + 0x5d, 0x97, 0x46, 0x66, 0x10, 0x6d, 0xba, 0xd2, 0xe1, 0x98, 0xb7, 0xde, + 0xf6, 0x8a, 0xae, 0x74, 0x98, 0x5c, 0xd5, 0xe1, 0x0d, 0xe8, 0xb0, 0x2a, + 0x9f, 0xc6, 0x9c, 0xb0, 0xbe, 0x5f, 0x18, 0x32, 0x67, 0x64, 0xab, 0xd2, + 0xbf, 0x35, 0x00, 0x9f, 0xea, 0xe9, 0xb2, 0xfd, 0x3e, 0x74, 0xf9, 0xba, + 0x28, 0x7d, 0xaa, 0x73, 0x44, 0x55, 0x45, 0x87, 0xbe, 0x8d, 0x73, 0x6b, + 0x57, 0x3e, 0x81, 0x3c, 0xaa, 0xb3, 0x01, 0x13, 0xae, 0x7e, 0xd5, 0x9a, + 0xf7, 0xf4, 0x9b, 0x9d, 0xa0, 0x0e, 0x7f, 0xad, 0xc7, 0xd5, 0x67, 0x87, + 0xea, 0x73, 0x2a, 0x36, 0xaa, 0xd6, 0xbb, 0x35, 0xf0, 0xe9, 0x1e, 0xea, + 0xf4, 0x79, 0xc7, 0xfd, 0x2e, 0x22, 0xce, 0x9d, 0x72, 0xde, 0x4b, 0xaf, + 0xae, 0x4e, 0xc7, 0xc4, 0x5d, 0x57, 0xeb, 0xf5, 0xa9, 0x5f, 0x08, 0x28, + 0x1b, 0x1e, 0x83, 0x0c, 0x8f, 0x97, 0x1e, 0xf4, 0xec, 0xde, 0x9d, 0xf3, + 0xc0, 0xfb, 0x9c, 0xf3, 0x91, 0x62, 0xbf, 0xf9, 0x26, 0xee, 0x8d, 0x63, + 0xce, 0x33, 0xd2, 0x26, 0x29, 0x6f, 0xce, 0x91, 0xd5, 0x39, 0xfb, 0x3c, + 0xba, 0xfd, 0x52, 0xcc, 0x63, 0x1d, 0xfa, 0xaf, 0x7f, 0xab, 0xde, 0x37, + 0xb9, 0x59, 0xa4, 0xdf, 0x06, 0x56, 0x0a, 0xf5, 0xca, 0xf5, 0x5a, 0x44, + 0xae, 0x13, 0x83, 0x8c, 0xe0, 0xdb, 0x99, 0xf3, 0x62, 0x78, 0x50, 0x5e, + 0x2f, 0x6e, 0xc4, 0xc7, 0xb0, 0xdc, 0x28, 0xfa, 0xbc, 0x10, 0x0b, 0x33, + 0x5f, 0x98, 0x92, 0x37, 0xe6, 0xfb, 0xa5, 0x31, 0x81, 0xb8, 0x3f, 0x40, + 0x99, 0x0c, 0x99, 0x7b, 0xd4, 0x7b, 0x48, 0x77, 0x9a, 0x97, 0x2d, 0xd0, + 0x5f, 0x68, 0xca, 0x41, 0xee, 0x67, 0xf3, 0x77, 0xed, 0x21, 0x69, 0x30, + 0xa7, 0x18, 0xe8, 0x95, 0xca, 0x02, 0xf2, 0xf9, 0x22, 0xe9, 0x53, 0x6e, + 0x7b, 0xd5, 0xef, 0x71, 0x8c, 0xf7, 0x39, 0xbe, 0x1f, 0x10, 0xa2, 0x6e, + 0xee, 0x34, 0x97, 0x2d, 0xee, 0x67, 0x4e, 0x49, 0x0d, 0xfa, 0xfb, 0xe7, + 0x31, 0xee, 0xb7, 0xe7, 0xd4, 0xf9, 0xdb, 0x4a, 0x6d, 0x02, 0xb9, 0xc3, + 0x9d, 0xe6, 0x9c, 0x75, 0x56, 0xe9, 0xad, 0x56, 0x7e, 0xc2, 0x6b, 0xe7, + 0x35, 0xef, 0x35, 0x32, 0xdb, 0x06, 0x98, 0xaf, 0x3e, 0x81, 0x7c, 0x81, + 0xb9, 0xea, 0x04, 0xf0, 0x1a, 0x65, 0x12, 0x91, 0xd9, 0x22, 0x69, 0x49, + 0x68, 0x13, 0xf2, 0xfb, 0x9c, 0x8c, 0x83, 0x9f, 0x08, 0x72, 0x7b, 0xc6, + 0x87, 0x47, 0x65, 0x39, 0xe4, 0xc6, 0x01, 0x9e, 0xfb, 0x5a, 0x46, 0x6c, + 0x58, 0x5e, 0x8d, 0x0d, 0x5b, 0x71, 0xdd, 0xc8, 0xc4, 0x07, 0xfe, 0x06, + 0xf4, 0x59, 0xb7, 0x61, 0x6c, 0x18, 0x45, 0x7f, 0xb6, 0xf5, 0xca, 0xec, + 0x02, 0x92, 0x08, 0xe4, 0x2c, 0x15, 0xe1, 0x99, 0x8e, 0xac, 0x9c, 0xaa, + 0xf5, 0x87, 0x2f, 0x6b, 0x69, 0x75, 0xf6, 0x23, 0x36, 0xc0, 0xf3, 0x2c, + 0xbd, 0x52, 0x5b, 0x90, 0x88, 0x91, 0x78, 0x52, 0x9c, 0x9a, 0x8b, 0xd9, + 0xe7, 0x34, 0x9e, 0x69, 0xb1, 0xa5, 0xb6, 0xb6, 0x8f, 0x89, 0xdc, 0x57, + 0xbe, 0xe3, 0xf5, 0x49, 0xab, 0x3e, 0x7f, 0xdd, 0xc3, 0x3d, 0xb4, 0x9a, + 0xd3, 0x03, 0x1e, 0xc8, 0xdb, 0xc3, 0xad, 0xe3, 0x46, 0xee, 0x8e, 0xcb, + 0x31, 0x91, 0xcd, 0x6c, 0xb1, 0x31, 0xee, 0x4d, 0x3c, 0xf3, 0x24, 0xf8, + 0xb8, 0x63, 0xe8, 0xd6, 0x93, 0x52, 0xa8, 0xad, 0x1f, 0xa3, 0x95, 0x07, + 0x3e, 0x43, 0xfa, 0x1c, 0xe7, 0x00, 0xf8, 0xbb, 0xa3, 0xe9, 0xd6, 0x01, + 0xc8, 0xd2, 0x1d, 0xc3, 0x38, 0x13, 0x35, 0x7f, 0x2a, 0x03, 0xa2, 0x9f, + 0xd3, 0x94, 0xfc, 0xf5, 0xca, 0x30, 0x16, 0x48, 0x46, 0xba, 0x96, 0x26, + 0xc5, 0x58, 0x62, 0x0d, 0xe1, 0xb5, 0xce, 0xb4, 0xda, 0xbf, 0xdd, 0x84, + 0xf5, 0x2d, 0x76, 0xc0, 0x62, 0xbd, 0x80, 0xf5, 0xe0, 0x9f, 0x6e, 0x96, + 0x1e, 0xd6, 0x0b, 0x98, 0x37, 0xec, 0xc7, 0x37, 0x73, 0x87, 0x4b, 0x4d, + 0xe4, 0x7a, 0x9b, 0x19, 0x5f, 0x73, 0x35, 0xde, 0x8f, 0x46, 0x44, 0x78, + 0x8f, 0x7e, 0xa3, 0x57, 0xda, 0xbe, 0x35, 0x08, 0x5f, 0xf1, 0x34, 0xb0, + 0x37, 0xe8, 0x9e, 0x1c, 0x90, 0x80, 0x7b, 0x66, 0x42, 0xd5, 0x5b, 0xde, + 0x58, 0x88, 0x7a, 0xef, 0x73, 0xc9, 0xb6, 0xcb, 0x71, 0xd6, 0x44, 0xfb, + 0x58, 0xf3, 0x41, 0x3f, 0xd1, 0x97, 0x91, 0x9f, 0x5e, 0xaf, 0x59, 0x9b, + 0x79, 0x7e, 0xf3, 0x86, 0x83, 0x6b, 0x62, 0xff, 0x90, 0xc2, 0x98, 0xde, + 0x3d, 0xfe, 0x46, 0xbe, 0xf4, 0x8e, 0x77, 0x13, 0x98, 0x4f, 0x4d, 0x7a, + 0x67, 0xe7, 0x1a, 0x99, 0xa3, 0x6b, 0x72, 0xaa, 0x41, 0x55, 0xef, 0x6d, + 0x38, 0x16, 0xfc, 0xe3, 0x08, 0xec, 0x93, 0x6b, 0xa0, 0xa9, 0x3d, 0x01, + 0x6c, 0x16, 0xe9, 0x55, 0x39, 0xd1, 0xf1, 0x27, 0xc4, 0xb5, 0x77, 0x58, + 0x99, 0xf2, 0x65, 0x8d, 0xb2, 0x9b, 0x83, 0x2c, 0x97, 0x33, 0xf2, 0x47, + 0xce, 0x15, 0x55, 0x6b, 0x9d, 0x47, 0x5e, 0x12, 0x38, 0xa5, 0x72, 0xb2, + 0x16, 0x7c, 0x0b, 0xbf, 0xf7, 0xe2, 0xd7, 0xb1, 0x16, 0xa3, 0xea, 0x8c, + 0x82, 0x7e, 0xae, 0xd9, 0x4c, 0xc1, 0x7f, 0xe8, 0x96, 0x65, 0x16, 0x10, + 0x0f, 0x53, 0xea, 0x9c, 0x0b, 0xd7, 0xf1, 0x6f, 0x2b, 0xff, 0x2c, 0x15, + 0xc8, 0xe6, 0x4c, 0x04, 0x74, 0x34, 0x65, 0x9f, 0x86, 0xd2, 0xc3, 0x13, + 0x0a, 0xf3, 0x1a, 0xe7, 0xe0, 0xb0, 0x96, 0x06, 0x44, 0xce, 0x65, 0x64, + 0x0e, 0x6b, 0x38, 0xb0, 0x44, 0x1d, 0x50, 0xb6, 0x93, 0xd2, 0x06, 0xd9, + 0x1f, 0x01, 0xf6, 0x30, 0x4e, 0x51, 0xc6, 0x61, 0xac, 0x8b, 0x5e, 0x09, + 0x9c, 0x81, 0x8c, 0x4f, 0x01, 0x23, 0x2c, 0xb4, 0xcb, 0xf7, 0x6a, 0xbe, + 0x4c, 0x2f, 0xf1, 0x5c, 0xbf, 0x3e, 0x35, 0xd2, 0x47, 0x1c, 0x25, 0xd5, + 0xda, 0x9c, 0xcc, 0x9d, 0x66, 0xce, 0x3e, 0xa9, 0xce, 0x0c, 0x04, 0xd4, + 0x99, 0x15, 0x37, 0x67, 0x76, 0xbf, 0x5d, 0x8c, 0x59, 0x15, 0xee, 0xb5, + 0x09, 0x6c, 0x67, 0x18, 0xe3, 0x6e, 0x24, 0x5f, 0x37, 0x57, 0x1d, 0x07, + 0xbf, 0x97, 0xe7, 0xa3, 0x99, 0xbc, 0xc4, 0x79, 0x76, 0x7a, 0xc2, 0xc6, + 0xfc, 0x97, 0xe1, 0x3f, 0xe7, 0x4a, 0x3c, 0x27, 0x5d, 0xc0, 0x0a, 0xcb, + 0xc8, 0xe5, 0x22, 0x73, 0xc6, 0x8f, 0x43, 0x6f, 0xbc, 0x2e, 0x8c, 0x1a, + 0xf0, 0x03, 0x2b, 0xea, 0xdd, 0xcf, 0xa8, 0xdd, 0x40, 0x0e, 0x1b, 0xd1, + 0xf6, 0x43, 0xd7, 0x79, 0xb3, 0xcd, 0xb3, 0x07, 0x9e, 0xc5, 0x3f, 0x0b, + 0x3f, 0x7a, 0x5e, 0xf8, 0x4e, 0xd6, 0xed, 0x26, 0xf3, 0xa5, 0xab, 0xf0, + 0x7b, 0x99, 0x58, 0x06, 0x36, 0x94, 0x0f, 0x77, 0x80, 0xe7, 0xdf, 0xc4, + 0xbd, 0x9c, 0xc3, 0x71, 0xa2, 0xf1, 0x15, 0x29, 0x44, 0x02, 0x32, 0x14, + 0xb9, 0x22, 0x9b, 0xe1, 0xc9, 0x34, 0x79, 0xdd, 0x8a, 0x8e, 0x8a, 0xa6, + 0xe8, 0x0d, 0xee, 0x86, 0x0d, 0xde, 0x84, 0xbf, 0x6b, 0xf7, 0x72, 0xfd, + 0x54, 0x91, 0x18, 0xea, 0x59, 0x75, 0xb6, 0xe0, 0xaa, 0xc5, 0x3a, 0x20, + 0xdf, 0xc5, 0xfe, 0x1f, 0x6a, 0x8c, 0xbb, 0x7b, 0x77, 0xac, 0x43, 0x93, + 0x3f, 0x77, 0x8e, 0xbb, 0x2c, 0x97, 0x47, 0xd2, 0x69, 0x6b, 0xa1, 0x73, + 0xd9, 0xa3, 0x73, 0xd6, 0xa3, 0x53, 0xf1, 0xe8, 0x5c, 0x5d, 0xa5, 0xb3, + 0x07, 0x76, 0xd0, 0x6c, 0x9e, 0x00, 0xde, 0x48, 0xc6, 0x9b, 0xcd, 0x34, + 0xf2, 0xb2, 0xd9, 0xe1, 0x69, 0xb5, 0xe7, 0xaa, 0x27, 0x46, 0xc7, 0x93, + 0x96, 0x2b, 0x7f, 0x58, 0x81, 0x4c, 0xc3, 0x1e, 0xf3, 0xe2, 0x62, 0x75, + 0xee, 0x07, 0xba, 0xfb, 0x85, 0x5d, 0xf0, 0x03, 0x4f, 0x23, 0x96, 0x5c, + 0x1c, 0x3f, 0x6f, 0x49, 0x7e, 0xdb, 0x27, 0x75, 0xd8, 0x7b, 0x0f, 0xdf, + 0x27, 0x35, 0xa5, 0xeb, 0xe2, 0x78, 0xb5, 0xf6, 0x34, 0xf2, 0x23, 0xf6, + 0xdf, 0x4e, 0x0c, 0xb6, 0xab, 0x52, 0x8b, 0xec, 0x3a, 0xcb, 0xfd, 0x21, + 0xf4, 0xab, 0xd4, 0xba, 0x21, 0xf7, 0x6e, 0x55, 0x57, 0xb9, 0x52, 0x0c, + 0x41, 0x8f, 0x26, 0x6c, 0x3e, 0x84, 0xb6, 0x30, 0xec, 0xa0, 0x0f, 0xed, + 0x3f, 0xc7, 0xda, 0x8e, 0xa0, 0x7d, 0xa5, 0x73, 0x5c, 0xe1, 0x58, 0x4b, + 0xce, 0x39, 0x37, 0x11, 0x73, 0xdf, 0x84, 0x1f, 0x1d, 0x44, 0x9f, 0x61, + 0xf4, 0xf9, 0x14, 0xc6, 0xe1, 0x3b, 0xcd, 0x1b, 0xf1, 0xd4, 0x00, 0x4f, + 0x7a, 0x0b, 0x4f, 0x0d, 0xf0, 0x03, 0xdf, 0x79, 0x92, 0x35, 0xe8, 0x61, + 0x39, 0x5a, 0xe4, 0x19, 0x29, 0xbe, 0x17, 0x6f, 0x4a, 0x00, 0x98, 0xb4, + 0xed, 0x64, 0x34, 0xdc, 0x50, 0xb5, 0x1e, 0xda, 0xd6, 0x50, 0xbc, 0x2a, + 0x2a, 0xce, 0x44, 0x8e, 0x22, 0x7e, 0xdd, 0x74, 0xba, 0xe5, 0x75, 0x6f, + 0xac, 0x15, 0xe1, 0xfe, 0xe5, 0xda, 0xb1, 0x8e, 0x95, 0xae, 0x8d, 0xbf, + 0x6a, 0x19, 0xde, 0xbc, 0x7a, 0x31, 0xd6, 0xaf, 0xa2, 0xef, 0xb5, 0xf1, + 0xcb, 0xb5, 0x8d, 0xfa, 0xde, 0x44, 0xdf, 0xb6, 0x96, 0xbe, 0x37, 0xd1, + 0xaf, 0x1b, 0x71, 0xb0, 0x5b, 0xcd, 0x69, 0x16, 0x7c, 0x5d, 0x2f, 0xaa, + 0xf7, 0xb4, 0x21, 0x77, 0x8e, 0x69, 0x12, 0x53, 0x67, 0xdc, 0x5a, 0x49, + 0xd4, 0x8c, 0x68, 0xef, 0xa8, 0xf7, 0x28, 0x1b, 0x18, 0xb3, 0x80, 0x7b, + 0xe7, 0x27, 0xb4, 0x54, 0x35, 0x87, 0x98, 0xf5, 0x30, 0xf1, 0x53, 0xdc, + 0x46, 0xcc, 0xac, 0x80, 0x5e, 0xad, 0xd8, 0xe0, 0x79, 0x6a, 0xd8, 0xc5, + 0x2d, 0xe2, 0xec, 0x87, 0x0d, 0x75, 0xae, 0x21, 0xad, 0x6a, 0x76, 0x95, + 0xa2, 0x98, 0xc9, 0x11, 0x9e, 0x65, 0xf8, 0x0c, 0xd6, 0xe5, 0x57, 0xd0, + 0x96, 0x44, 0x7c, 0x3c, 0xa0, 0x25, 0xcf, 0x8f, 0xe3, 0xfa, 0x49, 0x5c, + 0xc3, 0x1f, 0x2f, 0x64, 0x71, 0xff, 0x49, 0x5c, 0x4f, 0x6b, 0xa9, 0x7a, + 0x16, 0xd7, 0x4f, 0xe1, 0x7a, 0xca, 0x64, 0x9e, 0xf2, 0xaa, 0x95, 0xd1, + 0x6c, 0xd0, 0xb2, 0xcf, 0x8f, 0xe3, 0xd3, 0x4a, 0x8f, 0xf7, 0xa0, 0xa7, + 0x22, 0xf7, 0xda, 0x62, 0xe0, 0x69, 0x9f, 0x96, 0xae, 0x76, 0x81, 0xc6, + 0x00, 0x9e, 0xa7, 0x4d, 0xed, 0xf7, 0xc6, 0x67, 0xcd, 0xe9, 0x63, 0xaa, + 0xe6, 0x64, 0x24, 0x32, 0xc0, 0xc9, 0x87, 0x91, 0x07, 0x68, 0x92, 0xb6, + 0x9e, 0x93, 0x42, 0x1c, 0x7e, 0xa5, 0x6a, 0x48, 0x2a, 0x94, 0xc7, 0xef, + 0xbc, 0x24, 0x47, 0x71, 0xbf, 0x4a, 0x5b, 0x60, 0xbf, 0x3f, 0x95, 0x42, + 0x99, 0xb8, 0x9f, 0x75, 0x26, 0xd6, 0xa6, 0x58, 0x5f, 0xca, 0x41, 0x06, + 0x21, 0xda, 0xef, 0x06, 0x35, 0x31, 0xf7, 0x8c, 0x34, 0xe2, 0xb2, 0x96, + 0xac, 0x72, 0xdf, 0xaf, 0x91, 0xb9, 0x6c, 0xf1, 0xfd, 0xb1, 0x69, 0xee, + 0x23, 0x16, 0x8c, 0x04, 0xeb, 0x23, 0xaa, 0xbe, 0x1e, 0x77, 0xf7, 0x07, + 0x5b, 0xcf, 0xa4, 0xf8, 0xeb, 0x85, 0xe3, 0x7e, 0x0d, 0xcf, 0xbb, 0xf5, + 0xac, 0x54, 0xfd, 0x9d, 0xba, 0xe0, 0x3b, 0x00, 0xe7, 0xa0, 0x8b, 0xcb, + 0x2a, 0x37, 0xe6, 0x1e, 0xee, 0xbb, 0xe5, 0x54, 0xc8, 0x61, 0x8a, 0xac, + 0x91, 0xf9, 0xfb, 0x76, 0xbe, 0x1c, 0xd7, 0xf3, 0x4a, 0x3e, 0x67, 0x40, + 0x53, 0xe2, 0xf4, 0xbb, 0xd9, 0x10, 0xf7, 0xdf, 0xf8, 0x8c, 0x7c, 0xf3, + 0x2e, 0xdf, 0xe4, 0x99, 0xf2, 0x38, 0x0c, 0xff, 0xc9, 0xf7, 0x2b, 0x9e, + 0x93, 0x5c, 0x9c, 0x35, 0x1e, 0x03, 0xb1, 0x31, 0x8f, 0xdf, 0x77, 0xe5, + 0x37, 0xeb, 0xc9, 0x2f, 0x57, 0xfe, 0x2f, 0x4a, 0x87, 0x15, 0x8b, 0xe3, + 0xf9, 0xb5, 0x8f, 0xbd, 0x4a, 0x77, 0x15, 0x75, 0x7e, 0xd7, 0x97, 0x81, + 0x5f, 0xbf, 0xdb, 0xd8, 0xf6, 0xc6, 0x2d, 0xf2, 0xf6, 0x10, 0xcf, 0x43, + 0x0c, 0xda, 0x42, 0xfe, 0x39, 0x0f, 0xc6, 0x30, 0x7f, 0xaf, 0xd5, 0x9f, + 0x83, 0x3f, 0xcf, 0xfb, 0x95, 0x0f, 0xf9, 0xfd, 0xe4, 0x16, 0xe9, 0xca, + 0x98, 0x86, 0xc5, 0xd8, 0xf0, 0xb8, 0xb7, 0x3f, 0xf0, 0x7f, 0x43, 0xce, + 0xae, 0x2c, 0x02, 0x09, 0x99, 0xf5, 0xde, 0xbf, 0xde, 0xc0, 0x1e, 0xd6, + 0xef, 0x35, 0x37, 0x32, 0x67, 0xad, 0xbb, 0xf3, 0xae, 0x6c, 0x30, 0xef, + 0x8a, 0x37, 0xef, 0xea, 0x7d, 0xf2, 0x5b, 0x99, 0xb7, 0x31, 0x67, 0xda, + 0xdc, 0x46, 0xf6, 0x28, 0xea, 0xdd, 0xb0, 0x15, 0x23, 0x18, 0xb4, 0x9d, + 0x7b, 0xd5, 0x50, 0x99, 0x57, 0xbb, 0x76, 0x79, 0x16, 0xb1, 0xb0, 0x5c, + 0x76, 0x73, 0xec, 0xb2, 0xc3, 0x5a, 0xf6, 0xbb, 0xf1, 0xc0, 0x77, 0xb9, + 0xbe, 0xa8, 0xce, 0xbb, 0xcc, 0x3a, 0x6e, 0xdd, 0xab, 0x5c, 0x6e, 0x8d, + 0xa9, 0x0f, 0x32, 0x9e, 0x0e, 0xe6, 0x65, 0x82, 0xef, 0x94, 0xe3, 0xfa, + 0x11, 0xb9, 0xb2, 0xa0, 0xf6, 0xac, 0xbc, 0xbd, 0x21, 0xee, 0xf9, 0xa8, + 0xfd, 0x6f, 0xf8, 0xb5, 0x49, 0xe5, 0xd7, 0x97, 0x17, 0xd4, 0x3d, 0x17, + 0x2b, 0x39, 0x13, 0xf0, 0xfb, 0xc8, 0x25, 0xac, 0x07, 0xa4, 0x80, 0x9c, + 0xfb, 0xac, 0x75, 0x78, 0x0b, 0x71, 0x0e, 0x69, 0x2d, 0x83, 0xd6, 0xe5, + 0x05, 0xd9, 0xc2, 0x33, 0x25, 0x65, 0xb5, 0xcf, 0xe6, 0xd6, 0xc5, 0xa7, + 0xc5, 0xff, 0x7f, 0x1d, 0x41, 0x2f, 0x16, 0xf2, 0x5c, 0x0b, 0xdf, 0x73, + 0xa6, 0xaf, 0x40, 0x1e, 0x34, 0xc1, 0x7d, 0x9c, 0x66, 0xd3, 0xad, 0x9b, + 0x37, 0xb1, 0x2e, 0xda, 0xf8, 0x0e, 0x05, 0xfe, 0x0e, 0xc3, 0x7e, 0xb0, + 0x4e, 0x56, 0xdb, 0x79, 0xcd, 0xdc, 0xc3, 0xbf, 0x66, 0x60, 0xfb, 0x3f, + 0xe8, 0xf3, 0x49, 0x14, 0x38, 0x46, 0x00, 0x00, 0x00 }; static const u32 bnx2_TXP_b09FwData[(0xd0/4) + 1] = { 0x00000000, 0x00000014, 0x00000014, 0x00000014, 0x00000014, 0x00000010, @@ -4065,38 +4041,37 @@ static const u32 bnx2_TXP_b09FwData[(0xd0/4) + 1] = { 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }; static const u32 bnx2_TXP_b09FwRodata[(0x30/4) + 1] = { - 0x08003fdc, 0x08004008, 0x08004050, 0x08004050, 0x08003edc, 0x08003f08, - 0x08003f08, 0x08004050, 0x08004050, 0x08004050, 0x08003f70, 0x00000000, + 0x08004060, 0x0800408c, 0x080040d4, 0x080040d4, 0x08003f60, 0x08003f8c, + 0x08003f8c, 0x080040d4, 0x080040d4, 0x080040d4, 0x08003ff4, 0x00000000, 0x00000000 }; static struct fw_info bnx2_txp_fw_09 = { - /* Firmware version: 3.7.1 */ .ver_major = 0x3, - .ver_minor = 0x7, - .ver_fix = 0x1, + .ver_minor = 0x4, + .ver_fix = 0x3, .start_addr = 0x08000060, .text_addr = 0x08000000, - .text_len = 0x45b0, + .text_len = 0x4634, .text_index = 0x0, .gz_text = bnx2_TXP_b09FwText, .gz_text_len = sizeof(bnx2_TXP_b09FwText), - .data_addr = 0x08004600, + .data_addr = 0x08004680, .data_len = 0xd0, .data_index = 0x0, .data = bnx2_TXP_b09FwData, - .sbss_addr = 0x080046d0, + .sbss_addr = 0x08004750, .sbss_len = 0x8c, .sbss_index = 0x0, - .bss_addr = 0x08004760, + .bss_addr = 0x080047e0, .bss_len = 0xa20, .bss_index = 0x0, - .rodata_addr = 0x080045b0, + .rodata_addr = 0x08004638, .rodata_len = 0x30, .rodata_index = 0x0, .rodata = bnx2_TXP_b09FwRodata, diff --git a/trunk/drivers/net/bonding/bond_3ad.c b/trunk/drivers/net/bonding/bond_3ad.c index 084f0292ea6e..7a045a37056e 100644 --- a/trunk/drivers/net/bonding/bond_3ad.c +++ b/trunk/drivers/net/bonding/bond_3ad.c @@ -126,7 +126,7 @@ static struct aggregator *__get_active_agg(struct aggregator *aggregator); // ================= main 802.3ad protocol functions ================== static int ad_lacpdu_send(struct port *port); -static int ad_marker_send(struct port *port, struct bond_marker *marker); +static int ad_marker_send(struct port *port, struct marker *marker); static void ad_mux_machine(struct port *port); static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port); static void ad_tx_machine(struct port *port); @@ -139,8 +139,8 @@ static void ad_initialize_port(struct port *port, int lacp_fast); static void ad_initialize_lacpdu(struct lacpdu *Lacpdu); static void ad_enable_collecting_distributing(struct port *port); static void ad_disable_collecting_distributing(struct port *port); -static void ad_marker_info_received(struct bond_marker *marker_info, struct port *port); -static void ad_marker_response_received(struct bond_marker *marker, struct port *port); +static void ad_marker_info_received(struct marker *marker_info, struct port *port); +static void ad_marker_response_received(struct marker *marker, struct port *port); ///////////////////////////////////////////////////////////////////////////////// @@ -889,12 +889,12 @@ static int ad_lacpdu_send(struct port *port) * Returns: 0 on success * < 0 on error */ -static int ad_marker_send(struct port *port, struct bond_marker *marker) +static int ad_marker_send(struct port *port, struct marker *marker) { struct slave *slave = port->slave; struct sk_buff *skb; - struct bond_marker_header *marker_header; - int length = sizeof(struct bond_marker_header); + struct marker_header *marker_header; + int length = sizeof(struct marker_header); struct mac_addr lacpdu_multicast_address = AD_MULTICAST_LACPDU_ADDR; skb = dev_alloc_skb(length + 16); @@ -909,7 +909,7 @@ static int ad_marker_send(struct port *port, struct bond_marker *marker) skb->network_header = skb->mac_header + ETH_HLEN; skb->protocol = PKT_TYPE_LACPDU; - marker_header = (struct bond_marker_header *)skb_put(skb, length); + marker_header = (struct marker_header *)skb_put(skb, length); marker_header->ad_header.destination_address = lacpdu_multicast_address; /* Note: source addres is set to be the member's PERMANENT address, because we use it @@ -1709,7 +1709,7 @@ static void ad_disable_collecting_distributing(struct port *port) */ static void ad_marker_info_send(struct port *port) { - struct bond_marker marker; + struct marker marker; u16 index; // fill the marker PDU with the appropriate values @@ -1742,14 +1742,13 @@ static void ad_marker_info_send(struct port *port) * @port: the port we're looking at * */ -static void ad_marker_info_received(struct bond_marker *marker_info, - struct port *port) +static void ad_marker_info_received(struct marker *marker_info,struct port *port) { - struct bond_marker marker; + struct marker marker; // copy the received marker data to the response marker //marker = *marker_info; - memcpy(&marker, marker_info, sizeof(struct bond_marker)); + memcpy(&marker, marker_info, sizeof(struct marker)); // change the marker subtype to marker response marker.tlv_type=AD_MARKER_RESPONSE_SUBTYPE; // send the marker response @@ -1768,8 +1767,7 @@ static void ad_marker_info_received(struct bond_marker *marker_info, * response for marker PDU's, in this stage, but only to respond to marker * information. */ -static void ad_marker_response_received(struct bond_marker *marker, - struct port *port) +static void ad_marker_response_received(struct marker *marker, struct port *port) { marker=NULL; // just to satisfy the compiler port=NULL; // just to satisfy the compiler @@ -2166,15 +2164,15 @@ static void bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u case AD_TYPE_MARKER: // No need to convert fields to Little Endian since we don't use the marker's fields. - switch (((struct bond_marker *)lacpdu)->tlv_type) { + switch (((struct marker *)lacpdu)->tlv_type) { case AD_MARKER_INFORMATION_SUBTYPE: dprintk("Received Marker Information on port %d\n", port->actor_port_number); - ad_marker_info_received((struct bond_marker *)lacpdu, port); + ad_marker_info_received((struct marker *)lacpdu, port); break; case AD_MARKER_RESPONSE_SUBTYPE: dprintk("Received Marker Response on port %d\n", port->actor_port_number); - ad_marker_response_received((struct bond_marker *)lacpdu, port); + ad_marker_response_received((struct marker *)lacpdu, port); break; default: diff --git a/trunk/drivers/net/bonding/bond_3ad.h b/trunk/drivers/net/bonding/bond_3ad.h index f16557264944..862952fa6fd9 100644 --- a/trunk/drivers/net/bonding/bond_3ad.h +++ b/trunk/drivers/net/bonding/bond_3ad.h @@ -92,7 +92,7 @@ typedef enum { typedef enum { AD_MARKER_INFORMATION_SUBTYPE = 1, // marker imformation subtype AD_MARKER_RESPONSE_SUBTYPE // marker response subtype -} bond_marker_subtype_t; +} marker_subtype_t; // timers types(43.4.9 in the 802.3ad standard) typedef enum { @@ -148,7 +148,7 @@ typedef struct lacpdu_header { } lacpdu_header_t; // Marker Protocol Data Unit(PDU) structure(43.5.3.2 in the 802.3ad standard) -typedef struct bond_marker { +typedef struct marker { u8 subtype; // = 0x02 (marker PDU) u8 version_number; // = 0x01 u8 tlv_type; // = 0x01 (marker information) @@ -161,12 +161,12 @@ typedef struct bond_marker { u8 tlv_type_terminator; // = 0x00 u8 terminator_length; // = 0x00 u8 reserved_90[90]; // = 0 -} bond_marker_t; +} marker_t; -typedef struct bond_marker_header { +typedef struct marker_header { struct ad_header ad_header; - struct bond_marker marker; -} bond_marker_header_t; + struct marker marker; +} marker_header_t; #pragma pack() diff --git a/trunk/drivers/net/cris/eth_v10.c b/trunk/drivers/net/cris/eth_v10.c index edd6828f0a78..314b2f68f78f 100644 --- a/trunk/drivers/net/cris/eth_v10.c +++ b/trunk/drivers/net/cris/eth_v10.c @@ -234,7 +234,6 @@ #include #include #include -#include #include #include @@ -248,6 +247,7 @@ #include #include #include +#include #include #include diff --git a/trunk/drivers/net/cxgb3/adapter.h b/trunk/drivers/net/cxgb3/adapter.h index 2a3df145850d..044261703381 100644 --- a/trunk/drivers/net/cxgb3/adapter.h +++ b/trunk/drivers/net/cxgb3/adapter.h @@ -41,9 +41,9 @@ #include #include #include -#include #include "t3cdev.h" #include +#include #include typedef irqreturn_t(*intr_handler_t) (int, void *); diff --git a/trunk/drivers/net/ehea/ehea_main.c b/trunk/drivers/net/ehea/ehea_main.c index 2809c99906e0..fe5ffac7ac57 100644 --- a/trunk/drivers/net/ehea/ehea_main.c +++ b/trunk/drivers/net/ehea/ehea_main.c @@ -3218,7 +3218,7 @@ static int __devinit ehea_probe_adapter(struct of_device *dev, /* get adapter properties */ ret = ehea_sense_adapter_attr(adapter); if (ret) { - dev_err(&dev->dev, "sense_adapter_attr failed: %d\n", ret); + dev_err(&dev->dev, "sense_adapter_attr failed: %d", ret); goto out_free_ad; } @@ -3226,7 +3226,7 @@ static int __devinit ehea_probe_adapter(struct of_device *dev, EHEA_NEQ, EHEA_MAX_ENTRIES_EQ, 1); if (!adapter->neq) { ret = -EIO; - dev_err(&dev->dev, "NEQ creation failed\n"); + dev_err(&dev->dev, "NEQ creation failed"); goto out_free_ad; } @@ -3237,7 +3237,7 @@ static int __devinit ehea_probe_adapter(struct of_device *dev, ehea_interrupt_neq, IRQF_DISABLED, "ehea_neq", adapter); if (ret) { - dev_err(&dev->dev, "requesting NEQ IRQ failed\n"); + dev_err(&dev->dev, "requesting NEQ IRQ failed"); goto out_kill_eq; } @@ -3247,7 +3247,7 @@ static int __devinit ehea_probe_adapter(struct of_device *dev, ret = ehea_setup_ports(adapter); if (ret) { - dev_err(&dev->dev, "setup_ports failed\n"); + dev_err(&dev->dev, "setup_ports failed"); goto out_rem_dev_sysfs; } diff --git a/trunk/drivers/net/eth16i.c b/trunk/drivers/net/eth16i.c index e3dd8b136908..243fc6b354b5 100644 --- a/trunk/drivers/net/eth16i.c +++ b/trunk/drivers/net/eth16i.c @@ -170,6 +170,7 @@ static char *version = /* Few macros */ +#define BIT(a) ( (1 << (a)) ) #define BITSET(ioaddr, bnum) ((outb(((inb(ioaddr)) | (bnum)), ioaddr))) #define BITCLR(ioaddr, bnum) ((outb(((inb(ioaddr)) & (~(bnum))), ioaddr))) diff --git a/trunk/drivers/net/forcedeth.c b/trunk/drivers/net/forcedeth.c index 70ddf1acfd88..cfbb7aacfe94 100644 --- a/trunk/drivers/net/forcedeth.c +++ b/trunk/drivers/net/forcedeth.c @@ -992,7 +992,7 @@ static void nv_enable_irq(struct net_device *dev) if (np->msi_flags & NV_MSI_X_ENABLED) enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); else - enable_irq(np->pci_dev->irq); + enable_irq(dev->irq); } else { enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector); enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector); @@ -1008,7 +1008,7 @@ static void nv_disable_irq(struct net_device *dev) if (np->msi_flags & NV_MSI_X_ENABLED) disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); else - disable_irq(np->pci_dev->irq); + disable_irq(dev->irq); } else { disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector); disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector); @@ -1607,7 +1607,7 @@ static void nv_do_rx_refill(unsigned long data) if (np->msi_flags & NV_MSI_X_ENABLED) disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); else - disable_irq(np->pci_dev->irq); + disable_irq(dev->irq); } else { disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector); } @@ -1625,7 +1625,7 @@ static void nv_do_rx_refill(unsigned long data) if (np->msi_flags & NV_MSI_X_ENABLED) enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); else - enable_irq(np->pci_dev->irq); + enable_irq(dev->irq); } else { enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector); } @@ -2408,13 +2408,13 @@ static int nv_rx_process_optimized(struct net_device *dev, int limit) struct fe_priv *np = netdev_priv(dev); u32 flags; u32 vlanflags = 0; - int rx_work = 0; + u32 rx_processed_cnt = 0; struct sk_buff *skb; int len; while((np->get_rx.ex != np->put_rx.ex) && !((flags = le32_to_cpu(np->get_rx.ex->flaglen)) & NV_RX2_AVAIL) && - (rx_work < limit)) { + (rx_processed_cnt++ < limit)) { dprintk(KERN_DEBUG "%s: nv_rx_process_optimized: flags 0x%x.\n", dev->name, flags); @@ -2517,11 +2517,9 @@ static int nv_rx_process_optimized(struct net_device *dev, int limit) np->get_rx.ex = np->first_rx.ex; if (unlikely(np->get_rx_ctx++ == np->last_rx_ctx)) np->get_rx_ctx = np->first_rx_ctx; - - rx_work++; } - return rx_work; + return rx_processed_cnt; } static void set_bufsize(struct net_device *dev) @@ -3560,12 +3558,10 @@ static int nv_request_irq(struct net_device *dev, int intr_test) if (ret != 0 && np->msi_flags & NV_MSI_CAPABLE) { if ((ret = pci_enable_msi(np->pci_dev)) == 0) { np->msi_flags |= NV_MSI_ENABLED; - dev->irq = np->pci_dev->irq; if (request_irq(np->pci_dev->irq, handler, IRQF_SHARED, dev->name, dev) != 0) { printk(KERN_INFO "forcedeth: request_irq failed %d\n", ret); pci_disable_msi(np->pci_dev); np->msi_flags &= ~NV_MSI_ENABLED; - dev->irq = np->pci_dev->irq; goto out_err; } @@ -3628,7 +3624,7 @@ static void nv_do_nic_poll(unsigned long data) if (np->msi_flags & NV_MSI_X_ENABLED) disable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); else - disable_irq_lockdep(np->pci_dev->irq); + disable_irq_lockdep(dev->irq); mask = np->irqmask; } else { if (np->nic_poll_irq & NVREG_IRQ_RX_ALL) { @@ -3646,8 +3642,6 @@ static void nv_do_nic_poll(unsigned long data) } np->nic_poll_irq = 0; - /* disable_irq() contains synchronize_irq, thus no irq handler can run now */ - if (np->recover_error) { np->recover_error = 0; printk(KERN_INFO "forcedeth: MAC in recoverable error state\n"); @@ -3684,6 +3678,7 @@ static void nv_do_nic_poll(unsigned long data) } } + /* FIXME: Do we need synchronize_irq(dev->irq) here? */ writel(mask, base + NvRegIrqMask); pci_push(base); @@ -3696,7 +3691,7 @@ static void nv_do_nic_poll(unsigned long data) if (np->msi_flags & NV_MSI_X_ENABLED) enable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector); else - enable_irq_lockdep(np->pci_dev->irq); + enable_irq_lockdep(dev->irq); } else { if (np->nic_poll_irq & NVREG_IRQ_RX_ALL) { nv_nic_irq_rx(0, dev); @@ -4953,7 +4948,7 @@ static int nv_close(struct net_device *dev) #ifdef CONFIG_FORCEDETH_NAPI napi_disable(&np->napi); #endif - synchronize_irq(np->pci_dev->irq); + synchronize_irq(dev->irq); del_timer_sync(&np->oom_kick); del_timer_sync(&np->nic_poll); diff --git a/trunk/drivers/net/fs_enet/fs_enet-main.c b/trunk/drivers/net/fs_enet/fs_enet-main.c index f2a4d399a6e5..04c6faec88d2 100644 --- a/trunk/drivers/net/fs_enet/fs_enet-main.c +++ b/trunk/drivers/net/fs_enet/fs_enet-main.c @@ -88,7 +88,7 @@ static void skb_align(struct sk_buff *skb, int align) static int fs_enet_rx_napi(struct napi_struct *napi, int budget) { struct fs_enet_private *fep = container_of(napi, struct fs_enet_private, napi); - struct net_device *dev = fep->ndev; + struct net_device *dev = to_net_dev(fep->dev); const struct fs_platform_info *fpi = fep->fpi; cbd_t __iomem *bdp; struct sk_buff *skb, *skbn, *skbt; @@ -217,7 +217,7 @@ static int fs_enet_rx_napi(struct napi_struct *napi, int budget) fep->cur_rx = bdp; - if (received < budget) { + if (received >= budget) { /* done */ netif_rx_complete(dev, napi); (*fep->ops->napi_enable_rx)(dev); @@ -807,23 +807,20 @@ static int fs_enet_open(struct net_device *dev) int r; int err; - if (fep->fpi->use_napi) - napi_enable(&fep->napi); + napi_enable(&fep->napi); /* Install our interrupt handler. */ r = fs_request_irq(dev, fep->interrupt, "fs_enet-mac", fs_enet_interrupt); if (r != 0) { printk(KERN_ERR DRV_MODULE_NAME ": %s Could not allocate FS_ENET IRQ!", dev->name); - if (fep->fpi->use_napi) - napi_disable(&fep->napi); + napi_disable(&fep->napi); return -EINVAL; } err = fs_init_phy(dev); - if (err) { - if (fep->fpi->use_napi) - napi_disable(&fep->napi); + if(err) { + napi_disable(&fep->napi); return err; } phy_start(fep->phydev); @@ -1235,7 +1232,7 @@ static int __devinit fs_enet_probe(struct of_device *ofdev, fpi->rx_ring = 32; fpi->tx_ring = 32; fpi->rx_copybreak = 240; - fpi->use_napi = 1; + fpi->use_napi = 0; fpi->napi_weight = 17; ret = find_phy(ofdev->node, fpi); @@ -1252,11 +1249,11 @@ static int __devinit fs_enet_probe(struct of_device *ofdev, goto out_free_fpi; } + SET_MODULE_OWNER(ndev); dev_set_drvdata(&ofdev->dev, ndev); fep = netdev_priv(ndev); fep->dev = &ofdev->dev; - fep->ndev = ndev; fep->fpi = fpi; fep->ops = match->data; @@ -1291,11 +1288,10 @@ static int __devinit fs_enet_probe(struct of_device *ofdev, ndev->stop = fs_enet_close; ndev->get_stats = fs_enet_get_stats; ndev->set_multicast_list = fs_set_multicast_list; - - if (fpi->use_napi) - netif_napi_add(ndev, &fep->napi, fs_enet_rx_napi, - fpi->napi_weight); - + if (fpi->use_napi) { + ndev->poll = fs_enet_rx_napi; + ndev->weight = fpi->napi_weight; + } ndev->ethtool_ops = &fs_ethtool_ops; ndev->do_ioctl = fs_ioctl; diff --git a/trunk/drivers/net/fs_enet/fs_enet.h b/trunk/drivers/net/fs_enet/fs_enet.h index c675e29aadcc..baf6477165af 100644 --- a/trunk/drivers/net/fs_enet/fs_enet.h +++ b/trunk/drivers/net/fs_enet/fs_enet.h @@ -75,7 +75,6 @@ struct phy_info { struct fs_enet_private { struct napi_struct napi; struct device *dev; /* pointer back to the device (must be initialized first) */ - struct net_device *ndev; spinlock_t lock; /* during all ops except TX pckt processing */ spinlock_t tx_lock; /* during fs_start_xmit and fs_tx */ struct fs_platform_info *fpi; diff --git a/trunk/drivers/net/gianfar.c b/trunk/drivers/net/gianfar.c index 38268d7335a8..cc288d8f6a53 100644 --- a/trunk/drivers/net/gianfar.c +++ b/trunk/drivers/net/gianfar.c @@ -956,12 +956,10 @@ static int gfar_enet_open(struct net_device *dev) } err = startup_gfar(dev); - if (err) { + if (err) #ifdef CONFIG_GFAR_NAPI napi_disable(&priv->napi); #endif - return err; - } netif_start_queue(dev); diff --git a/trunk/drivers/net/gianfar.h b/trunk/drivers/net/gianfar.h index 46cd7735e6fe..c16cc8b946a9 100644 --- a/trunk/drivers/net/gianfar.h +++ b/trunk/drivers/net/gianfar.h @@ -749,6 +749,7 @@ struct gfar_private { uint32_t msg_enable; /* Network Statistics */ + struct net_device_stats stats; struct gfar_extra_stats extra_stats; }; diff --git a/trunk/drivers/net/hamradio/dmascc.c b/trunk/drivers/net/hamradio/dmascc.c index 11b83dae00ac..bc02e4694804 100644 --- a/trunk/drivers/net/hamradio/dmascc.c +++ b/trunk/drivers/net/hamradio/dmascc.c @@ -21,7 +21,6 @@ #include -#include #include #include #include @@ -36,6 +35,7 @@ #include #include #include +#include #include #include #include diff --git a/trunk/drivers/net/ibm_newemac/mal.c b/trunk/drivers/net/ibm_newemac/mal.c index 9a88f71db004..a680eb05ba60 100644 --- a/trunk/drivers/net/ibm_newemac/mal.c +++ b/trunk/drivers/net/ibm_newemac/mal.c @@ -322,7 +322,7 @@ void mal_poll_disable(struct mal_instance *mal, struct mal_commac *commac) msleep(1); /* Synchronize with the MAL NAPI poller */ - napi_synchronize(&mal->napi); + __napi_synchronize(&mal->napi); } void mal_poll_enable(struct mal_instance *mal, struct mal_commac *commac) diff --git a/trunk/drivers/net/mac89x0.c b/trunk/drivers/net/mac89x0.c index a19b5958cee9..30854f094965 100644 --- a/trunk/drivers/net/mac89x0.c +++ b/trunk/drivers/net/mac89x0.c @@ -99,9 +99,9 @@ static char *version = #include #include #include -#include #include +#include #include #include #include diff --git a/trunk/drivers/net/meth.h b/trunk/drivers/net/meth.h index a78dc1ca8c29..ea3b8fc86d1e 100644 --- a/trunk/drivers/net/meth.h +++ b/trunk/drivers/net/meth.h @@ -28,6 +28,9 @@ #define RX_BUFFER_OFFSET (sizeof(rx_status_vector)+2) /* staus vector + 2 bytes of padding */ #define RX_BUCKET_SIZE 256 +#undef BIT +#define BIT(x) (1UL << (x)) + /* For more detailed explanations of what each field menas, see Nick's great comments to #defines below (or docs, if you are lucky enough toget hold of them :)*/ diff --git a/trunk/drivers/net/myri10ge/myri10ge.c b/trunk/drivers/net/myri10ge/myri10ge.c index 366e62a2b1e5..64c8151f2004 100644 --- a/trunk/drivers/net/myri10ge/myri10ge.c +++ b/trunk/drivers/net/myri10ge/myri10ge.c @@ -3058,8 +3058,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (status != 0) { dac_enabled = 0; dev_err(&pdev->dev, - "64-bit pci address mask was refused, " - "trying 32-bit\n"); + "64-bit pci address mask was refused, trying 32-bit"); status = pci_set_dma_mask(pdev, DMA_32BIT_MASK); } if (status != 0) { diff --git a/trunk/drivers/net/netxen/netxen_nic_main.c b/trunk/drivers/net/netxen/netxen_nic_main.c index 601051c584e8..2a1d6d7ec351 100644 --- a/trunk/drivers/net/netxen/netxen_nic_main.c +++ b/trunk/drivers/net/netxen/netxen_nic_main.c @@ -53,6 +53,9 @@ static char netxen_nic_driver_string[] = "NetXen Network Driver version " #define NETXEN_ADAPTER_UP_MAGIC 777 #define NETXEN_NIC_PEG_TUNE 0 +#define DMA_32BIT_MASK 0x00000000ffffffffULL +#define DMA_35BIT_MASK 0x00000007ffffffffULL + /* Local functions to NetXen NIC driver */ static int __devinit netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent); diff --git a/trunk/drivers/net/pcnet32.c b/trunk/drivers/net/pcnet32.c index ff92aca0a7b3..5f994b5beda1 100644 --- a/trunk/drivers/net/pcnet32.c +++ b/trunk/drivers/net/pcnet32.c @@ -282,6 +282,7 @@ struct pcnet32_private { struct net_device *dev; struct napi_struct napi; + struct net_device_stats stats; char tx_full; char phycount; /* number of phys found */ int options; @@ -441,9 +442,7 @@ static struct pcnet32_access pcnet32_dwio = { static void pcnet32_netif_stop(struct net_device *dev) { -#ifdef CONFIG_PCNET32_NAPI struct pcnet32_private *lp = netdev_priv(dev); -#endif dev->trans_start = jiffies; #ifdef CONFIG_PCNET32_NAPI napi_disable(&lp->napi); @@ -453,9 +452,7 @@ static void pcnet32_netif_stop(struct net_device *dev) static void pcnet32_netif_start(struct net_device *dev) { -#ifdef CONFIG_PCNET32_NAPI struct pcnet32_private *lp = netdev_priv(dev); -#endif netif_wake_queue(dev); #ifdef CONFIG_PCNET32_NAPI napi_enable(&lp->napi); @@ -1181,15 +1178,15 @@ static void pcnet32_rx_entry(struct net_device *dev, * buffers, with only the last correctly noting the error. */ if (status & 0x01) /* Only count a general error at the */ - dev->stats.rx_errors++; /* end of a packet. */ + lp->stats.rx_errors++; /* end of a packet. */ if (status & 0x20) - dev->stats.rx_frame_errors++; + lp->stats.rx_frame_errors++; if (status & 0x10) - dev->stats.rx_over_errors++; + lp->stats.rx_over_errors++; if (status & 0x08) - dev->stats.rx_crc_errors++; + lp->stats.rx_crc_errors++; if (status & 0x04) - dev->stats.rx_fifo_errors++; + lp->stats.rx_fifo_errors++; return; } @@ -1200,13 +1197,13 @@ static void pcnet32_rx_entry(struct net_device *dev, if (netif_msg_drv(lp)) printk(KERN_ERR "%s: Impossible packet size %d!\n", dev->name, pkt_len); - dev->stats.rx_errors++; + lp->stats.rx_errors++; return; } if (pkt_len < 60) { if (netif_msg_rx_err(lp)) printk(KERN_ERR "%s: Runt packet!\n", dev->name); - dev->stats.rx_errors++; + lp->stats.rx_errors++; return; } @@ -1240,7 +1237,7 @@ static void pcnet32_rx_entry(struct net_device *dev, printk(KERN_ERR "%s: Memory squeeze, dropping packet.\n", dev->name); - dev->stats.rx_dropped++; + lp->stats.rx_dropped++; return; } skb->dev = dev; @@ -1259,7 +1256,7 @@ static void pcnet32_rx_entry(struct net_device *dev, pkt_len, PCI_DMA_FROMDEVICE); } - dev->stats.rx_bytes += skb->len; + lp->stats.rx_bytes += skb->len; skb->protocol = eth_type_trans(skb, dev); #ifdef CONFIG_PCNET32_NAPI netif_receive_skb(skb); @@ -1267,7 +1264,7 @@ static void pcnet32_rx_entry(struct net_device *dev, netif_rx(skb); #endif dev->last_rx = jiffies; - dev->stats.rx_packets++; + lp->stats.rx_packets++; return; } @@ -1315,21 +1312,21 @@ static int pcnet32_tx(struct net_device *dev) if (status & 0x4000) { /* There was a major error, log it. */ int err_status = le32_to_cpu(lp->tx_ring[entry].misc); - dev->stats.tx_errors++; + lp->stats.tx_errors++; if (netif_msg_tx_err(lp)) printk(KERN_ERR "%s: Tx error status=%04x err_status=%08x\n", dev->name, status, err_status); if (err_status & 0x04000000) - dev->stats.tx_aborted_errors++; + lp->stats.tx_aborted_errors++; if (err_status & 0x08000000) - dev->stats.tx_carrier_errors++; + lp->stats.tx_carrier_errors++; if (err_status & 0x10000000) - dev->stats.tx_window_errors++; + lp->stats.tx_window_errors++; #ifndef DO_DXSUFLO if (err_status & 0x40000000) { - dev->stats.tx_fifo_errors++; + lp->stats.tx_fifo_errors++; /* Ackk! On FIFO errors the Tx unit is turned off! */ /* Remove this verbosity later! */ if (netif_msg_tx_err(lp)) @@ -1340,7 +1337,7 @@ static int pcnet32_tx(struct net_device *dev) } #else if (err_status & 0x40000000) { - dev->stats.tx_fifo_errors++; + lp->stats.tx_fifo_errors++; if (!lp->dxsuflo) { /* If controller doesn't recover ... */ /* Ackk! On FIFO errors the Tx unit is turned off! */ /* Remove this verbosity later! */ @@ -1354,8 +1351,8 @@ static int pcnet32_tx(struct net_device *dev) #endif } else { if (status & 0x1800) - dev->stats.collisions++; - dev->stats.tx_packets++; + lp->stats.collisions++; + lp->stats.tx_packets++; } /* We must free the original skb */ @@ -1852,9 +1849,6 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev) lp->mii_if.mdio_read = mdio_read; lp->mii_if.mdio_write = mdio_write; - /* napi.weight is used in both the napi and non-napi cases */ - lp->napi.weight = lp->rx_ring_size / 2; - #ifdef CONFIG_PCNET32_NAPI netif_napi_add(dev, &lp->napi, pcnet32_poll, lp->rx_ring_size / 2); #endif @@ -2477,7 +2471,7 @@ static void pcnet32_tx_timeout(struct net_device *dev) "%s: transmit timed out, status %4.4x, resetting.\n", dev->name, lp->a.read_csr(ioaddr, CSR0)); lp->a.write_csr(ioaddr, CSR0, CSR0_STOP); - dev->stats.tx_errors++; + lp->stats.tx_errors++; if (netif_msg_tx_err(lp)) { int i; printk(KERN_DEBUG @@ -2547,7 +2541,7 @@ static int pcnet32_start_xmit(struct sk_buff *skb, struct net_device *dev) lp->tx_ring[entry].status = cpu_to_le16(status); lp->cur_tx++; - dev->stats.tx_bytes += skb->len; + lp->stats.tx_bytes += skb->len; /* Trigger an immediate send poll. */ lp->a.write_csr(ioaddr, CSR0, CSR0_INTEN | CSR0_TXPOLL); @@ -2592,7 +2586,7 @@ pcnet32_interrupt(int irq, void *dev_id) /* Log misc errors. */ if (csr0 & 0x4000) - dev->stats.tx_errors++; /* Tx babble. */ + lp->stats.tx_errors++; /* Tx babble. */ if (csr0 & 0x1000) { /* * This happens when our receive ring is full. This @@ -2605,7 +2599,7 @@ pcnet32_interrupt(int irq, void *dev_id) * don't get a rx interrupt, but a missed frame * interrupt sooner or later. */ - dev->stats.rx_errors++; /* Missed a Rx frame. */ + lp->stats.rx_errors++; /* Missed a Rx frame. */ } if (csr0 & 0x0800) { if (netif_msg_drv(lp)) @@ -2667,7 +2661,7 @@ static int pcnet32_close(struct net_device *dev) spin_lock_irqsave(&lp->lock, flags); - dev->stats.rx_missed_errors = lp->a.read_csr(ioaddr, 112); + lp->stats.rx_missed_errors = lp->a.read_csr(ioaddr, 112); if (netif_msg_ifdown(lp)) printk(KERN_DEBUG @@ -2704,10 +2698,10 @@ static struct net_device_stats *pcnet32_get_stats(struct net_device *dev) unsigned long flags; spin_lock_irqsave(&lp->lock, flags); - dev->stats.rx_missed_errors = lp->a.read_csr(ioaddr, 112); + lp->stats.rx_missed_errors = lp->a.read_csr(ioaddr, 112); spin_unlock_irqrestore(&lp->lock, flags); - return &dev->stats; + return &lp->stats; } /* taken from the sunlance driver, which it took from the depca driver */ diff --git a/trunk/drivers/net/s2io-regs.h b/trunk/drivers/net/s2io-regs.h index 01f08d726ace..aef66e2d98d2 100644 --- a/trunk/drivers/net/s2io-regs.h +++ b/trunk/drivers/net/s2io-regs.h @@ -20,17 +20,17 @@ struct XENA_dev_config { /* General Control-Status Registers */ u64 general_int_status; -#define GEN_INTR_TXPIC s2BIT(0) -#define GEN_INTR_TXDMA s2BIT(1) -#define GEN_INTR_TXMAC s2BIT(2) -#define GEN_INTR_TXXGXS s2BIT(3) -#define GEN_INTR_TXTRAFFIC s2BIT(8) -#define GEN_INTR_RXPIC s2BIT(32) -#define GEN_INTR_RXDMA s2BIT(33) -#define GEN_INTR_RXMAC s2BIT(34) -#define GEN_INTR_MC s2BIT(35) -#define GEN_INTR_RXXGXS s2BIT(36) -#define GEN_INTR_RXTRAFFIC s2BIT(40) +#define GEN_INTR_TXPIC BIT(0) +#define GEN_INTR_TXDMA BIT(1) +#define GEN_INTR_TXMAC BIT(2) +#define GEN_INTR_TXXGXS BIT(3) +#define GEN_INTR_TXTRAFFIC BIT(8) +#define GEN_INTR_RXPIC BIT(32) +#define GEN_INTR_RXDMA BIT(33) +#define GEN_INTR_RXMAC BIT(34) +#define GEN_INTR_MC BIT(35) +#define GEN_INTR_RXXGXS BIT(36) +#define GEN_INTR_RXTRAFFIC BIT(40) #define GEN_ERROR_INTR GEN_INTR_TXPIC | GEN_INTR_RXPIC | \ GEN_INTR_TXDMA | GEN_INTR_RXDMA | \ GEN_INTR_TXMAC | GEN_INTR_RXMAC | \ @@ -54,36 +54,36 @@ struct XENA_dev_config { u64 adapter_status; -#define ADAPTER_STATUS_TDMA_READY s2BIT(0) -#define ADAPTER_STATUS_RDMA_READY s2BIT(1) -#define ADAPTER_STATUS_PFC_READY s2BIT(2) -#define ADAPTER_STATUS_TMAC_BUF_EMPTY s2BIT(3) -#define ADAPTER_STATUS_PIC_QUIESCENT s2BIT(5) -#define ADAPTER_STATUS_RMAC_REMOTE_FAULT s2BIT(6) -#define ADAPTER_STATUS_RMAC_LOCAL_FAULT s2BIT(7) +#define ADAPTER_STATUS_TDMA_READY BIT(0) +#define ADAPTER_STATUS_RDMA_READY BIT(1) +#define ADAPTER_STATUS_PFC_READY BIT(2) +#define ADAPTER_STATUS_TMAC_BUF_EMPTY BIT(3) +#define ADAPTER_STATUS_PIC_QUIESCENT BIT(5) +#define ADAPTER_STATUS_RMAC_REMOTE_FAULT BIT(6) +#define ADAPTER_STATUS_RMAC_LOCAL_FAULT BIT(7) #define ADAPTER_STATUS_RMAC_PCC_IDLE vBIT(0xFF,8,8) #define ADAPTER_STATUS_RMAC_PCC_FOUR_IDLE vBIT(0x0F,8,8) #define ADAPTER_STATUS_RC_PRC_QUIESCENT vBIT(0xFF,16,8) -#define ADAPTER_STATUS_MC_DRAM_READY s2BIT(24) -#define ADAPTER_STATUS_MC_QUEUES_READY s2BIT(25) -#define ADAPTER_STATUS_M_PLL_LOCK s2BIT(30) -#define ADAPTER_STATUS_P_PLL_LOCK s2BIT(31) +#define ADAPTER_STATUS_MC_DRAM_READY BIT(24) +#define ADAPTER_STATUS_MC_QUEUES_READY BIT(25) +#define ADAPTER_STATUS_M_PLL_LOCK BIT(30) +#define ADAPTER_STATUS_P_PLL_LOCK BIT(31) u64 adapter_control; -#define ADAPTER_CNTL_EN s2BIT(7) -#define ADAPTER_EOI_TX_ON s2BIT(15) -#define ADAPTER_LED_ON s2BIT(23) +#define ADAPTER_CNTL_EN BIT(7) +#define ADAPTER_EOI_TX_ON BIT(15) +#define ADAPTER_LED_ON BIT(23) #define ADAPTER_UDPI(val) vBIT(val,36,4) -#define ADAPTER_WAIT_INT s2BIT(48) -#define ADAPTER_ECC_EN s2BIT(55) +#define ADAPTER_WAIT_INT BIT(48) +#define ADAPTER_ECC_EN BIT(55) u64 serr_source; -#define SERR_SOURCE_PIC s2BIT(0) -#define SERR_SOURCE_TXDMA s2BIT(1) -#define SERR_SOURCE_RXDMA s2BIT(2) -#define SERR_SOURCE_MAC s2BIT(3) -#define SERR_SOURCE_MC s2BIT(4) -#define SERR_SOURCE_XGXS s2BIT(5) +#define SERR_SOURCE_PIC BIT(0) +#define SERR_SOURCE_TXDMA BIT(1) +#define SERR_SOURCE_RXDMA BIT(2) +#define SERR_SOURCE_MAC BIT(3) +#define SERR_SOURCE_MC BIT(4) +#define SERR_SOURCE_XGXS BIT(5) #define SERR_SOURCE_ANY (SERR_SOURCE_PIC | \ SERR_SOURCE_TXDMA | \ SERR_SOURCE_RXDMA | \ @@ -101,41 +101,41 @@ struct XENA_dev_config { #define PCI_MODE_PCIX_M2_66 0x5 #define PCI_MODE_PCIX_M2_100 0x6 #define PCI_MODE_PCIX_M2_133 0x7 -#define PCI_MODE_UNSUPPORTED s2BIT(0) -#define PCI_MODE_32_BITS s2BIT(8) -#define PCI_MODE_UNKNOWN_MODE s2BIT(9) +#define PCI_MODE_UNSUPPORTED BIT(0) +#define PCI_MODE_32_BITS BIT(8) +#define PCI_MODE_UNKNOWN_MODE BIT(9) u8 unused_0[0x800 - 0x128]; /* PCI-X Controller registers */ u64 pic_int_status; u64 pic_int_mask; -#define PIC_INT_TX s2BIT(0) -#define PIC_INT_FLSH s2BIT(1) -#define PIC_INT_MDIO s2BIT(2) -#define PIC_INT_IIC s2BIT(3) -#define PIC_INT_GPIO s2BIT(4) -#define PIC_INT_RX s2BIT(32) +#define PIC_INT_TX BIT(0) +#define PIC_INT_FLSH BIT(1) +#define PIC_INT_MDIO BIT(2) +#define PIC_INT_IIC BIT(3) +#define PIC_INT_GPIO BIT(4) +#define PIC_INT_RX BIT(32) u64 txpic_int_reg; u64 txpic_int_mask; -#define PCIX_INT_REG_ECC_SG_ERR s2BIT(0) -#define PCIX_INT_REG_ECC_DB_ERR s2BIT(1) -#define PCIX_INT_REG_FLASHR_R_FSM_ERR s2BIT(8) -#define PCIX_INT_REG_FLASHR_W_FSM_ERR s2BIT(9) -#define PCIX_INT_REG_INI_TX_FSM_SERR s2BIT(10) -#define PCIX_INT_REG_INI_TXO_FSM_ERR s2BIT(11) -#define PCIX_INT_REG_TRT_FSM_SERR s2BIT(13) -#define PCIX_INT_REG_SRT_FSM_SERR s2BIT(14) -#define PCIX_INT_REG_PIFR_FSM_SERR s2BIT(15) -#define PCIX_INT_REG_WRC_TX_SEND_FSM_SERR s2BIT(21) -#define PCIX_INT_REG_RRC_TX_REQ_FSM_SERR s2BIT(23) -#define PCIX_INT_REG_INI_RX_FSM_SERR s2BIT(48) -#define PCIX_INT_REG_RA_RX_FSM_SERR s2BIT(50) +#define PCIX_INT_REG_ECC_SG_ERR BIT(0) +#define PCIX_INT_REG_ECC_DB_ERR BIT(1) +#define PCIX_INT_REG_FLASHR_R_FSM_ERR BIT(8) +#define PCIX_INT_REG_FLASHR_W_FSM_ERR BIT(9) +#define PCIX_INT_REG_INI_TX_FSM_SERR BIT(10) +#define PCIX_INT_REG_INI_TXO_FSM_ERR BIT(11) +#define PCIX_INT_REG_TRT_FSM_SERR BIT(13) +#define PCIX_INT_REG_SRT_FSM_SERR BIT(14) +#define PCIX_INT_REG_PIFR_FSM_SERR BIT(15) +#define PCIX_INT_REG_WRC_TX_SEND_FSM_SERR BIT(21) +#define PCIX_INT_REG_RRC_TX_REQ_FSM_SERR BIT(23) +#define PCIX_INT_REG_INI_RX_FSM_SERR BIT(48) +#define PCIX_INT_REG_RA_RX_FSM_SERR BIT(50) /* -#define PCIX_INT_REG_WRC_RX_SEND_FSM_SERR s2BIT(52) -#define PCIX_INT_REG_RRC_RX_REQ_FSM_SERR s2BIT(54) -#define PCIX_INT_REG_RRC_RX_SPLIT_FSM_SERR s2BIT(58) +#define PCIX_INT_REG_WRC_RX_SEND_FSM_SERR BIT(52) +#define PCIX_INT_REG_RRC_RX_REQ_FSM_SERR BIT(54) +#define PCIX_INT_REG_RRC_RX_SPLIT_FSM_SERR BIT(58) */ u64 txpic_alarms; u64 rxpic_int_reg; @@ -144,92 +144,92 @@ struct XENA_dev_config { u64 flsh_int_reg; u64 flsh_int_mask; -#define PIC_FLSH_INT_REG_CYCLE_FSM_ERR s2BIT(63) -#define PIC_FLSH_INT_REG_ERR s2BIT(62) +#define PIC_FLSH_INT_REG_CYCLE_FSM_ERR BIT(63) +#define PIC_FLSH_INT_REG_ERR BIT(62) u64 flash_alarms; u64 mdio_int_reg; u64 mdio_int_mask; -#define MDIO_INT_REG_MDIO_BUS_ERR s2BIT(0) -#define MDIO_INT_REG_DTX_BUS_ERR s2BIT(8) -#define MDIO_INT_REG_LASI s2BIT(39) +#define MDIO_INT_REG_MDIO_BUS_ERR BIT(0) +#define MDIO_INT_REG_DTX_BUS_ERR BIT(8) +#define MDIO_INT_REG_LASI BIT(39) u64 mdio_alarms; u64 iic_int_reg; u64 iic_int_mask; -#define IIC_INT_REG_BUS_FSM_ERR s2BIT(4) -#define IIC_INT_REG_BIT_FSM_ERR s2BIT(5) -#define IIC_INT_REG_CYCLE_FSM_ERR s2BIT(6) -#define IIC_INT_REG_REQ_FSM_ERR s2BIT(7) -#define IIC_INT_REG_ACK_ERR s2BIT(8) +#define IIC_INT_REG_BUS_FSM_ERR BIT(4) +#define IIC_INT_REG_BIT_FSM_ERR BIT(5) +#define IIC_INT_REG_CYCLE_FSM_ERR BIT(6) +#define IIC_INT_REG_REQ_FSM_ERR BIT(7) +#define IIC_INT_REG_ACK_ERR BIT(8) u64 iic_alarms; u8 unused4[0x08]; u64 gpio_int_reg; -#define GPIO_INT_REG_DP_ERR_INT s2BIT(0) -#define GPIO_INT_REG_LINK_DOWN s2BIT(1) -#define GPIO_INT_REG_LINK_UP s2BIT(2) +#define GPIO_INT_REG_DP_ERR_INT BIT(0) +#define GPIO_INT_REG_LINK_DOWN BIT(1) +#define GPIO_INT_REG_LINK_UP BIT(2) u64 gpio_int_mask; -#define GPIO_INT_MASK_LINK_DOWN s2BIT(1) -#define GPIO_INT_MASK_LINK_UP s2BIT(2) +#define GPIO_INT_MASK_LINK_DOWN BIT(1) +#define GPIO_INT_MASK_LINK_UP BIT(2) u64 gpio_alarms; u8 unused5[0x38]; u64 tx_traffic_int; -#define TX_TRAFFIC_INT_n(n) s2BIT(n) +#define TX_TRAFFIC_INT_n(n) BIT(n) u64 tx_traffic_mask; u64 rx_traffic_int; -#define RX_TRAFFIC_INT_n(n) s2BIT(n) +#define RX_TRAFFIC_INT_n(n) BIT(n) u64 rx_traffic_mask; /* PIC Control registers */ u64 pic_control; -#define PIC_CNTL_RX_ALARM_MAP_1 s2BIT(0) +#define PIC_CNTL_RX_ALARM_MAP_1 BIT(0) #define PIC_CNTL_SHARED_SPLITS(n) vBIT(n,11,5) u64 swapper_ctrl; -#define SWAPPER_CTRL_PIF_R_FE s2BIT(0) -#define SWAPPER_CTRL_PIF_R_SE s2BIT(1) -#define SWAPPER_CTRL_PIF_W_FE s2BIT(8) -#define SWAPPER_CTRL_PIF_W_SE s2BIT(9) -#define SWAPPER_CTRL_TXP_FE s2BIT(16) -#define SWAPPER_CTRL_TXP_SE s2BIT(17) -#define SWAPPER_CTRL_TXD_R_FE s2BIT(18) -#define SWAPPER_CTRL_TXD_R_SE s2BIT(19) -#define SWAPPER_CTRL_TXD_W_FE s2BIT(20) -#define SWAPPER_CTRL_TXD_W_SE s2BIT(21) -#define SWAPPER_CTRL_TXF_R_FE s2BIT(22) -#define SWAPPER_CTRL_TXF_R_SE s2BIT(23) -#define SWAPPER_CTRL_RXD_R_FE s2BIT(32) -#define SWAPPER_CTRL_RXD_R_SE s2BIT(33) -#define SWAPPER_CTRL_RXD_W_FE s2BIT(34) -#define SWAPPER_CTRL_RXD_W_SE s2BIT(35) -#define SWAPPER_CTRL_RXF_W_FE s2BIT(36) -#define SWAPPER_CTRL_RXF_W_SE s2BIT(37) -#define SWAPPER_CTRL_XMSI_FE s2BIT(40) -#define SWAPPER_CTRL_XMSI_SE s2BIT(41) -#define SWAPPER_CTRL_STATS_FE s2BIT(48) -#define SWAPPER_CTRL_STATS_SE s2BIT(49) +#define SWAPPER_CTRL_PIF_R_FE BIT(0) +#define SWAPPER_CTRL_PIF_R_SE BIT(1) +#define SWAPPER_CTRL_PIF_W_FE BIT(8) +#define SWAPPER_CTRL_PIF_W_SE BIT(9) +#define SWAPPER_CTRL_TXP_FE BIT(16) +#define SWAPPER_CTRL_TXP_SE BIT(17) +#define SWAPPER_CTRL_TXD_R_FE BIT(18) +#define SWAPPER_CTRL_TXD_R_SE BIT(19) +#define SWAPPER_CTRL_TXD_W_FE BIT(20) +#define SWAPPER_CTRL_TXD_W_SE BIT(21) +#define SWAPPER_CTRL_TXF_R_FE BIT(22) +#define SWAPPER_CTRL_TXF_R_SE BIT(23) +#define SWAPPER_CTRL_RXD_R_FE BIT(32) +#define SWAPPER_CTRL_RXD_R_SE BIT(33) +#define SWAPPER_CTRL_RXD_W_FE BIT(34) +#define SWAPPER_CTRL_RXD_W_SE BIT(35) +#define SWAPPER_CTRL_RXF_W_FE BIT(36) +#define SWAPPER_CTRL_RXF_W_SE BIT(37) +#define SWAPPER_CTRL_XMSI_FE BIT(40) +#define SWAPPER_CTRL_XMSI_SE BIT(41) +#define SWAPPER_CTRL_STATS_FE BIT(48) +#define SWAPPER_CTRL_STATS_SE BIT(49) u64 pif_rd_swapper_fb; #define IF_RD_SWAPPER_FB 0x0123456789ABCDEF u64 scheduled_int_ctrl; -#define SCHED_INT_CTRL_TIMER_EN s2BIT(0) -#define SCHED_INT_CTRL_ONE_SHOT s2BIT(1) +#define SCHED_INT_CTRL_TIMER_EN BIT(0) +#define SCHED_INT_CTRL_ONE_SHOT BIT(1) #define SCHED_INT_CTRL_INT2MSI(val) vBIT(val,10,6) #define SCHED_INT_PERIOD TBD u64 txreqtimeout; #define TXREQTO_VAL(val) vBIT(val,0,32) -#define TXREQTO_EN s2BIT(63) +#define TXREQTO_EN BIT(63) u64 statsreqtimeout; #define STATREQTO_VAL(n) TBD -#define STATREQTO_EN s2BIT(63) +#define STATREQTO_EN BIT(63) u64 read_retry_delay; u64 read_retry_acceleration; @@ -255,10 +255,10 @@ struct XENA_dev_config { /* Automated statistics collection */ u64 stat_cfg; -#define STAT_CFG_STAT_EN s2BIT(0) -#define STAT_CFG_ONE_SHOT_EN s2BIT(1) -#define STAT_CFG_STAT_NS_EN s2BIT(8) -#define STAT_CFG_STAT_RO s2BIT(9) +#define STAT_CFG_STAT_EN BIT(0) +#define STAT_CFG_ONE_SHOT_EN BIT(1) +#define STAT_CFG_STAT_NS_EN BIT(8) +#define STAT_CFG_STAT_RO BIT(9) #define STAT_TRSF_PER(n) TBD #define PER_SEC 0x208d5 #define SET_UPDT_PERIOD(n) vBIT((PER_SEC*n),32,32) @@ -290,18 +290,18 @@ struct XENA_dev_config { #define I2C_CONTROL_DEV_ID(id) vBIT(id,1,3) #define I2C_CONTROL_ADDR(addr) vBIT(addr,5,11) #define I2C_CONTROL_BYTE_CNT(cnt) vBIT(cnt,22,2) -#define I2C_CONTROL_READ s2BIT(24) -#define I2C_CONTROL_NACK s2BIT(25) +#define I2C_CONTROL_READ BIT(24) +#define I2C_CONTROL_NACK BIT(25) #define I2C_CONTROL_CNTL_START vBIT(0xE,28,4) #define I2C_CONTROL_CNTL_END(val) (val & vBIT(0x1,28,4)) #define I2C_CONTROL_GET_DATA(val) (u32)(val & 0xFFFFFFFF) #define I2C_CONTROL_SET_DATA(val) vBIT(val,32,32) u64 gpio_control; -#define GPIO_CTRL_GPIO_0 s2BIT(8) +#define GPIO_CTRL_GPIO_0 BIT(8) u64 misc_control; -#define FAULT_BEHAVIOUR s2BIT(0) -#define EXT_REQ_EN s2BIT(1) +#define FAULT_BEHAVIOUR BIT(0) +#define EXT_REQ_EN BIT(1) #define MISC_LINK_STABILITY_PRD(val) vBIT(val,29,3) u8 unused7_1[0x230 - 0x208]; @@ -317,29 +317,29 @@ struct XENA_dev_config { /* TxDMA registers */ u64 txdma_int_status; u64 txdma_int_mask; -#define TXDMA_PFC_INT s2BIT(0) -#define TXDMA_TDA_INT s2BIT(1) -#define TXDMA_PCC_INT s2BIT(2) -#define TXDMA_TTI_INT s2BIT(3) -#define TXDMA_LSO_INT s2BIT(4) -#define TXDMA_TPA_INT s2BIT(5) -#define TXDMA_SM_INT s2BIT(6) +#define TXDMA_PFC_INT BIT(0) +#define TXDMA_TDA_INT BIT(1) +#define TXDMA_PCC_INT BIT(2) +#define TXDMA_TTI_INT BIT(3) +#define TXDMA_LSO_INT BIT(4) +#define TXDMA_TPA_INT BIT(5) +#define TXDMA_SM_INT BIT(6) u64 pfc_err_reg; -#define PFC_ECC_SG_ERR s2BIT(7) -#define PFC_ECC_DB_ERR s2BIT(15) -#define PFC_SM_ERR_ALARM s2BIT(23) -#define PFC_MISC_0_ERR s2BIT(31) -#define PFC_MISC_1_ERR s2BIT(32) -#define PFC_PCIX_ERR s2BIT(39) +#define PFC_ECC_SG_ERR BIT(7) +#define PFC_ECC_DB_ERR BIT(15) +#define PFC_SM_ERR_ALARM BIT(23) +#define PFC_MISC_0_ERR BIT(31) +#define PFC_MISC_1_ERR BIT(32) +#define PFC_PCIX_ERR BIT(39) u64 pfc_err_mask; u64 pfc_err_alarm; u64 tda_err_reg; #define TDA_Fn_ECC_SG_ERR vBIT(0xff,0,8) #define TDA_Fn_ECC_DB_ERR vBIT(0xff,8,8) -#define TDA_SM0_ERR_ALARM s2BIT(22) -#define TDA_SM1_ERR_ALARM s2BIT(23) -#define TDA_PCIX_ERR s2BIT(39) +#define TDA_SM0_ERR_ALARM BIT(22) +#define TDA_SM1_ERR_ALARM BIT(23) +#define TDA_PCIX_ERR BIT(39) u64 tda_err_mask; u64 tda_err_alarm; @@ -351,40 +351,40 @@ struct XENA_dev_config { #define PCC_SM_ERR_ALARM vBIT(0xff,32,8) #define PCC_WR_ERR_ALARM vBIT(0xff,40,8) #define PCC_N_SERR vBIT(0xff,48,8) -#define PCC_6_COF_OV_ERR s2BIT(56) -#define PCC_7_COF_OV_ERR s2BIT(57) -#define PCC_6_LSO_OV_ERR s2BIT(58) -#define PCC_7_LSO_OV_ERR s2BIT(59) +#define PCC_6_COF_OV_ERR BIT(56) +#define PCC_7_COF_OV_ERR BIT(57) +#define PCC_6_LSO_OV_ERR BIT(58) +#define PCC_7_LSO_OV_ERR BIT(59) #define PCC_ENABLE_FOUR vBIT(0x0F,0,8) u64 pcc_err_mask; u64 pcc_err_alarm; u64 tti_err_reg; -#define TTI_ECC_SG_ERR s2BIT(7) -#define TTI_ECC_DB_ERR s2BIT(15) -#define TTI_SM_ERR_ALARM s2BIT(23) +#define TTI_ECC_SG_ERR BIT(7) +#define TTI_ECC_DB_ERR BIT(15) +#define TTI_SM_ERR_ALARM BIT(23) u64 tti_err_mask; u64 tti_err_alarm; u64 lso_err_reg; -#define LSO6_SEND_OFLOW s2BIT(12) -#define LSO7_SEND_OFLOW s2BIT(13) -#define LSO6_ABORT s2BIT(14) -#define LSO7_ABORT s2BIT(15) -#define LSO6_SM_ERR_ALARM s2BIT(22) -#define LSO7_SM_ERR_ALARM s2BIT(23) +#define LSO6_SEND_OFLOW BIT(12) +#define LSO7_SEND_OFLOW BIT(13) +#define LSO6_ABORT BIT(14) +#define LSO7_ABORT BIT(15) +#define LSO6_SM_ERR_ALARM BIT(22) +#define LSO7_SM_ERR_ALARM BIT(23) u64 lso_err_mask; u64 lso_err_alarm; u64 tpa_err_reg; -#define TPA_TX_FRM_DROP s2BIT(7) -#define TPA_SM_ERR_ALARM s2BIT(23) +#define TPA_TX_FRM_DROP BIT(7) +#define TPA_SM_ERR_ALARM BIT(23) u64 tpa_err_mask; u64 tpa_err_alarm; u64 sm_err_reg; -#define SM_SM_ERR_ALARM s2BIT(15) +#define SM_SM_ERR_ALARM BIT(15) u64 sm_err_mask; u64 sm_err_alarm; @@ -397,7 +397,7 @@ struct XENA_dev_config { #define X_MAX_FIFOS 8 #define X_FIFO_MAX_LEN 0x1FFF /*8191 */ u64 tx_fifo_partition_0; -#define TX_FIFO_PARTITION_EN s2BIT(0) +#define TX_FIFO_PARTITION_EN BIT(0) #define TX_FIFO_PARTITION_0_PRI(val) vBIT(val,5,3) #define TX_FIFO_PARTITION_0_LEN(val) vBIT(val,19,13) #define TX_FIFO_PARTITION_1_PRI(val) vBIT(val,37,3) @@ -437,16 +437,16 @@ struct XENA_dev_config { u64 tx_w_round_robin_4; u64 tti_command_mem; -#define TTI_CMD_MEM_WE s2BIT(7) -#define TTI_CMD_MEM_STROBE_NEW_CMD s2BIT(15) -#define TTI_CMD_MEM_STROBE_BEING_EXECUTED s2BIT(15) +#define TTI_CMD_MEM_WE BIT(7) +#define TTI_CMD_MEM_STROBE_NEW_CMD BIT(15) +#define TTI_CMD_MEM_STROBE_BEING_EXECUTED BIT(15) #define TTI_CMD_MEM_OFFSET(n) vBIT(n,26,6) u64 tti_data1_mem; #define TTI_DATA1_MEM_TX_TIMER_VAL(n) vBIT(n,6,26) #define TTI_DATA1_MEM_TX_TIMER_AC_CI(n) vBIT(n,38,2) -#define TTI_DATA1_MEM_TX_TIMER_AC_EN s2BIT(38) -#define TTI_DATA1_MEM_TX_TIMER_CI_EN s2BIT(39) +#define TTI_DATA1_MEM_TX_TIMER_AC_EN BIT(38) +#define TTI_DATA1_MEM_TX_TIMER_CI_EN BIT(39) #define TTI_DATA1_MEM_TX_URNG_A(n) vBIT(n,41,7) #define TTI_DATA1_MEM_TX_URNG_B(n) vBIT(n,49,7) #define TTI_DATA1_MEM_TX_URNG_C(n) vBIT(n,57,7) @@ -459,11 +459,11 @@ struct XENA_dev_config { /* Tx Protocol assist */ u64 tx_pa_cfg; -#define TX_PA_CFG_IGNORE_FRM_ERR s2BIT(1) -#define TX_PA_CFG_IGNORE_SNAP_OUI s2BIT(2) -#define TX_PA_CFG_IGNORE_LLC_CTRL s2BIT(3) -#define TX_PA_CFG_IGNORE_L2_ERR s2BIT(6) -#define RX_PA_CFG_STRIP_VLAN_TAG s2BIT(15) +#define TX_PA_CFG_IGNORE_FRM_ERR BIT(1) +#define TX_PA_CFG_IGNORE_SNAP_OUI BIT(2) +#define TX_PA_CFG_IGNORE_LLC_CTRL BIT(3) +#define TX_PA_CFG_IGNORE_L2_ERR BIT(6) +#define RX_PA_CFG_STRIP_VLAN_TAG BIT(15) /* Recent add, used only debug purposes. */ u64 pcc_enable; @@ -477,31 +477,31 @@ struct XENA_dev_config { /* RxDMA Registers */ u64 rxdma_int_status; u64 rxdma_int_mask; -#define RXDMA_INT_RC_INT_M s2BIT(0) -#define RXDMA_INT_RPA_INT_M s2BIT(1) -#define RXDMA_INT_RDA_INT_M s2BIT(2) -#define RXDMA_INT_RTI_INT_M s2BIT(3) +#define RXDMA_INT_RC_INT_M BIT(0) +#define RXDMA_INT_RPA_INT_M BIT(1) +#define RXDMA_INT_RDA_INT_M BIT(2) +#define RXDMA_INT_RTI_INT_M BIT(3) u64 rda_err_reg; #define RDA_RXDn_ECC_SG_ERR vBIT(0xFF,0,8) #define RDA_RXDn_ECC_DB_ERR vBIT(0xFF,8,8) -#define RDA_FRM_ECC_SG_ERR s2BIT(23) -#define RDA_FRM_ECC_DB_N_AERR s2BIT(31) -#define RDA_SM1_ERR_ALARM s2BIT(38) -#define RDA_SM0_ERR_ALARM s2BIT(39) -#define RDA_MISC_ERR s2BIT(47) -#define RDA_PCIX_ERR s2BIT(55) -#define RDA_RXD_ECC_DB_SERR s2BIT(63) +#define RDA_FRM_ECC_SG_ERR BIT(23) +#define RDA_FRM_ECC_DB_N_AERR BIT(31) +#define RDA_SM1_ERR_ALARM BIT(38) +#define RDA_SM0_ERR_ALARM BIT(39) +#define RDA_MISC_ERR BIT(47) +#define RDA_PCIX_ERR BIT(55) +#define RDA_RXD_ECC_DB_SERR BIT(63) u64 rda_err_mask; u64 rda_err_alarm; u64 rc_err_reg; #define RC_PRCn_ECC_SG_ERR vBIT(0xFF,0,8) #define RC_PRCn_ECC_DB_ERR vBIT(0xFF,8,8) -#define RC_FTC_ECC_SG_ERR s2BIT(23) -#define RC_FTC_ECC_DB_ERR s2BIT(31) +#define RC_FTC_ECC_SG_ERR BIT(23) +#define RC_FTC_ECC_DB_ERR BIT(31) #define RC_PRCn_SM_ERR_ALARM vBIT(0xFF,32,8) -#define RC_FTC_SM_ERR_ALARM s2BIT(47) +#define RC_FTC_SM_ERR_ALARM BIT(47) #define RC_RDA_FAIL_WR_Rn vBIT(0xFF,48,8) u64 rc_err_mask; u64 rc_err_alarm; @@ -517,18 +517,18 @@ struct XENA_dev_config { u64 prc_pcix_err_alarm; u64 rpa_err_reg; -#define RPA_ECC_SG_ERR s2BIT(7) -#define RPA_ECC_DB_ERR s2BIT(15) -#define RPA_FLUSH_REQUEST s2BIT(22) -#define RPA_SM_ERR_ALARM s2BIT(23) -#define RPA_CREDIT_ERR s2BIT(31) +#define RPA_ECC_SG_ERR BIT(7) +#define RPA_ECC_DB_ERR BIT(15) +#define RPA_FLUSH_REQUEST BIT(22) +#define RPA_SM_ERR_ALARM BIT(23) +#define RPA_CREDIT_ERR BIT(31) u64 rpa_err_mask; u64 rpa_err_alarm; u64 rti_err_reg; -#define RTI_ECC_SG_ERR s2BIT(7) -#define RTI_ECC_DB_ERR s2BIT(15) -#define RTI_SM_ERR_ALARM s2BIT(23) +#define RTI_ECC_SG_ERR BIT(7) +#define RTI_ECC_DB_ERR BIT(15) +#define RTI_SM_ERR_ALARM BIT(23) u64 rti_err_mask; u64 rti_err_alarm; @@ -568,49 +568,49 @@ struct XENA_dev_config { #endif u64 prc_rxd0_n[RX_MAX_RINGS]; u64 prc_ctrl_n[RX_MAX_RINGS]; -#define PRC_CTRL_RC_ENABLED s2BIT(7) -#define PRC_CTRL_RING_MODE (s2BIT(14)|s2BIT(15)) +#define PRC_CTRL_RC_ENABLED BIT(7) +#define PRC_CTRL_RING_MODE (BIT(14)|BIT(15)) #define PRC_CTRL_RING_MODE_1 vBIT(0,14,2) #define PRC_CTRL_RING_MODE_3 vBIT(1,14,2) #define PRC_CTRL_RING_MODE_5 vBIT(2,14,2) #define PRC_CTRL_RING_MODE_x vBIT(3,14,2) -#define PRC_CTRL_NO_SNOOP (s2BIT(22)|s2BIT(23)) -#define PRC_CTRL_NO_SNOOP_DESC s2BIT(22) -#define PRC_CTRL_NO_SNOOP_BUFF s2BIT(23) -#define PRC_CTRL_BIMODAL_INTERRUPT s2BIT(37) -#define PRC_CTRL_GROUP_READS s2BIT(38) +#define PRC_CTRL_NO_SNOOP (BIT(22)|BIT(23)) +#define PRC_CTRL_NO_SNOOP_DESC BIT(22) +#define PRC_CTRL_NO_SNOOP_BUFF BIT(23) +#define PRC_CTRL_BIMODAL_INTERRUPT BIT(37) +#define PRC_CTRL_GROUP_READS BIT(38) #define PRC_CTRL_RXD_BACKOFF_INTERVAL(val) vBIT(val,40,24) u64 prc_alarm_action; -#define PRC_ALARM_ACTION_RR_R0_STOP s2BIT(3) -#define PRC_ALARM_ACTION_RW_R0_STOP s2BIT(7) -#define PRC_ALARM_ACTION_RR_R1_STOP s2BIT(11) -#define PRC_ALARM_ACTION_RW_R1_STOP s2BIT(15) -#define PRC_ALARM_ACTION_RR_R2_STOP s2BIT(19) -#define PRC_ALARM_ACTION_RW_R2_STOP s2BIT(23) -#define PRC_ALARM_ACTION_RR_R3_STOP s2BIT(27) -#define PRC_ALARM_ACTION_RW_R3_STOP s2BIT(31) -#define PRC_ALARM_ACTION_RR_R4_STOP s2BIT(35) -#define PRC_ALARM_ACTION_RW_R4_STOP s2BIT(39) -#define PRC_ALARM_ACTION_RR_R5_STOP s2BIT(43) -#define PRC_ALARM_ACTION_RW_R5_STOP s2BIT(47) -#define PRC_ALARM_ACTION_RR_R6_STOP s2BIT(51) -#define PRC_ALARM_ACTION_RW_R6_STOP s2BIT(55) -#define PRC_ALARM_ACTION_RR_R7_STOP s2BIT(59) -#define PRC_ALARM_ACTION_RW_R7_STOP s2BIT(63) +#define PRC_ALARM_ACTION_RR_R0_STOP BIT(3) +#define PRC_ALARM_ACTION_RW_R0_STOP BIT(7) +#define PRC_ALARM_ACTION_RR_R1_STOP BIT(11) +#define PRC_ALARM_ACTION_RW_R1_STOP BIT(15) +#define PRC_ALARM_ACTION_RR_R2_STOP BIT(19) +#define PRC_ALARM_ACTION_RW_R2_STOP BIT(23) +#define PRC_ALARM_ACTION_RR_R3_STOP BIT(27) +#define PRC_ALARM_ACTION_RW_R3_STOP BIT(31) +#define PRC_ALARM_ACTION_RR_R4_STOP BIT(35) +#define PRC_ALARM_ACTION_RW_R4_STOP BIT(39) +#define PRC_ALARM_ACTION_RR_R5_STOP BIT(43) +#define PRC_ALARM_ACTION_RW_R5_STOP BIT(47) +#define PRC_ALARM_ACTION_RR_R6_STOP BIT(51) +#define PRC_ALARM_ACTION_RW_R6_STOP BIT(55) +#define PRC_ALARM_ACTION_RR_R7_STOP BIT(59) +#define PRC_ALARM_ACTION_RW_R7_STOP BIT(63) /* Receive traffic interrupts */ u64 rti_command_mem; -#define RTI_CMD_MEM_WE s2BIT(7) -#define RTI_CMD_MEM_STROBE s2BIT(15) -#define RTI_CMD_MEM_STROBE_NEW_CMD s2BIT(15) -#define RTI_CMD_MEM_STROBE_CMD_BEING_EXECUTED s2BIT(15) +#define RTI_CMD_MEM_WE BIT(7) +#define RTI_CMD_MEM_STROBE BIT(15) +#define RTI_CMD_MEM_STROBE_NEW_CMD BIT(15) +#define RTI_CMD_MEM_STROBE_CMD_BEING_EXECUTED BIT(15) #define RTI_CMD_MEM_OFFSET(n) vBIT(n,29,3) u64 rti_data1_mem; #define RTI_DATA1_MEM_RX_TIMER_VAL(n) vBIT(n,3,29) -#define RTI_DATA1_MEM_RX_TIMER_AC_EN s2BIT(38) -#define RTI_DATA1_MEM_RX_TIMER_CI_EN s2BIT(39) +#define RTI_DATA1_MEM_RX_TIMER_AC_EN BIT(38) +#define RTI_DATA1_MEM_RX_TIMER_CI_EN BIT(39) #define RTI_DATA1_MEM_RX_URNG_A(n) vBIT(n,41,7) #define RTI_DATA1_MEM_RX_URNG_B(n) vBIT(n,49,7) #define RTI_DATA1_MEM_RX_URNG_C(n) vBIT(n,57,7) @@ -622,10 +622,10 @@ struct XENA_dev_config { #define RTI_DATA2_MEM_RX_UFC_D(n) vBIT(n,48,16) u64 rx_pa_cfg; -#define RX_PA_CFG_IGNORE_FRM_ERR s2BIT(1) -#define RX_PA_CFG_IGNORE_SNAP_OUI s2BIT(2) -#define RX_PA_CFG_IGNORE_LLC_CTRL s2BIT(3) -#define RX_PA_CFG_IGNORE_L2_ERR s2BIT(6) +#define RX_PA_CFG_IGNORE_FRM_ERR BIT(1) +#define RX_PA_CFG_IGNORE_SNAP_OUI BIT(2) +#define RX_PA_CFG_IGNORE_LLC_CTRL BIT(3) +#define RX_PA_CFG_IGNORE_L2_ERR BIT(6) u64 unused_11_1; @@ -641,64 +641,64 @@ struct XENA_dev_config { /* Media Access Controller Register */ u64 mac_int_status; u64 mac_int_mask; -#define MAC_INT_STATUS_TMAC_INT s2BIT(0) -#define MAC_INT_STATUS_RMAC_INT s2BIT(1) +#define MAC_INT_STATUS_TMAC_INT BIT(0) +#define MAC_INT_STATUS_RMAC_INT BIT(1) u64 mac_tmac_err_reg; -#define TMAC_ECC_SG_ERR s2BIT(7) -#define TMAC_ECC_DB_ERR s2BIT(15) -#define TMAC_TX_BUF_OVRN s2BIT(23) -#define TMAC_TX_CRI_ERR s2BIT(31) -#define TMAC_TX_SM_ERR s2BIT(39) -#define TMAC_DESC_ECC_SG_ERR s2BIT(47) -#define TMAC_DESC_ECC_DB_ERR s2BIT(55) +#define TMAC_ECC_SG_ERR BIT(7) +#define TMAC_ECC_DB_ERR BIT(15) +#define TMAC_TX_BUF_OVRN BIT(23) +#define TMAC_TX_CRI_ERR BIT(31) +#define TMAC_TX_SM_ERR BIT(39) +#define TMAC_DESC_ECC_SG_ERR BIT(47) +#define TMAC_DESC_ECC_DB_ERR BIT(55) u64 mac_tmac_err_mask; u64 mac_tmac_err_alarm; u64 mac_rmac_err_reg; -#define RMAC_RX_BUFF_OVRN s2BIT(0) -#define RMAC_FRM_RCVD_INT s2BIT(1) -#define RMAC_UNUSED_INT s2BIT(2) -#define RMAC_RTS_PNUM_ECC_SG_ERR s2BIT(5) -#define RMAC_RTS_DS_ECC_SG_ERR s2BIT(6) -#define RMAC_RD_BUF_ECC_SG_ERR s2BIT(7) -#define RMAC_RTH_MAP_ECC_SG_ERR s2BIT(8) -#define RMAC_RTH_SPDM_ECC_SG_ERR s2BIT(9) -#define RMAC_RTS_VID_ECC_SG_ERR s2BIT(10) -#define RMAC_DA_SHADOW_ECC_SG_ERR s2BIT(11) -#define RMAC_RTS_PNUM_ECC_DB_ERR s2BIT(13) -#define RMAC_RTS_DS_ECC_DB_ERR s2BIT(14) -#define RMAC_RD_BUF_ECC_DB_ERR s2BIT(15) -#define RMAC_RTH_MAP_ECC_DB_ERR s2BIT(16) -#define RMAC_RTH_SPDM_ECC_DB_ERR s2BIT(17) -#define RMAC_RTS_VID_ECC_DB_ERR s2BIT(18) -#define RMAC_DA_SHADOW_ECC_DB_ERR s2BIT(19) -#define RMAC_LINK_STATE_CHANGE_INT s2BIT(31) -#define RMAC_RX_SM_ERR s2BIT(39) -#define RMAC_SINGLE_ECC_ERR (s2BIT(5) | s2BIT(6) | s2BIT(7) |\ - s2BIT(8) | s2BIT(9) | s2BIT(10)|\ - s2BIT(11)) -#define RMAC_DOUBLE_ECC_ERR (s2BIT(13) | s2BIT(14) | s2BIT(15) |\ - s2BIT(16) | s2BIT(17) | s2BIT(18)|\ - s2BIT(19)) +#define RMAC_RX_BUFF_OVRN BIT(0) +#define RMAC_FRM_RCVD_INT BIT(1) +#define RMAC_UNUSED_INT BIT(2) +#define RMAC_RTS_PNUM_ECC_SG_ERR BIT(5) +#define RMAC_RTS_DS_ECC_SG_ERR BIT(6) +#define RMAC_RD_BUF_ECC_SG_ERR BIT(7) +#define RMAC_RTH_MAP_ECC_SG_ERR BIT(8) +#define RMAC_RTH_SPDM_ECC_SG_ERR BIT(9) +#define RMAC_RTS_VID_ECC_SG_ERR BIT(10) +#define RMAC_DA_SHADOW_ECC_SG_ERR BIT(11) +#define RMAC_RTS_PNUM_ECC_DB_ERR BIT(13) +#define RMAC_RTS_DS_ECC_DB_ERR BIT(14) +#define RMAC_RD_BUF_ECC_DB_ERR BIT(15) +#define RMAC_RTH_MAP_ECC_DB_ERR BIT(16) +#define RMAC_RTH_SPDM_ECC_DB_ERR BIT(17) +#define RMAC_RTS_VID_ECC_DB_ERR BIT(18) +#define RMAC_DA_SHADOW_ECC_DB_ERR BIT(19) +#define RMAC_LINK_STATE_CHANGE_INT BIT(31) +#define RMAC_RX_SM_ERR BIT(39) +#define RMAC_SINGLE_ECC_ERR (BIT(5) | BIT(6) | BIT(7) |\ + BIT(8) | BIT(9) | BIT(10)|\ + BIT(11)) +#define RMAC_DOUBLE_ECC_ERR (BIT(13) | BIT(14) | BIT(15) |\ + BIT(16) | BIT(17) | BIT(18)|\ + BIT(19)) u64 mac_rmac_err_mask; u64 mac_rmac_err_alarm; u8 unused14[0x100 - 0x40]; u64 mac_cfg; -#define MAC_CFG_TMAC_ENABLE s2BIT(0) -#define MAC_CFG_RMAC_ENABLE s2BIT(1) -#define MAC_CFG_LAN_NOT_WAN s2BIT(2) -#define MAC_CFG_TMAC_LOOPBACK s2BIT(3) -#define MAC_CFG_TMAC_APPEND_PAD s2BIT(4) -#define MAC_CFG_RMAC_STRIP_FCS s2BIT(5) -#define MAC_CFG_RMAC_STRIP_PAD s2BIT(6) -#define MAC_CFG_RMAC_PROM_ENABLE s2BIT(7) -#define MAC_RMAC_DISCARD_PFRM s2BIT(8) -#define MAC_RMAC_BCAST_ENABLE s2BIT(9) -#define MAC_RMAC_ALL_ADDR_ENABLE s2BIT(10) +#define MAC_CFG_TMAC_ENABLE BIT(0) +#define MAC_CFG_RMAC_ENABLE BIT(1) +#define MAC_CFG_LAN_NOT_WAN BIT(2) +#define MAC_CFG_TMAC_LOOPBACK BIT(3) +#define MAC_CFG_TMAC_APPEND_PAD BIT(4) +#define MAC_CFG_RMAC_STRIP_FCS BIT(5) +#define MAC_CFG_RMAC_STRIP_PAD BIT(6) +#define MAC_CFG_RMAC_PROM_ENABLE BIT(7) +#define MAC_RMAC_DISCARD_PFRM BIT(8) +#define MAC_RMAC_BCAST_ENABLE BIT(9) +#define MAC_RMAC_ALL_ADDR_ENABLE BIT(10) #define MAC_RMAC_INVLD_IPG_THR(val) vBIT(val,16,8) u64 tmac_avg_ipg; @@ -710,14 +710,14 @@ struct XENA_dev_config { #define RMAC_MAX_PYLD_LEN_JUMBO_DEF vBIT(9600,2,14) u64 rmac_err_cfg; -#define RMAC_ERR_FCS s2BIT(0) -#define RMAC_ERR_FCS_ACCEPT s2BIT(1) -#define RMAC_ERR_TOO_LONG s2BIT(1) -#define RMAC_ERR_TOO_LONG_ACCEPT s2BIT(1) -#define RMAC_ERR_RUNT s2BIT(2) -#define RMAC_ERR_RUNT_ACCEPT s2BIT(2) -#define RMAC_ERR_LEN_MISMATCH s2BIT(3) -#define RMAC_ERR_LEN_MISMATCH_ACCEPT s2BIT(3) +#define RMAC_ERR_FCS BIT(0) +#define RMAC_ERR_FCS_ACCEPT BIT(1) +#define RMAC_ERR_TOO_LONG BIT(1) +#define RMAC_ERR_TOO_LONG_ACCEPT BIT(1) +#define RMAC_ERR_RUNT BIT(2) +#define RMAC_ERR_RUNT_ACCEPT BIT(2) +#define RMAC_ERR_LEN_MISMATCH BIT(3) +#define RMAC_ERR_LEN_MISMATCH_ACCEPT BIT(3) u64 rmac_cfg_key; #define RMAC_CFG_KEY(val) vBIT(val,0,16) @@ -728,15 +728,15 @@ struct XENA_dev_config { #define MAC_MC_ADDR_START_OFFSET 16 #define MAC_MC_ALL_MC_ADDR_OFFSET 63 /* enables all multicast pkts */ u64 rmac_addr_cmd_mem; -#define RMAC_ADDR_CMD_MEM_WE s2BIT(7) +#define RMAC_ADDR_CMD_MEM_WE BIT(7) #define RMAC_ADDR_CMD_MEM_RD 0 -#define RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD s2BIT(15) -#define RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING s2BIT(15) +#define RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD BIT(15) +#define RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING BIT(15) #define RMAC_ADDR_CMD_MEM_OFFSET(n) vBIT(n,26,6) u64 rmac_addr_data0_mem; #define RMAC_ADDR_DATA0_MEM_ADDR(n) vBIT(n,0,48) -#define RMAC_ADDR_DATA0_MEM_USER s2BIT(48) +#define RMAC_ADDR_DATA0_MEM_USER BIT(48) u64 rmac_addr_data1_mem; #define RMAC_ADDR_DATA1_MEM_MASK(n) vBIT(n,0,48) @@ -753,10 +753,10 @@ struct XENA_dev_config { u64 tmac_ipg_cfg; u64 rmac_pause_cfg; -#define RMAC_PAUSE_GEN s2BIT(0) -#define RMAC_PAUSE_GEN_ENABLE s2BIT(0) -#define RMAC_PAUSE_RX s2BIT(1) -#define RMAC_PAUSE_RX_ENABLE s2BIT(1) +#define RMAC_PAUSE_GEN BIT(0) +#define RMAC_PAUSE_GEN_ENABLE BIT(0) +#define RMAC_PAUSE_RX BIT(1) +#define RMAC_PAUSE_RX_ENABLE BIT(1) #define RMAC_PAUSE_HG_PTIME_DEF vBIT(0xFFFF,16,16) #define RMAC_PAUSE_HG_PTIME(val) vBIT(val,16,16) @@ -787,29 +787,29 @@ struct XENA_dev_config { #define MAX_DIX_MAP 4 u64 rts_dix_map_n[MAX_DIX_MAP]; #define RTS_DIX_MAP_ETYPE(val) vBIT(val,0,16) -#define RTS_DIX_MAP_SCW(val) s2BIT(val,21) +#define RTS_DIX_MAP_SCW(val) BIT(val,21) u64 rts_q_alternates; u64 rts_default_q; u64 rts_ctrl; -#define RTS_CTRL_IGNORE_SNAP_OUI s2BIT(2) -#define RTS_CTRL_IGNORE_LLC_CTRL s2BIT(3) +#define RTS_CTRL_IGNORE_SNAP_OUI BIT(2) +#define RTS_CTRL_IGNORE_LLC_CTRL BIT(3) u64 rts_pn_cam_ctrl; -#define RTS_PN_CAM_CTRL_WE s2BIT(7) -#define RTS_PN_CAM_CTRL_STROBE_NEW_CMD s2BIT(15) -#define RTS_PN_CAM_CTRL_STROBE_BEING_EXECUTED s2BIT(15) +#define RTS_PN_CAM_CTRL_WE BIT(7) +#define RTS_PN_CAM_CTRL_STROBE_NEW_CMD BIT(15) +#define RTS_PN_CAM_CTRL_STROBE_BEING_EXECUTED BIT(15) #define RTS_PN_CAM_CTRL_OFFSET(n) vBIT(n,24,8) u64 rts_pn_cam_data; -#define RTS_PN_CAM_DATA_TCP_SELECT s2BIT(7) +#define RTS_PN_CAM_DATA_TCP_SELECT BIT(7) #define RTS_PN_CAM_DATA_PORT(val) vBIT(val,8,16) #define RTS_PN_CAM_DATA_SCW(val) vBIT(val,24,8) u64 rts_ds_mem_ctrl; -#define RTS_DS_MEM_CTRL_WE s2BIT(7) -#define RTS_DS_MEM_CTRL_STROBE_NEW_CMD s2BIT(15) -#define RTS_DS_MEM_CTRL_STROBE_CMD_BEING_EXECUTED s2BIT(15) +#define RTS_DS_MEM_CTRL_WE BIT(7) +#define RTS_DS_MEM_CTRL_STROBE_NEW_CMD BIT(15) +#define RTS_DS_MEM_CTRL_STROBE_CMD_BEING_EXECUTED BIT(15) #define RTS_DS_MEM_CTRL_OFFSET(n) vBIT(n,26,6) u64 rts_ds_mem_data; #define RTS_DS_MEM_DATA(n) vBIT(n,0,8) @@ -823,23 +823,23 @@ struct XENA_dev_config { /* memory controller registers */ u64 mc_int_status; -#define MC_INT_STATUS_MC_INT s2BIT(0) +#define MC_INT_STATUS_MC_INT BIT(0) u64 mc_int_mask; -#define MC_INT_MASK_MC_INT s2BIT(0) +#define MC_INT_MASK_MC_INT BIT(0) u64 mc_err_reg; -#define MC_ERR_REG_ECC_DB_ERR_L s2BIT(14) -#define MC_ERR_REG_ECC_DB_ERR_U s2BIT(15) -#define MC_ERR_REG_MIRI_ECC_DB_ERR_0 s2BIT(18) -#define MC_ERR_REG_MIRI_ECC_DB_ERR_1 s2BIT(20) -#define MC_ERR_REG_MIRI_CRI_ERR_0 s2BIT(22) -#define MC_ERR_REG_MIRI_CRI_ERR_1 s2BIT(23) -#define MC_ERR_REG_SM_ERR s2BIT(31) -#define MC_ERR_REG_ECC_ALL_SNG (s2BIT(2) | s2BIT(3) | s2BIT(4) | s2BIT(5) |\ - s2BIT(17) | s2BIT(19)) -#define MC_ERR_REG_ECC_ALL_DBL (s2BIT(10) | s2BIT(11) | s2BIT(12) |\ - s2BIT(13) | s2BIT(18) | s2BIT(20)) -#define PLL_LOCK_N s2BIT(39) +#define MC_ERR_REG_ECC_DB_ERR_L BIT(14) +#define MC_ERR_REG_ECC_DB_ERR_U BIT(15) +#define MC_ERR_REG_MIRI_ECC_DB_ERR_0 BIT(18) +#define MC_ERR_REG_MIRI_ECC_DB_ERR_1 BIT(20) +#define MC_ERR_REG_MIRI_CRI_ERR_0 BIT(22) +#define MC_ERR_REG_MIRI_CRI_ERR_1 BIT(23) +#define MC_ERR_REG_SM_ERR BIT(31) +#define MC_ERR_REG_ECC_ALL_SNG (BIT(2) | BIT(3) | BIT(4) | BIT(5) |\ + BIT(17) | BIT(19)) +#define MC_ERR_REG_ECC_ALL_DBL (BIT(10) | BIT(11) | BIT(12) |\ + BIT(13) | BIT(18) | BIT(20)) +#define PLL_LOCK_N BIT(39) u64 mc_err_mask; u64 mc_err_alarm; @@ -857,8 +857,8 @@ struct XENA_dev_config { #define RX_QUEUE_CFG_Q7_SZ(n) vBIT(n,56,8) u64 mc_rldram_mrs; -#define MC_RLDRAM_QUEUE_SIZE_ENABLE s2BIT(39) -#define MC_RLDRAM_MRS_ENABLE s2BIT(47) +#define MC_RLDRAM_QUEUE_SIZE_ENABLE BIT(39) +#define MC_RLDRAM_MRS_ENABLE BIT(47) u64 mc_rldram_interleave; @@ -871,11 +871,11 @@ struct XENA_dev_config { u64 mc_rldram_ref_per; u8 unused20[0x220 - 0x208]; u64 mc_rldram_test_ctrl; -#define MC_RLDRAM_TEST_MODE s2BIT(47) -#define MC_RLDRAM_TEST_WRITE s2BIT(7) -#define MC_RLDRAM_TEST_GO s2BIT(15) -#define MC_RLDRAM_TEST_DONE s2BIT(23) -#define MC_RLDRAM_TEST_PASS s2BIT(31) +#define MC_RLDRAM_TEST_MODE BIT(47) +#define MC_RLDRAM_TEST_WRITE BIT(7) +#define MC_RLDRAM_TEST_GO BIT(15) +#define MC_RLDRAM_TEST_DONE BIT(23) +#define MC_RLDRAM_TEST_PASS BIT(31) u8 unused21[0x240 - 0x228]; u64 mc_rldram_test_add; @@ -888,7 +888,7 @@ struct XENA_dev_config { u8 unused24_1[0x360 - 0x308]; u64 mc_rldram_ctrl; -#define MC_RLDRAM_ENABLE_ODT s2BIT(7) +#define MC_RLDRAM_ENABLE_ODT BIT(7) u8 unused24_2[0x640 - 0x368]; u64 mc_rldram_ref_per_herc; @@ -906,24 +906,24 @@ struct XENA_dev_config { /* XGXS control registers */ u64 xgxs_int_status; -#define XGXS_INT_STATUS_TXGXS s2BIT(0) -#define XGXS_INT_STATUS_RXGXS s2BIT(1) +#define XGXS_INT_STATUS_TXGXS BIT(0) +#define XGXS_INT_STATUS_RXGXS BIT(1) u64 xgxs_int_mask; -#define XGXS_INT_MASK_TXGXS s2BIT(0) -#define XGXS_INT_MASK_RXGXS s2BIT(1) +#define XGXS_INT_MASK_TXGXS BIT(0) +#define XGXS_INT_MASK_RXGXS BIT(1) u64 xgxs_txgxs_err_reg; -#define TXGXS_ECC_SG_ERR s2BIT(7) -#define TXGXS_ECC_DB_ERR s2BIT(15) -#define TXGXS_ESTORE_UFLOW s2BIT(31) -#define TXGXS_TX_SM_ERR s2BIT(39) +#define TXGXS_ECC_SG_ERR BIT(7) +#define TXGXS_ECC_DB_ERR BIT(15) +#define TXGXS_ESTORE_UFLOW BIT(31) +#define TXGXS_TX_SM_ERR BIT(39) u64 xgxs_txgxs_err_mask; u64 xgxs_txgxs_err_alarm; u64 xgxs_rxgxs_err_reg; -#define RXGXS_ESTORE_OFLOW s2BIT(7) -#define RXGXS_RX_SM_ERR s2BIT(39) +#define RXGXS_ESTORE_OFLOW BIT(7) +#define RXGXS_RX_SM_ERR BIT(39) u64 xgxs_rxgxs_err_mask; u64 xgxs_rxgxs_err_alarm; @@ -942,10 +942,10 @@ struct XENA_dev_config { #define SPI_CONTROL_BYTECNT(cnt) vBIT(cnt,29,3) #define SPI_CONTROL_CMD(cmd) vBIT(cmd,32,8) #define SPI_CONTROL_ADDR(addr) vBIT(addr,40,24) -#define SPI_CONTROL_SEL1 s2BIT(4) -#define SPI_CONTROL_REQ s2BIT(7) -#define SPI_CONTROL_NACK s2BIT(5) -#define SPI_CONTROL_DONE s2BIT(6) +#define SPI_CONTROL_SEL1 BIT(4) +#define SPI_CONTROL_REQ BIT(7) +#define SPI_CONTROL_NACK BIT(5) +#define SPI_CONTROL_DONE BIT(6) u64 spi_data; #define SPI_DATA_WRITE(data,len) vBIT(data,0,len) }; diff --git a/trunk/drivers/net/s2io.c b/trunk/drivers/net/s2io.c index b8c0e7b4ca1c..22e4054d4fcb 100644 --- a/trunk/drivers/net/s2io.c +++ b/trunk/drivers/net/s2io.c @@ -1716,7 +1716,7 @@ static int init_nic(struct s2io_nic *nic) MISC_LINK_STABILITY_PRD(3); writeq(val64, &bar0->misc_control); val64 = readq(&bar0->pic_control2); - val64 &= ~(s2BIT(13)|s2BIT(14)|s2BIT(15)); + val64 &= ~(BIT(13)|BIT(14)|BIT(15)); writeq(val64, &bar0->pic_control2); } if (strstr(nic->product_name, "CX4")) { @@ -2427,7 +2427,7 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) } if ((rxdp->Control_1 & RXD_OWN_XENA) && ((nic->rxd_mode == RXD_MODE_3B) && - (rxdp->Control_2 & s2BIT(0)))) { + (rxdp->Control_2 & BIT(0)))) { mac_control->rings[ring_no].rx_curr_put_info. offset = off; goto end; @@ -2540,7 +2540,7 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) rxdp->Control_2 |= SET_BUFFER2_SIZE_3 (dev->mtu + 4); } - rxdp->Control_2 |= s2BIT(0); + rxdp->Control_2 |= BIT(0); } rxdp->Host_Control = (unsigned long) (skb); if (alloc_tab & ((1 << rxsync_frequency) - 1)) @@ -3377,7 +3377,7 @@ static void s2io_reset(struct s2io_nic * sp) pci_write_config_dword(sp->pdev, 0x68, 0x7C); /* Clearing PCI_STATUS error reflected here */ - writeq(s2BIT(62), &bar0->txpic_int_reg); + writeq(BIT(62), &bar0->txpic_int_reg); } /* Reset device statistics maintained by OS */ @@ -3575,7 +3575,7 @@ static int wait_for_msix_trans(struct s2io_nic *nic, int i) do { val64 = readq(&bar0->xmsi_access); - if (!(val64 & s2BIT(15))) + if (!(val64 & BIT(15))) break; mdelay(1); cnt++; @@ -3597,7 +3597,7 @@ static void restore_xmsi_data(struct s2io_nic *nic) for (i=0; i < MAX_REQUESTED_MSI_X; i++) { writeq(nic->msix_info[i].addr, &bar0->xmsi_address); writeq(nic->msix_info[i].data, &bar0->xmsi_data); - val64 = (s2BIT(7) | s2BIT(15) | vBIT(i, 26, 6)); + val64 = (BIT(7) | BIT(15) | vBIT(i, 26, 6)); writeq(val64, &bar0->xmsi_access); if (wait_for_msix_trans(nic, i)) { DBG_PRINT(ERR_DBG, "failed in %s\n", __FUNCTION__); @@ -3614,7 +3614,7 @@ static void store_xmsi_data(struct s2io_nic *nic) /* Store and display */ for (i=0; i < MAX_REQUESTED_MSI_X; i++) { - val64 = (s2BIT(15) | vBIT(i, 26, 6)); + val64 = (BIT(15) | vBIT(i, 26, 6)); writeq(val64, &bar0->xmsi_access); if (wait_for_msix_trans(nic, i)) { DBG_PRINT(ERR_DBG, "failed in %s\n", __FUNCTION__); @@ -4634,7 +4634,7 @@ static void s2io_updt_stats(struct s2io_nic *sp) do { udelay(100); val64 = readq(&bar0->stat_cfg); - if (!(val64 & s2BIT(0))) + if (!(val64 & BIT(0))) break; cnt++; if (cnt == 5) diff --git a/trunk/drivers/net/s2io.h b/trunk/drivers/net/s2io.h index cc1797a071aa..f6b45565304f 100644 --- a/trunk/drivers/net/s2io.h +++ b/trunk/drivers/net/s2io.h @@ -14,7 +14,7 @@ #define _S2IO_H #define TBD 0 -#define s2BIT(loc) (0x8000000000000000ULL >> (loc)) +#define BIT(loc) (0x8000000000000000ULL >> (loc)) #define vBIT(val, loc, sz) (((u64)val) << (64-loc-sz)) #define INV(d) ((d&0xff)<<24) | (((d>>8)&0xff)<<16) | (((d>>16)&0xff)<<8)| ((d>>24)&0xff) @@ -473,42 +473,42 @@ struct TxFIFO_element { u64 List_Control; #define TX_FIFO_LAST_TXD_NUM( val) vBIT(val,0,8) -#define TX_FIFO_FIRST_LIST s2BIT(14) -#define TX_FIFO_LAST_LIST s2BIT(15) +#define TX_FIFO_FIRST_LIST BIT(14) +#define TX_FIFO_LAST_LIST BIT(15) #define TX_FIFO_FIRSTNLAST_LIST vBIT(3,14,2) -#define TX_FIFO_SPECIAL_FUNC s2BIT(23) -#define TX_FIFO_DS_NO_SNOOP s2BIT(31) -#define TX_FIFO_BUFF_NO_SNOOP s2BIT(30) +#define TX_FIFO_SPECIAL_FUNC BIT(23) +#define TX_FIFO_DS_NO_SNOOP BIT(31) +#define TX_FIFO_BUFF_NO_SNOOP BIT(30) }; /* Tx descriptor structure */ struct TxD { u64 Control_1; /* bit mask */ -#define TXD_LIST_OWN_XENA s2BIT(7) -#define TXD_T_CODE (s2BIT(12)|s2BIT(13)|s2BIT(14)|s2BIT(15)) +#define TXD_LIST_OWN_XENA BIT(7) +#define TXD_T_CODE (BIT(12)|BIT(13)|BIT(14)|BIT(15)) #define TXD_T_CODE_OK(val) (|(val & TXD_T_CODE)) #define GET_TXD_T_CODE(val) ((val & TXD_T_CODE)<<12) -#define TXD_GATHER_CODE (s2BIT(22) | s2BIT(23)) -#define TXD_GATHER_CODE_FIRST s2BIT(22) -#define TXD_GATHER_CODE_LAST s2BIT(23) -#define TXD_TCP_LSO_EN s2BIT(30) -#define TXD_UDP_COF_EN s2BIT(31) -#define TXD_UFO_EN s2BIT(31) | s2BIT(30) +#define TXD_GATHER_CODE (BIT(22) | BIT(23)) +#define TXD_GATHER_CODE_FIRST BIT(22) +#define TXD_GATHER_CODE_LAST BIT(23) +#define TXD_TCP_LSO_EN BIT(30) +#define TXD_UDP_COF_EN BIT(31) +#define TXD_UFO_EN BIT(31) | BIT(30) #define TXD_TCP_LSO_MSS(val) vBIT(val,34,14) #define TXD_UFO_MSS(val) vBIT(val,34,14) #define TXD_BUFFER0_SIZE(val) vBIT(val,48,16) u64 Control_2; -#define TXD_TX_CKO_CONTROL (s2BIT(5)|s2BIT(6)|s2BIT(7)) -#define TXD_TX_CKO_IPV4_EN s2BIT(5) -#define TXD_TX_CKO_TCP_EN s2BIT(6) -#define TXD_TX_CKO_UDP_EN s2BIT(7) -#define TXD_VLAN_ENABLE s2BIT(15) +#define TXD_TX_CKO_CONTROL (BIT(5)|BIT(6)|BIT(7)) +#define TXD_TX_CKO_IPV4_EN BIT(5) +#define TXD_TX_CKO_TCP_EN BIT(6) +#define TXD_TX_CKO_UDP_EN BIT(7) +#define TXD_VLAN_ENABLE BIT(15) #define TXD_VLAN_TAG(val) vBIT(val,16,16) #define TXD_INT_NUMBER(val) vBIT(val,34,6) -#define TXD_INT_TYPE_PER_LIST s2BIT(47) -#define TXD_INT_TYPE_UTILZ s2BIT(46) +#define TXD_INT_TYPE_PER_LIST BIT(47) +#define TXD_INT_TYPE_UTILZ BIT(46) #define TXD_SET_MARKER vBIT(0x6,0,4) u64 Buffer_Pointer; @@ -525,14 +525,14 @@ struct list_info_hold { struct RxD_t { u64 Host_Control; /* reserved for host */ u64 Control_1; -#define RXD_OWN_XENA s2BIT(7) -#define RXD_T_CODE (s2BIT(12)|s2BIT(13)|s2BIT(14)|s2BIT(15)) +#define RXD_OWN_XENA BIT(7) +#define RXD_T_CODE (BIT(12)|BIT(13)|BIT(14)|BIT(15)) #define RXD_FRAME_PROTO vBIT(0xFFFF,24,8) -#define RXD_FRAME_PROTO_IPV4 s2BIT(27) -#define RXD_FRAME_PROTO_IPV6 s2BIT(28) -#define RXD_FRAME_IP_FRAG s2BIT(29) -#define RXD_FRAME_PROTO_TCP s2BIT(30) -#define RXD_FRAME_PROTO_UDP s2BIT(31) +#define RXD_FRAME_PROTO_IPV4 BIT(27) +#define RXD_FRAME_PROTO_IPV6 BIT(28) +#define RXD_FRAME_IP_FRAG BIT(29) +#define RXD_FRAME_PROTO_TCP BIT(30) +#define RXD_FRAME_PROTO_UDP BIT(31) #define TCP_OR_UDP_FRAME (RXD_FRAME_PROTO_TCP | RXD_FRAME_PROTO_UDP) #define RXD_GET_L3_CKSUM(val) ((u16)(val>> 16) & 0xFFFF) #define RXD_GET_L4_CKSUM(val) ((u16)(val) & 0xFFFF) @@ -998,26 +998,26 @@ static inline void SPECIAL_REG_WRITE(u64 val, void __iomem *addr, int order) /* Interrupt masks for the general interrupt mask register */ #define DISABLE_ALL_INTRS 0xFFFFFFFFFFFFFFFFULL -#define TXPIC_INT_M s2BIT(0) -#define TXDMA_INT_M s2BIT(1) -#define TXMAC_INT_M s2BIT(2) -#define TXXGXS_INT_M s2BIT(3) -#define TXTRAFFIC_INT_M s2BIT(8) -#define PIC_RX_INT_M s2BIT(32) -#define RXDMA_INT_M s2BIT(33) -#define RXMAC_INT_M s2BIT(34) -#define MC_INT_M s2BIT(35) -#define RXXGXS_INT_M s2BIT(36) -#define RXTRAFFIC_INT_M s2BIT(40) +#define TXPIC_INT_M BIT(0) +#define TXDMA_INT_M BIT(1) +#define TXMAC_INT_M BIT(2) +#define TXXGXS_INT_M BIT(3) +#define TXTRAFFIC_INT_M BIT(8) +#define PIC_RX_INT_M BIT(32) +#define RXDMA_INT_M BIT(33) +#define RXMAC_INT_M BIT(34) +#define MC_INT_M BIT(35) +#define RXXGXS_INT_M BIT(36) +#define RXTRAFFIC_INT_M BIT(40) /* PIC level Interrupts TODO*/ /* DMA level Inressupts */ -#define TXDMA_PFC_INT_M s2BIT(0) -#define TXDMA_PCC_INT_M s2BIT(2) +#define TXDMA_PFC_INT_M BIT(0) +#define TXDMA_PCC_INT_M BIT(2) /* PFC block interrupts */ -#define PFC_MISC_ERR_1 s2BIT(0) /* Interrupt to indicate FIFO full */ +#define PFC_MISC_ERR_1 BIT(0) /* Interrupt to indicate FIFO full */ /* PCC block interrupts. */ #define PCC_FB_ECC_ERR vBIT(0xff, 16, 8) /* Interrupt to indicate diff --git a/trunk/drivers/net/sky2.c b/trunk/drivers/net/sky2.c index 24cfb6275d9b..7967240534d5 100644 --- a/trunk/drivers/net/sky2.c +++ b/trunk/drivers/net/sky2.c @@ -1384,9 +1384,13 @@ static int sky2_up(struct net_device *dev) sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map, TX_RING_SIZE - 1); + napi_enable(&hw->napi); + err = sky2_rx_start(sky2); - if (err) + if (err) { + napi_disable(&hw->napi); goto err_out; + } /* Enable interrupts from phy/mac for port */ imask = sky2_read32(hw, B0_IMSK); @@ -1675,13 +1679,13 @@ static int sky2_down(struct net_device *dev) /* Stop more packets from being queued */ netif_stop_queue(dev); + napi_disable(&hw->napi); + /* Disable port IRQ */ imask = sky2_read32(hw, B0_IMSK); imask &= ~portirq_msk[port]; sky2_write32(hw, B0_IMSK, imask); - synchronize_irq(hw->pdev->irq); - sky2_gmac_reset(hw, port); /* Stop transmitter */ @@ -1695,9 +1699,6 @@ static int sky2_down(struct net_device *dev) ctrl &= ~(GM_GPCR_TX_ENA | GM_GPCR_RX_ENA); gma_write16(hw, port, GM_GP_CTRL, ctrl); - /* Make sure no packets are pending */ - napi_synchronize(&hw->napi); - sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET); /* Workaround shared GMAC reset */ @@ -1735,6 +1736,8 @@ static int sky2_down(struct net_device *dev) /* turn off LED's */ sky2_write16(hw, B0_Y2LED, LED_STAT_OFF); + synchronize_irq(hw->pdev->irq); + sky2_tx_clean(dev); sky2_rx_clean(sky2); @@ -2045,6 +2048,9 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu) err = sky2_rx_start(sky2); sky2_write32(hw, B0_IMSK, imask); + /* Unconditionally re-enable NAPI because even if we + * call dev_close() that will do a napi_disable(). + */ napi_enable(&hw->napi); if (err) @@ -2909,7 +2915,6 @@ static void sky2_restart(struct work_struct *work) rtnl_lock(); sky2_write32(hw, B0_IMSK, 0); sky2_read32(hw, B0_IMSK); - napi_disable(&hw->napi); for (i = 0; i < hw->ports; i++) { dev = hw->dev[i]; @@ -2919,7 +2924,6 @@ static void sky2_restart(struct work_struct *work) sky2_reset(hw); sky2_write32(hw, B0_IMSK, Y2_IS_BASE); - napi_enable(&hw->napi); for (i = 0; i < hw->ports; i++) { dev = hw->dev[i]; @@ -3957,7 +3961,7 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw, struct net_device *dev = alloc_etherdev(sizeof(*sky2)); if (!dev) { - dev_err(&hw->pdev->dev, "etherdev alloc failed\n"); + dev_err(&hw->pdev->dev, "etherdev alloc failed"); return NULL; } @@ -4187,6 +4191,7 @@ static int __devinit sky2_probe(struct pci_dev *pdev, err = -ENOMEM; goto err_out_free_pci; } + netif_napi_add(dev, &hw->napi, sky2_poll, NAPI_WEIGHT); if (!disable_msi && pci_enable_msi(pdev) == 0) { err = sky2_test_msi(hw); @@ -4202,8 +4207,6 @@ static int __devinit sky2_probe(struct pci_dev *pdev, goto err_out_free_netdev; } - netif_napi_add(dev, &hw->napi, sky2_poll, NAPI_WEIGHT); - err = request_irq(pdev->irq, sky2_intr, (hw->flags & SKY2_HW_USE_MSI) ? 0 : IRQF_SHARED, dev->name, hw); @@ -4212,7 +4215,6 @@ static int __devinit sky2_probe(struct pci_dev *pdev, goto err_out_unregister; } sky2_write32(hw, B0_IMSK, Y2_IS_BASE); - napi_enable(&hw->napi); sky2_show_addr(dev); @@ -4263,18 +4265,23 @@ static int __devinit sky2_probe(struct pci_dev *pdev, static void __devexit sky2_remove(struct pci_dev *pdev) { struct sky2_hw *hw = pci_get_drvdata(pdev); - int i; + struct net_device *dev0, *dev1; if (!hw) return; del_timer_sync(&hw->watchdog_timer); - cancel_work_sync(&hw->restart_work); - for (i = hw->ports; i >= 0; --i) - unregister_netdev(hw->dev[i]); + flush_scheduled_work(); sky2_write32(hw, B0_IMSK, 0); + synchronize_irq(hw->pdev->irq); + + dev0 = hw->dev[0]; + dev1 = hw->dev[1]; + if (dev1) + unregister_netdev(dev1); + unregister_netdev(dev0); sky2_power_aux(hw); @@ -4289,9 +4296,9 @@ static void __devexit sky2_remove(struct pci_dev *pdev) pci_release_regions(pdev); pci_disable_device(pdev); - for (i = hw->ports; i >= 0; --i) - free_netdev(hw->dev[i]); - + if (dev1) + free_netdev(dev1); + free_netdev(dev0); iounmap(hw->regs); kfree(hw); @@ -4321,7 +4328,6 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state) } sky2_write32(hw, B0_IMSK, 0); - napi_disable(&hw->napi); sky2_power_aux(hw); pci_save_state(pdev); @@ -4356,8 +4362,8 @@ static int sky2_resume(struct pci_dev *pdev) pci_write_config_dword(pdev, PCI_DEV_REG3, 0); sky2_reset(hw); + sky2_write32(hw, B0_IMSK, Y2_IS_BASE); - napi_enable(&hw->napi); for (i = 0; i < hw->ports; i++) { struct net_device *dev = hw->dev[i]; diff --git a/trunk/drivers/net/spider_net.c b/trunk/drivers/net/spider_net.c index 571060a3c91e..fab055ffcc90 100644 --- a/trunk/drivers/net/spider_net.c +++ b/trunk/drivers/net/spider_net.c @@ -46,7 +46,7 @@ #include #include #include -#include +#include #include #include diff --git a/trunk/drivers/net/tulip/uli526x.c b/trunk/drivers/net/tulip/uli526x.c index a7afeea156bd..76e55612430b 100644 --- a/trunk/drivers/net/tulip/uli526x.c +++ b/trunk/drivers/net/tulip/uli526x.c @@ -34,9 +34,9 @@ #include #include #include -#include #include +#include #include #include #include diff --git a/trunk/drivers/net/usb/mcs7830.c b/trunk/drivers/net/usb/mcs7830.c index f55a5951733a..6240b978fe3d 100644 --- a/trunk/drivers/net/usb/mcs7830.c +++ b/trunk/drivers/net/usb/mcs7830.c @@ -114,8 +114,8 @@ static void mcs7830_async_cmd_callback(struct urb *urb) struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context; if (urb->status < 0) - printk(KERN_DEBUG "%s() failed with %d\n", - __FUNCTION__, urb->status); + printk(KERN_DEBUG "mcs7830_async_cmd_callback() failed with %d", + urb->status); kfree(req); usb_free_urb(urb); @@ -129,15 +129,15 @@ static void mcs7830_set_reg_async(struct usbnet *dev, u16 index, u16 size, void urb = usb_alloc_urb(0, GFP_ATOMIC); if (!urb) { - dev_dbg(&dev->udev->dev, - "Error allocating URB in write_cmd_async!\n"); + dev_dbg(&dev->udev->dev, "Error allocating URB " + "in write_cmd_async!"); return; } req = kmalloc(sizeof *req, GFP_ATOMIC); if (!req) { - dev_err(&dev->udev->dev, - "Failed to allocate memory for control request\n"); + dev_err(&dev->udev->dev, "Failed to allocate memory for " + "control request"); goto out; } req->bRequestType = MCS7830_WR_BMREQ; @@ -153,8 +153,8 @@ static void mcs7830_set_reg_async(struct usbnet *dev, u16 index, u16 size, void ret = usb_submit_urb(urb, GFP_ATOMIC); if (ret < 0) { - dev_err(&dev->udev->dev, - "Error submitting the control message: ret=%d\n", ret); + dev_err(&dev->udev->dev, "Error submitting the control " + "message: ret=%d", ret); goto out; } return; diff --git a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_leds.c b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_leds.c index cb51dc51cce6..8f198befba39 100644 --- a/trunk/drivers/net/wireless/bcm43xx/bcm43xx_leds.c +++ b/trunk/drivers/net/wireless/bcm43xx/bcm43xx_leds.c @@ -29,7 +29,7 @@ #include "bcm43xx_radio.h" #include "bcm43xx.h" -#include +#include static void bcm43xx_led_changestate(struct bcm43xx_led *led) diff --git a/trunk/drivers/net/wireless/hostap/hostap_common.h b/trunk/drivers/net/wireless/hostap/hostap_common.h index 517f89845144..ceb7f1e5e9e0 100644 --- a/trunk/drivers/net/wireless/hostap/hostap_common.h +++ b/trunk/drivers/net/wireless/hostap/hostap_common.h @@ -4,6 +4,9 @@ #include #include +#define BIT(x) (1 << (x)) + + /* IEEE 802.11 defines */ /* Information Element IDs */ diff --git a/trunk/drivers/net/wireless/hostap/hostap_ioctl.c b/trunk/drivers/net/wireless/hostap/hostap_ioctl.c index d8f5efcfcab9..40f516d42c5e 100644 --- a/trunk/drivers/net/wireless/hostap/hostap_ioctl.c +++ b/trunk/drivers/net/wireless/hostap/hostap_ioctl.c @@ -2920,7 +2920,7 @@ static int prism2_ioctl_priv_monitor(struct net_device *dev, int *i) printk(KERN_DEBUG "%s: process %d (%s) used deprecated iwpriv monitor " "- update software to use iwconfig mode monitor\n", - dev->name, task_pid_nr(current), current->comm); + dev->name, current->pid, current->comm); /* Backward compatibility code - this can be removed at some point */ diff --git a/trunk/drivers/net/wireless/ipw2100.c b/trunk/drivers/net/wireless/ipw2100.c index c144e3cdb890..2d46a16c0945 100644 --- a/trunk/drivers/net/wireless/ipw2100.c +++ b/trunk/drivers/net/wireless/ipw2100.c @@ -1858,6 +1858,14 @@ static void ipw2100_down(struct ipw2100_priv *priv) modify_acceptable_latency("ipw2100", INFINITE_LATENCY); +#ifdef ACPI_CSTATE_LIMIT_DEFINED + if (priv->config & CFG_C3_DISABLED) { + IPW_DEBUG_INFO(": Resetting C3 transitions.\n"); + acpi_set_cstate_limit(priv->cstate_limit); + priv->config &= ~CFG_C3_DISABLED; + } +#endif + /* We have to signal any supplicant if we are disassociating */ if (associated) wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL); @@ -2083,6 +2091,14 @@ static void isr_indicate_rf_kill(struct ipw2100_priv *priv, u32 status) /* RF_KILL is now enabled (else we wouldn't be here) */ priv->status |= STATUS_RF_KILL_HW; +#ifdef ACPI_CSTATE_LIMIT_DEFINED + if (priv->config & CFG_C3_DISABLED) { + IPW_DEBUG_INFO(": Resetting C3 transitions.\n"); + acpi_set_cstate_limit(priv->cstate_limit); + priv->config &= ~CFG_C3_DISABLED; + } +#endif + /* Make sure the RF Kill check timer is running */ priv->stop_rf_kill = 0; cancel_delayed_work(&priv->rf_kill); @@ -2313,10 +2329,23 @@ static void ipw2100_corruption_detected(struct ipw2100_priv *priv, int i) u32 match, reg; int j; #endif +#ifdef ACPI_CSTATE_LIMIT_DEFINED + int limit; +#endif IPW_DEBUG_INFO(": PCI latency error detected at 0x%04zX.\n", i * sizeof(struct ipw2100_status)); +#ifdef ACPI_CSTATE_LIMIT_DEFINED + IPW_DEBUG_INFO(": Disabling C3 transitions.\n"); + limit = acpi_get_cstate_limit(); + if (limit > 2) { + priv->cstate_limit = limit; + acpi_set_cstate_limit(2); + priv->config |= CFG_C3_DISABLED; + } +#endif + #ifdef IPW2100_DEBUG_C3 /* Halt the fimrware so we can get a good image */ write_register(priv->net_dev, IPW_REG_RESET_REG, diff --git a/trunk/drivers/net/wireless/ipw2100.h b/trunk/drivers/net/wireless/ipw2100.h index 2b8be2418fa7..de7d384d38af 100644 --- a/trunk/drivers/net/wireless/ipw2100.h +++ b/trunk/drivers/net/wireless/ipw2100.h @@ -479,6 +479,7 @@ enum { #define CFG_ASSOCIATE (1<<6) #define CFG_FIXED_RATE (1<<7) #define CFG_ADHOC_CREATE (1<<8) +#define CFG_C3_DISABLED (1<<9) #define CFG_PASSIVE_SCAN (1<<10) #ifdef CONFIG_IPW2100_MONITOR #define CFG_CRC_CHECK (1<<11) @@ -507,6 +508,7 @@ struct ipw2100_priv { u8 bssid[ETH_ALEN]; u8 channel; int last_mode; + int cstate_limit; unsigned long connect_start; unsigned long last_reset; diff --git a/trunk/drivers/net/xen-netfront.c b/trunk/drivers/net/xen-netfront.c index 2a8fc431099f..7fd505cc4f7a 100644 --- a/trunk/drivers/net/xen-netfront.c +++ b/trunk/drivers/net/xen-netfront.c @@ -1526,7 +1526,7 @@ static int xennet_connect(struct net_device *dev) if (!feature_rx_copy) { dev_info(&dev->dev, - "backend does not support copying receive path\n"); + "backend does not support copying recieve path"); return -ENODEV; } diff --git a/trunk/drivers/of/platform.c b/trunk/drivers/of/platform.c index b47bb2d7476a..864f09fd9f86 100644 --- a/trunk/drivers/of/platform.c +++ b/trunk/drivers/of/platform.c @@ -12,7 +12,6 @@ * */ #include -#include #include #include #include @@ -95,23 +94,3 @@ int of_bus_type_init(struct bus_type *bus, const char *name) bus->resume = of_platform_device_resume; return bus_register(bus); } - -int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus) -{ - /* initialize common driver fields */ - if (!drv->driver.name) - drv->driver.name = drv->name; - if (!drv->driver.owner) - drv->driver.owner = drv->owner; - drv->driver.bus = bus; - - /* register with core */ - return driver_register(&drv->driver); -} -EXPORT_SYMBOL(of_register_driver); - -void of_unregister_driver(struct of_platform_driver *drv) -{ - driver_unregister(&drv->driver); -} -EXPORT_SYMBOL(of_unregister_driver); diff --git a/trunk/drivers/parport/daisy.c b/trunk/drivers/parport/daisy.c index 5bbff2028f8f..ff9f34453530 100644 --- a/trunk/drivers/parport/daisy.c +++ b/trunk/drivers/parport/daisy.c @@ -275,6 +275,35 @@ void parport_close(struct pardevice *dev) parport_unregister_device(dev); } +/** + * parport_device_num - convert device coordinates + * @parport: parallel port number + * @mux: multiplexor port number (-1 for no multiplexor) + * @daisy: daisy chain address (-1 for no daisy chain address) + * + * This tries to locate a device on the given parallel port, + * multiplexor port and daisy chain address, and returns its + * device number or %-ENXIO if no device with those coordinates + * exists. + **/ + +int parport_device_num(int parport, int mux, int daisy) +{ + int res = -ENXIO; + struct daisydev *dev; + + spin_lock(&topology_lock); + dev = topology; + while (dev && dev->port->portnum != parport && + dev->port->muxport != mux && dev->daisy != daisy) + dev = dev->next; + if (dev) + res = dev->devnum; + spin_unlock(&topology_lock); + + return res; +} + /* Send a daisy-chain-style CPP command packet. */ static int cpp_daisy(struct parport *port, int cmd) { diff --git a/trunk/drivers/parport/procfs.c b/trunk/drivers/parport/procfs.c index ed82e41210d1..bdbdab9285ca 100644 --- a/trunk/drivers/parport/procfs.c +++ b/trunk/drivers/parport/procfs.c @@ -237,7 +237,7 @@ static int do_hardware_modes (ctl_table *table, int write, #define PARPORT_PARPORT_DIR(CHILD) { .ctl_name = DEV_PARPORT, .procname = "parport", \ .mode = 0555, .child = CHILD } #define PARPORT_DEV_DIR(CHILD) { .ctl_name = CTL_DEV, .procname = "dev", .mode = 0555, .child = CHILD } -#define PARPORT_DEVICES_ROOT_DIR { .procname = "devices", \ +#define PARPORT_DEVICES_ROOT_DIR { .ctl_name = DEV_PARPORT_DEVICES, .procname = "devices", \ .mode = 0555, .child = NULL } static const unsigned long parport_min_timeslice_value = @@ -266,6 +266,7 @@ static const struct parport_sysctl_table parport_sysctl_template = { .sysctl_header = NULL, { { + .ctl_name = DEV_PARPORT_SPINTIME, .procname = "spintime", .data = NULL, .maxlen = sizeof(int), @@ -275,6 +276,7 @@ static const struct parport_sysctl_table parport_sysctl_template = { .extra2 = (void*) &parport_max_spintime_value }, { + .ctl_name = DEV_PARPORT_BASE_ADDR, .procname = "base-addr", .data = NULL, .maxlen = 0, @@ -282,6 +284,7 @@ static const struct parport_sysctl_table parport_sysctl_template = { .proc_handler = &do_hardware_base_addr }, { + .ctl_name = DEV_PARPORT_IRQ, .procname = "irq", .data = NULL, .maxlen = 0, @@ -289,6 +292,7 @@ static const struct parport_sysctl_table parport_sysctl_template = { .proc_handler = &do_hardware_irq }, { + .ctl_name = DEV_PARPORT_DMA, .procname = "dma", .data = NULL, .maxlen = 0, @@ -296,6 +300,7 @@ static const struct parport_sysctl_table parport_sysctl_template = { .proc_handler = &do_hardware_dma }, { + .ctl_name = DEV_PARPORT_MODES, .procname = "modes", .data = NULL, .maxlen = 0, @@ -305,6 +310,7 @@ static const struct parport_sysctl_table parport_sysctl_template = { PARPORT_DEVICES_ROOT_DIR, #ifdef CONFIG_PARPORT_1284 { + .ctl_name = DEV_PARPORT_AUTOPROBE, .procname = "autoprobe", .data = NULL, .maxlen = 0, @@ -312,6 +318,7 @@ static const struct parport_sysctl_table parport_sysctl_template = { .proc_handler = &do_autoprobe }, { + .ctl_name = DEV_PARPORT_AUTOPROBE + 1, .procname = "autoprobe0", .data = NULL, .maxlen = 0, @@ -319,6 +326,7 @@ static const struct parport_sysctl_table parport_sysctl_template = { .proc_handler = &do_autoprobe }, { + .ctl_name = DEV_PARPORT_AUTOPROBE + 2, .procname = "autoprobe1", .data = NULL, .maxlen = 0, @@ -326,6 +334,7 @@ static const struct parport_sysctl_table parport_sysctl_template = { .proc_handler = &do_autoprobe }, { + .ctl_name = DEV_PARPORT_AUTOPROBE + 3, .procname = "autoprobe2", .data = NULL, .maxlen = 0, @@ -333,6 +342,7 @@ static const struct parport_sysctl_table parport_sysctl_template = { .proc_handler = &do_autoprobe }, { + .ctl_name = DEV_PARPORT_AUTOPROBE + 4, .procname = "autoprobe3", .data = NULL, .maxlen = 0, @@ -344,6 +354,7 @@ static const struct parport_sysctl_table parport_sysctl_template = { }, { { + .ctl_name = DEV_PARPORT_DEVICES_ACTIVE, .procname = "active", .data = NULL, .maxlen = 0, @@ -382,6 +393,7 @@ parport_device_sysctl_template = { .sysctl_header = NULL, { { + .ctl_name = DEV_PARPORT_DEVICE_TIMESLICE, .procname = "timeslice", .data = NULL, .maxlen = sizeof(int), @@ -437,6 +449,7 @@ parport_default_sysctl_table = { .sysctl_header = NULL, { { + .ctl_name = DEV_PARPORT_DEFAULT_TIMESLICE, .procname = "timeslice", .data = &parport_default_timeslice, .maxlen = sizeof(parport_default_timeslice), @@ -446,6 +459,7 @@ parport_default_sysctl_table = { .extra2 = (void*) &parport_max_timeslice_value }, { + .ctl_name = DEV_PARPORT_DEFAULT_SPINTIME, .procname = "spintime", .data = &parport_default_spintime, .maxlen = sizeof(parport_default_spintime), @@ -488,7 +502,7 @@ int parport_proc_register(struct parport *port) t->device_dir[0].extra1 = port; - for (i = 0; i < 5; i++) + for (i = 0; i < 8; i++) t->vars[i].extra1 = port; t->vars[0].data = &port->spintime; @@ -498,7 +512,7 @@ int parport_proc_register(struct parport *port) t->vars[6 + i].extra2 = &port->probe_info[i]; t->port_dir[0].procname = port->name; - t->port_dir[0].ctl_name = 0; + t->port_dir[0].ctl_name = port->number + 1; /* nb 0 isn't legal here */ t->port_dir[0].child = t->vars; t->parport_dir[0].child = t->port_dir; @@ -537,12 +551,26 @@ int parport_device_proc_register(struct pardevice *device) t->dev_dir[0].child = t->parport_dir; t->parport_dir[0].child = t->port_dir; t->port_dir[0].procname = port->name; - t->port_dir[0].ctl_name = 0; + t->port_dir[0].ctl_name = port->number + 1; /* nb 0 isn't legal here */ t->port_dir[0].child = t->devices_root_dir; t->devices_root_dir[0].child = t->device_dir; - t->device_dir[0].ctl_name = 0; +#ifdef CONFIG_PARPORT_1284 + + t->device_dir[0].ctl_name = + parport_device_num(port->number, port->muxport, + device->daisy) + + 1; /* nb 0 isn't legal here */ + +#else /* No IEEE 1284 support */ + + /* parport_device_num isn't available. */ + t->device_dir[0].ctl_name = 1; + +#endif /* IEEE 1284 support or not */ + t->device_dir[0].procname = device->name; + t->device_dir[0].extra1 = device; t->device_dir[0].child = t->vars; t->vars[0].data = &device->timeslice; diff --git a/trunk/drivers/pcmcia/m32r_pcc.c b/trunk/drivers/pcmcia/m32r_pcc.c index c5e0d89c3ece..67d28ee80f22 100644 --- a/trunk/drivers/pcmcia/m32r_pcc.c +++ b/trunk/drivers/pcmcia/m32r_pcc.c @@ -22,9 +22,9 @@ #include #include #include -#include #include #include +#include #include #include diff --git a/trunk/drivers/pcmcia/m8xx_pcmcia.c b/trunk/drivers/pcmcia/m8xx_pcmcia.c index d182760f035b..b01985498460 100644 --- a/trunk/drivers/pcmcia/m8xx_pcmcia.c +++ b/trunk/drivers/pcmcia/m8xx_pcmcia.c @@ -48,9 +48,9 @@ #include #include #include -#include #include +#include #include #include #include diff --git a/trunk/drivers/power/ds2760_battery.c b/trunk/drivers/power/ds2760_battery.c index bdb9b7285b3d..be7021ee3611 100644 --- a/trunk/drivers/power/ds2760_battery.c +++ b/trunk/drivers/power/ds2760_battery.c @@ -366,7 +366,7 @@ static int ds2760_battery_probe(struct platform_device *pdev) retval = power_supply_register(&pdev->dev, &di->bat); if (retval) { - dev_err(di->dev, "failed to register battery\n"); + dev_err(di->dev, "failed to register battery"); goto batt_failed; } diff --git a/trunk/drivers/ps3/ps3av.c b/trunk/drivers/ps3/ps3av.c index 87b3493d88e5..397f4ce849dc 100644 --- a/trunk/drivers/ps3/ps3av.c +++ b/trunk/drivers/ps3/ps3av.c @@ -729,7 +729,7 @@ static void ps3av_monitor_info_dump(const struct ps3av_pkt_av_get_monitor_info * static const struct ps3av_monitor_quirk { const char *monitor_name; - u32 clear_60; + u32 clear_60, clear_50, clear_vesa; } ps3av_monitor_quirks[] = { { .monitor_name = "DELL 2007WFP", @@ -757,6 +757,10 @@ static void ps3av_fixup_monitor_info(struct ps3av_info_monitor *info) quirk->monitor_name); info->res_60.res_bits &= ~quirk->clear_60; info->res_60.native &= ~quirk->clear_60; + info->res_50.res_bits &= ~quirk->clear_50; + info->res_50.native &= ~quirk->clear_50; + info->res_vesa.res_bits &= ~quirk->clear_vesa; + info->res_vesa.native &= ~quirk->clear_vesa; break; } } diff --git a/trunk/drivers/ps3/ps3stor_lib.c b/trunk/drivers/ps3/ps3stor_lib.c index 55955f16ad91..3a9824e3b251 100644 --- a/trunk/drivers/ps3/ps3stor_lib.c +++ b/trunk/drivers/ps3/ps3stor_lib.c @@ -66,7 +66,7 @@ static int ps3stor_probe_access(struct ps3_storage_device *dev) if (n > 1) dev_info(&dev->sbd.core, "%s:%u: %lu accessible regions found. Only the first " - "one will be used\n", + "one will be used", __func__, __LINE__, n); dev->region_idx = __ffs(dev->accessible_regions); dev_info(&dev->sbd.core, diff --git a/trunk/drivers/ps3/vuart.c b/trunk/drivers/ps3/vuart.c index 9dea585ef806..bea25a1391ee 100644 --- a/trunk/drivers/ps3/vuart.c +++ b/trunk/drivers/ps3/vuart.c @@ -22,11 +22,11 @@ #include #include #include -#include #include #include #include +#include #include "vuart.h" diff --git a/trunk/drivers/rtc/rtc-pl031.c b/trunk/drivers/rtc/rtc-pl031.c index 2fd49edcc712..e4bf68ca96f7 100644 --- a/trunk/drivers/rtc/rtc-pl031.c +++ b/trunk/drivers/rtc/rtc-pl031.c @@ -21,11 +21,11 @@ #include #include #include -#include #include #include +#include #include #include #include diff --git a/trunk/drivers/rtc/rtc-sa1100.c b/trunk/drivers/rtc/rtc-sa1100.c index 6f1e9a9804bc..0918b787c4dd 100644 --- a/trunk/drivers/rtc/rtc-sa1100.c +++ b/trunk/drivers/rtc/rtc-sa1100.c @@ -29,8 +29,8 @@ #include #include #include -#include +#include #include #include #include diff --git a/trunk/drivers/rtc/rtc-sysfs.c b/trunk/drivers/rtc/rtc-sysfs.c index 2ae0e8304d3a..6cad0841f3c4 100644 --- a/trunk/drivers/rtc/rtc-sysfs.c +++ b/trunk/drivers/rtc/rtc-sysfs.c @@ -200,8 +200,9 @@ void rtc_sysfs_add_device(struct rtc_device *rtc) err = device_create_file(&rtc->dev, &dev_attr_wakealarm); if (err) - dev_err(rtc->dev.parent, - "failed to create alarm attribute, %d\n", err); + dev_err(rtc->dev.parent, "failed to create " + "alarm attribute, %d", + err); } void rtc_sysfs_del_device(struct rtc_device *rtc) diff --git a/trunk/drivers/s390/cio/idset.c b/trunk/drivers/s390/cio/idset.c index ef7bc0a125ef..16ea828e99f7 100644 --- a/trunk/drivers/s390/cio/idset.c +++ b/trunk/drivers/s390/cio/idset.c @@ -6,7 +6,7 @@ */ #include -#include +#include #include "idset.h" #include "css.h" diff --git a/trunk/drivers/s390/net/claw.c b/trunk/drivers/s390/net/claw.c index 3561982749e3..399695f7b1af 100644 --- a/trunk/drivers/s390/net/claw.c +++ b/trunk/drivers/s390/net/claw.c @@ -59,13 +59,13 @@ * 1.15 Changed for 2.6 Kernel No longer compiles on 2.4 or lower * 1.25 Added Packing support */ +#include #include #include #include #include #include -#include #include #include #include diff --git a/trunk/drivers/sbus/char/vfc.h b/trunk/drivers/sbus/char/vfc.h index f1aa1389ea4a..63941a259b92 100644 --- a/trunk/drivers/sbus/char/vfc.h +++ b/trunk/drivers/sbus/char/vfc.h @@ -126,7 +126,7 @@ struct vfc_dev { volatile struct vfc_regs __iomem *regs; struct vfc_regs *phys_regs; unsigned int control_reg; - struct mutex device_lock_mtx; + struct semaphore device_lock_sem; int instance; int busy; unsigned long which_io; diff --git a/trunk/drivers/sbus/char/vfc_dev.c b/trunk/drivers/sbus/char/vfc_dev.c index e7a1642b2aa4..9269f7fbd363 100644 --- a/trunk/drivers/sbus/char/vfc_dev.c +++ b/trunk/drivers/sbus/char/vfc_dev.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include @@ -55,12 +54,12 @@ static unsigned char saa9051_init_array[VFC_SAA9051_NR] = { void vfc_lock_device(struct vfc_dev *dev) { - mutex_lock(&dev->device_lock_mtx); + down(&dev->device_lock_sem); } void vfc_unlock_device(struct vfc_dev *dev) { - mutex_unlock(&dev->device_lock_mtx); + up(&dev->device_lock_sem); } diff --git a/trunk/drivers/scsi/FlashPoint.c b/trunk/drivers/scsi/FlashPoint.c index 1c9078191d9e..a7f916c0c9cd 100644 --- a/trunk/drivers/scsi/FlashPoint.c +++ b/trunk/drivers/scsi/FlashPoint.c @@ -25,6 +25,9 @@ #define FAILURE 0xFFFFFFFFL +#define BIT(x) ((unsigned char)(1<<(x))) /* single-bit mask in bit position x */ +#define BITW(x) ((unsigned short)(1<<(x))) /* single-bit mask in bit position x */ + struct sccb; typedef void (*CALL_BK_FN) (struct sccb *); @@ -371,9 +374,9 @@ typedef struct SCCBscam_info { #define SCAM_ENABLED BIT(2) #define SCAM_LEVEL2 BIT(3) -#define RENEGO_ENA BIT(10) -#define CONNIO_ENA BIT(11) -#define GREEN_PC_ENA BIT(12) +#define RENEGO_ENA BITW(10) +#define CONNIO_ENA BITW(11) +#define GREEN_PC_ENA BITW(12) #define AUTO_RATE_00 00 #define AUTO_RATE_05 01 @@ -508,23 +511,23 @@ typedef struct SCCBscam_info { #define hp_intena 0x40 -#define RESET BIT(7) -#define PROG_HLT BIT(6) -#define PARITY BIT(5) -#define FIFO BIT(4) -#define SEL BIT(3) -#define SCAM_SEL BIT(2) -#define RSEL BIT(1) -#define TIMEOUT BIT(0) -#define BUS_FREE BIT(15) -#define XFER_CNT_0 BIT(14) -#define PHASE BIT(13) -#define IUNKWN BIT(12) -#define ICMD_COMP BIT(11) -#define ITICKLE BIT(10) -#define IDO_STRT BIT(9) -#define ITAR_DISC BIT(8) -#define AUTO_INT (BIT(12)+BIT(11)+BIT(10)+BIT(9)+BIT(8)) +#define RESET BITW(7) +#define PROG_HLT BITW(6) +#define PARITY BITW(5) +#define FIFO BITW(4) +#define SEL BITW(3) +#define SCAM_SEL BITW(2) +#define RSEL BITW(1) +#define TIMEOUT BITW(0) +#define BUS_FREE BITW(15) +#define XFER_CNT_0 BITW(14) +#define PHASE BITW(13) +#define IUNKWN BITW(12) +#define ICMD_COMP BITW(11) +#define ITICKLE BITW(10) +#define IDO_STRT BITW(9) +#define ITAR_DISC BITW(8) +#define AUTO_INT (BITW(12)+BITW(11)+BITW(10)+BITW(9)+BITW(8)) #define CLR_ALL_INT 0xFFFF #define CLR_ALL_INT_1 0xFF00 @@ -671,37 +674,37 @@ typedef struct SCCBscam_info { #define BIOS_DATA_OFFSET 0x60 #define BIOS_RELATIVE_CARD 0x64 -#define AR3 (BIT(9) + BIT(8)) -#define SDATA BIT(10) +#define AR3 (BITW(9) + BITW(8)) +#define SDATA BITW(10) -#define CRD_OP BIT(11) /* Cmp Reg. w/ Data */ +#define CRD_OP BITW(11) /* Cmp Reg. w/ Data */ -#define CRR_OP BIT(12) /* Cmp Reg. w. Reg. */ +#define CRR_OP BITW(12) /* Cmp Reg. w. Reg. */ -#define CPE_OP (BIT(14)+BIT(11)) /* Cmp SCSI phs & Branch EQ */ +#define CPE_OP (BITW(14)+BITW(11)) /* Cmp SCSI phs & Branch EQ */ -#define CPN_OP (BIT(14)+BIT(12)) /* Cmp SCSI phs & Branch NOT EQ */ +#define CPN_OP (BITW(14)+BITW(12)) /* Cmp SCSI phs & Branch NOT EQ */ #define ADATA_OUT 0x00 -#define ADATA_IN BIT(8) -#define ACOMMAND BIT(10) -#define ASTATUS (BIT(10)+BIT(8)) -#define AMSG_OUT (BIT(10)+BIT(9)) -#define AMSG_IN (BIT(10)+BIT(9)+BIT(8)) +#define ADATA_IN BITW(8) +#define ACOMMAND BITW(10) +#define ASTATUS (BITW(10)+BITW(8)) +#define AMSG_OUT (BITW(10)+BITW(9)) +#define AMSG_IN (BITW(10)+BITW(9)+BITW(8)) -#define BRH_OP BIT(13) /* Branch */ +#define BRH_OP BITW(13) /* Branch */ #define ALWAYS 0x00 -#define EQUAL BIT(8) -#define NOT_EQ BIT(9) +#define EQUAL BITW(8) +#define NOT_EQ BITW(9) -#define TCB_OP (BIT(13)+BIT(11)) /* Test condition & branch */ +#define TCB_OP (BITW(13)+BITW(11)) /* Test condition & branch */ -#define FIFO_0 BIT(10) +#define FIFO_0 BITW(10) -#define MPM_OP BIT(15) /* Match phase and move data */ +#define MPM_OP BITW(15) /* Match phase and move data */ -#define MRR_OP BIT(14) /* Move DReg. to Reg. */ +#define MRR_OP BITW(14) /* Move DReg. to Reg. */ #define S_IDREG (BIT(2)+BIT(1)+BIT(0)) @@ -709,9 +712,9 @@ typedef struct SCCBscam_info { #define D_AR1 BIT(0) #define D_BUCKET (BIT(2) + BIT(1) + BIT(0)) -#define RAT_OP (BIT(14)+BIT(13)+BIT(11)) +#define RAT_OP (BITW(14)+BITW(13)+BITW(11)) -#define SSI_OP (BIT(15)+BIT(11)) +#define SSI_OP (BITW(15)+BITW(11)) #define SSI_ITAR_DISC (ITAR_DISC >> 8) #define SSI_IDO_STRT (IDO_STRT >> 8) diff --git a/trunk/drivers/scsi/Kconfig b/trunk/drivers/scsi/Kconfig index a5763c6e9362..30905cebefbb 100644 --- a/trunk/drivers/scsi/Kconfig +++ b/trunk/drivers/scsi/Kconfig @@ -521,7 +521,7 @@ config SCSI_DPT_I2O config SCSI_ADVANSYS tristate "AdvanSys SCSI support" - depends on SCSI && VIRT_TO_BUS + depends on SCSI depends on ISA || EISA || PCI help This is a driver for all SCSI host adapters manufactured by diff --git a/trunk/drivers/scsi/ide-scsi.c b/trunk/drivers/scsi/ide-scsi.c index 252d1806467f..fa7ba64483fb 100644 --- a/trunk/drivers/scsi/ide-scsi.c +++ b/trunk/drivers/scsi/ide-scsi.c @@ -47,9 +47,9 @@ #include #include #include -#include #include +#include #include #include diff --git a/trunk/drivers/scsi/ipr.c b/trunk/drivers/scsi/ipr.c index c316a0bcae6c..b41dfb539021 100644 --- a/trunk/drivers/scsi/ipr.c +++ b/trunk/drivers/scsi/ipr.c @@ -5134,7 +5134,6 @@ static void ipr_build_ata_ioadl(struct ipr_cmnd *ipr_cmd, u32 ioadl_flags = 0; struct ipr_ioarcb *ioarcb = &ipr_cmd->ioarcb; struct ipr_ioadl_desc *ioadl = ipr_cmd->ioadl; - struct ipr_ioadl_desc *last_ioadl = NULL; int len = qc->nbytes + qc->pad_len; struct scatterlist *sg; @@ -5157,13 +5156,11 @@ static void ipr_build_ata_ioadl(struct ipr_cmnd *ipr_cmd, ata_for_each_sg(sg, qc) { ioadl->flags_and_data_len = cpu_to_be32(ioadl_flags | sg_dma_len(sg)); ioadl->address = cpu_to_be32(sg_dma_address(sg)); - - last_ioadl = ioadl; - ioadl++; + if (ata_sg_is_last(sg, qc)) + ioadl->flags_and_data_len |= cpu_to_be32(IPR_IOADL_FLAGS_LAST); + else + ioadl++; } - - if (likely(last_ioadl)) - last_ioadl->flags_and_data_len |= cpu_to_be32(IPR_IOADL_FLAGS_LAST); } /** diff --git a/trunk/drivers/scsi/libsas/sas_discover.c b/trunk/drivers/scsi/libsas/sas_discover.c index 5f3a0d7b18de..7ef0afc3cd68 100644 --- a/trunk/drivers/scsi/libsas/sas_discover.c +++ b/trunk/drivers/scsi/libsas/sas_discover.c @@ -285,7 +285,7 @@ static void sas_discover_domain(struct work_struct *work) dev = port->port_dev; SAS_DPRINTK("DOING DISCOVERY on port %d, pid:%d\n", port->id, - task_pid_nr(current)); + current->pid); switch (dev->dev_type) { case SAS_END_DEV: @@ -320,7 +320,7 @@ static void sas_discover_domain(struct work_struct *work) } SAS_DPRINTK("DONE DISCOVERY on port %d, pid:%d, result:%d\n", port->id, - task_pid_nr(current), error); + current->pid, error); } static void sas_revalidate_domain(struct work_struct *work) @@ -334,12 +334,12 @@ static void sas_revalidate_domain(struct work_struct *work) &port->disc.pending); SAS_DPRINTK("REVALIDATING DOMAIN on port %d, pid:%d\n", port->id, - task_pid_nr(current)); + current->pid); if (port->port_dev) res = sas_ex_revalidate_domain(port->port_dev); SAS_DPRINTK("done REVALIDATING DOMAIN on port %d, pid:%d, res 0x%x\n", - port->id, task_pid_nr(current), res); + port->id, current->pid, res); } /* ---------- Events ---------- */ diff --git a/trunk/drivers/scsi/lpfc/lpfc_sli.c b/trunk/drivers/scsi/lpfc/lpfc_sli.c index ce348c5c706c..e5337ad4121e 100644 --- a/trunk/drivers/scsi/lpfc/lpfc_sli.c +++ b/trunk/drivers/scsi/lpfc/lpfc_sli.c @@ -1243,8 +1243,7 @@ void lpfc_sli_poll_fcp_ring(struct lpfc_hba *phba) memset(adaptermsg, 0, LPFC_MAX_ADPTMSG); memcpy(&adaptermsg[0], (uint8_t *) irsp, MAX_MSG_DATA); - dev_warn(&((phba->pcidev)->dev), - "lpfc%d: %s\n", + dev_warn(&((phba->pcidev)->dev), "lpfc%d: %s", phba->brd_no, adaptermsg); } else { /* Unknown IOCB command */ @@ -1431,8 +1430,7 @@ lpfc_sli_handle_fast_ring_event(struct lpfc_hba *phba, memset(adaptermsg, 0, LPFC_MAX_ADPTMSG); memcpy(&adaptermsg[0], (uint8_t *) irsp, MAX_MSG_DATA); - dev_warn(&((phba->pcidev)->dev), - "lpfc%d: %s\n", + dev_warn(&((phba->pcidev)->dev), "lpfc%d: %s", phba->brd_no, adaptermsg); } else { /* Unknown IOCB command */ @@ -1683,7 +1681,7 @@ lpfc_sli_handle_slow_ring_event(struct lpfc_hba *phba, memcpy(&adaptermsg[0], (uint8_t *) irsp, MAX_MSG_DATA); dev_warn(&((phba->pcidev)->dev), - "lpfc%d: %s\n", + "lpfc%d: %s", phba->brd_no, adaptermsg); } else { /* Unknown IOCB command */ diff --git a/trunk/drivers/scsi/nsp32.h b/trunk/drivers/scsi/nsp32.h index 6715ecb3bfca..a976e8193d16 100644 --- a/trunk/drivers/scsi/nsp32.h +++ b/trunk/drivers/scsi/nsp32.h @@ -68,6 +68,11 @@ static char * nsp32_model[] = { typedef u32 u32_le; typedef u16 u16_le; +/* + * MACRO + */ +#define BIT(x) (1UL << (x)) + /* * BASIC Definitions */ diff --git a/trunk/drivers/scsi/pcmcia/nsp_cs.h b/trunk/drivers/scsi/pcmcia/nsp_cs.h index 98397559c53b..b7f0fa246413 100644 --- a/trunk/drivers/scsi/pcmcia/nsp_cs.h +++ b/trunk/drivers/scsi/pcmcia/nsp_cs.h @@ -24,6 +24,7 @@ /************************************ * Some useful macros... */ +#define BIT(x) (1L << (x)) /* SCSI initiator must be ID 7 */ #define NSP_INITIATOR_ID 7 diff --git a/trunk/drivers/scsi/qla4xxx/ql4_fw.h b/trunk/drivers/scsi/qla4xxx/ql4_fw.h index fe415ec85655..9bb3d1d2a925 100644 --- a/trunk/drivers/scsi/qla4xxx/ql4_fw.h +++ b/trunk/drivers/scsi/qla4xxx/ql4_fw.h @@ -671,7 +671,7 @@ struct continuation_t1_entry { #define ET_CONTINUE ET_CONT_T1 /* Marker entry structure*/ -struct qla4_marker_entry { +struct marker_entry { struct qla4_header hdr; /* 00-03 */ uint32_t system_defined; /* 04-07 */ diff --git a/trunk/drivers/scsi/qla4xxx/ql4_iocb.c b/trunk/drivers/scsi/qla4xxx/ql4_iocb.c index e4461b5d767a..5006ecb3ef5e 100644 --- a/trunk/drivers/scsi/qla4xxx/ql4_iocb.c +++ b/trunk/drivers/scsi/qla4xxx/ql4_iocb.c @@ -69,7 +69,7 @@ static int qla4xxx_get_req_pkt(struct scsi_qla_host *ha, static int qla4xxx_send_marker_iocb(struct scsi_qla_host *ha, struct ddb_entry *ddb_entry, int lun) { - struct qla4_marker_entry *marker_entry; + struct marker_entry *marker_entry; unsigned long flags = 0; uint8_t status = QLA_SUCCESS; diff --git a/trunk/drivers/scsi/qla4xxx/ql4_os.c b/trunk/drivers/scsi/qla4xxx/ql4_os.c index 89460d27c689..03b68d4f3bd0 100644 --- a/trunk/drivers/scsi/qla4xxx/ql4_os.c +++ b/trunk/drivers/scsi/qla4xxx/ql4_os.c @@ -1286,7 +1286,7 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev, ret = scsi_init_shared_tag_map(host, MAX_SRBS); if (ret) { - dev_warn(&ha->pdev->dev, "scsi_init_shared_tag_map failed\n"); + dev_warn(&ha->pdev->dev, "scsi_init_shared_tag_map failed"); goto probe_failed; } diff --git a/trunk/drivers/serial/amba-pl011.c b/trunk/drivers/serial/amba-pl011.c index 40604a092921..72229df9dc11 100644 --- a/trunk/drivers/serial/amba-pl011.c +++ b/trunk/drivers/serial/amba-pl011.c @@ -263,15 +263,15 @@ static unsigned int pl01x_get_mctrl(struct uart_port *port) unsigned int result = 0; unsigned int status = readw(uap->port.membase + UART01x_FR); -#define TIOCMBIT(uartbit, tiocmbit) \ +#define BIT(uartbit, tiocmbit) \ if (status & uartbit) \ result |= tiocmbit - TIOCMBIT(UART01x_FR_DCD, TIOCM_CAR); - TIOCMBIT(UART01x_FR_DSR, TIOCM_DSR); - TIOCMBIT(UART01x_FR_CTS, TIOCM_CTS); - TIOCMBIT(UART011_FR_RI, TIOCM_RNG); -#undef TIOCMBIT + BIT(UART01x_FR_DCD, TIOCM_CAR); + BIT(UART01x_FR_DSR, TIOCM_DSR); + BIT(UART01x_FR_CTS, TIOCM_CTS); + BIT(UART011_FR_RI, TIOCM_RNG); +#undef BIT return result; } @@ -282,18 +282,18 @@ static void pl011_set_mctrl(struct uart_port *port, unsigned int mctrl) cr = readw(uap->port.membase + UART011_CR); -#define TIOCMBIT(tiocmbit, uartbit) \ +#define BIT(tiocmbit, uartbit) \ if (mctrl & tiocmbit) \ cr |= uartbit; \ else \ cr &= ~uartbit - TIOCMBIT(TIOCM_RTS, UART011_CR_RTS); - TIOCMBIT(TIOCM_DTR, UART011_CR_DTR); - TIOCMBIT(TIOCM_OUT1, UART011_CR_OUT1); - TIOCMBIT(TIOCM_OUT2, UART011_CR_OUT2); - TIOCMBIT(TIOCM_LOOP, UART011_CR_LBE); -#undef TIOCMBIT + BIT(TIOCM_RTS, UART011_CR_RTS); + BIT(TIOCM_DTR, UART011_CR_DTR); + BIT(TIOCM_OUT1, UART011_CR_OUT1); + BIT(TIOCM_OUT2, UART011_CR_OUT2); + BIT(TIOCM_LOOP, UART011_CR_LBE); +#undef BIT writew(cr, uap->port.membase + UART011_CR); } diff --git a/trunk/drivers/serial/crisv10.c b/trunk/drivers/serial/crisv10.c index f523cdf4b02b..7e8724d3571f 100644 --- a/trunk/drivers/serial/crisv10.c +++ b/trunk/drivers/serial/crisv10.c @@ -442,11 +442,11 @@ static char *serial_version = "$Revision: 1.25 $"; #include #include #include -#include #include #include #include +#include #include #include diff --git a/trunk/drivers/serial/serial_core.c b/trunk/drivers/serial/serial_core.c index 103189095c80..68aa4da01865 100644 --- a/trunk/drivers/serial/serial_core.c +++ b/trunk/drivers/serial/serial_core.c @@ -1959,11 +1959,12 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *port) mutex_lock(&state->mutex); - if (!console_suspend_enabled && uart_console(port)) { - /* we're going to avoid suspending serial console */ +#ifdef CONFIG_DISABLE_CONSOLE_SUSPEND + if (uart_console(port)) { mutex_unlock(&state->mutex); return 0; } +#endif tty_dev = device_find_child(port->dev, &match, serial_match_port); if (device_may_wakeup(tty_dev)) { @@ -2015,11 +2016,12 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *port) mutex_lock(&state->mutex); - if (!console_suspend_enabled && uart_console(port)) { - /* no need to resume serial console, it wasn't suspended */ +#ifdef CONFIG_DISABLE_CONSOLE_SUSPEND + if (uart_console(port)) { mutex_unlock(&state->mutex); return 0; } +#endif if (!port->suspended) { disable_irq_wake(port->irq); diff --git a/trunk/drivers/spi/spi_bfin5xx.c b/trunk/drivers/spi/spi_bfin5xx.c index 2ef11bb70b2e..6cb71d74738f 100644 --- a/trunk/drivers/spi/spi_bfin5xx.c +++ b/trunk/drivers/spi/spi_bfin5xx.c @@ -1070,7 +1070,7 @@ static int setup(struct spi_device *spi) return -ENODEV; } - dev_dbg(&spi->dev, "setup spi chip %s, width is %d, dma is %d\n", + dev_dbg(&spi->dev, "setup spi chip %s, width is %d, dma is %d,", spi->modalias, chip->width, chip->enable_dma); dev_dbg(&spi->dev, "ctl_reg is 0x%x, flag_reg is 0x%x\n", chip->ctl_reg, chip->flag); diff --git a/trunk/drivers/spi/spi_imx.c b/trunk/drivers/spi/spi_imx.c index 7686ba34430f..3b4650ae6f1a 100644 --- a/trunk/drivers/spi/spi_imx.c +++ b/trunk/drivers/spi/spi_imx.c @@ -1194,7 +1194,7 @@ static int setup(struct spi_device *spi) chip = kzalloc(sizeof(struct chip_data), GFP_KERNEL); if (!chip) { dev_err(&spi->dev, - "setup - cannot allocate controller state\n"); + "setup - cannot allocate controller state"); return -ENOMEM; } chip->control = SPI_DEFAULT_CONTROL; @@ -1206,7 +1206,7 @@ static int setup(struct spi_device *spi) if (!chip_info) { dev_err(&spi->dev, "setup - " - "cannot allocate controller data\n"); + "cannot allocate controller data"); status = -ENOMEM; goto err_first_setup; } diff --git a/trunk/drivers/ssb/Kconfig b/trunk/drivers/ssb/Kconfig index d976660cb7f0..b4a5e5e9d9fc 100644 --- a/trunk/drivers/ssb/Kconfig +++ b/trunk/drivers/ssb/Kconfig @@ -22,7 +22,7 @@ config SSB config SSB_PCIHOST_POSSIBLE bool - depends on SSB && (PCI = y || PCI = SSB) + depends on SSB && PCI default y config SSB_PCIHOST @@ -37,7 +37,7 @@ config SSB_PCIHOST config SSB_PCMCIAHOST_POSSIBLE bool - depends on SSB && (PCMCIA = y || PCMCIA = SSB) && EXPERIMENTAL + depends on SSB && PCMCIA && EXPERIMENTAL default y config SSB_PCMCIAHOST diff --git a/trunk/drivers/ssb/driver_mipscore.c b/trunk/drivers/ssb/driver_mipscore.c index 3d3dd32bf3ab..ab8691a32580 100644 --- a/trunk/drivers/ssb/driver_mipscore.c +++ b/trunk/drivers/ssb/driver_mipscore.c @@ -173,7 +173,7 @@ u32 ssb_cpu_clock(struct ssb_mipscore *mcore) void ssb_mipscore_init(struct ssb_mipscore *mcore) { - struct ssb_bus *bus; + struct ssb_bus *bus = mcore->dev->bus; struct ssb_device *dev; unsigned long hz, ns; unsigned int irq, i; @@ -183,7 +183,6 @@ void ssb_mipscore_init(struct ssb_mipscore *mcore) ssb_dprintk(KERN_INFO PFX "Initializing MIPS core...\n"); - bus = mcore->dev->bus; hz = ssb_clockspeed(bus); if (!hz) hz = 100000000; diff --git a/trunk/drivers/usb/class/cdc-acm.c b/trunk/drivers/usb/class/cdc-acm.c index 912d97aaf9bf..f51e22490edf 100644 --- a/trunk/drivers/usb/class/cdc-acm.c +++ b/trunk/drivers/usb/class/cdc-acm.c @@ -332,7 +332,7 @@ static void acm_read_bulk(struct urb *urb) return; if (status) - dev_dbg(&acm->data->dev, "bulk rx status %d\n", status); + dev_dbg(&acm->data->dev, "bulk rx status %d", status); buf = rcv->buffer; buf->size = urb->actual_length; @@ -831,13 +831,13 @@ static int acm_probe (struct usb_interface *intf, /* normal probing*/ if (!buffer) { - err("Weird descriptor references\n"); + err("Wierd descriptor references\n"); return -EINVAL; } if (!buflen) { if (intf->cur_altsetting->endpoint->extralen && intf->cur_altsetting->endpoint->extra) { - dev_dbg(&intf->dev,"Seeking extra descriptors on endpoint\n"); + dev_dbg(&intf->dev,"Seeking extra descriptors on endpoint"); buflen = intf->cur_altsetting->endpoint->extralen; buffer = intf->cur_altsetting->endpoint->extra; } else { @@ -887,24 +887,24 @@ static int acm_probe (struct usb_interface *intf, if (!union_header) { if (call_interface_num > 0) { - dev_dbg(&intf->dev,"No union descriptor, using call management descriptor\n"); + dev_dbg(&intf->dev,"No union descriptor, using call management descriptor"); data_interface = usb_ifnum_to_if(usb_dev, (data_interface_num = call_interface_num)); control_interface = intf; } else { - dev_dbg(&intf->dev,"No union descriptor, giving up\n"); + dev_dbg(&intf->dev,"No union descriptor, giving up"); return -ENODEV; } } else { control_interface = usb_ifnum_to_if(usb_dev, union_header->bMasterInterface0); data_interface = usb_ifnum_to_if(usb_dev, (data_interface_num = union_header->bSlaveInterface0)); if (!control_interface || !data_interface) { - dev_dbg(&intf->dev,"no interfaces\n"); + dev_dbg(&intf->dev,"no interfaces"); return -ENODEV; } } if (data_interface_num != call_interface_num) - dev_dbg(&intf->dev,"Seperate call control interface. That is not fully supported.\n"); + dev_dbg(&intf->dev,"Seperate call control interface. That is not fully supported."); skip_normal_probe: @@ -912,7 +912,7 @@ static int acm_probe (struct usb_interface *intf, if (data_interface->cur_altsetting->desc.bInterfaceClass != CDC_DATA_INTERFACE_TYPE) { if (control_interface->cur_altsetting->desc.bInterfaceClass == CDC_DATA_INTERFACE_TYPE) { struct usb_interface *t; - dev_dbg(&intf->dev,"Your device has switched interfaces.\n"); + dev_dbg(&intf->dev,"Your device has switched interfaces."); t = control_interface; control_interface = data_interface; @@ -927,7 +927,7 @@ static int acm_probe (struct usb_interface *intf, return -ENODEV; if (usb_interface_claimed(data_interface)) { /* valid in this context */ - dev_dbg(&intf->dev,"The data interface isn't available\n"); + dev_dbg(&intf->dev,"The data interface isn't available"); return -EBUSY; } @@ -944,7 +944,7 @@ static int acm_probe (struct usb_interface *intf, if (!usb_endpoint_dir_in(epread)) { /* descriptors are swapped */ struct usb_endpoint_descriptor *t; - dev_dbg(&intf->dev,"The data interface has switched endpoints\n"); + dev_dbg(&intf->dev,"The data interface has switched endpoints"); t = epread; epread = epwrite; @@ -959,7 +959,7 @@ static int acm_probe (struct usb_interface *intf, } if (!(acm = kzalloc(sizeof(struct acm), GFP_KERNEL))) { - dev_dbg(&intf->dev, "out of memory (acm kzalloc)\n"); + dev_dbg(&intf->dev, "out of memory (acm kzalloc)"); goto alloc_fail; } @@ -985,26 +985,26 @@ static int acm_probe (struct usb_interface *intf, buf = usb_buffer_alloc(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma); if (!buf) { - dev_dbg(&intf->dev, "out of memory (ctrl buffer alloc)\n"); + dev_dbg(&intf->dev, "out of memory (ctrl buffer alloc)"); goto alloc_fail2; } acm->ctrl_buffer = buf; if (acm_write_buffers_alloc(acm) < 0) { - dev_dbg(&intf->dev, "out of memory (write buffer alloc)\n"); + dev_dbg(&intf->dev, "out of memory (write buffer alloc)"); goto alloc_fail4; } acm->ctrlurb = usb_alloc_urb(0, GFP_KERNEL); if (!acm->ctrlurb) { - dev_dbg(&intf->dev, "out of memory (ctrlurb kmalloc)\n"); + dev_dbg(&intf->dev, "out of memory (ctrlurb kmalloc)"); goto alloc_fail5; } for (i = 0; i < num_rx_buf; i++) { struct acm_ru *rcv = &(acm->ru[i]); if (!(rcv->urb = usb_alloc_urb(0, GFP_KERNEL))) { - dev_dbg(&intf->dev, "out of memory (read urbs usb_alloc_urb)\n"); + dev_dbg(&intf->dev, "out of memory (read urbs usb_alloc_urb)"); goto alloc_fail7; } @@ -1015,13 +1015,13 @@ static int acm_probe (struct usb_interface *intf, struct acm_rb *buf = &(acm->rb[i]); if (!(buf->base = usb_buffer_alloc(acm->dev, readsize, GFP_KERNEL, &buf->dma))) { - dev_dbg(&intf->dev, "out of memory (read bufs usb_buffer_alloc)\n"); + dev_dbg(&intf->dev, "out of memory (read bufs usb_buffer_alloc)"); goto alloc_fail7; } } acm->writeurb = usb_alloc_urb(0, GFP_KERNEL); if (!acm->writeurb) { - dev_dbg(&intf->dev, "out of memory (writeurb kmalloc)\n"); + dev_dbg(&intf->dev, "out of memory (writeurb kmalloc)"); goto alloc_fail7; } diff --git a/trunk/drivers/usb/core/devio.c b/trunk/drivers/usb/core/devio.c index 1f4f6d02fe25..f013b4012c9a 100644 --- a/trunk/drivers/usb/core/devio.c +++ b/trunk/drivers/usb/core/devio.c @@ -460,7 +460,7 @@ static int checkintf(struct dev_state *ps, unsigned int ifnum) return 0; /* if not yet claimed, claim it for the driver */ dev_warn(&ps->dev->dev, "usbfs: process %d (%s) did not claim interface %u before use\n", - task_pid_nr(current), current->comm, ifnum); + current->pid, current->comm, ifnum); return claimintf(ps, ifnum); } diff --git a/trunk/drivers/usb/core/endpoint.c b/trunk/drivers/usb/core/endpoint.c index 99e5a68a3f12..7dc123d6b2d0 100644 --- a/trunk/drivers/usb/core/endpoint.c +++ b/trunk/drivers/usb/core/endpoint.c @@ -291,7 +291,7 @@ int usb_create_ep_files(struct device *parent, retval = endpoint_get_minor(ep_dev); if (retval) { - dev_err(parent, "can not allocate minor number for %s\n", + dev_err(parent, "can not allocate minor number for %s", ep_dev->dev.bus_id); goto error_register; } diff --git a/trunk/drivers/usb/core/hub.c b/trunk/drivers/usb/core/hub.c index 036c3dea855e..60a8f55a0cc7 100644 --- a/trunk/drivers/usb/core/hub.c +++ b/trunk/drivers/usb/core/hub.c @@ -2870,9 +2870,10 @@ static int hub_thread(void *__unused) set_freezable(); do { hub_events(); - wait_event_freezable(khubd_wait, + wait_event_interruptible(khubd_wait, !list_empty(&hub_event_list) || kthread_should_stop()); + try_to_freeze(); } while (!kthread_should_stop() || !list_empty(&hub_event_list)); pr_debug("%s: khubd exiting\n", usbcore_name); diff --git a/trunk/drivers/usb/core/message.c b/trunk/drivers/usb/core/message.c index 8dd5a6afd513..c021af390372 100644 --- a/trunk/drivers/usb/core/message.c +++ b/trunk/drivers/usb/core/message.c @@ -1526,7 +1526,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration) new_interfaces = kmalloc(nintf * sizeof(*new_interfaces), GFP_KERNEL); if (!new_interfaces) { - dev_err(&dev->dev, "Out of memory\n"); + dev_err(&dev->dev, "Out of memory"); return -ENOMEM; } @@ -1535,7 +1535,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration) sizeof(struct usb_interface), GFP_KERNEL); if (!new_interfaces[n]) { - dev_err(&dev->dev, "Out of memory\n"); + dev_err(&dev->dev, "Out of memory"); ret = -ENOMEM; free_interfaces: while (--n >= 0) diff --git a/trunk/drivers/usb/gadget/file_storage.c b/trunk/drivers/usb/gadget/file_storage.c index 1d174dcb3ac9..73726c570a6e 100644 --- a/trunk/drivers/usb/gadget/file_storage.c +++ b/trunk/drivers/usb/gadget/file_storage.c @@ -4006,7 +4006,7 @@ static int __init fsg_bind(struct usb_gadget *gadget) DBG(fsg, "removable=%d, stall=%d, buflen=%u\n", mod_data.removable, mod_data.can_stall, mod_data.buflen); - DBG(fsg, "I/O thread pid: %d\n", task_pid_nr(fsg->thread_task)); + DBG(fsg, "I/O thread pid: %d\n", fsg->thread_task->pid); set_bit(REGISTERED, &fsg->atomic_bitflags); diff --git a/trunk/drivers/usb/host/ohci-s3c2410.c b/trunk/drivers/usb/host/ohci-s3c2410.c index 44b79e8a6e25..6829814b7aaf 100644 --- a/trunk/drivers/usb/host/ohci-s3c2410.c +++ b/trunk/drivers/usb/host/ohci-s3c2410.c @@ -358,7 +358,7 @@ static int usb_hcd_s3c2410_probe (const struct hc_driver *driver, hcd->rsrc_len = dev->resource[0].end - dev->resource[0].start + 1; if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { - dev_err(&dev->dev, "request_mem_region failed\n"); + dev_err(&dev->dev, "request_mem_region failed"); retval = -EBUSY; goto err_put; } diff --git a/trunk/drivers/usb/misc/adutux.c b/trunk/drivers/usb/misc/adutux.c index c567aa7a41ea..5131cbfb2f52 100644 --- a/trunk/drivers/usb/misc/adutux.c +++ b/trunk/drivers/usb/misc/adutux.c @@ -805,7 +805,7 @@ static int adu_probe(struct usb_interface *interface, dev->minor = interface->minor; /* let the user know what node this device is now attached to */ - dev_info(&interface->dev, "ADU%d %s now attached to /dev/usb/adutux%d\n", + dev_info(&interface->dev, "ADU%d %s now attached to /dev/usb/adutux%d", udev->descriptor.idProduct, dev->serial_number, (dev->minor - ADU_MINOR_BASE)); exit: @@ -851,7 +851,7 @@ static void adu_disconnect(struct usb_interface *interface) mutex_unlock(&dev->mtx); } - dev_info(&interface->dev, "ADU device adutux%d now disconnected\n", + dev_info(&interface->dev, "ADU device adutux%d now disconnected", (minor - ADU_MINOR_BASE)); dbg(2," %s : leave", __FUNCTION__); diff --git a/trunk/drivers/usb/misc/iowarrior.c b/trunk/drivers/usb/misc/iowarrior.c index d372fbc4effb..46d9f27ec173 100644 --- a/trunk/drivers/usb/misc/iowarrior.c +++ b/trunk/drivers/usb/misc/iowarrior.c @@ -216,7 +216,7 @@ static void iowarrior_callback(struct urb *urb) exit: retval = usb_submit_urb(urb, GFP_ATOMIC); if (retval) - dev_err(&dev->interface->dev, "%s - usb_submit_urb failed with result %d\n", + dev_err(&dev->interface->dev, "%s - usb_submit_urb failed with result %d", __FUNCTION__, retval); } @@ -451,7 +451,7 @@ static ssize_t iowarrior_write(struct file *file, break; default: /* what do we have here ? An unsupported Product-ID ? */ - dev_err(&dev->interface->dev, "%s - not supported for product=0x%x\n", + dev_err(&dev->interface->dev, "%s - not supported for product=0x%x", __FUNCTION__, dev->product_id); retval = -EFAULT; goto exit; @@ -526,7 +526,7 @@ static int iowarrior_ioctl(struct inode *inode, struct file *file, } else { retval = -EINVAL; dev_err(&dev->interface->dev, - "ioctl 'IOW_WRITE' is not supported for product=0x%x.\n", + "ioctl 'IOW_WRITE' is not supported for product=0x%x.", dev->product_id); } break; @@ -752,7 +752,7 @@ static int iowarrior_probe(struct usb_interface *interface, /* allocate memory for our device state and intialize it */ dev = kzalloc(sizeof(struct iowarrior), GFP_KERNEL); if (dev == NULL) { - dev_err(&interface->dev, "Out of memory\n"); + dev_err(&interface->dev, "Out of memory"); return retval; } diff --git a/trunk/drivers/usb/misc/phidgetmotorcontrol.c b/trunk/drivers/usb/misc/phidgetmotorcontrol.c index 2ad09b1f4848..df0ebcdb9d6a 100644 --- a/trunk/drivers/usb/misc/phidgetmotorcontrol.c +++ b/trunk/drivers/usb/misc/phidgetmotorcontrol.c @@ -155,7 +155,7 @@ static void motorcontrol_irq(struct urb *urb) retval = usb_submit_urb(urb, GFP_ATOMIC); if (retval) dev_err(&mc->intf->dev, - "can't resubmit intr, %s-%s/motorcontrol0, retval %d\n", + "can't resubmit intr, %s-%s/motorcontrol0, retval %d", mc->udev->bus->bus_name, mc->udev->devpath, retval); } diff --git a/trunk/drivers/usb/serial/ftdi_sio.c b/trunk/drivers/usb/serial/ftdi_sio.c index 65257867b34b..e4c248c98e84 100644 --- a/trunk/drivers/usb/serial/ftdi_sio.c +++ b/trunk/drivers/usb/serial/ftdi_sio.c @@ -1071,7 +1071,7 @@ static ssize_t show_latency_timer(struct device *dev, struct device_attribute *a (char*) &latency, 1, WDR_TIMEOUT); if (rv < 0) { - dev_err(dev, "Unable to read latency timer: %i\n", rv); + dev_err(dev, "Unable to read latency timer: %i", rv); return -EIO; } return sprintf(buf, "%i\n", latency); @@ -1098,7 +1098,7 @@ static ssize_t store_latency_timer(struct device *dev, struct device_attribute * buf, 0, WDR_TIMEOUT); if (rv < 0) { - dev_err(dev, "Unable to write latency timer: %i\n", rv); + dev_err(dev, "Unable to write latency timer: %i", rv); return -EIO; } diff --git a/trunk/drivers/usb/serial/io_edgeport.c b/trunk/drivers/usb/serial/io_edgeport.c index 8dd3abc99d63..2ecb1d2a034d 100644 --- a/trunk/drivers/usb/serial/io_edgeport.c +++ b/trunk/drivers/usb/serial/io_edgeport.c @@ -2882,7 +2882,7 @@ static int edge_startup (struct usb_serial *serial) (edge_serial->product_info.NumPorts != serial->num_ports)) { dev_warn(&serial->dev->dev, "Device Reported %d serial ports " "vs. core thinking we have %d ports, email " - "greg@kroah.com this information.\n", + "greg@kroah.com this information.", edge_serial->product_info.NumPorts, serial->num_ports); } diff --git a/trunk/drivers/usb/serial/ipw.c b/trunk/drivers/usb/serial/ipw.c index cbe5530f3db2..1b94daa61584 100644 --- a/trunk/drivers/usb/serial/ipw.c +++ b/trunk/drivers/usb/serial/ipw.c @@ -227,7 +227,7 @@ static int ipw_open(struct usb_serial_port *port, struct file *filp) 0, 100000); if (result < 0) - dev_err(&port->dev, "Init of modem failed (error = %d)\n", result); + dev_err(&port->dev, "Init of modem failed (error = %d)", result); /* reset the bulk pipes */ usb_clear_halt(dev, usb_rcvbulkpipe(dev, port->bulk_in_endpointAddress)); @@ -255,7 +255,7 @@ static int ipw_open(struct usb_serial_port *port, struct file *filp) 0, 100000); if (result < 0) - dev_err(&port->dev, "Enabling bulk RxRead failed (error = %d)\n", result); + dev_err(&port->dev, "Enabling bulk RxRead failed (error = %d)", result); /*--4: setup the initial flowcontrol */ dbg("%s:setting init flowcontrol (%s)",__FUNCTION__,buf_flow_init); @@ -268,7 +268,7 @@ static int ipw_open(struct usb_serial_port *port, struct file *filp) 0x10, 200000); if (result < 0) - dev_err(&port->dev, "initial flowcontrol failed (error = %d)\n", result); + dev_err(&port->dev, "initial flowcontrol failed (error = %d)", result); /*--5: raise the dtr */ @@ -282,7 +282,7 @@ static int ipw_open(struct usb_serial_port *port, struct file *filp) 0, 200000); if (result < 0) - dev_err(&port->dev, "setting dtr failed (error = %d)\n", result); + dev_err(&port->dev, "setting dtr failed (error = %d)", result); /*--6: raise the rts */ dbg("%s:raising rts",__FUNCTION__); @@ -295,7 +295,7 @@ static int ipw_open(struct usb_serial_port *port, struct file *filp) 0, 200000); if (result < 0) - dev_err(&port->dev, "setting dtr failed (error = %d)\n", result); + dev_err(&port->dev, "setting dtr failed (error = %d)", result); kfree(buf_flow_init); return 0; @@ -322,7 +322,7 @@ static void ipw_close(struct usb_serial_port *port, struct file * filp) 0, 200000); if (result < 0) - dev_err(&port->dev, "dropping dtr failed (error = %d)\n", result); + dev_err(&port->dev, "dropping dtr failed (error = %d)", result); /*--2: drop the rts */ dbg("%s:dropping rts",__FUNCTION__); @@ -334,7 +334,7 @@ static void ipw_close(struct usb_serial_port *port, struct file * filp) 0, 200000); if (result < 0) - dev_err(&port->dev, "dropping rts failed (error = %d)\n", result); + dev_err(&port->dev, "dropping rts failed (error = %d)", result); /*--3: purge */ @@ -347,7 +347,7 @@ static void ipw_close(struct usb_serial_port *port, struct file * filp) 0, 200000); if (result < 0) - dev_err(&port->dev, "purge failed (error = %d)\n", result); + dev_err(&port->dev, "purge failed (error = %d)", result); /* send RXBULK_off (tell modem to stop transmitting bulk data on rx chan) */ @@ -361,7 +361,7 @@ static void ipw_close(struct usb_serial_port *port, struct file * filp) 100000); if (result < 0) - dev_err(&port->dev, "Disabling bulk RxRead failed (error = %d)\n", result); + dev_err(&port->dev, "Disabling bulk RxRead failed (error = %d)", result); /* shutdown any in-flight urbs that we know about */ usb_kill_urb(port->read_urb); diff --git a/trunk/drivers/usb/serial/mos7720.c b/trunk/drivers/usb/serial/mos7720.c index e02c198016b0..01e811becec4 100644 --- a/trunk/drivers/usb/serial/mos7720.c +++ b/trunk/drivers/usb/serial/mos7720.c @@ -478,7 +478,7 @@ static int mos7720_open(struct usb_serial_port *port, struct file * filp) response = usb_submit_urb(port0->interrupt_in_urb, GFP_KERNEL); if (response) dev_err(&port->dev, - "%s - Error %d submitting control urb\n", + "%s - Error %d submitting control urb", __FUNCTION__, response); } @@ -492,7 +492,7 @@ static int mos7720_open(struct usb_serial_port *port, struct file * filp) response = usb_submit_urb(port->read_urb, GFP_KERNEL); if (response) dev_err(&port->dev, - "%s - Error %d submitting read urb\n", __FUNCTION__, response); + "%s - Error %d submitting read urb", __FUNCTION__, response); /* initialize our icount structure */ memset(&(mos7720_port->icount), 0x00, sizeof(mos7720_port->icount)); diff --git a/trunk/drivers/usb/serial/oti6858.c b/trunk/drivers/usb/serial/oti6858.c index eea226ae37bd..d19861166b50 100644 --- a/trunk/drivers/usb/serial/oti6858.c +++ b/trunk/drivers/usb/serial/oti6858.c @@ -256,7 +256,7 @@ static void setup_line(struct work_struct *work) 100); if (result != OTI6858_CTRL_PKT_SIZE) { - dev_err(&port->dev, "%s(): error reading status\n", __FUNCTION__); + dev_err(&port->dev, "%s(): error reading status", __FUNCTION__); kfree(new_setup); /* we will try again */ schedule_delayed_work(&priv->delayed_setup_work, msecs_to_jiffies(2)); diff --git a/trunk/drivers/usb/serial/sierra.c b/trunk/drivers/usb/serial/sierra.c index 959b3e4e9077..0bb8de4cc524 100644 --- a/trunk/drivers/usb/serial/sierra.c +++ b/trunk/drivers/usb/serial/sierra.c @@ -48,7 +48,7 @@ enum devicetype { static int sierra_set_power_state(struct usb_device *udev, __u16 swiState) { int result; - dev_dbg(&udev->dev, "%s", "SET POWER STATE\n"); + dev_dbg(&udev->dev, "%s", "SET POWER STATE"); result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x00, /* __u8 request */ 0x40, /* __u8 request type */ @@ -63,7 +63,7 @@ static int sierra_set_power_state(struct usb_device *udev, __u16 swiState) static int sierra_set_ms_mode(struct usb_device *udev, __u16 eSocMode) { int result; - dev_dbg(&udev->dev, "%s", "DEVICE MODE SWITCH\n"); + dev_dbg(&udev->dev, "%s", "DEVICE MODE SWITCH"); result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), SWIMS_USB_REQUEST_SetMode, /* __u8 request */ SWIMS_USB_REQUEST_TYPE_SetMode, /* __u8 request type */ @@ -397,7 +397,7 @@ static void sierra_indat_callback(struct urb *urb) err = usb_submit_urb(urb, GFP_ATOMIC); if (err) dev_err(&port->dev, "resubmit read urb failed." - "(%d)\n", err); + "(%d)", err); } } return; @@ -525,7 +525,7 @@ static int sierra_open(struct usb_serial_port *port, struct file *filp) result = usb_submit_urb(urb, GFP_KERNEL); if (result) { - dev_err(&port->dev, "submit urb %d failed (%d) %d\n", + dev_err(&port->dev, "submit urb %d failed (%d) %d", i, result, urb->transfer_buffer_length); } } @@ -538,7 +538,7 @@ static int sierra_open(struct usb_serial_port *port, struct file *filp) if (port->interrupt_in_urb) { result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); if (result) - dev_err(&port->dev, "submit irq_in urb failed %d\n", + dev_err(&port->dev, "submit irq_in urb failed %d", result); } return 0; diff --git a/trunk/drivers/usb/storage/usb.c b/trunk/drivers/usb/storage/usb.c index ac6114eea0c3..3451e8d03ab0 100644 --- a/trunk/drivers/usb/storage/usb.c +++ b/trunk/drivers/usb/storage/usb.c @@ -907,9 +907,12 @@ static int usb_stor_scan_thread(void * __us) if (delay_use > 0) { printk(KERN_DEBUG "usb-storage: waiting for device " "to settle before scanning\n"); - wait_event_freezable_timeout(us->delay_wait, +retry: + wait_event_interruptible_timeout(us->delay_wait, test_bit(US_FLIDX_DISCONNECTING, &us->flags), delay_use * HZ); + if (try_to_freeze()) + goto retry; } /* If the device is still connected, perform the scanning */ diff --git a/trunk/drivers/video/au1100fb.c b/trunk/drivers/video/au1100fb.c index 62bd4441b5e0..832e4613673a 100644 --- a/trunk/drivers/video/au1100fb.c +++ b/trunk/drivers/video/au1100fb.c @@ -457,7 +457,7 @@ static struct fb_ops au1100fb_ops = /* AU1100 LCD controller device driver */ -static int __init au1100fb_drv_probe(struct device *dev) +int au1100fb_drv_probe(struct device *dev) { struct au1100fb_device *fbdev = NULL; struct resource *regs_res; diff --git a/trunk/drivers/video/console/newport_con.c b/trunk/drivers/video/console/newport_con.c index d31b203bf654..f57d7b2758b7 100644 --- a/trunk/drivers/video/console/newport_con.c +++ b/trunk/drivers/video/console/newport_con.c @@ -98,7 +98,7 @@ static inline void newport_init_cmap(void) } } -static const struct linux_logo *newport_show_logo(void) +static struct linux_logo *newport_show_logo(void) { #ifdef CONFIG_LOGO_SGI_CLUT224 const struct linux_logo *logo = fb_find_logo(8); @@ -108,8 +108,8 @@ static const struct linux_logo *newport_show_logo(void) if (!logo) return NULL; - clut = logo->clut; - data = logo->data; + *clut = logo->clut; + *data = logo->data; for (i = 0; i < logo->clutsize; i++) { newport_bfwait(npregs); diff --git a/trunk/drivers/video/cyber2000fb.c b/trunk/drivers/video/cyber2000fb.c index 5fb8675e0d6b..9bb2cbfe4a3d 100644 --- a/trunk/drivers/video/cyber2000fb.c +++ b/trunk/drivers/video/cyber2000fb.c @@ -62,7 +62,7 @@ struct cfb_info { struct display_switch *dispsw; struct display *display; struct pci_dev *dev; - unsigned char __iomem *region; + unsigned char __iomem *region; unsigned char __iomem *regs; u_int id; int func_use_count; @@ -97,11 +97,11 @@ MODULE_PARM_DESC(default_font, "Default font name"); /* * Our access methods. */ -#define cyber2000fb_writel(val, reg, cfb) writel(val, (cfb)->regs + (reg)) -#define cyber2000fb_writew(val, reg, cfb) writew(val, (cfb)->regs + (reg)) -#define cyber2000fb_writeb(val, reg, cfb) writeb(val, (cfb)->regs + (reg)) +#define cyber2000fb_writel(val,reg,cfb) writel(val, (cfb)->regs + (reg)) +#define cyber2000fb_writew(val,reg,cfb) writew(val, (cfb)->regs + (reg)) +#define cyber2000fb_writeb(val,reg,cfb) writeb(val, (cfb)->regs + (reg)) -#define cyber2000fb_readb(reg, cfb) readb((cfb)->regs + (reg)) +#define cyber2000fb_readb(reg,cfb) readb((cfb)->regs + (reg)) static inline void cyber2000_crtcw(unsigned int reg, unsigned int val, struct cfb_info *cfb) @@ -221,8 +221,12 @@ cyber2000fb_copyarea(struct fb_info *info, const struct fb_copyarea *region) static void cyber2000fb_imageblit(struct fb_info *info, const struct fb_image *image) { - cfb_imageblit(info, image); - return; +// struct cfb_info *cfb = (struct cfb_info *)info; + +// if (!(cfb->fb.var.accel_flags & FB_ACCELF_TEXT)) { + cfb_imageblit(info, image); + return; +// } } static int cyber2000fb_sync(struct fb_info *info) @@ -273,12 +277,12 @@ cyber2000fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, /* * Pseudocolour: - * 8 8 + * 8 8 * pixel --/--+--/--> red lut --> red dac - * | 8 - * +--/--> green lut --> green dac - * | 8 - * +--/--> blue lut --> blue dac + * | 8 + * +--/--> green lut --> green dac + * | 8 + * +--/--> blue lut --> blue dac */ case FB_VISUAL_PSEUDOCOLOR: if (regno >= NR_PALETTE) @@ -288,9 +292,9 @@ cyber2000fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, green >>= 8; blue >>= 8; - cfb->palette[regno].red = red; + cfb->palette[regno].red = red; cfb->palette[regno].green = green; - cfb->palette[regno].blue = blue; + cfb->palette[regno].blue = blue; cyber2000fb_writeb(regno, 0x3c8, cfb); cyber2000fb_writeb(red, 0x3c9, cfb); @@ -300,12 +304,12 @@ cyber2000fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, /* * Direct colour: - * n rl - * pixel --/--+--/--> red lut --> red dac - * | gl - * +--/--> green lut --> green dac - * | bl - * +--/--> blue lut --> blue dac + * n rl + * pixel --/--+--/--> red lut --> red dac + * | gl + * +--/--> green lut --> green dac + * | bl + * +--/--> blue lut --> blue dac * n = bpp, rl = red length, gl = green length, bl = blue length */ case FB_VISUAL_DIRECTCOLOR: @@ -321,11 +325,9 @@ cyber2000fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, * to the high 6 bits of the LUT. */ cyber2000fb_writeb(regno << 2, 0x3c8, cfb); - cyber2000fb_writeb(cfb->palette[regno >> 1].red, - 0x3c9, cfb); + cyber2000fb_writeb(cfb->palette[regno >> 1].red, 0x3c9, cfb); cyber2000fb_writeb(green, 0x3c9, cfb); - cyber2000fb_writeb(cfb->palette[regno >> 1].blue, - 0x3c9, cfb); + cyber2000fb_writeb(cfb->palette[regno >> 1].blue, 0x3c9, cfb); green = cfb->palette[regno << 3].green; @@ -333,9 +335,9 @@ cyber2000fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, } if (var->green.length >= 5 && regno < 32) { - cfb->palette[regno << 3].red = red; + cfb->palette[regno << 3].red = red; cfb->palette[regno << 3].green = green; - cfb->palette[regno << 3].blue = blue; + cfb->palette[regno << 3].blue = blue; /* * The 5 bits of each colour component are @@ -349,9 +351,9 @@ cyber2000fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, } if (var->green.length == 4 && regno < 16) { - cfb->palette[regno << 4].red = red; + cfb->palette[regno << 4].red = red; cfb->palette[regno << 4].green = green; - cfb->palette[regno << 4].blue = blue; + cfb->palette[regno << 4].blue = blue; /* * The 5 bits of each colour component are @@ -375,12 +377,12 @@ cyber2000fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, /* * True colour: - * n rl - * pixel --/--+--/--> red dac - * | gl - * +--/--> green dac - * | bl - * +--/--> blue dac + * n rl + * pixel --/--+--/--> red dac + * | gl + * +--/--> green dac + * | bl + * +--/--> blue dac * n = bpp, rl = red length, gl = green length, bl = blue length */ case FB_VISUAL_TRUECOLOR: @@ -492,9 +494,9 @@ static void cyber2000fb_set_timing(struct cfb_info *cfb, struct par_info *hw) /* PLL registers */ cyber2000_grphw(EXT_DCLK_MULT, hw->clock_mult, cfb); - cyber2000_grphw(EXT_DCLK_DIV, hw->clock_div, cfb); + cyber2000_grphw(EXT_DCLK_DIV, hw->clock_div, cfb); cyber2000_grphw(EXT_MCLK_MULT, cfb->mclk_mult, cfb); - cyber2000_grphw(EXT_MCLK_DIV, cfb->mclk_div, cfb); + cyber2000_grphw(EXT_MCLK_DIV, cfb->mclk_div, cfb); cyber2000_grphw(0x90, 0x01, cfb); cyber2000_grphw(0xb9, 0x80, cfb); cyber2000_grphw(0xb9, 0x00, cfb); @@ -513,8 +515,8 @@ static void cyber2000fb_set_timing(struct cfb_info *cfb, struct par_info *hw) /* * Set up accelerator registers */ - cyber2000fb_writew(hw->width, CO_REG_SRC_WIDTH, cfb); - cyber2000fb_writew(hw->width, CO_REG_DEST_WIDTH, cfb); + cyber2000fb_writew(hw->width, CO_REG_SRC_WIDTH, cfb); + cyber2000fb_writew(hw->width, CO_REG_DEST_WIDTH, cfb); cyber2000fb_writeb(hw->co_pixfmt, CO_REG_PIXFMT, cfb); } @@ -547,15 +549,15 @@ cyber2000fb_decode_crtc(struct par_info *hw, struct cfb_info *cfb, { u_int Htotal, Hblankend, Hsyncend; u_int Vtotal, Vdispend, Vblankstart, Vblankend, Vsyncstart, Vsyncend; -#define ENCODE_BIT(v, b1, m, b2) ((((v) >> (b1)) & (m)) << (b2)) +#define BIT(v,b1,m,b2) (((v >> b1) & m) << b2) hw->crtc[13] = hw->pitch; hw->crtc[17] = 0xe3; hw->crtc[14] = 0; hw->crtc[8] = 0; - Htotal = var->xres + var->right_margin + - var->hsync_len + var->left_margin; + Htotal = var->xres + var->right_margin + + var->hsync_len + var->left_margin; if (Htotal > 2080) return -EINVAL; @@ -565,15 +567,15 @@ cyber2000fb_decode_crtc(struct par_info *hw, struct cfb_info *cfb, hw->crtc[2] = var->xres >> 3; hw->crtc[4] = (var->xres + var->right_margin) >> 3; - Hblankend = (Htotal - 4 * 8) >> 3; + Hblankend = (Htotal - 4*8) >> 3; - hw->crtc[3] = ENCODE_BIT(Hblankend, 0, 0x1f, 0) | - ENCODE_BIT(1, 0, 0x01, 7); + hw->crtc[3] = BIT(Hblankend, 0, 0x1f, 0) | + BIT(1, 0, 0x01, 7); Hsyncend = (var->xres + var->right_margin + var->hsync_len) >> 3; - hw->crtc[5] = ENCODE_BIT(Hsyncend, 0, 0x1f, 0) | - ENCODE_BIT(Hblankend, 5, 0x01, 7); + hw->crtc[5] = BIT(Hsyncend, 0, 0x1f, 0) | + BIT(Hblankend, 5, 0x01, 7); Vdispend = var->yres - 1; Vsyncstart = var->yres + var->lower_margin; @@ -588,20 +590,20 @@ cyber2000fb_decode_crtc(struct par_info *hw, struct cfb_info *cfb, Vblankend = Vtotal - 10; hw->crtc[6] = Vtotal; - hw->crtc[7] = ENCODE_BIT(Vtotal, 8, 0x01, 0) | - ENCODE_BIT(Vdispend, 8, 0x01, 1) | - ENCODE_BIT(Vsyncstart, 8, 0x01, 2) | - ENCODE_BIT(Vblankstart, 8, 0x01, 3) | - ENCODE_BIT(1, 0, 0x01, 4) | - ENCODE_BIT(Vtotal, 9, 0x01, 5) | - ENCODE_BIT(Vdispend, 9, 0x01, 6) | - ENCODE_BIT(Vsyncstart, 9, 0x01, 7); - hw->crtc[9] = ENCODE_BIT(0, 0, 0x1f, 0) | - ENCODE_BIT(Vblankstart, 9, 0x01, 5) | - ENCODE_BIT(1, 0, 0x01, 6); + hw->crtc[7] = BIT(Vtotal, 8, 0x01, 0) | + BIT(Vdispend, 8, 0x01, 1) | + BIT(Vsyncstart, 8, 0x01, 2) | + BIT(Vblankstart,8, 0x01, 3) | + BIT(1, 0, 0x01, 4) | + BIT(Vtotal, 9, 0x01, 5) | + BIT(Vdispend, 9, 0x01, 6) | + BIT(Vsyncstart, 9, 0x01, 7); + hw->crtc[9] = BIT(0, 0, 0x1f, 0) | + BIT(Vblankstart,9, 0x01, 5) | + BIT(1, 0, 0x01, 6); hw->crtc[10] = Vsyncstart; - hw->crtc[11] = ENCODE_BIT(Vsyncend, 0, 0x0f, 0) | - ENCODE_BIT(1, 0, 0x01, 7); + hw->crtc[11] = BIT(Vsyncend, 0, 0x0f, 0) | + BIT(1, 0, 0x01, 7); hw->crtc[12] = Vdispend; hw->crtc[15] = Vblankstart; hw->crtc[16] = Vblankend; @@ -613,10 +615,10 @@ cyber2000fb_decode_crtc(struct par_info *hw, struct cfb_info *cfb, * 4=LINECOMP:10 5-IVIDEO 6=FIXCNT */ hw->crtc_ofl = - ENCODE_BIT(Vtotal, 10, 0x01, 0) | - ENCODE_BIT(Vdispend, 10, 0x01, 1) | - ENCODE_BIT(Vsyncstart, 10, 0x01, 2) | - ENCODE_BIT(Vblankstart, 10, 0x01, 3) | + BIT(Vtotal, 10, 0x01, 0) | + BIT(Vdispend, 10, 0x01, 1) | + BIT(Vsyncstart, 10, 0x01, 2) | + BIT(Vblankstart,10, 0x01, 3) | EXT_CRT_VRTOFL_LINECOMP10; /* woody: set the interlaced bit... */ @@ -748,11 +750,11 @@ cyber2000fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) var->red.msb_right = 0; var->green.msb_right = 0; var->blue.msb_right = 0; - var->transp.offset = 0; - var->transp.length = 0; switch (var->bits_per_pixel) { case 8: /* PSEUDOCOLOUR, 256 */ + var->transp.offset = 0; + var->transp.length = 0; var->red.offset = 0; var->red.length = 8; var->green.offset = 0; @@ -764,6 +766,8 @@ cyber2000fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) case 16:/* DIRECTCOLOUR, 64k or 32k */ switch (var->green.length) { case 6: /* RGB565, 64k */ + var->transp.offset = 0; + var->transp.length = 0; var->red.offset = 11; var->red.length = 5; var->green.offset = 5; @@ -774,6 +778,8 @@ cyber2000fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) default: case 5: /* RGB555, 32k */ + var->transp.offset = 0; + var->transp.length = 0; var->red.offset = 10; var->red.length = 5; var->green.offset = 5; @@ -796,6 +802,8 @@ cyber2000fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) break; case 24:/* TRUECOLOUR, 16m */ + var->transp.offset = 0; + var->transp.length = 0; var->red.offset = 16; var->red.length = 8; var->green.offset = 8; @@ -822,7 +830,7 @@ cyber2000fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) mem = var->xres_virtual * var->yres_virtual * (var->bits_per_pixel / 8); if (mem > cfb->fb.fix.smem_len) var->yres_virtual = cfb->fb.fix.smem_len * 8 / - (var->bits_per_pixel * var->xres_virtual); + (var->bits_per_pixel * var->xres_virtual); if (var->yres > var->yres_virtual) var->yres = var->yres_virtual; @@ -913,7 +921,7 @@ static int cyber2000fb_set_par(struct fb_info *info) hw.fetch <<= 1; hw.fetch += 1; - cfb->fb.fix.line_length = var->xres_virtual * var->bits_per_pixel / 8; + cfb->fb.fix.line_length = var->xres_virtual * var->bits_per_pixel / 8; /* * Same here - if the size of the video mode exceeds the @@ -944,6 +952,7 @@ static int cyber2000fb_set_par(struct fb_info *info) return 0; } + /* * Pan or Wrap the Display */ @@ -993,15 +1002,15 @@ static int cyber2000fb_blank(int blank, struct fb_info *info) switch (blank) { case FB_BLANK_POWERDOWN: /* powerdown - both sync lines down */ sync = EXT_SYNC_CTL_VS_0 | EXT_SYNC_CTL_HS_0; - break; + break; case FB_BLANK_HSYNC_SUSPEND: /* hsync off */ sync = EXT_SYNC_CTL_VS_NORMAL | EXT_SYNC_CTL_HS_0; - break; + break; case FB_BLANK_VSYNC_SUSPEND: /* vsync off */ sync = EXT_SYNC_CTL_VS_0 | EXT_SYNC_CTL_HS_NORMAL; break; - case FB_BLANK_NORMAL: /* soft blank */ - default: /* unblank */ + case FB_BLANK_NORMAL: /* soft blank */ + default: /* unblank */ break; } @@ -1009,8 +1018,7 @@ static int cyber2000fb_blank(int blank, struct fb_info *info) if (blank <= 1) { /* turn on ramdacs */ - cfb->ramdac_powerdown &= ~(RAMDAC_DACPWRDN | RAMDAC_BYPASS | - RAMDAC_RAMPWRDN); + cfb->ramdac_powerdown &= ~(RAMDAC_DACPWRDN | RAMDAC_BYPASS | RAMDAC_RAMPWRDN); cyber2000fb_write_ramdac_ctrl(cfb); } @@ -1035,8 +1043,7 @@ static int cyber2000fb_blank(int blank, struct fb_info *info) if (blank >= 2) { /* turn off ramdacs */ - cfb->ramdac_powerdown |= RAMDAC_DACPWRDN | RAMDAC_BYPASS | - RAMDAC_RAMPWRDN; + cfb->ramdac_powerdown |= RAMDAC_DACPWRDN | RAMDAC_BYPASS | RAMDAC_RAMPWRDN; cyber2000fb_write_ramdac_ctrl(cfb); } @@ -1061,7 +1068,7 @@ static struct fb_ops cyber2000fb_ops = { * of this driver. It is here solely at the moment to support the other * CyberPro modules external to this driver. */ -static struct cfb_info *int_cfb_info; +static struct cfb_info *int_cfb_info; /* * Enable access to the extended registers @@ -1078,7 +1085,6 @@ void cyber2000fb_enable_extregs(struct cfb_info *cfb) cyber2000_grphw(EXT_FUNC_CTL, old, cfb); } } -EXPORT_SYMBOL(cyber2000fb_enable_extregs); /* * Disable access to the extended registers @@ -1098,13 +1104,11 @@ void cyber2000fb_disable_extregs(struct cfb_info *cfb) else cfb->func_use_count -= 1; } -EXPORT_SYMBOL(cyber2000fb_disable_extregs); void cyber2000fb_get_fb_var(struct cfb_info *cfb, struct fb_var_screeninfo *var) { memcpy(var, &cfb->fb.var, sizeof(struct fb_var_screeninfo)); } -EXPORT_SYMBOL(cyber2000fb_get_fb_var); /* * Attach a capture/tv driver to the core CyberX0X0 driver. @@ -1118,15 +1122,13 @@ int cyber2000fb_attach(struct cyberpro_info *info, int idx) info->fb_size = int_cfb_info->fb.fix.smem_len; info->enable_extregs = cyber2000fb_enable_extregs; info->disable_extregs = cyber2000fb_disable_extregs; - info->info = int_cfb_info; + info->info = int_cfb_info; - strlcpy(info->dev_name, int_cfb_info->fb.fix.id, - sizeof(info->dev_name)); + strlcpy(info->dev_name, int_cfb_info->fb.fix.id, sizeof(info->dev_name)); } return int_cfb_info != NULL; } -EXPORT_SYMBOL(cyber2000fb_attach); /* * Detach a capture/tv driver from the core CyberX0X0 driver. @@ -1134,7 +1136,12 @@ EXPORT_SYMBOL(cyber2000fb_attach); void cyber2000fb_detach(int idx) { } + +EXPORT_SYMBOL(cyber2000fb_attach); EXPORT_SYMBOL(cyber2000fb_detach); +EXPORT_SYMBOL(cyber2000fb_enable_extregs); +EXPORT_SYMBOL(cyber2000fb_disable_extregs); +EXPORT_SYMBOL(cyber2000fb_get_fb_var); /* * These parameters give @@ -1198,7 +1205,7 @@ static void cyberpro_init_hw(struct cfb_info *cfb) int i; for (i = 0; i < sizeof(igs_regs); i += 2) - cyber2000_grphw(igs_regs[i], igs_regs[i + 1], cfb); + cyber2000_grphw(igs_regs[i], igs_regs[i+1], cfb); if (cfb->id == ID_CYBERPRO_5000) { unsigned char val; @@ -1208,8 +1215,8 @@ static void cyberpro_init_hw(struct cfb_info *cfb) } } -static struct cfb_info __devinit *cyberpro_alloc_fb_info(unsigned int id, - char *name) +static struct cfb_info * __devinit +cyberpro_alloc_fb_info(unsigned int id, char *name) { struct cfb_info *cfb; @@ -1221,9 +1228,9 @@ static struct cfb_info __devinit *cyberpro_alloc_fb_info(unsigned int id, cfb->id = id; if (id == ID_CYBERPRO_5000) - cfb->ref_ps = 40690; /* 24.576 MHz */ + cfb->ref_ps = 40690; // 24.576 MHz else - cfb->ref_ps = 69842; /* 14.31818 MHz (69841?) */ + cfb->ref_ps = 69842; // 14.31818 MHz (69841?) cfb->divisors[0] = 1; cfb->divisors[1] = 2; @@ -1275,7 +1282,8 @@ static struct cfb_info __devinit *cyberpro_alloc_fb_info(unsigned int id, return cfb; } -static void cyberpro_free_fb_info(struct cfb_info *cfb) +static void +cyberpro_free_fb_info(struct cfb_info *cfb) { if (cfb) { /* @@ -1292,7 +1300,8 @@ static void cyberpro_free_fb_info(struct cfb_info *cfb) * video=cyber2000:font:fontname */ #ifndef MODULE -static int cyber2000fb_setup(char *options) +static int +cyber2000fb_setup(char *options) { char *opt; @@ -1306,8 +1315,7 @@ static int cyber2000fb_setup(char *options) if (strncmp(opt, "font:", 5) == 0) { static char default_font_storage[40]; - strlcpy(default_font_storage, opt + 5, - sizeof(default_font_storage)); + strlcpy(default_font_storage, opt + 5, sizeof(default_font_storage)); default_font = default_font_storage; continue; } @@ -1346,18 +1354,10 @@ static int __devinit cyberpro_common_probe(struct cfb_info *cfb) * Determine the size of the memory. */ switch (cfb->mem_ctl2 & MEM_CTL2_SIZE_MASK) { - case MEM_CTL2_SIZE_4MB: - smem_size = 0x00400000; - break; - case MEM_CTL2_SIZE_2MB: - smem_size = 0x00200000; - break; - case MEM_CTL2_SIZE_1MB: - smem_size = 0x00100000; - break; - default: - smem_size = 0x00100000; - break; + case MEM_CTL2_SIZE_4MB: smem_size = 0x00400000; break; + case MEM_CTL2_SIZE_2MB: smem_size = 0x00200000; break; + case MEM_CTL2_SIZE_1MB: smem_size = 0x00100000; break; + default: smem_size = 0x00100000; break; } cfb->fb.fix.smem_len = smem_size; @@ -1366,8 +1366,8 @@ static int __devinit cyberpro_common_probe(struct cfb_info *cfb) err = -EINVAL; if (!fb_find_mode(&cfb->fb.var, &cfb->fb, NULL, NULL, 0, - &cyber2000fb_default_mode, 8)) { - printk(KERN_ERR "%s: no valid mode found\n", cfb->fb.fix.id); + &cyber2000fb_default_mode, 8)) { + printk("%s: no valid mode found\n", cfb->fb.fix.id); goto failed; } @@ -1377,7 +1377,7 @@ static int __devinit cyberpro_common_probe(struct cfb_info *cfb) if (cfb->fb.var.yres_virtual < cfb->fb.var.yres) cfb->fb.var.yres_virtual = cfb->fb.var.yres; -/* fb_set_var(&cfb->fb.var, -1, &cfb->fb); */ +// fb_set_var(&cfb->fb.var, -1, &cfb->fb); /* * Calculate the hsync and vsync frequencies. Note that @@ -1425,20 +1425,20 @@ static void cyberpro_common_resume(struct cfb_info *cfb) #include -static int __devinit cyberpro_vl_probe(void) +static int __devinit +cyberpro_vl_probe(void) { struct cfb_info *cfb; int err = -ENOMEM; - if (!request_mem_region(FB_START, FB_SIZE, "CyberPro2010")) - return err; + if (!request_mem_region(FB_START,FB_SIZE,"CyberPro2010")) return err; cfb = cyberpro_alloc_fb_info(ID_CYBERPRO_2010, "CyberPro2010"); if (!cfb) goto failed_release; cfb->dev = NULL; - cfb->region = ioremap(FB_START, FB_SIZE); + cfb->region = ioremap(FB_START,FB_SIZE); if (!cfb->region) goto failed_ioremap; @@ -1475,7 +1475,7 @@ static int __devinit cyberpro_vl_probe(void) failed_ioremap: cyberpro_free_fb_info(cfb); failed_release: - release_mem_region(FB_START, FB_SIZE); + release_mem_region(FB_START,FB_SIZE); return err; } @@ -1538,8 +1538,7 @@ static int cyberpro_pci_enable_mmio(struct cfb_info *cfb) * Allow the CyberPro to accept PCI burst accesses */ if (cfb->id == ID_CYBERPRO_2010) { - printk(KERN_INFO "%s: NOT enabling PCI bursts\n", - cfb->fb.fix.id); + printk(KERN_INFO "%s: NOT enabling PCI bursts\n", cfb->fb.fix.id); } else { val = cyber2000_grphr(EXT_BUS_CTL, cfb); if (!(val & EXT_BUS_CTL_PCIBURST_WRITE)) { @@ -1689,10 +1688,9 @@ static int cyberpro_pci_resume(struct pci_dev *dev) } static struct pci_device_id cyberpro_pci_table[] = { -/* Not yet - * { PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_1682, - * PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_IGA_1682 }, - */ +// Not yet +// { PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_1682, +// PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_IGA_1682 }, { PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_2000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_CYBERPRO_2000 }, { PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_2010, @@ -1702,7 +1700,7 @@ static struct pci_device_id cyberpro_pci_table[] = { { 0, } }; -MODULE_DEVICE_TABLE(pci, cyberpro_pci_table); +MODULE_DEVICE_TABLE(pci,cyberpro_pci_table); static struct pci_driver cyberpro_driver = { .name = "CyberPro", diff --git a/trunk/drivers/video/gxt4500.c b/trunk/drivers/video/gxt4500.c index e92337bef50d..23a6bcc3e3ce 100644 --- a/trunk/drivers/video/gxt4500.c +++ b/trunk/drivers/video/gxt4500.c @@ -636,7 +636,7 @@ static int __devinit gxt4500_probe(struct pci_dev *pdev, info = framebuffer_alloc(sizeof(struct gxt4500_par), &pdev->dev); if (!info) { - dev_err(&pdev->dev, "gxt4500: cannot alloc FB info record\n"); + dev_err(&pdev->dev, "gxt4500: cannot alloc FB info record"); goto err_free_fb; } par = info->par; diff --git a/trunk/drivers/video/logo/logo.c b/trunk/drivers/video/logo/logo.c index fc72684aae5a..a9283bae7790 100644 --- a/trunk/drivers/video/logo/logo.c +++ b/trunk/drivers/video/logo/logo.c @@ -78,7 +78,10 @@ const struct linux_logo * __init_refok fb_find_logo(int depth) #endif #ifdef CONFIG_LOGO_DEC_CLUT224 /* DEC Linux logo on MIPS/MIPS64 or ALPHA */ - logo = &logo_dec_clut224; +#ifndef CONFIG_ALPHA + if (mips_machgroup == MACH_GROUP_DEC) +#endif + logo = &logo_dec_clut224; #endif #ifdef CONFIG_LOGO_MAC_CLUT224 /* Macintosh Linux logo on m68k */ @@ -91,7 +94,10 @@ const struct linux_logo * __init_refok fb_find_logo(int depth) #endif #ifdef CONFIG_LOGO_SGI_CLUT224 /* SGI Linux logo on MIPS/MIPS64 and VISWS */ - logo = &logo_sgi_clut224; +#ifndef CONFIG_X86_VISWS + if (mips_machgroup == MACH_GROUP_SGI) +#endif + logo = &logo_sgi_clut224; #endif #ifdef CONFIG_LOGO_SUN_CLUT224 /* Sun Linux logo */ diff --git a/trunk/drivers/video/modedb.c b/trunk/drivers/video/modedb.c index 8d81ef019c6c..42f5d76a8777 100644 --- a/trunk/drivers/video/modedb.c +++ b/trunk/drivers/video/modedb.c @@ -510,9 +510,7 @@ int fb_find_mode(struct fb_var_screeninfo *var, default_bpp = 8; /* Did the user specify a video mode? */ - if (!mode_option) - mode_option = fb_mode_option; - if (mode_option) { + if (mode_option || (mode_option = fb_mode_option)) { const char *name = mode_option; unsigned int namelen = strlen(name); int res_specified = 0, bpp_specified = 0, refresh_specified = 0; diff --git a/trunk/drivers/video/omap/blizzard.c b/trunk/drivers/video/omap/blizzard.c index 4d8ad9cd0e19..e682940a97a4 100644 --- a/trunk/drivers/video/omap/blizzard.c +++ b/trunk/drivers/video/omap/blizzard.c @@ -225,7 +225,7 @@ static void blizzard_restart_sdram(void) while (!(blizzard_read_reg(BLIZZARD_MEM_BANK0_STATUS) & 0x01)) { if (time_after(jiffies, tmo)) { dev_err(blizzard.fbdev->dev, - "s1d1374x: SDRAM not ready\n"); + "s1d1374x: SDRAM not ready"); break; } msleep(1); diff --git a/trunk/drivers/video/omap/dispc.c b/trunk/drivers/video/omap/dispc.c index ab32ceb06178..f4c23434de6f 100644 --- a/trunk/drivers/video/omap/dispc.c +++ b/trunk/drivers/video/omap/dispc.c @@ -880,19 +880,19 @@ static irqreturn_t omap_dispc_irq_handler(int irq, void *dev) static int get_dss_clocks(void) { if (IS_ERR((dispc.dss_ick = clk_get(dispc.fbdev->dev, "dss_ick")))) { - dev_err(dispc.fbdev->dev, "can't get dss_ick\n"); + dev_err(dispc.fbdev->dev, "can't get dss_ick"); return PTR_ERR(dispc.dss_ick); } if (IS_ERR((dispc.dss1_fck = clk_get(dispc.fbdev->dev, "dss1_fck")))) { - dev_err(dispc.fbdev->dev, "can't get dss1_fck\n"); + dev_err(dispc.fbdev->dev, "can't get dss1_fck"); clk_put(dispc.dss_ick); return PTR_ERR(dispc.dss1_fck); } if (IS_ERR((dispc.dss_54m_fck = clk_get(dispc.fbdev->dev, "dss_54m_fck")))) { - dev_err(dispc.fbdev->dev, "can't get dss_54m_fck\n"); + dev_err(dispc.fbdev->dev, "can't get dss_54m_fck"); clk_put(dispc.dss_ick); clk_put(dispc.dss1_fck); return PTR_ERR(dispc.dss_54m_fck); diff --git a/trunk/drivers/video/omap/hwa742.c b/trunk/drivers/video/omap/hwa742.c index 1e642b7a20fe..dc48e02f215c 100644 --- a/trunk/drivers/video/omap/hwa742.c +++ b/trunk/drivers/video/omap/hwa742.c @@ -508,7 +508,7 @@ int hwa742_update_window_async(struct fb_info *fbi, if (unlikely(win->format & ~(0x03 | OMAPFB_FORMAT_FLAG_DOUBLE | OMAPFB_FORMAT_FLAG_TEARSYNC | OMAPFB_FORMAT_FLAG_FORCE_VSYNC))) { - dev_dbg(hwa742.fbdev->dev, "invalid window flag\n"); + dev_dbg(hwa742.fbdev->dev, "invalid window flag"); r = -EINVAL; goto out; } diff --git a/trunk/drivers/video/omap/rfbi.c b/trunk/drivers/video/omap/rfbi.c index 789cfd23c36b..2b4269813b22 100644 --- a/trunk/drivers/video/omap/rfbi.c +++ b/trunk/drivers/video/omap/rfbi.c @@ -84,12 +84,12 @@ static inline u32 rfbi_read_reg(int idx) static int rfbi_get_clocks(void) { if (IS_ERR((rfbi.dss_ick = clk_get(rfbi.fbdev->dev, "dss_ick")))) { - dev_err(rfbi.fbdev->dev, "can't get dss_ick\n"); + dev_err(rfbi.fbdev->dev, "can't get dss_ick"); return PTR_ERR(rfbi.dss_ick); } if (IS_ERR((rfbi.dss1_fck = clk_get(rfbi.fbdev->dev, "dss1_fck")))) { - dev_err(rfbi.fbdev->dev, "can't get dss1_fck\n"); + dev_err(rfbi.fbdev->dev, "can't get dss1_fck"); clk_put(rfbi.dss_ick); return PTR_ERR(rfbi.dss1_fck); } diff --git a/trunk/drivers/video/pnx4008/sdum.h b/trunk/drivers/video/pnx4008/sdum.h index 189c3d641383..e8c5dcdd8813 100644 --- a/trunk/drivers/video/pnx4008/sdum.h +++ b/trunk/drivers/video/pnx4008/sdum.h @@ -77,6 +77,9 @@ #define CONF_DIRTYDETECTION_OFF (0x600) #define CONF_DIRTYDETECTION_ON (0x601) +/* Set the corresponding bit. */ +#define BIT(n) (0x1U << (n)) + struct dumchannel_uf { int channelnr; u32 *dirty; diff --git a/trunk/drivers/w1/masters/ds1wm.c b/trunk/drivers/w1/masters/ds1wm.c index 5747997f8d7d..4b696641ce33 100644 --- a/trunk/drivers/w1/masters/ds1wm.c +++ b/trunk/drivers/w1/masters/ds1wm.c @@ -307,7 +307,7 @@ static void ds1wm_search(void *data, u8 search_type, rom_id |= (unsigned long long) r << (i * 4); } - dev_dbg(&ds1wm_data->pdev->dev, "found 0x%08llX\n", rom_id); + dev_dbg(&ds1wm_data->pdev->dev, "found 0x%08llX", rom_id); ds1wm_write_register(ds1wm_data, DS1WM_CMD, ~DS1WM_CMD_SRA); ds1wm_reset(ds1wm_data); diff --git a/trunk/drivers/xen/xenbus/xenbus_probe.c b/trunk/drivers/xen/xenbus/xenbus_probe.c index 4750de316ad3..0b769f7c4a48 100644 --- a/trunk/drivers/xen/xenbus/xenbus_probe.c +++ b/trunk/drivers/xen/xenbus/xenbus_probe.c @@ -185,14 +185,13 @@ static void otherend_changed(struct xenbus_watch *watch, if (!dev->otherend || strncmp(dev->otherend, vec[XS_WATCH_PATH], strlen(dev->otherend))) { - dev_dbg(&dev->dev, "Ignoring watch at %s\n", - vec[XS_WATCH_PATH]); + dev_dbg(&dev->dev, "Ignoring watch at %s", vec[XS_WATCH_PATH]); return; } state = xenbus_read_driver_state(dev->otherend); - dev_dbg(&dev->dev, "state is %d, (%s), %s, %s\n", + dev_dbg(&dev->dev, "state is %d, (%s), %s, %s", state, xenbus_strstate(state), dev->otherend_watch.node, vec[XS_WATCH_PATH]); diff --git a/trunk/fs/Kconfig b/trunk/fs/Kconfig index cc28a69246a7..d8062745716a 100644 --- a/trunk/fs/Kconfig +++ b/trunk/fs/Kconfig @@ -140,7 +140,6 @@ config EXT4DEV_FS tristate "Ext4dev/ext4 extended fs support development (EXPERIMENTAL)" depends on EXPERIMENTAL select JBD2 - select CRC16 help Ext4dev is a predecessor filesystem of the next generation extended fs ext4, based on ext3 filesystem code. It will be @@ -220,7 +219,7 @@ config JBD config JBD_DEBUG bool "JBD (ext3) debugging support" - depends on JBD && DEBUG_FS + depends on JBD help If you are using the ext3 journaled file system (or potentially any other file system/device using JBD), this option allows you to @@ -229,10 +228,10 @@ config JBD_DEBUG debugging output will be turned off. If you select Y here, then you will be able to turn on debugging - with "echo N > /sys/kernel/debug/jbd/jbd-debug", where N is a - number between 1 and 5, the higher the number, the more debugging - output is generated. To turn debugging off again, do - "echo 0 > /sys/kernel/debug/jbd/jbd-debug". + with "echo N > /proc/sys/fs/jbd-debug", where N is a number between + 1 and 5, the higher the number, the more debugging output is + generated. To turn debugging off again, do + "echo 0 > /proc/sys/fs/jbd-debug". config JBD2 tristate diff --git a/trunk/fs/aio.c b/trunk/fs/aio.c index f12db415c0f6..d02f43b50a3d 100644 --- a/trunk/fs/aio.c +++ b/trunk/fs/aio.c @@ -710,9 +710,18 @@ static ssize_t aio_run_iocb(struct kiocb *iocb) /* * Now we are all set to call the retry method in async - * context. + * context. By setting this thread's io_wait context + * to point to the wait queue entry inside the currently + * running iocb for the duration of the retry, we ensure + * that async notification wakeups are queued by the + * operation instead of blocking waits, and when notified, + * cause the iocb to be kicked for continuation (through + * the aio_wake_function callback). */ + BUG_ON(current->io_wait != NULL); + current->io_wait = &iocb->ki_wait; ret = retry(iocb); + current->io_wait = NULL; if (ret != -EIOCBRETRY && ret != -EIOCBQUEUED) { BUG_ON(!list_empty(&iocb->ki_wait.task_list)); @@ -1499,7 +1508,10 @@ static ssize_t aio_setup_iocb(struct kiocb *kiocb) * Simply triggers a retry of the operation via kick_iocb. * * This callback is specified in the wait queue entry in - * a kiocb. + * a kiocb (current->io_wait points to this wait queue + * entry when an aio operation executes; it is used + * instead of a synchronous wait when an i/o blocking + * condition is encountered during aio). * * Note: * This routine is executed with the wait queue lock held. diff --git a/trunk/fs/attr.c b/trunk/fs/attr.c index 966b73e25f82..ae58bd3f875f 100644 --- a/trunk/fs/attr.c +++ b/trunk/fs/attr.c @@ -103,11 +103,12 @@ EXPORT_SYMBOL(inode_setattr); int notify_change(struct dentry * dentry, struct iattr * attr) { struct inode *inode = dentry->d_inode; - mode_t mode = inode->i_mode; + mode_t mode; int error; struct timespec now; unsigned int ia_valid = attr->ia_valid; + mode = inode->i_mode; now = current_fs_time(inode->i_sb); attr->ia_ctime = now; @@ -124,25 +125,18 @@ int notify_change(struct dentry * dentry, struct iattr * attr) if (error) return error; } - - /* - * We now pass ATTR_KILL_S*ID to the lower level setattr function so - * that the function has the ability to reinterpret a mode change - * that's due to these bits. This adds an implicit restriction that - * no function will ever call notify_change with both ATTR_MODE and - * ATTR_KILL_S*ID set. - */ - if ((ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID)) && - (ia_valid & ATTR_MODE)) - BUG(); - if (ia_valid & ATTR_KILL_SUID) { + attr->ia_valid &= ~ATTR_KILL_SUID; if (mode & S_ISUID) { - ia_valid = attr->ia_valid |= ATTR_MODE; - attr->ia_mode = (inode->i_mode & ~S_ISUID); + if (!(ia_valid & ATTR_MODE)) { + ia_valid = attr->ia_valid |= ATTR_MODE; + attr->ia_mode = inode->i_mode; + } + attr->ia_mode &= ~S_ISUID; } } if (ia_valid & ATTR_KILL_SGID) { + attr->ia_valid &= ~ ATTR_KILL_SGID; if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) { if (!(ia_valid & ATTR_MODE)) { ia_valid = attr->ia_valid |= ATTR_MODE; @@ -151,7 +145,7 @@ int notify_change(struct dentry * dentry, struct iattr * attr) attr->ia_mode &= ~S_ISGID; } } - if (!(attr->ia_valid & ~(ATTR_KILL_SUID | ATTR_KILL_SGID))) + if (!attr->ia_valid) return 0; if (ia_valid & ATTR_SIZE) diff --git a/trunk/fs/autofs/inode.c b/trunk/fs/autofs/inode.c index 45f5992a0957..e7204d71acc9 100644 --- a/trunk/fs/autofs/inode.c +++ b/trunk/fs/autofs/inode.c @@ -80,7 +80,7 @@ static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid, *uid = current->uid; *gid = current->gid; - *pgrp = task_pgrp_nr(current); + *pgrp = process_group(current); *minproto = *maxproto = AUTOFS_PROTO_VERSION; diff --git a/trunk/fs/autofs/root.c b/trunk/fs/autofs/root.c index 5efff3c0d886..c1489533277a 100644 --- a/trunk/fs/autofs/root.c +++ b/trunk/fs/autofs/root.c @@ -214,8 +214,8 @@ static struct dentry *autofs_root_lookup(struct inode *dir, struct dentry *dentr oz_mode = autofs_oz_mode(sbi); DPRINTK(("autofs_lookup: pid = %u, pgrp = %u, catatonic = %d, " - "oz_mode = %d\n", task_pid_nr(current), - task_pgrp_nr(current), sbi->catatonic, + "oz_mode = %d\n", pid_nr(task_pid(current)), + process_group(current), sbi->catatonic, oz_mode)); /* @@ -536,7 +536,7 @@ static int autofs_root_ioctl(struct inode *inode, struct file *filp, struct autofs_sb_info *sbi = autofs_sbi(inode->i_sb); void __user *argp = (void __user *)arg; - DPRINTK(("autofs_ioctl: cmd = 0x%08x, arg = 0x%08lx, sbi = %p, pgrp = %u\n",cmd,arg,sbi,task_pgrp_nr(current))); + DPRINTK(("autofs_ioctl: cmd = 0x%08x, arg = 0x%08lx, sbi = %p, pgrp = %u\n",cmd,arg,sbi,process_group(current))); if (_IOC_TYPE(cmd) != _IOC_TYPE(AUTOFS_IOC_FIRST) || _IOC_NR(cmd) - _IOC_NR(AUTOFS_IOC_FIRST) >= AUTOFS_IOC_COUNT) diff --git a/trunk/fs/autofs/waitq.c b/trunk/fs/autofs/waitq.c index be46805972f0..19a9cafb5ddf 100644 --- a/trunk/fs/autofs/waitq.c +++ b/trunk/fs/autofs/waitq.c @@ -182,7 +182,7 @@ int autofs_wait_release(struct autofs_sb_info *sbi, autofs_wqt_t wait_queue_toke { struct autofs_wait_queue *wq, **wql; - for (wql = &sbi->queues; (wq = *wql) != NULL; wql = &wq->next) { + for ( wql = &sbi->queues ; (wq = *wql) != 0 ; wql = &wq->next ) { if ( wq->wait_queue_token == wait_queue_token ) break; } diff --git a/trunk/fs/autofs4/autofs_i.h b/trunk/fs/autofs4/autofs_i.h index 2d4ae40718d9..d85f42fa9206 100644 --- a/trunk/fs/autofs4/autofs_i.h +++ b/trunk/fs/autofs4/autofs_i.h @@ -131,7 +131,7 @@ static inline struct autofs_info *autofs4_dentry_ino(struct dentry *dentry) filesystem without "magic".) */ static inline int autofs4_oz_mode(struct autofs_sb_info *sbi) { - return sbi->catatonic || task_pgrp_nr(current) == sbi->oz_pgrp; + return sbi->catatonic || process_group(current) == sbi->oz_pgrp; } /* Does a dentry have some pending activity? */ diff --git a/trunk/fs/autofs4/inode.c b/trunk/fs/autofs4/inode.c index 7f05d6ccdb13..cd81f0836671 100644 --- a/trunk/fs/autofs4/inode.c +++ b/trunk/fs/autofs4/inode.c @@ -226,7 +226,7 @@ static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid, *uid = current->uid; *gid = current->gid; - *pgrp = task_pgrp_nr(current); + *pgrp = process_group(current); *minproto = AUTOFS_MIN_PROTO_VERSION; *maxproto = AUTOFS_MAX_PROTO_VERSION; @@ -323,7 +323,7 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent) sbi->pipe = NULL; sbi->catatonic = 1; sbi->exp_timeout = 0; - sbi->oz_pgrp = task_pgrp_nr(current); + sbi->oz_pgrp = process_group(current); sbi->sb = s; sbi->version = 0; sbi->sub_version = 0; diff --git a/trunk/fs/autofs4/root.c b/trunk/fs/autofs4/root.c index 2bbcc8151dc3..45ff3d63b758 100644 --- a/trunk/fs/autofs4/root.c +++ b/trunk/fs/autofs4/root.c @@ -582,7 +582,7 @@ static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, s oz_mode = autofs4_oz_mode(sbi); DPRINTK("pid = %u, pgrp = %u, catatonic = %d, oz_mode = %d", - current->pid, task_pgrp_nr(current), sbi->catatonic, oz_mode); + current->pid, process_group(current), sbi->catatonic, oz_mode); unhashed = autofs4_lookup_unhashed(sbi, dentry->d_parent, &dentry->d_name); if (!unhashed) { @@ -976,7 +976,7 @@ static int autofs4_root_ioctl(struct inode *inode, struct file *filp, void __user *p = (void __user *)arg; DPRINTK("cmd = 0x%08x, arg = 0x%08lx, sbi = %p, pgrp = %u", - cmd,arg,sbi,task_pgrp_nr(current)); + cmd,arg,sbi,process_group(current)); if (_IOC_TYPE(cmd) != _IOC_TYPE(AUTOFS_IOC_FIRST) || _IOC_NR(cmd) - _IOC_NR(AUTOFS_IOC_FIRST) >= AUTOFS_IOC_COUNT) diff --git a/trunk/fs/autofs4/waitq.c b/trunk/fs/autofs4/waitq.c index 1fe28e4754c2..0d041a9cb348 100644 --- a/trunk/fs/autofs4/waitq.c +++ b/trunk/fs/autofs4/waitq.c @@ -376,7 +376,7 @@ int autofs4_wait_release(struct autofs_sb_info *sbi, autofs_wqt_t wait_queue_tok struct autofs_wait_queue *wq, **wql; mutex_lock(&sbi->wq_mutex); - for (wql = &sbi->queues; (wq = *wql) != NULL; wql = &wq->next) { + for (wql = &sbi->queues ; (wq = *wql) != 0 ; wql = &wq->next) { if (wq->wait_queue_token == wait_queue_token) break; } diff --git a/trunk/fs/binfmt_elf.c b/trunk/fs/binfmt_elf.c index ba8de7ca260b..6e2f3b8dde7f 100644 --- a/trunk/fs/binfmt_elf.c +++ b/trunk/fs/binfmt_elf.c @@ -1383,10 +1383,10 @@ static void fill_prstatus(struct elf_prstatus *prstatus, prstatus->pr_info.si_signo = prstatus->pr_cursig = signr; prstatus->pr_sigpend = p->pending.signal.sig[0]; prstatus->pr_sighold = p->blocked.sig[0]; - prstatus->pr_pid = task_pid_vnr(p); - prstatus->pr_ppid = task_pid_vnr(p->parent); - prstatus->pr_pgrp = task_pgrp_vnr(p); - prstatus->pr_sid = task_session_vnr(p); + prstatus->pr_pid = p->pid; + prstatus->pr_ppid = p->parent->pid; + prstatus->pr_pgrp = process_group(p); + prstatus->pr_sid = process_session(p); if (thread_group_leader(p)) { /* * This is the record for the group leader. Add in the @@ -1429,10 +1429,10 @@ static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p, psinfo->pr_psargs[i] = ' '; psinfo->pr_psargs[len] = 0; - psinfo->pr_pid = task_pid_vnr(p); - psinfo->pr_ppid = task_pid_vnr(p->parent); - psinfo->pr_pgrp = task_pgrp_vnr(p); - psinfo->pr_sid = task_session_vnr(p); + psinfo->pr_pid = p->pid; + psinfo->pr_ppid = p->parent->pid; + psinfo->pr_pgrp = process_group(p); + psinfo->pr_sid = process_session(p); i = p->state ? ffz(~p->state) + 1 : 0; psinfo->pr_state = i; diff --git a/trunk/fs/binfmt_elf_fdpic.c b/trunk/fs/binfmt_elf_fdpic.c index 32649f2a1654..033861c6b8f1 100644 --- a/trunk/fs/binfmt_elf_fdpic.c +++ b/trunk/fs/binfmt_elf_fdpic.c @@ -1342,10 +1342,10 @@ static void fill_prstatus(struct elf_prstatus *prstatus, prstatus->pr_info.si_signo = prstatus->pr_cursig = signr; prstatus->pr_sigpend = p->pending.signal.sig[0]; prstatus->pr_sighold = p->blocked.sig[0]; - prstatus->pr_pid = task_pid_vnr(p); - prstatus->pr_ppid = task_pid_vnr(p->parent); - prstatus->pr_pgrp = task_pgrp_vnr(p); - prstatus->pr_sid = task_session_vnr(p); + prstatus->pr_pid = p->pid; + prstatus->pr_ppid = p->parent->pid; + prstatus->pr_pgrp = process_group(p); + prstatus->pr_sid = process_session(p); if (thread_group_leader(p)) { /* * This is the record for the group leader. Add in the @@ -1391,10 +1391,10 @@ static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p, psinfo->pr_psargs[i] = ' '; psinfo->pr_psargs[len] = 0; - psinfo->pr_pid = task_pid_vnr(p); - psinfo->pr_ppid = task_pid_vnr(p->parent); - psinfo->pr_pgrp = task_pgrp_vnr(p); - psinfo->pr_sid = task_session_vnr(p); + psinfo->pr_pid = p->pid; + psinfo->pr_ppid = p->parent->pid; + psinfo->pr_pgrp = process_group(p); + psinfo->pr_sid = process_session(p); i = p->state ? ffz(~p->state) + 1 : 0; psinfo->pr_state = i; diff --git a/trunk/fs/cifs/CHANGES b/trunk/fs/cifs/CHANGES index 3d419163c3d3..bed6215c0794 100644 --- a/trunk/fs/cifs/CHANGES +++ b/trunk/fs/cifs/CHANGES @@ -1,19 +1,3 @@ -Version 1.51 ------------- -Fix memory leak in statfs when mounted to very old servers (e.g. -Windows 9x). Add new feature "POSIX open" which allows servers -which support the current POSIX Extensions to provide better semantics -(e.g. delete for open files opened with posix open). Take into -account umask on posix mkdir not just older style mkdir. Add -ability to mount to IPC$ share (which allows CIFS named pipes to be -opened, read and written as if they were files). When 1st tree -connect fails (e.g. due to signing negotiation failure) fix -leak that causes cifsd not to stop and rmmod to fail to cleanup -cifs_request_buffers pool. Fix problem with POSIX Open/Mkdir on -bigendian architectures. Fix possible memory corruption when -EAGAIN returned on kern_recvmsg. Return better error if server -requires packet signing but client has disabled it. - Version 1.50 ------------ Fix NTLMv2 signing. NFS server mounted over cifs works (if cifs mount is @@ -22,10 +6,7 @@ done with "serverino" mount option). Add support for POSIX Unlink Samba supports newer POSIX CIFS Protocol Extensions). Add "nounix" mount option to allow disabling the CIFS Unix Extensions for just that mount. Fix hang on spinlock in find_writable_file (race when -reopening file after session crash). Byte range unlock request to -windows server could unlock more bytes (on server copy of file) -than intended if start of unlock request is well before start of -a previous byte range lock that we issued. +reopening file after session crash). Version 1.49 ------------ diff --git a/trunk/fs/cifs/Makefile b/trunk/fs/cifs/Makefile index ff6ba8d823f0..6ecd9d6ba3f3 100644 --- a/trunk/fs/cifs/Makefile +++ b/trunk/fs/cifs/Makefile @@ -3,4 +3,4 @@ # obj-$(CONFIG_CIFS) += cifs.o -cifs-objs := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o fcntl.o readdir.o ioctl.o sess.o export.o cifsacl.o +cifs-objs := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o fcntl.o readdir.o ioctl.o sess.o export.o diff --git a/trunk/fs/cifs/asn1.c b/trunk/fs/cifs/asn1.c index 2a01f3ef96a0..f50a88d58f78 100644 --- a/trunk/fs/cifs/asn1.c +++ b/trunk/fs/cifs/asn1.c @@ -385,9 +385,10 @@ asn1_oid_decode(struct asn1_ctx *ctx, unsigned long *optr; size = eoc - ctx->pointer + 1; - *oid = kmalloc(size * sizeof(unsigned long), GFP_ATOMIC); - if (*oid == NULL) + *oid = kmalloc(size * sizeof (unsigned long), GFP_ATOMIC); + if (*oid == NULL) { return 0; + } optr = *oid; @@ -580,8 +581,9 @@ decode_negTokenInit(unsigned char *security_blob, int length, return 0; } else if ((cls != ASN1_UNI) || (con != ASN1_CON) || (tag != ASN1_SEQ)) { - cFYI(1, ("cls = %d con = %d tag = %d end = %p (%d)", - cls, con, tag, end, *end)); + cFYI(1, + ("Exit 6 cls = %d con = %d tag = %d end = %p (%d)", + cls, con, tag, end, *end)); } if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { diff --git a/trunk/fs/cifs/cifs_debug.c b/trunk/fs/cifs/cifs_debug.c index 73c4c419663c..1bf8cf522ad6 100644 --- a/trunk/fs/cifs/cifs_debug.c +++ b/trunk/fs/cifs/cifs_debug.c @@ -209,16 +209,13 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset, i++; tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList); dev_type = le32_to_cpu(tcon->fsDevInfo.DeviceType); - length = sprintf(buf, "\n%d) %s Uses: %d ", i, - tcon->treeName, atomic_read(&tcon->useCount)); - buf += length; - if (tcon->nativeFileSystem) { - length = sprintf(buf, "Type: %s ", - tcon->nativeFileSystem); - buf += length; - } - length = sprintf(buf, "DevInfo: 0x%x Attributes: 0x%x" - "\nPathComponentMax: %d Status: %d", + length = + sprintf(buf, + "\n%d) %s Uses: %d Type: %s DevInfo: 0x%x " + "Attributes: 0x%x\nPathComponentMax: %d Status: %d", + i, tcon->treeName, + atomic_read(&tcon->useCount), + tcon->nativeFileSystem, le32_to_cpu(tcon->fsDevInfo.DeviceCharacteristics), le32_to_cpu(tcon->fsAttrInfo.Attributes), le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength), @@ -879,16 +876,11 @@ security_flags_write(struct file *file, const char __user *buffer, if (count < 3) { /* single char or single char followed by null */ c = flags_string[0]; - if (c == '0' || c == 'n' || c == 'N') { + if (c == '0' || c == 'n' || c == 'N') extended_security = CIFSSEC_DEF; /* default */ - return count; - } else if (c == '1' || c == 'y' || c == 'Y') { + else if (c == '1' || c == 'y' || c == 'Y') extended_security = CIFSSEC_MAX; - return count; - } else if (!isdigit(c)) { - cERROR(1, ("invalid flag %c", c)); - return -EINVAL; - } + return count; } /* else we have a number */ diff --git a/trunk/fs/cifs/cifsacl.c b/trunk/fs/cifs/cifsacl.c deleted file mode 100644 index e8e56353f5a1..000000000000 --- a/trunk/fs/cifs/cifsacl.c +++ /dev/null @@ -1,333 +0,0 @@ -/* - * fs/cifs/cifsacl.c - * - * Copyright (C) International Business Machines Corp., 2007 - * Author(s): Steve French (sfrench@us.ibm.com) - * - * Contains the routines for mapping CIFS/NTFS ACLs - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation; either version 2.1 of the License, or - * (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See - * the GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include "cifspdu.h" -#include "cifsglob.h" -#include "cifsacl.h" -#include "cifsproto.h" -#include "cifs_debug.h" - - -#ifdef CONFIG_CIFS_EXPERIMENTAL - -static struct cifs_wksid wksidarr[NUM_WK_SIDS] = { - {{1, 0, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0} }, "null user"}, - {{1, 1, {0, 0, 0, 0, 0, 1}, {0, 0, 0, 0, 0} }, "nobody"}, - {{1, 1, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(11), 0, 0, 0, 0} }, "net-users"}, - {{1, 1, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(18), 0, 0, 0, 0} }, "sys"}, - {{1, 2, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(32), cpu_to_le32(544), 0, 0, 0} }, "root"}, - {{1, 2, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(32), cpu_to_le32(545), 0, 0, 0} }, "users"}, - {{1, 2, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(32), cpu_to_le32(546), 0, 0, 0} }, "guest"} -}; - - -/* security id for everyone */ -static const struct cifs_sid sid_everyone = - {1, 1, {0, 0, 0, 0, 0, 0}, {} }; -/* group users */ -static const struct cifs_sid sid_user = - {1, 2 , {0, 0, 0, 0, 0, 5}, {} }; - - -int match_sid(struct cifs_sid *ctsid) -{ - int i, j; - int num_subauth, num_sat, num_saw; - struct cifs_sid *cwsid; - - if (!ctsid) - return (-1); - - for (i = 0; i < NUM_WK_SIDS; ++i) { - cwsid = &(wksidarr[i].cifssid); - - /* compare the revision */ - if (ctsid->revision != cwsid->revision) - continue; - - /* compare all of the six auth values */ - for (j = 0; j < 6; ++j) { - if (ctsid->authority[j] != cwsid->authority[j]) - break; - } - if (j < 6) - continue; /* all of the auth values did not match */ - - /* compare all of the subauth values if any */ - num_sat = ctsid->num_subauth; - num_saw = cwsid->num_subauth; - num_subauth = num_sat < num_saw ? num_sat : num_saw; - if (num_subauth) { - for (j = 0; j < num_subauth; ++j) { - if (ctsid->sub_auth[j] != cwsid->sub_auth[j]) - break; - } - if (j < num_subauth) - continue; /* all sub_auth values do not match */ - } - - cFYI(1, ("matching sid: %s\n", wksidarr[i].sidname)); - return (0); /* sids compare/match */ - } - - cFYI(1, ("No matching sid")); - return (-1); -} - -/* if the two SIDs (roughly equivalent to a UUID for a user or group) are - the same returns 1, if they do not match returns 0 */ -int compare_sids(struct cifs_sid *ctsid, struct cifs_sid *cwsid) -{ - int i; - int num_subauth, num_sat, num_saw; - - if ((!ctsid) || (!cwsid)) - return (0); - - /* compare the revision */ - if (ctsid->revision != cwsid->revision) - return (0); - - /* compare all of the six auth values */ - for (i = 0; i < 6; ++i) { - if (ctsid->authority[i] != cwsid->authority[i]) - return (0); - } - - /* compare all of the subauth values if any */ - num_sat = ctsid->num_subauth; - num_saw = cwsid->num_subauth; - num_subauth = num_sat < num_saw ? num_sat : num_saw; - if (num_subauth) { - for (i = 0; i < num_subauth; ++i) { - if (ctsid->sub_auth[i] != cwsid->sub_auth[i]) - return (0); - } - } - - return (1); /* sids compare/match */ -} - - -static void parse_ace(struct cifs_ace *pace, char *end_of_acl) -{ - int num_subauth; - - /* validate that we do not go past end of acl */ - - /* XXX this if statement can be removed - if (end_of_acl < (char *)pace + sizeof(struct cifs_ace)) { - cERROR(1, ("ACL too small to parse ACE")); - return; - } */ - - num_subauth = pace->num_subauth; - if (num_subauth) { -#ifdef CONFIG_CIFS_DEBUG2 - int i; - cFYI(1, ("ACE revision %d num_subauth %d", - pace->revision, pace->num_subauth)); - for (i = 0; i < num_subauth; ++i) { - cFYI(1, ("ACE sub_auth[%d]: 0x%x", i, - le32_to_cpu(pace->sub_auth[i]))); - } - - /* BB add length check to make sure that we do not have huge - num auths and therefore go off the end */ - - cFYI(1, ("RID %d", le32_to_cpu(pace->sub_auth[num_subauth-1]))); -#endif - } - - return; -} - -static void parse_ntace(struct cifs_ntace *pntace, char *end_of_acl) -{ - /* validate that we do not go past end of acl */ - if (end_of_acl < (char *)pntace + sizeof(struct cifs_ntace)) { - cERROR(1, ("ACL too small to parse NT ACE")); - return; - } - -#ifdef CONFIG_CIFS_DEBUG2 - cFYI(1, ("NTACE type %d flags 0x%x size %d, access Req 0x%x", - pntace->type, pntace->flags, pntace->size, - pntace->access_req)); -#endif - return; -} - - - -static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl, - struct cifs_sid *pownersid, struct cifs_sid *pgrpsid) -{ - int i; - int num_aces = 0; - int acl_size; - char *acl_base; - struct cifs_ntace **ppntace; - struct cifs_ace **ppace; - - /* BB need to add parm so we can store the SID BB */ - - /* validate that we do not go past end of acl */ - if (end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) { - cERROR(1, ("ACL too small to parse DACL")); - return; - } - -#ifdef CONFIG_CIFS_DEBUG2 - cFYI(1, ("DACL revision %d size %d num aces %d", - le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size), - le32_to_cpu(pdacl->num_aces))); -#endif - - acl_base = (char *)pdacl; - acl_size = sizeof(struct cifs_acl); - - num_aces = le32_to_cpu(pdacl->num_aces); - if (num_aces > 0) { - ppntace = kmalloc(num_aces * sizeof(struct cifs_ntace *), - GFP_KERNEL); - ppace = kmalloc(num_aces * sizeof(struct cifs_ace *), - GFP_KERNEL); - -/* cifscred->cecount = pdacl->num_aces; - cifscred->ntaces = kmalloc(num_aces * - sizeof(struct cifs_ntace *), GFP_KERNEL); - cifscred->aces = kmalloc(num_aces * - sizeof(struct cifs_ace *), GFP_KERNEL);*/ - - for (i = 0; i < num_aces; ++i) { - ppntace[i] = (struct cifs_ntace *) - (acl_base + acl_size); - ppace[i] = (struct cifs_ace *) ((char *)ppntace[i] + - sizeof(struct cifs_ntace)); - - parse_ntace(ppntace[i], end_of_acl); - if (end_of_acl < ((char *)ppace[i] + - (le16_to_cpu(ppntace[i]->size) - - sizeof(struct cifs_ntace)))) { - cERROR(1, ("ACL too small to parse ACE")); - break; - } else - parse_ace(ppace[i], end_of_acl); - -/* memcpy((void *)(&(cifscred->ntaces[i])), - (void *)ppntace[i], - sizeof(struct cifs_ntace)); - memcpy((void *)(&(cifscred->aces[i])), - (void *)ppace[i], - sizeof(struct cifs_ace)); */ - - acl_base = (char *)ppntace[i]; - acl_size = le16_to_cpu(ppntace[i]->size); - } - - kfree(ppace); - kfree(ppntace); - } - - return; -} - - -static int parse_sid(struct cifs_sid *psid, char *end_of_acl) -{ - - /* BB need to add parm so we can store the SID BB */ - - /* validate that we do not go past end of acl */ - if (end_of_acl < (char *)psid + sizeof(struct cifs_sid)) { - cERROR(1, ("ACL too small to parse SID")); - return -EINVAL; - } - - if (psid->num_subauth) { -#ifdef CONFIG_CIFS_DEBUG2 - int i; - cFYI(1, ("SID revision %d num_auth %d First subauth 0x%x", - psid->revision, psid->num_subauth, psid->sub_auth[0])); - - for (i = 0; i < psid->num_subauth; i++) { - cFYI(1, ("SID sub_auth[%d]: 0x%x ", i, - le32_to_cpu(psid->sub_auth[i]))); - } - - /* BB add length check to make sure that we do not have huge - num auths and therefore go off the end */ - cFYI(1, ("RID 0x%x", - le32_to_cpu(psid->sub_auth[psid->num_subauth-1]))); -#endif - } - - return 0; -} - - -/* Convert CIFS ACL to POSIX form */ -int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len) -{ - int rc; - struct cifs_sid *owner_sid_ptr, *group_sid_ptr; - struct cifs_acl *dacl_ptr; /* no need for SACL ptr */ - char *end_of_acl = ((char *)pntsd) + acl_len; - - owner_sid_ptr = (struct cifs_sid *)((char *)pntsd + - le32_to_cpu(pntsd->osidoffset)); - group_sid_ptr = (struct cifs_sid *)((char *)pntsd + - le32_to_cpu(pntsd->gsidoffset)); - dacl_ptr = (struct cifs_acl *)((char *)pntsd + - le32_to_cpu(pntsd->dacloffset)); -#ifdef CONFIG_CIFS_DEBUG2 - cFYI(1, ("revision %d type 0x%x ooffset 0x%x goffset 0x%x " - "sacloffset 0x%x dacloffset 0x%x", - pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset), - le32_to_cpu(pntsd->gsidoffset), - le32_to_cpu(pntsd->sacloffset), - le32_to_cpu(pntsd->dacloffset))); -#endif - rc = parse_sid(owner_sid_ptr, end_of_acl); - if (rc) - return rc; - - rc = parse_sid(group_sid_ptr, end_of_acl); - if (rc) - return rc; - - parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr, group_sid_ptr); - -/* cifscred->uid = owner_sid_ptr->rid; - cifscred->gid = group_sid_ptr->rid; - memcpy((void *)(&(cifscred->osid)), (void *)owner_sid_ptr, - sizeof (struct cifs_sid)); - memcpy((void *)(&(cifscred->gsid)), (void *)group_sid_ptr, - sizeof (struct cifs_sid)); */ - - - return (0); -} -#endif /* CONFIG_CIFS_EXPERIMENTAL */ diff --git a/trunk/fs/cifs/cifsacl.h b/trunk/fs/cifs/cifsacl.h index 420f87813647..5eff35d6e564 100644 --- a/trunk/fs/cifs/cifsacl.h +++ b/trunk/fs/cifs/cifsacl.h @@ -1,7 +1,7 @@ /* * fs/cifs/cifsacl.h * - * Copyright (c) International Business Machines Corp., 2007 + * Copyright (c) International Business Machines Corp., 2005 * Author(s): Steve French (sfrench@us.ibm.com) * * This library is free software; you can redistribute it and/or modify @@ -22,65 +22,17 @@ #ifndef _CIFSACL_H #define _CIFSACL_H - -#define NUM_AUTHS 6 /* number of authority fields */ -#define NUM_SUBAUTHS 5 /* number of sub authority fields */ -#define NUM_WK_SIDS 7 /* number of well known sids */ -#define SIDNAMELENGTH 20 /* long enough for the ones we care about */ - -#define READ_BIT 0x4 -#define WRITE_BIT 0x2 -#define EXEC_BIT 0x1 - -#define UBITSHIFT 6 -#define GBITSHIFT 3 - -struct cifs_ntsd { - __le16 revision; /* revision level */ - __le16 type; - __le32 osidoffset; - __le32 gsidoffset; - __le32 sacloffset; - __le32 dacloffset; -} __attribute__((packed)); - struct cifs_sid { __u8 revision; /* revision level */ - __u8 num_subauth; - __u8 authority[6]; - __le32 sub_auth[5]; /* sub_auth[num_subauth] */ /* BB FIXME endianness BB */ -} __attribute__((packed)); - -struct cifs_acl { - __le16 revision; /* revision level */ - __le16 size; - __le32 num_aces; -} __attribute__((packed)); - -struct cifs_ntace { /* first part of ACE which contains perms */ - __u8 type; - __u8 flags; - __le16 size; - __le32 access_req; -} __attribute__((packed)); - -struct cifs_ace { /* last part of ACE which includes user info */ - __u8 revision; /* revision level */ - __u8 num_subauth; + __u8 num_subauths; __u8 authority[6]; - __le32 sub_auth[5]; + __u32 sub_auth[4]; + /* next sub_auth if any ... */ } __attribute__((packed)); -struct cifs_wksid { - struct cifs_sid cifssid; - char sidname[SIDNAMELENGTH]; -} __attribute__((packed)); - -#ifdef CONFIG_CIFS_EXPERIMENTAL - -extern int match_sid(struct cifs_sid *); -extern int compare_sids(struct cifs_sid *, struct cifs_sid *); - -#endif /* CONFIG_CIFS_EXPERIMENTAL */ +/* everyone */ +/* extern const struct cifs_sid sid_everyone;*/ +/* group users */ +/* extern const struct cifs_sid sid_user;*/ #endif /* _CIFSACL_H */ diff --git a/trunk/fs/cifs/cifsencrypt.c b/trunk/fs/cifs/cifsencrypt.c index 632070b4275d..36272293027d 100644 --- a/trunk/fs/cifs/cifsencrypt.c +++ b/trunk/fs/cifs/cifsencrypt.c @@ -345,7 +345,7 @@ static int calc_ntlmv2_hash(struct cifsSesInfo *ses, user = kmalloc(2 + (len * 2), GFP_KERNEL); if (user == NULL) goto calc_exit_2; - len = cifs_strtoUCS((__le16 *)user, ses->userName, len, nls_cp); + len = cifs_strtoUCS(user, ses->userName, len, nls_cp); UniStrupr(user); hmac_md5_update((char *)user, 2*len, pctxt); @@ -356,8 +356,7 @@ static int calc_ntlmv2_hash(struct cifsSesInfo *ses, domain = kmalloc(2 + (len * 2), GFP_KERNEL); if (domain == NULL) goto calc_exit_1; - len = cifs_strtoUCS((__le16 *)domain, ses->domainName, len, - nls_cp); + len = cifs_strtoUCS(domain, ses->domainName, len, nls_cp); /* the following line was removed since it didn't work well with lower cased domain name that passed as an option. Maybe converting the domain name earlier makes sense */ diff --git a/trunk/fs/cifs/cifsfs.c b/trunk/fs/cifs/cifsfs.c index a6fbea57c4b1..ba8f7868cb23 100644 --- a/trunk/fs/cifs/cifsfs.c +++ b/trunk/fs/cifs/cifsfs.c @@ -49,6 +49,10 @@ static struct quotactl_ops cifs_quotactl_ops; #endif /* QUOTA */ +#ifdef CONFIG_CIFS_EXPERIMENTAL +extern struct export_operations cifs_export_ops; +#endif /* EXPERIMENTAL */ + int cifsFYI = 0; int cifsERROR = 1; int traceSMB = 0; @@ -236,9 +240,9 @@ static int cifs_permission(struct inode *inode, int mask, struct nameidata *nd) cifs_sb = CIFS_SB(inode->i_sb); - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) { return 0; - else /* file mode might have been restricted at mount time + } else /* file mode might have been restricted at mount time on the client (above and beyond ACL on servers) for servers which do not support setting and viewing mode bits, so allowing client to check permissions is useful */ @@ -308,15 +312,15 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m) seq_printf(s, ",domain=%s", cifs_sb->tcon->ses->domainName); } - if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) || - !(cifs_sb->tcon->unix_ext)) - seq_printf(s, ",uid=%d", cifs_sb->mnt_uid); - if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) || - !(cifs_sb->tcon->unix_ext)) - seq_printf(s, ",gid=%d", cifs_sb->mnt_gid); } if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) seq_printf(s, ",posixpaths"); + if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) || + !(cifs_sb->tcon->unix_ext)) + seq_printf(s, ",uid=%d", cifs_sb->mnt_uid); + if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) || + !(cifs_sb->tcon->unix_ext)) + seq_printf(s, ",gid=%d", cifs_sb->mnt_gid); seq_printf(s, ",rsize=%d", cifs_sb->rsize); seq_printf(s, ",wsize=%d", cifs_sb->wsize); } @@ -342,7 +346,7 @@ int cifs_xquota_set(struct super_block *sb, int quota_type, qid_t qid, if (pTcon) { cFYI(1, ("set type: 0x%x id: %d", quota_type, qid)); } else { - rc = -EIO; + return -EIO; } FreeXid(xid); @@ -712,7 +716,7 @@ static int cifs_init_inodecache(void) { cifs_inode_cachep = kmem_cache_create("cifs_inode_cache", - sizeof(struct cifsInodeInfo), + sizeof (struct cifsInodeInfo), 0, (SLAB_RECLAIM_ACCOUNT| SLAB_MEM_SPREAD), cifs_init_once); @@ -812,8 +816,8 @@ static int cifs_init_mids(void) { cifs_mid_cachep = kmem_cache_create("cifs_mpx_ids", - sizeof(struct mid_q_entry), 0, - SLAB_HWCACHE_ALIGN, NULL); + sizeof (struct mid_q_entry), 0, + SLAB_HWCACHE_ALIGN, NULL); if (cifs_mid_cachep == NULL) return -ENOMEM; @@ -825,8 +829,8 @@ cifs_init_mids(void) } cifs_oplock_cachep = kmem_cache_create("cifs_oplock_structs", - sizeof(struct oplock_q_entry), 0, - SLAB_HWCACHE_ALIGN, NULL); + sizeof (struct oplock_q_entry), 0, + SLAB_HWCACHE_ALIGN, NULL); if (cifs_oplock_cachep == NULL) { mempool_destroy(cifs_mid_poolp); kmem_cache_destroy(cifs_mid_cachep); @@ -878,8 +882,7 @@ static int cifs_oplock_thread(void *dummyarg) the call */ /* mutex_lock(&inode->i_mutex);*/ if (S_ISREG(inode->i_mode)) { - rc = - filemap_fdatawrite(inode->i_mapping); + rc = filemap_fdatawrite(inode->i_mapping); if (CIFS_I(inode)->clientCanCacheRead == 0) { filemap_fdatawait(inode->i_mapping); @@ -904,7 +907,8 @@ static int cifs_oplock_thread(void *dummyarg) 0 /* len */ , 0 /* offset */, 0, 0, LOCKING_ANDX_OPLOCK_RELEASE, 0 /* wait flag */); - cFYI(1, ("Oplock release rc = %d", rc)); + cFYI(1, + ("Oplock release rc = %d ", rc)); } } else spin_unlock(&GlobalMid_Lock); diff --git a/trunk/fs/cifs/cifsfs.h b/trunk/fs/cifs/cifsfs.h index 0a3ee5a322b0..a20de77a3856 100644 --- a/trunk/fs/cifs/cifsfs.h +++ b/trunk/fs/cifs/cifsfs.h @@ -1,7 +1,7 @@ /* * fs/cifs/cifsfs.h * - * Copyright (c) International Business Machines Corp., 2002, 2007 + * Copyright (c) International Business Machines Corp., 2002, 2005 * Author(s): Steve French (sfrench@us.ibm.com) * * This library is free software; you can redistribute it and/or modify @@ -99,12 +99,7 @@ extern int cifs_setxattr(struct dentry *, const char *, const void *, size_t, int); extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t); extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); -extern int cifs_ioctl(struct inode *inode, struct file *filep, +extern int cifs_ioctl (struct inode *inode, struct file *filep, unsigned int command, unsigned long arg); - -#ifdef CONFIG_CIFS_EXPERIMENTAL -extern struct export_operations cifs_export_ops; -#endif /* EXPERIMENTAL */ - -#define CIFS_VERSION "1.51" +#define CIFS_VERSION "1.50" #endif /* _CIFSFS_H */ diff --git a/trunk/fs/cifs/cifsglob.h b/trunk/fs/cifs/cifsglob.h index 87f51f23276f..b98742fc3b5a 100644 --- a/trunk/fs/cifs/cifsglob.h +++ b/trunk/fs/cifs/cifsglob.h @@ -19,7 +19,6 @@ #include #include #include "cifs_fs_sb.h" -#include "cifsacl.h" /* * The sizes of various internal tables and strings */ @@ -90,8 +89,7 @@ enum statusEnum { }; enum securityEnum { - PLAINTXT = 0, /* Legacy with Plaintext passwords */ - LANMAN, /* Legacy LANMAN auth */ + LANMAN = 0, /* Legacy LANMAN auth */ NTLM, /* Legacy NTLM012 auth with NTLM hash */ NTLMv2, /* Legacy NTLM auth with NTLMv2 hash */ RawNTLMSSP, /* NTLMSSP without SPNEGO */ @@ -117,17 +115,6 @@ struct mac_key { } data; }; -struct cifs_cred { - int uid; - int gid; - int mode; - int cecount; - struct cifs_sid osid; - struct cifs_sid gsid; - struct cifs_ntace *ntaces; - struct cifs_ace *aces; -}; - /* ***************************************************************** * Except the CIFS PDUs themselves all the @@ -292,7 +279,6 @@ struct cifsTconInfo { FILE_SYSTEM_DEVICE_INFO fsDevInfo; FILE_SYSTEM_ATTRIBUTE_INFO fsAttrInfo; /* ok if fs name truncated */ FILE_SYSTEM_UNIX_INFO fsUnixInfo; - unsigned ipc:1; /* set if connection to IPC$ eg for RPC/PIPES */ unsigned retry:1; unsigned nocase:1; unsigned unix_ext:1; /* if off disable Linux extensions to CIFS protocol @@ -343,7 +329,6 @@ struct cifsFileInfo { struct list_head llist; /* list of byte range locks we have. */ unsigned closePend:1; /* file is marked to close */ unsigned invalidHandle:1; /* file closed via session abend */ - unsigned messageMode:1; /* for pipes: message vs byte mode */ atomic_t wrtPending; /* handle in use - defer close */ struct semaphore fh_sem; /* prevents reopen race after dead ses*/ char *search_resume_name; /* BB removeme BB */ @@ -479,9 +464,6 @@ struct dir_notify_req { #ifdef CONFIG_CIFS_WEAK_PW_HASH #define CIFSSEC_MAY_LANMAN 0x00010 #define CIFSSEC_MAY_PLNTXT 0x00020 -#else -#define CIFSSEC_MAY_LANMAN 0 -#define CIFSSEC_MAY_PLNTXT 0 #endif /* weak passwords */ #define CIFSSEC_MAY_SEAL 0x00040 /* not supported yet */ @@ -495,23 +477,14 @@ require use of the stronger protocol */ #ifdef CONFIG_CIFS_WEAK_PW_HASH #define CIFSSEC_MUST_LANMAN 0x10010 #define CIFSSEC_MUST_PLNTXT 0x20020 -#ifdef CONFIG_CIFS_UPCALL -#define CIFSSEC_MASK 0x3F03F /* allows weak security but also krb5 */ -#else #define CIFSSEC_MASK 0x37037 /* current flags supported if weak */ -#endif /* UPCALL */ -#else /* do not allow weak pw hash */ -#ifdef CONFIG_CIFS_UPCALL -#define CIFSSEC_MASK 0x0F00F /* flags supported if no weak allowed */ #else -#define CIFSSEC_MASK 0x07007 /* flags supported if no weak allowed */ -#endif /* UPCALL */ +#define CIFSSEC_MASK 0x07007 /* flags supported if no weak config */ #endif /* WEAK_PW_HASH */ #define CIFSSEC_MUST_SEAL 0x40040 /* not supported yet */ #define CIFSSEC_DEF CIFSSEC_MAY_SIGN | CIFSSEC_MAY_NTLM | CIFSSEC_MAY_NTLMV2 #define CIFSSEC_MAX CIFSSEC_MUST_SIGN | CIFSSEC_MUST_NTLMV2 -#define CIFSSEC_AUTH_MASK (CIFSSEC_MAY_NTLM | CIFSSEC_MAY_NTLMV2 | CIFSSEC_MAY_LANMAN | CIFSSEC_MAY_PLNTXT | CIFSSEC_MAY_KRB5) /* ***************************************************************** * All constants go here diff --git a/trunk/fs/cifs/cifspdu.h b/trunk/fs/cifs/cifspdu.h index c41ff74e9128..6a2056e58ceb 100644 --- a/trunk/fs/cifs/cifspdu.h +++ b/trunk/fs/cifs/cifspdu.h @@ -215,12 +215,6 @@ /* file_execute, file_read_attributes*/ /* write_dac, and delete. */ -#define FILE_READ_RIGHTS (FILE_READ_DATA | FILE_READ_EA | FILE_READ_ATTRIBUTES) -#define FILE_WRITE_RIGHTS (FILE_WRITE_DATA | FILE_APPEND_DATA \ - | FILE_WRITE_EA | FILE_WRITE_ATTRIBUTES) -#define FILE_EXEC_RIGHTS (FILE_EXECUTE) - - /* * Invalid readdir handle */ @@ -366,10 +360,10 @@ struct smb_hdr { __u8 WordCount; } __attribute__((packed)); /* given a pointer to an smb_hdr retrieve the value of byte count */ -#define BCC(smb_var) ( *(__u16 *)((char *)smb_var + sizeof(struct smb_hdr) + (2 * smb_var->WordCount))) -#define BCC_LE(smb_var) ( *(__le16 *)((char *)smb_var + sizeof(struct smb_hdr) + (2 * smb_var->WordCount))) +#define BCC(smb_var) ( *(__u16 *)((char *)smb_var + sizeof(struct smb_hdr) + (2* smb_var->WordCount) ) ) +#define BCC_LE(smb_var) ( *(__le16 *)((char *)smb_var + sizeof(struct smb_hdr) + (2* smb_var->WordCount) ) ) /* given a pointer to an smb_hdr retrieve the pointer to the byte area */ -#define pByteArea(smb_var) ((unsigned char *)smb_var + sizeof(struct smb_hdr) + (2 * smb_var->WordCount) + 2) +#define pByteArea(smb_var) ((unsigned char *)smb_var + sizeof(struct smb_hdr) + (2* smb_var->WordCount) + 2 ) /* * Computer Name Length (since Netbios name was length 16 with last byte 0x20) @@ -722,14 +716,6 @@ typedef struct smb_com_findclose_req { #define REQ_OPENDIRONLY 0x00000008 #define REQ_EXTENDED_INFO 0x00000010 -/* File type */ -#define DISK_TYPE 0x0000 -#define BYTE_PIPE_TYPE 0x0001 -#define MESSAGE_PIPE_TYPE 0x0002 -#define PRINTER_TYPE 0x0003 -#define COMM_DEV_TYPE 0x0004 -#define UNKNOWN_TYPE 0xFFFF - typedef struct smb_com_open_req { /* also handles create */ struct smb_hdr hdr; /* wct = 24 */ __u8 AndXCommand; diff --git a/trunk/fs/cifs/cifsproto.h b/trunk/fs/cifs/cifsproto.h index 1a883663b22d..04a69dafedba 100644 --- a/trunk/fs/cifs/cifsproto.h +++ b/trunk/fs/cifs/cifsproto.h @@ -50,8 +50,7 @@ extern int SendReceive(const unsigned int /* xid */ , struct cifsSesInfo *, int * /* bytes returned */ , const int long_op); extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *, struct kvec *, int /* nvec to send */, - int * /* type of buf returned */ , const int long_op, - const int logError /* whether to log status code*/ ); + int * /* type of buf returned */ , const int long_op); extern int SendReceiveBlockingLock(const unsigned int /* xid */ , struct cifsTconInfo *, struct smb_hdr * /* input */ , @@ -66,7 +65,7 @@ extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr); extern int decode_negTokenInit(unsigned char *security_blob, int length, enum securityEnum *secType); extern int cifs_inet_pton(int, char *source, void *dst); -extern int map_smb_to_linux_error(struct smb_hdr *smb, int logErr); +extern int map_smb_to_linux_error(struct smb_hdr *smb); extern void header_assemble(struct smb_hdr *, char /* command */ , const struct cifsTconInfo *, int /* length of fixed section (word count) in two byte units */); @@ -305,13 +304,12 @@ extern int cifs_calculate_mac_key(struct mac_key *key, const char *rn, const char *pass); extern int CalcNTLMv2_partial_mac_key(struct cifsSesInfo *, const struct nls_table *); -extern void CalcNTLMv2_response(const struct cifsSesInfo *, char *); +extern void CalcNTLMv2_response(const struct cifsSesInfo *, char * ); extern void setup_ntlmv2_rsp(struct cifsSesInfo *, char *, const struct nls_table *); #ifdef CONFIG_CIFS_WEAK_PW_HASH extern void calc_lanman_hash(struct cifsSesInfo *ses, char *lnm_session_key); #endif /* CIFS_WEAK_PW_HASH */ -extern int parse_sec_desc(struct cifs_ntsd *, int); extern int CIFSSMBCopy(int xid, struct cifsTconInfo *source_tcon, const char *fromName, diff --git a/trunk/fs/cifs/cifssmb.c b/trunk/fs/cifs/cifssmb.c index f0d9a485d095..8eb102f940d4 100644 --- a/trunk/fs/cifs/cifssmb.c +++ b/trunk/fs/cifs/cifssmb.c @@ -34,10 +34,10 @@ #include #include "cifspdu.h" #include "cifsglob.h" -#include "cifsacl.h" #include "cifsproto.h" #include "cifs_unicode.h" #include "cifs_debug.h" +#include "cifsacl.h" #ifdef CONFIG_CIFS_POSIX static struct { @@ -94,8 +94,9 @@ static void mark_open_files_invalid(struct cifsTconInfo *pTcon) write_lock(&GlobalSMBSeslock); list_for_each_safe(tmp, tmp1, &pTcon->openFileList) { open_file = list_entry(tmp, struct cifsFileInfo, tlist); - if (open_file) + if (open_file) { open_file->invalidHandle = TRUE; + } } write_unlock(&GlobalSMBSeslock); /* BB Add call to invalidate_inodes(sb) for all superblocks mounted @@ -438,13 +439,8 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) pSMB->hdr.Mid = GetNextMid(server); pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS); - if ((secFlags & CIFSSEC_MUST_KRB5) == CIFSSEC_MUST_KRB5) pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC; - else if ((secFlags & CIFSSEC_AUTH_MASK) == CIFSSEC_MAY_KRB5) { - cFYI(1, ("Kerberos only mechanism, enable extended security")); - pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC; - } count = 0; for (i = 0; i < CIFS_NUM_PROT; i++) { @@ -517,7 +513,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) (int)ts.tv_sec, (int)utc.tv_sec, (int)(utc.tv_sec - ts.tv_sec))); val = (int)(utc.tv_sec - ts.tv_sec); - seconds = abs(val); + seconds = val < 0 ? -val : val; result = (seconds / MIN_TZ_ADJ) * MIN_TZ_ADJ; remain = seconds % MIN_TZ_ADJ; if (remain >= (MIN_TZ_ADJ / 2)) @@ -578,20 +574,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) server->secType = NTLM; else if (secFlags & CIFSSEC_MAY_NTLMV2) server->secType = NTLMv2; - else if (secFlags & CIFSSEC_MAY_KRB5) - server->secType = Kerberos; - else if (secFlags & CIFSSEC_MAY_LANMAN) - server->secType = LANMAN; -/* #ifdef CONFIG_CIFS_EXPERIMENTAL - else if (secFlags & CIFSSEC_MAY_PLNTXT) - server->secType = ?? -#endif */ - else { - rc = -EOPNOTSUPP; - cERROR(1, ("Invalid security type")); - goto neg_err_exit; - } - /* else ... any others ...? */ + /* else krb5 ... any others ... */ /* one byte, so no need to convert this or EncryptionKeyLen from little endian */ @@ -621,26 +604,22 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC) && (server->capabilities & CAP_EXTENDED_SECURITY)) { count = pSMBr->ByteCount; - if (count < 16) { + if (count < 16) rc = -EIO; - goto neg_err_exit; - } - - if (server->socketUseCount.counter > 1) { - if (memcmp(server->server_GUID, - pSMBr->u.extended_response. - GUID, 16) != 0) { - cFYI(1, ("server UID changed")); - memcpy(server->server_GUID, - pSMBr->u.extended_response.GUID, - 16); - } - } else - memcpy(server->server_GUID, - pSMBr->u.extended_response.GUID, 16); - - if (count == 16) { + else if (count == 16) { server->secType = RawNTLMSSP; + if (server->socketUseCount.counter > 1) { + if (memcmp(server->server_GUID, + pSMBr->u.extended_response. + GUID, 16) != 0) { + cFYI(1, ("server UID changed")); + memcpy(server->server_GUID, + pSMBr->u.extended_response.GUID, + 16); + } + } else + memcpy(server->server_GUID, + pSMBr->u.extended_response.GUID, 16); } else { rc = decode_negTokenInit(pSMBr->u.extended_response. SecurityBlob, @@ -663,12 +642,10 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) /* MUST_SIGN already includes the MAY_SIGN FLAG so if this is zero it means that signing is disabled */ cFYI(1, ("Signing disabled")); - if (server->secMode & SECMODE_SIGN_REQUIRED) { + if (server->secMode & SECMODE_SIGN_REQUIRED) cERROR(1, ("Server requires " - "packet signing to be enabled in " - "/proc/fs/cifs/SecurityFlags.")); - rc = -EOPNOTSUPP; - } + "/proc/fs/cifs/PacketSigningEnabled " + "to be on")); server->secMode &= ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED); } else if ((secFlags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) { @@ -1075,7 +1052,7 @@ CIFSPOSIXCreate(const int xid, struct cifsTconInfo *tcon, __u32 posix_flags, InformationLevel) - 4; offset = param_offset + params; pdata = (OPEN_PSX_REQ *)(((char *)&pSMB->hdr.Protocol) + offset); - pdata->Level = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC); + pdata->Level = SMB_QUERY_FILE_UNIX_BASIC; pdata->Permissions = cpu_to_le64(mode); pdata->PosixOpenFlags = cpu_to_le32(posix_flags); pdata->OpenFlags = cpu_to_le32(*pOplock); @@ -1121,8 +1098,8 @@ CIFSPOSIXCreate(const int xid, struct cifsTconInfo *tcon, __u32 posix_flags, if (cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction) *pOplock |= CIFS_CREATE_ACTION; /* check to make sure response data is there */ - if (psx_rsp->ReturnedLevel != cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC)) { - pRetData->Type = cpu_to_le32(-1); /* unknown */ + if (psx_rsp->ReturnedLevel != SMB_QUERY_FILE_UNIX_BASIC) { + pRetData->Type = -1; /* unknown */ #ifdef CONFIG_CIFS_DEBUG2 cFYI(1, ("unknown type")); #endif @@ -1130,12 +1107,12 @@ CIFSPOSIXCreate(const int xid, struct cifsTconInfo *tcon, __u32 posix_flags, if (pSMBr->ByteCount < sizeof(OPEN_PSX_RSP) + sizeof(FILE_UNIX_BASIC_INFO)) { cERROR(1, ("Open response data too small")); - pRetData->Type = cpu_to_le32(-1); + pRetData->Type = -1; goto psx_create_err; } memcpy((char *) pRetData, (char *)psx_rsp + sizeof(OPEN_PSX_RSP), - sizeof(FILE_UNIX_BASIC_INFO)); + sizeof (FILE_UNIX_BASIC_INFO)); } psx_create_err: @@ -1216,9 +1193,9 @@ SMBLegacyOpen(const int xid, struct cifsTconInfo *tcon, } if (*pOplock & REQ_OPLOCK) pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK); - else if (*pOplock & REQ_BATCHOPLOCK) + else if (*pOplock & REQ_BATCHOPLOCK) { pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK); - + } pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO); /* BB fixme add conversion for access_flags to bits 0 - 2 of mode */ /* 0 = read @@ -1333,8 +1310,9 @@ CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon, } if (*pOplock & REQ_OPLOCK) pSMB->OpenFlags = cpu_to_le32(REQ_OPLOCK); - else if (*pOplock & REQ_BATCHOPLOCK) + else if (*pOplock & REQ_BATCHOPLOCK) { pSMB->OpenFlags = cpu_to_le32(REQ_BATCHOPLOCK); + } pSMB->DesiredAccess = cpu_to_le32(access_flags); pSMB->AllocationSize = 0; /* set file as system file if special file such @@ -1446,8 +1424,9 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid, iov[0].iov_base = (char *)pSMB; iov[0].iov_len = pSMB->hdr.smb_buf_length + 4; - rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */, - &resp_buf_type, 0 /* not long op */, 1 /* log err */ ); + rc = SendReceive2(xid, tcon->ses, iov, + 1 /* num iovecs */, + &resp_buf_type, 0); cifs_stats_inc(&tcon->num_reads); pSMBr = (READ_RSP *)iov[0].iov_base; if (rc) { @@ -1467,11 +1446,11 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid, *nbytes = 0; } else { pReadData = (char *) (&pSMBr->hdr.Protocol) + - le16_to_cpu(pSMBr->DataOffset); -/* if (rc = copy_to_user(buf, pReadData, data_length)) { + le16_to_cpu(pSMBr->DataOffset); +/* if (rc = copy_to_user(buf, pReadData, data_length)) { cERROR(1,("Faulting on read rc = %d",rc)); rc = -EFAULT; - }*/ /* can not use copy_to_user when using page cache*/ + }*/ /* can not use copy_to_user when using page cache*/ if (*buf) memcpy(*buf, pReadData, data_length); } @@ -1666,7 +1645,7 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type, - long_op, 0 /* do not log STATUS code */ ); + long_op); cifs_stats_inc(&tcon->num_writes); if (rc) { cFYI(1, ("Send error Write2 = %d", rc)); @@ -2559,7 +2538,7 @@ validate_ntransact(char *buf, char **ppparm, char **ppdata, cFYI(1, ("data starts after end of smb")); return -EINVAL; } else if (data_count + *ppdata > end_of_smb) { - cFYI(1, ("data %p + count %d (%p) ends after end of smb %p start %p", + cFYI(1,("data %p + count %d (%p) ends after end of smb %p start %p", *ppdata, data_count, (data_count + *ppdata), end_of_smb, pSMBr)); return -EINVAL; @@ -2636,7 +2615,7 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon, reparse_buf->TargetNameOffset + reparse_buf->TargetNameLen) > end_of_smb) { - cFYI(1, ("reparse buf beyond SMB")); + cFYI(1,("reparse buf goes beyond SMB")); rc = -EIO; goto qreparse_out; } @@ -3063,12 +3042,25 @@ CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon, #endif /* CONFIG_POSIX */ -#ifdef CONFIG_CIFS_EXPERIMENTAL + +/* security id for everyone */ +static const struct cifs_sid sid_everyone = + {1, 1, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0}}; +/* group users */ +static const struct cifs_sid sid_user = + {1, 2 , {0, 0, 0, 0, 0, 5}, {32, 545, 0, 0}}; + +/* Convert CIFS ACL to POSIX form */ +static int parse_sec_desc(struct cifs_sid *psec_desc, int acl_len) +{ + return 0; +} + /* Get Security Descriptor (by handle) from remote server for a file or dir */ int CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, /* BB fix up return info */ char *acl_inf, const int buflen, - const int acl_type) + const int acl_type /* ACCESS/DEFAULT not sure implication */) { int rc = 0; int buf_type = 0; @@ -3093,13 +3085,12 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, iov[0].iov_base = (char *)pSMB; iov[0].iov_len = pSMB->hdr.smb_buf_length + 4; - rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type, - 0 /* not long op */, 0 /* do not log STATUS codes */ ); + rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type, 0); cifs_stats_inc(&tcon->num_acl_get); if (rc) { cFYI(1, ("Send error in QuerySecDesc = %d", rc)); } else { /* decode response */ - struct cifs_ntsd *psec_desc; + struct cifs_sid *psec_desc; __le32 * parm; int parm_len; int data_len; @@ -3114,7 +3105,8 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, goto qsec_out; pSMBr = (struct smb_com_ntransact_rsp *)iov[0].iov_base; - cFYI(1, ("smb %p parm %p data %p", pSMBr, parm, psec_desc)); + cERROR(1, ("smb %p parm %p data %p", + pSMBr, parm, psec_desc)); /* BB removeme BB */ if (le32_to_cpu(pSMBr->ParameterCount) != 4) { rc = -EIO; /* bad smb */ @@ -3123,7 +3115,7 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, /* BB check that data area is minimum length and as big as acl_len */ - acl_len = le32_to_cpu(*parm); + acl_len = le32_to_cpu(*(__le32 *)parm); /* BB check if (acl_len > bufsize) */ parse_sec_desc(psec_desc, acl_len); @@ -3136,7 +3128,6 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */ return rc; } -#endif /* CONFIG_CIFS_EXPERIMENTAL */ /* Legacy Query Path Information call for lookup to old servers such as Win9x/WinME */ @@ -3372,9 +3363,6 @@ CIFSSMBUnixQPathInfo(const int xid, struct cifsTconInfo *tcon, rc = validate_t2((struct smb_t2_rsp *)pSMBr); if (rc || (pSMBr->ByteCount < sizeof(FILE_UNIX_BASIC_INFO))) { - cERROR(1, ("Malformed FILE_UNIX_BASIC_INFO response.\n" - "Unix Extensions can be disabled on mount " - "by specifying the nosfu mount option.")); rc = -EIO; /* bad smb */ } else { __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); @@ -3895,10 +3883,12 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses, pSMB->hdr.Mid = GetNextMid(ses->server); pSMB->hdr.Tid = ses->ipc_tid; pSMB->hdr.Uid = ses->Suid; - if (ses->capabilities & CAP_STATUS32) + if (ses->capabilities & CAP_STATUS32) { pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS; - if (ses->capabilities & CAP_DFS) + } + if (ses->capabilities & CAP_DFS) { pSMB->hdr.Flags2 |= SMBFLG2_DFS; + } if (ses->capabilities & CAP_UNICODE) { pSMB->hdr.Flags2 |= SMBFLG2_UNICODE; @@ -4070,6 +4060,10 @@ SMBOldQFSInfo(const int xid, struct cifsTconInfo *tcon, struct kstatfs *FSData) (void **) &pSMBr); if (rc) return rc; + rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, + (void **) &pSMBr); + if (rc) + return rc; params = 2; /* level */ pSMB->TotalDataCount = 0; @@ -4271,7 +4265,7 @@ CIFSSMBQFSAttributeInfo(const int xid, struct cifsTconInfo *tcon) *) (((char *) &pSMBr->hdr.Protocol) + data_offset); memcpy(&tcon->fsAttrInfo, response_data, - sizeof(FILE_SYSTEM_ATTRIBUTE_INFO)); + sizeof (FILE_SYSTEM_ATTRIBUTE_INFO)); } } cifs_buf_release(pSMB); @@ -4340,7 +4334,7 @@ CIFSSMBQFSDeviceInfo(const int xid, struct cifsTconInfo *tcon) (((char *) &pSMBr->hdr.Protocol) + data_offset); memcpy(&tcon->fsDevInfo, response_data, - sizeof(FILE_SYSTEM_DEVICE_INFO)); + sizeof (FILE_SYSTEM_DEVICE_INFO)); } } cifs_buf_release(pSMB); @@ -4408,7 +4402,7 @@ CIFSSMBQFSUnixInfo(const int xid, struct cifsTconInfo *tcon) *) (((char *) &pSMBr->hdr.Protocol) + data_offset); memcpy(&tcon->fsUnixInfo, response_data, - sizeof(FILE_SYSTEM_UNIX_INFO)); + sizeof (FILE_SYSTEM_UNIX_INFO)); } } cifs_buf_release(pSMB); @@ -4618,7 +4612,7 @@ CIFSSMBSetEOF(const int xid, struct cifsTconInfo *tcon, const char *fileName, strncpy(pSMB->FileName, fileName, name_len); } params = 6 + name_len; - data_count = sizeof(struct file_end_of_file_info); + data_count = sizeof (struct file_end_of_file_info); pSMB->MaxParameterCount = cpu_to_le16(2); pSMB->MaxDataCount = cpu_to_le16(4100); pSMB->MaxSetupCount = 0; @@ -4806,7 +4800,7 @@ CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon, data_offset = (char *) (&pSMB->hdr.Protocol) + offset; - count = sizeof(FILE_BASIC_INFO); + count = sizeof (FILE_BASIC_INFO); pSMB->MaxParameterCount = cpu_to_le16(2); pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB PDU from sess */ pSMB->SetupCount = 1; @@ -4877,7 +4871,7 @@ CIFSSMBSetTimes(const int xid, struct cifsTconInfo *tcon, const char *fileName, } params = 6 + name_len; - count = sizeof(FILE_BASIC_INFO); + count = sizeof (FILE_BASIC_INFO); pSMB->MaxParameterCount = cpu_to_le16(2); pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find exact max SMB PDU from sess structure BB */ pSMB->MaxSetupCount = 0; @@ -4906,7 +4900,7 @@ CIFSSMBSetTimes(const int xid, struct cifsTconInfo *tcon, const char *fileName, pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO); pSMB->Reserved4 = 0; pSMB->hdr.smb_buf_length += byte_count; - memcpy(data_offset, data, sizeof(FILE_BASIC_INFO)); + memcpy(data_offset, data, sizeof (FILE_BASIC_INFO)); pSMB->ByteCount = cpu_to_le16(byte_count); rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); @@ -5009,7 +5003,7 @@ CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *tcon, } params = 6 + name_len; - count = sizeof(FILE_UNIX_BASIC_INFO); + count = sizeof (FILE_UNIX_BASIC_INFO); pSMB->MaxParameterCount = cpu_to_le16(2); pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find exact max SMB PDU from sess structure BB */ pSMB->MaxSetupCount = 0; diff --git a/trunk/fs/cifs/connect.c b/trunk/fs/cifs/connect.c index 19ee11f7f35a..4af3588c1a96 100644 --- a/trunk/fs/cifs/connect.c +++ b/trunk/fs/cifs/connect.c @@ -124,7 +124,7 @@ cifs_reconnect(struct TCP_Server_Info *server) struct mid_q_entry *mid_entry; spin_lock(&GlobalMid_Lock); - if (kthread_should_stop()) { + if ( kthread_should_stop() ) { /* the demux thread will exit normally next time through the loop */ spin_unlock(&GlobalMid_Lock); @@ -151,8 +151,9 @@ cifs_reconnect(struct TCP_Server_Info *server) } list_for_each(tmp, &GlobalTreeConnectionList) { tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList); - if ((tcon) && (tcon->ses) && (tcon->ses->server == server)) + if ((tcon) && (tcon->ses) && (tcon->ses->server == server)) { tcon->tidStatus = CifsNeedReconnect; + } } read_unlock(&GlobalSMBSeslock); /* do not want to be sending data on a socket we are freeing */ @@ -186,7 +187,7 @@ cifs_reconnect(struct TCP_Server_Info *server) spin_unlock(&GlobalMid_Lock); up(&server->tcpSem); - while ((!kthread_should_stop()) && (server->tcpStatus != CifsGood)) { + while ( (!kthread_should_stop()) && (server->tcpStatus != CifsGood)) { try_to_freeze(); if (server->protocolType == IPV6) { rc = ipv6_connect(&server->addr.sockAddr6, @@ -203,7 +204,7 @@ cifs_reconnect(struct TCP_Server_Info *server) } else { atomic_inc(&tcpSesReconnectCount); spin_lock(&GlobalMid_Lock); - if (!kthread_should_stop()) + if ( !kthread_should_stop() ) server->tcpStatus = CifsGood; server->sequence_number = 0; spin_unlock(&GlobalMid_Lock); @@ -351,15 +352,17 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) current->flags |= PF_MEMALLOC; server->tsk = current; /* save process info to wake at shutdown */ - cFYI(1, ("Demultiplex PID: %d", task_pid_nr(current))); + cFYI(1, ("Demultiplex PID: %d", current->pid)); write_lock(&GlobalSMBSeslock); atomic_inc(&tcpSesAllocCount); length = tcpSesAllocCount.counter; write_unlock(&GlobalSMBSeslock); complete(&cifsd_complete); - if (length > 1) - mempool_resize(cifs_req_poolp, length + cifs_min_rcv, - GFP_KERNEL); + if (length > 1) { + mempool_resize(cifs_req_poolp, + length + cifs_min_rcv, + GFP_KERNEL); + } set_freezable(); while (!kthread_should_stop()) { @@ -375,7 +378,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) } } else if (isLargeBuf) { /* we are reusing a dirty large buf, clear its start */ - memset(bigbuf, 0, sizeof(struct smb_hdr)); + memset(bigbuf, 0, sizeof (struct smb_hdr)); } if (smallbuf == NULL) { @@ -388,7 +391,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) } /* beginning of smb buffer is cleared in our buf_get */ } else /* if existing small buf clear beginning */ - memset(smallbuf, 0, sizeof(struct smb_hdr)); + memset(smallbuf, 0, sizeof (struct smb_hdr)); isLargeBuf = FALSE; isMultiRsp = FALSE; @@ -397,13 +400,11 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) iov.iov_len = 4; smb_msg.msg_control = NULL; smb_msg.msg_controllen = 0; - pdu_length = 4; /* enough to get RFC1001 header */ -incomplete_rcv: length = kernel_recvmsg(csocket, &smb_msg, - &iov, 1, pdu_length, 0 /* BB other flags? */); + &iov, 1, 4, 0 /* BB see socket.h flags */); - if (kthread_should_stop()) { + if ( kthread_should_stop() ) { break; } else if (server->tcpStatus == CifsNeedReconnect) { cFYI(1, ("Reconnect after server stopped responding")); @@ -415,10 +416,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) msleep(1); /* minimum sleep to prevent looping allowing socket to clear and app threads to set tcpStatus CifsNeedReconnect if server hung */ - if (pdu_length < 4) - goto incomplete_rcv; - else - continue; + continue; } else if (length <= 0) { if (server->tcpStatus == CifsNew) { cFYI(1, ("tcp session abend after SMBnegprot")); @@ -439,11 +437,13 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) wake_up(&server->response_q); continue; } else if (length < 4) { - cFYI(1, ("less than four bytes received (%d bytes)", + cFYI(1, + ("Frame under four bytes received (%d bytes long)", length)); - pdu_length -= length; - msleep(1); - goto incomplete_rcv; + cifs_reconnect(server); + csocket = server->ssocket; + wake_up(&server->response_q); + continue; } /* The right amount was read from socket - 4 bytes */ @@ -504,7 +504,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) /* else we have an SMB response */ if ((pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) || - (pdu_length < sizeof(struct smb_hdr) - 1 - 4)) { + (pdu_length < sizeof (struct smb_hdr) - 1 - 4)) { cERROR(1, ("Invalid size SMB length %d pdu_length %d", length, pdu_length+4)); cifs_reconnect(server); @@ -528,7 +528,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) total_read += length) { length = kernel_recvmsg(csocket, &smb_msg, &iov, 1, pdu_length - total_read, 0); - if (kthread_should_stop() || + if ( kthread_should_stop() || (length == -EINTR)) { /* then will exit */ reconnect = 2; @@ -546,7 +546,6 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) allowing socket to clear and app threads to set tcpStatus CifsNeedReconnect if server hung*/ - length = 0; continue; } else if (length <= 0) { cERROR(1, ("Received no data, expecting %d", @@ -632,9 +631,9 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) /* Was previous buf put in mpx struct for multi-rsp? */ if (!isMultiRsp) { /* smb buffer will be freed by user thread */ - if (isLargeBuf) + if (isLargeBuf) { bigbuf = NULL; - else + } else smallbuf = NULL; } wake_up_process(task_to_wake); @@ -677,8 +676,9 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) server->ssocket = NULL; } /* buffer usuallly freed in free_mid - need to free it here on exit */ - cifs_buf_release(bigbuf); - if (smallbuf) /* no sense logging a debug message if NULL */ + if (bigbuf != NULL) + cifs_buf_release(bigbuf); + if (smallbuf != NULL) cifs_small_buf_release(smallbuf); read_lock(&GlobalSMBSeslock); @@ -702,8 +702,9 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) list_for_each(tmp, &GlobalSMBSessionList) { ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList); - if (ses->server == server) + if (ses->server == server) { ses->status = CifsExiting; + } } spin_lock(&GlobalMid_Lock); @@ -713,8 +714,9 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) cFYI(1, ("Clearing Mid 0x%x - waking up ", mid_entry->mid)); task_to_wake = mid_entry->tsk; - if (task_to_wake) + if (task_to_wake) { wake_up_process(task_to_wake); + } } } spin_unlock(&GlobalMid_Lock); @@ -747,15 +749,18 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) list_for_each(tmp, &GlobalSMBSessionList) { ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList); - if (ses->server == server) + if (ses->server == server) { ses->server = NULL; + } } write_unlock(&GlobalSMBSeslock); kfree(server); - if (length > 0) - mempool_resize(cifs_req_poolp, length + cifs_min_rcv, - GFP_KERNEL); + if (length > 0) { + mempool_resize(cifs_req_poolp, + length + cifs_min_rcv, + GFP_KERNEL); + } return 0; } @@ -1472,7 +1477,7 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket, if (psin_server->sin_port) { /* user overrode default port */ rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *) psin_server, - sizeof(struct sockaddr_in), 0); + sizeof (struct sockaddr_in), 0); if (rc >= 0) connected = 1; } @@ -1488,7 +1493,7 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket, rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *) psin_server, - sizeof(struct sockaddr_in), 0); + sizeof (struct sockaddr_in), 0); if (rc >= 0) connected = 1; } @@ -1497,7 +1502,7 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket, psin_server->sin_port = htons(RFC1001_PORT); rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *) psin_server, - sizeof(struct sockaddr_in), 0); + sizeof (struct sockaddr_in), 0); if (rc >= 0) connected = 1; } @@ -1605,7 +1610,7 @@ ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket) if (psin_server->sin6_port) { /* user overrode default port */ rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *) psin_server, - sizeof(struct sockaddr_in6), 0); + sizeof (struct sockaddr_in6), 0); if (rc >= 0) connected = 1; } @@ -1621,7 +1626,7 @@ ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket) rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *) psin_server, - sizeof(struct sockaddr_in6), 0); + sizeof (struct sockaddr_in6), 0); if (rc >= 0) connected = 1; } @@ -1629,7 +1634,7 @@ ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket) if (!connected) { psin_server->sin6_port = htons(RFC1001_PORT); rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *) - psin_server, sizeof(struct sockaddr_in6), 0); + psin_server, sizeof (struct sockaddr_in6), 0); if (rc >= 0) connected = 1; } @@ -1745,16 +1750,7 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon, cFYI(1, ("very large write cap")); #endif /* CIFS_DEBUG2 */ if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) { - if (vol_info == NULL) { - cFYI(1, ("resetting capabilities failed")); - } else - cERROR(1, ("Negotiating Unix capabilities " - "with the server failed. Consider " - "mounting with the Unix Extensions\n" - "disabled, if problems are found, " - "by specifying the nounix mount " - "option.")); - + cFYI(1, ("setting capabilities failed")); } } } @@ -1913,8 +1909,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, return rc; } - srvTcp = kzalloc(sizeof(struct TCP_Server_Info), GFP_KERNEL); - if (!srvTcp) { + srvTcp = kmalloc(sizeof (struct TCP_Server_Info), GFP_KERNEL); + if (srvTcp == NULL) { rc = -ENOMEM; sock_release(csocket); kfree(volume_info.UNC); @@ -1923,8 +1919,9 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, FreeXid(xid); return rc; } else { + memset(srvTcp, 0, sizeof (struct TCP_Server_Info)); memcpy(&srvTcp->addr.sockAddr, &sin_server, - sizeof(struct sockaddr_in)); + sizeof (struct sockaddr_in)); atomic_set(&srvTcp->inFlight, 0); /* BB Add code for ipv6 case too */ srvTcp->ssocket = csocket; @@ -2176,18 +2173,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, if (tsk) kthread_stop(tsk); } - } else { + } else cFYI(1, ("No session or bad tcon")); - if ((pSesInfo->server) && - (pSesInfo->server->tsk)) { - struct task_struct *tsk; - force_sig(SIGKILL, - pSesInfo->server->tsk); - tsk = pSesInfo->server->tsk; - if (tsk) - kthread_stop(tsk); - } - } sesInfoFree(pSesInfo); /* pSesInfo = NULL; */ } @@ -2198,10 +2185,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, tcon->ses = pSesInfo; /* do not care if following two calls succeed - informational */ - if (!tcon->ipc) { - CIFSSMBQFSDeviceInfo(xid, tcon); - CIFSSMBQFSAttributeInfo(xid, tcon); - } + CIFSSMBQFSDeviceInfo(xid, tcon); + CIFSSMBQFSAttributeInfo(xid, tcon); /* tell server which Unix caps we support */ if (tcon->ses->capabilities & CAP_UNIX) @@ -2541,7 +2526,8 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, sesssetup_nomem: /* do not return an error on nomem for the info strings, since that could make reconnection harder, and reconnection might be needed to free memory */ - cifs_buf_release(smb_buffer); + if (smb_buffer) + cifs_buf_release(smb_buffer); return rc; } @@ -2561,7 +2547,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, int remaining_words = 0; int bytes_returned = 0; int len; - int SecurityBlobLength = sizeof(NEGOTIATE_MESSAGE); + int SecurityBlobLength = sizeof (NEGOTIATE_MESSAGE); PNEGOTIATE_MESSAGE SecurityBlob; PCHALLENGE_MESSAGE SecurityBlob2; __u32 negotiate_flags, capabilities; @@ -2879,14 +2865,15 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, rc = -EIO; } - cifs_buf_release(smb_buffer); + if (smb_buffer) + cifs_buf_release(smb_buffer); return rc; } static int CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, - char *ntlm_session_key, int ntlmv2_flag, - const struct nls_table *nls_codepage) + char *ntlm_session_key, int ntlmv2_flag, + const struct nls_table *nls_codepage) { struct smb_hdr *smb_buffer; struct smb_hdr *smb_buffer_response; @@ -2899,7 +2886,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, int remaining_words = 0; int bytes_returned = 0; int len; - int SecurityBlobLength = sizeof(AUTHENTICATE_MESSAGE); + int SecurityBlobLength = sizeof (AUTHENTICATE_MESSAGE); PAUTHENTICATE_MESSAGE SecurityBlob; __u32 negotiate_flags, capabilities; __u16 count; @@ -2914,8 +2901,8 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, return -ENOMEM; } smb_buffer_response = smb_buffer; - pSMB = (SESSION_SETUP_ANDX *)smb_buffer; - pSMBr = (SESSION_SETUP_ANDX *)smb_buffer_response; + pSMB = (SESSION_SETUP_ANDX *) smb_buffer; + pSMBr = (SESSION_SETUP_ANDX *) smb_buffer_response; /* send SMBsessionSetup here */ header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX, @@ -2934,7 +2921,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE; capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS | - CAP_EXTENDED_SECURITY; + CAP_EXTENDED_SECURITY; if (ses->capabilities & CAP_UNICODE) { smb_buffer->Flags2 |= SMBFLG2_UNICODE; capabilities |= CAP_UNICODE; @@ -2949,14 +2936,15 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, } pSMB->req.Capabilities = cpu_to_le32(capabilities); - bcc_ptr = (char *)&pSMB->req.SecurityBlob; - SecurityBlob = (PAUTHENTICATE_MESSAGE)bcc_ptr; + bcc_ptr = (char *) &pSMB->req.SecurityBlob; + SecurityBlob = (PAUTHENTICATE_MESSAGE) bcc_ptr; strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8); SecurityBlob->MessageType = NtLmAuthenticate; bcc_ptr += SecurityBlobLength; - negotiate_flags = NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET | - NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_TARGET_INFO | - 0x80000000 | NTLMSSP_NEGOTIATE_128; + negotiate_flags = + NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET | + NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_TARGET_INFO | + 0x80000000 | NTLMSSP_NEGOTIATE_128; if (sign_CIFS_PDUs) negotiate_flags |= /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN |*/ NTLMSSP_NEGOTIATE_SIGN; if (ntlmv2_flag) @@ -2991,32 +2979,36 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, SecurityBlob->DomainName.Length = 0; SecurityBlob->DomainName.MaximumLength = 0; } else { - __u16 ln = cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64, + __u16 len = + cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64, nls_codepage); - ln *= 2; + len *= 2; SecurityBlob->DomainName.MaximumLength = - cpu_to_le16(ln); + cpu_to_le16(len); SecurityBlob->DomainName.Buffer = cpu_to_le32(SecurityBlobLength); - bcc_ptr += ln; - SecurityBlobLength += ln; - SecurityBlob->DomainName.Length = cpu_to_le16(ln); + bcc_ptr += len; + SecurityBlobLength += len; + SecurityBlob->DomainName.Length = + cpu_to_le16(len); } if (user == NULL) { SecurityBlob->UserName.Buffer = 0; SecurityBlob->UserName.Length = 0; SecurityBlob->UserName.MaximumLength = 0; } else { - __u16 ln = cifs_strtoUCS((__le16 *) bcc_ptr, user, 64, + __u16 len = + cifs_strtoUCS((__le16 *) bcc_ptr, user, 64, nls_codepage); - ln *= 2; + len *= 2; SecurityBlob->UserName.MaximumLength = - cpu_to_le16(ln); + cpu_to_le16(len); SecurityBlob->UserName.Buffer = cpu_to_le32(SecurityBlobLength); - bcc_ptr += ln; - SecurityBlobLength += ln; - SecurityBlob->UserName.Length = cpu_to_le16(ln); + bcc_ptr += len; + SecurityBlobLength += len; + SecurityBlob->UserName.Length = + cpu_to_le16(len); } /* SecurityBlob->WorkstationName.Length = @@ -3060,32 +3052,33 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, SecurityBlob->DomainName.Length = 0; SecurityBlob->DomainName.MaximumLength = 0; } else { - __u16 ln; + __u16 len; negotiate_flags |= NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED; strncpy(bcc_ptr, domain, 63); - ln = strnlen(domain, 64); + len = strnlen(domain, 64); SecurityBlob->DomainName.MaximumLength = - cpu_to_le16(ln); + cpu_to_le16(len); SecurityBlob->DomainName.Buffer = cpu_to_le32(SecurityBlobLength); - bcc_ptr += ln; - SecurityBlobLength += ln; - SecurityBlob->DomainName.Length = cpu_to_le16(ln); + bcc_ptr += len; + SecurityBlobLength += len; + SecurityBlob->DomainName.Length = cpu_to_le16(len); } if (user == NULL) { SecurityBlob->UserName.Buffer = 0; SecurityBlob->UserName.Length = 0; SecurityBlob->UserName.MaximumLength = 0; } else { - __u16 ln; + __u16 len; strncpy(bcc_ptr, user, 63); - ln = strnlen(user, 64); - SecurityBlob->UserName.MaximumLength = cpu_to_le16(ln); + len = strnlen(user, 64); + SecurityBlob->UserName.MaximumLength = + cpu_to_le16(len); SecurityBlob->UserName.Buffer = - cpu_to_le32(SecurityBlobLength); - bcc_ptr += ln; - SecurityBlobLength += ln; - SecurityBlob->UserName.Length = cpu_to_le16(ln); + cpu_to_le32(SecurityBlobLength); + bcc_ptr += len; + SecurityBlobLength += len; + SecurityBlob->UserName.Length = cpu_to_le16(len); } /* BB fill in our workstation name if known BB */ @@ -3107,11 +3100,12 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &bytes_returned, 1); if (rc) { -/* rc = map_smb_to_linux_error(smb_buffer_response) done in SendReceive now */ - } else if ((smb_buffer_response->WordCount == 3) || - (smb_buffer_response->WordCount == 4)) { +/* rc = map_smb_to_linux_error(smb_buffer_response); *//* done in SendReceive now */ + } else if ((smb_buffer_response->WordCount == 3) + || (smb_buffer_response->WordCount == 4)) { __u16 action = le16_to_cpu(pSMBr->resp.Action); - __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength); + __u16 blob_len = + le16_to_cpu(pSMBr->resp.SecurityBlobLength); if (action & GUEST_LOGIN) cFYI(1, (" Guest login")); /* BB Should we set anything in SesInfo struct ? */ @@ -3151,8 +3145,8 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, } else { remaining_words = BCC(smb_buffer_response) / 2; } - len = UniStrnlen((wchar_t *) bcc_ptr, - remaining_words - 1); + len = + UniStrnlen((wchar_t *) bcc_ptr,remaining_words - 1); /* We look for obvious messed up bcc or strings in response so we do not go off the end since (at least) WIN2K and Windows XP have a major bug in not null terminating last Unicode string in response */ @@ -3236,7 +3230,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, <= BCC(smb_buffer_response)) { if (ses->serverOS) kfree(ses->serverOS); - ses->serverOS = kzalloc(len + 1, GFP_KERNEL); + ses->serverOS = kzalloc(len + 1,GFP_KERNEL); strncpy(ses->serverOS,bcc_ptr, len); bcc_ptr += len; @@ -3265,24 +3259,28 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, bcc_ptr[0] = 0; bcc_ptr++; } else - cFYI(1, ("field of length %d " + cFYI(1, + ("field of length %d " "extends beyond end of smb ", len)); } } else { - cERROR(1, ("Security Blob extends beyond end " + cERROR(1, + (" Security Blob extends beyond end " "of SMB")); } } else { cERROR(1, ("No session structure passed in.")); } } else { - cERROR(1, ("Invalid Word count %d: ", + cERROR(1, + (" Invalid Word count %d: ", smb_buffer_response->WordCount)); rc = -EIO; } - cifs_buf_release(smb_buffer); + if (smb_buffer) + cifs_buf_release(smb_buffer); return rc; } @@ -3391,18 +3389,6 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, bcc_ptr = pByteArea(smb_buffer_response); length = strnlen(bcc_ptr, BCC(smb_buffer_response) - 2); /* skip service field (NB: this field is always ASCII) */ - if (length == 3) { - if ((bcc_ptr[0] == 'I') && (bcc_ptr[1] == 'P') && - (bcc_ptr[2] == 'C')) { - cFYI(1, ("IPC connection")); - tcon->ipc = 1; - } - } else if (length == 2) { - if ((bcc_ptr[0] == 'A') && (bcc_ptr[1] == ':')) { - /* the most common case */ - cFYI(1, ("disk share connection")); - } - } bcc_ptr += length + 1; strncpy(tcon->treeName, tree, MAX_TREE_SIZE); if (smb_buffer->Flags2 & SMBFLG2_UNICODE) { @@ -3413,11 +3399,9 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, kfree(tcon->nativeFileSystem); tcon->nativeFileSystem = kzalloc(length + 2, GFP_KERNEL); - if (tcon->nativeFileSystem) - cifs_strfromUCS_le( - tcon->nativeFileSystem, - (__le16 *) bcc_ptr, - length, nls_codepage); + cifs_strfromUCS_le(tcon->nativeFileSystem, + (__le16 *) bcc_ptr, + length, nls_codepage); bcc_ptr += 2 * length; bcc_ptr[0] = 0; /* null terminate the string */ bcc_ptr[1] = 0; @@ -3432,9 +3416,8 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, kfree(tcon->nativeFileSystem); tcon->nativeFileSystem = kzalloc(length + 1, GFP_KERNEL); - if (tcon->nativeFileSystem) - strncpy(tcon->nativeFileSystem, bcc_ptr, - length); + strncpy(tcon->nativeFileSystem, bcc_ptr, + length); } /* else do not bother copying these information fields*/ } @@ -3450,7 +3433,8 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, ses->ipc_tid = smb_buffer_response->Tid; } - cifs_buf_release(smb_buffer); + if (smb_buffer) + cifs_buf_release(smb_buffer); return rc; } diff --git a/trunk/fs/cifs/dir.c b/trunk/fs/cifs/dir.c index 793404b10925..4830acc86d74 100644 --- a/trunk/fs/cifs/dir.c +++ b/trunk/fs/cifs/dir.c @@ -3,7 +3,7 @@ * * vfs operations that deal with dentries * - * Copyright (C) International Business Machines Corp., 2002,2007 + * Copyright (C) International Business Machines Corp., 2002,2005 * Author(s): Steve French (sfrench@us.ibm.com) * * This library is free software; you can redistribute it and/or modify @@ -269,7 +269,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, CIFSSMBClose(xid, pTcon, fileHandle); } else if (newinode) { pCifsFile = - kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL); + kzalloc(sizeof (struct cifsFileInfo), GFP_KERNEL); if (pCifsFile == NULL) goto cifs_create_out; @@ -397,7 +397,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, /* BB Do not bother to decode buf since no local inode yet to put timestamps in, but we can reuse it safely */ - unsigned int bytes_written; + int bytes_written; struct win_dev *pdev; pdev = (struct win_dev *)buf; if (S_ISCHR(mode)) { @@ -450,7 +450,8 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, xid = GetXid(); - cFYI(1, (" parent inode = 0x%p name is: %s and dentry = 0x%p", + cFYI(1, + (" parent inode = 0x%p name is: %s and dentry = 0x%p", parent_dir_inode, direntry->d_name.name, direntry)); /* check whether path exists */ diff --git a/trunk/fs/cifs/export.c b/trunk/fs/cifs/export.c index d614b91caeca..893fd0aebff8 100644 --- a/trunk/fs/cifs/export.c +++ b/trunk/fs/cifs/export.c @@ -43,7 +43,6 @@ #include #include "cifsglob.h" #include "cifs_debug.h" -#include "cifsfs.h" #ifdef CONFIG_CIFS_EXPERIMENTAL static struct dentry *cifs_get_parent(struct dentry *dentry) diff --git a/trunk/fs/cifs/file.c b/trunk/fs/cifs/file.c index 1e7e4c06d9e3..894b1f7b299d 100644 --- a/trunk/fs/cifs/file.c +++ b/trunk/fs/cifs/file.c @@ -467,7 +467,7 @@ static int cifs_reopen_file(struct file *file, int can_flush) int cifs_close(struct inode *inode, struct file *file) { int rc = 0; - int xid, timeout; + int xid; struct cifs_sb_info *cifs_sb; struct cifsTconInfo *pTcon; struct cifsFileInfo *pSMBFile = @@ -485,9 +485,9 @@ int cifs_close(struct inode *inode, struct file *file) /* no sense reconnecting to close a file that is already closed */ if (pTcon->tidStatus != CifsNeedReconnect) { - timeout = 2; + int timeout = 2; while ((atomic_read(&pSMBFile->wrtPending) != 0) - && (timeout <= 2048)) { + && (timeout < 1000) ) { /* Give write a better chance to get to server ahead of the close. We do not want to add a wait_q here as it would @@ -522,30 +522,12 @@ int cifs_close(struct inode *inode, struct file *file) list_del(&pSMBFile->flist); list_del(&pSMBFile->tlist); write_unlock(&GlobalSMBSeslock); - timeout = 10; - /* We waited above to give the SMBWrite a chance to issue - on the wire (so we do not get SMBWrite returning EBADF - if writepages is racing with close. Note that writepages - does not specify a file handle, so it is possible for a file - to be opened twice, and the application close the "wrong" - file handle - in these cases we delay long enough to allow - the SMBWrite to get on the wire before the SMB Close. - We allow total wait here over 45 seconds, more than - oplock break time, and more than enough to allow any write - to complete on the server, or to time out on the client */ - while ((atomic_read(&pSMBFile->wrtPending) != 0) - && (timeout <= 50000)) { - cERROR(1, ("writes pending, delay free of handle")); - msleep(timeout); - timeout *= 8; - } kfree(pSMBFile->search_resume_name); kfree(file->private_data); file->private_data = NULL; } else rc = -EBADF; - read_lock(&GlobalSMBSeslock); if (list_empty(&(CIFS_I(inode)->openFileList))) { cFYI(1, ("closing last open instance for inode %p", inode)); /* if the file is not open we do not know if we can cache info @@ -553,7 +535,6 @@ int cifs_close(struct inode *inode, struct file *file) CIFS_I(inode)->clientCanCacheRead = FALSE; CIFS_I(inode)->clientCanCacheAll = FALSE; } - read_unlock(&GlobalSMBSeslock); if ((rc == 0) && CIFS_I(inode)->write_behind_rc) rc = CIFS_I(inode)->write_behind_rc; FreeXid(xid); @@ -786,8 +767,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) mutex_lock(&fid->lock_mutex); list_for_each_entry_safe(li, tmp, &fid->llist, llist) { if (pfLock->fl_start <= li->offset && - (pfLock->fl_start + length) >= - (li->offset + li->length)) { + length >= li->length) { stored_rc = CIFSSMBLock(xid, pTcon, netfid, li->length, li->offset, @@ -1042,7 +1022,6 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode) } read_lock(&GlobalSMBSeslock); -refind_writable: list_for_each_entry(open_file, &cifs_inode->openFileList, flist) { if (open_file->closePend) continue; @@ -1050,49 +1029,24 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode) ((open_file->pfile->f_flags & O_RDWR) || (open_file->pfile->f_flags & O_WRONLY))) { atomic_inc(&open_file->wrtPending); - - if (!open_file->invalidHandle) { - /* found a good writable file */ - read_unlock(&GlobalSMBSeslock); - return open_file; - } - read_unlock(&GlobalSMBSeslock); - /* Had to unlock since following call can block */ - rc = cifs_reopen_file(open_file->pfile, FALSE); - if (!rc) { - if (!open_file->closePend) - return open_file; - else { /* start over in case this was deleted */ - /* since the list could be modified */ + if ((open_file->invalidHandle) && + (!open_file->closePend) /* BB fixme -since the second clause can not be true remove it BB */) { + rc = cifs_reopen_file(open_file->pfile, FALSE); + /* if it fails, try another handle - might be */ + /* dangerous to hold up writepages with retry */ + if (rc) { + cFYI(1, + ("failed on reopen file in wp")); read_lock(&GlobalSMBSeslock); - atomic_dec(&open_file->wrtPending); - goto refind_writable; + /* can not use this handle, no write + pending on this one after all */ + atomic_dec + (&open_file->wrtPending); + continue; } } - - /* if it fails, try another handle if possible - - (we can not do this if closePending since - loop could be modified - in which case we - have to start at the beginning of the list - again. Note that it would be bad - to hold up writepages here (rather than - in caller) with continuous retries */ - cFYI(1, ("wp failed on reopen file")); - read_lock(&GlobalSMBSeslock); - /* can not use this handle, no write - pending on this one after all */ - atomic_dec(&open_file->wrtPending); - - if (open_file->closePend) /* list could have changed */ - goto refind_writable; - /* else we simply continue to the next entry. Thus - we do not loop on reopen errors. If we - can not reopen the file, for example if we - reconnected to a server with another client - racing to delete or lock the file we would not - make progress if we restarted before the beginning - of the loop here. */ + return open_file; } } read_unlock(&GlobalSMBSeslock); @@ -1755,7 +1709,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, struct page *page; struct cifs_sb_info *cifs_sb; struct cifsTconInfo *pTcon; - unsigned int bytes_read = 0; + int bytes_read = 0; unsigned int read_size, i; char *smb_read_data = NULL; struct smb_com_read_rsp *pSMBr; @@ -1849,7 +1803,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, i += bytes_read >> PAGE_CACHE_SHIFT; cifs_stats_bytes_read(pTcon, bytes_read); - if ((bytes_read & PAGE_CACHE_MASK) != bytes_read) { + if ((int)(bytes_read & PAGE_CACHE_MASK) != bytes_read) { i++; /* account for partial page */ /* server copy of file can have smaller size diff --git a/trunk/fs/cifs/inode.c b/trunk/fs/cifs/inode.c index 5e8b388be3b6..dd4167762a8e 100644 --- a/trunk/fs/cifs/inode.c +++ b/trunk/fs/cifs/inode.c @@ -115,7 +115,7 @@ int cifs_get_inode_info_unix(struct inode **pinode, inode->i_mode = le64_to_cpu(findData.Permissions); /* since we set the inode type below we need to mask off to avoid strange results if bits set above */ - inode->i_mode &= ~S_IFMT; + inode->i_mode &= ~S_IFMT; if (type == UNIX_FILE) { inode->i_mode |= S_IFREG; } else if (type == UNIX_SYMLINK) { @@ -575,33 +575,19 @@ int cifs_get_inode_info(struct inode **pinode, return rc; } -static const struct inode_operations cifs_ipc_inode_ops = { - .lookup = cifs_lookup, -}; - /* gets root inode */ void cifs_read_inode(struct inode *inode) { - int xid, rc; + int xid; struct cifs_sb_info *cifs_sb; cifs_sb = CIFS_SB(inode->i_sb); xid = GetXid(); if (cifs_sb->tcon->unix_ext) - rc = cifs_get_inode_info_unix(&inode, "", inode->i_sb, xid); + cifs_get_inode_info_unix(&inode, "", inode->i_sb, xid); else - rc = cifs_get_inode_info(&inode, "", NULL, inode->i_sb, xid); - if (rc && cifs_sb->tcon->ipc) { - cFYI(1, ("ipc connection - fake read inode")); - inode->i_mode |= S_IFDIR; - inode->i_nlink = 2; - inode->i_op = &cifs_ipc_inode_ops; - inode->i_fop = &simple_dir_operations; - inode->i_uid = cifs_sb->mnt_uid; - inode->i_gid = cifs_sb->mnt_gid; - } - + cifs_get_inode_info(&inode, "", NULL, inode->i_sb, xid); /* can not call macro FreeXid here since in a void func */ _FreeXid(xid); } @@ -933,25 +919,18 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) goto mkdir_out; } - mode &= ~current->fs->umask; rc = CIFSPOSIXCreate(xid, pTcon, SMB_O_DIRECTORY | SMB_O_CREAT, mode, NULL /* netfid */, pInfo, &oplock, full_path, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); - if (rc == -EOPNOTSUPP) { - kfree(pInfo); - goto mkdir_retry_old; - } else if (rc) { + if (rc) { cFYI(1, ("posix mkdir returned 0x%x", rc)); d_drop(direntry); } else { int obj_type; - if (pInfo->Type == cpu_to_le32(-1)) { - /* no return info, go query for it */ - kfree(pInfo); + if (pInfo->Type == -1) /* no return info - go query */ goto mkdir_get_info; - } /*BB check (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID ) to see if need to set uid/gid */ inc_nlink(inode); @@ -961,10 +940,8 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) direntry->d_op = &cifs_dentry_ops; newinode = new_inode(inode->i_sb); - if (newinode == NULL) { - kfree(pInfo); + if (newinode == NULL) goto mkdir_get_info; - } /* Is an i_ino of zero legal? */ /* Are there sanity checks we can use to ensure that the server is really filling in that field? */ @@ -995,7 +972,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) kfree(pInfo); goto mkdir_out; } -mkdir_retry_old: + /* BB add setting the equivalent of mode via CreateX w/ACLs */ rc = CIFSSMBMkDir(xid, pTcon, full_path, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); @@ -1400,17 +1377,8 @@ static int cifs_vmtruncate(struct inode *inode, loff_t offset) } i_size_write(inode, offset); spin_unlock(&inode->i_lock); - /* - * unmap_mapping_range is called twice, first simply for efficiency - * so that truncate_inode_pages does fewer single-page unmaps. However - * after this first call, and before truncate_inode_pages finishes, - * it is possible for private pages to be COWed, which remain after - * truncate_inode_pages finishes, hence the second unmap_mapping_range - * call must be made for correctness. - */ unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1); truncate_inode_pages(mapping, offset); - unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1); goto out_truncate; do_expand: @@ -1501,7 +1469,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) atomic_dec(&open_file->wrtPending); cFYI(1, ("SetFSize for attrs rc = %d", rc)); if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { - unsigned int bytes_written; + int bytes_written; rc = CIFSSMBWrite(xid, pTcon, nfid, 0, attrs->ia_size, &bytes_written, NULL, NULL, @@ -1534,7 +1502,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); if (rc == 0) { - unsigned int bytes_written; + int bytes_written; rc = CIFSSMBWrite(xid, pTcon, netfid, 0, attrs->ia_size, @@ -1570,11 +1538,6 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) } time_buf.Attributes = 0; - - /* skip mode change if it's just for clearing setuid/setgid */ - if (attrs->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID)) - attrs->ia_valid &= ~ATTR_MODE; - if (attrs->ia_valid & ATTR_MODE) { cFYI(1, ("Mode changed to 0x%x", attrs->ia_mode)); mode = attrs->ia_mode; diff --git a/trunk/fs/cifs/link.c b/trunk/fs/cifs/link.c index 11f265726db7..6a85ef7b8797 100644 --- a/trunk/fs/cifs/link.c +++ b/trunk/fs/cifs/link.c @@ -237,7 +237,7 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen) char *tmp_path = NULL; char *tmpbuffer; unsigned char *referrals = NULL; - unsigned int num_referrals = 0; + int num_referrals = 0; int len; __u16 fid; diff --git a/trunk/fs/cifs/misc.c b/trunk/fs/cifs/misc.c index 51ec681fe74a..0bcec0844bee 100644 --- a/trunk/fs/cifs/misc.c +++ b/trunk/fs/cifs/misc.c @@ -169,6 +169,7 @@ cifs_buf_get(void) void cifs_buf_release(void *buf_to_free) { + if (buf_to_free == NULL) { /* cFYI(1, ("Null buffer passed to cifs_buf_release"));*/ return; diff --git a/trunk/fs/cifs/netmisc.c b/trunk/fs/cifs/netmisc.c index f06359cb22ee..2bfed3f45d0f 100644 --- a/trunk/fs/cifs/netmisc.c +++ b/trunk/fs/cifs/netmisc.c @@ -114,16 +114,10 @@ static const struct smb_to_posix_error mapping_table_ERRSRV[] = { {ERRusempx, -EIO}, {ERRusestd, -EIO}, {ERR_NOTIFY_ENUM_DIR, -ENOBUFS}, - {ERRnoSuchUser, -EACCES}, -/* {ERRaccountexpired, -EACCES}, + {ERRaccountexpired, -EACCES}, {ERRbadclient, -EACCES}, {ERRbadLogonTime, -EACCES}, - {ERRpasswordExpired, -EACCES},*/ - {ERRaccountexpired, -EKEYEXPIRED}, - {ERRbadclient, -EACCES}, - {ERRbadLogonTime, -EACCES}, - {ERRpasswordExpired, -EKEYEXPIRED}, - + {ERRpasswordExpired, -EACCES}, {ERRnosupport, -EINVAL}, {0, 0} }; @@ -276,7 +270,7 @@ static const struct { from NT_STATUS_NO_SUCH_USER to NT_STATUS_LOGON_FAILURE during the session setup } */ { - ERRDOS, ERRnoaccess, NT_STATUS_NO_SUCH_USER}, { /* could map to 2238 */ + ERRDOS, ERRnoaccess, NT_STATUS_NO_SUCH_USER}, { ERRHRD, ERRgeneral, NT_STATUS_GROUP_EXISTS}, { ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_GROUP}, { ERRHRD, ERRgeneral, NT_STATUS_MEMBER_IN_GROUP}, { @@ -291,10 +285,10 @@ static const struct { ERRHRD, ERRgeneral, NT_STATUS_PASSWORD_RESTRICTION}, { ERRDOS, ERRnoaccess, NT_STATUS_LOGON_FAILURE}, { ERRHRD, ERRgeneral, NT_STATUS_ACCOUNT_RESTRICTION}, { - ERRSRV, ERRbadLogonTime, NT_STATUS_INVALID_LOGON_HOURS}, { - ERRSRV, ERRbadclient, NT_STATUS_INVALID_WORKSTATION}, { + ERRSRV, 2241, NT_STATUS_INVALID_LOGON_HOURS}, { + ERRSRV, 2240, NT_STATUS_INVALID_WORKSTATION}, { ERRSRV, ERRpasswordExpired, NT_STATUS_PASSWORD_EXPIRED}, { - ERRSRV, ERRaccountexpired, NT_STATUS_ACCOUNT_DISABLED}, { + ERRSRV, 2239, NT_STATUS_ACCOUNT_DISABLED}, { ERRHRD, ERRgeneral, NT_STATUS_NONE_MAPPED}, { ERRHRD, ERRgeneral, NT_STATUS_TOO_MANY_LUIDS_REQUESTED}, { ERRHRD, ERRgeneral, NT_STATUS_LUIDS_EXHAUSTED}, { @@ -591,7 +585,7 @@ static const struct { ERRDOS, ERRnoaccess, NT_STATUS_TRUST_FAILURE}, { ERRHRD, ERRgeneral, NT_STATUS_MUTANT_LIMIT_EXCEEDED}, { ERRDOS, ERRnetlogonNotStarted, NT_STATUS_NETLOGON_NOT_STARTED}, { - ERRSRV, ERRaccountexpired, NT_STATUS_ACCOUNT_EXPIRED}, { + ERRSRV, 2239, NT_STATUS_ACCOUNT_EXPIRED}, { ERRHRD, ERRgeneral, NT_STATUS_POSSIBLE_DEADLOCK}, { ERRHRD, ERRgeneral, NT_STATUS_NETWORK_CREDENTIAL_CONFLICT}, { ERRHRD, ERRgeneral, NT_STATUS_REMOTE_SESSION_LIMIT}, { @@ -760,7 +754,7 @@ ntstatus_to_dos(__u32 ntstatus, __u8 * eclass, __u16 * ecode) } int -map_smb_to_linux_error(struct smb_hdr *smb, int logErr) +map_smb_to_linux_error(struct smb_hdr *smb) { unsigned int i; int rc = -EIO; /* if transport error smb error may not be set */ @@ -777,9 +771,7 @@ map_smb_to_linux_error(struct smb_hdr *smb, int logErr) /* translate the newer STATUS codes to old style SMB errors * and then to POSIX errors */ __u32 err = le32_to_cpu(smb->Status.CifsError); - if (logErr && (err != (NT_STATUS_MORE_PROCESSING_REQUIRED))) - cifs_print_status(err); - else if (cifsFYI & CIFS_RC) + if (cifsFYI & CIFS_RC) cifs_print_status(err); ntstatus_to_dos(err, &smberrclass, &smberrcode); } else { @@ -821,7 +813,7 @@ map_smb_to_linux_error(struct smb_hdr *smb, int logErr) } /* else ERRHRD class errors or junk - return EIO */ - cFYI(1, ("Mapping smb error code %d to POSIX err %d", + cFYI(1, (" !!Mapping smb error code %d to POSIX err %d !!", smberrcode, rc)); /* generic corrective action e.g. reconnect SMB session on @@ -907,11 +899,8 @@ struct timespec cnvrtDosUnixTm(__u16 date, __u16 time) cERROR(1, ("illegal hours %d", st->Hours)); days = sd->Day; month = sd->Month; - if ((days > 31) || (month > 12)) { + if ((days > 31) || (month > 12)) cERROR(1, ("illegal date, month %d day: %d", month, days)); - if (month > 12) - month = 12; - } month -= 1; days += total_days_of_prev_months[month]; days += 3652; /* account for difference in days between 1980 and 1970 */ diff --git a/trunk/fs/cifs/readdir.c b/trunk/fs/cifs/readdir.c index 3746580e9701..916df9431336 100644 --- a/trunk/fs/cifs/readdir.c +++ b/trunk/fs/cifs/readdir.c @@ -121,7 +121,7 @@ static void AdjustForTZ(struct cifsTconInfo *tcon, struct inode *inode) static void fill_in_inode(struct inode *tmp_inode, int new_buf_type, - char *buf, unsigned int *pobject_type, int isNewInode) + char *buf, int *pobject_type, int isNewInode) { loff_t local_size; struct timespec local_mtime; @@ -294,7 +294,7 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type, } static void unix_fill_in_inode(struct inode *tmp_inode, - FILE_UNIX_INFO *pfindData, unsigned int *pobject_type, int isNewInode) + FILE_UNIX_INFO *pfindData, int *pobject_type, int isNewInode) { loff_t local_size; struct timespec local_mtime; @@ -826,7 +826,7 @@ static int cifs_filldir(char *pfindEntry, struct file *file, int rc = 0; struct qstr qstring; struct cifsFileInfo *pCifsF; - unsigned int obj_type; + unsigned obj_type; ino_t inum; struct cifs_sb_info *cifs_sb; struct inode *tmp_inode; @@ -1067,7 +1067,7 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir) for (i = 0; (i < num_to_fill) && (rc == 0); i++) { if (current_entry == NULL) { /* evaluate whether this case is an error */ - cERROR(1, ("past SMB end, num to fill %d i %d", + cERROR(1,("past end of SMB num to fill %d i %d", num_to_fill, i)); break; } diff --git a/trunk/fs/cifs/sess.c b/trunk/fs/cifs/sess.c index 899dc6078d9a..892be9b4d1f3 100644 --- a/trunk/fs/cifs/sess.c +++ b/trunk/fs/cifs/sess.c @@ -67,59 +67,14 @@ static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB) pSMB->req.hdr.Flags2 |= SMBFLG2_DFS; capabilities |= CAP_DFS; } - if (ses->capabilities & CAP_UNIX) + if (ses->capabilities & CAP_UNIX) { capabilities |= CAP_UNIX; + } /* BB check whether to init vcnum BB */ return capabilities; } -static void -unicode_oslm_strings(char **pbcc_area, const struct nls_table *nls_cp) -{ - char *bcc_ptr = *pbcc_area; - int bytes_ret = 0; - - /* Copy OS version */ - bytes_ret = cifs_strtoUCS((__le16 *)bcc_ptr, "Linux version ", 32, - nls_cp); - bcc_ptr += 2 * bytes_ret; - bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, init_utsname()->release, - 32, nls_cp); - bcc_ptr += 2 * bytes_ret; - bcc_ptr += 2; /* trailing null */ - - bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS, - 32, nls_cp); - bcc_ptr += 2 * bytes_ret; - bcc_ptr += 2; /* trailing null */ - - *pbcc_area = bcc_ptr; -} - -static void unicode_domain_string(char **pbcc_area, struct cifsSesInfo *ses, - const struct nls_table *nls_cp) -{ - char *bcc_ptr = *pbcc_area; - int bytes_ret = 0; - - /* copy domain */ - if (ses->domainName == NULL) { - /* Sending null domain better than using a bogus domain name (as - we did briefly in 2.6.18) since server will use its default */ - *bcc_ptr = 0; - *(bcc_ptr+1) = 0; - bytes_ret = 0; - } else - bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->domainName, - 256, nls_cp); - bcc_ptr += 2 * bytes_ret; - bcc_ptr += 2; /* account for null terminator */ - - *pbcc_area = bcc_ptr; -} - - static void unicode_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses, const struct nls_table *nls_cp) { @@ -145,9 +100,32 @@ static void unicode_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses, } bcc_ptr += 2 * bytes_ret; bcc_ptr += 2; /* account for null termination */ + /* copy domain */ + if (ses->domainName == NULL) { + /* Sending null domain better than using a bogus domain name (as + we did briefly in 2.6.18) since server will use its default */ + *bcc_ptr = 0; + *(bcc_ptr+1) = 0; + bytes_ret = 0; + } else + bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->domainName, + 256, nls_cp); + bcc_ptr += 2 * bytes_ret; + bcc_ptr += 2; /* account for null terminator */ + + /* Copy OS version */ + bytes_ret = cifs_strtoUCS((__le16 *)bcc_ptr, "Linux version ", 32, + nls_cp); + bcc_ptr += 2 * bytes_ret; + bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, init_utsname()->release, + 32, nls_cp); + bcc_ptr += 2 * bytes_ret; + bcc_ptr += 2; /* trailing null */ - unicode_domain_string(&bcc_ptr, ses, nls_cp); - unicode_oslm_strings(&bcc_ptr, nls_cp); + bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS, + 32, nls_cp); + bcc_ptr += 2 * bytes_ret; + bcc_ptr += 2; /* trailing null */ *pbcc_area = bcc_ptr; } @@ -225,11 +203,14 @@ static int decode_unicode_ssetup(char **pbcc_area, int bleft, if (len >= words_left) return rc; - kfree(ses->serverOS); + if (ses->serverOS) + kfree(ses->serverOS); /* UTF-8 string will not grow more than four times as big as UCS-16 */ ses->serverOS = kzalloc(4 * len, GFP_KERNEL); - if (ses->serverOS != NULL) - cifs_strfromUCS_le(ses->serverOS, (__le16 *)data, len, nls_cp); + if (ses->serverOS != NULL) { + cifs_strfromUCS_le(ses->serverOS, (__le16 *)data, len, + nls_cp); + } data += 2 * (len + 1); words_left -= len + 1; @@ -239,7 +220,8 @@ static int decode_unicode_ssetup(char **pbcc_area, int bleft, if (len >= words_left) return rc; - kfree(ses->serverNOS); + if (ses->serverNOS) + kfree(ses->serverNOS); ses->serverNOS = kzalloc(4 * len, GFP_KERNEL); /* BB this is wrong length FIXME BB */ if (ses->serverNOS != NULL) { cifs_strfromUCS_le(ses->serverNOS, (__le16 *)data, len, @@ -258,7 +240,8 @@ static int decode_unicode_ssetup(char **pbcc_area, int bleft, if (len > words_left) return rc; - kfree(ses->serverDomain); + if (ses->serverDomain) + kfree(ses->serverDomain); ses->serverDomain = kzalloc(2 * (len + 1), GFP_KERNEL); /* BB FIXME wrong length */ if (ses->serverDomain != NULL) { cifs_strfromUCS_le(ses->serverDomain, (__le16 *)data, len, @@ -288,7 +271,8 @@ static int decode_ascii_ssetup(char **pbcc_area, int bleft, if (len >= bleft) return rc; - kfree(ses->serverOS); + if (ses->serverOS) + kfree(ses->serverOS); ses->serverOS = kzalloc(len + 1, GFP_KERNEL); if (ses->serverOS) @@ -305,7 +289,8 @@ static int decode_ascii_ssetup(char **pbcc_area, int bleft, if (len >= bleft) return rc; - kfree(ses->serverNOS); + if (ses->serverNOS) + kfree(ses->serverNOS); ses->serverNOS = kzalloc(len + 1, GFP_KERNEL); if (ses->serverNOS) @@ -494,8 +479,7 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, if (ses->capabilities & CAP_UNICODE) { if (iov[0].iov_len % 2) { *bcc_ptr = 0; - bcc_ptr++; - } + } bcc_ptr++; unicode_ssetup_strings(&bcc_ptr, ses, nls_cp); } else ascii_ssetup_strings(&bcc_ptr, ses, nls_cp); @@ -513,8 +497,7 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, iov[1].iov_base = str_area; iov[1].iov_len = count; - rc = SendReceive2(xid, ses, iov, 2 /* num_iovecs */, &resp_buf_type, - 0 /* not long op */, 1 /* log NT STATUS if any */ ); + rc = SendReceive2(xid, ses, iov, 2 /* num_iovecs */, &resp_buf_type, 0); /* SMB request buf freed in SendReceive2 */ cFYI(1, ("ssetup rc from sendrecv2 is %d", rc)); diff --git a/trunk/fs/cifs/smberr.h b/trunk/fs/cifs/smberr.h index 7f50e8577c1c..2ef0be288820 100644 --- a/trunk/fs/cifs/smberr.h +++ b/trunk/fs/cifs/smberr.h @@ -173,10 +173,9 @@ #define ERRusestd 251 /* temporarily unable to use either raw or mpx */ #define ERR_NOTIFY_ENUM_DIR 1024 -#define ERRnoSuchUser 2238 /* user account does not exist */ #define ERRaccountexpired 2239 -#define ERRbadclient 2240 /* can not logon from this client */ -#define ERRbadLogonTime 2241 /* logon hours do not allow this */ +#define ERRbadclient 2240 +#define ERRbadLogonTime 2241 #define ERRpasswordExpired 2242 #define ERRnetlogonNotStarted 2455 #define ERRnosupport 0xFFFF diff --git a/trunk/fs/cifs/transport.c b/trunk/fs/cifs/transport.c index 7ed32b3cb781..746bc9405db1 100644 --- a/trunk/fs/cifs/transport.c +++ b/trunk/fs/cifs/transport.c @@ -55,7 +55,7 @@ AllocMidQEntry(const struct smb_hdr *smb_buffer, struct cifsSesInfo *ses) if (temp == NULL) return temp; else { - memset(temp, 0, sizeof(struct mid_q_entry)); + memset(temp, 0, sizeof (struct mid_q_entry)); temp->mid = smb_buffer->Mid; /* always LE */ temp->pid = current->pid; temp->command = smb_buffer->Command; @@ -158,7 +158,7 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer, iov.iov_len = len; smb_msg.msg_name = sin; - smb_msg.msg_namelen = sizeof(struct sockaddr); + smb_msg.msg_namelen = sizeof (struct sockaddr); smb_msg.msg_control = NULL; smb_msg.msg_controllen = 0; smb_msg.msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL; /* BB add more flags?*/ @@ -228,7 +228,7 @@ smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec, return -ENOTSOCK; /* BB eventually add reconnect code here */ smb_msg.msg_name = sin; - smb_msg.msg_namelen = sizeof(struct sockaddr); + smb_msg.msg_namelen = sizeof (struct sockaddr); smb_msg.msg_control = NULL; smb_msg.msg_controllen = 0; smb_msg.msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL; /* BB add more flags?*/ @@ -363,8 +363,9 @@ static int allocate_mid(struct cifsSesInfo *ses, struct smb_hdr *in_buf, } /* else ok - we are setting up session */ } *ppmidQ = AllocMidQEntry(in_buf, ses); - if (*ppmidQ == NULL) + if (*ppmidQ == NULL) { return -ENOMEM; + } return 0; } @@ -418,7 +419,7 @@ static int wait_for_response(struct cifsSesInfo *ses, int SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, struct kvec *iov, int n_vec, int *pRespBufType /* ret */, - const int long_op, const int logError) + const int long_op) { int rc = 0; unsigned int receive_len; @@ -464,6 +465,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, wake_up(&ses->server->request_q); return rc; } + rc = cifs_sign_smb2(iov, n_vec, ses->server, &midQ->sequence_number); midQ->midState = MID_REQUEST_SUBMITTED; @@ -566,11 +568,13 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, } /* BB special case reconnect tid and uid here? */ - rc = map_smb_to_linux_error(midQ->resp_buf, logError); + /* BB special case Errbadpassword and pwdexpired here */ + rc = map_smb_to_linux_error(midQ->resp_buf); /* convert ByteCount if necessary */ - if (receive_len >= sizeof(struct smb_hdr) - 4 - /* do not count RFC1001 header */ + + if (receive_len >= + sizeof (struct smb_hdr) - + 4 /* do not count RFC1001 header */ + (2 * midQ->resp_buf->WordCount) + 2 /* bcc */ ) BCC(midQ->resp_buf) = le16_to_cpu(BCC_LE(midQ->resp_buf)); @@ -745,11 +749,12 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, *pbytes_returned = out_buf->smb_buf_length; /* BB special case reconnect tid and uid here? */ - rc = map_smb_to_linux_error(out_buf, 0 /* no log */ ); + rc = map_smb_to_linux_error(out_buf); /* convert ByteCount if necessary */ - if (receive_len >= sizeof(struct smb_hdr) - 4 - /* do not count RFC1001 header */ + + if (receive_len >= + sizeof (struct smb_hdr) - + 4 /* do not count RFC1001 header */ + (2 * out_buf->WordCount) + 2 /* bcc */ ) BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf)); } else { @@ -988,11 +993,12 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon, *pbytes_returned = out_buf->smb_buf_length; /* BB special case reconnect tid and uid here? */ - rc = map_smb_to_linux_error(out_buf, 0 /* no log */ ); + rc = map_smb_to_linux_error(out_buf); /* convert ByteCount if necessary */ - if (receive_len >= sizeof(struct smb_hdr) - 4 - /* do not count RFC1001 header */ + + if (receive_len >= + sizeof (struct smb_hdr) - + 4 /* do not count RFC1001 header */ + (2 * out_buf->WordCount) + 2 /* bcc */ ) BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf)); } else { diff --git a/trunk/fs/cifs/xattr.c b/trunk/fs/cifs/xattr.c index 369e838bebd3..f61e433d281c 100644 --- a/trunk/fs/cifs/xattr.c +++ b/trunk/fs/cifs/xattr.c @@ -261,26 +261,21 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); -#ifdef CONFIG_CIFS_EXPERIMENTAL - else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { +/* else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { __u16 fid; int oplock = FALSE; - if (experimEnabled) - rc = CIFSSMBOpen(xid, pTcon, full_path, - FILE_OPEN, GENERIC_READ, 0, &fid, - &oplock, NULL, cifs_sb->local_nls, - cifs_sb->mnt_cifs_flags & - CIFS_MOUNT_MAP_SPECIAL_CHR); - /* else rc is EOPNOTSUPP from above */ - + rc = CIFSSMBOpen(xid, pTcon, full_path, + FILE_OPEN, GENERIC_READ, 0, &fid, + &oplock, NULL, cifs_sb->local_nls, + cifs_sb->mnt_cifs_flags & + CIFS_MOUNT_MAP_SPECIAL_CHR); if(rc == 0) { rc = CIFSSMBGetCIFSACL(xid, pTcon, fid, ea_value, buf_size, ACL_TYPE_ACCESS); CIFSSMBClose(xid, pTcon, fid); } - } -#endif /* EXPERIMENTAL */ + } */ /* BB enable after fixing up return data */ #else cFYI(1, ("query POSIX ACL not supported yet")); #endif /* CONFIG_CIFS_POSIX */ diff --git a/trunk/fs/coda/upcall.c b/trunk/fs/coda/upcall.c index 359e531094dd..cdb4c07a7870 100644 --- a/trunk/fs/coda/upcall.c +++ b/trunk/fs/coda/upcall.c @@ -51,7 +51,7 @@ static void *alloc_upcall(int opcode, int size) inp->ih.opcode = opcode; inp->ih.pid = current->pid; - inp->ih.pgid = task_pgrp_nr(current); + inp->ih.pgid = process_group(current); #ifdef CONFIG_CODA_FS_OLD_API memset(&inp->ih.cred, 0, sizeof(struct coda_cred)); inp->ih.cred.cr_fsuid = current->fsuid; diff --git a/trunk/fs/compat_ioctl.c b/trunk/fs/compat_ioctl.c index a4284ccac1f9..6dacd39bf048 100644 --- a/trunk/fs/compat_ioctl.c +++ b/trunk/fs/compat_ioctl.c @@ -3001,7 +3001,7 @@ static int __init init_sys32_ioctl(void) int i; for (i = 0; i < ARRAY_SIZE(ioctl_start); i++) { - if (ioctl_start[i].next) { + if (ioctl_start[i].next != 0) { printk("ioctl translation %d bad\n",i); return -1; } diff --git a/trunk/fs/cramfs/inode.c b/trunk/fs/cramfs/inode.c index 350680fd7da7..5c817bd08389 100644 --- a/trunk/fs/cramfs/inode.c +++ b/trunk/fs/cramfs/inode.c @@ -148,7 +148,7 @@ static void *cramfs_read(struct super_block *sb, unsigned int offset, unsigned i { struct address_space *mapping = sb->s_bdev->bd_inode->i_mapping; struct page *pages[BLKS_PER_BUF]; - unsigned i, blocknr, buffer; + unsigned i, blocknr, buffer, unread; unsigned long devsize; char *data; @@ -175,6 +175,7 @@ static void *cramfs_read(struct super_block *sb, unsigned int offset, unsigned i devsize = mapping->host->i_size >> PAGE_CACHE_SHIFT; /* Ok, read in BLKS_PER_BUF pages completely first. */ + unread = 0; for (i = 0; i < BLKS_PER_BUF; i++) { struct page *page = NULL; @@ -361,7 +362,7 @@ static int cramfs_readdir(struct file *filp, void *dirent, filldir_t filldir) if (offset & 3) return -EINVAL; - buf = kmalloc(CRAMFS_MAXPATHLEN, GFP_KERNEL); + buf = kmalloc(256, GFP_KERNEL); if (!buf) return -ENOMEM; @@ -375,7 +376,7 @@ static int cramfs_readdir(struct file *filp, void *dirent, filldir_t filldir) int namelen, error; mutex_lock(&read_mutex); - de = cramfs_read(sb, OFFSET(inode) + offset, sizeof(*de)+CRAMFS_MAXPATHLEN); + de = cramfs_read(sb, OFFSET(inode) + offset, sizeof(*de)+256); name = (char *)(de+1); /* @@ -425,7 +426,7 @@ static struct dentry * cramfs_lookup(struct inode *dir, struct dentry *dentry, s char *name; int namelen, retval; - de = cramfs_read(dir->i_sb, OFFSET(dir) + offset, sizeof(*de)+CRAMFS_MAXPATHLEN); + de = cramfs_read(dir->i_sb, OFFSET(dir) + offset, sizeof(*de)+256); name = (char *)(de+1); /* Try to take advantage of sorted directories */ diff --git a/trunk/fs/dlm/user.c b/trunk/fs/dlm/user.c index 4f741546f4bb..6438941ab1f8 100644 --- a/trunk/fs/dlm/user.c +++ b/trunk/fs/dlm/user.c @@ -456,7 +456,7 @@ static int check_version(struct dlm_write_request *req) printk(KERN_DEBUG "dlm: process %s (%d) version mismatch " "user (%d.%d.%d) kernel (%d.%d.%d)\n", current->comm, - task_pid_nr(current), + current->pid, req->version[0], req->version[1], req->version[2], diff --git a/trunk/fs/ecryptfs/inode.c b/trunk/fs/ecryptfs/inode.c index 0b1ab016fa2e..5701f816faf4 100644 --- a/trunk/fs/ecryptfs/inode.c +++ b/trunk/fs/ecryptfs/inode.c @@ -914,14 +914,6 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia) if (rc < 0) goto out; } - - /* - * mode change is for clearing setuid/setgid bits. Allow lower fs - * to interpret this in its own way. - */ - if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) - ia->ia_valid &= ~ATTR_MODE; - rc = notify_change(lower_dentry, ia); out: fsstack_copy_attr_all(inode, lower_inode, NULL); diff --git a/trunk/fs/eventpoll.c b/trunk/fs/eventpoll.c index 34f68f3a069a..77b9953624f4 100644 --- a/trunk/fs/eventpoll.c +++ b/trunk/fs/eventpoll.c @@ -325,14 +325,15 @@ static void ep_poll_safewake(struct poll_safewake *psw, wait_queue_head_t *wq) int wake_nests = 0; unsigned long flags; struct task_struct *this_task = current; - struct list_head *lsthead = &psw->wake_task_list; + struct list_head *lsthead = &psw->wake_task_list, *lnk; struct wake_task_node *tncur; struct wake_task_node tnode; spin_lock_irqsave(&psw->lock, flags); /* Try to see if the current task is already inside this wakeup call */ - list_for_each_entry(tncur, lsthead, llink) { + list_for_each(lnk, lsthead) { + tncur = list_entry(lnk, struct wake_task_node, llink); if (tncur->wq == wq || (tncur->task == this_task && ++wake_nests > EP_MAX_POLLWAKE_NESTS)) { @@ -462,7 +463,7 @@ static void ep_free(struct eventpoll *ep) * holding "epmutex" we can be sure that no file cleanup code will hit * us during this operation. So we can avoid the lock on "ep->lock". */ - while ((rbp = rb_first(&ep->rbr)) != NULL) { + while ((rbp = rb_first(&ep->rbr)) != 0) { epi = rb_entry(rbp, struct epitem, rbn); ep_remove(ep, epi); } diff --git a/trunk/fs/exec.c b/trunk/fs/exec.c index 2c942e2d14ea..070ddf13cb71 100644 --- a/trunk/fs/exec.c +++ b/trunk/fs/exec.c @@ -234,7 +234,7 @@ static int __bprm_mm_init(struct linux_binprm *bprm) vma->vm_start = vma->vm_end - PAGE_SIZE; vma->vm_flags = VM_STACK_FLAGS; - vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); + vma->vm_page_prot = protection_map[vma->vm_flags & 0x7]; err = insert_vm_struct(mm, vma); if (err) { up_write(&mm->mmap_sem); @@ -775,8 +775,8 @@ static int de_thread(struct task_struct *tsk) * Reparenting needs write_lock on tasklist_lock, * so it is safe to do it under read_lock. */ - if (unlikely(tsk->group_leader == task_child_reaper(tsk))) - task_active_pid_ns(tsk)->child_reaper = tsk; + if (unlikely(tsk->group_leader == child_reaper(tsk))) + tsk->nsproxy->pid_ns->child_reaper = tsk; zap_other_threads(tsk); read_unlock(&tasklist_lock); @@ -841,8 +841,8 @@ static int de_thread(struct task_struct *tsk) */ tsk->start_time = leader->start_time; - BUG_ON(!same_thread_group(leader, tsk)); - BUG_ON(has_group_leader_pid(tsk)); + BUG_ON(leader->tgid != tsk->tgid); + BUG_ON(tsk->pid == tsk->tgid); /* * An exec() starts a new thread group with the * TGID of the previous thread group. Rehash the @@ -857,7 +857,7 @@ static int de_thread(struct task_struct *tsk) */ detach_pid(tsk, PIDTYPE_PID); tsk->pid = leader->pid; - attach_pid(tsk, PIDTYPE_PID, task_pid(leader)); + attach_pid(tsk, PIDTYPE_PID, find_pid(tsk->pid)); transfer_pid(leader, tsk, PIDTYPE_PGID); transfer_pid(leader, tsk, PIDTYPE_SID); list_replace_rcu(&leader->tasks, &tsk->tasks); @@ -1433,7 +1433,7 @@ static int format_corename(char *corename, const char *pattern, long signr) case 'p': pid_in_pattern = 1; rc = snprintf(out_ptr, out_end - out_ptr, - "%d", task_tgid_vnr(current)); + "%d", current->tgid); if (rc > out_end - out_ptr) goto out; out_ptr += rc; @@ -1513,7 +1513,7 @@ static int format_corename(char *corename, const char *pattern, long signr) if (!ispipe && !pid_in_pattern && (core_uses_pid || atomic_read(¤t->mm->mm_users) != 1)) { rc = snprintf(out_ptr, out_end - out_ptr, - ".%d", task_tgid_vnr(current)); + ".%d", current->tgid); if (rc > out_end - out_ptr) goto out; out_ptr += rc; diff --git a/trunk/fs/ext3/fsync.c b/trunk/fs/ext3/fsync.c index a588e23841d4..dd1fd3c0fc05 100644 --- a/trunk/fs/ext3/fsync.c +++ b/trunk/fs/ext3/fsync.c @@ -47,7 +47,7 @@ int ext3_sync_file(struct file * file, struct dentry *dentry, int datasync) struct inode *inode = dentry->d_inode; int ret = 0; - J_ASSERT(ext3_journal_current_handle() == NULL); + J_ASSERT(ext3_journal_current_handle() == 0); /* * data=writeback: diff --git a/trunk/fs/ext3/inode.c b/trunk/fs/ext3/inode.c index 9b162cd6c16c..2f2b6864db10 100644 --- a/trunk/fs/ext3/inode.c +++ b/trunk/fs/ext3/inode.c @@ -1028,7 +1028,7 @@ struct buffer_head *ext3_getblk(handle_t *handle, struct inode *inode, } if (buffer_new(&dummy)) { J_ASSERT(create != 0); - J_ASSERT(handle != NULL); + J_ASSERT(handle != 0); /* * Now that we do not always journal data, we should @@ -2954,7 +2954,7 @@ int ext3_write_inode(struct inode *inode, int wait) return 0; if (ext3_journal_current_handle()) { - jbd_debug(1, "called recursively, non-PF_MEMALLOC!\n"); + jbd_debug(0, "called recursively, non-PF_MEMALLOC!\n"); dump_stack(); return -EIO; } diff --git a/trunk/fs/ext3/resize.c b/trunk/fs/ext3/resize.c index 44de1453c301..771f7ada15d9 100644 --- a/trunk/fs/ext3/resize.c +++ b/trunk/fs/ext3/resize.c @@ -245,10 +245,10 @@ static int setup_new_group_blocks(struct super_block *sb, brelse(gdb); goto exit_bh; } - lock_buffer(gdb); - memcpy(gdb->b_data, sbi->s_group_desc[i]->b_data, gdb->b_size); + lock_buffer(bh); + memcpy(gdb->b_data, sbi->s_group_desc[i]->b_data, bh->b_size); set_buffer_uptodate(gdb); - unlock_buffer(gdb); + unlock_buffer(bh); ext3_journal_dirty_metadata(handle, gdb); ext3_set_bit(bit, bh->b_data); brelse(gdb); diff --git a/trunk/fs/ext3/super.c b/trunk/fs/ext3/super.c index 81868c0bc40e..141573de7a9a 100644 --- a/trunk/fs/ext3/super.c +++ b/trunk/fs/ext3/super.c @@ -1620,11 +1620,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent) } brelse (bh); - if (!sb_set_blocksize(sb, blocksize)) { - printk(KERN_ERR "EXT3-fs: bad blocksize %d.\n", - blocksize); - goto out_fail; - } + sb_set_blocksize(sb, blocksize); logic_sb_block = (sb_block * EXT3_MIN_BLOCK_SIZE) / blocksize; offset = (sb_block * EXT3_MIN_BLOCK_SIZE) % blocksize; bh = sb_bread(sb, logic_sb_block); diff --git a/trunk/fs/ext3/xattr.c b/trunk/fs/ext3/xattr.c index 408373819e34..f58cbb26323e 100644 --- a/trunk/fs/ext3/xattr.c +++ b/trunk/fs/ext3/xattr.c @@ -741,11 +741,12 @@ ext3_xattr_block_set(handle_t *handle, struct inode *inode, } } else { /* Allocate a buffer where we construct the new block. */ - s->base = kzalloc(sb->s_blocksize, GFP_KERNEL); + s->base = kmalloc(sb->s_blocksize, GFP_KERNEL); /* assert(header == s->base) */ error = -ENOMEM; if (s->base == NULL) goto cleanup; + memset(s->base, 0, sb->s_blocksize); header(s->base)->h_magic = cpu_to_le32(EXT3_XATTR_MAGIC); header(s->base)->h_blocks = cpu_to_le32(1); header(s->base)->h_refcount = cpu_to_le32(1); diff --git a/trunk/fs/ext4/balloc.c b/trunk/fs/ext4/balloc.c index e906b65448e2..b74bf4368441 100644 --- a/trunk/fs/ext4/balloc.c +++ b/trunk/fs/ext4/balloc.c @@ -20,7 +20,6 @@ #include #include -#include "group.h" /* * balloc.c contains the blocks allocation and deallocation routines */ @@ -43,94 +42,6 @@ void ext4_get_group_no_and_offset(struct super_block *sb, ext4_fsblk_t blocknr, } -/* Initializes an uninitialized block bitmap if given, and returns the - * number of blocks free in the group. */ -unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh, - int block_group, struct ext4_group_desc *gdp) -{ - unsigned long start; - int bit, bit_max; - unsigned free_blocks, group_blocks; - struct ext4_sb_info *sbi = EXT4_SB(sb); - - if (bh) { - J_ASSERT_BH(bh, buffer_locked(bh)); - - /* If checksum is bad mark all blocks used to prevent allocation - * essentially implementing a per-group read-only flag. */ - if (!ext4_group_desc_csum_verify(sbi, block_group, gdp)) { - ext4_error(sb, __FUNCTION__, - "Checksum bad for group %u\n", block_group); - gdp->bg_free_blocks_count = 0; - gdp->bg_free_inodes_count = 0; - gdp->bg_itable_unused = 0; - memset(bh->b_data, 0xff, sb->s_blocksize); - return 0; - } - memset(bh->b_data, 0, sb->s_blocksize); - } - - /* Check for superblock and gdt backups in this group */ - bit_max = ext4_bg_has_super(sb, block_group); - - if (!EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_META_BG) || - block_group < le32_to_cpu(sbi->s_es->s_first_meta_bg) * - sbi->s_desc_per_block) { - if (bit_max) { - bit_max += ext4_bg_num_gdb(sb, block_group); - bit_max += - le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks); - } - } else { /* For META_BG_BLOCK_GROUPS */ - int group_rel = (block_group - - le32_to_cpu(sbi->s_es->s_first_meta_bg)) % - EXT4_DESC_PER_BLOCK(sb); - if (group_rel == 0 || group_rel == 1 || - (group_rel == EXT4_DESC_PER_BLOCK(sb) - 1)) - bit_max += 1; - } - - if (block_group == sbi->s_groups_count - 1) { - /* - * Even though mke2fs always initialize first and last group - * if some other tool enabled the EXT4_BG_BLOCK_UNINIT we need - * to make sure we calculate the right free blocks - */ - group_blocks = ext4_blocks_count(sbi->s_es) - - le32_to_cpu(sbi->s_es->s_first_data_block) - - (EXT4_BLOCKS_PER_GROUP(sb) * (sbi->s_groups_count -1)); - } else { - group_blocks = EXT4_BLOCKS_PER_GROUP(sb); - } - - free_blocks = group_blocks - bit_max; - - if (bh) { - for (bit = 0; bit < bit_max; bit++) - ext4_set_bit(bit, bh->b_data); - - start = block_group * EXT4_BLOCKS_PER_GROUP(sb) + - le32_to_cpu(sbi->s_es->s_first_data_block); - - /* Set bits for block and inode bitmaps, and inode table */ - ext4_set_bit(ext4_block_bitmap(sb, gdp) - start, bh->b_data); - ext4_set_bit(ext4_inode_bitmap(sb, gdp) - start, bh->b_data); - for (bit = (ext4_inode_table(sb, gdp) - start), - bit_max = bit + sbi->s_itb_per_group; bit < bit_max; bit++) - ext4_set_bit(bit, bh->b_data); - - /* - * Also if the number of blocks within the group is - * less than the blocksize * 8 ( which is the size - * of bitmap ), set rest of the block bitmap to 1 - */ - mark_bitmap_end(group_blocks, sb->s_blocksize * 8, bh->b_data); - } - - return free_blocks - sbi->s_itb_per_group - 2; -} - - /* * The free blocks are managed by bitmaps. A file system contains several * blocks groups. Each group contains 1 bitmap block for blocks, 1 bitmap @@ -208,7 +119,7 @@ block_in_use(ext4_fsblk_t block, struct super_block *sb, unsigned char *map) * * Return buffer_head on success or NULL in case of failure. */ -struct buffer_head * +static struct buffer_head * read_block_bitmap(struct super_block *sb, unsigned int block_group) { int i; @@ -216,24 +127,11 @@ read_block_bitmap(struct super_block *sb, unsigned int block_group) struct buffer_head * bh = NULL; ext4_fsblk_t bitmap_blk; - desc = ext4_get_group_desc(sb, block_group, NULL); + desc = ext4_get_group_desc (sb, block_group, NULL); if (!desc) return NULL; bitmap_blk = ext4_block_bitmap(sb, desc); - if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { - bh = sb_getblk(sb, bitmap_blk); - if (!buffer_uptodate(bh)) { - lock_buffer(bh); - if (!buffer_uptodate(bh)) { - ext4_init_block_bitmap(sb, bh, block_group, - desc); - set_buffer_uptodate(bh); - } - unlock_buffer(bh); - } - } else { - bh = sb_bread(sb, bitmap_blk); - } + bh = sb_bread(sb, bitmap_blk); if (!bh) ext4_error (sb, __FUNCTION__, "Cannot read block bitmap - " @@ -729,7 +627,6 @@ void ext4_free_blocks_sb(handle_t *handle, struct super_block *sb, desc->bg_free_blocks_count = cpu_to_le16(le16_to_cpu(desc->bg_free_blocks_count) + group_freed); - desc->bg_checksum = ext4_group_desc_csum(sbi, block_group, desc); spin_unlock(sb_bgl_lock(sbi, block_group)); percpu_counter_add(&sbi->s_freeblocks_counter, count); @@ -1788,11 +1685,8 @@ ext4_fsblk_t ext4_new_blocks(handle_t *handle, struct inode *inode, ret_block, goal_hits, goal_attempts); spin_lock(sb_bgl_lock(sbi, group_no)); - if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) - gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT); gdp->bg_free_blocks_count = cpu_to_le16(le16_to_cpu(gdp->bg_free_blocks_count)-num); - gdp->bg_checksum = ext4_group_desc_csum(sbi, group_no, gdp); spin_unlock(sb_bgl_lock(sbi, group_no)); percpu_counter_sub(&sbi->s_freeblocks_counter, num); diff --git a/trunk/fs/ext4/dir.c b/trunk/fs/ext4/dir.c index f612bef98315..0fb1e62b20d0 100644 --- a/trunk/fs/ext4/dir.c +++ b/trunk/fs/ext4/dir.c @@ -47,7 +47,9 @@ const struct file_operations ext4_dir_operations = { .compat_ioctl = ext4_compat_ioctl, #endif .fsync = ext4_sync_file, /* BKL held */ +#ifdef CONFIG_EXT4_INDEX .release = ext4_release_dir, +#endif }; @@ -105,6 +107,7 @@ static int ext4_readdir(struct file * filp, sb = inode->i_sb; +#ifdef CONFIG_EXT4_INDEX if (EXT4_HAS_COMPAT_FEATURE(inode->i_sb, EXT4_FEATURE_COMPAT_DIR_INDEX) && ((EXT4_I(inode)->i_flags & EXT4_INDEX_FL) || @@ -120,6 +123,7 @@ static int ext4_readdir(struct file * filp, */ EXT4_I(filp->f_path.dentry->d_inode)->i_flags &= ~EXT4_INDEX_FL; } +#endif stored = 0; offset = filp->f_pos & (sb->s_blocksize - 1); @@ -228,6 +232,7 @@ static int ext4_readdir(struct file * filp, return ret; } +#ifdef CONFIG_EXT4_INDEX /* * These functions convert from the major/minor hash to an f_pos * value. @@ -513,3 +518,5 @@ static int ext4_release_dir (struct inode * inode, struct file * filp) return 0; } + +#endif diff --git a/trunk/fs/ext4/extents.c b/trunk/fs/ext4/extents.c index 85287742f2ae..78beb096f57d 100644 --- a/trunk/fs/ext4/extents.c +++ b/trunk/fs/ext4/extents.c @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include #include #include @@ -52,7 +52,7 @@ static ext4_fsblk_t ext_pblock(struct ext4_extent *ex) { ext4_fsblk_t block; - block = le32_to_cpu(ex->ee_start_lo); + block = le32_to_cpu(ex->ee_start); block |= ((ext4_fsblk_t) le16_to_cpu(ex->ee_start_hi) << 31) << 1; return block; } @@ -65,7 +65,7 @@ static ext4_fsblk_t idx_pblock(struct ext4_extent_idx *ix) { ext4_fsblk_t block; - block = le32_to_cpu(ix->ei_leaf_lo); + block = le32_to_cpu(ix->ei_leaf); block |= ((ext4_fsblk_t) le16_to_cpu(ix->ei_leaf_hi) << 31) << 1; return block; } @@ -77,7 +77,7 @@ static ext4_fsblk_t idx_pblock(struct ext4_extent_idx *ix) */ static void ext4_ext_store_pblock(struct ext4_extent *ex, ext4_fsblk_t pb) { - ex->ee_start_lo = cpu_to_le32((unsigned long) (pb & 0xffffffff)); + ex->ee_start = cpu_to_le32((unsigned long) (pb & 0xffffffff)); ex->ee_start_hi = cpu_to_le16((unsigned long) ((pb >> 31) >> 1) & 0xffff); } @@ -88,7 +88,7 @@ static void ext4_ext_store_pblock(struct ext4_extent *ex, ext4_fsblk_t pb) */ static void ext4_idx_store_pblock(struct ext4_extent_idx *ix, ext4_fsblk_t pb) { - ix->ei_leaf_lo = cpu_to_le32((unsigned long) (pb & 0xffffffff)); + ix->ei_leaf = cpu_to_le32((unsigned long) (pb & 0xffffffff)); ix->ei_leaf_hi = cpu_to_le16((unsigned long) ((pb >> 31) >> 1) & 0xffff); } @@ -1409,7 +1409,8 @@ int ext4_ext_insert_extent(handle_t *handle, struct inode *inode, eh->eh_entries = cpu_to_le16(le16_to_cpu(eh->eh_entries)+1); nearex = path[depth].p_ext; nearex->ee_block = newext->ee_block; - ext4_ext_store_pblock(nearex, ext_pblock(newext)); + nearex->ee_start = newext->ee_start; + nearex->ee_start_hi = newext->ee_start_hi; nearex->ee_len = newext->ee_len; merge: @@ -2176,6 +2177,7 @@ int ext4_ext_convert_to_initialized(handle_t *handle, struct inode *inode, } /* ex2: iblock to iblock + maxblocks-1 : initialised */ ex2->ee_block = cpu_to_le32(iblock); + ex2->ee_start = cpu_to_le32(newblock); ext4_ext_store_pblock(ex2, newblock); ex2->ee_len = cpu_to_le16(allocated); if (ex2 != ex) diff --git a/trunk/fs/ext4/fsync.c b/trunk/fs/ext4/fsync.c index 8d50879d1c2c..2a167d7131fa 100644 --- a/trunk/fs/ext4/fsync.c +++ b/trunk/fs/ext4/fsync.c @@ -47,7 +47,7 @@ int ext4_sync_file(struct file * file, struct dentry *dentry, int datasync) struct inode *inode = dentry->d_inode; int ret = 0; - J_ASSERT(ext4_journal_current_handle() == NULL); + J_ASSERT(ext4_journal_current_handle() == 0); /* * data=writeback: diff --git a/trunk/fs/ext4/group.h b/trunk/fs/ext4/group.h deleted file mode 100644 index 1577910bb58b..000000000000 --- a/trunk/fs/ext4/group.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * linux/fs/ext4/group.h - * - * Copyright (C) 2007 Cluster File Systems, Inc - * - * Author: Andreas Dilger - */ - -#ifndef _LINUX_EXT4_GROUP_H -#define _LINUX_EXT4_GROUP_H - -extern __le16 ext4_group_desc_csum(struct ext4_sb_info *sbi, __u32 group, - struct ext4_group_desc *gdp); -extern int ext4_group_desc_csum_verify(struct ext4_sb_info *sbi, __u32 group, - struct ext4_group_desc *gdp); -struct buffer_head *read_block_bitmap(struct super_block *sb, - unsigned int block_group); -extern unsigned ext4_init_block_bitmap(struct super_block *sb, - struct buffer_head *bh, int group, - struct ext4_group_desc *desc); -#define ext4_free_blocks_after_init(sb, group, desc) \ - ext4_init_block_bitmap(sb, NULL, group, desc) -extern unsigned ext4_init_inode_bitmap(struct super_block *sb, - struct buffer_head *bh, int group, - struct ext4_group_desc *desc); -extern void mark_bitmap_end(int start_bit, int end_bit, char *bitmap); -#endif /* _LINUX_EXT4_GROUP_H */ diff --git a/trunk/fs/ext4/ialloc.c b/trunk/fs/ext4/ialloc.c index c61f37fd3f05..d0c7793d9393 100644 --- a/trunk/fs/ext4/ialloc.c +++ b/trunk/fs/ext4/ialloc.c @@ -28,7 +28,6 @@ #include "xattr.h" #include "acl.h" -#include "group.h" /* * ialloc.c contains the inodes allocation and deallocation routines @@ -44,52 +43,6 @@ * the free blocks count in the block. */ -/* - * To avoid calling the atomic setbit hundreds or thousands of times, we only - * need to use it within a single byte (to ensure we get endianness right). - * We can use memset for the rest of the bitmap as there are no other users. - */ -void mark_bitmap_end(int start_bit, int end_bit, char *bitmap) -{ - int i; - - if (start_bit >= end_bit) - return; - - ext4_debug("mark end bits +%d through +%d used\n", start_bit, end_bit); - for (i = start_bit; i < ((start_bit + 7) & ~7UL); i++) - ext4_set_bit(i, bitmap); - if (i < end_bit) - memset(bitmap + (i >> 3), 0xff, (end_bit - i) >> 3); -} - -/* Initializes an uninitialized inode bitmap */ -unsigned ext4_init_inode_bitmap(struct super_block *sb, - struct buffer_head *bh, int block_group, - struct ext4_group_desc *gdp) -{ - struct ext4_sb_info *sbi = EXT4_SB(sb); - - J_ASSERT_BH(bh, buffer_locked(bh)); - - /* If checksum is bad mark all blocks and inodes use to prevent - * allocation, essentially implementing a per-group read-only flag. */ - if (!ext4_group_desc_csum_verify(sbi, block_group, gdp)) { - ext4_error(sb, __FUNCTION__, "Checksum bad for group %u\n", - block_group); - gdp->bg_free_blocks_count = 0; - gdp->bg_free_inodes_count = 0; - gdp->bg_itable_unused = 0; - memset(bh->b_data, 0xff, sb->s_blocksize); - return 0; - } - - memset(bh->b_data, 0, (EXT4_INODES_PER_GROUP(sb) + 7) / 8); - mark_bitmap_end(EXT4_INODES_PER_GROUP(sb), EXT4_BLOCKS_PER_GROUP(sb), - bh->b_data); - - return EXT4_INODES_PER_GROUP(sb); -} /* * Read the inode allocation bitmap for a given block_group, reading @@ -106,20 +59,8 @@ read_inode_bitmap(struct super_block * sb, unsigned long block_group) desc = ext4_get_group_desc(sb, block_group, NULL); if (!desc) goto error_out; - if (desc->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) { - bh = sb_getblk(sb, ext4_inode_bitmap(sb, desc)); - if (!buffer_uptodate(bh)) { - lock_buffer(bh); - if (!buffer_uptodate(bh)) { - ext4_init_inode_bitmap(sb, bh, block_group, - desc); - set_buffer_uptodate(bh); - } - unlock_buffer(bh); - } - } else { - bh = sb_bread(sb, ext4_inode_bitmap(sb, desc)); - } + + bh = sb_bread(sb, ext4_inode_bitmap(sb, desc)); if (!bh) ext4_error(sb, "read_inode_bitmap", "Cannot read inode bitmap - " @@ -228,8 +169,6 @@ void ext4_free_inode (handle_t *handle, struct inode * inode) if (is_directory) gdp->bg_used_dirs_count = cpu_to_le16( le16_to_cpu(gdp->bg_used_dirs_count) - 1); - gdp->bg_checksum = ext4_group_desc_csum(sbi, - block_group, gdp); spin_unlock(sb_bgl_lock(sbi, block_group)); percpu_counter_inc(&sbi->s_freeinodes_counter); if (is_directory) @@ -496,7 +435,7 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode * dir, int mode) struct ext4_sb_info *sbi; int err = 0; struct inode *ret; - int i, free = 0; + int i; /* Cannot create files in a deleted directory */ if (!dir || !dir->i_nlink) @@ -578,13 +517,11 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode * dir, int mode) goto out; got: - ino++; - if ((group == 0 && ino < EXT4_FIRST_INO(sb)) || - ino > EXT4_INODES_PER_GROUP(sb)) { - ext4_error(sb, __FUNCTION__, - "reserved inode or inode > inodes count - " - "block_group = %d, inode=%lu", group, - ino + group * EXT4_INODES_PER_GROUP(sb)); + ino += group * EXT4_INODES_PER_GROUP(sb) + 1; + if (ino < EXT4_FIRST_INO(sb) || ino > le32_to_cpu(es->s_inodes_count)) { + ext4_error (sb, "ext4_new_inode", + "reserved inode or inode > inodes count - " + "block_group = %d, inode=%lu", group, ino); err = -EIO; goto fail; } @@ -592,78 +529,13 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode * dir, int mode) BUFFER_TRACE(bh2, "get_write_access"); err = ext4_journal_get_write_access(handle, bh2); if (err) goto fail; - - /* We may have to initialize the block bitmap if it isn't already */ - if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_GDT_CSUM) && - gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { - struct buffer_head *block_bh = read_block_bitmap(sb, group); - - BUFFER_TRACE(block_bh, "get block bitmap access"); - err = ext4_journal_get_write_access(handle, block_bh); - if (err) { - brelse(block_bh); - goto fail; - } - - free = 0; - spin_lock(sb_bgl_lock(sbi, group)); - /* recheck and clear flag under lock if we still need to */ - if (gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { - gdp->bg_flags &= cpu_to_le16(~EXT4_BG_BLOCK_UNINIT); - free = ext4_free_blocks_after_init(sb, group, gdp); - gdp->bg_free_blocks_count = cpu_to_le16(free); - } - spin_unlock(sb_bgl_lock(sbi, group)); - - /* Don't need to dirty bitmap block if we didn't change it */ - if (free) { - BUFFER_TRACE(block_bh, "dirty block bitmap"); - err = ext4_journal_dirty_metadata(handle, block_bh); - } - - brelse(block_bh); - if (err) - goto fail; - } - spin_lock(sb_bgl_lock(sbi, group)); - /* If we didn't allocate from within the initialized part of the inode - * table then we need to initialize up to this inode. */ - if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) { - if (gdp->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) { - gdp->bg_flags &= cpu_to_le16(~EXT4_BG_INODE_UNINIT); - - /* When marking the block group with - * ~EXT4_BG_INODE_UNINIT we don't want to depend - * on the value of bg_itable_unsed even though - * mke2fs could have initialized the same for us. - * Instead we calculated the value below - */ - - free = 0; - } else { - free = EXT4_INODES_PER_GROUP(sb) - - le16_to_cpu(gdp->bg_itable_unused); - } - - /* - * Check the relative inode number against the last used - * relative inode number in this group. if it is greater - * we need to update the bg_itable_unused count - * - */ - if (ino > free) - gdp->bg_itable_unused = - cpu_to_le16(EXT4_INODES_PER_GROUP(sb) - ino); - } - gdp->bg_free_inodes_count = cpu_to_le16(le16_to_cpu(gdp->bg_free_inodes_count) - 1); if (S_ISDIR(mode)) { gdp->bg_used_dirs_count = cpu_to_le16(le16_to_cpu(gdp->bg_used_dirs_count) + 1); } - gdp->bg_checksum = ext4_group_desc_csum(sbi, group, gdp); spin_unlock(sb_bgl_lock(sbi, group)); BUFFER_TRACE(bh2, "call ext4_journal_dirty_metadata"); err = ext4_journal_dirty_metadata(handle, bh2); @@ -685,7 +557,7 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode * dir, int mode) inode->i_gid = current->fsgid; inode->i_mode = mode; - inode->i_ino = ino + group * EXT4_INODES_PER_GROUP(sb); + inode->i_ino = ino; /* This is the optimal IO size (for stat), not the fs block size */ inode->i_blocks = 0; inode->i_mtime = inode->i_atime = inode->i_ctime = ei->i_crtime = @@ -701,6 +573,11 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode * dir, int mode) /* dirsync only applies to directories */ if (!S_ISDIR(mode)) ei->i_flags &= ~EXT4_DIRSYNC_FL; +#ifdef EXT4_FRAGMENTS + ei->i_faddr = 0; + ei->i_frag_no = 0; + ei->i_frag_size = 0; +#endif ei->i_file_acl = 0; ei->i_dir_acl = 0; ei->i_dtime = 0; diff --git a/trunk/fs/ext4/inode.c b/trunk/fs/ext4/inode.c index 5489703d9573..0df2b1e06d0b 100644 --- a/trunk/fs/ext4/inode.c +++ b/trunk/fs/ext4/inode.c @@ -1027,7 +1027,7 @@ struct buffer_head *ext4_getblk(handle_t *handle, struct inode *inode, } if (buffer_new(&dummy)) { J_ASSERT(create != 0); - J_ASSERT(handle != NULL); + J_ASSERT(handle != 0); /* * Now that we do not always journal data, we should @@ -2711,6 +2711,11 @@ void ext4_read_inode(struct inode * inode) } inode->i_blocks = le32_to_cpu(raw_inode->i_blocks); ei->i_flags = le32_to_cpu(raw_inode->i_flags); +#ifdef EXT4_FRAGMENTS + ei->i_faddr = le32_to_cpu(raw_inode->i_faddr); + ei->i_frag_no = raw_inode->i_frag; + ei->i_frag_size = raw_inode->i_fsize; +#endif ei->i_file_acl = le32_to_cpu(raw_inode->i_file_acl); if (EXT4_SB(inode->i_sb)->s_es->s_creator_os != cpu_to_le32(EXT4_OS_HURD)) @@ -2855,6 +2860,11 @@ static int ext4_do_update_inode(handle_t *handle, raw_inode->i_blocks = cpu_to_le32(inode->i_blocks); raw_inode->i_dtime = cpu_to_le32(ei->i_dtime); raw_inode->i_flags = cpu_to_le32(ei->i_flags); +#ifdef EXT4_FRAGMENTS + raw_inode->i_faddr = cpu_to_le32(ei->i_faddr); + raw_inode->i_frag = ei->i_frag_no; + raw_inode->i_fsize = ei->i_frag_size; +#endif if (EXT4_SB(inode->i_sb)->s_es->s_creator_os != cpu_to_le32(EXT4_OS_HURD)) raw_inode->i_file_acl_high = @@ -3233,14 +3243,12 @@ int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode) iloc, handle); if (ret) { EXT4_I(inode)->i_state |= EXT4_STATE_NO_EXPAND; - if (mnt_count != - le16_to_cpu(sbi->s_es->s_mnt_count)) { + if (mnt_count != sbi->s_es->s_mnt_count) { ext4_warning(inode->i_sb, __FUNCTION__, "Unable to expand inode %lu. Delete" " some EAs or run e2fsck.", inode->i_ino); - mnt_count = - le16_to_cpu(sbi->s_es->s_mnt_count); + mnt_count = sbi->s_es->s_mnt_count; } } } diff --git a/trunk/fs/ext4/namei.c b/trunk/fs/ext4/namei.c index 94ee6f315dc1..5fdb862e71c4 100644 --- a/trunk/fs/ext4/namei.c +++ b/trunk/fs/ext4/namei.c @@ -144,6 +144,7 @@ struct dx_map_entry u16 size; }; +#ifdef CONFIG_EXT4_INDEX static inline unsigned dx_get_block (struct dx_entry *entry); static void dx_set_block (struct dx_entry *entry, unsigned value); static inline unsigned dx_get_hash (struct dx_entry *entry); @@ -765,6 +766,8 @@ static void dx_insert_block(struct dx_frame *frame, u32 hash, u32 block) dx_set_block(new, block); dx_set_count(entries, count + 1); } +#endif + static void ext4_update_dx_flag(struct inode *inode) { @@ -866,6 +869,7 @@ static struct buffer_head * ext4_find_entry (struct dentry *dentry, name = dentry->d_name.name; if (namelen > EXT4_NAME_LEN) return NULL; +#ifdef CONFIG_EXT4_INDEX if (is_dx(dir)) { bh = ext4_dx_find_entry(dentry, res_dir, &err); /* @@ -877,6 +881,7 @@ static struct buffer_head * ext4_find_entry (struct dentry *dentry, return bh; dxtrace(printk("ext4_find_entry: dx failed, falling back\n")); } +#endif nblocks = dir->i_size >> EXT4_BLOCK_SIZE_BITS(sb); start = EXT4_I(dir)->i_dir_start_lookup; if (start >= nblocks) @@ -952,6 +957,7 @@ static struct buffer_head * ext4_find_entry (struct dentry *dentry, return ret; } +#ifdef CONFIG_EXT4_INDEX static struct buffer_head * ext4_dx_find_entry(struct dentry *dentry, struct ext4_dir_entry_2 **res_dir, int *err) { @@ -1019,6 +1025,7 @@ static struct buffer_head * ext4_dx_find_entry(struct dentry *dentry, dx_release (frames); return NULL; } +#endif static struct dentry *ext4_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd) { @@ -1114,6 +1121,7 @@ static inline void ext4_set_de_type(struct super_block *sb, de->file_type = ext4_type_by_mode[(mode & S_IFMT)>>S_SHIFT]; } +#ifdef CONFIG_EXT4_INDEX /* * Move count entries from end of map between two memory locations. * Returns pointer to last entry moved. @@ -1258,6 +1266,8 @@ static struct ext4_dir_entry_2 *do_split(handle_t *handle, struct inode *dir, *error = err; return NULL; } +#endif + /* * Add a new entry into a directory (leaf) block. If de is non-NULL, @@ -1354,6 +1364,7 @@ static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry, return 0; } +#ifdef CONFIG_EXT4_INDEX /* * This converts a one block unindexed directory to a 3 block indexed * directory, and adds the dentry to the indexed directory. @@ -1432,6 +1443,7 @@ static int make_indexed_dir(handle_t *handle, struct dentry *dentry, return add_dirent_to_buf(handle, dentry, inode, de, bh); } +#endif /* * ext4_add_entry() @@ -1452,7 +1464,9 @@ static int ext4_add_entry (handle_t *handle, struct dentry *dentry, struct ext4_dir_entry_2 *de; struct super_block * sb; int retval; +#ifdef CONFIG_EXT4_INDEX int dx_fallback=0; +#endif unsigned blocksize; u32 block, blocks; @@ -1460,6 +1474,7 @@ static int ext4_add_entry (handle_t *handle, struct dentry *dentry, blocksize = sb->s_blocksize; if (!dentry->d_name.len) return -EINVAL; +#ifdef CONFIG_EXT4_INDEX if (is_dx(dir)) { retval = ext4_dx_add_entry(handle, dentry, inode); if (!retval || (retval != ERR_BAD_DX_DIR)) @@ -1468,6 +1483,7 @@ static int ext4_add_entry (handle_t *handle, struct dentry *dentry, dx_fallback++; ext4_mark_inode_dirty(handle, dir); } +#endif blocks = dir->i_size >> sb->s_blocksize_bits; for (block = 0, offset = 0; block < blocks; block++) { bh = ext4_bread(handle, dir, block, 0, &retval); @@ -1477,9 +1493,11 @@ static int ext4_add_entry (handle_t *handle, struct dentry *dentry, if (retval != -ENOSPC) return retval; +#ifdef CONFIG_EXT4_INDEX if (blocks == 1 && !dx_fallback && EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_DIR_INDEX)) return make_indexed_dir(handle, dentry, inode, bh); +#endif brelse(bh); } bh = ext4_append(handle, dir, &block, &retval); @@ -1491,6 +1509,7 @@ static int ext4_add_entry (handle_t *handle, struct dentry *dentry, return add_dirent_to_buf(handle, dentry, inode, de, bh); } +#ifdef CONFIG_EXT4_INDEX /* * Returns 0 for success, or a negative error value */ @@ -1625,6 +1644,7 @@ static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry, dx_release(frames); return err; } +#endif /* * ext4_delete_entry deletes a directory entry by merging it with the diff --git a/trunk/fs/ext4/resize.c b/trunk/fs/ext4/resize.c index bd8a52bb3999..472fc0d3e1c0 100644 --- a/trunk/fs/ext4/resize.c +++ b/trunk/fs/ext4/resize.c @@ -16,7 +16,6 @@ #include #include -#include "group.h" #define outside(b, first, last) ((b) < (first) || (b) >= (last)) #define inside(b, first, last) ((b) >= (first) && (b) < (last)) @@ -141,29 +140,22 @@ static struct buffer_head *bclean(handle_t *handle, struct super_block *sb, } /* - * If we have fewer than thresh credits, extend by EXT4_MAX_TRANS_DATA. - * If that fails, restart the transaction & regain write access for the - * buffer head which is used for block_bitmap modifications. + * To avoid calling the atomic setbit hundreds or thousands of times, we only + * need to use it within a single byte (to ensure we get endianness right). + * We can use memset for the rest of the bitmap as there are no other users. */ -static int extend_or_restart_transaction(handle_t *handle, int thresh, - struct buffer_head *bh) +static void mark_bitmap_end(int start_bit, int end_bit, char *bitmap) { - int err; - - if (handle->h_buffer_credits >= thresh) - return 0; + int i; - err = ext4_journal_extend(handle, EXT4_MAX_TRANS_DATA); - if (err < 0) - return err; - if (err) { - if ((err = ext4_journal_restart(handle, EXT4_MAX_TRANS_DATA))) - return err; - if ((err = ext4_journal_get_write_access(handle, bh))) - return err; - } + if (start_bit >= end_bit) + return; - return 0; + ext4_debug("mark end bits +%d through +%d used\n", start_bit, end_bit); + for (i = start_bit; i < ((start_bit + 7) & ~7UL); i++) + ext4_set_bit(i, bitmap); + if (i < end_bit) + memset(bitmap + (i >> 3), 0xff, (end_bit - i) >> 3); } /* @@ -188,9 +180,8 @@ static int setup_new_group_blocks(struct super_block *sb, int i; int err = 0, err2; - /* This transaction may be extended/restarted along the way */ - handle = ext4_journal_start_sb(sb, EXT4_MAX_TRANS_DATA); - + handle = ext4_journal_start_sb(sb, reserved_gdb + gdblocks + + 2 + sbi->s_itb_per_group); if (IS_ERR(handle)) return PTR_ERR(handle); @@ -217,9 +208,6 @@ static int setup_new_group_blocks(struct super_block *sb, ext4_debug("update backup group %#04lx (+%d)\n", block, bit); - if ((err = extend_or_restart_transaction(handle, 1, bh))) - goto exit_bh; - gdb = sb_getblk(sb, block); if (!gdb) { err = -EIO; @@ -229,10 +217,10 @@ static int setup_new_group_blocks(struct super_block *sb, brelse(gdb); goto exit_bh; } - lock_buffer(gdb); - memcpy(gdb->b_data, sbi->s_group_desc[i]->b_data, gdb->b_size); + lock_buffer(bh); + memcpy(gdb->b_data, sbi->s_group_desc[i]->b_data, bh->b_size); set_buffer_uptodate(gdb); - unlock_buffer(gdb); + unlock_buffer(bh); ext4_journal_dirty_metadata(handle, gdb); ext4_set_bit(bit, bh->b_data); brelse(gdb); @@ -245,9 +233,6 @@ static int setup_new_group_blocks(struct super_block *sb, ext4_debug("clear reserved block %#04lx (+%d)\n", block, bit); - if ((err = extend_or_restart_transaction(handle, 1, bh))) - goto exit_bh; - if (IS_ERR(gdb = bclean(handle, sb, block))) { err = PTR_ERR(bh); goto exit_bh; @@ -269,10 +254,6 @@ static int setup_new_group_blocks(struct super_block *sb, struct buffer_head *it; ext4_debug("clear inode block %#04lx (+%d)\n", block, bit); - - if ((err = extend_or_restart_transaction(handle, 1, bh))) - goto exit_bh; - if (IS_ERR(it = bclean(handle, sb, block))) { err = PTR_ERR(it); goto exit_bh; @@ -281,10 +262,6 @@ static int setup_new_group_blocks(struct super_block *sb, brelse(it); ext4_set_bit(bit, bh->b_data); } - - if ((err = extend_or_restart_transaction(handle, 2, bh))) - goto exit_bh; - mark_bitmap_end(input->blocks_count, EXT4_BLOCKS_PER_GROUP(sb), bh->b_data); ext4_journal_dirty_metadata(handle, bh); @@ -312,6 +289,7 @@ static int setup_new_group_blocks(struct super_block *sb, return err; } + /* * Iterate through the groups which hold BACKUP superblock/GDT copies in an * ext4 filesystem. The counters should be initialized to 1, 5, and 7 before @@ -864,7 +842,6 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input) ext4_inode_table_set(sb, gdp, input->inode_table); /* LV FIXME */ gdp->bg_free_blocks_count = cpu_to_le16(input->free_blocks_count); gdp->bg_free_inodes_count = cpu_to_le16(EXT4_INODES_PER_GROUP(sb)); - gdp->bg_checksum = ext4_group_desc_csum(sbi, input->group, gdp); /* * Make the new blocks and inodes valid next. We do this before diff --git a/trunk/fs/ext4/super.c b/trunk/fs/ext4/super.c index b11e9e2bcd01..4c8d31c61454 100644 --- a/trunk/fs/ext4/super.c +++ b/trunk/fs/ext4/super.c @@ -37,14 +37,12 @@ #include #include #include -#include #include #include "xattr.h" #include "acl.h" #include "namei.h" -#include "group.h" static int ext4_load_journal(struct super_block *, struct ext4_super_block *, unsigned long journal_devnum); @@ -70,31 +68,31 @@ static void ext4_write_super_lockfs(struct super_block *sb); ext4_fsblk_t ext4_block_bitmap(struct super_block *sb, struct ext4_group_desc *bg) { - return le32_to_cpu(bg->bg_block_bitmap_lo) | + return le32_to_cpu(bg->bg_block_bitmap) | (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ? - (ext4_fsblk_t)le32_to_cpu(bg->bg_block_bitmap_hi) << 32 : 0); + (ext4_fsblk_t)le32_to_cpu(bg->bg_block_bitmap_hi) << 32 : 0); } ext4_fsblk_t ext4_inode_bitmap(struct super_block *sb, struct ext4_group_desc *bg) { - return le32_to_cpu(bg->bg_inode_bitmap_lo) | + return le32_to_cpu(bg->bg_inode_bitmap) | (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ? - (ext4_fsblk_t)le32_to_cpu(bg->bg_inode_bitmap_hi) << 32 : 0); + (ext4_fsblk_t)le32_to_cpu(bg->bg_inode_bitmap_hi) << 32 : 0); } ext4_fsblk_t ext4_inode_table(struct super_block *sb, struct ext4_group_desc *bg) { - return le32_to_cpu(bg->bg_inode_table_lo) | + return le32_to_cpu(bg->bg_inode_table) | (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ? - (ext4_fsblk_t)le32_to_cpu(bg->bg_inode_table_hi) << 32 : 0); + (ext4_fsblk_t)le32_to_cpu(bg->bg_inode_table_hi) << 32 : 0); } void ext4_block_bitmap_set(struct super_block *sb, struct ext4_group_desc *bg, ext4_fsblk_t blk) { - bg->bg_block_bitmap_lo = cpu_to_le32((u32)blk); + bg->bg_block_bitmap = cpu_to_le32((u32)blk); if (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT) bg->bg_block_bitmap_hi = cpu_to_le32(blk >> 32); } @@ -102,7 +100,7 @@ void ext4_block_bitmap_set(struct super_block *sb, void ext4_inode_bitmap_set(struct super_block *sb, struct ext4_group_desc *bg, ext4_fsblk_t blk) { - bg->bg_inode_bitmap_lo = cpu_to_le32((u32)blk); + bg->bg_inode_bitmap = cpu_to_le32((u32)blk); if (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT) bg->bg_inode_bitmap_hi = cpu_to_le32(blk >> 32); } @@ -110,7 +108,7 @@ void ext4_inode_bitmap_set(struct super_block *sb, void ext4_inode_table_set(struct super_block *sb, struct ext4_group_desc *bg, ext4_fsblk_t blk) { - bg->bg_inode_table_lo = cpu_to_le32((u32)blk); + bg->bg_inode_table = cpu_to_le32((u32)blk); if (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT) bg->bg_inode_table_hi = cpu_to_le32(blk >> 32); } @@ -1039,7 +1037,7 @@ static int parse_options (char *options, struct super_block *sb, if (option < 0) return 0; if (option == 0) - option = JBD2_DEFAULT_MAX_COMMIT_AGE; + option = JBD_DEFAULT_MAX_COMMIT_AGE; sbi->s_commit_interval = HZ * option; break; case Opt_data_journal: @@ -1310,43 +1308,6 @@ static int ext4_setup_super(struct super_block *sb, struct ext4_super_block *es, return res; } -__le16 ext4_group_desc_csum(struct ext4_sb_info *sbi, __u32 block_group, - struct ext4_group_desc *gdp) -{ - __u16 crc = 0; - - if (sbi->s_es->s_feature_ro_compat & - cpu_to_le32(EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) { - int offset = offsetof(struct ext4_group_desc, bg_checksum); - __le32 le_group = cpu_to_le32(block_group); - - crc = crc16(~0, sbi->s_es->s_uuid, sizeof(sbi->s_es->s_uuid)); - crc = crc16(crc, (__u8 *)&le_group, sizeof(le_group)); - crc = crc16(crc, (__u8 *)gdp, offset); - offset += sizeof(gdp->bg_checksum); /* skip checksum */ - /* for checksum of struct ext4_group_desc do the rest...*/ - if ((sbi->s_es->s_feature_incompat & - cpu_to_le32(EXT4_FEATURE_INCOMPAT_64BIT)) && - offset < le16_to_cpu(sbi->s_es->s_desc_size)) - crc = crc16(crc, (__u8 *)gdp + offset, - le16_to_cpu(sbi->s_es->s_desc_size) - - offset); - } - - return cpu_to_le16(crc); -} - -int ext4_group_desc_csum_verify(struct ext4_sb_info *sbi, __u32 block_group, - struct ext4_group_desc *gdp) -{ - if ((sbi->s_es->s_feature_ro_compat & - cpu_to_le32(EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) && - (gdp->bg_checksum != ext4_group_desc_csum(sbi, block_group, gdp))) - return 0; - - return 1; -} - /* Called at mount-time, super-block is locked */ static int ext4_check_descriptors (struct super_block * sb) { @@ -1358,17 +1319,13 @@ static int ext4_check_descriptors (struct super_block * sb) ext4_fsblk_t inode_table; struct ext4_group_desc * gdp = NULL; int desc_block = 0; - int flexbg_flag = 0; int i; - if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG)) - flexbg_flag = 1; - ext4_debug ("Checking group descriptors"); for (i = 0; i < sbi->s_groups_count; i++) { - if (i == sbi->s_groups_count - 1 || flexbg_flag) + if (i == sbi->s_groups_count - 1) last_block = ext4_blocks_count(sbi->s_es) - 1; else last_block = first_block + @@ -1405,16 +1362,7 @@ static int ext4_check_descriptors (struct super_block * sb) i, inode_table); return 0; } - if (!ext4_group_desc_csum_verify(sbi, i, gdp)) { - ext4_error(sb, __FUNCTION__, - "Checksum for group %d failed (%u!=%u)\n", i, - le16_to_cpu(ext4_group_desc_csum(sbi, i, - gdp)), - le16_to_cpu(gdp->bg_checksum)); - return 0; - } - if (!flexbg_flag) - first_block += EXT4_BLOCKS_PER_GROUP(sb); + first_block += EXT4_BLOCKS_PER_GROUP(sb); gdp = (struct ext4_group_desc *) ((__u8 *)gdp + EXT4_DESC_SIZE(sb)); } @@ -1778,6 +1726,14 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent) if (sbi->s_inode_size > EXT4_GOOD_OLD_INODE_SIZE) sb->s_time_gran = 1 << (EXT4_EPOCH_BITS - 2); } + sbi->s_frag_size = EXT4_MIN_FRAG_SIZE << + le32_to_cpu(es->s_log_frag_size); + if (blocksize != sbi->s_frag_size) { + printk(KERN_ERR + "EXT4-fs: fragsize %lu != blocksize %u (unsupported)\n", + sbi->s_frag_size, blocksize); + goto failed_mount; + } sbi->s_desc_size = le16_to_cpu(es->s_desc_size); if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_64BIT)) { if (sbi->s_desc_size < EXT4_MIN_DESC_SIZE_64BIT || @@ -1791,6 +1747,7 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent) } else sbi->s_desc_size = EXT4_MIN_DESC_SIZE; sbi->s_blocks_per_group = le32_to_cpu(es->s_blocks_per_group); + sbi->s_frags_per_group = le32_to_cpu(es->s_frags_per_group); sbi->s_inodes_per_group = le32_to_cpu(es->s_inodes_per_group); if (EXT4_INODE_SIZE(sb) == 0) goto cantfind_ext4; @@ -1814,6 +1771,12 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent) sbi->s_blocks_per_group); goto failed_mount; } + if (sbi->s_frags_per_group > blocksize * 8) { + printk (KERN_ERR + "EXT4-fs: #fragments per group too big: %lu\n", + sbi->s_frags_per_group); + goto failed_mount; + } if (sbi->s_inodes_per_group > blocksize * 8) { printk (KERN_ERR "EXT4-fs: #inodes per group too big: %lu\n", @@ -2667,7 +2630,7 @@ static int ext4_statfs (struct dentry * dentry, struct kstatfs * buf) if (test_opt(sb, MINIX_DF)) { sbi->s_overhead_last = 0; - } else if (sbi->s_blocks_last != ext4_blocks_count(es)) { + } else if (sbi->s_blocks_last != le32_to_cpu(es->s_blocks_count)) { unsigned long ngroups = sbi->s_groups_count, i; ext4_fsblk_t overhead = 0; smp_rmb(); @@ -2702,14 +2665,14 @@ static int ext4_statfs (struct dentry * dentry, struct kstatfs * buf) overhead += ngroups * (2 + sbi->s_itb_per_group); sbi->s_overhead_last = overhead; smp_wmb(); - sbi->s_blocks_last = ext4_blocks_count(es); + sbi->s_blocks_last = le32_to_cpu(es->s_blocks_count); } buf->f_type = EXT4_SUPER_MAGIC; buf->f_bsize = sb->s_blocksize; buf->f_blocks = ext4_blocks_count(es) - sbi->s_overhead_last; buf->f_bfree = percpu_counter_sum_positive(&sbi->s_freeblocks_counter); - ext4_free_blocks_count_set(es, buf->f_bfree); + es->s_free_blocks_count = cpu_to_le32(buf->f_bfree); buf->f_bavail = buf->f_bfree - ext4_r_blocks_count(es); if (buf->f_bfree < ext4_r_blocks_count(es)) buf->f_bavail = 0; diff --git a/trunk/fs/ext4/xattr.c b/trunk/fs/ext4/xattr.c index 86387302c2a9..b10d68fffb55 100644 --- a/trunk/fs/ext4/xattr.c +++ b/trunk/fs/ext4/xattr.c @@ -750,11 +750,12 @@ ext4_xattr_block_set(handle_t *handle, struct inode *inode, } } else { /* Allocate a buffer where we construct the new block. */ - s->base = kzalloc(sb->s_blocksize, GFP_KERNEL); + s->base = kmalloc(sb->s_blocksize, GFP_KERNEL); /* assert(header == s->base) */ error = -ENOMEM; if (s->base == NULL) goto cleanup; + memset(s->base, 0, sb->s_blocksize); header(s->base)->h_magic = cpu_to_le32(EXT4_XATTR_MAGIC); header(s->base)->h_blocks = cpu_to_le32(1); header(s->base)->h_refcount = cpu_to_le32(1); @@ -1120,7 +1121,7 @@ int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize, int total_ino, total_blk; void *base, *start, *end; int extra_isize = 0, error = 0, tried_min_extra_isize = 0; - int s_min_extra_isize = le16_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_min_extra_isize); + int s_min_extra_isize = EXT4_SB(inode->i_sb)->s_es->s_min_extra_isize; down_write(&EXT4_I(inode)->xattr_sem); retry: @@ -1292,7 +1293,7 @@ int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize, i.name = b_entry_name; i.value = buffer; - i.value_len = size; + i.value_len = cpu_to_le32(size); error = ext4_xattr_block_find(inode, &i, bs); if (error) goto cleanup; diff --git a/trunk/fs/fcntl.c b/trunk/fs/fcntl.c index 8685263ccc4a..c9db73fc5e3d 100644 --- a/trunk/fs/fcntl.c +++ b/trunk/fs/fcntl.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include @@ -293,7 +292,7 @@ int f_setown(struct file *filp, unsigned long arg, int force) who = -who; } rcu_read_lock(); - pid = find_vpid(who); + pid = find_pid(who); result = __f_setown(filp, pid, type, force); rcu_read_unlock(); return result; @@ -309,7 +308,7 @@ pid_t f_getown(struct file *filp) { pid_t pid; read_lock(&filp->f_owner.lock); - pid = pid_nr_ns(filp->f_owner.pid, current->nsproxy->pid_ns); + pid = pid_nr(filp->f_owner.pid); if (filp->f_owner.pid_type == PIDTYPE_PGID) pid = -pid; read_unlock(&filp->f_owner.lock); diff --git a/trunk/fs/file_table.c b/trunk/fs/file_table.c index 664e3f2309b8..3176fefc92e1 100644 --- a/trunk/fs/file_table.c +++ b/trunk/fs/file_table.c @@ -323,11 +323,12 @@ void file_kill(struct file *file) int fs_may_remount_ro(struct super_block *sb) { - struct file *file; + struct list_head *p; /* Check that no files are currently opened for writing. */ file_list_lock(); - list_for_each_entry(file, &sb->s_files, f_u.fu_list) { + list_for_each(p, &sb->s_files) { + struct file *file = list_entry(p, struct file, f_u.fu_list); struct inode *inode = file->f_path.dentry->d_inode; /* File with pending delete? */ diff --git a/trunk/fs/fs-writeback.c b/trunk/fs/fs-writeback.c index 0fca82021d76..686734ff973d 100644 --- a/trunk/fs/fs-writeback.c +++ b/trunk/fs/fs-writeback.c @@ -89,7 +89,7 @@ void __mark_inode_dirty(struct inode *inode, int flags) if (inode->i_ino || strcmp(inode->i_sb->s_id, "bdev")) printk(KERN_DEBUG "%s(%d): dirtied inode %lu (%s) on %s\n", - current->comm, task_pid_nr(current), inode->i_ino, + current->comm, current->pid, inode->i_ino, name, inode->i_sb->s_id); } diff --git a/trunk/fs/fuse/dir.c b/trunk/fs/fuse/dir.c index 3763757f9fe7..d1acab931330 100644 --- a/trunk/fs/fuse/dir.c +++ b/trunk/fs/fuse/dir.c @@ -63,21 +63,13 @@ static u64 time_to_jiffies(unsigned long sec, unsigned long nsec) * Set dentry and possibly attribute timeouts from the lookup/mk* * replies */ -static void fuse_change_entry_timeout(struct dentry *entry, - struct fuse_entry_out *o) +static void fuse_change_timeout(struct dentry *entry, struct fuse_entry_out *o) { fuse_dentry_settime(entry, time_to_jiffies(o->entry_valid, o->entry_valid_nsec)); -} - -static u64 attr_timeout(struct fuse_attr_out *o) -{ - return time_to_jiffies(o->attr_valid, o->attr_valid_nsec); -} - -static u64 entry_attr_timeout(struct fuse_entry_out *o) -{ - return time_to_jiffies(o->attr_valid, o->attr_valid_nsec); + if (entry->d_inode) + get_fuse_inode(entry->d_inode)->i_time = + time_to_jiffies(o->attr_valid, o->attr_valid_nsec); } /* @@ -116,19 +108,13 @@ static void fuse_lookup_init(struct fuse_req *req, struct inode *dir, struct dentry *entry, struct fuse_entry_out *outarg) { - struct fuse_conn *fc = get_fuse_conn(dir); - - memset(outarg, 0, sizeof(struct fuse_entry_out)); req->in.h.opcode = FUSE_LOOKUP; req->in.h.nodeid = get_node_id(dir); req->in.numargs = 1; req->in.args[0].size = entry->d_name.len + 1; req->in.args[0].value = entry->d_name.name; req->out.numargs = 1; - if (fc->minor < 9) - req->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE; - else - req->out.args[0].size = sizeof(struct fuse_entry_out); + req->out.args[0].size = sizeof(struct fuse_entry_out); req->out.args[0].value = outarg; } @@ -154,7 +140,6 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd) struct fuse_req *req; struct fuse_req *forget_req; struct dentry *parent; - u64 attr_version; /* For negative dentries, always do a fresh lookup */ if (!inode) @@ -171,10 +156,6 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd) return 0; } - spin_lock(&fc->lock); - attr_version = fc->attr_version; - spin_unlock(&fc->lock); - parent = dget_parent(entry); fuse_lookup_init(req, parent->d_inode, entry, &outarg); request_send(fc, req); @@ -199,10 +180,8 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd) if (err || (outarg.attr.mode ^ inode->i_mode) & S_IFMT) return 0; - fuse_change_attributes(inode, &outarg.attr, - entry_attr_timeout(&outarg), - attr_version); - fuse_change_entry_timeout(entry, &outarg); + fuse_change_attributes(inode, &outarg.attr); + fuse_change_timeout(entry, &outarg); } return 1; } @@ -249,7 +228,6 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry, struct fuse_conn *fc = get_fuse_conn(dir); struct fuse_req *req; struct fuse_req *forget_req; - u64 attr_version; if (entry->d_name.len > FUSE_NAME_MAX) return ERR_PTR(-ENAMETOOLONG); @@ -264,10 +242,6 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry, return ERR_PTR(PTR_ERR(forget_req)); } - spin_lock(&fc->lock); - attr_version = fc->attr_version; - spin_unlock(&fc->lock); - fuse_lookup_init(req, dir, entry, &outarg); request_send(fc, req); err = req->out.h.error; @@ -279,8 +253,7 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry, err = -EIO; if (!err && outarg.nodeid) { inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation, - &outarg.attr, entry_attr_timeout(&outarg), - attr_version); + &outarg.attr); if (!inode) { fuse_send_forget(fc, forget_req, outarg.nodeid, 1); return ERR_PTR(-ENOMEM); @@ -303,7 +276,7 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry, entry->d_op = &fuse_dentry_operations; if (!err) - fuse_change_entry_timeout(entry, &outarg); + fuse_change_timeout(entry, &outarg); else fuse_invalidate_entry_cache(entry); return NULL; @@ -362,7 +335,6 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode, flags &= ~O_NOCTTY; memset(&inarg, 0, sizeof(inarg)); - memset(&outentry, 0, sizeof(outentry)); inarg.flags = flags; inarg.mode = mode; req->in.h.opcode = FUSE_CREATE; @@ -373,10 +345,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode, req->in.args[1].size = entry->d_name.len + 1; req->in.args[1].value = entry->d_name.name; req->out.numargs = 2; - if (fc->minor < 9) - req->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE; - else - req->out.args[0].size = sizeof(outentry); + req->out.args[0].size = sizeof(outentry); req->out.args[0].value = &outentry; req->out.args[1].size = sizeof(outopen); req->out.args[1].value = &outopen; @@ -394,7 +363,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode, fuse_put_request(fc, req); inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation, - &outentry.attr, entry_attr_timeout(&outentry), 0); + &outentry.attr); if (!inode) { flags &= ~(O_CREAT | O_EXCL | O_TRUNC); ff->fh = outopen.fh; @@ -404,7 +373,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode, } fuse_put_request(fc, forget_req); d_instantiate(entry, inode); - fuse_change_entry_timeout(entry, &outentry); + fuse_change_timeout(entry, &outentry); file = lookup_instantiate_filp(nd, entry, generic_file_open); if (IS_ERR(file)) { ff->fh = outopen.fh; @@ -441,13 +410,9 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req, return PTR_ERR(forget_req); } - memset(&outarg, 0, sizeof(outarg)); req->in.h.nodeid = get_node_id(dir); req->out.numargs = 1; - if (fc->minor < 9) - req->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE; - else - req->out.args[0].size = sizeof(outarg); + req->out.args[0].size = sizeof(outarg); req->out.args[0].value = &outarg; request_send(fc, req); err = req->out.h.error; @@ -463,7 +428,7 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req, goto out_put_forget_req; inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation, - &outarg.attr, entry_attr_timeout(&outarg), 0); + &outarg.attr); if (!inode) { fuse_send_forget(fc, forget_req, outarg.nodeid, 1); return -ENOMEM; @@ -486,7 +451,7 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req, } else d_instantiate(entry, inode); - fuse_change_entry_timeout(entry, &outarg); + fuse_change_timeout(entry, &outarg); fuse_invalidate_attr(dir); return 0; @@ -698,83 +663,51 @@ static int fuse_link(struct dentry *entry, struct inode *newdir, return err; } -static void fuse_fillattr(struct inode *inode, struct fuse_attr *attr, - struct kstat *stat) -{ - stat->dev = inode->i_sb->s_dev; - stat->ino = attr->ino; - stat->mode = (inode->i_mode & S_IFMT) | (attr->mode & 07777); - stat->nlink = attr->nlink; - stat->uid = attr->uid; - stat->gid = attr->gid; - stat->rdev = inode->i_rdev; - stat->atime.tv_sec = attr->atime; - stat->atime.tv_nsec = attr->atimensec; - stat->mtime.tv_sec = attr->mtime; - stat->mtime.tv_nsec = attr->mtimensec; - stat->ctime.tv_sec = attr->ctime; - stat->ctime.tv_nsec = attr->ctimensec; - stat->size = attr->size; - stat->blocks = attr->blocks; - stat->blksize = (1 << inode->i_blkbits); -} - -static int fuse_do_getattr(struct inode *inode, struct kstat *stat, - struct file *file) +static int fuse_do_getattr(struct inode *inode) { int err; - struct fuse_getattr_in inarg; - struct fuse_attr_out outarg; + struct fuse_attr_out arg; struct fuse_conn *fc = get_fuse_conn(inode); - struct fuse_req *req; - u64 attr_version; - - req = fuse_get_req(fc); + struct fuse_req *req = fuse_get_req(fc); if (IS_ERR(req)) return PTR_ERR(req); - spin_lock(&fc->lock); - attr_version = fc->attr_version; - spin_unlock(&fc->lock); - - memset(&inarg, 0, sizeof(inarg)); - memset(&outarg, 0, sizeof(outarg)); - /* Directories have separate file-handle space */ - if (file && S_ISREG(inode->i_mode)) { - struct fuse_file *ff = file->private_data; - - inarg.getattr_flags |= FUSE_GETATTR_FH; - inarg.fh = ff->fh; - } req->in.h.opcode = FUSE_GETATTR; req->in.h.nodeid = get_node_id(inode); - req->in.numargs = 1; - req->in.args[0].size = sizeof(inarg); - req->in.args[0].value = &inarg; req->out.numargs = 1; - if (fc->minor < 9) - req->out.args[0].size = FUSE_COMPAT_ATTR_OUT_SIZE; - else - req->out.args[0].size = sizeof(outarg); - req->out.args[0].value = &outarg; + req->out.args[0].size = sizeof(arg); + req->out.args[0].value = &arg; request_send(fc, req); err = req->out.h.error; fuse_put_request(fc, req); if (!err) { - if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) { + if ((inode->i_mode ^ arg.attr.mode) & S_IFMT) { make_bad_inode(inode); err = -EIO; } else { - fuse_change_attributes(inode, &outarg.attr, - attr_timeout(&outarg), - attr_version); - if (stat) - fuse_fillattr(inode, &outarg.attr, stat); + struct fuse_inode *fi = get_fuse_inode(inode); + fuse_change_attributes(inode, &arg.attr); + fi->i_time = time_to_jiffies(arg.attr_valid, + arg.attr_valid_nsec); } } return err; } +/* + * Check if attributes are still valid, and if not send a GETATTR + * request to refresh them. + */ +static int fuse_refresh_attributes(struct inode *inode) +{ + struct fuse_inode *fi = get_fuse_inode(inode); + + if (fi->i_time < get_jiffies_64()) + return fuse_do_getattr(inode); + else + return 0; +} + /* * Calling into a user-controlled filesystem gives the filesystem * daemon ptrace-like capabilities over the requester process. This @@ -788,7 +721,7 @@ static int fuse_do_getattr(struct inode *inode, struct kstat *stat, * for which the owner of the mount has ptrace privilege. This * excludes processes started by other users, suid or sgid processes. */ -int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task) +static int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task) { if (fc->flags & FUSE_ALLOW_OTHER) return 1; @@ -862,14 +795,11 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd) */ if ((fc->flags & FUSE_DEFAULT_PERMISSIONS) || ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))) { - struct fuse_inode *fi = get_fuse_inode(inode); - if (fi->i_time < get_jiffies_64()) { - err = fuse_do_getattr(inode, NULL, NULL); - if (err) - return err; + err = fuse_refresh_attributes(inode); + if (err) + return err; - refreshed = true; - } + refreshed = true; } if (fc->flags & FUSE_DEFAULT_PERMISSIONS) { @@ -879,7 +809,7 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd) attributes. This is also needed, because the root node will at first have no permissions */ if (err == -EACCES && !refreshed) { - err = fuse_do_getattr(inode, NULL, NULL); + err = fuse_do_getattr(inode); if (!err) err = generic_permission(inode, mask, NULL); } @@ -895,7 +825,7 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd) if (refreshed) return -EACCES; - err = fuse_do_getattr(inode, NULL, NULL); + err = fuse_do_getattr(inode); if (!err && !(inode->i_mode & S_IXUGO)) return -EACCES; } @@ -1032,20 +962,6 @@ static int fuse_dir_fsync(struct file *file, struct dentry *de, int datasync) return file ? fuse_fsync_common(file, de, datasync, 1) : 0; } -static bool update_mtime(unsigned ivalid) -{ - /* Always update if mtime is explicitly set */ - if (ivalid & ATTR_MTIME_SET) - return true; - - /* If it's an open(O_TRUNC) or an ftruncate(), don't update */ - if ((ivalid & ATTR_SIZE) && (ivalid & (ATTR_OPEN | ATTR_FILE))) - return false; - - /* In all other cases update */ - return true; -} - static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg) { unsigned ivalid = iattr->ia_valid; @@ -1058,19 +974,16 @@ static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg) arg->valid |= FATTR_GID, arg->gid = iattr->ia_gid; if (ivalid & ATTR_SIZE) arg->valid |= FATTR_SIZE, arg->size = iattr->ia_size; - if (ivalid & ATTR_ATIME) { - arg->valid |= FATTR_ATIME; + /* You can only _set_ these together (they may change by themselves) */ + if ((ivalid & (ATTR_ATIME | ATTR_MTIME)) == (ATTR_ATIME | ATTR_MTIME)) { + arg->valid |= FATTR_ATIME | FATTR_MTIME; arg->atime = iattr->ia_atime.tv_sec; - arg->atimensec = iattr->ia_atime.tv_nsec; - if (!(ivalid & ATTR_ATIME_SET)) - arg->valid |= FATTR_ATIME_NOW; - } - if ((ivalid & ATTR_MTIME) && update_mtime(ivalid)) { - arg->valid |= FATTR_MTIME; arg->mtime = iattr->ia_mtime.tv_sec; - arg->mtimensec = iattr->ia_mtime.tv_nsec; - if (!(ivalid & ATTR_MTIME_SET)) - arg->valid |= FATTR_MTIME_NOW; + } + if (ivalid & ATTR_FILE) { + struct fuse_file *ff = iattr->ia_file->private_data; + arg->valid |= FATTR_FH; + arg->fh = ff->fh; } } @@ -1082,28 +995,22 @@ static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg) * vmtruncate() doesn't allow for this case, so do the rlimit checking * and the actual truncation by hand. */ -static int fuse_do_setattr(struct dentry *entry, struct iattr *attr, - struct file *file) +static int fuse_setattr(struct dentry *entry, struct iattr *attr) { struct inode *inode = entry->d_inode; struct fuse_conn *fc = get_fuse_conn(inode); + struct fuse_inode *fi = get_fuse_inode(inode); struct fuse_req *req; struct fuse_setattr_in inarg; struct fuse_attr_out outarg; int err; - if (!fuse_allow_task(fc, current)) - return -EACCES; - if (fc->flags & FUSE_DEFAULT_PERMISSIONS) { err = inode_change_ok(inode, attr); if (err) return err; } - if ((attr->ia_valid & ATTR_OPEN) && fc->atomic_o_trunc) - return 0; - if (attr->ia_valid & ATTR_SIZE) { unsigned long limit; if (IS_SWAPFILE(inode)) @@ -1120,28 +1027,14 @@ static int fuse_do_setattr(struct dentry *entry, struct iattr *attr, return PTR_ERR(req); memset(&inarg, 0, sizeof(inarg)); - memset(&outarg, 0, sizeof(outarg)); iattr_to_fattr(attr, &inarg); - if (file) { - struct fuse_file *ff = file->private_data; - inarg.valid |= FATTR_FH; - inarg.fh = ff->fh; - } - if (attr->ia_valid & ATTR_SIZE) { - /* For mandatory locking in truncate */ - inarg.valid |= FATTR_LOCKOWNER; - inarg.lock_owner = fuse_lock_owner_id(fc, current->files); - } req->in.h.opcode = FUSE_SETATTR; req->in.h.nodeid = get_node_id(inode); req->in.numargs = 1; req->in.args[0].size = sizeof(inarg); req->in.args[0].value = &inarg; req->out.numargs = 1; - if (fc->minor < 9) - req->out.args[0].size = FUSE_COMPAT_ATTR_OUT_SIZE; - else - req->out.args[0].size = sizeof(outarg); + req->out.args[0].size = sizeof(outarg); req->out.args[0].value = &outarg; request_send(fc, req); err = req->out.h.error; @@ -1157,18 +1050,11 @@ static int fuse_do_setattr(struct dentry *entry, struct iattr *attr, return -EIO; } - fuse_change_attributes(inode, &outarg.attr, attr_timeout(&outarg), 0); + fuse_change_attributes(inode, &outarg.attr); + fi->i_time = time_to_jiffies(outarg.attr_valid, outarg.attr_valid_nsec); return 0; } -static int fuse_setattr(struct dentry *entry, struct iattr *attr) -{ - if (attr->ia_valid & ATTR_FILE) - return fuse_do_setattr(entry, attr, attr->ia_file); - else - return fuse_do_setattr(entry, attr, NULL); -} - static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry, struct kstat *stat) { @@ -1180,10 +1066,8 @@ static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry, if (!fuse_allow_task(fc, current)) return -EACCES; - if (fi->i_time < get_jiffies_64()) - err = fuse_do_getattr(inode, stat, NULL); - else { - err = 0; + err = fuse_refresh_attributes(inode); + if (!err) { generic_fillattr(inode, stat); stat->mode = fi->orig_i_mode; } @@ -1288,9 +1172,6 @@ static ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size) struct fuse_getxattr_out outarg; ssize_t ret; - if (!fuse_allow_task(fc, current)) - return -EACCES; - if (fc->no_listxattr) return -EOPNOTSUPP; diff --git a/trunk/fs/fuse/file.c b/trunk/fs/fuse/file.c index 0fcdba9d47c0..c4b98c03a46e 100644 --- a/trunk/fs/fuse/file.c +++ b/trunk/fs/fuse/file.c @@ -28,9 +28,7 @@ static int fuse_send_open(struct inode *inode, struct file *file, int isdir, return PTR_ERR(req); memset(&inarg, 0, sizeof(inarg)); - inarg.flags = file->f_flags & ~(O_CREAT | O_EXCL | O_NOCTTY); - if (!fc->atomic_o_trunc) - inarg.flags &= ~O_TRUNC; + inarg.flags = file->f_flags & ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC); req->in.h.opcode = isdir ? FUSE_OPENDIR : FUSE_OPEN; req->in.h.nodeid = get_node_id(inode); req->in.numargs = 1; @@ -56,7 +54,6 @@ struct fuse_file *fuse_file_alloc(void) kfree(ff); ff = NULL; } - INIT_LIST_HEAD(&ff->write_entry); atomic_set(&ff->count, 0); } return ff; @@ -151,18 +148,12 @@ int fuse_release_common(struct inode *inode, struct file *file, int isdir) { struct fuse_file *ff = file->private_data; if (ff) { - struct fuse_conn *fc = get_fuse_conn(inode); - fuse_release_fill(ff, get_node_id(inode), file->f_flags, isdir ? FUSE_RELEASEDIR : FUSE_RELEASE); /* Hold vfsmount and dentry until release is finished */ ff->reserved_req->vfsmount = mntget(file->f_path.mnt); ff->reserved_req->dentry = dget(file->f_path.dentry); - - spin_lock(&fc->lock); - list_del(&ff->write_entry); - spin_unlock(&fc->lock); /* * Normally this will send the RELEASE request, * however if some asynchronous READ or WRITE requests @@ -189,7 +180,7 @@ static int fuse_release(struct inode *inode, struct file *file) * Scramble the ID space with XTEA, so that the value of the files_struct * pointer is not exposed to userspace. */ -u64 fuse_lock_owner_id(struct fuse_conn *fc, fl_owner_t id) +static u64 fuse_lock_owner_id(struct fuse_conn *fc, fl_owner_t id) { u32 *k = fc->scramble_key; u64 v = (unsigned long) id; @@ -308,19 +299,11 @@ void fuse_read_fill(struct fuse_req *req, struct fuse_file *ff, } static size_t fuse_send_read(struct fuse_req *req, struct file *file, - struct inode *inode, loff_t pos, size_t count, - fl_owner_t owner) + struct inode *inode, loff_t pos, size_t count) { struct fuse_conn *fc = get_fuse_conn(inode); struct fuse_file *ff = file->private_data; - fuse_read_fill(req, ff, inode, pos, count, FUSE_READ); - if (owner != NULL) { - struct fuse_read_in *inarg = &req->misc.read_in; - - inarg->read_flags |= FUSE_READ_LOCKOWNER; - inarg->lock_owner = fuse_lock_owner_id(fc, owner); - } request_send(fc, req); return req->out.args[0].size; } @@ -344,8 +327,7 @@ static int fuse_readpage(struct file *file, struct page *page) req->out.page_zeroing = 1; req->num_pages = 1; req->pages[0] = page; - fuse_send_read(req, file, inode, page_offset(page), PAGE_CACHE_SIZE, - NULL); + fuse_send_read(req, file, inode, page_offset(page), PAGE_CACHE_SIZE); err = req->out.h.error; fuse_put_request(fc, req); if (!err) @@ -452,47 +434,30 @@ static int fuse_readpages(struct file *file, struct address_space *mapping, return err; } -static void fuse_write_fill(struct fuse_req *req, struct fuse_file *ff, - struct inode *inode, loff_t pos, size_t count, - int writepage) +static size_t fuse_send_write(struct fuse_req *req, struct file *file, + struct inode *inode, loff_t pos, size_t count) { struct fuse_conn *fc = get_fuse_conn(inode); - struct fuse_write_in *inarg = &req->misc.write.in; - struct fuse_write_out *outarg = &req->misc.write.out; + struct fuse_file *ff = file->private_data; + struct fuse_write_in inarg; + struct fuse_write_out outarg; - memset(inarg, 0, sizeof(struct fuse_write_in)); - inarg->fh = ff->fh; - inarg->offset = pos; - inarg->size = count; - inarg->write_flags = writepage ? FUSE_WRITE_CACHE : 0; + memset(&inarg, 0, sizeof(struct fuse_write_in)); + inarg.fh = ff->fh; + inarg.offset = pos; + inarg.size = count; req->in.h.opcode = FUSE_WRITE; req->in.h.nodeid = get_node_id(inode); req->in.argpages = 1; req->in.numargs = 2; - if (fc->minor < 9) - req->in.args[0].size = FUSE_COMPAT_WRITE_IN_SIZE; - else - req->in.args[0].size = sizeof(struct fuse_write_in); - req->in.args[0].value = inarg; + req->in.args[0].size = sizeof(struct fuse_write_in); + req->in.args[0].value = &inarg; req->in.args[1].size = count; req->out.numargs = 1; req->out.args[0].size = sizeof(struct fuse_write_out); - req->out.args[0].value = outarg; -} - -static size_t fuse_send_write(struct fuse_req *req, struct file *file, - struct inode *inode, loff_t pos, size_t count, - fl_owner_t owner) -{ - struct fuse_conn *fc = get_fuse_conn(inode); - fuse_write_fill(req, file->private_data, inode, pos, count, 0); - if (owner != NULL) { - struct fuse_write_in *inarg = &req->misc.write.in; - inarg->write_flags |= FUSE_WRITE_LOCKOWNER; - inarg->lock_owner = fuse_lock_owner_id(fc, owner); - } + req->out.args[0].value = &outarg; request_send(fc, req); - return req->misc.write.out.size; + return outarg.size; } static int fuse_write_begin(struct file *file, struct address_space *mapping, @@ -513,7 +478,6 @@ static int fuse_buffered_write(struct file *file, struct inode *inode, int err; size_t nres; struct fuse_conn *fc = get_fuse_conn(inode); - struct fuse_inode *fi = get_fuse_inode(inode); unsigned offset = pos & (PAGE_CACHE_SIZE - 1); struct fuse_req *req; @@ -527,7 +491,7 @@ static int fuse_buffered_write(struct file *file, struct inode *inode, req->num_pages = 1; req->pages[0] = page; req->page_offset = offset; - nres = fuse_send_write(req, file, inode, pos, count, NULL); + nres = fuse_send_write(req, file, inode, pos, count); err = req->out.h.error; fuse_put_request(fc, req); if (!err && !nres) @@ -535,7 +499,6 @@ static int fuse_buffered_write(struct file *file, struct inode *inode, if (!err) { pos += nres; spin_lock(&fc->lock); - fi->attr_version = ++fc->attr_version; if (pos > inode->i_size) i_size_write(inode, pos); spin_unlock(&fc->lock); @@ -628,11 +591,9 @@ static ssize_t fuse_direct_io(struct file *file, const char __user *buf, nbytes = (req->num_pages << PAGE_SHIFT) - req->page_offset; nbytes = min(count, nbytes); if (write) - nres = fuse_send_write(req, file, inode, pos, nbytes, - current->files); + nres = fuse_send_write(req, file, inode, pos, nbytes); else - nres = fuse_send_read(req, file, inode, pos, nbytes, - current->files); + nres = fuse_send_read(req, file, inode, pos, nbytes); fuse_release_user_pages(req, !write); if (req->out.h.error) { if (!res) @@ -734,8 +695,7 @@ static int convert_fuse_file_lock(const struct fuse_file_lock *ffl, } static void fuse_lk_fill(struct fuse_req *req, struct file *file, - const struct file_lock *fl, int opcode, pid_t pid, - int flock) + const struct file_lock *fl, int opcode, pid_t pid) { struct inode *inode = file->f_path.dentry->d_inode; struct fuse_conn *fc = get_fuse_conn(inode); @@ -748,8 +708,6 @@ static void fuse_lk_fill(struct fuse_req *req, struct file *file, arg->lk.end = fl->fl_end; arg->lk.type = fl->fl_type; arg->lk.pid = pid; - if (flock) - arg->lk_flags |= FUSE_LK_FLOCK; req->in.h.opcode = opcode; req->in.h.nodeid = get_node_id(inode); req->in.numargs = 1; @@ -769,7 +727,7 @@ static int fuse_getlk(struct file *file, struct file_lock *fl) if (IS_ERR(req)) return PTR_ERR(req); - fuse_lk_fill(req, file, fl, FUSE_GETLK, 0, 0); + fuse_lk_fill(req, file, fl, FUSE_GETLK, 0); req->out.numargs = 1; req->out.args[0].size = sizeof(outarg); req->out.args[0].value = &outarg; @@ -782,7 +740,7 @@ static int fuse_getlk(struct file *file, struct file_lock *fl) return err; } -static int fuse_setlk(struct file *file, struct file_lock *fl, int flock) +static int fuse_setlk(struct file *file, struct file_lock *fl) { struct inode *inode = file->f_path.dentry->d_inode; struct fuse_conn *fc = get_fuse_conn(inode); @@ -799,7 +757,7 @@ static int fuse_setlk(struct file *file, struct file_lock *fl, int flock) if (IS_ERR(req)) return PTR_ERR(req); - fuse_lk_fill(req, file, fl, opcode, pid, flock); + fuse_lk_fill(req, file, fl, opcode, pid); request_send(fc, req); err = req->out.h.error; /* locking is restartable */ @@ -825,25 +783,8 @@ static int fuse_file_lock(struct file *file, int cmd, struct file_lock *fl) if (fc->no_lock) err = posix_lock_file_wait(file, fl); else - err = fuse_setlk(file, fl, 0); - } - return err; -} - -static int fuse_file_flock(struct file *file, int cmd, struct file_lock *fl) -{ - struct inode *inode = file->f_path.dentry->d_inode; - struct fuse_conn *fc = get_fuse_conn(inode); - int err; - - if (fc->no_lock) { - err = flock_lock_file_wait(file, fl); - } else { - /* emulate flock with POSIX locks */ - fl->fl_owner = (fl_owner_t) file; - err = fuse_setlk(file, fl, 1); + err = fuse_setlk(file, fl); } - return err; } @@ -895,7 +836,6 @@ static const struct file_operations fuse_file_operations = { .release = fuse_release, .fsync = fuse_fsync, .lock = fuse_file_lock, - .flock = fuse_file_flock, .splice_read = generic_file_splice_read, }; @@ -908,7 +848,6 @@ static const struct file_operations fuse_direct_io_file_operations = { .release = fuse_release, .fsync = fuse_fsync, .lock = fuse_file_lock, - .flock = fuse_file_flock, /* no mmap and splice_read */ }; diff --git a/trunk/fs/fuse/fuse_i.h b/trunk/fs/fuse/fuse_i.h index 6c5461de1a5f..1764506fdd11 100644 --- a/trunk/fs/fuse/fuse_i.h +++ b/trunk/fs/fuse/fuse_i.h @@ -67,12 +67,6 @@ struct fuse_inode { /** The sticky bit in inode->i_mode may have been removed, so preserve the original mode */ mode_t orig_i_mode; - - /** Version of last attribute change */ - u64 attr_version; - - /** Files usable in writepage. Protected by fc->lock */ - struct list_head write_files; }; /** FUSE specific file data */ @@ -85,9 +79,6 @@ struct fuse_file { /** Refcount */ atomic_t count; - - /** Entry on inode's write_files list */ - struct list_head write_entry; }; /** One input argument of a request */ @@ -219,10 +210,6 @@ struct fuse_req { struct fuse_init_in init_in; struct fuse_init_out init_out; struct fuse_read_in read_in; - struct { - struct fuse_write_in in; - struct fuse_write_out out; - } write; struct fuse_lk_in lk_in; } misc; @@ -330,9 +317,6 @@ struct fuse_conn { /** Do readpages asynchronously? Only set in INIT */ unsigned async_read : 1; - /** Do not send separate SETATTR request before open(O_TRUNC) */ - unsigned atomic_o_trunc : 1; - /* * The following bitfields are only for optimization purposes * and hence races in setting them will not cause malfunction @@ -403,9 +387,6 @@ struct fuse_conn { /** Reserved request for the DESTROY message */ struct fuse_req *destroy_req; - - /** Version counter for attribute changes */ - u64 attr_version; }; static inline struct fuse_conn *get_fuse_conn_super(struct super_block *sb) @@ -435,8 +416,7 @@ extern const struct file_operations fuse_dev_operations; * Get a filled in inode */ struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid, - int generation, struct fuse_attr *attr, - u64 attr_valid, u64 attr_version); + int generation, struct fuse_attr *attr); /** * Send FORGET command @@ -497,8 +477,7 @@ void fuse_init_symlink(struct inode *inode); /** * Change attributes of an inode */ -void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr, - u64 attr_valid, u64 attr_version); +void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr); /** * Initialize the client device @@ -586,10 +565,3 @@ void fuse_ctl_remove_conn(struct fuse_conn *fc); * Is file type valid? */ int fuse_valid_type(int m); - -/** - * Is task allowed to perform filesystem operation? - */ -int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task); - -u64 fuse_lock_owner_id(struct fuse_conn *fc, fl_owner_t id); diff --git a/trunk/fs/fuse/inode.c b/trunk/fs/fuse/inode.c index 9a68d6970845..fd0735715c14 100644 --- a/trunk/fs/fuse/inode.c +++ b/trunk/fs/fuse/inode.c @@ -56,7 +56,6 @@ static struct inode *fuse_alloc_inode(struct super_block *sb) fi->i_time = 0; fi->nodeid = 0; fi->nlookup = 0; - INIT_LIST_HEAD(&fi->write_files); fi->forget_req = fuse_request_alloc(); if (!fi->forget_req) { kmem_cache_free(fuse_inode_cachep, inode); @@ -69,7 +68,6 @@ static struct inode *fuse_alloc_inode(struct super_block *sb) static void fuse_destroy_inode(struct inode *inode) { struct fuse_inode *fi = get_fuse_inode(inode); - BUG_ON(!list_empty(&fi->write_files)); if (fi->forget_req) fuse_request_free(fi->forget_req); kmem_cache_free(fuse_inode_cachep, inode); @@ -119,22 +117,12 @@ static void fuse_truncate(struct address_space *mapping, loff_t offset) unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1); } - -void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr, - u64 attr_valid, u64 attr_version) +void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr) { struct fuse_conn *fc = get_fuse_conn(inode); struct fuse_inode *fi = get_fuse_inode(inode); loff_t oldsize; - spin_lock(&fc->lock); - if (attr_version != 0 && fi->attr_version > attr_version) { - spin_unlock(&fc->lock); - return; - } - fi->attr_version = ++fc->attr_version; - fi->i_time = attr_valid; - inode->i_ino = attr->ino; inode->i_mode = (inode->i_mode & S_IFMT) | (attr->mode & 07777); inode->i_nlink = attr->nlink; @@ -148,11 +136,6 @@ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr, inode->i_ctime.tv_sec = attr->ctime; inode->i_ctime.tv_nsec = attr->ctimensec; - if (attr->blksize != 0) - inode->i_blkbits = ilog2(attr->blksize); - else - inode->i_blkbits = inode->i_sb->s_blocksize_bits; - /* * Don't set the sticky bit in i_mode, unless we want the VFS * to check permissions. This prevents failures due to the @@ -162,6 +145,7 @@ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr, if (!(fc->flags & FUSE_DEFAULT_PERMISSIONS)) inode->i_mode &= ~S_ISVTX; + spin_lock(&fc->lock); oldsize = inode->i_size; i_size_write(inode, attr->size); spin_unlock(&fc->lock); @@ -210,8 +194,7 @@ static int fuse_inode_set(struct inode *inode, void *_nodeidp) } struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid, - int generation, struct fuse_attr *attr, - u64 attr_valid, u64 attr_version) + int generation, struct fuse_attr *attr) { struct inode *inode; struct fuse_inode *fi; @@ -239,8 +222,7 @@ struct inode *fuse_iget(struct super_block *sb, unsigned long nodeid, spin_lock(&fc->lock); fi->nlookup ++; spin_unlock(&fc->lock); - fuse_change_attributes(inode, attr, attr_valid, attr_version); - + fuse_change_attributes(inode, attr); return inode; } @@ -305,11 +287,6 @@ static int fuse_statfs(struct dentry *dentry, struct kstatfs *buf) struct fuse_statfs_out outarg; int err; - if (!fuse_allow_task(fc, current)) { - buf->f_type = FUSE_SUPER_MAGIC; - return 0; - } - req = fuse_get_req(fc); if (IS_ERR(req)) return PTR_ERR(req); @@ -475,7 +452,6 @@ static struct fuse_conn *new_conn(void) } fc->reqctr = 0; fc->blocked = 1; - fc->attr_version = 1; get_random_bytes(&fc->scramble_key, sizeof(fc->scramble_key)); } out: @@ -507,7 +483,7 @@ static struct inode *get_root_inode(struct super_block *sb, unsigned mode) attr.mode = mode; attr.ino = FUSE_ROOT_ID; attr.nlink = 1; - return fuse_iget(sb, 1, 0, &attr, 0, 0); + return fuse_iget(sb, 1, 0, &attr); } static const struct super_operations fuse_super_operations = { @@ -538,8 +514,6 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req) fc->async_read = 1; if (!(arg->flags & FUSE_POSIX_LOCKS)) fc->no_lock = 1; - if (arg->flags & FUSE_ATOMIC_O_TRUNC) - fc->atomic_o_trunc = 1; } else { ra_pages = fc->max_read / PAGE_CACHE_SIZE; fc->no_lock = 1; @@ -562,8 +536,7 @@ static void fuse_send_init(struct fuse_conn *fc, struct fuse_req *req) arg->major = FUSE_KERNEL_VERSION; arg->minor = FUSE_KERNEL_MINOR_VERSION; arg->max_readahead = fc->bdi.ra_pages * PAGE_CACHE_SIZE; - arg->flags |= FUSE_ASYNC_READ | FUSE_POSIX_LOCKS | FUSE_FILE_OPS | - FUSE_ATOMIC_O_TRUNC; + arg->flags |= FUSE_ASYNC_READ | FUSE_POSIX_LOCKS; req->in.h.opcode = FUSE_INIT; req->in.numargs = 1; req->in.args[0].size = sizeof(*arg); diff --git a/trunk/fs/ioprio.c b/trunk/fs/ioprio.c index d6ff77e8e7ec..10d2c211d18b 100644 --- a/trunk/fs/ioprio.c +++ b/trunk/fs/ioprio.c @@ -25,7 +25,6 @@ #include #include #include -#include static int set_task_ioprio(struct task_struct *task, int ioprio) { @@ -94,7 +93,7 @@ asmlinkage long sys_ioprio_set(int which, int who, int ioprio) if (!who) p = current; else - p = find_task_by_vpid(who); + p = find_task_by_pid(who); if (p) ret = set_task_ioprio(p, ioprio); break; @@ -102,7 +101,7 @@ asmlinkage long sys_ioprio_set(int which, int who, int ioprio) if (!who) pgrp = task_pgrp(current); else - pgrp = find_vpid(who); + pgrp = find_pid(who); do_each_pid_task(pgrp, PIDTYPE_PGID, p) { ret = set_task_ioprio(p, ioprio); if (ret) @@ -181,7 +180,7 @@ asmlinkage long sys_ioprio_get(int which, int who) if (!who) p = current; else - p = find_task_by_vpid(who); + p = find_task_by_pid(who); if (p) ret = get_task_ioprio(p); break; @@ -189,7 +188,7 @@ asmlinkage long sys_ioprio_get(int which, int who) if (!who) pgrp = task_pgrp(current); else - pgrp = find_vpid(who); + pgrp = find_pid(who); do_each_pid_task(pgrp, PIDTYPE_PGID, p) { tmpio = get_task_ioprio(p); if (tmpio < 0) diff --git a/trunk/fs/jbd/commit.c b/trunk/fs/jbd/commit.c index 8f1f2aa5fb39..a003d50edcdb 100644 --- a/trunk/fs/jbd/commit.c +++ b/trunk/fs/jbd/commit.c @@ -375,7 +375,7 @@ void journal_commit_transaction(journal_t *journal) struct buffer_head *bh = jh2bh(jh); jbd_lock_bh_state(bh); - jbd_free(jh->b_committed_data, bh->b_size); + jbd_slab_free(jh->b_committed_data, bh->b_size); jh->b_committed_data = NULL; jbd_unlock_bh_state(bh); } @@ -466,7 +466,7 @@ void journal_commit_transaction(journal_t *journal) spin_unlock(&journal->j_list_lock); if (err) - journal_abort(journal, err); + __journal_abort_hard(journal); journal_write_revoke_records(journal, commit_transaction); @@ -524,7 +524,7 @@ void journal_commit_transaction(journal_t *journal) descriptor = journal_get_descriptor_buffer(journal); if (!descriptor) { - journal_abort(journal, -EIO); + __journal_abort_hard(journal); continue; } @@ -557,7 +557,7 @@ void journal_commit_transaction(journal_t *journal) and repeat this loop: we'll fall into the refile-on-abort condition above. */ if (err) { - journal_abort(journal, err); + __journal_abort_hard(journal); continue; } @@ -748,7 +748,7 @@ void journal_commit_transaction(journal_t *journal) err = -EIO; if (err) - journal_abort(journal, err); + __journal_abort_hard(journal); /* End of a transaction! Finally, we can do checkpoint processing: any buffers committed as a result of this @@ -792,14 +792,14 @@ void journal_commit_transaction(journal_t *journal) * Otherwise, we can just throw away the frozen data now. */ if (jh->b_committed_data) { - jbd_free(jh->b_committed_data, bh->b_size); + jbd_slab_free(jh->b_committed_data, bh->b_size); jh->b_committed_data = NULL; if (jh->b_frozen_data) { jh->b_committed_data = jh->b_frozen_data; jh->b_frozen_data = NULL; } } else if (jh->b_frozen_data) { - jbd_free(jh->b_frozen_data, bh->b_size); + jbd_slab_free(jh->b_frozen_data, bh->b_size); jh->b_frozen_data = NULL; } diff --git a/trunk/fs/jbd/journal.c b/trunk/fs/jbd/journal.c index 5d14243499d4..a6be78c05dce 100644 --- a/trunk/fs/jbd/journal.c +++ b/trunk/fs/jbd/journal.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include @@ -84,6 +83,7 @@ EXPORT_SYMBOL(journal_force_commit); static int journal_convert_superblock_v1(journal_t *, journal_superblock_t *); static void __journal_abort_soft (journal_t *journal, int errno); +static int journal_create_jbd_slab(size_t slab_size); /* * Helper function used to manage commit timeouts @@ -218,7 +218,7 @@ static int journal_start_thread(journal_t *journal) if (IS_ERR(t)) return PTR_ERR(t); - wait_event(journal->j_wait_done_commit, journal->j_task != NULL); + wait_event(journal->j_wait_done_commit, journal->j_task != 0); return 0; } @@ -230,8 +230,7 @@ static void journal_kill_thread(journal_t *journal) while (journal->j_task) { wake_up(&journal->j_wait_commit); spin_unlock(&journal->j_state_lock); - wait_event(journal->j_wait_done_commit, - journal->j_task == NULL); + wait_event(journal->j_wait_done_commit, journal->j_task == 0); spin_lock(&journal->j_state_lock); } spin_unlock(&journal->j_state_lock); @@ -335,10 +334,10 @@ int journal_write_metadata_buffer(transaction_t *transaction, char *tmp; jbd_unlock_bh_state(bh_in); - tmp = jbd_alloc(bh_in->b_size, GFP_NOFS); + tmp = jbd_slab_alloc(bh_in->b_size, GFP_NOFS); jbd_lock_bh_state(bh_in); if (jh_in->b_frozen_data) { - jbd_free(tmp, bh_in->b_size); + jbd_slab_free(tmp, bh_in->b_size); goto repeat; } @@ -655,9 +654,10 @@ static journal_t * journal_init_common (void) journal_t *journal; int err; - journal = kzalloc(sizeof(*journal), GFP_KERNEL); + journal = jbd_kmalloc(sizeof(*journal), GFP_KERNEL); if (!journal) goto fail; + memset(journal, 0, sizeof(*journal)); init_waitqueue_head(&journal->j_wait_transaction_locked); init_waitqueue_head(&journal->j_wait_logspace); @@ -1095,6 +1095,13 @@ int journal_load(journal_t *journal) } } + /* + * Create a slab for this blocksize + */ + err = journal_create_jbd_slab(be32_to_cpu(sb->s_blocksize)); + if (err) + return err; + /* Let the recovery code check whether it needs to recover any * data from the journal. */ if (journal_recover(journal)) @@ -1607,6 +1614,86 @@ int journal_blocks_per_page(struct inode *inode) return 1 << (PAGE_CACHE_SHIFT - inode->i_sb->s_blocksize_bits); } +/* + * Simple support for retrying memory allocations. Introduced to help to + * debug different VM deadlock avoidance strategies. + */ +void * __jbd_kmalloc (const char *where, size_t size, gfp_t flags, int retry) +{ + return kmalloc(size, flags | (retry ? __GFP_NOFAIL : 0)); +} + +/* + * jbd slab management: create 1k, 2k, 4k, 8k slabs as needed + * and allocate frozen and commit buffers from these slabs. + * + * Reason for doing this is to avoid, SLAB_DEBUG - since it could + * cause bh to cross page boundary. + */ + +#define JBD_MAX_SLABS 5 +#define JBD_SLAB_INDEX(size) (size >> 11) + +static struct kmem_cache *jbd_slab[JBD_MAX_SLABS]; +static const char *jbd_slab_names[JBD_MAX_SLABS] = { + "jbd_1k", "jbd_2k", "jbd_4k", NULL, "jbd_8k" +}; + +static void journal_destroy_jbd_slabs(void) +{ + int i; + + for (i = 0; i < JBD_MAX_SLABS; i++) { + if (jbd_slab[i]) + kmem_cache_destroy(jbd_slab[i]); + jbd_slab[i] = NULL; + } +} + +static int journal_create_jbd_slab(size_t slab_size) +{ + int i = JBD_SLAB_INDEX(slab_size); + + BUG_ON(i >= JBD_MAX_SLABS); + + /* + * Check if we already have a slab created for this size + */ + if (jbd_slab[i]) + return 0; + + /* + * Create a slab and force alignment to be same as slabsize - + * this will make sure that allocations won't cross the page + * boundary. + */ + jbd_slab[i] = kmem_cache_create(jbd_slab_names[i], + slab_size, slab_size, 0, NULL); + if (!jbd_slab[i]) { + printk(KERN_EMERG "JBD: no memory for jbd_slab cache\n"); + return -ENOMEM; + } + return 0; +} + +void * jbd_slab_alloc(size_t size, gfp_t flags) +{ + int idx; + + idx = JBD_SLAB_INDEX(size); + BUG_ON(jbd_slab[idx] == NULL); + return kmem_cache_alloc(jbd_slab[idx], flags | __GFP_NOFAIL); +} + +void jbd_slab_free(void *ptr, size_t size) +{ + int idx; + + idx = JBD_SLAB_INDEX(size); + BUG_ON(jbd_slab[idx] == NULL); + kmem_cache_free(jbd_slab[idx], ptr); +} + /* * Journal_head storage management */ @@ -1652,14 +1739,14 @@ static struct journal_head *journal_alloc_journal_head(void) atomic_inc(&nr_journal_heads); #endif ret = kmem_cache_alloc(journal_head_cache, GFP_NOFS); - if (ret == NULL) { + if (ret == 0) { jbd_debug(1, "out of memory for journal_head\n"); if (time_after(jiffies, last_warning + 5*HZ)) { printk(KERN_NOTICE "ENOMEM in %s, retrying.\n", __FUNCTION__); last_warning = jiffies; } - while (ret == NULL) { + while (ret == 0) { yield(); ret = kmem_cache_alloc(journal_head_cache, GFP_NOFS); } @@ -1794,13 +1881,13 @@ static void __journal_remove_journal_head(struct buffer_head *bh) printk(KERN_WARNING "%s: freeing " "b_frozen_data\n", __FUNCTION__); - jbd_free(jh->b_frozen_data, bh->b_size); + jbd_slab_free(jh->b_frozen_data, bh->b_size); } if (jh->b_committed_data) { printk(KERN_WARNING "%s: freeing " "b_committed_data\n", __FUNCTION__); - jbd_free(jh->b_committed_data, bh->b_size); + jbd_slab_free(jh->b_committed_data, bh->b_size); } bh->b_private = NULL; jh->b_bh = NULL; /* debug, really */ @@ -1852,41 +1939,64 @@ void journal_put_journal_head(struct journal_head *jh) } /* - * debugfs tunables + * /proc tunables */ -#ifdef CONFIG_JBD_DEBUG - -u8 journal_enable_debug __read_mostly; +#if defined(CONFIG_JBD_DEBUG) +int journal_enable_debug; EXPORT_SYMBOL(journal_enable_debug); +#endif + +#if defined(CONFIG_JBD_DEBUG) && defined(CONFIG_PROC_FS) -static struct dentry *jbd_debugfs_dir; -static struct dentry *jbd_debug; +static struct proc_dir_entry *proc_jbd_debug; -static void __init jbd_create_debugfs_entry(void) +static int read_jbd_debug(char *page, char **start, off_t off, + int count, int *eof, void *data) { - jbd_debugfs_dir = debugfs_create_dir("jbd", NULL); - if (jbd_debugfs_dir) - jbd_debug = debugfs_create_u8("jbd-debug", S_IRUGO, - jbd_debugfs_dir, - &journal_enable_debug); + int ret; + + ret = sprintf(page + off, "%d\n", journal_enable_debug); + *eof = 1; + return ret; } -static void __exit jbd_remove_debugfs_entry(void) +static int write_jbd_debug(struct file *file, const char __user *buffer, + unsigned long count, void *data) { - debugfs_remove(jbd_debug); - debugfs_remove(jbd_debugfs_dir); + char buf[32]; + + if (count > ARRAY_SIZE(buf) - 1) + count = ARRAY_SIZE(buf) - 1; + if (copy_from_user(buf, buffer, count)) + return -EFAULT; + buf[ARRAY_SIZE(buf) - 1] = '\0'; + journal_enable_debug = simple_strtoul(buf, NULL, 10); + return count; } -#else +#define JBD_PROC_NAME "sys/fs/jbd-debug" -static inline void jbd_create_debugfs_entry(void) +static void __init create_jbd_proc_entry(void) { + proc_jbd_debug = create_proc_entry(JBD_PROC_NAME, 0644, NULL); + if (proc_jbd_debug) { + /* Why is this so hard? */ + proc_jbd_debug->read_proc = read_jbd_debug; + proc_jbd_debug->write_proc = write_jbd_debug; + } } -static inline void jbd_remove_debugfs_entry(void) +static void __exit remove_jbd_proc_entry(void) { + if (proc_jbd_debug) + remove_proc_entry(JBD_PROC_NAME, NULL); } +#else + +#define create_jbd_proc_entry() do {} while (0) +#define remove_jbd_proc_entry() do {} while (0) + #endif struct kmem_cache *jbd_handle_cache; @@ -1932,6 +2042,7 @@ static void journal_destroy_caches(void) journal_destroy_revoke_caches(); journal_destroy_journal_head_cache(); journal_destroy_handle_cache(); + journal_destroy_jbd_slabs(); } static int __init journal_init(void) @@ -1943,7 +2054,7 @@ static int __init journal_init(void) ret = journal_init_caches(); if (ret != 0) journal_destroy_caches(); - jbd_create_debugfs_entry(); + create_jbd_proc_entry(); return ret; } @@ -1954,7 +2065,7 @@ static void __exit journal_exit(void) if (n) printk(KERN_EMERG "JBD: leaked %d journal_heads!\n", n); #endif - jbd_remove_debugfs_entry(); + remove_jbd_proc_entry(); journal_destroy_caches(); } diff --git a/trunk/fs/jbd/recovery.c b/trunk/fs/jbd/recovery.c index c5d9694b6a2f..2a5f4b833e35 100644 --- a/trunk/fs/jbd/recovery.c +++ b/trunk/fs/jbd/recovery.c @@ -250,10 +250,10 @@ int journal_recover(journal_t *journal) if (!err) err = do_one_pass(journal, &info, PASS_REPLAY); - jbd_debug(1, "JBD: recovery, exit status %d, " + jbd_debug(0, "JBD: recovery, exit status %d, " "recovered transactions %u to %u\n", err, info.start_transaction, info.end_transaction); - jbd_debug(1, "JBD: Replayed %d and revoked %d/%d blocks\n", + jbd_debug(0, "JBD: Replayed %d and revoked %d/%d blocks\n", info.nr_replays, info.nr_revoke_hits, info.nr_revokes); /* Restart the log at the next transaction ID, thus invalidating @@ -297,7 +297,7 @@ int journal_skip_recovery(journal_t *journal) #ifdef CONFIG_JBD_DEBUG int dropped = info.end_transaction - be32_to_cpu(sb->s_sequence); #endif - jbd_debug(1, + jbd_debug(0, "JBD: ignoring %d transaction%s from the journal.\n", dropped, (dropped == 1) ? "" : "s"); journal->j_transaction_sequence = ++info.end_transaction; diff --git a/trunk/fs/jbd/transaction.c b/trunk/fs/jbd/transaction.c index 08ff6c7028cc..8df5bac0b7a5 100644 --- a/trunk/fs/jbd/transaction.c +++ b/trunk/fs/jbd/transaction.c @@ -96,12 +96,13 @@ static int start_this_handle(journal_t *journal, handle_t *handle) alloc_transaction: if (!journal->j_running_transaction) { - new_transaction = kzalloc(sizeof(*new_transaction), - GFP_NOFS|__GFP_NOFAIL); + new_transaction = jbd_kmalloc(sizeof(*new_transaction), + GFP_NOFS); if (!new_transaction) { ret = -ENOMEM; goto out; } + memset(new_transaction, 0, sizeof(*new_transaction)); } jbd_debug(3, "New handle %p going live.\n", handle); @@ -674,7 +675,7 @@ do_get_write_access(handle_t *handle, struct journal_head *jh, JBUFFER_TRACE(jh, "allocate memory for buffer"); jbd_unlock_bh_state(bh); frozen_buffer = - jbd_alloc(jh2bh(jh)->b_size, + jbd_slab_alloc(jh2bh(jh)->b_size, GFP_NOFS); if (!frozen_buffer) { printk(KERN_EMERG @@ -734,7 +735,7 @@ do_get_write_access(handle_t *handle, struct journal_head *jh, out: if (unlikely(frozen_buffer)) /* It's usually NULL */ - jbd_free(frozen_buffer, bh->b_size); + jbd_slab_free(frozen_buffer, bh->b_size); JBUFFER_TRACE(jh, "exit"); return error; @@ -887,7 +888,7 @@ int journal_get_undo_access(handle_t *handle, struct buffer_head *bh) repeat: if (!jh->b_committed_data) { - committed_data = jbd_alloc(jh2bh(jh)->b_size, GFP_NOFS); + committed_data = jbd_slab_alloc(jh2bh(jh)->b_size, GFP_NOFS); if (!committed_data) { printk(KERN_EMERG "%s: No memory for committed data\n", __FUNCTION__); @@ -914,7 +915,7 @@ int journal_get_undo_access(handle_t *handle, struct buffer_head *bh) out: journal_put_journal_head(jh); if (unlikely(committed_data)) - jbd_free(committed_data, bh->b_size); + jbd_slab_free(committed_data, bh->b_size); return err; } @@ -1171,7 +1172,7 @@ int journal_dirty_metadata(handle_t *handle, struct buffer_head *bh) } /* That test should have eliminated the following case: */ - J_ASSERT_JH(jh, jh->b_frozen_data == NULL); + J_ASSERT_JH(jh, jh->b_frozen_data == 0); JBUFFER_TRACE(jh, "file as BJ_Metadata"); spin_lock(&journal->j_list_lock); @@ -1521,7 +1522,7 @@ static void __journal_temp_unlink_buffer(struct journal_head *jh) J_ASSERT_JH(jh, jh->b_jlist < BJ_Types); if (jh->b_jlist != BJ_None) - J_ASSERT_JH(jh, transaction != NULL); + J_ASSERT_JH(jh, transaction != 0); switch (jh->b_jlist) { case BJ_None: @@ -1590,11 +1591,11 @@ __journal_try_to_free_buffer(journal_t *journal, struct buffer_head *bh) if (buffer_locked(bh) || buffer_dirty(bh)) goto out; - if (jh->b_next_transaction != NULL) + if (jh->b_next_transaction != 0) goto out; spin_lock(&journal->j_list_lock); - if (jh->b_transaction != NULL && jh->b_cp_transaction == NULL) { + if (jh->b_transaction != 0 && jh->b_cp_transaction == 0) { if (jh->b_jlist == BJ_SyncData || jh->b_jlist == BJ_Locked) { /* A written-back ordered data buffer */ JBUFFER_TRACE(jh, "release data"); @@ -1602,7 +1603,7 @@ __journal_try_to_free_buffer(journal_t *journal, struct buffer_head *bh) journal_remove_journal_head(bh); __brelse(bh); } - } else if (jh->b_cp_transaction != NULL && jh->b_transaction == NULL) { + } else if (jh->b_cp_transaction != 0 && jh->b_transaction == 0) { /* written-back checkpointed metadata buffer */ if (jh->b_jlist == BJ_None) { JBUFFER_TRACE(jh, "remove from checkpoint list"); @@ -1962,7 +1963,7 @@ void __journal_file_buffer(struct journal_head *jh, J_ASSERT_JH(jh, jh->b_jlist < BJ_Types); J_ASSERT_JH(jh, jh->b_transaction == transaction || - jh->b_transaction == NULL); + jh->b_transaction == 0); if (jh->b_transaction && jh->b_jlist == jlist) return; diff --git a/trunk/fs/jbd2/commit.c b/trunk/fs/jbd2/commit.c index 6986f334c643..c0f59d1b13dc 100644 --- a/trunk/fs/jbd2/commit.c +++ b/trunk/fs/jbd2/commit.c @@ -278,7 +278,7 @@ static inline void write_tag_block(int tag_bytes, journal_block_tag_t *tag, unsigned long long block) { tag->t_blocknr = cpu_to_be32(block & (u32)~0); - if (tag_bytes > JBD2_TAG_SIZE32) + if (tag_bytes > JBD_TAG_SIZE32) tag->t_blocknr_high = cpu_to_be32((block >> 31) >> 1); } @@ -384,7 +384,7 @@ void jbd2_journal_commit_transaction(journal_t *journal) struct buffer_head *bh = jh2bh(jh); jbd_lock_bh_state(bh); - jbd2_free(jh->b_committed_data, bh->b_size); + jbd2_slab_free(jh->b_committed_data, bh->b_size); jh->b_committed_data = NULL; jbd_unlock_bh_state(bh); } @@ -475,7 +475,7 @@ void jbd2_journal_commit_transaction(journal_t *journal) spin_unlock(&journal->j_list_lock); if (err) - jbd2_journal_abort(journal, err); + __jbd2_journal_abort_hard(journal); jbd2_journal_write_revoke_records(journal, commit_transaction); @@ -533,7 +533,7 @@ void jbd2_journal_commit_transaction(journal_t *journal) descriptor = jbd2_journal_get_descriptor_buffer(journal); if (!descriptor) { - jbd2_journal_abort(journal, -EIO); + __jbd2_journal_abort_hard(journal); continue; } @@ -566,7 +566,7 @@ void jbd2_journal_commit_transaction(journal_t *journal) and repeat this loop: we'll fall into the refile-on-abort condition above. */ if (err) { - jbd2_journal_abort(journal, err); + __jbd2_journal_abort_hard(journal); continue; } @@ -757,7 +757,7 @@ void jbd2_journal_commit_transaction(journal_t *journal) err = -EIO; if (err) - jbd2_journal_abort(journal, err); + __jbd2_journal_abort_hard(journal); /* End of a transaction! Finally, we can do checkpoint processing: any buffers committed as a result of this @@ -801,14 +801,14 @@ void jbd2_journal_commit_transaction(journal_t *journal) * Otherwise, we can just throw away the frozen data now. */ if (jh->b_committed_data) { - jbd2_free(jh->b_committed_data, bh->b_size); + jbd2_slab_free(jh->b_committed_data, bh->b_size); jh->b_committed_data = NULL; if (jh->b_frozen_data) { jh->b_committed_data = jh->b_frozen_data; jh->b_frozen_data = NULL; } } else if (jh->b_frozen_data) { - jbd2_free(jh->b_frozen_data, bh->b_size); + jbd2_slab_free(jh->b_frozen_data, bh->b_size); jh->b_frozen_data = NULL; } diff --git a/trunk/fs/jbd2/journal.c b/trunk/fs/jbd2/journal.c index 6ddc5531587c..f37324aee817 100644 --- a/trunk/fs/jbd2/journal.c +++ b/trunk/fs/jbd2/journal.c @@ -84,6 +84,7 @@ EXPORT_SYMBOL(jbd2_journal_force_commit); static int journal_convert_superblock_v1(journal_t *, journal_superblock_t *); static void __journal_abort_soft (journal_t *journal, int errno); +static int jbd2_journal_create_jbd_slab(size_t slab_size); /* * Helper function used to manage commit timeouts @@ -334,10 +335,10 @@ int jbd2_journal_write_metadata_buffer(transaction_t *transaction, char *tmp; jbd_unlock_bh_state(bh_in); - tmp = jbd2_alloc(bh_in->b_size, GFP_NOFS); + tmp = jbd2_slab_alloc(bh_in->b_size, GFP_NOFS); jbd_lock_bh_state(bh_in); if (jh_in->b_frozen_data) { - jbd2_free(tmp, bh_in->b_size); + jbd2_slab_free(tmp, bh_in->b_size); goto repeat; } @@ -654,9 +655,10 @@ static journal_t * journal_init_common (void) journal_t *journal; int err; - journal = kzalloc(sizeof(*journal), GFP_KERNEL|__GFP_NOFAIL); + journal = jbd_kmalloc(sizeof(*journal), GFP_KERNEL); if (!journal) goto fail; + memset(journal, 0, sizeof(*journal)); init_waitqueue_head(&journal->j_wait_transaction_locked); init_waitqueue_head(&journal->j_wait_logspace); @@ -670,7 +672,7 @@ static journal_t * journal_init_common (void) spin_lock_init(&journal->j_list_lock); spin_lock_init(&journal->j_state_lock); - journal->j_commit_interval = (HZ * JBD2_DEFAULT_MAX_COMMIT_AGE); + journal->j_commit_interval = (HZ * JBD_DEFAULT_MAX_COMMIT_AGE); /* The journal is marked for error until we succeed with recovery! */ journal->j_flags = JBD2_ABORT; @@ -1094,6 +1096,13 @@ int jbd2_journal_load(journal_t *journal) } } + /* + * Create a slab for this blocksize + */ + err = jbd2_journal_create_jbd_slab(be32_to_cpu(sb->s_blocksize)); + if (err) + return err; + /* Let the recovery code check whether it needs to recover any * data from the journal. */ if (jbd2_journal_recover(journal)) @@ -1612,9 +1621,89 @@ int jbd2_journal_blocks_per_page(struct inode *inode) size_t journal_tag_bytes(journal_t *journal) { if (JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_64BIT)) - return JBD2_TAG_SIZE64; + return JBD_TAG_SIZE64; else - return JBD2_TAG_SIZE32; + return JBD_TAG_SIZE32; +} + +/* + * Simple support for retrying memory allocations. Introduced to help to + * debug different VM deadlock avoidance strategies. + */ +void * __jbd2_kmalloc (const char *where, size_t size, gfp_t flags, int retry) +{ + return kmalloc(size, flags | (retry ? __GFP_NOFAIL : 0)); +} + +/* + * jbd slab management: create 1k, 2k, 4k, 8k slabs as needed + * and allocate frozen and commit buffers from these slabs. + * + * Reason for doing this is to avoid, SLAB_DEBUG - since it could + * cause bh to cross page boundary. + */ + +#define JBD_MAX_SLABS 5 +#define JBD_SLAB_INDEX(size) (size >> 11) + +static struct kmem_cache *jbd_slab[JBD_MAX_SLABS]; +static const char *jbd_slab_names[JBD_MAX_SLABS] = { + "jbd2_1k", "jbd2_2k", "jbd2_4k", NULL, "jbd2_8k" +}; + +static void jbd2_journal_destroy_jbd_slabs(void) +{ + int i; + + for (i = 0; i < JBD_MAX_SLABS; i++) { + if (jbd_slab[i]) + kmem_cache_destroy(jbd_slab[i]); + jbd_slab[i] = NULL; + } +} + +static int jbd2_journal_create_jbd_slab(size_t slab_size) +{ + int i = JBD_SLAB_INDEX(slab_size); + + BUG_ON(i >= JBD_MAX_SLABS); + + /* + * Check if we already have a slab created for this size + */ + if (jbd_slab[i]) + return 0; + + /* + * Create a slab and force alignment to be same as slabsize - + * this will make sure that allocations won't cross the page + * boundary. + */ + jbd_slab[i] = kmem_cache_create(jbd_slab_names[i], + slab_size, slab_size, 0, NULL); + if (!jbd_slab[i]) { + printk(KERN_EMERG "JBD: no memory for jbd_slab cache\n"); + return -ENOMEM; + } + return 0; +} + +void * jbd2_slab_alloc(size_t size, gfp_t flags) +{ + int idx; + + idx = JBD_SLAB_INDEX(size); + BUG_ON(jbd_slab[idx] == NULL); + return kmem_cache_alloc(jbd_slab[idx], flags | __GFP_NOFAIL); +} + +void jbd2_slab_free(void *ptr, size_t size) +{ + int idx; + + idx = JBD_SLAB_INDEX(size); + BUG_ON(jbd_slab[idx] == NULL); + kmem_cache_free(jbd_slab[idx], ptr); } /* @@ -1681,7 +1770,7 @@ static void journal_free_journal_head(struct journal_head *jh) { #ifdef CONFIG_JBD2_DEBUG atomic_dec(&nr_journal_heads); - memset(jh, JBD2_POISON_FREE, sizeof(*jh)); + memset(jh, JBD_POISON_FREE, sizeof(*jh)); #endif kmem_cache_free(jbd2_journal_head_cache, jh); } @@ -1804,13 +1893,13 @@ static void __journal_remove_journal_head(struct buffer_head *bh) printk(KERN_WARNING "%s: freeing " "b_frozen_data\n", __FUNCTION__); - jbd2_free(jh->b_frozen_data, bh->b_size); + jbd2_slab_free(jh->b_frozen_data, bh->b_size); } if (jh->b_committed_data) { printk(KERN_WARNING "%s: freeing " "b_committed_data\n", __FUNCTION__); - jbd2_free(jh->b_committed_data, bh->b_size); + jbd2_slab_free(jh->b_committed_data, bh->b_size); } bh->b_private = NULL; jh->b_bh = NULL; /* debug, really */ @@ -1864,14 +1953,16 @@ void jbd2_journal_put_journal_head(struct journal_head *jh) /* * debugfs tunables */ -#ifdef CONFIG_JBD2_DEBUG -u8 jbd2_journal_enable_debug __read_mostly; +#if defined(CONFIG_JBD2_DEBUG) +u8 jbd2_journal_enable_debug; EXPORT_SYMBOL(jbd2_journal_enable_debug); +#endif + +#if defined(CONFIG_JBD2_DEBUG) && defined(CONFIG_DEBUG_FS) #define JBD2_DEBUG_NAME "jbd2-debug" -static struct dentry *jbd2_debugfs_dir; -static struct dentry *jbd2_debug; +struct dentry *jbd2_debugfs_dir, *jbd2_debug; static void __init jbd2_create_debugfs_entry(void) { @@ -1884,18 +1975,24 @@ static void __init jbd2_create_debugfs_entry(void) static void __exit jbd2_remove_debugfs_entry(void) { - debugfs_remove(jbd2_debug); - debugfs_remove(jbd2_debugfs_dir); + if (jbd2_debug) + debugfs_remove(jbd2_debug); + if (jbd2_debugfs_dir) + debugfs_remove(jbd2_debugfs_dir); } #else static void __init jbd2_create_debugfs_entry(void) { + do { + } while (0); } static void __exit jbd2_remove_debugfs_entry(void) { + do { + } while (0); } #endif @@ -1943,6 +2040,7 @@ static void jbd2_journal_destroy_caches(void) jbd2_journal_destroy_revoke_caches(); jbd2_journal_destroy_jbd2_journal_head_cache(); jbd2_journal_destroy_handle_cache(); + jbd2_journal_destroy_jbd_slabs(); } static int __init journal_init(void) diff --git a/trunk/fs/jbd2/recovery.c b/trunk/fs/jbd2/recovery.c index d0ce627539ef..b50be8a044eb 100644 --- a/trunk/fs/jbd2/recovery.c +++ b/trunk/fs/jbd2/recovery.c @@ -311,7 +311,7 @@ int jbd2_journal_skip_recovery(journal_t *journal) static inline unsigned long long read_tag_block(int tag_bytes, journal_block_tag_t *tag) { unsigned long long block = be32_to_cpu(tag->t_blocknr); - if (tag_bytes > JBD2_TAG_SIZE32) + if (tag_bytes > JBD_TAG_SIZE32) block |= (u64)be32_to_cpu(tag->t_blocknr_high) << 32; return block; } diff --git a/trunk/fs/jbd2/revoke.c b/trunk/fs/jbd2/revoke.c index 3595fd432d5b..01d88975e0c5 100644 --- a/trunk/fs/jbd2/revoke.c +++ b/trunk/fs/jbd2/revoke.c @@ -352,7 +352,7 @@ int jbd2_journal_revoke(handle_t *handle, unsigned long long blocknr, if (bh) BUFFER_TRACE(bh, "found on hash"); } -#ifdef JBD2_EXPENSIVE_CHECKING +#ifdef JBD_EXPENSIVE_CHECKING else { struct buffer_head *bh2; @@ -453,7 +453,7 @@ int jbd2_journal_cancel_revoke(handle_t *handle, struct journal_head *jh) } } -#ifdef JBD2_EXPENSIVE_CHECKING +#ifdef JBD_EXPENSIVE_CHECKING /* There better not be one left behind by now! */ record = find_revoke_record(journal, bh->b_blocknr); J_ASSERT_JH(jh, record == NULL); diff --git a/trunk/fs/jbd2/transaction.c b/trunk/fs/jbd2/transaction.c index b1fcf2b3dca3..7946ff43fc40 100644 --- a/trunk/fs/jbd2/transaction.c +++ b/trunk/fs/jbd2/transaction.c @@ -96,12 +96,13 @@ static int start_this_handle(journal_t *journal, handle_t *handle) alloc_transaction: if (!journal->j_running_transaction) { - new_transaction = kzalloc(sizeof(*new_transaction), - GFP_NOFS|__GFP_NOFAIL); + new_transaction = jbd_kmalloc(sizeof(*new_transaction), + GFP_NOFS); if (!new_transaction) { ret = -ENOMEM; goto out; } + memset(new_transaction, 0, sizeof(*new_transaction)); } jbd_debug(3, "New handle %p going live.\n", handle); @@ -235,7 +236,7 @@ static int start_this_handle(journal_t *journal, handle_t *handle) /* Allocate a new handle. This should probably be in a slab... */ static handle_t *new_handle(int nblocks) { - handle_t *handle = jbd2_alloc_handle(GFP_NOFS); + handle_t *handle = jbd_alloc_handle(GFP_NOFS); if (!handle) return NULL; memset(handle, 0, sizeof(*handle)); @@ -281,7 +282,7 @@ handle_t *jbd2_journal_start(journal_t *journal, int nblocks) err = start_this_handle(journal, handle); if (err < 0) { - jbd2_free_handle(handle); + jbd_free_handle(handle); current->journal_info = NULL; handle = ERR_PTR(err); } @@ -667,7 +668,7 @@ do_get_write_access(handle_t *handle, struct journal_head *jh, JBUFFER_TRACE(jh, "allocate memory for buffer"); jbd_unlock_bh_state(bh); frozen_buffer = - jbd2_alloc(jh2bh(jh)->b_size, + jbd2_slab_alloc(jh2bh(jh)->b_size, GFP_NOFS); if (!frozen_buffer) { printk(KERN_EMERG @@ -727,7 +728,7 @@ do_get_write_access(handle_t *handle, struct journal_head *jh, out: if (unlikely(frozen_buffer)) /* It's usually NULL */ - jbd2_free(frozen_buffer, bh->b_size); + jbd2_slab_free(frozen_buffer, bh->b_size); JBUFFER_TRACE(jh, "exit"); return error; @@ -880,7 +881,7 @@ int jbd2_journal_get_undo_access(handle_t *handle, struct buffer_head *bh) repeat: if (!jh->b_committed_data) { - committed_data = jbd2_alloc(jh2bh(jh)->b_size, GFP_NOFS); + committed_data = jbd2_slab_alloc(jh2bh(jh)->b_size, GFP_NOFS); if (!committed_data) { printk(KERN_EMERG "%s: No memory for committed data\n", __FUNCTION__); @@ -907,7 +908,7 @@ int jbd2_journal_get_undo_access(handle_t *handle, struct buffer_head *bh) out: jbd2_journal_put_journal_head(jh); if (unlikely(committed_data)) - jbd2_free(committed_data, bh->b_size); + jbd2_slab_free(committed_data, bh->b_size); return err; } @@ -1410,7 +1411,7 @@ int jbd2_journal_stop(handle_t *handle) spin_unlock(&journal->j_state_lock); } - jbd2_free_handle(handle); + jbd_free_handle(handle); return err; } diff --git a/trunk/fs/jffs2/debug.h b/trunk/fs/jffs2/debug.h index 4130adabd76e..2a49f2c51a9f 100644 --- a/trunk/fs/jffs2/debug.h +++ b/trunk/fs/jffs2/debug.h @@ -80,28 +80,28 @@ #define JFFS2_ERROR(fmt, ...) \ do { \ printk(JFFS2_ERR_MSG_PREFIX \ - " (%d) %s: " fmt, task_pid_nr(current), \ + " (%d) %s: " fmt, current->pid, \ __FUNCTION__ , ##__VA_ARGS__); \ } while(0) #define JFFS2_WARNING(fmt, ...) \ do { \ printk(JFFS2_WARN_MSG_PREFIX \ - " (%d) %s: " fmt, task_pid_nr(current), \ + " (%d) %s: " fmt, current->pid, \ __FUNCTION__ , ##__VA_ARGS__); \ } while(0) #define JFFS2_NOTICE(fmt, ...) \ do { \ printk(JFFS2_NOTICE_MSG_PREFIX \ - " (%d) %s: " fmt, task_pid_nr(current), \ + " (%d) %s: " fmt, current->pid, \ __FUNCTION__ , ##__VA_ARGS__); \ } while(0) #define JFFS2_DEBUG(fmt, ...) \ do { \ printk(JFFS2_DBG_MSG_PREFIX \ - " (%d) %s: " fmt, task_pid_nr(current), \ + " (%d) %s: " fmt, current->pid, \ __FUNCTION__ , ##__VA_ARGS__); \ } while(0) diff --git a/trunk/fs/namei.c b/trunk/fs/namei.c index 1e5c71669164..464eeccb675b 100644 --- a/trunk/fs/namei.c +++ b/trunk/fs/namei.c @@ -1659,10 +1659,8 @@ int may_open(struct nameidata *nd, int acc_mode, int flag) error = locks_verify_locked(inode); if (!error) { DQUOT_INIT(inode); - - error = do_truncate(dentry, 0, - ATTR_MTIME|ATTR_CTIME|ATTR_OPEN, - NULL); + + error = do_truncate(dentry, 0, ATTR_MTIME|ATTR_CTIME, NULL); } put_write_access(inode); if (error) diff --git a/trunk/fs/namespace.c b/trunk/fs/namespace.c index 860752998fb3..07daa7972591 100644 --- a/trunk/fs/namespace.c +++ b/trunk/fs/namespace.c @@ -1411,7 +1411,7 @@ long do_mount(char *dev_name, char *dir_name, char *type_page, mnt_flags |= MNT_RELATIME; flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE | - MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT); + MS_NOATIME | MS_NODIRATIME | MS_RELATIME); /* ... and get the mountpoint */ retval = path_lookup(dir_name, LOOKUP_FOLLOW, &nd); diff --git a/trunk/fs/nfs/inode.c b/trunk/fs/nfs/inode.c index 6d2f2a3eccf8..6c22453d77ae 100644 --- a/trunk/fs/nfs/inode.c +++ b/trunk/fs/nfs/inode.c @@ -357,10 +357,6 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr) nfs_inc_stats(inode, NFSIOS_VFSSETATTR); - /* skip mode change if it's just for clearing setuid/setgid */ - if (attr->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) - attr->ia_valid &= ~ATTR_MODE; - if (attr->ia_valid & ATTR_SIZE) { if (!S_ISREG(inode->i_mode) || attr->ia_size == i_size_read(inode)) attr->ia_valid &= ~ATTR_SIZE; diff --git a/trunk/fs/nfsd/vfs.c b/trunk/fs/nfsd/vfs.c index d0199189924c..819545d21670 100644 --- a/trunk/fs/nfsd/vfs.c +++ b/trunk/fs/nfsd/vfs.c @@ -364,23 +364,14 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap, if (iap->ia_valid & ATTR_MODE) { iap->ia_mode &= S_IALLUGO; imode = iap->ia_mode |= (imode & ~S_IALLUGO); - /* if changing uid/gid revoke setuid/setgid in mode */ - if ((iap->ia_valid & ATTR_UID) && iap->ia_uid != inode->i_uid) { - iap->ia_valid |= ATTR_KILL_PRIV; - iap->ia_mode &= ~S_ISUID; - } - if ((iap->ia_valid & ATTR_GID) && iap->ia_gid != inode->i_gid) - iap->ia_mode &= ~S_ISGID; - } else { - /* - * Revoke setuid/setgid bit on chown/chgrp - */ - if ((iap->ia_valid & ATTR_UID) && iap->ia_uid != inode->i_uid) - iap->ia_valid |= ATTR_KILL_SUID | ATTR_KILL_PRIV; - if ((iap->ia_valid & ATTR_GID) && iap->ia_gid != inode->i_gid) - iap->ia_valid |= ATTR_KILL_SGID; } + /* Revoke setuid/setgid bit on chown/chgrp */ + if ((iap->ia_valid & ATTR_UID) && iap->ia_uid != inode->i_uid) + iap->ia_valid |= ATTR_KILL_SUID | ATTR_KILL_PRIV; + if ((iap->ia_valid & ATTR_GID) && iap->ia_gid != inode->i_gid) + iap->ia_valid |= ATTR_KILL_SGID; + /* Change the attributes. */ iap->ia_valid |= ATTR_CTIME; @@ -1029,13 +1020,13 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, if (EX_WGATHER(exp)) { if (atomic_read(&inode->i_writecount) > 1 || (last_ino == inode->i_ino && last_dev == inode->i_sb->s_dev)) { - dprintk("nfsd: write defer %d\n", task_pid_nr(current)); + dprintk("nfsd: write defer %d\n", current->pid); msleep(10); - dprintk("nfsd: write resume %d\n", task_pid_nr(current)); + dprintk("nfsd: write resume %d\n", current->pid); } if (inode->i_state & I_DIRTY) { - dprintk("nfsd: write sync %d\n", task_pid_nr(current)); + dprintk("nfsd: write sync %d\n", current->pid); host_err=nfsd_sync(file); } #if 0 diff --git a/trunk/fs/nls/nls_base.c b/trunk/fs/nls/nls_base.c index 64965e1c21c4..e7905816c4ca 100644 --- a/trunk/fs/nls/nls_base.c +++ b/trunk/fs/nls/nls_base.c @@ -111,7 +111,7 @@ utf8_wctomb(__u8 *s, wchar_t wc, int maxlen) int c, nc; const struct utf8_table *t; - if (!s) + if (s == 0) return 0; l = wc; diff --git a/trunk/fs/ocfs2/cluster/heartbeat.c b/trunk/fs/ocfs2/cluster/heartbeat.c index 9cc7c0418b70..f14b541fab95 100644 --- a/trunk/fs/ocfs2/cluster/heartbeat.c +++ b/trunk/fs/ocfs2/cluster/heartbeat.c @@ -1372,7 +1372,7 @@ static ssize_t o2hb_region_pid_read(struct o2hb_region *reg, spin_lock(&o2hb_live_lock); if (reg->hr_task) - pid = task_pid_nr(reg->hr_task); + pid = reg->hr_task->pid; spin_unlock(&o2hb_live_lock); if (!pid) diff --git a/trunk/fs/ocfs2/cluster/masklog.h b/trunk/fs/ocfs2/cluster/masklog.h index cd046060114e..75cd877f6d42 100644 --- a/trunk/fs/ocfs2/cluster/masklog.h +++ b/trunk/fs/ocfs2/cluster/masklog.h @@ -192,7 +192,7 @@ extern struct mlog_bits mlog_and_bits, mlog_not_bits; * previous token if args expands to nothing. */ #define __mlog_printk(level, fmt, args...) \ - printk(level "(%u,%lu):%s:%d " fmt, task_pid_nr(current), \ + printk(level "(%u,%lu):%s:%d " fmt, current->pid, \ __mlog_cpu_guess, __PRETTY_FUNCTION__, __LINE__ , \ ##args) diff --git a/trunk/fs/ocfs2/dlm/dlmrecovery.c b/trunk/fs/ocfs2/dlm/dlmrecovery.c index 2fde7bf91434..a2c33160bfd6 100644 --- a/trunk/fs/ocfs2/dlm/dlmrecovery.c +++ b/trunk/fs/ocfs2/dlm/dlmrecovery.c @@ -259,7 +259,7 @@ static void dlm_print_reco_node_status(struct dlm_ctxt *dlm) struct dlm_lock_resource *res; mlog(ML_NOTICE, "%s(%d): recovery info, state=%s, dead=%u, master=%u\n", - dlm->name, task_pid_nr(dlm->dlm_reco_thread_task), + dlm->name, dlm->dlm_reco_thread_task->pid, dlm->reco.state & DLM_RECO_STATE_ACTIVE ? "ACTIVE" : "inactive", dlm->reco.dead_node, dlm->reco.new_master); @@ -420,7 +420,7 @@ void dlm_wait_for_recovery(struct dlm_ctxt *dlm) if (dlm_in_recovery(dlm)) { mlog(0, "%s: reco thread %d in recovery: " "state=%d, master=%u, dead=%u\n", - dlm->name, task_pid_nr(dlm->dlm_reco_thread_task), + dlm->name, dlm->dlm_reco_thread_task->pid, dlm->reco.state, dlm->reco.new_master, dlm->reco.dead_node); } @@ -483,7 +483,7 @@ static int dlm_do_recovery(struct dlm_ctxt *dlm) return 0; } mlog(0, "%s(%d):recovery thread found node %u in the recovery map!\n", - dlm->name, task_pid_nr(dlm->dlm_reco_thread_task), + dlm->name, dlm->dlm_reco_thread_task->pid, dlm->reco.dead_node); spin_unlock(&dlm->spinlock); @@ -507,7 +507,7 @@ static int dlm_do_recovery(struct dlm_ctxt *dlm) mlog(0, "another node will master this recovery session.\n"); } mlog(0, "dlm=%s (%d), new_master=%u, this node=%u, dead_node=%u\n", - dlm->name, task_pid_nr(dlm->dlm_reco_thread_task), dlm->reco.new_master, + dlm->name, dlm->dlm_reco_thread_task->pid, dlm->reco.new_master, dlm->node_num, dlm->reco.dead_node); /* it is safe to start everything back up here @@ -520,7 +520,7 @@ static int dlm_do_recovery(struct dlm_ctxt *dlm) master_here: mlog(0, "(%d) mastering recovery of %s:%u here(this=%u)!\n", - task_pid_nr(dlm->dlm_reco_thread_task), + dlm->dlm_reco_thread_task->pid, dlm->name, dlm->reco.dead_node, dlm->node_num); status = dlm_remaster_locks(dlm, dlm->reco.dead_node); diff --git a/trunk/fs/proc/array.c b/trunk/fs/proc/array.c index 63c95afb561f..27b59f5f3bd1 100644 --- a/trunk/fs/proc/array.c +++ b/trunk/fs/proc/array.c @@ -77,7 +77,6 @@ #include #include #include -#include #include #include @@ -146,7 +145,8 @@ static inline const char *get_task_state(struct task_struct *tsk) TASK_UNINTERRUPTIBLE | TASK_STOPPED | TASK_TRACED)) | - tsk->exit_state; + (tsk->exit_state & (EXIT_ZOMBIE | + EXIT_DEAD)); const char **p = &task_state_array[0]; while (state) { @@ -161,15 +161,8 @@ static inline char *task_state(struct task_struct *p, char *buffer) struct group_info *group_info; int g; struct fdtable *fdt = NULL; - struct pid_namespace *ns; - pid_t ppid, tpid; - ns = current->nsproxy->pid_ns; rcu_read_lock(); - ppid = pid_alive(p) ? - task_tgid_nr_ns(rcu_dereference(p->real_parent), ns) : 0; - tpid = pid_alive(p) && p->ptrace ? - task_ppid_nr_ns(rcu_dereference(p->parent), ns) : 0; buffer += sprintf(buffer, "State:\t%s\n" "Tgid:\t%d\n" @@ -179,9 +172,9 @@ static inline char *task_state(struct task_struct *p, char *buffer) "Uid:\t%d\t%d\t%d\t%d\n" "Gid:\t%d\t%d\t%d\t%d\n", get_task_state(p), - task_tgid_nr_ns(p, ns), - task_pid_nr_ns(p, ns), - ppid, tpid, + p->tgid, p->pid, + pid_alive(p) ? rcu_dereference(p->real_parent)->tgid : 0, + pid_alive(p) && p->ptrace ? rcu_dereference(p->parent)->pid : 0, p->uid, p->euid, p->suid, p->fsuid, p->gid, p->egid, p->sgid, p->fsgid); @@ -401,9 +394,6 @@ static int do_task_stat(struct task_struct *task, char *buffer, int whole) unsigned long rsslim = 0; char tcomm[sizeof(task->comm)]; unsigned long flags; - struct pid_namespace *ns; - - ns = current->nsproxy->pid_ns; state = *get_task_state(task); vsize = eip = esp = 0; @@ -426,7 +416,7 @@ static int do_task_stat(struct task_struct *task, char *buffer, int whole) struct signal_struct *sig = task->signal; if (sig->tty) { - tty_pgrp = pid_nr_ns(sig->tty->pgrp, ns); + tty_pgrp = pid_nr(sig->tty->pgrp); tty_nr = new_encode_dev(tty_devnum(sig->tty)); } @@ -456,12 +446,12 @@ static int do_task_stat(struct task_struct *task, char *buffer, int whole) maj_flt += sig->maj_flt; utime = cputime_add(utime, sig->utime); stime = cputime_add(stime, sig->stime); - gtime = cputime_add(gtime, sig->gtime); + gtime += cputime_add(gtime, sig->gtime); } - sid = task_session_nr_ns(task, ns); - pgid = task_pgrp_nr_ns(task, ns); - ppid = task_ppid_nr_ns(task, ns); + sid = signal_session(sig); + pgid = process_group(task); + ppid = rcu_dereference(task->real_parent)->tgid; unlock_task_sighand(task, &flags); } @@ -493,7 +483,7 @@ static int do_task_stat(struct task_struct *task, char *buffer, int whole) res = sprintf(buffer, "%d (%s) %c %d %d %d %d %d %u %lu \ %lu %lu %lu %lu %lu %ld %ld %ld %ld %d 0 %llu %lu %ld %lu %lu %lu %lu %lu \ %lu %lu %lu %lu %lu %lu %lu %lu %d %d %u %u %llu %lu %ld\n", - task_pid_nr_ns(task, ns), + task->pid, tcomm, state, ppid, diff --git a/trunk/fs/proc/base.c b/trunk/fs/proc/base.c index 39a3d7c969c5..4fe74d156416 100644 --- a/trunk/fs/proc/base.c +++ b/trunk/fs/proc/base.c @@ -63,19 +63,16 @@ #include #include #include -#include #include #include #include #include -#include #include #include #include #include #include #include -#include #include "internal.h" /* NOTE: @@ -304,78 +301,6 @@ static int proc_oom_score(struct task_struct *task, char *buffer) return sprintf(buffer, "%lu\n", points); } -struct limit_names { - char *name; - char *unit; -}; - -static const struct limit_names lnames[RLIM_NLIMITS] = { - [RLIMIT_CPU] = {"Max cpu time", "ms"}, - [RLIMIT_FSIZE] = {"Max file size", "bytes"}, - [RLIMIT_DATA] = {"Max data size", "bytes"}, - [RLIMIT_STACK] = {"Max stack size", "bytes"}, - [RLIMIT_CORE] = {"Max core file size", "bytes"}, - [RLIMIT_RSS] = {"Max resident set", "bytes"}, - [RLIMIT_NPROC] = {"Max processes", "processes"}, - [RLIMIT_NOFILE] = {"Max open files", "files"}, - [RLIMIT_MEMLOCK] = {"Max locked memory", "bytes"}, - [RLIMIT_AS] = {"Max address space", "bytes"}, - [RLIMIT_LOCKS] = {"Max file locks", "locks"}, - [RLIMIT_SIGPENDING] = {"Max pending signals", "signals"}, - [RLIMIT_MSGQUEUE] = {"Max msgqueue size", "bytes"}, - [RLIMIT_NICE] = {"Max nice priority", NULL}, - [RLIMIT_RTPRIO] = {"Max realtime priority", NULL}, -}; - -/* Display limits for a process */ -static int proc_pid_limits(struct task_struct *task, char *buffer) -{ - unsigned int i; - int count = 0; - unsigned long flags; - char *bufptr = buffer; - - struct rlimit rlim[RLIM_NLIMITS]; - - rcu_read_lock(); - if (!lock_task_sighand(task,&flags)) { - rcu_read_unlock(); - return 0; - } - memcpy(rlim, task->signal->rlim, sizeof(struct rlimit) * RLIM_NLIMITS); - unlock_task_sighand(task, &flags); - rcu_read_unlock(); - - /* - * print the file header - */ - count += sprintf(&bufptr[count], "%-25s %-20s %-20s %-10s\n", - "Limit", "Soft Limit", "Hard Limit", "Units"); - - for (i = 0; i < RLIM_NLIMITS; i++) { - if (rlim[i].rlim_cur == RLIM_INFINITY) - count += sprintf(&bufptr[count], "%-25s %-20s ", - lnames[i].name, "unlimited"); - else - count += sprintf(&bufptr[count], "%-25s %-20lu ", - lnames[i].name, rlim[i].rlim_cur); - - if (rlim[i].rlim_max == RLIM_INFINITY) - count += sprintf(&bufptr[count], "%-20s ", "unlimited"); - else - count += sprintf(&bufptr[count], "%-20lu ", - rlim[i].rlim_max); - - if (lnames[i].unit) - count += sprintf(&bufptr[count], "%-10s\n", - lnames[i].unit); - else - count += sprintf(&bufptr[count], "\n"); - } - - return count; -} - /************************************************************************/ /* Here the fs part begins */ /************************************************************************/ @@ -424,21 +349,18 @@ struct proc_mounts { static int mounts_open(struct inode *inode, struct file *file) { struct task_struct *task = get_proc_task(inode); - struct nsproxy *nsp; struct mnt_namespace *ns = NULL; struct proc_mounts *p; int ret = -EINVAL; if (task) { - rcu_read_lock(); - nsp = task_nsproxy(task); - if (nsp) { - ns = nsp->mnt_ns; + task_lock(task); + if (task->nsproxy) { + ns = task->nsproxy->mnt_ns; if (ns) get_mnt_ns(ns); } - rcu_read_unlock(); - + task_unlock(task); put_task_struct(task); } @@ -501,20 +423,16 @@ static int mountstats_open(struct inode *inode, struct file *file) if (!ret) { struct seq_file *m = file->private_data; - struct nsproxy *nsp; struct mnt_namespace *mnt_ns = NULL; struct task_struct *task = get_proc_task(inode); if (task) { - rcu_read_lock(); - nsp = task_nsproxy(task); - if (nsp) { - mnt_ns = nsp->mnt_ns; - if (mnt_ns) - get_mnt_ns(mnt_ns); - } - rcu_read_unlock(); - + task_lock(task); + if (task->nsproxy) + mnt_ns = task->nsproxy->mnt_ns; + if (mnt_ns) + get_mnt_ns(mnt_ns); + task_unlock(task); put_task_struct(task); } @@ -1519,7 +1437,7 @@ static int proc_readfd_common(struct file * filp, void * dirent, struct dentry *dentry = filp->f_path.dentry; struct inode *inode = dentry->d_inode; struct task_struct *p = get_proc_task(inode); - unsigned int fd, ino; + unsigned int fd, tid, ino; int retval; struct files_struct * files; struct fdtable *fdt; @@ -1528,6 +1446,7 @@ static int proc_readfd_common(struct file * filp, void * dirent, if (!p) goto out_no_task; retval = 0; + tid = p->pid; fd = filp->f_pos; switch (fd) { @@ -1762,6 +1681,7 @@ static int proc_pident_readdir(struct file *filp, const struct pid_entry *ents, unsigned int nents) { int i; + int pid; struct dentry *dentry = filp->f_path.dentry; struct inode *inode = dentry->d_inode; struct task_struct *task = get_proc_task(inode); @@ -1774,6 +1694,7 @@ static int proc_pident_readdir(struct file *filp, goto out_no_task; ret = 0; + pid = task->pid; i = filp->f_pos; switch (i) { case 0: @@ -2007,14 +1928,14 @@ static int proc_self_readlink(struct dentry *dentry, char __user *buffer, int buflen) { char tmp[PROC_NUMBUF]; - sprintf(tmp, "%d", task_tgid_vnr(current)); + sprintf(tmp, "%d", current->tgid); return vfs_readlink(dentry,buffer,buflen,tmp); } static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd) { char tmp[PROC_NUMBUF]; - sprintf(tmp, "%d", task_tgid_vnr(current)); + sprintf(tmp, "%d", current->tgid); return ERR_PTR(vfs_follow_link(nd,tmp)); } @@ -2180,7 +2101,6 @@ static const struct pid_entry tgid_base_stuff[] = { REG("environ", S_IRUSR, environ), INF("auxv", S_IRUSR, pid_auxv), INF("status", S_IRUGO, pid_status), - INF("limits", S_IRUSR, pid_limits), #ifdef CONFIG_SCHED_DEBUG REG("sched", S_IRUGO|S_IWUSR, pid_sched), #endif @@ -2210,11 +2130,8 @@ static const struct pid_entry tgid_base_stuff[] = { #ifdef CONFIG_SCHEDSTATS INF("schedstat", S_IRUGO, pid_schedstat), #endif -#ifdef CONFIG_PROC_PID_CPUSET +#ifdef CONFIG_CPUSETS REG("cpuset", S_IRUGO, cpuset), -#endif -#ifdef CONFIG_CGROUPS - REG("cgroup", S_IRUGO, cgroup), #endif INF("oom_score", S_IRUGO, oom_score), REG("oom_adj", S_IRUGO|S_IWUSR, oom_adjust), @@ -2276,27 +2193,27 @@ static const struct inode_operations proc_tgid_base_inode_operations = { * that no dcache entries will exist at process exit time it * just makes it very unlikely that any will persist. */ -static void proc_flush_task_mnt(struct vfsmount *mnt, pid_t pid, pid_t tgid) +void proc_flush_task(struct task_struct *task) { struct dentry *dentry, *leader, *dir; char buf[PROC_NUMBUF]; struct qstr name; name.name = buf; - name.len = snprintf(buf, sizeof(buf), "%d", pid); - dentry = d_hash_and_lookup(mnt->mnt_root, &name); + name.len = snprintf(buf, sizeof(buf), "%d", task->pid); + dentry = d_hash_and_lookup(proc_mnt->mnt_root, &name); if (dentry) { shrink_dcache_parent(dentry); d_drop(dentry); dput(dentry); } - if (tgid == 0) + if (thread_group_leader(task)) goto out; name.name = buf; - name.len = snprintf(buf, sizeof(buf), "%d", tgid); - leader = d_hash_and_lookup(mnt->mnt_root, &name); + name.len = snprintf(buf, sizeof(buf), "%d", task->tgid); + leader = d_hash_and_lookup(proc_mnt->mnt_root, &name); if (!leader) goto out; @@ -2307,7 +2224,7 @@ static void proc_flush_task_mnt(struct vfsmount *mnt, pid_t pid, pid_t tgid) goto out_put_leader; name.name = buf; - name.len = snprintf(buf, sizeof(buf), "%d", pid); + name.len = snprintf(buf, sizeof(buf), "%d", task->pid); dentry = d_hash_and_lookup(dir, &name); if (dentry) { shrink_dcache_parent(dentry); @@ -2322,36 +2239,6 @@ static void proc_flush_task_mnt(struct vfsmount *mnt, pid_t pid, pid_t tgid) return; } -/* - * when flushing dentries from proc one need to flush them from global - * proc (proc_mnt) and from all the namespaces' procs this task was seen - * in. this call is supposed to make all this job. - */ - -void proc_flush_task(struct task_struct *task) -{ - int i, leader; - struct pid *pid, *tgid; - struct upid *upid; - - leader = thread_group_leader(task); - proc_flush_task_mnt(proc_mnt, task->pid, leader ? task->tgid : 0); - pid = task_pid(task); - if (pid->level == 0) - return; - - tgid = task_tgid(task); - for (i = 1; i <= pid->level; i++) { - upid = &pid->numbers[i]; - proc_flush_task_mnt(upid->ns->proc_mnt, upid->nr, - leader ? 0 : tgid->numbers[i].nr); - } - - upid = &pid->numbers[pid->level]; - if (upid->nr == 1) - pid_ns_release_proc(upid->ns); -} - static struct dentry *proc_pid_instantiate(struct inode *dir, struct dentry * dentry, struct task_struct *task, const void *ptr) @@ -2387,7 +2274,6 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct struct dentry *result = ERR_PTR(-ENOENT); struct task_struct *task; unsigned tgid; - struct pid_namespace *ns; result = proc_base_lookup(dir, dentry); if (!IS_ERR(result) || PTR_ERR(result) != -ENOENT) @@ -2397,9 +2283,8 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct if (tgid == ~0U) goto out; - ns = dentry->d_sb->s_fs_info; rcu_read_lock(); - task = find_task_by_pid_ns(tgid, ns); + task = find_task_by_pid(tgid); if (task) get_task_struct(task); rcu_read_unlock(); @@ -2416,8 +2301,7 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct * Find the first task with tgid >= tgid * */ -static struct task_struct *next_tgid(unsigned int tgid, - struct pid_namespace *ns) +static struct task_struct *next_tgid(unsigned int tgid) { struct task_struct *task; struct pid *pid; @@ -2425,9 +2309,9 @@ static struct task_struct *next_tgid(unsigned int tgid, rcu_read_lock(); retry: task = NULL; - pid = find_ge_pid(tgid, ns); + pid = find_ge_pid(tgid); if (pid) { - tgid = pid_nr_ns(pid, ns) + 1; + tgid = pid->nr + 1; task = pid_task(pid, PIDTYPE_PID); /* What we to know is if the pid we have find is the * pid of a thread_group_leader. Testing for task @@ -2467,7 +2351,6 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir) struct task_struct *reaper = get_proc_task(filp->f_path.dentry->d_inode); struct task_struct *task; int tgid; - struct pid_namespace *ns; if (!reaper) goto out_no_task; @@ -2478,12 +2361,11 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir) goto out; } - ns = filp->f_dentry->d_sb->s_fs_info; tgid = filp->f_pos - TGID_OFFSET; - for (task = next_tgid(tgid, ns); + for (task = next_tgid(tgid); task; - put_task_struct(task), task = next_tgid(tgid + 1, ns)) { - tgid = task_pid_nr_ns(task, ns); + put_task_struct(task), task = next_tgid(tgid + 1)) { + tgid = task->pid; filp->f_pos = tgid + TGID_OFFSET; if (proc_pid_fill_cache(filp, dirent, filldir, task, tgid) < 0) { put_task_struct(task); @@ -2506,7 +2388,6 @@ static const struct pid_entry tid_base_stuff[] = { REG("environ", S_IRUSR, environ), INF("auxv", S_IRUSR, pid_auxv), INF("status", S_IRUGO, pid_status), - INF("limits", S_IRUSR, pid_limits), #ifdef CONFIG_SCHED_DEBUG REG("sched", S_IRUGO|S_IWUSR, pid_sched), #endif @@ -2535,11 +2416,8 @@ static const struct pid_entry tid_base_stuff[] = { #ifdef CONFIG_SCHEDSTATS INF("schedstat", S_IRUGO, pid_schedstat), #endif -#ifdef CONFIG_PROC_PID_CPUSET +#ifdef CONFIG_CPUSETS REG("cpuset", S_IRUGO, cpuset), -#endif -#ifdef CONFIG_CGROUPS - REG("cgroup", S_IRUGO, cgroup), #endif INF("oom_score", S_IRUGO, oom_score), REG("oom_adj", S_IRUGO|S_IWUSR, oom_adjust), @@ -2608,7 +2486,6 @@ static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry struct task_struct *task; struct task_struct *leader = get_proc_task(dir); unsigned tid; - struct pid_namespace *ns; if (!leader) goto out_no_task; @@ -2617,15 +2494,14 @@ static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry if (tid == ~0U) goto out; - ns = dentry->d_sb->s_fs_info; rcu_read_lock(); - task = find_task_by_pid_ns(tid, ns); + task = find_task_by_pid(tid); if (task) get_task_struct(task); rcu_read_unlock(); if (!task) goto out; - if (!same_thread_group(leader, task)) + if (leader->tgid != task->tgid) goto out_drop_task; result = proc_task_instantiate(dir, dentry, task, NULL); @@ -2650,14 +2526,14 @@ static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry * threads past it. */ static struct task_struct *first_tid(struct task_struct *leader, - int tid, int nr, struct pid_namespace *ns) + int tid, int nr) { struct task_struct *pos; rcu_read_lock(); /* Attempt to start with the pid of a thread */ if (tid && (nr > 0)) { - pos = find_task_by_pid_ns(tid, ns); + pos = find_task_by_pid(tid); if (pos && (pos->group_leader == leader)) goto found; } @@ -2726,7 +2602,6 @@ static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldi ino_t ino; int tid; unsigned long pos = filp->f_pos; /* avoiding "long long" filp->f_pos */ - struct pid_namespace *ns; task = get_proc_task(inode); if (!task) @@ -2760,13 +2635,12 @@ static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldi /* f_version caches the tgid value that the last readdir call couldn't * return. lseek aka telldir automagically resets f_version to 0. */ - ns = filp->f_dentry->d_sb->s_fs_info; tid = (int)filp->f_version; filp->f_version = 0; - for (task = first_tid(leader, tid, pos - 2, ns); + for (task = first_tid(leader, tid, pos - 2); task; task = next_tid(task), pos++) { - tid = task_pid_nr_ns(task, ns); + tid = task->pid; if (proc_task_fill_cache(filp, dirent, filldir, task, tid) < 0) { /* returning this tgid failed, save it as the first * pid for the next readir call */ diff --git a/trunk/fs/proc/inode.c b/trunk/fs/proc/inode.c index abe6a3f04368..99ca00485fc3 100644 --- a/trunk/fs/proc/inode.c +++ b/trunk/fs/proc/inode.c @@ -448,7 +448,7 @@ struct inode *proc_get_inode(struct super_block *sb, unsigned int ino, return NULL; } -int proc_fill_super(struct super_block *s) +int proc_fill_super(struct super_block *s, void *data, int silent) { struct inode * root_inode; diff --git a/trunk/fs/proc/proc_misc.c b/trunk/fs/proc/proc_misc.c index e0d064e9764e..d6dc72c78bc1 100644 --- a/trunk/fs/proc/proc_misc.c +++ b/trunk/fs/proc/proc_misc.c @@ -91,8 +91,7 @@ static int loadavg_read_proc(char *page, char **start, off_t off, LOAD_INT(a), LOAD_FRAC(a), LOAD_INT(b), LOAD_FRAC(b), LOAD_INT(c), LOAD_FRAC(c), - nr_running(), nr_threads, - task_active_pid_ns(current)->last_pid); + nr_running(), nr_threads, current->nsproxy->pid_ns->last_pid); return proc_calc_metrics(page, start, off, count, eof, len); } diff --git a/trunk/fs/proc/root.c b/trunk/fs/proc/root.c index ec9cb3b6c93b..cf3046638b09 100644 --- a/trunk/fs/proc/root.c +++ b/trunk/fs/proc/root.c @@ -18,90 +18,32 @@ #include #include #include -#include #include "internal.h" struct proc_dir_entry *proc_bus, *proc_root_fs, *proc_root_driver; -static int proc_test_super(struct super_block *sb, void *data) -{ - return sb->s_fs_info == data; -} - -static int proc_set_super(struct super_block *sb, void *data) -{ - struct pid_namespace *ns; - - ns = (struct pid_namespace *)data; - sb->s_fs_info = get_pid_ns(ns); - return set_anon_super(sb, NULL); -} - static int proc_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, void *data, struct vfsmount *mnt) { - int err; - struct super_block *sb; - struct pid_namespace *ns; - struct proc_inode *ei; - if (proc_mnt) { /* Seed the root directory with a pid so it doesn't need * to be special in base.c. I would do this earlier but * the only task alive when /proc is mounted the first time * is the init_task and it doesn't have any pids. */ + struct proc_inode *ei; ei = PROC_I(proc_mnt->mnt_sb->s_root->d_inode); if (!ei->pid) ei->pid = find_get_pid(1); } - - if (flags & MS_KERNMOUNT) - ns = (struct pid_namespace *)data; - else - ns = current->nsproxy->pid_ns; - - sb = sget(fs_type, proc_test_super, proc_set_super, ns); - if (IS_ERR(sb)) - return PTR_ERR(sb); - - if (!sb->s_root) { - sb->s_flags = flags; - err = proc_fill_super(sb); - if (err) { - up_write(&sb->s_umount); - deactivate_super(sb); - return err; - } - - ei = PROC_I(sb->s_root->d_inode); - if (!ei->pid) { - rcu_read_lock(); - ei->pid = get_pid(find_pid_ns(1, ns)); - rcu_read_unlock(); - } - - sb->s_flags |= MS_ACTIVE; - ns->proc_mnt = mnt; - } - - return simple_set_mnt(mnt, sb); -} - -static void proc_kill_sb(struct super_block *sb) -{ - struct pid_namespace *ns; - - ns = (struct pid_namespace *)sb->s_fs_info; - kill_anon_super(sb); - put_pid_ns(ns); + return get_sb_single(fs_type, flags, data, proc_fill_super, mnt); } static struct file_system_type proc_fs_type = { .name = "proc", .get_sb = proc_get_sb, - .kill_sb = proc_kill_sb, + .kill_sb = kill_anon_super, }; void __init proc_root_init(void) @@ -112,13 +54,12 @@ void __init proc_root_init(void) err = register_filesystem(&proc_fs_type); if (err) return; - proc_mnt = kern_mount_data(&proc_fs_type, &init_pid_ns); + proc_mnt = kern_mount(&proc_fs_type); err = PTR_ERR(proc_mnt); if (IS_ERR(proc_mnt)) { unregister_filesystem(&proc_fs_type); return; } - proc_misc_init(); proc_net_init(); @@ -212,22 +153,6 @@ struct proc_dir_entry proc_root = { .parent = &proc_root, }; -int pid_ns_prepare_proc(struct pid_namespace *ns) -{ - struct vfsmount *mnt; - - mnt = kern_mount_data(&proc_fs_type, ns); - if (IS_ERR(mnt)) - return PTR_ERR(mnt); - - return 0; -} - -void pid_ns_release_proc(struct pid_namespace *ns) -{ - mntput(ns->proc_mnt); -} - EXPORT_SYMBOL(proc_symlink); EXPORT_SYMBOL(proc_mkdir); EXPORT_SYMBOL(create_proc_entry); diff --git a/trunk/fs/reiserfs/bitmap.c b/trunk/fs/reiserfs/bitmap.c index 16b331dd9913..2a5dd34649b3 100644 --- a/trunk/fs/reiserfs/bitmap.c +++ b/trunk/fs/reiserfs/bitmap.c @@ -47,9 +47,7 @@ test_bit(_ALLOC_ ## optname , &SB_ALLOC_OPTS(s)) static inline void get_bit_address(struct super_block *s, - b_blocknr_t block, - unsigned int *bmap_nr, - unsigned int *offset) + b_blocknr_t block, int *bmap_nr, int *offset) { /* It is in the bitmap block number equal to the block * number divided by the number of bits in a block. */ @@ -58,10 +56,10 @@ static inline void get_bit_address(struct super_block *s, *offset = block & ((s->s_blocksize << 3) - 1); } +#ifdef CONFIG_REISERFS_CHECK int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value) { - unsigned int bmap, offset; - unsigned int bmap_count = reiserfs_bmap_count(s); + int bmap, offset; if (block == 0 || block >= SB_BLOCK_COUNT(s)) { reiserfs_warning(s, @@ -77,26 +75,25 @@ int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value) if (unlikely(test_bit(REISERFS_OLD_FORMAT, &(REISERFS_SB(s)->s_properties)))) { b_blocknr_t bmap1 = REISERFS_SB(s)->s_sbh->b_blocknr + 1; - if (block >= bmap1 && - block <= bmap1 + bmap_count) { + if (block >= bmap1 && block <= bmap1 + SB_BMAP_NR(s)) { reiserfs_warning(s, "vs: 4019: is_reusable: " "bitmap block %lu(%u) can't be freed or reused", - block, bmap_count); + block, SB_BMAP_NR(s)); return 0; } } else { if (offset == 0) { reiserfs_warning(s, "vs: 4020: is_reusable: " "bitmap block %lu(%u) can't be freed or reused", - block, bmap_count); + block, SB_BMAP_NR(s)); return 0; } } - if (bmap >= bmap_count) { + if (bmap >= SB_BMAP_NR(s)) { reiserfs_warning(s, "vs-4030: is_reusable: there is no so many bitmap blocks: " - "block=%lu, bitmap_nr=%u", block, bmap); + "block=%lu, bitmap_nr=%d", block, bmap); return 0; } @@ -109,11 +106,12 @@ int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value) return 1; } +#endif /* CONFIG_REISERFS_CHECK */ /* searches in journal structures for a given block number (bmap, off). If block is found in reiserfs journal it suggests next free block candidate to test. */ -static inline int is_block_in_journal(struct super_block *s, unsigned int bmap, - int off, int *next) +static inline int is_block_in_journal(struct super_block *s, int bmap, int + off, int *next) { b_blocknr_t tmp; @@ -134,8 +132,8 @@ static inline int is_block_in_journal(struct super_block *s, unsigned int bmap, /* it searches for a window of zero bits with given minimum and maximum lengths in one bitmap * block; */ static int scan_bitmap_block(struct reiserfs_transaction_handle *th, - unsigned int bmap_n, int *beg, int boundary, - int min, int max, int unfm) + int bmap_n, int *beg, int boundary, int min, + int max, int unfm) { struct super_block *s = th->t_super; struct reiserfs_bitmap_info *bi = &SB_AP_BITMAP(s)[bmap_n]; @@ -145,8 +143,8 @@ static int scan_bitmap_block(struct reiserfs_transaction_handle *th, BUG_ON(!th->t_trans_id); - RFALSE(bmap_n >= reiserfs_bmap_count(s), "Bitmap %u is out of " - "range (0..%u)", bmap_n, reiserfs_bmap_count(s) - 1); + RFALSE(bmap_n >= SB_BMAP_NR(s), "Bitmap %d is out of range (0..%d)", + bmap_n, SB_BMAP_NR(s) - 1); PROC_INFO_INC(s, scan_bitmap.bmap); /* this is unclear and lacks comments, explain how journal bitmaps work here for the reader. Convey a sense of the design here. What @@ -251,12 +249,12 @@ static int bmap_hash_id(struct super_block *s, u32 id) } else { hash_in = (char *)(&id); hash = keyed_hash(hash_in, 4); - bm = hash % reiserfs_bmap_count(s); + bm = hash % SB_BMAP_NR(s); if (!bm) bm = 1; } /* this can only be true when SB_BMAP_NR = 1 */ - if (bm >= reiserfs_bmap_count(s)) + if (bm >= SB_BMAP_NR(s)) bm = 0; return bm; } @@ -275,7 +273,7 @@ static inline int block_group_used(struct super_block *s, u32 id) * to make a better decision. This favors long-term performace gain * with a better on-disk layout vs. a short term gain of skipping the * read and potentially having a bad placement. */ - if (info->free_count == UINT_MAX) { + if (info->first_zero_hint == 0) { struct buffer_head *bh = reiserfs_read_bitmap_block(s, bm); brelse(bh); } @@ -311,16 +309,16 @@ __le32 reiserfs_choose_packing(struct inode * dir) * bitmap and place new blocks there. Returns number of allocated blocks. */ static int scan_bitmap(struct reiserfs_transaction_handle *th, b_blocknr_t * start, b_blocknr_t finish, - int min, int max, int unfm, sector_t file_block) + int min, int max, int unfm, unsigned long file_block) { int nr_allocated = 0; struct super_block *s = th->t_super; /* find every bm and bmap and bmap_nr in this file, and change them all to bitmap_blocknr * - Hans, it is not a block number - Zam. */ - unsigned int bm, off; - unsigned int end_bm, end_off; - unsigned int off_max = s->s_blocksize << 3; + int bm, off; + int end_bm, end_off; + int off_max = s->s_blocksize << 3; BUG_ON(!th->t_trans_id); @@ -330,10 +328,10 @@ static int scan_bitmap(struct reiserfs_transaction_handle *th, get_bit_address(s, *start, &bm, &off); get_bit_address(s, finish, &end_bm, &end_off); - if (bm > reiserfs_bmap_count(s)) + if (bm > SB_BMAP_NR(s)) return 0; - if (end_bm > reiserfs_bmap_count(s)) - end_bm = reiserfs_bmap_count(s); + if (end_bm > SB_BMAP_NR(s)) + end_bm = SB_BMAP_NR(s); /* When the bitmap is more than 10% free, anyone can allocate. * When it's less than 10% free, only files that already use the @@ -387,7 +385,7 @@ static void _reiserfs_free_block(struct reiserfs_transaction_handle *th, struct reiserfs_super_block *rs; struct buffer_head *sbh, *bmbh; struct reiserfs_bitmap_info *apbi; - unsigned int nr, offset; + int nr, offset; BUG_ON(!th->t_trans_id); @@ -399,12 +397,10 @@ static void _reiserfs_free_block(struct reiserfs_transaction_handle *th, get_bit_address(s, block, &nr, &offset); - if (nr >= reiserfs_bmap_count(s)) { + if (nr >= sb_bmap_nr(rs)) { reiserfs_warning(s, "vs-4075: reiserfs_free_block: " - "block %lu is out of range on %s " - "(nr=%u,max=%u)", block, - reiserfs_bdevname(s), nr, - reiserfs_bmap_count(s)); + "block %lu is out of range on %s", + block, reiserfs_bdevname(s)); return; } @@ -438,19 +434,12 @@ void reiserfs_free_block(struct reiserfs_transaction_handle *th, int for_unformatted) { struct super_block *s = th->t_super; + BUG_ON(!th->t_trans_id); RFALSE(!s, "vs-4061: trying to free block on nonexistent device"); - if (!is_reusable(s, block, 1)) - return; - - if (block > sb_block_count(REISERFS_SB(s)->s_rs)) { - reiserfs_panic(th->t_super, "bitmap-4072", - "Trying to free block outside file system " - "boundaries (%lu > %lu)", - block, sb_block_count(REISERFS_SB(s)->s_rs)); - return; - } + RFALSE(is_reusable(s, block, 1) == 0, + "vs-4071: can not free such block"); /* mark it before we clear it, just in case */ journal_mark_freed(th, s, block); _reiserfs_free_block(th, inode, block, for_unformatted); @@ -460,11 +449,11 @@ void reiserfs_free_block(struct reiserfs_transaction_handle *th, static void reiserfs_free_prealloc_block(struct reiserfs_transaction_handle *th, struct inode *inode, b_blocknr_t block) { - BUG_ON(!th->t_trans_id); RFALSE(!th->t_super, "vs-4060: trying to free block on nonexistent device"); - if (!is_reusable(th->t_super, block, 1)) - return; + RFALSE(is_reusable(th->t_super, block, 1) == 0, + "vs-4070: can not free such block"); + BUG_ON(!th->t_trans_id); _reiserfs_free_block(th, inode, block, 1); } @@ -1218,22 +1207,27 @@ void reiserfs_cache_bitmap_metadata(struct super_block *sb, { unsigned long *cur = (unsigned long *)(bh->b_data + bh->b_size); - /* The first bit must ALWAYS be 1 */ - BUG_ON(!reiserfs_test_le_bit(0, (unsigned long *)bh->b_data)); - - info->free_count = 0; + info->first_zero_hint = 1 << (sb->s_blocksize_bits + 3); while (--cur >= (unsigned long *)bh->b_data) { - int i; + int base = ((char *)cur - bh->b_data) << 3; /* 0 and ~0 are special, we can optimize for them */ - if (*cur == 0) + if (*cur == 0) { + info->first_zero_hint = base; info->free_count += BITS_PER_LONG; - else if (*cur != ~0L) /* A mix, investigate */ - for (i = BITS_PER_LONG - 1; i >= 0; i--) - if (!reiserfs_test_le_bit(i, cur)) + } else if (*cur != ~0L) { /* A mix, investigate */ + int b; + for (b = BITS_PER_LONG - 1; b >= 0; b--) { + if (!reiserfs_test_le_bit(b, cur)) { + info->first_zero_hint = base + b; info->free_count++; + } + } + } } + /* The first bit must ALWAYS be 1 */ + BUG_ON(info->first_zero_hint == 0); } struct buffer_head *reiserfs_read_bitmap_block(struct super_block *sb, @@ -1263,7 +1257,7 @@ struct buffer_head *reiserfs_read_bitmap_block(struct super_block *sb, BUG_ON(!buffer_uptodate(bh)); BUG_ON(atomic_read(&bh->b_count) == 0); - if (info->free_count == UINT_MAX) + if (info->first_zero_hint == 0) reiserfs_cache_bitmap_metadata(sb, bh, info); } @@ -1273,13 +1267,12 @@ struct buffer_head *reiserfs_read_bitmap_block(struct super_block *sb, int reiserfs_init_bitmap_cache(struct super_block *sb) { struct reiserfs_bitmap_info *bitmap; - unsigned int bmap_nr = reiserfs_bmap_count(sb); - bitmap = vmalloc(sizeof(*bitmap) * bmap_nr); + bitmap = vmalloc(sizeof (*bitmap) * SB_BMAP_NR(sb)); if (bitmap == NULL) return -ENOMEM; - memset(bitmap, 0xff, sizeof(*bitmap) * bmap_nr); + memset(bitmap, 0, sizeof (*bitmap) * SB_BMAP_NR(sb)); SB_AP_BITMAP(sb) = bitmap; diff --git a/trunk/fs/reiserfs/inode.c b/trunk/fs/reiserfs/inode.c index a991af96f3f0..9ea12004fa57 100644 --- a/trunk/fs/reiserfs/inode.c +++ b/trunk/fs/reiserfs/inode.c @@ -199,7 +199,7 @@ static inline void set_block_dev_mapped(struct buffer_head *bh, // files which were created in the earlier version can not be longer, // than 2 gb // -static int file_capable(struct inode *inode, sector_t block) +static int file_capable(struct inode *inode, long block) { if (get_inode_item_key_version(inode) != KEY_FORMAT_3_5 || // it is new file. block < (1 << (31 - inode->i_sb->s_blocksize_bits))) // old file, but 'block' is inside of 2gb @@ -242,7 +242,7 @@ static int restart_transaction(struct reiserfs_transaction_handle *th, // Please improve the english/clarity in the comment above, as it is // hard to understand. -static int _get_block_create_0(struct inode *inode, sector_t block, +static int _get_block_create_0(struct inode *inode, long block, struct buffer_head *bh_result, int args) { INITIALIZE_PATH(path); @@ -250,7 +250,7 @@ static int _get_block_create_0(struct inode *inode, sector_t block, struct buffer_head *bh; struct item_head *ih, tmp_ih; int fs_gen; - b_blocknr_t blocknr; + int blocknr; char *p = NULL; int chars; int ret; @@ -569,7 +569,7 @@ static int convert_tail_for_hole(struct inode *inode, } static inline int _allocate_block(struct reiserfs_transaction_handle *th, - sector_t block, + long block, struct inode *inode, b_blocknr_t * allocated_block_nr, struct treepath *path, int flags) @@ -3061,11 +3061,7 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr) { struct inode *inode = dentry->d_inode; int error; - unsigned int ia_valid; - - /* must be turned off for recursive notify_change calls */ - ia_valid = attr->ia_valid &= ~(ATTR_KILL_SUID|ATTR_KILL_SGID); - + unsigned int ia_valid = attr->ia_valid; reiserfs_write_lock(inode->i_sb); if (attr->ia_valid & ATTR_SIZE) { /* version 2 items will be caught by the s_maxbytes check diff --git a/trunk/fs/reiserfs/journal.c b/trunk/fs/reiserfs/journal.c index bb05a3e51b93..4cad9e75ef56 100644 --- a/trunk/fs/reiserfs/journal.c +++ b/trunk/fs/reiserfs/journal.c @@ -219,12 +219,11 @@ static void allocate_bitmap_nodes(struct super_block *p_s_sb) } } -static int set_bit_in_list_bitmap(struct super_block *p_s_sb, - b_blocknr_t block, +static int set_bit_in_list_bitmap(struct super_block *p_s_sb, int block, struct reiserfs_list_bitmap *jb) { - unsigned int bmap_nr = block / (p_s_sb->s_blocksize << 3); - unsigned int bit_nr = block % (p_s_sb->s_blocksize << 3); + int bmap_nr = block / (p_s_sb->s_blocksize << 3); + int bit_nr = block % (p_s_sb->s_blocksize << 3); if (!jb->bitmaps[bmap_nr]) { jb->bitmaps[bmap_nr] = get_bitmap_node(p_s_sb); @@ -240,7 +239,7 @@ static void cleanup_bitmap_list(struct super_block *p_s_sb, if (jb->bitmaps == NULL) return; - for (i = 0; i < reiserfs_bmap_count(p_s_sb); i++) { + for (i = 0; i < SB_BMAP_NR(p_s_sb); i++) { if (jb->bitmaps[i]) { free_bitmap_node(p_s_sb, jb->bitmaps[i]); jb->bitmaps[i] = NULL; @@ -290,7 +289,7 @@ static int free_bitmap_nodes(struct super_block *p_s_sb) */ int reiserfs_allocate_list_bitmaps(struct super_block *p_s_sb, struct reiserfs_list_bitmap *jb_array, - unsigned int bmap_nr) + int bmap_nr) { int i; int failed = 0; @@ -484,7 +483,7 @@ static inline struct reiserfs_journal_cnode *get_journal_hash_dev(struct ** */ int reiserfs_in_journal(struct super_block *p_s_sb, - unsigned int bmap_nr, int bit_nr, int search_all, + int bmap_nr, int bit_nr, int search_all, b_blocknr_t * next_zero_bit) { struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb); @@ -1014,7 +1013,7 @@ static int flush_commit_list(struct super_block *s, struct reiserfs_journal_list *jl, int flushall) { int i; - b_blocknr_t bn; + int bn; struct buffer_head *tbh = NULL; unsigned long trans_id = jl->j_trans_id; struct reiserfs_journal *journal = SB_JOURNAL(s); @@ -2308,9 +2307,8 @@ static int journal_read_transaction(struct super_block *p_s_sb, Right now it is only used from journal code. But later we might use it from other places. Note: Do not use journal_getblk/sb_getblk functions here! */ -static struct buffer_head *reiserfs_breada(struct block_device *dev, - b_blocknr_t block, int bufsize, - b_blocknr_t max_block) +static struct buffer_head *reiserfs_breada(struct block_device *dev, int block, + int bufsize, unsigned int max_block) { struct buffer_head *bhlist[BUFNR]; unsigned int blocks = BUFNR; @@ -2734,7 +2732,7 @@ int journal_init(struct super_block *p_s_sb, const char *j_dev_name, journal->j_persistent_trans = 0; if (reiserfs_allocate_list_bitmaps(p_s_sb, journal->j_list_bitmap, - reiserfs_bmap_count(p_s_sb))) + SB_BMAP_NR(p_s_sb))) goto free_and_return; allocate_bitmap_nodes(p_s_sb); @@ -2742,7 +2740,7 @@ int journal_init(struct super_block *p_s_sb, const char *j_dev_name, SB_JOURNAL_1st_RESERVED_BLOCK(p_s_sb) = (old_format ? REISERFS_OLD_DISK_OFFSET_IN_BYTES / p_s_sb->s_blocksize + - reiserfs_bmap_count(p_s_sb) + + SB_BMAP_NR(p_s_sb) + 1 : REISERFS_DISK_OFFSET_IN_BYTES / p_s_sb->s_blocksize + 2); diff --git a/trunk/fs/reiserfs/prints.c b/trunk/fs/reiserfs/prints.c index 5e7388b32d02..bc808a91eeaa 100644 --- a/trunk/fs/reiserfs/prints.c +++ b/trunk/fs/reiserfs/prints.c @@ -356,11 +356,13 @@ extern struct tree_balance *cur_tb; void reiserfs_panic(struct super_block *sb, const char *fmt, ...) { do_reiserfs_warning(fmt); - - dump_stack(); - - panic(KERN_EMERG "REISERFS: panic (device %s): %s\n", + printk(KERN_EMERG "REISERFS: panic (device %s): %s\n", reiserfs_bdevname(sb), error_buf); + BUG(); + + /* this is not actually called, but makes reiserfs_panic() "noreturn" */ + panic("REISERFS: panic (device %s): %s\n", + reiserfs_bdevname(sb), error_buf); } void reiserfs_abort(struct super_block *sb, int errno, const char *fmt, ...) diff --git a/trunk/fs/reiserfs/resize.c b/trunk/fs/reiserfs/resize.c index f71c3948edef..976cc7887a0d 100644 --- a/trunk/fs/reiserfs/resize.c +++ b/trunk/fs/reiserfs/resize.c @@ -61,8 +61,7 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new) } /* count used bits in last bitmap block */ - block_r = SB_BLOCK_COUNT(s) - - (reiserfs_bmap_count(s) - 1) * s->s_blocksize * 8; + block_r = SB_BLOCK_COUNT(s) - (SB_BMAP_NR(s) - 1) * s->s_blocksize * 8; /* count bitmap blocks in new fs */ bmap_nr_new = block_count_new / (s->s_blocksize * 8); @@ -74,7 +73,7 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new) /* save old values */ block_count = SB_BLOCK_COUNT(s); - bmap_nr = reiserfs_bmap_count(s); + bmap_nr = SB_BMAP_NR(s); /* resizing of reiserfs bitmaps (journal and real), if needed */ if (bmap_nr_new > bmap_nr) { @@ -120,7 +119,7 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new) return -ENOMEM; } memset(bitmap, 0, - sizeof(struct reiserfs_bitmap_info) * bmap_nr_new); + sizeof(struct reiserfs_bitmap_info) * SB_BMAP_NR(s)); for (i = 0; i < bmap_nr; i++) bitmap[i] = old_bitmap[i]; @@ -144,6 +143,7 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new) mark_buffer_dirty(bh); sync_dirty_buffer(bh); // update bitmap_info stuff + bitmap[i].first_zero_hint = 1; bitmap[i].free_count = sb_blocksize(sb) * 8 - 1; brelse(bh); } @@ -173,6 +173,8 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new) for (i = block_r; i < s->s_blocksize * 8; i++) reiserfs_test_and_clear_le_bit(i, bh->b_data); info->free_count += s->s_blocksize * 8 - block_r; + if (!info->first_zero_hint) + info->first_zero_hint = block_r; journal_mark_dirty(&th, s, bh); brelse(bh); @@ -194,6 +196,9 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new) brelse(bh); info->free_count -= s->s_blocksize * 8 - block_r_new; + /* Extreme case where last bitmap is the only valid block in itself. */ + if (!info->free_count) + info->first_zero_hint = 0; /* update super */ reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1); free_blocks = SB_FREE_BLOCKS(s); @@ -201,7 +206,7 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new) free_blocks + (block_count_new - block_count - (bmap_nr_new - bmap_nr))); PUT_SB_BLOCK_COUNT(s, block_count_new); - PUT_SB_BMAP_NR(s, bmap_would_wrap(bmap_nr_new) ? : bmap_nr_new); + PUT_SB_BMAP_NR(s, bmap_nr_new); s->s_dirt = 1; journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB(s)); diff --git a/trunk/fs/reiserfs/stree.c b/trunk/fs/reiserfs/stree.c index ca41567d7890..981027d1187b 100644 --- a/trunk/fs/reiserfs/stree.c +++ b/trunk/fs/reiserfs/stree.c @@ -559,7 +559,7 @@ static int is_tree_node(struct buffer_head *bh, int level) /* The function is NOT SCHEDULE-SAFE! */ static void search_by_key_reada(struct super_block *s, struct buffer_head **bh, - b_blocknr_t *b, int num) + unsigned long *b, int num) { int i, j; @@ -611,7 +611,7 @@ int search_by_key(struct super_block *p_s_sb, const struct cpu_key *p_s_key, /* DISK_LEAF_NODE_LEVEL */ ) { - b_blocknr_t n_block_number; + int n_block_number; int expected_level; struct buffer_head *p_s_bh; struct path_element *p_s_last_element; @@ -619,7 +619,7 @@ int search_by_key(struct super_block *p_s_sb, const struct cpu_key *p_s_key, /* int right_neighbor_of_leaf_node; int fs_gen; struct buffer_head *reada_bh[SEARCH_BY_KEY_READA]; - b_blocknr_t reada_blocks[SEARCH_BY_KEY_READA]; + unsigned long reada_blocks[SEARCH_BY_KEY_READA]; int reada_count = 0; #ifdef CONFIG_REISERFS_CHECK diff --git a/trunk/fs/reiserfs/super.c b/trunk/fs/reiserfs/super.c index 57adfe90d5ae..b82897ae090b 100644 --- a/trunk/fs/reiserfs/super.c +++ b/trunk/fs/reiserfs/super.c @@ -1725,21 +1725,6 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent) set_sb_umount_state(rs, REISERFS_ERROR_FS); set_sb_fs_state(rs, 0); - /* Clear out s_bmap_nr if it would wrap. We can handle this - * case, but older revisions can't. This will cause the - * file system to fail mount on those older implementations, - * avoiding corruption. -jeffm */ - if (bmap_would_wrap(reiserfs_bmap_count(s)) && - sb_bmap_nr(rs) != 0) { - reiserfs_warning(s, "super-2030: This file system " - "claims to use %u bitmap blocks in " - "its super block, but requires %u. " - "Clearing to zero.", sb_bmap_nr(rs), - reiserfs_bmap_count(s)); - - set_sb_bmap_nr(rs, 0); - } - if (old_format_only(s)) { /* filesystem of format 3.5 either with standard or non-standard journal */ diff --git a/trunk/fs/reiserfs/xattr.c b/trunk/fs/reiserfs/xattr.c index 1597f6b649e0..fab4b9b2664f 100644 --- a/trunk/fs/reiserfs/xattr.c +++ b/trunk/fs/reiserfs/xattr.c @@ -484,7 +484,7 @@ reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer, /* Resize it so we're ok to write there */ newattrs.ia_size = buffer_size; newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME; - mutex_lock_nested(&xinode->i_mutex, I_MUTEX_XATTR); + mutex_lock(&xinode->i_mutex); err = notify_change(fp->f_path.dentry, &newattrs); if (err) goto out_filp; @@ -1223,8 +1223,7 @@ int reiserfs_xattr_init(struct super_block *s, int mount_flags) if (!IS_ERR(dentry)) { if (!(mount_flags & MS_RDONLY) && !dentry->d_inode) { struct inode *inode = dentry->d_parent->d_inode; - mutex_lock_nested(&inode->i_mutex, - I_MUTEX_XATTR); + mutex_lock(&inode->i_mutex); err = inode->i_op->mkdir(inode, dentry, 0700); mutex_unlock(&inode->i_mutex); if (err) { diff --git a/trunk/fs/select.c b/trunk/fs/select.c index 47f47925aea2..7dede89658f5 100644 --- a/trunk/fs/select.c +++ b/trunk/fs/select.c @@ -177,6 +177,11 @@ static int max_select_fd(unsigned long n, fd_set_bits *fds) return max; } +#define BIT(i) (1UL << ((i)&(__NFDBITS-1))) +#define MEM(i,m) ((m)+(unsigned)(i)/__NFDBITS) +#define ISSET(i,m) (((i)&*(m)) != 0) +#define SET(i,m) (*(m) |= (i)) + #define POLLIN_SET (POLLRDNORM | POLLRDBAND | POLLIN | POLLHUP | POLLERR) #define POLLOUT_SET (POLLWRBAND | POLLWRNORM | POLLOUT | POLLERR) #define POLLEX_SET (POLLPRI) diff --git a/trunk/fs/super.c b/trunk/fs/super.c index d28fde7e1cfb..1bfcca2104be 100644 --- a/trunk/fs/super.c +++ b/trunk/fs/super.c @@ -40,6 +40,10 @@ #include +void get_filesystem(struct file_system_type *fs); +void put_filesystem(struct file_system_type *fs); +struct file_system_type *get_fs_type(const char *name); + LIST_HEAD(super_blocks); DEFINE_SPINLOCK(sb_lock); @@ -332,21 +336,21 @@ struct super_block *sget(struct file_system_type *type, void *data) { struct super_block *s = NULL; - struct super_block *old; + struct list_head *p; int err; retry: spin_lock(&sb_lock); - if (test) { - list_for_each_entry(old, &type->fs_supers, s_instances) { - if (!test(old, data)) - continue; - if (!grab_super(old)) - goto retry; - if (s) - destroy_super(s); - return old; - } + if (test) list_for_each(p, &type->fs_supers) { + struct super_block *old; + old = list_entry(p, struct super_block, s_instances); + if (!test(old, data)) + continue; + if (!grab_super(old)) + goto retry; + if (s) + destroy_super(s); + return old; } if (!s) { spin_unlock(&sb_lock); @@ -944,9 +948,9 @@ do_kern_mount(const char *fstype, int flags, const char *name, void *data) return mnt; } -struct vfsmount *kern_mount_data(struct file_system_type *type, void *data) +struct vfsmount *kern_mount(struct file_system_type *type) { - return vfs_kern_mount(type, MS_KERNMOUNT, type->name, data); + return vfs_kern_mount(type, 0, type->name, NULL); } -EXPORT_SYMBOL_GPL(kern_mount_data); +EXPORT_SYMBOL(kern_mount); diff --git a/trunk/fs/xfs/linux-2.6/xfs_export.c b/trunk/fs/xfs/linux-2.6/xfs_export.c index 3586c7a28d2c..726449d4fd22 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_export.c +++ b/trunk/fs/xfs/linux-2.6/xfs_export.c @@ -54,8 +54,8 @@ xfs_fs_decode_fh( struct dentry *de), void *context) { - xfs_fid_t ifid; - xfs_fid_t pfid; + xfs_fid2_t ifid; + xfs_fid2_t pfid; void *parent = NULL; int is64 = 0; __u32 *p = fh; @@ -144,7 +144,7 @@ xfs_fs_get_dentry( struct dentry *result; int error; - error = xfs_vget(XFS_M(sb), &vp, data); + error = xfs_vget(XFS_M(sb), &vp, (fid_t *)data); if (error || vp == NULL) return ERR_PTR(-ESTALE) ; diff --git a/trunk/fs/xfs/linux-2.6/xfs_export.h b/trunk/fs/xfs/linux-2.6/xfs_export.h index 2f36071a86f7..e794ca4efc76 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_export.h +++ b/trunk/fs/xfs/linux-2.6/xfs_export.h @@ -71,13 +71,13 @@ xfs_fileid_length(int hasparent, int is64) /* * Decode encoded inode information (either for the inode itself - * or the parent) into an xfs_fid_t structure. Advances and + * or the parent) into an xfs_fid2_t structure. Advances and * returns the new data pointer */ static inline __u32 * -xfs_fileid_decode_fid2(__u32 *p, xfs_fid_t *fid, int is64) +xfs_fileid_decode_fid2(__u32 *p, xfs_fid2_t *fid, int is64) { - fid->fid_len = sizeof(xfs_fid_t) - sizeof(fid->fid_len); + fid->fid_len = sizeof(xfs_fid2_t) - sizeof(fid->fid_len); fid->fid_pad = 0; fid->fid_ino = *p++; #if XFS_BIG_INUMS diff --git a/trunk/fs/xfs/linux-2.6/xfs_ioctl.c b/trunk/fs/xfs/linux-2.6/xfs_ioctl.c index 2b34bad48b07..ffec630e7db7 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_ioctl.c +++ b/trunk/fs/xfs/linux-2.6/xfs_ioctl.c @@ -152,11 +152,11 @@ xfs_find_handle( lock_mode = xfs_ilock_map_shared(ip); /* fill in fid section of handle from inode */ - handle.ha_fid.fid_len = sizeof(xfs_fid_t) - - sizeof(handle.ha_fid.fid_len); - handle.ha_fid.fid_pad = 0; - handle.ha_fid.fid_gen = ip->i_d.di_gen; - handle.ha_fid.fid_ino = ip->i_ino; + handle.ha_fid.xfs_fid_len = sizeof(xfs_fid_t) - + sizeof(handle.ha_fid.xfs_fid_len); + handle.ha_fid.xfs_fid_pad = 0; + handle.ha_fid.xfs_fid_gen = ip->i_d.di_gen; + handle.ha_fid.xfs_fid_ino = ip->i_ino; xfs_iunlock_map_shared(ip, lock_mode); @@ -222,10 +222,10 @@ xfs_vget_fsop_handlereq( if (hlen < sizeof(*handlep)) memset(((char *)handlep) + hlen, 0, sizeof(*handlep) - hlen); if (hlen > sizeof(handlep->ha_fsid)) { - if (handlep->ha_fid.fid_len != - (hlen - sizeof(handlep->ha_fsid) - - sizeof(handlep->ha_fid.fid_len)) || - handlep->ha_fid.fid_pad) + if (handlep->ha_fid.xfs_fid_len != + (hlen - sizeof(handlep->ha_fsid) + - sizeof(handlep->ha_fid.xfs_fid_len)) + || handlep->ha_fid.xfs_fid_pad) return XFS_ERROR(EINVAL); } @@ -233,9 +233,9 @@ xfs_vget_fsop_handlereq( * Crack the handle, obtain the inode # & generation # */ xfid = (struct xfs_fid *)&handlep->ha_fid; - if (xfid->fid_len == sizeof(*xfid) - sizeof(xfid->fid_len)) { - ino = xfid->fid_ino; - igen = xfid->fid_gen; + if (xfid->xfs_fid_len == sizeof(*xfid) - sizeof(xfid->xfs_fid_len)) { + ino = xfid->xfs_fid_ino; + igen = xfid->xfs_fid_gen; } else { return XFS_ERROR(EINVAL); } diff --git a/trunk/fs/xfs/xfs_dmops.c b/trunk/fs/xfs/xfs_dmops.c index a1e55fb9d5dd..6cd5704258a2 100644 --- a/trunk/fs/xfs/xfs_dmops.c +++ b/trunk/fs/xfs/xfs_dmops.c @@ -41,16 +41,29 @@ int xfs_dmops_get(struct xfs_mount *mp, struct xfs_mount_args *args) { if (args->flags & XFSMNT_DMAPI) { - cmn_err(CE_WARN, - "XFS: dmapi support not available in this kernel."); - return EINVAL; + struct xfs_dmops *ops; + + ops = symbol_get(xfs_dmcore_xfs); + if (!ops) { + request_module("xfs_dmapi"); + ops = symbol_get(xfs_dmcore_xfs); + } + + if (!ops) { + cmn_err(CE_WARN, "XFS: no dmapi support available."); + return EINVAL; + } + mp->m_dm_ops = ops; + } else { + mp->m_dm_ops = &xfs_dmcore_stub; } - mp->m_dm_ops = &xfs_dmcore_stub; return 0; } void xfs_dmops_put(struct xfs_mount *mp) { + if (mp->m_dm_ops != &xfs_dmcore_stub) + symbol_put(xfs_dmcore_xfs); } diff --git a/trunk/fs/xfs/xfs_fs.h b/trunk/fs/xfs/xfs_fs.h index aab966276517..ec3c9c27e0de 100644 --- a/trunk/fs/xfs/xfs_fs.h +++ b/trunk/fs/xfs/xfs_fs.h @@ -389,13 +389,30 @@ typedef struct xfs_fsop_attrmulti_handlereq { */ typedef struct { __u32 val[2]; } xfs_fsid_t; /* file system id type */ + +#ifndef HAVE_FID +#define MAXFIDSZ 46 + +typedef struct fid { + __u16 fid_len; /* length of data in bytes */ + unsigned char fid_data[MAXFIDSZ]; /* data (fid_len worth) */ +} fid_t; +#endif + typedef struct xfs_fid { - __u16 fid_len; /* length of remainder */ - __u16 fid_pad; - __u32 fid_gen; /* generation number */ - __u64 fid_ino; /* 64 bits inode number */ + __u16 xfs_fid_len; /* length of remainder */ + __u16 xfs_fid_pad; + __u32 xfs_fid_gen; /* generation number */ + __u64 xfs_fid_ino; /* 64 bits inode number */ } xfs_fid_t; +typedef struct xfs_fid2 { + __u16 fid_len; /* length of remainder */ + __u16 fid_pad; /* padding, must be zero */ + __u32 fid_gen; /* generation number */ + __u64 fid_ino; /* inode number */ +} xfs_fid2_t; + typedef struct xfs_handle { union { __s64 align; /* force alignment of ha_fid */ @@ -405,9 +422,9 @@ typedef struct xfs_handle { } xfs_handle_t; #define ha_fsid ha_u._ha_fsid -#define XFS_HSIZE(handle) (((char *) &(handle).ha_fid.fid_pad \ +#define XFS_HSIZE(handle) (((char *) &(handle).ha_fid.xfs_fid_pad \ - (char *) &(handle)) \ - + (handle).ha_fid.fid_len) + + (handle).ha_fid.xfs_fid_len) /* * Flags for going down operation diff --git a/trunk/fs/xfs/xfs_qmops.c b/trunk/fs/xfs/xfs_qmops.c index 2ec1d8a27352..c266a0184b42 100644 --- a/trunk/fs/xfs/xfs_qmops.c +++ b/trunk/fs/xfs/xfs_qmops.c @@ -135,13 +135,19 @@ int xfs_qmops_get(struct xfs_mount *mp, struct xfs_mount_args *args) { if (args->flags & (XFSMNT_UQUOTA | XFSMNT_PQUOTA | XFSMNT_GQUOTA)) { -#ifdef CONFIG_XFS_QUOTA - mp->m_qm_ops = &xfs_qmcore_xfs; -#else - cmn_err(CE_WARN, - "XFS: qouta support not available in this kernel."); - return EINVAL; -#endif + struct xfs_qmops *ops; + + ops = symbol_get(xfs_qmcore_xfs); + if (!ops) { + request_module("xfs_quota"); + ops = symbol_get(xfs_qmcore_xfs); + } + + if (!ops) { + cmn_err(CE_WARN, "XFS: no quota support available."); + return EINVAL; + } + mp->m_qm_ops = ops; } else { mp->m_qm_ops = &xfs_qmcore_stub; } @@ -152,4 +158,6 @@ xfs_qmops_get(struct xfs_mount *mp, struct xfs_mount_args *args) void xfs_qmops_put(struct xfs_mount *mp) { + if (mp->m_qm_ops != &xfs_qmcore_stub) + symbol_put(xfs_qmcore_xfs); } diff --git a/trunk/fs/xfs/xfs_vfsops.c b/trunk/fs/xfs/xfs_vfsops.c index a1544597bcd3..a5a8454f2a63 100644 --- a/trunk/fs/xfs/xfs_vfsops.c +++ b/trunk/fs/xfs/xfs_vfsops.c @@ -1635,8 +1635,9 @@ int xfs_vget( xfs_mount_t *mp, bhv_vnode_t **vpp, - xfs_fid_t *xfid) + fid_t *fidp) { + xfs_fid_t *xfid = (struct xfs_fid *)fidp; xfs_inode_t *ip; int error; xfs_ino_t ino; @@ -1646,11 +1647,11 @@ xfs_vget( * Invalid. Since handles can be created in user space and passed in * via gethandle(), this is not cause for a panic. */ - if (xfid->fid_len != sizeof(*xfid) - sizeof(xfid->fid_len)) + if (xfid->xfs_fid_len != sizeof(*xfid) - sizeof(xfid->xfs_fid_len)) return XFS_ERROR(EINVAL); - ino = xfid->fid_ino; - igen = xfid->fid_gen; + ino = xfid->xfs_fid_ino; + igen = xfid->xfs_fid_gen; /* * NFS can sometimes send requests for ino 0. Fail them gracefully. diff --git a/trunk/fs/xfs/xfs_vfsops.h b/trunk/fs/xfs/xfs_vfsops.h index a592fe02a339..bc99e3eb7dbb 100644 --- a/trunk/fs/xfs/xfs_vfsops.h +++ b/trunk/fs/xfs/xfs_vfsops.h @@ -2,7 +2,7 @@ #define _XFS_VFSOPS_H 1 struct cred; -struct xfs_fid; +struct fid; struct inode; struct kstatfs; struct xfs_mount; @@ -17,7 +17,7 @@ int xfs_root(struct xfs_mount *mp, bhv_vnode_t **vpp); int xfs_statvfs(struct xfs_mount *mp, struct kstatfs *statp, bhv_vnode_t *vp); int xfs_sync(struct xfs_mount *mp, int flags); -int xfs_vget(struct xfs_mount *mp, bhv_vnode_t **vpp, struct xfs_fid *xfid); +int xfs_vget(struct xfs_mount *mp, bhv_vnode_t **vpp, struct fid *fidp); int xfs_parseargs(struct xfs_mount *mp, char *options, struct xfs_mount_args *args, int update); int xfs_showargs(struct xfs_mount *mp, struct seq_file *m); diff --git a/trunk/fs/xfs/xfs_vnodeops.c b/trunk/fs/xfs/xfs_vnodeops.c index efd5aff9eaf6..5e3c57ca9981 100644 --- a/trunk/fs/xfs/xfs_vnodeops.c +++ b/trunk/fs/xfs/xfs_vnodeops.c @@ -3466,14 +3466,23 @@ xfs_symlink( } +/* + * xfs_fid2 + * + * A fid routine that takes a pointer to a previously allocated + * fid structure (like xfs_fast_fid) but uses a 64 bit inode number. + */ int xfs_fid2( xfs_inode_t *ip, - xfs_fid_t *xfid) + fid_t *fidp) { + xfs_fid2_t *xfid = (xfs_fid2_t *)fidp; + vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address); + ASSERT(sizeof(fid_t) >= sizeof(xfs_fid2_t)); - xfid->fid_len = sizeof(xfs_fid_t) - sizeof(xfid->fid_len); + xfid->fid_len = sizeof(xfs_fid2_t) - sizeof(xfid->fid_len); xfid->fid_pad = 0; /* * use memcpy because the inode is a long long and there's no diff --git a/trunk/fs/xfs/xfs_vnodeops.h b/trunk/fs/xfs/xfs_vnodeops.h index b7e461c40cfb..f36e74f2f0c2 100644 --- a/trunk/fs/xfs/xfs_vnodeops.h +++ b/trunk/fs/xfs/xfs_vnodeops.h @@ -39,7 +39,7 @@ int xfs_readdir(struct xfs_inode *dp, void *dirent, size_t bufsize, int xfs_symlink(struct xfs_inode *dp, bhv_vname_t *dentry, char *target_path, mode_t mode, bhv_vnode_t **vpp, struct cred *credp); -int xfs_fid2(struct xfs_inode *ip, struct xfs_fid *xfid); +int xfs_fid2(struct xfs_inode *ip, fid_t *fidp); int xfs_rwlock(struct xfs_inode *ip, bhv_vrwlock_t locktype); void xfs_rwunlock(struct xfs_inode *ip, bhv_vrwlock_t locktype); int xfs_inode_flush(struct xfs_inode *ip, int flags); diff --git a/trunk/include/acpi/achware.h b/trunk/include/acpi/achware.h index 4053df943453..9df275cf7bc1 100644 --- a/trunk/include/acpi/achware.h +++ b/trunk/include/acpi/achware.h @@ -71,9 +71,9 @@ u32 acpi_hw_get_mode(void); struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id); acpi_status -acpi_hw_register_read(u32 register_id, u32 * return_value); +acpi_hw_register_read(u8 use_lock, u32 register_id, u32 * return_value); -acpi_status acpi_hw_register_write(u32 register_id, u32 value); +acpi_status acpi_hw_register_write(u8 use_lock, u32 register_id, u32 value); acpi_status acpi_hw_low_level_read(u32 width, diff --git a/trunk/include/acpi/acpi_bus.h b/trunk/include/acpi/acpi_bus.h index 7b74b60a68a4..86aea44ce6d4 100644 --- a/trunk/include/acpi/acpi_bus.h +++ b/trunk/include/acpi/acpi_bus.h @@ -264,6 +264,7 @@ struct acpi_device_wakeup_flags { struct acpi_device_wakeup_state { u8 enabled:1; + u8 active:1; }; struct acpi_device_wakeup { @@ -332,7 +333,6 @@ int acpi_bus_get_power(acpi_handle handle, int *state); int acpi_bus_set_power(acpi_handle handle, int state); #ifdef CONFIG_ACPI_PROC_EVENT int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data); -int acpi_bus_generate_proc_event4(const char *class, const char *bid, u8 type, int data); int acpi_bus_receive_event(struct acpi_bus_event *event); #else static inline int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data) diff --git a/trunk/include/acpi/acpixf.h b/trunk/include/acpi/acpixf.h index 9512f0456ad1..3d7ab9e0c9fe 100644 --- a/trunk/include/acpi/acpixf.h +++ b/trunk/include/acpi/acpixf.h @@ -314,8 +314,6 @@ acpi_resource_to_address64(struct acpi_resource *resource, */ acpi_status acpi_get_register(u32 register_id, u32 * return_value); -acpi_status acpi_get_register_unlocked(u32 register_id, u32 *return_value); - acpi_status acpi_set_register(u32 register_id, u32 value); acpi_status diff --git a/trunk/include/acpi/processor.h b/trunk/include/acpi/processor.h index 26d79f6db8a0..99934a999e66 100644 --- a/trunk/include/acpi/processor.h +++ b/trunk/include/acpi/processor.h @@ -3,7 +3,6 @@ #include #include -#include #include @@ -76,9 +75,7 @@ struct acpi_processor_cx { }; struct acpi_processor_power { - struct cpuidle_device dev; struct acpi_processor_cx *state; - struct acpi_processor_cx *bm_state; unsigned long bm_check_timestamp; u32 default_state; u32 bm_activity; @@ -202,7 +199,6 @@ struct acpi_processor_flags { u8 bm_check:1; u8 has_cst:1; u8 power_setup_done:1; - u8 bm_rld_set:1; }; struct acpi_processor { @@ -326,7 +322,6 @@ int acpi_processor_power_exit(struct acpi_processor *pr, struct acpi_device *device); int acpi_processor_suspend(struct acpi_device * device, pm_message_t state); int acpi_processor_resume(struct acpi_device * device); -extern struct cpuidle_driver acpi_idle_driver; /* in processor_thermal.c */ int acpi_processor_get_limit_info(struct acpi_processor *pr); diff --git a/trunk/include/asm-alpha/bitops.h b/trunk/include/asm-alpha/bitops.h index 9e19a704d484..9e71201000d5 100644 --- a/trunk/include/asm-alpha/bitops.h +++ b/trunk/include/asm-alpha/bitops.h @@ -1,12 +1,7 @@ #ifndef _ALPHA_BITOPS_H #define _ALPHA_BITOPS_H -#ifndef _LINUX_BITOPS_H -#error only can be included directly -#endif - #include -#include /* * Copyright 1994, Linus Torvalds. @@ -74,13 +69,6 @@ clear_bit(unsigned long nr, volatile void * addr) :"Ir" (1UL << (nr & 31)), "m" (*m)); } -static inline void -clear_bit_unlock(unsigned long nr, volatile void * addr) -{ - smp_mb(); - clear_bit(nr, addr); -} - /* * WARNING: non atomic version. */ @@ -92,13 +80,6 @@ __clear_bit(unsigned long nr, volatile void * addr) *m &= ~(1 << (nr & 31)); } -static inline void -__clear_bit_unlock(unsigned long nr, volatile void * addr) -{ - smp_mb(); - __clear_bit(nr, addr); -} - static inline void change_bit(unsigned long nr, volatile void * addr) { @@ -135,36 +116,6 @@ test_and_set_bit(unsigned long nr, volatile void *addr) unsigned long temp; int *m = ((int *) addr) + (nr >> 5); - __asm__ __volatile__( -#ifdef CONFIG_SMP - " mb\n" -#endif - "1: ldl_l %0,%4\n" - " and %0,%3,%2\n" - " bne %2,2f\n" - " xor %0,%3,%0\n" - " stl_c %0,%1\n" - " beq %0,3f\n" - "2:\n" -#ifdef CONFIG_SMP - " mb\n" -#endif - ".subsection 2\n" - "3: br 1b\n" - ".previous" - :"=&r" (temp), "=m" (*m), "=&r" (oldbit) - :"Ir" (1UL << (nr & 31)), "m" (*m) : "memory"); - - return oldbit != 0; -} - -static inline int -test_and_set_bit_lock(unsigned long nr, volatile void *addr) -{ - unsigned long oldbit; - unsigned long temp; - int *m = ((int *) addr) + (nr >> 5); - __asm__ __volatile__( "1: ldl_l %0,%4\n" " and %0,%3,%2\n" @@ -207,9 +158,6 @@ test_and_clear_bit(unsigned long nr, volatile void * addr) int *m = ((int *) addr) + (nr >> 5); __asm__ __volatile__( -#ifdef CONFIG_SMP - " mb\n" -#endif "1: ldl_l %0,%4\n" " and %0,%3,%2\n" " beq %2,2f\n" @@ -251,9 +199,6 @@ test_and_change_bit(unsigned long nr, volatile void * addr) int *m = ((int *) addr) + (nr >> 5); __asm__ __volatile__( -#ifdef CONFIG_SMP - " mb\n" -#endif "1: ldl_l %0,%4\n" " and %0,%3,%2\n" " xor %0,%3,%0\n" diff --git a/trunk/include/asm-alpha/tlbflush.h b/trunk/include/asm-alpha/tlbflush.h index eefab3fb51ae..1ca3ed3bd6d3 100644 --- a/trunk/include/asm-alpha/tlbflush.h +++ b/trunk/include/asm-alpha/tlbflush.h @@ -92,6 +92,17 @@ flush_tlb_other(struct mm_struct *mm) if (*mmc) *mmc = 0; } +/* Flush a specified range of user mapping page tables from TLB. + Although Alpha uses VPTE caches, this can be a nop, as Alpha does + not have finegrained tlb flushing, so it will flush VPTE stuff + during next flush_tlb_range. */ + +static inline void +flush_tlb_pgtables(struct mm_struct *mm, unsigned long start, + unsigned long end) +{ +} + #ifndef CONFIG_SMP /* Flush everything (kernel mapping may also have changed due to vmalloc/vfree). */ diff --git a/trunk/include/asm-arm/arch-ixp4xx/io.h b/trunk/include/asm-arm/arch-ixp4xx/io.h index eeeea90cd5a9..c72f9d79417c 100644 --- a/trunk/include/asm-arm/arch-ixp4xx/io.h +++ b/trunk/include/asm-arm/arch-ixp4xx/io.h @@ -17,6 +17,9 @@ #define IO_SPACE_LIMIT 0xffff0000 +#define BIT(x) ((1)<<(x)) + + extern int (*ixp4xx_pci_read)(u32 addr, u32 cmd, u32* data); extern int ixp4xx_pci_write(u32 addr, u32 cmd, u32 data); diff --git a/trunk/include/asm-arm/arch-pxa/pm.h b/trunk/include/asm-arm/arch-pxa/pm.h index 9d9f4b54b2ce..6903db7fae15 100644 --- a/trunk/include/asm-arm/arch-pxa/pm.h +++ b/trunk/include/asm-arm/arch-pxa/pm.h @@ -7,8 +7,6 @@ * */ -#include - struct pxa_cpu_pm_fns { int save_size; void (*save)(unsigned long *); diff --git a/trunk/include/asm-arm/bitops.h b/trunk/include/asm-arm/bitops.h index 47a6b086eee2..b41831b6432f 100644 --- a/trunk/include/asm-arm/bitops.h +++ b/trunk/include/asm-arm/bitops.h @@ -19,10 +19,6 @@ #ifdef __KERNEL__ -#ifndef _LINUX_BITOPS_H -#error only can be included directly -#endif - #include #include @@ -290,7 +286,6 @@ static inline int constant_fls(int x) #include #include -#include /* * Ext2 is defined to use little-endian byte ordering. diff --git a/trunk/include/asm-arm/tlbflush.h b/trunk/include/asm-arm/tlbflush.h index 8c6bc1bb9d1a..71be4fded7e2 100644 --- a/trunk/include/asm-arm/tlbflush.h +++ b/trunk/include/asm-arm/tlbflush.h @@ -463,6 +463,11 @@ extern void flush_tlb_kernel_range(unsigned long start, unsigned long end); */ extern void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte); +/* + * ARM processors do not cache TLB tables in RAM. + */ +#define flush_tlb_pgtables(mm,start,end) do { } while (0) + #endif #endif /* CONFIG_MMU */ diff --git a/trunk/include/asm-avr32/bitops.h b/trunk/include/asm-avr32/bitops.h index 1a50b69b1a19..5299f8c8e11d 100644 --- a/trunk/include/asm-avr32/bitops.h +++ b/trunk/include/asm-avr32/bitops.h @@ -8,10 +8,6 @@ #ifndef __ASM_AVR32_BITOPS_H #define __ASM_AVR32_BITOPS_H -#ifndef _LINUX_BITOPS_H -#error only can be included directly -#endif - #include #include @@ -292,7 +288,6 @@ static inline int ffs(unsigned long word) #include #include #include -#include #include #include diff --git a/trunk/include/asm-avr32/tlbflush.h b/trunk/include/asm-avr32/tlbflush.h index 5bc7c88a5770..730e268f81f3 100644 --- a/trunk/include/asm-avr32/tlbflush.h +++ b/trunk/include/asm-avr32/tlbflush.h @@ -19,6 +19,7 @@ * - flush_tlb_page(vma, vmaddr) flushes one page * - flush_tlb_range(vma, start, end) flushes a range of pages * - flush_tlb_kernel_range(start, end) flushes a range of kernel pages + * - flush_tlb_pgtables(mm, start, end) flushes a range of page tables */ extern void flush_tlb(void); extern void flush_tlb_all(void); @@ -28,6 +29,12 @@ extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long page); extern void __flush_tlb_page(unsigned long asid, unsigned long page); +static inline void flush_tlb_pgtables(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ + /* Nothing to do */ +} + extern void flush_tlb_kernel_range(unsigned long start, unsigned long end); #endif /* __ASM_AVR32_TLBFLUSH_H */ diff --git a/trunk/include/asm-blackfin/bitops.h b/trunk/include/asm-blackfin/bitops.h index b39a175c79c1..27c2d0e48e1b 100644 --- a/trunk/include/asm-blackfin/bitops.h +++ b/trunk/include/asm-blackfin/bitops.h @@ -11,10 +11,6 @@ #ifdef __KERNEL__ -#ifndef _LINUX_BITOPS_H -#error only can be included directly -#endif - #include #include #include @@ -203,7 +199,6 @@ static __inline__ int __test_bit(int nr, const void *addr) #include #include -#include #include #include diff --git a/trunk/include/asm-blackfin/processor.h b/trunk/include/asm-blackfin/processor.h index c571e958558c..6bb3e0d4705d 100644 --- a/trunk/include/asm-blackfin/processor.h +++ b/trunk/include/asm-blackfin/processor.h @@ -104,13 +104,13 @@ unsigned long get_wchan(struct task_struct *p); #define cpu_relax() barrier() /* Get the Silicon Revision of the chip */ -static inline uint32_t __pure bfin_revid(void) +static inline __attribute_pure__ uint32_t bfin_revid(void) { /* stored in the upper 4 bits */ return bfin_read_CHIPID() >> 28; } -static inline uint32_t __pure bfin_compiled_revid(void) +static inline __attribute_pure__ uint32_t bfin_compiled_revid(void) { #if defined(CONFIG_BF_REV_0_0) return 0; diff --git a/trunk/include/asm-blackfin/tlbflush.h b/trunk/include/asm-blackfin/tlbflush.h index 277b400924b8..10a07ba1e011 100644 --- a/trunk/include/asm-blackfin/tlbflush.h +++ b/trunk/include/asm-blackfin/tlbflush.h @@ -53,4 +53,10 @@ static inline void flush_tlb_kernel_page(unsigned long addr) BUG(); } +static inline void flush_tlb_pgtables(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ + BUG(); +} + #endif diff --git a/trunk/include/asm-cris/bitops.h b/trunk/include/asm-cris/bitops.h index e2f49c27ed29..a569065113d9 100644 --- a/trunk/include/asm-cris/bitops.h +++ b/trunk/include/asm-cris/bitops.h @@ -14,10 +14,6 @@ /* Currently this is unsuitable for consumption outside the kernel. */ #ifdef __KERNEL__ -#ifndef _LINUX_BITOPS_H -#error only can be included directly -#endif - #include #include #include @@ -158,7 +154,6 @@ static inline int test_and_change_bit(int nr, volatile unsigned long *addr) #include #include #include -#include #include diff --git a/trunk/include/asm-cris/posix_types.h b/trunk/include/asm-cris/posix_types.h index 92000d0c3f97..7b9ed22ab5dd 100644 --- a/trunk/include/asm-cris/posix_types.h +++ b/trunk/include/asm-cris/posix_types.h @@ -52,7 +52,7 @@ typedef struct { } __kernel_fsid_t; #ifdef __KERNEL__ -#include +#include #undef __FD_SET #define __FD_SET(fd,fdsetp) set_bit(fd, (void *)(fdsetp)) diff --git a/trunk/include/asm-cris/tlbflush.h b/trunk/include/asm-cris/tlbflush.h index 20697e7ef4f2..0569612477e3 100644 --- a/trunk/include/asm-cris/tlbflush.h +++ b/trunk/include/asm-cris/tlbflush.h @@ -38,6 +38,13 @@ static inline void flush_tlb_range(struct vm_area_struct * vma, unsigned long st flush_tlb_mm(vma->vm_mm); } +static inline void flush_tlb_pgtables(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ + /* CRIS does not keep any page table caches in TLB */ +} + + static inline void flush_tlb(void) { flush_tlb_mm(current->mm); diff --git a/trunk/include/asm-frv/bitops.h b/trunk/include/asm-frv/bitops.h index e29de7131b79..f8560edf59ff 100644 --- a/trunk/include/asm-frv/bitops.h +++ b/trunk/include/asm-frv/bitops.h @@ -21,10 +21,6 @@ #ifdef __KERNEL__ -#ifndef _LINUX_BITOPS_H -#error only can be included directly -#endif - #include /* @@ -306,7 +302,6 @@ int __ilog2_u64(u64 n) #include #include -#include #include diff --git a/trunk/include/asm-frv/tlbflush.h b/trunk/include/asm-frv/tlbflush.h index 7ac5eafc5d98..8370f97e41ee 100644 --- a/trunk/include/asm-frv/tlbflush.h +++ b/trunk/include/asm-frv/tlbflush.h @@ -57,6 +57,7 @@ do { \ #define __flush_tlb_global() flush_tlb_all() #define flush_tlb() flush_tlb_all() #define flush_tlb_kernel_range(start, end) flush_tlb_all() +#define flush_tlb_pgtables(mm,start,end) do { } while(0) #else @@ -65,6 +66,7 @@ do { \ #define flush_tlb_mm(mm) BUG() #define flush_tlb_page(vma,addr) BUG() #define flush_tlb_range(mm,start,end) BUG() +#define flush_tlb_pgtables(mm,start,end) BUG() #define flush_tlb_kernel_range(start, end) BUG() #endif diff --git a/trunk/include/asm-generic/bitops.h b/trunk/include/asm-generic/bitops.h index 15e6f253dda4..1f9d99193df8 100644 --- a/trunk/include/asm-generic/bitops.h +++ b/trunk/include/asm-generic/bitops.h @@ -19,14 +19,9 @@ #ifdef __KERNEL__ -#ifndef _LINUX_BITOPS_H -#error only can be included directly -#endif - #include #include #include -#include #include #include diff --git a/trunk/include/asm-generic/bitops/atomic.h b/trunk/include/asm-generic/bitops/atomic.h index 4657f3e410fc..cd8a9641bd66 100644 --- a/trunk/include/asm-generic/bitops/atomic.h +++ b/trunk/include/asm-generic/bitops/atomic.h @@ -3,6 +3,9 @@ #include +#define BITOP_MASK(nr) (1UL << ((nr) % BITS_PER_LONG)) +#define BITOP_WORD(nr) ((nr) / BITS_PER_LONG) + #ifdef CONFIG_SMP #include #include /* we use L1_CACHE_BYTES */ @@ -63,8 +66,8 @@ extern raw_spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned; */ static inline void set_bit(int nr, volatile unsigned long *addr) { - unsigned long mask = BIT_MASK(nr); - unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); + unsigned long mask = BITOP_MASK(nr); + unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr); unsigned long flags; _atomic_spin_lock_irqsave(p, flags); @@ -84,8 +87,8 @@ static inline void set_bit(int nr, volatile unsigned long *addr) */ static inline void clear_bit(int nr, volatile unsigned long *addr) { - unsigned long mask = BIT_MASK(nr); - unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); + unsigned long mask = BITOP_MASK(nr); + unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr); unsigned long flags; _atomic_spin_lock_irqsave(p, flags); @@ -105,8 +108,8 @@ static inline void clear_bit(int nr, volatile unsigned long *addr) */ static inline void change_bit(int nr, volatile unsigned long *addr) { - unsigned long mask = BIT_MASK(nr); - unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); + unsigned long mask = BITOP_MASK(nr); + unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr); unsigned long flags; _atomic_spin_lock_irqsave(p, flags); @@ -125,8 +128,8 @@ static inline void change_bit(int nr, volatile unsigned long *addr) */ static inline int test_and_set_bit(int nr, volatile unsigned long *addr) { - unsigned long mask = BIT_MASK(nr); - unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); + unsigned long mask = BITOP_MASK(nr); + unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr); unsigned long old; unsigned long flags; @@ -149,8 +152,8 @@ static inline int test_and_set_bit(int nr, volatile unsigned long *addr) */ static inline int test_and_clear_bit(int nr, volatile unsigned long *addr) { - unsigned long mask = BIT_MASK(nr); - unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); + unsigned long mask = BITOP_MASK(nr); + unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr); unsigned long old; unsigned long flags; @@ -172,8 +175,8 @@ static inline int test_and_clear_bit(int nr, volatile unsigned long *addr) */ static inline int test_and_change_bit(int nr, volatile unsigned long *addr) { - unsigned long mask = BIT_MASK(nr); - unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); + unsigned long mask = BITOP_MASK(nr); + unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr); unsigned long old; unsigned long flags; diff --git a/trunk/include/asm-generic/bitops/lock.h b/trunk/include/asm-generic/bitops/lock.h deleted file mode 100644 index 308a9e22c802..000000000000 --- a/trunk/include/asm-generic/bitops/lock.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef _ASM_GENERIC_BITOPS_LOCK_H_ -#define _ASM_GENERIC_BITOPS_LOCK_H_ - -/** - * test_and_set_bit_lock - Set a bit and return its old value, for lock - * @nr: Bit to set - * @addr: Address to count from - * - * This operation is atomic and provides acquire barrier semantics. - * It can be used to implement bit locks. - */ -#define test_and_set_bit_lock(nr, addr) test_and_set_bit(nr, addr) - -/** - * clear_bit_unlock - Clear a bit in memory, for unlock - * @nr: the bit to set - * @addr: the address to start counting from - * - * This operation is atomic and provides release barrier semantics. - */ -#define clear_bit_unlock(nr, addr) \ -do { \ - smp_mb__before_clear_bit(); \ - clear_bit(nr, addr); \ -} while (0) - -/** - * __clear_bit_unlock - Clear a bit in memory, for unlock - * @nr: the bit to set - * @addr: the address to start counting from - * - * This operation is like clear_bit_unlock, however it is not atomic. - * It does provide release barrier semantics so it can be used to unlock - * a bit lock, however it would only be used if no other CPU can modify - * any bits in the memory until the lock is released (a good example is - * if the bit lock itself protects access to the other bits in the word). - */ -#define __clear_bit_unlock(nr, addr) \ -do { \ - smp_mb(); \ - __clear_bit(nr, addr); \ -} while (0) - -#endif /* _ASM_GENERIC_BITOPS_LOCK_H_ */ - diff --git a/trunk/include/asm-generic/bitops/non-atomic.h b/trunk/include/asm-generic/bitops/non-atomic.h index 697cc2b7e0f0..46a825cf2ae1 100644 --- a/trunk/include/asm-generic/bitops/non-atomic.h +++ b/trunk/include/asm-generic/bitops/non-atomic.h @@ -3,6 +3,9 @@ #include +#define BITOP_MASK(nr) (1UL << ((nr) % BITS_PER_LONG)) +#define BITOP_WORD(nr) ((nr) / BITS_PER_LONG) + /** * __set_bit - Set a bit in memory * @nr: the bit to set @@ -14,16 +17,16 @@ */ static inline void __set_bit(int nr, volatile unsigned long *addr) { - unsigned long mask = BIT_MASK(nr); - unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); + unsigned long mask = BITOP_MASK(nr); + unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr); *p |= mask; } static inline void __clear_bit(int nr, volatile unsigned long *addr) { - unsigned long mask = BIT_MASK(nr); - unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); + unsigned long mask = BITOP_MASK(nr); + unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr); *p &= ~mask; } @@ -39,8 +42,8 @@ static inline void __clear_bit(int nr, volatile unsigned long *addr) */ static inline void __change_bit(int nr, volatile unsigned long *addr) { - unsigned long mask = BIT_MASK(nr); - unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); + unsigned long mask = BITOP_MASK(nr); + unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr); *p ^= mask; } @@ -56,8 +59,8 @@ static inline void __change_bit(int nr, volatile unsigned long *addr) */ static inline int __test_and_set_bit(int nr, volatile unsigned long *addr) { - unsigned long mask = BIT_MASK(nr); - unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); + unsigned long mask = BITOP_MASK(nr); + unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr); unsigned long old = *p; *p = old | mask; @@ -75,8 +78,8 @@ static inline int __test_and_set_bit(int nr, volatile unsigned long *addr) */ static inline int __test_and_clear_bit(int nr, volatile unsigned long *addr) { - unsigned long mask = BIT_MASK(nr); - unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); + unsigned long mask = BITOP_MASK(nr); + unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr); unsigned long old = *p; *p = old & ~mask; @@ -87,8 +90,8 @@ static inline int __test_and_clear_bit(int nr, volatile unsigned long *addr) static inline int __test_and_change_bit(int nr, volatile unsigned long *addr) { - unsigned long mask = BIT_MASK(nr); - unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); + unsigned long mask = BITOP_MASK(nr); + unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr); unsigned long old = *p; *p = old ^ mask; @@ -102,7 +105,7 @@ static inline int __test_and_change_bit(int nr, */ static inline int test_bit(int nr, const volatile unsigned long *addr) { - return 1UL & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1))); + return 1UL & (addr[BITOP_WORD(nr)] >> (nr & (BITS_PER_LONG-1))); } #endif /* _ASM_GENERIC_BITOPS_NON_ATOMIC_H_ */ diff --git a/trunk/include/asm-generic/vmlinux.lds.h b/trunk/include/asm-generic/vmlinux.lds.h index 9f584cc5c5fb..5615440027ec 100644 --- a/trunk/include/asm-generic/vmlinux.lds.h +++ b/trunk/include/asm-generic/vmlinux.lds.h @@ -12,11 +12,7 @@ /* .data section */ #define DATA_DATA \ *(.data) \ - *(.data.init.refok) \ - . = ALIGN(8); \ - VMLINUX_SYMBOL(__start___markers) = .; \ - *(__markers) \ - VMLINUX_SYMBOL(__stop___markers) = .; + *(.data.init.refok) #define RO_DATA(align) \ . = ALIGN((align)); \ @@ -24,7 +20,6 @@ VMLINUX_SYMBOL(__start_rodata) = .; \ *(.rodata) *(.rodata.*) \ *(__vermagic) /* Kernel version magic */ \ - *(__markers_strings) /* Markers: strings */ \ } \ \ .rodata1 : AT(ADDR(.rodata1) - LOAD_OFFSET) { \ diff --git a/trunk/include/asm-h8300/bitops.h b/trunk/include/asm-h8300/bitops.h index cb18e3b0aa94..d76299c98b81 100644 --- a/trunk/include/asm-h8300/bitops.h +++ b/trunk/include/asm-h8300/bitops.h @@ -10,11 +10,6 @@ #include #ifdef __KERNEL__ - -#ifndef _LINUX_BITOPS_H -#error only can be included directly -#endif - /* * Function prototypes to keep gcc -Wall happy */ @@ -199,7 +194,6 @@ static __inline__ unsigned long __ffs(unsigned long word) #include #include #include -#include #include #include #include diff --git a/trunk/include/asm-h8300/tlbflush.h b/trunk/include/asm-h8300/tlbflush.h index 41c148a9208e..9a2c5c9fd700 100644 --- a/trunk/include/asm-h8300/tlbflush.h +++ b/trunk/include/asm-h8300/tlbflush.h @@ -52,4 +52,10 @@ static inline void flush_tlb_kernel_page(unsigned long addr) BUG(); } +static inline void flush_tlb_pgtables(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ + BUG(); +} + #endif /* _H8300_TLBFLUSH_H */ diff --git a/trunk/include/asm-ia64/bitops.h b/trunk/include/asm-ia64/bitops.h index a977affaebec..6cc517e212a9 100644 --- a/trunk/include/asm-ia64/bitops.h +++ b/trunk/include/asm-ia64/bitops.h @@ -9,10 +9,6 @@ * O(1) scheduler patch */ -#ifndef _LINUX_BITOPS_H -#error only can be included directly -#endif - #include #include #include @@ -97,38 +93,6 @@ clear_bit (int nr, volatile void *addr) } while (cmpxchg_acq(m, old, new) != old); } -/** - * clear_bit_unlock - Clears a bit in memory with release - * @nr: Bit to clear - * @addr: Address to start counting from - * - * clear_bit_unlock() is atomic and may not be reordered. It does - * contain a memory barrier suitable for unlock type operations. - */ -static __inline__ void -clear_bit_unlock (int nr, volatile void *addr) -{ - __u32 mask, old, new; - volatile __u32 *m; - CMPXCHG_BUGCHECK_DECL - - m = (volatile __u32 *) addr + (nr >> 5); - mask = ~(1 << (nr & 31)); - do { - CMPXCHG_BUGCHECK(m); - old = *m; - new = old & mask; - } while (cmpxchg_rel(m, old, new) != old); -} - -/** - * __clear_bit_unlock - Non-atomically clear a bit with release - * - * This is like clear_bit_unlock, but the implementation may use a non-atomic - * store (this one uses an atomic, however). - */ -#define __clear_bit_unlock clear_bit_unlock - /** * __clear_bit - Clears a bit in memory (non-atomic version) */ @@ -205,15 +169,6 @@ test_and_set_bit (int nr, volatile void *addr) return (old & bit) != 0; } -/** - * test_and_set_bit_lock - Set a bit and return its old value for lock - * @nr: Bit to set - * @addr: Address to count from - * - * This is the same as test_and_set_bit on ia64 - */ -#define test_and_set_bit_lock test_and_set_bit - /** * __test_and_set_bit - Set a bit and return its old value * @nr: Bit to set diff --git a/trunk/include/asm-ia64/cacheflush.h b/trunk/include/asm-ia64/cacheflush.h index afcfbda76e20..4906916d715b 100644 --- a/trunk/include/asm-ia64/cacheflush.h +++ b/trunk/include/asm-ia64/cacheflush.h @@ -7,8 +7,8 @@ */ #include -#include +#include #include /* diff --git a/trunk/include/asm-ia64/meminit.h b/trunk/include/asm-ia64/meminit.h index f93308f54b61..3a62878e84f3 100644 --- a/trunk/include/asm-ia64/meminit.h +++ b/trunk/include/asm-ia64/meminit.h @@ -35,7 +35,7 @@ extern void find_memory (void); extern void reserve_memory (void); extern void find_initrd (void); extern int filter_rsvd_memory (unsigned long start, unsigned long end, void *arg); -extern unsigned long efi_memmap_init(unsigned long *s, unsigned long *e); +extern void efi_memmap_init(unsigned long *, unsigned long *); extern int find_max_min_low_pfn (unsigned long , unsigned long, void *); extern unsigned long vmcore_find_descriptor_size(unsigned long address); diff --git a/trunk/include/asm-ia64/pgtable.h b/trunk/include/asm-ia64/pgtable.h index e6204f14f614..0971ec90807e 100644 --- a/trunk/include/asm-ia64/pgtable.h +++ b/trunk/include/asm-ia64/pgtable.h @@ -150,7 +150,7 @@ # ifndef __ASSEMBLY__ #include /* for mm_struct */ -#include +#include #include #include #include diff --git a/trunk/include/asm-ia64/smp.h b/trunk/include/asm-ia64/smp.h index 471cc2ee9ac4..1703c9d885bd 100644 --- a/trunk/include/asm-ia64/smp.h +++ b/trunk/include/asm-ia64/smp.h @@ -14,8 +14,8 @@ #include #include #include -#include +#include #include #include #include diff --git a/trunk/include/asm-ia64/spinlock.h b/trunk/include/asm-ia64/spinlock.h index 0229fb95fb38..ff857e31738a 100644 --- a/trunk/include/asm-ia64/spinlock.h +++ b/trunk/include/asm-ia64/spinlock.h @@ -11,9 +11,9 @@ #include #include -#include #include +#include #include #include diff --git a/trunk/include/asm-ia64/tlbflush.h b/trunk/include/asm-ia64/tlbflush.h index 80bcb0a38e8a..e37f9fbf33af 100644 --- a/trunk/include/asm-ia64/tlbflush.h +++ b/trunk/include/asm-ia64/tlbflush.h @@ -83,6 +83,19 @@ flush_tlb_page (struct vm_area_struct *vma, unsigned long addr) #endif } +/* + * Flush the TLB entries mapping the virtually mapped linear page + * table corresponding to address range [START-END). + */ +static inline void +flush_tlb_pgtables (struct mm_struct *mm, unsigned long start, unsigned long end) +{ + /* + * Deprecated. The virtual page table is now flushed via the normal gather/flush + * interface (see tlb.h). + */ +} + /* * Flush the local TLB. Invoked from another cpu using an IPI. */ diff --git a/trunk/include/asm-m32r/bitops.h b/trunk/include/asm-m32r/bitops.h index 6dc9b81bf9f3..66ab672162cd 100644 --- a/trunk/include/asm-m32r/bitops.h +++ b/trunk/include/asm-m32r/bitops.h @@ -11,10 +11,6 @@ * Copyright (C) 2004 Hirokazu Takata */ -#ifndef _LINUX_BITOPS_H -#error only can be included directly -#endif - #include #include #include @@ -259,7 +255,6 @@ static __inline__ int test_and_change_bit(int nr, volatile void * addr) #include #include #include -#include #endif /* __KERNEL__ */ diff --git a/trunk/include/asm-m32r/pgtable.h b/trunk/include/asm-m32r/pgtable.h index 86505387be08..92d7266783fd 100644 --- a/trunk/include/asm-m32r/pgtable.h +++ b/trunk/include/asm-m32r/pgtable.h @@ -21,9 +21,9 @@ #ifndef __ASSEMBLY__ #include -#include #include #include +#include #include struct mm_struct; diff --git a/trunk/include/asm-m32r/tlbflush.h b/trunk/include/asm-m32r/tlbflush.h index 0ef95307784e..3d37ac002bcc 100644 --- a/trunk/include/asm-m32r/tlbflush.h +++ b/trunk/include/asm-m32r/tlbflush.h @@ -12,6 +12,7 @@ * - flush_tlb_page(vma, vmaddr) flushes one page * - flush_tlb_range(vma, start, end) flushes a range of pages * - flush_tlb_kernel_range(start, end) flushes a range of kernel pages + * - flush_tlb_pgtables(mm, start, end) flushes a range of page tables */ extern void local_flush_tlb_all(void); @@ -92,6 +93,8 @@ static __inline__ void __flush_tlb_all(void) ); } +#define flush_tlb_pgtables(mm, start, end) do { } while (0) + extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t); #endif /* _ASM_M32R_TLBFLUSH_H */ diff --git a/trunk/include/asm-m68k/bitops.h b/trunk/include/asm-m68k/bitops.h index 2976b5d68e96..1a61fdb56aaf 100644 --- a/trunk/include/asm-m68k/bitops.h +++ b/trunk/include/asm-m68k/bitops.h @@ -8,10 +8,6 @@ * for more details. */ -#ifndef _LINUX_BITOPS_H -#error only can be included directly -#endif - #include /* @@ -318,7 +314,6 @@ static inline int fls(int x) #include #include #include -#include /* Bitmap functions for the minix filesystem */ diff --git a/trunk/include/asm-m68k/tlbflush.h b/trunk/include/asm-m68k/tlbflush.h index 17707ec315e2..31678831ee47 100644 --- a/trunk/include/asm-m68k/tlbflush.h +++ b/trunk/include/asm-m68k/tlbflush.h @@ -92,6 +92,11 @@ static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end flush_tlb_all(); } +static inline void flush_tlb_pgtables(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ +} + #else @@ -214,6 +219,11 @@ static inline void flush_tlb_kernel_page (unsigned long addr) sun3_put_segmap (addr & ~(SUN3_PMEG_SIZE - 1), SUN3_INVALID_PMEG); } +static inline void flush_tlb_pgtables(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ +} + #endif #endif /* _M68K_TLBFLUSH_H */ diff --git a/trunk/include/asm-m68knommu/bitops.h b/trunk/include/asm-m68knommu/bitops.h index f8dfb7ba2e25..7d6075d9b5cb 100644 --- a/trunk/include/asm-m68knommu/bitops.h +++ b/trunk/include/asm-m68knommu/bitops.h @@ -10,10 +10,6 @@ #ifdef __KERNEL__ -#ifndef _LINUX_BITOPS_H -#error only can be included directly -#endif - #include #include #include @@ -164,7 +160,6 @@ static __inline__ int __test_bit(int nr, const volatile unsigned long * addr) #include #include -#include static __inline__ int ext2_set_bit(int nr, volatile void * addr) { diff --git a/trunk/include/asm-m68knommu/tlbflush.h b/trunk/include/asm-m68knommu/tlbflush.h index a470cfb803eb..de858db28b00 100644 --- a/trunk/include/asm-m68knommu/tlbflush.h +++ b/trunk/include/asm-m68knommu/tlbflush.h @@ -52,4 +52,10 @@ static inline void flush_tlb_kernel_page(unsigned long addr) BUG(); } +static inline void flush_tlb_pgtables(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ + BUG(); +} + #endif /* _M68KNOMMU_TLBFLUSH_H */ diff --git a/trunk/include/asm-mips/bitops.h b/trunk/include/asm-mips/bitops.h index ec75ce4cdb8c..899357a72ac4 100644 --- a/trunk/include/asm-mips/bitops.h +++ b/trunk/include/asm-mips/bitops.h @@ -9,10 +9,6 @@ #ifndef _ASM_BITOPS_H #define _ASM_BITOPS_H -#ifndef _LINUX_BITOPS_H -#error only can be included directly -#endif - #include #include #include @@ -175,20 +171,6 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) } } -/* - * clear_bit_unlock - Clears a bit in memory - * @nr: Bit to clear - * @addr: Address to start counting from - * - * clear_bit() is atomic and implies release semantics before the memory - * operation. It can be used for an unlock. - */ -static inline void clear_bit_unlock(unsigned long nr, volatile unsigned long *addr) -{ - smp_mb__before_clear_bit(); - clear_bit(nr, addr); -} - /* * change_bit - Toggle a bit in memory * @nr: Bit to change @@ -258,8 +240,6 @@ static inline int test_and_set_bit(unsigned long nr, unsigned short bit = nr & SZLONG_MASK; unsigned long res; - smp_llsc_mb(); - if (cpu_has_llsc && R10000_LLSC_WAR) { unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); unsigned long temp; @@ -314,73 +294,6 @@ static inline int test_and_set_bit(unsigned long nr, return res != 0; } -/* - * test_and_set_bit_lock - Set a bit and return its old value - * @nr: Bit to set - * @addr: Address to count from - * - * This operation is atomic and implies acquire ordering semantics - * after the memory operation. - */ -static inline int test_and_set_bit_lock(unsigned long nr, - volatile unsigned long *addr) -{ - unsigned short bit = nr & SZLONG_MASK; - unsigned long res; - - if (cpu_has_llsc && R10000_LLSC_WAR) { - unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); - unsigned long temp; - - __asm__ __volatile__( - " .set mips3 \n" - "1: " __LL "%0, %1 # test_and_set_bit \n" - " or %2, %0, %3 \n" - " " __SC "%2, %1 \n" - " beqzl %2, 1b \n" - " and %2, %0, %3 \n" - " .set mips0 \n" - : "=&r" (temp), "=m" (*m), "=&r" (res) - : "r" (1UL << bit), "m" (*m) - : "memory"); - } else if (cpu_has_llsc) { - unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); - unsigned long temp; - - __asm__ __volatile__( - " .set push \n" - " .set noreorder \n" - " .set mips3 \n" - "1: " __LL "%0, %1 # test_and_set_bit \n" - " or %2, %0, %3 \n" - " " __SC "%2, %1 \n" - " beqz %2, 2f \n" - " and %2, %0, %3 \n" - " .subsection 2 \n" - "2: b 1b \n" - " nop \n" - " .previous \n" - " .set pop \n" - : "=&r" (temp), "=m" (*m), "=&r" (res) - : "r" (1UL << bit), "m" (*m) - : "memory"); - } else { - volatile unsigned long *a = addr; - unsigned long mask; - unsigned long flags; - - a += nr >> SZLONG_LOG; - mask = 1UL << bit; - raw_local_irq_save(flags); - res = (mask & *a); - *a |= mask; - raw_local_irq_restore(flags); - } - - smp_llsc_mb(); - - return res != 0; -} /* * test_and_clear_bit - Clear a bit and return its old value * @nr: Bit to clear @@ -395,8 +308,6 @@ static inline int test_and_clear_bit(unsigned long nr, unsigned short bit = nr & SZLONG_MASK; unsigned long res; - smp_llsc_mb(); - if (cpu_has_llsc && R10000_LLSC_WAR) { unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); unsigned long temp; @@ -485,8 +396,6 @@ static inline int test_and_change_bit(unsigned long nr, unsigned short bit = nr & SZLONG_MASK; unsigned long res; - smp_llsc_mb(); - if (cpu_has_llsc && R10000_LLSC_WAR) { unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); unsigned long temp; @@ -543,21 +452,6 @@ static inline int test_and_change_bit(unsigned long nr, #include -/* - * __clear_bit_unlock - Clears a bit in memory - * @nr: Bit to clear - * @addr: Address to start counting from - * - * __clear_bit() is non-atomic and implies release semantics before the memory - * operation. It can be used for an unlock if no other CPUs can concurrently - * modify other bits in the word. - */ -static inline void __clear_bit_unlock(unsigned long nr, volatile unsigned long *addr) -{ - smp_mb(); - __clear_bit(nr, addr); -} - /* * Return the bit position (0..63) of the most significant 1 bit in a word * Returns -1 if no 1 bit exists diff --git a/trunk/include/asm-mips/fpu.h b/trunk/include/asm-mips/fpu.h index e59d4c039661..483685b1592e 100644 --- a/trunk/include/asm-mips/fpu.h +++ b/trunk/include/asm-mips/fpu.h @@ -12,12 +12,12 @@ #include #include -#include #include #include #include #include +#include #include #include diff --git a/trunk/include/asm-mips/ip32/crime.h b/trunk/include/asm-mips/ip32/crime.h index 7c36b0e5b1c6..a13702fafa85 100644 --- a/trunk/include/asm-mips/ip32/crime.h +++ b/trunk/include/asm-mips/ip32/crime.h @@ -17,6 +17,9 @@ */ #define CRIME_BASE 0x14000000 /* physical */ +#undef BIT +#define BIT(x) (1UL << (x)) + struct sgi_crime { volatile unsigned long id; #define CRIME_ID_MASK 0xff diff --git a/trunk/include/asm-mips/ip32/mace.h b/trunk/include/asm-mips/ip32/mace.h index d08d7c672139..990082c81f39 100644 --- a/trunk/include/asm-mips/ip32/mace.h +++ b/trunk/include/asm-mips/ip32/mace.h @@ -17,6 +17,9 @@ */ #define MACE_BASE 0x1f000000 /* physical */ +#undef BIT +#define BIT(x) (1UL << (x)) + /* * PCI interface */ diff --git a/trunk/include/asm-mips/mach-ip27/kernel-entry-init.h b/trunk/include/asm-mips/mach-ip27/kernel-entry-init.h index 624d66c7f290..c1a10314b317 100644 --- a/trunk/include/asm-mips/mach-ip27/kernel-entry-init.h +++ b/trunk/include/asm-mips/mach-ip27/kernel-entry-init.h @@ -46,14 +46,7 @@ lh t1, KV_RO_NASID_OFFSET(t0) lh t2, KV_RW_NASID_OFFSET(t0) MAPPED_KERNEL_SETUP_TLB - - /* - * We might not get launched at the address the kernel is linked to, - * so we jump there. - */ - PTR_LA t0, 0f - jr t0 -0: + ARC64_TWIDDLE_PC .endm #endif /* __ASM_MACH_IP27_KERNEL_ENTRY_H */ diff --git a/trunk/include/asm-mips/sni.h b/trunk/include/asm-mips/sni.h index af081457f847..4d43dbb7f8b8 100644 --- a/trunk/include/asm-mips/sni.h +++ b/trunk/include/asm-mips/sni.h @@ -141,6 +141,8 @@ extern unsigned int sni_brd_type; #define A20R_PT_TIM0_ACK 0xbc050000 #define A20R_PT_TIM1_ACK 0xbc060000 +#define SNI_MIPS_IRQ_CPU_TIMER (MIPS_CPU_IRQ_BASE+7) + #define SNI_A20R_IRQ_BASE MIPS_CPU_IRQ_BASE #define SNI_A20R_IRQ_TIMER (SNI_A20R_IRQ_BASE+5) diff --git a/trunk/include/asm-mips/time.h b/trunk/include/asm-mips/time.h index bc47af313bcd..35555bd5c52d 100644 --- a/trunk/include/asm-mips/time.h +++ b/trunk/include/asm-mips/time.h @@ -21,7 +21,6 @@ #include #include #include -#include #include extern spinlock_t rtc_lock; @@ -41,6 +40,7 @@ extern int rtc_mips_set_mmss(unsigned long); * mips_timer_ack may be NULL if the interrupt is self-recoverable. */ extern int (*mips_timer_state)(void); +extern void (*mips_timer_ack)(void); /* * High precision timer clocksource. @@ -76,16 +76,6 @@ extern int (*perf_irq)(void); /* * Initialize the calling CPU's compare interrupt as clockevent device */ -#ifdef CONFIG_CEVT_R4K extern void mips_clockevent_init(void); -#else -static inline void mips_clockevent_init(void) -{ -} -#endif - -extern void clocksource_set_clock(struct clocksource *cs, unsigned int clock); -extern void clockevent_set_clock(struct clock_event_device *cd, - unsigned int clock); #endif /* _ASM_TIME_H */ diff --git a/trunk/include/asm-mips/tlbflush.h b/trunk/include/asm-mips/tlbflush.h index 86b21de12e91..730e841fb08a 100644 --- a/trunk/include/asm-mips/tlbflush.h +++ b/trunk/include/asm-mips/tlbflush.h @@ -11,6 +11,7 @@ * - flush_tlb_page(vma, vmaddr) flushes one page * - flush_tlb_range(vma, start, end) flushes a range of pages * - flush_tlb_kernel_range(start, end) flushes a range of kernel pages + * - flush_tlb_pgtables(mm, start, end) flushes a range of page tables */ extern void local_flush_tlb_all(void); extern void local_flush_tlb_mm(struct mm_struct *mm); @@ -44,4 +45,10 @@ extern void flush_tlb_one(unsigned long vaddr); #endif /* CONFIG_SMP */ +static inline void flush_tlb_pgtables(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ + /* Nothing to do on MIPS. */ +} + #endif /* __ASM_TLBFLUSH_H */ diff --git a/trunk/include/asm-parisc/bitops.h b/trunk/include/asm-parisc/bitops.h index f8eebcbad01f..015cb0d379bd 100644 --- a/trunk/include/asm-parisc/bitops.h +++ b/trunk/include/asm-parisc/bitops.h @@ -1,10 +1,6 @@ #ifndef _PARISC_BITOPS_H #define _PARISC_BITOPS_H -#ifndef _LINUX_BITOPS_H -#error only can be included directly -#endif - #include #include /* for BITS_PER_LONG/SHIFT_PER_LONG */ #include @@ -212,7 +208,6 @@ static __inline__ int fls(int x) #include #include -#include #include #endif /* __KERNEL__ */ diff --git a/trunk/include/asm-parisc/pgtable.h b/trunk/include/asm-parisc/pgtable.h index 9ab79c8e5a41..e88cacd63724 100644 --- a/trunk/include/asm-parisc/pgtable.h +++ b/trunk/include/asm-parisc/pgtable.h @@ -11,9 +11,9 @@ */ #include /* for vm_area_struct */ -#include #include #include +#include /* * kern_addr_valid(ADDR) tests if ADDR is pointing to valid kernel diff --git a/trunk/include/asm-parisc/tlbflush.h b/trunk/include/asm-parisc/tlbflush.h index b72ec66db699..270cf309772b 100644 --- a/trunk/include/asm-parisc/tlbflush.h +++ b/trunk/include/asm-parisc/tlbflush.h @@ -57,6 +57,10 @@ static inline void flush_tlb_mm(struct mm_struct *mm) #endif } +extern __inline__ void flush_tlb_pgtables(struct mm_struct *mm, unsigned long start, unsigned long end) +{ +} + static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr) { diff --git a/trunk/include/asm-powerpc/bitops.h b/trunk/include/asm-powerpc/bitops.h index 733b4af7f4f1..8144a2788db6 100644 --- a/trunk/include/asm-powerpc/bitops.h +++ b/trunk/include/asm-powerpc/bitops.h @@ -38,10 +38,6 @@ #ifdef __KERNEL__ -#ifndef _LINUX_BITOPS_H -#error only can be included directly -#endif - #include #include #include @@ -90,24 +86,6 @@ static __inline__ void clear_bit(int nr, volatile unsigned long *addr) : "cc" ); } -static __inline__ void clear_bit_unlock(int nr, volatile unsigned long *addr) -{ - unsigned long old; - unsigned long mask = BITOP_MASK(nr); - unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr); - - __asm__ __volatile__( - LWSYNC_ON_SMP -"1:" PPC_LLARX "%0,0,%3 # clear_bit_unlock\n" - "andc %0,%0,%2\n" - PPC405_ERR77(0,%3) - PPC_STLCX "%0,0,%3\n" - "bne- 1b" - : "=&r" (old), "+m" (*p) - : "r" (mask), "r" (p) - : "cc", "memory"); -} - static __inline__ void change_bit(int nr, volatile unsigned long *addr) { unsigned long old; @@ -147,27 +125,6 @@ static __inline__ int test_and_set_bit(unsigned long nr, return (old & mask) != 0; } -static __inline__ int test_and_set_bit_lock(unsigned long nr, - volatile unsigned long *addr) -{ - unsigned long old, t; - unsigned long mask = BITOP_MASK(nr); - unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr); - - __asm__ __volatile__( -"1:" PPC_LLARX "%0,0,%3 # test_and_set_bit_lock\n" - "or %1,%0,%2 \n" - PPC405_ERR77(0,%3) - PPC_STLCX "%1,0,%3 \n" - "bne- 1b" - ISYNC_ON_SMP - : "=&r" (old), "=&r" (t) - : "r" (mask), "r" (p) - : "cc", "memory"); - - return (old & mask) != 0; -} - static __inline__ int test_and_clear_bit(unsigned long nr, volatile unsigned long *addr) { @@ -228,12 +185,6 @@ static __inline__ void set_bits(unsigned long mask, unsigned long *addr) #include -static __inline__ void __clear_bit_unlock(int nr, volatile unsigned long *addr) -{ - __asm__ __volatile__(LWSYNC_ON_SMP "" ::: "memory"); - __clear_bit(nr, addr); -} - /* * Return the zero-based bit position (LE, not IBM bit numbering) of * the most significant 1-bit in a double word. diff --git a/trunk/include/asm-powerpc/iommu.h b/trunk/include/asm-powerpc/iommu.h index 4a82fdccee92..870967e47204 100644 --- a/trunk/include/asm-powerpc/iommu.h +++ b/trunk/include/asm-powerpc/iommu.h @@ -26,9 +26,9 @@ #include #include #include -#include #include #include +#include #define IOMMU_PAGE_SHIFT 12 #define IOMMU_PAGE_SIZE (ASM_CONST(1) << IOMMU_PAGE_SHIFT) diff --git a/trunk/include/asm-powerpc/mmu_context.h b/trunk/include/asm-powerpc/mmu_context.h index 9102b8bf0ead..f863ac21409e 100644 --- a/trunk/include/asm-powerpc/mmu_context.h +++ b/trunk/include/asm-powerpc/mmu_context.h @@ -8,7 +8,7 @@ #ifndef CONFIG_PPC64 #include -#include +#include /* * On 32-bit PowerPC 6xx/7xx/7xxx CPUs, we use a set of 16 VSIDs diff --git a/trunk/include/asm-powerpc/mpc52xx.h b/trunk/include/asm-powerpc/mpc52xx.h index 568135fe52ea..24751df791ac 100644 --- a/trunk/include/asm-powerpc/mpc52xx.h +++ b/trunk/include/asm-powerpc/mpc52xx.h @@ -18,8 +18,6 @@ #include #endif /* __ASSEMBLY__ */ -#include - /* ======================================================================== */ /* Structures mapping of some unit register set */ @@ -269,9 +267,9 @@ extern int mpc52xx_set_wakeup_gpio(u8 pin, u8 level); extern int __init lite5200_pm_init(void); /* lite5200 calls mpc5200 suspend functions, so here they are */ -extern int mpc52xx_pm_prepare(void); +extern int mpc52xx_pm_prepare(suspend_state_t); extern int mpc52xx_pm_enter(suspend_state_t); -extern void mpc52xx_pm_finish(void); +extern int mpc52xx_pm_finish(suspend_state_t); extern char saved_sram[0x4000]; /* reuse buffer from mpc52xx suspend */ #endif #endif /* CONFIG_PM */ diff --git a/trunk/include/asm-powerpc/paca.h b/trunk/include/asm-powerpc/paca.h index 98c6bd5756b7..fcd7b428ed0b 100644 --- a/trunk/include/asm-powerpc/paca.h +++ b/trunk/include/asm-powerpc/paca.h @@ -114,9 +114,6 @@ struct paca_struct { u64 user_time; /* accumulated usermode TB ticks */ u64 system_time; /* accumulated system TB ticks */ u64 startpurr; /* PURR/TB value snapshot */ - u64 startspurr; /* SPURR value snapshot */ - u64 purrdelta; /* FIXME: document */ - u64 spurrdelta; /* FIXME: document */ }; extern struct paca_struct paca[]; diff --git a/trunk/include/asm-powerpc/tlbflush.h b/trunk/include/asm-powerpc/tlbflush.h index b6b036ccee34..a022f806bb21 100644 --- a/trunk/include/asm-powerpc/tlbflush.h +++ b/trunk/include/asm-powerpc/tlbflush.h @@ -8,6 +8,7 @@ * - flush_tlb_page_nohash(vma, vmaddr) flushes one page if SW loaded TLB * - flush_tlb_range(vma, start, end) flushes a range of pages * - flush_tlb_kernel_range(start, end) flushes a range of kernel pages + * - flush_tlb_pgtables(mm, start, end) flushes a range of page tables * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -173,5 +174,15 @@ extern void __flush_hash_table_range(struct mm_struct *mm, unsigned long start, */ extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t); +/* + * This is called in munmap when we have freed up some page-table + * pages. We don't need to do anything here, there's nothing special + * about our page-table pages. -- paulus + */ +static inline void flush_tlb_pgtables(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ +} + #endif /*__KERNEL__ */ #endif /* _ASM_POWERPC_TLBFLUSH_H */ diff --git a/trunk/include/asm-ppc/mmu_context.h b/trunk/include/asm-ppc/mmu_context.h index b2e25d8997bf..a6441a063e5d 100644 --- a/trunk/include/asm-ppc/mmu_context.h +++ b/trunk/include/asm-ppc/mmu_context.h @@ -2,9 +2,8 @@ #ifndef __PPC_MMU_CONTEXT_H #define __PPC_MMU_CONTEXT_H -#include - #include +#include #include #include #include diff --git a/trunk/include/asm-ppc/time.h b/trunk/include/asm-ppc/time.h index 81dbcd43a501..f7eadf6ac806 100644 --- a/trunk/include/asm-ppc/time.h +++ b/trunk/include/asm-ppc/time.h @@ -57,7 +57,7 @@ static __inline__ void set_dec(unsigned int val) /* Accessor functions for the timebase (RTC on 601) registers. */ /* If one day CONFIG_POWER is added just define __USE_RTC as 1 */ #ifdef CONFIG_6xx -extern __inline__ int __pure __USE_RTC(void) { +extern __inline__ int __attribute_pure__ __USE_RTC(void) { return (mfspr(SPRN_PVR)>>16) == 1; } #else diff --git a/trunk/include/asm-s390/bitops.h b/trunk/include/asm-s390/bitops.h index 34d9a6357c38..f79c9b792af1 100644 --- a/trunk/include/asm-s390/bitops.h +++ b/trunk/include/asm-s390/bitops.h @@ -15,10 +15,6 @@ #ifdef __KERNEL__ -#ifndef _LINUX_BITOPS_H -#error only can be included directly -#endif - #include /* @@ -750,7 +746,6 @@ static inline int sched_find_first_bit(unsigned long *b) #include #include -#include /* * ATTENTION: intel byte ordering convention for ext2 and minix !! diff --git a/trunk/include/asm-s390/tlbflush.h b/trunk/include/asm-s390/tlbflush.h index 6de2632a3e4f..66793f55c8b2 100644 --- a/trunk/include/asm-s390/tlbflush.h +++ b/trunk/include/asm-s390/tlbflush.h @@ -14,6 +14,7 @@ * - flush_tlb_page(vma, vmaddr) flushes one page * - flush_tlb_range(vma, start, end) flushes a range of pages * - flush_tlb_kernel_range(start, end) flushes a range of kernel pages + * - flush_tlb_pgtables(mm, start, end) flushes a range of page tables */ /* @@ -151,4 +152,10 @@ static inline void flush_tlb_range(struct vm_area_struct *vma, #endif +static inline void flush_tlb_pgtables(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ + /* S/390 does not keep any page table caches in TLB */ +} + #endif /* _S390_TLBFLUSH_H */ diff --git a/trunk/include/asm-sh/bitops.h b/trunk/include/asm-sh/bitops.h index df805f20b267..1c16792cee1d 100644 --- a/trunk/include/asm-sh/bitops.h +++ b/trunk/include/asm-sh/bitops.h @@ -2,11 +2,6 @@ #define __ASM_SH_BITOPS_H #ifdef __KERNEL__ - -#ifndef _LINUX_BITOPS_H -#error only can be included directly -#endif - #include /* For __swab32 */ #include @@ -142,7 +137,6 @@ static inline unsigned long __ffs(unsigned long word) #include #include #include -#include #include #include #include diff --git a/trunk/include/asm-sh/tlbflush.h b/trunk/include/asm-sh/tlbflush.h index e0ac97221ae6..455fb8da441e 100644 --- a/trunk/include/asm-sh/tlbflush.h +++ b/trunk/include/asm-sh/tlbflush.h @@ -9,6 +9,7 @@ * - flush_tlb_page(vma, vmaddr) flushes one page * - flush_tlb_range(vma, start, end) flushes a range of pages * - flush_tlb_kernel_range(start, end) flushes a range of kernel pages + * - flush_tlb_pgtables(mm, start, end) flushes a range of page tables */ extern void local_flush_tlb_all(void); extern void local_flush_tlb_mm(struct mm_struct *mm); @@ -46,4 +47,9 @@ extern void flush_tlb_one(unsigned long asid, unsigned long page); #endif /* CONFIG_SMP */ +static inline void flush_tlb_pgtables(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ + /* Nothing to do */ +} #endif /* __ASM_SH_TLBFLUSH_H */ diff --git a/trunk/include/asm-sh64/bitops.h b/trunk/include/asm-sh64/bitops.h index 600c59efb4c2..f3bdcdb5d046 100644 --- a/trunk/include/asm-sh64/bitops.h +++ b/trunk/include/asm-sh64/bitops.h @@ -13,11 +13,6 @@ */ #ifdef __KERNEL__ - -#ifndef _LINUX_BITOPS_H -#error only can be included directly -#endif - #include #include /* For __swab32 */ @@ -141,7 +136,6 @@ static __inline__ unsigned long ffz(unsigned long word) #include #include #include -#include #include #include #include diff --git a/trunk/include/asm-sh64/tlbflush.h b/trunk/include/asm-sh64/tlbflush.h index 16a164a23754..e45beadc29ee 100644 --- a/trunk/include/asm-sh64/tlbflush.h +++ b/trunk/include/asm-sh64/tlbflush.h @@ -20,6 +20,10 @@ extern void flush_tlb_mm(struct mm_struct *mm); extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, unsigned long end); extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long page); +static inline void flush_tlb_pgtables(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ +} extern void flush_tlb_kernel_range(unsigned long start, unsigned long end); diff --git a/trunk/include/asm-sparc/bitops.h b/trunk/include/asm-sparc/bitops.h index cb3cefab6e09..329e696e7751 100644 --- a/trunk/include/asm-sparc/bitops.h +++ b/trunk/include/asm-sparc/bitops.h @@ -14,10 +14,6 @@ #ifdef __KERNEL__ -#ifndef _LINUX_BITOPS_H -#error only can be included directly -#endif - extern unsigned long ___set_bit(unsigned long *addr, unsigned long mask); extern unsigned long ___clear_bit(unsigned long *addr, unsigned long mask); extern unsigned long ___change_bit(unsigned long *addr, unsigned long mask); @@ -100,7 +96,6 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr) #include #include #include -#include #include #include #include diff --git a/trunk/include/asm-sparc/ioctls.h b/trunk/include/asm-sparc/ioctls.h index 058c2064f706..bdf77b0dfd8e 100644 --- a/trunk/include/asm-sparc/ioctls.h +++ b/trunk/include/asm-sparc/ioctls.h @@ -15,10 +15,6 @@ #define TCSETS _IOW('T', 9, struct termios) #define TCSETSW _IOW('T', 10, struct termios) #define TCSETSF _IOW('T', 11, struct termios) -#define TCGETS2 _IOR('T', 12, struct termios2) -#define TCSETS2 _IOW('T', 13, struct termios2) -#define TCSETSW2 _IOW('T', 14, struct termios2) -#define TCSETSF2 _IOW('T', 15, struct termios2) /* Note that all the ioctls that are not available in Linux have a * double underscore on the front to: a) avoid some programs to diff --git a/trunk/include/asm-sparc/of_platform.h b/trunk/include/asm-sparc/of_platform.h index d638737ff13c..64a230064ef2 100644 --- a/trunk/include/asm-sparc/of_platform.h +++ b/trunk/include/asm-sparc/of_platform.h @@ -18,9 +18,12 @@ extern struct bus_type ebus_bus_type; extern struct bus_type sbus_bus_type; - +extern struct bus_type of_platform_bus_type; #define of_bus_type of_platform_bus_type /* for compatibility */ +extern int of_register_driver(struct of_platform_driver *drv, + struct bus_type *bus); +extern void of_unregister_driver(struct of_platform_driver *drv); extern struct of_device *of_platform_device_create(struct device_node *np, const char *bus_id, struct device *parent, diff --git a/trunk/include/asm-sparc/termbits.h b/trunk/include/asm-sparc/termbits.h index 90cf2210118b..5eb00a105d7c 100644 --- a/trunk/include/asm-sparc/termbits.h +++ b/trunk/include/asm-sparc/termbits.h @@ -31,18 +31,6 @@ struct termios { #endif }; -struct termios2 { - tcflag_t c_iflag; /* input mode flags */ - tcflag_t c_oflag; /* output mode flags */ - tcflag_t c_cflag; /* control mode flags */ - tcflag_t c_lflag; /* local mode flags */ - cc_t c_line; /* line discipline */ - cc_t c_cc[NCCS]; /* control characters */ - cc_t _x_cc[2]; /* padding to match ktermios */ - speed_t c_ispeed; /* input speed */ - speed_t c_ospeed; /* output speed */ -}; - struct ktermios { tcflag_t c_iflag; /* input mode flags */ tcflag_t c_oflag; /* output mode flags */ @@ -172,7 +160,6 @@ struct ktermios { #define CLOCAL 0x00000800 #define CBAUDEX 0x00001000 /* We'll never see these speeds with the Zilogs, but for completeness... */ -#define BOTHER 0x00001000 #define B57600 0x00001001 #define B115200 0x00001002 #define B230400 0x00001003 @@ -202,8 +189,6 @@ struct ktermios { #define CMSPAR 0x40000000 /* mark or space (stick) parity */ #define CRTSCTS 0x80000000 /* flow control */ -#define IBSHIFT 16 /* Shift from CBAUD to CIBAUD */ - /* c_lflag bits */ #define ISIG 0x00000001 #define ICANON 0x00000002 diff --git a/trunk/include/asm-sparc/termios.h b/trunk/include/asm-sparc/termios.h index 4333232abb9f..d767f206ab33 100644 --- a/trunk/include/asm-sparc/termios.h +++ b/trunk/include/asm-sparc/termios.h @@ -107,48 +107,6 @@ struct winsize { }) #define user_termios_to_kernel_termios(k, u) \ -({ \ - int err; \ - err = get_user((k)->c_iflag, &(u)->c_iflag); \ - err |= get_user((k)->c_oflag, &(u)->c_oflag); \ - err |= get_user((k)->c_cflag, &(u)->c_cflag); \ - err |= get_user((k)->c_lflag, &(u)->c_lflag); \ - err |= get_user((k)->c_line, &(u)->c_line); \ - err |= copy_from_user((k)->c_cc, (u)->c_cc, NCCS); \ - if ((k)->c_lflag & ICANON) { \ - err |= get_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \ - err |= get_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \ - } else { \ - err |= get_user((k)->c_cc[VMIN], &(u)->c_cc[_VMIN]); \ - err |= get_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \ - } \ - err |= get_user((k)->c_ispeed, &(u)->c_ispeed); \ - err |= get_user((k)->c_ospeed, &(u)->c_ospeed); \ - err; \ -}) - -#define kernel_termios_to_user_termios(u, k) \ -({ \ - int err; \ - err = put_user((k)->c_iflag, &(u)->c_iflag); \ - err |= put_user((k)->c_oflag, &(u)->c_oflag); \ - err |= put_user((k)->c_cflag, &(u)->c_cflag); \ - err |= put_user((k)->c_lflag, &(u)->c_lflag); \ - err |= put_user((k)->c_line, &(u)->c_line); \ - err |= copy_to_user((u)->c_cc, (k)->c_cc, NCCS); \ - if (!((k)->c_lflag & ICANON)) { \ - err |= put_user((k)->c_cc[VMIN], &(u)->c_cc[_VMIN]); \ - err |= put_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \ - } else { \ - err |= put_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \ - err |= put_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \ - } \ - err |= put_user((k)->c_ispeed, &(u)->c_ispeed); \ - err |= put_user((k)->c_ospeed, &(u)->c_ospeed); \ - err; \ -}) - -#define user_termios_to_kernel_termios_1(k, u) \ ({ \ get_user((k)->c_iflag, &(u)->c_iflag); \ get_user((k)->c_oflag, &(u)->c_oflag); \ @@ -156,7 +114,7 @@ struct winsize { get_user((k)->c_lflag, &(u)->c_lflag); \ get_user((k)->c_line, &(u)->c_line); \ copy_from_user((k)->c_cc, (u)->c_cc, NCCS); \ - if ((k)->c_lflag & ICANON) { \ + if((k)->c_lflag & ICANON) { \ get_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \ get_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \ } else { \ @@ -166,7 +124,7 @@ struct winsize { 0; \ }) -#define kernel_termios_to_user_termios_1(u, k) \ +#define kernel_termios_to_user_termios(u, k) \ ({ \ put_user((k)->c_iflag, &(u)->c_iflag); \ put_user((k)->c_oflag, &(u)->c_oflag); \ @@ -174,7 +132,7 @@ struct winsize { put_user((k)->c_lflag, &(u)->c_lflag); \ put_user((k)->c_line, &(u)->c_line); \ copy_to_user((u)->c_cc, (k)->c_cc, NCCS); \ - if (!((k)->c_lflag & ICANON)) { \ + if(!((k)->c_lflag & ICANON)) { \ put_user((k)->c_cc[VMIN], &(u)->c_cc[_VMIN]); \ put_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \ } else { \ diff --git a/trunk/include/asm-sparc/tlbflush.h b/trunk/include/asm-sparc/tlbflush.h index b957e29d2ae1..a619da5cfaa9 100644 --- a/trunk/include/asm-sparc/tlbflush.h +++ b/trunk/include/asm-sparc/tlbflush.h @@ -13,6 +13,7 @@ * - flush_tlb_page(vma, vmaddr) flushes one page * - flush_tlb_range(vma, start, end) flushes a range of pages * - flush_tlb_kernel_range(start, end) flushes a range of kernel pages + * - flush_tlb_pgtables(mm, start, end) flushes a range of page tables */ #ifdef CONFIG_SMP @@ -41,6 +42,11 @@ BTFIXUPDEF_CALL(void, flush_tlb_mm, struct mm_struct *) BTFIXUPDEF_CALL(void, flush_tlb_range, struct vm_area_struct *, unsigned long, unsigned long) BTFIXUPDEF_CALL(void, flush_tlb_page, struct vm_area_struct *, unsigned long) +// Thanks to Anton Blanchard, our pagetables became uncached in 2.4. Wee! +// extern void flush_tlb_pgtables(struct mm_struct *mm, +// unsigned long start, unsigned long end); +#define flush_tlb_pgtables(mm, start, end) do{ }while(0) + #define flush_tlb_all() BTFIXUP_CALL(flush_tlb_all)() #define flush_tlb_mm(mm) BTFIXUP_CALL(flush_tlb_mm)(mm) #define flush_tlb_range(vma,start,end) BTFIXUP_CALL(flush_tlb_range)(vma,start,end) diff --git a/trunk/include/asm-sparc64/backoff.h b/trunk/include/asm-sparc64/backoff.h deleted file mode 100644 index 0e32f8b62fd2..000000000000 --- a/trunk/include/asm-sparc64/backoff.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef _SPARC64_BACKOFF_H -#define _SPARC64_BACKOFF_H - -#define BACKOFF_LIMIT (4 * 1024) - -#ifdef CONFIG_SMP - -#define BACKOFF_SETUP(reg) \ - mov 1, reg - -#define BACKOFF_SPIN(reg, tmp, label) \ - mov reg, tmp; \ -88: brnz,pt tmp, 88b; \ - sub tmp, 1, tmp; \ - cmp reg, BACKOFF_LIMIT; \ - bg,pn %xcc, label; \ - nop; \ - ba,pt %xcc, label; \ - sllx reg, 1, reg; - -#else - -#define BACKOFF_SETUP(reg) -#define BACKOFF_SPIN(reg, tmp, label) - -#endif - -#endif /* _SPARC64_BACKOFF_H */ diff --git a/trunk/include/asm-sparc64/bitops.h b/trunk/include/asm-sparc64/bitops.h index 982ce8992b91..3d5e1af84723 100644 --- a/trunk/include/asm-sparc64/bitops.h +++ b/trunk/include/asm-sparc64/bitops.h @@ -7,10 +7,6 @@ #ifndef _SPARC64_BITOPS_H #define _SPARC64_BITOPS_H -#ifndef _LINUX_BITOPS_H -#error only can be included directly -#endif - #include #include @@ -85,7 +81,6 @@ static inline unsigned int hweight8(unsigned int w) #include #endif -#include #endif /* __KERNEL__ */ #include diff --git a/trunk/include/asm-sparc64/ioctls.h b/trunk/include/asm-sparc64/ioctls.h index 083c9a0f37de..2223b6d0e5ed 100644 --- a/trunk/include/asm-sparc64/ioctls.h +++ b/trunk/include/asm-sparc64/ioctls.h @@ -16,10 +16,6 @@ #define TCSETS _IOW('T', 9, struct termios) #define TCSETSW _IOW('T', 10, struct termios) #define TCSETSF _IOW('T', 11, struct termios) -#define TCGETS2 _IOR('T', 12, struct termios2) -#define TCSETS2 _IOW('T', 13, struct termios2) -#define TCSETSW2 _IOW('T', 14, struct termios2) -#define TCSETSF2 _IOW('T', 15, struct termios2) /* Note that all the ioctls that are not available in Linux have a * double underscore on the front to: a) avoid some programs to diff --git a/trunk/include/asm-sparc64/of_platform.h b/trunk/include/asm-sparc64/of_platform.h index f15cfa723916..f7c1f17c7d52 100644 --- a/trunk/include/asm-sparc64/of_platform.h +++ b/trunk/include/asm-sparc64/of_platform.h @@ -19,9 +19,12 @@ extern struct bus_type isa_bus_type; extern struct bus_type ebus_bus_type; extern struct bus_type sbus_bus_type; - +extern struct bus_type of_platform_bus_type; #define of_bus_type of_platform_bus_type /* for compatibility */ +extern int of_register_driver(struct of_platform_driver *drv, + struct bus_type *bus); +extern void of_unregister_driver(struct of_platform_driver *drv); extern struct of_device *of_platform_device_create(struct device_node *np, const char *bus_id, struct device *parent, diff --git a/trunk/include/asm-sparc64/smp.h b/trunk/include/asm-sparc64/smp.h index 1c1c5ea5cea5..42c09949526c 100644 --- a/trunk/include/asm-sparc64/smp.h +++ b/trunk/include/asm-sparc64/smp.h @@ -26,7 +26,7 @@ * Private routines/data */ -#include +#include #include #include diff --git a/trunk/include/asm-sparc64/termbits.h b/trunk/include/asm-sparc64/termbits.h index ebe31c152f16..705cd44b4173 100644 --- a/trunk/include/asm-sparc64/termbits.h +++ b/trunk/include/asm-sparc64/termbits.h @@ -5,6 +5,8 @@ typedef unsigned char cc_t; typedef unsigned int speed_t; + +/* XXX is this right for sparc64? it was an unsigned long... XXX */ typedef unsigned int tcflag_t; #define NCC 8 @@ -31,18 +33,6 @@ struct termios { #endif }; -struct termios2 { - tcflag_t c_iflag; /* input mode flags */ - tcflag_t c_oflag; /* output mode flags */ - tcflag_t c_cflag; /* control mode flags */ - tcflag_t c_lflag; /* local mode flags */ - cc_t c_line; /* line discipline */ - cc_t c_cc[NCCS]; /* control characters */ - cc_t _x_cc[2]; /* padding to match ktermios */ - speed_t c_ispeed; /* input speed */ - speed_t c_ospeed; /* output speed */ -}; - struct ktermios { tcflag_t c_iflag; /* input mode flags */ tcflag_t c_oflag; /* output mode flags */ @@ -171,7 +161,6 @@ struct ktermios { #define HUPCL 0x00000400 #define CLOCAL 0x00000800 #define CBAUDEX 0x00001000 -#define BOTHER 0x00001000 #define B57600 0x00001001 #define B115200 0x00001002 #define B230400 0x00001003 @@ -201,8 +190,6 @@ struct ktermios { #define CMSPAR 0x40000000 /* mark or space (stick) parity */ #define CRTSCTS 0x80000000 /* flow control */ -#define IBSHIFT 16 /* Shift from CBAUD to CIBAUD */ - /* c_lflag bits */ #define ISIG 0x00000001 #define ICANON 0x00000002 diff --git a/trunk/include/asm-sparc64/termios.h b/trunk/include/asm-sparc64/termios.h index ef527211f8a8..f05d390993d5 100644 --- a/trunk/include/asm-sparc64/termios.h +++ b/trunk/include/asm-sparc64/termios.h @@ -123,52 +123,10 @@ struct winsize { err |= get_user((k)->c_cc[VMIN], &(u)->c_cc[_VMIN]); \ err |= get_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \ } \ - err |= get_user((k)->c_ispeed, &(u)->c_ispeed); \ - err |= get_user((k)->c_ospeed, &(u)->c_ospeed); \ err; \ }) #define kernel_termios_to_user_termios(u, k) \ -({ \ - int err; \ - err = put_user((k)->c_iflag, &(u)->c_iflag); \ - err |= put_user((k)->c_oflag, &(u)->c_oflag); \ - err |= put_user((k)->c_cflag, &(u)->c_cflag); \ - err |= put_user((k)->c_lflag, &(u)->c_lflag); \ - err |= put_user((k)->c_line, &(u)->c_line); \ - err |= copy_to_user((u)->c_cc, (k)->c_cc, NCCS); \ - if(!((k)->c_lflag & ICANON)) { \ - err |= put_user((k)->c_cc[VMIN], &(u)->c_cc[_VMIN]); \ - err |= put_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \ - } else { \ - err |= put_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \ - err |= put_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \ - } \ - err |= put_user((k)->c_ispeed, &(u)->c_ispeed); \ - err |= put_user((k)->c_ospeed, &(u)->c_ospeed); \ - err; \ -}) - -#define user_termios_to_kernel_termios_1(k, u) \ -({ \ - int err; \ - err = get_user((k)->c_iflag, &(u)->c_iflag); \ - err |= get_user((k)->c_oflag, &(u)->c_oflag); \ - err |= get_user((k)->c_cflag, &(u)->c_cflag); \ - err |= get_user((k)->c_lflag, &(u)->c_lflag); \ - err |= get_user((k)->c_line, &(u)->c_line); \ - err |= copy_from_user((k)->c_cc, (u)->c_cc, NCCS); \ - if((k)->c_lflag & ICANON) { \ - err |= get_user((k)->c_cc[VEOF], &(u)->c_cc[VEOF]); \ - err |= get_user((k)->c_cc[VEOL], &(u)->c_cc[VEOL]); \ - } else { \ - err |= get_user((k)->c_cc[VMIN], &(u)->c_cc[_VMIN]); \ - err |= get_user((k)->c_cc[VTIME], &(u)->c_cc[_VTIME]); \ - } \ - err; \ -}) - -#define kernel_termios_to_user_termios_1(u, k) \ ({ \ int err; \ err = put_user((k)->c_iflag, &(u)->c_iflag); \ diff --git a/trunk/include/asm-sparc64/tlbflush.h b/trunk/include/asm-sparc64/tlbflush.h index fbb675dbe0c9..3487328570ed 100644 --- a/trunk/include/asm-sparc64/tlbflush.h +++ b/trunk/include/asm-sparc64/tlbflush.h @@ -41,4 +41,11 @@ do { flush_tsb_kernel_range(start,end); \ #endif /* ! CONFIG_SMP */ +static inline void flush_tlb_pgtables(struct mm_struct *mm, unsigned long start, unsigned long end) +{ + /* We don't use virtual page tables for TLB miss processing + * any more. Nowadays we use the TSB. + */ +} + #endif /* _SPARC64_TLBFLUSH_H */ diff --git a/trunk/include/asm-um/bitops.h b/trunk/include/asm-um/bitops.h index e4d38d437b97..46d781953d3a 100644 --- a/trunk/include/asm-um/bitops.h +++ b/trunk/include/asm-um/bitops.h @@ -1,10 +1,6 @@ #ifndef __UM_BITOPS_H #define __UM_BITOPS_H -#ifndef _LINUX_BITOPS_H -#error only can be included directly -#endif - #include "asm/arch/bitops.h" #endif diff --git a/trunk/include/asm-um/tlbflush.h b/trunk/include/asm-um/tlbflush.h index 614f2c091178..9d647c55350b 100644 --- a/trunk/include/asm-um/tlbflush.h +++ b/trunk/include/asm-um/tlbflush.h @@ -17,6 +17,7 @@ * - flush_tlb_page(vma, vmaddr) flushes one page * - flush_tlb_kernel_vm() flushes the kernel vm area * - flush_tlb_range(vma, start, end) flushes a range of pages + * - flush_tlb_pgtables(mm, start, end) flushes a range of page tables */ extern void flush_tlb_all(void); @@ -28,4 +29,9 @@ extern void flush_tlb_kernel_vm(void); extern void flush_tlb_kernel_range(unsigned long start, unsigned long end); extern void __flush_tlb_one(unsigned long addr); +static inline void flush_tlb_pgtables(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ +} + #endif diff --git a/trunk/include/asm-v850/bitops.h b/trunk/include/asm-v850/bitops.h index f82f5b4a56e0..1fa99baf4e25 100644 --- a/trunk/include/asm-v850/bitops.h +++ b/trunk/include/asm-v850/bitops.h @@ -13,9 +13,6 @@ #ifndef __V850_BITOPS_H__ #define __V850_BITOPS_H__ -#ifndef _LINUX_BITOPS_H -#error only can be included directly -#endif #include /* unlikely */ #include /* swab32 */ @@ -148,7 +145,6 @@ static inline int __test_bit (int nr, const void *addr) #include #include #include -#include #include #define ext2_set_bit_atomic(l,n,a) test_and_set_bit(n,a) diff --git a/trunk/include/asm-v850/tlbflush.h b/trunk/include/asm-v850/tlbflush.h index c44aa64449c8..5f2f85f636ea 100644 --- a/trunk/include/asm-v850/tlbflush.h +++ b/trunk/include/asm-v850/tlbflush.h @@ -61,4 +61,10 @@ static inline void flush_tlb_kernel_page(unsigned long addr) BUG (); } +static inline void flush_tlb_pgtables(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ + BUG (); +} + #endif /* __V850_TLBFLUSH_H__ */ diff --git a/trunk/include/asm-x86/bitops_32.h b/trunk/include/asm-x86/bitops_32.h index 3268a341cf49..a20fe9822f60 100644 --- a/trunk/include/asm-x86/bitops_32.h +++ b/trunk/include/asm-x86/bitops_32.h @@ -5,10 +5,6 @@ * Copyright 1992, Linus Torvalds. */ -#ifndef _LINUX_BITOPS_H -#error only can be included directly -#endif - #include #include @@ -406,7 +402,6 @@ static inline int fls(int x) } #include -#include #endif /* __KERNEL__ */ diff --git a/trunk/include/asm-x86/bitops_64.h b/trunk/include/asm-x86/bitops_64.h index dacaa5f1febc..1d7d9b4bcacb 100644 --- a/trunk/include/asm-x86/bitops_64.h +++ b/trunk/include/asm-x86/bitops_64.h @@ -5,10 +5,6 @@ * Copyright 1992, Linus Torvalds. */ -#ifndef _LINUX_BITOPS_H -#error only can be included directly -#endif - #include #if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 1) @@ -412,7 +408,6 @@ static __inline__ int fls(int x) #define ARCH_HAS_FAST_MULTIPLIER 1 #include -#include #endif /* __KERNEL__ */ diff --git a/trunk/include/asm-x86/pgtable_32.h b/trunk/include/asm-x86/pgtable_32.h index ed3e70d8d04b..acd4b339c49b 100644 --- a/trunk/include/asm-x86/pgtable_32.h +++ b/trunk/include/asm-x86/pgtable_32.h @@ -17,7 +17,10 @@ #include #include -#include +#ifndef _I386_BITOPS_H +#include +#endif + #include #include #include diff --git a/trunk/include/asm-x86/pgtable_64.h b/trunk/include/asm-x86/pgtable_64.h index 9b0ff477b39e..a79f5355e3b0 100644 --- a/trunk/include/asm-x86/pgtable_64.h +++ b/trunk/include/asm-x86/pgtable_64.h @@ -9,7 +9,7 @@ * the x86-64 page table tree. */ #include -#include +#include #include #include diff --git a/trunk/include/asm-x86/smp_32.h b/trunk/include/asm-x86/smp_32.h index 1f576a93368f..ee46038d126c 100644 --- a/trunk/include/asm-x86/smp_32.h +++ b/trunk/include/asm-x86/smp_32.h @@ -11,7 +11,7 @@ #endif #if defined(CONFIG_X86_LOCAL_APIC) && !defined(__ASSEMBLY__) -#include +#include #include #include #ifdef CONFIG_X86_IO_APIC diff --git a/trunk/include/asm-x86/suspend_64.h b/trunk/include/asm-x86/suspend_64.h index 9440a7a1b99a..b897e8cb55fb 100644 --- a/trunk/include/asm-x86/suspend_64.h +++ b/trunk/include/asm-x86/suspend_64.h @@ -53,5 +53,3 @@ extern unsigned long saved_rdi; /* routines for saving/restoring kernel state */ extern int acpi_save_state_mem(void); -extern char core_restore_code; -extern char restore_registers; diff --git a/trunk/include/asm-x86/tlbflush_32.h b/trunk/include/asm-x86/tlbflush_32.h index 2bd5b95e2048..a50fa6741486 100644 --- a/trunk/include/asm-x86/tlbflush_32.h +++ b/trunk/include/asm-x86/tlbflush_32.h @@ -78,6 +78,7 @@ * - flush_tlb_page(vma, vmaddr) flushes one page * - flush_tlb_range(vma, start, end) flushes a range of pages * - flush_tlb_kernel_range(start, end) flushes a range of kernel pages + * - flush_tlb_pgtables(mm, start, end) flushes a range of page tables * - flush_tlb_others(cpumask, mm, va) flushes a TLBs on other cpus * * ..but the i386 has somewhat limited tlb flushing capabilities, @@ -165,4 +166,10 @@ static inline void flush_tlb_kernel_range(unsigned long start, flush_tlb_all(); } +static inline void flush_tlb_pgtables(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ + /* i386 does not keep any page table caches in TLB */ +} + #endif /* _I386_TLBFLUSH_H */ diff --git a/trunk/include/asm-x86/tlbflush_64.h b/trunk/include/asm-x86/tlbflush_64.h index 7731fd23d572..888eb4abdd07 100644 --- a/trunk/include/asm-x86/tlbflush_64.h +++ b/trunk/include/asm-x86/tlbflush_64.h @@ -31,6 +31,7 @@ static inline void __flush_tlb_all(void) * - flush_tlb_page(vma, vmaddr) flushes one page * - flush_tlb_range(vma, start, end) flushes a range of pages * - flush_tlb_kernel_range(start, end) flushes a range of kernel pages + * - flush_tlb_pgtables(mm, start, end) flushes a range of page tables * * x86-64 can only flush individual pages or full VMs. For a range flush * we always do the full VM. Might be worth trying if for a small @@ -97,4 +98,12 @@ static inline void flush_tlb_kernel_range(unsigned long start, flush_tlb_all(); } +static inline void flush_tlb_pgtables(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ + /* x86_64 does not keep any page table caches in a software TLB. + The CPUs do in their hardware TLBs, but they are handled + by the normal TLB flushing algorithms. */ +} + #endif /* _X8664_TLBFLUSH_H */ diff --git a/trunk/include/asm-x86/topology_64.h b/trunk/include/asm-x86/topology_64.h index c0c93d744673..848c17f92226 100644 --- a/trunk/include/asm-x86/topology_64.h +++ b/trunk/include/asm-x86/topology_64.h @@ -5,7 +5,7 @@ #ifdef CONFIG_NUMA #include -#include +#include extern cpumask_t cpu_online_map; diff --git a/trunk/include/asm-xtensa/bitops.h b/trunk/include/asm-xtensa/bitops.h index 23261e8f2e5a..1c1e0d933eea 100644 --- a/trunk/include/asm-xtensa/bitops.h +++ b/trunk/include/asm-xtensa/bitops.h @@ -15,10 +15,6 @@ #ifdef __KERNEL__ -#ifndef _LINUX_BITOPS_H -#error only can be included directly -#endif - #include #include #include @@ -112,7 +108,6 @@ static inline int fls (unsigned int x) #endif #include -#include #include #include diff --git a/trunk/include/asm-xtensa/tlbflush.h b/trunk/include/asm-xtensa/tlbflush.h index 46d240074f74..7c637b3c352c 100644 --- a/trunk/include/asm-xtensa/tlbflush.h +++ b/trunk/include/asm-xtensa/tlbflush.h @@ -41,6 +41,17 @@ extern void flush_tlb_range(struct vm_area_struct*,unsigned long,unsigned long); #define flush_tlb_kernel_range(start,end) flush_tlb_all() + +/* This is calld in munmap when we have freed up some page-table pages. + * We don't need to do anything here, there's nothing special about our + * page-table pages. + */ + +static inline void flush_tlb_pgtables(struct mm_struct *mm, + unsigned long start, unsigned long end) +{ +} + /* TLB operations. */ static inline unsigned long itlb_probe(unsigned long addr) diff --git a/trunk/include/linux/Kbuild b/trunk/include/linux/Kbuild index e3ffd14a3f0b..7ac8303c8471 100644 --- a/trunk/include/linux/Kbuild +++ b/trunk/include/linux/Kbuild @@ -47,7 +47,6 @@ header-y += coda_psdev.h header-y += coff.h header-y += comstats.h header-y += const.h -header-y += cgroupstats.h header-y += cycx_cfm.h header-y += dlm_device.h header-y += dlm_netlink.h diff --git a/trunk/include/linux/acpi.h b/trunk/include/linux/acpi.h index 8ccedf7a0a5a..bf5e0009de75 100644 --- a/trunk/include/linux/acpi.h +++ b/trunk/include/linux/acpi.h @@ -189,6 +189,32 @@ extern int ec_transaction(u8 command, extern int acpi_blacklisted(void); extern void acpi_bios_year(char *s); +#define ACPI_CSTATE_LIMIT_DEFINED /* for driver builds */ +#ifdef CONFIG_ACPI + +/* + * Set highest legal C-state + * 0: C0 okay, but not C1 + * 1: C1 okay, but not C2 + * 2: C2 okay, but not C3 etc. + */ + +extern unsigned int max_cstate; + +static inline unsigned int acpi_get_cstate_limit(void) +{ + return max_cstate; +} +static inline void acpi_set_cstate_limit(unsigned int new_limit) +{ + max_cstate = new_limit; + return; +} +#else +static inline unsigned int acpi_get_cstate_limit(void) { return 0; } +static inline void acpi_set_cstate_limit(unsigned int new_limit) { return; } +#endif + #ifdef CONFIG_ACPI_NUMA int acpi_get_pxm(acpi_handle handle); int acpi_get_node(acpi_handle *handle); diff --git a/trunk/include/linux/aio.h b/trunk/include/linux/aio.h index 7ef8de662001..d10e608f232d 100644 --- a/trunk/include/linux/aio.h +++ b/trunk/include/linux/aio.h @@ -232,6 +232,18 @@ int FASTCALL(io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb, __put_ioctx(kioctx); \ } while (0) +#define in_aio() (unlikely(!is_sync_wait(current->io_wait))) + +/* may be used for debugging */ +#define warn_if_async() \ +do { \ + if (in_aio()) { \ + printk(KERN_ERR "%s(%s:%d) called in async context!\n", \ + __FUNCTION__, __FILE__, __LINE__); \ + dump_stack(); \ + } \ +} while (0) + #define io_wait_to_kiocb(wait) container_of(wait, struct kiocb, ki_wait) #include diff --git a/trunk/include/linux/bit_spinlock.h b/trunk/include/linux/bit_spinlock.h index 7113a32a86ea..6b20af0bbb79 100644 --- a/trunk/include/linux/bit_spinlock.h +++ b/trunk/include/linux/bit_spinlock.h @@ -18,7 +18,7 @@ static inline void bit_spin_lock(int bitnum, unsigned long *addr) */ preempt_disable(); #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) - while (unlikely(test_and_set_bit_lock(bitnum, addr))) { + while (test_and_set_bit(bitnum, addr)) { while (test_bit(bitnum, addr)) { preempt_enable(); cpu_relax(); @@ -36,7 +36,7 @@ static inline int bit_spin_trylock(int bitnum, unsigned long *addr) { preempt_disable(); #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) - if (unlikely(test_and_set_bit_lock(bitnum, addr))) { + if (test_and_set_bit(bitnum, addr)) { preempt_enable(); return 0; } @@ -50,28 +50,10 @@ static inline int bit_spin_trylock(int bitnum, unsigned long *addr) */ static inline void bit_spin_unlock(int bitnum, unsigned long *addr) { -#ifdef CONFIG_DEBUG_SPINLOCK - BUG_ON(!test_bit(bitnum, addr)); -#endif #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) - clear_bit_unlock(bitnum, addr); -#endif - preempt_enable(); - __release(bitlock); -} - -/* - * bit-based spin_unlock() - * non-atomic version, which can be used eg. if the bit lock itself is - * protecting the rest of the flags in the word. - */ -static inline void __bit_spin_unlock(int bitnum, unsigned long *addr) -{ -#ifdef CONFIG_DEBUG_SPINLOCK BUG_ON(!test_bit(bitnum, addr)); -#endif -#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) - __clear_bit_unlock(bitnum, addr); + smp_mb__before_clear_bit(); + clear_bit(bitnum, addr); #endif preempt_enable(); __release(bitlock); diff --git a/trunk/include/linux/bitmap.h b/trunk/include/linux/bitmap.h index acad1105d942..64b4641904fe 100644 --- a/trunk/include/linux/bitmap.h +++ b/trunk/include/linux/bitmap.h @@ -6,7 +6,6 @@ #include #include #include -#include /* * bitmaps provide bit arrays that consume one or more unsigned diff --git a/trunk/include/linux/bitops.h b/trunk/include/linux/bitops.h index 69c1edb9fe54..b9fb8ee3308b 100644 --- a/trunk/include/linux/bitops.h +++ b/trunk/include/linux/bitops.h @@ -2,14 +2,6 @@ #define _LINUX_BITOPS_H #include -#ifdef __KERNEL__ -#define BIT(nr) (1UL << (nr)) -#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG)) -#define BIT_WORD(nr) ((nr) / BITS_PER_LONG) -#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_LONG) -#define BITS_PER_BYTE 8 -#endif - /* * Include this here because some architectures need generic_ffs/fls in * scope diff --git a/trunk/include/linux/capability.h b/trunk/include/linux/capability.h index 7a8d7ade28a0..8961e7fb755c 100644 --- a/trunk/include/linux/capability.h +++ b/trunk/include/linux/capability.h @@ -310,6 +310,10 @@ typedef __u32 kernel_cap_t; #define CAP_SETFCAP 31 #ifdef __KERNEL__ +/* + * Bounding set + */ +extern kernel_cap_t cap_bset; /* * Internal kernel functions only diff --git a/trunk/include/linux/cgroup.h b/trunk/include/linux/cgroup.h deleted file mode 100644 index 87479328d46d..000000000000 --- a/trunk/include/linux/cgroup.h +++ /dev/null @@ -1,327 +0,0 @@ -#ifndef _LINUX_CGROUP_H -#define _LINUX_CGROUP_H -/* - * cgroup interface - * - * Copyright (C) 2003 BULL SA - * Copyright (C) 2004-2006 Silicon Graphics, Inc. - * - */ - -#include -#include -#include -#include -#include -#include - -#ifdef CONFIG_CGROUPS - -struct cgroupfs_root; -struct cgroup_subsys; -struct inode; - -extern int cgroup_init_early(void); -extern int cgroup_init(void); -extern void cgroup_init_smp(void); -extern void cgroup_lock(void); -extern void cgroup_unlock(void); -extern void cgroup_fork(struct task_struct *p); -extern void cgroup_fork_callbacks(struct task_struct *p); -extern void cgroup_post_fork(struct task_struct *p); -extern void cgroup_exit(struct task_struct *p, int run_callbacks); -extern int cgroupstats_build(struct cgroupstats *stats, - struct dentry *dentry); - -extern struct file_operations proc_cgroup_operations; - -/* Define the enumeration of all cgroup subsystems */ -#define SUBSYS(_x) _x ## _subsys_id, -enum cgroup_subsys_id { -#include - CGROUP_SUBSYS_COUNT -}; -#undef SUBSYS - -/* Per-subsystem/per-cgroup state maintained by the system. */ -struct cgroup_subsys_state { - /* The cgroup that this subsystem is attached to. Useful - * for subsystems that want to know about the cgroup - * hierarchy structure */ - struct cgroup *cgroup; - - /* State maintained by the cgroup system to allow - * subsystems to be "busy". Should be accessed via css_get() - * and css_put() */ - - atomic_t refcnt; - - unsigned long flags; -}; - -/* bits in struct cgroup_subsys_state flags field */ -enum { - CSS_ROOT, /* This CSS is the root of the subsystem */ -}; - -/* - * Call css_get() to hold a reference on the cgroup; - * - */ - -static inline void css_get(struct cgroup_subsys_state *css) -{ - /* We don't need to reference count the root state */ - if (!test_bit(CSS_ROOT, &css->flags)) - atomic_inc(&css->refcnt); -} -/* - * css_put() should be called to release a reference taken by - * css_get() - */ - -extern void __css_put(struct cgroup_subsys_state *css); -static inline void css_put(struct cgroup_subsys_state *css) -{ - if (!test_bit(CSS_ROOT, &css->flags)) - __css_put(css); -} - -struct cgroup { - unsigned long flags; /* "unsigned long" so bitops work */ - - /* count users of this cgroup. >0 means busy, but doesn't - * necessarily indicate the number of tasks in the - * cgroup */ - atomic_t count; - - /* - * We link our 'sibling' struct into our parent's 'children'. - * Our children link their 'sibling' into our 'children'. - */ - struct list_head sibling; /* my parent's children */ - struct list_head children; /* my children */ - - struct cgroup *parent; /* my parent */ - struct dentry *dentry; /* cgroup fs entry */ - - /* Private pointers for each registered subsystem */ - struct cgroup_subsys_state *subsys[CGROUP_SUBSYS_COUNT]; - - struct cgroupfs_root *root; - struct cgroup *top_cgroup; - - /* - * List of cg_cgroup_links pointing at css_sets with - * tasks in this cgroup. Protected by css_set_lock - */ - struct list_head css_sets; - - /* - * Linked list running through all cgroups that can - * potentially be reaped by the release agent. Protected by - * release_list_lock - */ - struct list_head release_list; -}; - -/* A css_set is a structure holding pointers to a set of - * cgroup_subsys_state objects. This saves space in the task struct - * object and speeds up fork()/exit(), since a single inc/dec and a - * list_add()/del() can bump the reference count on the entire - * cgroup set for a task. - */ - -struct css_set { - - /* Reference count */ - struct kref ref; - - /* - * List running through all cgroup groups. Protected by - * css_set_lock - */ - struct list_head list; - - /* - * List running through all tasks using this cgroup - * group. Protected by css_set_lock - */ - struct list_head tasks; - - /* - * List of cg_cgroup_link objects on link chains from - * cgroups referenced from this css_set. Protected by - * css_set_lock - */ - struct list_head cg_links; - - /* - * Set of subsystem states, one for each subsystem. This array - * is immutable after creation apart from the init_css_set - * during subsystem registration (at boot time). - */ - struct cgroup_subsys_state *subsys[CGROUP_SUBSYS_COUNT]; - -}; - -/* struct cftype: - * - * The files in the cgroup filesystem mostly have a very simple read/write - * handling, some common function will take care of it. Nevertheless some cases - * (read tasks) are special and therefore I define this structure for every - * kind of file. - * - * - * When reading/writing to a file: - * - the cgroup to use in file->f_dentry->d_parent->d_fsdata - * - the 'cftype' of the file is file->f_dentry->d_fsdata - */ - -#define MAX_CFTYPE_NAME 64 -struct cftype { - /* By convention, the name should begin with the name of the - * subsystem, followed by a period */ - char name[MAX_CFTYPE_NAME]; - int private; - int (*open) (struct inode *inode, struct file *file); - ssize_t (*read) (struct cgroup *cont, struct cftype *cft, - struct file *file, - char __user *buf, size_t nbytes, loff_t *ppos); - /* - * read_uint() is a shortcut for the common case of returning a - * single integer. Use it in place of read() - */ - u64 (*read_uint) (struct cgroup *cont, struct cftype *cft); - ssize_t (*write) (struct cgroup *cont, struct cftype *cft, - struct file *file, - const char __user *buf, size_t nbytes, loff_t *ppos); - - /* - * write_uint() is a shortcut for the common case of accepting - * a single integer (as parsed by simple_strtoull) from - * userspace. Use in place of write(); return 0 or error. - */ - int (*write_uint) (struct cgroup *cont, struct cftype *cft, u64 val); - - int (*release) (struct inode *inode, struct file *file); -}; - -/* Add a new file to the given cgroup directory. Should only be - * called by subsystems from within a populate() method */ -int cgroup_add_file(struct cgroup *cont, struct cgroup_subsys *subsys, - const struct cftype *cft); - -/* Add a set of new files to the given cgroup directory. Should - * only be called by subsystems from within a populate() method */ -int cgroup_add_files(struct cgroup *cont, - struct cgroup_subsys *subsys, - const struct cftype cft[], - int count); - -int cgroup_is_removed(const struct cgroup *cont); - -int cgroup_path(const struct cgroup *cont, char *buf, int buflen); - -int cgroup_task_count(const struct cgroup *cont); - -/* Return true if the cgroup is a descendant of the current cgroup */ -int cgroup_is_descendant(const struct cgroup *cont); - -/* Control Group subsystem type. See Documentation/cgroups.txt for details */ - -struct cgroup_subsys { - struct cgroup_subsys_state *(*create)(struct cgroup_subsys *ss, - struct cgroup *cont); - void (*destroy)(struct cgroup_subsys *ss, struct cgroup *cont); - int (*can_attach)(struct cgroup_subsys *ss, - struct cgroup *cont, struct task_struct *tsk); - void (*attach)(struct cgroup_subsys *ss, struct cgroup *cont, - struct cgroup *old_cont, struct task_struct *tsk); - void (*fork)(struct cgroup_subsys *ss, struct task_struct *task); - void (*exit)(struct cgroup_subsys *ss, struct task_struct *task); - int (*populate)(struct cgroup_subsys *ss, - struct cgroup *cont); - void (*post_clone)(struct cgroup_subsys *ss, struct cgroup *cont); - void (*bind)(struct cgroup_subsys *ss, struct cgroup *root); - int subsys_id; - int active; - int early_init; -#define MAX_CGROUP_TYPE_NAMELEN 32 - const char *name; - - /* Protected by RCU */ - struct cgroupfs_root *root; - - struct list_head sibling; - - void *private; -}; - -#define SUBSYS(_x) extern struct cgroup_subsys _x ## _subsys; -#include -#undef SUBSYS - -static inline struct cgroup_subsys_state *cgroup_subsys_state( - struct cgroup *cont, int subsys_id) -{ - return cont->subsys[subsys_id]; -} - -static inline struct cgroup_subsys_state *task_subsys_state( - struct task_struct *task, int subsys_id) -{ - return rcu_dereference(task->cgroups->subsys[subsys_id]); -} - -static inline struct cgroup* task_cgroup(struct task_struct *task, - int subsys_id) -{ - return task_subsys_state(task, subsys_id)->cgroup; -} - -int cgroup_path(const struct cgroup *cont, char *buf, int buflen); - -int cgroup_clone(struct task_struct *tsk, struct cgroup_subsys *ss); - -/* A cgroup_iter should be treated as an opaque object */ -struct cgroup_iter { - struct list_head *cg_link; - struct list_head *task; -}; - -/* To iterate across the tasks in a cgroup: - * - * 1) call cgroup_iter_start to intialize an iterator - * - * 2) call cgroup_iter_next() to retrieve member tasks until it - * returns NULL or until you want to end the iteration - * - * 3) call cgroup_iter_end() to destroy the iterator. - */ -void cgroup_iter_start(struct cgroup *cont, struct cgroup_iter *it); -struct task_struct *cgroup_iter_next(struct cgroup *cont, - struct cgroup_iter *it); -void cgroup_iter_end(struct cgroup *cont, struct cgroup_iter *it); - -#else /* !CONFIG_CGROUPS */ - -static inline int cgroup_init_early(void) { return 0; } -static inline int cgroup_init(void) { return 0; } -static inline void cgroup_init_smp(void) {} -static inline void cgroup_fork(struct task_struct *p) {} -static inline void cgroup_fork_callbacks(struct task_struct *p) {} -static inline void cgroup_post_fork(struct task_struct *p) {} -static inline void cgroup_exit(struct task_struct *p, int callbacks) {} - -static inline void cgroup_lock(void) {} -static inline void cgroup_unlock(void) {} -static inline int cgroupstats_build(struct cgroupstats *stats, - struct dentry *dentry) -{ - return -EINVAL; -} - -#endif /* !CONFIG_CGROUPS */ - -#endif /* _LINUX_CGROUP_H */ diff --git a/trunk/include/linux/cgroup_subsys.h b/trunk/include/linux/cgroup_subsys.h deleted file mode 100644 index 0b9bfbde8168..000000000000 --- a/trunk/include/linux/cgroup_subsys.h +++ /dev/null @@ -1,38 +0,0 @@ -/* Add subsystem definitions of the form SUBSYS() in this - * file. Surround each one by a line of comment markers so that - * patches don't collide - */ - -/* */ - -/* */ - -#ifdef CONFIG_CPUSETS -SUBSYS(cpuset) -#endif - -/* */ - -#ifdef CONFIG_CGROUP_CPUACCT -SUBSYS(cpuacct) -#endif - -/* */ - -#ifdef CONFIG_CGROUP_DEBUG -SUBSYS(debug) -#endif - -/* */ - -#ifdef CONFIG_CGROUP_NS -SUBSYS(ns) -#endif - -/* */ - -#ifdef CONFIG_FAIR_CGROUP_SCHED -SUBSYS(cpu_cgroup) -#endif - -/* */ diff --git a/trunk/include/linux/cgroupstats.h b/trunk/include/linux/cgroupstats.h deleted file mode 100644 index 4f53abf6855d..000000000000 --- a/trunk/include/linux/cgroupstats.h +++ /dev/null @@ -1,70 +0,0 @@ -/* cgroupstats.h - exporting per-cgroup statistics - * - * Copyright IBM Corporation, 2007 - * Author Balbir Singh - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2.1 of the GNU Lesser General Public License - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it would be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - */ - -#ifndef _LINUX_CGROUPSTATS_H -#define _LINUX_CGROUPSTATS_H - -#include - -/* - * Data shared between user space and kernel space on a per cgroup - * basis. This data is shared using taskstats. - * - * Most of these states are derived by looking at the task->state value - * For the nr_io_wait state, a flag in the delay accounting structure - * indicates that the task is waiting on IO - * - * Each member is aligned to a 8 byte boundary. - */ -struct cgroupstats { - __u64 nr_sleeping; /* Number of tasks sleeping */ - __u64 nr_running; /* Number of tasks running */ - __u64 nr_stopped; /* Number of tasks in stopped state */ - __u64 nr_uninterruptible; /* Number of tasks in uninterruptible */ - /* state */ - __u64 nr_io_wait; /* Number of tasks waiting on IO */ -}; - -/* - * Commands sent from userspace - * Not versioned. New commands should only be inserted at the enum's end - * prior to __CGROUPSTATS_CMD_MAX - */ - -enum { - CGROUPSTATS_CMD_UNSPEC = __TASKSTATS_CMD_MAX, /* Reserved */ - CGROUPSTATS_CMD_GET, /* user->kernel request/get-response */ - CGROUPSTATS_CMD_NEW, /* kernel->user event */ - __CGROUPSTATS_CMD_MAX, -}; - -#define CGROUPSTATS_CMD_MAX (__CGROUPSTATS_CMD_MAX - 1) - -enum { - CGROUPSTATS_TYPE_UNSPEC = 0, /* Reserved */ - CGROUPSTATS_TYPE_CGROUP_STATS, /* contains name + stats */ - __CGROUPSTATS_TYPE_MAX, -}; - -#define CGROUPSTATS_TYPE_MAX (__CGROUPSTATS_TYPE_MAX - 1) - -enum { - CGROUPSTATS_CMD_ATTR_UNSPEC = 0, - CGROUPSTATS_CMD_ATTR_FD, - __CGROUPSTATS_CMD_ATTR_MAX, -}; - -#define CGROUPSTATS_CMD_ATTR_MAX (__CGROUPSTATS_CMD_ATTR_MAX - 1) - -#endif /* _LINUX_CGROUPSTATS_H */ diff --git a/trunk/include/linux/clocksource.h b/trunk/include/linux/clocksource.h index 107787aacb64..16ea3374dddf 100644 --- a/trunk/include/linux/clocksource.h +++ b/trunk/include/linux/clocksource.h @@ -221,15 +221,10 @@ extern void clocksource_resume(void); #ifdef CONFIG_GENERIC_TIME_VSYSCALL extern void update_vsyscall(struct timespec *ts, struct clocksource *c); -extern void update_vsyscall_tz(void); #else static inline void update_vsyscall(struct timespec *ts, struct clocksource *c) { } - -static inline void update_vsyscall_tz(void) -{ -} #endif #endif /* _LINUX_CLOCKSOURCE_H */ diff --git a/trunk/include/linux/compiler-gcc.h b/trunk/include/linux/compiler-gcc.h index fe23792f05c1..acd583384bd9 100644 --- a/trunk/include/linux/compiler-gcc.h +++ b/trunk/include/linux/compiler-gcc.h @@ -36,20 +36,10 @@ #define __weak __attribute__((weak)) #define __naked __attribute__((naked)) #define __noreturn __attribute__((noreturn)) - -/* - * From the GCC manual: - * - * Many functions have no effects except the return value and their - * return value depends only on the parameters and/or global - * variables. Such a function can be subject to common subexpression - * elimination and loop optimization just as an arithmetic operator - * would be. - * [...] - */ #define __pure __attribute__((pure)) #define __aligned(x) __attribute__((aligned(x))) #define __printf(a,b) __attribute__((format(printf,a,b))) #define noinline __attribute__((noinline)) +#define __attribute_pure__ __attribute__((pure)) #define __attribute_const__ __attribute__((__const__)) #define __maybe_unused __attribute__((unused)) diff --git a/trunk/include/linux/compiler.h b/trunk/include/linux/compiler.h index c811c8b979ac..86f9a3a6137d 100644 --- a/trunk/include/linux/compiler.h +++ b/trunk/include/linux/compiler.h @@ -132,6 +132,20 @@ extern void __chk_io_ptr(const volatile void __iomem *); # define __maybe_unused /* unimplemented */ #endif +/* + * From the GCC manual: + * + * Many functions have no effects except the return value and their + * return value depends only on the parameters and/or global + * variables. Such a function can be subject to common subexpression + * elimination and loop optimization just as an arithmetic operator + * would be. + * [...] + */ +#ifndef __attribute_pure__ +# define __attribute_pure__ /* unimplemented */ +#endif + #ifndef noinline #define noinline #endif diff --git a/trunk/include/linux/console.h b/trunk/include/linux/console.h index a5f88a6a259d..0a4542ddb73d 100644 --- a/trunk/include/linux/console.h +++ b/trunk/include/linux/console.h @@ -122,11 +122,14 @@ extern void console_stop(struct console *); extern void console_start(struct console *); extern int is_console_locked(void); -extern int console_suspend_enabled; - +#ifndef CONFIG_DISABLE_CONSOLE_SUSPEND /* Suspend and resume console messages over PM events */ extern void suspend_console(void); extern void resume_console(void); +#else +static inline void suspend_console(void) {} +static inline void resume_console(void) {} +#endif /* CONFIG_DISABLE_CONSOLE_SUSPEND */ int mda_console_init(void); void prom_con_init(void); diff --git a/trunk/include/linux/cpu.h b/trunk/include/linux/cpu.h index b79c57569367..0ad72c4cf312 100644 --- a/trunk/include/linux/cpu.h +++ b/trunk/include/linux/cpu.h @@ -119,9 +119,8 @@ static inline void cpuhotplug_mutex_unlock(struct mutex *cpu_hp_mutex) #define lock_cpu_hotplug() do { } while (0) #define unlock_cpu_hotplug() do { } while (0) #define hotcpu_notifier(fn, pri) do { (void)(fn); } while (0) -/* These aren't inline functions due to a GCC bug. */ -#define register_hotcpu_notifier(nb) ({ (void)(nb); 0; }) -#define unregister_hotcpu_notifier(nb) ({ (void)(nb); }) +#define register_hotcpu_notifier(nb) do { (void)(nb); } while (0) +#define unregister_hotcpu_notifier(nb) do { (void)(nb); } while (0) /* CPUs don't go offline once they're online w/o CONFIG_HOTPLUG_CPU */ static inline int cpu_is_offline(int cpu) { return 0; } diff --git a/trunk/include/linux/cpu_acct.h b/trunk/include/linux/cpu_acct.h deleted file mode 100644 index 6b5fd8a66c8d..000000000000 --- a/trunk/include/linux/cpu_acct.h +++ /dev/null @@ -1,14 +0,0 @@ - -#ifndef _LINUX_CPU_ACCT_H -#define _LINUX_CPU_ACCT_H - -#include -#include - -#ifdef CONFIG_CGROUP_CPUACCT -extern void cpuacct_charge(struct task_struct *, cputime_t cputime); -#else -static void inline cpuacct_charge(struct task_struct *p, cputime_t cputime) {} -#endif - -#endif diff --git a/trunk/include/linux/cpuidle.h b/trunk/include/linux/cpuidle.h deleted file mode 100644 index 16a51546db44..000000000000 --- a/trunk/include/linux/cpuidle.h +++ /dev/null @@ -1,180 +0,0 @@ -/* - * cpuidle.h - a generic framework for CPU idle power management - * - * (C) 2007 Venkatesh Pallipadi - * Shaohua Li - * Adam Belay - * - * This code is licenced under the GPL. - */ - -#ifndef _LINUX_CPUIDLE_H -#define _LINUX_CPUIDLE_H - -#include -#include -#include -#include -#include - -#define CPUIDLE_STATE_MAX 8 -#define CPUIDLE_NAME_LEN 16 - -struct cpuidle_device; - - -/**************************** - * CPUIDLE DEVICE INTERFACE * - ****************************/ - -struct cpuidle_state { - char name[CPUIDLE_NAME_LEN]; - void *driver_data; - - unsigned int flags; - unsigned int exit_latency; /* in US */ - unsigned int power_usage; /* in mW */ - unsigned int target_residency; /* in US */ - - unsigned int usage; - unsigned int time; /* in US */ - - int (*enter) (struct cpuidle_device *dev, - struct cpuidle_state *state); -}; - -/* Idle State Flags */ -#define CPUIDLE_FLAG_TIME_VALID (0x01) /* is residency time measurable? */ -#define CPUIDLE_FLAG_CHECK_BM (0x02) /* BM activity will exit state */ -#define CPUIDLE_FLAG_SHALLOW (0x10) /* low latency, minimal savings */ -#define CPUIDLE_FLAG_BALANCED (0x20) /* medium latency, moderate savings */ -#define CPUIDLE_FLAG_DEEP (0x40) /* high latency, large savings */ - -#define CPUIDLE_DRIVER_FLAGS_MASK (0xFFFF0000) - -/** - * cpuidle_get_statedata - retrieves private driver state data - * @state: the state - */ -static inline void * cpuidle_get_statedata(struct cpuidle_state *state) -{ - return state->driver_data; -} - -/** - * cpuidle_set_statedata - stores private driver state data - * @state: the state - * @data: the private data - */ -static inline void -cpuidle_set_statedata(struct cpuidle_state *state, void *data) -{ - state->driver_data = data; -} - -struct cpuidle_state_kobj { - struct cpuidle_state *state; - struct completion kobj_unregister; - struct kobject kobj; -}; - -struct cpuidle_device { - int enabled:1; - unsigned int cpu; - - int last_residency; - int state_count; - struct cpuidle_state states[CPUIDLE_STATE_MAX]; - struct cpuidle_state_kobj *kobjs[CPUIDLE_STATE_MAX]; - struct cpuidle_state *last_state; - - struct list_head device_list; - struct kobject kobj; - struct completion kobj_unregister; - void *governor_data; -}; - -DECLARE_PER_CPU(struct cpuidle_device *, cpuidle_devices); - -/** - * cpuidle_get_last_residency - retrieves the last state's residency time - * @dev: the target CPU - * - * NOTE: this value is invalid if CPUIDLE_FLAG_TIME_VALID isn't set - */ -static inline int cpuidle_get_last_residency(struct cpuidle_device *dev) -{ - return dev->last_residency; -} - - -/**************************** - * CPUIDLE DRIVER INTERFACE * - ****************************/ - -struct cpuidle_driver { - char name[CPUIDLE_NAME_LEN]; - struct module *owner; -}; - -#ifdef CONFIG_CPU_IDLE - -extern int cpuidle_register_driver(struct cpuidle_driver *drv); -extern void cpuidle_unregister_driver(struct cpuidle_driver *drv); -extern int cpuidle_register_device(struct cpuidle_device *dev); -extern void cpuidle_unregister_device(struct cpuidle_device *dev); - -extern void cpuidle_pause_and_lock(void); -extern void cpuidle_resume_and_unlock(void); -extern int cpuidle_enable_device(struct cpuidle_device *dev); -extern void cpuidle_disable_device(struct cpuidle_device *dev); - -#else - -static inline int cpuidle_register_driver(struct cpuidle_driver *drv) -{return 0;} -static inline void cpuidle_unregister_driver(struct cpuidle_driver *drv) { } -static inline int cpuidle_register_device(struct cpuidle_device *dev) -{return 0;} -static inline void cpuidle_unregister_device(struct cpuidle_device *dev) { } - -static inline void cpuidle_pause_and_lock(void) { } -static inline void cpuidle_resume_and_unlock(void) { } -static inline int cpuidle_enable_device(struct cpuidle_device *dev) -{return 0;} -static inline void cpuidle_disable_device(struct cpuidle_device *dev) { } - -#endif - -/****************************** - * CPUIDLE GOVERNOR INTERFACE * - ******************************/ - -struct cpuidle_governor { - char name[CPUIDLE_NAME_LEN]; - struct list_head governor_list; - unsigned int rating; - - int (*enable) (struct cpuidle_device *dev); - void (*disable) (struct cpuidle_device *dev); - - int (*select) (struct cpuidle_device *dev); - void (*reflect) (struct cpuidle_device *dev); - - struct module *owner; -}; - -#ifdef CONFIG_CPU_IDLE - -extern int cpuidle_register_governor(struct cpuidle_governor *gov); -extern void cpuidle_unregister_governor(struct cpuidle_governor *gov); - -#else - -static inline int cpuidle_register_governor(struct cpuidle_governor *gov) -{return 0;} -static inline void cpuidle_unregister_governor(struct cpuidle_governor *gov) { } - -#endif - -#endif /* _LINUX_CPUIDLE_H */ diff --git a/trunk/include/linux/cpuset.h b/trunk/include/linux/cpuset.h index ecae585ec3da..ea44d2e768a0 100644 --- a/trunk/include/linux/cpuset.h +++ b/trunk/include/linux/cpuset.h @@ -11,7 +11,6 @@ #include #include #include -#include #ifdef CONFIG_CPUSETS @@ -20,8 +19,9 @@ extern int number_of_cpusets; /* How many cpusets are defined in system? */ extern int cpuset_init_early(void); extern int cpuset_init(void); extern void cpuset_init_smp(void); +extern void cpuset_fork(struct task_struct *p); +extern void cpuset_exit(struct task_struct *p); extern cpumask_t cpuset_cpus_allowed(struct task_struct *p); -extern cpumask_t cpuset_cpus_allowed_locked(struct task_struct *p); extern nodemask_t cpuset_mems_allowed(struct task_struct *p); #define cpuset_current_mems_allowed (current->mems_allowed) void cpuset_init_current_mems_allowed(void); @@ -76,22 +76,18 @@ static inline int cpuset_do_slab_mem_spread(void) extern void cpuset_track_online_nodes(void); -extern int current_cpuset_is_being_rebound(void); - #else /* !CONFIG_CPUSETS */ static inline int cpuset_init_early(void) { return 0; } static inline int cpuset_init(void) { return 0; } static inline void cpuset_init_smp(void) {} +static inline void cpuset_fork(struct task_struct *p) {} +static inline void cpuset_exit(struct task_struct *p) {} static inline cpumask_t cpuset_cpus_allowed(struct task_struct *p) { return cpu_possible_map; } -static inline cpumask_t cpuset_cpus_allowed_locked(struct task_struct *p) -{ - return cpu_possible_map; -} static inline nodemask_t cpuset_mems_allowed(struct task_struct *p) { @@ -152,11 +148,6 @@ static inline int cpuset_do_slab_mem_spread(void) static inline void cpuset_track_online_nodes(void) {} -static inline int current_cpuset_is_being_rebound(void) -{ - return 0; -} - #endif /* !CONFIG_CPUSETS */ #endif /* _LINUX_CPUSET_H */ diff --git a/trunk/include/linux/cyclades.h b/trunk/include/linux/cyclades.h index 8f3dcd30828f..72aa00cc4b2d 100644 --- a/trunk/include/linux/cyclades.h +++ b/trunk/include/linux/cyclades.h @@ -512,11 +512,11 @@ struct cyclades_card { void __iomem *base_addr; void __iomem *ctl_addr; int irq; - unsigned int num_chips; /* 0 if card absent, -1 if Z/PCI, else Y */ - unsigned int first_line; /* minor number of first channel on card */ - unsigned int nports; /* Number of ports in the card */ - int bus_index; /* address shift - 0 for ISA, 1 for PCI */ - int intr_enabled; /* FW Interrupt flag - 0 disabled, 1 enabled */ + int num_chips; /* 0 if card absent, -1 if Z/PCI, else Y */ + int first_line; /* minor number of first channel on card */ + int nports; /* Number of ports in the card */ + int bus_index; /* address shift - 0 for ISA, 1 for PCI */ + int intr_enabled; /* FW Interrupt flag - 0 disabled, 1 enabled */ spinlock_t card_lock; struct cyclades_port *ports; }; @@ -566,9 +566,10 @@ struct cyclades_port { int rtsdtr_inv; int chip_rev; int custom_divisor; - u8 x_char; /* to be pushed out ASAP */ + int x_char; /* to be pushed out ASAP */ int close_delay; unsigned short closing_wait; + unsigned long event; int count; /* # of fd on device */ int breakon; int breakoff; @@ -583,6 +584,7 @@ struct cyclades_port { struct cyclades_monitor mon; struct cyclades_idle_stats idle_stats; struct cyclades_icount icount; + struct work_struct tqueue; wait_queue_head_t open_wait; wait_queue_head_t close_wait; struct completion shutdown_wait; @@ -590,6 +592,19 @@ struct cyclades_port { int throttle; }; +/* + * Events are used to schedule things to happen at timer-interrupt + * time, instead of at cy interrupt time. + */ +#define Cy_EVENT_READ_PROCESS 0 +#define Cy_EVENT_WRITE_WAKEUP 1 +#define Cy_EVENT_HANGUP 2 +#define Cy_EVENT_BREAK 3 +#define Cy_EVENT_OPEN_WAKEUP 4 +#define Cy_EVENT_SHUTDOWN_WAKEUP 5 +#define Cy_EVENT_DELTA_WAKEUP 6 +#define Cy_EVENT_Z_RX_FULL 7 + #define CLOSING_WAIT_DELAY 30*HZ #define CY_CLOSING_WAIT_NONE 65535 #define CY_CLOSING_WAIT_INF 0 diff --git a/trunk/include/linux/delayacct.h b/trunk/include/linux/delayacct.h index ab94bc083558..55d1ca5e60f5 100644 --- a/trunk/include/linux/delayacct.h +++ b/trunk/include/linux/delayacct.h @@ -26,7 +26,6 @@ * Used to set current->delays->flags */ #define DELAYACCT_PF_SWAPIN 0x00000001 /* I am doing a swapin */ -#define DELAYACCT_PF_BLKIO 0x00000002 /* I am waiting on IO */ #ifdef CONFIG_TASK_DELAY_ACCT @@ -40,14 +39,6 @@ extern void __delayacct_blkio_end(void); extern int __delayacct_add_tsk(struct taskstats *, struct task_struct *); extern __u64 __delayacct_blkio_ticks(struct task_struct *); -static inline int delayacct_is_task_waiting_on_io(struct task_struct *p) -{ - if (p->delays) - return (p->delays->flags & DELAYACCT_PF_BLKIO); - else - return 0; -} - static inline void delayacct_set_flag(int flag) { if (current->delays) @@ -80,7 +71,6 @@ static inline void delayacct_tsk_free(struct task_struct *tsk) static inline void delayacct_blkio_start(void) { - delayacct_set_flag(DELAYACCT_PF_BLKIO); if (current->delays) __delayacct_blkio_start(); } @@ -89,7 +79,6 @@ static inline void delayacct_blkio_end(void) { if (current->delays) __delayacct_blkio_end(); - delayacct_clear_flag(DELAYACCT_PF_BLKIO); } static inline int delayacct_add_tsk(struct taskstats *d, @@ -127,8 +116,6 @@ static inline int delayacct_add_tsk(struct taskstats *d, { return 0; } static inline __u64 delayacct_blkio_ticks(struct task_struct *tsk) { return 0; } -static inline int delayacct_is_task_waiting_on_io(struct task_struct *p) -{ return 0; } #endif /* CONFIG_TASK_DELAY_ACCT */ #endif diff --git a/trunk/include/linux/dma-mapping.h b/trunk/include/linux/dma-mapping.h index 101a2d4636be..0ebfafbd338c 100644 --- a/trunk/include/linux/dma-mapping.h +++ b/trunk/include/linux/dma-mapping.h @@ -13,26 +13,16 @@ enum dma_data_direction { DMA_NONE = 3, }; -#define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1)) - -/* - * NOTE: do not use the below macros in new code and do not add new definitions - * here. - * - * Instead, just open-code DMA_BIT_MASK(n) within your driver - */ -#define DMA_64BIT_MASK DMA_BIT_MASK(64) -#define DMA_48BIT_MASK DMA_BIT_MASK(48) -#define DMA_47BIT_MASK DMA_BIT_MASK(47) -#define DMA_40BIT_MASK DMA_BIT_MASK(40) -#define DMA_39BIT_MASK DMA_BIT_MASK(39) -#define DMA_35BIT_MASK DMA_BIT_MASK(35) -#define DMA_32BIT_MASK DMA_BIT_MASK(32) -#define DMA_31BIT_MASK DMA_BIT_MASK(31) -#define DMA_30BIT_MASK DMA_BIT_MASK(30) -#define DMA_29BIT_MASK DMA_BIT_MASK(29) -#define DMA_28BIT_MASK DMA_BIT_MASK(28) -#define DMA_24BIT_MASK DMA_BIT_MASK(24) +#define DMA_64BIT_MASK 0xffffffffffffffffULL +#define DMA_48BIT_MASK 0x0000ffffffffffffULL +#define DMA_40BIT_MASK 0x000000ffffffffffULL +#define DMA_39BIT_MASK 0x0000007fffffffffULL +#define DMA_32BIT_MASK 0x00000000ffffffffULL +#define DMA_31BIT_MASK 0x000000007fffffffULL +#define DMA_30BIT_MASK 0x000000003fffffffULL +#define DMA_29BIT_MASK 0x000000001fffffffULL +#define DMA_28BIT_MASK 0x000000000fffffffULL +#define DMA_24BIT_MASK 0x0000000000ffffffULL #define DMA_MASK_NONE 0x0ULL diff --git a/trunk/include/linux/ext3_fs.h b/trunk/include/linux/ext3_fs.h index 64134456ed8c..589b0b355d84 100644 --- a/trunk/include/linux/ext3_fs.h +++ b/trunk/include/linux/ext3_fs.h @@ -72,8 +72,8 @@ * Macro-instructions used to manage several block sizes */ #define EXT3_MIN_BLOCK_SIZE 1024 -#define EXT3_MAX_BLOCK_SIZE 65536 -#define EXT3_MIN_BLOCK_LOG_SIZE 10 +#define EXT3_MAX_BLOCK_SIZE 4096 +#define EXT3_MIN_BLOCK_LOG_SIZE 10 #ifdef __KERNEL__ # define EXT3_BLOCK_SIZE(s) ((s)->s_blocksize) #else diff --git a/trunk/include/linux/ext4_fs.h b/trunk/include/linux/ext4_fs.h index 97dd409d5f4a..cdee7aaa57aa 100644 --- a/trunk/include/linux/ext4_fs.h +++ b/trunk/include/linux/ext4_fs.h @@ -36,6 +36,10 @@ /*max window size: 1024(direct blocks) + 3([t,d]indirect blocks) */ #define EXT4_MAX_RESERVE_BLOCKS 1027 #define EXT4_RESERVE_WINDOW_NOT_ALLOCATED 0 +/* + * Always enable hashed directories + */ +#define CONFIG_EXT4_INDEX /* * Debug code @@ -100,30 +104,38 @@ #endif #define EXT4_BLOCK_ALIGN(size, blkbits) ALIGN((size), (1 << (blkbits))) +/* + * Macro-instructions used to manage fragments + */ +#define EXT4_MIN_FRAG_SIZE 1024 +#define EXT4_MAX_FRAG_SIZE 4096 +#define EXT4_MIN_FRAG_LOG_SIZE 10 +#ifdef __KERNEL__ +# define EXT4_FRAG_SIZE(s) (EXT4_SB(s)->s_frag_size) +# define EXT4_FRAGS_PER_BLOCK(s) (EXT4_SB(s)->s_frags_per_block) +#else +# define EXT4_FRAG_SIZE(s) (EXT4_MIN_FRAG_SIZE << (s)->s_log_frag_size) +# define EXT4_FRAGS_PER_BLOCK(s) (EXT4_BLOCK_SIZE(s) / EXT4_FRAG_SIZE(s)) +#endif + /* * Structure of a blocks group descriptor */ struct ext4_group_desc { - __le32 bg_block_bitmap_lo; /* Blocks bitmap block */ - __le32 bg_inode_bitmap_lo; /* Inodes bitmap block */ - __le32 bg_inode_table_lo; /* Inodes table block */ + __le32 bg_block_bitmap; /* Blocks bitmap block */ + __le32 bg_inode_bitmap; /* Inodes bitmap block */ + __le32 bg_inode_table; /* Inodes table block */ __le16 bg_free_blocks_count; /* Free blocks count */ __le16 bg_free_inodes_count; /* Free inodes count */ __le16 bg_used_dirs_count; /* Directories count */ - __le16 bg_flags; /* EXT4_BG_flags (INODE_UNINIT, etc) */ - __u32 bg_reserved[2]; /* Likely block/inode bitmap checksum */ - __le16 bg_itable_unused; /* Unused inodes count */ - __le16 bg_checksum; /* crc16(sb_uuid+group+desc) */ + __u16 bg_flags; + __u32 bg_reserved[3]; __le32 bg_block_bitmap_hi; /* Blocks bitmap block MSB */ __le32 bg_inode_bitmap_hi; /* Inodes bitmap block MSB */ __le32 bg_inode_table_hi; /* Inodes table block MSB */ }; -#define EXT4_BG_INODE_UNINIT 0x0001 /* Inode table/bitmap not in use */ -#define EXT4_BG_BLOCK_UNINIT 0x0002 /* Block bitmap not in use */ -#define EXT4_BG_INODE_ZEROED 0x0004 /* On-disk itable initialized to zero */ - #ifdef __KERNEL__ #include #include @@ -299,24 +311,27 @@ struct ext4_inode { __le32 i_generation; /* File version (for NFS) */ __le32 i_file_acl; /* File ACL */ __le32 i_dir_acl; /* Directory ACL */ - __le32 i_obso_faddr; /* Obsoleted fragment address */ + __le32 i_faddr; /* Fragment address */ union { struct { - __le16 l_i_reserved1; /* Obsoleted fragment number/size which are removed in ext4 */ + __u8 l_i_frag; /* Fragment number */ + __u8 l_i_fsize; /* Fragment size */ __le16 l_i_file_acl_high; __le16 l_i_uid_high; /* these 2 fields */ __le16 l_i_gid_high; /* were reserved2[0] */ __u32 l_i_reserved2; } linux2; struct { - __le16 h_i_reserved1; /* Obsoleted fragment number/size which are removed in ext4 */ + __u8 h_i_frag; /* Fragment number */ + __u8 h_i_fsize; /* Fragment size */ __u16 h_i_mode_high; __u16 h_i_uid_high; __u16 h_i_gid_high; __u32 h_i_author; } hurd2; struct { - __le16 h_i_reserved1; /* Obsoleted fragment number/size which are removed in ext4 */ + __u8 m_i_frag; /* Fragment number */ + __u8 m_i_fsize; /* Fragment size */ __le16 m_i_file_acl_high; __u32 m_i_reserved2[2]; } masix2; @@ -404,6 +419,8 @@ do { \ #if defined(__KERNEL__) || defined(__linux__) #define i_reserved1 osd1.linux1.l_i_reserved1 +#define i_frag osd2.linux2.l_i_frag +#define i_fsize osd2.linux2.l_i_fsize #define i_file_acl_high osd2.linux2.l_i_file_acl_high #define i_uid_low i_uid #define i_gid_low i_gid @@ -414,6 +431,8 @@ do { \ #elif defined(__GNU__) #define i_translator osd1.hurd1.h_i_translator +#define i_frag osd2.hurd2.h_i_frag; +#define i_fsize osd2.hurd2.h_i_fsize; #define i_uid_high osd2.hurd2.h_i_uid_high #define i_gid_high osd2.hurd2.h_i_gid_high #define i_author osd2.hurd2.h_i_author @@ -421,6 +440,8 @@ do { \ #elif defined(__masix__) #define i_reserved1 osd1.masix1.m_i_reserved1 +#define i_frag osd2.masix2.m_i_frag +#define i_fsize osd2.masix2.m_i_fsize #define i_file_acl_high osd2.masix2.m_i_file_acl_high #define i_reserved2 osd2.masix2.m_i_reserved2 @@ -501,15 +522,15 @@ do { \ */ struct ext4_super_block { /*00*/ __le32 s_inodes_count; /* Inodes count */ - __le32 s_blocks_count_lo; /* Blocks count */ - __le32 s_r_blocks_count_lo; /* Reserved blocks count */ - __le32 s_free_blocks_count_lo; /* Free blocks count */ + __le32 s_blocks_count; /* Blocks count */ + __le32 s_r_blocks_count; /* Reserved blocks count */ + __le32 s_free_blocks_count; /* Free blocks count */ /*10*/ __le32 s_free_inodes_count; /* Free inodes count */ __le32 s_first_data_block; /* First Data Block */ __le32 s_log_block_size; /* Block size */ - __le32 s_obso_log_frag_size; /* Obsoleted fragment size */ + __le32 s_log_frag_size; /* Fragment size */ /*20*/ __le32 s_blocks_per_group; /* # Blocks per group */ - __le32 s_obso_frags_per_group; /* Obsoleted fragments per group */ + __le32 s_frags_per_group; /* # Fragments per group */ __le32 s_inodes_per_group; /* # Inodes per group */ __le32 s_mtime; /* Mount time */ /*30*/ __le32 s_wtime; /* Write time */ @@ -574,13 +595,13 @@ struct ext4_super_block { /*150*/ __le32 s_blocks_count_hi; /* Blocks count */ __le32 s_r_blocks_count_hi; /* Reserved blocks count */ __le32 s_free_blocks_count_hi; /* Free blocks count */ - __le16 s_min_extra_isize; /* All inodes have at least # bytes */ - __le16 s_want_extra_isize; /* New inodes should reserve # bytes */ - __le32 s_flags; /* Miscellaneous flags */ - __le16 s_raid_stride; /* RAID stride */ - __le16 s_mmp_interval; /* # seconds to wait in MMP checking */ - __le64 s_mmp_block; /* Block for multi-mount protection */ - __le32 s_raid_stripe_width; /* blocks on all data disks (N*stride)*/ + __u16 s_min_extra_isize; /* All inodes have at least # bytes */ + __u16 s_want_extra_isize; /* New inodes should reserve # bytes */ + __u32 s_flags; /* Miscellaneous flags */ + __u16 s_raid_stride; /* RAID stride */ + __u16 s_mmp_interval; /* # seconds to wait in MMP checking */ + __u64 s_mmp_block; /* Block for multi-mount protection */ + __u32 s_raid_stripe_width; /* blocks on all data disks (N*stride)*/ __u32 s_reserved[163]; /* Padding to the end of the block */ }; @@ -671,7 +692,6 @@ static inline int ext4_valid_inum(struct super_block *sb, unsigned long ino) #define EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001 #define EXT4_FEATURE_RO_COMPAT_LARGE_FILE 0x0002 #define EXT4_FEATURE_RO_COMPAT_BTREE_DIR 0x0004 -#define EXT4_FEATURE_RO_COMPAT_GDT_CSUM 0x0010 #define EXT4_FEATURE_RO_COMPAT_DIR_NLINK 0x0020 #define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE 0x0040 @@ -682,18 +702,15 @@ static inline int ext4_valid_inum(struct super_block *sb, unsigned long ino) #define EXT4_FEATURE_INCOMPAT_META_BG 0x0010 #define EXT4_FEATURE_INCOMPAT_EXTENTS 0x0040 /* extents support */ #define EXT4_FEATURE_INCOMPAT_64BIT 0x0080 -#define EXT4_FEATURE_INCOMPAT_FLEX_BG 0x0200 #define EXT4_FEATURE_COMPAT_SUPP EXT2_FEATURE_COMPAT_EXT_ATTR #define EXT4_FEATURE_INCOMPAT_SUPP (EXT4_FEATURE_INCOMPAT_FILETYPE| \ EXT4_FEATURE_INCOMPAT_RECOVER| \ EXT4_FEATURE_INCOMPAT_META_BG| \ EXT4_FEATURE_INCOMPAT_EXTENTS| \ - EXT4_FEATURE_INCOMPAT_64BIT| \ - EXT4_FEATURE_INCOMPAT_FLEX_BG) + EXT4_FEATURE_INCOMPAT_64BIT) #define EXT4_FEATURE_RO_COMPAT_SUPP (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER| \ EXT4_FEATURE_RO_COMPAT_LARGE_FILE| \ - EXT4_FEATURE_RO_COMPAT_GDT_CSUM| \ EXT4_FEATURE_RO_COMPAT_DIR_NLINK | \ EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE | \ EXT4_FEATURE_RO_COMPAT_BTREE_DIR) @@ -772,11 +789,17 @@ struct ext4_dir_entry_2 { * (c) Daniel Phillips, 2001 */ -#define is_dx(dir) (EXT4_HAS_COMPAT_FEATURE(dir->i_sb, \ - EXT4_FEATURE_COMPAT_DIR_INDEX) && \ +#ifdef CONFIG_EXT4_INDEX + #define is_dx(dir) (EXT4_HAS_COMPAT_FEATURE(dir->i_sb, \ + EXT4_FEATURE_COMPAT_DIR_INDEX) && \ (EXT4_I(dir)->i_flags & EXT4_INDEX_FL)) #define EXT4_DIR_LINK_MAX(dir) (!is_dx(dir) && (dir)->i_nlink >= EXT4_LINK_MAX) #define EXT4_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2 || (dir)->i_nlink == 1) +#else + #define is_dx(dir) 0 +#define EXT4_DIR_LINK_MAX(dir) ((dir)->i_nlink >= EXT4_LINK_MAX) +#define EXT4_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2) +#endif /* Legal values for the dx_root hash_version field: */ @@ -981,39 +1004,39 @@ extern void ext4_inode_table_set(struct super_block *sb, static inline ext4_fsblk_t ext4_blocks_count(struct ext4_super_block *es) { return ((ext4_fsblk_t)le32_to_cpu(es->s_blocks_count_hi) << 32) | - le32_to_cpu(es->s_blocks_count_lo); + le32_to_cpu(es->s_blocks_count); } static inline ext4_fsblk_t ext4_r_blocks_count(struct ext4_super_block *es) { return ((ext4_fsblk_t)le32_to_cpu(es->s_r_blocks_count_hi) << 32) | - le32_to_cpu(es->s_r_blocks_count_lo); + le32_to_cpu(es->s_r_blocks_count); } static inline ext4_fsblk_t ext4_free_blocks_count(struct ext4_super_block *es) { return ((ext4_fsblk_t)le32_to_cpu(es->s_free_blocks_count_hi) << 32) | - le32_to_cpu(es->s_free_blocks_count_lo); + le32_to_cpu(es->s_free_blocks_count); } static inline void ext4_blocks_count_set(struct ext4_super_block *es, ext4_fsblk_t blk) { - es->s_blocks_count_lo = cpu_to_le32((u32)blk); + es->s_blocks_count = cpu_to_le32((u32)blk); es->s_blocks_count_hi = cpu_to_le32(blk >> 32); } static inline void ext4_free_blocks_count_set(struct ext4_super_block *es, ext4_fsblk_t blk) { - es->s_free_blocks_count_lo = cpu_to_le32((u32)blk); + es->s_free_blocks_count = cpu_to_le32((u32)blk); es->s_free_blocks_count_hi = cpu_to_le32(blk >> 32); } static inline void ext4_r_blocks_count_set(struct ext4_super_block *es, ext4_fsblk_t blk) { - es->s_r_blocks_count_lo = cpu_to_le32((u32)blk); + es->s_r_blocks_count = cpu_to_le32((u32)blk); es->s_r_blocks_count_hi = cpu_to_le32(blk >> 32); } diff --git a/trunk/include/linux/ext4_fs_extents.h b/trunk/include/linux/ext4_fs_extents.h index d2045a26195d..81406f3655d4 100644 --- a/trunk/include/linux/ext4_fs_extents.h +++ b/trunk/include/linux/ext4_fs_extents.h @@ -74,7 +74,7 @@ struct ext4_extent { __le32 ee_block; /* first logical block extent covers */ __le16 ee_len; /* number of blocks covered by extent */ __le16 ee_start_hi; /* high 16 bits of physical block */ - __le32 ee_start_lo; /* low 32 bits of physical block */ + __le32 ee_start; /* low 32 bits of physical block */ }; /* @@ -83,7 +83,7 @@ struct ext4_extent { */ struct ext4_extent_idx { __le32 ei_block; /* index covers logical blocks from 'block' */ - __le32 ei_leaf_lo; /* pointer to the physical block of the next * + __le32 ei_leaf; /* pointer to the physical block of the next * * level. leaf or next index could be there */ __le16 ei_leaf_hi; /* high 16 bits of physical block */ __u16 ei_unused; diff --git a/trunk/include/linux/ext4_fs_i.h b/trunk/include/linux/ext4_fs_i.h index 86ddfe2089f3..1a511e9905aa 100644 --- a/trunk/include/linux/ext4_fs_i.h +++ b/trunk/include/linux/ext4_fs_i.h @@ -78,6 +78,11 @@ struct ext4_ext_cache { struct ext4_inode_info { __le32 i_data[15]; /* unconverted */ __u32 i_flags; +#ifdef EXT4_FRAGMENTS + __u32 i_faddr; + __u8 i_frag_no; + __u8 i_frag_size; +#endif ext4_fsblk_t i_file_acl; __u32 i_dir_acl; __u32 i_dtime; diff --git a/trunk/include/linux/ext4_fs_sb.h b/trunk/include/linux/ext4_fs_sb.h index b40e827cd495..0a8e47d47c91 100644 --- a/trunk/include/linux/ext4_fs_sb.h +++ b/trunk/include/linux/ext4_fs_sb.h @@ -28,8 +28,11 @@ * third extended-fs super-block data in memory */ struct ext4_sb_info { + unsigned long s_frag_size; /* Size of a fragment in bytes */ unsigned long s_desc_size; /* Size of a group descriptor in bytes */ + unsigned long s_frags_per_block;/* Number of fragments per block */ unsigned long s_inodes_per_block;/* Number of inodes per block */ + unsigned long s_frags_per_group;/* Number of fragments in a group */ unsigned long s_blocks_per_group;/* Number of blocks in a group */ unsigned long s_inodes_per_group;/* Number of inodes in a group */ unsigned long s_itb_per_group; /* Number of inode table blocks per group */ diff --git a/trunk/include/linux/ext4_jbd2.h b/trunk/include/linux/ext4_jbd2.h index 38c71d3c8dbf..d716e6392cf6 100644 --- a/trunk/include/linux/ext4_jbd2.h +++ b/trunk/include/linux/ext4_jbd2.h @@ -12,8 +12,8 @@ * Ext4-specific journaling extensions. */ -#ifndef _LINUX_EXT4_JBD2_H -#define _LINUX_EXT4_JBD2_H +#ifndef _LINUX_EXT4_JBD_H +#define _LINUX_EXT4_JBD_H #include #include @@ -228,4 +228,4 @@ static inline int ext4_should_writeback_data(struct inode *inode) return 0; } -#endif /* _LINUX_EXT4_JBD2_H */ +#endif /* _LINUX_EXT4_JBD_H */ diff --git a/trunk/include/linux/filter.h b/trunk/include/linux/filter.h index ddfa0372a3b7..91b2e3b9251e 100644 --- a/trunk/include/linux/filter.h +++ b/trunk/include/linux/filter.h @@ -146,7 +146,6 @@ struct sock; extern unsigned int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen); extern int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk); -extern int sk_detach_filter(struct sock *sk); extern int sk_chk_filter(struct sock_filter *filter, int flen); #endif /* __KERNEL__ */ diff --git a/trunk/include/linux/freezer.h b/trunk/include/linux/freezer.h index 08934995c7ab..efded00ad08c 100644 --- a/trunk/include/linux/freezer.h +++ b/trunk/include/linux/freezer.h @@ -4,7 +4,6 @@ #define FREEZER_H_INCLUDED #include -#include #ifdef CONFIG_PM_SLEEP /* @@ -127,36 +126,6 @@ static inline void set_freezable(void) current->flags &= ~PF_NOFREEZE; } -/* - * Freezer-friendly wrappers around wait_event_interruptible() and - * wait_event_interruptible_timeout(), originally defined in - */ - -#define wait_event_freezable(wq, condition) \ -({ \ - int __retval; \ - do { \ - __retval = wait_event_interruptible(wq, \ - (condition) || freezing(current)); \ - if (__retval && !freezing(current)) \ - break; \ - else if (!(condition)) \ - __retval = -ERESTARTSYS; \ - } while (try_to_freeze()); \ - __retval; \ -}) - - -#define wait_event_freezable_timeout(wq, condition, timeout) \ -({ \ - long __retval = timeout; \ - do { \ - __retval = wait_event_interruptible_timeout(wq, \ - (condition) || freezing(current), \ - __retval); \ - } while (try_to_freeze()); \ - __retval; \ -}) #else /* !CONFIG_PM_SLEEP */ static inline int frozen(struct task_struct *p) { return 0; } static inline int freezing(struct task_struct *p) { return 0; } @@ -174,13 +143,6 @@ static inline void freezer_do_not_count(void) {} static inline void freezer_count(void) {} static inline int freezer_should_skip(struct task_struct *p) { return 0; } static inline void set_freezable(void) {} - -#define wait_event_freezable(wq, condition) \ - wait_event_interruptible(wq, condition) - -#define wait_event_freezable_timeout(wq, condition, timeout) \ - wait_event_interruptible_timeout(wq, condition, timeout) - #endif /* !CONFIG_PM_SLEEP */ #endif /* FREEZER_H_INCLUDED */ diff --git a/trunk/include/linux/fs.h b/trunk/include/linux/fs.h index 1657e995f72c..e3fc5dbb2246 100644 --- a/trunk/include/linux/fs.h +++ b/trunk/include/linux/fs.h @@ -123,7 +123,6 @@ extern int dir_notify_enable; #define MS_SLAVE (1<<19) /* change to slave */ #define MS_SHARED (1<<20) /* change to shared */ #define MS_RELATIME (1<<21) /* Update atime relative to mtime/ctime. */ -#define MS_KERNMOUNT (1<<22) /* this is a kern_mount call */ #define MS_ACTIVE (1<<30) #define MS_NOUSER (1<<31) @@ -331,7 +330,6 @@ typedef void (dio_iodone_t)(struct kiocb *iocb, loff_t offset, #define ATTR_KILL_SGID 4096 #define ATTR_FILE 8192 #define ATTR_KILL_PRIV 16384 -#define ATTR_OPEN 32768 /* Truncating from open(O_TRUNC) */ /* * This is the Inode Attributes structure, used for notify_change(). It @@ -1460,8 +1458,7 @@ void unnamed_dev_init(void); extern int register_filesystem(struct file_system_type *); extern int unregister_filesystem(struct file_system_type *); -extern struct vfsmount *kern_mount_data(struct file_system_type *, void *data); -#define kern_mount(type) kern_mount_data(type, NULL) +extern struct vfsmount *kern_mount(struct file_system_type *); extern int may_umount_tree(struct vfsmount *); extern int may_umount(struct vfsmount *); extern void umount_tree(struct vfsmount *, int, struct list_head *); @@ -1924,8 +1921,6 @@ extern int vfs_fstat(unsigned int, struct kstat *); extern int vfs_ioctl(struct file *, unsigned int, unsigned int, unsigned long); -extern void get_filesystem(struct file_system_type *fs); -extern void put_filesystem(struct file_system_type *fs); extern struct file_system_type *get_fs_type(const char *name); extern struct super_block *get_super(struct block_device *); extern struct super_block *user_get_super(dev_t); diff --git a/trunk/include/linux/fuse.h b/trunk/include/linux/fuse.h index d0c437028c80..9fbe9d258e22 100644 --- a/trunk/include/linux/fuse.h +++ b/trunk/include/linux/fuse.h @@ -6,17 +6,7 @@ See the file COPYING. */ -/* - * This file defines the kernel interface of FUSE - * - * Protocol changelog: - * - * 7.9: - * - new fuse_getattr_in input argument of GETATTR - * - add lk_flags in fuse_lk_in - * - add lock_owner field to fuse_setattr_in, fuse_read_in and fuse_write_in - * - add blksize field to fuse_attr - */ +/* This file defines the kernel interface of FUSE */ #include #include @@ -25,7 +15,7 @@ #define FUSE_KERNEL_VERSION 7 /** Minor version number of this interface */ -#define FUSE_KERNEL_MINOR_VERSION 9 +#define FUSE_KERNEL_MINOR_VERSION 8 /** The node ID of the root inode */ #define FUSE_ROOT_ID 1 @@ -54,8 +44,6 @@ struct fuse_attr { __u32 uid; __u32 gid; __u32 rdev; - __u32 blksize; - __u32 padding; }; struct fuse_kstatfs { @@ -88,9 +76,6 @@ struct fuse_file_lock { #define FATTR_ATIME (1 << 4) #define FATTR_MTIME (1 << 5) #define FATTR_FH (1 << 6) -#define FATTR_ATIME_NOW (1 << 7) -#define FATTR_MTIME_NOW (1 << 8) -#define FATTR_LOCKOWNER (1 << 9) /** * Flags returned by the OPEN request @@ -106,38 +91,12 @@ struct fuse_file_lock { */ #define FUSE_ASYNC_READ (1 << 0) #define FUSE_POSIX_LOCKS (1 << 1) -#define FUSE_FILE_OPS (1 << 2) -#define FUSE_ATOMIC_O_TRUNC (1 << 3) /** * Release flags */ #define FUSE_RELEASE_FLUSH (1 << 0) -/** - * Getattr flags - */ -#define FUSE_GETATTR_FH (1 << 0) - -/** - * Lock flags - */ -#define FUSE_LK_FLOCK (1 << 0) - -/** - * WRITE flags - * - * FUSE_WRITE_CACHE: delayed write from page cache, file handle is guessed - * FUSE_WRITE_LOCKOWNER: lock_owner field is valid - */ -#define FUSE_WRITE_CACHE (1 << 0) -#define FUSE_WRITE_LOCKOWNER (1 << 1) - -/** - * Read flags - */ -#define FUSE_READ_LOCKOWNER (1 << 1) - enum fuse_opcode { FUSE_LOOKUP = 1, FUSE_FORGET = 2, /* no reply */ @@ -180,8 +139,6 @@ enum fuse_opcode { /* The read buffer is required to be at least 8k, but may be much larger */ #define FUSE_MIN_READ_BUFFER 8192 -#define FUSE_COMPAT_ENTRY_OUT_SIZE 120 - struct fuse_entry_out { __u64 nodeid; /* Inode ID */ __u64 generation; /* Inode generation: nodeid:gen must @@ -197,14 +154,6 @@ struct fuse_forget_in { __u64 nlookup; }; -struct fuse_getattr_in { - __u32 getattr_flags; - __u32 dummy; - __u64 fh; -}; - -#define FUSE_COMPAT_ATTR_OUT_SIZE 96 - struct fuse_attr_out { __u64 attr_valid; /* Cache timeout for the attributes */ __u32 attr_valid_nsec; @@ -235,7 +184,7 @@ struct fuse_setattr_in { __u32 padding; __u64 fh; __u64 size; - __u64 lock_owner; + __u64 unused1; __u64 atime; __u64 mtime; __u64 unused2; @@ -278,18 +227,14 @@ struct fuse_read_in { __u64 fh; __u64 offset; __u32 size; - __u32 read_flags; - __u64 lock_owner; + __u32 padding; }; -#define FUSE_COMPAT_WRITE_IN_SIZE 24 - struct fuse_write_in { __u64 fh; __u64 offset; __u32 size; __u32 write_flags; - __u64 lock_owner; }; struct fuse_write_out { @@ -328,8 +273,6 @@ struct fuse_lk_in { __u64 fh; __u64 owner; struct fuse_file_lock lk; - __u32 lk_flags; - __u32 padding; }; struct fuse_lk_out { diff --git a/trunk/include/linux/hid.h b/trunk/include/linux/hid.h index 6e35b92b1d2c..edb8024d744b 100644 --- a/trunk/include/linux/hid.h +++ b/trunk/include/linux/hid.h @@ -469,8 +469,8 @@ struct hid_device { /* device report descriptor */ /* handler for raw output data, used by hidraw */ int (*hid_output_raw_report) (struct hid_device *, __u8 *, size_t); #ifdef CONFIG_USB_HIDINPUT_POWERBOOK - unsigned long pb_pressed_fn[BITS_TO_LONGS(KEY_CNT)]; - unsigned long pb_pressed_numlock[BITS_TO_LONGS(KEY_CNT)]; + unsigned long pb_pressed_fn[NBITS(KEY_MAX)]; + unsigned long pb_pressed_numlock[NBITS(KEY_MAX)]; #endif }; diff --git a/trunk/include/linux/hrtimer.h b/trunk/include/linux/hrtimer.h index 7a9398e19704..540799bc85f8 100644 --- a/trunk/include/linux/hrtimer.h +++ b/trunk/include/linux/hrtimer.h @@ -300,7 +300,7 @@ hrtimer_forward(struct hrtimer *timer, ktime_t now, ktime_t interval); /* Precise sleep: */ extern long hrtimer_nanosleep(struct timespec *rqtp, - struct timespec *rmtp, + struct timespec __user *rmtp, const enum hrtimer_mode mode, const clockid_t clockid); extern long hrtimer_nanosleep_restart(struct restart_block *restart_block); diff --git a/trunk/include/linux/ide.h b/trunk/include/linux/ide.h index 19db0a4ae447..e39ee2fa2607 100644 --- a/trunk/include/linux/ide.h +++ b/trunk/include/linux/ide.h @@ -685,6 +685,7 @@ typedef struct hwif_s { u8 pio_mask; + u8 atapi_dma; /* host supports atapi_dma */ u8 ultra_mask; u8 mwdma_mask; u8 swdma_mask; @@ -796,9 +797,12 @@ typedef struct hwif_s { unsigned serialized : 1; /* serialized all channel operation */ unsigned sharing_irq: 1; /* 1 = sharing irq with another hwif */ unsigned reset : 1; /* reset after probe */ + unsigned no_lba48 : 1; /* 1 = cannot do LBA48 */ + unsigned no_lba48_dma : 1; /* 1 = cannot do LBA48 DMA */ unsigned auto_poll : 1; /* supports nop auto-poll */ unsigned sg_mapped : 1; /* sg_table and sg_nents are ready */ unsigned no_io_32bit : 1; /* 1 = can not do 32-bit IO ops */ + unsigned err_stops_fifo : 1; /* 1=data FIFO is cleared by an error */ unsigned mmio : 1; /* host uses MMIO */ struct device gendev; @@ -1207,6 +1211,19 @@ extern void default_hwif_iops(ide_hwif_t *); extern void default_hwif_mmiops(ide_hwif_t *); extern void default_hwif_transport(ide_hwif_t *); +#define ON_BOARD 1 +#define NEVER_BOARD 0 + +#ifdef CONFIG_BLK_DEV_OFFBOARD +# define OFF_BOARD ON_BOARD +#else /* CONFIG_BLK_DEV_OFFBOARD */ +# define OFF_BOARD NEVER_BOARD +#endif /* CONFIG_BLK_DEV_OFFBOARD */ + +#define NODMA 0 +#define NOAUTODMA 1 +#define AUTODMA 2 + typedef struct ide_pci_enablebit_s { u8 reg; /* byte pci reg holding the enable-bit */ u8 mask; /* mask to isolate the enable-bit */ @@ -1241,48 +1258,24 @@ enum { IDE_HFLAG_TRUST_BIOS_FOR_DMA = (1 << 10), /* host uses VDMA */ IDE_HFLAG_VDMA = (1 << 11), - /* ATAPI DMA is unsupported */ - IDE_HFLAG_NO_ATAPI_DMA = (1 << 12), - /* set if host is a "bootable" controller */ - IDE_HFLAG_BOOTABLE = (1 << 13), - /* host doesn't support DMA */ - IDE_HFLAG_NO_DMA = (1 << 14), - /* check if host is PCI IDE device before allowing DMA */ - IDE_HFLAG_NO_AUTODMA = (1 << 15), - /* host is CS5510/CS5520 */ - IDE_HFLAG_CS5520 = (1 << 16), - /* no LBA48 */ - IDE_HFLAG_NO_LBA48 = (1 << 17), - /* no LBA48 DMA */ - IDE_HFLAG_NO_LBA48_DMA = (1 << 18), - /* data FIFO is cleared by an error */ - IDE_HFLAG_ERROR_STOPS_FIFO = (1 << 19), - /* serialize ports */ - IDE_HFLAG_SERIALIZE = (1 << 20), - /* use legacy IRQs */ - IDE_HFLAG_LEGACY_IRQS = (1 << 21), }; -#ifdef CONFIG_BLK_DEV_OFFBOARD -# define IDE_HFLAG_OFF_BOARD IDE_HFLAG_BOOTABLE -#else -# define IDE_HFLAG_OFF_BOARD 0 -#endif - typedef struct ide_pci_device_s { char *name; + int (*init_setup)(struct pci_dev *, struct ide_pci_device_s *); + void (*init_setup_dma)(struct pci_dev *, struct ide_pci_device_s *, ide_hwif_t *); unsigned int (*init_chipset)(struct pci_dev *, const char *); void (*init_iops)(ide_hwif_t *); void (*init_hwif)(ide_hwif_t *); void (*init_dma)(ide_hwif_t *, unsigned long); void (*fixup)(ide_hwif_t *); + u8 autodma; ide_pci_enablebit_t enablebits[2]; + u8 bootable; unsigned int extra; struct ide_pci_device_s *next; - u32 host_flags; + u16 host_flags; u8 pio_mask; - u8 swdma_mask; - u8 mwdma_mask; u8 udma_mask; } ide_pci_device_t; @@ -1461,11 +1454,4 @@ static inline int hwif_to_node(ide_hwif_t *hwif) return dev ? pcibus_to_node(dev->bus) : -1; } -static inline ide_drive_t *ide_get_paired_drive(ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - - return &hwif->drives[(drive->dn ^ 1) & 1]; -} - #endif /* _IDE_H */ diff --git a/trunk/include/linux/init_task.h b/trunk/include/linux/init_task.h index cae35b6b9aec..d4b2f1c76e12 100644 --- a/trunk/include/linux/init_task.h +++ b/trunk/include/linux/init_task.h @@ -67,6 +67,9 @@ .posix_timers = LIST_HEAD_INIT(sig.posix_timers), \ .cpu_timers = INIT_CPU_TIMERS(sig.cpu_timers), \ .rlim = INIT_RLIMITS, \ + .pgrp = 0, \ + .tty_old_pgrp = NULL, \ + { .__session = 0}, \ } extern struct nsproxy init_nsproxy; @@ -91,18 +94,15 @@ extern struct group_info init_groups; #define INIT_STRUCT_PID { \ .count = ATOMIC_INIT(1), \ + .nr = 0, \ + /* Don't put this struct pid in pid_hash */ \ + .pid_chain = { .next = NULL, .pprev = NULL }, \ .tasks = { \ { .first = &init_task.pids[PIDTYPE_PID].node }, \ { .first = &init_task.pids[PIDTYPE_PGID].node }, \ { .first = &init_task.pids[PIDTYPE_SID].node }, \ }, \ .rcu = RCU_HEAD_INIT, \ - .level = 0, \ - .numbers = { { \ - .nr = 0, \ - .ns = &init_pid_ns, \ - .pid_chain = { .next = NULL, .pprev = NULL }, \ - }, } \ } #define INIT_PID_LINK(type) \ diff --git a/trunk/include/linux/input.h b/trunk/include/linux/input.h index 62268929856c..f30da6fc08e3 100644 --- a/trunk/include/linux/input.h +++ b/trunk/include/linux/input.h @@ -98,7 +98,6 @@ struct input_absinfo { #define EV_PWR 0x16 #define EV_FF_STATUS 0x17 #define EV_MAX 0x1f -#define EV_CNT (EV_MAX+1) /* * Synchronization events. @@ -568,7 +567,6 @@ struct input_absinfo { /* We avoid low common keys in module aliases so they don't get huge. */ #define KEY_MIN_INTERESTING KEY_MUTE #define KEY_MAX 0x1ff -#define KEY_CNT (KEY_MAX+1) /* * Relative axes @@ -585,7 +583,6 @@ struct input_absinfo { #define REL_WHEEL 0x08 #define REL_MISC 0x09 #define REL_MAX 0x0f -#define REL_CNT (REL_MAX+1) /* * Absolute axes @@ -618,7 +615,6 @@ struct input_absinfo { #define ABS_VOLUME 0x20 #define ABS_MISC 0x28 #define ABS_MAX 0x3f -#define ABS_CNT (ABS_MAX+1) /* * Switch events @@ -629,7 +625,6 @@ struct input_absinfo { #define SW_HEADPHONE_INSERT 0x02 /* set = inserted */ #define SW_RADIO 0x03 /* set = radio enabled */ #define SW_MAX 0x0f -#define SW_CNT (SW_MAX+1) /* * Misc events @@ -641,7 +636,6 @@ struct input_absinfo { #define MSC_RAW 0x03 #define MSC_SCAN 0x04 #define MSC_MAX 0x07 -#define MSC_CNT (MSC_MAX+1) /* * LEDs @@ -659,7 +653,6 @@ struct input_absinfo { #define LED_MAIL 0x09 #define LED_CHARGING 0x0a #define LED_MAX 0x0f -#define LED_CNT (LED_MAX+1) /* * Autorepeat values @@ -677,7 +670,6 @@ struct input_absinfo { #define SND_BELL 0x01 #define SND_TONE 0x02 #define SND_MAX 0x07 -#define SND_CNT (SND_MAX+1) /* * IDs. @@ -928,7 +920,6 @@ struct ff_effect { #define FF_AUTOCENTER 0x61 #define FF_MAX 0x7f -#define FF_CNT (FF_MAX+1) #ifdef __KERNEL__ @@ -941,6 +932,10 @@ struct ff_effect { #include #include +#define NBITS(x) (((x)/BITS_PER_LONG)+1) +#define BIT(x) (1UL<<((x)%BITS_PER_LONG)) +#define LONG(x) ((x)/BITS_PER_LONG) + /** * struct input_dev - represents an input device * @name: name of the device @@ -1010,30 +1005,28 @@ struct ff_effect { * @going_away: marks devices that are in a middle of unregistering and * causes input_open_device*() fail with -ENODEV. * @dev: driver model's view of this device - * @cdev: union for struct device pointer * @h_list: list of input handles associated with the device. When * accessing the list dev->mutex must be held * @node: used to place the device onto input_dev_list */ struct input_dev { - /* private: */ + void *private; /* do not use */ - /* public: */ const char *name; const char *phys; const char *uniq; struct input_id id; - unsigned long evbit[BITS_TO_LONGS(EV_CNT)]; - unsigned long keybit[BITS_TO_LONGS(KEY_CNT)]; - unsigned long relbit[BITS_TO_LONGS(REL_CNT)]; - unsigned long absbit[BITS_TO_LONGS(ABS_CNT)]; - unsigned long mscbit[BITS_TO_LONGS(MSC_CNT)]; - unsigned long ledbit[BITS_TO_LONGS(LED_CNT)]; - unsigned long sndbit[BITS_TO_LONGS(SND_CNT)]; - unsigned long ffbit[BITS_TO_LONGS(FF_CNT)]; - unsigned long swbit[BITS_TO_LONGS(SW_CNT)]; + unsigned long evbit[NBITS(EV_MAX)]; + unsigned long keybit[NBITS(KEY_MAX)]; + unsigned long relbit[NBITS(REL_MAX)]; + unsigned long absbit[NBITS(ABS_MAX)]; + unsigned long mscbit[NBITS(MSC_MAX)]; + unsigned long ledbit[NBITS(LED_MAX)]; + unsigned long sndbit[NBITS(SND_MAX)]; + unsigned long ffbit[NBITS(FF_MAX)]; + unsigned long swbit[NBITS(SW_MAX)]; unsigned int keycodemax; unsigned int keycodesize; @@ -1051,10 +1044,10 @@ struct input_dev { int abs[ABS_MAX + 1]; int rep[REP_MAX + 1]; - unsigned long key[BITS_TO_LONGS(KEY_CNT)]; - unsigned long led[BITS_TO_LONGS(LED_CNT)]; - unsigned long snd[BITS_TO_LONGS(SND_CNT)]; - unsigned long sw[BITS_TO_LONGS(SW_CNT)]; + unsigned long key[NBITS(KEY_MAX)]; + unsigned long led[NBITS(LED_MAX)]; + unsigned long snd[NBITS(SND_MAX)]; + unsigned long sw[NBITS(SW_MAX)]; int absmax[ABS_MAX + 1]; int absmin[ABS_MAX + 1]; @@ -1298,7 +1291,7 @@ static inline void input_set_abs_params(struct input_dev *dev, int axis, int min dev->absfuzz[axis] = fuzz; dev->absflat[axis] = flat; - dev->absbit[BIT_WORD(axis)] |= BIT_MASK(axis); + dev->absbit[LONG(axis)] |= BIT(axis); } extern struct class input_class; @@ -1339,7 +1332,7 @@ struct ff_device { void *private; - unsigned long ffbit[BITS_TO_LONGS(FF_CNT)]; + unsigned long ffbit[NBITS(FF_MAX)]; struct mutex mutex; diff --git a/trunk/include/linux/ipc.h b/trunk/include/linux/ipc.h index 408696ea5189..ee111834091c 100644 --- a/trunk/include/linux/ipc.h +++ b/trunk/include/linux/ipc.h @@ -89,7 +89,6 @@ struct kern_ipc_perm { spinlock_t lock; int deleted; - int id; key_t key; uid_t uid; gid_t gid; @@ -111,8 +110,6 @@ struct ipc_namespace { int msg_ctlmax; int msg_ctlmnb; int msg_ctlmni; - atomic_t msg_bytes; - atomic_t msg_hdrs; size_t shm_ctlmax; size_t shm_ctlall; diff --git a/trunk/include/linux/ipmi.h b/trunk/include/linux/ipmi.h index c5bd28b69aec..7a9db390c56a 100644 --- a/trunk/include/linux/ipmi.h +++ b/trunk/include/linux/ipmi.h @@ -364,16 +364,6 @@ int ipmi_request_supply_msgs(ipmi_user_t user, struct ipmi_recv_msg *supplied_recv, int priority); -/* - * Poll the IPMI interface for the user. This causes the IPMI code to - * do an immediate check for information from the driver and handle - * anything that is immediately pending. This will not block in any - * way. This is useful if you need to implement polling from the user - * for things like modifying the watchdog timeout when a panic occurs - * or disabling the watchdog timer on a reboot. - */ -void ipmi_poll_interface(ipmi_user_t user); - /* * When commands come in to the SMS, the user can register to receive * them. Only one user can be listening on a specific netfn/cmd/chan tuple diff --git a/trunk/include/linux/ipmi_smi.h b/trunk/include/linux/ipmi_smi.h index efa292a52e7e..c0633108d05d 100644 --- a/trunk/include/linux/ipmi_smi.h +++ b/trunk/include/linux/ipmi_smi.h @@ -148,46 +148,26 @@ struct ipmi_device_id { /* Take a pointer to a raw data buffer and a length and extract device id information from it. The first byte of data must point to the - netfn << 2, the data should be of the format: - netfn << 2, cmd, completion code, data - as normally comes from a device interface. */ -static inline int ipmi_demangle_device_id(const unsigned char *data, - unsigned int data_len, - struct ipmi_device_id *id) + byte from the get device id response after the completion code. + The caller is responsible for making sure the length is at least + 11 and the command completed without error. */ +static inline void ipmi_demangle_device_id(unsigned char *data, + unsigned int data_len, + struct ipmi_device_id *id) { - if (data_len < 9) - return -EINVAL; - if (data[0] != IPMI_NETFN_APP_RESPONSE << 2 || - data[1] != IPMI_GET_DEVICE_ID_CMD) - /* Strange, didn't get the response we expected. */ - return -EINVAL; - if (data[2] != 0) - /* That's odd, it shouldn't be able to fail. */ - return -EINVAL; - - data += 3; - data_len -= 3; id->device_id = data[0]; id->device_revision = data[1]; id->firmware_revision_1 = data[2]; id->firmware_revision_2 = data[3]; id->ipmi_version = data[4]; id->additional_device_support = data[5]; - if (data_len >= 6) { - id->manufacturer_id = (data[6] | (data[7] << 8) | - (data[8] << 16)); - id->product_id = data[9] | (data[10] << 8); - } else { - id->manufacturer_id = 0; - id->product_id = 0; - } + id->manufacturer_id = data[6] | (data[7] << 8) | (data[8] << 16); + id->product_id = data[9] | (data[10] << 8); if (data_len >= 15) { memcpy(id->aux_firmware_revision, data+11, 4); id->aux_firmware_revision_set = 1; } else id->aux_firmware_revision_set = 0; - - return 0; } /* Add a low-level interface to the IPMI driver. Note that if the diff --git a/trunk/include/linux/jbd.h b/trunk/include/linux/jbd.h index 16e7ed855a18..72f522372924 100644 --- a/trunk/include/linux/jbd.h +++ b/trunk/include/linux/jbd.h @@ -58,7 +58,7 @@ * CONFIG_JBD_DEBUG is on. */ #define JBD_EXPENSIVE_CHECKING -extern u8 journal_enable_debug; +extern int journal_enable_debug; #define jbd_debug(n, f, a...) \ do { \ @@ -72,15 +72,14 @@ extern u8 journal_enable_debug; #define jbd_debug(f, a...) /**/ #endif -static inline void *jbd_alloc(size_t size, gfp_t flags) -{ - return (void *)__get_free_pages(flags, get_order(size)); -} +extern void * __jbd_kmalloc (const char *where, size_t size, gfp_t flags, int retry); +extern void * jbd_slab_alloc(size_t size, gfp_t flags); +extern void jbd_slab_free(void *ptr, size_t size); -static inline void jbd_free(void *ptr, size_t size) -{ - free_pages((unsigned long)ptr, get_order(size)); -}; +#define jbd_kmalloc(size, flags) \ + __jbd_kmalloc(__FUNCTION__, (size), (flags), journal_oom_retry) +#define jbd_rep_kmalloc(size, flags) \ + __jbd_kmalloc(__FUNCTION__, (size), (flags), 1) #define JFS_MIN_JOURNAL_BLOCKS 1024 @@ -248,7 +247,17 @@ typedef struct journal_superblock_s #include #include -#define J_ASSERT(assert) BUG_ON(!(assert)) +#define JBD_ASSERTIONS +#ifdef JBD_ASSERTIONS +#define J_ASSERT(assert) \ +do { \ + if (!(assert)) { \ + printk (KERN_EMERG \ + "Assertion failure in %s() at %s:%d: \"%s\"\n", \ + __FUNCTION__, __FILE__, __LINE__, # assert); \ + BUG(); \ + } \ +} while (0) #if defined(CONFIG_BUFFER_DEBUG) void buffer_assertion_failure(struct buffer_head *bh); @@ -264,6 +273,10 @@ void buffer_assertion_failure(struct buffer_head *bh); #define J_ASSERT_JH(jh, expr) J_ASSERT(expr) #endif +#else +#define J_ASSERT(assert) do { } while (0) +#endif /* JBD_ASSERTIONS */ + #if defined(JBD_PARANOID_IOFAIL) #define J_EXPECT(expr, why...) J_ASSERT(expr) #define J_EXPECT_BH(bh, expr, why...) J_ASSERT_BH(bh, expr) diff --git a/trunk/include/linux/jbd2.h b/trunk/include/linux/jbd2.h index 06ef11457051..260d6d76c5f3 100644 --- a/trunk/include/linux/jbd2.h +++ b/trunk/include/linux/jbd2.h @@ -13,8 +13,8 @@ * filesystem journaling support. */ -#ifndef _LINUX_JBD2_H -#define _LINUX_JBD2_H +#ifndef _LINUX_JBD_H +#define _LINUX_JBD_H /* Allow this file to be included directly into e2fsprogs */ #ifndef __KERNEL__ @@ -37,26 +37,26 @@ #define journal_oom_retry 1 /* - * Define JBD2_PARANIOD_IOFAIL to cause a kernel BUG() if ext4 finds + * Define JBD_PARANIOD_IOFAIL to cause a kernel BUG() if ext3 finds * certain classes of error which can occur due to failed IOs. Under - * normal use we want ext4 to continue after such errors, because + * normal use we want ext3 to continue after such errors, because * hardware _can_ fail, but for debugging purposes when running tests on * known-good hardware we may want to trap these errors. */ -#undef JBD2_PARANOID_IOFAIL +#undef JBD_PARANOID_IOFAIL /* * The default maximum commit age, in seconds. */ -#define JBD2_DEFAULT_MAX_COMMIT_AGE 5 +#define JBD_DEFAULT_MAX_COMMIT_AGE 5 #ifdef CONFIG_JBD2_DEBUG /* - * Define JBD2_EXPENSIVE_CHECKING to enable more expensive internal + * Define JBD_EXPENSIVE_CHECKING to enable more expensive internal * consistency checks. By default we don't do this unless * CONFIG_JBD2_DEBUG is on. */ -#define JBD2_EXPENSIVE_CHECKING +#define JBD_EXPENSIVE_CHECKING extern u8 jbd2_journal_enable_debug; #define jbd_debug(n, f, a...) \ @@ -71,15 +71,14 @@ extern u8 jbd2_journal_enable_debug; #define jbd_debug(f, a...) /**/ #endif -static inline void *jbd2_alloc(size_t size, gfp_t flags) -{ - return (void *)__get_free_pages(flags, get_order(size)); -} +extern void * __jbd2_kmalloc (const char *where, size_t size, gfp_t flags, int retry); +extern void * jbd2_slab_alloc(size_t size, gfp_t flags); +extern void jbd2_slab_free(void *ptr, size_t size); -static inline void jbd2_free(void *ptr, size_t size) -{ - free_pages((unsigned long)ptr, get_order(size)); -}; +#define jbd_kmalloc(size, flags) \ + __jbd2_kmalloc(__FUNCTION__, (size), (flags), journal_oom_retry) +#define jbd_rep_kmalloc(size, flags) \ + __jbd2_kmalloc(__FUNCTION__, (size), (flags), 1) #define JBD2_MIN_JOURNAL_BLOCKS 1024 @@ -163,8 +162,8 @@ typedef struct journal_block_tag_s __be32 t_blocknr_high; /* most-significant high 32bits. */ } journal_block_tag_t; -#define JBD2_TAG_SIZE32 (offsetof(journal_block_tag_t, t_blocknr_high)) -#define JBD2_TAG_SIZE64 (sizeof(journal_block_tag_t)) +#define JBD_TAG_SIZE32 (offsetof(journal_block_tag_t, t_blocknr_high)) +#define JBD_TAG_SIZE64 (sizeof(journal_block_tag_t)) /* * The revoke descriptor: used on disk to describe a series of blocks to @@ -256,8 +255,8 @@ typedef struct journal_superblock_s #include #include -#define JBD2_ASSERTIONS -#ifdef JBD2_ASSERTIONS +#define JBD_ASSERTIONS +#ifdef JBD_ASSERTIONS #define J_ASSERT(assert) \ do { \ if (!(assert)) { \ @@ -284,9 +283,9 @@ void buffer_assertion_failure(struct buffer_head *bh); #else #define J_ASSERT(assert) do { } while (0) -#endif /* JBD2_ASSERTIONS */ +#endif /* JBD_ASSERTIONS */ -#if defined(JBD2_PARANOID_IOFAIL) +#if defined(JBD_PARANOID_IOFAIL) #define J_EXPECT(expr, why...) J_ASSERT(expr) #define J_EXPECT_BH(bh, expr, why...) J_ASSERT_BH(bh, expr) #define J_EXPECT_JH(jh, expr, why...) J_ASSERT_JH(jh, expr) @@ -960,12 +959,12 @@ void jbd2_journal_put_journal_head(struct journal_head *jh); */ extern struct kmem_cache *jbd2_handle_cache; -static inline handle_t *jbd2_alloc_handle(gfp_t gfp_flags) +static inline handle_t *jbd_alloc_handle(gfp_t gfp_flags) { return kmem_cache_alloc(jbd2_handle_cache, gfp_flags); } -static inline void jbd2_free_handle(handle_t *handle) +static inline void jbd_free_handle(handle_t *handle) { kmem_cache_free(jbd2_handle_cache, handle); } @@ -1104,4 +1103,4 @@ extern int jbd_blocks_per_page(struct inode *inode); #endif /* __KERNEL__ */ -#endif /* _LINUX_JBD2_H */ +#endif /* _LINUX_JBD_H */ diff --git a/trunk/include/linux/kernel_stat.h b/trunk/include/linux/kernel_stat.h index e8ffce898bf9..12bf44f083f5 100644 --- a/trunk/include/linux/kernel_stat.h +++ b/trunk/include/linux/kernel_stat.h @@ -53,9 +53,7 @@ static inline int kstat_irqs(int irq) } extern void account_user_time(struct task_struct *, cputime_t); -extern void account_user_time_scaled(struct task_struct *, cputime_t); extern void account_system_time(struct task_struct *, int, cputime_t); -extern void account_system_time_scaled(struct task_struct *, cputime_t); extern void account_steal_time(struct task_struct *, cputime_t); #endif /* _LINUX_KERNEL_STAT_H */ diff --git a/trunk/include/linux/kexec.h b/trunk/include/linux/kexec.h index 2d9c448d8c52..ad4b82ce84af 100644 --- a/trunk/include/linux/kexec.h +++ b/trunk/include/linux/kexec.h @@ -187,8 +187,6 @@ extern u32 vmcoreinfo_note[VMCOREINFO_NOTE_SIZE/4]; extern size_t vmcoreinfo_size; extern size_t vmcoreinfo_max_size; -int __init parse_crashkernel(char *cmdline, unsigned long long system_ram, - unsigned long long *crash_size, unsigned long long *crash_base); #else /* !CONFIG_KEXEC */ struct pt_regs; diff --git a/trunk/include/linux/keyboard.h b/trunk/include/linux/keyboard.h index 65c2d70853e9..33b5c2e325b9 100644 --- a/trunk/include/linux/keyboard.h +++ b/trunk/include/linux/keyboard.h @@ -23,21 +23,10 @@ #define MAX_NR_OF_USER_KEYMAPS 256 /* should be at least 7 */ #ifdef __KERNEL__ -struct notifier_block; extern const int NR_TYPES; extern const int max_vals[]; extern unsigned short *key_maps[MAX_NR_KEYMAPS]; extern unsigned short plain_map[NR_KEYS]; - -struct keyboard_notifier_param { - struct vc_data *vc; /* VC on which the keyboard press was done */ - int down; /* Pressure of the key? */ - int shift; /* Current shift mask */ - unsigned int value; /* keycode, unicode value or keysym */ -}; - -extern int register_keyboard_notifier(struct notifier_block *nb); -extern int unregister_keyboard_notifier(struct notifier_block *nb); #endif #define MAX_NR_FUNC 256 /* max nr of strings assigned to keys */ diff --git a/trunk/include/linux/libata.h b/trunk/include/linux/libata.h index bc3b6fc7b98d..377e6d4d9be3 100644 --- a/trunk/include/linux/libata.h +++ b/trunk/include/linux/libata.h @@ -1037,6 +1037,18 @@ extern void ata_port_pbar_desc(struct ata_port *ap, int bar, ssize_t offset, /* * qc helpers */ +static inline int +ata_sg_is_last(struct scatterlist *sg, struct ata_queued_cmd *qc) +{ + if (sg == &qc->pad_sgent) + return 1; + if (qc->pad_len) + return 0; + if (qc->n_iter == qc->n_elem) + return 1; + return 0; +} + static inline struct scatterlist * ata_qc_first_sg(struct ata_queued_cmd *qc) { diff --git a/trunk/include/linux/list.h b/trunk/include/linux/list.h index 75ce2cb4ff6e..b0cf0135fe3e 100644 --- a/trunk/include/linux/list.h +++ b/trunk/include/linux/list.h @@ -478,7 +478,8 @@ static inline void list_splice_init_rcu(struct list_head *list, pos = n, n = pos->next) /** - * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry + * list_for_each_prev_safe - iterate over a list backwards safe against removal + of list entry * @pos: the &struct list_head to use as a loop cursor. * @n: another &struct list_head to use as temporary storage * @head: the head for your list. diff --git a/trunk/include/linux/lockdep.h b/trunk/include/linux/lockdep.h index 4c4d236ded18..f6279f68a827 100644 --- a/trunk/include/linux/lockdep.h +++ b/trunk/include/linux/lockdep.h @@ -275,14 +275,6 @@ extern void lockdep_init_map(struct lockdep_map *lock, const char *name, lockdep_init_map(&(lock)->dep_map, #lock, \ (lock)->dep_map.key, sub) -/* - * To initialize a lockdep_map statically use this macro. - * Note that _name must not be NULL. - */ -#define STATIC_LOCKDEP_MAP_INIT(_name, _key) \ - { .name = (_name), .key = (void *)(_key), } - - /* * Acquire a lock. * diff --git a/trunk/include/linux/magic.h b/trunk/include/linux/magic.h index 1fa0c2ce4dec..722d4755060f 100644 --- a/trunk/include/linux/magic.h +++ b/trunk/include/linux/magic.h @@ -37,7 +37,6 @@ #define SMB_SUPER_MAGIC 0x517B #define USBDEVICE_SUPER_MAGIC 0x9fa2 -#define CGROUP_SUPER_MAGIC 0x27e0eb #define FUTEXFS_SUPER_MAGIC 0xBAD1DEA #define INOTIFYFS_SUPER_MAGIC 0x2BAD1DEA diff --git a/trunk/include/linux/marker.h b/trunk/include/linux/marker.h deleted file mode 100644 index 5f36cf946bcb..000000000000 --- a/trunk/include/linux/marker.h +++ /dev/null @@ -1,129 +0,0 @@ -#ifndef _LINUX_MARKER_H -#define _LINUX_MARKER_H - -/* - * Code markup for dynamic and static tracing. - * - * See Documentation/marker.txt. - * - * (C) Copyright 2006 Mathieu Desnoyers - * - * This file is released under the GPLv2. - * See the file COPYING for more details. - */ - -#include - -struct module; -struct marker; - -/** - * marker_probe_func - Type of a marker probe function - * @mdata: pointer of type struct marker - * @private_data: caller site private data - * @fmt: format string - * @...: variable argument list - * - * Type of marker probe functions. They receive the mdata and need to parse the - * format string to recover the variable argument list. - */ -typedef void marker_probe_func(const struct marker *mdata, - void *private_data, const char *fmt, ...); - -struct marker { - const char *name; /* Marker name */ - const char *format; /* Marker format string, describing the - * variable argument list. - */ - char state; /* Marker state. */ - marker_probe_func *call;/* Probe handler function pointer */ - void *private; /* Private probe data */ -} __attribute__((aligned(8))); - -#ifdef CONFIG_MARKERS - -/* - * Note : the empty asm volatile with read constraint is used here instead of a - * "used" attribute to fix a gcc 4.1.x bug. - * Make sure the alignment of the structure in the __markers section will - * not add unwanted padding between the beginning of the section and the - * structure. Force alignment to the same alignment as the section start. - */ -#define __trace_mark(name, call_data, format, args...) \ - do { \ - static const char __mstrtab_name_##name[] \ - __attribute__((section("__markers_strings"))) \ - = #name; \ - static const char __mstrtab_format_##name[] \ - __attribute__((section("__markers_strings"))) \ - = format; \ - static struct marker __mark_##name \ - __attribute__((section("__markers"), aligned(8))) = \ - { __mstrtab_name_##name, __mstrtab_format_##name, \ - 0, __mark_empty_function, NULL }; \ - __mark_check_format(format, ## args); \ - if (unlikely(__mark_##name.state)) { \ - preempt_disable(); \ - (*__mark_##name.call) \ - (&__mark_##name, call_data, \ - format, ## args); \ - preempt_enable(); \ - } \ - } while (0) - -extern void marker_update_probe_range(struct marker *begin, - struct marker *end, struct module *probe_module, int *refcount); -#else /* !CONFIG_MARKERS */ -#define __trace_mark(name, call_data, format, args...) \ - __mark_check_format(format, ## args) -static inline void marker_update_probe_range(struct marker *begin, - struct marker *end, struct module *probe_module, int *refcount) -{ } -#endif /* CONFIG_MARKERS */ - -/** - * trace_mark - Marker - * @name: marker name, not quoted. - * @format: format string - * @args...: variable argument list - * - * Places a marker. - */ -#define trace_mark(name, format, args...) \ - __trace_mark(name, NULL, format, ## args) - -#define MARK_MAX_FORMAT_LEN 1024 - -/** - * MARK_NOARGS - Format string for a marker with no argument. - */ -#define MARK_NOARGS " " - -/* To be used for string format validity checking with gcc */ -static inline void __printf(1, 2) __mark_check_format(const char *fmt, ...) -{ -} - -extern marker_probe_func __mark_empty_function; - -/* - * Connect a probe to a marker. - * private data pointer must be a valid allocated memory address, or NULL. - */ -extern int marker_probe_register(const char *name, const char *format, - marker_probe_func *probe, void *private); - -/* - * Returns the private data given to marker_probe_register. - */ -extern void *marker_probe_unregister(const char *name); -/* - * Unregister a marker by providing the registered private data. - */ -extern void *marker_probe_unregister_private_data(void *private); - -extern int marker_arm(const char *name); -extern int marker_disarm(const char *name); -extern void *marker_get_private_data(const char *name); - -#endif diff --git a/trunk/include/linux/mempolicy.h b/trunk/include/linux/mempolicy.h index 59c4865bc85f..38c04d61ee06 100644 --- a/trunk/include/linux/mempolicy.h +++ b/trunk/include/linux/mempolicy.h @@ -148,6 +148,14 @@ extern void mpol_rebind_task(struct task_struct *tsk, const nodemask_t *new); extern void mpol_rebind_mm(struct mm_struct *mm, nodemask_t *new); extern void mpol_fix_fork_child_flag(struct task_struct *p); +#define set_cpuset_being_rebound(x) (cpuset_being_rebound = (x)) + +#ifdef CONFIG_CPUSETS +#define current_cpuset_is_being_rebound() \ + (cpuset_being_rebound == current->cpuset) +#else +#define current_cpuset_is_being_rebound() 0 +#endif extern struct mempolicy default_policy; extern struct zonelist *huge_zonelist(struct vm_area_struct *vma, @@ -165,6 +173,8 @@ static inline void check_highest_zone(enum zone_type k) int do_migrate_pages(struct mm_struct *mm, const nodemask_t *from_nodes, const nodemask_t *to_nodes, int flags); +extern void *cpuset_being_rebound; /* Trigger mpol_copy vma rebind */ + #else struct mempolicy {}; @@ -238,6 +248,8 @@ static inline void mpol_fix_fork_child_flag(struct task_struct *p) { } +#define set_cpuset_being_rebound(x) do {} while (0) + static inline struct zonelist *huge_zonelist(struct vm_area_struct *vma, unsigned long addr, gfp_t gfp_flags, struct mempolicy **mpol) { diff --git a/trunk/include/linux/module.h b/trunk/include/linux/module.h index 2cbc0b87e329..642f325e4917 100644 --- a/trunk/include/linux/module.h +++ b/trunk/include/linux/module.h @@ -15,7 +15,6 @@ #include #include #include -#include #include #include @@ -355,10 +354,6 @@ struct module /* The command line arguments (may be mangled). People like keeping pointers to this stuff */ char *args; -#ifdef CONFIG_MARKERS - struct marker *markers; - unsigned int num_markers; -#endif }; #ifndef MODULE_ARCH_INIT #define MODULE_ARCH_INIT {} @@ -462,8 +457,6 @@ int unregister_module_notifier(struct notifier_block * nb); extern void print_modules(void); -extern void module_update_markers(struct module *probe_module, int *refcount); - #else /* !CONFIG_MODULES... */ #define EXPORT_SYMBOL(sym) #define EXPORT_SYMBOL_GPL(sym) @@ -563,11 +556,6 @@ static inline void print_modules(void) { } -static inline void module_update_markers(struct module *probe_module, - int *refcount) -{ -} - #endif /* CONFIG_MODULES */ struct device_driver; diff --git a/trunk/include/linux/msg.h b/trunk/include/linux/msg.h index 10a3d5a1abff..f1b60740d641 100644 --- a/trunk/include/linux/msg.h +++ b/trunk/include/linux/msg.h @@ -77,6 +77,7 @@ struct msg_msg { /* one msq_queue structure for each present queue on the system */ struct msg_queue { struct kern_ipc_perm q_perm; + int q_id; time_t q_stime; /* last msgsnd time */ time_t q_rtime; /* last msgrcv time */ time_t q_ctime; /* last change time */ diff --git a/trunk/include/linux/netdevice.h b/trunk/include/linux/netdevice.h index 6f85db3535e2..39dd83b183a9 100644 --- a/trunk/include/linux/netdevice.h +++ b/trunk/include/linux/netdevice.h @@ -407,24 +407,6 @@ static inline void napi_enable(struct napi_struct *n) clear_bit(NAPI_STATE_SCHED, &n->state); } -#ifdef CONFIG_SMP -/** - * napi_synchronize - wait until NAPI is not running - * @n: napi context - * - * Wait until NAPI is done being scheduled on this context. - * Waits till any outstanding processing completes but - * does not disable future activations. - */ -static inline void napi_synchronize(const struct napi_struct *n) -{ - while (test_bit(NAPI_STATE_SCHED, &n->state)) - msleep(1); -} -#else -# define napi_synchronize(n) barrier() -#endif - /* * The DEVICE structure. * Actually, this whole structure is a big mistake. It mixes I/O @@ -845,7 +827,7 @@ static inline int dev_parse_header(const struct sk_buff *skb, { const struct net_device *dev = skb->dev; - if (!dev->header_ops || !dev->header_ops->parse) + if (!dev->header_ops->parse) return 0; return dev->header_ops->parse(skb, haddr); } diff --git a/trunk/include/linux/netfilter/xt_sctp.h b/trunk/include/linux/netfilter/xt_sctp.h index dd5a4fd4cfd3..b157897e7792 100644 --- a/trunk/include/linux/netfilter/xt_sctp.h +++ b/trunk/include/linux/netfilter/xt_sctp.h @@ -7,6 +7,9 @@ #define XT_SCTP_VALID_FLAGS 0x07 +#define ELEMCOUNT(x) (sizeof(x)/sizeof(x[0])) + + struct xt_sctp_flag_info { u_int8_t chunktype; u_int8_t flag; @@ -56,21 +59,21 @@ struct xt_sctp_info { #define SCTP_CHUNKMAP_RESET(chunkmap) \ do { \ int i; \ - for (i = 0; i < ARRAY_SIZE(chunkmap); i++) \ + for (i = 0; i < ELEMCOUNT(chunkmap); i++) \ chunkmap[i] = 0; \ } while (0) #define SCTP_CHUNKMAP_SET_ALL(chunkmap) \ do { \ int i; \ - for (i = 0; i < ARRAY_SIZE(chunkmap); i++) \ + for (i = 0; i < ELEMCOUNT(chunkmap); i++) \ chunkmap[i] = ~0; \ } while (0) #define SCTP_CHUNKMAP_COPY(destmap, srcmap) \ do { \ int i; \ - for (i = 0; i < ARRAY_SIZE(srcmap); i++) \ + for (i = 0; i < ELEMCOUNT(chunkmap); i++) \ destmap[i] = srcmap[i]; \ } while (0) @@ -78,7 +81,7 @@ struct xt_sctp_info { ({ \ int i; \ int flag = 1; \ - for (i = 0; i < ARRAY_SIZE(chunkmap); i++) { \ + for (i = 0; i < ELEMCOUNT(chunkmap); i++) { \ if (chunkmap[i]) { \ flag = 0; \ break; \ @@ -91,7 +94,7 @@ struct xt_sctp_info { ({ \ int i; \ int flag = 1; \ - for (i = 0; i < ARRAY_SIZE(chunkmap); i++) { \ + for (i = 0; i < ELEMCOUNT(chunkmap); i++) { \ if (chunkmap[i] != ~0) { \ flag = 0; \ break; \ diff --git a/trunk/include/linux/notifier.h b/trunk/include/linux/notifier.h index 0c40cc0b4a36..fad7ff17e468 100644 --- a/trunk/include/linux/notifier.h +++ b/trunk/include/linux/notifier.h @@ -231,22 +231,5 @@ static inline int notifier_to_errno(int ret) #define PM_SUSPEND_PREPARE 0x0003 /* Going to suspend the system */ #define PM_POST_SUSPEND 0x0004 /* Suspend finished */ -/* Console keyboard events. - * Note: KBD_KEYCODE is always sent before KBD_UNBOUND_KEYCODE, KBD_UNICODE and - * KBD_KEYSYM. */ -#define KBD_KEYCODE 0x0001 /* Keyboard keycode, called before any other */ -#define KBD_UNBOUND_KEYCODE 0x0002 /* Keyboard keycode which is not bound to any other */ -#define KBD_UNICODE 0x0003 /* Keyboard unicode */ -#define KBD_KEYSYM 0x0004 /* Keyboard keysym */ -#define KBD_POST_KEYSYM 0x0005 /* Called after keyboard keysym interpretation */ - -extern struct blocking_notifier_head reboot_notifier_list; - -/* Virtual Terminal events. */ -#define VT_ALLOCATE 0x0001 /* Console got allocated */ -#define VT_DEALLOCATE 0x0002 /* Console will be deallocated */ -#define VT_WRITE 0x0003 /* A char got output */ -#define VT_UPDATE 0x0004 /* A bigger update occurred */ - #endif /* __KERNEL__ */ #endif /* _LINUX_NOTIFIER_H */ diff --git a/trunk/include/linux/nsproxy.h b/trunk/include/linux/nsproxy.h index 0e66b57631fc..033a648709b6 100644 --- a/trunk/include/linux/nsproxy.h +++ b/trunk/include/linux/nsproxy.h @@ -32,39 +32,8 @@ struct nsproxy { }; extern struct nsproxy init_nsproxy; -/* - * the namespaces access rules are: - * - * 1. only current task is allowed to change tsk->nsproxy pointer or - * any pointer on the nsproxy itself - * - * 2. when accessing (i.e. reading) current task's namespaces - no - * precautions should be taken - just dereference the pointers - * - * 3. the access to other task namespaces is performed like this - * rcu_read_lock(); - * nsproxy = task_nsproxy(tsk); - * if (nsproxy != NULL) { - * / * - * * work with the namespaces here - * * e.g. get the reference on one of them - * * / - * } / * - * * NULL task_nsproxy() means that this task is - * * almost dead (zombie) - * * / - * rcu_read_unlock(); - * - */ - -static inline struct nsproxy *task_nsproxy(struct task_struct *tsk) -{ - return rcu_dereference(tsk->nsproxy); -} - int copy_namespaces(unsigned long flags, struct task_struct *tsk); -void exit_task_namespaces(struct task_struct *tsk); -void switch_task_namespaces(struct task_struct *tsk, struct nsproxy *new); +void get_task_namespaces(struct task_struct *tsk); void free_nsproxy(struct nsproxy *ns); int unshare_nsproxy_namespaces(unsigned long, struct nsproxy **, struct fs_struct *); @@ -76,15 +45,14 @@ static inline void put_nsproxy(struct nsproxy *ns) } } -static inline void get_nsproxy(struct nsproxy *ns) +static inline void exit_task_namespaces(struct task_struct *p) { - atomic_inc(&ns->count); + struct nsproxy *ns = p->nsproxy; + if (ns) { + task_lock(p); + p->nsproxy = NULL; + task_unlock(p); + put_nsproxy(ns); + } } - -#ifdef CONFIG_CGROUP_NS -int ns_cgroup_clone(struct task_struct *tsk); -#else -static inline int ns_cgroup_clone(struct task_struct *tsk) { return 0; } -#endif - #endif diff --git a/trunk/include/linux/of.h b/trunk/include/linux/of.h index 5c39b9270ff7..6df80e985914 100644 --- a/trunk/include/linux/of.h +++ b/trunk/include/linux/of.h @@ -16,8 +16,8 @@ * 2 of the License, or (at your option) any later version. */ #include -#include +#include #include /* flag descriptions */ diff --git a/trunk/include/linux/of_platform.h b/trunk/include/linux/of_platform.h index a8efcfeea732..448f70b30a0c 100644 --- a/trunk/include/linux/of_platform.h +++ b/trunk/include/linux/of_platform.h @@ -48,10 +48,6 @@ struct of_platform_driver #define to_of_platform_driver(drv) \ container_of(drv,struct of_platform_driver, driver) -extern int of_register_driver(struct of_platform_driver *drv, - struct bus_type *bus); -extern void of_unregister_driver(struct of_platform_driver *drv); - #include extern struct of_device *of_find_device_by_node(struct device_node *np); diff --git a/trunk/include/linux/parport.h b/trunk/include/linux/parport.h index ec3f76598327..9cdd6943e01b 100644 --- a/trunk/include/linux/parport.h +++ b/trunk/include/linux/parport.h @@ -510,6 +510,7 @@ extern struct pardevice *parport_open (int devnum, const char *name, int flags, void *handle); extern void parport_close (struct pardevice *dev); extern ssize_t parport_device_id (int devnum, char *buffer, size_t len); +extern int parport_device_num (int parport, int mux, int daisy); extern void parport_daisy_deselect_all (struct parport *port); extern int parport_daisy_select (struct parport *port, int daisy, int mode); diff --git a/trunk/include/linux/phantom.h b/trunk/include/linux/phantom.h index 96f4048a6cc3..d3ebbfae6903 100644 --- a/trunk/include/linux/phantom.h +++ b/trunk/include/linux/phantom.h @@ -30,11 +30,7 @@ struct phm_regs { #define PHN_SET_REG _IOW (PH_IOC_MAGIC, 1, struct phm_reg *) #define PHN_GET_REGS _IOWR(PH_IOC_MAGIC, 2, struct phm_regs *) #define PHN_SET_REGS _IOW (PH_IOC_MAGIC, 3, struct phm_regs *) -/* this ioctl tells the driver, that the caller is not OpenHaptics and might - * use improved registers update (no more phantom switchoffs when using - * libphantom) */ -#define PHN_NOT_OH _IO (PH_IOC_MAGIC, 4) -#define PH_IOC_MAXNR 4 +#define PH_IOC_MAXNR 3 #define PHN_CONTROL 0x6 /* control byte in iaddr space */ #define PHN_CTL_AMP 0x1 /* switch after torques change */ diff --git a/trunk/include/linux/pid.h b/trunk/include/linux/pid.h index e29a900a8499..1e0e4e3423a6 100644 --- a/trunk/include/linux/pid.h +++ b/trunk/include/linux/pid.h @@ -40,28 +40,15 @@ enum pid_type * processes. */ - -/* - * struct upid is used to get the id of the struct pid, as it is - * seen in particular namespace. Later the struct pid is found with - * find_pid_ns() using the int nr and struct pid_namespace *ns. - */ - -struct upid { - /* Try to keep pid_chain in the same cacheline as nr for find_pid */ - int nr; - struct pid_namespace *ns; - struct hlist_node pid_chain; -}; - struct pid { atomic_t count; + /* Try to keep pid_chain in the same cacheline as nr for find_pid */ + int nr; + struct hlist_node pid_chain; /* lists of tasks that use this pid */ struct hlist_head tasks[PIDTYPE_MAX]; struct rcu_head rcu; - int level; - struct upid numbers[1]; }; extern struct pid init_struct_pid; @@ -96,60 +83,26 @@ extern void FASTCALL(detach_pid(struct task_struct *task, enum pid_type)); extern void FASTCALL(transfer_pid(struct task_struct *old, struct task_struct *new, enum pid_type)); -struct pid_namespace; -extern struct pid_namespace init_pid_ns; - /* * look up a PID in the hash table. Must be called with the tasklist_lock * or rcu_read_lock() held. - * - * find_pid_ns() finds the pid in the namespace specified - * find_pid() find the pid by its global id, i.e. in the init namespace - * find_vpid() finr the pid by its virtual id, i.e. in the current namespace - * - * see also find_task_by_pid() set in include/linux/sched.h */ -extern struct pid *FASTCALL(find_pid_ns(int nr, struct pid_namespace *ns)); -extern struct pid *find_vpid(int nr); -extern struct pid *find_pid(int nr); +extern struct pid *FASTCALL(find_pid(int nr)); /* * Lookup a PID in the hash table, and return with it's count elevated. */ extern struct pid *find_get_pid(int nr); -extern struct pid *find_ge_pid(int nr, struct pid_namespace *); +extern struct pid *find_ge_pid(int nr); -extern struct pid *alloc_pid(struct pid_namespace *ns); +extern struct pid *alloc_pid(void); extern void FASTCALL(free_pid(struct pid *pid)); -extern void zap_pid_ns_processes(struct pid_namespace *pid_ns); - -/* - * the helpers to get the pid's id seen from different namespaces - * - * pid_nr() : global id, i.e. the id seen from the init namespace; - * pid_vnr() : virtual id, i.e. the id seen from the namespace this pid - * belongs to. this only makes sence when called in the - * context of the task that belongs to the same namespace; - * pid_nr_ns() : id seen from the ns specified. - * - * see also task_xid_nr() etc in include/linux/sched.h - */ static inline pid_t pid_nr(struct pid *pid) { pid_t nr = 0; if (pid) - nr = pid->numbers[0].nr; - return nr; -} - -pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns); - -static inline pid_t pid_vnr(struct pid *pid) -{ - pid_t nr = 0; - if (pid) - nr = pid->numbers[pid->level].nr; + nr = pid->nr; return nr; } diff --git a/trunk/include/linux/pid_namespace.h b/trunk/include/linux/pid_namespace.h index 0135c76c76c6..b9a17e08ff0f 100644 --- a/trunk/include/linux/pid_namespace.h +++ b/trunk/include/linux/pid_namespace.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -19,21 +20,13 @@ struct pid_namespace { struct pidmap pidmap[PIDMAP_ENTRIES]; int last_pid; struct task_struct *child_reaper; - struct kmem_cache *pid_cachep; - int level; - struct pid_namespace *parent; -#ifdef CONFIG_PROC_FS - struct vfsmount *proc_mnt; -#endif }; extern struct pid_namespace init_pid_ns; -static inline struct pid_namespace *get_pid_ns(struct pid_namespace *ns) +static inline void get_pid_ns(struct pid_namespace *ns) { - if (ns != &init_pid_ns) - kref_get(&ns->kref); - return ns; + kref_get(&ns->kref); } extern struct pid_namespace *copy_pid_ns(unsigned long flags, struct pid_namespace *ns); @@ -41,19 +34,12 @@ extern void free_pid_ns(struct kref *kref); static inline void put_pid_ns(struct pid_namespace *ns) { - if (ns != &init_pid_ns) - kref_put(&ns->kref, free_pid_ns); + kref_put(&ns->kref, free_pid_ns); } -static inline struct pid_namespace *task_active_pid_ns(struct task_struct *tsk) +static inline struct task_struct *child_reaper(struct task_struct *tsk) { - return tsk->nsproxy->pid_ns; -} - -static inline struct task_struct *task_child_reaper(struct task_struct *tsk) -{ - BUG_ON(tsk != current); - return tsk->nsproxy->pid_ns->child_reaper; + return init_pid_ns.child_reaper; } #endif /* _LINUX_PID_NS_H */ diff --git a/trunk/include/linux/pm.h b/trunk/include/linux/pm.h index 09a309b7b5d2..48b71badfb4c 100644 --- a/trunk/include/linux/pm.h +++ b/trunk/include/linux/pm.h @@ -104,6 +104,104 @@ extern void (*pm_idle)(void); extern void (*pm_power_off)(void); extern void (*pm_power_off_prepare)(void); +typedef int __bitwise suspend_state_t; + +#define PM_SUSPEND_ON ((__force suspend_state_t) 0) +#define PM_SUSPEND_STANDBY ((__force suspend_state_t) 1) +#define PM_SUSPEND_MEM ((__force suspend_state_t) 3) +#define PM_SUSPEND_MAX ((__force suspend_state_t) 4) + +/** + * struct pm_ops - Callbacks for managing platform dependent system sleep + * states. + * + * @valid: Callback to determine if given system sleep state is supported by + * the platform. + * Valid (ie. supported) states are advertised in /sys/power/state. Note + * that it still may be impossible to enter given system sleep state if the + * conditions aren't right. + * There is the %pm_valid_only_mem function available that can be assigned + * to this if the platform only supports mem sleep. + * + * @set_target: Tell the platform which system sleep state is going to be + * entered. + * @set_target() is executed right prior to suspending devices. The + * information conveyed to the platform code by @set_target() should be + * disregarded by the platform as soon as @finish() is executed and if + * @prepare() fails. If @set_target() fails (ie. returns nonzero), + * @prepare(), @enter() and @finish() will not be called by the PM core. + * This callback is optional. However, if it is implemented, the argument + * passed to @prepare(), @enter() and @finish() is meaningless and should + * be ignored. + * + * @prepare: Prepare the platform for entering the system sleep state indicated + * by @set_target() or represented by the argument if @set_target() is not + * implemented. + * @prepare() is called right after devices have been suspended (ie. the + * appropriate .suspend() method has been executed for each device) and + * before the nonboot CPUs are disabled (it is executed with IRQs enabled). + * This callback is optional. It returns 0 on success or a negative + * error code otherwise, in which case the system cannot enter the desired + * sleep state (@enter() and @finish() will not be called in that case). + * + * @enter: Enter the system sleep state indicated by @set_target() or + * represented by the argument if @set_target() is not implemented. + * This callback is mandatory. It returns 0 on success or a negative + * error code otherwise, in which case the system cannot enter the desired + * sleep state. + * + * @finish: Called when the system has just left a sleep state, right after + * the nonboot CPUs have been enabled and before devices are resumed (it is + * executed with IRQs enabled). If @set_target() is not implemented, the + * argument represents the sleep state being left. + * This callback is optional, but should be implemented by the platforms + * that implement @prepare(). If implemented, it is always called after + * @enter() (even if @enter() fails). + */ +struct pm_ops { + int (*valid)(suspend_state_t state); + int (*set_target)(suspend_state_t state); + int (*prepare)(suspend_state_t state); + int (*enter)(suspend_state_t state); + int (*finish)(suspend_state_t state); +}; + +#ifdef CONFIG_SUSPEND +extern struct pm_ops *pm_ops; + +/** + * pm_set_ops - set platform dependent power management ops + * @pm_ops: The new power management operations to set. + */ +extern void pm_set_ops(struct pm_ops *pm_ops); +extern int pm_valid_only_mem(suspend_state_t state); + +/** + * arch_suspend_disable_irqs - disable IRQs for suspend + * + * Disables IRQs (in the default case). This is a weak symbol in the common + * code and thus allows architectures to override it if more needs to be + * done. Not called for suspend to disk. + */ +extern void arch_suspend_disable_irqs(void); + +/** + * arch_suspend_enable_irqs - enable IRQs after suspend + * + * Enables IRQs (in the default case). This is a weak symbol in the common + * code and thus allows architectures to override it if more needs to be + * done. Not called for suspend to disk. + */ +extern void arch_suspend_enable_irqs(void); + +extern int pm_suspend(suspend_state_t state); +#else /* !CONFIG_SUSPEND */ +#define suspend_valid_only_mem NULL + +static inline void pm_set_ops(struct pm_ops *pm_ops) {} +static inline int pm_suspend(suspend_state_t state) { return -ENOSYS; } +#endif /* !CONFIG_SUSPEND */ + /* * Device power management */ diff --git a/trunk/include/linux/poison.h b/trunk/include/linux/poison.h index a9c31be7052c..d93c300a3449 100644 --- a/trunk/include/linux/poison.h +++ b/trunk/include/linux/poison.h @@ -36,8 +36,7 @@ */ /********** fs/jbd/journal.c **********/ -#define JBD_POISON_FREE 0x5b -#define JBD2_POISON_FREE 0x5c +#define JBD_POISON_FREE 0x5b /********** drivers/base/dmapool.c **********/ #define POOL_POISON_FREED 0xa7 /* !inuse */ diff --git a/trunk/include/linux/prio_heap.h b/trunk/include/linux/prio_heap.h deleted file mode 100644 index 08094350f26a..000000000000 --- a/trunk/include/linux/prio_heap.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef _LINUX_PRIO_HEAP_H -#define _LINUX_PRIO_HEAP_H - -/* - * Simple insertion-only static-sized priority heap containing - * pointers, based on CLR, chapter 7 - */ - -#include - -/** - * struct ptr_heap - simple static-sized priority heap - * @ptrs - pointer to data area - * @max - max number of elements that can be stored in @ptrs - * @size - current number of valid elements in @ptrs (in the range 0..@size-1 - * @gt: comparison operator, which should implement "greater than" - */ -struct ptr_heap { - void **ptrs; - int max; - int size; - int (*gt)(void *, void *); -}; - -/** - * heap_init - initialize an empty heap with a given memory size - * @heap: the heap structure to be initialized - * @size: amount of memory to use in bytes - * @gfp_mask: mask to pass to kmalloc() - * @gt: comparison operator, which should implement "greater than" - */ -extern int heap_init(struct ptr_heap *heap, size_t size, gfp_t gfp_mask, - int (*gt)(void *, void *)); - -/** - * heap_free - release a heap's storage - * @heap: the heap structure whose data should be released - */ -void heap_free(struct ptr_heap *heap); - -/** - * heap_insert - insert a value into the heap and return any overflowed value - * @heap: the heap to be operated on - * @p: the pointer to be inserted - * - * Attempts to insert the given value into the priority heap. If the - * heap is full prior to the insertion, then the resulting heap will - * consist of the smallest @max elements of the original heap and the - * new element; the greatest element will be removed from the heap and - * returned. Note that the returned element will be the new element - * (i.e. no change to the heap) if the new element is greater than all - * elements currently in the heap. - */ -extern void *heap_insert(struct ptr_heap *heap, void *p); - - - -#endif /* _LINUX_PRIO_HEAP_H */ diff --git a/trunk/include/linux/proc_fs.h b/trunk/include/linux/proc_fs.h index 1ff461672060..20741f668f7b 100644 --- a/trunk/include/linux/proc_fs.h +++ b/trunk/include/linux/proc_fs.h @@ -125,8 +125,7 @@ extern struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode, extern void remove_proc_entry(const char *name, struct proc_dir_entry *parent); extern struct vfsmount *proc_mnt; -struct pid_namespace; -extern int proc_fill_super(struct super_block *); +extern int proc_fill_super(struct super_block *,void *,int); extern struct inode *proc_get_inode(struct super_block *, unsigned int, struct proc_dir_entry *); /* @@ -143,9 +142,6 @@ extern const struct file_operations proc_kcore_operations; extern const struct file_operations proc_kmsg_operations; extern const struct file_operations ppc_htab_operations; -extern int pid_ns_prepare_proc(struct pid_namespace *ns); -extern void pid_ns_release_proc(struct pid_namespace *ns); - /* * proc_tty.c */ @@ -211,9 +207,7 @@ extern void proc_net_remove(struct net *net, const char *name); #define proc_net_create(net, name, mode, info) ({ (void)(mode), NULL; }) static inline void proc_net_remove(struct net *net, const char *name) {} -static inline void proc_flush_task(struct task_struct *task) -{ -} +static inline void proc_flush_task(struct task_struct *task) { } static inline struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode, struct proc_dir_entry *parent) { return NULL; } @@ -238,15 +232,6 @@ static inline void proc_tty_unregister_driver(struct tty_driver *driver) {}; extern struct proc_dir_entry proc_root; -static inline int pid_ns_prepare_proc(struct pid_namespace *ns) -{ - return 0; -} - -static inline void pid_ns_release_proc(struct pid_namespace *ns) -{ -} - #endif /* CONFIG_PROC_FS */ #if !defined(CONFIG_PROC_KCORE) diff --git a/trunk/include/linux/reiserfs_fs.h b/trunk/include/linux/reiserfs_fs.h index 72bfccd3da22..8dcf237d3386 100644 --- a/trunk/include/linux/reiserfs_fs.h +++ b/trunk/include/linux/reiserfs_fs.h @@ -85,7 +85,7 @@ void reiserfs_warning(struct super_block *s, const char *fmt, ...); if( !( cond ) ) \ reiserfs_panic( NULL, "reiserfs[%i]: assertion " scond " failed at " \ __FILE__ ":%i:%s: " format "\n", \ - in_interrupt() ? -1 : task_pid_nr(current), __LINE__ , __FUNCTION__ , ##args ) + in_interrupt() ? -1 : current -> pid, __LINE__ , __FUNCTION__ , ##args ) #define RASSERT(cond, format, args...) __RASSERT(cond, #cond, format, ##args) @@ -283,18 +283,6 @@ static inline struct reiserfs_sb_info *REISERFS_SB(const struct super_block *sb) return sb->s_fs_info; } -/* Don't trust REISERFS_SB(sb)->s_bmap_nr, it's a u16 - * which overflows on large file systems. */ -static inline u32 reiserfs_bmap_count(struct super_block *sb) -{ - return (SB_BLOCK_COUNT(sb) - 1) / (sb->s_blocksize * 8) + 1; -} - -static inline int bmap_would_wrap(unsigned bmap_nr) -{ - return bmap_nr > ((1LL << 16) - 1); -} - /** this says about version of key of all items (but stat data) the object consists of */ #define get_inode_item_key_version( inode ) \ @@ -1746,8 +1734,8 @@ int journal_end_sync(struct reiserfs_transaction_handle *, struct super_block *, int journal_mark_freed(struct reiserfs_transaction_handle *, struct super_block *, b_blocknr_t blocknr); int journal_transaction_should_end(struct reiserfs_transaction_handle *, int); -int reiserfs_in_journal(struct super_block *p_s_sb, unsigned int bmap_nr, - int bit_nr, int searchall, b_blocknr_t *next); +int reiserfs_in_journal(struct super_block *p_s_sb, int bmap_nr, int bit_nr, + int searchall, b_blocknr_t * next); int journal_begin(struct reiserfs_transaction_handle *, struct super_block *p_s_sb, unsigned long); int journal_join_abort(struct reiserfs_transaction_handle *, @@ -1755,7 +1743,7 @@ int journal_join_abort(struct reiserfs_transaction_handle *, void reiserfs_journal_abort(struct super_block *sb, int errno); void reiserfs_abort(struct super_block *sb, int errno, const char *fmt, ...); int reiserfs_allocate_list_bitmaps(struct super_block *s, - struct reiserfs_list_bitmap *, unsigned int); + struct reiserfs_list_bitmap *, int); void add_save_link(struct reiserfs_transaction_handle *th, struct inode *inode, int truncate); @@ -2053,7 +2041,7 @@ struct buffer_head *get_FEB(struct tree_balance *); * arguments, such as node, search path, transaction_handle, etc. */ struct __reiserfs_blocknr_hint { struct inode *inode; /* inode passed to allocator, if we allocate unf. nodes */ - sector_t block; /* file offset, in blocks */ + long block; /* file offset, in blocks */ struct in_core_key key; struct treepath *path; /* search path, used by allocator to deternine search_start by * various ways */ @@ -2111,8 +2099,7 @@ static inline int reiserfs_new_form_blocknrs(struct tree_balance *tb, static inline int reiserfs_new_unf_blocknrs(struct reiserfs_transaction_handle *th, struct inode *inode, b_blocknr_t * new_blocknrs, - struct treepath *path, - sector_t block) + struct treepath *path, long block) { reiserfs_blocknr_hint_t hint = { .th = th, @@ -2129,8 +2116,7 @@ static inline int reiserfs_new_unf_blocknrs(struct reiserfs_transaction_handle static inline int reiserfs_new_unf_blocknrs2(struct reiserfs_transaction_handle *th, struct inode *inode, b_blocknr_t * new_blocknrs, - struct treepath *path, - sector_t block) + struct treepath *path, long block) { reiserfs_blocknr_hint_t hint = { .th = th, diff --git a/trunk/include/linux/reiserfs_fs_sb.h b/trunk/include/linux/reiserfs_fs_sb.h index 10fa0c832018..ff9e9234f8ba 100644 --- a/trunk/include/linux/reiserfs_fs_sb.h +++ b/trunk/include/linux/reiserfs_fs_sb.h @@ -265,7 +265,9 @@ enum journal_state_bits { typedef __u32(*hashf_t) (const signed char *, int); struct reiserfs_bitmap_info { - __u32 free_count; + // FIXME: Won't work with block sizes > 8K + __u16 first_zero_hint; + __u16 free_count; }; struct proc_dir_entry; diff --git a/trunk/include/linux/sched.h b/trunk/include/linux/sched.h index 13df99fb2769..c204ab0d4df1 100644 --- a/trunk/include/linux/sched.h +++ b/trunk/include/linux/sched.h @@ -25,7 +25,6 @@ #define CLONE_NEWUTS 0x04000000 /* New utsname group? */ #define CLONE_NEWIPC 0x08000000 /* New ipcs */ #define CLONE_NEWUSER 0x10000000 /* New user namespace */ -#define CLONE_NEWPID 0x20000000 /* New pid namespace */ #define CLONE_NEWNET 0x40000000 /* New network namespace */ /* @@ -429,17 +428,7 @@ struct signal_struct { cputime_t it_prof_incr, it_virt_incr; /* job control IDs */ - - /* - * pgrp and session fields are deprecated. - * use the task_session_Xnr and task_pgrp_Xnr routines below - */ - - union { - pid_t pgrp __deprecated; - pid_t __pgrp; - }; - + pid_t pgrp; struct pid *tty_old_pgrp; union { @@ -580,7 +569,7 @@ struct sched_info { last_queued; /* when we were last queued to run */ #ifdef CONFIG_SCHEDSTATS /* BKL stats */ - unsigned int bkl_count; + unsigned long bkl_count; #endif }; #endif /* defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) */ @@ -716,39 +705,37 @@ struct sched_domain { #ifdef CONFIG_SCHEDSTATS /* load_balance() stats */ - unsigned int lb_count[CPU_MAX_IDLE_TYPES]; - unsigned int lb_failed[CPU_MAX_IDLE_TYPES]; - unsigned int lb_balanced[CPU_MAX_IDLE_TYPES]; - unsigned int lb_imbalance[CPU_MAX_IDLE_TYPES]; - unsigned int lb_gained[CPU_MAX_IDLE_TYPES]; - unsigned int lb_hot_gained[CPU_MAX_IDLE_TYPES]; - unsigned int lb_nobusyg[CPU_MAX_IDLE_TYPES]; - unsigned int lb_nobusyq[CPU_MAX_IDLE_TYPES]; + unsigned long lb_count[CPU_MAX_IDLE_TYPES]; + unsigned long lb_failed[CPU_MAX_IDLE_TYPES]; + unsigned long lb_balanced[CPU_MAX_IDLE_TYPES]; + unsigned long lb_imbalance[CPU_MAX_IDLE_TYPES]; + unsigned long lb_gained[CPU_MAX_IDLE_TYPES]; + unsigned long lb_hot_gained[CPU_MAX_IDLE_TYPES]; + unsigned long lb_nobusyg[CPU_MAX_IDLE_TYPES]; + unsigned long lb_nobusyq[CPU_MAX_IDLE_TYPES]; /* Active load balancing */ - unsigned int alb_count; - unsigned int alb_failed; - unsigned int alb_pushed; + unsigned long alb_count; + unsigned long alb_failed; + unsigned long alb_pushed; /* SD_BALANCE_EXEC stats */ - unsigned int sbe_count; - unsigned int sbe_balanced; - unsigned int sbe_pushed; + unsigned long sbe_count; + unsigned long sbe_balanced; + unsigned long sbe_pushed; /* SD_BALANCE_FORK stats */ - unsigned int sbf_count; - unsigned int sbf_balanced; - unsigned int sbf_pushed; + unsigned long sbf_count; + unsigned long sbf_balanced; + unsigned long sbf_pushed; /* try_to_wake_up() stats */ - unsigned int ttwu_wake_remote; - unsigned int ttwu_move_affine; - unsigned int ttwu_move_balance; + unsigned long ttwu_wake_remote; + unsigned long ttwu_move_affine; + unsigned long ttwu_move_balance; #endif }; -extern void partition_sched_domains(int ndoms_new, cpumask_t *doms_new); - #endif /* CONFIG_SMP */ /* @@ -769,6 +756,8 @@ static inline int above_background_load(void) } struct io_context; /* See blkdev.h */ +struct cpuset; + #define NGROUPS_SMALL 32 #define NGROUPS_PER_BLOCK ((int)(PAGE_SIZE / sizeof(gid_t))) struct group_info { @@ -1002,7 +991,7 @@ struct task_struct { int __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */ unsigned int rt_priority; - cputime_t utime, stime, utimescaled, stimescaled; + cputime_t utime, stime; cputime_t gtime; unsigned long nvcsw, nivcsw; /* context switch counts */ struct timespec start_time; /* monotonic time */ @@ -1121,6 +1110,13 @@ struct task_struct { unsigned long ptrace_message; siginfo_t *last_siginfo; /* For ptrace use. */ +/* + * current io wait handle: wait queue entry to use for io waits + * If this thread is processing aio, this points at the waitqueue + * inside the currently handled kiocb. It may be NULL (i.e. default + * to a stack based synchronous wait) if its doing sync IO. + */ + wait_queue_t *io_wait; #ifdef CONFIG_TASK_XACCT /* i/o counters(bytes read/written, #syscalls */ u64 rchar, wchar, syscr, syscw; @@ -1136,16 +1132,11 @@ struct task_struct { short il_next; #endif #ifdef CONFIG_CPUSETS + struct cpuset *cpuset; nodemask_t mems_allowed; int cpuset_mems_generation; int cpuset_mem_spread_rotor; #endif -#ifdef CONFIG_CGROUPS - /* Control Group info protected by css_set_lock */ - struct css_set *cgroups; - /* 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 @@ -1201,14 +1192,24 @@ static inline int rt_task(struct task_struct *p) return rt_prio(p->prio); } -static inline void set_task_session(struct task_struct *tsk, pid_t session) +static inline pid_t process_group(struct task_struct *tsk) +{ + return tsk->signal->pgrp; +} + +static inline pid_t signal_session(struct signal_struct *sig) { - tsk->signal->__session = session; + return sig->__session; } -static inline void set_task_pgrp(struct task_struct *tsk, pid_t pgrp) +static inline pid_t process_session(struct task_struct *tsk) { - tsk->signal->__pgrp = pgrp; + return signal_session(tsk->signal); +} + +static inline void set_signal_session(struct signal_struct *sig, pid_t session) +{ + sig->__session = session; } static inline struct pid *task_pid(struct task_struct *task) @@ -1231,88 +1232,6 @@ static inline struct pid *task_session(struct task_struct *task) return task->group_leader->pids[PIDTYPE_SID].pid; } -struct pid_namespace; - -/* - * the helpers to get the task's different pids as they are seen - * from various namespaces - * - * task_xid_nr() : global id, i.e. the id seen from the init namespace; - * task_xid_vnr() : virtual id, i.e. the id seen from the namespace the task - * belongs to. this only makes sence when called in the - * context of the task that belongs to the same namespace; - * task_xid_nr_ns() : id seen from the ns specified; - * - * set_task_vxid() : assigns a virtual id to a task; - * - * task_ppid_nr_ns() : the parent's id as seen from the namespace specified. - * the result depends on the namespace and whether the - * task in question is the namespace's init. e.g. for the - * namespace's init this will return 0 when called from - * the namespace of this init, or appropriate id otherwise. - * - * - * see also pid_nr() etc in include/linux/pid.h - */ - -static inline pid_t task_pid_nr(struct task_struct *tsk) -{ - return tsk->pid; -} - -pid_t task_pid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns); - -static inline pid_t task_pid_vnr(struct task_struct *tsk) -{ - return pid_vnr(task_pid(tsk)); -} - - -static inline pid_t task_tgid_nr(struct task_struct *tsk) -{ - return tsk->tgid; -} - -pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns); - -static inline pid_t task_tgid_vnr(struct task_struct *tsk) -{ - return pid_vnr(task_tgid(tsk)); -} - - -static inline pid_t task_pgrp_nr(struct task_struct *tsk) -{ - return tsk->signal->__pgrp; -} - -pid_t task_pgrp_nr_ns(struct task_struct *tsk, struct pid_namespace *ns); - -static inline pid_t task_pgrp_vnr(struct task_struct *tsk) -{ - return pid_vnr(task_pgrp(tsk)); -} - - -static inline pid_t task_session_nr(struct task_struct *tsk) -{ - return tsk->signal->__session; -} - -pid_t task_session_nr_ns(struct task_struct *tsk, struct pid_namespace *ns); - -static inline pid_t task_session_vnr(struct task_struct *tsk) -{ - return pid_vnr(task_session(tsk)); -} - - -static inline pid_t task_ppid_nr_ns(struct task_struct *tsk, - struct pid_namespace *ns) -{ - return pid_nr_ns(task_pid(rcu_dereference(tsk->real_parent)), ns); -} - /** * pid_alive - check that a task structure is not stale * @p: Task structure to be checked. @@ -1327,22 +1246,16 @@ static inline int pid_alive(struct task_struct *p) } /** - * is_global_init - check if a task structure is init + * is_init - check if a task structure is init * @tsk: Task structure to be checked. * * Check if a task structure is the first user space task the kernel created. */ -static inline int is_global_init(struct task_struct *tsk) +static inline int is_init(struct task_struct *tsk) { return tsk->pid == 1; } -/* - * is_container_init: - * check whether in the task is init in its own pid namespace. - */ -extern int is_container_init(struct task_struct *tsk); - extern struct pid *cad_pid; extern void free_task(struct task_struct *tsk); @@ -1514,32 +1427,8 @@ extern struct task_struct init_task; extern struct mm_struct init_mm; -extern struct pid_namespace init_pid_ns; - -/* - * find a task by one of its numerical ids - * - * find_task_by_pid_type_ns(): - * it is the most generic call - it finds a task by all id, - * type and namespace specified - * find_task_by_pid_ns(): - * finds a task by its pid in the specified namespace - * find_task_by_vpid(): - * finds a task by its virtual pid - * find_task_by_pid(): - * finds a task by its global pid - * - * see also find_pid() etc in include/linux/pid.h - */ - -extern struct task_struct *find_task_by_pid_type_ns(int type, int pid, - struct pid_namespace *ns); - -extern struct task_struct *find_task_by_pid(pid_t nr); -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); - +#define find_task_by_pid(nr) find_task_by_pid_type(PIDTYPE_PID, nr) +extern struct task_struct *find_task_by_pid_type(int type, int pid); extern void __set_special_pids(pid_t session, pid_t pgrp); /* per-UID process charging. */ @@ -1726,12 +1615,6 @@ static inline int has_group_leader_pid(struct task_struct *p) return p->pid == p->tgid; } -static inline -int same_thread_group(struct task_struct *p1, struct task_struct *p2) -{ - return p1->tgid == p2->tgid; -} - static inline struct task_struct *next_thread(const struct task_struct *p) { return list_entry(rcu_dereference(p->thread_group.next), @@ -1749,8 +1632,7 @@ static inline int thread_group_empty(struct task_struct *p) /* * Protects ->fs, ->files, ->mm, ->group_info, ->comm, keyring * subscriptions and synchronises with wait4(). Also used in procfs. Also - * pins the final release of task.io_context. Also protects ->cpuset and - * ->cgroup.subsys[]. + * pins the final release of task.io_context. Also protects ->cpuset. * * Nests both inside and outside of read_lock(&tasklist_lock). * It must not be nested with write_lock_irq(&tasklist_lock), diff --git a/trunk/include/linux/security.h b/trunk/include/linux/security.h index ff3f857f6957..9b0b63c50f44 100644 --- a/trunk/include/linux/security.h +++ b/trunk/include/linux/security.h @@ -34,13 +34,6 @@ #include #include -/* - * Bounding set - */ -extern kernel_cap_t cap_bset; - -extern unsigned securebits; - struct ctl_table; /* diff --git a/trunk/include/linux/sem.h b/trunk/include/linux/sem.h index c8eaad9e4b72..9aaffb0b1d81 100644 --- a/trunk/include/linux/sem.h +++ b/trunk/include/linux/sem.h @@ -90,6 +90,7 @@ struct sem { /* One sem_array data structure for each set of semaphores in the system. */ struct sem_array { struct kern_ipc_perm sem_perm; /* permissions .. see ipc.h */ + int sem_id; time_t sem_otime; /* last semop time */ time_t sem_ctime; /* last change time */ struct sem *sem_base; /* ptr to first semaphore in array */ diff --git a/trunk/include/linux/shm.h b/trunk/include/linux/shm.h index eeaed921a1dc..bea65d9c93ef 100644 --- a/trunk/include/linux/shm.h +++ b/trunk/include/linux/shm.h @@ -79,6 +79,7 @@ struct shmid_kernel /* private to the kernel */ { struct kern_ipc_perm shm_perm; struct file * shm_file; + int id; unsigned long shm_nattch; unsigned long shm_segsz; time_t shm_atim; diff --git a/trunk/include/linux/suspend.h b/trunk/include/linux/suspend.h index 4360e0816956..388cace9751f 100644 --- a/trunk/include/linux/suspend.h +++ b/trunk/include/linux/suspend.h @@ -1,5 +1,5 @@ -#ifndef _LINUX_SUSPEND_H -#define _LINUX_SUSPEND_H +#ifndef _LINUX_SWSUSP_H +#define _LINUX_SWSUSP_H #if defined(CONFIG_X86) || defined(CONFIG_FRV) || defined(CONFIG_PPC32) || defined(CONFIG_PPC64) #include @@ -9,108 +9,6 @@ #include #include #include -#include - -#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_VT) && defined(CONFIG_VT_CONSOLE) -extern int pm_prepare_console(void); -extern void pm_restore_console(void); -#else -static inline int pm_prepare_console(void) { return 0; } -static inline void pm_restore_console(void) {} -#endif - -typedef int __bitwise suspend_state_t; - -#define PM_SUSPEND_ON ((__force suspend_state_t) 0) -#define PM_SUSPEND_STANDBY ((__force suspend_state_t) 1) -#define PM_SUSPEND_MEM ((__force suspend_state_t) 3) -#define PM_SUSPEND_MAX ((__force suspend_state_t) 4) - -/** - * struct platform_suspend_ops - Callbacks for managing platform dependent - * system sleep states. - * - * @valid: Callback to determine if given system sleep state is supported by - * the platform. - * Valid (ie. supported) states are advertised in /sys/power/state. Note - * that it still may be impossible to enter given system sleep state if the - * conditions aren't right. - * There is the %suspend_valid_only_mem function available that can be - * assigned to this if the platform only supports mem sleep. - * - * @set_target: Tell the platform which system sleep state is going to be - * entered. - * @set_target() is executed right prior to suspending devices. The - * information conveyed to the platform code by @set_target() should be - * disregarded by the platform as soon as @finish() is executed and if - * @prepare() fails. If @set_target() fails (ie. returns nonzero), - * @prepare(), @enter() and @finish() will not be called by the PM core. - * This callback is optional. However, if it is implemented, the argument - * passed to @enter() is meaningless and should be ignored. - * - * @prepare: Prepare the platform for entering the system sleep state indicated - * by @set_target(). - * @prepare() is called right after devices have been suspended (ie. the - * appropriate .suspend() method has been executed for each device) and - * before the nonboot CPUs are disabled (it is executed with IRQs enabled). - * This callback is optional. It returns 0 on success or a negative - * error code otherwise, in which case the system cannot enter the desired - * sleep state (@enter() and @finish() will not be called in that case). - * - * @enter: Enter the system sleep state indicated by @set_target() or - * represented by the argument if @set_target() is not implemented. - * This callback is mandatory. It returns 0 on success or a negative - * error code otherwise, in which case the system cannot enter the desired - * sleep state. - * - * @finish: Called when the system has just left a sleep state, right after - * the nonboot CPUs have been enabled and before devices are resumed (it is - * executed with IRQs enabled). - * This callback is optional, but should be implemented by the platforms - * that implement @prepare(). If implemented, it is always called after - * @enter() (even if @enter() fails). - */ -struct platform_suspend_ops { - int (*valid)(suspend_state_t state); - int (*set_target)(suspend_state_t state); - int (*prepare)(void); - int (*enter)(suspend_state_t state); - void (*finish)(void); -}; - -#ifdef CONFIG_SUSPEND -/** - * suspend_set_ops - set platform dependent suspend operations - * @ops: The new suspend operations to set. - */ -extern void suspend_set_ops(struct platform_suspend_ops *ops); -extern int suspend_valid_only_mem(suspend_state_t state); - -/** - * arch_suspend_disable_irqs - disable IRQs for suspend - * - * Disables IRQs (in the default case). This is a weak symbol in the common - * code and thus allows architectures to override it if more needs to be - * done. Not called for suspend to disk. - */ -extern void arch_suspend_disable_irqs(void); - -/** - * arch_suspend_enable_irqs - enable IRQs after suspend - * - * Enables IRQs (in the default case). This is a weak symbol in the common - * code and thus allows architectures to override it if more needs to be - * done. Not called for suspend to disk. - */ -extern void arch_suspend_enable_irqs(void); - -extern int pm_suspend(suspend_state_t state); -#else /* !CONFIG_SUSPEND */ -#define suspend_valid_only_mem NULL - -static inline void suspend_set_ops(struct platform_suspend_ops *ops) {} -static inline int pm_suspend(suspend_state_t state) { return -ENOSYS; } -#endif /* !CONFIG_SUSPEND */ /* struct pbe is used for creating lists of pages that should be restored * atomically during the resume from disk, because the page frames they have @@ -126,57 +24,32 @@ struct pbe { extern void drain_local_pages(void); extern void mark_free_pages(struct zone *zone); +#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_VT) && defined(CONFIG_VT_CONSOLE) +extern int pm_prepare_console(void); +extern void pm_restore_console(void); +#else +static inline int pm_prepare_console(void) { return 0; } +static inline void pm_restore_console(void) {} +#endif + /** - * struct platform_hibernation_ops - hibernation platform support + * struct hibernation_ops - hibernation platform support * * The methods in this structure allow a platform to override the default * mechanism of shutting down the machine during a hibernation transition. * * All three methods must be assigned. * - * @start: Tell the platform driver that we're starting hibernation. - * Called right after shrinking memory and before freezing devices. - * - * @pre_snapshot: Prepare the platform for creating the hibernation image. - * Called right after devices have been frozen and before the nonboot - * CPUs are disabled (runs with IRQs on). - * - * @finish: Restore the previous state of the platform after the hibernation - * image has been created *or* put the platform into the normal operation - * mode after the hibernation (the same method is executed in both cases). - * Called right after the nonboot CPUs have been enabled and before - * thawing devices (runs with IRQs on). - * - * @prepare: Prepare the platform for entering the low power state. - * Called right after the hibernation image has been saved and before - * devices are prepared for entering the low power state. - * - * @enter: Put the system into the low power state after the hibernation image - * has been saved to disk. - * Called after the nonboot CPUs have been disabled and all of the low - * level devices have been shut down (runs with IRQs off). - * - * @leave: Perform the first stage of the cleanup after the system sleep state - * indicated by @set_target() has been left. - * Called right after the control has been passed from the boot kernel to - * the image kernel, before the nonboot CPUs are enabled and before devices - * are resumed. Executed with interrupts disabled. - * - * @pre_restore: Prepare system for the restoration from a hibernation image. - * Called right after devices have been frozen and before the nonboot - * CPUs are disabled (runs with IRQs on). - * - * @restore_cleanup: Clean up after a failing image restoration. - * Called right after the nonboot CPUs have been enabled and before - * thawing devices (runs with IRQs on). + * @prepare: prepare system for hibernation + * @enter: shut down system after state has been saved to disk + * @finish: finish/clean up after state has been reloaded + * @pre_restore: prepare system for the restoration from a hibernation image + * @restore_cleanup: clean up after a failing image restoration */ -struct platform_hibernation_ops { - int (*start)(void); - int (*pre_snapshot)(void); - void (*finish)(void); +struct hibernation_ops { int (*prepare)(void); int (*enter)(void); - void (*leave)(void); + void (*finish)(void); int (*pre_restore)(void); void (*restore_cleanup)(void); }; @@ -197,14 +70,14 @@ extern void swsusp_set_page_free(struct page *); extern void swsusp_unset_page_free(struct page *); extern unsigned long get_safe_page(gfp_t gfp_mask); -extern void hibernation_set_ops(struct platform_hibernation_ops *ops); +extern void hibernation_set_ops(struct hibernation_ops *ops); extern int hibernate(void); #else /* CONFIG_HIBERNATION */ static inline int swsusp_page_is_forbidden(struct page *p) { return 0; } static inline void swsusp_set_page_free(struct page *p) {} static inline void swsusp_unset_page_free(struct page *p) {} -static inline void hibernation_set_ops(struct platform_hibernation_ops *ops) {} +static inline void hibernation_set_ops(struct hibernation_ops *ops) {} static inline int hibernate(void) { return -ENOSYS; } #endif /* CONFIG_HIBERNATION */ @@ -257,4 +130,4 @@ static inline void register_nosave_region_late(unsigned long b, unsigned long e) } #endif -#endif /* _LINUX_SUSPEND_H */ +#endif /* _LINUX_SWSUSP_H */ diff --git a/trunk/include/linux/sysctl.h b/trunk/include/linux/sysctl.h index e99171f01b4c..483050c924c3 100644 --- a/trunk/include/linux/sysctl.h +++ b/trunk/include/linux/sysctl.h @@ -238,7 +238,6 @@ enum NET_LLC=18, NET_NETFILTER=19, NET_DCCP=20, - NET_IRDA=412, }; /* /proc/sys/kernel/random */ @@ -796,25 +795,6 @@ enum { NET_BRIDGE_NF_FILTER_PPPOE_TAGGED = 5, }; -/* proc/sys/net/irda */ -enum { - NET_IRDA_DISCOVERY=1, - NET_IRDA_DEVNAME=2, - NET_IRDA_DEBUG=3, - NET_IRDA_FAST_POLL=4, - NET_IRDA_DISCOVERY_SLOTS=5, - NET_IRDA_DISCOVERY_TIMEOUT=6, - NET_IRDA_SLOT_TIMEOUT=7, - NET_IRDA_MAX_BAUD_RATE=8, - NET_IRDA_MIN_TX_TURN_TIME=9, - NET_IRDA_MAX_TX_DATA_SIZE=10, - NET_IRDA_MAX_TX_WINDOW=11, - NET_IRDA_MAX_NOREPLY_TIME=12, - NET_IRDA_WARN_NOREPLY_TIME=13, - NET_IRDA_LAP_KEEPALIVE_TIME=14, -}; - - /* CTL_FS names: */ enum { @@ -957,42 +937,41 @@ extern int sysctl_perm(struct ctl_table *table, int op); typedef struct ctl_table ctl_table; -typedef int ctl_handler (struct ctl_table *table, int __user *name, int nlen, +typedef int ctl_handler (ctl_table *table, int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp, void __user *newval, size_t newlen); -typedef int proc_handler (struct ctl_table *ctl, int write, struct file * filp, +typedef int proc_handler (ctl_table *ctl, int write, struct file * filp, void __user *buffer, size_t *lenp, loff_t *ppos); -extern int proc_dostring(struct ctl_table *, int, struct file *, +extern int proc_dostring(ctl_table *, int, struct file *, void __user *, size_t *, loff_t *); -extern int proc_dointvec(struct ctl_table *, int, struct file *, +extern int proc_dointvec(ctl_table *, int, struct file *, void __user *, size_t *, loff_t *); -extern int proc_dointvec_bset(struct ctl_table *, int, struct file *, +extern int proc_dointvec_bset(ctl_table *, int, struct file *, void __user *, size_t *, loff_t *); -extern int proc_dointvec_minmax(struct ctl_table *, int, struct file *, +extern int proc_dointvec_minmax(ctl_table *, int, struct file *, void __user *, size_t *, loff_t *); -extern int proc_dointvec_jiffies(struct ctl_table *, int, struct file *, +extern int proc_dointvec_jiffies(ctl_table *, int, struct file *, void __user *, size_t *, loff_t *); -extern int proc_dointvec_userhz_jiffies(struct ctl_table *, int, struct file *, +extern int proc_dointvec_userhz_jiffies(ctl_table *, int, struct file *, void __user *, size_t *, loff_t *); -extern int proc_dointvec_ms_jiffies(struct ctl_table *, int, struct file *, +extern int proc_dointvec_ms_jiffies(ctl_table *, int, struct file *, void __user *, size_t *, loff_t *); -extern int proc_doulongvec_minmax(struct ctl_table *, int, struct file *, +extern int proc_doulongvec_minmax(ctl_table *, int, struct file *, void __user *, size_t *, loff_t *); -extern int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int, +extern int proc_doulongvec_ms_jiffies_minmax(ctl_table *table, int, struct file *, void __user *, size_t *, loff_t *); extern int do_sysctl (int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp, void __user *newval, size_t newlen); -extern int do_sysctl_strategy (struct ctl_table *table, +extern int do_sysctl_strategy (ctl_table *table, int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp, void __user *newval, size_t newlen); -extern ctl_handler sysctl_data; extern ctl_handler sysctl_string; extern ctl_handler sysctl_intvec; extern ctl_handler sysctl_jiffies; @@ -1001,7 +980,7 @@ extern ctl_handler sysctl_ms_jiffies; /* * Register a set of sysctl names by calling register_sysctl_table - * with an initialised array of struct ctl_table's. An entry with zero + * with an initialised array of ctl_table's. An entry with zero * ctl_name and NULL procname terminates the table. table->de will be * set up by the registration and need not be initialised in advance. * @@ -1047,8 +1026,8 @@ struct ctl_table void *data; int maxlen; mode_t mode; - struct ctl_table *child; - struct ctl_table *parent; /* Automatically set */ + ctl_table *child; + ctl_table *parent; /* Automatically set */ proc_handler *proc_handler; /* Callback for text formatting */ ctl_handler *strategy; /* Callback function for all r/w */ void *extra1; @@ -1056,19 +1035,18 @@ struct ctl_table }; /* struct ctl_table_header is used to maintain dynamic lists of - struct ctl_table trees. */ + ctl_table trees. */ struct ctl_table_header { - struct ctl_table *ctl_table; + ctl_table *ctl_table; struct list_head ctl_entry; int used; struct completion *unregistering; }; -struct ctl_table_header *register_sysctl_table(struct ctl_table * table); +struct ctl_table_header * register_sysctl_table(ctl_table * table); void unregister_sysctl_table(struct ctl_table_header * table); -int sysctl_check_table(struct ctl_table *table); #else /* __KERNEL__ */ diff --git a/trunk/include/linux/taskstats.h b/trunk/include/linux/taskstats.h index 5d69c0744fff..dce1ed204972 100644 --- a/trunk/include/linux/taskstats.h +++ b/trunk/include/linux/taskstats.h @@ -31,7 +31,7 @@ */ -#define TASKSTATS_VERSION 6 +#define TASKSTATS_VERSION 5 #define TS_COMM_LEN 32 /* should be >= TASK_COMM_LEN * in linux/sched.h */ @@ -152,11 +152,6 @@ struct taskstats { __u64 nvcsw; /* voluntary_ctxt_switches */ __u64 nivcsw; /* nonvoluntary_ctxt_switches */ - - /* time accounting for SMT machines */ - __u64 ac_utimescaled; /* utime scaled on frequency etc */ - __u64 ac_stimescaled; /* stime scaled on frequency etc */ - __u64 cpu_scaled_run_real_total; /* scaled cpu_run_real_total */ }; diff --git a/trunk/include/linux/tick.h b/trunk/include/linux/tick.h index f4a1395e05ff..9a7252e089b9 100644 --- a/trunk/include/linux/tick.h +++ b/trunk/include/linux/tick.h @@ -40,7 +40,6 @@ enum tick_nohz_mode { * @idle_sleeps: Number of idle calls, where the sched tick was stopped * @idle_entrytime: Time when the idle call was entered * @idle_sleeptime: Sum of the time slept in idle with sched tick stopped - * @sleep_length: Duration of the current idle sleep */ struct tick_sched { struct hrtimer sched_timer; @@ -53,7 +52,6 @@ struct tick_sched { unsigned long idle_sleeps; ktime_t idle_entrytime; ktime_t idle_sleeptime; - ktime_t sleep_length; unsigned long last_jiffies; unsigned long next_jiffies; ktime_t idle_expires; @@ -102,17 +100,10 @@ static inline int tick_check_oneshot_change(int allow_nohz) { return 0; } extern void tick_nohz_stop_sched_tick(void); extern void tick_nohz_restart_sched_tick(void); extern void tick_nohz_update_jiffies(void); -extern ktime_t tick_nohz_get_sleep_length(void); # else static inline void tick_nohz_stop_sched_tick(void) { } static inline void tick_nohz_restart_sched_tick(void) { } static inline void tick_nohz_update_jiffies(void) { } -static inline ktime_t tick_nohz_get_sleep_length(void) -{ - ktime_t len = { .tv64 = NSEC_PER_SEC/HZ }; - - return len; -} # endif /* !NO_HZ */ #endif diff --git a/trunk/include/linux/types.h b/trunk/include/linux/types.h index 4f0dad21c917..0351bf2fac85 100644 --- a/trunk/include/linux/types.h +++ b/trunk/include/linux/types.h @@ -3,9 +3,12 @@ #ifdef __KERNEL__ +#define BITS_TO_LONGS(bits) \ + (((bits)+BITS_PER_LONG-1)/BITS_PER_LONG) #define DECLARE_BITMAP(name,bits) \ unsigned long name[BITS_TO_LONGS(bits)] +#define BITS_PER_BYTE 8 #endif #include diff --git a/trunk/include/linux/uinput.h b/trunk/include/linux/uinput.h index 15ddd4483b09..a6c1e8eed226 100644 --- a/trunk/include/linux/uinput.h +++ b/trunk/include/linux/uinput.h @@ -162,6 +162,10 @@ struct uinput_ff_erase { #define UI_FF_UPLOAD 1 #define UI_FF_ERASE 2 +#ifndef NBITS +#define NBITS(x) ((((x)-1)/(sizeof(long)*8))+1) +#endif /* NBITS */ + #define UINPUT_MAX_NAME_SIZE 80 struct uinput_user_dev { char name[UINPUT_MAX_NAME_SIZE]; diff --git a/trunk/include/linux/vt.h b/trunk/include/linux/vt.h index 02c1c0288770..ba806e8711be 100644 --- a/trunk/include/linux/vt.h +++ b/trunk/include/linux/vt.h @@ -1,18 +1,6 @@ #ifndef _LINUX_VT_H #define _LINUX_VT_H -#ifdef __KERNEL__ -struct notifier_block; - -struct vt_notifier_param { - struct vc_data *vc; /* VC on which the update happened */ - unsigned int c; /* Printed char */ -}; - -extern int register_vt_notifier(struct notifier_block *nb); -extern int unregister_vt_notifier(struct notifier_block *nb); -#endif - /* * These constants are also useful for user-level apps (e.g., VC * resizing). diff --git a/trunk/include/linux/workqueue.h b/trunk/include/linux/workqueue.h index 7daafdc2514b..ce6badc98f6d 100644 --- a/trunk/include/linux/workqueue.h +++ b/trunk/include/linux/workqueue.h @@ -8,7 +8,6 @@ #include #include #include -#include #include struct workqueue_struct; @@ -29,9 +28,6 @@ struct work_struct { #define WORK_STRUCT_WQ_DATA_MASK (~WORK_STRUCT_FLAG_MASK) struct list_head entry; work_func_t func; -#ifdef CONFIG_LOCKDEP - struct lockdep_map lockdep_map; -#endif }; #define WORK_DATA_INIT() ATOMIC_LONG_INIT(0) @@ -45,23 +41,10 @@ struct execute_work { struct work_struct work; }; -#ifdef CONFIG_LOCKDEP -/* - * NB: because we have to copy the lockdep_map, setting _key - * here is required, otherwise it could get initialised to the - * copy of the lockdep_map! - */ -#define __WORK_INIT_LOCKDEP_MAP(n, k) \ - .lockdep_map = STATIC_LOCKDEP_MAP_INIT(n, k), -#else -#define __WORK_INIT_LOCKDEP_MAP(n, k) -#endif - #define __WORK_INITIALIZER(n, f) { \ .data = WORK_DATA_INIT(), \ .entry = { &(n).entry, &(n).entry }, \ .func = (f), \ - __WORK_INIT_LOCKDEP_MAP(#n, &(n)) \ } #define __DELAYED_WORK_INITIALIZER(n, f) { \ @@ -93,24 +76,12 @@ struct execute_work { * assignment of the work data initializer allows the compiler * to generate better code. */ -#ifdef CONFIG_LOCKDEP -#define INIT_WORK(_work, _func) \ - do { \ - static struct lock_class_key __key; \ - \ - (_work)->data = (atomic_long_t) WORK_DATA_INIT(); \ - lockdep_init_map(&(_work)->lockdep_map, #_work, &__key, 0);\ - INIT_LIST_HEAD(&(_work)->entry); \ - PREPARE_WORK((_work), (_func)); \ - } while (0) -#else #define INIT_WORK(_work, _func) \ do { \ (_work)->data = (atomic_long_t) WORK_DATA_INIT(); \ INIT_LIST_HEAD(&(_work)->entry); \ PREPARE_WORK((_work), (_func)); \ } while (0) -#endif #define INIT_DELAYED_WORK(_work, _func) \ do { \ @@ -147,23 +118,9 @@ struct execute_work { clear_bit(WORK_STRUCT_PENDING, work_data_bits(work)) -extern struct workqueue_struct * -__create_workqueue_key(const char *name, int singlethread, - int freezeable, struct lock_class_key *key); - -#ifdef CONFIG_LOCKDEP -#define __create_workqueue(name, singlethread, freezeable) \ -({ \ - static struct lock_class_key __key; \ - \ - __create_workqueue_key((name), (singlethread), \ - (freezeable), &__key); \ -}) -#else -#define __create_workqueue(name, singlethread, freezeable) \ - __create_workqueue_key((name), (singlethread), (freezeable), NULL) -#endif - +extern struct workqueue_struct *__create_workqueue(const char *name, + int singlethread, + int freezeable); #define create_workqueue(name) __create_workqueue((name), 0, 0) #define create_freezeable_workqueue(name) __create_workqueue((name), 1, 1) #define create_singlethread_workqueue(name) __create_workqueue((name), 1, 0) diff --git a/trunk/include/net/9p/9p.h b/trunk/include/net/9p/9p.h index 625346c47ee2..686425a97b0f 100644 --- a/trunk/include/net/9p/9p.h +++ b/trunk/include/net/9p/9p.h @@ -44,7 +44,7 @@ extern unsigned int p9_debug_level; do { \ if ((p9_debug_level & level) == level) \ printk(KERN_NOTICE "-- %s (%d): " \ - format , __FUNCTION__, task_pid_nr(current) , ## arg); \ + format , __FUNCTION__, current->pid , ## arg); \ } while (0) #define PRINT_FCALL_ERROR(s, fcall) P9_DPRINTK(P9_DEBUG_ERROR, \ @@ -59,7 +59,7 @@ do { \ #define P9_EPRINTK(level, format, arg...) \ do { \ printk(level "9p: %s (%d): " \ - format , __FUNCTION__, task_pid_nr(current), ## arg); \ + format , __FUNCTION__, current->pid , ## arg); \ } while (0) diff --git a/trunk/include/net/inet_frag.h b/trunk/include/net/inet_frag.h index 954def408975..911c2cd02941 100644 --- a/trunk/include/net/inet_frag.h +++ b/trunk/include/net/inet_frag.h @@ -39,13 +39,8 @@ struct inet_frags { struct inet_frags_ctl *ctl; unsigned int (*hashfn)(struct inet_frag_queue *); - void (*constructor)(struct inet_frag_queue *q, - void *arg); void (*destructor)(struct inet_frag_queue *); void (*skb_free)(struct sk_buff *); - int (*match)(struct inet_frag_queue *q, - void *arg); - void (*frag_expire)(unsigned long data); }; void inet_frags_init(struct inet_frags *); @@ -55,8 +50,6 @@ void inet_frag_kill(struct inet_frag_queue *q, struct inet_frags *f); void inet_frag_destroy(struct inet_frag_queue *q, struct inet_frags *f, int *work); int inet_frag_evictor(struct inet_frags *f); -struct inet_frag_queue *inet_frag_find(struct inet_frags *f, void *key, - unsigned int hash); static inline void inet_frag_put(struct inet_frag_queue *q, struct inet_frags *f) { diff --git a/trunk/include/net/ipv6.h b/trunk/include/net/ipv6.h index ae328b680ff2..cc796cbc1b26 100644 --- a/trunk/include/net/ipv6.h +++ b/trunk/include/net/ipv6.h @@ -377,17 +377,6 @@ static inline int ipv6_prefix_equal(const struct in6_addr *a1, prefixlen); } -struct inet_frag_queue; - -struct ip6_create_arg { - __be32 id; - struct in6_addr *src; - struct in6_addr *dst; -}; - -void ip6_frag_init(struct inet_frag_queue *q, void *a); -int ip6_frag_match(struct inet_frag_queue *q, void *a); - static inline int ipv6_addr_any(const struct in6_addr *a) { return ((a->s6_addr32[0] | a->s6_addr32[1] | diff --git a/trunk/include/net/scm.h b/trunk/include/net/scm.h index 06df126103ca..423cb1d5ac25 100644 --- a/trunk/include/net/scm.h +++ b/trunk/include/net/scm.h @@ -4,8 +4,6 @@ #include #include #include -#include -#include /* Well, we should have at least one descriptor open * to accept passed FDs 8) @@ -56,7 +54,7 @@ static __inline__ int scm_send(struct socket *sock, struct msghdr *msg, struct task_struct *p = current; scm->creds.uid = p->uid; scm->creds.gid = p->gid; - scm->creds.pid = task_tgid_vnr(p); + scm->creds.pid = p->tgid; scm->fp = NULL; scm->seq = 0; unix_get_peersec_dgram(sock, scm); diff --git a/trunk/include/net/sock.h b/trunk/include/net/sock.h index 43fc3fa50d62..453c79d0915b 100644 --- a/trunk/include/net/sock.h +++ b/trunk/include/net/sock.h @@ -904,6 +904,16 @@ static inline int sk_filter(struct sock *sk, struct sk_buff *skb) return err; } +/** + * sk_filter_rcu_free: Free a socket filter + * @rcu: rcu_head that contains the sk_filter to free + */ +static inline void sk_filter_rcu_free(struct rcu_head *rcu) +{ + struct sk_filter *fp = container_of(rcu, struct sk_filter, rcu); + kfree(fp); +} + /** * sk_filter_release: Release a socket filter * @sk: socket @@ -912,18 +922,14 @@ static inline int sk_filter(struct sock *sk, struct sk_buff *skb) * Remove a filter from a socket and release its resources. */ -static inline void sk_filter_release(struct sk_filter *fp) -{ - if (atomic_dec_and_test(&fp->refcnt)) - kfree(fp); -} - -static inline void sk_filter_uncharge(struct sock *sk, struct sk_filter *fp) +static inline void sk_filter_release(struct sock *sk, struct sk_filter *fp) { unsigned int size = sk_filter_len(fp); atomic_sub(size, &sk->sk_omem_alloc); - sk_filter_release(fp); + + if (atomic_dec_and_test(&fp->refcnt)) + call_rcu_bh(&fp->rcu, sk_filter_rcu_free); } static inline void sk_filter_charge(struct sock *sk, struct sk_filter *fp) diff --git a/trunk/include/net/xfrm.h b/trunk/include/net/xfrm.h index 688f6f5d3285..0e844845f3f4 100644 --- a/trunk/include/net/xfrm.h +++ b/trunk/include/net/xfrm.h @@ -186,8 +186,7 @@ struct xfrm_state /* Reference to data common to all the instances of this * transformer. */ struct xfrm_type *type; - struct xfrm_mode *inner_mode; - struct xfrm_mode *outer_mode; + struct xfrm_mode *mode; /* Security context */ struct xfrm_sec_ctx *security; @@ -229,6 +228,8 @@ struct xfrm_type; struct xfrm_dst; struct xfrm_policy_afinfo { unsigned short family; + struct xfrm_type *type_map[IPPROTO_MAX]; + struct xfrm_mode *mode_map[XFRM_MODE_MAX]; struct dst_ops *dst_ops; void (*garbage_collect)(void); int (*dst_lookup)(struct xfrm_dst **dst, struct flowi *fl); @@ -254,10 +255,7 @@ extern void km_state_expired(struct xfrm_state *x, int hard, u32 pid); extern int __xfrm_state_delete(struct xfrm_state *x); struct xfrm_state_afinfo { - unsigned int family; - struct module *owner; - struct xfrm_type *type_map[IPPROTO_MAX]; - struct xfrm_mode *mode_map[XFRM_MODE_MAX]; + unsigned short family; int (*init_flags)(struct xfrm_state *x); void (*init_tempsel)(struct xfrm_state *x, struct flowi *fl, struct xfrm_tmpl *tmpl, @@ -269,6 +267,8 @@ struct xfrm_state_afinfo { extern int xfrm_state_register_afinfo(struct xfrm_state_afinfo *afinfo); extern int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo); +extern struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned short family); +extern void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo); extern void xfrm_state_delete_tunnel(struct xfrm_state *x); @@ -295,6 +295,8 @@ struct xfrm_type extern int xfrm_register_type(struct xfrm_type *type, unsigned short family); extern int xfrm_unregister_type(struct xfrm_type *type, unsigned short family); +extern struct xfrm_type *xfrm_get_type(u8 proto, unsigned short family); +extern void xfrm_put_type(struct xfrm_type *type); struct xfrm_mode { int (*input)(struct xfrm_state *x, struct sk_buff *skb); @@ -312,19 +314,14 @@ struct xfrm_mode { */ int (*output)(struct xfrm_state *x,struct sk_buff *skb); - struct xfrm_state_afinfo *afinfo; struct module *owner; unsigned int encap; - int flags; -}; - -/* Flags for xfrm_mode. */ -enum { - XFRM_MODE_FLAG_TUNNEL = 1, }; extern int xfrm_register_mode(struct xfrm_mode *mode, int family); extern int xfrm_unregister_mode(struct xfrm_mode *mode, int family); +extern struct xfrm_mode *xfrm_get_mode(unsigned int encap, int family); +extern void xfrm_put_mode(struct xfrm_mode *mode); struct xfrm_tmpl { @@ -1049,19 +1046,11 @@ extern void xfrm_replay_notify(struct xfrm_state *x, int event); extern int xfrm_state_mtu(struct xfrm_state *x, int mtu); extern int xfrm_init_state(struct xfrm_state *x); extern int xfrm_output(struct sk_buff *skb); -extern int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi, - int encap_type); extern int xfrm4_rcv(struct sk_buff *skb); - -static inline int xfrm4_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi) -{ - return xfrm4_rcv_encap(skb, nexthdr, spi, 0); -} - extern int xfrm4_output(struct sk_buff *skb); extern int xfrm4_tunnel_register(struct xfrm_tunnel *handler, unsigned short family); extern int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler, unsigned short family); -extern int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi); +extern int xfrm6_rcv_spi(struct sk_buff *skb, __be32 spi); extern int xfrm6_rcv(struct sk_buff *skb); extern int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr, xfrm_address_t *saddr, u8 proto); diff --git a/trunk/include/video/sstfb.h b/trunk/include/video/sstfb.h index b52f07381243..baa163f770ab 100644 --- a/trunk/include/video/sstfb.h +++ b/trunk/include/video/sstfb.h @@ -68,6 +68,7 @@ # define print_var(X,Y...) #endif +#define BIT(x) (1ul<<(x)) #define POW2(x) (1ul<<(x)) /* diff --git a/trunk/include/video/tdfx.h b/trunk/include/video/tdfx.h index 7431d9681e57..05b63c2a5abc 100644 --- a/trunk/include/video/tdfx.h +++ b/trunk/include/video/tdfx.h @@ -79,6 +79,8 @@ /* register bitfields (not all, only as needed) */ +#define BIT(x) (1UL << (x)) + /* COMMAND_2D reg. values */ #define TDFX_ROP_COPY 0xcc /* src */ #define TDFX_ROP_INVERT 0x55 /* NOT dst */ diff --git a/trunk/init/Kconfig b/trunk/init/Kconfig index 541382d539ad..a29a688c47d3 100644 --- a/trunk/init/Kconfig +++ b/trunk/init/Kconfig @@ -270,43 +270,9 @@ config LOG_BUF_SHIFT 13 => 8 KB 12 => 4 KB -config CGROUPS - bool "Control Group support" - help - This option will let you use process cgroup subsystems - such as Cpusets - - Say N if unsure. - -config CGROUP_DEBUG - bool "Example debug cgroup subsystem" - depends on CGROUPS - help - This option enables a simple cgroup subsystem that - exports useful debugging information about the cgroups - framework - - Say N if unsure - -config CGROUP_NS - bool "Namespace cgroup subsystem" - depends on CGROUPS - help - Provides a simple namespace cgroup subsystem to - provide hierarchical naming of sets of namespaces, - for instance virtual servers and checkpoint/restart - jobs. - -config CGROUP_CPUACCT - bool "Simple CPU accounting cgroup subsystem" - depends on CGROUPS - help - Provides a simple Resource Controller for monitoring the - total CPU consumed by the tasks in a cgroup - config CPUSETS bool "Cpuset support" - depends on SMP && CGROUPS + depends on SMP help This option will let you create and manage CPUSETs which allow dynamically partitioning a system into sets of CPUs and @@ -334,16 +300,6 @@ config FAIR_USER_SCHED This option will choose userid as the basis for grouping tasks, thus providing equal CPU bandwidth to each user. -config FAIR_CGROUP_SCHED - bool "Control groups" - depends on CGROUPS - help - This option allows you to create arbitrary task groups - using the "cgroup" pseudo filesystem and control - the cpu bandwidth allocated to each such task group. - Refer to Documentation/cgroups.txt for more information - on "cgroup" pseudo filesystem. - endchoice config SYSFS_DEPRECATED @@ -366,11 +322,6 @@ config SYSFS_DEPRECATED If you are using a distro that was released in 2006 or later, it should be safe to say N here. -config PROC_PID_CPUSET - bool "Include legacy /proc//cpuset file" - depends on CPUSETS - default y - config RELAY bool "Kernel->user space relay support (formerly relayfs)" help diff --git a/trunk/init/do_mounts_rd.c b/trunk/init/do_mounts_rd.c index 3ac5904d1b12..ed652f40f075 100644 --- a/trunk/init/do_mounts_rd.c +++ b/trunk/init/do_mounts_rd.c @@ -57,7 +57,7 @@ identify_ramdisk_image(int fd, int start_block) unsigned char *buf; buf = kmalloc(size, GFP_KERNEL); - if (!buf) + if (buf == 0) return -1; minixsb = (struct minix_super_block *) buf; @@ -407,12 +407,12 @@ static int __init crd_load(int in_fd, int out_fd) crd_infd = in_fd; crd_outfd = out_fd; inbuf = kmalloc(INBUFSIZ, GFP_KERNEL); - if (!inbuf) { + if (inbuf == 0) { printk(KERN_ERR "RAMDISK: Couldn't allocate gzip buffer\n"); return -1; } window = kmalloc(WSIZE, GFP_KERNEL); - if (!window) { + if (window == 0) { printk(KERN_ERR "RAMDISK: Couldn't allocate gzip window\n"); kfree(inbuf); return -1; diff --git a/trunk/init/main.c b/trunk/init/main.c index 0dd0e7a1f632..9def935ab13a 100644 --- a/trunk/init/main.c +++ b/trunk/init/main.c @@ -39,7 +39,6 @@ #include #include #include -#include #include #include #include @@ -524,7 +523,6 @@ asmlinkage void __init start_kernel(void) */ unwind_init(); lockdep_init(); - cgroup_init_early(); local_irq_disable(); early_boot_irqs_off(); @@ -642,7 +640,6 @@ asmlinkage void __init start_kernel(void) #ifdef CONFIG_PROC_FS proc_root_init(); #endif - cgroup_init(); cpuset_init(); taskstats_init_early(); delayacct_init(); diff --git a/trunk/ipc/mqueue.c b/trunk/ipc/mqueue.c index c0b26dc4617b..774843cff756 100644 --- a/trunk/ipc/mqueue.c +++ b/trunk/ipc/mqueue.c @@ -29,8 +29,6 @@ #include #include #include -#include -#include #include #include "util.h" @@ -46,6 +44,12 @@ #define STATE_PENDING 1 #define STATE_READY 2 +/* used by sysctl */ +#define FS_MQUEUE 1 +#define CTL_QUEUESMAX 2 +#define CTL_MSGMAX 3 +#define CTL_MSGSIZEMAX 4 + /* default values */ #define DFLT_QUEUESMAX 256 /* max number of message queues */ #define DFLT_MSGMAX 10 /* max number of messages in each queue */ @@ -332,8 +336,7 @@ static ssize_t mqueue_read_file(struct file *filp, char __user *u_data, (info->notify_owner && info->notify.sigev_notify == SIGEV_SIGNAL) ? info->notify.sigev_signo : 0, - pid_nr_ns(info->notify_owner, - current->nsproxy->pid_ns)); + pid_nr(info->notify_owner)); spin_unlock(&info->lock); buffer[sizeof(buffer)-1] = '\0'; slen = strlen(buffer)+1; @@ -510,7 +513,7 @@ static void __do_notify(struct mqueue_inode_info *info) sig_i.si_errno = 0; sig_i.si_code = SI_MESGQ; sig_i.si_value = info->notify.sigev_value; - sig_i.si_pid = task_pid_vnr(current); + sig_i.si_pid = current->tgid; sig_i.si_uid = current->uid; kill_pid_info(info->notify.sigev_signo, @@ -1193,6 +1196,7 @@ static int msg_maxsize_limit_max = INT_MAX; static ctl_table mq_sysctls[] = { { + .ctl_name = CTL_QUEUESMAX, .procname = "queues_max", .data = &queues_max, .maxlen = sizeof(int), @@ -1200,6 +1204,7 @@ static ctl_table mq_sysctls[] = { .proc_handler = &proc_dointvec, }, { + .ctl_name = CTL_MSGMAX, .procname = "msg_max", .data = &msg_max, .maxlen = sizeof(int), @@ -1209,6 +1214,7 @@ static ctl_table mq_sysctls[] = { .extra2 = &msg_max_limit_max, }, { + .ctl_name = CTL_MSGSIZEMAX, .procname = "msgsize_max", .data = &msgsize_max, .maxlen = sizeof(int), @@ -1222,6 +1228,7 @@ static ctl_table mq_sysctls[] = { static ctl_table mq_sysctl_dir[] = { { + .ctl_name = FS_MQUEUE, .procname = "mqueue", .mode = 0555, .child = mq_sysctls, diff --git a/trunk/ipc/msg.c b/trunk/ipc/msg.c index fdf3db5731ce..a03fcb522fff 100644 --- a/trunk/ipc/msg.c +++ b/trunk/ipc/msg.c @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include #include @@ -66,15 +66,23 @@ struct msg_sender { #define SEARCH_NOTEQUAL 3 #define SEARCH_LESSEQUAL 4 +static atomic_t msg_bytes = ATOMIC_INIT(0); +static atomic_t msg_hdrs = ATOMIC_INIT(0); + static struct ipc_ids init_msg_ids; #define msg_ids(ns) (*((ns)->ids[IPC_MSG_IDS])) +#define msg_lock(ns, id) ((struct msg_queue*)ipc_lock(&msg_ids(ns), id)) #define msg_unlock(msq) ipc_unlock(&(msq)->q_perm) -#define msg_buildid(id, seq) ipc_buildid(id, seq) - -static void freeque(struct ipc_namespace *, struct msg_queue *); -static int newque(struct ipc_namespace *, struct ipc_params *); +#define msg_rmid(ns, id) ((struct msg_queue*)ipc_rmid(&msg_ids(ns), id)) +#define msg_checkid(ns, msq, msgid) \ + ipc_checkid(&msg_ids(ns), &msq->q_perm, msgid) +#define msg_buildid(ns, id, seq) \ + ipc_buildid(&msg_ids(ns), id, seq) + +static void freeque (struct ipc_namespace *ns, struct msg_queue *msq, int id); +static int newque (struct ipc_namespace *ns, key_t key, int msgflg); #ifdef CONFIG_PROC_FS static int sysvipc_msg_proc_show(struct seq_file *s, void *it); #endif @@ -85,9 +93,7 @@ static void __msg_init_ns(struct ipc_namespace *ns, struct ipc_ids *ids) ns->msg_ctlmax = MSGMAX; ns->msg_ctlmnb = MSGMNB; ns->msg_ctlmni = MSGMNI; - atomic_set(&ns->msg_bytes, 0); - atomic_set(&ns->msg_hdrs, 0); - ipc_init_ids(ids); + ipc_init_ids(ids, ns->msg_ctlmni); } int msg_init_ns(struct ipc_namespace *ns) @@ -104,25 +110,20 @@ int msg_init_ns(struct ipc_namespace *ns) void msg_exit_ns(struct ipc_namespace *ns) { + int i; struct msg_queue *msq; - int next_id; - int total, in_use; - - down_write(&msg_ids(ns).rw_mutex); - - in_use = msg_ids(ns).in_use; - for (total = 0, next_id = 0; total < in_use; next_id++) { - msq = idr_find(&msg_ids(ns).ipcs_idr, next_id); + mutex_lock(&msg_ids(ns).mutex); + for (i = 0; i <= msg_ids(ns).max_id; i++) { + msq = msg_lock(ns, i); if (msq == NULL) continue; - ipc_lock_by_ptr(&msq->q_perm); - freeque(ns, msq); - total++; - } - up_write(&msg_ids(ns).rw_mutex); + freeque(ns, msq, i); + } + mutex_unlock(&msg_ids(ns).mutex); + ipc_fini_ids(ns->ids[IPC_MSG_IDS]); kfree(ns->ids[IPC_MSG_IDS]); ns->ids[IPC_MSG_IDS] = NULL; } @@ -135,55 +136,10 @@ void __init msg_init(void) IPC_MSG_IDS, sysvipc_msg_proc_show); } -/* - * This routine is called in the paths where the rw_mutex is held to protect - * access to the idr tree. - */ -static inline struct msg_queue *msg_lock_check_down(struct ipc_namespace *ns, - int id) -{ - struct kern_ipc_perm *ipcp = ipc_lock_check_down(&msg_ids(ns), id); - - return container_of(ipcp, struct msg_queue, q_perm); -} - -/* - * msg_lock_(check_) routines are called in the paths where the rw_mutex - * is not held. - */ -static inline struct msg_queue *msg_lock(struct ipc_namespace *ns, int id) -{ - struct kern_ipc_perm *ipcp = ipc_lock(&msg_ids(ns), id); - - return container_of(ipcp, struct msg_queue, q_perm); -} - -static inline struct msg_queue *msg_lock_check(struct ipc_namespace *ns, - int id) -{ - struct kern_ipc_perm *ipcp = ipc_lock_check(&msg_ids(ns), id); - - return container_of(ipcp, struct msg_queue, q_perm); -} - -static inline void msg_rmid(struct ipc_namespace *ns, struct msg_queue *s) -{ - ipc_rmid(&msg_ids(ns), &s->q_perm); -} - -/** - * newque - Create a new msg queue - * @ns: namespace - * @params: ptr to the structure that contains the key and msgflg - * - * Called with msg_ids.rw_mutex held (writer) - */ -static int newque(struct ipc_namespace *ns, struct ipc_params *params) +static int newque (struct ipc_namespace *ns, key_t key, int msgflg) { struct msg_queue *msq; int id, retval; - key_t key = params->key; - int msgflg = params->flg; msq = ipc_rcu_alloc(sizeof(*msq)); if (!msq) @@ -199,17 +155,14 @@ static int newque(struct ipc_namespace *ns, struct ipc_params *params) return retval; } - /* - * ipc_addid() locks msq - */ id = ipc_addid(&msg_ids(ns), &msq->q_perm, ns->msg_ctlmni); - if (id < 0) { + if (id == -1) { security_msg_queue_free(msq); ipc_rcu_putref(msq); - return id; + return -ENOSPC; } - msq->q_perm.id = msg_buildid(id, msq->q_perm.seq); + msq->q_id = msg_buildid(ns, id, msq->q_perm.seq); msq->q_stime = msq->q_rtime = 0; msq->q_ctime = get_seconds(); msq->q_cbytes = msq->q_qnum = 0; @@ -218,10 +171,9 @@ static int newque(struct ipc_namespace *ns, struct ipc_params *params) INIT_LIST_HEAD(&msq->q_messages); INIT_LIST_HEAD(&msq->q_receivers); INIT_LIST_HEAD(&msq->q_senders); - msg_unlock(msq); - return msq->q_perm.id; + return msq->q_id; } static inline void ss_add(struct msg_queue *msq, struct msg_sender *mss) @@ -272,19 +224,19 @@ static void expunge_all(struct msg_queue *msq, int res) /* * freeque() wakes up waiters on the sender and receiver waiting queue, - * removes the message queue from message queue ID IDR, and cleans up all the - * messages associated with this queue. + * removes the message queue from message queue ID + * array, and cleans up all the messages associated with this queue. * - * msg_ids.rw_mutex (writer) and the spinlock for this message queue are held - * before freeque() is called. msg_ids.rw_mutex remains locked on exit. + * msg_ids.mutex and the spinlock for this message queue is hold + * before freeque() is called. msg_ids.mutex remains locked on exit. */ -static void freeque(struct ipc_namespace *ns, struct msg_queue *msq) +static void freeque(struct ipc_namespace *ns, struct msg_queue *msq, int id) { struct list_head *tmp; expunge_all(msq, -EIDRM); ss_wakeup(&msq->q_senders, 1); - msg_rmid(ns, msq); + msq = msg_rmid(ns, id); msg_unlock(msq); tmp = msq->q_messages.next; @@ -292,40 +244,49 @@ static void freeque(struct ipc_namespace *ns, struct msg_queue *msq) struct msg_msg *msg = list_entry(tmp, struct msg_msg, m_list); tmp = tmp->next; - atomic_dec(&ns->msg_hdrs); + atomic_dec(&msg_hdrs); free_msg(msg); } - atomic_sub(msq->q_cbytes, &ns->msg_bytes); + atomic_sub(msq->q_cbytes, &msg_bytes); security_msg_queue_free(msq); ipc_rcu_putref(msq); } -/* - * Called with msg_ids.rw_mutex and ipcp locked. - */ -static inline int msg_security(struct kern_ipc_perm *ipcp, int msgflg) -{ - struct msg_queue *msq = container_of(ipcp, struct msg_queue, q_perm); - - return security_msg_queue_associate(msq, msgflg); -} - asmlinkage long sys_msgget(key_t key, int msgflg) { + struct msg_queue *msq; + int id, ret = -EPERM; struct ipc_namespace *ns; - struct ipc_ops msg_ops; - struct ipc_params msg_params; ns = current->nsproxy->ipc_ns; + + mutex_lock(&msg_ids(ns).mutex); + if (key == IPC_PRIVATE) + ret = newque(ns, key, msgflg); + else if ((id = ipc_findkey(&msg_ids(ns), key)) == -1) { /* key not used */ + if (!(msgflg & IPC_CREAT)) + ret = -ENOENT; + else + ret = newque(ns, key, msgflg); + } else if (msgflg & IPC_CREAT && msgflg & IPC_EXCL) { + ret = -EEXIST; + } else { + msq = msg_lock(ns, id); + BUG_ON(msq == NULL); + if (ipcperms(&msq->q_perm, msgflg)) + ret = -EACCES; + else { + int qid = msg_buildid(ns, id, msq->q_perm.seq); + + ret = security_msg_queue_associate(msq, msgflg); + if (!ret) + ret = qid; + } + msg_unlock(msq); + } + mutex_unlock(&msg_ids(ns).mutex); - msg_ops.getnew = newque; - msg_ops.associate = msg_security; - msg_ops.more_checks = NULL; - - msg_params.key = key; - msg_params.flg = msgflg; - - return ipcget(ns, &msg_ids(ns), &msg_ops, &msg_params); + return ret; } static inline unsigned long @@ -459,23 +420,23 @@ asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf) msginfo.msgmnb = ns->msg_ctlmnb; msginfo.msgssz = MSGSSZ; msginfo.msgseg = MSGSEG; - down_read(&msg_ids(ns).rw_mutex); + mutex_lock(&msg_ids(ns).mutex); if (cmd == MSG_INFO) { msginfo.msgpool = msg_ids(ns).in_use; - msginfo.msgmap = atomic_read(&ns->msg_hdrs); - msginfo.msgtql = atomic_read(&ns->msg_bytes); + msginfo.msgmap = atomic_read(&msg_hdrs); + msginfo.msgtql = atomic_read(&msg_bytes); } else { msginfo.msgmap = MSGMAP; msginfo.msgpool = MSGPOOL; msginfo.msgtql = MSGTQL; } - max_id = ipc_get_maxid(&msg_ids(ns)); - up_read(&msg_ids(ns).rw_mutex); + max_id = msg_ids(ns).max_id; + mutex_unlock(&msg_ids(ns).mutex); if (copy_to_user(buf, &msginfo, sizeof(struct msginfo))) return -EFAULT; return (max_id < 0) ? 0 : max_id; } - case MSG_STAT: /* msqid is an index rather than a msg queue id */ + case MSG_STAT: case IPC_STAT: { struct msqid64_ds tbuf; @@ -483,16 +444,21 @@ asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf) if (!buf) return -EFAULT; + if (cmd == MSG_STAT && msqid >= msg_ids(ns).entries->size) + return -EINVAL; + + memset(&tbuf, 0, sizeof(tbuf)); + + msq = msg_lock(ns, msqid); + if (msq == NULL) + return -EINVAL; if (cmd == MSG_STAT) { - msq = msg_lock(ns, msqid); - if (IS_ERR(msq)) - return PTR_ERR(msq); - success_return = msq->q_perm.id; + success_return = msg_buildid(ns, msqid, msq->q_perm.seq); } else { - msq = msg_lock_check(ns, msqid); - if (IS_ERR(msq)) - return PTR_ERR(msq); + err = -EIDRM; + if (msg_checkid(ns, msq, msqid)) + goto out_unlock; success_return = 0; } err = -EACCES; @@ -503,8 +469,6 @@ asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf) if (err) goto out_unlock; - memset(&tbuf, 0, sizeof(tbuf)); - kernel_to_ipc64_perm(&msq->q_perm, &tbuf.msg_perm); tbuf.msg_stime = msq->q_stime; tbuf.msg_rtime = msq->q_rtime; @@ -531,13 +495,15 @@ asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf) return -EINVAL; } - down_write(&msg_ids(ns).rw_mutex); - msq = msg_lock_check_down(ns, msqid); - if (IS_ERR(msq)) { - err = PTR_ERR(msq); + mutex_lock(&msg_ids(ns).mutex); + msq = msg_lock(ns, msqid); + err = -EINVAL; + if (msq == NULL) goto out_up; - } + err = -EIDRM; + if (msg_checkid(ns, msq, msqid)) + goto out_unlock_up; ipcp = &msq->q_perm; err = audit_ipc_obj(ipcp); @@ -586,12 +552,12 @@ asmlinkage long sys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf) break; } case IPC_RMID: - freeque(ns, msq); + freeque(ns, msq, msqid); break; } err = 0; out_up: - up_write(&msg_ids(ns).rw_mutex); + mutex_unlock(&msg_ids(ns).mutex); return err; out_unlock_up: msg_unlock(msq); @@ -645,7 +611,7 @@ static inline int pipelined_send(struct msg_queue *msq, struct msg_msg *msg) msr->r_msg = ERR_PTR(-E2BIG); } else { msr->r_msg = NULL; - msq->q_lrpid = task_pid_vnr(msr->r_tsk); + msq->q_lrpid = msr->r_tsk->pid; msq->q_rtime = get_seconds(); wake_up_process(msr->r_tsk); smp_mb(); @@ -680,11 +646,14 @@ long do_msgsnd(int msqid, long mtype, void __user *mtext, msg->m_type = mtype; msg->m_ts = msgsz; - msq = msg_lock_check(ns, msqid); - if (IS_ERR(msq)) { - err = PTR_ERR(msq); + msq = msg_lock(ns, msqid); + err = -EINVAL; + if (msq == NULL) goto out_free; - } + + err= -EIDRM; + if (msg_checkid(ns, msq, msqid)) + goto out_unlock_free; for (;;) { struct msg_sender s; @@ -726,7 +695,7 @@ long do_msgsnd(int msqid, long mtype, void __user *mtext, } } - msq->q_lspid = task_tgid_vnr(current); + msq->q_lspid = current->tgid; msq->q_stime = get_seconds(); if (!pipelined_send(msq, msg)) { @@ -734,8 +703,8 @@ long do_msgsnd(int msqid, long mtype, void __user *mtext, list_add_tail(&msg->m_list, &msq->q_messages); msq->q_cbytes += msgsz; msq->q_qnum++; - atomic_add(msgsz, &ns->msg_bytes); - atomic_inc(&ns->msg_hdrs); + atomic_add(msgsz, &msg_bytes); + atomic_inc(&msg_hdrs); } err = 0; @@ -791,9 +760,13 @@ long do_msgrcv(int msqid, long *pmtype, void __user *mtext, mode = convert_mode(&msgtyp, msgflg); ns = current->nsproxy->ipc_ns; - msq = msg_lock_check(ns, msqid); - if (IS_ERR(msq)) - return PTR_ERR(msq); + msq = msg_lock(ns, msqid); + if (msq == NULL) + return -EINVAL; + + msg = ERR_PTR(-EIDRM); + if (msg_checkid(ns, msq, msqid)) + goto out_unlock; for (;;) { struct msg_receiver msr_d; @@ -837,10 +810,10 @@ long do_msgrcv(int msqid, long *pmtype, void __user *mtext, list_del(&msg->m_list); msq->q_qnum--; msq->q_rtime = get_seconds(); - msq->q_lrpid = task_tgid_vnr(current); + msq->q_lrpid = current->tgid; msq->q_cbytes -= msg->m_ts; - atomic_sub(msg->m_ts, &ns->msg_bytes); - atomic_dec(&ns->msg_hdrs); + atomic_sub(msg->m_ts, &msg_bytes); + atomic_dec(&msg_hdrs); ss_wakeup(&msq->q_senders, 0); msg_unlock(msq); break; @@ -953,7 +926,7 @@ static int sysvipc_msg_proc_show(struct seq_file *s, void *it) return seq_printf(s, "%10d %10d %4o %10lu %10lu %5u %5u %5u %5u %5u %5u %10lu %10lu %10lu\n", msq->q_perm.key, - msq->q_perm.id, + msq->q_id, msq->q_perm.mode, msq->q_cbytes, msq->q_qnum, diff --git a/trunk/ipc/sem.c b/trunk/ipc/sem.c index 35952c0bae46..b676fef6d208 100644 --- a/trunk/ipc/sem.c +++ b/trunk/ipc/sem.c @@ -80,7 +80,7 @@ #include #include #include -#include +#include #include #include @@ -88,14 +88,18 @@ #define sem_ids(ns) (*((ns)->ids[IPC_SEM_IDS])) +#define sem_lock(ns, id) ((struct sem_array*)ipc_lock(&sem_ids(ns), id)) #define sem_unlock(sma) ipc_unlock(&(sma)->sem_perm) -#define sem_checkid(sma, semid) ipc_checkid(&sma->sem_perm, semid) -#define sem_buildid(id, seq) ipc_buildid(id, seq) +#define sem_rmid(ns, id) ((struct sem_array*)ipc_rmid(&sem_ids(ns), id)) +#define sem_checkid(ns, sma, semid) \ + ipc_checkid(&sem_ids(ns),&sma->sem_perm,semid) +#define sem_buildid(ns, id, seq) \ + ipc_buildid(&sem_ids(ns), id, seq) static struct ipc_ids init_sem_ids; -static int newary(struct ipc_namespace *, struct ipc_params *); -static void freeary(struct ipc_namespace *, struct sem_array *); +static int newary(struct ipc_namespace *, key_t, int, int); +static void freeary(struct ipc_namespace *ns, struct sem_array *sma, int id); #ifdef CONFIG_PROC_FS static int sysvipc_sem_proc_show(struct seq_file *s, void *it); #endif @@ -125,7 +129,7 @@ static void __sem_init_ns(struct ipc_namespace *ns, struct ipc_ids *ids) ns->sc_semopm = SEMOPM; ns->sc_semmni = SEMMNI; ns->used_sems = 0; - ipc_init_ids(ids); + ipc_init_ids(ids, ns->sc_semmni); } int sem_init_ns(struct ipc_namespace *ns) @@ -142,24 +146,20 @@ int sem_init_ns(struct ipc_namespace *ns) void sem_exit_ns(struct ipc_namespace *ns) { + int i; struct sem_array *sma; - int next_id; - int total, in_use; - down_write(&sem_ids(ns).rw_mutex); - - in_use = sem_ids(ns).in_use; - - for (total = 0, next_id = 0; total < in_use; next_id++) { - sma = idr_find(&sem_ids(ns).ipcs_idr, next_id); + mutex_lock(&sem_ids(ns).mutex); + for (i = 0; i <= sem_ids(ns).max_id; i++) { + sma = sem_lock(ns, i); if (sma == NULL) continue; - ipc_lock_by_ptr(&sma->sem_perm); - freeary(ns, sma); - total++; + + freeary(ns, sma, i); } - up_write(&sem_ids(ns).rw_mutex); + mutex_unlock(&sem_ids(ns).mutex); + ipc_fini_ids(ns->ids[IPC_SEM_IDS]); kfree(ns->ids[IPC_SEM_IDS]); ns->ids[IPC_SEM_IDS] = NULL; } @@ -172,42 +172,6 @@ void __init sem_init (void) IPC_SEM_IDS, sysvipc_sem_proc_show); } -/* - * This routine is called in the paths where the rw_mutex is held to protect - * access to the idr tree. - */ -static inline struct sem_array *sem_lock_check_down(struct ipc_namespace *ns, - int id) -{ - struct kern_ipc_perm *ipcp = ipc_lock_check_down(&sem_ids(ns), id); - - return container_of(ipcp, struct sem_array, sem_perm); -} - -/* - * sem_lock_(check_) routines are called in the paths where the rw_mutex - * is not held. - */ -static inline struct sem_array *sem_lock(struct ipc_namespace *ns, int id) -{ - struct kern_ipc_perm *ipcp = ipc_lock(&sem_ids(ns), id); - - return container_of(ipcp, struct sem_array, sem_perm); -} - -static inline struct sem_array *sem_lock_check(struct ipc_namespace *ns, - int id) -{ - struct kern_ipc_perm *ipcp = ipc_lock_check(&sem_ids(ns), id); - - return container_of(ipcp, struct sem_array, sem_perm); -} - -static inline void sem_rmid(struct ipc_namespace *ns, struct sem_array *s) -{ - ipc_rmid(&sem_ids(ns), &s->sem_perm); -} - /* * Lockless wakeup algorithm: * Without the check/retry algorithm a lockless wakeup is possible: @@ -242,23 +206,12 @@ static inline void sem_rmid(struct ipc_namespace *ns, struct sem_array *s) */ #define IN_WAKEUP 1 -/** - * newary - Create a new semaphore set - * @ns: namespace - * @params: ptr to the structure that contains key, semflg and nsems - * - * Called with sem_ids.rw_mutex held (as a writer) - */ - -static int newary(struct ipc_namespace *ns, struct ipc_params *params) +static int newary (struct ipc_namespace *ns, key_t key, int nsems, int semflg) { int id; int retval; struct sem_array *sma; int size; - key_t key = params->key; - int nsems = params->u.nsems; - int semflg = params->flg; if (!nsems) return -EINVAL; @@ -283,14 +236,14 @@ static int newary(struct ipc_namespace *ns, struct ipc_params *params) } id = ipc_addid(&sem_ids(ns), &sma->sem_perm, ns->sc_semmni); - if (id < 0) { + if(id == -1) { security_sem_free(sma); ipc_rcu_putref(sma); - return id; + return -ENOSPC; } ns->used_sems += nsems; - sma->sem_perm.id = sem_buildid(id, sma->sem_perm.seq); + sma->sem_id = sem_buildid(ns, id, sma->sem_perm.seq); sma->sem_base = (struct sem *) &sma[1]; /* sma->sem_pending = NULL; */ sma->sem_pending_last = &sma->sem_pending; @@ -299,56 +252,48 @@ static int newary(struct ipc_namespace *ns, struct ipc_params *params) sma->sem_ctime = get_seconds(); sem_unlock(sma); - return sma->sem_perm.id; -} - - -/* - * Called with sem_ids.rw_mutex and ipcp locked. - */ -static inline int sem_security(struct kern_ipc_perm *ipcp, int semflg) -{ - struct sem_array *sma; - - sma = container_of(ipcp, struct sem_array, sem_perm); - return security_sem_associate(sma, semflg); + return sma->sem_id; } -/* - * Called with sem_ids.rw_mutex and ipcp locked. - */ -static inline int sem_more_checks(struct kern_ipc_perm *ipcp, - struct ipc_params *params) +asmlinkage long sys_semget (key_t key, int nsems, int semflg) { + int id, err = -EINVAL; struct sem_array *sma; - - sma = container_of(ipcp, struct sem_array, sem_perm); - if (params->u.nsems > sma->sem_nsems) - return -EINVAL; - - return 0; -} - -asmlinkage long sys_semget(key_t key, int nsems, int semflg) -{ struct ipc_namespace *ns; - struct ipc_ops sem_ops; - struct ipc_params sem_params; ns = current->nsproxy->ipc_ns; if (nsems < 0 || nsems > ns->sc_semmsl) return -EINVAL; + mutex_lock(&sem_ids(ns).mutex); + + if (key == IPC_PRIVATE) { + err = newary(ns, key, nsems, semflg); + } else if ((id = ipc_findkey(&sem_ids(ns), key)) == -1) { /* key not used */ + if (!(semflg & IPC_CREAT)) + err = -ENOENT; + else + err = newary(ns, key, nsems, semflg); + } else if (semflg & IPC_CREAT && semflg & IPC_EXCL) { + err = -EEXIST; + } else { + sma = sem_lock(ns, id); + BUG_ON(sma==NULL); + if (nsems > sma->sem_nsems) + err = -EINVAL; + else if (ipcperms(&sma->sem_perm, semflg)) + err = -EACCES; + else { + int semid = sem_buildid(ns, id, sma->sem_perm.seq); + err = security_sem_associate(sma, semflg); + if (!err) + err = semid; + } + sem_unlock(sma); + } - sem_ops.getnew = newary; - sem_ops.associate = sem_security; - sem_ops.more_checks = sem_more_checks; - - sem_params.key = key; - sem_params.flg = semflg; - sem_params.u.nsems = nsems; - - return ipcget(ns, &sem_ids(ns), &sem_ops, &sem_params); + mutex_unlock(&sem_ids(ns).mutex); + return err; } /* Manage the doubly linked list sma->sem_pending as a FIFO: @@ -542,14 +487,15 @@ static int count_semzcnt (struct sem_array * sma, ushort semnum) return semzcnt; } -/* Free a semaphore set. freeary() is called with sem_ids.rw_mutex locked - * as a writer and the spinlock for this semaphore set hold. sem_ids.rw_mutex - * remains locked on exit. +/* Free a semaphore set. freeary() is called with sem_ids.mutex locked and + * the spinlock for this semaphore set hold. sem_ids.mutex remains locked + * on exit. */ -static void freeary(struct ipc_namespace *ns, struct sem_array *sma) +static void freeary (struct ipc_namespace *ns, struct sem_array *sma, int id) { struct sem_undo *un; struct sem_queue *q; + int size; /* Invalidate the existing undo structures for this semaphore set. * (They will be freed without any further action in exit_sem() @@ -572,11 +518,12 @@ static void freeary(struct ipc_namespace *ns, struct sem_array *sma) q = n; } - /* Remove the semaphore set from the IDR */ - sem_rmid(ns, sma); + /* Remove the semaphore set from the ID array*/ + sma = sem_rmid(ns, id); sem_unlock(sma); ns->used_sems -= sma->sem_nsems; + size = sizeof (*sma) + sma->sem_nsems * sizeof (struct sem); security_sem_free(sma); ipc_rcu_putref(sma); } @@ -629,7 +576,7 @@ static int semctl_nolock(struct ipc_namespace *ns, int semid, int semnum, seminfo.semmnu = SEMMNU; seminfo.semmap = SEMMAP; seminfo.semume = SEMUME; - down_read(&sem_ids(ns).rw_mutex); + mutex_lock(&sem_ids(ns).mutex); if (cmd == SEM_INFO) { seminfo.semusz = sem_ids(ns).in_use; seminfo.semaem = ns->used_sems; @@ -637,8 +584,8 @@ static int semctl_nolock(struct ipc_namespace *ns, int semid, int semnum, seminfo.semusz = SEMUSZ; seminfo.semaem = SEMAEM; } - max_id = ipc_get_maxid(&sem_ids(ns)); - up_read(&sem_ids(ns).rw_mutex); + max_id = sem_ids(ns).max_id; + mutex_unlock(&sem_ids(ns).mutex); if (copy_to_user (arg.__buf, &seminfo, sizeof(struct seminfo))) return -EFAULT; return (max_id < 0) ? 0: max_id; @@ -648,9 +595,14 @@ static int semctl_nolock(struct ipc_namespace *ns, int semid, int semnum, struct semid64_ds tbuf; int id; + if(semid >= sem_ids(ns).entries->size) + return -EINVAL; + + memset(&tbuf,0,sizeof(tbuf)); + sma = sem_lock(ns, semid); - if (IS_ERR(sma)) - return PTR_ERR(sma); + if(sma == NULL) + return -EINVAL; err = -EACCES; if (ipcperms (&sma->sem_perm, S_IRUGO)) @@ -660,9 +612,7 @@ static int semctl_nolock(struct ipc_namespace *ns, int semid, int semnum, if (err) goto out_unlock; - id = sma->sem_perm.id; - - memset(&tbuf, 0, sizeof(tbuf)); + id = sem_buildid(ns, semid, sma->sem_perm.seq); kernel_to_ipc64_perm(&sma->sem_perm, &tbuf.sem_perm); tbuf.sem_otime = sma->sem_otime; @@ -692,12 +642,16 @@ static int semctl_main(struct ipc_namespace *ns, int semid, int semnum, ushort* sem_io = fast_sem_io; int nsems; - sma = sem_lock_check(ns, semid); - if (IS_ERR(sma)) - return PTR_ERR(sma); + sma = sem_lock(ns, semid); + if(sma==NULL) + return -EINVAL; nsems = sma->sem_nsems; + err=-EIDRM; + if (sem_checkid(ns,sma,semid)) + goto out_unlock; + err = -EACCES; if (ipcperms (&sma->sem_perm, (cmd==SETVAL||cmd==SETALL)?S_IWUGO:S_IRUGO)) goto out_unlock; @@ -841,7 +795,7 @@ static int semctl_main(struct ipc_namespace *ns, int semid, int semnum, for (un = sma->undo; un; un = un->id_next) un->semadj[semnum] = 0; curr->semval = val; - curr->sempid = task_tgid_vnr(current); + curr->sempid = current->tgid; sma->sem_ctime = get_seconds(); /* maybe some queued-up processes were waiting for this */ update_queue(sma); @@ -909,10 +863,14 @@ static int semctl_down(struct ipc_namespace *ns, int semid, int semnum, if(copy_semid_from_user (&setbuf, arg.buf, version)) return -EFAULT; } - sma = sem_lock_check_down(ns, semid); - if (IS_ERR(sma)) - return PTR_ERR(sma); + sma = sem_lock(ns, semid); + if(sma==NULL) + return -EINVAL; + if (sem_checkid(ns,sma,semid)) { + err=-EIDRM; + goto out_unlock; + } ipcp = &sma->sem_perm; err = audit_ipc_obj(ipcp); @@ -936,7 +894,7 @@ static int semctl_down(struct ipc_namespace *ns, int semid, int semnum, switch(cmd){ case IPC_RMID: - freeary(ns, sma); + freeary(ns, sma, semid); err = 0; break; case IPC_SET: @@ -990,15 +948,45 @@ asmlinkage long sys_semctl (int semid, int semnum, int cmd, union semun arg) return err; case IPC_RMID: case IPC_SET: - down_write(&sem_ids(ns).rw_mutex); + mutex_lock(&sem_ids(ns).mutex); err = semctl_down(ns,semid,semnum,cmd,version,arg); - up_write(&sem_ids(ns).rw_mutex); + mutex_unlock(&sem_ids(ns).mutex); return err; default: return -EINVAL; } } +static inline void lock_semundo(void) +{ + struct sem_undo_list *undo_list; + + undo_list = current->sysvsem.undo_list; + if (undo_list) + spin_lock(&undo_list->lock); +} + +/* This code has an interaction with copy_semundo(). + * Consider; two tasks are sharing the undo_list. task1 + * acquires the undo_list lock in lock_semundo(). If task2 now + * exits before task1 releases the lock (by calling + * unlock_semundo()), then task1 will never call spin_unlock(). + * This leave the sem_undo_list in a locked state. If task1 now creats task3 + * and once again shares the sem_undo_list, the sem_undo_list will still be + * locked, and future SEM_UNDO operations will deadlock. This case is + * dealt with in copy_semundo() by having it reinitialize the spin lock when + * the refcnt goes from 1 to 2. + */ +static inline void unlock_semundo(void) +{ + struct sem_undo_list *undo_list; + + undo_list = current->sysvsem.undo_list; + if (undo_list) + spin_unlock(&undo_list->lock); +} + + /* If the task doesn't already have a undo_list, then allocate one * here. We guarantee there is only one thread using this undo list, * and current is THE ONE @@ -1059,17 +1047,22 @@ static struct sem_undo *find_undo(struct ipc_namespace *ns, int semid) if (error) return ERR_PTR(error); - spin_lock(&ulp->lock); + lock_semundo(); un = lookup_undo(ulp, semid); - spin_unlock(&ulp->lock); + unlock_semundo(); if (likely(un!=NULL)) goto out; /* no undo structure around - allocate one. */ - sma = sem_lock_check(ns, semid); - if (IS_ERR(sma)) - return ERR_PTR(PTR_ERR(sma)); - + sma = sem_lock(ns, semid); + un = ERR_PTR(-EINVAL); + if(sma==NULL) + goto out; + un = ERR_PTR(-EIDRM); + if (sem_checkid(ns,sma,semid)) { + sem_unlock(sma); + goto out; + } nsems = sma->sem_nsems; ipc_rcu_getref(sma); sem_unlock(sma); @@ -1084,10 +1077,10 @@ static struct sem_undo *find_undo(struct ipc_namespace *ns, int semid) new->semadj = (short *) &new[1]; new->semid = semid; - spin_lock(&ulp->lock); + lock_semundo(); un = lookup_undo(ulp, semid); if (un) { - spin_unlock(&ulp->lock); + unlock_semundo(); kfree(new); ipc_lock_by_ptr(&sma->sem_perm); ipc_rcu_putref(sma); @@ -1098,7 +1091,7 @@ static struct sem_undo *find_undo(struct ipc_namespace *ns, int semid) ipc_rcu_putref(sma); if (sma->sem_perm.deleted) { sem_unlock(sma); - spin_unlock(&ulp->lock); + unlock_semundo(); kfree(new); un = ERR_PTR(-EIDRM); goto out; @@ -1109,7 +1102,7 @@ static struct sem_undo *find_undo(struct ipc_namespace *ns, int semid) sma->undo = new; sem_unlock(sma); un = new; - spin_unlock(&ulp->lock); + unlock_semundo(); out: return un; } @@ -1175,14 +1168,15 @@ asmlinkage long sys_semtimedop(int semid, struct sembuf __user *tsops, } else un = NULL; - sma = sem_lock_check(ns, semid); - if (IS_ERR(sma)) { - error = PTR_ERR(sma); + sma = sem_lock(ns, semid); + error=-EINVAL; + if(sma==NULL) goto out_free; - } - + error = -EIDRM; + if (sem_checkid(ns,sma,semid)) + goto out_unlock_free; /* - * semid identifiers are not unique - find_undo may have + * semid identifies are not unique - find_undo may have * allocated an undo structure, it was invalidated by an RMID * and now a new array with received the same id. Check and retry. */ @@ -1202,7 +1196,7 @@ asmlinkage long sys_semtimedop(int semid, struct sembuf __user *tsops, if (error) goto out_unlock_free; - error = try_atomic_semop (sma, sops, nsops, un, task_tgid_vnr(current)); + error = try_atomic_semop (sma, sops, nsops, un, current->tgid); if (error <= 0) { if (alter && error == 0) update_queue (sma); @@ -1217,7 +1211,7 @@ asmlinkage long sys_semtimedop(int semid, struct sembuf __user *tsops, queue.sops = sops; queue.nsops = nsops; queue.undo = un; - queue.pid = task_tgid_vnr(current); + queue.pid = current->tgid; queue.id = semid; queue.alter = alter; if (alter) @@ -1248,7 +1242,7 @@ asmlinkage long sys_semtimedop(int semid, struct sembuf __user *tsops, } sma = sem_lock(ns, semid); - if (IS_ERR(sma)) { + if(sma==NULL) { BUG_ON(queue.prev != NULL); error = -EIDRM; goto out_free; @@ -1285,6 +1279,10 @@ asmlinkage long sys_semop (int semid, struct sembuf __user *tsops, unsigned nsop /* If CLONE_SYSVSEM is set, establish sharing of SEM_UNDO state between * parent and child tasks. + * + * See the notes above unlock_semundo() regarding the spin_lock_init() + * in this code. Initialize the undo_list->lock here instead of get_undo_list() + * because of the reasoning in the comment above unlock_semundo. */ int copy_semundo(unsigned long clone_flags, struct task_struct *tsk) @@ -1344,13 +1342,13 @@ void exit_sem(struct task_struct *tsk) if(semid == -1) continue; sma = sem_lock(ns, semid); - if (IS_ERR(sma)) + if (sma == NULL) continue; if (u->semid == -1) goto next_entry; - BUG_ON(sem_checkid(sma, u->semid)); + BUG_ON(sem_checkid(ns,sma,u->semid)); /* remove u from the sma->undo list */ for (unp = &sma->undo; (un = *unp); unp = &un->id_next) { @@ -1384,7 +1382,7 @@ void exit_sem(struct task_struct *tsk) semaphore->semval = 0; if (semaphore->semval > SEMVMX) semaphore->semval = SEMVMX; - semaphore->sempid = task_tgid_vnr(current); + semaphore->sempid = current->tgid; } } sma->sem_otime = get_seconds(); @@ -1404,7 +1402,7 @@ static int sysvipc_sem_proc_show(struct seq_file *s, void *it) return seq_printf(s, "%10d %10d %4o %10lu %5u %5u %5u %5u %10lu %10lu\n", sma->sem_perm.key, - sma->sem_perm.id, + sma->sem_id, sma->sem_perm.mode, sma->sem_nsems, sma->sem_perm.uid, diff --git a/trunk/ipc/shm.c b/trunk/ipc/shm.c index 3818fae625c5..5fc5cf50cf1b 100644 --- a/trunk/ipc/shm.c +++ b/trunk/ipc/shm.c @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include #include @@ -59,11 +59,17 @@ static struct ipc_ids init_shm_ids; #define shm_ids(ns) (*((ns)->ids[IPC_SHM_IDS])) +#define shm_lock(ns, id) \ + ((struct shmid_kernel*)ipc_lock(&shm_ids(ns),id)) #define shm_unlock(shp) \ ipc_unlock(&(shp)->shm_perm) -#define shm_buildid(id, seq) ipc_buildid(id, seq) +#define shm_get(ns, id) \ + ((struct shmid_kernel*)ipc_get(&shm_ids(ns),id)) +#define shm_buildid(ns, id, seq) \ + ipc_buildid(&shm_ids(ns), id, seq) -static int newseg(struct ipc_namespace *, struct ipc_params *); +static int newseg (struct ipc_namespace *ns, key_t key, + int shmflg, size_t size); static void shm_open(struct vm_area_struct *vma); static void shm_close(struct vm_area_struct *vma); static void shm_destroy (struct ipc_namespace *ns, struct shmid_kernel *shp); @@ -78,13 +84,9 @@ static void __shm_init_ns(struct ipc_namespace *ns, struct ipc_ids *ids) ns->shm_ctlall = SHMALL; ns->shm_ctlmni = SHMMNI; ns->shm_tot = 0; - ipc_init_ids(ids); + ipc_init_ids(ids, 1); } -/* - * Called with shm_ids.rw_mutex (writer) and the shp structure locked. - * Only shm_ids.rw_mutex remains locked on exit. - */ static void do_shm_rmid(struct ipc_namespace *ns, struct shmid_kernel *shp) { if (shp->shm_nattch){ @@ -110,24 +112,20 @@ int shm_init_ns(struct ipc_namespace *ns) void shm_exit_ns(struct ipc_namespace *ns) { + int i; struct shmid_kernel *shp; - int next_id; - int total, in_use; - - down_write(&shm_ids(ns).rw_mutex); - in_use = shm_ids(ns).in_use; - - for (total = 0, next_id = 0; total < in_use; next_id++) { - shp = idr_find(&shm_ids(ns).ipcs_idr, next_id); + mutex_lock(&shm_ids(ns).mutex); + for (i = 0; i <= shm_ids(ns).max_id; i++) { + shp = shm_lock(ns, i); if (shp == NULL) continue; - ipc_lock_by_ptr(&shp->shm_perm); + do_shm_rmid(ns, shp); - total++; } - up_write(&shm_ids(ns).rw_mutex); + mutex_unlock(&shm_ids(ns).mutex); + ipc_fini_ids(ns->ids[IPC_SHM_IDS]); kfree(ns->ids[IPC_SHM_IDS]); ns->ids[IPC_SHM_IDS] = NULL; } @@ -140,49 +138,17 @@ void __init shm_init (void) IPC_SHM_IDS, sysvipc_shm_proc_show); } -/* - * shm_lock_(check_)down routines are called in the paths where the rw_mutex - * is held to protect access to the idr tree. - */ -static inline struct shmid_kernel *shm_lock_down(struct ipc_namespace *ns, - int id) -{ - struct kern_ipc_perm *ipcp = ipc_lock_down(&shm_ids(ns), id); - - return container_of(ipcp, struct shmid_kernel, shm_perm); -} - -static inline struct shmid_kernel *shm_lock_check_down( - struct ipc_namespace *ns, - int id) -{ - struct kern_ipc_perm *ipcp = ipc_lock_check_down(&shm_ids(ns), id); - - return container_of(ipcp, struct shmid_kernel, shm_perm); -} - -/* - * shm_lock_(check_) routines are called in the paths where the rw_mutex - * is not held. - */ -static inline struct shmid_kernel *shm_lock(struct ipc_namespace *ns, int id) -{ - struct kern_ipc_perm *ipcp = ipc_lock(&shm_ids(ns), id); - - return container_of(ipcp, struct shmid_kernel, shm_perm); -} - -static inline struct shmid_kernel *shm_lock_check(struct ipc_namespace *ns, - int id) +static inline int shm_checkid(struct ipc_namespace *ns, + struct shmid_kernel *s, int id) { - struct kern_ipc_perm *ipcp = ipc_lock_check(&shm_ids(ns), id); - - return container_of(ipcp, struct shmid_kernel, shm_perm); + if (ipc_checkid(&shm_ids(ns), &s->shm_perm, id)) + return -EIDRM; + return 0; } -static inline void shm_rmid(struct ipc_namespace *ns, struct shmid_kernel *s) +static inline struct shmid_kernel *shm_rmid(struct ipc_namespace *ns, int id) { - ipc_rmid(&shm_ids(ns), &s->shm_perm); + return (struct shmid_kernel *)ipc_rmid(&shm_ids(ns), id); } static inline int shm_addid(struct ipc_namespace *ns, struct shmid_kernel *shp) @@ -200,9 +166,9 @@ static void shm_open(struct vm_area_struct *vma) struct shmid_kernel *shp; shp = shm_lock(sfd->ns, sfd->id); - BUG_ON(IS_ERR(shp)); + BUG_ON(!shp); shp->shm_atim = get_seconds(); - shp->shm_lprid = task_tgid_vnr(current); + shp->shm_lprid = current->tgid; shp->shm_nattch++; shm_unlock(shp); } @@ -210,16 +176,15 @@ static void shm_open(struct vm_area_struct *vma) /* * shm_destroy - free the struct shmid_kernel * - * @ns: namespace * @shp: struct to free * - * It has to be called with shp and shm_ids.rw_mutex (writer) locked, + * It has to be called with shp and shm_ids.mutex locked, * but returns with shp unlocked and freed. */ static void shm_destroy(struct ipc_namespace *ns, struct shmid_kernel *shp) { ns->shm_tot -= (shp->shm_segsz + PAGE_SIZE - 1) >> PAGE_SHIFT; - shm_rmid(ns, shp); + shm_rmid(ns, shp->id); shm_unlock(shp); if (!is_file_hugepages(shp->shm_file)) shmem_lock(shp->shm_file, 0, shp->mlock_user); @@ -244,11 +209,11 @@ static void shm_close(struct vm_area_struct *vma) struct shmid_kernel *shp; struct ipc_namespace *ns = sfd->ns; - down_write(&shm_ids(ns).rw_mutex); + mutex_lock(&shm_ids(ns).mutex); /* remove from the list of attaches of the shm segment */ - shp = shm_lock_down(ns, sfd->id); - BUG_ON(IS_ERR(shp)); - shp->shm_lprid = task_tgid_vnr(current); + shp = shm_lock(ns, sfd->id); + BUG_ON(!shp); + shp->shm_lprid = current->tgid; shp->shm_dtim = get_seconds(); shp->shm_nattch--; if(shp->shm_nattch == 0 && @@ -256,7 +221,7 @@ static void shm_close(struct vm_area_struct *vma) shm_destroy(ns, shp); else shm_unlock(shp); - up_write(&shm_ids(ns).rw_mutex); + mutex_unlock(&shm_ids(ns).mutex); } static int shm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) @@ -372,19 +337,8 @@ static struct vm_operations_struct shm_vm_ops = { #endif }; -/** - * newseg - Create a new shared memory segment - * @ns: namespace - * @params: ptr to the structure that contains key, size and shmflg - * - * Called with shm_ids.rw_mutex held as a writer. - */ - -static int newseg(struct ipc_namespace *ns, struct ipc_params *params) +static int newseg (struct ipc_namespace *ns, key_t key, int shmflg, size_t size) { - key_t key = params->key; - int shmflg = params->flg; - size_t size = params->u.size; int error; struct shmid_kernel *shp; int numpages = (size + PAGE_SIZE -1) >> PAGE_SHIFT; @@ -433,30 +387,28 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params) if (IS_ERR(file)) goto no_file; + error = -ENOSPC; id = shm_addid(ns, shp); - if (id < 0) { - error = id; + if(id == -1) goto no_id; - } - shp->shm_cprid = task_tgid_vnr(current); + shp->shm_cprid = current->tgid; shp->shm_lprid = 0; shp->shm_atim = shp->shm_dtim = 0; shp->shm_ctim = get_seconds(); shp->shm_segsz = size; shp->shm_nattch = 0; - shp->shm_perm.id = shm_buildid(id, shp->shm_perm.seq); + shp->id = shm_buildid(ns, id, shp->shm_perm.seq); shp->shm_file = file; /* * shmid gets reported as "inode#" in /proc/pid/maps. * proc-ps tools use this. Changing this will break them. */ - file->f_dentry->d_inode->i_ino = shp->shm_perm.id; + file->f_dentry->d_inode->i_ino = shp->id; ns->shm_tot += numpages; - error = shp->shm_perm.id; shm_unlock(shp); - return error; + return shp->id; no_id: fput(file); @@ -466,49 +418,42 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params) return error; } -/* - * Called with shm_ids.rw_mutex and ipcp locked. - */ -static inline int shm_security(struct kern_ipc_perm *ipcp, int shmflg) -{ - struct shmid_kernel *shp; - - shp = container_of(ipcp, struct shmid_kernel, shm_perm); - return security_shm_associate(shp, shmflg); -} - -/* - * Called with shm_ids.rw_mutex and ipcp locked. - */ -static inline int shm_more_checks(struct kern_ipc_perm *ipcp, - struct ipc_params *params) -{ - struct shmid_kernel *shp; - - shp = container_of(ipcp, struct shmid_kernel, shm_perm); - if (shp->shm_segsz < params->u.size) - return -EINVAL; - - return 0; -} - asmlinkage long sys_shmget (key_t key, size_t size, int shmflg) { + struct shmid_kernel *shp; + int err, id = 0; struct ipc_namespace *ns; - struct ipc_ops shm_ops; - struct ipc_params shm_params; ns = current->nsproxy->ipc_ns; - shm_ops.getnew = newseg; - shm_ops.associate = shm_security; - shm_ops.more_checks = shm_more_checks; - - shm_params.key = key; - shm_params.flg = shmflg; - shm_params.u.size = size; + mutex_lock(&shm_ids(ns).mutex); + if (key == IPC_PRIVATE) { + err = newseg(ns, key, shmflg, size); + } else if ((id = ipc_findkey(&shm_ids(ns), key)) == -1) { + if (!(shmflg & IPC_CREAT)) + err = -ENOENT; + else + err = newseg(ns, key, shmflg, size); + } else if ((shmflg & IPC_CREAT) && (shmflg & IPC_EXCL)) { + err = -EEXIST; + } else { + shp = shm_lock(ns, id); + BUG_ON(shp==NULL); + if (shp->shm_segsz < size) + err = -EINVAL; + else if (ipcperms(&shp->shm_perm, shmflg)) + err = -EACCES; + else { + int shmid = shm_buildid(ns, id, shp->shm_perm.seq); + err = security_shm_associate(shp, shmflg); + if (!err) + err = shmid; + } + shm_unlock(shp); + } + mutex_unlock(&shm_ids(ns).mutex); - return ipcget(ns, &shm_ids(ns), &shm_ops, &shm_params); + return err; } static inline unsigned long copy_shmid_to_user(void __user *buf, struct shmid64_ds *in, int version) @@ -602,26 +547,20 @@ static inline unsigned long copy_shminfo_to_user(void __user *buf, struct shminf } } -/* - * Called with shm_ids.rw_mutex held as a reader - */ static void shm_get_stat(struct ipc_namespace *ns, unsigned long *rss, unsigned long *swp) { - int next_id; - int total, in_use; + int i; *rss = 0; *swp = 0; - in_use = shm_ids(ns).in_use; - - for (total = 0, next_id = 0; total < in_use; next_id++) { + for (i = 0; i <= shm_ids(ns).max_id; i++) { struct shmid_kernel *shp; struct inode *inode; - shp = idr_find(&shm_ids(ns).ipcs_idr, next_id); - if (shp == NULL) + shp = shm_get(ns, i); + if(!shp) continue; inode = shp->shm_file->f_path.dentry->d_inode; @@ -636,8 +575,6 @@ static void shm_get_stat(struct ipc_namespace *ns, unsigned long *rss, *swp += info->swapped; spin_unlock(&info->lock); } - - total++; } } @@ -673,11 +610,8 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf) shminfo.shmmin = SHMMIN; if(copy_shminfo_to_user (buf, &shminfo, version)) return -EFAULT; - - down_read(&shm_ids(ns).rw_mutex); - err = ipc_get_maxid(&shm_ids(ns)); - up_read(&shm_ids(ns).rw_mutex); - + /* reading a integer is always atomic */ + err= shm_ids(ns).max_id; if(err<0) err = 0; goto out; @@ -691,14 +625,14 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf) return err; memset(&shm_info,0,sizeof(shm_info)); - down_read(&shm_ids(ns).rw_mutex); + mutex_lock(&shm_ids(ns).mutex); shm_info.used_ids = shm_ids(ns).in_use; shm_get_stat (ns, &shm_info.shm_rss, &shm_info.shm_swp); shm_info.shm_tot = ns->shm_tot; shm_info.swap_attempts = 0; shm_info.swap_successes = 0; - err = ipc_get_maxid(&shm_ids(ns)); - up_read(&shm_ids(ns).rw_mutex); + err = shm_ids(ns).max_id; + mutex_unlock(&shm_ids(ns).mutex); if(copy_to_user (buf, &shm_info, sizeof(shm_info))) { err = -EFAULT; goto out; @@ -712,25 +646,20 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf) { struct shmid64_ds tbuf; int result; - - if (!buf) { - err = -EFAULT; + memset(&tbuf, 0, sizeof(tbuf)); + shp = shm_lock(ns, shmid); + if(shp==NULL) { + err = -EINVAL; goto out; - } - - if (cmd == SHM_STAT) { - shp = shm_lock(ns, shmid); - if (IS_ERR(shp)) { - err = PTR_ERR(shp); - goto out; - } - result = shp->shm_perm.id; + } else if(cmd==SHM_STAT) { + err = -EINVAL; + if (shmid > shm_ids(ns).max_id) + goto out_unlock; + result = shm_buildid(ns, shmid, shp->shm_perm.seq); } else { - shp = shm_lock_check(ns, shmid); - if (IS_ERR(shp)) { - err = PTR_ERR(shp); - goto out; - } + err = shm_checkid(ns, shp,shmid); + if(err) + goto out_unlock; result = 0; } err=-EACCES; @@ -739,7 +668,6 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf) err = security_shm_shmctl(shp, cmd); if (err) goto out_unlock; - memset(&tbuf, 0, sizeof(tbuf)); kernel_to_ipc64_perm(&shp->shm_perm, &tbuf.shm_perm); tbuf.shm_segsz = shp->shm_segsz; tbuf.shm_atime = shp->shm_atim; @@ -758,11 +686,14 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf) case SHM_LOCK: case SHM_UNLOCK: { - shp = shm_lock_check(ns, shmid); - if (IS_ERR(shp)) { - err = PTR_ERR(shp); + shp = shm_lock(ns, shmid); + if(shp==NULL) { + err = -EINVAL; goto out; } + err = shm_checkid(ns, shp,shmid); + if(err) + goto out_unlock; err = audit_ipc_obj(&(shp->shm_perm)); if (err) @@ -811,12 +742,14 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf) * Instead we set a destroyed flag, and then blow * the name away when the usage hits zero. */ - down_write(&shm_ids(ns).rw_mutex); - shp = shm_lock_check_down(ns, shmid); - if (IS_ERR(shp)) { - err = PTR_ERR(shp); + mutex_lock(&shm_ids(ns).mutex); + shp = shm_lock(ns, shmid); + err = -EINVAL; + if (shp == NULL) goto out_up; - } + err = shm_checkid(ns, shp, shmid); + if(err) + goto out_unlock_up; err = audit_ipc_obj(&(shp->shm_perm)); if (err) @@ -834,27 +767,24 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf) goto out_unlock_up; do_shm_rmid(ns, shp); - up_write(&shm_ids(ns).rw_mutex); + mutex_unlock(&shm_ids(ns).mutex); goto out; } case IPC_SET: { - if (!buf) { - err = -EFAULT; - goto out; - } - if (copy_shmid_from_user (&setbuf, buf, version)) { err = -EFAULT; goto out; } - down_write(&shm_ids(ns).rw_mutex); - shp = shm_lock_check_down(ns, shmid); - if (IS_ERR(shp)) { - err = PTR_ERR(shp); + mutex_lock(&shm_ids(ns).mutex); + shp = shm_lock(ns, shmid); + err=-EINVAL; + if(shp==NULL) goto out_up; - } + err = shm_checkid(ns, shp,shmid); + if(err) + goto out_unlock_up; err = audit_ipc_obj(&(shp->shm_perm)); if (err) goto out_unlock_up; @@ -889,7 +819,7 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf) out_unlock_up: shm_unlock(shp); out_up: - up_write(&shm_ids(ns).rw_mutex); + mutex_unlock(&shm_ids(ns).mutex); goto out; out_unlock: shm_unlock(shp); @@ -960,11 +890,13 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr) * additional creator id... */ ns = current->nsproxy->ipc_ns; - shp = shm_lock_check(ns, shmid); - if (IS_ERR(shp)) { - err = PTR_ERR(shp); + shp = shm_lock(ns, shmid); + if(shp == NULL) goto out; - } + + err = shm_checkid(ns, shp,shmid); + if (err) + goto out_unlock; err = -EACCES; if (ipcperms(&shp->shm_perm, acc_mode)) @@ -993,7 +925,7 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr) file->private_data = sfd; file->f_mapping = shp->shm_file->f_mapping; - sfd->id = shp->shm_perm.id; + sfd->id = shp->id; sfd->ns = get_ipc_ns(ns); sfd->file = shp->shm_file; sfd->vm_ops = NULL; @@ -1023,16 +955,16 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr) fput(file); out_nattch: - down_write(&shm_ids(ns).rw_mutex); - shp = shm_lock_down(ns, shmid); - BUG_ON(IS_ERR(shp)); + mutex_lock(&shm_ids(ns).mutex); + shp = shm_lock(ns, shmid); + BUG_ON(!shp); shp->shm_nattch--; if(shp->shm_nattch == 0 && shp->shm_perm.mode & SHM_DEST) shm_destroy(ns, shp); else shm_unlock(shp); - up_write(&shm_ids(ns).rw_mutex); + mutex_unlock(&shm_ids(ns).mutex); out: return err; @@ -1162,7 +1094,7 @@ static int sysvipc_shm_proc_show(struct seq_file *s, void *it) format = BIG_STRING; return seq_printf(s, format, shp->shm_perm.key, - shp->shm_perm.id, + shp->id, shp->shm_perm.mode, shp->shm_segsz, shp->shm_cprid, diff --git a/trunk/ipc/util.c b/trunk/ipc/util.c index 1aa0ebf71bac..44e5135aee47 100644 --- a/trunk/ipc/util.c +++ b/trunk/ipc/util.c @@ -32,7 +32,6 @@ #include #include #include -#include #include @@ -130,16 +129,23 @@ __initcall(ipc_init); /** * ipc_init_ids - initialise IPC identifiers * @ids: Identifier set + * @size: Number of identifiers * - * Set up the sequence range to use for the ipc identifier range (limited - * below IPCMNI) then initialise the ids idr. + * Given a size for the ipc identifier range (limited below IPCMNI) + * set up the sequence range to use then allocate and initialise the + * array itself. */ -void ipc_init_ids(struct ipc_ids *ids) +void ipc_init_ids(struct ipc_ids* ids, int size) { - init_rwsem(&ids->rw_mutex); + int i; + mutex_init(&ids->mutex); + + if(size > IPCMNI) + size = IPCMNI; ids->in_use = 0; + ids->max_id = -1; ids->seq = 0; { int seq_limit = INT_MAX/SEQ_MULTIPLIER; @@ -149,7 +155,17 @@ void ipc_init_ids(struct ipc_ids *ids) ids->seq_max = seq_limit; } - idr_init(&ids->ipcs_idr); + ids->entries = ipc_rcu_alloc(sizeof(struct kern_ipc_perm *)*size + + sizeof(struct ipc_id_ary)); + + if(ids->entries == NULL) { + printk(KERN_ERR "ipc_init_ids() failed, ipc service disabled.\n"); + size = 0; + ids->entries = &ids->nullentry; + } + ids->entries->size = size; + for(i=0;ientries->p[i] = NULL; } #ifdef CONFIG_PROC_FS @@ -192,96 +208,99 @@ void __init ipc_init_proc_interface(const char *path, const char *header, * @ids: Identifier set * @key: The key to find * - * Requires ipc_ids.rw_mutex locked. - * Returns the LOCKED pointer to the ipc structure if found or NULL - * if not. - * If key is found ipc points to the owning ipc structure + * Requires ipc_ids.mutex locked. + * Returns the identifier if found or -1 if not. */ -static struct kern_ipc_perm *ipc_findkey(struct ipc_ids *ids, key_t key) +int ipc_findkey(struct ipc_ids* ids, key_t key) { - struct kern_ipc_perm *ipc; - int next_id; - int total; + int id; + struct kern_ipc_perm* p; + int max_id = ids->max_id; - for (total = 0, next_id = 0; total < ids->in_use; next_id++) { - ipc = idr_find(&ids->ipcs_idr, next_id); - - if (ipc == NULL) - continue; - - if (ipc->key != key) { - total++; + /* + * rcu_dereference() is not needed here + * since ipc_ids.mutex is held + */ + for (id = 0; id <= max_id; id++) { + p = ids->entries->p[id]; + if(p==NULL) continue; - } - - ipc_lock_by_ptr(ipc); - return ipc; + if (key == p->key) + return id; } - - return NULL; + return -1; } -/** - * ipc_get_maxid - get the last assigned id - * @ids: IPC identifier set - * - * Called with ipc_ids.rw_mutex held. +/* + * Requires ipc_ids.mutex locked */ +static int grow_ary(struct ipc_ids* ids, int newsize) +{ + struct ipc_id_ary* new; + struct ipc_id_ary* old; + int i; + int size = ids->entries->size; + + if(newsize > IPCMNI) + newsize = IPCMNI; + if(newsize <= size) + return newsize; + + new = ipc_rcu_alloc(sizeof(struct kern_ipc_perm *)*newsize + + sizeof(struct ipc_id_ary)); + if(new == NULL) + return size; + new->size = newsize; + memcpy(new->p, ids->entries->p, sizeof(struct kern_ipc_perm *)*size); + for(i=size;ip[i] = NULL; + } + old = ids->entries; -int ipc_get_maxid(struct ipc_ids *ids) -{ - struct kern_ipc_perm *ipc; - int max_id = -1; - int total, id; - - if (ids->in_use == 0) - return -1; - - if (ids->in_use == IPCMNI) - return IPCMNI - 1; + /* + * Use rcu_assign_pointer() to make sure the memcpyed contents + * of the new array are visible before the new array becomes visible. + */ + rcu_assign_pointer(ids->entries, new); - /* Look for the last assigned id */ - total = 0; - for (id = 0; id < IPCMNI && total < ids->in_use; id++) { - ipc = idr_find(&ids->ipcs_idr, id); - if (ipc != NULL) { - max_id = id; - total++; - } - } - return max_id; + __ipc_fini_ids(ids, old); + return newsize; } /** * ipc_addid - add an IPC identifier * @ids: IPC identifier set * @new: new IPC permission set - * @size: limit for the number of used ids + * @size: new size limit for the id array * - * Add an entry 'new' to the IPC ids idr. The permissions object is + * Add an entry 'new' to the IPC arrays. The permissions object is * initialised and the first free entry is set up and the id assigned - * is returned. The 'new' entry is returned in a locked state on success. - * On failure the entry is not locked and a negative err-code is returned. + * is returned. The list is returned in a locked state on success. + * On failure the list is not locked and -1 is returned. * - * Called with ipc_ids.rw_mutex held as a writer. + * Called with ipc_ids.mutex held. */ int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size) { - int id, err; - - if (size > IPCMNI) - size = IPCMNI; + int id; - if (ids->in_use >= size) - return -ENOSPC; - - err = idr_get_new(&ids->ipcs_idr, new, &id); - if (err) - return err; + size = grow_ary(ids,size); + /* + * rcu_dereference()() is not needed here since + * ipc_ids.mutex is held + */ + for (id = 0; id < size; id++) { + if(ids->entries->p[id] == NULL) + goto found; + } + return -1; +found: ids->in_use++; + if (id > ids->max_id) + ids->max_id = id; new->cuid = new->uid = current->euid; new->gid = new->cgid = current->egid; @@ -294,153 +313,48 @@ int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size) new->deleted = 0; rcu_read_lock(); spin_lock(&new->lock); + ids->entries->p[id] = new; return id; } -/** - * ipcget_new - create a new ipc object - * @ns: namespace - * @ids: IPC identifer set - * @ops: the actual creation routine to call - * @params: its parameters - * - * This routine is called by sys_msgget, sys_semget() and sys_shmget() - * when the key is IPC_PRIVATE. - */ -int ipcget_new(struct ipc_namespace *ns, struct ipc_ids *ids, - struct ipc_ops *ops, struct ipc_params *params) -{ - int err; -retry: - err = idr_pre_get(&ids->ipcs_idr, GFP_KERNEL); - - if (!err) - return -ENOMEM; - - down_write(&ids->rw_mutex); - err = ops->getnew(ns, params); - up_write(&ids->rw_mutex); - - if (err == -EAGAIN) - goto retry; - - return err; -} - -/** - * ipc_check_perms - check security and permissions for an IPC - * @ipcp: ipc permission set - * @ops: the actual security routine to call - * @params: its parameters - * - * This routine is called by sys_msgget(), sys_semget() and sys_shmget() - * when the key is not IPC_PRIVATE and that key already exists in the - * ids IDR. - * - * On success, the IPC id is returned. - * - * It is called with ipc_ids.rw_mutex and ipcp->lock held. - */ -static int ipc_check_perms(struct kern_ipc_perm *ipcp, struct ipc_ops *ops, - struct ipc_params *params) -{ - int err; - - if (ipcperms(ipcp, params->flg)) - err = -EACCES; - else { - err = ops->associate(ipcp, params->flg); - if (!err) - err = ipcp->id; - } - - return err; -} - -/** - * ipcget_public - get an ipc object or create a new one - * @ns: namespace - * @ids: IPC identifer set - * @ops: the actual creation routine to call - * @params: its parameters - * - * This routine is called by sys_msgget, sys_semget() and sys_shmget() - * when the key is not IPC_PRIVATE. - * It adds a new entry if the key is not found and does some permission - * / security checkings if the key is found. - * - * On success, the ipc id is returned. - */ -int ipcget_public(struct ipc_namespace *ns, struct ipc_ids *ids, - struct ipc_ops *ops, struct ipc_params *params) -{ - struct kern_ipc_perm *ipcp; - int flg = params->flg; - int err; -retry: - err = idr_pre_get(&ids->ipcs_idr, GFP_KERNEL); - - /* - * Take the lock as a writer since we are potentially going to add - * a new entry + read locks are not "upgradable" - */ - down_write(&ids->rw_mutex); - ipcp = ipc_findkey(ids, params->key); - if (ipcp == NULL) { - /* key not used */ - if (!(flg & IPC_CREAT)) - err = -ENOENT; - else if (!err) - err = -ENOMEM; - else - err = ops->getnew(ns, params); - } else { - /* ipc object has been locked by ipc_findkey() */ - - if (flg & IPC_CREAT && flg & IPC_EXCL) - err = -EEXIST; - else { - err = 0; - if (ops->more_checks) - err = ops->more_checks(ipcp, params); - if (!err) - /* - * ipc_check_perms returns the IPC id on - * success - */ - err = ipc_check_perms(ipcp, ops, params); - } - ipc_unlock(ipcp); - } - up_write(&ids->rw_mutex); - - if (err == -EAGAIN) - goto retry; - - return err; -} - - /** * ipc_rmid - remove an IPC identifier - * @ids: IPC identifier set - * @ipcp: ipc perm structure containing the identifier to remove + * @ids: identifier set + * @id: Identifier to remove * - * ipc_ids.rw_mutex (as a writer) and the spinlock for this ID are held - * before this function is called, and remain locked on the exit. + * The identifier must be valid, and in use. The kernel will panic if + * fed an invalid identifier. The entry is removed and internal + * variables recomputed. The object associated with the identifier + * is returned. + * ipc_ids.mutex and the spinlock for this ID is hold before this function + * is called, and remain locked on the exit. */ -void ipc_rmid(struct ipc_ids *ids, struct kern_ipc_perm *ipcp) +struct kern_ipc_perm* ipc_rmid(struct ipc_ids* ids, int id) { - int lid = ipcid_to_idx(ipcp->id); - - idr_remove(&ids->ipcs_idr, lid); + struct kern_ipc_perm* p; + int lid = id % SEQ_MULTIPLIER; + BUG_ON(lid >= ids->entries->size); + /* + * do not need a rcu_dereference()() here to force ordering + * on Alpha, since the ipc_ids.mutex is held. + */ + p = ids->entries->p[lid]; + ids->entries->p[lid] = NULL; + BUG_ON(p==NULL); ids->in_use--; - ipcp->deleted = 1; - - return; + if (lid == ids->max_id) { + do { + lid--; + if(lid == -1) + break; + } while (ids->entries->p[lid] == NULL); + ids->max_id = lid; + } + p->deleted = 1; + return p; } /** @@ -577,12 +491,10 @@ static void ipc_do_vfree(struct work_struct *work) */ static void ipc_schedule_free(struct rcu_head *head) { - struct ipc_rcu_grace *grace; - struct ipc_rcu_sched *sched; - - grace = container_of(head, struct ipc_rcu_grace, rcu); - sched = container_of(&(grace->data[0]), struct ipc_rcu_sched, - data[0]); + struct ipc_rcu_grace *grace = + container_of(head, struct ipc_rcu_grace, rcu); + struct ipc_rcu_sched *sched = + container_of(&(grace->data[0]), struct ipc_rcu_sched, data[0]); INIT_WORK(&sched->work, ipc_do_vfree); schedule_work(&sched->work); @@ -671,7 +583,7 @@ void kernel_to_ipc64_perm (struct kern_ipc_perm *in, struct ipc64_perm *out) } /** - * ipc64_perm_to_ipc_perm - convert new ipc permissions to old + * ipc64_perm_to_ipc_perm - convert old ipc permissions to new * @in: new style IPC permissions * @out: old style IPC permissions * @@ -690,37 +602,44 @@ void ipc64_perm_to_ipc_perm (struct ipc64_perm *in, struct ipc_perm *out) out->seq = in->seq; } -/** - * ipc_lock - Lock an ipc structure without rw_mutex held - * @ids: IPC identifier set - * @id: ipc id to look for - * - * Look for an id in the ipc ids idr and lock the associated ipc object. - * - * The ipc object is locked on exit. +/* + * So far only shm_get_stat() calls ipc_get() via shm_get(), so ipc_get() + * is called with shm_ids.mutex locked. Since grow_ary() is also called with + * shm_ids.mutex down(for Shared Memory), there is no need to add read + * barriers here to gurantee the writes in grow_ary() are seen in order + * here (for Alpha). * - * This is the routine that should be called when the rw_mutex is not already - * held, i.e. idr tree not protected: it protects the idr tree in read mode - * during the idr_find(). + * However ipc_get() itself does not necessary require ipc_ids.mutex down. So + * if in the future ipc_get() is used by other places without ipc_ids.mutex + * down, then ipc_get() needs read memery barriers as ipc_lock() does. */ - -struct kern_ipc_perm *ipc_lock(struct ipc_ids *ids, int id) +struct kern_ipc_perm* ipc_get(struct ipc_ids* ids, int id) { - struct kern_ipc_perm *out; - int lid = ipcid_to_idx(id); + struct kern_ipc_perm* out; + int lid = id % SEQ_MULTIPLIER; + if(lid >= ids->entries->size) + return NULL; + out = ids->entries->p[lid]; + return out; +} - down_read(&ids->rw_mutex); +struct kern_ipc_perm* ipc_lock(struct ipc_ids* ids, int id) +{ + struct kern_ipc_perm* out; + int lid = id % SEQ_MULTIPLIER; + struct ipc_id_ary* entries; rcu_read_lock(); - out = idr_find(&ids->ipcs_idr, lid); - if (out == NULL) { + entries = rcu_dereference(ids->entries); + if(lid >= entries->size) { + rcu_read_unlock(); + return NULL; + } + out = entries->p[lid]; + if(out == NULL) { rcu_read_unlock(); - up_read(&ids->rw_mutex); - return ERR_PTR(-EINVAL); + return NULL; } - - up_read(&ids->rw_mutex); - spin_lock(&out->lock); /* ipc_rmid() may have already freed the ID while ipc_lock @@ -729,44 +648,33 @@ struct kern_ipc_perm *ipc_lock(struct ipc_ids *ids, int id) if (out->deleted) { spin_unlock(&out->lock); rcu_read_unlock(); - return ERR_PTR(-EINVAL); + return NULL; } - return out; } -/** - * ipc_lock_down - Lock an ipc structure with rw_sem held - * @ids: IPC identifier set - * @id: ipc id to look for - * - * Look for an id in the ipc ids idr and lock the associated ipc object. - * - * The ipc object is locked on exit. - * - * This is the routine that should be called when the rw_mutex is already - * held, i.e. idr tree protected. - */ - -struct kern_ipc_perm *ipc_lock_down(struct ipc_ids *ids, int id) +void ipc_lock_by_ptr(struct kern_ipc_perm *perm) { - struct kern_ipc_perm *out; - int lid = ipcid_to_idx(id); - rcu_read_lock(); - out = idr_find(&ids->ipcs_idr, lid); - if (out == NULL) { - rcu_read_unlock(); - return ERR_PTR(-EINVAL); - } + spin_lock(&perm->lock); +} - spin_lock(&out->lock); +void ipc_unlock(struct kern_ipc_perm* perm) +{ + spin_unlock(&perm->lock); + rcu_read_unlock(); +} - /* - * No need to verify that the structure is still valid since the - * rw_mutex is held. - */ - return out; +int ipc_buildid(struct ipc_ids* ids, int id, int seq) +{ + return SEQ_MULTIPLIER*seq + id; +} + +int ipc_checkid(struct ipc_ids* ids, struct kern_ipc_perm* ipcp, int uid) +{ + if(uid/SEQ_MULTIPLIER != ipcp->seq) + return 1; + return 0; } #ifdef __ARCH_WANT_IPC_PARSE_VERSION @@ -799,59 +707,45 @@ struct ipc_proc_iter { struct ipc_proc_iface *iface; }; -/* - * This routine locks the ipc structure found at least at position pos. - */ -struct kern_ipc_perm *sysvipc_find_ipc(struct ipc_ids *ids, loff_t pos, - loff_t *new_pos) -{ - struct kern_ipc_perm *ipc; - int total, id; - - total = 0; - for (id = 0; id < pos && total < ids->in_use; id++) { - ipc = idr_find(&ids->ipcs_idr, id); - if (ipc != NULL) - total++; - } - - if (total >= ids->in_use) - return NULL; - - for ( ; pos < IPCMNI; pos++) { - ipc = idr_find(&ids->ipcs_idr, pos); - if (ipc != NULL) { - *new_pos = pos + 1; - ipc_lock_by_ptr(ipc); - return ipc; - } - } - - /* Out of range - return NULL to terminate iteration */ - return NULL; -} - static void *sysvipc_proc_next(struct seq_file *s, void *it, loff_t *pos) { struct ipc_proc_iter *iter = s->private; struct ipc_proc_iface *iface = iter->iface; struct kern_ipc_perm *ipc = it; + loff_t p; + struct ipc_ids *ids; + + ids = iter->ns->ids[iface->ids]; /* If we had an ipc id locked before, unlock it */ if (ipc && ipc != SEQ_START_TOKEN) ipc_unlock(ipc); - return sysvipc_find_ipc(iter->ns->ids[iface->ids], *pos, pos); + /* + * p = *pos - 1 (because id 0 starts at position 1) + * + 1 (because we increment the position by one) + */ + for (p = *pos; p <= ids->max_id; p++) { + if ((ipc = ipc_lock(ids, p)) != NULL) { + *pos = p + 1; + return ipc; + } + } + + /* Out of range - return NULL to terminate iteration */ + return NULL; } /* - * File positions: pos 0 -> header, pos n -> ipc id = n - 1. - * SeqFile iterator: iterator value locked ipc pointer or SEQ_TOKEN_START. + * File positions: pos 0 -> header, pos n -> ipc id + 1. + * SeqFile iterator: iterator value locked shp or SEQ_TOKEN_START. */ static void *sysvipc_proc_start(struct seq_file *s, loff_t *pos) { struct ipc_proc_iter *iter = s->private; struct ipc_proc_iface *iface = iter->iface; + struct kern_ipc_perm *ipc; + loff_t p; struct ipc_ids *ids; ids = iter->ns->ids[iface->ids]; @@ -860,7 +754,7 @@ static void *sysvipc_proc_start(struct seq_file *s, loff_t *pos) * Take the lock - this will be released by the corresponding * call to stop(). */ - down_read(&ids->rw_mutex); + mutex_lock(&ids->mutex); /* pos < 0 is invalid */ if (*pos < 0) @@ -871,7 +765,13 @@ static void *sysvipc_proc_start(struct seq_file *s, loff_t *pos) return SEQ_START_TOKEN; /* Find the (pos-1)th ipc */ - return sysvipc_find_ipc(ids, *pos - 1, pos); + for (p = *pos - 1; p <= ids->max_id; p++) { + if ((ipc = ipc_lock(ids, p)) != NULL) { + *pos = p + 1; + return ipc; + } + } + return NULL; } static void sysvipc_proc_stop(struct seq_file *s, void *it) @@ -881,13 +781,13 @@ static void sysvipc_proc_stop(struct seq_file *s, void *it) struct ipc_proc_iface *iface = iter->iface; struct ipc_ids *ids; - /* If we had a locked structure, release it */ + /* If we had a locked segment, release it */ if (ipc && ipc != SEQ_START_TOKEN) ipc_unlock(ipc); ids = iter->ns->ids[iface->ids]; /* Release the lock we took in start() */ - up_read(&ids->rw_mutex); + mutex_unlock(&ids->mutex); } static int sysvipc_proc_show(struct seq_file *s, void *it) diff --git a/trunk/ipc/util.h b/trunk/ipc/util.h index 9ffea40457ce..333e891bcaca 100644 --- a/trunk/ipc/util.h +++ b/trunk/ipc/util.h @@ -10,9 +10,6 @@ #ifndef _IPC_UTIL_H #define _IPC_UTIL_H -#include -#include - #define USHRT_MAX 0xffff #define SEQ_MULTIPLIER (IPCMNI) @@ -28,46 +25,24 @@ void sem_exit_ns(struct ipc_namespace *ns); void msg_exit_ns(struct ipc_namespace *ns); void shm_exit_ns(struct ipc_namespace *ns); +struct ipc_id_ary { + int size; + struct kern_ipc_perm *p[0]; +}; + struct ipc_ids { int in_use; + int max_id; unsigned short seq; unsigned short seq_max; - struct rw_semaphore rw_mutex; - struct idr ipcs_idr; -}; - -/* - * Structure that holds the parameters needed by the ipc operations - * (see after) - */ -struct ipc_params { - key_t key; - int flg; - union { - size_t size; /* for shared memories */ - int nsems; /* for semaphores */ - } u; /* holds the getnew() specific param */ -}; - -/* - * Structure that holds some ipc operations. This structure is used to unify - * the calls to sys_msgget(), sys_semget(), sys_shmget() - * . routine to call to create a new ipc object. Can be one of newque, - * newary, newseg - * . routine to call to check permissions for a new ipc object. - * Can be one of security_msg_associate, security_sem_associate, - * security_shm_associate - * . routine to call for an extra check if needed - */ -struct ipc_ops { - int (*getnew) (struct ipc_namespace *, struct ipc_params *); - int (*associate) (struct kern_ipc_perm *, int); - int (*more_checks) (struct kern_ipc_perm *, struct ipc_params *); + struct mutex mutex; + struct ipc_id_ary nullentry; + struct ipc_id_ary* entries; }; struct seq_file; -void ipc_init_ids(struct ipc_ids *); +void ipc_init_ids(struct ipc_ids *ids, int size); #ifdef CONFIG_PROC_FS void __init ipc_init_proc_interface(const char *path, const char *header, int ids, int (*show)(struct seq_file *, void *)); @@ -79,19 +54,14 @@ void __init ipc_init_proc_interface(const char *path, const char *header, #define IPC_MSG_IDS 1 #define IPC_SHM_IDS 2 -#define ipcid_to_idx(id) ((id) % SEQ_MULTIPLIER) - -/* must be called with ids->rw_mutex acquired for writing */ -int ipc_addid(struct ipc_ids *, struct kern_ipc_perm *, int); - -/* must be called with ids->rw_mutex acquired for reading */ -int ipc_get_maxid(struct ipc_ids *); +/* must be called with ids->mutex acquired.*/ +int ipc_findkey(struct ipc_ids* ids, key_t key); +int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size); /* must be called with both locks acquired. */ -void ipc_rmid(struct ipc_ids *, struct kern_ipc_perm *); +struct kern_ipc_perm* ipc_rmid(struct ipc_ids* ids, int id); -/* must be called with ipcp locked */ -int ipcperms(struct kern_ipc_perm *ipcp, short flg); +int ipcperms (struct kern_ipc_perm *ipcp, short flg); /* for rare, potentially huge allocations. * both function can sleep @@ -109,12 +79,24 @@ void* ipc_rcu_alloc(int size); void ipc_rcu_getref(void *ptr); void ipc_rcu_putref(void *ptr); -/* - * ipc_lock_down: called with rw_mutex held - * ipc_lock: called without that lock held - */ -struct kern_ipc_perm *ipc_lock_down(struct ipc_ids *, int); -struct kern_ipc_perm *ipc_lock(struct ipc_ids *, int); +static inline void __ipc_fini_ids(struct ipc_ids *ids, + struct ipc_id_ary *entries) +{ + if (entries != &ids->nullentry) + ipc_rcu_putref(entries); +} + +static inline void ipc_fini_ids(struct ipc_ids *ids) +{ + __ipc_fini_ids(ids, ids->entries); +} + +struct kern_ipc_perm* ipc_get(struct ipc_ids* ids, int id); +struct kern_ipc_perm* ipc_lock(struct ipc_ids* ids, int id); +void ipc_lock_by_ptr(struct kern_ipc_perm *ipcp); +void ipc_unlock(struct kern_ipc_perm* perm); +int ipc_buildid(struct ipc_ids* ids, int id, int seq); +int ipc_checkid(struct ipc_ids* ids, struct kern_ipc_perm* ipcp, int uid); void kernel_to_ipc64_perm(struct kern_ipc_perm *in, struct ipc64_perm *out); void ipc64_perm_to_ipc_perm(struct ipc64_perm *in, struct ipc_perm *out); @@ -129,89 +111,5 @@ int ipc_parse_version (int *cmd); extern void free_msg(struct msg_msg *msg); extern struct msg_msg *load_msg(const void __user *src, int len); extern int store_msg(void __user *dest, struct msg_msg *msg, int len); -extern int ipcget_new(struct ipc_namespace *, struct ipc_ids *, - struct ipc_ops *, struct ipc_params *); -extern int ipcget_public(struct ipc_namespace *, struct ipc_ids *, - struct ipc_ops *, struct ipc_params *); - -static inline int ipc_buildid(int id, int seq) -{ - return SEQ_MULTIPLIER * seq + id; -} - -/* - * Must be called with ipcp locked - */ -static inline int ipc_checkid(struct kern_ipc_perm *ipcp, int uid) -{ - if (uid / SEQ_MULTIPLIER != ipcp->seq) - return 1; - return 0; -} - -static inline void ipc_lock_by_ptr(struct kern_ipc_perm *perm) -{ - rcu_read_lock(); - spin_lock(&perm->lock); -} - -static inline void ipc_unlock(struct kern_ipc_perm *perm) -{ - spin_unlock(&perm->lock); - rcu_read_unlock(); -} - -static inline struct kern_ipc_perm *ipc_lock_check_down(struct ipc_ids *ids, - int id) -{ - struct kern_ipc_perm *out; - - out = ipc_lock_down(ids, id); - if (IS_ERR(out)) - return out; - - if (ipc_checkid(out, id)) { - ipc_unlock(out); - return ERR_PTR(-EIDRM); - } - - return out; -} - -static inline struct kern_ipc_perm *ipc_lock_check(struct ipc_ids *ids, - int id) -{ - struct kern_ipc_perm *out; - - out = ipc_lock(ids, id); - if (IS_ERR(out)) - return out; - - if (ipc_checkid(out, id)) { - ipc_unlock(out); - return ERR_PTR(-EIDRM); - } - - return out; -} - -/** - * ipcget - Common sys_*get() code - * @ns : namsepace - * @ids : IPC identifier set - * @ops : operations to be called on ipc object creation, permission checks - * and further checks - * @params : the parameters needed by the previous operations. - * - * Common routine called by sys_msgget(), sys_semget() and sys_shmget(). - */ -static inline int ipcget(struct ipc_namespace *ns, struct ipc_ids *ids, - struct ipc_ops *ops, struct ipc_params *params) -{ - if (params->key == IPC_PRIVATE) - return ipcget_new(ns, ids, ops, params); - else - return ipcget_public(ns, ids, ops, params); -} #endif diff --git a/trunk/kernel/Kconfig.instrumentation b/trunk/kernel/Kconfig.instrumentation deleted file mode 100644 index f5f2c769d95e..000000000000 --- a/trunk/kernel/Kconfig.instrumentation +++ /dev/null @@ -1,49 +0,0 @@ -menuconfig INSTRUMENTATION - bool "Instrumentation Support" - default y - ---help--- - Say Y here to get to see options related to performance measurement, - system-wide debugging, and testing. This option alone does not add any - kernel code. - - If you say N, all options in this submenu will be skipped and - disabled. If you're trying to debug the kernel itself, go see the - Kernel Hacking menu. - -if INSTRUMENTATION - -config PROFILING - bool "Profiling support (EXPERIMENTAL)" - help - Say Y here to enable the extended profiling support mechanisms used - by profilers such as OProfile. - -config OPROFILE - tristate "OProfile system profiling (EXPERIMENTAL)" - depends on PROFILING - depends on ALPHA || ARM || BLACKFIN || X86_32 || IA64 || M32R || MIPS || PARISC || PPC || S390 || SUPERH || SPARC || X86_64 - help - OProfile is a profiling system capable of profiling the - whole system, include the kernel, kernel modules, libraries, - and applications. - - If unsure, say N. - -config KPROBES - bool "Kprobes" - depends on KALLSYMS && MODULES - depends on X86_32 || IA64 || PPC || S390 || SPARC64 || X86_64 || AVR32 - help - Kprobes allows you to trap at almost any kernel address and - execute a callback function. register_kprobe() establishes - a probepoint and specifies the callback. Kprobes is useful - for kernel debugging, non-intrusive instrumentation and testing. - If in doubt, say "N". - -config MARKERS - bool "Activate markers" - help - Place an empty function call at each marker site. Can be - dynamically changed for a probe function. - -endif # INSTRUMENTATION diff --git a/trunk/kernel/Makefile b/trunk/kernel/Makefile index 05c3e6df8597..2a999836ca18 100644 --- a/trunk/kernel/Makefile +++ b/trunk/kernel/Makefile @@ -8,8 +8,8 @@ obj-y = sched.o fork.o exec_domain.o panic.o printk.o profile.o \ signal.o sys.o kmod.o workqueue.o pid.o \ rcupdate.o extable.o params.o posix-timers.o \ kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \ - hrtimer.o rwsem.o latency.o nsproxy.o srcu.o \ - utsname.o sysctl_check.o notifier.o + hrtimer.o rwsem.o latency.o nsproxy.o srcu.o die_notifier.o \ + utsname.o obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-y += time/ @@ -36,11 +36,7 @@ obj-$(CONFIG_PM) += power/ obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o obj-$(CONFIG_KEXEC) += kexec.o obj-$(CONFIG_COMPAT) += compat.o -obj-$(CONFIG_CGROUPS) += cgroup.o -obj-$(CONFIG_CGROUP_DEBUG) += cgroup_debug.o obj-$(CONFIG_CPUSETS) += cpuset.o -obj-$(CONFIG_CGROUP_CPUACCT) += cpu_acct.o -obj-$(CONFIG_CGROUP_NS) += ns_cgroup.o obj-$(CONFIG_IKCONFIG) += configs.o obj-$(CONFIG_STOP_MACHINE) += stop_machine.o obj-$(CONFIG_AUDIT) += audit.o auditfilter.o @@ -55,7 +51,6 @@ obj-$(CONFIG_RELAY) += relay.o obj-$(CONFIG_SYSCTL) += utsname_sysctl.o obj-$(CONFIG_TASK_DELAY_ACCT) += delayacct.o obj-$(CONFIG_TASKSTATS) += taskstats.o tsacct.o -obj-$(CONFIG_MARKERS) += marker.o ifneq ($(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER),y) # According to Alan Modra , the -fno-omit-frame-pointer is diff --git a/trunk/kernel/acct.c b/trunk/kernel/acct.c index fce53d8df8a7..24f0f8b2ba72 100644 --- a/trunk/kernel/acct.c +++ b/trunk/kernel/acct.c @@ -329,16 +329,16 @@ static comp_t encode_comp_t(unsigned long value) } /* - * If we need to round up, do it (and handle overflow correctly). - */ + * If we need to round up, do it (and handle overflow correctly). + */ if (rnd && (++value > MAXFRACT)) { value >>= EXPSIZE; exp++; } /* - * Clean it up and polish it off. - */ + * Clean it up and polish it off. + */ exp <<= MANTSIZE; /* Shift the exponent into place */ exp += value; /* and add on the mantissa. */ return exp; @@ -361,30 +361,30 @@ static comp_t encode_comp_t(unsigned long value) static comp2_t encode_comp2_t(u64 value) { - int exp, rnd; - - exp = (value > (MAXFRACT2>>1)); - rnd = 0; - while (value > MAXFRACT2) { - rnd = value & 1; - value >>= 1; - exp++; - } - - /* - * If we need to round up, do it (and handle overflow correctly). - */ - if (rnd && (++value > MAXFRACT2)) { - value >>= 1; - exp++; - } - - if (exp > MAXEXP2) { - /* Overflow. Return largest representable number instead. */ - return (1ul << (MANTSIZE2+EXPSIZE2-1)) - 1; - } else { - return (value & (MAXFRACT2>>1)) | (exp << (MANTSIZE2-1)); - } + int exp, rnd; + + exp = (value > (MAXFRACT2>>1)); + rnd = 0; + while (value > MAXFRACT2) { + rnd = value & 1; + value >>= 1; + exp++; + } + + /* + * If we need to round up, do it (and handle overflow correctly). + */ + if (rnd && (++value > MAXFRACT2)) { + value >>= 1; + exp++; + } + + if (exp > MAXEXP2) { + /* Overflow. Return largest representable number instead. */ + return (1ul << (MANTSIZE2+EXPSIZE2-1)) - 1; + } else { + return (value & (MAXFRACT2>>1)) | (exp << (MANTSIZE2-1)); + } } #endif @@ -501,14 +501,14 @@ static void do_acct_process(struct file *file) ac.ac_swaps = encode_comp_t(0); /* - * Kernel segment override to datasegment and write it - * to the accounting file. - */ + * Kernel segment override to datasegment and write it + * to the accounting file. + */ fs = get_fs(); set_fs(KERNEL_DS); /* - * Accounting records are not subject to resource limits. - */ + * Accounting records are not subject to resource limits. + */ flim = current->signal->rlim[RLIMIT_FSIZE].rlim_cur; current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY; file->f_op->write(file, (char *)&ac, diff --git a/trunk/kernel/audit.c b/trunk/kernel/audit.c index 6977ea57a7e2..2924251a6547 100644 --- a/trunk/kernel/audit.c +++ b/trunk/kernel/audit.c @@ -664,11 +664,11 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) if (sid) { if (selinux_sid_to_string( sid, &ctx, &len)) { - audit_log_format(ab, + audit_log_format(ab, " ssid=%u", sid); /* Maybe call audit_panic? */ } else - audit_log_format(ab, + audit_log_format(ab, " subj=%s", ctx); kfree(ctx); } @@ -769,7 +769,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) sig_data->pid = audit_sig_pid; memcpy(sig_data->ctx, ctx, len); kfree(ctx); - audit_send_reply(NETLINK_CB(skb).pid, seq, AUDIT_SIGNAL_INFO, + audit_send_reply(NETLINK_CB(skb).pid, seq, AUDIT_SIGNAL_INFO, 0, 0, sig_data, sizeof(*sig_data) + len); kfree(sig_data); break; @@ -1005,7 +1005,7 @@ unsigned int audit_serial(void) return ret; } -static inline void audit_get_stamp(struct audit_context *ctx, +static inline void audit_get_stamp(struct audit_context *ctx, struct timespec *t, unsigned int *serial) { if (ctx) @@ -1056,7 +1056,7 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, if (gfp_mask & __GFP_WAIT) reserve = 0; else - reserve = 5; /* Allow atomic callers to go up to five + reserve = 5; /* Allow atomic callers to go up to five entries over the normal backlog limit */ while (audit_backlog_limit @@ -1319,7 +1319,7 @@ void audit_log_d_path(struct audit_buffer *ab, const char *prefix, if (IS_ERR(p)) { /* Should never happen since we send PATH_MAX */ /* FIXME: can we save some information here? */ audit_log_format(ab, ""); - } else + } else audit_log_untrustedstring(ab, p); kfree(path); } @@ -1365,7 +1365,7 @@ void audit_log_end(struct audit_buffer *ab) * audit_log_vformat, and audit_log_end. It may be called * in any context. */ -void audit_log(struct audit_context *ctx, gfp_t gfp_mask, int type, +void audit_log(struct audit_context *ctx, gfp_t gfp_mask, int type, const char *fmt, ...) { struct audit_buffer *ab; diff --git a/trunk/kernel/auditfilter.c b/trunk/kernel/auditfilter.c index df66a21fb360..359645cff5b2 100644 --- a/trunk/kernel/auditfilter.c +++ b/trunk/kernel/auditfilter.c @@ -1498,7 +1498,7 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data, * auditctl to read from it... which isn't ever going to * happen if we're actually running in the context of auditctl * trying to _send_ the stuff */ - + dest = kmalloc(sizeof(struct audit_netlink_list), GFP_KERNEL); if (!dest) return -ENOMEM; @@ -1678,7 +1678,7 @@ int audit_filter_type(int type) { struct audit_entry *e; int result = 0; - + rcu_read_lock(); if (list_empty(&audit_filter_list[AUDIT_FILTER_TYPE])) goto unlock_and_return; diff --git a/trunk/kernel/auditsc.c b/trunk/kernel/auditsc.c index e19b5a33aede..938e60a61882 100644 --- a/trunk/kernel/auditsc.c +++ b/trunk/kernel/auditsc.c @@ -320,7 +320,7 @@ static int audit_filter_rules(struct task_struct *tsk, result = audit_comparator(tsk->personality, f->op, f->val); break; case AUDIT_ARCH: - if (ctx) + if (ctx) result = audit_comparator(ctx->arch, f->op, f->val); break; @@ -898,7 +898,7 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts if (context->personality != PER_LINUX) audit_log_format(ab, " per=%lx", context->personality); if (context->return_valid) - audit_log_format(ab, " success=%s exit=%ld", + audit_log_format(ab, " success=%s exit=%ld", (context->return_valid==AUDITSC_SUCCESS)?"yes":"no", context->return_code); @@ -1135,8 +1135,8 @@ void audit_free(struct task_struct *tsk) return; /* Check for system calls that do not go through the exit - * function (e.g., exit_group), then free context block. - * We use GFP_ATOMIC here because we might be doing this + * function (e.g., exit_group), then free context block. + * We use GFP_ATOMIC here because we might be doing this * in the context of the idle thread */ /* that can happen only if we are called from do_exit() */ if (context->in_syscall && context->auditable) @@ -1316,7 +1316,7 @@ void __audit_getname(const char *name) context->pwdmnt = mntget(current->fs->pwdmnt); read_unlock(¤t->fs->lock); } - + } /* audit_putname - intercept a putname request diff --git a/trunk/kernel/capability.c b/trunk/kernel/capability.c index efbd9cdce132..4e350a36ed6a 100644 --- a/trunk/kernel/capability.c +++ b/trunk/kernel/capability.c @@ -3,18 +3,20 @@ * * Copyright (C) 1997 Andrew Main * - * Integrated into 2.1.97+, Andrew G. Morgan + * Integrated into 2.1.97+, Andrew G. Morgan * 30 May 2002: Cleanup, Robert M. Love - */ + */ #include #include #include #include #include -#include #include +unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */ +kernel_cap_t cap_bset = CAP_INIT_EFF_SET; + /* * This lock protects task->cap_* for all tasks including current. * Locking rule: acquire this prior to tasklist_lock. @@ -38,49 +40,49 @@ static DEFINE_SPINLOCK(task_capability_lock); */ asmlinkage long sys_capget(cap_user_header_t header, cap_user_data_t dataptr) { - int ret = 0; - pid_t pid; - __u32 version; - struct task_struct *target; - struct __user_cap_data_struct data; - - if (get_user(version, &header->version)) - return -EFAULT; - - if (version != _LINUX_CAPABILITY_VERSION) { - if (put_user(_LINUX_CAPABILITY_VERSION, &header->version)) - return -EFAULT; - return -EINVAL; - } + int ret = 0; + pid_t pid; + __u32 version; + struct task_struct *target; + struct __user_cap_data_struct data; - if (get_user(pid, &header->pid)) - return -EFAULT; + if (get_user(version, &header->version)) + return -EFAULT; - if (pid < 0) - return -EINVAL; + if (version != _LINUX_CAPABILITY_VERSION) { + if (put_user(_LINUX_CAPABILITY_VERSION, &header->version)) + return -EFAULT; + return -EINVAL; + } - spin_lock(&task_capability_lock); - read_lock(&tasklist_lock); + if (get_user(pid, &header->pid)) + return -EFAULT; - if (pid && pid != task_pid_vnr(current)) { - target = find_task_by_vpid(pid); - if (!target) { - ret = -ESRCH; - goto out; - } - } else - target = current; + if (pid < 0) + return -EINVAL; + + spin_lock(&task_capability_lock); + read_lock(&tasklist_lock); - ret = security_capget(target, &data.effective, &data.inheritable, &data.permitted); + if (pid && pid != current->pid) { + target = find_task_by_pid(pid); + if (!target) { + ret = -ESRCH; + goto out; + } + } else + target = current; + + ret = security_capget(target, &data.effective, &data.inheritable, &data.permitted); out: - read_unlock(&tasklist_lock); - spin_unlock(&task_capability_lock); + read_unlock(&tasklist_lock); + spin_unlock(&task_capability_lock); - if (!ret && copy_to_user(dataptr, &data, sizeof data)) - return -EFAULT; + if (!ret && copy_to_user(dataptr, &data, sizeof data)) + return -EFAULT; - return ret; + return ret; } /* @@ -96,7 +98,7 @@ static inline int cap_set_pg(int pgrp_nr, kernel_cap_t *effective, int found = 0; struct pid *pgrp; - pgrp = find_vpid(pgrp_nr); + pgrp = find_pid(pgrp_nr); do_each_pid_task(pgrp, PIDTYPE_PGID, g) { target = g; while_each_thread(g, target) { @@ -113,7 +115,7 @@ static inline int cap_set_pg(int pgrp_nr, kernel_cap_t *effective, } while_each_pid_task(pgrp, PIDTYPE_PGID, g); if (!found) - ret = 0; + ret = 0; return ret; } @@ -130,7 +132,7 @@ static inline int cap_set_all(kernel_cap_t *effective, int found = 0; do_each_thread(g, target) { - if (target == current || is_container_init(target->group_leader)) + if (target == current || is_init(target)) continue; found = 1; if (security_capset_check(target, effective, inheritable, @@ -167,68 +169,68 @@ static inline int cap_set_all(kernel_cap_t *effective, */ asmlinkage long sys_capset(cap_user_header_t header, const cap_user_data_t data) { - kernel_cap_t inheritable, permitted, effective; - __u32 version; - struct task_struct *target; - int ret; - pid_t pid; - - if (get_user(version, &header->version)) - return -EFAULT; - - if (version != _LINUX_CAPABILITY_VERSION) { - if (put_user(_LINUX_CAPABILITY_VERSION, &header->version)) - return -EFAULT; - return -EINVAL; - } - - if (get_user(pid, &header->pid)) - return -EFAULT; - - if (pid && pid != task_pid_vnr(current) && !capable(CAP_SETPCAP)) - return -EPERM; - - if (copy_from_user(&effective, &data->effective, sizeof(effective)) || - copy_from_user(&inheritable, &data->inheritable, sizeof(inheritable)) || - copy_from_user(&permitted, &data->permitted, sizeof(permitted))) - return -EFAULT; - - spin_lock(&task_capability_lock); - read_lock(&tasklist_lock); - - if (pid > 0 && pid != task_pid_vnr(current)) { - target = find_task_by_vpid(pid); - if (!target) { - ret = -ESRCH; - goto out; - } - } else - target = current; - - ret = 0; - - /* having verified that the proposed changes are legal, - we now put them into effect. */ - if (pid < 0) { - if (pid == -1) /* all procs other than current and init */ - ret = cap_set_all(&effective, &inheritable, &permitted); - - else /* all procs in process group */ - ret = cap_set_pg(-pid, &effective, &inheritable, - &permitted); - } else { - ret = security_capset_check(target, &effective, &inheritable, - &permitted); - if (!ret) - security_capset_set(target, &effective, &inheritable, - &permitted); - } + kernel_cap_t inheritable, permitted, effective; + __u32 version; + struct task_struct *target; + int ret; + pid_t pid; + + if (get_user(version, &header->version)) + return -EFAULT; + + if (version != _LINUX_CAPABILITY_VERSION) { + if (put_user(_LINUX_CAPABILITY_VERSION, &header->version)) + return -EFAULT; + return -EINVAL; + } + + if (get_user(pid, &header->pid)) + return -EFAULT; + + if (pid && pid != current->pid && !capable(CAP_SETPCAP)) + return -EPERM; + + if (copy_from_user(&effective, &data->effective, sizeof(effective)) || + copy_from_user(&inheritable, &data->inheritable, sizeof(inheritable)) || + copy_from_user(&permitted, &data->permitted, sizeof(permitted))) + return -EFAULT; + + spin_lock(&task_capability_lock); + read_lock(&tasklist_lock); + + if (pid > 0 && pid != current->pid) { + target = find_task_by_pid(pid); + if (!target) { + ret = -ESRCH; + goto out; + } + } else + target = current; + + ret = 0; + + /* having verified that the proposed changes are legal, + we now put them into effect. */ + if (pid < 0) { + if (pid == -1) /* all procs other than current and init */ + ret = cap_set_all(&effective, &inheritable, &permitted); + + else /* all procs in process group */ + ret = cap_set_pg(-pid, &effective, &inheritable, + &permitted); + } else { + ret = security_capset_check(target, &effective, &inheritable, + &permitted); + if (!ret) + security_capset_set(target, &effective, &inheritable, + &permitted); + } out: - read_unlock(&tasklist_lock); - spin_unlock(&task_capability_lock); + read_unlock(&tasklist_lock); + spin_unlock(&task_capability_lock); - return ret; + return ret; } int __capable(struct task_struct *t, int cap) diff --git a/trunk/kernel/cgroup.c b/trunk/kernel/cgroup.c deleted file mode 100644 index 5987dccdb2a0..000000000000 --- a/trunk/kernel/cgroup.c +++ /dev/null @@ -1,2805 +0,0 @@ -/* - * kernel/cgroup.c - * - * Generic process-grouping system. - * - * Based originally on the cpuset system, extracted by Paul Menage - * Copyright (C) 2006 Google, Inc - * - * Copyright notices from the original cpuset code: - * -------------------------------------------------- - * Copyright (C) 2003 BULL SA. - * Copyright (C) 2004-2006 Silicon Graphics, Inc. - * - * Portions derived from Patrick Mochel's sysfs code. - * sysfs is Copyright (c) 2001-3 Patrick Mochel - * - * 2003-10-10 Written by Simon Derr. - * 2003-10-22 Updates by Stephen Hemminger. - * 2004 May-July Rework by Paul Jackson. - * --------------------------------------------------- - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of the Linux - * distribution for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -static DEFINE_MUTEX(cgroup_mutex); - -/* Generate an array of cgroup subsystem pointers */ -#define SUBSYS(_x) &_x ## _subsys, - -static struct cgroup_subsys *subsys[] = { -#include -}; - -/* - * A cgroupfs_root represents the root of a cgroup hierarchy, - * and may be associated with a superblock to form an active - * hierarchy - */ -struct cgroupfs_root { - struct super_block *sb; - - /* - * The bitmask of subsystems intended to be attached to this - * hierarchy - */ - unsigned long subsys_bits; - - /* The bitmask of subsystems currently attached to this hierarchy */ - unsigned long actual_subsys_bits; - - /* A list running through the attached subsystems */ - struct list_head subsys_list; - - /* The root cgroup for this hierarchy */ - struct cgroup top_cgroup; - - /* Tracks how many cgroups are currently defined in hierarchy.*/ - int number_of_cgroups; - - /* A list running through the mounted hierarchies */ - struct list_head root_list; - - /* Hierarchy-specific flags */ - unsigned long flags; - - /* The path to use for release notifications. No locking - * between setting and use - so if userspace updates this - * while child cgroups exist, you could miss a - * notification. We ensure that it's always a valid - * NUL-terminated string */ - char release_agent_path[PATH_MAX]; -}; - - -/* - * The "rootnode" hierarchy is the "dummy hierarchy", reserved for the - * subsystems that are otherwise unattached - it never has more than a - * single cgroup, and all tasks are part of that cgroup. - */ -static struct cgroupfs_root rootnode; - -/* The list of hierarchy roots */ - -static LIST_HEAD(roots); -static int root_count; - -/* dummytop is a shorthand for the dummy hierarchy's top cgroup */ -#define dummytop (&rootnode.top_cgroup) - -/* This flag indicates whether tasks in the fork and exit paths should - * take callback_mutex and check for fork/exit handlers to call. This - * avoids us having to do extra work in the fork/exit path if none of the - * subsystems need to be called. - */ -static int need_forkexit_callback; - -/* bits in struct cgroup flags field */ -enum { - /* Control Group is dead */ - CGRP_REMOVED, - /* Control Group has previously had a child cgroup or a task, - * but no longer (only if CGRP_NOTIFY_ON_RELEASE is set) */ - CGRP_RELEASABLE, - /* Control Group requires release notifications to userspace */ - CGRP_NOTIFY_ON_RELEASE, -}; - -/* convenient tests for these bits */ -inline int cgroup_is_removed(const struct cgroup *cgrp) -{ - return test_bit(CGRP_REMOVED, &cgrp->flags); -} - -/* bits in struct cgroupfs_root flags field */ -enum { - ROOT_NOPREFIX, /* mounted subsystems have no named prefix */ -}; - -inline int cgroup_is_releasable(const struct cgroup *cgrp) -{ - const int bits = - (1 << CGRP_RELEASABLE) | - (1 << CGRP_NOTIFY_ON_RELEASE); - return (cgrp->flags & bits) == bits; -} - -inline int notify_on_release(const struct cgroup *cgrp) -{ - return test_bit(CGRP_NOTIFY_ON_RELEASE, &cgrp->flags); -} - -/* - * for_each_subsys() allows you to iterate on each subsystem attached to - * an active hierarchy - */ -#define for_each_subsys(_root, _ss) \ -list_for_each_entry(_ss, &_root->subsys_list, sibling) - -/* for_each_root() allows you to iterate across the active hierarchies */ -#define for_each_root(_root) \ -list_for_each_entry(_root, &roots, root_list) - -/* the list of cgroups eligible for automatic release. Protected by - * release_list_lock */ -static LIST_HEAD(release_list); -static DEFINE_SPINLOCK(release_list_lock); -static void cgroup_release_agent(struct work_struct *work); -static DECLARE_WORK(release_agent_work, cgroup_release_agent); -static void check_for_release(struct cgroup *cgrp); - -/* Link structure for associating css_set objects with cgroups */ -struct cg_cgroup_link { - /* - * List running through cg_cgroup_links associated with a - * cgroup, anchored on cgroup->css_sets - */ - struct list_head cgrp_link_list; - /* - * List running through cg_cgroup_links pointing at a - * single css_set object, anchored on css_set->cg_links - */ - struct list_head cg_link_list; - struct css_set *cg; -}; - -/* The default css_set - used by init and its children prior to any - * hierarchies being mounted. It contains a pointer to the root state - * for each subsystem. Also used to anchor the list of css_sets. Not - * reference-counted, to improve performance when child cgroups - * haven't been created. - */ - -static struct css_set init_css_set; -static struct cg_cgroup_link init_css_set_link; - -/* css_set_lock protects the list of css_set objects, and the - * chain of tasks off each css_set. Nests outside task->alloc_lock - * due to cgroup_iter_start() */ -static DEFINE_RWLOCK(css_set_lock); -static int css_set_count; - -/* We don't maintain the lists running through each css_set to its - * task until after the first call to cgroup_iter_start(). This - * reduces the fork()/exit() overhead for people who have cgroups - * compiled into their kernel but not actually in use */ -static int use_task_css_set_links; - -/* When we create or destroy a css_set, the operation simply - * takes/releases a reference count on all the cgroups referenced - * by subsystems in this css_set. This can end up multiple-counting - * some cgroups, but that's OK - the ref-count is just a - * busy/not-busy indicator; ensuring that we only count each cgroup - * once would require taking a global lock to ensure that no - * subsystems moved between hierarchies while we were doing so. - * - * Possible TODO: decide at boot time based on the number of - * registered subsystems and the number of CPUs or NUMA nodes whether - * it's better for performance to ref-count every subsystem, or to - * take a global lock and only add one ref count to each hierarchy. - */ - -/* - * unlink a css_set from the list and free it - */ -static void unlink_css_set(struct css_set *cg) -{ - write_lock(&css_set_lock); - list_del(&cg->list); - css_set_count--; - while (!list_empty(&cg->cg_links)) { - struct cg_cgroup_link *link; - link = list_entry(cg->cg_links.next, - struct cg_cgroup_link, cg_link_list); - list_del(&link->cg_link_list); - list_del(&link->cgrp_link_list); - kfree(link); - } - write_unlock(&css_set_lock); -} - -static void __release_css_set(struct kref *k, int taskexit) -{ - int i; - struct css_set *cg = container_of(k, struct css_set, ref); - - unlink_css_set(cg); - - rcu_read_lock(); - for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) { - struct cgroup *cgrp = cg->subsys[i]->cgroup; - if (atomic_dec_and_test(&cgrp->count) && - notify_on_release(cgrp)) { - if (taskexit) - set_bit(CGRP_RELEASABLE, &cgrp->flags); - check_for_release(cgrp); - } - } - rcu_read_unlock(); - kfree(cg); -} - -static void release_css_set(struct kref *k) -{ - __release_css_set(k, 0); -} - -static void release_css_set_taskexit(struct kref *k) -{ - __release_css_set(k, 1); -} - -/* - * refcounted get/put for css_set objects - */ -static inline void get_css_set(struct css_set *cg) -{ - kref_get(&cg->ref); -} - -static inline void put_css_set(struct css_set *cg) -{ - kref_put(&cg->ref, release_css_set); -} - -static inline void put_css_set_taskexit(struct css_set *cg) -{ - kref_put(&cg->ref, release_css_set_taskexit); -} - -/* - * find_existing_css_set() is a helper for - * find_css_set(), and checks to see whether an existing - * css_set is suitable. This currently walks a linked-list for - * simplicity; a later patch will use a hash table for better - * performance - * - * oldcg: the cgroup group that we're using before the cgroup - * transition - * - * cgrp: the cgroup that we're moving into - * - * template: location in which to build the desired set of subsystem - * state objects for the new cgroup group - */ - -static struct css_set *find_existing_css_set( - struct css_set *oldcg, - struct cgroup *cgrp, - struct cgroup_subsys_state *template[]) -{ - int i; - struct cgroupfs_root *root = cgrp->root; - struct list_head *l = &init_css_set.list; - - /* Built the set of subsystem state objects that we want to - * see in the new css_set */ - for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) { - if (root->subsys_bits & (1ull << i)) { - /* Subsystem is in this hierarchy. So we want - * the subsystem state from the new - * cgroup */ - template[i] = cgrp->subsys[i]; - } else { - /* Subsystem is not in this hierarchy, so we - * don't want to change the subsystem state */ - template[i] = oldcg->subsys[i]; - } - } - - /* Look through existing cgroup groups to find one to reuse */ - do { - struct css_set *cg = - list_entry(l, struct css_set, list); - - if (!memcmp(template, cg->subsys, sizeof(cg->subsys))) { - /* All subsystems matched */ - return cg; - } - /* Try the next cgroup group */ - l = l->next; - } while (l != &init_css_set.list); - - /* No existing cgroup group matched */ - return NULL; -} - -/* - * allocate_cg_links() allocates "count" cg_cgroup_link structures - * and chains them on tmp through their cgrp_link_list fields. Returns 0 on - * success or a negative error - */ - -static int allocate_cg_links(int count, struct list_head *tmp) -{ - struct cg_cgroup_link *link; - int i; - INIT_LIST_HEAD(tmp); - for (i = 0; i < count; i++) { - link = kmalloc(sizeof(*link), GFP_KERNEL); - if (!link) { - while (!list_empty(tmp)) { - link = list_entry(tmp->next, - struct cg_cgroup_link, - cgrp_link_list); - list_del(&link->cgrp_link_list); - kfree(link); - } - return -ENOMEM; - } - list_add(&link->cgrp_link_list, tmp); - } - return 0; -} - -static void free_cg_links(struct list_head *tmp) -{ - while (!list_empty(tmp)) { - struct cg_cgroup_link *link; - link = list_entry(tmp->next, - struct cg_cgroup_link, - cgrp_link_list); - list_del(&link->cgrp_link_list); - kfree(link); - } -} - -/* - * find_css_set() takes an existing cgroup group and a - * cgroup object, and returns a css_set object that's - * equivalent to the old group, but with the given cgroup - * substituted into the appropriate hierarchy. Must be called with - * cgroup_mutex held - */ - -static struct css_set *find_css_set( - struct css_set *oldcg, struct cgroup *cgrp) -{ - struct css_set *res; - struct cgroup_subsys_state *template[CGROUP_SUBSYS_COUNT]; - int i; - - struct list_head tmp_cg_links; - struct cg_cgroup_link *link; - - /* First see if we already have a cgroup group that matches - * the desired set */ - write_lock(&css_set_lock); - res = find_existing_css_set(oldcg, cgrp, template); - if (res) - get_css_set(res); - write_unlock(&css_set_lock); - - if (res) - return res; - - res = kmalloc(sizeof(*res), GFP_KERNEL); - if (!res) - return NULL; - - /* Allocate all the cg_cgroup_link objects that we'll need */ - if (allocate_cg_links(root_count, &tmp_cg_links) < 0) { - kfree(res); - return NULL; - } - - kref_init(&res->ref); - INIT_LIST_HEAD(&res->cg_links); - INIT_LIST_HEAD(&res->tasks); - - /* Copy the set of subsystem state objects generated in - * find_existing_css_set() */ - memcpy(res->subsys, template, sizeof(res->subsys)); - - write_lock(&css_set_lock); - /* Add reference counts and links from the new css_set. */ - for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) { - struct cgroup *cgrp = res->subsys[i]->cgroup; - struct cgroup_subsys *ss = subsys[i]; - atomic_inc(&cgrp->count); - /* - * We want to add a link once per cgroup, so we - * only do it for the first subsystem in each - * hierarchy - */ - if (ss->root->subsys_list.next == &ss->sibling) { - BUG_ON(list_empty(&tmp_cg_links)); - link = list_entry(tmp_cg_links.next, - struct cg_cgroup_link, - cgrp_link_list); - list_del(&link->cgrp_link_list); - list_add(&link->cgrp_link_list, &cgrp->css_sets); - link->cg = res; - list_add(&link->cg_link_list, &res->cg_links); - } - } - if (list_empty(&rootnode.subsys_list)) { - link = list_entry(tmp_cg_links.next, - struct cg_cgroup_link, - cgrp_link_list); - list_del(&link->cgrp_link_list); - list_add(&link->cgrp_link_list, &dummytop->css_sets); - link->cg = res; - list_add(&link->cg_link_list, &res->cg_links); - } - - BUG_ON(!list_empty(&tmp_cg_links)); - - /* Link this cgroup group into the list */ - list_add(&res->list, &init_css_set.list); - css_set_count++; - INIT_LIST_HEAD(&res->tasks); - write_unlock(&css_set_lock); - - return res; -} - -/* - * There is one global cgroup mutex. We also require taking - * task_lock() when dereferencing a task's cgroup subsys pointers. - * See "The task_lock() exception", at the end of this comment. - * - * A task must hold cgroup_mutex to modify cgroups. - * - * Any task can increment and decrement the count field without lock. - * So in general, code holding cgroup_mutex can't rely on the count - * field not changing. However, if the count goes to zero, then only - * attach_task() can increment it again. Because a count of zero - * means that no tasks are currently attached, therefore there is no - * way a task attached to that cgroup can fork (the other way to - * increment the count). So code holding cgroup_mutex can safely - * assume that if the count is zero, it will stay zero. Similarly, if - * a task holds cgroup_mutex on a cgroup with zero count, it - * knows that the cgroup won't be removed, as cgroup_rmdir() - * needs that mutex. - * - * The cgroup_common_file_write handler for operations that modify - * the cgroup hierarchy holds cgroup_mutex across the entire operation, - * single threading all such cgroup modifications across the system. - * - * The fork and exit callbacks cgroup_fork() and cgroup_exit(), don't - * (usually) take cgroup_mutex. These are the two most performance - * critical pieces of code here. The exception occurs on cgroup_exit(), - * when a task in a notify_on_release cgroup exits. Then cgroup_mutex - * is taken, and if the cgroup count is zero, a usermode call made - * to /sbin/cgroup_release_agent with the name of the cgroup (path - * relative to the root of cgroup file system) as the argument. - * - * A cgroup can only be deleted if both its 'count' of using tasks - * is zero, and its list of 'children' cgroups is empty. Since all - * tasks in the system use _some_ cgroup, and since there is always at - * least one task in the system (init, pid == 1), therefore, top_cgroup - * always has either children cgroups and/or using tasks. So we don't - * need a special hack to ensure that top_cgroup cannot be deleted. - * - * The task_lock() exception - * - * The need for this exception arises from the action of - * attach_task(), which overwrites one tasks cgroup pointer with - * another. It does so using cgroup_mutexe, however there are - * several performance critical places that need to reference - * task->cgroup without the expense of grabbing a system global - * mutex. Therefore except as noted below, when dereferencing or, as - * in attach_task(), modifying a task'ss cgroup pointer we use - * task_lock(), which acts on a spinlock (task->alloc_lock) already in - * the task_struct routinely used for such matters. - * - * P.S. One more locking exception. RCU is used to guard the - * update of a tasks cgroup pointer by attach_task() - */ - -/** - * cgroup_lock - lock out any changes to cgroup structures - * - */ - -void cgroup_lock(void) -{ - mutex_lock(&cgroup_mutex); -} - -/** - * cgroup_unlock - release lock on cgroup changes - * - * Undo the lock taken in a previous cgroup_lock() call. - */ - -void cgroup_unlock(void) -{ - mutex_unlock(&cgroup_mutex); -} - -/* - * A couple of forward declarations required, due to cyclic reference loop: - * cgroup_mkdir -> cgroup_create -> cgroup_populate_dir -> - * cgroup_add_file -> cgroup_create_file -> cgroup_dir_inode_operations - * -> cgroup_mkdir. - */ - -static int cgroup_mkdir(struct inode *dir, struct dentry *dentry, int mode); -static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry); -static int cgroup_populate_dir(struct cgroup *cgrp); -static struct inode_operations cgroup_dir_inode_operations; -static struct file_operations proc_cgroupstats_operations; - -static struct backing_dev_info cgroup_backing_dev_info = { - .capabilities = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK, -}; - -static struct inode *cgroup_new_inode(mode_t mode, struct super_block *sb) -{ - struct inode *inode = new_inode(sb); - - if (inode) { - inode->i_mode = mode; - inode->i_uid = current->fsuid; - inode->i_gid = current->fsgid; - inode->i_blocks = 0; - inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; - inode->i_mapping->backing_dev_info = &cgroup_backing_dev_info; - } - return inode; -} - -static void cgroup_diput(struct dentry *dentry, struct inode *inode) -{ - /* is dentry a directory ? if so, kfree() associated cgroup */ - if (S_ISDIR(inode->i_mode)) { - struct cgroup *cgrp = dentry->d_fsdata; - BUG_ON(!(cgroup_is_removed(cgrp))); - /* It's possible for external users to be holding css - * reference counts on a cgroup; css_put() needs to - * be able to access the cgroup after decrementing - * the reference count in order to know if it needs to - * queue the cgroup to be handled by the release - * agent */ - synchronize_rcu(); - kfree(cgrp); - } - iput(inode); -} - -static void remove_dir(struct dentry *d) -{ - struct dentry *parent = dget(d->d_parent); - - d_delete(d); - simple_rmdir(parent->d_inode, d); - dput(parent); -} - -static void cgroup_clear_directory(struct dentry *dentry) -{ - struct list_head *node; - - BUG_ON(!mutex_is_locked(&dentry->d_inode->i_mutex)); - spin_lock(&dcache_lock); - node = dentry->d_subdirs.next; - while (node != &dentry->d_subdirs) { - struct dentry *d = list_entry(node, struct dentry, d_u.d_child); - list_del_init(node); - if (d->d_inode) { - /* This should never be called on a cgroup - * directory with child cgroups */ - BUG_ON(d->d_inode->i_mode & S_IFDIR); - d = dget_locked(d); - spin_unlock(&dcache_lock); - d_delete(d); - simple_unlink(dentry->d_inode, d); - dput(d); - spin_lock(&dcache_lock); - } - node = dentry->d_subdirs.next; - } - spin_unlock(&dcache_lock); -} - -/* - * NOTE : the dentry must have been dget()'ed - */ -static void cgroup_d_remove_dir(struct dentry *dentry) -{ - cgroup_clear_directory(dentry); - - spin_lock(&dcache_lock); - list_del_init(&dentry->d_u.d_child); - spin_unlock(&dcache_lock); - remove_dir(dentry); -} - -static int rebind_subsystems(struct cgroupfs_root *root, - unsigned long final_bits) -{ - unsigned long added_bits, removed_bits; - struct cgroup *cgrp = &root->top_cgroup; - int i; - - removed_bits = root->actual_subsys_bits & ~final_bits; - added_bits = final_bits & ~root->actual_subsys_bits; - /* Check that any added subsystems are currently free */ - for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) { - unsigned long long bit = 1ull << i; - struct cgroup_subsys *ss = subsys[i]; - if (!(bit & added_bits)) - continue; - if (ss->root != &rootnode) { - /* Subsystem isn't free */ - return -EBUSY; - } - } - - /* Currently we don't handle adding/removing subsystems when - * any child cgroups exist. This is theoretically supportable - * but involves complex error handling, so it's being left until - * later */ - if (!list_empty(&cgrp->children)) - return -EBUSY; - - /* Process each subsystem */ - for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) { - struct cgroup_subsys *ss = subsys[i]; - unsigned long bit = 1UL << i; - if (bit & added_bits) { - /* We're binding this subsystem to this hierarchy */ - BUG_ON(cgrp->subsys[i]); - BUG_ON(!dummytop->subsys[i]); - BUG_ON(dummytop->subsys[i]->cgroup != dummytop); - cgrp->subsys[i] = dummytop->subsys[i]; - cgrp->subsys[i]->cgroup = cgrp; - list_add(&ss->sibling, &root->subsys_list); - rcu_assign_pointer(ss->root, root); - if (ss->bind) - ss->bind(ss, cgrp); - - } else if (bit & removed_bits) { - /* We're removing this subsystem */ - BUG_ON(cgrp->subsys[i] != dummytop->subsys[i]); - BUG_ON(cgrp->subsys[i]->cgroup != cgrp); - if (ss->bind) - ss->bind(ss, dummytop); - dummytop->subsys[i]->cgroup = dummytop; - cgrp->subsys[i] = NULL; - rcu_assign_pointer(subsys[i]->root, &rootnode); - list_del(&ss->sibling); - } else if (bit & final_bits) { - /* Subsystem state should already exist */ - BUG_ON(!cgrp->subsys[i]); - } else { - /* Subsystem state shouldn't exist */ - BUG_ON(cgrp->subsys[i]); - } - } - root->subsys_bits = root->actual_subsys_bits = final_bits; - synchronize_rcu(); - - return 0; -} - -static int cgroup_show_options(struct seq_file *seq, struct vfsmount *vfs) -{ - struct cgroupfs_root *root = vfs->mnt_sb->s_fs_info; - struct cgroup_subsys *ss; - - mutex_lock(&cgroup_mutex); - for_each_subsys(root, ss) - seq_printf(seq, ",%s", ss->name); - if (test_bit(ROOT_NOPREFIX, &root->flags)) - seq_puts(seq, ",noprefix"); - if (strlen(root->release_agent_path)) - seq_printf(seq, ",release_agent=%s", root->release_agent_path); - mutex_unlock(&cgroup_mutex); - return 0; -} - -struct cgroup_sb_opts { - unsigned long subsys_bits; - unsigned long flags; - char *release_agent; -}; - -/* Convert a hierarchy specifier into a bitmask of subsystems and - * flags. */ -static int parse_cgroupfs_options(char *data, - struct cgroup_sb_opts *opts) -{ - char *token, *o = data ?: "all"; - - opts->subsys_bits = 0; - opts->flags = 0; - opts->release_agent = NULL; - - while ((token = strsep(&o, ",")) != NULL) { - if (!*token) - return -EINVAL; - if (!strcmp(token, "all")) { - opts->subsys_bits = (1 << CGROUP_SUBSYS_COUNT) - 1; - } else if (!strcmp(token, "noprefix")) { - set_bit(ROOT_NOPREFIX, &opts->flags); - } else if (!strncmp(token, "release_agent=", 14)) { - /* Specifying two release agents is forbidden */ - if (opts->release_agent) - return -EINVAL; - opts->release_agent = kzalloc(PATH_MAX, GFP_KERNEL); - if (!opts->release_agent) - return -ENOMEM; - strncpy(opts->release_agent, token + 14, PATH_MAX - 1); - opts->release_agent[PATH_MAX - 1] = 0; - } else { - struct cgroup_subsys *ss; - int i; - for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) { - ss = subsys[i]; - if (!strcmp(token, ss->name)) { - set_bit(i, &opts->subsys_bits); - break; - } - } - if (i == CGROUP_SUBSYS_COUNT) - return -ENOENT; - } - } - - /* We can't have an empty hierarchy */ - if (!opts->subsys_bits) - return -EINVAL; - - return 0; -} - -static int cgroup_remount(struct super_block *sb, int *flags, char *data) -{ - int ret = 0; - struct cgroupfs_root *root = sb->s_fs_info; - struct cgroup *cgrp = &root->top_cgroup; - struct cgroup_sb_opts opts; - - mutex_lock(&cgrp->dentry->d_inode->i_mutex); - mutex_lock(&cgroup_mutex); - - /* See what subsystems are wanted */ - ret = parse_cgroupfs_options(data, &opts); - if (ret) - goto out_unlock; - - /* Don't allow flags to change at remount */ - if (opts.flags != root->flags) { - ret = -EINVAL; - goto out_unlock; - } - - ret = rebind_subsystems(root, opts.subsys_bits); - - /* (re)populate subsystem files */ - if (!ret) - cgroup_populate_dir(cgrp); - - if (opts.release_agent) - strcpy(root->release_agent_path, opts.release_agent); - out_unlock: - if (opts.release_agent) - kfree(opts.release_agent); - mutex_unlock(&cgroup_mutex); - mutex_unlock(&cgrp->dentry->d_inode->i_mutex); - return ret; -} - -static struct super_operations cgroup_ops = { - .statfs = simple_statfs, - .drop_inode = generic_delete_inode, - .show_options = cgroup_show_options, - .remount_fs = cgroup_remount, -}; - -static void init_cgroup_root(struct cgroupfs_root *root) -{ - struct cgroup *cgrp = &root->top_cgroup; - INIT_LIST_HEAD(&root->subsys_list); - INIT_LIST_HEAD(&root->root_list); - root->number_of_cgroups = 1; - cgrp->root = root; - cgrp->top_cgroup = cgrp; - INIT_LIST_HEAD(&cgrp->sibling); - INIT_LIST_HEAD(&cgrp->children); - INIT_LIST_HEAD(&cgrp->css_sets); - INIT_LIST_HEAD(&cgrp->release_list); -} - -static int cgroup_test_super(struct super_block *sb, void *data) -{ - struct cgroupfs_root *new = data; - struct cgroupfs_root *root = sb->s_fs_info; - - /* First check subsystems */ - if (new->subsys_bits != root->subsys_bits) - return 0; - - /* Next check flags */ - if (new->flags != root->flags) - return 0; - - return 1; -} - -static int cgroup_set_super(struct super_block *sb, void *data) -{ - int ret; - struct cgroupfs_root *root = data; - - ret = set_anon_super(sb, NULL); - if (ret) - return ret; - - sb->s_fs_info = root; - root->sb = sb; - - sb->s_blocksize = PAGE_CACHE_SIZE; - sb->s_blocksize_bits = PAGE_CACHE_SHIFT; - sb->s_magic = CGROUP_SUPER_MAGIC; - sb->s_op = &cgroup_ops; - - return 0; -} - -static int cgroup_get_rootdir(struct super_block *sb) -{ - struct inode *inode = - cgroup_new_inode(S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR, sb); - struct dentry *dentry; - - if (!inode) - return -ENOMEM; - - inode->i_op = &simple_dir_inode_operations; - inode->i_fop = &simple_dir_operations; - inode->i_op = &cgroup_dir_inode_operations; - /* directories start off with i_nlink == 2 (for "." entry) */ - inc_nlink(inode); - dentry = d_alloc_root(inode); - if (!dentry) { - iput(inode); - return -ENOMEM; - } - sb->s_root = dentry; - return 0; -} - -static int cgroup_get_sb(struct file_system_type *fs_type, - int flags, const char *unused_dev_name, - void *data, struct vfsmount *mnt) -{ - struct cgroup_sb_opts opts; - int ret = 0; - struct super_block *sb; - struct cgroupfs_root *root; - struct list_head tmp_cg_links, *l; - INIT_LIST_HEAD(&tmp_cg_links); - - /* First find the desired set of subsystems */ - ret = parse_cgroupfs_options(data, &opts); - if (ret) { - if (opts.release_agent) - kfree(opts.release_agent); - return ret; - } - - root = kzalloc(sizeof(*root), GFP_KERNEL); - if (!root) - return -ENOMEM; - - init_cgroup_root(root); - root->subsys_bits = opts.subsys_bits; - root->flags = opts.flags; - if (opts.release_agent) { - strcpy(root->release_agent_path, opts.release_agent); - kfree(opts.release_agent); - } - - sb = sget(fs_type, cgroup_test_super, cgroup_set_super, root); - - if (IS_ERR(sb)) { - kfree(root); - return PTR_ERR(sb); - } - - if (sb->s_fs_info != root) { - /* Reusing an existing superblock */ - BUG_ON(sb->s_root == NULL); - kfree(root); - root = NULL; - } else { - /* New superblock */ - struct cgroup *cgrp = &root->top_cgroup; - struct inode *inode; - - BUG_ON(sb->s_root != NULL); - - ret = cgroup_get_rootdir(sb); - if (ret) - goto drop_new_super; - inode = sb->s_root->d_inode; - - mutex_lock(&inode->i_mutex); - mutex_lock(&cgroup_mutex); - - /* - * We're accessing css_set_count without locking - * css_set_lock here, but that's OK - it can only be - * increased by someone holding cgroup_lock, and - * that's us. The worst that can happen is that we - * have some link structures left over - */ - ret = allocate_cg_links(css_set_count, &tmp_cg_links); - if (ret) { - mutex_unlock(&cgroup_mutex); - mutex_unlock(&inode->i_mutex); - goto drop_new_super; - } - - ret = rebind_subsystems(root, root->subsys_bits); - if (ret == -EBUSY) { - mutex_unlock(&cgroup_mutex); - mutex_unlock(&inode->i_mutex); - goto drop_new_super; - } - - /* EBUSY should be the only error here */ - BUG_ON(ret); - - list_add(&root->root_list, &roots); - root_count++; - - sb->s_root->d_fsdata = &root->top_cgroup; - root->top_cgroup.dentry = sb->s_root; - - /* Link the top cgroup in this hierarchy into all - * the css_set objects */ - write_lock(&css_set_lock); - l = &init_css_set.list; - do { - struct css_set *cg; - struct cg_cgroup_link *link; - cg = list_entry(l, struct css_set, list); - BUG_ON(list_empty(&tmp_cg_links)); - link = list_entry(tmp_cg_links.next, - struct cg_cgroup_link, - cgrp_link_list); - list_del(&link->cgrp_link_list); - link->cg = cg; - list_add(&link->cgrp_link_list, - &root->top_cgroup.css_sets); - list_add(&link->cg_link_list, &cg->cg_links); - l = l->next; - } while (l != &init_css_set.list); - write_unlock(&css_set_lock); - - free_cg_links(&tmp_cg_links); - - BUG_ON(!list_empty(&cgrp->sibling)); - BUG_ON(!list_empty(&cgrp->children)); - BUG_ON(root->number_of_cgroups != 1); - - cgroup_populate_dir(cgrp); - mutex_unlock(&inode->i_mutex); - mutex_unlock(&cgroup_mutex); - } - - return simple_set_mnt(mnt, sb); - - drop_new_super: - up_write(&sb->s_umount); - deactivate_super(sb); - free_cg_links(&tmp_cg_links); - return ret; -} - -static void cgroup_kill_sb(struct super_block *sb) { - struct cgroupfs_root *root = sb->s_fs_info; - struct cgroup *cgrp = &root->top_cgroup; - int ret; - - BUG_ON(!root); - - BUG_ON(root->number_of_cgroups != 1); - BUG_ON(!list_empty(&cgrp->children)); - BUG_ON(!list_empty(&cgrp->sibling)); - - mutex_lock(&cgroup_mutex); - - /* Rebind all subsystems back to the default hierarchy */ - ret = rebind_subsystems(root, 0); - /* Shouldn't be able to fail ... */ - BUG_ON(ret); - - /* - * Release all the links from css_sets to this hierarchy's - * root cgroup - */ - write_lock(&css_set_lock); - while (!list_empty(&cgrp->css_sets)) { - struct cg_cgroup_link *link; - link = list_entry(cgrp->css_sets.next, - struct cg_cgroup_link, cgrp_link_list); - list_del(&link->cg_link_list); - list_del(&link->cgrp_link_list); - kfree(link); - } - write_unlock(&css_set_lock); - - if (!list_empty(&root->root_list)) { - list_del(&root->root_list); - root_count--; - } - mutex_unlock(&cgroup_mutex); - - kfree(root); - kill_litter_super(sb); -} - -static struct file_system_type cgroup_fs_type = { - .name = "cgroup", - .get_sb = cgroup_get_sb, - .kill_sb = cgroup_kill_sb, -}; - -static inline struct cgroup *__d_cgrp(struct dentry *dentry) -{ - return dentry->d_fsdata; -} - -static inline struct cftype *__d_cft(struct dentry *dentry) -{ - return dentry->d_fsdata; -} - -/* - * Called with cgroup_mutex held. Writes path of cgroup into buf. - * Returns 0 on success, -errno on error. - */ -int cgroup_path(const struct cgroup *cgrp, char *buf, int buflen) -{ - char *start; - - if (cgrp == dummytop) { - /* - * Inactive subsystems have no dentry for their root - * cgroup - */ - strcpy(buf, "/"); - return 0; - } - - start = buf + buflen; - - *--start = '\0'; - for (;;) { - int len = cgrp->dentry->d_name.len; - if ((start -= len) < buf) - return -ENAMETOOLONG; - memcpy(start, cgrp->dentry->d_name.name, len); - cgrp = cgrp->parent; - if (!cgrp) - break; - if (!cgrp->parent) - continue; - if (--start < buf) - return -ENAMETOOLONG; - *start = '/'; - } - memmove(buf, start, buf + buflen - start); - return 0; -} - -/* - * Return the first subsystem attached to a cgroup's hierarchy, and - * its subsystem id. - */ - -static void get_first_subsys(const struct cgroup *cgrp, - struct cgroup_subsys_state **css, int *subsys_id) -{ - const struct cgroupfs_root *root = cgrp->root; - const struct cgroup_subsys *test_ss; - BUG_ON(list_empty(&root->subsys_list)); - test_ss = list_entry(root->subsys_list.next, - struct cgroup_subsys, sibling); - if (css) { - *css = cgrp->subsys[test_ss->subsys_id]; - BUG_ON(!*css); - } - if (subsys_id) - *subsys_id = test_ss->subsys_id; -} - -/* - * Attach task 'tsk' to cgroup 'cgrp' - * - * Call holding cgroup_mutex. May take task_lock of - * the task 'pid' during call. - */ -static int attach_task(struct cgroup *cgrp, struct task_struct *tsk) -{ - int retval = 0; - struct cgroup_subsys *ss; - struct cgroup *oldcgrp; - struct css_set *cg = tsk->cgroups; - struct css_set *newcg; - struct cgroupfs_root *root = cgrp->root; - int subsys_id; - - get_first_subsys(cgrp, NULL, &subsys_id); - - /* Nothing to do if the task is already in that cgroup */ - oldcgrp = task_cgroup(tsk, subsys_id); - if (cgrp == oldcgrp) - return 0; - - for_each_subsys(root, ss) { - if (ss->can_attach) { - retval = ss->can_attach(ss, cgrp, tsk); - if (retval) { - return retval; - } - } - } - - /* - * Locate or allocate a new css_set for this task, - * based on its final set of cgroups - */ - newcg = find_css_set(cg, cgrp); - if (!newcg) { - return -ENOMEM; - } - - task_lock(tsk); - if (tsk->flags & PF_EXITING) { - task_unlock(tsk); - put_css_set(newcg); - return -ESRCH; - } - rcu_assign_pointer(tsk->cgroups, newcg); - task_unlock(tsk); - - /* Update the css_set linked lists if we're using them */ - write_lock(&css_set_lock); - if (!list_empty(&tsk->cg_list)) { - list_del(&tsk->cg_list); - list_add(&tsk->cg_list, &newcg->tasks); - } - write_unlock(&css_set_lock); - - for_each_subsys(root, ss) { - if (ss->attach) { - ss->attach(ss, cgrp, oldcgrp, tsk); - } - } - set_bit(CGRP_RELEASABLE, &oldcgrp->flags); - synchronize_rcu(); - put_css_set(cg); - return 0; -} - -/* - * Attach task with pid 'pid' to cgroup 'cgrp'. Call with - * cgroup_mutex, may take task_lock of task - */ -static int attach_task_by_pid(struct cgroup *cgrp, char *pidbuf) -{ - pid_t pid; - struct task_struct *tsk; - int ret; - - if (sscanf(pidbuf, "%d", &pid) != 1) - return -EIO; - - if (pid) { - rcu_read_lock(); - tsk = find_task_by_pid(pid); - if (!tsk || tsk->flags & PF_EXITING) { - rcu_read_unlock(); - return -ESRCH; - } - get_task_struct(tsk); - rcu_read_unlock(); - - if ((current->euid) && (current->euid != tsk->uid) - && (current->euid != tsk->suid)) { - put_task_struct(tsk); - return -EACCES; - } - } else { - tsk = current; - get_task_struct(tsk); - } - - ret = attach_task(cgrp, tsk); - put_task_struct(tsk); - return ret; -} - -/* The various types of files and directories in a cgroup file system */ - -enum cgroup_filetype { - FILE_ROOT, - FILE_DIR, - FILE_TASKLIST, - FILE_NOTIFY_ON_RELEASE, - FILE_RELEASABLE, - FILE_RELEASE_AGENT, -}; - -static ssize_t cgroup_write_uint(struct cgroup *cgrp, struct cftype *cft, - struct file *file, - const char __user *userbuf, - size_t nbytes, loff_t *unused_ppos) -{ - char buffer[64]; - int retval = 0; - u64 val; - char *end; - - if (!nbytes) - return -EINVAL; - if (nbytes >= sizeof(buffer)) - return -E2BIG; - if (copy_from_user(buffer, userbuf, nbytes)) - return -EFAULT; - - buffer[nbytes] = 0; /* nul-terminate */ - - /* strip newline if necessary */ - if (nbytes && (buffer[nbytes-1] == '\n')) - buffer[nbytes-1] = 0; - val = simple_strtoull(buffer, &end, 0); - if (*end) - return -EINVAL; - - /* Pass to subsystem */ - retval = cft->write_uint(cgrp, cft, val); - if (!retval) - retval = nbytes; - return retval; -} - -static ssize_t cgroup_common_file_write(struct cgroup *cgrp, - struct cftype *cft, - struct file *file, - const char __user *userbuf, - size_t nbytes, loff_t *unused_ppos) -{ - enum cgroup_filetype type = cft->private; - char *buffer; - int retval = 0; - - if (nbytes >= PATH_MAX) - return -E2BIG; - - /* +1 for nul-terminator */ - buffer = kmalloc(nbytes + 1, GFP_KERNEL); - if (buffer == NULL) - return -ENOMEM; - - if (copy_from_user(buffer, userbuf, nbytes)) { - retval = -EFAULT; - goto out1; - } - buffer[nbytes] = 0; /* nul-terminate */ - - mutex_lock(&cgroup_mutex); - - if (cgroup_is_removed(cgrp)) { - retval = -ENODEV; - goto out2; - } - - switch (type) { - case FILE_TASKLIST: - retval = attach_task_by_pid(cgrp, buffer); - break; - case FILE_NOTIFY_ON_RELEASE: - clear_bit(CGRP_RELEASABLE, &cgrp->flags); - if (simple_strtoul(buffer, NULL, 10) != 0) - set_bit(CGRP_NOTIFY_ON_RELEASE, &cgrp->flags); - else - clear_bit(CGRP_NOTIFY_ON_RELEASE, &cgrp->flags); - break; - case FILE_RELEASE_AGENT: - { - struct cgroupfs_root *root = cgrp->root; - /* Strip trailing newline */ - if (nbytes && (buffer[nbytes-1] == '\n')) { - buffer[nbytes-1] = 0; - } - if (nbytes < sizeof(root->release_agent_path)) { - /* We never write anything other than '\0' - * into the last char of release_agent_path, - * so it always remains a NUL-terminated - * string */ - strncpy(root->release_agent_path, buffer, nbytes); - root->release_agent_path[nbytes] = 0; - } else { - retval = -ENOSPC; - } - break; - } - default: - retval = -EINVAL; - goto out2; - } - - if (retval == 0) - retval = nbytes; -out2: - mutex_unlock(&cgroup_mutex); -out1: - kfree(buffer); - return retval; -} - -static ssize_t cgroup_file_write(struct file *file, const char __user *buf, - size_t nbytes, loff_t *ppos) -{ - struct cftype *cft = __d_cft(file->f_dentry); - struct cgroup *cgrp = __d_cgrp(file->f_dentry->d_parent); - - if (!cft) - return -ENODEV; - if (cft->write) - return cft->write(cgrp, cft, file, buf, nbytes, ppos); - if (cft->write_uint) - return cgroup_write_uint(cgrp, cft, file, buf, nbytes, ppos); - return -EINVAL; -} - -static ssize_t cgroup_read_uint(struct cgroup *cgrp, struct cftype *cft, - struct file *file, - char __user *buf, size_t nbytes, - loff_t *ppos) -{ - char tmp[64]; - u64 val = cft->read_uint(cgrp, cft); - int len = sprintf(tmp, "%llu\n", (unsigned long long) val); - - return simple_read_from_buffer(buf, nbytes, ppos, tmp, len); -} - -static ssize_t cgroup_common_file_read(struct cgroup *cgrp, - struct cftype *cft, - struct file *file, - char __user *buf, - size_t nbytes, loff_t *ppos) -{ - enum cgroup_filetype type = cft->private; - char *page; - ssize_t retval = 0; - char *s; - - if (!(page = (char *)__get_free_page(GFP_KERNEL))) - return -ENOMEM; - - s = page; - - switch (type) { - case FILE_RELEASE_AGENT: - { - struct cgroupfs_root *root; - size_t n; - mutex_lock(&cgroup_mutex); - root = cgrp->root; - n = strnlen(root->release_agent_path, - sizeof(root->release_agent_path)); - n = min(n, (size_t) PAGE_SIZE); - strncpy(s, root->release_agent_path, n); - mutex_unlock(&cgroup_mutex); - s += n; - break; - } - default: - retval = -EINVAL; - goto out; - } - *s++ = '\n'; - - retval = simple_read_from_buffer(buf, nbytes, ppos, page, s - page); -out: - free_page((unsigned long)page); - return retval; -} - -static ssize_t cgroup_file_read(struct file *file, char __user *buf, - size_t nbytes, loff_t *ppos) -{ - struct cftype *cft = __d_cft(file->f_dentry); - struct cgroup *cgrp = __d_cgrp(file->f_dentry->d_parent); - - if (!cft) - return -ENODEV; - - if (cft->read) - return cft->read(cgrp, cft, file, buf, nbytes, ppos); - if (cft->read_uint) - return cgroup_read_uint(cgrp, cft, file, buf, nbytes, ppos); - return -EINVAL; -} - -static int cgroup_file_open(struct inode *inode, struct file *file) -{ - int err; - struct cftype *cft; - - err = generic_file_open(inode, file); - if (err) - return err; - - cft = __d_cft(file->f_dentry); - if (!cft) - return -ENODEV; - if (cft->open) - err = cft->open(inode, file); - else - err = 0; - - return err; -} - -static int cgroup_file_release(struct inode *inode, struct file *file) -{ - struct cftype *cft = __d_cft(file->f_dentry); - if (cft->release) - return cft->release(inode, file); - return 0; -} - -/* - * cgroup_rename - Only allow simple rename of directories in place. - */ -static int cgroup_rename(struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry) -{ - if (!S_ISDIR(old_dentry->d_inode->i_mode)) - return -ENOTDIR; - if (new_dentry->d_inode) - return -EEXIST; - if (old_dir != new_dir) - return -EIO; - return simple_rename(old_dir, old_dentry, new_dir, new_dentry); -} - -static struct file_operations cgroup_file_operations = { - .read = cgroup_file_read, - .write = cgroup_file_write, - .llseek = generic_file_llseek, - .open = cgroup_file_open, - .release = cgroup_file_release, -}; - -static struct inode_operations cgroup_dir_inode_operations = { - .lookup = simple_lookup, - .mkdir = cgroup_mkdir, - .rmdir = cgroup_rmdir, - .rename = cgroup_rename, -}; - -static int cgroup_create_file(struct dentry *dentry, int mode, - struct super_block *sb) -{ - static struct dentry_operations cgroup_dops = { - .d_iput = cgroup_diput, - }; - - struct inode *inode; - - if (!dentry) - return -ENOENT; - if (dentry->d_inode) - return -EEXIST; - - inode = cgroup_new_inode(mode, sb); - if (!inode) - return -ENOMEM; - - if (S_ISDIR(mode)) { - inode->i_op = &cgroup_dir_inode_operations; - inode->i_fop = &simple_dir_operations; - - /* start off with i_nlink == 2 (for "." entry) */ - inc_nlink(inode); - - /* start with the directory inode held, so that we can - * populate it without racing with another mkdir */ - mutex_lock_nested(&inode->i_mutex, I_MUTEX_CHILD); - } else if (S_ISREG(mode)) { - inode->i_size = 0; - inode->i_fop = &cgroup_file_operations; - } - dentry->d_op = &cgroup_dops; - d_instantiate(dentry, inode); - dget(dentry); /* Extra count - pin the dentry in core */ - return 0; -} - -/* - * cgroup_create_dir - create a directory for an object. - * cgrp: the cgroup we create the directory for. - * It must have a valid ->parent field - * And we are going to fill its ->dentry field. - * dentry: dentry of the new cgroup - * mode: mode to set on new directory. - */ -static int cgroup_create_dir(struct cgroup *cgrp, struct dentry *dentry, - int mode) -{ - struct dentry *parent; - int error = 0; - - parent = cgrp->parent->dentry; - error = cgroup_create_file(dentry, S_IFDIR | mode, cgrp->root->sb); - if (!error) { - dentry->d_fsdata = cgrp; - inc_nlink(parent->d_inode); - cgrp->dentry = dentry; - dget(dentry); - } - dput(dentry); - - return error; -} - -int cgroup_add_file(struct cgroup *cgrp, - struct cgroup_subsys *subsys, - const struct cftype *cft) -{ - struct dentry *dir = cgrp->dentry; - struct dentry *dentry; - int error; - - char name[MAX_CGROUP_TYPE_NAMELEN + MAX_CFTYPE_NAME + 2] = { 0 }; - if (subsys && !test_bit(ROOT_NOPREFIX, &cgrp->root->flags)) { - strcpy(name, subsys->name); - strcat(name, "."); - } - strcat(name, cft->name); - BUG_ON(!mutex_is_locked(&dir->d_inode->i_mutex)); - dentry = lookup_one_len(name, dir, strlen(name)); - if (!IS_ERR(dentry)) { - error = cgroup_create_file(dentry, 0644 | S_IFREG, - cgrp->root->sb); - if (!error) - dentry->d_fsdata = (void *)cft; - dput(dentry); - } else - error = PTR_ERR(dentry); - return error; -} - -int cgroup_add_files(struct cgroup *cgrp, - struct cgroup_subsys *subsys, - const struct cftype cft[], - int count) -{ - int i, err; - for (i = 0; i < count; i++) { - err = cgroup_add_file(cgrp, subsys, &cft[i]); - if (err) - return err; - } - return 0; -} - -/* Count the number of tasks in a cgroup. */ - -int cgroup_task_count(const struct cgroup *cgrp) -{ - int count = 0; - struct list_head *l; - - read_lock(&css_set_lock); - l = cgrp->css_sets.next; - while (l != &cgrp->css_sets) { - struct cg_cgroup_link *link = - list_entry(l, struct cg_cgroup_link, cgrp_link_list); - count += atomic_read(&link->cg->ref.refcount); - l = l->next; - } - read_unlock(&css_set_lock); - return count; -} - -/* - * Advance a list_head iterator. The iterator should be positioned at - * the start of a css_set - */ -static void cgroup_advance_iter(struct cgroup *cgrp, - struct cgroup_iter *it) -{ - struct list_head *l = it->cg_link; - struct cg_cgroup_link *link; - struct css_set *cg; - - /* Advance to the next non-empty css_set */ - do { - l = l->next; - if (l == &cgrp->css_sets) { - it->cg_link = NULL; - return; - } - link = list_entry(l, struct cg_cgroup_link, cgrp_link_list); - cg = link->cg; - } while (list_empty(&cg->tasks)); - it->cg_link = l; - it->task = cg->tasks.next; -} - -void cgroup_iter_start(struct cgroup *cgrp, struct cgroup_iter *it) -{ - /* - * The first time anyone tries to iterate across a cgroup, - * we need to enable the list linking each css_set to its - * tasks, and fix up all existing tasks. - */ - if (!use_task_css_set_links) { - struct task_struct *p, *g; - write_lock(&css_set_lock); - use_task_css_set_links = 1; - do_each_thread(g, p) { - task_lock(p); - if (list_empty(&p->cg_list)) - list_add(&p->cg_list, &p->cgroups->tasks); - task_unlock(p); - } while_each_thread(g, p); - write_unlock(&css_set_lock); - } - read_lock(&css_set_lock); - it->cg_link = &cgrp->css_sets; - cgroup_advance_iter(cgrp, it); -} - -struct task_struct *cgroup_iter_next(struct cgroup *cgrp, - struct cgroup_iter *it) -{ - struct task_struct *res; - struct list_head *l = it->task; - - /* If the iterator cg is NULL, we have no tasks */ - if (!it->cg_link) - return NULL; - res = list_entry(l, struct task_struct, cg_list); - /* Advance iterator to find next entry */ - l = l->next; - if (l == &res->cgroups->tasks) { - /* We reached the end of this task list - move on to - * the next cg_cgroup_link */ - cgroup_advance_iter(cgrp, it); - } else { - it->task = l; - } - return res; -} - -void cgroup_iter_end(struct cgroup *cgrp, struct cgroup_iter *it) -{ - read_unlock(&css_set_lock); -} - -/* - * Stuff for reading the 'tasks' file. - * - * Reading this file can return large amounts of data if a cgroup has - * *lots* of attached tasks. So it may need several calls to read(), - * but we cannot guarantee that the information we produce is correct - * unless we produce it entirely atomically. - * - * Upon tasks file open(), a struct ctr_struct is allocated, that - * will have a pointer to an array (also allocated here). The struct - * ctr_struct * is stored in file->private_data. Its resources will - * be freed by release() when the file is closed. The array is used - * to sprintf the PIDs and then used by read(). - */ -struct ctr_struct { - char *buf; - int bufsz; -}; - -/* - * Load into 'pidarray' up to 'npids' of the tasks using cgroup - * 'cgrp'. Return actual number of pids loaded. No need to - * task_lock(p) when reading out p->cgroup, since we're in an RCU - * read section, so the css_set can't go away, and is - * immutable after creation. - */ -static int pid_array_load(pid_t *pidarray, int npids, struct cgroup *cgrp) -{ - int n = 0; - struct cgroup_iter it; - struct task_struct *tsk; - cgroup_iter_start(cgrp, &it); - while ((tsk = cgroup_iter_next(cgrp, &it))) { - if (unlikely(n == npids)) - break; - pidarray[n++] = task_pid_nr(tsk); - } - cgroup_iter_end(cgrp, &it); - return n; -} - -/** - * Build and fill cgroupstats so that taskstats can export it to user - * space. - * - * @stats: cgroupstats to fill information into - * @dentry: A dentry entry belonging to the cgroup for which stats have - * been requested. - */ -int cgroupstats_build(struct cgroupstats *stats, struct dentry *dentry) -{ - int ret = -EINVAL; - struct cgroup *cgrp; - struct cgroup_iter it; - struct task_struct *tsk; - /* - * Validate dentry by checking the superblock operations - */ - if (dentry->d_sb->s_op != &cgroup_ops) - goto err; - - ret = 0; - cgrp = dentry->d_fsdata; - rcu_read_lock(); - - cgroup_iter_start(cgrp, &it); - while ((tsk = cgroup_iter_next(cgrp, &it))) { - switch (tsk->state) { - case TASK_RUNNING: - stats->nr_running++; - break; - case TASK_INTERRUPTIBLE: - stats->nr_sleeping++; - break; - case TASK_UNINTERRUPTIBLE: - stats->nr_uninterruptible++; - break; - case TASK_STOPPED: - stats->nr_stopped++; - break; - default: - if (delayacct_is_task_waiting_on_io(tsk)) - stats->nr_io_wait++; - break; - } - } - cgroup_iter_end(cgrp, &it); - - rcu_read_unlock(); -err: - return ret; -} - -static int cmppid(const void *a, const void *b) -{ - return *(pid_t *)a - *(pid_t *)b; -} - -/* - * Convert array 'a' of 'npids' pid_t's to a string of newline separated - * decimal pids in 'buf'. Don't write more than 'sz' chars, but return - * count 'cnt' of how many chars would be written if buf were large enough. - */ -static int pid_array_to_buf(char *buf, int sz, pid_t *a, int npids) -{ - int cnt = 0; - int i; - - for (i = 0; i < npids; i++) - cnt += snprintf(buf + cnt, max(sz - cnt, 0), "%d\n", a[i]); - return cnt; -} - -/* - * Handle an open on 'tasks' file. Prepare a buffer listing the - * process id's of tasks currently attached to the cgroup being opened. - * - * Does not require any specific cgroup mutexes, and does not take any. - */ -static int cgroup_tasks_open(struct inode *unused, struct file *file) -{ - struct cgroup *cgrp = __d_cgrp(file->f_dentry->d_parent); - struct ctr_struct *ctr; - pid_t *pidarray; - int npids; - char c; - - if (!(file->f_mode & FMODE_READ)) - return 0; - - ctr = kmalloc(sizeof(*ctr), GFP_KERNEL); - if (!ctr) - goto err0; - - /* - * If cgroup gets more users after we read count, we won't have - * enough space - tough. This race is indistinguishable to the - * caller from the case that the additional cgroup users didn't - * show up until sometime later on. - */ - npids = cgroup_task_count(cgrp); - if (npids) { - pidarray = kmalloc(npids * sizeof(pid_t), GFP_KERNEL); - if (!pidarray) - goto err1; - - npids = pid_array_load(pidarray, npids, cgrp); - sort(pidarray, npids, sizeof(pid_t), cmppid, NULL); - - /* Call pid_array_to_buf() twice, first just to get bufsz */ - ctr->bufsz = pid_array_to_buf(&c, sizeof(c), pidarray, npids) + 1; - ctr->buf = kmalloc(ctr->bufsz, GFP_KERNEL); - if (!ctr->buf) - goto err2; - ctr->bufsz = pid_array_to_buf(ctr->buf, ctr->bufsz, pidarray, npids); - - kfree(pidarray); - } else { - ctr->buf = 0; - ctr->bufsz = 0; - } - file->private_data = ctr; - return 0; - -err2: - kfree(pidarray); -err1: - kfree(ctr); -err0: - return -ENOMEM; -} - -static ssize_t cgroup_tasks_read(struct cgroup *cgrp, - struct cftype *cft, - struct file *file, char __user *buf, - size_t nbytes, loff_t *ppos) -{ - struct ctr_struct *ctr = file->private_data; - - return simple_read_from_buffer(buf, nbytes, ppos, ctr->buf, ctr->bufsz); -} - -static int cgroup_tasks_release(struct inode *unused_inode, - struct file *file) -{ - struct ctr_struct *ctr; - - if (file->f_mode & FMODE_READ) { - ctr = file->private_data; - kfree(ctr->buf); - kfree(ctr); - } - return 0; -} - -static u64 cgroup_read_notify_on_release(struct cgroup *cgrp, - struct cftype *cft) -{ - return notify_on_release(cgrp); -} - -static u64 cgroup_read_releasable(struct cgroup *cgrp, struct cftype *cft) -{ - return test_bit(CGRP_RELEASABLE, &cgrp->flags); -} - -/* - * for the common functions, 'private' gives the type of file - */ -static struct cftype files[] = { - { - .name = "tasks", - .open = cgroup_tasks_open, - .read = cgroup_tasks_read, - .write = cgroup_common_file_write, - .release = cgroup_tasks_release, - .private = FILE_TASKLIST, - }, - - { - .name = "notify_on_release", - .read_uint = cgroup_read_notify_on_release, - .write = cgroup_common_file_write, - .private = FILE_NOTIFY_ON_RELEASE, - }, - - { - .name = "releasable", - .read_uint = cgroup_read_releasable, - .private = FILE_RELEASABLE, - } -}; - -static struct cftype cft_release_agent = { - .name = "release_agent", - .read = cgroup_common_file_read, - .write = cgroup_common_file_write, - .private = FILE_RELEASE_AGENT, -}; - -static int cgroup_populate_dir(struct cgroup *cgrp) -{ - int err; - struct cgroup_subsys *ss; - - /* First clear out any existing files */ - cgroup_clear_directory(cgrp->dentry); - - err = cgroup_add_files(cgrp, NULL, files, ARRAY_SIZE(files)); - if (err < 0) - return err; - - if (cgrp == cgrp->top_cgroup) { - if ((err = cgroup_add_file(cgrp, NULL, &cft_release_agent)) < 0) - return err; - } - - for_each_subsys(cgrp->root, ss) { - if (ss->populate && (err = ss->populate(ss, cgrp)) < 0) - return err; - } - - return 0; -} - -static void init_cgroup_css(struct cgroup_subsys_state *css, - struct cgroup_subsys *ss, - struct cgroup *cgrp) -{ - css->cgroup = cgrp; - atomic_set(&css->refcnt, 0); - css->flags = 0; - if (cgrp == dummytop) - set_bit(CSS_ROOT, &css->flags); - BUG_ON(cgrp->subsys[ss->subsys_id]); - cgrp->subsys[ss->subsys_id] = css; -} - -/* - * cgroup_create - create a cgroup - * parent: cgroup that will be parent of the new cgroup. - * name: name of the new cgroup. Will be strcpy'ed. - * mode: mode to set on new inode - * - * Must be called with the mutex on the parent inode held - */ - -static long cgroup_create(struct cgroup *parent, struct dentry *dentry, - int mode) -{ - struct cgroup *cgrp; - struct cgroupfs_root *root = parent->root; - int err = 0; - struct cgroup_subsys *ss; - struct super_block *sb = root->sb; - - cgrp = kzalloc(sizeof(*cgrp), GFP_KERNEL); - if (!cgrp) - return -ENOMEM; - - /* Grab a reference on the superblock so the hierarchy doesn't - * get deleted on unmount if there are child cgroups. This - * can be done outside cgroup_mutex, since the sb can't - * disappear while someone has an open control file on the - * fs */ - atomic_inc(&sb->s_active); - - mutex_lock(&cgroup_mutex); - - cgrp->flags = 0; - INIT_LIST_HEAD(&cgrp->sibling); - INIT_LIST_HEAD(&cgrp->children); - INIT_LIST_HEAD(&cgrp->css_sets); - INIT_LIST_HEAD(&cgrp->release_list); - - cgrp->parent = parent; - cgrp->root = parent->root; - cgrp->top_cgroup = parent->top_cgroup; - - for_each_subsys(root, ss) { - struct cgroup_subsys_state *css = ss->create(ss, cgrp); - if (IS_ERR(css)) { - err = PTR_ERR(css); - goto err_destroy; - } - init_cgroup_css(css, ss, cgrp); - } - - list_add(&cgrp->sibling, &cgrp->parent->children); - root->number_of_cgroups++; - - err = cgroup_create_dir(cgrp, dentry, mode); - if (err < 0) - goto err_remove; - - /* The cgroup directory was pre-locked for us */ - BUG_ON(!mutex_is_locked(&cgrp->dentry->d_inode->i_mutex)); - - err = cgroup_populate_dir(cgrp); - /* If err < 0, we have a half-filled directory - oh well ;) */ - - mutex_unlock(&cgroup_mutex); - mutex_unlock(&cgrp->dentry->d_inode->i_mutex); - - return 0; - - err_remove: - - list_del(&cgrp->sibling); - root->number_of_cgroups--; - - err_destroy: - - for_each_subsys(root, ss) { - if (cgrp->subsys[ss->subsys_id]) - ss->destroy(ss, cgrp); - } - - mutex_unlock(&cgroup_mutex); - - /* Release the reference count that we took on the superblock */ - deactivate_super(sb); - - kfree(cgrp); - return err; -} - -static int cgroup_mkdir(struct inode *dir, struct dentry *dentry, int mode) -{ - struct cgroup *c_parent = dentry->d_parent->d_fsdata; - - /* the vfs holds inode->i_mutex already */ - return cgroup_create(c_parent, dentry, mode | S_IFDIR); -} - -static inline int cgroup_has_css_refs(struct cgroup *cgrp) -{ - /* Check the reference count on each subsystem. Since we - * already established that there are no tasks in the - * cgroup, if the css refcount is also 0, then there should - * be no outstanding references, so the subsystem is safe to - * destroy. We scan across all subsystems rather than using - * the per-hierarchy linked list of mounted subsystems since - * we can be called via check_for_release() with no - * synchronization other than RCU, and the subsystem linked - * list isn't RCU-safe */ - int i; - for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) { - struct cgroup_subsys *ss = subsys[i]; - struct cgroup_subsys_state *css; - /* Skip subsystems not in this hierarchy */ - if (ss->root != cgrp->root) - continue; - css = cgrp->subsys[ss->subsys_id]; - /* When called from check_for_release() it's possible - * that by this point the cgroup has been removed - * and the css deleted. But a false-positive doesn't - * matter, since it can only happen if the cgroup - * has been deleted and hence no longer needs the - * release agent to be called anyway. */ - if (css && atomic_read(&css->refcnt)) { - return 1; - } - } - return 0; -} - -static int cgroup_rmdir(struct inode *unused_dir, struct dentry *dentry) -{ - struct cgroup *cgrp = dentry->d_fsdata; - struct dentry *d; - struct cgroup *parent; - struct cgroup_subsys *ss; - struct super_block *sb; - struct cgroupfs_root *root; - - /* the vfs holds both inode->i_mutex already */ - - mutex_lock(&cgroup_mutex); - if (atomic_read(&cgrp->count) != 0) { - mutex_unlock(&cgroup_mutex); - return -EBUSY; - } - if (!list_empty(&cgrp->children)) { - mutex_unlock(&cgroup_mutex); - return -EBUSY; - } - - parent = cgrp->parent; - root = cgrp->root; - sb = root->sb; - - if (cgroup_has_css_refs(cgrp)) { - mutex_unlock(&cgroup_mutex); - return -EBUSY; - } - - for_each_subsys(root, ss) { - if (cgrp->subsys[ss->subsys_id]) - ss->destroy(ss, cgrp); - } - - spin_lock(&release_list_lock); - set_bit(CGRP_REMOVED, &cgrp->flags); - if (!list_empty(&cgrp->release_list)) - list_del(&cgrp->release_list); - spin_unlock(&release_list_lock); - /* delete my sibling from parent->children */ - list_del(&cgrp->sibling); - spin_lock(&cgrp->dentry->d_lock); - d = dget(cgrp->dentry); - cgrp->dentry = NULL; - spin_unlock(&d->d_lock); - - cgroup_d_remove_dir(d); - dput(d); - root->number_of_cgroups--; - - set_bit(CGRP_RELEASABLE, &parent->flags); - check_for_release(parent); - - mutex_unlock(&cgroup_mutex); - /* Drop the active superblock reference that we took when we - * created the cgroup */ - deactivate_super(sb); - return 0; -} - -static void cgroup_init_subsys(struct cgroup_subsys *ss) -{ - struct cgroup_subsys_state *css; - struct list_head *l; - printk(KERN_ERR "Initializing cgroup subsys %s\n", ss->name); - - /* Create the top cgroup state for this subsystem */ - ss->root = &rootnode; - css = ss->create(ss, dummytop); - /* We don't handle early failures gracefully */ - BUG_ON(IS_ERR(css)); - init_cgroup_css(css, ss, dummytop); - - /* Update all cgroup groups to contain a subsys - * pointer to this state - since the subsystem is - * newly registered, all tasks and hence all cgroup - * groups are in the subsystem's top cgroup. */ - write_lock(&css_set_lock); - l = &init_css_set.list; - do { - struct css_set *cg = - list_entry(l, struct css_set, list); - cg->subsys[ss->subsys_id] = dummytop->subsys[ss->subsys_id]; - l = l->next; - } while (l != &init_css_set.list); - write_unlock(&css_set_lock); - - /* If this subsystem requested that it be notified with fork - * events, we should send it one now for every process in the - * system */ - if (ss->fork) { - struct task_struct *g, *p; - - read_lock(&tasklist_lock); - do_each_thread(g, p) { - ss->fork(ss, p); - } while_each_thread(g, p); - read_unlock(&tasklist_lock); - } - - need_forkexit_callback |= ss->fork || ss->exit; - - ss->active = 1; -} - -/** - * cgroup_init_early - initialize cgroups at system boot, and - * initialize any subsystems that request early init. - */ -int __init cgroup_init_early(void) -{ - int i; - kref_init(&init_css_set.ref); - kref_get(&init_css_set.ref); - INIT_LIST_HEAD(&init_css_set.list); - INIT_LIST_HEAD(&init_css_set.cg_links); - INIT_LIST_HEAD(&init_css_set.tasks); - css_set_count = 1; - init_cgroup_root(&rootnode); - list_add(&rootnode.root_list, &roots); - root_count = 1; - init_task.cgroups = &init_css_set; - - init_css_set_link.cg = &init_css_set; - list_add(&init_css_set_link.cgrp_link_list, - &rootnode.top_cgroup.css_sets); - list_add(&init_css_set_link.cg_link_list, - &init_css_set.cg_links); - - for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) { - struct cgroup_subsys *ss = subsys[i]; - - BUG_ON(!ss->name); - BUG_ON(strlen(ss->name) > MAX_CGROUP_TYPE_NAMELEN); - BUG_ON(!ss->create); - BUG_ON(!ss->destroy); - if (ss->subsys_id != i) { - printk(KERN_ERR "Subsys %s id == %d\n", - ss->name, ss->subsys_id); - BUG(); - } - - if (ss->early_init) - cgroup_init_subsys(ss); - } - return 0; -} - -/** - * cgroup_init - register cgroup filesystem and /proc file, and - * initialize any subsystems that didn't request early init. - */ -int __init cgroup_init(void) -{ - int err; - int i; - struct proc_dir_entry *entry; - - err = bdi_init(&cgroup_backing_dev_info); - if (err) - return err; - - for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) { - struct cgroup_subsys *ss = subsys[i]; - if (!ss->early_init) - cgroup_init_subsys(ss); - } - - err = register_filesystem(&cgroup_fs_type); - if (err < 0) - goto out; - - entry = create_proc_entry("cgroups", 0, NULL); - if (entry) - entry->proc_fops = &proc_cgroupstats_operations; - -out: - if (err) - bdi_destroy(&cgroup_backing_dev_info); - - return err; -} - -/* - * proc_cgroup_show() - * - Print task's cgroup paths into seq_file, one line for each hierarchy - * - Used for /proc//cgroup. - * - No need to task_lock(tsk) on this tsk->cgroup reference, as it - * doesn't really matter if tsk->cgroup changes after we read it, - * and we take cgroup_mutex, keeping attach_task() from changing it - * anyway. No need to check that tsk->cgroup != NULL, thanks to - * the_top_cgroup_hack in cgroup_exit(), which sets an exiting tasks - * cgroup to top_cgroup. - */ - -/* TODO: Use a proper seq_file iterator */ -static int proc_cgroup_show(struct seq_file *m, void *v) -{ - struct pid *pid; - struct task_struct *tsk; - char *buf; - int retval; - struct cgroupfs_root *root; - - retval = -ENOMEM; - buf = kmalloc(PAGE_SIZE, GFP_KERNEL); - if (!buf) - goto out; - - retval = -ESRCH; - pid = m->private; - tsk = get_pid_task(pid, PIDTYPE_PID); - if (!tsk) - goto out_free; - - retval = 0; - - mutex_lock(&cgroup_mutex); - - for_each_root(root) { - struct cgroup_subsys *ss; - struct cgroup *cgrp; - int subsys_id; - int count = 0; - - /* Skip this hierarchy if it has no active subsystems */ - if (!root->actual_subsys_bits) - continue; - for_each_subsys(root, ss) - seq_printf(m, "%s%s", count++ ? "," : "", ss->name); - seq_putc(m, ':'); - get_first_subsys(&root->top_cgroup, NULL, &subsys_id); - cgrp = task_cgroup(tsk, subsys_id); - retval = cgroup_path(cgrp, buf, PAGE_SIZE); - if (retval < 0) - goto out_unlock; - seq_puts(m, buf); - seq_putc(m, '\n'); - } - -out_unlock: - mutex_unlock(&cgroup_mutex); - put_task_struct(tsk); -out_free: - kfree(buf); -out: - return retval; -} - -static int cgroup_open(struct inode *inode, struct file *file) -{ - struct pid *pid = PROC_I(inode)->pid; - return single_open(file, proc_cgroup_show, pid); -} - -struct file_operations proc_cgroup_operations = { - .open = cgroup_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -/* Display information about each subsystem and each hierarchy */ -static int proc_cgroupstats_show(struct seq_file *m, void *v) -{ - int i; - struct cgroupfs_root *root; - - seq_puts(m, "#subsys_name\thierarchy\tnum_cgroups\n"); - mutex_lock(&cgroup_mutex); - for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) { - struct cgroup_subsys *ss = subsys[i]; - seq_printf(m, "%s\t%lu\t%d\n", - ss->name, ss->root->subsys_bits, - ss->root->number_of_cgroups); - } - mutex_unlock(&cgroup_mutex); - return 0; -} - -static int cgroupstats_open(struct inode *inode, struct file *file) -{ - return single_open(file, proc_cgroupstats_show, 0); -} - -static struct file_operations proc_cgroupstats_operations = { - .open = cgroupstats_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -/** - * cgroup_fork - attach newly forked task to its parents cgroup. - * @tsk: pointer to task_struct of forking parent process. - * - * Description: A task inherits its parent's cgroup at fork(). - * - * A pointer to the shared css_set was automatically copied in - * fork.c by dup_task_struct(). However, we ignore that copy, since - * it was not made under the protection of RCU or cgroup_mutex, so - * might no longer be a valid cgroup pointer. attach_task() might - * have already changed current->cgroups, allowing the previously - * referenced cgroup group to be removed and freed. - * - * At the point that cgroup_fork() is called, 'current' is the parent - * task, and the passed argument 'child' points to the child task. - */ -void cgroup_fork(struct task_struct *child) -{ - task_lock(current); - child->cgroups = current->cgroups; - get_css_set(child->cgroups); - task_unlock(current); - INIT_LIST_HEAD(&child->cg_list); -} - -/** - * cgroup_fork_callbacks - called on a new task very soon before - * adding it to the tasklist. No need to take any locks since no-one - * can be operating on this task - */ -void cgroup_fork_callbacks(struct task_struct *child) -{ - if (need_forkexit_callback) { - int i; - for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) { - struct cgroup_subsys *ss = subsys[i]; - if (ss->fork) - ss->fork(ss, child); - } - } -} - -/** - * cgroup_post_fork - called on a new task after adding it to the - * task list. Adds the task to the list running through its css_set - * if necessary. Has to be after the task is visible on the task list - * in case we race with the first call to cgroup_iter_start() - to - * guarantee that the new task ends up on its list. */ -void cgroup_post_fork(struct task_struct *child) -{ - if (use_task_css_set_links) { - write_lock(&css_set_lock); - if (list_empty(&child->cg_list)) - list_add(&child->cg_list, &child->cgroups->tasks); - write_unlock(&css_set_lock); - } -} -/** - * cgroup_exit - detach cgroup from exiting task - * @tsk: pointer to task_struct of exiting process - * - * Description: Detach cgroup from @tsk and release it. - * - * Note that cgroups marked notify_on_release force every task in - * them to take the global cgroup_mutex mutex when exiting. - * This could impact scaling on very large systems. Be reluctant to - * use notify_on_release cgroups where very high task exit scaling - * is required on large systems. - * - * the_top_cgroup_hack: - * - * Set the exiting tasks cgroup to the root cgroup (top_cgroup). - * - * We call cgroup_exit() while the task is still competent to - * handle notify_on_release(), then leave the task attached to the - * root cgroup in each hierarchy for the remainder of its exit. - * - * To do this properly, we would increment the reference count on - * top_cgroup, and near the very end of the kernel/exit.c do_exit() - * code we would add a second cgroup function call, to drop that - * reference. This would just create an unnecessary hot spot on - * the top_cgroup reference count, to no avail. - * - * Normally, holding a reference to a cgroup without bumping its - * count is unsafe. The cgroup could go away, or someone could - * attach us to a different cgroup, decrementing the count on - * the first cgroup that we never incremented. But in this case, - * top_cgroup isn't going away, and either task has PF_EXITING set, - * which wards off any attach_task() attempts, or task is a failed - * fork, never visible to attach_task. - * - */ -void cgroup_exit(struct task_struct *tsk, int run_callbacks) -{ - int i; - struct css_set *cg; - - if (run_callbacks && need_forkexit_callback) { - for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) { - struct cgroup_subsys *ss = subsys[i]; - if (ss->exit) - ss->exit(ss, tsk); - } - } - - /* - * Unlink from the css_set task list if necessary. - * Optimistically check cg_list before taking - * css_set_lock - */ - if (!list_empty(&tsk->cg_list)) { - write_lock(&css_set_lock); - if (!list_empty(&tsk->cg_list)) - list_del(&tsk->cg_list); - write_unlock(&css_set_lock); - } - - /* Reassign the task to the init_css_set. */ - task_lock(tsk); - cg = tsk->cgroups; - tsk->cgroups = &init_css_set; - task_unlock(tsk); - if (cg) - put_css_set_taskexit(cg); -} - -/** - * cgroup_clone - duplicate the current cgroup in the hierarchy - * that the given subsystem is attached to, and move this task into - * the new child - */ -int cgroup_clone(struct task_struct *tsk, struct cgroup_subsys *subsys) -{ - struct dentry *dentry; - int ret = 0; - char nodename[MAX_CGROUP_TYPE_NAMELEN]; - struct cgroup *parent, *child; - struct inode *inode; - struct css_set *cg; - struct cgroupfs_root *root; - struct cgroup_subsys *ss; - - /* We shouldn't be called by an unregistered subsystem */ - BUG_ON(!subsys->active); - - /* First figure out what hierarchy and cgroup we're dealing - * with, and pin them so we can drop cgroup_mutex */ - mutex_lock(&cgroup_mutex); - again: - root = subsys->root; - if (root == &rootnode) { - printk(KERN_INFO - "Not cloning cgroup for unused subsystem %s\n", - subsys->name); - mutex_unlock(&cgroup_mutex); - return 0; - } - cg = tsk->cgroups; - parent = task_cgroup(tsk, subsys->subsys_id); - - snprintf(nodename, MAX_CGROUP_TYPE_NAMELEN, "node_%d", tsk->pid); - - /* Pin the hierarchy */ - atomic_inc(&parent->root->sb->s_active); - - /* Keep the cgroup alive */ - get_css_set(cg); - mutex_unlock(&cgroup_mutex); - - /* Now do the VFS work to create a cgroup */ - inode = parent->dentry->d_inode; - - /* Hold the parent directory mutex across this operation to - * stop anyone else deleting the new cgroup */ - mutex_lock(&inode->i_mutex); - dentry = lookup_one_len(nodename, parent->dentry, strlen(nodename)); - if (IS_ERR(dentry)) { - printk(KERN_INFO - "Couldn't allocate dentry for %s: %ld\n", nodename, - PTR_ERR(dentry)); - ret = PTR_ERR(dentry); - goto out_release; - } - - /* Create the cgroup directory, which also creates the cgroup */ - ret = vfs_mkdir(inode, dentry, S_IFDIR | 0755); - child = __d_cgrp(dentry); - dput(dentry); - if (ret) { - printk(KERN_INFO - "Failed to create cgroup %s: %d\n", nodename, - ret); - goto out_release; - } - - if (!child) { - printk(KERN_INFO - "Couldn't find new cgroup %s\n", nodename); - ret = -ENOMEM; - goto out_release; - } - - /* The cgroup now exists. Retake cgroup_mutex and check - * that we're still in the same state that we thought we - * were. */ - mutex_lock(&cgroup_mutex); - if ((root != subsys->root) || - (parent != task_cgroup(tsk, subsys->subsys_id))) { - /* Aargh, we raced ... */ - mutex_unlock(&inode->i_mutex); - put_css_set(cg); - - deactivate_super(parent->root->sb); - /* The cgroup is still accessible in the VFS, but - * we're not going to try to rmdir() it at this - * point. */ - printk(KERN_INFO - "Race in cgroup_clone() - leaking cgroup %s\n", - nodename); - goto again; - } - - /* do any required auto-setup */ - for_each_subsys(root, ss) { - if (ss->post_clone) - ss->post_clone(ss, child); - } - - /* All seems fine. Finish by moving the task into the new cgroup */ - ret = attach_task(child, tsk); - mutex_unlock(&cgroup_mutex); - - out_release: - mutex_unlock(&inode->i_mutex); - - mutex_lock(&cgroup_mutex); - put_css_set(cg); - mutex_unlock(&cgroup_mutex); - deactivate_super(parent->root->sb); - return ret; -} - -/* - * See if "cgrp" is a descendant of the current task's cgroup in - * the appropriate hierarchy - * - * If we are sending in dummytop, then presumably we are creating - * the top cgroup in the subsystem. - * - * Called only by the ns (nsproxy) cgroup. - */ -int cgroup_is_descendant(const struct cgroup *cgrp) -{ - int ret; - struct cgroup *target; - int subsys_id; - - if (cgrp == dummytop) - return 1; - - get_first_subsys(cgrp, NULL, &subsys_id); - target = task_cgroup(current, subsys_id); - while (cgrp != target && cgrp!= cgrp->top_cgroup) - cgrp = cgrp->parent; - ret = (cgrp == target); - return ret; -} - -static void check_for_release(struct cgroup *cgrp) -{ - /* All of these checks rely on RCU to keep the cgroup - * structure alive */ - if (cgroup_is_releasable(cgrp) && !atomic_read(&cgrp->count) - && list_empty(&cgrp->children) && !cgroup_has_css_refs(cgrp)) { - /* Control Group is currently removeable. If it's not - * already queued for a userspace notification, queue - * it now */ - int need_schedule_work = 0; - spin_lock(&release_list_lock); - if (!cgroup_is_removed(cgrp) && - list_empty(&cgrp->release_list)) { - list_add(&cgrp->release_list, &release_list); - need_schedule_work = 1; - } - spin_unlock(&release_list_lock); - if (need_schedule_work) - schedule_work(&release_agent_work); - } -} - -void __css_put(struct cgroup_subsys_state *css) -{ - struct cgroup *cgrp = css->cgroup; - rcu_read_lock(); - if (atomic_dec_and_test(&css->refcnt) && notify_on_release(cgrp)) { - set_bit(CGRP_RELEASABLE, &cgrp->flags); - check_for_release(cgrp); - } - rcu_read_unlock(); -} - -/* - * Notify userspace when a cgroup is released, by running the - * configured release agent with the name of the cgroup (path - * relative to the root of cgroup file system) as the argument. - * - * Most likely, this user command will try to rmdir this cgroup. - * - * This races with the possibility that some other task will be - * attached to this cgroup before it is removed, or that some other - * user task will 'mkdir' a child cgroup of this cgroup. That's ok. - * The presumed 'rmdir' will fail quietly if this cgroup is no longer - * unused, and this cgroup will be reprieved from its death sentence, - * to continue to serve a useful existence. Next time it's released, - * we will get notified again, if it still has 'notify_on_release' set. - * - * The final arg to call_usermodehelper() is UMH_WAIT_EXEC, which - * means only wait until the task is successfully execve()'d. The - * separate release agent task is forked by call_usermodehelper(), - * then control in this thread returns here, without waiting for the - * release agent task. We don't bother to wait because the caller of - * this routine has no use for the exit status of the release agent - * task, so no sense holding our caller up for that. - * - */ - -static void cgroup_release_agent(struct work_struct *work) -{ - BUG_ON(work != &release_agent_work); - mutex_lock(&cgroup_mutex); - spin_lock(&release_list_lock); - while (!list_empty(&release_list)) { - char *argv[3], *envp[3]; - int i; - char *pathbuf; - struct cgroup *cgrp = list_entry(release_list.next, - struct cgroup, - release_list); - list_del_init(&cgrp->release_list); - spin_unlock(&release_list_lock); - pathbuf = kmalloc(PAGE_SIZE, GFP_KERNEL); - if (!pathbuf) { - spin_lock(&release_list_lock); - continue; - } - - if (cgroup_path(cgrp, pathbuf, PAGE_SIZE) < 0) { - kfree(pathbuf); - spin_lock(&release_list_lock); - continue; - } - - i = 0; - argv[i++] = cgrp->root->release_agent_path; - argv[i++] = (char *)pathbuf; - argv[i] = NULL; - - i = 0; - /* minimal command environment */ - envp[i++] = "HOME=/"; - envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin"; - envp[i] = NULL; - - /* Drop the lock while we invoke the usermode helper, - * since the exec could involve hitting disk and hence - * be a slow process */ - mutex_unlock(&cgroup_mutex); - call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC); - kfree(pathbuf); - mutex_lock(&cgroup_mutex); - spin_lock(&release_list_lock); - } - spin_unlock(&release_list_lock); - mutex_unlock(&cgroup_mutex); -} diff --git a/trunk/kernel/cgroup_debug.c b/trunk/kernel/cgroup_debug.c deleted file mode 100644 index 37301e877cb0..000000000000 --- a/trunk/kernel/cgroup_debug.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * kernel/ccontainer_debug.c - Example cgroup subsystem that - * exposes debug info - * - * Copyright (C) Google Inc, 2007 - * - * Developed by Paul Menage (menage@google.com) - * - */ - -#include -#include -#include -#include - -#include - -static struct cgroup_subsys_state *debug_create(struct cgroup_subsys *ss, - struct cgroup *cont) -{ - struct cgroup_subsys_state *css = kzalloc(sizeof(*css), GFP_KERNEL); - - if (!css) - return ERR_PTR(-ENOMEM); - - return css; -} - -static void debug_destroy(struct cgroup_subsys *ss, struct cgroup *cont) -{ - kfree(cont->subsys[debug_subsys_id]); -} - -static u64 cgroup_refcount_read(struct cgroup *cont, struct cftype *cft) -{ - return atomic_read(&cont->count); -} - -static u64 taskcount_read(struct cgroup *cont, struct cftype *cft) -{ - u64 count; - - cgroup_lock(); - count = cgroup_task_count(cont); - cgroup_unlock(); - return count; -} - -static u64 current_css_set_read(struct cgroup *cont, struct cftype *cft) -{ - return (u64)(long)current->cgroups; -} - -static u64 current_css_set_refcount_read(struct cgroup *cont, - struct cftype *cft) -{ - u64 count; - - rcu_read_lock(); - count = atomic_read(¤t->cgroups->ref.refcount); - rcu_read_unlock(); - return count; -} - -static struct cftype files[] = { - { - .name = "cgroup_refcount", - .read_uint = cgroup_refcount_read, - }, - { - .name = "taskcount", - .read_uint = taskcount_read, - }, - - { - .name = "current_css_set", - .read_uint = current_css_set_read, - }, - - { - .name = "current_css_set_refcount", - .read_uint = current_css_set_refcount_read, - }, -}; - -static int debug_populate(struct cgroup_subsys *ss, struct cgroup *cont) -{ - return cgroup_add_files(cont, ss, files, ARRAY_SIZE(files)); -} - -struct cgroup_subsys debug_subsys = { - .name = "debug", - .create = debug_create, - .destroy = debug_destroy, - .populate = debug_populate, - .subsys_id = debug_subsys_id, -}; diff --git a/trunk/kernel/compat.c b/trunk/kernel/compat.c index 42a1ed4b61b1..3bae3742c2aa 100644 --- a/trunk/kernel/compat.c +++ b/trunk/kernel/compat.c @@ -40,27 +40,62 @@ int put_compat_timespec(const struct timespec *ts, struct compat_timespec __user __put_user(ts->tv_nsec, &cts->tv_nsec)) ? -EFAULT : 0; } +static long compat_nanosleep_restart(struct restart_block *restart) +{ + unsigned long expire = restart->arg0, now = jiffies; + struct compat_timespec __user *rmtp; + + /* Did it expire while we handled signals? */ + if (!time_after(expire, now)) + return 0; + + expire = schedule_timeout_interruptible(expire - now); + if (expire == 0) + return 0; + + rmtp = (struct compat_timespec __user *)restart->arg1; + if (rmtp) { + struct compat_timespec ct; + struct timespec t; + + jiffies_to_timespec(expire, &t); + ct.tv_sec = t.tv_sec; + ct.tv_nsec = t.tv_nsec; + if (copy_to_user(rmtp, &ct, sizeof(ct))) + return -EFAULT; + } + /* The 'restart' block is already filled in */ + return -ERESTART_RESTARTBLOCK; +} + asmlinkage long compat_sys_nanosleep(struct compat_timespec __user *rqtp, - struct compat_timespec __user *rmtp) + struct compat_timespec __user *rmtp) { - struct timespec tu, rmt; - long ret; + struct timespec t; + struct restart_block *restart; + unsigned long expire; - if (get_compat_timespec(&tu, rqtp)) + if (get_compat_timespec(&t, rqtp)) return -EFAULT; - if (!timespec_valid(&tu)) + if ((t.tv_nsec >= 1000000000L) || (t.tv_nsec < 0) || (t.tv_sec < 0)) return -EINVAL; - ret = hrtimer_nanosleep(&tu, rmtp ? &rmt : NULL, HRTIMER_MODE_REL, - CLOCK_MONOTONIC); + expire = timespec_to_jiffies(&t) + (t.tv_sec || t.tv_nsec); + expire = schedule_timeout_interruptible(expire); + if (expire == 0) + return 0; - if (ret && rmtp) { - if (put_compat_timespec(&rmt, rmtp)) + if (rmtp) { + jiffies_to_timespec(expire, &t); + if (put_compat_timespec(&t, rmtp)) return -EFAULT; } - - return ret; + restart = ¤t_thread_info()->restart_block; + restart->fn = compat_nanosleep_restart; + restart->arg0 = jiffies + expire; + restart->arg1 = (unsigned long) rmtp; + return -ERESTART_RESTARTBLOCK; } static inline long get_compat_itimerval(struct itimerval *o, @@ -212,8 +247,8 @@ asmlinkage long compat_sys_setrlimit(unsigned int resource, int ret; mm_segment_t old_fs = get_fs (); - if (resource >= RLIM_NLIMITS) - return -EINVAL; + if (resource >= RLIM_NLIMITS) + return -EINVAL; if (!access_ok(VERIFY_READ, rlim, sizeof(*rlim)) || __get_user(r.rlim_cur, &rlim->rlim_cur) || @@ -442,21 +477,21 @@ asmlinkage long compat_sys_sched_getaffinity(compat_pid_t pid, unsigned int len, int get_compat_itimerspec(struct itimerspec *dst, const struct compat_itimerspec __user *src) -{ +{ if (get_compat_timespec(&dst->it_interval, &src->it_interval) || get_compat_timespec(&dst->it_value, &src->it_value)) return -EFAULT; return 0; -} +} int put_compat_itimerspec(struct compat_itimerspec __user *dst, const struct itimerspec *src) -{ +{ if (put_compat_timespec(&src->it_interval, &dst->it_interval) || put_compat_timespec(&src->it_value, &dst->it_value)) return -EFAULT; return 0; -} +} long compat_sys_timer_create(clockid_t which_clock, struct compat_sigevent __user *timer_event_spec, @@ -477,9 +512,9 @@ long compat_sys_timer_create(clockid_t which_clock, } long compat_sys_timer_settime(timer_t timer_id, int flags, - struct compat_itimerspec __user *new, + struct compat_itimerspec __user *new, struct compat_itimerspec __user *old) -{ +{ long err; mm_segment_t oldfs; struct itimerspec newts, oldts; @@ -487,58 +522,58 @@ long compat_sys_timer_settime(timer_t timer_id, int flags, if (!new) return -EINVAL; if (get_compat_itimerspec(&newts, new)) - return -EFAULT; + return -EFAULT; oldfs = get_fs(); set_fs(KERNEL_DS); err = sys_timer_settime(timer_id, flags, (struct itimerspec __user *) &newts, (struct itimerspec __user *) &oldts); - set_fs(oldfs); + set_fs(oldfs); if (!err && old && put_compat_itimerspec(old, &oldts)) return -EFAULT; return err; -} +} long compat_sys_timer_gettime(timer_t timer_id, struct compat_itimerspec __user *setting) -{ +{ long err; mm_segment_t oldfs; - struct itimerspec ts; + struct itimerspec ts; oldfs = get_fs(); set_fs(KERNEL_DS); err = sys_timer_gettime(timer_id, - (struct itimerspec __user *) &ts); - set_fs(oldfs); + (struct itimerspec __user *) &ts); + set_fs(oldfs); if (!err && put_compat_itimerspec(setting, &ts)) return -EFAULT; return err; -} +} long compat_sys_clock_settime(clockid_t which_clock, struct compat_timespec __user *tp) { long err; mm_segment_t oldfs; - struct timespec ts; + struct timespec ts; if (get_compat_timespec(&ts, tp)) - return -EFAULT; + return -EFAULT; oldfs = get_fs(); - set_fs(KERNEL_DS); + set_fs(KERNEL_DS); err = sys_clock_settime(which_clock, (struct timespec __user *) &ts); set_fs(oldfs); return err; -} +} long compat_sys_clock_gettime(clockid_t which_clock, struct compat_timespec __user *tp) { long err; mm_segment_t oldfs; - struct timespec ts; + struct timespec ts; oldfs = get_fs(); set_fs(KERNEL_DS); @@ -546,16 +581,16 @@ long compat_sys_clock_gettime(clockid_t which_clock, (struct timespec __user *) &ts); set_fs(oldfs); if (!err && put_compat_timespec(&ts, tp)) - return -EFAULT; + return -EFAULT; return err; -} +} long compat_sys_clock_getres(clockid_t which_clock, struct compat_timespec __user *tp) { long err; mm_segment_t oldfs; - struct timespec ts; + struct timespec ts; oldfs = get_fs(); set_fs(KERNEL_DS); @@ -563,9 +598,9 @@ long compat_sys_clock_getres(clockid_t which_clock, (struct timespec __user *) &ts); set_fs(oldfs); if (!err && tp && put_compat_timespec(&ts, tp)) - return -EFAULT; + return -EFAULT; return err; -} +} static long compat_clock_nanosleep_restart(struct restart_block *restart) { @@ -597,10 +632,10 @@ long compat_sys_clock_nanosleep(clockid_t which_clock, int flags, { long err; mm_segment_t oldfs; - struct timespec in, out; + struct timespec in, out; struct restart_block *restart; - if (get_compat_timespec(&in, rqtp)) + if (get_compat_timespec(&in, rqtp)) return -EFAULT; oldfs = get_fs(); @@ -619,8 +654,8 @@ long compat_sys_clock_nanosleep(clockid_t which_clock, int flags, restart->fn = compat_clock_nanosleep_restart; restart->arg1 = (unsigned long) rmtp; } - return err; -} + return err; +} /* * We currently only need the following fields from the sigevent diff --git a/trunk/kernel/cpu.c b/trunk/kernel/cpu.c index 6b3a0c15144f..38033db8d8ec 100644 --- a/trunk/kernel/cpu.c +++ b/trunk/kernel/cpu.c @@ -98,8 +98,7 @@ static inline void check_for_tasks(int cpu) !cputime_eq(p->stime, cputime_zero))) printk(KERN_WARNING "Task %s (pid = %d) is on cpu %d\ (state = %ld, flags = %x) \n", - p->comm, task_pid_nr(p), cpu, - p->state, p->flags); + p->comm, p->pid, cpu, p->state, p->flags); } write_unlock_irq(&tasklist_lock); } @@ -151,7 +150,6 @@ static int _cpu_down(unsigned int cpu, int tasks_frozen) err = __raw_notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE | mod, hcpu, -1, &nr_calls); if (err == NOTIFY_BAD) { - nr_calls--; __raw_notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED | mod, hcpu, nr_calls, NULL); printk("%s: attempt to take down CPU %u failed\n", @@ -235,7 +233,6 @@ static int __cpuinit _cpu_up(unsigned int cpu, int tasks_frozen) ret = __raw_notifier_call_chain(&cpu_chain, CPU_UP_PREPARE | mod, hcpu, -1, &nr_calls); if (ret == NOTIFY_BAD) { - nr_calls--; printk("%s: attempt to bring up CPU %u failed\n", __FUNCTION__, cpu); ret = -EINVAL; @@ -265,15 +262,6 @@ static int __cpuinit _cpu_up(unsigned int cpu, int tasks_frozen) int __cpuinit cpu_up(unsigned int cpu) { int err = 0; - if (!cpu_isset(cpu, cpu_possible_map)) { - printk(KERN_ERR "can't online cpu %d because it is not " - "configured as may-hotadd at boot time\n", cpu); -#if defined(CONFIG_IA64) || defined(CONFIG_X86_64) || defined(CONFIG_S390) - printk(KERN_ERR "please check additional_cpus= boot " - "parameter\n"); -#endif - return -EINVAL; - } mutex_lock(&cpu_add_remove_lock); if (cpu_hotplug_disabled) diff --git a/trunk/kernel/cpu_acct.c b/trunk/kernel/cpu_acct.c deleted file mode 100644 index 731e47e7f164..000000000000 --- a/trunk/kernel/cpu_acct.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * kernel/cpu_acct.c - CPU accounting cgroup subsystem - * - * Copyright (C) Google Inc, 2006 - * - * Developed by Paul Menage (menage@google.com) and Balbir Singh - * (balbir@in.ibm.com) - * - */ - -/* - * Example cgroup subsystem for reporting total CPU usage of tasks in a - * cgroup, along with percentage load over a time interval - */ - -#include -#include -#include -#include - -#include - -struct cpuacct { - struct cgroup_subsys_state css; - spinlock_t lock; - /* total time used by this class */ - cputime64_t time; - - /* time when next load calculation occurs */ - u64 next_interval_check; - - /* time used in current period */ - cputime64_t current_interval_time; - - /* time used in last period */ - cputime64_t last_interval_time; -}; - -struct cgroup_subsys cpuacct_subsys; - -static inline struct cpuacct *cgroup_ca(struct cgroup *cont) -{ - return container_of(cgroup_subsys_state(cont, cpuacct_subsys_id), - struct cpuacct, css); -} - -static inline struct cpuacct *task_ca(struct task_struct *task) -{ - return container_of(task_subsys_state(task, cpuacct_subsys_id), - struct cpuacct, css); -} - -#define INTERVAL (HZ * 10) - -static inline u64 next_interval_boundary(u64 now) -{ - /* calculate the next interval boundary beyond the - * current time */ - do_div(now, INTERVAL); - return (now + 1) * INTERVAL; -} - -static struct cgroup_subsys_state *cpuacct_create( - struct cgroup_subsys *ss, struct cgroup *cont) -{ - struct cpuacct *ca = kzalloc(sizeof(*ca), GFP_KERNEL); - - if (!ca) - return ERR_PTR(-ENOMEM); - spin_lock_init(&ca->lock); - ca->next_interval_check = next_interval_boundary(get_jiffies_64()); - return &ca->css; -} - -static void cpuacct_destroy(struct cgroup_subsys *ss, - struct cgroup *cont) -{ - kfree(cgroup_ca(cont)); -} - -/* Lazily update the load calculation if necessary. Called with ca locked */ -static void cpuusage_update(struct cpuacct *ca) -{ - u64 now = get_jiffies_64(); - - /* If we're not due for an update, return */ - if (ca->next_interval_check > now) - return; - - if (ca->next_interval_check <= (now - INTERVAL)) { - /* If it's been more than an interval since the last - * check, then catch up - the last interval must have - * been zero load */ - ca->last_interval_time = 0; - ca->next_interval_check = next_interval_boundary(now); - } else { - /* If a steal takes the last interval time negative, - * then we just ignore it */ - if ((s64)ca->current_interval_time > 0) - ca->last_interval_time = ca->current_interval_time; - else - ca->last_interval_time = 0; - ca->next_interval_check += INTERVAL; - } - ca->current_interval_time = 0; -} - -static u64 cpuusage_read(struct cgroup *cont, struct cftype *cft) -{ - struct cpuacct *ca = cgroup_ca(cont); - u64 time; - - spin_lock_irq(&ca->lock); - cpuusage_update(ca); - time = cputime64_to_jiffies64(ca->time); - spin_unlock_irq(&ca->lock); - - /* Convert 64-bit jiffies to seconds */ - time *= 1000; - do_div(time, HZ); - return time; -} - -static u64 load_read(struct cgroup *cont, struct cftype *cft) -{ - struct cpuacct *ca = cgroup_ca(cont); - u64 time; - - /* Find the time used in the previous interval */ - spin_lock_irq(&ca->lock); - cpuusage_update(ca); - time = cputime64_to_jiffies64(ca->last_interval_time); - spin_unlock_irq(&ca->lock); - - /* Convert time to a percentage, to give the load in the - * previous period */ - time *= 100; - do_div(time, INTERVAL); - - return time; -} - -static struct cftype files[] = { - { - .name = "usage", - .read_uint = cpuusage_read, - }, - { - .name = "load", - .read_uint = load_read, - } -}; - -static int cpuacct_populate(struct cgroup_subsys *ss, struct cgroup *cont) -{ - return cgroup_add_files(cont, ss, files, ARRAY_SIZE(files)); -} - -void cpuacct_charge(struct task_struct *task, cputime_t cputime) -{ - - struct cpuacct *ca; - unsigned long flags; - - if (!cpuacct_subsys.active) - return; - rcu_read_lock(); - ca = task_ca(task); - if (ca) { - spin_lock_irqsave(&ca->lock, flags); - cpuusage_update(ca); - ca->time = cputime64_add(ca->time, cputime); - ca->current_interval_time = - cputime64_add(ca->current_interval_time, cputime); - spin_unlock_irqrestore(&ca->lock, flags); - } - rcu_read_unlock(); -} - -struct cgroup_subsys cpuacct_subsys = { - .name = "cpuacct", - .create = cpuacct_create, - .destroy = cpuacct_destroy, - .populate = cpuacct_populate, - .subsys_id = cpuacct_subsys_id, -}; diff --git a/trunk/kernel/cpuset.c b/trunk/kernel/cpuset.c index 50f5dc463688..2eb2e50db0d6 100644 --- a/trunk/kernel/cpuset.c +++ b/trunk/kernel/cpuset.c @@ -4,8 +4,7 @@ * Processor and Memory placement constraints for sets of tasks. * * Copyright (C) 2003 BULL SA. - * Copyright (C) 2004-2007 Silicon Graphics, Inc. - * Copyright (C) 2006 Google, Inc + * Copyright (C) 2004-2006 Silicon Graphics, Inc. * * Portions derived from Patrick Mochel's sysfs code. * sysfs is Copyright (c) 2001-3 Patrick Mochel @@ -13,7 +12,6 @@ * 2003-10-10 Written by Simon Derr. * 2003-10-22 Updates by Stephen Hemminger. * 2004 May-July Rework by Paul Jackson. - * 2006 Rework by Paul Menage to use generic cgroups * * This file is subject to the terms and conditions of the GNU General Public * License. See the file COPYING in the main directory of the Linux @@ -38,7 +36,6 @@ #include #include #include -#include #include #include #include @@ -55,7 +52,8 @@ #include #include #include -#include + +#define CPUSET_SUPER_MAGIC 0x27e0eb /* * Tracks how many cpusets are currently defined in system. @@ -64,10 +62,6 @@ */ int number_of_cpusets __read_mostly; -/* Retrieve the cpuset from a cgroup */ -struct cgroup_subsys cpuset_subsys; -struct cpuset; - /* See "Frequency meter" comments, below. */ struct fmeter { @@ -78,13 +72,24 @@ struct fmeter { }; struct cpuset { - struct cgroup_subsys_state css; - unsigned long flags; /* "unsigned long" so bitops work */ cpumask_t cpus_allowed; /* CPUs allowed to tasks in cpuset */ nodemask_t mems_allowed; /* Memory Nodes allowed to tasks */ + /* + * Count is atomic so can incr (fork) or decr (exit) without a lock. + */ + atomic_t count; /* count tasks using this cpuset */ + + /* + * We link our 'sibling' struct into our parents 'children'. + * Our children link their 'sibling' into our 'children'. + */ + struct list_head sibling; /* my parents children */ + struct list_head children; /* my children */ + struct cpuset *parent; /* my parent */ + struct dentry *dentry; /* cpuset fs entry */ /* * Copy of global cpuset_mems_generation as of the most @@ -93,32 +98,15 @@ struct cpuset { int mems_generation; struct fmeter fmeter; /* memory_pressure filter */ - - /* partition number for rebuild_sched_domains() */ - int pn; }; -/* Retrieve the cpuset for a cgroup */ -static inline struct cpuset *cgroup_cs(struct cgroup *cont) -{ - return container_of(cgroup_subsys_state(cont, cpuset_subsys_id), - struct cpuset, css); -} - -/* Retrieve the cpuset for a task */ -static inline struct cpuset *task_cs(struct task_struct *task) -{ - return container_of(task_subsys_state(task, cpuset_subsys_id), - struct cpuset, css); -} - - /* bits in struct cpuset flags field */ typedef enum { CS_CPU_EXCLUSIVE, CS_MEM_EXCLUSIVE, CS_MEMORY_MIGRATE, - CS_SCHED_LOAD_BALANCE, + CS_REMOVED, + CS_NOTIFY_ON_RELEASE, CS_SPREAD_PAGE, CS_SPREAD_SLAB, } cpuset_flagbits_t; @@ -134,9 +122,14 @@ static inline int is_mem_exclusive(const struct cpuset *cs) return test_bit(CS_MEM_EXCLUSIVE, &cs->flags); } -static inline int is_sched_load_balance(const struct cpuset *cs) +static inline int is_removed(const struct cpuset *cs) { - return test_bit(CS_SCHED_LOAD_BALANCE, &cs->flags); + return test_bit(CS_REMOVED, &cs->flags); +} + +static inline int notify_on_release(const struct cpuset *cs) +{ + return test_bit(CS_NOTIFY_ON_RELEASE, &cs->flags); } static inline int is_memory_migrate(const struct cpuset *cs) @@ -179,8 +172,14 @@ static struct cpuset top_cpuset = { .flags = ((1 << CS_CPU_EXCLUSIVE) | (1 << CS_MEM_EXCLUSIVE)), .cpus_allowed = CPU_MASK_ALL, .mems_allowed = NODE_MASK_ALL, + .count = ATOMIC_INIT(0), + .sibling = LIST_HEAD_INIT(top_cpuset.sibling), + .children = LIST_HEAD_INIT(top_cpuset.children), }; +static struct vfsmount *cpuset_mount; +static struct super_block *cpuset_sb; + /* * We have two global cpuset mutexes below. They can nest. * It is ok to first take manage_mutex, then nest callback_mutex. We also @@ -264,33 +263,297 @@ static struct cpuset top_cpuset = { * the routine cpuset_update_task_memory_state(). */ +static DEFINE_MUTEX(manage_mutex); static DEFINE_MUTEX(callback_mutex); -/* This is ugly, but preserves the userspace API for existing cpuset - * users. If someone tries to mount the "cpuset" filesystem, we - * silently switch it to mount "cgroup" instead */ +/* + * A couple of forward declarations required, due to cyclic reference loop: + * cpuset_mkdir -> cpuset_create -> cpuset_populate_dir -> cpuset_add_file + * -> cpuset_create_file -> cpuset_dir_inode_operations -> cpuset_mkdir. + */ + +static int cpuset_mkdir(struct inode *dir, struct dentry *dentry, int mode); +static int cpuset_rmdir(struct inode *unused_dir, struct dentry *dentry); + +static struct backing_dev_info cpuset_backing_dev_info = { + .ra_pages = 0, /* No readahead */ + .capabilities = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK, +}; + +static struct inode *cpuset_new_inode(mode_t mode) +{ + struct inode *inode = new_inode(cpuset_sb); + + if (inode) { + inode->i_mode = mode; + inode->i_uid = current->fsuid; + inode->i_gid = current->fsgid; + inode->i_blocks = 0; + inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; + inode->i_mapping->backing_dev_info = &cpuset_backing_dev_info; + } + return inode; +} + +static void cpuset_diput(struct dentry *dentry, struct inode *inode) +{ + /* is dentry a directory ? if so, kfree() associated cpuset */ + if (S_ISDIR(inode->i_mode)) { + struct cpuset *cs = dentry->d_fsdata; + BUG_ON(!(is_removed(cs))); + kfree(cs); + } + iput(inode); +} + +static struct dentry_operations cpuset_dops = { + .d_iput = cpuset_diput, +}; + +static struct dentry *cpuset_get_dentry(struct dentry *parent, const char *name) +{ + struct dentry *d = lookup_one_len(name, parent, strlen(name)); + if (!IS_ERR(d)) + d->d_op = &cpuset_dops; + return d; +} + +static void remove_dir(struct dentry *d) +{ + struct dentry *parent = dget(d->d_parent); + + d_delete(d); + simple_rmdir(parent->d_inode, d); + dput(parent); +} + +/* + * NOTE : the dentry must have been dget()'ed + */ +static void cpuset_d_remove_dir(struct dentry *dentry) +{ + struct list_head *node; + + spin_lock(&dcache_lock); + node = dentry->d_subdirs.next; + while (node != &dentry->d_subdirs) { + struct dentry *d = list_entry(node, struct dentry, d_u.d_child); + list_del_init(node); + if (d->d_inode) { + d = dget_locked(d); + spin_unlock(&dcache_lock); + d_delete(d); + simple_unlink(dentry->d_inode, d); + dput(d); + spin_lock(&dcache_lock); + } + node = dentry->d_subdirs.next; + } + list_del_init(&dentry->d_u.d_child); + spin_unlock(&dcache_lock); + remove_dir(dentry); +} + +static struct super_operations cpuset_ops = { + .statfs = simple_statfs, + .drop_inode = generic_delete_inode, +}; + +static int cpuset_fill_super(struct super_block *sb, void *unused_data, + int unused_silent) +{ + struct inode *inode; + struct dentry *root; + + sb->s_blocksize = PAGE_CACHE_SIZE; + sb->s_blocksize_bits = PAGE_CACHE_SHIFT; + sb->s_magic = CPUSET_SUPER_MAGIC; + sb->s_op = &cpuset_ops; + cpuset_sb = sb; + + inode = cpuset_new_inode(S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR); + if (inode) { + inode->i_op = &simple_dir_inode_operations; + inode->i_fop = &simple_dir_operations; + /* directories start off with i_nlink == 2 (for "." entry) */ + inc_nlink(inode); + } else { + return -ENOMEM; + } + + root = d_alloc_root(inode); + if (!root) { + iput(inode); + return -ENOMEM; + } + sb->s_root = root; + return 0; +} + static int cpuset_get_sb(struct file_system_type *fs_type, int flags, const char *unused_dev_name, void *data, struct vfsmount *mnt) { - struct file_system_type *cgroup_fs = get_fs_type("cgroup"); - int ret = -ENODEV; - if (cgroup_fs) { - char mountopts[] = - "cpuset,noprefix," - "release_agent=/sbin/cpuset_release_agent"; - ret = cgroup_fs->get_sb(cgroup_fs, flags, - unused_dev_name, mountopts, mnt); - put_filesystem(cgroup_fs); - } - return ret; + return get_sb_single(fs_type, flags, data, cpuset_fill_super, mnt); } static struct file_system_type cpuset_fs_type = { .name = "cpuset", .get_sb = cpuset_get_sb, + .kill_sb = kill_litter_super, }; +/* struct cftype: + * + * The files in the cpuset filesystem mostly have a very simple read/write + * handling, some common function will take care of it. Nevertheless some cases + * (read tasks) are special and therefore I define this structure for every + * kind of file. + * + * + * When reading/writing to a file: + * - the cpuset to use in file->f_path.dentry->d_parent->d_fsdata + * - the 'cftype' of the file is file->f_path.dentry->d_fsdata + */ + +struct cftype { + char *name; + int private; + int (*open) (struct inode *inode, struct file *file); + ssize_t (*read) (struct file *file, char __user *buf, size_t nbytes, + loff_t *ppos); + int (*write) (struct file *file, const char __user *buf, size_t nbytes, + loff_t *ppos); + int (*release) (struct inode *inode, struct file *file); +}; + +static inline struct cpuset *__d_cs(struct dentry *dentry) +{ + return dentry->d_fsdata; +} + +static inline struct cftype *__d_cft(struct dentry *dentry) +{ + return dentry->d_fsdata; +} + +/* + * Call with manage_mutex held. Writes path of cpuset into buf. + * Returns 0 on success, -errno on error. + */ + +static int cpuset_path(const struct cpuset *cs, char *buf, int buflen) +{ + char *start; + + start = buf + buflen; + + *--start = '\0'; + for (;;) { + int len = cs->dentry->d_name.len; + if ((start -= len) < buf) + return -ENAMETOOLONG; + memcpy(start, cs->dentry->d_name.name, len); + cs = cs->parent; + if (!cs) + break; + if (!cs->parent) + continue; + if (--start < buf) + return -ENAMETOOLONG; + *start = '/'; + } + memmove(buf, start, buf + buflen - start); + return 0; +} + +/* + * Notify userspace when a cpuset is released, by running + * /sbin/cpuset_release_agent with the name of the cpuset (path + * relative to the root of cpuset file system) as the argument. + * + * Most likely, this user command will try to rmdir this cpuset. + * + * This races with the possibility that some other task will be + * attached to this cpuset before it is removed, or that some other + * user task will 'mkdir' a child cpuset of this cpuset. That's ok. + * The presumed 'rmdir' will fail quietly if this cpuset is no longer + * unused, and this cpuset will be reprieved from its death sentence, + * to continue to serve a useful existence. Next time it's released, + * we will get notified again, if it still has 'notify_on_release' set. + * + * The final arg to call_usermodehelper() is 0, which means don't + * wait. The separate /sbin/cpuset_release_agent task is forked by + * call_usermodehelper(), then control in this thread returns here, + * without waiting for the release agent task. We don't bother to + * wait because the caller of this routine has no use for the exit + * status of the /sbin/cpuset_release_agent task, so no sense holding + * our caller up for that. + * + * When we had only one cpuset mutex, we had to call this + * without holding it, to avoid deadlock when call_usermodehelper() + * allocated memory. With two locks, we could now call this while + * holding manage_mutex, but we still don't, so as to minimize + * the time manage_mutex is held. + */ + +static void cpuset_release_agent(const char *pathbuf) +{ + char *argv[3], *envp[3]; + int i; + + if (!pathbuf) + return; + + i = 0; + argv[i++] = "/sbin/cpuset_release_agent"; + argv[i++] = (char *)pathbuf; + argv[i] = NULL; + + i = 0; + /* minimal command environment */ + envp[i++] = "HOME=/"; + envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin"; + envp[i] = NULL; + + call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC); + kfree(pathbuf); +} + +/* + * Either cs->count of using tasks transitioned to zero, or the + * cs->children list of child cpusets just became empty. If this + * cs is notify_on_release() and now both the user count is zero and + * the list of children is empty, prepare cpuset path in a kmalloc'd + * buffer, to be returned via ppathbuf, so that the caller can invoke + * cpuset_release_agent() with it later on, once manage_mutex is dropped. + * Call here with manage_mutex held. + * + * This check_for_release() routine is responsible for kmalloc'ing + * pathbuf. The above cpuset_release_agent() is responsible for + * kfree'ing pathbuf. The caller of these routines is responsible + * for providing a pathbuf pointer, initialized to NULL, then + * calling check_for_release() with manage_mutex held and the address + * of the pathbuf pointer, then dropping manage_mutex, then calling + * cpuset_release_agent() with pathbuf, as set by check_for_release(). + */ + +static void check_for_release(struct cpuset *cs, char **ppathbuf) +{ + if (notify_on_release(cs) && atomic_read(&cs->count) == 0 && + list_empty(&cs->children)) { + char *buf; + + buf = kmalloc(PAGE_SIZE, GFP_KERNEL); + if (!buf) + return; + if (cpuset_path(cs, buf, PAGE_SIZE) < 0) + kfree(buf); + else + *ppathbuf = buf; + } +} + /* * Return in *pmask the portion of a cpusets's cpus_allowed that * are online. If none are online, walk up the cpuset hierarchy @@ -390,19 +653,20 @@ void cpuset_update_task_memory_state(void) struct task_struct *tsk = current; struct cpuset *cs; - if (task_cs(tsk) == &top_cpuset) { + if (tsk->cpuset == &top_cpuset) { /* Don't need rcu for top_cpuset. It's never freed. */ my_cpusets_mem_gen = top_cpuset.mems_generation; } else { rcu_read_lock(); - my_cpusets_mem_gen = task_cs(current)->mems_generation; + cs = rcu_dereference(tsk->cpuset); + my_cpusets_mem_gen = cs->mems_generation; rcu_read_unlock(); } if (my_cpusets_mem_gen != tsk->cpuset_mems_generation) { mutex_lock(&callback_mutex); task_lock(tsk); - cs = task_cs(tsk); /* Maybe changed when task not locked */ + cs = tsk->cpuset; /* Maybe changed when task not locked */ guarantee_online_mems(cs, &tsk->mems_allowed); tsk->cpuset_mems_generation = cs->mems_generation; if (is_spread_page(cs)) @@ -457,12 +721,11 @@ static int is_cpuset_subset(const struct cpuset *p, const struct cpuset *q) static int validate_change(const struct cpuset *cur, const struct cpuset *trial) { - struct cgroup *cont; struct cpuset *c, *par; /* Each of our child cpusets must be a subset of us */ - list_for_each_entry(cont, &cur->css.cgroup->children, sibling) { - if (!is_cpuset_subset(cgroup_cs(cont), trial)) + list_for_each_entry(c, &cur->children, sibling) { + if (!is_cpuset_subset(c, trial)) return -EBUSY; } @@ -477,8 +740,7 @@ static int validate_change(const struct cpuset *cur, const struct cpuset *trial) return -EACCES; /* If either I or some sibling (!= me) is exclusive, we can't overlap */ - list_for_each_entry(cont, &par->css.cgroup->children, sibling) { - c = cgroup_cs(cont); + list_for_each_entry(c, &par->children, sibling) { if ((is_cpu_exclusive(trial) || is_cpu_exclusive(c)) && c != cur && cpus_intersects(trial->cpus_allowed, c->cpus_allowed)) @@ -489,249 +751,9 @@ static int validate_change(const struct cpuset *cur, const struct cpuset *trial) return -EINVAL; } - /* Cpusets with tasks can't have empty cpus_allowed or mems_allowed */ - if (cgroup_task_count(cur->css.cgroup)) { - if (cpus_empty(trial->cpus_allowed) || - nodes_empty(trial->mems_allowed)) { - return -ENOSPC; - } - } - return 0; } -/* - * Helper routine for rebuild_sched_domains(). - * Do cpusets a, b have overlapping cpus_allowed masks? - */ - -static int cpusets_overlap(struct cpuset *a, struct cpuset *b) -{ - return cpus_intersects(a->cpus_allowed, b->cpus_allowed); -} - -/* - * rebuild_sched_domains() - * - * If the flag 'sched_load_balance' of any cpuset with non-empty - * 'cpus' changes, or if the 'cpus' allowed changes in any cpuset - * which has that flag enabled, or if any cpuset with a non-empty - * 'cpus' is removed, then call this routine to rebuild the - * scheduler's dynamic sched domains. - * - * This routine builds a partial partition of the systems CPUs - * (the set of non-overlappping cpumask_t's in the array 'part' - * below), and passes that partial partition to the kernel/sched.c - * partition_sched_domains() routine, which will rebuild the - * schedulers load balancing domains (sched domains) as specified - * by that partial partition. A 'partial partition' is a set of - * non-overlapping subsets whose union is a subset of that set. - * - * See "What is sched_load_balance" in Documentation/cpusets.txt - * for a background explanation of this. - * - * Does not return errors, on the theory that the callers of this - * routine would rather not worry about failures to rebuild sched - * domains when operating in the severe memory shortage situations - * that could cause allocation failures below. - * - * Call with cgroup_mutex held. May take callback_mutex during - * call due to the kfifo_alloc() and kmalloc() calls. May nest - * a call to the lock_cpu_hotplug()/unlock_cpu_hotplug() pair. - * Must not be called holding callback_mutex, because we must not - * call lock_cpu_hotplug() while holding callback_mutex. Elsewhere - * the kernel nests callback_mutex inside lock_cpu_hotplug() calls. - * So the reverse nesting would risk an ABBA deadlock. - * - * The three key local variables below are: - * q - a kfifo queue of cpuset pointers, used to implement a - * top-down scan of all cpusets. This scan loads a pointer - * to each cpuset marked is_sched_load_balance into the - * array 'csa'. For our purposes, rebuilding the schedulers - * sched domains, we can ignore !is_sched_load_balance cpusets. - * csa - (for CpuSet Array) Array of pointers to all the cpusets - * that need to be load balanced, for convenient iterative - * access by the subsequent code that finds the best partition, - * i.e the set of domains (subsets) of CPUs such that the - * cpus_allowed of every cpuset marked is_sched_load_balance - * is a subset of one of these domains, while there are as - * many such domains as possible, each as small as possible. - * doms - Conversion of 'csa' to an array of cpumasks, for passing to - * the kernel/sched.c routine partition_sched_domains() in a - * convenient format, that can be easily compared to the prior - * value to determine what partition elements (sched domains) - * were changed (added or removed.) - * - * Finding the best partition (set of domains): - * The triple nested loops below over i, j, k scan over the - * load balanced cpusets (using the array of cpuset pointers in - * csa[]) looking for pairs of cpusets that have overlapping - * cpus_allowed, but which don't have the same 'pn' partition - * number and gives them in the same partition number. It keeps - * looping on the 'restart' label until it can no longer find - * any such pairs. - * - * The union of the cpus_allowed masks from the set of - * all cpusets having the same 'pn' value then form the one - * element of the partition (one sched domain) to be passed to - * partition_sched_domains(). - */ - -static void rebuild_sched_domains(void) -{ - struct kfifo *q; /* queue of cpusets to be scanned */ - struct cpuset *cp; /* scans q */ - struct cpuset **csa; /* array of all cpuset ptrs */ - int csn; /* how many cpuset ptrs in csa so far */ - int i, j, k; /* indices for partition finding loops */ - cpumask_t *doms; /* resulting partition; i.e. sched domains */ - int ndoms; /* number of sched domains in result */ - int nslot; /* next empty doms[] cpumask_t slot */ - - q = NULL; - csa = NULL; - doms = NULL; - - /* Special case for the 99% of systems with one, full, sched domain */ - if (is_sched_load_balance(&top_cpuset)) { - ndoms = 1; - doms = kmalloc(sizeof(cpumask_t), GFP_KERNEL); - if (!doms) - goto rebuild; - *doms = top_cpuset.cpus_allowed; - goto rebuild; - } - - q = kfifo_alloc(number_of_cpusets * sizeof(cp), GFP_KERNEL, NULL); - if (IS_ERR(q)) - goto done; - csa = kmalloc(number_of_cpusets * sizeof(cp), GFP_KERNEL); - if (!csa) - goto done; - csn = 0; - - cp = &top_cpuset; - __kfifo_put(q, (void *)&cp, sizeof(cp)); - while (__kfifo_get(q, (void *)&cp, sizeof(cp))) { - struct cgroup *cont; - struct cpuset *child; /* scans child cpusets of cp */ - if (is_sched_load_balance(cp)) - csa[csn++] = cp; - list_for_each_entry(cont, &cp->css.cgroup->children, sibling) { - child = cgroup_cs(cont); - __kfifo_put(q, (void *)&child, sizeof(cp)); - } - } - - for (i = 0; i < csn; i++) - csa[i]->pn = i; - ndoms = csn; - -restart: - /* Find the best partition (set of sched domains) */ - for (i = 0; i < csn; i++) { - struct cpuset *a = csa[i]; - int apn = a->pn; - - for (j = 0; j < csn; j++) { - struct cpuset *b = csa[j]; - int bpn = b->pn; - - if (apn != bpn && cpusets_overlap(a, b)) { - for (k = 0; k < csn; k++) { - struct cpuset *c = csa[k]; - - if (c->pn == bpn) - c->pn = apn; - } - ndoms--; /* one less element */ - goto restart; - } - } - } - - /* Convert to */ - doms = kmalloc(ndoms * sizeof(cpumask_t), GFP_KERNEL); - if (!doms) - goto rebuild; - - for (nslot = 0, i = 0; i < csn; i++) { - struct cpuset *a = csa[i]; - int apn = a->pn; - - if (apn >= 0) { - cpumask_t *dp = doms + nslot; - - if (nslot == ndoms) { - static int warnings = 10; - if (warnings) { - printk(KERN_WARNING - "rebuild_sched_domains confused:" - " nslot %d, ndoms %d, csn %d, i %d," - " apn %d\n", - nslot, ndoms, csn, i, apn); - warnings--; - } - continue; - } - - cpus_clear(*dp); - for (j = i; j < csn; j++) { - struct cpuset *b = csa[j]; - - if (apn == b->pn) { - cpus_or(*dp, *dp, b->cpus_allowed); - b->pn = -1; - } - } - nslot++; - } - } - BUG_ON(nslot != ndoms); - -rebuild: - /* Have scheduler rebuild sched domains */ - lock_cpu_hotplug(); - partition_sched_domains(ndoms, doms); - unlock_cpu_hotplug(); - -done: - if (q && !IS_ERR(q)) - kfifo_free(q); - kfree(csa); - /* Don't kfree(doms) -- partition_sched_domains() does that. */ -} - -static inline int started_after_time(struct task_struct *t1, - struct timespec *time, - struct task_struct *t2) -{ - int start_diff = timespec_compare(&t1->start_time, time); - if (start_diff > 0) { - return 1; - } else if (start_diff < 0) { - return 0; - } else { - /* - * Arbitrarily, if two processes started at the same - * time, we'll say that the lower pointer value - * started first. Note that t2 may have exited by now - * so this may not be a valid pointer any longer, but - * that's fine - it still serves to distinguish - * between two tasks started (effectively) - * simultaneously. - */ - return t1 > t2; - } -} - -static inline int started_after(void *p1, void *p2) -{ - struct task_struct *t1 = p1; - struct task_struct *t2 = p2; - return started_after_time(t1, &t2->start_time, t2); -} - /* * Call with manage_mutex held. May take callback_mutex during call. */ @@ -739,15 +761,7 @@ static inline int started_after(void *p1, void *p2) static int update_cpumask(struct cpuset *cs, char *buf) { struct cpuset trialcs; - int retval, i; - int is_load_balanced; - struct cgroup_iter it; - struct cgroup *cgrp = cs->css.cgroup; - struct task_struct *p, *dropped; - /* Never dereference latest_task, since it's not refcounted */ - struct task_struct *latest_task = NULL; - struct ptr_heap heap; - struct timespec latest_time = { 0, 0 }; + int retval; /* top_cpuset.cpus_allowed tracks cpu_online_map; it's read-only */ if (cs == &top_cpuset) @@ -756,13 +770,11 @@ static int update_cpumask(struct cpuset *cs, char *buf) trialcs = *cs; /* - * An empty cpus_allowed is ok iff there are no tasks in the cpuset. - * Since cpulist_parse() fails on an empty mask, we special case - * that parsing. The validate_change() call ensures that cpusets - * with tasks have cpus. + * We allow a cpuset's cpus_allowed to be empty; if it has attached + * tasks, we'll catch it later when we validate the change and return + * -ENOSPC. */ - buf = strstrip(buf); - if (!*buf) { + if (!buf[0] || (buf[0] == '\n' && !buf[1])) { cpus_clear(trialcs.cpus_allowed); } else { retval = cpulist_parse(buf, trialcs.cpus_allowed); @@ -770,79 +782,15 @@ static int update_cpumask(struct cpuset *cs, char *buf) return retval; } cpus_and(trialcs.cpus_allowed, trialcs.cpus_allowed, cpu_online_map); + /* cpus_allowed cannot be empty for a cpuset with attached tasks. */ + if (atomic_read(&cs->count) && cpus_empty(trialcs.cpus_allowed)) + return -ENOSPC; retval = validate_change(cs, &trialcs); if (retval < 0) return retval; - - /* Nothing to do if the cpus didn't change */ - if (cpus_equal(cs->cpus_allowed, trialcs.cpus_allowed)) - return 0; - retval = heap_init(&heap, PAGE_SIZE, GFP_KERNEL, &started_after); - if (retval) - return retval; - - is_load_balanced = is_sched_load_balance(&trialcs); - mutex_lock(&callback_mutex); cs->cpus_allowed = trialcs.cpus_allowed; mutex_unlock(&callback_mutex); - - again: - /* - * Scan tasks in the cpuset, and update the cpumasks of any - * that need an update. Since we can't call set_cpus_allowed() - * while holding tasklist_lock, gather tasks to be processed - * in a heap structure. If the statically-sized heap fills up, - * overflow tasks that started later, and in future iterations - * only consider tasks that started after the latest task in - * the previous pass. This guarantees forward progress and - * that we don't miss any tasks - */ - heap.size = 0; - cgroup_iter_start(cgrp, &it); - while ((p = cgroup_iter_next(cgrp, &it))) { - /* Only affect tasks that don't have the right cpus_allowed */ - if (cpus_equal(p->cpus_allowed, cs->cpus_allowed)) - continue; - /* - * Only process tasks that started after the last task - * we processed - */ - if (!started_after_time(p, &latest_time, latest_task)) - continue; - dropped = heap_insert(&heap, p); - if (dropped == NULL) { - get_task_struct(p); - } else if (dropped != p) { - get_task_struct(p); - put_task_struct(dropped); - } - } - cgroup_iter_end(cgrp, &it); - if (heap.size) { - for (i = 0; i < heap.size; i++) { - struct task_struct *p = heap.ptrs[i]; - if (i == 0) { - latest_time = p->start_time; - latest_task = p; - } - set_cpus_allowed(p, cs->cpus_allowed); - put_task_struct(p); - } - /* - * If we had to process any tasks at all, scan again - * in case some of them were in the middle of forking - * children that didn't notice the new cpumask - * restriction. Not the most efficient way to do it, - * but it avoids having to take callback_mutex in the - * fork path - */ - goto again; - } - heap_free(&heap); - if (is_load_balanced) - rebuild_sched_domains(); - return 0; } @@ -891,7 +839,7 @@ static void cpuset_migrate_mm(struct mm_struct *mm, const nodemask_t *from, do_migrate_pages(mm, from, to, MPOL_MF_MOVE_ALL); mutex_lock(&callback_mutex); - guarantee_online_mems(task_cs(tsk),&tsk->mems_allowed); + guarantee_online_mems(tsk->cpuset, &tsk->mems_allowed); mutex_unlock(&callback_mutex); } @@ -909,19 +857,16 @@ static void cpuset_migrate_mm(struct mm_struct *mm, const nodemask_t *from, * their mempolicies to the cpusets new mems_allowed. */ -static void *cpuset_being_rebound; - static int update_nodemask(struct cpuset *cs, char *buf) { struct cpuset trialcs; nodemask_t oldmem; - struct task_struct *p; + struct task_struct *g, *p; struct mm_struct **mmarray; int i, n, ntasks; int migrate; int fudge; int retval; - struct cgroup_iter it; /* * top_cpuset.mems_allowed tracks node_stats[N_HIGH_MEMORY]; @@ -933,19 +878,29 @@ static int update_nodemask(struct cpuset *cs, char *buf) trialcs = *cs; /* - * An empty mems_allowed is ok iff there are no tasks in the cpuset. - * Since nodelist_parse() fails on an empty mask, we special case - * that parsing. The validate_change() call ensures that cpusets - * with tasks have memory. + * We allow a cpuset's mems_allowed to be empty; if it has attached + * tasks, we'll catch it later when we validate the change and return + * -ENOSPC. */ - buf = strstrip(buf); - if (!*buf) { + if (!buf[0] || (buf[0] == '\n' && !buf[1])) { nodes_clear(trialcs.mems_allowed); } else { retval = nodelist_parse(buf, trialcs.mems_allowed); if (retval < 0) goto done; + if (!nodes_intersects(trialcs.mems_allowed, + node_states[N_HIGH_MEMORY])) { + /* + * error if only memoryless nodes specified. + */ + retval = -ENOSPC; + goto done; + } } + /* + * Exclude memoryless nodes. We know that trialcs.mems_allowed + * contains at least one node with memory. + */ nodes_and(trialcs.mems_allowed, trialcs.mems_allowed, node_states[N_HIGH_MEMORY]); oldmem = cs->mems_allowed; @@ -953,6 +908,11 @@ static int update_nodemask(struct cpuset *cs, char *buf) retval = 0; /* Too easy - nothing to do */ goto done; } + /* mems_allowed cannot be empty for a cpuset with attached tasks. */ + if (atomic_read(&cs->count) && nodes_empty(trialcs.mems_allowed)) { + retval = -ENOSPC; + goto done; + } retval = validate_change(cs, &trialcs); if (retval < 0) goto done; @@ -962,7 +922,7 @@ static int update_nodemask(struct cpuset *cs, char *buf) cs->mems_generation = cpuset_mems_generation++; mutex_unlock(&callback_mutex); - cpuset_being_rebound = cs; /* causes mpol_copy() rebind */ + set_cpuset_being_rebound(cs); /* causes mpol_copy() rebind */ fudge = 10; /* spare mmarray[] slots */ fudge += cpus_weight(cs->cpus_allowed); /* imagine one fork-bomb/cpu */ @@ -976,13 +936,13 @@ static int update_nodemask(struct cpuset *cs, char *buf) * enough mmarray[] w/o using GFP_ATOMIC. */ while (1) { - ntasks = cgroup_task_count(cs->css.cgroup); /* guess */ + ntasks = atomic_read(&cs->count); /* guess */ ntasks += fudge; mmarray = kmalloc(ntasks * sizeof(*mmarray), GFP_KERNEL); if (!mmarray) goto done; read_lock(&tasklist_lock); /* block fork */ - if (cgroup_task_count(cs->css.cgroup) <= ntasks) + if (atomic_read(&cs->count) <= ntasks) break; /* got enough */ read_unlock(&tasklist_lock); /* try again */ kfree(mmarray); @@ -991,21 +951,21 @@ static int update_nodemask(struct cpuset *cs, char *buf) n = 0; /* Load up mmarray[] with mm reference for each task in cpuset. */ - cgroup_iter_start(cs->css.cgroup, &it); - while ((p = cgroup_iter_next(cs->css.cgroup, &it))) { + do_each_thread(g, p) { struct mm_struct *mm; if (n >= ntasks) { printk(KERN_WARNING "Cpuset mempolicy rebind incomplete.\n"); - break; + continue; } + if (p->cpuset != cs) + continue; mm = get_task_mm(p); if (!mm) continue; mmarray[n++] = mm; - } - cgroup_iter_end(cs->css.cgroup, &it); + } while_each_thread(g, p); read_unlock(&tasklist_lock); /* @@ -1033,17 +993,12 @@ static int update_nodemask(struct cpuset *cs, char *buf) /* We're done rebinding vma's to this cpusets new mems_allowed. */ kfree(mmarray); - cpuset_being_rebound = NULL; + set_cpuset_being_rebound(NULL); retval = 0; done: return retval; } -int current_cpuset_is_being_rebound(void) -{ - return task_cs(current) == cpuset_being_rebound; -} - /* * Call with manage_mutex held. */ @@ -1060,7 +1015,6 @@ static int update_memory_pressure_enabled(struct cpuset *cs, char *buf) /* * update_flag - read a 0 or a 1 in a file and update associated flag * bit: the bit to update (CS_CPU_EXCLUSIVE, CS_MEM_EXCLUSIVE, - * CS_SCHED_LOAD_BALANCE, * CS_NOTIFY_ON_RELEASE, CS_MEMORY_MIGRATE, * CS_SPREAD_PAGE, CS_SPREAD_SLAB) * cs: the cpuset to update @@ -1074,7 +1028,6 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs, char *buf) int turning_on; struct cpuset trialcs; int err; - int cpus_nonempty, balance_flag_changed; turning_on = (simple_strtoul(buf, NULL, 10) != 0); @@ -1087,18 +1040,10 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs, char *buf) err = validate_change(cs, &trialcs); if (err < 0) return err; - - cpus_nonempty = !cpus_empty(trialcs.cpus_allowed); - balance_flag_changed = (is_sched_load_balance(cs) != - is_sched_load_balance(&trialcs)); - mutex_lock(&callback_mutex); cs->flags = trialcs.flags; mutex_unlock(&callback_mutex); - if (cpus_nonempty && balance_flag_changed) - rebuild_sched_domains(); - return 0; } @@ -1200,34 +1145,85 @@ static int fmeter_getrate(struct fmeter *fmp) return val; } -static int cpuset_can_attach(struct cgroup_subsys *ss, - struct cgroup *cont, struct task_struct *tsk) +/* + * Attack task specified by pid in 'pidbuf' to cpuset 'cs', possibly + * writing the path of the old cpuset in 'ppathbuf' if it needs to be + * notified on release. + * + * Call holding manage_mutex. May take callback_mutex and task_lock of + * the task 'pid' during call. + */ + +static int attach_task(struct cpuset *cs, char *pidbuf, char **ppathbuf) { - struct cpuset *cs = cgroup_cs(cont); + pid_t pid; + struct task_struct *tsk; + struct cpuset *oldcs; + cpumask_t cpus; + nodemask_t from, to; + struct mm_struct *mm; + int retval; + if (sscanf(pidbuf, "%d", &pid) != 1) + return -EIO; if (cpus_empty(cs->cpus_allowed) || nodes_empty(cs->mems_allowed)) return -ENOSPC; - return security_task_setscheduler(tsk, 0, NULL); -} + if (pid) { + read_lock(&tasklist_lock); -static void cpuset_attach(struct cgroup_subsys *ss, - struct cgroup *cont, struct cgroup *oldcont, - struct task_struct *tsk) -{ - cpumask_t cpus; - nodemask_t from, to; - struct mm_struct *mm; - struct cpuset *cs = cgroup_cs(cont); - struct cpuset *oldcs = cgroup_cs(oldcont); + tsk = find_task_by_pid(pid); + if (!tsk || tsk->flags & PF_EXITING) { + read_unlock(&tasklist_lock); + return -ESRCH; + } + + get_task_struct(tsk); + read_unlock(&tasklist_lock); + + if ((current->euid) && (current->euid != tsk->uid) + && (current->euid != tsk->suid)) { + put_task_struct(tsk); + return -EACCES; + } + } else { + tsk = current; + get_task_struct(tsk); + } + + retval = security_task_setscheduler(tsk, 0, NULL); + if (retval) { + put_task_struct(tsk); + return retval; + } mutex_lock(&callback_mutex); + + task_lock(tsk); + oldcs = tsk->cpuset; + /* + * After getting 'oldcs' cpuset ptr, be sure still not exiting. + * If 'oldcs' might be the top_cpuset due to the_top_cpuset_hack + * then fail this attach_task(), to avoid breaking top_cpuset.count. + */ + if (tsk->flags & PF_EXITING) { + task_unlock(tsk); + mutex_unlock(&callback_mutex); + put_task_struct(tsk); + return -ESRCH; + } + atomic_inc(&cs->count); + rcu_assign_pointer(tsk->cpuset, cs); + task_unlock(tsk); + guarantee_online_cpus(cs, &cpus); set_cpus_allowed(tsk, cpus); - mutex_unlock(&callback_mutex); from = oldcs->mems_allowed; to = cs->mems_allowed; + + mutex_unlock(&callback_mutex); + mm = get_task_mm(tsk); if (mm) { mpol_rebind_mm(mm, &to); @@ -1236,36 +1232,44 @@ static void cpuset_attach(struct cgroup_subsys *ss, mmput(mm); } + put_task_struct(tsk); + synchronize_rcu(); + if (atomic_dec_and_test(&oldcs->count)) + check_for_release(oldcs, ppathbuf); + return 0; } /* The various types of files and directories in a cpuset file system */ typedef enum { + FILE_ROOT, + FILE_DIR, FILE_MEMORY_MIGRATE, FILE_CPULIST, FILE_MEMLIST, FILE_CPU_EXCLUSIVE, FILE_MEM_EXCLUSIVE, - FILE_SCHED_LOAD_BALANCE, + FILE_NOTIFY_ON_RELEASE, FILE_MEMORY_PRESSURE_ENABLED, FILE_MEMORY_PRESSURE, FILE_SPREAD_PAGE, FILE_SPREAD_SLAB, + FILE_TASKLIST, } cpuset_filetype_t; -static ssize_t cpuset_common_file_write(struct cgroup *cont, - struct cftype *cft, - struct file *file, +static ssize_t cpuset_common_file_write(struct file *file, const char __user *userbuf, size_t nbytes, loff_t *unused_ppos) { - struct cpuset *cs = cgroup_cs(cont); + struct cpuset *cs = __d_cs(file->f_path.dentry->d_parent); + struct cftype *cft = __d_cft(file->f_path.dentry); cpuset_filetype_t type = cft->private; char *buffer; + char *pathbuf = NULL; int retval = 0; /* Crude upper limit on largest legitimate cpulist user might write. */ - if (nbytes > 100U + 6 * max(NR_CPUS, MAX_NUMNODES)) + if (nbytes > 100 + 6 * max(NR_CPUS, MAX_NUMNODES)) return -E2BIG; /* +1 for nul-terminator */ @@ -1278,9 +1282,9 @@ static ssize_t cpuset_common_file_write(struct cgroup *cont, } buffer[nbytes] = 0; /* nul-terminate */ - cgroup_lock(); + mutex_lock(&manage_mutex); - if (cgroup_is_removed(cont)) { + if (is_removed(cs)) { retval = -ENODEV; goto out2; } @@ -1298,8 +1302,8 @@ static ssize_t cpuset_common_file_write(struct cgroup *cont, case FILE_MEM_EXCLUSIVE: retval = update_flag(CS_MEM_EXCLUSIVE, cs, buffer); break; - case FILE_SCHED_LOAD_BALANCE: - retval = update_flag(CS_SCHED_LOAD_BALANCE, cs, buffer); + case FILE_NOTIFY_ON_RELEASE: + retval = update_flag(CS_NOTIFY_ON_RELEASE, cs, buffer); break; case FILE_MEMORY_MIGRATE: retval = update_flag(CS_MEMORY_MIGRATE, cs, buffer); @@ -1318,6 +1322,9 @@ static ssize_t cpuset_common_file_write(struct cgroup *cont, retval = update_flag(CS_SPREAD_SLAB, cs, buffer); cs->mems_generation = cpuset_mems_generation++; break; + case FILE_TASKLIST: + retval = attach_task(cs, buffer, &pathbuf); + break; default: retval = -EINVAL; goto out2; @@ -1326,12 +1333,30 @@ static ssize_t cpuset_common_file_write(struct cgroup *cont, if (retval == 0) retval = nbytes; out2: - cgroup_unlock(); + mutex_unlock(&manage_mutex); + cpuset_release_agent(pathbuf); out1: kfree(buffer); return retval; } +static ssize_t cpuset_file_write(struct file *file, const char __user *buf, + size_t nbytes, loff_t *ppos) +{ + ssize_t retval = 0; + struct cftype *cft = __d_cft(file->f_path.dentry); + if (!cft) + return -ENODEV; + + /* special function ? */ + if (cft->write) + retval = cft->write(file, buf, nbytes, ppos); + else + retval = cpuset_common_file_write(file, buf, nbytes, ppos); + + return retval; +} + /* * These ascii lists should be read in a single call, by using a user * buffer large enough to hold the entire map. If read in smaller @@ -1366,13 +1391,11 @@ static int cpuset_sprintf_memlist(char *page, struct cpuset *cs) return nodelist_scnprintf(page, PAGE_SIZE, mask); } -static ssize_t cpuset_common_file_read(struct cgroup *cont, - struct cftype *cft, - struct file *file, - char __user *buf, - size_t nbytes, loff_t *ppos) +static ssize_t cpuset_common_file_read(struct file *file, char __user *buf, + size_t nbytes, loff_t *ppos) { - struct cpuset *cs = cgroup_cs(cont); + struct cftype *cft = __d_cft(file->f_path.dentry); + struct cpuset *cs = __d_cs(file->f_path.dentry->d_parent); cpuset_filetype_t type = cft->private; char *page; ssize_t retval = 0; @@ -1396,8 +1419,8 @@ static ssize_t cpuset_common_file_read(struct cgroup *cont, case FILE_MEM_EXCLUSIVE: *s++ = is_mem_exclusive(cs) ? '1' : '0'; break; - case FILE_SCHED_LOAD_BALANCE: - *s++ = is_sched_load_balance(cs) ? '1' : '0'; + case FILE_NOTIFY_ON_RELEASE: + *s++ = notify_on_release(cs) ? '1' : '0'; break; case FILE_MEMORY_MIGRATE: *s++ = is_memory_migrate(cs) ? '1' : '0'; @@ -1426,149 +1449,389 @@ static ssize_t cpuset_common_file_read(struct cgroup *cont, return retval; } +static ssize_t cpuset_file_read(struct file *file, char __user *buf, size_t nbytes, + loff_t *ppos) +{ + ssize_t retval = 0; + struct cftype *cft = __d_cft(file->f_path.dentry); + if (!cft) + return -ENODEV; + + /* special function ? */ + if (cft->read) + retval = cft->read(file, buf, nbytes, ppos); + else + retval = cpuset_common_file_read(file, buf, nbytes, ppos); + + return retval; +} +static int cpuset_file_open(struct inode *inode, struct file *file) +{ + int err; + struct cftype *cft; + err = generic_file_open(inode, file); + if (err) + return err; + cft = __d_cft(file->f_path.dentry); + if (!cft) + return -ENODEV; + if (cft->open) + err = cft->open(inode, file); + else + err = 0; + + return err; +} + +static int cpuset_file_release(struct inode *inode, struct file *file) +{ + struct cftype *cft = __d_cft(file->f_path.dentry); + if (cft->release) + return cft->release(inode, file); + return 0; +} + +/* + * cpuset_rename - Only allow simple rename of directories in place. + */ +static int cpuset_rename(struct inode *old_dir, struct dentry *old_dentry, + struct inode *new_dir, struct dentry *new_dentry) +{ + if (!S_ISDIR(old_dentry->d_inode->i_mode)) + return -ENOTDIR; + if (new_dentry->d_inode) + return -EEXIST; + if (old_dir != new_dir) + return -EIO; + return simple_rename(old_dir, old_dentry, new_dir, new_dentry); +} + +static const struct file_operations cpuset_file_operations = { + .read = cpuset_file_read, + .write = cpuset_file_write, + .llseek = generic_file_llseek, + .open = cpuset_file_open, + .release = cpuset_file_release, +}; + +static const struct inode_operations cpuset_dir_inode_operations = { + .lookup = simple_lookup, + .mkdir = cpuset_mkdir, + .rmdir = cpuset_rmdir, + .rename = cpuset_rename, +}; + +static int cpuset_create_file(struct dentry *dentry, int mode) +{ + struct inode *inode; + + if (!dentry) + return -ENOENT; + if (dentry->d_inode) + return -EEXIST; + + inode = cpuset_new_inode(mode); + if (!inode) + return -ENOMEM; + + if (S_ISDIR(mode)) { + inode->i_op = &cpuset_dir_inode_operations; + inode->i_fop = &simple_dir_operations; + + /* start off with i_nlink == 2 (for "." entry) */ + inc_nlink(inode); + } else if (S_ISREG(mode)) { + inode->i_size = 0; + inode->i_fop = &cpuset_file_operations; + } + + d_instantiate(dentry, inode); + dget(dentry); /* Extra count - pin the dentry in core */ + return 0; +} + +/* + * cpuset_create_dir - create a directory for an object. + * cs: the cpuset we create the directory for. + * It must have a valid ->parent field + * And we are going to fill its ->dentry field. + * name: The name to give to the cpuset directory. Will be copied. + * mode: mode to set on new directory. + */ + +static int cpuset_create_dir(struct cpuset *cs, const char *name, int mode) +{ + struct dentry *dentry = NULL; + struct dentry *parent; + int error = 0; + + parent = cs->parent->dentry; + dentry = cpuset_get_dentry(parent, name); + if (IS_ERR(dentry)) + return PTR_ERR(dentry); + error = cpuset_create_file(dentry, S_IFDIR | mode); + if (!error) { + dentry->d_fsdata = cs; + inc_nlink(parent->d_inode); + cs->dentry = dentry; + } + dput(dentry); + + return error; +} + +static int cpuset_add_file(struct dentry *dir, const struct cftype *cft) +{ + struct dentry *dentry; + int error; + + mutex_lock(&dir->d_inode->i_mutex); + dentry = cpuset_get_dentry(dir, cft->name); + if (!IS_ERR(dentry)) { + error = cpuset_create_file(dentry, 0644 | S_IFREG); + if (!error) + dentry->d_fsdata = (void *)cft; + dput(dentry); + } else + error = PTR_ERR(dentry); + mutex_unlock(&dir->d_inode->i_mutex); + return error; +} + +/* + * Stuff for reading the 'tasks' file. + * + * Reading this file can return large amounts of data if a cpuset has + * *lots* of attached tasks. So it may need several calls to read(), + * but we cannot guarantee that the information we produce is correct + * unless we produce it entirely atomically. + * + * Upon tasks file open(), a struct ctr_struct is allocated, that + * will have a pointer to an array (also allocated here). The struct + * ctr_struct * is stored in file->private_data. Its resources will + * be freed by release() when the file is closed. The array is used + * to sprintf the PIDs and then used by read(). + */ + +/* cpusets_tasks_read array */ + +struct ctr_struct { + char *buf; + int bufsz; +}; + +/* + * Load into 'pidarray' up to 'npids' of the tasks using cpuset 'cs'. + * Return actual number of pids loaded. No need to task_lock(p) + * when reading out p->cpuset, as we don't really care if it changes + * on the next cycle, and we are not going to try to dereference it. + */ +static int pid_array_load(pid_t *pidarray, int npids, struct cpuset *cs) +{ + int n = 0; + struct task_struct *g, *p; + + read_lock(&tasklist_lock); + + do_each_thread(g, p) { + if (p->cpuset == cs) { + if (unlikely(n == npids)) + goto array_full; + pidarray[n++] = p->pid; + } + } while_each_thread(g, p); + +array_full: + read_unlock(&tasklist_lock); + return n; +} + +static int cmppid(const void *a, const void *b) +{ + return *(pid_t *)a - *(pid_t *)b; +} + +/* + * Convert array 'a' of 'npids' pid_t's to a string of newline separated + * decimal pids in 'buf'. Don't write more than 'sz' chars, but return + * count 'cnt' of how many chars would be written if buf were large enough. + */ +static int pid_array_to_buf(char *buf, int sz, pid_t *a, int npids) +{ + int cnt = 0; + int i; + + for (i = 0; i < npids; i++) + cnt += snprintf(buf + cnt, max(sz - cnt, 0), "%d\n", a[i]); + return cnt; +} + +/* + * Handle an open on 'tasks' file. Prepare a buffer listing the + * process id's of tasks currently attached to the cpuset being opened. + * + * Does not require any specific cpuset mutexes, and does not take any. + */ +static int cpuset_tasks_open(struct inode *unused, struct file *file) +{ + struct cpuset *cs = __d_cs(file->f_path.dentry->d_parent); + struct ctr_struct *ctr; + pid_t *pidarray; + int npids; + char c; + + if (!(file->f_mode & FMODE_READ)) + return 0; + + ctr = kmalloc(sizeof(*ctr), GFP_KERNEL); + if (!ctr) + goto err0; + + /* + * If cpuset gets more users after we read count, we won't have + * enough space - tough. This race is indistinguishable to the + * caller from the case that the additional cpuset users didn't + * show up until sometime later on. + */ + npids = atomic_read(&cs->count); + pidarray = kmalloc(npids * sizeof(pid_t), GFP_KERNEL); + if (!pidarray) + goto err1; + + npids = pid_array_load(pidarray, npids, cs); + sort(pidarray, npids, sizeof(pid_t), cmppid, NULL); + + /* Call pid_array_to_buf() twice, first just to get bufsz */ + ctr->bufsz = pid_array_to_buf(&c, sizeof(c), pidarray, npids) + 1; + ctr->buf = kmalloc(ctr->bufsz, GFP_KERNEL); + if (!ctr->buf) + goto err2; + ctr->bufsz = pid_array_to_buf(ctr->buf, ctr->bufsz, pidarray, npids); + + kfree(pidarray); + file->private_data = ctr; + return 0; + +err2: + kfree(pidarray); +err1: + kfree(ctr); +err0: + return -ENOMEM; +} + +static ssize_t cpuset_tasks_read(struct file *file, char __user *buf, + size_t nbytes, loff_t *ppos) +{ + struct ctr_struct *ctr = file->private_data; + + return simple_read_from_buffer(buf, nbytes, ppos, ctr->buf, ctr->bufsz); +} + +static int cpuset_tasks_release(struct inode *unused_inode, struct file *file) +{ + struct ctr_struct *ctr; + + if (file->f_mode & FMODE_READ) { + ctr = file->private_data; + kfree(ctr->buf); + kfree(ctr); + } + return 0; +} /* * for the common functions, 'private' gives the type of file */ +static struct cftype cft_tasks = { + .name = "tasks", + .open = cpuset_tasks_open, + .read = cpuset_tasks_read, + .release = cpuset_tasks_release, + .private = FILE_TASKLIST, +}; + static struct cftype cft_cpus = { .name = "cpus", - .read = cpuset_common_file_read, - .write = cpuset_common_file_write, .private = FILE_CPULIST, }; static struct cftype cft_mems = { .name = "mems", - .read = cpuset_common_file_read, - .write = cpuset_common_file_write, .private = FILE_MEMLIST, }; static struct cftype cft_cpu_exclusive = { .name = "cpu_exclusive", - .read = cpuset_common_file_read, - .write = cpuset_common_file_write, .private = FILE_CPU_EXCLUSIVE, }; static struct cftype cft_mem_exclusive = { .name = "mem_exclusive", - .read = cpuset_common_file_read, - .write = cpuset_common_file_write, .private = FILE_MEM_EXCLUSIVE, }; -static struct cftype cft_sched_load_balance = { - .name = "sched_load_balance", - .read = cpuset_common_file_read, - .write = cpuset_common_file_write, - .private = FILE_SCHED_LOAD_BALANCE, +static struct cftype cft_notify_on_release = { + .name = "notify_on_release", + .private = FILE_NOTIFY_ON_RELEASE, }; static struct cftype cft_memory_migrate = { .name = "memory_migrate", - .read = cpuset_common_file_read, - .write = cpuset_common_file_write, .private = FILE_MEMORY_MIGRATE, }; static struct cftype cft_memory_pressure_enabled = { .name = "memory_pressure_enabled", - .read = cpuset_common_file_read, - .write = cpuset_common_file_write, .private = FILE_MEMORY_PRESSURE_ENABLED, }; static struct cftype cft_memory_pressure = { .name = "memory_pressure", - .read = cpuset_common_file_read, - .write = cpuset_common_file_write, .private = FILE_MEMORY_PRESSURE, }; static struct cftype cft_spread_page = { .name = "memory_spread_page", - .read = cpuset_common_file_read, - .write = cpuset_common_file_write, .private = FILE_SPREAD_PAGE, }; static struct cftype cft_spread_slab = { .name = "memory_spread_slab", - .read = cpuset_common_file_read, - .write = cpuset_common_file_write, .private = FILE_SPREAD_SLAB, }; -static int cpuset_populate(struct cgroup_subsys *ss, struct cgroup *cont) +static int cpuset_populate_dir(struct dentry *cs_dentry) { int err; - if ((err = cgroup_add_file(cont, ss, &cft_cpus)) < 0) + if ((err = cpuset_add_file(cs_dentry, &cft_cpus)) < 0) return err; - if ((err = cgroup_add_file(cont, ss, &cft_mems)) < 0) + if ((err = cpuset_add_file(cs_dentry, &cft_mems)) < 0) return err; - if ((err = cgroup_add_file(cont, ss, &cft_cpu_exclusive)) < 0) + if ((err = cpuset_add_file(cs_dentry, &cft_cpu_exclusive)) < 0) return err; - if ((err = cgroup_add_file(cont, ss, &cft_mem_exclusive)) < 0) + if ((err = cpuset_add_file(cs_dentry, &cft_mem_exclusive)) < 0) return err; - if ((err = cgroup_add_file(cont, ss, &cft_memory_migrate)) < 0) + if ((err = cpuset_add_file(cs_dentry, &cft_notify_on_release)) < 0) return err; - if ((err = cgroup_add_file(cont, ss, &cft_sched_load_balance)) < 0) + if ((err = cpuset_add_file(cs_dentry, &cft_memory_migrate)) < 0) return err; - if ((err = cgroup_add_file(cont, ss, &cft_memory_pressure)) < 0) + if ((err = cpuset_add_file(cs_dentry, &cft_memory_pressure)) < 0) return err; - if ((err = cgroup_add_file(cont, ss, &cft_spread_page)) < 0) + if ((err = cpuset_add_file(cs_dentry, &cft_spread_page)) < 0) return err; - if ((err = cgroup_add_file(cont, ss, &cft_spread_slab)) < 0) + if ((err = cpuset_add_file(cs_dentry, &cft_spread_slab)) < 0) + return err; + if ((err = cpuset_add_file(cs_dentry, &cft_tasks)) < 0) return err; - /* memory_pressure_enabled is in root cpuset only */ - if (err == 0 && !cont->parent) - err = cgroup_add_file(cont, ss, - &cft_memory_pressure_enabled); return 0; } -/* - * post_clone() is called at the end of cgroup_clone(). - * 'cgroup' was just created automatically as a result of - * a cgroup_clone(), and the current task is about to - * be moved into 'cgroup'. - * - * Currently we refuse to set up the cgroup - thereby - * refusing the task to be entered, and as a result refusing - * the sys_unshare() or clone() which initiated it - if any - * sibling cpusets have exclusive cpus or mem. - * - * If this becomes a problem for some users who wish to - * allow that scenario, then cpuset_post_clone() could be - * changed to grant parent->cpus_allowed-sibling_cpus_exclusive - * (and likewise for mems) to the new cgroup. - */ -static void cpuset_post_clone(struct cgroup_subsys *ss, - struct cgroup *cgroup) -{ - struct cgroup *parent, *child; - struct cpuset *cs, *parent_cs; - - parent = cgroup->parent; - list_for_each_entry(child, &parent->children, sibling) { - cs = cgroup_cs(child); - if (is_mem_exclusive(cs) || is_cpu_exclusive(cs)) - return; - } - cs = cgroup_cs(cgroup); - parent_cs = cgroup_cs(parent); - - cs->mems_allowed = parent_cs->mems_allowed; - cs->cpus_allowed = parent_cs->cpus_allowed; - return; -} - /* * cpuset_create - create a cpuset * parent: cpuset that will be parent of the new cpuset. @@ -1578,77 +1841,106 @@ static void cpuset_post_clone(struct cgroup_subsys *ss, * Must be called with the mutex on the parent inode held */ -static struct cgroup_subsys_state *cpuset_create( - struct cgroup_subsys *ss, - struct cgroup *cont) +static long cpuset_create(struct cpuset *parent, const char *name, int mode) { struct cpuset *cs; - struct cpuset *parent; + int err; - if (!cont->parent) { - /* This is early initialization for the top cgroup */ - top_cpuset.mems_generation = cpuset_mems_generation++; - return &top_cpuset.css; - } - parent = cgroup_cs(cont->parent); cs = kmalloc(sizeof(*cs), GFP_KERNEL); if (!cs) - return ERR_PTR(-ENOMEM); + return -ENOMEM; + mutex_lock(&manage_mutex); cpuset_update_task_memory_state(); cs->flags = 0; + if (notify_on_release(parent)) + set_bit(CS_NOTIFY_ON_RELEASE, &cs->flags); if (is_spread_page(parent)) set_bit(CS_SPREAD_PAGE, &cs->flags); if (is_spread_slab(parent)) set_bit(CS_SPREAD_SLAB, &cs->flags); - set_bit(CS_SCHED_LOAD_BALANCE, &cs->flags); cs->cpus_allowed = CPU_MASK_NONE; cs->mems_allowed = NODE_MASK_NONE; + atomic_set(&cs->count, 0); + INIT_LIST_HEAD(&cs->sibling); + INIT_LIST_HEAD(&cs->children); cs->mems_generation = cpuset_mems_generation++; fmeter_init(&cs->fmeter); cs->parent = parent; + + mutex_lock(&callback_mutex); + list_add(&cs->sibling, &cs->parent->children); number_of_cpusets++; - return &cs->css ; -} + mutex_unlock(&callback_mutex); -/* - * Locking note on the strange update_flag() call below: - * - * If the cpuset being removed has its flag 'sched_load_balance' - * enabled, then simulate turning sched_load_balance off, which - * will call rebuild_sched_domains(). The lock_cpu_hotplug() - * call in rebuild_sched_domains() must not be made while holding - * callback_mutex. Elsewhere the kernel nests callback_mutex inside - * lock_cpu_hotplug() calls. So the reverse nesting would risk an - * ABBA deadlock. - */ + err = cpuset_create_dir(cs, name, mode); + if (err < 0) + goto err; + + /* + * Release manage_mutex before cpuset_populate_dir() because it + * will down() this new directory's i_mutex and if we race with + * another mkdir, we might deadlock. + */ + mutex_unlock(&manage_mutex); + + err = cpuset_populate_dir(cs->dentry); + /* If err < 0, we have a half-filled directory - oh well ;) */ + return 0; +err: + list_del(&cs->sibling); + mutex_unlock(&manage_mutex); + kfree(cs); + return err; +} -static void cpuset_destroy(struct cgroup_subsys *ss, struct cgroup *cont) +static int cpuset_mkdir(struct inode *dir, struct dentry *dentry, int mode) { - struct cpuset *cs = cgroup_cs(cont); + struct cpuset *c_parent = dentry->d_parent->d_fsdata; - cpuset_update_task_memory_state(); + /* the vfs holds inode->i_mutex already */ + return cpuset_create(c_parent, dentry->d_name.name, mode | S_IFDIR); +} - if (is_sched_load_balance(cs)) - update_flag(CS_SCHED_LOAD_BALANCE, cs, "0"); +static int cpuset_rmdir(struct inode *unused_dir, struct dentry *dentry) +{ + struct cpuset *cs = dentry->d_fsdata; + struct dentry *d; + struct cpuset *parent; + char *pathbuf = NULL; + + /* the vfs holds both inode->i_mutex already */ + mutex_lock(&manage_mutex); + cpuset_update_task_memory_state(); + if (atomic_read(&cs->count) > 0) { + mutex_unlock(&manage_mutex); + return -EBUSY; + } + if (!list_empty(&cs->children)) { + mutex_unlock(&manage_mutex); + return -EBUSY; + } + parent = cs->parent; + mutex_lock(&callback_mutex); + set_bit(CS_REMOVED, &cs->flags); + list_del(&cs->sibling); /* delete my sibling from parent->children */ + spin_lock(&cs->dentry->d_lock); + d = dget(cs->dentry); + cs->dentry = NULL; + spin_unlock(&d->d_lock); + cpuset_d_remove_dir(d); + dput(d); number_of_cpusets--; - kfree(cs); + mutex_unlock(&callback_mutex); + if (list_empty(&parent->children)) + check_for_release(parent, &pathbuf); + mutex_unlock(&manage_mutex); + cpuset_release_agent(pathbuf); + return 0; } -struct cgroup_subsys cpuset_subsys = { - .name = "cpuset", - .create = cpuset_create, - .destroy = cpuset_destroy, - .can_attach = cpuset_can_attach, - .attach = cpuset_attach, - .populate = cpuset_populate, - .post_clone = cpuset_post_clone, - .subsys_id = cpuset_subsys_id, - .early_init = 1, -}; - /* * cpuset_init_early - just enough so that the calls to * cpuset_update_task_memory_state() in early init code @@ -1657,11 +1949,13 @@ struct cgroup_subsys cpuset_subsys = { int __init cpuset_init_early(void) { - top_cpuset.mems_generation = cpuset_mems_generation++; + struct task_struct *tsk = current; + + tsk->cpuset = &top_cpuset; + tsk->cpuset->mems_generation = cpuset_mems_generation++; return 0; } - /** * cpuset_init - initialize cpusets at system boot * @@ -1670,21 +1964,39 @@ int __init cpuset_init_early(void) int __init cpuset_init(void) { - int err = 0; + struct dentry *root; + int err; top_cpuset.cpus_allowed = CPU_MASK_ALL; top_cpuset.mems_allowed = NODE_MASK_ALL; fmeter_init(&top_cpuset.fmeter); top_cpuset.mems_generation = cpuset_mems_generation++; - set_bit(CS_SCHED_LOAD_BALANCE, &top_cpuset.flags); + + init_task.cpuset = &top_cpuset; err = register_filesystem(&cpuset_fs_type); if (err < 0) - return err; - + goto out; + cpuset_mount = kern_mount(&cpuset_fs_type); + if (IS_ERR(cpuset_mount)) { + printk(KERN_ERR "cpuset: could not mount!\n"); + err = PTR_ERR(cpuset_mount); + cpuset_mount = NULL; + goto out; + } + root = cpuset_mount->mnt_sb->s_root; + root->d_fsdata = &top_cpuset; + inc_nlink(root->d_inode); + top_cpuset.dentry = root; + root->d_inode->i_op = &cpuset_dir_inode_operations; number_of_cpusets = 1; - return 0; + err = cpuset_populate_dir(root); + /* memory_pressure_enabled is in root cpuset only */ + if (err == 0) + err = cpuset_add_file(root, &cft_memory_pressure_enabled); +out: + return err; } /* @@ -1710,12 +2022,10 @@ int __init cpuset_init(void) static void guarantee_online_cpus_mems_in_subtree(const struct cpuset *cur) { - struct cgroup *cont; struct cpuset *c; /* Each of our child cpusets mems must be online */ - list_for_each_entry(cont, &cur->css.cgroup->children, sibling) { - c = cgroup_cs(cont); + list_for_each_entry(c, &cur->children, sibling) { guarantee_online_cpus_mems_in_subtree(c); if (!cpus_empty(c->cpus_allowed)) guarantee_online_cpus(c, &c->cpus_allowed); @@ -1743,7 +2053,7 @@ static void guarantee_online_cpus_mems_in_subtree(const struct cpuset *cur) static void common_cpu_mem_hotplug_unplug(void) { - cgroup_lock(); + mutex_lock(&manage_mutex); mutex_lock(&callback_mutex); guarantee_online_cpus_mems_in_subtree(&top_cpuset); @@ -1751,7 +2061,7 @@ static void common_cpu_mem_hotplug_unplug(void) top_cpuset.mems_allowed = node_states[N_HIGH_MEMORY]; mutex_unlock(&callback_mutex); - cgroup_unlock(); + mutex_unlock(&manage_mutex); } /* @@ -1764,8 +2074,8 @@ static void common_cpu_mem_hotplug_unplug(void) * cpu_online_map on each CPU hotplug (cpuhp) event. */ -static int cpuset_handle_cpuhp(struct notifier_block *unused_nb, - unsigned long phase, void *unused_cpu) +static int cpuset_handle_cpuhp(struct notifier_block *nb, + unsigned long phase, void *cpu) { if (phase == CPU_DYING || phase == CPU_DYING_FROZEN) return NOTIFY_DONE; @@ -1803,7 +2113,109 @@ void __init cpuset_init_smp(void) } /** + * cpuset_fork - attach newly forked task to its parents cpuset. + * @tsk: pointer to task_struct of forking parent process. + * + * Description: A task inherits its parent's cpuset at fork(). + * + * A pointer to the shared cpuset was automatically copied in fork.c + * by dup_task_struct(). However, we ignore that copy, since it was + * not made under the protection of task_lock(), so might no longer be + * a valid cpuset pointer. attach_task() might have already changed + * current->cpuset, allowing the previously referenced cpuset to + * be removed and freed. Instead, we task_lock(current) and copy + * its present value of current->cpuset for our freshly forked child. + * + * At the point that cpuset_fork() is called, 'current' is the parent + * task, and the passed argument 'child' points to the child task. + **/ + +void cpuset_fork(struct task_struct *child) +{ + task_lock(current); + child->cpuset = current->cpuset; + atomic_inc(&child->cpuset->count); + task_unlock(current); +} + +/** + * cpuset_exit - detach cpuset from exiting task + * @tsk: pointer to task_struct of exiting process + * + * Description: Detach cpuset from @tsk and release it. + * + * Note that cpusets marked notify_on_release force every task in + * them to take the global manage_mutex mutex when exiting. + * This could impact scaling on very large systems. Be reluctant to + * use notify_on_release cpusets where very high task exit scaling + * is required on large systems. + * + * Don't even think about derefencing 'cs' after the cpuset use count + * goes to zero, except inside a critical section guarded by manage_mutex + * or callback_mutex. Otherwise a zero cpuset use count is a license to + * any other task to nuke the cpuset immediately, via cpuset_rmdir(). + * + * This routine has to take manage_mutex, not callback_mutex, because + * it is holding that mutex while calling check_for_release(), + * which calls kmalloc(), so can't be called holding callback_mutex(). + * + * the_top_cpuset_hack: + * + * Set the exiting tasks cpuset to the root cpuset (top_cpuset). + * + * Don't leave a task unable to allocate memory, as that is an + * accident waiting to happen should someone add a callout in + * do_exit() after the cpuset_exit() call that might allocate. + * If a task tries to allocate memory with an invalid cpuset, + * it will oops in cpuset_update_task_memory_state(). + * + * We call cpuset_exit() while the task is still competent to + * handle notify_on_release(), then leave the task attached to + * the root cpuset (top_cpuset) for the remainder of its exit. + * + * To do this properly, we would increment the reference count on + * top_cpuset, and near the very end of the kernel/exit.c do_exit() + * code we would add a second cpuset function call, to drop that + * reference. This would just create an unnecessary hot spot on + * the top_cpuset reference count, to no avail. + * + * Normally, holding a reference to a cpuset without bumping its + * count is unsafe. The cpuset could go away, or someone could + * attach us to a different cpuset, decrementing the count on + * the first cpuset that we never incremented. But in this case, + * top_cpuset isn't going away, and either task has PF_EXITING set, + * which wards off any attach_task() attempts, or task is a failed + * fork, never visible to attach_task. + * + * Another way to do this would be to set the cpuset pointer + * to NULL here, and check in cpuset_update_task_memory_state() + * for a NULL pointer. This hack avoids that NULL check, for no + * cost (other than this way too long comment ;). + **/ + +void cpuset_exit(struct task_struct *tsk) +{ + struct cpuset *cs; + + task_lock(current); + cs = tsk->cpuset; + tsk->cpuset = &top_cpuset; /* the_top_cpuset_hack - see above */ + task_unlock(current); + + if (notify_on_release(cs)) { + char *pathbuf = NULL; + mutex_lock(&manage_mutex); + if (atomic_dec_and_test(&cs->count)) + check_for_release(cs, &pathbuf); + mutex_unlock(&manage_mutex); + cpuset_release_agent(pathbuf); + } else { + atomic_dec(&cs->count); + } +} + +/** * cpuset_cpus_allowed - return cpus_allowed mask from a tasks cpuset. * @tsk: pointer to task_struct from which to obtain cpuset->cpus_allowed. * @@ -1818,23 +2230,10 @@ cpumask_t cpuset_cpus_allowed(struct task_struct *tsk) cpumask_t mask; mutex_lock(&callback_mutex); - mask = cpuset_cpus_allowed_locked(tsk); - mutex_unlock(&callback_mutex); - - return mask; -} - -/** - * cpuset_cpus_allowed_locked - return cpus_allowed mask from a tasks cpuset. - * Must be called with callback_mutex held. - **/ -cpumask_t cpuset_cpus_allowed_locked(struct task_struct *tsk) -{ - cpumask_t mask; - task_lock(tsk); - guarantee_online_cpus(task_cs(tsk), &mask); + guarantee_online_cpus(tsk->cpuset, &mask); task_unlock(tsk); + mutex_unlock(&callback_mutex); return mask; } @@ -1860,7 +2259,7 @@ nodemask_t cpuset_mems_allowed(struct task_struct *tsk) mutex_lock(&callback_mutex); task_lock(tsk); - guarantee_online_mems(task_cs(tsk), &mask); + guarantee_online_mems(tsk->cpuset, &mask); task_unlock(tsk); mutex_unlock(&callback_mutex); @@ -1991,7 +2390,7 @@ int __cpuset_zone_allowed_softwall(struct zone *z, gfp_t gfp_mask) mutex_lock(&callback_mutex); task_lock(current); - cs = nearest_exclusive_ancestor(task_cs(current)); + cs = nearest_exclusive_ancestor(current->cpuset); task_unlock(current); allowed = node_isset(node, cs->mems_allowed); @@ -2032,12 +2431,12 @@ int __cpuset_zone_allowed_hardwall(struct zone *z, gfp_t gfp_mask) node = zone_to_nid(z); if (node_isset(node, current->mems_allowed)) return 1; - /* - * Allow tasks that have access to memory reserves because they have - * been OOM killed to get memory anywhere. - */ - if (unlikely(test_thread_flag(TIF_MEMDIE))) - return 1; + /* + * Allow tasks that have access to memory reserves because they have + * been OOM killed to get memory anywhere. + */ + if (unlikely(test_thread_flag(TIF_MEMDIE))) + return 1; return 0; } @@ -2151,12 +2550,14 @@ int cpuset_memory_pressure_enabled __read_mostly; void __cpuset_memory_pressure_bump(void) { + struct cpuset *cs; + task_lock(current); - fmeter_markevent(&task_cs(current)->fmeter); + cs = current->cpuset; + fmeter_markevent(&cs->fmeter); task_unlock(current); } -#ifdef CONFIG_PROC_PID_CPUSET /* * proc_cpuset_show() * - Print tasks cpuset path into seq_file. @@ -2168,12 +2569,11 @@ void __cpuset_memory_pressure_bump(void) * the_top_cpuset_hack in cpuset_exit(), which sets an exiting tasks * cpuset to top_cpuset. */ -static int proc_cpuset_show(struct seq_file *m, void *unused_v) +static int proc_cpuset_show(struct seq_file *m, void *v) { struct pid *pid; struct task_struct *tsk; char *buf; - struct cgroup_subsys_state *css; int retval; retval = -ENOMEM; @@ -2188,15 +2588,15 @@ static int proc_cpuset_show(struct seq_file *m, void *unused_v) goto out_free; retval = -EINVAL; - cgroup_lock(); - css = task_subsys_state(tsk, cpuset_subsys_id); - retval = cgroup_path(css->cgroup, buf, PAGE_SIZE); + mutex_lock(&manage_mutex); + + retval = cpuset_path(tsk->cpuset, buf, PAGE_SIZE); if (retval < 0) goto out_unlock; seq_puts(m, buf); seq_putc(m, '\n'); out_unlock: - cgroup_unlock(); + mutex_unlock(&manage_mutex); put_task_struct(tsk); out_free: kfree(buf); @@ -2216,7 +2616,6 @@ const struct file_operations proc_cpuset_operations = { .llseek = seq_lseek, .release = single_release, }; -#endif /* CONFIG_PROC_PID_CPUSET */ /* Display task cpus_allowed, mems_allowed in /proc//status file. */ char *cpuset_task_status_allowed(struct task_struct *task, char *buffer) diff --git a/trunk/kernel/delayacct.c b/trunk/kernel/delayacct.c index 10e43fd8b721..09e9574eeb26 100644 --- a/trunk/kernel/delayacct.c +++ b/trunk/kernel/delayacct.c @@ -115,12 +115,6 @@ int __delayacct_add_tsk(struct taskstats *d, struct task_struct *tsk) tmp += timespec_to_ns(&ts); d->cpu_run_real_total = (tmp < (s64)d->cpu_run_real_total) ? 0 : tmp; - tmp = (s64)d->cpu_scaled_run_real_total; - cputime_to_timespec(tsk->utimescaled + tsk->stimescaled, &ts); - tmp += timespec_to_ns(&ts); - d->cpu_scaled_run_real_total = - (tmp < (s64)d->cpu_scaled_run_real_total) ? 0 : tmp; - /* * No locking available for sched_info (and too expensive to add one) * Mitigate by taking snapshot of values diff --git a/trunk/kernel/die_notifier.c b/trunk/kernel/die_notifier.c new file mode 100644 index 000000000000..0d98827887a7 --- /dev/null +++ b/trunk/kernel/die_notifier.c @@ -0,0 +1,38 @@ + +#include +#include +#include +#include + + +static ATOMIC_NOTIFIER_HEAD(die_chain); + +int notify_die(enum die_val val, const char *str, + struct pt_regs *regs, long err, int trap, int sig) +{ + struct die_args args = { + .regs = regs, + .str = str, + .err = err, + .trapnr = trap, + .signr = sig, + + }; + + return atomic_notifier_call_chain(&die_chain, val, &args); +} + +int register_die_notifier(struct notifier_block *nb) +{ + vmalloc_sync_all(); + return atomic_notifier_chain_register(&die_chain, nb); +} +EXPORT_SYMBOL_GPL(register_die_notifier); + +int unregister_die_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_unregister(&die_chain, nb); +} +EXPORT_SYMBOL_GPL(unregister_die_notifier); + + diff --git a/trunk/kernel/dma.c b/trunk/kernel/dma.c index 6a82bb716dac..937b13ca33ba 100644 --- a/trunk/kernel/dma.c +++ b/trunk/kernel/dma.c @@ -20,7 +20,7 @@ #include #include - + /* A note on resource allocation: * @@ -95,7 +95,7 @@ void free_dma(unsigned int dmanr) if (xchg(&dma_chan_busy[dmanr].lock, 0) == 0) { printk(KERN_WARNING "Trying to free free DMA%d\n", dmanr); return; - } + } } /* free_dma */ @@ -121,8 +121,8 @@ static int proc_dma_show(struct seq_file *m, void *v) for (i = 0 ; i < MAX_DMA_CHANNELS ; i++) { if (dma_chan_busy[i].lock) { - seq_printf(m, "%2d: %s\n", i, - dma_chan_busy[i].device_id); + seq_printf(m, "%2d: %s\n", i, + dma_chan_busy[i].device_id); } } return 0; diff --git a/trunk/kernel/exec_domain.c b/trunk/kernel/exec_domain.c index a9e6bad9f706..3c2eaea66b1e 100644 --- a/trunk/kernel/exec_domain.c +++ b/trunk/kernel/exec_domain.c @@ -57,7 +57,7 @@ lookup_exec_domain(u_long personality) { struct exec_domain * ep; u_long pers = personality(personality); - + read_lock(&exec_domains_lock); for (ep = exec_domains; ep; ep = ep->next) { if (pers >= ep->pers_low && pers <= ep->pers_high) diff --git a/trunk/kernel/exit.c b/trunk/kernel/exit.c index f1aec27f1df0..2c704c86edb3 100644 --- a/trunk/kernel/exit.c +++ b/trunk/kernel/exit.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include #include @@ -148,7 +148,6 @@ void release_task(struct task_struct * p) int zap_leader; repeat: atomic_dec(&p->user->processes); - proc_flush_task(p); write_lock_irq(&tasklist_lock); ptrace_unlink(p); BUG_ON(!list_empty(&p->ptrace_list) || !list_empty(&p->ptrace_children)); @@ -176,6 +175,7 @@ void release_task(struct task_struct * p) } write_unlock_irq(&tasklist_lock); + proc_flush_task(p); release_thread(p); call_rcu(&p->rcu, delayed_put_task_struct); @@ -221,7 +221,7 @@ static int will_become_orphaned_pgrp(struct pid *pgrp, struct task_struct *ignor do_each_pid_task(pgrp, PIDTYPE_PGID, p) { if (p == ignored_task || p->exit_state - || is_global_init(p->real_parent)) + || is_init(p->real_parent)) continue; if (task_pgrp(p->real_parent) != pgrp && task_session(p->real_parent) == task_session(p)) { @@ -299,14 +299,14 @@ void __set_special_pids(pid_t session, pid_t pgrp) { struct task_struct *curr = current->group_leader; - if (task_session_nr(curr) != session) { + if (process_session(curr) != session) { detach_pid(curr, PIDTYPE_SID); - set_task_session(curr, session); + set_signal_session(curr->signal, session); attach_pid(curr, PIDTYPE_SID, find_pid(session)); } - if (task_pgrp_nr(curr) != pgrp) { + if (process_group(curr) != pgrp) { detach_pid(curr, PIDTYPE_PGID); - set_task_pgrp(curr, pgrp); + curr->signal->pgrp = pgrp; attach_pid(curr, PIDTYPE_PGID, find_pid(pgrp)); } } @@ -400,12 +400,11 @@ void daemonize(const char *name, ...) current->fs = fs; atomic_inc(&fs->count); - if (current->nsproxy != init_task.nsproxy) { - get_nsproxy(init_task.nsproxy); - switch_task_namespaces(current, init_task.nsproxy); - } + exit_task_namespaces(current); + current->nsproxy = init_task.nsproxy; + get_task_namespaces(current); - exit_files(current); + exit_files(current); current->files = init_task.files; atomic_inc(¤t->files->count); @@ -493,7 +492,7 @@ void reset_files_struct(struct task_struct *tsk, struct files_struct *files) } EXPORT_SYMBOL(reset_files_struct); -static void __exit_files(struct task_struct *tsk) +static inline void __exit_files(struct task_struct *tsk) { struct files_struct * files = tsk->files; @@ -510,7 +509,7 @@ void exit_files(struct task_struct *tsk) __exit_files(tsk); } -static void __put_fs_struct(struct fs_struct *fs) +static inline void __put_fs_struct(struct fs_struct *fs) { /* No need to hold fs->lock if we are killing it */ if (atomic_dec_and_test(&fs->count)) { @@ -531,7 +530,7 @@ void put_fs_struct(struct fs_struct *fs) __put_fs_struct(fs); } -static void __exit_fs(struct task_struct *tsk) +static inline void __exit_fs(struct task_struct *tsk) { struct fs_struct * fs = tsk->fs; @@ -666,22 +665,19 @@ reparent_thread(struct task_struct *p, struct task_struct *father, int traced) * the child reaper process (ie "init") in our pid * space. */ -static void forget_original_parent(struct task_struct *father) +static void +forget_original_parent(struct task_struct *father, struct list_head *to_release) { - struct task_struct *p, *n, *reaper = father; - struct list_head ptrace_dead; - - INIT_LIST_HEAD(&ptrace_dead); - - write_lock_irq(&tasklist_lock); + struct task_struct *p, *reaper = father; + struct list_head *_p, *_n; do { reaper = next_thread(reaper); if (reaper == father) { - reaper = task_child_reaper(father); + reaper = child_reaper(father); break; } - } while (reaper->flags & PF_EXITING); + } while (reaper->exit_state); /* * There are only two places where our children can be: @@ -691,8 +687,9 @@ static void forget_original_parent(struct task_struct *father) * * Search them and reparent children. */ - list_for_each_entry_safe(p, n, &father->children, sibling) { + list_for_each_safe(_p, _n, &father->children) { int ptrace; + p = list_entry(_p, struct task_struct, sibling); ptrace = p->ptrace; @@ -718,23 +715,13 @@ static void forget_original_parent(struct task_struct *father) * while it was being traced by us, to be able to see it in wait4. */ if (unlikely(ptrace && p->exit_state == EXIT_ZOMBIE && p->exit_signal == -1)) - list_add(&p->ptrace_list, &ptrace_dead); + list_add(&p->ptrace_list, to_release); } - - list_for_each_entry_safe(p, n, &father->ptrace_children, ptrace_list) { + list_for_each_safe(_p, _n, &father->ptrace_children) { + p = list_entry(_p, struct task_struct, ptrace_list); p->real_parent = reaper; reparent_thread(p, father, 1); } - - write_unlock_irq(&tasklist_lock); - BUG_ON(!list_empty(&father->children)); - BUG_ON(!list_empty(&father->ptrace_children)); - - list_for_each_entry_safe(p, n, &ptrace_dead, ptrace_list) { - list_del_init(&p->ptrace_list); - release_task(p); - } - } /* @@ -745,6 +732,7 @@ static void exit_notify(struct task_struct *tsk) { int state; struct task_struct *t; + struct list_head ptrace_dead, *_p, *_n; struct pid *pgrp; if (signal_pending(tsk) && !(tsk->signal->flags & SIGNAL_GROUP_EXIT) @@ -765,6 +753,8 @@ static void exit_notify(struct task_struct *tsk) spin_unlock_irq(&tsk->sighand->siglock); } + write_lock_irq(&tasklist_lock); + /* * This does two things: * @@ -773,10 +763,12 @@ static void exit_notify(struct task_struct *tsk) * as a result of our exiting, and if they have any stopped * jobs, send them a SIGHUP and then a SIGCONT. (POSIX 3.2.2.2) */ - forget_original_parent(tsk); - exit_task_namespaces(tsk); - write_lock_irq(&tasklist_lock); + INIT_LIST_HEAD(&ptrace_dead); + forget_original_parent(tsk, &ptrace_dead); + BUG_ON(!list_empty(&tsk->children)); + BUG_ON(!list_empty(&tsk->ptrace_children)); + /* * Check to see if any process groups have become orphaned * as a result of our exiting, and if they have any stopped @@ -800,7 +792,7 @@ static void exit_notify(struct task_struct *tsk) /* Let father know we died * * Thread signals are configurable, but you aren't going to use - * that to send signals to arbitary processes. + * that to send signals to arbitary processes. * That stops right now. * * If the parent exec id doesn't match the exec id we saved @@ -841,6 +833,12 @@ static void exit_notify(struct task_struct *tsk) write_unlock_irq(&tasklist_lock); + list_for_each_safe(_p, _n, &ptrace_dead) { + list_del_init(_p); + t = list_entry(_p, struct task_struct, ptrace_list); + release_task(t); + } + /* If the process is dead, release it - nobody will wait for it */ if (state == EXIT_DEAD) release_task(tsk); @@ -876,35 +874,10 @@ static inline void check_stack_usage(void) {} static inline void exit_child_reaper(struct task_struct *tsk) { - if (likely(tsk->group_leader != task_child_reaper(tsk))) + if (likely(tsk->group_leader != child_reaper(tsk))) return; - if (tsk->nsproxy->pid_ns == &init_pid_ns) - panic("Attempted to kill init!"); - - /* - * @tsk is the last thread in the 'cgroup-init' and is exiting. - * Terminate all remaining processes in the namespace and reap them - * before exiting @tsk. - * - * Note that @tsk (last thread of cgroup-init) may not necessarily - * be the child-reaper (i.e main thread of cgroup-init) of the - * namespace i.e the child_reaper may have already exited. - * - * Even after a child_reaper exits, we let it inherit orphaned children, - * because, pid_ns->child_reaper remains valid as long as there is - * at least one living sub-thread in the cgroup init. - - * This living sub-thread of the cgroup-init will be notified when - * a child inherited by the 'child-reaper' exits (do_notify_parent() - * uses __group_send_sig_info()). Further, when reaping child processes, - * do_wait() iterates over children of all living sub threads. - - * i.e even though 'child_reaper' thread is listed as the parent of the - * orphaned children, any living sub-thread in the cgroup-init can - * perform the role of the child_reaper. - */ - zap_pid_ns_processes(tsk->nsproxy->pid_ns); + panic("Attempted to kill init!"); } fastcall NORET_TYPE void do_exit(long code) @@ -959,7 +932,7 @@ fastcall NORET_TYPE void do_exit(long code) if (unlikely(in_atomic())) printk(KERN_INFO "note: %s[%d] exited with preempt_count %d\n", - current->comm, task_pid_nr(current), + current->comm, current->pid, preempt_count()); acct_update_integrals(tsk); @@ -999,7 +972,7 @@ fastcall NORET_TYPE void do_exit(long code) __exit_fs(tsk); check_stack_usage(); exit_thread(); - cgroup_exit(tsk, 1); + cpuset_exit(tsk); exit_keys(tsk); if (group_dead && tsk->signal->leader) @@ -1010,6 +983,7 @@ fastcall NORET_TYPE void do_exit(long code) module_put(tsk->binfmt->module); proc_exit_connector(tsk); + exit_task_namespaces(tsk); exit_notify(tsk); #ifdef CONFIG_NUMA mpol_free(tsk->mempolicy); @@ -1112,17 +1086,15 @@ asmlinkage void sys_exit_group(int error_code) static int eligible_child(pid_t pid, int options, struct task_struct *p) { int err; - struct pid_namespace *ns; - ns = current->nsproxy->pid_ns; if (pid > 0) { - if (task_pid_nr_ns(p, ns) != pid) + if (p->pid != pid) return 0; } else if (!pid) { - if (task_pgrp_nr_ns(p, ns) != task_pgrp_vnr(current)) + if (process_group(p) != process_group(current)) return 0; } else if (pid != -1) { - if (task_pgrp_nr_ns(p, ns) != -pid) + if (process_group(p) != -pid) return 0; } @@ -1192,12 +1164,9 @@ static int wait_task_zombie(struct task_struct *p, int noreap, { unsigned long state; int retval, status, traced; - struct pid_namespace *ns; - - ns = current->nsproxy->pid_ns; if (unlikely(noreap)) { - pid_t pid = task_pid_nr_ns(p, ns); + pid_t pid = p->pid; uid_t uid = p->uid; int exit_code = p->exit_code; int why, status; @@ -1316,11 +1285,11 @@ static int wait_task_zombie(struct task_struct *p, int noreap, retval = put_user(status, &infop->si_status); } if (!retval && infop) - retval = put_user(task_pid_nr_ns(p, ns), &infop->si_pid); + retval = put_user(p->pid, &infop->si_pid); if (!retval && infop) retval = put_user(p->uid, &infop->si_uid); if (!retval) - retval = task_pid_nr_ns(p, ns); + retval = p->pid; if (traced) { write_lock_irq(&tasklist_lock); @@ -1357,7 +1326,6 @@ static int wait_task_stopped(struct task_struct *p, int delayed_group_leader, int __user *stat_addr, struct rusage __user *ru) { int retval, exit_code; - struct pid_namespace *ns; if (!p->exit_code) return 0; @@ -1376,12 +1344,11 @@ static int wait_task_stopped(struct task_struct *p, int delayed_group_leader, * keep holding onto the tasklist_lock while we call getrusage and * possibly take page faults for user memory. */ - ns = current->nsproxy->pid_ns; get_task_struct(p); read_unlock(&tasklist_lock); if (unlikely(noreap)) { - pid_t pid = task_pid_nr_ns(p, ns); + pid_t pid = p->pid; uid_t uid = p->uid; int why = (p->ptrace & PT_PTRACED) ? CLD_TRAPPED : CLD_STOPPED; @@ -1452,11 +1419,11 @@ static int wait_task_stopped(struct task_struct *p, int delayed_group_leader, if (!retval && infop) retval = put_user(exit_code, &infop->si_status); if (!retval && infop) - retval = put_user(task_pid_nr_ns(p, ns), &infop->si_pid); + retval = put_user(p->pid, &infop->si_pid); if (!retval && infop) retval = put_user(p->uid, &infop->si_uid); if (!retval) - retval = task_pid_nr_ns(p, ns); + retval = p->pid; put_task_struct(p); BUG_ON(!retval); @@ -1476,7 +1443,6 @@ static int wait_task_continued(struct task_struct *p, int noreap, int retval; pid_t pid; uid_t uid; - struct pid_namespace *ns; if (!(p->signal->flags & SIGNAL_STOP_CONTINUED)) return 0; @@ -1491,8 +1457,7 @@ static int wait_task_continued(struct task_struct *p, int noreap, p->signal->flags &= ~SIGNAL_STOP_CONTINUED; spin_unlock_irq(&p->sighand->siglock); - ns = current->nsproxy->pid_ns; - pid = task_pid_nr_ns(p, ns); + pid = p->pid; uid = p->uid; get_task_struct(p); read_unlock(&tasklist_lock); @@ -1503,7 +1468,7 @@ static int wait_task_continued(struct task_struct *p, int noreap, if (!retval && stat_addr) retval = put_user(0xffff, stat_addr); if (!retval) - retval = task_pid_nr_ns(p, ns); + retval = p->pid; } else { retval = wait_noreap_copyout(p, pid, uid, CLD_CONTINUED, SIGCONT, @@ -1552,9 +1517,12 @@ static long do_wait(pid_t pid, int options, struct siginfo __user *infop, tsk = current; do { struct task_struct *p; + struct list_head *_p; int ret; - list_for_each_entry(p, &tsk->children, sibling) { + list_for_each(_p,&tsk->children) { + p = list_entry(_p, struct task_struct, sibling); + ret = eligible_child(pid, options, p); if (!ret) continue; @@ -1636,8 +1604,9 @@ static long do_wait(pid_t pid, int options, struct siginfo __user *infop, } } if (!flag) { - list_for_each_entry(p, &tsk->ptrace_children, - ptrace_list) { + list_for_each(_p, &tsk->ptrace_children) { + p = list_entry(_p, struct task_struct, + ptrace_list); if (!eligible_child(pid, options, p)) continue; flag = 1; diff --git a/trunk/kernel/fork.c b/trunk/kernel/fork.c index ddafdfac9456..490495a39c7e 100644 --- a/trunk/kernel/fork.c +++ b/trunk/kernel/fork.c @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include #include @@ -50,7 +50,6 @@ #include #include #include -#include #include #include @@ -117,7 +116,7 @@ EXPORT_SYMBOL(free_task); void __put_task_struct(struct task_struct *tsk) { - WARN_ON(!tsk->exit_state); + WARN_ON(!(tsk->exit_state & (EXIT_DEAD | EXIT_ZOMBIE))); WARN_ON(atomic_read(&tsk->usage)); WARN_ON(tsk == current); @@ -206,7 +205,7 @@ static struct task_struct *dup_task_struct(struct task_struct *orig) } #ifdef CONFIG_MMU -static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) +static inline int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) { struct vm_area_struct *mpnt, *tmp, **pprev; struct rb_node **rb_link, *rb_parent; @@ -269,7 +268,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) get_file(file); if (tmp->vm_flags & VM_DENYWRITE) atomic_dec(&inode->i_writecount); - + /* insert tmp into the share list, just after mpnt */ spin_lock(&file->f_mapping->i_mmap_lock); tmp->vm_truncate_count = mpnt->vm_truncate_count; @@ -332,7 +331,7 @@ static inline void mm_free_pgd(struct mm_struct * mm) #define mm_free_pgd(mm) #endif /* CONFIG_MMU */ -__cacheline_aligned_in_smp DEFINE_SPINLOCK(mmlist_lock); + __cacheline_aligned_in_smp DEFINE_SPINLOCK(mmlist_lock); #define allocate_mm() (kmem_cache_alloc(mm_cachep, GFP_KERNEL)) #define free_mm(mm) (kmem_cache_free(mm_cachep, (mm))) @@ -584,7 +583,7 @@ static int copy_mm(unsigned long clone_flags, struct task_struct * tsk) return retval; } -static struct fs_struct *__copy_fs_struct(struct fs_struct *old) +static inline struct fs_struct *__copy_fs_struct(struct fs_struct *old) { struct fs_struct *fs = kmem_cache_alloc(fs_cachep, GFP_KERNEL); /* We don't need to lock fs - think why ;-) */ @@ -616,7 +615,7 @@ struct fs_struct *copy_fs_struct(struct fs_struct *old) EXPORT_SYMBOL_GPL(copy_fs_struct); -static int copy_fs(unsigned long clone_flags, struct task_struct *tsk) +static inline int copy_fs(unsigned long clone_flags, struct task_struct * tsk) { if (clone_flags & CLONE_FS) { atomic_inc(¤t->fs->count); @@ -739,8 +738,8 @@ static struct files_struct *dup_fd(struct files_struct *oldf, int *errorp) /* compute the remainder to be cleared */ size = (new_fdt->max_fds - open_files) * sizeof(struct file *); - /* This is long word aligned thus could use a optimized version */ - memset(new_fds, 0, size); + /* This is long word aligned thus could use a optimized version */ + memset(new_fds, 0, size); if (new_fdt->max_fds > open_files) { int left = (new_fdt->max_fds-open_files)/8; @@ -819,7 +818,7 @@ int unshare_files(void) EXPORT_SYMBOL(unshare_files); -static int copy_sighand(unsigned long clone_flags, struct task_struct *tsk) +static inline int copy_sighand(unsigned long clone_flags, struct task_struct * tsk) { struct sighand_struct *sig; @@ -842,7 +841,7 @@ void __cleanup_sighand(struct sighand_struct *sighand) kmem_cache_free(sighand_cachep, sighand); } -static int copy_signal(unsigned long clone_flags, struct task_struct *tsk) +static inline int copy_signal(unsigned long clone_flags, struct task_struct * tsk) { struct signal_struct *sig; int ret; @@ -924,7 +923,7 @@ void __cleanup_signal(struct signal_struct *sig) kmem_cache_free(signal_cachep, sig); } -static void cleanup_signal(struct task_struct *tsk) +static inline void cleanup_signal(struct task_struct *tsk) { struct signal_struct *sig = tsk->signal; @@ -934,7 +933,7 @@ static void cleanup_signal(struct task_struct *tsk) __cleanup_signal(sig); } -static void copy_flags(unsigned long clone_flags, struct task_struct *p) +static inline void copy_flags(unsigned long clone_flags, struct task_struct *p) { unsigned long new_flags = p->flags; @@ -943,17 +942,16 @@ static void copy_flags(unsigned long clone_flags, struct task_struct *p) if (!(clone_flags & CLONE_PTRACE)) p->ptrace = 0; p->flags = new_flags; - clear_freeze_flag(p); } asmlinkage long sys_set_tid_address(int __user *tidptr) { current->clear_child_tid = tidptr; - return task_pid_vnr(current); + return current->pid; } -static void rt_mutex_init_task(struct task_struct *p) +static inline void rt_mutex_init_task(struct task_struct *p) { spin_lock_init(&p->pi_lock); #ifdef CONFIG_RT_MUTEXES @@ -974,12 +972,12 @@ static struct task_struct *copy_process(unsigned long clone_flags, unsigned long stack_start, struct pt_regs *regs, unsigned long stack_size, + int __user *parent_tidptr, int __user *child_tidptr, struct pid *pid) { int retval; - struct task_struct *p; - int cgroup_callbacks_done = 0; + struct task_struct *p = NULL; if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS)) return ERR_PTR(-EINVAL); @@ -1043,6 +1041,12 @@ static struct task_struct *copy_process(unsigned long clone_flags, p->did_exec = 0; delayacct_tsk_init(p); /* Must remain after dup_task_struct() */ copy_flags(clone_flags, p); + p->pid = pid_nr(pid); + retval = -EFAULT; + if (clone_flags & CLONE_PARENT_SETTID) + if (put_user(p->pid, parent_tidptr)) + goto bad_fork_cleanup_delays_binfmt; + INIT_LIST_HEAD(&p->children); INIT_LIST_HEAD(&p->sibling); p->vfork_done = NULL; @@ -1054,8 +1058,6 @@ static struct task_struct *copy_process(unsigned long clone_flags, p->utime = cputime_zero; p->stime = cputime_zero; p->gtime = cputime_zero; - p->utimescaled = cputime_zero; - p->stimescaled = cputime_zero; #ifdef CONFIG_TASK_XACCT p->rchar = 0; /* I/O counter: bytes read */ @@ -1066,12 +1068,12 @@ static struct task_struct *copy_process(unsigned long clone_flags, task_io_accounting_init(p); acct_clear_integrals(p); - p->it_virt_expires = cputime_zero; + p->it_virt_expires = cputime_zero; p->it_prof_expires = cputime_zero; - p->it_sched_expires = 0; - INIT_LIST_HEAD(&p->cpu_timers[0]); - INIT_LIST_HEAD(&p->cpu_timers[1]); - INIT_LIST_HEAD(&p->cpu_timers[2]); + p->it_sched_expires = 0; + INIT_LIST_HEAD(&p->cpu_timers[0]); + INIT_LIST_HEAD(&p->cpu_timers[1]); + INIT_LIST_HEAD(&p->cpu_timers[2]); p->lock_depth = -1; /* -1 = no lock */ do_posix_clock_monotonic_gettime(&p->start_time); @@ -1081,14 +1083,15 @@ static struct task_struct *copy_process(unsigned long clone_flags, p->security = NULL; #endif p->io_context = NULL; + p->io_wait = NULL; p->audit_context = NULL; - cgroup_fork(p); + cpuset_fork(p); #ifdef CONFIG_NUMA p->mempolicy = mpol_copy(p->mempolicy); if (IS_ERR(p->mempolicy)) { retval = PTR_ERR(p->mempolicy); p->mempolicy = NULL; - goto bad_fork_cleanup_cgroup; + goto bad_fork_cleanup_cpuset; } mpol_fix_fork_child_flag(p); #endif @@ -1121,6 +1124,10 @@ static struct task_struct *copy_process(unsigned long clone_flags, p->blocked_on = NULL; /* not blocked yet */ #endif + p->tgid = p->pid; + if (clone_flags & CLONE_THREAD) + p->tgid = current->tgid; + if ((retval = security_task_alloc(p))) goto bad_fork_cleanup_policy; if ((retval = audit_alloc(p))) @@ -1146,24 +1153,6 @@ static struct task_struct *copy_process(unsigned long clone_flags, if (retval) goto bad_fork_cleanup_namespaces; - if (pid != &init_struct_pid) { - retval = -ENOMEM; - pid = alloc_pid(task_active_pid_ns(p)); - if (!pid) - goto bad_fork_cleanup_namespaces; - - if (clone_flags & CLONE_NEWPID) { - retval = pid_ns_prepare_proc(task_active_pid_ns(p)); - if (retval < 0) - goto bad_fork_free_pid; - } - } - - p->pid = pid_nr(pid); - p->tgid = p->pid; - if (clone_flags & CLONE_THREAD) - p->tgid = current->tgid; - p->set_child_tid = (clone_flags & CLONE_CHILD_SETTID) ? child_tidptr : NULL; /* * Clear TID on mm_release()? @@ -1213,12 +1202,6 @@ static struct task_struct *copy_process(unsigned long clone_flags, /* Perform scheduler related setup. Assign this task to a CPU. */ sched_fork(p, clone_flags); - /* Now that the task is set up, run cgroup callbacks if - * necessary. We need to run them before the task is visible - * on the tasklist. */ - cgroup_fork_callbacks(p); - cgroup_callbacks_done = 1; - /* Need tasklist lock for parent etc handling! */ write_lock_irq(&tasklist_lock); @@ -1256,12 +1239,12 @@ static struct task_struct *copy_process(unsigned long clone_flags, * A fatal signal pending means that current will exit, so the new * thread can't slip out of an OOM kill (or normal SIGKILL). */ - recalc_sigpending(); + recalc_sigpending(); if (signal_pending(current)) { spin_unlock(¤t->sighand->siglock); write_unlock_irq(&tasklist_lock); retval = -ERESTARTNOINTR; - goto bad_fork_free_pid; + goto bad_fork_cleanup_namespaces; } if (clone_flags & CLONE_THREAD) { @@ -1290,22 +1273,11 @@ static struct task_struct *copy_process(unsigned long clone_flags, __ptrace_link(p, current->parent); if (thread_group_leader(p)) { - if (clone_flags & CLONE_NEWPID) { - p->nsproxy->pid_ns->child_reaper = p; - p->signal->tty = NULL; - set_task_pgrp(p, p->pid); - set_task_session(p, p->pid); - attach_pid(p, PIDTYPE_PGID, pid); - attach_pid(p, PIDTYPE_SID, pid); - } else { - p->signal->tty = current->signal->tty; - set_task_pgrp(p, task_pgrp_nr(current)); - set_task_session(p, task_session_nr(current)); - attach_pid(p, PIDTYPE_PGID, - task_pgrp(current)); - attach_pid(p, PIDTYPE_SID, - task_session(current)); - } + p->signal->tty = current->signal->tty; + p->signal->pgrp = process_group(current); + set_signal_session(p->signal, process_session(current)); + attach_pid(p, PIDTYPE_PGID, task_pgrp(current)); + attach_pid(p, PIDTYPE_SID, task_session(current)); list_add_tail_rcu(&p->tasks, &init_task.tasks); __get_cpu_var(process_counts)++; @@ -1318,12 +1290,8 @@ static struct task_struct *copy_process(unsigned long clone_flags, spin_unlock(¤t->sighand->siglock); write_unlock_irq(&tasklist_lock); proc_fork_connector(p); - cgroup_post_fork(p); return p; -bad_fork_free_pid: - if (pid != &init_struct_pid) - free_pid(pid); bad_fork_cleanup_namespaces: exit_task_namespaces(p); bad_fork_cleanup_keys: @@ -1348,9 +1316,10 @@ static struct task_struct *copy_process(unsigned long clone_flags, bad_fork_cleanup_policy: #ifdef CONFIG_NUMA mpol_free(p->mempolicy); -bad_fork_cleanup_cgroup: +bad_fork_cleanup_cpuset: #endif - cgroup_exit(p, cgroup_callbacks_done); + cpuset_exit(p); +bad_fork_cleanup_delays_binfmt: delayacct_tsk_free(p); if (p->binfmt) module_put(p->binfmt->module); @@ -1377,7 +1346,7 @@ struct task_struct * __cpuinit fork_idle(int cpu) struct task_struct *task; struct pt_regs regs; - task = copy_process(CLONE_VM, 0, idle_regs(®s), 0, NULL, + task = copy_process(CLONE_VM, 0, idle_regs(®s), 0, NULL, NULL, &init_struct_pid); if (!IS_ERR(task)) init_idle(task, cpu); @@ -1385,7 +1354,7 @@ struct task_struct * __cpuinit fork_idle(int cpu) return task; } -static int fork_traceflag(unsigned clone_flags) +static inline int fork_traceflag (unsigned clone_flags) { if (clone_flags & CLONE_UNTRACED) return 0; @@ -1416,16 +1385,19 @@ long do_fork(unsigned long clone_flags, { struct task_struct *p; int trace = 0; + struct pid *pid = alloc_pid(); long nr; + if (!pid) + return -EAGAIN; + nr = pid->nr; if (unlikely(current->ptrace)) { trace = fork_traceflag (clone_flags); if (trace) clone_flags |= CLONE_PTRACE; } - p = copy_process(clone_flags, stack_start, regs, stack_size, - child_tidptr, NULL); + p = copy_process(clone_flags, stack_start, regs, stack_size, parent_tidptr, child_tidptr, pid); /* * Do this prior waking up the new thread - the thread pointer * might get invalid after that point, if the thread exits quickly. @@ -1433,17 +1405,6 @@ long do_fork(unsigned long clone_flags, if (!IS_ERR(p)) { struct completion vfork; - /* - * this is enough to call pid_nr_ns here, but this if - * improves optimisation of regular fork() - */ - nr = (clone_flags & CLONE_NEWPID) ? - task_pid_nr_ns(p, current->nsproxy->pid_ns) : - task_pid_vnr(p); - - if (clone_flags & CLONE_PARENT_SETTID) - put_user(nr, parent_tidptr); - if (clone_flags & CLONE_VFORK) { p->vfork_done = &vfork; init_completion(&vfork); @@ -1477,6 +1438,7 @@ long do_fork(unsigned long clone_flags, } } } else { + free_pid(pid); nr = PTR_ERR(p); } return nr; @@ -1521,7 +1483,7 @@ void __init proc_caches_init(void) * Check constraints on flags passed to the unshare system call and * force unsharing of additional process context as appropriate. */ -static void check_unshare_flags(unsigned long *flags_ptr) +static inline void check_unshare_flags(unsigned long *flags_ptr) { /* * If unsharing a thread from a thread group, must also @@ -1653,7 +1615,7 @@ asmlinkage long sys_unshare(unsigned long unshare_flags) struct mm_struct *mm, *new_mm = NULL, *active_mm = NULL; struct files_struct *fd, *new_fd = NULL; struct sem_undo_list *new_ulist = NULL; - struct nsproxy *new_nsproxy = NULL; + struct nsproxy *new_nsproxy = NULL, *old_nsproxy = NULL; check_unshare_flags(&unshare_flags); @@ -1683,13 +1645,14 @@ asmlinkage long sys_unshare(unsigned long unshare_flags) if (new_fs || new_mm || new_fd || new_ulist || new_nsproxy) { + task_lock(current); + if (new_nsproxy) { - switch_task_namespaces(current, new_nsproxy); - new_nsproxy = NULL; + old_nsproxy = current->nsproxy; + current->nsproxy = new_nsproxy; + new_nsproxy = old_nsproxy; } - task_lock(current); - if (new_fs) { fs = current->fs; current->fs = new_fs; diff --git a/trunk/kernel/futex.c b/trunk/kernel/futex.c index 32710451dc20..d725676d84f3 100644 --- a/trunk/kernel/futex.c +++ b/trunk/kernel/futex.c @@ -53,9 +53,6 @@ #include #include #include -#include -#include - #include #include "rtmutex_common.h" @@ -296,7 +293,7 @@ EXPORT_SYMBOL_GPL(get_futex_key_refs); */ void drop_futex_key_refs(union futex_key *key) { - if (!key->both.ptr) + if (key->both.ptr == 0) return; switch (key->both.offset & (FUT_OFF_INODE|FUT_OFF_MMSHARED)) { case FUT_OFF_INODE: @@ -446,7 +443,8 @@ static struct task_struct * futex_find_get_task(pid_t pid) struct task_struct *p; rcu_read_lock(); - p = find_task_by_vpid(pid); + p = find_task_by_pid(pid); + if (!p || ((current->euid != p->euid) && (current->euid != p->uid))) p = ERR_PTR(-ESRCH); else @@ -655,7 +653,7 @@ static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_q *this) if (!(uval & FUTEX_OWNER_DIED)) { int ret = 0; - newval = FUTEX_WAITERS | task_pid_vnr(new_owner); + newval = FUTEX_WAITERS | new_owner->pid; curval = cmpxchg_futex_value_locked(uaddr, uval, newval); @@ -1048,7 +1046,7 @@ static int unqueue_me(struct futex_q *q) retry: lock_ptr = q->lock_ptr; barrier(); - if (lock_ptr != NULL) { + if (lock_ptr != 0) { spin_lock(lock_ptr); /* * q->lock_ptr can change between reading it and @@ -1108,7 +1106,7 @@ static void unqueue_me_pi(struct futex_q *q) static int fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q, struct task_struct *curr) { - u32 newtid = task_pid_vnr(curr) | FUTEX_WAITERS; + u32 newtid = curr->pid | FUTEX_WAITERS; struct futex_pi_state *pi_state = q->pi_state; u32 uval, curval, newval; int ret; @@ -1370,7 +1368,7 @@ static int futex_lock_pi(u32 __user *uaddr, struct rw_semaphore *fshared, * (by doing a 0 -> TID atomic cmpxchg), while holding all * the locks. It will most likely not succeed. */ - newval = task_pid_vnr(current); + newval = current->pid; curval = cmpxchg_futex_value_locked(uaddr, 0, newval); @@ -1381,7 +1379,7 @@ static int futex_lock_pi(u32 __user *uaddr, struct rw_semaphore *fshared, * Detect deadlocks. In case of REQUEUE_PI this is a valid * situation and we return success to user space. */ - if (unlikely((curval & FUTEX_TID_MASK) == task_pid_vnr(current))) { + if (unlikely((curval & FUTEX_TID_MASK) == current->pid)) { ret = -EDEADLK; goto out_unlock_release_sem; } @@ -1410,7 +1408,7 @@ static int futex_lock_pi(u32 __user *uaddr, struct rw_semaphore *fshared, */ if (unlikely(ownerdied || !(curval & FUTEX_TID_MASK))) { /* Keep the OWNER_DIED bit */ - newval = (curval & ~FUTEX_TID_MASK) | task_pid_vnr(current); + newval = (curval & ~FUTEX_TID_MASK) | current->pid; ownerdied = 0; lock_taken = 1; } @@ -1589,7 +1587,7 @@ static int futex_unlock_pi(u32 __user *uaddr, struct rw_semaphore *fshared) /* * We release only a lock we actually own: */ - if ((uval & FUTEX_TID_MASK) != task_pid_vnr(current)) + if ((uval & FUTEX_TID_MASK) != current->pid) return -EPERM; /* * First take all the futex related locks: @@ -1610,7 +1608,7 @@ static int futex_unlock_pi(u32 __user *uaddr, struct rw_semaphore *fshared) * anyone else up: */ if (!(uval & FUTEX_OWNER_DIED)) - uval = cmpxchg_futex_value_locked(uaddr, task_pid_vnr(current), 0); + uval = cmpxchg_futex_value_locked(uaddr, current->pid, 0); if (unlikely(uval == -EFAULT)) @@ -1619,7 +1617,7 @@ static int futex_unlock_pi(u32 __user *uaddr, struct rw_semaphore *fshared) * Rare case: we managed to release the lock atomically, * no need to wake anyone else up: */ - if (unlikely(uval == task_pid_vnr(current))) + if (unlikely(uval == current->pid)) goto out_unlock; /* @@ -1856,7 +1854,7 @@ sys_get_robust_list(int pid, struct robust_list_head __user * __user *head_ptr, ret = -ESRCH; rcu_read_lock(); - p = find_task_by_vpid(pid); + p = find_task_by_pid(pid); if (!p) goto err_unlock; ret = -EPERM; @@ -1889,7 +1887,7 @@ int handle_futex_death(u32 __user *uaddr, struct task_struct *curr, int pi) if (get_user(uval, uaddr)) return -1; - if ((uval & FUTEX_TID_MASK) == task_pid_vnr(curr)) { + if ((uval & FUTEX_TID_MASK) == curr->pid) { /* * Ok, this dying thread is truly holding a futex * of interest. Set the OWNER_DIED bit atomically diff --git a/trunk/kernel/futex_compat.c b/trunk/kernel/futex_compat.c index 00b572666cc7..2c2e2954b713 100644 --- a/trunk/kernel/futex_compat.c +++ b/trunk/kernel/futex_compat.c @@ -8,7 +8,6 @@ #include #include -#include #include #include @@ -125,7 +124,7 @@ compat_sys_get_robust_list(int pid, compat_uptr_t __user *head_ptr, ret = -ESRCH; read_lock(&tasklist_lock); - p = find_task_by_vpid(pid); + p = find_task_by_pid(pid); if (!p) goto err_unlock; ret = -EPERM; diff --git a/trunk/kernel/hrtimer.c b/trunk/kernel/hrtimer.c index b2b2c2b0a49b..dc8a4451d79b 100644 --- a/trunk/kernel/hrtimer.c +++ b/trunk/kernel/hrtimer.c @@ -1286,7 +1286,8 @@ static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mod long __sched hrtimer_nanosleep_restart(struct restart_block *restart) { struct hrtimer_sleeper t; - struct timespec *rmtp; + struct timespec __user *rmtp; + struct timespec tu; ktime_t time; restart->fn = do_no_restart_syscall; @@ -1297,12 +1298,14 @@ long __sched hrtimer_nanosleep_restart(struct restart_block *restart) if (do_nanosleep(&t, HRTIMER_MODE_ABS)) return 0; - rmtp = (struct timespec *)restart->arg1; + rmtp = (struct timespec __user *) restart->arg1; if (rmtp) { time = ktime_sub(t.timer.expires, t.timer.base->get_time()); if (time.tv64 <= 0) return 0; - *rmtp = ktime_to_timespec(time); + tu = ktime_to_timespec(time); + if (copy_to_user(rmtp, &tu, sizeof(tu))) + return -EFAULT; } restart->fn = hrtimer_nanosleep_restart; @@ -1311,11 +1314,12 @@ long __sched hrtimer_nanosleep_restart(struct restart_block *restart) return -ERESTART_RESTARTBLOCK; } -long hrtimer_nanosleep(struct timespec *rqtp, struct timespec *rmtp, +long hrtimer_nanosleep(struct timespec *rqtp, struct timespec __user *rmtp, const enum hrtimer_mode mode, const clockid_t clockid) { struct restart_block *restart; struct hrtimer_sleeper t; + struct timespec tu; ktime_t rem; hrtimer_init(&t.timer, clockid, mode); @@ -1331,7 +1335,9 @@ long hrtimer_nanosleep(struct timespec *rqtp, struct timespec *rmtp, rem = ktime_sub(t.timer.expires, t.timer.base->get_time()); if (rem.tv64 <= 0) return 0; - *rmtp = ktime_to_timespec(rem); + tu = ktime_to_timespec(rem); + if (copy_to_user(rmtp, &tu, sizeof(tu))) + return -EFAULT; } restart = ¤t_thread_info()->restart_block; @@ -1347,8 +1353,7 @@ long hrtimer_nanosleep(struct timespec *rqtp, struct timespec *rmtp, asmlinkage long sys_nanosleep(struct timespec __user *rqtp, struct timespec __user *rmtp) { - struct timespec tu, rmt; - int ret; + struct timespec tu; if (copy_from_user(&tu, rqtp, sizeof(tu))) return -EFAULT; @@ -1356,15 +1361,7 @@ sys_nanosleep(struct timespec __user *rqtp, struct timespec __user *rmtp) if (!timespec_valid(&tu)) return -EINVAL; - ret = hrtimer_nanosleep(&tu, rmtp ? &rmt : NULL, HRTIMER_MODE_REL, - CLOCK_MONOTONIC); - - if (ret && rmtp) { - if (copy_to_user(rmtp, &rmt, sizeof(*rmtp))) - return -EFAULT; - } - - return ret; + return hrtimer_nanosleep(&tu, rmtp, HRTIMER_MODE_REL, CLOCK_MONOTONIC); } /* diff --git a/trunk/kernel/itimer.c b/trunk/kernel/itimer.c index 2fab344dbf56..3205e8e114fa 100644 --- a/trunk/kernel/itimer.c +++ b/trunk/kernel/itimer.c @@ -130,7 +130,7 @@ asmlinkage long sys_getitimer(int which, struct itimerval __user *value) enum hrtimer_restart it_real_fn(struct hrtimer *timer) { struct signal_struct *sig = - container_of(timer, struct signal_struct, real_timer); + container_of(timer, struct signal_struct, real_timer); send_group_sig_info(SIGALRM, SEND_SIG_PRIV, sig->tsk); @@ -291,6 +291,6 @@ asmlinkage long sys_setitimer(int which, return error; if (copy_to_user(ovalue, &get_buffer, sizeof(get_buffer))) - return -EFAULT; + return -EFAULT; return 0; } diff --git a/trunk/kernel/kexec.c b/trunk/kernel/kexec.c index aa74a1ef2da8..7885269b0da2 100644 --- a/trunk/kernel/kexec.c +++ b/trunk/kernel/kexec.c @@ -51,7 +51,7 @@ struct resource crashk_res = { int kexec_should_crash(struct task_struct *p) { - if (in_interrupt() || !p->pid || is_global_init(p) || panic_on_oops) + if (in_interrupt() || !p->pid || is_init(p) || panic_on_oops) return 1; return 0; } @@ -785,7 +785,7 @@ static int kimage_load_normal_segment(struct kimage *image, size_t uchunk, mchunk; page = kimage_alloc_page(image, GFP_HIGHUSER, maddr); - if (!page) { + if (page == 0) { result = -ENOMEM; goto out; } @@ -844,7 +844,7 @@ static int kimage_load_crash_segment(struct kimage *image, size_t uchunk, mchunk; page = pfn_to_page(maddr >> PAGE_SHIFT); - if (!page) { + if (page == 0) { result = -ENOMEM; goto out; } @@ -1146,172 +1146,6 @@ static int __init crash_notes_memory_init(void) } module_init(crash_notes_memory_init) - -/* - * parsing the "crashkernel" commandline - * - * this code is intended to be called from architecture specific code - */ - - -/* - * This function parses command lines in the format - * - * crashkernel=ramsize-range:size[,...][@offset] - * - * The function returns 0 on success and -EINVAL on failure. - */ -static int __init parse_crashkernel_mem(char *cmdline, - unsigned long long system_ram, - unsigned long long *crash_size, - unsigned long long *crash_base) -{ - char *cur = cmdline, *tmp; - - /* for each entry of the comma-separated list */ - do { - unsigned long long start, end = ULLONG_MAX, size; - - /* get the start of the range */ - start = memparse(cur, &tmp); - if (cur == tmp) { - pr_warning("crashkernel: Memory value expected\n"); - return -EINVAL; - } - cur = tmp; - if (*cur != '-') { - pr_warning("crashkernel: '-' expected\n"); - return -EINVAL; - } - cur++; - - /* if no ':' is here, than we read the end */ - if (*cur != ':') { - end = memparse(cur, &tmp); - if (cur == tmp) { - pr_warning("crashkernel: Memory " - "value expected\n"); - return -EINVAL; - } - cur = tmp; - if (end <= start) { - pr_warning("crashkernel: end <= start\n"); - return -EINVAL; - } - } - - if (*cur != ':') { - pr_warning("crashkernel: ':' expected\n"); - return -EINVAL; - } - cur++; - - size = memparse(cur, &tmp); - if (cur == tmp) { - pr_warning("Memory value expected\n"); - return -EINVAL; - } - cur = tmp; - if (size >= system_ram) { - pr_warning("crashkernel: invalid size\n"); - return -EINVAL; - } - - /* match ? */ - if (system_ram >= start && system_ram <= end) { - *crash_size = size; - break; - } - } while (*cur++ == ','); - - if (*crash_size > 0) { - while (*cur != ' ' && *cur != '@') - cur++; - if (*cur == '@') { - cur++; - *crash_base = memparse(cur, &tmp); - if (cur == tmp) { - pr_warning("Memory value expected " - "after '@'\n"); - return -EINVAL; - } - } - } - - return 0; -} - -/* - * That function parses "simple" (old) crashkernel command lines like - * - * crashkernel=size[@offset] - * - * It returns 0 on success and -EINVAL on failure. - */ -static int __init parse_crashkernel_simple(char *cmdline, - unsigned long long *crash_size, - unsigned long long *crash_base) -{ - char *cur = cmdline; - - *crash_size = memparse(cmdline, &cur); - if (cmdline == cur) { - pr_warning("crashkernel: memory value expected\n"); - return -EINVAL; - } - - if (*cur == '@') - *crash_base = memparse(cur+1, &cur); - - return 0; -} - -/* - * That function is the entry point for command line parsing and should be - * called from the arch-specific code. - */ -int __init parse_crashkernel(char *cmdline, - unsigned long long system_ram, - unsigned long long *crash_size, - unsigned long long *crash_base) -{ - char *p = cmdline, *ck_cmdline = NULL; - char *first_colon, *first_space; - - BUG_ON(!crash_size || !crash_base); - *crash_size = 0; - *crash_base = 0; - - /* find crashkernel and use the last one if there are more */ - p = strstr(p, "crashkernel="); - while (p) { - ck_cmdline = p; - p = strstr(p+1, "crashkernel="); - } - - if (!ck_cmdline) - return -EINVAL; - - ck_cmdline += 12; /* strlen("crashkernel=") */ - - /* - * if the commandline contains a ':', then that's the extended - * syntax -- if not, it must be the classic syntax - */ - first_colon = strchr(ck_cmdline, ':'); - first_space = strchr(ck_cmdline, ' '); - if (first_colon && (!first_space || first_colon < first_space)) - return parse_crashkernel_mem(ck_cmdline, system_ram, - crash_size, crash_base); - else - return parse_crashkernel_simple(ck_cmdline, crash_size, - crash_base); - - return 0; -} - - - void crash_save_vmcoreinfo(void) { u32 *buf; diff --git a/trunk/kernel/lockdep.c b/trunk/kernel/lockdep.c index 55fe0c7cd95f..a6f1ee9c92d9 100644 --- a/trunk/kernel/lockdep.c +++ b/trunk/kernel/lockdep.c @@ -511,11 +511,11 @@ static void lockdep_print_held_locks(struct task_struct *curr) int i, depth = curr->lockdep_depth; if (!depth) { - printk("no locks held by %s/%d.\n", curr->comm, task_pid_nr(curr)); + printk("no locks held by %s/%d.\n", curr->comm, curr->pid); return; } printk("%d lock%s held by %s/%d:\n", - depth, depth > 1 ? "s" : "", curr->comm, task_pid_nr(curr)); + depth, depth > 1 ? "s" : "", curr->comm, curr->pid); for (i = 0; i < depth; i++) { printk(" #%d: ", i); @@ -904,7 +904,7 @@ print_circular_bug_header(struct lock_list *entry, unsigned int depth) print_kernel_version(); printk( "-------------------------------------------------------\n"); printk("%s/%d is trying to acquire lock:\n", - curr->comm, task_pid_nr(curr)); + curr->comm, curr->pid); print_lock(check_source); printk("\nbut task is already holding lock:\n"); print_lock(check_target); @@ -1085,7 +1085,7 @@ print_bad_irq_dependency(struct task_struct *curr, print_kernel_version(); printk( "------------------------------------------------------\n"); printk("%s/%d [HC%u[%lu]:SC%u[%lu]:HE%u:SE%u] is trying to acquire:\n", - curr->comm, task_pid_nr(curr), + curr->comm, curr->pid, curr->hardirq_context, hardirq_count() >> HARDIRQ_SHIFT, curr->softirq_context, softirq_count() >> SOFTIRQ_SHIFT, curr->hardirqs_enabled, @@ -1237,7 +1237,7 @@ print_deadlock_bug(struct task_struct *curr, struct held_lock *prev, print_kernel_version(); printk( "---------------------------------------------\n"); printk("%s/%d is trying to acquire lock:\n", - curr->comm, task_pid_nr(curr)); + curr->comm, curr->pid); print_lock(next); printk("\nbut task is already holding lock:\n"); print_lock(prev); @@ -1521,7 +1521,7 @@ static inline int lookup_chain_cache(u64 chain_key, struct lock_class *class) } static int validate_chain(struct task_struct *curr, struct lockdep_map *lock, - struct held_lock *hlock, int chain_head, u64 chain_key) + struct held_lock *hlock, int chain_head, u64 chain_key) { /* * Trylock needs to maintain the stack of held locks, but it @@ -1641,7 +1641,7 @@ print_usage_bug(struct task_struct *curr, struct held_lock *this, usage_str[prev_bit], usage_str[new_bit]); printk("%s/%d [HC%u[%lu]:SC%u[%lu]:HE%u:SE%u] takes:\n", - curr->comm, task_pid_nr(curr), + curr->comm, curr->pid, trace_hardirq_context(curr), hardirq_count() >> HARDIRQ_SHIFT, trace_softirq_context(curr), softirq_count() >> SOFTIRQ_SHIFT, trace_hardirqs_enabled(curr), @@ -1694,7 +1694,7 @@ print_irq_inversion_bug(struct task_struct *curr, struct lock_class *other, print_kernel_version(); printk( "---------------------------------------------------------\n"); printk("%s/%d just changed the state of lock:\n", - curr->comm, task_pid_nr(curr)); + curr->comm, curr->pid); print_lock(this); if (forwards) printk("but this lock took another, %s-irq-unsafe lock in the past:\n", irqclass); @@ -2487,7 +2487,7 @@ print_unlock_inbalance_bug(struct task_struct *curr, struct lockdep_map *lock, printk( "[ BUG: bad unlock balance detected! ]\n"); printk( "-------------------------------------\n"); printk("%s/%d is trying to release lock (", - curr->comm, task_pid_nr(curr)); + curr->comm, curr->pid); print_lockdep_cache(lock); printk(") at:\n"); print_ip_sym(ip); @@ -2737,7 +2737,7 @@ print_lock_contention_bug(struct task_struct *curr, struct lockdep_map *lock, printk( "[ BUG: bad contention detected! ]\n"); printk( "---------------------------------\n"); printk("%s/%d is trying to contend lock (", - curr->comm, task_pid_nr(curr)); + curr->comm, curr->pid); print_lockdep_cache(lock); printk(") at:\n"); print_ip_sym(ip); @@ -3072,7 +3072,7 @@ print_freed_lock_bug(struct task_struct *curr, const void *mem_from, printk( "[ BUG: held lock freed! ]\n"); printk( "-------------------------\n"); printk("%s/%d is freeing memory %p-%p, with a lock still held there!\n", - curr->comm, task_pid_nr(curr), mem_from, mem_to-1); + curr->comm, curr->pid, mem_from, mem_to-1); print_lock(hlock); lockdep_print_held_locks(curr); @@ -3125,7 +3125,7 @@ static void print_held_locks_bug(struct task_struct *curr) printk( "[ BUG: lock held at task exit time! ]\n"); printk( "-------------------------------------\n"); printk("%s/%d is exiting with locks still held!\n", - curr->comm, task_pid_nr(curr)); + curr->comm, curr->pid); lockdep_print_held_locks(curr); printk("\nstack backtrace:\n"); diff --git a/trunk/kernel/marker.c b/trunk/kernel/marker.c deleted file mode 100644 index ccb48d9a3657..000000000000 --- a/trunk/kernel/marker.c +++ /dev/null @@ -1,525 +0,0 @@ -/* - * Copyright (C) 2007 Mathieu Desnoyers - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ -#include -#include -#include -#include -#include -#include -#include -#include - -extern struct marker __start___markers[]; -extern struct marker __stop___markers[]; - -/* - * module_mutex nests inside markers_mutex. Markers mutex protects the builtin - * and module markers, the hash table and deferred_sync. - */ -static DEFINE_MUTEX(markers_mutex); - -/* - * Marker deferred synchronization. - * Upon marker probe_unregister, we delay call to synchronize_sched() to - * accelerate mass unregistration (only when there is no more reference to a - * given module do we call synchronize_sched()). However, we need to make sure - * every critical region has ended before we re-arm a marker that has been - * unregistered and then registered back with a different probe data. - */ -static int deferred_sync; - -/* - * Marker hash table, containing the active markers. - * Protected by module_mutex. - */ -#define MARKER_HASH_BITS 6 -#define MARKER_TABLE_SIZE (1 << MARKER_HASH_BITS) - -struct marker_entry { - struct hlist_node hlist; - char *format; - marker_probe_func *probe; - void *private; - int refcount; /* Number of times armed. 0 if disarmed. */ - char name[0]; /* Contains name'\0'format'\0' */ -}; - -static struct hlist_head marker_table[MARKER_TABLE_SIZE]; - -/** - * __mark_empty_function - Empty probe callback - * @mdata: pointer of type const struct marker - * @fmt: format string - * @...: variable argument list - * - * Empty callback provided as a probe to the markers. By providing this to a - * disabled marker, we make sure the execution flow is always valid even - * though the function pointer change and the marker enabling are two distinct - * operations that modifies the execution flow of preemptible code. - */ -void __mark_empty_function(const struct marker *mdata, void *private, - const char *fmt, ...) -{ -} -EXPORT_SYMBOL_GPL(__mark_empty_function); - -/* - * Get marker if the marker is present in the marker hash table. - * Must be called with markers_mutex held. - * Returns NULL if not present. - */ -static struct marker_entry *get_marker(const char *name) -{ - struct hlist_head *head; - struct hlist_node *node; - struct marker_entry *e; - u32 hash = jhash(name, strlen(name), 0); - - head = &marker_table[hash & ((1 << MARKER_HASH_BITS)-1)]; - hlist_for_each_entry(e, node, head, hlist) { - if (!strcmp(name, e->name)) - return e; - } - return NULL; -} - -/* - * Add the marker to the marker hash table. Must be called with markers_mutex - * held. - */ -static int add_marker(const char *name, const char *format, - marker_probe_func *probe, void *private) -{ - struct hlist_head *head; - struct hlist_node *node; - struct marker_entry *e; - size_t name_len = strlen(name) + 1; - size_t format_len = 0; - u32 hash = jhash(name, name_len-1, 0); - - if (format) - format_len = strlen(format) + 1; - head = &marker_table[hash & ((1 << MARKER_HASH_BITS)-1)]; - hlist_for_each_entry(e, node, head, hlist) { - if (!strcmp(name, e->name)) { - printk(KERN_NOTICE - "Marker %s busy, probe %p already installed\n", - name, e->probe); - return -EBUSY; /* Already there */ - } - } - /* - * Using kmalloc here to allocate a variable length element. Could - * cause some memory fragmentation if overused. - */ - e = kmalloc(sizeof(struct marker_entry) + name_len + format_len, - GFP_KERNEL); - if (!e) - return -ENOMEM; - memcpy(&e->name[0], name, name_len); - if (format) { - e->format = &e->name[name_len]; - memcpy(e->format, format, format_len); - trace_mark(core_marker_format, "name %s format %s", - e->name, e->format); - } else - e->format = NULL; - e->probe = probe; - e->private = private; - e->refcount = 0; - hlist_add_head(&e->hlist, head); - return 0; -} - -/* - * Remove the marker from the marker hash table. Must be called with mutex_lock - * held. - */ -static void *remove_marker(const char *name) -{ - struct hlist_head *head; - struct hlist_node *node; - struct marker_entry *e; - int found = 0; - size_t len = strlen(name) + 1; - void *private = NULL; - u32 hash = jhash(name, len-1, 0); - - head = &marker_table[hash & ((1 << MARKER_HASH_BITS)-1)]; - hlist_for_each_entry(e, node, head, hlist) { - if (!strcmp(name, e->name)) { - found = 1; - break; - } - } - if (found) { - private = e->private; - hlist_del(&e->hlist); - kfree(e); - } - return private; -} - -/* - * Set the mark_entry format to the format found in the element. - */ -static int marker_set_format(struct marker_entry **entry, const char *format) -{ - struct marker_entry *e; - size_t name_len = strlen((*entry)->name) + 1; - size_t format_len = strlen(format) + 1; - - e = kmalloc(sizeof(struct marker_entry) + name_len + format_len, - GFP_KERNEL); - if (!e) - return -ENOMEM; - memcpy(&e->name[0], (*entry)->name, name_len); - e->format = &e->name[name_len]; - memcpy(e->format, format, format_len); - e->probe = (*entry)->probe; - e->private = (*entry)->private; - e->refcount = (*entry)->refcount; - hlist_add_before(&e->hlist, &(*entry)->hlist); - hlist_del(&(*entry)->hlist); - kfree(*entry); - *entry = e; - trace_mark(core_marker_format, "name %s format %s", - e->name, e->format); - return 0; -} - -/* - * Sets the probe callback corresponding to one marker. - */ -static int set_marker(struct marker_entry **entry, struct marker *elem) -{ - int ret; - WARN_ON(strcmp((*entry)->name, elem->name) != 0); - - if ((*entry)->format) { - if (strcmp((*entry)->format, elem->format) != 0) { - printk(KERN_NOTICE - "Format mismatch for probe %s " - "(%s), marker (%s)\n", - (*entry)->name, - (*entry)->format, - elem->format); - return -EPERM; - } - } else { - ret = marker_set_format(entry, elem->format); - if (ret) - return ret; - } - elem->call = (*entry)->probe; - elem->private = (*entry)->private; - elem->state = 1; - return 0; -} - -/* - * Disable a marker and its probe callback. - * Note: only after a synchronize_sched() issued after setting elem->call to the - * empty function insures that the original callback is not used anymore. This - * insured by preemption disabling around the call site. - */ -static void disable_marker(struct marker *elem) -{ - elem->state = 0; - elem->call = __mark_empty_function; - /* - * Leave the private data and id there, because removal is racy and - * should be done only after a synchronize_sched(). These are never used - * until the next initialization anyway. - */ -} - -/** - * marker_update_probe_range - Update a probe range - * @begin: beginning of the range - * @end: end of the range - * @probe_module: module address of the probe being updated - * @refcount: number of references left to the given probe_module (out) - * - * Updates the probe callback corresponding to a range of markers. - * Must be called with markers_mutex held. - */ -void marker_update_probe_range(struct marker *begin, - struct marker *end, struct module *probe_module, - int *refcount) -{ - struct marker *iter; - struct marker_entry *mark_entry; - - for (iter = begin; iter < end; iter++) { - mark_entry = get_marker(iter->name); - if (mark_entry && mark_entry->refcount) { - set_marker(&mark_entry, iter); - /* - * ignore error, continue - */ - if (probe_module) - if (probe_module == - __module_text_address((unsigned long)mark_entry->probe)) - (*refcount)++; - } else { - disable_marker(iter); - } - } -} - -/* - * Update probes, removing the faulty probes. - * Issues a synchronize_sched() when no reference to the module passed - * as parameter is found in the probes so the probe module can be - * safely unloaded from now on. - */ -static void marker_update_probes(struct module *probe_module) -{ - int refcount = 0; - - mutex_lock(&markers_mutex); - /* Core kernel markers */ - marker_update_probe_range(__start___markers, - __stop___markers, probe_module, &refcount); - /* Markers in modules. */ - module_update_markers(probe_module, &refcount); - if (probe_module && refcount == 0) { - synchronize_sched(); - deferred_sync = 0; - } - mutex_unlock(&markers_mutex); -} - -/** - * marker_probe_register - Connect a probe to a marker - * @name: marker name - * @format: format string - * @probe: probe handler - * @private: probe private data - * - * private data must be a valid allocated memory address, or NULL. - * Returns 0 if ok, error value on error. - */ -int marker_probe_register(const char *name, const char *format, - marker_probe_func *probe, void *private) -{ - struct marker_entry *entry; - int ret = 0, need_update = 0; - - mutex_lock(&markers_mutex); - entry = get_marker(name); - if (entry && entry->refcount) { - ret = -EBUSY; - goto end; - } - if (deferred_sync) { - synchronize_sched(); - deferred_sync = 0; - } - ret = add_marker(name, format, probe, private); - if (ret) - goto end; - need_update = 1; -end: - mutex_unlock(&markers_mutex); - if (need_update) - marker_update_probes(NULL); - return ret; -} -EXPORT_SYMBOL_GPL(marker_probe_register); - -/** - * marker_probe_unregister - Disconnect a probe from a marker - * @name: marker name - * - * Returns the private data given to marker_probe_register, or an ERR_PTR(). - */ -void *marker_probe_unregister(const char *name) -{ - struct module *probe_module; - struct marker_entry *entry; - void *private; - int need_update = 0; - - mutex_lock(&markers_mutex); - entry = get_marker(name); - if (!entry) { - private = ERR_PTR(-ENOENT); - goto end; - } - entry->refcount = 0; - /* In what module is the probe handler ? */ - probe_module = __module_text_address((unsigned long)entry->probe); - private = remove_marker(name); - deferred_sync = 1; - need_update = 1; -end: - mutex_unlock(&markers_mutex); - if (need_update) - marker_update_probes(probe_module); - return private; -} -EXPORT_SYMBOL_GPL(marker_probe_unregister); - -/** - * marker_probe_unregister_private_data - Disconnect a probe from a marker - * @private: probe private data - * - * Unregister a marker by providing the registered private data. - * Returns the private data given to marker_probe_register, or an ERR_PTR(). - */ -void *marker_probe_unregister_private_data(void *private) -{ - struct module *probe_module; - struct hlist_head *head; - struct hlist_node *node; - struct marker_entry *entry; - int found = 0; - unsigned int i; - int need_update = 0; - - mutex_lock(&markers_mutex); - for (i = 0; i < MARKER_TABLE_SIZE; i++) { - head = &marker_table[i]; - hlist_for_each_entry(entry, node, head, hlist) { - if (entry->private == private) { - found = 1; - goto iter_end; - } - } - } -iter_end: - if (!found) { - private = ERR_PTR(-ENOENT); - goto end; - } - entry->refcount = 0; - /* In what module is the probe handler ? */ - probe_module = __module_text_address((unsigned long)entry->probe); - private = remove_marker(entry->name); - deferred_sync = 1; - need_update = 1; -end: - mutex_unlock(&markers_mutex); - if (need_update) - marker_update_probes(probe_module); - return private; -} -EXPORT_SYMBOL_GPL(marker_probe_unregister_private_data); - -/** - * marker_arm - Arm a marker - * @name: marker name - * - * Activate a marker. It keeps a reference count of the number of - * arming/disarming done. - * Returns 0 if ok, error value on error. - */ -int marker_arm(const char *name) -{ - struct marker_entry *entry; - int ret = 0, need_update = 0; - - mutex_lock(&markers_mutex); - entry = get_marker(name); - if (!entry) { - ret = -ENOENT; - goto end; - } - /* - * Only need to update probes when refcount passes from 0 to 1. - */ - if (entry->refcount++) - goto end; - need_update = 1; -end: - mutex_unlock(&markers_mutex); - if (need_update) - marker_update_probes(NULL); - return ret; -} -EXPORT_SYMBOL_GPL(marker_arm); - -/** - * marker_disarm - Disarm a marker - * @name: marker name - * - * Disarm a marker. It keeps a reference count of the number of arming/disarming - * done. - * Returns 0 if ok, error value on error. - */ -int marker_disarm(const char *name) -{ - struct marker_entry *entry; - int ret = 0, need_update = 0; - - mutex_lock(&markers_mutex); - entry = get_marker(name); - if (!entry) { - ret = -ENOENT; - goto end; - } - /* - * Only permit decrement refcount if higher than 0. - * Do probe update only on 1 -> 0 transition. - */ - if (entry->refcount) { - if (--entry->refcount) - goto end; - } else { - ret = -EPERM; - goto end; - } - need_update = 1; -end: - mutex_unlock(&markers_mutex); - if (need_update) - marker_update_probes(NULL); - return ret; -} -EXPORT_SYMBOL_GPL(marker_disarm); - -/** - * marker_get_private_data - Get a marker's probe private data - * @name: marker name - * - * Returns the private data pointer, or an ERR_PTR. - * The private data pointer should _only_ be dereferenced if the caller is the - * owner of the data, or its content could vanish. This is mostly used to - * confirm that a caller is the owner of a registered probe. - */ -void *marker_get_private_data(const char *name) -{ - struct hlist_head *head; - struct hlist_node *node; - struct marker_entry *e; - size_t name_len = strlen(name) + 1; - u32 hash = jhash(name, name_len-1, 0); - int found = 0; - - head = &marker_table[hash & ((1 << MARKER_HASH_BITS)-1)]; - hlist_for_each_entry(e, node, head, hlist) { - if (!strcmp(name, e->name)) { - found = 1; - return e->private; - } - } - return ERR_PTR(-ENOENT); -} -EXPORT_SYMBOL_GPL(marker_get_private_data); diff --git a/trunk/kernel/module.c b/trunk/kernel/module.c index 3202c9950073..a389b423c279 100644 --- a/trunk/kernel/module.c +++ b/trunk/kernel/module.c @@ -105,7 +105,7 @@ void __module_put_and_exit(struct module *mod, long code) do_exit(code); } EXPORT_SYMBOL(__module_put_and_exit); - + /* Find a module section: 0 means not found. */ static unsigned int find_sec(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, @@ -179,7 +179,7 @@ static unsigned long __find_symbol(const char *name, struct module *mod; const struct kernel_symbol *ks; - /* Core kernel first. */ + /* Core kernel first. */ *owner = NULL; ks = lookup_symbol(name, __start___ksymtab, __stop___ksymtab); if (ks) { @@ -231,7 +231,7 @@ static unsigned long __find_symbol(const char *name, return ks->value; } - /* Now try modules. */ + /* Now try modules. */ list_for_each_entry(mod, &modules, list) { *owner = mod; ks = lookup_symbol(name, mod->syms, mod->syms + mod->num_syms); @@ -285,7 +285,7 @@ static unsigned long __find_symbol(const char *name, } } DEBUGP("Failed to find symbol %s\n", name); - return 0; + return 0; } /* Search for module by name: must hold module_mutex. */ @@ -441,7 +441,7 @@ static int percpu_modinit(void) } return 0; -} +} __initcall(percpu_modinit); #else /* ... !CONFIG_SMP */ static inline void *percpu_modalloc(unsigned long size, unsigned long align, @@ -483,8 +483,8 @@ static int modinfo_##field##_exists(struct module *mod) \ } \ static void free_modinfo_##field(struct module *mod) \ { \ - kfree(mod->field); \ - mod->field = NULL; \ + kfree(mod->field); \ + mod->field = NULL; \ } \ static struct module_attribute modinfo_##field = { \ .attr = { .name = __stringify(field), .mode = 0444 }, \ @@ -990,7 +990,7 @@ static void add_sect_attrs(struct module *mod, unsigned int nsect, struct module_sect_attrs *sect_attrs; struct module_sect_attr *sattr; struct attribute **gattr; - + /* Count loaded sections and allocate structures */ for (i = 0; i < nsect; i++) if (sechdrs[i].sh_flags & SHF_ALLOC) @@ -1348,14 +1348,14 @@ static int verify_export_symbols(struct module *mod) const unsigned long *crc; for (i = 0; i < mod->num_syms; i++) - if (__find_symbol(mod->syms[i].name, &owner, &crc, 1)) { + if (__find_symbol(mod->syms[i].name, &owner, &crc, 1)) { name = mod->syms[i].name; ret = -ENOEXEC; goto dup; } for (i = 0; i < mod->num_gpl_syms; i++) - if (__find_symbol(mod->gpl_syms[i].name, &owner, &crc, 1)) { + if (__find_symbol(mod->gpl_syms[i].name, &owner, &crc, 1)) { name = mod->gpl_syms[i].name; ret = -ENOEXEC; goto dup; @@ -1673,8 +1673,6 @@ static struct module *load_module(void __user *umod, unsigned int unusedcrcindex; unsigned int unusedgplindex; unsigned int unusedgplcrcindex; - unsigned int markersindex; - unsigned int markersstringsindex; struct module *mod; long err = 0; void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */ @@ -1931,7 +1929,7 @@ static struct module *load_module(void __user *umod, mod->unused_crcs = (void *)sechdrs[unusedgplcrcindex].sh_addr; #ifdef CONFIG_MODVERSIONS - if ((mod->num_syms && !crcindex) || + if ((mod->num_syms && !crcindex) || (mod->num_gpl_syms && !gplcrcindex) || (mod->num_gpl_future_syms && !gplfuturecrcindex) || (mod->num_unused_syms && !unusedcrcindex) || @@ -1941,9 +1939,6 @@ static struct module *load_module(void __user *umod, add_taint_module(mod, TAINT_FORCED_MODULE); } #endif - markersindex = find_sec(hdr, sechdrs, secstrings, "__markers"); - markersstringsindex = find_sec(hdr, sechdrs, secstrings, - "__markers_strings"); /* Now do relocations. */ for (i = 1; i < hdr->e_shnum; i++) { @@ -1966,11 +1961,6 @@ static struct module *load_module(void __user *umod, if (err < 0) goto cleanup; } -#ifdef CONFIG_MARKERS - mod->markers = (void *)sechdrs[markersindex].sh_addr; - mod->num_markers = - sechdrs[markersindex].sh_size / sizeof(*mod->markers); -#endif /* Find duplicate symbols */ err = verify_export_symbols(mod); @@ -1989,11 +1979,6 @@ static struct module *load_module(void __user *umod, add_kallsyms(mod, sechdrs, symindex, strindex, secstrings); -#ifdef CONFIG_MARKERS - if (!mod->taints) - marker_update_probe_range(mod->markers, - mod->markers + mod->num_markers, NULL, NULL); -#endif err = module_finalize(hdr, sechdrs, mod); if (err < 0) goto cleanup; @@ -2031,7 +2016,7 @@ static struct module *load_module(void __user *umod, if (err < 0) goto arch_cleanup; - err = mod_sysfs_setup(mod, + err = mod_sysfs_setup(mod, (struct kernel_param *) sechdrs[setupindex].sh_addr, sechdrs[setupindex].sh_size @@ -2043,8 +2028,8 @@ static struct module *load_module(void __user *umod, /* Size of section 0 is 0, so this works well if no unwind info. */ mod->unwind_info = unwind_add_table(mod, - (void *)sechdrs[unwindex].sh_addr, - sechdrs[unwindex].sh_size); + (void *)sechdrs[unwindex].sh_addr, + sechdrs[unwindex].sh_size); /* Get rid of temporary copy */ vfree(hdr); @@ -2161,7 +2146,7 @@ static inline int within(unsigned long addr, void *start, unsigned long size) */ static inline int is_arm_mapping_symbol(const char *str) { - return str[0] == '$' && strchr("atd", str[1]) + return str[0] == '$' && strchr("atd", str[1]) && (str[2] == '\0' || str[2] == '.'); } @@ -2176,11 +2161,11 @@ static const char *get_ksymbol(struct module *mod, /* At worse, next value is at end of module */ if (within(addr, mod->module_init, mod->init_size)) nextval = (unsigned long)mod->module_init+mod->init_text_size; - else + else nextval = (unsigned long)mod->module_core+mod->core_text_size; /* Scan for closest preceeding symbol, and next symbol. (ELF - starts real symbols at 1). */ + starts real symbols at 1). */ for (i = 1; i < mod->num_symtab; i++) { if (mod->symtab[i].st_shndx == SHN_UNDEF) continue; @@ -2422,7 +2407,7 @@ const struct exception_table_entry *search_module_extables(unsigned long addr) list_for_each_entry(mod, &modules, list) { if (mod->num_exentries == 0) continue; - + e = search_extable(mod->extable, mod->extable + mod->num_exentries - 1, addr); @@ -2432,7 +2417,7 @@ const struct exception_table_entry *search_module_extables(unsigned long addr) preempt_enable(); /* Now, if we found one, we are running inside it now, hence - we cannot unload the module, hence no refcnt needed. */ + we cannot unload the module, hence no refcnt needed. */ return e; } @@ -2585,18 +2570,3 @@ EXPORT_SYMBOL(module_remove_driver); void struct_module(struct module *mod) { return; } EXPORT_SYMBOL(struct_module); #endif - -#ifdef CONFIG_MARKERS -void module_update_markers(struct module *probe_module, int *refcount) -{ - struct module *mod; - - mutex_lock(&module_mutex); - list_for_each_entry(mod, &modules, list) - if (!mod->taints) - marker_update_probe_range(mod->markers, - mod->markers + mod->num_markers, - probe_module, refcount); - mutex_unlock(&module_mutex); -} -#endif diff --git a/trunk/kernel/notifier.c b/trunk/kernel/notifier.c deleted file mode 100644 index 4253f472f060..000000000000 --- a/trunk/kernel/notifier.c +++ /dev/null @@ -1,539 +0,0 @@ -#include -#include -#include -#include -#include -#include - -/* - * Notifier list for kernel code which wants to be called - * at shutdown. This is used to stop any idling DMA operations - * and the like. - */ -BLOCKING_NOTIFIER_HEAD(reboot_notifier_list); - -/* - * Notifier chain core routines. The exported routines below - * are layered on top of these, with appropriate locking added. - */ - -static int notifier_chain_register(struct notifier_block **nl, - struct notifier_block *n) -{ - while ((*nl) != NULL) { - if (n->priority > (*nl)->priority) - break; - nl = &((*nl)->next); - } - n->next = *nl; - rcu_assign_pointer(*nl, n); - return 0; -} - -static int notifier_chain_unregister(struct notifier_block **nl, - struct notifier_block *n) -{ - while ((*nl) != NULL) { - if ((*nl) == n) { - rcu_assign_pointer(*nl, n->next); - return 0; - } - nl = &((*nl)->next); - } - return -ENOENT; -} - -/** - * notifier_call_chain - Informs the registered notifiers about an event. - * @nl: Pointer to head of the blocking notifier chain - * @val: Value passed unmodified to notifier function - * @v: Pointer passed unmodified to notifier function - * @nr_to_call: Number of notifier functions to be called. Don't care - * value of this parameter is -1. - * @nr_calls: Records the number of notifications sent. Don't care - * value of this field is NULL. - * @returns: notifier_call_chain returns the value returned by the - * last notifier function called. - */ -static int __kprobes notifier_call_chain(struct notifier_block **nl, - unsigned long val, void *v, - int nr_to_call, int *nr_calls) -{ - int ret = NOTIFY_DONE; - struct notifier_block *nb, *next_nb; - - nb = rcu_dereference(*nl); - - while (nb && nr_to_call) { - next_nb = rcu_dereference(nb->next); - ret = nb->notifier_call(nb, val, v); - - if (nr_calls) - (*nr_calls)++; - - if ((ret & NOTIFY_STOP_MASK) == NOTIFY_STOP_MASK) - break; - nb = next_nb; - nr_to_call--; - } - return ret; -} - -/* - * Atomic notifier chain routines. Registration and unregistration - * use a spinlock, and call_chain is synchronized by RCU (no locks). - */ - -/** - * atomic_notifier_chain_register - Add notifier to an atomic notifier chain - * @nh: Pointer to head of the atomic notifier chain - * @n: New entry in notifier chain - * - * Adds a notifier to an atomic notifier chain. - * - * Currently always returns zero. - */ -int atomic_notifier_chain_register(struct atomic_notifier_head *nh, - struct notifier_block *n) -{ - unsigned long flags; - int ret; - - spin_lock_irqsave(&nh->lock, flags); - ret = notifier_chain_register(&nh->head, n); - spin_unlock_irqrestore(&nh->lock, flags); - return ret; -} -EXPORT_SYMBOL_GPL(atomic_notifier_chain_register); - -/** - * atomic_notifier_chain_unregister - Remove notifier from an atomic notifier chain - * @nh: Pointer to head of the atomic notifier chain - * @n: Entry to remove from notifier chain - * - * Removes a notifier from an atomic notifier chain. - * - * Returns zero on success or %-ENOENT on failure. - */ -int atomic_notifier_chain_unregister(struct atomic_notifier_head *nh, - struct notifier_block *n) -{ - unsigned long flags; - int ret; - - spin_lock_irqsave(&nh->lock, flags); - ret = notifier_chain_unregister(&nh->head, n); - spin_unlock_irqrestore(&nh->lock, flags); - synchronize_rcu(); - return ret; -} -EXPORT_SYMBOL_GPL(atomic_notifier_chain_unregister); - -/** - * __atomic_notifier_call_chain - Call functions in an atomic notifier chain - * @nh: Pointer to head of the atomic notifier chain - * @val: Value passed unmodified to notifier function - * @v: Pointer passed unmodified to notifier function - * @nr_to_call: See the comment for notifier_call_chain. - * @nr_calls: See the comment for notifier_call_chain. - * - * Calls each function in a notifier chain in turn. The functions - * run in an atomic context, so they must not block. - * This routine uses RCU to synchronize with changes to the chain. - * - * If the return value of the notifier can be and'ed - * with %NOTIFY_STOP_MASK then atomic_notifier_call_chain() - * will return immediately, with the return value of - * the notifier function which halted execution. - * Otherwise the return value is the return value - * of the last notifier function called. - */ -int __kprobes __atomic_notifier_call_chain(struct atomic_notifier_head *nh, - unsigned long val, void *v, - int nr_to_call, int *nr_calls) -{ - int ret; - - rcu_read_lock(); - ret = notifier_call_chain(&nh->head, val, v, nr_to_call, nr_calls); - rcu_read_unlock(); - return ret; -} -EXPORT_SYMBOL_GPL(__atomic_notifier_call_chain); - -int __kprobes atomic_notifier_call_chain(struct atomic_notifier_head *nh, - unsigned long val, void *v) -{ - return __atomic_notifier_call_chain(nh, val, v, -1, NULL); -} -EXPORT_SYMBOL_GPL(atomic_notifier_call_chain); - -/* - * Blocking notifier chain routines. All access to the chain is - * synchronized by an rwsem. - */ - -/** - * blocking_notifier_chain_register - Add notifier to a blocking notifier chain - * @nh: Pointer to head of the blocking notifier chain - * @n: New entry in notifier chain - * - * Adds a notifier to a blocking notifier chain. - * Must be called in process context. - * - * Currently always returns zero. - */ -int blocking_notifier_chain_register(struct blocking_notifier_head *nh, - struct notifier_block *n) -{ - int ret; - - /* - * This code gets used during boot-up, when task switching is - * not yet working and interrupts must remain disabled. At - * such times we must not call down_write(). - */ - if (unlikely(system_state == SYSTEM_BOOTING)) - return notifier_chain_register(&nh->head, n); - - down_write(&nh->rwsem); - ret = notifier_chain_register(&nh->head, n); - up_write(&nh->rwsem); - return ret; -} -EXPORT_SYMBOL_GPL(blocking_notifier_chain_register); - -/** - * blocking_notifier_chain_unregister - Remove notifier from a blocking notifier chain - * @nh: Pointer to head of the blocking notifier chain - * @n: Entry to remove from notifier chain - * - * Removes a notifier from a blocking notifier chain. - * Must be called from process context. - * - * Returns zero on success or %-ENOENT on failure. - */ -int blocking_notifier_chain_unregister(struct blocking_notifier_head *nh, - struct notifier_block *n) -{ - int ret; - - /* - * This code gets used during boot-up, when task switching is - * not yet working and interrupts must remain disabled. At - * such times we must not call down_write(). - */ - if (unlikely(system_state == SYSTEM_BOOTING)) - return notifier_chain_unregister(&nh->head, n); - - down_write(&nh->rwsem); - ret = notifier_chain_unregister(&nh->head, n); - up_write(&nh->rwsem); - return ret; -} -EXPORT_SYMBOL_GPL(blocking_notifier_chain_unregister); - -/** - * __blocking_notifier_call_chain - Call functions in a blocking notifier chain - * @nh: Pointer to head of the blocking notifier chain - * @val: Value passed unmodified to notifier function - * @v: Pointer passed unmodified to notifier function - * @nr_to_call: See comment for notifier_call_chain. - * @nr_calls: See comment for notifier_call_chain. - * - * Calls each function in a notifier chain in turn. The functions - * run in a process context, so they are allowed to block. - * - * If the return value of the notifier can be and'ed - * with %NOTIFY_STOP_MASK then blocking_notifier_call_chain() - * will return immediately, with the return value of - * the notifier function which halted execution. - * Otherwise the return value is the return value - * of the last notifier function called. - */ -int __blocking_notifier_call_chain(struct blocking_notifier_head *nh, - unsigned long val, void *v, - int nr_to_call, int *nr_calls) -{ - int ret = NOTIFY_DONE; - - /* - * We check the head outside the lock, but if this access is - * racy then it does not matter what the result of the test - * is, we re-check the list after having taken the lock anyway: - */ - if (rcu_dereference(nh->head)) { - down_read(&nh->rwsem); - ret = notifier_call_chain(&nh->head, val, v, nr_to_call, - nr_calls); - up_read(&nh->rwsem); - } - return ret; -} -EXPORT_SYMBOL_GPL(__blocking_notifier_call_chain); - -int blocking_notifier_call_chain(struct blocking_notifier_head *nh, - unsigned long val, void *v) -{ - return __blocking_notifier_call_chain(nh, val, v, -1, NULL); -} -EXPORT_SYMBOL_GPL(blocking_notifier_call_chain); - -/* - * Raw notifier chain routines. There is no protection; - * the caller must provide it. Use at your own risk! - */ - -/** - * raw_notifier_chain_register - Add notifier to a raw notifier chain - * @nh: Pointer to head of the raw notifier chain - * @n: New entry in notifier chain - * - * Adds a notifier to a raw notifier chain. - * All locking must be provided by the caller. - * - * Currently always returns zero. - */ -int raw_notifier_chain_register(struct raw_notifier_head *nh, - struct notifier_block *n) -{ - return notifier_chain_register(&nh->head, n); -} -EXPORT_SYMBOL_GPL(raw_notifier_chain_register); - -/** - * raw_notifier_chain_unregister - Remove notifier from a raw notifier chain - * @nh: Pointer to head of the raw notifier chain - * @n: Entry to remove from notifier chain - * - * Removes a notifier from a raw notifier chain. - * All locking must be provided by the caller. - * - * Returns zero on success or %-ENOENT on failure. - */ -int raw_notifier_chain_unregister(struct raw_notifier_head *nh, - struct notifier_block *n) -{ - return notifier_chain_unregister(&nh->head, n); -} -EXPORT_SYMBOL_GPL(raw_notifier_chain_unregister); - -/** - * __raw_notifier_call_chain - Call functions in a raw notifier chain - * @nh: Pointer to head of the raw notifier chain - * @val: Value passed unmodified to notifier function - * @v: Pointer passed unmodified to notifier function - * @nr_to_call: See comment for notifier_call_chain. - * @nr_calls: See comment for notifier_call_chain - * - * Calls each function in a notifier chain in turn. The functions - * run in an undefined context. - * All locking must be provided by the caller. - * - * If the return value of the notifier can be and'ed - * with %NOTIFY_STOP_MASK then raw_notifier_call_chain() - * will return immediately, with the return value of - * the notifier function which halted execution. - * Otherwise the return value is the return value - * of the last notifier function called. - */ -int __raw_notifier_call_chain(struct raw_notifier_head *nh, - unsigned long val, void *v, - int nr_to_call, int *nr_calls) -{ - return notifier_call_chain(&nh->head, val, v, nr_to_call, nr_calls); -} -EXPORT_SYMBOL_GPL(__raw_notifier_call_chain); - -int raw_notifier_call_chain(struct raw_notifier_head *nh, - unsigned long val, void *v) -{ - return __raw_notifier_call_chain(nh, val, v, -1, NULL); -} -EXPORT_SYMBOL_GPL(raw_notifier_call_chain); - -/* - * SRCU notifier chain routines. Registration and unregistration - * use a mutex, and call_chain is synchronized by SRCU (no locks). - */ - -/** - * srcu_notifier_chain_register - Add notifier to an SRCU notifier chain - * @nh: Pointer to head of the SRCU notifier chain - * @n: New entry in notifier chain - * - * Adds a notifier to an SRCU notifier chain. - * Must be called in process context. - * - * Currently always returns zero. - */ -int srcu_notifier_chain_register(struct srcu_notifier_head *nh, - struct notifier_block *n) -{ - int ret; - - /* - * This code gets used during boot-up, when task switching is - * not yet working and interrupts must remain disabled. At - * such times we must not call mutex_lock(). - */ - if (unlikely(system_state == SYSTEM_BOOTING)) - return notifier_chain_register(&nh->head, n); - - mutex_lock(&nh->mutex); - ret = notifier_chain_register(&nh->head, n); - mutex_unlock(&nh->mutex); - return ret; -} -EXPORT_SYMBOL_GPL(srcu_notifier_chain_register); - -/** - * srcu_notifier_chain_unregister - Remove notifier from an SRCU notifier chain - * @nh: Pointer to head of the SRCU notifier chain - * @n: Entry to remove from notifier chain - * - * Removes a notifier from an SRCU notifier chain. - * Must be called from process context. - * - * Returns zero on success or %-ENOENT on failure. - */ -int srcu_notifier_chain_unregister(struct srcu_notifier_head *nh, - struct notifier_block *n) -{ - int ret; - - /* - * This code gets used during boot-up, when task switching is - * not yet working and interrupts must remain disabled. At - * such times we must not call mutex_lock(). - */ - if (unlikely(system_state == SYSTEM_BOOTING)) - return notifier_chain_unregister(&nh->head, n); - - mutex_lock(&nh->mutex); - ret = notifier_chain_unregister(&nh->head, n); - mutex_unlock(&nh->mutex); - synchronize_srcu(&nh->srcu); - return ret; -} -EXPORT_SYMBOL_GPL(srcu_notifier_chain_unregister); - -/** - * __srcu_notifier_call_chain - Call functions in an SRCU notifier chain - * @nh: Pointer to head of the SRCU notifier chain - * @val: Value passed unmodified to notifier function - * @v: Pointer passed unmodified to notifier function - * @nr_to_call: See comment for notifier_call_chain. - * @nr_calls: See comment for notifier_call_chain - * - * Calls each function in a notifier chain in turn. The functions - * run in a process context, so they are allowed to block. - * - * If the return value of the notifier can be and'ed - * with %NOTIFY_STOP_MASK then srcu_notifier_call_chain() - * will return immediately, with the return value of - * the notifier function which halted execution. - * Otherwise the return value is the return value - * of the last notifier function called. - */ -int __srcu_notifier_call_chain(struct srcu_notifier_head *nh, - unsigned long val, void *v, - int nr_to_call, int *nr_calls) -{ - int ret; - int idx; - - idx = srcu_read_lock(&nh->srcu); - ret = notifier_call_chain(&nh->head, val, v, nr_to_call, nr_calls); - srcu_read_unlock(&nh->srcu, idx); - return ret; -} -EXPORT_SYMBOL_GPL(__srcu_notifier_call_chain); - -int srcu_notifier_call_chain(struct srcu_notifier_head *nh, - unsigned long val, void *v) -{ - return __srcu_notifier_call_chain(nh, val, v, -1, NULL); -} -EXPORT_SYMBOL_GPL(srcu_notifier_call_chain); - -/** - * srcu_init_notifier_head - Initialize an SRCU notifier head - * @nh: Pointer to head of the srcu notifier chain - * - * Unlike other sorts of notifier heads, SRCU notifier heads require - * dynamic initialization. Be sure to call this routine before - * calling any of the other SRCU notifier routines for this head. - * - * If an SRCU notifier head is deallocated, it must first be cleaned - * up by calling srcu_cleanup_notifier_head(). Otherwise the head's - * per-cpu data (used by the SRCU mechanism) will leak. - */ -void srcu_init_notifier_head(struct srcu_notifier_head *nh) -{ - mutex_init(&nh->mutex); - if (init_srcu_struct(&nh->srcu) < 0) - BUG(); - nh->head = NULL; -} -EXPORT_SYMBOL_GPL(srcu_init_notifier_head); - -/** - * register_reboot_notifier - Register function to be called at reboot time - * @nb: Info about notifier function to be called - * - * Registers a function with the list of functions - * to be called at reboot time. - * - * Currently always returns zero, as blocking_notifier_chain_register() - * always returns zero. - */ -int register_reboot_notifier(struct notifier_block *nb) -{ - return blocking_notifier_chain_register(&reboot_notifier_list, nb); -} -EXPORT_SYMBOL(register_reboot_notifier); - -/** - * unregister_reboot_notifier - Unregister previously registered reboot notifier - * @nb: Hook to be unregistered - * - * Unregisters a previously registered reboot - * notifier function. - * - * Returns zero on success, or %-ENOENT on failure. - */ -int unregister_reboot_notifier(struct notifier_block *nb) -{ - return blocking_notifier_chain_unregister(&reboot_notifier_list, nb); -} -EXPORT_SYMBOL(unregister_reboot_notifier); - -static ATOMIC_NOTIFIER_HEAD(die_chain); - -int notify_die(enum die_val val, const char *str, - struct pt_regs *regs, long err, int trap, int sig) -{ - struct die_args args = { - .regs = regs, - .str = str, - .err = err, - .trapnr = trap, - .signr = sig, - - }; - return atomic_notifier_call_chain(&die_chain, val, &args); -} - -int register_die_notifier(struct notifier_block *nb) -{ - vmalloc_sync_all(); - return atomic_notifier_chain_register(&die_chain, nb); -} -EXPORT_SYMBOL_GPL(register_die_notifier); - -int unregister_die_notifier(struct notifier_block *nb) -{ - return atomic_notifier_chain_unregister(&die_chain, nb); -} -EXPORT_SYMBOL_GPL(unregister_die_notifier); diff --git a/trunk/kernel/ns_cgroup.c b/trunk/kernel/ns_cgroup.c deleted file mode 100644 index aead4d69f62b..000000000000 --- a/trunk/kernel/ns_cgroup.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * ns_cgroup.c - namespace cgroup subsystem - * - * Copyright 2006, 2007 IBM Corp - */ - -#include -#include -#include - -struct ns_cgroup { - struct cgroup_subsys_state css; - spinlock_t lock; -}; - -struct cgroup_subsys ns_subsys; - -static inline struct ns_cgroup *cgroup_to_ns( - struct cgroup *cgroup) -{ - return container_of(cgroup_subsys_state(cgroup, ns_subsys_id), - struct ns_cgroup, css); -} - -int ns_cgroup_clone(struct task_struct *task) -{ - return cgroup_clone(task, &ns_subsys); -} - -/* - * Rules: - * 1. you can only enter a cgroup which is a child of your current - * cgroup - * 2. you can only place another process into a cgroup if - * a. you have CAP_SYS_ADMIN - * b. your cgroup is an ancestor of task's destination cgroup - * (hence either you are in the same cgroup as task, or in an - * ancestor cgroup thereof) - */ -static int ns_can_attach(struct cgroup_subsys *ss, - struct cgroup *new_cgroup, struct task_struct *task) -{ - struct cgroup *orig; - - if (current != task) { - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - - if (!cgroup_is_descendant(new_cgroup)) - return -EPERM; - } - - if (atomic_read(&new_cgroup->count) != 0) - return -EPERM; - - orig = task_cgroup(task, ns_subsys_id); - if (orig && orig != new_cgroup->parent) - return -EPERM; - - return 0; -} - -/* - * Rules: you can only create a cgroup if - * 1. you are capable(CAP_SYS_ADMIN) - * 2. the target cgroup is a descendant of your own cgroup - */ -static struct cgroup_subsys_state *ns_create(struct cgroup_subsys *ss, - struct cgroup *cgroup) -{ - struct ns_cgroup *ns_cgroup; - - if (!capable(CAP_SYS_ADMIN)) - return ERR_PTR(-EPERM); - if (!cgroup_is_descendant(cgroup)) - return ERR_PTR(-EPERM); - - ns_cgroup = kzalloc(sizeof(*ns_cgroup), GFP_KERNEL); - if (!ns_cgroup) - return ERR_PTR(-ENOMEM); - spin_lock_init(&ns_cgroup->lock); - return &ns_cgroup->css; -} - -static void ns_destroy(struct cgroup_subsys *ss, - struct cgroup *cgroup) -{ - struct ns_cgroup *ns_cgroup; - - ns_cgroup = cgroup_to_ns(cgroup); - kfree(ns_cgroup); -} - -struct cgroup_subsys ns_subsys = { - .name = "ns", - .can_attach = ns_can_attach, - .create = ns_create, - .destroy = ns_destroy, - .subsys_id = ns_subsys_id, -}; diff --git a/trunk/kernel/nsproxy.c b/trunk/kernel/nsproxy.c index 79f871bc0ef4..049e7c0ac566 100644 --- a/trunk/kernel/nsproxy.c +++ b/trunk/kernel/nsproxy.c @@ -26,6 +26,19 @@ static struct kmem_cache *nsproxy_cachep; struct nsproxy init_nsproxy = INIT_NSPROXY(init_nsproxy); +static inline void get_nsproxy(struct nsproxy *ns) +{ + atomic_inc(&ns->count); +} + +void get_task_namespaces(struct task_struct *tsk) +{ + struct nsproxy *ns = tsk->nsproxy; + if (ns) { + get_nsproxy(ns); + } +} + /* * creates a copy of "orig" with refcount 1. */ @@ -74,7 +87,7 @@ static struct nsproxy *create_new_namespaces(unsigned long flags, goto out_ipc; } - new_nsp->pid_ns = copy_pid_ns(flags, task_active_pid_ns(tsk)); + new_nsp->pid_ns = copy_pid_ns(flags, tsk->nsproxy->pid_ns); if (IS_ERR(new_nsp->pid_ns)) { err = PTR_ERR(new_nsp->pid_ns); goto out_pid; @@ -129,8 +142,7 @@ int copy_namespaces(unsigned long flags, struct task_struct *tsk) get_nsproxy(old_ns); - if (!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC | - CLONE_NEWUSER | CLONE_NEWPID | CLONE_NEWNET))) + if (!(flags & (CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWIPC | CLONE_NEWUSER | CLONE_NEWNET))) return 0; if (!capable(CAP_SYS_ADMIN)) { @@ -144,14 +156,7 @@ int copy_namespaces(unsigned long flags, struct task_struct *tsk) goto out; } - err = ns_cgroup_clone(tsk); - if (err) { - put_nsproxy(new_ns); - goto out; - } - tsk->nsproxy = new_ns; - out: put_nsproxy(old_ns); return err; @@ -191,46 +196,11 @@ int unshare_nsproxy_namespaces(unsigned long unshare_flags, *new_nsp = create_new_namespaces(unshare_flags, current, new_fs ? new_fs : current->fs); - if (IS_ERR(*new_nsp)) { + if (IS_ERR(*new_nsp)) err = PTR_ERR(*new_nsp); - goto out; - } - - err = ns_cgroup_clone(current); - if (err) - put_nsproxy(*new_nsp); - -out: return err; } -void switch_task_namespaces(struct task_struct *p, struct nsproxy *new) -{ - struct nsproxy *ns; - - might_sleep(); - - ns = p->nsproxy; - - rcu_assign_pointer(p->nsproxy, new); - - if (ns && atomic_dec_and_test(&ns->count)) { - /* - * wait for others to get what they want from this nsproxy. - * - * cannot release this nsproxy via the call_rcu() since - * put_mnt_ns() will want to sleep - */ - synchronize_rcu(); - free_nsproxy(ns); - } -} - -void exit_task_namespaces(struct task_struct *p) -{ - switch_task_namespaces(p, NULL); -} - static int __init nsproxy_cache_init(void) { nsproxy_cachep = KMEM_CACHE(nsproxy, SLAB_PANIC); diff --git a/trunk/kernel/panic.c b/trunk/kernel/panic.c index 3886bd8230fe..f64f4c1ac11f 100644 --- a/trunk/kernel/panic.c +++ b/trunk/kernel/panic.c @@ -56,14 +56,14 @@ EXPORT_SYMBOL(panic_blink); * * This function never returns. */ - + NORET_TYPE void panic(const char * fmt, ...) { long i; static char buf[1024]; va_list args; #if defined(CONFIG_S390) - unsigned long caller = (unsigned long) __builtin_return_address(0); + unsigned long caller = (unsigned long) __builtin_return_address(0); #endif /* @@ -128,7 +128,7 @@ NORET_TYPE void panic(const char * fmt, ...) } #endif #if defined(CONFIG_S390) - disabled_wait(caller); + disabled_wait(caller); #endif local_irq_enable(); for (i = 0;;) { @@ -154,7 +154,7 @@ EXPORT_SYMBOL(panic); * * The string is overwritten by the next call to print_taint(). */ - + const char *print_tainted(void) { static char buf[20]; @@ -164,7 +164,7 @@ const char *print_tainted(void) tainted & TAINT_FORCED_MODULE ? 'F' : ' ', tainted & TAINT_UNSAFE_SMP ? 'S' : ' ', tainted & TAINT_FORCED_RMMOD ? 'R' : ' ', - tainted & TAINT_MACHINE_CHECK ? 'M' : ' ', + tainted & TAINT_MACHINE_CHECK ? 'M' : ' ', tainted & TAINT_BAD_PAGE ? 'B' : ' ', tainted & TAINT_USER ? 'U' : ' ', tainted & TAINT_DIE ? 'D' : ' '); diff --git a/trunk/kernel/params.c b/trunk/kernel/params.c index 16f269e9ddc9..1d6aca288cdc 100644 --- a/trunk/kernel/params.c +++ b/trunk/kernel/params.c @@ -592,17 +592,11 @@ static void __init param_sysfs_builtin(void) for (i=0; i < __stop___param - __start___param; i++) { char *dot; - size_t kplen; kp = &__start___param[i]; - kplen = strlen(kp->name); /* We do not handle args without periods. */ - if (kplen > MAX_KBUILD_MODNAME) { - DEBUGP("kernel parameter name is too long: %s\n", kp->name); - continue; - } - dot = memchr(kp->name, '.', kplen); + dot = memchr(kp->name, '.', MAX_KBUILD_MODNAME); if (!dot) { DEBUGP("couldn't find period in %s\n", kp->name); continue; diff --git a/trunk/kernel/pid.c b/trunk/kernel/pid.c index d1db36b94674..c6e3f9ffff87 100644 --- a/trunk/kernel/pid.c +++ b/trunk/kernel/pid.c @@ -18,12 +18,6 @@ * allocation scenario when all but one out of 1 million PIDs possible are * allocated already: the scanning of 32 list entries and at most PAGE_SIZE * bytes. The typical fastpath is a single successful setbit. Freeing is O(1). - * - * Pid namespaces: - * (C) 2007 Pavel Emelyanov , OpenVZ, SWsoft Inc. - * (C) 2007 Sukadev Bhattiprolu , IBM - * Many thanks to Oleg Nesterov for comments and help - * */ #include @@ -34,14 +28,12 @@ #include #include #include -#include -#define pid_hashfn(nr, ns) \ - hash_long((unsigned long)nr + (unsigned long)ns, pidhash_shift) +#define pid_hashfn(nr) hash_long((unsigned long)nr, pidhash_shift) static struct hlist_head *pid_hash; static int pidhash_shift; +static struct kmem_cache *pid_cachep; struct pid init_struct_pid = INIT_STRUCT_PID; -static struct kmem_cache *pid_ns_cachep; int pid_max = PID_MAX_DEFAULT; @@ -76,25 +68,8 @@ struct pid_namespace init_pid_ns = { [ 0 ... PIDMAP_ENTRIES-1] = { ATOMIC_INIT(BITS_PER_PAGE), NULL } }, .last_pid = 0, - .level = 0, - .child_reaper = &init_task, + .child_reaper = &init_task }; -EXPORT_SYMBOL_GPL(init_pid_ns); - -int is_container_init(struct task_struct *tsk) -{ - int ret = 0; - struct pid *pid; - - rcu_read_lock(); - pid = task_pid(tsk); - if (pid != NULL && pid->numbers[pid->level].nr == 1) - ret = 1; - rcu_read_unlock(); - - return ret; -} -EXPORT_SYMBOL(is_container_init); /* * Note: disable interrupts while the pidmap_lock is held as an @@ -201,17 +176,11 @@ static int next_pidmap(struct pid_namespace *pid_ns, int last) fastcall void put_pid(struct pid *pid) { - struct pid_namespace *ns; - if (!pid) return; - - ns = pid->numbers[pid->level].ns; if ((atomic_read(&pid->count) == 1) || - atomic_dec_and_test(&pid->count)) { - kmem_cache_free(ns->pid_cachep, pid); - put_pid_ns(ns); - } + atomic_dec_and_test(&pid->count)) + kmem_cache_free(pid_cachep, pid); } EXPORT_SYMBOL_GPL(put_pid); @@ -224,94 +193,60 @@ static void delayed_put_pid(struct rcu_head *rhp) fastcall void free_pid(struct pid *pid) { /* We can be called with write_lock_irq(&tasklist_lock) held */ - int i; unsigned long flags; spin_lock_irqsave(&pidmap_lock, flags); - for (i = 0; i <= pid->level; i++) - hlist_del_rcu(&pid->numbers[i].pid_chain); + hlist_del_rcu(&pid->pid_chain); spin_unlock_irqrestore(&pidmap_lock, flags); - for (i = 0; i <= pid->level; i++) - free_pidmap(pid->numbers[i].ns, pid->numbers[i].nr); - + free_pidmap(&init_pid_ns, pid->nr); call_rcu(&pid->rcu, delayed_put_pid); } -struct pid *alloc_pid(struct pid_namespace *ns) +struct pid *alloc_pid(void) { struct pid *pid; enum pid_type type; - int i, nr; - struct pid_namespace *tmp; - struct upid *upid; + int nr = -1; - pid = kmem_cache_alloc(ns->pid_cachep, GFP_KERNEL); + pid = kmem_cache_alloc(pid_cachep, GFP_KERNEL); if (!pid) goto out; - tmp = ns; - for (i = ns->level; i >= 0; i--) { - nr = alloc_pidmap(tmp); - if (nr < 0) - goto out_free; - - pid->numbers[i].nr = nr; - pid->numbers[i].ns = tmp; - tmp = tmp->parent; - } + nr = alloc_pidmap(current->nsproxy->pid_ns); + if (nr < 0) + goto out_free; - get_pid_ns(ns); - pid->level = ns->level; atomic_set(&pid->count, 1); + pid->nr = nr; for (type = 0; type < PIDTYPE_MAX; ++type) INIT_HLIST_HEAD(&pid->tasks[type]); spin_lock_irq(&pidmap_lock); - for (i = ns->level; i >= 0; i--) { - upid = &pid->numbers[i]; - hlist_add_head_rcu(&upid->pid_chain, - &pid_hash[pid_hashfn(upid->nr, upid->ns)]); - } + hlist_add_head_rcu(&pid->pid_chain, &pid_hash[pid_hashfn(pid->nr)]); spin_unlock_irq(&pidmap_lock); out: return pid; out_free: - for (i++; i <= ns->level; i++) - free_pidmap(pid->numbers[i].ns, pid->numbers[i].nr); - - kmem_cache_free(ns->pid_cachep, pid); + kmem_cache_free(pid_cachep, pid); pid = NULL; goto out; } -struct pid * fastcall find_pid_ns(int nr, struct pid_namespace *ns) +struct pid * fastcall find_pid(int nr) { struct hlist_node *elem; - struct upid *pnr; - - hlist_for_each_entry_rcu(pnr, elem, - &pid_hash[pid_hashfn(nr, ns)], pid_chain) - if (pnr->nr == nr && pnr->ns == ns) - return container_of(pnr, struct pid, - numbers[ns->level]); + struct pid *pid; + hlist_for_each_entry_rcu(pid, elem, + &pid_hash[pid_hashfn(nr)], pid_chain) { + if (pid->nr == nr) + return pid; + } return NULL; } -EXPORT_SYMBOL_GPL(find_pid_ns); - -struct pid *find_vpid(int nr) -{ - return find_pid_ns(nr, current->nsproxy->pid_ns); -} -EXPORT_SYMBOL_GPL(find_vpid); - -struct pid *find_pid(int nr) -{ - return find_pid_ns(nr, &init_pid_ns); -} EXPORT_SYMBOL_GPL(find_pid); /* @@ -372,32 +307,12 @@ struct task_struct * fastcall pid_task(struct pid *pid, enum pid_type type) /* * Must be called under rcu_read_lock() or with tasklist_lock read-held. */ -struct task_struct *find_task_by_pid_type_ns(int type, int nr, - struct pid_namespace *ns) +struct task_struct *find_task_by_pid_type(int type, int nr) { - return pid_task(find_pid_ns(nr, ns), type); + return pid_task(find_pid(nr), type); } -EXPORT_SYMBOL(find_task_by_pid_type_ns); - -struct task_struct *find_task_by_pid(pid_t nr) -{ - return find_task_by_pid_type_ns(PIDTYPE_PID, nr, &init_pid_ns); -} -EXPORT_SYMBOL(find_task_by_pid); - -struct task_struct *find_task_by_vpid(pid_t vnr) -{ - return find_task_by_pid_type_ns(PIDTYPE_PID, vnr, - current->nsproxy->pid_ns); -} -EXPORT_SYMBOL(find_task_by_vpid); - -struct task_struct *find_task_by_pid_ns(pid_t nr, struct pid_namespace *ns) -{ - return find_task_by_pid_type_ns(PIDTYPE_PID, nr, ns); -} -EXPORT_SYMBOL(find_task_by_pid_ns); +EXPORT_SYMBOL(find_task_by_pid_type); struct pid *get_task_pid(struct task_struct *task, enum pid_type type) { @@ -424,239 +339,45 @@ struct pid *find_get_pid(pid_t nr) struct pid *pid; rcu_read_lock(); - pid = get_pid(find_vpid(nr)); + pid = get_pid(find_pid(nr)); rcu_read_unlock(); return pid; } -pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns) -{ - struct upid *upid; - pid_t nr = 0; - - if (pid && ns->level <= pid->level) { - upid = &pid->numbers[ns->level]; - if (upid->ns == ns) - nr = upid->nr; - } - return nr; -} - -pid_t task_pid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns) -{ - return pid_nr_ns(task_pid(tsk), ns); -} -EXPORT_SYMBOL(task_pid_nr_ns); - -pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns) -{ - return pid_nr_ns(task_tgid(tsk), ns); -} -EXPORT_SYMBOL(task_tgid_nr_ns); - -pid_t task_pgrp_nr_ns(struct task_struct *tsk, struct pid_namespace *ns) -{ - return pid_nr_ns(task_pgrp(tsk), ns); -} -EXPORT_SYMBOL(task_pgrp_nr_ns); - -pid_t task_session_nr_ns(struct task_struct *tsk, struct pid_namespace *ns) -{ - return pid_nr_ns(task_session(tsk), ns); -} -EXPORT_SYMBOL(task_session_nr_ns); - /* * Used by proc to find the first pid that is greater then or equal to nr. * * If there is a pid at nr this function is exactly the same as find_pid. */ -struct pid *find_ge_pid(int nr, struct pid_namespace *ns) +struct pid *find_ge_pid(int nr) { struct pid *pid; do { - pid = find_pid_ns(nr, ns); + pid = find_pid(nr); if (pid) break; - nr = next_pidmap(ns, nr); + nr = next_pidmap(current->nsproxy->pid_ns, nr); } while (nr > 0); return pid; } EXPORT_SYMBOL_GPL(find_get_pid); -struct pid_cache { - int nr_ids; - char name[16]; - struct kmem_cache *cachep; - struct list_head list; -}; - -static LIST_HEAD(pid_caches_lh); -static DEFINE_MUTEX(pid_caches_mutex); - -/* - * creates the kmem cache to allocate pids from. - * @nr_ids: the number of numerical ids this pid will have to carry - */ - -static struct kmem_cache *create_pid_cachep(int nr_ids) -{ - struct pid_cache *pcache; - struct kmem_cache *cachep; - - mutex_lock(&pid_caches_mutex); - list_for_each_entry (pcache, &pid_caches_lh, list) - if (pcache->nr_ids == nr_ids) - goto out; - - pcache = kmalloc(sizeof(struct pid_cache), GFP_KERNEL); - if (pcache == NULL) - goto err_alloc; - - snprintf(pcache->name, sizeof(pcache->name), "pid_%d", nr_ids); - cachep = kmem_cache_create(pcache->name, - sizeof(struct pid) + (nr_ids - 1) * sizeof(struct upid), - 0, SLAB_HWCACHE_ALIGN, NULL); - if (cachep == NULL) - goto err_cachep; - - pcache->nr_ids = nr_ids; - pcache->cachep = cachep; - list_add(&pcache->list, &pid_caches_lh); -out: - mutex_unlock(&pid_caches_mutex); - return pcache->cachep; - -err_cachep: - kfree(pcache); -err_alloc: - mutex_unlock(&pid_caches_mutex); - return NULL; -} - -static struct pid_namespace *create_pid_namespace(int level) -{ - struct pid_namespace *ns; - int i; - - ns = kmem_cache_alloc(pid_ns_cachep, GFP_KERNEL); - if (ns == NULL) - goto out; - - ns->pidmap[0].page = kzalloc(PAGE_SIZE, GFP_KERNEL); - if (!ns->pidmap[0].page) - goto out_free; - - ns->pid_cachep = create_pid_cachep(level + 1); - if (ns->pid_cachep == NULL) - goto out_free_map; - - kref_init(&ns->kref); - ns->last_pid = 0; - ns->child_reaper = NULL; - ns->level = level; - - set_bit(0, ns->pidmap[0].page); - atomic_set(&ns->pidmap[0].nr_free, BITS_PER_PAGE - 1); - - for (i = 1; i < PIDMAP_ENTRIES; i++) { - ns->pidmap[i].page = 0; - atomic_set(&ns->pidmap[i].nr_free, BITS_PER_PAGE); - } - - return ns; - -out_free_map: - kfree(ns->pidmap[0].page); -out_free: - kmem_cache_free(pid_ns_cachep, ns); -out: - return ERR_PTR(-ENOMEM); -} - -static void destroy_pid_namespace(struct pid_namespace *ns) -{ - int i; - - for (i = 0; i < PIDMAP_ENTRIES; i++) - kfree(ns->pidmap[i].page); - kmem_cache_free(pid_ns_cachep, ns); -} - struct pid_namespace *copy_pid_ns(unsigned long flags, struct pid_namespace *old_ns) { - struct pid_namespace *new_ns; - BUG_ON(!old_ns); - new_ns = get_pid_ns(old_ns); - if (!(flags & CLONE_NEWPID)) - goto out; - - new_ns = ERR_PTR(-EINVAL); - if (flags & CLONE_THREAD) - goto out_put; - - new_ns = create_pid_namespace(old_ns->level + 1); - if (!IS_ERR(new_ns)) - new_ns->parent = get_pid_ns(old_ns); - -out_put: - put_pid_ns(old_ns); -out: - return new_ns; + get_pid_ns(old_ns); + return old_ns; } void free_pid_ns(struct kref *kref) { - struct pid_namespace *ns, *parent; + struct pid_namespace *ns; ns = container_of(kref, struct pid_namespace, kref); - - parent = ns->parent; - destroy_pid_namespace(ns); - - if (parent != NULL) - put_pid_ns(parent); -} - -void zap_pid_ns_processes(struct pid_namespace *pid_ns) -{ - int nr; - int rc; - - /* - * The last thread in the cgroup-init thread group is terminating. - * Find remaining pid_ts in the namespace, signal and wait for them - * to exit. - * - * Note: This signals each threads in the namespace - even those that - * belong to the same thread group, To avoid this, we would have - * to walk the entire tasklist looking a processes in this - * namespace, but that could be unnecessarily expensive if the - * pid namespace has just a few processes. Or we need to - * maintain a tasklist for each pid namespace. - * - */ - read_lock(&tasklist_lock); - nr = next_pidmap(pid_ns, 1); - while (nr > 0) { - kill_proc_info(SIGKILL, SEND_SIG_PRIV, nr); - nr = next_pidmap(pid_ns, nr); - } - read_unlock(&tasklist_lock); - - do { - clear_thread_flag(TIF_SIGPENDING); - rc = sys_wait4(-1, NULL, __WALL, NULL); - } while (rc != -ECHILD); - - - /* Child reaper for the pid namespace is going away */ - pid_ns->child_reaper = NULL; - return; + kfree(ns); } /* @@ -691,9 +412,5 @@ void __init pidmap_init(void) set_bit(0, init_pid_ns.pidmap[0].page); atomic_dec(&init_pid_ns.pidmap[0].nr_free); - init_pid_ns.pid_cachep = create_pid_cachep(1); - if (init_pid_ns.pid_cachep == NULL) - panic("Can't create pid_1 cachep\n"); - - pid_ns_cachep = KMEM_CACHE(pid_namespace, SLAB_PANIC); + pid_cachep = KMEM_CACHE(pid, SLAB_PANIC); } diff --git a/trunk/kernel/posix-cpu-timers.c b/trunk/kernel/posix-cpu-timers.c index 68c96376e84a..b53c8fcd9d82 100644 --- a/trunk/kernel/posix-cpu-timers.c +++ b/trunk/kernel/posix-cpu-timers.c @@ -21,8 +21,8 @@ static int check_clock(const clockid_t which_clock) read_lock(&tasklist_lock); p = find_task_by_pid(pid); - if (!p || !(CPUCLOCK_PERTHREAD(which_clock) ? - same_thread_group(p, current) : thread_group_leader(p))) { + if (!p || (CPUCLOCK_PERTHREAD(which_clock) ? + p->tgid != current->tgid : p->tgid != pid)) { error = -EINVAL; } read_unlock(&tasklist_lock); @@ -308,13 +308,13 @@ int posix_cpu_clock_get(const clockid_t which_clock, struct timespec *tp) p = find_task_by_pid(pid); if (p) { if (CPUCLOCK_PERTHREAD(which_clock)) { - if (same_thread_group(p, current)) { + if (p->tgid == current->tgid) { error = cpu_clock_sample(which_clock, p, &rtn); } } else { read_lock(&tasklist_lock); - if (thread_group_leader(p) && p->signal) { + if (p->tgid == pid && p->signal) { error = cpu_clock_sample_group(which_clock, p, &rtn); @@ -355,7 +355,7 @@ int posix_cpu_timer_create(struct k_itimer *new_timer) p = current; } else { p = find_task_by_pid(pid); - if (p && !same_thread_group(p, current)) + if (p && p->tgid != current->tgid) p = NULL; } } else { @@ -363,7 +363,7 @@ int posix_cpu_timer_create(struct k_itimer *new_timer) p = current->group_leader; } else { p = find_task_by_pid(pid); - if (p && !thread_group_leader(p)) + if (p && p->tgid != pid) p = NULL; } } diff --git a/trunk/kernel/posix-timers.c b/trunk/kernel/posix-timers.c index 35b4bbfc78ff..d71ed09fe1dd 100644 --- a/trunk/kernel/posix-timers.c +++ b/trunk/kernel/posix-timers.c @@ -404,7 +404,7 @@ static struct task_struct * good_sigevent(sigevent_t * event) if ((event->sigev_notify & SIGEV_THREAD_ID ) && (!(rtn = find_task_by_pid(event->sigev_notify_thread_id)) || - !same_thread_group(rtn, current) || + rtn->tgid != current->tgid || (event->sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_SIGNAL)) return NULL; @@ -608,7 +608,7 @@ static struct k_itimer * lock_timer(timer_t timer_id, unsigned long *flags) spin_lock(&timr->it_lock); if ((timr->it_id != timer_id) || !(timr->it_process) || - !same_thread_group(timr->it_process, current)) { + timr->it_process->tgid != current->tgid) { spin_unlock(&timr->it_lock); spin_unlock_irqrestore(&idr_lock, *flags); timr = NULL; @@ -981,20 +981,9 @@ sys_clock_getres(const clockid_t which_clock, struct timespec __user *tp) static int common_nsleep(const clockid_t which_clock, int flags, struct timespec *tsave, struct timespec __user *rmtp) { - struct timespec rmt; - int ret; - - ret = hrtimer_nanosleep(tsave, rmtp ? &rmt : NULL, - flags & TIMER_ABSTIME ? - HRTIMER_MODE_ABS : HRTIMER_MODE_REL, - which_clock); - - if (ret && rmtp) { - if (copy_to_user(rmtp, &rmt, sizeof(*rmtp))) - return -EFAULT; - } - - return ret; + return hrtimer_nanosleep(tsave, rmtp, flags & TIMER_ABSTIME ? + HRTIMER_MODE_ABS : HRTIMER_MODE_REL, + which_clock); } asmlinkage long diff --git a/trunk/kernel/power/Kconfig b/trunk/kernel/power/Kconfig index 8e186c678149..14b0e10dc95c 100644 --- a/trunk/kernel/power/Kconfig +++ b/trunk/kernel/power/Kconfig @@ -44,6 +44,17 @@ config PM_VERBOSE ---help--- This option enables verbose messages from the Power Management code. +config DISABLE_CONSOLE_SUSPEND + bool "Keep console(s) enabled during suspend/resume (DANGEROUS)" + depends on PM_DEBUG && PM_SLEEP + default n + ---help--- + This option turns off the console suspend mechanism that prevents + debug messages from reaching the console during the suspend/resume + operations. This may be helpful when debugging device drivers' + suspend/resume routines, but may itself lead to problems, for example + if netconsole is used. + config PM_TRACE bool "Suspend/resume event tracing" depends on PM_DEBUG && X86 && PM_SLEEP && EXPERIMENTAL diff --git a/trunk/kernel/power/disk.c b/trunk/kernel/power/disk.c index 8b15f777010a..eb72255b5c86 100644 --- a/trunk/kernel/power/disk.c +++ b/trunk/kernel/power/disk.c @@ -45,18 +45,17 @@ enum { static int hibernation_mode = HIBERNATION_SHUTDOWN; -static struct platform_hibernation_ops *hibernation_ops; +static struct hibernation_ops *hibernation_ops; /** * hibernation_set_ops - set the global hibernate operations * @ops: the hibernation operations to use in subsequent hibernation transitions */ -void hibernation_set_ops(struct platform_hibernation_ops *ops) +void hibernation_set_ops(struct hibernation_ops *ops) { - if (ops && !(ops->start && ops->pre_snapshot && ops->finish - && ops->prepare && ops->enter && ops->pre_restore - && ops->restore_cleanup)) { + if (ops && !(ops->prepare && ops->enter && ops->finish + && ops->pre_restore && ops->restore_cleanup)) { WARN_ON(1); return; } @@ -70,37 +69,16 @@ void hibernation_set_ops(struct platform_hibernation_ops *ops) mutex_unlock(&pm_mutex); } -/** - * platform_start - tell the platform driver that we're starting - * hibernation - */ - -static int platform_start(int platform_mode) -{ - return (platform_mode && hibernation_ops) ? - hibernation_ops->start() : 0; -} /** - * platform_pre_snapshot - prepare the machine for hibernation using the + * platform_prepare - prepare the machine for hibernation using the * platform driver if so configured and return an error code if it fails */ -static int platform_pre_snapshot(int platform_mode) +static int platform_prepare(int platform_mode) { return (platform_mode && hibernation_ops) ? - hibernation_ops->pre_snapshot() : 0; -} - -/** - * platform_leave - prepare the machine for switching to the normal mode - * of operation using the platform driver (called with interrupts disabled) - */ - -static void platform_leave(int platform_mode) -{ - if (platform_mode && hibernation_ops) - hibernation_ops->leave(); + hibernation_ops->prepare() : 0; } /** @@ -139,51 +117,6 @@ static void platform_restore_cleanup(int platform_mode) hibernation_ops->restore_cleanup(); } -/** - * create_image - freeze devices that need to be frozen with interrupts - * off, create the hibernation image and thaw those devices. Control - * reappears in this routine after a restore. - */ - -int create_image(int platform_mode) -{ - int error; - - error = arch_prepare_suspend(); - if (error) - return error; - - local_irq_disable(); - /* At this point, device_suspend() has been called, but *not* - * device_power_down(). We *must* call device_power_down() now. - * Otherwise, drivers for some devices (e.g. interrupt controllers) - * become desynchronized with the actual state of the hardware - * at resume time, and evil weirdness ensues. - */ - error = device_power_down(PMSG_FREEZE); - if (error) { - printk(KERN_ERR "Some devices failed to power down, " - KERN_ERR "aborting suspend\n"); - goto Enable_irqs; - } - - save_processor_state(); - error = swsusp_arch_suspend(); - if (error) - printk(KERN_ERR "Error %d while creating the image\n", error); - /* Restore control flow magically appears here */ - restore_processor_state(); - if (!in_suspend) - platform_leave(platform_mode); - /* NOTE: device_power_up() is just a resume() for devices - * that suspended with irqs off ... no overall powerup. - */ - device_power_up(); - Enable_irqs: - local_irq_enable(); - return error; -} - /** * hibernation_snapshot - quiesce devices and create the hibernation * snapshot image. @@ -202,16 +135,12 @@ int hibernation_snapshot(int platform_mode) if (error) return error; - error = platform_start(platform_mode); - if (error) - return error; - suspend_console(); error = device_suspend(PMSG_FREEZE); if (error) goto Resume_console; - error = platform_pre_snapshot(platform_mode); + error = platform_prepare(platform_mode); if (error) goto Resume_devices; @@ -219,7 +148,7 @@ int hibernation_snapshot(int platform_mode) if (!error) { if (hibernation_mode != HIBERNATION_TEST) { in_suspend = 1; - error = create_image(platform_mode); + error = swsusp_suspend(); /* Control returns here after successful restore */ } else { printk("swsusp debug: Waiting for 5 seconds.\n"); @@ -278,50 +207,21 @@ int hibernation_platform_enter(void) { int error; - if (!hibernation_ops) - return -ENOSYS; - - /* - * We have cancelled the power transition by running - * hibernation_ops->finish() before saving the image, so we should let - * the firmware know that we're going to enter the sleep state after all - */ - error = hibernation_ops->start(); - if (error) - return error; - - suspend_console(); - error = device_suspend(PMSG_SUSPEND); - if (error) - goto Resume_console; - - error = hibernation_ops->prepare(); - if (error) - goto Resume_devices; - - error = disable_nonboot_cpus(); - if (error) - goto Finish; - - local_irq_disable(); - error = device_power_down(PMSG_SUSPEND); - if (!error) { - hibernation_ops->enter(); - /* We should never get here */ - while (1); + if (hibernation_ops) { + kernel_shutdown_prepare(SYSTEM_SUSPEND_DISK); + /* + * We have cancelled the power transition by running + * hibernation_ops->finish() before saving the image, so we + * should let the firmware know that we're going to enter the + * sleep state after all + */ + error = hibernation_ops->prepare(); + sysdev_shutdown(); + if (!error) + error = hibernation_ops->enter(); + } else { + error = -ENOSYS; } - local_irq_enable(); - - /* - * We don't need to reenable the nonboot CPUs or resume consoles, since - * the system is going to be halted anyway. - */ - Finish: - hibernation_ops->finish(); - Resume_devices: - device_resume(); - Resume_console: - resume_console(); return error; } @@ -338,14 +238,14 @@ static void power_down(void) case HIBERNATION_TEST: case HIBERNATION_TESTPROC: break; + case HIBERNATION_SHUTDOWN: + kernel_power_off(); + break; case HIBERNATION_REBOOT: kernel_restart(NULL); break; case HIBERNATION_PLATFORM: hibernation_platform_enter(); - case HIBERNATION_SHUTDOWN: - kernel_power_off(); - break; } kernel_halt(); /* @@ -398,10 +298,6 @@ int hibernate(void) if (error) goto Exit; - printk("Syncing filesystems ... "); - sys_sync(); - printk("done.\n"); - error = prepare_processes(); if (error) goto Finish; diff --git a/trunk/kernel/power/main.c b/trunk/kernel/power/main.c index 3cdf95b1dc92..350b485b3b60 100644 --- a/trunk/kernel/power/main.c +++ b/trunk/kernel/power/main.c @@ -20,7 +20,6 @@ #include #include #include -#include #include "power.h" @@ -33,32 +32,39 @@ DEFINE_MUTEX(pm_mutex); /* This is just an arbitrary number */ #define FREE_PAGE_NUMBER (100) -static struct platform_suspend_ops *suspend_ops; +struct pm_ops *pm_ops; /** - * suspend_set_ops - Set the global suspend method table. + * pm_set_ops - Set the global power method table. * @ops: Pointer to ops structure. */ -void suspend_set_ops(struct platform_suspend_ops *ops) +void pm_set_ops(struct pm_ops * ops) { mutex_lock(&pm_mutex); - suspend_ops = ops; + pm_ops = ops; mutex_unlock(&pm_mutex); } /** - * suspend_valid_only_mem - generic memory-only valid callback + * pm_valid_only_mem - generic memory-only valid callback * - * Platform drivers that implement mem suspend only and only need + * pm_ops drivers that implement mem suspend only and only need * to check for that in their .valid callback can use this instead * of rolling their own .valid callback. */ -int suspend_valid_only_mem(suspend_state_t state) +int pm_valid_only_mem(suspend_state_t state) { return state == PM_SUSPEND_MEM; } + +static inline void pm_finish(suspend_state_t state) +{ + if (pm_ops->finish) + pm_ops->finish(state); +} + /** * suspend_prepare - Do prep work before entering low-power state. * @@ -70,7 +76,7 @@ static int suspend_prepare(void) int error; unsigned int free_pages; - if (!suspend_ops || !suspend_ops->enter) + if (!pm_ops || !pm_ops->enter) return -EPERM; error = pm_notifier_call_chain(PM_SUSPEND_PREPARE); @@ -122,7 +128,7 @@ void __attribute__ ((weak)) arch_suspend_enable_irqs(void) * * This function should be called after devices have been suspended. */ -static int suspend_enter(suspend_state_t state) +int suspend_enter(suspend_state_t state) { int error = 0; @@ -133,7 +139,7 @@ static int suspend_enter(suspend_state_t state) printk(KERN_ERR "Some devices failed to power down\n"); goto Done; } - error = suspend_ops->enter(state); + error = pm_ops->enter(state); device_power_up(); Done: arch_suspend_enable_irqs(); @@ -150,11 +156,11 @@ int suspend_devices_and_enter(suspend_state_t state) { int error; - if (!suspend_ops) + if (!pm_ops) return -ENOSYS; - if (suspend_ops->set_target) { - error = suspend_ops->set_target(state); + if (pm_ops->set_target) { + error = pm_ops->set_target(state); if (error) return error; } @@ -164,8 +170,8 @@ int suspend_devices_and_enter(suspend_state_t state) printk(KERN_ERR "Some devices failed to suspend\n"); goto Resume_console; } - if (suspend_ops->prepare) { - error = suspend_ops->prepare(); + if (pm_ops->prepare) { + error = pm_ops->prepare(state); if (error) goto Resume_devices; } @@ -174,8 +180,7 @@ int suspend_devices_and_enter(suspend_state_t state) suspend_enter(state); enable_nonboot_cpus(); - if (suspend_ops->finish) - suspend_ops->finish(); + pm_finish(state); Resume_devices: device_resume(); Resume_console: @@ -209,7 +214,7 @@ static inline int valid_state(suspend_state_t state) /* All states need lowlevel support and need to be valid * to the lowlevel implementation, no valid callback * implies that none are valid. */ - if (!suspend_ops || !suspend_ops->valid || !suspend_ops->valid(state)) + if (!pm_ops || !pm_ops->valid || !pm_ops->valid(state)) return 0; return 1; } @@ -231,14 +236,9 @@ static int enter_state(suspend_state_t state) if (!valid_state(state)) return -ENODEV; - if (!mutex_trylock(&pm_mutex)) return -EBUSY; - printk("Syncing filesystems ... "); - sys_sync(); - printk("done.\n"); - pr_debug("PM: Preparing system for %s sleep\n", pm_states[state]); if ((error = suspend_prepare())) goto Unlock; diff --git a/trunk/kernel/power/power.h b/trunk/kernel/power/power.h index 195dc4611764..95fbf2dd3fe3 100644 --- a/trunk/kernel/power/power.h +++ b/trunk/kernel/power/power.h @@ -11,32 +11,14 @@ struct swsusp_info { unsigned long size; } __attribute__((aligned(PAGE_SIZE))); -#ifdef CONFIG_HIBERNATION -#ifdef CONFIG_ARCH_HIBERNATION_HEADER -/* Maximum size of architecture specific data in a hibernation header */ -#define MAX_ARCH_HEADER_SIZE (sizeof(struct new_utsname) + 4) -extern int arch_hibernation_header_save(void *addr, unsigned int max_size); -extern int arch_hibernation_header_restore(void *addr); - -static inline int init_header_complete(struct swsusp_info *info) -{ - return arch_hibernation_header_save(info, MAX_ARCH_HEADER_SIZE); -} - -static inline char *check_image_kernel(struct swsusp_info *info) -{ - return arch_hibernation_header_restore(info) ? - "architecture specific data" : NULL; -} -#endif /* CONFIG_ARCH_HIBERNATION_HEADER */ +#ifdef CONFIG_HIBERNATION /* * Keep some memory free so that I/O operations can succeed without paging * [Might this be more than 4 MB?] */ #define PAGES_FOR_IO ((4096 * 1024) >> PAGE_SHIFT) - /* * Keep 1 MB of memory free so that device drivers can allocate some pages in * their .suspend() routines without breaking the suspend to disk. @@ -183,6 +165,7 @@ extern int swsusp_swap_in_use(void); extern int swsusp_check(void); extern int swsusp_shrink_memory(void); extern void swsusp_free(void); +extern int swsusp_suspend(void); extern int swsusp_resume(void); extern int swsusp_read(unsigned int *flags_p); extern int swsusp_write(unsigned int flags); diff --git a/trunk/kernel/power/process.c b/trunk/kernel/power/process.c index 6533923e711b..3434940a3df1 100644 --- a/trunk/kernel/power/process.c +++ b/trunk/kernel/power/process.c @@ -75,79 +75,21 @@ void refrigerator(void) __set_current_state(save); } -static void fake_signal_wake_up(struct task_struct *p, int resume) +static void freeze_task(struct task_struct *p) { unsigned long flags; - spin_lock_irqsave(&p->sighand->siglock, flags); - signal_wake_up(p, resume); - spin_unlock_irqrestore(&p->sighand->siglock, flags); -} - -static void send_fake_signal(struct task_struct *p) -{ - if (p->state == TASK_STOPPED) - force_sig_specific(SIGSTOP, p); - fake_signal_wake_up(p, p->state == TASK_STOPPED); -} - -static int has_mm(struct task_struct *p) -{ - return (p->mm && !(p->flags & PF_BORROWED_MM)); -} - -/** - * freeze_task - send a freeze request to given task - * @p: task to send the request to - * @with_mm_only: if set, the request will only be sent if the task has its - * own mm - * Return value: 0, if @with_mm_only is set and the task has no mm of its - * own or the task is frozen, 1, otherwise - * - * The freeze request is sent by seting the tasks's TIF_FREEZE flag and - * either sending a fake signal to it or waking it up, depending on whether - * or not it has its own mm (ie. it is a user land task). If @with_mm_only - * is set and the task has no mm of its own (ie. it is a kernel thread), - * its TIF_FREEZE flag should not be set. - * - * The task_lock() is necessary to prevent races with exit_mm() or - * use_mm()/unuse_mm() from occuring. - */ -static int freeze_task(struct task_struct *p, int with_mm_only) -{ - int ret = 1; - - task_lock(p); - if (freezing(p)) { - if (has_mm(p)) { - if (!signal_pending(p)) - fake_signal_wake_up(p, 0); - } else { - if (with_mm_only) - ret = 0; - else - wake_up_state(p, TASK_INTERRUPTIBLE); - } - } else { + if (!freezing(p)) { rmb(); - if (frozen(p)) { - ret = 0; - } else { - if (has_mm(p)) { - set_freeze_flag(p); - send_fake_signal(p); - } else { - if (with_mm_only) { - ret = 0; - } else { - set_freeze_flag(p); - wake_up_state(p, TASK_INTERRUPTIBLE); - } - } + if (!frozen(p)) { + set_freeze_flag(p); + if (p->state == TASK_STOPPED) + force_sig_specific(SIGSTOP, p); + spin_lock_irqsave(&p->sighand->siglock, flags); + signal_wake_up(p, p->state == TASK_STOPPED); + spin_unlock_irqrestore(&p->sighand->siglock, flags); } } - task_unlock(p); - return ret; } static void cancel_freezing(struct task_struct *p) @@ -168,11 +110,6 @@ static int try_to_freeze_tasks(int freeze_user_space) struct task_struct *g, *p; unsigned long end_time; unsigned int todo; - struct timeval start, end; - s64 elapsed_csecs64; - unsigned int elapsed_csecs; - - do_gettimeofday(&start); end_time = jiffies + TIMEOUT; do { @@ -182,14 +119,31 @@ static int try_to_freeze_tasks(int freeze_user_space) if (frozen(p) || !freezeable(p)) continue; - if (p->state == TASK_TRACED && frozen(p->parent)) { - cancel_freezing(p); - continue; + if (freeze_user_space) { + if (p->state == TASK_TRACED && + frozen(p->parent)) { + cancel_freezing(p); + continue; + } + /* + * Kernel threads should not have TIF_FREEZE set + * at this point, so we must ensure that either + * p->mm is not NULL *and* PF_BORROWED_MM is + * unset, or TIF_FRREZE is left unset. + * The task_lock() is necessary to prevent races + * with exit_mm() or use_mm()/unuse_mm() from + * occuring. + */ + task_lock(p); + if (!p->mm || (p->flags & PF_BORROWED_MM)) { + task_unlock(p); + continue; + } + freeze_task(p); + task_unlock(p); + } else { + freeze_task(p); } - - if (!freeze_task(p, freeze_user_space)) - continue; - if (!freezer_should_skip(p)) todo++; } while_each_thread(g, p); @@ -199,11 +153,6 @@ static int try_to_freeze_tasks(int freeze_user_space) break; } while (todo); - do_gettimeofday(&end); - elapsed_csecs64 = timeval_to_ns(&end) - timeval_to_ns(&start); - do_div(elapsed_csecs64, NSEC_PER_SEC / 100); - elapsed_csecs = elapsed_csecs64; - if (todo) { /* This does not unfreeze processes that are already frozen * (we have slightly ugly calling convention in that respect, @@ -211,9 +160,10 @@ static int try_to_freeze_tasks(int freeze_user_space) * but it cleans up leftover PF_FREEZE requests. */ printk("\n"); - printk(KERN_ERR "Freezing of tasks failed after %d.%02d seconds " + printk(KERN_ERR "Freezing of %s timed out after %d seconds " "(%d tasks refusing to freeze):\n", - elapsed_csecs / 100, elapsed_csecs % 100, todo); + freeze_user_space ? "user space " : "tasks ", + TIMEOUT / HZ, todo); show_state(); read_lock(&tasklist_lock); do_each_thread(g, p) { @@ -224,9 +174,6 @@ static int try_to_freeze_tasks(int freeze_user_space) task_unlock(p); } while_each_thread(g, p); read_unlock(&tasklist_lock); - } else { - printk("(elapsed %d.%02d seconds) ", elapsed_csecs / 100, - elapsed_csecs % 100); } return todo ? -EBUSY : 0; @@ -239,21 +186,19 @@ int freeze_processes(void) { int error; - printk("Freezing user space processes ... "); + printk("Stopping tasks ... "); error = try_to_freeze_tasks(FREEZER_USER_SPACE); if (error) - goto Exit; - printk("done.\n"); + return error; - printk("Freezing remaining freezable tasks ... "); + sys_sync(); error = try_to_freeze_tasks(FREEZER_KERNEL_THREADS); if (error) - goto Exit; - printk("done."); - Exit: + return error; + + printk("done.\n"); BUG_ON(in_atomic()); - printk("\n"); - return error; + return 0; } static void thaw_tasks(int thaw_user_space) diff --git a/trunk/kernel/power/snapshot.c b/trunk/kernel/power/snapshot.c index ccc95ac07bed..a686590d88c1 100644 --- a/trunk/kernel/power/snapshot.c +++ b/trunk/kernel/power/snapshot.c @@ -1239,39 +1239,17 @@ asmlinkage int swsusp_save(void) return 0; } -#ifndef CONFIG_ARCH_HIBERNATION_HEADER -static int init_header_complete(struct swsusp_info *info) -{ - memcpy(&info->uts, init_utsname(), sizeof(struct new_utsname)); - info->version_code = LINUX_VERSION_CODE; - return 0; -} - -static char *check_image_kernel(struct swsusp_info *info) -{ - if (info->version_code != LINUX_VERSION_CODE) - return "kernel version"; - if (strcmp(info->uts.sysname,init_utsname()->sysname)) - return "system type"; - if (strcmp(info->uts.release,init_utsname()->release)) - return "kernel release"; - if (strcmp(info->uts.version,init_utsname()->version)) - return "version"; - if (strcmp(info->uts.machine,init_utsname()->machine)) - return "machine"; - return NULL; -} -#endif /* CONFIG_ARCH_HIBERNATION_HEADER */ - -static int init_header(struct swsusp_info *info) +static void init_header(struct swsusp_info *info) { memset(info, 0, sizeof(struct swsusp_info)); + info->version_code = LINUX_VERSION_CODE; info->num_physpages = num_physpages; + memcpy(&info->uts, init_utsname(), sizeof(struct new_utsname)); + info->cpus = num_online_cpus(); info->image_pages = nr_copy_pages; info->pages = nr_copy_pages + nr_meta_pages + 1; info->size = info->pages; info->size <<= PAGE_SHIFT; - return init_header_complete(info); } /** @@ -1325,11 +1303,7 @@ int snapshot_read_next(struct snapshot_handle *handle, size_t count) return -ENOMEM; } if (!handle->offset) { - int error; - - error = init_header((struct swsusp_info *)buffer); - if (error) - return error; + init_header((struct swsusp_info *)buffer); handle->buffer = buffer; memory_bm_position_reset(&orig_bm); memory_bm_position_reset(©_bm); @@ -1420,13 +1394,22 @@ duplicate_memory_bitmap(struct memory_bitmap *dst, struct memory_bitmap *src) } } -static int check_header(struct swsusp_info *info) +static inline int check_header(struct swsusp_info *info) { - char *reason; + char *reason = NULL; - reason = check_image_kernel(info); - if (!reason && info->num_physpages != num_physpages) + if (info->version_code != LINUX_VERSION_CODE) + reason = "kernel version"; + if (info->num_physpages != num_physpages) reason = "memory size"; + if (strcmp(info->uts.sysname,init_utsname()->sysname)) + reason = "system type"; + if (strcmp(info->uts.release,init_utsname()->release)) + reason = "kernel release"; + if (strcmp(info->uts.version,init_utsname()->version)) + reason = "version"; + if (strcmp(info->uts.machine,init_utsname()->machine)) + reason = "machine"; if (reason) { printk(KERN_ERR "swsusp: Resume mismatch: %s\n", reason); return -EPERM; diff --git a/trunk/kernel/power/swsusp.c b/trunk/kernel/power/swsusp.c index e1722d3155f1..5da304c8f1f6 100644 --- a/trunk/kernel/power/swsusp.c +++ b/trunk/kernel/power/swsusp.c @@ -270,6 +270,39 @@ int swsusp_shrink_memory(void) return 0; } +int swsusp_suspend(void) +{ + int error; + + if ((error = arch_prepare_suspend())) + return error; + + local_irq_disable(); + /* At this point, device_suspend() has been called, but *not* + * device_power_down(). We *must* device_power_down() now. + * Otherwise, drivers for some devices (e.g. interrupt controllers) + * become desynchronized with the actual state of the hardware + * at resume time, and evil weirdness ensues. + */ + if ((error = device_power_down(PMSG_FREEZE))) { + printk(KERN_ERR "Some devices failed to power down, aborting suspend\n"); + goto Enable_irqs; + } + + save_processor_state(); + if ((error = swsusp_arch_suspend())) + printk(KERN_ERR "Error %d suspending\n", error); + /* Restore control flow magically appears here */ + restore_processor_state(); + /* NOTE: device_power_up() is just a resume() for devices + * that suspended with irqs off ... no overall powerup. + */ + device_power_up(); + Enable_irqs: + local_irq_enable(); + return error; +} + int swsusp_resume(void) { int error; diff --git a/trunk/kernel/power/user.c b/trunk/kernel/power/user.c index 5bd321bcbb75..bd0723a7df3f 100644 --- a/trunk/kernel/power/user.c +++ b/trunk/kernel/power/user.c @@ -153,10 +153,6 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp, mutex_lock(&pm_mutex); error = pm_notifier_call_chain(PM_HIBERNATION_PREPARE); if (!error) { - printk("Syncing filesystems ... "); - sys_sync(); - printk("done.\n"); - error = freeze_processes(); if (error) thaw_processes(); diff --git a/trunk/kernel/printk.c b/trunk/kernel/printk.c index a30fe33de395..52493474f0ab 100644 --- a/trunk/kernel/printk.c +++ b/trunk/kernel/printk.c @@ -862,16 +862,7 @@ int update_console_cmdline(char *name, int idx, char *name_new, int idx_new, cha return -1; } -int console_suspend_enabled = 1; -EXPORT_SYMBOL(console_suspend_enabled); - -static int __init console_suspend_disable(char *str) -{ - console_suspend_enabled = 0; - return 1; -} -__setup("no_console_suspend", console_suspend_disable); - +#ifndef CONFIG_DISABLE_CONSOLE_SUSPEND /** * suspend_console - suspend the console subsystem * @@ -879,8 +870,6 @@ __setup("no_console_suspend", console_suspend_disable); */ void suspend_console(void) { - if (!console_suspend_enabled) - return; printk("Suspending console(s)\n"); acquire_console_sem(); console_suspended = 1; @@ -888,11 +877,10 @@ void suspend_console(void) void resume_console(void) { - if (!console_suspend_enabled) - return; console_suspended = 0; release_console_sem(); } +#endif /* CONFIG_DISABLE_CONSOLE_SUSPEND */ /** * acquire_console_sem - lock the console system for exclusive use. diff --git a/trunk/kernel/ptrace.c b/trunk/kernel/ptrace.c index 7c76f2ffaeaa..a73ebd3b9d4c 100644 --- a/trunk/kernel/ptrace.c +++ b/trunk/kernel/ptrace.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include @@ -169,7 +168,7 @@ int ptrace_attach(struct task_struct *task) retval = -EPERM; if (task->pid <= 1) goto out; - if (same_thread_group(task, current)) + if (task->tgid == current->tgid) goto out; repeat: @@ -444,7 +443,7 @@ struct task_struct *ptrace_get_task_struct(pid_t pid) return ERR_PTR(-EPERM); read_lock(&tasklist_lock); - child = find_task_by_vpid(pid); + child = find_task_by_pid(pid); if (child) get_task_struct(child); diff --git a/trunk/kernel/relay.c b/trunk/kernel/relay.c index 61134eb7a0c8..ad855017bc59 100644 --- a/trunk/kernel/relay.c +++ b/trunk/kernel/relay.c @@ -370,7 +370,7 @@ void relay_reset(struct rchan *chan) if (!chan) return; - if (chan->is_global && chan->buf[0]) { + if (chan->is_global && chan->buf[0]) { __relay_reset(chan->buf[0], 0); return; } @@ -850,13 +850,13 @@ static int relay_file_read_avail(struct rchan_buf *buf, size_t read_pos) buf->subbufs_consumed = consumed; buf->bytes_consumed = 0; } - + produced = (produced % n_subbufs) * subbuf_size + buf->offset; consumed = (consumed % n_subbufs) * subbuf_size + buf->bytes_consumed; if (consumed > produced) produced += n_subbufs * subbuf_size; - + if (consumed == produced) return 0; diff --git a/trunk/kernel/rtmutex-debug.c b/trunk/kernel/rtmutex-debug.c index 56d73cb8826d..6b0703db152d 100644 --- a/trunk/kernel/rtmutex-debug.c +++ b/trunk/kernel/rtmutex-debug.c @@ -87,7 +87,7 @@ static int rt_trace_on = 1; static void printk_task(struct task_struct *p) { if (p) - printk("%16s:%5d [%p, %3d]", p->comm, task_pid_nr(p), p, p->prio); + printk("%16s:%5d [%p, %3d]", p->comm, p->pid, p, p->prio); else printk(""); } @@ -152,25 +152,22 @@ void debug_rt_mutex_print_deadlock(struct rt_mutex_waiter *waiter) printk( "[ BUG: circular locking deadlock detected! ]\n"); printk( "--------------------------------------------\n"); printk("%s/%d is deadlocking current task %s/%d\n\n", - task->comm, task_pid_nr(task), - current->comm, task_pid_nr(current)); + task->comm, task->pid, current->comm, current->pid); printk("\n1) %s/%d is trying to acquire this lock:\n", - current->comm, task_pid_nr(current)); + current->comm, current->pid); printk_lock(waiter->lock, 1); - printk("\n2) %s/%d is blocked on this lock:\n", - task->comm, task_pid_nr(task)); + printk("\n2) %s/%d is blocked on this lock:\n", task->comm, task->pid); printk_lock(waiter->deadlock_lock, 1); debug_show_held_locks(current); debug_show_held_locks(task); - printk("\n%s/%d's [blocked] stackdump:\n\n", - task->comm, task_pid_nr(task)); + printk("\n%s/%d's [blocked] stackdump:\n\n", task->comm, task->pid); show_stack(task, NULL); printk("\n%s/%d's [current] stackdump:\n\n", - current->comm, task_pid_nr(current)); + current->comm, current->pid); dump_stack(); debug_show_all_locks(); diff --git a/trunk/kernel/rtmutex.c b/trunk/kernel/rtmutex.c index 0deef71ff8d2..8cd9bd2cdb34 100644 --- a/trunk/kernel/rtmutex.c +++ b/trunk/kernel/rtmutex.c @@ -185,7 +185,7 @@ static int rt_mutex_adjust_prio_chain(struct task_struct *task, prev_max = max_lock_depth; printk(KERN_WARNING "Maximum lock depth %d reached " "task: %s (%d)\n", max_lock_depth, - top_task->comm, task_pid_nr(top_task)); + top_task->comm, top_task->pid); } put_task_struct(task); diff --git a/trunk/kernel/sched.c b/trunk/kernel/sched.c index afe76ec2e7fe..92721d1534b8 100644 --- a/trunk/kernel/sched.c +++ b/trunk/kernel/sched.c @@ -44,7 +44,6 @@ #include #include #include -#include #include #include #include @@ -52,7 +51,6 @@ #include #include #include -#include #include #include #include @@ -155,15 +153,10 @@ struct rt_prio_array { #ifdef CONFIG_FAIR_GROUP_SCHED -#include - struct cfs_rq; /* task group related information */ struct task_group { -#ifdef CONFIG_FAIR_CGROUP_SCHED - struct cgroup_subsys_state css; -#endif /* schedulable entities of this group on each cpu */ struct sched_entity **se; /* runqueue "owned" by this group on each cpu */ @@ -204,9 +197,6 @@ static inline struct task_group *task_group(struct task_struct *p) #ifdef CONFIG_FAIR_USER_SCHED tg = p->user->tg; -#elif defined(CONFIG_FAIR_CGROUP_SCHED) - tg = container_of(task_subsys_state(p, cpu_cgroup_subsys_id), - struct task_group, css); #else tg = &init_task_group; #endif @@ -276,8 +266,7 @@ struct rt_rq { * acquire operations must be ordered by ascending &runqueue. */ struct rq { - /* runqueue lock: */ - spinlock_t lock; + spinlock_t lock; /* runqueue lock */ /* * nr_running and cpu_load should be in the same cacheline because @@ -290,15 +279,13 @@ struct rq { #ifdef CONFIG_NO_HZ unsigned char in_nohz_recently; #endif - /* capture load from *all* tasks on this cpu: */ - struct load_weight load; + struct load_weight load; /* capture load from *all* tasks on this cpu */ unsigned long nr_load_updates; u64 nr_switches; struct cfs_rq cfs; #ifdef CONFIG_FAIR_GROUP_SCHED - /* list of leaf cfs_rq on this cpu: */ - struct list_head leaf_cfs_rq_list; + struct list_head leaf_cfs_rq_list; /* list of leaf cfs_rq on this cpu */ #endif struct rt_rq rt; @@ -330,8 +317,7 @@ struct rq { /* For active balancing */ int active_balance; int push_cpu; - /* cpu of this runqueue: */ - int cpu; + int cpu; /* cpu of this runqueue */ struct task_struct *migration_thread; struct list_head migration_queue; @@ -342,22 +328,22 @@ struct rq { struct sched_info rq_sched_info; /* sys_sched_yield() stats */ - unsigned int yld_exp_empty; - unsigned int yld_act_empty; - unsigned int yld_both_empty; - unsigned int yld_count; + unsigned long yld_exp_empty; + unsigned long yld_act_empty; + unsigned long yld_both_empty; + unsigned long yld_count; /* schedule() stats */ - unsigned int sched_switch; - unsigned int sched_count; - unsigned int sched_goidle; + unsigned long sched_switch; + unsigned long sched_count; + unsigned long sched_goidle; /* try_to_wake_up() stats */ - unsigned int ttwu_count; - unsigned int ttwu_local; + unsigned long ttwu_count; + unsigned long ttwu_local; /* BKL stats */ - unsigned int bkl_count; + unsigned long bkl_count; #endif struct lock_class_key rq_lock_key; }; @@ -463,12 +449,12 @@ enum { }; const_debug unsigned int sysctl_sched_features = - SCHED_FEAT_NEW_FAIR_SLEEPERS * 1 | - SCHED_FEAT_START_DEBIT * 1 | - SCHED_FEAT_TREE_AVG * 0 | - SCHED_FEAT_APPROX_AVG * 0 | - SCHED_FEAT_WAKEUP_PREEMPT * 1 | - SCHED_FEAT_PREEMPT_RESTRICT * 1; + SCHED_FEAT_NEW_FAIR_SLEEPERS *1 | + SCHED_FEAT_START_DEBIT *1 | + SCHED_FEAT_TREE_AVG *0 | + SCHED_FEAT_APPROX_AVG *0 | + SCHED_FEAT_WAKEUP_PREEMPT *1 | + SCHED_FEAT_PREEMPT_RESTRICT *1; #define sched_feat(x) (sysctl_sched_features & SCHED_FEAT_##x) @@ -1885,7 +1871,7 @@ asmlinkage void schedule_tail(struct task_struct *prev) preempt_enable(); #endif if (current->set_child_tid) - put_user(task_pid_vnr(current), current->set_child_tid); + put_user(current->pid, current->set_child_tid); } /* @@ -3317,13 +3303,9 @@ void account_user_time(struct task_struct *p, cputime_t cputime) { struct cpu_usage_stat *cpustat = &kstat_this_cpu.cpustat; cputime64_t tmp; - struct rq *rq = this_rq(); p->utime = cputime_add(p->utime, cputime); - if (p != rq->idle) - cpuacct_charge(p, cputime); - /* Add user time to cpustat. */ tmp = cputime_to_cputime64(cputime); if (TASK_NICE(p) > 0) @@ -3351,16 +3333,6 @@ void account_guest_time(struct task_struct *p, cputime_t cputime) cpustat->guest = cputime64_add(cpustat->guest, tmp); } -/* - * Account scaled user cpu time to a process. - * @p: the process that the cpu time gets accounted to - * @cputime: the cpu time spent in user space since the last update - */ -void account_user_time_scaled(struct task_struct *p, cputime_t cputime) -{ - p->utimescaled = cputime_add(p->utimescaled, cputime); -} - /* * Account system cpu time to a process. * @p: the process that the cpu time gets accounted to @@ -3388,10 +3360,9 @@ void account_system_time(struct task_struct *p, int hardirq_offset, cpustat->irq = cputime64_add(cpustat->irq, tmp); else if (softirq_count()) cpustat->softirq = cputime64_add(cpustat->softirq, tmp); - else if (p != rq->idle) { + else if (p != rq->idle) cpustat->system = cputime64_add(cpustat->system, tmp); - cpuacct_charge(p, cputime); - } else if (atomic_read(&rq->nr_iowait) > 0) + else if (atomic_read(&rq->nr_iowait) > 0) cpustat->iowait = cputime64_add(cpustat->iowait, tmp); else cpustat->idle = cputime64_add(cpustat->idle, tmp); @@ -3399,17 +3370,6 @@ void account_system_time(struct task_struct *p, int hardirq_offset, acct_update_integrals(p); } -/* - * Account scaled system cpu time to a process. - * @p: the process that the cpu time gets accounted to - * @hardirq_offset: the offset to subtract from hardirq_count() - * @cputime: the cpu time spent in kernel space since the last update - */ -void account_system_time_scaled(struct task_struct *p, cputime_t cputime) -{ - p->stimescaled = cputime_add(p->stimescaled, cputime); -} - /* * Account for involuntary wait time. * @p: the process from which the cpu time has been stolen @@ -3427,10 +3387,8 @@ void account_steal_time(struct task_struct *p, cputime_t steal) cpustat->iowait = cputime64_add(cpustat->iowait, tmp); else cpustat->idle = cputime64_add(cpustat->idle, tmp); - } else { + } else cpustat->steal = cputime64_add(cpustat->steal, tmp); - cpuacct_charge(p, -tmp); - } } /* @@ -3510,7 +3468,7 @@ EXPORT_SYMBOL(sub_preempt_count); static noinline void __schedule_bug(struct task_struct *prev) { printk(KERN_ERR "BUG: scheduling while atomic: %s/0x%08x/%d\n", - prev->comm, preempt_count(), task_pid_nr(prev)); + prev->comm, preempt_count(), prev->pid); debug_show_held_locks(prev); if (irqs_disabled()) print_irqtrace_events(prev); @@ -3901,10 +3859,7 @@ EXPORT_SYMBOL(wait_for_completion_timeout); int __sched wait_for_completion_interruptible(struct completion *x) { - long t = wait_for_common(x, MAX_SCHEDULE_TIMEOUT, TASK_INTERRUPTIBLE); - if (t == -ERESTARTSYS) - return t; - return 0; + return wait_for_common(x, MAX_SCHEDULE_TIMEOUT, TASK_INTERRUPTIBLE); } EXPORT_SYMBOL(wait_for_completion_interruptible); @@ -4176,7 +4131,7 @@ struct task_struct *idle_task(int cpu) */ static struct task_struct *find_process_by_pid(pid_t pid) { - return pid ? find_task_by_vpid(pid) : current; + return pid ? find_task_by_pid(pid) : current; } /* Actually do priority change: must hold rq lock. */ @@ -4479,21 +4434,8 @@ long sched_setaffinity(pid_t pid, cpumask_t new_mask) cpus_allowed = cpuset_cpus_allowed(p); cpus_and(new_mask, new_mask, cpus_allowed); - again: retval = set_cpus_allowed(p, new_mask); - if (!retval) { - cpus_allowed = cpuset_cpus_allowed(p); - if (!cpus_subset(new_mask, cpus_allowed)) { - /* - * We must have raced with a concurrent cpuset - * update. Just reset the cpus_allowed to the - * cpuset's cpus_allowed - */ - new_mask = cpus_allowed; - goto again; - } - } out_unlock: put_task_struct(p); mutex_unlock(&sched_hotcpu_mutex); @@ -4852,18 +4794,18 @@ static void show_task(struct task_struct *p) unsigned state; state = p->state ? __ffs(p->state) + 1 : 0; - printk(KERN_INFO "%-13.13s %c", p->comm, + printk("%-13.13s %c", p->comm, state < sizeof(stat_nam) - 1 ? stat_nam[state] : '?'); #if BITS_PER_LONG == 32 if (state == TASK_RUNNING) - printk(KERN_CONT " running "); + printk(" running "); else - printk(KERN_CONT " %08lx ", thread_saved_pc(p)); + printk(" %08lx ", thread_saved_pc(p)); #else if (state == TASK_RUNNING) - printk(KERN_CONT " running task "); + printk(" running task "); else - printk(KERN_CONT " %016lx ", thread_saved_pc(p)); + printk(" %016lx ", thread_saved_pc(p)); #endif #ifdef CONFIG_DEBUG_STACK_USAGE { @@ -4873,8 +4815,7 @@ static void show_task(struct task_struct *p) free = (unsigned long)n - (unsigned long)end_of_stack(p); } #endif - printk(KERN_CONT "%5lu %5d %6d\n", free, - task_pid_nr(p), task_pid_nr(p->parent)); + printk("%5lu %5d %6d\n", free, p->pid, p->parent->pid); if (state != TASK_RUNNING) show_stack(p, NULL); @@ -5168,16 +5109,8 @@ static void move_task_off_dead_cpu(int dead_cpu, struct task_struct *p) /* No more Mr. Nice Guy. */ if (dest_cpu == NR_CPUS) { - cpumask_t cpus_allowed = cpuset_cpus_allowed_locked(p); - /* - * Try to stay on the same cpuset, where the - * current cpuset may be a subset of all cpus. - * The cpuset_cpus_allowed_locked() variant of - * cpuset_cpus_allowed() will not block. It must be - * called within calls to cpuset_lock/cpuset_unlock. - */ rq = task_rq_lock(p, &flags); - p->cpus_allowed = cpus_allowed; + cpus_setall(p->cpus_allowed); dest_cpu = any_online_cpu(p->cpus_allowed); task_rq_unlock(rq, &flags); @@ -5189,7 +5122,7 @@ static void move_task_off_dead_cpu(int dead_cpu, struct task_struct *p) if (p->mm && printk_ratelimit()) printk(KERN_INFO "process %d (%s) no " "longer affine to cpu%d\n", - task_pid_nr(p), p->comm, dead_cpu); + p->pid, p->comm, dead_cpu); } } while (!__migrate_task_irq(p, dead_cpu, dest_cpu)); } @@ -5296,7 +5229,7 @@ static void migrate_dead(unsigned int dead_cpu, struct task_struct *p) struct rq *rq = cpu_rq(dead_cpu); /* Must be exiting, otherwise would be on tasklist. */ - BUG_ON(!p->exit_state); + BUG_ON(p->exit_state != EXIT_ZOMBIE && p->exit_state != EXIT_DEAD); /* Cannot have done final schedule yet: would have vanished. */ BUG_ON(p->state == TASK_DEAD); @@ -5431,7 +5364,7 @@ sd_alloc_ctl_domain_table(struct sched_domain *sd) return table; } -static ctl_table * sd_alloc_ctl_cpu_table(int cpu) +static ctl_table *sd_alloc_ctl_cpu_table(int cpu) { struct ctl_table *entry, *table; struct sched_domain *sd; @@ -5543,7 +5476,6 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu) case CPU_DEAD: case CPU_DEAD_FROZEN: - cpuset_lock(); /* around calls to cpuset_cpus_allowed_lock() */ migrate_live_tasks(cpu); rq = cpu_rq(cpu); kthread_stop(rq->migration_thread); @@ -5557,7 +5489,6 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu) rq->idle->sched_class = &idle_sched_class; migrate_dead_tasks(cpu); spin_unlock_irq(&rq->lock); - cpuset_unlock(); migrate_nr_uninterruptible(rq); BUG_ON(rq->nr_running != 0); @@ -5667,20 +5598,20 @@ static void sched_domain_debug(struct sched_domain *sd, int cpu) } if (!group->__cpu_power) { - printk(KERN_CONT "\n"); + printk("\n"); printk(KERN_ERR "ERROR: domain->cpu_power not " "set\n"); break; } if (!cpus_weight(group->cpumask)) { - printk(KERN_CONT "\n"); + printk("\n"); printk(KERN_ERR "ERROR: empty group\n"); break; } if (cpus_intersects(groupmask, group->cpumask)) { - printk(KERN_CONT "\n"); + printk("\n"); printk(KERN_ERR "ERROR: repeated CPUs\n"); break; } @@ -5688,11 +5619,11 @@ static void sched_domain_debug(struct sched_domain *sd, int cpu) cpus_or(groupmask, groupmask, group->cpumask); cpumask_scnprintf(str, NR_CPUS, group->cpumask); - printk(KERN_CONT " %s", str); + printk(" %s", str); group = group->next; } while (group != sd->groups); - printk(KERN_CONT "\n"); + printk("\n"); if (!cpus_equal(sd->span, groupmask)) printk(KERN_ERR "ERROR: groups don't span " @@ -6408,31 +6339,26 @@ static int build_sched_domains(const cpumask_t *cpu_map) return -ENOMEM; #endif } - -static cpumask_t *doms_cur; /* current sched domains */ -static int ndoms_cur; /* number of sched domains in 'doms_cur' */ - -/* - * Special case: If a kmalloc of a doms_cur partition (array of - * cpumask_t) fails, then fallback to a single sched domain, - * as determined by the single cpumask_t fallback_doms. - */ -static cpumask_t fallback_doms; - /* * Set up scheduler domains and groups. Callers must hold the hotplug lock. - * For now this just excludes isolated cpus, but could be used to - * exclude other special cases in the future. */ static int arch_init_sched_domains(const cpumask_t *cpu_map) { - ndoms_cur = 1; - doms_cur = kmalloc(sizeof(cpumask_t), GFP_KERNEL); - if (!doms_cur) - doms_cur = &fallback_doms; - cpus_andnot(*doms_cur, *cpu_map, cpu_isolated_map); + cpumask_t cpu_default_map; + int err; + + /* + * Setup mask for cpus without special case scheduling requirements. + * For now this just excludes isolated cpus, but could be used to + * exclude other special cases in the future. + */ + cpus_andnot(cpu_default_map, *cpu_map, cpu_isolated_map); + + err = build_sched_domains(&cpu_default_map); + register_sched_domain_sysctl(); - return build_sched_domains(doms_cur); + + return err; } static void arch_destroy_sched_domains(const cpumask_t *cpu_map) @@ -6456,68 +6382,6 @@ static void detach_destroy_domains(const cpumask_t *cpu_map) arch_destroy_sched_domains(cpu_map); } -/* - * Partition sched domains as specified by the 'ndoms_new' - * cpumasks in the array doms_new[] of cpumasks. This compares - * doms_new[] to the current sched domain partitioning, doms_cur[]. - * It destroys each deleted domain and builds each new domain. - * - * 'doms_new' is an array of cpumask_t's of length 'ndoms_new'. - * The masks don't intersect (don't overlap.) We should setup one - * sched domain for each mask. CPUs not in any of the cpumasks will - * not be load balanced. If the same cpumask appears both in the - * current 'doms_cur' domains and in the new 'doms_new', we can leave - * it as it is. - * - * The passed in 'doms_new' should be kmalloc'd. This routine takes - * ownership of it and will kfree it when done with it. If the caller - * failed the kmalloc call, then it can pass in doms_new == NULL, - * and partition_sched_domains() will fallback to the single partition - * 'fallback_doms'. - * - * Call with hotplug lock held - */ -void partition_sched_domains(int ndoms_new, cpumask_t *doms_new) -{ - int i, j; - - if (doms_new == NULL) { - ndoms_new = 1; - doms_new = &fallback_doms; - cpus_andnot(doms_new[0], cpu_online_map, cpu_isolated_map); - } - - /* Destroy deleted domains */ - for (i = 0; i < ndoms_cur; i++) { - for (j = 0; j < ndoms_new; j++) { - if (cpus_equal(doms_cur[i], doms_new[j])) - goto match1; - } - /* no match - a current sched domain not in new doms_new[] */ - detach_destroy_domains(doms_cur + i); -match1: - ; - } - - /* Build new domains */ - for (i = 0; i < ndoms_new; i++) { - for (j = 0; j < ndoms_cur; j++) { - if (cpus_equal(doms_new[i], doms_cur[j])) - goto match2; - } - /* no match - add a new doms_new */ - build_sched_domains(doms_new + i); -match2: - ; - } - - /* Remember the new sched domains */ - if (doms_cur != &fallback_doms) - kfree(doms_cur); - doms_cur = doms_new; - ndoms_cur = ndoms_new; -} - #if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT) static int arch_reinit_sched_domains(void) { @@ -7099,116 +6963,3 @@ unsigned long sched_group_shares(struct task_group *tg) } #endif /* CONFIG_FAIR_GROUP_SCHED */ - -#ifdef CONFIG_FAIR_CGROUP_SCHED - -/* return corresponding task_group object of a cgroup */ -static inline struct task_group *cgroup_tg(struct cgroup *cont) -{ - return container_of(cgroup_subsys_state(cont, cpu_cgroup_subsys_id), - struct task_group, css); -} - -static struct cgroup_subsys_state * -cpu_cgroup_create(struct cgroup_subsys *ss, struct cgroup *cont) -{ - struct task_group *tg; - - if (!cont->parent) { - /* This is early initialization for the top cgroup */ - init_task_group.css.cgroup = cont; - return &init_task_group.css; - } - - /* we support only 1-level deep hierarchical scheduler atm */ - if (cont->parent->parent) - return ERR_PTR(-EINVAL); - - tg = sched_create_group(); - if (IS_ERR(tg)) - return ERR_PTR(-ENOMEM); - - /* Bind the cgroup to task_group object we just created */ - tg->css.cgroup = cont; - - return &tg->css; -} - -static void cpu_cgroup_destroy(struct cgroup_subsys *ss, - struct cgroup *cont) -{ - struct task_group *tg = cgroup_tg(cont); - - sched_destroy_group(tg); -} - -static int cpu_cgroup_can_attach(struct cgroup_subsys *ss, - struct cgroup *cont, struct task_struct *tsk) -{ - /* We don't support RT-tasks being in separate groups */ - if (tsk->sched_class != &fair_sched_class) - return -EINVAL; - - return 0; -} - -static void -cpu_cgroup_attach(struct cgroup_subsys *ss, struct cgroup *cont, - struct cgroup *old_cont, struct task_struct *tsk) -{ - sched_move_task(tsk); -} - -static ssize_t cpu_shares_write(struct cgroup *cont, struct cftype *cftype, - struct file *file, const char __user *userbuf, - size_t nbytes, loff_t *ppos) -{ - unsigned long shareval; - struct task_group *tg = cgroup_tg(cont); - char buffer[2*sizeof(unsigned long) + 1]; - int rc; - - if (nbytes > 2*sizeof(unsigned long)) /* safety check */ - return -E2BIG; - - if (copy_from_user(buffer, userbuf, nbytes)) - return -EFAULT; - - buffer[nbytes] = 0; /* nul-terminate */ - shareval = simple_strtoul(buffer, NULL, 10); - - rc = sched_group_set_shares(tg, shareval); - - return (rc < 0 ? rc : nbytes); -} - -static u64 cpu_shares_read_uint(struct cgroup *cont, struct cftype *cft) -{ - struct task_group *tg = cgroup_tg(cont); - - return (u64) tg->shares; -} - -static struct cftype cpu_shares = { - .name = "shares", - .read_uint = cpu_shares_read_uint, - .write = cpu_shares_write, -}; - -static int cpu_cgroup_populate(struct cgroup_subsys *ss, struct cgroup *cont) -{ - return cgroup_add_file(cont, ss, &cpu_shares); -} - -struct cgroup_subsys cpu_cgroup_subsys = { - .name = "cpu", - .create = cpu_cgroup_create, - .destroy = cpu_cgroup_destroy, - .can_attach = cpu_cgroup_can_attach, - .attach = cpu_cgroup_attach, - .populate = cpu_cgroup_populate, - .subsys_id = cpu_cgroup_subsys_id, - .early_init = 1, -}; - -#endif /* CONFIG_FAIR_CGROUP_SCHED */ diff --git a/trunk/kernel/sched_debug.c b/trunk/kernel/sched_debug.c index e6fb392e5164..a5e517ec07c3 100644 --- a/trunk/kernel/sched_debug.c +++ b/trunk/kernel/sched_debug.c @@ -137,7 +137,7 @@ void print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq) SEQ_printf(m, " .%-30s: %ld\n", "nr_running", cfs_rq->nr_running); SEQ_printf(m, " .%-30s: %ld\n", "load", cfs_rq->load.weight); #ifdef CONFIG_SCHEDSTATS - SEQ_printf(m, " .%-30s: %d\n", "bkl_count", + SEQ_printf(m, " .%-30s: %ld\n", "bkl_count", rq->bkl_count); #endif SEQ_printf(m, " .%-30s: %ld\n", "nr_spread_over", diff --git a/trunk/kernel/sched_stats.h b/trunk/kernel/sched_stats.h index ef1a7df80ea2..1c084842c3e7 100644 --- a/trunk/kernel/sched_stats.h +++ b/trunk/kernel/sched_stats.h @@ -21,7 +21,7 @@ static int show_schedstat(struct seq_file *seq, void *v) /* runqueue-specific stats */ seq_printf(seq, - "cpu%d %u %u %u %u %u %u %u %u %u %llu %llu %lu", + "cpu%d %lu %lu %lu %lu %lu %lu %lu %lu %lu %llu %llu %lu", cpu, rq->yld_both_empty, rq->yld_act_empty, rq->yld_exp_empty, rq->yld_count, rq->sched_switch, rq->sched_count, rq->sched_goidle, @@ -42,7 +42,8 @@ static int show_schedstat(struct seq_file *seq, void *v) seq_printf(seq, "domain%d %s", dcount++, mask_str); for (itype = CPU_IDLE; itype < CPU_MAX_IDLE_TYPES; itype++) { - seq_printf(seq, " %u %u %u %u %u %u %u %u", + seq_printf(seq, " %lu %lu %lu %lu %lu %lu %lu " + "%lu", sd->lb_count[itype], sd->lb_balanced[itype], sd->lb_failed[itype], @@ -52,7 +53,8 @@ static int show_schedstat(struct seq_file *seq, void *v) sd->lb_nobusyq[itype], sd->lb_nobusyg[itype]); } - seq_printf(seq, " %u %u %u %u %u %u %u %u %u %u %u %u\n", + seq_printf(seq, " %lu %lu %lu %lu %lu %lu %lu %lu %lu" + " %lu %lu %lu\n", sd->alb_count, sd->alb_failed, sd->alb_pushed, sd->sbe_count, sd->sbe_balanced, sd->sbe_pushed, sd->sbf_count, sd->sbf_balanced, sd->sbf_pushed, diff --git a/trunk/kernel/signal.c b/trunk/kernel/signal.c index 12006308c7eb..2124ffadcfde 100644 --- a/trunk/kernel/signal.c +++ b/trunk/kernel/signal.c @@ -99,6 +99,7 @@ static inline int has_pending_signals(sigset_t *signal, sigset_t *blocked) static int recalc_sigpending_tsk(struct task_struct *t) { if (t->signal->group_stop_count > 0 || + (freezing(t)) || PENDING(&t->pending, &t->blocked) || PENDING(&t->signal->shared_pending, &t->blocked)) { set_tsk_thread_flag(t, TIF_SIGPENDING); @@ -256,7 +257,7 @@ flush_signal_handlers(struct task_struct *t, int force_default) int unhandled_signal(struct task_struct *tsk, int sig) { - if (is_global_init(tsk)) + if (is_init(tsk)) return 1; if (tsk->ptrace & PT_PTRACED) return 0; @@ -536,7 +537,7 @@ static int check_kill_permission(int sig, struct siginfo *info, return error; error = -EPERM; if (((sig != SIGCONT) || - (task_session_nr(current) != task_session_nr(t))) + (process_session(current) != process_session(t))) && (current->euid ^ t->suid) && (current->euid ^ t->uid) && (current->uid ^ t->suid) && (current->uid ^ t->uid) && !capable(CAP_KILL)) @@ -694,7 +695,7 @@ static int send_signal(int sig, struct siginfo *info, struct task_struct *t, q->info.si_signo = sig; q->info.si_errno = 0; q->info.si_code = SI_USER; - q->info.si_pid = task_pid_vnr(current); + q->info.si_pid = current->pid; q->info.si_uid = current->uid; break; case (unsigned long) SEND_SIG_PRIV: @@ -730,7 +731,7 @@ int print_fatal_signals; static void print_fatal_signal(struct pt_regs *regs, int signr) { printk("%s/%d: potentially unexpected fatal signal %d.\n", - current->comm, task_pid_nr(current), signr); + current->comm, current->pid, signr); #ifdef __i386__ printk("code at %08lx: ", regs->eip); @@ -1089,7 +1090,7 @@ kill_proc_info(int sig, struct siginfo *info, pid_t pid) { int error; rcu_read_lock(); - error = kill_pid_info(sig, info, find_vpid(pid)); + error = kill_pid_info(sig, info, find_pid(pid)); rcu_read_unlock(); return error; } @@ -1150,7 +1151,7 @@ static int kill_something_info(int sig, struct siginfo *info, int pid) read_lock(&tasklist_lock); for_each_process(p) { - if (p->pid > 1 && !same_thread_group(p, current)) { + if (p->pid > 1 && p->tgid != current->tgid) { int err = group_send_sig_info(sig, info, p); ++count; if (err != -EPERM) @@ -1160,9 +1161,9 @@ static int kill_something_info(int sig, struct siginfo *info, int pid) read_unlock(&tasklist_lock); ret = count ? retval : -ESRCH; } else if (pid < 0) { - ret = kill_pgrp_info(sig, info, find_vpid(-pid)); + ret = kill_pgrp_info(sig, info, find_pid(-pid)); } else { - ret = kill_pid_info(sig, info, find_vpid(pid)); + ret = kill_pid_info(sig, info, find_pid(pid)); } rcu_read_unlock(); return ret; @@ -1266,12 +1267,7 @@ EXPORT_SYMBOL(kill_pid); int kill_proc(pid_t pid, int sig, int priv) { - int ret; - - rcu_read_lock(); - ret = kill_pid_info(sig, __si_special(priv), find_pid(pid)); - rcu_read_unlock(); - return ret; + return kill_proc_info(sig, __si_special(priv), pid); } /* @@ -1448,22 +1444,7 @@ void do_notify_parent(struct task_struct *tsk, int sig) info.si_signo = sig; info.si_errno = 0; - /* - * we are under tasklist_lock here so our parent is tied to - * us and cannot exit and release its namespace. - * - * the only it can is to switch its nsproxy with sys_unshare, - * bu uncharing pid namespaces is not allowed, so we'll always - * see relevant namespace - * - * write_lock() currently calls preempt_disable() which is the - * same as rcu_read_lock(), but according to Oleg, this is not - * correct to rely on this - */ - rcu_read_lock(); - info.si_pid = task_pid_nr_ns(tsk, tsk->parent->nsproxy->pid_ns); - rcu_read_unlock(); - + info.si_pid = tsk->pid; info.si_uid = tsk->uid; /* FIXME: find out whether or not this is supposed to be c*time. */ @@ -1528,13 +1509,7 @@ static void do_notify_parent_cldstop(struct task_struct *tsk, int why) info.si_signo = SIGCHLD; info.si_errno = 0; - /* - * see comment in do_notify_parent() abot the following 3 lines - */ - rcu_read_lock(); - info.si_pid = task_pid_nr_ns(tsk, tsk->parent->nsproxy->pid_ns); - rcu_read_unlock(); - + info.si_pid = tsk->pid; info.si_uid = tsk->uid; /* FIXME: find out whether or not this is supposed to be c*time. */ @@ -1660,7 +1635,7 @@ void ptrace_notify(int exit_code) memset(&info, 0, sizeof info); info.si_signo = SIGTRAP; info.si_code = exit_code; - info.si_pid = task_pid_vnr(current); + info.si_pid = current->pid; info.si_uid = current->uid; /* Let the debugger run. */ @@ -1830,7 +1805,7 @@ int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, info->si_signo = signr; info->si_errno = 0; info->si_code = SI_USER; - info->si_pid = task_pid_vnr(current->parent); + info->si_pid = current->parent->pid; info->si_uid = current->parent->uid; } @@ -1861,9 +1836,11 @@ int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, continue; /* - * Global init gets no signals it doesn't want. + * Init of a pid space gets no signals it doesn't want from + * within that pid space. It can of course get signals from + * its parent pid space. */ - if (is_global_init(current)) + if (current == child_reaper(current)) continue; if (sig_kernel_stop(signr)) { @@ -2217,7 +2194,7 @@ sys_kill(int pid, int sig) info.si_signo = sig; info.si_errno = 0; info.si_code = SI_USER; - info.si_pid = task_tgid_vnr(current); + info.si_pid = current->tgid; info.si_uid = current->uid; return kill_something_info(sig, &info, pid); @@ -2233,12 +2210,12 @@ static int do_tkill(int tgid, int pid, int sig) info.si_signo = sig; info.si_errno = 0; info.si_code = SI_TKILL; - info.si_pid = task_tgid_vnr(current); + info.si_pid = current->tgid; info.si_uid = current->uid; read_lock(&tasklist_lock); - p = find_task_by_vpid(pid); - if (p && (tgid <= 0 || task_tgid_vnr(p) == tgid)) { + p = find_task_by_pid(pid); + if (p && (tgid <= 0 || p->tgid == tgid)) { error = check_kill_permission(sig, &info, p); /* * The null signal is a permissions and process existence diff --git a/trunk/kernel/softlockup.c b/trunk/kernel/softlockup.c index 11df812263c8..edeeef3a6a32 100644 --- a/trunk/kernel/softlockup.c +++ b/trunk/kernel/softlockup.c @@ -113,7 +113,7 @@ void softlockup_tick(void) spin_lock(&print_lock); printk(KERN_ERR "BUG: soft lockup - CPU#%d stuck for %lus! [%s:%d]\n", this_cpu, now - touch_timestamp, - current->comm, task_pid_nr(current)); + current->comm, current->pid); if (regs) show_regs(regs); else diff --git a/trunk/kernel/sys.c b/trunk/kernel/sys.c index 304b5410d746..8ae2e636eb1b 100644 --- a/trunk/kernel/sys.c +++ b/trunk/kernel/sys.c @@ -105,6 +105,538 @@ EXPORT_SYMBOL(cad_pid); */ void (*pm_power_off_prepare)(void); +EXPORT_SYMBOL(pm_power_off_prepare); + +/* + * Notifier list for kernel code which wants to be called + * at shutdown. This is used to stop any idling DMA operations + * and the like. + */ + +static BLOCKING_NOTIFIER_HEAD(reboot_notifier_list); + +/* + * Notifier chain core routines. The exported routines below + * are layered on top of these, with appropriate locking added. + */ + +static int notifier_chain_register(struct notifier_block **nl, + struct notifier_block *n) +{ + while ((*nl) != NULL) { + if (n->priority > (*nl)->priority) + break; + nl = &((*nl)->next); + } + n->next = *nl; + rcu_assign_pointer(*nl, n); + return 0; +} + +static int notifier_chain_unregister(struct notifier_block **nl, + struct notifier_block *n) +{ + while ((*nl) != NULL) { + if ((*nl) == n) { + rcu_assign_pointer(*nl, n->next); + return 0; + } + nl = &((*nl)->next); + } + return -ENOENT; +} + +/** + * notifier_call_chain - Informs the registered notifiers about an event. + * @nl: Pointer to head of the blocking notifier chain + * @val: Value passed unmodified to notifier function + * @v: Pointer passed unmodified to notifier function + * @nr_to_call: Number of notifier functions to be called. Don't care + * value of this parameter is -1. + * @nr_calls: Records the number of notifications sent. Don't care + * value of this field is NULL. + * @returns: notifier_call_chain returns the value returned by the + * last notifier function called. + */ + +static int __kprobes notifier_call_chain(struct notifier_block **nl, + unsigned long val, void *v, + int nr_to_call, int *nr_calls) +{ + int ret = NOTIFY_DONE; + struct notifier_block *nb, *next_nb; + + nb = rcu_dereference(*nl); + + while (nb && nr_to_call) { + next_nb = rcu_dereference(nb->next); + ret = nb->notifier_call(nb, val, v); + + if (nr_calls) + (*nr_calls)++; + + if ((ret & NOTIFY_STOP_MASK) == NOTIFY_STOP_MASK) + break; + nb = next_nb; + nr_to_call--; + } + return ret; +} + +/* + * Atomic notifier chain routines. Registration and unregistration + * use a spinlock, and call_chain is synchronized by RCU (no locks). + */ + +/** + * atomic_notifier_chain_register - Add notifier to an atomic notifier chain + * @nh: Pointer to head of the atomic notifier chain + * @n: New entry in notifier chain + * + * Adds a notifier to an atomic notifier chain. + * + * Currently always returns zero. + */ + +int atomic_notifier_chain_register(struct atomic_notifier_head *nh, + struct notifier_block *n) +{ + unsigned long flags; + int ret; + + spin_lock_irqsave(&nh->lock, flags); + ret = notifier_chain_register(&nh->head, n); + spin_unlock_irqrestore(&nh->lock, flags); + return ret; +} + +EXPORT_SYMBOL_GPL(atomic_notifier_chain_register); + +/** + * atomic_notifier_chain_unregister - Remove notifier from an atomic notifier chain + * @nh: Pointer to head of the atomic notifier chain + * @n: Entry to remove from notifier chain + * + * Removes a notifier from an atomic notifier chain. + * + * Returns zero on success or %-ENOENT on failure. + */ +int atomic_notifier_chain_unregister(struct atomic_notifier_head *nh, + struct notifier_block *n) +{ + unsigned long flags; + int ret; + + spin_lock_irqsave(&nh->lock, flags); + ret = notifier_chain_unregister(&nh->head, n); + spin_unlock_irqrestore(&nh->lock, flags); + synchronize_rcu(); + return ret; +} + +EXPORT_SYMBOL_GPL(atomic_notifier_chain_unregister); + +/** + * __atomic_notifier_call_chain - Call functions in an atomic notifier chain + * @nh: Pointer to head of the atomic notifier chain + * @val: Value passed unmodified to notifier function + * @v: Pointer passed unmodified to notifier function + * @nr_to_call: See the comment for notifier_call_chain. + * @nr_calls: See the comment for notifier_call_chain. + * + * Calls each function in a notifier chain in turn. The functions + * run in an atomic context, so they must not block. + * This routine uses RCU to synchronize with changes to the chain. + * + * If the return value of the notifier can be and'ed + * with %NOTIFY_STOP_MASK then atomic_notifier_call_chain() + * will return immediately, with the return value of + * the notifier function which halted execution. + * Otherwise the return value is the return value + * of the last notifier function called. + */ + +int __kprobes __atomic_notifier_call_chain(struct atomic_notifier_head *nh, + unsigned long val, void *v, + int nr_to_call, int *nr_calls) +{ + int ret; + + rcu_read_lock(); + ret = notifier_call_chain(&nh->head, val, v, nr_to_call, nr_calls); + rcu_read_unlock(); + return ret; +} + +EXPORT_SYMBOL_GPL(__atomic_notifier_call_chain); + +int __kprobes atomic_notifier_call_chain(struct atomic_notifier_head *nh, + unsigned long val, void *v) +{ + return __atomic_notifier_call_chain(nh, val, v, -1, NULL); +} + +EXPORT_SYMBOL_GPL(atomic_notifier_call_chain); +/* + * Blocking notifier chain routines. All access to the chain is + * synchronized by an rwsem. + */ + +/** + * blocking_notifier_chain_register - Add notifier to a blocking notifier chain + * @nh: Pointer to head of the blocking notifier chain + * @n: New entry in notifier chain + * + * Adds a notifier to a blocking notifier chain. + * Must be called in process context. + * + * Currently always returns zero. + */ + +int blocking_notifier_chain_register(struct blocking_notifier_head *nh, + struct notifier_block *n) +{ + int ret; + + /* + * This code gets used during boot-up, when task switching is + * not yet working and interrupts must remain disabled. At + * such times we must not call down_write(). + */ + if (unlikely(system_state == SYSTEM_BOOTING)) + return notifier_chain_register(&nh->head, n); + + down_write(&nh->rwsem); + ret = notifier_chain_register(&nh->head, n); + up_write(&nh->rwsem); + return ret; +} + +EXPORT_SYMBOL_GPL(blocking_notifier_chain_register); + +/** + * blocking_notifier_chain_unregister - Remove notifier from a blocking notifier chain + * @nh: Pointer to head of the blocking notifier chain + * @n: Entry to remove from notifier chain + * + * Removes a notifier from a blocking notifier chain. + * Must be called from process context. + * + * Returns zero on success or %-ENOENT on failure. + */ +int blocking_notifier_chain_unregister(struct blocking_notifier_head *nh, + struct notifier_block *n) +{ + int ret; + + /* + * This code gets used during boot-up, when task switching is + * not yet working and interrupts must remain disabled. At + * such times we must not call down_write(). + */ + if (unlikely(system_state == SYSTEM_BOOTING)) + return notifier_chain_unregister(&nh->head, n); + + down_write(&nh->rwsem); + ret = notifier_chain_unregister(&nh->head, n); + up_write(&nh->rwsem); + return ret; +} + +EXPORT_SYMBOL_GPL(blocking_notifier_chain_unregister); + +/** + * __blocking_notifier_call_chain - Call functions in a blocking notifier chain + * @nh: Pointer to head of the blocking notifier chain + * @val: Value passed unmodified to notifier function + * @v: Pointer passed unmodified to notifier function + * @nr_to_call: See comment for notifier_call_chain. + * @nr_calls: See comment for notifier_call_chain. + * + * Calls each function in a notifier chain in turn. The functions + * run in a process context, so they are allowed to block. + * + * If the return value of the notifier can be and'ed + * with %NOTIFY_STOP_MASK then blocking_notifier_call_chain() + * will return immediately, with the return value of + * the notifier function which halted execution. + * Otherwise the return value is the return value + * of the last notifier function called. + */ + +int __blocking_notifier_call_chain(struct blocking_notifier_head *nh, + unsigned long val, void *v, + int nr_to_call, int *nr_calls) +{ + int ret = NOTIFY_DONE; + + /* + * We check the head outside the lock, but if this access is + * racy then it does not matter what the result of the test + * is, we re-check the list after having taken the lock anyway: + */ + if (rcu_dereference(nh->head)) { + down_read(&nh->rwsem); + ret = notifier_call_chain(&nh->head, val, v, nr_to_call, + nr_calls); + up_read(&nh->rwsem); + } + return ret; +} +EXPORT_SYMBOL_GPL(__blocking_notifier_call_chain); + +int blocking_notifier_call_chain(struct blocking_notifier_head *nh, + unsigned long val, void *v) +{ + return __blocking_notifier_call_chain(nh, val, v, -1, NULL); +} +EXPORT_SYMBOL_GPL(blocking_notifier_call_chain); + +/* + * Raw notifier chain routines. There is no protection; + * the caller must provide it. Use at your own risk! + */ + +/** + * raw_notifier_chain_register - Add notifier to a raw notifier chain + * @nh: Pointer to head of the raw notifier chain + * @n: New entry in notifier chain + * + * Adds a notifier to a raw notifier chain. + * All locking must be provided by the caller. + * + * Currently always returns zero. + */ + +int raw_notifier_chain_register(struct raw_notifier_head *nh, + struct notifier_block *n) +{ + return notifier_chain_register(&nh->head, n); +} + +EXPORT_SYMBOL_GPL(raw_notifier_chain_register); + +/** + * raw_notifier_chain_unregister - Remove notifier from a raw notifier chain + * @nh: Pointer to head of the raw notifier chain + * @n: Entry to remove from notifier chain + * + * Removes a notifier from a raw notifier chain. + * All locking must be provided by the caller. + * + * Returns zero on success or %-ENOENT on failure. + */ +int raw_notifier_chain_unregister(struct raw_notifier_head *nh, + struct notifier_block *n) +{ + return notifier_chain_unregister(&nh->head, n); +} + +EXPORT_SYMBOL_GPL(raw_notifier_chain_unregister); + +/** + * __raw_notifier_call_chain - Call functions in a raw notifier chain + * @nh: Pointer to head of the raw notifier chain + * @val: Value passed unmodified to notifier function + * @v: Pointer passed unmodified to notifier function + * @nr_to_call: See comment for notifier_call_chain. + * @nr_calls: See comment for notifier_call_chain + * + * Calls each function in a notifier chain in turn. The functions + * run in an undefined context. + * All locking must be provided by the caller. + * + * If the return value of the notifier can be and'ed + * with %NOTIFY_STOP_MASK then raw_notifier_call_chain() + * will return immediately, with the return value of + * the notifier function which halted execution. + * Otherwise the return value is the return value + * of the last notifier function called. + */ + +int __raw_notifier_call_chain(struct raw_notifier_head *nh, + unsigned long val, void *v, + int nr_to_call, int *nr_calls) +{ + return notifier_call_chain(&nh->head, val, v, nr_to_call, nr_calls); +} + +EXPORT_SYMBOL_GPL(__raw_notifier_call_chain); + +int raw_notifier_call_chain(struct raw_notifier_head *nh, + unsigned long val, void *v) +{ + return __raw_notifier_call_chain(nh, val, v, -1, NULL); +} + +EXPORT_SYMBOL_GPL(raw_notifier_call_chain); + +/* + * SRCU notifier chain routines. Registration and unregistration + * use a mutex, and call_chain is synchronized by SRCU (no locks). + */ + +/** + * srcu_notifier_chain_register - Add notifier to an SRCU notifier chain + * @nh: Pointer to head of the SRCU notifier chain + * @n: New entry in notifier chain + * + * Adds a notifier to an SRCU notifier chain. + * Must be called in process context. + * + * Currently always returns zero. + */ + +int srcu_notifier_chain_register(struct srcu_notifier_head *nh, + struct notifier_block *n) +{ + int ret; + + /* + * This code gets used during boot-up, when task switching is + * not yet working and interrupts must remain disabled. At + * such times we must not call mutex_lock(). + */ + if (unlikely(system_state == SYSTEM_BOOTING)) + return notifier_chain_register(&nh->head, n); + + mutex_lock(&nh->mutex); + ret = notifier_chain_register(&nh->head, n); + mutex_unlock(&nh->mutex); + return ret; +} + +EXPORT_SYMBOL_GPL(srcu_notifier_chain_register); + +/** + * srcu_notifier_chain_unregister - Remove notifier from an SRCU notifier chain + * @nh: Pointer to head of the SRCU notifier chain + * @n: Entry to remove from notifier chain + * + * Removes a notifier from an SRCU notifier chain. + * Must be called from process context. + * + * Returns zero on success or %-ENOENT on failure. + */ +int srcu_notifier_chain_unregister(struct srcu_notifier_head *nh, + struct notifier_block *n) +{ + int ret; + + /* + * This code gets used during boot-up, when task switching is + * not yet working and interrupts must remain disabled. At + * such times we must not call mutex_lock(). + */ + if (unlikely(system_state == SYSTEM_BOOTING)) + return notifier_chain_unregister(&nh->head, n); + + mutex_lock(&nh->mutex); + ret = notifier_chain_unregister(&nh->head, n); + mutex_unlock(&nh->mutex); + synchronize_srcu(&nh->srcu); + return ret; +} + +EXPORT_SYMBOL_GPL(srcu_notifier_chain_unregister); + +/** + * __srcu_notifier_call_chain - Call functions in an SRCU notifier chain + * @nh: Pointer to head of the SRCU notifier chain + * @val: Value passed unmodified to notifier function + * @v: Pointer passed unmodified to notifier function + * @nr_to_call: See comment for notifier_call_chain. + * @nr_calls: See comment for notifier_call_chain + * + * Calls each function in a notifier chain in turn. The functions + * run in a process context, so they are allowed to block. + * + * If the return value of the notifier can be and'ed + * with %NOTIFY_STOP_MASK then srcu_notifier_call_chain() + * will return immediately, with the return value of + * the notifier function which halted execution. + * Otherwise the return value is the return value + * of the last notifier function called. + */ + +int __srcu_notifier_call_chain(struct srcu_notifier_head *nh, + unsigned long val, void *v, + int nr_to_call, int *nr_calls) +{ + int ret; + int idx; + + idx = srcu_read_lock(&nh->srcu); + ret = notifier_call_chain(&nh->head, val, v, nr_to_call, nr_calls); + srcu_read_unlock(&nh->srcu, idx); + return ret; +} +EXPORT_SYMBOL_GPL(__srcu_notifier_call_chain); + +int srcu_notifier_call_chain(struct srcu_notifier_head *nh, + unsigned long val, void *v) +{ + return __srcu_notifier_call_chain(nh, val, v, -1, NULL); +} +EXPORT_SYMBOL_GPL(srcu_notifier_call_chain); + +/** + * srcu_init_notifier_head - Initialize an SRCU notifier head + * @nh: Pointer to head of the srcu notifier chain + * + * Unlike other sorts of notifier heads, SRCU notifier heads require + * dynamic initialization. Be sure to call this routine before + * calling any of the other SRCU notifier routines for this head. + * + * If an SRCU notifier head is deallocated, it must first be cleaned + * up by calling srcu_cleanup_notifier_head(). Otherwise the head's + * per-cpu data (used by the SRCU mechanism) will leak. + */ + +void srcu_init_notifier_head(struct srcu_notifier_head *nh) +{ + mutex_init(&nh->mutex); + if (init_srcu_struct(&nh->srcu) < 0) + BUG(); + nh->head = NULL; +} + +EXPORT_SYMBOL_GPL(srcu_init_notifier_head); + +/** + * register_reboot_notifier - Register function to be called at reboot time + * @nb: Info about notifier function to be called + * + * Registers a function with the list of functions + * to be called at reboot time. + * + * Currently always returns zero, as blocking_notifier_chain_register() + * always returns zero. + */ + +int register_reboot_notifier(struct notifier_block * nb) +{ + return blocking_notifier_chain_register(&reboot_notifier_list, nb); +} + +EXPORT_SYMBOL(register_reboot_notifier); + +/** + * unregister_reboot_notifier - Unregister previously registered reboot notifier + * @nb: Hook to be unregistered + * + * Unregisters a previously registered reboot + * notifier function. + * + * Returns zero on success, or %-ENOENT on failure. + */ + +int unregister_reboot_notifier(struct notifier_block * nb) +{ + return blocking_notifier_chain_unregister(&reboot_notifier_list, nb); +} + +EXPORT_SYMBOL(unregister_reboot_notifier); static int set_one_prio(struct task_struct *p, int niceval, int error) { @@ -152,7 +684,7 @@ asmlinkage long sys_setpriority(int which, int who, int niceval) switch (which) { case PRIO_PROCESS: if (who) - p = find_task_by_vpid(who); + p = find_task_by_pid(who); else p = current; if (p) @@ -160,7 +692,7 @@ asmlinkage long sys_setpriority(int which, int who, int niceval) break; case PRIO_PGRP: if (who) - pgrp = find_vpid(who); + pgrp = find_pid(who); else pgrp = task_pgrp(current); do_each_pid_task(pgrp, PIDTYPE_PGID, p) { @@ -209,7 +741,7 @@ asmlinkage long sys_getpriority(int which, int who) switch (which) { case PRIO_PROCESS: if (who) - p = find_task_by_vpid(who); + p = find_task_by_pid(who); else p = current; if (p) { @@ -220,7 +752,7 @@ asmlinkage long sys_getpriority(int which, int who) break; case PRIO_PGRP: if (who) - pgrp = find_vpid(who); + pgrp = find_pid(who); else pgrp = task_pgrp(current); do_each_pid_task(pgrp, PIDTYPE_PGID, p) { @@ -917,10 +1449,9 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid) struct task_struct *p; struct task_struct *group_leader = current->group_leader; int err = -EINVAL; - struct pid_namespace *ns; if (!pid) - pid = task_pid_vnr(group_leader); + pid = group_leader->pid; if (!pgid) pgid = pid; if (pgid < 0) @@ -929,12 +1460,10 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid) /* From this point forward we keep holding onto the tasklist lock * so that our parent does not change from under us. -DaveM */ - ns = current->nsproxy->pid_ns; - write_lock_irq(&tasklist_lock); err = -ESRCH; - p = find_task_by_pid_ns(pid, ns); + p = find_task_by_pid(pid); if (!p) goto out; @@ -960,9 +1489,9 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid) goto out; if (pgid != pid) { - struct task_struct *g; + struct task_struct *g = + find_task_by_pid_type(PIDTYPE_PGID, pgid); - g = find_task_by_pid_type_ns(PIDTYPE_PGID, pgid, ns); if (!g || task_session(g) != task_session(group_leader)) goto out; } @@ -971,13 +1500,10 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid) if (err) goto out; - if (task_pgrp_nr_ns(p, ns) != pgid) { - struct pid *pid; - + if (process_group(p) != pgid) { detach_pid(p, PIDTYPE_PGID); - pid = find_vpid(pgid); - attach_pid(p, PIDTYPE_PGID, pid); - set_task_pgrp(p, pid_nr(pid)); + p->signal->pgrp = pgid; + attach_pid(p, PIDTYPE_PGID, find_pid(pgid)); } err = 0; @@ -990,21 +1516,19 @@ asmlinkage long sys_setpgid(pid_t pid, pid_t pgid) asmlinkage long sys_getpgid(pid_t pid) { if (!pid) - return task_pgrp_vnr(current); + return process_group(current); else { int retval; struct task_struct *p; - struct pid_namespace *ns; - - ns = current->nsproxy->pid_ns; read_lock(&tasklist_lock); - p = find_task_by_pid_ns(pid, ns); + p = find_task_by_pid(pid); + retval = -ESRCH; if (p) { retval = security_task_getpgid(p); if (!retval) - retval = task_pgrp_nr_ns(p, ns); + retval = process_group(p); } read_unlock(&tasklist_lock); return retval; @@ -1016,7 +1540,7 @@ asmlinkage long sys_getpgid(pid_t pid) asmlinkage long sys_getpgrp(void) { /* SMP - assuming writes are word atomic this is fine */ - return task_pgrp_vnr(current); + return process_group(current); } #endif @@ -1024,21 +1548,19 @@ asmlinkage long sys_getpgrp(void) asmlinkage long sys_getsid(pid_t pid) { if (!pid) - return task_session_vnr(current); + return process_session(current); else { int retval; struct task_struct *p; - struct pid_namespace *ns; - - ns = current->nsproxy->pid_ns; read_lock(&tasklist_lock); - p = find_task_by_pid_ns(pid, ns); + p = find_task_by_pid(pid); + retval = -ESRCH; if (p) { retval = security_task_getsid(p); if (!retval) - retval = task_session_nr_ns(p, ns); + retval = process_session(p); } read_unlock(&tasklist_lock); return retval; @@ -1065,8 +1587,7 @@ asmlinkage long sys_setsid(void) * session id and so the check will always fail and make it so * init cannot successfully call setsid. */ - if (session > 1 && find_task_by_pid_type_ns(PIDTYPE_PGID, - session, &init_pid_ns)) + if (session > 1 && find_task_by_pid_type(PIDTYPE_PGID, session)) goto out; group_leader->signal->leader = 1; @@ -1076,7 +1597,7 @@ asmlinkage long sys_setsid(void) group_leader->signal->tty = NULL; spin_unlock(&group_leader->sighand->siglock); - err = task_pgrp_vnr(group_leader); + err = process_group(group_leader); out: write_unlock_irq(&tasklist_lock); return err; diff --git a/trunk/kernel/sysctl.c b/trunk/kernel/sysctl.c index 3b4efbe26445..dde3d53e8adc 100644 --- a/trunk/kernel/sysctl.c +++ b/trunk/kernel/sysctl.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include #include @@ -55,8 +55,6 @@ #include #endif -static int deprecated_sysctl_warning(struct __sysctl_args *args); - #if defined(CONFIG_SYSCTL) /* External variables not in a header file. */ @@ -144,29 +142,32 @@ extern int max_lock_depth; #ifdef CONFIG_SYSCTL_SYSCALL static int parse_table(int __user *, int, void __user *, size_t __user *, - void __user *, size_t, struct ctl_table *); + void __user *, size_t, ctl_table *); #endif #ifdef CONFIG_PROC_SYSCTL -static int proc_do_cad_pid(struct ctl_table *table, int write, struct file *filp, +static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos); -static int proc_dointvec_taint(struct ctl_table *table, int write, struct file *filp, +static int proc_dointvec_taint(ctl_table *table, int write, struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos); #endif -static struct ctl_table root_table[]; +static ctl_table root_table[]; static struct ctl_table_header root_table_header = { root_table, LIST_HEAD_INIT(root_table_header.ctl_entry) }; -static struct ctl_table kern_table[]; -static struct ctl_table vm_table[]; -static struct ctl_table fs_table[]; -static struct ctl_table debug_table[]; -static struct ctl_table dev_table[]; -extern struct ctl_table random_table[]; +static ctl_table kern_table[]; +static ctl_table vm_table[]; +static ctl_table fs_table[]; +static ctl_table debug_table[]; +static ctl_table dev_table[]; +extern ctl_table random_table[]; +#ifdef CONFIG_UNIX98_PTYS +extern ctl_table pty_table[]; +#endif #ifdef CONFIG_INOTIFY_USER -extern struct ctl_table inotify_table[]; +extern ctl_table inotify_table[]; #endif #ifdef HAVE_ARCH_PICK_MMAP_LAYOUT @@ -178,7 +179,7 @@ extern int lock_stat; /* The default sysctl tables: */ -static struct ctl_table root_table[] = { +static ctl_table root_table[] = { { .ctl_name = CTL_KERN, .procname = "kernel", @@ -231,7 +232,7 @@ static unsigned long min_wakeup_granularity_ns; /* 0 usecs */ static unsigned long max_wakeup_granularity_ns = 1000000000; /* 1 second */ #endif -static struct ctl_table kern_table[] = { +static ctl_table kern_table[] = { #ifdef CONFIG_SCHED_DEBUG { .ctl_name = CTL_UNNUMBERED, @@ -364,6 +365,7 @@ static struct ctl_table kern_table[] = { }, #ifdef CONFIG_PROC_SYSCTL { + .ctl_name = KERN_TAINTED, .procname = "tainted", .data = &tainted, .maxlen = sizeof(int), @@ -371,15 +373,14 @@ static struct ctl_table kern_table[] = { .proc_handler = &proc_dointvec_taint, }, #endif -#ifdef CONFIG_SECURITY_CAPABILITIES { + .ctl_name = KERN_CAP_BSET, .procname = "cap-bound", .data = &cap_bset, .maxlen = sizeof(kernel_cap_t), .mode = 0600, .proc_handler = &proc_dointvec_bset, }, -#endif /* def CONFIG_SECURITY_CAPABILITIES */ #ifdef CONFIG_BLK_DEV_INITRD { .ctl_name = KERN_REALROOTDEV, @@ -513,6 +514,7 @@ static struct ctl_table kern_table[] = { #endif #ifdef CONFIG_PROC_SYSCTL { + .ctl_name = KERN_CADPID, .procname = "cad_pid", .data = NULL, .maxlen = sizeof (int), @@ -534,6 +536,14 @@ static struct ctl_table kern_table[] = { .mode = 0555, .child = random_table, }, +#ifdef CONFIG_UNIX98_PTYS + { + .ctl_name = KERN_PTY, + .procname = "pty", + .mode = 0555, + .child = pty_table, + }, +#endif { .ctl_name = KERN_OVERFLOWUID, .procname = "overflowuid", @@ -640,6 +650,7 @@ static struct ctl_table kern_table[] = { .proc_handler = &proc_dointvec, }, { + .ctl_name = KERN_NMI_WATCHDOG, .procname = "nmi_watchdog", .data = &nmi_watchdog_enabled, .maxlen = sizeof (int), @@ -695,6 +706,7 @@ static struct ctl_table kern_table[] = { #endif #if defined(CONFIG_ACPI_SLEEP) && defined(CONFIG_X86) { + .ctl_name = KERN_ACPI_VIDEO_FLAGS, .procname = "acpi_video_flags", .data = &acpi_realmode_flags, .maxlen = sizeof (unsigned long), @@ -771,7 +783,7 @@ static struct ctl_table kern_table[] = { { .ctl_name = 0 } }; -static struct ctl_table vm_table[] = { +static ctl_table vm_table[] = { { .ctl_name = VM_OVERCOMMIT_MEMORY, .procname = "overcommit_memory", @@ -835,6 +847,7 @@ static struct ctl_table vm_table[] = { .extra2 = &one_hundred, }, { + .ctl_name = VM_DIRTY_WB_CS, .procname = "dirty_writeback_centisecs", .data = &dirty_writeback_interval, .maxlen = sizeof(dirty_writeback_interval), @@ -842,6 +855,7 @@ static struct ctl_table vm_table[] = { .proc_handler = &dirty_writeback_centisecs_handler, }, { + .ctl_name = VM_DIRTY_EXPIRE_CS, .procname = "dirty_expire_centisecs", .data = &dirty_expire_interval, .maxlen = sizeof(dirty_expire_interval), @@ -869,6 +883,7 @@ static struct ctl_table vm_table[] = { }, #ifdef CONFIG_HUGETLB_PAGE { + .ctl_name = VM_HUGETLB_PAGES, .procname = "nr_hugepages", .data = &max_huge_pages, .maxlen = sizeof(unsigned long), @@ -1078,12 +1093,12 @@ static struct ctl_table vm_table[] = { }; #if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE) -static struct ctl_table binfmt_misc_table[] = { +static ctl_table binfmt_misc_table[] = { { .ctl_name = 0 } }; #endif -static struct ctl_table fs_table[] = { +static ctl_table fs_table[] = { { .ctl_name = FS_NRINODE, .procname = "inode-nr", @@ -1101,6 +1116,7 @@ static struct ctl_table fs_table[] = { .proc_handler = &proc_dointvec, }, { + .ctl_name = FS_NRFILE, .procname = "file-nr", .data = &files_stat, .maxlen = 3*sizeof(int), @@ -1176,6 +1192,7 @@ static struct ctl_table fs_table[] = { .extra2 = &two, }, { + .ctl_name = FS_AIO_NR, .procname = "aio-nr", .data = &aio_nr, .maxlen = sizeof(aio_nr), @@ -1183,6 +1200,7 @@ static struct ctl_table fs_table[] = { .proc_handler = &proc_doulongvec_minmax, }, { + .ctl_name = FS_AIO_MAX_NR, .procname = "aio-max-nr", .data = &aio_max_nr, .maxlen = sizeof(aio_max_nr), @@ -1221,7 +1239,7 @@ static struct ctl_table fs_table[] = { { .ctl_name = 0 } }; -static struct ctl_table debug_table[] = { +static ctl_table debug_table[] = { #if defined(CONFIG_X86) || defined(CONFIG_PPC) { .ctl_name = CTL_UNNUMBERED, @@ -1235,7 +1253,7 @@ static struct ctl_table debug_table[] = { { .ctl_name = 0 } }; -static struct ctl_table dev_table[] = { +static ctl_table dev_table[] = { { .ctl_name = 0 } }; @@ -1351,15 +1369,10 @@ asmlinkage long sys_sysctl(struct __sysctl_args __user *args) if (copy_from_user(&tmp, args, sizeof(tmp))) return -EFAULT; - error = deprecated_sysctl_warning(&tmp); - if (error) - goto out; - lock_kernel(); error = do_sysctl(tmp.name, tmp.nlen, tmp.oldval, tmp.oldlenp, tmp.newval, tmp.newlen); unlock_kernel(); -out: return error; } #endif /* CONFIG_SYSCTL_SYSCALL */ @@ -1380,7 +1393,7 @@ static int test_perm(int mode, int op) return -EACCES; } -int sysctl_perm(struct ctl_table *table, int op) +int sysctl_perm(ctl_table *table, int op) { int error; error = security_sysctl(table, op); @@ -1393,7 +1406,7 @@ int sysctl_perm(struct ctl_table *table, int op) static int parse_table(int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp, void __user *newval, size_t newlen, - struct ctl_table *table) + ctl_table *table) { int n; repeat: @@ -1424,12 +1437,13 @@ static int parse_table(int __user *name, int nlen, } /* Perform the actual read/write of a sysctl table entry. */ -int do_sysctl_strategy (struct ctl_table *table, +int do_sysctl_strategy (ctl_table *table, int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp, void __user *newval, size_t newlen) { int op = 0, rc; + size_t len; if (oldval) op |= 004; @@ -1450,10 +1464,25 @@ int do_sysctl_strategy (struct ctl_table *table, /* If there is no strategy routine, or if the strategy returns * zero, proceed with automatic r/w */ if (table->data && table->maxlen) { - rc = sysctl_data(table, name, nlen, oldval, oldlenp, - newval, newlen); - if (rc < 0) - return rc; + if (oldval && oldlenp) { + if (get_user(len, oldlenp)) + return -EFAULT; + if (len) { + if (len > table->maxlen) + len = table->maxlen; + if(copy_to_user(oldval, table->data, len)) + return -EFAULT; + if(put_user(len, oldlenp)) + return -EFAULT; + } + } + if (newval && newlen) { + len = newlen; + if (len > table->maxlen) + len = table->maxlen; + if(copy_from_user(table->data, newval, len)) + return -EFAULT; + } } return 0; } @@ -1470,9 +1499,7 @@ static void sysctl_set_parent(struct ctl_table *parent, struct ctl_table *table) static __init int sysctl_init(void) { - int err; sysctl_set_parent(NULL, root_table); - err = sysctl_check_table(root_table); return 0; } @@ -1485,7 +1512,7 @@ core_initcall(sysctl_init); * Register a sysctl table hierarchy. @table should be a filled in ctl_table * array. An entry with a ctl_name of 0 terminates the table. * - * The members of the &struct ctl_table structure are used as follows: + * The members of the &ctl_table structure are used as follows: * * ctl_name - This is the numeric sysctl value used by sysctl(2). The number * must be unique within that level of sysctl @@ -1546,7 +1573,7 @@ core_initcall(sysctl_init); * This routine returns %NULL on a failure to register, and a pointer * to the table header on success. */ -struct ctl_table_header *register_sysctl_table(struct ctl_table * table) +struct ctl_table_header *register_sysctl_table(ctl_table * table) { struct ctl_table_header *tmp; tmp = kmalloc(sizeof(struct ctl_table_header), GFP_KERNEL); @@ -1557,10 +1584,6 @@ struct ctl_table_header *register_sysctl_table(struct ctl_table * table) tmp->used = 0; tmp->unregistering = NULL; sysctl_set_parent(NULL, table); - if (sysctl_check_table(tmp->ctl_table)) { - kfree(tmp); - return NULL; - } spin_lock(&sysctl_lock); list_add_tail(&tmp->ctl_entry, &root_table_header.ctl_entry); spin_unlock(&sysctl_lock); @@ -1584,7 +1607,7 @@ void unregister_sysctl_table(struct ctl_table_header * header) } #else /* !CONFIG_SYSCTL */ -struct ctl_table_header *register_sysctl_table(struct ctl_table * table) +struct ctl_table_header *register_sysctl_table(ctl_table * table) { return NULL; } @@ -1677,7 +1700,7 @@ static int _proc_do_string(void* data, int maxlen, int write, * * Returns 0 on success. */ -int proc_dostring(struct ctl_table *table, int write, struct file *filp, +int proc_dostring(ctl_table *table, int write, struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos) { return _proc_do_string(table->data, table->maxlen, write, filp, @@ -1704,7 +1727,7 @@ static int do_proc_dointvec_conv(int *negp, unsigned long *lvalp, return 0; } -static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table, +static int __do_proc_dointvec(void *tbl_data, ctl_table *table, int write, struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos, int (*conv)(int *negp, unsigned long *lvalp, int *valp, @@ -1814,7 +1837,7 @@ static int __do_proc_dointvec(void *tbl_data, struct ctl_table *table, #undef TMPBUFLEN } -static int do_proc_dointvec(struct ctl_table *table, int write, struct file *filp, +static int do_proc_dointvec(ctl_table *table, int write, struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos, int (*conv)(int *negp, unsigned long *lvalp, int *valp, int write, void *data), @@ -1838,7 +1861,7 @@ static int do_proc_dointvec(struct ctl_table *table, int write, struct file *fil * * Returns 0 on success. */ -int proc_dointvec(struct ctl_table *table, int write, struct file *filp, +int proc_dointvec(ctl_table *table, int write, struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos) { return do_proc_dointvec(table,write,filp,buffer,lenp,ppos, @@ -1874,12 +1897,11 @@ static int do_proc_dointvec_bset_conv(int *negp, unsigned long *lvalp, return 0; } -#ifdef CONFIG_SECURITY_CAPABILITIES /* * init may raise the set. */ - -int proc_dointvec_bset(struct ctl_table *table, int write, struct file *filp, + +int proc_dointvec_bset(ctl_table *table, int write, struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos) { int op; @@ -1888,16 +1910,15 @@ int proc_dointvec_bset(struct ctl_table *table, int write, struct file *filp, return -EPERM; } - op = is_global_init(current) ? OP_SET : OP_AND; + op = is_init(current) ? OP_SET : OP_AND; return do_proc_dointvec(table,write,filp,buffer,lenp,ppos, do_proc_dointvec_bset_conv,&op); } -#endif /* def CONFIG_SECURITY_CAPABILITIES */ /* * Taint values can only be increased */ -static int proc_dointvec_taint(struct ctl_table *table, int write, struct file *filp, +static int proc_dointvec_taint(ctl_table *table, int write, struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos) { int op; @@ -1956,7 +1977,7 @@ static int do_proc_dointvec_minmax_conv(int *negp, unsigned long *lvalp, * * Returns 0 on success. */ -int proc_dointvec_minmax(struct ctl_table *table, int write, struct file *filp, +int proc_dointvec_minmax(ctl_table *table, int write, struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos) { struct do_proc_dointvec_minmax_conv_param param = { @@ -1967,7 +1988,7 @@ int proc_dointvec_minmax(struct ctl_table *table, int write, struct file *filp, do_proc_dointvec_minmax_conv, ¶m); } -static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int write, +static int __do_proc_doulongvec_minmax(void *data, ctl_table *table, int write, struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos, @@ -2072,7 +2093,7 @@ static int __do_proc_doulongvec_minmax(void *data, struct ctl_table *table, int #undef TMPBUFLEN } -static int do_proc_doulongvec_minmax(struct ctl_table *table, int write, +static int do_proc_doulongvec_minmax(ctl_table *table, int write, struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos, @@ -2100,7 +2121,7 @@ static int do_proc_doulongvec_minmax(struct ctl_table *table, int write, * * Returns 0 on success. */ -int proc_doulongvec_minmax(struct ctl_table *table, int write, struct file *filp, +int proc_doulongvec_minmax(ctl_table *table, int write, struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos) { return do_proc_doulongvec_minmax(table, write, filp, buffer, lenp, ppos, 1l, 1l); @@ -2124,7 +2145,7 @@ int proc_doulongvec_minmax(struct ctl_table *table, int write, struct file *filp * * Returns 0 on success. */ -int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int write, +int proc_doulongvec_ms_jiffies_minmax(ctl_table *table, int write, struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos) @@ -2217,7 +2238,7 @@ static int do_proc_dointvec_ms_jiffies_conv(int *negp, unsigned long *lvalp, * * Returns 0 on success. */ -int proc_dointvec_jiffies(struct ctl_table *table, int write, struct file *filp, +int proc_dointvec_jiffies(ctl_table *table, int write, struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos) { return do_proc_dointvec(table,write,filp,buffer,lenp,ppos, @@ -2240,7 +2261,7 @@ int proc_dointvec_jiffies(struct ctl_table *table, int write, struct file *filp, * * Returns 0 on success. */ -int proc_dointvec_userhz_jiffies(struct ctl_table *table, int write, struct file *filp, +int proc_dointvec_userhz_jiffies(ctl_table *table, int write, struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos) { return do_proc_dointvec(table,write,filp,buffer,lenp,ppos, @@ -2264,21 +2285,21 @@ int proc_dointvec_userhz_jiffies(struct ctl_table *table, int write, struct file * * Returns 0 on success. */ -int proc_dointvec_ms_jiffies(struct ctl_table *table, int write, struct file *filp, +int proc_dointvec_ms_jiffies(ctl_table *table, int write, struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos) { return do_proc_dointvec(table, write, filp, buffer, lenp, ppos, do_proc_dointvec_ms_jiffies_conv, NULL); } -static int proc_do_cad_pid(struct ctl_table *table, int write, struct file *filp, +static int proc_do_cad_pid(ctl_table *table, int write, struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos) { struct pid *new_pid; pid_t tmp; int r; - tmp = pid_nr_ns(cad_pid, current->nsproxy->pid_ns); + tmp = pid_nr(cad_pid); r = __do_proc_dointvec(&tmp, table, write, filp, buffer, lenp, ppos, NULL, NULL); @@ -2295,55 +2316,55 @@ static int proc_do_cad_pid(struct ctl_table *table, int write, struct file *filp #else /* CONFIG_PROC_FS */ -int proc_dostring(struct ctl_table *table, int write, struct file *filp, +int proc_dostring(ctl_table *table, int write, struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos) { return -ENOSYS; } -int proc_dointvec(struct ctl_table *table, int write, struct file *filp, +int proc_dointvec(ctl_table *table, int write, struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos) { return -ENOSYS; } -int proc_dointvec_bset(struct ctl_table *table, int write, struct file *filp, +int proc_dointvec_bset(ctl_table *table, int write, struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos) { return -ENOSYS; } -int proc_dointvec_minmax(struct ctl_table *table, int write, struct file *filp, +int proc_dointvec_minmax(ctl_table *table, int write, struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos) { return -ENOSYS; } -int proc_dointvec_jiffies(struct ctl_table *table, int write, struct file *filp, +int proc_dointvec_jiffies(ctl_table *table, int write, struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos) { return -ENOSYS; } -int proc_dointvec_userhz_jiffies(struct ctl_table *table, int write, struct file *filp, +int proc_dointvec_userhz_jiffies(ctl_table *table, int write, struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos) { return -ENOSYS; } -int proc_dointvec_ms_jiffies(struct ctl_table *table, int write, struct file *filp, +int proc_dointvec_ms_jiffies(ctl_table *table, int write, struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos) { return -ENOSYS; } -int proc_doulongvec_minmax(struct ctl_table *table, int write, struct file *filp, +int proc_doulongvec_minmax(ctl_table *table, int write, struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos) { return -ENOSYS; } -int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int write, +int proc_doulongvec_ms_jiffies_minmax(ctl_table *table, int write, struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos) @@ -2360,42 +2381,8 @@ int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int write, * General sysctl support routines */ -/* The generic sysctl data routine (used if no strategy routine supplied) */ -int sysctl_data(struct ctl_table *table, int __user *name, int nlen, - void __user *oldval, size_t __user *oldlenp, - void __user *newval, size_t newlen) -{ - size_t len; - - /* Get out of I don't have a variable */ - if (!table->data || !table->maxlen) - return -ENOTDIR; - - if (oldval && oldlenp) { - if (get_user(len, oldlenp)) - return -EFAULT; - if (len) { - if (len > table->maxlen) - len = table->maxlen; - if (copy_to_user(oldval, table->data, len)) - return -EFAULT; - if (put_user(len, oldlenp)) - return -EFAULT; - } - } - - if (newval && newlen) { - if (newlen > table->maxlen) - newlen = table->maxlen; - - if (copy_from_user(table->data, newval, newlen)) - return -EFAULT; - } - return 1; -} - /* The generic string strategy routine: */ -int sysctl_string(struct ctl_table *table, int __user *name, int nlen, +int sysctl_string(ctl_table *table, int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp, void __user *newval, size_t newlen) { @@ -2441,7 +2428,7 @@ int sysctl_string(struct ctl_table *table, int __user *name, int nlen, * are between the minimum and maximum values given in the arrays * table->extra1 and table->extra2, respectively. */ -int sysctl_intvec(struct ctl_table *table, int __user *name, int nlen, +int sysctl_intvec(ctl_table *table, int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp, void __user *newval, size_t newlen) { @@ -2477,7 +2464,7 @@ int sysctl_intvec(struct ctl_table *table, int __user *name, int nlen, } /* Strategy function to convert jiffies to seconds */ -int sysctl_jiffies(struct ctl_table *table, int __user *name, int nlen, +int sysctl_jiffies(ctl_table *table, int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp, void __user *newval, size_t newlen) { @@ -2511,7 +2498,7 @@ int sysctl_jiffies(struct ctl_table *table, int __user *name, int nlen, } /* Strategy function to convert jiffies to seconds */ -int sysctl_ms_jiffies(struct ctl_table *table, int __user *name, int nlen, +int sysctl_ms_jiffies(ctl_table *table, int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp, void __user *newval, size_t newlen) { @@ -2551,50 +2538,59 @@ int sysctl_ms_jiffies(struct ctl_table *table, int __user *name, int nlen, asmlinkage long sys_sysctl(struct __sysctl_args __user *args) { + static int msg_count; struct __sysctl_args tmp; - int error; + int name[CTL_MAXNAME]; + int i; + /* Read in the sysctl name for better debug message logging */ if (copy_from_user(&tmp, args, sizeof(tmp))) return -EFAULT; + if (tmp.nlen <= 0 || tmp.nlen >= CTL_MAXNAME) + return -ENOTDIR; + for (i = 0; i < tmp.nlen; i++) + if (get_user(name[i], tmp.name + i)) + return -EFAULT; - error = deprecated_sysctl_warning(&tmp); - - /* If no error reading the parameters then just -ENOSYS ... */ - if (!error) - error = -ENOSYS; - - return error; -} + /* Ignore accesses to kernel.version */ + if ((tmp.nlen == 2) && (name[0] == CTL_KERN) && (name[1] == KERN_VERSION)) + goto out; -int sysctl_data(struct ctl_table *table, int __user *name, int nlen, - void __user *oldval, size_t __user *oldlenp, - void __user *newval, size_t newlen) -{ + if (msg_count < 5) { + msg_count++; + printk(KERN_INFO + "warning: process `%s' used the removed sysctl " + "system call with ", current->comm); + for (i = 0; i < tmp.nlen; i++) + printk("%d.", name[i]); + printk("\n"); + } +out: return -ENOSYS; } -int sysctl_string(struct ctl_table *table, int __user *name, int nlen, +int sysctl_string(ctl_table *table, int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp, void __user *newval, size_t newlen) { return -ENOSYS; } -int sysctl_intvec(struct ctl_table *table, int __user *name, int nlen, +int sysctl_intvec(ctl_table *table, int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp, void __user *newval, size_t newlen) { return -ENOSYS; } -int sysctl_jiffies(struct ctl_table *table, int __user *name, int nlen, +int sysctl_jiffies(ctl_table *table, int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp, void __user *newval, size_t newlen) { return -ENOSYS; } -int sysctl_ms_jiffies(struct ctl_table *table, int __user *name, int nlen, +int sysctl_ms_jiffies(ctl_table *table, int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp, void __user *newval, size_t newlen) { @@ -2603,33 +2599,6 @@ int sysctl_ms_jiffies(struct ctl_table *table, int __user *name, int nlen, #endif /* CONFIG_SYSCTL_SYSCALL */ -static int deprecated_sysctl_warning(struct __sysctl_args *args) -{ - static int msg_count; - int name[CTL_MAXNAME]; - int i; - - /* Read in the sysctl name for better debug message logging */ - for (i = 0; i < args->nlen; i++) - if (get_user(name[i], args->name + i)) - return -EFAULT; - - /* Ignore accesses to kernel.version */ - if ((args->nlen == 2) && (name[0] == CTL_KERN) && (name[1] == KERN_VERSION)) - return 0; - - if (msg_count < 5) { - msg_count++; - printk(KERN_INFO - "warning: process `%s' used the deprecated sysctl " - "system call with ", current->comm); - for (i = 0; i < args->nlen; i++) - printk("%d.", name[i]); - printk("\n"); - } - return 0; -} - /* * No sense putting this after each symbol definition, twice, * exception granted :-) @@ -2647,5 +2616,4 @@ EXPORT_SYMBOL(sysctl_intvec); EXPORT_SYMBOL(sysctl_jiffies); EXPORT_SYMBOL(sysctl_ms_jiffies); EXPORT_SYMBOL(sysctl_string); -EXPORT_SYMBOL(sysctl_data); EXPORT_SYMBOL(unregister_sysctl_table); diff --git a/trunk/kernel/sysctl_check.c b/trunk/kernel/sysctl_check.c deleted file mode 100644 index 3c9ef5a7d575..000000000000 --- a/trunk/kernel/sysctl_check.c +++ /dev/null @@ -1,1588 +0,0 @@ -#include -#include -#include "../arch/s390/appldata/appldata.h" -#include "../fs/xfs/linux-2.6/xfs_sysctl.h" -#include -#include -#include - -struct trans_ctl_table { - int ctl_name; - const char *procname; - struct trans_ctl_table *child; -}; - -static struct trans_ctl_table trans_random_table[] = { - { RANDOM_POOLSIZE, "poolsize" }, - { RANDOM_ENTROPY_COUNT, "entropy_avail" }, - { RANDOM_READ_THRESH, "read_wakeup_threshold" }, - { RANDOM_WRITE_THRESH, "write_wakeup_threshold" }, - { RANDOM_BOOT_ID, "boot_id" }, - { RANDOM_UUID, "uuid" }, - {} -}; - -static struct trans_ctl_table trans_pty_table[] = { - { PTY_MAX, "max" }, - { PTY_NR, "nr" }, - {} -}; - -static struct trans_ctl_table trans_kern_table[] = { - { KERN_OSTYPE, "ostype" }, - { KERN_OSRELEASE, "osrelease" }, - /* KERN_OSREV not used */ - { KERN_VERSION, "version" }, - /* KERN_SECUREMASK not used */ - /* KERN_PROF not used */ - { KERN_NODENAME, "hostname" }, - { KERN_DOMAINNAME, "domainname" }, - -#ifdef CONFIG_SECURITY_CAPABILITIES - { KERN_CAP_BSET, "cap-bound" }, -#endif /* def CONFIG_SECURITY_CAPABILITIES */ - - { KERN_PANIC, "panic" }, - { KERN_REALROOTDEV, "real-root-dev" }, - - { KERN_SPARC_REBOOT, "reboot-cmd" }, - { KERN_CTLALTDEL, "ctrl-alt-del" }, - { KERN_PRINTK, "printk" }, - - /* KERN_NAMETRANS not used */ - /* KERN_PPC_HTABRECLAIM not used */ - /* KERN_PPC_ZEROPAGED not used */ - { KERN_PPC_POWERSAVE_NAP, "powersave-nap" }, - - { KERN_MODPROBE, "modprobe" }, - { KERN_SG_BIG_BUFF, "sg-big-buff" }, - { KERN_ACCT, "acct" }, - { KERN_PPC_L2CR, "l2cr" }, - - /* KERN_RTSIGNR not used */ - /* KERN_RTSIGMAX not used */ - - { KERN_SHMMAX, "shmmax" }, - { KERN_MSGMAX, "msgmax" }, - { KERN_MSGMNB, "msgmnb" }, - /* KERN_MSGPOOL not used*/ - { KERN_SYSRQ, "sysrq" }, - { KERN_MAX_THREADS, "threads-max" }, - { KERN_RANDOM, "random", trans_random_table }, - { KERN_SHMALL, "shmall" }, - { KERN_MSGMNI, "msgmni" }, - { KERN_SEM, "sem" }, - { KERN_SPARC_STOP_A, "stop-a" }, - { KERN_SHMMNI, "shmmni" }, - - { KERN_OVERFLOWUID, "overflowuid" }, - { KERN_OVERFLOWGID, "overflowgid" }, - - { KERN_HOTPLUG, "hotplug", }, - { KERN_IEEE_EMULATION_WARNINGS, "ieee_emulation_warnings" }, - - { KERN_S390_USER_DEBUG_LOGGING, "userprocess_debug" }, - { KERN_CORE_USES_PID, "core_uses_pid" }, - { KERN_TAINTED, "tainted" }, - { KERN_CADPID, "cad_pid" }, - { KERN_PIDMAX, "pid_max" }, - { KERN_CORE_PATTERN, "core_pattern" }, - { KERN_PANIC_ON_OOPS, "panic_on_oops" }, - { KERN_HPPA_PWRSW, "soft-power" }, - { KERN_HPPA_UNALIGNED, "unaligned-trap" }, - - { KERN_PRINTK_RATELIMIT, "printk_ratelimit" }, - { KERN_PRINTK_RATELIMIT_BURST, "printk_ratelimit_burst" }, - - { KERN_PTY, "pty", trans_pty_table }, - { KERN_NGROUPS_MAX, "ngroups_max" }, - { KERN_SPARC_SCONS_PWROFF, "scons_poweroff" }, - { KERN_HZ_TIMER, "hz_timer" }, - { KERN_UNKNOWN_NMI_PANIC, "unknown_nmi_panic" }, - { KERN_BOOTLOADER_TYPE, "bootloader_type" }, - { KERN_RANDOMIZE, "randomize_va_space" }, - - { KERN_SPIN_RETRY, "spin_retry" }, - { KERN_ACPI_VIDEO_FLAGS, "acpi_video_flags" }, - { KERN_IA64_UNALIGNED, "ignore-unaligned-usertrap" }, - { KERN_COMPAT_LOG, "compat-log" }, - { KERN_MAX_LOCK_DEPTH, "max_lock_depth" }, - { KERN_NMI_WATCHDOG, "nmi_watchdog" }, - { KERN_PANIC_ON_NMI, "panic_on_unrecovered_nmi" }, - {} -}; - -static struct trans_ctl_table trans_vm_table[] = { - { VM_OVERCOMMIT_MEMORY, "overcommit_memory" }, - { VM_PAGE_CLUSTER, "page-cluster" }, - { VM_DIRTY_BACKGROUND, "dirty_background_ratio" }, - { VM_DIRTY_RATIO, "dirty_ratio" }, - { VM_DIRTY_WB_CS, "dirty_writeback_centisecs" }, - { VM_DIRTY_EXPIRE_CS, "dirty_expire_centisecs" }, - { VM_NR_PDFLUSH_THREADS, "nr_pdflush_threads" }, - { VM_OVERCOMMIT_RATIO, "overcommit_ratio" }, - /* VM_PAGEBUF unused */ - { VM_HUGETLB_PAGES, "nr_hugepages" }, - { VM_SWAPPINESS, "swappiness" }, - { VM_LOWMEM_RESERVE_RATIO, "lowmem_reserve_ratio" }, - { VM_MIN_FREE_KBYTES, "min_free_kbytes" }, - { VM_MAX_MAP_COUNT, "max_map_count" }, - { VM_LAPTOP_MODE, "laptop_mode" }, - { VM_BLOCK_DUMP, "block_dump" }, - { VM_HUGETLB_GROUP, "hugetlb_shm_group" }, - { VM_VFS_CACHE_PRESSURE, "vfs_cache_pressure" }, - { VM_LEGACY_VA_LAYOUT, "legacy_va_layout" }, - /* VM_SWAP_TOKEN_TIMEOUT unused */ - { VM_DROP_PAGECACHE, "drop_caches" }, - { VM_PERCPU_PAGELIST_FRACTION, "percpu_pagelist_fraction" }, - { VM_ZONE_RECLAIM_MODE, "zone_reclaim_mode" }, - { VM_MIN_UNMAPPED, "min_unmapped_ratio" }, - { VM_PANIC_ON_OOM, "panic_on_oom" }, - { VM_VDSO_ENABLED, "vdso_enabled" }, - { VM_MIN_SLAB, "min_slab_ratio" }, - { VM_CMM_PAGES, "cmm_pages" }, - { VM_CMM_TIMED_PAGES, "cmm_timed_pages" }, - { VM_CMM_TIMEOUT, "cmm_timeout" }, - - {} -}; - -static struct trans_ctl_table trans_net_core_table[] = { - { NET_CORE_WMEM_MAX, "wmem_max" }, - { NET_CORE_RMEM_MAX, "rmem_max" }, - { NET_CORE_WMEM_DEFAULT, "wmem_default" }, - { NET_CORE_RMEM_DEFAULT, "rmem_default" }, - /* NET_CORE_DESTROY_DELAY unused */ - { NET_CORE_MAX_BACKLOG, "netdev_max_backlog" }, - /* NET_CORE_FASTROUTE unused */ - { NET_CORE_MSG_COST, "message_cost" }, - { NET_CORE_MSG_BURST, "message_burst" }, - { NET_CORE_OPTMEM_MAX, "optmem_max" }, - /* NET_CORE_HOT_LIST_LENGTH unused */ - /* NET_CORE_DIVERT_VERSION unused */ - /* NET_CORE_NO_CONG_THRESH unused */ - /* NET_CORE_NO_CONG unused */ - /* NET_CORE_LO_CONG unused */ - /* NET_CORE_MOD_CONG unused */ - { NET_CORE_DEV_WEIGHT, "dev_weight" }, - { NET_CORE_SOMAXCONN, "somaxconn" }, - { NET_CORE_BUDGET, "netdev_budget" }, - { NET_CORE_AEVENT_ETIME, "xfrm_aevent_etime" }, - { NET_CORE_AEVENT_RSEQTH, "xfrm_aevent_rseqth" }, - { NET_CORE_WARNINGS, "warnings" }, - {}, -}; - -static struct trans_ctl_table trans_net_unix_table[] = { - /* NET_UNIX_DESTROY_DELAY unused */ - /* NET_UNIX_DELETE_DELAY unused */ - { NET_UNIX_MAX_DGRAM_QLEN, "max_dgram_qlen" }, - {} -}; - -static struct trans_ctl_table trans_net_ipv4_route_table[] = { - { NET_IPV4_ROUTE_FLUSH, "flush" }, - { NET_IPV4_ROUTE_MIN_DELAY, "min_delay" }, - { NET_IPV4_ROUTE_MAX_DELAY, "max_delay" }, - { NET_IPV4_ROUTE_GC_THRESH, "gc_thresh" }, - { NET_IPV4_ROUTE_MAX_SIZE, "max_size" }, - { NET_IPV4_ROUTE_GC_MIN_INTERVAL, "gc_min_interval" }, - { NET_IPV4_ROUTE_GC_TIMEOUT, "gc_timeout" }, - { NET_IPV4_ROUTE_GC_INTERVAL, "gc_interval" }, - { NET_IPV4_ROUTE_REDIRECT_LOAD, "redirect_load" }, - { NET_IPV4_ROUTE_REDIRECT_NUMBER, "redirect_number" }, - { NET_IPV4_ROUTE_REDIRECT_SILENCE, "redirect_silence" }, - { NET_IPV4_ROUTE_ERROR_COST, "error_cost" }, - { NET_IPV4_ROUTE_ERROR_BURST, "error_burst" }, - { NET_IPV4_ROUTE_GC_ELASTICITY, "gc_elasticity" }, - { NET_IPV4_ROUTE_MTU_EXPIRES, "mtu_expires" }, - { NET_IPV4_ROUTE_MIN_PMTU, "min_pmtu" }, - { NET_IPV4_ROUTE_MIN_ADVMSS, "min_adv_mss" }, - { NET_IPV4_ROUTE_SECRET_INTERVAL, "secret_interval" }, - { NET_IPV4_ROUTE_GC_MIN_INTERVAL_MS, "gc_min_interval_ms" }, - {} -}; - -static struct trans_ctl_table trans_net_ipv4_conf_vars_table[] = { - { NET_IPV4_CONF_FORWARDING, "forwarding" }, - { NET_IPV4_CONF_MC_FORWARDING, "mc_forwarding" }, - - { NET_IPV4_CONF_PROXY_ARP, "proxy_arp" }, - { NET_IPV4_CONF_ACCEPT_REDIRECTS, "accept_redirects" }, - { NET_IPV4_CONF_SECURE_REDIRECTS, "secure_redirects" }, - { NET_IPV4_CONF_SEND_REDIRECTS, "send_redirects" }, - { NET_IPV4_CONF_SHARED_MEDIA, "shared_media" }, - { NET_IPV4_CONF_RP_FILTER, "rp_filter" }, - { NET_IPV4_CONF_ACCEPT_SOURCE_ROUTE, "accept_source_route" }, - { NET_IPV4_CONF_BOOTP_RELAY, "bootp_relay" }, - { NET_IPV4_CONF_LOG_MARTIANS, "log_martians" }, - { NET_IPV4_CONF_TAG, "tag" }, - { NET_IPV4_CONF_ARPFILTER, "arp_filter" }, - { NET_IPV4_CONF_MEDIUM_ID, "medium_id" }, - { NET_IPV4_CONF_NOXFRM, "disable_xfrm" }, - { NET_IPV4_CONF_NOPOLICY, "disable_policy" }, - { NET_IPV4_CONF_FORCE_IGMP_VERSION, "force_igmp_version" }, - - { NET_IPV4_CONF_ARP_ANNOUNCE, "arp_announce" }, - { NET_IPV4_CONF_ARP_IGNORE, "arp_ignore" }, - { NET_IPV4_CONF_PROMOTE_SECONDARIES, "promote_secondaries" }, - { NET_IPV4_CONF_ARP_ACCEPT, "arp_accept" }, - {} -}; - -static struct trans_ctl_table trans_net_ipv4_conf_table[] = { - { NET_PROTO_CONF_ALL, "all", trans_net_ipv4_conf_vars_table }, - { NET_PROTO_CONF_DEFAULT, "default", trans_net_ipv4_conf_vars_table }, - { 0, NULL, trans_net_ipv4_conf_vars_table }, - {} -}; - - -static struct trans_ctl_table trans_net_ipv4_vs_table[] = { - { NET_IPV4_VS_AMEMTHRESH, "amemthresh" }, - { NET_IPV4_VS_DEBUG_LEVEL, "debug_level" }, - { NET_IPV4_VS_AMDROPRATE, "am_droprate" }, - { NET_IPV4_VS_DROP_ENTRY, "drop_entry" }, - { NET_IPV4_VS_DROP_PACKET, "drop_packet" }, - { NET_IPV4_VS_SECURE_TCP, "secure_tcp" }, - { NET_IPV4_VS_TO_ES, "timeout_established" }, - { NET_IPV4_VS_TO_SS, "timeout_synsent" }, - { NET_IPV4_VS_TO_SR, "timeout_synrecv" }, - { NET_IPV4_VS_TO_FW, "timeout_finwait" }, - { NET_IPV4_VS_TO_TW, "timeout_timewait" }, - { NET_IPV4_VS_TO_CL, "timeout_close" }, - { NET_IPV4_VS_TO_CW, "timeout_closewait" }, - { NET_IPV4_VS_TO_LA, "timeout_lastack" }, - { NET_IPV4_VS_TO_LI, "timeout_listen" }, - { NET_IPV4_VS_TO_SA, "timeout_synack" }, - { NET_IPV4_VS_TO_UDP, "timeout_udp" }, - { NET_IPV4_VS_TO_ICMP, "timeout_icmp" }, - { NET_IPV4_VS_CACHE_BYPASS, "cache_bypass" }, - { NET_IPV4_VS_EXPIRE_NODEST_CONN, "expire_nodest_conn" }, - { NET_IPV4_VS_EXPIRE_QUIESCENT_TEMPLATE, "expire_quiescent_template" }, - { NET_IPV4_VS_SYNC_THRESHOLD, "sync_threshold" }, - { NET_IPV4_VS_NAT_ICMP_SEND, "nat_icmp_send" }, - { NET_IPV4_VS_LBLC_EXPIRE, "lblc_expiration" }, - { NET_IPV4_VS_LBLCR_EXPIRE, "lblcr_expiration" }, - {} -}; - -static struct trans_ctl_table trans_net_neigh_vars_table[] = { - { NET_NEIGH_MCAST_SOLICIT, "mcast_solicit" }, - { NET_NEIGH_UCAST_SOLICIT, "ucast_solicit" }, - { NET_NEIGH_APP_SOLICIT, "app_solicit" }, - { NET_NEIGH_RETRANS_TIME, "retrans_time" }, - { NET_NEIGH_REACHABLE_TIME, "base_reachable_time" }, - { NET_NEIGH_DELAY_PROBE_TIME, "delay_first_probe_time" }, - { NET_NEIGH_GC_STALE_TIME, "gc_stale_time" }, - { NET_NEIGH_UNRES_QLEN, "unres_qlen" }, - { NET_NEIGH_PROXY_QLEN, "proxy_qlen" }, - { NET_NEIGH_ANYCAST_DELAY, "anycast_delay" }, - { NET_NEIGH_PROXY_DELAY, "proxy_delay" }, - { NET_NEIGH_LOCKTIME, "locktime" }, - { NET_NEIGH_GC_INTERVAL, "gc_interval" }, - { NET_NEIGH_GC_THRESH1, "gc_thresh1" }, - { NET_NEIGH_GC_THRESH2, "gc_thresh2" }, - { NET_NEIGH_GC_THRESH3, "gc_thresh3" }, - { NET_NEIGH_RETRANS_TIME_MS, "retrans_time_ms" }, - { NET_NEIGH_REACHABLE_TIME_MS, "base_reachable_time_ms" }, - {} -}; - -static struct trans_ctl_table trans_net_neigh_table[] = { - { NET_PROTO_CONF_DEFAULT, "default", trans_net_neigh_vars_table }, - { 0, NULL, trans_net_neigh_vars_table }, - {} -}; - -static struct trans_ctl_table trans_net_ipv4_netfilter_table[] = { - { NET_IPV4_NF_CONNTRACK_MAX, "ip_conntrack_max" }, - - { NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT, "ip_conntrack_tcp_timeout_syn_sent" }, - { NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_RECV, "ip_conntrack_tcp_timeout_syn_recv" }, - { NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED, "ip_conntrack_tcp_timeout_established" }, - { NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT, "ip_conntrack_tcp_timeout_fin_wait" }, - { NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_CLOSE_WAIT, "ip_conntrack_tcp_timeout_close_wait" }, - { NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_LAST_ACK, "ip_conntrack_tcp_timeout_last_ack" }, - { NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT, "ip_conntrack_tcp_timeout_time_wait" }, - { NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_CLOSE, "ip_conntrack_tcp_timeout_close" }, - - { NET_IPV4_NF_CONNTRACK_UDP_TIMEOUT, "ip_conntrack_udp_timeout" }, - { NET_IPV4_NF_CONNTRACK_UDP_TIMEOUT_STREAM, "ip_conntrack_udp_timeout_stream" }, - { NET_IPV4_NF_CONNTRACK_ICMP_TIMEOUT, "ip_conntrack_icmp_timeout" }, - { NET_IPV4_NF_CONNTRACK_GENERIC_TIMEOUT, "ip_conntrack_generic_timeout" }, - - { NET_IPV4_NF_CONNTRACK_BUCKETS, "ip_conntrack_buckets" }, - { NET_IPV4_NF_CONNTRACK_LOG_INVALID, "ip_conntrack_log_invalid" }, - { NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_MAX_RETRANS, "ip_conntrack_tcp_timeout_max_retrans" }, - { NET_IPV4_NF_CONNTRACK_TCP_LOOSE, "ip_conntrack_tcp_loose" }, - { NET_IPV4_NF_CONNTRACK_TCP_BE_LIBERAL, "ip_conntrack_tcp_be_liberal" }, - { NET_IPV4_NF_CONNTRACK_TCP_MAX_RETRANS, "ip_conntrack_tcp_max_retrans" }, - - { NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED, "ip_conntrack_sctp_timeout_closed" }, - { NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_WAIT, "ip_conntrack_sctp_timeout_cookie_wait" }, - { NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_ECHOED, "ip_conntrack_sctp_timeout_cookie_echoed" }, - { NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_ESTABLISHED, "ip_conntrack_sctp_timeout_established" }, - { NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT, "ip_conntrack_sctp_timeout_shutdown_sent" }, - { NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD, "ip_conntrack_sctp_timeout_shutdown_recd" }, - { NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT, "ip_conntrack_sctp_timeout_shutdown_ack_sent" }, - - { NET_IPV4_NF_CONNTRACK_COUNT, "ip_conntrack_count" }, - { NET_IPV4_NF_CONNTRACK_CHECKSUM, "ip_conntrack_checksum" }, - {} -}; - -static struct trans_ctl_table trans_net_ipv4_table[] = { - { NET_IPV4_FORWARD, "ip_forward" }, - { NET_IPV4_DYNADDR, "ip_dynaddr" }, - - { NET_IPV4_CONF, "conf", trans_net_ipv4_conf_table }, - { NET_IPV4_NEIGH, "neigh", trans_net_neigh_table }, - { NET_IPV4_ROUTE, "route", trans_net_ipv4_route_table }, - /* NET_IPV4_FIB_HASH unused */ - { NET_IPV4_NETFILTER, "netfilter", trans_net_ipv4_netfilter_table }, - { NET_IPV4_VS, "vs", trans_net_ipv4_vs_table }, - - { NET_IPV4_TCP_TIMESTAMPS, "tcp_timestamps" }, - { NET_IPV4_TCP_WINDOW_SCALING, "tcp_window_scaling" }, - { NET_IPV4_TCP_SACK, "tcp_sack" }, - { NET_IPV4_TCP_RETRANS_COLLAPSE, "tcp_retrans_collapse" }, - { NET_IPV4_DEFAULT_TTL, "ip_default_ttl" }, - /* NET_IPV4_AUTOCONFIG unused */ - { NET_IPV4_NO_PMTU_DISC, "ip_no_pmtu_disc" }, - { NET_IPV4_TCP_SYN_RETRIES, "tcp_syn_retries" }, - { NET_IPV4_IPFRAG_HIGH_THRESH, "ipfrag_high_thresh" }, - { NET_IPV4_IPFRAG_LOW_THRESH, "ipfrag_low_thresh" }, - { NET_IPV4_IPFRAG_TIME, "ipfrag_time" }, - /* NET_IPV4_TCP_MAX_KA_PROBES unused */ - { NET_IPV4_TCP_KEEPALIVE_TIME, "tcp_keepalive_time" }, - { NET_IPV4_TCP_KEEPALIVE_PROBES, "tcp_keepalive_probes" }, - { NET_IPV4_TCP_RETRIES1, "tcp_retries1" }, - { NET_IPV4_TCP_RETRIES2, "tcp_retries2" }, - { NET_IPV4_TCP_FIN_TIMEOUT, "tcp_fin_timeout" }, - /* NET_IPV4_IP_MASQ_DEBUG unused */ - { NET_TCP_SYNCOOKIES, "tcp_syncookies" }, - { NET_TCP_STDURG, "tcp_stdurg" }, - { NET_TCP_RFC1337, "tcp_rfc1337" }, - /* NET_TCP_SYN_TAILDROP unused */ - { NET_TCP_MAX_SYN_BACKLOG, "tcp_max_syn_backlog" }, - { NET_IPV4_LOCAL_PORT_RANGE, "ip_local_port_range" }, - { NET_IPV4_ICMP_ECHO_IGNORE_ALL, "icmp_echo_ignore_all" }, - { NET_IPV4_ICMP_ECHO_IGNORE_BROADCASTS, "icmp_echo_ignore_broadcasts" }, - /* NET_IPV4_ICMP_SOURCEQUENCH_RATE unused */ - /* NET_IPV4_ICMP_DESTUNREACH_RATE unused */ - /* NET_IPV4_ICMP_TIMEEXCEED_RATE unused */ - /* NET_IPV4_ICMP_PARAMPROB_RATE unused */ - /* NET_IPV4_ICMP_ECHOREPLY_RATE unused */ - { NET_IPV4_ICMP_IGNORE_BOGUS_ERROR_RESPONSES, "icmp_ignore_bogus_error_responses" }, - { NET_IPV4_IGMP_MAX_MEMBERSHIPS, "igmp_max_memberships" }, - { NET_TCP_TW_RECYCLE, "tcp_tw_recycle" }, - /* NET_IPV4_ALWAYS_DEFRAG unused */ - { NET_IPV4_TCP_KEEPALIVE_INTVL, "tcp_keepalive_intvl" }, - { NET_IPV4_INET_PEER_THRESHOLD, "inet_peer_threshold" }, - { NET_IPV4_INET_PEER_MINTTL, "inet_peer_minttl" }, - { NET_IPV4_INET_PEER_MAXTTL, "inet_peer_maxttl" }, - { NET_IPV4_INET_PEER_GC_MINTIME, "inet_peer_gc_mintime" }, - { NET_IPV4_INET_PEER_GC_MAXTIME, "inet_peer_gc_maxtime" }, - { NET_TCP_ORPHAN_RETRIES, "tcp_orphan_retries" }, - { NET_TCP_ABORT_ON_OVERFLOW, "tcp_abort_on_overflow" }, - { NET_TCP_SYNACK_RETRIES, "tcp_synack_retries" }, - { NET_TCP_MAX_ORPHANS, "tcp_max_orphans" }, - { NET_TCP_MAX_TW_BUCKETS, "tcp_max_tw_buckets" }, - { NET_TCP_FACK, "tcp_fack" }, - { NET_TCP_REORDERING, "tcp_reordering" }, - { NET_TCP_ECN, "tcp_ecn" }, - { NET_TCP_DSACK, "tcp_dsack" }, - { NET_TCP_MEM, "tcp_mem" }, - { NET_TCP_WMEM, "tcp_wmem" }, - { NET_TCP_RMEM, "tcp_rmem" }, - { NET_TCP_APP_WIN, "tcp_app_win" }, - { NET_TCP_ADV_WIN_SCALE, "tcp_adv_win_scale" }, - { NET_IPV4_NONLOCAL_BIND, "ip_nonlocal_bind" }, - { NET_IPV4_ICMP_RATELIMIT, "icmp_ratelimit" }, - { NET_IPV4_ICMP_RATEMASK, "icmp_ratemask" }, - { NET_TCP_TW_REUSE, "tcp_tw_reuse" }, - { NET_TCP_FRTO, "tcp_frto" }, - { NET_TCP_LOW_LATENCY, "tcp_low_latency" }, - { NET_IPV4_IPFRAG_SECRET_INTERVAL, "ipfrag_secret_interval" }, - { NET_IPV4_IGMP_MAX_MSF, "igmp_max_msf" }, - { NET_TCP_NO_METRICS_SAVE, "tcp_no_metrics_save" }, - /* NET_TCP_DEFAULT_WIN_SCALE unused */ - { NET_TCP_MODERATE_RCVBUF, "tcp_moderate_rcvbuf" }, - { NET_TCP_TSO_WIN_DIVISOR, "tcp_tso_win_divisor" }, - /* NET_TCP_BIC_BETA unused */ - { NET_IPV4_ICMP_ERRORS_USE_INBOUND_IFADDR, "icmp_errors_use_inbound_ifaddr" }, - { NET_TCP_CONG_CONTROL, "tcp_congestion_control" }, - { NET_TCP_ABC, "tcp_abc" }, - { NET_IPV4_IPFRAG_MAX_DIST, "ipfrag_max_dist" }, - { NET_TCP_MTU_PROBING, "tcp_mtu_probing" }, - { NET_TCP_BASE_MSS, "tcp_base_mss" }, - { NET_IPV4_TCP_WORKAROUND_SIGNED_WINDOWS, "tcp_workaround_signed_windows" }, - { NET_TCP_DMA_COPYBREAK, "tcp_dma_copybreak" }, - { NET_TCP_SLOW_START_AFTER_IDLE, "tcp_slow_start_after_idle" }, - { NET_CIPSOV4_CACHE_ENABLE, "cipso_cache_enable" }, - { NET_CIPSOV4_CACHE_BUCKET_SIZE, "cipso_cache_bucket_size" }, - { NET_CIPSOV4_RBM_OPTFMT, "cipso_rbm_optfmt" }, - { NET_CIPSOV4_RBM_STRICTVALID, "cipso_rbm_strictvalid" }, - { NET_TCP_AVAIL_CONG_CONTROL, "tcp_available_congestion_control" }, - { NET_TCP_ALLOWED_CONG_CONTROL, "tcp_allowed_congestion_control" }, - { NET_TCP_MAX_SSTHRESH, "tcp_max_ssthresh" }, - { NET_TCP_FRTO_RESPONSE, "tcp_frto_response" }, - { 2088 /* NET_IPQ_QMAX */, "ip_queue_maxlen" }, - {} -}; - -static struct trans_ctl_table trans_net_ipx_table[] = { - { NET_IPX_PPROP_BROADCASTING, "ipx_pprop_broadcasting" }, - /* NET_IPX_FORWARDING unused */ - {} -}; - -static struct trans_ctl_table trans_net_atalk_table[] = { - { NET_ATALK_AARP_EXPIRY_TIME, "aarp-expiry-time" }, - { NET_ATALK_AARP_TICK_TIME, "aarp-tick-time" }, - { NET_ATALK_AARP_RETRANSMIT_LIMIT, "aarp-retransmit-limit" }, - { NET_ATALK_AARP_RESOLVE_TIME, "aarp-resolve-time" }, - {}, -}; - -static struct trans_ctl_table trans_net_netrom_table[] = { - { NET_NETROM_DEFAULT_PATH_QUALITY, "default_path_quality" }, - { NET_NETROM_OBSOLESCENCE_COUNT_INITIALISER, "obsolescence_count_initialiser" }, - { NET_NETROM_NETWORK_TTL_INITIALISER, "network_ttl_initialiser" }, - { NET_NETROM_TRANSPORT_TIMEOUT, "transport_timeout" }, - { NET_NETROM_TRANSPORT_MAXIMUM_TRIES, "transport_maximum_tries" }, - { NET_NETROM_TRANSPORT_ACKNOWLEDGE_DELAY, "transport_acknowledge_delay" }, - { NET_NETROM_TRANSPORT_BUSY_DELAY, "transport_busy_delay" }, - { NET_NETROM_TRANSPORT_REQUESTED_WINDOW_SIZE, "transport_requested_window_size" }, - { NET_NETROM_TRANSPORT_NO_ACTIVITY_TIMEOUT, "transport_no_activity_timeout" }, - { NET_NETROM_ROUTING_CONTROL, "routing_control" }, - { NET_NETROM_LINK_FAILS_COUNT, "link_fails_count" }, - { NET_NETROM_RESET, "reset" }, - {} -}; - -static struct trans_ctl_table trans_net_ax25_table[] = { - { NET_AX25_IP_DEFAULT_MODE, "ip_default_mode" }, - { NET_AX25_DEFAULT_MODE, "ax25_default_mode" }, - { NET_AX25_BACKOFF_TYPE, "backoff_type" }, - { NET_AX25_CONNECT_MODE, "connect_mode" }, - { NET_AX25_STANDARD_WINDOW, "standard_window_size" }, - { NET_AX25_EXTENDED_WINDOW, "extended_window_size" }, - { NET_AX25_T1_TIMEOUT, "t1_timeout" }, - { NET_AX25_T2_TIMEOUT, "t2_timeout" }, - { NET_AX25_T3_TIMEOUT, "t3_timeout" }, - { NET_AX25_IDLE_TIMEOUT, "idle_timeout" }, - { NET_AX25_N2, "maximum_retry_count" }, - { NET_AX25_PACLEN, "maximum_packet_length" }, - { NET_AX25_PROTOCOL, "protocol" }, - { NET_AX25_DAMA_SLAVE_TIMEOUT, "dama_slave_timeout" }, - {} -}; - -static struct trans_ctl_table trans_net_bridge_table[] = { - { NET_BRIDGE_NF_CALL_ARPTABLES, "bridge-nf-call-arptables" }, - { NET_BRIDGE_NF_CALL_IPTABLES, "bridge-nf-call-iptables" }, - { NET_BRIDGE_NF_CALL_IP6TABLES, "bridge-nf-call-ip6tables" }, - { NET_BRIDGE_NF_FILTER_VLAN_TAGGED, "bridge-nf-filter-vlan-tagged" }, - { NET_BRIDGE_NF_FILTER_PPPOE_TAGGED, "bridge-nf-filter-pppoe-tagged" }, - {} -}; - -static struct trans_ctl_table trans_net_rose_table[] = { - { NET_ROSE_RESTART_REQUEST_TIMEOUT, "restart_request_timeout" }, - { NET_ROSE_CALL_REQUEST_TIMEOUT, "call_request_timeout" }, - { NET_ROSE_RESET_REQUEST_TIMEOUT, "reset_request_timeout" }, - { NET_ROSE_CLEAR_REQUEST_TIMEOUT, "clear_request_timeout" }, - { NET_ROSE_ACK_HOLD_BACK_TIMEOUT, "acknowledge_hold_back_timeout" }, - { NET_ROSE_ROUTING_CONTROL, "routing_control" }, - { NET_ROSE_LINK_FAIL_TIMEOUT, "link_fail_timeout" }, - { NET_ROSE_MAX_VCS, "maximum_virtual_circuits" }, - { NET_ROSE_WINDOW_SIZE, "window_size" }, - { NET_ROSE_NO_ACTIVITY_TIMEOUT, "no_activity_timeout" }, - {} -}; - -static struct trans_ctl_table trans_net_ipv6_conf_var_table[] = { - { NET_IPV6_FORWARDING, "forwarding" }, - { NET_IPV6_HOP_LIMIT, "hop_limit" }, - { NET_IPV6_MTU, "mtu" }, - { NET_IPV6_ACCEPT_RA, "accept_ra" }, - { NET_IPV6_ACCEPT_REDIRECTS, "accept_redirects" }, - { NET_IPV6_AUTOCONF, "autoconf" }, - { NET_IPV6_DAD_TRANSMITS, "dad_transmits" }, - { NET_IPV6_RTR_SOLICITS, "router_solicitations" }, - { NET_IPV6_RTR_SOLICIT_INTERVAL, "router_solicitation_interval" }, - { NET_IPV6_RTR_SOLICIT_DELAY, "router_solicitation_delay" }, - { NET_IPV6_USE_TEMPADDR, "use_tempaddr" }, - { NET_IPV6_TEMP_VALID_LFT, "temp_valid_lft" }, - { NET_IPV6_TEMP_PREFERED_LFT, "temp_prefered_lft" }, - { NET_IPV6_REGEN_MAX_RETRY, "regen_max_retry" }, - { NET_IPV6_MAX_DESYNC_FACTOR, "max_desync_factor" }, - { NET_IPV6_MAX_ADDRESSES, "max_addresses" }, - { NET_IPV6_FORCE_MLD_VERSION, "force_mld_version" }, - { NET_IPV6_ACCEPT_RA_DEFRTR, "accept_ra_defrtr" }, - { NET_IPV6_ACCEPT_RA_PINFO, "accept_ra_pinfo" }, - { NET_IPV6_ACCEPT_RA_RTR_PREF, "accept_ra_rtr_pref" }, - { NET_IPV6_RTR_PROBE_INTERVAL, "router_probe_interval" }, - { NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN, "accept_ra_rt_info_max_plen" }, - { NET_IPV6_PROXY_NDP, "proxy_ndp" }, - { NET_IPV6_ACCEPT_SOURCE_ROUTE, "accept_source_route" }, - {} -}; - -static struct trans_ctl_table trans_net_ipv6_conf_table[] = { - { NET_PROTO_CONF_ALL, "all", trans_net_ipv6_conf_var_table }, - { NET_PROTO_CONF_DEFAULT, "default", trans_net_ipv6_conf_var_table }, - { 0, NULL, trans_net_ipv6_conf_var_table }, - {} -}; - -static struct trans_ctl_table trans_net_ipv6_route_table[] = { - { NET_IPV6_ROUTE_FLUSH, "flush" }, - { NET_IPV6_ROUTE_GC_THRESH, "gc_thresh" }, - { NET_IPV6_ROUTE_MAX_SIZE, "max_size" }, - { NET_IPV6_ROUTE_GC_MIN_INTERVAL, "gc_min_interval" }, - { NET_IPV6_ROUTE_GC_TIMEOUT, "gc_timeout" }, - { NET_IPV6_ROUTE_GC_INTERVAL, "gc_interval" }, - { NET_IPV6_ROUTE_GC_ELASTICITY, "gc_elasticity" }, - { NET_IPV6_ROUTE_MTU_EXPIRES, "mtu_expires" }, - { NET_IPV6_ROUTE_MIN_ADVMSS, "min_adv_mss" }, - { NET_IPV6_ROUTE_GC_MIN_INTERVAL_MS, "gc_min_interval_ms" }, - {} -}; - -static struct trans_ctl_table trans_net_ipv6_icmp_table[] = { - { NET_IPV6_ICMP_RATELIMIT, "ratelimit" }, - {} -}; - -static struct trans_ctl_table trans_net_ipv6_table[] = { - { NET_IPV6_CONF, "conf", trans_net_ipv6_conf_table }, - { NET_IPV6_NEIGH, "neigh", trans_net_neigh_table }, - { NET_IPV6_ROUTE, "route", trans_net_ipv6_route_table }, - { NET_IPV6_ICMP, "icmp", trans_net_ipv6_icmp_table }, - { NET_IPV6_BINDV6ONLY, "bindv6only" }, - { NET_IPV6_IP6FRAG_HIGH_THRESH, "ip6frag_high_thresh" }, - { NET_IPV6_IP6FRAG_LOW_THRESH, "ip6frag_low_thresh" }, - { NET_IPV6_IP6FRAG_TIME, "ip6frag_time" }, - { NET_IPV6_IP6FRAG_SECRET_INTERVAL, "ip6frag_secret_interval" }, - { NET_IPV6_MLD_MAX_MSF, "mld_max_msf" }, - { 2088 /* IPQ_QMAX */, "ip6_queue_maxlen" }, - {} -}; - -static struct trans_ctl_table trans_net_x25_table[] = { - { NET_X25_RESTART_REQUEST_TIMEOUT, "restart_request_timeout" }, - { NET_X25_CALL_REQUEST_TIMEOUT, "call_request_timeout" }, - { NET_X25_RESET_REQUEST_TIMEOUT, "reset_request_timeout" }, - { NET_X25_CLEAR_REQUEST_TIMEOUT, "clear_request_timeout" }, - { NET_X25_ACK_HOLD_BACK_TIMEOUT, "acknowledgement_hold_back_timeout" }, - { NET_X25_FORWARD, "x25_forward" }, - {} -}; - -static struct trans_ctl_table trans_net_tr_table[] = { - { NET_TR_RIF_TIMEOUT, "rif_timeout" }, - {} -}; - - -static struct trans_ctl_table trans_net_decnet_conf_vars[] = { - { NET_DECNET_CONF_DEV_FORWARDING, "forwarding" }, - { NET_DECNET_CONF_DEV_PRIORITY, "priority" }, - { NET_DECNET_CONF_DEV_T2, "t2" }, - { NET_DECNET_CONF_DEV_T3, "t3" }, - {} -}; - -static struct trans_ctl_table trans_net_decnet_conf[] = { - { 0, NULL, trans_net_decnet_conf_vars }, - {} -}; - -static struct trans_ctl_table trans_net_decnet_table[] = { - { NET_DECNET_CONF, "conf", trans_net_decnet_conf }, - { NET_DECNET_NODE_ADDRESS, "node_address" }, - { NET_DECNET_NODE_NAME, "node_name" }, - { NET_DECNET_DEFAULT_DEVICE, "default_device" }, - { NET_DECNET_TIME_WAIT, "time_wait" }, - { NET_DECNET_DN_COUNT, "dn_count" }, - { NET_DECNET_DI_COUNT, "di_count" }, - { NET_DECNET_DR_COUNT, "dr_count" }, - { NET_DECNET_DST_GC_INTERVAL, "dst_gc_interval" }, - { NET_DECNET_NO_FC_MAX_CWND, "no_fc_max_cwnd" }, - { NET_DECNET_MEM, "decnet_mem" }, - { NET_DECNET_RMEM, "decnet_rmem" }, - { NET_DECNET_WMEM, "decnet_wmem" }, - { NET_DECNET_DEBUG_LEVEL, "debug" }, - {} -}; - -static struct trans_ctl_table trans_net_sctp_table[] = { - { NET_SCTP_RTO_INITIAL, "rto_initial" }, - { NET_SCTP_RTO_MIN, "rto_min" }, - { NET_SCTP_RTO_MAX, "rto_max" }, - { NET_SCTP_RTO_ALPHA, "rto_alpha_exp_divisor" }, - { NET_SCTP_RTO_BETA, "rto_beta_exp_divisor" }, - { NET_SCTP_VALID_COOKIE_LIFE, "valid_cookie_life" }, - { NET_SCTP_ASSOCIATION_MAX_RETRANS, "association_max_retrans" }, - { NET_SCTP_PATH_MAX_RETRANS, "path_max_retrans" }, - { NET_SCTP_MAX_INIT_RETRANSMITS, "max_init_retransmits" }, - { NET_SCTP_HB_INTERVAL, "hb_interval" }, - { NET_SCTP_PRESERVE_ENABLE, "cookie_preserve_enable" }, - { NET_SCTP_MAX_BURST, "max_burst" }, - { NET_SCTP_ADDIP_ENABLE, "addip_enable" }, - { NET_SCTP_PRSCTP_ENABLE, "prsctp_enable" }, - { NET_SCTP_SNDBUF_POLICY, "sndbuf_policy" }, - { NET_SCTP_SACK_TIMEOUT, "sack_timeout" }, - { NET_SCTP_RCVBUF_POLICY, "rcvbuf_policy" }, - {} -}; - -static struct trans_ctl_table trans_net_llc_llc2_timeout_table[] = { - { NET_LLC2_ACK_TIMEOUT, "ack" }, - { NET_LLC2_P_TIMEOUT, "p" }, - { NET_LLC2_REJ_TIMEOUT, "rej" }, - { NET_LLC2_BUSY_TIMEOUT, "busy" }, - {} -}; - -static struct trans_ctl_table trans_net_llc_station_table[] = { - { NET_LLC_STATION_ACK_TIMEOUT, "ack_timeout" }, - {} -}; - -static struct trans_ctl_table trans_net_llc_llc2_table[] = { - { NET_LLC2, "timeout", trans_net_llc_llc2_timeout_table }, - {} -}; - -static struct trans_ctl_table trans_net_llc_table[] = { - { NET_LLC2, "llc2", trans_net_llc_llc2_table }, - { NET_LLC_STATION, "station", trans_net_llc_station_table }, - {} -}; - -static struct trans_ctl_table trans_net_netfilter_table[] = { - { NET_NF_CONNTRACK_MAX, "nf_conntrack_max" }, - { NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT, "nf_conntrack_tcp_timeout_syn_sent" }, - { NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_RECV, "nf_conntrack_tcp_timeout_syn_recv" }, - { NET_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED, "nf_conntrack_tcp_timeout_established" }, - { NET_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT, "nf_conntrack_tcp_timeout_fin_wait" }, - { NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE_WAIT, "nf_conntrack_tcp_timeout_close_wait" }, - { NET_NF_CONNTRACK_TCP_TIMEOUT_LAST_ACK, "nf_conntrack_tcp_timeout_last_ack" }, - { NET_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT, "nf_conntrack_tcp_timeout_time_wait" }, - { NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE, "nf_conntrack_tcp_timeout_close" }, - { NET_NF_CONNTRACK_UDP_TIMEOUT, "nf_conntrack_udp_timeout" }, - { NET_NF_CONNTRACK_UDP_TIMEOUT_STREAM, "nf_conntrack_udp_timeout_stream" }, - { NET_NF_CONNTRACK_ICMP_TIMEOUT, "nf_conntrack_icmp_timeout" }, - { NET_NF_CONNTRACK_GENERIC_TIMEOUT, "nf_conntrack_generic_timeout" }, - { NET_NF_CONNTRACK_BUCKETS, "nf_conntrack_buckets" }, - { NET_NF_CONNTRACK_LOG_INVALID, "nf_conntrack_log_invalid" }, - { NET_NF_CONNTRACK_TCP_TIMEOUT_MAX_RETRANS, "nf_conntrack_tcp_timeout_max_retrans" }, - { NET_NF_CONNTRACK_TCP_LOOSE, "nf_conntrack_tcp_loose" }, - { NET_NF_CONNTRACK_TCP_BE_LIBERAL, "nf_conntrack_tcp_be_liberal" }, - { NET_NF_CONNTRACK_TCP_MAX_RETRANS, "nf_conntrack_tcp_max_retrans" }, - { NET_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED, "nf_conntrack_sctp_timeout_closed" }, - { NET_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_WAIT, "nf_conntrack_sctp_timeout_cookie_wait" }, - { NET_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_ECHOED, "nf_conntrack_sctp_timeout_cookie_echoed" }, - { NET_NF_CONNTRACK_SCTP_TIMEOUT_ESTABLISHED, "nf_conntrack_sctp_timeout_established" }, - { NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT, "nf_conntrack_sctp_timeout_shutdown_sent" }, - { NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD, "nf_conntrack_sctp_timeout_shutdown_recd" }, - { NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT, "nf_conntrack_sctp_timeout_shutdown_ack_sent" }, - { NET_NF_CONNTRACK_COUNT, "nf_conntrack_count" }, - { NET_NF_CONNTRACK_ICMPV6_TIMEOUT, "nf_conntrack_icmpv6_timeout" }, - { NET_NF_CONNTRACK_FRAG6_TIMEOUT, "nf_conntrack_frag6_timeout" }, - { NET_NF_CONNTRACK_FRAG6_LOW_THRESH, "nf_conntrack_frag6_low_thresh" }, - { NET_NF_CONNTRACK_FRAG6_HIGH_THRESH, "nf_conntrack_frag6_high_thresh" }, - { NET_NF_CONNTRACK_CHECKSUM, "nf_conntrack_checksum" }, - - {} -}; - -static struct trans_ctl_table trans_net_dccp_table[] = { - { NET_DCCP_DEFAULT, "default" }, - {} -}; - -static struct trans_ctl_table trans_net_irda_table[] = { - { NET_IRDA_DISCOVERY, "discovery" }, - { NET_IRDA_DEVNAME, "devname" }, - { NET_IRDA_DEBUG, "debug" }, - { NET_IRDA_FAST_POLL, "fast_poll_increase" }, - { NET_IRDA_DISCOVERY_SLOTS, "discovery_slots" }, - { NET_IRDA_DISCOVERY_TIMEOUT, "discovery_timeout" }, - { NET_IRDA_SLOT_TIMEOUT, "slot_timeout" }, - { NET_IRDA_MAX_BAUD_RATE, "max_baud_rate" }, - { NET_IRDA_MIN_TX_TURN_TIME, "min_tx_turn_time" }, - { NET_IRDA_MAX_TX_DATA_SIZE, "max_tx_data_size" }, - { NET_IRDA_MAX_TX_WINDOW, "max_tx_window" }, - { NET_IRDA_MAX_NOREPLY_TIME, "max_noreply_time" }, - { NET_IRDA_WARN_NOREPLY_TIME, "warn_noreply_time" }, - { NET_IRDA_LAP_KEEPALIVE_TIME, "lap_keepalive_time" }, - {} -}; - -static struct trans_ctl_table trans_net_table[] = { - { NET_CORE, "core", trans_net_core_table }, - /* NET_ETHER not used */ - /* NET_802 not used */ - { NET_UNIX, "unix", trans_net_unix_table }, - { NET_IPV4, "ipv4", trans_net_ipv4_table }, - { NET_IPX, "ipx", trans_net_ipx_table }, - { NET_ATALK, "atalk", trans_net_atalk_table }, - { NET_NETROM, "netrom", trans_net_netrom_table }, - { NET_AX25, "ax25", trans_net_ax25_table }, - { NET_BRIDGE, "bridge", trans_net_bridge_table }, - { NET_ROSE, "rose", trans_net_rose_table }, - { NET_IPV6, "ipv6", trans_net_ipv6_table }, - { NET_X25, "x25", trans_net_x25_table }, - { NET_TR, "tr", trans_net_tr_table }, - { NET_DECNET, "decnet", trans_net_decnet_table }, - /* NET_ECONET not used */ - { NET_SCTP, "sctp", trans_net_sctp_table }, - { NET_LLC, "llc", trans_net_llc_table }, - { NET_NETFILTER, "netfilter", trans_net_netfilter_table }, - { NET_DCCP, "dccp", trans_net_dccp_table }, - { NET_IRDA, "irda", trans_net_irda_table }, - { 2089, "nf_conntrack_max" }, - {} -}; - -static struct trans_ctl_table trans_fs_quota_table[] = { - { FS_DQ_LOOKUPS, "lookups" }, - { FS_DQ_DROPS, "drops" }, - { FS_DQ_READS, "reads" }, - { FS_DQ_WRITES, "writes" }, - { FS_DQ_CACHE_HITS, "cache_hits" }, - { FS_DQ_ALLOCATED, "allocated_dquots" }, - { FS_DQ_FREE, "free_dquots" }, - { FS_DQ_SYNCS, "syncs" }, - { FS_DQ_WARNINGS, "warnings" }, - {} -}; - -static struct trans_ctl_table trans_fs_xfs_table[] = { - { XFS_RESTRICT_CHOWN, "restrict_chown" }, - { XFS_SGID_INHERIT, "irix_sgid_inherit" }, - { XFS_SYMLINK_MODE, "irix_symlink_mode" }, - { XFS_PANIC_MASK, "panic_mask" }, - - { XFS_ERRLEVEL, "error_level" }, - { XFS_SYNCD_TIMER, "xfssyncd_centisecs" }, - { XFS_INHERIT_SYNC, "inherit_sync" }, - { XFS_INHERIT_NODUMP, "inherit_nodump" }, - { XFS_INHERIT_NOATIME, "inherit_noatime" }, - { XFS_BUF_TIMER, "xfsbufd_centisecs" }, - { XFS_BUF_AGE, "age_buffer_centisecs" }, - { XFS_INHERIT_NOSYM, "inherit_nosymlinks" }, - { XFS_ROTORSTEP, "rotorstep" }, - { XFS_INHERIT_NODFRG, "inherit_nodefrag" }, - { XFS_FILESTREAM_TIMER, "filestream_centisecs" }, - { XFS_STATS_CLEAR, "stats_clear" }, - {} -}; - -static struct trans_ctl_table trans_fs_ocfs2_nm_table[] = { - { 1, "hb_ctl_path" }, - {} -}; - -static struct trans_ctl_table trans_fs_ocfs2_table[] = { - { 1, "nm", trans_fs_ocfs2_nm_table }, - {} -}; - -static struct trans_ctl_table trans_inotify_table[] = { - { INOTIFY_MAX_USER_INSTANCES, "max_user_instances" }, - { INOTIFY_MAX_USER_WATCHES, "max_user_watches" }, - { INOTIFY_MAX_QUEUED_EVENTS, "max_queued_events" }, - {} -}; - -static struct trans_ctl_table trans_fs_table[] = { - { FS_NRINODE, "inode-nr" }, - { FS_STATINODE, "inode-state" }, - /* FS_MAXINODE unused */ - /* FS_NRDQUOT unused */ - /* FS_MAXDQUOT unused */ - { FS_NRFILE, "file-nr" }, - { FS_MAXFILE, "file-max" }, - { FS_DENTRY, "dentry-state" }, - /* FS_NRSUPER unused */ - /* FS_MAXUPSER unused */ - { FS_OVERFLOWUID, "overflowuid" }, - { FS_OVERFLOWGID, "overflowgid" }, - { FS_LEASES, "leases-enable" }, - { FS_DIR_NOTIFY, "dir-notify-enable" }, - { FS_LEASE_TIME, "lease-break-time" }, - { FS_DQSTATS, "quota", trans_fs_quota_table }, - { FS_XFS, "xfs", trans_fs_xfs_table }, - { FS_AIO_NR, "aio-nr" }, - { FS_AIO_MAX_NR, "aio-max-nr" }, - { FS_INOTIFY, "inotify", trans_inotify_table }, - { FS_OCFS2, "ocfs2", trans_fs_ocfs2_table }, - { KERN_SETUID_DUMPABLE, "suid_dumpable" }, - {} -}; - -static struct trans_ctl_table trans_debug_table[] = { - {} -}; - -static struct trans_ctl_table trans_cdrom_table[] = { - { DEV_CDROM_INFO, "info" }, - { DEV_CDROM_AUTOCLOSE, "autoclose" }, - { DEV_CDROM_AUTOEJECT, "autoeject" }, - { DEV_CDROM_DEBUG, "debug" }, - { DEV_CDROM_LOCK, "lock" }, - { DEV_CDROM_CHECK_MEDIA, "check_media" }, - {} -}; - -static struct trans_ctl_table trans_ipmi_table[] = { - { DEV_IPMI_POWEROFF_POWERCYCLE, "poweroff_powercycle" }, - {} -}; - -static struct trans_ctl_table trans_mac_hid_files[] = { - /* DEV_MAC_HID_KEYBOARD_SENDS_LINUX_KEYCODES unused */ - /* DEV_MAC_HID_KEYBOARD_LOCK_KEYCODES unused */ - { DEV_MAC_HID_MOUSE_BUTTON_EMULATION, "mouse_button_emulation" }, - { DEV_MAC_HID_MOUSE_BUTTON2_KEYCODE, "mouse_button2_keycode" }, - { DEV_MAC_HID_MOUSE_BUTTON3_KEYCODE, "mouse_button3_keycode" }, - /* DEV_MAC_HID_ADB_MOUSE_SENDS_KEYCODES unused */ - {} -}; - -static struct trans_ctl_table trans_raid_table[] = { - { DEV_RAID_SPEED_LIMIT_MIN, "speed_limit_min" }, - { DEV_RAID_SPEED_LIMIT_MAX, "speed_limit_max" }, - {} -}; - -static struct trans_ctl_table trans_scsi_table[] = { - { DEV_SCSI_LOGGING_LEVEL, "logging_level" }, - {} -}; - -static struct trans_ctl_table trans_parport_default_table[] = { - { DEV_PARPORT_DEFAULT_TIMESLICE, "timeslice" }, - { DEV_PARPORT_DEFAULT_SPINTIME, "spintime" }, - {} -}; - -static struct trans_ctl_table trans_parport_device_table[] = { - { DEV_PARPORT_DEVICE_TIMESLICE, "timeslice" }, - {} -}; - -static struct trans_ctl_table trans_parport_devices_table[] = { - { DEV_PARPORT_DEVICES_ACTIVE, "active" }, - { 0, NULL, trans_parport_device_table }, - {} -}; - -static struct trans_ctl_table trans_parport_parport_table[] = { - { DEV_PARPORT_SPINTIME, "spintime" }, - { DEV_PARPORT_BASE_ADDR, "base-addr" }, - { DEV_PARPORT_IRQ, "irq" }, - { DEV_PARPORT_DMA, "dma" }, - { DEV_PARPORT_MODES, "modes" }, - { DEV_PARPORT_DEVICES, "devices", trans_parport_devices_table }, - { DEV_PARPORT_AUTOPROBE, "autoprobe" }, - { DEV_PARPORT_AUTOPROBE + 1, "autoprobe0" }, - { DEV_PARPORT_AUTOPROBE + 2, "autoprobe1" }, - { DEV_PARPORT_AUTOPROBE + 3, "autoprobe2" }, - { DEV_PARPORT_AUTOPROBE + 4, "autoprobe3" }, - {} -}; -static struct trans_ctl_table trans_parport_table[] = { - { DEV_PARPORT_DEFAULT, "default", trans_parport_default_table }, - { 0, NULL, trans_parport_parport_table }, - {} -}; - -static struct trans_ctl_table trans_dev_table[] = { - { DEV_CDROM, "cdrom", trans_cdrom_table }, - /* DEV_HWMON unused */ - { DEV_PARPORT, "parport", trans_parport_table }, - { DEV_RAID, "raid", trans_raid_table }, - { DEV_MAC_HID, "mac_hid", trans_mac_hid_files }, - { DEV_SCSI, "scsi", trans_scsi_table }, - { DEV_IPMI, "ipmi", trans_ipmi_table }, - {} -}; - -static struct trans_ctl_table trans_bus_isa_table[] = { - { BUS_ISA_MEM_BASE, "membase" }, - { BUS_ISA_PORT_BASE, "portbase" }, - { BUS_ISA_PORT_SHIFT, "portshift" }, - {} -}; - -static struct trans_ctl_table trans_bus_table[] = { - { CTL_BUS_ISA, "isa", trans_bus_isa_table }, - {} -}; - -static struct trans_ctl_table trans_arlan_conf_table0[] = { - { 1, "spreadingCode" }, - { 2, "channelNumber" }, - { 3, "scramblingDisable" }, - { 4, "txAttenuation" }, - { 5, "systemId" }, - { 6, "maxDatagramSize" }, - { 7, "maxFrameSize" }, - { 8, "maxRetries" }, - { 9, "receiveMode" }, - { 10, "priority" }, - { 11, "rootOrRepeater" }, - { 12, "SID" }, - { 13, "registrationMode" }, - { 14, "registrationFill" }, - { 15, "localTalkAddress" }, - { 16, "codeFormat" }, - { 17, "numChannels" }, - { 18, "channel1" }, - { 19, "channel2" }, - { 20, "channel3" }, - { 21, "channel4" }, - { 22, "txClear" }, - { 23, "txRetries" }, - { 24, "txRouting" }, - { 25, "txScrambled" }, - { 26, "rxParameter" }, - { 27, "txTimeoutMs" }, - { 28, "waitCardTimeout" }, - { 29, "channelSet" }, - { 30, "name" }, - { 31, "waitTime" }, - { 32, "lParameter" }, - { 33, "_15" }, - { 34, "headerSize" }, - { 36, "tx_delay_ms" }, - { 37, "retries" }, - { 38, "ReTransmitPacketMaxSize" }, - { 39, "waitReTransmitPacketMaxSize" }, - { 40, "fastReTransCount" }, - { 41, "driverRetransmissions" }, - { 42, "txAckTimeoutMs" }, - { 43, "registrationInterrupts" }, - { 44, "hardwareType" }, - { 45, "radioType" }, - { 46, "writeEEPROM" }, - { 47, "writeRadioType" }, - { 48, "entry_exit_debug" }, - { 49, "debug" }, - { 50, "in_speed" }, - { 51, "out_speed" }, - { 52, "in_speed10" }, - { 53, "out_speed10" }, - { 54, "in_speed_max" }, - { 55, "out_speed_max" }, - { 56, "measure_rate" }, - { 57, "pre_Command_Wait" }, - { 58, "rx_tweak1" }, - { 59, "rx_tweak2" }, - { 60, "tx_queue_len" }, - - { 150, "arlan0-txRing" }, - { 151, "arlan0-rxRing" }, - { 152, "arlan0-18" }, - { 153, "arlan0-ring" }, - { 154, "arlan0-shm-cpy" }, - { 155, "config0" }, - { 156, "reset0" }, - {} -}; - -static struct trans_ctl_table trans_arlan_conf_table1[] = { - { 1, "spreadingCode" }, - { 2, "channelNumber" }, - { 3, "scramblingDisable" }, - { 4, "txAttenuation" }, - { 5, "systemId" }, - { 6, "maxDatagramSize" }, - { 7, "maxFrameSize" }, - { 8, "maxRetries" }, - { 9, "receiveMode" }, - { 10, "priority" }, - { 11, "rootOrRepeater" }, - { 12, "SID" }, - { 13, "registrationMode" }, - { 14, "registrationFill" }, - { 15, "localTalkAddress" }, - { 16, "codeFormat" }, - { 17, "numChannels" }, - { 18, "channel1" }, - { 19, "channel2" }, - { 20, "channel3" }, - { 21, "channel4" }, - { 22, "txClear" }, - { 23, "txRetries" }, - { 24, "txRouting" }, - { 25, "txScrambled" }, - { 26, "rxParameter" }, - { 27, "txTimeoutMs" }, - { 28, "waitCardTimeout" }, - { 29, "channelSet" }, - { 30, "name" }, - { 31, "waitTime" }, - { 32, "lParameter" }, - { 33, "_15" }, - { 34, "headerSize" }, - { 36, "tx_delay_ms" }, - { 37, "retries" }, - { 38, "ReTransmitPacketMaxSize" }, - { 39, "waitReTransmitPacketMaxSize" }, - { 40, "fastReTransCount" }, - { 41, "driverRetransmissions" }, - { 42, "txAckTimeoutMs" }, - { 43, "registrationInterrupts" }, - { 44, "hardwareType" }, - { 45, "radioType" }, - { 46, "writeEEPROM" }, - { 47, "writeRadioType" }, - { 48, "entry_exit_debug" }, - { 49, "debug" }, - { 50, "in_speed" }, - { 51, "out_speed" }, - { 52, "in_speed10" }, - { 53, "out_speed10" }, - { 54, "in_speed_max" }, - { 55, "out_speed_max" }, - { 56, "measure_rate" }, - { 57, "pre_Command_Wait" }, - { 58, "rx_tweak1" }, - { 59, "rx_tweak2" }, - { 60, "tx_queue_len" }, - - { 150, "arlan1-txRing" }, - { 151, "arlan1-rxRing" }, - { 152, "arlan1-18" }, - { 153, "arlan1-ring" }, - { 154, "arlan1-shm-cpy" }, - { 155, "config1" }, - { 156, "reset1" }, - {} -}; - -static struct trans_ctl_table trans_arlan_conf_table2[] = { - { 1, "spreadingCode" }, - { 2, "channelNumber" }, - { 3, "scramblingDisable" }, - { 4, "txAttenuation" }, - { 5, "systemId" }, - { 6, "maxDatagramSize" }, - { 7, "maxFrameSize" }, - { 8, "maxRetries" }, - { 9, "receiveMode" }, - { 10, "priority" }, - { 11, "rootOrRepeater" }, - { 12, "SID" }, - { 13, "registrationMode" }, - { 14, "registrationFill" }, - { 15, "localTalkAddress" }, - { 16, "codeFormat" }, - { 17, "numChannels" }, - { 18, "channel1" }, - { 19, "channel2" }, - { 20, "channel3" }, - { 21, "channel4" }, - { 22, "txClear" }, - { 23, "txRetries" }, - { 24, "txRouting" }, - { 25, "txScrambled" }, - { 26, "rxParameter" }, - { 27, "txTimeoutMs" }, - { 28, "waitCardTimeout" }, - { 29, "channelSet" }, - { 30, "name" }, - { 31, "waitTime" }, - { 32, "lParameter" }, - { 33, "_15" }, - { 34, "headerSize" }, - { 36, "tx_delay_ms" }, - { 37, "retries" }, - { 38, "ReTransmitPacketMaxSize" }, - { 39, "waitReTransmitPacketMaxSize" }, - { 40, "fastReTransCount" }, - { 41, "driverRetransmissions" }, - { 42, "txAckTimeoutMs" }, - { 43, "registrationInterrupts" }, - { 44, "hardwareType" }, - { 45, "radioType" }, - { 46, "writeEEPROM" }, - { 47, "writeRadioType" }, - { 48, "entry_exit_debug" }, - { 49, "debug" }, - { 50, "in_speed" }, - { 51, "out_speed" }, - { 52, "in_speed10" }, - { 53, "out_speed10" }, - { 54, "in_speed_max" }, - { 55, "out_speed_max" }, - { 56, "measure_rate" }, - { 57, "pre_Command_Wait" }, - { 58, "rx_tweak1" }, - { 59, "rx_tweak2" }, - { 60, "tx_queue_len" }, - - { 150, "arlan2-txRing" }, - { 151, "arlan2-rxRing" }, - { 152, "arlan2-18" }, - { 153, "arlan2-ring" }, - { 154, "arlan2-shm-cpy" }, - { 155, "config2" }, - { 156, "reset2" }, - {} -}; - -static struct trans_ctl_table trans_arlan_conf_table3[] = { - { 1, "spreadingCode" }, - { 2, "channelNumber" }, - { 3, "scramblingDisable" }, - { 4, "txAttenuation" }, - { 5, "systemId" }, - { 6, "maxDatagramSize" }, - { 7, "maxFrameSize" }, - { 8, "maxRetries" }, - { 9, "receiveMode" }, - { 10, "priority" }, - { 11, "rootOrRepeater" }, - { 12, "SID" }, - { 13, "registrationMode" }, - { 14, "registrationFill" }, - { 15, "localTalkAddress" }, - { 16, "codeFormat" }, - { 17, "numChannels" }, - { 18, "channel1" }, - { 19, "channel2" }, - { 20, "channel3" }, - { 21, "channel4" }, - { 22, "txClear" }, - { 23, "txRetries" }, - { 24, "txRouting" }, - { 25, "txScrambled" }, - { 26, "rxParameter" }, - { 27, "txTimeoutMs" }, - { 28, "waitCardTimeout" }, - { 29, "channelSet" }, - { 30, "name" }, - { 31, "waitTime" }, - { 32, "lParameter" }, - { 33, "_15" }, - { 34, "headerSize" }, - { 36, "tx_delay_ms" }, - { 37, "retries" }, - { 38, "ReTransmitPacketMaxSize" }, - { 39, "waitReTransmitPacketMaxSize" }, - { 40, "fastReTransCount" }, - { 41, "driverRetransmissions" }, - { 42, "txAckTimeoutMs" }, - { 43, "registrationInterrupts" }, - { 44, "hardwareType" }, - { 45, "radioType" }, - { 46, "writeEEPROM" }, - { 47, "writeRadioType" }, - { 48, "entry_exit_debug" }, - { 49, "debug" }, - { 50, "in_speed" }, - { 51, "out_speed" }, - { 52, "in_speed10" }, - { 53, "out_speed10" }, - { 54, "in_speed_max" }, - { 55, "out_speed_max" }, - { 56, "measure_rate" }, - { 57, "pre_Command_Wait" }, - { 58, "rx_tweak1" }, - { 59, "rx_tweak2" }, - { 60, "tx_queue_len" }, - - { 150, "arlan3-txRing" }, - { 151, "arlan3-rxRing" }, - { 152, "arlan3-18" }, - { 153, "arlan3-ring" }, - { 154, "arlan3-shm-cpy" }, - { 155, "config3" }, - { 156, "reset3" }, - {} -}; - -static struct trans_ctl_table trans_arlan_table[] = { - { 1, "arlan0", trans_arlan_conf_table0 }, - { 2, "arlan1", trans_arlan_conf_table1 }, - { 3, "arlan2", trans_arlan_conf_table2 }, - { 4, "arlan3", trans_arlan_conf_table3 }, - {} -}; - -static struct trans_ctl_table trans_appldata_table[] = { - { CTL_APPLDATA_TIMER, "timer" }, - { CTL_APPLDATA_INTERVAL, "interval" }, - { CTL_APPLDATA_OS, "os" }, - { CTL_APPLDATA_NET_SUM, "net_sum" }, - { CTL_APPLDATA_MEM, "mem" }, - {} - -}; - -static struct trans_ctl_table trans_s390dbf_table[] = { - { 5678 /* CTL_S390DBF_STOPPABLE */, "debug_stoppable" }, - { 5679 /* CTL_S390DBF_ACTIVE */, "debug_active" }, - {} -}; - -static struct trans_ctl_table trans_sunrpc_table[] = { - { CTL_RPCDEBUG, "rpc_debug" }, - { CTL_NFSDEBUG, "nfs_debug" }, - { CTL_NFSDDEBUG, "nfsd_debug" }, - { CTL_NLMDEBUG, "nlm_debug" }, - { CTL_SLOTTABLE_UDP, "udp_slot_table_entries" }, - { CTL_SLOTTABLE_TCP, "tcp_slot_table_entries" }, - { CTL_MIN_RESVPORT, "min_resvport" }, - { CTL_MAX_RESVPORT, "max_resvport" }, - {} -}; - -static struct trans_ctl_table trans_pm_table[] = { - { 1 /* CTL_PM_SUSPEND */, "suspend" }, - { 2 /* CTL_PM_CMODE */, "cmode" }, - { 3 /* CTL_PM_P0 */, "p0" }, - { 4 /* CTL_PM_CM */, "cm" }, - {} -}; - -static struct trans_ctl_table trans_frv_table[] = { - { 1, "cache-mode" }, - { 2, "pin-cxnr" }, - {} -}; - -static struct trans_ctl_table trans_root_table[] = { - { CTL_KERN, "kernel", trans_kern_table }, - { CTL_VM, "vm", trans_vm_table }, - { CTL_NET, "net", trans_net_table }, - /* CTL_PROC not used */ - { CTL_FS, "fs", trans_fs_table }, - { CTL_DEBUG, "debug", trans_debug_table }, - { CTL_DEV, "dev", trans_dev_table }, - { CTL_BUS, "bus", trans_bus_table }, - { CTL_ABI, "abi" }, - /* CTL_CPU not used */ - { CTL_ARLAN, "arlan", trans_arlan_table }, - { CTL_APPLDATA, "appldata", trans_appldata_table }, - { CTL_S390DBF, "s390dbf", trans_s390dbf_table }, - { CTL_SUNRPC, "sunrpc", trans_sunrpc_table }, - { CTL_PM, "pm", trans_pm_table }, - { CTL_FRV, "frv", trans_frv_table }, - {} -}; - - - - -static int sysctl_depth(struct ctl_table *table) -{ - struct ctl_table *tmp; - int depth; - - depth = 0; - for (tmp = table; tmp->parent; tmp = tmp->parent) - depth++; - - return depth; -} - -static struct ctl_table *sysctl_parent(struct ctl_table *table, int n) -{ - int i; - - for (i = 0; table && i < n; i++) - table = table->parent; - - return table; -} - -static struct trans_ctl_table *sysctl_binary_lookup(struct ctl_table *table) -{ - struct ctl_table *test; - struct trans_ctl_table *ref; - int depth, cur_depth; - - depth = sysctl_depth(table); - - cur_depth = depth; - ref = trans_root_table; -repeat: - test = sysctl_parent(table, cur_depth); - for (; ref->ctl_name || ref->procname || ref->child; ref++) { - int match = 0; - - if (cur_depth && !ref->child) - continue; - - if (test->procname && ref->procname && - (strcmp(test->procname, ref->procname) == 0)) - match++; - - if (test->ctl_name && ref->ctl_name && - (test->ctl_name == ref->ctl_name)) - match++; - - if (!ref->ctl_name && !ref->procname) - match++; - - if (match) { - if (cur_depth != 0) { - cur_depth--; - ref = ref->child; - goto repeat; - } - goto out; - } - } - ref = NULL; -out: - return ref; -} - -static void sysctl_print_path(struct ctl_table *table) -{ - struct ctl_table *tmp; - int depth, i; - depth = sysctl_depth(table); - if (table->procname) { - for (i = depth; i >= 0; i--) { - tmp = sysctl_parent(table, i); - printk("/%s", tmp->procname?tmp->procname:""); - } - } - printk(" "); - if (table->ctl_name) { - for (i = depth; i >= 0; i--) { - tmp = sysctl_parent(table, i); - printk(".%d", tmp->ctl_name); - } - } -} - -static void sysctl_repair_table(struct ctl_table *table) -{ - /* Don't complain about the classic default - * sysctl strategy routine. Maybe later we - * can get the tables fixed and complain about - * this. - */ - if (table->ctl_name && table->procname && - (table->proc_handler == proc_dointvec) && - (!table->strategy)) { - table->strategy = sysctl_data; - } -} - -static struct ctl_table *sysctl_check_lookup(struct ctl_table *table) -{ - struct ctl_table_header *head; - struct ctl_table *ref, *test; - int depth, cur_depth; - - depth = sysctl_depth(table); - - for (head = sysctl_head_next(NULL); head; - head = sysctl_head_next(head)) { - cur_depth = depth; - ref = head->ctl_table; -repeat: - test = sysctl_parent(table, cur_depth); - for (; ref->ctl_name || ref->procname; ref++) { - int match = 0; - if (cur_depth && !ref->child) - continue; - - if (test->procname && ref->procname && - (strcmp(test->procname, ref->procname) == 0)) - match++; - - if (test->ctl_name && ref->ctl_name && - (test->ctl_name == ref->ctl_name)) - match++; - - if (match) { - if (cur_depth != 0) { - cur_depth--; - ref = ref->child; - goto repeat; - } - goto out; - } - } - } - ref = NULL; -out: - sysctl_head_finish(head); - return ref; -} - -static void set_fail(const char **fail, struct ctl_table *table, const char *str) -{ - if (*fail) { - printk(KERN_ERR "sysctl table check failed: "); - sysctl_print_path(table); - printk(" %s\n", *fail); - } - *fail = str; -} - -static int sysctl_check_dir(struct ctl_table *table) -{ - struct ctl_table *ref; - int error; - - error = 0; - ref = sysctl_check_lookup(table); - if (ref) { - int match = 0; - if ((!table->procname && !ref->procname) || - (table->procname && ref->procname && - (strcmp(table->procname, ref->procname) == 0))) - match++; - - if ((!table->ctl_name && !ref->ctl_name) || - (table->ctl_name && ref->ctl_name && - (table->ctl_name == ref->ctl_name))) - match++; - - if (match != 2) { - printk(KERN_ERR "%s: failed: ", __func__); - sysctl_print_path(table); - printk(" ref: "); - sysctl_print_path(ref); - printk("\n"); - error = -EINVAL; - } - } - return error; -} - -static void sysctl_check_leaf(struct ctl_table *table, const char **fail) -{ - struct ctl_table *ref; - - ref = sysctl_check_lookup(table); - if (ref && (ref != table)) - set_fail(fail, table, "Sysctl already exists"); -} - -static void sysctl_check_bin_path(struct ctl_table *table, const char **fail) -{ - struct trans_ctl_table *ref; - - ref = sysctl_binary_lookup(table); - if (table->ctl_name && !ref) - set_fail(fail, table, "Unknown sysctl binary path"); - if (ref) { - if (ref->procname && - (!table->procname || - (strcmp(table->procname, ref->procname) != 0))) - set_fail(fail, table, "procname does not match binary path procname"); - - if (ref->ctl_name && table->ctl_name && - (table->ctl_name != ref->ctl_name)) - set_fail(fail, table, "ctl_name does not match binary path ctl_name"); - } -} - -int sysctl_check_table(struct ctl_table *table) -{ - int error = 0; - for (; table->ctl_name || table->procname; table++) { - const char *fail = NULL; - - sysctl_repair_table(table); - if (table->parent) { - if (table->procname && !table->parent->procname) - set_fail(&fail, table, "Parent without procname"); - if (table->ctl_name && !table->parent->ctl_name) - set_fail(&fail, table, "Parent without ctl_name"); - } - if (!table->procname) - set_fail(&fail, table, "No procname"); - if (table->child) { - if (table->data) - set_fail(&fail, table, "Directory with data?"); - if (table->maxlen) - set_fail(&fail, table, "Directory with maxlen?"); - if ((table->mode & (S_IRUGO|S_IXUGO)) != table->mode) - set_fail(&fail, table, "Writable sysctl directory"); - if (table->proc_handler) - set_fail(&fail, table, "Directory with proc_handler"); - if (table->strategy) - set_fail(&fail, table, "Directory with strategy"); - if (table->extra1) - set_fail(&fail, table, "Directory with extra1"); - if (table->extra2) - set_fail(&fail, table, "Directory with extra2"); - if (sysctl_check_dir(table)) - set_fail(&fail, table, "Inconsistent directory names"); - } else { - if ((table->strategy == sysctl_data) || - (table->strategy == sysctl_string) || - (table->strategy == sysctl_intvec) || - (table->strategy == sysctl_jiffies) || - (table->strategy == sysctl_ms_jiffies) || - (table->proc_handler == proc_dostring) || - (table->proc_handler == proc_dointvec) || -#ifdef CONFIG_SECURITY_CAPABILITIES - (table->proc_handler == proc_dointvec_bset) || -#endif /* def CONFIG_SECURITY_CAPABILITIES */ - (table->proc_handler == proc_dointvec_minmax) || - (table->proc_handler == proc_dointvec_jiffies) || - (table->proc_handler == proc_dointvec_userhz_jiffies) || - (table->proc_handler == proc_dointvec_ms_jiffies) || - (table->proc_handler == proc_doulongvec_minmax) || - (table->proc_handler == proc_doulongvec_ms_jiffies_minmax)) { - if (!table->data) - set_fail(&fail, table, "No data"); - if (!table->maxlen) - set_fail(&fail, table, "No maxlen"); - } - if ((table->proc_handler == proc_doulongvec_minmax) || - (table->proc_handler == proc_doulongvec_ms_jiffies_minmax)) { - if (table->maxlen > sizeof (unsigned long)) { - if (!table->extra1) - set_fail(&fail, table, "No min"); - if (!table->extra2) - set_fail(&fail, table, "No max"); - } - } -#ifdef CONFIG_SYSCTL_SYSCALL - if (table->ctl_name && !table->strategy) - set_fail(&fail, table, "Missing strategy"); -#endif -#if 0 - if (!table->ctl_name && table->strategy) - set_fail(&fail, table, "Strategy without ctl_name"); -#endif -#ifdef CONFIG_PROC_FS - if (table->procname && !table->proc_handler) - set_fail(&fail, table, "No proc_handler"); -#endif -#if 0 - if (!table->procname && table->proc_handler) - set_fail(&fail, table, "proc_handler without procname"); -#endif - sysctl_check_leaf(table, &fail); - } - sysctl_check_bin_path(table, &fail); - if (fail) { - set_fail(&fail, table, NULL); - error = -EINVAL; - } - if (table->child) - error |= sysctl_check_table(table->child); - } - return error; -} diff --git a/trunk/kernel/taskstats.c b/trunk/kernel/taskstats.c index 9f360f68aad6..7d4d7f9c1bb2 100644 --- a/trunk/kernel/taskstats.c +++ b/trunk/kernel/taskstats.c @@ -22,10 +22,6 @@ #include #include #include -#include -#include -#include -#include #include #include @@ -53,11 +49,6 @@ __read_mostly = { [TASKSTATS_CMD_ATTR_REGISTER_CPUMASK] = { .type = NLA_STRING }, [TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK] = { .type = NLA_STRING },}; -static struct nla_policy -cgroupstats_cmd_get_policy[CGROUPSTATS_CMD_ATTR_MAX+1] __read_mostly = { - [CGROUPSTATS_CMD_ATTR_FD] = { .type = NLA_U32 }, -}; - struct listener { struct list_head list; pid_t pid; @@ -381,51 +372,6 @@ static struct taskstats *mk_reply(struct sk_buff *skb, int type, u32 pid) return NULL; } -static int cgroupstats_user_cmd(struct sk_buff *skb, struct genl_info *info) -{ - int rc = 0; - struct sk_buff *rep_skb; - struct cgroupstats *stats; - struct nlattr *na; - size_t size; - u32 fd; - struct file *file; - int fput_needed; - - na = info->attrs[CGROUPSTATS_CMD_ATTR_FD]; - if (!na) - return -EINVAL; - - fd = nla_get_u32(info->attrs[CGROUPSTATS_CMD_ATTR_FD]); - file = fget_light(fd, &fput_needed); - if (file) { - size = nla_total_size(sizeof(struct cgroupstats)); - - rc = prepare_reply(info, CGROUPSTATS_CMD_NEW, &rep_skb, - size); - if (rc < 0) - goto err; - - na = nla_reserve(rep_skb, CGROUPSTATS_TYPE_CGROUP_STATS, - sizeof(struct cgroupstats)); - stats = nla_data(na); - memset(stats, 0, sizeof(*stats)); - - rc = cgroupstats_build(stats, file->f_dentry); - if (rc < 0) - goto err; - - fput_light(file, fput_needed); - return send_reply(rep_skb, info->snd_pid); - } - -err: - if (file) - fput_light(file, fput_needed); - nlmsg_free(rep_skb); - return rc; -} - static int taskstats_user_cmd(struct sk_buff *skb, struct genl_info *info) { int rc = 0; @@ -576,12 +522,6 @@ static struct genl_ops taskstats_ops = { .policy = taskstats_cmd_get_policy, }; -static struct genl_ops cgroupstats_ops = { - .cmd = CGROUPSTATS_CMD_GET, - .doit = cgroupstats_user_cmd, - .policy = cgroupstats_cmd_get_policy, -}; - /* Needed early in initialization */ void __init taskstats_init_early(void) { @@ -606,15 +546,8 @@ static int __init taskstats_init(void) if (rc < 0) goto err; - rc = genl_register_ops(&family, &cgroupstats_ops); - if (rc < 0) - goto err_cgroup_ops; - family_registered = 1; - printk("registered taskstats version %d\n", TASKSTATS_GENL_VERSION); return 0; -err_cgroup_ops: - genl_unregister_ops(&family, &taskstats_ops); err: genl_unregister_family(&family); return rc; diff --git a/trunk/kernel/time.c b/trunk/kernel/time.c index 09d3c45c4da7..2d5b6a682138 100644 --- a/trunk/kernel/time.c +++ b/trunk/kernel/time.c @@ -9,9 +9,9 @@ */ /* * Modification history kernel/time.c - * + * * 1993-09-02 Philip Gladstone - * Created file with time related functions from sched.c and adjtimex() + * Created file with time related functions from sched.c and adjtimex() * 1993-10-08 Torsten Duwe * adjtime interface update and CMOS clock write code * 1995-08-13 Torsten Duwe @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include @@ -39,7 +38,7 @@ #include #include -/* +/* * The timezone where the local system is located. Used as a default by some * programs who obtain this value by using gettimeofday. */ @@ -72,7 +71,7 @@ asmlinkage long sys_time(time_t __user * tloc) * why not move it into the appropriate arch directory (for those * architectures that need it). */ - + asmlinkage long sys_stime(time_t __user *tptr) { struct timespec tv; @@ -111,10 +110,10 @@ asmlinkage long sys_gettimeofday(struct timeval __user *tv, struct timezone __us /* * Adjust the time obtained from the CMOS to be UTC time instead of * local time. - * + * * This is ugly, but preferable to the alternatives. Otherwise we * would either need to write a program to do it in /etc/rc (and risk - * confusion if the program gets run more than once; it would also be + * confusion if the program gets run more than once; it would also be * hard to make the program warp the clock precisely n hours) or * compile in the timezone information into the kernel. Bad, bad.... * @@ -159,7 +158,6 @@ int do_sys_settimeofday(struct timespec *tv, struct timezone *tz) if (tz) { /* SMP safe, global irq locking makes it work. */ sys_tz = *tz; - update_vsyscall_tz(); if (firsttime) { firsttime = 0; if (!tv) diff --git a/trunk/kernel/time/clocksource.c b/trunk/kernel/time/clocksource.c index c8a9d13874df..51b6a6a6158c 100644 --- a/trunk/kernel/time/clocksource.c +++ b/trunk/kernel/time/clocksource.c @@ -207,12 +207,15 @@ static inline void clocksource_resume_watchdog(void) { } */ void clocksource_resume(void) { - struct clocksource *cs; + struct list_head *tmp; unsigned long flags; spin_lock_irqsave(&clocksource_lock, flags); - list_for_each_entry(cs, &clocksource_list, list) { + list_for_each(tmp, &clocksource_list) { + struct clocksource *cs; + + cs = list_entry(tmp, struct clocksource, list); if (cs->resume) cs->resume(); } @@ -366,6 +369,7 @@ static ssize_t sysfs_override_clocksource(struct sys_device *dev, const char *buf, size_t count) { struct clocksource *ovr = NULL; + struct list_head *tmp; size_t ret = count; int len; @@ -385,11 +389,12 @@ static ssize_t sysfs_override_clocksource(struct sys_device *dev, len = strlen(override_name); if (len) { - struct clocksource *cs; - ovr = clocksource_override; /* try to select it: */ - list_for_each_entry(cs, &clocksource_list, list) { + list_for_each(tmp, &clocksource_list) { + struct clocksource *cs; + + cs = list_entry(tmp, struct clocksource, list); if (strlen(cs->name) == len && !strcmp(cs->name, override_name)) ovr = cs; @@ -417,11 +422,14 @@ static ssize_t sysfs_override_clocksource(struct sys_device *dev, static ssize_t sysfs_show_available_clocksources(struct sys_device *dev, char *buf) { - struct clocksource *src; + struct list_head *tmp; char *curr = buf; spin_lock_irq(&clocksource_lock); - list_for_each_entry(src, &clocksource_list, list) { + list_for_each(tmp, &clocksource_list) { + struct clocksource *src; + + src = list_entry(tmp, struct clocksource, list); curr += sprintf(curr, "%s ", src->name); } spin_unlock_irq(&clocksource_lock); diff --git a/trunk/kernel/time/tick-sched.c b/trunk/kernel/time/tick-sched.c index 10a1347597fd..ce89ffb474d0 100644 --- a/trunk/kernel/time/tick-sched.c +++ b/trunk/kernel/time/tick-sched.c @@ -153,7 +153,6 @@ void tick_nohz_stop_sched_tick(void) unsigned long seq, last_jiffies, next_jiffies, delta_jiffies, flags; struct tick_sched *ts; ktime_t last_update, expires, now, delta; - struct clock_event_device *dev = __get_cpu_var(tick_cpu_device).evtdev; int cpu; local_irq_save(flags); @@ -303,25 +302,10 @@ void tick_nohz_stop_sched_tick(void) out: ts->next_jiffies = next_jiffies; ts->last_jiffies = last_jiffies; - ts->sleep_length = ktime_sub(dev->next_event, now); end: local_irq_restore(flags); } -/** - * tick_nohz_get_sleep_length - return the length of the current sleep - * - * Called from power state control code with interrupts disabled - */ -ktime_t tick_nohz_get_sleep_length(void) -{ - struct tick_sched *ts = &__get_cpu_var(tick_cpu_sched); - - return ts->sleep_length; -} - -EXPORT_SYMBOL_GPL(tick_nohz_get_sleep_length); - /** * nohz_restart_sched_tick - restart the idle tick from the idle task * diff --git a/trunk/kernel/timer.c b/trunk/kernel/timer.c index fb4e67d5dd60..6ce1952eea7d 100644 --- a/trunk/kernel/timer.c +++ b/trunk/kernel/timer.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include @@ -818,7 +817,7 @@ unsigned long next_timer_interrupt(void) #endif /* - * Called from the timer interrupt handler to charge one tick to the current + * Called from the timer interrupt handler to charge one tick to the current * process. user_tick is 1 if the tick is user time, 0 for system. */ void update_process_times(int user_tick) @@ -827,13 +826,10 @@ void update_process_times(int user_tick) int cpu = smp_processor_id(); /* Note: this timer irq context must be accounted for as well. */ - if (user_tick) { + if (user_tick) account_user_time(p, jiffies_to_cputime(1)); - account_user_time_scaled(p, jiffies_to_cputime(1)); - } else { + else account_system_time(p, HARDIRQ_OFFSET, jiffies_to_cputime(1)); - account_system_time_scaled(p, jiffies_to_cputime(1)); - } run_local_timers(); if (rcu_pending(cpu)) rcu_check_callbacks(cpu, user_tick); @@ -957,7 +953,7 @@ asmlinkage unsigned long sys_alarm(unsigned int seconds) */ asmlinkage long sys_getpid(void) { - return task_tgid_vnr(current); + return current->tgid; } /* @@ -971,7 +967,7 @@ asmlinkage long sys_getppid(void) int pid; rcu_read_lock(); - pid = task_ppid_nr_ns(current, current->nsproxy->pid_ns); + pid = rcu_dereference(current->real_parent)->tgid; rcu_read_unlock(); return pid; @@ -1103,7 +1099,7 @@ EXPORT_SYMBOL(schedule_timeout_uninterruptible); /* Thread ID - the internal kernel "pid" */ asmlinkage long sys_gettid(void) { - return task_pid_vnr(current); + return current->pid; } /** diff --git a/trunk/kernel/tsacct.c b/trunk/kernel/tsacct.c index 4ab1b584961b..c122131a122f 100644 --- a/trunk/kernel/tsacct.c +++ b/trunk/kernel/tsacct.c @@ -62,10 +62,6 @@ void bacct_add_tsk(struct taskstats *stats, struct task_struct *tsk) rcu_read_unlock(); stats->ac_utime = cputime_to_msecs(tsk->utime) * USEC_PER_MSEC; stats->ac_stime = cputime_to_msecs(tsk->stime) * USEC_PER_MSEC; - stats->ac_utimescaled = - cputime_to_msecs(tsk->utimescaled) * USEC_PER_MSEC; - stats->ac_stimescaled = - cputime_to_msecs(tsk->stimescaled) * USEC_PER_MSEC; stats->ac_minflt = tsk->min_flt; stats->ac_majflt = tsk->maj_flt; diff --git a/trunk/kernel/workqueue.c b/trunk/kernel/workqueue.c index 52d5e7c9a8e6..e080d1d744cc 100644 --- a/trunk/kernel/workqueue.c +++ b/trunk/kernel/workqueue.c @@ -32,7 +32,6 @@ #include #include #include -#include /* * The per-CPU workqueue (if single thread, we always use the first @@ -62,9 +61,6 @@ struct workqueue_struct { const char *name; int singlethread; int freezeable; /* Freeze threads during suspend */ -#ifdef CONFIG_LOCKDEP - struct lockdep_map lockdep_map; -#endif }; /* All the per-cpu workqueues on the system, for hotplug cpu to add/remove @@ -254,17 +250,6 @@ static void run_workqueue(struct cpu_workqueue_struct *cwq) struct work_struct *work = list_entry(cwq->worklist.next, struct work_struct, entry); work_func_t f = work->func; -#ifdef CONFIG_LOCKDEP - /* - * It is permissible to free the struct work_struct - * from inside the function that is called from it, - * this we need to take into account for lockdep too. - * To avoid bogus "held lock freed" warnings as well - * as problems when looking into work->lockdep_map, - * make a copy and use that here. - */ - struct lockdep_map lockdep_map = work->lockdep_map; -#endif cwq->current_work = work; list_del_init(cwq->worklist.next); @@ -272,17 +257,13 @@ static void run_workqueue(struct cpu_workqueue_struct *cwq) BUG_ON(get_wq_data(work) != cwq); work_clear_pending(work); - lock_acquire(&cwq->wq->lockdep_map, 0, 0, 0, 2, _THIS_IP_); - lock_acquire(&lockdep_map, 0, 0, 0, 2, _THIS_IP_); f(work); - lock_release(&lockdep_map, 1, _THIS_IP_); - lock_release(&cwq->wq->lockdep_map, 1, _THIS_IP_); if (unlikely(in_atomic() || lockdep_depth(current) > 0)) { printk(KERN_ERR "BUG: workqueue leaked lock or atomic: " "%s/0x%08x/%d\n", current->comm, preempt_count(), - task_pid_nr(current)); + current->pid); printk(KERN_ERR " last function: "); print_symbol("%s\n", (unsigned long)f); debug_show_held_locks(current); @@ -395,8 +376,6 @@ void fastcall flush_workqueue(struct workqueue_struct *wq) int cpu; might_sleep(); - lock_acquire(&wq->lockdep_map, 0, 0, 0, 2, _THIS_IP_); - lock_release(&wq->lockdep_map, 1, _THIS_IP_); for_each_cpu_mask(cpu, *cpu_map) flush_cpu_workqueue(per_cpu_ptr(wq->cpu_wq, cpu)); } @@ -467,9 +446,6 @@ static void wait_on_work(struct work_struct *work) might_sleep(); - lock_acquire(&work->lockdep_map, 0, 0, 0, 2, _THIS_IP_); - lock_release(&work->lockdep_map, 1, _THIS_IP_); - cwq = get_wq_data(work); if (!cwq) return; @@ -719,10 +695,8 @@ static void start_workqueue_thread(struct cpu_workqueue_struct *cwq, int cpu) } } -struct workqueue_struct *__create_workqueue_key(const char *name, - int singlethread, - int freezeable, - struct lock_class_key *key) +struct workqueue_struct *__create_workqueue(const char *name, + int singlethread, int freezeable) { struct workqueue_struct *wq; struct cpu_workqueue_struct *cwq; @@ -739,7 +713,6 @@ struct workqueue_struct *__create_workqueue_key(const char *name, } wq->name = name; - lockdep_init_map(&wq->lockdep_map, name, key, 0); wq->singlethread = singlethread; wq->freezeable = freezeable; INIT_LIST_HEAD(&wq->list); @@ -768,7 +741,7 @@ struct workqueue_struct *__create_workqueue_key(const char *name, } return wq; } -EXPORT_SYMBOL_GPL(__create_workqueue_key); +EXPORT_SYMBOL_GPL(__create_workqueue); static void cleanup_workqueue_thread(struct cpu_workqueue_struct *cwq, int cpu) { @@ -779,9 +752,6 @@ static void cleanup_workqueue_thread(struct cpu_workqueue_struct *cwq, int cpu) if (cwq->thread == NULL) return; - lock_acquire(&cwq->wq->lockdep_map, 0, 0, 0, 2, _THIS_IP_); - lock_release(&cwq->wq->lockdep_map, 1, _THIS_IP_); - flush_cpu_workqueue(cwq); /* * If the caller is CPU_DEAD and cwq->worklist was not empty, diff --git a/trunk/lib/Kconfig.debug b/trunk/lib/Kconfig.debug index c567f219191d..7d16e6433302 100644 --- a/trunk/lib/Kconfig.debug +++ b/trunk/lib/Kconfig.debug @@ -498,5 +498,3 @@ config FAULT_INJECTION_STACKTRACE_FILTER select FRAME_POINTER help Provide stacktrace filter for fault-injection capabilities - -source "samples/Kconfig" diff --git a/trunk/lib/Makefile b/trunk/lib/Makefile index 3a0983b77412..c5f215d509d3 100644 --- a/trunk/lib/Makefile +++ b/trunk/lib/Makefile @@ -6,7 +6,7 @@ lib-y := ctype.o string.o vsprintf.o cmdline.o \ rbtree.o radix-tree.o dump_stack.o \ idr.o int_sqrt.o bitmap.o extable.o prio_tree.o \ sha1.o irq_regs.o reciprocal_div.o argv_split.o \ - proportions.o prio_heap.o + proportions.o lib-$(CONFIG_MMU) += ioremap.o lib-$(CONFIG_SMP) += cpumask.o diff --git a/trunk/lib/crc32.c b/trunk/lib/crc32.c index d2c2f257bedd..bfc33314c720 100644 --- a/trunk/lib/crc32.c +++ b/trunk/lib/crc32.c @@ -49,7 +49,7 @@ MODULE_LICENSE("GPL"); * @p: pointer to buffer over which CRC is run * @len: length of buffer @p */ -u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len); +u32 __attribute_pure__ crc32_le(u32 crc, unsigned char const *p, size_t len); #if CRC_LE_BITS == 1 /* @@ -57,7 +57,7 @@ u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len); * simplified by inlining the table in ?: form. */ -u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len) +u32 __attribute_pure__ crc32_le(u32 crc, unsigned char const *p, size_t len) { int i; while (len--) { @@ -69,7 +69,7 @@ u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len) } #else /* Table-based approach */ -u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len) +u32 __attribute_pure__ crc32_le(u32 crc, unsigned char const *p, size_t len) { # if CRC_LE_BITS == 8 const u32 *b =(u32 *)p; @@ -145,7 +145,7 @@ u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len) * @p: pointer to buffer over which CRC is run * @len: length of buffer @p */ -u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len); +u32 __attribute_pure__ crc32_be(u32 crc, unsigned char const *p, size_t len); #if CRC_BE_BITS == 1 /* @@ -153,7 +153,7 @@ u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len); * simplified by inlining the table in ?: form. */ -u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len) +u32 __attribute_pure__ crc32_be(u32 crc, unsigned char const *p, size_t len) { int i; while (len--) { @@ -167,7 +167,7 @@ u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len) } #else /* Table-based approach */ -u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len) +u32 __attribute_pure__ crc32_be(u32 crc, unsigned char const *p, size_t len) { # if CRC_BE_BITS == 8 const u32 *b =(u32 *)p; diff --git a/trunk/lib/hweight.c b/trunk/lib/hweight.c index 389424ecb129..360556a7803d 100644 --- a/trunk/lib/hweight.c +++ b/trunk/lib/hweight.c @@ -1,6 +1,6 @@ #include -#include #include +#include /** * hweightN - returns the hamming weight of a N-bit word diff --git a/trunk/lib/libcrc32c.c b/trunk/lib/libcrc32c.c index 802f11f0bf5b..60f46803af3f 100644 --- a/trunk/lib/libcrc32c.c +++ b/trunk/lib/libcrc32c.c @@ -66,7 +66,7 @@ EXPORT_SYMBOL(crc32c_le); * loop below with crc32 and vary the POLY if we don't find value in terms * of space and maintainability in keeping the two modules separate. */ -u32 __pure +u32 __attribute_pure__ crc32c_le(u32 crc, unsigned char const *p, size_t len) { int i; @@ -160,7 +160,7 @@ static const u32 crc32c_table[256] = { * crc using table. */ -u32 __pure +u32 __attribute_pure__ crc32c_le(u32 seed, unsigned char const *data, size_t length) { u32 crc = __cpu_to_le32(seed); @@ -177,7 +177,7 @@ crc32c_le(u32 seed, unsigned char const *data, size_t length) EXPORT_SYMBOL(crc32c_be); #if CRC_BE_BITS == 1 -u32 __pure +u32 __attribute_pure__ crc32c_be(u32 crc, unsigned char const *p, size_t len) { int i; diff --git a/trunk/lib/percpu_counter.c b/trunk/lib/percpu_counter.c index 393a0e915c23..9659eabffc31 100644 --- a/trunk/lib/percpu_counter.c +++ b/trunk/lib/percpu_counter.c @@ -124,13 +124,12 @@ static int __cpuinit percpu_counter_hotcpu_callback(struct notifier_block *nb, mutex_lock(&percpu_counters_lock); list_for_each_entry(fbc, &percpu_counters, list) { s32 *pcount; - unsigned long flags; - spin_lock_irqsave(&fbc->lock, flags); + spin_lock(&fbc->lock); pcount = per_cpu_ptr(fbc->counters, cpu); fbc->count += *pcount; *pcount = 0; - spin_unlock_irqrestore(&fbc->lock, flags); + spin_unlock(&fbc->lock); } mutex_unlock(&percpu_counters_lock); return NOTIFY_OK; diff --git a/trunk/lib/prio_heap.c b/trunk/lib/prio_heap.c deleted file mode 100644 index 471944a54e23..000000000000 --- a/trunk/lib/prio_heap.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Simple insertion-only static-sized priority heap containing - * pointers, based on CLR, chapter 7 - */ - -#include -#include - -int heap_init(struct ptr_heap *heap, size_t size, gfp_t gfp_mask, - int (*gt)(void *, void *)) -{ - heap->ptrs = kmalloc(size, gfp_mask); - if (!heap->ptrs) - return -ENOMEM; - heap->size = 0; - heap->max = size / sizeof(void *); - heap->gt = gt; - return 0; -} - -void heap_free(struct ptr_heap *heap) -{ - kfree(heap->ptrs); -} - -void *heap_insert(struct ptr_heap *heap, void *p) -{ - void *res; - void **ptrs = heap->ptrs; - int pos; - - if (heap->size < heap->max) { - /* Heap insertion */ - int pos = heap->size++; - while (pos > 0 && heap->gt(p, ptrs[(pos-1)/2])) { - ptrs[pos] = ptrs[(pos-1)/2]; - pos = (pos-1)/2; - } - ptrs[pos] = p; - return NULL; - } - - /* The heap is full, so something will have to be dropped */ - - /* If the new pointer is greater than the current max, drop it */ - if (heap->gt(p, ptrs[0])) - return p; - - /* Replace the current max and heapify */ - res = ptrs[0]; - ptrs[0] = p; - pos = 0; - - while (1) { - int left = 2 * pos + 1; - int right = 2 * pos + 2; - int largest = pos; - if (left < heap->size && heap->gt(ptrs[left], p)) - largest = left; - if (right < heap->size && heap->gt(ptrs[right], ptrs[largest])) - largest = right; - if (largest == pos) - break; - /* Push p down the heap one level and bump one up */ - ptrs[pos] = ptrs[largest]; - ptrs[largest] = p; - pos = largest; - } - return res; -} diff --git a/trunk/lib/spinlock_debug.c b/trunk/lib/spinlock_debug.c index 9c4b0256490b..479fd462eaa9 100644 --- a/trunk/lib/spinlock_debug.c +++ b/trunk/lib/spinlock_debug.c @@ -60,12 +60,12 @@ static void spin_bug(spinlock_t *lock, const char *msg) owner = lock->owner; printk(KERN_EMERG "BUG: spinlock %s on CPU#%d, %s/%d\n", msg, raw_smp_processor_id(), - current->comm, task_pid_nr(current)); + current->comm, current->pid); printk(KERN_EMERG " lock: %p, .magic: %08x, .owner: %s/%d, " ".owner_cpu: %d\n", lock, lock->magic, owner ? owner->comm : "", - owner ? task_pid_nr(owner) : -1, + owner ? owner->pid : -1, lock->owner_cpu); dump_stack(); } @@ -116,7 +116,7 @@ static void __spin_lock_debug(spinlock_t *lock) printk(KERN_EMERG "BUG: spinlock lockup on CPU#%d, " "%s/%d, %p\n", raw_smp_processor_id(), current->comm, - task_pid_nr(current), lock); + current->pid, lock); dump_stack(); #ifdef CONFIG_SMP trigger_all_cpu_backtrace(); @@ -161,7 +161,7 @@ static void rwlock_bug(rwlock_t *lock, const char *msg) printk(KERN_EMERG "BUG: rwlock %s on CPU#%d, %s/%d, %p\n", msg, raw_smp_processor_id(), current->comm, - task_pid_nr(current), lock); + current->pid, lock); dump_stack(); } diff --git a/trunk/mm/filemap.c b/trunk/mm/filemap.c index 5209e47b7fe3..79f24a969cb4 100644 --- a/trunk/mm/filemap.c +++ b/trunk/mm/filemap.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -841,7 +840,7 @@ static void shrink_readahead_size_eio(struct file *filp, /** * do_generic_mapping_read - generic file read routine * @mapping: address_space to be read - * @ra: file's readahead state + * @_ra: file's readahead state * @filp: the file to read * @ppos: current file position * @desc: read_descriptor diff --git a/trunk/mm/hugetlb.c b/trunk/mm/hugetlb.c index 034617f8cdb2..ae2959bb59cb 100644 --- a/trunk/mm/hugetlb.c +++ b/trunk/mm/hugetlb.c @@ -1020,7 +1020,7 @@ static long region_chg(struct list_head *head, long f, long t) * size such that we can guarentee to record the reservation. */ if (&rg->link == head || t < rg->from) { nrg = kmalloc(sizeof(*nrg), GFP_KERNEL); - if (!nrg) + if (nrg == 0) return -ENOMEM; nrg->from = f; nrg->to = f; diff --git a/trunk/mm/memory.c b/trunk/mm/memory.c index 142683df8755..bd16dcaeefb8 100644 --- a/trunk/mm/memory.c +++ b/trunk/mm/memory.c @@ -259,6 +259,9 @@ void free_pgd_range(struct mmu_gather **tlb, continue; free_pud_range(*tlb, pgd, addr, next, floor, ceiling); } while (pgd++, addr = next, addr != end); + + if (!(*tlb)->fullmm) + flush_tlb_pgtables((*tlb)->mm, start, end); } void free_pgtables(struct mmu_gather **tlb, struct vm_area_struct *vma, diff --git a/trunk/mm/mempolicy.c b/trunk/mm/mempolicy.c index c1592a94582f..568152ae6caf 100644 --- a/trunk/mm/mempolicy.c +++ b/trunk/mm/mempolicy.c @@ -78,7 +78,6 @@ #include #include #include -#include #include #include #include @@ -941,7 +940,7 @@ asmlinkage long sys_migrate_pages(pid_t pid, unsigned long maxnode, /* Find the mm_struct */ read_lock(&tasklist_lock); - task = pid ? find_task_by_vpid(pid) : current; + task = pid ? find_task_by_pid(pid) : current; if (!task) { read_unlock(&tasklist_lock); return -ESRCH; @@ -1389,6 +1388,7 @@ EXPORT_SYMBOL(alloc_pages_current); * keeps mempolicies cpuset relative after its cpuset moves. See * further kernel/cpuset.c update_nodemask(). */ +void *cpuset_being_rebound; /* Slow path of a mempolicy copy */ struct mempolicy *__mpol_copy(struct mempolicy *old) @@ -2019,3 +2019,4 @@ int show_numa_map(struct seq_file *m, void *v) m->version = (vma != priv->tail_vma) ? vma->vm_start : 0; return 0; } + diff --git a/trunk/mm/migrate.c b/trunk/mm/migrate.c index 4d6ee03db946..06d0877a66ef 100644 --- a/trunk/mm/migrate.c +++ b/trunk/mm/migrate.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include @@ -925,7 +924,7 @@ asmlinkage long sys_move_pages(pid_t pid, unsigned long nr_pages, /* Find the mm_struct */ read_lock(&tasklist_lock); - task = pid ? find_task_by_vpid(pid) : current; + task = pid ? find_task_by_pid(pid) : current; if (!task) { read_unlock(&tasklist_lock); return -ESRCH; diff --git a/trunk/mm/mmap.c b/trunk/mm/mmap.c index 7a30c4988231..4275e81e25ba 100644 --- a/trunk/mm/mmap.c +++ b/trunk/mm/mmap.c @@ -1048,7 +1048,8 @@ int vma_wants_writenotify(struct vm_area_struct *vma) /* The open routine did something to the protections already? */ if (pgprot_val(vma->vm_page_prot) != - pgprot_val(vm_get_page_prot(vm_flags))) + pgprot_val(protection_map[vm_flags & + (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)])) return 0; /* Specialty mapping? */ @@ -1129,7 +1130,8 @@ unsigned long mmap_region(struct file *file, unsigned long addr, vma->vm_start = addr; vma->vm_end = addr + len; vma->vm_flags = vm_flags; - vma->vm_page_prot = vm_get_page_prot(vm_flags); + vma->vm_page_prot = protection_map[vm_flags & + (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)]; vma->vm_pgoff = pgoff; if (file) { @@ -2000,7 +2002,8 @@ unsigned long do_brk(unsigned long addr, unsigned long len) vma->vm_end = addr + len; vma->vm_pgoff = pgoff; vma->vm_flags = flags; - vma->vm_page_prot = vm_get_page_prot(flags); + vma->vm_page_prot = protection_map[flags & + (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)]; vma_link(mm, vma, prev, rb_link, rb_parent); out: mm->total_vm += len >> PAGE_SHIFT; @@ -2206,7 +2209,7 @@ int install_special_mapping(struct mm_struct *mm, vma->vm_end = addr + len; vma->vm_flags = vm_flags | mm->def_flags; - vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); + vma->vm_page_prot = protection_map[vma->vm_flags & 7]; vma->vm_ops = &special_mapping_vmops; vma->vm_private_data = pages; diff --git a/trunk/mm/mprotect.c b/trunk/mm/mprotect.c index 55227845abbe..1d4d69790e59 100644 --- a/trunk/mm/mprotect.c +++ b/trunk/mm/mprotect.c @@ -192,9 +192,11 @@ mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev, * held in write mode. */ vma->vm_flags = newflags; - vma->vm_page_prot = vm_get_page_prot(newflags); + vma->vm_page_prot = protection_map[newflags & + (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)]; if (vma_wants_writenotify(vma)) { - vma->vm_page_prot = vm_get_page_prot(newflags); + vma->vm_page_prot = protection_map[newflags & + (VM_READ|VM_WRITE|VM_EXEC)]; dirty_accountable = 1; } diff --git a/trunk/mm/mremap.c b/trunk/mm/mremap.c index 08e3c7f2bd15..8ea5c2412c6e 100644 --- a/trunk/mm/mremap.c +++ b/trunk/mm/mremap.c @@ -291,7 +291,7 @@ unsigned long do_mremap(unsigned long addr, if ((addr <= new_addr) && (addr+old_len) > new_addr) goto out; - ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1); + ret = security_file_mmap(0, 0, 0, 0, new_addr, 1); if (ret) goto out; @@ -399,7 +399,7 @@ unsigned long do_mremap(unsigned long addr, goto out; } - ret = security_file_mmap(NULL, 0, 0, 0, new_addr, 1); + ret = security_file_mmap(0, 0, 0, 0, new_addr, 1); if (ret) goto out; } diff --git a/trunk/mm/oom_kill.c b/trunk/mm/oom_kill.c index 824cade07827..a64decb5b13f 100644 --- a/trunk/mm/oom_kill.c +++ b/trunk/mm/oom_kill.c @@ -212,7 +212,7 @@ static struct task_struct *select_bad_process(unsigned long *ppoints) if (!p->mm) continue; /* skip the init task */ - if (is_global_init(p)) + if (is_init(p)) continue; /* @@ -265,7 +265,7 @@ static struct task_struct *select_bad_process(unsigned long *ppoints) */ static void __oom_kill_task(struct task_struct *p, int verbose) { - if (is_global_init(p)) { + if (is_init(p)) { WARN_ON(1); printk(KERN_WARNING "tried to kill init!\n"); return; @@ -278,8 +278,7 @@ static void __oom_kill_task(struct task_struct *p, int verbose) } if (verbose) - printk(KERN_ERR "Killed process %d (%s)\n", - task_pid_nr(p), p->comm); + printk(KERN_ERR "Killed process %d (%s)\n", p->pid, p->comm); /* * We give our sacrificial lamb high priority and access to @@ -327,7 +326,7 @@ static int oom_kill_task(struct task_struct *p) * to memory reserves though, otherwise we might deplete all memory. */ do_each_thread(g, q) { - if (q->mm == mm && !same_thread_group(q, p)) + if (q->mm == mm && q->tgid != p->tgid) force_sig(SIGKILL, q); } while_each_thread(g, q); @@ -338,6 +337,7 @@ static int oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order, unsigned long points, const char *message) { struct task_struct *c; + struct list_head *tsk; if (printk_ratelimit()) { printk(KERN_WARNING "%s invoked oom-killer: " @@ -357,10 +357,11 @@ static int oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order, } printk(KERN_ERR "%s: kill process %d (%s) score %li or a child\n", - message, task_pid_nr(p), p->comm, points); + message, p->pid, p->comm, points); /* Try to kill a child first */ - list_for_each_entry(c, &p->children, sibling) { + list_for_each(tsk, &p->children) { + c = list_entry(tsk, struct task_struct, sibling); if (c->mm == p->mm) continue; if (!oom_kill_task(c)) diff --git a/trunk/mm/slab.c b/trunk/mm/slab.c index 54eb555c4ef8..3ce9bc024d67 100644 --- a/trunk/mm/slab.c +++ b/trunk/mm/slab.c @@ -1156,187 +1156,105 @@ static inline int cache_free_alien(struct kmem_cache *cachep, void *objp) } #endif -static void __cpuinit cpuup_canceled(long cpu) -{ - struct kmem_cache *cachep; - struct kmem_list3 *l3 = NULL; - int node = cpu_to_node(cpu); - - list_for_each_entry(cachep, &cache_chain, next) { - struct array_cache *nc; - struct array_cache *shared; - struct array_cache **alien; - cpumask_t mask; - - mask = node_to_cpumask(node); - /* cpu is dead; no one can alloc from it. */ - nc = cachep->array[cpu]; - cachep->array[cpu] = NULL; - l3 = cachep->nodelists[node]; - - if (!l3) - goto free_array_cache; - - spin_lock_irq(&l3->list_lock); - - /* Free limit for this kmem_list3 */ - l3->free_limit -= cachep->batchcount; - if (nc) - free_block(cachep, nc->entry, nc->avail, node); - - if (!cpus_empty(mask)) { - spin_unlock_irq(&l3->list_lock); - goto free_array_cache; - } - - shared = l3->shared; - if (shared) { - free_block(cachep, shared->entry, - shared->avail, node); - l3->shared = NULL; - } - - alien = l3->alien; - l3->alien = NULL; - - spin_unlock_irq(&l3->list_lock); - - kfree(shared); - if (alien) { - drain_alien_cache(cachep, alien); - free_alien_cache(alien); - } -free_array_cache: - kfree(nc); - } - /* - * In the previous loop, all the objects were freed to - * the respective cache's slabs, now we can go ahead and - * shrink each nodelist to its limit. - */ - list_for_each_entry(cachep, &cache_chain, next) { - l3 = cachep->nodelists[node]; - if (!l3) - continue; - drain_freelist(cachep, l3, l3->free_objects); - } -} - -static int __cpuinit cpuup_prepare(long cpu) +static int __cpuinit cpuup_callback(struct notifier_block *nfb, + unsigned long action, void *hcpu) { + long cpu = (long)hcpu; struct kmem_cache *cachep; struct kmem_list3 *l3 = NULL; int node = cpu_to_node(cpu); const int memsize = sizeof(struct kmem_list3); - /* - * We need to do this right in the beginning since - * alloc_arraycache's are going to use this list. - * kmalloc_node allows us to add the slab to the right - * kmem_list3 and not this cpu's kmem_list3 - */ - - list_for_each_entry(cachep, &cache_chain, next) { + switch (action) { + case CPU_LOCK_ACQUIRE: + mutex_lock(&cache_chain_mutex); + break; + case CPU_UP_PREPARE: + case CPU_UP_PREPARE_FROZEN: /* - * Set up the size64 kmemlist for cpu before we can - * begin anything. Make sure some other cpu on this - * node has not already allocated this + * We need to do this right in the beginning since + * alloc_arraycache's are going to use this list. + * kmalloc_node allows us to add the slab to the right + * kmem_list3 and not this cpu's kmem_list3 */ - if (!cachep->nodelists[node]) { - l3 = kmalloc_node(memsize, GFP_KERNEL, node); - if (!l3) - goto bad; - kmem_list3_init(l3); - l3->next_reap = jiffies + REAPTIMEOUT_LIST3 + - ((unsigned long)cachep) % REAPTIMEOUT_LIST3; + list_for_each_entry(cachep, &cache_chain, next) { /* - * The l3s don't come and go as CPUs come and - * go. cache_chain_mutex is sufficient - * protection here. + * Set up the size64 kmemlist for cpu before we can + * begin anything. Make sure some other cpu on this + * node has not already allocated this */ - cachep->nodelists[node] = l3; - } - - spin_lock_irq(&cachep->nodelists[node]->list_lock); - cachep->nodelists[node]->free_limit = - (1 + nr_cpus_node(node)) * - cachep->batchcount + cachep->num; - spin_unlock_irq(&cachep->nodelists[node]->list_lock); - } - - /* - * Now we can go ahead with allocating the shared arrays and - * array caches - */ - list_for_each_entry(cachep, &cache_chain, next) { - struct array_cache *nc; - struct array_cache *shared = NULL; - struct array_cache **alien = NULL; - - nc = alloc_arraycache(node, cachep->limit, - cachep->batchcount); - if (!nc) - goto bad; - if (cachep->shared) { - shared = alloc_arraycache(node, - cachep->shared * cachep->batchcount, - 0xbaadf00d); - if (!shared) { - kfree(nc); - goto bad; + if (!cachep->nodelists[node]) { + l3 = kmalloc_node(memsize, GFP_KERNEL, node); + if (!l3) + goto bad; + kmem_list3_init(l3); + l3->next_reap = jiffies + REAPTIMEOUT_LIST3 + + ((unsigned long)cachep) % REAPTIMEOUT_LIST3; + + /* + * The l3s don't come and go as CPUs come and + * go. cache_chain_mutex is sufficient + * protection here. + */ + cachep->nodelists[node] = l3; } + + spin_lock_irq(&cachep->nodelists[node]->list_lock); + cachep->nodelists[node]->free_limit = + (1 + nr_cpus_node(node)) * + cachep->batchcount + cachep->num; + spin_unlock_irq(&cachep->nodelists[node]->list_lock); } - if (use_alien_caches) { - alien = alloc_alien_cache(node, cachep->limit); - if (!alien) { - kfree(shared); - kfree(nc); + + /* + * Now we can go ahead with allocating the shared arrays and + * array caches + */ + list_for_each_entry(cachep, &cache_chain, next) { + struct array_cache *nc; + struct array_cache *shared = NULL; + struct array_cache **alien = NULL; + + nc = alloc_arraycache(node, cachep->limit, + cachep->batchcount); + if (!nc) goto bad; + if (cachep->shared) { + shared = alloc_arraycache(node, + cachep->shared * cachep->batchcount, + 0xbaadf00d); + if (!shared) + goto bad; } - } - cachep->array[cpu] = nc; - l3 = cachep->nodelists[node]; - BUG_ON(!l3); + if (use_alien_caches) { + alien = alloc_alien_cache(node, cachep->limit); + if (!alien) + goto bad; + } + cachep->array[cpu] = nc; + l3 = cachep->nodelists[node]; + BUG_ON(!l3); - spin_lock_irq(&l3->list_lock); - if (!l3->shared) { - /* - * We are serialised from CPU_DEAD or - * CPU_UP_CANCELLED by the cpucontrol lock - */ - l3->shared = shared; - shared = NULL; - } + spin_lock_irq(&l3->list_lock); + if (!l3->shared) { + /* + * We are serialised from CPU_DEAD or + * CPU_UP_CANCELLED by the cpucontrol lock + */ + l3->shared = shared; + shared = NULL; + } #ifdef CONFIG_NUMA - if (!l3->alien) { - l3->alien = alien; - alien = NULL; - } + if (!l3->alien) { + l3->alien = alien; + alien = NULL; + } #endif - spin_unlock_irq(&l3->list_lock); - kfree(shared); - free_alien_cache(alien); - } - return 0; -bad: - cpuup_canceled(cpu); - return -ENOMEM; -} - -static int __cpuinit cpuup_callback(struct notifier_block *nfb, - unsigned long action, void *hcpu) -{ - long cpu = (long)hcpu; - int err = 0; - - switch (action) { - case CPU_LOCK_ACQUIRE: - mutex_lock(&cache_chain_mutex); - break; - case CPU_UP_PREPARE: - case CPU_UP_PREPARE_FROZEN: - err = cpuup_prepare(cpu); + spin_unlock_irq(&l3->list_lock); + kfree(shared); + free_alien_cache(alien); + } break; case CPU_ONLINE: case CPU_ONLINE_FROZEN: @@ -1373,13 +1291,72 @@ static int __cpuinit cpuup_callback(struct notifier_block *nfb, #endif case CPU_UP_CANCELED: case CPU_UP_CANCELED_FROZEN: - cpuup_canceled(cpu); + list_for_each_entry(cachep, &cache_chain, next) { + struct array_cache *nc; + struct array_cache *shared; + struct array_cache **alien; + cpumask_t mask; + + mask = node_to_cpumask(node); + /* cpu is dead; no one can alloc from it. */ + nc = cachep->array[cpu]; + cachep->array[cpu] = NULL; + l3 = cachep->nodelists[node]; + + if (!l3) + goto free_array_cache; + + spin_lock_irq(&l3->list_lock); + + /* Free limit for this kmem_list3 */ + l3->free_limit -= cachep->batchcount; + if (nc) + free_block(cachep, nc->entry, nc->avail, node); + + if (!cpus_empty(mask)) { + spin_unlock_irq(&l3->list_lock); + goto free_array_cache; + } + + shared = l3->shared; + if (shared) { + free_block(cachep, shared->entry, + shared->avail, node); + l3->shared = NULL; + } + + alien = l3->alien; + l3->alien = NULL; + + spin_unlock_irq(&l3->list_lock); + + kfree(shared); + if (alien) { + drain_alien_cache(cachep, alien); + free_alien_cache(alien); + } +free_array_cache: + kfree(nc); + } + /* + * In the previous loop, all the objects were freed to + * the respective cache's slabs, now we can go ahead and + * shrink each nodelist to its limit. + */ + list_for_each_entry(cachep, &cache_chain, next) { + l3 = cachep->nodelists[node]; + if (!l3) + continue; + drain_freelist(cachep, l3, l3->free_objects); + } break; case CPU_LOCK_RELEASE: mutex_unlock(&cache_chain_mutex); break; } - return err ? NOTIFY_BAD : NOTIFY_OK; + return NOTIFY_OK; +bad: + return NOTIFY_BAD; } static struct notifier_block __cpuinitdata cpucache_notifier = { diff --git a/trunk/mm/vmscan.c b/trunk/mm/vmscan.c index cb474cc99645..e1471385d001 100644 --- a/trunk/mm/vmscan.c +++ b/trunk/mm/vmscan.c @@ -1282,7 +1282,7 @@ unsigned long try_to_free_pages(struct zone **zones, int order, gfp_t gfp_mask) */ if (priority < 0) priority = 0; - for (i = 0; zones[i] != NULL; i++) { + for (i = 0; zones[i] != 0; i++) { struct zone *zone = zones[i]; if (!cpuset_zone_allowed_hardwall(zone, GFP_KERNEL)) diff --git a/trunk/net/atm/br2684.c b/trunk/net/atm/br2684.c index ba6428f204f9..c742d37bfb97 100644 --- a/trunk/net/atm/br2684.c +++ b/trunk/net/atm/br2684.c @@ -24,6 +24,16 @@ Author: Marcell GAL, 2000, XDSL Ltd, Hungary #include "common.h" +/* + * Define this to use a version of the code which interacts with the higher + * layers in a more intellegent way, by always reserving enough space for + * our header at the begining of the packet. However, there may still be + * some problems with programs like tcpdump. In 2.5 we'll sort out what + * we need to do to get this perfect. For now we just will copy the packet + * if we need space for the header + */ +/* #define FASTER_VERSION */ + #ifdef SKB_DEBUG static void skb_debug(const struct sk_buff *skb) { @@ -59,7 +69,9 @@ struct br2684_vcc { #ifdef CONFIG_ATM_BR2684_IPFILTER struct br2684_filter filter; #endif /* CONFIG_ATM_BR2684_IPFILTER */ +#ifndef FASTER_VERSION unsigned copies_needed, copies_failed; +#endif /* FASTER_VERSION */ }; struct br2684_dev { @@ -135,6 +147,13 @@ static int br2684_xmit_vcc(struct sk_buff *skb, struct br2684_dev *brdev, struct br2684_vcc *brvcc) { struct atm_vcc *atmvcc; +#ifdef FASTER_VERSION + if (brvcc->encaps == e_llc) + memcpy(skb_push(skb, 8), llc_oui_pid_pad, 8); + /* last 2 bytes of llc_oui_pid_pad are managed by header routines; + yes, you got it: 8 + 2 = sizeof(llc_oui_pid_pad) + */ +#else int minheadroom = (brvcc->encaps == e_llc) ? 10 : 2; if (skb_headroom(skb) < minheadroom) { struct sk_buff *skb2 = skb_realloc_headroom(skb, minheadroom); @@ -151,6 +170,7 @@ static int br2684_xmit_vcc(struct sk_buff *skb, struct br2684_dev *brdev, skb_copy_to_linear_data(skb, llc_oui_pid_pad, 10); else memset(skb->data, 0, 2); +#endif /* FASTER_VERSION */ skb_debug(skb); ATM_SKB(skb)->vcc = atmvcc = brvcc->atmvcc; @@ -217,6 +237,87 @@ static struct net_device_stats *br2684_get_stats(struct net_device *dev) return &BRPRIV(dev)->stats; } +#ifdef FASTER_VERSION +/* + * These mirror eth_header and eth_header_cache. They are not usually + * exported for use in modules, so we grab them from net_device + * after ether_setup() is done with it. Bit of a hack. + */ +static int (*my_eth_header)(struct sk_buff *, struct net_device *, + unsigned short, void *, void *, unsigned); +static int (*my_eth_header_cache)(struct neighbour *, struct hh_cache *); + +static int +br2684_header(struct sk_buff *skb, struct net_device *dev, + unsigned short type, void *daddr, void *saddr, unsigned len) +{ + u16 *pad_before_eth; + int t = my_eth_header(skb, dev, type, daddr, saddr, len); + if (t > 0) { + pad_before_eth = (u16 *) skb_push(skb, 2); + *pad_before_eth = 0; + return dev->hard_header_len; /* or return 16; ? */ + } else + return t; +} + +static int +br2684_header_cache(struct neighbour *neigh, struct hh_cache *hh) +{ +/* hh_data is 16 bytes long. if encaps is ether-llc we need 24, so +xmit will add the additional header part in that case */ + u16 *pad_before_eth = (u16 *)(hh->hh_data); + int t = my_eth_header_cache(neigh, hh); + DPRINTK("br2684_header_cache, neigh=%p, hh_cache=%p\n", neigh, hh); + if (t < 0) + return t; + else { + *pad_before_eth = 0; + hh->hh_len = PADLEN + ETH_HLEN; + } + return 0; +} + +/* + * This is similar to eth_type_trans, which cannot be used because of + * our dev->hard_header_len + */ +static inline __be16 br_type_trans(struct sk_buff *skb, struct net_device *dev) +{ + struct ethhdr *eth; + unsigned char *rawp; + eth = eth_hdr(skb); + + if (is_multicast_ether_addr(eth->h_dest)) { + if (!compare_ether_addr(eth->h_dest, dev->broadcast)) + skb->pkt_type = PACKET_BROADCAST; + else + skb->pkt_type = PACKET_MULTICAST; + } + + else if (compare_ether_addr(eth->h_dest, dev->dev_addr)) + skb->pkt_type = PACKET_OTHERHOST; + + if (ntohs(eth->h_proto) >= 1536) + return eth->h_proto; + + rawp = skb->data; + + /* + * This is a magic hack to spot IPX packets. Older Novell breaks + * the protocol design and runs IPX over 802.3 without an 802.2 LLC + * layer. We look for FFFF which isn't a used 802.2 SSAP/DSAP. This + * won't work for fault tolerant netware but does for the rest. + */ + if (*(unsigned short *) rawp == 0xFFFF) + return htons(ETH_P_802_3); + + /* + * Real 802.2 LLC + */ + return htons(ETH_P_802_2); +} +#endif /* FASTER_VERSION */ /* * We remember when the MAC gets set, so we don't override it later with @@ -347,8 +448,17 @@ static void br2684_push(struct atm_vcc *atmvcc, struct sk_buff *skb) return; } +#ifdef FASTER_VERSION + /* FIXME: tcpdump shows that pointer to mac header is 2 bytes earlier, + than should be. What else should I set? */ + skb_pull(skb, plen); + skb_set_mac_header(skb, -ETH_HLEN); + skb->pkt_type = PACKET_HOST; + skb->protocol = br_type_trans(skb, net_dev); +#else skb_pull(skb, plen - ETH_HLEN); skb->protocol = eth_type_trans(skb, net_dev); +#endif /* FASTER_VERSION */ #ifdef CONFIG_ATM_BR2684_IPFILTER if (unlikely(packet_fails_filter(skb->protocol, brvcc, skb))) { brdev->stats.rx_dropped++; @@ -474,6 +584,13 @@ static void br2684_setup(struct net_device *netdev) ether_setup(netdev); brdev->net_dev = netdev; +#ifdef FASTER_VERSION + my_eth_header = netdev->hard_header; + netdev->hard_header = br2684_header; + my_eth_header_cache = netdev->hard_header_cache; + netdev->hard_header_cache = br2684_header_cache; + netdev->hard_header_len = sizeof(llc_oui_pid_pad) + ETH_HLEN; /* 10 + 14 */ +#endif my_eth_mac_addr = netdev->set_mac_address; netdev->set_mac_address = br2684_mac_addr; netdev->hard_start_xmit = br2684_start_xmit; @@ -602,12 +719,16 @@ static int br2684_seq_show(struct seq_file *seq, void *v) list_for_each_entry(brvcc, &brdev->brvccs, brvccs) { seq_printf(seq, " vcc %d.%d.%d: encaps=%s" +#ifndef FASTER_VERSION ", failed copies %u/%u" +#endif /* FASTER_VERSION */ "\n", brvcc->atmvcc->dev->number, brvcc->atmvcc->vpi, brvcc->atmvcc->vci, (brvcc->encaps == e_llc) ? "LLC" : "VC" +#ifndef FASTER_VERSION , brvcc->copies_failed , brvcc->copies_needed +#endif /* FASTER_VERSION */ ); #ifdef CONFIG_ATM_BR2684_IPFILTER #define b1(var, byte) ((u8 *) &brvcc->filter.var)[byte] diff --git a/trunk/net/bluetooth/hidp/core.c b/trunk/net/bluetooth/hidp/core.c index 66c736953cfe..ff5784b440d7 100644 --- a/trunk/net/bluetooth/hidp/core.c +++ b/trunk/net/bluetooth/hidp/core.c @@ -656,13 +656,11 @@ static inline int hidp_setup_input(struct hidp_session *session, struct hidp_con } if (req->subclass & 0x80) { - input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); - input->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) | - BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE); - input->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y); - input->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_SIDE) | - BIT_MASK(BTN_EXTRA); - input->relbit[0] |= BIT_MASK(REL_WHEEL); + input->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); + input->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE); + input->relbit[0] = BIT(REL_X) | BIT(REL_Y); + input->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_SIDE) | BIT(BTN_EXTRA); + input->relbit[0] |= BIT(REL_WHEEL); } input->dev.parent = hidp_get_device(session); diff --git a/trunk/net/core/filter.c b/trunk/net/core/filter.c index e0a06942c025..bd903aaf7aa7 100644 --- a/trunk/net/core/filter.c +++ b/trunk/net/core/filter.c @@ -386,25 +386,6 @@ int sk_chk_filter(struct sock_filter *filter, int flen) return (BPF_CLASS(filter[flen - 1].code) == BPF_RET) ? 0 : -EINVAL; } -/** - * sk_filter_rcu_release: Release a socket filter by rcu_head - * @rcu: rcu_head that contains the sk_filter to free - */ -static void sk_filter_rcu_release(struct rcu_head *rcu) -{ - struct sk_filter *fp = container_of(rcu, struct sk_filter, rcu); - - sk_filter_release(fp); -} - -static void sk_filter_delayed_uncharge(struct sock *sk, struct sk_filter *fp) -{ - unsigned int size = sk_filter_len(fp); - - atomic_sub(size, &sk->sk_omem_alloc); - call_rcu_bh(&fp->rcu, sk_filter_rcu_release); -} - /** * sk_attach_filter - attach a socket filter * @fprog: the filter program @@ -417,7 +398,7 @@ static void sk_filter_delayed_uncharge(struct sock *sk, struct sk_filter *fp) */ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk) { - struct sk_filter *fp, *old_fp; + struct sk_filter *fp; unsigned int fsize = sizeof(struct sock_filter) * fprog->len; int err; @@ -437,35 +418,19 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk) fp->len = fprog->len; err = sk_chk_filter(fp->insns, fp->len); - if (err) { - sk_filter_uncharge(sk, fp); - return err; + if (!err) { + struct sk_filter *old_fp; + + rcu_read_lock_bh(); + old_fp = rcu_dereference(sk->sk_filter); + rcu_assign_pointer(sk->sk_filter, fp); + rcu_read_unlock_bh(); + fp = old_fp; } - rcu_read_lock_bh(); - old_fp = rcu_dereference(sk->sk_filter); - rcu_assign_pointer(sk->sk_filter, fp); - rcu_read_unlock_bh(); - - if (old_fp) - sk_filter_delayed_uncharge(sk, old_fp); - return 0; -} - -int sk_detach_filter(struct sock *sk) -{ - int ret = -ENOENT; - struct sk_filter *filter; - - rcu_read_lock_bh(); - filter = rcu_dereference(sk->sk_filter); - if (filter) { - rcu_assign_pointer(sk->sk_filter, NULL); - sk_filter_delayed_uncharge(sk, filter); - ret = 0; - } - rcu_read_unlock_bh(); - return ret; + if (fp) + sk_filter_release(sk, fp); + return err; } EXPORT_SYMBOL(sk_chk_filter); diff --git a/trunk/net/core/gen_estimator.c b/trunk/net/core/gen_estimator.c index daadbcc4e8dd..590a767b029c 100644 --- a/trunk/net/core/gen_estimator.c +++ b/trunk/net/core/gen_estimator.c @@ -15,7 +15,7 @@ #include #include -#include +#include #include #include #include diff --git a/trunk/net/core/neighbour.c b/trunk/net/core/neighbour.c index 67ba9914e52e..cd3af59b38a1 100644 --- a/trunk/net/core/neighbour.c +++ b/trunk/net/core/neighbour.c @@ -2496,6 +2496,7 @@ static struct neigh_sysctl_table { .proc_handler = &proc_dointvec, }, { + .ctl_name = NET_NEIGH_RETRANS_TIME, .procname = "retrans_time", .maxlen = sizeof(int), .mode = 0644, @@ -2540,39 +2541,26 @@ static struct neigh_sysctl_table { .proc_handler = &proc_dointvec, }, { + .ctl_name = NET_NEIGH_ANYCAST_DELAY, .procname = "anycast_delay", .maxlen = sizeof(int), .mode = 0644, .proc_handler = &proc_dointvec_userhz_jiffies, }, { + .ctl_name = NET_NEIGH_PROXY_DELAY, .procname = "proxy_delay", .maxlen = sizeof(int), .mode = 0644, .proc_handler = &proc_dointvec_userhz_jiffies, }, { + .ctl_name = NET_NEIGH_LOCKTIME, .procname = "locktime", .maxlen = sizeof(int), .mode = 0644, .proc_handler = &proc_dointvec_userhz_jiffies, }, - { - .ctl_name = NET_NEIGH_RETRANS_TIME_MS, - .procname = "retrans_time_ms", - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec_ms_jiffies, - .strategy = &sysctl_ms_jiffies, - }, - { - .ctl_name = NET_NEIGH_REACHABLE_TIME_MS, - .procname = "base_reachable_time_ms", - .maxlen = sizeof(int), - .mode = 0644, - .proc_handler = &proc_dointvec_ms_jiffies, - .strategy = &sysctl_ms_jiffies, - }, { .ctl_name = NET_NEIGH_GC_INTERVAL, .procname = "gc_interval", @@ -2602,7 +2590,22 @@ static struct neigh_sysctl_table { .mode = 0644, .proc_handler = &proc_dointvec, }, - {} + { + .ctl_name = NET_NEIGH_RETRANS_TIME_MS, + .procname = "retrans_time_ms", + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_ms_jiffies, + .strategy = &sysctl_ms_jiffies, + }, + { + .ctl_name = NET_NEIGH_REACHABLE_TIME_MS, + .procname = "base_reachable_time_ms", + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec_ms_jiffies, + .strategy = &sysctl_ms_jiffies, + }, }, .neigh_dev = { { @@ -2655,48 +2658,42 @@ int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p, t->neigh_vars[9].data = &p->anycast_delay; t->neigh_vars[10].data = &p->proxy_delay; t->neigh_vars[11].data = &p->locktime; - t->neigh_vars[12].data = &p->retrans_time; - t->neigh_vars[13].data = &p->base_reachable_time; if (dev) { dev_name_source = dev->name; t->neigh_dev[0].ctl_name = dev->ifindex; - /* Terminate the table early */ - memset(&t->neigh_vars[14], 0, sizeof(t->neigh_vars[14])); + t->neigh_vars[12].procname = NULL; + t->neigh_vars[13].procname = NULL; + t->neigh_vars[14].procname = NULL; + t->neigh_vars[15].procname = NULL; } else { dev_name_source = t->neigh_dev[0].procname; - t->neigh_vars[14].data = (int *)(p + 1); - t->neigh_vars[15].data = (int *)(p + 1) + 1; - t->neigh_vars[16].data = (int *)(p + 1) + 2; - t->neigh_vars[17].data = (int *)(p + 1) + 3; + t->neigh_vars[12].data = (int *)(p + 1); + t->neigh_vars[13].data = (int *)(p + 1) + 1; + t->neigh_vars[14].data = (int *)(p + 1) + 2; + t->neigh_vars[15].data = (int *)(p + 1) + 3; } + t->neigh_vars[16].data = &p->retrans_time; + t->neigh_vars[17].data = &p->base_reachable_time; if (handler || strategy) { /* RetransTime */ t->neigh_vars[3].proc_handler = handler; t->neigh_vars[3].strategy = strategy; t->neigh_vars[3].extra1 = dev; - if (!strategy) - t->neigh_vars[3].ctl_name = CTL_UNNUMBERED; /* ReachableTime */ t->neigh_vars[4].proc_handler = handler; t->neigh_vars[4].strategy = strategy; t->neigh_vars[4].extra1 = dev; - if (!strategy) - t->neigh_vars[4].ctl_name = CTL_UNNUMBERED; /* RetransTime (in milliseconds)*/ - t->neigh_vars[12].proc_handler = handler; - t->neigh_vars[12].strategy = strategy; - t->neigh_vars[12].extra1 = dev; - if (!strategy) - t->neigh_vars[12].ctl_name = CTL_UNNUMBERED; + t->neigh_vars[16].proc_handler = handler; + t->neigh_vars[16].strategy = strategy; + t->neigh_vars[16].extra1 = dev; /* ReachableTime (in milliseconds) */ - t->neigh_vars[13].proc_handler = handler; - t->neigh_vars[13].strategy = strategy; - t->neigh_vars[13].extra1 = dev; - if (!strategy) - t->neigh_vars[13].ctl_name = CTL_UNNUMBERED; + t->neigh_vars[17].proc_handler = handler; + t->neigh_vars[17].strategy = strategy; + t->neigh_vars[17].extra1 = dev; } dev_name = kstrdup(dev_name_source, GFP_KERNEL); diff --git a/trunk/net/core/pktgen.c b/trunk/net/core/pktgen.c index 7ac703171ff3..2100c734b102 100644 --- a/trunk/net/core/pktgen.c +++ b/trunk/net/core/pktgen.c @@ -161,7 +161,7 @@ #endif #include #include -#include +#include #include #include #include @@ -2454,7 +2454,7 @@ static int pktgen_output_ipsec(struct sk_buff *skb, struct pktgen_dev *pkt_dev) spin_lock(&x->lock); iph = ip_hdr(skb); - err = x->outer_mode->output(x, skb); + err = x->mode->output(x, skb); if (err) goto error; err = x->type->output(x, skb); @@ -3514,7 +3514,7 @@ static int pktgen_thread_worker(void *arg) init_waitqueue_head(&t->queue); - pr_debug("pktgen: starting pktgen/%d: pid=%d\n", cpu, task_pid_nr(current)); + pr_debug("pktgen: starting pktgen/%d: pid=%d\n", cpu, current->pid); set_current_state(TASK_INTERRUPTIBLE); diff --git a/trunk/net/core/rtnetlink.c b/trunk/net/core/rtnetlink.c index 4a2640d38261..1072d16696c3 100644 --- a/trunk/net/core/rtnetlink.c +++ b/trunk/net/core/rtnetlink.c @@ -744,10 +744,10 @@ static struct net *get_net_ns_by_pid(pid_t pid) rcu_read_lock(); tsk = find_task_by_pid(pid); if (tsk) { - struct nsproxy *nsproxy; - nsproxy = task_nsproxy(tsk); - if (nsproxy) - net = get_net(nsproxy->net_ns); + task_lock(tsk); + if (tsk->nsproxy) + net = get_net(tsk->nsproxy->net_ns); + task_unlock(tsk); } rcu_read_unlock(); return net; diff --git a/trunk/net/core/scm.c b/trunk/net/core/scm.c index 100ba6d9d478..530bee8d9ed9 100644 --- a/trunk/net/core/scm.c +++ b/trunk/net/core/scm.c @@ -24,8 +24,6 @@ #include #include #include -#include -#include #include #include @@ -44,7 +42,7 @@ static __inline__ int scm_check_creds(struct ucred *creds) { - if ((creds->pid == task_tgid_vnr(current) || capable(CAP_SYS_ADMIN)) && + if ((creds->pid == current->tgid || capable(CAP_SYS_ADMIN)) && ((creds->uid == current->uid || creds->uid == current->euid || creds->uid == current->suid) || capable(CAP_SETUID)) && ((creds->gid == current->gid || creds->gid == current->egid || diff --git a/trunk/net/core/sock.c b/trunk/net/core/sock.c index febbcbcf8022..d45ecdccc6a1 100644 --- a/trunk/net/core/sock.c +++ b/trunk/net/core/sock.c @@ -232,7 +232,7 @@ static int sock_set_timeout(long *timeo_p, char __user *optval, int optlen) warned++; printk(KERN_INFO "sock_set_timeout: `%s' (pid %d) " "tries to set negative timeout\n", - current->comm, task_pid_nr(current)); + current->comm, current->pid); return 0; } *timeo_p = MAX_SCHEDULE_TIMEOUT; @@ -428,6 +428,7 @@ int sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, int optlen) { struct sock *sk=sock->sk; + struct sk_filter *filter; int val; int valbool; struct linger ling; @@ -651,7 +652,16 @@ int sock_setsockopt(struct socket *sock, int level, int optname, break; case SO_DETACH_FILTER: - ret = sk_detach_filter(sk); + rcu_read_lock_bh(); + filter = rcu_dereference(sk->sk_filter); + if (filter) { + rcu_assign_pointer(sk->sk_filter, NULL); + sk_filter_release(sk, filter); + rcu_read_unlock_bh(); + break; + } + rcu_read_unlock_bh(); + ret = -ENONET; break; case SO_PASSSEC: @@ -915,7 +925,7 @@ void sk_free(struct sock *sk) filter = rcu_dereference(sk->sk_filter); if (filter) { - sk_filter_uncharge(sk, filter); + sk_filter_release(sk, filter); rcu_assign_pointer(sk->sk_filter, NULL); } diff --git a/trunk/net/dccp/input.c b/trunk/net/dccp/input.c index 3560a2a875a0..19d7e1dbd87e 100644 --- a/trunk/net/dccp/input.c +++ b/trunk/net/dccp/input.c @@ -19,9 +19,6 @@ #include "ccid.h" #include "dccp.h" -/* rate-limit for syncs in reply to sequence-invalid packets; RFC 4340, 7.5.4 */ -int sysctl_dccp_sync_ratelimit __read_mostly = HZ / 8; - static void dccp_fin(struct sock *sk, struct sk_buff *skb) { sk->sk_shutdown |= RCV_SHUTDOWN; diff --git a/trunk/net/dccp/sysctl.c b/trunk/net/dccp/sysctl.c index c62c05039f69..9364b2fb4dbd 100644 --- a/trunk/net/dccp/sysctl.c +++ b/trunk/net/dccp/sysctl.c @@ -18,6 +18,9 @@ #error This file should not be compiled without CONFIG_SYSCTL defined #endif +/* rate-limit for syncs in reply to sequence-invalid packets; RFC 4340, 7.5.4 */ +int sysctl_dccp_sync_ratelimit __read_mostly = HZ / 8; + static struct ctl_table dccp_default_table[] = { { .procname = "seq_window", diff --git a/trunk/net/ieee80211/ieee80211_crypt_tkip.c b/trunk/net/ieee80211/ieee80211_crypt_tkip.c index 72e6ab66834f..6cc54eeca3ed 100644 --- a/trunk/net/ieee80211/ieee80211_crypt_tkip.c +++ b/trunk/net/ieee80211/ieee80211_crypt_tkip.c @@ -586,7 +586,7 @@ static void michael_mic_hdr(struct sk_buff *skb, u8 * hdr) if (stype & IEEE80211_STYPE_QOS_DATA) { const struct ieee80211_hdr_3addrqos *qoshdr = (struct ieee80211_hdr_3addrqos *)skb->data; - hdr[12] = le16_to_cpu(qoshdr->qos_ctl) & IEEE80211_QCTL_TID; + hdr[12] = qoshdr->qos_ctl & cpu_to_le16(IEEE80211_QCTL_TID); } else hdr[12] = 0; /* priority */ diff --git a/trunk/net/ipv4/fib_trie.c b/trunk/net/ipv4/fib_trie.c index 8d8c2915e064..81a8285d6d6a 100644 --- a/trunk/net/ipv4/fib_trie.c +++ b/trunk/net/ipv4/fib_trie.c @@ -54,7 +54,7 @@ #include #include -#include +#include #include #include #include diff --git a/trunk/net/ipv4/inet_connection_sock.c b/trunk/net/ipv4/inet_connection_sock.c index 8fb6ca23700a..3cef12835c4b 100644 --- a/trunk/net/ipv4/inet_connection_sock.c +++ b/trunk/net/ipv4/inet_connection_sock.c @@ -93,7 +93,7 @@ int inet_csk_get_port(struct inet_hashinfo *hashinfo, int remaining, rover, low, high; inet_get_local_port_range(&low, &high); - remaining = (high - low) + 1; + remaining = high - low; rover = net_random() % remaining + low; do { diff --git a/trunk/net/ipv4/inet_fragment.c b/trunk/net/ipv4/inet_fragment.c index e15e04fc6661..484cf512858f 100644 --- a/trunk/net/ipv4/inet_fragment.c +++ b/trunk/net/ipv4/inet_fragment.c @@ -136,9 +136,7 @@ void inet_frag_destroy(struct inet_frag_queue *q, struct inet_frags *f, *work -= f->qsize; atomic_sub(f->qsize, &f->mem); - if (f->destructor) - f->destructor(q); - kfree(q); + f->destructor(q); } EXPORT_SYMBOL(inet_frag_destroy); @@ -174,88 +172,3 @@ int inet_frag_evictor(struct inet_frags *f) return evicted; } EXPORT_SYMBOL(inet_frag_evictor); - -static struct inet_frag_queue *inet_frag_intern(struct inet_frag_queue *qp_in, - struct inet_frags *f, unsigned int hash, void *arg) -{ - struct inet_frag_queue *qp; -#ifdef CONFIG_SMP - struct hlist_node *n; -#endif - - write_lock(&f->lock); -#ifdef CONFIG_SMP - /* With SMP race we have to recheck hash table, because - * such entry could be created on other cpu, while we - * promoted read lock to write lock. - */ - hlist_for_each_entry(qp, n, &f->hash[hash], list) { - if (f->match(qp, arg)) { - atomic_inc(&qp->refcnt); - write_unlock(&f->lock); - qp_in->last_in |= COMPLETE; - inet_frag_put(qp_in, f); - return qp; - } - } -#endif - qp = qp_in; - if (!mod_timer(&qp->timer, jiffies + f->ctl->timeout)) - atomic_inc(&qp->refcnt); - - atomic_inc(&qp->refcnt); - hlist_add_head(&qp->list, &f->hash[hash]); - list_add_tail(&qp->lru_list, &f->lru_list); - f->nqueues++; - write_unlock(&f->lock); - return qp; -} - -static struct inet_frag_queue *inet_frag_alloc(struct inet_frags *f, void *arg) -{ - struct inet_frag_queue *q; - - q = kzalloc(f->qsize, GFP_ATOMIC); - if (q == NULL) - return NULL; - - f->constructor(q, arg); - atomic_add(f->qsize, &f->mem); - setup_timer(&q->timer, f->frag_expire, (unsigned long)q); - spin_lock_init(&q->lock); - atomic_set(&q->refcnt, 1); - - return q; -} - -static struct inet_frag_queue *inet_frag_create(struct inet_frags *f, - void *arg, unsigned int hash) -{ - struct inet_frag_queue *q; - - q = inet_frag_alloc(f, arg); - if (q == NULL) - return NULL; - - return inet_frag_intern(q, f, hash, arg); -} - -struct inet_frag_queue *inet_frag_find(struct inet_frags *f, void *key, - unsigned int hash) -{ - struct inet_frag_queue *q; - struct hlist_node *n; - - read_lock(&f->lock); - hlist_for_each_entry(q, n, &f->hash[hash], list) { - if (f->match(q, key)) { - atomic_inc(&q->refcnt); - read_unlock(&f->lock); - return q; - } - } - read_unlock(&f->lock); - - return inet_frag_create(f, key, hash); -} -EXPORT_SYMBOL(inet_frag_find); diff --git a/trunk/net/ipv4/inet_hashtables.c b/trunk/net/ipv4/inet_hashtables.c index 16eecc7046a3..fac6398e4367 100644 --- a/trunk/net/ipv4/inet_hashtables.c +++ b/trunk/net/ipv4/inet_hashtables.c @@ -286,7 +286,7 @@ int inet_hash_connect(struct inet_timewait_death_row *death_row, struct inet_timewait_sock *tw = NULL; inet_get_local_port_range(&low, &high); - remaining = (high - low) + 1; + remaining = high - low; local_bh_disable(); for (i = 1; i <= remaining; i++) { diff --git a/trunk/net/ipv4/ip_fragment.c b/trunk/net/ipv4/ip_fragment.c index 2143bf30597a..443b3f89192f 100644 --- a/trunk/net/ipv4/ip_fragment.c +++ b/trunk/net/ipv4/ip_fragment.c @@ -108,11 +108,6 @@ int ip_frag_mem(void) static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev, struct net_device *dev); -struct ip4_create_arg { - struct iphdr *iph; - u32 user; -}; - static unsigned int ipqhashfn(__be16 id, __be32 saddr, __be32 daddr, u8 prot) { return jhash_3words((__force u32)id << 16 | prot, @@ -128,19 +123,6 @@ static unsigned int ip4_hashfn(struct inet_frag_queue *q) return ipqhashfn(ipq->id, ipq->saddr, ipq->daddr, ipq->protocol); } -static int ip4_frag_match(struct inet_frag_queue *q, void *a) -{ - struct ipq *qp; - struct ip4_create_arg *arg = a; - - qp = container_of(q, struct ipq, q); - return (qp->id == arg->iph->id && - qp->saddr == arg->iph->saddr && - qp->daddr == arg->iph->daddr && - qp->protocol == arg->iph->protocol && - qp->user == arg->user); -} - /* Memory Tracking Functions. */ static __inline__ void frag_kfree_skb(struct sk_buff *skb, int *work) { @@ -150,20 +132,6 @@ static __inline__ void frag_kfree_skb(struct sk_buff *skb, int *work) kfree_skb(skb); } -static void ip4_frag_init(struct inet_frag_queue *q, void *a) -{ - struct ipq *qp = container_of(q, struct ipq, q); - struct ip4_create_arg *arg = a; - - qp->protocol = arg->iph->protocol; - qp->id = arg->iph->id; - qp->saddr = arg->iph->saddr; - qp->daddr = arg->iph->daddr; - qp->user = arg->user; - qp->peer = sysctl_ipfrag_max_dist ? - inet_getpeer(arg->iph->saddr, 1) : NULL; -} - static __inline__ void ip4_frag_free(struct inet_frag_queue *q) { struct ipq *qp; @@ -171,6 +139,17 @@ static __inline__ void ip4_frag_free(struct inet_frag_queue *q) qp = container_of(q, struct ipq, q); if (qp->peer) inet_putpeer(qp->peer); + kfree(qp); +} + +static __inline__ struct ipq *frag_alloc_queue(void) +{ + struct ipq *qp = kzalloc(sizeof(struct ipq), GFP_ATOMIC); + + if (!qp) + return NULL; + atomic_add(sizeof(struct ipq), &ip4_frags.mem); + return qp; } @@ -206,9 +185,7 @@ static void ip_evictor(void) */ static void ip_expire(unsigned long arg) { - struct ipq *qp; - - qp = container_of((struct inet_frag_queue *) arg, struct ipq, q); + struct ipq *qp = (struct ipq *) arg; spin_lock(&qp->q.lock); @@ -233,30 +210,112 @@ static void ip_expire(unsigned long arg) ipq_put(qp); } -/* Find the correct entry in the "incomplete datagrams" queue for - * this IP datagram, and create new one, if nothing is found. - */ -static inline struct ipq *ip_find(struct iphdr *iph, u32 user) +/* Creation primitives. */ + +static struct ipq *ip_frag_intern(struct ipq *qp_in) { - struct inet_frag_queue *q; - struct ip4_create_arg arg; + struct ipq *qp; +#ifdef CONFIG_SMP + struct hlist_node *n; +#endif unsigned int hash; - arg.iph = iph; - arg.user = user; - hash = ipqhashfn(iph->id, iph->saddr, iph->daddr, iph->protocol); + write_lock(&ip4_frags.lock); + hash = ipqhashfn(qp_in->id, qp_in->saddr, qp_in->daddr, + qp_in->protocol); +#ifdef CONFIG_SMP + /* With SMP race we have to recheck hash table, because + * such entry could be created on other cpu, while we + * promoted read lock to write lock. + */ + hlist_for_each_entry(qp, n, &ip4_frags.hash[hash], q.list) { + if (qp->id == qp_in->id && + qp->saddr == qp_in->saddr && + qp->daddr == qp_in->daddr && + qp->protocol == qp_in->protocol && + qp->user == qp_in->user) { + atomic_inc(&qp->q.refcnt); + write_unlock(&ip4_frags.lock); + qp_in->q.last_in |= COMPLETE; + ipq_put(qp_in); + return qp; + } + } +#endif + qp = qp_in; + + if (!mod_timer(&qp->q.timer, jiffies + ip4_frags_ctl.timeout)) + atomic_inc(&qp->q.refcnt); - q = inet_frag_find(&ip4_frags, &arg, hash); - if (q == NULL) + atomic_inc(&qp->q.refcnt); + hlist_add_head(&qp->q.list, &ip4_frags.hash[hash]); + INIT_LIST_HEAD(&qp->q.lru_list); + list_add_tail(&qp->q.lru_list, &ip4_frags.lru_list); + ip4_frags.nqueues++; + write_unlock(&ip4_frags.lock); + return qp; +} + +/* Add an entry to the 'ipq' queue for a newly received IP datagram. */ +static struct ipq *ip_frag_create(struct iphdr *iph, u32 user) +{ + struct ipq *qp; + + if ((qp = frag_alloc_queue()) == NULL) goto out_nomem; - return container_of(q, struct ipq, q); + qp->protocol = iph->protocol; + qp->id = iph->id; + qp->saddr = iph->saddr; + qp->daddr = iph->daddr; + qp->user = user; + qp->peer = sysctl_ipfrag_max_dist ? inet_getpeer(iph->saddr, 1) : NULL; + + /* Initialize a timer for this entry. */ + init_timer(&qp->q.timer); + qp->q.timer.data = (unsigned long) qp; /* pointer to queue */ + qp->q.timer.function = ip_expire; /* expire function */ + spin_lock_init(&qp->q.lock); + atomic_set(&qp->q.refcnt, 1); + + return ip_frag_intern(qp); out_nomem: LIMIT_NETDEBUG(KERN_ERR "ip_frag_create: no memory left !\n"); return NULL; } +/* Find the correct entry in the "incomplete datagrams" queue for + * this IP datagram, and create new one, if nothing is found. + */ +static inline struct ipq *ip_find(struct iphdr *iph, u32 user) +{ + __be16 id = iph->id; + __be32 saddr = iph->saddr; + __be32 daddr = iph->daddr; + __u8 protocol = iph->protocol; + unsigned int hash; + struct ipq *qp; + struct hlist_node *n; + + read_lock(&ip4_frags.lock); + hash = ipqhashfn(id, saddr, daddr, protocol); + hlist_for_each_entry(qp, n, &ip4_frags.hash[hash], q.list) { + if (qp->id == id && + qp->saddr == saddr && + qp->daddr == daddr && + qp->protocol == protocol && + qp->user == user) { + atomic_inc(&qp->q.refcnt); + read_unlock(&ip4_frags.lock); + return qp; + } + } + read_unlock(&ip4_frags.lock); + + return ip_frag_create(iph, user); +} + /* Is the fragment too far ahead to be part of ipq? */ static inline int ip_frag_too_far(struct ipq *qp) { @@ -486,6 +545,7 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev, if (prev) { head = prev->next; fp = skb_clone(head, GFP_ATOMIC); + if (!fp) goto out_nomem; @@ -511,6 +571,7 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev, goto out_oversize; /* Head of list must not be cloned. */ + err = -ENOMEM; if (skb_cloned(head) && pskb_expand_head(head, 0, 0, GFP_ATOMIC)) goto out_nomem; @@ -566,7 +627,6 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev, out_nomem: LIMIT_NETDEBUG(KERN_ERR "IP: queue_glue: no memory for gluing " "queue %p\n", qp); - err = -ENOMEM; goto out_fail; out_oversize: if (net_ratelimit()) @@ -611,12 +671,9 @@ void __init ipfrag_init(void) { ip4_frags.ctl = &ip4_frags_ctl; ip4_frags.hashfn = ip4_hashfn; - ip4_frags.constructor = ip4_frag_init; ip4_frags.destructor = ip4_frag_free; ip4_frags.skb_free = NULL; ip4_frags.qsize = sizeof(struct ipq); - ip4_frags.match = ip4_frag_match; - ip4_frags.frag_expire = ip_expire; inet_frags_init(&ip4_frags); } diff --git a/trunk/net/ipv4/ipvs/ip_vs_sync.c b/trunk/net/ipv4/ipvs/ip_vs_sync.c index c99f2a33fb9e..1960747f354c 100644 --- a/trunk/net/ipv4/ipvs/ip_vs_sync.c +++ b/trunk/net/ipv4/ipvs/ip_vs_sync.c @@ -794,7 +794,7 @@ static int sync_thread(void *startup) add_wait_queue(&sync_wait, &wait); - set_sync_pid(state, task_pid_nr(current)); + set_sync_pid(state, current->pid); complete(tinfo->startup); /* @@ -877,7 +877,7 @@ int start_sync_thread(int state, char *mcast_ifn, __u8 syncid) if (!tinfo) return -ENOMEM; - IP_VS_DBG(7, "%s: pid %d\n", __FUNCTION__, task_pid_nr(current)); + IP_VS_DBG(7, "%s: pid %d\n", __FUNCTION__, current->pid); IP_VS_DBG(7, "Each ip_vs_sync_conn entry need %Zd bytes\n", sizeof(struct ip_vs_sync_conn)); @@ -917,7 +917,7 @@ int stop_sync_thread(int state) (state == IP_VS_STATE_BACKUP && !sync_backup_pid)) return -ESRCH; - IP_VS_DBG(7, "%s: pid %d\n", __FUNCTION__, task_pid_nr(current)); + IP_VS_DBG(7, "%s: pid %d\n", __FUNCTION__, current->pid); IP_VS_INFO("stopping sync thread %d ...\n", (state == IP_VS_STATE_MASTER) ? sync_master_pid : sync_backup_pid); diff --git a/trunk/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/trunk/net/ipv4/netfilter/nf_conntrack_proto_icmp.c index adcbaf6d4299..11fedc73049c 100644 --- a/trunk/net/ipv4/netfilter/nf_conntrack_proto_icmp.c +++ b/trunk/net/ipv4/netfilter/nf_conntrack_proto_icmp.c @@ -281,6 +281,7 @@ static int icmp_nlattr_to_tuple(struct nlattr *tb[], static struct ctl_table_header *icmp_sysctl_header; static struct ctl_table icmp_sysctl_table[] = { { + .ctl_name = NET_NF_CONNTRACK_ICMP_TIMEOUT, .procname = "nf_conntrack_icmp_timeout", .data = &nf_ct_icmp_timeout, .maxlen = sizeof(unsigned int), @@ -294,6 +295,7 @@ static struct ctl_table icmp_sysctl_table[] = { #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT static struct ctl_table icmp_compat_sysctl_table[] = { { + .ctl_name = NET_IPV4_NF_CONNTRACK_ICMP_TIMEOUT, .procname = "ip_conntrack_icmp_timeout", .data = &nf_ct_icmp_timeout, .maxlen = sizeof(unsigned int), diff --git a/trunk/net/ipv4/sysctl_net_ipv4.c b/trunk/net/ipv4/sysctl_net_ipv4.c index ffddd2b45352..c98ef16effd2 100644 --- a/trunk/net/ipv4/sysctl_net_ipv4.c +++ b/trunk/net/ipv4/sysctl_net_ipv4.c @@ -122,7 +122,7 @@ static int ipv4_local_port_range(ctl_table *table, int write, struct file *filp, ret = proc_dointvec_minmax(&tmp, write, filp, buffer, lenp, ppos); if (write && ret == 0) { - if (range[1] < range[0]) + if (range[1] <= range[0]) ret = -EINVAL; else set_local_port_range(range); @@ -150,7 +150,7 @@ static int ipv4_sysctl_local_port_range(ctl_table *table, int __user *name, ret = sysctl_intvec(&tmp, name, nlen, oldval, oldlenp, newval, newlen); if (ret == 0 && newval && newlen) { - if (range[1] < range[0]) + if (range[1] <= range[0]) ret = -EINVAL; else set_local_port_range(range); @@ -740,6 +740,7 @@ ctl_table ipv4_table[] = { .strategy = &sysctl_jiffies }, { + .ctl_name = NET_IPV4_IPFRAG_MAX_DIST, .procname = "ipfrag_max_dist", .data = &sysctl_ipfrag_max_dist, .maxlen = sizeof(int), @@ -864,6 +865,7 @@ ctl_table ipv4_table[] = { }, #endif /* CONFIG_NETLABEL */ { + .ctl_name = NET_TCP_AVAIL_CONG_CONTROL, .procname = "tcp_available_congestion_control", .maxlen = TCP_CA_BUF_MAX, .mode = 0444, diff --git a/trunk/net/ipv4/tcp.c b/trunk/net/ipv4/tcp.c index 2e6ad6dbba6c..4f322003835d 100644 --- a/trunk/net/ipv4/tcp.c +++ b/trunk/net/ipv4/tcp.c @@ -1334,7 +1334,7 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, if ((flags & MSG_PEEK) && peek_seq != tp->copied_seq) { if (net_ratelimit()) printk(KERN_DEBUG "TCP(%s:%d): Application bug, race in MSG_PEEK.\n", - current->comm, task_pid_nr(current)); + current->comm, current->pid); peek_seq = tp->copied_seq; } continue; diff --git a/trunk/net/ipv4/tcp_input.c b/trunk/net/ipv4/tcp_input.c index 9288220b73a8..0f00966b1784 100644 --- a/trunk/net/ipv4/tcp_input.c +++ b/trunk/net/ipv4/tcp_input.c @@ -1121,7 +1121,7 @@ static int tcp_mark_lost_retrans(struct sock *sk, u32 received_upto) struct sk_buff *skb; int flag = 0; int cnt = 0; - u32 new_low_seq = tp->snd_nxt; + u32 new_low_seq = 0; tcp_for_write_queue(skb, sk) { u32 ack_seq = TCP_SKB_CB(skb)->ack_seq; @@ -1153,7 +1153,7 @@ static int tcp_mark_lost_retrans(struct sock *sk, u32 received_upto) NET_INC_STATS_BH(LINUX_MIB_TCPLOSTRETRANSMIT); } } else { - if (before(ack_seq, new_low_seq)) + if (!new_low_seq || before(ack_seq, new_low_seq)) new_low_seq = ack_seq; cnt += tcp_skb_pcount(skb); } @@ -1242,7 +1242,7 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ int num_sacks = (ptr[1] - TCPOLEN_SACK_BASE)>>3; int reord = tp->packets_out; int prior_fackets; - u32 highest_sack_end_seq = tp->lost_retrans_low; + u32 highest_sack_end_seq = 0; int flag = 0; int found_dup_sack = 0; int cached_fack_count; diff --git a/trunk/net/ipv4/udp.c b/trunk/net/ipv4/udp.c index 35d2b0e9e10b..cb9fc58efb2f 100644 --- a/trunk/net/ipv4/udp.c +++ b/trunk/net/ipv4/udp.c @@ -147,14 +147,13 @@ int __udp_lib_get_port(struct sock *sk, unsigned short snum, write_lock_bh(&udp_hash_lock); if (!snum) { - int i, low, high, remaining; + int i, low, high; unsigned rover, best, best_size_so_far; inet_get_local_port_range(&low, &high); - remaining = (high - low) + 1; best_size_so_far = UINT_MAX; - best = rover = net_random() % remaining + low; + best = rover = net_random() % (high - low) + low; /* 1st pass: look for empty (or shortest) hash chain */ for (i = 0; i < UDP_HTABLE_SIZE; i++) { diff --git a/trunk/net/ipv4/xfrm4_input.c b/trunk/net/ipv4/xfrm4_input.c index 5e95c8a07efb..e9bbfde19ac3 100644 --- a/trunk/net/ipv4/xfrm4_input.c +++ b/trunk/net/ipv4/xfrm4_input.c @@ -16,6 +16,19 @@ #include #include +static int xfrm4_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq) +{ + switch (nexthdr) { + case IPPROTO_IPIP: + case IPPROTO_IPV6: + *spi = ip_hdr(skb)->saddr; + *seq = 0; + return 0; + } + + return xfrm_parse_spi(skb, nexthdr, spi, seq); +} + #ifdef CONFIG_NETFILTER static inline int xfrm4_rcv_encap_finish(struct sk_buff *skb) { @@ -33,29 +46,28 @@ static inline int xfrm4_rcv_encap_finish(struct sk_buff *skb) } #endif -int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi, - int encap_type) +static int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type) { - int err; - __be32 seq; + __be32 spi, seq; struct xfrm_state *xfrm_vec[XFRM_MAX_DEPTH]; struct xfrm_state *x; int xfrm_nr = 0; int decaps = 0; + int err = xfrm4_parse_spi(skb, ip_hdr(skb)->protocol, &spi, &seq); unsigned int nhoff = offsetof(struct iphdr, protocol); - seq = 0; - if (!spi && (err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0) + if (err != 0) goto drop; do { const struct iphdr *iph = ip_hdr(skb); + int nexthdr; if (xfrm_nr == XFRM_MAX_DEPTH) goto drop; x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, spi, - nexthdr, AF_INET); + iph->protocol != IPPROTO_IPV6 ? iph->protocol : IPPROTO_IPIP, AF_INET); if (x == NULL) goto drop; @@ -91,15 +103,15 @@ int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi, xfrm_vec[xfrm_nr++] = x; - if (x->outer_mode->input(x, skb)) + if (x->mode->input(x, skb)) goto drop; - if (x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) { + if (x->props.mode == XFRM_MODE_TUNNEL) { decaps = 1; break; } - err = xfrm_parse_spi(skb, nexthdr, &spi, &seq); + err = xfrm_parse_spi(skb, ip_hdr(skb)->protocol, &spi, &seq); if (err < 0) goto drop; } while (!err); @@ -153,7 +165,6 @@ int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi, kfree_skb(skb); return 0; } -EXPORT_SYMBOL(xfrm4_rcv_encap); /* If it's a keepalive packet, then just eat it. * If it's an encapsulated packet, then pass it to the @@ -241,8 +252,11 @@ int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb) __skb_pull(skb, len); skb_reset_transport_header(skb); + /* modify the protocol (it's ESP!) */ + iph->protocol = IPPROTO_ESP; + /* process ESP */ - ret = xfrm4_rcv_encap(skb, IPPROTO_ESP, 0, encap_type); + ret = xfrm4_rcv_encap(skb, encap_type); return ret; drop: @@ -252,7 +266,7 @@ int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb) int xfrm4_rcv(struct sk_buff *skb) { - return xfrm4_rcv_spi(skb, ip_hdr(skb)->protocol, 0); + return xfrm4_rcv_encap(skb, 0); } EXPORT_SYMBOL(xfrm4_rcv); diff --git a/trunk/net/ipv4/xfrm4_mode_beet.c b/trunk/net/ipv4/xfrm4_mode_beet.c index e42e122414be..73d2338bec55 100644 --- a/trunk/net/ipv4/xfrm4_mode_beet.c +++ b/trunk/net/ipv4/xfrm4_mode_beet.c @@ -114,7 +114,6 @@ static struct xfrm_mode xfrm4_beet_mode = { .output = xfrm4_beet_output, .owner = THIS_MODULE, .encap = XFRM_MODE_BEET, - .flags = XFRM_MODE_FLAG_TUNNEL, }; static int __init xfrm4_beet_init(void) diff --git a/trunk/net/ipv4/xfrm4_mode_tunnel.c b/trunk/net/ipv4/xfrm4_mode_tunnel.c index e4deecba6dd2..1ae9d32276f0 100644 --- a/trunk/net/ipv4/xfrm4_mode_tunnel.c +++ b/trunk/net/ipv4/xfrm4_mode_tunnel.c @@ -139,7 +139,6 @@ static struct xfrm_mode xfrm4_tunnel_mode = { .output = xfrm4_tunnel_output, .owner = THIS_MODULE, .encap = XFRM_MODE_TUNNEL, - .flags = XFRM_MODE_FLAG_TUNNEL, }; static int __init xfrm4_tunnel_init(void) diff --git a/trunk/net/ipv4/xfrm4_output.c b/trunk/net/ipv4/xfrm4_output.c index c4a7156962bd..a4edd666318b 100644 --- a/trunk/net/ipv4/xfrm4_output.c +++ b/trunk/net/ipv4/xfrm4_output.c @@ -47,7 +47,7 @@ static inline int xfrm4_output_one(struct sk_buff *skb) struct iphdr *iph; int err; - if (x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) { + if (x->props.mode == XFRM_MODE_TUNNEL) { err = xfrm4_tunnel_check_size(skb); if (err) goto error_nolock; diff --git a/trunk/net/ipv4/xfrm4_policy.c b/trunk/net/ipv4/xfrm4_policy.c index cc86fb110dd8..329825ca68fe 100644 --- a/trunk/net/ipv4/xfrm4_policy.c +++ b/trunk/net/ipv4/xfrm4_policy.c @@ -117,7 +117,7 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int header_len += xfrm[i]->props.header_len; trailer_len += xfrm[i]->props.trailer_len; - if (xfrm[i]->props.mode != XFRM_MODE_TRANSPORT) { + if (xfrm[i]->props.mode == XFRM_MODE_TUNNEL) { unsigned short encap_family = xfrm[i]->props.family; switch (encap_family) { case AF_INET: @@ -151,6 +151,7 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int i = 0; for (; dst_prev != &rt->u.dst; dst_prev = dst_prev->child) { struct xfrm_dst *x = (struct xfrm_dst*)dst_prev; + struct xfrm_state_afinfo *afinfo; x->u.rt.fl = *fl; dst_prev->xfrm = xfrm[i++]; @@ -168,17 +169,27 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int /* Copy neighbout for reachability confirmation */ dst_prev->neighbour = neigh_clone(rt->u.dst.neighbour); dst_prev->input = rt->u.dst.input; - dst_prev->output = dst_prev->xfrm->outer_mode->afinfo->output; - if (rt0->peer) - atomic_inc(&rt0->peer->refcnt); - x->u.rt.peer = rt0->peer; + /* XXX: When IPv6 module can be unloaded, we should manage reference + * to xfrm6_output in afinfo->output. Miyazawa + * */ + afinfo = xfrm_state_get_afinfo(dst_prev->xfrm->props.family); + if (!afinfo) { + dst = *dst_p; + err = -EAFNOSUPPORT; + goto error; + } + dst_prev->output = afinfo->output; + xfrm_state_put_afinfo(afinfo); + if (dst_prev->xfrm->props.family == AF_INET && rt->peer) + atomic_inc(&rt->peer->refcnt); + x->u.rt.peer = rt->peer; /* Sheit... I remember I did this right. Apparently, * it was magically lost, so this code needs audit */ x->u.rt.rt_flags = rt0->rt_flags&(RTCF_BROADCAST|RTCF_MULTICAST|RTCF_LOCAL); - x->u.rt.rt_type = rt0->rt_type; + x->u.rt.rt_type = rt->rt_type; x->u.rt.rt_src = rt0->rt_src; x->u.rt.rt_dst = rt0->rt_dst; - x->u.rt.rt_gateway = rt0->rt_gateway; + x->u.rt.rt_gateway = rt->rt_gateway; x->u.rt.rt_spec_dst = rt0->rt_spec_dst; x->u.rt.idev = rt0->idev; in_dev_hold(rt0->idev); @@ -280,7 +291,7 @@ static void xfrm4_dst_destroy(struct dst_entry *dst) if (likely(xdst->u.rt.idev)) in_dev_put(xdst->u.rt.idev); - if (likely(xdst->u.rt.peer)) + if (dst->xfrm && dst->xfrm->props.family == AF_INET && likely(xdst->u.rt.peer)) inet_putpeer(xdst->u.rt.peer); xfrm_dst_destroy(xdst); } diff --git a/trunk/net/ipv4/xfrm4_state.c b/trunk/net/ipv4/xfrm4_state.c index 13d54a1c3337..93e2c061cdda 100644 --- a/trunk/net/ipv4/xfrm4_state.c +++ b/trunk/net/ipv4/xfrm4_state.c @@ -49,7 +49,6 @@ __xfrm4_init_tempsel(struct xfrm_state *x, struct flowi *fl, static struct xfrm_state_afinfo xfrm4_state_afinfo = { .family = AF_INET, - .owner = THIS_MODULE, .init_flags = xfrm4_init_flags, .init_tempsel = __xfrm4_init_tempsel, .output = xfrm4_output, diff --git a/trunk/net/ipv4/xfrm4_tunnel.c b/trunk/net/ipv4/xfrm4_tunnel.c index 326845195620..1312417608e2 100644 --- a/trunk/net/ipv4/xfrm4_tunnel.c +++ b/trunk/net/ipv4/xfrm4_tunnel.c @@ -18,7 +18,7 @@ static int ipip_output(struct xfrm_state *x, struct sk_buff *skb) static int ipip_xfrm_rcv(struct xfrm_state *x, struct sk_buff *skb) { - return ip_hdr(skb)->protocol; + return IPPROTO_IP; } static int ipip_init_state(struct xfrm_state *x) @@ -48,25 +48,20 @@ static struct xfrm_type ipip_type = { .output = ipip_output }; -static int xfrm_tunnel_rcv(struct sk_buff *skb) -{ - return xfrm4_rcv_spi(skb, IPPROTO_IP, ip_hdr(skb)->saddr); -} - static int xfrm_tunnel_err(struct sk_buff *skb, u32 info) { return -ENOENT; } static struct xfrm_tunnel xfrm_tunnel_handler = { - .handler = xfrm_tunnel_rcv, + .handler = xfrm4_rcv, .err_handler = xfrm_tunnel_err, .priority = 2, }; #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) static struct xfrm_tunnel xfrm64_tunnel_handler = { - .handler = xfrm_tunnel_rcv, + .handler = xfrm4_rcv, .err_handler = xfrm_tunnel_err, .priority = 2, }; diff --git a/trunk/net/ipv6/addrconf.c b/trunk/net/ipv6/addrconf.c index 348bd8d06112..52d10d213217 100644 --- a/trunk/net/ipv6/addrconf.c +++ b/trunk/net/ipv6/addrconf.c @@ -255,6 +255,11 @@ static void addrconf_mod_timer(struct inet6_ifaddr *ifp, static int snmp6_alloc_dev(struct inet6_dev *idev) { + int err = -ENOMEM; + + if (!idev || !idev->dev) + return -EINVAL; + if (snmp_mib_init((void **)idev->stats.ipv6, sizeof(struct ipstats_mib), __alignof__(struct ipstats_mib)) < 0) @@ -275,14 +280,15 @@ static int snmp6_alloc_dev(struct inet6_dev *idev) err_icmp: snmp_mib_free((void **)idev->stats.ipv6); err_ip: - return -ENOMEM; + return err; } -static void snmp6_free_dev(struct inet6_dev *idev) +static int snmp6_free_dev(struct inet6_dev *idev) { snmp_mib_free((void **)idev->stats.icmpv6msg); snmp_mib_free((void **)idev->stats.icmpv6); snmp_mib_free((void **)idev->stats.ipv6); + return 0; } /* Nobody refers to this device, we may destroy it. */ diff --git a/trunk/net/ipv6/af_inet6.c b/trunk/net/ipv6/af_inet6.c index 1b1caf3aa1c1..bc929381fa46 100644 --- a/trunk/net/ipv6/af_inet6.c +++ b/trunk/net/ipv6/af_inet6.c @@ -747,7 +747,6 @@ static void cleanup_ipv6_mibs(void) { snmp_mib_free((void **)ipv6_statistics); snmp_mib_free((void **)icmpv6_statistics); - snmp_mib_free((void **)icmpv6msg_statistics); snmp_mib_free((void **)udp_stats_in6); snmp_mib_free((void **)udplite_stats_in6); } diff --git a/trunk/net/ipv6/ah6.c b/trunk/net/ipv6/ah6.c index 67cd06613a25..f9f689162692 100644 --- a/trunk/net/ipv6/ah6.c +++ b/trunk/net/ipv6/ah6.c @@ -344,8 +344,6 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb) pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) goto out; - skb->ip_summed = CHECKSUM_NONE; - hdr_len = skb->data - skb_network_header(skb); ah = (struct ip_auth_hdr *)skb->data; ahp = x->data; @@ -477,15 +475,8 @@ static int ah6_init_state(struct xfrm_state *x) x->props.header_len = XFRM_ALIGN8(sizeof(struct ip_auth_hdr) + ahp->icv_trunc_len); - switch (x->props.mode) { - case XFRM_MODE_BEET: - case XFRM_MODE_TRANSPORT: - break; - case XFRM_MODE_TUNNEL: + if (x->props.mode == XFRM_MODE_TUNNEL) x->props.header_len += sizeof(struct ipv6hdr); - default: - goto error; - } x->data = ahp; return 0; diff --git a/trunk/net/ipv6/esp6.c b/trunk/net/ipv6/esp6.c index b0715432e454..9eb928598351 100644 --- a/trunk/net/ipv6/esp6.c +++ b/trunk/net/ipv6/esp6.c @@ -354,15 +354,8 @@ static int esp6_init_state(struct xfrm_state *x) (x->ealg->alg_key_len + 7) / 8)) goto error; x->props.header_len = sizeof(struct ip_esp_hdr) + esp->conf.ivlen; - switch (x->props.mode) { - case XFRM_MODE_BEET: - case XFRM_MODE_TRANSPORT: - break; - case XFRM_MODE_TUNNEL: + if (x->props.mode == XFRM_MODE_TUNNEL) x->props.header_len += sizeof(struct ipv6hdr); - default: - goto error; - } x->data = esp; return 0; diff --git a/trunk/net/ipv6/inet6_hashtables.c b/trunk/net/ipv6/inet6_hashtables.c index d6f1026f1943..1c2c27655435 100644 --- a/trunk/net/ipv6/inet6_hashtables.c +++ b/trunk/net/ipv6/inet6_hashtables.c @@ -261,7 +261,7 @@ int inet6_hash_connect(struct inet_timewait_death_row *death_row, struct inet_timewait_sock *tw = NULL; inet_get_local_port_range(&low, &high); - remaining = (high - low) + 1; + remaining = high - low; local_bh_disable(); for (i = 1; i <= remaining; i++) { diff --git a/trunk/net/ipv6/ip6_flowlabel.c b/trunk/net/ipv6/ip6_flowlabel.c index b12cc22e7745..217d60f9fc80 100644 --- a/trunk/net/ipv6/ip6_flowlabel.c +++ b/trunk/net/ipv6/ip6_flowlabel.c @@ -154,10 +154,8 @@ static void ip6_fl_gc(unsigned long dummy) write_unlock(&ip6_fl_lock); } -static struct ip6_flowlabel *fl_intern(struct ip6_flowlabel *fl, __be32 label) +static int fl_intern(struct ip6_flowlabel *fl, __be32 label) { - struct ip6_flowlabel *lfl; - fl->label = label & IPV6_FLOWLABEL_MASK; write_lock_bh(&ip6_fl_lock); @@ -165,26 +163,12 @@ static struct ip6_flowlabel *fl_intern(struct ip6_flowlabel *fl, __be32 label) for (;;) { fl->label = htonl(net_random())&IPV6_FLOWLABEL_MASK; if (fl->label) { + struct ip6_flowlabel *lfl; lfl = __fl_lookup(fl->label); if (lfl == NULL) break; } } - } else { - /* - * we dropper the ip6_fl_lock, so this entry could reappear - * and we need to recheck with it. - * - * OTOH no need to search the active socket first, like it is - * done in ipv6_flowlabel_opt - sock is locked, so new entry - * with the same label can only appear on another sock - */ - lfl = __fl_lookup(fl->label); - if (lfl != NULL) { - atomic_inc(&lfl->users); - write_unlock_bh(&ip6_fl_lock); - return lfl; - } } fl->lastuse = jiffies; @@ -192,7 +176,7 @@ static struct ip6_flowlabel *fl_intern(struct ip6_flowlabel *fl, __be32 label) fl_ht[FL_HASH(fl->label)] = fl; atomic_inc(&fl_size); write_unlock_bh(&ip6_fl_lock); - return NULL; + return 0; } @@ -206,17 +190,14 @@ struct ip6_flowlabel * fl6_sock_lookup(struct sock *sk, __be32 label) label &= IPV6_FLOWLABEL_MASK; - read_lock_bh(&ip6_sk_fl_lock); for (sfl=np->ipv6_fl_list; sfl; sfl = sfl->next) { struct ip6_flowlabel *fl = sfl->fl; if (fl->label == label) { fl->lastuse = jiffies; atomic_inc(&fl->users); - read_unlock_bh(&ip6_sk_fl_lock); return fl; } } - read_unlock_bh(&ip6_sk_fl_lock); return NULL; } @@ -428,16 +409,6 @@ static int ipv6_opt_cmp(struct ipv6_txoptions *o1, struct ipv6_txoptions *o2) return 0; } -static inline void fl_link(struct ipv6_pinfo *np, struct ipv6_fl_socklist *sfl, - struct ip6_flowlabel *fl) -{ - write_lock_bh(&ip6_sk_fl_lock); - sfl->fl = fl; - sfl->next = np->ipv6_fl_list; - np->ipv6_fl_list = sfl; - write_unlock_bh(&ip6_sk_fl_lock); -} - int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen) { int err; @@ -445,8 +416,7 @@ int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen) struct in6_flowlabel_req freq; struct ipv6_fl_socklist *sfl1=NULL; struct ipv6_fl_socklist *sfl, **sflp; - struct ip6_flowlabel *fl, *fl1 = NULL; - + struct ip6_flowlabel *fl; if (optlen < sizeof(freq)) return -EINVAL; @@ -502,6 +472,8 @@ int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen) sfl1 = kmalloc(sizeof(*sfl1), GFP_KERNEL); if (freq.flr_label) { + struct ip6_flowlabel *fl1 = NULL; + err = -EEXIST; read_lock_bh(&ip6_sk_fl_lock); for (sfl = np->ipv6_fl_list; sfl; sfl = sfl->next) { @@ -520,7 +492,6 @@ int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen) if (fl1 == NULL) fl1 = fl_lookup(freq.flr_label); if (fl1) { -recheck: err = -EEXIST; if (freq.flr_flags&IPV6_FL_F_EXCL) goto release; @@ -542,7 +513,11 @@ int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen) fl1->linger = fl->linger; if ((long)(fl->expires - fl1->expires) > 0) fl1->expires = fl->expires; - fl_link(np, sfl1, fl1); + write_lock_bh(&ip6_sk_fl_lock); + sfl1->fl = fl1; + sfl1->next = np->ipv6_fl_list; + np->ipv6_fl_list = sfl1; + write_unlock_bh(&ip6_sk_fl_lock); fl_free(fl); return 0; @@ -559,9 +534,9 @@ int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen) if (sfl1 == NULL || (err = mem_check(sk)) != 0) goto done; - fl1 = fl_intern(fl, freq.flr_label); - if (fl1 != NULL) - goto recheck; + err = fl_intern(fl, freq.flr_label); + if (err) + goto done; if (!freq.flr_label) { if (copy_to_user(&((struct in6_flowlabel_req __user *) optval)->flr_label, @@ -570,7 +545,9 @@ int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen) } } - fl_link(np, sfl1, fl); + sfl1->fl = fl; + sfl1->next = np->ipv6_fl_list; + np->ipv6_fl_list = sfl1; return 0; default: diff --git a/trunk/net/ipv6/ipcomp6.c b/trunk/net/ipv6/ipcomp6.c index 80ef2a1d39fd..28fc8edfdc3a 100644 --- a/trunk/net/ipv6/ipcomp6.c +++ b/trunk/net/ipv6/ipcomp6.c @@ -411,15 +411,8 @@ static int ipcomp6_init_state(struct xfrm_state *x) goto out; x->props.header_len = 0; - switch (x->props.mode) { - case XFRM_MODE_BEET: - case XFRM_MODE_TRANSPORT: - break; - case XFRM_MODE_TUNNEL: + if (x->props.mode == XFRM_MODE_TUNNEL) x->props.header_len += sizeof(struct ipv6hdr); - default: - goto error; - } mutex_lock(&ipcomp6_resource_mutex); if (!ipcomp6_alloc_scratches()) diff --git a/trunk/net/ipv6/ndisc.c b/trunk/net/ipv6/ndisc.c index 20cfc90d5597..6cc33dc83d1c 100644 --- a/trunk/net/ipv6/ndisc.c +++ b/trunk/net/ipv6/ndisc.c @@ -1658,26 +1658,30 @@ int ndisc_ifinfo_sysctl_change(struct ctl_table *ctl, int write, struct file * f struct inet6_dev *idev; int ret; - if ((strcmp(ctl->procname, "retrans_time") == 0) || - (strcmp(ctl->procname, "base_reachable_time") == 0)) + if (ctl->ctl_name == NET_NEIGH_RETRANS_TIME || + ctl->ctl_name == NET_NEIGH_REACHABLE_TIME) ndisc_warn_deprecated_sysctl(ctl, "syscall", dev ? dev->name : "default"); - if (strcmp(ctl->procname, "retrans_time") == 0) + switch (ctl->ctl_name) { + case NET_NEIGH_RETRANS_TIME: ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos); - - else if (strcmp(ctl->procname, "base_reachable_time") == 0) + break; + case NET_NEIGH_REACHABLE_TIME: ret = proc_dointvec_jiffies(ctl, write, filp, buffer, lenp, ppos); - - else if ((strcmp(ctl->procname, "retrans_time_ms") == 0) || - (strcmp(ctl->procname, "base_reacable_time_ms") == 0)) + break; + case NET_NEIGH_RETRANS_TIME_MS: + case NET_NEIGH_REACHABLE_TIME_MS: ret = proc_dointvec_ms_jiffies(ctl, write, filp, buffer, lenp, ppos); - else + break; + default: ret = -1; + } if (write && ret == 0 && dev && (idev = in6_dev_get(dev)) != NULL) { - if (ctl->data == &idev->nd_parms->base_reachable_time) + if (ctl->ctl_name == NET_NEIGH_REACHABLE_TIME || + ctl->ctl_name == NET_NEIGH_REACHABLE_TIME_MS) idev->nd_parms->reachable_time = neigh_rand_reach_time(idev->nd_parms->base_reachable_time); idev->tstamp = jiffies; inet6_ifinfo_notify(RTM_NEWLINK, idev); diff --git a/trunk/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/trunk/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c index ad74bab05047..0e40948f4fc6 100644 --- a/trunk/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c +++ b/trunk/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c @@ -306,6 +306,7 @@ static struct nf_hook_ops ipv6_conntrack_ops[] = { #ifdef CONFIG_SYSCTL static ctl_table nf_ct_ipv6_sysctl_table[] = { { + .ctl_name = NET_NF_CONNTRACK_FRAG6_TIMEOUT, .procname = "nf_conntrack_frag6_timeout", .data = &nf_frags_ctl.timeout, .maxlen = sizeof(unsigned int), diff --git a/trunk/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/trunk/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c index fd9123f3dc04..fbdc66920de4 100644 --- a/trunk/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c +++ b/trunk/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c @@ -260,6 +260,7 @@ static int icmpv6_nlattr_to_tuple(struct nlattr *tb[], static struct ctl_table_header *icmpv6_sysctl_header; static struct ctl_table icmpv6_sysctl_table[] = { { + .ctl_name = NET_NF_CONNTRACK_ICMPV6_TIMEOUT, .procname = "nf_conntrack_icmpv6_timeout", .data = &nf_ct_icmpv6_timeout, .maxlen = sizeof(unsigned int), diff --git a/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c b/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c index e170c67c47a5..726fafd41961 100644 --- a/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c @@ -130,6 +130,22 @@ static inline void frag_kfree_skb(struct sk_buff *skb, unsigned int *work) kfree_skb(skb); } +static void nf_frag_free(struct inet_frag_queue *q) +{ + kfree(container_of(q, struct nf_ct_frag6_queue, q)); +} + +static inline struct nf_ct_frag6_queue *frag_alloc_queue(void) +{ + struct nf_ct_frag6_queue *fq; + + fq = kzalloc(sizeof(struct nf_ct_frag6_queue), GFP_ATOMIC); + if (fq == NULL) + return NULL; + atomic_add(sizeof(struct nf_ct_frag6_queue), &nf_frags.mem); + return fq; +} + /* Destruction primitives. */ static __inline__ void fq_put(struct nf_ct_frag6_queue *fq) @@ -152,10 +168,7 @@ static void nf_ct_frag6_evictor(void) static void nf_ct_frag6_expire(unsigned long data) { - struct nf_ct_frag6_queue *fq; - - fq = container_of((struct inet_frag_queue *)data, - struct nf_ct_frag6_queue, q); + struct nf_ct_frag6_queue *fq = (struct nf_ct_frag6_queue *) data; spin_lock(&fq->q.lock); @@ -171,29 +184,89 @@ static void nf_ct_frag6_expire(unsigned long data) /* Creation primitives. */ -static __inline__ struct nf_ct_frag6_queue * -fq_find(__be32 id, struct in6_addr *src, struct in6_addr *dst) +static struct nf_ct_frag6_queue *nf_ct_frag6_intern(unsigned int hash, + struct nf_ct_frag6_queue *fq_in) { - struct inet_frag_queue *q; - struct ip6_create_arg arg; - unsigned int hash; + struct nf_ct_frag6_queue *fq; +#ifdef CONFIG_SMP + struct hlist_node *n; +#endif + + write_lock(&nf_frags.lock); +#ifdef CONFIG_SMP + hlist_for_each_entry(fq, n, &nf_frags.hash[hash], q.list) { + if (fq->id == fq_in->id && + ipv6_addr_equal(&fq_in->saddr, &fq->saddr) && + ipv6_addr_equal(&fq_in->daddr, &fq->daddr)) { + atomic_inc(&fq->q.refcnt); + write_unlock(&nf_frags.lock); + fq_in->q.last_in |= COMPLETE; + fq_put(fq_in); + return fq; + } + } +#endif + fq = fq_in; + + if (!mod_timer(&fq->q.timer, jiffies + nf_frags_ctl.timeout)) + atomic_inc(&fq->q.refcnt); + + atomic_inc(&fq->q.refcnt); + hlist_add_head(&fq->q.list, &nf_frags.hash[hash]); + INIT_LIST_HEAD(&fq->q.lru_list); + list_add_tail(&fq->q.lru_list, &nf_frags.lru_list); + nf_frags.nqueues++; + write_unlock(&nf_frags.lock); + return fq; +} - arg.id = id; - arg.src = src; - arg.dst = dst; - hash = ip6qhashfn(id, src, dst); - q = inet_frag_find(&nf_frags, &arg, hash); - if (q == NULL) +static struct nf_ct_frag6_queue * +nf_ct_frag6_create(unsigned int hash, __be32 id, struct in6_addr *src, struct in6_addr *dst) +{ + struct nf_ct_frag6_queue *fq; + + if ((fq = frag_alloc_queue()) == NULL) { + pr_debug("Can't alloc new queue\n"); goto oom; + } + + fq->id = id; + ipv6_addr_copy(&fq->saddr, src); + ipv6_addr_copy(&fq->daddr, dst); + + setup_timer(&fq->q.timer, nf_ct_frag6_expire, (unsigned long)fq); + spin_lock_init(&fq->q.lock); + atomic_set(&fq->q.refcnt, 1); - return container_of(q, struct nf_ct_frag6_queue, q); + return nf_ct_frag6_intern(hash, fq); oom: - pr_debug("Can't alloc new queue\n"); return NULL; } +static __inline__ struct nf_ct_frag6_queue * +fq_find(__be32 id, struct in6_addr *src, struct in6_addr *dst) +{ + struct nf_ct_frag6_queue *fq; + struct hlist_node *n; + unsigned int hash = ip6qhashfn(id, src, dst); + + read_lock(&nf_frags.lock); + hlist_for_each_entry(fq, n, &nf_frags.hash[hash], q.list) { + if (fq->id == id && + ipv6_addr_equal(src, &fq->saddr) && + ipv6_addr_equal(dst, &fq->daddr)) { + atomic_inc(&fq->q.refcnt); + read_unlock(&nf_frags.lock); + return fq; + } + } + read_unlock(&nf_frags.lock); + + return nf_ct_frag6_create(hash, id, src, dst); +} + static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb, struct frag_hdr *fhdr, int nhoff) @@ -676,12 +749,9 @@ int nf_ct_frag6_init(void) { nf_frags.ctl = &nf_frags_ctl; nf_frags.hashfn = nf_hashfn; - nf_frags.constructor = ip6_frag_init; - nf_frags.destructor = NULL; + nf_frags.destructor = nf_frag_free; nf_frags.skb_free = nf_skb_free; nf_frags.qsize = sizeof(struct nf_ct_frag6_queue); - nf_frags.match = ip6_frag_match; - nf_frags.frag_expire = nf_ct_frag6_expire; inet_frags_init(&nf_frags); return 0; diff --git a/trunk/net/ipv6/reassembly.c b/trunk/net/ipv6/reassembly.c index 76c88a93b9b5..6ad19cfc2025 100644 --- a/trunk/net/ipv6/reassembly.c +++ b/trunk/net/ipv6/reassembly.c @@ -143,18 +143,6 @@ static unsigned int ip6_hashfn(struct inet_frag_queue *q) return ip6qhashfn(fq->id, &fq->saddr, &fq->daddr); } -int ip6_frag_match(struct inet_frag_queue *q, void *a) -{ - struct frag_queue *fq; - struct ip6_create_arg *arg = a; - - fq = container_of(q, struct frag_queue, q); - return (fq->id == arg->id && - ipv6_addr_equal(&fq->saddr, arg->src) && - ipv6_addr_equal(&fq->daddr, arg->dst)); -} -EXPORT_SYMBOL(ip6_frag_match); - /* Memory Tracking Functions. */ static inline void frag_kfree_skb(struct sk_buff *skb, int *work) { @@ -164,16 +152,20 @@ static inline void frag_kfree_skb(struct sk_buff *skb, int *work) kfree_skb(skb); } -void ip6_frag_init(struct inet_frag_queue *q, void *a) +static void ip6_frag_free(struct inet_frag_queue *fq) { - struct frag_queue *fq = container_of(q, struct frag_queue, q); - struct ip6_create_arg *arg = a; + kfree(container_of(fq, struct frag_queue, q)); +} + +static inline struct frag_queue *frag_alloc_queue(void) +{ + struct frag_queue *fq = kzalloc(sizeof(struct frag_queue), GFP_ATOMIC); - fq->id = arg->id; - ipv6_addr_copy(&fq->saddr, arg->src); - ipv6_addr_copy(&fq->daddr, arg->dst); + if(!fq) + return NULL; + atomic_add(sizeof(struct frag_queue), &ip6_frags.mem); + return fq; } -EXPORT_SYMBOL(ip6_frag_init); /* Destruction primitives. */ @@ -201,11 +193,9 @@ static void ip6_evictor(struct inet6_dev *idev) static void ip6_frag_expire(unsigned long data) { - struct frag_queue *fq; + struct frag_queue *fq = (struct frag_queue *) data; struct net_device *dev = NULL; - fq = container_of((struct inet_frag_queue *)data, struct frag_queue, q); - spin_lock(&fq->q.lock); if (fq->q.last_in & COMPLETE) @@ -240,30 +230,98 @@ static void ip6_frag_expire(unsigned long data) fq_put(fq); } -static __inline__ struct frag_queue * -fq_find(__be32 id, struct in6_addr *src, struct in6_addr *dst, - struct inet6_dev *idev) +/* Creation primitives. */ + + +static struct frag_queue *ip6_frag_intern(struct frag_queue *fq_in) { - struct inet_frag_queue *q; - struct ip6_create_arg arg; + struct frag_queue *fq; unsigned int hash; +#ifdef CONFIG_SMP + struct hlist_node *n; +#endif - arg.id = id; - arg.src = src; - arg.dst = dst; - hash = ip6qhashfn(id, src, dst); + write_lock(&ip6_frags.lock); + hash = ip6qhashfn(fq_in->id, &fq_in->saddr, &fq_in->daddr); +#ifdef CONFIG_SMP + hlist_for_each_entry(fq, n, &ip6_frags.hash[hash], q.list) { + if (fq->id == fq_in->id && + ipv6_addr_equal(&fq_in->saddr, &fq->saddr) && + ipv6_addr_equal(&fq_in->daddr, &fq->daddr)) { + atomic_inc(&fq->q.refcnt); + write_unlock(&ip6_frags.lock); + fq_in->q.last_in |= COMPLETE; + fq_put(fq_in); + return fq; + } + } +#endif + fq = fq_in; - q = inet_frag_find(&ip6_frags, &arg, hash); - if (q == NULL) + if (!mod_timer(&fq->q.timer, jiffies + ip6_frags_ctl.timeout)) + atomic_inc(&fq->q.refcnt); + + atomic_inc(&fq->q.refcnt); + hlist_add_head(&fq->q.list, &ip6_frags.hash[hash]); + INIT_LIST_HEAD(&fq->q.lru_list); + list_add_tail(&fq->q.lru_list, &ip6_frags.lru_list); + ip6_frags.nqueues++; + write_unlock(&ip6_frags.lock); + return fq; +} + + +static struct frag_queue * +ip6_frag_create(__be32 id, struct in6_addr *src, struct in6_addr *dst, + struct inet6_dev *idev) +{ + struct frag_queue *fq; + + if ((fq = frag_alloc_queue()) == NULL) goto oom; - return container_of(q, struct frag_queue, q); + fq->id = id; + ipv6_addr_copy(&fq->saddr, src); + ipv6_addr_copy(&fq->daddr, dst); + + init_timer(&fq->q.timer); + fq->q.timer.function = ip6_frag_expire; + fq->q.timer.data = (long) fq; + spin_lock_init(&fq->q.lock); + atomic_set(&fq->q.refcnt, 1); + + return ip6_frag_intern(fq); oom: IP6_INC_STATS_BH(idev, IPSTATS_MIB_REASMFAILS); return NULL; } +static __inline__ struct frag_queue * +fq_find(__be32 id, struct in6_addr *src, struct in6_addr *dst, + struct inet6_dev *idev) +{ + struct frag_queue *fq; + struct hlist_node *n; + unsigned int hash; + + read_lock(&ip6_frags.lock); + hash = ip6qhashfn(id, src, dst); + hlist_for_each_entry(fq, n, &ip6_frags.hash[hash], q.list) { + if (fq->id == id && + ipv6_addr_equal(src, &fq->saddr) && + ipv6_addr_equal(dst, &fq->daddr)) { + atomic_inc(&fq->q.refcnt); + read_unlock(&ip6_frags.lock); + return fq; + } + } + read_unlock(&ip6_frags.lock); + + return ip6_frag_create(id, src, dst, idev); +} + + static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb, struct frag_hdr *fhdr, int nhoff) { @@ -639,11 +697,8 @@ void __init ipv6_frag_init(void) ip6_frags.ctl = &ip6_frags_ctl; ip6_frags.hashfn = ip6_hashfn; - ip6_frags.constructor = ip6_frag_init; - ip6_frags.destructor = NULL; + ip6_frags.destructor = ip6_frag_free; ip6_frags.skb_free = NULL; ip6_frags.qsize = sizeof(struct frag_queue); - ip6_frags.match = ip6_frag_match; - ip6_frags.frag_expire = ip6_frag_expire; inet_frags_init(&ip6_frags); } diff --git a/trunk/net/ipv6/route.c b/trunk/net/ipv6/route.c index 95f8e4a62f68..cce9941c11c6 100644 --- a/trunk/net/ipv6/route.c +++ b/trunk/net/ipv6/route.c @@ -2397,6 +2397,7 @@ int ipv6_sysctl_rtcache_flush(ctl_table *ctl, int write, struct file * filp, ctl_table ipv6_route_table[] = { { + .ctl_name = NET_IPV6_ROUTE_FLUSH, .procname = "flush", .data = &flush_delay, .maxlen = sizeof(int), diff --git a/trunk/net/ipv6/xfrm6_input.c b/trunk/net/ipv6/xfrm6_input.c index 515783707e86..02f69e544f6f 100644 --- a/trunk/net/ipv6/xfrm6_input.c +++ b/trunk/net/ipv6/xfrm6_input.c @@ -16,7 +16,7 @@ #include #include -int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi) +int xfrm6_rcv_spi(struct sk_buff *skb, __be32 spi) { int err; __be32 seq; @@ -24,9 +24,11 @@ int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi) struct xfrm_state *x; int xfrm_nr = 0; int decaps = 0; + int nexthdr; unsigned int nhoff; nhoff = IP6CB(skb)->nhoff; + nexthdr = skb_network_header(skb)[nhoff]; seq = 0; if (!spi && (err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0) @@ -39,7 +41,7 @@ int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi) goto drop; x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, spi, - nexthdr, AF_INET6); + nexthdr != IPPROTO_IPIP ? nexthdr : IPPROTO_IPV6, AF_INET6); if (x == NULL) goto drop; spin_lock(&x->lock); @@ -68,10 +70,10 @@ int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi) xfrm_vec[xfrm_nr++] = x; - if (x->outer_mode->input(x, skb)) + if (x->mode->input(x, skb)) goto drop; - if (x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) { + if (x->props.mode == XFRM_MODE_TUNNEL) { /* XXX */ decaps = 1; break; } @@ -97,6 +99,7 @@ int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi) memcpy(skb->sp->xvec + skb->sp->len, xfrm_vec, xfrm_nr * sizeof(xfrm_vec[0])); skb->sp->len += xfrm_nr; + skb->ip_summed = CHECKSUM_NONE; nf_reset(skb); @@ -132,8 +135,7 @@ EXPORT_SYMBOL(xfrm6_rcv_spi); int xfrm6_rcv(struct sk_buff *skb) { - return xfrm6_rcv_spi(skb, skb_network_header(skb)[IP6CB(skb)->nhoff], - 0); + return xfrm6_rcv_spi(skb, 0); } EXPORT_SYMBOL(xfrm6_rcv); diff --git a/trunk/net/ipv6/xfrm6_mode_beet.c b/trunk/net/ipv6/xfrm6_mode_beet.c index 2bfb4f05c14c..13bb1e856764 100644 --- a/trunk/net/ipv6/xfrm6_mode_beet.c +++ b/trunk/net/ipv6/xfrm6_mode_beet.c @@ -79,7 +79,6 @@ static struct xfrm_mode xfrm6_beet_mode = { .output = xfrm6_beet_output, .owner = THIS_MODULE, .encap = XFRM_MODE_BEET, - .flags = XFRM_MODE_FLAG_TUNNEL, }; static int __init xfrm6_beet_init(void) diff --git a/trunk/net/ipv6/xfrm6_mode_ro.c b/trunk/net/ipv6/xfrm6_mode_ro.c index a7bc8c62317a..957ae36b6695 100644 --- a/trunk/net/ipv6/xfrm6_mode_ro.c +++ b/trunk/net/ipv6/xfrm6_mode_ro.c @@ -58,7 +58,16 @@ static int xfrm6_ro_output(struct xfrm_state *x, struct sk_buff *skb) return 0; } +/* + * Do nothing about routing optimization header unlike IPsec. + */ +static int xfrm6_ro_input(struct xfrm_state *x, struct sk_buff *skb) +{ + return 0; +} + static struct xfrm_mode xfrm6_ro_mode = { + .input = xfrm6_ro_input, .output = xfrm6_ro_output, .owner = THIS_MODULE, .encap = XFRM_MODE_ROUTEOPTIMIZATION, diff --git a/trunk/net/ipv6/xfrm6_mode_tunnel.c b/trunk/net/ipv6/xfrm6_mode_tunnel.c index fd84e2217274..ea2283879112 100644 --- a/trunk/net/ipv6/xfrm6_mode_tunnel.c +++ b/trunk/net/ipv6/xfrm6_mode_tunnel.c @@ -118,7 +118,6 @@ static struct xfrm_mode xfrm6_tunnel_mode = { .output = xfrm6_tunnel_output, .owner = THIS_MODULE, .encap = XFRM_MODE_TUNNEL, - .flags = XFRM_MODE_FLAG_TUNNEL, }; static int __init xfrm6_tunnel_init(void) diff --git a/trunk/net/ipv6/xfrm6_output.c b/trunk/net/ipv6/xfrm6_output.c index 656976760ad4..a5a32c17249d 100644 --- a/trunk/net/ipv6/xfrm6_output.c +++ b/trunk/net/ipv6/xfrm6_output.c @@ -50,7 +50,7 @@ static inline int xfrm6_output_one(struct sk_buff *skb) struct ipv6hdr *iph; int err; - if (x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) { + if (x->props.mode == XFRM_MODE_TUNNEL) { err = xfrm6_tunnel_check_size(skb); if (err) goto error_nolock; diff --git a/trunk/net/ipv6/xfrm6_policy.c b/trunk/net/ipv6/xfrm6_policy.c index 82e27b80d07d..15aa4c58c315 100644 --- a/trunk/net/ipv6/xfrm6_policy.c +++ b/trunk/net/ipv6/xfrm6_policy.c @@ -178,7 +178,8 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int __xfrm6_bundle_len_inc(&header_len, &nfheader_len, xfrm[i]); trailer_len += xfrm[i]->props.trailer_len; - if (xfrm[i]->props.mode != XFRM_MODE_TRANSPORT) { + if (xfrm[i]->props.mode == XFRM_MODE_TUNNEL || + xfrm[i]->props.mode == XFRM_MODE_ROUTEOPTIMIZATION) { unsigned short encap_family = xfrm[i]->props.family; switch(encap_family) { case AF_INET: @@ -214,6 +215,7 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int i = 0; for (; dst_prev != &rt->u.dst; dst_prev = dst_prev->child) { struct xfrm_dst *x = (struct xfrm_dst*)dst_prev; + struct xfrm_state_afinfo *afinfo; dst_prev->xfrm = xfrm[i++]; dst_prev->dev = rt->u.dst.dev; @@ -230,7 +232,18 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int /* Copy neighbour for reachability confirmation */ dst_prev->neighbour = neigh_clone(rt->u.dst.neighbour); dst_prev->input = rt->u.dst.input; - dst_prev->output = dst_prev->xfrm->outer_mode->afinfo->output; + /* XXX: When IPv4 is implemented as module and can be unloaded, + * we should manage reference to xfrm4_output in afinfo->output. + * Miyazawa + */ + afinfo = xfrm_state_get_afinfo(dst_prev->xfrm->props.family); + if (!afinfo) { + dst = *dst_p; + goto error; + } + + dst_prev->output = afinfo->output; + xfrm_state_put_afinfo(afinfo); /* Sheit... I remember I did this right. Apparently, * it was magically lost, so this code needs audit */ x->u.rt6.rt6i_flags = rt0->rt6i_flags&(RTCF_BROADCAST|RTCF_MULTICAST|RTCF_LOCAL); diff --git a/trunk/net/ipv6/xfrm6_state.c b/trunk/net/ipv6/xfrm6_state.c index b392bee396f1..cdadb4847469 100644 --- a/trunk/net/ipv6/xfrm6_state.c +++ b/trunk/net/ipv6/xfrm6_state.c @@ -93,8 +93,7 @@ __xfrm6_state_sort(struct xfrm_state **dst, struct xfrm_state **src, int n) /* Rule 4: select IPsec tunnel */ for (i = 0; i < n; i++) { if (src[i] && - (src[i]->props.mode == XFRM_MODE_TUNNEL || - src[i]->props.mode == XFRM_MODE_BEET)) { + src[i]->props.mode == XFRM_MODE_TUNNEL) { dst[j++] = src[i]; src[i] = NULL; } @@ -147,8 +146,7 @@ __xfrm6_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n) /* Rule 3: select IPsec tunnel */ for (i = 0; i < n; i++) { if (src[i] && - (src[i]->mode == XFRM_MODE_TUNNEL || - src[i]->mode == XFRM_MODE_BEET)) { + src[i]->mode == XFRM_MODE_TUNNEL) { dst[j++] = src[i]; src[i] = NULL; } @@ -170,7 +168,6 @@ __xfrm6_tmpl_sort(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n) static struct xfrm_state_afinfo xfrm6_state_afinfo = { .family = AF_INET6, - .owner = THIS_MODULE, .init_tempsel = __xfrm6_init_tempsel, .tmpl_sort = __xfrm6_tmpl_sort, .state_sort = __xfrm6_state_sort, diff --git a/trunk/net/ipv6/xfrm6_tunnel.c b/trunk/net/ipv6/xfrm6_tunnel.c index fae90ff31087..3f8a3abde67e 100644 --- a/trunk/net/ipv6/xfrm6_tunnel.c +++ b/trunk/net/ipv6/xfrm6_tunnel.c @@ -248,7 +248,7 @@ static int xfrm6_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) static int xfrm6_tunnel_input(struct xfrm_state *x, struct sk_buff *skb) { - return skb_network_header(skb)[IP6CB(skb)->nhoff]; + return 0; } static int xfrm6_tunnel_rcv(struct sk_buff *skb) @@ -257,7 +257,7 @@ static int xfrm6_tunnel_rcv(struct sk_buff *skb) __be32 spi; spi = xfrm6_tunnel_spi_lookup((xfrm_address_t *)&iph->saddr); - return xfrm6_rcv_spi(skb, IPPROTO_IPV6, spi) > 0 ? : 0; + return xfrm6_rcv_spi(skb, spi) > 0 ? : 0; } static int xfrm6_tunnel_err(struct sk_buff *skb, struct inet6_skb_parm *opt, diff --git a/trunk/net/irda/ircomm/ircomm_tty_attach.c b/trunk/net/irda/ircomm/ircomm_tty_attach.c index b5a13882c927..824309dabfe9 100644 --- a/trunk/net/irda/ircomm/ircomm_tty_attach.c +++ b/trunk/net/irda/ircomm/ircomm_tty_attach.c @@ -381,9 +381,18 @@ static void ircomm_tty_discovery_indication(discinfo_t *discovery, info.daddr = discovery->daddr; info.saddr = discovery->saddr; - self = (struct ircomm_tty_cb *) priv; - ircomm_tty_do_event(self, IRCOMM_TTY_DISCOVERY_INDICATION, - NULL, &info); + /* FIXME. We have a locking problem on the hashbin here. + * We probably need to use hashbin_find_next(), but we first + * need to ensure that "line" is unique. - Jean II */ + self = (struct ircomm_tty_cb *) hashbin_get_first(ircomm_tty); + while (self != NULL) { + IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;); + + ircomm_tty_do_event(self, IRCOMM_TTY_DISCOVERY_INDICATION, + NULL, &info); + + self = (struct ircomm_tty_cb *) hashbin_get_next(ircomm_tty); + } } /* diff --git a/trunk/net/irda/irsysctl.c b/trunk/net/irda/irsysctl.c index 525343a1c521..957e04feb0f7 100644 --- a/trunk/net/irda/irsysctl.c +++ b/trunk/net/irda/irsysctl.c @@ -31,6 +31,12 @@ #include /* irda_debug */ #include +#define NET_IRDA 412 /* Random number */ +enum { DISCOVERY=1, DEVNAME, DEBUG, FAST_POLL, DISCOVERY_SLOTS, + DISCOVERY_TIMEOUT, SLOT_TIMEOUT, MAX_BAUD_RATE, MIN_TX_TURN_TIME, + MAX_TX_DATA_SIZE, MAX_TX_WINDOW, MAX_NOREPLY_TIME, WARN_NOREPLY_TIME, + LAP_KEEPALIVE_TIME }; + extern int sysctl_discovery; extern int sysctl_discovery_slots; extern int sysctl_discovery_timeout; @@ -88,7 +94,7 @@ static int do_devname(ctl_table *table, int write, struct file *filp, /* One file */ static ctl_table irda_table[] = { { - .ctl_name = NET_IRDA_DISCOVERY, + .ctl_name = DISCOVERY, .procname = "discovery", .data = &sysctl_discovery, .maxlen = sizeof(int), @@ -96,7 +102,7 @@ static ctl_table irda_table[] = { .proc_handler = &proc_dointvec }, { - .ctl_name = NET_IRDA_DEVNAME, + .ctl_name = DEVNAME, .procname = "devname", .data = sysctl_devname, .maxlen = 65, @@ -106,7 +112,7 @@ static ctl_table irda_table[] = { }, #ifdef CONFIG_IRDA_DEBUG { - .ctl_name = NET_IRDA_DEBUG, + .ctl_name = DEBUG, .procname = "debug", .data = &irda_debug, .maxlen = sizeof(int), @@ -116,7 +122,7 @@ static ctl_table irda_table[] = { #endif #ifdef CONFIG_IRDA_FAST_RR { - .ctl_name = NET_IRDA_FAST_POLL, + .ctl_name = FAST_POLL, .procname = "fast_poll_increase", .data = &sysctl_fast_poll_increase, .maxlen = sizeof(int), @@ -125,7 +131,7 @@ static ctl_table irda_table[] = { }, #endif { - .ctl_name = NET_IRDA_DISCOVERY_SLOTS, + .ctl_name = DISCOVERY_SLOTS, .procname = "discovery_slots", .data = &sysctl_discovery_slots, .maxlen = sizeof(int), @@ -136,7 +142,7 @@ static ctl_table irda_table[] = { .extra2 = &max_discovery_slots }, { - .ctl_name = NET_IRDA_DISCOVERY_TIMEOUT, + .ctl_name = DISCOVERY_TIMEOUT, .procname = "discovery_timeout", .data = &sysctl_discovery_timeout, .maxlen = sizeof(int), @@ -144,7 +150,7 @@ static ctl_table irda_table[] = { .proc_handler = &proc_dointvec }, { - .ctl_name = NET_IRDA_SLOT_TIMEOUT, + .ctl_name = SLOT_TIMEOUT, .procname = "slot_timeout", .data = &sysctl_slot_timeout, .maxlen = sizeof(int), @@ -155,7 +161,7 @@ static ctl_table irda_table[] = { .extra2 = &max_slot_timeout }, { - .ctl_name = NET_IRDA_MAX_BAUD_RATE, + .ctl_name = MAX_BAUD_RATE, .procname = "max_baud_rate", .data = &sysctl_max_baud_rate, .maxlen = sizeof(int), @@ -166,7 +172,7 @@ static ctl_table irda_table[] = { .extra2 = &max_max_baud_rate }, { - .ctl_name = NET_IRDA_MIN_TX_TURN_TIME, + .ctl_name = MIN_TX_TURN_TIME, .procname = "min_tx_turn_time", .data = &sysctl_min_tx_turn_time, .maxlen = sizeof(int), @@ -177,7 +183,7 @@ static ctl_table irda_table[] = { .extra2 = &max_min_tx_turn_time }, { - .ctl_name = NET_IRDA_MAX_TX_DATA_SIZE, + .ctl_name = MAX_TX_DATA_SIZE, .procname = "max_tx_data_size", .data = &sysctl_max_tx_data_size, .maxlen = sizeof(int), @@ -188,7 +194,7 @@ static ctl_table irda_table[] = { .extra2 = &max_max_tx_data_size }, { - .ctl_name = NET_IRDA_MAX_TX_WINDOW, + .ctl_name = MAX_TX_WINDOW, .procname = "max_tx_window", .data = &sysctl_max_tx_window, .maxlen = sizeof(int), @@ -199,7 +205,7 @@ static ctl_table irda_table[] = { .extra2 = &max_max_tx_window }, { - .ctl_name = NET_IRDA_MAX_NOREPLY_TIME, + .ctl_name = MAX_NOREPLY_TIME, .procname = "max_noreply_time", .data = &sysctl_max_noreply_time, .maxlen = sizeof(int), @@ -210,7 +216,7 @@ static ctl_table irda_table[] = { .extra2 = &max_max_noreply_time }, { - .ctl_name = NET_IRDA_WARN_NOREPLY_TIME, + .ctl_name = WARN_NOREPLY_TIME, .procname = "warn_noreply_time", .data = &sysctl_warn_noreply_time, .maxlen = sizeof(int), @@ -221,7 +227,7 @@ static ctl_table irda_table[] = { .extra2 = &max_warn_noreply_time }, { - .ctl_name = NET_IRDA_LAP_KEEPALIVE_TIME, + .ctl_name = LAP_KEEPALIVE_TIME, .procname = "lap_keepalive_time", .data = &sysctl_lap_keepalive_time, .maxlen = sizeof(int), diff --git a/trunk/net/llc/af_llc.c b/trunk/net/llc/af_llc.c index 46cf962f7f88..49eacba824df 100644 --- a/trunk/net/llc/af_llc.c +++ b/trunk/net/llc/af_llc.c @@ -762,7 +762,7 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock, if (net_ratelimit()) printk(KERN_DEBUG "LLC(%s:%d): Application " "bug, race in MSG_PEEK.\n", - current->comm, task_pid_nr(current)); + current->comm, current->pid); peek_seq = llc->copied_seq; } continue; diff --git a/trunk/net/mac80211/ieee80211_i.h b/trunk/net/mac80211/ieee80211_i.h index 4b4ed2a5803c..d34a9deca67a 100644 --- a/trunk/net/mac80211/ieee80211_i.h +++ b/trunk/net/mac80211/ieee80211_i.h @@ -37,6 +37,8 @@ struct ieee80211_local; +#define BIT(x) (1 << (x)) + #define IEEE80211_ALIGN32_PAD(a) ((4 - ((a) & 3)) & 3) /* Maximum number of broadcast/multicast frames to buffer when some of the diff --git a/trunk/net/mac80211/ieee80211_ioctl.c b/trunk/net/mac80211/ieee80211_ioctl.c index 6caa3ec2cff7..f0224c2311d2 100644 --- a/trunk/net/mac80211/ieee80211_ioctl.c +++ b/trunk/net/mac80211/ieee80211_ioctl.c @@ -306,12 +306,9 @@ int ieee80211_set_channel(struct ieee80211_local *local, int channel, int freq) ((chan->chan == channel) || (chan->freq == freq))) { local->oper_channel = chan; local->oper_hw_mode = mode; - set = 1; - break; + set++; } } - if (set) - break; } if (set) { @@ -511,11 +508,10 @@ static int ieee80211_ioctl_giwap(struct net_device *dev, static int ieee80211_ioctl_siwscan(struct net_device *dev, struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) + struct iw_point *data, char *extra) { struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - struct iw_scan_req *req = NULL; u8 *ssid = NULL; size_t ssid_len = 0; @@ -540,14 +536,6 @@ static int ieee80211_ioctl_siwscan(struct net_device *dev, return -EOPNOTSUPP; } - /* if SSID was specified explicitly then use that */ - if (wrqu->data.length == sizeof(struct iw_scan_req) && - wrqu->data.flags & IW_SCAN_THIS_ESSID) { - req = (struct iw_scan_req *)extra; - ssid = req->essid; - ssid_len = req->essid_len; - } - return ieee80211_sta_req_scan(dev, ssid, ssid_len); } diff --git a/trunk/net/mac80211/ieee80211_sta.c b/trunk/net/mac80211/ieee80211_sta.c index f7ffeec3913f..1641e8fe44b7 100644 --- a/trunk/net/mac80211/ieee80211_sta.c +++ b/trunk/net/mac80211/ieee80211_sta.c @@ -12,6 +12,7 @@ */ /* TODO: + * BSS table: use as the key to support multi-SSID APs * order BSS list by RSSI(?) ("quality of AP") * scan result table filtering (by capability (privacy, IBSS/BSS, WPA/RSN IE, * SSID) @@ -60,8 +61,7 @@ static void ieee80211_send_probe_req(struct net_device *dev, u8 *dst, u8 *ssid, size_t ssid_len); static struct ieee80211_sta_bss * -ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int channel, - u8 *ssid, u8 ssid_len); +ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid); static void ieee80211_rx_bss_put(struct net_device *dev, struct ieee80211_sta_bss *bss); static int ieee80211_sta_find_ibss(struct net_device *dev, @@ -108,11 +108,14 @@ struct ieee802_11_elems { u8 wmm_param_len; }; -static void ieee802_11_parse_elems(u8 *start, size_t len, - struct ieee802_11_elems *elems) +enum ParseRes { ParseOK = 0, ParseUnknown = 1, ParseFailed = -1 }; + +static enum ParseRes ieee802_11_parse_elems(u8 *start, size_t len, + struct ieee802_11_elems *elems) { size_t left = len; u8 *pos = start; + int unknown = 0; memset(elems, 0, sizeof(*elems)); @@ -123,8 +126,15 @@ static void ieee802_11_parse_elems(u8 *start, size_t len, elen = *pos++; left -= 2; - if (elen > left) - return; + if (elen > left) { +#if 0 + if (net_ratelimit()) + printk(KERN_DEBUG "IEEE 802.11 element parse " + "failed (id=%d elen=%d left=%d)\n", + id, elen, left); +#endif + return ParseFailed; + } switch (id) { case WLAN_EID_SSID: @@ -191,15 +201,28 @@ static void ieee802_11_parse_elems(u8 *start, size_t len, elems->ext_supp_rates_len = elen; break; default: +#if 0 + printk(KERN_DEBUG "IEEE 802.11 element parse ignored " + "unknown element (id=%d elen=%d)\n", + id, elen); +#endif + unknown++; break; } left -= elen; pos += elen; } + + /* Do not trigger error if left == 1 as Apple Airport base stations + * send AssocResps that are one spurious byte too long. */ + + return unknown ? ParseUnknown : ParseOK; } + + static int ecw2cw(int ecw) { int cw = 1; @@ -404,9 +427,7 @@ static void ieee80211_set_associated(struct net_device *dev, if (sdata->type != IEEE80211_IF_TYPE_STA) return; - bss = ieee80211_rx_bss_get(dev, ifsta->bssid, - local->hw.conf.channel, - ifsta->ssid, ifsta->ssid_len); + bss = ieee80211_rx_bss_get(dev, ifsta->bssid); if (bss) { if (bss->has_erp_value) ieee80211_handle_erp_ie(dev, bss->erp_value); @@ -553,8 +574,7 @@ static void ieee80211_send_assoc(struct net_device *dev, capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME | WLAN_CAPABILITY_SHORT_PREAMBLE; } - bss = ieee80211_rx_bss_get(dev, ifsta->bssid, local->hw.conf.channel, - ifsta->ssid, ifsta->ssid_len); + bss = ieee80211_rx_bss_get(dev, ifsta->bssid); if (bss) { if (bss->capability & WLAN_CAPABILITY_PRIVACY) capab |= WLAN_CAPABILITY_PRIVACY; @@ -702,7 +722,6 @@ static void ieee80211_send_disassoc(struct net_device *dev, static int ieee80211_privacy_mismatch(struct net_device *dev, struct ieee80211_if_sta *ifsta) { - struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); struct ieee80211_sta_bss *bss; int res = 0; @@ -710,8 +729,7 @@ static int ieee80211_privacy_mismatch(struct net_device *dev, ifsta->key_management_enabled) return 0; - bss = ieee80211_rx_bss_get(dev, ifsta->bssid, local->hw.conf.channel, - ifsta->ssid, ifsta->ssid_len); + bss = ieee80211_rx_bss_get(dev, ifsta->bssid); if (!bss) return 0; @@ -908,7 +926,12 @@ static void ieee80211_auth_challenge(struct net_device *dev, printk(KERN_DEBUG "%s: replying to auth challenge\n", dev->name); pos = mgmt->u.auth.variable; - ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems); + if (ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems) + == ParseFailed) { + printk(KERN_DEBUG "%s: failed to parse Auth(challenge)\n", + dev->name); + return; + } if (!elems.challenge) { printk(KERN_DEBUG "%s: no challenge IE in shared key auth " "frame\n", dev->name); @@ -1180,11 +1203,15 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev, capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info); status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code); aid = le16_to_cpu(mgmt->u.assoc_resp.aid); + if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14))) + printk(KERN_DEBUG "%s: invalid aid value %d; bits 15:14 not " + "set\n", dev->name, aid); + aid &= ~(BIT(15) | BIT(14)); printk(KERN_DEBUG "%s: RX %sssocResp from %s (capab=0x%x " "status=%d aid=%d)\n", dev->name, reassoc ? "Rea" : "A", print_mac(mac, mgmt->sa), - capab_info, status_code, aid & ~(BIT(15) | BIT(14))); + capab_info, status_code, aid); if (status_code != WLAN_STATUS_SUCCESS) { printk(KERN_DEBUG "%s: AP denied association (code=%d)\n", @@ -1196,13 +1223,13 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev, return; } - if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14))) - printk(KERN_DEBUG "%s: invalid aid value %d; bits 15:14 not " - "set\n", dev->name, aid); - aid &= ~(BIT(15) | BIT(14)); - pos = mgmt->u.assoc_resp.variable; - ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems); + if (ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems) + == ParseFailed) { + printk(KERN_DEBUG "%s: failed to parse AssocResp\n", + dev->name); + return; + } if (!elems.supp_rates) { printk(KERN_DEBUG "%s: no SuppRates element in AssocResp\n", @@ -1214,9 +1241,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev, * update our stored copy */ if (elems.erp_info && elems.erp_info_len >= 1) { struct ieee80211_sta_bss *bss - = ieee80211_rx_bss_get(dev, ifsta->bssid, - local->hw.conf.channel, - ifsta->ssid, ifsta->ssid_len); + = ieee80211_rx_bss_get(dev, ifsta->bssid); if (bss) { bss->erp_value = elems.erp_info[0]; bss->has_erp_value = 1; @@ -1246,9 +1271,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev, " AP\n", dev->name); return; } - bss = ieee80211_rx_bss_get(dev, ifsta->bssid, - local->hw.conf.channel, - ifsta->ssid, ifsta->ssid_len); + bss = ieee80211_rx_bss_get(dev, ifsta->bssid); if (bss) { sta->last_rssi = bss->rssi; sta->last_signal = bss->signal; @@ -1324,8 +1347,7 @@ static void __ieee80211_rx_bss_hash_del(struct net_device *dev, static struct ieee80211_sta_bss * -ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid, int channel, - u8 *ssid, u8 ssid_len) +ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid) { struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); struct ieee80211_sta_bss *bss; @@ -1336,11 +1358,6 @@ ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid, int channel, atomic_inc(&bss->users); atomic_inc(&bss->users); memcpy(bss->bssid, bssid, ETH_ALEN); - bss->channel = channel; - if (ssid && ssid_len <= IEEE80211_MAX_SSID_LEN) { - memcpy(bss->ssid, ssid, ssid_len); - bss->ssid_len = ssid_len; - } spin_lock_bh(&local->sta_bss_lock); /* TODO: order by RSSI? */ @@ -1352,8 +1369,7 @@ ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid, int channel, static struct ieee80211_sta_bss * -ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int channel, - u8 *ssid, u8 ssid_len) +ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid) { struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); struct ieee80211_sta_bss *bss; @@ -1361,10 +1377,7 @@ ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int channel, spin_lock_bh(&local->sta_bss_lock); bss = local->sta_bss_hash[STA_HASH(bssid)]; while (bss) { - if (!memcmp(bss->bssid, bssid, ETH_ALEN) && - bss->channel == channel && - bss->ssid_len == ssid_len && - (ssid_len == 0 || !memcmp(bss->ssid, ssid, ssid_len))) { + if (memcmp(bss->bssid, bssid, ETH_ALEN) == 0) { atomic_inc(&bss->users); break; } @@ -1426,7 +1439,7 @@ static void ieee80211_rx_bss_info(struct net_device *dev, struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); struct ieee802_11_elems elems; size_t baselen; - int channel, clen; + int channel, invalid = 0, clen; struct ieee80211_sta_bss *bss; struct sta_info *sta; struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); @@ -1472,7 +1485,9 @@ static void ieee80211_rx_bss_info(struct net_device *dev, #endif /* CONFIG_MAC80211_IBSS_DEBUG */ } - ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems); + if (ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, + &elems) == ParseFailed) + invalid = 1; if (sdata->type == IEEE80211_IF_TYPE_IBSS && elems.supp_rates && memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0 && @@ -1530,11 +1545,9 @@ static void ieee80211_rx_bss_info(struct net_device *dev, else channel = rx_status->channel; - bss = ieee80211_rx_bss_get(dev, mgmt->bssid, channel, - elems.ssid, elems.ssid_len); + bss = ieee80211_rx_bss_get(dev, mgmt->bssid); if (!bss) { - bss = ieee80211_rx_bss_add(dev, mgmt->bssid, channel, - elems.ssid, elems.ssid_len); + bss = ieee80211_rx_bss_add(dev, mgmt->bssid); if (!bss) return; } else { @@ -1560,6 +1573,10 @@ static void ieee80211_rx_bss_info(struct net_device *dev, bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int); bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info); + if (elems.ssid && elems.ssid_len <= IEEE80211_MAX_SSID_LEN) { + memcpy(bss->ssid, elems.ssid, elems.ssid_len); + bss->ssid_len = elems.ssid_len; + } bss->supp_rates_len = 0; if (elems.supp_rates) { @@ -1630,6 +1647,7 @@ static void ieee80211_rx_bss_info(struct net_device *dev, bss->hw_mode = rx_status->phymode; + bss->channel = channel; bss->freq = rx_status->freq; if (channel != rx_status->channel && (bss->hw_mode == MODE_IEEE80211G || @@ -1689,7 +1707,9 @@ static void ieee80211_rx_mgmt_beacon(struct net_device *dev, if (baselen > len) return; - ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems); + if (ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, + &elems) == ParseFailed) + return; if (elems.erp_info && elems.erp_info_len >= 1) ieee80211_handle_erp_ie(dev, elems.erp_info[0]); @@ -2355,7 +2375,7 @@ static int ieee80211_sta_create_ibss(struct net_device *dev, { struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); struct ieee80211_sta_bss *bss; - struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + struct ieee80211_sub_if_data *sdata; struct ieee80211_hw_mode *mode; u8 bssid[ETH_ALEN], *pos; int i; @@ -2378,17 +2398,18 @@ static int ieee80211_sta_create_ibss(struct net_device *dev, printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %s\n", dev->name, print_mac(mac, bssid)); - bss = ieee80211_rx_bss_add(dev, bssid, local->hw.conf.channel, - sdata->u.sta.ssid, sdata->u.sta.ssid_len); + bss = ieee80211_rx_bss_add(dev, bssid); if (!bss) return -ENOMEM; + sdata = IEEE80211_DEV_TO_SUB_IF(dev); mode = local->oper_hw_mode; if (local->hw.conf.beacon_int == 0) local->hw.conf.beacon_int = 100; bss->beacon_int = local->hw.conf.beacon_int; bss->hw_mode = local->hw.conf.phymode; + bss->channel = local->hw.conf.channel; bss->freq = local->hw.conf.freq; bss->last_update = jiffies; bss->capability = WLAN_CAPABILITY_IBSS; @@ -2448,8 +2469,7 @@ static int ieee80211_sta_find_ibss(struct net_device *dev, "%s\n", print_mac(mac, bssid), print_mac(mac2, ifsta->bssid)); #endif /* CONFIG_MAC80211_IBSS_DEBUG */ if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0 && - (bss = ieee80211_rx_bss_get(dev, bssid, local->hw.conf.channel, - ifsta->ssid, ifsta->ssid_len))) { + (bss = ieee80211_rx_bss_get(dev, bssid))) { printk(KERN_DEBUG "%s: Selected IBSS BSSID %s" " based on configured SSID\n", dev->name, print_mac(mac, bssid)); diff --git a/trunk/net/netfilter/nf_conntrack_proto_generic.c b/trunk/net/netfilter/nf_conntrack_proto_generic.c index 13f819179642..d8b501878d9f 100644 --- a/trunk/net/netfilter/nf_conntrack_proto_generic.c +++ b/trunk/net/netfilter/nf_conntrack_proto_generic.c @@ -70,6 +70,7 @@ static int new(struct nf_conn *conntrack, const struct sk_buff *skb, static struct ctl_table_header *generic_sysctl_header; static struct ctl_table generic_sysctl_table[] = { { + .ctl_name = NET_NF_CONNTRACK_GENERIC_TIMEOUT, .procname = "nf_conntrack_generic_timeout", .data = &nf_ct_generic_timeout, .maxlen = sizeof(unsigned int), @@ -83,6 +84,7 @@ static struct ctl_table generic_sysctl_table[] = { #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT static struct ctl_table generic_compat_sysctl_table[] = { { + .ctl_name = NET_IPV4_NF_CONNTRACK_GENERIC_TIMEOUT, .procname = "ip_conntrack_generic_timeout", .data = &nf_ct_generic_timeout, .maxlen = sizeof(unsigned int), diff --git a/trunk/net/netfilter/nf_conntrack_proto_sctp.c b/trunk/net/netfilter/nf_conntrack_proto_sctp.c index cb0467510592..04192acc7c40 100644 --- a/trunk/net/netfilter/nf_conntrack_proto_sctp.c +++ b/trunk/net/netfilter/nf_conntrack_proto_sctp.c @@ -476,6 +476,7 @@ static unsigned int sctp_sysctl_table_users; static struct ctl_table_header *sctp_sysctl_header; static struct ctl_table sctp_sysctl_table[] = { { + .ctl_name = NET_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED, .procname = "nf_conntrack_sctp_timeout_closed", .data = &nf_ct_sctp_timeout_closed, .maxlen = sizeof(unsigned int), @@ -483,6 +484,7 @@ static struct ctl_table sctp_sysctl_table[] = { .proc_handler = &proc_dointvec_jiffies, }, { + .ctl_name = NET_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_WAIT, .procname = "nf_conntrack_sctp_timeout_cookie_wait", .data = &nf_ct_sctp_timeout_cookie_wait, .maxlen = sizeof(unsigned int), @@ -490,6 +492,7 @@ static struct ctl_table sctp_sysctl_table[] = { .proc_handler = &proc_dointvec_jiffies, }, { + .ctl_name = NET_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_ECHOED, .procname = "nf_conntrack_sctp_timeout_cookie_echoed", .data = &nf_ct_sctp_timeout_cookie_echoed, .maxlen = sizeof(unsigned int), @@ -497,6 +500,7 @@ static struct ctl_table sctp_sysctl_table[] = { .proc_handler = &proc_dointvec_jiffies, }, { + .ctl_name = NET_NF_CONNTRACK_SCTP_TIMEOUT_ESTABLISHED, .procname = "nf_conntrack_sctp_timeout_established", .data = &nf_ct_sctp_timeout_established, .maxlen = sizeof(unsigned int), @@ -504,6 +508,7 @@ static struct ctl_table sctp_sysctl_table[] = { .proc_handler = &proc_dointvec_jiffies, }, { + .ctl_name = NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT, .procname = "nf_conntrack_sctp_timeout_shutdown_sent", .data = &nf_ct_sctp_timeout_shutdown_sent, .maxlen = sizeof(unsigned int), @@ -511,6 +516,7 @@ static struct ctl_table sctp_sysctl_table[] = { .proc_handler = &proc_dointvec_jiffies, }, { + .ctl_name = NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD, .procname = "nf_conntrack_sctp_timeout_shutdown_recd", .data = &nf_ct_sctp_timeout_shutdown_recd, .maxlen = sizeof(unsigned int), @@ -518,6 +524,7 @@ static struct ctl_table sctp_sysctl_table[] = { .proc_handler = &proc_dointvec_jiffies, }, { + .ctl_name = NET_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT, .procname = "nf_conntrack_sctp_timeout_shutdown_ack_sent", .data = &nf_ct_sctp_timeout_shutdown_ack_sent, .maxlen = sizeof(unsigned int), @@ -532,6 +539,7 @@ static struct ctl_table sctp_sysctl_table[] = { #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT static struct ctl_table sctp_compat_sysctl_table[] = { { + .ctl_name = NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED, .procname = "ip_conntrack_sctp_timeout_closed", .data = &nf_ct_sctp_timeout_closed, .maxlen = sizeof(unsigned int), @@ -539,6 +547,7 @@ static struct ctl_table sctp_compat_sysctl_table[] = { .proc_handler = &proc_dointvec_jiffies, }, { + .ctl_name = NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_WAIT, .procname = "ip_conntrack_sctp_timeout_cookie_wait", .data = &nf_ct_sctp_timeout_cookie_wait, .maxlen = sizeof(unsigned int), @@ -546,6 +555,7 @@ static struct ctl_table sctp_compat_sysctl_table[] = { .proc_handler = &proc_dointvec_jiffies, }, { + .ctl_name = NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_ECHOED, .procname = "ip_conntrack_sctp_timeout_cookie_echoed", .data = &nf_ct_sctp_timeout_cookie_echoed, .maxlen = sizeof(unsigned int), @@ -553,6 +563,7 @@ static struct ctl_table sctp_compat_sysctl_table[] = { .proc_handler = &proc_dointvec_jiffies, }, { + .ctl_name = NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_ESTABLISHED, .procname = "ip_conntrack_sctp_timeout_established", .data = &nf_ct_sctp_timeout_established, .maxlen = sizeof(unsigned int), @@ -560,6 +571,7 @@ static struct ctl_table sctp_compat_sysctl_table[] = { .proc_handler = &proc_dointvec_jiffies, }, { + .ctl_name = NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT, .procname = "ip_conntrack_sctp_timeout_shutdown_sent", .data = &nf_ct_sctp_timeout_shutdown_sent, .maxlen = sizeof(unsigned int), @@ -567,6 +579,7 @@ static struct ctl_table sctp_compat_sysctl_table[] = { .proc_handler = &proc_dointvec_jiffies, }, { + .ctl_name = NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD, .procname = "ip_conntrack_sctp_timeout_shutdown_recd", .data = &nf_ct_sctp_timeout_shutdown_recd, .maxlen = sizeof(unsigned int), @@ -574,6 +587,7 @@ static struct ctl_table sctp_compat_sysctl_table[] = { .proc_handler = &proc_dointvec_jiffies, }, { + .ctl_name = NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT, .procname = "ip_conntrack_sctp_timeout_shutdown_ack_sent", .data = &nf_ct_sctp_timeout_shutdown_ack_sent, .maxlen = sizeof(unsigned int), diff --git a/trunk/net/netfilter/nf_conntrack_proto_tcp.c b/trunk/net/netfilter/nf_conntrack_proto_tcp.c index 7a3f64c1aca6..c7075345971b 100644 --- a/trunk/net/netfilter/nf_conntrack_proto_tcp.c +++ b/trunk/net/netfilter/nf_conntrack_proto_tcp.c @@ -834,12 +834,10 @@ static int tcp_packet(struct nf_conn *conntrack, case TCP_CONNTRACK_SYN_SENT: if (old_state < TCP_CONNTRACK_TIME_WAIT) break; - if ((conntrack->proto.tcp.seen[!dir].flags & - IP_CT_TCP_FLAG_CLOSE_INIT) - || (conntrack->proto.tcp.last_dir == dir - && conntrack->proto.tcp.last_index == TCP_RST_SET)) { - /* Attempt to reopen a closed/aborted connection. - * Delete this connection and look up again. */ + if (conntrack->proto.tcp.seen[!dir].flags & + IP_CT_TCP_FLAG_CLOSE_INIT) { + /* Attempt to reopen a closed connection. + * Delete this connection and look up again. */ write_unlock_bh(&tcp_lock); if (del_timer(&conntrack->timeout)) conntrack->timeout.function((unsigned long) @@ -927,7 +925,6 @@ static int tcp_packet(struct nf_conn *conntrack, in_window: /* From now on we have got in-window packets */ conntrack->proto.tcp.last_index = index; - conntrack->proto.tcp.last_dir = dir; pr_debug("tcp_conntracks: "); NF_CT_DUMP_TUPLE(tuple); @@ -1165,6 +1162,7 @@ static unsigned int tcp_sysctl_table_users; static struct ctl_table_header *tcp_sysctl_header; static struct ctl_table tcp_sysctl_table[] = { { + .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT, .procname = "nf_conntrack_tcp_timeout_syn_sent", .data = &nf_ct_tcp_timeout_syn_sent, .maxlen = sizeof(unsigned int), @@ -1172,6 +1170,7 @@ static struct ctl_table tcp_sysctl_table[] = { .proc_handler = &proc_dointvec_jiffies, }, { + .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_RECV, .procname = "nf_conntrack_tcp_timeout_syn_recv", .data = &nf_ct_tcp_timeout_syn_recv, .maxlen = sizeof(unsigned int), @@ -1179,6 +1178,7 @@ static struct ctl_table tcp_sysctl_table[] = { .proc_handler = &proc_dointvec_jiffies, }, { + .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED, .procname = "nf_conntrack_tcp_timeout_established", .data = &nf_ct_tcp_timeout_established, .maxlen = sizeof(unsigned int), @@ -1186,6 +1186,7 @@ static struct ctl_table tcp_sysctl_table[] = { .proc_handler = &proc_dointvec_jiffies, }, { + .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT, .procname = "nf_conntrack_tcp_timeout_fin_wait", .data = &nf_ct_tcp_timeout_fin_wait, .maxlen = sizeof(unsigned int), @@ -1193,6 +1194,7 @@ static struct ctl_table tcp_sysctl_table[] = { .proc_handler = &proc_dointvec_jiffies, }, { + .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE_WAIT, .procname = "nf_conntrack_tcp_timeout_close_wait", .data = &nf_ct_tcp_timeout_close_wait, .maxlen = sizeof(unsigned int), @@ -1200,6 +1202,7 @@ static struct ctl_table tcp_sysctl_table[] = { .proc_handler = &proc_dointvec_jiffies, }, { + .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_LAST_ACK, .procname = "nf_conntrack_tcp_timeout_last_ack", .data = &nf_ct_tcp_timeout_last_ack, .maxlen = sizeof(unsigned int), @@ -1207,6 +1210,7 @@ static struct ctl_table tcp_sysctl_table[] = { .proc_handler = &proc_dointvec_jiffies, }, { + .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT, .procname = "nf_conntrack_tcp_timeout_time_wait", .data = &nf_ct_tcp_timeout_time_wait, .maxlen = sizeof(unsigned int), @@ -1214,6 +1218,7 @@ static struct ctl_table tcp_sysctl_table[] = { .proc_handler = &proc_dointvec_jiffies, }, { + .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE, .procname = "nf_conntrack_tcp_timeout_close", .data = &nf_ct_tcp_timeout_close, .maxlen = sizeof(unsigned int), @@ -1221,6 +1226,7 @@ static struct ctl_table tcp_sysctl_table[] = { .proc_handler = &proc_dointvec_jiffies, }, { + .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_MAX_RETRANS, .procname = "nf_conntrack_tcp_timeout_max_retrans", .data = &nf_ct_tcp_timeout_max_retrans, .maxlen = sizeof(unsigned int), @@ -1259,6 +1265,7 @@ static struct ctl_table tcp_sysctl_table[] = { #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT static struct ctl_table tcp_compat_sysctl_table[] = { { + .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT, .procname = "ip_conntrack_tcp_timeout_syn_sent", .data = &nf_ct_tcp_timeout_syn_sent, .maxlen = sizeof(unsigned int), @@ -1266,6 +1273,7 @@ static struct ctl_table tcp_compat_sysctl_table[] = { .proc_handler = &proc_dointvec_jiffies, }, { + .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_RECV, .procname = "ip_conntrack_tcp_timeout_syn_recv", .data = &nf_ct_tcp_timeout_syn_recv, .maxlen = sizeof(unsigned int), @@ -1273,6 +1281,7 @@ static struct ctl_table tcp_compat_sysctl_table[] = { .proc_handler = &proc_dointvec_jiffies, }, { + .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED, .procname = "ip_conntrack_tcp_timeout_established", .data = &nf_ct_tcp_timeout_established, .maxlen = sizeof(unsigned int), @@ -1280,6 +1289,7 @@ static struct ctl_table tcp_compat_sysctl_table[] = { .proc_handler = &proc_dointvec_jiffies, }, { + .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT, .procname = "ip_conntrack_tcp_timeout_fin_wait", .data = &nf_ct_tcp_timeout_fin_wait, .maxlen = sizeof(unsigned int), @@ -1287,6 +1297,7 @@ static struct ctl_table tcp_compat_sysctl_table[] = { .proc_handler = &proc_dointvec_jiffies, }, { + .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_CLOSE_WAIT, .procname = "ip_conntrack_tcp_timeout_close_wait", .data = &nf_ct_tcp_timeout_close_wait, .maxlen = sizeof(unsigned int), @@ -1294,6 +1305,7 @@ static struct ctl_table tcp_compat_sysctl_table[] = { .proc_handler = &proc_dointvec_jiffies, }, { + .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_LAST_ACK, .procname = "ip_conntrack_tcp_timeout_last_ack", .data = &nf_ct_tcp_timeout_last_ack, .maxlen = sizeof(unsigned int), @@ -1301,6 +1313,7 @@ static struct ctl_table tcp_compat_sysctl_table[] = { .proc_handler = &proc_dointvec_jiffies, }, { + .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT, .procname = "ip_conntrack_tcp_timeout_time_wait", .data = &nf_ct_tcp_timeout_time_wait, .maxlen = sizeof(unsigned int), @@ -1308,6 +1321,7 @@ static struct ctl_table tcp_compat_sysctl_table[] = { .proc_handler = &proc_dointvec_jiffies, }, { + .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_CLOSE, .procname = "ip_conntrack_tcp_timeout_close", .data = &nf_ct_tcp_timeout_close, .maxlen = sizeof(unsigned int), @@ -1315,6 +1329,7 @@ static struct ctl_table tcp_compat_sysctl_table[] = { .proc_handler = &proc_dointvec_jiffies, }, { + .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_MAX_RETRANS, .procname = "ip_conntrack_tcp_timeout_max_retrans", .data = &nf_ct_tcp_timeout_max_retrans, .maxlen = sizeof(unsigned int), diff --git a/trunk/net/netfilter/nf_conntrack_proto_udp.c b/trunk/net/netfilter/nf_conntrack_proto_udp.c index b3e7ecb080e6..ba80e1a1ea17 100644 --- a/trunk/net/netfilter/nf_conntrack_proto_udp.c +++ b/trunk/net/netfilter/nf_conntrack_proto_udp.c @@ -146,6 +146,7 @@ static unsigned int udp_sysctl_table_users; static struct ctl_table_header *udp_sysctl_header; static struct ctl_table udp_sysctl_table[] = { { + .ctl_name = NET_NF_CONNTRACK_UDP_TIMEOUT, .procname = "nf_conntrack_udp_timeout", .data = &nf_ct_udp_timeout, .maxlen = sizeof(unsigned int), @@ -153,6 +154,7 @@ static struct ctl_table udp_sysctl_table[] = { .proc_handler = &proc_dointvec_jiffies, }, { + .ctl_name = NET_NF_CONNTRACK_UDP_TIMEOUT_STREAM, .procname = "nf_conntrack_udp_timeout_stream", .data = &nf_ct_udp_timeout_stream, .maxlen = sizeof(unsigned int), @@ -166,6 +168,7 @@ static struct ctl_table udp_sysctl_table[] = { #ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT static struct ctl_table udp_compat_sysctl_table[] = { { + .ctl_name = NET_IPV4_NF_CONNTRACK_UDP_TIMEOUT, .procname = "ip_conntrack_udp_timeout", .data = &nf_ct_udp_timeout, .maxlen = sizeof(unsigned int), @@ -173,6 +176,7 @@ static struct ctl_table udp_compat_sysctl_table[] = { .proc_handler = &proc_dointvec_jiffies, }, { + .ctl_name = NET_IPV4_NF_CONNTRACK_UDP_TIMEOUT_STREAM, .procname = "ip_conntrack_udp_timeout_stream", .data = &nf_ct_udp_timeout_stream, .maxlen = sizeof(unsigned int), diff --git a/trunk/net/netfilter/xt_connbytes.c b/trunk/net/netfilter/xt_connbytes.c index 9ec50139b9a1..af79423bc8e8 100644 --- a/trunk/net/netfilter/xt_connbytes.c +++ b/trunk/net/netfilter/xt_connbytes.c @@ -2,13 +2,13 @@ * GPL (C) 2002 Martin Devera (devik@cdi.cz). */ #include -#include #include #include #include #include #include +#include MODULE_LICENSE("GPL"); MODULE_AUTHOR("Harald Welte "); diff --git a/trunk/net/netfilter/xt_sctp.c b/trunk/net/netfilter/xt_sctp.c index 3358273a47b7..f907770fd4e9 100644 --- a/trunk/net/netfilter/xt_sctp.c +++ b/trunk/net/netfilter/xt_sctp.c @@ -42,21 +42,21 @@ match_flags(const struct xt_sctp_flag_info *flag_info, static inline bool match_packet(const struct sk_buff *skb, unsigned int offset, - const struct xt_sctp_info *info, + const u_int32_t *chunkmap, + int chunk_match_type, + const struct xt_sctp_flag_info *flag_info, + const int flag_count, bool *hotdrop) { u_int32_t chunkmapcopy[256 / sizeof (u_int32_t)]; sctp_chunkhdr_t _sch, *sch; - int chunk_match_type = info->chunk_match_type; - const struct xt_sctp_flag_info *flag_info = info->flag_info; - int flag_count = info->flag_count; #ifdef DEBUG_SCTP int i = 0; #endif if (chunk_match_type == SCTP_CHUNK_MATCH_ALL) - SCTP_CHUNKMAP_COPY(chunkmapcopy, info->chunkmap); + SCTP_CHUNKMAP_COPY(chunkmapcopy, chunkmap); do { sch = skb_header_pointer(skb, offset, sizeof(_sch), &_sch); @@ -73,7 +73,7 @@ match_packet(const struct sk_buff *skb, duprintf("skb->len: %d\toffset: %d\n", skb->len, offset); - if (SCTP_CHUNKMAP_IS_SET(info->chunkmap, sch->type)) { + if (SCTP_CHUNKMAP_IS_SET(chunkmap, sch->type)) { switch (chunk_match_type) { case SCTP_CHUNK_MATCH_ANY: if (match_flags(flag_info, flag_count, @@ -104,7 +104,7 @@ match_packet(const struct sk_buff *skb, switch (chunk_match_type) { case SCTP_CHUNK_MATCH_ALL: - return SCTP_CHUNKMAP_IS_CLEAR(info->chunkmap); + return SCTP_CHUNKMAP_IS_CLEAR(chunkmap); case SCTP_CHUNK_MATCH_ANY: return false; case SCTP_CHUNK_MATCH_ONLY: @@ -148,7 +148,9 @@ match(const struct sk_buff *skb, && ntohs(sh->dest) <= info->dpts[1], XT_SCTP_DEST_PORTS, info->flags, info->invflags) && SCCHECK(match_packet(skb, protoff + sizeof (sctp_sctphdr_t), - info, hotdrop), + info->chunkmap, info->chunk_match_type, + info->flag_info, info->flag_count, + hotdrop), XT_SCTP_CHUNK_TYPES, info->flags, info->invflags); } diff --git a/trunk/net/packet/af_packet.c b/trunk/net/packet/af_packet.c index d0936506b731..e11000a8e950 100644 --- a/trunk/net/packet/af_packet.c +++ b/trunk/net/packet/af_packet.c @@ -1623,6 +1623,11 @@ static struct vm_operations_struct packet_mmap_ops = { .close =packet_mm_close, }; +static inline struct page *pg_vec_endpage(char *one_pg_vec, unsigned int order) +{ + return virt_to_page(one_pg_vec + (PAGE_SIZE << order) - 1); +} + static void free_pg_vec(char **pg_vec, unsigned int order, unsigned int len) { int i; diff --git a/trunk/net/rfkill/rfkill-input.c b/trunk/net/rfkill/rfkill-input.c index d1e9d68f8ba0..eaabf087c59b 100644 --- a/trunk/net/rfkill/rfkill-input.c +++ b/trunk/net/rfkill/rfkill-input.c @@ -146,18 +146,18 @@ static void rfkill_disconnect(struct input_handle *handle) static const struct input_device_id rfkill_ids[] = { { .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT, - .evbit = { BIT_MASK(EV_KEY) }, - .keybit = { [BIT_WORD(KEY_WLAN)] = BIT_MASK(KEY_WLAN) }, + .evbit = { BIT(EV_KEY) }, + .keybit = { [LONG(KEY_WLAN)] = BIT(KEY_WLAN) }, }, { .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT, - .evbit = { BIT_MASK(EV_KEY) }, - .keybit = { [BIT_WORD(KEY_BLUETOOTH)] = BIT_MASK(KEY_BLUETOOTH) }, + .evbit = { BIT(EV_KEY) }, + .keybit = { [LONG(KEY_BLUETOOTH)] = BIT(KEY_BLUETOOTH) }, }, { .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT, - .evbit = { BIT_MASK(EV_KEY) }, - .keybit = { [BIT_WORD(KEY_UWB)] = BIT_MASK(KEY_UWB) }, + .evbit = { BIT(EV_KEY) }, + .keybit = { [LONG(KEY_UWB)] = BIT(KEY_UWB) }, }, { } }; diff --git a/trunk/net/sched/Kconfig b/trunk/net/sched/Kconfig index 9c15c4888d12..92435a882fac 100644 --- a/trunk/net/sched/Kconfig +++ b/trunk/net/sched/Kconfig @@ -2,7 +2,9 @@ # Traffic control configuration. # -menuconfig NET_SCHED +menu "QoS and/or fair queueing" + +config NET_SCHED bool "QoS and/or fair queueing" select NET_SCH_FIFO ---help--- @@ -39,6 +41,9 @@ menuconfig NET_SCHED The available schedulers are listed in the following questions; you can say Y to as many as you like. If unsure, say N now. +config NET_SCH_FIFO + bool + if NET_SCHED comment "Queueing/Scheduling" @@ -495,5 +500,4 @@ config NET_CLS_IND endif # NET_SCHED -config NET_SCH_FIFO - bool +endmenu diff --git a/trunk/net/sched/sch_generic.c b/trunk/net/sched/sch_generic.c index fa1a6f45dc41..95ae11956f35 100644 --- a/trunk/net/sched/sch_generic.c +++ b/trunk/net/sched/sch_generic.c @@ -249,11 +249,10 @@ static void dev_watchdog_down(struct net_device *dev) */ void netif_carrier_on(struct net_device *dev) { - if (test_and_clear_bit(__LINK_STATE_NOCARRIER, &dev->state)) { + if (test_and_clear_bit(__LINK_STATE_NOCARRIER, &dev->state)) linkwatch_fire_event(dev); - if (netif_running(dev)) - __netdev_watchdog_up(dev); - } + if (netif_running(dev)) + __netdev_watchdog_up(dev); } /** @@ -556,7 +555,6 @@ void dev_deactivate(struct net_device *dev) { struct Qdisc *qdisc; struct sk_buff *skb; - int running; spin_lock_bh(&dev->queue_lock); qdisc = dev->qdisc; @@ -572,31 +570,12 @@ void dev_deactivate(struct net_device *dev) dev_watchdog_down(dev); - /* Wait for outstanding qdisc-less dev_queue_xmit calls. */ + /* Wait for outstanding dev_queue_xmit calls. */ synchronize_rcu(); /* Wait for outstanding qdisc_run calls. */ - do { - while (test_bit(__LINK_STATE_QDISC_RUNNING, &dev->state)) - yield(); - - /* - * Double-check inside queue lock to ensure that all effects - * of the queue run are visible when we return. - */ - spin_lock_bh(&dev->queue_lock); - running = test_bit(__LINK_STATE_QDISC_RUNNING, &dev->state); - spin_unlock_bh(&dev->queue_lock); - - /* - * The running flag should never be set at this point because - * we've already set dev->qdisc to noop_qdisc *inside* the same - * pair of spin locks. That is, if any qdisc_run starts after - * our initial test it should see the noop_qdisc and then - * clear the RUNNING bit before dropping the queue lock. So - * if it is set here then we've found a bug. - */ - } while (WARN_ON_ONCE(running)); + while (test_bit(__LINK_STATE_QDISC_RUNNING, &dev->state)) + yield(); } void dev_init_scheduler(struct net_device *dev) diff --git a/trunk/net/sunrpc/sched.c b/trunk/net/sunrpc/sched.c index c98873f39aec..3c773c53e12e 100644 --- a/trunk/net/sunrpc/sched.c +++ b/trunk/net/sunrpc/sched.c @@ -847,7 +847,7 @@ void rpc_init_task(struct rpc_task *task, struct rpc_clnt *clnt, int flags, cons task->tk_start = jiffies; dprintk("RPC: new task initialized, procpid %u\n", - task_pid_nr(current)); + current->pid); } static struct rpc_task * diff --git a/trunk/net/sunrpc/sysctl.c b/trunk/net/sunrpc/sysctl.c index 864b541bbf51..738db32a287d 100644 --- a/trunk/net/sunrpc/sysctl.c +++ b/trunk/net/sunrpc/sysctl.c @@ -114,6 +114,7 @@ proc_dodebug(ctl_table *table, int write, struct file *file, static ctl_table debug_table[] = { { + .ctl_name = CTL_RPCDEBUG, .procname = "rpc_debug", .data = &rpc_debug, .maxlen = sizeof(int), @@ -121,6 +122,7 @@ static ctl_table debug_table[] = { .proc_handler = &proc_dodebug }, { + .ctl_name = CTL_NFSDEBUG, .procname = "nfs_debug", .data = &nfs_debug, .maxlen = sizeof(int), @@ -128,6 +130,7 @@ static ctl_table debug_table[] = { .proc_handler = &proc_dodebug }, { + .ctl_name = CTL_NFSDDEBUG, .procname = "nfsd_debug", .data = &nfsd_debug, .maxlen = sizeof(int), @@ -135,6 +138,7 @@ static ctl_table debug_table[] = { .proc_handler = &proc_dodebug }, { + .ctl_name = CTL_NLMDEBUG, .procname = "nlm_debug", .data = &nlm_debug, .maxlen = sizeof(int), diff --git a/trunk/net/unix/af_unix.c b/trunk/net/unix/af_unix.c index 9163ec526c2a..6996cba5aa96 100644 --- a/trunk/net/unix/af_unix.c +++ b/trunk/net/unix/af_unix.c @@ -483,7 +483,7 @@ static int unix_listen(struct socket *sock, int backlog) sk->sk_max_ack_backlog = backlog; sk->sk_state = TCP_LISTEN; /* set credentials so connect can copy them */ - sk->sk_peercred.pid = task_tgid_vnr(current); + sk->sk_peercred.pid = current->tgid; sk->sk_peercred.uid = current->euid; sk->sk_peercred.gid = current->egid; err = 0; @@ -1133,7 +1133,7 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr, unix_peer(newsk) = sk; newsk->sk_state = TCP_ESTABLISHED; newsk->sk_type = sk->sk_type; - newsk->sk_peercred.pid = task_tgid_vnr(current); + newsk->sk_peercred.pid = current->tgid; newsk->sk_peercred.uid = current->euid; newsk->sk_peercred.gid = current->egid; newu = unix_sk(newsk); @@ -1194,7 +1194,7 @@ static int unix_socketpair(struct socket *socka, struct socket *sockb) sock_hold(skb); unix_peer(ska)=skb; unix_peer(skb)=ska; - ska->sk_peercred.pid = skb->sk_peercred.pid = task_tgid_vnr(current); + ska->sk_peercred.pid = skb->sk_peercred.pid = current->tgid; ska->sk_peercred.uid = skb->sk_peercred.uid = current->euid; ska->sk_peercred.gid = skb->sk_peercred.gid = current->egid; diff --git a/trunk/net/xfrm/xfrm_input.c b/trunk/net/xfrm/xfrm_input.c index cb97fda1b6df..113f44429982 100644 --- a/trunk/net/xfrm/xfrm_input.c +++ b/trunk/net/xfrm/xfrm_input.c @@ -49,16 +49,13 @@ EXPORT_SYMBOL(secpath_dup); int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq) { int offset, offset_seq; - int hlen; switch (nexthdr) { case IPPROTO_AH: - hlen = sizeof(struct ip_auth_hdr); offset = offsetof(struct ip_auth_hdr, spi); offset_seq = offsetof(struct ip_auth_hdr, seq_no); break; case IPPROTO_ESP: - hlen = sizeof(struct ip_esp_hdr); offset = offsetof(struct ip_esp_hdr, spi); offset_seq = offsetof(struct ip_esp_hdr, seq_no); break; @@ -72,7 +69,7 @@ int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq) return 1; } - if (!pskb_may_pull(skb, hlen)) + if (!pskb_may_pull(skb, 16)) return -EINVAL; *spi = *(__be32*)(skb_transport_header(skb) + offset); diff --git a/trunk/net/xfrm/xfrm_output.c b/trunk/net/xfrm/xfrm_output.c index f4bfd6c45651..0eb3377602e9 100644 --- a/trunk/net/xfrm/xfrm_output.c +++ b/trunk/net/xfrm/xfrm_output.c @@ -63,7 +63,7 @@ int xfrm_output(struct sk_buff *skb) xfrm_replay_notify(x, XFRM_REPLAY_UPDATE); } - err = x->outer_mode->output(x, skb); + err = x->mode->output(x, skb); if (err) goto error; @@ -82,7 +82,7 @@ int xfrm_output(struct sk_buff *skb) } dst = skb->dst; x = dst->xfrm; - } while (x && !(x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL)); + } while (x && (x->props.mode != XFRM_MODE_TUNNEL)); err = 0; diff --git a/trunk/net/xfrm/xfrm_policy.c b/trunk/net/xfrm/xfrm_policy.c index b702bd8a3893..af27c193697c 100644 --- a/trunk/net/xfrm/xfrm_policy.c +++ b/trunk/net/xfrm/xfrm_policy.c @@ -49,6 +49,8 @@ static DEFINE_SPINLOCK(xfrm_policy_gc_lock); static struct xfrm_policy_afinfo *xfrm_policy_get_afinfo(unsigned short family); static void xfrm_policy_put_afinfo(struct xfrm_policy_afinfo *afinfo); +static struct xfrm_policy_afinfo *xfrm_policy_lock_afinfo(unsigned int family); +static void xfrm_policy_unlock_afinfo(struct xfrm_policy_afinfo *afinfo); static inline int __xfrm4_selector_match(struct xfrm_selector *sel, struct flowi *fl) @@ -84,6 +86,72 @@ int xfrm_selector_match(struct xfrm_selector *sel, struct flowi *fl, return 0; } +int xfrm_register_type(struct xfrm_type *type, unsigned short family) +{ + struct xfrm_policy_afinfo *afinfo = xfrm_policy_lock_afinfo(family); + struct xfrm_type **typemap; + int err = 0; + + if (unlikely(afinfo == NULL)) + return -EAFNOSUPPORT; + typemap = afinfo->type_map; + + if (likely(typemap[type->proto] == NULL)) + typemap[type->proto] = type; + else + err = -EEXIST; + xfrm_policy_unlock_afinfo(afinfo); + return err; +} +EXPORT_SYMBOL(xfrm_register_type); + +int xfrm_unregister_type(struct xfrm_type *type, unsigned short family) +{ + struct xfrm_policy_afinfo *afinfo = xfrm_policy_lock_afinfo(family); + struct xfrm_type **typemap; + int err = 0; + + if (unlikely(afinfo == NULL)) + return -EAFNOSUPPORT; + typemap = afinfo->type_map; + + if (unlikely(typemap[type->proto] != type)) + err = -ENOENT; + else + typemap[type->proto] = NULL; + xfrm_policy_unlock_afinfo(afinfo); + return err; +} +EXPORT_SYMBOL(xfrm_unregister_type); + +struct xfrm_type *xfrm_get_type(u8 proto, unsigned short family) +{ + struct xfrm_policy_afinfo *afinfo; + struct xfrm_type **typemap; + struct xfrm_type *type; + int modload_attempted = 0; + +retry: + afinfo = xfrm_policy_get_afinfo(family); + if (unlikely(afinfo == NULL)) + return NULL; + typemap = afinfo->type_map; + + type = typemap[proto]; + if (unlikely(type && !try_module_get(type->owner))) + type = NULL; + if (!type && !modload_attempted) { + xfrm_policy_put_afinfo(afinfo); + request_module("xfrm-type-%d-%d", + (int) family, (int) proto); + modload_attempted = 1; + goto retry; + } + + xfrm_policy_put_afinfo(afinfo); + return type; +} + int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl, unsigned short family) { @@ -102,6 +170,94 @@ int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl, } EXPORT_SYMBOL(xfrm_dst_lookup); +void xfrm_put_type(struct xfrm_type *type) +{ + module_put(type->owner); +} + +int xfrm_register_mode(struct xfrm_mode *mode, int family) +{ + struct xfrm_policy_afinfo *afinfo; + struct xfrm_mode **modemap; + int err; + + if (unlikely(mode->encap >= XFRM_MODE_MAX)) + return -EINVAL; + + afinfo = xfrm_policy_lock_afinfo(family); + if (unlikely(afinfo == NULL)) + return -EAFNOSUPPORT; + + err = -EEXIST; + modemap = afinfo->mode_map; + if (likely(modemap[mode->encap] == NULL)) { + modemap[mode->encap] = mode; + err = 0; + } + + xfrm_policy_unlock_afinfo(afinfo); + return err; +} +EXPORT_SYMBOL(xfrm_register_mode); + +int xfrm_unregister_mode(struct xfrm_mode *mode, int family) +{ + struct xfrm_policy_afinfo *afinfo; + struct xfrm_mode **modemap; + int err; + + if (unlikely(mode->encap >= XFRM_MODE_MAX)) + return -EINVAL; + + afinfo = xfrm_policy_lock_afinfo(family); + if (unlikely(afinfo == NULL)) + return -EAFNOSUPPORT; + + err = -ENOENT; + modemap = afinfo->mode_map; + if (likely(modemap[mode->encap] == mode)) { + modemap[mode->encap] = NULL; + err = 0; + } + + xfrm_policy_unlock_afinfo(afinfo); + return err; +} +EXPORT_SYMBOL(xfrm_unregister_mode); + +struct xfrm_mode *xfrm_get_mode(unsigned int encap, int family) +{ + struct xfrm_policy_afinfo *afinfo; + struct xfrm_mode *mode; + int modload_attempted = 0; + + if (unlikely(encap >= XFRM_MODE_MAX)) + return NULL; + +retry: + afinfo = xfrm_policy_get_afinfo(family); + if (unlikely(afinfo == NULL)) + return NULL; + + mode = afinfo->mode_map[encap]; + if (unlikely(mode && !try_module_get(mode->owner))) + mode = NULL; + if (!mode && !modload_attempted) { + xfrm_policy_put_afinfo(afinfo); + request_module("xfrm-mode-%d-%d", family, encap); + modload_attempted = 1; + goto retry; + } + + xfrm_policy_put_afinfo(afinfo); + return mode; +} + +void xfrm_put_mode(struct xfrm_mode *mode) +{ + module_put(mode->owner); +} + static inline unsigned long make_jiffies(long secs) { if (secs >= (MAX_SCHEDULE_TIMEOUT-1)/HZ) @@ -1940,8 +2096,7 @@ int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *first, if (xdst->genid != dst->xfrm->genid) return 0; - if (strict && fl && - !(dst->xfrm->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) && + if (strict && fl && dst->xfrm->props.mode != XFRM_MODE_TUNNEL && !xfrm_state_addr_flow_check(dst->xfrm, fl, family)) return 0; @@ -2058,6 +2213,23 @@ static void xfrm_policy_put_afinfo(struct xfrm_policy_afinfo *afinfo) read_unlock(&xfrm_policy_afinfo_lock); } +static struct xfrm_policy_afinfo *xfrm_policy_lock_afinfo(unsigned int family) +{ + struct xfrm_policy_afinfo *afinfo; + if (unlikely(family >= NPROTO)) + return NULL; + write_lock_bh(&xfrm_policy_afinfo_lock); + afinfo = xfrm_policy_afinfo[family]; + if (unlikely(!afinfo)) + write_unlock_bh(&xfrm_policy_afinfo_lock); + return afinfo; +} + +static void xfrm_policy_unlock_afinfo(struct xfrm_policy_afinfo *afinfo) +{ + write_unlock_bh(&xfrm_policy_afinfo_lock); +} + static int xfrm_dev_event(struct notifier_block *this, unsigned long event, void *ptr) { struct net_device *dev = ptr; @@ -2292,8 +2464,7 @@ static int xfrm_policy_migrate(struct xfrm_policy *pol, if (!migrate_tmpl_match(mp, &pol->xfrm_vec[i])) continue; n++; - if (pol->xfrm_vec[i].mode != XFRM_MODE_TUNNEL && - pol->xfrm_vec[i].mode != XFRM_MODE_BEET) + if (pol->xfrm_vec[i].mode != XFRM_MODE_TUNNEL) continue; /* update endpoints */ memcpy(&pol->xfrm_vec[i].id.daddr, &mp->new_daddr, diff --git a/trunk/net/xfrm/xfrm_state.c b/trunk/net/xfrm/xfrm_state.c index 224b44e31a07..344f0a6abec5 100644 --- a/trunk/net/xfrm/xfrm_state.c +++ b/trunk/net/xfrm/xfrm_state.c @@ -57,9 +57,6 @@ static unsigned int xfrm_state_hashmax __read_mostly = 1 * 1024 * 1024; static unsigned int xfrm_state_num; static unsigned int xfrm_state_genid; -static struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family); -static void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo); - static inline unsigned int xfrm_dst_hash(xfrm_address_t *daddr, xfrm_address_t *saddr, u32 reqid, @@ -190,184 +187,6 @@ int __xfrm_state_delete(struct xfrm_state *x); int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *pol); void km_state_expired(struct xfrm_state *x, int hard, u32 pid); -static struct xfrm_state_afinfo *xfrm_state_lock_afinfo(unsigned int family) -{ - struct xfrm_state_afinfo *afinfo; - if (unlikely(family >= NPROTO)) - return NULL; - write_lock_bh(&xfrm_state_afinfo_lock); - afinfo = xfrm_state_afinfo[family]; - if (unlikely(!afinfo)) - write_unlock_bh(&xfrm_state_afinfo_lock); - return afinfo; -} - -static void xfrm_state_unlock_afinfo(struct xfrm_state_afinfo *afinfo) -{ - write_unlock_bh(&xfrm_state_afinfo_lock); -} - -int xfrm_register_type(struct xfrm_type *type, unsigned short family) -{ - struct xfrm_state_afinfo *afinfo = xfrm_state_lock_afinfo(family); - struct xfrm_type **typemap; - int err = 0; - - if (unlikely(afinfo == NULL)) - return -EAFNOSUPPORT; - typemap = afinfo->type_map; - - if (likely(typemap[type->proto] == NULL)) - typemap[type->proto] = type; - else - err = -EEXIST; - xfrm_state_unlock_afinfo(afinfo); - return err; -} -EXPORT_SYMBOL(xfrm_register_type); - -int xfrm_unregister_type(struct xfrm_type *type, unsigned short family) -{ - struct xfrm_state_afinfo *afinfo = xfrm_state_lock_afinfo(family); - struct xfrm_type **typemap; - int err = 0; - - if (unlikely(afinfo == NULL)) - return -EAFNOSUPPORT; - typemap = afinfo->type_map; - - if (unlikely(typemap[type->proto] != type)) - err = -ENOENT; - else - typemap[type->proto] = NULL; - xfrm_state_unlock_afinfo(afinfo); - return err; -} -EXPORT_SYMBOL(xfrm_unregister_type); - -static struct xfrm_type *xfrm_get_type(u8 proto, unsigned short family) -{ - struct xfrm_state_afinfo *afinfo; - struct xfrm_type **typemap; - struct xfrm_type *type; - int modload_attempted = 0; - -retry: - afinfo = xfrm_state_get_afinfo(family); - if (unlikely(afinfo == NULL)) - return NULL; - typemap = afinfo->type_map; - - type = typemap[proto]; - if (unlikely(type && !try_module_get(type->owner))) - type = NULL; - if (!type && !modload_attempted) { - xfrm_state_put_afinfo(afinfo); - request_module("xfrm-type-%d-%d", family, proto); - modload_attempted = 1; - goto retry; - } - - xfrm_state_put_afinfo(afinfo); - return type; -} - -static void xfrm_put_type(struct xfrm_type *type) -{ - module_put(type->owner); -} - -int xfrm_register_mode(struct xfrm_mode *mode, int family) -{ - struct xfrm_state_afinfo *afinfo; - struct xfrm_mode **modemap; - int err; - - if (unlikely(mode->encap >= XFRM_MODE_MAX)) - return -EINVAL; - - afinfo = xfrm_state_lock_afinfo(family); - if (unlikely(afinfo == NULL)) - return -EAFNOSUPPORT; - - err = -EEXIST; - modemap = afinfo->mode_map; - if (modemap[mode->encap]) - goto out; - - err = -ENOENT; - if (!try_module_get(afinfo->owner)) - goto out; - - mode->afinfo = afinfo; - modemap[mode->encap] = mode; - err = 0; - -out: - xfrm_state_unlock_afinfo(afinfo); - return err; -} -EXPORT_SYMBOL(xfrm_register_mode); - -int xfrm_unregister_mode(struct xfrm_mode *mode, int family) -{ - struct xfrm_state_afinfo *afinfo; - struct xfrm_mode **modemap; - int err; - - if (unlikely(mode->encap >= XFRM_MODE_MAX)) - return -EINVAL; - - afinfo = xfrm_state_lock_afinfo(family); - if (unlikely(afinfo == NULL)) - return -EAFNOSUPPORT; - - err = -ENOENT; - modemap = afinfo->mode_map; - if (likely(modemap[mode->encap] == mode)) { - modemap[mode->encap] = NULL; - module_put(mode->afinfo->owner); - err = 0; - } - - xfrm_state_unlock_afinfo(afinfo); - return err; -} -EXPORT_SYMBOL(xfrm_unregister_mode); - -static struct xfrm_mode *xfrm_get_mode(unsigned int encap, int family) -{ - struct xfrm_state_afinfo *afinfo; - struct xfrm_mode *mode; - int modload_attempted = 0; - - if (unlikely(encap >= XFRM_MODE_MAX)) - return NULL; - -retry: - afinfo = xfrm_state_get_afinfo(family); - if (unlikely(afinfo == NULL)) - return NULL; - - mode = afinfo->mode_map[encap]; - if (unlikely(mode && !try_module_get(mode->owner))) - mode = NULL; - if (!mode && !modload_attempted) { - xfrm_state_put_afinfo(afinfo); - request_module("xfrm-mode-%d-%d", family, encap); - modload_attempted = 1; - goto retry; - } - - xfrm_state_put_afinfo(afinfo); - return mode; -} - -static void xfrm_put_mode(struct xfrm_mode *mode) -{ - module_put(mode->owner); -} - static void xfrm_state_gc_destroy(struct xfrm_state *x) { del_timer_sync(&x->timer); @@ -377,10 +196,8 @@ static void xfrm_state_gc_destroy(struct xfrm_state *x) kfree(x->calg); kfree(x->encap); kfree(x->coaddr); - if (x->inner_mode) - xfrm_put_mode(x->inner_mode); - if (x->outer_mode) - xfrm_put_mode(x->outer_mode); + if (x->mode) + xfrm_put_mode(x->mode); if (x->type) { x->type->destructor(x); xfrm_put_type(x->type); @@ -1882,7 +1699,7 @@ int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo) } EXPORT_SYMBOL(xfrm_state_unregister_afinfo); -static struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family) +struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned short family) { struct xfrm_state_afinfo *afinfo; if (unlikely(family >= NPROTO)) @@ -1894,11 +1711,14 @@ static struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family) return afinfo; } -static void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo) +void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo) { read_unlock(&xfrm_state_afinfo_lock); } +EXPORT_SYMBOL(xfrm_state_get_afinfo); +EXPORT_SYMBOL(xfrm_state_put_afinfo); + /* Temporarily located here until net/xfrm/xfrm_tunnel.c is created */ void xfrm_state_delete_tunnel(struct xfrm_state *x) { @@ -1949,14 +1769,6 @@ int xfrm_init_state(struct xfrm_state *x) goto error; err = -EPROTONOSUPPORT; - x->inner_mode = xfrm_get_mode(x->props.mode, x->sel.family); - if (x->inner_mode == NULL) - goto error; - - if (!(x->inner_mode->flags & XFRM_MODE_FLAG_TUNNEL) && - family != x->sel.family) - goto error; - x->type = xfrm_get_type(x->id.proto, family); if (x->type == NULL) goto error; @@ -1965,8 +1777,8 @@ int xfrm_init_state(struct xfrm_state *x) if (err) goto error; - x->outer_mode = xfrm_get_mode(x->props.mode, family); - if (x->outer_mode == NULL) + x->mode = xfrm_get_mode(x->props.mode, family); + if (x->mode == NULL) goto error; x->km.state = XFRM_STATE_VALID; diff --git a/trunk/samples/Kconfig b/trunk/samples/Kconfig deleted file mode 100644 index 57bb2236952c..000000000000 --- a/trunk/samples/Kconfig +++ /dev/null @@ -1,16 +0,0 @@ -# samples/Kconfig - -menuconfig SAMPLES - bool "Sample kernel code" - help - You can build and test sample kernel code here. - -if SAMPLES - -config SAMPLE_MARKERS - tristate "Build markers examples -- loadable modules only" - depends on MARKERS && m - help - This build markers example modules. - -endif # SAMPLES diff --git a/trunk/samples/Makefile b/trunk/samples/Makefile deleted file mode 100644 index 5a4f0b6bcbed..000000000000 --- a/trunk/samples/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -# Makefile for Linux samples code - -obj-$(CONFIG_SAMPLES) += markers/ diff --git a/trunk/samples/markers/Makefile b/trunk/samples/markers/Makefile deleted file mode 100644 index 6d7231265f0f..000000000000 --- a/trunk/samples/markers/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -# builds the kprobes example kernel modules; -# then to use one (as root): insmod - -obj-$(CONFIG_SAMPLE_MARKERS) += probe-example.o marker-example.o diff --git a/trunk/samples/markers/marker-example.c b/trunk/samples/markers/marker-example.c deleted file mode 100644 index e787c6d16dd7..000000000000 --- a/trunk/samples/markers/marker-example.c +++ /dev/null @@ -1,54 +0,0 @@ -/* marker-example.c - * - * Executes a marker when /proc/marker-example is opened. - * - * (C) Copyright 2007 Mathieu Desnoyers - * - * This file is released under the GPLv2. - * See the file COPYING for more details. - */ - -#include -#include -#include -#include - -struct proc_dir_entry *pentry_example; - -static int my_open(struct inode *inode, struct file *file) -{ - int i; - - trace_mark(subsystem_event, "%d %s", 123, "example string"); - for (i = 0; i < 10; i++) - trace_mark(subsystem_eventb, MARK_NOARGS); - return -EPERM; -} - -static struct file_operations mark_ops = { - .open = my_open, -}; - -static int example_init(void) -{ - printk(KERN_ALERT "example init\n"); - pentry_example = create_proc_entry("marker-example", 0444, NULL); - if (pentry_example) - pentry_example->proc_fops = &mark_ops; - else - return -EPERM; - return 0; -} - -static void example_exit(void) -{ - printk(KERN_ALERT "example exit\n"); - remove_proc_entry("marker-example", NULL); -} - -module_init(example_init) -module_exit(example_exit) - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mathieu Desnoyers"); -MODULE_DESCRIPTION("Marker example"); diff --git a/trunk/samples/markers/probe-example.c b/trunk/samples/markers/probe-example.c deleted file mode 100644 index 238b2e384fc8..000000000000 --- a/trunk/samples/markers/probe-example.c +++ /dev/null @@ -1,98 +0,0 @@ -/* probe-example.c - * - * Connects two functions to marker call sites. - * - * (C) Copyright 2007 Mathieu Desnoyers - * - * This file is released under the GPLv2. - * See the file COPYING for more details. - */ - -#include -#include -#include -#include -#include - -struct probe_data { - const char *name; - const char *format; - marker_probe_func *probe_func; -}; - -void probe_subsystem_event(const struct marker *mdata, void *private, - const char *format, ...) -{ - va_list ap; - /* Declare args */ - unsigned int value; - const char *mystr; - - /* Assign args */ - va_start(ap, format); - value = va_arg(ap, typeof(value)); - mystr = va_arg(ap, typeof(mystr)); - - /* Call printk */ - printk(KERN_DEBUG "Value %u, string %s\n", value, mystr); - - /* or count, check rights, serialize data in a buffer */ - - va_end(ap); -} - -atomic_t eventb_count = ATOMIC_INIT(0); - -void probe_subsystem_eventb(const struct marker *mdata, void *private, - const char *format, ...) -{ - /* Increment counter */ - atomic_inc(&eventb_count); -} - -static struct probe_data probe_array[] = -{ - { .name = "subsystem_event", - .format = "%d %s", - .probe_func = probe_subsystem_event }, - { .name = "subsystem_eventb", - .format = MARK_NOARGS, - .probe_func = probe_subsystem_eventb }, -}; - -static int __init probe_init(void) -{ - int result; - int i; - - for (i = 0; i < ARRAY_SIZE(probe_array); i++) { - result = marker_probe_register(probe_array[i].name, - probe_array[i].format, - probe_array[i].probe_func, &probe_array[i]); - if (result) - printk(KERN_INFO "Unable to register probe %s\n", - probe_array[i].name); - result = marker_arm(probe_array[i].name); - if (result) - printk(KERN_INFO "Unable to arm probe %s\n", - probe_array[i].name); - } - return 0; -} - -static void __exit probe_fini(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(probe_array); i++) - marker_probe_unregister(probe_array[i].name); - printk(KERN_INFO "Number of event b : %u\n", - atomic_read(&eventb_count)); -} - -module_init(probe_init); -module_exit(probe_fini); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Mathieu Desnoyers"); -MODULE_DESCRIPTION("SUBSYSTEM Probe"); diff --git a/trunk/scripts/checkpatch.pl b/trunk/scripts/checkpatch.pl index cbb42580a81d..59ad83caa210 100755 --- a/trunk/scripts/checkpatch.pl +++ b/trunk/scripts/checkpatch.pl @@ -9,7 +9,7 @@ my $P = $0; $P =~ s@.*/@@g; -my $V = '0.11'; +my $V = '0.10'; use Getopt::Long qw(:config no_auto_abbrev); @@ -18,21 +18,12 @@ my $chk_signoff = 1; my $chk_patch = 1; my $tst_type = 0; -my $emacs = 0; -my $file = 0; -my $check = 0; -my $root; GetOptions( - 'q|quiet+' => \$quiet, + 'q|quiet' => \$quiet, 'tree!' => \$tree, 'signoff!' => \$chk_signoff, 'patch!' => \$chk_patch, 'test-type!' => \$tst_type, - 'emacs!' => \$emacs, - 'file!' => \$file, - 'subjective!' => \$check, - 'strict!' => \$check, - 'root=s' => \$root, ) or exit; my $exit = 0; @@ -42,110 +33,19 @@ print "version: $V\n"; print "options: -q => quiet\n"; print " --no-tree => run without a kernel tree\n"; - print " --emacs => emacs compile window format\n"; - print " --file => check a source file\n"; - print " --strict => enable more subjective tests\n"; - print " --root => path to the kernel tree root\n"; exit(1); } -if ($tree) { - if (defined $root) { - if (!top_of_kernel_tree($root)) { - die "$P: $root: --root does not point at a valid tree\n"; - } - } else { - if (top_of_kernel_tree('.')) { - $root = '.'; - } elsif ($0 =~ m@(.*)/scripts/[^/]*$@ && - top_of_kernel_tree($1)) { - $root = $1; - } - } - - if (!defined $root) { - print "Must be run from the top-level dir. of a kernel tree\n"; - exit(2); - } +if ($tree && !top_of_kernel_tree()) { + print "Must be run from the top-level dir. of a kernel tree\n"; + exit(2); } -my $emitted_corrupt = 0; - -our $Ident = qr{[A-Za-z_][A-Za-z\d_]*}; -our $Storage = qr{extern|static|asmlinkage}; -our $Sparse = qr{ - __user| - __kernel| - __force| - __iomem| - __must_check| - __init_refok| - __kprobes| - fastcall - }x; -our $Attribute = qr{ - const| - __read_mostly| - __kprobes| - __(?:mem|cpu|dev|)(?:initdata|init) - }x; -our $Inline = qr{inline|__always_inline|noinline}; -our $NonptrType = qr{ - \b - (?:const\s+)? - (?:unsigned\s+)? - (?: - void| - char| - short| - int| - long| - unsigned| - float| - double| - bool| - long\s+int| - long\s+long| - long\s+long\s+int| - (?:__)?(?:u|s|be|le)(?:8|16|32|64)| - struct\s+$Ident| - union\s+$Ident| - enum\s+$Ident| - ${Ident}_t| - ${Ident}_handler| - ${Ident}_handler_fn - ) - (?:\s+$Sparse)* - \b - }x; - -our $Type = qr{ - \b$NonptrType\b - (?:\s*\*+\s*const|\s*\*+|(?:\s*\[\s*\])+)? - (?:\s+$Sparse|\s+$Attribute)* - }x; -our $Declare = qr{(?:$Storage\s+)?$Type}; -our $Member = qr{->$Ident|\.$Ident|\[[^]]*\]}; -our $Lval = qr{$Ident(?:$Member)*}; - -our $Constant = qr{(?:[0-9]+|0x[0-9a-fA-F]+)[UL]*}; -our $Assignment = qr{(?:\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=)}; -our $Operators = qr{ - <=|>=|==|!=| - =>|->|<<|>>|<|>|!|~| - &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/ - }x; - -our $Bare = ''; - -$chk_signoff = 0 if ($file); - my @dep_includes = (); my @dep_functions = (); -my $removal = "Documentation/feature-removal-schedule.txt"; -if ($tree && -f "$root/$removal") { - open(REMOVE, "<$root/$removal") || - die "$P: $removal: open failed - $!\n"; +my $removal = 'Documentation/feature-removal-schedule.txt'; +if ($tree && -f $removal) { + open(REMOVE, "<$removal") || die "$P: $removal: open failed - $!\n"; while () { if (/^Check:\s+(.*\S)/) { for my $entry (split(/[, ]+/, $1)) { @@ -161,42 +61,28 @@ } my @rawlines = (); -for my $filename (@ARGV) { - if ($file) { - open(FILE, "diff -u /dev/null $filename|") || - die "$P: $filename: diff failed - $!\n"; - } else { - open(FILE, "<$filename") || - die "$P: $filename: open failed - $!\n"; +while (<>) { + chomp; + push(@rawlines, $_); + if (eof(ARGV)) { + if (!process($ARGV, @rawlines)) { + $exit = 1; + } + @rawlines = (); } - while () { - chomp; - push(@rawlines, $_); - } - close(FILE); - if (!process($filename, @rawlines)) { - $exit = 1; - } - @rawlines = (); } exit($exit); sub top_of_kernel_tree { - my ($root) = @_; - - my @tree_check = ( - "COPYING", "CREDITS", "Kbuild", "MAINTAINERS", "Makefile", - "README", "Documentation", "arch", "include", "drivers", - "fs", "init", "ipc", "kernel", "lib", "scripts", - ); - - foreach my $check (@tree_check) { - if (! -e $root . '/' . $check) { - return 0; - } + if ((-f "COPYING") && (-f "CREDITS") && (-f "Kbuild") && + (-f "MAINTAINERS") && (-f "Makefile") && (-f "README") && + (-d "Documentation") && (-d "arch") && (-d "include") && + (-d "drivers") && (-d "fs") && (-d "init") && (-d "ipc") && + (-d "kernel") && (-d "lib") && (-d "scripts")) { + return 1; } - return 1; + return 0; } sub expand_tabs { @@ -219,20 +105,6 @@ sub expand_tabs { return $res; } -sub copy_spacing { - my ($str) = @_; - - my $res = ''; - for my $c (split(//, $str)) { - if ($c eq "\t") { - $res .= $c; - } else { - $res .= ' '; - } - } - - return $res; -} sub line_stats { my ($line) = @_; @@ -388,138 +260,47 @@ sub ctx_has_comment { return ($cmt ne ''); } -sub cat_vet { - my ($vet) = @_; - my ($res, $coded); - - $res = ''; - while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]]|$)/g) { - $res .= $1; - if ($2 ne '') { - $coded = sprintf("^%c", unpack('C', $2) + 64); - $res .= $coded; - } - } - $res =~ s/$/\$/; - - return $res; -} - -sub annotate_values { - my ($stream, $type) = @_; - - my $res; - my $cur = $stream; - - my $debug = 0; - - print "$stream\n" if ($debug); - - ##my $type = 'N'; - my $pos = 0; - my $preprocessor = 0; - my $paren = 0; - my @paren_type; - - # Include any user defined types we may have found as we went. - my $type_match = "(?:$Type$Bare)"; - - while (length($cur)) { - print " <$type> " if ($debug); - if ($cur =~ /^(\s+)/o) { - print "WS($1)\n" if ($debug); - if ($1 =~ /\n/ && $preprocessor) { - $preprocessor = 0; - $type = 'N'; - } - - } elsif ($cur =~ /^($type_match)/) { - print "DECLARE($1)\n" if ($debug); - $type = 'T'; - - } elsif ($cur =~ /^(#\s*define\s*$Ident)(\(?)/o) { - print "DEFINE($1)\n" if ($debug); - $preprocessor = 1; - $paren_type[$paren] = 'N'; +sub ctx_expr_before { + my ($line) = @_; - } elsif ($cur =~ /^(#\s*(?:ifdef|ifndef|if|else|endif))/o) { - print "PRE($1)\n" if ($debug); - $preprocessor = 1; - $type = 'N'; + ##print "CHECK<$line>\n"; - } elsif ($cur =~ /^(\\\n)/o) { - print "PRECONT($1)\n" if ($debug); + my $pos = length($line) - 1; + my $count = 0; + my $c; - } elsif ($cur =~ /^(sizeof)\s*(\()?/o) { - print "SIZEOF($1)\n" if ($debug); - if (defined $2) { - $paren_type[$paren] = 'V'; - } - $type = 'N'; - - } elsif ($cur =~ /^(if|while|typeof)\b/o) { - print "COND($1)\n" if ($debug); - $paren_type[$paren] = 'N'; - $type = 'N'; - - } elsif ($cur =~/^(return|case|else)/o) { - print "KEYWORD($1)\n" if ($debug); - $type = 'N'; - - } elsif ($cur =~ /^(\()/o) { - print "PAREN('$1')\n" if ($debug); - $paren++; - $type = 'N'; - - } elsif ($cur =~ /^(\))/o) { - $paren-- if ($paren > 0); - if (defined $paren_type[$paren]) { - $type = $paren_type[$paren]; - undef $paren_type[$paren]; - print "PAREN('$1') -> $type\n" if ($debug); - } else { - print "PAREN('$1')\n" if ($debug); - } - - } elsif ($cur =~ /^($Ident)\(/o) { - print "FUNC($1)\n" if ($debug); - $paren_type[$paren] = 'V'; - - } elsif ($cur =~ /^($Ident|$Constant)/o) { - print "IDENT($1)\n" if ($debug); - $type = 'V'; + for (; $pos >= 0; $pos--) { + $c = substr($line, $pos, 1); + ##print "CHECK: c<$c> count<$count>\n"; + if ($c eq ')') { + $count++; + } elsif ($c eq '(') { + last if (--$count == 0); + } + } - } elsif ($cur =~ /^($Assignment)/o) { - print "ASSIGN($1)\n" if ($debug); - $type = 'N'; + ##print "CHECK: result<" . substr($line, 0, $pos) . ">\n"; - } elsif ($cur =~ /^(;|{|}|\?|:|\[)/o) { - print "END($1)\n" if ($debug); - $type = 'N'; + return substr($line, 0, $pos); +} - } elsif ($cur =~ /^($Operators)/o) { - print "OP($1)\n" if ($debug); - if ($1 ne '++' && $1 ne '--') { - $type = 'N'; - } +sub cat_vet { + my ($vet) = @_; + my ($res, $coded); - } elsif ($cur =~ /(^.)/o) { - print "C($1)\n" if ($debug); - } - if (defined $1) { - $cur = substr($cur, length($1)); - $res .= $type x length($1); - } + $res = ''; + while ($vet =~ /([^[:cntrl:]]*)([[:cntrl:]])/g) { + $coded = sprintf("^%c", unpack('C', $2) + 64); + $res .= $1 . $coded; } + $res =~ s/$/\$/; return $res; } -my $prefix = ''; - my @report = (); sub report { - push(@report, $prefix . $_[0]); + push(@report, $_[0]); } sub report_dump { @report; @@ -527,19 +308,14 @@ sub report_dump { sub ERROR { report("ERROR: $_[0]\n"); our $clean = 0; - our $cnt_error++; } sub WARN { report("WARNING: $_[0]\n"); our $clean = 0; - our $cnt_warn++; } sub CHK { - if ($check) { - report("CHECK: $_[0]\n"); - our $clean = 0; - our $cnt_chk++; - } + report("CHECK: $_[0]\n"); + our $clean = 0; } sub process { @@ -559,11 +335,6 @@ sub process { my $signoff = 0; my $is_patch = 0; - our $cnt_lines = 0; - our $cnt_error = 0; - our $cnt_warn = 0; - our $cnt_chk = 0; - # Trace the real file/line as we go. my $realfile = ''; my $realline = 0; @@ -572,10 +343,62 @@ sub process { my $in_comment = 0; my $first_line = 0; - my $prev_values = 'N'; + my $Ident = qr{[A-Za-z\d_]+}; + my $Storage = qr{extern|static|asmlinkage}; + my $Sparse = qr{ + __user| + __kernel| + __force| + __iomem| + __must_check| + __init_refok| + fastcall + }x; + my $Inline = qr{inline|__always_inline|noinline}; + my $NonptrType = qr{ + \b + (?:const\s+)? + (?:unsigned\s+)? + (?: + void| + char| + short| + int| + long| + unsigned| + float| + double| + bool| + long\s+int| + long\s+long| + long\s+long\s+int| + u8|u16|u32|u64| + s8|s16|s32|s64| + struct\s+$Ident| + union\s+$Ident| + enum\s+$Ident| + ${Ident}_t + ) + (?:\s+$Sparse)* + \b + }x; + my $Type = qr{ + \b$NonptrType\b + (?:\s*\*+\s*const|\s*\*+|(?:\s*\[\s*\])+)? + (?:\s+$Sparse)* + }x; + my $Declare = qr{(?:$Storage\s+)?$Type}; + my $Attribute = qr{ + const| + __read_mostly| + __(?:mem|cpu|dev|)(?:initdata|init) + }x; + my $Member = qr{->$Ident|\.$Ident|\[[^]]*\]}; + my $Lval = qr{$Ident(?:$Member)*}; # Possible bare types. my @bare = (); + my $Bare = $NonptrType; # Pre-scan the patch looking for any __setup documentation. my @setup_docs = (); @@ -594,14 +417,11 @@ sub process { } } - $prefix = ''; - foreach my $line (@lines) { $linenr++; my $rawline = $line; - #extract the filename as it passes if ($line=~/^\+\+\+\s+(\S+)/) { $realfile=$1; @@ -610,7 +430,7 @@ sub process { next; } #extract the line range in the file after the patch is applied - if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) { + if ($line=~/^\@\@ -\d+,\d+ \+(\d+)(,(\d+))? \@\@/) { $is_patch = 1; $first_line = $linenr + 1; $in_comment = 0; @@ -620,7 +440,6 @@ sub process { } else { $realcnt=1+1; } - $prev_values = 'N'; next; } @@ -654,24 +473,18 @@ sub process { # Track the previous line. ($prevline, $stashline) = ($stashline, $line); ($previndent, $stashindent) = ($stashindent, $indent); - } elsif ($realcnt == 1) { $realcnt--; } #make up the handle for any error we report on this line - $here = "#$linenr: " if (!$file); - $here = "#$realline: " if ($file); + $here = "#$linenr: "; $here .= "FILE: $realfile:$realline:" if ($realcnt != 0); my $hereline = "$here\n$line\n"; my $herecurr = "$here\n$line\n"; my $hereprev = "$here\n$prevline\n$line\n"; - $prefix = "$filename:$realline: " if ($emacs && $file); - $prefix = "$filename:$linenr: " if ($emacs && !$file); - $cnt_lines++ if ($realcnt != 0); - #check the patch for a signoff: if ($line =~ /^\s*signed-off-by:/i) { # This is a signoff, if ugly, so do not double report. @@ -689,7 +502,7 @@ sub process { # Check for wrappage within a valid hunk of the file if ($realcnt != 0 && $line !~ m{^(?:\+|-| |$)}) { ERROR("patch seems to be corrupt (line wrapped?)\n" . - $herecurr) if (!$emitted_corrupt++); + $herecurr); } # UTF-8 regex found at http://www.w3.org/International/questions/qa-forms-utf-8.en.php @@ -755,12 +568,8 @@ sub process { $line !~ /^.\s*(?:$Storage\s+)?(?:$Inline\s+)?$Type\b/ && $line !~ /$Ident:\s*$/ && $line !~ /^.\s*$Ident\s*\(/ && - # definitions in global scope can only start with types ($line =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?($Ident)\b/ || - # declarations always start with types - $line =~ /^.\s*(?:$Storage\s+)?($Ident)\b\s*\**\s*$Ident\s*(?:;|=)/) || - # any (foo ... *) is a pointer cast, and foo is a type - $line =~ /\(($Ident)(?:\s+$Sparse)*\s*\*+\s*\)/) { + $line =~ /^.\s*(?:$Storage\s+)?($Ident)\b\s*\**\s*$Ident\s*(?:;|=)/)) { my $possible = $1; if ($possible !~ /^(?:$Storage|$Type|DEFINE_\S+)$/ && $possible ne 'goto' && $possible ne 'return' && @@ -770,7 +579,7 @@ sub process { #print "POSSIBLE<$possible>\n"; push(@bare, $possible); my $bare = join("|", @bare); - $Bare = '|' . qr{ + $Bare = qr{ \b(?:$bare)\b (?:\s*\*+\s*const|\s*\*+|(?:\s*\[\s*\])+)? (?:\s+$Sparse)* @@ -832,14 +641,6 @@ sub process { } } - # Track the 'values' across context and added lines. - my $opline = $line; $opline =~ s/^./ /; - my $curr_values = annotate_values($opline . "\n", $prev_values); - $curr_values = $prev_values . $curr_values; - #warn "--> $opline\n"; - #warn "--> $curr_values ($prev_values)\n"; - $prev_values = substr($curr_values, -1); - #ignore lines not being added if ($line=~/^[^\+]/) {next;} @@ -877,7 +678,6 @@ sub process { } # Remove C99 comments. $line =~ s@//.*@@; - $opline =~ s@//.*@@; #EXPORT_SYMBOL should immediately follow its function closing }. if (($line =~ /EXPORT_SYMBOL.*\((.*)\)/) || @@ -966,13 +766,18 @@ sub process { } # check for spaces between functions and their parentheses. - while ($line =~ /($Ident)\s+\(/g) { - if ($1 !~ /^(?:if|for|while|switch|return|volatile|__volatile__|__attribute__|format|__extension__|Copyright|case)$/ && - $line !~ /$Type\s+\(/ && $line !~ /^.\#\s*define\b/) { - WARN("no space between function name and open parenthesis '('\n" . $herecurr); - } + if ($line =~ /($Ident)\s+\(/ && + $1 !~ /^(?:if|for|while|switch|return|volatile|__volatile__|__attribute__|format|__extension__|Copyright)$/ && + $line !~ /$Type\s+\(/ && $line !~ /^.\#\s*define\b/) { + WARN("no space between function name and open parenthesis '('\n" . $herecurr); } # Check operator spacing. + # Note we expand the line with the leading + as the real + # line will be displayed with the leading + and the tabs + # will therefore also expand that way. + my $opline = $line; + $opline = expand_tabs($opline); + $opline =~ s/^./ /; if (!($line=~/\#\s*include/)) { my $ops = qr{ <<=|>>=|<=|>=|==|!=| @@ -982,9 +787,6 @@ sub process { }x; my @elements = split(/($ops|;)/, $opline); my $off = 0; - - my $blank = copy_spacing($opline); - for (my $n = 0; $n < $#elements; $n += 2) { $off += length($elements[$n]); @@ -1020,24 +822,62 @@ sub process { my $at = "(ctx:$ctx)"; - my $ptr = substr($blank, 0, $off) . "^"; + my $ptr = (" " x $off) . "^"; my $hereptr = "$hereline$ptr\n"; # Classify operators into binary, unary, or # definitions (* only) where they have more # than one mode. - my $op_type = substr($curr_values, $off + 1, 1); - my $op_left = substr($curr_values, $off, 1); - my $is_unary; - if ($op_type eq 'T') { - $is_unary = 2; - } elsif ($op_left eq 'V') { - $is_unary = 0; - } else { - $is_unary = 1; + my $unary_ctx = $prevline . $ca; + $unary_ctx =~ s/^./ /; + my $is_unary = 0; + my $Unary = qr{ + (?: + ^|;|,|$ops|\(|\?|:| + \(\s*$Type\s*\)| + $Type| + return|case|else| + \{|\}| + \[| + ^.\#\s*define\s+$Ident\s*(?:\([^\)]*\))?| + ^.\#\s*else| + ^.\#\s*endif| + ^.\#\s*(?:if|ifndef|ifdef)\b.* + )\s*(?:|\\)\s*$ + }x; + my $UnaryFalse = qr{ + sizeof\s*\(\s*$Type\s*\)\s*$ + }x; + my $UnaryDefine = qr{ + (?:$Type|$Bare)\s*| + (?:$Type|$Bare).*,\s*\** + }x; + if ($op eq '-' || $op eq '&' || $op eq '*') { + # An operator is binary if the left hand + # side is a value. Pick out the known + # non-values. + if ($unary_ctx =~ /$Unary$/s && + $unary_ctx !~ /$UnaryFalse$/s) { + $is_unary = 1; + + # Special handling for ')' check if this + # brace represents a conditional, if so + # we are unary. + } elsif ($unary_ctx =~ /\)\s*$/) { + my $before = ctx_expr_before($unary_ctx); + if ($before =~ /(?:for|if|while)\s*$/) { + $is_unary = 1; + } + } + + # Check for type definition for of '*'. + if ($op eq '*' && $unary_ctx =~ /$UnaryDefine$/) { + $is_unary = 2; + } } + #if ($op eq '-' || $op eq '&' || $op eq '*') { - # print "UNARY: <$op_left$op_type $is_unary $a:$op:$c> <$ca:$op:$cc> <$unary_ctx>\n"; + # print "UNARY: <$is_unary $a:$op:$c> <$ca:$op:$cc> <$unary_ctx>\n"; #} # ; should have either the end of line or a space or \ after it @@ -1112,7 +952,7 @@ sub process { # check for multiple assignments if ($line =~ /^.\s*$Lval\s*=\s*$Lval\s*=(?!=)/) { - CHK("multiple assignments should be avoided\n" . $herecurr); + WARN("multiple assignments should be avoided\n" . $herecurr); } ## # check for multiple declarations, allowing for a function declaration @@ -1172,7 +1012,7 @@ sub process { } # Check for illegal assignment in if conditional. - if ($line=~/\bif\s*\(.*[^<>!=]=[^=]/) { + if ($line=~/\bif\s*\(.*[^<>!=]=[^=].*\)/) { #next if ($line=~/\".*\Q$op\E.*\"/ or $line=~/\'\Q$op\E\'/); ERROR("do not use assignment in if condition\n" . $herecurr); } @@ -1198,8 +1038,8 @@ sub process { #warn if is #included and is available (uses RAW line) if ($tree && $rawline =~ m{^.\#\s*include\s*\}) { - my $checkfile = "$root/include/linux/$1.h"; - if (-f $checkfile && $1 ne 'irq.h') { + my $checkfile = "include/linux/$1.h"; + if (-f $checkfile) { CHK("Use #include instead of \n" . $herecurr); } @@ -1311,8 +1151,7 @@ sub process { } # no volatiles please - my $asm_volatile = qr{\b(__asm__|asm)\s+(__volatile__|volatile)\b}; - if ($line =~ /\bvolatile\b/ && $line !~ /$asm_volatile/) { + if ($line =~ /\bvolatile\b/ && $line !~ /\basm\s+volatile\b/) { WARN("Use of volatile is usually wrong: see Documentation/volatile-considered-harmful.txt\n" . $herecurr); } @@ -1401,11 +1240,6 @@ sub process { if ($clean == 0 && ($chk_patch || $is_patch)) { print report_dump(); - if ($quiet < 2) { - print "total: $cnt_error errors, $cnt_warn warnings, " . - (($check)? "$cnt_chk checks, " : "") . - "$cnt_lines lines checked\n"; - } } if ($clean == 1 && $quiet == 0) { print "Your patch has no obvious style problems and is ready for submission.\n" diff --git a/trunk/scripts/checkstack.pl b/trunk/scripts/checkstack.pl index 28e480c8100f..b458e2acb4ac 100755 --- a/trunk/scripts/checkstack.pl +++ b/trunk/scripts/checkstack.pl @@ -15,7 +15,7 @@ # AVR32 port by Haavard Skinnemoen # # Usage: -# objdump -d vmlinux | scripts/checkstack.pl [arch] +# objdump -d vmlinux | stackcheck.pl [arch] # # TODO : Port to all architectures (one regex per arch) diff --git a/trunk/security/commoncap.c b/trunk/security/commoncap.c index 43f902750a1b..778cb0cfc5d8 100644 --- a/trunk/security/commoncap.c +++ b/trunk/security/commoncap.c @@ -23,26 +23,6 @@ #include #include #include -#include - -#ifdef CONFIG_SECURITY_FILE_CAPABILITIES -/* - * Because of the reduced scope of CAP_SETPCAP when filesystem - * capabilities are in effect, it is safe to allow this capability to - * be available in the default configuration. - */ -# define CAP_INIT_BSET CAP_FULL_SET -#else /* ie. ndef CONFIG_SECURITY_FILE_CAPABILITIES */ -# define CAP_INIT_BSET CAP_INIT_EFF_SET -#endif /* def CONFIG_SECURITY_FILE_CAPABILITIES */ - -kernel_cap_t cap_bset = CAP_INIT_BSET; /* systemwide capability bound */ -EXPORT_SYMBOL(cap_bset); - -/* Global security state */ - -unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */ -EXPORT_SYMBOL(securebits); int cap_netlink_send(struct sock *sk, struct sk_buff *skb) { @@ -93,44 +73,14 @@ int cap_capget (struct task_struct *target, kernel_cap_t *effective, return 0; } -#ifdef CONFIG_SECURITY_FILE_CAPABILITIES - -static inline int cap_block_setpcap(struct task_struct *target) -{ - /* - * No support for remote process capability manipulation with - * filesystem capability support. - */ - return (target != current); -} - -static inline int cap_inh_is_capped(void) -{ - /* - * return 1 if changes to the inheritable set are limited - * to the old permitted set. - */ - return !cap_capable(current, CAP_SETPCAP); -} - -#else /* ie., ndef CONFIG_SECURITY_FILE_CAPABILITIES */ - -static inline int cap_block_setpcap(struct task_struct *t) { return 0; } -static inline int cap_inh_is_capped(void) { return 1; } - -#endif /* def CONFIG_SECURITY_FILE_CAPABILITIES */ - int cap_capset_check (struct task_struct *target, kernel_cap_t *effective, kernel_cap_t *inheritable, kernel_cap_t *permitted) { - if (cap_block_setpcap(target)) { - return -EPERM; - } - if (cap_inh_is_capped() - && !cap_issubset(*inheritable, - cap_combine(target->cap_inheritable, - current->cap_permitted))) { - /* incapable of using this inheritable set */ + /* Derived from kernel/capability.c:sys_capset. */ + /* verify restrictions on target's new Inheritable set */ + if (!cap_issubset (*inheritable, + cap_combine (target->cap_inheritable, + current->cap_permitted))) { return -EPERM; } @@ -335,7 +285,7 @@ void cap_bprm_apply_creds (struct linux_binprm *bprm, int unsafe) /* For init, we want to retain the capabilities set * in the init_task struct. Thus we skip the usual * capability rules */ - if (!is_global_init(current)) { + if (!is_init(current)) { current->cap_permitted = new_permitted; current->cap_effective = bprm->cap_effective ? new_permitted : 0; diff --git a/trunk/security/dummy.c b/trunk/security/dummy.c index 6d895ade73de..bc43d4c7383e 100644 --- a/trunk/security/dummy.c +++ b/trunk/security/dummy.c @@ -37,13 +37,15 @@ static int dummy_capget (struct task_struct *target, kernel_cap_t * effective, kernel_cap_t * inheritable, kernel_cap_t * permitted) { *effective = *inheritable = *permitted = 0; - if (target->euid == 0) { - *permitted |= (~0 & ~CAP_FS_MASK); - *effective |= (~0 & ~CAP_TO_MASK(CAP_SETPCAP) & ~CAP_FS_MASK); - } - if (target->fsuid == 0) { - *permitted |= CAP_FS_MASK; - *effective |= CAP_FS_MASK; + if (!issecure(SECURE_NOROOT)) { + if (target->euid == 0) { + *permitted |= (~0 & ~CAP_FS_MASK); + *effective |= (~0 & ~CAP_TO_MASK(CAP_SETPCAP) & ~CAP_FS_MASK); + } + if (target->fsuid == 0) { + *permitted |= CAP_FS_MASK; + *effective |= CAP_FS_MASK; + } } return 0; } diff --git a/trunk/security/selinux/xfrm.c b/trunk/security/selinux/xfrm.c index 36a191e7004e..cb008d9f0a82 100644 --- a/trunk/security/selinux/xfrm.c +++ b/trunk/security/selinux/xfrm.c @@ -448,7 +448,7 @@ int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb, if (dst) { struct dst_entry *dst_test; - for (dst_test = dst; dst_test != NULL; + for (dst_test = dst; dst_test != 0; dst_test = dst_test->child) { struct xfrm_state *x = dst_test->xfrm; diff --git a/trunk/sound/arm/aaci.c b/trunk/sound/arm/aaci.c index 3b73ba7d03e8..b9eca9f3dd25 100644 --- a/trunk/sound/arm/aaci.c +++ b/trunk/sound/arm/aaci.c @@ -209,7 +209,7 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask) void *ptr; if (!aacirun->substream || !aacirun->start) { - dev_warn(&aaci->dev->dev, "RX interrupt???\n"); + dev_warn(&aaci->dev->dev, "RX interrupt???"); writel(0, aacirun->base + AACI_IE); return; } @@ -263,7 +263,7 @@ static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask) void *ptr; if (!aacirun->substream || !aacirun->start) { - dev_warn(&aaci->dev->dev, "TX interrupt???\n"); + dev_warn(&aaci->dev->dev, "TX interrupt???"); writel(0, aacirun->base + AACI_IE); return; } diff --git a/trunk/sound/oss/Makefile b/trunk/sound/oss/Makefile index f883c4b676ab..1200670017bd 100644 --- a/trunk/sound/oss/Makefile +++ b/trunk/sound/oss/Makefile @@ -36,6 +36,7 @@ obj-$(CONFIG_SOUND_MSNDCLAS) += msnd.o msnd_classic.o obj-$(CONFIG_SOUND_MSNDPIN) += msnd.o msnd_pinnacle.o obj-$(CONFIG_SOUND_VWSND) += vwsnd.o obj-$(CONFIG_SOUND_ICH) += i810_audio.o ac97_codec.o +obj-$(CONFIG_SOUND_ES1371) += es1371.o ac97_codec.o obj-$(CONFIG_SOUND_AU1550_AC97) += au1550_ac97.o ac97_codec.o obj-$(CONFIG_SOUND_TRIDENT) += trident.o ac97_codec.o obj-$(CONFIG_SOUND_BCM_CS4297A) += swarm_cs4297a.o diff --git a/trunk/sound/oss/dmasound/Makefile b/trunk/sound/oss/dmasound/Makefile index 3c1531652d11..4611636b1a81 100644 --- a/trunk/sound/oss/dmasound/Makefile +++ b/trunk/sound/oss/dmasound/Makefile @@ -2,6 +2,12 @@ # Makefile for the DMA sound driver # +dmasound_pmac-y += dmasound_awacs.o \ + trans_16.o dac3550a.o tas_common.o \ + tas3001c.o tas3001c_tables.o \ + tas3004.o tas3004_tables.o + obj-$(CONFIG_DMASOUND_ATARI) += dmasound_core.o dmasound_atari.o +obj-$(CONFIG_DMASOUND_PMAC) += dmasound_core.o dmasound_pmac.o obj-$(CONFIG_DMASOUND_PAULA) += dmasound_core.o dmasound_paula.o obj-$(CONFIG_DMASOUND_Q40) += dmasound_core.o dmasound_q40.o diff --git a/trunk/sound/oss/dmasound/awacs_defs.h b/trunk/sound/oss/dmasound/awacs_defs.h new file mode 100644 index 000000000000..2194f46b046c --- /dev/null +++ b/trunk/sound/oss/dmasound/awacs_defs.h @@ -0,0 +1,251 @@ +/*********************************************************/ +/* This file was written by someone, somewhere, sometime */ +/* And is released into the Public Domain */ +/*********************************************************/ + +#ifndef _AWACS_DEFS_H_ +#define _AWACS_DEFS_H_ + +/*******************************/ +/* AWACs Audio Register Layout */ +/*******************************/ + +struct awacs_regs { + unsigned control; /* Audio control register */ + unsigned pad0[3]; + unsigned codec_ctrl; /* Codec control register */ + unsigned pad1[3]; + unsigned codec_stat; /* Codec status register */ + unsigned pad2[3]; + unsigned clip_count; /* Clipping count register */ + unsigned pad3[3]; + unsigned byteswap; /* Data is little-endian if 1 */ +}; + +/*******************/ +/* Audio Bit Masks */ +/*******************/ + +/* Audio Control Reg Bit Masks */ +/* ----- ------- --- --- ----- */ +#define MASK_ISFSEL (0xf) /* Input SubFrame Select */ +#define MASK_OSFSEL (0xf << 4) /* Output SubFrame Select */ +#define MASK_RATE (0x7 << 8) /* Sound Rate */ +#define MASK_CNTLERR (0x1 << 11) /* Error */ +#define MASK_PORTCHG (0x1 << 12) /* Port Change */ +#define MASK_IEE (0x1 << 13) /* Enable Interrupt on Error */ +#define MASK_IEPC (0x1 << 14) /* Enable Interrupt on Port Change */ +#define MASK_SSFSEL (0x3 << 15) /* Status SubFrame Select */ + +/* Audio Codec Control Reg Bit Masks */ +/* ----- ----- ------- --- --- ----- */ +#define MASK_NEWECMD (0x1 << 24) /* Lock: don't write to reg when 1 */ +#define MASK_EMODESEL (0x3 << 22) /* Send info out on which frame? */ +#define MASK_EXMODEADDR (0x3ff << 12) /* Extended Mode Address -- 10 bits */ +#define MASK_EXMODEDATA (0xfff) /* Extended Mode Data -- 12 bits */ + +/* Audio Codec Control Address Values / Masks */ +/* ----- ----- ------- ------- ------ - ----- */ +#define MASK_ADDR0 (0x0 << 12) /* Expanded Data Mode Address 0 */ +#define MASK_ADDR_MUX MASK_ADDR0 /* Mux Control */ +#define MASK_ADDR_GAIN MASK_ADDR0 + +#define MASK_ADDR1 (0x1 << 12) /* Expanded Data Mode Address 1 */ +#define MASK_ADDR_MUTE MASK_ADDR1 +#define MASK_ADDR_RATE MASK_ADDR1 + +#define MASK_ADDR2 (0x2 << 12) /* Expanded Data Mode Address 2 */ +#define MASK_ADDR_VOLA MASK_ADDR2 /* Volume Control A -- Headphones */ +#define MASK_ADDR_VOLHD MASK_ADDR2 + +#define MASK_ADDR4 (0x4 << 12) /* Expanded Data Mode Address 4 */ +#define MASK_ADDR_VOLC MASK_ADDR4 /* Volume Control C -- Speaker */ +#define MASK_ADDR_VOLSPK MASK_ADDR4 + +/* additional registers of screamer */ +#define MASK_ADDR5 (0x5 << 12) /* Expanded Data Mode Address 5 */ +#define MASK_ADDR6 (0x6 << 12) /* Expanded Data Mode Address 6 */ +#define MASK_ADDR7 (0x7 << 12) /* Expanded Data Mode Address 7 */ + +/* Address 0 Bit Masks & Macros */ +/* ------- - --- ----- - ------ */ +#define MASK_GAINRIGHT (0xf) /* Gain Right Mask */ +#define MASK_GAINLEFT (0xf << 4) /* Gain Left Mask */ +#define MASK_GAINLINE (0x1 << 8) /* Disable Mic preamp */ +#define MASK_GAINMIC (0x0 << 8) /* Enable Mic preamp */ + +#define MASK_MUX_CD (0x1 << 9) /* Select CD in MUX */ +#define MASK_MUX_MIC (0x1 << 10) /* Select Mic in MUX */ +#define MASK_MUX_AUDIN (0x1 << 11) /* Select Audio In in MUX */ +#define MASK_MUX_LINE MASK_MUX_AUDIN + +#define GAINRIGHT(x) ((x) & MASK_GAINRIGHT) +#define GAINLEFT(x) (((x) << 4) & MASK_GAINLEFT) + +#define DEF_CD_GAIN 0x00bb +#define DEF_MIC_GAIN 0x00cc + +/* Address 1 Bit Masks */ +/* ------- - --- ----- */ +#define MASK_ADDR1RES1 (0x3) /* Reserved */ +#define MASK_RECALIBRATE (0x1 << 2) /* Recalibrate */ +#define MASK_SAMPLERATE (0x7 << 3) /* Sample Rate: */ +#define MASK_LOOPTHRU (0x1 << 6) /* Loopthrough Enable */ +#define MASK_CMUTE (0x1 << 7) /* Output C (Speaker) Mute when 1 */ +#define MASK_SPKMUTE MASK_CMUTE +#define MASK_ADDR1RES2 (0x1 << 8) /* Reserved */ +#define MASK_AMUTE (0x1 << 9) /* Output A (Headphone) Mute when 1 */ +#define MASK_HDMUTE MASK_AMUTE +#define MASK_PAROUT0 (0x1 << 10) /* Parallel Output 0 */ +#define MASK_PAROUT1 (0x2 << 10) /* Parallel Output 1 */ + +#define MASK_MIC_BOOST (0x4) /* screamer mic boost */ + +#define SAMPLERATE_48000 (0x0 << 3) /* 48 or 44.1 kHz */ +#define SAMPLERATE_32000 (0x1 << 3) /* 32 or 29.4 kHz */ +#define SAMPLERATE_24000 (0x2 << 3) /* 24 or 22.05 kHz */ +#define SAMPLERATE_19200 (0x3 << 3) /* 19.2 or 17.64 kHz */ +#define SAMPLERATE_16000 (0x4 << 3) /* 16 or 14.7 kHz */ +#define SAMPLERATE_12000 (0x5 << 3) /* 12 or 11.025 kHz */ +#define SAMPLERATE_9600 (0x6 << 3) /* 9.6 or 8.82 kHz */ +#define SAMPLERATE_8000 (0x7 << 3) /* 8 or 7.35 kHz */ + +/* Address 2 & 4 Bit Masks & Macros */ +/* ------- - - - --- ----- - ------ */ +#define MASK_OUTVOLRIGHT (0xf) /* Output Right Volume */ +#define MASK_ADDR2RES1 (0x2 << 4) /* Reserved */ +#define MASK_ADDR4RES1 MASK_ADDR2RES1 +#define MASK_OUTVOLLEFT (0xf << 6) /* Output Left Volume */ +#define MASK_ADDR2RES2 (0x2 << 10) /* Reserved */ +#define MASK_ADDR4RES2 MASK_ADDR2RES2 + +#define VOLRIGHT(x) (((~(x)) & MASK_OUTVOLRIGHT)) +#define VOLLEFT(x) (((~(x)) << 6) & MASK_OUTVOLLEFT) + +/* Audio Codec Status Reg Bit Masks */ +/* ----- ----- ------ --- --- ----- */ +#define MASK_EXTEND (0x1 << 23) /* Extend */ +#define MASK_VALID (0x1 << 22) /* Valid Data? */ +#define MASK_OFLEFT (0x1 << 21) /* Overflow Left */ +#define MASK_OFRIGHT (0x1 << 20) /* Overflow Right */ +#define MASK_ERRCODE (0xf << 16) /* Error Code */ +#define MASK_REVISION (0xf << 12) /* Revision Number */ +#define MASK_MFGID (0xf << 8) /* Mfg. ID */ +#define MASK_CODSTATRES (0xf << 4) /* bits 4 - 7 reserved */ +#define MASK_INPPORT (0xf) /* Input Port */ +#define MASK_HDPCONN 8 /* headphone plugged in */ + +/* Clipping Count Reg Bit Masks */ +/* -------- ----- --- --- ----- */ +#define MASK_CLIPLEFT (0xff << 7) /* Clipping Count, Left Channel */ +#define MASK_CLIPRIGHT (0xff) /* Clipping Count, Right Channel */ + +/* DBDMA ChannelStatus Bit Masks */ +/* ----- ------------- --- ----- */ +#define MASK_CSERR (0x1 << 7) /* Error */ +#define MASK_EOI (0x1 << 6) /* End of Input -- only for Input Channel */ +#define MASK_CSUNUSED (0x1f << 1) /* bits 1-5 not used */ +#define MASK_WAIT (0x1) /* Wait */ + +/* Various Rates */ +/* ------- ----- */ +#define RATE_48000 (0x0 << 8) /* 48 kHz */ +#define RATE_44100 (0x0 << 8) /* 44.1 kHz */ +#define RATE_32000 (0x1 << 8) /* 32 kHz */ +#define RATE_29400 (0x1 << 8) /* 29.4 kHz */ +#define RATE_24000 (0x2 << 8) /* 24 kHz */ +#define RATE_22050 (0x2 << 8) /* 22.05 kHz */ +#define RATE_19200 (0x3 << 8) /* 19.2 kHz */ +#define RATE_17640 (0x3 << 8) /* 17.64 kHz */ +#define RATE_16000 (0x4 << 8) /* 16 kHz */ +#define RATE_14700 (0x4 << 8) /* 14.7 kHz */ +#define RATE_12000 (0x5 << 8) /* 12 kHz */ +#define RATE_11025 (0x5 << 8) /* 11.025 kHz */ +#define RATE_9600 (0x6 << 8) /* 9.6 kHz */ +#define RATE_8820 (0x6 << 8) /* 8.82 kHz */ +#define RATE_8000 (0x7 << 8) /* 8 kHz */ +#define RATE_7350 (0x7 << 8) /* 7.35 kHz */ + +#define RATE_LOW 1 /* HIGH = 48kHz, etc; LOW = 44.1kHz, etc. */ + +/*******************/ +/* Burgundy values */ +/*******************/ + +#define MASK_ADDR_BURGUNDY_INPSEL21 (0x11 << 12) +#define MASK_ADDR_BURGUNDY_INPSEL3 (0x12 << 12) + +#define MASK_ADDR_BURGUNDY_GAINCH1 (0x13 << 12) +#define MASK_ADDR_BURGUNDY_GAINCH2 (0x14 << 12) +#define MASK_ADDR_BURGUNDY_GAINCH3 (0x15 << 12) +#define MASK_ADDR_BURGUNDY_GAINCH4 (0x16 << 12) + +#define MASK_ADDR_BURGUNDY_VOLCH1 (0x20 << 12) +#define MASK_ADDR_BURGUNDY_VOLCH2 (0x21 << 12) +#define MASK_ADDR_BURGUNDY_VOLCH3 (0x22 << 12) +#define MASK_ADDR_BURGUNDY_VOLCH4 (0x23 << 12) + +#define MASK_ADDR_BURGUNDY_OUTPUTSELECTS (0x2B << 12) +#define MASK_ADDR_BURGUNDY_OUTPUTENABLES (0x2F << 12) + +#define MASK_ADDR_BURGUNDY_MASTER_VOLUME (0x30 << 12) + +#define MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES (0x60 << 12) + +#define MASK_ADDR_BURGUNDY_ATTENSPEAKER (0x62 << 12) +#define MASK_ADDR_BURGUNDY_ATTENLINEOUT (0x63 << 12) +#define MASK_ADDR_BURGUNDY_ATTENHP (0x64 << 12) + +#define MASK_ADDR_BURGUNDY_VOLCD (MASK_ADDR_BURGUNDY_VOLCH1) +#define MASK_ADDR_BURGUNDY_VOLLINE (MASK_ADDR_BURGUNDY_VOLCH2) +#define MASK_ADDR_BURGUNDY_VOLMIC (MASK_ADDR_BURGUNDY_VOLCH3) +#define MASK_ADDR_BURGUNDY_VOLMODEM (MASK_ADDR_BURGUNDY_VOLCH4) + +#define MASK_ADDR_BURGUNDY_GAINCD (MASK_ADDR_BURGUNDY_GAINCH1) +#define MASK_ADDR_BURGUNDY_GAINLINE (MASK_ADDR_BURGUNDY_GAINCH2) +#define MASK_ADDR_BURGUNDY_GAINMIC (MASK_ADDR_BURGUNDY_GAINCH3) +#define MASK_ADDR_BURGUNDY_GAINMODEM (MASK_ADDR_BURGUNDY_VOLCH4) + + +/* These are all default values for the burgundy */ +#define DEF_BURGUNDY_INPSEL21 (0xAA) +#define DEF_BURGUNDY_INPSEL3 (0x0A) + +#define DEF_BURGUNDY_GAINCD (0x33) +#define DEF_BURGUNDY_GAINLINE (0x44) +#define DEF_BURGUNDY_GAINMIC (0x44) +#define DEF_BURGUNDY_GAINMODEM (0x06) + +/* Remember: lowest volume here is 0x9b */ +#define DEF_BURGUNDY_VOLCD (0xCCCCCCCC) +#define DEF_BURGUNDY_VOLLINE (0x00000000) +#define DEF_BURGUNDY_VOLMIC (0x00000000) +#define DEF_BURGUNDY_VOLMODEM (0xCCCCCCCC) + +#define DEF_BURGUNDY_OUTPUTSELECTS (0x010f010f) +#define DEF_BURGUNDY_OUTPUTENABLES (0x0A) + +#define DEF_BURGUNDY_MASTER_VOLUME (0xFFFFFFFF) + +#define DEF_BURGUNDY_MORE_OUTPUTENABLES (0x7E) + +#define DEF_BURGUNDY_ATTENSPEAKER (0x44) +#define DEF_BURGUNDY_ATTENLINEOUT (0xCC) +#define DEF_BURGUNDY_ATTENHP (0xCC) + +/*********************/ +/* i2s layout values */ +/*********************/ + +#define I2S_REG_INT_CTL 0x00 +#define I2S_REG_SERIAL_FORMAT 0x10 +#define I2S_REG_CODEC_MSG_OUT 0x20 +#define I2S_REG_CODEC_MSG_IN 0x30 +#define I2S_REG_FRAME_COUNT 0x40 +#define I2S_REG_FRAME_MATCH 0x50 +#define I2S_REG_DATAWORD_SIZES 0x60 +#define I2S_REG_PEAKLEVEL_SEL 0x70 +#define I2S_REG_PEAKLEVEL_IN0 0x80 +#define I2S_REG_PEAKLEVEL_IN1 0x90 + +#endif /* _AWACS_DEFS_H_ */ diff --git a/trunk/sound/oss/dmasound/dac3550a.c b/trunk/sound/oss/dmasound/dac3550a.c new file mode 100644 index 000000000000..0f0d03a55dab --- /dev/null +++ b/trunk/sound/oss/dmasound/dac3550a.c @@ -0,0 +1,209 @@ +/* + * Driver for the i2c/i2s based DAC3550a sound chip used + * on some Apple iBooks. Also known as "DACA". + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dmasound.h" + +/* FYI: This code was derived from the tas3001c.c Texas/Tumbler mixer + * control code, as well as info derived from the AppleDACAAudio driver + * from Darwin CVS (main thing I derived being register numbers and + * values, as well as when to make the calls). */ + +#define I2C_DRIVERID_DACA (0xFDCB) + +#define DACA_VERSION "0.1" +#define DACA_DATE "20010930" + +static int cur_left_vol; +static int cur_right_vol; +static struct i2c_client *daca_client; + +static int daca_attach_adapter(struct i2c_adapter *adapter); +static int daca_detect_client(struct i2c_adapter *adapter, int address); +static int daca_detach_client(struct i2c_client *client); + +struct i2c_driver daca_driver = { + .driver = { + .name = "DAC3550A driver V " DACA_VERSION, + }, + .id = I2C_DRIVERID_DACA, + .attach_adapter = daca_attach_adapter, + .detach_client = daca_detach_client, +}; + +#define VOL_MAX ((1<<20) - 1) + +void daca_get_volume(uint * left_vol, uint *right_vol) +{ + *left_vol = cur_left_vol >> 5; + *right_vol = cur_right_vol >> 5; +} + +int daca_set_volume(uint left_vol, uint right_vol) +{ + unsigned short voldata; + + if (!daca_client) + return -1; + + /* Derived from experience, not from any specific values */ + left_vol <<= 5; + right_vol <<= 5; + + if (left_vol > VOL_MAX) + left_vol = VOL_MAX; + if (right_vol > VOL_MAX) + right_vol = VOL_MAX; + + voldata = ((left_vol >> 14) & 0x3f) << 8; + voldata |= (right_vol >> 14) & 0x3f; + + if (i2c_smbus_write_word_data(daca_client, 2, voldata) < 0) { + printk("daca: failed to set volume \n"); + return -1; + } + + cur_left_vol = left_vol; + cur_right_vol = right_vol; + + return 0; +} + +int daca_leave_sleep(void) +{ + if (!daca_client) + return -1; + + /* Do a short sleep, just to make sure I2C bus is awake and paying + * attention to us + */ + msleep(20); + /* Write the sample rate reg the value it needs */ + i2c_smbus_write_byte_data(daca_client, 1, 8); + daca_set_volume(cur_left_vol >> 5, cur_right_vol >> 5); + /* Another short delay, just to make sure the other I2C bus writes + * have taken... + */ + msleep(20); + /* Write the global config reg - invert right power amp, + * DAC on, use 5-volt mode */ + i2c_smbus_write_byte_data(daca_client, 3, 0x45); + + return 0; +} + +int daca_enter_sleep(void) +{ + if (!daca_client) + return -1; + + i2c_smbus_write_byte_data(daca_client, 1, 8); + daca_set_volume(cur_left_vol >> 5, cur_right_vol >> 5); + + /* Write the global config reg - invert right power amp, + * DAC on, enter low-power mode, use 5-volt mode + */ + i2c_smbus_write_byte_data(daca_client, 3, 0x65); + + return 0; +} + +static int daca_attach_adapter(struct i2c_adapter *adapter) +{ + if (!strncmp(adapter->name, "mac-io", 6)) + daca_detect_client(adapter, 0x4d); + return 0; +} + +static int daca_init_client(struct i2c_client * new_client) +{ + /* + * Probe is not working with the current i2c-keywest + * driver. We try to use addr 0x4d on each adapters + * instead, by setting the format register. + * + * FIXME: I'm sure that can be obtained from the + * device-tree. --BenH. + */ + + /* Write the global config reg - invert right power amp, + * DAC on, use 5-volt mode + */ + if (i2c_smbus_write_byte_data(new_client, 3, 0x45)) + return -1; + + i2c_smbus_write_byte_data(new_client, 1, 8); + daca_client = new_client; + daca_set_volume(15000, 15000); + + return 0; +} + +static int daca_detect_client(struct i2c_adapter *adapter, int address) +{ + const char *client_name = "DAC 3550A Digital Equalizer"; + struct i2c_client *new_client; + int rc = -ENODEV; + + new_client = kzalloc(sizeof(*new_client), GFP_KERNEL); + if (!new_client) + return -ENOMEM; + + new_client->addr = address; + new_client->adapter = adapter; + new_client->driver = &daca_driver; + new_client->flags = 0; + strcpy(new_client->name, client_name); + + if (daca_init_client(new_client)) + goto bail; + + /* Tell the i2c layer a new client has arrived */ + if (i2c_attach_client(new_client)) + goto bail; + + return 0; + bail: + kfree(new_client); + return rc; +} + + +static int daca_detach_client(struct i2c_client *client) +{ + if (client == daca_client) + daca_client = NULL; + + i2c_detach_client(client); + kfree(client); + return 0; +} + +void daca_cleanup(void) +{ + i2c_del_driver(&daca_driver); +} + +int daca_init(void) +{ + printk("dac3550a driver version %s (%s)\n",DACA_VERSION,DACA_DATE); + return i2c_add_driver(&daca_driver); +} diff --git a/trunk/sound/oss/dmasound/dmasound.h b/trunk/sound/oss/dmasound/dmasound.h index d978b0096564..25dd5a318eb4 100644 --- a/trunk/sound/oss/dmasound/dmasound.h +++ b/trunk/sound/oss/dmasound/dmasound.h @@ -59,6 +59,7 @@ static inline int ioctl_return(int __user *addr, int value) */ #undef HAS_8BIT_TABLES +#undef HAS_RECORD #if defined(CONFIG_DMASOUND_ATARI) || defined(CONFIG_DMASOUND_ATARI_MODULE) ||\ defined(CONFIG_DMASOUND_PAULA) || defined(CONFIG_DMASOUND_PAULA_MODULE) ||\ @@ -82,6 +83,10 @@ static inline int ioctl_return(int __user *addr, int value) #define DEFAULT_N_BUFFERS 4 #define DEFAULT_BUFF_SIZE (1<<15) +#if defined(CONFIG_DMASOUND_PMAC) || defined(CONFIG_DMASOUND_PMAC_MODULE) +#define HAS_RECORD +#endif + /* * Initialization */ @@ -163,6 +168,9 @@ struct sound_settings { SETTINGS soft; /* software settings */ SETTINGS dsp; /* /dev/dsp default settings */ TRANS *trans_write; /* supported translations */ +#ifdef HAS_RECORD + TRANS *trans_read; /* supported translations */ +#endif int volume_left; /* volume (range is machine dependent) */ int volume_right; int bass; /* tone (range is machine dependent) */ @@ -245,6 +253,11 @@ struct sound_queue { extern struct sound_queue dmasound_write_sq; #define write_sq dmasound_write_sq +#ifdef HAS_RECORD +extern struct sound_queue dmasound_read_sq; +#define read_sq dmasound_read_sq +#endif + extern int dmasound_catchRadius; #define catchRadius dmasound_catchRadius diff --git a/trunk/sound/oss/dmasound/dmasound_awacs.c b/trunk/sound/oss/dmasound/dmasound_awacs.c new file mode 100644 index 000000000000..8f6388004f44 --- /dev/null +++ b/trunk/sound/oss/dmasound/dmasound_awacs.c @@ -0,0 +1,3215 @@ +/* + * linux/sound/oss/dmasound/dmasound_awacs.c + * + * PowerMac `AWACS' and `Burgundy' DMA Sound Driver + * with some limited support for DACA & Tumbler + * + * See linux/sound/oss/dmasound/dmasound_core.c for copyright and + * history prior to 2001/01/26. + * + * 26/01/2001 ed 0.1 Iain Sandoe + * - added version info. + * - moved dbdma command buffer allocation to PMacXXXSqSetup() + * - fixed up beep dbdma cmd buffers + * + * 08/02/2001 [0.2] + * - make SNDCTL_DSP_GETFMTS return the correct info for the h/w + * - move soft format translations to a separate file + * - [0.3] make SNDCTL_DSP_GETCAPS return correct info. + * - [0.4] more informative machine name strings. + * - [0.5] + * - record changes. + * - made the default_hard/soft entries. + * 04/04/2001 [0.6] + * - minor correction to bit assignments in awacs_defs.h + * - incorporate mixer changes from 2.2.x back-port. + * - take out passthru as a rec input (it isn't). + * - make Input Gain slider work the 'right way up'. + * - try to make the mixer sliders more logical - so now the + * input selectors are just two-state (>50% == ON) and the + * Input Gain slider handles the rest of the gain issues. + * - try to pick slider representations that most closely match + * the actual use - e.g. IGain for input gain... + * - first stab at over/under-run detection. + * - minor cosmetic changes to IRQ identification. + * - fix bug where rates > max would be reported as supported. + * - first stab at over/under-run detection. + * - make use of i2c for mixer settings conditional on perch + * rather than cuda (some machines without perch have cuda). + * - fix bug where TX stops when dbdma status comes up "DEAD" + * so far only reported on PowerComputing clones ... but. + * - put in AWACS/Screamer register write timeouts. + * - part way to partitioning the init() stuff + * - first pass at 'tumbler' stuff (not support - just an attempt + * to allow the driver to load on new G4s). + * 01/02/2002 [0.7] - BenH + * - all sort of minor bits went in since the latest update, I + * bumped the version number for that reason + * + * 07/26/2002 [0.8] - BenH + * - More minor bits since last changelog (I should be more careful + * with those) + * - Support for snapper & better tumbler integration by Toby Sargeant + * - Headphone detect for scremer by Julien Blache + * - More tumbler fixed by Andreas Schwab + * 11/29/2003 [0.8.1] - Renzo Davoli (King Enzo) + * - Support for Snapper line in + * - snapper input resampling (for rates < 44100) + * - software line gain control + */ + +/* GENERAL FIXME/TODO: check that the assumptions about what is written to + mac-io is valid for DACA & Tumbler. + + This driver is in bad need of a rewrite. The dbdma code has to be split, + some proper device-tree parsing code has to be written, etc... +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_ADB_CUDA +#include +#endif +#ifdef CONFIG_ADB_PMU +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "awacs_defs.h" +#include "dmasound.h" +#include "tas3001c.h" +#include "tas3004.h" +#include "tas_common.h" + +#define DMASOUND_AWACS_REVISION 0 +#define DMASOUND_AWACS_EDITION 7 + +#define AWACS_SNAPPER 110 /* fake revision # for snapper */ +#define AWACS_BURGUNDY 100 /* fake revision # for burgundy */ +#define AWACS_TUMBLER 90 /* fake revision # for tumbler */ +#define AWACS_DACA 80 /* fake revision # for daca (ibook) */ +#define AWACS_AWACS 2 /* holding revision for AWACS */ +#define AWACS_SCREAMER 3 /* holding revision for Screamer */ +/* + * Interrupt numbers and addresses, & info obtained from the device tree. + */ +static int awacs_irq, awacs_tx_irq, awacs_rx_irq; +static volatile struct awacs_regs __iomem *awacs; +static volatile u32 __iomem *i2s; +static volatile struct dbdma_regs __iomem *awacs_txdma, *awacs_rxdma; +static int awacs_rate_index; +static int awacs_subframe; +static struct device_node* awacs_node; +static struct device_node* i2s_node; +static struct resource awacs_rsrc[3]; + +static char awacs_name[64]; +static int awacs_revision; +static int awacs_sleeping; +static DEFINE_MUTEX(dmasound_mutex); + +static int sound_device_id; /* exists after iMac revA */ +static int hw_can_byteswap = 1 ; /* most pmac sound h/w can */ + +/* model info */ +/* To be replaced with better interaction with pmac_feature.c */ +static int is_pbook_3X00; +static int is_pbook_g3; + +/* expansion info */ +static int has_perch; +static int has_ziva; + +/* for earlier powerbooks which need fiddling with mac-io to enable + * cd etc. +*/ +static unsigned char __iomem *latch_base; +static unsigned char __iomem *macio_base; + +/* + * Space for the DBDMA command blocks. + */ +static void *awacs_tx_cmd_space; +static volatile struct dbdma_cmd *awacs_tx_cmds; +static int number_of_tx_cmd_buffers; + +static void *awacs_rx_cmd_space; +static volatile struct dbdma_cmd *awacs_rx_cmds; +static int number_of_rx_cmd_buffers; + +/* + * Cached values of AWACS registers (we can't read them). + * Except on the burgundy (and screamer). XXX + */ + +int awacs_reg[8]; +int awacs_reg1_save; + +/* tracking values for the mixer contents +*/ + +static int spk_vol; +static int line_vol; +static int passthru_vol; + +static int ip_gain; /* mic preamp settings */ +static int rec_lev = 0x4545 ; /* default CD gain 69 % */ +static int mic_lev; +static int cd_lev = 0x6363 ; /* 99 % */ +static int line_lev; + +static int hdp_connected; + +/* + * Stuff for outputting a beep. The values range from -327 to +327 + * so we can multiply by an amplitude in the range 0..100 to get a + * signed short value to put in the output buffer. + */ +static short beep_wform[256] = { + 0, 40, 79, 117, 153, 187, 218, 245, + 269, 288, 304, 316, 323, 327, 327, 324, + 318, 310, 299, 288, 275, 262, 249, 236, + 224, 213, 204, 196, 190, 186, 183, 182, + 182, 183, 186, 189, 192, 196, 200, 203, + 206, 208, 209, 209, 209, 207, 204, 201, + 197, 193, 188, 183, 179, 174, 170, 166, + 163, 161, 160, 159, 159, 160, 161, 162, + 164, 166, 168, 169, 171, 171, 171, 170, + 169, 167, 163, 159, 155, 150, 144, 139, + 133, 128, 122, 117, 113, 110, 107, 105, + 103, 103, 103, 103, 104, 104, 105, 105, + 105, 103, 101, 97, 92, 86, 78, 68, + 58, 45, 32, 18, 3, -11, -26, -41, + -55, -68, -79, -88, -95, -100, -102, -102, + -99, -93, -85, -75, -62, -48, -33, -16, + 0, 16, 33, 48, 62, 75, 85, 93, + 99, 102, 102, 100, 95, 88, 79, 68, + 55, 41, 26, 11, -3, -18, -32, -45, + -58, -68, -78, -86, -92, -97, -101, -103, + -105, -105, -105, -104, -104, -103, -103, -103, + -103, -105, -107, -110, -113, -117, -122, -128, + -133, -139, -144, -150, -155, -159, -163, -167, + -169, -170, -171, -171, -171, -169, -168, -166, + -164, -162, -161, -160, -159, -159, -160, -161, + -163, -166, -170, -174, -179, -183, -188, -193, + -197, -201, -204, -207, -209, -209, -209, -208, + -206, -203, -200, -196, -192, -189, -186, -183, + -182, -182, -183, -186, -190, -196, -204, -213, + -224, -236, -249, -262, -275, -288, -299, -310, + -318, -324, -327, -327, -323, -316, -304, -288, + -269, -245, -218, -187, -153, -117, -79, -40, +}; + +/* beep support */ +#define BEEP_SRATE 22050 /* 22050 Hz sample rate */ +#define BEEP_BUFLEN 512 +#define BEEP_VOLUME 15 /* 0 - 100 */ + +static int beep_vol = BEEP_VOLUME; +static int beep_playing; +static int awacs_beep_state; +static short *beep_buf; +static void *beep_dbdma_cmd_space; +static volatile struct dbdma_cmd *beep_dbdma_cmd; + +/* Burgundy functions */ +static void awacs_burgundy_wcw(unsigned addr,unsigned newval); +static unsigned awacs_burgundy_rcw(unsigned addr); +static void awacs_burgundy_write_volume(unsigned address, int volume); +static int awacs_burgundy_read_volume(unsigned address); +static void awacs_burgundy_write_mvolume(unsigned address, int volume); +static int awacs_burgundy_read_mvolume(unsigned address); + +/* we will allocate a single 'emergency' dbdma cmd block to use if the + tx status comes up "DEAD". This happens on some PowerComputing Pmac + clones, either owing to a bug in dbdma or some interaction between + IDE and sound. However, this measure would deal with DEAD status if + if appeared elsewhere. + + for the sake of memory efficiency we'll allocate this cmd as part of + the beep cmd stuff. +*/ + +static volatile struct dbdma_cmd *emergency_dbdma_cmd; + +#ifdef CONFIG_PM +/* + * Stuff for restoring after a sleep. + */ +static void awacs_sleep_notify(struct pmu_sleep_notifier *self, int when); +struct pmu_sleep_notifier awacs_sleep_notifier = { + awacs_sleep_notify, SLEEP_LEVEL_SOUND, +}; +#endif /* CONFIG_PM */ + +/* for (soft) sample rate translations */ +int expand_bal; /* Balance factor for expanding (not volume!) */ +int expand_read_bal; /* Balance factor for expanding reads (not volume!) */ + +/*** Low level stuff *********************************************************/ + +static void *PMacAlloc(unsigned int size, gfp_t flags); +static void PMacFree(void *ptr, unsigned int size); +static int PMacIrqInit(void); +#ifdef MODULE +static void PMacIrqCleanup(void); +#endif +static void PMacSilence(void); +static void PMacInit(void); +static int PMacSetFormat(int format); +static int PMacSetVolume(int volume); +static void PMacPlay(void); +static void PMacRecord(void); +static irqreturn_t pmac_awacs_tx_intr(int irq, void *devid); +static irqreturn_t pmac_awacs_rx_intr(int irq, void *devid); +static irqreturn_t pmac_awacs_intr(int irq, void *devid); +static void awacs_write(int val); +static int awacs_get_volume(int reg, int lshift); +static int awacs_volume_setter(int volume, int n, int mute, int lshift); + + +/*** Mid level stuff **********************************************************/ + +static int PMacMixerIoctl(u_int cmd, u_long arg); +static int PMacWriteSqSetup(void); +static int PMacReadSqSetup(void); +static void PMacAbortRead(void); + +extern TRANS transAwacsNormal ; +extern TRANS transAwacsExpand ; +extern TRANS transAwacsNormalRead ; +extern TRANS transAwacsExpandRead ; + +extern int daca_init(void); +extern void daca_cleanup(void); +extern int daca_set_volume(uint left_vol, uint right_vol); +extern void daca_get_volume(uint * left_vol, uint *right_vol); +extern int daca_enter_sleep(void); +extern int daca_leave_sleep(void); + +#define TRY_LOCK() \ + if ((rc = mutex_lock_interruptible(&dmasound_mutex)) != 0) \ + return rc; +#define LOCK() mutex_lock(&dmasound_mutex); + +#define UNLOCK() mutex_unlock(&dmasound_mutex); + +/* We use different versions that the ones provided in dmasound.h + * + * FIXME: Use different names ;) + */ +#undef IOCTL_IN +#undef IOCTL_OUT + +#define IOCTL_IN(arg, ret) \ + rc = get_user(ret, (int __user *)(arg)); \ + if (rc) break; +#define IOCTL_OUT(arg, ret) \ + ioctl_return2((int __user *)(arg), ret) + +static inline int ioctl_return2(int __user *addr, int value) +{ + return value < 0 ? value : put_user(value, addr); +} + + +/*** AE - TUMBLER / SNAPPER START ************************************************/ + + +int gpio_audio_reset, gpio_audio_reset_pol; +int gpio_amp_mute, gpio_amp_mute_pol; +int gpio_headphone_mute, gpio_headphone_mute_pol; +int gpio_headphone_detect, gpio_headphone_detect_pol; +int gpio_headphone_irq; + +int +setup_audio_gpio(const char *name, const char* compatible, int *gpio_addr, int* gpio_pol) +{ + struct device_node *gpiop; + struct device_node *np; + const u32* pp; + int ret = -ENODEV; + + gpiop = of_find_node_by_name(NULL, "gpio"); + if (!gpiop) + goto done; + + np = of_get_next_child(gpiop, NULL); + while(np != 0) { + if (name) { + const char *property = + of_get_property(np,"audio-gpio",NULL); + if (property != 0 && strcmp(property,name) == 0) + break; + } else if (compatible && of_device_is_compatible(np, compatible)) + break; + np = of_get_next_child(gpiop, np); + } + if (!np) + goto done; + pp = of_get_property(np, "AAPL,address", NULL); + if (!pp) + goto done; + *gpio_addr = (*pp) & 0x0000ffff; + pp = of_get_property(np, "audio-gpio-active-state", NULL); + if (pp) + *gpio_pol = *pp; + else + *gpio_pol = 1; + ret = irq_of_parse_and_map(np, 0); +done: + of_node_put(np); + of_node_put(gpiop); + return ret; +} + +static inline void +write_audio_gpio(int gpio_addr, int data) +{ + if (!gpio_addr) + return; + pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, gpio_addr, data ? 0x05 : 0x04); +} + +static inline int +read_audio_gpio(int gpio_addr) +{ + if (!gpio_addr) + return 0; + return ((pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, gpio_addr, 0) & 0x02) !=0); +} + +/* + * Headphone interrupt via GPIO (Tumbler, Snapper, DACA) + */ +static irqreturn_t +headphone_intr(int irq, void *devid) +{ + unsigned long flags; + + spin_lock_irqsave(&dmasound.lock, flags); + if (read_audio_gpio(gpio_headphone_detect) == gpio_headphone_detect_pol) { + printk(KERN_INFO "Audio jack plugged, muting speakers.\n"); + write_audio_gpio(gpio_headphone_mute, !gpio_headphone_mute_pol); + write_audio_gpio(gpio_amp_mute, gpio_amp_mute_pol); + tas_output_device_change(sound_device_id,TAS_OUTPUT_HEADPHONES,0); + } else { + printk(KERN_INFO "Audio jack unplugged, enabling speakers.\n"); + write_audio_gpio(gpio_amp_mute, !gpio_amp_mute_pol); + write_audio_gpio(gpio_headphone_mute, gpio_headphone_mute_pol); + tas_output_device_change(sound_device_id,TAS_OUTPUT_INTERNAL_SPKR,0); + } + spin_unlock_irqrestore(&dmasound.lock, flags); + return IRQ_HANDLED; +} + + +/* Initialize tumbler */ + +static int +tas_dmasound_init(void) +{ + setup_audio_gpio( + "audio-hw-reset", + NULL, + &gpio_audio_reset, + &gpio_audio_reset_pol); + setup_audio_gpio( + "amp-mute", + NULL, + &gpio_amp_mute, + &gpio_amp_mute_pol); + setup_audio_gpio("headphone-mute", + NULL, + &gpio_headphone_mute, + &gpio_headphone_mute_pol); + gpio_headphone_irq = setup_audio_gpio( + "headphone-detect", + NULL, + &gpio_headphone_detect, + &gpio_headphone_detect_pol); + /* Fix some broken OF entries in desktop machines */ + if (!gpio_headphone_irq) + gpio_headphone_irq = setup_audio_gpio( + NULL, + "keywest-gpio15", + &gpio_headphone_detect, + &gpio_headphone_detect_pol); + + write_audio_gpio(gpio_audio_reset, gpio_audio_reset_pol); + msleep(100); + write_audio_gpio(gpio_audio_reset, !gpio_audio_reset_pol); + msleep(100); + if (gpio_headphone_irq) { + if (request_irq(gpio_headphone_irq,headphone_intr,0,"Headphone detect",NULL) < 0) { + printk(KERN_ERR "tumbler: Can't request headphone interrupt\n"); + gpio_headphone_irq = 0; + } else { + u8 val; + /* Activate headphone status interrupts */ + val = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, gpio_headphone_detect, 0); + pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, gpio_headphone_detect, val | 0x80); + /* Trigger it */ + headphone_intr(0, NULL); + } + } + if (!gpio_headphone_irq) { + /* Some machine enter this case ? */ + printk(KERN_WARNING "tumbler: Headphone detect IRQ not found, enabling all outputs !\n"); + write_audio_gpio(gpio_amp_mute, !gpio_amp_mute_pol); + write_audio_gpio(gpio_headphone_mute, !gpio_headphone_mute_pol); + } + return 0; +} + + +static int +tas_dmasound_cleanup(void) +{ + if (gpio_headphone_irq) + free_irq(gpio_headphone_irq, NULL); + return 0; +} + +/* We don't support 48k yet */ +static int tas_freqs[1] = { 44100 } ; +static int tas_freqs_ok[1] = { 1 } ; + +/* don't know what to do really - just have to leave it where + * OF left things +*/ + +static int +tas_set_frame_rate(void) +{ + if (i2s) { + out_le32(i2s + (I2S_REG_SERIAL_FORMAT >> 2), 0x41190000); + out_le32(i2s + (I2S_REG_DATAWORD_SIZES >> 2), 0x02000200); + } + dmasound.hard.speed = 44100 ; + awacs_rate_index = 0 ; + return 44100 ; +} + +static int +tas_mixer_ioctl(u_int cmd, u_long arg) +{ + int __user *argp = (int __user *)arg; + int data; + int rc; + + rc=tas_device_ioctl(cmd, arg); + if (rc != -EINVAL) { + return rc; + } + + if ((cmd & ~0xff) == MIXER_WRITE(0) && + tas_supported_mixers() & (1<<(cmd & 0xff))) { + rc = get_user(data, argp); + if (rc<0) return rc; + tas_set_mixer_level(cmd & 0xff, data); + tas_get_mixer_level(cmd & 0xff, &data); + return ioctl_return2(argp, data); + } + if ((cmd & ~0xff) == MIXER_READ(0) && + tas_supported_mixers() & (1<<(cmd & 0xff))) { + tas_get_mixer_level(cmd & 0xff, &data); + return ioctl_return2(argp, data); + } + + switch(cmd) { + case SOUND_MIXER_READ_DEVMASK: + data = tas_supported_mixers() | SOUND_MASK_SPEAKER; + rc = IOCTL_OUT(arg, data); + break; + case SOUND_MIXER_READ_STEREODEVS: + data = tas_stereo_mixers(); + rc = IOCTL_OUT(arg, data); + break; + case SOUND_MIXER_READ_CAPS: + rc = IOCTL_OUT(arg, 0); + break; + case SOUND_MIXER_READ_RECMASK: + // XXX FIXME: find a way to check what is really available */ + data = SOUND_MASK_LINE | SOUND_MASK_MIC; + rc = IOCTL_OUT(arg, data); + break; + case SOUND_MIXER_READ_RECSRC: + if (awacs_reg[0] & MASK_MUX_AUDIN) + data |= SOUND_MASK_LINE; + if (awacs_reg[0] & MASK_MUX_MIC) + data |= SOUND_MASK_MIC; + rc = IOCTL_OUT(arg, data); + break; + case SOUND_MIXER_WRITE_RECSRC: + IOCTL_IN(arg, data); + data =0; + rc = IOCTL_OUT(arg, data); + break; + case SOUND_MIXER_WRITE_SPEAKER: /* really bell volume */ + IOCTL_IN(arg, data); + beep_vol = data & 0xff; + /* fall through */ + case SOUND_MIXER_READ_SPEAKER: + rc = IOCTL_OUT(arg, (beep_vol<<8) | beep_vol); + break; + case SOUND_MIXER_OUTMASK: + case SOUND_MIXER_OUTSRC: + default: + rc = -EINVAL; + } + + return rc; +} + +static void __init +tas_init_frame_rates(const unsigned int *prop, unsigned int l) +{ + int i ; + if (prop) { + for (i=0; i<1; i++) + tas_freqs_ok[i] = 0; + for (l /= sizeof(int); l > 0; --l) { + unsigned int r = *prop++; + /* Apple 'Fixed' format */ + if (r >= 0x10000) + r >>= 16; + for (i = 0; i < 1; ++i) { + if (r == tas_freqs[i]) { + tas_freqs_ok[i] = 1; + break; + } + } + } + } + /* else we assume that all the rates are available */ +} + + +/*** AE - TUMBLER / SNAPPER END ************************************************/ + + + +/*** Low level stuff *********************************************************/ + +/* + * PCI PowerMac, with AWACS, Screamer, Burgundy, DACA or Tumbler and DBDMA. + */ +static void *PMacAlloc(unsigned int size, gfp_t flags) +{ + return kmalloc(size, flags); +} + +static void PMacFree(void *ptr, unsigned int size) +{ + kfree(ptr); +} + +static int __init PMacIrqInit(void) +{ + if (awacs) + if (request_irq(awacs_irq, pmac_awacs_intr, 0, "Built-in Sound misc", NULL)) + return 0; + if (request_irq(awacs_tx_irq, pmac_awacs_tx_intr, 0, "Built-in Sound out", NULL) + || request_irq(awacs_rx_irq, pmac_awacs_rx_intr, 0, "Built-in Sound in", NULL)) + return 0; + return 1; +} + +#ifdef MODULE +static void PMacIrqCleanup(void) +{ + /* turn off input & output dma */ + DBDMA_DO_STOP(awacs_txdma); + DBDMA_DO_STOP(awacs_rxdma); + + if (awacs) + /* disable interrupts from awacs interface */ + out_le32(&awacs->control, in_le32(&awacs->control) & 0xfff); + + /* Switch off the sound clock */ + pmac_call_feature(PMAC_FTR_SOUND_CHIP_ENABLE, awacs_node, 0, 0); + /* Make sure proper bits are set on pismo & tipb */ + if ((machine_is_compatible("PowerBook3,1") || + machine_is_compatible("PowerBook3,2")) && awacs) { + awacs_reg[1] |= MASK_PAROUT0 | MASK_PAROUT1; + awacs_write(MASK_ADDR1 | awacs_reg[1]); + msleep(200); + } + if (awacs) + free_irq(awacs_irq, NULL); + free_irq(awacs_tx_irq, NULL); + free_irq(awacs_rx_irq, NULL); + + if (awacs) + iounmap(awacs); + if (i2s) + iounmap(i2s); + iounmap(awacs_txdma); + iounmap(awacs_rxdma); + + release_mem_region(awacs_rsrc[0].start, + awacs_rsrc[0].end - awacs_rsrc[0].start + 1); + release_mem_region(awacs_rsrc[1].start, + awacs_rsrc[1].end - awacs_rsrc[1].start + 1); + release_mem_region(awacs_rsrc[2].start, + awacs_rsrc[2].end - awacs_rsrc[2].start + 1); + + kfree(awacs_tx_cmd_space); + kfree(awacs_rx_cmd_space); + kfree(beep_dbdma_cmd_space); + kfree(beep_buf); +#ifdef CONFIG_PM + pmu_unregister_sleep_notifier(&awacs_sleep_notifier); +#endif +} +#endif /* MODULE */ + +static void PMacSilence(void) +{ + /* turn off output dma */ + DBDMA_DO_STOP(awacs_txdma); +} + +/* don't know what to do really - just have to leave it where + * OF left things +*/ + +static int daca_set_frame_rate(void) +{ + if (i2s) { + out_le32(i2s + (I2S_REG_SERIAL_FORMAT >> 2), 0x41190000); + out_le32(i2s + (I2S_REG_DATAWORD_SIZES >> 2), 0x02000200); + } + dmasound.hard.speed = 44100 ; + awacs_rate_index = 0 ; + return 44100 ; +} + +static int awacs_freqs[8] = { + 44100, 29400, 22050, 17640, 14700, 11025, 8820, 7350 +}; +static int awacs_freqs_ok[8] = { 1, 1, 1, 1, 1, 1, 1, 1 }; + +static int +awacs_set_frame_rate(int desired, int catch_r) +{ + int tolerance, i = 8 ; + /* + * If we have a sample rate which is within catchRadius percent + * of the requested value, we don't have to expand the samples. + * Otherwise choose the next higher rate. + * N.B.: burgundy awacs only works at 44100 Hz. + */ + do { + tolerance = catch_r * awacs_freqs[--i] / 100; + if (awacs_freqs_ok[i] + && dmasound.soft.speed <= awacs_freqs[i] + tolerance) + break; + } while (i > 0); + dmasound.hard.speed = awacs_freqs[i]; + awacs_rate_index = i; + + out_le32(&awacs->control, MASK_IEPC | (i << 8) | 0x11 ); + awacs_reg[1] = (awacs_reg[1] & ~MASK_SAMPLERATE) | (i << 3); + awacs_write(awacs_reg[1] | MASK_ADDR1); + return dmasound.hard.speed; +} + +static int +burgundy_set_frame_rate(void) +{ + awacs_rate_index = 0 ; + awacs_reg[1] = (awacs_reg[1] & ~MASK_SAMPLERATE) ; + /* XXX disable error interrupt on burgundy for now */ + out_le32(&awacs->control, MASK_IEPC | 0 | 0x11 | MASK_IEE); + return 44100 ; +} + +static int +set_frame_rate(int desired, int catch_r) +{ + switch (awacs_revision) { + case AWACS_BURGUNDY: + dmasound.hard.speed = burgundy_set_frame_rate(); + break ; + case AWACS_TUMBLER: + case AWACS_SNAPPER: + dmasound.hard.speed = tas_set_frame_rate(); + break ; + case AWACS_DACA: + dmasound.hard.speed = + daca_set_frame_rate(); + break ; + default: + dmasound.hard.speed = awacs_set_frame_rate(desired, + catch_r); + break ; + } + return dmasound.hard.speed ; +} + +static void +awacs_recalibrate(void) +{ + /* Sorry for the horrible delays... I hope to get that improved + * by making the whole PM process asynchronous in a future version + */ + msleep(750); + awacs_reg[1] |= MASK_CMUTE | MASK_AMUTE; + awacs_write(awacs_reg[1] | MASK_RECALIBRATE | MASK_ADDR1); + msleep(1000); + awacs_write(awacs_reg[1] | MASK_ADDR1); +} + +static void PMacInit(void) +{ + int tolerance; + + switch (dmasound.soft.format) { + case AFMT_S16_LE: + case AFMT_U16_LE: + if (hw_can_byteswap) + dmasound.hard.format = AFMT_S16_LE; + else + dmasound.hard.format = AFMT_S16_BE; + break; + default: + dmasound.hard.format = AFMT_S16_BE; + break; + } + dmasound.hard.stereo = 1; + dmasound.hard.size = 16; + + /* set dmasound.hard.speed - on the basis of what we want (soft) + * and the tolerance we'll allow. + */ + set_frame_rate(dmasound.soft.speed, catchRadius) ; + + tolerance = (catchRadius * dmasound.hard.speed) / 100; + if (dmasound.soft.speed >= dmasound.hard.speed - tolerance) { + dmasound.trans_write = &transAwacsNormal; + dmasound.trans_read = &transAwacsNormalRead; + } else { + dmasound.trans_write = &transAwacsExpand; + dmasound.trans_read = &transAwacsExpandRead; + } + + if (awacs) { + if (hw_can_byteswap && (dmasound.hard.format == AFMT_S16_LE)) + out_le32(&awacs->byteswap, BS_VAL); + else + out_le32(&awacs->byteswap, 0); + } + + expand_bal = -dmasound.soft.speed; + expand_read_bal = -dmasound.soft.speed; +} + +static int PMacSetFormat(int format) +{ + int size; + int req_format = format; + + switch (format) { + case AFMT_QUERY: + return dmasound.soft.format; + case AFMT_MU_LAW: + case AFMT_A_LAW: + case AFMT_U8: + case AFMT_S8: + size = 8; + break; + case AFMT_S16_LE: + if(!hw_can_byteswap) + format = AFMT_S16_BE; + case AFMT_S16_BE: + size = 16; + break; + case AFMT_U16_LE: + if(!hw_can_byteswap) + format = AFMT_U16_BE; + case AFMT_U16_BE: + size = 16; + break; + default: /* :-) */ + printk(KERN_ERR "dmasound: unknown format 0x%x, using AFMT_U8\n", + format); + size = 8; + format = AFMT_U8; + } + + if (req_format == format) { + dmasound.soft.format = format; + dmasound.soft.size = size; + if (dmasound.minDev == SND_DEV_DSP) { + dmasound.dsp.format = format; + dmasound.dsp.size = size; + } + } + + return format; +} + +#define AWACS_VOLUME_TO_MASK(x) (15 - ((((x) - 1) * 15) / 99)) +#define AWACS_MASK_TO_VOLUME(y) (100 - ((y) * 99 / 15)) + +static int awacs_get_volume(int reg, int lshift) +{ + int volume; + + volume = AWACS_MASK_TO_VOLUME((reg >> lshift) & 0xf); + volume |= AWACS_MASK_TO_VOLUME(reg & 0xf) << 8; + return volume; +} + +static int awacs_volume_setter(int volume, int n, int mute, int lshift) +{ + int r1, rn; + + if (mute && volume == 0) { + r1 = awacs_reg[1] | mute; + } else { + r1 = awacs_reg[1] & ~mute; + rn = awacs_reg[n] & ~(0xf | (0xf << lshift)); + rn |= ((AWACS_VOLUME_TO_MASK(volume & 0xff) & 0xf) << lshift); + rn |= AWACS_VOLUME_TO_MASK((volume >> 8) & 0xff) & 0xf; + awacs_reg[n] = rn; + awacs_write((n << 12) | rn); + volume = awacs_get_volume(rn, lshift); + } + if (r1 != awacs_reg[1]) { + awacs_reg[1] = r1; + awacs_write(r1 | MASK_ADDR1); + } + return volume; +} + +static int PMacSetVolume(int volume) +{ + printk(KERN_WARNING "Bogus call to PMacSetVolume !\n"); + return 0; +} + +static void awacs_setup_for_beep(int speed) +{ + out_le32(&awacs->control, + (in_le32(&awacs->control) & ~0x1f00) + | ((speed > 0 ? speed : awacs_rate_index) << 8)); + + if (hw_can_byteswap && (dmasound.hard.format == AFMT_S16_LE) && speed == -1) + out_le32(&awacs->byteswap, BS_VAL); + else + out_le32(&awacs->byteswap, 0); +} + +/* CHECK: how much of this *really* needs IRQs masked? */ +static void __PMacPlay(void) +{ + volatile struct dbdma_cmd *cp; + int next_frg, count; + + count = 300 ; /* > two cycles at the lowest sample rate */ + + /* what we want to send next */ + next_frg = (write_sq.front + write_sq.active) % write_sq.max_count; + + if (awacs_beep_state) { + /* sound takes precedence over beeps */ + /* stop the dma channel */ + out_le32(&awacs_txdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16); + while ( (in_le32(&awacs_txdma->status) & RUN) && count--) + udelay(1); + if (awacs) + awacs_setup_for_beep(-1); + out_le32(&awacs_txdma->cmdptr, + virt_to_bus(&(awacs_tx_cmds[next_frg]))); + + beep_playing = 0; + awacs_beep_state = 0; + } + /* this won't allow more than two frags to be in the output queue at + once. (or one, if the max frags is 2 - because count can't exceed + 2 in that case) + */ + while (write_sq.active < 2 && write_sq.active < write_sq.count) { + count = (write_sq.count == write_sq.active + 1) ? + write_sq.rear_size:write_sq.block_size ; + if (count < write_sq.block_size) { + if (!write_sq.syncing) /* last block not yet filled,*/ + break; /* and we're not syncing or POST-ed */ + else { + /* pretend the block is full to force a new + block to be started on the next write */ + write_sq.rear_size = write_sq.block_size ; + write_sq.syncing &= ~2 ; /* clear POST */ + } + } + cp = &awacs_tx_cmds[next_frg]; + st_le16(&cp->req_count, count); + st_le16(&cp->xfer_status, 0); + st_le16(&cp->command, OUTPUT_MORE + INTR_ALWAYS); + /* put a STOP at the end of the queue - but only if we have + space for it. This means that, if we under-run and we only + have two fragments, we might re-play sound from an existing + queued frag. I guess the solution to that is not to set two + frags if you are likely to under-run... + */ + if (write_sq.count < write_sq.max_count) { + if (++next_frg >= write_sq.max_count) + next_frg = 0 ; /* wrap */ + /* if we get here then we've underrun so we will stop*/ + st_le16(&awacs_tx_cmds[next_frg].command, DBDMA_STOP); + } + /* set the dbdma controller going, if it is not already */ + if (write_sq.active == 0) + out_le32(&awacs_txdma->cmdptr, virt_to_bus(cp)); + (void)in_le32(&awacs_txdma->status); + out_le32(&awacs_txdma->control, ((RUN|WAKE) << 16) + (RUN|WAKE)); + ++write_sq.active; + } +} + +static void PMacPlay(void) +{ + LOCK(); + if (!awacs_sleeping) { + unsigned long flags; + + spin_lock_irqsave(&dmasound.lock, flags); + __PMacPlay(); + spin_unlock_irqrestore(&dmasound.lock, flags); + } + UNLOCK(); +} + +static void PMacRecord(void) +{ + unsigned long flags; + + if (read_sq.active) + return; + + spin_lock_irqsave(&dmasound.lock, flags); + + /* This is all we have to do......Just start it up. + */ + out_le32(&awacs_rxdma->control, ((RUN|WAKE) << 16) + (RUN|WAKE)); + read_sq.active = 1; + + spin_unlock_irqrestore(&dmasound.lock, flags); +} + +/* if the TX status comes up "DEAD" - reported on some Power Computing machines + we need to re-start the dbdma - but from a different physical start address + and with a different transfer length. It would get very messy to do this + with the normal dbdma_cmd blocks - we would have to re-write the buffer start + addresses each time. So, we will keep a single dbdma_cmd block which can be + fiddled with. + When DEAD status is first reported the content of the faulted dbdma block is + copied into the emergency buffer and we note that the buffer is in use. + we then bump the start physical address by the amount that was successfully + output before it died. + On any subsequent DEAD result we just do the bump-ups (we know that we are + already using the emergency dbdma_cmd). + CHECK: this just tries to "do it". It is possible that we should abandon + xfers when the number of residual bytes gets below a certain value - I can + see that this might cause a loop-forever if too small a transfer causes + DEAD status. However this is a TODO for now - we'll see what gets reported. + When we get a successful transfer result with the emergency buffer we just + pretend that it completed using the original dmdma_cmd and carry on. The + 'next_cmd' field will already point back to the original loop of blocks. +*/ + +static irqreturn_t +pmac_awacs_tx_intr(int irq, void *devid) +{ + int i = write_sq.front; + int stat; + int i_nowrap = write_sq.front; + volatile struct dbdma_cmd *cp; + /* != 0 when we are dealing with a DEAD xfer */ + static int emergency_in_use; + + spin_lock(&dmasound.lock); + while (write_sq.active > 0) { /* we expect to have done something*/ + if (emergency_in_use) /* we are dealing with DEAD xfer */ + cp = emergency_dbdma_cmd ; + else + cp = &awacs_tx_cmds[i]; + stat = ld_le16(&cp->xfer_status); + if (stat & DEAD) { + unsigned short req, res ; + unsigned int phy ; +#ifdef DEBUG_DMASOUND +printk("dmasound_pmac: tx-irq: xfer died - patching it up...\n") ; +#endif + /* to clear DEAD status we must first clear RUN + set it to quiescent to be on the safe side */ + (void)in_le32(&awacs_txdma->status); + out_le32(&awacs_txdma->control, + (RUN|PAUSE|FLUSH|WAKE) << 16); + write_sq.died++ ; + if (!emergency_in_use) { /* new problem */ + memcpy((void *)emergency_dbdma_cmd, (void *)cp, + sizeof(struct dbdma_cmd)); + emergency_in_use = 1; + cp = emergency_dbdma_cmd; + } + /* now bump the values to reflect the amount + we haven't yet shifted */ + req = ld_le16(&cp->req_count); + res = ld_le16(&cp->res_count); + phy = ld_le32(&cp->phy_addr); + phy += (req - res); + st_le16(&cp->req_count, res); + st_le16(&cp->res_count, 0); + st_le16(&cp->xfer_status, 0); + st_le32(&cp->phy_addr, phy); + st_le32(&cp->cmd_dep, virt_to_bus(&awacs_tx_cmds[(i+1)%write_sq.max_count])); + st_le16(&cp->command, OUTPUT_MORE | BR_ALWAYS | INTR_ALWAYS); + + /* point at our patched up command block */ + out_le32(&awacs_txdma->cmdptr, virt_to_bus(cp)); + /* we must re-start the controller */ + (void)in_le32(&awacs_txdma->status); + /* should complete clearing the DEAD status */ + out_le32(&awacs_txdma->control, + ((RUN|WAKE) << 16) + (RUN|WAKE)); + break; /* this block is still going */ + } + if ((stat & ACTIVE) == 0) + break; /* this frame is still going */ + if (emergency_in_use) + emergency_in_use = 0 ; /* done that */ + --write_sq.count; + --write_sq.active; + i_nowrap++; + if (++i >= write_sq.max_count) + i = 0; + } + + /* if we stopped and we were not sync-ing - then we under-ran */ + if( write_sq.syncing == 0 ){ + stat = in_le32(&awacs_txdma->status) ; + /* we hit the dbdma_stop */ + if( (stat & ACTIVE) == 0 ) write_sq.xruns++ ; + } + + /* if we used some data up then wake the writer to supply some more*/ + if (i_nowrap != write_sq.front) + WAKE_UP(write_sq.action_queue); + write_sq.front = i; + + /* but make sure we funnel what we've already got */\ + if (!awacs_sleeping) + __PMacPlay(); + + /* make the wake-on-empty conditional on syncing */ + if (!write_sq.active && (write_sq.syncing & 1)) + WAKE_UP(write_sq.sync_queue); /* any time we're empty */ + spin_unlock(&dmasound.lock); + return IRQ_HANDLED; +} + + +static irqreturn_t +pmac_awacs_rx_intr(int irq, void *devid) +{ + int stat ; + /* For some reason on my PowerBook G3, I get one interrupt + * when the interrupt vector is installed (like something is + * pending). This happens before the dbdma is initialized by + * us, so I just check the command pointer and if it is zero, + * just blow it off. + */ + if (in_le32(&awacs_rxdma->cmdptr) == 0) + return IRQ_HANDLED; + + /* We also want to blow 'em off when shutting down. + */ + if (read_sq.active == 0) + return IRQ_HANDLED; + + spin_lock(&dmasound.lock); + /* Check multiple buffers in case we were held off from + * interrupt processing for a long time. Geeze, I really hope + * this doesn't happen. + */ + while ((stat=awacs_rx_cmds[read_sq.rear].xfer_status)) { + + /* if we got a "DEAD" status then just log it for now. + and try to restart dma. + TODO: figure out how best to fix it up + */ + if (stat & DEAD){ +#ifdef DEBUG_DMASOUND +printk("dmasound_pmac: rx-irq: DIED - attempting resurection\n"); +#endif + /* to clear DEAD status we must first clear RUN + set it to quiescent to be on the safe side */ + (void)in_le32(&awacs_txdma->status); + out_le32(&awacs_txdma->control, + (RUN|PAUSE|FLUSH|WAKE) << 16); + awacs_rx_cmds[read_sq.rear].xfer_status = 0; + awacs_rx_cmds[read_sq.rear].res_count = 0; + read_sq.died++ ; + (void)in_le32(&awacs_txdma->status); + /* re-start the same block */ + out_le32(&awacs_rxdma->cmdptr, + virt_to_bus(&awacs_rx_cmds[read_sq.rear])); + /* we must re-start the controller */ + (void)in_le32(&awacs_rxdma->status); + /* should complete clearing the DEAD status */ + out_le32(&awacs_rxdma->control, + ((RUN|WAKE) << 16) + (RUN|WAKE)); + spin_unlock(&dmasound.lock); + return IRQ_HANDLED; /* try this block again */ + } + /* Clear status and move on to next buffer. + */ + awacs_rx_cmds[read_sq.rear].xfer_status = 0; + read_sq.rear++; + + /* Wrap the buffer ring. + */ + if (read_sq.rear >= read_sq.max_active) + read_sq.rear = 0; + + /* If we have caught up to the front buffer, bump it. + * This will cause weird (but not fatal) results if the + * read loop is currently using this buffer. The user is + * behind in this case anyway, so weird things are going + * to happen. + */ + if (read_sq.rear == read_sq.front) { + read_sq.front++; + read_sq.xruns++ ; /* we overan */ + if (read_sq.front >= read_sq.max_active) + read_sq.front = 0; + } + } + + WAKE_UP(read_sq.action_queue); + spin_unlock(&dmasound.lock); + return IRQ_HANDLED; +} + + +static irqreturn_t +pmac_awacs_intr(int irq, void *devid) +{ + int ctrl; + int status; + int r1; + + spin_lock(&dmasound.lock); + ctrl = in_le32(&awacs->control); + status = in_le32(&awacs->codec_stat); + + if (ctrl & MASK_PORTCHG) { + /* tested on Screamer, should work on others too */ + if (awacs_revision == AWACS_SCREAMER) { + if (((status & MASK_HDPCONN) >> 3) && (hdp_connected == 0)) { + hdp_connected = 1; + + r1 = awacs_reg[1] | MASK_SPKMUTE; + awacs_reg[1] = r1; + awacs_write(r1 | MASK_ADDR_MUTE); + } else if (((status & MASK_HDPCONN) >> 3 == 0) && (hdp_connected == 1)) { + hdp_connected = 0; + + r1 = awacs_reg[1] & ~MASK_SPKMUTE; + awacs_reg[1] = r1; + awacs_write(r1 | MASK_ADDR_MUTE); + } + } + } + if (ctrl & MASK_CNTLERR) { + int err = (in_le32(&awacs->codec_stat) & MASK_ERRCODE) >> 16; + /* CHECK: we just swallow burgundy errors at the moment..*/ + if (err != 0 && awacs_revision != AWACS_BURGUNDY) + printk(KERN_ERR "dmasound_pmac: error %x\n", err); + } + /* Writing 1s to the CNTLERR and PORTCHG bits clears them... */ + out_le32(&awacs->control, ctrl); + spin_unlock(&dmasound.lock); + return IRQ_HANDLED; +} + +static void +awacs_write(int val) +{ + int count = 300 ; + if (awacs_revision >= AWACS_DACA || !awacs) + return ; + + while ((in_le32(&awacs->codec_ctrl) & MASK_NEWECMD) && count--) + udelay(1) ; /* timeout is > 2 samples at lowest rate */ + out_le32(&awacs->codec_ctrl, val | (awacs_subframe << 22)); + (void)in_le32(&awacs->byteswap); +} + +/* this is called when the beep timer expires... it will be called even + if the beep has been overidden by other sound output. +*/ +static void awacs_nosound(unsigned long xx) +{ + unsigned long flags; + int count = 600 ; /* > four samples at lowest rate */ + + spin_lock_irqsave(&dmasound.lock, flags); + if (beep_playing) { + st_le16(&beep_dbdma_cmd->command, DBDMA_STOP); + out_le32(&awacs_txdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16); + while ((in_le32(&awacs_txdma->status) & RUN) && count--) + udelay(1); + if (awacs) + awacs_setup_for_beep(-1); + beep_playing = 0; + } + spin_unlock_irqrestore(&dmasound.lock, flags); +} + +/* + * We generate the beep with a single dbdma command that loops a buffer + * forever - without generating interrupts. + * + * So, to stop it you have to stop dma output as per awacs_nosound. + */ +static int awacs_beep_event(struct input_dev *dev, unsigned int type, + unsigned int code, int hz) +{ + unsigned long flags; + int beep_speed = 0; + int srate; + int period, ncycles, nsamples; + int i, j, f; + short *p; + static int beep_hz_cache; + static int beep_nsamples_cache; + static int beep_volume_cache; + + if (type != EV_SND) + return -1; + switch (code) { + case SND_BELL: + if (hz) + hz = 1000; + break; + case SND_TONE: + break; + default: + return -1; + } + + if (beep_buf == NULL) + return -1; + + /* quick-hack fix for DACA, Burgundy & Tumbler */ + + if (awacs_revision >= AWACS_DACA){ + srate = 44100 ; + } else { + for (i = 0; i < 8 && awacs_freqs[i] >= BEEP_SRATE; ++i) + if (awacs_freqs_ok[i]) + beep_speed = i; + srate = awacs_freqs[beep_speed]; + } + + if (hz <= srate / BEEP_BUFLEN || hz > srate / 2) { + /* cancel beep currently playing */ + awacs_nosound(0); + return 0; + } + + spin_lock_irqsave(&dmasound.lock, flags); + if (beep_playing || write_sq.active || beep_buf == NULL) { + spin_unlock_irqrestore(&dmasound.lock, flags); + return -1; /* too hard, sorry :-( */ + } + beep_playing = 1; + st_le16(&beep_dbdma_cmd->command, OUTPUT_MORE + BR_ALWAYS); + spin_unlock_irqrestore(&dmasound.lock, flags); + + if (hz == beep_hz_cache && beep_vol == beep_volume_cache) { + nsamples = beep_nsamples_cache; + } else { + period = srate * 256 / hz; /* fixed point */ + ncycles = BEEP_BUFLEN * 256 / period; + nsamples = (period * ncycles) >> 8; + f = ncycles * 65536 / nsamples; + j = 0; + p = beep_buf; + for (i = 0; i < nsamples; ++i, p += 2) { + p[0] = p[1] = beep_wform[j >> 8] * beep_vol; + j = (j + f) & 0xffff; + } + beep_hz_cache = hz; + beep_volume_cache = beep_vol; + beep_nsamples_cache = nsamples; + } + + st_le16(&beep_dbdma_cmd->req_count, nsamples*4); + st_le16(&beep_dbdma_cmd->xfer_status, 0); + st_le32(&beep_dbdma_cmd->cmd_dep, virt_to_bus(beep_dbdma_cmd)); + st_le32(&beep_dbdma_cmd->phy_addr, virt_to_bus(beep_buf)); + awacs_beep_state = 1; + + spin_lock_irqsave(&dmasound.lock, flags); + if (beep_playing) { /* i.e. haven't been terminated already */ + int count = 300 ; + out_le32(&awacs_txdma->control, (RUN|WAKE|FLUSH|PAUSE) << 16); + while ((in_le32(&awacs_txdma->status) & RUN) && count--) + udelay(1); /* timeout > 2 samples at lowest rate*/ + if (awacs) + awacs_setup_for_beep(beep_speed); + out_le32(&awacs_txdma->cmdptr, virt_to_bus(beep_dbdma_cmd)); + (void)in_le32(&awacs_txdma->status); + out_le32(&awacs_txdma->control, RUN | (RUN << 16)); + } + spin_unlock_irqrestore(&dmasound.lock, flags); + + return 0; +} + +/* used in init and for wake-up */ + +static void +load_awacs(void) +{ + awacs_write(awacs_reg[0] + MASK_ADDR0); + awacs_write(awacs_reg[1] + MASK_ADDR1); + awacs_write(awacs_reg[2] + MASK_ADDR2); + awacs_write(awacs_reg[4] + MASK_ADDR4); + + if (awacs_revision == AWACS_SCREAMER) { + awacs_write(awacs_reg[5] + MASK_ADDR5); + msleep(100); + awacs_write(awacs_reg[6] + MASK_ADDR6); + msleep(2); + awacs_write(awacs_reg[1] + MASK_ADDR1); + awacs_write(awacs_reg[7] + MASK_ADDR7); + } + if (awacs) { + if (hw_can_byteswap && (dmasound.hard.format == AFMT_S16_LE)) + out_le32(&awacs->byteswap, BS_VAL); + else + out_le32(&awacs->byteswap, 0); + } +} + +#ifdef CONFIG_PM +/* + * Save state when going to sleep, restore it afterwards. + */ +/* FIXME: sort out disabling/re-enabling of read stuff as well */ +static void awacs_sleep_notify(struct pmu_sleep_notifier *self, int when) +{ + unsigned long flags; + + switch (when) { + case PBOOK_SLEEP_NOW: + LOCK(); + awacs_sleeping = 1; + /* Tell the rest of the driver we are now going to sleep */ + mb(); + if (awacs_revision == AWACS_SCREAMER || + awacs_revision == AWACS_AWACS) { + awacs_reg1_save = awacs_reg[1]; + awacs_reg[1] |= MASK_AMUTE | MASK_CMUTE; + awacs_write(MASK_ADDR1 | awacs_reg[1]); + } + + PMacSilence(); + /* stop rx - if going - a bit of a daft user... but */ + out_le32(&awacs_rxdma->control, (RUN|WAKE|FLUSH << 16)); + /* deny interrupts */ + if (awacs) + disable_irq(awacs_irq); + disable_irq(awacs_tx_irq); + disable_irq(awacs_rx_irq); + /* Chip specific sleep code */ + switch (awacs_revision) { + case AWACS_TUMBLER: + case AWACS_SNAPPER: + write_audio_gpio(gpio_headphone_mute, gpio_headphone_mute_pol); + write_audio_gpio(gpio_amp_mute, gpio_amp_mute_pol); + tas_enter_sleep(); + write_audio_gpio(gpio_audio_reset, gpio_audio_reset_pol); + break ; + case AWACS_DACA: + daca_enter_sleep(); + break ; + case AWACS_BURGUNDY: + break ; + case AWACS_SCREAMER: + case AWACS_AWACS: + default: + out_le32(&awacs->control, 0x11) ; + break ; + } + /* Disable sound clock */ + pmac_call_feature(PMAC_FTR_SOUND_CHIP_ENABLE, awacs_node, 0, 0); + /* According to Darwin, we do that after turning off the sound + * chip clock. All this will have to be cleaned up once we properly + * parse the OF sound-objects + */ + if ((machine_is_compatible("PowerBook3,1") || + machine_is_compatible("PowerBook3,2")) && awacs) { + awacs_reg[1] |= MASK_PAROUT0 | MASK_PAROUT1; + awacs_write(MASK_ADDR1 | awacs_reg[1]); + msleep(200); + } + break; + case PBOOK_WAKE: + /* Enable sound clock */ + pmac_call_feature(PMAC_FTR_SOUND_CHIP_ENABLE, awacs_node, 0, 1); + if ((machine_is_compatible("PowerBook3,1") || + machine_is_compatible("PowerBook3,2")) && awacs) { + msleep(100); + awacs_reg[1] &= ~(MASK_PAROUT0 | MASK_PAROUT1); + awacs_write(MASK_ADDR1 | awacs_reg[1]); + msleep(300); + } else + msleep(1000); + /* restore settings */ + switch (awacs_revision) { + case AWACS_TUMBLER: + case AWACS_SNAPPER: + write_audio_gpio(gpio_headphone_mute, gpio_headphone_mute_pol); + write_audio_gpio(gpio_amp_mute, gpio_amp_mute_pol); + write_audio_gpio(gpio_audio_reset, gpio_audio_reset_pol); + msleep(100); + write_audio_gpio(gpio_audio_reset, !gpio_audio_reset_pol); + msleep(150); + tas_leave_sleep(); /* Stub for now */ + headphone_intr(0, NULL); + break; + case AWACS_DACA: + msleep(10); /* Check this !!! */ + daca_leave_sleep(); + break ; /* dont know how yet */ + case AWACS_BURGUNDY: + break ; + case AWACS_SCREAMER: + case AWACS_AWACS: + default: + load_awacs() ; + break ; + } + /* Recalibrate chip */ + if (awacs_revision == AWACS_SCREAMER && awacs) + awacs_recalibrate(); + /* Make sure dma is stopped */ + PMacSilence(); + if (awacs) + enable_irq(awacs_irq); + enable_irq(awacs_tx_irq); + enable_irq(awacs_rx_irq); + if (awacs) { + /* OK, allow ints back again */ + out_le32(&awacs->control, MASK_IEPC + | (awacs_rate_index << 8) | 0x11 + | (awacs_revision < AWACS_DACA ? MASK_IEE: 0)); + } + if (macio_base && is_pbook_g3) { + /* FIXME: should restore the setup we had...*/ + out_8(macio_base + 0x37, 3); + } else if (is_pbook_3X00) { + in_8(latch_base + 0x190); + } + /* Remove mute */ + if (awacs_revision == AWACS_SCREAMER || + awacs_revision == AWACS_AWACS) { + awacs_reg[1] = awacs_reg1_save; + awacs_write(MASK_ADDR1 | awacs_reg[1]); + } + awacs_sleeping = 0; + /* Resume pending sounds. */ + /* we don't try to restart input... */ + spin_lock_irqsave(&dmasound.lock, flags); + __PMacPlay(); + spin_unlock_irqrestore(&dmasound.lock, flags); + UNLOCK(); + } +} +#endif /* CONFIG_PM */ + + +/* All the burgundy functions: */ + +/* Waits for busy flag to clear */ +static inline void +awacs_burgundy_busy_wait(void) +{ + int count = 50; /* > 2 samples at 44k1 */ + while ((in_le32(&awacs->codec_ctrl) & MASK_NEWECMD) && count--) + udelay(1) ; +} + +static inline void +awacs_burgundy_extend_wait(void) +{ + int count = 50 ; /* > 2 samples at 44k1 */ + while ((!(in_le32(&awacs->codec_stat) & MASK_EXTEND)) && count--) + udelay(1) ; + count = 50; + while ((in_le32(&awacs->codec_stat) & MASK_EXTEND) && count--) + udelay(1); +} + +static void +awacs_burgundy_wcw(unsigned addr, unsigned val) +{ + out_le32(&awacs->codec_ctrl, addr + 0x200c00 + (val & 0xff)); + awacs_burgundy_busy_wait(); + out_le32(&awacs->codec_ctrl, addr + 0x200d00 +((val>>8) & 0xff)); + awacs_burgundy_busy_wait(); + out_le32(&awacs->codec_ctrl, addr + 0x200e00 +((val>>16) & 0xff)); + awacs_burgundy_busy_wait(); + out_le32(&awacs->codec_ctrl, addr + 0x200f00 +((val>>24) & 0xff)); + awacs_burgundy_busy_wait(); +} + +static unsigned +awacs_burgundy_rcw(unsigned addr) +{ + unsigned val = 0; + unsigned long flags; + + /* should have timeouts here */ + spin_lock_irqsave(&dmasound.lock, flags); + + out_le32(&awacs->codec_ctrl, addr + 0x100000); + awacs_burgundy_busy_wait(); + awacs_burgundy_extend_wait(); + val += (in_le32(&awacs->codec_stat) >> 4) & 0xff; + + out_le32(&awacs->codec_ctrl, addr + 0x100100); + awacs_burgundy_busy_wait(); + awacs_burgundy_extend_wait(); + val += ((in_le32(&awacs->codec_stat)>>4) & 0xff) <<8; + + out_le32(&awacs->codec_ctrl, addr + 0x100200); + awacs_burgundy_busy_wait(); + awacs_burgundy_extend_wait(); + val += ((in_le32(&awacs->codec_stat)>>4) & 0xff) <<16; + + out_le32(&awacs->codec_ctrl, addr + 0x100300); + awacs_burgundy_busy_wait(); + awacs_burgundy_extend_wait(); + val += ((in_le32(&awacs->codec_stat)>>4) & 0xff) <<24; + + spin_unlock_irqrestore(&dmasound.lock, flags); + + return val; +} + + +static void +awacs_burgundy_wcb(unsigned addr, unsigned val) +{ + out_le32(&awacs->codec_ctrl, addr + 0x300000 + (val & 0xff)); + awacs_burgundy_busy_wait(); +} + +static unsigned +awacs_burgundy_rcb(unsigned addr) +{ + unsigned val = 0; + unsigned long flags; + + /* should have timeouts here */ + spin_lock_irqsave(&dmasound.lock, flags); + + out_le32(&awacs->codec_ctrl, addr + 0x100000); + awacs_burgundy_busy_wait(); + awacs_burgundy_extend_wait(); + val += (in_le32(&awacs->codec_stat) >> 4) & 0xff; + + spin_unlock_irqrestore(&dmasound.lock, flags); + + return val; +} + +static int +awacs_burgundy_check(void) +{ + /* Checks to see the chip is alive and kicking */ + int error = in_le32(&awacs->codec_ctrl) & MASK_ERRCODE; + + return error == 0xf0000; +} + +static int +awacs_burgundy_init(void) +{ + if (awacs_burgundy_check()) { + printk(KERN_WARNING "dmasound_pmac: burgundy not working :-(\n"); + return 1; + } + + awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_OUTPUTENABLES, + DEF_BURGUNDY_OUTPUTENABLES); + awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES, + DEF_BURGUNDY_MORE_OUTPUTENABLES); + awacs_burgundy_wcw(MASK_ADDR_BURGUNDY_OUTPUTSELECTS, + DEF_BURGUNDY_OUTPUTSELECTS); + + awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_INPSEL21, + DEF_BURGUNDY_INPSEL21); + awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_INPSEL3, + DEF_BURGUNDY_INPSEL3); + awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_GAINCD, + DEF_BURGUNDY_GAINCD); + awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_GAINLINE, + DEF_BURGUNDY_GAINLINE); + awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_GAINMIC, + DEF_BURGUNDY_GAINMIC); + awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_GAINMODEM, + DEF_BURGUNDY_GAINMODEM); + + awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_ATTENSPEAKER, + DEF_BURGUNDY_ATTENSPEAKER); + awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_ATTENLINEOUT, + DEF_BURGUNDY_ATTENLINEOUT); + awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_ATTENHP, + DEF_BURGUNDY_ATTENHP); + + awacs_burgundy_wcw(MASK_ADDR_BURGUNDY_MASTER_VOLUME, + DEF_BURGUNDY_MASTER_VOLUME); + awacs_burgundy_wcw(MASK_ADDR_BURGUNDY_VOLCD, + DEF_BURGUNDY_VOLCD); + awacs_burgundy_wcw(MASK_ADDR_BURGUNDY_VOLLINE, + DEF_BURGUNDY_VOLLINE); + awacs_burgundy_wcw(MASK_ADDR_BURGUNDY_VOLMIC, + DEF_BURGUNDY_VOLMIC); + return 0; +} + +static void +awacs_burgundy_write_volume(unsigned address, int volume) +{ + int hardvolume,lvolume,rvolume; + + lvolume = (volume & 0xff) ? (volume & 0xff) + 155 : 0; + rvolume = ((volume >>8)&0xff) ? ((volume >> 8)&0xff ) + 155 : 0; + + hardvolume = lvolume + (rvolume << 16); + + awacs_burgundy_wcw(address, hardvolume); +} + +static int +awacs_burgundy_read_volume(unsigned address) +{ + int softvolume,wvolume; + + wvolume = awacs_burgundy_rcw(address); + + softvolume = (wvolume & 0xff) - 155; + softvolume += (((wvolume >> 16) & 0xff) - 155)<<8; + + return softvolume > 0 ? softvolume : 0; +} + +static int +awacs_burgundy_read_mvolume(unsigned address) +{ + int lvolume,rvolume,wvolume; + + wvolume = awacs_burgundy_rcw(address); + + wvolume &= 0xffff; + + rvolume = (wvolume & 0xff) - 155; + lvolume = ((wvolume & 0xff00)>>8) - 155; + + return lvolume + (rvolume << 8); +} + +static void +awacs_burgundy_write_mvolume(unsigned address, int volume) +{ + int lvolume,rvolume,hardvolume; + + lvolume = (volume &0xff) ? (volume & 0xff) + 155 :0; + rvolume = ((volume >>8) & 0xff) ? (volume >> 8) + 155 :0; + + hardvolume = lvolume + (rvolume << 8); + hardvolume += (hardvolume << 16); + + awacs_burgundy_wcw(address, hardvolume); +} + +/* End burgundy functions */ + +/* Set up output volumes on machines with the 'perch/whisper' extension card. + * this has an SGS i2c chip (7433) which is accessed using the cuda. + * + * TODO: split this out and make use of the other parts of the SGS chip to + * do Bass, Treble etc. + */ + +static void +awacs_enable_amp(int spkr_vol) +{ +#ifdef CONFIG_ADB_CUDA + struct adb_request req; + + if (sys_ctrler != SYS_CTRLER_CUDA) + return; + + /* turn on headphones */ + cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_GET_SET_IIC, + 0x8a, 4, 0); + while (!req.complete) cuda_poll(); + cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_GET_SET_IIC, + 0x8a, 6, 0); + while (!req.complete) cuda_poll(); + + /* turn on speaker */ + cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_GET_SET_IIC, + 0x8a, 3, (100 - (spkr_vol & 0xff)) * 32 / 100); + while (!req.complete) cuda_poll(); + cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_GET_SET_IIC, + 0x8a, 5, (100 - ((spkr_vol >> 8) & 0xff)) * 32 / 100); + while (!req.complete) cuda_poll(); + + cuda_request(&req, NULL, 5, CUDA_PACKET, + CUDA_GET_SET_IIC, 0x8a, 1, 0x29); + while (!req.complete) cuda_poll(); +#endif /* CONFIG_ADB_CUDA */ +} + + +/*** Mid level stuff *********************************************************/ + + +/* + * /dev/mixer abstraction + */ + +static void do_line_lev(int data) +{ + line_lev = data ; + awacs_reg[0] &= ~MASK_MUX_AUDIN; + if ((data & 0xff) >= 50) + awacs_reg[0] |= MASK_MUX_AUDIN; + awacs_write(MASK_ADDR0 | awacs_reg[0]); +} + +static void do_ip_gain(int data) +{ + ip_gain = data ; + data &= 0xff; + awacs_reg[0] &= ~MASK_GAINLINE; + if (awacs_revision == AWACS_SCREAMER) { + awacs_reg[6] &= ~MASK_MIC_BOOST ; + if (data >= 33) { + awacs_reg[0] |= MASK_GAINLINE; + if( data >= 66) + awacs_reg[6] |= MASK_MIC_BOOST ; + } + awacs_write(MASK_ADDR6 | awacs_reg[6]) ; + } else { + if (data >= 50) + awacs_reg[0] |= MASK_GAINLINE; + } + awacs_write(MASK_ADDR0 | awacs_reg[0]); +} + +static void do_mic_lev(int data) +{ + mic_lev = data ; + data &= 0xff; + awacs_reg[0] &= ~MASK_MUX_MIC; + if (data >= 50) + awacs_reg[0] |= MASK_MUX_MIC; + awacs_write(MASK_ADDR0 | awacs_reg[0]); +} + +static void do_cd_lev(int data) +{ + cd_lev = data ; + awacs_reg[0] &= ~MASK_MUX_CD; + if ((data & 0xff) >= 50) + awacs_reg[0] |= MASK_MUX_CD; + awacs_write(MASK_ADDR0 | awacs_reg[0]); +} + +static void do_rec_lev(int data) +{ + int left, right ; + rec_lev = data ; + /* need to fudge this to use the volume setter routine */ + left = 100 - (data & 0xff) ; if( left < 0 ) left = 0 ; + right = 100 - ((data >> 8) & 0xff) ; if( right < 0 ) right = 0 ; + left |= (right << 8 ); + left = awacs_volume_setter(left, 0, 0, 4); +} + +static void do_passthru_vol(int data) +{ + passthru_vol = data ; + awacs_reg[1] &= ~MASK_LOOPTHRU; + if (awacs_revision == AWACS_SCREAMER) { + if( data ) { /* switch it on for non-zero */ + awacs_reg[1] |= MASK_LOOPTHRU; + awacs_write(MASK_ADDR1 | awacs_reg[1]); + } + data = awacs_volume_setter(data, 5, 0, 6) ; + } else { + if ((data & 0xff) >= 50) + awacs_reg[1] |= MASK_LOOPTHRU; + awacs_write(MASK_ADDR1 | awacs_reg[1]); + data = (awacs_reg[1] & MASK_LOOPTHRU)? 100: 0; + } +} + +static int awacs_mixer_ioctl(u_int cmd, u_long arg) +{ + int data; + int rc; + + switch (cmd) { + case SOUND_MIXER_READ_CAPS: + /* say we will allow multiple inputs? prob. wrong + so I'm switching it to single */ + return IOCTL_OUT(arg, 1); + case SOUND_MIXER_READ_DEVMASK: + data = SOUND_MASK_VOLUME | SOUND_MASK_SPEAKER + | SOUND_MASK_LINE | SOUND_MASK_MIC | SOUND_MASK_CD + | SOUND_MASK_IGAIN | SOUND_MASK_RECLEV + | SOUND_MASK_ALTPCM + | SOUND_MASK_MONITOR; + rc = IOCTL_OUT(arg, data); + break; + case SOUND_MIXER_READ_RECMASK: + data = SOUND_MASK_LINE | SOUND_MASK_MIC | SOUND_MASK_CD; + rc = IOCTL_OUT(arg, data); + break; + case SOUND_MIXER_READ_RECSRC: + data = 0; + if (awacs_reg[0] & MASK_MUX_AUDIN) + data |= SOUND_MASK_LINE; + if (awacs_reg[0] & MASK_MUX_MIC) + data |= SOUND_MASK_MIC; + if (awacs_reg[0] & MASK_MUX_CD) + data |= SOUND_MASK_CD; + rc = IOCTL_OUT(arg, data); + break; + case SOUND_MIXER_WRITE_RECSRC: + IOCTL_IN(arg, data); + data &= (SOUND_MASK_LINE | SOUND_MASK_MIC | SOUND_MASK_CD); + awacs_reg[0] &= ~(MASK_MUX_CD | MASK_MUX_MIC + | MASK_MUX_AUDIN); + if (data & SOUND_MASK_LINE) + awacs_reg[0] |= MASK_MUX_AUDIN; + if (data & SOUND_MASK_MIC) + awacs_reg[0] |= MASK_MUX_MIC; + if (data & SOUND_MASK_CD) + awacs_reg[0] |= MASK_MUX_CD; + awacs_write(awacs_reg[0] | MASK_ADDR0); + rc = IOCTL_OUT(arg, data); + break; + case SOUND_MIXER_READ_STEREODEVS: + data = SOUND_MASK_VOLUME | SOUND_MASK_SPEAKER| SOUND_MASK_RECLEV ; + if (awacs_revision == AWACS_SCREAMER) + data |= SOUND_MASK_MONITOR ; + rc = IOCTL_OUT(arg, data); + break; + case SOUND_MIXER_WRITE_VOLUME: + IOCTL_IN(arg, data); + line_vol = data ; + awacs_volume_setter(data, 2, 0, 6); + /* fall through */ + case SOUND_MIXER_READ_VOLUME: + rc = IOCTL_OUT(arg, line_vol); + break; + case SOUND_MIXER_WRITE_SPEAKER: + IOCTL_IN(arg, data); + spk_vol = data ; + if (has_perch) + awacs_enable_amp(data); + else + (void)awacs_volume_setter(data, 4, MASK_CMUTE, 6); + /* fall though */ + case SOUND_MIXER_READ_SPEAKER: + rc = IOCTL_OUT(arg, spk_vol); + break; + case SOUND_MIXER_WRITE_ALTPCM: /* really bell volume */ + IOCTL_IN(arg, data); + beep_vol = data & 0xff; + /* fall through */ + case SOUND_MIXER_READ_ALTPCM: + rc = IOCTL_OUT(arg, beep_vol); + break; + case SOUND_MIXER_WRITE_LINE: + IOCTL_IN(arg, data); + do_line_lev(data) ; + /* fall through */ + case SOUND_MIXER_READ_LINE: + rc = IOCTL_OUT(arg, line_lev); + break; + case SOUND_MIXER_WRITE_IGAIN: + IOCTL_IN(arg, data); + do_ip_gain(data) ; + /* fall through */ + case SOUND_MIXER_READ_IGAIN: + rc = IOCTL_OUT(arg, ip_gain); + break; + case SOUND_MIXER_WRITE_MIC: + IOCTL_IN(arg, data); + do_mic_lev(data); + /* fall through */ + case SOUND_MIXER_READ_MIC: + rc = IOCTL_OUT(arg, mic_lev); + break; + case SOUND_MIXER_WRITE_CD: + IOCTL_IN(arg, data); + do_cd_lev(data); + /* fall through */ + case SOUND_MIXER_READ_CD: + rc = IOCTL_OUT(arg, cd_lev); + break; + case SOUND_MIXER_WRITE_RECLEV: + IOCTL_IN(arg, data); + do_rec_lev(data) ; + /* fall through */ + case SOUND_MIXER_READ_RECLEV: + rc = IOCTL_OUT(arg, rec_lev); + break; + case MIXER_WRITE(SOUND_MIXER_MONITOR): + IOCTL_IN(arg, data); + do_passthru_vol(data) ; + /* fall through */ + case MIXER_READ(SOUND_MIXER_MONITOR): + rc = IOCTL_OUT(arg, passthru_vol); + break; + default: + rc = -EINVAL; + } + + return rc; +} + +static void awacs_mixer_init(void) +{ + awacs_volume_setter(line_vol, 2, 0, 6); + if (has_perch) + awacs_enable_amp(spk_vol); + else + (void)awacs_volume_setter(spk_vol, 4, MASK_CMUTE, 6); + do_line_lev(line_lev) ; + do_ip_gain(ip_gain) ; + do_mic_lev(mic_lev) ; + do_cd_lev(cd_lev) ; + do_rec_lev(rec_lev) ; + do_passthru_vol(passthru_vol) ; +} + +static int burgundy_mixer_ioctl(u_int cmd, u_long arg) +{ + int data; + int rc; + + /* We are, we are, we are... Burgundy or better */ + switch(cmd) { + case SOUND_MIXER_READ_DEVMASK: + data = SOUND_MASK_VOLUME | SOUND_MASK_CD | + SOUND_MASK_LINE | SOUND_MASK_MIC | + SOUND_MASK_SPEAKER | SOUND_MASK_ALTPCM; + rc = IOCTL_OUT(arg, data); + break; + case SOUND_MIXER_READ_RECMASK: + data = SOUND_MASK_LINE | SOUND_MASK_MIC + | SOUND_MASK_CD; + rc = IOCTL_OUT(arg, data); + break; + case SOUND_MIXER_READ_RECSRC: + data = 0; + if (awacs_reg[0] & MASK_MUX_AUDIN) + data |= SOUND_MASK_LINE; + if (awacs_reg[0] & MASK_MUX_MIC) + data |= SOUND_MASK_MIC; + if (awacs_reg[0] & MASK_MUX_CD) + data |= SOUND_MASK_CD; + rc = IOCTL_OUT(arg, data); + break; + case SOUND_MIXER_WRITE_RECSRC: + IOCTL_IN(arg, data); + data &= (SOUND_MASK_LINE + | SOUND_MASK_MIC | SOUND_MASK_CD); + awacs_reg[0] &= ~(MASK_MUX_CD | MASK_MUX_MIC + | MASK_MUX_AUDIN); + if (data & SOUND_MASK_LINE) + awacs_reg[0] |= MASK_MUX_AUDIN; + if (data & SOUND_MASK_MIC) + awacs_reg[0] |= MASK_MUX_MIC; + if (data & SOUND_MASK_CD) + awacs_reg[0] |= MASK_MUX_CD; + awacs_write(awacs_reg[0] | MASK_ADDR0); + rc = IOCTL_OUT(arg, data); + break; + case SOUND_MIXER_READ_STEREODEVS: + data = SOUND_MASK_VOLUME | SOUND_MASK_SPEAKER + | SOUND_MASK_RECLEV | SOUND_MASK_CD + | SOUND_MASK_LINE; + rc = IOCTL_OUT(arg, data); + break; + case SOUND_MIXER_READ_CAPS: + rc = IOCTL_OUT(arg, 0); + break; + case SOUND_MIXER_WRITE_VOLUME: + IOCTL_IN(arg, data); + awacs_burgundy_write_mvolume(MASK_ADDR_BURGUNDY_MASTER_VOLUME, data); + /* Fall through */ + case SOUND_MIXER_READ_VOLUME: + rc = IOCTL_OUT(arg, awacs_burgundy_read_mvolume(MASK_ADDR_BURGUNDY_MASTER_VOLUME)); + break; + case SOUND_MIXER_WRITE_SPEAKER: + IOCTL_IN(arg, data); + if (!(data & 0xff)) { + /* Mute the left speaker */ + awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES, + awacs_burgundy_rcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES) & ~0x2); + } else { + /* Unmute the left speaker */ + awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES, + awacs_burgundy_rcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES) | 0x2); + } + if (!(data & 0xff00)) { + /* Mute the right speaker */ + awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES, + awacs_burgundy_rcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES) & ~0x4); + } else { + /* Unmute the right speaker */ + awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES, + awacs_burgundy_rcb(MASK_ADDR_BURGUNDY_MORE_OUTPUTENABLES) | 0x4); + } + + data = (((data&0xff)*16)/100 > 0xf ? 0xf : + (((data&0xff)*16)/100)) + + ((((data>>8)*16)/100 > 0xf ? 0xf : + ((((data>>8)*16)/100)))<<4); + + awacs_burgundy_wcb(MASK_ADDR_BURGUNDY_ATTENSPEAKER, ~data); + /* Fall through */ + case SOUND_MIXER_READ_SPEAKER: + data = awacs_burgundy_rcb(MASK_ADDR_BURGUNDY_ATTENSPEAKER); + data = (((data & 0xf)*100)/16) + ((((data>>4)*100)/16)<<8); + rc = IOCTL_OUT(arg, (~data) & 0x0000ffff); + break; + case SOUND_MIXER_WRITE_ALTPCM: /* really bell volume */ + IOCTL_IN(arg, data); + beep_vol = data & 0xff; + /* fall through */ + case SOUND_MIXER_READ_ALTPCM: + rc = IOCTL_OUT(arg, beep_vol); + break; + case SOUND_MIXER_WRITE_LINE: + IOCTL_IN(arg, data); + awacs_burgundy_write_volume(MASK_ADDR_BURGUNDY_VOLLINE, data); + + /* fall through */ + case SOUND_MIXER_READ_LINE: + data = awacs_burgundy_read_volume(MASK_ADDR_BURGUNDY_VOLLINE); + rc = IOCTL_OUT(arg, data); + break; + case SOUND_MIXER_WRITE_MIC: + IOCTL_IN(arg, data); + /* Mic is mono device */ + data = (data << 8) + (data << 24); + awacs_burgundy_write_volume(MASK_ADDR_BURGUNDY_VOLMIC, data); + /* fall through */ + case SOUND_MIXER_READ_MIC: + data = awacs_burgundy_read_volume(MASK_ADDR_BURGUNDY_VOLMIC); + data <<= 24; + rc = IOCTL_OUT(arg, data); + break; + case SOUND_MIXER_WRITE_CD: + IOCTL_IN(arg, data); + awacs_burgundy_write_volume(MASK_ADDR_BURGUNDY_VOLCD, data); + /* fall through */ + case SOUND_MIXER_READ_CD: + data = awacs_burgundy_read_volume(MASK_ADDR_BURGUNDY_VOLCD); + rc = IOCTL_OUT(arg, data); + break; + case SOUND_MIXER_WRITE_RECLEV: + IOCTL_IN(arg, data); + data = awacs_volume_setter(data, 0, 0, 4); + rc = IOCTL_OUT(arg, data); + break; + case SOUND_MIXER_READ_RECLEV: + data = awacs_get_volume(awacs_reg[0], 4); + rc = IOCTL_OUT(arg, data); + break; + case SOUND_MIXER_OUTMASK: + case SOUND_MIXER_OUTSRC: + default: + rc = -EINVAL; + } + + return rc; +} + +static int daca_mixer_ioctl(u_int cmd, u_long arg) +{ + int data; + int rc; + + /* And the DACA's no genius either! */ + + switch(cmd) { + case SOUND_MIXER_READ_DEVMASK: + data = SOUND_MASK_VOLUME; + rc = IOCTL_OUT(arg, data); + break; + case SOUND_MIXER_READ_RECMASK: + data = 0; + rc = IOCTL_OUT(arg, data); + break; + case SOUND_MIXER_READ_RECSRC: + data = 0; + rc = IOCTL_OUT(arg, data); + break; + case SOUND_MIXER_WRITE_RECSRC: + IOCTL_IN(arg, data); + data =0; + rc = IOCTL_OUT(arg, data); + break; + case SOUND_MIXER_READ_STEREODEVS: + data = SOUND_MASK_VOLUME; + rc = IOCTL_OUT(arg, data); + break; + case SOUND_MIXER_READ_CAPS: + rc = IOCTL_OUT(arg, 0); + break; + case SOUND_MIXER_WRITE_VOLUME: + IOCTL_IN(arg, data); + daca_set_volume(data, data); + /* Fall through */ + case SOUND_MIXER_READ_VOLUME: + daca_get_volume(& data, &data); + rc = IOCTL_OUT(arg, data); + break; + case SOUND_MIXER_OUTMASK: + case SOUND_MIXER_OUTSRC: + default: + rc = -EINVAL; + } + return rc; +} + +static int PMacMixerIoctl(u_int cmd, u_long arg) +{ + int rc; + + /* Different IOCTLS for burgundy and, eventually, DACA & Tumbler */ + + TRY_LOCK(); + + switch (awacs_revision){ + case AWACS_BURGUNDY: + rc = burgundy_mixer_ioctl(cmd, arg); + break ; + case AWACS_DACA: + rc = daca_mixer_ioctl(cmd, arg); + break; + case AWACS_TUMBLER: + case AWACS_SNAPPER: + rc = tas_mixer_ioctl(cmd, arg); + break ; + default: /* ;-)) */ + rc = awacs_mixer_ioctl(cmd, arg); + } + + UNLOCK(); + + return rc; +} + +static void PMacMixerInit(void) +{ + switch (awacs_revision) { + case AWACS_TUMBLER: + printk("AE-Init tumbler mixer\n"); + break ; + case AWACS_SNAPPER: + printk("AE-Init snapper mixer\n"); + break ; + case AWACS_DACA: + case AWACS_BURGUNDY: + break ; /* don't know yet */ + case AWACS_AWACS: + case AWACS_SCREAMER: + default: + awacs_mixer_init() ; + break ; + } +} + +/* Write/Read sq setup functions: + Check to see if we have enough (or any) dbdma cmd buffers for the + user's fragment settings. If not, allocate some. If this fails we will + point at the beep buffer - as an emergency provision - to stop dma tromping + on some random bit of memory (if someone lets it go anyway). + The command buffers are then set up to point to the fragment buffers + (allocated elsewhere). We need n+1 commands the last of which holds + a NOP + loop to start. +*/ + +static int PMacWriteSqSetup(void) +{ + int i, count = 600 ; + volatile struct dbdma_cmd *cp; + + LOCK(); + + /* stop the controller from doing any output - if it isn't already. + it _should_ be before this is called anyway */ + + out_le32(&awacs_txdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16); + while ((in_le32(&awacs_txdma->status) & RUN) && count--) + udelay(1); +#ifdef DEBUG_DMASOUND +if (count <= 0) + printk("dmasound_pmac: write sq setup: timeout waiting for dma to stop\n"); +#endif + + if ((write_sq.max_count + 1) > number_of_tx_cmd_buffers) { + kfree(awacs_tx_cmd_space); + number_of_tx_cmd_buffers = 0; + + /* we need nbufs + 1 (for the loop) and we should request + 1 + again because the DBDMA_ALIGN might pull the start up by up + to sizeof(struct dbdma_cmd) - 4. + */ + + awacs_tx_cmd_space = kmalloc + ((write_sq.max_count + 1 + 1) * sizeof(struct dbdma_cmd), + GFP_KERNEL); + if (awacs_tx_cmd_space == NULL) { + /* don't leave it dangling - nasty but better than a + random address */ + out_le32(&awacs_txdma->cmdptr, virt_to_bus(beep_dbdma_cmd)); + printk(KERN_ERR + "dmasound_pmac: can't allocate dbdma cmd buffers" + ", driver disabled\n"); + UNLOCK(); + return -ENOMEM; + } + awacs_tx_cmds = (volatile struct dbdma_cmd *) + DBDMA_ALIGN(awacs_tx_cmd_space); + number_of_tx_cmd_buffers = write_sq.max_count + 1; + } + + cp = awacs_tx_cmds; + memset((void *)cp, 0, (write_sq.max_count+1) * sizeof(struct dbdma_cmd)); + for (i = 0; i < write_sq.max_count; ++i, ++cp) { + st_le32(&cp->phy_addr, virt_to_bus(write_sq.buffers[i])); + } + st_le16(&cp->command, DBDMA_NOP + BR_ALWAYS); + st_le32(&cp->cmd_dep, virt_to_bus(awacs_tx_cmds)); + /* point the controller at the command stack - ready to go */ + out_le32(&awacs_txdma->cmdptr, virt_to_bus(awacs_tx_cmds)); + UNLOCK(); + return 0; +} + +static int PMacReadSqSetup(void) +{ + int i, count = 600; + volatile struct dbdma_cmd *cp; + + LOCK(); + + /* stop the controller from doing any input - if it isn't already. + it _should_ be before this is called anyway */ + + out_le32(&awacs_rxdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16); + while ((in_le32(&awacs_rxdma->status) & RUN) && count--) + udelay(1); +#ifdef DEBUG_DMASOUND +if (count <= 0) + printk("dmasound_pmac: read sq setup: timeout waiting for dma to stop\n"); +#endif + + if ((read_sq.max_count+1) > number_of_rx_cmd_buffers ) { + kfree(awacs_rx_cmd_space); + number_of_rx_cmd_buffers = 0; + + /* we need nbufs + 1 (for the loop) and we should request + 1 again + because the DBDMA_ALIGN might pull the start up by up to + sizeof(struct dbdma_cmd) - 4 (assuming kmalloc aligns 32 bits). + */ + + awacs_rx_cmd_space = kmalloc + ((read_sq.max_count + 1 + 1) * sizeof(struct dbdma_cmd), + GFP_KERNEL); + if (awacs_rx_cmd_space == NULL) { + /* don't leave it dangling - nasty but better than a + random address */ + out_le32(&awacs_rxdma->cmdptr, virt_to_bus(beep_dbdma_cmd)); + printk(KERN_ERR + "dmasound_pmac: can't allocate dbdma cmd buffers" + ", driver disabled\n"); + UNLOCK(); + return -ENOMEM; + } + awacs_rx_cmds = (volatile struct dbdma_cmd *) + DBDMA_ALIGN(awacs_rx_cmd_space); + number_of_rx_cmd_buffers = read_sq.max_count + 1 ; + } + cp = awacs_rx_cmds; + memset((void *)cp, 0, (read_sq.max_count+1) * sizeof(struct dbdma_cmd)); + + /* Set dma buffers up in a loop */ + for (i = 0; i < read_sq.max_count; i++,cp++) { + st_le32(&cp->phy_addr, virt_to_bus(read_sq.buffers[i])); + st_le16(&cp->command, INPUT_MORE + INTR_ALWAYS); + st_le16(&cp->req_count, read_sq.block_size); + st_le16(&cp->xfer_status, 0); + } + + /* The next two lines make the thing loop around. + */ + st_le16(&cp->command, DBDMA_NOP + BR_ALWAYS); + st_le32(&cp->cmd_dep, virt_to_bus(awacs_rx_cmds)); + /* point the controller at the command stack - ready to go */ + out_le32(&awacs_rxdma->cmdptr, virt_to_bus(awacs_rx_cmds)); + + UNLOCK(); + return 0; +} + +/* TODO: this needs work to guarantee that when it returns DMA has stopped + but in a more elegant way than is done here.... +*/ + +static void PMacAbortRead(void) +{ + int i; + volatile struct dbdma_cmd *cp; + + LOCK(); + /* give it a chance to update the output and provide the IRQ + that is expected. + */ + + out_le32(&awacs_rxdma->control, ((FLUSH) << 16) + FLUSH ); + + cp = awacs_rx_cmds; + for (i = 0; i < read_sq.max_count; i++,cp++) + st_le16(&cp->command, DBDMA_STOP); + /* + * We should probably wait for the thing to stop before we + * release the memory. + */ + + msleep(100) ; /* give it a (small) chance to act */ + + /* apply the sledgehammer approach - just stop it now */ + + out_le32(&awacs_rxdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16); + UNLOCK(); +} + +extern char *get_afmt_string(int); +static int PMacStateInfo(char *b, size_t sp) +{ + int i, len = 0; + len = sprintf(b,"HW rates: "); + switch (awacs_revision){ + case AWACS_DACA: + case AWACS_BURGUNDY: + len += sprintf(b,"44100 ") ; + break ; + case AWACS_TUMBLER: + case AWACS_SNAPPER: + for (i=0; i<1; i++){ + if (tas_freqs_ok[i]) + len += sprintf(b+len,"%d ", tas_freqs[i]) ; + } + break ; + case AWACS_AWACS: + case AWACS_SCREAMER: + default: + for (i=0; i<8; i++){ + if (awacs_freqs_ok[i]) + len += sprintf(b+len,"%d ", awacs_freqs[i]) ; + } + break ; + } + len += sprintf(b+len,"s/sec\n") ; + if (len < sp) { + len += sprintf(b+len,"HW AFMTS: "); + i = AFMT_U16_BE ; + while (i) { + if (i & dmasound.mach.hardware_afmts) + len += sprintf(b+len,"%s ", + get_afmt_string(i & dmasound.mach.hardware_afmts)); + i >>= 1 ; + } + len += sprintf(b+len,"\n") ; + } + return len ; +} + +/*** Machine definitions *****************************************************/ + +static SETTINGS def_hard = { + .format = AFMT_S16_BE, + .stereo = 1, + .size = 16, + .speed = 44100 +} ; + +static SETTINGS def_soft = { + .format = AFMT_S16_BE, + .stereo = 1, + .size = 16, + .speed = 44100 +} ; + +static MACHINE machPMac = { + .name = awacs_name, + .name2 = "PowerMac Built-in Sound", + .owner = THIS_MODULE, + .dma_alloc = PMacAlloc, + .dma_free = PMacFree, + .irqinit = PMacIrqInit, +#ifdef MODULE + .irqcleanup = PMacIrqCleanup, +#endif /* MODULE */ + .init = PMacInit, + .silence = PMacSilence, + .setFormat = PMacSetFormat, + .setVolume = PMacSetVolume, + .play = PMacPlay, + .record = NULL, /* default to no record */ + .mixer_init = PMacMixerInit, + .mixer_ioctl = PMacMixerIoctl, + .write_sq_setup = PMacWriteSqSetup, + .read_sq_setup = PMacReadSqSetup, + .state_info = PMacStateInfo, + .abort_read = PMacAbortRead, + .min_dsp_speed = 7350, + .max_dsp_speed = 44100, + .version = ((DMASOUND_AWACS_REVISION<<8) + DMASOUND_AWACS_EDITION) +}; + + +/*** Config & Setup **********************************************************/ + +/* Check for pmac models that we care about in terms of special actions. +*/ + +void __init +set_model(void) +{ + /* portables/lap-tops */ + + if (machine_is_compatible("AAPL,3400/2400") || + machine_is_compatible("AAPL,3500")) { + is_pbook_3X00 = 1 ; + } + if (machine_is_compatible("PowerBook1,1") || /* lombard */ + machine_is_compatible("AAPL,PowerBook1998")){ /* wallstreet */ + is_pbook_g3 = 1 ; + return ; + } +} + +/* Get the OF node that tells us about the registers, interrupts etc. to use + for sound IO. + + On most machines the sound IO OF node is the 'davbus' node. On newer pmacs + with DACA (& Tumbler) the node to use is i2s-a. On much older machines i.e. + before 9500 there is no davbus node and we have to use the 'awacs' property. + + In the latter case we signal this by setting the codec value - so that the + code that looks for chip properties knows how to go about it. +*/ + +static struct device_node* __init +get_snd_io_node(void) +{ + struct device_node *np; + + /* set up awacs_node for early OF which doesn't have a full set of + * properties on davbus + */ + awacs_node = of_find_node_by_name(NULL, "awacs"); + if (awacs_node) + awacs_revision = AWACS_AWACS; + + /* powermac models after 9500 (other than those which use DACA or + * Tumbler) have a node called "davbus". + */ + np = of_find_node_by_name(NULL, "davbus"); + /* + * if we didn't find a davbus device, try 'i2s-a' since + * this seems to be what iBooks (& Tumbler) have. + */ + if (np == NULL) { + i2s_node = of_find_node_by_name(NULL, "i2s-a"); + np = of_node_get(i2s_node); + } + + /* if we didn't find this - perhaps we are on an early model + * which _only_ has an 'awacs' node + */ + if (np == NULL && awacs_node) + np = of_node_get(awacs_node); + + /* if we failed all these return null - this will cause the + * driver to give up... + */ + return np ; +} + +/* Get the OF node that contains the info about the sound chip, inputs s-rates + etc. + This node does not exist (or contains much reduced info) on earlier machines + we have to deduce the info other ways for these. +*/ + +static struct device_node* __init +get_snd_info_node(struct device_node *io) +{ + struct device_node *info; + + for_each_node_by_name(info, "sound") + if (info->parent == io) + break; + return info; +} + +/* Find out what type of codec we have. +*/ + +static int __init +get_codec_type(struct device_node *info) +{ + /* already set if pre-davbus model and info will be NULL */ + int codec = awacs_revision ; + + if (info) { + /* must do awacs first to allow screamer to overide it */ + if (of_device_is_compatible(info, "awacs")) + codec = AWACS_AWACS ; + if (of_device_is_compatible(info, "screamer")) + codec = AWACS_SCREAMER; + if (of_device_is_compatible(info, "burgundy")) + codec = AWACS_BURGUNDY ; + if (of_device_is_compatible(info, "daca")) + codec = AWACS_DACA; + if (of_device_is_compatible(info, "tumbler")) + codec = AWACS_TUMBLER; + if (of_device_is_compatible(info, "snapper")) + codec = AWACS_SNAPPER; + } + return codec ; +} + +/* find out what type, if any, of expansion card we have +*/ +static void __init +get_expansion_type(void) +{ + struct device_node *dn; + + dn = of_find_node_by_name(NULL, "perch"); + if (dn != NULL) + has_perch = 1; + of_node_put(dn); + + dn = of_find_node_by_name(NULL, "pb-ziva-pc"); + if (dn != NULL) + has_ziva = 1; + of_node_put(dn); + /* need to work out how we deal with iMac SRS module */ +} + +/* set up frame rates. + * I suspect that these routines don't quite go about it the right way: + * - where there is more than one rate - I think that the first property + * value is the number of rates. + * TODO: check some more device trees and modify accordingly + * Set dmasound.mach.max_dsp_rate on the basis of these routines. +*/ + +static void __init +awacs_init_frame_rates(const unsigned int *prop, unsigned int l) +{ + int i ; + if (prop) { + for (i=0; i<8; i++) + awacs_freqs_ok[i] = 0 ; + for (l /= sizeof(int); l > 0; --l) { + unsigned int r = *prop++; + /* Apple 'Fixed' format */ + if (r >= 0x10000) + r >>= 16; + for (i = 0; i < 8; ++i) { + if (r == awacs_freqs[i]) { + awacs_freqs_ok[i] = 1; + break; + } + } + } + } + /* else we assume that all the rates are available */ +} + +static void __init +burgundy_init_frame_rates(const unsigned int *prop, unsigned int l) +{ + int temp[9] ; + int i = 0 ; + if (prop) { + for (l /= sizeof(int); l > 0; --l) { + unsigned int r = *prop++; + /* Apple 'Fixed' format */ + if (r >= 0x10000) + r >>= 16; + temp[i] = r ; + i++ ; if(i>=9) i=8; + } + } +#ifdef DEBUG_DMASOUND +if (i > 1){ + int j; + printk("dmasound_pmac: burgundy with multiple frame rates\n"); + for(j=0; j 0; --l) { + unsigned int r = *prop++; + /* Apple 'Fixed' format */ + if (r >= 0x10000) + r >>= 16; + temp[i] = r ; + i++ ; if(i>=9) i=8; + + } + } +#ifdef DEBUG_DMASOUND +if (i > 1){ + int j; + printk("dmasound_pmac: DACA with multiple frame rates\n"); + for(j=0; jparent; mio ; mio = mio->parent) { + if (strcmp(mio->name, "mac-io") == 0) { + if (of_device_is_compatible(mio, "Keylargo")) + kl = 1; + break; + } + } + hw_can_byteswap = !kl; +} + +/* Allocate the resources necessary for beep generation. This cannot be (quite) + done statically (yet) because we cannot do virt_to_bus() on static vars when + the code is loaded as a module. + + for the sake of saving the possibility that two allocations will incur the + overhead of two pull-ups in DBDMA_ALIGN() we allocate the 'emergency' dmdma + command here as well... even tho' it is not part of the beep process. +*/ + +int32_t +__init setup_beep(void) +{ + /* Initialize beep stuff */ + /* want one cmd buffer for beeps, and a second one for emergencies + - i.e. dbdma error conditions. + ask for three to allow for pull up in DBDMA_ALIGN(). + */ + beep_dbdma_cmd_space = + kmalloc((2 + 1) * sizeof(struct dbdma_cmd), GFP_KERNEL); + if(beep_dbdma_cmd_space == NULL) { + printk(KERN_ERR "dmasound_pmac: no beep dbdma cmd space\n") ; + return -ENOMEM ; + } + beep_dbdma_cmd = (volatile struct dbdma_cmd *) + DBDMA_ALIGN(beep_dbdma_cmd_space); + /* set up emergency dbdma cmd */ + emergency_dbdma_cmd = beep_dbdma_cmd+1 ; + beep_buf = kmalloc(BEEP_BUFLEN * 4, GFP_KERNEL); + if (beep_buf == NULL) { + printk(KERN_ERR "dmasound_pmac: no memory for beep buffer\n"); + kfree(beep_dbdma_cmd_space) ; + return -ENOMEM ; + } + return 0 ; +} + +static struct input_dev *awacs_beep_dev; + +int __init dmasound_awacs_init(void) +{ + struct device_node *io = NULL, *info = NULL; + int vol, res; + + if (!machine_is(powermac)) + return -ENODEV; + + awacs_subframe = 0; + awacs_revision = 0; + hw_can_byteswap = 1 ; /* most can */ + + /* look for models we need to handle specially */ + set_model() ; + + /* find the OF node that tells us about the dbdma stuff + */ + io = get_snd_io_node(); + if (io == NULL) { +#ifdef DEBUG_DMASOUND +printk("dmasound_pmac: couldn't find sound io OF node\n"); +#endif + goto no_device; + } + + /* find the OF node that tells us about the sound sub-system + * this doesn't exist on pre-davbus machines (earlier than 9500) + */ + if (awacs_revision != AWACS_AWACS) { /* set for pre-davbus */ + info = get_snd_info_node(io) ; + if (info == NULL){ +#ifdef DEBUG_DMASOUND +printk("dmasound_pmac: couldn't find 'sound' OF node\n"); +#endif + goto no_device; + } + } + + awacs_revision = get_codec_type(info) ; + if (awacs_revision == 0) { +#ifdef DEBUG_DMASOUND +printk("dmasound_pmac: couldn't find a Codec we can handle\n"); +#endif + goto no_device; /* we don't know this type of h/w */ + } + + /* set up perch, ziva, SRS or whatever else we have as sound + * expansion. + */ + get_expansion_type(); + + /* we've now got enough information to make up the audio topology. + * we will map the sound part of mac-io now so that we can probe for + * other info if necessary (early AWACS we want to read chip ids) + */ + + if (of_get_address(io, 2, NULL, NULL) == NULL) { + /* OK - maybe we need to use the 'awacs' node (on earlier + * machines). + */ + if (awacs_node) { + of_node_put(io); + io = of_node_get(awacs_node); + if (of_get_address(io, 2, NULL, NULL) == NULL) { + printk("dmasound_pmac: can't use %s\n", + io->full_name); + goto no_device; + } + } else + printk("dmasound_pmac: can't use %s\n", io->full_name); + } + + if (of_address_to_resource(io, 0, &awacs_rsrc[0]) || + request_mem_region(awacs_rsrc[0].start, + awacs_rsrc[0].end - awacs_rsrc[0].start + 1, + " (IO)") == NULL) { + printk(KERN_ERR "dmasound: can't request IO resource !\n"); + goto no_device; + } + if (of_address_to_resource(io, 1, &awacs_rsrc[1]) || + request_mem_region(awacs_rsrc[1].start, + awacs_rsrc[1].end - awacs_rsrc[1].start + 1, + " (tx dma)") == NULL) { + release_mem_region(awacs_rsrc[0].start, + awacs_rsrc[0].end - awacs_rsrc[0].start + 1); + printk(KERN_ERR "dmasound: can't request Tx DMA resource !\n"); + goto no_device; + } + if (of_address_to_resource(io, 2, &awacs_rsrc[2]) || + request_mem_region(awacs_rsrc[2].start, + awacs_rsrc[2].end - awacs_rsrc[2].start + 1, + " (rx dma)") == NULL) { + release_mem_region(awacs_rsrc[0].start, + awacs_rsrc[0].end - awacs_rsrc[0].start + 1); + release_mem_region(awacs_rsrc[1].start, + awacs_rsrc[1].end - awacs_rsrc[1].start + 1); + printk(KERN_ERR "dmasound: can't request Rx DMA resource !\n"); + goto no_device; + } + + awacs_beep_dev = input_allocate_device(); + if (!awacs_beep_dev) { + release_mem_region(awacs_rsrc[0].start, + awacs_rsrc[0].end - awacs_rsrc[0].start + 1); + release_mem_region(awacs_rsrc[1].start, + awacs_rsrc[1].end - awacs_rsrc[1].start + 1); + release_mem_region(awacs_rsrc[2].start, + awacs_rsrc[2].end - awacs_rsrc[2].start + 1); + printk(KERN_ERR "dmasound: can't allocate input device !\n"); + goto no_device; + } + + awacs_beep_dev->name = "dmasound beeper"; + awacs_beep_dev->phys = "macio/input0"; + awacs_beep_dev->id.bustype = BUS_HOST; + awacs_beep_dev->event = awacs_beep_event; + awacs_beep_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); + awacs_beep_dev->evbit[0] = BIT(EV_SND); + + /* all OF versions I've seen use this value */ + if (i2s_node) + i2s = ioremap(awacs_rsrc[0].start, 0x1000); + else + awacs = ioremap(awacs_rsrc[0].start, 0x1000); + awacs_txdma = ioremap(awacs_rsrc[1].start, 0x100); + awacs_rxdma = ioremap(awacs_rsrc[2].start, 0x100); + + /* first of all make sure that the chip is powered up....*/ + pmac_call_feature(PMAC_FTR_SOUND_CHIP_ENABLE, io, 0, 1); + if (awacs_revision == AWACS_SCREAMER && awacs) + awacs_recalibrate(); + + awacs_irq = irq_of_parse_and_map(io, 0); + awacs_tx_irq = irq_of_parse_and_map(io, 1); + awacs_rx_irq = irq_of_parse_and_map(io, 2); + + /* Hack for legacy crap that will be killed someday */ + of_node_put(awacs_node); + awacs_node = of_node_get(io); + + /* if we have an awacs or screamer - probe the chip to make + * sure we have the right revision. + */ + + if (awacs_revision <= AWACS_SCREAMER){ + uint32_t temp, rev, mfg ; + /* find out the awacs revision from the chip */ + temp = in_le32(&awacs->codec_stat); + rev = (temp >> 12) & 0xf; + mfg = (temp >> 8) & 0xf; +#ifdef DEBUG_DMASOUND +printk("dmasound_pmac: Awacs/Screamer Codec Mfct: %d Rev %d\n", mfg, rev); +#endif + if (rev >= AWACS_SCREAMER) + awacs_revision = AWACS_SCREAMER ; + else + awacs_revision = rev ; + } + + dmasound.mach = machPMac; + + /* find out other bits & pieces from OF, these may be present + only on some models ... so be careful. + */ + + /* in the absence of a frame rates property we will use the defaults + */ + + if (info) { + const unsigned int *prop; + unsigned int l; + + sound_device_id = 0; + /* device ID appears post g3 b&w */ + prop = of_get_property(info, "device-id", NULL); + if (prop != 0) + sound_device_id = *prop; + + /* look for a property saying what sample rates + are available */ + + prop = of_get_property(info, "sample-rates", &l); + if (prop == 0) + prop = of_get_property(info, "output-frame-rates", &l); + + /* if it's there use it to set up frame rates */ + init_frame_rates(prop, l) ; + of_node_put(info); + info = NULL; + } + + if (awacs) + out_le32(&awacs->control, 0x11); /* set everything quiesent */ + + set_hw_byteswap(io) ; /* figure out if the h/w can do it */ + +#ifdef CONFIG_NVRAM + /* get default volume from nvram */ + vol = ((pmac_xpram_read( 8 ) & 7 ) << 1 ); +#else + vol = 0; +#endif + + /* set up tracking values */ + spk_vol = vol * 100 ; + spk_vol /= 7 ; /* get set value to a percentage */ + spk_vol |= (spk_vol << 8) ; /* equal left & right */ + line_vol = passthru_vol = spk_vol ; + + /* fill regs that are shared between AWACS & Burgundy */ + + awacs_reg[2] = vol + (vol << 6); + awacs_reg[4] = vol + (vol << 6); + awacs_reg[5] = vol + (vol << 6); /* screamer has loopthru vol control */ + awacs_reg[6] = 0; /* maybe should be vol << 3 for PCMCIA speaker */ + awacs_reg[7] = 0; + + awacs_reg[0] = MASK_MUX_CD; + awacs_reg[1] = MASK_LOOPTHRU; + + /* FIXME: Only machines with external SRS module need MASK_PAROUT */ + if (has_perch || sound_device_id == 0x5 + || /*sound_device_id == 0x8 ||*/ sound_device_id == 0xb) + awacs_reg[1] |= MASK_PAROUT0 | MASK_PAROUT1; + + switch (awacs_revision) { + case AWACS_TUMBLER: + tas_register_driver(&tas3001c_hooks); + tas_init(I2C_DRIVERID_TAS3001C, I2C_DRIVERNAME_TAS3001C); + tas_dmasound_init(); + tas_post_init(); + break ; + case AWACS_SNAPPER: + tas_register_driver(&tas3004_hooks); + tas_init(I2C_DRIVERID_TAS3004,I2C_DRIVERNAME_TAS3004); + tas_dmasound_init(); + tas_post_init(); + break; + case AWACS_DACA: + daca_init(); + break; + case AWACS_BURGUNDY: + awacs_burgundy_init(); + break ; + case AWACS_SCREAMER: + case AWACS_AWACS: + default: + load_awacs(); + break ; + } + + /* enable/set-up external modules - when we know how */ + + if (has_perch) + awacs_enable_amp(100 * 0x101); + + /* Reset dbdma channels */ + out_le32(&awacs_txdma->control, (RUN|PAUSE|FLUSH|WAKE|DEAD) << 16); + while (in_le32(&awacs_txdma->status) & RUN) + udelay(1); + out_le32(&awacs_rxdma->control, (RUN|PAUSE|FLUSH|WAKE|DEAD) << 16); + while (in_le32(&awacs_rxdma->status) & RUN) + udelay(1); + + /* Initialize beep stuff */ + if ((res=setup_beep())) + return res ; + +#ifdef CONFIG_PM + pmu_register_sleep_notifier(&awacs_sleep_notifier); +#endif /* CONFIG_PM */ + + /* Powerbooks have odd ways of enabling inputs such as + an expansion-bay CD or sound from an internal modem + or a PC-card modem. */ + if (is_pbook_3X00) { + /* + * Enable CD and PC-card sound inputs. + * This is done by reading from address + * f301a000, + 0x10 to enable the expansion-bay + * CD sound input, + 0x80 to enable the PC-card + * sound input. The 0x100 enables the SCSI bus + * terminator power. + */ + latch_base = ioremap (0xf301a000, 0x1000); + in_8(latch_base + 0x190); + + } else if (is_pbook_g3) { + struct device_node* mio; + macio_base = NULL; + for (mio = io->parent; mio; mio = mio->parent) { + if (strcmp(mio->name, "mac-io") == 0) { + struct resource r; + if (of_address_to_resource(mio, 0, &r) == 0) + macio_base = ioremap(r.start, 0x40); + break; + } + } + /* + * Enable CD sound input. + * The relevant bits for writing to this byte are 0x8f. + * I haven't found out what the 0x80 bit does. + * For the 0xf bits, writing 3 or 7 enables the CD + * input, any other value disables it. Values + * 1, 3, 5, 7 enable the microphone. Values 0, 2, + * 4, 6, 8 - f enable the input from the modem. + * -- paulus. + */ + if (macio_base) + out_8(macio_base + 0x37, 3); + } + + if (hw_can_byteswap) + dmasound.mach.hardware_afmts = (AFMT_S16_BE | AFMT_S16_LE) ; + else + dmasound.mach.hardware_afmts = AFMT_S16_BE ; + + /* shut out chips that do output only. + * may need to extend this to machines which have no inputs - even tho' + * they use screamer - IIRC one of the powerbooks is like this. + */ + + if (awacs_revision != AWACS_DACA) { + dmasound.mach.capabilities = DSP_CAP_DUPLEX ; + dmasound.mach.record = PMacRecord ; + } + + dmasound.mach.default_hard = def_hard ; + dmasound.mach.default_soft = def_soft ; + + switch (awacs_revision) { + case AWACS_BURGUNDY: + sprintf(awacs_name, "PowerMac Burgundy ") ; + break ; + case AWACS_DACA: + sprintf(awacs_name, "PowerMac DACA ") ; + break ; + case AWACS_TUMBLER: + sprintf(awacs_name, "PowerMac Tumbler ") ; + break ; + case AWACS_SNAPPER: + sprintf(awacs_name, "PowerMac Snapper ") ; + break ; + case AWACS_SCREAMER: + sprintf(awacs_name, "PowerMac Screamer ") ; + break ; + case AWACS_AWACS: + default: + sprintf(awacs_name, "PowerMac AWACS rev %d ", awacs_revision) ; + break ; + } + + /* + * XXX: we should handle errors here, but that would mean + * rewriting the whole init code. later.. + */ + input_register_device(awacs_beep_dev); + + of_node_put(io); + + return dmasound_init(); + +no_device: + of_node_put(info); + of_node_put(awacs_node); + of_node_put(i2s_node); + of_node_put(io); + return -ENODEV ; +} + +static void __exit dmasound_awacs_cleanup(void) +{ + input_unregister_device(awacs_beep_dev); + + switch (awacs_revision) { + case AWACS_TUMBLER: + case AWACS_SNAPPER: + tas_dmasound_cleanup(); + tas_cleanup(); + break ; + case AWACS_DACA: + daca_cleanup(); + break; + } + dmasound_deinit(); + + of_node_put(awacs_node); + of_node_put(i2s_node); +} + +MODULE_DESCRIPTION("PowerMac built-in audio driver."); +MODULE_LICENSE("GPL"); + +module_init(dmasound_awacs_init); +module_exit(dmasound_awacs_cleanup); diff --git a/trunk/sound/oss/dmasound/dmasound_core.c b/trunk/sound/oss/dmasound/dmasound_core.c index a003c0ea9303..f4056a9c371b 100644 --- a/trunk/sound/oss/dmasound/dmasound_core.c +++ b/trunk/sound/oss/dmasound/dmasound_core.c @@ -202,6 +202,13 @@ module_param(numWriteBufs, int, 0); static unsigned int writeBufSize = DEFAULT_BUFF_SIZE ; /* in bytes */ module_param(writeBufSize, int, 0); +#ifdef HAS_RECORD +static unsigned int numReadBufs = DEFAULT_N_BUFFERS; +module_param(numReadBufs, int, 0); +static unsigned int readBufSize = DEFAULT_BUFF_SIZE; /* in bytes */ +module_param(readBufSize, int, 0); +#endif + MODULE_LICENSE("GPL"); #ifdef MODULE @@ -396,6 +403,10 @@ static void mixer_init(void) struct sound_queue dmasound_write_sq; static void sq_reset_output(void) ; +#ifdef HAS_RECORD +struct sound_queue dmasound_read_sq; +static void sq_reset_input(void) ; +#endif static int sq_allocate_buffers(struct sound_queue *sq, int num, int size) { @@ -519,6 +530,12 @@ printk("dmasound_core: invalid frag count (user set %d)\n", sq->user_frags) ; sq->rear = -1; setup_func = dmasound.mach.write_sq_setup; } +#ifdef HAS_RECORD + else { + sq->rear = 0; + setup_func = dmasound.mach.read_sq_setup; + } +#endif if (setup_func) return setup_func(); return 0 ; @@ -655,6 +672,13 @@ static unsigned int sq_poll(struct file *file, struct poll_table_struct *wait) } if (file->f_mode & FMODE_WRITE ) poll_wait(file, &write_sq.action_queue, wait); +#ifdef HAS_RECORD + if (file->f_mode & FMODE_READ) + poll_wait(file, &read_sq.action_queue, wait); + if (file->f_mode & FMODE_READ) + if (read_sq.block_size - read_sq.rear_size > 0) + mask |= POLLIN | POLLRDNORM; +#endif if (file->f_mode & FMODE_WRITE) if (write_sq.count < write_sq.max_active || write_sq.block_size - write_sq.rear_size > 0) mask |= POLLOUT | POLLWRNORM; @@ -662,6 +686,101 @@ static unsigned int sq_poll(struct file *file, struct poll_table_struct *wait) } +#ifdef HAS_RECORD + /* + * Here is how the values are used for reading. + * The value 'active' simply indicates the DMA is running. This is done + * so the driver semantics are DMA starts when the first read is posted. + * The value 'front' indicates the buffer we should next send to the user. + * The value 'rear' indicates the buffer the DMA is currently filling. + * When 'front' == 'rear' the buffer "ring" is empty (we always have an + * empty available). The 'rear_size' is used to track partial offsets + * into the buffer we are currently returning to the user. + + * This level (> [1.5]) doesn't care what strategy the LL driver uses with + * DMA on over-run. It can leave it running (and keep active == 1) or it + * can kill it and set active == 0 in which case this routine will spot + * it and restart the DMA. + */ + +static ssize_t sq_read(struct file *file, char __user *dst, size_t uLeft, + loff_t *ppos) +{ + + ssize_t uRead, bLeft, bUsed, uUsed; + + if (uLeft == 0) + return 0; + + /* cater for the compatibility mode - record compiled in but no LL */ + if (dmasound.mach.record == NULL) + return -EINVAL ; + + /* see comment in sq_write() + */ + + if( shared_resources_initialised == 0) { + dmasound.mach.init() ; + shared_resources_initialised = 1 ; + } + + /* set up the sq if it is not already done. see comments in sq_write(). + */ + + if (read_sq.locked == 0) { + if ((uRead = sq_setup(&read_sq)) < 0) + return uRead ; + } + + uRead = 0; + + /* Move what the user requests, depending upon other options. + */ + while (uLeft > 0) { + + /* we happened to get behind and the LL driver killed DMA + then we should set it going again. This also sets it + going the first time through. + */ + if ( !read_sq.active ) + dmasound.mach.record(); + + /* When front == rear, the DMA is not done yet. + */ + while (read_sq.front == read_sq.rear) { + if (read_sq.open_mode & O_NONBLOCK) { + return uRead > 0 ? uRead : -EAGAIN; + } + SLEEP(read_sq.action_queue); + if (signal_pending(current)) + return uRead > 0 ? uRead : -EINTR; + } + + /* The amount we move is either what is left in the + * current buffer or what the user wants. + */ + bLeft = read_sq.block_size - read_sq.rear_size; + bUsed = read_sq.rear_size; + uUsed = sound_copy_translate(dmasound.trans_read, dst, uLeft, + read_sq.buffers[read_sq.front], + &bUsed, bLeft); + if (uUsed <= 0) + return uUsed; + dst += uUsed; + uRead += uUsed; + uLeft -= uUsed; + read_sq.rear_size += bUsed; + if (read_sq.rear_size >= read_sq.block_size) { + read_sq.rear_size = 0; + read_sq.front++; + if (read_sq.front >= read_sq.max_active) + read_sq.front = 0; + } + } + return uRead; +} +#endif /* HAS_RECORD */ + static inline void sq_init_waitqueue(struct sound_queue *sq) { init_waitqueue_head(&sq->action_queue); @@ -735,6 +854,23 @@ static int sq_open2(struct sound_queue *sq, struct file *file, mode_t mode, #define write_sq_open(file) \ sq_open2(&write_sq, file, FMODE_WRITE, numWriteBufs, writeBufSize ) +#ifdef HAS_RECORD +#define read_sq_init_waitqueue() sq_init_waitqueue(&read_sq) +#if 0 /* blocking open() */ +#define read_sq_wake_up(file) sq_wake_up(&read_sq, file, FMODE_READ) +#endif +#define read_sq_release_buffers() sq_release_buffers(&read_sq) +#define read_sq_open(file) \ + sq_open2(&read_sq, file, FMODE_READ, numReadBufs, readBufSize ) +#else +#define read_sq_init_waitqueue() do {} while (0) +#if 0 /* blocking open() */ +#define read_sq_wake_up(file) do {} while (0) +#endif +#define read_sq_release_buffers() do {} while (0) +#define sq_reset_input() do {} while (0) +#endif + static int sq_open(struct inode *inode, struct file *file) { int rc; @@ -745,11 +881,25 @@ static int sq_open(struct inode *inode, struct file *file) rc = write_sq_open(file); /* checks the f_mode */ if (rc) goto out; +#ifdef HAS_RECORD + if (dmasound.mach.record) { + rc = read_sq_open(file); /* checks the f_mode */ + if (rc) + goto out; + } else { /* no record function installed; in compat mode */ + if (file->f_mode & FMODE_READ) { + /* TODO: if O_RDWR, release any resources grabbed by write part */ + rc = -ENXIO; + goto out; + } + } +#else /* !HAS_RECORD */ if (file->f_mode & FMODE_READ) { /* TODO: if O_RDWR, release any resources grabbed by write part */ rc = -ENXIO ; /* I think this is what is required by open(2) */ goto out; } +#endif /* HAS_RECORD */ if (dmasound.mach.sq_open) dmasound.mach.sq_open(file->f_mode); @@ -806,9 +956,43 @@ static void sq_reset_output(void) write_sq.user_frag_size = 0 ; } +#ifdef HAS_RECORD + +static void sq_reset_input(void) +{ + if (dmasound.mach.record && read_sq.active) { + if (dmasound.mach.abort_read) { /* this routine must really be present */ + read_sq.syncing = 1 ; + /* this can use the read_sq.sync_queue to sleep if + necessary - it should not return until DMA + is really stopped - because we might deallocate + the buffers as the next action... + */ + dmasound.mach.abort_read() ; + } else { + printk(KERN_ERR + "dmasound_core: %s has no abort_read()!! all bets are off\n", + dmasound.mach.name) ; + } + } + read_sq.syncing = + read_sq.active = + read_sq.front = + read_sq.count = + read_sq.rear = 0 ; + + /* OK - we can unlock the parameters and fragment settings */ + read_sq.locked = 0 ; + read_sq.user_frags = 0 ; + read_sq.user_frag_size = 0 ; +} + +#endif + static void sq_reset(void) { sq_reset_output() ; + sq_reset_input() ; /* we could consider resetting the shared_resources_owner here... but I think it is probably still rather non-obvious to application writer */ @@ -854,6 +1038,17 @@ static int sq_release(struct inode *inode, struct file *file) lock_kernel(); +#ifdef HAS_RECORD + /* probably best to do the read side first - so that time taken to do it + overlaps with playing any remaining output samples. + */ + if (file->f_mode & FMODE_READ) { + sq_reset_input() ; /* make sure dma is stopped and all is quiet */ + read_sq_release_buffers(); + read_sq.busy = 0; + } +#endif + if (file->f_mode & FMODE_WRITE) { if (write_sq.busy) rc = sq_fsync(file, file->f_path.dentry); @@ -910,6 +1105,11 @@ static int shared_resources_are_mine(mode_t md) static int queues_are_quiescent(void) { +#ifdef HAS_RECORD + if (dmasound.mach.record) + if (read_sq.locked) + return 0 ; +#endif if (write_sq.locked) return 0 ; return 1 ; @@ -985,6 +1185,13 @@ static int sq_ioctl(struct inode *inode, struct file *file, u_int cmd, the read_sq ones. */ size = 0 ; +#ifdef HAS_RECORD + if (dmasound.mach.record && (file->f_mode & FMODE_READ)) { + if ( !read_sq.locked ) + sq_setup(&read_sq) ; /* set params */ + size = read_sq.user_frag_size ; + } +#endif if (file->f_mode & FMODE_WRITE) { if ( !write_sq.locked ) sq_setup(&write_sq) ; @@ -1007,6 +1214,8 @@ static int sq_ioctl(struct inode *inode, struct file *file, u_int cmd, everything - read, however, is killed imediately. */ result = 0 ; + if ((file->f_mode & FMODE_READ) && dmasound.mach.record) + sq_reset_input() ; if (file->f_mode & FMODE_WRITE) { result = sq_fsync(file, file->f_path.dentry); sq_reset_output() ; @@ -1085,6 +1294,13 @@ static int sq_ioctl(struct inode *inode, struct file *file, u_int cmd, result = 0 ; nbufs = (data >> 16) & 0x7fff ; /* 0x7fff is 'use maximum' */ size = data & 0xffff; +#ifdef HAS_RECORD + if ((file->f_mode & FMODE_READ) && dmasound.mach.record) { + result = set_queue_frags(&read_sq, nbufs, size) ; + if (result) + return result ; + } +#endif if (file->f_mode & FMODE_WRITE) { result = set_queue_frags(&write_sq, nbufs, size) ; if (result) @@ -1132,6 +1348,20 @@ static const struct file_operations sq_fops = .release = sq_release, }; +#ifdef HAS_RECORD +static const struct file_operations sq_fops_record = +{ + .owner = THIS_MODULE, + .llseek = no_llseek, + .write = sq_write, + .poll = sq_poll, + .ioctl = sq_ioctl, + .open = sq_open, + .release = sq_release, + .read = sq_read, +}; +#endif + static int sq_init(void) { const struct file_operations *fops = &sq_fops; @@ -1139,6 +1369,10 @@ static int sq_init(void) int sq_unit; #endif +#ifdef HAS_RECORD + if (dmasound.mach.record) + fops = &sq_fops_record; +#endif sq_unit = register_sound_dsp(fops, -1); if (sq_unit < 0) { printk(KERN_ERR "dmasound_core: couldn't register fops\n") ; @@ -1146,6 +1380,7 @@ static int sq_init(void) } write_sq_init_waitqueue(); + read_sq_init_waitqueue(); /* These parameters will be restored for every clean open() * in the case of multiple open()s (e.g. dsp0 & dsp1) they @@ -1171,7 +1406,11 @@ static int sq_init(void) driver. */ +#ifdef HAS_RECORD +#define STAT_BUFF_LEN 1024 +#else #define STAT_BUFF_LEN 768 +#endif /* this is how much space we will allow the low-level driver to use in the stat buffer. Currently, 2 * (80 character line + ). @@ -1279,6 +1518,11 @@ static int state_open(struct inode *inode, struct file *file) len += sprintf(buffer+len,"Allocated:%8s%6s\n","Buffers","Size") ; len += sprintf(buffer+len,"%9s:%8d%6d\n", "write", write_sq.numBufs, write_sq.bufSize) ; +#ifdef HAS_RECORD + if (dmasound.mach.record) + len += sprintf(buffer+len,"%9s:%8d%6d\n", + "read", read_sq.numBufs, read_sq.bufSize) ; +#endif len += sprintf(buffer+len, "Current : MaxFrg FragSiz MaxAct Frnt Rear " "Cnt RrSize A B S L xruns\n") ; @@ -1287,6 +1531,14 @@ static int state_open(struct inode *inode, struct file *file) write_sq.max_active, write_sq.front, write_sq.rear, write_sq.count, write_sq.rear_size, write_sq.active, write_sq.busy, write_sq.syncing, write_sq.locked, write_sq.xruns) ; +#ifdef HAS_RECORD + if (dmasound.mach.record) + len += sprintf(buffer+len,"%9s:%7d%8d%7d%5d%5d%4d%7d%2d%2d%2d%2d%7d\n", + "read", read_sq.max_count, read_sq.block_size, + read_sq.max_active, read_sq.front, read_sq.rear, + read_sq.count, read_sq.rear_size, read_sq.active, + read_sq.busy, read_sq.syncing, read_sq.locked, read_sq.xruns) ; +#endif #ifdef DEBUG_DMASOUND printk("dmasound: stat buffer used %d bytes\n", len) ; #endif @@ -1386,6 +1638,13 @@ int dmasound_init(void) (dmasound.mach.version >> 8), (dmasound.mach.version & 0xff)) ; printk(KERN_INFO "Write will use %4d fragments of %7d bytes as default\n", numWriteBufs, writeBufSize) ; +#ifdef HAS_RECORD + if (dmasound.mach.record) + printk(KERN_INFO + "Read will use %4d fragments of %7d bytes as default\n", + numReadBufs, readBufSize) ; +#endif + return 0; } @@ -1400,6 +1659,7 @@ void dmasound_deinit(void) } write_sq_release_buffers(); + read_sq_release_buffers(); if (mixer_unit >= 0) unregister_sound_mixer(mixer_unit); @@ -1424,12 +1684,36 @@ static int dmasound_setup(char *str) */ switch (ints[0]) { +#ifdef HAS_RECORD + case 5: + if ((ints[5] < 0) || (ints[5] > MAX_CATCH_RADIUS)) + printk("dmasound_setup: invalid catch radius, using default = %d\n", catchRadius); + else + catchRadius = ints[5]; + /* fall through */ + case 4: + if (ints[4] < MIN_BUFFERS) + printk("dmasound_setup: invalid number of read buffers, using default = %d\n", + numReadBufs); + else + numReadBufs = ints[4]; + /* fall through */ + case 3: + if ((size = ints[3]) < 256) /* check for small buffer specs */ + size <<= 10 ; + if (size < MIN_BUFSIZE || size > MAX_BUFSIZE) + printk("dmasound_setup: invalid read buffer size, using default = %d\n", readBufSize); + else + readBufSize = size; + /* fall through */ +#else case 3: if ((ints[3] < 0) || (ints[3] > MAX_CATCH_RADIUS)) printk("dmasound_setup: invalid catch radius, using default = %d\n", catchRadius); else catchRadius = ints[3]; /* fall through */ +#endif case 2: if (ints[1] < MIN_BUFFERS) printk("dmasound_setup: invalid number of buffers, using default = %d\n", numWriteBufs); @@ -1546,6 +1830,9 @@ EXPORT_SYMBOL(dmasound_init); EXPORT_SYMBOL(dmasound_deinit); #endif EXPORT_SYMBOL(dmasound_write_sq); +#ifdef HAS_RECORD +EXPORT_SYMBOL(dmasound_read_sq); +#endif EXPORT_SYMBOL(dmasound_catchRadius); #ifdef HAS_8BIT_TABLES EXPORT_SYMBOL(dmasound_ulaw2dma8); diff --git a/trunk/sound/oss/dmasound/tas3001c.c b/trunk/sound/oss/dmasound/tas3001c.c new file mode 100644 index 000000000000..4b7dbdd2a438 --- /dev/null +++ b/trunk/sound/oss/dmasound/tas3001c.c @@ -0,0 +1,849 @@ +/* + * Driver for the i2c/i2s based TA3004 sound chip used + * on some Apple hardware. Also known as "snapper". + * + * Tobias Sargeant + * Based upon, tas3001c.c by Christopher C. Chimelis : + * + * TODO: + * ----- + * * Enable control over input line 2 (is this connected?) + * * Implement sleep support (at least mute everything and + * * set gains to minimum during sleep) + * * Look into some of Darwin's tweaks regarding the mute + * * lines (delays & different behaviour on some HW) + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dmasound.h" +#include "tas_common.h" +#include "tas3001c.h" + +#include "tas_ioctl.h" + +#define TAS3001C_BIQUAD_FILTER_COUNT 6 +#define TAS3001C_BIQUAD_CHANNEL_COUNT 2 + +#define VOL_DEFAULT (100 * 4 / 5) +#define INPUT_DEFAULT (100 * 4 / 5) +#define BASS_DEFAULT (100 / 2) +#define TREBLE_DEFAULT (100 / 2) + +struct tas3001c_data_t { + struct tas_data_t super; + int device_id; + int output_id; + int speaker_id; + struct tas_drce_t drce_state; + struct work_struct change; +}; + + +static const union tas_biquad_t +tas3001c_eq_unity={ + .buf = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } +}; + + +static inline unsigned char db_to_regval(short db) { + int r=0; + + r=(db+0x59a0) / 0x60; + + if (r < 0x91) return 0x91; + if (r > 0xef) return 0xef; + return r; +} + +static inline short quantize_db(short db) { + return db_to_regval(db) * 0x60 - 0x59a0; +} + + +static inline int +register_width(enum tas3001c_reg_t r) +{ + switch(r) { + case TAS3001C_REG_MCR: + case TAS3001C_REG_TREBLE: + case TAS3001C_REG_BASS: + return 1; + + case TAS3001C_REG_DRC: + return 2; + + case TAS3001C_REG_MIXER1: + case TAS3001C_REG_MIXER2: + return 3; + + case TAS3001C_REG_VOLUME: + return 6; + + case TAS3001C_REG_LEFT_BIQUAD0: + case TAS3001C_REG_LEFT_BIQUAD1: + case TAS3001C_REG_LEFT_BIQUAD2: + case TAS3001C_REG_LEFT_BIQUAD3: + case TAS3001C_REG_LEFT_BIQUAD4: + case TAS3001C_REG_LEFT_BIQUAD5: + case TAS3001C_REG_LEFT_BIQUAD6: + + case TAS3001C_REG_RIGHT_BIQUAD0: + case TAS3001C_REG_RIGHT_BIQUAD1: + case TAS3001C_REG_RIGHT_BIQUAD2: + case TAS3001C_REG_RIGHT_BIQUAD3: + case TAS3001C_REG_RIGHT_BIQUAD4: + case TAS3001C_REG_RIGHT_BIQUAD5: + case TAS3001C_REG_RIGHT_BIQUAD6: + return 15; + + default: + return 0; + } +} + +static int +tas3001c_write_register( struct tas3001c_data_t *self, + enum tas3001c_reg_t reg_num, + char *data, + uint write_mode) +{ + if (reg_num==TAS3001C_REG_MCR || + reg_num==TAS3001C_REG_BASS || + reg_num==TAS3001C_REG_TREBLE) { + return tas_write_byte_register(&self->super, + (uint)reg_num, + *data, + write_mode); + } else { + return tas_write_register(&self->super, + (uint)reg_num, + register_width(reg_num), + data, + write_mode); + } +} + +static int +tas3001c_sync_register( struct tas3001c_data_t *self, + enum tas3001c_reg_t reg_num) +{ + if (reg_num==TAS3001C_REG_MCR || + reg_num==TAS3001C_REG_BASS || + reg_num==TAS3001C_REG_TREBLE) { + return tas_sync_byte_register(&self->super, + (uint)reg_num, + register_width(reg_num)); + } else { + return tas_sync_register(&self->super, + (uint)reg_num, + register_width(reg_num)); + } +} + +static int +tas3001c_read_register( struct tas3001c_data_t *self, + enum tas3001c_reg_t reg_num, + char *data, + uint write_mode) +{ + return tas_read_register(&self->super, + (uint)reg_num, + register_width(reg_num), + data); +} + +static inline int +tas3001c_fast_load(struct tas3001c_data_t *self, int fast) +{ + if (fast) + self->super.shadow[TAS3001C_REG_MCR][0] |= 0x80; + else + self->super.shadow[TAS3001C_REG_MCR][0] &= 0x7f; + return tas3001c_sync_register(self,TAS3001C_REG_MCR); +} + +static uint +tas3001c_supported_mixers(struct tas3001c_data_t *self) +{ + return SOUND_MASK_VOLUME | + SOUND_MASK_PCM | + SOUND_MASK_ALTPCM | + SOUND_MASK_TREBLE | + SOUND_MASK_BASS; +} + +static int +tas3001c_mixer_is_stereo(struct tas3001c_data_t *self,int mixer) +{ + switch(mixer) { + case SOUND_MIXER_VOLUME: + return 1; + default: + return 0; + } +} + +static uint +tas3001c_stereo_mixers(struct tas3001c_data_t *self) +{ + uint r=tas3001c_supported_mixers(self); + uint i; + + for (i=1; isuper.mixer[mixer]; + + return 0; +} + +static int +tas3001c_set_mixer_level(struct tas3001c_data_t *self,int mixer,uint level) +{ + int rc; + tas_shadow_t *shadow; + + uint temp; + uint offset=0; + + if (!self) + return -1; + + shadow=self->super.shadow; + + if (!tas3001c_mixer_is_stereo(self,mixer)) + level = tas_mono_to_stereo(level); + + switch(mixer) { + case SOUND_MIXER_VOLUME: + temp = tas3001c_gain.master[level&0xff]; + shadow[TAS3001C_REG_VOLUME][0] = (temp >> 16) & 0xff; + shadow[TAS3001C_REG_VOLUME][1] = (temp >> 8) & 0xff; + shadow[TAS3001C_REG_VOLUME][2] = (temp >> 0) & 0xff; + temp = tas3001c_gain.master[(level>>8)&0xff]; + shadow[TAS3001C_REG_VOLUME][3] = (temp >> 16) & 0xff; + shadow[TAS3001C_REG_VOLUME][4] = (temp >> 8) & 0xff; + shadow[TAS3001C_REG_VOLUME][5] = (temp >> 0) & 0xff; + rc = tas3001c_sync_register(self,TAS3001C_REG_VOLUME); + break; + case SOUND_MIXER_ALTPCM: + /* tas3001c_fast_load(self, 1); */ + level = tas_mono_to_stereo(level); + temp = tas3001c_gain.mixer[level&0xff]; + shadow[TAS3001C_REG_MIXER2][offset+0] = (temp >> 16) & 0xff; + shadow[TAS3001C_REG_MIXER2][offset+1] = (temp >> 8) & 0xff; + shadow[TAS3001C_REG_MIXER2][offset+2] = (temp >> 0) & 0xff; + rc = tas3001c_sync_register(self,TAS3001C_REG_MIXER2); + /* tas3001c_fast_load(self, 0); */ + break; + case SOUND_MIXER_PCM: + /* tas3001c_fast_load(self, 1); */ + level = tas_mono_to_stereo(level); + temp = tas3001c_gain.mixer[level&0xff]; + shadow[TAS3001C_REG_MIXER1][offset+0] = (temp >> 16) & 0xff; + shadow[TAS3001C_REG_MIXER1][offset+1] = (temp >> 8) & 0xff; + shadow[TAS3001C_REG_MIXER1][offset+2] = (temp >> 0) & 0xff; + rc = tas3001c_sync_register(self,TAS3001C_REG_MIXER1); + /* tas3001c_fast_load(self, 0); */ + break; + case SOUND_MIXER_TREBLE: + temp = tas3001c_gain.treble[level&0xff]; + shadow[TAS3001C_REG_TREBLE][0]=temp&0xff; + rc = tas3001c_sync_register(self,TAS3001C_REG_TREBLE); + break; + case SOUND_MIXER_BASS: + temp = tas3001c_gain.bass[level&0xff]; + shadow[TAS3001C_REG_BASS][0]=temp&0xff; + rc = tas3001c_sync_register(self,TAS3001C_REG_BASS); + break; + default: + rc = -1; + break; + } + if (rc < 0) + return rc; + self->super.mixer[mixer]=level; + return 0; +} + +static int +tas3001c_leave_sleep(struct tas3001c_data_t *self) +{ + unsigned char mcr = (1<<6)+(2<<4)+(2<<2); + + if (!self) + return -1; + + /* Make sure something answers on the i2c bus */ + if (tas3001c_write_register(self, TAS3001C_REG_MCR, &mcr, + WRITE_NORMAL|FORCE_WRITE) < 0) + return -1; + + tas3001c_fast_load(self, 1); + + (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD0); + (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD1); + (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD2); + (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD3); + (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD4); + (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD5); + + (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD0); + (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD1); + (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD2); + (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD3); + (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD4); + (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD5); + + tas3001c_fast_load(self, 0); + + (void)tas3001c_sync_register(self,TAS3001C_REG_BASS); + (void)tas3001c_sync_register(self,TAS3001C_REG_TREBLE); + (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER1); + (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER2); + (void)tas3001c_sync_register(self,TAS3001C_REG_VOLUME); + + return 0; +} + +static int +tas3001c_enter_sleep(struct tas3001c_data_t *self) +{ + /* Stub for now, but I have the details on low-power mode */ + if (!self) + return -1; + return 0; +} + +static int +tas3001c_sync_biquad( struct tas3001c_data_t *self, + u_int channel, + u_int filter) +{ + enum tas3001c_reg_t reg; + + if (channel >= TAS3001C_BIQUAD_CHANNEL_COUNT || + filter >= TAS3001C_BIQUAD_FILTER_COUNT) return -EINVAL; + + reg=( channel ? TAS3001C_REG_RIGHT_BIQUAD0 : TAS3001C_REG_LEFT_BIQUAD0 ) + filter; + + return tas3001c_sync_register(self,reg); +} + +static int +tas3001c_write_biquad_shadow( struct tas3001c_data_t *self, + u_int channel, + u_int filter, + const union tas_biquad_t *biquad) +{ + tas_shadow_t *shadow=self->super.shadow; + enum tas3001c_reg_t reg; + + if (channel >= TAS3001C_BIQUAD_CHANNEL_COUNT || + filter >= TAS3001C_BIQUAD_FILTER_COUNT) return -EINVAL; + + reg=( channel ? TAS3001C_REG_RIGHT_BIQUAD0 : TAS3001C_REG_LEFT_BIQUAD0 ) + filter; + + SET_4_20(shadow[reg], 0,biquad->coeff.b0); + SET_4_20(shadow[reg], 3,biquad->coeff.b1); + SET_4_20(shadow[reg], 6,biquad->coeff.b2); + SET_4_20(shadow[reg], 9,biquad->coeff.a1); + SET_4_20(shadow[reg],12,biquad->coeff.a2); + + return 0; +} + +static int +tas3001c_write_biquad( struct tas3001c_data_t *self, + u_int channel, + u_int filter, + const union tas_biquad_t *biquad) +{ + int rc; + + rc=tas3001c_write_biquad_shadow(self, channel, filter, biquad); + if (rc < 0) return rc; + + return tas3001c_sync_biquad(self, channel, filter); +} + +static int +tas3001c_write_biquad_list( struct tas3001c_data_t *self, + u_int filter_count, + u_int flags, + struct tas_biquad_ctrl_t *biquads) +{ + int i; + int rc; + + if (flags & TAS_BIQUAD_FAST_LOAD) tas3001c_fast_load(self,1); + + for (i=0; isuper.shadow; + enum tas3001c_reg_t reg; + + if (channel >= TAS3001C_BIQUAD_CHANNEL_COUNT || + filter >= TAS3001C_BIQUAD_FILTER_COUNT) return -EINVAL; + + reg=( channel ? TAS3001C_REG_RIGHT_BIQUAD0 : TAS3001C_REG_LEFT_BIQUAD0 ) + filter; + + biquad->coeff.b0=GET_4_20(shadow[reg], 0); + biquad->coeff.b1=GET_4_20(shadow[reg], 3); + biquad->coeff.b2=GET_4_20(shadow[reg], 6); + biquad->coeff.a1=GET_4_20(shadow[reg], 9); + biquad->coeff.a2=GET_4_20(shadow[reg],12); + + return 0; +} + +static int +tas3001c_eq_rw( struct tas3001c_data_t *self, + u_int cmd, + u_long arg) +{ + int rc; + struct tas_biquad_ctrl_t biquad; + void __user *argp = (void __user *)arg; + + if (copy_from_user(&biquad, argp, sizeof(struct tas_biquad_ctrl_t))) { + return -EFAULT; + } + + if (cmd & SIOC_IN) { + rc=tas3001c_write_biquad(self, biquad.channel, biquad.filter, &biquad.data); + if (rc != 0) return rc; + } + + if (cmd & SIOC_OUT) { + rc=tas3001c_read_biquad(self, biquad.channel, biquad.filter, &biquad.data); + if (rc != 0) return rc; + + if (copy_to_user(argp, &biquad, sizeof(struct tas_biquad_ctrl_t))) { + return -EFAULT; + } + + } + return 0; +} + +static int +tas3001c_eq_list_rw( struct tas3001c_data_t *self, + u_int cmd, + u_long arg) +{ + int rc; + int filter_count; + int flags; + int i,j; + char sync_required[2][6]; + struct tas_biquad_ctrl_t biquad; + struct tas_biquad_ctrl_list_t __user *argp = (void __user *)arg; + + memset(sync_required,0,sizeof(sync_required)); + + if (copy_from_user(&filter_count, &argp->filter_count, sizeof(int))) + return -EFAULT; + + if (copy_from_user(&flags, &argp->flags, sizeof(int))) + return -EFAULT; + + if (cmd & SIOC_IN) { + } + + for (i=0; i < filter_count; i++) { + if (copy_from_user(&biquad, &argp->biquads[i], + sizeof(struct tas_biquad_ctrl_t))) { + return -EFAULT; + } + + if (cmd & SIOC_IN) { + sync_required[biquad.channel][biquad.filter]=1; + rc=tas3001c_write_biquad_shadow(self, biquad.channel, biquad.filter, &biquad.data); + if (rc != 0) return rc; + } + + if (cmd & SIOC_OUT) { + rc=tas3001c_read_biquad(self, biquad.channel, biquad.filter, &biquad.data); + if (rc != 0) return rc; + + if (copy_to_user(&argp->biquads[i], &biquad, + sizeof(struct tas_biquad_ctrl_t))) { + return -EFAULT; + } + } + } + + if (cmd & SIOC_IN) { + if (flags & TAS_BIQUAD_FAST_LOAD) tas3001c_fast_load(self,1); + for (i=0; i<2; i++) { + for (j=0; j<6; j++) { + if (sync_required[i][j]) { + rc=tas3001c_sync_biquad(self, i, j); + if (rc < 0) return rc; + } + } + } + if (flags & TAS_BIQUAD_FAST_LOAD) { + tas3001c_fast_load(self,0); + /* now we need to set up the mixers again, + because leaving fast mode resets them. */ + (void)tas3001c_sync_register(self,TAS3001C_REG_BASS); + (void)tas3001c_sync_register(self,TAS3001C_REG_TREBLE); + (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER1); + (void)tas3001c_sync_register(self,TAS3001C_REG_MIXER2); + (void)tas3001c_sync_register(self,TAS3001C_REG_VOLUME); + } + } + + return 0; +} + +static int +tas3001c_update_drce( struct tas3001c_data_t *self, + int flags, + struct tas_drce_t *drce) +{ + tas_shadow_t *shadow; + shadow=self->super.shadow; + + shadow[TAS3001C_REG_DRC][1] = 0xc1; + + if (flags & TAS_DRCE_THRESHOLD) { + self->drce_state.threshold=quantize_db(drce->threshold); + shadow[TAS3001C_REG_DRC][2] = db_to_regval(self->drce_state.threshold); + } + + if (flags & TAS_DRCE_ENABLE) { + self->drce_state.enable = drce->enable; + } + + if (!self->drce_state.enable) { + shadow[TAS3001C_REG_DRC][0] = 0xf0; + } + +#ifdef DEBUG_DRCE + printk("DRCE IOCTL: set [ ENABLE:%x THRESH:%x\n", + self->drce_state.enable, + self->drce_state.threshold); + + printk("DRCE IOCTL: reg [ %02x %02x ]\n", + (unsigned char)shadow[TAS3001C_REG_DRC][0], + (unsigned char)shadow[TAS3001C_REG_DRC][1]); +#endif + + return tas3001c_sync_register(self, TAS3001C_REG_DRC); +} + +static int +tas3001c_drce_rw( struct tas3001c_data_t *self, + u_int cmd, + u_long arg) +{ + int rc; + struct tas_drce_ctrl_t drce_ctrl; + void __user *argp = (void __user *)arg; + + if (copy_from_user(&drce_ctrl, argp, sizeof(struct tas_drce_ctrl_t))) + return -EFAULT; + +#ifdef DEBUG_DRCE + printk("DRCE IOCTL: input [ FLAGS:%x ENABLE:%x THRESH:%x\n", + drce_ctrl.flags, + drce_ctrl.data.enable, + drce_ctrl.data.threshold); +#endif + + if (cmd & SIOC_IN) { + rc = tas3001c_update_drce(self, drce_ctrl.flags, &drce_ctrl.data); + if (rc < 0) + return rc; + } + + if (cmd & SIOC_OUT) { + if (drce_ctrl.flags & TAS_DRCE_ENABLE) + drce_ctrl.data.enable = self->drce_state.enable; + + if (drce_ctrl.flags & TAS_DRCE_THRESHOLD) + drce_ctrl.data.threshold = self->drce_state.threshold; + + if (copy_to_user(argp, &drce_ctrl, + sizeof(struct tas_drce_ctrl_t))) { + return -EFAULT; + } + } + + return 0; +} + +static void +tas3001c_update_device_parameters(struct tas3001c_data_t *self) +{ + int i,j; + + if (!self) return; + + if (self->output_id == TAS_OUTPUT_HEADPHONES) { + tas3001c_fast_load(self, 1); + + for (i=0; idevice_id == self->device_id && + (eq->output_id == 0 || eq->output_id == self->output_id) && + (eq->speaker_id == 0 || eq->speaker_id == self->speaker_id)) { + + tas3001c_update_drce(self, TAS_DRCE_ALL, eq->drce); + tas3001c_write_biquad_list(self, eq->filter_count, TAS_BIQUAD_FAST_LOAD, eq->biquads); + + break; + } + } +} + +static void +tas3001c_device_change_handler(struct work_struct *work) +{ + struct tas3001c_data_t *self; + self = container_of(work, struct tas3001c_data_t, change); + tas3001c_update_device_parameters(self); +} + +static int +tas3001c_output_device_change( struct tas3001c_data_t *self, + int device_id, + int output_id, + int speaker_id) +{ + self->device_id=device_id; + self->output_id=output_id; + self->speaker_id=speaker_id; + + schedule_work(&self->change); + return 0; +} + +static int +tas3001c_device_ioctl( struct tas3001c_data_t *self, + u_int cmd, + u_long arg) +{ + uint __user *argp = (void __user *)arg; + switch (cmd) { + case TAS_READ_EQ: + case TAS_WRITE_EQ: + return tas3001c_eq_rw(self, cmd, arg); + + case TAS_READ_EQ_LIST: + case TAS_WRITE_EQ_LIST: + return tas3001c_eq_list_rw(self, cmd, arg); + + case TAS_READ_EQ_FILTER_COUNT: + put_user(TAS3001C_BIQUAD_FILTER_COUNT, argp); + return 0; + + case TAS_READ_EQ_CHANNEL_COUNT: + put_user(TAS3001C_BIQUAD_CHANNEL_COUNT, argp); + return 0; + + case TAS_READ_DRCE: + case TAS_WRITE_DRCE: + return tas3001c_drce_rw(self, cmd, arg); + + case TAS_READ_DRCE_CAPS: + put_user(TAS_DRCE_ENABLE | TAS_DRCE_THRESHOLD, argp); + return 0; + + case TAS_READ_DRCE_MIN: + case TAS_READ_DRCE_MAX: { + struct tas_drce_ctrl_t drce_ctrl; + + if (copy_from_user(&drce_ctrl, argp, + sizeof(struct tas_drce_ctrl_t))) { + return -EFAULT; + } + + if (drce_ctrl.flags & TAS_DRCE_THRESHOLD) { + if (cmd == TAS_READ_DRCE_MIN) { + drce_ctrl.data.threshold=-36<<8; + } else { + drce_ctrl.data.threshold=-6<<8; + } + } + + if (copy_to_user(argp, &drce_ctrl, + sizeof(struct tas_drce_ctrl_t))) { + return -EFAULT; + } + } + } + + return -EINVAL; +} + +static int +tas3001c_init_mixer(struct tas3001c_data_t *self) +{ + unsigned char mcr = (1<<6)+(2<<4)+(2<<2); + + /* Make sure something answers on the i2c bus */ + if (tas3001c_write_register(self, TAS3001C_REG_MCR, &mcr, + WRITE_NORMAL|FORCE_WRITE) < 0) + return -1; + + tas3001c_fast_load(self, 1); + + (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD0); + (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD1); + (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD2); + (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD3); + (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD4); + (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD5); + (void)tas3001c_sync_register(self,TAS3001C_REG_RIGHT_BIQUAD6); + + (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD0); + (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD1); + (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD2); + (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD3); + (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD4); + (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD5); + (void)tas3001c_sync_register(self,TAS3001C_REG_LEFT_BIQUAD6); + + tas3001c_fast_load(self, 0); + + tas3001c_set_mixer_level(self, SOUND_MIXER_VOLUME, VOL_DEFAULT<<8 | VOL_DEFAULT); + tas3001c_set_mixer_level(self, SOUND_MIXER_PCM, INPUT_DEFAULT<<8 | INPUT_DEFAULT); + tas3001c_set_mixer_level(self, SOUND_MIXER_ALTPCM, 0); + + tas3001c_set_mixer_level(self, SOUND_MIXER_BASS, BASS_DEFAULT); + tas3001c_set_mixer_level(self, SOUND_MIXER_TREBLE, TREBLE_DEFAULT); + + return 0; +} + +static int +tas3001c_uninit_mixer(struct tas3001c_data_t *self) +{ + tas3001c_set_mixer_level(self, SOUND_MIXER_VOLUME, 0); + tas3001c_set_mixer_level(self, SOUND_MIXER_PCM, 0); + tas3001c_set_mixer_level(self, SOUND_MIXER_ALTPCM, 0); + + tas3001c_set_mixer_level(self, SOUND_MIXER_BASS, 0); + tas3001c_set_mixer_level(self, SOUND_MIXER_TREBLE, 0); + + return 0; +} + +static int +tas3001c_init(struct i2c_client *client) +{ + struct tas3001c_data_t *self; + size_t sz = sizeof(*self) + (TAS3001C_REG_MAX*sizeof(tas_shadow_t)); + int i, j; + + self = kzalloc(sz, GFP_KERNEL); + if (!self) + return -ENOMEM; + + self->super.client = client; + self->super.shadow = (tas_shadow_t *)(self+1); + self->output_id = TAS_OUTPUT_HEADPHONES; + + dev_set_drvdata(&client->dev, self); + + for (i = 0; i < TAS3001C_BIQUAD_CHANNEL_COUNT; i++) + for (j = 0; j < TAS3001C_BIQUAD_FILTER_COUNT; j++) + tas3001c_write_biquad_shadow(self, i, j, + &tas3001c_eq_unity); + + INIT_WORK(&self->change, tas3001c_device_change_handler); + return 0; +} + +static void +tas3001c_uninit(struct tas3001c_data_t *self) +{ + tas3001c_uninit_mixer(self); + kfree(self); +} + +struct tas_driver_hooks_t tas3001c_hooks = { + .init = (tas_hook_init_t)tas3001c_init, + .post_init = (tas_hook_post_init_t)tas3001c_init_mixer, + .uninit = (tas_hook_uninit_t)tas3001c_uninit, + .get_mixer_level = (tas_hook_get_mixer_level_t)tas3001c_get_mixer_level, + .set_mixer_level = (tas_hook_set_mixer_level_t)tas3001c_set_mixer_level, + .enter_sleep = (tas_hook_enter_sleep_t)tas3001c_enter_sleep, + .leave_sleep = (tas_hook_leave_sleep_t)tas3001c_leave_sleep, + .supported_mixers = (tas_hook_supported_mixers_t)tas3001c_supported_mixers, + .mixer_is_stereo = (tas_hook_mixer_is_stereo_t)tas3001c_mixer_is_stereo, + .stereo_mixers = (tas_hook_stereo_mixers_t)tas3001c_stereo_mixers, + .output_device_change = (tas_hook_output_device_change_t)tas3001c_output_device_change, + .device_ioctl = (tas_hook_device_ioctl_t)tas3001c_device_ioctl +}; diff --git a/trunk/sound/oss/dmasound/tas3001c.h b/trunk/sound/oss/dmasound/tas3001c.h new file mode 100644 index 000000000000..3660da33a2db --- /dev/null +++ b/trunk/sound/oss/dmasound/tas3001c.h @@ -0,0 +1,64 @@ +/* + * Header file for the i2c/i2s based TA3001c sound chip used + * on some Apple hardware. Also known as "tumbler". + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + * + * Written by Christopher C. Chimelis + */ + +#ifndef _TAS3001C_H_ +#define _TAS3001C_H_ + +#include + +#include "tas_common.h" +#include "tas_eq_prefs.h" + +/* + * Macros that correspond to the registers that we write to + * when setting the various values. + */ + +#define TAS3001C_VERSION "0.3" +#define TAS3001C_DATE "20011214" + +#define I2C_DRIVERNAME_TAS3001C "TAS3001c driver V " TAS3001C_VERSION +#define I2C_DRIVERID_TAS3001C (I2C_DRIVERID_TAS_BASE+0) + +extern struct tas_driver_hooks_t tas3001c_hooks; +extern struct tas_gain_t tas3001c_gain; +extern struct tas_eq_pref_t *tas3001c_eq_prefs[]; + +enum tas3001c_reg_t { + TAS3001C_REG_MCR = 0x01, + TAS3001C_REG_DRC = 0x02, + + TAS3001C_REG_VOLUME = 0x04, + TAS3001C_REG_TREBLE = 0x05, + TAS3001C_REG_BASS = 0x06, + TAS3001C_REG_MIXER1 = 0x07, + TAS3001C_REG_MIXER2 = 0x08, + + TAS3001C_REG_LEFT_BIQUAD0 = 0x0a, + TAS3001C_REG_LEFT_BIQUAD1 = 0x0b, + TAS3001C_REG_LEFT_BIQUAD2 = 0x0c, + TAS3001C_REG_LEFT_BIQUAD3 = 0x0d, + TAS3001C_REG_LEFT_BIQUAD4 = 0x0e, + TAS3001C_REG_LEFT_BIQUAD5 = 0x0f, + TAS3001C_REG_LEFT_BIQUAD6 = 0x10, + + TAS3001C_REG_RIGHT_BIQUAD0 = 0x13, + TAS3001C_REG_RIGHT_BIQUAD1 = 0x14, + TAS3001C_REG_RIGHT_BIQUAD2 = 0x15, + TAS3001C_REG_RIGHT_BIQUAD3 = 0x16, + TAS3001C_REG_RIGHT_BIQUAD4 = 0x17, + TAS3001C_REG_RIGHT_BIQUAD5 = 0x18, + TAS3001C_REG_RIGHT_BIQUAD6 = 0x19, + + TAS3001C_REG_MAX = 0x20 +}; + +#endif /* _TAS3001C_H_ */ diff --git a/trunk/sound/oss/dmasound/tas3001c_tables.c b/trunk/sound/oss/dmasound/tas3001c_tables.c new file mode 100644 index 000000000000..1768fa95f25b --- /dev/null +++ b/trunk/sound/oss/dmasound/tas3001c_tables.c @@ -0,0 +1,375 @@ +#include "tas_common.h" +#include "tas_eq_prefs.h" + +static struct tas_drce_t eqp_0e_2_1_drce = { + .enable = 1, + .above = { .val = 3.0 * (1<<8), .expand = 0 }, + .below = { .val = 1.0 * (1<<8), .expand = 0 }, + .threshold = -15.33 * (1<<8), + .energy = 2.4 * (1<<12), + .attack = 0.013 * (1<<12), + .decay = 0.212 * (1<<12), +}; + +static struct tas_biquad_ctrl_t eqp_0e_2_1_biquads[]={ + { .channel = 0, .filter = 0, .data = { .coeff = { 0x0FCAD3, 0xE06A58, 0x0FCAD3, 0xE06B09, 0x0F9657 } } }, + { .channel = 0, .filter = 1, .data = { .coeff = { 0x041731, 0x082E63, 0x041731, 0xFD8D08, 0x02CFBD } } }, + { .channel = 0, .filter = 2, .data = { .coeff = { 0x0FFDC7, 0xE0524C, 0x0FBFAA, 0xE0524C, 0x0FBD72 } } }, + { .channel = 0, .filter = 3, .data = { .coeff = { 0x0F3D35, 0xE228CA, 0x0EC7B2, 0xE228CA, 0x0E04E8 } } }, + { .channel = 0, .filter = 4, .data = { .coeff = { 0x0FCEBF, 0xE181C2, 0x0F2656, 0xE181C2, 0x0EF516 } } }, + { .channel = 0, .filter = 5, .data = { .coeff = { 0x0EC417, 0x073E22, 0x0B0633, 0x073E22, 0x09CA4A } } }, + + { .channel = 1, .filter = 0, .data = { .coeff = { 0x0FCAD3, 0xE06A58, 0x0FCAD3, 0xE06B09, 0x0F9657 } } }, + { .channel = 1, .filter = 1, .data = { .coeff = { 0x041731, 0x082E63, 0x041731, 0xFD8D08, 0x02CFBD } } }, + { .channel = 1, .filter = 2, .data = { .coeff = { 0x0FFDC7, 0xE0524C, 0x0FBFAA, 0xE0524C, 0x0FBD72 } } }, + { .channel = 1, .filter = 3, .data = { .coeff = { 0x0F3D35, 0xE228CA, 0x0EC7B2, 0xE228CA, 0x0E04E8 } } }, + { .channel = 1, .filter = 4, .data = { .coeff = { 0x0FCEBF, 0xE181C2, 0x0F2656, 0xE181C2, 0x0EF516 } } }, + { .channel = 1, .filter = 5, .data = { .coeff = { 0x0EC417, 0x073E22, 0x0B0633, 0x073E22, 0x09CA4A } } }, +}; + +static struct tas_eq_pref_t eqp_0e_2_1 = { + .sample_rate = 44100, + .device_id = 0x0e, + .output_id = TAS_OUTPUT_EXTERNAL_SPKR, + .speaker_id = 0x01, + + .drce = &eqp_0e_2_1_drce, + + .filter_count = 12, + .biquads = eqp_0e_2_1_biquads +}; + +/* ======================================================================== */ + +static struct tas_drce_t eqp_10_1_0_drce={ + .enable = 1, + .above = { .val = 3.0 * (1<<8), .expand = 0 }, + .below = { .val = 1.0 * (1<<8), .expand = 0 }, + .threshold = -12.46 * (1<<8), + .energy = 2.4 * (1<<12), + .attack = 0.013 * (1<<12), + .decay = 0.212 * (1<<12), +}; + +static struct tas_biquad_ctrl_t eqp_10_1_0_biquads[]={ + { .channel = 0, .filter = 0, .data = { .coeff = { 0x0F4A12, 0xE16BDA, 0x0F4A12, 0xE173F0, 0x0E9C3A } } }, + { .channel = 0, .filter = 1, .data = { .coeff = { 0x02DD54, 0x05BAA8, 0x02DD54, 0xF8001D, 0x037532 } } }, + { .channel = 0, .filter = 2, .data = { .coeff = { 0x0E2FC7, 0xE4D5DC, 0x0D7477, 0xE4D5DC, 0x0BA43F } } }, + { .channel = 0, .filter = 3, .data = { .coeff = { 0x0E7899, 0xE67CCA, 0x0D0E93, 0xE67CCA, 0x0B872D } } }, + { .channel = 0, .filter = 4, .data = { .coeff = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } }, + { .channel = 0, .filter = 5, .data = { .coeff = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } }, + + { .channel = 1, .filter = 0, .data = { .coeff = { 0x0F4A12, 0xE16BDA, 0x0F4A12, 0xE173F0, 0x0E9C3A } } }, + { .channel = 1, .filter = 1, .data = { .coeff = { 0x02DD54, 0x05BAA8, 0x02DD54, 0xF8001D, 0x037532 } } }, + { .channel = 1, .filter = 2, .data = { .coeff = { 0x0E2FC7, 0xE4D5DC, 0x0D7477, 0xE4D5DC, 0x0BA43F } } }, + { .channel = 1, .filter = 3, .data = { .coeff = { 0x0E7899, 0xE67CCA, 0x0D0E93, 0xE67CCA, 0x0B872D } } }, + { .channel = 1, .filter = 4, .data = { .coeff = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } }, + { .channel = 1, .filter = 5, .data = { .coeff = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } }, +}; + +static struct tas_eq_pref_t eqp_10_1_0 = { + .sample_rate = 44100, + .device_id = 0x10, + .output_id = TAS_OUTPUT_INTERNAL_SPKR, + .speaker_id = 0x00, + + .drce = &eqp_10_1_0_drce, + + .filter_count = 12, + .biquads = eqp_10_1_0_biquads +}; + +/* ======================================================================== */ + +static struct tas_drce_t eqp_15_2_1_drce={ + .enable = 1, + .above = { .val = 3.0 * (1<<8), .expand = 0 }, + .below = { .val = 1.0 * (1<<8), .expand = 0 }, + .threshold = -15.33 * (1<<8), + .energy = 2.4 * (1<<12), + .attack = 0.013 * (1<<12), + .decay = 0.212 * (1<<12), +}; + +static struct tas_biquad_ctrl_t eqp_15_2_1_biquads[]={ + { .channel = 0, .filter = 0, .data = { .coeff = { 0x0FE143, 0xE05204, 0x0FCCC5, 0xE05266, 0x0FAE6B } } }, + { .channel = 0, .filter = 1, .data = { .coeff = { 0x102383, 0xE03A03, 0x0FA325, 0xE03A03, 0x0FC6A8 } } }, + { .channel = 0, .filter = 2, .data = { .coeff = { 0x0FF2AB, 0xE06285, 0x0FB20A, 0xE06285, 0x0FA4B5 } } }, + { .channel = 0, .filter = 3, .data = { .coeff = { 0x0F544D, 0xE35971, 0x0D8F3A, 0xE35971, 0x0CE388 } } }, + { .channel = 0, .filter = 4, .data = { .coeff = { 0x13E1D3, 0xF3ECB5, 0x042227, 0xF3ECB5, 0x0803FA } } }, + { .channel = 0, .filter = 5, .data = { .coeff = { 0x0AC119, 0x034181, 0x078AB1, 0x034181, 0x024BCA } } }, + + { .channel = 1, .filter = 0, .data = { .coeff = { 0x0FE143, 0xE05204, 0x0FCCC5, 0xE05266, 0x0FAE6B } } }, + { .channel = 1, .filter = 1, .data = { .coeff = { 0x102383, 0xE03A03, 0x0FA325, 0xE03A03, 0x0FC6A8 } } }, + { .channel = 1, .filter = 2, .data = { .coeff = { 0x0FF2AB, 0xE06285, 0x0FB20A, 0xE06285, 0x0FA4B5 } } }, + { .channel = 1, .filter = 3, .data = { .coeff = { 0x0F544D, 0xE35971, 0x0D8F3A, 0xE35971, 0x0CE388 } } }, + { .channel = 1, .filter = 4, .data = { .coeff = { 0x13E1D3, 0xF3ECB5, 0x042227, 0xF3ECB5, 0x0803FA } } }, + { .channel = 1, .filter = 5, .data = { .coeff = { 0x0AC119, 0x034181, 0x078AB1, 0x034181, 0x024BCA } } }, +}; + +static struct tas_eq_pref_t eqp_15_2_1 = { + .sample_rate = 44100, + .device_id = 0x15, + .output_id = TAS_OUTPUT_EXTERNAL_SPKR, + .speaker_id = 0x01, + + .drce = &eqp_15_2_1_drce, + + .filter_count = 12, + .biquads = eqp_15_2_1_biquads +}; + +/* ======================================================================== */ + +static struct tas_drce_t eqp_15_1_0_drce={ + .enable = 1, + .above = { .val = 3.0 * (1<<8), .expand = 0 }, + .below = { .val = 1.0 * (1<<8), .expand = 0 }, + .threshold = 0.0 * (1<<8), + .energy = 2.4 * (1<<12), + .attack = 0.013 * (1<<12), + .decay = 0.212 * (1<<12), +}; + +static struct tas_biquad_ctrl_t eqp_15_1_0_biquads[]={ + { .channel = 0, .filter = 0, .data = { .coeff = { 0x0FAD08, 0xE0A5EF, 0x0FAD08, 0xE0A79D, 0x0F5BBE } } }, + { .channel = 0, .filter = 1, .data = { .coeff = { 0x04B38D, 0x09671B, 0x04B38D, 0x000F71, 0x02BEC5 } } }, + { .channel = 0, .filter = 2, .data = { .coeff = { 0x0FDD32, 0xE0A56F, 0x0F8A69, 0xE0A56F, 0x0F679C } } }, + { .channel = 0, .filter = 3, .data = { .coeff = { 0x0FD284, 0xE135FB, 0x0F2161, 0xE135FB, 0x0EF3E5 } } }, + { .channel = 0, .filter = 4, .data = { .coeff = { 0x0E81B1, 0xE6283F, 0x0CE49D, 0xE6283F, 0x0B664F } } }, + { .channel = 0, .filter = 5, .data = { .coeff = { 0x0F2D62, 0xE98797, 0x0D1E19, 0xE98797, 0x0C4B7B } } }, + + { .channel = 1, .filter = 0, .data = { .coeff = { 0x0FAD08, 0xE0A5EF, 0x0FAD08, 0xE0A79D, 0x0F5BBE } } }, + { .channel = 1, .filter = 1, .data = { .coeff = { 0x04B38D, 0x09671B, 0x04B38D, 0x000F71, 0x02BEC5 } } }, + { .channel = 1, .filter = 2, .data = { .coeff = { 0x0FDD32, 0xE0A56F, 0x0F8A69, 0xE0A56F, 0x0F679C } } }, + { .channel = 1, .filter = 3, .data = { .coeff = { 0x0FD284, 0xE135FB, 0x0F2161, 0xE135FB, 0x0EF3E5 } } }, + { .channel = 1, .filter = 4, .data = { .coeff = { 0x0E81B1, 0xE6283F, 0x0CE49D, 0xE6283F, 0x0B664F } } }, + { .channel = 1, .filter = 5, .data = { .coeff = { 0x0F2D62, 0xE98797, 0x0D1E19, 0xE98797, 0x0C4B7B } } }, +}; + +static struct tas_eq_pref_t eqp_15_1_0 = { + .sample_rate = 44100, + .device_id = 0x15, + .output_id = TAS_OUTPUT_INTERNAL_SPKR, + .speaker_id = 0x00, + + .drce = &eqp_15_1_0_drce, + + .filter_count = 12, + .biquads = eqp_15_1_0_biquads +}; + +/* ======================================================================== */ + +static struct tas_drce_t eqp_0f_2_1_drce={ + .enable = 1, + .above = { .val = 3.0 * (1<<8), .expand = 0 }, + .below = { .val = 1.0 * (1<<8), .expand = 0 }, + .threshold = -15.33 * (1<<8), + .energy = 2.4 * (1<<12), + .attack = 0.013 * (1<<12), + .decay = 0.212 * (1<<12), +}; + +static struct tas_biquad_ctrl_t eqp_0f_2_1_biquads[]={ + { .channel = 0, .filter = 0, .data = { .coeff = { 0x0FE143, 0xE05204, 0x0FCCC5, 0xE05266, 0x0FAE6B } } }, + { .channel = 0, .filter = 1, .data = { .coeff = { 0x102383, 0xE03A03, 0x0FA325, 0xE03A03, 0x0FC6A8 } } }, + { .channel = 0, .filter = 2, .data = { .coeff = { 0x0FF2AB, 0xE06285, 0x0FB20A, 0xE06285, 0x0FA4B5 } } }, + { .channel = 0, .filter = 3, .data = { .coeff = { 0x0F544D, 0xE35971, 0x0D8F3A, 0xE35971, 0x0CE388 } } }, + { .channel = 0, .filter = 4, .data = { .coeff = { 0x13E1D3, 0xF3ECB5, 0x042227, 0xF3ECB5, 0x0803FA } } }, + { .channel = 0, .filter = 5, .data = { .coeff = { 0x0AC119, 0x034181, 0x078AB1, 0x034181, 0x024BCA } } }, + + { .channel = 1, .filter = 0, .data = { .coeff = { 0x0FE143, 0xE05204, 0x0FCCC5, 0xE05266, 0x0FAE6B } } }, + { .channel = 1, .filter = 1, .data = { .coeff = { 0x102383, 0xE03A03, 0x0FA325, 0xE03A03, 0x0FC6A8 } } }, + { .channel = 1, .filter = 2, .data = { .coeff = { 0x0FF2AB, 0xE06285, 0x0FB20A, 0xE06285, 0x0FA4B5 } } }, + { .channel = 1, .filter = 3, .data = { .coeff = { 0x0F544D, 0xE35971, 0x0D8F3A, 0xE35971, 0x0CE388 } } }, + { .channel = 1, .filter = 4, .data = { .coeff = { 0x13E1D3, 0xF3ECB5, 0x042227, 0xF3ECB5, 0x0803FA } } }, + { .channel = 1, .filter = 5, .data = { .coeff = { 0x0AC119, 0x034181, 0x078AB1, 0x034181, 0x024BCA } } }, +}; + +static struct tas_eq_pref_t eqp_0f_2_1 = { + .sample_rate = 44100, + .device_id = 0x0f, + .output_id = TAS_OUTPUT_EXTERNAL_SPKR, + .speaker_id = 0x01, + + .drce = &eqp_0f_2_1_drce, + + .filter_count = 12, + .biquads = eqp_0f_2_1_biquads +}; + +/* ======================================================================== */ + +static struct tas_drce_t eqp_0f_1_0_drce={ + .enable = 1, + .above = { .val = 3.0 * (1<<8), .expand = 0 }, + .below = { .val = 1.0 * (1<<8), .expand = 0 }, + .threshold = -15.33 * (1<<8), + .energy = 2.4 * (1<<12), + .attack = 0.013 * (1<<12), + .decay = 0.212 * (1<<12), +}; + +static struct tas_biquad_ctrl_t eqp_0f_1_0_biquads[]={ + { .channel = 0, .filter = 0, .data = { .coeff = { 0x0FCAD3, 0xE06A58, 0x0FCAD3, 0xE06B09, 0x0F9657 } } }, + { .channel = 0, .filter = 1, .data = { .coeff = { 0x041731, 0x082E63, 0x041731, 0xFD8D08, 0x02CFBD } } }, + { .channel = 0, .filter = 2, .data = { .coeff = { 0x0FFDC7, 0xE0524C, 0x0FBFAA, 0xE0524C, 0x0FBD72 } } }, + { .channel = 0, .filter = 3, .data = { .coeff = { 0x0F3D35, 0xE228CA, 0x0EC7B2, 0xE228CA, 0x0E04E8 } } }, + { .channel = 0, .filter = 4, .data = { .coeff = { 0x0FCEBF, 0xE181C2, 0x0F2656, 0xE181C2, 0x0EF516 } } }, + { .channel = 0, .filter = 5, .data = { .coeff = { 0x0EC417, 0x073E22, 0x0B0633, 0x073E22, 0x09CA4A } } }, + + { .channel = 1, .filter = 0, .data = { .coeff = { 0x0FCAD3, 0xE06A58, 0x0FCAD3, 0xE06B09, 0x0F9657 } } }, + { .channel = 1, .filter = 1, .data = { .coeff = { 0x041731, 0x082E63, 0x041731, 0xFD8D08, 0x02CFBD } } }, + { .channel = 1, .filter = 2, .data = { .coeff = { 0x0FFDC7, 0xE0524C, 0x0FBFAA, 0xE0524C, 0x0FBD72 } } }, + { .channel = 1, .filter = 3, .data = { .coeff = { 0x0F3D35, 0xE228CA, 0x0EC7B2, 0xE228CA, 0x0E04E8 } } }, + { .channel = 1, .filter = 4, .data = { .coeff = { 0x0FCEBF, 0xE181C2, 0x0F2656, 0xE181C2, 0x0EF516 } } }, + { .channel = 1, .filter = 5, .data = { .coeff = { 0x0EC417, 0x073E22, 0x0B0633, 0x073E22, 0x09CA4A } } }, +}; + +static struct tas_eq_pref_t eqp_0f_1_0 = { + .sample_rate = 44100, + .device_id = 0x0f, + .output_id = TAS_OUTPUT_INTERNAL_SPKR, + .speaker_id = 0x00, + + .drce = &eqp_0f_1_0_drce, + + .filter_count = 12, + .biquads = eqp_0f_1_0_biquads +}; + +/* ======================================================================== */ + +static uint tas3001c_master_tab[]={ + 0x0, 0x75, 0x9c, 0xbb, + 0xdb, 0xfb, 0x11e, 0x143, + 0x16b, 0x196, 0x1c3, 0x1f5, + 0x229, 0x263, 0x29f, 0x2e1, + 0x328, 0x373, 0x3c5, 0x41b, + 0x478, 0x4dc, 0x547, 0x5b8, + 0x633, 0x6b5, 0x740, 0x7d5, + 0x873, 0x91c, 0x9d2, 0xa92, + 0xb5e, 0xc39, 0xd22, 0xe19, + 0xf20, 0x1037, 0x1161, 0x129e, + 0x13ed, 0x1551, 0x16ca, 0x185d, + 0x1a08, 0x1bcc, 0x1dac, 0x1fa7, + 0x21c1, 0x23fa, 0x2655, 0x28d6, + 0x2b7c, 0x2e4a, 0x3141, 0x3464, + 0x37b4, 0x3b35, 0x3ee9, 0x42d3, + 0x46f6, 0x4b53, 0x4ff0, 0x54ce, + 0x59f2, 0x5f5f, 0x6519, 0x6b24, + 0x7183, 0x783c, 0x7f53, 0x86cc, + 0x8ead, 0x96fa, 0x9fba, 0xa8f2, + 0xb2a7, 0xbce1, 0xc7a5, 0xd2fa, + 0xdee8, 0xeb75, 0xf8aa, 0x1068e, + 0x1152a, 0x12487, 0x134ad, 0x145a5, + 0x1577b, 0x16a37, 0x17df5, 0x192bd, + 0x1a890, 0x1bf7b, 0x1d78d, 0x1f0d1, + 0x20b55, 0x22727, 0x24456, 0x262f2, + 0x2830b +}; + +static uint tas3001c_mixer_tab[]={ + 0x0, 0x748, 0x9be, 0xbaf, + 0xda4, 0xfb1, 0x11de, 0x1431, + 0x16ad, 0x1959, 0x1c37, 0x1f4b, + 0x2298, 0x2628, 0x29fb, 0x2e12, + 0x327d, 0x3734, 0x3c47, 0x41b4, + 0x4787, 0x4dbe, 0x546d, 0x5b86, + 0x632e, 0x6b52, 0x7400, 0x7d54, + 0x873b, 0x91c6, 0x9d1a, 0xa920, + 0xb5e5, 0xc38c, 0xd21b, 0xe18f, + 0xf1f5, 0x1036a, 0x1160f, 0x129d6, + 0x13ed0, 0x1550c, 0x16ca0, 0x185c9, + 0x1a07b, 0x1bcc3, 0x1dab9, 0x1fa75, + 0x21c0f, 0x23fa3, 0x26552, 0x28d64, + 0x2b7c9, 0x2e4a2, 0x31411, 0x3463b, + 0x37b44, 0x3b353, 0x3ee94, 0x42d30, + 0x46f55, 0x4b533, 0x4fefc, 0x54ce5, + 0x59f25, 0x5f5f6, 0x65193, 0x6b23c, + 0x71835, 0x783c3, 0x7f52c, 0x86cc0, + 0x8eacc, 0x96fa5, 0x9fba0, 0xa8f1a, + 0xb2a71, 0xbce0a, 0xc7a4a, 0xd2fa0, + 0xdee7b, 0xeb752, 0xf8a9f, 0x1068e4, + 0x1152a3, 0x12486a, 0x134ac8, 0x145a55, + 0x1577ac, 0x16a370, 0x17df51, 0x192bc2, + 0x1a88f8, 0x1bf7b7, 0x1d78c9, 0x1f0d04, + 0x20b542, 0x227268, 0x244564, 0x262f26, + 0x2830af +}; + +static uint tas3001c_treble_tab[]={ + 0x96, 0x95, 0x95, 0x94, + 0x93, 0x92, 0x92, 0x91, + 0x90, 0x90, 0x8f, 0x8e, + 0x8d, 0x8d, 0x8c, 0x8b, + 0x8a, 0x8a, 0x89, 0x88, + 0x88, 0x87, 0x86, 0x85, + 0x85, 0x84, 0x83, 0x83, + 0x82, 0x81, 0x80, 0x80, + 0x7f, 0x7e, 0x7e, 0x7d, + 0x7c, 0x7b, 0x7b, 0x7a, + 0x79, 0x78, 0x78, 0x77, + 0x76, 0x76, 0x75, 0x74, + 0x73, 0x73, 0x72, 0x71, + 0x71, 0x70, 0x6e, 0x6d, + 0x6d, 0x6c, 0x6b, 0x6a, + 0x69, 0x68, 0x67, 0x66, + 0x65, 0x63, 0x62, 0x62, + 0x60, 0x5f, 0x5d, 0x5c, + 0x5a, 0x58, 0x56, 0x55, + 0x53, 0x51, 0x4f, 0x4c, + 0x4a, 0x48, 0x45, 0x43, + 0x40, 0x3d, 0x3a, 0x37, + 0x35, 0x32, 0x2e, 0x2a, + 0x27, 0x22, 0x1e, 0x1a, + 0x15, 0x11, 0xc, 0x7, + 0x1 +}; + +static uint tas3001c_bass_tab[]={ + 0x86, 0x83, 0x81, 0x7f, + 0x7d, 0x7b, 0x79, 0x78, + 0x76, 0x75, 0x74, 0x72, + 0x71, 0x6f, 0x6e, 0x6d, + 0x6c, 0x6b, 0x69, 0x67, + 0x65, 0x64, 0x61, 0x60, + 0x5e, 0x5d, 0x5c, 0x5b, + 0x5a, 0x59, 0x58, 0x57, + 0x56, 0x55, 0x55, 0x54, + 0x53, 0x52, 0x50, 0x4f, + 0x4d, 0x4c, 0x4b, 0x49, + 0x47, 0x45, 0x44, 0x42, + 0x41, 0x3f, 0x3e, 0x3d, + 0x3c, 0x3b, 0x39, 0x38, + 0x37, 0x36, 0x35, 0x34, + 0x33, 0x31, 0x30, 0x2f, + 0x2e, 0x2c, 0x2b, 0x2b, + 0x29, 0x28, 0x27, 0x26, + 0x25, 0x24, 0x22, 0x21, + 0x20, 0x1e, 0x1c, 0x19, + 0x18, 0x18, 0x17, 0x16, + 0x15, 0x14, 0x13, 0x12, + 0x11, 0x10, 0xf, 0xe, + 0xd, 0xb, 0xa, 0x9, + 0x8, 0x6, 0x4, 0x2, + 0x1 +}; + +struct tas_gain_t tas3001c_gain = { + .master = tas3001c_master_tab, + .treble = tas3001c_treble_tab, + .bass = tas3001c_bass_tab, + .mixer = tas3001c_mixer_tab +}; + +struct tas_eq_pref_t *tas3001c_eq_prefs[]={ + &eqp_0e_2_1, + &eqp_10_1_0, + &eqp_15_2_1, + &eqp_15_1_0, + &eqp_0f_2_1, + &eqp_0f_1_0, + NULL +}; diff --git a/trunk/sound/oss/dmasound/tas3004.c b/trunk/sound/oss/dmasound/tas3004.c new file mode 100644 index 000000000000..678bf0ff6da2 --- /dev/null +++ b/trunk/sound/oss/dmasound/tas3004.c @@ -0,0 +1,1138 @@ +/* + * Driver for the i2c/i2s based TA3004 sound chip used + * on some Apple hardware. Also known as "snapper". + * + * Tobias Sargeant + * Based upon tas3001c.c by Christopher C. Chimelis : + * + * Input support by Renzo Davoli + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "dmasound.h" +#include "tas_common.h" +#include "tas3004.h" + +#include "tas_ioctl.h" + +/* #define DEBUG_DRCE */ + +#define TAS3004_BIQUAD_FILTER_COUNT 7 +#define TAS3004_BIQUAD_CHANNEL_COUNT 2 + +#define VOL_DEFAULT (100 * 4 / 5) +#define INPUT_DEFAULT (100 * 4 / 5) +#define BASS_DEFAULT (100 / 2) +#define TREBLE_DEFAULT (100 / 2) + +struct tas3004_data_t { + struct tas_data_t super; + int device_id; + int output_id; + int speaker_id; + struct tas_drce_t drce_state; + struct work_struct change; +}; + +#define MAKE_TIME(sec,usec) (((sec)<<12) + (50000+(usec/10)*(1<<12))/100000) + +#define MAKE_RATIO(i,f) (((i)<<8) + ((500+(f)*(1<<8))/1000)) + + +static const union tas_biquad_t tas3004_eq_unity = { + .buf = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 }, +}; + + +static const struct tas_drce_t tas3004_drce_min = { + .enable = 1, + .above = { .val = MAKE_RATIO(16,0), .expand = 0 }, + .below = { .val = MAKE_RATIO(2,0), .expand = 0 }, + .threshold = -0x59a0, + .energy = MAKE_TIME(0, 1700), + .attack = MAKE_TIME(0, 1700), + .decay = MAKE_TIME(0, 1700), +}; + + +static const struct tas_drce_t tas3004_drce_max = { + .enable = 1, + .above = { .val = MAKE_RATIO(1,500), .expand = 1 }, + .below = { .val = MAKE_RATIO(2,0), .expand = 1 }, + .threshold = -0x0, + .energy = MAKE_TIME(2,400000), + .attack = MAKE_TIME(2,400000), + .decay = MAKE_TIME(2,400000), +}; + + +static const unsigned short time_constants[]={ + MAKE_TIME(0, 1700), + MAKE_TIME(0, 3500), + MAKE_TIME(0, 6700), + MAKE_TIME(0, 13000), + MAKE_TIME(0, 26000), + MAKE_TIME(0, 53000), + MAKE_TIME(0,106000), + MAKE_TIME(0,212000), + MAKE_TIME(0,425000), + MAKE_TIME(0,850000), + MAKE_TIME(1,700000), + MAKE_TIME(2,400000), +}; + +static const unsigned short above_threshold_compression_ratio[]={ + MAKE_RATIO( 1, 70), + MAKE_RATIO( 1,140), + MAKE_RATIO( 1,230), + MAKE_RATIO( 1,330), + MAKE_RATIO( 1,450), + MAKE_RATIO( 1,600), + MAKE_RATIO( 1,780), + MAKE_RATIO( 2, 0), + MAKE_RATIO( 2,290), + MAKE_RATIO( 2,670), + MAKE_RATIO( 3,200), + MAKE_RATIO( 4, 0), + MAKE_RATIO( 5,330), + MAKE_RATIO( 8, 0), + MAKE_RATIO(16, 0), +}; + +static const unsigned short above_threshold_expansion_ratio[]={ + MAKE_RATIO(1, 60), + MAKE_RATIO(1,130), + MAKE_RATIO(1,190), + MAKE_RATIO(1,250), + MAKE_RATIO(1,310), + MAKE_RATIO(1,380), + MAKE_RATIO(1,440), + MAKE_RATIO(1,500) +}; + +static const unsigned short below_threshold_compression_ratio[]={ + MAKE_RATIO(1, 70), + MAKE_RATIO(1,140), + MAKE_RATIO(1,230), + MAKE_RATIO(1,330), + MAKE_RATIO(1,450), + MAKE_RATIO(1,600), + MAKE_RATIO(1,780), + MAKE_RATIO(2, 0) +}; + +static const unsigned short below_threshold_expansion_ratio[]={ + MAKE_RATIO(1, 60), + MAKE_RATIO(1,130), + MAKE_RATIO(1,190), + MAKE_RATIO(1,250), + MAKE_RATIO(1,310), + MAKE_RATIO(1,380), + MAKE_RATIO(1,440), + MAKE_RATIO(1,500), + MAKE_RATIO(1,560), + MAKE_RATIO(1,630), + MAKE_RATIO(1,690), + MAKE_RATIO(1,750), + MAKE_RATIO(1,810), + MAKE_RATIO(1,880), + MAKE_RATIO(1,940), + MAKE_RATIO(2, 0) +}; + +static inline int +search( unsigned short val, + const unsigned short *arr, + const int arrsize) { + /* + * This could be a binary search, but for small tables, + * a linear search is likely to be faster + */ + + int i; + + for (i=0; i < arrsize; i++) + if (arr[i] >= val) + goto _1; + return arrsize-1; + _1: + if (i == 0) + return 0; + return (arr[i]-val < val-arr[i-1]) ? i : i-1; +} + +#define SEARCH(a, b) search(a, b, ARRAY_SIZE(b)) + +static inline int +time_index(unsigned short time) +{ + return SEARCH(time, time_constants); +} + + +static inline int +above_threshold_compression_index(unsigned short ratio) +{ + return SEARCH(ratio, above_threshold_compression_ratio); +} + + +static inline int +above_threshold_expansion_index(unsigned short ratio) +{ + return SEARCH(ratio, above_threshold_expansion_ratio); +} + + +static inline int +below_threshold_compression_index(unsigned short ratio) +{ + return SEARCH(ratio, below_threshold_compression_ratio); +} + + +static inline int +below_threshold_expansion_index(unsigned short ratio) +{ + return SEARCH(ratio, below_threshold_expansion_ratio); +} + +static inline unsigned char db_to_regval(short db) { + int r=0; + + r=(db+0x59a0) / 0x60; + + if (r < 0x91) return 0x91; + if (r > 0xef) return 0xef; + return r; +} + +static inline short quantize_db(short db) +{ + return db_to_regval(db) * 0x60 - 0x59a0; +} + +static inline int +register_width(enum tas3004_reg_t r) +{ + switch(r) { + case TAS3004_REG_MCR: + case TAS3004_REG_TREBLE: + case TAS3004_REG_BASS: + case TAS3004_REG_ANALOG_CTRL: + case TAS3004_REG_TEST1: + case TAS3004_REG_TEST2: + case TAS3004_REG_MCR2: + return 1; + + case TAS3004_REG_LEFT_LOUD_BIQUAD_GAIN: + case TAS3004_REG_RIGHT_LOUD_BIQUAD_GAIN: + return 3; + + case TAS3004_REG_DRC: + case TAS3004_REG_VOLUME: + return 6; + + case TAS3004_REG_LEFT_MIXER: + case TAS3004_REG_RIGHT_MIXER: + return 9; + + case TAS3004_REG_TEST: + return 10; + + case TAS3004_REG_LEFT_BIQUAD0: + case TAS3004_REG_LEFT_BIQUAD1: + case TAS3004_REG_LEFT_BIQUAD2: + case TAS3004_REG_LEFT_BIQUAD3: + case TAS3004_REG_LEFT_BIQUAD4: + case TAS3004_REG_LEFT_BIQUAD5: + case TAS3004_REG_LEFT_BIQUAD6: + + case TAS3004_REG_RIGHT_BIQUAD0: + case TAS3004_REG_RIGHT_BIQUAD1: + case TAS3004_REG_RIGHT_BIQUAD2: + case TAS3004_REG_RIGHT_BIQUAD3: + case TAS3004_REG_RIGHT_BIQUAD4: + case TAS3004_REG_RIGHT_BIQUAD5: + case TAS3004_REG_RIGHT_BIQUAD6: + + case TAS3004_REG_LEFT_LOUD_BIQUAD: + case TAS3004_REG_RIGHT_LOUD_BIQUAD: + return 15; + + default: + return 0; + } +} + +static int +tas3004_write_register( struct tas3004_data_t *self, + enum tas3004_reg_t reg_num, + char *data, + uint write_mode) +{ + if (reg_num==TAS3004_REG_MCR || + reg_num==TAS3004_REG_BASS || + reg_num==TAS3004_REG_TREBLE || + reg_num==TAS3004_REG_ANALOG_CTRL) { + return tas_write_byte_register(&self->super, + (uint)reg_num, + *data, + write_mode); + } else { + return tas_write_register(&self->super, + (uint)reg_num, + register_width(reg_num), + data, + write_mode); + } +} + +static int +tas3004_sync_register( struct tas3004_data_t *self, + enum tas3004_reg_t reg_num) +{ + if (reg_num==TAS3004_REG_MCR || + reg_num==TAS3004_REG_BASS || + reg_num==TAS3004_REG_TREBLE || + reg_num==TAS3004_REG_ANALOG_CTRL) { + return tas_sync_byte_register(&self->super, + (uint)reg_num, + register_width(reg_num)); + } else { + return tas_sync_register(&self->super, + (uint)reg_num, + register_width(reg_num)); + } +} + +static int +tas3004_read_register( struct tas3004_data_t *self, + enum tas3004_reg_t reg_num, + char *data, + uint write_mode) +{ + return tas_read_register(&self->super, + (uint)reg_num, + register_width(reg_num), + data); +} + +static inline int +tas3004_fast_load(struct tas3004_data_t *self, int fast) +{ + if (fast) + self->super.shadow[TAS3004_REG_MCR][0] |= 0x80; + else + self->super.shadow[TAS3004_REG_MCR][0] &= 0x7f; + return tas3004_sync_register(self,TAS3004_REG_MCR); +} + +static uint +tas3004_supported_mixers(struct tas3004_data_t *self) +{ + return SOUND_MASK_VOLUME | + SOUND_MASK_PCM | + SOUND_MASK_ALTPCM | + SOUND_MASK_IMIX | + SOUND_MASK_TREBLE | + SOUND_MASK_BASS | + SOUND_MASK_MIC | + SOUND_MASK_LINE; +} + +static int +tas3004_mixer_is_stereo(struct tas3004_data_t *self, int mixer) +{ + switch(mixer) { + case SOUND_MIXER_VOLUME: + case SOUND_MIXER_PCM: + case SOUND_MIXER_ALTPCM: + case SOUND_MIXER_IMIX: + return 1; + default: + return 0; + } +} + +static uint +tas3004_stereo_mixers(struct tas3004_data_t *self) +{ + uint r = tas3004_supported_mixers(self); + uint i; + + for (i=1; isuper.mixer[mixer]; + + return 0; +} + +static int +tas3004_set_mixer_level(struct tas3004_data_t *self, int mixer, uint level) +{ + int rc; + tas_shadow_t *shadow; + uint temp; + uint offset=0; + + if (!self) + return -1; + + shadow = self->super.shadow; + + if (!tas3004_mixer_is_stereo(self,mixer)) + level = tas_mono_to_stereo(level); + switch(mixer) { + case SOUND_MIXER_VOLUME: + temp = tas3004_gain.master[level&0xff]; + SET_4_20(shadow[TAS3004_REG_VOLUME], 0, temp); + temp = tas3004_gain.master[(level>>8)&0xff]; + SET_4_20(shadow[TAS3004_REG_VOLUME], 3, temp); + rc = tas3004_sync_register(self,TAS3004_REG_VOLUME); + break; + case SOUND_MIXER_IMIX: + offset += 3; + case SOUND_MIXER_ALTPCM: + offset += 3; + case SOUND_MIXER_PCM: + /* + * Don't load these in fast mode. The documentation + * says it can be done in either mode, but testing it + * shows that fast mode produces ugly clicking. + */ + /* tas3004_fast_load(self,1); */ + temp = tas3004_gain.mixer[level&0xff]; + SET_4_20(shadow[TAS3004_REG_LEFT_MIXER], offset, temp); + temp = tas3004_gain.mixer[(level>>8)&0xff]; + SET_4_20(shadow[TAS3004_REG_RIGHT_MIXER], offset, temp); + rc = tas3004_sync_register(self,TAS3004_REG_LEFT_MIXER); + if (rc == 0) + rc=tas3004_sync_register(self,TAS3004_REG_RIGHT_MIXER); + /* tas3004_fast_load(self,0); */ + break; + case SOUND_MIXER_TREBLE: + temp = tas3004_gain.treble[level&0xff]; + shadow[TAS3004_REG_TREBLE][0]=temp&0xff; + rc = tas3004_sync_register(self,TAS3004_REG_TREBLE); + break; + case SOUND_MIXER_BASS: + temp = tas3004_gain.bass[level&0xff]; + shadow[TAS3004_REG_BASS][0]=temp&0xff; + rc = tas3004_sync_register(self,TAS3004_REG_BASS); + break; + case SOUND_MIXER_MIC: + if ((level&0xff)>0) { + software_input_volume = SW_INPUT_VOLUME_SCALE * (level&0xff); + if (self->super.mixer[mixer] == 0) { + self->super.mixer[SOUND_MIXER_LINE] = 0; + shadow[TAS3004_REG_ANALOG_CTRL][0]=0xc2; + rc = tas3004_sync_register(self,TAS3004_REG_ANALOG_CTRL); + } else rc=0; + } else { + self->super.mixer[SOUND_MIXER_LINE] = SW_INPUT_VOLUME_DEFAULT; + software_input_volume = SW_INPUT_VOLUME_SCALE * + (self->super.mixer[SOUND_MIXER_LINE]&0xff); + shadow[TAS3004_REG_ANALOG_CTRL][0]=0x00; + rc = tas3004_sync_register(self,TAS3004_REG_ANALOG_CTRL); + } + break; + case SOUND_MIXER_LINE: + if (self->super.mixer[SOUND_MIXER_MIC] == 0) { + software_input_volume = SW_INPUT_VOLUME_SCALE * (level&0xff); + rc=0; + } + break; + default: + rc = -1; + break; + } + if (rc < 0) + return rc; + self->super.mixer[mixer] = level; + + return 0; +} + +static int +tas3004_leave_sleep(struct tas3004_data_t *self) +{ + unsigned char mcr = (1<<6)+(2<<4)+(2<<2); + + if (!self) + return -1; + + /* Make sure something answers on the i2c bus */ + if (tas3004_write_register(self, TAS3004_REG_MCR, &mcr, + WRITE_NORMAL | FORCE_WRITE) < 0) + return -1; + + tas3004_fast_load(self, 1); + + (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD0); + (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD1); + (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD2); + (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD3); + (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD4); + (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD5); + (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD6); + + (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD0); + (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD1); + (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD2); + (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD3); + (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD4); + (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD5); + (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD6); + + tas3004_fast_load(self, 0); + + (void)tas3004_sync_register(self,TAS3004_REG_VOLUME); + (void)tas3004_sync_register(self,TAS3004_REG_LEFT_MIXER); + (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_MIXER); + (void)tas3004_sync_register(self,TAS3004_REG_TREBLE); + (void)tas3004_sync_register(self,TAS3004_REG_BASS); + (void)tas3004_sync_register(self,TAS3004_REG_ANALOG_CTRL); + + return 0; +} + +static int +tas3004_enter_sleep(struct tas3004_data_t *self) +{ + if (!self) + return -1; + return 0; +} + +static int +tas3004_sync_biquad( struct tas3004_data_t *self, + u_int channel, + u_int filter) +{ + enum tas3004_reg_t reg; + + if (channel >= TAS3004_BIQUAD_CHANNEL_COUNT || + filter >= TAS3004_BIQUAD_FILTER_COUNT) return -EINVAL; + + reg=( channel ? TAS3004_REG_RIGHT_BIQUAD0 : TAS3004_REG_LEFT_BIQUAD0 ) + filter; + + return tas3004_sync_register(self,reg); +} + +static int +tas3004_write_biquad_shadow( struct tas3004_data_t *self, + u_int channel, + u_int filter, + const union tas_biquad_t *biquad) +{ + tas_shadow_t *shadow=self->super.shadow; + enum tas3004_reg_t reg; + + if (channel >= TAS3004_BIQUAD_CHANNEL_COUNT || + filter >= TAS3004_BIQUAD_FILTER_COUNT) return -EINVAL; + + reg=( channel ? TAS3004_REG_RIGHT_BIQUAD0 : TAS3004_REG_LEFT_BIQUAD0 ) + filter; + + SET_4_20(shadow[reg], 0,biquad->coeff.b0); + SET_4_20(shadow[reg], 3,biquad->coeff.b1); + SET_4_20(shadow[reg], 6,biquad->coeff.b2); + SET_4_20(shadow[reg], 9,biquad->coeff.a1); + SET_4_20(shadow[reg],12,biquad->coeff.a2); + + return 0; +} + +static int +tas3004_write_biquad( struct tas3004_data_t *self, + u_int channel, + u_int filter, + const union tas_biquad_t *biquad) +{ + int rc; + + rc=tas3004_write_biquad_shadow(self, channel, filter, biquad); + if (rc < 0) return rc; + + return tas3004_sync_biquad(self, channel, filter); +} + +static int +tas3004_write_biquad_list( struct tas3004_data_t *self, + u_int filter_count, + u_int flags, + struct tas_biquad_ctrl_t *biquads) +{ + int i; + int rc; + + if (flags & TAS_BIQUAD_FAST_LOAD) tas3004_fast_load(self,1); + + for (i=0; isuper.shadow; + enum tas3004_reg_t reg; + + if (channel >= TAS3004_BIQUAD_CHANNEL_COUNT || + filter >= TAS3004_BIQUAD_FILTER_COUNT) return -EINVAL; + + reg=( channel ? TAS3004_REG_RIGHT_BIQUAD0 : TAS3004_REG_LEFT_BIQUAD0 ) + filter; + + biquad->coeff.b0=GET_4_20(shadow[reg], 0); + biquad->coeff.b1=GET_4_20(shadow[reg], 3); + biquad->coeff.b2=GET_4_20(shadow[reg], 6); + biquad->coeff.a1=GET_4_20(shadow[reg], 9); + biquad->coeff.a2=GET_4_20(shadow[reg],12); + + return 0; +} + +static int +tas3004_eq_rw( struct tas3004_data_t *self, + u_int cmd, + u_long arg) +{ + void __user *argp = (void __user *)arg; + int rc; + struct tas_biquad_ctrl_t biquad; + + if (copy_from_user((void *)&biquad, argp, sizeof(struct tas_biquad_ctrl_t))) { + return -EFAULT; + } + + if (cmd & SIOC_IN) { + rc=tas3004_write_biquad(self, biquad.channel, biquad.filter, &biquad.data); + if (rc != 0) return rc; + } + + if (cmd & SIOC_OUT) { + rc=tas3004_read_biquad(self, biquad.channel, biquad.filter, &biquad.data); + if (rc != 0) return rc; + + if (copy_to_user(argp, &biquad, sizeof(struct tas_biquad_ctrl_t))) { + return -EFAULT; + } + + } + return 0; +} + +static int +tas3004_eq_list_rw( struct tas3004_data_t *self, + u_int cmd, + u_long arg) +{ + int rc = 0; + int filter_count; + int flags; + int i,j; + char sync_required[TAS3004_BIQUAD_CHANNEL_COUNT][TAS3004_BIQUAD_FILTER_COUNT]; + struct tas_biquad_ctrl_t biquad; + struct tas_biquad_ctrl_list_t __user *argp = (void __user *)arg; + + memset(sync_required,0,sizeof(sync_required)); + + if (copy_from_user(&filter_count, &argp->filter_count, sizeof(int))) + return -EFAULT; + + if (copy_from_user(&flags, &argp->flags, sizeof(int))) + return -EFAULT; + + if (cmd & SIOC_IN) { + } + + for (i=0; i < filter_count; i++) { + if (copy_from_user(&biquad, &argp->biquads[i], + sizeof(struct tas_biquad_ctrl_t))) { + return -EFAULT; + } + + if (cmd & SIOC_IN) { + sync_required[biquad.channel][biquad.filter]=1; + rc=tas3004_write_biquad_shadow(self, biquad.channel, biquad.filter, &biquad.data); + if (rc != 0) return rc; + } + + if (cmd & SIOC_OUT) { + rc=tas3004_read_biquad(self, biquad.channel, biquad.filter, &biquad.data); + if (rc != 0) return rc; + + if (copy_to_user(&argp->biquads[i], &biquad, + sizeof(struct tas_biquad_ctrl_t))) { + return -EFAULT; + } + } + } + + if (cmd & SIOC_IN) { + /* + * This is OK for the tas3004. For the + * tas3001c, going into fast load mode causes + * the treble and bass to be reset to 0dB, and + * volume controls to be muted. + */ + if (flags & TAS_BIQUAD_FAST_LOAD) tas3004_fast_load(self,1); + for (i=0; isuper.shadow; + + if (flags & TAS_DRCE_ABOVE_RATIO) { + self->drce_state.above.expand = drce->above.expand; + if (drce->above.val == (1<<8)) { + self->drce_state.above.val = 1<<8; + shadow[TAS3004_REG_DRC][0] = 0x02; + + } else if (drce->above.expand) { + i=above_threshold_expansion_index(drce->above.val); + self->drce_state.above.val=above_threshold_expansion_ratio[i]; + shadow[TAS3004_REG_DRC][0] = 0x0a + (i<<3); + } else { + i=above_threshold_compression_index(drce->above.val); + self->drce_state.above.val=above_threshold_compression_ratio[i]; + shadow[TAS3004_REG_DRC][0] = 0x08 + (i<<3); + } + } + + if (flags & TAS_DRCE_BELOW_RATIO) { + self->drce_state.below.expand = drce->below.expand; + if (drce->below.val == (1<<8)) { + self->drce_state.below.val = 1<<8; + shadow[TAS3004_REG_DRC][1] = 0x02; + + } else if (drce->below.expand) { + i=below_threshold_expansion_index(drce->below.val); + self->drce_state.below.val=below_threshold_expansion_ratio[i]; + shadow[TAS3004_REG_DRC][1] = 0x08 + (i<<3); + } else { + i=below_threshold_compression_index(drce->below.val); + self->drce_state.below.val=below_threshold_compression_ratio[i]; + shadow[TAS3004_REG_DRC][1] = 0x0a + (i<<3); + } + } + + if (flags & TAS_DRCE_THRESHOLD) { + self->drce_state.threshold=quantize_db(drce->threshold); + shadow[TAS3004_REG_DRC][2] = db_to_regval(self->drce_state.threshold); + } + + if (flags & TAS_DRCE_ENERGY) { + i=time_index(drce->energy); + self->drce_state.energy=time_constants[i]; + shadow[TAS3004_REG_DRC][3] = 0x40 + (i<<4); + } + + if (flags & TAS_DRCE_ATTACK) { + i=time_index(drce->attack); + self->drce_state.attack=time_constants[i]; + shadow[TAS3004_REG_DRC][4] = 0x40 + (i<<4); + } + + if (flags & TAS_DRCE_DECAY) { + i=time_index(drce->decay); + self->drce_state.decay=time_constants[i]; + shadow[TAS3004_REG_DRC][5] = 0x40 + (i<<4); + } + + if (flags & TAS_DRCE_ENABLE) { + self->drce_state.enable = drce->enable; + } + + if (!self->drce_state.enable) { + shadow[TAS3004_REG_DRC][0] |= 0x01; + } + +#ifdef DEBUG_DRCE + printk("DRCE: set [ ENABLE:%x ABOVE:%x/%x BELOW:%x/%x THRESH:%x ENERGY:%x ATTACK:%x DECAY:%x\n", + self->drce_state.enable, + self->drce_state.above.expand,self->drce_state.above.val, + self->drce_state.below.expand,self->drce_state.below.val, + self->drce_state.threshold, + self->drce_state.energy, + self->drce_state.attack, + self->drce_state.decay); + + printk("DRCE: reg [ %02x %02x %02x %02x %02x %02x ]\n", + (unsigned char)shadow[TAS3004_REG_DRC][0], + (unsigned char)shadow[TAS3004_REG_DRC][1], + (unsigned char)shadow[TAS3004_REG_DRC][2], + (unsigned char)shadow[TAS3004_REG_DRC][3], + (unsigned char)shadow[TAS3004_REG_DRC][4], + (unsigned char)shadow[TAS3004_REG_DRC][5]); +#endif + + return tas3004_sync_register(self, TAS3004_REG_DRC); +} + +static int +tas3004_drce_rw( struct tas3004_data_t *self, + u_int cmd, + u_long arg) +{ + int rc; + struct tas_drce_ctrl_t drce_ctrl; + void __user *argp = (void __user *)arg; + + if (copy_from_user(&drce_ctrl, argp, sizeof(struct tas_drce_ctrl_t))) + return -EFAULT; + +#ifdef DEBUG_DRCE + printk("DRCE: input [ FLAGS:%x ENABLE:%x ABOVE:%x/%x BELOW:%x/%x THRESH:%x ENERGY:%x ATTACK:%x DECAY:%x\n", + drce_ctrl.flags, + drce_ctrl.data.enable, + drce_ctrl.data.above.expand,drce_ctrl.data.above.val, + drce_ctrl.data.below.expand,drce_ctrl.data.below.val, + drce_ctrl.data.threshold, + drce_ctrl.data.energy, + drce_ctrl.data.attack, + drce_ctrl.data.decay); +#endif + + if (cmd & SIOC_IN) { + rc = tas3004_update_drce(self, drce_ctrl.flags, &drce_ctrl.data); + if (rc < 0) return rc; + } + + if (cmd & SIOC_OUT) { + if (drce_ctrl.flags & TAS_DRCE_ENABLE) + drce_ctrl.data.enable = self->drce_state.enable; + if (drce_ctrl.flags & TAS_DRCE_ABOVE_RATIO) + drce_ctrl.data.above = self->drce_state.above; + if (drce_ctrl.flags & TAS_DRCE_BELOW_RATIO) + drce_ctrl.data.below = self->drce_state.below; + if (drce_ctrl.flags & TAS_DRCE_THRESHOLD) + drce_ctrl.data.threshold = self->drce_state.threshold; + if (drce_ctrl.flags & TAS_DRCE_ENERGY) + drce_ctrl.data.energy = self->drce_state.energy; + if (drce_ctrl.flags & TAS_DRCE_ATTACK) + drce_ctrl.data.attack = self->drce_state.attack; + if (drce_ctrl.flags & TAS_DRCE_DECAY) + drce_ctrl.data.decay = self->drce_state.decay; + + if (copy_to_user(argp, &drce_ctrl, + sizeof(struct tas_drce_ctrl_t))) { + return -EFAULT; + } + } + + return 0; +} + +static void +tas3004_update_device_parameters(struct tas3004_data_t *self) +{ + char data; + int i; + + if (!self) return; + + if (self->output_id == TAS_OUTPUT_HEADPHONES) { + /* turn on allPass when headphones are plugged in */ + data = 0x02; + } else { + data = 0x00; + } + + tas3004_write_register(self, TAS3004_REG_MCR2, &data, WRITE_NORMAL | FORCE_WRITE); + + for (i=0; tas3004_eq_prefs[i]; i++) { + struct tas_eq_pref_t *eq = tas3004_eq_prefs[i]; + + if (eq->device_id == self->device_id && + (eq->output_id == 0 || eq->output_id == self->output_id) && + (eq->speaker_id == 0 || eq->speaker_id == self->speaker_id)) { + + tas3004_update_drce(self, TAS_DRCE_ALL, eq->drce); + tas3004_write_biquad_list(self, eq->filter_count, TAS_BIQUAD_FAST_LOAD, eq->biquads); + + break; + } + } +} + +static void +tas3004_device_change_handler(struct work_struct *work) +{ + struct tas3004_data_t *self; + self = container_of(work, struct tas3004_data_t, change); + tas3004_update_device_parameters(self); +} + +static int +tas3004_output_device_change( struct tas3004_data_t *self, + int device_id, + int output_id, + int speaker_id) +{ + self->device_id=device_id; + self->output_id=output_id; + self->speaker_id=speaker_id; + + schedule_work(&self->change); + + return 0; +} + +static int +tas3004_device_ioctl( struct tas3004_data_t *self, + u_int cmd, + u_long arg) +{ + uint __user *argp = (void __user *)arg; + switch (cmd) { + case TAS_READ_EQ: + case TAS_WRITE_EQ: + return tas3004_eq_rw(self, cmd, arg); + + case TAS_READ_EQ_LIST: + case TAS_WRITE_EQ_LIST: + return tas3004_eq_list_rw(self, cmd, arg); + + case TAS_READ_EQ_FILTER_COUNT: + put_user(TAS3004_BIQUAD_FILTER_COUNT, argp); + return 0; + + case TAS_READ_EQ_CHANNEL_COUNT: + put_user(TAS3004_BIQUAD_CHANNEL_COUNT, argp); + return 0; + + case TAS_READ_DRCE: + case TAS_WRITE_DRCE: + return tas3004_drce_rw(self, cmd, arg); + + case TAS_READ_DRCE_CAPS: + put_user(TAS_DRCE_ENABLE | + TAS_DRCE_ABOVE_RATIO | + TAS_DRCE_BELOW_RATIO | + TAS_DRCE_THRESHOLD | + TAS_DRCE_ENERGY | + TAS_DRCE_ATTACK | + TAS_DRCE_DECAY, + argp); + return 0; + + case TAS_READ_DRCE_MIN: + case TAS_READ_DRCE_MAX: { + struct tas_drce_ctrl_t drce_ctrl; + const struct tas_drce_t *drce_copy; + + if (copy_from_user(&drce_ctrl, argp, + sizeof(struct tas_drce_ctrl_t))) { + return -EFAULT; + } + + if (cmd == TAS_READ_DRCE_MIN) { + drce_copy=&tas3004_drce_min; + } else { + drce_copy=&tas3004_drce_max; + } + + if (drce_ctrl.flags & TAS_DRCE_ABOVE_RATIO) { + drce_ctrl.data.above=drce_copy->above; + } + if (drce_ctrl.flags & TAS_DRCE_BELOW_RATIO) { + drce_ctrl.data.below=drce_copy->below; + } + if (drce_ctrl.flags & TAS_DRCE_THRESHOLD) { + drce_ctrl.data.threshold=drce_copy->threshold; + } + if (drce_ctrl.flags & TAS_DRCE_ENERGY) { + drce_ctrl.data.energy=drce_copy->energy; + } + if (drce_ctrl.flags & TAS_DRCE_ATTACK) { + drce_ctrl.data.attack=drce_copy->attack; + } + if (drce_ctrl.flags & TAS_DRCE_DECAY) { + drce_ctrl.data.decay=drce_copy->decay; + } + + if (copy_to_user(argp, &drce_ctrl, + sizeof(struct tas_drce_ctrl_t))) { + return -EFAULT; + } + } + } + + return -EINVAL; +} + +static int +tas3004_init_mixer(struct tas3004_data_t *self) +{ + unsigned char mcr = (1<<6)+(2<<4)+(2<<2); + + /* Make sure something answers on the i2c bus */ + if (tas3004_write_register(self, TAS3004_REG_MCR, &mcr, + WRITE_NORMAL | FORCE_WRITE) < 0) + return -1; + + tas3004_fast_load(self, 1); + + (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD0); + (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD1); + (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD2); + (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD3); + (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD4); + (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD5); + (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD6); + + (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD0); + (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD1); + (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD2); + (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD3); + (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD4); + (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD5); + (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD6); + + tas3004_sync_register(self, TAS3004_REG_DRC); + + tas3004_sync_register(self, TAS3004_REG_MCR2); + + tas3004_fast_load(self, 0); + + tas3004_set_mixer_level(self, SOUND_MIXER_VOLUME, VOL_DEFAULT<<8 | VOL_DEFAULT); + tas3004_set_mixer_level(self, SOUND_MIXER_PCM, INPUT_DEFAULT<<8 | INPUT_DEFAULT); + tas3004_set_mixer_level(self, SOUND_MIXER_ALTPCM, 0); + tas3004_set_mixer_level(self, SOUND_MIXER_IMIX, 0); + + tas3004_set_mixer_level(self, SOUND_MIXER_BASS, BASS_DEFAULT); + tas3004_set_mixer_level(self, SOUND_MIXER_TREBLE, TREBLE_DEFAULT); + + tas3004_set_mixer_level(self, SOUND_MIXER_LINE,SW_INPUT_VOLUME_DEFAULT); + + return 0; +} + +static int +tas3004_uninit_mixer(struct tas3004_data_t *self) +{ + tas3004_set_mixer_level(self, SOUND_MIXER_VOLUME, 0); + tas3004_set_mixer_level(self, SOUND_MIXER_PCM, 0); + tas3004_set_mixer_level(self, SOUND_MIXER_ALTPCM, 0); + tas3004_set_mixer_level(self, SOUND_MIXER_IMIX, 0); + + tas3004_set_mixer_level(self, SOUND_MIXER_BASS, 0); + tas3004_set_mixer_level(self, SOUND_MIXER_TREBLE, 0); + + tas3004_set_mixer_level(self, SOUND_MIXER_LINE, 0); + + return 0; +} + +static int +tas3004_init(struct i2c_client *client) +{ + struct tas3004_data_t *self; + size_t sz = sizeof(*self) + (TAS3004_REG_MAX*sizeof(tas_shadow_t)); + char drce_init[] = { 0x69, 0x22, 0x9f, 0xb0, 0x60, 0xa0 }; + char mcr2 = 0; + int i, j; + + self = kzalloc(sz, GFP_KERNEL); + if (!self) + return -ENOMEM; + + self->super.client = client; + self->super.shadow = (tas_shadow_t *)(self+1); + self->output_id = TAS_OUTPUT_HEADPHONES; + + dev_set_drvdata(&client->dev, self); + + for (i = 0; i < TAS3004_BIQUAD_CHANNEL_COUNT; i++) + for (j = 0; jchange, tas3004_device_change_handler); + return 0; +} + +static void +tas3004_uninit(struct tas3004_data_t *self) +{ + tas3004_uninit_mixer(self); + kfree(self); +} + + +struct tas_driver_hooks_t tas3004_hooks = { + .init = (tas_hook_init_t)tas3004_init, + .post_init = (tas_hook_post_init_t)tas3004_init_mixer, + .uninit = (tas_hook_uninit_t)tas3004_uninit, + .get_mixer_level = (tas_hook_get_mixer_level_t)tas3004_get_mixer_level, + .set_mixer_level = (tas_hook_set_mixer_level_t)tas3004_set_mixer_level, + .enter_sleep = (tas_hook_enter_sleep_t)tas3004_enter_sleep, + .leave_sleep = (tas_hook_leave_sleep_t)tas3004_leave_sleep, + .supported_mixers = (tas_hook_supported_mixers_t)tas3004_supported_mixers, + .mixer_is_stereo = (tas_hook_mixer_is_stereo_t)tas3004_mixer_is_stereo, + .stereo_mixers = (tas_hook_stereo_mixers_t)tas3004_stereo_mixers, + .output_device_change = (tas_hook_output_device_change_t)tas3004_output_device_change, + .device_ioctl = (tas_hook_device_ioctl_t)tas3004_device_ioctl +}; diff --git a/trunk/sound/oss/dmasound/tas3004.h b/trunk/sound/oss/dmasound/tas3004.h new file mode 100644 index 000000000000..c6d584bf2ca4 --- /dev/null +++ b/trunk/sound/oss/dmasound/tas3004.h @@ -0,0 +1,77 @@ +/* + * Header file for the i2c/i2s based TA3004 sound chip used + * on some Apple hardware. Also known as "tumbler". + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + * + * Written by Christopher C. Chimelis + */ + +#ifndef _TAS3004_H_ +#define _TAS3004_H_ + +#include + +#include "tas_common.h" +#include "tas_eq_prefs.h" + +/* + * Macros that correspond to the registers that we write to + * when setting the various values. + */ + +#define TAS3004_VERSION "0.3" +#define TAS3004_DATE "20011214" + +#define I2C_DRIVERNAME_TAS3004 "TAS3004 driver V " TAS3004_VERSION +#define I2C_DRIVERID_TAS3004 (I2C_DRIVERID_TAS_BASE+1) + +extern struct tas_driver_hooks_t tas3004_hooks; +extern struct tas_gain_t tas3004_gain; +extern struct tas_eq_pref_t *tas3004_eq_prefs[]; + +enum tas3004_reg_t { + TAS3004_REG_MCR = 0x01, + TAS3004_REG_DRC = 0x02, + + TAS3004_REG_VOLUME = 0x04, + TAS3004_REG_TREBLE = 0x05, + TAS3004_REG_BASS = 0x06, + TAS3004_REG_LEFT_MIXER = 0x07, + TAS3004_REG_RIGHT_MIXER = 0x08, + + TAS3004_REG_LEFT_BIQUAD0 = 0x0a, + TAS3004_REG_LEFT_BIQUAD1 = 0x0b, + TAS3004_REG_LEFT_BIQUAD2 = 0x0c, + TAS3004_REG_LEFT_BIQUAD3 = 0x0d, + TAS3004_REG_LEFT_BIQUAD4 = 0x0e, + TAS3004_REG_LEFT_BIQUAD5 = 0x0f, + TAS3004_REG_LEFT_BIQUAD6 = 0x10, + + TAS3004_REG_RIGHT_BIQUAD0 = 0x13, + TAS3004_REG_RIGHT_BIQUAD1 = 0x14, + TAS3004_REG_RIGHT_BIQUAD2 = 0x15, + TAS3004_REG_RIGHT_BIQUAD3 = 0x16, + TAS3004_REG_RIGHT_BIQUAD4 = 0x17, + TAS3004_REG_RIGHT_BIQUAD5 = 0x18, + TAS3004_REG_RIGHT_BIQUAD6 = 0x19, + + TAS3004_REG_LEFT_LOUD_BIQUAD = 0x21, + TAS3004_REG_RIGHT_LOUD_BIQUAD = 0x22, + + TAS3004_REG_LEFT_LOUD_BIQUAD_GAIN = 0x23, + TAS3004_REG_RIGHT_LOUD_BIQUAD_GAIN = 0x24, + + TAS3004_REG_TEST = 0x29, + + TAS3004_REG_ANALOG_CTRL = 0x40, + TAS3004_REG_TEST1 = 0x41, + TAS3004_REG_TEST2 = 0x42, + TAS3004_REG_MCR2 = 0x43, + + TAS3004_REG_MAX = 0x44 +}; + +#endif /* _TAS3004_H_ */ diff --git a/trunk/sound/oss/dmasound/tas3004_tables.c b/trunk/sound/oss/dmasound/tas3004_tables.c new file mode 100644 index 000000000000..b910e0a66775 --- /dev/null +++ b/trunk/sound/oss/dmasound/tas3004_tables.c @@ -0,0 +1,301 @@ +#include "tas3004.h" +#include "tas_eq_prefs.h" + +static struct tas_drce_t eqp_17_1_0_drce={ + .enable = 1, + .above = { .val = 3.0 * (1<<8), .expand = 0 }, + .below = { .val = 1.0 * (1<<8), .expand = 0 }, + .threshold = -19.12 * (1<<8), + .energy = 2.4 * (1<<12), + .attack = 0.013 * (1<<12), + .decay = 0.212 * (1<<12), +}; + +static struct tas_biquad_ctrl_t eqp_17_1_0_biquads[]={ + { .channel = 0, .filter = 0, .data = { .coeff = { 0x0fd0d4, 0xe05e56, 0x0fd0d4, 0xe05ee1, 0x0fa234 } } }, + { .channel = 0, .filter = 1, .data = { .coeff = { 0x0910d7, 0x088e1a, 0x030651, 0x01dcb1, 0x02c892 } } }, + { .channel = 0, .filter = 2, .data = { .coeff = { 0x0ff895, 0xe0970b, 0x0f7f00, 0xe0970b, 0x0f7795 } } }, + { .channel = 0, .filter = 3, .data = { .coeff = { 0x0fd1c4, 0xe1ac22, 0x0ec8cf, 0xe1ac22, 0x0e9a94 } } }, + { .channel = 0, .filter = 4, .data = { .coeff = { 0x0f7c1c, 0xe3cc03, 0x0df786, 0xe3cc03, 0x0d73a2 } } }, + { .channel = 0, .filter = 5, .data = { .coeff = { 0x11fb92, 0xf5a1a0, 0x073cd2, 0xf5a1a0, 0x093865 } } }, + { .channel = 0, .filter = 6, .data = { .coeff = { 0x0e17a9, 0x068b6c, 0x08a0e5, 0x068b6c, 0x06b88e } } }, + + { .channel = 1, .filter = 0, .data = { .coeff = { 0x0fd0d4, 0xe05e56, 0x0fd0d4, 0xe05ee1, 0x0fa234 } } }, + { .channel = 1, .filter = 1, .data = { .coeff = { 0x0910d7, 0x088e1a, 0x030651, 0x01dcb1, 0x02c892 } } }, + { .channel = 1, .filter = 2, .data = { .coeff = { 0x0ff895, 0xe0970b, 0x0f7f00, 0xe0970b, 0x0f7795 } } }, + { .channel = 1, .filter = 3, .data = { .coeff = { 0x0fd1c4, 0xe1ac22, 0x0ec8cf, 0xe1ac22, 0x0e9a94 } } }, + { .channel = 1, .filter = 4, .data = { .coeff = { 0x0f7c1c, 0xe3cc03, 0x0df786, 0xe3cc03, 0x0d73a2 } } }, + { .channel = 1, .filter = 5, .data = { .coeff = { 0x11fb92, 0xf5a1a0, 0x073cd2, 0xf5a1a0, 0x093865 } } }, + { .channel = 1, .filter = 6, .data = { .coeff = { 0x0e17a9, 0x068b6c, 0x08a0e5, 0x068b6c, 0x06b88e } } } +}; + +static struct tas_eq_pref_t eqp_17_1_0 = { + .sample_rate = 44100, + .device_id = 0x17, + .output_id = TAS_OUTPUT_INTERNAL_SPKR, + .speaker_id = 0x00, + + .drce = &eqp_17_1_0_drce, + + .filter_count = 14, + .biquads = eqp_17_1_0_biquads +}; + +/* ======================================================================== */ + +static struct tas_drce_t eqp_18_1_0_drce={ + .enable = 1, + .above = { .val = 3.0 * (1<<8), .expand = 0 }, + .below = { .val = 1.0 * (1<<8), .expand = 0 }, + .threshold = -13.14 * (1<<8), + .energy = 2.4 * (1<<12), + .attack = 0.013 * (1<<12), + .decay = 0.212 * (1<<12), +}; + +static struct tas_biquad_ctrl_t eqp_18_1_0_biquads[]={ + { .channel = 0, .filter = 0, .data = { .coeff = { 0x0f5514, 0xe155d7, 0x0f5514, 0xe15cfa, 0x0eb14b } } }, + { .channel = 0, .filter = 1, .data = { .coeff = { 0x06ec33, 0x02abe3, 0x015eef, 0xf764d9, 0x03922d } } }, + { .channel = 0, .filter = 2, .data = { .coeff = { 0x0ef5f2, 0xe67d1f, 0x0bcf37, 0xe67d1f, 0x0ac529 } } }, + { .channel = 0, .filter = 3, .data = { .coeff = { 0x0db050, 0xe5be4d, 0x0d0c78, 0xe5be4d, 0x0abcc8 } } }, + { .channel = 0, .filter = 4, .data = { .coeff = { 0x0f1298, 0xe64ec6, 0x0cc03e, 0xe64ec6, 0x0bd2d7 } } }, + { .channel = 0, .filter = 5, .data = { .coeff = { 0x0c641a, 0x06537a, 0x08d155, 0x06537a, 0x053570 } } }, + { .channel = 0, .filter = 6, .data = { .coeff = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } }, + + { .channel = 1, .filter = 0, .data = { .coeff = { 0x0f5514, 0xe155d7, 0x0f5514, 0xe15cfa, 0x0eb14b } } }, + { .channel = 1, .filter = 1, .data = { .coeff = { 0x06ec33, 0x02abe3, 0x015eef, 0xf764d9, 0x03922d } } }, + { .channel = 1, .filter = 2, .data = { .coeff = { 0x0ef5f2, 0xe67d1f, 0x0bcf37, 0xe67d1f, 0x0ac529 } } }, + { .channel = 1, .filter = 3, .data = { .coeff = { 0x0db050, 0xe5be4d, 0x0d0c78, 0xe5be4d, 0x0abcc8 } } }, + { .channel = 1, .filter = 4, .data = { .coeff = { 0x0f1298, 0xe64ec6, 0x0cc03e, 0xe64ec6, 0x0bd2d7 } } }, + { .channel = 1, .filter = 5, .data = { .coeff = { 0x0c641a, 0x06537a, 0x08d155, 0x06537a, 0x053570 } } }, + { .channel = 1, .filter = 6, .data = { .coeff = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 } } } +}; + +static struct tas_eq_pref_t eqp_18_1_0 = { + .sample_rate = 44100, + .device_id = 0x18, + .output_id = TAS_OUTPUT_INTERNAL_SPKR, + .speaker_id = 0x00, + + .drce = &eqp_18_1_0_drce, + + .filter_count = 14, + .biquads = eqp_18_1_0_biquads +}; + +/* ======================================================================== */ + +static struct tas_drce_t eqp_1a_1_0_drce={ + .enable = 1, + .above = { .val = 3.0 * (1<<8), .expand = 0 }, + .below = { .val = 1.0 * (1<<8), .expand = 0 }, + .threshold = -10.75 * (1<<8), + .energy = 2.4 * (1<<12), + .attack = 0.013 * (1<<12), + .decay = 0.212 * (1<<12), +}; + +static struct tas_biquad_ctrl_t eqp_1a_1_0_biquads[]={ + { .channel = 0, .filter = 0, .data = { .coeff = { 0x0fb8fd, 0xe08e04, 0x0fb8fd, 0xe08f40, 0x0f7336 } } }, + { .channel = 0, .filter = 1, .data = { .coeff = { 0x06371d, 0x0c6e3a, 0x06371d, 0x05bfd3, 0x031ca2 } } }, + { .channel = 0, .filter = 2, .data = { .coeff = { 0x0fa1c0, 0xe18692, 0x0f030e, 0xe18692, 0x0ea4ce } } }, + { .channel = 0, .filter = 3, .data = { .coeff = { 0x0fe495, 0xe17eff, 0x0f0452, 0xe17eff, 0x0ee8e7 } } }, + { .channel = 0, .filter = 4, .data = { .coeff = { 0x100857, 0xe7e71c, 0x0e9599, 0xe7e71c, 0x0e9df1 } } }, + { .channel = 0, .filter = 5, .data = { .coeff = { 0x0fb26e, 0x06a82c, 0x0db2b4, 0x06a82c, 0x0d6522 } } }, + { .channel = 0, .filter = 6, .data = { .coeff = { 0x11419d, 0xf06cbf, 0x0a4f6e, 0xf06cbf, 0x0b910c } } }, + + { .channel = 1, .filter = 0, .data = { .coeff = { 0x0fb8fd, 0xe08e04, 0x0fb8fd, 0xe08f40, 0x0f7336 } } }, + { .channel = 1, .filter = 1, .data = { .coeff = { 0x06371d, 0x0c6e3a, 0x06371d, 0x05bfd3, 0x031ca2 } } }, + { .channel = 1, .filter = 2, .data = { .coeff = { 0x0fa1c0, 0xe18692, 0x0f030e, 0xe18692, 0x0ea4ce } } }, + { .channel = 1, .filter = 3, .data = { .coeff = { 0x0fe495, 0xe17eff, 0x0f0452, 0xe17eff, 0x0ee8e7 } } }, + { .channel = 1, .filter = 4, .data = { .coeff = { 0x100857, 0xe7e71c, 0x0e9599, 0xe7e71c, 0x0e9df1 } } }, + { .channel = 1, .filter = 5, .data = { .coeff = { 0x0fb26e, 0x06a82c, 0x0db2b4, 0x06a82c, 0x0d6522 } } }, + { .channel = 1, .filter = 6, .data = { .coeff = { 0x11419d, 0xf06cbf, 0x0a4f6e, 0xf06cbf, 0x0b910c } } } +}; + +static struct tas_eq_pref_t eqp_1a_1_0 = { + .sample_rate = 44100, + .device_id = 0x1a, + .output_id = TAS_OUTPUT_INTERNAL_SPKR, + .speaker_id = 0x00, + + .drce = &eqp_1a_1_0_drce, + + .filter_count = 14, + .biquads = eqp_1a_1_0_biquads +}; + +/* ======================================================================== */ + +static struct tas_drce_t eqp_1c_1_0_drce={ + .enable = 1, + .above = { .val = 3.0 * (1<<8), .expand = 0 }, + .below = { .val = 1.0 * (1<<8), .expand = 0 }, + .threshold = -14.34 * (1<<8), + .energy = 2.4 * (1<<12), + .attack = 0.013 * (1<<12), + .decay = 0.212 * (1<<12), +}; + +static struct tas_biquad_ctrl_t eqp_1c_1_0_biquads[]={ + { .channel = 0, .filter = 0, .data = { .coeff = { 0x0f4f95, 0xe160d4, 0x0f4f95, 0xe1686e, 0x0ea6c5 } } }, + { .channel = 0, .filter = 1, .data = { .coeff = { 0x066b92, 0x0290d4, 0x0148a0, 0xf6853f, 0x03bfc7 } } }, + { .channel = 0, .filter = 2, .data = { .coeff = { 0x0f57dc, 0xe51c91, 0x0dd1cb, 0xe51c91, 0x0d29a8 } } }, + { .channel = 0, .filter = 3, .data = { .coeff = { 0x0df1cb, 0xe4fa84, 0x0d7cdc, 0xe4fa84, 0x0b6ea7 } } }, + { .channel = 0, .filter = 4, .data = { .coeff = { 0x0eba36, 0xe6aa48, 0x0b9f52, 0xe6aa48, 0x0a5989 } } }, + { .channel = 0, .filter = 5, .data = { .coeff = { 0x0caf02, 0x05ef9d, 0x084beb, 0x05ef9d, 0x04faee } } }, + { .channel = 0, .filter = 6, .data = { .coeff = { 0x0fc686, 0xe22947, 0x0e4b5d, 0xe22947, 0x0e11e4 } } }, + + { .channel = 1, .filter = 0, .data = { .coeff = { 0x0f4f95, 0xe160d4, 0x0f4f95, 0xe1686e, 0x0ea6c5 } } }, + { .channel = 1, .filter = 1, .data = { .coeff = { 0x066b92, 0x0290d4, 0x0148a0, 0xf6853f, 0x03bfc7 } } }, + { .channel = 1, .filter = 2, .data = { .coeff = { 0x0f57dc, 0xe51c91, 0x0dd1cb, 0xe51c91, 0x0d29a8 } } }, + { .channel = 1, .filter = 3, .data = { .coeff = { 0x0df1cb, 0xe4fa84, 0x0d7cdc, 0xe4fa84, 0x0b6ea7 } } }, + { .channel = 1, .filter = 4, .data = { .coeff = { 0x0eba36, 0xe6aa48, 0x0b9f52, 0xe6aa48, 0x0a5989 } } }, + { .channel = 1, .filter = 5, .data = { .coeff = { 0x0caf02, 0x05ef9d, 0x084beb, 0x05ef9d, 0x04faee } } }, + { .channel = 1, .filter = 6, .data = { .coeff = { 0x0fc686, 0xe22947, 0x0e4b5d, 0xe22947, 0x0e11e4 } } } +}; + +static struct tas_eq_pref_t eqp_1c_1_0 = { + .sample_rate = 44100, + .device_id = 0x1c, + .output_id = TAS_OUTPUT_INTERNAL_SPKR, + .speaker_id = 0x00, + + .drce = &eqp_1c_1_0_drce, + + .filter_count = 14, + .biquads = eqp_1c_1_0_biquads +}; + +/* ======================================================================== */ + +static uint tas3004_master_tab[]={ + 0x0, 0x75, 0x9c, 0xbb, + 0xdb, 0xfb, 0x11e, 0x143, + 0x16b, 0x196, 0x1c3, 0x1f5, + 0x229, 0x263, 0x29f, 0x2e1, + 0x328, 0x373, 0x3c5, 0x41b, + 0x478, 0x4dc, 0x547, 0x5b8, + 0x633, 0x6b5, 0x740, 0x7d5, + 0x873, 0x91c, 0x9d2, 0xa92, + 0xb5e, 0xc39, 0xd22, 0xe19, + 0xf20, 0x1037, 0x1161, 0x129e, + 0x13ed, 0x1551, 0x16ca, 0x185d, + 0x1a08, 0x1bcc, 0x1dac, 0x1fa7, + 0x21c1, 0x23fa, 0x2655, 0x28d6, + 0x2b7c, 0x2e4a, 0x3141, 0x3464, + 0x37b4, 0x3b35, 0x3ee9, 0x42d3, + 0x46f6, 0x4b53, 0x4ff0, 0x54ce, + 0x59f2, 0x5f5f, 0x6519, 0x6b24, + 0x7183, 0x783c, 0x7f53, 0x86cc, + 0x8ead, 0x96fa, 0x9fba, 0xa8f2, + 0xb2a7, 0xbce1, 0xc7a5, 0xd2fa, + 0xdee8, 0xeb75, 0xf8aa, 0x1068e, + 0x1152a, 0x12487, 0x134ad, 0x145a5, + 0x1577b, 0x16a37, 0x17df5, 0x192bd, + 0x1a890, 0x1bf7b, 0x1d78d, 0x1f0d1, + 0x20b55, 0x22727, 0x24456, 0x262f2, + 0x2830b +}; + +static uint tas3004_mixer_tab[]={ + 0x0, 0x748, 0x9be, 0xbaf, + 0xda4, 0xfb1, 0x11de, 0x1431, + 0x16ad, 0x1959, 0x1c37, 0x1f4b, + 0x2298, 0x2628, 0x29fb, 0x2e12, + 0x327d, 0x3734, 0x3c47, 0x41b4, + 0x4787, 0x4dbe, 0x546d, 0x5b86, + 0x632e, 0x6b52, 0x7400, 0x7d54, + 0x873b, 0x91c6, 0x9d1a, 0xa920, + 0xb5e5, 0xc38c, 0xd21b, 0xe18f, + 0xf1f5, 0x1036a, 0x1160f, 0x129d6, + 0x13ed0, 0x1550c, 0x16ca0, 0x185c9, + 0x1a07b, 0x1bcc3, 0x1dab9, 0x1fa75, + 0x21c0f, 0x23fa3, 0x26552, 0x28d64, + 0x2b7c9, 0x2e4a2, 0x31411, 0x3463b, + 0x37b44, 0x3b353, 0x3ee94, 0x42d30, + 0x46f55, 0x4b533, 0x4fefc, 0x54ce5, + 0x59f25, 0x5f5f6, 0x65193, 0x6b23c, + 0x71835, 0x783c3, 0x7f52c, 0x86cc0, + 0x8eacc, 0x96fa5, 0x9fba0, 0xa8f1a, + 0xb2a71, 0xbce0a, 0xc7a4a, 0xd2fa0, + 0xdee7b, 0xeb752, 0xf8a9f, 0x1068e4, + 0x1152a3, 0x12486a, 0x134ac8, 0x145a55, + 0x1577ac, 0x16a370, 0x17df51, 0x192bc2, + 0x1a88f8, 0x1bf7b7, 0x1d78c9, 0x1f0d04, + 0x20b542, 0x227268, 0x244564, 0x262f26, + 0x2830af +}; + +static uint tas3004_treble_tab[]={ + 0x96, 0x95, 0x95, 0x94, + 0x93, 0x92, 0x92, 0x91, + 0x90, 0x90, 0x8f, 0x8e, + 0x8d, 0x8d, 0x8c, 0x8b, + 0x8a, 0x8a, 0x89, 0x88, + 0x88, 0x87, 0x86, 0x85, + 0x85, 0x84, 0x83, 0x83, + 0x82, 0x81, 0x80, 0x80, + 0x7f, 0x7e, 0x7e, 0x7d, + 0x7c, 0x7b, 0x7b, 0x7a, + 0x79, 0x78, 0x78, 0x77, + 0x76, 0x76, 0x75, 0x74, + 0x73, 0x73, 0x72, 0x71, + 0x71, 0x68, 0x45, 0x5b, + 0x6d, 0x6c, 0x6b, 0x6a, + 0x69, 0x68, 0x67, 0x66, + 0x65, 0x63, 0x62, 0x62, + 0x60, 0x5e, 0x5c, 0x5b, + 0x59, 0x57, 0x55, 0x53, + 0x52, 0x4f, 0x4d, 0x4a, + 0x48, 0x46, 0x43, 0x40, + 0x3d, 0x3a, 0x36, 0x33, + 0x2f, 0x2c, 0x27, 0x23, + 0x1f, 0x1a, 0x15, 0xf, + 0x8, 0x5, 0x2, 0x1, + 0x1 +}; + +static uint tas3004_bass_tab[]={ + 0x96, 0x95, 0x95, 0x94, + 0x93, 0x92, 0x92, 0x91, + 0x90, 0x90, 0x8f, 0x8e, + 0x8d, 0x8d, 0x8c, 0x8b, + 0x8a, 0x8a, 0x89, 0x88, + 0x88, 0x87, 0x86, 0x85, + 0x85, 0x84, 0x83, 0x83, + 0x82, 0x81, 0x80, 0x80, + 0x7f, 0x7e, 0x7e, 0x7d, + 0x7c, 0x7b, 0x7b, 0x7a, + 0x79, 0x78, 0x78, 0x77, + 0x76, 0x76, 0x75, 0x74, + 0x73, 0x73, 0x72, 0x71, + 0x70, 0x6f, 0x6e, 0x6d, + 0x6c, 0x6b, 0x6a, 0x6a, + 0x69, 0x67, 0x66, 0x66, + 0x65, 0x63, 0x62, 0x62, + 0x61, 0x60, 0x5e, 0x5d, + 0x5b, 0x59, 0x57, 0x55, + 0x53, 0x51, 0x4f, 0x4c, + 0x4a, 0x48, 0x46, 0x44, + 0x41, 0x3e, 0x3b, 0x38, + 0x36, 0x33, 0x2f, 0x2b, + 0x28, 0x24, 0x20, 0x1c, + 0x17, 0x12, 0xd, 0x7, + 0x1 +}; + +struct tas_gain_t tas3004_gain={ + .master = tas3004_master_tab, + .treble = tas3004_treble_tab, + .bass = tas3004_bass_tab, + .mixer = tas3004_mixer_tab +}; + +struct tas_eq_pref_t *tas3004_eq_prefs[]={ + &eqp_17_1_0, + &eqp_18_1_0, + &eqp_1a_1_0, + &eqp_1c_1_0, + NULL +}; diff --git a/trunk/sound/oss/dmasound/tas_common.c b/trunk/sound/oss/dmasound/tas_common.c new file mode 100644 index 000000000000..b295ef682192 --- /dev/null +++ b/trunk/sound/oss/dmasound/tas_common.c @@ -0,0 +1,214 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tas_common.h" + +#define CALL0(proc) \ + do { \ + struct tas_data_t *self; \ + if (!tas_client || driver_hooks == NULL) \ + return -1; \ + self = dev_get_drvdata(&tas_client->dev); \ + if (driver_hooks->proc) \ + return driver_hooks->proc(self); \ + else \ + return -EINVAL; \ + } while (0) + +#define CALL(proc,arg...) \ + do { \ + struct tas_data_t *self; \ + if (!tas_client || driver_hooks == NULL) \ + return -1; \ + self = dev_get_drvdata(&tas_client->dev); \ + if (driver_hooks->proc) \ + return driver_hooks->proc(self, ## arg); \ + else \ + return -EINVAL; \ + } while (0) + + +static u8 tas_i2c_address = 0x34; +static struct i2c_client *tas_client; + +static int tas_attach_adapter(struct i2c_adapter *); +static int tas_detach_client(struct i2c_client *); + +struct i2c_driver tas_driver = { + .driver = { + .name = "tas", + }, + .attach_adapter = tas_attach_adapter, + .detach_client = tas_detach_client, +}; + +struct tas_driver_hooks_t *driver_hooks; + +int +tas_register_driver(struct tas_driver_hooks_t *hooks) +{ + driver_hooks = hooks; + return 0; +} + +int +tas_get_mixer_level(int mixer, uint *level) +{ + CALL(get_mixer_level,mixer,level); +} + +int +tas_set_mixer_level(int mixer,uint level) +{ + CALL(set_mixer_level,mixer,level); +} + +int +tas_enter_sleep(void) +{ + CALL0(enter_sleep); +} + +int +tas_leave_sleep(void) +{ + CALL0(leave_sleep); +} + +int +tas_supported_mixers(void) +{ + CALL0(supported_mixers); +} + +int +tas_mixer_is_stereo(int mixer) +{ + CALL(mixer_is_stereo,mixer); +} + +int +tas_stereo_mixers(void) +{ + CALL0(stereo_mixers); +} + +int +tas_output_device_change(int device_id,int layout_id,int speaker_id) +{ + CALL(output_device_change,device_id,layout_id,speaker_id); +} + +int +tas_device_ioctl(u_int cmd, u_long arg) +{ + CALL(device_ioctl,cmd,arg); +} + +int +tas_post_init(void) +{ + CALL0(post_init); +} + +static int +tas_detect_client(struct i2c_adapter *adapter, int address) +{ + static const char *client_name = "tas Digital Equalizer"; + struct i2c_client *new_client; + int rc = -ENODEV; + + if (!driver_hooks) { + printk(KERN_ERR "tas_detect_client called with no hooks !\n"); + return -ENODEV; + } + + new_client = kzalloc(sizeof(*new_client), GFP_KERNEL); + if (!new_client) + return -ENOMEM; + + new_client->addr = address; + new_client->adapter = adapter; + new_client->driver = &tas_driver; + strlcpy(new_client->name, client_name, DEVICE_NAME_SIZE); + + if (driver_hooks->init(new_client)) + goto bail; + + /* Tell the i2c layer a new client has arrived */ + if (i2c_attach_client(new_client)) { + driver_hooks->uninit(dev_get_drvdata(&new_client->dev)); + goto bail; + } + + tas_client = new_client; + return 0; + bail: + tas_client = NULL; + kfree(new_client); + return rc; +} + +static int +tas_attach_adapter(struct i2c_adapter *adapter) +{ + if (!strncmp(adapter->name, "mac-io", 6)) + return tas_detect_client(adapter, tas_i2c_address); + return 0; +} + +static int +tas_detach_client(struct i2c_client *client) +{ + if (client == tas_client) { + driver_hooks->uninit(dev_get_drvdata(&client->dev)); + + i2c_detach_client(client); + kfree(client); + } + return 0; +} + +void +tas_cleanup(void) +{ + i2c_del_driver(&tas_driver); +} + +int __init +tas_init(int driver_id, const char *driver_name) +{ + const u32* paddr; + struct device_node *tas_node; + + printk(KERN_INFO "tas driver [%s])\n", driver_name); + +#ifndef CONFIG_I2C_POWERMAC + request_module("i2c-powermac"); +#endif + tas_node = of_find_node_by_name("deq"); + if (tas_node == NULL) + return -ENODEV; + paddr = of_get_property(tas_node, "i2c-address", NULL); + if (paddr) { + tas_i2c_address = (*paddr) >> 1; + printk(KERN_INFO "using i2c address: 0x%x from device-tree\n", + tas_i2c_address); + } else + printk(KERN_INFO "using i2c address: 0x%x (default)\n", + tas_i2c_address); + of_node_put(tas_node); + + return i2c_add_driver(&tas_driver); +} diff --git a/trunk/sound/oss/dmasound/tas_common.h b/trunk/sound/oss/dmasound/tas_common.h new file mode 100644 index 000000000000..0741c28e56ce --- /dev/null +++ b/trunk/sound/oss/dmasound/tas_common.h @@ -0,0 +1,284 @@ +#ifndef _TAS_COMMON_H_ +#define _TAS_COMMON_H_ + +#include +#include +#include + +#define I2C_DRIVERID_TAS_BASE (0xFEBA) + +#define SET_4_20(shadow, offset, val) \ + do { \ + (shadow)[(offset)+0] = ((val) >> 16) & 0xff; \ + (shadow)[(offset)+1] = ((val) >> 8) & 0xff; \ + (shadow)[(offset)+2] = ((val) >> 0) & 0xff; \ + } while (0) + +#define GET_4_20(shadow, offset) \ + (((u_int)((shadow)[(offset)+0]) << 16) | \ + ((u_int)((shadow)[(offset)+1]) << 8) | \ + ((u_int)((shadow)[(offset)+2]) << 0)) + + +#define TAS_BIQUAD_FAST_LOAD 0x01 + +#define TAS_DRCE_ENABLE 0x01 +#define TAS_DRCE_ABOVE_RATIO 0x02 +#define TAS_DRCE_BELOW_RATIO 0x04 +#define TAS_DRCE_THRESHOLD 0x08 +#define TAS_DRCE_ENERGY 0x10 +#define TAS_DRCE_ATTACK 0x20 +#define TAS_DRCE_DECAY 0x40 + +#define TAS_DRCE_ALL 0x7f + + +#define TAS_OUTPUT_HEADPHONES 0x00 +#define TAS_OUTPUT_INTERNAL_SPKR 0x01 +#define TAS_OUTPUT_EXTERNAL_SPKR 0x02 + + +union tas_biquad_t { + struct { + int b0,b1,b2,a1,a2; + } coeff; + int buf[5]; +}; + +struct tas_biquad_ctrl_t { + u_int channel:4; + u_int filter:4; + + union tas_biquad_t data; +}; + +struct tas_biquad_ctrl_list_t { + int flags; + int filter_count; + struct tas_biquad_ctrl_t biquads[0]; +}; + +struct tas_ratio_t { + unsigned short val; /* 8.8 */ + unsigned short expand; /* 0 = compress, !0 = expand. */ +}; + +struct tas_drce_t { + unsigned short enable; + struct tas_ratio_t above; + struct tas_ratio_t below; + short threshold; /* dB, 8.8 signed */ + unsigned short energy; /* seconds, 4.12 unsigned */ + unsigned short attack; /* seconds, 4.12 unsigned */ + unsigned short decay; /* seconds, 4.12 unsigned */ +}; + +struct tas_drce_ctrl_t { + uint flags; + + struct tas_drce_t data; +}; + +struct tas_gain_t +{ + unsigned int *master; + unsigned int *treble; + unsigned int *bass; + unsigned int *mixer; +}; + +typedef char tas_shadow_t[0x45]; + +struct tas_data_t +{ + struct i2c_client *client; + tas_shadow_t *shadow; + uint mixer[SOUND_MIXER_NRDEVICES]; +}; + +typedef int (*tas_hook_init_t)(struct i2c_client *); +typedef int (*tas_hook_post_init_t)(struct tas_data_t *); +typedef void (*tas_hook_uninit_t)(struct tas_data_t *); + +typedef int (*tas_hook_get_mixer_level_t)(struct tas_data_t *,int,uint *); +typedef int (*tas_hook_set_mixer_level_t)(struct tas_data_t *,int,uint); + +typedef int (*tas_hook_enter_sleep_t)(struct tas_data_t *); +typedef int (*tas_hook_leave_sleep_t)(struct tas_data_t *); + +typedef int (*tas_hook_supported_mixers_t)(struct tas_data_t *); +typedef int (*tas_hook_mixer_is_stereo_t)(struct tas_data_t *,int); +typedef int (*tas_hook_stereo_mixers_t)(struct tas_data_t *); + +typedef int (*tas_hook_output_device_change_t)(struct tas_data_t *,int,int,int); +typedef int (*tas_hook_device_ioctl_t)(struct tas_data_t *,u_int,u_long); + +struct tas_driver_hooks_t { + /* + * All hardware initialisation must be performed in + * post_init(), as tas_dmasound_init() does a hardware reset. + * + * init() is called before tas_dmasound_init() so that + * ouput_device_change() is always called after i2c driver + * initialisation. The implication is that + * output_device_change() must cope with the fact that it + * may be called before post_init(). + */ + + tas_hook_init_t init; + tas_hook_post_init_t post_init; + tas_hook_uninit_t uninit; + + tas_hook_get_mixer_level_t get_mixer_level; + tas_hook_set_mixer_level_t set_mixer_level; + + tas_hook_enter_sleep_t enter_sleep; + tas_hook_leave_sleep_t leave_sleep; + + tas_hook_supported_mixers_t supported_mixers; + tas_hook_mixer_is_stereo_t mixer_is_stereo; + tas_hook_stereo_mixers_t stereo_mixers; + + tas_hook_output_device_change_t output_device_change; + tas_hook_device_ioctl_t device_ioctl; +}; + +enum tas_write_mode_t { + WRITE_HW = 0x01, + WRITE_SHADOW = 0x02, + WRITE_NORMAL = 0x03, + FORCE_WRITE = 0x04 +}; + +static inline uint +tas_mono_to_stereo(uint mono) +{ + mono &=0xff; + return mono | (mono<<8); +} + +/* + * Todo: make these functions a bit more efficient ! + */ +static inline int +tas_write_register( struct tas_data_t *self, + uint reg_num, + uint reg_width, + char *data, + uint write_mode) +{ + int rc; + + if (reg_width==0 || data==NULL || self==NULL) + return -EINVAL; + if (!(write_mode & FORCE_WRITE) && + !memcmp(data,self->shadow[reg_num],reg_width)) + return 0; + + if (write_mode & WRITE_SHADOW) + memcpy(self->shadow[reg_num],data,reg_width); + if (write_mode & WRITE_HW) { + rc=i2c_smbus_write_i2c_block_data(self->client, + reg_num, + reg_width, + data); + if (rc < 0) { + printk("tas: I2C block write failed \n"); + return rc; + } + } + return 0; +} + +static inline int +tas_sync_register( struct tas_data_t *self, + uint reg_num, + uint reg_width) +{ + int rc; + + if (reg_width==0 || self==NULL) + return -EINVAL; + rc=i2c_smbus_write_i2c_block_data(self->client, + reg_num, + reg_width, + self->shadow[reg_num]); + if (rc < 0) { + printk("tas: I2C block write failed \n"); + return rc; + } + return 0; +} + +static inline int +tas_write_byte_register( struct tas_data_t *self, + uint reg_num, + char data, + uint write_mode) +{ + if (self==NULL) + return -1; + if (!(write_mode & FORCE_WRITE) && data != self->shadow[reg_num][0]) + return 0; + if (write_mode & WRITE_SHADOW) + self->shadow[reg_num][0]=data; + if (write_mode & WRITE_HW) { + if (i2c_smbus_write_byte_data(self->client, reg_num, data) < 0) { + printk("tas: I2C byte write failed \n"); + return -1; + } + } + return 0; +} + +static inline int +tas_sync_byte_register( struct tas_data_t *self, + uint reg_num, + uint reg_width) +{ + if (reg_width==0 || self==NULL) + return -1; + if (i2c_smbus_write_byte_data( + self->client, reg_num, self->shadow[reg_num][0]) < 0) { + printk("tas: I2C byte write failed \n"); + return -1; + } + return 0; +} + +static inline int +tas_read_register( struct tas_data_t *self, + uint reg_num, + uint reg_width, + char *data) +{ + if (reg_width==0 || data==NULL || self==NULL) + return -1; + memcpy(data,self->shadow[reg_num],reg_width); + return 0; +} + +extern int tas_register_driver(struct tas_driver_hooks_t *hooks); + +extern int tas_get_mixer_level(int mixer,uint *level); +extern int tas_set_mixer_level(int mixer,uint level); +extern int tas_enter_sleep(void); +extern int tas_leave_sleep(void); +extern int tas_supported_mixers(void); +extern int tas_mixer_is_stereo(int mixer); +extern int tas_stereo_mixers(void); +extern int tas_output_device_change(int,int,int); +extern int tas_device_ioctl(u_int, u_long); + +extern void tas_cleanup(void); +extern int tas_init(int driver_id,const char *driver_name); +extern int tas_post_init(void); + +#endif /* _TAS_COMMON_H_ */ +/* + * Local Variables: + * tab-width: 8 + * indent-tabs-mode: t + * c-basic-offset: 8 + * End: + */ diff --git a/trunk/sound/oss/dmasound/tas_eq_prefs.h b/trunk/sound/oss/dmasound/tas_eq_prefs.h new file mode 100644 index 000000000000..3a994eda6abc --- /dev/null +++ b/trunk/sound/oss/dmasound/tas_eq_prefs.h @@ -0,0 +1,24 @@ +#ifndef _TAS_EQ_PREFS_H_ +#define _TAS_EQ_PREFS_H_ + +struct tas_eq_pref_t { + u_int sample_rate; + u_int device_id; + u_int output_id; + u_int speaker_id; + + struct tas_drce_t *drce; + + u_int filter_count; + struct tas_biquad_ctrl_t *biquads; +}; + +#endif /* _TAS_EQ_PREFS_H_ */ + +/* + * Local Variables: + * tab-width: 8 + * indent-tabs-mode: t + * c-basic-offset: 8 + * End: + */ diff --git a/trunk/sound/oss/dmasound/tas_ioctl.h b/trunk/sound/oss/dmasound/tas_ioctl.h new file mode 100644 index 000000000000..9d12b373b4a9 --- /dev/null +++ b/trunk/sound/oss/dmasound/tas_ioctl.h @@ -0,0 +1,23 @@ +#ifndef _TAS_IOCTL_H_ +#define _TAS_IOCTL_H_ + +#include + + +#define TAS_READ_EQ _SIOR('t',0,struct tas_biquad_ctrl_t) +#define TAS_WRITE_EQ _SIOW('t',0,struct tas_biquad_ctrl_t) + +#define TAS_READ_EQ_LIST _SIOR('t',1,struct tas_biquad_ctrl_t) +#define TAS_WRITE_EQ_LIST _SIOW('t',1,struct tas_biquad_ctrl_t) + +#define TAS_READ_EQ_FILTER_COUNT _SIOR('t',2,int) +#define TAS_READ_EQ_CHANNEL_COUNT _SIOR('t',3,int) + +#define TAS_READ_DRCE _SIOR('t',4,struct tas_drce_ctrl_t) +#define TAS_WRITE_DRCE _SIOW('t',4,struct tas_drce_ctrl_t) + +#define TAS_READ_DRCE_CAPS _SIOR('t',5,int) +#define TAS_READ_DRCE_MIN _SIOR('t',6,int) +#define TAS_READ_DRCE_MAX _SIOR('t',7,int) + +#endif diff --git a/trunk/sound/oss/dmasound/trans_16.c b/trunk/sound/oss/dmasound/trans_16.c new file mode 100644 index 000000000000..ca973ac2a30a --- /dev/null +++ b/trunk/sound/oss/dmasound/trans_16.c @@ -0,0 +1,898 @@ +/* + * linux/sound/oss/dmasound/trans_16.c + * + * 16 bit translation routines. Only used by Power mac at present. + * + * See linux/sound/oss/dmasound/dmasound_core.c for copyright and + * history prior to 08/02/2001. + * + * 08/02/2001 Iain Sandoe + * split from dmasound_awacs.c + * 11/29/2003 Renzo Davoli (King Enzo) + * - input resampling (for soft rate < hard rate) + * - software line in gain control + */ + +#include +#include +#include "dmasound.h" + +extern int expand_bal; /* Balance factor for expanding (not volume!) */ +static short dmasound_alaw2dma16[] ; +static short dmasound_ulaw2dma16[] ; + +static ssize_t pmac_ct_law(const u_char __user *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft); +static ssize_t pmac_ct_s8(const u_char __user *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft); +static ssize_t pmac_ct_u8(const u_char __user *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft); +static ssize_t pmac_ct_s16(const u_char __user *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft); +static ssize_t pmac_ct_u16(const u_char __user *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft); + +static ssize_t pmac_ctx_law(const u_char __user *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft); +static ssize_t pmac_ctx_s8(const u_char __user *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft); +static ssize_t pmac_ctx_u8(const u_char __user *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft); +static ssize_t pmac_ctx_s16(const u_char __user *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft); +static ssize_t pmac_ctx_u16(const u_char __user *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft); + +static ssize_t pmac_ct_s16_read(const u_char __user *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft); +static ssize_t pmac_ct_u16_read(const u_char __user *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft); + +/*** Translations ************************************************************/ + +static int expand_data; /* Data for expanding */ + +static ssize_t pmac_ct_law(const u_char __user *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft) +{ + short *table = dmasound.soft.format == AFMT_MU_LAW + ? dmasound_ulaw2dma16 : dmasound_alaw2dma16; + ssize_t count, used; + short *p = (short *) &frame[*frameUsed]; + int val, stereo = dmasound.soft.stereo; + + frameLeft >>= 2; + if (stereo) + userCount >>= 1; + used = count = min_t(unsigned long, userCount, frameLeft); + while (count > 0) { + u_char data; + if (get_user(data, userPtr++)) + return -EFAULT; + val = table[data]; + *p++ = val; + if (stereo) { + if (get_user(data, userPtr++)) + return -EFAULT; + val = table[data]; + } + *p++ = val; + count--; + } + *frameUsed += used * 4; + return stereo? used * 2: used; +} + + +static ssize_t pmac_ct_s8(const u_char __user *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft) +{ + ssize_t count, used; + short *p = (short *) &frame[*frameUsed]; + int val, stereo = dmasound.soft.stereo; + + frameLeft >>= 2; + if (stereo) + userCount >>= 1; + used = count = min_t(unsigned long, userCount, frameLeft); + while (count > 0) { + u_char data; + if (get_user(data, userPtr++)) + return -EFAULT; + val = data << 8; + *p++ = val; + if (stereo) { + if (get_user(data, userPtr++)) + return -EFAULT; + val = data << 8; + } + *p++ = val; + count--; + } + *frameUsed += used * 4; + return stereo? used * 2: used; +} + + +static ssize_t pmac_ct_u8(const u_char __user *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft) +{ + ssize_t count, used; + short *p = (short *) &frame[*frameUsed]; + int val, stereo = dmasound.soft.stereo; + + frameLeft >>= 2; + if (stereo) + userCount >>= 1; + used = count = min_t(unsigned long, userCount, frameLeft); + while (count > 0) { + u_char data; + if (get_user(data, userPtr++)) + return -EFAULT; + val = (data ^ 0x80) << 8; + *p++ = val; + if (stereo) { + if (get_user(data, userPtr++)) + return -EFAULT; + val = (data ^ 0x80) << 8; + } + *p++ = val; + count--; + } + *frameUsed += used * 4; + return stereo? used * 2: used; +} + + +static ssize_t pmac_ct_s16(const u_char __user *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft) +{ + ssize_t count, used; + int stereo = dmasound.soft.stereo; + short *fp = (short *) &frame[*frameUsed]; + + frameLeft >>= 2; + userCount >>= (stereo? 2: 1); + used = count = min_t(unsigned long, userCount, frameLeft); + if (!stereo) { + short __user *up = (short __user *) userPtr; + while (count > 0) { + short data; + if (get_user(data, up++)) + return -EFAULT; + *fp++ = data; + *fp++ = data; + count--; + } + } else { + if (copy_from_user(fp, userPtr, count * 4)) + return -EFAULT; + } + *frameUsed += used * 4; + return stereo? used * 4: used * 2; +} + +static ssize_t pmac_ct_u16(const u_char __user *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft) +{ + ssize_t count, used; + int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000); + int stereo = dmasound.soft.stereo; + short *fp = (short *) &frame[*frameUsed]; + short __user *up = (short __user *) userPtr; + + frameLeft >>= 2; + userCount >>= (stereo? 2: 1); + used = count = min_t(unsigned long, userCount, frameLeft); + while (count > 0) { + short data; + if (get_user(data, up++)) + return -EFAULT; + data ^= mask; + *fp++ = data; + if (stereo) { + if (get_user(data, up++)) + return -EFAULT; + data ^= mask; + } + *fp++ = data; + count--; + } + *frameUsed += used * 4; + return stereo? used * 4: used * 2; +} + + +static ssize_t pmac_ctx_law(const u_char __user *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft) +{ + unsigned short *table = (unsigned short *) + (dmasound.soft.format == AFMT_MU_LAW + ? dmasound_ulaw2dma16 : dmasound_alaw2dma16); + unsigned int data = expand_data; + unsigned int *p = (unsigned int *) &frame[*frameUsed]; + int bal = expand_bal; + int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed; + int utotal, ftotal; + int stereo = dmasound.soft.stereo; + + frameLeft >>= 2; + if (stereo) + userCount >>= 1; + ftotal = frameLeft; + utotal = userCount; + while (frameLeft) { + u_char c; + if (bal < 0) { + if (userCount == 0) + break; + if (get_user(c, userPtr++)) + return -EFAULT; + data = table[c]; + if (stereo) { + if (get_user(c, userPtr++)) + return -EFAULT; + data = (data << 16) + table[c]; + } else + data = (data << 16) + data; + userCount--; + bal += hSpeed; + } + *p++ = data; + frameLeft--; + bal -= sSpeed; + } + expand_bal = bal; + expand_data = data; + *frameUsed += (ftotal - frameLeft) * 4; + utotal -= userCount; + return stereo? utotal * 2: utotal; +} + +static ssize_t pmac_ctx_s8(const u_char __user *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft) +{ + unsigned int *p = (unsigned int *) &frame[*frameUsed]; + unsigned int data = expand_data; + int bal = expand_bal; + int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed; + int stereo = dmasound.soft.stereo; + int utotal, ftotal; + + frameLeft >>= 2; + if (stereo) + userCount >>= 1; + ftotal = frameLeft; + utotal = userCount; + while (frameLeft) { + u_char c; + if (bal < 0) { + if (userCount == 0) + break; + if (get_user(c, userPtr++)) + return -EFAULT; + data = c << 8; + if (stereo) { + if (get_user(c, userPtr++)) + return -EFAULT; + data = (data << 16) + (c << 8); + } else + data = (data << 16) + data; + userCount--; + bal += hSpeed; + } + *p++ = data; + frameLeft--; + bal -= sSpeed; + } + expand_bal = bal; + expand_data = data; + *frameUsed += (ftotal - frameLeft) * 4; + utotal -= userCount; + return stereo? utotal * 2: utotal; +} + + +static ssize_t pmac_ctx_u8(const u_char __user *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft) +{ + unsigned int *p = (unsigned int *) &frame[*frameUsed]; + unsigned int data = expand_data; + int bal = expand_bal; + int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed; + int stereo = dmasound.soft.stereo; + int utotal, ftotal; + + frameLeft >>= 2; + if (stereo) + userCount >>= 1; + ftotal = frameLeft; + utotal = userCount; + while (frameLeft) { + u_char c; + if (bal < 0) { + if (userCount == 0) + break; + if (get_user(c, userPtr++)) + return -EFAULT; + data = (c ^ 0x80) << 8; + if (stereo) { + if (get_user(c, userPtr++)) + return -EFAULT; + data = (data << 16) + ((c ^ 0x80) << 8); + } else + data = (data << 16) + data; + userCount--; + bal += hSpeed; + } + *p++ = data; + frameLeft--; + bal -= sSpeed; + } + expand_bal = bal; + expand_data = data; + *frameUsed += (ftotal - frameLeft) * 4; + utotal -= userCount; + return stereo? utotal * 2: utotal; +} + + +static ssize_t pmac_ctx_s16(const u_char __user *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft) +{ + unsigned int *p = (unsigned int *) &frame[*frameUsed]; + unsigned int data = expand_data; + unsigned short __user *up = (unsigned short __user *) userPtr; + int bal = expand_bal; + int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed; + int stereo = dmasound.soft.stereo; + int utotal, ftotal; + + frameLeft >>= 2; + userCount >>= (stereo? 2: 1); + ftotal = frameLeft; + utotal = userCount; + while (frameLeft) { + unsigned short c; + if (bal < 0) { + if (userCount == 0) + break; + if (get_user(data, up++)) + return -EFAULT; + if (stereo) { + if (get_user(c, up++)) + return -EFAULT; + data = (data << 16) + c; + } else + data = (data << 16) + data; + userCount--; + bal += hSpeed; + } + *p++ = data; + frameLeft--; + bal -= sSpeed; + } + expand_bal = bal; + expand_data = data; + *frameUsed += (ftotal - frameLeft) * 4; + utotal -= userCount; + return stereo? utotal * 4: utotal * 2; +} + + +static ssize_t pmac_ctx_u16(const u_char __user *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft) +{ + int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000); + unsigned int *p = (unsigned int *) &frame[*frameUsed]; + unsigned int data = expand_data; + unsigned short __user *up = (unsigned short __user *) userPtr; + int bal = expand_bal; + int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed; + int stereo = dmasound.soft.stereo; + int utotal, ftotal; + + frameLeft >>= 2; + userCount >>= (stereo? 2: 1); + ftotal = frameLeft; + utotal = userCount; + while (frameLeft) { + unsigned short c; + if (bal < 0) { + if (userCount == 0) + break; + if (get_user(data, up++)) + return -EFAULT; + data ^= mask; + if (stereo) { + if (get_user(c, up++)) + return -EFAULT; + data = (data << 16) + (c ^ mask); + } else + data = (data << 16) + data; + userCount--; + bal += hSpeed; + } + *p++ = data; + frameLeft--; + bal -= sSpeed; + } + expand_bal = bal; + expand_data = data; + *frameUsed += (ftotal - frameLeft) * 4; + utotal -= userCount; + return stereo? utotal * 4: utotal * 2; +} + +/* data in routines... */ + +static ssize_t pmac_ct_s8_read(const u_char __user *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft) +{ + ssize_t count, used; + short *p = (short *) &frame[*frameUsed]; + int val, stereo = dmasound.soft.stereo; + + frameLeft >>= 2; + if (stereo) + userCount >>= 1; + used = count = min_t(unsigned long, userCount, frameLeft); + while (count > 0) { + u_char data; + + val = *p++; + val = (val * software_input_volume) >> 7; + data = val >> 8; + if (put_user(data, (u_char __user *)userPtr++)) + return -EFAULT; + if (stereo) { + val = *p; + val = (val * software_input_volume) >> 7; + data = val >> 8; + if (put_user(data, (u_char __user *)userPtr++)) + return -EFAULT; + } + p++; + count--; + } + *frameUsed += used * 4; + return stereo? used * 2: used; +} + + +static ssize_t pmac_ct_u8_read(const u_char __user *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft) +{ + ssize_t count, used; + short *p = (short *) &frame[*frameUsed]; + int val, stereo = dmasound.soft.stereo; + + frameLeft >>= 2; + if (stereo) + userCount >>= 1; + used = count = min_t(unsigned long, userCount, frameLeft); + while (count > 0) { + u_char data; + + val = *p++; + val = (val * software_input_volume) >> 7; + data = (val >> 8) ^ 0x80; + if (put_user(data, (u_char __user *)userPtr++)) + return -EFAULT; + if (stereo) { + val = *p; + val = (val * software_input_volume) >> 7; + data = (val >> 8) ^ 0x80; + if (put_user(data, (u_char __user *)userPtr++)) + return -EFAULT; + } + p++; + count--; + } + *frameUsed += used * 4; + return stereo? used * 2: used; +} + +static ssize_t pmac_ct_s16_read(const u_char __user *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft) +{ + ssize_t count, used; + int stereo = dmasound.soft.stereo; + short *fp = (short *) &frame[*frameUsed]; + short __user *up = (short __user *) userPtr; + + frameLeft >>= 2; + userCount >>= (stereo? 2: 1); + used = count = min_t(unsigned long, userCount, frameLeft); + while (count > 0) { + short data; + + data = *fp++; + data = (data * software_input_volume) >> 7; + if (put_user(data, up++)) + return -EFAULT; + if (stereo) { + data = *fp; + data = (data * software_input_volume) >> 7; + if (put_user(data, up++)) + return -EFAULT; + } + fp++; + count--; + } + *frameUsed += used * 4; + return stereo? used * 4: used * 2; +} + +static ssize_t pmac_ct_u16_read(const u_char __user *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft) +{ + ssize_t count, used; + int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000); + int stereo = dmasound.soft.stereo; + short *fp = (short *) &frame[*frameUsed]; + short __user *up = (short __user *) userPtr; + + frameLeft >>= 2; + userCount >>= (stereo? 2: 1); + used = count = min_t(unsigned long, userCount, frameLeft); + while (count > 0) { + int data; + + data = *fp++; + data = (data * software_input_volume) >> 7; + data ^= mask; + if (put_user(data, up++)) + return -EFAULT; + if (stereo) { + data = *fp; + data = (data * software_input_volume) >> 7; + data ^= mask; + if (put_user(data, up++)) + return -EFAULT; + } + fp++; + count--; + } + *frameUsed += used * 4; + return stereo? used * 4: used * 2; +} + +/* data in routines (reducing speed)... */ + +static ssize_t pmac_ctx_s8_read(const u_char __user *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft) +{ + short *p = (short *) &frame[*frameUsed]; + int bal = expand_read_bal; + int vall,valr, stereo = dmasound.soft.stereo; + int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed; + int utotal, ftotal; + + frameLeft >>= 2; + if (stereo) + userCount >>= 1; + ftotal = frameLeft; + utotal = userCount; + while (frameLeft) { + u_char data; + + if (bal<0 && userCount == 0) + break; + vall = *p++; + vall = (vall * software_input_volume) >> 7; + if (stereo) { + valr = *p; + valr = (valr * software_input_volume) >> 7; + } + p++; + if (bal < 0) { + data = vall >> 8; + if (put_user(data, (u_char __user *)userPtr++)) + return -EFAULT; + if (stereo) { + data = valr >> 8; + if (put_user(data, (u_char __user *)userPtr++)) + return -EFAULT; + } + userCount--; + bal += hSpeed; + } + frameLeft--; + bal -= sSpeed; + } + expand_read_bal=bal; + *frameUsed += (ftotal - frameLeft) * 4; + utotal -= userCount; + return stereo? utotal * 2: utotal; +} + + +static ssize_t pmac_ctx_u8_read(const u_char __user *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft) +{ + short *p = (short *) &frame[*frameUsed]; + int bal = expand_read_bal; + int vall,valr, stereo = dmasound.soft.stereo; + int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed; + int utotal, ftotal; + + frameLeft >>= 2; + if (stereo) + userCount >>= 1; + ftotal = frameLeft; + utotal = userCount; + while (frameLeft) { + u_char data; + + if (bal<0 && userCount == 0) + break; + + vall = *p++; + vall = (vall * software_input_volume) >> 7; + if (stereo) { + valr = *p; + valr = (valr * software_input_volume) >> 7; + } + p++; + if (bal < 0) { + data = (vall >> 8) ^ 0x80; + if (put_user(data, (u_char __user *)userPtr++)) + return -EFAULT; + if (stereo) { + data = (valr >> 8) ^ 0x80; + if (put_user(data, (u_char __user *)userPtr++)) + return -EFAULT; + } + userCount--; + bal += hSpeed; + } + frameLeft--; + bal -= sSpeed; + } + expand_read_bal=bal; + *frameUsed += (ftotal - frameLeft) * 4; + utotal -= userCount; + return stereo? utotal * 2: utotal; +} + +static ssize_t pmac_ctx_s16_read(const u_char __user *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft) +{ + int bal = expand_read_bal; + short *fp = (short *) &frame[*frameUsed]; + short __user *up = (short __user *) userPtr; + int stereo = dmasound.soft.stereo; + int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed; + int utotal, ftotal; + + frameLeft >>= 2; + userCount >>= (stereo? 2: 1); + ftotal = frameLeft; + utotal = userCount; + while (frameLeft) { + int datal,datar; + + if (bal<0 && userCount == 0) + break; + + datal = *fp++; + datal = (datal * software_input_volume) >> 7; + if (stereo) { + datar = *fp; + datar = (datar * software_input_volume) >> 7; + } + fp++; + if (bal < 0) { + if (put_user(datal, up++)) + return -EFAULT; + if (stereo) { + if (put_user(datar, up++)) + return -EFAULT; + } + userCount--; + bal += hSpeed; + } + frameLeft--; + bal -= sSpeed; + } + expand_read_bal=bal; + *frameUsed += (ftotal - frameLeft) * 4; + utotal -= userCount; + return stereo? utotal * 4: utotal * 2; +} + +static ssize_t pmac_ctx_u16_read(const u_char __user *userPtr, size_t userCount, + u_char frame[], ssize_t *frameUsed, + ssize_t frameLeft) +{ + int bal = expand_read_bal; + int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000); + short *fp = (short *) &frame[*frameUsed]; + short __user *up = (short __user *) userPtr; + int stereo = dmasound.soft.stereo; + int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed; + int utotal, ftotal; + + frameLeft >>= 2; + userCount >>= (stereo? 2: 1); + ftotal = frameLeft; + utotal = userCount; + while (frameLeft) { + int datal,datar; + + if (bal<0 && userCount == 0) + break; + + datal = *fp++; + datal = (datal * software_input_volume) >> 7; + datal ^= mask; + if (stereo) { + datar = *fp; + datar = (datar * software_input_volume) >> 7; + datar ^= mask; + } + fp++; + if (bal < 0) { + if (put_user(datal, up++)) + return -EFAULT; + if (stereo) { + if (put_user(datar, up++)) + return -EFAULT; + } + userCount--; + bal += hSpeed; + } + frameLeft--; + bal -= sSpeed; + } + expand_read_bal=bal; + *frameUsed += (ftotal - frameLeft) * 4; + utotal -= userCount; + return stereo? utotal * 4: utotal * 2; +} + + +TRANS transAwacsNormal = { + .ct_ulaw= pmac_ct_law, + .ct_alaw= pmac_ct_law, + .ct_s8= pmac_ct_s8, + .ct_u8= pmac_ct_u8, + .ct_s16be= pmac_ct_s16, + .ct_u16be= pmac_ct_u16, + .ct_s16le= pmac_ct_s16, + .ct_u16le= pmac_ct_u16, +}; + +TRANS transAwacsExpand = { + .ct_ulaw= pmac_ctx_law, + .ct_alaw= pmac_ctx_law, + .ct_s8= pmac_ctx_s8, + .ct_u8= pmac_ctx_u8, + .ct_s16be= pmac_ctx_s16, + .ct_u16be= pmac_ctx_u16, + .ct_s16le= pmac_ctx_s16, + .ct_u16le= pmac_ctx_u16, +}; + +TRANS transAwacsNormalRead = { + .ct_s8= pmac_ct_s8_read, + .ct_u8= pmac_ct_u8_read, + .ct_s16be= pmac_ct_s16_read, + .ct_u16be= pmac_ct_u16_read, + .ct_s16le= pmac_ct_s16_read, + .ct_u16le= pmac_ct_u16_read, +}; + +TRANS transAwacsExpandRead = { + .ct_s8= pmac_ctx_s8_read, + .ct_u8= pmac_ctx_u8_read, + .ct_s16be= pmac_ctx_s16_read, + .ct_u16be= pmac_ctx_u16_read, + .ct_s16le= pmac_ctx_s16_read, + .ct_u16le= pmac_ctx_u16_read, +}; + +/* translation tables */ +/* 16 bit mu-law */ + +static short dmasound_ulaw2dma16[] = { + -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956, + -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764, + -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412, + -11900, -11388, -10876, -10364, -9852, -9340, -8828, -8316, + -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140, + -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092, + -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004, + -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980, + -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436, + -1372, -1308, -1244, -1180, -1116, -1052, -988, -924, + -876, -844, -812, -780, -748, -716, -684, -652, + -620, -588, -556, -524, -492, -460, -428, -396, + -372, -356, -340, -324, -308, -292, -276, -260, + -244, -228, -212, -196, -180, -164, -148, -132, + -120, -112, -104, -96, -88, -80, -72, -64, + -56, -48, -40, -32, -24, -16, -8, 0, + 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956, + 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764, + 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412, + 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316, + 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140, + 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092, + 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004, + 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980, + 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436, + 1372, 1308, 1244, 1180, 1116, 1052, 988, 924, + 876, 844, 812, 780, 748, 716, 684, 652, + 620, 588, 556, 524, 492, 460, 428, 396, + 372, 356, 340, 324, 308, 292, 276, 260, + 244, 228, 212, 196, 180, 164, 148, 132, + 120, 112, 104, 96, 88, 80, 72, 64, + 56, 48, 40, 32, 24, 16, 8, 0, +}; + +/* 16 bit A-law */ + +static short dmasound_alaw2dma16[] = { + -5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736, + -7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784, + -2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368, + -3776, -3648, -4032, -3904, -3264, -3136, -3520, -3392, + -22016, -20992, -24064, -23040, -17920, -16896, -19968, -18944, + -30208, -29184, -32256, -31232, -26112, -25088, -28160, -27136, + -11008, -10496, -12032, -11520, -8960, -8448, -9984, -9472, + -15104, -14592, -16128, -15616, -13056, -12544, -14080, -13568, + -344, -328, -376, -360, -280, -264, -312, -296, + -472, -456, -504, -488, -408, -392, -440, -424, + -88, -72, -120, -104, -24, -8, -56, -40, + -216, -200, -248, -232, -152, -136, -184, -168, + -1376, -1312, -1504, -1440, -1120, -1056, -1248, -1184, + -1888, -1824, -2016, -1952, -1632, -1568, -1760, -1696, + -688, -656, -752, -720, -560, -528, -624, -592, + -944, -912, -1008, -976, -816, -784, -880, -848, + 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736, + 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784, + 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368, + 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392, + 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944, + 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136, + 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472, + 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568, + 344, 328, 376, 360, 280, 264, 312, 296, + 472, 456, 504, 488, 408, 392, 440, 424, + 88, 72, 120, 104, 24, 8, 56, 40, + 216, 200, 248, 232, 152, 136, 184, 168, + 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184, + 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696, + 688, 656, 752, 720, 560, 528, 624, 592, + 944, 912, 1008, 976, 816, 784, 880, 848, +}; diff --git a/trunk/sound/oss/es1371.c b/trunk/sound/oss/es1371.c new file mode 100644 index 000000000000..52648573f601 --- /dev/null +++ b/trunk/sound/oss/es1371.c @@ -0,0 +1,3131 @@ +/*****************************************************************************/ + +/* + * es1371.c -- Creative Ensoniq ES1371. + * + * Copyright (C) 1998-2001, 2003 Thomas Sailer (t.sailer@alumni.ethz.ch) + * + * 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. + * + * Special thanks to Ensoniq + * + * Supported devices: + * /dev/dsp standard /dev/dsp device, (mostly) OSS compatible + * /dev/mixer standard /dev/mixer device, (mostly) OSS compatible + * /dev/dsp1 additional DAC, like /dev/dsp, but outputs to mixer "SYNTH" setting + * /dev/midi simple MIDI UART interface, no ioctl + * + * NOTE: the card does not have any FM/Wavetable synthesizer, it is supposed + * to be done in software. That is what /dev/dac is for. By now (Q2 1998) + * there are several MIDI to PCM (WAV) packages, one of them is timidity. + * + * Revision history + * 04.06.1998 0.1 Initial release + * Mixer stuff should be overhauled; especially optional AC97 mixer bits + * should be detected. This results in strange behaviour of some mixer + * settings, like master volume and mic. + * 08.06.1998 0.2 First release using Alan Cox' soundcore instead of miscdevice + * 03.08.1998 0.3 Do not include modversions.h + * Now mixer behaviour can basically be selected between + * "OSS documented" and "OSS actual" behaviour + * 31.08.1998 0.4 Fix realplayer problems - dac.count issues + * 27.10.1998 0.5 Fix joystick support + * -- Oliver Neukum (c188@org.chemie.uni-muenchen.de) + * 10.12.1998 0.6 Fix drain_dac trying to wait on not yet initialized DMA + * 23.12.1998 0.7 Fix a few f_file & FMODE_ bugs + * Don't wake up app until there are fragsize bytes to read/write + * 06.01.1999 0.8 remove the silly SA_INTERRUPT flag. + * hopefully killed the egcs section type conflict + * 12.03.1999 0.9 cinfo.blocks should be reset after GETxPTR ioctl. + * reported by Johan Maes + * 22.03.1999 0.10 return EAGAIN instead of EBUSY when O_NONBLOCK + * read/write cannot be executed + * 07.04.1999 0.11 implemented the following ioctl's: SOUND_PCM_READ_RATE, + * SOUND_PCM_READ_CHANNELS, SOUND_PCM_READ_BITS; + * Alpha fixes reported by Peter Jones + * Another Alpha fix (wait_src_ready in init routine) + * reported by "Ivan N. Kokshaysky" + * Note: joystick address handling might still be wrong on archs + * other than i386 + * 15.06.1999 0.12 Fix bad allocation bug. + * Thanks to Deti Fliegl + * 28.06.1999 0.13 Add pci_set_master + * 03.08.1999 0.14 adapt to Linus' new __setup/__initcall + * added kernel command line option "es1371=joystickaddr" + * removed CONFIG_SOUND_ES1371_JOYPORT_BOOT kludge + * 10.08.1999 0.15 (Re)added S/PDIF module option for cards revision >= 4. + * Initial version by Dave Platt . + * module_init/__setup fixes + * 08.16.1999 0.16 Joe Cotellese + * Added detection for ES1371 revision ID so that we can + * detect the ES1373 and later parts. + * added AC97 #defines for readability + * added a /proc file system for dumping hardware state + * updated SRC and CODEC w/r functions to accommodate bugs + * in some versions of the ES137x chips. + * 31.08.1999 0.17 add spin_lock_init + * replaced current->state = x with set_current_state(x) + * 03.09.1999 0.18 change read semantics for MIDI to match + * OSS more closely; remove possible wakeup race + * 21.10.1999 0.19 Round sampling rates, requested by + * Kasamatsu Kenichi + * 27.10.1999 0.20 Added SigmaTel 3D enhancement string + * Codec ID printing changes + * 28.10.1999 0.21 More waitqueue races fixed + * Joe Cotellese + * Changed PCI detection routine so we can more easily + * detect ES137x chip and derivatives. + * 05.01.2000 0.22 Should now work with rev7 boards; patch by + * Eric Lemar, elemar@cs.washington.edu + * 08.01.2000 0.23 Prevent some ioctl's from returning bad count values on underrun/overrun; + * Tim Janik's BSE (Bedevilled Sound Engine) found this + * 07.02.2000 0.24 Use pci_alloc_consistent and pci_register_driver + * 07.02.2000 0.25 Use ac97_codec + * 01.03.2000 0.26 SPDIF patch by Mikael Bouillot + * Use pci_module_init + * 21.11.2000 0.27 Initialize dma buffers in poll, otherwise poll may return a bogus mask + * 12.12.2000 0.28 More dma buffer initializations, patch from + * Tjeerd Mulder + * 05.01.2001 0.29 Hopefully updates will not be required anymore when Creative bumps + * the CT5880 revision. + * suggested by Stephan Müller + * 31.01.2001 0.30 Register/Unregister gameport + * Fix SETTRIGGER non OSS API conformity + * 14.07.2001 0.31 Add list of laptops needing amplifier control + * 03.01.2003 0.32 open_mode fixes from Georg Acher + */ + +/*****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE)) +#define SUPPORT_JOYSTICK +#endif + +/* --------------------------------------------------------------------- */ + +#undef OSS_DOCUMENTED_MIXER_SEMANTICS +#define ES1371_DEBUG +#define DBG(x) {} +/*#define DBG(x) {x}*/ + +/* --------------------------------------------------------------------- */ + +#ifndef PCI_VENDOR_ID_ENSONIQ +#define PCI_VENDOR_ID_ENSONIQ 0x1274 +#endif + +#ifndef PCI_VENDOR_ID_ECTIVA +#define PCI_VENDOR_ID_ECTIVA 0x1102 +#endif + +#ifndef PCI_DEVICE_ID_ENSONIQ_ES1371 +#define PCI_DEVICE_ID_ENSONIQ_ES1371 0x1371 +#endif + +#ifndef PCI_DEVICE_ID_ENSONIQ_CT5880 +#define PCI_DEVICE_ID_ENSONIQ_CT5880 0x5880 +#endif + +#ifndef PCI_DEVICE_ID_ECTIVA_EV1938 +#define PCI_DEVICE_ID_ECTIVA_EV1938 0x8938 +#endif + +/* ES1371 chip ID */ +/* This is a little confusing because all ES1371 compatible chips have the + same DEVICE_ID, the only thing differentiating them is the REV_ID field. + This is only significant if you want to enable features on the later parts. + Yes, I know it's stupid and why didn't we use the sub IDs? +*/ +#define ES1371REV_ES1373_A 0x04 +#define ES1371REV_ES1373_B 0x06 +#define ES1371REV_CT5880_A 0x07 +#define CT5880REV_CT5880_C 0x02 +#define CT5880REV_CT5880_D 0x03 +#define ES1371REV_ES1371_B 0x09 +#define EV1938REV_EV1938_A 0x00 +#define ES1371REV_ES1373_8 0x08 + +#define ES1371_MAGIC ((PCI_VENDOR_ID_ENSONIQ<<16)|PCI_DEVICE_ID_ENSONIQ_ES1371) + +#define ES1371_EXTENT 0x40 +#define JOY_EXTENT 8 + +#define ES1371_REG_CONTROL 0x00 +#define ES1371_REG_STATUS 0x04 /* on the 5880 it is control/status */ +#define ES1371_REG_UART_DATA 0x08 +#define ES1371_REG_UART_STATUS 0x09 +#define ES1371_REG_UART_CONTROL 0x09 +#define ES1371_REG_UART_TEST 0x0a +#define ES1371_REG_MEMPAGE 0x0c +#define ES1371_REG_SRCONV 0x10 +#define ES1371_REG_CODEC 0x14 +#define ES1371_REG_LEGACY 0x18 +#define ES1371_REG_SERIAL_CONTROL 0x20 +#define ES1371_REG_DAC1_SCOUNT 0x24 +#define ES1371_REG_DAC2_SCOUNT 0x28 +#define ES1371_REG_ADC_SCOUNT 0x2c + +#define ES1371_REG_DAC1_FRAMEADR 0xc30 +#define ES1371_REG_DAC1_FRAMECNT 0xc34 +#define ES1371_REG_DAC2_FRAMEADR 0xc38 +#define ES1371_REG_DAC2_FRAMECNT 0xc3c +#define ES1371_REG_ADC_FRAMEADR 0xd30 +#define ES1371_REG_ADC_FRAMECNT 0xd34 + +#define ES1371_FMT_U8_MONO 0 +#define ES1371_FMT_U8_STEREO 1 +#define ES1371_FMT_S16_MONO 2 +#define ES1371_FMT_S16_STEREO 3 +#define ES1371_FMT_STEREO 1 +#define ES1371_FMT_S16 2 +#define ES1371_FMT_MASK 3 + +static const unsigned sample_size[] = { 1, 2, 2, 4 }; +static const unsigned sample_shift[] = { 0, 1, 1, 2 }; + +#define CTRL_RECEN_B 0x08000000 /* 1 = don't mix analog in to digital out */ +#define CTRL_SPDIFEN_B 0x04000000 +#define CTRL_JOY_SHIFT 24 +#define CTRL_JOY_MASK 3 +#define CTRL_JOY_200 0x00000000 /* joystick base address */ +#define CTRL_JOY_208 0x01000000 +#define CTRL_JOY_210 0x02000000 +#define CTRL_JOY_218 0x03000000 +#define CTRL_GPIO_IN0 0x00100000 /* general purpose inputs/outputs */ +#define CTRL_GPIO_IN1 0x00200000 +#define CTRL_GPIO_IN2 0x00400000 +#define CTRL_GPIO_IN3 0x00800000 +#define CTRL_GPIO_OUT0 0x00010000 +#define CTRL_GPIO_OUT1 0x00020000 +#define CTRL_GPIO_OUT2 0x00040000 +#define CTRL_GPIO_OUT3 0x00080000 +#define CTRL_MSFMTSEL 0x00008000 /* MPEG serial data fmt: 0 = Sony, 1 = I2S */ +#define CTRL_SYNCRES 0x00004000 /* AC97 warm reset */ +#define CTRL_ADCSTOP 0x00002000 /* stop ADC transfers */ +#define CTRL_PWR_INTRM 0x00001000 /* 1 = power level ints enabled */ +#define CTRL_M_CB 0x00000800 /* recording source: 0 = ADC, 1 = MPEG */ +#define CTRL_CCB_INTRM 0x00000400 /* 1 = CCB "voice" ints enabled */ +#define CTRL_PDLEV0 0x00000000 /* power down level */ +#define CTRL_PDLEV1 0x00000100 +#define CTRL_PDLEV2 0x00000200 +#define CTRL_PDLEV3 0x00000300 +#define CTRL_BREQ 0x00000080 /* 1 = test mode (internal mem test) */ +#define CTRL_DAC1_EN 0x00000040 /* enable DAC1 */ +#define CTRL_DAC2_EN 0x00000020 /* enable DAC2 */ +#define CTRL_ADC_EN 0x00000010 /* enable ADC */ +#define CTRL_UART_EN 0x00000008 /* enable MIDI uart */ +#define CTRL_JYSTK_EN 0x00000004 /* enable Joystick port */ +#define CTRL_XTALCLKDIS 0x00000002 /* 1 = disable crystal clock input */ +#define CTRL_PCICLKDIS 0x00000001 /* 1 = disable PCI clock distribution */ + + +#define STAT_INTR 0x80000000 /* wired or of all interrupt bits */ +#define CSTAT_5880_AC97_RST 0x20000000 /* CT5880 Reset bit */ +#define STAT_EN_SPDIF 0x00040000 /* enable S/PDIF circuitry */ +#define STAT_TS_SPDIF 0x00020000 /* test S/PDIF circuitry */ +#define STAT_TESTMODE 0x00010000 /* test ASIC */ +#define STAT_SYNC_ERR 0x00000100 /* 1 = codec sync error */ +#define STAT_VC 0x000000c0 /* CCB int source, 0=DAC1, 1=DAC2, 2=ADC, 3=undef */ +#define STAT_SH_VC 6 +#define STAT_MPWR 0x00000020 /* power level interrupt */ +#define STAT_MCCB 0x00000010 /* CCB int pending */ +#define STAT_UART 0x00000008 /* UART int pending */ +#define STAT_DAC1 0x00000004 /* DAC1 int pending */ +#define STAT_DAC2 0x00000002 /* DAC2 int pending */ +#define STAT_ADC 0x00000001 /* ADC int pending */ + +#define USTAT_RXINT 0x80 /* UART rx int pending */ +#define USTAT_TXINT 0x04 /* UART tx int pending */ +#define USTAT_TXRDY 0x02 /* UART tx ready */ +#define USTAT_RXRDY 0x01 /* UART rx ready */ + +#define UCTRL_RXINTEN 0x80 /* 1 = enable RX ints */ +#define UCTRL_TXINTEN 0x60 /* TX int enable field mask */ +#define UCTRL_ENA_TXINT 0x20 /* enable TX int */ +#define UCTRL_CNTRL 0x03 /* control field */ +#define UCTRL_CNTRL_SWR 0x03 /* software reset command */ + +/* sample rate converter */ +#define SRC_OKSTATE 1 + +#define SRC_RAMADDR_MASK 0xfe000000 +#define SRC_RAMADDR_SHIFT 25 +#define SRC_DAC1FREEZE (1UL << 21) +#define SRC_DAC2FREEZE (1UL << 20) +#define SRC_ADCFREEZE (1UL << 19) + + +#define SRC_WE 0x01000000 /* read/write control for SRC RAM */ +#define SRC_BUSY 0x00800000 /* SRC busy */ +#define SRC_DIS 0x00400000 /* 1 = disable SRC */ +#define SRC_DDAC1 0x00200000 /* 1 = disable accum update for DAC1 */ +#define SRC_DDAC2 0x00100000 /* 1 = disable accum update for DAC2 */ +#define SRC_DADC 0x00080000 /* 1 = disable accum update for ADC2 */ +#define SRC_CTLMASK 0x00780000 +#define SRC_RAMDATA_MASK 0x0000ffff +#define SRC_RAMDATA_SHIFT 0 + +#define SRCREG_ADC 0x78 +#define SRCREG_DAC1 0x70 +#define SRCREG_DAC2 0x74 +#define SRCREG_VOL_ADC 0x6c +#define SRCREG_VOL_DAC1 0x7c +#define SRCREG_VOL_DAC2 0x7e + +#define SRCREG_TRUNC_N 0x00 +#define SRCREG_INT_REGS 0x01 +#define SRCREG_ACCUM_FRAC 0x02 +#define SRCREG_VFREQ_FRAC 0x03 + +#define CODEC_PIRD 0x00800000 /* 0 = write AC97 register */ +#define CODEC_PIADD_MASK 0x007f0000 +#define CODEC_PIADD_SHIFT 16 +#define CODEC_PIDAT_MASK 0x0000ffff +#define CODEC_PIDAT_SHIFT 0 + +#define CODEC_RDY 0x80000000 /* AC97 read data valid */ +#define CODEC_WIP 0x40000000 /* AC97 write in progress */ +#define CODEC_PORD 0x00800000 /* 0 = write AC97 register */ +#define CODEC_POADD_MASK 0x007f0000 +#define CODEC_POADD_SHIFT 16 +#define CODEC_PODAT_MASK 0x0000ffff +#define CODEC_PODAT_SHIFT 0 + + +#define LEGACY_JFAST 0x80000000 /* fast joystick timing */ +#define LEGACY_FIRQ 0x01000000 /* force IRQ */ + +#define SCTRL_DACTEST 0x00400000 /* 1 = DAC test, test vector generation purposes */ +#define SCTRL_P2ENDINC 0x00380000 /* */ +#define SCTRL_SH_P2ENDINC 19 +#define SCTRL_P2STINC 0x00070000 /* */ +#define SCTRL_SH_P2STINC 16 +#define SCTRL_R1LOOPSEL 0x00008000 /* 0 = loop mode */ +#define SCTRL_P2LOOPSEL 0x00004000 /* 0 = loop mode */ +#define SCTRL_P1LOOPSEL 0x00002000 /* 0 = loop mode */ +#define SCTRL_P2PAUSE 0x00001000 /* 1 = pause mode */ +#define SCTRL_P1PAUSE 0x00000800 /* 1 = pause mode */ +#define SCTRL_R1INTEN 0x00000400 /* enable interrupt */ +#define SCTRL_P2INTEN 0x00000200 /* enable interrupt */ +#define SCTRL_P1INTEN 0x00000100 /* enable interrupt */ +#define SCTRL_P1SCTRLD 0x00000080 /* reload sample count register for DAC1 */ +#define SCTRL_P2DACSEN 0x00000040 /* 1 = DAC2 play back last sample when disabled */ +#define SCTRL_R1SEB 0x00000020 /* 1 = 16bit */ +#define SCTRL_R1SMB 0x00000010 /* 1 = stereo */ +#define SCTRL_R1FMT 0x00000030 /* format mask */ +#define SCTRL_SH_R1FMT 4 +#define SCTRL_P2SEB 0x00000008 /* 1 = 16bit */ +#define SCTRL_P2SMB 0x00000004 /* 1 = stereo */ +#define SCTRL_P2FMT 0x0000000c /* format mask */ +#define SCTRL_SH_P2FMT 2 +#define SCTRL_P1SEB 0x00000002 /* 1 = 16bit */ +#define SCTRL_P1SMB 0x00000001 /* 1 = stereo */ +#define SCTRL_P1FMT 0x00000003 /* format mask */ +#define SCTRL_SH_P1FMT 0 + + +/* misc stuff */ +#define POLL_COUNT 0x1000 +#define FMODE_DAC 4 /* slight misuse of mode_t */ + +/* MIDI buffer sizes */ + +#define MIDIINBUF 256 +#define MIDIOUTBUF 256 + +#define FMODE_MIDI_SHIFT 3 +#define FMODE_MIDI_READ (FMODE_READ << FMODE_MIDI_SHIFT) +#define FMODE_MIDI_WRITE (FMODE_WRITE << FMODE_MIDI_SHIFT) + +#define ES1371_MODULE_NAME "es1371" +#define PFX ES1371_MODULE_NAME ": " + +/* --------------------------------------------------------------------- */ + +struct es1371_state { + /* magic */ + unsigned int magic; + + /* list of es1371 devices */ + struct list_head devs; + + /* the corresponding pci_dev structure */ + struct pci_dev *dev; + + /* soundcore stuff */ + int dev_audio; + int dev_dac; + int dev_midi; + + /* hardware resources */ + unsigned long io; /* long for SPARC */ + unsigned int irq; + + /* PCI ID's */ + u16 vendor; + u16 device; + u8 rev; /* the chip revision */ + + /* options */ + int spdif_volume; /* S/PDIF output is enabled if != -1 */ + +#ifdef ES1371_DEBUG + /* debug /proc entry */ + struct proc_dir_entry *ps; +#endif /* ES1371_DEBUG */ + + struct ac97_codec *codec; + + /* wave stuff */ + unsigned ctrl; + unsigned sctrl; + unsigned dac1rate, dac2rate, adcrate; + + spinlock_t lock; + struct mutex open_mutex; + mode_t open_mode; + wait_queue_head_t open_wait; + + struct dmabuf { + void *rawbuf; + dma_addr_t dmaaddr; + unsigned buforder; + unsigned numfrag; + unsigned fragshift; + unsigned hwptr, swptr; + unsigned total_bytes; + int count; + unsigned error; /* over/underrun */ + wait_queue_head_t wait; + /* redundant, but makes calculations easier */ + unsigned fragsize; + unsigned dmasize; + unsigned fragsamples; + /* OSS stuff */ + unsigned mapped:1; + unsigned ready:1; + unsigned endcleared:1; + unsigned enabled:1; + unsigned ossfragshift; + int ossmaxfrags; + unsigned subdivision; + } dma_dac1, dma_dac2, dma_adc; + + /* midi stuff */ + struct { + unsigned ird, iwr, icnt; + unsigned ord, owr, ocnt; + wait_queue_head_t iwait; + wait_queue_head_t owait; + unsigned char ibuf[MIDIINBUF]; + unsigned char obuf[MIDIOUTBUF]; + } midi; + +#ifdef SUPPORT_JOYSTICK + struct gameport *gameport; +#endif + + struct mutex sem; +}; + +/* --------------------------------------------------------------------- */ + +static LIST_HEAD(devs); + +/* --------------------------------------------------------------------- */ + +static inline unsigned ld2(unsigned int x) +{ + unsigned r = 0; + + if (x >= 0x10000) { + x >>= 16; + r += 16; + } + if (x >= 0x100) { + x >>= 8; + r += 8; + } + if (x >= 0x10) { + x >>= 4; + r += 4; + } + if (x >= 4) { + x >>= 2; + r += 2; + } + if (x >= 2) + r++; + return r; +} + +/* --------------------------------------------------------------------- */ + +static unsigned wait_src_ready(struct es1371_state *s) +{ + unsigned int t, r; + + for (t = 0; t < POLL_COUNT; t++) { + if (!((r = inl(s->io + ES1371_REG_SRCONV)) & SRC_BUSY)) + return r; + udelay(1); + } + printk(KERN_DEBUG PFX "sample rate converter timeout r = 0x%08x\n", r); + return r; +} + +static unsigned src_read(struct es1371_state *s, unsigned reg) +{ + unsigned int temp,i,orig; + + /* wait for ready */ + temp = wait_src_ready (s); + + /* we can only access the SRC at certain times, make sure + we're allowed to before we read */ + + orig = temp; + /* expose the SRC state bits */ + outl ( (temp & SRC_CTLMASK) | (reg << SRC_RAMADDR_SHIFT) | 0x10000UL, + s->io + ES1371_REG_SRCONV); + + /* now, wait for busy and the correct time to read */ + temp = wait_src_ready (s); + + if ( (temp & 0x00870000UL ) != ( SRC_OKSTATE << 16 )){ + /* wait for the right state */ + for (i=0; iio + ES1371_REG_SRCONV); + if ( (temp & 0x00870000UL ) == ( SRC_OKSTATE << 16 )) + break; + } + } + + /* hide the state bits */ + outl ((orig & SRC_CTLMASK) | (reg << SRC_RAMADDR_SHIFT), s->io + ES1371_REG_SRCONV); + return temp; + + +} + +static void src_write(struct es1371_state *s, unsigned reg, unsigned data) +{ + + unsigned int r; + + r = wait_src_ready(s) & (SRC_DIS | SRC_DDAC1 | SRC_DDAC2 | SRC_DADC); + r |= (reg << SRC_RAMADDR_SHIFT) & SRC_RAMADDR_MASK; + r |= (data << SRC_RAMDATA_SHIFT) & SRC_RAMDATA_MASK; + outl(r | SRC_WE, s->io + ES1371_REG_SRCONV); + +} + +/* --------------------------------------------------------------------- */ + +/* most of the following here is black magic */ +static void set_adc_rate(struct es1371_state *s, unsigned rate) +{ + unsigned long flags; + unsigned int n, truncm, freq; + + if (rate > 48000) + rate = 48000; + if (rate < 4000) + rate = 4000; + n = rate / 3000; + if ((1 << n) & ((1 << 15) | (1 << 13) | (1 << 11) | (1 << 9))) + n--; + truncm = (21 * n - 1) | 1; + freq = ((48000UL << 15) / rate) * n; + s->adcrate = (48000UL << 15) / (freq / n); + spin_lock_irqsave(&s->lock, flags); + if (rate >= 24000) { + if (truncm > 239) + truncm = 239; + src_write(s, SRCREG_ADC+SRCREG_TRUNC_N, + (((239 - truncm) >> 1) << 9) | (n << 4)); + } else { + if (truncm > 119) + truncm = 119; + src_write(s, SRCREG_ADC+SRCREG_TRUNC_N, + 0x8000 | (((119 - truncm) >> 1) << 9) | (n << 4)); + } + src_write(s, SRCREG_ADC+SRCREG_INT_REGS, + (src_read(s, SRCREG_ADC+SRCREG_INT_REGS) & 0x00ff) | + ((freq >> 5) & 0xfc00)); + src_write(s, SRCREG_ADC+SRCREG_VFREQ_FRAC, freq & 0x7fff); + src_write(s, SRCREG_VOL_ADC, n << 8); + src_write(s, SRCREG_VOL_ADC+1, n << 8); + spin_unlock_irqrestore(&s->lock, flags); +} + + +static void set_dac1_rate(struct es1371_state *s, unsigned rate) +{ + unsigned long flags; + unsigned int freq, r; + + if (rate > 48000) + rate = 48000; + if (rate < 4000) + rate = 4000; + freq = ((rate << 15) + 1500) / 3000; + s->dac1rate = (freq * 3000 + 16384) >> 15; + spin_lock_irqsave(&s->lock, flags); + r = (wait_src_ready(s) & (SRC_DIS | SRC_DDAC2 | SRC_DADC)) | SRC_DDAC1; + outl(r, s->io + ES1371_REG_SRCONV); + src_write(s, SRCREG_DAC1+SRCREG_INT_REGS, + (src_read(s, SRCREG_DAC1+SRCREG_INT_REGS) & 0x00ff) | + ((freq >> 5) & 0xfc00)); + src_write(s, SRCREG_DAC1+SRCREG_VFREQ_FRAC, freq & 0x7fff); + r = (wait_src_ready(s) & (SRC_DIS | SRC_DDAC2 | SRC_DADC)); + outl(r, s->io + ES1371_REG_SRCONV); + spin_unlock_irqrestore(&s->lock, flags); +} + +static void set_dac2_rate(struct es1371_state *s, unsigned rate) +{ + unsigned long flags; + unsigned int freq, r; + + if (rate > 48000) + rate = 48000; + if (rate < 4000) + rate = 4000; + freq = ((rate << 15) + 1500) / 3000; + s->dac2rate = (freq * 3000 + 16384) >> 15; + spin_lock_irqsave(&s->lock, flags); + r = (wait_src_ready(s) & (SRC_DIS | SRC_DDAC1 | SRC_DADC)) | SRC_DDAC2; + outl(r, s->io + ES1371_REG_SRCONV); + src_write(s, SRCREG_DAC2+SRCREG_INT_REGS, + (src_read(s, SRCREG_DAC2+SRCREG_INT_REGS) & 0x00ff) | + ((freq >> 5) & 0xfc00)); + src_write(s, SRCREG_DAC2+SRCREG_VFREQ_FRAC, freq & 0x7fff); + r = (wait_src_ready(s) & (SRC_DIS | SRC_DDAC1 | SRC_DADC)); + outl(r, s->io + ES1371_REG_SRCONV); + spin_unlock_irqrestore(&s->lock, flags); +} + +/* --------------------------------------------------------------------- */ + +static void __devinit src_init(struct es1371_state *s) +{ + unsigned int i; + + /* before we enable or disable the SRC we need + to wait for it to become ready */ + wait_src_ready(s); + + outl(SRC_DIS, s->io + ES1371_REG_SRCONV); + + for (i = 0; i < 0x80; i++) + src_write(s, i, 0); + + src_write(s, SRCREG_DAC1+SRCREG_TRUNC_N, 16 << 4); + src_write(s, SRCREG_DAC1+SRCREG_INT_REGS, 16 << 10); + src_write(s, SRCREG_DAC2+SRCREG_TRUNC_N, 16 << 4); + src_write(s, SRCREG_DAC2+SRCREG_INT_REGS, 16 << 10); + src_write(s, SRCREG_VOL_ADC, 1 << 12); + src_write(s, SRCREG_VOL_ADC+1, 1 << 12); + src_write(s, SRCREG_VOL_DAC1, 1 << 12); + src_write(s, SRCREG_VOL_DAC1+1, 1 << 12); + src_write(s, SRCREG_VOL_DAC2, 1 << 12); + src_write(s, SRCREG_VOL_DAC2+1, 1 << 12); + set_adc_rate(s, 22050); + set_dac1_rate(s, 22050); + set_dac2_rate(s, 22050); + + /* WARNING: + * enabling the sample rate converter without properly programming + * its parameters causes the chip to lock up (the SRC busy bit will + * be stuck high, and I've found no way to rectify this other than + * power cycle) + */ + wait_src_ready(s); + outl(0, s->io+ES1371_REG_SRCONV); +} + +/* --------------------------------------------------------------------- */ + +static void wrcodec(struct ac97_codec *codec, u8 addr, u16 data) +{ + struct es1371_state *s = (struct es1371_state *)codec->private_data; + unsigned long flags; + unsigned t, x; + + spin_lock_irqsave(&s->lock, flags); + for (t = 0; t < POLL_COUNT; t++) + if (!(inl(s->io+ES1371_REG_CODEC) & CODEC_WIP)) + break; + + /* save the current state for later */ + x = wait_src_ready(s); + + /* enable SRC state data in SRC mux */ + outl((x & (SRC_DIS | SRC_DDAC1 | SRC_DDAC2 | SRC_DADC)) | 0x00010000, + s->io+ES1371_REG_SRCONV); + + /* wait for not busy (state 0) first to avoid + transition states */ + for (t=0; tio+ES1371_REG_SRCONV) & 0x00870000) ==0 ) + break; + udelay(1); + } + + /* wait for a SAFE time to write addr/data and then do it, dammit */ + for (t=0; tio+ES1371_REG_SRCONV) & 0x00870000) ==0x00010000) + break; + udelay(1); + } + + outl(((addr << CODEC_POADD_SHIFT) & CODEC_POADD_MASK) | + ((data << CODEC_PODAT_SHIFT) & CODEC_PODAT_MASK), s->io+ES1371_REG_CODEC); + + /* restore SRC reg */ + wait_src_ready(s); + outl(x, s->io+ES1371_REG_SRCONV); + spin_unlock_irqrestore(&s->lock, flags); +} + +static u16 rdcodec(struct ac97_codec *codec, u8 addr) +{ + struct es1371_state *s = (struct es1371_state *)codec->private_data; + unsigned long flags; + unsigned t, x; + + spin_lock_irqsave(&s->lock, flags); + + /* wait for WIP to go away */ + for (t = 0; t < 0x1000; t++) + if (!(inl(s->io+ES1371_REG_CODEC) & CODEC_WIP)) + break; + + /* save the current state for later */ + x = (wait_src_ready(s) & (SRC_DIS | SRC_DDAC1 | SRC_DDAC2 | SRC_DADC)); + + /* enable SRC state data in SRC mux */ + outl( x | 0x00010000, + s->io+ES1371_REG_SRCONV); + + /* wait for not busy (state 0) first to avoid + transition states */ + for (t=0; tio+ES1371_REG_SRCONV) & 0x00870000) ==0 ) + break; + udelay(1); + } + + /* wait for a SAFE time to write addr/data and then do it, dammit */ + for (t=0; tio+ES1371_REG_SRCONV) & 0x00870000) ==0x00010000) + break; + udelay(1); + } + + outl(((addr << CODEC_POADD_SHIFT) & CODEC_POADD_MASK) | CODEC_PORD, s->io+ES1371_REG_CODEC); + /* restore SRC reg */ + wait_src_ready(s); + outl(x, s->io+ES1371_REG_SRCONV); + + /* wait for WIP again */ + for (t = 0; t < 0x1000; t++) + if (!(inl(s->io+ES1371_REG_CODEC) & CODEC_WIP)) + break; + + /* now wait for the stinkin' data (RDY) */ + for (t = 0; t < POLL_COUNT; t++) + if ((x = inl(s->io+ES1371_REG_CODEC)) & CODEC_RDY) + break; + + spin_unlock_irqrestore(&s->lock, flags); + return ((x & CODEC_PIDAT_MASK) >> CODEC_PIDAT_SHIFT); +} + +/* --------------------------------------------------------------------- */ + +static inline void stop_adc(struct es1371_state *s) +{ + unsigned long flags; + + spin_lock_irqsave(&s->lock, flags); + s->ctrl &= ~CTRL_ADC_EN; + outl(s->ctrl, s->io+ES1371_REG_CONTROL); + spin_unlock_irqrestore(&s->lock, flags); +} + +static inline void stop_dac1(struct es1371_state *s) +{ + unsigned long flags; + + spin_lock_irqsave(&s->lock, flags); + s->ctrl &= ~CTRL_DAC1_EN; + outl(s->ctrl, s->io+ES1371_REG_CONTROL); + spin_unlock_irqrestore(&s->lock, flags); +} + +static inline void stop_dac2(struct es1371_state *s) +{ + unsigned long flags; + + spin_lock_irqsave(&s->lock, flags); + s->ctrl &= ~CTRL_DAC2_EN; + outl(s->ctrl, s->io+ES1371_REG_CONTROL); + spin_unlock_irqrestore(&s->lock, flags); +} + +static void start_dac1(struct es1371_state *s) +{ + unsigned long flags; + unsigned fragremain, fshift; + + spin_lock_irqsave(&s->lock, flags); + if (!(s->ctrl & CTRL_DAC1_EN) && (s->dma_dac1.mapped || s->dma_dac1.count > 0) + && s->dma_dac1.ready) { + s->ctrl |= CTRL_DAC1_EN; + s->sctrl = (s->sctrl & ~(SCTRL_P1LOOPSEL | SCTRL_P1PAUSE | SCTRL_P1SCTRLD)) | SCTRL_P1INTEN; + outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL); + fragremain = ((- s->dma_dac1.hwptr) & (s->dma_dac1.fragsize-1)); + fshift = sample_shift[(s->sctrl & SCTRL_P1FMT) >> SCTRL_SH_P1FMT]; + if (fragremain < 2*fshift) + fragremain = s->dma_dac1.fragsize; + outl((fragremain >> fshift) - 1, s->io+ES1371_REG_DAC1_SCOUNT); + outl(s->ctrl, s->io+ES1371_REG_CONTROL); + outl((s->dma_dac1.fragsize >> fshift) - 1, s->io+ES1371_REG_DAC1_SCOUNT); + } + spin_unlock_irqrestore(&s->lock, flags); +} + +static void start_dac2(struct es1371_state *s) +{ + unsigned long flags; + unsigned fragremain, fshift; + + spin_lock_irqsave(&s->lock, flags); + if (!(s->ctrl & CTRL_DAC2_EN) && (s->dma_dac2.mapped || s->dma_dac2.count > 0) + && s->dma_dac2.ready) { + s->ctrl |= CTRL_DAC2_EN; + s->sctrl = (s->sctrl & ~(SCTRL_P2LOOPSEL | SCTRL_P2PAUSE | SCTRL_P2DACSEN | + SCTRL_P2ENDINC | SCTRL_P2STINC)) | SCTRL_P2INTEN | + (((s->sctrl & SCTRL_P2FMT) ? 2 : 1) << SCTRL_SH_P2ENDINC) | + (0 << SCTRL_SH_P2STINC); + outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL); + fragremain = ((- s->dma_dac2.hwptr) & (s->dma_dac2.fragsize-1)); + fshift = sample_shift[(s->sctrl & SCTRL_P2FMT) >> SCTRL_SH_P2FMT]; + if (fragremain < 2*fshift) + fragremain = s->dma_dac2.fragsize; + outl((fragremain >> fshift) - 1, s->io+ES1371_REG_DAC2_SCOUNT); + outl(s->ctrl, s->io+ES1371_REG_CONTROL); + outl((s->dma_dac2.fragsize >> fshift) - 1, s->io+ES1371_REG_DAC2_SCOUNT); + } + spin_unlock_irqrestore(&s->lock, flags); +} + +static void start_adc(struct es1371_state *s) +{ + unsigned long flags; + unsigned fragremain, fshift; + + spin_lock_irqsave(&s->lock, flags); + if (!(s->ctrl & CTRL_ADC_EN) && (s->dma_adc.mapped || s->dma_adc.count < (signed)(s->dma_adc.dmasize - 2*s->dma_adc.fragsize)) + && s->dma_adc.ready) { + s->ctrl |= CTRL_ADC_EN; + s->sctrl = (s->sctrl & ~SCTRL_R1LOOPSEL) | SCTRL_R1INTEN; + outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL); + fragremain = ((- s->dma_adc.hwptr) & (s->dma_adc.fragsize-1)); + fshift = sample_shift[(s->sctrl & SCTRL_R1FMT) >> SCTRL_SH_R1FMT]; + if (fragremain < 2*fshift) + fragremain = s->dma_adc.fragsize; + outl((fragremain >> fshift) - 1, s->io+ES1371_REG_ADC_SCOUNT); + outl(s->ctrl, s->io+ES1371_REG_CONTROL); + outl((s->dma_adc.fragsize >> fshift) - 1, s->io+ES1371_REG_ADC_SCOUNT); + } + spin_unlock_irqrestore(&s->lock, flags); +} + +/* --------------------------------------------------------------------- */ + +#define DMABUF_DEFAULTORDER (17-PAGE_SHIFT) +#define DMABUF_MINORDER 1 + + +static inline void dealloc_dmabuf(struct es1371_state *s, struct dmabuf *db) +{ + struct page *page, *pend; + + if (db->rawbuf) { + /* undo marking the pages as reserved */ + pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1); + for (page = virt_to_page(db->rawbuf); page <= pend; page++) + ClearPageReserved(page); + pci_free_consistent(s->dev, PAGE_SIZE << db->buforder, db->rawbuf, db->dmaaddr); + } + db->rawbuf = NULL; + db->mapped = db->ready = 0; +} + +static int prog_dmabuf(struct es1371_state *s, struct dmabuf *db, unsigned rate, unsigned fmt, unsigned reg) +{ + int order; + unsigned bytepersec; + unsigned bufs; + struct page *page, *pend; + + db->hwptr = db->swptr = db->total_bytes = db->count = db->error = db->endcleared = 0; + if (!db->rawbuf) { + db->ready = db->mapped = 0; + for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--) + if ((db->rawbuf = pci_alloc_consistent(s->dev, PAGE_SIZE << order, &db->dmaaddr))) + break; + if (!db->rawbuf) + return -ENOMEM; + db->buforder = order; + /* now mark the pages as reserved; otherwise remap_pfn_range doesn't do what we want */ + pend = virt_to_page(db->rawbuf + (PAGE_SIZE << db->buforder) - 1); + for (page = virt_to_page(db->rawbuf); page <= pend; page++) + SetPageReserved(page); + } + fmt &= ES1371_FMT_MASK; + bytepersec = rate << sample_shift[fmt]; + bufs = PAGE_SIZE << db->buforder; + if (db->ossfragshift) { + if ((1000 << db->ossfragshift) < bytepersec) + db->fragshift = ld2(bytepersec/1000); + else + db->fragshift = db->ossfragshift; + } else { + db->fragshift = ld2(bytepersec/100/(db->subdivision ? db->subdivision : 1)); + if (db->fragshift < 3) + db->fragshift = 3; + } + db->numfrag = bufs >> db->fragshift; + while (db->numfrag < 4 && db->fragshift > 3) { + db->fragshift--; + db->numfrag = bufs >> db->fragshift; + } + db->fragsize = 1 << db->fragshift; + if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag) + db->numfrag = db->ossmaxfrags; + db->fragsamples = db->fragsize >> sample_shift[fmt]; + db->dmasize = db->numfrag << db->fragshift; + memset(db->rawbuf, (fmt & ES1371_FMT_S16) ? 0 : 0x80, db->dmasize); + outl((reg >> 8) & 15, s->io+ES1371_REG_MEMPAGE); + outl(db->dmaaddr, s->io+(reg & 0xff)); + outl((db->dmasize >> 2)-1, s->io+((reg + 4) & 0xff)); + db->enabled = 1; + db->ready = 1; + return 0; +} + +static inline int prog_dmabuf_adc(struct es1371_state *s) +{ + stop_adc(s); + return prog_dmabuf(s, &s->dma_adc, s->adcrate, (s->sctrl >> SCTRL_SH_R1FMT) & ES1371_FMT_MASK, + ES1371_REG_ADC_FRAMEADR); +} + +static inline int prog_dmabuf_dac2(struct es1371_state *s) +{ + stop_dac2(s); + return prog_dmabuf(s, &s->dma_dac2, s->dac2rate, (s->sctrl >> SCTRL_SH_P2FMT) & ES1371_FMT_MASK, + ES1371_REG_DAC2_FRAMEADR); +} + +static inline int prog_dmabuf_dac1(struct es1371_state *s) +{ + stop_dac1(s); + return prog_dmabuf(s, &s->dma_dac1, s->dac1rate, (s->sctrl >> SCTRL_SH_P1FMT) & ES1371_FMT_MASK, + ES1371_REG_DAC1_FRAMEADR); +} + +static inline unsigned get_hwptr(struct es1371_state *s, struct dmabuf *db, unsigned reg) +{ + unsigned hwptr, diff; + + outl((reg >> 8) & 15, s->io+ES1371_REG_MEMPAGE); + hwptr = (inl(s->io+(reg & 0xff)) >> 14) & 0x3fffc; + diff = (db->dmasize + hwptr - db->hwptr) % db->dmasize; + db->hwptr = hwptr; + return diff; +} + +static inline void clear_advance(void *buf, unsigned bsize, unsigned bptr, unsigned len, unsigned char c) +{ + if (bptr + len > bsize) { + unsigned x = bsize - bptr; + memset(((char *)buf) + bptr, c, x); + bptr = 0; + len -= x; + } + memset(((char *)buf) + bptr, c, len); +} + +/* call with spinlock held! */ +static void es1371_update_ptr(struct es1371_state *s) +{ + int diff; + + /* update ADC pointer */ + if (s->ctrl & CTRL_ADC_EN) { + diff = get_hwptr(s, &s->dma_adc, ES1371_REG_ADC_FRAMECNT); + s->dma_adc.total_bytes += diff; + s->dma_adc.count += diff; + if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) + wake_up(&s->dma_adc.wait); + if (!s->dma_adc.mapped) { + if (s->dma_adc.count > (signed)(s->dma_adc.dmasize - ((3 * s->dma_adc.fragsize) >> 1))) { + s->ctrl &= ~CTRL_ADC_EN; + outl(s->ctrl, s->io+ES1371_REG_CONTROL); + s->dma_adc.error++; + } + } + } + /* update DAC1 pointer */ + if (s->ctrl & CTRL_DAC1_EN) { + diff = get_hwptr(s, &s->dma_dac1, ES1371_REG_DAC1_FRAMECNT); + s->dma_dac1.total_bytes += diff; + if (s->dma_dac1.mapped) { + s->dma_dac1.count += diff; + if (s->dma_dac1.count >= (signed)s->dma_dac1.fragsize) + wake_up(&s->dma_dac1.wait); + } else { + s->dma_dac1.count -= diff; + if (s->dma_dac1.count <= 0) { + s->ctrl &= ~CTRL_DAC1_EN; + outl(s->ctrl, s->io+ES1371_REG_CONTROL); + s->dma_dac1.error++; + } else if (s->dma_dac1.count <= (signed)s->dma_dac1.fragsize && !s->dma_dac1.endcleared) { + clear_advance(s->dma_dac1.rawbuf, s->dma_dac1.dmasize, s->dma_dac1.swptr, + s->dma_dac1.fragsize, (s->sctrl & SCTRL_P1SEB) ? 0 : 0x80); + s->dma_dac1.endcleared = 1; + } + if (s->dma_dac1.count + (signed)s->dma_dac1.fragsize <= (signed)s->dma_dac1.dmasize) + wake_up(&s->dma_dac1.wait); + } + } + /* update DAC2 pointer */ + if (s->ctrl & CTRL_DAC2_EN) { + diff = get_hwptr(s, &s->dma_dac2, ES1371_REG_DAC2_FRAMECNT); + s->dma_dac2.total_bytes += diff; + if (s->dma_dac2.mapped) { + s->dma_dac2.count += diff; + if (s->dma_dac2.count >= (signed)s->dma_dac2.fragsize) + wake_up(&s->dma_dac2.wait); + } else { + s->dma_dac2.count -= diff; + if (s->dma_dac2.count <= 0) { + s->ctrl &= ~CTRL_DAC2_EN; + outl(s->ctrl, s->io+ES1371_REG_CONTROL); + s->dma_dac2.error++; + } else if (s->dma_dac2.count <= (signed)s->dma_dac2.fragsize && !s->dma_dac2.endcleared) { + clear_advance(s->dma_dac2.rawbuf, s->dma_dac2.dmasize, s->dma_dac2.swptr, + s->dma_dac2.fragsize, (s->sctrl & SCTRL_P2SEB) ? 0 : 0x80); + s->dma_dac2.endcleared = 1; + } + if (s->dma_dac2.count + (signed)s->dma_dac2.fragsize <= (signed)s->dma_dac2.dmasize) + wake_up(&s->dma_dac2.wait); + } + } +} + +/* hold spinlock for the following! */ +static void es1371_handle_midi(struct es1371_state *s) +{ + unsigned char ch; + int wake; + + if (!(s->ctrl & CTRL_UART_EN)) + return; + wake = 0; + while (inb(s->io+ES1371_REG_UART_STATUS) & USTAT_RXRDY) { + ch = inb(s->io+ES1371_REG_UART_DATA); + if (s->midi.icnt < MIDIINBUF) { + s->midi.ibuf[s->midi.iwr] = ch; + s->midi.iwr = (s->midi.iwr + 1) % MIDIINBUF; + s->midi.icnt++; + } + wake = 1; + } + if (wake) + wake_up(&s->midi.iwait); + wake = 0; + while ((inb(s->io+ES1371_REG_UART_STATUS) & USTAT_TXRDY) && s->midi.ocnt > 0) { + outb(s->midi.obuf[s->midi.ord], s->io+ES1371_REG_UART_DATA); + s->midi.ord = (s->midi.ord + 1) % MIDIOUTBUF; + s->midi.ocnt--; + if (s->midi.ocnt < MIDIOUTBUF-16) + wake = 1; + } + if (wake) + wake_up(&s->midi.owait); + outb((s->midi.ocnt > 0) ? UCTRL_RXINTEN | UCTRL_ENA_TXINT : UCTRL_RXINTEN, s->io+ES1371_REG_UART_CONTROL); +} + +static irqreturn_t es1371_interrupt(int irq, void *dev_id) +{ + struct es1371_state *s = dev_id; + unsigned int intsrc, sctl; + + /* fastpath out, to ease interrupt sharing */ + intsrc = inl(s->io+ES1371_REG_STATUS); + if (!(intsrc & 0x80000000)) + return IRQ_NONE; + spin_lock(&s->lock); + /* clear audio interrupts first */ + sctl = s->sctrl; + if (intsrc & STAT_ADC) + sctl &= ~SCTRL_R1INTEN; + if (intsrc & STAT_DAC1) + sctl &= ~SCTRL_P1INTEN; + if (intsrc & STAT_DAC2) + sctl &= ~SCTRL_P2INTEN; + outl(sctl, s->io+ES1371_REG_SERIAL_CONTROL); + outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL); + es1371_update_ptr(s); + es1371_handle_midi(s); + spin_unlock(&s->lock); + return IRQ_HANDLED; +} + +/* --------------------------------------------------------------------- */ + +static const char invalid_magic[] = KERN_CRIT PFX "invalid magic value\n"; + +#define VALIDATE_STATE(s) \ +({ \ + if (!(s) || (s)->magic != ES1371_MAGIC) { \ + printk(invalid_magic); \ + return -ENXIO; \ + } \ +}) + +/* --------------------------------------------------------------------- */ + +/* Conversion table for S/PDIF PCM volume emulation through the SRC */ +/* dB-linear table of DAC vol values; -0dB to -46.5dB with mute */ +static const unsigned short DACVolTable[101] = +{ + 0x1000, 0x0f2a, 0x0e60, 0x0da0, 0x0cea, 0x0c3e, 0x0b9a, 0x0aff, + 0x0a6d, 0x09e1, 0x095e, 0x08e1, 0x086a, 0x07fa, 0x078f, 0x072a, + 0x06cb, 0x0670, 0x061a, 0x05c9, 0x057b, 0x0532, 0x04ed, 0x04ab, + 0x046d, 0x0432, 0x03fa, 0x03c5, 0x0392, 0x0363, 0x0335, 0x030b, + 0x02e2, 0x02bc, 0x0297, 0x0275, 0x0254, 0x0235, 0x0217, 0x01fb, + 0x01e1, 0x01c8, 0x01b0, 0x0199, 0x0184, 0x0170, 0x015d, 0x014b, + 0x0139, 0x0129, 0x0119, 0x010b, 0x00fd, 0x00f0, 0x00e3, 0x00d7, + 0x00cc, 0x00c1, 0x00b7, 0x00ae, 0x00a5, 0x009c, 0x0094, 0x008c, + 0x0085, 0x007e, 0x0077, 0x0071, 0x006b, 0x0066, 0x0060, 0x005b, + 0x0057, 0x0052, 0x004e, 0x004a, 0x0046, 0x0042, 0x003f, 0x003c, + 0x0038, 0x0036, 0x0033, 0x0030, 0x002e, 0x002b, 0x0029, 0x0027, + 0x0025, 0x0023, 0x0021, 0x001f, 0x001e, 0x001c, 0x001b, 0x0019, + 0x0018, 0x0017, 0x0016, 0x0014, 0x0000 +}; + +/* + * when we are in S/PDIF mode, we want to disable any analog output so + * we filter the mixer ioctls + */ +static int mixdev_ioctl(struct ac97_codec *codec, unsigned int cmd, unsigned long arg) +{ + struct es1371_state *s = (struct es1371_state *)codec->private_data; + int val; + unsigned long flags; + unsigned int left, right; + + VALIDATE_STATE(s); + /* filter mixer ioctls to catch PCM and MASTER volume when in S/PDIF mode */ + if (s->spdif_volume == -1) + return codec->mixer_ioctl(codec, cmd, arg); + switch (cmd) { + case SOUND_MIXER_WRITE_VOLUME: + return 0; + + case SOUND_MIXER_WRITE_PCM: /* use SRC for PCM volume */ + if (get_user(val, (int __user *)arg)) + return -EFAULT; + right = ((val >> 8) & 0xff); + left = (val & 0xff); + if (right > 100) + right = 100; + if (left > 100) + left = 100; + s->spdif_volume = (right << 8) | left; + spin_lock_irqsave(&s->lock, flags); + src_write(s, SRCREG_VOL_DAC2, DACVolTable[100 - left]); + src_write(s, SRCREG_VOL_DAC2+1, DACVolTable[100 - right]); + spin_unlock_irqrestore(&s->lock, flags); + return 0; + + case SOUND_MIXER_READ_PCM: + return put_user(s->spdif_volume, (int __user *)arg); + } + return codec->mixer_ioctl(codec, cmd, arg); +} + +/* --------------------------------------------------------------------- */ + +/* + * AC97 Mixer Register to Connections mapping of the Concert 97 board + * + * AC97_MASTER_VOL_STEREO Line Out + * AC97_MASTER_VOL_MONO TAD Output + * AC97_PCBEEP_VOL none + * AC97_PHONE_VOL TAD Input (mono) + * AC97_MIC_VOL MIC Input (mono) + * AC97_LINEIN_VOL Line Input (stereo) + * AC97_CD_VOL CD Input (stereo) + * AC97_VIDEO_VOL none + * AC97_AUX_VOL Aux Input (stereo) + * AC97_PCMOUT_VOL Wave Output (stereo) + */ + +static int es1371_open_mixdev(struct inode *inode, struct file *file) +{ + int minor = iminor(inode); + struct list_head *list; + struct es1371_state *s; + + for (list = devs.next; ; list = list->next) { + if (list == &devs) + return -ENODEV; + s = list_entry(list, struct es1371_state, devs); + if (s->codec->dev_mixer == minor) + break; + } + VALIDATE_STATE(s); + file->private_data = s; + return nonseekable_open(inode, file); +} + +static int es1371_release_mixdev(struct inode *inode, struct file *file) +{ + struct es1371_state *s = (struct es1371_state *)file->private_data; + + VALIDATE_STATE(s); + return 0; +} + +static int es1371_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +{ + struct es1371_state *s = (struct es1371_state *)file->private_data; + struct ac97_codec *codec = s->codec; + + return mixdev_ioctl(codec, cmd, arg); +} + +static /*const*/ struct file_operations es1371_mixer_fops = { + .owner = THIS_MODULE, + .llseek = no_llseek, + .ioctl = es1371_ioctl_mixdev, + .open = es1371_open_mixdev, + .release = es1371_release_mixdev, +}; + +/* --------------------------------------------------------------------- */ + +static int drain_dac1(struct es1371_state *s, int nonblock) +{ + DECLARE_WAITQUEUE(wait, current); + unsigned long flags; + int count, tmo; + + if (s->dma_dac1.mapped || !s->dma_dac1.ready) + return 0; + add_wait_queue(&s->dma_dac1.wait, &wait); + for (;;) { + __set_current_state(TASK_INTERRUPTIBLE); + spin_lock_irqsave(&s->lock, flags); + count = s->dma_dac1.count; + spin_unlock_irqrestore(&s->lock, flags); + if (count <= 0) + break; + if (signal_pending(current)) + break; + if (nonblock) { + remove_wait_queue(&s->dma_dac1.wait, &wait); + set_current_state(TASK_RUNNING); + return -EBUSY; + } + tmo = 3 * HZ * (count + s->dma_dac1.fragsize) / 2 / s->dac1rate; + tmo >>= sample_shift[(s->sctrl & SCTRL_P1FMT) >> SCTRL_SH_P1FMT]; + if (!schedule_timeout(tmo + 1)) + DBG(printk(KERN_DEBUG PFX "dac1 dma timed out??\n");) + } + remove_wait_queue(&s->dma_dac1.wait, &wait); + set_current_state(TASK_RUNNING); + if (signal_pending(current)) + return -ERESTARTSYS; + return 0; +} + +static int drain_dac2(struct es1371_state *s, int nonblock) +{ + DECLARE_WAITQUEUE(wait, current); + unsigned long flags; + int count, tmo; + + if (s->dma_dac2.mapped || !s->dma_dac2.ready) + return 0; + add_wait_queue(&s->dma_dac2.wait, &wait); + for (;;) { + __set_current_state(TASK_UNINTERRUPTIBLE); + spin_lock_irqsave(&s->lock, flags); + count = s->dma_dac2.count; + spin_unlock_irqrestore(&s->lock, flags); + if (count <= 0) + break; + if (signal_pending(current)) + break; + if (nonblock) { + remove_wait_queue(&s->dma_dac2.wait, &wait); + set_current_state(TASK_RUNNING); + return -EBUSY; + } + tmo = 3 * HZ * (count + s->dma_dac2.fragsize) / 2 / s->dac2rate; + tmo >>= sample_shift[(s->sctrl & SCTRL_P2FMT) >> SCTRL_SH_P2FMT]; + if (!schedule_timeout(tmo + 1)) + DBG(printk(KERN_DEBUG PFX "dac2 dma timed out??\n");) + } + remove_wait_queue(&s->dma_dac2.wait, &wait); + set_current_state(TASK_RUNNING); + if (signal_pending(current)) + return -ERESTARTSYS; + return 0; +} + +/* --------------------------------------------------------------------- */ + +static ssize_t es1371_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) +{ + struct es1371_state *s = (struct es1371_state *)file->private_data; + DECLARE_WAITQUEUE(wait, current); + ssize_t ret = 0; + unsigned long flags; + unsigned swptr; + int cnt; + + VALIDATE_STATE(s); + if (s->dma_adc.mapped) + return -ENXIO; + if (!access_ok(VERIFY_WRITE, buffer, count)) + return -EFAULT; + mutex_lock(&s->sem); + if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s))) + goto out2; + + add_wait_queue(&s->dma_adc.wait, &wait); + while (count > 0) { + spin_lock_irqsave(&s->lock, flags); + swptr = s->dma_adc.swptr; + cnt = s->dma_adc.dmasize-swptr; + if (s->dma_adc.count < cnt) + cnt = s->dma_adc.count; + if (cnt <= 0) + __set_current_state(TASK_INTERRUPTIBLE); + spin_unlock_irqrestore(&s->lock, flags); + if (cnt > count) + cnt = count; + if (cnt <= 0) { + if (s->dma_adc.enabled) + start_adc(s); + if (file->f_flags & O_NONBLOCK) { + if (!ret) + ret = -EAGAIN; + goto out; + } + mutex_unlock(&s->sem); + schedule(); + if (signal_pending(current)) { + if (!ret) + ret = -ERESTARTSYS; + goto out2; + } + mutex_lock(&s->sem); + if (s->dma_adc.mapped) + { + ret = -ENXIO; + goto out; + } + continue; + } + if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) { + if (!ret) + ret = -EFAULT; + goto out; + } + swptr = (swptr + cnt) % s->dma_adc.dmasize; + spin_lock_irqsave(&s->lock, flags); + s->dma_adc.swptr = swptr; + s->dma_adc.count -= cnt; + spin_unlock_irqrestore(&s->lock, flags); + count -= cnt; + buffer += cnt; + ret += cnt; + if (s->dma_adc.enabled) + start_adc(s); + } +out: + mutex_unlock(&s->sem); +out2: + remove_wait_queue(&s->dma_adc.wait, &wait); + set_current_state(TASK_RUNNING); + return ret; +} + +static ssize_t es1371_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) +{ + struct es1371_state *s = (struct es1371_state *)file->private_data; + DECLARE_WAITQUEUE(wait, current); + ssize_t ret; + unsigned long flags; + unsigned swptr; + int cnt; + + VALIDATE_STATE(s); + if (s->dma_dac2.mapped) + return -ENXIO; + if (!access_ok(VERIFY_READ, buffer, count)) + return -EFAULT; + mutex_lock(&s->sem); + if (!s->dma_dac2.ready && (ret = prog_dmabuf_dac2(s))) + goto out3; + ret = 0; + add_wait_queue(&s->dma_dac2.wait, &wait); + while (count > 0) { + spin_lock_irqsave(&s->lock, flags); + if (s->dma_dac2.count < 0) { + s->dma_dac2.count = 0; + s->dma_dac2.swptr = s->dma_dac2.hwptr; + } + swptr = s->dma_dac2.swptr; + cnt = s->dma_dac2.dmasize-swptr; + if (s->dma_dac2.count + cnt > s->dma_dac2.dmasize) + cnt = s->dma_dac2.dmasize - s->dma_dac2.count; + if (cnt <= 0) + __set_current_state(TASK_INTERRUPTIBLE); + spin_unlock_irqrestore(&s->lock, flags); + if (cnt > count) + cnt = count; + if (cnt <= 0) { + if (s->dma_dac2.enabled) + start_dac2(s); + if (file->f_flags & O_NONBLOCK) { + if (!ret) + ret = -EAGAIN; + goto out; + } + mutex_unlock(&s->sem); + schedule(); + if (signal_pending(current)) { + if (!ret) + ret = -ERESTARTSYS; + goto out2; + } + mutex_lock(&s->sem); + if (s->dma_dac2.mapped) + { + ret = -ENXIO; + goto out; + } + continue; + } + if (copy_from_user(s->dma_dac2.rawbuf + swptr, buffer, cnt)) { + if (!ret) + ret = -EFAULT; + goto out; + } + swptr = (swptr + cnt) % s->dma_dac2.dmasize; + spin_lock_irqsave(&s->lock, flags); + s->dma_dac2.swptr = swptr; + s->dma_dac2.count += cnt; + s->dma_dac2.endcleared = 0; + spin_unlock_irqrestore(&s->lock, flags); + count -= cnt; + buffer += cnt; + ret += cnt; + if (s->dma_dac2.enabled) + start_dac2(s); + } +out: + mutex_unlock(&s->sem); +out2: + remove_wait_queue(&s->dma_dac2.wait, &wait); +out3: + set_current_state(TASK_RUNNING); + return ret; +} + +/* No kernel lock - we have our own spinlock */ +static unsigned int es1371_poll(struct file *file, struct poll_table_struct *wait) +{ + struct es1371_state *s = (struct es1371_state *)file->private_data; + unsigned long flags; + unsigned int mask = 0; + + VALIDATE_STATE(s); + if (file->f_mode & FMODE_WRITE) { + if (!s->dma_dac2.ready && prog_dmabuf_dac2(s)) + return 0; + poll_wait(file, &s->dma_dac2.wait, wait); + } + if (file->f_mode & FMODE_READ) { + if (!s->dma_adc.ready && prog_dmabuf_adc(s)) + return 0; + poll_wait(file, &s->dma_adc.wait, wait); + } + spin_lock_irqsave(&s->lock, flags); + es1371_update_ptr(s); + if (file->f_mode & FMODE_READ) { + if (s->dma_adc.count >= (signed)s->dma_adc.fragsize) + mask |= POLLIN | POLLRDNORM; + } + if (file->f_mode & FMODE_WRITE) { + if (s->dma_dac2.mapped) { + if (s->dma_dac2.count >= (signed)s->dma_dac2.fragsize) + mask |= POLLOUT | POLLWRNORM; + } else { + if ((signed)s->dma_dac2.dmasize >= s->dma_dac2.count + (signed)s->dma_dac2.fragsize) + mask |= POLLOUT | POLLWRNORM; + } + } + spin_unlock_irqrestore(&s->lock, flags); + return mask; +} + +static int es1371_mmap(struct file *file, struct vm_area_struct *vma) +{ + struct es1371_state *s = (struct es1371_state *)file->private_data; + struct dmabuf *db; + int ret = 0; + unsigned long size; + + VALIDATE_STATE(s); + lock_kernel(); + mutex_lock(&s->sem); + + if (vma->vm_flags & VM_WRITE) { + if ((ret = prog_dmabuf_dac2(s)) != 0) { + goto out; + } + db = &s->dma_dac2; + } else if (vma->vm_flags & VM_READ) { + if ((ret = prog_dmabuf_adc(s)) != 0) { + goto out; + } + db = &s->dma_adc; + } else { + ret = -EINVAL; + goto out; + } + if (vma->vm_pgoff != 0) { + ret = -EINVAL; + goto out; + } + size = vma->vm_end - vma->vm_start; + if (size > (PAGE_SIZE << db->buforder)) { + ret = -EINVAL; + goto out; + } + if (remap_pfn_range(vma, vma->vm_start, + virt_to_phys(db->rawbuf) >> PAGE_SHIFT, + size, vma->vm_page_prot)) { + ret = -EAGAIN; + goto out; + } + db->mapped = 1; +out: + mutex_unlock(&s->sem); + unlock_kernel(); + return ret; +} + +static int es1371_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +{ + struct es1371_state *s = (struct es1371_state *)file->private_data; + unsigned long flags; + audio_buf_info abinfo; + count_info cinfo; + int count; + int val, mapped, ret; + void __user *argp = (void __user *)arg; + int __user *p = argp; + + VALIDATE_STATE(s); + mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac2.mapped) || + ((file->f_mode & FMODE_READ) && s->dma_adc.mapped); + switch (cmd) { + case OSS_GETVERSION: + return put_user(SOUND_VERSION, p); + + case SNDCTL_DSP_SYNC: + if (file->f_mode & FMODE_WRITE) + return drain_dac2(s, 0/*file->f_flags & O_NONBLOCK*/); + return 0; + + case SNDCTL_DSP_SETDUPLEX: + return 0; + + case SNDCTL_DSP_GETCAPS: + return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, p); + + case SNDCTL_DSP_RESET: + if (file->f_mode & FMODE_WRITE) { + stop_dac2(s); + synchronize_irq(s->irq); + s->dma_dac2.swptr = s->dma_dac2.hwptr = s->dma_dac2.count = s->dma_dac2.total_bytes = 0; + } + if (file->f_mode & FMODE_READ) { + stop_adc(s); + synchronize_irq(s->irq); + s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count = s->dma_adc.total_bytes = 0; + } + return 0; + + case SNDCTL_DSP_SPEED: + if (get_user(val, p)) + return -EFAULT; + if (val >= 0) { + if (file->f_mode & FMODE_READ) { + stop_adc(s); + s->dma_adc.ready = 0; + set_adc_rate(s, val); + } + if (file->f_mode & FMODE_WRITE) { + stop_dac2(s); + s->dma_dac2.ready = 0; + set_dac2_rate(s, val); + } + } + return put_user((file->f_mode & FMODE_READ) ? s->adcrate : s->dac2rate, p); + + case SNDCTL_DSP_STEREO: + if (get_user(val, p)) + return -EFAULT; + if (file->f_mode & FMODE_READ) { + stop_adc(s); + s->dma_adc.ready = 0; + spin_lock_irqsave(&s->lock, flags); + if (val) + s->sctrl |= SCTRL_R1SMB; + else + s->sctrl &= ~SCTRL_R1SMB; + outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL); + spin_unlock_irqrestore(&s->lock, flags); + } + if (file->f_mode & FMODE_WRITE) { + stop_dac2(s); + s->dma_dac2.ready = 0; + spin_lock_irqsave(&s->lock, flags); + if (val) + s->sctrl |= SCTRL_P2SMB; + else + s->sctrl &= ~SCTRL_P2SMB; + outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL); + spin_unlock_irqrestore(&s->lock, flags); + } + return 0; + + case SNDCTL_DSP_CHANNELS: + if (get_user(val, p)) + return -EFAULT; + if (val != 0) { + if (file->f_mode & FMODE_READ) { + stop_adc(s); + s->dma_adc.ready = 0; + spin_lock_irqsave(&s->lock, flags); + if (val >= 2) + s->sctrl |= SCTRL_R1SMB; + else + s->sctrl &= ~SCTRL_R1SMB; + outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL); + spin_unlock_irqrestore(&s->lock, flags); + } + if (file->f_mode & FMODE_WRITE) { + stop_dac2(s); + s->dma_dac2.ready = 0; + spin_lock_irqsave(&s->lock, flags); + if (val >= 2) + s->sctrl |= SCTRL_P2SMB; + else + s->sctrl &= ~SCTRL_P2SMB; + outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL); + spin_unlock_irqrestore(&s->lock, flags); + } + } + return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SMB : SCTRL_P2SMB)) ? 2 : 1, p); + + case SNDCTL_DSP_GETFMTS: /* Returns a mask */ + return put_user(AFMT_S16_LE|AFMT_U8, p); + + case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/ + if (get_user(val, p)) + return -EFAULT; + if (val != AFMT_QUERY) { + if (file->f_mode & FMODE_READ) { + stop_adc(s); + s->dma_adc.ready = 0; + spin_lock_irqsave(&s->lock, flags); + if (val == AFMT_S16_LE) + s->sctrl |= SCTRL_R1SEB; + else + s->sctrl &= ~SCTRL_R1SEB; + outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL); + spin_unlock_irqrestore(&s->lock, flags); + } + if (file->f_mode & FMODE_WRITE) { + stop_dac2(s); + s->dma_dac2.ready = 0; + spin_lock_irqsave(&s->lock, flags); + if (val == AFMT_S16_LE) + s->sctrl |= SCTRL_P2SEB; + else + s->sctrl &= ~SCTRL_P2SEB; + outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL); + spin_unlock_irqrestore(&s->lock, flags); + } + } + return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SEB : SCTRL_P2SEB)) ? + AFMT_S16_LE : AFMT_U8, p); + + case SNDCTL_DSP_POST: + return 0; + + case SNDCTL_DSP_GETTRIGGER: + val = 0; + if (file->f_mode & FMODE_READ && s->ctrl & CTRL_ADC_EN) + val |= PCM_ENABLE_INPUT; + if (file->f_mode & FMODE_WRITE && s->ctrl & CTRL_DAC2_EN) + val |= PCM_ENABLE_OUTPUT; + return put_user(val, p); + + case SNDCTL_DSP_SETTRIGGER: + if (get_user(val, p)) + return -EFAULT; + if (file->f_mode & FMODE_READ) { + if (val & PCM_ENABLE_INPUT) { + if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s))) + return ret; + s->dma_adc.enabled = 1; + start_adc(s); + } else { + s->dma_adc.enabled = 0; + stop_adc(s); + } + } + if (file->f_mode & FMODE_WRITE) { + if (val & PCM_ENABLE_OUTPUT) { + if (!s->dma_dac2.ready && (ret = prog_dmabuf_dac2(s))) + return ret; + s->dma_dac2.enabled = 1; + start_dac2(s); + } else { + s->dma_dac2.enabled = 0; + stop_dac2(s); + } + } + return 0; + + case SNDCTL_DSP_GETOSPACE: + if (!(file->f_mode & FMODE_WRITE)) + return -EINVAL; + if (!s->dma_dac2.ready && (val = prog_dmabuf_dac2(s)) != 0) + return val; + spin_lock_irqsave(&s->lock, flags); + es1371_update_ptr(s); + abinfo.fragsize = s->dma_dac2.fragsize; + count = s->dma_dac2.count; + if (count < 0) + count = 0; + abinfo.bytes = s->dma_dac2.dmasize - count; + abinfo.fragstotal = s->dma_dac2.numfrag; + abinfo.fragments = abinfo.bytes >> s->dma_dac2.fragshift; + spin_unlock_irqrestore(&s->lock, flags); + return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0; + + case SNDCTL_DSP_GETISPACE: + if (!(file->f_mode & FMODE_READ)) + return -EINVAL; + if (!s->dma_adc.ready && (val = prog_dmabuf_adc(s)) != 0) + return val; + spin_lock_irqsave(&s->lock, flags); + es1371_update_ptr(s); + abinfo.fragsize = s->dma_adc.fragsize; + count = s->dma_adc.count; + if (count < 0) + count = 0; + abinfo.bytes = count; + abinfo.fragstotal = s->dma_adc.numfrag; + abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift; + spin_unlock_irqrestore(&s->lock, flags); + return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0; + + case SNDCTL_DSP_NONBLOCK: + file->f_flags |= O_NONBLOCK; + return 0; + + case SNDCTL_DSP_GETODELAY: + if (!(file->f_mode & FMODE_WRITE)) + return -EINVAL; + if (!s->dma_dac2.ready && (val = prog_dmabuf_dac2(s)) != 0) + return val; + spin_lock_irqsave(&s->lock, flags); + es1371_update_ptr(s); + count = s->dma_dac2.count; + spin_unlock_irqrestore(&s->lock, flags); + if (count < 0) + count = 0; + return put_user(count, p); + + case SNDCTL_DSP_GETIPTR: + if (!(file->f_mode & FMODE_READ)) + return -EINVAL; + if (!s->dma_adc.ready && (val = prog_dmabuf_adc(s)) != 0) + return val; + spin_lock_irqsave(&s->lock, flags); + es1371_update_ptr(s); + cinfo.bytes = s->dma_adc.total_bytes; + count = s->dma_adc.count; + if (count < 0) + count = 0; + cinfo.blocks = count >> s->dma_adc.fragshift; + cinfo.ptr = s->dma_adc.hwptr; + if (s->dma_adc.mapped) + s->dma_adc.count &= s->dma_adc.fragsize-1; + spin_unlock_irqrestore(&s->lock, flags); + if (copy_to_user(argp, &cinfo, sizeof(cinfo))) + return -EFAULT; + return 0; + + case SNDCTL_DSP_GETOPTR: + if (!(file->f_mode & FMODE_WRITE)) + return -EINVAL; + if (!s->dma_dac2.ready && (val = prog_dmabuf_dac2(s)) != 0) + return val; + spin_lock_irqsave(&s->lock, flags); + es1371_update_ptr(s); + cinfo.bytes = s->dma_dac2.total_bytes; + count = s->dma_dac2.count; + if (count < 0) + count = 0; + cinfo.blocks = count >> s->dma_dac2.fragshift; + cinfo.ptr = s->dma_dac2.hwptr; + if (s->dma_dac2.mapped) + s->dma_dac2.count &= s->dma_dac2.fragsize-1; + spin_unlock_irqrestore(&s->lock, flags); + if (copy_to_user(argp, &cinfo, sizeof(cinfo))) + return -EFAULT; + return 0; + + case SNDCTL_DSP_GETBLKSIZE: + if (file->f_mode & FMODE_WRITE) { + if ((val = prog_dmabuf_dac2(s))) + return val; + return put_user(s->dma_dac2.fragsize, p); + } + if ((val = prog_dmabuf_adc(s))) + return val; + return put_user(s->dma_adc.fragsize, p); + + case SNDCTL_DSP_SETFRAGMENT: + if (get_user(val, p)) + return -EFAULT; + if (file->f_mode & FMODE_READ) { + s->dma_adc.ossfragshift = val & 0xffff; + s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff; + if (s->dma_adc.ossfragshift < 4) + s->dma_adc.ossfragshift = 4; + if (s->dma_adc.ossfragshift > 15) + s->dma_adc.ossfragshift = 15; + if (s->dma_adc.ossmaxfrags < 4) + s->dma_adc.ossmaxfrags = 4; + } + if (file->f_mode & FMODE_WRITE) { + s->dma_dac2.ossfragshift = val & 0xffff; + s->dma_dac2.ossmaxfrags = (val >> 16) & 0xffff; + if (s->dma_dac2.ossfragshift < 4) + s->dma_dac2.ossfragshift = 4; + if (s->dma_dac2.ossfragshift > 15) + s->dma_dac2.ossfragshift = 15; + if (s->dma_dac2.ossmaxfrags < 4) + s->dma_dac2.ossmaxfrags = 4; + } + return 0; + + case SNDCTL_DSP_SUBDIVIDE: + if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) || + (file->f_mode & FMODE_WRITE && s->dma_dac2.subdivision)) + return -EINVAL; + if (get_user(val, p)) + return -EFAULT; + if (val != 1 && val != 2 && val != 4) + return -EINVAL; + if (file->f_mode & FMODE_READ) + s->dma_adc.subdivision = val; + if (file->f_mode & FMODE_WRITE) + s->dma_dac2.subdivision = val; + return 0; + + case SOUND_PCM_READ_RATE: + return put_user((file->f_mode & FMODE_READ) ? s->adcrate : s->dac2rate, p); + + case SOUND_PCM_READ_CHANNELS: + return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SMB : SCTRL_P2SMB)) ? 2 : 1, p); + + case SOUND_PCM_READ_BITS: + return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SEB : SCTRL_P2SEB)) ? 16 : 8, p); + + case SOUND_PCM_WRITE_FILTER: + case SNDCTL_DSP_SETSYNCRO: + case SOUND_PCM_READ_FILTER: + return -EINVAL; + + } + return mixdev_ioctl(s->codec, cmd, arg); +} + +static int es1371_open(struct inode *inode, struct file *file) +{ + int minor = iminor(inode); + DECLARE_WAITQUEUE(wait, current); + unsigned long flags; + struct list_head *list; + struct es1371_state *s; + + for (list = devs.next; ; list = list->next) { + if (list == &devs) + return -ENODEV; + s = list_entry(list, struct es1371_state, devs); + if (!((s->dev_audio ^ minor) & ~0xf)) + break; + } + VALIDATE_STATE(s); + file->private_data = s; + /* wait for device to become free */ + mutex_lock(&s->open_mutex); + while (s->open_mode & file->f_mode) { + if (file->f_flags & O_NONBLOCK) { + mutex_unlock(&s->open_mutex); + return -EBUSY; + } + add_wait_queue(&s->open_wait, &wait); + __set_current_state(TASK_INTERRUPTIBLE); + mutex_unlock(&s->open_mutex); + schedule(); + remove_wait_queue(&s->open_wait, &wait); + set_current_state(TASK_RUNNING); + if (signal_pending(current)) + return -ERESTARTSYS; + mutex_lock(&s->open_mutex); + } + if (file->f_mode & FMODE_READ) { + s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision = 0; + s->dma_adc.enabled = 1; + set_adc_rate(s, 8000); + } + if (file->f_mode & FMODE_WRITE) { + s->dma_dac2.ossfragshift = s->dma_dac2.ossmaxfrags = s->dma_dac2.subdivision = 0; + s->dma_dac2.enabled = 1; + set_dac2_rate(s, 8000); + } + spin_lock_irqsave(&s->lock, flags); + if (file->f_mode & FMODE_READ) { + s->sctrl &= ~SCTRL_R1FMT; + if ((minor & 0xf) == SND_DEV_DSP16) + s->sctrl |= ES1371_FMT_S16_MONO << SCTRL_SH_R1FMT; + else + s->sctrl |= ES1371_FMT_U8_MONO << SCTRL_SH_R1FMT; + } + if (file->f_mode & FMODE_WRITE) { + s->sctrl &= ~SCTRL_P2FMT; + if ((minor & 0xf) == SND_DEV_DSP16) + s->sctrl |= ES1371_FMT_S16_MONO << SCTRL_SH_P2FMT; + else + s->sctrl |= ES1371_FMT_U8_MONO << SCTRL_SH_P2FMT; + } + outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL); + spin_unlock_irqrestore(&s->lock, flags); + s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); + mutex_unlock(&s->open_mutex); + mutex_init(&s->sem); + return nonseekable_open(inode, file); +} + +static int es1371_release(struct inode *inode, struct file *file) +{ + struct es1371_state *s = (struct es1371_state *)file->private_data; + + VALIDATE_STATE(s); + lock_kernel(); + if (file->f_mode & FMODE_WRITE) + drain_dac2(s, file->f_flags & O_NONBLOCK); + mutex_lock(&s->open_mutex); + if (file->f_mode & FMODE_WRITE) { + stop_dac2(s); + dealloc_dmabuf(s, &s->dma_dac2); + } + if (file->f_mode & FMODE_READ) { + stop_adc(s); + dealloc_dmabuf(s, &s->dma_adc); + } + s->open_mode &= ~(file->f_mode & (FMODE_READ|FMODE_WRITE)); + mutex_unlock(&s->open_mutex); + wake_up(&s->open_wait); + unlock_kernel(); + return 0; +} + +static /*const*/ struct file_operations es1371_audio_fops = { + .owner = THIS_MODULE, + .llseek = no_llseek, + .read = es1371_read, + .write = es1371_write, + .poll = es1371_poll, + .ioctl = es1371_ioctl, + .mmap = es1371_mmap, + .open = es1371_open, + .release = es1371_release, +}; + +/* --------------------------------------------------------------------- */ + +static ssize_t es1371_write_dac(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) +{ + struct es1371_state *s = (struct es1371_state *)file->private_data; + DECLARE_WAITQUEUE(wait, current); + ssize_t ret = 0; + unsigned long flags; + unsigned swptr; + int cnt; + + VALIDATE_STATE(s); + if (s->dma_dac1.mapped) + return -ENXIO; + if (!s->dma_dac1.ready && (ret = prog_dmabuf_dac1(s))) + return ret; + if (!access_ok(VERIFY_READ, buffer, count)) + return -EFAULT; + add_wait_queue(&s->dma_dac1.wait, &wait); + while (count > 0) { + spin_lock_irqsave(&s->lock, flags); + if (s->dma_dac1.count < 0) { + s->dma_dac1.count = 0; + s->dma_dac1.swptr = s->dma_dac1.hwptr; + } + swptr = s->dma_dac1.swptr; + cnt = s->dma_dac1.dmasize-swptr; + if (s->dma_dac1.count + cnt > s->dma_dac1.dmasize) + cnt = s->dma_dac1.dmasize - s->dma_dac1.count; + if (cnt <= 0) + __set_current_state(TASK_INTERRUPTIBLE); + spin_unlock_irqrestore(&s->lock, flags); + if (cnt > count) + cnt = count; + if (cnt <= 0) { + if (s->dma_dac1.enabled) + start_dac1(s); + if (file->f_flags & O_NONBLOCK) { + if (!ret) + ret = -EAGAIN; + break; + } + schedule(); + if (signal_pending(current)) { + if (!ret) + ret = -ERESTARTSYS; + break; + } + continue; + } + if (copy_from_user(s->dma_dac1.rawbuf + swptr, buffer, cnt)) { + if (!ret) + ret = -EFAULT; + break; + } + swptr = (swptr + cnt) % s->dma_dac1.dmasize; + spin_lock_irqsave(&s->lock, flags); + s->dma_dac1.swptr = swptr; + s->dma_dac1.count += cnt; + s->dma_dac1.endcleared = 0; + spin_unlock_irqrestore(&s->lock, flags); + count -= cnt; + buffer += cnt; + ret += cnt; + if (s->dma_dac1.enabled) + start_dac1(s); + } + remove_wait_queue(&s->dma_dac1.wait, &wait); + set_current_state(TASK_RUNNING); + return ret; +} + +/* No kernel lock - we have our own spinlock */ +static unsigned int es1371_poll_dac(struct file *file, struct poll_table_struct *wait) +{ + struct es1371_state *s = (struct es1371_state *)file->private_data; + unsigned long flags; + unsigned int mask = 0; + + VALIDATE_STATE(s); + if (!s->dma_dac1.ready && prog_dmabuf_dac1(s)) + return 0; + poll_wait(file, &s->dma_dac1.wait, wait); + spin_lock_irqsave(&s->lock, flags); + es1371_update_ptr(s); + if (s->dma_dac1.mapped) { + if (s->dma_dac1.count >= (signed)s->dma_dac1.fragsize) + mask |= POLLOUT | POLLWRNORM; + } else { + if ((signed)s->dma_dac1.dmasize >= s->dma_dac1.count + (signed)s->dma_dac1.fragsize) + mask |= POLLOUT | POLLWRNORM; + } + spin_unlock_irqrestore(&s->lock, flags); + return mask; +} + +static int es1371_mmap_dac(struct file *file, struct vm_area_struct *vma) +{ + struct es1371_state *s = (struct es1371_state *)file->private_data; + int ret; + unsigned long size; + + VALIDATE_STATE(s); + if (!(vma->vm_flags & VM_WRITE)) + return -EINVAL; + lock_kernel(); + if ((ret = prog_dmabuf_dac1(s)) != 0) + goto out; + ret = -EINVAL; + if (vma->vm_pgoff != 0) + goto out; + size = vma->vm_end - vma->vm_start; + if (size > (PAGE_SIZE << s->dma_dac1.buforder)) + goto out; + ret = -EAGAIN; + if (remap_pfn_range(vma, vma->vm_start, + virt_to_phys(s->dma_dac1.rawbuf) >> PAGE_SHIFT, + size, vma->vm_page_prot)) + goto out; + s->dma_dac1.mapped = 1; + ret = 0; +out: + unlock_kernel(); + return ret; +} + +static int es1371_ioctl_dac(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +{ + struct es1371_state *s = (struct es1371_state *)file->private_data; + unsigned long flags; + audio_buf_info abinfo; + count_info cinfo; + int count; + int val, ret; + int __user *p = (int __user *)arg; + + VALIDATE_STATE(s); + switch (cmd) { + case OSS_GETVERSION: + return put_user(SOUND_VERSION, p); + + case SNDCTL_DSP_SYNC: + return drain_dac1(s, 0/*file->f_flags & O_NONBLOCK*/); + + case SNDCTL_DSP_SETDUPLEX: + return -EINVAL; + + case SNDCTL_DSP_GETCAPS: + return put_user(DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, p); + + case SNDCTL_DSP_RESET: + stop_dac1(s); + synchronize_irq(s->irq); + s->dma_dac1.swptr = s->dma_dac1.hwptr = s->dma_dac1.count = s->dma_dac1.total_bytes = 0; + return 0; + + case SNDCTL_DSP_SPEED: + if (get_user(val, p)) + return -EFAULT; + if (val >= 0) { + stop_dac1(s); + s->dma_dac1.ready = 0; + set_dac1_rate(s, val); + } + return put_user(s->dac1rate, p); + + case SNDCTL_DSP_STEREO: + if (get_user(val, p)) + return -EFAULT; + stop_dac1(s); + s->dma_dac1.ready = 0; + spin_lock_irqsave(&s->lock, flags); + if (val) + s->sctrl |= SCTRL_P1SMB; + else + s->sctrl &= ~SCTRL_P1SMB; + outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL); + spin_unlock_irqrestore(&s->lock, flags); + return 0; + + case SNDCTL_DSP_CHANNELS: + if (get_user(val, p)) + return -EFAULT; + if (val != 0) { + stop_dac1(s); + s->dma_dac1.ready = 0; + spin_lock_irqsave(&s->lock, flags); + if (val >= 2) + s->sctrl |= SCTRL_P1SMB; + else + s->sctrl &= ~SCTRL_P1SMB; + outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL); + spin_unlock_irqrestore(&s->lock, flags); + } + return put_user((s->sctrl & SCTRL_P1SMB) ? 2 : 1, p); + + case SNDCTL_DSP_GETFMTS: /* Returns a mask */ + return put_user(AFMT_S16_LE|AFMT_U8, p); + + case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/ + if (get_user(val, p)) + return -EFAULT; + if (val != AFMT_QUERY) { + stop_dac1(s); + s->dma_dac1.ready = 0; + spin_lock_irqsave(&s->lock, flags); + if (val == AFMT_S16_LE) + s->sctrl |= SCTRL_P1SEB; + else + s->sctrl &= ~SCTRL_P1SEB; + outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL); + spin_unlock_irqrestore(&s->lock, flags); + } + return put_user((s->sctrl & SCTRL_P1SEB) ? AFMT_S16_LE : AFMT_U8, p); + + case SNDCTL_DSP_POST: + return 0; + + case SNDCTL_DSP_GETTRIGGER: + return put_user((s->ctrl & CTRL_DAC1_EN) ? PCM_ENABLE_OUTPUT : 0, p); + + case SNDCTL_DSP_SETTRIGGER: + if (get_user(val, p)) + return -EFAULT; + if (val & PCM_ENABLE_OUTPUT) { + if (!s->dma_dac1.ready && (ret = prog_dmabuf_dac1(s))) + return ret; + s->dma_dac1.enabled = 1; + start_dac1(s); + } else { + s->dma_dac1.enabled = 0; + stop_dac1(s); + } + return 0; + + case SNDCTL_DSP_GETOSPACE: + if (!s->dma_dac1.ready && (val = prog_dmabuf_dac1(s)) != 0) + return val; + spin_lock_irqsave(&s->lock, flags); + es1371_update_ptr(s); + abinfo.fragsize = s->dma_dac1.fragsize; + count = s->dma_dac1.count; + if (count < 0) + count = 0; + abinfo.bytes = s->dma_dac1.dmasize - count; + abinfo.fragstotal = s->dma_dac1.numfrag; + abinfo.fragments = abinfo.bytes >> s->dma_dac1.fragshift; + spin_unlock_irqrestore(&s->lock, flags); + return copy_to_user((void __user *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0; + + case SNDCTL_DSP_NONBLOCK: + file->f_flags |= O_NONBLOCK; + return 0; + + case SNDCTL_DSP_GETODELAY: + if (!s->dma_dac1.ready && (val = prog_dmabuf_dac1(s)) != 0) + return val; + spin_lock_irqsave(&s->lock, flags); + es1371_update_ptr(s); + count = s->dma_dac1.count; + spin_unlock_irqrestore(&s->lock, flags); + if (count < 0) + count = 0; + return put_user(count, p); + + case SNDCTL_DSP_GETOPTR: + if (!s->dma_dac1.ready && (val = prog_dmabuf_dac1(s)) != 0) + return val; + spin_lock_irqsave(&s->lock, flags); + es1371_update_ptr(s); + cinfo.bytes = s->dma_dac1.total_bytes; + count = s->dma_dac1.count; + if (count < 0) + count = 0; + cinfo.blocks = count >> s->dma_dac1.fragshift; + cinfo.ptr = s->dma_dac1.hwptr; + if (s->dma_dac1.mapped) + s->dma_dac1.count &= s->dma_dac1.fragsize-1; + spin_unlock_irqrestore(&s->lock, flags); + if (copy_to_user((void __user *)arg, &cinfo, sizeof(cinfo))) + return -EFAULT; + return 0; + + case SNDCTL_DSP_GETBLKSIZE: + if ((val = prog_dmabuf_dac1(s))) + return val; + return put_user(s->dma_dac1.fragsize, p); + + case SNDCTL_DSP_SETFRAGMENT: + if (get_user(val, p)) + return -EFAULT; + s->dma_dac1.ossfragshift = val & 0xffff; + s->dma_dac1.ossmaxfrags = (val >> 16) & 0xffff; + if (s->dma_dac1.ossfragshift < 4) + s->dma_dac1.ossfragshift = 4; + if (s->dma_dac1.ossfragshift > 15) + s->dma_dac1.ossfragshift = 15; + if (s->dma_dac1.ossmaxfrags < 4) + s->dma_dac1.ossmaxfrags = 4; + return 0; + + case SNDCTL_DSP_SUBDIVIDE: + if (s->dma_dac1.subdivision) + return -EINVAL; + if (get_user(val, p)) + return -EFAULT; + if (val != 1 && val != 2 && val != 4) + return -EINVAL; + s->dma_dac1.subdivision = val; + return 0; + + case SOUND_PCM_READ_RATE: + return put_user(s->dac1rate, p); + + case SOUND_PCM_READ_CHANNELS: + return put_user((s->sctrl & SCTRL_P1SMB) ? 2 : 1, p); + + case SOUND_PCM_READ_BITS: + return put_user((s->sctrl & SCTRL_P1SEB) ? 16 : 8, p); + + case SOUND_PCM_WRITE_FILTER: + case SNDCTL_DSP_SETSYNCRO: + case SOUND_PCM_READ_FILTER: + return -EINVAL; + + } + return mixdev_ioctl(s->codec, cmd, arg); +} + +static int es1371_open_dac(struct inode *inode, struct file *file) +{ + int minor = iminor(inode); + DECLARE_WAITQUEUE(wait, current); + unsigned long flags; + struct list_head *list; + struct es1371_state *s; + + for (list = devs.next; ; list = list->next) { + if (list == &devs) + return -ENODEV; + s = list_entry(list, struct es1371_state, devs); + if (!((s->dev_dac ^ minor) & ~0xf)) + break; + } + VALIDATE_STATE(s); + /* we allow opening with O_RDWR, most programs do it although they will only write */ +#if 0 + if (file->f_mode & FMODE_READ) + return -EPERM; +#endif + if (!(file->f_mode & FMODE_WRITE)) + return -EINVAL; + file->private_data = s; + /* wait for device to become free */ + mutex_lock(&s->open_mutex); + while (s->open_mode & FMODE_DAC) { + if (file->f_flags & O_NONBLOCK) { + mutex_unlock(&s->open_mutex); + return -EBUSY; + } + add_wait_queue(&s->open_wait, &wait); + __set_current_state(TASK_INTERRUPTIBLE); + mutex_unlock(&s->open_mutex); + schedule(); + remove_wait_queue(&s->open_wait, &wait); + set_current_state(TASK_RUNNING); + if (signal_pending(current)) + return -ERESTARTSYS; + mutex_lock(&s->open_mutex); + } + s->dma_dac1.ossfragshift = s->dma_dac1.ossmaxfrags = s->dma_dac1.subdivision = 0; + s->dma_dac1.enabled = 1; + set_dac1_rate(s, 8000); + spin_lock_irqsave(&s->lock, flags); + s->sctrl &= ~SCTRL_P1FMT; + if ((minor & 0xf) == SND_DEV_DSP16) + s->sctrl |= ES1371_FMT_S16_MONO << SCTRL_SH_P1FMT; + else + s->sctrl |= ES1371_FMT_U8_MONO << SCTRL_SH_P1FMT; + outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL); + spin_unlock_irqrestore(&s->lock, flags); + s->open_mode |= FMODE_DAC; + mutex_unlock(&s->open_mutex); + return nonseekable_open(inode, file); +} + +static int es1371_release_dac(struct inode *inode, struct file *file) +{ + struct es1371_state *s = (struct es1371_state *)file->private_data; + + VALIDATE_STATE(s); + lock_kernel(); + drain_dac1(s, file->f_flags & O_NONBLOCK); + mutex_lock(&s->open_mutex); + stop_dac1(s); + dealloc_dmabuf(s, &s->dma_dac1); + s->open_mode &= ~FMODE_DAC; + mutex_unlock(&s->open_mutex); + wake_up(&s->open_wait); + unlock_kernel(); + return 0; +} + +static /*const*/ struct file_operations es1371_dac_fops = { + .owner = THIS_MODULE, + .llseek = no_llseek, + .write = es1371_write_dac, + .poll = es1371_poll_dac, + .ioctl = es1371_ioctl_dac, + .mmap = es1371_mmap_dac, + .open = es1371_open_dac, + .release = es1371_release_dac, +}; + +/* --------------------------------------------------------------------- */ + +static ssize_t es1371_midi_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) +{ + struct es1371_state *s = (struct es1371_state *)file->private_data; + DECLARE_WAITQUEUE(wait, current); + ssize_t ret; + unsigned long flags; + unsigned ptr; + int cnt; + + VALIDATE_STATE(s); + if (!access_ok(VERIFY_WRITE, buffer, count)) + return -EFAULT; + if (count == 0) + return 0; + ret = 0; + add_wait_queue(&s->midi.iwait, &wait); + while (count > 0) { + spin_lock_irqsave(&s->lock, flags); + ptr = s->midi.ird; + cnt = MIDIINBUF - ptr; + if (s->midi.icnt < cnt) + cnt = s->midi.icnt; + if (cnt <= 0) + __set_current_state(TASK_INTERRUPTIBLE); + spin_unlock_irqrestore(&s->lock, flags); + if (cnt > count) + cnt = count; + if (cnt <= 0) { + if (file->f_flags & O_NONBLOCK) { + if (!ret) + ret = -EAGAIN; + break; + } + schedule(); + if (signal_pending(current)) { + if (!ret) + ret = -ERESTARTSYS; + break; + } + continue; + } + if (copy_to_user(buffer, s->midi.ibuf + ptr, cnt)) { + if (!ret) + ret = -EFAULT; + break; + } + ptr = (ptr + cnt) % MIDIINBUF; + spin_lock_irqsave(&s->lock, flags); + s->midi.ird = ptr; + s->midi.icnt -= cnt; + spin_unlock_irqrestore(&s->lock, flags); + count -= cnt; + buffer += cnt; + ret += cnt; + break; + } + __set_current_state(TASK_RUNNING); + remove_wait_queue(&s->midi.iwait, &wait); + return ret; +} + +static ssize_t es1371_midi_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) +{ + struct es1371_state *s = (struct es1371_state *)file->private_data; + DECLARE_WAITQUEUE(wait, current); + ssize_t ret; + unsigned long flags; + unsigned ptr; + int cnt; + + VALIDATE_STATE(s); + if (!access_ok(VERIFY_READ, buffer, count)) + return -EFAULT; + if (count == 0) + return 0; + ret = 0; + add_wait_queue(&s->midi.owait, &wait); + while (count > 0) { + spin_lock_irqsave(&s->lock, flags); + ptr = s->midi.owr; + cnt = MIDIOUTBUF - ptr; + if (s->midi.ocnt + cnt > MIDIOUTBUF) + cnt = MIDIOUTBUF - s->midi.ocnt; + if (cnt <= 0) { + __set_current_state(TASK_INTERRUPTIBLE); + es1371_handle_midi(s); + } + spin_unlock_irqrestore(&s->lock, flags); + if (cnt > count) + cnt = count; + if (cnt <= 0) { + if (file->f_flags & O_NONBLOCK) { + if (!ret) + ret = -EAGAIN; + break; + } + schedule(); + if (signal_pending(current)) { + if (!ret) + ret = -ERESTARTSYS; + break; + } + continue; + } + if (copy_from_user(s->midi.obuf + ptr, buffer, cnt)) { + if (!ret) + ret = -EFAULT; + break; + } + ptr = (ptr + cnt) % MIDIOUTBUF; + spin_lock_irqsave(&s->lock, flags); + s->midi.owr = ptr; + s->midi.ocnt += cnt; + spin_unlock_irqrestore(&s->lock, flags); + count -= cnt; + buffer += cnt; + ret += cnt; + spin_lock_irqsave(&s->lock, flags); + es1371_handle_midi(s); + spin_unlock_irqrestore(&s->lock, flags); + } + __set_current_state(TASK_RUNNING); + remove_wait_queue(&s->midi.owait, &wait); + return ret; +} + +/* No kernel lock - we have our own spinlock */ +static unsigned int es1371_midi_poll(struct file *file, struct poll_table_struct *wait) +{ + struct es1371_state *s = (struct es1371_state *)file->private_data; + unsigned long flags; + unsigned int mask = 0; + + VALIDATE_STATE(s); + if (file->f_mode & FMODE_WRITE) + poll_wait(file, &s->midi.owait, wait); + if (file->f_mode & FMODE_READ) + poll_wait(file, &s->midi.iwait, wait); + spin_lock_irqsave(&s->lock, flags); + if (file->f_mode & FMODE_READ) { + if (s->midi.icnt > 0) + mask |= POLLIN | POLLRDNORM; + } + if (file->f_mode & FMODE_WRITE) { + if (s->midi.ocnt < MIDIOUTBUF) + mask |= POLLOUT | POLLWRNORM; + } + spin_unlock_irqrestore(&s->lock, flags); + return mask; +} + +static int es1371_midi_open(struct inode *inode, struct file *file) +{ + int minor = iminor(inode); + DECLARE_WAITQUEUE(wait, current); + unsigned long flags; + struct list_head *list; + struct es1371_state *s; + + for (list = devs.next; ; list = list->next) { + if (list == &devs) + return -ENODEV; + s = list_entry(list, struct es1371_state, devs); + if (s->dev_midi == minor) + break; + } + VALIDATE_STATE(s); + file->private_data = s; + /* wait for device to become free */ + mutex_lock(&s->open_mutex); + while (s->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) { + if (file->f_flags & O_NONBLOCK) { + mutex_unlock(&s->open_mutex); + return -EBUSY; + } + add_wait_queue(&s->open_wait, &wait); + __set_current_state(TASK_INTERRUPTIBLE); + mutex_unlock(&s->open_mutex); + schedule(); + remove_wait_queue(&s->open_wait, &wait); + set_current_state(TASK_RUNNING); + if (signal_pending(current)) + return -ERESTARTSYS; + mutex_lock(&s->open_mutex); + } + spin_lock_irqsave(&s->lock, flags); + if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) { + s->midi.ird = s->midi.iwr = s->midi.icnt = 0; + s->midi.ord = s->midi.owr = s->midi.ocnt = 0; + outb(UCTRL_CNTRL_SWR, s->io+ES1371_REG_UART_CONTROL); + outb(0, s->io+ES1371_REG_UART_CONTROL); + outb(0, s->io+ES1371_REG_UART_TEST); + } + if (file->f_mode & FMODE_READ) { + s->midi.ird = s->midi.iwr = s->midi.icnt = 0; + } + if (file->f_mode & FMODE_WRITE) { + s->midi.ord = s->midi.owr = s->midi.ocnt = 0; + } + s->ctrl |= CTRL_UART_EN; + outl(s->ctrl, s->io+ES1371_REG_CONTROL); + es1371_handle_midi(s); + spin_unlock_irqrestore(&s->lock, flags); + s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE); + mutex_unlock(&s->open_mutex); + return nonseekable_open(inode, file); +} + +static int es1371_midi_release(struct inode *inode, struct file *file) +{ + struct es1371_state *s = (struct es1371_state *)file->private_data; + DECLARE_WAITQUEUE(wait, current); + unsigned long flags; + unsigned count, tmo; + + VALIDATE_STATE(s); + lock_kernel(); + if (file->f_mode & FMODE_WRITE) { + add_wait_queue(&s->midi.owait, &wait); + for (;;) { + __set_current_state(TASK_INTERRUPTIBLE); + spin_lock_irqsave(&s->lock, flags); + count = s->midi.ocnt; + spin_unlock_irqrestore(&s->lock, flags); + if (count <= 0) + break; + if (signal_pending(current)) + break; + if (file->f_flags & O_NONBLOCK) + break; + tmo = (count * HZ) / 3100; + if (!schedule_timeout(tmo ? : 1) && tmo) + printk(KERN_DEBUG PFX "midi timed out??\n"); + } + remove_wait_queue(&s->midi.owait, &wait); + set_current_state(TASK_RUNNING); + } + mutex_lock(&s->open_mutex); + s->open_mode &= ~((file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ|FMODE_MIDI_WRITE)); + spin_lock_irqsave(&s->lock, flags); + if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) { + s->ctrl &= ~CTRL_UART_EN; + outl(s->ctrl, s->io+ES1371_REG_CONTROL); + } + spin_unlock_irqrestore(&s->lock, flags); + mutex_unlock(&s->open_mutex); + wake_up(&s->open_wait); + unlock_kernel(); + return 0; +} + +static /*const*/ struct file_operations es1371_midi_fops = { + .owner = THIS_MODULE, + .llseek = no_llseek, + .read = es1371_midi_read, + .write = es1371_midi_write, + .poll = es1371_midi_poll, + .open = es1371_midi_open, + .release = es1371_midi_release, +}; + +/* --------------------------------------------------------------------- */ + +/* + * for debugging purposes, we'll create a proc device that dumps the + * CODEC chipstate + */ + +#ifdef ES1371_DEBUG +static int proc_es1371_dump (char *buf, char **start, off_t fpos, int length, int *eof, void *data) +{ + struct es1371_state *s; + int cnt, len = 0; + + if (list_empty(&devs)) + return 0; + s = list_entry(devs.next, struct es1371_state, devs); + /* print out header */ + len += sprintf(buf + len, "\t\tCreative ES137x Debug Dump-o-matic\n"); + + /* print out CODEC state */ + len += sprintf (buf + len, "AC97 CODEC state\n"); + for (cnt=0; cnt <= 0x7e; cnt = cnt +2) + len+= sprintf (buf + len, "reg:0x%02x val:0x%04x\n", cnt, rdcodec(s->codec, cnt)); + + if (fpos >=len){ + *start = buf; + *eof =1; + return 0; + } + *start = buf + fpos; + if ((len -= fpos) > length) + return length; + *eof =1; + return len; + +} +#endif /* ES1371_DEBUG */ + +/* --------------------------------------------------------------------- */ + +/* maximum number of devices; only used for command line params */ +#define NR_DEVICE 5 + +static int spdif[NR_DEVICE]; +static int nomix[NR_DEVICE]; +static int amplifier[NR_DEVICE]; + +static unsigned int devindex; + +module_param_array(spdif, bool, NULL, 0); +MODULE_PARM_DESC(spdif, "if 1 the output is in S/PDIF digital mode"); +module_param_array(nomix, bool, NULL, 0); +MODULE_PARM_DESC(nomix, "if 1 no analog audio is mixed to the digital output"); +module_param_array(amplifier, bool, NULL, 0); +MODULE_PARM_DESC(amplifier, "Set to 1 if the machine needs the amp control enabling (many laptops)"); + +MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu"); +MODULE_DESCRIPTION("ES1371 AudioPCI97 Driver"); +MODULE_LICENSE("GPL"); + + +/* --------------------------------------------------------------------- */ + +static struct initvol { + int mixch; + int vol; +} initvol[] __devinitdata = { + { SOUND_MIXER_WRITE_LINE, 0x4040 }, + { SOUND_MIXER_WRITE_CD, 0x4040 }, + { MIXER_WRITE(SOUND_MIXER_VIDEO), 0x4040 }, + { SOUND_MIXER_WRITE_LINE1, 0x4040 }, + { SOUND_MIXER_WRITE_PCM, 0x4040 }, + { SOUND_MIXER_WRITE_VOLUME, 0x4040 }, + { MIXER_WRITE(SOUND_MIXER_PHONEOUT), 0x4040 }, + { SOUND_MIXER_WRITE_OGAIN, 0x4040 }, + { MIXER_WRITE(SOUND_MIXER_PHONEIN), 0x4040 }, + { SOUND_MIXER_WRITE_SPEAKER, 0x4040 }, + { SOUND_MIXER_WRITE_MIC, 0x4040 }, + { SOUND_MIXER_WRITE_RECLEV, 0x4040 }, + { SOUND_MIXER_WRITE_IGAIN, 0x4040 } +}; + +static struct +{ + short svid, sdid; +} amplifier_needed[] = +{ + { 0x107B, 0x2150 }, /* Gateway Solo 2150 */ + { 0x13BD, 0x100C }, /* Mebius PC-MJ100V */ + { 0x1102, 0x5938 }, /* Targa Xtender 300 */ + { 0x1102, 0x8938 }, /* IPC notebook */ + { PCI_ANY_ID, PCI_ANY_ID } +}; + +#ifdef SUPPORT_JOYSTICK + +static int __devinit es1371_register_gameport(struct es1371_state *s) +{ + struct gameport *gp; + int gpio; + + for (gpio = 0x218; gpio >= 0x200; gpio -= 0x08) + if (request_region(gpio, JOY_EXTENT, "es1371")) + break; + + if (gpio < 0x200) { + printk(KERN_ERR PFX "no free joystick address found\n"); + return -EBUSY; + } + + s->gameport = gp = gameport_allocate_port(); + if (!gp) { + printk(KERN_ERR PFX "can not allocate memory for gameport\n"); + release_region(gpio, JOY_EXTENT); + return -ENOMEM; + } + + gameport_set_name(gp, "ESS1371 Gameport"); + gameport_set_phys(gp, "isa%04x/gameport0", gpio); + gp->dev.parent = &s->dev->dev; + gp->io = gpio; + + s->ctrl |= CTRL_JYSTK_EN | (((gpio >> 3) & CTRL_JOY_MASK) << CTRL_JOY_SHIFT); + outl(s->ctrl, s->io + ES1371_REG_CONTROL); + + gameport_register_port(gp); + + return 0; +} + +static inline void es1371_unregister_gameport(struct es1371_state *s) +{ + if (s->gameport) { + int gpio = s->gameport->io; + gameport_unregister_port(s->gameport); + release_region(gpio, JOY_EXTENT); + + } +} + +#else +static inline int es1371_register_gameport(struct es1371_state *s) { return -ENOSYS; } +static inline void es1371_unregister_gameport(struct es1371_state *s) { } +#endif /* SUPPORT_JOYSTICK */ + + +static int __devinit es1371_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid) +{ + struct es1371_state *s; + mm_segment_t fs; + int i, val, res = -1; + int idx; + unsigned long tmo; + signed long tmo2; + unsigned int cssr; + + if ((res=pci_enable_device(pcidev))) + return res; + + if (!(pci_resource_flags(pcidev, 0) & IORESOURCE_IO)) + return -ENODEV; + if (pcidev->irq == 0) + return -ENODEV; + i = pci_set_dma_mask(pcidev, DMA_32BIT_MASK); + if (i) { + printk(KERN_WARNING "es1371: architecture does not support 32bit PCI busmaster DMA\n"); + return i; + } + if (!(s = kzalloc(sizeof(struct es1371_state), GFP_KERNEL))) { + printk(KERN_WARNING PFX "out of memory\n"); + return -ENOMEM; + } + + s->codec = ac97_alloc_codec(); + if(s->codec == NULL) + goto err_codec; + + init_waitqueue_head(&s->dma_adc.wait); + init_waitqueue_head(&s->dma_dac1.wait); + init_waitqueue_head(&s->dma_dac2.wait); + init_waitqueue_head(&s->open_wait); + init_waitqueue_head(&s->midi.iwait); + init_waitqueue_head(&s->midi.owait); + mutex_init(&s->open_mutex); + spin_lock_init(&s->lock); + s->magic = ES1371_MAGIC; + s->dev = pcidev; + s->io = pci_resource_start(pcidev, 0); + s->irq = pcidev->irq; + s->vendor = pcidev->vendor; + s->device = pcidev->device; + s->rev = pcidev->revision; + s->codec->private_data = s; + s->codec->id = 0; + s->codec->codec_read = rdcodec; + s->codec->codec_write = wrcodec; + printk(KERN_INFO PFX "found chip, vendor id 0x%04x device id 0x%04x revision 0x%02x\n", + s->vendor, s->device, s->rev); + if (!request_region(s->io, ES1371_EXTENT, "es1371")) { + printk(KERN_ERR PFX "io ports %#lx-%#lx in use\n", s->io, s->io+ES1371_EXTENT-1); + res = -EBUSY; + goto err_region; + } + if ((res=request_irq(s->irq, es1371_interrupt, IRQF_SHARED, "es1371",s))) { + printk(KERN_ERR PFX "irq %u in use\n", s->irq); + goto err_irq; + } + printk(KERN_INFO PFX "found es1371 rev %d at io %#lx irq %u\n", + s->rev, s->io, s->irq); + /* register devices */ + if ((res=(s->dev_audio = register_sound_dsp(&es1371_audio_fops,-1)))<0) + goto err_dev1; + if ((res=(s->codec->dev_mixer = register_sound_mixer(&es1371_mixer_fops, -1))) < 0) + goto err_dev2; + if ((res=(s->dev_dac = register_sound_dsp(&es1371_dac_fops, -1))) < 0) + goto err_dev3; + if ((res=(s->dev_midi = register_sound_midi(&es1371_midi_fops, -1)))<0 ) + goto err_dev4; +#ifdef ES1371_DEBUG + /* initialize the debug proc device */ + s->ps = create_proc_read_entry("es1371",0,NULL,proc_es1371_dump,NULL); +#endif /* ES1371_DEBUG */ + + /* initialize codec registers */ + s->ctrl = 0; + + /* Check amplifier requirements */ + + if (amplifier[devindex]) + s->ctrl |= CTRL_GPIO_OUT0; + else for(idx = 0; amplifier_needed[idx].svid != PCI_ANY_ID; idx++) + { + if(pcidev->subsystem_vendor == amplifier_needed[idx].svid && + pcidev->subsystem_device == amplifier_needed[idx].sdid) + { + s->ctrl |= CTRL_GPIO_OUT0; /* turn internal amplifier on */ + printk(KERN_INFO PFX "Enabling internal amplifier.\n"); + } + } + + s->sctrl = 0; + cssr = 0; + s->spdif_volume = -1; + /* check to see if s/pdif mode is being requested */ + if (spdif[devindex]) { + if (s->rev >= 4) { + printk(KERN_INFO PFX "enabling S/PDIF output\n"); + s->spdif_volume = 0; + cssr |= STAT_EN_SPDIF; + s->ctrl |= CTRL_SPDIFEN_B; + if (nomix[devindex]) /* don't mix analog inputs to s/pdif output */ + s->ctrl |= CTRL_RECEN_B; + } else { + printk(KERN_ERR PFX "revision %d does not support S/PDIF\n", s->rev); + } + } + /* initialize the chips */ + outl(s->ctrl, s->io+ES1371_REG_CONTROL); + outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL); + outl(LEGACY_JFAST, s->io+ES1371_REG_LEGACY); + pci_set_master(pcidev); /* enable bus mastering */ + /* if we are a 5880 turn on the AC97 */ + if (s->vendor == PCI_VENDOR_ID_ENSONIQ && + ((s->device == PCI_DEVICE_ID_ENSONIQ_CT5880 && s->rev >= CT5880REV_CT5880_C) || + (s->device == PCI_DEVICE_ID_ENSONIQ_ES1371 && s->rev == ES1371REV_CT5880_A) || + (s->device == PCI_DEVICE_ID_ENSONIQ_ES1371 && s->rev == ES1371REV_ES1373_8))) { + cssr |= CSTAT_5880_AC97_RST; + outl(cssr, s->io+ES1371_REG_STATUS); + /* need to delay around 20ms(bleech) to give + some CODECs enough time to wakeup */ + tmo = jiffies + (HZ / 50) + 1; + for (;;) { + tmo2 = tmo - jiffies; + if (tmo2 <= 0) + break; + schedule_timeout(tmo2); + } + } + /* AC97 warm reset to start the bitclk */ + outl(s->ctrl | CTRL_SYNCRES, s->io+ES1371_REG_CONTROL); + udelay(2); + outl(s->ctrl, s->io+ES1371_REG_CONTROL); + /* init the sample rate converter */ + src_init(s); + /* codec init */ + if (!ac97_probe_codec(s->codec)) { + res = -ENODEV; + goto err_gp; + } + /* set default values */ + + fs = get_fs(); + set_fs(KERNEL_DS); + val = SOUND_MASK_LINE; + mixdev_ioctl(s->codec, SOUND_MIXER_WRITE_RECSRC, (unsigned long)&val); + for (i = 0; i < ARRAY_SIZE(initvol); i++) { + val = initvol[i].vol; + mixdev_ioctl(s->codec, initvol[i].mixch, (unsigned long)&val); + } + /* mute master and PCM when in S/PDIF mode */ + if (s->spdif_volume != -1) { + val = 0x0000; + s->codec->mixer_ioctl(s->codec, SOUND_MIXER_WRITE_VOLUME, (unsigned long)&val); + s->codec->mixer_ioctl(s->codec, SOUND_MIXER_WRITE_PCM, (unsigned long)&val); + } + set_fs(fs); + /* turn on S/PDIF output driver if requested */ + outl(cssr, s->io+ES1371_REG_STATUS); + + es1371_register_gameport(s); + + /* store it in the driver field */ + pci_set_drvdata(pcidev, s); + /* put it into driver list */ + list_add_tail(&s->devs, &devs); + /* increment devindex */ + if (devindex < NR_DEVICE-1) + devindex++; + return 0; + + err_gp: +#ifdef ES1371_DEBUG + if (s->ps) + remove_proc_entry("es1371", NULL); +#endif + unregister_sound_midi(s->dev_midi); + err_dev4: + unregister_sound_dsp(s->dev_dac); + err_dev3: + unregister_sound_mixer(s->codec->dev_mixer); + err_dev2: + unregister_sound_dsp(s->dev_audio); + err_dev1: + printk(KERN_ERR PFX "cannot register misc device\n"); + free_irq(s->irq, s); + err_irq: + release_region(s->io, ES1371_EXTENT); + err_region: + err_codec: + ac97_release_codec(s->codec); + kfree(s); + return res; +} + +static void __devexit es1371_remove(struct pci_dev *dev) +{ + struct es1371_state *s = pci_get_drvdata(dev); + + if (!s) + return; + list_del(&s->devs); +#ifdef ES1371_DEBUG + if (s->ps) + remove_proc_entry("es1371", NULL); +#endif /* ES1371_DEBUG */ + outl(0, s->io+ES1371_REG_CONTROL); /* switch everything off */ + outl(0, s->io+ES1371_REG_SERIAL_CONTROL); /* clear serial interrupts */ + synchronize_irq(s->irq); + free_irq(s->irq, s); + es1371_unregister_gameport(s); + release_region(s->io, ES1371_EXTENT); + unregister_sound_dsp(s->dev_audio); + unregister_sound_mixer(s->codec->dev_mixer); + unregister_sound_dsp(s->dev_dac); + unregister_sound_midi(s->dev_midi); + ac97_release_codec(s->codec); + kfree(s); + pci_set_drvdata(dev, NULL); +} + +static struct pci_device_id id_table[] = { + { PCI_VENDOR_ID_ENSONIQ, PCI_DEVICE_ID_ENSONIQ_ES1371, PCI_ANY_ID, PCI_ANY_ID, 0, 0 }, + { PCI_VENDOR_ID_ENSONIQ, PCI_DEVICE_ID_ENSONIQ_CT5880, PCI_ANY_ID, PCI_ANY_ID, 0, 0 }, + { PCI_VENDOR_ID_ECTIVA, PCI_DEVICE_ID_ECTIVA_EV1938, PCI_ANY_ID, PCI_ANY_ID, 0, 0 }, + { 0, } +}; + +MODULE_DEVICE_TABLE(pci, id_table); + +static struct pci_driver es1371_driver = { + .name = "es1371", + .id_table = id_table, + .probe = es1371_probe, + .remove = __devexit_p(es1371_remove), +}; + +static int __init init_es1371(void) +{ + printk(KERN_INFO PFX "version v0.32 time " __TIME__ " " __DATE__ "\n"); + return pci_register_driver(&es1371_driver); +} + +static void __exit cleanup_es1371(void) +{ + printk(KERN_INFO PFX "unloading\n"); + pci_unregister_driver(&es1371_driver); +} + +module_init(init_es1371); +module_exit(cleanup_es1371); + +/* --------------------------------------------------------------------- */ + +#ifndef MODULE + +/* format is: es1371=[spdif,[nomix,[amplifier]]] */ + +static int __init es1371_setup(char *str) +{ + static unsigned __initdata nr_dev = 0; + + if (nr_dev >= NR_DEVICE) + return 0; + + (void) + ((get_option(&str, &spdif[nr_dev]) == 2) + && (get_option(&str, &nomix[nr_dev]) == 2) + && (get_option(&str, &lifier[nr_dev]))); + + nr_dev++; + return 1; +} + +__setup("es1371=", es1371_setup); + +#endif /* MODULE */ diff --git a/trunk/sound/ppc/beep.c b/trunk/sound/ppc/beep.c index 566b5ab9d4e8..a1aa89f2faf3 100644 --- a/trunk/sound/ppc/beep.c +++ b/trunk/sound/ppc/beep.c @@ -236,8 +236,8 @@ int __init snd_pmac_attach_beep(struct snd_pmac *chip) input_dev->id.product = 0x0001; input_dev->id.version = 0x0100; - input_dev->evbit[0] = BIT_MASK(EV_SND); - input_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE); + input_dev->evbit[0] = BIT(EV_SND); + input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); input_dev->event = snd_pmac_beep_event; input_dev->dev.parent = &chip->pdev->dev; input_set_drvdata(input_dev, chip); diff --git a/trunk/sound/usb/caiaq/caiaq-input.c b/trunk/sound/usb/caiaq/caiaq-input.c index cd536ca20e56..a1de0c608957 100644 --- a/trunk/sound/usb/caiaq/caiaq-input.c +++ b/trunk/sound/usb/caiaq/caiaq-input.c @@ -200,9 +200,8 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev) switch (dev->chip.usb_id) { case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2): - input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); - input->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) | - BIT_MASK(ABS_Z); + input->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + input->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_Z); input->keycode = keycode_rk2; input->keycodesize = sizeof(char); input->keycodemax = ARRAY_SIZE(keycode_rk2); @@ -229,8 +228,8 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev) snd_usb_caiaq_set_auto_msg(dev, 1, 10, 0); break; case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1): - input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); - input->absbit[0] = BIT_MASK(ABS_X); + input->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); + input->absbit[0] = BIT(ABS_X); input->keycode = keycode_ak1; input->keycodesize = sizeof(char); input->keycodemax = ARRAY_SIZE(keycode_ak1);