rpms/kernel-xen-2.6/F-7 Makefile.config, NONE, 1.1.2.1 config-debug, NONE, 1.1.2.1 config-generic, NONE, 1.1.2.1 config-i586, NONE, 1.1.2.1 config-i686, NONE, 1.1.2.1 config-i686-PAE, NONE, 1.1.2.1 config-ia64, NONE, 1.1.2.1 config-ia64-generic, NONE, 1.1.2.1 config-nodebug, NONE, 1.1.2.1 config-powerpc-generic, NONE, 1.1.2.1 config-powerpc32-generic, NONE, 1.1.2.1 config-powerpc32-smp, NONE, 1.1.2.1 config-powerpc64, NONE, 1.1.2.1 config-powerpc64-kdump, NONE, 1.1.2.1 config-s390x, NONE, 1.1.2.1 config-sparc, NONE, 1.1.2.1 config-sparc-generic, NONE, 1.1.2.1 config-sparc-smp, NONE, 1.1.2.1 config-sparc64, NONE, 1.1.2.1 config-sparc64-generic, NONE, 1.1.2.1 config-sparc64-smp, NONE, 1.1.2.1 config-x86-generic, NONE, 1.1.2.1 config-x86_64-generic, NONE, 1.1.2.1 config-xen-generic, NONE, 1.1.2.1 config-xen-ia64, NONE, 1.1.2.1 config-xen-x86, NONE, 1.1.2.1 config-xen-x86_64, NONE, 1.1.2.1 drm-mm-git.patch, NONE, 1.1.2.1 gen-patches, NONE, 1.1.2.1 git-wireless-dev.patch, NONE, 1.1.2.1 kernel-2.6.21.7-i686-xen.config, NONE, 1.1.2.1 kernel-2.6.21.7-x86_64-xen.config, NONE, 1.1.2.1 kernel.spec, NONE, 1.1.2.1 linux-2.6-2110_scsi-sd-printing.patch, NONE, 1.1.2.1 linux-2.6-2111_sd-start-stop.patch, NONE, 1.1.2.1 linux-2.6-2112_libata-suspend.patch, NONE, 1.1.2.1 linux-2.6-2113_libata-spindown-compat.patch, NONE, 1.1.2.1 linux-2.6-2114_libata-shutdown-warning.patch, NONE, 1.1.2.1 linux-2.6-2115_libata-spindown-status.patch, NONE, 1.1.2.1 linux-2.6-2116_libata-remove-spindown-compat.patch, NONE, 1.1.2.1 linux-2.6-2117_sata-via-suspend.patch, NONE, 1.1.2.1 linux-2.6-2118_scsi-constants.patch, NONE, 1.1.2.1 linux-2.6-acpi-boot-regression.patch, NONE, 1.1.2.1 linux-2.6-acpi-dock-oops.patch, NONE, 1.1.2.1 linux-2.6-acpi-git-ec-init-fixes.patch, NONE, 1.1.2.1 linux-2.6-acpi-keep-tsc-stable-when-lapic-timer-c2-ok-is-set.patch, NONE, 1.1.2.1 linux-2.6-acpi-preserve-ebx-in-acpi_copy_wakeup_routine.patch, NONE, 1.1.2.1 linux-2.6-acpi-unblacklist-dell-gx240.patch, NONE, 1.1.2.1 linux-2.6-add-mmf_dump_elf_headers.patch, NONE, 1.1.2.1 linux-2.6-add-sys-module-name-notes.patch, NONE, 1.1.2.1 linux-2.6-amd-disabled-svm-detect-msr-1.patch, NONE, 1.1.2.1 linux-2.6-amd-disabled-svm-detect.patch, NONE, 1.1.2.1 linux-2.6-at76.patch, NONE, 1.1.2.1 linux-2.6-ata-call-check-dma-with-qc-prepared.patch, NONE, 1.1.2.1 linux-2.6-ata-quirk.patch, NONE, 1.1.2.1 linux-2.6-ata-use-pio-for-non-16-byte-xfers.patch, NONE, 1.1.2.1 linux-2.6-ath5k.patch, NONE, 1.1.2.1 linux-2.6-bcm43xx-pci-neuter.patch, NONE, 1.1.2.1 linux-2.6-cell-spu-device-tree.patch, NONE, 1.1.2.1 linux-2.6-cell-spufs-fixes.patch, NONE, 1.1.2.1 linux-2.6-clockevents-fix-resume-logic.patch, NONE, 1.1.2.1 linux-2.6-crap-sysfs-workaround.patch, NONE, 1.1.2.1 linux-2.6-debug-acpi-os-write-port.patch, NONE, 1.1.2.1 linux-2.6-debug-extra-warnings.patch, NONE, 1.1.2.1 linux-2.6-debug-nmi-timeout.patch, NONE, 1.1.2.1 linux-2.6-default-mmf_dump_elf_headers.patch, NONE, 1.1.2.1 linux-2.6-defaults-pci_no_msi_mmconf.patch, NONE, 1.1.2.1 linux-2.6-drivers-ssb-debug-revision.patch, NONE, 1.1.2.1 linux-2.6-dvb-spinlock.patch, NONE, 1.1.2.1 linux-2.6-e1000-corrupt-eeprom-checksum.patch, NONE, 1.1.2.1 linux-2.6-execshield-xen.patch, NONE, 1.1.2.1 linux-2.6-firewire-be32-fix.patch, NONE, 1.1.2.1 linux-2.6-firewire-lockdep.patch, NONE, 1.1.2.1 linux-2.6-firewire-multi-lun.patch, NONE, 1.1.2.1 linux-2.6-fix-pmops-1.patch, NONE, 1.1.2.1 linux-2.6-fix-pmops-2.patch, NONE, 1.1.2.1 linux-2.6-fix-pmops-3.patch, NONE, 1.1.2.1 linux-2.6-fix-pmops-4.patch, NONE, 1.1.2.1 linux-2.6-gfs-locking-exports.patch, NONE, 1.1.2.1 linux-2.6-highres-timers.patch, NONE, 1.1.2.1 linux-2.6-i386-vdso-install-unstripped-copies-on-disk.patch, NONE, 1.1.2.1 linux-2.6-i82875-edac-pci-setup.patch, NONE, 1.1.2.1 linux-2.6-i965gm-support.patch, NONE, 1.1.2.1 linux-2.6-iwlwifi-fixes.patch, NONE, 1.1.2.1 linux-2.6-kvm-19.patch, NONE, 1.1.2.1 linux-2.6-kvm-reinit-real-mode-tss.patch, NONE, 1.1.2.1 linux-2.6-libata-acpi-enable.patch, NONE, 1.1.2.1 linux-2.6-libata-ali-atapi-dma.patch, NONE, 1.1.2.1 linux-2.6-libata-atiixp-ids.patch, NONE, 1.1.2.1 linux-2.6-libata-hpa.patch, NONE, 1.1.2.1 linux-2.6-libata-ich8m-add-pciid.patch, NONE, 1.1.2.1 linux-2.6-libata-ncq-blacklist-2.6.22-rc7.patch, NONE, 1.1.2.1 linux-2.6-libata-pata-dma-disable-option.patch, NONE, 1.1.2.1 linux-2.6-libata-pata-hpt3x2n-correct-revision-boundary.patch, NONE, 1.1.2.1 linux-2.6-libata-pata-pcmcia-new-ident.patch, NONE, 1.1.2.1 linux-2.6-libata-pata-sis-fix-timing.patch, NONE, 1.1.2.1 linux-2.6-libata-pata_dma-param.patch, NONE, 1.1.2.1 linux-2.6-libata-pata_it821x-partly-fix-dma.patch, NONE, 1.1.2.1 linux-2.6-libata-sata_nv-adma.patch, NONE, 1.1.2.1 linux-2.6-libata-sata_nv-wildcard-removal.patch, NONE, 1.1.2.1 linux-2.6-libata-setxfer.patch, NONE, 1.1.2.1 linux-2.6-libata_ali_max_dma_speed.patch, NONE, 1.1.2.1 linux-2.6-lirc.patch, NONE, 1.1.2.1 linux-2.6-mac80211-extras.patch, NONE, 1.1.2.1 linux-2.6-mac80211-nm-hidden-ssid.patch, NONE, 1.1.2.1 linux-2.6-mm-udf-fixes.patch, NONE, 1.1.2.1 linux-2.6-mpc52xx-fec.patch, NONE, 1.1.2.1 linux-2.6-mpc52xx-sdma.patch, NONE, 1.1.2.1 linux-2.6-net-e1000-no-msi-warning.patch, NONE, 1.1.2.1 linux-2.6-net-silence-noisy-printks.patch, NONE, 1.1.2.1 linux-2.6-netdev-e1000e-01.patch, NONE, 1.1.2.1 linux-2.6-netdev-e1000e-02.patch, NONE, 1.1.2.1 linux-2.6-netdev-e1000e-03.patch, NONE, 1.1.2.1 linux-2.6-netdev-e1000e-04.patch, NONE, 1.1.2.1 linux-2.6-netdev-e1000e-05.patch, NONE, 1.1.2.1 linux-2.6-netdev-e1000e-06.patch, NONE, 1.1.2.1 linux-2.6-netdev-e1000e-07.patch, NONE, 1.1.2.1 linux-2.6-netdev-e1000e-08.patch, NONE, 1.1.2.1 linux-2.6-netdev-e1000e-09.patch, NONE, 1.1.2.1 linux-2.6-netdev-e1000e-10.patch, NONE, 1.1.2.1 linux-2.6-nfs-missing-braces.patch, NONE, 1.1.2.1 linux-2.6-nfs-noreaddirplus.patch, NONE, 1.1.2.1 linux-2.6-ondemand-timer.patch, NONE, 1.1.2.1 linux-2.6-pass-g-to-assembler-under-config_debug_info.patch, NONE, 1.1.2.1 linux-2.6-pmac-zilog.patch, NONE, 1.1.2.1 linux-2.6-pmtrace-time-fix.patch, NONE, 1.1.2.1 linux-2.6-powermac-generic-suspend-1.patch, NONE, 1.1.2.1 linux-2.6-powermac-generic-suspend-2.patch, NONE, 1.1.2.1 linux-2.6-powermac-generic-suspend-3.patch, NONE, 1.1.2.1 linux-2.6-powermac-generic-suspend-4.patch, NONE, 1.1.2.1 linux-2.6-powerpc-generic-suspend-2-remove-adb-sleep-notifier.patch, NONE, 1.1.2.1 linux-2.6-powerpc-generic-suspend-3-remove-dmasound.patch, NONE, 1.1.2.1 linux-2.6-powerpc-generic-suspend-4-kill-pmu-sleep-notifier.patch, NONE, 1.1.2.1 linux-2.6-powerpc-generic-suspend-5-pmu-pm_ops.patch, NONE, 1.1.2.1 linux-2.6-powerpc-lparmap-g.patch, NONE, 1.1.2.1 linux-2.6-powerpc-reserve-initrd-1.patch, NONE, 1.1.2.1 linux-2.6-powerpc-reserve-initrd-2.patch, NONE, 1.1.2.1 linux-2.6-powerpc-slabalign.patch, NONE, 1.1.2.1 linux-2.6-powerpc-spu-vicinity.patch, NONE, 1.1.2.1 linux-2.6-powerpc-vdso-install-unstripped-copies-on-disk.patch, NONE, 1.1.2.1 linux-2.6-ppc-data-exception.patch, NONE, 1.1.2.1 linux-2.6-ppc-pegasos-via-ata-legacy-irq.patch, NONE, 1.1.2.1 linux-2.6-ps3-clear-spu-irq.patch, NONE, 1.1.2.1 linux-2.6-ps3-device-init.patch, NONE, 1.1.2.1 linux-2.6-ps3-ehci-iso.patch, NONE, 1.1.2.1 linux-2.6-ps3-ethernet-autoload.patch, NONE, 1.1.2.1 linux-2.6-ps3-ethernet-modular.patch, NONE, 1.1.2.1 linux-2.6-ps3-gelic-wireless.patch, NONE, 1.1.2.1 linux-2.6-ps3-gelic.patch, NONE, 1.1.2.1 linux-2.6-ps3-kexec.patch, NONE, 1.1.2.1 linux-2.6-ps3-legacy-bootloader-hack.patch, NONE, 1.1.2.1 linux-2.6-ps3-legacy-ioport.patch, NONE, 1.1.2.1 linux-2.6-ps3-memory-probe.patch, NONE, 1.1.2.1 linux-2.6-ps3-smp-boot.patch, NONE, 1.1.2.1 linux-2.6-ps3-sound-autoload.patch, NONE, 1.1.2.1 linux-2.6-ps3-sound.patch, NONE, 1.1.2.1 linux-2.6-ps3-stable-patches.patch, NONE, 1.1.2.1 linux-2.6-ps3-storage-alias.patch, NONE, 1.1.2.1 linux-2.6-ps3-storage.patch, NONE, 1.1.2.1 linux-2.6-ps3-system-bus-rework-2.patch, NONE, 1.1.2.1 linux-2.6-ps3-system-bus-rework.patch, NONE, 1.1.2.1 linux-2.6-ps3-usb-autoload.patch, NONE, 1.1.2.1 linux-2.6-ps3-wrap-spu-runctl.patch, NONE, 1.1.2.1 linux-2.6-ps3av-export-header.patch, NONE, 1.1.2.1 linux-2.6-ps3fb-panic.patch, NONE, 1.1.2.1 linux-2.6-scsi-async-double-add.patch, NONE, 1.1.2.1 linux-2.6-scsi-bounce-isa.patch, NONE, 1.1.2.1 linux-2.6-scsi-mpt-vmware-fix.patch, NONE, 1.1.2.1 linux-2.6-smarter-relatime.patch, NONE, 1.1.2.1 linux-2.6-softirq-printout-irq-trace-events.patch, NONE, 1.1.2.1 linux-2.6-suspend-ordering.patch, NONE, 1.1.2.1 linux-2.6-sysfs-inode-allocator-oops.patch, NONE, 1.1.2.1 linux-2.6-udf-2.6.22-rc2-1-udf_data_corruption.patch, NONE, 1.1.2.1 linux-2.6-udf-2.6.22-rc4-1-udf_block_leak.patch, NONE, 1.1.2.1 linux-2.6-usb-autosuspend-default-disable.patch, NONE, 1.1.2.1 linux-2.6-usb-storage-initialize-huawei-e220-properly.patch, NONE, 1.1.2.1 linux-2.6-usb-suspend-classes.patch, NONE, 1.1.2.1 linux-2.6-utrace-core.patch, NONE, 1.1.2.1 linux-2.6-utrace-ptrace-compat-avr32.patch, NONE, 1.1.2.1 linux-2.6-utrace-ptrace-compat-ia64.patch, NONE, 1.1.2.1 linux-2.6-utrace-ptrace-compat-s390.patch, NONE, 1.1.2.1 linux-2.6-utrace-ptrace-compat-sparc64.patch, NONE, 1.1.2.1 linux-2.6-utrace-ptrace-compat-xen.patch, NONE, 1.1.2.1 linux-2.6-utrace-ptrace-compat.patch, NONE, 1.1.2.1 linux-2.6-utrace-recalc_sigpending_and_wake.patch, NONE, 1.1.2.1 linux-2.6-utrace-regset-avr32.patch, NONE, 1.1.2.1 linux-2.6-utrace-regset-ia64.patch, NONE, 1.1.2.1 linux-2.6-utrace-regset-s390.patch, NONE, 1.1.2.1 linux-2.6-utrace-regset-sparc64.patch, NONE, 1.1.2.1 linux-2.6-utrace-regset.patch, NONE, 1.1.2.1 linux-2.6-utrace-sig_kernel-macros.patch, NONE, 1.1.2.1 linux-2.6-utrace-tracehook-avr32.patch, NONE, 1.1.2.1 linux-2.6-utrace-tracehook-ia64.patch, NONE, 1.1.2.1 linux-2.6-utrace-tracehook-s390.patch, NONE, 1.1.2.1 linux-2.6-utrace-tracehook-sparc64.patch, NONE, 1.1.2.1 linux-2.6-utrace-tracehook-um.patch, NONE, 1.1.2.1 linux-2.6-utrace-tracehook-xen.patch, NONE, 1.1.2.1 linux-2.6-utrace-tracehook.patch, NONE, 1.1.2.1 linux-2.6-vm-invalidate_mapping_pages-cond-resched.patch, NONE, 1.1.2.1 linux-2.6-wakeups-hdaps.patch, NONE, 1.1.2.1 linux-2.6-wakeups.patch, NONE, 1.1.2.1 linux-2.6-wireless.patch, NONE, 1.1.2.1 linux-2.6-x86-64_pmtrace.patch, NONE, 1.1.2.1 linux-2.6-x86-clean-up-oops-bug-reports.patch, NONE, 1.1.2.1 linux-2.6-x86-debug-boot.patch, NONE, 1.1.2.1 linux-2.6-x86-dell-hpet.patch, NONE, 1.1.2.1 linux-2.6-x86-dont-delete-cpu_devs-data.patch, NONE, 1.1.2.1 linux-2.6-x86-fsc-interrupt-controller-quirk.patch, NONE, 1.1.2.1 linux-2.6-x86_64-ia32-vdso-install-unstripped-copies-on-disk.patch, NONE, 1.1.2.1 linux-2.6-x86_64-silence-up-apic-errors-xen.patch, NONE, 1.1.2.1 linux-2.6-x86_64-vdso-install-unstripped-copies-on-disk.patch, NONE, 1.1.2.1 linux-2.6-xen-irq_vector-uninitialize.patch, NONE, 1.1.2.1 linux-2.6-xfs-optimize-away-dmapi-tests.patch, NONE, 1.1.2.1 linux-2.6-xfs-optimize-away-realtime-tests.patch, NONE, 1.1.2.1 linux-2.6-xfs-refactor-xfs_mountfs.patch, NONE, 1.1.2.1 linux-2.6-xfs-setfattr-32bit-compat.patch, NONE, 1.1.2.1 linux-2.6-zd1211rw-mac80211.patch, NONE, 1.1.2.1 linux-2.6.21.7-xen-3.1.0.patch.bz2, NONE, 1.1.2.1 linux-2.6.21.tar.bz2.sign, NONE, 1.1.2.1 linux-2.6.23.tar.bz2.sign, NONE, 1.1.2.1 mirrors, NONE, 1.1.2.1 nouveau-drm.patch, NONE, 1.1.2.1 patch-2.6.21.7.bz2, NONE, 1.1.2.1 patch-2.6.23-git2.bz2.sign, NONE, 1.1.2.1 patch-2.6.23.1.bz2.sign, NONE, 1.1.2.1 upstream, NONE, 1.1.2.1 upstream-key.gpg, NONE, 1.1.2.1 Config.mk, 1.1, 1.1.14.1 Makefile, 1.1, 1.1.14.1 config-rhel-generic, 1.1, 1.1.14.1 linux-2.6-common-uevent.patch, 1.1, 1.1.14.1 linux-2.6-compile-fixes.patch, 1.2, 1.2.14.1 linux-2.6-crash-driver-xen.patch, 1.1, 1.1.14.1 linux-2.6-crash-driver.patch, 1.1, 1.1.14.1 linux-2.6-debug-no-quiet.patch, 1.1, 1.1.14.1 linux-2.6-debug-sizeof-structs.patch, 1.1, 1.1.14.1 linux-2.6-debug-sysfs-crash-debugging-xen.patch, 1.1, 1.1.14.1 linux-2.6-debug-sysfs-crash-debugging.patch, 1.1, 1.1.14.1 linux-2.6-debug-taint-vm.patch, 1.2, 1.2.14.1 linux-2.6-devmem-xen.patch, 1.1, 1.1.14.1 linux-2.6-devmem.patch, 1.2, 1.2.14.1 linux-2.6-disable-netback-checksum.patch, 1.1, 1.1.8.1 linux-2.6-execshield.patch, 1.2, 1.2.14.1 linux-2.6-firewire.patch, 1.1, 1.1.14.1 linux-2.6-gfs2-update.patch, 1.1, 1.1.14.1 linux-2.6-modsign-core.patch, 1.2, 1.2.14.1 linux-2.6-modsign-crypto.patch, 1.2, 1.2.14.1 linux-2.6-modsign-include.patch, 1.2, 1.2.14.1 linux-2.6-modsign-ksign.patch, 1.2, 1.2.14.1 linux-2.6-modsign-mpilib.patch, 1.2, 1.2.14.1 linux-2.6-modsign-script.patch, 1.2, 1.2.14.1 linux-2.6-silence-noise.patch, 1.2, 1.2.14.1 linux-2.6-squashfs.patch, 1.2, 1.2.14.1 linux-2.6-xen-backwards-time.patch, 1.1, 1.1.4.1 linux-2.6-xen-blkfront-wait-add.patch, 1.1, 1.1.4.1 sources, 1.6, 1.6.4.1 xen-compile-fix.patch, 1.2, 1.2.10.1 xen-version-strings.patch, 1.3, 1.3.8.1 xen-vmx-fpu-ts-fix.patch, 1.1, 1.1.4.1 xen-vpic-irqbase-mode.patch, 1.1, 1.1.4.1 config-olpc-generic, 1.1, NONE git-geode.patch, 1.1, NONE kernel-2.6.20-i586.config, 1.1, NONE kernel-2.6.20-i686-PAE-debug.config, 1.1, NONE kernel-2.6.20-i686-PAE.config, 1.1, NONE kernel-2.6.20-i686-debug.config, 1.1, NONE kernel-2.6.20-i686-xen.config, 1.7, NONE kernel-2.6.20-i686.config, 1.1, NONE kernel-2.6.20-ia64-xen.config, 1.2, NONE kernel-2.6.20-ia64.config, 1.1, NONE kernel-2.6.20-ppc-smp.config, 1.1, NONE kernel-2.6.20-ppc.config, 1.1, NONE kernel-2.6.20-ppc64-kdump.config, 1.1, NONE kernel-2.6.20-ppc64.config, 1.1, NONE kernel-2.6.20-ppc64iseries-kdump.config, 1.1, NONE kernel-2.6.20-ppc64iseries.config, 1.1, NONE kernel-2.6.20-s390.config, 1.1, NONE kernel-2.6.20-s390x.config, 1.1, NONE kernel-2.6.20-x86_64-debug.config, 1.1, NONE kernel-2.6.20-x86_64-kdump.config, 1.1, NONE kernel-2.6.20-x86_64-xen.config, 1.6, NONE kernel-2.6.20-x86_64.config, 1.1, NONE kernel-xen.spec, 1.54, NONE linux-2.6-NFSD-badness.patch, 1.1, NONE linux-2.6-NFSD-ctlbits.patch, 1.1, NONE linux-2.6-build-input-not-embedded.patch, 1.1, NONE linux-2.6-cachefiles.patch, 1.1, NONE linux-2.6-cafe-nand.patch, 1.1, NONE linux-2.6-cell-mambo-drivers.patch, 1.2, NONE linux-2.6-cpufreq-unload-smi.patch, 1.1, NONE linux-2.6-csum-missing-line.patch, 1.3, NONE linux-2.6-debug-Wundef.patch, 1.1, NONE linux-2.6-debug-disable-builtins.patch, 1.1, NONE linux-2.6-debug-sleep-in-irq-warning.patch, 1.1, NONE linux-2.6-debug-verbosify-bug.patch, 1.1, NONE linux-2.6-defaults-disable-split-ptlock.patch, 1.2, NONE linux-2.6-defaults-firmware-loader-timeout.patch, 1.1, NONE linux-2.6-defaults-phys-start.patch, 1.1, NONE linux-2.6-drivers-add-qlogic-firmware.patch, 1.1, NONE linux-2.6-fix-x86_64-vgetcpu.patch, 1.1, NONE linux-2.6-forwarding_of_ip_summed.patch, 1.2, NONE linux-2.6-gfs2-locking-exports.patch, 1.1, NONE linux-2.6-gfs2-tux.patch, 1.1, NONE linux-2.6-hvc-console.patch, 1.1, NONE linux-2.6-ia64-kexec-kdump-xen-conflict.patch, 1.1, NONE linux-2.6-ips-softlockup.patch, 1.1, NONE linux-2.6-kill_skbuff_hack.patch, 1.3, NONE linux-2.6-lockdep-fixes.patch, 1.1, NONE linux-2.6-mac-raid-autorun.patch, 1.1, NONE linux-2.6-marvell-88alp01.patch, 1.1, NONE linux-2.6-marvell-update.patch, 1.1, NONE linux-2.6-mm-prevent-oom-fixes.patch, 1.1, NONE linux-2.6-mpc52xx-ata.patch, 1.1, NONE linux-2.6-mtd-update.patch, 1.1, NONE linux-2.6-net-forcedeth-suspend.patch, 1.1, NONE linux-2.6-obsolete-oss-warning.patch, 1.1, NONE linux-2.6-ohci-multi-init.patch, 1.1, NONE linux-2.6-ohci-platform-bus.patch, 1.1, NONE linux-2.6-olpc-battery.patch, 1.1, NONE linux-2.6-olpc-dcon.patch, 1.1, NONE linux-2.6-power6-no-ci-large-page.patch, 1.1, NONE linux-2.6-ppc-iseries-input-layer.patch, 1.1, NONE linux-2.6-ppc-rtas-check.patch, 1.1, NONE linux-2.6-sata-ahci-suspend.patch, 1.1, NONE linux-2.6-sata-pata-piix3.patch, 1.1, NONE linux-2.6-sata-promise-pata-ports.patch, 1.2, NONE linux-2.6-sata-sg_init_one-oops.patch, 1.1, NONE linux-2.6-serial-tickle-nmi.patch, 1.1, NONE linux-2.6-sleepon.patch, 1.1, NONE linux-2.6-softcursor-persistent-alloc.patch, 1.1, NONE linux-2.6-sysprof-1.0.3.patch, 1.1, NONE linux-2.6-systemsim-work.patch, 1.1, NONE linux-2.6-treat_partial_as_unnecessary.patch, 1.2, NONE linux-2.6-tux.patch, 1.1, NONE linux-2.6-usb-endian-ehci.patch, 1.2, NONE linux-2.6-usb-endian-quirks.patch, 1.1, NONE linux-2.6-usb-endian-toshiba.patch, 1.1, NONE linux-2.6-usb-storage-reboot.patch, 1.1, NONE linux-2.6-use_csum_start_offset_instead.patch, 1.2, NONE linux-2.6-utrace.patch, 1.2, NONE linux-2.6-vm-debug.patch, 1.1, NONE linux-2.6-warn-c-p-a.patch, 1.1, NONE linux-2.6-x86-apic-auto.patch, 1.1, NONE linux-2.6-xen-add-packet_auxdata-cmsg-1.patch, 1.2, NONE linux-2.6-xen-add-packet_auxdata-cmsg-2.patch, 1.2, NONE linux-2.6-xen-af_packet-no-skb_checksum_setup.patch, 1.2, NONE linux-2.6-xen-execshield.patch, 1.4, NONE linux-2.6-xen-iscsi-x86_64-no_iommu_init.patch, 1.2, NONE linux-2.6-xen-tux.patch, 1.1, NONE linux-2.6-xen-utrace.patch, 1.3, NONE linux-2.6-xen-x86_64-silence-up-apic-errors.patch, 1.1, NONE linux-2.6-xfs-umount-fix.patch, 1.1, NONE linux-2.6-xfs_attr2.patch, 1.1, NONE linux-2.6.20.14-xen-3.1.0.patch, 1.1, NONE linux-2.6.20.tar.bz2.sign, 1.1, NONE

Eduardo Habkost (ehabkost) fedora-extras-commits at redhat.com
Wed Oct 17 19:27:42 UTC 2007


Author: ehabkost

Update of /cvs/pkgs/rpms/kernel-xen-2.6/F-7
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv2290

Modified Files:
      Tag: private-ehabkost-debuginfo-branch
	Config.mk Makefile config-rhel-generic 
	linux-2.6-common-uevent.patch linux-2.6-compile-fixes.patch 
	linux-2.6-crash-driver-xen.patch linux-2.6-crash-driver.patch 
	linux-2.6-debug-no-quiet.patch 
	linux-2.6-debug-sizeof-structs.patch 
	linux-2.6-debug-sysfs-crash-debugging-xen.patch 
	linux-2.6-debug-sysfs-crash-debugging.patch 
	linux-2.6-debug-taint-vm.patch linux-2.6-devmem-xen.patch 
	linux-2.6-devmem.patch 
	linux-2.6-disable-netback-checksum.patch 
	linux-2.6-execshield.patch linux-2.6-firewire.patch 
	linux-2.6-gfs2-update.patch linux-2.6-modsign-core.patch 
	linux-2.6-modsign-crypto.patch linux-2.6-modsign-include.patch 
	linux-2.6-modsign-ksign.patch linux-2.6-modsign-mpilib.patch 
	linux-2.6-modsign-script.patch linux-2.6-silence-noise.patch 
	linux-2.6-squashfs.patch linux-2.6-xen-backwards-time.patch 
	linux-2.6-xen-blkfront-wait-add.patch sources 
	xen-compile-fix.patch xen-version-strings.patch 
	xen-vmx-fpu-ts-fix.patch xen-vpic-irqbase-mode.patch 
Added Files:
      Tag: private-ehabkost-debuginfo-branch
	Makefile.config config-debug config-generic config-i586 
	config-i686 config-i686-PAE config-ia64 config-ia64-generic 
	config-nodebug config-powerpc-generic config-powerpc32-generic 
	config-powerpc32-smp config-powerpc64 config-powerpc64-kdump 
	config-s390x config-sparc config-sparc-generic 
	config-sparc-smp config-sparc64 config-sparc64-generic 
	config-sparc64-smp config-x86-generic config-x86_64-generic 
	config-xen-generic config-xen-ia64 config-xen-x86 
	config-xen-x86_64 drm-mm-git.patch gen-patches 
	git-wireless-dev.patch kernel-2.6.21.7-i686-xen.config 
	kernel-2.6.21.7-x86_64-xen.config kernel.spec 
	linux-2.6-2110_scsi-sd-printing.patch 
	linux-2.6-2111_sd-start-stop.patch 
	linux-2.6-2112_libata-suspend.patch 
	linux-2.6-2113_libata-spindown-compat.patch 
	linux-2.6-2114_libata-shutdown-warning.patch 
	linux-2.6-2115_libata-spindown-status.patch 
	linux-2.6-2116_libata-remove-spindown-compat.patch 
	linux-2.6-2117_sata-via-suspend.patch 
	linux-2.6-2118_scsi-constants.patch 
	linux-2.6-acpi-boot-regression.patch 
	linux-2.6-acpi-dock-oops.patch 
	linux-2.6-acpi-git-ec-init-fixes.patch 
	linux-2.6-acpi-keep-tsc-stable-when-lapic-timer-c2-ok-is-set.patch 
	linux-2.6-acpi-preserve-ebx-in-acpi_copy_wakeup_routine.patch 
	linux-2.6-acpi-unblacklist-dell-gx240.patch 
	linux-2.6-add-mmf_dump_elf_headers.patch 
	linux-2.6-add-sys-module-name-notes.patch 
	linux-2.6-amd-disabled-svm-detect-msr-1.patch 
	linux-2.6-amd-disabled-svm-detect.patch linux-2.6-at76.patch 
	linux-2.6-ata-call-check-dma-with-qc-prepared.patch 
	linux-2.6-ata-quirk.patch 
	linux-2.6-ata-use-pio-for-non-16-byte-xfers.patch 
	linux-2.6-ath5k.patch linux-2.6-bcm43xx-pci-neuter.patch 
	linux-2.6-cell-spu-device-tree.patch 
	linux-2.6-cell-spufs-fixes.patch 
	linux-2.6-clockevents-fix-resume-logic.patch 
	linux-2.6-crap-sysfs-workaround.patch 
	linux-2.6-debug-acpi-os-write-port.patch 
	linux-2.6-debug-extra-warnings.patch 
	linux-2.6-debug-nmi-timeout.patch 
	linux-2.6-default-mmf_dump_elf_headers.patch 
	linux-2.6-defaults-pci_no_msi_mmconf.patch 
	linux-2.6-drivers-ssb-debug-revision.patch 
	linux-2.6-dvb-spinlock.patch 
	linux-2.6-e1000-corrupt-eeprom-checksum.patch 
	linux-2.6-execshield-xen.patch 
	linux-2.6-firewire-be32-fix.patch 
	linux-2.6-firewire-lockdep.patch 
	linux-2.6-firewire-multi-lun.patch linux-2.6-fix-pmops-1.patch 
	linux-2.6-fix-pmops-2.patch linux-2.6-fix-pmops-3.patch 
	linux-2.6-fix-pmops-4.patch 
	linux-2.6-gfs-locking-exports.patch 
	linux-2.6-highres-timers.patch 
	linux-2.6-i386-vdso-install-unstripped-copies-on-disk.patch 
	linux-2.6-i82875-edac-pci-setup.patch 
	linux-2.6-i965gm-support.patch linux-2.6-iwlwifi-fixes.patch 
	linux-2.6-kvm-19.patch 
	linux-2.6-kvm-reinit-real-mode-tss.patch 
	linux-2.6-libata-acpi-enable.patch 
	linux-2.6-libata-ali-atapi-dma.patch 
	linux-2.6-libata-atiixp-ids.patch linux-2.6-libata-hpa.patch 
	linux-2.6-libata-ich8m-add-pciid.patch 
	linux-2.6-libata-ncq-blacklist-2.6.22-rc7.patch 
	linux-2.6-libata-pata-dma-disable-option.patch 
	linux-2.6-libata-pata-hpt3x2n-correct-revision-boundary.patch 
	linux-2.6-libata-pata-pcmcia-new-ident.patch 
	linux-2.6-libata-pata-sis-fix-timing.patch 
	linux-2.6-libata-pata_dma-param.patch 
	linux-2.6-libata-pata_it821x-partly-fix-dma.patch 
	linux-2.6-libata-sata_nv-adma.patch 
	linux-2.6-libata-sata_nv-wildcard-removal.patch 
	linux-2.6-libata-setxfer.patch 
	linux-2.6-libata_ali_max_dma_speed.patch linux-2.6-lirc.patch 
	linux-2.6-mac80211-extras.patch 
	linux-2.6-mac80211-nm-hidden-ssid.patch 
	linux-2.6-mm-udf-fixes.patch linux-2.6-mpc52xx-fec.patch 
	linux-2.6-mpc52xx-sdma.patch 
	linux-2.6-net-e1000-no-msi-warning.patch 
	linux-2.6-net-silence-noisy-printks.patch 
	linux-2.6-netdev-e1000e-01.patch 
	linux-2.6-netdev-e1000e-02.patch 
	linux-2.6-netdev-e1000e-03.patch 
	linux-2.6-netdev-e1000e-04.patch 
	linux-2.6-netdev-e1000e-05.patch 
	linux-2.6-netdev-e1000e-06.patch 
	linux-2.6-netdev-e1000e-07.patch 
	linux-2.6-netdev-e1000e-08.patch 
	linux-2.6-netdev-e1000e-09.patch 
	linux-2.6-netdev-e1000e-10.patch 
	linux-2.6-nfs-missing-braces.patch 
	linux-2.6-nfs-noreaddirplus.patch 
	linux-2.6-ondemand-timer.patch 
	linux-2.6-pass-g-to-assembler-under-config_debug_info.patch 
	linux-2.6-pmac-zilog.patch linux-2.6-pmtrace-time-fix.patch 
	linux-2.6-powermac-generic-suspend-1.patch 
	linux-2.6-powermac-generic-suspend-2.patch 
	linux-2.6-powermac-generic-suspend-3.patch 
	linux-2.6-powermac-generic-suspend-4.patch 
	linux-2.6-powerpc-generic-suspend-2-remove-adb-sleep-notifier.patch 
	linux-2.6-powerpc-generic-suspend-3-remove-dmasound.patch 
	linux-2.6-powerpc-generic-suspend-4-kill-pmu-sleep-notifier.patch 
	linux-2.6-powerpc-generic-suspend-5-pmu-pm_ops.patch 
	linux-2.6-powerpc-lparmap-g.patch 
	linux-2.6-powerpc-reserve-initrd-1.patch 
	linux-2.6-powerpc-reserve-initrd-2.patch 
	linux-2.6-powerpc-slabalign.patch 
	linux-2.6-powerpc-spu-vicinity.patch 
	linux-2.6-powerpc-vdso-install-unstripped-copies-on-disk.patch 
	linux-2.6-ppc-data-exception.patch 
	linux-2.6-ppc-pegasos-via-ata-legacy-irq.patch 
	linux-2.6-ps3-clear-spu-irq.patch 
	linux-2.6-ps3-device-init.patch linux-2.6-ps3-ehci-iso.patch 
	linux-2.6-ps3-ethernet-autoload.patch 
	linux-2.6-ps3-ethernet-modular.patch 
	linux-2.6-ps3-gelic-wireless.patch linux-2.6-ps3-gelic.patch 
	linux-2.6-ps3-kexec.patch 
	linux-2.6-ps3-legacy-bootloader-hack.patch 
	linux-2.6-ps3-legacy-ioport.patch 
	linux-2.6-ps3-memory-probe.patch linux-2.6-ps3-smp-boot.patch 
	linux-2.6-ps3-sound-autoload.patch linux-2.6-ps3-sound.patch 
	linux-2.6-ps3-stable-patches.patch 
	linux-2.6-ps3-storage-alias.patch linux-2.6-ps3-storage.patch 
	linux-2.6-ps3-system-bus-rework-2.patch 
	linux-2.6-ps3-system-bus-rework.patch 
	linux-2.6-ps3-usb-autoload.patch 
	linux-2.6-ps3-wrap-spu-runctl.patch 
	linux-2.6-ps3av-export-header.patch 
	linux-2.6-ps3fb-panic.patch 
	linux-2.6-scsi-async-double-add.patch 
	linux-2.6-scsi-bounce-isa.patch 
	linux-2.6-scsi-mpt-vmware-fix.patch 
	linux-2.6-smarter-relatime.patch 
	linux-2.6-softirq-printout-irq-trace-events.patch 
	linux-2.6-suspend-ordering.patch 
	linux-2.6-sysfs-inode-allocator-oops.patch 
	linux-2.6-udf-2.6.22-rc2-1-udf_data_corruption.patch 
	linux-2.6-udf-2.6.22-rc4-1-udf_block_leak.patch 
	linux-2.6-usb-autosuspend-default-disable.patch 
	linux-2.6-usb-storage-initialize-huawei-e220-properly.patch 
	linux-2.6-usb-suspend-classes.patch 
	linux-2.6-utrace-core.patch 
	linux-2.6-utrace-ptrace-compat-avr32.patch 
	linux-2.6-utrace-ptrace-compat-ia64.patch 
	linux-2.6-utrace-ptrace-compat-s390.patch 
	linux-2.6-utrace-ptrace-compat-sparc64.patch 
	linux-2.6-utrace-ptrace-compat-xen.patch 
	linux-2.6-utrace-ptrace-compat.patch 
	linux-2.6-utrace-recalc_sigpending_and_wake.patch 
	linux-2.6-utrace-regset-avr32.patch 
	linux-2.6-utrace-regset-ia64.patch 
	linux-2.6-utrace-regset-s390.patch 
	linux-2.6-utrace-regset-sparc64.patch 
	linux-2.6-utrace-regset.patch 
	linux-2.6-utrace-sig_kernel-macros.patch 
	linux-2.6-utrace-tracehook-avr32.patch 
	linux-2.6-utrace-tracehook-ia64.patch 
	linux-2.6-utrace-tracehook-s390.patch 
	linux-2.6-utrace-tracehook-sparc64.patch 
	linux-2.6-utrace-tracehook-um.patch 
	linux-2.6-utrace-tracehook-xen.patch 
	linux-2.6-utrace-tracehook.patch 
	linux-2.6-vm-invalidate_mapping_pages-cond-resched.patch 
	linux-2.6-wakeups-hdaps.patch linux-2.6-wakeups.patch 
	linux-2.6-wireless.patch linux-2.6-x86-64_pmtrace.patch 
	linux-2.6-x86-clean-up-oops-bug-reports.patch 
	linux-2.6-x86-debug-boot.patch linux-2.6-x86-dell-hpet.patch 
	linux-2.6-x86-dont-delete-cpu_devs-data.patch 
	linux-2.6-x86-fsc-interrupt-controller-quirk.patch 
	linux-2.6-x86_64-ia32-vdso-install-unstripped-copies-on-disk.patch 
	linux-2.6-x86_64-silence-up-apic-errors-xen.patch 
	linux-2.6-x86_64-vdso-install-unstripped-copies-on-disk.patch 
	linux-2.6-xen-irq_vector-uninitialize.patch 
	linux-2.6-xfs-optimize-away-dmapi-tests.patch 
	linux-2.6-xfs-optimize-away-realtime-tests.patch 
	linux-2.6-xfs-refactor-xfs_mountfs.patch 
	linux-2.6-xfs-setfattr-32bit-compat.patch 
	linux-2.6-zd1211rw-mac80211.patch 
	linux-2.6.21.7-xen-3.1.0.patch.bz2 linux-2.6.21.tar.bz2.sign 
	linux-2.6.23.tar.bz2.sign mirrors nouveau-drm.patch 
	patch-2.6.21.7.bz2 patch-2.6.23-git2.bz2.sign 
	patch-2.6.23.1.bz2.sign upstream upstream-key.gpg 
Removed Files:
      Tag: private-ehabkost-debuginfo-branch
	config-olpc-generic git-geode.patch kernel-2.6.20-i586.config 
	kernel-2.6.20-i686-PAE-debug.config 
	kernel-2.6.20-i686-PAE.config kernel-2.6.20-i686-debug.config 
	kernel-2.6.20-i686-xen.config kernel-2.6.20-i686.config 
	kernel-2.6.20-ia64-xen.config kernel-2.6.20-ia64.config 
	kernel-2.6.20-ppc-smp.config kernel-2.6.20-ppc.config 
	kernel-2.6.20-ppc64-kdump.config kernel-2.6.20-ppc64.config 
	kernel-2.6.20-ppc64iseries-kdump.config 
	kernel-2.6.20-ppc64iseries.config kernel-2.6.20-s390.config 
	kernel-2.6.20-s390x.config kernel-2.6.20-x86_64-debug.config 
	kernel-2.6.20-x86_64-kdump.config 
	kernel-2.6.20-x86_64-xen.config kernel-2.6.20-x86_64.config 
	kernel-xen.spec linux-2.6-NFSD-badness.patch 
	linux-2.6-NFSD-ctlbits.patch 
	linux-2.6-build-input-not-embedded.patch 
	linux-2.6-cachefiles.patch linux-2.6-cafe-nand.patch 
	linux-2.6-cell-mambo-drivers.patch 
	linux-2.6-cpufreq-unload-smi.patch 
	linux-2.6-csum-missing-line.patch linux-2.6-debug-Wundef.patch 
	linux-2.6-debug-disable-builtins.patch 
	linux-2.6-debug-sleep-in-irq-warning.patch 
	linux-2.6-debug-verbosify-bug.patch 
	linux-2.6-defaults-disable-split-ptlock.patch 
	linux-2.6-defaults-firmware-loader-timeout.patch 
	linux-2.6-defaults-phys-start.patch 
	linux-2.6-drivers-add-qlogic-firmware.patch 
	linux-2.6-fix-x86_64-vgetcpu.patch 
	linux-2.6-forwarding_of_ip_summed.patch 
	linux-2.6-gfs2-locking-exports.patch linux-2.6-gfs2-tux.patch 
	linux-2.6-hvc-console.patch 
	linux-2.6-ia64-kexec-kdump-xen-conflict.patch 
	linux-2.6-ips-softlockup.patch 
	linux-2.6-kill_skbuff_hack.patch linux-2.6-lockdep-fixes.patch 
	linux-2.6-mac-raid-autorun.patch 
	linux-2.6-marvell-88alp01.patch linux-2.6-marvell-update.patch 
	linux-2.6-mm-prevent-oom-fixes.patch 
	linux-2.6-mpc52xx-ata.patch linux-2.6-mtd-update.patch 
	linux-2.6-net-forcedeth-suspend.patch 
	linux-2.6-obsolete-oss-warning.patch 
	linux-2.6-ohci-multi-init.patch 
	linux-2.6-ohci-platform-bus.patch linux-2.6-olpc-battery.patch 
	linux-2.6-olpc-dcon.patch 
	linux-2.6-power6-no-ci-large-page.patch 
	linux-2.6-ppc-iseries-input-layer.patch 
	linux-2.6-ppc-rtas-check.patch 
	linux-2.6-sata-ahci-suspend.patch 
	linux-2.6-sata-pata-piix3.patch 
	linux-2.6-sata-promise-pata-ports.patch 
	linux-2.6-sata-sg_init_one-oops.patch 
	linux-2.6-serial-tickle-nmi.patch linux-2.6-sleepon.patch 
	linux-2.6-softcursor-persistent-alloc.patch 
	linux-2.6-sysprof-1.0.3.patch linux-2.6-systemsim-work.patch 
	linux-2.6-treat_partial_as_unnecessary.patch 
	linux-2.6-tux.patch linux-2.6-usb-endian-ehci.patch 
	linux-2.6-usb-endian-quirks.patch 
	linux-2.6-usb-endian-toshiba.patch 
	linux-2.6-usb-storage-reboot.patch 
	linux-2.6-use_csum_start_offset_instead.patch 
	linux-2.6-utrace.patch linux-2.6-vm-debug.patch 
	linux-2.6-warn-c-p-a.patch linux-2.6-x86-apic-auto.patch 
	linux-2.6-xen-add-packet_auxdata-cmsg-1.patch 
	linux-2.6-xen-add-packet_auxdata-cmsg-2.patch 
	linux-2.6-xen-af_packet-no-skb_checksum_setup.patch 
	linux-2.6-xen-execshield.patch 
	linux-2.6-xen-iscsi-x86_64-no_iommu_init.patch 
	linux-2.6-xen-tux.patch linux-2.6-xen-utrace.patch 
	linux-2.6-xen-x86_64-silence-up-apic-errors.patch 
	linux-2.6-xfs-umount-fix.patch linux-2.6-xfs_attr2.patch 
	linux-2.6.20.14-xen-3.1.0.patch linux-2.6.20.tar.bz2.sign 
Log Message:
Major package changes

- Getting spec from non-xen kernel/devel
- Using source+patches from kernel-xen-2.6/devel (2.6.21)
- -debuginfo packages should be enabled, with this package




***** Error reading new file: [Errno 2] No such file or directory: 'Makefile.config'

--- NEW FILE config-debug ---
CONFIG_SND_VERBOSE_PRINTK=y
CONFIG_SND_DEBUG=y
CONFIG_SND_DEBUG_DETECT=y
CONFIG_SND_PCM_XRUN_DEBUG=y

CONFIG_DEBUG_IGNORE_QUIET=y
CONFIG_DEBUG_MUTEXES=y
CONFIG_DEBUG_RT_MUTEXES=y
CONFIG_DEBUG_LOCK_ALLOC=y
CONFIG_PROVE_LOCKING=y
CONFIG_DEBUG_VM=y
CONFIG_DEBUG_SPINLOCK=y

CONFIG_FAULT_INJECTION=y
CONFIG_FAILSLAB=y
CONFIG_FAIL_PAGE_ALLOC=y
CONFIG_FAIL_MAKE_REQUEST=y
CONFIG_FAULT_INJECTION_DEBUG_FS=y
CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y

CONFIG_SLUB_DEBUG_ON=y

CONFIG_LOCK_STAT=y

CONFIG_DEBUG_STACK_USAGE=y

CONFIG_ACPI_DEBUG=y
# CONFIG_ACPI_DEBUG_FUNC_TRACE is not set

--- NEW FILE config-generic ---
#
# Automatically generated make config: don't edit
#
CONFIG_MMU=y
CONFIG_SMP=y
CONFIG_HOTPLUG_CPU=y
CONFIG_LOCALVERSION=""
# CONFIG_CRASH_DUMP is not set
#
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# General setup
#
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
CONFIG_TASKSTATS=y
CONFIG_TASK_DELAY_ACCT=y
CONFIG_TASK_XACCT=y
CONFIG_TASK_IO_ACCOUNTING=y
CONFIG_SYSCTL=y
CONFIG_LOG_BUF_SHIFT=17
# CONFIG_IKCONFIG is not set
# CONFIG_EMBEDDED is not set
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
CONFIG_KALLSYMS_EXTRA_PASS=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_IOSCHED_NOOP=y
CONFIG_IOSCHED_AS=y
CONFIG_IOSCHED_DEADLINE=y
CONFIG_IOSCHED_CFQ=y
CONFIG_DEFAULT_CFQ=y
CONFIG_IPC_NS=y
CONFIG_USER_NS=y
CONFIG_POSIX_MQUEUE=y
# CONFIG_PREEMPT_NONE is not set
CONFIG_PREEMPT_VOLUNTARY=y
# CONFIG_PREEMPT is not set
CONFIG_PREEMPT_BKL=y

CONFIG_SLUB=y

CONFIG_MISC_DEVICES=y

#
# Loadable module support
#
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_FORCE_UNLOAD is not set
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_KMOD=y
CONFIG_MODULE_SIG=y
# CONFIG_MODULE_SIG_FORCE is not set
CONFIG_MODULE_VERIFY_ELF=y

#
# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
#
CONFIG_PCI=y
# CONFIG_PCI_DEBUG is not set
CONFIG_HT_IRQ=y
CONFIG_PCI_MSI=y
CONFIG_PCIEPORTBUS=y
CONFIG_PCIEAER=y
CONFIG_HOTPLUG_PCI_PCIE=m
CONFIG_HOTPLUG_PCI_FAKE=m
# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set
CONFIG_ISA=y
# CONFIG_EISA is not set
# CONFIG_MCA is not set
# CONFIG_SCx200 is not set
CONFIG_HOTPLUG=y
# CONFIG_DEBUG_KOBJECT is not set

#
# PCMCIA/CardBus support
#
CONFIG_PCMCIA=y
CONFIG_PCMCIA_LOAD_CIS=y
# CONFIG_PCMCIA_DEBUG is not set
CONFIG_YENTA=y
CONFIG_CARDBUS=y
CONFIG_I82092=m
CONFIG_PD6729=m
CONFIG_PCMCIA_IOCTL=y

CONFIG_PCCARD=y
CONFIG_MMC=m
CONFIG_MMC_BLOCK_BOUNCE=y
# CONFIG_MMC_DEBUG is not set
# CONFIG_MMC_UNSAFE_RESUME is not set
CONFIG_MMC_BLOCK=m
CONFIG_MMC_WBSD=m
CONFIG_MMC_SDHCI=m
CONFIG_MMC_TIFM_SD=m

CONFIG_INFINIBAND=m
CONFIG_INFINIBAND_MTHCA=m
# CONFIG_INFINIBAND_MTHCA_DEBUG is not set
CONFIG_INFINIBAND_IPOIB=m
CONFIG_INFINIBAND_IPOIB_DEBUG=y
CONFIG_INFINIBAND_IPOIB_DEBUG_DATA=y
# CONFIG_INFINIBAND_IPOIB_CM is not set
CONFIG_INFINIBAND_SRP=m
CONFIG_INFINIBAND_USER_MAD=m
CONFIG_INFINIBAND_USER_ACCESS=m
CONFIG_INFINIBAND_IPATH=m
CONFIG_INFINIBAND_ISER=m
CONFIG_INFINIBAND_AMSO1100=m
# CONFIG_INFINIBAND_AMSO1100_DEBUG is not set
CONFIG_INFINIBAND_CXGB3=m
# CONFIG_INFINIBAND_CXGB3_DEBUG is not set
CONFIG_MLX4_INFINIBAND=m

#
# Executable file formats
#
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_AOUT is not set
CONFIG_BINFMT_MISC=y

#
# Device Drivers
#

#
# Generic Driver Options
#
CONFIG_FW_LOADER=y

# CONFIG_SPI is not set

#
# Memory Technology Devices (MTD)
#
CONFIG_MTD=m
# CONFIG_MTD_DEBUG is not set
CONFIG_MTD_PARTITIONS=y
CONFIG_MTD_CONCAT=m
CONFIG_MTD_CMDLINE_PARTS=y
#
# User Modules And Translation Layers
#
CONFIG_MTD_CHAR=m
CONFIG_MTD_BLOCK=m
CONFIG_MTD_BLOCK_RO=m
CONFIG_MTD_BLOCK2MTD=m
CONFIG_FTL=m
CONFIG_NFTL=m
CONFIG_NFTL_RW=y
CONFIG_INFTL=m
CONFIG_RFD_FTL=m
CONFIG_SSFDC=m

CONFIG_MTD_UBI=m
CONFIG_MTD_UBI_WL_THRESHOLD=4096
CONFIG_MTD_UBI_BEB_RESERVE=1
# CONFIG_MTD_UBI_GLUEBI is not set
# CONFIG_MTD_UBI_DEBUG is not set

#
# RAM/ROM/Flash chip drivers
#
CONFIG_MTD_CFI=m
CONFIG_MTD_JEDECPROBE=m
CONFIG_MTD_GEN_PROBE=m
# CONFIG_MTD_CFI_ADV_OPTIONS is not set
CONFIG_MTD_CFI_INTELEXT=m
CONFIG_MTD_CFI_AMDSTD=m
CONFIG_MTD_CFI_STAA=m
CONFIG_MTD_RAM=m
CONFIG_MTD_ROM=m
CONFIG_MTD_ABSENT=m

#
# Mapping drivers for chip access
#
CONFIG_MTD_COMPLEX_MAPPINGS=y
# CONFIG_MTD_PHYSMAP is not set
# CONFIG_MTD_PNC2000 is not set
CONFIG_MTD_SC520CDP=m
CONFIG_MTD_NETSC520=m
# CONFIG_MTD_SBC_GXX is not set
# CONFIG_MTD_SCx200_DOCFLASH is not set
# CONFIG_MTD_AMD76XROM is not set
CONFIG_MTD_SCB2_FLASH=m
# CONFIG_MTD_NETtel is not set
# CONFIG_MTD_DILNETPC is not set
# CONFIG_MTD_L440GX is not set
[...2860 lines suppressed...]
# CONFIG_DEPCA is not set
CONFIG_NET_ISA=y
CONFIG_NE2000=m
# CONFIG_E2100 is not set
CONFIG_EWRK3=m
# CONFIG_EEXPRESS is not set
# CONFIG_EEXPRESS_PRO is not set
# CONFIG_HPLAN_PLUS is not set
# CONFIG_HPLAN is not set
# CONFIG_LP486E is not set
# CONFIG_ETH16I is not set
# CONFIG_ZNET is not set
# CONFIG_SEEQ8005 is not set
# CONFIG_AC3200 is not set
# CONFIG_APRICOT is not set
# CONFIG_CS89x0 is not set
# CONFIG_IBMTR is not set
# CONFIG_SKISA is not set
# CONFIG_PROTEON is not set
# CONFIG_SMCTR is not set
# CONFIG_WAVELAN is not set
# CONFIG_HISAX_16_0 is not set
# CONFIG_HISAX_AVM_A1 is not set
# CONFIG_HISAX_IX1MICROR2 is not set
# CONFIG_HISAX_ASUSCOM is not set
# CONFIG_HISAX_TELEINT is not set
# CONFIG_HISAX_HFCS is not set
# CONFIG_HISAX_SPORTSTER is not set
# CONFIG_HISAX_MIC is not set
# CONFIG_HISAX_ISURF is not set
# CONFIG_HISAX_HSTSAPHIR is not set
# CONFIG_ISDN_DRV_ICN is not set
# CONFIG_ISDN_DRV_PCBIT is not set
# CONFIG_ISDN_DRV_SC is not set
# CONFIG_ISDN_DRV_ACT2000 is not set
# CONFIG_ISDN_DRV_AVMB1_B1ISA is not set
# CONFIG_ISDN_DRV_AVMB1_T1ISA is not set

# CONFIG_MOUSE_INPORT is not set
# CONFIG_MOUSE_ATIXL is not set
# CONFIG_MOUSE_LOGIBM is not set
# CONFIG_MOUSE_PC110PAD is not set

# CONFIG_SERIAL_8250_FOURPORT is not set
# CONFIG_SERIAL_8250_ACCENT is not set
# CONFIG_SERIAL_8250_BOCA is not set
# CONFIG_SERIAL_8250_HUB6 is not set
# CONFIG_SERIAL_8250_EXAR_ST16C554 is not set

# CONFIG_PCWATCHDOG is not set
# CONFIG_WDT is not set

# CONFIG_VIDEO_PMS is not set
CONFIG_RADIO_ADAPTERS=y
# CONFIG_RADIO_CADET is not set
# CONFIG_RADIO_RTRACK is not set
# CONFIG_RADIO_RTRACK2 is not set
# CONFIG_RADIO_AZTECH is not set
# CONFIG_RADIO_GEMTEK is not set
# CONFIG_RADIO_SF16FMI is not set
# CONFIG_RADIO_SF16FMR2 is not set
# CONFIG_RADIO_TERRATEC is not set
# CONFIG_RADIO_TRUST is not set
# CONFIG_RADIO_TYPHOON is not set
# CONFIG_RADIO_ZOLTRIX is not set

# CONFIG_SND_OPL4_LIB is not set
# CONFIG_SND_AD1848_LIB is not set
# CONFIG_SND_AD1816A is not set
# CONFIG_SND_AD1848 is not set
# CONFIG_SND_CS4231 is not set
# CONFIG_SND_CS4232 is not set
CONFIG_SND_CS4231_LIB=m
CONFIG_SND_CS4236=m
# CONFIG_SND_ES968 is not set
# CONFIG_SND_ES1688 is not set
# CONFIG_SND_ES18XX is not set
# CONFIG_SND_GUS_SYNTH is not set
# CONFIG_SND_GUSCLASSIC is not set
# CONFIG_SND_GUSEXTREME is not set
# CONFIG_SND_GUSMAX is not set
# CONFIG_SND_INTERWAVE is not set
# CONFIG_SND_INTERWAVE_STB is not set
# CONFIG_SND_OPTI92X_AD1848 is not set
# CONFIG_SND_OPTI92X_CS4231 is not set
# CONFIG_SND_OPTI93X is not set
# CONFIG_SND_SB8 is not set
CONFIG_SND_SB16=m
CONFIG_SND_SBAWE=m
# CONFIG_SND_SB16_CSP is not set
# CONFIG_SND_ALS100 is not set
# CONFIG_SND_AZT2320 is not set
# CONFIG_SND_CMI8330 is not set
# CONFIG_SND_DT019X is not set
CONFIG_SND_OPL3SA2=m
# CONFIG_SND_SGALAXY is not set
# CONFIG_SND_SSCAPE is not set
# CONFIG_SND_PDAUDIOCF is not set
CONFIG_SND_DARLA20=m
CONFIG_SND_GINA20=m
CONFIG_SND_LAYLA20=m
CONFIG_SND_DARLA24=m
CONFIG_SND_GINA24=m
CONFIG_SND_LAYLA24=m
CONFIG_SND_MONA=m
CONFIG_SND_MIA=m
CONFIG_SND_ECHO3G=m
CONFIG_SND_INDIGO=m
CONFIG_SND_INDIGOIO=m
CONFIG_SND_INDIGODJ=m
# CONFIG_SND_SOC is not set

## END of ISA options.

# CONFIG_FORCED_INLINING is not set

CONFIG_MIGRATION=y
CONFIG_RESOURCES_64BIT=y
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
# CONFIG_LEDS_CORGI is not set
# CONFIG_LEDS_LOCOMO is not set
# CONFIG_LEDS_SPITZ is not set
# CONFIG_LEDS_IXP4XX is not set
# CONFIG_LEDS_TOSA is not set
# CONFIG_LEDS_S3C24XX is not set
# CONFIG_LEDS_AMS_DELTA is not set
# CONFIG_LEDS_NET48XX is not set
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_TIMER=m
CONFIG_LEDS_TRIGGER_IDE_DISK=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=m

CONFIG_DMA_ENGINE=y
CONFIG_NET_DMA=y
CONFIG_INTEL_IOATDMA=m

# CONFIG_UNUSED_SYMBOLS is not set

CONFIG_UTRACE=y
CONFIG_PTRACE=y

CONFIG_KPROBES=y

# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set

CONFIG_HZ_1000=y

CONFIG_TIMER_STATS=y

# Auxillary displays
CONFIG_KS0108=m
CONFIG_KS0108_PORT=0x378
CONFIG_KS0108_DELAY=2
CONFIG_CFAG12864B=y
CONFIG_CFAG12864B_RATE=20

# CONFIG_PHANTOM is not set
# CONFIG_BLINK is not set
CONFIG_EEPROM_93CX6=m

CONFIG_CPU_IDLE=y
# CONFIG_CPU_IDLE_GOV_LADDER is not set
CONFIG_CPU_IDLE_GOV_MENU=y

CONFIG_POWER_SUPPLY=m
# CONFIG_POWER_SUPPLY_DEBUG is not set
CONFIG_APM_POWER=m
# CONFIG_BATTERY_DS2760 is not set
CONFIG_BATTERY_PMU=m
# CONFIG_PDA_POWER is not set

CONFIG_AUXDISPLAY=y

CONFIG_UIO=m
CONFIG_UIO_CIF=m

CONFIG_INSTRUMENTATION=y
# CONFIG_CRC7 is not set

CONFIG_DEFAULT_RELATIME=y

# LIRC
CONFIG_INPUT_LIRC=y
CONFIG_LIRC_DEV=m
CONFIG_LIRC_ATIUSB=m
CONFIG_LIRC_BT829=m
CONFIG_LIRC_CMDIR=m
CONFIG_LIRC_I2C=m
CONFIG_LIRC_IGORPLUGUSB=m
CONFIG_LIRC_IMON=m
CONFIG_LIRC_IT87=m
CONFIG_LIRC_MCEUSB=m
CONFIG_LIRC_MCEUSB2=m
CONFIG_LIRC_PVR150=m
CONFIG_LIRC_PARALLEL=m
CONFIG_LIRC_SERIAL=m
CONFIG_LIRC_SIR=m
CONFIG_LIRC_STREAMZAP=m
CONFIG_LIRC_TTUSBIR=m


--- NEW FILE config-i586 ---
CONFIG_M586=y

# CONFIG_NOHIGHMEM is not set
CONFIG_HIGHMEM4G=y
# CONFIG_HIGHMEM64G is not set

CONFIG_X86_POWERNOW_K6=m


--- NEW FILE config-i686 ---
CONFIG_M686=y
# CONFIG_NOHIGHMEM is not set
CONFIG_HIGHMEM4G=y
# CONFIG_HIGHMEM64G is not set

CONFIG_CRYPTO_DEV_PADLOCK=m
CONFIG_CRYPTO_DEV_PADLOCK_AES=m
CONFIG_CRYPTO_DEV_PADLOCK_SHA=m


--- NEW FILE config-i686-PAE ---
CONFIG_M686=y
# CONFIG_NOHIGHMEM is not set
# CONFIG_HIGHMEM4G is not set
CONFIG_HIGHMEM64G=y



--- NEW FILE config-ia64 ---
CONFIG_CRASH_DUMP=y
CONFIG_PROC_VMCORE=y



--- NEW FILE config-ia64-generic ---
#
# Automatically generated make config: don't edit
#

#
# Processor type and features
#
CONFIG_IA64=y
CONFIG_64BIT=y
# CONFIG_XEN is not set
# CONFIG_ARCH_XEN is not set
# CONFIG_XEN_PRIVILEGED_GUEST is not set
# CONFIG_XEN_VT is not set
CONFIG_MMU=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
CONFIG_TIME_INTERPOLATION=y
CONFIG_EFI=y
# CONFIG_ITANIUM is not set
CONFIG_MCKINLEY=y
CONFIG_IA64_GENERIC=y
# CONFIG_IA64_DIG is not set
# CONFIG_IA64_HP_ZX1 is not set
# CONFIG_IA64_SGI_SN2 is not set
CONFIG_IA64_ESI=y
CONFIG_MSPEC=y
# CONFIG_IA64_HP_SIM is not set
# CONFIG_IA64_PAGE_SIZE_4KB is not set
# CONFIG_IA64_PAGE_SIZE_8KB is not set
CONFIG_IA64_PAGE_SIZE_16KB=y
# CONFIG_IA64_PAGE_SIZE_64KB is not set
CONFIG_IA64_L1_CACHE_SHIFT=7
CONFIG_NUMA=y
# CONFIG_VIRTUAL_MEM_MAP is not set
CONFIG_SPARSEMEM_MANUAL=y
CONFIG_SPARSEMEM=y
CONFIG_MEMORY_HOTPLUG=y
CONFIG_IA64_MCA_RECOVERY=m
CONFIG_IA64_CYCLONE=y
CONFIG_MMTIMER=y
CONFIG_IOSAPIC=y
CONFIG_FORCE_MAX_ZONEORDER=18
CONFIG_NR_CPUS=1024
# CONFIG_IA32_SUPPORT is not set
# CONFIG_COMPAT is not set
CONFIG_PERFMON=y
CONFIG_IA64_PALINFO=y
CONFIG_EFI_VARS=y
CONFIG_SERIAL_8250_RUNTIME_UARTS=16
CONFIG_EFI_PCDP=y
#
# Block devices
#
# CONFIG_BLK_DEV_FD is not set

#
# IDE chipset support/bugfixes
#
CONFIG_IDE_MAX_HWIFS=4
CONFIG_BLK_DEV_SGIIOC4=y

#
# Character devices
#

#
# Watchdog Cards
#
# CONFIG_HW_RANDOM is not set
# CONFIG_GEN_RTC is not set
CONFIG_EFI_RTC=y


#
# AGP
#
CONFIG_AGP_I460=y
CONFIG_AGP_HP_ZX1=y
CONFIG_AGP_SGI_TIOCA=y

#
# HP Simulator drivers
#
# CONFIG_HP_SIMETH is not set
# CONFIG_HP_SIMSERIAL is not set
# CONFIG_HP_SIMSCSI is not set

#
# Kernel hacking
#
# CONFIG_IA64_PRINT_HAZARDS is not set
# CONFIG_DISABLE_VHPT is not set
# CONFIG_IA64_DEBUG_CMPXCHG is not set
# CONFIG_IA64_DEBUG_IRQ is not set

#
# Memory Technology Devices (MTD)
#
# CONFIG_MTD is not set

#
# SGI
#
CONFIG_SGI_SNSC=y
CONFIG_IA64_SGI_SN_XP=y

#
# SCSI low-level drivers
#
# CONFIG_SCSI_BUSLOGIC is not set

#
CONFIG_ACPI=y
CONFIG_ACPI_AC=m
# CONFIG_ACPI_ASUS is not set
CONFIG_ACPI_BAY=m
CONFIG_ACPI_BATTERY=m
CONFIG_ACPI_BLACKLIST_YEAR=0
CONFIG_ACPI_BUTTON=m
# CONFIG_ACPI_DOCK is not set
CONFIG_ACPI_EC=y
CONFIG_ACPI_FAN=y
CONFIG_ACPI_HOTPLUG_MEMORY=y
CONFIG_ACPI_NUMA=y
CONFIG_ACPI_POWER=y
CONFIG_ACPI_PROCESSOR=y
CONFIG_ACPI_PROCFS=y
CONFIG_ACPI_SLEEP=y
CONFIG_ACPI_SYSTEM=y
CONFIG_ACPI_THERMAL=y
# CONFIG_ACPI_TOSHIBA is not set
CONFIG_ACPI_VIDEO=m
# CONFIG_ACPI_PROC_EVENT is not set

CONFIG_SERIAL_SGI_L1_CONSOLE=y
CONFIG_PM=y
CONFIG_HOTPLUG_PCI=y
# CONFIG_HPET is not set
# CONFIG_HOTPLUG_PCI_CPCI is not set
CONFIG_HOTPLUG_PCI_SHPC=m
CONFIG_HOTPLUG_PCI_SGI=m
CONFIG_PNPACPI=y

CONFIG_SCHED_SMT=y
CONFIG_SGI_TIOCX=y
CONFIG_SGI_MBCS=m

CONFIG_ARCH_DISCONTIGMEM_ENABLE=y

CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_DEBUG=y
CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=m
CONFIG_CPU_FREQ_GOV_USERSPACE=m
CONFIG_CPU_FREQ_GOV_ONDEMAND=m
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
CONFIG_CPU_FREQ_STAT=m
CONFIG_CPU_FREQ_STAT_DETAILS=y

CONFIG_IA64_ACPI_CPUFREQ=m

# CONFIG_CRASH is not set

CONFIG_SERIAL_SGI_IOC3=m
CONFIG_SGI_IOC3=m
CONFIG_SERIAL_SGI_IOC4=m
CONFIG_SGI_IOC4=y

# CONFIG_PERMIT_BSP_REMOVE is not set
# CONFIG_FORCE_CPEI_RETARGET is not set

CONFIG_NODES_SHIFT=10

# CONFIG_BCM43XX is not set

CONFIG_HW_RANDOM_INTEL=m

#temporary until ia64 kexec/kdump is fixed (breaks xen)
CONFIG_CRASH_DUMP=y
CONFIG_PROC_VMCORE=y

# drivers/media/video/usbvision/usbvision-i2c.c:64:39: error: macro "outb" passed 4 arguments, but takes just 2
# CONFIG_VIDEO_USBVISION is not set

# CONFIG_IA64_MC_ERR_INJECT is not set

CONFIG_DMIID=y


--- NEW FILE config-nodebug ---
CONFIG_SND_VERBOSE_PRINTK=y
CONFIG_SND_DEBUG=y
CONFIG_SND_DEBUG_DETECT=y
CONFIG_SND_PCM_XRUN_DEBUG=y

CONFIG_DEBUG_IGNORE_QUIET=y
CONFIG_DEBUG_MUTEXES=y
CONFIG_DEBUG_RT_MUTEXES=y
CONFIG_DEBUG_LOCK_ALLOC=y
CONFIG_PROVE_LOCKING=y
CONFIG_DEBUG_VM=y
CONFIG_DEBUG_SPINLOCK=y

CONFIG_FAULT_INJECTION=y
CONFIG_FAILSLAB=y
CONFIG_FAIL_PAGE_ALLOC=y
CONFIG_FAIL_MAKE_REQUEST=y
CONFIG_FAULT_INJECTION_DEBUG_FS=y
CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y

CONFIG_SLUB_DEBUG_ON=y

CONFIG_LOCK_STAT=y

CONFIG_DEBUG_STACK_USAGE=y

# CONFIG_ACPI_DEBUG is not set


--- NEW FILE config-powerpc-generic ---
# Most PowerPC kernels we build are SMP
CONFIG_SMP=y
CONFIG_IRQ_ALL_CPUS=y
CONFIG_PPC=y
CONFIG_WATCHDOG_RTAS=m
CONFIG_DEBUGGER=y
CONFIG_GENERIC_NVRAM=y
CONFIG_ALTIVEC=y

CONFIG_TAU=y
# CONFIG_TAU_INT is not set
CONFIG_TAU_AVERAGE=y

CONFIG_SECCOMP=y

CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_DEBUG=y
# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=m
CONFIG_CPU_FREQ_GOV_USERSPACE=m
CONFIG_CPU_FREQ_GOV_ONDEMAND=m
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
CONFIG_CPU_FREQ_TABLE=y
CONFIG_CPU_FREQ_STAT=m
CONFIG_CPU_FREQ_STAT_DETAILS=y

CONFIG_PM=y

CONFIG_PM_STD_PARTITION=""

CONFIG_SUSPEND=y
CONFIG_HIBERNATION=y
# CONFIG_RTC is not set
CONFIG_GEN_RTC=y
# CONFIG_GEN_RTC_X is not set
CONFIG_PROC_DEVICETREE=y
# CONFIG_CMDLINE_BOOL is not set
CONFIG_BLK_DEV_IDE_PMAC=y
CONFIG_BLK_DEV_IDE_PMAC_ATA100FIRST=y
CONFIG_BLK_DEV_IDEDMA_PMAC=y
CONFIG_ELECTRA_IDE=y

CONFIG_ADB=y
CONFIG_ADB_PMU=y
CONFIG_WINDFARM=y
CONFIG_WINDFARM_PM112=y
CONFIG_I2C_POWERMAC=y
CONFIG_APPLE_AIRPORT=m
CONFIG_SERIAL_PMACZILOG=m
CONFIG_AGP_UNINORTH=y
CONFIG_FB_OF=y
# CONFIG_FB_CONTROL is not set
CONFIG_FB_IBM_GXT4500=y
CONFIG_FB_RADEON=y
CONFIG_FB_MATROX=y
CONFIG_FB_NVIDIA=y
# CONFIG_FB_VGA16 is not set
CONFIG_FB_ATY128_BACKLIGHT=y
CONFIG_FB_ATY_BACKLIGHT=y
CONFIG_FB_RADEON_BACKLIGHT=y
CONFIG_FB_RIVA_BACKLIGHT=y
CONFIG_FB_NVIDIA_BACKLIGHT=y

CONFIG_SND_POWERMAC=m
CONFIG_SND_POWERMAC_AUTO_DRC=y
CONFIG_SND_AOA=m
CONFIG_SND_AOA_SOUNDBUS=m
CONFIG_SND_AOA_FABRIC_LAYOUT=m
CONFIG_SND_AOA_ONYX=m
CONFIG_SND_AOA_TAS=m
CONFIG_SND_AOA_TOONIE=m
CONFIG_SND_AOA_SOUNDBUS_I2S=m

CONFIG_XMON=y
CONFIG_XMON_DEFAULT=y
CONFIG_XMON_DISASSEMBLY=y

CONFIG_BOOTX_TEXT=y
CONFIG_MAC_EMUMOUSEBTN=y
CONFIG_CAPI_EICON=y

CONFIG_NVRAM=y

# CONFIG_PCMCIA_M8XX is not set
# CONFIG_SCSI_AHA1542 is not set
# CONFIG_SCSI_IN2000 is not set
# CONFIG_NI52 is not set
# CONFIG_NI65 is not set
# CONFIG_LANCE is not set
# CONFIG_3C515 is not set
# CONFIG_ELPLUS is not set

CONFIG_MEMORY_HOTPLUG=y

# Stuff which wants bus_to_virt() or virt_to_bus()
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_VIDEO_STRADIS is not set
# CONFIG_VIDEO_ZORAN is not set
# CONFIG_ATM_HORIZON is not set
# CONFIG_ATM_FIRESTREAM is not set
# CONFIG_ATM_AMBASSADOR is not set
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_BUSLOGIC is not set

CONFIG_USB_HIDINPUT_POWERBOOK=y

# CONFIG_PPC_EARLY_DEBUG is not set

# CONFIG_PMAC_BACKLIGHT_LEGACY is not set
CONFIG_LEDS_TRIGGER_TIMER=m
CONFIG_LEDS_TRIGGER_HEARTBEAT=m

# FIXME: Should depend on IA64/x86
# CONFIG_SGI_IOC4 is not set

CONFIG_PPC_EFIKA=y
CONFIG_PPC_LITE5200=y
CONFIG_PPC_BESTCOMM=y
CONFIG_PMAC_RACKMETER=m
CONFIG_SERIAL_MPC52xx=y
CONFIG_SERIAL_MPC52xx_CONSOLE=y
CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=115200
CONFIG_USB_OHCI_HCD_PPC_SOC=y
CONFIG_USB_OHCI_HCD_PCI=y
CONFIG_USB_OHCI_HCD_PPC_OF=y
CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
CONFIG_USB_OHCI_HCD_PPC_OF_LE=y

CONFIG_SERIAL_UARTLITE=m
CONFIG_SERIAL_UARTLITE_CONSOLE=y

CONFIG_SENSORS_AMS=m
CONFIG_SENSORS_AMS_PMU=y
CONFIG_SENSORS_AMS_I2C=y

CONFIG_IDE=y
CONFIG_BLK_DEV_IDE=y

#
# Please see Documentation/ide.txt for help/info on IDE drives
#
# CONFIG_BLK_DEV_IDE_SATA is not set
CONFIG_BLK_DEV_IDEDISK=y
CONFIG_IDEDISK_MULTI_MODE=y
# CONFIG_BLK_DEV_IDECS is not set
CONFIG_BLK_DEV_IDECD=m
# CONFIG_BLK_DEV_IDETAPE is not set
CONFIG_BLK_DEV_IDEFLOPPY=m
# CONFIG_BLK_DEV_IDESCSI is not set
CONFIG_IDE_TASK_IOCTL=y
#
# IDE chipset support/bugfixes
#
# CONFIG_IDE_GENERIC is not set
# CONFIG_BLK_DEV_IDEPNP is not set
# CONFIG_BLK_DEV_IDEPCI is not set
CONFIG_IDEPCI_SHARE_IRQ=y
# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
# CONFIG_IDEDMA_ONLYDISK is not set
# CONFIG_BLK_DEV_AEC62XX is not set
# CONFIG_BLK_DEV_ALI15X3 is not set
# CONFIG_BLK_DEV_AMD74XX is not set
# CONFIG_BLK_DEV_CMD64X is not set
# CONFIG_BLK_DEV_TRIFLEX is not set
# CONFIG_BLK_DEV_CY82C693 is not set
# CONFIG_BLK_DEV_CS5520 is not set
# CONFIG_BLK_DEV_CS5530 is not set
# CONFIG_BLK_DEV_HPT34X is not set
# CONFIG_BLK_DEV_HPT366 is not set
# CONFIG_BLK_DEV_JMICRON is not set
# CONFIG_BLK_DEV_SC1200 is not set
# CONFIG_BLK_DEV_PIIX is not set
# CONFIG_BLK_DEV_IT821X is not set
# CONFIG_BLK_DEV_NS87415 is not set
# CONFIG_BLK_DEV_PDC202XX_OLD is not set
# CONFIG_BLK_DEV_PDC202XX_NEW is not set
# CONFIG_BLK_DEV_SVWKS is not set
# CONFIG_BLK_DEV_SIIMAGE is not set
# CONFIG_BLK_DEV_SL82C105 is not set
# CONFIG_BLK_DEV_SLC90E66 is not set
# CONFIG_BLK_DEV_TRM290 is not set
# CONFIG_BLK_DEV_VIA82CXXX is not set
CONFIG_BLK_DEV_IDE_PMAC=y
CONFIG_BLK_DEV_IDE_PMAC_ATA100FIRST=y
CONFIG_BLK_DEV_IDEDMA_PMAC=y
# CONFIG_IDE_ARM is not set
# CONFIG_IDE_CHIPSETS is not set
CONFIG_BLK_DEV_IDEDMA=y
# CONFIG_IDEDMA_IVB is not set
# CONFIG_BLK_DEV_HD is not set
# CONFIG_USB_STORAGE_ISD200 is not set
CONFIG_MTD_PHYSMAP_OF=m
CONFIG_IDE_PROC_FS=y
CONFIG_MACINTOSH_DRIVERS=y
# CONFIG_DEBUG_PAGEALLOC is not set

CONFIG_PPC_PASEMI_MDIO=m
CONFIG_SPU_FS_64K_LS=y
CONFIG_PPC_PASEMI_CPUFREQ=y
CONFIG_PMAC_APM_EMU=m
CONFIG_HW_RANDOM_PASEMI=m

CONFIG_EDAC=y
# CONFIG_EDAC_DEBUG is not set
CONFIG_EDAC_MM_EDAC=m
CONFIG_EDAC_PASEMI=m

CONFIG_AXON_RAM=m
CONFIG_OPROFILE_CELL=y

# CONFIG_MPC5200_WDT is not set


--- NEW FILE config-powerpc32-generic ---
# CONFIG_SMP is not set
CONFIG_PPC32=y
# CONFIG_PPC64 is not set
# CONFIG_RTAS_PROC is not set
# CONFIG_PCMCIA_M8XX is not set
# CONFIG_HOTPLUG_PCI is not set
CONFIG_CLASSIC32=y
CONFIG_CPU_FREQ_PMAC=y
CONFIG_PPC_MULTIPLATFORM=y
CONFIG_PPC_CHRP=y
CONFIG_PPC_PMAC=y
# CONFIG_PPC_PREP is not set

CONFIG_PMAC_APM_EMU=y
CONFIG_PMAC_BACKLIGHT=y

CONFIG_HIGHMEM=y
# CONFIG_HIGHMEM_START_BOOL is not set
# CONFIG_LOWMEM_SIZE_BOOL is not set
# CONFIG_TASK_SIZE_BOOL is not set
# CONFIG_KERNEL_START_BOOL is not set
# CONFIG_PPC601_SYNC_FIX is not set
CONFIG_ADVANCED_OPTIONS=y
CONFIG_SCSI_MESH=m
CONFIG_SCSI_MESH_SYNC_RATE=5
CONFIG_SCSI_MESH_RESET_DELAY_MS=4000

CONFIG_SCSI_MAC53C94=m
CONFIG_ADB_CUDA=y
CONFIG_ADB_MACIO=y
CONFIG_INPUT_ADBHID=y
CONFIG_ADB_PMU_LED=y
CONFIG_ADB_PMU_LED_IDE=y

CONFIG_PMAC_MEDIABAY=y
CONFIG_BMAC=m
CONFIG_MACE=m
# CONFIG_MACE_AAUI_PORT is not set
CONFIG_MV643XX_ETH=m
CONFIG_I2C_HYDRA=m
CONFIG_I2C_MPC=m
CONFIG_THERM_WINDTUNNEL=m
CONFIG_THERM_ADT746X=m
# CONFIG_ANSLCD is not set

CONFIG_SENSORS_M41T00=m
CONFIG_FB_PLATINUM=y
CONFIG_FB_VALKYRIE=y
CONFIG_FB_CT65550=y
CONFIG_DMASOUND_PMAC=m
# CONFIG_BDI_SWITCH is not set
CONFIG_MAC_FLOPPY=m
# CONFIG_BLK_DEV_FD is not set

CONFIG_FB_ATY128=y
CONFIG_FB_ATY=y
CONFIG_FB_MATROX=y
# CONFIG_KEXEC is not set

# CONFIG_CRASH is not set

# CONFIG_HVC_RTAS is not set
# CONFIG_MAMBO is not set

# CONFIG_UDBG_RTAS_CONSOLE is not set
CONFIG_BRIQ_PANEL=m

CONFIG_PATA_MPC52xx=m

CONFIG_PPC_MPC5200_BUGFIX=y
CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_DEBUG_STACKOVERFLOW=y


--- NEW FILE config-powerpc32-smp ---
CONFIG_SMP=y
# CONFIG_HOTPLUG_CPU is not set
CONFIG_NR_CPUS=4
# CONFIG_BATTERY_PMU is not set


--- NEW FILE config-powerpc64 ---
CONFIG_WINDFARM_PM81=y
CONFIG_WINDFARM_PM91=y
CONFIG_PPC_PMAC64=y
CONFIG_PPC_MAPLE=y
CONFIG_PPC_SYSTEMSIM=y
CONFIG_BLK_DEV_SYSTEMSIM=m
CONFIG_SYSTEMSIM_NET=m
CONFIG_PPC_CELL=y
CONFIG_PPC_IBM_CELL_BLADE=y
CONFIG_PPC_ISERIES=y
CONFIG_PPC_PSERIES=y
CONFIG_PPC_PMAC=y
CONFIG_PPC_PASEMI=y
CONFIG_PPC_PS3=y
CONFIG_PPC_CELLEB=y
CONFIG_PS3_HTAB_SIZE=20
# CONFIG_PS3_DYNAMIC_DMA is not set
CONFIG_PS3_USE_LPAR_ADDR=y
CONFIG_PS3_ADVANCED=y
CONFIG_PS3_HTAB_SIZE=20
# CONFIG_PS3_DYNAMIC_DMA is not set
CONFIG_PS3_USE_LPAR_ADDR=y
CONFIG_PS3_VUART=y
CONFIG_PS3_PS3AV=y
CONFIG_PS3_STORAGE=m
CONFIG_PS3_STORAGE_EXPECTED_NUM_DRIVES=3
CONFIG_PS3_STORAGE_MAX_SPINUP_WAIT_TIME=10
CONFIG_PS3_DISK=m
CONFIG_PS3_ROM=m
CONFIG_PS3_FLASH=m
CONFIG_SND_PS3=m
CONFIG_SND_PS3_DEFAULT_START_DELAY=1000
CONFIG_GELIC_NET=m
CONFIG_GELIC_WIRELESS=y
CONFIG_CBE_THERM=m
CONFIG_CBE_CPUFREQ=m
CONFIG_CBE_CPUFREQ_PMI=m
CONFIG_PMAC_RACKMETER=m
CONFIG_IBMEBUS=y
CONFIG_SPU_FS=m
CONFIG_RTAS_FLASH=y
CONFIG_PPC_SPLPAR=y
CONFIG_SCANLOG=y
CONFIG_LPARCFG=y
CONFIG_SERIAL_ICOM=m
CONFIG_HVCS=m
CONFIG_HVC_CONSOLE=y
CONFIG_HOTPLUG_PCI=y
CONFIG_THERM_PM72=y
CONFIG_IBMVETH=m
CONFIG_SCSI_IBMVSCSI=m
# CONFIG_HOTPLUG_PCI_CPCI is not set
CONFIG_HOTPLUG_PCI_SHPC=m
CONFIG_HOTPLUG_PCI_RPA=m
CONFIG_HOTPLUG_PCI_RPA_DLPAR=y
CONFIG_ADB_PMU_LED=y
CONFIG_ADB_PMU_LED_IDE=y
CONFIG_PMAC_SMU=y
CONFIG_CPU_FREQ_PMAC64=y
CONFIG_SCSI_IPR=m
CONFIG_SCSI_IPR_TRACE=y
CONFIG_SCSI_IPR_DUMP=y
CONFIG_SPIDER_NET=m
CONFIG_HVC_RTAS=y
CONFIG_HVC_ISERIES=y
CONFIG_MAMBO=y
CONFIG_MAMBO_DISK=m
CONFIG_MAMBO_NET=m
CONFIG_CBE_RAS=y

# iSeries device drivers
#
CONFIG_ISERIES_VETH=m
# CONFIG_VIOCONS is not set
CONFIG_VIODASD=m
CONFIG_VIOCD=m
CONFIG_VIOTAPE=m

# virq_to_hw() requires irq_map[] to be exported. Ick.
# CONFIG_PASEMI_MAC is not set 
CONFIG_SERIAL_OF_PLATFORM=m

CONFIG_PPC_PASEMI_IOMMU=y
CONFIG_SERIAL_TXX9=y
CONFIG_SERIAL_TXX9_NR_UARTS=6
CONFIG_SERIAL_TXX9_CONSOLE=y

CONFIG_HVC_BEAT=y

CONFIG_FB_PS3=y
CONFIG_FB_PS3_DEFAULT_SIZE_M=18

CONFIG_PPC_PMI=m
CONFIG_PS3_SYS_MANAGER=y
# CONFIG_BLK_DEV_CELLEB is not set

CONFIG_PATA_SCC=m

CONFIG_APM_EMULATION=m

CONFIG_PPC64=y
CONFIG_VIRT_CPU_ACCOUNTING=y
CONFIG_NR_CPUS=128
# CONFIG_FB_PLATINUM is not set
# CONFIG_FB_VALKYRIE is not set
# CONFIG_FB_CT65550 is not set
# CONFIG_FB_VGA16 is not set
# CONFIG_FB_ATY128 is not set
# CONFIG_FB_ATY is not set

# CONFIG_POWER4_ONLY is not set
# CONFIG_PPC_PASEMI is not set

CONFIG_RTAS_PROC=y
CONFIG_IOMMU_VMERGE=y
CONFIG_NUMA=y
# CONFIG_PPC_64K_PAGES is not set
CONFIG_SCHED_SMT=y

# CONFIG_MV643XX_ETH is not set
CONFIG_IRQSTACKS=y
CONFIG_DEBUG_STACKOVERFLOW=y
# CONFIG_CRASH is not set
# CONFIG_INPUT_PCSPKR is not set

CONFIG_EHEA=m
CONFIG_INFINIBAND_EHCA=m
CONFIG_INFINIBAND_EHCA_SCALING=y

CONFIG_HCALL_STATS=y

CONFIG_XMON_DISASSEMBLY=y

CONFIG_SCSI_IBMVSCSIS=m

CONFIG_SECCOMP=y


--- NEW FILE config-powerpc64-kdump ---
# CONFIG_EMBEDDED is not set
CONFIG_CRASH_DUMP=y
CONFIG_PROC_VMCORE=y


--- NEW FILE config-s390x ---
CONFIG_64BIT=y
# CONFIG_MARCH_G5 is not set
CONFIG_MARCH_Z900=y
# CONFIG_MARCH_Z990 is not set
CONFIG_NR_CPUS=64
CONFIG_COMPAT=y

CONFIG_MMU=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y

CONFIG_LOG_BUF_SHIFT=16
CONFIG_NO_IDLE_HZ=y
CONFIG_NO_IDLE_HZ_INIT=y

CONFIG_SMP=y

#
# I/O subsystem configuration
#
CONFIG_MACHCHK_WARNING=y
CONFIG_QDIO=m
# CONFIG_QDIO_DEBUG is not set

#
# Misc
#
CONFIG_IPL=y
# CONFIG_IPL_TAPE is not set
CONFIG_IPL_VM=y
# CONFIG_PROCESS_DEBUG is not set
CONFIG_PFAULT=y
# CONFIG_SHARED_KERNEL is not set
CONFIG_CMM=m
CONFIG_CMM_PROC=y
CONFIG_VIRT_TIMER=y
CONFIG_NETIUCV=m
CONFIG_SMSGIUCV=m

#
# SCSI low-level drivers
#
CONFIG_ZFCP=m
CONFIG_ZFCPDUMP=m
CONFIG_CCW=y

#
# S/390 block device drivers
#
CONFIG_DCSSBLK=m
CONFIG_BLK_DEV_XPRAM=m
CONFIG_DASD=m
CONFIG_DASD_PROFILE=y
CONFIG_DASD_ECKD=m
CONFIG_DASD_FBA=m
CONFIG_DASD_DIAG=m
CONFIG_DASD_EER=y

#
# S/390 character device drivers
#
CONFIG_TN3270=y
CONFIG_TN3270_CONSOLE=y
CONFIG_TN3215=y
CONFIG_TN3215_CONSOLE=y
CONFIG_CCW_CONSOLE=y
CONFIG_SCLP=y
CONFIG_SCLP_TTY=y
CONFIG_SCLP_CONSOLE=y
CONFIG_SCLP_VT220_TTY=y
CONFIG_SCLP_VT220_CONSOLE=y
CONFIG_SCLP_CPI=m
CONFIG_S390_TAPE=m
CONFIG_S390_TAPE_3590=m

CONFIG_APPLDATA_BASE=y
CONFIG_APPLDATA_MEM=m
CONFIG_APPLDATA_OS=m
CONFIG_APPLDATA_NET_SUM=m
CONFIG_TN3270_TTY=y
CONFIG_TN3270_FS=m


#
# S/390 tape interface support
#
CONFIG_S390_TAPE_BLOCK=y

#
# S/390 tape hardware support
#
CONFIG_S390_TAPE_34XX=m

# CONFIG_PPP is not set
# CONFIG_SLIP is not set

#
# Token Ring devices
#
CONFIG_TR=y
# CONFIG_SHAPER is not set
CONFIG_NETCONSOLE=m

#
# Wan interfaces
#
# CONFIG_WAN is not set

#
# S/390 network device drivers
#
CONFIG_LCS=m
CONFIG_CTC=m
CONFIG_IUCV=m
CONFIG_QETH=m
CONFIG_QETH_IPV6=y
CONFIG_QETH_VLAN=y
CONFIG_CCWGROUP=m

# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_WIRELESS_EXT is not set
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
# CONFIG_MAC80211 is not set
# CONFIG_IEEE80211 is not set
# CONFIG_B44 is not set

# The s390 CPU does not have hardware support for big pages at all.
# CONFIG_HUGETLBFS is not set
# CONFIG_HUGETLB_PAGE is not set

#
# Partition Types
#
CONFIG_PARTITION_ADVANCED=y
# CONFIG_OSF_PARTITION is not set
CONFIG_IBM_PARTITION=y
# CONFIG_MAC_PARTITION is not set
CONFIG_MSDOS_PARTITION=y
# CONFIG_SGI_PARTITION is not set
# CONFIG_SUN_PARTITION is not set


#
# S390 crypto hw
#
CONFIG_CRYPTO_SHA1_S390=m
CONFIG_CRYPTO_SHA256_S390=m
CONFIG_CRYPTO_DES_S390=m
CONFIG_CRYPTO_AES_S390=m

#
# Kernel hacking
#

#
# S390 specific stack options; needs gcc 3.5 so off for now
#
CONFIG_PACK_STACK=y
CONFIG_CHECK_STACK=y
# CONFIG_WARN_STACK is not set
# CONFIG_SMALL_STACK is not set

CONFIG_ZVM_WATCHDOG=m
CONFIG_VMLOGRDR=m
CONFIG_MONREADER=m

CONFIG_VIRT_CPU_ACCOUNTING=y

# CONFIG_CLAW is not set

CONFIG_VMCP=m

# CONFIG_ATMEL is not set

# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_MII is not set

# CONFIG_BOOT_DELAY is not set

CONFIG_STACK_GUARD=256
CONFIG_CMM_IUCV=y

# CONFIG_DETECT_SOFTLOCKUP is not set

CONFIG_S390_HYPFS_FS=y

CONFIG_MONWRITER=m
CONFIG_ZCRYPT=m
CONFIG_ZCRYPT_MONOLITHIC=y

CONFIG_S390_SWITCH_AMODE=y
CONFIG_S390_EXEC_PROTECT=y
CONFIG_AFIUCV=m
CONFIG_S390_PRNG=m

CONFIG_S390_VMUR=m



--- NEW FILE config-sparc ---
# CONFIG_SMP is not set
# CONFIG_DVB_CAPTURE_DRIVERS is not set
CONFIG_SPARC_LED=y
# CONFIG_ATM_FORE200E_SBA is not set
# CONFIG_FB_MODE_HELPERS is not set 
# CONFIG_FONT_7x14 is not set
# CONFIG_FONT_10x18 is not set
# CONFIG_LOGO_SUN_CLUT224 is not set
# CONFIG_SND_SUN_DBRI is not set
CONFIG_UNIX98_PTY_COUNT=256


--- NEW FILE config-sparc-generic ---
CONFIG_HIGHMEM=y
CONFIG_LOG_BUF_SHIFT=15
CONFIG_VT=y
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
CONFIG_NR_CPUS=32
CONFIG_SPARC32=y
CONFIG_SMP=y
CONFIG_SBUS=y
CONFIG_SBUSCHAR=y
CONFIG_SERIAL_CONSOLE=y
CONFIG_SUN_AUXIO=y
CONFIG_SUN_IO=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
# CONFIG_SUN4 is not set
# CONFIG_PCI is not set
CONFIG_SUN_PM=y
CONFIG_SUN_OPENPROMFS=m
# CONFIG_SUNOS_EMUL is not set
CONFIG_PARPORT=m
# CONFIG_PARPORT_PC is not set
# CONFIG_PARPORT_PC_CML1 is not set
CONFIG_PARPORT_SERIAL=m
# CONFIG_PARPORT_PC_FIFO is not set
# CONFIG_PARPORT_PC_SUPERIO is not set
CONFIG_PARPORT_SUNBPP=m
# CONFIG_PARPORT_OTHER is not set
CONFIG_PARPORT_1284=y
# CONFIG_GAMEPORT is not set
CONFIG_PRINTER=m
CONFIG_FB=y
# CONFIG_FB_CYBER2000 is not set
# CONFIG_FB_IMSTT is not set
CONFIG_FB_BW2=y
CONFIG_FB_CG3=y
CONFIG_FB_CG6=y
CONFIG_FB_SBUS=y
CONFIG_FB_TCX=y
CONFIG_FB_CG14=y
CONFIG_FB_P9100=y
CONFIG_FB_LEO=y
# CONFIG_FB_PCI is not set
# CONFIG_FB_IGA is not set
# CONFIG_MDA_CONSOLE is not set
CONFIG_PROM_CONSOLE=y
CONFIG_DUMMY_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE=y
# CONFIG_PCI_CONSOLE is not set
CONFIG_FONTS=y
# CONFIG_FONT_8x8 is not set
# CONFIG_FONT_8x16 is not set
# CONFIG_FONT_6x11 is not set
# CONFIG_FONT_PEARL_8x8 is not set
# CONFIG_FONT_ACORN_8x8 is not set
CONFIG_FONT_SUN8x16=y
# CONFIG_FONT_SUN12x22 is not set
# CONFIG_MTD is not set
CONFIG_LOGO=y
# CONFIG_LOGO_LINUX_MONO is not set
# CONFIG_LOGO_LINUX_VGA16 is not set
CONFIG_LOGO_LINUX_CLUT224=y
# CONFIG_SERIAL_8250 is not set
# CONFIG_SERIAL_8250_CONSOLE is not set
# CONFIG_SERIAL_8250_NR_UARTS is not set
# CONFIG_SERIAL_8250_EXTENDED is not set
# CONFIG_SERIAL_8250_MANY_PORTS is not set
# CONFIG_SERIAL_8250_SHARE_IRQ is not set
# CONFIG_SERIAL_8250_DETECT_IRQ is not set 
# CONFIG_SERIAL_8250_MULTIPORT is not set
# CONFIG_SERIAL_8250_RSA is not set
CONFIG_SERIAL_SUNCORE=y
CONFIG_SERIAL_SUNZILOG=y
CONFIG_SERIAL_SUNZILOG_CONSOLE=y
CONFIG_SERIAL_SUNSU=y
CONFIG_SERIAL_SUNSU_CONSOLE=y
CONFIG_SERIAL_SUNSAB=y
CONFIG_SERIAL_SUNSAB_CONSOLE=y
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_SUN_OPENPROMIO=m
CONFIG_SUN_MOSTEK_RTC=y
# CONFIG_SUN_BPP is not set
# CONFIG_SUN_VIDEOPIX is not set
# CONFIG_SUN_AURORA is not set
CONFIG_TADPOLE_TS102_UCTRL=m
CONFIG_SUN_JSFLASH=m
CONFIG_APM_RTC_IS_GMT=y
CONFIG_RTC=y
# CONFIG_IDE is not set
CONFIG_BLK_DEV_FD=y
# CONFIG_SCSI_CONSTANTS is not set
CONFIG_SCSI_MULTI_LUN=y
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_ACARD is not set
# CONFIG_SCSI_AACRAID is not set
# CONFIG_SCSI_AIC7XXX is not set
# CONFIG_SCSI_AIC7XXX_OLD is not set
# CONFIG_SCSI_AIC79XX is not set
# CONFIG_SCSI_ADVANSYS is not set
# CONFIG_SCSI_MEGARAID is not set
# CONFIG_SCSI_SATA is not set
# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_SCSI_CPQFCTS is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_EATA is not set
# CONFIG_SCSI_EATA_PIO is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
# CONFIG_SCSI_GDTH is not set
# CONFIG_SCSI_IPS is not set
# CONFIG_SCSI_INIA100 is not set
# CONFIG_SCSI_PPA is not set
# CONFIG_SCSI_IMM is not set
CONFIG_SCSI_SYM53C8XX_2=m
CONFIG_SCSI_QLOGICPTI=m
# CONFIG_SCSI_DC395x is not set
# CONFIG_SCSI_NSP32 is not set
CONFIG_SCSI_SUNESP=m
CONFIG_FC4=m
CONFIG_FC4_SOC=m
CONFIG_FC4_SOCAL=m
CONFIG_SCSI_PLUTO=m
CONFIG_SCSI_FCAL=m
CONFIG_SUNLANCE=m
CONFIG_SUNBMAC=m
CONFIG_MYRI_SBUS=m
CONFIG_SUNQE=m
# CONFIG_KEYBOARD_ATKBD is not set
CONFIG_KEYBOARD_SUNKBD=y
CONFIG_INPUT_SPARCSPKR=m
# CONFIG_SOUND_PRIME is not set
CONFIG_SND_SUN_AMD7930=m
CONFIG_SND_SUN_CS4231=m
# CONFIG_ISDN_BOOL is not set
# CONFIG_BT is not set
# CONFIG_SERIO_I8042 is not set
# CONFIG_INPUT_JOYSTICK is not set
# CONFIG_INPUT_TOUCHSCREEN is not set
# CONFIG_USB is not set
# CONFIG_USB_GADGET is not set
# CONFIG_USB_NET2280 is not set
# CONFIG_USB_ZERO is not set
# CONFIG_USB_ETH is not set
# CONFIG_USB_GADGETFS is not set
# CONFIG_ACORN_PARTITION is not set
# CONFIG_OSF_PARTITION is not set
# CONFIG_AMIGA_PARTITION is not set
# CONFIG_ATARI_PARTITION is not set
# CONFIG_MAC_PARTITION is not set
# CONFIG_MSDOS_PARTITION is not set
# CONFIG_LDM_PARTITION is not set
# CONFIG_NEC98_PARTITION is not set
# CONFIG_SGI_PARTITION is not set
# CONFIG_ULTRIX_PARTITION is not set
# CONFIG_EFI_PARTITION is not set


--- NEW FILE config-sparc-smp ---


--- NEW FILE config-sparc64 ---
# CONFIG_SMP is not set



--- NEW FILE config-sparc64-generic ---
CONFIG_SPARC=y
CONFIG_SPARC64=y
CONFIG_SECCOMP=y

CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_TABLE=m
CONFIG_CPU_FREQ_DEBUG=y
# CONFIG_CPU_FREQ_STAT is not set
# CONFIG_CPU_FREQ_STAT_DETAILS is not set
CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=m
CONFIG_CPU_FREQ_GOV_USERSPACE=m
CONFIG_CPU_FREQ_GOV_ONDEMAND=m
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
CONFIG_US3_FREQ=m
CONFIG_US2E_FREQ=m

CONFIG_SUN_LDOMS=y
# CONFIG_NO_HZ is not set
# CONFIG_HIGH_RES_TIMERS is not set
CONFIG_SCHED_SMT=y
CONFIG_SCHED_MC=y
# CONFIG_CRASH is not set
CONFIG_64BIT=y
# CONFIG_BBC_I2C is not set
CONFIG_HUGETLB_PAGE_SIZE_4MB=y
# CONFIG_HUGETLB_PAGE_SIZE_512K is not set
# CONFIG_HUGETLB_PAGE_SIZE_64K is not set
CONFIG_NR_CPUS=32
CONFIG_US3_FREQ=m
CONFIG_US2E_FREQ=m
CONFIG_SUN_OPENPROMFS=m
CONFIG_SPARC32_COMPAT=y
CONFIG_COMPAT=y
CONFIG_UID16=y
CONFIG_BINFMT_ELF32=y
CONFIG_BINFMT_AOUT32=y
CONFIG_SUNOS_EMUL=y
CONFIG_SOLARIS_EMUL=m
CONFIG_ENVCTRL=m
CONFIG_DISPLAY7SEG=m
CONFIG_WATCHDOG_CP1XXX=m
CONFIG_WATCHDOG_RIO=m
# CONFIG_CMDLINE_BOOL is not set
CONFIG_FB_BW2=y
CONFIG_FB_CG3=y
CONFIG_FB_CG6=y
# CONFIG_FB_RIVA is not set
# CONFIG_FB_MATROX is not set
# CONFIG_FB_RADEON is not set
CONFIG_FB_ATY=y
# CONFIG_FB_SIS is not set
# CONFIG_FB_NEOMAGIC is not set
# CONFIG_FB_3DFX is not set
# CONFIG_FB_VOODOO1 is not set
# CONFIG_FB_TRIDENT is not set
CONFIG_FB_SBUS=y
CONFIG_FB_FFB=y
# CONFIG_FB_TCX is not set
# CONFIG_FB_CG14 is not set
CONFIG_FB_PM2=y
CONFIG_FB_P9100=y
# CONFIG_FB_LEO is not set
CONFIG_FB_PCI=y
CONFIG_FB_XVR500=y
CONFIG_FB_XVR2500=y
# CONFIG_MDA_CONSOLE is not set
# CONFIG_PROM_CONSOLE is not set
CONFIG_FONTS=y
# CONFIG_FONT_8x8 is not set
# CONFIG_FONT_8x16 is not set
# CONFIG_FONT_7x14 is not set
# CONFIG_FONT_10x18 is not set
# CONFIG_FONT_6x11 is not set
# CONFIG_FONT_PEARL_8x8 is not set
# CONFIG_FONT_ACORN_8x8 is not set
CONFIG_FONT_SUN8x16=y
CONFIG_FONT_SUN12x22=y
# CONFIG_SERIAL_8250 is not set
CONFIG_SERIAL_SUNZILOG=y
CONFIG_SERIAL_SUNZILOG_CONSOLE=y
CONFIG_SERIAL_SUNSU=y
CONFIG_SERIAL_SUNSU_CONSOLE=y
CONFIG_SERIAL_SUNSAB=y
CONFIG_SERIAL_SUNSAB_CONSOLE=y
CONFIG_SERIAL_SUNHV=y
CONFIG_SUN_OPENPROMIO=y
CONFIG_SUN_MOSTEK_RTC=y
CONFIG_OBP_FLASH=m
# CONFIG_SUN_VIDEOPIX is not set
# CONFIG_SUN_AURORA is not set
# CONFIG_SERIO_SERPORT is not set
CONFIG_BLK_DEV_FD=y
CONFIG_SUNVDC=m
CONFIG_SUNVNET=m
# CONFIG_BLK_DEV_AEC62XX is not set
# CONFIG_BLK_DEV_HPT34X is not set
# CONFIG_BLK_DEV_HPT366 is not set
# CONFIG_BLK_DEV_PDC202XX_OLD is not set
# CONFIG_BLK_DEV_PDC202XX_NEW is not set
# CONFIG_BLK_DEV_SIIMAGE is not set
# CONFIG_BLK_DEV_SLC90E66 is not set
# CONFIG_BLK_DEV_VIA82CXXX is not set
# CONFIG_SCSI_ADVANSYS is not set
# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_SCSI_EATA is not set
# CONFIG_SCSI_GDTH is not set
# CONFIG_SCSI_AIC7XXX is not set
# CONFIG_SCSI_AIC79XX is not set
# CONFIG_SCSI_MEGARAID is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
CONFIG_SCSI_QLOGICPTI=m
CONFIG_SCSI_SUNESP=m
CONFIG_FC4=m
CONFIG_FC4_SOC=m
CONFIG_FC4_SOCAL=m
CONFIG_SCSI_PLUTO=m
CONFIG_SCSI_FCAL=m
CONFIG_SUNLANCE=m
CONFIG_SUNBMAC=m
CONFIG_SUNQE=m
# CONFIG_DM9102 is not set
# CONFIG_HAMACHI is not set
# CONFIG_R8169 is not set
CONFIG_ATM_FORE200E_SBA=y
CONFIG_ATM_FORE200E_SBA_DEFAULT_FW=y
# CONFIG_ATM_FORE200E_SBA_FW is not set
CONFIG_ATM_FORE200E_USE_TASKLET=y
CONFIG_ATM_FORE200E_DEBUG=0
CONFIG_ATM_FORE200E_TX_RETRY=16
CONFIG_DRM_FFB=m
# CONFIG_DRM_TDFX is not set
# CONFIG_DRM_R128 is not set
# CONFIG_KEYBOARD_ATKBD is not set
CONFIG_KEYBOARD_SUNKBD=y
# CONFIG_INPUT_PCSPKR is not set
CONFIG_INPUT_SPARCSPKR=m
# CONFIG_SOUND_PRIME is not set
CONFIG_SND_BIT32_EMUL=m
CONFIG_SND_SUN_AMD7930=m
CONFIG_SND_SUN_CS4231=m
CONFIG_SND_SUN_DBRI=m
CONFIG_PARPORT_SUNBPP=m
CONFIG_LOGO_SUN_CLUT224=y
CONFIG_SUN_BPP=m
CONFIG_MTD_SUN_UFLASH=m
CONFIG_MYRI_SBUS=m
# CONFIG_SGI_IOC4 is not set
# CONFIG_VIDEO_ZORAN is not set
# CONFIG_VIDEO_STRADIS is not set
# CONFIG_IEEE1394_SBP2 is not set
# CONFIG_USB_NET2280 is not set
# CONFIG_DEBUG_SPINLOCK is not set
# CONFIG_DEBUG_BUGVERBOSE is not set
# CONFIG_DEBUG_DCFLUSH is not set
# CONFIG_DEBUG_BOOTMEM is not set
# CONFIG_DEBUG_PAGEALLOC is not set
# CONFIG_STACK_DEBUG is not set



--- NEW FILE config-sparc64-smp ---


--- NEW FILE config-x86-generic ---
CONFIG_UID16=y
CONFIG_X86_64_XEN is not set
#
# Processor type and features
#
#
# Enable summit and co via the generic arch
#
# CONFIG_X86_PC is not set
CONFIG_X86_GENERICARCH=y
# CONFIG_X86_ELAN is not set
# CONFIG_X86_VOYAGER is not set
# CONFIG_X86_NUMAQ is not set
# CONFIG_X86_SUMMIT is not set
# CONFIG_X86_BIGSMP is not set
# CONFIG_X86_VISWS is not set
# CONFIG_X86_ES7000 is not set
# CONFIG_M386 is not set
# CONFIG_M486 is not set
# CONFIG_M586 is not set
# CONFIG_M586TSC is not set
# CONFIG_M586MMX is not set
# CONFIG_M686 is not set
# CONFIG_MPENTIUMII is not set
# CONFIG_MPENTIUMIII is not set
# CONFIG_MPENTIUMM is not set
# CONFIG_MPENTIUM4 is not set
# CONFIG_MK6 is not set
# CONFIG_MK7 is not set
# CONFIG_MK8 is not set
# CONFIG_MCRUSOE is not set
# CONFIG_MWINCHIPC6 is not set
# CONFIG_MWINCHIP2 is not set
# CONFIG_MWINCHIP3D is not set
# CONFIG_MCYRIXIII is not set
# CONFIG_MVIAC3_2 is not set
CONFIG_SMP=y
CONFIG_NR_CPUS=32
CONFIG_X86_GENERIC=y
CONFIG_X86_CMPXCHG=y
CONFIG_X86_L1_CACHE_SHIFT=7
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
CONFIG_X86_PPRO_FENCE=y
CONFIG_X86_WP_WORKS_OK=y
CONFIG_X86_INVLPG=y
CONFIG_X86_BSWAP=y
CONFIG_X86_POPAD_OK=y
CONFIG_X86_GOOD_APIC=y
CONFIG_X86_INTEL_USERCOPY=y
CONFIG_X86_USE_PPRO_CHECKSUM=y
CONFIG_HPET=y
CONFIG_HPET_TIMER=y
CONFIG_HPET_EMULATE_RTC=y
# CONFIG_HPET_RTC_IRQ is not set
# CONFIG_HPET_MMAP is not set
CONFIG_X86_LOCAL_APIC=y
CONFIG_X86_IO_APIC=y
CONFIG_X86_TSC=y
CONFIG_X86_MCE=y
# CONFIG_X86_MCE_NONFATAL is not set
CONFIG_X86_MCE_P4THERMAL=y
CONFIG_TOSHIBA=m
CONFIG_I8K=m
CONFIG_SONY_LAPTOP=m
CONFIG_SONYPI=m
CONFIG_SONYPI_COMPAT=y
CONFIG_MICROCODE=m
CONFIG_X86_MSR=m
CONFIG_X86_CPUID=m
CONFIG_EDD=m
# CONFIG_NUMA is not set
CONFIG_HIGHMEM=y
CONFIG_HIGHPTE=y
# CONFIG_MATH_EMULATION is not set
CONFIG_MTRR=y
CONFIG_X86_PM_TIMER=y

CONFIG_EFI=y
CONFIG_EFI_VARS=y
CONFIG_EFI_PCDP=y
CONFIG_EFI_RTC=y

# CONFIG_PCI_GOBIOS is not set
# CONFIG_PCI_GODIRECT is not set
# CONFIG_PCI_GOMMCONFIG is not set
CONFIG_PCI_GOANY=y

#
# x86 specific drivers
#
CONFIG_PCMCIA_FDOMAIN=m
CONFIG_SCSI_FUTURE_DOMAIN=m
CONFIG_SCSI_ADVANSYS=m

CONFIG_SECCOMP=y

CONFIG_CAPI_EICON=y

CONFIG_I2O=m
CONFIG_I2O_BLOCK=m
CONFIG_I2O_SCSI=m
CONFIG_I2O_PROC=m
CONFIG_I2O_CONFIG=y
CONFIG_I2O_EXT_ADAPTEC=y
CONFIG_I2O_EXT_ADAPTEC_DMA64=y
CONFIG_I2O_CONFIG_OLD_IOCTL=y
CONFIG_I2O_BUS=m

#
# APM (Advanced Power Management) BIOS Support
#
CONFIG_APM=y
# CONFIG_APM_IGNORE_USER_SUSPEND is not set
# CONFIG_APM_DO_ENABLE is not set
CONFIG_APM_CPU_IDLE=y
# CONFIG_APM_DISPLAY_BLANK is not set
# CONFIG_APM_ALLOW_INTS is not set
# CONFIG_APM_REAL_MODE_POWER_OFF is not set

#
# Kernel debugging
#
CONFIG_X86_FIND_SMP_CONFIG=y
CONFIG_X86_MPPARSE=y

CONFIG_ACPI=y
CONFIG_ACPI_AC=m
# CONFIG_ACPI_ASUS is not set
CONFIG_ACPI_BATTERY=m
CONFIG_ACPI_BAY=m
CONFIG_ACPI_BLACKLIST_YEAR=1999
CONFIG_ACPI_BUTTON=m
CONFIG_ACPI_CONTAINER=m
CONFIG_ACPI_DOCK=y
CONFIG_ACPI_EC=y
CONFIG_ACPI_FAN=y
CONFIG_ACPI_NUMA=y
CONFIG_ACPI_PROCESSOR=y
CONFIG_ACPI_POWER=y
CONFIG_ACPI_PROCFS=y
CONFIG_ACPI_SBS=m
CONFIG_ACPI_SLEEP=y
# CONFIG_ACPI_PROCFS_SLEEP is not set
CONFIG_ACPI_SYSTEM=y
CONFIG_ACPI_THERMAL=y
CONFIG_ACPI_TOSHIBA=m
CONFIG_ACPI_VIDEO=m
# Disable in F9.
CONFIG_ACPI_PROC_EVENT=y
CONFIG_PNPACPI=y

CONFIG_ASUS_LAPTOP=m

#
# CPUFreq processor drivers
#
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_DEBUG=y
# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=m
CONFIG_CPU_FREQ_GOV_USERSPACE=m
CONFIG_CPU_FREQ_GOV_ONDEMAND=m
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
CONFIG_CPU_FREQ_TABLE=y
CONFIG_CPU_FREQ_STAT=m
CONFIG_CPU_FREQ_STAT_DETAILS=y

CONFIG_X86_ACPI_CPUFREQ=m
# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set
# CONFIG_X86_POWERNOW_K6 is not set
CONFIG_X86_POWERNOW_K7=y
CONFIG_X86_POWERNOW_K8=y
CONFIG_X86_POWERNOW_K8_ACPI=y
# CONFIG_X86_GX_SUSPMOD is not set
# CONFIG_X86_SPEEDSTEP_CENTRINO is not set
CONFIG_X86_SPEEDSTEP_ICH=y
CONFIG_X86_SPEEDSTEP_SMI=y
CONFIG_X86_SPEEDSTEP_LIB=y
# CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK is not set
CONFIG_X86_P4_CLOCKMOD=m
CONFIG_X86_LONGRUN=y
# CONFIG_X86_LONGHAUL is not set
# CONFIG_X86_CPUFREQ_NFORCE2 is not set
CONFIG_X86_E_POWERSAVER=y

CONFIG_X86_SMP=y
CONFIG_X86_HT=y
CONFIG_X86_BIOS_REBOOT=y
CONFIG_X86_TRAMPOLINE=y

#
# various x86 specific drivers
#
CONFIG_NVRAM=y
CONFIG_IBM_ASM=m
CONFIG_CRYPTO_AES_586=m
CONFIG_CRYPTO_TWOFISH_586=m
# CONFIG_CRYPTO_DEV_PADLOCK is not set
# CONFIG_CRYPTO_DEV_PADLOCK_AES is not set
# CONFIG_CRYPTO_DEV_PADLOCK_SHA is not set

CONFIG_GENERIC_ISA_DMA=y
CONFIG_SCHED_SMT=y
# CONFIG_IRQBALANCE is not set
CONFIG_SUSPEND=y
CONFIG_HIBERNATION=y
CONFIG_PM_STD_PARTITION=""

CONFIG_DEBUG_RODATA=y
# CONFIG_DEBUG_STACKOVERFLOW is not set
CONFIG_4KSTACKS=y
CONFIG_DEBUG_NMI_TIMEOUT=5

# CONFIG_DEBUG_PAGEALLOC is not set

CONFIG_PCI_DIRECT=y
CONFIG_PCI_MMCONFIG=y
CONFIG_PCI_BIOS=y

CONFIG_HOTPLUG_PCI=y
CONFIG_HOTPLUG_PCI_COMPAQ=m
# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set
CONFIG_HOTPLUG_PCI_IBM=m

# CONFIG_HOTPLUG_PCI_CPCI is not set
CONFIG_HOTPLUG_PCI_PCIE=m
# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set
# SHPC has half-arsed PCI probing, which makes it load on too many systems
# CONFIG_HOTPLUG_PCI_SHPC is not set
CONFIG_PM=y

CONFIG_IEEE80211=m
# CONFIG_IEEE80211_DEBUG is not set
CONFIG_IEEE80211_CRYPT_CCMP=m
CONFIG_IEEE80211_CRYPT_TKIP=m
CONFIG_IPW2100=m
CONFIG_IPW2100_MONITOR=y
CONFIG_IPW2200=m
CONFIG_IPW2200_MONITOR=y
CONFIG_IPW2200_RADIOTAP=y
CONFIG_IPW2200_PROMISCUOUS=y
CONFIG_IPW2200_QOS=y

CONFIG_BLK_DEV_AMD74XX=y

CONFIG_I2C_ALI1535=m
CONFIG_I2C_ALI15X3=m
CONFIG_I2C_ALI1563=m
CONFIG_I2C_AMD756=m
CONFIG_I2C_AMD756_S4882=m
CONFIG_I2C_AMD8111=m
CONFIG_I2C_I801=m
CONFIG_I2C_I810=m
CONFIG_I2C_ISA=m
CONFIG_I2C_NFORCE2=m
CONFIG_I2C_PIIX4=m
CONFIG_I2C_PROSAVAGE=m
CONFIG_I2C_SAVAGE4=m
CONFIG_I2C_SIS5595=m
CONFIG_I2C_SIS630=m
CONFIG_I2C_SIS96X=m
CONFIG_I2C_VIA=m
CONFIG_I2C_VIAPRO=m
CONFIG_I2C_VOODOO3=m

# CONFIG_X86_REBOOTFIXUPS is not set

CONFIG_DELL_RBU=m
CONFIG_DCDBAS=m

CONFIG_PC8736x_GPIO=m
# CONFIG_NSC_GPIO is not set
CONFIG_CS5535_GPIO=m

CONFIG_EDAC=y
# CONFIG_EDAC_DEBUG is not set
CONFIG_EDAC_MM_EDAC=m
CONFIG_EDAC_AMD76X=m
CONFIG_EDAC_E7XXX=m
CONFIG_EDAC_E752X=m
CONFIG_EDAC_I82860=m
CONFIG_EDAC_I82875P=m
CONFIG_EDAC_I82975X=m
CONFIG_EDAC_I3000=m
CONFIG_EDAC_I5000=m
CONFIG_EDAC_K8=m
CONFIG_EDAC_R82600=m

CONFIG_SCHED_MC=y

CONFIG_SND_ES18XX=m

CONFIG_TCG_INFINEON=m

CONFIG_HW_RANDOM_INTEL=m
CONFIG_HW_RANDOM_AMD=m
CONFIG_HW_RANDOM_GEODE=m
CONFIG_HW_RANDOM_VIA=m

CONFIG_USB_HIDINPUT_POWERBOOK=y

# CONFIG_COMPAT_VDSO is not set

# CONFIG_SGI_IOC4 is not set
CONFIG_MSI_LAPTOP=m

# CONFIG_SMSC37B787_WDT is not set
CONFIG_W83697HF_WDT=m

CONFIG_PARAVIRT=y

CONFIG_RELOCATABLE=y
CONFIG_PHYSICAL_ALIGN=0x400000
CONFIG_PHYSICAL_START=0x1000000
CONFIG_CRASH_DUMP=y
CONFIG_PROC_VMCORE=y

CONFIG_CRYPTO_DEV_GEODE=m

CONFIG_VIDEO_CAFE_CCIC=m

CONFIG_KVM=m
CONFIG_KVM_INTEL=m
CONFIG_KVM_AMD=m

CONFIG_MTD_ESB2ROM=m
CONFIG_MTD_CK804XROM=m
CONFIG_MTD_NAND_CAFE=m

CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y

CONFIG_THINKPAD_ACPI=m
# CONFIG_THINKPAD_ACPI_DEBUG is not set
CONFIG_THINKPAD_ACPI_BAY=y

CONFIG_MACINTOSH_DRIVERS=y

CONFIG_DMIID=y

CONFIG_VIRTUALIZATION=y
CONFIG_VMI=y
CONFIG_LGUEST=m
# CONFIG_XEN is not set
# CONFIG_HVC_XEN is not set


--- NEW FILE config-x86_64-generic ---
CONFIG_UID16=y
# CONFIG_X86_64_XEN is not set
# CONFIG_MK8 is not set
# CONFIG_MPSC is not set
CONFIG_GENERIC_CPU=y
CONFIG_X86_MSR=y
CONFIG_X86_CPUID=y
CONFIG_MTRR=y
CONFIG_NUMA=y
CONFIG_K8_NUMA=y
CONFIG_X86_64_ACPI_NUMA=y
# CONFIG_NUMA_EMU is not set
CONFIG_NR_CPUS=64
CONFIG_X86_POWERNOW_K8=y
CONFIG_IA32_EMULATION=y
# CONFIG_IA32_AOUT is not set
# CONFIG_IOMMU_DEBUG is not set
CONFIG_DEBUG_RODATA=y
CONFIG_MICROCODE=m
CONFIG_SWIOTLB=y
CONFIG_CALGARY_IOMMU=y
CONFIG_CALGARY_IOMMU_ENABLED_BY_DEFAULT=y
CONFIG_X86_PM_TIMER=y
CONFIG_EDD=m
CONFIG_PCI_BIOS=y
CONFIG_PCI_MMCONFIG=y

CONFIG_I2O=m
CONFIG_I2O_BLOCK=m
CONFIG_I2O_SCSI=m
CONFIG_I2O_PROC=m
CONFIG_I2O_CONFIG=y
CONFIG_I2O_EXT_ADAPTEC=y
CONFIG_I2O_EXT_ADAPTEC_DMA64=y
CONFIG_I2O_CONFIG_OLD_IOCTL=y
CONFIG_I2O_BUS=m

CONFIG_SECCOMP=y

CONFIG_GENERIC_ISA_DMA=y
CONFIG_SCHED_SMT=y
CONFIG_SUSPEND=y
CONFIG_HIBERNATION=y
CONFIG_PM_STD_PARTITION=""

CONFIG_CPU_FREQ=y
# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=m
CONFIG_CPU_FREQ_GOV_USERSPACE=m
CONFIG_CPU_FREQ_GOV_ONDEMAND=m
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
CONFIG_CPU_FREQ_TABLE=y
CONFIG_CPU_FREQ_DEBUG=y
# CONFIG_X86_SPEEDSTEP_CENTRINO is not set
CONFIG_X86_ACPI_CPUFREQ=m
# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set
CONFIG_CPU_FREQ_STAT=m
CONFIG_CPU_FREQ_STAT_DETAILS=y

CONFIG_ACPI=y
CONFIG_ACPI_AC=m
# CONFIG_ACPI_ASUS is not set
CONFIG_ACPI_BATTERY=m
CONFIG_ACPI_BAY=m
CONFIG_ACPI_BLACKLIST_YEAR=0
CONFIG_ACPI_BUTTON=m
CONFIG_ACPI_CONTAINER=m
CONFIG_ACPI_DOCK=y
CONFIG_ACPI_EC=y
CONFIG_ACPI_FAN=y
CONFIG_ACPI_HOTPLUG_MEMORY=m
CONFIG_ACPI_NUMA=y
CONFIG_ACPI_PROCESSOR=y
CONFIG_ACPI_PROCFS=y
CONFIG_ACPI_SBS=m
CONFIG_ACPI_SLEEP=y
# CONFIG_ACPI_PROCFS_SLEEP is not set
CONFIG_ACPI_THERMAL=y
CONFIG_ACPI_TOSHIBA=m
CONFIG_ACPI_POWER=y
CONFIG_ACPI_SYSTEM=y
CONFIG_ACPI_VIDEO=m
# Disable in F9.
CONFIG_ACPI_PROC_EVENT=y

CONFIG_ASUS_LAPTOP=m
CONFIG_MSI_LAPTOP=m
CONFIG_SONY_LAPTOP=m
CONFIG_SONYPI_COMPAT=y

CONFIG_THINKPAD_ACPI=m
# CONFIG_THINKPAD_ACPI_DEBUG is not set
CONFIG_THINKPAD_ACPI_BAY=y

CONFIG_HOTPLUG_PCI=y
CONFIG_HOTPLUG_PCI_COMPAQ=m
# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set
CONFIG_HOTPLUG_PCI_IBM=m
# CONFIG_HOTPLUG_PCI_CPCI is not set
CONFIG_HOTPLUG_PCI_PCIE=m
# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set
# SHPC has half-arsed PCI probing, which makes it load on too many systems
CONFIG_HOTPLUG_PCI_SHPC=m
CONFIG_HPET=y
# CONFIG_HPET_MMAP is not set
# CONFIG_HPET_RTC_IRQ is not set
CONFIG_HPET_EMULATE_RTC=y
CONFIG_PM=y

CONFIG_IEEE80211=m
# CONFIG_IEEE80211_DEBUG is not set
CONFIG_IEEE80211_CRYPT_CCMP=m
CONFIG_IEEE80211_CRYPT_TKIP=m
CONFIG_IPW2100=m
CONFIG_IPW2100_MONITOR=y
CONFIG_IPW2200=m
CONFIG_IPW2200_MONITOR=y
CONFIG_IPW2200_RADIOTAP=y
CONFIG_IPW2200_PROMISCUOUS=y
CONFIG_IPW2200_QOS=y

CONFIG_PNP=y
CONFIG_PNPACPI=y

CONFIG_BLK_DEV_AMD74XX=y
CONFIG_CRYPTO_DEV_PADLOCK=m
CONFIG_CRYPTO_DEV_PADLOCK_AES=y
CONFIG_CRYPTO_AES_X86_64=m
CONFIG_CRYPTO_TWOFISH_X86_64=m

CONFIG_X86_MCE_INTEL=y
CONFIG_X86_MCE_AMD=y

# CONFIG_I2C_ALI1535 is not set
# CONFIG_I2C_ALI1563 is not set
# CONFIG_I2C_ALI15X3 is not set
CONFIG_I2C_AMD756=m
CONFIG_I2C_AMD756_S4882=m
CONFIG_I2C_AMD8111=m
CONFIG_I2C_I801=m
# CONFIG_I2C_I810 is not set
# CONFIG_I2C_PIIX4 is not set
# CONFIG_I2C_SIS5595 is not set
# CONFIG_I2C_SIS630 is not set
CONFIG_I2C_SIS96X=m
CONFIG_I2C_VIA=m
CONFIG_I2C_VIAPRO=m
CONFIG_I2C_ISA=m

CONFIG_DELL_RBU=m
CONFIG_DCDBAS=m

CONFIG_NVRAM=y

CONFIG_EDAC=y
# CONFIG_EDAC_DEBUG is not set
CONFIG_EDAC_MM_EDAC=m
CONFIG_EDAC_AMD76X=m
CONFIG_EDAC_E7XXX=m
CONFIG_EDAC_E752X=m
CONFIG_EDAC_I5000=m
CONFIG_EDAC_I82875P=m
CONFIG_EDAC_I82860=m
CONFIG_EDAC_I82975X=m
CONFIG_EDAC_K8=m
CONFIG_EDAC_R82600=m

CONFIG_SCHED_MC=y

CONFIG_TCG_INFINEON=m

CONFIG_HW_RANDOM_INTEL=m
CONFIG_HW_RANDOM_AMD=m
CONFIG_HW_RANDOM_VIA=m

# CONFIG_HW_RANDOM_GEODE is not set

CONFIG_DEBUG_STACKOVERFLOW=y
CONFIG_DEBUG_NMI_TIMEOUT=5

CONFIG_PC8736x_GPIO=m

# CONFIG_DISCONTIGMEM_MANUAL is not set
CONFIG_SPARSEMEM_MANUAL=y
CONFIG_SPARSEMEM=y
CONFIG_HAVE_MEMORY_PRESENT=y
CONFIG_SPARSEMEM_EXTREME=y

# CONFIG_BLK_DEV_CMD640 is not set
# CONFIG_BLK_DEV_RZ1000 is not set
# CONFIG_BLK_DEV_TRIFLEX is not set
# CONFIG_BLK_DEV_CS5520 is not set
# CONFIG_BLK_DEV_CS5530 is not set
# CONFIG_BLK_DEV_CS5535 is not set

CONFIG_CC_STACKPROTECTOR=y
# CONFIG_CC_STACKPROTECTOR_ALL is not set

CONFIG_SGI_IOC4=m
# CONFIG_SGI_IOC4 is not set

# CONFIG_SMSC37B787_WDT is not set
CONFIG_W83697HF_WDT=m

CONFIG_VIDEO_CAFE_CCIC=m

CONFIG_KVM=m
CONFIG_KVM_INTEL=m
CONFIG_KVM_AMD=m

CONFIG_MTD_ESB2ROM=m
CONFIG_MTD_CK804XROM=m

CONFIG_RELOCATABLE=y
CONFIG_MACINTOSH_DRIVERS=y

CONFIG_CRASH_DUMP=y
CONFIG_PHYSICAL_START=0x1000000
CONFIG_PROC_VMCORE=y

CONFIG_DMIID=y

CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y

CONFIG_VIRTUALIZATION=y


--- NEW FILE config-xen-generic ---

CONFIG_XEN_PCIDEV_FRONTEND=y
# CONFIG_XEN_PCIDEV_FE_DEBUG is not set


CONFIG_XEN=y
CONFIG_XEN_INTERFACE_VERSION=0x00030202

#
# XEN
#
CONFIG_XEN_PRIVILEGED_GUEST=y
# CONFIG_XEN_UNPRIVILEGED_GUEST is not set
CONFIG_XEN_PRIVCMD=y
CONFIG_XEN_XENBUS_DEV=y
CONFIG_XEN_BACKEND=y
CONFIG_XEN_BLKDEV_BACKEND=m
CONFIG_XEN_BLKDEV_TAP=m
CONFIG_XEN_NETDEV_BACKEND=m
# CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
CONFIG_XEN_NETDEV_LOOPBACK=m
CONFIG_XEN_PCIDEV_BACKEND=m
CONFIG_XEN_PCIDEV_BACKEND_VPCI=y
# CONFIG_XEN_PCIDEV_BACKEND_PASS is not set
# CONFIG_XEN_PCIDEV_BE_DEBUG is not set
# CONFIG_XEN_TPMDEV_BACKEND is not set
CONFIG_XEN_BLKDEV_FRONTEND=m
CONFIG_XEN_NETDEV_FRONTEND=m
CONFIG_XEN_FRAMEBUFFER=y
CONFIG_XEN_KEYBOARD=y
CONFIG_XEN_SCRUB_PAGES=y
# CONFIG_XEN_DISABLE_SERIAL is not set
CONFIG_XEN_SYSFS=y
CONFIG_XEN_COMPAT_030002_AND_LATER=y
# CONFIG_XEN_COMPAT_LATEST_ONLY is not set
CONFIG_XEN_COMPAT_030002=y
CONFIG_HAVE_ARCH_ALLOC_SKB=y
CONFIG_HAVE_ARCH_DEV_ALLOC_SKB=y
CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y
CONFIG_NO_IDLE_HZ=y
CONFIG_XEN_UTIL=y
CONFIG_XEN_BALLOON=y
CONFIG_XEN_DEVMEM=y
CONFIG_XEN_SKBUFF=y
CONFIG_XEN_REBOOT=y
CONFIG_XEN_SMPBOOT=y

# Microcode needs sys_mlock & sys_munlock that are not exported
# it needs to be compiled in
# FIXME: This isn't going to work as of .19, due to firmware loader
# not being available that early in boot. This will cause long pauses during boot.
CONFIG_MICROCODE=y

# TPM is not working, somebody have to merge the xen bits
# CONFIG_TCG_TPM is not set

# frequency scaling really needs to be done in the hypervisor instead
# CONFIG_CPU_FREQ is not set

# need to set the serial stuff up like this or serial console doesn't
# work quite right in dom0.  ick.
CONFIG_SERIAL_8250=m
# CONFIG_SERIAL_8250_CONSOLE is not set

# CONFIG_HZ_1000 is not set
CONFIG_HZ_250=y

# xen and kvm conflict
# CONFIG_KVM is not set
# CONFIG_KVM_INTEL is not set
# CONFIG_KVM_AMD is not set



--- NEW FILE config-xen-ia64 ---
# CONFIG_IA64_GENERIC is not set
CONFIG_IA64_DIG=y
# CONFIG_DISCONTIGMEM_MANUAL is not set
# CONFIG_SPARSEMEM_MANUAL is not set
CONFIG_FLATMEM_MANUAL=y
CONFIG_FORCE_MAX_ZONEORDER=11

CONFIG_XEN=y
CONFIG_XEN_IA64_DOM0_VP=y
CONFIG_XEN_DISABLE_SERIAL=y
# CONFIG_XEN_PCIDEV_BACKEND is not set
# CONFIG_XEN_PCIDEV_BACKEND_VPCI is not set
# CONFIG_XEN_PCIDEV_BACKEND_PASS is not set
# CONFIG_XEN_PCIDEV_BE_DEBUG is not set
# CONFIG_XEN_TPMDEV_BACKEND is not set

# internal #defines conflict with xen-ia64
# CONFIG_FB_NEOMAGIC is not set

# don't work, missing symbols
# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set

# Missing function not exported
# CONFIG_XEN_BLKDEV_TAP is not set


--- NEW FILE config-xen-x86 ---

# CONFIG_X86_PC is not set
CONFIG_X86_XEN=y
# CONFIG_X86_GENERICARCH is not set


--- NEW FILE config-xen-x86_64 ---
# things we want different from i686 xen

CONFIG_X86_64=y

# CONFIG_X86_XEN is not set
CONFIG_X86_64_XEN=y

CONFIG_GENERIC_CPU=y

drm-mm-git.patch:

--- NEW FILE drm-mm-git.patch ---
diff --git a/drivers/char/drm/drm.h b/drivers/char/drm/drm.h
index 2d6f2d0..82fb3d0 100644
--- a/drivers/char/drm/drm.h
+++ b/drivers/char/drm/drm.h
@@ -63,27 +63,9 @@
 #define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size)
 #endif
 
-#define XFREE86_VERSION(major,minor,patch,snap) \
-		((major << 16) | (minor << 8) | patch)
-
-#ifndef CONFIG_XFREE86_VERSION
-#define CONFIG_XFREE86_VERSION XFREE86_VERSION(4,1,0,0)
-#endif
-
-#if CONFIG_XFREE86_VERSION < XFREE86_VERSION(4,1,0,0)
-#define DRM_PROC_DEVICES "/proc/devices"
-#define DRM_PROC_MISC	 "/proc/misc"
-#define DRM_PROC_DRM	 "/proc/drm"
-#define DRM_DEV_DRM	 "/dev/drm"
-#define DRM_DEV_MODE	 (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP)
-#define DRM_DEV_UID	 0
-#define DRM_DEV_GID	 0
-#endif
-
-#if CONFIG_XFREE86_VERSION >= XFREE86_VERSION(4,1,0,0)
 #define DRM_MAJOR       226
 #define DRM_MAX_MINOR   15
-#endif
+
 #define DRM_NAME	"drm"	  /**< Name in kernel, /dev, and /proc */
 #define DRM_MIN_ORDER	5	  /**< At least 2^5 bytes = 32 bytes */
 #define DRM_MAX_ORDER	22	  /**< Up to 2^22 bytes = 4MB */
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h
index 0df87fc..9dd0760 100644
--- a/drivers/char/drm/drmP.h
+++ b/drivers/char/drm/drmP.h
@@ -80,6 +80,9 @@
 #define __OS_HAS_AGP (defined(CONFIG_AGP) || (defined(CONFIG_AGP_MODULE) && defined(MODULE)))
 #define __OS_HAS_MTRR (defined(CONFIG_MTRR))
 
+struct drm_file;
+struct drm_device;
+
 #include "drm_os_linux.h"
 #include "drm_hashtab.h"
 
@@ -231,12 +234,13 @@
  * \param dev DRM device.
  * \param filp file pointer of the caller.
  */
-#define LOCK_TEST_WITH_RETURN( dev, filp )				\
+#define LOCK_TEST_WITH_RETURN( dev, file_priv )				\
 do {									\
 	if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||		\
-	     dev->lock.filp != filp ) {				\
-		DRM_ERROR( "%s called without lock held\n",		\
-			   __FUNCTION__ );				\
+	     dev->lock.file_priv != file_priv )	{			\
+		DRM_ERROR( "%s called without lock held, held  %d owner %p %p\n",\
+			   __FUNCTION__, _DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ),\
+			   dev->lock.file_priv, file_priv );		\
 		return -EINVAL;						\
 	}								\
 } while (0)
@@ -257,12 +261,12 @@ do {									\
  * Ioctl function type.
  *
  * \param inode device inode.
- * \param filp file pointer.
+ * \param file_priv DRM file private pointer.
  * \param cmd command.
  * \param arg argument.
  */
-typedef int drm_ioctl_t(struct inode *inode, struct file *filp,
-			unsigned int cmd, unsigned long arg);
+typedef int drm_ioctl_t(struct drm_device *dev, void *data,
+			struct drm_file *file_priv);
 
 typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd,
 			       unsigned long arg);
@@ -271,10 +275,18 @@ typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd,
 #define	DRM_MASTER	0x2
 #define DRM_ROOT_ONLY	0x4
 
-typedef struct drm_ioctl_desc {
+struct drm_ioctl_desc {
+	unsigned int cmd;
 	drm_ioctl_t *func;
 	int flags;
-} drm_ioctl_desc_t;
+};
+
+/**
+ * Creates a driver or general drm_ioctl_desc array entry for the given
+ * ioctl, for use by drm_ioctl().
+ */
+#define DRM_IOCTL_DEF(ioctl, func, flags) \
+	[DRM_IOCTL_NR(ioctl)] = {ioctl, func, flags}
 
 struct drm_magic_entry {
 	struct list_head head;
@@ -304,7 +316,7 @@ struct drm_buf {
 	__volatile__ int waiting;      /**< On kernel DMA queue */
 	__volatile__ int pending;      /**< On hardware DMA queue */
 	wait_queue_head_t dma_wait;    /**< Processes waiting */
-	struct file *filp;	       /**< Pointer to holding file descr */
+	struct drm_file *file_priv;    /**< Private of holding file descr */
 	int context;		       /**< Kernel queue for this buffer */
 	int while_locked;	       /**< Dispatch this buffer while locked */
 	enum {
@@ -377,6 +389,7 @@ struct drm_file {
 	int remove_auth_on_close;
 	unsigned long lock_count;
 	void *driver_priv;
+	struct file *filp;
 };
 
 /** Wait queue */
@@ -403,7 +416,7 @@ struct drm_queue {
  */
 struct drm_lock_data {
 	struct drm_hw_lock *hw_lock;	/**< Hardware lock */
-	struct file *filp;		/**< File descr of lock holder (0=kernel) */
+	struct drm_file *file_priv;	/**< File descr of lock holder (0=kernel) */
 	wait_queue_head_t lock_queue;	/**< Queue of blocked processes */
 	unsigned long lock_time;	/**< Time of last lock in jiffies */
 	spinlock_t spinlock;
@@ -552,11 +565,11 @@ struct drm_driver {
 	int (*load) (struct drm_device *, unsigned long flags);
 	int (*firstopen) (struct drm_device *);
 	int (*open) (struct drm_device *, struct drm_file *);
-	void (*preclose) (struct drm_device *, struct file * filp);
+	void (*preclose) (struct drm_device *, struct drm_file *file_priv);
 	void (*postclose) (struct drm_device *, struct drm_file *);
 	void (*lastclose) (struct drm_device *);
 	int (*unload) (struct drm_device *);
-	int (*dma_ioctl) (DRM_IOCTL_ARGS);
+	int (*dma_ioctl) (struct drm_device *dev, void *data, struct drm_file *file_priv);
 	void (*dma_ready) (struct drm_device *);
 	int (*dma_quiescent) (struct drm_device *);
 	int (*context_ctor) (struct drm_device *dev, int context);
@@ -587,11 +600,12 @@ struct drm_driver {
 	void (*irq_preinstall) (struct drm_device *dev);
 	void (*irq_postinstall) (struct drm_device *dev);
 	void (*irq_uninstall) (struct drm_device *dev);
-	void (*reclaim_buffers) (struct drm_device *dev, struct file * filp);
+	void (*reclaim_buffers) (struct drm_device *dev,
+				 struct drm_file * file_priv);
 	void (*reclaim_buffers_locked) (struct drm_device *dev,
-					struct file *filp);
+					struct drm_file *file_priv);
 	void (*reclaim_buffers_idlelocked) (struct drm_device *dev,
-					struct file * filp);
+					    struct drm_file *file_priv);
 	unsigned long (*get_map_ofs) (struct drm_map * map);
 	unsigned long (*get_reg_ofs) (struct drm_device *dev);
 	void (*set_version) (struct drm_device *dev,
@@ -606,7 +620,7 @@ struct drm_driver {
 
 	u32 driver_features;
 	int dev_priv_size;
-	drm_ioctl_desc_t *ioctls;
+	struct drm_ioctl_desc *ioctls;
 	int num_ioctls;
 	struct file_operations fops;
 	struct pci_driver pci_driver;
@@ -850,70 +864,70 @@ extern int drm_bind_agp(DRM_AGP_MEM * handle, unsigned int start);
 extern int drm_unbind_agp(DRM_AGP_MEM * handle);
 
 				/* Misc. IOCTL support (drm_ioctl.h) */
-extern int drm_irq_by_busid(struct inode *inode, struct file *filp,
-			    unsigned int cmd, unsigned long arg);
-extern int drm_getunique(struct inode *inode, struct file *filp,
-			 unsigned int cmd, unsigned long arg);
-extern int drm_setunique(struct inode *inode, struct file *filp,
-			 unsigned int cmd, unsigned long arg);
-extern int drm_getmap(struct inode *inode, struct file *filp,
-		      unsigned int cmd, unsigned long arg);
-extern int drm_getclient(struct inode *inode, struct file *filp,
-			 unsigned int cmd, unsigned long arg);
-extern int drm_getstats(struct inode *inode, struct file *filp,
-			unsigned int cmd, unsigned long arg);
-extern int drm_setversion(struct inode *inode, struct file *filp,
-			  unsigned int cmd, unsigned long arg);
-extern int drm_noop(struct inode *inode, struct file *filp,
-		    unsigned int cmd, unsigned long arg);
+extern int drm_irq_by_busid(struct drm_device *dev, void *data,
+			    struct drm_file *file_priv);
+extern int drm_getunique(struct drm_device *dev, void *data,
+			 struct drm_file *file_priv);
+extern int drm_setunique(struct drm_device *dev, void *data,
+			 struct drm_file *file_priv);
+extern int drm_getmap(struct drm_device *dev, void *data,
+		      struct drm_file *file_priv);
+extern int drm_getclient(struct drm_device *dev, void *data,
+			 struct drm_file *file_priv);
+extern int drm_getstats(struct drm_device *dev, void *data,
+			struct drm_file *file_priv);
[...12031 lines suppressed...]
-	dev_priv->vram_offset = fb.offset;
+	dev_priv->vram_offset = fb->offset;
 
 	mutex_unlock(&dev->struct_mutex);
-	DRM_DEBUG("offset = %u, size = %u", fb.offset, fb.size);
+	DRM_DEBUG("offset = %u, size = %u", fb->offset, fb->size);
 
 	return 0;
 
@@ -121,80 +115,71 @@ void via_lastclose(struct drm_device *dev)
 	mutex_unlock(&dev->struct_mutex);
 }	
 
-int via_mem_alloc(DRM_IOCTL_ARGS)
+int via_mem_alloc(struct drm_device *dev, void *data,
+		  struct drm_file *file_priv)
 {
-	DRM_DEVICE;
-
-	drm_via_mem_t mem;
+	drm_via_mem_t *mem = data;
 	int retval = 0;
 	struct drm_memblock_item *item;
 	drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
 	unsigned long tmpSize;
 
-	DRM_COPY_FROM_USER_IOCTL(mem, (drm_via_mem_t __user *) data,
-				 sizeof(mem));
-
-	if (mem.type > VIA_MEM_AGP) {
+	if (mem->type > VIA_MEM_AGP) {
 		DRM_ERROR("Unknown memory type allocation\n");
-		return DRM_ERR(EINVAL);
+		return -EINVAL;
 	}
 	mutex_lock(&dev->struct_mutex);
-	if (0 == ((mem.type == VIA_MEM_VIDEO) ? dev_priv->vram_initialized :
+	if (0 == ((mem->type == VIA_MEM_VIDEO) ? dev_priv->vram_initialized :
 		      dev_priv->agp_initialized)) {
 		DRM_ERROR
 		    ("Attempt to allocate from uninitialized memory manager.\n");
 		mutex_unlock(&dev->struct_mutex);
-		return DRM_ERR(EINVAL);
+		return -EINVAL;
 	}
 
-	tmpSize = (mem.size + VIA_MM_ALIGN_MASK) >> VIA_MM_ALIGN_SHIFT;
-	item = drm_sman_alloc(&dev_priv->sman, mem.type, tmpSize, 0,
-			      (unsigned long)priv);
+	tmpSize = (mem->size + VIA_MM_ALIGN_MASK) >> VIA_MM_ALIGN_SHIFT;
+	item = drm_sman_alloc(&dev_priv->sman, mem->type, tmpSize, 0,
+			      (unsigned long)file_priv);
 	mutex_unlock(&dev->struct_mutex);
 	if (item) {
-		mem.offset = ((mem.type == VIA_MEM_VIDEO) ?
+		mem->offset = ((mem->type == VIA_MEM_VIDEO) ?
 			      dev_priv->vram_offset : dev_priv->agp_offset) +
 		    (item->mm->
 		     offset(item->mm, item->mm_info) << VIA_MM_ALIGN_SHIFT);
-		mem.index = item->user_hash.key;
+		mem->index = item->user_hash.key;
 	} else {
-		mem.offset = 0;
-		mem.size = 0;
-		mem.index = 0;
+		mem->offset = 0;
+		mem->size = 0;
+		mem->index = 0;
 		DRM_DEBUG("Video memory allocation failed\n");
-		retval = DRM_ERR(ENOMEM);
+		retval = -ENOMEM;
 	}
-	DRM_COPY_TO_USER_IOCTL((drm_via_mem_t __user *) data, mem, sizeof(mem));
 
 	return retval;
 }
 
-int via_mem_free(DRM_IOCTL_ARGS)
+int via_mem_free(struct drm_device *dev, void *data, struct drm_file *file_priv)
 {
-	DRM_DEVICE;
 	drm_via_private_t *dev_priv = dev->dev_private;
-	drm_via_mem_t mem;
+	drm_via_mem_t *mem = data;
 	int ret;
 
-	DRM_COPY_FROM_USER_IOCTL(mem, (drm_via_mem_t __user *) data,
-				 sizeof(mem));
-
 	mutex_lock(&dev->struct_mutex);
-	ret = drm_sman_free_key(&dev_priv->sman, mem.index);
+	ret = drm_sman_free_key(&dev_priv->sman, mem->index);
 	mutex_unlock(&dev->struct_mutex);
-	DRM_DEBUG("free = 0x%lx\n", mem.index);
+	DRM_DEBUG("free = 0x%lx\n", mem->index);
 
 	return ret;
 }
 
 
-void via_reclaim_buffers_locked(struct drm_device * dev, struct file *filp)
+void via_reclaim_buffers_locked(struct drm_device * dev,
+				struct drm_file *file_priv)
 {
 	drm_via_private_t *dev_priv = dev->dev_private;
-	struct drm_file *priv = filp->private_data;
 
 	mutex_lock(&dev->struct_mutex);
-	if (drm_sman_owner_clean(&dev_priv->sman, (unsigned long)priv)) {
+	if (drm_sman_owner_clean(&dev_priv->sman, (unsigned long)file_priv)) {
 		mutex_unlock(&dev->struct_mutex);
 		return;
 	}
@@ -203,7 +188,7 @@ void via_reclaim_buffers_locked(struct drm_device * dev, struct file *filp)
 		dev->driver->dma_quiescent(dev);
 	}
 
-	drm_sman_owner_cleanup(&dev_priv->sman, (unsigned long)priv);
+	drm_sman_owner_cleanup(&dev_priv->sman, (unsigned long)file_priv);
 	mutex_unlock(&dev->struct_mutex);
 	return;
 }
diff --git a/drivers/char/drm/via_verifier.c b/drivers/char/drm/via_verifier.c
index 832d483..46a5791 100644
--- a/drivers/char/drm/via_verifier.c
+++ b/drivers/char/drm/via_verifier.c
@@ -1026,12 +1026,12 @@ via_verify_command_stream(const uint32_t * buf, unsigned int size,
 		case state_error:
 		default:
 			*hc_state = saved_state;
-			return DRM_ERR(EINVAL);
+			return -EINVAL;
 		}
 	}
 	if (state == state_error) {
 		*hc_state = saved_state;
-		return DRM_ERR(EINVAL);
+		return -EINVAL;
 	}
 	return 0;
 }
@@ -1082,11 +1082,11 @@ via_parse_command_stream(struct drm_device * dev, const uint32_t * buf,
 			break;
 		case state_error:
 		default:
-			return DRM_ERR(EINVAL);
+			return -EINVAL;
 		}
 	}
 	if (state == state_error) {
-		return DRM_ERR(EINVAL);
+		return -EINVAL;
 	}
 	return 0;
 }
diff --git a/drivers/char/drm/via_video.c b/drivers/char/drm/via_video.c
index 300ac61..c15e75b 100644
--- a/drivers/char/drm/via_video.c
+++ b/drivers/char/drm/via_video.c
@@ -65,10 +65,9 @@ void via_release_futex(drm_via_private_t * dev_priv, int context)
 	}
 }
 
-int via_decoder_futex(DRM_IOCTL_ARGS)
+int via_decoder_futex(struct drm_device *dev, void *data, struct drm_file *file_priv)
 {
-	DRM_DEVICE;
-	drm_via_futex_t fx;
+	drm_via_futex_t *fx = data;
 	volatile int *lock;
 	drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
 	drm_via_sarea_t *sAPriv = dev_priv->sarea_priv;
@@ -76,21 +75,18 @@ int via_decoder_futex(DRM_IOCTL_ARGS)
 
 	DRM_DEBUG("%s\n", __FUNCTION__);
 
-	DRM_COPY_FROM_USER_IOCTL(fx, (drm_via_futex_t __user *) data,
-				 sizeof(fx));
-
-	if (fx.lock > VIA_NR_XVMC_LOCKS)
+	if (fx->lock > VIA_NR_XVMC_LOCKS)
 		return -EFAULT;
 
-	lock = (volatile int *)XVMCLOCKPTR(sAPriv, fx.lock);
+	lock = (volatile int *)XVMCLOCKPTR(sAPriv, fx->lock);
 
-	switch (fx.func) {
+	switch (fx->func) {
 	case VIA_FUTEX_WAIT:
-		DRM_WAIT_ON(ret, dev_priv->decoder_queue[fx.lock],
-			    (fx.ms / 10) * (DRM_HZ / 100), *lock != fx.val);
+		DRM_WAIT_ON(ret, dev_priv->decoder_queue[fx->lock],
+			    (fx->ms / 10) * (DRM_HZ / 100), *lock != fx->val);
 		return ret;
 	case VIA_FUTEX_WAKE:
-		DRM_WAKEUP(&(dev_priv->decoder_queue[fx.lock]));
+		DRM_WAKEUP(&(dev_priv->decoder_queue[fx->lock]));
 		return 0;
 	}
 	return 0;


--- NEW FILE gen-patches ---
#!/bin/sh
#
# This script goes with the Makefile hacks for git/branch builds.
#

nopatches=1
if [ "x$1" = "x--fedora" ]; then
  nopatches=0
  shift
  patchcomment="plus Fedora patches"
else
  patchcomment="no Fedora patches"
fi

name=
if [ "x$1" = "x--name" ]; then
  shift
  name="$1"
  shift
fi

if [ $# -lt 2 ]; then
  echo >&2 "Usage: GIT_DIR=REPO $0 [--fedora] [--name NAME]\
 TARBALL-TAG [PATCH-TAG...] BRANCH..."
  exit 2
fi

base=$1
shift
base_rev=`git-rev-parse "$base"` || exit

nextpatch=1
usepatch()
{
  patches[$nextpatch]=$1
  nextpatch=$(($nextpatch + 1))
}

lasturl=:
loglines="- Experimental build from git sources ($patchcomment)\\
"
log()
{
  local logrev=$1
  local logbranch=$3
  case $logbranch in
  refs/remotes/*)
    logbranch=${logbranch#refs/remotes/}
    local remote=${logbranch%%/*}
    logbranch=${logbranch#*/}
    logbranch=${logbranch//\//-}
    local url
    url=`git-config "remote.${remote}.url"` || {
      echo >&2 "Cannot find URL for remote $remote"
      exit 2
    }
    if [ "$url" != "$lasturl" ]; then
      lasturl="$url"
      loglines="${loglines}- $url\\
"
    fi
    logtext="$(printf %12s "remote: ")$logbranch"
    ;;
  *)
    lasturl=:
    logtext="$(printf %-12s "git $2:")$logbranch"
    ;;
  esac
  loglines="${loglines}- $(printf %-35s "$logtext") ${logrev}\\
"
}

patch_headers()
{
  p=1
  while [ $p -lt $nextpatch ]; do
    echo "Patch$p: ${patches[$p]}\\"
    p=$(($p + 1))
  done
}

patch_apply()
{
  p=1
  while [ $p -lt $nextpatch ]; do
#    echo "%patch$p -p1\\"
    echo "ApplyPatch ${patches[$p]}\\"
    p=$(($p + 1))
  done
}

base_rev()
{
  local base=$1
  tag_rev=`git-rev-parse --revs-only --verify $base 2> /dev/null` &&
  [ "`git-describe --tags $tag_rev`" = "$base" ] && return 0
  case "$1" in
  v*-git*)
    local id=patch-${1#v}.id
    if [ ! -r $id ]; then
      make download UPSTREAM_FILES=$id UPSTREAM_CHECKS=-- > /dev/null 2>&1
    fi
    [ -r $id ] && tag_rev=`cat $id` && return 0
    ;;
  v2*)
    echo >&2 "Cannot find tag $base"
    exit 2
    ;;
  esac
  return 1
}

log $base_rev base $base
while base_rev $1; do
  base=$1
  base_rev=$tag_rev
  shift
  usepatch patch-${base#v}.bz2
  log $tag_rev tag $base
done
version=${base#v}

now="`date +'%Y-%m-%d %H:%M %Z'`"

for branch; do

  merge_base=`git-merge-base $base_rev $branch` || {
    echo >&2 "No common ancestor for $base and $branch"
    exit 2
  }
  branch_rev=`git-rev-parse $branch`

  case "$branch" in
  refs/remotes/*/master)
    branch_name=${branch#refs/remotes/}
    branch_name=${branch_name%/master}
    ;;
  refs/remotes/*)
    branch_name=${branch#refs/remotes/}
    branch_name=${branch_name//\//-}
    ;;
  */*)
    branch_name=${branch_name//\//-}
    ;;
  *)
    branch_name=$branch
    ;;
  esac

  file=linux-${version}-${branch_name}.patch
  git diff --no-renames -p \
	   -r "${merge_base}" -r "${branch_rev}" > $file || exit
  if [ ! -s $file ]; then
    rm -f $file
    continue
  fi

  usepatch $file
  log $branch_rev branch $branch

  base="$branch"
  base_rev="$base"
done
name=`echo ${name:-${branch}} | sed s/-/_/g`

#upstream_branch=`date -u -d "$now" +${branch}.%Y%m%dT%H%M | sed s/-/_/g`
upstream_branch=$name
branch_rev=`git describe $base_rev | sed 's/-g[0-9a-f]*$//;s/-/./g;s/^v//'`

logdate=`date -d "$now" +'%a %b %d %Y'`

sed "/%define nopatches/c\\
%define nopatches ${nopatches}\\
%define upstream_branch ${name}\\
%define upstream_branch_release ${branch_rev}
/^### BRANCH PATCH/a\\
`patch_headers`
###
/^### BRANCH APPLY/a\\
`patch_apply`
###
/^%changelog/a\\
* ${logdate} ${GIT_AUTHOR_NAME} <${GIT_AUTHOR_EMAIL}>\\
$loglines

"

git-wireless-dev.patch:

--- NEW FILE git-wireless-dev.patch ---
--- linux-2.6.21.noarch/CREDITS.orig	2007-06-14 14:07:08.000000000 -0400
+++ linux-2.6.21.noarch/CREDITS	2007-06-14 14:07:58.000000000 -0400
@@ -665,6 +665,11 @@ D: Minor updates to SCSI code for the Co
 S: (ask for current address)
 S: USA
 
+N: Robin Cornelius
+E: robincornelius at users.sourceforge.net
+D: Ralink rt2x00 WLAN driver
+S: Cornwall, U.K.
+
 N: Mark Corner
 E: mcorner at umich.edu
 W: http://www.eecs.umich.edu/~mcorner/
@@ -679,6 +684,11 @@ D: Kernel module SMART utilities
 S: Santa Cruz, California
 S: USA
 
+N: Luis Correia
+E: lfcorreia at users.sf.net
+D: Ralink rt2x00 WLAN driver
+S: Belas, Portugal
+
 N: Alan Cox
 W: http://www.linux.org.uk/diary/
 D: Linux Networking (0.99.10->2.0.29)
@@ -833,6 +843,12 @@ S: Lancs
 S: PR4 6AX
 S: United Kingdom
 
+N: Ivo van Doorn
+E: IvDoorn at gmail.com
+W: http://www.mendiosus.nl
+D: Ralink rt2x00 WLAN driver
+S: Haarlem, The Netherlands
+
 N: John G Dorsey
 E: john+ at cs.cmu.edu
 D: ARM Linux ports to Assabet/Neponset, Spot
@@ -3516,6 +3532,12 @@ S: Maastrichterweg 63
 S: 5554 GG Valkenswaard
 S: The Netherlands
 
+N: Mark Wallis
+E: mwallis at serialmonkey.com
+W: http://mark.serialmonkey.com
+D: Ralink rt2x00 WLAN driver
+S: Newcastle, Australia
+
 N: Peter Shaobo Wang
 E: pwang at mmdcorp.com
 W: http://www.mmdcorp.com/pw/linux
@@ -3650,6 +3672,15 @@ S: Alte Regensburger Str. 11a
 S: 93149 Nittenau
 S: Germany
 
+N: Gertjan van Wingerde
+E: gwingerde at home.nl
+D: Ralink rt2x00 WLAN driver
+D: Minix V2 file-system
+D: Misc fixes
+S: Geessinkweg 177
+S: 7544 TX Enschede
+S: The Netherlands
+
 N: Lars Wirzenius
 E: liw at iki.fi
 D: Linux System Administrator's Guide, author, former maintainer
--- linux-2.6.21.noarch/include/linux/nl80211.h.orig	2007-06-14 14:07:08.000000000 -0400
+++ linux-2.6.21.noarch/include/linux/nl80211.h	2007-06-14 14:07:58.000000000 -0400
@@ -7,6 +7,217 @@
  */
 
 /**
+ * enum nl80211_commands - supported nl80211 commands
+ * @NL80211_CMD_UNSPEC: unspecified command to catch errors
+ * @NL80211_CMD_RENAME_WIPHY: rename a wiphy, needs
+ *	%NL80211_ATTR_WIPHY and %NL80211_ATTR_WIPHY_NAME
+ * @NL80211_CMD_WIPHY_NEWNAME: rename notification
+ * @NL80211_CMD_GET_CMDLIST: TO BE DEFINED PROPERLY. currently the code makes
+ *	it depend on the wiphy only but it really should depend on the
+ *	interface type too....
+ * @NL80211_CMD_NEW_CMDLIST: command list result
+ * @NL80211_CMD_ADD_VIRTUAL_INTERFACE: create a virtual interface for the
+ *	wiphy identified by an %NL80211_ATTR_WIPHY attribute with the given
+ *	%NL80211_ATTR_IFTYPE and %NL80211_ATTR_IFNAME.
+ * @NL80211_CMD_DEL_VIRTUAL_INTERFACE: destroy a virtual interface identified
+ *	by %NL80211_ATTR_IFINDEX.
+ * @NL80211_CMD_CHANGE_VIRTUAL_INTERFACE: change type of virtual interface to
+ *	the type given by %NL80211_ATTR_IFTYPE, the interface is identified by
+ *	%NL80211_ATTR_IFINDEX.
+ * @NL80211_CMD_GET_WIPHYS: request a list of all wiphys present in the system
+ * @NL80211_CMD_NEW_WIPHYS: returned list of all wiphys
+ * @NL80211_CMD_GET_INTERFACES: request a list of all interfaces belonging to
+ *	the wiphy identified by %NL80211_ATTR_WIPHY
+ * @NL80211_CMD_NEW_INTERFACES: result for %NL80211_CMD_GET_INTERFACES
+ * @NL80211_CMD_INITIATE_SCAN: initiate a scan with the passed parameters. THe
+ *	parameters may contain %NL80211_ATTR_FLAG_SCAN_ACTIVE,
+ *	%NL80211_ATTR_PHYMODE and a list of channels in an
+ *	%NL80211_ATTR_CHANNEL_LIST attribute (an array of nested attributes)
+ *	containing %NL80211_ATTR_CHANNEL, %NL80211_ATTR_PHYMODE, and possibly
+ *	%NL80211_ATTR_FLAG_SCAN_ACTIVE. The outer %NL80211_ATTR_FLAG_SCAN_ACTIVE
+ *	is ignored when a channel list is present.
+ * @NL80211_CMD_SCAN_RESULT: scan result, contains an array in
+ *	%NL80211_ATTR_BSS_LIST.
+ * @NL80211_CMD_ASSOCIATE: associate with the given parameters
+ *	(%NL80211_ATTR_SSID is mandatory, %NL80211_ATTR_TIMEOUT_TU,
+ *	%NL80211_ATTR_BSSID, %NL80211_ATTR_CHANNEL, %NL80211_ATTR_PHYMODE,
+ *	and %NL80211_ATTR_IE may be given)
+ * @NL80211_CMD_ADD_KEY: add a key with given %NL80211_ATTR_KEY_DATA,
+ * 	%NL80211_ATTR_KEY_ID, %NL80211_ATTR_KEY_TYPE, %NL80211_ATTR_MAC and
+ *	%NL80211_ATTR_KEY_CIPHER attributes.
+ * @NL80211_CMD_DEL_KEY: delete a key identified by %NL80211_ATTR_KEY_ID,
+ *	%NL80211_ATTR_KEY_TYPE and %NL80211_ATTR_MAC or all keys.
+ * @__NL80211_CMD_AFTER_LAST: internal use
+ */
+enum nl80211_commands {
+/* don't change the order or add anything inbetween, this is ABI! */
+	NL80211_CMD_UNSPEC,
+	/* %input: wiphy, wiphy_name */
+	NL80211_CMD_RENAME_WIPHY,
+	NL80211_CMD_WIPHY_NEWNAME,
+	/* %input: wiphy|ifindex */
+	NL80211_CMD_GET_CMDLIST,
+	NL80211_CMD_NEW_CMDLIST,
+	/* %input: wiphy, ifname, {iftype} */
+	NL80211_CMD_ADD_VIRTUAL_INTERFACE,
+	/* %input: wiphy, ifindex */
+	NL80211_CMD_DEL_VIRTUAL_INTERFACE,
+	/* %input: ifindex, iftype */
+	NL80211_CMD_CHANGE_VIRTUAL_INTERFACE,
+	/* %input: */
+	NL80211_CMD_GET_WIPHYS,
+	NL80211_CMD_NEW_WIPHYS,
+	/* %input: wiphy */
+	NL80211_CMD_GET_INTERFACES,
+	NL80211_CMD_NEW_INTERFACES,
+	NL80211_CMD_INITIATE_SCAN,
+	NL80211_CMD_SCAN_RESULT,
+	NL80211_CMD_GET_ASSOCIATION,
+	NL80211_CMD_ASSOCIATION_CHANGED,
+	NL80211_CMD_ASSOCIATE,
+	NL80211_CMD_DISASSOCIATE,
+	NL80211_CMD_DEAUTH,
+	NL80211_CMD_GET_AUTH_LIST,
+	NL80211_CMD_NEW_AUTH_LIST,
+	NL80211_CMD_AUTHENTICATION_CHANGED,
+	NL80211_CMD_AP_SET_BEACON,
+	NL80211_CMD_AP_ADD_STA,
+	NL80211_CMD_AP_UPDATE_STA,
+	NL80211_CMD_AP_GET_STA_INFO,
+	NL80211_CMD_AP_SET_RATESETS,
+	NL80211_CMD_ADD_KEY,
+	NL80211_CMD_DEL_KEY,
+
+	/* add commands here */
+
+	/* used to define NL80211_CMD_MAX below */
+	__NL80211_CMD_AFTER_LAST
+};
+#define NL80211_CMD_MAX (__NL80211_CMD_AFTER_LAST - 1)
+
+
+/**
+ * enum nl80211_attrs - nl80211 netlink attributes
+ * @NL80211_ATTR_UNSPEC: unspecified attribute to catch errors
+ * @NL80211_ATTR_IFINDEX: network interface index of the device to operate on
+ * @NL80211_ATTR_IFNAME: network interface name
+ * @NL80211_ATTR_WIPHY: index of wiphy to operate on, cf.
+ *	/sys/class/ieee80211/<phyname>/index
+ * @NL80211_ATTR_WIPHY_NAME: wiphy name (used for renaming)
+ * @NL80211_ATTR_CMDS: list of u8's identifying commands a device supports
+ * @NL80211_ATTR_IFTYPE: type of virtual interface, see &enum nl80211_iftype
+ * @NL80211_ATTR_INTERFACE_LIST: interface array, nested netlink attribute
+ * @NL80211_ATTR_WIPHY_LIST: wiphy array, nested netlink attribute
+ * @NL80211_ATTR_BSSID: BSSID (must be 6 bytes)
+ * @NL80211_ATTR_SSID: SSID (1-32 bytes)
+ * @NL80211_ATTR_CHANNEL: channel number
+ * @NL80211_ATTR_PHYMODE: PHY mode, see &enum nl80211_phymode
+ * @NL80211_ATTR_CHANNEL_LIST: netlink nested attribute array containing scan
+ *	parameters for channels
+ * @NL80211_ATTR_BSS_LIST: nested attribute containing an array
+ * @NL80211_ATTR_BSSTYPE: BSS type, see &enum nl80211_bsstype
+ * @NL80211_ATTR_BEACON_PERIOD: beacon period
+ * @NL80211_ATTR_DTIM_PERIOD: DTIM period
+ * @NL80211_ATTR_TIMESTAMP: 64-bit timestamp of received beacon/probe response
+ * @NL80211_ATTR_IE: information element(s), maximum length %NL80211_MAX_IE_LEN
+ * @NL80211_ATTR_AUTH_ALGORITHM: authentication algorithm
+ * @NL80211_ATTR_TIMEOUT_TU: timeout in TU (TO BE USED)
+ * @NL80211_ATTR_REASON_CODE: 802.11 reason code
+ * @NL80211_ATTR_ASSOCIATION_ID: association ID (u16, 1-2007)
+ * @NL80211_ATTR_DEAUTHENTICATED: TO BE USED
+ * @NL80211_ATTR_RX_SENSITIVITY: receiver sensitivity in dBm
+ * @NL80211_ATTR_TRANSMIT_POWER: transmit power in mW
+ * @NL80211_ATTR_FRAG_THRESHOLD: fragmentation threshold (bytes)
+ * @NL80211_ATTR_FLAG_SCAN_ACTIVE: netlink flag indiciating active scan
+ * @NL80211_ATTR_KEY_DATA: temporal key data
+ * @NL80211_ATTR_KEY_ID: key ID (u8, 0-3)
+ * @NL80211_ATTR_KEY_TYPE: key type (see &enum nl80211_keytype)
[...91009 lines suppressed...]
+	 * PCI is bonded out, some boards may leave the pins floating. */
+	if (bus->chip_id == 0x4712) {
+		if (bus->chip_package == SSB_CHIPPACK_BCM4712S)
+			return 0;
+		if (bus->chip_package == SSB_CHIPPACK_BCM4712M)
+			return 0;
+	}
+	if (bus->chip_id == 0x5350)
+		return 0;
+
+	return !mips_busprobe(tmp, (u32 *) (bus->mmio + (pc->dev->core_index * SSB_CORE_SIZE)));
+}
+#endif /* CONFIG_SSB_PCICORE_HOSTMODE */
+
+
+/**************************************************
+ * Generic and Clientmode operation code.
+ **************************************************/
+
+static void ssb_pcicore_init_clientmode(struct ssb_pcicore *pc)
+{
+	/* Disable PCI interrupts. */
+	ssb_write32(pc->dev, SSB_INTVEC, 0);
+}
+
+void ssb_pcicore_init(struct ssb_pcicore *pc)
+{
+	struct ssb_device *dev = pc->dev;
+	struct ssb_bus *bus;
+
+	if (!dev)
+		return;
+	bus = dev->bus;
+	if (!ssb_device_is_enabled(dev))
+		ssb_device_enable(dev, 0);
+
+#ifdef CONFIG_SSB_PCICORE_HOSTMODE
+	pc->hostmode = pcicore_is_in_hostmode(pc);
+	if (pc->hostmode)
+		ssb_pcicore_init_hostmode(pc);
+#endif /* CONFIG_SSB_PCICORE_HOSTMODE */
+	if (!pc->hostmode)
+		ssb_pcicore_init_clientmode(pc);
+}
+
+static u32 ssb_pcie_read(struct ssb_pcicore *pc, u32 address)
+{
+	pcicore_write32(pc, 0x130, address);
+	return pcicore_read32(pc, 0x134);
+}
+
+static void ssb_pcie_write(struct ssb_pcicore *pc, u32 address, u32 data)
+{
+	pcicore_write32(pc, 0x130, address);
+	pcicore_write32(pc, 0x134, data);
+}
+
+static void ssb_pcie_mdio_write(struct ssb_pcicore *pc, u8 device,
+				u8 address, u16 data)
+{
+	const u16 mdio_control = 0x128;
+	const u16 mdio_data = 0x12C;
+	u32 v;
+	int i;
+
+	v = 0x80; /* Enable Preamble Sequence */
+	v |= 0x2; /* MDIO Clock Divisor */
+	pcicore_write32(pc, mdio_control, v);
+
+	v = (1 << 30); /* Start of Transaction */
+	v |= (1 << 28); /* Write Transaction */
+	v |= (1 << 17); /* Turnaround */
+	v |= (u32)device << 22;
+	v |= (u32)address << 18;
+	v |= data;
+	pcicore_write32(pc, mdio_data, v);
+	udelay(10);
+	for (i = 0; i < 10; i++) {
+		v = pcicore_read32(pc, mdio_control);
+		if (v & 0x100 /* Trans complete */)
+			break;
+		msleep(1);
+	}
+	pcicore_write32(pc, mdio_control, 0);
+}
+
+static void ssb_broadcast_value(struct ssb_device *dev,
+				u32 address, u32 data)
+{
+	/* This is used for both, PCI and ChipCommon core, so be careful. */
+	BUILD_BUG_ON(SSB_PCICORE_BCAST_ADDR != SSB_CHIPCO_BCAST_ADDR);
+	BUILD_BUG_ON(SSB_PCICORE_BCAST_DATA != SSB_CHIPCO_BCAST_DATA);
+
+	ssb_write32(dev, SSB_PCICORE_BCAST_ADDR, address);
+	ssb_read32(dev, SSB_PCICORE_BCAST_ADDR); /* flush */
+	ssb_write32(dev, SSB_PCICORE_BCAST_DATA, data);
+	ssb_read32(dev, SSB_PCICORE_BCAST_DATA); /* flush */
+}
+
+static void ssb_commit_settings(struct ssb_bus *bus)
+{
+	struct ssb_device *dev;
+
+	dev = bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev;
+	assert(dev);
+	/* This forces an update of the cached registers. */
+	ssb_broadcast_value(dev, 0xFD8, 0);
+}
+
+int ssb_pcicore_dev_irqvecs_enable(struct ssb_pcicore *pc,
+				   struct ssb_device *dev)
+{
+	struct ssb_device *pdev = pc->dev;
+	struct ssb_bus *bus;
+	int err = 0;
+	u32 tmp;
+
+	might_sleep();
+
+	if (!pdev)
+		goto out;
+	bus = pdev->bus;
+
+	/* Enable interrupts for this device. */
+	if (bus->host_pci &&
+	    ((pdev->id.revision >= 6) || (pdev->id.coreid == SSB_DEV_PCIE))) {
+		u32 coremask;
+
+		/* Calculate the "coremask" for the device. */
+		coremask = (1 << dev->core_index);
+
+		err = pci_read_config_dword(bus->host_pci, SSB_PCI_IRQMASK, &tmp);
+		if (err)
+			goto out;
+		tmp |= coremask << 8;
+		err = pci_write_config_dword(bus->host_pci, SSB_PCI_IRQMASK, tmp);
+		if (err)
+			goto out;
+	} else {
+		u32 intvec;
+
+		intvec = ssb_read32(pdev, SSB_INTVEC);
+		tmp = ssb_read32(dev, SSB_TPSFLAG);
+		tmp &= SSB_TPSFLAG_BPFLAG;
+		intvec |= tmp;
+		ssb_write32(pdev, SSB_INTVEC, intvec);
+	}
+
+	/* Setup PCIcore operation. */
+	if (pc->setup_done)
+		goto out;
+	if (pdev->id.coreid == SSB_DEV_PCI) {
+		tmp = pcicore_read32(pc, SSB_PCICORE_SBTOPCI2);
+		tmp |= SSB_PCICORE_SBTOPCI_PREF;
+		tmp |= SSB_PCICORE_SBTOPCI_BURST;
+		pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, tmp);
+
+		if (pdev->id.revision < 5) {
+			tmp = ssb_read32(pdev, SSB_IMCFGLO);
+			tmp &= ~SSB_IMCFGLO_SERTO;
+			tmp |= 2;
+			tmp &= ~SSB_IMCFGLO_REQTO;
+			tmp |= 3 << SSB_IMCFGLO_REQTO_SHIFT;
+			ssb_write32(pdev, SSB_IMCFGLO, tmp);
+			ssb_commit_settings(bus);
+		} else if (pdev->id.revision >= 11) {
+			tmp = pcicore_read32(pc, SSB_PCICORE_SBTOPCI2);
+			tmp |= SSB_PCICORE_SBTOPCI_MRM;
+			pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, tmp);
+		}
+	} else {
+		assert(pdev->id.coreid == SSB_DEV_PCIE);
+		//TODO: Better make defines for all these magic PCIE values.
+		if ((pdev->id.revision == 0) || (pdev->id.revision == 1)) {
+			/* TLP Workaround register. */
+			tmp = ssb_pcie_read(pc, 0x4);
+			tmp |= 0x8;
+			ssb_pcie_write(pc, 0x4, tmp);
+		}
+		if (pdev->id.revision == 0) {
+			const u8 serdes_rx_device = 0x1F;
+
+			ssb_pcie_mdio_write(pc, serdes_rx_device,
+					    2 /* Timer */, 0x8128);
+			ssb_pcie_mdio_write(pc, serdes_rx_device,
+					    6 /* CDR */, 0x0100);
+			ssb_pcie_mdio_write(pc, serdes_rx_device,
+					    7 /* CDR BW */, 0x1466);
+		} else if (pdev->id.revision == 1) {
+			/* DLLP Link Control register. */
+			tmp = ssb_pcie_read(pc, 0x100);
+			tmp |= 0x40;
+			ssb_pcie_write(pc, 0x100, tmp);
+		}
+	}
+	pc->setup_done = 1;
+out:
+	return err;
+}
+EXPORT_SYMBOL(ssb_pcicore_dev_irqvecs_enable);


--- NEW FILE kernel-2.6.21.7-i686-xen.config ---
# i386
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.21-prep
# Mon Jul 23 15:25:09 2007
#
CONFIG_X86_32=y
CONFIG_CLOCKSOURCE_WATCHDOG=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_SEMAPHORE_SLEEPERS=y
CONFIG_X86=y
CONFIG_MMU=y
CONFIG_ZONE_DMA=y
CONFIG_GENERIC_ISA_DMA=y
CONFIG_GENERIC_IOMAP=y
CONFIG_GENERIC_BUG=y
CONFIG_GENERIC_HWEIGHT=y
CONFIG_ARCH_MAY_HAVE_PC_FDC=y
CONFIG_DMI=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"

#
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
CONFIG_LOCK_KERNEL=y
CONFIG_INIT_ENV_ARG_LIMIT=32

#
# General setup
#
CONFIG_LOCALVERSION=""
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_IPC_NS=y
CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
CONFIG_TASKSTATS=y
CONFIG_TASK_DELAY_ACCT=y
CONFIG_TASK_XACCT=y
CONFIG_TASK_IO_ACCOUNTING=y
CONFIG_UTS_NS=y
CONFIG_AUDIT=y
CONFIG_AUDITSYSCALL=y
# CONFIG_IKCONFIG is not set
CONFIG_CPUSETS=y
CONFIG_SYSFS_DEPRECATED=y
CONFIG_RELAY=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
# CONFIG_EMBEDDED is not set
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
CONFIG_KALLSYMS_EXTRA_PASS=y
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_SHMEM=y
CONFIG_SLAB=y
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_MODULE_VERIFY_ELF=y
CONFIG_MODULE_SIG=y
# CONFIG_MODULE_SIG_FORCE is not set
CONFIG_MODULE_VERIFY=y
CONFIG_KMOD=y
CONFIG_STOP_MACHINE=y

#
# Process debugging support
#
CONFIG_PTRACE=y
CONFIG_UTRACE=y

#
# Block layer
#
CONFIG_BLOCK=y
CONFIG_LBD=y
CONFIG_BLK_DEV_IO_TRACE=y
CONFIG_LSF=y

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

#
# Processor type and features
#
# CONFIG_TICK_ONESHOT is not set
CONFIG_SMP=y
# CONFIG_X86_PC is not set
CONFIG_X86_XEN=y
# CONFIG_X86_ELAN is not set
# CONFIG_X86_VOYAGER is not set
# CONFIG_X86_NUMAQ is not set
# CONFIG_X86_SUMMIT is not set
# CONFIG_X86_BIGSMP is not set
# CONFIG_X86_VISWS is not set
# CONFIG_X86_GENERICARCH is not set
# CONFIG_X86_ES7000 is not set
# CONFIG_PARAVIRT is not set
# CONFIG_M386 is not set
# CONFIG_M486 is not set
# CONFIG_M586 is not set
# CONFIG_M586TSC is not set
# CONFIG_M586MMX is not set
CONFIG_M686=y
# CONFIG_MPENTIUMII is not set
# CONFIG_MPENTIUMIII is not set
# CONFIG_MPENTIUMM is not set
# CONFIG_MCORE2 is not set
# CONFIG_MPENTIUM4 is not set
# CONFIG_MK6 is not set
# CONFIG_MK7 is not set
# CONFIG_MK8 is not set
# CONFIG_MCRUSOE is not set
# CONFIG_MEFFICEON is not set
# CONFIG_MWINCHIPC6 is not set
# CONFIG_MWINCHIP2 is not set
# CONFIG_MWINCHIP3D is not set
# CONFIG_MGEODEGX1 is not set
# CONFIG_MGEODE_LX is not set
# CONFIG_MCYRIXIII is not set
# CONFIG_MVIAC3_2 is not set
CONFIG_X86_GENERIC=y
CONFIG_X86_CMPXCHG=y
CONFIG_X86_L1_CACHE_SHIFT=7
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_X86_PPRO_FENCE=y
CONFIG_X86_WP_WORKS_OK=y
CONFIG_X86_INVLPG=y
CONFIG_X86_BSWAP=y
CONFIG_X86_POPAD_OK=y
CONFIG_X86_CMPXCHG64=y
CONFIG_X86_GOOD_APIC=y
CONFIG_X86_INTEL_USERCOPY=y
CONFIG_X86_USE_PPRO_CHECKSUM=y
CONFIG_NR_CPUS=32
# CONFIG_PREEMPT_NONE is not set
CONFIG_PREEMPT_VOLUNTARY=y
# CONFIG_PREEMPT is not set
CONFIG_PREEMPT_BKL=y
CONFIG_X86_LOCAL_APIC=y
CONFIG_X86_IO_APIC=y
CONFIG_VM86=y
CONFIG_TOSHIBA=m
CONFIG_I8K=m
# CONFIG_X86_REBOOTFIXUPS is not set
CONFIG_MICROCODE=m
CONFIG_MICROCODE_OLD_INTERFACE=y
CONFIG_X86_CPUID=m
CONFIG_SWIOTLB=y

#
# Firmware Drivers
#
CONFIG_DELL_RBU=m
CONFIG_DCDBAS=m
# CONFIG_NOHIGHMEM is not set
# CONFIG_HIGHMEM4G is not set
[...3104 lines suppressed...]
CONFIG_DLM=m
CONFIG_DLM_TCP=y
# CONFIG_DLM_SCTP is not set
CONFIG_DLM_DEBUG=y

#
# Instrumentation Support
#
CONFIG_PROFILING=y
CONFIG_OPROFILE=m
CONFIG_KPROBES=y

#
# Kernel hacking
#
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_DEBUG_IGNORE_QUIET is not set
# CONFIG_PRINTK_TIME is not set
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_MAGIC_SYSRQ=y
# CONFIG_UNUSED_SYMBOLS is not set
CONFIG_DEBUG_FS=y
CONFIG_HEADERS_CHECK=y
CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_SHIRQ=y
CONFIG_LOG_BUF_SHIFT=17
CONFIG_DETECT_SOFTLOCKUP=y
CONFIG_DEBUG_NMI_TIMEOUT=5
CONFIG_SCHEDSTATS=y
CONFIG_TIMER_STATS=y
# 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_LOCK_ALLOC is not set
# CONFIG_PROVE_LOCKING is not set
CONFIG_DEBUG_SPINLOCK_SLEEP=y
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
# CONFIG_DEBUG_KOBJECT is not set
CONFIG_DEBUG_HIGHMEM=y
CONFIG_DEBUG_BUGVERBOSE=y
CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_VM is not set
CONFIG_DEBUG_LIST=y
# CONFIG_FRAME_POINTER is not set
# CONFIG_FORCED_INLINING is not set
CONFIG_BOOT_DELAY=y
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_LKDTM is not set
# CONFIG_FAULT_INJECTION is not set
CONFIG_EARLY_PRINTK=y
CONFIG_DEBUG_STACKOVERFLOW=y
CONFIG_DEBUG_STACK_USAGE=y
# CONFIG_DEBUG_PAGEALLOC is not set
CONFIG_DEBUG_RODATA=y
CONFIG_4KSTACKS=y
CONFIG_X86_FIND_SMP_CONFIG=y
CONFIG_X86_MPPARSE=y

#
# Security options
#
CONFIG_KEYS=y
CONFIG_KEYS_DEBUG_PROC_KEYS=y
CONFIG_SECURITY=y
CONFIG_SECURITY_NETWORK=y
CONFIG_SECURITY_NETWORK_XFRM=y
CONFIG_SECURITY_CAPABILITIES=y
# CONFIG_SECURITY_ROOTPLUG is not set
CONFIG_SECURITY_SELINUX=y
CONFIG_SECURITY_SELINUX_BOOTPARAM=y
CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1
CONFIG_SECURITY_SELINUX_DISABLE=y
CONFIG_SECURITY_SELINUX_DEVELOP=y
CONFIG_SECURITY_SELINUX_AVC_STATS=y
CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set
# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX 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=m
CONFIG_CRYPTO_MD4=m
CONFIG_CRYPTO_MD5=y
CONFIG_CRYPTO_SHA1=y
CONFIG_CRYPTO_SHA256=m
CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_TGR192=m
CONFIG_CRYPTO_GF128MUL=m
CONFIG_CRYPTO_ECB=m
CONFIG_CRYPTO_CBC=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_DES=m
CONFIG_CRYPTO_FCRYPT=m
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_TWOFISH_COMMON=m
# CONFIG_CRYPTO_TWOFISH_586 is not set
CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_AES=m
# CONFIG_CRYPTO_AES_586 is not set
CONFIG_CRYPTO_CAST5=m
CONFIG_CRYPTO_CAST6=m
CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_KHAZAD=m
CONFIG_CRYPTO_ANUBIS=m
CONFIG_CRYPTO_DEFLATE=m
CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_CRC32C=m
CONFIG_CRYPTO_CAMELLIA=m
# CONFIG_CRYPTO_TEST is not set
CONFIG_CRYPTO_MPILIB=y
CONFIG_CRYPTO_SIGNATURE=y
CONFIG_CRYPTO_SIGNATURE_DSA=y

#
# Hardware crypto devices
#
# CONFIG_CRYPTO_DEV_PADLOCK is not set
CONFIG_CRYPTO_DEV_GEODE=m
CONFIG_XEN=y
CONFIG_XEN_INTERFACE_VERSION=0x00030205

#
# XEN
#
CONFIG_XEN_PRIVILEGED_GUEST=y
# CONFIG_XEN_UNPRIVILEGED_GUEST is not set
CONFIG_XEN_PRIVCMD=y
CONFIG_XEN_XENBUS_DEV=y
CONFIG_XEN_BACKEND=y
CONFIG_XEN_BLKDEV_BACKEND=m
CONFIG_XEN_BLKDEV_TAP=m
CONFIG_XEN_NETDEV_BACKEND=m
# CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
CONFIG_XEN_NETDEV_LOOPBACK=m
CONFIG_XEN_PCIDEV_BACKEND=m
CONFIG_XEN_PCIDEV_BACKEND_VPCI=y
# CONFIG_XEN_PCIDEV_BACKEND_PASS is not set
# CONFIG_XEN_PCIDEV_BACKEND_SLOT is not set
# CONFIG_XEN_PCIDEV_BE_DEBUG is not set
# CONFIG_XEN_TPMDEV_BACKEND is not set
CONFIG_XEN_BLKDEV_FRONTEND=m
CONFIG_XEN_NETDEV_FRONTEND=m
CONFIG_XEN_FRAMEBUFFER=y
CONFIG_XEN_KEYBOARD=y
CONFIG_XEN_SCRUB_PAGES=y
# CONFIG_XEN_DISABLE_SERIAL is not set
CONFIG_XEN_SYSFS=y
CONFIG_XEN_COMPAT_030002_AND_LATER=y
# CONFIG_XEN_COMPAT_030004_AND_LATER is not set
# CONFIG_XEN_COMPAT_LATEST_ONLY is not set
CONFIG_XEN_COMPAT=0x030002
CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y
CONFIG_NO_IDLE_HZ=y
CONFIG_XEN_SMPBOOT=y

#
# Library routines
#
CONFIG_BITREVERSE=y
CONFIG_CRC_CCITT=m
CONFIG_CRC16=m
CONFIG_CRC_ITU_T=m
CONFIG_CRC32=y
CONFIG_LIBCRC32C=m
CONFIG_AUDIT_GENERIC=y
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=m
CONFIG_GENERIC_ALLOCATOR=y
CONFIG_REED_SOLOMON=m
CONFIG_REED_SOLOMON_DEC16=y
CONFIG_TEXTSEARCH=y
CONFIG_TEXTSEARCH_KMP=m
CONFIG_TEXTSEARCH_BM=m
CONFIG_TEXTSEARCH_FSM=m
CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_GENERIC_PENDING_IRQ=y
CONFIG_X86_SMP=y
CONFIG_X86_BIOS_REBOOT=y
CONFIG_X86_TRAMPOLINE=y
CONFIG_X86_NO_TSS=y
CONFIG_X86_NO_IDT=y
CONFIG_KTIME_SCALAR=y


--- NEW FILE kernel-2.6.21.7-x86_64-xen.config ---
# x86_64
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.21-prep
# Tue Jul 24 13:48:09 2007
#
CONFIG_X86_64=y
CONFIG_64BIT=y
CONFIG_X86=y
CONFIG_GENERIC_TIME_VSYSCALL=y
CONFIG_ZONE_DMA32=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_SEMAPHORE_SLEEPERS=y
CONFIG_MMU=y
CONFIG_ZONE_DMA=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_X86_CMPXCHG=y
CONFIG_EARLY_PRINTK=y
CONFIG_GENERIC_ISA_DMA=y
CONFIG_GENERIC_IOMAP=y
CONFIG_ARCH_MAY_HAVE_PC_FDC=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_DMI=y
CONFIG_AUDIT_ARCH=y
CONFIG_GENERIC_BUG=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"

#
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
CONFIG_LOCK_KERNEL=y
CONFIG_INIT_ENV_ARG_LIMIT=32

#
# General setup
#
CONFIG_LOCALVERSION=""
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_IPC_NS=y
CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
CONFIG_TASKSTATS=y
CONFIG_TASK_DELAY_ACCT=y
CONFIG_TASK_XACCT=y
CONFIG_TASK_IO_ACCOUNTING=y
CONFIG_UTS_NS=y
CONFIG_AUDIT=y
CONFIG_AUDITSYSCALL=y
# CONFIG_IKCONFIG is not set
CONFIG_CPUSETS=y
CONFIG_SYSFS_DEPRECATED=y
CONFIG_RELAY=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
# CONFIG_EMBEDDED is not set
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
CONFIG_KALLSYMS_EXTRA_PASS=y
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_SHMEM=y
CONFIG_SLAB=y
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_MODULE_VERIFY_ELF=y
CONFIG_MODULE_SIG=y
# CONFIG_MODULE_SIG_FORCE is not set
CONFIG_MODULE_VERIFY=y
CONFIG_KMOD=y
CONFIG_STOP_MACHINE=y

#
# Process debugging support
#
CONFIG_PTRACE=y
CONFIG_UTRACE=y

#
# Block layer
#
CONFIG_BLOCK=y
CONFIG_BLK_DEV_IO_TRACE=y

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

#
# Processor type and features
#
CONFIG_X86_PC=y
# CONFIG_X86_VSMP is not set
# CONFIG_MK8 is not set
# CONFIG_MPSC is not set
# CONFIG_MCORE2 is not set
CONFIG_GENERIC_CPU=y
CONFIG_X86_64_XEN=y
CONFIG_X86_NO_TSS=y
CONFIG_X86_NO_IDT=y
CONFIG_X86_L1_CACHE_BYTES=128
CONFIG_X86_L1_CACHE_SHIFT=7
CONFIG_X86_INTERNODE_CACHE_BYTES=128
CONFIG_X86_GOOD_APIC=y
CONFIG_MICROCODE=m
CONFIG_MICROCODE_OLD_INTERFACE=y
CONFIG_X86_MSR=y
CONFIG_X86_CPUID=y
CONFIG_X86_IO_APIC=y
CONFIG_X86_XEN_GENAPIC=y
CONFIG_X86_LOCAL_APIC=y
# CONFIG_MTRR is not set
CONFIG_SMP=y
# CONFIG_PREEMPT_NONE is not set
CONFIG_PREEMPT_VOLUNTARY=y
# CONFIG_PREEMPT is not set
CONFIG_PREEMPT_BKL=y
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
# CONFIG_DISCONTIGMEM_MANUAL is not set
# CONFIG_SPARSEMEM_MANUAL is not set
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_SPLIT_PTLOCK_CPUS=4096
CONFIG_RESOURCES_64BIT=y
CONFIG_ZONE_DMA_FLAG=1
CONFIG_NR_CPUS=64
CONFIG_HOTPLUG_CPU=y
CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
CONFIG_CALGARY_IOMMU=y
CONFIG_CALGARY_IOMMU_ENABLED_BY_DEFAULT=y
CONFIG_SWIOTLB=y
# CONFIG_KEXEC is not set
# CONFIG_CRASH_DUMP is not set
CONFIG_PHYSICAL_START=0x200000
# CONFIG_SECCOMP is not set
CONFIG_CC_STACKPROTECTOR=y
# CONFIG_CC_STACKPROTECTOR_ALL is not set
# CONFIG_HZ_100 is not set
# CONFIG_HZ_250 is not set
# CONFIG_HZ_300 is not set
CONFIG_HZ_1000=y
CONFIG_HZ=1000
CONFIG_REORDER=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_ISA_DMA_API=y
CONFIG_GENERIC_PENDING_IRQ=y

#
# Power management options
#

#
# ACPI (Advanced Configuration and Power Interface) Support
#
CONFIG_ACPI=y
CONFIG_ACPI_PROCFS=y
CONFIG_ACPI_AC=y
[...2954 lines suppressed...]
CONFIG_NLS_CODEPAGE_949=m
CONFIG_NLS_CODEPAGE_874=m
CONFIG_NLS_ISO8859_8=m
CONFIG_NLS_CODEPAGE_1250=m
CONFIG_NLS_CODEPAGE_1251=m
CONFIG_NLS_ASCII=y
CONFIG_NLS_ISO8859_1=m
CONFIG_NLS_ISO8859_2=m
CONFIG_NLS_ISO8859_3=m
CONFIG_NLS_ISO8859_4=m
CONFIG_NLS_ISO8859_5=m
CONFIG_NLS_ISO8859_6=m
CONFIG_NLS_ISO8859_7=m
CONFIG_NLS_ISO8859_9=m
CONFIG_NLS_ISO8859_13=m
CONFIG_NLS_ISO8859_14=m
CONFIG_NLS_ISO8859_15=m
CONFIG_NLS_KOI8_R=m
CONFIG_NLS_KOI8_U=m
CONFIG_NLS_UTF8=m

#
# Distributed Lock Manager
#
CONFIG_DLM=m
CONFIG_DLM_TCP=y
# CONFIG_DLM_SCTP is not set
CONFIG_DLM_DEBUG=y

#
# Instrumentation Support
#
CONFIG_PROFILING=y
CONFIG_OPROFILE=m
CONFIG_KPROBES=y

#
# Kernel hacking
#
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_DEBUG_IGNORE_QUIET is not set
# CONFIG_PRINTK_TIME is not set
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_MAGIC_SYSRQ=y
# CONFIG_UNUSED_SYMBOLS is not set
CONFIG_DEBUG_FS=y
CONFIG_HEADERS_CHECK=y
CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_SHIRQ=y
CONFIG_LOG_BUF_SHIFT=17
CONFIG_DETECT_SOFTLOCKUP=y
CONFIG_DEBUG_NMI_TIMEOUT=5
CONFIG_SCHEDSTATS=y
CONFIG_TIMER_STATS=y
# CONFIG_DEBUG_SLAB is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
# CONFIG_DEBUG_MUTEXES is not set
CONFIG_DEBUG_SPINLOCK_SLEEP=y
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
# CONFIG_DEBUG_KOBJECT is not set
CONFIG_DEBUG_BUGVERBOSE=y
CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_VM is not set
CONFIG_DEBUG_LIST=y
# CONFIG_FRAME_POINTER is not set
# CONFIG_FORCED_INLINING is not set
CONFIG_BOOT_DELAY=y
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_LKDTM is not set
# CONFIG_FAULT_INJECTION is not set
CONFIG_DEBUG_RODATA=y
CONFIG_DEBUG_STACKOVERFLOW=y
# CONFIG_DEBUG_STACK_USAGE is not set

#
# Security options
#
CONFIG_KEYS=y
CONFIG_KEYS_DEBUG_PROC_KEYS=y
CONFIG_SECURITY=y
CONFIG_SECURITY_NETWORK=y
CONFIG_SECURITY_NETWORK_XFRM=y
CONFIG_SECURITY_CAPABILITIES=y
# CONFIG_SECURITY_ROOTPLUG is not set
CONFIG_SECURITY_SELINUX=y
CONFIG_SECURITY_SELINUX_BOOTPARAM=y
CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1
CONFIG_SECURITY_SELINUX_DISABLE=y
CONFIG_SECURITY_SELINUX_DEVELOP=y
CONFIG_SECURITY_SELINUX_AVC_STATS=y
CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set
# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX 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=m
CONFIG_CRYPTO_MD4=m
CONFIG_CRYPTO_MD5=y
CONFIG_CRYPTO_SHA1=y
CONFIG_CRYPTO_SHA256=m
CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_TGR192=m
CONFIG_CRYPTO_GF128MUL=m
CONFIG_CRYPTO_ECB=m
CONFIG_CRYPTO_CBC=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_DES=m
CONFIG_CRYPTO_FCRYPT=m
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_TWOFISH_COMMON=m
CONFIG_CRYPTO_TWOFISH_X86_64=m
CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_AES=m
CONFIG_CRYPTO_AES_X86_64=m
CONFIG_CRYPTO_CAST5=m
CONFIG_CRYPTO_CAST6=m
CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_KHAZAD=m
CONFIG_CRYPTO_ANUBIS=m
CONFIG_CRYPTO_DEFLATE=m
CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_CRC32C=m
CONFIG_CRYPTO_CAMELLIA=m
# CONFIG_CRYPTO_TEST is not set
CONFIG_CRYPTO_MPILIB=y
CONFIG_CRYPTO_SIGNATURE=y
CONFIG_CRYPTO_SIGNATURE_DSA=y

#
# Hardware crypto devices
#
CONFIG_XEN=y
CONFIG_XEN_INTERFACE_VERSION=0x00030205

#
# XEN
#
CONFIG_XEN_PRIVILEGED_GUEST=y
# CONFIG_XEN_UNPRIVILEGED_GUEST is not set
CONFIG_XEN_PRIVCMD=y
CONFIG_XEN_XENBUS_DEV=y
CONFIG_XEN_BACKEND=m
CONFIG_XEN_BLKDEV_BACKEND=m
CONFIG_XEN_BLKDEV_TAP=m
CONFIG_XEN_NETDEV_BACKEND=m
# CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set
CONFIG_XEN_NETDEV_LOOPBACK=m
# CONFIG_XEN_PCIDEV_BACKEND is not set
# CONFIG_XEN_TPMDEV_BACKEND is not set
CONFIG_XEN_BLKDEV_FRONTEND=m
CONFIG_XEN_NETDEV_FRONTEND=m
CONFIG_XEN_FRAMEBUFFER=y
CONFIG_XEN_KEYBOARD=y
CONFIG_XEN_SCRUB_PAGES=y
# CONFIG_XEN_DISABLE_SERIAL is not set
CONFIG_XEN_SYSFS=y
CONFIG_XEN_COMPAT_030002_AND_LATER=y
# CONFIG_XEN_COMPAT_030004_AND_LATER is not set
# CONFIG_XEN_COMPAT_LATEST_ONLY is not set
CONFIG_XEN_COMPAT=0x030002
CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y
CONFIG_NO_IDLE_HZ=y
CONFIG_XEN_SMPBOOT=y

#
# Library routines
#
CONFIG_BITREVERSE=y
CONFIG_CRC_CCITT=m
CONFIG_CRC16=m
CONFIG_CRC_ITU_T=m
CONFIG_CRC32=y
CONFIG_LIBCRC32C=m
CONFIG_ZLIB_INFLATE=y
CONFIG_ZLIB_DEFLATE=m
CONFIG_GENERIC_ALLOCATOR=y
CONFIG_REED_SOLOMON=m
CONFIG_REED_SOLOMON_DEC16=y
CONFIG_TEXTSEARCH=y
CONFIG_TEXTSEARCH_KMP=m
CONFIG_TEXTSEARCH_BM=m
CONFIG_TEXTSEARCH_FSM=m
CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y


***** Error reading new file: [Errno 2] No such file or directory: 'kernel.spec'
linux-2.6-2110_scsi-sd-printing.patch:

--- NEW FILE linux-2.6-2110_scsi-sd-printing.patch ---
>From e73aec8247032ee730b5f38edf48922c4f72522e Mon Sep 17 00:00:00 2001
From: Martin K. Petersen <martin.petersen at oracle.com>
Date: Tue, 27 Feb 2007 22:40:55 -0500
Subject: [PATCH] [SCSI] sd: make printing use a common prefix

Make SCSI disk printing more consistent:

 - Define sd_printk(), sd_print_sense_hdr() and sd_print_result()

 - Move relevant header bits into sd.h

 - Remove all the legacy disk_name passing and use scsi_disk pointers
   where possible

 - Switch printk() lines to the new sd_ functions so that output is
   consistent

Signed-off-by: Martin K. Petersen <martin.petersen at oracle.com>
Signed-off-by: James Bottomley <James.Bottomley at SteelEye.com>
---
 drivers/scsi/sd.c |  253 ++++++++++++++++++++---------------------------------
 include/scsi/sd.h |   70 +++++++++++++++
 2 files changed, 165 insertions(+), 158 deletions(-)
 create mode 100644 include/scsi/sd.h

diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 5a8f55f..b5562b8 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -58,16 +58,10 @@
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_ioctl.h>
 #include <scsi/scsicam.h>
+#include <scsi/sd.h>
 
 #include "scsi_logging.h"
 
-/*
- * More than enough for everybody ;)  The huge number of majors
- * is a leftover from 16bit dev_t days, we don't really need that
- * much numberspace.
- */
-#define SD_MAJORS	16
-
 MODULE_AUTHOR("Eric Youngdale");
 MODULE_DESCRIPTION("SCSI disk (sd) driver");
 MODULE_LICENSE("GPL");
@@ -89,45 +83,6 @@ MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK13_MAJOR);
 MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK14_MAJOR);
 MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_DISK15_MAJOR);
 
-/*
- * This is limited by the naming scheme enforced in sd_probe,
- * add another character to it if you really need more disks.
- */
-#define SD_MAX_DISKS	(((26 * 26) + 26 + 1) * 26)
-
-/*
- * Time out in seconds for disks and Magneto-opticals (which are slower).
- */
-#define SD_TIMEOUT		(30 * HZ)
-#define SD_MOD_TIMEOUT		(75 * HZ)
-
-/*
- * Number of allowed retries
- */
-#define SD_MAX_RETRIES		5
-#define SD_PASSTHROUGH_RETRIES	1
-
-/*
- * Size of the initial data buffer for mode and read capacity data
- */
-#define SD_BUF_SIZE		512
-
-struct scsi_disk {
-	struct scsi_driver *driver;	/* always &sd_template */
-	struct scsi_device *device;
-	struct class_device cdev;
-	struct gendisk	*disk;
-	unsigned int	openers;	/* protected by BKL for now, yuck */
-	sector_t	capacity;	/* size in 512-byte sectors */
-	u32		index;
-	u8		media_present;
-	u8		write_prot;
-	unsigned	WCE : 1;	/* state of disk WCE bit */
-	unsigned	RCD : 1;	/* state of disk RCD bit, unused */
-	unsigned	DPOFUA : 1;	/* state of disk DPOFUA bit */
-};
-#define to_scsi_disk(obj) container_of(obj,struct scsi_disk,cdev)
-
 static DEFINE_IDR(sd_index_idr);
 static DEFINE_SPINLOCK(sd_index_lock);
 
@@ -136,20 +91,6 @@ static DEFINE_SPINLOCK(sd_index_lock);
  * object after last put) */
 static DEFINE_MUTEX(sd_ref_mutex);
 
-static int sd_revalidate_disk(struct gendisk *disk);
-static void sd_rw_intr(struct scsi_cmnd * SCpnt);
-
-static int sd_probe(struct device *);
-static int sd_remove(struct device *);
-static void sd_shutdown(struct device *dev);
-static void sd_rescan(struct device *);
-static int sd_init_command(struct scsi_cmnd *);
-static int sd_issue_flush(struct device *, sector_t *);
-static void sd_prepare_flush(request_queue_t *, struct request *);
-static void sd_read_capacity(struct scsi_disk *sdkp, char *diskname,
-			     unsigned char *buffer);
-static void scsi_disk_release(struct class_device *cdev);
-
 static const char *sd_cache_types[] = {
 	"write through", "none", "write back",
 	"write back, no read (daft)"
@@ -199,7 +140,7 @@ static ssize_t sd_store_cache_type(struct class_device *cdev, const char *buf,
 	if (scsi_mode_select(sdp, 1, sp, 8, buffer_data, len, SD_TIMEOUT,
 			     SD_MAX_RETRIES, &data, &sshdr)) {
 		if (scsi_sense_valid(&sshdr))
-			scsi_print_sense_hdr(sdkp->disk->disk_name, &sshdr);
+			sd_print_sense_hdr(sdkp, &sshdr);
 		return -EINVAL;
 	}
 	sd_revalidate_disk(sdkp->disk);
@@ -407,7 +348,8 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
 	 */
 	if (sdp->sector_size == 1024) {
 		if ((block & 1) || (rq->nr_sectors & 1)) {
-			printk(KERN_ERR "sd: Bad block number requested");
+			scmd_printk(KERN_ERR, SCpnt,
+				    "Bad block number requested\n");
 			return 0;
 		} else {
 			block = block >> 1;
@@ -416,7 +358,8 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
 	}
 	if (sdp->sector_size == 2048) {
 		if ((block & 3) || (rq->nr_sectors & 3)) {
-			printk(KERN_ERR "sd: Bad block number requested");
+			scmd_printk(KERN_ERR, SCpnt,
+				    "Bad block number requested\n");
 			return 0;
 		} else {
 			block = block >> 2;
@@ -425,7 +368,8 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
 	}
 	if (sdp->sector_size == 4096) {
 		if ((block & 7) || (rq->nr_sectors & 7)) {
-			printk(KERN_ERR "sd: Bad block number requested");
+			scmd_printk(KERN_ERR, SCpnt,
+				    "Bad block number requested\n");
 			return 0;
 		} else {
 			block = block >> 3;
@@ -442,7 +386,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
 		SCpnt->cmnd[0] = READ_6;
 		SCpnt->sc_data_direction = DMA_FROM_DEVICE;
 	} else {
-		printk(KERN_ERR "sd: Unknown command %x\n", rq->cmd_flags);
+		scmd_printk(KERN_ERR, SCpnt, "Unknown command %x\n", rq->cmd_flags);
 		return 0;
 	}
 
@@ -490,7 +434,8 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
 			 * during operation and thus turned off
 			 * use_10_for_rw.
 			 */
-			printk(KERN_ERR "sd: FUA write on READ/WRITE(6) drive\n");
+			scmd_printk(KERN_ERR, SCpnt,
+				    "FUA write on READ/WRITE(6) drive\n");
 			return 0;
 		}
 
@@ -786,9 +731,10 @@ not_present:
 	return 1;
 }
 
-static int sd_sync_cache(struct scsi_device *sdp)
+static int sd_sync_cache(struct scsi_disk *sdkp)
 {
 	int retries, res;
+	struct scsi_device *sdp = sdkp->device;
 	struct scsi_sense_hdr sshdr;
 
 	if (!scsi_device_online(sdp))
@@ -809,12 +755,10 @@ static int sd_sync_cache(struct scsi_device *sdp)
 			break;
 	}
 
-	if (res) {		printk(KERN_WARNING "FAILED\n  status = %x, message = %02x, "
-				    "host = %d, driver = %02x\n  ",
-				    status_byte(res), msg_byte(res),
-				    host_byte(res), driver_byte(res));
-			if (driver_byte(res) & DRIVER_SENSE)
-				scsi_print_sense_hdr("sd", &sshdr);
+	if (res) {
+		sd_print_result(sdkp, res);
+		if (driver_byte(res) & DRIVER_SENSE)
+			sd_print_sense_hdr(sdkp, &sshdr);
 	}
 
 	return res;
@@ -823,14 +767,13 @@ static int sd_sync_cache(struct scsi_device *sdp)
 static int sd_issue_flush(struct device *dev, sector_t *error_sector)
 {
 	int ret = 0;
-	struct scsi_device *sdp = to_scsi_device(dev);
 	struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev);
 
 	if (!sdkp)
                return -ENODEV;
 
 	if (sdkp->WCE)
-		ret = sd_sync_cache(sdp);
+		ret = sd_sync_cache(sdkp);
 	scsi_disk_put(sdkp);
 	return ret;
 }
@@ -1025,7 +968,7 @@ static int media_not_present(struct scsi_disk *sdkp,
  * spinup disk - called only in sd_revalidate_disk()
  */
 static void
-sd_spinup_disk(struct scsi_disk *sdkp, char *diskname)
+sd_spinup_disk(struct scsi_disk *sdkp)
 {
 	unsigned char cmd[10];
 	unsigned long spintime_expire = 0;
@@ -1069,9 +1012,10 @@ sd_spinup_disk(struct scsi_disk *sdkp, char *diskname)
 		if ((driver_byte(the_result) & DRIVER_SENSE) == 0) {
 			/* no sense, TUR either succeeded or failed
 			 * with a status error */
-			if(!spintime && !scsi_status_is_good(the_result))
-				printk(KERN_NOTICE "%s: Unit Not Ready, "
-				       "error = 0x%x\n", diskname, the_result);
+			if(!spintime && !scsi_status_is_good(the_result)) {
+				sd_printk(KERN_NOTICE, sdkp, "Unit Not Ready\n");
+				sd_print_result(sdkp, the_result);
+			}
 			break;
 		}
 					
@@ -1096,8 +1040,7 @@ sd_spinup_disk(struct scsi_disk *sdkp, char *diskname)
 		 */
 		} else if (sense_valid && sshdr.sense_key == NOT_READY) {
 			if (!spintime) {
-				printk(KERN_NOTICE "%s: Spinning up disk...",
-				       diskname);
+				sd_printk(KERN_NOTICE, sdkp, "Spinning up disk...");
 				cmd[0] = START_STOP;
 				cmd[1] = 1;	/* Return immediately */
 				memset((void *) &cmd[2], 0, 8);
@@ -1130,9 +1073,8 @@ sd_spinup_disk(struct scsi_disk *sdkp, char *diskname)
 			/* we don't understand the sense code, so it's
 			 * probably pointless to loop */
 			if(!spintime) {
-				printk(KERN_NOTICE "%s: Unit Not Ready, "
-					"sense:\n", diskname);
-				scsi_print_sense_hdr("", &sshdr);
+				sd_printk(KERN_NOTICE, sdkp, "Unit Not Ready\n");
+				sd_print_sense_hdr(sdkp, &sshdr);
 			}
 			break;
 		}
@@ -1151,8 +1093,7 @@ sd_spinup_disk(struct scsi_disk *sdkp, char *diskname)
  * read disk capacity
  */
 static void
-sd_read_capacity(struct scsi_disk *sdkp, char *diskname,
-		 unsigned char *buffer)
+sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer)
 {
 	unsigned char cmd[16];
 	int the_result, retries;
@@ -1191,18 +1132,12 @@ repeat:
 	} while (the_result && retries);
 
 	if (the_result && !longrc) {
-		printk(KERN_NOTICE "%s : READ CAPACITY failed.\n"
-		       "%s : status=%x, message=%02x, host=%d, driver=%02x \n",
-		       diskname, diskname,
-		       status_byte(the_result),
-		       msg_byte(the_result),
-		       host_byte(the_result),
-		       driver_byte(the_result));
-
+		sd_printk(KERN_NOTICE, sdkp, "READ CAPACITY failed\n");
+		sd_print_result(sdkp, the_result);
 		if (driver_byte(the_result) & DRIVER_SENSE)
-			scsi_print_sense_hdr("sd", &sshdr);
+			sd_print_sense_hdr(sdkp, &sshdr);
 		else
-			printk("%s : sense not available. \n", diskname);
+			sd_printk(KERN_NOTICE, sdkp, "Sense not available.\n");
 
 		/* Set dirty bit for removable devices if not ready -
 		 * sometimes drives will not report this properly. */
@@ -1218,16 +1153,10 @@ repeat:
 		return;
 	} else if (the_result && longrc) {
 		/* READ CAPACITY(16) has been failed */
-		printk(KERN_NOTICE "%s : READ CAPACITY(16) failed.\n"
-		       "%s : status=%x, message=%02x, host=%d, driver=%02x \n",
-		       diskname, diskname,
-		       status_byte(the_result),
-		       msg_byte(the_result),
-		       host_byte(the_result),
-		       driver_byte(the_result));
-		printk(KERN_NOTICE "%s : use 0xffffffff as device size\n",
-		       diskname);
-		
+		sd_printk(KERN_NOTICE, sdkp, "READ CAPACITY(16) failed\n");
+		sd_print_result(sdkp, the_result);
+		sd_printk(KERN_NOTICE, sdkp, "Use 0xffffffff as device size\n");
+
 		sdkp->capacity = 1 + (sector_t) 0xffffffff;		
 		goto got_data;
 	}	
@@ -1238,14 +1167,14 @@ repeat:
 		if (buffer[0] == 0xff && buffer[1] == 0xff &&
 		    buffer[2] == 0xff && buffer[3] == 0xff) {
 			if(sizeof(sdkp->capacity) > 4) {
-				printk(KERN_NOTICE "%s : very big device. try to use"
-				       " READ CAPACITY(16).\n", diskname);
+				sd_printk(KERN_NOTICE, sdkp, "Very big device. "
+					  "Trying to use READ CAPACITY(16).\n");
 				longrc = 1;
 				goto repeat;
 			}
-			printk(KERN_ERR "%s: too big for this kernel.  Use a "
-			       "kernel compiled with support for large block "
-			       "devices.\n", diskname);
+			sd_printk(KERN_ERR, sdkp, "Too big for this kernel. Use "
+				  "a kernel compiled with support for large "
+				  "block devices.\n");
 			sdkp->capacity = 0;
 			goto got_data;
 		}
@@ -1284,8 +1213,8 @@ repeat:
 got_data:
 	if (sector_size == 0) {
 		sector_size = 512;
-		printk(KERN_NOTICE "%s : sector size 0 reported, "
-		       "assuming 512.\n", diskname);
+		sd_printk(KERN_NOTICE, sdkp, "Sector size 0 reported, "
+			  "assuming 512.\n");
 	}
 
 	if (sector_size != 512 &&
@@ -1293,8 +1222,8 @@ got_data:
 	    sector_size != 2048 &&
 	    sector_size != 4096 &&
 	    sector_size != 256) {
-		printk(KERN_NOTICE "%s : unsupported sector size "
-		       "%d.\n", diskname, sector_size);
+		sd_printk(KERN_NOTICE, sdkp, "Unsupported sector size %d.\n",
+			  sector_size);
 		/*
 		 * The user might want to re-format the drive with
 		 * a supported sectorsize.  Once this happens, it
@@ -1327,10 +1256,10 @@ got_data:
 		mb -= sz - 974;
 		sector_div(mb, 1950);
 
-		printk(KERN_NOTICE "SCSI device %s: "
-		       "%llu %d-byte hdwr sectors (%llu MB)\n",
-		       diskname, (unsigned long long)sdkp->capacity,
-		       hard_sector, (unsigned long long)mb);
+		sd_printk(KERN_NOTICE, sdkp,
+			  "%llu %d-byte hardware sectors (%llu MB)\n",
+			  (unsigned long long)sdkp->capacity,
+			  hard_sector, (unsigned long long)mb);
 	}
 
 	/* Rescale capacity to 512-byte units */
@@ -1362,8 +1291,7 @@ sd_do_mode_sense(struct scsi_device *sdp, int dbd, int modepage,
  * called with buffer of length SD_BUF_SIZE
  */
 static void
-sd_read_write_protect_flag(struct scsi_disk *sdkp, char *diskname,
-			   unsigned char *buffer)
+sd_read_write_protect_flag(struct scsi_disk *sdkp, unsigned char *buffer)
 {
 	int res;
 	struct scsi_device *sdp = sdkp->device;
@@ -1371,7 +1299,7 @@ sd_read_write_protect_flag(struct scsi_disk *sdkp, char *diskname,
 
 	set_disk_ro(sdkp->disk, 0);
 	if (sdp->skip_ms_page_3f) {
-		printk(KERN_NOTICE "%s: assuming Write Enabled\n", diskname);
+		sd_printk(KERN_NOTICE, sdkp, "Assuming Write Enabled\n");
 		return;
 	}
 
@@ -1403,15 +1331,16 @@ sd_read_write_protect_flag(struct scsi_disk *sdkp, char *diskname,
 	}
 
 	if (!scsi_status_is_good(res)) {
-		printk(KERN_WARNING
-		       "%s: test WP failed, assume Write Enabled\n", diskname);
+		sd_printk(KERN_WARNING, sdkp,
+			  "Test WP failed, assume Write Enabled\n");
 	} else {
 		sdkp->write_prot = ((data.device_specific & 0x80) != 0);
 		set_disk_ro(sdkp->disk, sdkp->write_prot);
-		printk(KERN_NOTICE "%s: Write Protect is %s\n", diskname,
-		       sdkp->write_prot ? "on" : "off");
-		printk(KERN_DEBUG "%s: Mode Sense: %02x %02x %02x %02x\n",
-		       diskname, buffer[0], buffer[1], buffer[2], buffer[3]);
+		sd_printk(KERN_NOTICE, sdkp, "Write Protect is %s\n",
+			  sdkp->write_prot ? "on" : "off");
+		sd_printk(KERN_DEBUG, sdkp,
+			  "Mode Sense: %02x %02x %02x %02x\n",
+			  buffer[0], buffer[1], buffer[2], buffer[3]);
 	}
 }
 
@@ -1420,8 +1349,7 @@ sd_read_write_protect_flag(struct scsi_disk *sdkp, char *diskname,
  * called with buffer of length SD_BUF_SIZE
  */
 static void
-sd_read_cache_type(struct scsi_disk *sdkp, char *diskname,
-		   unsigned char *buffer)
+sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer)
 {
 	int len = 0, res;
 	struct scsi_device *sdp = sdkp->device;
@@ -1450,8 +1378,7 @@ sd_read_cache_type(struct scsi_disk *sdkp, char *diskname,
 
 	if (!data.header_length) {
 		modepage = 6;
-		printk(KERN_ERR "%s: missing header in MODE_SENSE response\n",
-		       diskname);
+		sd_printk(KERN_ERR, sdkp, "Missing header in MODE_SENSE response\n");
 	}
 
 	/* that went OK, now ask for the proper length */
@@ -1478,13 +1405,12 @@ sd_read_cache_type(struct scsi_disk *sdkp, char *diskname,
 		int offset = data.header_length + data.block_descriptor_length;
 
 		if (offset >= SD_BUF_SIZE - 2) {
-			printk(KERN_ERR "%s: malformed MODE SENSE response",
-				diskname);
+			sd_printk(KERN_ERR, sdkp, "Malformed MODE SENSE response\n");
 			goto defaults;
 		}
 
 		if ((buffer[offset] & 0x3f) != modepage) {
-			printk(KERN_ERR "%s: got wrong page\n", diskname);
+			sd_printk(KERN_ERR, sdkp, "Got wrong page\n");
 			goto defaults;
 		}
 
@@ -1498,14 +1424,13 @@ sd_read_cache_type(struct scsi_disk *sdkp, char *diskname,
 
 		sdkp->DPOFUA = (data.device_specific & 0x10) != 0;
 		if (sdkp->DPOFUA && !sdkp->device->use_10_for_rw) {
-			printk(KERN_NOTICE "SCSI device %s: uses "
-			       "READ/WRITE(6), disabling FUA\n", diskname);
+			sd_printk(KERN_NOTICE, sdkp,
+				  "Uses READ/WRITE(6), disabling FUA\n");
 			sdkp->DPOFUA = 0;
 		}
 
-		printk(KERN_NOTICE "SCSI device %s: "
-		       "write cache: %s, read cache: %s, %s\n",
-		       diskname,
+		sd_printk(KERN_NOTICE, sdkp,
+		       "Write cache: %s, read cache: %s, %s\n",
 		       sdkp->WCE ? "enabled" : "disabled",
 		       sdkp->RCD ? "disabled" : "enabled",
 		       sdkp->DPOFUA ? "supports DPO and FUA"
@@ -1518,15 +1443,13 @@ bad_sense:
 	if (scsi_sense_valid(&sshdr) &&
 	    sshdr.sense_key == ILLEGAL_REQUEST &&
 	    sshdr.asc == 0x24 && sshdr.ascq == 0x0)
-		printk(KERN_NOTICE "%s: cache data unavailable\n",
-		       diskname);	/* Invalid field in CDB */
+		/* Invalid field in CDB */
+		sd_printk(KERN_NOTICE, sdkp, "Cache data unavailable\n");
 	else
-		printk(KERN_ERR "%s: asking for cache data failed\n",
-		       diskname);
+		sd_printk(KERN_ERR, sdkp, "Asking for cache data failed\n");
 
 defaults:
-	printk(KERN_ERR "%s: assuming drive cache: write through\n",
-	       diskname);
+	sd_printk(KERN_ERR, sdkp, "Assuming drive cache: write through\n");
 	sdkp->WCE = 0;
 	sdkp->RCD = 0;
 	sdkp->DPOFUA = 0;
@@ -1555,8 +1478,8 @@ static int sd_revalidate_disk(struct gendisk *disk)
 
 	buffer = kmalloc(SD_BUF_SIZE, GFP_KERNEL | __GFP_DMA);
 	if (!buffer) {
-		printk(KERN_WARNING "(sd_revalidate_disk:) Memory allocation "
-		       "failure.\n");
+		sd_printk(KERN_WARNING, sdkp, "sd_revalidate_disk: Memory "
+			  "allocation failure.\n");
 		goto out;
 	}
 
@@ -1568,16 +1491,16 @@ static int sd_revalidate_disk(struct gendisk *disk)
 	sdkp->WCE = 0;
 	sdkp->RCD = 0;
 
-	sd_spinup_disk(sdkp, disk->disk_name);
+	sd_spinup_disk(sdkp);
 
 	/*
 	 * Without media there is no reason to ask; moreover, some devices
 	 * react badly if we do.
 	 */
 	if (sdkp->media_present) {
-		sd_read_capacity(sdkp, disk->disk_name, buffer);
-		sd_read_write_protect_flag(sdkp, disk->disk_name, buffer);
-		sd_read_cache_type(sdkp, disk->disk_name, buffer);
+		sd_read_capacity(sdkp, buffer);
+		sd_read_write_protect_flag(sdkp, buffer);
+		sd_read_cache_type(sdkp, buffer);
 	}
 
 	/*
@@ -1709,8 +1632,8 @@ static int sd_probe(struct device *dev)
 	dev_set_drvdata(dev, sdkp);
 	add_disk(gd);
 
-	sdev_printk(KERN_NOTICE, sdp, "Attached scsi %sdisk %s\n",
-		    sdp->removable ? "removable " : "", gd->disk_name);
+	sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n",
+		  sdp->removable ? "removable " : "");
 
 	return 0;
 
@@ -1781,16 +1704,14 @@ static void scsi_disk_release(struct class_device *cdev)
  */
 static void sd_shutdown(struct device *dev)
 {
-	struct scsi_device *sdp = to_scsi_device(dev);
 	struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev);
 
 	if (!sdkp)
 		return;         /* this can happen */
 
 	if (sdkp->WCE) {
-		printk(KERN_NOTICE "Synchronizing SCSI cache for disk %s: \n",
-				sdkp->disk->disk_name);
-		sd_sync_cache(sdp);
+		sd_printk(KERN_NOTICE, sdkp, "Synchronizing SCSI cache\n");
+		sd_sync_cache(sdkp);
 	}
 	scsi_disk_put(sdkp);
 }
@@ -1852,3 +1773,19 @@ static void __exit exit_sd(void)
 
 module_init(init_sd);
 module_exit(exit_sd);
+
+static void sd_print_sense_hdr(struct scsi_disk *sdkp,
+			       struct scsi_sense_hdr *sshdr)
+{
+	sd_printk(KERN_INFO, sdkp, "");
+	scsi_show_sense_hdr(sshdr);
+	sd_printk(KERN_INFO, sdkp, "");
+	scsi_show_extd_sense(sshdr->asc, sshdr->ascq);
+}
+
+static void sd_print_result(struct scsi_disk *sdkp, int result)
+{
+	sd_printk(KERN_INFO, sdkp, "");
+	scsi_show_result(result);
+}
+
diff --git a/include/scsi/sd.h b/include/scsi/sd.h
new file mode 100644
index 0000000..82e6a84
--- /dev/null
+++ b/include/scsi/sd.h
@@ -0,0 +1,70 @@
+#ifndef _SCSI_DISK_H
+#define _SCSI_DISK_H
+
+/*
+ * More than enough for everybody ;)  The huge number of majors
+ * is a leftover from 16bit dev_t days, we don't really need that
+ * much numberspace.
+ */
+#define SD_MAJORS	16
+
+/*
+ * This is limited by the naming scheme enforced in sd_probe,
+ * add another character to it if you really need more disks.
+ */
+#define SD_MAX_DISKS	(((26 * 26) + 26 + 1) * 26)
+
+/*
+ * Time out in seconds for disks and Magneto-opticals (which are slower).
+ */
+#define SD_TIMEOUT		(30 * HZ)
+#define SD_MOD_TIMEOUT		(75 * HZ)
+
+/*
+ * Number of allowed retries
+ */
+#define SD_MAX_RETRIES		5
+#define SD_PASSTHROUGH_RETRIES	1
+
+/*
+ * Size of the initial data buffer for mode and read capacity data
+ */
+#define SD_BUF_SIZE		512
+
+struct scsi_disk {
+	struct scsi_driver *driver;	/* always &sd_template */
+	struct scsi_device *device;
+	struct class_device cdev;
+	struct gendisk	*disk;
+	unsigned int	openers;	/* protected by BKL for now, yuck */
+	sector_t	capacity;	/* size in 512-byte sectors */
+	u32		index;
+	u8		media_present;
+	u8		write_prot;
+	unsigned	WCE : 1;	/* state of disk WCE bit */
+	unsigned	RCD : 1;	/* state of disk RCD bit, unused */
+	unsigned	DPOFUA : 1;	/* state of disk DPOFUA bit */
+};
+#define to_scsi_disk(obj) container_of(obj,struct scsi_disk,cdev)
+
+static int  sd_revalidate_disk(struct gendisk *disk);
+static void sd_rw_intr(struct scsi_cmnd * SCpnt);
+static int  sd_probe(struct device *);
+static int  sd_remove(struct device *);
+static void sd_shutdown(struct device *dev);
+static void sd_rescan(struct device *);
+static int  sd_init_command(struct scsi_cmnd *);
+static int  sd_issue_flush(struct device *, sector_t *);
+static void sd_prepare_flush(request_queue_t *, struct request *);
+static void sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer);
+static void scsi_disk_release(struct class_device *cdev);
+static void sd_print_sense_hdr(struct scsi_disk *, struct scsi_sense_hdr *);
+static void sd_print_result(struct scsi_disk *, int);
+
+#define sd_printk(prefix, sdsk, fmt, a...)				\
+        (sdsk)->disk ?							\
+	sdev_printk(prefix, (sdsk)->device, "[%s] " fmt,		\
+		    (sdsk)->disk->disk_name, ##a) :			\
+	sdev_printk(prefix, (sdsk)->device, fmt, ##a)
+
+#endif /* _SCSI_DISK_H */
-- 
1.5.1.4


linux-2.6-2111_sd-start-stop.patch:

--- NEW FILE linux-2.6-2111_sd-start-stop.patch ---
>From c3c94c5a2fb43a654e777f509d5032b0db8ed09f Mon Sep 17 00:00:00 2001
From: Tejun Heo <htejun at gmail.com>
Date: Wed, 21 Mar 2007 00:13:59 +0900
Subject: [PATCH] [SCSI] sd: implement START/STOP management

Implement SBC START/STOP management.  sdev->mange_start_stop is added.
When it's set to one, sd STOPs the device on suspend and shutdown and
STARTs it on resume.  sdev->manage_start_stop defaults is in sdev
instead of scsi_disk cdev to allow ->slave_config() override the
default configuration but is exported under scsi_disk sysfs node as
sdev->allow_restart is.

When manage_start_stop is zero (the default value), this patch doesn't
introduce any behavior change.

Signed-off-by: Tejun Heo <htejun at gmail.com>

Rejections fixed and
Signed-off-by: James Bottomley <James.Bottomley at SteelEye.com>
---
 drivers/scsi/scsi_sysfs.c  |   31 ++++++++++++--
 drivers/scsi/sd.c          |  101 ++++++++++++++++++++++++++++++++++++++++++++
 include/scsi/scsi_device.h |    1 +
 include/scsi/sd.h          |    2 +
 4 files changed, 131 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index c275dca..96db51c 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -278,6 +278,7 @@ static int scsi_bus_match(struct device *dev, struct device_driver *gendrv)
 
 static int scsi_bus_suspend(struct device * dev, pm_message_t state)
 {
+	struct device_driver *drv = dev->driver;
 	struct scsi_device *sdev = to_scsi_device(dev);
 	struct scsi_host_template *sht = sdev->host->hostt;
 	int err;
@@ -286,23 +287,45 @@ static int scsi_bus_suspend(struct device * dev, pm_message_t state)
 	if (err)
 		return err;
 
-	if (sht->suspend)
+	/* call HLD suspend first */
+	if (drv && drv->suspend) {
+		err = drv->suspend(dev, state);
+		if (err)
+			return err;
+	}
+
+	/* then, call host suspend */
+	if (sht->suspend) {
 		err = sht->suspend(sdev, state);
+		if (err) {
+			if (drv && drv->resume)
+				drv->resume(dev);
+			return err;
+		}
+	}
 
-	return err;
+	return 0;
 }
 
 static int scsi_bus_resume(struct device * dev)
 {
+	struct device_driver *drv = dev->driver;
 	struct scsi_device *sdev = to_scsi_device(dev);
 	struct scsi_host_template *sht = sdev->host->hostt;
-	int err = 0;
+	int err = 0, err2 = 0;
 
+	/* call host resume first */
 	if (sht->resume)
 		err = sht->resume(sdev);
 
+	/* then, call HLD resume */
+	if (drv && drv->resume)
+		err2 = drv->resume(dev);
+
 	scsi_device_resume(sdev);
-	return err;
+
+	/* favor LLD failure */
+	return err ? err : err2;;
 }
 
 struct bus_type scsi_bus_type = {
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 3dda77c..49a94ae 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -147,6 +147,20 @@ static ssize_t sd_store_cache_type(struct class_device *cdev, const char *buf,
 	return count;
 }
 
+static ssize_t sd_store_manage_start_stop(struct class_device *cdev,
+					  const char *buf, size_t count)
+{
+	struct scsi_disk *sdkp = to_scsi_disk(cdev);
+	struct scsi_device *sdp = sdkp->device;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EACCES;
+
+	sdp->manage_start_stop = simple_strtoul(buf, NULL, 10);
+
+	return count;
+}
+
 static ssize_t sd_store_allow_restart(struct class_device *cdev, const char *buf,
 				      size_t count)
 {
@@ -179,6 +193,14 @@ static ssize_t sd_show_fua(struct class_device *cdev, char *buf)
 	return snprintf(buf, 20, "%u\n", sdkp->DPOFUA);
 }
 
+static ssize_t sd_show_manage_start_stop(struct class_device *cdev, char *buf)
+{
+	struct scsi_disk *sdkp = to_scsi_disk(cdev);
+	struct scsi_device *sdp = sdkp->device;
+
+	return snprintf(buf, 20, "%u\n", sdp->manage_start_stop);
+}
+
 static ssize_t sd_show_allow_restart(struct class_device *cdev, char *buf)
 {
 	struct scsi_disk *sdkp = to_scsi_disk(cdev);
@@ -192,6 +214,8 @@ static struct class_device_attribute sd_disk_attrs[] = {
 	__ATTR(FUA, S_IRUGO, sd_show_fua, NULL),
 	__ATTR(allow_restart, S_IRUGO|S_IWUSR, sd_show_allow_restart,
 	       sd_store_allow_restart),
+	__ATTR(manage_start_stop, S_IRUGO|S_IWUSR, sd_show_manage_start_stop,
+	       sd_store_manage_start_stop),
 	__ATTR_NULL,
 };
 
@@ -208,6 +232,8 @@ static struct scsi_driver sd_template = {
 		.name		= "sd",
 		.probe		= sd_probe,
 		.remove		= sd_remove,
+		.suspend	= sd_suspend,
+		.resume		= sd_resume,
 		.shutdown	= sd_shutdown,
 	},
 	.rescan			= sd_rescan,
@@ -1707,6 +1733,32 @@ static void scsi_disk_release(struct class_device *cdev)
 	kfree(sdkp);
 }
 
+static int sd_start_stop_device(struct scsi_device *sdp, int start)
+{
+	unsigned char cmd[6] = { START_STOP };	/* START_VALID */
+	struct scsi_sense_hdr sshdr;
+	int res;
+
+	if (start)
+		cmd[4] |= 1;	/* START */
+
+	if (!scsi_device_online(sdp))
+		return -ENODEV;
+
+	res = scsi_execute_req(sdp, cmd, DMA_NONE, NULL, 0, &sshdr,
+			       SD_TIMEOUT, SD_MAX_RETRIES);
+	if (res) {
+		printk(KERN_WARNING "FAILED\n  status = %x, message = %02x, "
+		       "host = %d, driver = %02x\n  ",
+		       status_byte(res), msg_byte(res),
+		       host_byte(res), driver_byte(res));
+		if (driver_byte(res) & DRIVER_SENSE)
+			scsi_print_sense_hdr("sd", &sshdr);
+	}
+
+	return res;
+}
+
 /*
  * Send a SYNCHRONIZE CACHE instruction down to the device through
  * the normal SCSI command structure.  Wait for the command to
@@ -1714,6 +1766,7 @@ static void scsi_disk_release(struct class_device *cdev)
  */
 static void sd_shutdown(struct device *dev)
 {
+	struct scsi_device *sdp = to_scsi_device(dev);
 	struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev);
 
 	if (!sdkp)
@@ -1723,9 +1776,57 @@ static void sd_shutdown(struct device *dev)
 		sd_printk(KERN_NOTICE, sdkp, "Synchronizing SCSI cache\n");
 		sd_sync_cache(sdkp);
 	}
+
+	if (system_state != SYSTEM_RESTART && sdp->manage_start_stop) {
+		printk(KERN_NOTICE "Stopping disk %s: \n",
+		       sdkp->disk->disk_name);
+		sd_start_stop_device(sdp, 0);
+	}
+
 	scsi_disk_put(sdkp);
 }
 
+static int sd_suspend(struct device *dev, pm_message_t mesg)
+{
+	struct scsi_device *sdp = to_scsi_device(dev);
+	struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev);
+	int ret;
+
+	if (!sdkp)
+		return 0;	/* this can happen */
+
+	if (sdkp->WCE) {
+		printk(KERN_NOTICE "Synchronizing SCSI cache for disk %s: \n",
+				sdkp->disk->disk_name);
+		ret = sd_sync_cache(sdkp);
+		if (ret)
+			return ret;
+	}
+
+	if (mesg.event == PM_EVENT_SUSPEND && sdp->manage_start_stop) {
+		printk(KERN_NOTICE "Stopping disk %s: \n",
+		       sdkp->disk->disk_name);
+		ret = sd_start_stop_device(sdp, 0);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int sd_resume(struct device *dev)
+{
+	struct scsi_device *sdp = to_scsi_device(dev);
+	struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev);
+
+	if (!sdp->manage_start_stop)
+		return 0;
+
+	printk(KERN_NOTICE "Starting disk %s: \n", sdkp->disk->disk_name);
+
+	return sd_start_stop_device(sdp, 1);
+}
+
 /**
  *	init_sd - entry point for this driver (both when built in or when
  *	a module).
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index c86e6ce..b05cd3b 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -120,6 +120,7 @@ struct scsi_device {
 	unsigned use_192_bytes_for_3f:1; /* ask for 192 bytes from page 0x3f */
 	unsigned no_start_on_add:1;	/* do not issue start on add */
 	unsigned allow_restart:1; /* issue START_UNIT in error handler */
+	unsigned manage_start_stop:1;	/* Let HLD (sd) manage start/stop */
 	unsigned no_uld_attach:1; /* disable connecting to upper level drivers */
 	unsigned select_no_atn:1;
 	unsigned fix_capacity:1;	/* READ_CAPACITY is too high by 1 */
diff --git a/include/scsi/sd.h b/include/scsi/sd.h
index 82e6a84..5261488 100644
--- a/include/scsi/sd.h
+++ b/include/scsi/sd.h
@@ -52,6 +52,8 @@ static void sd_rw_intr(struct scsi_cmnd * SCpnt);
 static int  sd_probe(struct device *);
 static int  sd_remove(struct device *);
 static void sd_shutdown(struct device *dev);
+static int sd_suspend(struct device *dev, pm_message_t state);
+static int sd_resume(struct device *dev);
 static void sd_rescan(struct device *);
 static int  sd_init_command(struct scsi_cmnd *);
 static int  sd_issue_flush(struct device *, sector_t *);
-- 
1.5.1.4


linux-2.6-2112_libata-suspend.patch:

--- NEW FILE linux-2.6-2112_libata-suspend.patch ---
>From 9666f4009c22f6520ac3fb8a19c9e32ab973e828 Mon Sep 17 00:00:00 2001
From: Tejun Heo <htejun at gmail.com>
Date: Fri, 4 May 2007 21:27:47 +0200
Subject: [PATCH] libata: reimplement suspend/resume support using sdev->manage_start_stop

Reimplement suspend/resume support using sdev->manage_start_stop.

* Device suspend/resume is now SCSI layer's responsibility and the
  code is simplified a lot.

* DPM is dropped.  This also simplifies code a lot.  Suspend/resume
  status is port-wide now.

* ata_scsi_device_suspend/resume() and ata_dev_ready() removed.

* Resume now has to wait for disk to spin up before proceeding.  I
  couldn't find easy way out as libata is in EH waiting for the
  disk to be ready and sd is waiting for EH to complete to issue
  START_STOP.

* sdev->manage_start_stop is set to 1 in ata_scsi_slave_config().
  This fixes spindown on shutdown and suspend-to-disk.

Signed-off-by: Tejun Heo <htejun at gmail.com>
Signed-off-by: Jeff Garzik <jeff at garzik.org>
---
 drivers/ata/ahci.c              |    4 -
 drivers/ata/ata_generic.c       |    6 +-
 drivers/ata/ata_piix.c          |    4 -
 drivers/ata/libata-core.c       |   39 +------
 drivers/ata/libata-eh.c         |  237 +--------------------------------------
 drivers/ata/libata-scsi.c       |  129 +---------------------
 drivers/ata/pata_ali.c          |    4 -
 drivers/ata/pata_amd.c          |    4 -
 drivers/ata/pata_atiixp.c       |    4 -
 drivers/ata/pata_cmd640.c       |    4 -
 drivers/ata/pata_cmd64x.c       |    4 -
 drivers/ata/pata_cs5520.c       |    4 -
 drivers/ata/pata_cs5530.c       |    4 -
 drivers/ata/pata_cs5535.c       |    4 -
 drivers/ata/pata_cypress.c      |    4 -
 drivers/ata/pata_efar.c         |    4 -
 drivers/ata/pata_hpt366.c       |    4 -
 drivers/ata/pata_hpt3x3.c       |    4 -
 drivers/ata/pata_it8213.c       |    4 -
 drivers/ata/pata_it821x.c       |    4 -
 drivers/ata/pata_ixp4xx_cf.c    |    2 +-
 drivers/ata/pata_jmicron.c      |    4 -
 drivers/ata/pata_marvell.c      |    4 -
 drivers/ata/pata_mpc52xx.c      |    4 -
 drivers/ata/pata_mpiix.c        |    4 -
 drivers/ata/pata_netcell.c      |    4 -
 drivers/ata/pata_ns87410.c      |    4 -
 drivers/ata/pata_oldpiix.c      |    4 -
 drivers/ata/pata_opti.c         |    4 -
 drivers/ata/pata_optidma.c      |    4 -
 drivers/ata/pata_pdc202xx_old.c |    4 -
 drivers/ata/pata_radisys.c      |    4 -
 drivers/ata/pata_rz1000.c       |    6 +-
 drivers/ata/pata_sc1200.c       |    4 -
 drivers/ata/pata_scc.c          |    4 -
 drivers/ata/pata_serverworks.c  |    4 -
 drivers/ata/pata_sil680.c       |    4 -
 drivers/ata/pata_sis.c          |    4 -
 drivers/ata/pata_triflex.c      |    4 -
 drivers/ata/pata_via.c          |    4 -
 drivers/ata/sata_inic162x.c     |    4 -
 drivers/ata/sata_nv.c           |    8 --
 drivers/ata/sata_sil.c          |    4 -
 drivers/ata/sata_sil24.c        |    4 -
 include/linux/libata.h          |   14 +--
 45 files changed, 14 insertions(+), 575 deletions(-)

Index: linux-2.6.21-gentoo-r1/drivers/ata/ahci.c
===================================================================
--- linux-2.6.21-gentoo-r1.orig/drivers/ata/ahci.c
+++ linux-2.6.21-gentoo-r1/drivers/ata/ahci.c
@@ -245,10 +245,6 @@ static struct scsi_host_template ahci_sh
 	.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 ahci_ops = {
Index: linux-2.6.21-gentoo-r1/drivers/ata/ata_generic.c
===================================================================
--- linux-2.6.21-gentoo-r1.orig/drivers/ata/ata_generic.c
+++ linux-2.6.21-gentoo-r1/drivers/ata/ata_generic.c
@@ -83,7 +83,7 @@ static int generic_set_mode(struct ata_p
 
 	for (i = 0; i < ATA_MAX_DEVICES; i++) {
 		struct ata_device *dev = &ap->device[i];
-		if (ata_dev_ready(dev)) {
+		if (ata_dev_enabled(dev)) {
 			/* We don't really care */
 			dev->pio_mode = XFER_PIO_0;
 			dev->dma_mode = XFER_MW_DMA_0;
@@ -119,10 +119,6 @@ static struct scsi_host_template generic
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
 	.bios_param		= ata_std_bios_param,
-#ifdef CONFIG_PM
-	.resume			= ata_scsi_device_resume,
-	.suspend		= ata_scsi_device_suspend,
-#endif
 };
 
 static struct ata_port_operations generic_port_ops = {
Index: linux-2.6.21-gentoo-r1/drivers/ata/ata_piix.c
===================================================================
--- linux-2.6.21-gentoo-r1.orig/drivers/ata/ata_piix.c
+++ linux-2.6.21-gentoo-r1/drivers/ata/ata_piix.c
@@ -275,10 +275,6 @@ static struct scsi_host_template piix_sh
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
 	.bios_param		= ata_std_bios_param,
-#ifdef CONFIG_PM
-	.resume			= ata_scsi_device_resume,
-	.suspend		= ata_scsi_device_suspend,
-#endif
 };
 
 static const struct ata_port_operations piix_pata_ops = {
Index: linux-2.6.21-gentoo-r1/drivers/ata/libata-core.c
===================================================================
--- linux-2.6.21-gentoo-r1.orig/drivers/ata/libata-core.c
+++ linux-2.6.21-gentoo-r1/drivers/ata/libata-core.c
@@ -2563,7 +2563,7 @@ int ata_set_mode(struct ata_port *ap, st
 		dev = &ap->device[i];
 
 		/* don't update suspended devices' xfer mode */
-		if (!ata_dev_ready(dev))
+		if (!ata_dev_enabled(dev))
 			continue;
 
 		rc = ata_dev_set_mode(dev);
@@ -5460,37 +5460,11 @@ static int ata_host_request_pm(struct at
  */
 int ata_host_suspend(struct ata_host *host, pm_message_t mesg)
 {
-	int i, j, rc;
+	int rc;
 
 	rc = ata_host_request_pm(host, mesg, 0, ATA_EHI_QUIET, 1);
-	if (rc)
-		goto fail;
-
-	/* EH is quiescent now.  Fail if we have any ready device.
-	 * This happens if hotplug occurs between completion of device
-	 * suspension and here.
-	 */
-	for (i = 0; i < host->n_ports; i++) {
-		struct ata_port *ap = host->ports[i];
-
-		for (j = 0; j < ATA_MAX_DEVICES; j++) {
-			struct ata_device *dev = &ap->device[j];
-
-			if (ata_dev_ready(dev)) {
-				ata_port_printk(ap, KERN_WARNING,
-						"suspend failed, device %d "
-						"still active\n", dev->devno);
-				rc = -EBUSY;
-				goto fail;
-			}
-		}
-	}
-
-	host->dev->power.power_state = mesg;
-	return 0;
-
- fail:
-	ata_host_resume(host);
+	if (rc == 0)
+		host->dev->power.power_state = mesg;
 	return rc;
 }
 
@@ -6442,11 +6416,6 @@ EXPORT_SYMBOL_GPL(ata_pci_default_filter
 EXPORT_SYMBOL_GPL(ata_pci_clear_simplex);
 #endif /* CONFIG_PCI */
 
-#ifdef CONFIG_PM
-EXPORT_SYMBOL_GPL(ata_scsi_device_suspend);
-EXPORT_SYMBOL_GPL(ata_scsi_device_resume);
-#endif /* CONFIG_PM */
-
 EXPORT_SYMBOL_GPL(ata_eng_timeout);
 EXPORT_SYMBOL_GPL(ata_port_schedule_eh);
 EXPORT_SYMBOL_GPL(ata_port_abort);
Index: linux-2.6.21-gentoo-r1/drivers/ata/libata-eh.c
===================================================================
--- linux-2.6.21-gentoo-r1.orig/drivers/ata/libata-eh.c
+++ linux-2.6.21-gentoo-r1/drivers/ata/libata-eh.c
@@ -55,29 +55,12 @@ static void ata_eh_finish(struct ata_por
 #ifdef CONFIG_PM
 static void ata_eh_handle_port_suspend(struct ata_port *ap);
 static void ata_eh_handle_port_resume(struct ata_port *ap);
-static int ata_eh_suspend(struct ata_port *ap,
-			  struct ata_device **r_failed_dev);
-static void ata_eh_prep_resume(struct ata_port *ap);
-static int ata_eh_resume(struct ata_port *ap, struct ata_device **r_failed_dev);
 #else /* CONFIG_PM */
 static void ata_eh_handle_port_suspend(struct ata_port *ap)
 { }
 
 static void ata_eh_handle_port_resume(struct ata_port *ap)
 { }
-
-static int ata_eh_suspend(struct ata_port *ap, struct ata_device **r_failed_dev)
-{
-	return 0;
-}
-
-static void ata_eh_prep_resume(struct ata_port *ap)
-{ }
-
-static int ata_eh_resume(struct ata_port *ap, struct ata_device **r_failed_dev)
-{
-	return 0;
-}
 #endif /* CONFIG_PM */
 
 static void ata_ering_record(struct ata_ering *ering, int is_io,
@@ -1762,7 +1745,7 @@ static int ata_eh_revalidate_and_attach(
 		if (ehc->i.flags & ATA_EHI_DID_RESET)
 			readid_flags |= ATA_READID_POSTRESET;
 
-		if (action & ATA_EH_REVALIDATE && ata_dev_ready(dev)) {
+		if ((action & ATA_EH_REVALIDATE) && ata_dev_enabled(dev)) {
 			if (ata_port_offline(ap)) {
 				rc = -EIO;
 				goto err;
@@ -1839,166 +1822,6 @@ static int ata_eh_revalidate_and_attach(
 	return rc;
 }
 
-#ifdef CONFIG_PM
-/**
- *	ata_eh_suspend - handle suspend EH action
- *	@ap: target host port
- *	@r_failed_dev: result parameter to indicate failing device
- *
- *	Handle suspend EH action.  Disk devices are spinned down and
- *	other types of devices are just marked suspended.  Once
- *	suspended, no EH action to the device is allowed until it is
- *	resumed.
- *
- *	LOCKING:
- *	Kernel thread context (may sleep).
- *
- *	RETURNS:
- *	0 on success, -errno otherwise
- */
-static int ata_eh_suspend(struct ata_port *ap, struct ata_device **r_failed_dev)
-{
-	struct ata_device *dev;
-	int i, rc = 0;
-
-	DPRINTK("ENTER\n");
-
-	for (i = 0; i < ATA_MAX_DEVICES; i++) {
-		unsigned long flags;
-		unsigned int action, err_mask;
-
-		dev = &ap->device[i];
-		action = ata_eh_dev_action(dev);
-
-		if (!ata_dev_enabled(dev) || !(action & ATA_EH_SUSPEND))
-			continue;
-
-		WARN_ON(dev->flags & ATA_DFLAG_SUSPENDED);
-
-		ata_eh_about_to_do(ap, dev, ATA_EH_SUSPEND);
-
-		if (dev->class == ATA_DEV_ATA && !(action & ATA_EH_PM_FREEZE)) {
-			/* flush cache */
-			rc = ata_flush_cache(dev);
-			if (rc)
-				break;
-
-			/* spin down */
-			err_mask = ata_do_simple_cmd(dev, ATA_CMD_STANDBYNOW1);
-			if (err_mask) {
-				ata_dev_printk(dev, KERN_ERR, "failed to "
-					       "spin down (err_mask=0x%x)\n",
-					       err_mask);
-				rc = -EIO;
-				break;
-			}
-		}
-
-		spin_lock_irqsave(ap->lock, flags);
-		dev->flags |= ATA_DFLAG_SUSPENDED;
-		spin_unlock_irqrestore(ap->lock, flags);
-
-		ata_eh_done(ap, dev, ATA_EH_SUSPEND);
-	}
-
-	if (rc)
-		*r_failed_dev = dev;
-
-	DPRINTK("EXIT\n");
-	return rc;
-}
-
-/**
- *	ata_eh_prep_resume - prep for resume EH action
- *	@ap: target host port
- *
- *	Clear SUSPENDED in preparation for scheduled resume actions.
- *	This allows other parts of EH to access the devices being
- *	resumed.
- *
- *	LOCKING:
- *	Kernel thread context (may sleep).
- */
-static void ata_eh_prep_resume(struct ata_port *ap)
-{
-	struct ata_device *dev;
-	unsigned long flags;
-	int i;
-
-	DPRINTK("ENTER\n");
-
-	for (i = 0; i < ATA_MAX_DEVICES; i++) {
-		unsigned int action;
-
-		dev = &ap->device[i];
-		action = ata_eh_dev_action(dev);
-
-		if (!ata_dev_enabled(dev) || !(action & ATA_EH_RESUME))
-			continue;
-
-		spin_lock_irqsave(ap->lock, flags);
-		dev->flags &= ~ATA_DFLAG_SUSPENDED;
-		spin_unlock_irqrestore(ap->lock, flags);
-	}
-
-	DPRINTK("EXIT\n");
-}
-
-/**
- *	ata_eh_resume - handle resume EH action
- *	@ap: target host port
- *	@r_failed_dev: result parameter to indicate failing device
- *
- *	Handle resume EH action.  Target devices are already reset and
- *	revalidated.  Spinning up is the only operation left.
- *
- *	LOCKING:
- *	Kernel thread context (may sleep).
- *
- *	RETURNS:
- *	0 on success, -errno otherwise
- */
-static int ata_eh_resume(struct ata_port *ap, struct ata_device **r_failed_dev)
-{
-	struct ata_device *dev;
-	int i, rc = 0;
-
-	DPRINTK("ENTER\n");
-
-	for (i = 0; i < ATA_MAX_DEVICES; i++) {
-		unsigned int action, err_mask;
-
-		dev = &ap->device[i];
-		action = ata_eh_dev_action(dev);
-
-		if (!ata_dev_enabled(dev) || !(action & ATA_EH_RESUME))
-			continue;
-
-		ata_eh_about_to_do(ap, dev, ATA_EH_RESUME);
-
-		if (dev->class == ATA_DEV_ATA && !(action & ATA_EH_PM_FREEZE)) {
-			err_mask = ata_do_simple_cmd(dev,
-						     ATA_CMD_IDLEIMMEDIATE);
-			if (err_mask) {
-				ata_dev_printk(dev, KERN_ERR, "failed to "
-					       "spin up (err_mask=0x%x)\n",
-					       err_mask);
-				rc = -EIO;
-				break;
-			}
-		}
-
-		ata_eh_done(ap, dev, ATA_EH_RESUME);
-	}
-
-	if (rc)
-		*r_failed_dev = dev;
-
-	DPRINTK("EXIT\n");
-	return 0;
-}
-#endif /* CONFIG_PM */
-
 static int ata_port_nr_enabled(struct ata_port *ap)
 {
 	int i, cnt = 0;
@@ -2024,17 +1847,6 @@ static int ata_eh_skip_recovery(struct a
 	struct ata_eh_context *ehc = &ap->eh_context;
 	int i;
 
-	/* skip if all possible devices are suspended */
-	for (i = 0; i < ata_port_max_devices(ap); i++) {
-		struct ata_device *dev = &ap->device[i];
-
-		if (!(dev->flags & ATA_DFLAG_SUSPENDED))
-			break;
-	}
-
-	if (i == ata_port_max_devices(ap))
-		return 1;
-
 	/* thaw frozen port, resume link and recover failed devices */
 	if ((ap->pflags & ATA_PFLAG_FROZEN) ||
 	    (ehc->i.flags & ATA_EHI_RESUME_LINK) || ata_port_nr_enabled(ap))
@@ -2114,9 +1926,6 @@ static int ata_eh_recover(struct ata_por
 	if (ap->pflags & ATA_PFLAG_UNLOADING)
 		goto out;
 
-	/* prep for resume */
-	ata_eh_prep_resume(ap);
-
 	/* skip EH if possible. */
 	if (ata_eh_skip_recovery(ap))
 		ehc->i.action = 0;
@@ -2144,11 +1953,6 @@ static int ata_eh_recover(struct ata_por
 	if (rc)
 		goto dev_fail;
 
-	/* resume devices */
-	rc = ata_eh_resume(ap, &dev);
-	if (rc)
-		goto dev_fail;
-
 	/* configure transfer mode if necessary */
 	if (ehc->i.flags & ATA_EHI_SETMODE) {
 		rc = ata_set_mode(ap, &dev);
@@ -2157,11 +1961,6 @@ static int ata_eh_recover(struct ata_por
 		ehc->i.flags &= ~ATA_EHI_SETMODE;
 	}
 
-	/* suspend devices */
-	rc = ata_eh_suspend(ap, &dev);
-	if (rc)
-		goto dev_fail;
-
 	goto out;
 
  dev_fail:
@@ -2357,22 +2156,13 @@ static void ata_eh_handle_port_suspend(s
  *
  *	Resume @ap.
  *
- *	This function also waits upto one second until all devices
- *	hanging off this port requests resume EH action.  This is to
- *	prevent invoking EH and thus reset multiple times on resume.
- *
- *	On DPM resume, where some of devices might not be resumed
- *	together, this may delay port resume upto one second, but such
- *	DPM resumes are rare and 1 sec delay isn't too bad.
- *
  *	LOCKING:
  *	Kernel thread context (may sleep).
  */
 static void ata_eh_handle_port_resume(struct ata_port *ap)
 {
-	unsigned long timeout;
 	unsigned long flags;
-	int i, rc = 0;
+	int rc = 0;
 
 	/* are we resuming? */
 	spin_lock_irqsave(ap->lock, flags);
@@ -2383,31 +2173,12 @@ static void ata_eh_handle_port_resume(st
 	}
 	spin_unlock_irqrestore(ap->lock, flags);
 
-	/* spurious? */
-	if (!(ap->pflags & ATA_PFLAG_SUSPENDED))
-		goto done;
+	WARN_ON(!(ap->pflags & ATA_PFLAG_SUSPENDED));
 
 	if (ap->ops->port_resume)
 		rc = ap->ops->port_resume(ap);
 
-	/* give devices time to request EH */
-	timeout = jiffies + HZ; /* 1s max */
-	while (1) {
-		for (i = 0; i < ATA_MAX_DEVICES; i++) {
-			struct ata_device *dev = &ap->device[i];
-			unsigned int action = ata_eh_dev_action(dev);
-
-			if ((dev->flags & ATA_DFLAG_SUSPENDED) &&
-			    !(action & ATA_EH_RESUME))
-				break;
-		}
-
-		if (i == ATA_MAX_DEVICES || time_after(jiffies, timeout))
-			break;
-		msleep(10);
-	}
-
- done:
+	/* report result */
 	spin_lock_irqsave(ap->lock, flags);
 	ap->pflags &= ~(ATA_PFLAG_PM_PENDING | ATA_PFLAG_SUSPENDED);
 	if (ap->pm_result) {
Index: linux-2.6.21-gentoo-r1/drivers/ata/libata-scsi.c
===================================================================
--- linux-2.6.21-gentoo-r1.orig/drivers/ata/libata-scsi.c
+++ linux-2.6.21-gentoo-r1/drivers/ata/libata-scsi.c
@@ -510,133 +510,6 @@ static void ata_dump_status(unsigned id,
 	}
 }
 
-#ifdef CONFIG_PM
-/**
- *	ata_scsi_device_suspend - suspend ATA device associated with sdev
- *	@sdev: the SCSI device to suspend
- *	@mesg: target power management message
- *
- *	Request suspend EH action on the ATA device associated with
- *	@sdev and wait for the operation to complete.
- *
- *	LOCKING:
- *	Kernel thread context (may sleep).
- *
- *	RETURNS:
- *	0 on success, -errno otherwise.
- */
-int ata_scsi_device_suspend(struct scsi_device *sdev, pm_message_t mesg)
-{
-	struct ata_port *ap = ata_shost_to_port(sdev->host);
-	struct ata_device *dev = ata_scsi_find_dev(ap, sdev);
-	unsigned long flags;
-	unsigned int action;
-	int rc = 0;
-
-	if (!dev)
-		goto out;
-
-	spin_lock_irqsave(ap->lock, flags);
-
-	/* wait for the previous resume to complete */
-	while (dev->flags & ATA_DFLAG_SUSPENDED) {
-		spin_unlock_irqrestore(ap->lock, flags);
-		ata_port_wait_eh(ap);
-		spin_lock_irqsave(ap->lock, flags);
-	}
-
-	/* if @sdev is already detached, nothing to do */
-	if (sdev->sdev_state == SDEV_OFFLINE ||
-	    sdev->sdev_state == SDEV_CANCEL || sdev->sdev_state == SDEV_DEL)
-		goto out_unlock;
-
-	/* request suspend */
-	action = ATA_EH_SUSPEND;
-	if (mesg.event != PM_EVENT_SUSPEND)
-		action |= ATA_EH_PM_FREEZE;
-	ap->eh_info.dev_action[dev->devno] |= action;
-	ap->eh_info.flags |= ATA_EHI_QUIET;
-	ata_port_schedule_eh(ap);
-
-	spin_unlock_irqrestore(ap->lock, flags);
-
-	/* wait for EH to do the job */
-	ata_port_wait_eh(ap);
-
-	spin_lock_irqsave(ap->lock, flags);
-
-	/* If @sdev is still attached but the associated ATA device
-	 * isn't suspended, the operation failed.
-	 */
-	if (sdev->sdev_state != SDEV_OFFLINE &&
-	    sdev->sdev_state != SDEV_CANCEL && sdev->sdev_state != SDEV_DEL &&
-	    !(dev->flags & ATA_DFLAG_SUSPENDED))
-		rc = -EIO;
-
- out_unlock:
-	spin_unlock_irqrestore(ap->lock, flags);
- out:
-	if (rc == 0)
-		sdev->sdev_gendev.power.power_state = mesg;
-	return rc;
-}
-
-/**
- *	ata_scsi_device_resume - resume ATA device associated with sdev
- *	@sdev: the SCSI device to resume
- *
- *	Request resume EH action on the ATA device associated with
- *	@sdev and return immediately.  This enables parallel
- *	wakeup/spinup of devices.
- *
- *	LOCKING:
- *	Kernel thread context (may sleep).
- *
- *	RETURNS:
- *	0.
- */
-int ata_scsi_device_resume(struct scsi_device *sdev)
-{
-	struct ata_port *ap = ata_shost_to_port(sdev->host);
-	struct ata_device *dev = ata_scsi_find_dev(ap, sdev);
-	struct ata_eh_info *ehi = &ap->eh_info;
-	unsigned long flags;
-	unsigned int action;
-
-	if (!dev)
-		goto out;
-
-	spin_lock_irqsave(ap->lock, flags);
-
-	/* if @sdev is already detached, nothing to do */
-	if (sdev->sdev_state == SDEV_OFFLINE ||
-	    sdev->sdev_state == SDEV_CANCEL || sdev->sdev_state == SDEV_DEL)
-		goto out_unlock;
-
-	/* request resume */
-	action = ATA_EH_RESUME;
-	if (sdev->sdev_gendev.power.power_state.event == PM_EVENT_SUSPEND)
-		__ata_ehi_hotplugged(ehi);
-	else
-		action |= ATA_EH_PM_FREEZE | ATA_EH_SOFTRESET;
-	ehi->dev_action[dev->devno] |= action;
-
-	/* We don't want autopsy and verbose EH messages.  Disable
-	 * those if we're the only device on this link.
-	 */
-	if (ata_port_max_devices(ap) == 1)
-		ehi->flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET;
-
-	ata_port_schedule_eh(ap);
-
- out_unlock:
-	spin_unlock_irqrestore(ap->lock, flags);
- out:
-	sdev->sdev_gendev.power.power_state = PMSG_ON;
-	return 0;
-}
-#endif /* CONFIG_PM */
-
 /**
  *	ata_to_sense_error - convert ATA error to SCSI error
  *	@id: ATA device number
@@ -929,6 +802,8 @@ int ata_scsi_slave_config(struct scsi_de
 
 	blk_queue_max_phys_segments(sdev->request_queue, LIBATA_MAX_PRD);
 
+	sdev->manage_start_stop = 1;
+
 	if (dev)
 		ata_scsi_dev_config(sdev, dev);
 
Index: linux-2.6.21-gentoo-r1/drivers/ata/pata_ali.c
===================================================================
--- linux-2.6.21-gentoo-r1.orig/drivers/ata/pata_ali.c
+++ linux-2.6.21-gentoo-r1/drivers/ata/pata_ali.c
@@ -345,10 +345,6 @@ static struct scsi_host_template ali_sht
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
 	.bios_param		= ata_std_bios_param,
-#ifdef CONFIG_PM
-	.resume			= ata_scsi_device_resume,
-	.suspend		= ata_scsi_device_suspend,
-#endif
 };
 
 /*
Index: linux-2.6.21-gentoo-r1/drivers/ata/pata_amd.c
===================================================================
--- linux-2.6.21-gentoo-r1.orig/drivers/ata/pata_amd.c
+++ linux-2.6.21-gentoo-r1/drivers/ata/pata_amd.c
@@ -334,10 +334,6 @@ static struct scsi_host_template amd_sht
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
 	.bios_param		= ata_std_bios_param,
-#ifdef CONFIG_PM
-	.resume			= ata_scsi_device_resume,
-	.suspend		= ata_scsi_device_suspend,
-#endif
 };
 
 static struct ata_port_operations amd33_port_ops = {
Index: linux-2.6.21-gentoo-r1/drivers/ata/pata_atiixp.c
===================================================================
--- linux-2.6.21-gentoo-r1.orig/drivers/ata/pata_atiixp.c
+++ linux-2.6.21-gentoo-r1/drivers/ata/pata_atiixp.c
@@ -224,10 +224,6 @@ static struct scsi_host_template atiixp_
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
 	.bios_param		= ata_std_bios_param,
-#ifdef CONFIG_PM
-	.resume			= ata_scsi_device_resume,
-	.suspend		= ata_scsi_device_suspend,
-#endif
 };
 
 static struct ata_port_operations atiixp_port_ops = {
Index: linux-2.6.21-gentoo-r1/drivers/ata/pata_cmd64x.c
===================================================================
--- linux-2.6.21-gentoo-r1.orig/drivers/ata/pata_cmd64x.c
+++ linux-2.6.21-gentoo-r1/drivers/ata/pata_cmd64x.c
@@ -285,10 +285,6 @@ static struct scsi_host_template cmd64x_
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
 	.bios_param		= ata_std_bios_param,
-#ifdef CONFIG_PM
-	.resume			= ata_scsi_device_resume,
-	.suspend		= ata_scsi_device_suspend,
-#endif
 };
 
 static struct ata_port_operations cmd64x_port_ops = {
Index: linux-2.6.21-gentoo-r1/drivers/ata/pata_cs5520.c
===================================================================
--- linux-2.6.21-gentoo-r1.orig/drivers/ata/pata_cs5520.c
+++ linux-2.6.21-gentoo-r1/drivers/ata/pata_cs5520.c
@@ -167,10 +167,6 @@ static struct scsi_host_template cs5520_
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
 	.bios_param		= ata_std_bios_param,
-#ifdef CONFIG_PM
-	.resume			= ata_scsi_device_resume,
-	.suspend		= ata_scsi_device_suspend,
-#endif
 };
 
 static struct ata_port_operations cs5520_port_ops = {
Index: linux-2.6.21-gentoo-r1/drivers/ata/pata_cs5530.c
===================================================================
--- linux-2.6.21-gentoo-r1.orig/drivers/ata/pata_cs5530.c
+++ linux-2.6.21-gentoo-r1/drivers/ata/pata_cs5530.c
@@ -188,10 +188,6 @@ static struct scsi_host_template cs5530_
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
 	.bios_param		= ata_std_bios_param,
-#ifdef CONFIG_PM
-	.resume			= ata_scsi_device_resume,
-	.suspend		= ata_scsi_device_suspend,
-#endif
 };
 
 static struct ata_port_operations cs5530_port_ops = {
Index: linux-2.6.21-gentoo-r1/drivers/ata/pata_cs5535.c
===================================================================
--- linux-2.6.21-gentoo-r1.orig/drivers/ata/pata_cs5535.c
+++ linux-2.6.21-gentoo-r1/drivers/ata/pata_cs5535.c
@@ -185,10 +185,6 @@ static struct scsi_host_template cs5535_
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
 	.bios_param		= ata_std_bios_param,
-#ifdef CONFIG_PM
-	.resume			= ata_scsi_device_resume,
-	.suspend		= ata_scsi_device_suspend,
-#endif
 };
 
 static struct ata_port_operations cs5535_port_ops = {
Index: linux-2.6.21-gentoo-r1/drivers/ata/pata_cypress.c
===================================================================
--- linux-2.6.21-gentoo-r1.orig/drivers/ata/pata_cypress.c
+++ linux-2.6.21-gentoo-r1/drivers/ata/pata_cypress.c
@@ -136,10 +136,6 @@ static struct scsi_host_template cy82c69
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
 	.bios_param		= ata_std_bios_param,
-#ifdef CONFIG_PM
-	.resume			= ata_scsi_device_resume,
-	.suspend		= ata_scsi_device_suspend,
-#endif
 };
 
 static struct ata_port_operations cy82c693_port_ops = {
Index: linux-2.6.21-gentoo-r1/drivers/ata/pata_efar.c
===================================================================
--- linux-2.6.21-gentoo-r1.orig/drivers/ata/pata_efar.c
+++ linux-2.6.21-gentoo-r1/drivers/ata/pata_efar.c
@@ -234,10 +234,6 @@ static struct scsi_host_template efar_sh
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
 	.bios_param		= ata_std_bios_param,
-#ifdef CONFIG_PM
-	.resume			= ata_scsi_device_resume,
-	.suspend		= ata_scsi_device_suspend,
-#endif
 };
 
 static const struct ata_port_operations efar_ops = {
Index: linux-2.6.21-gentoo-r1/drivers/ata/pata_hpt366.c
===================================================================
--- linux-2.6.21-gentoo-r1.orig/drivers/ata/pata_hpt366.c
+++ linux-2.6.21-gentoo-r1/drivers/ata/pata_hpt366.c
@@ -328,10 +328,6 @@ static struct scsi_host_template hpt36x_
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
 	.bios_param		= ata_std_bios_param,
-#ifdef CONFIG_PM
-	.resume			= ata_scsi_device_resume,
-	.suspend		= ata_scsi_device_suspend,
-#endif
 };
 
 /*
Index: linux-2.6.21-gentoo-r1/drivers/ata/pata_hpt3x3.c
===================================================================
--- linux-2.6.21-gentoo-r1.orig/drivers/ata/pata_hpt3x3.c
+++ linux-2.6.21-gentoo-r1/drivers/ata/pata_hpt3x3.c
@@ -119,10 +119,6 @@ static struct scsi_host_template hpt3x3_
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
 	.bios_param		= ata_std_bios_param,
-#ifdef CONFIG_PM
-	.resume			= ata_scsi_device_resume,
-	.suspend		= ata_scsi_device_suspend,
-#endif
 };
 
 static struct ata_port_operations hpt3x3_port_ops = {
Index: linux-2.6.21-gentoo-r1/drivers/ata/pata_it8213.c
===================================================================
--- linux-2.6.21-gentoo-r1.orig/drivers/ata/pata_it8213.c
+++ linux-2.6.21-gentoo-r1/drivers/ata/pata_it8213.c
@@ -246,10 +246,6 @@ static struct scsi_host_template it8213_
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.bios_param		= ata_std_bios_param,
-#ifdef CONFIG_PM
-	.resume			= ata_scsi_device_resume,
-	.suspend		= ata_scsi_device_suspend,
-#endif
 };
 
 static const struct ata_port_operations it8213_ops = {
Index: linux-2.6.21-gentoo-r1/drivers/ata/pata_it821x.c
===================================================================
--- linux-2.6.21-gentoo-r1.orig/drivers/ata/pata_it821x.c
+++ linux-2.6.21-gentoo-r1/drivers/ata/pata_it821x.c
@@ -646,10 +646,6 @@ static struct scsi_host_template it821x_
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
 	.bios_param		= ata_std_bios_param,
-#ifdef CONFIG_PM
-	.resume			= ata_scsi_device_resume,
-	.suspend		= ata_scsi_device_suspend,
-#endif
 };
 
 static struct ata_port_operations it821x_smart_port_ops = {
Index: linux-2.6.21-gentoo-r1/drivers/ata/pata_ixp4xx_cf.c
===================================================================
--- linux-2.6.21-gentoo-r1.orig/drivers/ata/pata_ixp4xx_cf.c
+++ linux-2.6.21-gentoo-r1/drivers/ata/pata_ixp4xx_cf.c
@@ -31,7 +31,7 @@ static int ixp4xx_set_mode(struct ata_po
 
 	for (i = 0; i < ATA_MAX_DEVICES; i++) {
 		struct ata_device *dev = &ap->device[i];
-		if (ata_dev_ready(dev)) {
+		if (ata_dev_enabled(dev)) {
 			ata_dev_printk(dev, KERN_INFO, "configured for PIO0\n");
 			dev->pio_mode = XFER_PIO_0;
 			dev->xfer_mode = XFER_PIO_0;
Index: linux-2.6.21-gentoo-r1/drivers/ata/pata_jmicron.c
===================================================================
--- linux-2.6.21-gentoo-r1.orig/drivers/ata/pata_jmicron.c
+++ linux-2.6.21-gentoo-r1/drivers/ata/pata_jmicron.c
@@ -137,10 +137,6 @@ static struct scsi_host_template jmicron
 	.slave_destroy		= ata_scsi_slave_destroy,
 	/* Use standard CHS mapping rules */
 	.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 jmicron_ops = {
Index: linux-2.6.21-gentoo-r1/drivers/ata/pata_marvell.c
===================================================================
--- linux-2.6.21-gentoo-r1.orig/drivers/ata/pata_marvell.c
+++ linux-2.6.21-gentoo-r1/drivers/ata/pata_marvell.c
@@ -103,10 +103,6 @@ static struct scsi_host_template marvell
 	.slave_destroy		= ata_scsi_slave_destroy,
 	/* Use standard CHS mapping rules */
 	.bios_param		= ata_std_bios_param,
-#ifdef CONFIG_PM
-	.resume			= ata_scsi_device_resume,
-	.suspend		= ata_scsi_device_suspend,
-#endif
 };
 
 static const struct ata_port_operations marvell_ops = {
Index: linux-2.6.21-gentoo-r1/drivers/ata/pata_mpc52xx.c
===================================================================
--- linux-2.6.21-gentoo-r1.orig/drivers/ata/pata_mpc52xx.c
+++ linux-2.6.21-gentoo-r1/drivers/ata/pata_mpc52xx.c
@@ -280,10 +280,6 @@ static struct scsi_host_template mpc52xx
 	.dma_boundary		= ATA_DMA_BOUNDARY,
 	.slave_configure	= ata_scsi_slave_config,
 	.bios_param		= ata_std_bios_param,
-#ifdef CONFIG_PM
-	.suspend		= ata_scsi_device_suspend,
-	.resume			= ata_scsi_device_resume,
-#endif
 };
 
 static struct ata_port_operations mpc52xx_ata_port_ops = {
Index: linux-2.6.21-gentoo-r1/drivers/ata/pata_mpiix.c
===================================================================
--- linux-2.6.21-gentoo-r1.orig/drivers/ata/pata_mpiix.c
+++ linux-2.6.21-gentoo-r1/drivers/ata/pata_mpiix.c
@@ -165,10 +165,6 @@ static struct scsi_host_template mpiix_s
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
 	.bios_param		= ata_std_bios_param,
-#ifdef CONFIG_PM
-	.resume			= ata_scsi_device_resume,
-	.suspend		= ata_scsi_device_suspend,
-#endif
 };
 
 static struct ata_port_operations mpiix_port_ops = {
Index: linux-2.6.21-gentoo-r1/drivers/ata/pata_netcell.c
===================================================================
--- linux-2.6.21-gentoo-r1.orig/drivers/ata/pata_netcell.c
+++ linux-2.6.21-gentoo-r1/drivers/ata/pata_netcell.c
@@ -63,10 +63,6 @@ static struct scsi_host_template netcell
 	.slave_destroy		= ata_scsi_slave_destroy,
 	/* Use standard CHS mapping rules */
 	.bios_param		= ata_std_bios_param,
-#ifdef CONFIG_PM
-	.resume			= ata_scsi_device_resume,
-	.suspend		= ata_scsi_device_suspend,
-#endif
 };
 
 static const struct ata_port_operations netcell_ops = {
Index: linux-2.6.21-gentoo-r1/drivers/ata/pata_ns87410.c
===================================================================
--- linux-2.6.21-gentoo-r1.orig/drivers/ata/pata_ns87410.c
+++ linux-2.6.21-gentoo-r1/drivers/ata/pata_ns87410.c
@@ -157,10 +157,6 @@ static struct scsi_host_template ns87410
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
 	.bios_param		= ata_std_bios_param,
-#ifdef CONFIG_PM
-	.resume			= ata_scsi_device_resume,
-	.suspend		= ata_scsi_device_suspend,
-#endif
 };
 
 static struct ata_port_operations ns87410_port_ops = {
Index: linux-2.6.21-gentoo-r1/drivers/ata/pata_oldpiix.c
===================================================================
--- linux-2.6.21-gentoo-r1.orig/drivers/ata/pata_oldpiix.c
+++ linux-2.6.21-gentoo-r1/drivers/ata/pata_oldpiix.c
@@ -233,10 +233,6 @@ static struct scsi_host_template oldpiix
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
 	.bios_param		= ata_std_bios_param,
-#ifdef CONFIG_PM
-	.resume			= ata_scsi_device_resume,
-	.suspend		= ata_scsi_device_suspend,
-#endif
 };
 
 static const struct ata_port_operations oldpiix_pata_ops = {
Index: linux-2.6.21-gentoo-r1/drivers/ata/pata_opti.c
===================================================================
--- linux-2.6.21-gentoo-r1.orig/drivers/ata/pata_opti.c
+++ linux-2.6.21-gentoo-r1/drivers/ata/pata_opti.c
@@ -179,10 +179,6 @@ static struct scsi_host_template opti_sh
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
 	.bios_param		= ata_std_bios_param,
-#ifdef CONFIG_PM
-	.resume			= ata_scsi_device_resume,
-	.suspend		= ata_scsi_device_suspend,
-#endif
 };
 
 static struct ata_port_operations opti_port_ops = {
Index: linux-2.6.21-gentoo-r1/drivers/ata/pata_optidma.c
===================================================================
--- linux-2.6.21-gentoo-r1.orig/drivers/ata/pata_optidma.c
+++ linux-2.6.21-gentoo-r1/drivers/ata/pata_optidma.c
@@ -360,10 +360,6 @@ static struct scsi_host_template optidma
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
 	.bios_param		= ata_std_bios_param,
-#ifdef CONFIG_PM
-	.resume			= ata_scsi_device_resume,
-	.suspend		= ata_scsi_device_suspend,
-#endif
 };
 
 static struct ata_port_operations optidma_port_ops = {
Index: linux-2.6.21-gentoo-r1/drivers/ata/pata_pdc202xx_old.c
===================================================================
--- linux-2.6.21-gentoo-r1.orig/drivers/ata/pata_pdc202xx_old.c
+++ linux-2.6.21-gentoo-r1/drivers/ata/pata_pdc202xx_old.c
@@ -273,10 +273,6 @@ static struct scsi_host_template pdc202x
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
 	.bios_param		= ata_std_bios_param,
-#ifdef CONFIG_PM
-	.resume			= ata_scsi_device_resume,
-	.suspend		= ata_scsi_device_suspend,
-#endif
 };
 
 static struct ata_port_operations pdc2024x_port_ops = {
Index: linux-2.6.21-gentoo-r1/drivers/ata/pata_radisys.c
===================================================================
--- linux-2.6.21-gentoo-r1.orig/drivers/ata/pata_radisys.c
+++ linux-2.6.21-gentoo-r1/drivers/ata/pata_radisys.c
@@ -228,10 +228,6 @@ static struct scsi_host_template radisys
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
 	.bios_param		= ata_std_bios_param,
-#ifdef CONFIG_PM
-	.resume			= ata_scsi_device_resume,
-	.suspend		= ata_scsi_device_suspend,
-#endif
 };
 
 static const struct ata_port_operations radisys_pata_ops = {
Index: linux-2.6.21-gentoo-r1/drivers/ata/pata_rz1000.c
===================================================================
--- linux-2.6.21-gentoo-r1.orig/drivers/ata/pata_rz1000.c
+++ linux-2.6.21-gentoo-r1/drivers/ata/pata_rz1000.c
@@ -65,7 +65,7 @@ static int rz1000_set_mode(struct ata_po
 
 	for (i = 0; i < ATA_MAX_DEVICES; i++) {
 		struct ata_device *dev = &ap->device[i];
-		if (ata_dev_ready(dev)) {
+		if (ata_dev_enabled(dev)) {
 			/* We don't really care */
 			dev->pio_mode = XFER_PIO_0;
 			dev->xfer_mode = XFER_PIO_0;
@@ -94,10 +94,6 @@ static struct scsi_host_template rz1000_
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
 	.bios_param		= ata_std_bios_param,
-#ifdef CONFIG_PM
-	.resume			= ata_scsi_device_resume,
-	.suspend		= ata_scsi_device_suspend,
-#endif
 };
 
 static struct ata_port_operations rz1000_port_ops = {
Index: linux-2.6.21-gentoo-r1/drivers/ata/pata_sc1200.c
===================================================================
--- linux-2.6.21-gentoo-r1.orig/drivers/ata/pata_sc1200.c
+++ linux-2.6.21-gentoo-r1/drivers/ata/pata_sc1200.c
@@ -194,10 +194,6 @@ static struct scsi_host_template sc1200_
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
 	.bios_param		= ata_std_bios_param,
-#ifdef CONFIG_PM
-	.resume			= ata_scsi_device_resume,
-	.suspend		= ata_scsi_device_suspend,
-#endif
 };
 
 static struct ata_port_operations sc1200_port_ops = {
Index: linux-2.6.21-gentoo-r1/drivers/ata/pata_scc.c
===================================================================
--- linux-2.6.21-gentoo-r1.orig/drivers/ata/pata_scc.c
+++ linux-2.6.21-gentoo-r1/drivers/ata/pata_scc.c
@@ -984,10 +984,6 @@ static struct scsi_host_template scc_sht
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
 	.bios_param		= ata_std_bios_param,
-#ifdef CONFIG_PM
-	.resume			= ata_scsi_device_resume,
-	.suspend		= ata_scsi_device_suspend,
-#endif
 };
 
 static const struct ata_port_operations scc_pata_ops = {
Index: linux-2.6.21-gentoo-r1/drivers/ata/pata_serverworks.c
===================================================================
--- linux-2.6.21-gentoo-r1.orig/drivers/ata/pata_serverworks.c
+++ linux-2.6.21-gentoo-r1/drivers/ata/pata_serverworks.c
@@ -319,10 +319,6 @@ static struct scsi_host_template serverw
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
 	.bios_param		= ata_std_bios_param,
-#ifdef CONFIG_PM
-	.resume			= ata_scsi_device_resume,
-	.suspend		= ata_scsi_device_suspend,
-#endif
 };
 
 static struct ata_port_operations serverworks_osb4_port_ops = {
Index: linux-2.6.21-gentoo-r1/drivers/ata/pata_sil680.c
===================================================================
--- linux-2.6.21-gentoo-r1.orig/drivers/ata/pata_sil680.c
+++ linux-2.6.21-gentoo-r1/drivers/ata/pata_sil680.c
@@ -236,10 +236,6 @@ static struct scsi_host_template sil680_
 	.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 struct ata_port_operations sil680_port_ops = {
Index: linux-2.6.21-gentoo-r1/drivers/ata/pata_sis.c
===================================================================
--- linux-2.6.21-gentoo-r1.orig/drivers/ata/pata_sis.c
+++ linux-2.6.21-gentoo-r1/drivers/ata/pata_sis.c
@@ -575,10 +575,6 @@ static struct scsi_host_template sis_sht
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
 	.bios_param		= ata_std_bios_param,
-#ifdef CONFIG_PM
-	.resume			= ata_scsi_device_resume,
-	.suspend		= ata_scsi_device_suspend,
-#endif
 };
 
 static const struct ata_port_operations sis_133_ops = {
Index: linux-2.6.21-gentoo-r1/drivers/ata/pata_triflex.c
===================================================================
--- linux-2.6.21-gentoo-r1.orig/drivers/ata/pata_triflex.c
+++ linux-2.6.21-gentoo-r1/drivers/ata/pata_triflex.c
@@ -193,10 +193,6 @@ static struct scsi_host_template triflex
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
 	.bios_param		= ata_std_bios_param,
-#ifdef CONFIG_PM
-	.resume			= ata_scsi_device_resume,
-	.suspend		= ata_scsi_device_suspend,
-#endif
 };
 
 static struct ata_port_operations triflex_port_ops = {
Index: linux-2.6.21-gentoo-r1/drivers/ata/pata_via.c
===================================================================
--- linux-2.6.21-gentoo-r1.orig/drivers/ata/pata_via.c
+++ linux-2.6.21-gentoo-r1/drivers/ata/pata_via.c
@@ -305,10 +305,6 @@ static struct scsi_host_template via_sht
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
 	.bios_param		= ata_std_bios_param,
-#ifdef CONFIG_PM
-	.resume			= ata_scsi_device_resume,
-	.suspend		= ata_scsi_device_suspend,
-#endif
 };
 
 static struct ata_port_operations via_port_ops = {
Index: linux-2.6.21-gentoo-r1/drivers/ata/sata_inic162x.c
===================================================================
--- linux-2.6.21-gentoo-r1.orig/drivers/ata/sata_inic162x.c
+++ linux-2.6.21-gentoo-r1/drivers/ata/sata_inic162x.c
@@ -135,10 +135,6 @@ static struct scsi_host_template inic_sh
 	.slave_configure	= inic_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 int scr_map[] = {
Index: linux-2.6.21-gentoo-r1/drivers/ata/sata_nv.c
===================================================================
--- linux-2.6.21-gentoo-r1.orig/drivers/ata/sata_nv.c
+++ linux-2.6.21-gentoo-r1/drivers/ata/sata_nv.c
@@ -322,10 +322,6 @@ static struct scsi_host_template nv_sht 
 	.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 struct scsi_host_template nv_adma_sht = {
@@ -344,10 +340,6 @@ static struct scsi_host_template nv_adma
 	.slave_configure	= nv_adma_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 nv_generic_ops = {
Index: linux-2.6.21-gentoo-r1/drivers/ata/sata_sil.c
===================================================================
--- linux-2.6.21-gentoo-r1.orig/drivers/ata/sata_sil.c
+++ linux-2.6.21-gentoo-r1/drivers/ata/sata_sil.c
@@ -183,10 +183,6 @@ static struct scsi_host_template sil_sht
 	.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 sil_ops = {
Index: linux-2.6.21-gentoo-r1/drivers/ata/sata_sil24.c
===================================================================
--- linux-2.6.21-gentoo-r1.orig/drivers/ata/sata_sil24.c
+++ linux-2.6.21-gentoo-r1/drivers/ata/sata_sil24.c
@@ -381,10 +381,6 @@ static struct scsi_host_template sil24_s
 	.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 sil24_ops = {
Index: linux-2.6.21-gentoo-r1/include/linux/libata.h
===================================================================
--- linux-2.6.21-gentoo-r1.orig/include/linux/libata.h
+++ linux-2.6.21-gentoo-r1/include/linux/libata.h
@@ -140,7 +140,6 @@ enum {
 
 	ATA_DFLAG_PIO		= (1 << 8), /* device limited to PIO mode */
 	ATA_DFLAG_NCQ_OFF	= (1 << 9), /* device limited to non-NCQ mode */
-	ATA_DFLAG_SUSPENDED	= (1 << 10), /* device suspended */
 	ATA_DFLAG_INIT_MASK	= (1 << 16) - 1,
 
 	ATA_DFLAG_DETACH	= (1 << 16),
@@ -267,13 +266,9 @@ enum {
 	ATA_EH_REVALIDATE	= (1 << 0),
 	ATA_EH_SOFTRESET	= (1 << 1),
 	ATA_EH_HARDRESET	= (1 << 2),
-	ATA_EH_SUSPEND		= (1 << 3),
-	ATA_EH_RESUME		= (1 << 4),
-	ATA_EH_PM_FREEZE	= (1 << 5),
 
 	ATA_EH_RESET_MASK	= ATA_EH_SOFTRESET | ATA_EH_HARDRESET,
-	ATA_EH_PERDEV_MASK	= ATA_EH_REVALIDATE | ATA_EH_SUSPEND |
-				  ATA_EH_RESUME | ATA_EH_PM_FREEZE,
+	ATA_EH_PERDEV_MASK	= ATA_EH_REVALIDATE,
 
 	/* ata_eh_info->flags */
 	ATA_EHI_HOTPLUGGED	= (1 << 0),  /* could have been hotplugged */
@@ -752,8 +747,6 @@ extern int sata_scr_write_flush(struct a
 extern int ata_port_online(struct ata_port *ap);
 extern int ata_port_offline(struct ata_port *ap);
 #ifdef CONFIG_PM
-extern int ata_scsi_device_resume(struct scsi_device *);
-extern int ata_scsi_device_suspend(struct scsi_device *, pm_message_t mesg);
 extern int ata_host_suspend(struct ata_host *host, pm_message_t mesg);
 extern void ata_host_resume(struct ata_host *host);
 #endif
@@ -1019,11 +1012,6 @@ static inline unsigned int ata_dev_absen
 	return ata_class_absent(dev->class);
 }
 
-static inline unsigned int ata_dev_ready(const struct ata_device *dev)
-{
-	return ata_dev_enabled(dev) && !(dev->flags & ATA_DFLAG_SUSPENDED);
-}
-
 /*
  * port helpers
  */

linux-2.6-2113_libata-spindown-compat.patch:

--- NEW FILE linux-2.6-2113_libata-spindown-compat.patch ---
>From 920a4b1038e442700a1cfac77ea7e20bd615a2c3 Mon Sep 17 00:00:00 2001
From: Tejun Heo <htejun at gmail.com>
Date: Fri, 4 May 2007 21:28:48 +0200
Subject: [PATCH] libata: implement libata.spindown_compat

Now that libata uses sd->manage_start_stop, libata spins down disk on
shutdown.  In an attempt to compensate libata's previous shortcoming,
some distros sync and spin down disks attached via libata in their
shutdown(8).  Some disks spin back up just to spin down again on
STANDBYNOW1 if the command is issued when the disk is spun down, so
this double spinning down causes problem.

This patch implements module parameter libata.spindown_compat which,
when set to one (default value), prevents libata from spinning down
disks on shutdown thus avoiding double spinning down.  Note that
libata spins down disks for suspend to mem and disk, so with
libata.spindown_compat set to one, disks should be properly spun down
in all cases without modifying shutdown(8).

shutdown(8) should be fixed eventually.  Some drive do spin up on
SYNCHRONZE_CACHE even when their cache is clean.  Those disks
currently spin up briefly when sd tries to shutdown the device and
then the machine powers off immediately, which can't be good for the
head.  We can't skip SYNCHRONIZE_CACHE during shudown as it can be
dangerous data integrity-wise.

So, this spindown_compat parameter is already scheduled for removal by
the end of the next year and here's what shutdown(8) should do.

  * Check whether /sys/modules/libata/parameters/spindown_compat
    exists.  If it does, write 0 to it.

  * For each libata harddisk {
	* Check whether /sys/class/scsi_disk/h:c:i:l/manage_start_stop
	  exists.  Iff it doesn't, synchronize cache and spin the disk
	  down as before.
  }

The above procedure will make shutdown(8) work properly with kernels
before this change, ones with this workaround and later ones without
it.

To accelerate shutdown(8) updates, if the compat mode is in use, this
patch prints BIG FAT warning for five seconds during shutdown (the
optimal interval to annoy the user just the right amount discovered by
hours of tireless usability testing).

Signed-off-by: Tejun Heo <htejun at gmail.com>
Signed-off-by: Jeff Garzik <jeff at garzik.org>
---
 Documentation/feature-removal-schedule.txt |   19 +++++++++++++++++++
 drivers/ata/libata-core.c                  |    6 ++++++
 drivers/ata/libata-scsi.c                  |   28 +++++++++++++++++++++++++++-
 drivers/ata/libata.h                       |    1 +
 4 files changed, 53 insertions(+), 1 deletions(-)

Index: linux-2.6.21-gentoo-r1/drivers/ata/libata-core.c
===================================================================
--- linux-2.6.21-gentoo-r1.orig/drivers/ata/libata-core.c
+++ linux-2.6.21-gentoo-r1/drivers/ata/libata-core.c
@@ -97,6 +97,12 @@ int libata_noacpi = 1;
 module_param_named(noacpi, libata_noacpi, int, 0444);
 MODULE_PARM_DESC(noacpi, "Disables the use of ACPI in suspend/resume when set");
 
+int ata_spindown_compat = 1;
+module_param_named(spindown_compat, ata_spindown_compat, int, 0644);
+MODULE_PARM_DESC(spindown_compat, "Enable backward compatible spindown "
+		 "behavior.  Will be removed.  More info can be found in "
+		 "Documentation/feature-removal-schedule.txt\n");
+
 MODULE_AUTHOR("Jeff Garzik");
 MODULE_DESCRIPTION("Library module for ATA devices");
 MODULE_LICENSE("GPL");
Index: linux-2.6.21-gentoo-r1/drivers/ata/libata-scsi.c
===================================================================
--- linux-2.6.21-gentoo-r1.orig/drivers/ata/libata-scsi.c
+++ linux-2.6.21-gentoo-r1/drivers/ata/libata-scsi.c
@@ -944,9 +944,35 @@ static unsigned int ata_scsi_start_stop_
 		}
 
 		tf->command = ATA_CMD_VERIFY;	/* READ VERIFY */
-	} else
+	} else {
+		/* XXX: This is for backward compatibility, will be
+		 * removed.  Read Documentation/feature-removal-schedule.txt
+		 * for more info.
+		 */
+		if (ata_spindown_compat &&
+		    (system_state == SYSTEM_HALT ||
+		     system_state == SYSTEM_POWER_OFF)) {
+			static int warned = 0;
+
+			if (!warned) {
+				spin_unlock_irq(qc->ap->lock);
+				ata_dev_printk(qc->dev, KERN_WARNING,
+					"DISK MIGHT NOT BE SPUN DOWN PROPERLY. "
+					"UPDATE SHUTDOWN UTILITY\n");
+				ata_dev_printk(qc->dev, KERN_WARNING,
+					"For more info, visit "
+					"http://linux-ata.org/shutdown.html\n");
+				warned = 1;
+				ssleep(5);
+				spin_lock_irq(qc->ap->lock);
+			}
+			scmd->result = SAM_STAT_GOOD;
+			return 1;
+		}
+
 		/* Issue ATA STANDBY IMMEDIATE command */
 		tf->command = ATA_CMD_STANDBYNOW1;
+	}
 
 	/*
 	 * Standby and Idle condition timers could be implemented but that
Index: linux-2.6.21-gentoo-r1/drivers/ata/libata.h
===================================================================
--- linux-2.6.21-gentoo-r1.orig/drivers/ata/libata.h
+++ linux-2.6.21-gentoo-r1/drivers/ata/libata.h
@@ -57,6 +57,7 @@ extern int atapi_enabled;
 extern int atapi_dmadir;
 extern int libata_fua;
 extern int libata_noacpi;
+extern int ata_spindown_compat;
 extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev);
 extern int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev,
 			   u64 block, u32 n_block, unsigned int tf_flags,

linux-2.6-2114_libata-shutdown-warning.patch:

--- NEW FILE linux-2.6-2114_libata-shutdown-warning.patch ---
>From da071b42f73dabbd0daf7ea4c3ff157d53b00648 Mon Sep 17 00:00:00 2001
From: Tejun Heo <htejun at gmail.com>
Date: Mon, 14 May 2007 17:26:18 +0200
Subject: [PATCH] libata: fix shutdown warning message printing

Unlocking ap->lock and ssleeping don't work because SCSI commands can
be issued from completion path without context.  Reimplement delayed
completion by allowing translation functions to override
qc->scsidone(), storing the original completion function to
scmd->scsi_done() and overriding qc->scsidone() with a function which
schedules delayed invocation of scmd->scsi_done().

This isn't pretty at all but all the ugly parts are thankfully
contained in the stop translation path where the compat feature is
implemented.

Signed-off-by: Tejun Heo <htejun at gmail.com>
Signed-off-by: Jeff Garzik <jeff at garzik.org>
---
 drivers/ata/libata-scsi.c |   35 +++++++++++++++++++++++++++--------
 1 files changed, 27 insertions(+), 8 deletions(-)

diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index dd81fa7..07b5a3d 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -893,6 +893,23 @@ int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth)
 	return queue_depth;
 }
 
+/* XXX: for ata_spindown_compat */
+static void ata_delayed_done_timerfn(unsigned long arg)
+{
+	struct scsi_cmnd *scmd = (void *)arg;
+
+	scmd->scsi_done(scmd);
+}
+
+/* XXX: for ata_spindown_compat */
+static void ata_delayed_done(struct scsi_cmnd *scmd)
+{
+	static struct timer_list timer;
+
+	setup_timer(&timer, ata_delayed_done_timerfn, (unsigned long)scmd);
+	mod_timer(&timer, jiffies + 5 * HZ);
+}
+
 /**
  *	ata_scsi_start_stop_xlat - Translate SCSI START STOP UNIT command
  *	@qc: Storage for translated ATA taskfile
@@ -952,19 +969,21 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc)
 		if (ata_spindown_compat &&
 		    (system_state == SYSTEM_HALT ||
 		     system_state == SYSTEM_POWER_OFF)) {
-			static int warned = 0;
+			static unsigned long warned = 0;
 
-			if (!warned) {
-				spin_unlock_irq(qc->ap->lock);
+			if (!test_and_set_bit(0, &warned)) {
 				ata_dev_printk(qc->dev, KERN_WARNING,
 					"DISK MIGHT NOT BE SPUN DOWN PROPERLY. "
 					"UPDATE SHUTDOWN UTILITY\n");
 				ata_dev_printk(qc->dev, KERN_WARNING,
 					"For more info, visit "
 					"http://linux-ata.org/shutdown.html\n");
-				warned = 1;
-				ssleep(5);
-				spin_lock_irq(qc->ap->lock);
+
+				/* ->scsi_done is not used, use it for
+				 * delayed completion.
+				 */
+				scmd->scsi_done = qc->scsidone;
+				qc->scsidone = ata_delayed_done;
 			}
 			scmd->result = SAM_STAT_GOOD;
 			return 1;
@@ -1488,14 +1507,14 @@ static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd,
 
 early_finish:
         ata_qc_free(qc);
-	done(cmd);
+	qc->scsidone(cmd);
 	DPRINTK("EXIT - early finish (good or error)\n");
 	return 0;
 
 err_did:
 	ata_qc_free(qc);
 	cmd->result = (DID_ERROR << 16);
-	done(cmd);
+	qc->scsidone(cmd);
 err_mem:
 	DPRINTK("EXIT - internal\n");
 	return 0;
-- 
1.5.1.4


linux-2.6-2115_libata-spindown-status.patch:

--- NEW FILE linux-2.6-2115_libata-spindown-status.patch ---
>From 13b8d09f5de0aaa3153bbccc98baf247387823dc Mon Sep 17 00:00:00 2001
From: Tejun Heo <htejun at gmail.com>
Date: Tue, 15 May 2007 12:29:22 +0200
Subject: [PATCH] libata: track spindown status and skip spindown_compat if possible

Our assumption that most distros issue STANDBYNOW seems wrong.  The
upstream sysvinit and thus many distros including gentoo and opensuse
don't take any action for libata disks on spindown.  We can skip
compat handling for these distros so that they don't need to update
anything to take advantage of kernel-side shutdown.

Signed-off-by: Tejun Heo <htejun at gmail.com>
Signed-off-by: Jeff Garzik <jeff at garzik.org>
---
 drivers/ata/libata-scsi.c |    9 +++++++++
 include/linux/libata.h    |    1 +
 2 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 07b5a3d..b6a1de8 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -967,6 +967,7 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc)
 		 * for more info.
 		 */
 		if (ata_spindown_compat &&
+		    (qc->dev->flags & ATA_DFLAG_SPUNDOWN) &&
 		    (system_state == SYSTEM_HALT ||
 		     system_state == SYSTEM_POWER_OFF)) {
 			static unsigned long warned = 0;
@@ -1394,6 +1395,14 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc)
 		}
 	}
 
+	/* XXX: track spindown state for spindown_compat */
+	if (unlikely(qc->tf.command == ATA_CMD_STANDBY ||
+		     qc->tf.command == ATA_CMD_STANDBYNOW1))
+		qc->dev->flags |= ATA_DFLAG_SPUNDOWN;
+	else if (likely(system_state != SYSTEM_HALT &&
+			system_state != SYSTEM_POWER_OFF))
+		qc->dev->flags &= ~ATA_DFLAG_SPUNDOWN;
+
 	if (need_sense && !ap->ops->error_handler)
 		ata_dump_status(ap->print_id, &qc->result_tf);
 
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 9b2122d..666592e 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -140,6 +140,7 @@ enum {
 
 	ATA_DFLAG_PIO		= (1 << 8), /* device limited to PIO mode */
 	ATA_DFLAG_NCQ_OFF	= (1 << 9), /* device limited to non-NCQ mode */
+	ATA_DFLAG_SPUNDOWN	= (1 << 10), /* XXX: for spindown_compat */
 	ATA_DFLAG_INIT_MASK	= (1 << 16) - 1,
 
 	ATA_DFLAG_DETACH	= (1 << 16),
-- 
1.5.1.4


linux-2.6-2116_libata-remove-spindown-compat.patch:

--- NEW FILE linux-2.6-2116_libata-remove-spindown-compat.patch ---
>From d9aca22cf443f5ed77d15a320abbab055ae4a976 Mon Sep 17 00:00:00 2001
From: Tejun Heo <htejun at gmail.com>
Date: Thu, 17 May 2007 16:43:26 +0200
Subject: [PATCH] libata: remove libata.spindown_compat

With STANDBYDOWN tracking added, libata.spindown_compat isn't
necessary anymore.  If userspace shutdown(8) issues STANDBYNOW, libata
warns.  If userspace shutdown(8) doesn't issue STANDBYNOW, libata does
the right thing.  Userspace can tell whether kernel supports spindown
by testing whether sysfs node manage_start_stop exists as before.

Signed-off-by: Tejun Heo <htejun at gmail.com>
Signed-off-by: Jeff Garzik <jeff at garzik.org>
---
 Documentation/feature-removal-schedule.txt |   25 ++++++++++++-------------
 drivers/ata/libata-core.c                  |    6 ------
 drivers/ata/libata-scsi.c                  |    9 ++++-----
 drivers/ata/libata.h                       |    1 -
 4 files changed, 16 insertions(+), 25 deletions(-)

Index: linux-2.6.21-gentoo-r1/drivers/ata/libata-core.c
===================================================================
--- linux-2.6.21-gentoo-r1.orig/drivers/ata/libata-core.c
+++ linux-2.6.21-gentoo-r1/drivers/ata/libata-core.c
@@ -97,12 +97,6 @@ int libata_noacpi = 1;
 module_param_named(noacpi, libata_noacpi, int, 0444);
 MODULE_PARM_DESC(noacpi, "Disables the use of ACPI in suspend/resume when set");
 
-int ata_spindown_compat = 1;
-module_param_named(spindown_compat, ata_spindown_compat, int, 0644);
-MODULE_PARM_DESC(spindown_compat, "Enable backward compatible spindown "
-		 "behavior.  Will be removed.  More info can be found in "
-		 "Documentation/feature-removal-schedule.txt\n");
-
 MODULE_AUTHOR("Jeff Garzik");
 MODULE_DESCRIPTION("Library module for ATA devices");
 MODULE_LICENSE("GPL");
Index: linux-2.6.21-gentoo-r1/drivers/ata/libata-scsi.c
===================================================================
--- linux-2.6.21-gentoo-r1.orig/drivers/ata/libata-scsi.c
+++ linux-2.6.21-gentoo-r1/drivers/ata/libata-scsi.c
@@ -893,7 +893,7 @@ int ata_scsi_change_queue_depth(struct s
 	return queue_depth;
 }
 
-/* XXX: for ata_spindown_compat */
+/* XXX: for spindown warning */
 static void ata_delayed_done_timerfn(unsigned long arg)
 {
 	struct scsi_cmnd *scmd = (void *)arg;
@@ -901,7 +901,7 @@ static void ata_delayed_done_timerfn(uns
 	scmd->scsi_done(scmd);
 }
 
-/* XXX: for ata_spindown_compat */
+/* XXX: for spindown warning */
 static void ata_delayed_done(struct scsi_cmnd *scmd)
 {
 	static struct timer_list timer;
@@ -966,8 +966,7 @@ static unsigned int ata_scsi_start_stop_
 		 * removed.  Read Documentation/feature-removal-schedule.txt
 		 * for more info.
 		 */
-		if (ata_spindown_compat &&
-		    (qc->dev->flags & ATA_DFLAG_SPUNDOWN) &&
+		if ((qc->dev->flags & ATA_DFLAG_SPUNDOWN) &&
 		    (system_state == SYSTEM_HALT ||
 		     system_state == SYSTEM_POWER_OFF)) {
 			static unsigned long warned = 0;
@@ -1395,7 +1394,7 @@ static void ata_scsi_qc_complete(struct 
 		}
 	}
 
-	/* XXX: track spindown state for spindown_compat */
+	/* XXX: track spindown state for spindown skipping and warning */
 	if (unlikely(qc->tf.command == ATA_CMD_STANDBY ||
 		     qc->tf.command == ATA_CMD_STANDBYNOW1))
 		qc->dev->flags |= ATA_DFLAG_SPUNDOWN;
Index: linux-2.6.21-gentoo-r1/drivers/ata/libata.h
===================================================================
--- linux-2.6.21-gentoo-r1.orig/drivers/ata/libata.h
+++ linux-2.6.21-gentoo-r1/drivers/ata/libata.h
@@ -57,7 +57,6 @@ extern int atapi_enabled;
 extern int atapi_dmadir;
 extern int libata_fua;
 extern int libata_noacpi;
-extern int ata_spindown_compat;
 extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev);
 extern int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev,
 			   u64 block, u32 n_block, unsigned int tf_flags,

linux-2.6-2117_sata-via-suspend.patch:

--- NEW FILE linux-2.6-2117_sata-via-suspend.patch ---
Index: linux-2.6.21-gentoo-r2/drivers/ata/sata_via.c
===================================================================
--- linux-2.6.21-gentoo-r2.orig/drivers/ata/sata_via.c
+++ linux-2.6.21-gentoo-r2/drivers/ata/sata_via.c
@@ -120,10 +120,6 @@ static struct scsi_host_template svia_sh
 	.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 vt6420_sata_ops = {

linux-2.6-2118_scsi-constants.patch:

--- NEW FILE linux-2.6-2118_scsi-constants.patch ---
From: Martin K. Petersen <martin.petersen at oracle.com>
Date: Wed, 28 Feb 2007 03:39:44 +0000 (-0500)
Subject: [SCSI] constants.c: cleanup, verbose result printing
X-Git-Tag: v2.6.22-rc1~1015^2~85
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=684b7fe976554d12e6266d7280c87a0f3feff02e

[SCSI] constants.c: cleanup, verbose result printing

Clean up constants.c and make result printing more user friendly:

 - Refactor the command and sense functions so that the actual
   formatting can be called from the various helper functions with the
   correct prefix.

 - Replace scsi_print_hostbyte() and scsi_print_driverbyte() with
   scsi_print_result() which is verbose when CONFIG_SCSI_CONSTANTS is
   on.

Signed-off-by: Martin K. Petersen <martin.petersen at oracle.com>
Signed-off-by: James Bottomley <James.Bottomley at SteelEye.com>
---

diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c
index 61f6024..6114875 100644
--- a/drivers/scsi/constants.c
+++ b/drivers/scsi/constants.c
@@ -202,31 +202,29 @@ static const char * get_sa_name(const struct value_name_pair * arr,
 }
 
 /* attempt to guess cdb length if cdb_len==0 . No trailing linefeed. */
-static void print_opcode_name(unsigned char * cdbp, int cdb_len,
-			      int start_of_line)
+static void print_opcode_name(unsigned char * cdbp, int cdb_len)
 {
 	int sa, len, cdb0;
 	const char * name;
-	const char * leadin = start_of_line ? KERN_INFO : "";
 
 	cdb0 = cdbp[0];
 	switch(cdb0) {
 	case VARIABLE_LENGTH_CMD:
 		len = cdbp[7] + 8;
 		if (len < 10) {
-			printk("%sshort variable length command, "
-			       "len=%d ext_len=%d", leadin, len, cdb_len);
+			printk("short variable length command, "
+			       "len=%d ext_len=%d", len, cdb_len);
 			break;
 		}
 		sa = (cdbp[8] << 8) + cdbp[9];
 		name = get_sa_name(maint_in_arr, MAINT_IN_SZ, sa);
 		if (name) {
-			printk("%s%s", leadin, name);
+			printk("%s", name);
 			if ((cdb_len > 0) && (len != cdb_len))
 				printk(", in_cdb_len=%d, ext_len=%d",
 				       len, cdb_len);
 		} else {
-			printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa);
+			printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa);
 			if ((cdb_len > 0) && (len != cdb_len))
 				printk(", in_cdb_len=%d, ext_len=%d",
 				       len, cdb_len);
@@ -236,83 +234,80 @@ static void print_opcode_name(unsigned char * cdbp, int cdb_len,
 		sa = cdbp[1] & 0x1f;
 		name = get_sa_name(maint_in_arr, MAINT_IN_SZ, sa);
 		if (name)
-			printk("%s%s", leadin, name);
+			printk("%s", name);
 		else
-			printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa);
+			printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa);
 		break;
 	case MAINTENANCE_OUT:
 		sa = cdbp[1] & 0x1f;
 		name = get_sa_name(maint_out_arr, MAINT_OUT_SZ, sa);
 		if (name)
-			printk("%s%s", leadin, name);
+			printk("%s", name);
 		else
-			printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa);
+			printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa);
 		break;
 	case SERVICE_ACTION_IN_12:
 		sa = cdbp[1] & 0x1f;
 		name = get_sa_name(serv_in12_arr, SERV_IN12_SZ, sa);
 		if (name)
-			printk("%s%s", leadin, name);
+			printk("%s", name);
 		else
-			printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa);
+			printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa);
 		break;
 	case SERVICE_ACTION_OUT_12:
 		sa = cdbp[1] & 0x1f;
 		name = get_sa_name(serv_out12_arr, SERV_OUT12_SZ, sa);
 		if (name)
-			printk("%s%s", leadin, name);
+			printk("%s", name);
 		else
-			printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa);
+			printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa);
 		break;
 	case SERVICE_ACTION_IN_16:
 		sa = cdbp[1] & 0x1f;
 		name = get_sa_name(serv_in16_arr, SERV_IN16_SZ, sa);
 		if (name)
-			printk("%s%s", leadin, name);
+			printk("%s", name);
 		else
-			printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa);
+			printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa);
 		break;
 	case SERVICE_ACTION_OUT_16:
 		sa = cdbp[1] & 0x1f;
 		name = get_sa_name(serv_out16_arr, SERV_OUT16_SZ, sa);
 		if (name)
-			printk("%s%s", leadin, name);
+			printk("%s", name);
 		else
-			printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa);
+			printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa);
 		break;
 	default:
 		if (cdb0 < 0xc0) {
 			name = cdb_byte0_names[cdb0];
 			if (name)
-				printk("%s%s", leadin, name);
+				printk("%s", name);
 			else
-				printk("%scdb[0]=0x%x (reserved)",
-				       leadin, cdb0);
+				printk("cdb[0]=0x%x (reserved)", cdb0);
 		} else
-			printk("%scdb[0]=0x%x (vendor)", leadin, cdb0);
+			printk("cdb[0]=0x%x (vendor)", cdb0);
 		break;
 	}
 }
 
 #else /* ifndef CONFIG_SCSI_CONSTANTS */
 
-static void print_opcode_name(unsigned char * cdbp, int cdb_len,
-			      int start_of_line)
+static void print_opcode_name(unsigned char * cdbp, int cdb_len)
 {
 	int sa, len, cdb0;
-	const char * leadin = start_of_line ? KERN_INFO : "";
 
 	cdb0 = cdbp[0];
 	switch(cdb0) {
 	case VARIABLE_LENGTH_CMD:
 		len = cdbp[7] + 8;
 		if (len < 10) {
-			printk("%sshort opcode=0x%x command, len=%d "
-			       "ext_len=%d", leadin, cdb0, len, cdb_len);
+			printk("short opcode=0x%x command, len=%d "
+			       "ext_len=%d", cdb0, len, cdb_len);
 			break;
 		}
 		sa = (cdbp[8] << 8) + cdbp[9];
-		printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa);
+		printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa);
 		if (len != cdb_len)
 			printk(", in_cdb_len=%d, ext_len=%d", len, cdb_len);
 		break;
@@ -323,49 +318,48 @@ static void print_opcode_name(unsigned char * cdbp, int cdb_len,
 	case SERVICE_ACTION_IN_16:
 	case SERVICE_ACTION_OUT_16:
 		sa = cdbp[1] & 0x1f;
-		printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa);
+		printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa);
 		break;
 	default:
 		if (cdb0 < 0xc0)
-			printk("%scdb[0]=0x%x", leadin, cdb0);
+			printk("cdb[0]=0x%x", cdb0);
 		else
-			printk("%scdb[0]=0x%x (vendor)", leadin, cdb0);
+			printk("cdb[0]=0x%x (vendor)", cdb0);
 		break;
 	}
 }
 #endif  
 
-void __scsi_print_command(unsigned char *command)
+void __scsi_print_command(unsigned char *cdb)
 {
 	int k, len;
 
-	print_opcode_name(command, 0, 1);
-	if (VARIABLE_LENGTH_CMD == command[0])
-		len = command[7] + 8;
+	print_opcode_name(cdb, 0);
+	if (VARIABLE_LENGTH_CMD == cdb[0])
+		len = cdb[7] + 8;
 	else
-		len = COMMAND_SIZE(command[0]);
+		len = COMMAND_SIZE(cdb[0]);
 	/* print out all bytes in cdb */
 	for (k = 0; k < len; ++k) 
-		printk(" %02x", command[k]);
+		printk(" %02x", cdb[k]);
 	printk("\n");
 }
 EXPORT_SYMBOL(__scsi_print_command);
 
-/* This function (perhaps with the addition of peripheral device type)
- * is more approriate than __scsi_print_command(). Perhaps that static
- * can be dropped later if it replaces the __scsi_print_command version.
- */
-static void scsi_print_cdb(unsigned char *cdb, int cdb_len, int start_of_line)
+void scsi_print_command(struct scsi_cmnd *cmd)
 {
 	int k;
 
-	print_opcode_name(cdb, cdb_len, start_of_line);
+	scmd_printk(KERN_INFO, cmd, "CDB: ");
+	print_opcode_name(cmd->cmnd, cmd->cmd_len);
+
 	/* print out all bytes in cdb */
 	printk(":");
-	for (k = 0; k < cdb_len; ++k) 
-		printk(" %02x", cdb[k]);
+	for (k = 0; k < cmd->cmd_len; ++k)
+		printk(" %02x", cmd->cmnd[k]);
 	printk("\n");
 }
+EXPORT_SYMBOL(scsi_print_command);
 
 /**
  *
@@ -1176,67 +1170,77 @@ scsi_extd_sense_format(unsigned char asc, unsigned char ascq) {
 }
 EXPORT_SYMBOL(scsi_extd_sense_format);
 
-/* Print extended sense information; no leadin, no linefeed */
-static void
+void
 scsi_show_extd_sense(unsigned char asc, unsigned char ascq)
 {
-	const char *extd_sense_fmt = scsi_extd_sense_format(asc, ascq);
+        const char *extd_sense_fmt = scsi_extd_sense_format(asc, ascq);
 
 	if (extd_sense_fmt) {
 		if (strstr(extd_sense_fmt, "%x")) {
-			printk("Additional sense: ");
+			printk("Add. Sense: ");
 			printk(extd_sense_fmt, ascq);
 		} else
-			printk("Additional sense: %s", extd_sense_fmt);
+			printk("Add. Sense: %s", extd_sense_fmt);
 	} else {
 		if (asc >= 0x80)
-			printk("<<vendor>> ASC=0x%x ASCQ=0x%x", asc, ascq);
+			printk("<<vendor>> ASC=0x%x ASCQ=0x%x", asc,
+			       ascq);
 		if (ascq >= 0x80)
-			printk("ASC=0x%x <<vendor>> ASCQ=0x%x", asc, ascq);
+			printk("ASC=0x%x <<vendor>> ASCQ=0x%x", asc,
+			       ascq);
 		else
 			printk("ASC=0x%x ASCQ=0x%x", asc, ascq);
 	}
+
+	printk("\n");
 }
+EXPORT_SYMBOL(scsi_show_extd_sense);
 
 void
-scsi_print_sense_hdr(const char *name, struct scsi_sense_hdr *sshdr)
+scsi_show_sense_hdr(struct scsi_sense_hdr *sshdr)
 {
 	const char *sense_txt;
-	/* An example of deferred is when an earlier write to disk cache
-	 * succeeded, but now the disk discovers that it cannot write the
-	 * data to the magnetic media.
-	 */
-	const char *error = scsi_sense_is_deferred(sshdr) ? 
-		"<<DEFERRED>>" : "Current";
-	printk(KERN_INFO "%s: %s", name, error);
-	if (sshdr->response_code >= 0x72)
-		printk(" [descriptor]");
 
 	sense_txt = scsi_sense_key_string(sshdr->sense_key);
 	if (sense_txt)
-		printk(": sense key: %s\n", sense_txt);
+		printk("Sense Key : %s ", sense_txt);
 	else
-		printk(": sense key=0x%x\n", sshdr->sense_key);
-	printk(KERN_INFO "    ");
-	scsi_show_extd_sense(sshdr->asc, sshdr->ascq);
+		printk("Sense Key : 0x%x ", sshdr->sense_key);
+
+	printk("%s", scsi_sense_is_deferred(sshdr) ? "[deferred] " :
+	       "[current] ");
+
+	if (sshdr->response_code >= 0x72)
+		printk("[descriptor]");
+
 	printk("\n");
 }
+EXPORT_SYMBOL(scsi_show_sense_hdr);
+
+/*
+ * Print normalized SCSI sense header with a prefix.
+ */
+void
+scsi_print_sense_hdr(const char *name, struct scsi_sense_hdr *sshdr)
+{
+	printk(KERN_INFO "%s: ", name);
+	scsi_show_sense_hdr(sshdr);
+	printk(KERN_INFO "%s: ", name);
+	scsi_show_extd_sense(sshdr->asc, sshdr->ascq);
+}
 EXPORT_SYMBOL(scsi_print_sense_hdr);
 
-/* Print sense information */
 void
-__scsi_print_sense(const char *name, const unsigned char *sense_buffer,
-		   int sense_len)
+scsi_decode_sense_buffer(const unsigned char *sense_buffer, int sense_len,
+		       struct scsi_sense_hdr *sshdr)
 {
 	int k, num, res;
-	unsigned int info;
-	struct scsi_sense_hdr ssh;
     
-	res = scsi_normalize_sense(sense_buffer, sense_len, &ssh);
+	res = scsi_normalize_sense(sense_buffer, sense_len, sshdr);
 	if (0 == res) {
 		/* this may be SCSI-1 sense data */
 		num = (sense_len < 32) ? sense_len : 32;
-		printk(KERN_INFO "Unrecognized sense data (in hex):");
+		printk("Unrecognized sense data (in hex):");
 		for (k = 0; k < num; ++k) {
 			if (0 == (k % 16)) {
 				printk("\n");
@@ -1247,11 +1251,20 @@ __scsi_print_sense(const char *name, const unsigned char *sense_buffer,
 		printk("\n");
 		return;
 	}
-	scsi_print_sense_hdr(name, &ssh);
-	if (ssh.response_code < 0x72) {
+}
+
+void
+scsi_decode_sense_extras(const unsigned char *sense_buffer, int sense_len,
+			 struct scsi_sense_hdr *sshdr)
+{
+	int k, num, res;
+
+	if (sshdr->response_code < 0x72)
+	{
 		/* only decode extras for "fixed" format now */
 		char buff[80];
 		int blen, fixed_valid;
+		unsigned int info;
 
 		fixed_valid = sense_buffer[0] & 0x80;
 		info = ((sense_buffer[3] << 24) | (sense_buffer[4] << 16) |
@@ -1281,13 +1294,13 @@ __scsi_print_sense(const char *name, const unsigned char *sense_buffer,
 			res += snprintf(buff + res, blen - res, "ILI");
 		}
 		if (res > 0)
-			printk(KERN_INFO "%s\n", buff);
-	} else if (ssh.additional_length > 0) {
+			printk("%s\n", buff);
+	} else if (sshdr->additional_length > 0) {
 		/* descriptor format with sense descriptors */
-		num = 8 + ssh.additional_length;
+		num = 8 + sshdr->additional_length;
 		num = (sense_len < num) ? sense_len : num;
-		printk(KERN_INFO "Descriptor sense data with sense "
-		       "descriptors (in hex):");
+		printk("Descriptor sense data with sense descriptors "
+		       "(in hex):");
 		for (k = 0; k < num; ++k) {
 			if (0 == (k % 16)) {
 				printk("\n");
@@ -1295,29 +1308,42 @@ __scsi_print_sense(const char *name, const unsigned char *sense_buffer,
 			}
 			printk("%02x ", sense_buffer[k]);
 		}
+
 		printk("\n");
 	}
+
 }
-EXPORT_SYMBOL(__scsi_print_sense);
 
-void scsi_print_sense(const char *devclass, struct scsi_cmnd *cmd)
+/* Normalize and print sense buffer with name prefix */
+void __scsi_print_sense(const char *name, const unsigned char *sense_buffer,
+			int sense_len)
 {
-	const char *name = devclass;
-
-	if (cmd->request->rq_disk)
-		name = cmd->request->rq_disk->disk_name;
-	__scsi_print_sense(name, cmd->sense_buffer, SCSI_SENSE_BUFFERSIZE);
+	struct scsi_sense_hdr sshdr;
+
+	printk(KERN_INFO "%s: ", name);
+	scsi_decode_sense_buffer(sense_buffer, sense_len, &sshdr);
+	scsi_show_sense_hdr(&sshdr);
+	scsi_decode_sense_extras(sense_buffer, sense_len, &sshdr);
+	printk(KERN_INFO "%s: ", name);
+	scsi_show_extd_sense(sshdr.asc, sshdr.ascq);
 }
-EXPORT_SYMBOL(scsi_print_sense);
+EXPORT_SYMBOL(__scsi_print_sense);
 
-void scsi_print_command(struct scsi_cmnd *cmd)
+/* Normalize and print sense buffer in SCSI command */
+void scsi_print_sense(char *name, struct scsi_cmnd *cmd)
 {
-	/* Assume appended output (i.e. not at start of line) */
-	sdev_printk("", cmd->device, "\n");
-	printk(KERN_INFO "        command: ");
-	scsi_print_cdb(cmd->cmnd, cmd->cmd_len, 0);
+	struct scsi_sense_hdr sshdr;
+
+	scmd_printk(KERN_INFO, cmd, "");
+	scsi_decode_sense_buffer(cmd->sense_buffer, SCSI_SENSE_BUFFERSIZE,
+				 &sshdr);
+	scsi_show_sense_hdr(&sshdr);
+	scsi_decode_sense_extras(cmd->sense_buffer, SCSI_SENSE_BUFFERSIZE,
+				 &sshdr);
+	scmd_printk(KERN_INFO, cmd, "");
+	scsi_show_extd_sense(sshdr.asc, sshdr.ascq);
 }
-EXPORT_SYMBOL(scsi_print_command);
+EXPORT_SYMBOL(scsi_print_sense);
 
 #ifdef CONFIG_SCSI_CONSTANTS
 
@@ -1327,25 +1353,6 @@ static const char * const hostbyte_table[]={
 "DID_PASSTHROUGH", "DID_SOFT_ERROR", "DID_IMM_RETRY"};
 #define NUM_HOSTBYTE_STRS ARRAY_SIZE(hostbyte_table)
 
-void scsi_print_hostbyte(int scsiresult)
-{
-	int hb = host_byte(scsiresult);
-
-	printk("Hostbyte=0x%02x", hb);
-	if (hb < NUM_HOSTBYTE_STRS)
-		printk("(%s) ", hostbyte_table[hb]);
-	else
-		printk("is invalid ");
-}
-#else
-void scsi_print_hostbyte(int scsiresult)
-{
-	printk("Hostbyte=0x%02x ", host_byte(scsiresult));
-}
-#endif
-
-#ifdef CONFIG_SCSI_CONSTANTS
-
 static const char * const driverbyte_table[]={
 "DRIVER_OK", "DRIVER_BUSY", "DRIVER_SOFT",  "DRIVER_MEDIA", "DRIVER_ERROR",
 "DRIVER_INVALID", "DRIVER_TIMEOUT", "DRIVER_HARD", "DRIVER_SENSE"};
@@ -1356,19 +1363,35 @@ static const char * const driversuggest_table[]={"SUGGEST_OK",
 "SUGGEST_5", "SUGGEST_6", "SUGGEST_7", "SUGGEST_SENSE"};
 #define NUM_SUGGEST_STRS ARRAY_SIZE(driversuggest_table)
 
-void scsi_print_driverbyte(int scsiresult)
+void scsi_show_result(int result)
 {
-	int dr = (driver_byte(scsiresult) & DRIVER_MASK);
-	int su = ((driver_byte(scsiresult) & SUGGEST_MASK) >> 4);
+	int hb = host_byte(result);
+	int db = (driver_byte(result) & DRIVER_MASK);
+	int su = ((driver_byte(result) & SUGGEST_MASK) >> 4);
 
-	printk("Driverbyte=0x%02x ", driver_byte(scsiresult));
-	printk("(%s,%s) ",
-	       (dr < NUM_DRIVERBYTE_STRS ? driverbyte_table[dr] : "invalid"),
+	printk("Result: hostbyte=%s driverbyte=%s,%s\n",
+	       (hb < NUM_HOSTBYTE_STRS ? hostbyte_table[hb]     : "invalid"),
+	       (db < NUM_DRIVERBYTE_STRS ? driverbyte_table[db] : "invalid"),
 	       (su < NUM_SUGGEST_STRS ? driversuggest_table[su] : "invalid"));
 }
+
 #else
-void scsi_print_driverbyte(int scsiresult)
+
+void scsi_show_result(int result)
 {
-	printk("Driverbyte=0x%02x ", driver_byte(scsiresult));
+	printk("Result: hostbyte=0x%02x driverbyte=0x%02x\n",
+	       host_byte(result), driver_byte(result));
 }
+
 #endif
+EXPORT_SYMBOL(scsi_show_result);
+
+
+void scsi_print_result(struct scsi_cmnd *cmd)
+{
+	scmd_printk(KERN_INFO, cmd, "");
+	scsi_show_result(cmd->result);
+}
+EXPORT_SYMBOL(scsi_print_result);
+
+
diff --git a/include/scsi/scsi_dbg.h b/include/scsi/scsi_dbg.h
index 3bbbfbe..5a43a4c 100644
--- a/include/scsi/scsi_dbg.h
+++ b/include/scsi/scsi_dbg.h
@@ -5,14 +5,16 @@ struct scsi_cmnd;
 struct scsi_sense_hdr;
 
 extern void scsi_print_command(struct scsi_cmnd *);
-extern void scsi_print_sense_hdr(const char *, struct scsi_sense_hdr *);
 extern void __scsi_print_command(unsigned char *);
-extern void scsi_print_sense(const char *, struct scsi_cmnd *);
+extern void scsi_show_extd_sense(unsigned char, unsigned char);
+extern void scsi_show_sense_hdr(struct scsi_sense_hdr *);
+extern void scsi_print_sense_hdr(const char *, struct scsi_sense_hdr *);
+extern void scsi_print_sense(char *, struct scsi_cmnd *);
 extern void __scsi_print_sense(const char *name,
 			       const unsigned char *sense_buffer,
 			       int sense_len);
-extern void scsi_print_driverbyte(int);
-extern void scsi_print_hostbyte(int);
+extern void scsi_show_result(int);
+extern void scsi_print_result(struct scsi_cmnd *);
 extern void scsi_print_status(unsigned char);
 extern const char *scsi_sense_key_string(unsigned char);
 extern const char *scsi_extd_sense_format(unsigned char, unsigned char);

linux-2.6-acpi-boot-regression.patch:

--- NEW FILE linux-2.6-acpi-boot-regression.patch ---
commit d5a3d32a042126f65a008e0e5204ef92ad2ee55d
Author: Venkatesh Pallipadi <venkatesh.pallipadi at intel.com>
Date:   Fri Jun 15 19:36:00 2007 -0400

    ACPI: fix 2.6.20 SMP boot regression
    
    Always disable/enable interrupts in the acpi idle routine,
    even in the error path.
    
    This is required as the 2.6.20 change in git commit d331e739f5ad2aaa9...
    "Fix interrupt race in idle callback" expects the idle handler
    to enable interrupt before returning.
    
    There was a case in acpi idle routine, in which interrupt was not being
    enabled before return, which caused the system to hang at bootup, while
    enabling C-states on an SMP system.
    
    The signature of the hang was that "processor.nocst"
    was required to enable boot.
    
    Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi at intel.com>
    Signed-off-by: Len Brown <len.brown at intel.com>

diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index ee5759b..80ffc78 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -332,16 +332,18 @@ static void acpi_processor_idle(void)
 	int sleep_ticks = 0;
 	u32 t1, t2 = 0;
 
-	pr = processors[smp_processor_id()];
-	if (!pr)
-		return;
-
 	/*
 	 * Interrupts must be disabled during bus mastering calculations and
 	 * for C2/C3 transitions.
 	 */
 	local_irq_disable();
 
+	pr = processors[smp_processor_id()];
+	if (!pr) {
+		local_irq_enable();
+		return;
+	}
+
 	/*
 	 * Check whether we truly need to go idle, or should
 	 * reschedule:

linux-2.6-acpi-dock-oops.patch:

--- NEW FILE linux-2.6-acpi-dock-oops.patch ---
---
 drivers/acpi/dock.c |    6 ++++++
 1 file changed, 6 insertions(+)

--- 2.6.21-d390.orig/drivers/acpi/dock.c
+++ 2.6.21-d390/drivers/acpi/dock.c
@@ -698,6 +698,7 @@ static int dock_add(acpi_handle handle)
 	if (ret) {
 		printk(KERN_ERR PREFIX "Error %d registering dock device\n", ret);
 		kfree(dock_station);
+		dock_station = NULL;
 		return ret;
 	}
 	ret = device_create_file(&dock_device.dev, &dev_attr_docked);
@@ -705,6 +706,7 @@ static int dock_add(acpi_handle handle)
 		printk("Error %d adding sysfs file\n", ret);
 		platform_device_unregister(&dock_device);
 		kfree(dock_station);
+		dock_station = NULL;
 		return ret;
 	}
 	ret = device_create_file(&dock_device.dev, &dev_attr_undock);
@@ -713,6 +715,7 @@ static int dock_add(acpi_handle handle)
 		device_remove_file(&dock_device.dev, &dev_attr_docked);
 		platform_device_unregister(&dock_device);
 		kfree(dock_station);
+		dock_station = NULL;
 		return ret;
 	}
 
@@ -725,6 +728,7 @@ static int dock_add(acpi_handle handle)
 	dd = alloc_dock_dependent_device(handle);
 	if (!dd) {
 		kfree(dock_station);
+		dock_station = NULL;
 		ret = -ENOMEM;
 		goto dock_add_err_unregister;
 	}
@@ -752,6 +756,7 @@ dock_add_err_unregister:
 	device_remove_file(&dock_device.dev, &dev_attr_undock);
 	platform_device_unregister(&dock_device);
 	kfree(dock_station);
+	dock_station = NULL;
 	return ret;
 }
 
@@ -785,6 +790,7 @@ static int dock_remove(void)
 
 	/* free dock station memory */
 	kfree(dock_station);
+	dock_station = NULL;
 	return 0;
 }
 

linux-2.6-acpi-git-ec-init-fixes.patch:

--- NEW FILE linux-2.6-acpi-git-ec-init-fixes.patch ---
From: Alexey Starikovskiy <astarikovskiy at suse.de>
Date: Wed, 5 Sep 2007 23:56:38 +0000 (-0400)
Subject: ACPI: EC: Drop ECDT-based boot_ec as soon as we find DSDT-based one.
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Flenb%2Flinux-acpi-2.6.git;a=commitdiff_plain;h=4c611060660f0de3e9b8f02df207312bc6f5c331

ACPI: EC: Drop ECDT-based boot_ec as soon as we find DSDT-based one.

ASUS notebooks have numerous problems with EC initialization
This patch tries to work around three known issues reported
in bugzilla 8598, 8709 and 8909/8919.

Signed-off-by: Alexey Starikovskiy <astarikovskiy at suse.de>
Signed-off-by: Len Brown <len.brown at intel.com>
---

diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 3f7935a..9cd7997 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -121,6 +121,7 @@ static struct acpi_ec {
 	atomic_t event_count;
 	wait_queue_head_t wait;
 	struct list_head list;
+	u8 handlers_installed;
 } *boot_ec, *first_ec;
 
 /* --------------------------------------------------------------------------
@@ -680,32 +681,50 @@ 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;
-
-	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 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;
+}
+
 static int acpi_ec_add(struct acpi_device *device)
 {
 	struct acpi_ec *ec = NULL;
 
 	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;
@@ -715,25 +734,14 @@ static int acpi_ec_add(struct acpi_device *device)
 		kfree(ec);
 		return -EINVAL;
 	}
-
-	/* 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;
+      end:
+	if (!first_ec)
+		first_ec = ec;
 	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;
 }
 
@@ -756,10 +764,7 @@ static int acpi_ec_remove(struct acpi_device *device, int type)
 	acpi_driver_data(device) = NULL;
 	if (ec == first_ec)
 		first_ec = NULL;
-
-	/* Don't touch boot EC */
-	if (boot_ec != ec)
-		kfree(ec);
+	kfree(ec);
 	return 0;
 }
 
@@ -789,6 +794,8 @@ 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);
@@ -807,6 +814,7 @@ static int ec_install_handlers(struct acpi_ec *ec)
 		return -ENODEV;
 	}
 
+	ec->handlers_installed = 1;
 	return 0;
 }
 
@@ -823,41 +831,22 @@ static int acpi_ec_start(struct acpi_device *device)
 	if (!ec)
 		return -EINVAL;
 
-	/* Boot EC is already working */
-	if (ec != boot_ec)
-		ret = ec_install_handlers(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;
-
-	/* 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;
+	ec_remove_handlers(ec);
 
 	return 0;
 }
@@ -877,7 +866,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\n");
+		printk(KERN_INFO PREFIX "EC description table is found, configuring boot EC\n");
 		boot_ec->command_addr = ecdt_ptr->control.address;
 		boot_ec->data_addr = ecdt_ptr->data.address;
 		boot_ec->gpe = ecdt_ptr->gpe;
@@ -899,7 +888,6 @@ int __init acpi_ec_ecdt_probe(void)
       error:
 	kfree(boot_ec);
 	boot_ec = NULL;
-
 	return -ENODEV;
 }
 

linux-2.6-acpi-keep-tsc-stable-when-lapic-timer-c2-ok-is-set.patch:

--- NEW FILE linux-2.6-acpi-keep-tsc-stable-when-lapic-timer-c2-ok-is-set.patch ---
Subject: ACPI: Keep TSC stable, when lapic_timer_c2_ok is set

The local apic timer stop in C2 resp. C3 states is coupled with the
stop of the TSC. When the local apic timer is marked stable in C2
on the kernel commandline, then keep the TSC marked stable in C2 as well.

Signed-off-by: Thomas Gleixner <tglx at linutronix.de>

---
 drivers/acpi/processor_idle.c |   19 ++++++++-----------
 1 file changed, 8 insertions(+), 11 deletions(-)

Index: linux-2.6.21/drivers/acpi/processor_idle.c
===================================================================
--- linux-2.6.21.orig/drivers/acpi/processor_idle.c
+++ linux-2.6.21/drivers/acpi/processor_idle.c
@@ -305,18 +305,23 @@ static void acpi_state_timer_broadcast(s
 				       struct acpi_processor_cx *cx,
 				       int broadcast)
 {
-#ifdef CONFIG_GENERIC_CLOCKEVENTS
-
 	int state = cx - pr->power.states;
 
 	if (state >= pr->power.timer_broadcast_on_state) {
+
+#ifdef CONFIG_GENERIC_CLOCKEVENTS
 		unsigned long reason;
 
 		reason = broadcast ?  CLOCK_EVT_NOTIFY_BROADCAST_ENTER :
 			CLOCK_EVT_NOTIFY_BROADCAST_EXIT;
 		clockevents_notify(reason, &pr->id);
-	}
 #endif
+
+#ifdef CONFIG_GENERIC_TIME
+		/* TSC halts in C2/3, so notify users */
+		mark_tsc_unstable();
+#endif
+	}
 }
 
 #else
@@ -481,10 +486,6 @@ static void acpi_processor_idle(void)
 		/* Get end time (ticks) */
 		t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
 
-#ifdef CONFIG_GENERIC_TIME
-		/* TSC halts in C2, so notify users */
-		mark_tsc_unstable();
-#endif
 		/* Re-enable interrupts */
 		local_irq_enable();
 		current_thread_info()->status |= TS_POLLING;
@@ -523,10 +524,6 @@ static void acpi_processor_idle(void)
 			acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0);
 		}
 
-#ifdef CONFIG_GENERIC_TIME
-		/* TSC halts in C3, so notify users */
-		mark_tsc_unstable();
-#endif
 		/* Re-enable interrupts */
 		local_irq_enable();
 		current_thread_info()->status |= TS_POLLING;

linux-2.6-acpi-preserve-ebx-in-acpi_copy_wakeup_routine.patch:

--- NEW FILE linux-2.6-acpi-preserve-ebx-in-acpi_copy_wakeup_routine.patch ---
Gitweb:     http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=c8cbee61c9d53ee28473ad33bbb54f6a88f5e3af
Commit:     c8cbee61c9d53ee28473ad33bbb54f6a88f5e3af
Parent:     e5d2861f31474b373ce7754dc5122b414a176c64
Author:     Tian Kevin <kevin.tian at intel.com>
AuthorDate: Sat Jun 23 17:16:52 2007 -0700
Committer:  Linus Torvalds <torvalds at woody.linux-foundation.org>
CommitDate: Sun Jun 24 08:59:12 2007 -0700

    ACPI: preserve the ebx value in acpi_copy_wakeup_routine
    
    Register %ebx serves as the "global offset table base register" for
    position-independent code.  For absolute code, %ebx serves as a local
    register and has no specified role in the function calling sequence.  In
    either case, a function must preserve the register value for the caller.
    
    acpi_copy_wakeup_routine overrides %ebx without saving it, this may corrupt
    the called data.
    
    Kevin found that most time the value of Sx is saved in %esi, however
    sometimes compiler also uses %ebx.  When this happens, suspends fails since
    sleep value in ebx is changed by acpi_copy_wakeup_routine.
    
    The same funtion in X86_64 doesn't have this problem.
    
    Signed-off-by: Zhang Rui <rui.zhang at intel.com>
    Looks-okay-to: Pavel Machek <pavel at ucw.cz>
    Signed-off-by: Rafael J. Wysocki <rjw at sisk.pl>
    Cc: Len Brown <lenb at kernel.org>
    Acked-by: Andi Kleen <ak at suse.de>
    Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
    Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
---
 arch/i386/kernel/acpi/wakeup.S |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/arch/i386/kernel/acpi/wakeup.S b/arch/i386/kernel/acpi/wakeup.S
index b781b38..a2295a3 100644
--- a/arch/i386/kernel/acpi/wakeup.S
+++ b/arch/i386/kernel/acpi/wakeup.S
@@ -230,6 +230,7 @@ bogus_magic:
 #
 ENTRY(acpi_copy_wakeup_routine)
 
+	pushl	%ebx
 	sgdt	saved_gdt
 	sidt	saved_idt
 	sldt	saved_ldt
@@ -263,6 +264,7 @@ ENTRY(acpi_copy_wakeup_routine)
 	movl	%edx, video_flags - wakeup_start (%eax)
 	movl	$0x12345678, real_magic - wakeup_start (%eax)
 	movl	$0x12345678, saved_magic
+	popl	%ebx
 	ret
 
 save_registers:

linux-2.6-acpi-unblacklist-dell-gx240.patch:

--- NEW FILE linux-2.6-acpi-unblacklist-dell-gx240.patch ---
>From davej  Wed May 23 17:33:54 2007
Return-Path: <linux-acpi-owner at vger.kernel.org>
X-Spam-Checker-Version: SpamAssassin 3.1.8 (2007-02-13) on
	gelk.kernelslacker.org
X-Spam-Level: 
X-Spam-Status: No, score=-1.6 required=5.0 tests=AWL,BAYES_00,FORGED_RCVD_HELO,
	NO_REAL_NAME,UNPARSEABLE_RELAY autolearn=no version=3.1.8
Received: from pobox.devel.redhat.com [10.11.255.8]
	by gelk.kernelslacker.org with IMAP (fetchmail-6.3.6)
	for <davej at localhost> (single-drop); Wed, 23 May 2007 17:33:54 -0400 (EDT)
Received: from pobox.devel.redhat.com ([unix socket])
	 by pobox.devel.redhat.com (Cyrus v2.2.12-Invoca-RPM-2.2.12-8.1.RHEL4) with LMTPA;
	 Wed, 23 May 2007 17:31:47 -0400
X-Sieve: CMU Sieve 2.2
Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254])
	by pobox.devel.redhat.com (8.13.1/8.13.1) with ESMTP id l4NLVlpG032241
	for <davej at pobox.devel.redhat.com>; Wed, 23 May 2007 17:31:47 -0400
Received: from mx1.redhat.com (mx1.redhat.com [172.16.48.31])
	by int-mx1.corp.redhat.com (8.13.1/8.13.1) with ESMTP id l4NLVkpU029647;
	Wed, 23 May 2007 17:31:46 -0400
Received: from vger.kernel.org (vger.kernel.org [209.132.176.167])
	by mx1.redhat.com (8.13.1/8.13.1) with ESMTP id l4NJIQrC021439;
	Wed, 23 May 2007 17:31:45 -0400
Received: (majordomo at vger.kernel.org) by vger.kernel.org via listexpand
	id S1755625AbXEWVYq (ORCPT <rfc822;prarit at redhat.com> + 1 other);
	Wed, 23 May 2007 17:24:46 -0400
Received: (majordomo at vger.kernel.org) by vger.kernel.org id S1755898AbXEWVYq
	(ORCPT <rfc822;linux-acpi-outgoing>);
	Wed, 23 May 2007 17:24:46 -0400
Received: from smtp1.linux-foundation.org ([207.189.120.13]:57412 "EHLO
	smtp1.linux-foundation.org" rhost-flags-OK-OK-OK-OK)
	by vger.kernel.org with ESMTP id S1755684AbXEWVYp (ORCPT
	<rfc822;linux-acpi at vger.kernel.org>);
	Wed, 23 May 2007 17:24:45 -0400
X-Greylist: delayed 661 seconds by postgrey-1.27 at vger.kernel.org; Wed, 23 May 2007 17:24:44 EDT
Received: from shell0.pdx.osdl.net (fw.osdl.org [65.172.181.6])
	by smtp1.linux-foundation.org (8.13.5.20060308/8.13.5/Debian-3ubuntu1.1) with ESMTP id l4NLCVvd022824
	(version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO);
	Wed, 23 May 2007 14:12:32 -0700
Received: from localhost.localdomain (shell0.pdx.osdl.net [10.9.0.31])
	by shell0.pdx.osdl.net (8.13.1/8.11.6) with ESMTP id l4NLCUrC032160;
	Wed, 23 May 2007 14:12:31 -0700
Message-Id: <200705232112.l4NLCUrC032160 at shell0.pdx.osdl.net>
Subject: [patch 6/6] Remove Dell Optiplex GX240 from the ACPI blacklist
To: lenb at kernel.org
Cc: linux-acpi at vger.kernel.org, akpm at linux-foundation.org, tarrqt at yahoo.com
From: akpm at linux-foundation.org
Date: 	Wed, 23 May 2007 14:12:30 -0700
X-MIMEDefang-Filter: osdl$Revision: 1.179 $
X-Scanned-By: MIMEDefang 2.53 on 207.189.120.13
Sender: linux-acpi-owner at vger.kernel.org
Precedence: bulk
X-Mailing-List: 	linux-acpi at vger.kernel.org
X-RedHat-Spam-Score: 0.55 
Status: RO
Content-Length: 2331
Lines: 62

From: Tear <tarrqt at yahoo.com>

I have a Dell Optiplex GX240 and when I boot Linux, ACPI gets set up by only
acpi=ht.  dmesg shows the following line:

   DELL GX240 detected: force use of acpi=ht

Everything seemed to be fine.  However, I discovered that everything is not
fine.  The USB controller works so slowly that copying a few (uncached) 1
megabyte large photos from a USB-enabled digital camera takes many minutes
instead of a couple of seconds.

I am using Linux 2.6.21.1 on a Debian 4.0 ("Etch") system.

I thought that this might be related to ACPI.  So I tried to boot with _only_
"acpi=force" appended to the kernel command line.  Voila, the USB controller
started to work at full speed and copying photos from my digital camera took
only seconds.

I tested the system with "acpi=force" and could not find anything which did
not work.  So, can we please remove Dell Optiplex GX240 from the blacklist in

..../arch/i386/kernel/acpi/boot.c

?  The attached patch does just that: It removes Dell Optiplex GX240 from the
ACPI blacklist.

I thought that this might be related to interrupts and APIC as well.  (Note
that this is APIC, not ACPI.) I tried booting with _only_ "noapic" and
"nolapic" appended to the command line.  Again, the USB controller started to
work at full speed.

Cc: Len Brown <lenb at kernel.org>
Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
---

 arch/i386/kernel/acpi/boot.c |    8 --------
 1 files changed, 8 deletions(-)

diff -puN arch/i386/kernel/acpi/boot.c~remove-dell-optiplex-gx240-from-the-acpi-blacklist arch/i386/kernel/acpi/boot.c
--- a/arch/i386/kernel/acpi/boot.c~remove-dell-optiplex-gx240-from-the-acpi-blacklist
+++ a/arch/i386/kernel/acpi/boot.c
@@ -971,14 +971,6 @@ static struct dmi_system_id __initdata a
 	 },
 	{
 	 .callback = force_acpi_ht,
-	 .ident = "DELL GX240",
-	 .matches = {
-		     DMI_MATCH(DMI_BOARD_VENDOR, "Dell Computer Corporation"),
-		     DMI_MATCH(DMI_BOARD_NAME, "OptiPlex GX240"),
-		     },
-	 },
-	{
-	 .callback = force_acpi_ht,
 	 .ident = "HP VISUALIZE NT Workstation",
 	 .matches = {
 		     DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
_
-
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


linux-2.6-add-mmf_dump_elf_headers.patch:

--- NEW FILE linux-2.6-add-mmf_dump_elf_headers.patch ---


*** Remember to use Documentation/SubmitChecklist when testing your code ***

See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt to find
out what to do about this

------------------------------------------------------
Subject: Add MMF_DUMP_ELF_HEADERS
From: Roland McGrath <roland at redhat.com>

This adds the MMF_DUMP_ELF_HEADERS option to /proc/pid/coredump_filter. 
This dumps the first page (only) of a private file mapping if it appears to
be a mapping of an ELF file.  Including these pages in the core dump may
give sufficient identifying information to associate the original DSO and
executable file images and their debugging information with a core file in
a generic way just from its contents (e.g.  when those binaries were built
with ld --build-id).  I expect this to become the default behavior
eventually.  Existing versions of gdb can be confused by the core dumps it
creates, so it won't enabled by default for some time to come.  Soon many
people will have systems with a gdb that handle these dumps, so they can
arrange to set the bit at boot and have it inherited system-wide.

This also cleans up the checking of the MMF_DUMP_* flag bits, which did not
need to be using atomic macros.

Signed-off-by: Roland McGrath <roland at redhat.com>
Cc: Hidehiro Kawai <hidehiro.kawai.ez at hitachi.com>
Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
---

 fs/binfmt_elf.c       |   78 +++++++++++++++++++++++++++-------------
 include/linux/sched.h |    3 +
 2 files changed, 55 insertions(+), 26 deletions(-)

diff -puN fs/binfmt_elf.c~add-mmf_dump_elf_headers fs/binfmt_elf.c
--- a/fs/binfmt_elf.c~add-mmf_dump_elf_headers
+++ a/fs/binfmt_elf.c
@@ -1201,35 +1201,68 @@ static int dump_seek(struct file *file, 
 }
 
 /*
- * Decide whether a segment is worth dumping; default is yes to be
- * sure (missing info is worse than too much; etc).
- * Personally I'd include everything, and use the coredump limit...
- *
- * I think we should skip something. But I am not sure how. H.J.
+ * Decide what to dump of a segment, part, all or none.
  */
-static int maydump(struct vm_area_struct *vma, unsigned long mm_flags)
+static unsigned long vma_dump_size(struct vm_area_struct *vma,
+				   unsigned long mm_flags)
 {
 	/* The vma can be set up to tell us the answer directly.  */
 	if (vma->vm_flags & VM_ALWAYSDUMP)
-		return 1;
+		goto whole;
 
 	/* Do not dump I/O mapped devices or special mappings */
 	if (vma->vm_flags & (VM_IO | VM_RESERVED))
 		return 0;
 
+#define FILTER(type)	(mm_flags & (1UL << MMF_DUMP_##type))
+
 	/* By default, dump shared memory if mapped from an anonymous file. */
 	if (vma->vm_flags & VM_SHARED) {
-		if (vma->vm_file->f_path.dentry->d_inode->i_nlink == 0)
-			return test_bit(MMF_DUMP_ANON_SHARED, &mm_flags);
-		else
-			return test_bit(MMF_DUMP_MAPPED_SHARED, &mm_flags);
+		if (vma->vm_file->f_path.dentry->d_inode->i_nlink == 0 ?
+		    FILTER(ANON_SHARED) : FILTER(MAPPED_SHARED))
+			goto whole;
+		return 0;
 	}
 
-	/* By default, if it hasn't been written to, don't write it out. */
-	if (!vma->anon_vma)
-		return test_bit(MMF_DUMP_MAPPED_PRIVATE, &mm_flags);
+	/* Dump segments that have been written to.  */
+	if (vma->anon_vma && FILTER(ANON_PRIVATE))
+		goto whole;
+	if (vma->vm_file == NULL)
+		return 0;
+
+	if (FILTER(MAPPED_PRIVATE))
+		goto whole;
 
-	return test_bit(MMF_DUMP_ANON_PRIVATE, &mm_flags);
+	/*
+	 * If this looks like the beginning of a DSO or executable mapping,
+	 * check for an ELF header.  If we find one, dump the first page to
+	 * aid in determining what was mapped here.
+	 */
+	if (FILTER(ELF_HEADERS) && vma->vm_file != NULL && vma->vm_pgoff == 0) {
+		u32 __user *header = (u32 __user *) vma->vm_start;
+		u32 word;
+		/*
+		 * Doing it this way gets the constant folded by GCC.
+		 */
+		union {
+			u32 cmp;
+			char elfmag[SELFMAG];
+		} magic;
+		BUILD_BUG_ON(SELFMAG != sizeof word);
+		magic.elfmag[EI_MAG0] = ELFMAG0;
+		magic.elfmag[EI_MAG1] = ELFMAG1;
+		magic.elfmag[EI_MAG2] = ELFMAG2;
+		magic.elfmag[EI_MAG3] = ELFMAG3;
+		if (get_user(word, header) == 0 && word == magic.cmp)
+			return PAGE_SIZE;
+	}
+
+#undef	FILTER
+
+	return 0;
+
+whole:
+	return vma->vm_end - vma->vm_start;
 }
 
 /* An ELF note in memory */
@@ -1675,16 +1708,13 @@ static int elf_core_dump(long signr, str
 	for (vma = first_vma(current, gate_vma); vma != NULL;
 			vma = next_vma(vma, gate_vma)) {
 		struct elf_phdr phdr;
-		size_t sz;
-
-		sz = vma->vm_end - vma->vm_start;
 
 		phdr.p_type = PT_LOAD;
 		phdr.p_offset = offset;
 		phdr.p_vaddr = vma->vm_start;
 		phdr.p_paddr = 0;
-		phdr.p_filesz = maydump(vma, mm_flags) ? sz : 0;
-		phdr.p_memsz = sz;
+		phdr.p_filesz = vma_dump_size(vma, mm_flags);
+		phdr.p_memsz = vma->vm_end - vma->vm_start;
 		offset += phdr.p_filesz;
 		phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
 		if (vma->vm_flags & VM_WRITE)
@@ -1726,13 +1756,11 @@ static int elf_core_dump(long signr, str
 	for (vma = first_vma(current, gate_vma); vma != NULL;
 			vma = next_vma(vma, gate_vma)) {
 		unsigned long addr;
+		unsigned long end;
 
-		if (!maydump(vma, mm_flags))
-			continue;
+		end = vma->vm_start + vma_dump_size(vma, mm_flags);
 
-		for (addr = vma->vm_start;
-		     addr < vma->vm_end;
-		     addr += PAGE_SIZE) {
+		for (addr = vma->vm_start; addr < end; addr += PAGE_SIZE) {
 			struct page *page;
 			struct vm_area_struct *vma;
 
diff -puN include/linux/sched.h~add-mmf_dump_elf_headers include/linux/sched.h
--- a/include/linux/sched.h~add-mmf_dump_elf_headers
+++ a/include/linux/sched.h
@@ -360,8 +360,9 @@ extern int get_dumpable(struct mm_struct
 #define MMF_DUMP_ANON_SHARED	3
 #define MMF_DUMP_MAPPED_PRIVATE	4
 #define MMF_DUMP_MAPPED_SHARED	5
+#define MMF_DUMP_ELF_HEADERS	6
 #define MMF_DUMP_FILTER_SHIFT	MMF_DUMPABLE_BITS
-#define MMF_DUMP_FILTER_BITS	4
+#define MMF_DUMP_FILTER_BITS	5
 #define MMF_DUMP_FILTER_MASK \
 	(((1 << MMF_DUMP_FILTER_BITS) - 1) << MMF_DUMP_FILTER_SHIFT)
 #define MMF_DUMP_FILTER_DEFAULT \

linux-2.6-add-sys-module-name-notes.patch:

--- NEW FILE linux-2.6-add-sys-module-name-notes.patch ---


*** Remember to use Documentation/SubmitChecklist when testing your code ***

See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt to find
out what to do about this

------------------------------------------------------
Subject: Add /sys/module/name/notes
From: Roland McGrath <roland at redhat.com>

This patch adds the /sys/module/<name>/notes/ magic directory, which has a
file for each allocated SHT_NOTE section that appears in <name>.ko.  This
is the counterpart for each module of /sys/kernel/notes for vmlinux. 
Reading this delivers the contents of the module's SHT_NOTE sections.  This
lets userland easily glean any detailed information about that module's
build that was stored there at compile time (e.g.  by ld --build-id).

Signed-off-by: Roland McGrath <roland at redhat.com>
Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
---

 include/linux/module.h |    3 +
 kernel/module.c        |  106 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 109 insertions(+)

diff -puN include/linux/module.h~add-sys-module-name-notes include/linux/module.h
--- a/include/linux/module.h~add-sys-module-name-notes
+++ a/include/linux/module.h
@@ -359,6 +359,9 @@ struct module
 
 	/* Section attributes */
 	struct module_sect_attrs *sect_attrs;
+
+	/* Notes attributes */
+	struct module_notes_attrs *notes_attrs;
 #endif
 
 	/* Per-cpu data. */
diff -puN kernel/module.c~add-sys-module-name-notes kernel/module.c
--- a/kernel/module.c~add-sys-module-name-notes
+++ a/kernel/module.c
@@ -20,6 +20,7 @@
 #include <linux/moduleloader.h>
 #include <linux/init.h>
 #include <linux/kallsyms.h>
+#include <linux/sysfs.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
@@ -1063,6 +1064,100 @@ static void remove_sect_attrs(struct mod
 	}
 }
 
+/*
+ * /sys/module/foo/notes/.section.name gives contents of SHT_NOTE sections.
+ */
+
+struct module_notes_attrs {
+	struct kobject *dir;
+	unsigned int notes;
+	struct bin_attribute attrs[0];
+};
+
+static ssize_t module_notes_read(struct kobject *kobj,
+				 struct bin_attribute *bin_attr,
+				 char *buf, loff_t pos, size_t count)
+{
+	/*
+	 * The caller checked the pos and count against our size.
+	 */
+	memcpy(buf, bin_attr->private + pos, count);
+	return count;
+}
+
+static void free_notes_attrs(struct module_notes_attrs *notes_attrs,
+			     unsigned int i)
+{
+	if (notes_attrs->dir) {
+		while (i-- > 0)
+			sysfs_remove_bin_file(notes_attrs->dir,
+					      &notes_attrs->attrs[i]);
+		kobject_del(notes_attrs->dir);
+	}
+	kfree(notes_attrs);
+}
+
+static void add_notes_attrs(struct module *mod, unsigned int nsect,
+			    char *secstrings, Elf_Shdr *sechdrs)
+{
+	unsigned int notes, loaded, i;
+	struct module_notes_attrs *notes_attrs;
+	struct bin_attribute *nattr;
+
+	/* Count notes sections and allocate structures.  */
+	notes = 0;
+	for (i = 0; i < nsect; i++)
+		if ((sechdrs[i].sh_flags & SHF_ALLOC) &&
+		    (sechdrs[i].sh_type == SHT_NOTE))
+			++notes;
+
+	if (notes == 0)
+		return;
+
+	notes_attrs = kzalloc(sizeof(*notes_attrs)
+			      + notes * sizeof(notes_attrs->attrs[0]),
+			      GFP_KERNEL);
+	if (notes_attrs == NULL)
+		return;
+
+	notes_attrs->notes = notes;
+	nattr = &notes_attrs->attrs[0];
+	for (loaded = i = 0; i < nsect; ++i) {
+		if (!(sechdrs[i].sh_flags & SHF_ALLOC))
+			continue;
+		if (sechdrs[i].sh_type == SHT_NOTE) {
+			nattr->attr.name = mod->sect_attrs->attrs[loaded].name;
+			nattr->attr.mode = S_IRUGO;
+			nattr->size = sechdrs[i].sh_size;
+			nattr->private = (void *) sechdrs[i].sh_addr;
+			nattr->read = module_notes_read;
+			++nattr;
+		}
+		++loaded;
+	}
+
+	notes_attrs->dir = kobject_add_dir(&mod->mkobj.kobj, "notes");
+	if (!notes_attrs->dir)
+		goto out;
+
+	for (i = 0; i < notes; ++i)
+		if (sysfs_create_bin_file(notes_attrs->dir,
+					  &notes_attrs->attrs[i]))
+			goto out;
+
+	mod->notes_attrs = notes_attrs;
+	return;
+
+  out:
+	free_notes_attrs(notes_attrs, i);
+}
+
+static void remove_notes_attrs(struct module *mod)
+{
+	if (mod->notes_attrs)
+		free_notes_attrs(mod->notes_attrs, mod->notes_attrs->notes);
+}
+
 #else
 
 static inline void add_sect_attrs(struct module *mod, unsigned int nsect,
@@ -1073,6 +1168,15 @@ static inline void add_sect_attrs(struct
 static inline void remove_sect_attrs(struct module *mod)
 {
 }
+
+static inline void add_notes_attrs(struct module *mod, unsigned int nsect,
+				   char *sectstrings, Elf_Shdr *sechdrs)
+{
+}
+
+static inline void remove_notes_attrs(struct module *mod)
+{
+}
 #endif /* CONFIG_KALLSYMS */
 
 #ifdef CONFIG_SYSFS
@@ -1207,6 +1311,7 @@ static void free_module(struct module *m
 {
 	/* Delete from various lists */
 	stop_machine_run(__unlink_module, mod, NR_CPUS);
+	remove_notes_attrs(mod);
 	remove_sect_attrs(mod);
 	mod_kobject_remove(mod);
 
@@ -1971,6 +2076,7 @@ static struct module *load_module(void _
 	if (err < 0)
 		goto arch_cleanup;
 	add_sect_attrs(mod, hdr->e_shnum, secstrings, sechdrs);
+	add_notes_attrs(mod, hdr->e_shnum, secstrings, sechdrs);
 
 	/* Size of section 0 is 0, so this works well if no unwind info. */
 	mod->unwind_info = unwind_add_table(mod,

linux-2.6-amd-disabled-svm-detect-msr-1.patch:

--- NEW FILE linux-2.6-amd-disabled-svm-detect-msr-1.patch ---
bz #246250

From: H.J. Lu

--- linux-2.6.21.i686/drivers/kvm/svm.h.msr	2007-06-28 22:42:12.000000000 -0700
+++ linux-2.6.21.i686/drivers/kvm/svm.h	2007-06-29 08:03:09.000000000 -0700
@@ -175,8 +175,8 @@ struct __attribute__ ((__packed__)) vmcb
 #define SVM_CPUID_FUNC 0x8000000a
 
 #define MSR_EFER_SVME_MASK (1ULL << 12)
-#define MSR_VM_CR       0xc0010114ULL
-#define MSR_VM_HSAVE_PA 0xc0010117ULL
+#define MSR_VM_CR       0xc0010114
+#define MSR_VM_HSAVE_PA 0xc0010117
 
 #define SVM_VM_CR_SVM_DISABLE 4
 

linux-2.6-amd-disabled-svm-detect.patch:

--- NEW FILE linux-2.6-amd-disabled-svm-detect.patch ---
commit cfc329b216bc3e54fe1107e8f714c7b3bc133224
Author: Joerg Roedel <joerg.roedel at amd.com>
Date:   Fri Jun 22 12:29:50 2007 +0300

    KVM: SVM: Reliably detect if SVM was disabled by BIOS
    
    This patch adds an implementation to the svm is_disabled function to
    detect reliably if the BIOS disabled the SVM feature in the CPU. This
    fixes the issues with kernel panics when loading the kvm-amd module on
    machines where SVM is available but disabled.
    
    Signed-off-by: Joerg Roedel <joerg.roedel at amd.com>
    Signed-off-by: Avi Kivity <avi at qumranet.com>

diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c
index 62ec38c..a0d4428 100644
--- a/drivers/kvm/svm.c
+++ b/drivers/kvm/svm.c
@@ -1735,6 +1735,12 @@ static void svm_inject_page_fault(struct kvm_vcpu *vcpu,
 
 static int is_disabled(void)
 {
+	u64 vm_cr;
+
+	rdmsrl(MSR_VM_CR, vm_cr);
+	if (vm_cr & (1 << SVM_VM_CR_SVM_DISABLE))
+		return 1;
+
 	return 0;
 }
 
diff --git a/drivers/kvm/svm.h b/drivers/kvm/svm.h
index 5e93814..005a9c5 100644
--- a/drivers/kvm/svm.h
+++ b/drivers/kvm/svm.h
@@ -175,8 +175,11 @@ struct __attribute__ ((__packed__)) vmcb {
 #define SVM_CPUID_FUNC 0x8000000a
 
 #define MSR_EFER_SVME_MASK (1ULL << 12)
+#define MSR_VM_CR       0xc0010114ULL
 #define MSR_VM_HSAVE_PA 0xc0010117ULL
 
+#define SVM_VM_CR_SVM_DISABLE 4
+
 #define SVM_SELECTOR_S_SHIFT 4
 #define SVM_SELECTOR_DPL_SHIFT 5
 #define SVM_SELECTOR_P_SHIFT 7

linux-2.6-at76.patch:

--- NEW FILE linux-2.6-at76.patch ---
diff -up linux-2.6.22.noarch/MAINTAINERS.orig linux-2.6.22.noarch/MAINTAINERS
--- linux-2.6.22.noarch/MAINTAINERS.orig	2007-09-26 19:57:31.000000000 -0400
+++ linux-2.6.22.noarch/MAINTAINERS	2007-09-26 19:59:33.000000000 -0400
@@ -685,6 +685,15 @@ W:	http://www.thekelleys.org.uk/atmel
 W:	http://atmelwlandriver.sourceforge.net/
 S:	Maintained
 
+ATMEL USB WIRELESS DRIVER
+P:	Pavel Roskin
+M:	proski at gnu.org
+L:	linux-wireless at vger.kernel.org
+L:	at76c503a-user at lists.berlios.de
+L:	at76c503a-develop at lists.berlios.de
+W:	http://at76c503a.berlios.de/
+S:	Maintained
+
 AUDIT SUBSYSTEM
 P:	David Woodhouse
 M:	dwmw2 at infradead.org
diff -up /dev/null linux-2.6.22.noarch/drivers/net/wireless/at76_usb.h
--- /dev/null	2007-09-25 08:26:55.562976333 -0400
+++ linux-2.6.22.noarch/drivers/net/wireless/at76_usb.h	2007-09-26 19:59:33.000000000 -0400
@@ -0,0 +1,662 @@
+/*
+ * Copyright (c) 2002,2003 Oliver Kurth
+ *	     (c) 2003,2004 Joerg Albert <joerg.albert at gmx.de>
+ *	     (c) 2007 Guido Guenther <agx at sigxcpu.org>
+ *
+ * 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 driver was based on information from the Sourceforge driver
+ * released and maintained by Atmel:
+ *
+ *  http://sourceforge.net/projects/atmelwlandriver/
+ *
+ * Although the code was completely re-written,
+ * it would have been impossible without Atmel's decision to
+ * release an Open Source driver (unfortunately the firmware was
+ * kept binary only). Thanks for that decision to Atmel!
+ */
+
+#ifndef _AT76_USB_H
+#define _AT76_USB_H
+
+#include <net/ieee80211.h>
+
+/* current driver version */
+#define DRIVER_VERSION	"0.16"
+
+/* Board types */
+enum board_type {
+	BOARD_503_ISL3861 = 1,
+	BOARD_503_ISL3863 = 2,
+	BOARD_503 = 3,
+	BOARD_503_ACC = 4,
+	BOARD_505 = 5,
+	BOARD_505_2958 = 6,
+	BOARD_505A = 7,
+	BOARD_505AMX = 8
+};
+
+/* our private ioctl's */
+/* preamble length (0 - long, 1 - short, 2 - auto) */
+#define AT76_SET_SHORT_PREAMBLE		(SIOCIWFIRSTPRIV + 0)
+#define AT76_GET_SHORT_PREAMBLE		(SIOCIWFIRSTPRIV + 1)
+/* which debug channels are enabled */
+#define AT76_SET_DEBUG			(SIOCIWFIRSTPRIV + 2)
+#define AT76_GET_DEBUG			(SIOCIWFIRSTPRIV + 3)
+/* power save mode (incl. the Atmel proprietary smart save mode) */
+#define AT76_SET_POWERSAVE_MODE		(SIOCIWFIRSTPRIV + 4)
+#define AT76_GET_POWERSAVE_MODE		(SIOCIWFIRSTPRIV + 5)
+/* min and max channel times for scan */
+#define AT76_SET_SCAN_TIMES		(SIOCIWFIRSTPRIV + 6)
+#define AT76_GET_SCAN_TIMES		(SIOCIWFIRSTPRIV + 7)
+/* scan mode (0 - active, 1 - passive) */
+#define AT76_SET_SCAN_MODE		(SIOCIWFIRSTPRIV + 8)
+#define AT76_GET_SCAN_MODE		(SIOCIWFIRSTPRIV + 9)
+
+#define CMD_STATUS_IDLE				0x00
+#define CMD_STATUS_COMPLETE			0x01
+#define CMD_STATUS_UNKNOWN			0x02
+#define CMD_STATUS_INVALID_PARAMETER		0x03
+#define CMD_STATUS_FUNCTION_NOT_SUPPORTED	0x04
+#define CMD_STATUS_TIME_OUT			0x07
+#define CMD_STATUS_IN_PROGRESS			0x08
+#define CMD_STATUS_HOST_FAILURE			0xff
+#define CMD_STATUS_SCAN_FAILED			0xf0
+
+/* answers to get op mode */
+#define OPMODE_NONE				0x00
+#define OPMODE_NORMAL_NIC_WITH_FLASH		0x01
+#define OPMODE_HW_CONFIG_MODE			0x02
+#define OPMODE_DFU_MODE_WITH_FLASH		0x03
+#define OPMODE_NORMAL_NIC_WITHOUT_FLASH		0x04
+
+#define CMD_SET_MIB		0x01
+#define CMD_GET_MIB		0x02
+#define CMD_SCAN		0x03
+#define CMD_JOIN		0x04
+#define CMD_START_IBSS		0x05
+#define CMD_RADIO		0x06
+#define CMD_STARTUP		0x0B
+#define CMD_GETOPMODE		0x33
+
+#define MIB_LOCAL		0x01
+#define MIB_MAC_ADDR		0x02
+#define MIB_MAC			0x03
+#define MIB_MAC_MGMT		0x05
+#define MIB_MAC_WEP		0x06
+#define MIB_PHY			0x07
+#define MIB_FW_VERSION		0x08
+#define MIB_MDOMAIN		0x09
+
+#define ADHOC_MODE		1
+#define INFRASTRUCTURE_MODE	2
+
+/* values for struct mib_local, field preamble_type */
+#define PREAMBLE_TYPE_LONG	0
+#define PREAMBLE_TYPE_SHORT	1
+#define PREAMBLE_TYPE_AUTO	2
+
+/* values for tx_rate */
+#define TX_RATE_1MBIT		0
+#define TX_RATE_2MBIT		1
+#define TX_RATE_5_5MBIT 	2
+#define TX_RATE_11MBIT		3
+#define TX_RATE_AUTO		4
+
+/* power management modes */
+#define AT76_PM_OFF		1
+#define AT76_PM_ON		2
+#define AT76_PM_SMART		3
+
+struct hwcfg_r505 {
+	u8 cr39_values[14];
+	u8 reserved1[14];
+	u8 bb_cr[14];
+	u8 pidvid[4];
+	u8 mac_addr[ETH_ALEN];
+	u8 regulatory_domain;
+	u8 reserved2[14];
+	u8 cr15_values[14];
+	u8 reserved3[3];
+} __attribute__((packed));
+
+struct hwcfg_rfmd {
+	u8 cr20_values[14];
+	u8 cr21_values[14];
+	u8 bb_cr[14];
+	u8 pidvid[4];
+	u8 mac_addr[ETH_ALEN];
+	u8 regulatory_domain;
+	u8 low_power_values[14];
+	u8 normal_power_values[14];
+	u8 reserved1[3];
+} __attribute__((packed));
+
+struct hwcfg_intersil {
+	u8 mac_addr[ETH_ALEN];
+	u8 cr31_values[14];
+	u8 cr58_values[14];
+	u8 pidvid[4];
+	u8 regulatory_domain;
+	u8 reserved[1];
+} __attribute__((packed));
+
+union at76_hwcfg {
+	struct hwcfg_intersil i;
+	struct hwcfg_rfmd r3;
+	struct hwcfg_r505 r5;
+};
+
+#define WEP_SMALL_KEY_LEN	(40 / 8)
+#define WEP_LARGE_KEY_LEN	(104 / 8)
+
+struct at76_card_config {
+	u8 exclude_unencrypted;
+	u8 promiscuous_mode;
+	u8 short_retry_limit;
+	u8 encryption_type;
+	__le16 rts_threshold;
+	__le16 fragmentation_threshold;	/* 256..2346 */
+	u8 basic_rate_set[4];
+	u8 auto_rate_fallback;	/* 0,1 */
+	u8 channel;
+	u8 privacy_invoked;
+	u8 wep_default_key_id;	/* 0..3 */
+	u8 current_ssid[32];
+	u8 wep_default_key_value[4][WEP_KEY_LEN];
+	u8 ssid_len;
+	u8 short_preamble;
+	__le16 beacon_period;
+} __attribute__((packed));
+
+struct at76_command {
+	u8 cmd;
[...5873 lines suppressed...]
+{
+	int ret;
+	struct at76_priv *priv;
+	struct fwentry *fwe;
+	struct usb_device *udev;
+	int op_mode;
+	int need_ext_fw = 0;
+	struct mib_fw_version fwv;
+	int board_type = (int)id->driver_info;
+
+	udev = usb_get_dev(interface_to_usbdev(interface));
+
+	/* Load firmware into kernel memory */
+	fwe = at76_load_firmware(udev, board_type);
+	if (!fwe) {
+		ret = -ENOENT;
+		goto error;
+	}
+
+	op_mode = at76_get_op_mode(udev);
+
+	at76_dbg(DBG_DEVSTART, "opmode %d", op_mode);
+
+	/* we get OPMODE_NONE with 2.4.23, SMC2662W-AR ???
+	   we get 204 with 2.4.23, Fiberline FL-WL240u (505A+RFMD2958) ??? */
+
+	if (op_mode == OPMODE_HW_CONFIG_MODE) {
+		err("cannot handle a device in HW_CONFIG_MODE (opmode %d)",
+		    op_mode);
+		ret = -EBUSY;
+		goto error;
+	}
+
+	if (op_mode != OPMODE_NORMAL_NIC_WITH_FLASH
+	    && op_mode != OPMODE_NORMAL_NIC_WITHOUT_FLASH) {
+		/* download internal firmware part */
+		at76_dbg(DBG_DEVSTART, "downloading internal firmware");
+		ret = at76_load_internal_fw(udev, fwe);
+		if (ret < 0) {
+			err("error %d downloading internal firmware", ret);
+			goto error;
+		}
+		usb_put_dev(udev);
+		return ret;
+	}
+
+	/* Internal firmware already inside the device.  Get firmware
+	 * version to test if external firmware is loaded.
+	 * This works only for newer firmware, e.g. the Intersil 0.90.x
+	 * says "control timeout on ep0in" and subsequent
+	 * at76_get_op_mode() fail too :-( */
+
+	/* if version >= 0.100.x.y or device with built-in flash we can
+	 * query the device for the fw version */
+	if ((fwe->fw_version.major > 0 || fwe->fw_version.minor >= 100)
+	    || (op_mode == OPMODE_NORMAL_NIC_WITH_FLASH)) {
+		ret = at76_get_mib(udev, MIB_FW_VERSION, &fwv, sizeof(fwv));
+		if (ret < 0 || (fwv.major | fwv.minor) == 0)
+			need_ext_fw = 1;
+	} else
+		/* No way to check firmware version, reload to be sure */
+		need_ext_fw = 1;
+
+	if (need_ext_fw) {
+		at76_dbg(DBG_DEVSTART, "downloading external firmware");
+
+		ret = at76_load_external_fw(udev, fwe);
+		if (ret)
+			goto error;
+
+		/* Re-check firmware version */
+		ret = at76_get_mib(udev, MIB_FW_VERSION, &fwv, sizeof(fwv));
+		if (ret < 0) {
+			err("error %d getting firmware version", ret);
+			goto error;
+		}
+
+		/* Major and minor version must match */
+		if (fwv.major != fwe->fw_version.major
+		    || fwv.minor != fwe->fw_version.minor) {
+			printk(KERN_ERR DRIVER_NAME
+			       ": wrong firmware version, loaded %d.%d.%d-%d, "
+			       "read back %d.%d.%d-%d\n",
+			       fwe->fw_version.major, fwe->fw_version.minor,
+			       fwe->fw_version.patch, fwe->fw_version.build,
+			       fwv.major, fwv.minor, fwv.patch, fwv.build);
+			ret = -EBUSY;
+			goto error;
+		}
+	}
+
+	priv = at76_alloc_new_device(udev);
+	if (!priv) {
+		ret = -ENOMEM;
+		goto error;
+	}
+
+	SET_NETDEV_DEV(priv->netdev, &interface->dev);
+	usb_set_intfdata(interface, priv);
+
+	memcpy(&priv->fw_version, &fwv, sizeof(struct mib_fw_version));
+	priv->board_type = board_type;
+
+	ret = at76_init_new_device(priv, interface);
+	if (ret < 0)
+		at76_delete_device(priv);
+
+	return ret;
+
+error:
+	usb_put_dev(udev);
+	return ret;
+}
+
+static void at76_disconnect(struct usb_interface *interface)
+{
+	struct at76_priv *priv;
+
+	priv = usb_get_intfdata(interface);
+	usb_set_intfdata(interface, NULL);
+
+	/* Disconnect after loading internal firmware */
+	if (!priv)
+		return;
+
+	printk(KERN_INFO "%s: disconnecting\n", priv->netdev->name);
+	at76_delete_device(priv);
+	printk(KERN_INFO DRIVER_NAME ": disconnected\n");
+}
+
+/* Structure for registering this driver with the USB subsystem */
+static struct usb_driver at76_driver = {
+	.name = DRIVER_NAME,
+	.probe = at76_probe,
+	.disconnect = at76_disconnect,
+	.id_table = dev_table,
+};
+
+static int __init at76_mod_init(void)
+{
+	int result;
+
+	printk(KERN_INFO DRIVER_DESC " " DRIVER_VERSION " loading\n");
+
+	mutex_init(&fw_mutex);
+
+	/* register this driver with the USB subsystem */
+	result = usb_register(&at76_driver);
+	if (result < 0)
+		err("usb_register failed (status %d)", result);
+
+	led_trigger_register_simple("at76_usb-tx", &ledtrig_tx);
+	return result;
+}
+
+static void __exit at76_mod_exit(void)
+{
+	int i;
+
+	printk(KERN_INFO DRIVER_DESC " " DRIVER_VERSION " unloading\n");
+	usb_deregister(&at76_driver);
+	for (i = 0; i < ARRAY_SIZE(firmwares); i++) {
+		if (firmwares[i].fw)
+			release_firmware(firmwares[i].fw);
+	}
+	led_trigger_unregister_simple(ledtrig_tx);
+}
+
+module_param_named(debug, at76_debug, int, 0600);
+MODULE_PARM_DESC(debug, "Debugging level");
+
+module_init(at76_mod_init);
+module_exit(at76_mod_exit);
+
+MODULE_AUTHOR("Oliver Kurth <oku at masqmail.cx>");
+MODULE_AUTHOR("Joerg Albert <joerg.albert at gmx.de>");
+MODULE_AUTHOR("Alex <alex at foogod.com>");
+MODULE_AUTHOR("Nick Jones");
+MODULE_AUTHOR("Balint Seeber <n0_5p4m_p13453 at hotmail.com>");
+MODULE_AUTHOR("Pavel Roskin <proski at gnu.org>");
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
diff -up linux-2.6.22.noarch/drivers/net/wireless/Kconfig.orig linux-2.6.22.noarch/drivers/net/wireless/Kconfig
--- linux-2.6.22.noarch/drivers/net/wireless/Kconfig.orig	2007-09-26 19:57:31.000000000 -0400
+++ linux-2.6.22.noarch/drivers/net/wireless/Kconfig	2007-09-26 19:59:33.000000000 -0400
@@ -381,6 +381,14 @@ config PCI_HERMES
 	  common.  Some of the built-in wireless adaptors in laptops are of
 	  this variety.
 
+config USB_ATMEL
+	tristate "Atmel at76c503/at76c505/at76c505a USB cards"
+	depends on WLAN_80211 && USB
+	select FW_LOADER
+	---help---
+	  Enable support for USB Wireless devices using Atmel at76c503,
+	  at76c505 or at76c505a chips.
+
 config PCMCIA_HERMES
 	tristate "Hermes PCMCIA card support"
 	depends on PCMCIA && HERMES

linux-2.6-ata-call-check-dma-with-qc-prepared.patch:

--- NEW FILE linux-2.6-ata-call-check-dma-with-qc-prepared.patch ---
Gitweb:     http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=e00f1ff3c8977eff07d0214d2f3478ac947bda0f
Commit:     e00f1ff3c8977eff07d0214d2f3478ac947bda0f
Parent:     914616a3c2a54504f3b0eda0b67fcd32226b3e83
Author:     Tejun Heo <htejun at gmail.com>
AuthorDate: Wed Jun 27 02:47:35 2007 +0900
Committer:  Jeff Garzik <jeff at garzik.org>
CommitDate: Wed Jun 27 02:50:08 2007 -0400

    libata: call ata_check_atapi_dma() with qc better prepared
    
    In atapi_xlat(), prepare qc better before calling
    ata_check_atapi_dma() such that ata_check_atapi_dma() can use info
    from qc.  While at it, reformat weird looking if/else block in the
    function.
    
    Signed-off-by: Tejun Heo <htejun at gmail.com>
    Signed-off-by: Jeff Garzik <jeff at garzik.org>
---
 drivers/ata/libata-scsi.c |   20 ++++++++------------
 1 files changed, 8 insertions(+), 12 deletions(-)

diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index c228df2..4ddf00c 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -2373,11 +2373,6 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
 	int using_pio = (dev->flags & ATA_DFLAG_PIO);
 	int nodata = (scmd->sc_data_direction == DMA_NONE);
 
-	if (!using_pio)
-		/* Check whether ATAPI DMA is safe */
-		if (ata_check_atapi_dma(qc))
-			using_pio = 1;
-
 	memset(qc->cdb, 0, dev->cdb_len);
 	memcpy(qc->cdb, scmd->cmnd, scmd->cmd_len);
 
@@ -2390,19 +2385,22 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
 	}
 
 	qc->tf.command = ATA_CMD_PACKET;
+	qc->nbytes = scmd->request_bufflen;
+
+	/* check whether ATAPI DMA is safe */
+	if (!using_pio && ata_check_atapi_dma(qc))
+		using_pio = 1;
 
-	/* no data, or PIO data xfer */
 	if (using_pio || nodata) {
+		/* no data, or PIO data xfer */
 		if (nodata)
 			qc->tf.protocol = ATA_PROT_ATAPI_NODATA;
 		else
 			qc->tf.protocol = ATA_PROT_ATAPI;
 		qc->tf.lbam = (8 * 1024) & 0xff;
 		qc->tf.lbah = (8 * 1024) >> 8;
-	}
-
-	/* DMA data xfer */
-	else {
+	} else {
+		/* DMA data xfer */
 		qc->tf.protocol = ATA_PROT_ATAPI_DMA;
 		qc->tf.feature |= ATAPI_PKT_DMA;
 
@@ -2411,8 +2409,6 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
 			qc->tf.feature |= ATAPI_DMADIR;
 	}
 
-	qc->nbytes = scmd->request_bufflen;
-
 	return 0;
 }
 

linux-2.6-ata-quirk.patch:

--- NEW FILE linux-2.6-ata-quirk.patch ---
--- linux-2.6.20/arch/ia64/kernel/quirks.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-2.6.20_fix/arch/ia64/kernel/quirks.c	2007-02-13 13:56:34.000000000 -0500
@@ -0,0 +1,45 @@
+/*
+ * This file contains work-arounds for ia64 platform bugs.
+ */
+#include <linux/pci.h>
+
+/*
+ * quirk_intel_ide_controller: If an ide/ata controller is
+ * at legacy mode, BIOS might initiates BAR(bar 0~3 and 5)
+ * with incorrect value. This quirk will reset the incorrect
+ * value to 0.
+ */
+static void __devinit quirk_intel_ide_controller(struct pci_dev *dev)
+{
+	unsigned int pos;
+	struct resource *res;
+	int fixed = 0;
+	u8 tmp8;
+
+	if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE)
+		return;
+
+	/* TODO: What if one channel is in native mode ... */
+	pci_read_config_byte(dev, PCI_CLASS_PROG, &tmp8);
+	if ((tmp8 & 5) == 5)
+		return;
+
+	for( pos = 0; pos < 6; pos ++ ) {
+		res = &dev->resource[pos];
+		if (!(res->flags & (IORESOURCE_IO | IORESOURCE_MEM)))
+			continue;
+
+		if (!res->start && res->end) {
+			res->start = res->end = 0;
+			res->flags = 0;
+			fixed = 1;
+		}
+	}
+	if (fixed)
+		printk(KERN_WARNING
+			"PCI device %s: BIOS resource configuration fixed.\n",
+			pci_name(dev));
+}
+
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_11, quirk_intel_ide_controller);
+
--- linux-2.6.20/arch/ia64/kernel/Makefile	2007-02-08 02:13:41.000000000 -0500
+++ linux-2.6.20_fix/arch/ia64/kernel/Makefile	2007-02-12 09:49:39.000000000 -0500
@@ -33,6 +33,7 @@ obj-$(CONFIG_CRASH_DUMP)	+= crash_dump.o
 obj-$(CONFIG_IA64_UNCACHED_ALLOCATOR)	+= uncached.o
 obj-$(CONFIG_AUDIT)		+= audit.o
 obj-$(CONFIG_PCI_MSI)		+= msi_ia64.o
+obj-$(CONFIG_PCI)		+= quirks.o
 mca_recovery-y			+= mca_drv.o mca_drv_asm.o
 
 obj-$(CONFIG_IA64_ESI)		+= esi.o

linux-2.6-ata-use-pio-for-non-16-byte-xfers.patch:

--- NEW FILE linux-2.6-ata-use-pio-for-non-16-byte-xfers.patch ---
Gitweb:     http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=b9a4197e266a40d5d1d16c9fb2a852cf10743afe
Commit:     b9a4197e266a40d5d1d16c9fb2a852cf10743afe
Parent:     e00f1ff3c8977eff07d0214d2f3478ac947bda0f
Author:     Tejun Heo <htejun at gmail.com>
AuthorDate: Wed Jun 27 02:48:43 2007 +0900
Committer:  Jeff Garzik <jeff at garzik.org>
CommitDate: Wed Jun 27 02:50:08 2007 -0400

    libata: use PIO for non-16 byte aligned ATAPI commands
    
    The IDE driver used DMA for ATAPI commands if READ/WRITE command is
    multiple of sector size or sg command is multiple of 16 bytes.  For
    libata, READ/WRITE sector alignment is guaranteed by the high level
    driver (sr), so we only have to worry about the 16 byte alignment.
    
    This patch makes ata_check_atapi_dma() always request PIO for all data
    transfer commands which are not multiple of 16 bytes.
    
    The following reports are related to this problem.
    
    http://bugzilla.kernel.org/show_bug.cgi?id=8605		(confirmed)
    http://thread.gmane.org/gmane.linux.kernel/476620	(confirmed)
    https://bugzilla.novell.com/show_bug.cgi?id=229260	(probably)
    
    Albert first pointed out the difference between IDE and libata.  Kudos
    to him.
    
    Signed-off-by: Tejun Heo <htejun at gmail.com>
    Cc: Albert Lee <albertcc at tw.ibm.com>
    Signed-off-by: Jeff Garzik <jeff at garzik.org>
    [cebbert at redhat.com: removed extraneous whitespace change for -stable]
---
 drivers/ata/libata-core.c |   33 ++++++++++-----------------------
 1 files changed, 10 insertions(+), 23 deletions(-)

diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 642097a..094b518 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -3900,33 +3900,19 @@ static void ata_fill_sg(struct ata_queued_cmd *qc)
 int ata_check_atapi_dma(struct ata_queued_cmd *qc)
 {
 	struct ata_port *ap = qc->ap;
-	int rc = 0; /* Assume ATAPI DMA is OK by default */
-
-	/* some drives can only do ATAPI DMA on read/write */
-	if (unlikely(qc->dev->horkage & ATA_HORKAGE_DMA_RW_ONLY)) {
-		struct scsi_cmnd *cmd = qc->scsicmd;
-		u8 *scsicmd = cmd->cmnd;
-
-		switch (scsicmd[0]) {
-		case READ_10:
-		case WRITE_10:
-		case READ_12:
-		case WRITE_12:
-		case READ_6:
-		case WRITE_6:
-			/* atapi dma maybe ok */
-			break;
-		default:
-			/* turn off atapi dma */
-			return 1;
-		}
-	}
+
+	/* Don't allow DMA if it isn't multiple of 16 bytes.  Quite a
+	 * few ATAPI devices choke on such DMA requests.
+	 */
+	if (unlikely(qc->nbytes & 15))
+		return 1;
 
 	if (ap->ops->check_atapi_dma)
-		rc = ap->ops->check_atapi_dma(qc);
+		return ap->ops->check_atapi_dma(qc);
 
-	return rc;
+	return 0;
 }
+
 /**
  *	ata_qc_prep - Prepare taskfile for submission
  *	@qc: Metadata associated with taskfile to be prepared

linux-2.6-ath5k.patch:

--- NEW FILE linux-2.6-ath5k.patch ---
diff -up linux-2.6.22.noarch/MAINTAINERS.orig linux-2.6.22.noarch/MAINTAINERS
--- linux-2.6.22.noarch/MAINTAINERS.orig	2007-09-27 19:25:02.000000000 -0400
+++ linux-2.6.22.noarch/MAINTAINERS	2007-09-27 19:26:44.000000000 -0400
@@ -642,6 +642,14 @@ M:	ecashin at coraid.com
 W:	http://www.coraid.com/support/linux
 S:	Supported
 
+ATHEROS ATH5K WIRELESS DRIVER
+P:	Jiri Slaby
+M:	jirislaby at gmail.com
+P:	Luis R. Rodriguez
+M:	mcgrof at gmail.com
+L:	linux-wireless at vger.kernel.org
+S:	Maintained
+
 ATL1 ETHERNET DRIVER
 P:	Jay Cliburn
 M:	jcliburn at gmail.com
diff -up linux-2.6.22.noarch/drivers/net/wireless/Makefile.orig linux-2.6.22.noarch/drivers/net/wireless/Makefile
--- linux-2.6.22.noarch/drivers/net/wireless/Makefile.orig	2007-09-27 19:25:02.000000000 -0400
+++ linux-2.6.22.noarch/drivers/net/wireless/Makefile	2007-09-27 19:27:03.000000000 -0400
@@ -61,3 +61,5 @@ obj-$(CONFIG_RT2X00)		+= rt2x00/
 obj-$(CONFIG_P54_COMMON)	+= p54common.o
 obj-$(CONFIG_P54_USB)		+= p54usb.o
 obj-$(CONFIG_P54_PCI)		+= p54pci.o
+
+obj-$(CONFIG_ATH5K)	+= ath5k/
diff -up linux-2.6.22.noarch/drivers/net/wireless/Kconfig.orig linux-2.6.22.noarch/drivers/net/wireless/Kconfig
--- linux-2.6.22.noarch/drivers/net/wireless/Kconfig.orig	2007-09-27 19:25:02.000000000 -0400
+++ linux-2.6.22.noarch/drivers/net/wireless/Kconfig	2007-09-27 19:26:44.000000000 -0400
@@ -598,6 +598,19 @@ config P54_PCI
 	tristate "Prism54 PCI support"
 	depends on P54_COMMON && PCI
 
+config ATH5K
+	tristate "Atheros 5xxx wireless cards support"
+	depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL
+	default m
+	---help---
+	  This module adds support for atheros 5xxx (e.g. 5212) wireless
+	  cards. If you have this card in your PC, select this to be build.
+
+	  This driver uses the kernel's mac80211 subsystem.
+
+	  If you choose to build a module, it'll be called ath5k. Say M if
+	  unsure.
+
 source "drivers/net/wireless/hostap/Kconfig"
 source "drivers/net/wireless/bcm43xx/Kconfig"
 source "drivers/net/wireless/b43/Kconfig"
diff -up /dev/null linux-2.6.22.noarch/drivers/net/wireless/ath5k/phy.c
--- /dev/null	2007-09-27 08:31:24.563724082 -0400
+++ linux-2.6.22.noarch/drivers/net/wireless/ath5k/phy.c	2007-09-27 19:26:44.000000000 -0400
@@ -0,0 +1,1704 @@
+/*
+ * PHY functions
+ *
+ * Copyright (c) 2006-2007 Nick Kossifidis <mickflemm at gmail.com>
+ *
+ *  This file is free software: you can copy, redistribute 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 file 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, see <http://www.gnu.org/licenses/>.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *
+ *     Copyright (c) 2007 Jiri Slaby <jirislaby at gmail.com>
+ *     Copyright (c) 2004, 2005, 2006, 2007 Reyk Floeter <reyk at openbsd.org>
+ *
+ *     Permission to use, copy, modify, and distribute this software for
+ *     any purpose with or without fee is hereby granted, provided that
+ *     the above copyright notice and this permission notice appear in all
+ *     copies.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ *     WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ *     WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ *     AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
+ *     CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+ *     OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ *     NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ *     CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/delay.h>
+
+#include "ath5k.h"
+#include "reg.h"
+
+/* Struct to hold initial RF register values (RF Banks) */
+struct ath5k_ini_rf {
+	u8	rf_bank;	/* check out ath5k_reg.h */
+	u16	rf_register;	/* register address */
+	u32	rf_value[5];	/* register value for different modes (above) */
+};
+
+/*
+ * Mode-specific RF Gain table (64bytes) for RF5111/5112
+ * (RF5110 only comes with AR5210 and only supports a/turbo a mode so initial
+ * RF Gain values are included in AR5K_AR5210_INI)
+ */
+struct ath5k_ini_rfgain {
+	u16	rfg_register;	/* RF Gain register address */
+	u32	rfg_value[2];	/* [freq (see below)] */
+};
+
+struct ath5k_gain_opt {
+	u32			go_default;
+	u32			go_steps_count;
+	const struct ath5k_gain_opt_step	go_step[AR5K_GAIN_STEP_COUNT];
+};
+
+/* RF5111 mode-specific init registers */
+static const struct ath5k_ini_rf rfregs_5111[] = {
+	{ 0, 0x989c,
+	/*    mode a/XR   mode aTurbo mode b      mode g      mode gTurbo */
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 0, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 0, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 0, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 0, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 0, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 0, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 0, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 0, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 0, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 0, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 0, 0x989c,
+	    { 0x00380000, 0x00380000, 0x00380000, 0x00380000, 0x00380000 } },
+	{ 0, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 0, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 0, 0x989c,
+	    { 0x00000000, 0x00000000, 0x000000c0, 0x00000080, 0x00000080 } },
+	{ 0, 0x989c,
+	    { 0x000400f9, 0x000400f9, 0x000400ff, 0x000400fd, 0x000400fd } },
+	{ 0, 0x98d4,
+	    { 0x00000000, 0x00000000, 0x00000004, 0x00000004, 0x00000004 } },
+	{ 1, 0x98d4,
+	    { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
+	{ 2, 0x98d4,
+	    { 0x00000010, 0x00000014, 0x00000010, 0x00000010, 0x00000014 } },
+	{ 3, 0x98d8,
+	    { 0x00601068, 0x00601068, 0x00601068, 0x00601068, 0x00601068 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } },
+	{ 6, 0x989c,
+	    { 0x04000000, 0x04000000, 0x04000000, 0x04000000, 0x04000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x00000000, 0x00000000, 0x0a000000, 0x00000000, 0x00000000 } },
+	{ 6, 0x989c,
+	    { 0x003800c0, 0x00380080, 0x023800c0, 0x003800c0, 0x003800c0 } },
+	{ 6, 0x989c,
+	    { 0x00020006, 0x00020006, 0x00000006, 0x00020006, 0x00020006 } },
+	{ 6, 0x989c,
+	    { 0x00000089, 0x00000089, 0x00000089, 0x00000089, 0x00000089 } },
+	{ 6, 0x989c,
+	    { 0x000000a0, 0x000000a0, 0x000000a0, 0x000000a0, 0x000000a0 } },
+	{ 6, 0x989c,
+	    { 0x00040007, 0x00040007, 0x00040007, 0x00040007, 0x00040007 } },
+	{ 6, 0x98d4,
+	    { 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a } },
+	{ 7, 0x989c,
[...13858 lines suppressed...]
+	enum ieee80211_if_types	opmode;
+	struct ath_hw		*ah;		/* Atheros HW */
+
+	int			debug;
+
+	struct ath_buf		*bufptr;	/* allocated buffer ptr */
+	struct ath_desc		*desc;		/* TX/RX descriptors */
+	dma_addr_t		desc_daddr;	/* DMA (physical) address */
+	size_t			desc_len;	/* size of TX/RX descriptors */
+	u16			cachelsz;	/* cache line size */
+
+	DECLARE_BITMAP(status, 6);
+#define ATH_STAT_INVALID	0		/* disable hardware accesses */
+#define ATH_STAT_MRRETRY	1		/* multi-rate retry support */
+#define ATH_STAT_PROMISC	2
+#define ATH_STAT_LEDBLINKING	3		/* LED blink operation active */
+#define ATH_STAT_LEDENDBLINK	4		/* finish LED blink operation */
+#define ATH_STAT_LEDSOFT	5		/* enable LED gpio status */
+
+	unsigned int		curmode;	/* current phy mode */
+	struct ieee80211_channel *curchan;	/* current h/w channel */
+
+	int 			iface_id;	/* add/remove_interface id */
+
+	struct {
+		u8	rxflags;	/* radiotap rx flags */
+		u8	txflags;	/* radiotap tx flags */
+		u16	ledon;		/* softled on time */
+		u16	ledoff;		/* softled off time */
+	} hwmap[32];				/* h/w rate ix mappings */
+
+	enum ath5k_int		imask;		/* interrupt mask copy */
+
+	DECLARE_BITMAP(keymap, AR5K_KEYCACHE_SIZE); /* key use bit map */
+
+	u8			bssidmask[ETH_ALEN];
+
+	unsigned int		led_pin,	/* GPIO pin for driving LED */
+				led_on,		/* pin setting for LED on */
+				led_off;	/* off time for current blink */
+	struct timer_list	led_tim;	/* led off timer */
+	u8			led_rxrate;	/* current rx rate for LED */
+	u8			led_txrate;	/* current tx rate for LED */
+
+	struct tasklet_struct	restq;		/* reset tasklet */
+
+	unsigned int		rxbufsize;	/* rx size based on mtu */
+	struct list_head	rxbuf;		/* receive buffer */
+	spinlock_t		rxbuflock;
+	u32			*rxlink;	/* link ptr in last RX desc */
+	struct tasklet_struct	rxtq;		/* rx intr tasklet */
+
+	struct list_head	txbuf;		/* transmit buffer */
+	spinlock_t		txbuflock;
+	unsigned int		txbuf_len;	/* buf count in txbuf list */
+	struct ath_txq		txqs[2];	/* beacon and tx */
+
+	struct ath_txq		*txq;		/* beacon and tx*/
+	struct tasklet_struct	txtq;		/* tx intr tasklet */
+
+	struct ath_buf		*bbuf;		/* beacon buffer */
+	unsigned int		bhalq,		/* HAL q for outgoing beacons */
+				bmisscount,	/* missed beacon transmits */
+				bintval,	/* beacon interval */
+				bsent;
+
+	struct timer_list	calib_tim;	/* calibration timer */
+};
+
+#define ath5k_hw_hasbssidmask(_ah) \
+	(ath5k_hw_get_capability(_ah, AR5K_CAP_BSSIDMASK, 0, NULL) == 0)
+#define ath5k_hw_hasveol(_ah) \
+	(ath5k_hw_get_capability(_ah, AR5K_CAP_VEOL, 0, NULL) == 0)
+
+#endif
diff -up /dev/null linux-2.6.22.noarch/drivers/net/wireless/ath5k/regdom.c
--- /dev/null	2007-09-27 08:31:24.563724082 -0400
+++ linux-2.6.22.noarch/drivers/net/wireless/ath5k/regdom.c	2007-09-27 19:26:44.000000000 -0400
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2004, 2005 Reyk Floeter <reyk at vantronix.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Basic regulation domain extensions for the IEEE 802.11 stack
+ */
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+
+#include "regdom.h"
+
+static const struct ath5k_regdommap {
+	enum ath5k_regdom dmn;
+	enum ath5k_regdom dmn5;
+	enum ath5k_regdom dmn2;
+} r_map[] = {
+	{ DMN_DEFAULT,		DMN_DEBUG,	DMN_DEBUG },
+	{ DMN_NULL_WORLD,	DMN_NULL,	DMN_WORLD },
+	{ DMN_NULL_ETSIB,	DMN_NULL,	DMN_ETSIB },
+	{ DMN_NULL_ETSIC,	DMN_NULL,	DMN_ETSIC },
+	{ DMN_FCC1_FCCA,	DMN_FCC1,	DMN_FCCA },
+	{ DMN_FCC1_WORLD,	DMN_FCC1,	DMN_WORLD },
+	{ DMN_FCC2_FCCA,	DMN_FCC2,	DMN_FCCA },
+	{ DMN_FCC2_WORLD,	DMN_FCC2,	DMN_WORLD },
+	{ DMN_FCC2_ETSIC,	DMN_FCC2,	DMN_ETSIC },
+	{ DMN_FRANCE_NULL,	DMN_ETSI3,	DMN_ETSI3 },
+	{ DMN_FCC3_FCCA,	DMN_FCC3,	DMN_WORLD },
+	{ DMN_ETSI1_WORLD,	DMN_ETSI1,	DMN_WORLD },
+	{ DMN_ETSI3_ETSIA,	DMN_ETSI3,	DMN_WORLD },
+	{ DMN_ETSI2_WORLD,	DMN_ETSI2,	DMN_WORLD },
+	{ DMN_ETSI3_WORLD,	DMN_ETSI3,	DMN_WORLD },
+	{ DMN_ETSI4_WORLD,	DMN_ETSI4,	DMN_WORLD },
+	{ DMN_ETSI4_ETSIC,	DMN_ETSI4,	DMN_ETSIC },
+	{ DMN_ETSI5_WORLD,	DMN_ETSI5,	DMN_WORLD },
+	{ DMN_ETSI6_WORLD,	DMN_ETSI6,	DMN_WORLD },
+	{ DMN_ETSI_NULL,	DMN_ETSI1,	DMN_ETSI1 },
+	{ DMN_MKK1_MKKA,	DMN_MKK1,	DMN_MKKA },
+	{ DMN_MKK1_MKKB,	DMN_MKK1,	DMN_MKKA },
+	{ DMN_APL4_WORLD,	DMN_APL4,	DMN_WORLD },
+	{ DMN_MKK2_MKKA,	DMN_MKK2,	DMN_MKKA },
+	{ DMN_APL_NULL,		DMN_APL1,	DMN_NULL },
+	{ DMN_APL2_WORLD,	DMN_APL2,	DMN_WORLD },
+	{ DMN_APL2_APLC,	DMN_APL2,	DMN_WORLD },
+	{ DMN_APL3_WORLD,	DMN_APL3,	DMN_WORLD },
+	{ DMN_MKK1_FCCA,	DMN_MKK1,	DMN_FCCA },
+	{ DMN_APL2_APLD,	DMN_APL2,	DMN_APLD },
+	{ DMN_MKK1_MKKA1,	DMN_MKK1,	DMN_MKKA },
+	{ DMN_MKK1_MKKA2,	DMN_MKK1,	DMN_MKKA },
+	{ DMN_APL1_WORLD,	DMN_APL1,	DMN_WORLD },
+	{ DMN_APL1_FCCA,	DMN_APL1,	DMN_FCCA },
+	{ DMN_APL1_APLA,	DMN_APL1,	DMN_WORLD },
+	{ DMN_APL1_ETSIC,	DMN_APL1,	DMN_ETSIC },
+	{ DMN_APL2_ETSIC,	DMN_APL2,	DMN_ETSIC },
+	{ DMN_APL5_WORLD,	DMN_APL5,	DMN_WORLD },
+	{ DMN_WOR0_WORLD,	DMN_WORLD,	DMN_WORLD },
+	{ DMN_WOR1_WORLD,	DMN_WORLD,	DMN_WORLD },
+	{ DMN_WOR2_WORLD,	DMN_WORLD,	DMN_WORLD },
+	{ DMN_WOR3_WORLD,	DMN_WORLD,	DMN_WORLD },
+	{ DMN_WOR4_WORLD,	DMN_WORLD,	DMN_WORLD },
+	{ DMN_WOR5_ETSIC,	DMN_WORLD,	DMN_WORLD },
+	{ DMN_WOR01_WORLD,	DMN_WORLD,	DMN_WORLD },
+	{ DMN_WOR02_WORLD,	DMN_WORLD,	DMN_WORLD },
+	{ DMN_EU1_WORLD,	DMN_ETSI1,	DMN_WORLD },
+	{ DMN_WOR9_WORLD,	DMN_WORLD,	DMN_WORLD },
+	{ DMN_WORA_WORLD,	DMN_WORLD,	DMN_WORLD },
+};
+
+enum ath5k_regdom ath5k_regdom2flag(enum ath5k_regdom dmn, u16 mhz)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(r_map); i++) {
+		if (r_map[i].dmn == dmn) {
+			if (mhz >= 2000 && mhz <= 3000)
+				return r_map[i].dmn2;
+			if (mhz >= IEEE80211_CHANNELS_5GHZ_MIN &&
+					mhz <= IEEE80211_CHANNELS_5GHZ_MAX)
+				return r_map[i].dmn5;
+		}
+	}
+
+	return DMN_DEBUG;
+}
+
+u16 ath5k_regdom_from_ieee(enum ath5k_regdom ieee)
+{
+	u32 regdomain = (u32)ieee;
+
+	/*
+	 * Use the default regulation domain if the value is empty
+	 * or not supported by the net80211 regulation code.
+	 */
+	if (ath5k_regdom2flag(regdomain, IEEE80211_CHANNELS_5GHZ_MIN) ==
+			DMN_DEBUG)
+		return (u16)AR5K_TUNE_REGDOMAIN;
+
+	/* It is supported, just return the value */
+	return regdomain;
+}
+
+enum ath5k_regdom ath5k_regdom_to_ieee(u16 regdomain)
+{
+	enum ath5k_regdom ieee = (enum ath5k_regdom)regdomain;
+
+	return ieee;
+}
+

linux-2.6-bcm43xx-pci-neuter.patch:

--- NEW FILE linux-2.6-bcm43xx-pci-neuter.patch ---
--- linux-2.6.21.noarch/drivers/net/wireless/bcm43xx/bcm43xx_main.c.orig	2007-05-08 14:16:48.000000000 -0400
+++ linux-2.6.21.noarch/drivers/net/wireless/bcm43xx/bcm43xx_main.c	2007-05-08 14:17:35.000000000 -0400
@@ -124,6 +124,7 @@
 	static struct pci_device_id bcm43xx_pci_tbl[] = {
 	/* Broadcom 4303 802.11b */
 	{ PCI_VENDOR_ID_BROADCOM, 0x4301, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+#if 0 /* Disable in favor of bcm43xx-mac80211 */
 	/* Broadcom 4307 802.11b */
 	{ PCI_VENDOR_ID_BROADCOM, 0x4307, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
 	/* Broadcom 4311 802.11(a)/b/g */
@@ -146,6 +147,7 @@
 	/* SB bus on BCM947xx */
 	{ PCI_VENDOR_ID_BROADCOM, 0x0800, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
 #endif
+#endif
 	{ 0 },
 };
 MODULE_DEVICE_TABLE(pci, bcm43xx_pci_tbl);

linux-2.6-cell-spu-device-tree.patch:

--- NEW FILE linux-2.6-cell-spu-device-tree.patch ---
Subject: [PATCH 01/10] cell: add cbe_node_to_cpu function
From: Christian Krafft <krafft at de.ibm.com>

This patch adds code to deal with conversion of
logical cpu to cbe nodes. It removes code that
assummed there were two logical CPUs per CBE.

Signed-off-by: Christian Krafft <krafft at de.ibm.com>
Signed-off-by: Arnd Bergmann <arnd.bergmann at de.ibm.com>

----------

Subject: [PATCH 07/10] add of_iomap function
From: Christian Krafft <krafft at de.ibm.com>

The of_iomap function maps memory for a given
device_node and returns a pointer to that memory.
This is used at some places, so it makes sense to
a seperate function.

Signed-off-by: Christian Krafft <krafft at de.ibm.com>
Signed-off-by: Arnd Bergmann <arnd.bergmann at de.ibm.com>

----------

Subject: [PATCH 08/10] cell: add support for proper device-tree
From: Christian Krafft <krafft at de.ibm.com>

This patch adds support for a proper device-tree.
A porper device-tree on cell contains be nodes
for each CBE containg nodes for SPEs and all the
other special devices on it.
Ofcourse oldschool devicetree is still supported.

Signed-off-by: Christian Krafft <krafft at de.ibm.com>
Signed-off-by: Arnd Bergmann <arnd.bergmann at de.ibm.com>


diff -ur linux-2.6.20.ppc64.3108/arch/powerpc/oprofile/op_model_cell.c linux-2.6.20.ppc64/arch/powerpc/oprofile/op_model_cell.c
--- linux-2.6.20.ppc64.3108/arch/powerpc/oprofile/op_model_cell.c	2007-04-24 18:03:51.000000000 +0100
+++ linux-2.6.20.ppc64/arch/powerpc/oprofile/op_model_cell.c	2007-04-24 19:34:42.000000000 +0100
@@ -37,6 +37,7 @@
 #include <asm/system.h>
 
 #include "../platforms/cell/interrupt.h"
+#include "../platforms/cell/cbe_regs.h"
 
 #define PPU_CYCLES_EVENT_NUM 1	/*  event number for CYCLES */
 #define PPU_CYCLES_GRP_NUM   1  /* special group number for identifying
diff -ur linux-2.6.20.ppc64.3108/arch/powerpc/platforms/cell/cbe_regs.c linux-2.6.20.ppc64/arch/powerpc/platforms/cell/cbe_regs.c
--- linux-2.6.20.ppc64/arch/powerpc//platforms/cell/cbe_regs.c	2007-04-24 22:50:22.000000000 +0100
+++ linux-2.6.20.ppc64.spustuff/arch/powerpc/platforms/cell/cbe_regs.c	2007-04-24 19:39:15.000000000 +0100
@@ -14,6 +14,8 @@
 #include <asm/pgtable.h>
 #include <asm/prom.h>
 #include <asm/ptrace.h>
+#include <asm/of_device.h>
+#include <asm/of_platform.h>
 
 #include "cbe_regs.h"
 
@@ -27,6 +29,7 @@
 static struct cbe_regs_map
 {
 	struct device_node *cpu_node;
+	struct device_node *be_node;
 	struct cbe_pmd_regs __iomem *pmd_regs;
 	struct cbe_iic_regs __iomem *iic_regs;
 	struct cbe_mic_tm_regs __iomem *mic_tm_regs;
@@ -37,30 +40,43 @@ static int cbe_regs_map_count;
 static struct cbe_thread_map
 {
 	struct device_node *cpu_node;
+	struct device_node *be_node;
 	struct cbe_regs_map *regs;
+	unsigned int thread_id;
+	unsigned int cbe_id;
 } cbe_thread_map[NR_CPUS];
 
+static cpumask_t cbe_local_mask[MAX_CBE] = { [0 ... MAX_CBE-1] = CPU_MASK_NONE };
+static cpumask_t cbe_first_online_cpu = CPU_MASK_NONE;
+
 static struct cbe_regs_map *cbe_find_map(struct device_node *np)
 {
 	int i;
 	struct device_node *tmp_np;
 
-	if (strcasecmp(np->type, "spe") == 0) {
-		if (np->data == NULL) {
-			/* walk up path until cpu node was found */
-			tmp_np = np->parent;
-			while (tmp_np != NULL && strcasecmp(tmp_np->type, "cpu") != 0)
-				tmp_np = tmp_np->parent;
+	if (strcasecmp(np->type, "spe")) {
+		for (i = 0; i < cbe_regs_map_count; i++)
+			if (cbe_regs_maps[i].cpu_node == np ||
+			    cbe_regs_maps[i].be_node == np)
+				return &cbe_regs_maps[i];
+		return NULL;
+	}
 
-			np->data = cbe_find_map(tmp_np);
-		}
+	if (np->data)
 		return np->data;
-	}
 
-	for (i = 0; i < cbe_regs_map_count; i++)
-		if (cbe_regs_maps[i].cpu_node == np)
-			return &cbe_regs_maps[i];
-	return NULL;
+	/* walk up path until cpu or be node was found */
+	tmp_np = np;
+	do {
+		tmp_np = tmp_np->parent;
+		/* on a correct devicetree we wont get up to root */
+		BUG_ON(!tmp_np);
+	} while (strcasecmp(tmp_np->type, "cpu") &&
+		 strcasecmp(tmp_np->type, "be"));
+
+	np->data = cbe_find_map(tmp_np);
+
+	return np->data;
 }
 
 struct cbe_pmd_regs __iomem *cbe_get_pmd_regs(struct device_node *np)
@@ -130,49 +146,69 @@ struct cbe_mic_tm_regs __iomem *cbe_get_
 }
 EXPORT_SYMBOL_GPL(cbe_get_cpu_mic_tm_regs);
 
-/* FIXME
- * This is little more than a stub at the moment.  It should be
- * fleshed out so that it works for both SMT and non-SMT, no
- * matter if the passed cpu is odd or even.
- * For SMT enabled, returns 0 for even-numbered cpu; otherwise 1.
- * For SMT disabled, returns 0 for all cpus.
- */
 u32 cbe_get_hw_thread_id(int cpu)
 {
-	return (cpu & 1);
+	return cbe_thread_map[cpu].thread_id;
 }
 EXPORT_SYMBOL_GPL(cbe_get_hw_thread_id);
 
-void __init cbe_regs_init(void)
+u32 cbe_cpu_to_node(int cpu)
 {
-	int i;
-	struct device_node *cpu;
+	return cbe_thread_map[cpu].cbe_id;
+}
+EXPORT_SYMBOL_GPL(cbe_cpu_to_node);
 
-	/* Build local fast map of CPUs */
-	for_each_possible_cpu(i)
-		cbe_thread_map[i].cpu_node = of_get_cpu_node(i, NULL);
+u32 cbe_node_to_cpu(int node)
+{
+	return find_first_bit( (unsigned long *) &cbe_local_mask[node], sizeof(cpumask_t));
+}
+EXPORT_SYMBOL_GPL(cbe_node_to_cpu);
 
-	/* Find maps for each device tree CPU */
-	for_each_node_by_type(cpu, "cpu") {
-		struct cbe_regs_map *map = &cbe_regs_maps[cbe_regs_map_count++];
+static struct device_node *cbe_get_be_node(int cpu_id)
+{
+	struct device_node *np;
+
+	for_each_node_by_type (np, "be") {
+		int len,i;
+		const phandle *cpu_handle;
+
+		cpu_handle = get_property(np, "cpus", &len);
+
+		for (i=0; i<len; i++)
+			if (of_find_node_by_phandle(cpu_handle[i]) == of_get_cpu_node(cpu_id, NULL))
+				return np;
+	}
+
+	return NULL;
+}
+
+void __init cbe_fill_regs_map(struct cbe_regs_map *map)
+{
+	if(map->be_node) {
+		struct device_node *be, *np;
 
+		be = map->be_node;
+
+		for_each_node_by_type(np, "pervasive")
+			if (of_get_parent(np) == be)
+				map->pmd_regs = of_iomap(np, 0);
+
+		for_each_node_by_type(np, "CBEA-Internal-Interrupt-Controller")
+			if (of_get_parent(np) == be)
+				map->iic_regs = of_iomap(np, 2);
+
+		for_each_node_by_type(np, "mic-tm")
+			if (of_get_parent(np) == be)
+				map->mic_tm_regs = of_iomap(np, 0);
+	} else {
+		struct device_node *cpu;
 		/* That hack must die die die ! */
 		const struct address_prop {
 			unsigned long address;
 			unsigned int len;
 		} __attribute__((packed)) *prop;
 
-
-		if (cbe_regs_map_count > MAX_CBE) {
-			printk(KERN_ERR "cbe_regs: More BE chips than supported"
-			       "!\n");
-			cbe_regs_map_count--;
-			return;
-		}
-		map->cpu_node = cpu;
-		for_each_possible_cpu(i)
-			if (cbe_thread_map[i].cpu_node == cpu)
-				cbe_thread_map[i].regs = map;
+		cpu = map->cpu_node;
 
 		prop = get_property(cpu, "pervasive", NULL);
 		if (prop != NULL)
@@ -182,10 +218,56 @@ void __init cbe_regs_init(void)
 		if (prop != NULL)
 			map->iic_regs = ioremap(prop->address, prop->len);
 
-		prop = (struct address_prop *)get_property(cpu, "mic-tm",
-							   NULL);
+		prop = get_property(cpu, "mic-tm", NULL);
 		if (prop != NULL)
 			map->mic_tm_regs = ioremap(prop->address, prop->len);
 	}
 }
 
+
+void __init cbe_regs_init(void)
+{
+	int i;
+	unsigned int thread_id;
+	struct device_node *cpu;
+
+	/* Build local fast map of CPUs */
+	for_each_possible_cpu(i) {
+		cbe_thread_map[i].cpu_node = of_get_cpu_node(i, &thread_id);
+		cbe_thread_map[i].be_node = cbe_get_be_node(i);
+		cbe_thread_map[i].thread_id = thread_id;
+	}
+
+	/* Find maps for each device tree CPU */
+	for_each_node_by_type(cpu, "cpu") {
+		struct cbe_regs_map *map;
+		unsigned int cbe_id;
+
+		cbe_id = cbe_regs_map_count++;
+		map = &cbe_regs_maps[cbe_id];
+
+		if (cbe_regs_map_count > MAX_CBE) {
+			printk(KERN_ERR "cbe_regs: More BE chips than supported"
+			       "!\n");
+			cbe_regs_map_count--;
+			return;
+		}
+		map->cpu_node = cpu;
+
+		for_each_possible_cpu(i) {
+			struct cbe_thread_map *thread = &cbe_thread_map[i];
+
+			if (thread->cpu_node == cpu) {
+				thread->regs = map;
+				thread->cbe_id = cbe_id;
+				map->be_node = thread->be_node;
+				cpu_set(i, cbe_local_mask[cbe_id]);
+				if(thread->thread_id == 0)
+					cpu_set(i, cbe_first_online_cpu);
+			}
+		}
+
+		cbe_fill_regs_map(map);
+	}
+}
+
diff -ur linux-2.6.20.ppc64.3108/arch/powerpc/platforms/cell/cbe_regs.h linux-2.6.20.ppc64/arch/powerpc/platforms/cell/cbe_regs.h
--- linux-2.6.20.ppc64.3108/arch/powerpc/platforms/cell/cbe_regs.h	2007-02-04 18:44:54.000000000 +0000
+++ linux-2.6.20.ppc64/arch/powerpc/platforms/cell/cbe_regs.h	2007-04-24 19:34:42.000000000 +0100
@@ -255,6 +255,11 @@
 extern struct cbe_mic_tm_regs __iomem *cbe_get_mic_tm_regs(struct device_node *np);
 extern struct cbe_mic_tm_regs __iomem *cbe_get_cpu_mic_tm_regs(int cpu);
 
+/* some utility functions to deal with SMT */
+extern u32 cbe_get_hw_thread_id(int cpu);
+extern u32 cbe_cpu_to_node(int cpu);
+extern u32 cbe_node_to_cpu(int node);
+
 /* Init this module early */
 extern void cbe_regs_init(void);
 
diff -ur linux-2.6.20.ppc64.3108/include/asm-powerpc/cell-pmu.h linux-2.6.20.ppc64/include/asm-powerpc/cell-pmu.h
--- linux-2.6.20.ppc64.3108/include/asm-powerpc/cell-pmu.h	2007-04-24 18:03:57.000000000 +0100
+++ linux-2.6.20.ppc64/include/asm-powerpc/cell-pmu.h	2007-04-24 19:34:42.000000000 +0100
@@ -97,11 +97,6 @@
 extern u32  cbe_get_and_clear_pm_interrupts(u32 cpu);
 extern void cbe_sync_irq(int node);
 
-/* Utility functions, macros */
-extern u32 cbe_get_hw_thread_id(int cpu);
-
-#define cbe_cpu_to_node(cpu) ((cpu) >> 1)
-
 #define CBE_COUNT_SUPERVISOR_MODE       0
 #define CBE_COUNT_HYPERVISOR_MODE       1
 #define CBE_COUNT_PROBLEM_MODE          2
--- linux-2.6.orig/arch/powerpc/sysdev/pmi.c
+++ linux-2.6/arch/powerpc/sysdev/pmi.c
@@ -33,7 +33,7 @@
 #include <asm/of_platform.h>
 #include <asm/io.h>
 #include <asm/pmi.h>
-
+#include <asm/prom.h>
 
 struct pmi_data {
 	struct list_head	handler;
@@ -49,21 +49,6 @@ struct pmi_data {
 };
 
 
-
-static void __iomem *of_iomap(struct device_node *np)
-{
-	struct resource res;
-
-	if (of_address_to_resource(np, 0, &res))
-		return NULL;
-
-	pr_debug("Resource start: 0x%lx\n", res.start);
-	pr_debug("Resource end: 0x%lx\n", res.end);
-
-	return ioremap(res.start, 1 + res.end - res.start);
-}
-
-
 static int pmi_irq_handler(int irq, void *dev_id)
 {
 	struct pmi_data *data;
@@ -154,7 +139,7 @@ static int pmi_of_probe(struct of_device
 		goto out;
 	}
 
-	data->pmi_reg = of_iomap(np);
+	data->pmi_reg = of_iomap(np, 0);
 	if (!data->pmi_reg) {
 		printk(KERN_ERR "pmi: invalid register address.\n");
 		rc = -EFAULT;
Index: linux-2.6/include/asm-powerpc/prom.h
===================================================================
--- linux-2.6.orig/include/asm-powerpc/prom.h
+++ linux-2.6/include/asm-powerpc/prom.h
@@ -20,6 +20,7 @@
 #include <linux/platform_device.h>
 #include <asm/irq.h>
 #include <asm/atomic.h>
+#include <asm/io.h>
 
 /* Definitions used by the flattened device tree */
 #define OF_DT_HEADER		0xd00dfeed	/* marker */
@@ -355,6 +356,16 @@ static inline int of_irq_to_resource(str
 	return irq;
 }
 
+static inline void __iomem *of_iomap(struct device_node *np, int index)
+{
+	struct resource res;
+
+	if (of_address_to_resource(np, index, &res))
+		return NULL;
+
+	return ioremap(res.start, 1 + res.end - res.start);
+}
+
 
 #endif /* __KERNEL__ */
 #endif /* _POWERPC_PROM_H */

--

_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev at ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev

linux-2.6-cell-spufs-fixes.patch:

--- NEW FILE linux-2.6-cell-spufs-fixes.patch ---
commit ccf17e9d008dfebbf90dfa4ee1a56e81c784c73e
Author: Jeremy Kerr <jk at ozlabs.org>
Date:   Mon Apr 23 21:08:29 2007 +0200

    [POWERPC] spu_base: fix initialisation on systems with no SPEs
    
    This change fixes the case where spu_base and spufs are initialised on a
    system with no SPEs - unconditionally create the spu_lists so spu_alloc
    doesn't explode, and check for spu_management ops before starting spufs.
    
    Signed-off-by: Jeremy Kerr <jk at ozlabs.org>
    Signed-off-by: Arnd Bergmann <arnd.bergmann at de.ibm.com>
    
     arch/powerpc/platforms/cell/spu_base.c    |    7 ++++---
     arch/powerpc/platforms/cell/spufs/inode.c |    5 +++++
     2 files changed, 9 insertions(+), 3 deletions(-)

commit befdc746ee027d686a06be29cb1391f9d2c45cf6
Author: Christoph Hellwig <hch at lst.de>
Date:   Mon Apr 23 21:08:28 2007 +0200

    [POWERPC] spu_base: remove cleanup_spu_base
    
    spu_base.c is always built into the kernel image, so there is no need
    for a cleanup function.  And some of the things it does are in the
    way for my following patches, so I'd rather get rid of it ASAP.
    
    Signed-off-by: Christoph Hellwig <hch at lst.de>
    Signed-off-by: Arnd Bergmann <arnd.bergmann at de.ibm.com>

commit aa45e2569ffe963dfbbbfddfdccd12afe69b2d65
Author: Christoph Hellwig <hch at lst.de>
Date:   Mon Apr 23 21:08:27 2007 +0200

    [POWERPC] spufs: various run.c cleanups
    
     - remove the spu_acquire_runnable from spu_run_init.  I need to
       opencode it in spufs_run_spu in the next patch
     - remove various inline attributes, we don't really want to inline
       long functions with multiple callsites
     - cleanup return values and runcntl_write calls in spu_run_init
     - use normal kernel codingstyle in spu_reacquire_runnable
    
    Signed-off-by: Christoph Hellwig <hch at lst.de>
    Signed-off-by: Arnd Bergmann <arnd.bergmann at de.ibm.com>

commit fe8a29db5bce1b5bd1ceb85fd153fac52cdab7b2
Author: Akinobu Mita <mita at fixstars.com>
Date:   Mon Apr 23 21:08:26 2007 +0200

    [POWERPC] spufs: enable SPU coredump for kernel-builtin spufs
    
    spu_coredump_calls.owner is NULL in case of a builtin spufs,
    so the checks in here break.
    Check for the availability of the spu_coredump_calls variable
    instead.
    
    Signed-off-by: Arnd Bergmann <arnd.bergmann at de.ibm.com>

commit 6cf2179202cf706471777ad6ee5d0377d5990ab7
Author: Arnd Bergmann <arnd.bergmann at de.ibm.com>
Date:   Mon Apr 23 21:08:25 2007 +0200

    [POWERPC] spufs: fix memory leak on coredump
    
    Dynamically allocated read/write buffer in spufs_arch_write_note() will
    not be freed. Convert it to get_free_page at the same time.
    
    Cc: Akinobu Mita <mita at fixstars.com>
    Signed-off-by: Arnd Bergmann <arnd.bergmann at de.ibm.com>

commit d3764397d07b1e03943edfdcc3fb77af7bdac02b
Author: Jeremy Kerr <jk at ozlabs.org>
Date:   Mon Apr 23 21:08:24 2007 +0200

    [POWERPC] spufs: Minor cleanup of spu_wait
    
    Change the loop in spu_wait to be a little more straightforward.
    
    Signed-off-by: Jeremy Kerr <jk at ozlabs.org>
    Signed-off-by: Arnd Bergmann <arnd.bergmann at de.ibm.com>

commit f11f5ee70f48899506514e5e0d10ee2c8ddd359a
Author: Jeremy Kerr <jk at ozlabs.org>
Date:   Mon Apr 23 21:08:23 2007 +0200

    [POWERPC] spufs: add mode= mount option
    
    Add a 'mode=' option to spufs mount arguments. This allows more
    control over access to the top-level spufs directory.
    
    Tested on Cell.
    
    Signed-off-by: Jeremy Kerr <jk at ozlabs.org>
    Signed-off-by: Arnd Bergmann <arnd.bergmann at de.ibm.com>

commit 9e2fe2ce4e957a79d3dc5d813e0cfb10d79b79b3
Author: Akinobu Mita <mita at fixstars.com>
Date:   Mon Apr 23 21:08:22 2007 +0200

    [POWERPC] spufs: use memcpy_fromio() to copy from local store
    
    GCC may generates inline copy loop to handle memcpy() function
    instead of kernel defined memcpy(). But this inlined version of memcpy()
    causes an alignment interrupt when copying from local store.
    
    This patch uses memcpy_fromio() and memcpy_toio to copy local store
    to prevent memcpy() being inlined.
    
    Signed-off-by: Akinobu Mita <mita at fixstars.com>
    Signed-off-by: Arnd Bergmann <arnd.bergmann at de.ibm.com>

commit 8a7d86bdb22678b17928eef0c8fa356d8b21cc76
Author: Christoph Hellwig <hch at lst.de>
Date:   Mon Apr 23 21:08:21 2007 +0200

    [POWERPC] spufs: avoid spurious memory barriers
    
    We now have proper locking around assignets of the mapping pointers,
    and the spin_unlock implies enough of a barrier to get rid of the
    explicit one.
    
    Signed-off-by: Christoph Hellwig <hch at lst.de>
    Signed-off-by: Arnd Bergmann <arnd.bergmann at de.ibm.com>

commit db1384b40d12eda6910513ff429ad90453ca49e1
Author: Akinobu Mita <mita at fixstars.com>
Date:   Mon Apr 23 21:08:20 2007 +0200

    [POWERPC] spufs: fix memory leak on spufs reloading
    
    When SPU isolation mode enabled, isolated_loader would be
    allocated by spufs_init_isolated_loader() on module_init().
    But anyone do not free it.
    
    This patch introduces spufs_exit_isolated_loader() which is
    the opposite of spufs_init_isolated_loader() and called on
    module_exit().
    
    Cc: Arnd Bergmann <arnd at arndb.de>
    Signed-off-by: Akinobu Mita <mita at fixstars.com>
    Signed-off-by: Christoph Hellwig <hch at lst.de>
    Signed-off-by: Arnd Bergmann <arnd.bergmann at de.ibm.com>

commit c99c1994a2bb9493b4ac372b2b6ee2606d291171
Author: Akinobu Mita <mita at fixstars.com>
Date:   Mon Apr 23 21:08:19 2007 +0200

    [POWERPC] spufs: fix missing error handling in module_init()
    
    spufs module_init forgot to call a few cleanup functions
    on error path. This patch also includes cosmetic changes in
    spu_sched_init() (identation fix and return error code).
    
    [modified by hch to apply ontop of the latest schedule changes]
    
    Cc: Arnd Bergmann <arnd at arndb.de>
    Signed-off-by: Akinobu Mita <mita at fixstars.com>
    Signed-off-by: Christoph Hellwig <hch at lst.de>
    Signed-off-by: Arnd Bergmann <arnd.bergmann at de.ibm.com>

commit 577f8f1021f9ee6ef2a98a142652759ec122d27f
Author: Akinobu Mita <mita at fixstars.com>
Date:   Mon Apr 23 21:08:18 2007 +0200

    [POWERPC] spufs: check spu_acquire_runnable() return value
    
    This patch checks return value of spu_acquire_runnable() in
    spufs_mfc_write().
    
    Signed-off-by: Akinobu Mita <mita at fixstars.com>
    Signed-off-by: Christoph Hellwig <hch at lst.de>
    Signed-off-by: Arnd Bergmann <arnd.bergmann at de.ibm.com>

commit e45d48a34d4d1862d28d22c2533b8c6bb83b8c1f
Author: Christoph Hellwig <hch at lst.de>
Date:   Mon Apr 23 21:08:17 2007 +0200

    [POWERPC] spufs: turn run_sema into run_mutex
    
    There is no reason for run_sema to be a struct semaphore.  Changing
    it to a mutex and rename it accordingly.
    
    Signed-off-by: Christoph Hellwig <hch at lst.de>
    Signed-off-by: Arnd Bergmann <arnd.bergmann at de.ibm.com>

commit c8a1e9393a86f862ab9c8bc0db9b8a1822226f84
Author: Jeremy Kerr <jk at ozlabs.org>
Date:   Mon Apr 23 21:08:16 2007 +0200

    [POWERPC] spufs: provide siginfo for SPE faults
    
    This change populates a siginfo struct for SPE application exceptions
    (ie, invalid DMAs and illegal instructions).
    
    Tested on an IBM Cell Blade.
    
    Signed-off-by: Jeremy Kerr <jk at ozlabs.org>
    Signed-off-by: Arnd Bergmann <arnd.bergmann at de.ibm.com>
[...1665 lines suppressed...]
+		spin_lock(&spu_prio->runq_lock);
+		__spu_del_from_rq(ctx);
 	}
+	spin_unlock(&spu_prio->runq_lock);
 	__set_current_state(TASK_RUNNING);
 	remove_wait_queue(&ctx->stop_wq, &wait);
 }
@@ -280,9 +290,14 @@ static void spu_reschedule(struct spu *spu)
 	spin_lock(&spu_prio->runq_lock);
 	best = sched_find_first_bit(spu_prio->bitmap);
 	if (best < MAX_PRIO) {
-		struct spu_context *ctx = spu_grab_context(best);
-		if (ctx)
-			wake_up(&ctx->stop_wq);
+		struct list_head *rq = &spu_prio->runq[best];
+		struct spu_context *ctx;
+
+		BUG_ON(list_empty(rq));
+
+		ctx = list_entry(rq->next, struct spu_context, rq);
+		__spu_del_from_rq(ctx);
+		wake_up(&ctx->stop_wq);
 	}
 	spin_unlock(&spu_prio->runq_lock);
 }
@@ -365,6 +380,12 @@ static struct spu *find_victim(struct spu_context *ctx)
 			}
 			spu_unbind_context(spu, victim);
 			mutex_unlock(&victim->state_mutex);
+			/*
+			 * We need to break out of the wait loop in spu_run
+			 * manually to ensure this context gets put on the
+			 * runqueue again ASAP.
+			 */
+			wake_up(&victim->stop_wq);
 			return spu;
 		}
 	}
@@ -377,7 +398,7 @@ static struct spu *find_victim(struct spu_context *ctx)
  * @ctx:	spu context to schedule
  * @flags:	flags (currently ignored)
  *
- * Tries to find a free spu to run @ctx.  If no free spu is availble
+ * Tries to find a free spu to run @ctx.  If no free spu is available
  * add the context to the runqueue so it gets woken up once an spu
  * is available.
  */
@@ -402,9 +423,7 @@ int spu_activate(struct spu_context *ctx, unsigned long flags)
 			return 0;
 		}
 
-		spu_add_to_rq(ctx);
 		spu_prio_wait(ctx);
-		spu_del_from_rq(ctx);
 	} while (!signal_pending(current));
 
 	return -ERESTARTSYS;
diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h
index 5c4e47d..0a947fd 100644
--- a/arch/powerpc/platforms/cell/spufs/spufs.h
+++ b/arch/powerpc/platforms/cell/spufs/spufs.h
@@ -41,7 +41,7 @@ struct spu_gang;
 
 /* ctx->sched_flags */
 enum {
-	SPU_SCHED_WAKE = 0, /* currently unused */
+	SPU_SCHED_EXITING = 0,
 };
 
 struct spu_context {
@@ -50,16 +50,17 @@ struct spu_context {
 	spinlock_t mmio_lock;		  /* protects mmio access */
 	struct address_space *local_store; /* local store mapping.  */
 	struct address_space *mfc;	   /* 'mfc' area mappings. */
-	struct address_space *cntl; 	   /* 'control' area mappings. */
-	struct address_space *signal1; 	   /* 'signal1' area mappings. */
-	struct address_space *signal2; 	   /* 'signal2' area mappings. */
-	struct address_space *mss; 	   /* 'mss' area mappings. */
-	struct address_space *psmap; 	   /* 'psmap' area mappings. */
+	struct address_space *cntl;	   /* 'control' area mappings. */
+	struct address_space *signal1;	   /* 'signal1' area mappings. */
+	struct address_space *signal2;	   /* 'signal2' area mappings. */
+	struct address_space *mss;	   /* 'mss' area mappings. */
+	struct address_space *psmap;	   /* 'psmap' area mappings. */
+	spinlock_t mapping_lock;
 	u64 object_id;		   /* user space pointer for oprofile */
 
 	enum { SPU_STATE_RUNNABLE, SPU_STATE_SAVED } state;
 	struct mutex state_mutex;
-	struct semaphore run_sema;
+	struct mutex run_mutex;
 
 	struct mm_struct *owner;
 
@@ -140,6 +141,7 @@ struct spu_context_ops {
 			       struct spu_dma_info * info);
 	void (*proxydma_info_read) (struct spu_context * ctx,
 				    struct spu_proxydma_info * info);
+	void (*restart_dma)(struct spu_context *ctx);
 };
 
 extern struct spu_context_ops spu_hw_ops;
@@ -149,6 +151,7 @@ struct spufs_inode_info {
 	struct spu_context *i_ctx;
 	struct spu_gang *i_gang;
 	struct inode vfs_inode;
+	int i_openers;
 };
 #define SPUFS_I(inode) \
 	container_of(inode, struct spufs_inode_info, vfs_inode)
@@ -170,6 +173,9 @@ int put_spu_gang(struct spu_gang *gang);
 void spu_gang_remove_ctx(struct spu_gang *gang, struct spu_context *ctx);
 void spu_gang_add_ctx(struct spu_gang *gang, struct spu_context *ctx);
 
+/* fault handling */
+int spufs_handle_class1(struct spu_context *ctx);
+
 /* context management */
 static inline void spu_acquire(struct spu_context *ctx)
 {
@@ -190,7 +196,6 @@ void spu_unmap_mappings(struct spu_context *ctx);
 void spu_forget(struct spu_context *ctx);
 int spu_acquire_runnable(struct spu_context *ctx, unsigned long flags);
 void spu_acquire_saved(struct spu_context *ctx);
-int spu_acquire_exclusive(struct spu_context *ctx);
 
 int spu_activate(struct spu_context *ctx, unsigned long flags);
 void spu_deactivate(struct spu_context *ctx);
@@ -218,14 +223,13 @@ extern char *isolated_loader;
 		prepare_to_wait(&(wq), &__wait, TASK_INTERRUPTIBLE);	\
 		if (condition)						\
 			break;						\
-		if (!signal_pending(current)) {				\
-			spu_release(ctx);				\
-			schedule();					\
-			spu_acquire(ctx);				\
-			continue;					\
+		if (signal_pending(current)) {				\
+			__ret = -ERESTARTSYS;				\
+			break;						\
 		}							\
-		__ret = -ERESTARTSYS;					\
-		break;							\
+		spu_release(ctx);					\
+		schedule();						\
+		spu_acquire(ctx);					\
 	}								\
 	finish_wait(&(wq), &__wait);					\
 	__ret;								\
diff --git a/arch/powerpc/platforms/cell/spufs/switch.c b/arch/powerpc/platforms/cell/spufs/switch.c
index fd91c73..8347c4a 100644
--- a/arch/powerpc/platforms/cell/spufs/switch.c
+++ b/arch/powerpc/platforms/cell/spufs/switch.c
@@ -2084,6 +2084,10 @@ int spu_save(struct spu_state *prev, struct spu *spu)
 	int rc;
 
 	acquire_spu_lock(spu);	        /* Step 1.     */
+	prev->dar = spu->dar;
+	prev->dsisr = spu->dsisr;
+	spu->dar = 0;
+	spu->dsisr = 0;
 	rc = __do_spu_save(prev, spu);	/* Steps 2-53. */
 	release_spu_lock(spu);
 	if (rc != 0 && rc != 2 && rc != 6) {
@@ -2109,9 +2113,9 @@ int spu_restore(struct spu_state *new, struct spu *spu)
 
 	acquire_spu_lock(spu);
 	harvest(NULL, spu);
-	spu->dar = 0;
-	spu->dsisr = 0;
 	spu->slb_replace = 0;
+	new->dar = 0;
+	new->dsisr = 0;
 	spu->class_0_pending = 0;
 	rc = __do_spu_restore(new, spu);
 	release_spu_lock(spu);
diff --git a/include/asm-powerpc/mmu.h b/include/asm-powerpc/mmu.h
index 200055a..e22fd88 100644
--- a/include/asm-powerpc/mmu.h
+++ b/include/asm-powerpc/mmu.h
@@ -234,6 +234,7 @@ extern int __hash_page_64K(unsigned long ea, unsigned long access,
 			   unsigned long vsid, pte_t *ptep, unsigned long trap,
 			   unsigned int local);
 struct mm_struct;
+extern int hash_page(unsigned long ea, unsigned long access, unsigned long trap);
 extern int hash_huge_page(struct mm_struct *mm, unsigned long access,
 			  unsigned long ea, unsigned long vsid, int local,
 			  unsigned long trap);
diff --git a/include/asm-powerpc/spu_csa.h b/include/asm-powerpc/spu_csa.h
index 8aad061..02e56a6 100644
--- a/include/asm-powerpc/spu_csa.h
+++ b/include/asm-powerpc/spu_csa.h
@@ -242,6 +242,7 @@ struct spu_state {
 	u64 spu_chnldata_RW[32];
 	u32 spu_mailbox_data[4];
 	u32 pu_mailbox_data[1];
+	u64 dar, dsisr;
 	unsigned long suspend_time;
 	spinlock_t register_lock;
 };

linux-2.6-clockevents-fix-resume-logic.patch:

--- NEW FILE linux-2.6-clockevents-fix-resume-logic.patch ---
Subject: clockevents: Fix resume logic

We need to make sure, that the clockevent devices are resumed, before
the tick is resumed. The current resume logic does not guarantee this.

Add CLOCK_EVT_MODE_RESUME and call the set mode functions of the clock
event devices before resuming the tick / oneshot functionality.

Fixup the existing users.

Signed-off-by: Thomas Gleixner <tglx at linutronix.de>

---
 arch/i386/kernel/apic.c      |    3 +
 arch/i386/kernel/hpet.c      |   71 +++----------------------------------------
 arch/i386/kernel/i8253.c     |   43 +++++++++++++++++---------
 include/linux/clockchips.h   |    1 
 kernel/time/tick-broadcast.c |    4 +-
 kernel/time/tick-common.c    |   16 ++++++---
 6 files changed, 51 insertions(+), 87 deletions(-)

Index: linux-2.6.21/arch/i386/kernel/apic.c
===================================================================
--- linux-2.6.21.orig/arch/i386/kernel/apic.c
+++ linux-2.6.21/arch/i386/kernel/apic.c
@@ -242,6 +242,9 @@ static void lapic_timer_setup(enum clock
 		v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR);
 		apic_write_around(APIC_LVTT, v);
 		break;
+	case CLOCK_EVT_MODE_RESUME:
+		/* Nothing to do here */
+		break;
 	}
 
 	local_irq_restore(flags);
Index: linux-2.6.21/arch/i386/kernel/hpet.c
===================================================================
--- linux-2.6.21.orig/arch/i386/kernel/hpet.c
+++ linux-2.6.21/arch/i386/kernel/hpet.c
@@ -187,6 +187,10 @@ static void hpet_set_mode(enum clock_eve
 		cfg &= ~HPET_TN_ENABLE;
 		hpet_writel(cfg, HPET_T0_CFG);
 		break;
+
+	case CLOCK_EVT_MODE_RESUME:
+		hpet_enable_int();
+		break;
 	}
 }
 
@@ -217,6 +221,7 @@ static struct clocksource clocksource_hp
 	.mask		= HPET_MASK,
 	.shift		= HPET_SHIFT,
 	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
+	.resume		= hpet_start_counter,
 };
 
 /*
@@ -291,7 +296,6 @@ int __init hpet_enable(void)
 
 	clocksource_register(&clocksource_hpet);
 
-
 	if (id & HPET_ID_LEGSUP) {
 		hpet_enable_int();
 		hpet_reserve_platform_timers(id);
@@ -524,68 +528,3 @@ irqreturn_t hpet_rtc_interrupt(int irq, 
 	return IRQ_HANDLED;
 }
 #endif
-
-
-/*
- * Suspend/resume part
- */
-
-#ifdef CONFIG_PM
-
-static int hpet_suspend(struct sys_device *sys_device, pm_message_t state)
-{
-	unsigned long cfg = hpet_readl(HPET_CFG);
-
-	cfg &= ~(HPET_CFG_ENABLE|HPET_CFG_LEGACY);
-	hpet_writel(cfg, HPET_CFG);
-
-	return 0;
-}
-
-static int hpet_resume(struct sys_device *sys_device)
-{
-	unsigned int id;
-
-	hpet_start_counter();
-
-	id = hpet_readl(HPET_ID);
-
-	if (id & HPET_ID_LEGSUP)
-		hpet_enable_int();
-
-	return 0;
-}
-
-static struct sysdev_class hpet_class = {
-	set_kset_name("hpet"),
-	.suspend	= hpet_suspend,
-	.resume		= hpet_resume,
-};
-
-static struct sys_device hpet_device = {
-	.id		= 0,
-	.cls		= &hpet_class,
-};
-
-
-static __init int hpet_register_sysfs(void)
-{
-	int err;
-
-	if (!is_hpet_capable())
-		return 0;
-
-	err = sysdev_class_register(&hpet_class);
-
-	if (!err) {
-		err = sysdev_register(&hpet_device);
-		if (err)
-			sysdev_class_unregister(&hpet_class);
-	}
-
-	return err;
-}
-
-device_initcall(hpet_register_sysfs);
-
-#endif
Index: linux-2.6.21/arch/i386/kernel/i8253.c
===================================================================
--- linux-2.6.21.orig/arch/i386/kernel/i8253.c
+++ linux-2.6.21/arch/i386/kernel/i8253.c
@@ -3,11 +3,11 @@
  *
  */
 #include <linux/clockchips.h>
-#include <linux/spinlock.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
 #include <linux/jiffies.h>
-#include <linux/sysdev.h>
 #include <linux/module.h>
-#include <linux/init.h>
+#include <linux/spinlock.h>
 
 #include <asm/smp.h>
 #include <asm/delay.h>
@@ -25,6 +25,24 @@ EXPORT_SYMBOL(i8253_lock);
  */
 struct clock_event_device *global_clock_event;
 
+/* Status of the PIT interrupt */
+static int pit_irq_disabled;
+
+/*
+ * Control pit interrupt enable / disable
+ */
+static void pit_control_irq(int disable)
+{
+	if (pit_irq_disabled == disable)
+		return;
+
+	pit_irq_disabled = disable;
+	if (disable)
+		disable_irq(0);
+	else
+		enable_irq(0);
+}
+
 /*
  * Initialize the PIT timer.
  *
@@ -41,26 +59,23 @@ static void init_pit_timer(enum clock_ev
 	case CLOCK_EVT_MODE_PERIODIC:
 		/* binary, mode 2, LSB/MSB, ch 0 */
 		outb_p(0x34, PIT_MODE);
-		udelay(10);
 		outb_p(LATCH & 0xff , PIT_CH0);	/* LSB */
-		udelay(10);
 		outb(LATCH >> 8 , PIT_CH0);	/* MSB */
+		pit_control_irq(0);
 		break;
 
-	/*
-	 * Avoid unnecessary state transitions, as it confuses
-	 * Geode / Cyrix based boxen.
-	 */
 	case CLOCK_EVT_MODE_SHUTDOWN:
-		if (evt->mode == CLOCK_EVT_MODE_UNUSED)
-			break;
 	case CLOCK_EVT_MODE_UNUSED:
-		if (evt->mode == CLOCK_EVT_MODE_SHUTDOWN)
-			break;
+		pit_control_irq(1);
+		break;
 	case CLOCK_EVT_MODE_ONESHOT:
 		/* One shot setup */
 		outb_p(0x38, PIT_MODE);
-		udelay(10);
+		pit_control_irq(0);
+		break;
+
+	case CLOCK_EVT_MODE_RESUME:
+		/* Nothing to do here */
 		break;
 	}
 	spin_unlock_irqrestore(&i8253_lock, flags);
Index: linux-2.6.21/include/linux/clockchips.h
===================================================================
--- linux-2.6.21.orig/include/linux/clockchips.h
+++ linux-2.6.21/include/linux/clockchips.h
@@ -23,6 +23,7 @@ enum clock_event_mode {
 	CLOCK_EVT_MODE_SHUTDOWN,
 	CLOCK_EVT_MODE_PERIODIC,
 	CLOCK_EVT_MODE_ONESHOT,
+	CLOCK_EVT_MODE_RESUME,
 };
 
 /* Clock event notification values */
Index: linux-2.6.21/kernel/time/tick-broadcast.c
===================================================================
--- linux-2.6.21.orig/kernel/time/tick-broadcast.c
+++ linux-2.6.21/kernel/time/tick-broadcast.c
@@ -292,7 +292,7 @@ void tick_suspend_broadcast(void)
 	spin_lock_irqsave(&tick_broadcast_lock, flags);
 
 	bc = tick_broadcast_device.evtdev;
-	if (bc && tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC)
+	if (bc)
 		clockevents_set_mode(bc, CLOCK_EVT_MODE_SHUTDOWN);
 
 	spin_unlock_irqrestore(&tick_broadcast_lock, flags);
@@ -309,6 +309,8 @@ int tick_resume_broadcast(void)
 	bc = tick_broadcast_device.evtdev;
 
 	if (bc) {
+		clockevents_set_mode(bc, CLOCK_EVT_MODE_RESUME);
+
 		switch (tick_broadcast_device.mode) {
 		case TICKDEV_MODE_PERIODIC:
 			if(!cpus_empty(tick_broadcast_mask))
Index: linux-2.6.21/kernel/time/tick-common.c
===================================================================
--- linux-2.6.21.orig/kernel/time/tick-common.c
+++ linux-2.6.21/kernel/time/tick-common.c
@@ -318,12 +318,17 @@ static void tick_resume(void)
 {
 	struct tick_device *td = &__get_cpu_var(tick_cpu_device);
 	unsigned long flags;
+	int broadcast = tick_resume_broadcast();
 
 	spin_lock_irqsave(&tick_device_lock, flags);
-	if (td->mode == TICKDEV_MODE_PERIODIC)
-		tick_setup_periodic(td->evtdev, 0);
-	else
-		tick_resume_oneshot();
+	clockevents_set_mode(td->evtdev, CLOCK_EVT_MODE_RESUME);
+
+	if (!broadcast) {
+		if (td->mode == TICKDEV_MODE_PERIODIC)
+			tick_setup_periodic(td->evtdev, 0);
+		else
+			tick_resume_oneshot();
+	}
 	spin_unlock_irqrestore(&tick_device_lock, flags);
 }
 
@@ -360,8 +365,7 @@ static int tick_notify(struct notifier_b
 		break;
 
 	case CLOCK_EVT_NOTIFY_RESUME:
-		if (!tick_resume_broadcast())
-			tick_resume();
+		tick_resume();
 		break;
 
 	default:

linux-2.6-crap-sysfs-workaround.patch:

--- NEW FILE linux-2.6-crap-sysfs-workaround.patch ---
--- linux-2.6.20.ppc/drivers/base/class.c~	2007-02-04 18:44:54.000000000 +0000
+++ linux-2.6.20.ppc/drivers/base/class.c	2007-03-28 00:23:30.000000000 +0100
@@ -380,7 +380,7 @@ static int deprecated_class_uevent(char 
 	struct device *dev = class_dev->dev;
 	char *path;
 
-	if (!dev)
+	//if (!dev)
 		return 0;
 
 	/* add device, backing this class device (deprecated) */

linux-2.6-debug-acpi-os-write-port.patch:

--- NEW FILE linux-2.6-debug-acpi-os-write-port.patch ---
---
 drivers/acpi/osl.c |    2 ++
 1 file changed, 2 insertions(+)

--- linux-2.6.22.noarch.orig/drivers/acpi/osl.c
+++ linux-2.6.22.noarch/drivers/acpi/osl.c
@@ -419,6 +419,8 @@ acpi_status acpi_os_write_port(acpi_io_a
 		outl(value, port);
 		break;
 	default:
+		printk(KERN_ERR PREFIX
+		       "writing %d bits to port %d\n", (int)width, (int)port);
 		BUG();
 	}
 

linux-2.6-debug-extra-warnings.patch:

--- NEW FILE linux-2.6-debug-extra-warnings.patch ---
-Werror-implicit-function-declaration
 This makes builds fail sooner if something is implicitly defined instead
 of having to wait half an hour for it to fail at the linking stage.

-Wpointer-arith
 http://bugzilla.kernel.org/show_bug.cgi?id=7561

Signed-off-by: Dave Jones <davej at redhat.com>

--- linux-2.6.21.noarch/Makefile~	2007-06-04 16:46:24.000000000 -0400
+++ linux-2.6.21.noarch/Makefile	2007-06-04 16:46:53.000000000 -0400
@@ -313,7 +313,8 @@ LINUXINCLUDE    := -Iinclude \
 CPPFLAGS        := -D__KERNEL__ $(LINUXINCLUDE)
 
 CFLAGS          := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
-                   -fno-strict-aliasing -fno-common
+		   -fno-strict-aliasing -fno-common \
+		   -Werror-implicit-function-declaration -Wpointer-arith
 AFLAGS          := -D__ASSEMBLY__
 
 # Read KERNELRELEASE from include/config/kernel.release (if it exists)

linux-2.6-debug-nmi-timeout.patch:

--- NEW FILE linux-2.6-debug-nmi-timeout.patch ---
--- linux-2.6.20.noarch/arch/i386/kernel/nmi.c~	2007-04-13 15:52:37.000000000 -0400
+++ linux-2.6.20.noarch/arch/i386/kernel/nmi.c	2007-04-13 15:53:06.000000000 -0400
@@ -1044,7 +1044,7 @@ __kprobes int nmi_watchdog_tick(struct p
 		 * wait a few IRQs (5 seconds) before doing the oops ...
 		 */
 		alert_counter[cpu]++;
-		if (alert_counter[cpu] == 5*nmi_hz)
+		if (alert_counter[cpu] == CONFIG_DEBUG_NMI_TIMEOUT*nmi_hz)
 			/*
 			 * die_nmi will return ONLY if NOTIFY_STOP happens..
 			 */
--- linux-2.6.20.noarch/arch/x86_64/kernel/nmi.c~	2007-04-13 15:53:09.000000000 -0400
+++ linux-2.6.20.noarch/arch/x86_64/kernel/nmi.c	2007-04-13 15:53:29.000000000 -0400
@@ -923,7 +923,7 @@ int __kprobes nmi_watchdog_tick(struct p
 		 * wait a few IRQs (5 seconds) before doing the oops ...
 		 */
 		local_inc(&__get_cpu_var(alert_counter));
-		if (local_read(&__get_cpu_var(alert_counter)) == 5*nmi_hz)
+		if (local_read(&__get_cpu_var(alert_counter)) == CONFIG_DEBUG_NMI_TIMEOUT*nmi_hz)
 			die_nmi("NMI Watchdog detected LOCKUP on CPU %d\n", regs,
 				panic_on_timeout);
 	} else {
--- linux-2.6.20.noarch/lib/Kconfig.debug~	2007-04-13 15:53:48.000000000 -0400
+++ linux-2.6.20.noarch/lib/Kconfig.debug	2007-04-13 15:55:18.000000000 -0400
@@ -133,6 +133,14 @@ config DETECT_SOFTLOCKUP
 	   can be detected via the NMI-watchdog, on platforms that
 	   support it.)
 
+config DEBUG_NMI_TIMEOUT
+	int "Number of seconds before NMI timeout"
+	depends on X86
+	default 5
+	help
+	  This value is the number of seconds the NMI watchdog will tick
+	  before it decides the machine has hung.
+
 config SCHEDSTATS
 	bool "Collect scheduler statistics"
 	depends on DEBUG_KERNEL && PROC_FS

linux-2.6-default-mmf_dump_elf_headers.patch:

--- NEW FILE linux-2.6-default-mmf_dump_elf_headers.patch ---
--- linux-2.6/include/linux/sched.h
+++ linux-2.6/include/linux/sched.h
@@ -365,7 +365,8 @@ extern int get_dumpable(struct mm_struct
 #define MMF_DUMP_FILTER_MASK \
 	(((1 << MMF_DUMP_FILTER_BITS) - 1) << MMF_DUMP_FILTER_SHIFT)
 #define MMF_DUMP_FILTER_DEFAULT \
-	((1 << MMF_DUMP_ANON_PRIVATE) |	(1 << MMF_DUMP_ANON_SHARED))
+	((1 << MMF_DUMP_ANON_PRIVATE) |	(1 << MMF_DUMP_ANON_SHARED) | \
+	 (1 << MMF_DUMP_ELF_HEADERS))
 
 struct mm_struct {
 	struct vm_area_struct * mmap;		/* list of VMAs */


linux-2.6-defaults-pci_no_msi_mmconf.patch:

--- NEW FILE linux-2.6-defaults-pci_no_msi_mmconf.patch ---
Disable PCI MSI and MMCONFIG by default, add kernel parameters
to enable them.

Original mmconfig patch by Kyle McMartin <kyle at ubuntu.com>

Signed-off-by: Chuck Ebbert <cebbert at redhat.com>

---
 Documentation/kernel-parameters.txt |    5 +++++
 arch/i386/pci/common.c              |    6 +++++-
 drivers/pci/msi.c                   |    6 +++++-
 drivers/pci/pci.c                   |    2 ++
 drivers/pci/pci.h                   |    2 ++
 5 files changed, 19 insertions(+), 2 deletions(-)

--- linux-2.6.20.noarch.orig/drivers/pci/msi.c
+++ linux-2.6.20.noarch/drivers/pci/msi.c
@@ -28,7 +28,7 @@ static DEFINE_SPINLOCK(msi_lock);
 static struct msi_desc* msi_desc[NR_IRQS] = { [0 ... NR_IRQS-1] = NULL };
 static struct kmem_cache* msi_cachep;
 
-static int pci_msi_enable = 1;
+static int pci_msi_enable = 0;
 
 static int msi_cache_init(void)
 {
@@ -977,6 +977,10 @@ void pci_no_msi(void)
 {
 	pci_msi_enable = 0;
 }
+void pci_yes_msi(void)
+{
+	pci_msi_enable = 1;
+}
 
 EXPORT_SYMBOL(pci_enable_msi);
 EXPORT_SYMBOL(pci_disable_msi);
--- linux-2.6.20.noarch.orig/Documentation/kernel-parameters.txt
+++ linux-2.6.20.noarch/Documentation/kernel-parameters.txt
@@ -1197,8 +1197,13 @@ and is between 256 and 4096 characters. 
 				Mechanism 1.
 		conf2		[IA-32] Force use of PCI Configuration
 				Mechanism 2.
+		mmconf		[IA-32,X86_64] Enable use of MMCONFIG for PCI
+				Configuration
 		nommconf	[IA-32,X86_64] Disable use of MMCONFIG for PCI
 				Configuration
+		msi		[MSI] If the PCI_MSI kernel config parameter is
+				enabled, this kernel boot option can be used to
+				enable the use of MSI interrupts system-wide.
 		nomsi		[MSI] If the PCI_MSI kernel config parameter is
 				enabled, this kernel boot option can be used to
 				disable the use of MSI interrupts system-wide.
--- linux-2.6.20.noarch.orig/arch/i386/pci/common.c
+++ linux-2.6.20.noarch/arch/i386/pci/common.c
@@ -18,7 +18,7 @@
 #include "pci.h"
 
 unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 |
-				PCI_PROBE_MMCONF;
+				0; /* PCI_PROBE_MMCONF */
 
 static int pci_bf_sort;
 int pci_routeirq;
@@ -292,6 +292,10 @@ char * __devinit  pcibios_setup(char *st
 		pci_probe &= ~PCI_PROBE_MMCONF;
 		return NULL;
 	}
+	else if (!strcmp(str, "mmconf")) {
+		pci_probe |= PCI_PROBE_MMCONF;
+		return NULL;
+	}
 #endif
 	else if (!strcmp(str, "noacpi")) {
 		acpi_noirq_set();
--- linux-2.6.20.noarch/drivers/pci/pci.c~	2007-04-04 01:33:08.000000000 -0400
+++ linux-2.6.20.noarch/drivers/pci/pci.c	2007-04-04 01:33:33.000000000 -0400
@@ -1358,6 +1358,8 @@ static int __devinit pci_setup(char *str
 		if (*str && (str = pcibios_setup(str)) && *str) {
 			if (!strcmp(str, "nomsi")) {
 				pci_no_msi();
+			} else if (!strcmp(str, "msi")) {
+				pci_yes_msi();
 			} else if (!strncmp(str, "cbiosize=", 9)) {
 				pci_cardbus_io_size = memparse(str + 9, &str);
 			} else if (!strncmp(str, "cbmemsize=", 10)) {
--- linux-2.6.20.noarch/drivers/pci/pci.h~	2007-04-04 01:34:07.000000000 -0400
+++ linux-2.6.20.noarch/drivers/pci/pci.h	2007-04-04 01:34:31.000000000 -0400
@@ -47,8 +47,10 @@ extern unsigned int pci_pm_d3_delay;
 
 #ifdef CONFIG_PCI_MSI
 void pci_no_msi(void);
+void pci_yes_msi(void);
 #else
 static inline void pci_no_msi(void) { }
+static inline void pci_yes_msi(void) { }
 #endif
 
 #if defined(CONFIG_PCI_MSI) && defined(CONFIG_PM)

linux-2.6-drivers-ssb-debug-revision.patch:

--- NEW FILE linux-2.6-drivers-ssb-debug-revision.patch ---
---
 drivers/ssb/main.c |    2 ++
 1 file changed, 2 insertions(+)

--- linux-2.6.22.noarch.orig/drivers/ssb/main.c
+++ linux-2.6.22.noarch/drivers/ssb/main.c
@@ -884,6 +884,8 @@ static u32 ssb_tmslow_reject_bitmask(str
 	case SSB_IDLOW_SSBREV_23:
 		return SSB_TMSLOW_REJECT_23;
 	default:
+		printk(KERN_ERR "ssb: rev %x\n", 
+		       ssb_read32(dev, SSB_IDLOW) & SSB_IDLOW_SSBREV);
 		WARN_ON(1);
 	}
 	return (SSB_TMSLOW_REJECT_22 | SSB_TMSLOW_REJECT_23);

linux-2.6-dvb-spinlock.patch:

--- NEW FILE linux-2.6-dvb-spinlock.patch ---

# HG changeset patch
# User Mauro Carvalho Chehab <mchehab at infradead.org>
# Date Thu Apr 05 14:28:11 2007 -0300
# Node ID a80058519added447f1cdd870334282e8ac3226e
# parent: 628ca02d680721a85e9b2fca7cf4b782b31f9443
Fix Kernel Bugzilla #8301: spinlock fix for flexcop-pci

# Now, patch author (just the main one), on a From: field
# Please change below if the committer is not the patch author.
#
>From Hendrik Borghorst <hendrik at borghorst.org>

# Then a detailed description:
If you modprobe the b2c2-flexcop-pci module you got a hardlock of your system.
This is due the usage of spin_lock before spin_lock_init is called.

# At the end Signed-off-by: fields by patch author and committer, at least.
#
Signed-Off-By: Patrick Boettcher <pb at linuxtv.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab at infradead.org>

--- a/drivers/media/dvb/b2c2/flexcop-pci.c	Wed Apr 04 13:11:06 2007 -0700
+++ b/drivers/media/dvb/b2c2/flexcop-pci.c	Thu Apr 05 14:28:11 2007 -0300
@@ -143,10 +143,11 @@ static irqreturn_t flexcop_pci_isr(int i
 {
 	struct flexcop_pci *fc_pci = dev_id;
 	struct flexcop_device *fc = fc_pci->fc_dev;
+	unsigned long flags;
 	flexcop_ibi_value v;
 	irqreturn_t ret = IRQ_HANDLED;
 
-	spin_lock_irq(&fc_pci->irq_lock);
+	spin_lock_irqsave(&fc_pci->irq_lock,flags);
 
 	v = fc->read_ibi_reg(fc,irq_20c);
 
@@ -210,7 +211,7 @@ static irqreturn_t flexcop_pci_isr(int i
 		ret = IRQ_NONE;
 	}
 
-	spin_unlock_irq(&fc_pci->irq_lock);
+	spin_unlock_irqrestore(&fc_pci->irq_lock,flags);
 
 	return ret;
 }
@@ -309,12 +310,12 @@ static int flexcop_pci_init(struct flexc
 	}
 
 	pci_set_drvdata(fc_pci->pdev, fc_pci);
-
+	spin_lock_init(&fc_pci->irq_lock);
 	if ((ret = request_irq(fc_pci->pdev->irq, flexcop_pci_isr,
 					IRQF_SHARED, DRIVER_NAME, fc_pci)) != 0)
 		goto err_pci_iounmap;
 
-	spin_lock_init(&fc_pci->irq_lock);
+
 
 	fc_pci->init_state |= FC_PCI_INIT;
 	return ret;


linux-2.6-e1000-corrupt-eeprom-checksum.patch:

--- NEW FILE linux-2.6-e1000-corrupt-eeprom-checksum.patch ---
http://www.thinkwiki.org/wiki/Problem_with_e1000:_EEPROM_Checksum_Is_Not_Valid

--- linux-2.6.23.noarch/drivers/net/e1000/e1000_main.c~	2007-10-15 14:29:07.000000000 -0400
+++ linux-2.6.23.noarch/drivers/net/e1000/e1000_main.c	2007-10-15 14:31:11.000000000 -0400
@@ -1003,14 +1003,18 @@ e1000_probe(struct pci_dev *pdev,
 		goto err_eeprom;
 	}
 
-	/* before reading the EEPROM, reset the controller to
-	 * put the device in a known good starting state */
-
-	e1000_reset_hw(&adapter->hw);
-
-	/* make sure the EEPROM is good */
-
 	if (e1000_validate_eeprom_checksum(&adapter->hw) < 0) {
+		/* before reading the EEPROM, reset the controller to
+		 * put the device in a known good starting state */
+		e1000_reset_hw(&adapter->hw);
+
+		/* make sure the EEPROM is good */
+
+		if (e1000_validate_eeprom_checksum(&adapter->hw) < 0) {
+			DPRINTK(PROBE, ERR, "The EEPROM Checksum Is Not Valid\n");
+			goto err_eeprom;
+		}
+
 		DPRINTK(PROBE, ERR, "The EEPROM Checksum Is Not Valid\n");
 		goto err_eeprom;
 	}

linux-2.6-execshield-xen.patch:

--- NEW FILE linux-2.6-execshield-xen.patch ---
Index: patching/arch/i386/kernel/process-xen.c
===================================================================
--- patching.orig/arch/i386/kernel/process-xen.c
+++ patching/arch/i386/kernel/process-xen.c
@@ -605,6 +605,9 @@ struct task_struct fastcall * __switch_t
 	else BUG_ON(!(read_cr0() & 8));
 #endif
 
+	if (next_p->mm)
+		load_user_cs_desc(cpu, next_p->mm);
+
 	/* we're going to use this soon, after a few expensive things */
 	if (next_p->fpu_counter > 5)
 		prefetch(&next->i387.fxsave);
@@ -900,3 +903,60 @@ unsigned long arch_align_stack(unsigned 
 		sp -= get_random_int() % 8192;
 	return sp & ~0xf;
 }
+
+void arch_add_exec_range(struct mm_struct *mm, unsigned long limit)
+{
+	if (limit > mm->context.exec_limit) {
+		mm->context.exec_limit = limit;
+		set_user_cs(&mm->context.user_cs, limit);
+		if (mm == current->mm) {
+			preempt_disable();
+			load_user_cs_desc(smp_processor_id(), mm);
+			preempt_enable();
+		}
+	}
+}
+
+void arch_remove_exec_range(struct mm_struct *mm, unsigned long old_end)
+{
+	struct vm_area_struct *vma;
+	unsigned long limit = PAGE_SIZE;
+
+	if (old_end == mm->context.exec_limit) {
+		for (vma = mm->mmap; vma; vma = vma->vm_next)
+			if ((vma->vm_flags & VM_EXEC) && (vma->vm_end > limit))
+				limit = vma->vm_end;
+
+		mm->context.exec_limit = limit;
+		set_user_cs(&mm->context.user_cs, limit);
+		if (mm == current->mm) {
+			preempt_disable();
+			load_user_cs_desc(smp_processor_id(), mm);
+			preempt_enable();
+		}
+	}
+}
+
+void arch_flush_exec_range(struct mm_struct *mm)
+{
+	mm->context.exec_limit = 0;
+	set_user_cs(&mm->context.user_cs, 0);
+}
+
+/*
+ * Generate random brk address between 128MB and 196MB. (if the layout
+ * allows it.)
+ */
+void randomize_brk(unsigned long old_brk)
+{
+	unsigned long new_brk, range_start, range_end;
+
+	range_start = 0x08000000;
+	if (current->mm->brk >= range_start)
+		range_start = current->mm->brk;
+	range_end = range_start + 0x02000000;
+	new_brk = randomize_range(range_start, range_end, 0);
+	if (new_brk)
+		current->mm->brk = new_brk;
+}
+
Index: patching/arch/i386/kernel/smp-xen.c
===================================================================
--- patching.orig/arch/i386/kernel/smp-xen.c
+++ patching/arch/i386/kernel/smp-xen.c
@@ -23,6 +23,7 @@
 
 #include <asm/mtrr.h>
 #include <asm/tlbflush.h>
+#include <asm/desc.h>
 #ifndef CONFIG_XEN
 #include <mach_apic.h>
 #endif
@@ -285,6 +286,8 @@ fastcall void smp_invalidate_interrupt(s
 	unsigned long cpu;
 
 	cpu = get_cpu();
+	if (current->active_mm)
+		load_user_cs_desc(cpu, current->active_mm);
 
 	if (!cpu_isset(cpu, flush_cpumask))
 		goto out;
Index: patching/arch/i386/kernel/traps-xen.c
===================================================================
--- patching.orig/arch/i386/kernel/traps-xen.c
+++ patching/arch/i386/kernel/traps-xen.c
@@ -578,11 +578,89 @@ DO_ERROR(10, SIGSEGV, "invalid TSS", inv
 DO_ERROR(11, SIGBUS,  "segment not present", segment_not_present)
 DO_ERROR(12, SIGBUS,  "stack segment", stack_segment)
 DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0)
-DO_ERROR_INFO(32, SIGSEGV, "iret exception", iret_error, ILL_BADSTK, 0)
+
+
+/*
+ * lazy-check for CS validity on exec-shield binaries:
+ *
+ * the original non-exec stack patch was written by
+ * Solar Designer <solar at openwall.com>. Thanks!
+ */
+static int
+check_lazy_exec_limit(int cpu, struct pt_regs *regs, long error_code)
+{
+	struct desc_struct *desc1, *desc2;
+	struct vm_area_struct *vma;
+	unsigned long limit;
+
+	if (current->mm == NULL)
+		return 0;
+
+	limit = -1UL;
+	if (current->mm->context.exec_limit != -1UL) {
+		limit = PAGE_SIZE;
+		spin_lock(&current->mm->page_table_lock);
+		for (vma = current->mm->mmap; vma; vma = vma->vm_next)
+			if ((vma->vm_flags & VM_EXEC) && (vma->vm_end > limit))
+				limit = vma->vm_end;
+		spin_unlock(&current->mm->page_table_lock);
+		if (limit >= TASK_SIZE)
+			limit = -1UL;
+		current->mm->context.exec_limit = limit;
+	}
+	set_user_cs(&current->mm->context.user_cs, limit);
+
+	desc1 = &current->mm->context.user_cs;
+	desc2 = get_cpu_gdt_table(cpu) + GDT_ENTRY_DEFAULT_USER_CS;
+
+	if (desc1->a != desc2->a || desc1->b != desc2->b) {
+		/*
+		 * The CS was not in sync - reload it and retry the
+		 * instruction. If the instruction still faults then
+		 * we won't hit this branch next time around.
+		 */
+		if (print_fatal_signals >= 2) {
+			printk("#GPF fixup (%ld[seg:%lx]) at %08lx, CPU#%d.\n", error_code, error_code/8, regs->eip, smp_processor_id());
+			printk(" exec_limit: %08lx, user_cs: %08lx/%08lx, CPU_cs: %08lx/%08lx.\n", current->mm->context.exec_limit, desc1->a, desc1->b, desc2->a, desc2->b);
+		}
+		load_user_cs_desc(cpu, current->mm);
+		return 1;
+	}
+
+	return 0;
+}
+
+/*
+ * The fixup code for errors in iret jumps to here (iret_exc).  It loses
+ * the original trap number and error code.  The bogus trap 32 and error
+ * code 0 are what the vanilla kernel delivers via:
+ * DO_ERROR_INFO(32, SIGSEGV, "iret exception", iret_error, ILL_BADSTK, 0)
+ *
+ * In case of a general protection fault in the iret instruction, we
+ * need to check for a lazy CS update for exec-shield.
+ */
+fastcall void do_iret_error(struct pt_regs *regs, long error_code)
+{
+	int ok = check_lazy_exec_limit(get_cpu(), regs, error_code);
+	put_cpu();
+	if (!ok && notify_die(DIE_TRAP, "iret exception", regs,
+			      error_code, 32, SIGSEGV) != NOTIFY_STOP) {
+		siginfo_t info;
+		info.si_signo = SIGSEGV;
+		info.si_errno = 0;
+		info.si_code = ILL_BADSTK;
+		info.si_addr = 0;
+		do_trap(32, SIGSEGV, "iret exception", 0, regs, error_code,
+			&info);
+	}
+}
 
 fastcall void __kprobes do_general_protection(struct pt_regs * regs,
 					      long error_code)
 {
+	int cpu = get_cpu();
+	int ok;
+
 	current->thread.error_code = error_code;
 	current->thread.trap_no = 13;
 
@@ -592,17 +670,31 @@ fastcall void __kprobes do_general_prote
 	if (!user_mode(regs))
 		goto gp_in_kernel;
 
+	ok = check_lazy_exec_limit(cpu, regs, error_code);
+
+	put_cpu();
+
+	if (ok)
+		return;
+
+	if (print_fatal_signals) {
+		printk("#GPF(%ld[seg:%lx]) at %08lx, CPU#%d.\n", error_code, error_code/8, regs->eip, smp_processor_id());
+		printk(" exec_limit: %08lx, user_cs: %08lx/%08lx.\n", current->mm->context.exec_limit, current->mm->context.user_cs.a, current->mm->context.user_cs.b);
+	}
+
 	current->thread.error_code = error_code;
 	current->thread.trap_no = 13;
 	force_sig(SIGSEGV, current);
 	return;
 
 gp_in_vm86:
+	put_cpu();
 	local_irq_enable();
 	handle_vm86_fault((struct kernel_vm86_regs *) regs, error_code);
 	return;
 
 gp_in_kernel:
+	put_cpu();
 	if (!fixup_exception(regs)) {
 		if (notify_die(DIE_GPF, "general protection fault", regs,
 				error_code, 13, SIGSEGV) == NOTIFY_STOP)
Index: patching/arch/i386/mm/init-xen.c
===================================================================
--- patching.orig/arch/i386/mm/init-xen.c
+++ patching/arch/i386/mm/init-xen.c
@@ -486,7 +486,7 @@ EXPORT_SYMBOL(__supported_pte_mask);
  * Control non executable mappings.
  *
  * on      Enable
- * off     Disable
+ * off     Disable (disables exec-shield too)
  */
 static int __init noexec_setup(char *str)
 {
@@ -498,6 +498,7 @@ static int __init noexec_setup(char *str
 	} else if (!strcmp(str,"off")) {
 		disable_nx = 1;
 		__supported_pte_mask &= ~_PAGE_NX;
+		exec_shield = 0;
 	} else
 		return -EINVAL;
 
@@ -569,7 +570,10 @@ void __init paging_init(void)
 	set_nx();
 	if (nx_enabled)
 		printk("NX (Execute Disable) protection: active\n");
+	else
 #endif
+	if (exec_shield)
+		printk("Using x86 segment limits to approximate NX protection\n");
 
 	pagetable_init();
 
Index: patching/arch/x86_64/kernel/process-xen.c
===================================================================
--- patching.orig/arch/x86_64/kernel/process-xen.c
+++ patching/arch/x86_64/kernel/process-xen.c
@@ -701,12 +701,6 @@ void set_personality_64bit(void)
 
 	/* Make sure to be in 64bit mode */
 	clear_thread_flag(TIF_IA32); 
-
-	/* TBD: overwrites user setup. Should have two bits.
-	   But 64bit processes have always behaved this way,
-	   so it's not too bad. The main problem is just that
-   	   32bit childs are affected again. */
-	current->personality &= ~READ_IMPLIES_EXEC;
 }
 
 asmlinkage long sys_fork(struct pt_regs *regs)
Index: patching/arch/x86_64/kernel/setup64-xen.c
===================================================================
--- patching.orig/arch/x86_64/kernel/setup64-xen.c
+++ patching/arch/x86_64/kernel/setup64-xen.c
@@ -49,46 +49,6 @@ unsigned long __supported_pte_mask __rea
 EXPORT_SYMBOL(__supported_pte_mask);
 static int do_not_nx __cpuinitdata = 0;
 
-/* noexec=on|off
-Control non executable mappings for 64bit processes.
-
-on	Enable(default)
-off	Disable
-*/ 
-static int __init nonx_setup(char *str)
-{
-	if (!str)
-		return -EINVAL;
-	if (!strncmp(str, "on", 2)) {
-                __supported_pte_mask |= _PAGE_NX; 
- 		do_not_nx = 0; 
-	} else if (!strncmp(str, "off", 3)) {
-		do_not_nx = 1;
-		__supported_pte_mask &= ~_PAGE_NX;
-        }
-	return 0;
-} 
-early_param("noexec", nonx_setup);
-
-int force_personality32 = 0; 
-
-/* noexec32=on|off
-Control non executable heap for 32bit processes.
-To control the stack too use noexec=off
-
-on	PROT_READ does not imply PROT_EXEC for 32bit processes
-off	PROT_READ implies PROT_EXEC (default)
-*/
-static int __init nonx32_setup(char *str)
-{
-	if (!strcmp(str, "on"))
-		force_personality32 &= ~READ_IMPLIES_EXEC;
-	else if (!strcmp(str, "off"))
-		force_personality32 |= READ_IMPLIES_EXEC;
-	return 1;
-}
-__setup("noexec32=", nonx32_setup);
-
 /*
  * Great future plan:
  * Declare PDA itself and support (irqstack,tss,pgd) as per cpu data.
Index: patching/include/asm-i386/mach-xen/asm/processor.h
===================================================================
--- patching.orig/include/asm-i386/mach-xen/asm/processor.h
+++ patching/include/asm-i386/mach-xen/asm/processor.h
@@ -280,7 +280,10 @@ extern int bootloader_type;
 /* This decides where the kernel will search for a free chunk of vm
  * space during mmap's.
  */
-#define TASK_UNMAPPED_BASE	(PAGE_ALIGN(TASK_SIZE / 3))
+#define TASK_UNMAPPED_BASE	PAGE_ALIGN(TASK_SIZE/3)
+
+#define __HAVE_ARCH_ALIGN_STACK
+extern unsigned long arch_align_stack(unsigned long sp);
 
 #define HAVE_ARCH_PICK_MMAP_LAYOUT
 
@@ -460,6 +463,9 @@ struct thread_struct {
 	regs->xcs = __USER_CS;					\
 	regs->eip = new_eip;					\
 	regs->esp = new_esp;					\
+	preempt_disable();					\
+	load_user_cs_desc(smp_processor_id(), current->mm);	\
+	preempt_enable();					\
 } while (0)
 
 /* Forward declaration, a strange C thing */
Index: patching/include/asm-x86_64/mach-xen/asm/pgalloc.h
===================================================================
--- patching.orig/include/asm-x86_64/mach-xen/asm/pgalloc.h
+++ patching/include/asm-x86_64/mach-xen/asm/pgalloc.h
@@ -15,6 +15,13 @@ void make_pages_writable(void *va, unsig
 
 #define __user_pgd(pgd) ((pgd) + PTRS_PER_PGD)
 
+#define arch_add_exec_range(mm, limit) \
+		do { (void)(mm), (void)(limit); } while (0)
+#define arch_flush_exec_range(mm) \
+		do { (void)(mm); } while (0)
+#define arch_remove_exec_range(mm, limit) \
+		do { (void)(mm), (void)(limit); } while (0)
+
 static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte)
 {
 	set_pmd(pmd, __pmd(_PAGE_TABLE | __pa(pte)));
Index: patching/include/asm-i386/desc.h
===================================================================
--- patching.orig/include/asm-i386/desc.h
+++ patching/include/asm-i386/desc.h
@@ -206,9 +206,18 @@ static inline void set_user_cs(struct de
 	desc->b = (limit & 0xf0000) | 0x00c0fb00;
 }
 
+#ifdef CONFIG_XEN
+
+#define load_user_cs_desc(cpu, mm) \
+        HYPERVISOR_update_descriptor(virt_to_machine(&get_cpu_gdt_table(cpu)[GDT_ENTRY_DEFAULT_USER_CS]), (u64)(mm)->context.user_cs.a | ((u64)(mm)->context.user_cs.b) << 32);
+
+#else /* CONFIG_XEN */
+
 #define load_user_cs_desc(cpu, mm) \
 	get_cpu_gdt_table(cpu)[GDT_ENTRY_DEFAULT_USER_CS] = (mm)->context.user_cs
 
+#endif /* CONFIG_XEN */
+
 extern void arch_add_exec_range(struct mm_struct *mm, unsigned long limit);
 extern void arch_remove_exec_range(struct mm_struct *mm, unsigned long limit);
 extern void arch_flush_exec_range(struct mm_struct *mm);

linux-2.6-firewire-be32-fix.patch:

--- NEW FILE linux-2.6-firewire-be32-fix.patch ---
diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c
index c17342d..2e4cfa5 100644
--- a/drivers/firewire/fw-ohci.c
+++ b/drivers/firewire/fw-ohci.c
@@ -268,7 +268,7 @@ static int ar_context_add_page(struct ar_context *ctx)
 
 	dma_sync_single_for_device(dev, ab_bus, PAGE_SIZE, DMA_BIDIRECTIONAL);
 
-	ctx->last_buffer->descriptor.branch_address = ab_bus | 1;
+	ctx->last_buffer->descriptor.branch_address = cpu_to_le32(ab_bus | 1);
 	ctx->last_buffer->next = ab;
 	ctx->last_buffer = ab;
 
@@ -417,7 +417,8 @@ ar_context_init(struct ar_context *ctx, struct fw_ohci *ohci, u32 regs)
 	ctx->current_buffer = ab.next;
 	ctx->pointer = ctx->current_buffer->data;
 
-	reg_write(ctx->ohci, command_ptr(ctx->regs), ab.descriptor.branch_address);
+	reg_write(ctx->ohci, command_ptr(ctx->regs),
+		  le32_to_cpu(ab.descriptor.branch_address));
 	reg_write(ctx->ohci, control_set(ctx->regs), CONTEXT_RUN);
 	flush_writes(ctx->ohci);
 

linux-2.6-firewire-lockdep.patch:

--- NEW FILE linux-2.6-firewire-lockdep.patch ---
Date: Mon, 8 Oct 2007 17:00:29 -0400
From: Jay Fenlason <fenlason at redhat.com>
To: linux1394-devel at lists.sourceforge.net
Message-ID: <20071008210029.GA19900 at redhat.com>
References: <b3998a500710080618t46eddf7ah7e64b3d297ff8218 at mail.gmail.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
In-Reply-To: <b3998a500710080618t46eddf7ah7e64b3d297ff8218 at mail.gmail.com>
User-Agent: Mutt/1.4.2.2i
X-loop: fedora-test-list at redhat.com
Cc: fedora-test-list at redhat.com
Subject: PATCH Re: Firewire locking problem
X-BeenThere: fedora-test-list at redhat.com
X-Mailman-Version: 2.1.5
Precedence: junk
Reply-To: For testers of Fedora Core development releases <fedora-test-list at redhat.com>
List-Id: For testers of Fedora Core development releases
	<fedora-test-list.redhat.com>
List-Unsubscribe: <https://www.redhat.com/mailman/listinfo/fedora-test-list>, 
	<mailto:fedora-test-list-request at redhat.com?subject=unsubscribe>
List-Archive: <https://www.redhat.com/archives/fedora-test-list>
List-Post: <mailto:fedora-test-list at redhat.com>
List-Help: <mailto:fedora-test-list-request at redhat.com?subject=help>
List-Subscribe: <https://www.redhat.com/mailman/listinfo/fedora-test-list>,
	<mailto:fedora-test-list-request at redhat.com?subject=subscribe>
Sender: fedora-test-list-bounces at redhat.com
Errors-To: fedora-test-list-bounces at redhat.com
Status: RO
Content-Length: 2963
Lines: 80

On Mon, Oct 08, 2007 at 09:18:18AM -0400, Pat Kane wrote:
> While trying to use dvgrab to input DV from an ADVC-100 Firewire
> device on my DELL Inspiron 8600 laptop, I got the following
> console message:
> 
>   =============================================
>   [ INFO: possible recursive locking detected ]
>   2.6.23-0.222.rc9.git4.fc8 #1
>   ---------------------------------------------
>   X/2522 is trying to acquire lock:
>    (&q->lock){++..}, at: [<c042671c>] __wake_up+0x15/0x42
> 
>   but task is already holding lock:
>    (&q->lock){++..}, at: [<c042671c>] __wake_up+0x15/0x42
> 
>   other info that might help us debug this:
>   2 locks held by X/2522:
>    #0:  (&client->lock){.+..}, at: [<e0993f51>] queue_event+0x2b/0x68
> [firewire_core]
>    #1:  (&q->lock){++..}, at: [<c042671c>] __wake_up+0x15/0x42
> 
>   stack backtrace:
>    [<c0406463>] show_trace_log_lvl+0x1a/0x2f
>    [<c0406e4d>] show_trace+0x12/0x14
>    [<c0406e65>] dump_stack+0x16/0x18
>    [<c0449c56>] __lock_acquire+0x189/0xc67
>    [<c044abae>] lock_acquire+0x7b/0x9e
>    [<c0634712>] _spin_lock_irqsave+0x4a/0x77
>    [<c042671c>] __wake_up+0x15/0x42
>    [<c04aed7e>] ep_poll_safewake+0x86/0xa8
>    [<c04afa05>] ep_poll_callback+0x9f/0xaa
>    [<c042483e>] __wake_up_common+0x32/0x55
>    [<c0426738>] __wake_up+0x31/0x42
>    [<e0993f7d>] queue_event+0x57/0x68 [firewire_core]
>    [<e0994a5a>] handle_request+0xd8/0xe0 [firewire_core]
>    [<e099269a>] fw_core_handle_request+0x215/0x23c [firewire_core]
>    [<e0961c42>] handle_ar_packet+0xd7/0xeb [firewire_ohci]
>    [<e0962bac>] ar_context_tasklet+0xb6/0xc4 [firewire_ohci]
>    [<c0432b5b>] tasklet_action+0x68/0xd3
>    [<c0432a39>] __do_softirq+0x78/0xff
>    [<c04075d4>] do_softirq+0x74/0xf7
>    =======================
(snip)

I think this is caused by queue_event() calling
wake_up_interruptible(&client->wait) with client->lock still held.  I
don't see a compelling reason to do the wake_up... inside the lock, so
I propose the following patch.  I tested it out against
2.6.23-0.222.rc9.git4.fc8, which is the latest fedora rawhide kernel.
I never reproduced the original problem, but at least this doesn't
seem to introduce any regressions.

			-- JF


Signed-off-by: Jay Fenlason <fenlason at redhat.com>

-----------------------------------------------------------------------------
--- 1/drivers/firewire/fw-cdev.c	2007-07-08 19:32:17.000000000 -0400
+++ 2/drivers/firewire/fw-cdev.c	2007-10-08 11:21:53.000000000 -0400
@@ -140,11 +140,10 @@ static void queue_event(struct client *c
 	event->v[1].size = size1;
 
 	spin_lock_irqsave(&client->lock, flags);
-
 	list_add_tail(&event->link, &client->event_list);
-	wake_up_interruptible(&client->wait);
-
 	spin_unlock_irqrestore(&client->lock, flags);
+
+	wake_up_interruptible(&client->wait);
 }
 
 static int

-- 
fedora-test-list mailing list
fedora-test-list at redhat.com
To unsubscribe: 
https://www.redhat.com/mailman/listinfo/fedora-test-list


linux-2.6-firewire-multi-lun.patch:

--- NEW FILE linux-2.6-firewire-multi-lun.patch ---
From: Stefan Richter <stefanr at s5r6.in-berlin.de>
Subject: [PATCH update] firewire: fw-sbp2: add support for multiple logical
	units per target
To: linux1394-devel at lists.sourceforge.net
cc: =?iso-8859-1?Q?Kristian_H=F8gsberg?= <krh at redhat.com>
Message-ID: <tkrat.1d824f10636d44c0 at s5r6.in-berlin.de>
MIME-Version: 1.0
Content-Type: TEXT/PLAIN; CHARSET=us-ascii
Content-Disposition: INLINE
Content-Transfer-Encoding: 8bit

Fixes "New firewire stack only recognizing half of a chain of drives",
https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=242254

Signed-off-by: Stefan Richter <stefanr at s5r6.in-berlin.de>
---

Update:
  - refresh after patch "Add ref-counting for sbp2 orbs"
  - further simplify exit paths in sbp2_scsi_queuecommand
  - use the eight_bytes_lun variable more readably

 drivers/firewire/fw-device.h |    5 
 drivers/firewire/fw-sbp2.c   |  583 +++++++++++++++++++----------------
 2 files changed, 328 insertions(+), 260 deletions(-)

Index: linux/drivers/firewire/fw-device.h
===================================================================
--- linux.orig/drivers/firewire/fw-device.h
+++ linux/drivers/firewire/fw-device.h
@@ -102,11 +102,6 @@ fw_unit(struct device *dev)
 #define CSR_INSTANCE		0x18
 #define CSR_DIRECTORY_ID	0x20
 
-#define SBP2_COMMAND_SET_SPECIFIER	0x38
-#define SBP2_COMMAND_SET		0x39
-#define SBP2_COMMAND_SET_REVISION	0x3b
-#define SBP2_FIRMWARE_REVISION		0x3c
-
 struct fw_csr_iterator {
 	u32 *p;
 	u32 *end;
Index: linux/drivers/firewire/fw-sbp2.c
===================================================================
--- linux.orig/drivers/firewire/fw-sbp2.c
+++ linux/drivers/firewire/fw-sbp2.c
@@ -41,7 +41,6 @@
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
-#include <scsi/scsi_dbg.h>
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_host.h>
 
@@ -66,31 +65,49 @@ typedef void (*scsi_done_fn_t)(struct sc
 
 static const char sbp2_driver_name[] = "sbp2";
 
-struct sbp2_device {
-	struct kref kref;
-	struct fw_unit *unit;
+/*
+ * We create one struct sbp2_logical_unit per SBP-2 Logical Unit Number Entry
+ * and one struct scsi_device per sbp2_logical_unit.
+ */
+struct sbp2_logical_unit {
+	struct sbp2_target *tgt;
+	struct list_head link;
+	struct scsi_device *sdev;
 	struct fw_address_handler address_handler;
 	struct list_head orb_list;
-	u64 management_agent_address;
+
 	u64 command_block_agent_address;
-	u32 workarounds;
+	u16 lun;
 	int login_id;
 
 	/*
-	 * We cache these addresses and only update them once we've
-	 * logged in or reconnected to the sbp2 device.  That way, any
-	 * IO to the device will automatically fail and get retried if
-	 * it happens in a window where the device is not ready to
-	 * handle it (e.g. after a bus reset but before we reconnect).
+	 * The generation is updated once we've logged in or reconnected
+	 * to the logical unit.  Thus, I/O to the device will automatically
+	 * fail and get retried if it happens in a window where the device
+	 * is not ready, e.g. after a bus reset but before we reconnect.
 	 */
-	int node_id;
-	int address_high;
 	int generation;
-
 	int retries;
 	struct delayed_work work;
 };
 
+/*
+ * We create one struct sbp2_target per IEEE 1212 Unit Directory
+ * and one struct Scsi_Host per sbp2_target.
+ */
+struct sbp2_target {
+	struct kref kref;
+	struct fw_unit *unit;
+
+	u64 management_agent_address;
+	int directory_id;
+	int node_id;
+	int address_high;
+
+	unsigned workarounds;
+	struct list_head lu_list;
+};
+
 #define SBP2_MAX_SG_ELEMENT_LENGTH	0xf000
 #define SBP2_MAX_SECTORS		255	/* Max sectors supported */
 #define SBP2_ORB_TIMEOUT		2000	/* Timeout in ms */
@@ -101,10 +118,9 @@ struct sbp2_device {
 #define SBP2_DIRECTION_FROM_MEDIA	0x1
 
 /* Unit directory keys */
-#define SBP2_COMMAND_SET_SPECIFIER	0x38
-#define SBP2_COMMAND_SET		0x39
-#define SBP2_COMMAND_SET_REVISION	0x3b
-#define SBP2_FIRMWARE_REVISION		0x3c
+#define SBP2_CSR_FIRMWARE_REVISION	0x3c
+#define SBP2_CSR_LOGICAL_UNIT_NUMBER	0x14
+#define SBP2_CSR_LOGICAL_UNIT_DIRECTORY	0xd4
 
 /* Flags for detected oddities and brokeness */
 #define SBP2_WORKAROUND_128K_MAX_TRANS	0x1
@@ -219,7 +235,7 @@ struct sbp2_command_orb {
 	} request;
 	struct scsi_cmnd *cmd;
 	scsi_done_fn_t done;
-	struct fw_unit *unit;
+	struct sbp2_logical_unit *lu;
 
 	struct sbp2_pointer page_table[SG_ALL] __attribute__((aligned(8)));
 	dma_addr_t page_table_bus;
@@ -295,7 +311,7 @@ sbp2_status_write(struct fw_card *card, 
 		  unsigned long long offset,
 		  void *payload, size_t length, void *callback_data)
 {
-	struct sbp2_device *sd = callback_data;
+	struct sbp2_logical_unit *lu = callback_data;
 	struct sbp2_orb *orb;
 	struct sbp2_status status;
 	size_t header_size;
@@ -319,7 +335,7 @@ sbp2_status_write(struct fw_card *card, 
 
 	/* Lookup the orb corresponding to this status write. */
 	spin_lock_irqsave(&card->lock, flags);
-	list_for_each_entry(orb, &sd->orb_list, link) {
+	list_for_each_entry(orb, &lu->orb_list, link) {
 		if (STATUS_GET_ORB_HIGH(status) == 0 &&
 		    STATUS_GET_ORB_LOW(status) == orb->request_bus) {
 			orb->rcode = RCODE_COMPLETE;
@@ -329,7 +345,7 @@ sbp2_status_write(struct fw_card *card, 
 	}
 	spin_unlock_irqrestore(&card->lock, flags);
 
-	if (&orb->link != &sd->orb_list)
+	if (&orb->link != &lu->orb_list)
 		orb->callback(orb, &status);
 	else
 		fw_error("status write for unknown orb\n");
@@ -371,11 +387,10 @@ complete_transaction(struct fw_card *car
 }
 
 static void
-sbp2_send_orb(struct sbp2_orb *orb, struct fw_unit *unit,
+sbp2_send_orb(struct sbp2_orb *orb, struct sbp2_logical_unit *lu,
 	      int node_id, int generation, u64 offset)
 {
-	struct fw_device *device = fw_device(unit->device.parent);
-	struct sbp2_device *sd = unit->device.driver_data;
+	struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
 	unsigned long flags;
 
 	orb->pointer.high = 0;
@@ -383,7 +398,7 @@ sbp2_send_orb(struct sbp2_orb *orb, stru
 	fw_memcpy_to_be32(&orb->pointer, &orb->pointer, sizeof(orb->pointer));
 
 	spin_lock_irqsave(&device->card->lock, flags);
-	list_add_tail(&orb->link, &sd->orb_list);
+	list_add_tail(&orb->link, &lu->orb_list);
 	spin_unlock_irqrestore(&device->card->lock, flags);
 
 	/* Take a ref for the orb list and for the transaction callback. */
@@ -396,10 +411,9 @@ sbp2_send_orb(struct sbp2_orb *orb, stru
 			complete_transaction, orb);
 }
 
-static int sbp2_cancel_orbs(struct fw_unit *unit)
+static int sbp2_cancel_orbs(struct sbp2_logical_unit *lu)
 {
-	struct fw_device *device = fw_device(unit->device.parent);
-	struct sbp2_device *sd = unit->device.driver_data;
+	struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
 	struct sbp2_orb *orb, *next;
 	struct list_head list;
 	unsigned long flags;
@@ -407,7 +421,7 @@ static int sbp2_cancel_orbs(struct fw_un
 
 	INIT_LIST_HEAD(&list);
 	spin_lock_irqsave(&device->card->lock, flags);
-	list_splice_init(&sd->orb_list, &list);
+	list_splice_init(&lu->orb_list, &list);
 	spin_unlock_irqrestore(&device->card->lock, flags);
 
 	list_for_each_entry_safe(orb, next, &list, link) {
@@ -434,11 +448,11 @@ complete_management_orb(struct sbp2_orb 
 }
 
 static int
-sbp2_send_management_orb(struct fw_unit *unit, int node_id, int generation,
-			 int function, int lun, void *response)
+sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id,
+			 int generation, int function, int lun_or_login_id,
+			 void *response)
 {
-	struct fw_device *device = fw_device(unit->device.parent);
-	struct sbp2_device *sd = unit->device.driver_data;
+	struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
 	struct sbp2_management_orb *orb;
 	int retval = -ENOMEM;
 
@@ -459,12 +473,12 @@ sbp2_send_management_orb(struct fw_unit 
 	orb->request.misc =
 		MANAGEMENT_ORB_NOTIFY |
 		MANAGEMENT_ORB_FUNCTION(function) |
-		MANAGEMENT_ORB_LUN(lun);
+		MANAGEMENT_ORB_LUN(lun_or_login_id);
 	orb->request.length =
 		MANAGEMENT_ORB_RESPONSE_LENGTH(sizeof(orb->response));
 
-	orb->request.status_fifo.high = sd->address_handler.offset >> 32;
-	orb->request.status_fifo.low  = sd->address_handler.offset;
+	orb->request.status_fifo.high = lu->address_handler.offset >> 32;
+	orb->request.status_fifo.low  = lu->address_handler.offset;
 
 	if (function == SBP2_LOGIN_REQUEST) {
 		orb->request.misc |=
@@ -483,14 +497,14 @@ sbp2_send_management_orb(struct fw_unit 
 	if (dma_mapping_error(orb->base.request_bus))
 		goto fail_mapping_request;
 
-	sbp2_send_orb(&orb->base, unit,
-		      node_id, generation, sd->management_agent_address);
+	sbp2_send_orb(&orb->base, lu, node_id, generation,
+		      lu->tgt->management_agent_address);
 
 	wait_for_completion_timeout(&orb->done,
 				    msecs_to_jiffies(SBP2_ORB_TIMEOUT));
 
 	retval = -EIO;
-	if (sbp2_cancel_orbs(unit) == 0) {
+	if (sbp2_cancel_orbs(lu) == 0) {
 		fw_error("orb reply timed out, rcode=0x%02x\n",
 			 orb->base.rcode);
 		goto out;
@@ -535,10 +549,9 @@ complete_agent_reset_write(struct fw_car
 	kfree(t);
 }
 
-static int sbp2_agent_reset(struct fw_unit *unit)
+static int sbp2_agent_reset(struct sbp2_logical_unit *lu)
 {
-	struct fw_device *device = fw_device(unit->device.parent);
-	struct sbp2_device *sd = unit->device.driver_data;
+	struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
 	struct fw_transaction *t;
 	static u32 zero;
 
@@ -547,181 +560,261 @@ static int sbp2_agent_reset(struct fw_un
 		return -ENOMEM;
 
 	fw_send_request(device->card, t, TCODE_WRITE_QUADLET_REQUEST,
-			sd->node_id, sd->generation, device->max_speed,
-			sd->command_block_agent_address + SBP2_AGENT_RESET,
+			lu->tgt->node_id, lu->generation, device->max_speed,
+			lu->command_block_agent_address + SBP2_AGENT_RESET,
 			&zero, sizeof(zero), complete_agent_reset_write, t);
 
 	return 0;
 }
 
-static void sbp2_reconnect(struct work_struct *work);
-static struct scsi_host_template scsi_driver_template;
-
-static void release_sbp2_device(struct kref *kref)
+static void sbp2_release_target(struct kref *kref)
 {
-	struct sbp2_device *sd = container_of(kref, struct sbp2_device, kref);
-	struct Scsi_Host *host =
-		container_of((void *)sd, struct Scsi_Host, hostdata[0]);
-
-	scsi_remove_host(host);
-	sbp2_send_management_orb(sd->unit, sd->node_id, sd->generation,
-				 SBP2_LOGOUT_REQUEST, sd->login_id, NULL);
-	fw_core_remove_address_handler(&sd->address_handler);
-	fw_notify("removed sbp2 unit %s\n", sd->unit->device.bus_id);
-	put_device(&sd->unit->device);
-	scsi_host_put(host);
+	struct sbp2_target *tgt = container_of(kref, struct sbp2_target, kref);
+	struct sbp2_logical_unit *lu, *next;
+	struct Scsi_Host *shost =
+		container_of((void *)tgt, struct Scsi_Host, hostdata[0]);
+
+	list_for_each_entry_safe(lu, next, &tgt->lu_list, link) {
+		if (lu->sdev)
+			scsi_remove_device(lu->sdev);
+
+		sbp2_send_management_orb(lu, tgt->node_id, lu->generation,
+				SBP2_LOGOUT_REQUEST, lu->login_id, NULL);
+		fw_core_remove_address_handler(&lu->address_handler);
+		list_del(&lu->link);
+		kfree(lu);
+	}
+	scsi_remove_host(shost);
+	fw_notify("released %s\n", tgt->unit->device.bus_id);
+
+	put_device(&tgt->unit->device);
+	scsi_host_put(shost);
 }
 
+static void sbp2_reconnect(struct work_struct *work);
+
 static void sbp2_login(struct work_struct *work)
 {
-	struct sbp2_device *sd =
-		container_of(work, struct sbp2_device, work.work);
-	struct Scsi_Host *host =
-		container_of((void *)sd, struct Scsi_Host, hostdata[0]);
-	struct fw_unit *unit = sd->unit;
+	struct sbp2_logical_unit *lu =
+		container_of(work, struct sbp2_logical_unit, work.work);
+	struct Scsi_Host *shost =
+		container_of((void *)lu->tgt, struct Scsi_Host, hostdata[0]);
+	struct scsi_device *sdev;
+	struct scsi_lun eight_bytes_lun;
+	struct fw_unit *unit = lu->tgt->unit;
 	struct fw_device *device = fw_device(unit->device.parent);
 	struct sbp2_login_response response;
-	int generation, node_id, local_node_id, lun, retval;
-
-	/* FIXME: Make this work for multi-lun devices. */
-	lun = 0;
+	int generation, node_id, local_node_id;
 
 	generation    = device->card->generation;
 	node_id       = device->node->node_id;
 	local_node_id = device->card->local_node->node_id;
 
-	if (sbp2_send_management_orb(unit, node_id, generation,
-				     SBP2_LOGIN_REQUEST, lun, &response) < 0) {
-		if (sd->retries++ < 5) {
-			schedule_delayed_work(&sd->work, DIV_ROUND_UP(HZ, 5));
+	if (sbp2_send_management_orb(lu, node_id, generation,
+				SBP2_LOGIN_REQUEST, lu->lun, &response) < 0) {
+		if (lu->retries++ < 5) {
+			schedule_delayed_work(&lu->work, DIV_ROUND_UP(HZ, 5));
 		} else {
-			fw_error("failed to login to %s\n",
-				 unit->device.bus_id);
-			kref_put(&sd->kref, release_sbp2_device);
+			fw_error("failed to login to %s LUN %04x\n",
+				 unit->device.bus_id, lu->lun);
+			kref_put(&lu->tgt->kref, sbp2_release_target);
 		}
 		return;
 	}
 
-	sd->generation   = generation;
-	sd->node_id      = node_id;
-	sd->address_high = local_node_id << 16;
+	lu->generation        = generation;
+	lu->tgt->node_id      = node_id;
+	lu->tgt->address_high = local_node_id << 16;
 
 	/* Get command block agent offset and login id. */
-	sd->command_block_agent_address =
+	lu->command_block_agent_address =
 		((u64) (response.command_block_agent.high & 0xffff) << 32) |
 		response.command_block_agent.low;
-	sd->login_id = LOGIN_RESPONSE_GET_LOGIN_ID(response);
+	lu->login_id = LOGIN_RESPONSE_GET_LOGIN_ID(response);
 
-	fw_notify("logged in to sbp2 unit %s (%d retries)\n",
-		  unit->device.bus_id, sd->retries);
-	fw_notify(" - management_agent_address:    0x%012llx\n",
-		  (unsigned long long) sd->management_agent_address);
-	fw_notify(" - command_block_agent_address: 0x%012llx\n",
-		  (unsigned long long) sd->command_block_agent_address);
-	fw_notify(" - status write address:        0x%012llx\n",
-		  (unsigned long long) sd->address_handler.offset);
+	fw_notify("logged in to %s LUN %04x (%d retries)\n",
+		  unit->device.bus_id, lu->lun, lu->retries);
 
 #if 0
 	/* FIXME: The linux1394 sbp2 does this last step. */
 	sbp2_set_busy_timeout(scsi_id);
 #endif
 
-	PREPARE_DELAYED_WORK(&sd->work, sbp2_reconnect);
-	sbp2_agent_reset(unit);
+	PREPARE_DELAYED_WORK(&lu->work, sbp2_reconnect);
+	sbp2_agent_reset(lu);
 
-	/* FIXME: Loop over luns here. */
-	lun = 0;
-	retval = scsi_add_device(host, 0, 0, lun);
-	if (retval < 0) {
-		sbp2_send_management_orb(unit, sd->node_id, sd->generation,
-					 SBP2_LOGOUT_REQUEST, sd->login_id,
-					 NULL);
+	memset(&eight_bytes_lun, 0, sizeof(eight_bytes_lun));
+	eight_bytes_lun.scsi_lun[0] = (lu->lun >> 8) & 0xff;
+	eight_bytes_lun.scsi_lun[1] = lu->lun & 0xff;
+
+	sdev = __scsi_add_device(shost, 0, 0,
+				 scsilun_to_int(&eight_bytes_lun), lu);
+	if (IS_ERR(sdev)) {
+		sbp2_send_management_orb(lu, node_id, generation,
+				SBP2_LOGOUT_REQUEST, lu->login_id, NULL);
 		/*
 		 * Set this back to sbp2_login so we fall back and
 		 * retry login on bus reset.
 		 */
-		PREPARE_DELAYED_WORK(&sd->work, sbp2_login);
+		PREPARE_DELAYED_WORK(&lu->work, sbp2_login);
+	} else {
+		lu->sdev = sdev;
+		scsi_device_put(sdev);
 	}
-	kref_put(&sd->kref, release_sbp2_device);
+	kref_put(&lu->tgt->kref, sbp2_release_target);
 }
 
-static int sbp2_probe(struct device *dev)
+static int sbp2_add_logical_unit(struct sbp2_target *tgt, int lun_entry)
+{
+	struct sbp2_logical_unit *lu;
+
+	lu = kmalloc(sizeof(*lu), GFP_KERNEL);
+	if (!lu)
+		return -ENOMEM;
+
+	lu->address_handler.length           = 0x100;
+	lu->address_handler.address_callback = sbp2_status_write;
+	lu->address_handler.callback_data    = lu;
+
+	if (fw_core_add_address_handler(&lu->address_handler,
+					&fw_high_memory_region) < 0) {
+		kfree(lu);
+		return -ENOMEM;
+	}
+
+	lu->tgt  = tgt;
+	lu->sdev = NULL;
+	lu->lun  = lun_entry & 0xffff;
+	lu->retries = 0;
+	INIT_LIST_HEAD(&lu->orb_list);
+	INIT_DELAYED_WORK(&lu->work, sbp2_login);
+
+	list_add_tail(&lu->link, &tgt->lu_list);
+	return 0;
+}
+
+static int sbp2_scan_logical_unit_dir(struct sbp2_target *tgt, u32 *directory)
 {
-	struct fw_unit *unit = fw_unit(dev);
-	struct fw_device *device = fw_device(unit->device.parent);
-	struct sbp2_device *sd;
 	struct fw_csr_iterator ci;
-	struct Scsi_Host *host;
-	int i, key, value, err;
-	u32 model, firmware_revision;
+	int key, value;
 
-	err = -ENOMEM;
-	host = scsi_host_alloc(&scsi_driver_template, sizeof(*sd));
-	if (host == NULL)
-		goto fail;
+	fw_csr_iterator_init(&ci, directory);
+	while (fw_csr_iterator_next(&ci, &key, &value))
+		if (key == SBP2_CSR_LOGICAL_UNIT_NUMBER &&
+		    sbp2_add_logical_unit(tgt, value) < 0)
+			return -ENOMEM;
+	return 0;
+}
 
-	sd = (struct sbp2_device *) host->hostdata;
-	unit->device.driver_data = sd;
-	sd->unit = unit;
-	INIT_LIST_HEAD(&sd->orb_list);
-	kref_init(&sd->kref);
-
-	sd->address_handler.length = 0x100;
-	sd->address_handler.address_callback = sbp2_status_write;
-	sd->address_handler.callback_data = sd;
-
-	err = fw_core_add_address_handler(&sd->address_handler,
-					  &fw_high_memory_region);
-	if (err < 0)
-		goto fail_host;
-
-	err = fw_device_enable_phys_dma(device);
-	if (err < 0)
-		goto fail_address_handler;
-
-	err = scsi_add_host(host, &unit->device);
-	if (err < 0)
-		goto fail_address_handler;
+static int sbp2_scan_unit_dir(struct sbp2_target *tgt, u32 *directory,
+			      u32 *model, u32 *firmware_revision)
+{
+	struct fw_csr_iterator ci;
+	int key, value;
 
-	/*
-	 * Scan unit directory to get management agent address,
-	 * firmware revison and model.  Initialize firmware_revision
-	 * and model to values that wont match anything in our table.
-	 */
-	firmware_revision = 0xff000000;
-	model = 0xff000000;
-	fw_csr_iterator_init(&ci, unit->directory);
+	fw_csr_iterator_init(&ci, directory);
 	while (fw_csr_iterator_next(&ci, &key, &value)) {
 		switch (key) {
+
 		case CSR_DEPENDENT_INFO | CSR_OFFSET:
-			sd->management_agent_address =
-				0xfffff0000000ULL + 4 * value;
+			tgt->management_agent_address =
+					CSR_REGISTER_BASE + 4 * value;
 			break;
-		case SBP2_FIRMWARE_REVISION:
-			firmware_revision = value;
+
+		case CSR_DIRECTORY_ID:
+			tgt->directory_id = value;
 			break;
+
 		case CSR_MODEL:
-			model = value;
+			*model = value;
+			break;
+
+		case SBP2_CSR_FIRMWARE_REVISION:
+			*firmware_revision = value;
+			break;
+
+		case SBP2_CSR_LOGICAL_UNIT_NUMBER:
+			if (sbp2_add_logical_unit(tgt, value) < 0)
+				return -ENOMEM;
+			break;
+
+		case SBP2_CSR_LOGICAL_UNIT_DIRECTORY:
+			if (sbp2_scan_logical_unit_dir(tgt, ci.p + value) < 0)
+				return -ENOMEM;
 			break;
 		}
 	}
+	return 0;
+}
+
+static void sbp2_init_workarounds(struct sbp2_target *tgt, u32 model,
+				  u32 firmware_revision)
+{
+	int i;
+
+	tgt->workarounds = 0;
 
 	for (i = 0; i < ARRAY_SIZE(sbp2_workarounds_table); i++) {
+
 		if (sbp2_workarounds_table[i].firmware_revision !=
 		    (firmware_revision & 0xffffff00))
 			continue;
+
 		if (sbp2_workarounds_table[i].model != model &&
 		    sbp2_workarounds_table[i].model != ~0)
 			continue;
-		sd->workarounds |= sbp2_workarounds_table[i].workarounds;
+
+		tgt->workarounds |= sbp2_workarounds_table[i].workarounds;
 		break;
 	}
 
-	if (sd->workarounds)
-		fw_notify("Workarounds for node %s: 0x%x "
+	if (tgt->workarounds)
+		fw_notify("Workarounds for %s: 0x%x "
 			  "(firmware_revision 0x%06x, model_id 0x%06x)\n",
-			  unit->device.bus_id,
-			  sd->workarounds, firmware_revision, model);
+			  tgt->unit->device.bus_id,
+			  tgt->workarounds, firmware_revision, model);
+}
+
+static struct scsi_host_template scsi_driver_template;
+
+static int sbp2_probe(struct device *dev)
+{
+	struct fw_unit *unit = fw_unit(dev);
+	struct fw_device *device = fw_device(unit->device.parent);
+	struct sbp2_target *tgt;
+	struct sbp2_logical_unit *lu;
+	struct Scsi_Host *shost;
+	u32 model, firmware_revision;
+
+	shost = scsi_host_alloc(&scsi_driver_template, sizeof(*tgt));
+	if (shost == NULL)
+		return -ENOMEM;
+
+	tgt = (struct sbp2_target *)shost->hostdata;
+	unit->device.driver_data = tgt;
+	tgt->unit = unit;
+	kref_init(&tgt->kref);
+	INIT_LIST_HEAD(&tgt->lu_list);
+
+	if (fw_device_enable_phys_dma(device) < 0)
+		goto fail_shost_put;
+
+	if (scsi_add_host(shost, &unit->device) < 0)
+		goto fail_shost_put;
+
+	/* Initialize to values that won't match anything in our table. */
+	firmware_revision = 0xff000000;
+	model = 0xff000000;
+
+	/* implicit directory ID */
+	tgt->directory_id = ((unit->directory - device->config_rom) * 4
+			     + CSR_CONFIG_ROM) & 0xffffff;
+
+	if (sbp2_scan_unit_dir(tgt, unit->directory, &model,
+			       &firmware_revision) < 0)
+		goto fail_tgt_put;
+
+	sbp2_init_workarounds(tgt, model, firmware_revision);
 
 	get_device(&unit->device);
 
@@ -730,35 +823,34 @@ static int sbp2_probe(struct device *dev
 	 * reschedule retries. Always get the ref before scheduling
 	 * work.
 	 */
-	INIT_DELAYED_WORK(&sd->work, sbp2_login);
-	if (schedule_delayed_work(&sd->work, 0))
-		kref_get(&sd->kref);
-
+	list_for_each_entry(lu, &tgt->lu_list, link)
+		if (schedule_delayed_work(&lu->work, 0))
+			kref_get(&tgt->kref);
 	return 0;
 
- fail_address_handler:
-	fw_core_remove_address_handler(&sd->address_handler);
- fail_host:
-	scsi_host_put(host);
- fail:
-	return err;
+ fail_tgt_put:
+	kref_put(&tgt->kref, sbp2_release_target);
+	return -ENOMEM;
+
+ fail_shost_put:
+	scsi_host_put(shost);
+	return -ENOMEM;
 }
 
 static int sbp2_remove(struct device *dev)
 {
 	struct fw_unit *unit = fw_unit(dev);
-	struct sbp2_device *sd = unit->device.driver_data;
-
-	kref_put(&sd->kref, release_sbp2_device);
+	struct sbp2_target *tgt = unit->device.driver_data;
 
+	kref_put(&tgt->kref, sbp2_release_target);
 	return 0;
 }
 
 static void sbp2_reconnect(struct work_struct *work)
 {
-	struct sbp2_device *sd =
-		container_of(work, struct sbp2_device, work.work);
-	struct fw_unit *unit = sd->unit;
+	struct sbp2_logical_unit *lu =
+		container_of(work, struct sbp2_logical_unit, work.work);
+	struct fw_unit *unit = lu->tgt->unit;
 	struct fw_device *device = fw_device(unit->device.parent);
 	int generation, node_id, local_node_id;
 
@@ -766,40 +858,49 @@ static void sbp2_reconnect(struct work_s
 	node_id       = device->node->node_id;
 	local_node_id = device->card->local_node->node_id;
 
-	if (sbp2_send_management_orb(unit, node_id, generation,
+	if (sbp2_send_management_orb(lu, node_id, generation,
 				     SBP2_RECONNECT_REQUEST,
-				     sd->login_id, NULL) < 0) {
-		if (sd->retries++ >= 5) {
+				     lu->login_id, NULL) < 0) {
+		if (lu->retries++ >= 5) {
 			fw_error("failed to reconnect to %s\n",
 				 unit->device.bus_id);
 			/* Fall back and try to log in again. */
-			sd->retries = 0;
-			PREPARE_DELAYED_WORK(&sd->work, sbp2_login);
+			lu->retries = 0;
+			PREPARE_DELAYED_WORK(&lu->work, sbp2_login);
 		}
-		schedule_delayed_work(&sd->work, DIV_ROUND_UP(HZ, 5));
+		schedule_delayed_work(&lu->work, DIV_ROUND_UP(HZ, 5));
 		return;
 	}
 
-	sd->generation   = generation;
-	sd->node_id      = node_id;
-	sd->address_high = local_node_id << 16;
-
-	fw_notify("reconnected to unit %s (%d retries)\n",
-		  unit->device.bus_id, sd->retries);
-	sbp2_agent_reset(unit);
-	sbp2_cancel_orbs(unit);
-	kref_put(&sd->kref, release_sbp2_device);
+	lu->generation        = generation;
+	lu->tgt->node_id      = node_id;
+	lu->tgt->address_high = local_node_id << 16;
+
+	fw_notify("reconnected to %s LUN %04x (%d retries)\n",
+		  unit->device.bus_id, lu->lun, lu->retries);
+
+	sbp2_agent_reset(lu);
+	sbp2_cancel_orbs(lu);
+
+	kref_put(&lu->tgt->kref, sbp2_release_target);
 }
 
 static void sbp2_update(struct fw_unit *unit)
 {
-	struct fw_device *device = fw_device(unit->device.parent);
-	struct sbp2_device *sd = unit->device.driver_data;
+	struct sbp2_target *tgt = unit->device.driver_data;
+	struct sbp2_logical_unit *lu;
 
-	sd->retries = 0;
-	fw_device_enable_phys_dma(device);
-	if (schedule_delayed_work(&sd->work, 0))
-		kref_get(&sd->kref);
+	fw_device_enable_phys_dma(fw_device(unit->device.parent));
+
+	/*
+	 * Fw-core serializes sbp2_update() against sbp2_remove().
+	 * Iteration over tgt->lu_list is therefore safe here.
+	 */
+	list_for_each_entry(lu, &tgt->lu_list, link) {
+		lu->retries = 0;
+		if (schedule_delayed_work(&lu->work, 0))
+			kref_get(&tgt->kref);
+	}
 }
 
 #define SBP2_UNIT_SPEC_ID_ENTRY	0x0000609e
@@ -869,13 +970,12 @@ complete_command_orb(struct sbp2_orb *ba
 {
 	struct sbp2_command_orb *orb =
 		container_of(base_orb, struct sbp2_command_orb, base);
-	struct fw_unit *unit = orb->unit;
-	struct fw_device *device = fw_device(unit->device.parent);
+	struct fw_device *device = fw_device(orb->lu->tgt->unit->device.parent);
 	int result;
 
 	if (status != NULL) {
 		if (STATUS_GET_DEAD(*status))
-			sbp2_agent_reset(unit);
+			sbp2_agent_reset(orb->lu);
 
 		switch (STATUS_GET_RESPONSE(*status)) {
 		case SBP2_STATUS_REQUEST_COMPLETE:
@@ -919,12 +1019,10 @@ complete_command_orb(struct sbp2_orb *ba
 	orb->done(orb->cmd);
 }
 
-static int sbp2_command_orb_map_scatterlist(struct sbp2_command_orb *orb)
+static int
+sbp2_map_scatterlist(struct sbp2_command_orb *orb, struct fw_device *device,
+		     struct sbp2_logical_unit *lu)
 {
-	struct sbp2_device *sd =
-		(struct sbp2_device *)orb->cmd->device->host->hostdata;
-	struct fw_unit *unit = sd->unit;
-	struct fw_device *device = fw_device(unit->device.parent);
 	struct scatterlist *sg;
 	int sg_len, l, i, j, count;
 	dma_addr_t sg_addr;
@@ -943,10 +1041,9 @@ static int sbp2_command_orb_map_scatterl
 	 * tables.
 	 */
 	if (count == 1 && sg_dma_len(sg) < SBP2_MAX_SG_ELEMENT_LENGTH) {
-		orb->request.data_descriptor.high = sd->address_high;
+		orb->request.data_descriptor.high = lu->tgt->address_high;
 		orb->request.data_descriptor.low  = sg_dma_address(sg);
-		orb->request.misc |=
-			COMMAND_ORB_DATA_SIZE(sg_dma_len(sg));
+		orb->request.misc |= COMMAND_ORB_DATA_SIZE(sg_dma_len(sg));
 		return 0;
 	}
 
@@ -990,7 +1087,7 @@ static int sbp2_command_orb_map_scatterl
 	 * initiator (i.e. us), but data_descriptor can refer to data
 	 * on other nodes so we need to put our ID in descriptor.high.
 	 */
-	orb->request.data_descriptor.high = sd->address_high;
+	orb->request.data_descriptor.high = lu->tgt->address_high;
 	orb->request.data_descriptor.low  = orb->page_table_bus;
 	orb->request.misc |=
 		COMMAND_ORB_PAGE_TABLE_PRESENT |
@@ -1009,12 +1106,11 @@ static int sbp2_command_orb_map_scatterl
 
 static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done)
 {
-	struct sbp2_device *sd =
-		(struct sbp2_device *)cmd->device->host->hostdata;
-	struct fw_unit *unit = sd->unit;
-	struct fw_device *device = fw_device(unit->device.parent);
+	struct sbp2_logical_unit *lu = cmd->device->hostdata;
+	struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
 	struct sbp2_command_orb *orb;
 	unsigned max_payload;
+	int retval = SCSI_MLQUEUE_HOST_BUSY;
 
 	/*
 	 * Bidirectional commands are not yet implemented, and unknown
@@ -1030,14 +1126,14 @@ static int sbp2_scsi_queuecommand(struct
 	orb = kzalloc(sizeof(*orb), GFP_ATOMIC);
 	if (orb == NULL) {
 		fw_notify("failed to alloc orb\n");
-		goto fail_alloc;
+		return SCSI_MLQUEUE_HOST_BUSY;
 	}
 
 	/* Initialize rcode to something not RCODE_COMPLETE. */
 	orb->base.rcode = -1;
 	kref_init(&orb->base.kref);
 
-	orb->unit = unit;
+	orb->lu   = lu;
 	orb->done = done;
 	orb->cmd  = cmd;
 
@@ -1063,8 +1159,8 @@ static int sbp2_scsi_queuecommand(struct
 		orb->request.misc |=
 			COMMAND_ORB_DIRECTION(SBP2_DIRECTION_TO_MEDIA);
 
-	if (scsi_sg_count(cmd) && sbp2_command_orb_map_scatterlist(orb) < 0)
-		goto fail_mapping;
+	if (scsi_sg_count(cmd) && sbp2_map_scatterlist(orb, device, lu) < 0)
+		goto out;
 
 	fw_memcpy_to_be32(&orb->request, &orb->request, sizeof(orb->request));
 
@@ -1077,49 +1173,47 @@ static int sbp2_scsi_queuecommand(struct
 		dma_map_single(device->card->device, &orb->request,
 			       sizeof(orb->request), DMA_TO_DEVICE);
 	if (dma_mapping_error(orb->base.request_bus))
-		goto fail_mapping;
-
-	sbp2_send_orb(&orb->base, unit, sd->node_id, sd->generation,
-		      sd->command_block_agent_address + SBP2_ORB_POINTER);
-
-	kref_put(&orb->base.kref, free_orb);
-	return 0;
+		goto out;
 
- fail_mapping:
+	sbp2_send_orb(&orb->base, lu, lu->tgt->node_id, lu->generation,
+		      lu->command_block_agent_address + SBP2_ORB_POINTER);
+	retval = 0;
+ out:
 	kref_put(&orb->base.kref, free_orb);
- fail_alloc:
-	return SCSI_MLQUEUE_HOST_BUSY;
+	return retval;
 }
 
 static int sbp2_scsi_slave_alloc(struct scsi_device *sdev)
 {
-	struct sbp2_device *sd = (struct sbp2_device *)sdev->host->hostdata;
+	struct sbp2_logical_unit *lu = sdev->hostdata;
 
 	sdev->allow_restart = 1;
 
-	if (sd->workarounds & SBP2_WORKAROUND_INQUIRY_36)
+	if (lu->tgt->workarounds & SBP2_WORKAROUND_INQUIRY_36)
 		sdev->inquiry_len = 36;
+
 	return 0;
 }
 
 static int sbp2_scsi_slave_configure(struct scsi_device *sdev)
 {
-	struct sbp2_device *sd = (struct sbp2_device *)sdev->host->hostdata;
-	struct fw_unit *unit = sd->unit;
+	struct sbp2_logical_unit *lu = sdev->hostdata;
 
 	sdev->use_10_for_rw = 1;
 
 	if (sdev->type == TYPE_ROM)
 		sdev->use_10_for_ms = 1;
+
 	if (sdev->type == TYPE_DISK &&
-	    sd->workarounds & SBP2_WORKAROUND_MODE_SENSE_8)
+	    lu->tgt->workarounds & SBP2_WORKAROUND_MODE_SENSE_8)
 		sdev->skip_ms_page_8 = 1;
-	if (sd->workarounds & SBP2_WORKAROUND_FIX_CAPACITY) {
-		fw_notify("setting fix_capacity for %s\n", unit->device.bus_id);
+
+	if (lu->tgt->workarounds & SBP2_WORKAROUND_FIX_CAPACITY)
 		sdev->fix_capacity = 1;
-	}
-	if (sd->workarounds & SBP2_WORKAROUND_128K_MAX_TRANS)
+
+	if (lu->tgt->workarounds & SBP2_WORKAROUND_128K_MAX_TRANS)
 		blk_queue_max_sectors(sdev->request_queue, 128 * 1024 / 512);
+
 	return 0;
 }
 
@@ -1129,13 +1223,11 @@ static int sbp2_scsi_slave_configure(str
  */
 static int sbp2_scsi_abort(struct scsi_cmnd *cmd)
 {
-	struct sbp2_device *sd =
-		(struct sbp2_device *)cmd->device->host->hostdata;
-	struct fw_unit *unit = sd->unit;
+	struct sbp2_logical_unit *lu = cmd->device->hostdata;
 
 	fw_notify("sbp2_scsi_abort\n");
-	sbp2_agent_reset(unit);
-	sbp2_cancel_orbs(unit);
+	sbp2_agent_reset(lu);
+	sbp2_cancel_orbs(lu);
 
 	return SUCCESS;
 }
@@ -1152,37 +1244,18 @@ sbp2_sysfs_ieee1394_id_show(struct devic
 			    char *buf)
 {
 	struct scsi_device *sdev = to_scsi_device(dev);
-	struct sbp2_device *sd;
-	struct fw_unit *unit;
+	struct sbp2_logical_unit *lu;
 	struct fw_device *device;
-	u32 directory_id;
-	struct fw_csr_iterator ci;
-	int key, value, lun;
 
 	if (!sdev)
 		return 0;
-	sd = (struct sbp2_device *)sdev->host->hostdata;
-	unit = sd->unit;
-	device = fw_device(unit->device.parent);
-
-	/* implicit directory ID */
-	directory_id = ((unit->directory - device->config_rom) * 4
-			+ CSR_CONFIG_ROM) & 0xffffff;
-
-	/* explicit directory ID, overrides implicit ID if present */
-	fw_csr_iterator_init(&ci, unit->directory);
-	while (fw_csr_iterator_next(&ci, &key, &value))
-		if (key == CSR_DIRECTORY_ID) {
-			directory_id = value;
-			break;
-		}
 
-	/* FIXME: Make this work for multi-lun devices. */
-	lun = 0;
+	lu = sdev->hostdata;
+	device = fw_device(lu->tgt->unit->device.parent);
 
 	return sprintf(buf, "%08x%08x:%06x:%04x\n",
 			device->config_rom[3], device->config_rom[4],
-			directory_id, lun);
+			lu->tgt->directory_id, lu->lun);
 }
 
 static DEVICE_ATTR(ieee1394_id, S_IRUGO, sbp2_sysfs_ieee1394_id_show, NULL);

-- 
Stefan Richter
-=====-=-=== =--- ==--=
http://arcgraph.de/sr/


linux-2.6-fix-pmops-1.patch:

--- NEW FILE linux-2.6-fix-pmops-1.patch ---
>From johannes at sipsolutions.net Wed Mar 21 15:56:28 2007
Date: Wed, 21 Mar 2007 15:56:28 +0100
From: Johannes Berg <johannes at sipsolutions.net>
To: Andrew Morton <akpm at linux-foundation.org>
Cc: linux-pm at lists.linux-foundation.org, David Brownell <david-b at pacbell.net>, Pavel Machek <pavel at ucw.cz>
Subject: [PATCH 1/3] rework pm_ops pm_disk_mode, kill misuse

The pm_ops.pm_disk_mode is used in totally bogus ways since
nobody really seems to understand what it actually does.

This patch clarifies the pm_disk_mode description.

It also removes all the arm and sh users that think they can veto
suspend to disk via pm_ops; not so since the user can always
do echo shutdown > /sys/power/disk, they need to find a better
way involving Kconfig or such.

ACPI is the only user left with a non-zero pm_disk_mode.

The patch also sets the default mode to shutdown again, but
when a new pm_ops is registered its pm_disk_mode is selected
as default, that way the default stays for ACPI where it is
apparently required.

Signed-off-by: Johannes Berg <johannes at sipsolutions.net>
Cc: David Brownell <david-b at pacbell.net>
Cc: Pavel Machek <pavel at ucw.cz>
Cc: linux-pm at lists.linux-foundation.org

---
 arch/arm/common/sharpsl_pm.c |    1 
 arch/arm/mach-at91/pm.c      |    1 
 arch/arm/mach-omap1/pm.c     |    1 
 arch/arm/mach-omap2/pm.c     |    1 
 arch/arm/mach-pxa/pm.c       |    4 ---
 arch/arm/mach-sa1100/pm.c    |    7 -----
 arch/arm/plat-s3c24xx/pm.c   |    9 ------
 arch/sh/boards/hp6xx/pm.c    |    7 -----
 include/linux/pm.h           |   23 +++++++++--------
 kernel/power/disk.c          |   56 ++++++++++++++++++++++++++++---------------
 kernel/power/main.c          |    6 +++-
 11 files changed, 54 insertions(+), 62 deletions(-)

--- linux-2.6.orig/include/linux/pm.h	2007-03-20 12:41:38.423214909 +0100
+++ linux-2.6/include/linux/pm.h	2007-03-20 12:42:02.253214909 +0100
@@ -112,6 +112,8 @@ typedef int __bitwise suspend_state_t;
 
 typedef int __bitwise suspend_disk_method_t;
 
+/* invalid must be 0 so struct pm_ops initialisers can leave it out */
+#define PM_DISK_INVALID		((__force suspend_disk_method_t) 0)
 #define	PM_DISK_FIRMWARE	((__force suspend_disk_method_t) 1)
 #define	PM_DISK_PLATFORM	((__force suspend_disk_method_t) 2)
 #define	PM_DISK_SHUTDOWN	((__force suspend_disk_method_t) 3)
@@ -137,17 +139,16 @@ typedef int __bitwise suspend_disk_metho
  * @finish: Called when the system has left the given state and all devices
  *	are resumed. The return value is ignored.
  *
- * @pm_disk_mode: Set to the disk method that the user should be able to
- *	configure for suspend-to-disk. Since %PM_DISK_SHUTDOWN,
- *	%PM_DISK_REBOOT, %PM_DISK_TEST and %PM_DISK_TESTPROC
- *	are always allowed, currently only %PM_DISK_PLATFORM
- *	makes sense. If the user then choses %PM_DISK_PLATFORM,
- *	the @prepare call will be called before suspending to disk
- *	(if present), the @enter call should be present and will
- *	be called after all state has been saved and the machine
- *	is ready to be shut down/suspended/..., and the @finish
- *	callback is called after state has been restored. All
- *	these calls are called with %PM_SUSPEND_DISK as the state.
+ * @pm_disk_mode: The generic code always allows one of the shutdown methods
+ *	%PM_DISK_SHUTDOWN, %PM_DISK_REBOOT, %PM_DISK_TEST and
+ *	%PM_DISK_TESTPROC. If this variable is set, the mode it is set
+ *	to is allowed in addition to those modes and is also made default.
+ *	When this mode is sent selected, the @prepare call will be called
+ *	before suspending to disk (if present), the @enter call should be
+ *	present and will be called after all state has been saved and the
+ *	machine is ready to be powered off; the @finish callback is called
+ *	after state has been restored. All these calls are called with
+ *	%PM_SUSPEND_DISK as the state.
  */
 struct pm_ops {
 	int (*valid)(suspend_state_t state);
--- linux-2.6.orig/kernel/power/disk.c	2007-03-20 12:41:38.463214909 +0100
+++ linux-2.6/kernel/power/disk.c	2007-03-20 12:42:02.263214909 +0100
@@ -39,7 +39,13 @@ static inline int platform_prepare(void)
 {
 	int error = 0;
 
-	if (pm_disk_mode == PM_DISK_PLATFORM) {
+	switch (pm_disk_mode) {
+	case PM_DISK_TEST:
+	case PM_DISK_TESTPROC:
+	case PM_DISK_SHUTDOWN:
+	case PM_DISK_REBOOT:
+		break;
+	default:
 		if (pm_ops && pm_ops->prepare)
 			error = pm_ops->prepare(PM_SUSPEND_DISK);
 	}
@@ -48,30 +54,32 @@ static inline int platform_prepare(void)
 
 /**
  *	power_down - Shut machine down for hibernate.
- *	@mode:		Suspend-to-disk mode
  *
- *	Use the platform driver, if configured so, and return gracefully if it
- *	fails.
- *	Otherwise, try to power off and reboot. If they fail, halt the machine,
- *	there ain't no turning back.
+ *	Use the platform driver, if configured so; otherwise try
+ *	to power off or reboot.
  */
 
-static void power_down(suspend_disk_method_t mode)
+static void power_down(void)
 {
-	switch(mode) {
-	case PM_DISK_PLATFORM:
-		if (pm_ops && pm_ops->enter) {
-			kernel_shutdown_prepare(SYSTEM_SUSPEND_DISK);
-			pm_ops->enter(PM_SUSPEND_DISK);
-			break;
-		}
+
+	switch (pm_disk_mode) {
+	case PM_DISK_TEST:
+	case PM_DISK_TESTPROC:
+		break;
 	case PM_DISK_SHUTDOWN:
 		kernel_power_off();
 		break;
 	case PM_DISK_REBOOT:
 		kernel_restart(NULL);
 		break;
+	default:
+		if (pm_ops && pm_ops->enter) {
+			kernel_shutdown_prepare(SYSTEM_SUSPEND_DISK);
+			pm_ops->enter(PM_SUSPEND_DISK);
+			break;
+		}
 	}
+
 	kernel_halt();
 	/* Valid image is on the disk, if we continue we risk serious data corruption
 	   after resume. */
@@ -82,7 +90,13 @@ static void power_down(suspend_disk_meth
 
 static inline void platform_finish(void)
 {
-	if (pm_disk_mode == PM_DISK_PLATFORM) {
+	switch (pm_disk_mode) {
+	case PM_DISK_TEST:
+	case PM_DISK_TESTPROC:
+	case PM_DISK_SHUTDOWN:
+	case PM_DISK_REBOOT:
+		break;
+	default:
 		if (pm_ops && pm_ops->finish)
 			pm_ops->finish(PM_SUSPEND_DISK);
 	}
@@ -167,7 +181,7 @@ int pm_suspend_disk(void)
 		pr_debug("PM: writing image.\n");
 		error = swsusp_write();
 		if (!error)
-			power_down(pm_disk_mode);
+			power_down();
 		else {
 			swsusp_free();
 			goto Thaw;
@@ -347,10 +361,14 @@ static ssize_t disk_store(struct subsyst
 		}
 	}
 	if (mode) {
-		if (mode == PM_DISK_SHUTDOWN || mode == PM_DISK_REBOOT ||
-		     mode == PM_DISK_TEST || mode == PM_DISK_TESTPROC) {
+		switch (mode) {
+		case PM_DISK_SHUTDOWN:
+		case PM_DISK_REBOOT:
+		case PM_DISK_TEST:
+		case PM_DISK_TESTPROC:
 			pm_disk_mode = mode;
-		} else {
+			break;
+		default:
 			if (pm_ops && pm_ops->enter &&
 			    (mode == pm_ops->pm_disk_mode))
 				pm_disk_mode = mode;
--- linux-2.6.orig/kernel/power/main.c	2007-03-20 12:41:38.543214909 +0100
+++ linux-2.6/kernel/power/main.c	2007-03-20 12:42:02.263214909 +0100
@@ -30,7 +30,7 @@
 DEFINE_MUTEX(pm_mutex);
 
 struct pm_ops *pm_ops;
-suspend_disk_method_t pm_disk_mode = PM_DISK_PLATFORM;
+suspend_disk_method_t pm_disk_mode = PM_DISK_SHUTDOWN;
 
 /**
  *	pm_set_ops - Set the global power method table. 
@@ -41,6 +41,10 @@ void pm_set_ops(struct pm_ops * ops)
 {
 	mutex_lock(&pm_mutex);
 	pm_ops = ops;
+	if (ops && ops->pm_disk_mode != PM_DISK_INVALID) {
+		pm_disk_mode = ops->pm_disk_mode;
+	} else
+		pm_disk_mode = PM_DISK_SHUTDOWN;
 	mutex_unlock(&pm_mutex);
 }
 
--- linux-2.6.orig/arch/arm/common/sharpsl_pm.c	2007-03-20 12:41:38.673214909 +0100
+++ linux-2.6/arch/arm/common/sharpsl_pm.c	2007-03-20 12:42:02.263214909 +0100
@@ -766,7 +766,6 @@ static void sharpsl_apm_get_power_status
 }
 
 static struct pm_ops sharpsl_pm_ops = {
-	.pm_disk_mode	= PM_DISK_FIRMWARE,
 	.prepare	= pxa_pm_prepare,
 	.enter		= corgi_pxa_pm_enter,
 	.finish		= pxa_pm_finish,
--- linux-2.6.orig/arch/arm/mach-at91/pm.c	2007-03-20 12:41:38.743214909 +0100
+++ linux-2.6/arch/arm/mach-at91/pm.c	2007-03-20 12:42:02.263214909 +0100
@@ -201,7 +201,6 @@ error:
 
 
 static struct pm_ops at91_pm_ops ={
-	.pm_disk_mode	= 0,
 	.valid		= at91_pm_valid_state,
 	.prepare	= at91_pm_prepare,
 	.enter		= at91_pm_enter,
--- linux-2.6.orig/arch/arm/mach-omap1/pm.c	2007-03-20 12:41:38.763214909 +0100
+++ linux-2.6/arch/arm/mach-omap1/pm.c	2007-03-20 12:42:02.263214909 +0100
@@ -698,7 +698,6 @@ static struct irqaction omap_wakeup_irq 
 
 
 static struct pm_ops omap_pm_ops ={
-	.pm_disk_mode	= 0,
 	.prepare	= omap_pm_prepare,
 	.enter		= omap_pm_enter,
 	.finish		= omap_pm_finish,
--- linux-2.6.orig/arch/arm/mach-omap2/pm.c	2007-03-20 12:41:38.833214909 +0100
+++ linux-2.6/arch/arm/mach-omap2/pm.c	2007-03-20 12:42:02.263214909 +0100
@@ -370,7 +370,6 @@ static int omap2_pm_finish(suspend_state
 }
 
 static struct pm_ops omap_pm_ops = {
-	.pm_disk_mode	= 0,
 	.prepare	= omap2_pm_prepare,
 	.enter		= omap2_pm_enter,
 	.finish		= omap2_pm_finish,
--- linux-2.6.orig/arch/arm/mach-pxa/pm.c	2007-03-20 12:41:38.853214909 +0100
+++ linux-2.6/arch/arm/mach-pxa/pm.c	2007-03-20 12:42:02.263214909 +0100
@@ -223,11 +223,7 @@ int pxa_pm_finish(suspend_state_t state)
 
 EXPORT_SYMBOL_GPL(pxa_pm_finish);
 
-/*
- * Set to PM_DISK_FIRMWARE so we can quickly veto suspend-to-disk.
- */
 static struct pm_ops pxa_pm_ops = {
-	.pm_disk_mode	= PM_DISK_FIRMWARE,
 	.prepare	= pxa_pm_prepare,
 	.enter		= pxa_pm_enter,
 	.finish		= pxa_pm_finish,
--- linux-2.6.orig/arch/arm/mach-sa1100/pm.c	2007-03-20 12:41:38.903214909 +0100
+++ linux-2.6/arch/arm/mach-sa1100/pm.c	2007-03-20 12:42:02.273214909 +0100
@@ -59,9 +59,6 @@ static int sa11x0_pm_enter(suspend_state
 	unsigned long gpio, sleep_save[SLEEP_SAVE_SIZE];
 	struct timespec delta, rtc;
 
-	if (state != PM_SUSPEND_MEM)
-		return -EINVAL;
-
 	/* preserve current time */
 	rtc.tv_sec = RCNR;
 	rtc.tv_nsec = 0;
@@ -134,11 +131,7 @@ unsigned long sleep_phys_sp(void *sp)
 	return virt_to_phys(sp);
 }
 
-/*
- * Set to PM_DISK_FIRMWARE so we can quickly veto suspend-to-disk.
- */
 static struct pm_ops sa11x0_pm_ops = {
-	.pm_disk_mode	= PM_DISK_FIRMWARE,
 	.enter		= sa11x0_pm_enter,
 };
 
--- linux-2.6.orig/arch/arm/plat-s3c24xx/pm.c	2007-03-20 12:41:38.953214909 +0100
+++ linux-2.6/arch/arm/plat-s3c24xx/pm.c	2007-03-20 12:42:02.273214909 +0100
@@ -511,11 +511,6 @@ static int s3c2410_pm_enter(suspend_stat
 		return -EINVAL;
 	}
 
-	if (state != PM_SUSPEND_MEM) {
-		printk(KERN_ERR PFX "error: only PM_SUSPEND_MEM supported\n");
-		return -EINVAL;
-	}
-
 	/* check if we have anything to wake-up with... bad things seem
 	 * to happen if you suspend with no wakeup (system will often
 	 * require a full power-cycle)
@@ -633,11 +628,7 @@ static int s3c2410_pm_finish(suspend_sta
 	return 0;
 }
 
-/*
- * Set to PM_DISK_FIRMWARE so we can quickly veto suspend-to-disk.
- */
 static struct pm_ops s3c2410_pm_ops = {
-	.pm_disk_mode	= PM_DISK_FIRMWARE,
 	.prepare	= s3c2410_pm_prepare,
 	.enter		= s3c2410_pm_enter,
 	.finish		= s3c2410_pm_finish,
--- linux-2.6.orig/arch/sh/boards/hp6xx/pm.c	2007-03-20 12:41:39.163214909 +0100
+++ linux-2.6/arch/sh/boards/hp6xx/pm.c	2007-03-20 12:42:02.273214909 +0100
@@ -27,9 +27,6 @@ static int hp6x0_pm_enter(suspend_state_
 	u16 hd64461_stbcr;
 #endif
 
-	if (state != PM_SUSPEND_MEM)
-		return -EINVAL;
-
 #ifdef CONFIG_HD64461_ENABLER
 	outb(0, HD64461_PCC1CSCIER);
 
@@ -70,11 +67,7 @@ static int hp6x0_pm_enter(suspend_state_
 	return 0;
 }
 
-/*
- * Set to PM_DISK_FIRMWARE so we can quickly veto suspend-to-disk.
- */
 static struct pm_ops hp6x0_pm_ops = {
-	.pm_disk_mode	= PM_DISK_FIRMWARE,
 	.enter		= hp6x0_pm_enter,
 };
 

--

linux-2.6-fix-pmops-2.patch:

--- NEW FILE linux-2.6-fix-pmops-2.patch ---
>From johannes at sipsolutions.net Wed Mar 21 15:56:26 2007
Date: Wed, 21 Mar 2007 15:56:26 +0100
From: Johannes Berg <johannes at sipsolutions.net>
To: Andrew Morton <akpm at linux-foundation.org>
Cc: linux-pm at lists.linux-foundation.org, Pavel Machek <pavel at ucw.cz>
Subject: [PATCH 2/3] power management: remove firmware disk mode

This patch removes the firmware disk suspend mode which is the wrong
approach, it is supposed to be used for implementing firmware-based disk
suspend but cannot actually be used for that.

Signed-off-by: Johannes Berg <johannes at sipsolutions.net>
Cc: Pavel Machek <pavel at ucw.cz>
Cc: linux-pm at lists.linux-foundation.org

---
 Documentation/power/interface.txt |   21 +++++----------------
 Documentation/power/states.txt    |   13 +++++++------
 Documentation/power/swsusp.txt    |   14 +++++---------
 include/linux/pm.h                |   13 ++++++-------
 kernel/power/disk.c               |   27 +++++++++++----------------
 5 files changed, 34 insertions(+), 54 deletions(-)

--- linux-2.6.orig/include/linux/pm.h	2007-03-21 15:44:54.663148946 +0100
+++ linux-2.6/include/linux/pm.h	2007-03-21 15:45:04.403148946 +0100
@@ -114,13 +114,12 @@ typedef int __bitwise suspend_disk_metho
 
 /* invalid must be 0 so struct pm_ops initialisers can leave it out */
 #define PM_DISK_INVALID		((__force suspend_disk_method_t) 0)
-#define	PM_DISK_FIRMWARE	((__force suspend_disk_method_t) 1)
-#define	PM_DISK_PLATFORM	((__force suspend_disk_method_t) 2)
-#define	PM_DISK_SHUTDOWN	((__force suspend_disk_method_t) 3)
-#define	PM_DISK_REBOOT		((__force suspend_disk_method_t) 4)
-#define	PM_DISK_TEST		((__force suspend_disk_method_t) 5)
-#define	PM_DISK_TESTPROC	((__force suspend_disk_method_t) 6)
-#define	PM_DISK_MAX		((__force suspend_disk_method_t) 7)
+#define	PM_DISK_PLATFORM	((__force suspend_disk_method_t) 1)
+#define	PM_DISK_SHUTDOWN	((__force suspend_disk_method_t) 2)
+#define	PM_DISK_REBOOT		((__force suspend_disk_method_t) 3)
+#define	PM_DISK_TEST		((__force suspend_disk_method_t) 4)
+#define	PM_DISK_TESTPROC	((__force suspend_disk_method_t) 5)
+#define	PM_DISK_MAX		((__force suspend_disk_method_t) 6)
 
 /**
  * struct pm_ops - Callbacks for managing platform dependent suspend states.
--- linux-2.6.orig/kernel/power/disk.c	2007-03-21 15:44:54.693148946 +0100
+++ linux-2.6/kernel/power/disk.c	2007-03-21 15:48:06.073148946 +0100
@@ -123,8 +123,6 @@ static int prepare_processes(void)
 /**
  *	pm_suspend_disk - The granpappy of hibernation power management.
  *
- *	If we're going through the firmware, then get it over with quickly.
- *
  *	If not, then call swsusp to do its thing, then figure out how
  *	to power down the system.
  */
@@ -301,7 +299,6 @@ late_initcall(software_resume);
 
 
 static const char * const pm_disk_modes[] = {
-	[PM_DISK_FIRMWARE]	= "firmware",
 	[PM_DISK_PLATFORM]	= "platform",
 	[PM_DISK_SHUTDOWN]	= "shutdown",
 	[PM_DISK_REBOOT]	= "reboot",
@@ -312,27 +309,25 @@ static const char * const pm_disk_modes[
 /**
  *	disk - Control suspend-to-disk mode
  *
- *	Suspend-to-disk can be handled in several ways. The greatest
- *	distinction is who writes memory to disk - the firmware or the OS.
- *	If the firmware does it, we assume that it also handles suspending
- *	the system.
- *	If the OS does it, then we have three options for putting the system
- *	to sleep - using the platform driver (e.g. ACPI or other PM registers),
- *	powering off the system or rebooting the system (for testing).
+ *	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 pm_ops), powering off the system or rebooting the system
+ *	(for testing) as well as the two test modes.
  *
- *	The system will support either 'firmware' or 'platform', and that is
- *	known a priori (and encoded in pm_ops). But, the user may choose
- *	'shutdown' or 'reboot' as alternatives.
+ *	The system can support 'platform', and that is known a priori (and
+ *	encoded in pm_ops). However, the user may choose 'shutdown' or 'reboot'
+ *	as alternatives, as well as the test modes 'test' and 'testproc'.
  *
  *	show() will display what the mode is currently set to.
  *	store() will accept one of
  *
- *	'firmware'
  *	'platform'
  *	'shutdown'
  *	'reboot'
+ *	'test'
+ *	'testproc'
  *
- *	It will only change to 'firmware' or 'platform' if the system
+ *	It will only change to 'platform' if the system
  *	supports it (as determined from pm_ops->pm_disk_mode).
  */
 
@@ -354,7 +349,7 @@ static ssize_t disk_store(struct subsyst
 	len = p ? p - buf : n;
 
 	mutex_lock(&pm_mutex);
-	for (i = PM_DISK_FIRMWARE; i < PM_DISK_MAX; i++) {
+	for (i = PM_DISK_PLATFORM; i < PM_DISK_MAX; i++) {
 		if (!strncmp(buf, pm_disk_modes[i], len)) {
 			mode = i;
 			break;
--- linux-2.6.orig/Documentation/power/interface.txt	2007-03-21 15:45:17.873148946 +0100
+++ linux-2.6/Documentation/power/interface.txt	2007-03-21 15:49:26.673148946 +0100
@@ -18,17 +18,10 @@ states.
 
 
 /sys/power/disk controls the operating mode of the suspend-to-disk
-mechanism. Suspend-to-disk can be handled in several ways. The
-greatest distinction is who writes memory to disk - the firmware or
-the kernel. If the firmware does it, we assume that it also handles
-suspending the system. 
-
-If the kernel does it, then we have three options for putting the system
-to sleep - using the platform driver (e.g. ACPI or other PM
-registers), powering off the system or rebooting the system (for
-testing). The system will support either 'firmware' or 'platform', and
-that is known a priori. But, the user may choose 'shutdown' or
-'reboot' as alternatives. 
+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 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
 modes of the suspend-to-disk mechanism: 'testproc' or 'test'.  If the
@@ -44,16 +37,12 @@ is being slow and which device drivers a
 Reading from this file will display what the mode is currently set
 to. Writing to this file will accept one of
 
-       'firmware'
-       'platform'
+       'platform' (only if the platform supports it)
        'shutdown'
        'reboot'
        'testproc'
        'test'
 
-It will only change to 'firmware' or 'platform' if the system supports
-it. 
-
 /sys/power/image_size controls the size of the image created by
 the suspend-to-disk mechanism.  It can be written a string
 representing a non-negative integer that will be used as an upper
--- linux-2.6.orig/Documentation/power/states.txt	2007-03-21 15:45:17.993148946 +0100
+++ linux-2.6/Documentation/power/states.txt	2007-03-21 15:51:18.763148946 +0100
@@ -62,17 +62,18 @@ setup via another operating system for i
 inconvenience, this method requires minimal work by the kernel, since
 the firmware will also handle restoring memory contents on resume. 
 
-If the kernel is responsible for persistently saving state, a mechanism
-called 'swsusp' (Swap Suspend) is used to write memory contents to
-free swap space. swsusp has some restrictive requirements, but should
-work in most cases. Some, albeit outdated, documentation can be found
-in Documentation/power/swsusp.txt. 
+For suspend-to-disk, a mechanism called swsusp called 'swsusp' (Swap
+Suspend) is used to write memory contents to free swap space.
+swsusp has some restrictive requirements, but should work in most
+cases. Some, albeit outdated, documentation can be found in
+Documentation/power/swsusp.txt. Alternatively, userspace can do most
+of the actual suspend to disk work, see userland-swsusp.txt.
 
 Once memory state is written to disk, the system may either enter a
 low-power state (like ACPI S4), or it may simply power down. Powering
 down offers greater savings, and allows this mechanism to work on any
 system. However, entering a real low-power state allows the user to
-trigger wake up events (e.g. pressing a key or opening a laptop lid). 
+trigger wake up events (e.g. pressing a key or opening a laptop lid).
 
 A transition from Suspend-to-Disk to the On state should take about 30
 seconds, though it's typically a bit more with the current
--- linux-2.6.orig/Documentation/power/swsusp.txt	2007-03-21 15:45:18.133148946 +0100
+++ linux-2.6/Documentation/power/swsusp.txt	2007-03-21 15:52:20.423148946 +0100
@@ -156,8 +156,7 @@ instead set the PF_NOFREEZE process flag
 be very careful).
 
 
-Q: What is the difference between "platform", "shutdown" and
-"firmware" in /sys/power/disk?
+Q: What is the difference between "platform" and "shutdown"?
 
 A:
 
@@ -166,11 +165,8 @@ shutdown: save state in linux, then tell
 platform: save state in linux, then tell bios to powerdown and blink
           "suspended led"
 
-firmware: tell bios to save state itself [needs BIOS-specific suspend
-	  partition, and has very little to do with swsusp]
-
-"platform" is actually right thing to do, but "shutdown" is most
-reliable.
+"platform" is actually right thing to do where supported, but
+"shutdown" is most reliable (except on ACPI systems).
 
 Q: I do not understand why you have such strong objections to idea of
 selective suspend.
@@ -388,8 +384,8 @@ while the system is asleep, maintaining 
 modes like "suspend-to-RAM" or "standby".  (Don't write "disk" to the
 /sys/power/state file; write "standby" or "mem".)  We've not seen any
 hardware that can use these modes through software suspend, although in
-theory some systems might support "platform" or "firmware" modes that
-won't break the USB connections.
+theory some systems might support "platform" modes that won't break the
+USB connections.
 
 Remember that it's always a bad idea to unplug a disk drive containing a
 mounted filesystem.  That's true even when your system is asleep!  The

--

linux-2.6-fix-pmops-3.patch:

--- NEW FILE linux-2.6-fix-pmops-3.patch ---
>From johannes at sipsolutions.net Wed Mar 21 15:56:31 2007
Date: Wed, 21 Mar 2007 15:56:31 +0100
From: Johannes Berg <johannes at sipsolutions.net>
To: Andrew Morton <akpm at linux-foundation.org>
Cc: linux-pm at lists.linux-foundation.org, David Brownell <david-b at pacbell.net>, Pavel Machek <pavel at ucw.cz>
Subject: [PATCH 3/3] power management: implement pm_ops.valid for everybody

Almost all users of pm_ops only support mem sleep, don't check in .valid
and don't reject any others in .prepare so users can be confused if they
check /sys/power/state, especially when new states are added (these would
then result in s-t-r although they're supposed to be something different).

This patch implements a generic pm_valid_only_mem function that is then
exported for users and puts it to use in almost all existing pm_ops.

Signed-off-by: Johannes Berg <johannes at sipsolutions.net>
Cc: David Brownell <david-b at pacbell.net>
Cc: Pavel Machek <pavel at ucw.cz>
Cc: linux-pm at lists.linux-foundation.org

---
 arch/arm/common/sharpsl_pm.c |    1 +
 arch/arm/mach-omap1/pm.c     |    1 +
 arch/arm/mach-omap2/pm.c     |    1 +
 arch/arm/mach-pnx4008/pm.c   |   35 +----------------------------------
 arch/arm/mach-pxa/pm.c       |    1 +
 arch/arm/mach-sa1100/pm.c    |    1 +
 arch/arm/plat-s3c24xx/pm.c   |   19 +------------------
 arch/sh/boards/hp6xx/pm.c    |    1 +
 drivers/acpi/sleep/main.c    |   13 +++++++++++--
 include/linux/pm.h           |    4 ++++
 kernel/power/main.c          |   13 +++++++++++++
 11 files changed, 36 insertions(+), 54 deletions(-)

--- linux-2.6.orig/include/linux/pm.h	2007-03-20 12:42:04.813214909 +0100
+++ linux-2.6/include/linux/pm.h	2007-03-20 12:42:05.693214909 +0100
@@ -128,6 +128,9 @@ typedef int __bitwise suspend_disk_metho
  *	always valid and never passed to this call.
  *	If not assigned, all suspend states are advertised as valid
  *	in /sys/power/state (but can still be rejected by prepare or enter.)
+ *	Since new states can be added for other platforms, you should
+ *	assign this callback. There is a %pm_valid_only_mem function
+ *	available if you only implemented mem sleep.
  *
  * @prepare: Prepare the platform for the given suspend state. Can return a
  *	negative error code if necessary.
@@ -165,6 +168,7 @@ extern void pm_set_ops(struct pm_ops *pm
 extern struct pm_ops *pm_ops;
 extern int pm_suspend(suspend_state_t state);
 
+extern int pm_valid_only_mem(suspend_state_t state);
 
 /*
  * Device power management
--- linux-2.6.orig/arch/arm/common/sharpsl_pm.c	2007-03-20 12:42:02.263214909 +0100
+++ linux-2.6/arch/arm/common/sharpsl_pm.c	2007-03-20 12:42:05.693214909 +0100
@@ -769,6 +769,7 @@ static struct pm_ops sharpsl_pm_ops = {
 	.prepare	= pxa_pm_prepare,
 	.enter		= corgi_pxa_pm_enter,
 	.finish		= pxa_pm_finish,
+	.valid		= pm_valid_only_mem,
 };
 
 static int __init sharpsl_pm_probe(struct platform_device *pdev)
--- linux-2.6.orig/arch/arm/mach-omap1/pm.c	2007-03-20 12:42:02.263214909 +0100
+++ linux-2.6/arch/arm/mach-omap1/pm.c	2007-03-20 12:42:05.703214909 +0100
@@ -701,6 +701,7 @@ static struct pm_ops omap_pm_ops ={
 	.prepare	= omap_pm_prepare,
 	.enter		= omap_pm_enter,
 	.finish		= omap_pm_finish,
+	.valid		= pm_valid_only_mem,
 };
 
 static int __init omap_pm_init(void)
--- linux-2.6.orig/arch/arm/mach-omap2/pm.c	2007-03-20 12:42:02.263214909 +0100
+++ linux-2.6/arch/arm/mach-omap2/pm.c	2007-03-20 12:42:05.703214909 +0100
@@ -373,6 +373,7 @@ static struct pm_ops omap_pm_ops = {
 	.prepare	= omap2_pm_prepare,
 	.enter		= omap2_pm_enter,
 	.finish		= omap2_pm_finish,
+	.valid		= pm_valid_only_mem,
 };
 
 int __init omap2_pm_init(void)
--- linux-2.6.orig/arch/arm/mach-pnx4008/pm.c	2007-03-20 12:41:36.133214909 +0100
+++ linux-2.6/arch/arm/mach-pnx4008/pm.c	2007-03-20 12:42:05.703214909 +0100
@@ -115,42 +115,9 @@ static int pnx4008_pm_enter(suspend_stat
 	return 0;
 }
 
-/*
- * Called after processes are frozen, but before we shut down devices.
- */
-static int pnx4008_pm_prepare(suspend_state_t state)
-{
-	switch (state) {
-	case PM_SUSPEND_STANDBY:
-	case PM_SUSPEND_MEM:
-		break;
-
-	case PM_SUSPEND_DISK:
-		return -ENOTSUPP;
-		break;
-
-	default:
-		return -EINVAL;
-		break;
-	}
-	return 0;
-}
-
-/*
- * Called after devices are re-setup, but before processes are thawed.
- */
-static int pnx4008_pm_finish(suspend_state_t state)
-{
-	return 0;
-}
-
-/*
- * Set to PM_DISK_FIRMWARE so we can quickly veto suspend-to-disk.
- */
 static struct pm_ops pnx4008_pm_ops = {
-	.prepare = pnx4008_pm_prepare,
 	.enter = pnx4008_pm_enter,
-	.finish = pnx4008_pm_finish,
+	.valid = pm_valid_only_mem,
 };
 
 static int __init pnx4008_pm_init(void)
--- linux-2.6.orig/arch/arm/mach-pxa/pm.c	2007-03-20 12:42:02.263214909 +0100
+++ linux-2.6/arch/arm/mach-pxa/pm.c	2007-03-20 12:42:05.703214909 +0100
@@ -227,6 +227,7 @@ static struct pm_ops pxa_pm_ops = {
 	.prepare	= pxa_pm_prepare,
 	.enter		= pxa_pm_enter,
 	.finish		= pxa_pm_finish,
+	.valid		= pm_valid_only_mem,
 };
 
 static int __init pxa_pm_init(void)
--- linux-2.6.orig/arch/arm/mach-sa1100/pm.c	2007-03-20 12:42:02.273214909 +0100
+++ linux-2.6/arch/arm/mach-sa1100/pm.c	2007-03-20 12:42:05.703214909 +0100
@@ -133,6 +133,7 @@ unsigned long sleep_phys_sp(void *sp)
 
 static struct pm_ops sa11x0_pm_ops = {
 	.enter		= sa11x0_pm_enter,
+	.valid		= pm_valid_only_mem,
 };
 
 static int __init sa11x0_pm_init(void)
--- linux-2.6.orig/arch/arm/plat-s3c24xx/pm.c	2007-03-20 12:42:02.273214909 +0100
+++ linux-2.6/arch/arm/plat-s3c24xx/pm.c	2007-03-20 12:42:05.703214909 +0100
@@ -612,26 +612,9 @@ static int s3c2410_pm_enter(suspend_stat
 	return 0;
 }
 
-/*
- * Called after processes are frozen, but before we shut down devices.
- */
-static int s3c2410_pm_prepare(suspend_state_t state)
-{
-	return 0;
-}
-
-/*
- * Called after devices are re-setup, but before processes are thawed.
- */
-static int s3c2410_pm_finish(suspend_state_t state)
-{
-	return 0;
-}
-
 static struct pm_ops s3c2410_pm_ops = {
-	.prepare	= s3c2410_pm_prepare,
 	.enter		= s3c2410_pm_enter,
-	.finish		= s3c2410_pm_finish,
+	.valid		= pm_valid_only_mem,
 };
 
 /* s3c2410_pm_init
--- linux-2.6.orig/arch/sh/boards/hp6xx/pm.c	2007-03-20 12:42:02.273214909 +0100
+++ linux-2.6/arch/sh/boards/hp6xx/pm.c	2007-03-20 12:42:05.713214909 +0100
@@ -69,6 +69,7 @@ static int hp6x0_pm_enter(suspend_state_
 
 static struct pm_ops hp6x0_pm_ops = {
 	.enter		= hp6x0_pm_enter,
+	.valid		= pm_valid_only_mem,
 };
 
 static int __init hp6x0_pm_init(void)
--- linux-2.6.orig/drivers/acpi/sleep/main.c	2007-03-20 12:41:36.863214909 +0100
+++ linux-2.6/drivers/acpi/sleep/main.c	2007-03-20 12:42:05.713214909 +0100
@@ -168,9 +168,18 @@ int acpi_suspend(u32 acpi_state)
 
 static int acpi_pm_state_valid(suspend_state_t pm_state)
 {
-	u32 acpi_state = acpi_suspend_states[pm_state];
+	u32 acpi_state;
 
-	return sleep_states[acpi_state];
+	switch (pm_state) {
+	case PM_SUSPEND_ON:
+	case PM_SUSPEND_STANDBY:
+	case PM_SUSPEND_MEM:
+		acpi_state = acpi_suspend_states[pm_state];
+
+		return sleep_states[acpi_state];
+	default:
+		return 0;
+	}
 }
 
 static struct pm_ops acpi_pm_ops = {
--- linux-2.6.orig/kernel/power/main.c	2007-03-20 12:42:02.263214909 +0100
+++ linux-2.6/kernel/power/main.c	2007-03-20 12:42:05.713214909 +0100
@@ -48,6 +48,19 @@ void pm_set_ops(struct pm_ops * ops)
 	mutex_unlock(&pm_mutex);
 }
 
+/**
+ * pm_valid_only_mem - generic memory-only valid callback
+ *
+ * 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 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)

--

linux-2.6-fix-pmops-4.patch:

--- NEW FILE linux-2.6-fix-pmops-4.patch ---
---
 include/linux/pm.h  |   10 ++++++++++
 kernel/power/main.c |   10 ++++++++--
 2 files changed, 18 insertions(+), 2 deletions(-)

--- wireless-dev.orig/include/linux/pm.h	2007-04-05 18:14:07.948549941 +0200
+++ wireless-dev/include/linux/pm.h	2007-04-05 18:14:13.568549941 +0200
@@ -131,9 +131,17 @@ typedef int __bitwise suspend_disk_metho
  * @prepare: Prepare the platform for the given suspend state. Can return a
  *	negative error code if necessary.
  *
+ * @irq_off: If assigned, the generic suspend code does not turn off IRQs
+ *	but relies on this callback instead. It is currently not called for
+ *	%PM_SUSPEND_DISK.
+ *
  * @enter: Enter the given suspend state, must be assigned. Can return a
  *	negative error code if necessary.
  *
+ * @irq_on: If assigned, the generic suspend code does not turn on IRQs
+ *	but relies on this callback instead. it is currently not called for
+ *	%PM_SUSPEND_DISK.
+ *
  * @finish: Called when the system has left the given state and all devices
  *	are resumed. The return value is ignored.
  *
@@ -152,7 +160,9 @@ typedef int __bitwise suspend_disk_metho
 struct pm_ops {
 	int (*valid)(suspend_state_t state);
 	int (*prepare)(suspend_state_t state);
+	void (*irq_off)(suspend_state_t state);
 	int (*enter)(suspend_state_t state);
+	void (*irq_on)(suspend_state_t state);
 	int (*finish)(suspend_state_t state);
 	suspend_disk_method_t pm_disk_mode;
 };
--- wireless-dev.orig/kernel/power/main.c	2007-04-05 18:14:07.988549941 +0200
+++ wireless-dev/kernel/power/main.c	2007-04-05 18:25:21.108549941 +0200
@@ -117,7 +117,10 @@ int suspend_enter(suspend_state_t state)
 	int error = 0;
 	unsigned long flags;
 
-	local_irq_save(flags);
+	if (pm_ops->irq_off)
+		pm_ops->irq_off(state);
+	else
+		local_irq_save(flags);
 
 	if ((error = device_power_down(PMSG_SUSPEND))) {
 		printk(KERN_ERR "Some devices failed to power down\n");
@@ -126,7 +129,10 @@ int suspend_enter(suspend_state_t state)
 	error = pm_ops->enter(state);
 	device_power_up();
  Done:
-	local_irq_restore(flags);
+	if (pm_ops->irq_on)
+		pm_ops->irq_on(state);
+	else
+		local_irq_restore(flags);
 	return error;
 }
 

linux-2.6-gfs-locking-exports.patch:

--- NEW FILE linux-2.6-gfs-locking-exports.patch ---
Please add the following patch to the Fedora kernel (F-7, FC-6 & devel).
This was originally in the FC-6 kernel but seems to have vanished. This
patch isn't going to get sent upstream for various reasons but we need
it in Fedora so that the GFS kernel stuff will build against the GFS2
lock modules.

Steve.

-----------------------------------------------------------------------------
--- linux-2.6.17.noarch/fs/gfs2/locking.c~	2006-08-10 13:33:09.000000000 -0400
+++ linux-2.6.17.noarch/fs/gfs2/locking.c	2006-08-10 13:33:23.000000000 -0400
@@ -188,4 +188,6 @@ void __init gfs2_init_lmh(void)
 
 EXPORT_SYMBOL_GPL(gfs2_register_lockproto);
 EXPORT_SYMBOL_GPL(gfs2_unregister_lockproto);
-
+EXPORT_SYMBOL_GPL(gfs2_withdraw_lockproto);
+EXPORT_SYMBOL_GPL(gfs2_mount_lockproto);
+EXPORT_SYMBOL_GPL(gfs2_unmount_lockproto);



linux-2.6-highres-timers.patch:

--- NEW FILE linux-2.6-highres-timers.patch ---
Index: linux-2.6.23/include/linux/clockchips.h
===================================================================
--- linux-2.6.23.orig/include/linux/clockchips.h	2007-10-10 09:43:06.000000000 +0200
+++ linux-2.6.23/include/linux/clockchips.h	2007-10-10 09:43:06.000000000 +0200
@@ -8,7 +8,7 @@
 #ifndef _LINUX_CLOCKCHIPS_H
 #define _LINUX_CLOCKCHIPS_H
 
-#ifdef CONFIG_GENERIC_CLOCKEVENTS
+#ifdef CONFIG_GENERIC_CLOCKEVENTS_BUILD
 
 #include <linux/clocksource.h>
 #include <linux/cpumask.h>
@@ -126,11 +126,14 @@ extern int clockevents_register_notifier
 extern int clockevents_program_event(struct clock_event_device *dev,
 				     ktime_t expires, ktime_t now);
 
+#ifdef CONFIG_GENERIC_CLOCKEVENTS
 extern void clockevents_notify(unsigned long reason, void *arg);
-
 #else
+# define clockevents_notify(reason, arg) do { } while (0)
+#endif
+
+#else /* CONFIG_GENERIC_CLOCKEVENTS_BUILD */
 
-static inline void clockevents_resume_events(void) { }
 #define clockevents_notify(reason, arg) do { } while (0)
 
 #endif
Index: linux-2.6.23/kernel/time/Kconfig
===================================================================
--- linux-2.6.23.orig/kernel/time/Kconfig	2007-10-10 09:43:06.000000000 +0200
+++ linux-2.6.23/kernel/time/Kconfig	2007-10-10 09:43:06.000000000 +0200
@@ -23,3 +23,8 @@ config HIGH_RES_TIMERS
 	  hardware is not capable then this option only increases
 	  the size of the kernel image.
 
+config GENERIC_CLOCKEVENTS_BUILD
+	bool
+	default y
+	depends on GENERIC_CLOCKEVENTS || GENERIC_CLOCKEVENTS_MIGR
+
Index: linux-2.6.23/kernel/time/Makefile
===================================================================
--- linux-2.6.23.orig/kernel/time/Makefile	2007-10-10 09:43:06.000000000 +0200
+++ linux-2.6.23/kernel/time/Makefile	2007-10-10 09:43:06.000000000 +0200
@@ -1,6 +1,6 @@
 obj-y += timekeeping.o ntp.o clocksource.o jiffies.o timer_list.o
 
-obj-$(CONFIG_GENERIC_CLOCKEVENTS)		+= clockevents.o
+obj-$(CONFIG_GENERIC_CLOCKEVENTS_BUILD)		+= clockevents.o
 obj-$(CONFIG_GENERIC_CLOCKEVENTS)		+= tick-common.o
 obj-$(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)	+= tick-broadcast.o
 obj-$(CONFIG_TICK_ONESHOT)			+= tick-oneshot.o
Index: linux-2.6.23/kernel/time/clockevents.c
===================================================================
--- linux-2.6.23.orig/kernel/time/clockevents.c	2007-10-10 09:43:06.000000000 +0200
+++ linux-2.6.23/kernel/time/clockevents.c	2007-10-10 09:43:06.000000000 +0200
@@ -194,6 +194,7 @@ void clockevents_exchange_device(struct 
 	local_irq_restore(flags);
 }
 
+#ifdef CONFIG_GENERIC_CLOCKEVENTS
 /**
  * clockevents_notify - notification about relevant events
  */
@@ -222,4 +223,4 @@ void clockevents_notify(unsigned long re
 	spin_unlock(&clockevents_lock);
 }
 EXPORT_SYMBOL_GPL(clockevents_notify);
-
+#endif
Index: linux-2.6.23/kernel/time/tick-broadcast.c
===================================================================
--- linux-2.6.23.orig/kernel/time/tick-broadcast.c	2007-10-10 09:43:06.000000000 +0200
+++ linux-2.6.23/kernel/time/tick-broadcast.c	2007-10-10 09:43:09.000000000 +0200
@@ -64,8 +64,9 @@ static void tick_broadcast_start_periodi
  */
 int tick_check_broadcast_device(struct clock_event_device *dev)
 {
-	if (tick_broadcast_device.evtdev ||
-	    (dev->features & CLOCK_EVT_FEAT_C3STOP))
+	if ((tick_broadcast_device.evtdev &&
+	     tick_broadcast_device.evtdev->rating >= dev->rating) ||
+	     (dev->features & CLOCK_EVT_FEAT_C3STOP))
 		return 0;
 
 	clockevents_exchange_device(NULL, dev);
@@ -176,8 +177,6 @@ static void tick_do_periodic_broadcast(v
  */
 static void tick_handle_periodic_broadcast(struct clock_event_device *dev)
 {
-	dev->next_event.tv64 = KTIME_MAX;
-
 	tick_do_periodic_broadcast();
 
 	/*
@@ -515,11 +514,9 @@ static void tick_broadcast_clear_oneshot
  */
 void tick_broadcast_setup_oneshot(struct clock_event_device *bc)
 {
-	if (bc->mode != CLOCK_EVT_MODE_ONESHOT) {
-		bc->event_handler = tick_handle_oneshot_broadcast;
-		clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT);
-		bc->next_event.tv64 = KTIME_MAX;
-	}
+	bc->event_handler = tick_handle_oneshot_broadcast;
+	clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT);
+	bc->next_event.tv64 = KTIME_MAX;
 }
 
 /*
Index: linux-2.6.23/Documentation/00-INDEX
===================================================================
--- linux-2.6.23.orig/Documentation/00-INDEX	2007-10-10 09:43:06.000000000 +0200
+++ linux-2.6.23/Documentation/00-INDEX	2007-10-10 09:43:06.000000000 +0200
@@ -62,6 +62,8 @@ VGA-softcursor.txt
 	- how to change your VGA cursor from a blinking underscore.
 accounting/
 	- documentation on accounting and taskstats.
+acpi
+	- general ACPI information
 aoe/
 	- description of AoE (ATA over Ethernet) along with config examples.
 applying-patches.txt
Index: linux-2.6.23/Documentation/acpi/00-INDEX
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.23/Documentation/acpi/00-INDEX	2007-10-10 09:43:06.000000000 +0200
@@ -0,0 +1,6 @@
+00-INDEX
+	- this file
+README.ACPI
+	- where to start
+acpi_debugging.txt
+	- How to debug ACPI problems
Index: linux-2.6.23/Documentation/acpi/README.ACPI
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.23/Documentation/acpi/README.ACPI	2007-10-10 09:43:06.000000000 +0200
@@ -0,0 +1,377 @@
+Developing ACPI for Linux - July 13, 2007
+------------------------------------------
+Len Brown <lenb at kernel.org> (Intel Open Source Technology Center)
+
+This is how you can be most effective improving Linux ACPI support.
+
+Latest version of this file
+---------------------------
+http://ftp.kernel.org/pub/linux/kernel/people/lenb/acpi/patches/README.ACPI
+
+Linux/ACPI home page
+--------------------
+http://acpi.sourceforge.net/
+
+Mailing Lists
+-------------
+Inventory of lists: http://acpi.sourceforge.net/mailinglists.html
+
+The main list is linux-acpi at vger.kernel.org.
+Subscribe here: http://vger.kernel.org/vger-lists.html#linux-acpi
+Note this list server has a 100KB message limit size.
+If you need to post something big, attaching it to a bugzilla entry
+(below) is usually the way to go.
+
+Which e-mail address to use?
+----------------------------
+For issues, discussion, RFC's, debugging etc:
+To: linux-acpi at vger.kernel.org
+
+To request an ACPI patch be applied to Linux:
+To: lenb at kernel.org
+Cc: linux-acpi at vger.kernel.org
+
+Feedback to (only) Intel on Intel's ACPICA,
+or ACPI-related issues with NDA pre-production systems:
+To: acpi at linux.intel.com
+
+Len Brown is on both of these lists, and he also sees traffic to
+LKML, cpufreq, pci, and ia64 lists when the word ACPI appears in it.
+
+Note that Len signs-off using "len.brown at intel.com" to make it clear
+that he is employed by Intel.  While that address is functional,
+lenb at kernel.org is preferred for all public Linux work.
+
+asus_acpi or asus-laptop specific e-mail:
+to: acpi4asus-user at lists.sourceforge.net
+
+ibm_acpi specific e-mail:
+ibm-acpi-devel at lists.sourceforge.net
+
+Bugzilla
+--------
+The Linux/ACPI community makes active use of bugzilla.
+http://bugzilla.kernel.org/enter_bug.cgi?product=ACPI
+Note that this database is for kernel.org kernels only.
+
+If an issue is specific to a distribution, it should
[...6087 lines suppressed...]
+		printk(KERN_DEBUG "Failed to force enable HPET\n");
+	} else {
+		force_hpet_resume_type = ICH_FORCE_HPET_RESUME;
+		printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n",
+			       force_hpet_address);
+	}
+}
+
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_0,
+                         ich_force_enable_hpet);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1,
+                         ich_force_enable_hpet);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0,
+                         ich_force_enable_hpet);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1,
+                         ich_force_enable_hpet);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_31,
+                         ich_force_enable_hpet);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_1,
+                         ich_force_enable_hpet);
+
+
+static struct pci_dev *cached_dev;
+
+static void old_ich_force_hpet_resume(void)
+{
+	u32 val;
+	u32 uninitialized_var(gen_cntl);
+
+	if (!force_hpet_address || !cached_dev)
+		return;
+
+	pci_read_config_dword(cached_dev, 0xD0, &gen_cntl);
+	gen_cntl &= (~(0x7 << 15));
+	gen_cntl |= (0x4 << 15);
+
+	pci_write_config_dword(cached_dev, 0xD0, gen_cntl);
+	pci_read_config_dword(cached_dev, 0xD0, &gen_cntl);
+	val = gen_cntl >> 15;
+	val &= 0x7;
+	if (val == 0x4)
+		printk(KERN_DEBUG "Force enabled HPET at resume\n");
+	else
+		BUG();
+}
+
+static void old_ich_force_enable_hpet(struct pci_dev *dev)
+{
+	u32 val;
+	u32 uninitialized_var(gen_cntl);
+
+	if (hpet_address || force_hpet_address)
+		return;
+
+	pci_read_config_dword(dev, 0xD0, &gen_cntl);
+	/*
+	 * Bit 17 is HPET enable bit.
+	 * Bit 16:15 control the HPET base address.
+	 */
+	val = gen_cntl >> 15;
+	val &= 0x7;
+	if (val & 0x4) {
+		val &= 0x3;
+		force_hpet_address = 0xFED00000 | (val << 12);
+		printk(KERN_DEBUG "HPET at base address 0x%lx\n",
+			       force_hpet_address);
+		return;
+	}
+
+	/*
+	 * HPET is disabled. Trying enabling at FED00000 and check
+	 * whether it sticks
+	 */
+	gen_cntl &= (~(0x7 << 15));
+	gen_cntl |= (0x4 << 15);
+	pci_write_config_dword(dev, 0xD0, gen_cntl);
+
+	pci_read_config_dword(dev, 0xD0, &gen_cntl);
+
+	val = gen_cntl >> 15;
+	val &= 0x7;
+	if (val & 0x4) {
+		/* HPET is enabled in HPTC. Just not reported by BIOS */
+		val &= 0x3;
+		force_hpet_address = 0xFED00000 | (val << 12);
+		printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n",
+			       force_hpet_address);
+		cached_dev = dev;
+		force_hpet_resume_type = OLD_ICH_FORCE_HPET_RESUME;
+		return;
+	}
+
+	printk(KERN_DEBUG "Failed to force enable HPET\n");
+}
+
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0,
+                         old_ich_force_enable_hpet);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12,
+                         old_ich_force_enable_hpet);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0,
+                         old_ich_force_enable_hpet);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12,
+                         old_ich_force_enable_hpet);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0,
+                         old_ich_force_enable_hpet);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_12,
+                         old_ich_force_enable_hpet);
+
+
+static void vt8237_force_hpet_resume(void)
+{
+	u32 val;
+
+	if (!force_hpet_address || !cached_dev)
+		return;
+
+	val = 0xfed00000 | 0x80;
+	pci_write_config_dword(cached_dev, 0x68, val);
+
+	pci_read_config_dword(cached_dev, 0x68, &val);
+	if (val & 0x80)
+		printk(KERN_DEBUG "Force enabled HPET at resume\n");
+	else
+		BUG();
+}
+
+static void vt8237_force_enable_hpet(struct pci_dev *dev)
+{
+	u32 val;
+
+	if (hpet_address || force_hpet_address)
+		return;
+
+	pci_read_config_dword(dev, 0x68, &val);
+	/*
+	 * Bit 7 is HPET enable bit.
+	 * Bit 31:10 is HPET base address (contrary to what datasheet claims)
+	 */
+	if (val & 0x80) {
+		force_hpet_address = (val & ~0x3ff);
+		printk(KERN_DEBUG "HPET at base address 0x%lx\n",
+			       force_hpet_address);
+		return;
+	}
+
+	/*
+	 * HPET is disabled. Trying enabling at FED00000 and check
+	 * whether it sticks
+	 */
+	val = 0xfed00000 | 0x80;
+	pci_write_config_dword(dev, 0x68, val);
+
+	pci_read_config_dword(dev, 0x68, &val);
+	if (val & 0x80) {
+		force_hpet_address = (val & ~0x3ff);
+		printk(KERN_DEBUG "Force enabled HPET at base address 0x%lx\n",
+			       force_hpet_address);
+		cached_dev = dev;
+		force_hpet_resume_type = VT8237_FORCE_HPET_RESUME;
+		return;
+	}
+
+	printk(KERN_DEBUG "Failed to force enable HPET\n");
+}
+
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235,
+			 vt8237_force_enable_hpet);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237,
+			 vt8237_force_enable_hpet);
+
+void force_hpet_resume(void)
+{
+	switch (force_hpet_resume_type) {
+	    case ICH_FORCE_HPET_RESUME:
+		return ich_force_hpet_resume();
+
+	    case OLD_ICH_FORCE_HPET_RESUME:
+		return old_ich_force_hpet_resume();
+
+	    case VT8237_FORCE_HPET_RESUME:
+		return vt8237_force_hpet_resume();
+
+	    default:
+		break;
+	}
+}
+
+#endif
Index: linux-2.6.23/include/linux/pci_ids.h
===================================================================
--- linux-2.6.23.orig/include/linux/pci_ids.h	2007-10-10 09:43:03.000000000 +0200
+++ linux-2.6.23/include/linux/pci_ids.h	2007-10-10 09:43:09.000000000 +0200
@@ -2221,6 +2221,7 @@
 #define PCI_DEVICE_ID_INTEL_82801EB_5	0x24d5
 #define PCI_DEVICE_ID_INTEL_82801EB_6	0x24d6
 #define PCI_DEVICE_ID_INTEL_82801EB_11	0x24db
+#define PCI_DEVICE_ID_INTEL_82801EB_12	0x24dc
 #define PCI_DEVICE_ID_INTEL_82801EB_13	0x24dd
 #define PCI_DEVICE_ID_INTEL_ESB_1	0x25a1
 #define PCI_DEVICE_ID_INTEL_ESB_2	0x25a2

linux-2.6-i386-vdso-install-unstripped-copies-on-disk.patch:

--- NEW FILE linux-2.6-i386-vdso-install-unstripped-copies-on-disk.patch ---
From: Roland McGrath <roland at redhat.com>

This keeps an unstripped copy of the vDSO images built before they are
stripped and embedded in the kernel.  The unstripped copies get installed in
$(MODLIB)/vdso/ by "make install".  These files can be useful when they
contain source-level debugging information.

Signed-off-by: Roland McGrath <roland at redhat.com>
Cc: Sam Ravnborg <sam at ravnborg.org>
Cc: Andi Kleen <ak at suse.de>
Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
---

 arch/i386/Makefile        |    1 +
 arch/i386/kernel/Makefile |   27 ++++++++++++++++++++++-----
 2 files changed, 23 insertions(+), 5 deletions(-)

diff -puN arch/i386/Makefile~i386-vdso-install-unstripped-copies-on-disk arch/i386/Makefile
--- a/arch/i386/Makefile~i386-vdso-install-unstripped-copies-on-disk
+++ a/arch/i386/Makefile
@@ -141,9 +141,12 @@ zdisk bzdisk: vmlinux
 fdimage fdimage144 fdimage288 isoimage: vmlinux
 	$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) $@
 
-install:
+install: vdso_install
 	$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) install
 
+vdso_install:
+	$(Q)$(MAKE) $(build)=arch/x86/kernel vdso_install
+
 archclean:
 	$(Q)$(MAKE) $(clean)=arch/x86/boot
 
diff -puN arch/x86/kernel/Makefile~i386-vdso-install-unstripped-copies-on-disk arch/x86/kernel/Makefile
--- a/arch/x86/kernel/Makefile_32~i386-vdso-install-unstripped-copies-on-disk
+++ a/arch/x86/kernel/Makefile_32
@@ -52,7 +52,8 @@ obj-$(CONFIG_SCx200)		+= scx200_32.o
 # We must build both images before we can assemble it.
 # Note: kbuild does not track this dependency due to usage of .incbin
 $(obj)/vsyscall_32.o: $(obj)/vsyscall-int80_32.so $(obj)/vsyscall-sysenter_32.so
-targets += $(foreach F,int80 sysenter,vsyscall-$F.o vsyscall-$F.so)
+targets += $(foreach F,$(addprefix vsyscall-,int80 sysenter),\
+		     $F.o $F.so $F.so.dbg)
 targets += vsyscall-note_32.o vsyscall_32.lds
 
 # The DSO images are built using a special linker script.
@@ -62,16 +63,32 @@ quiet_cmd_syscall = SYSCALL $@
 
 export CPPFLAGS_vsyscall_32.lds += -P -C -U$(ARCH)
 
-vsyscall-flags = -shared -s -Wl,-soname=linux-gate.so.1 \
+vsyscall-flags = -shared -Wl,-soname=linux-gate.so.1 \
 		 $(call ld-option, -Wl$(comma)--hash-style=sysv)
-SYSCFLAGS_vsyscall-sysenter_32.so	= $(vsyscall-flags)
-SYSCFLAGS_vsyscall-int80_32.so	= $(vsyscall-flags)
+SYSCFLAGS_vsyscall-sysenter.so.dbg	= $(vsyscall-flags)
+SYSCFLAGS_vsyscall-int80.so.dbg		= $(vsyscall-flags)
 
-$(obj)/vsyscall-int80_32.so $(obj)/vsyscall-sysenter_32.so: \
-$(obj)/vsyscall-%.so: $(src)/vsyscall_32.lds \
-		      $(obj)/vsyscall-%.o $(obj)/vsyscall-note_32.o FORCE
+$(obj)/vsyscall-int80.so.dbg $(obj)/vsyscall-sysenter.so.dbg: \
+$(obj)/vsyscall-%.so.dbg: $(src)/vsyscall.lds \
+		      $(obj)/vsyscall-%.o $(obj)/vsyscall-note_32.o FORCE
 	$(call if_changed,syscall)
 
+$(obj)/%.so: OBJCOPYFLAGS := -S
+$(obj)/%.so: $(obj)/%.so.dbg FORCE
+	$(call if_changed,objcopy)
+
+vdsos := vdso-int80.so vdso-sysenter.so
+
+quiet_cmd_vdso_install = INSTALL $@
+      cmd_vdso_install = cp $(@:vdso-%.so=$(obj)/vsyscall-%.so.dbg) \
+			    $(MODLIB)/vdso/$@
+
+$(vdsos):
+	@mkdir -p $(MODLIB)/vdso
+	$(call cmd,vdso_install)
+
+vdso_install: $(vdsos)
+
 # We also create a special relocatable object that should mirror the symbol
 # table and layout of the linked DSO.  With ld -R we can then refer to
 # these symbols in the kernel code rather than hand-coded addresses.

linux-2.6-i82875-edac-pci-setup.patch:

--- NEW FILE linux-2.6-i82875-edac-pci-setup.patch ---
From: John Feeney <jfeeney at redhat.com>
Subject: [PATCH RHEL-5] BZ219288 /proc/bus/pci/devices speaks LIES
Date: Mon, 08 Jan 2007 15:52:30 -0500
Bugzilla: 219288
Message-Id: <45A2AF0E.5080901 at redhat.com>
Changelog: edac: fix /proc/bus/pci/devices to allow X to start


RHBZ#: 219288 /proc/bus/pci/devices speaks LIES
https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=219288

Description:
On specific Dell systems (e.g. PE 700), X fails to start with the following
errors in /var/log/Xorg.0.log:

(EE) No devices detected.

Fatal server error:
no screens found
XIO:  fatal IO error 104 (Connection reset by peer) on X server ":0.0"
    after 0 requests (0 known processed) with 0 events remaining.

After some investigation, by Ajax, it was determined that the
/proc/bus/pci/devices file and the /proc/bus/pci/* tree did not match,  
that is,
the devices file could list 15 devices while there would be 16 entries 
in the
tree. This discrepancy caused X to be unable to find its device, e.g. 
mach64.

Upon further review, it was determined that the device with the 8086:257e
pci id was missing from the devices file, hence the investigation lead to
drivers/edac/i82875p_edac.c where Dell determined that this driver was
adding an entry to the /proc tree with a call to pci_proc_attach_device()
but not to the global list of devices, the list that the devices file 
displays.

RHEL Version Found:
RHEL5-B2 (2.6.18-1.2767.el5)

The Proposed Fix:
The pci_bus_add_device function will replace pci_proc_attach_device()
because pci_bus_add_device() calls pci_proc_attach_device() while
populating the devices file as well.

In lieu of qualifying the call (with a "if(dev->procent==NULL)"), the
pci_bus_add_device() will be included in the if statement that detects a 
hidden
device. Thus, when the device previously hidden by BIOS is enabled and
detected, the /proc file system components will be fully implemented 
with the
pci_bus_add_device() call.

Note: In the drivers subdirectory, it appears as though i82875p_edac.c
is the only place outside of the pci directory where 
pci_proc_attach_device()
is called while pci_bus_add_device() is called by 17 other drivers. 
Perhaps,
this and the fact that pci_proc_attach_device() needed to be externed 
should
have been a red flag to the author of the original patch that added this
functionality.

Also note: even though the original code had pci_proc_attach_device() call
enveloped in "#ifdef CONFIG_PROC_FS", all other situations in drivers/*
where pci_bus_add_device() was called did not use this ifdef so it was not
carried forward.

Upstream Status:
It  does not  appear as though this fix is upstream at this point in
time. The offending function was added to 2.6.17-git17 in June of
2006. This patch will be submitted upstream.

--- linux-2.6.18.noarch/drivers/edac/i82875p_edac.c.dell
+++ linux-2.6.18.noarch/drivers/edac/i82875p_edac.c
@@ -261,10 +261,6 @@ static void i82875p_check(struct mem_ctl
 	i82875p_process_error_info(mci, &info, 1);
 }
 
-#ifdef CONFIG_PROC_FS
-extern int pci_proc_attach_device(struct pci_dev *);
-#endif
-
 /* Return 0 on success or 1 on failure. */
 static int i82875p_setup_overfl_dev(struct pci_dev *pdev,
 		struct pci_dev **ovrfl_pdev, void __iomem **ovrfl_window)
@@ -287,17 +283,12 @@ static int i82875p_setup_overfl_dev(stru
 
 		if (dev == NULL)
 			return 1;
+
+        	pci_bus_add_device(dev);
 	}
 
 	*ovrfl_pdev = dev;
 
-#ifdef CONFIG_PROC_FS
-	if ((dev->procent == NULL) && pci_proc_attach_device(dev)) {
-		i82875p_printk(KERN_ERR, "%s(): Failed to attach overflow "
-			       "device\n", __func__);
-		return 1;
-	}
-#endif  /* CONFIG_PROC_FS */
 	if (pci_enable_device(dev)) {
 		i82875p_printk(KERN_ERR, "%s(): Failed to enable overflow "
 			       "device\n", __func__);


linux-2.6-i965gm-support.patch:

--- NEW FILE linux-2.6-i965gm-support.patch ---
 
--- linux-2.6.20.noarch/drivers/char/drm/i915_dma.c.jx	2007-02-04 13:44:54.000000000 -0500
+++ linux-2.6.20.noarch/drivers/char/drm/i915_dma.c	2007-04-05 05:18:12.000000000 -0400
@@ -34,7 +34,8 @@
 #define IS_I965G(dev) (dev->pci_device == 0x2972 || \
 		       dev->pci_device == 0x2982 || \
 		       dev->pci_device == 0x2992 || \
-		       dev->pci_device == 0x29A2)
+		       dev->pci_device == 0x29A2 || \
+		       dev->pci_device == 0x2A02)
 
 /* Really want an OS-independent resettable timer.  Would like to have
  * this loop run for (eg) 3 sec, but have the timer reset every time
--- linux-2.6.20.noarch/drivers/char/drm/drm_pciids.h.jx	2007-04-05 05:18:10.000000000 -0400
+++ linux-2.6.20.noarch/drivers/char/drm/drm_pciids.h	2007-04-05 05:19:53.000000000 -0400
@@ -296,6 +296,7 @@
 	{0x8086, 0x2982, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
 	{0x8086, 0x2992, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
 	{0x8086, 0x29a2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
+	{0, 0, 0}
 
 #define nouveau_PCI_IDS \
 	{0x10de, 0x0008, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_03}, \

linux-2.6-iwlwifi-fixes.patch:

--- NEW FILE linux-2.6-iwlwifi-fixes.patch ---
diff -up linux-2.6.22.noarch/drivers/net/wireless/iwlwifi/iwl-4965-rs.c.orig linux-2.6.22.noarch/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
--- linux-2.6.22.noarch/drivers/net/wireless/iwlwifi/iwl-4965-rs.c.orig	2007-09-27 19:08:16.000000000 -0400
+++ linux-2.6.22.noarch/drivers/net/wireless/iwlwifi/iwl-4965-rs.c	2007-09-27 19:09:01.000000000 -0400
@@ -115,24 +115,38 @@ struct iwl_rate_scale_priv {
 	u8 is_dup;
 	u8 phymode;
 	u8 ibss_sta_added;
+	u32 supp_rates;
 	u16 active_rate;
 	u16 active_siso_rate;
 	u16 active_mimo_rate;
 	u16 active_rate_basic;
 	struct iwl_link_quality_cmd lq;
 	struct iwl_scale_tbl_info lq_info[LQ_SIZE];
+#ifdef CONFIG_MAC80211_DEBUGFS
+	struct dentry *rs_sta_dbgfs_scale_table_file;
+	struct dentry *rs_sta_dbgfs_stats_table_file;
+	struct iwl_rate dbg_fixed;
+	struct iwl_priv *drv;
+#endif
 };
 
 static void rs_rate_scale_perform(struct iwl_priv *priv,
 				   struct net_device *dev,
 				   struct ieee80211_hdr *hdr,
 				   struct sta_info *sta);
-static int rs_fill_link_cmd(struct iwl_rate_scale_priv *lq_data,
+static void rs_fill_link_cmd(struct iwl_rate_scale_priv *lq_data,
 			     struct iwl_rate *tx_mcs,
-			     struct iwl_link_quality_cmd *tbl,
-			     struct sta_info *sta);
+			     struct iwl_link_quality_cmd *tbl);
 
 
+#ifdef CONFIG_MAC80211_DEBUGFS
+static void rs_dbgfs_set_mcs(struct iwl_rate_scale_priv *rs_priv,
+				struct iwl_rate *mcs, int index);
+#else
+static void rs_dbgfs_set_mcs(struct iwl_rate_scale_priv *rs_priv,
+				struct iwl_rate *mcs, int index)
+{}
+#endif
 static s32 expected_tpt_A[IWL_RATE_COUNT] = {
 	0, 0, 0, 0, 40, 57, 72, 98, 121, 154, 177, 186, 186
 };
@@ -539,14 +553,13 @@ static u16 rs_get_adjacent_rate(u8 index
 
 static int rs_get_lower_rate(struct iwl_rate_scale_priv *lq_data,
 			     struct iwl_scale_tbl_info *tbl, u8 scale_index,
-			     u8 ht_possible, struct iwl_rate *mcs_rate,
-			     struct sta_info *sta)
+			     u8 ht_possible, struct iwl_rate *mcs_rate)
 {
-	u8 is_green = lq_data->is_green;
 	s32 low;
 	u16 rate_mask;
 	u16 high_low;
 	u8 switch_to_legacy = 0;
+	u8 is_green = lq_data->is_green;
 
 	/* check if we need to switch from HT to legacy rates.
 	 * assumption is that mandatory rates (1Mbps or 6Mbps)
@@ -573,9 +586,9 @@ static int rs_get_lower_rate(struct iwl_
 	if (is_legacy(tbl->lq_type)) {
 		if (lq_data->phymode == (u8) MODE_IEEE80211A)
 			rate_mask  = (u16)(rate_mask &
-			   (sta->supp_rates << IWL_FIRST_OFDM_RATE));
+			   (lq_data->supp_rates << IWL_FIRST_OFDM_RATE));
 		else
-			rate_mask = (u16)(rate_mask & sta->supp_rates);
+			rate_mask = (u16)(rate_mask & lq_data->supp_rates);
 	}
 
 	/* if we did switched from HT to legacy check current rate */
@@ -619,7 +632,7 @@ static void rs_tx_status(void *priv_rate
 	u16 fc = le16_to_cpu(hdr->frame_control);
 	s32 tpt = 0;
 
-	IWL_DEBUG_RATE("get frame ack response, update rate scale window\n");
+	IWL_DEBUG_RATE_LIMIT("get frame ack response, update rate scale window\n");
 
 	if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1))
 		return;
@@ -1388,10 +1401,10 @@ static void rs_rate_scale_perform(struct
 	if (is_legacy(tbl->lq_type)) {
 		if (lq_data->phymode == (u8) MODE_IEEE80211A)
 			rate_scale_index_msk = (u16) (rate_mask &
-				(sta->supp_rates << IWL_FIRST_OFDM_RATE));
+				(lq_data->supp_rates << IWL_FIRST_OFDM_RATE));
 		else
 			rate_scale_index_msk = (u16) (rate_mask &
-						      sta->supp_rates);
+						      lq_data->supp_rates);
 
 	} else
 		rate_scale_index_msk = rate_mask;
@@ -1431,7 +1444,7 @@ static void rs_rate_scale_perform(struct
 		rs_stay_in_table(lq_data);
 		if (update_lq) {
 			rs_mcs_from_tbl(&mcs_rate, tbl, index, is_green);
-			rs_fill_link_cmd(lq_data, &mcs_rate, &lq_data->lq, sta);
+			rs_fill_link_cmd(lq_data, &mcs_rate, &lq_data->lq);
 			rs_send_lq_cmd(priv, &lq_data->lq, CMD_ASYNC);
 		}
 		goto out;
@@ -1555,7 +1568,7 @@ static void rs_rate_scale_perform(struct
  lq_update:
 	if (update_lq) {
 		rs_mcs_from_tbl(&mcs_rate, tbl, index, is_green);
-		rs_fill_link_cmd(lq_data, &mcs_rate, &lq_data->lq, sta);
+		rs_fill_link_cmd(lq_data, &mcs_rate, &lq_data->lq);
 		rs_send_lq_cmd(priv, &lq_data->lq, CMD_ASYNC);
 	}
 	rs_stay_in_table(lq_data);
@@ -1581,7 +1594,7 @@ static void rs_rate_scale_perform(struct
 			IWL_DEBUG_HT("Switch current  mcs: %X index: %d\n",
 				     tbl->current_rate.rate_n_flags, index);
 			rs_fill_link_cmd(lq_data, &tbl->current_rate,
-					 &(lq_data->lq), sta);
+					 &lq_data->lq);
 			rs_send_lq_cmd(priv, &lq_data->lq, CMD_ASYNC);
 		}
 		tbl1 = &(lq_data->lq_info[lq_data->active_tbl]);
@@ -1672,12 +1685,12 @@ static void rs_initialize_lq(struct iwl_
 	tbl->antenna_type = ANT_AUX;
 	rs_get_tbl_info_from_mcs(&mcs_rate, priv->phymode, tbl, &rate_idx);
 	if (!rs_is_ant_connected(priv->valid_antenna, tbl->antenna_type))
-	    rs_toggle_antenna(&mcs_rate, tbl),
+	    rs_toggle_antenna(&mcs_rate, tbl);
 
 	rs_mcs_from_tbl(&mcs_rate, tbl, rate_idx, use_green);
 	tbl->current_rate.rate_n_flags = mcs_rate.rate_n_flags;
 	rs_get_expected_tpt_table(lq, tbl);
-	rs_fill_link_cmd(lq, &mcs_rate, &(lq->lq), sta);
+	rs_fill_link_cmd(lq, &mcs_rate, &lq->lq);
 	rs_send_lq_cmd(priv, &lq->lq, CMD_ASYNC);
  out:
 	return;
@@ -1714,7 +1727,7 @@ static struct ieee80211_rate *rs_get_rat
 	struct iwl_priv *priv = (struct iwl_priv *)priv_rate;
 	struct iwl_rate_scale_priv *lq;
 
-	IWL_DEBUG_RATE("rate scale calculate new rate for skb\n");
+	IWL_DEBUG_RATE_LIMIT("rate scale calculate new rate for skb\n");
 
 	memset(extra, 0, sizeof(*extra));
 
@@ -1775,10 +1788,9 @@ static void *rs_alloc_sta(void *priv, gf
 
 	if (crl == NULL)
 		return NULL;
-
-	memset(crl, 0, sizeof(struct iwl_rate_scale_priv));
 	crl->lq.sta_id = 0xff;
 
+
 	for (j = 0; j < LQ_SIZE; j++)
 		for (i = 0; i < IWL_RATE_COUNT; i++)
 			rs_rate_scale_clear_window(&(crl->lq_info[j].win[i]));
@@ -1795,10 +1807,8 @@ static void rs_rate_init(void *priv_rate
 	struct iwl_priv *priv = (struct iwl_priv *)priv_rate;
 	struct iwl_rate_scale_priv *crl = priv_sta;
 
-	memset(crl, 0, sizeof(struct iwl_rate_scale_priv));
-
-	crl->lq.sta_id = 0xff;
 	crl->flush_timer = 0;
+	crl->supp_rates = sta->supp_rates;
 	sta->txrate = 3;
 	for (j = 0; j < LQ_SIZE; j++)
 		for (i = 0; i < IWL_RATE_COUNT; i++)
@@ -1864,6 +1874,9 @@ static void rs_rate_init(void *priv_rate
 	IWL_DEBUG_HT("MIMO RATE 0x%X SISO MASK 0x%X\n", crl->active_siso_rate,
 		     crl->active_mimo_rate);
 #endif /*CONFIG_IWLWIFI_HT*/
+#ifdef CONFIG_MAC80211_DEBUGFS
+	crl->drv = priv;
+#endif
 
 	if (priv->assoc_station_added)
 		priv->lq_mngr.lq_ready = 1;
@@ -1871,28 +1884,28 @@ static void rs_rate_init(void *priv_rate
 	rs_initialize_lq(priv, sta);
 }
 
-static int rs_fill_link_cmd(struct iwl_rate_scale_priv *lq_data,
+static void rs_fill_link_cmd(struct iwl_rate_scale_priv *lq_data,
 			    struct iwl_rate *tx_mcs,
-			    struct iwl_link_quality_cmd *lq_cmd,
-			    struct sta_info *sta)
+			    struct iwl_link_quality_cmd *lq_cmd)
 {
 	int index = 0;
-	int rc = 0;
 	int rate_idx;
+	int repeat_rate = 0;
 	u8 ant_toggle_count = 0;
 	u8 use_ht_possible = 1;
-	u8 repeat_cur_rate = 0;
 	struct iwl_rate new_rate;
 	struct iwl_scale_tbl_info tbl_type = { 0 };
 
+	rs_dbgfs_set_mcs(lq_data, tx_mcs, index);
+
 	rs_get_tbl_info_from_mcs(tx_mcs, lq_data->phymode,
 				  &tbl_type, &rate_idx);
 
 	if (is_legacy(tbl_type.lq_type)) {
 		ant_toggle_count = 1;
-		repeat_cur_rate = IWL_NUMBER_TRY;
+		repeat_rate = IWL_NUMBER_TRY;
 	} else
-		repeat_cur_rate = IWL_HT_NUMBER_TRY;
+		repeat_rate = IWL_HT_NUMBER_TRY;
 
 	lq_cmd->general_params.mimo_delimiter =
 			is_mimo(tbl_type.lq_type) ? 1 : 0;
@@ -1906,10 +1919,10 @@ static int rs_fill_link_cmd(struct iwl_r
 		lq_cmd->general_params.single_stream_ant_msk = 2;
 
 	index++;
-	repeat_cur_rate--;
+	repeat_rate--;
 
 	while (index < LINK_QUAL_MAX_RETRY_NUM) {
-		while (repeat_cur_rate && (index < LINK_QUAL_MAX_RETRY_NUM)) {
+		while (repeat_rate > 0 && (index < LINK_QUAL_MAX_RETRY_NUM)) {
 			if (is_legacy(tbl_type.lq_type)) {
 				if (ant_toggle_count <
 				    NUM_TRY_BEFORE_ANTENNA_TOGGLE)
@@ -1919,9 +1932,11 @@ static int rs_fill_link_cmd(struct iwl_r
 					ant_toggle_count = 1;
 				}
 			}
+
+			rs_dbgfs_set_mcs(lq_data, &new_rate, index);
 			lq_cmd->rs_table[index].rate_n_flags =
 					cpu_to_le32(new_rate.rate_n_flags);
-			repeat_cur_rate--;
+			repeat_rate--;
 			index++;
 		}
 
@@ -1932,7 +1947,7 @@ static int rs_fill_link_cmd(struct iwl_r
 			lq_cmd->general_params.mimo_delimiter = index;
 
 		rs_get_lower_rate(lq_data, &tbl_type, rate_idx,
-				  use_ht_possible, &new_rate, sta);
+				  use_ht_possible, &new_rate);
 
 		if (is_legacy(tbl_type.lq_type)) {
 			if (ant_toggle_count < NUM_TRY_BEFORE_ANTENNA_TOGGLE)
@@ -1941,26 +1956,23 @@ static int rs_fill_link_cmd(struct iwl_r
 				rs_toggle_antenna(&new_rate, &tbl_type);
 				ant_toggle_count = 1;
 			}
-			repeat_cur_rate = IWL_NUMBER_TRY;
+			repeat_rate = IWL_NUMBER_TRY;
 		} else
-			repeat_cur_rate = IWL_HT_NUMBER_TRY;
+			repeat_rate = IWL_HT_NUMBER_TRY;
 
 		use_ht_possible = 0;
 
+		rs_dbgfs_set_mcs(lq_data, &new_rate, index);
 		lq_cmd->rs_table[index].rate_n_flags =
 				cpu_to_le32(new_rate.rate_n_flags);
-		/* lq_cmd->rs_table[index].rate_n_flags = 0x800d; */
 
 		index++;
-		repeat_cur_rate--;
+		repeat_rate--;
 	}
 
-	/* lq_cmd->rs_table[0].rate_n_flags = 0x800d; */
-
 	lq_cmd->general_params.dual_stream_ant_msk = 3;
 	lq_cmd->agg_params.agg_dis_start_th = 3;
 	lq_cmd->agg_params.agg_time_limit = cpu_to_le16(4000);
-	return rc;
 }
 
 static void *rs_alloc(struct ieee80211_local *local)
@@ -2000,6 +2012,162 @@ static void rs_free_sta(void *priv, void
 }
 
 
+#ifdef CONFIG_MAC80211_DEBUGFS
+static int open_file_generic(struct inode *inode, struct file *file)
+{
+	file->private_data = inode->i_private;
+	return 0;
+}
+static void rs_dbgfs_set_mcs(struct iwl_rate_scale_priv *rs_priv,
+				struct iwl_rate *mcs, int index)
+{
+	const u32 cck_rate = 0x820A;
+	if (rs_priv->dbg_fixed.rate_n_flags) {
+		if (index < 12)
+			mcs->rate_n_flags = rs_priv->dbg_fixed.rate_n_flags;
+		else
+			mcs->rate_n_flags = cck_rate;
+		IWL_DEBUG_RATE("Fixed rate ON\n");
+		return;
+	}
+
+	IWL_DEBUG_RATE("Fixed rate OFF\n");
+}
+
+static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file,
+			const char __user *user_buf, size_t count, loff_t *ppos)
+{
+	struct iwl_rate_scale_priv *rs_priv = file->private_data;
+	char buf[64];
+	int buf_size;
+	u32 parsed_rate;
+
+	memset(buf, 0, sizeof(buf));
+	buf_size = min(count, sizeof(buf) -  1);
+	if (copy_from_user(buf, user_buf, buf_size))
+		return -EFAULT;
+
+	if (sscanf(buf, "%x", &parsed_rate) == 1)
+		rs_priv->dbg_fixed.rate_n_flags = parsed_rate;
+	else
+		rs_priv->dbg_fixed.rate_n_flags = 0;
+
+	rs_priv->active_rate = 0x0FFF;
+	rs_priv->active_siso_rate = 0x1FD0;
+	rs_priv->active_mimo_rate = 0x1FD0;
+
+	IWL_DEBUG_RATE("sta_id %d rate 0x%X\n",
+		rs_priv->lq.sta_id, rs_priv->dbg_fixed.rate_n_flags);
+
+	if (rs_priv->dbg_fixed.rate_n_flags) {
+		rs_fill_link_cmd(rs_priv, &rs_priv->dbg_fixed, &rs_priv->lq);
+		rs_send_lq_cmd(rs_priv->drv, &rs_priv->lq, CMD_ASYNC);
+	}
+
+	return count;
+}
+
+static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
+			char __user *user_buf, size_t count, loff_t *ppos)
+{
+	char buff[1024];
+	int desc = 0;
+	int i = 0;
+
+	struct iwl_rate_scale_priv *rs_priv = file->private_data;
+
+	desc += sprintf(buff+desc, "sta_id %d\n", rs_priv->lq.sta_id);
+	desc += sprintf(buff+desc, "failed=%d success=%d rate=0%X\n",
+			rs_priv->total_failed, rs_priv->total_success,
+			rs_priv->active_rate);
+	desc += sprintf(buff+desc, "fixed rate 0x%X\n",
+			rs_priv->dbg_fixed.rate_n_flags);
+	desc += sprintf(buff+desc, "general:"
+		"flags=0x%X mimo-d=%d s-ant0x%x d-ant=0x%x\n",
+		rs_priv->lq.general_params.flags,
+		rs_priv->lq.general_params.mimo_delimiter,
+		rs_priv->lq.general_params.single_stream_ant_msk,
+		rs_priv->lq.general_params.dual_stream_ant_msk);
+
+	desc += sprintf(buff+desc, "agg:"
+			"time_limit=%d dist_start_th=%d frame_cnt_limit=%d\n",
+			le16_to_cpu(rs_priv->lq.agg_params.agg_time_limit),
+			rs_priv->lq.agg_params.agg_dis_start_th,
+			rs_priv->lq.agg_params.agg_frame_cnt_limit);
+
+	desc += sprintf(buff+desc,
+			"Start idx [0]=0x%x [1]=0x%x [2]=0x%x [3]=0x%x\n",
+			rs_priv->lq.general_params.start_rate_index[0],
+			rs_priv->lq.general_params.start_rate_index[1],
+			rs_priv->lq.general_params.start_rate_index[2],
+			rs_priv->lq.general_params.start_rate_index[3]);
+
+
+	for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++)
+		desc += sprintf(buff+desc, " rate[%d] 0x%X\n",
+			i, le32_to_cpu(rs_priv->lq.rs_table[i].rate_n_flags));
+
+	return simple_read_from_buffer(user_buf, count, ppos, buff, desc);
+}
+
+static const struct file_operations rs_sta_dbgfs_scale_table_ops = {
+	.write = rs_sta_dbgfs_scale_table_write,
+	.read = rs_sta_dbgfs_scale_table_read,
+	.open = open_file_generic,
+};
+static ssize_t rs_sta_dbgfs_stats_table_read(struct file *file,
+			char __user *user_buf, size_t count, loff_t *ppos)
+{
+	char buff[1024];
+	int desc = 0;
+	int i, j;
+
+	struct iwl_rate_scale_priv *rs_priv = file->private_data;
+	for (i = 0; i < LQ_SIZE; i++) {
+		desc += sprintf(buff+desc, "%s type=%d SGI=%d FAT=%d DUP=%d\n"
+				"rate=0x%X\n",
+				rs_priv->active_tbl == i?"*":"x",
+				rs_priv->lq_info[i].lq_type,
+				rs_priv->lq_info[i].is_SGI,
+				rs_priv->lq_info[i].is_fat,
+				rs_priv->lq_info[i].is_dup,
+				rs_priv->lq_info[i].current_rate.rate_n_flags);
+		for (j = 0; j < IWL_RATE_COUNT; j++) {
+			desc += sprintf(buff+desc,
+					"counter=%d success=%d %%=%d\n",
+					rs_priv->lq_info[i].win[j].counter,
+					rs_priv->lq_info[i].win[j].success_counter,
+					rs_priv->lq_info[i].win[j].success_ratio);
+		}
+	}
+	return simple_read_from_buffer(user_buf, count, ppos, buff, desc);
+}
+
+static const struct file_operations rs_sta_dbgfs_stats_table_ops = {
+	.read = rs_sta_dbgfs_stats_table_read,
+	.open = open_file_generic,
+};
+
+static void rs_add_debugfs(void *priv, void *priv_sta,
+					struct dentry *dir)
+{
+	struct iwl_rate_scale_priv *rs_priv = priv_sta;
+	rs_priv->rs_sta_dbgfs_scale_table_file =
+		debugfs_create_file("rate_scale_table", 0600, dir,
+				rs_priv, &rs_sta_dbgfs_scale_table_ops);
+	rs_priv->rs_sta_dbgfs_stats_table_file =
+		debugfs_create_file("rate_stats_table", 0600, dir,
+			rs_priv, &rs_sta_dbgfs_stats_table_ops);
+}
+
+static void rs_remove_debugfs(void *priv, void *priv_sta)
+{
+	struct iwl_rate_scale_priv *rs_priv = priv_sta;
+	debugfs_remove(rs_priv->rs_sta_dbgfs_scale_table_file);
+	debugfs_remove(rs_priv->rs_sta_dbgfs_stats_table_file);
+}
+#endif
+
 static struct rate_control_ops rs_ops = {
 	.module = NULL,
 	.name = RS_NAME,
@@ -2011,6 +2179,10 @@ static struct rate_control_ops rs_ops = 
 	.free = rs_free,
 	.alloc_sta = rs_alloc_sta,
 	.free_sta = rs_free_sta,
+#ifdef CONFIG_MAC80211_DEBUGFS
+	.add_sta_debugfs = rs_add_debugfs,
+	.remove_sta_debugfs = rs_remove_debugfs,
+#endif
 };
 
 int iwl_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id)
diff -up linux-2.6.22.noarch/drivers/net/wireless/iwlwifi/iwl4965-base.c.orig linux-2.6.22.noarch/drivers/net/wireless/iwlwifi/iwl4965-base.c
--- linux-2.6.22.noarch/drivers/net/wireless/iwlwifi/iwl4965-base.c.orig	2007-09-27 19:08:16.000000000 -0400
+++ linux-2.6.22.noarch/drivers/net/wireless/iwlwifi/iwl4965-base.c	2007-09-27 19:09:01.000000000 -0400
@@ -102,7 +102,7 @@ int iwl_param_queues_num = IWL_MAX_NUM_Q
 #define VS
 #endif
 
-#define IWLWIFI_VERSION "0.1.15k" VD VS
+#define IWLWIFI_VERSION "1.1.17k" VD VS
 #define DRV_COPYRIGHT	"Copyright(c) 2003-2007 Intel Corporation"
 #define DRV_VERSION     IWLWIFI_VERSION
 
@@ -203,7 +203,7 @@ static void iwl_print_hex_dump(int level
  * reclaiming packets (on 'tx done IRQ), if free space become > high mark,
  * Tx queue resumed.
  *
- * The IPW operates with six queues, one receive queue in the device's
+ * The IWL operates with six queues, one receive queue in the device's
  * sram, one transmit queue for sending commands to the device firmware,
  * and four transmit queues for data.
  ***************************************************/
@@ -407,6 +407,7 @@ const u8 BROADCAST_ADDR[ETH_ALEN] = { 0x
 
 /**************************************************************/
 
+#if 0 /* temparary disable till we add real remove station */
 static u8 iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap)
 {
 	int index = IWL_INVALID_STATION;
@@ -442,6 +443,7 @@ out:
 	spin_unlock_irqrestore(&priv->sta_lock, flags);
 	return 0;
 }
+#endif
 
 static void iwl_clear_stations_table(struct iwl_priv *priv)
 {
@@ -851,16 +853,12 @@ int iwl_send_statistics_request(struct i
 static int iwl_rxon_add_station(struct iwl_priv *priv,
 				const u8 *addr, int is_ap)
 {
-	u8 rc;
-
-	/* Remove this station if it happens to already exist */
-	iwl_remove_station(priv, addr, is_ap);
-
-	rc = iwl_add_station(priv, addr, is_ap, 0);
+	u8 sta_id;
 
+	sta_id = iwl_add_station(priv, addr, is_ap, 0);
 	iwl4965_add_station(priv, addr, is_ap);
 
-	return rc;
+	return sta_id;
 }
 
 /**
@@ -1147,16 +1145,6 @@ static int iwl_commit_rxon(struct iwl_pr
 				  "configuration (%d).\n", rc);
 			return rc;
 		}
-
-		/* The RXON bit toggling will have cleared out the
-		 * station table in the uCode, so blank it in the driver
-		 * as well */
-		iwl_clear_stations_table(priv);
-	} else if (priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) {
-		/* When switching from non-associated to associated, the
-		 * uCode clears out the station table; so clear it in the
-		 * driver as well */
-		iwl_clear_stations_table(priv);
 	}
 
 	IWL_DEBUG_INFO("Sending RXON\n"
@@ -1176,6 +1164,8 @@ static int iwl_commit_rxon(struct iwl_pr
 		return rc;
 	}
 
+	iwl_clear_stations_table(priv);
+
 #ifdef CONFIG_IWLWIFI_SENSITIVITY
 	if (!priv->error_recovering)
 		priv->start_calib = 0;
@@ -4608,6 +4598,7 @@ static void iwl_rx_handle(struct iwl_pri
 		reclaim = !(pkt->hdr.sequence & SEQ_RX_FRAME) &&
 			(pkt->hdr.cmd != REPLY_RX_PHY_CMD) &&
 			(pkt->hdr.cmd != REPLY_4965_RX) &&
+			(pkt->hdr.cmd != REPLY_COMPRESSED_BA) &&
 			(pkt->hdr.cmd != STATISTICS_NOTIFICATION) &&
 			(pkt->hdr.cmd != REPLY_TX);
 
@@ -4893,12 +4884,12 @@ static void iwl_dump_nic_event_log(struc
 
 	/* bail out if nothing in log */
 	if (size == 0) {
-		IWL_ERROR("Start IPW Event Log Dump: nothing in log\n");
+		IWL_ERROR("Start IWL Event Log Dump: nothing in log\n");
 		iwl_release_restricted_access(priv);
 		return;
 	}
 
-	IWL_ERROR("Start IPW Event Log Dump: display count %d, wraps %d\n",
+	IWL_ERROR("Start IWL Event Log Dump: display count %d, wraps %d\n",
 		  size, num_wraps);
 
 	/* if uCode has wrapped back to top of log, start at the oldest entry,
@@ -7483,9 +7474,8 @@ static void iwl_config_ap(struct iwl_pri
 		iwl_activate_qos(priv, 1);
 #endif
 		iwl_rxon_add_station(priv, BROADCAST_ADDR, 0);
-		iwl_send_beacon_cmd(priv);
-	} else
-		iwl_send_beacon_cmd(priv);
+	}
+	iwl_send_beacon_cmd(priv);
 
 	/* FIXME - we need to add code here to detect a totally new
 	 * configuration, reset the AP, unassoc, rxon timing, assoc,
diff -up linux-2.6.22.noarch/drivers/net/wireless/iwlwifi/iwl-4965.c.orig linux-2.6.22.noarch/drivers/net/wireless/iwlwifi/iwl-4965.c
--- linux-2.6.22.noarch/drivers/net/wireless/iwlwifi/iwl-4965.c.orig	2007-09-27 19:08:16.000000000 -0400
+++ linux-2.6.22.noarch/drivers/net/wireless/iwlwifi/iwl-4965.c	2007-09-27 19:10:39.000000000 -0400
@@ -183,7 +183,7 @@ u8 iwl_hw_find_station(struct iwl_priv *
 			goto out;
 		}
 
-	IWL_DEBUG_ASSOC("can not find STA " MAC_FMT " total %d\n",
+	IWL_DEBUG_ASSOC_LIMIT("can not find STA " MAC_FMT " total %d\n",
 			MAC_ARG(addr), priv->num_stations);
 
  out:
diff -up linux-2.6.22.noarch/drivers/net/wireless/iwlwifi/iwl-debug.h.orig linux-2.6.22.noarch/drivers/net/wireless/iwlwifi/iwl-debug.h
--- linux-2.6.22.noarch/drivers/net/wireless/iwlwifi/iwl-debug.h.orig	2007-09-27 19:08:16.000000000 -0400
+++ linux-2.6.22.noarch/drivers/net/wireless/iwlwifi/iwl-debug.h	2007-09-27 19:09:01.000000000 -0400
@@ -136,8 +136,11 @@ static inline void IWL_DEBUG_LIMIT(int l
 #define IWL_DEBUG_TXPOWER(f, a...) IWL_DEBUG(IWL_DL_TXPOWER, f, ## a)
 #define IWL_DEBUG_IO(f, a...) IWL_DEBUG(IWL_DL_IO, f, ## a)
 #define IWL_DEBUG_RATE(f, a...) IWL_DEBUG(IWL_DL_RATE, f, ## a)
+#define IWL_DEBUG_RATE_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_RATE, f, ## a)
 #define IWL_DEBUG_NOTIF(f, a...) IWL_DEBUG(IWL_DL_NOTIF, f, ## a)
 #define IWL_DEBUG_ASSOC(f, a...) IWL_DEBUG(IWL_DL_ASSOC | IWL_DL_INFO, f, ## a)
+#define IWL_DEBUG_ASSOC_LIMIT(f, a...) \
+	IWL_DEBUG_LIMIT(IWL_DL_ASSOC | IWL_DL_INFO, f, ## a)
 #define IWL_DEBUG_HT(f, a...) IWL_DEBUG(IWL_DL_HT, f, ## a)
 #define IWL_DEBUG_STATS(f, a...) IWL_DEBUG(IWL_DL_STATS, f, ## a)
 #define IWL_DEBUG_TX_REPLY(f, a...) IWL_DEBUG(IWL_DL_TX_REPLY, f, ## a)
diff -up linux-2.6.22.noarch/drivers/net/wireless/iwlwifi/iwl3945-base.c.orig linux-2.6.22.noarch/drivers/net/wireless/iwlwifi/iwl3945-base.c
--- linux-2.6.22.noarch/drivers/net/wireless/iwlwifi/iwl3945-base.c.orig	2007-09-27 19:08:16.000000000 -0400
+++ linux-2.6.22.noarch/drivers/net/wireless/iwlwifi/iwl3945-base.c	2007-09-27 19:10:13.000000000 -0400
@@ -103,7 +103,7 @@ int iwl_param_queues_num = IWL_MAX_NUM_Q
 #define VS
 #endif
 
-#define IWLWIFI_VERSION "0.1.15k" VD VS
+#define IWLWIFI_VERSION "1.1.17k" VD VS
 #define DRV_COPYRIGHT	"Copyright(c) 2003-2007 Intel Corporation"
 #define DRV_VERSION     IWLWIFI_VERSION
 
@@ -204,7 +204,7 @@ static void iwl_print_hex_dump(int level
  * reclaiming packets (on 'tx done IRQ), if free space become > high mark,
  * Tx queue resumed.
  *
- * The IPW operates with six queues, one receive queue in the device's
+ * The IWL operates with six queues, one receive queue in the device's
  * sram, one transmit queue for sending commands to the device firmware,
  * and four transmit queues for data.
  ***************************************************/
@@ -407,6 +407,7 @@ const u8 BROADCAST_ADDR[ETH_ALEN] = { 0x
  */
 
 /**************************************************************/
+#if 0 /* temparary disable till we add real remove station */
 static u8 iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap)
 {
 	int index = IWL_INVALID_STATION;
@@ -442,7 +443,7 @@ out:
 	spin_unlock_irqrestore(&priv->sta_lock, flags);
 	return 0;
 }
-
+#endif
 static void iwl_clear_stations_table(struct iwl_priv *priv)
 {
 	unsigned long flags;
@@ -462,6 +463,7 @@ u8 iwl_add_station(struct iwl_priv *priv
 	int index = IWL_INVALID_STATION;
 	struct iwl_station_entry *station;
 	unsigned long flags_spin;
+	u8 rate;
 
 	spin_lock_irqsave(&priv->sta_lock, flags_spin);
 	if (is_ap)
@@ -505,6 +507,15 @@ u8 iwl_add_station(struct iwl_priv *priv
 	station->sta.sta.sta_id = index;
 	station->sta.station_flags = 0;
 
+	rate = (priv->phymode == MODE_IEEE80211A) ? IWL_RATE_6M_PLCP :
+				IWL_RATE_1M_PLCP | priv->hw_setting.cck_flag;
+
+	/* Turn on both antennas for the station... */
+	station->sta.rate_n_flags =
+			iwl_hw_set_rate_n_flags(rate, RATE_MCS_ANT_AB_MSK);
+	station->current_rate.rate_n_flags =
+			le16_to_cpu(station->sta.rate_n_flags);
+
 	spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
 	iwl_send_add_station(priv, &station->sta, flags);
 	return index;
@@ -834,25 +845,6 @@ int iwl_send_statistics_request(struct i
 }
 
 /**
- * iwl_rxon_add_station - add station into station table.
- *
- * there is only one AP station with id= IWL_AP_ID
- * NOTE: mutex must be held before calling the this fnction
-*/
-static int iwl_rxon_add_station(struct iwl_priv *priv,
-				const u8 *addr, int is_ap)
-{
-	u8 rc;
-
-	/* Remove this station if it happens to already exist */
-	iwl_remove_station(priv, addr, is_ap);
-
-	rc = iwl_add_station(priv, addr, is_ap, 0);
-
-	return rc;
-}
-
-/**
  * iwl_set_rxon_channel - Set the phymode and channel values in staging RXON
  * @phymode: MODE_IEEE80211A sets to 5.2GHz; all else set to 2.4GHz
  * @channel: Any channel valid for the requested phymode
@@ -1121,16 +1113,6 @@ static int iwl_commit_rxon(struct iwl_pr
 				  "configuration (%d).\n", rc);
 			return rc;
 		}
-
-		/* The RXON bit toggling will have cleared out the
-		 * station table in the uCode, so blank it in the driver
-		 * as well */
-		iwl_clear_stations_table(priv);
-	} else if (priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) {
-		/* When switching from non-associated to associated, the
-		 * uCode clears out the station table; so clear it in the
-		 * driver as well */
-		iwl_clear_stations_table(priv);
 	}
 
 	IWL_DEBUG_INFO("Sending RXON\n"
@@ -1152,6 +1134,8 @@ static int iwl_commit_rxon(struct iwl_pr
 
 	memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
 
+	iwl_clear_stations_table(priv);
+
 	/* If we issue a new RXON command which required a tune then we must
 	 * send a new TXPOWER command or we won't be able to Tx any frames */
 	rc = iwl_hw_reg_send_txpower(priv);
@@ -1161,7 +1145,7 @@ static int iwl_commit_rxon(struct iwl_pr
 	}
 
 	/* Add the broadcast address so we can send broadcast frames */
-	if (iwl_rxon_add_station(priv, BROADCAST_ADDR, 0) ==
+	if (iwl_add_station(priv, BROADCAST_ADDR, 0, 0) ==
 	    IWL_INVALID_STATION) {
 		IWL_ERROR("Error adding BROADCAST address for transmit.\n");
 		return -EIO;
@@ -1171,7 +1155,7 @@ static int iwl_commit_rxon(struct iwl_pr
 	 * add the IWL_AP_ID to the station rate table */
 	if (iwl_is_associated(priv) &&
 	    (priv->iw_mode == IEEE80211_IF_TYPE_STA))
-		if (iwl_rxon_add_station(priv, priv->active_rxon.bssid_addr, 1)
+		if (iwl_add_station(priv, priv->active_rxon.bssid_addr, 1, 0)
 		    == IWL_INVALID_STATION) {
 			IWL_ERROR("Error adding AP address for transmit.\n");
 			return -EIO;
@@ -4583,12 +4567,12 @@ static void iwl_dump_nic_event_log(struc
 
 	/* bail out if nothing in log */
 	if (size == 0) {
-		IWL_ERROR("Start IPW Event Log Dump: nothing in log\n");
+		IWL_ERROR("Start IWL Event Log Dump: nothing in log\n");
 		iwl_release_restricted_access(priv);
 		return;
 	}
 
-	IWL_ERROR("Start IPW Event Log Dump: display count %d, wraps %d\n",
+	IWL_ERROR("Start IWL Event Log Dump: display count %d, wraps %d\n",
 		  size, num_wraps);
 
 	/* if uCode has wrapped back to top of log, start at the oldest entry,
@@ -4650,7 +4634,7 @@ static void iwl_error_recovery(struct iw
 	priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
 	iwl_commit_rxon(priv);
 
-	iwl_rxon_add_station(priv, priv->bssid, 1);
+	iwl_add_station(priv, priv->bssid, 1, 0);
 
 	spin_lock_irqsave(&priv->lock, flags);
 	priv->assoc_id = le16_to_cpu(priv->staging_rxon.assoc_id);
@@ -6793,8 +6777,8 @@ static void iwl_bg_post_associate(struct
 		/* clear out the station table */
 		iwl_clear_stations_table(priv);
 
-		iwl_rxon_add_station(priv, BROADCAST_ADDR, 0);
-		iwl_rxon_add_station(priv, priv->bssid, 0);
+		iwl_add_station(priv, BROADCAST_ADDR, 0, 0);
+		iwl_add_station(priv, priv->bssid, 0, 0);
 		iwl3945_sync_sta(priv, IWL_STA_ID,
 				 (priv->phymode == MODE_IEEE80211A)?
 				 IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP,
@@ -7082,10 +7066,9 @@ static void iwl_config_ap(struct iwl_pri
 		/* restore RXON assoc */
 		priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
 		iwl_commit_rxon(priv);
-		iwl_rxon_add_station(priv, BROADCAST_ADDR, 0);
-		iwl_send_beacon_cmd(priv);
-	} else
-		iwl_send_beacon_cmd(priv);
+		iwl_add_station(priv, BROADCAST_ADDR, 0, 0);
+	}
+	iwl_send_beacon_cmd(priv);
 
 	/* FIXME - we need to add code here to detect a totally new
 	 * configuration, reset the AP, unassoc, rxon timing, assoc,
@@ -7168,8 +7151,8 @@ static int iwl_mac_config_interface(stru
 						RXON_FILTER_ASSOC_MSK;
 			rc = iwl_commit_rxon(priv);
 			if ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && rc)
-				iwl_rxon_add_station(
-					priv, priv->active_rxon.bssid_addr, 1);
+				iwl_add_station(priv,
+					priv->active_rxon.bssid_addr, 1, 0);
 		}
 
 	} else {

linux-2.6-kvm-19.patch:

--- NEW FILE linux-2.6-kvm-19.patch ---
--- linux-2.6.20.noarch/drivers/kvm/vmx.c.kvmorig	2007-04-16 20:54:19.000000000 -0400
+++ linux-2.6.20.noarch/drivers/kvm/vmx.c	2007-04-16 20:54:50.000000000 -0400
@@ -712,6 +712,8 @@
 
 	vmcs_write32(GUEST_CS_AR_BYTES, 0xf3);
 	vmcs_write32(GUEST_CS_LIMIT, 0xffff);
+	if (vmcs_readl(GUEST_CS_BASE) == 0xffff0000)
+		vmcs_writel(GUEST_CS_BASE, 0xf0000);
 	vmcs_write16(GUEST_CS_SELECTOR, vmcs_readl(GUEST_CS_BASE) >> 4);
 
 	fix_rmode_seg(VCPU_SREG_ES, &vcpu->rmode.es);
@@ -786,22 +788,6 @@
 	vcpu->cr0 = cr0;
 }
 
-/*
- * Used when restoring the VM to avoid corrupting segment registers
- */
-static void vmx_set_cr0_no_modeswitch(struct kvm_vcpu *vcpu, unsigned long cr0)
-{
-	if (!vcpu->rmode.active && !(cr0 & CR0_PE_MASK))
-		enter_rmode(vcpu);
-
-	vcpu->rmode.active = ((cr0 & CR0_PE_MASK) == 0);
-	update_exception_bitmap(vcpu);
-	vmcs_writel(CR0_READ_SHADOW, cr0);
-	vmcs_writel(GUEST_CR0,
-		    (cr0 & ~KVM_GUEST_CR0_MASK) | KVM_VM_CR0_ALWAYS_ON);
-	vcpu->cr0 = cr0;
-}
-
 static void vmx_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
 {
 	vmcs_writel(GUEST_CR3, cr3);
@@ -878,7 +864,14 @@
 	vmcs_writel(sf->base, var->base);
 	vmcs_write32(sf->limit, var->limit);
 	vmcs_write16(sf->selector, var->selector);
-	if (var->unusable)
+	if (vcpu->rmode.active && var->s) {
+		/*
+		 * Hack real-mode segments into vm86 compatibility.
+		 */
+		if (var->base == 0xffff0000 && var->selector == 0xf000)
+			vmcs_writel(sf->base, 0xf0000);
+		ar = 0xf3;
+	} else if (var->unusable)
 		ar = 1 << 16;
 	else {
 		ar = var->type & 15;
@@ -933,9 +926,9 @@
 	gfn_t fn = rmode_tss_base(kvm) >> PAGE_SHIFT;
 	char *page;
 
-	p1 = _gfn_to_page(kvm, fn++);
-	p2 = _gfn_to_page(kvm, fn++);
-	p3 = _gfn_to_page(kvm, fn);
+	p1 = gfn_to_page(kvm, fn++);
+	p2 = gfn_to_page(kvm, fn++);
+	p3 = gfn_to_page(kvm, fn);
 
 	if (!p1 || !p2 || !p3) {
 		kvm_printf(kvm,"%s: gfn_to_page failed\n", __FUNCTION__);
@@ -1138,7 +1131,6 @@
 		vcpu->guest_msrs[j] = vcpu->host_msrs[j];
 		++vcpu->nmsrs;
 	}
-	printk(KERN_DEBUG "kvm: msrs: %d\n", vcpu->nmsrs);
 
 	nr_good_msrs = vcpu->nmsrs - NR_BAD_MSRS;
 	vmcs_writel(VM_ENTRY_MSR_LOAD_ADDR,
@@ -1190,7 +1182,7 @@
 	u16 sp =  vmcs_readl(GUEST_RSP);
 	u32 ss_limit = vmcs_read32(GUEST_SS_LIMIT);
 
-	if (sp > ss_limit || sp - 6 > sp) {
+	if (sp > ss_limit || sp < 6 ) {
 		vcpu_printf(vcpu, "%s: #SS, rsp 0x%lx ss 0x%lx limit 0x%x\n",
 			    __FUNCTION__,
 			    vmcs_readl(GUEST_RSP),
@@ -1394,7 +1386,7 @@
 	return 0;
 }
 
-static int get_io_count(struct kvm_vcpu *vcpu, u64 *count)
+static int get_io_count(struct kvm_vcpu *vcpu, unsigned long *count)
 {
 	u64 inst;
 	gva_t rip;
@@ -1439,33 +1431,35 @@
 done:
 	countr_size *= 8;
 	*count = vcpu->regs[VCPU_REGS_RCX] & (~0ULL >> (64 - countr_size));
+	//printk("cx: %lx\n", vcpu->regs[VCPU_REGS_RCX]);
 	return 1;
 }
 
 static int handle_io(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 {
 	u64 exit_qualification;
+	int size, down, in, string, rep;
+	unsigned port;
+	unsigned long count;
+	gva_t address;
 
 	++kvm_stat.io_exits;
 	exit_qualification = vmcs_read64(EXIT_QUALIFICATION);
-	kvm_run->exit_reason = KVM_EXIT_IO;
-	if (exit_qualification & 8)
-		kvm_run->io.direction = KVM_EXIT_IO_IN;
-	else
-		kvm_run->io.direction = KVM_EXIT_IO_OUT;
-	kvm_run->io.size = (exit_qualification & 7) + 1;
-	kvm_run->io.string = (exit_qualification & 16) != 0;
-	kvm_run->io.string_down
-		= (vmcs_readl(GUEST_RFLAGS) & X86_EFLAGS_DF) != 0;
-	kvm_run->io.rep = (exit_qualification & 32) != 0;
-	kvm_run->io.port = exit_qualification >> 16;
-	if (kvm_run->io.string) {
-		if (!get_io_count(vcpu, &kvm_run->io.count))
+	in = (exit_qualification & 8) != 0;
+	size = (exit_qualification & 7) + 1;
+	string = (exit_qualification & 16) != 0;
+	down = (vmcs_readl(GUEST_RFLAGS) & X86_EFLAGS_DF) != 0;
+	count = 1;
+	rep = (exit_qualification & 32) != 0;
+	port = exit_qualification >> 16;
+	address = 0;
+	if (string) {
+		if (rep && !get_io_count(vcpu, &count))
 			return 1;
-		kvm_run->io.address = vmcs_readl(GUEST_LINEAR_ADDRESS);
-	} else
-		kvm_run->io.value = vcpu->regs[VCPU_REGS_RAX]; /* rax */
-	return 0;
+		address = vmcs_readl(GUEST_LINEAR_ADDRESS);
+	}
+	return kvm_setup_pio(vcpu, kvm_run, in, size, count, string, down,
+			     address, rep, port);
 }
 
 static void
@@ -1583,8 +1577,8 @@
 
 static int handle_cpuid(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 {
-	kvm_run->exit_reason = KVM_EXIT_CPUID;
-	return 0;
+	kvm_emulate_cpuid(vcpu);
+	return 1;
 }
 
 static int handle_rdmsr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
@@ -1658,7 +1652,7 @@
 
 static int handle_vmcall(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 {
-	vmcs_writel(GUEST_RIP, vmcs_readl(GUEST_RIP)+3);
+	skip_emulated_instruction(vcpu);
 	return kvm_hypercall(vcpu, kvm_run);
 }
 
@@ -1920,10 +1914,10 @@
 
 	asm ("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS));
 
-	kvm_run->exit_type = 0;
 	if (fail) {
-		kvm_run->exit_type = KVM_EXIT_TYPE_FAIL_ENTRY;
-		kvm_run->exit_reason = vmcs_read32(VM_INSTRUCTION_ERROR);
+		kvm_run->exit_reason = KVM_EXIT_FAIL_ENTRY;
+		kvm_run->fail_entry.hardware_entry_failure_reason
+			= vmcs_read32(VM_INSTRUCTION_ERROR);
 		r = 0;
 	} else {
 		/*
@@ -1933,19 +1927,20 @@
 			profile_hit(KVM_PROFILING, (void *)vmcs_readl(GUEST_RIP));
 
 		vcpu->launched = 1;
-		kvm_run->exit_type = KVM_EXIT_TYPE_VM_EXIT;
 		r = kvm_handle_exit(kvm_run, vcpu);
 		if (r > 0) {
 			/* Give scheduler a change to reschedule. */
 			if (signal_pending(current)) {
 				++kvm_stat.signal_exits;
 				post_kvm_run_save(vcpu, kvm_run);
+				kvm_run->exit_reason = KVM_EXIT_INTR;
 				return -EINTR;
 			}
 
 			if (dm_request_for_irq_injection(vcpu, kvm_run)) {
 				++kvm_stat.request_irq_exits;
 				post_kvm_run_save(vcpu, kvm_run);
+				kvm_run->exit_reason = KVM_EXIT_INTR;
 				return -EINTR;
 			}
 
@@ -2064,7 +2059,6 @@
[...2996 lines suppressed...]
+	KVM_EXIT_INTR             = 10,
 };
 
-/* for KVM_RUN */
+/* for KVM_RUN, returned by mmap(vcpu_fd, offset=0) */
 struct kvm_run {
 	/* in */
-	__u32 emulated;  /* skip current instruction */
-	__u32 mmio_completed; /* mmio request completed */
+	__u32 io_completed; /* mmio/pio request completed */
 	__u8 request_interrupt_window;
-	__u8 padding1[7];
+	__u8 padding1[3];
 
 	/* out */
-	__u32 exit_type;
 	__u32 exit_reason;
 	__u32 instruction_length;
 	__u8 ready_for_interrupt_injection;
 	__u8 if_flag;
-	__u16 padding2;
+	__u8 padding2[6];
 
 	/* in (pre_kvm_run), out (post_kvm_run) */
 	__u64 cr8;
@@ -72,29 +76,26 @@
 	union {
 		/* KVM_EXIT_UNKNOWN */
 		struct {
-			__u32 hardware_exit_reason;
+			__u64 hardware_exit_reason;
 		} hw;
+		/* KVM_EXIT_FAIL_ENTRY */
+		struct {
+			__u64 hardware_entry_failure_reason;
+		} fail_entry;
 		/* KVM_EXIT_EXCEPTION */
 		struct {
 			__u32 exception;
 			__u32 error_code;
 		} ex;
 		/* KVM_EXIT_IO */
-		struct {
+		struct kvm_io {
 #define KVM_EXIT_IO_IN  0
 #define KVM_EXIT_IO_OUT 1
 			__u8 direction;
 			__u8 size; /* bytes */
-			__u8 string;
-			__u8 string_down;
-			__u8 rep;
-			__u8 pad;
 			__u16 port;
-			__u64 count;
-			union {
-				__u64 address;
-				__u32 value;
-			};
+			__u32 count;
+			__u64 data_offset; /* relative to kvm_run start */
 		} io;
 		struct {
 		} debug;
@@ -105,6 +106,13 @@
 			__u32 len;
 			__u8  is_write;
 		} mmio;
+		/* KVM_EXIT_HYPERCALL */
+		struct {
+			__u64 args[6];
+			__u64 ret;
+			__u32 longmode;
+			__u32 pad;
+		} hypercall;
 	};
 };
 
@@ -118,6 +126,21 @@
 	__u64 rip, rflags;
 };
 
+/* for KVM_GET_FPU and KVM_SET_FPU */
+struct kvm_fpu {
+	__u8  fpr[8][16];
+	__u16 fcw;
+	__u16 fsw;
+	__u8  ftwx;  /* in fxsave format */
+	__u8  pad1;
+	__u16 last_opcode;
+	__u64 last_ip;
+	__u64 last_dp;
+	__u8  xmm[16][16];
+	__u32 mxcsr;
+	__u32 pad2;
+};
+
 struct kvm_segment {
 	__u64 base;
 	__u32 limit;
@@ -210,38 +233,74 @@
 	};
 };
 
+struct kvm_cpuid_entry {
+	__u32 function;
+	__u32 eax;
+	__u32 ebx;
+	__u32 ecx;
+	__u32 edx;
+	__u32 padding;
+};
+
+/* for KVM_SET_CPUID */
+struct kvm_cpuid {
+	__u32 nent;
+	__u32 padding;
+	struct kvm_cpuid_entry entries[0];
+};
+
+/* for KVM_SET_SIGNAL_MASK */
+struct kvm_signal_mask {
+	__u32 len;
+	__u8  sigset[0];
+};
+
 #define KVMIO 0xAE
 
 /*
  * ioctls for /dev/kvm fds:
  */
-#define KVM_GET_API_VERSION       _IO(KVMIO, 1)
-#define KVM_CREATE_VM             _IO(KVMIO, 2) /* returns a VM fd */
-#define KVM_GET_MSR_INDEX_LIST    _IOWR(KVMIO, 15, struct kvm_msr_list)
+#define KVM_GET_API_VERSION       _IO(KVMIO,   0x00)
+#define KVM_CREATE_VM             _IO(KVMIO,   0x01) /* returns a VM fd */
+#define KVM_GET_MSR_INDEX_LIST    _IOWR(KVMIO, 0x02, struct kvm_msr_list)
+/*
+ * Check if a kvm extension is available.  Argument is extension number,
+ * return is 1 (yes) or 0 (no, sorry).
+ */
+#define KVM_CHECK_EXTENSION       _IO(KVMIO,   0x03)
+/*
+ * Get size for mmap(vcpu_fd)
+ */
+#define KVM_GET_VCPU_MMAP_SIZE    _IO(KVMIO,   0x04) /* in bytes */
 
 /*
  * ioctls for VM fds
  */
-#define KVM_SET_MEMORY_REGION     _IOW(KVMIO, 10, struct kvm_memory_region)
+#define KVM_SET_MEMORY_REGION     _IOW(KVMIO, 0x40, struct kvm_memory_region)
 /*
  * KVM_CREATE_VCPU receives as a parameter the vcpu slot, and returns
  * a vcpu fd.
  */
-#define KVM_CREATE_VCPU           _IOW(KVMIO, 11, int)
-#define KVM_GET_DIRTY_LOG         _IOW(KVMIO, 12, struct kvm_dirty_log)
+#define KVM_CREATE_VCPU           _IO(KVMIO,  0x41)
+#define KVM_GET_DIRTY_LOG         _IOW(KVMIO, 0x42, struct kvm_dirty_log)
+#define KVM_SET_MEMORY_ALIAS      _IOW(KVMIO, 0x43, struct kvm_memory_alias)
 
 /*
  * ioctls for vcpu fds
  */
-#define KVM_RUN                   _IOWR(KVMIO, 2, struct kvm_run)
-#define KVM_GET_REGS              _IOR(KVMIO, 3, struct kvm_regs)
-#define KVM_SET_REGS              _IOW(KVMIO, 4, struct kvm_regs)
-#define KVM_GET_SREGS             _IOR(KVMIO, 5, struct kvm_sregs)
-#define KVM_SET_SREGS             _IOW(KVMIO, 6, struct kvm_sregs)
-#define KVM_TRANSLATE             _IOWR(KVMIO, 7, struct kvm_translation)
-#define KVM_INTERRUPT             _IOW(KVMIO, 8, struct kvm_interrupt)
-#define KVM_DEBUG_GUEST           _IOW(KVMIO, 9, struct kvm_debug_guest)
-#define KVM_GET_MSRS              _IOWR(KVMIO, 13, struct kvm_msrs)
-#define KVM_SET_MSRS              _IOW(KVMIO, 14, struct kvm_msrs)
+#define KVM_RUN                   _IO(KVMIO,   0x80)
+#define KVM_GET_REGS              _IOR(KVMIO,  0x81, struct kvm_regs)
+#define KVM_SET_REGS              _IOW(KVMIO,  0x82, struct kvm_regs)
+#define KVM_GET_SREGS             _IOR(KVMIO,  0x83, struct kvm_sregs)
+#define KVM_SET_SREGS             _IOW(KVMIO,  0x84, struct kvm_sregs)
+#define KVM_TRANSLATE             _IOWR(KVMIO, 0x85, struct kvm_translation)
+#define KVM_INTERRUPT             _IOW(KVMIO,  0x86, struct kvm_interrupt)
+#define KVM_DEBUG_GUEST           _IOW(KVMIO,  0x87, struct kvm_debug_guest)
+#define KVM_GET_MSRS              _IOWR(KVMIO, 0x88, struct kvm_msrs)
+#define KVM_SET_MSRS              _IOW(KVMIO,  0x89, struct kvm_msrs)
+#define KVM_SET_CPUID             _IOW(KVMIO,  0x8a, struct kvm_cpuid)
+#define KVM_SET_SIGNAL_MASK       _IOW(KVMIO,  0x8b, struct kvm_signal_mask)
+#define KVM_GET_FPU               _IOR(KVMIO,  0x8c, struct kvm_fpu)
+#define KVM_SET_FPU               _IOW(KVMIO,  0x8d, struct kvm_fpu)
 
 #endif
--- linux-2.6.20.noarch/include/linux/miscdevice.h.kvmorig	2007-04-17 11:56:31.000000000 -0400
+++ linux-2.6.20.noarch/include/linux/miscdevice.h	2007-04-17 11:56:53.000000000 -0400
@@ -25,6 +25,7 @@
 #define MICROCODE_MINOR		184
 #define MWAVE_MINOR	219		/* ACP/Mwave Modem */
 #define MPT_MINOR	220
+#define KVM_MINOR 232
 #define MISC_DYNAMIC_MINOR 255
 
 #define TUN_MINOR	     200

linux-2.6-kvm-reinit-real-mode-tss.patch:

--- NEW FILE linux-2.6-kvm-reinit-real-mode-tss.patch ---
From: Avi Kivity <avi at qumranet.com>
Date: Wed, 20 Jun 2007 08:20:04 +0000 (+0300)
Subject: KVM: VMX: Reinitialize the real-mode tss when entering real mode
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Favi%2Fkvm.git;a=commitdiff_plain;h=030421334ae91b7f6302a1cfe9c971a8991b4870

KVM: VMX: Reinitialize the real-mode tss when entering real mode

Protected mode code may have corrupted the real-mode tss, so re-initialize
it when switching to real mode.

Signed-off-by: Avi Kivity <avi at qumranet.com>
---

diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index b47ddcc..42a9163 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -31,6 +31,8 @@
 MODULE_AUTHOR("Qumranet");
 MODULE_LICENSE("GPL");
 
+static int init_rmode_tss(struct kvm *kvm);
+
 static DEFINE_PER_CPU(struct vmcs *, vmxarea);
 static DEFINE_PER_CPU(struct vmcs *, current_vmcs);
 
@@ -951,6 +953,8 @@ static void enter_rmode(struct kvm_vcpu *vcpu)
 	fix_rmode_seg(VCPU_SREG_DS, &vcpu->rmode.ds);
 	fix_rmode_seg(VCPU_SREG_GS, &vcpu->rmode.gs);
 	fix_rmode_seg(VCPU_SREG_FS, &vcpu->rmode.fs);
+
+	init_rmode_tss(vcpu->kvm);
 }
 
 #ifdef CONFIG_X86_64

linux-2.6-libata-acpi-enable.patch:

--- NEW FILE linux-2.6-libata-acpi-enable.patch ---
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 2ad4dda..cc44214 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -98,7 +98,7 @@ static int ata_probe_timeout = ATA_TMOUT_INTERNAL / HZ;
 module_param(ata_probe_timeout, int, 0444);
 MODULE_PARM_DESC(ata_probe_timeout, "Set ATA probing timeout (seconds)");
 
-int libata_noacpi = 1;
+int libata_noacpi = 0;
 module_param_named(noacpi, libata_noacpi, int, 0444);
 MODULE_PARM_DESC(noacpi, "Disables the use of ACPI in suspend/resume when set");
 

linux-2.6-libata-ali-atapi-dma.patch:

--- NEW FILE linux-2.6-libata-ali-atapi-dma.patch ---
ali atapi dma is broken right now. disable it (but not disk dma)
until the problem is better understood.

--- 1/drivers/ata/pata_ali.c~	2007-05-04 18:22:41.129254272 +0100
+++ 2/drivers/ata/pata_ali.c	2007-05-04 18:22:57.105825464 +0100
@@ -329,6 +329,11 @@
 	adev->max_sectors = 255;
 }
 
+static int ali_no_atapi_dma(struct ata_queued_cmd *qc)
+{
+	return -1;
+}
+
 static struct scsi_host_template ali_sht = {
 	.module			= THIS_MODULE,
 	.name			= DRV_NAME,
@@ -371,6 +376,7 @@
 
 	.qc_prep 	= ata_qc_prep,
 	.qc_issue	= ata_qc_issue_prot,
+	.check_atapi_dma= ali_no_atapi_dma,
 
 	.data_xfer	= ata_data_xfer,
 
@@ -412,6 +418,7 @@
 
 	.qc_prep 	= ata_qc_prep,
 	.qc_issue	= ata_qc_issue_prot,
+	.check_atapi_dma= ali_no_atapi_dma,
 
 	.data_xfer	= ata_data_xfer,
 
@@ -450,6 +457,7 @@
 
 	.qc_prep 	= ata_qc_prep,
 	.qc_issue	= ata_qc_issue_prot,
+	.check_atapi_dma= ali_no_atapi_dma,
 
 	.data_xfer	= ata_data_xfer,
 
@@ -487,6 +495,7 @@
 
 	.qc_prep 	= ata_qc_prep,
 	.qc_issue	= ata_qc_issue_prot,
+	.check_atapi_dma= ali_no_atapi_dma,
 
 	.data_xfer	= ata_data_xfer,
 


linux-2.6-libata-atiixp-ids.patch:

--- NEW FILE linux-2.6-libata-atiixp-ids.patch ---
--- linux-2.6.21.noarch/include/linux/pci_ids.h~	2007-05-18 15:41:44.000000000 -0400
+++ linux-2.6.21.noarch/include/linux/pci_ids.h	2007-05-18 15:45:16.000000000 -0400
@@ -371,6 +371,9 @@
 #define PCI_DEVICE_ID_ATI_IXP600_SRAID	0x4381
 #define PCI_DEVICE_ID_ATI_IXP600_SMBUS	0x4385
 #define PCI_DEVICE_ID_ATI_IXP600_IDE	0x438c
+#define PCI_DEVICE_ID_ATI_IXP700_SATA	0x4390
+#define PCI_DEVICE_ID_ATI_IXP700_SMBUS	0x4395
+#define PCI_DEVICE_ID_ATI_IXP700_IDE	0x439c
 
 #define PCI_VENDOR_ID_VLSI		0x1004
 #define PCI_DEVICE_ID_VLSI_82C592	0x0005
--- linux-2.6.21.noarch/drivers/ata/pata_atiixp.c~	2007-05-18 15:45:20.000000000 -0400
+++ linux-2.6.21.noarch/drivers/ata/pata_atiixp.c	2007-05-18 15:45:30.000000000 -0400
@@ -283,6 +283,7 @@ static const struct pci_device_id atiixp
 	{ PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP300_IDE), },
 	{ PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP400_IDE), },
 	{ PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP600_IDE), },
+	{ PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP700_IDE), },
 
 	{ },
 };
--- linux-2.6.21.noarch/drivers/ata/ahci.c~	2007-05-18 15:45:33.000000000 -0400
+++ linux-2.6.21.noarch/drivers/ata/ahci.c	2007-05-18 15:45:49.000000000 -0400
@@ -415,6 +415,7 @@ static const struct pci_device_id ahci_p
 	/* ATI */
 	{ PCI_VDEVICE(ATI, 0x4380), board_ahci_sb600 }, /* ATI SB600 non-raid */
 	{ PCI_VDEVICE(ATI, 0x4381), board_ahci }, /* ATI SB600 raid */
+	{ PCI_VDEVICE(ATI, 0x4390), board_ahci_sb600 }, /* ATI SB700 non-raid */
 
 	/* VIA */
 	{ PCI_VDEVICE(VIA, 0x3349), board_ahci_vt8251 }, /* VIA VT8251 */
--- linux-2.6.21.noarch/drivers/pci/quirks.c~	2007-05-18 15:46:20.000000000 -0400
+++ linux-2.6.21.noarch/drivers/pci/quirks.c	2007-05-18 15:46:32.000000000 -0400
@@ -875,6 +875,7 @@ static void __devinit quirk_sb600_sata(s
 	}
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk_sb600_sata);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP700_SATA, quirk_sb600_sata);
 
 /*
  *	Serverworks CSB5 IDE does not fully support native mode

linux-2.6-libata-hpa.patch:

--- NEW FILE linux-2.6-libata-hpa.patch ---

Signed-off-by: Alan Cox <alan at redhat.com>

Add support for ignoring the BIOS HPA result (off by default) and setting
the disk to the full available size unless already frozen.

Tested with various platforms/disks and confirmed to work with the
Macintosh (which broke earlier) and ata_piix (breakage due to the LBA48
readback that Tejun fixed).

For normal users this brings us, I believe, to feature parity with old IDE
(and of course more featured in some areas too).

diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 735f0b0..e4fc33e 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -89,6 +89,10 @@ int libata_fua = 0;
 module_param_named(fua, libata_fua, int, 0444);
 MODULE_PARM_DESC(fua, "FUA support (0=off, 1=on)");
 
+static int ata_ignore_hpa = 0;
+module_param_named(ignore_hpa, ata_ignore_hpa, int, 0644);
+MODULE_PARM_DESC(ignore_hpa, "Ignore HPA (0=keep BIOS setting 1=ignore it)");
+
 static int ata_probe_timeout = ATA_TMOUT_INTERNAL / HZ;
 module_param(ata_probe_timeout, int, 0444);
 MODULE_PARM_DESC(ata_probe_timeout, "Set ATA probing timeout (seconds)");
@@ -808,6 +812,202 @@ void ata_id_c_string(const u16 *id, unsi
 	*p = '\0';
 }
 
+static u64 ata_tf_to_lba48(struct ata_taskfile *tf)
+{
+	u64 sectors = 0;
+
+	sectors |= ((u64)(tf->hob_lbah & 0xff)) << 40;
+	sectors |= ((u64)(tf->hob_lbam & 0xff)) << 32;
+	sectors |= (tf->hob_lbal & 0xff) << 24;
+	sectors |= (tf->lbah & 0xff) << 16;
+	sectors |= (tf->lbam & 0xff) << 8;
+	sectors |= (tf->lbal & 0xff);
+
+	return ++sectors;
+}
+
+static u64 ata_tf_to_lba(struct ata_taskfile *tf)
+{
+	u64 sectors = 0;
+
+	sectors |= (tf->device & 0x0f) << 24;
+	sectors |= (tf->lbah & 0xff) << 16;
+	sectors |= (tf->lbam & 0xff) << 8;
+	sectors |= (tf->lbal & 0xff);
+
+	return ++sectors;
+}
+
+/**
+ *	ata_read_native_max_address_ext	-	LBA48 native max query
+ *	@dev: Device to query
+ *
+ *	Perform an LBA48 size query upon the device in question. Return the
+ *	actual LBA48 size or zero if the command fails.
+ */
+
+static u64 ata_read_native_max_address_ext(struct ata_device *dev)
+{
+	unsigned int err;
+	struct ata_taskfile tf;
+
+	ata_tf_init(dev, &tf);
+
+	tf.command = ATA_CMD_READ_NATIVE_MAX_EXT;
+	tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_LBA48 | ATA_TFLAG_ISADDR;
+	tf.protocol |= ATA_PROT_NODATA;
+	tf.device |= 0x40;
+
+	err = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0);
+	if (err)
+		return 0;
+
+	return ata_tf_to_lba48(&tf);
+}
+
+/**
+ *	ata_read_native_max_address	-	LBA28 native max query
+ *	@dev: Device to query
+ *
+ *	Performa an LBA28 size query upon the device in question. Return the
+ *	actual LBA28 size or zero if the command fails.
+ */
+
+static u64 ata_read_native_max_address(struct ata_device *dev)
+{
+	unsigned int err;
+	struct ata_taskfile tf;
+
+	ata_tf_init(dev, &tf);
+
+	tf.command = ATA_CMD_READ_NATIVE_MAX;
+	tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR;
+	tf.protocol |= ATA_PROT_NODATA;
+	tf.device |= 0x40;
+
+	err = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0);
+	if (err)
+		return 0;
+
+	return ata_tf_to_lba(&tf);
+}
+
+/**
+ *	ata_set_native_max_address_ext	-	LBA48 native max set
+ *	@dev: Device to query
+ *
+ *	Perform an LBA48 size set max upon the device in question. Return the
+ *	actual LBA48 size or zero if the command fails.
+ */
+
+static u64 ata_set_native_max_address_ext(struct ata_device *dev, u64 new_sectors)
+{
+	unsigned int err;
+	struct ata_taskfile tf;
+
+	new_sectors--;
+
+	ata_tf_init(dev, &tf);
+
+	tf.command = ATA_CMD_SET_MAX_EXT;
+	tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_LBA48 | ATA_TFLAG_ISADDR;
+	tf.protocol |= ATA_PROT_NODATA;
+	tf.device |= 0x40;
+
+	tf.lbal = (new_sectors >> 0) & 0xff;
+	tf.lbam = (new_sectors >> 8) & 0xff;
+	tf.lbah = (new_sectors >> 16) & 0xff;
+
+	tf.hob_lbal = (new_sectors >> 24) & 0xff;
+	tf.hob_lbam = (new_sectors >> 32) & 0xff;
+	tf.hob_lbah = (new_sectors >> 40) & 0xff;
+
+	err = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0);
+	if (err)
+		return 0;
+
+	return ata_tf_to_lba48(&tf);
+}
+
+/**
+ *	ata_set_native_max_address	-	LBA28 native max set
+ *	@dev: Device to query
+ *
+ *	Perform an LBA28 size set max upon the device in question. Return the
+ *	actual LBA28 size or zero if the command fails.
+ */
+
+static u64 ata_set_native_max_address(struct ata_device *dev, u64 new_sectors)
+{
+	unsigned int err;
+	struct ata_taskfile tf;
+
+	new_sectors--;
+
+	ata_tf_init(dev, &tf);
+
+	tf.command = ATA_CMD_SET_MAX;
+	tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR;
+	tf.protocol |= ATA_PROT_NODATA;
+
+	tf.lbal = (new_sectors >> 0) & 0xff;
+	tf.lbam = (new_sectors >> 8) & 0xff;
+	tf.lbah = (new_sectors >> 16) & 0xff;
+	tf.device |= ((new_sectors >> 24) & 0x0f) | 0x40;
+
+	err = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0);
+	if (err)
+		return 0;
+
+	return ata_tf_to_lba(&tf);
+}
+
+/**
+ *	ata_hpa_resize		-	Resize a device with an HPA set
+ *	@dev: Device to resize
+ *
+ *	Read the size of an LBA28 or LBA48 disk with HPA features and resize
+ *	it if required to the full size of the media. The caller must check
+ *	the drive has the HPA feature set enabled.
+ */
+
+static u64 ata_hpa_resize(struct ata_device *dev)
+{
+	u64 sectors = dev->n_sectors;
+	u64 hpa_sectors;
+	
+	if (ata_id_has_lba48(dev->id))
+		hpa_sectors = ata_read_native_max_address_ext(dev);
+	else
+		hpa_sectors = ata_read_native_max_address(dev);
+
+	/* if no hpa, both should be equal */
+	ata_dev_printk(dev, KERN_INFO, "%s 1: sectors = %lld, hpa_sectors = %lld\n",
+		__FUNCTION__, sectors, hpa_sectors);
+
+	if (hpa_sectors > sectors) {
+		ata_dev_printk(dev, KERN_INFO,
+			"Host Protected Area detected:\n"
+			"\tcurrent size: %lld sectors\n"
+			"\tnative size: %lld sectors\n",
+			sectors, hpa_sectors);
+
+		if (ata_ignore_hpa) {
+			if (ata_id_has_lba48(dev->id))
+				hpa_sectors = ata_set_native_max_address_ext(dev, hpa_sectors);
+			else
+				hpa_sectors = ata_set_native_max_address(dev, hpa_sectors);
+
+			if (hpa_sectors) {
+				ata_dev_printk(dev, KERN_INFO,
+					"native size increased to %lld sectors\n", hpa_sectors);
+				return hpa_sectors;
+			}
+		}
+	}
+	return sectors;
+}
+
 static u64 ata_id_n_sectors(const u16 *id)
 {
 	if (ata_id_has_lba(id)) {
@@ -1658,6 +1858,7 @@ int ata_dev_configure(struct ata_device 
 			snprintf(revbuf, 7, "ATA-%d",  ata_id_major_version(id));
 
 		dev->n_sectors = ata_id_n_sectors(id);
+		dev->n_sectors_boot = dev->n_sectors;
 
 		/* SCSI only uses 4-char revisions, dump full 8 chars from ATA */
 		ata_id_c_string(dev->id, fwrevbuf, ATA_ID_FW_REV,
@@ -1684,6 +1885,9 @@ int ata_dev_configure(struct ata_device 
 					dev->flags |= ATA_DFLAG_FLUSH_EXT;
 			}
 
+			if (ata_id_hpa_enabled(dev->id))
+				dev->n_sectors = ata_hpa_resize(dev);
+
 			/* config NCQ */
 			ata_dev_config_ncq(dev, ncq_desc, sizeof(ncq_desc));
 
@@ -3341,6 +3545,11 @@ static int ata_dev_same_device(struct at
 			       "%llu != %llu\n",
 			       (unsigned long long)dev->n_sectors,
 			       (unsigned long long)new_n_sectors);
+		/* Are we the boot time size - if so we appear to be the
+		   same disk at this point and our HPA got reapplied */
+		if (ata_ignore_hpa && dev->n_sectors_boot == new_n_sectors 
+		    && ata_id_hpa_enabled(new_id))
+			return 1;
 		return 0;
 	}
 
diff --git a/include/linux/ata.h b/include/linux/ata.h
index ffb6cdc..f4dc8df 100644
--- a/include/linux/ata.h
+++ b/include/linux/ata.h
@@ -159,6 +159,8 @@ enum {
 	ATA_CMD_INIT_DEV_PARAMS	= 0x91,
 	ATA_CMD_READ_NATIVE_MAX	= 0xF8,
 	ATA_CMD_READ_NATIVE_MAX_EXT = 0x27,
+	ATA_CMD_SET_MAX		= 0xF9,
+	ATA_CMD_SET_MAX_EXT	= 0x37,
 	ATA_CMD_READ_LOG_EXT	= 0x2f,
 
 	/* READ_LOG_EXT pages */
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 12237d4..b29850b 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -473,6 +473,7 @@ struct ata_device {
 	struct scsi_device	*sdev;		/* attached SCSI device */
 	/* n_sector is used as CLEAR_OFFSET, read comment above CLEAR_OFFSET */
 	u64			n_sectors;	/* size of device, if ATA */
+	u64			n_sectors_boot;	/* size of ATA device at startup */
 	unsigned int		class;		/* ATA_DEV_xxx */
 	u16			id[ATA_ID_WORDS]; /* IDENTIFY xxx DEVICE data */
 	u8			pio_mode;


linux-2.6-libata-ich8m-add-pciid.patch:

--- NEW FILE linux-2.6-libata-ich8m-add-pciid.patch ---
From: Christian Lamparter <chunkeey at web.de>

ATA: add a PCI ID for Intel Santa Rosa PATA controller.

Signed-off-by: Christian Lamparter <chunkeey at web.de>
---
 drivers/ata/ata_piix.c |    2 ++
 1 file changed, 2 insertions(+) 
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index 9c07b88..b210726 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -200,6 +200,8 @@ static const struct pci_device_id piix_pci_tbl[] = {
 	/* ICH7/7-R (i945, i975) UDMA 100*/
 	{ 0x8086, 0x27DF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_133 },
 	{ 0x8086, 0x269E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 },
+	/* ICH8 Mobile PATA Controller */
+	{ 0x8086, 0x2850, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_133 },
 
 	/* NOTE: The following PCI ids must be kept in sync with the
 	 * list in drivers/pci/quirks.c.

linux-2.6-libata-ncq-blacklist-2.6.22-rc7.patch:

--- NEW FILE linux-2.6-libata-ncq-blacklist-2.6.22-rc7.patch ---
Updata libata NCQ blacklist to 2.6.22-rc7.

---
 drivers/ata/libata-core.c |    6 ++++++
 1 file changed, 6 insertions(+)

--- linux-2.6.21.noarch.orig/drivers/ata/libata-core.c
+++ linux-2.6.21.noarch/drivers/ata/libata-core.c
@@ -3590,6 +3590,7 @@ static const struct ata_blacklist_entry 
 	{ "FUJITSU MHT2060BH",	NULL,		ATA_HORKAGE_NONCQ },
 	/* NCQ is broken */
 	{ "Maxtor 6L250S0",     "BANC1G10",     ATA_HORKAGE_NONCQ },
+	{ "Maxtor 6B200M0",	"BANC1B10",	ATA_HORKAGE_NONCQ },
 	/* NCQ hard hangs device under heavier load, needs hard power cycle */
 	{ "Maxtor 6B250S0",	"BANC1B70",	ATA_HORKAGE_NONCQ },
 	/* Blacklist entries taken from Silicon Image 3124/3132
@@ -3597,6 +3598,11 @@ static const struct ata_blacklist_entry 
 	{ "HTS541060G9SA00",    "MB3OC60D",     ATA_HORKAGE_NONCQ, },
 	{ "HTS541080G9SA00",    "MB4OC60D",     ATA_HORKAGE_NONCQ, },
 	{ "HTS541010G9SA00",    "MBZOC60D",     ATA_HORKAGE_NONCQ, },
+	/* Drives which do spurious command completion */
+	{ "HTS541680J9SA00",	"SB2IC7EP",	ATA_HORKAGE_NONCQ, },
+	{ "HTS541612J9SA00",	"SBDIC7JP",	ATA_HORKAGE_NONCQ, },
+	{ "Hitachi HTS541616J9SA00", "SB4OC70P", ATA_HORKAGE_NONCQ, },
+	{ "WDC WD740ADFD-00NLR1", NULL,		ATA_HORKAGE_NONCQ, },
 
 	/* Devices with NCQ limits */
 

linux-2.6-libata-pata-dma-disable-option.patch:

--- NEW FILE linux-2.6-libata-pata-dma-disable-option.patch ---
This is useful when debugging, handling problem systems, or for
distributions just to get the system installed so it can be sorted
out later.

This is a bit smarter than the old IDE one and lets you do

libata.pata_dma=0		Disable all PATA DMA like old IDE
libata.pata_dma=1		Disk DMA only
libata.pata_dma=2		ATAPI DMA only
libata.pata_dma=4		CF DMA only

(or combinations thereof - 0,1,3 being the useful ones I suspect)

(I've split CF as it seems to be a seperate case of pain and suffering
different to the others and caused by assorted PIO wired adapters etc)

SATA is not affected - for one its not clear it makes sense to disable
DMA for SATA if even always possible, for two we've seen no failure 
evidence to justify needing to support this kind of hammer on SATA.

Signed-off-by: Alan Cox <alan at redhat.com>

diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.23rc3-mm1/include/linux/libata.h linux-2.6.23rc3-mm1/include/linux/libata.h
--- linux.vanilla-2.6.23rc3-mm1/include/linux/libata.h	2007-08-22 17:23:14.000000000 +0100
+++ linux-2.6.23rc3-mm1/include/linux/libata.h	2007-08-22 17:50:32.000000000 +0100
@@ -315,6 +315,12 @@
 	ATA_HORKAGE_NONCQ	= (1 << 2),	/* Don't use NCQ */
 	ATA_HORKAGE_MAX_SEC_128	= (1 << 3),	/* Limit max sects to 128 */
 	ATA_HORKAGE_BROKEN_HPA	= (1 << 4),	/* Broken HPA */
+ 
+	/* DMA mask for user DMA control: User visible values do not 
+	   renumber */
+	ATA_DMA_MASK_ATA	= (1 << 0),	/* DMA on ATA Disk */
+	ATA_DMA_MASK_ATAPI	= (1 << 1),	/* DMA on ATAPI */
+	ATA_DMA_MASK_CFA	= (1 << 2),	/* DMA on CF Card */
 };
 
 enum hsm_task_states {
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.23rc3-mm1/drivers/ata/libata-core.c linux-2.6.23rc3-mm1/drivers/ata/libata-core.c
--- linux.vanilla-2.6.23rc3-mm1/drivers/ata/libata-core.c	2007-08-22 17:23:00.000000000 +0100
+++ linux-2.6.23rc3-mm1/drivers/ata/libata-core.c	2007-08-22 18:17:31.321738376 +0100
@@ -99,6 +99,10 @@
 module_param_named(ignore_hpa, ata_ignore_hpa, int, 0644);
 MODULE_PARM_DESC(ignore_hpa, "Ignore HPA limit (0=keep BIOS limits, 1=ignore limits, using full disk)");
 
+static int ata_pata_dma = ATA_DMA_MASK_ATA|ATA_DMA_MASK_ATAPI|ATA_DMA_MASK_CFA;
+module_param_named(pata_dma, ata_pata_dma, int, 0644);
+MODULE_PARM_DESC(pata_dma, "Use DMA on PATA devices");
+
 static int ata_probe_timeout = ATA_TMOUT_INTERNAL / HZ;
 module_param(ata_probe_timeout, int, 0444);
 MODULE_PARM_DESC(ata_probe_timeout, "Set ATA probing timeout (seconds)");
@@ -2839,16 +2854,29 @@
 	/* step 1: calculate xfer_mask */
	for (i = 0; i < ATA_MAX_DEVICES; i++) {
 		unsigned int pio_mask, dma_mask;
+		unsigned int mode_mask;
 
 		dev = &ap->device[i];
 
 		if (!ata_dev_enabled(dev))
 			continue;
 
+		mode_mask = ATA_DMA_MASK_ATA;
+		if (dev->class == ATA_DEV_ATAPI)
+			mode_mask = ATA_DMA_MASK_ATAPI;
+		else if (ata_id_is_cfa(dev->id))
+			mode_mask = ATA_DMA_MASK_CFA;
+
 		ata_dev_xfermask(dev);
 
 		pio_mask = ata_pack_xfermask(dev->pio_mask, 0, 0);
 		dma_mask = ata_pack_xfermask(0, dev->mwdma_mask, dev->udma_mask);
+
+		if ((ata_pata_dma & mode_mask) || ap->cbl == ATA_CBL_SATA)
+			dma_mask = ata_pack_xfermask(0, dev->mwdma_mask, dev->udma_mask);
+		else
+			dma_mask = 0;
+
 		dev->pio_mode = ata_xfer_mask2mode(pio_mask);
 		dev->dma_mode = ata_xfer_mask2mode(dma_mask);
 
--- linux-2.6.22.noarch.orig/Documentation/kernel-parameters.txt
+++ linux-2.6.22.noarch/Documentation/kernel-parameters.txt
@@ -870,6 +870,12 @@ and is between 256 and 4096 characters. 
 	lasi=		[HW,SCSI] PARISC LASI driver for the 53c700 chip
 			Format: addr:<io>,irq:<irq>
 
+	libata.pata_dma= [LIBATA]
+		libata.pata_dma=0	Disable all PATA DMA like old IDE
+		libata.pata_dma=1	Disk DMA only
+		libata.pata_dma=2	ATAPI DMA only
+		libata.pata_dma=4	CF DMA only
+
 	load_ramdisk=	[RAM] List of ramdisks to load from floppy
 			See Documentation/ramdisk.txt.
 

linux-2.6-libata-pata-hpt3x2n-correct-revision-boundary.patch:

--- NEW FILE linux-2.6-libata-pata-hpt3x2n-correct-revision-boundary.patch ---
>From davej  Mon May 21 09:55:32 2007
Return-path: <linux-ide-owner at vger.kernel.org>
X-Spam-Checker-Version: SpamAssassin 3.1.8 (2007-02-13) on
	gelk.kernelslacker.org
X-Spam-Level: 
X-Spam-Status: No, score=-2.4 required=5.0 tests=AWL,BAYES_00 autolearn=ham
	version=3.1.8
Envelope-to: davej at codemonkey.org.uk
Delivery-date: Mon, 21 May 2007 14:53:17 +0100
Received: from testure.choralone.org [194.9.77.134]
	by gelk.kernelslacker.org with IMAP (fetchmail-6.3.6)
	for <davej at localhost> (single-drop); Mon, 21 May 2007 09:55:32 -0400 (EDT)
Received: from vger.kernel.org ([209.132.176.167])
	by testure.choralone.org with esmtp (Exim 4.63)
	(envelope-from <linux-ide-owner at vger.kernel.org>)
	id 1Hq8K4-0003Ov-L0
	for davej at codemonkey.org.uk; Mon, 21 May 2007 14:53:17 +0100
Received: (majordomo at vger.kernel.org) by vger.kernel.org via listexpand
	id S1756248AbXEUNwz (ORCPT <rfc822;davej at codemonkey.org.uk>);
	Mon, 21 May 2007 09:52:55 -0400
Received: (majordomo at vger.kernel.org) by vger.kernel.org id S1762141AbXEUNwz
	(ORCPT <rfc822;linux-ide-outgoing>); Mon, 21 May 2007 09:52:55 -0400
Received: from outpipe-village-512-1.bc.nu ([81.2.110.250]:38718 "EHLO
	the-village.bc.nu" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org
	with ESMTP id S1756248AbXEUNwy (ORCPT
	<rfc822;linux-ide at vger.kernel.org>); Mon, 21 May 2007 09:52:54 -0400
Received: from the-village.bc.nu (localhost.localdomain [127.0.0.1])
	by the-village.bc.nu (8.13.8/8.13.8) with ESMTP id l4LDv1RB022969;
	Mon, 21 May 2007 14:57:01 +0100
Date:	Mon, 21 May 2007 14:57:01 +0100
From:	Alan Cox <alan at lxorguk.ukuu.org.uk>
To:	akpm at osdl.org, linux-ide at vger.kernel.org, jeff at garzik.org
Subject: [PATCH] hpt3x2n: Correct revision boundary
Message-ID: <20070521145701.7283c30a at the-village.bc.nu>
X-Mailer: Claws Mail 2.9.1 (GTK+ 2.10.8; i386-redhat-linux-gnu)
Mime-Version: 1.0
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit
Sender:	linux-ide-owner at vger.kernel.org
Precedence: bulk
X-Mailing-List:	linux-ide at vger.kernel.org
Status: RO
Content-Length: 987
Lines: 23

We have a revision that isn't correctly claimed as two drivers both go
for it: Fix the test accordingly. Noticed originally by Bill Nottingham.

Signed-off-by: Alan Cox <alan at redhat.com>

diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.22-rc1-mm1/drivers/ata/pata_hpt3x2n.c linux-2.6.22-rc1-mm1/drivers/ata/pata_hpt3x2n.c
--- linux.vanilla-2.6.22-rc1-mm1/drivers/ata/pata_hpt3x2n.c	2007-05-18 16:21:46.000000000 +0100
+++ linux-2.6.22-rc1-mm1/drivers/ata/pata_hpt3x2n.c	2007-05-18 16:33:57.000000000 +0100
@@ -521,8 +521,8 @@
 			/* 371N if rev > 1 */
 			break;
 		case PCI_DEVICE_ID_TTI_HPT372:
-			/* 372N if rev >= 1*/
-			if (class_rev == 0)
+			/* 372N if rev >= 2*/
+			if (class_rev < 2)
 				return -ENODEV;
 			break;
 		case PCI_DEVICE_ID_TTI_HPT302:
-
To unsubscribe from this list: send the line "unsubscribe linux-ide" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


linux-2.6-libata-pata-pcmcia-new-ident.patch:

--- NEW FILE linux-2.6-libata-pata-pcmcia-new-ident.patch ---
>From davej  Tue May  8 10:22:45 2007
Return-path: <linux-ide-owner at vger.kernel.org>
X-Spam-Checker-Version: SpamAssassin 3.1.8 (2007-02-13) on
	gelk.kernelslacker.org
X-Spam-Level: 
X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00 autolearn=ham
	version=3.1.8
Envelope-to: davej at codemonkey.org.uk
Delivery-date: Tue, 08 May 2007 15:21:14 +0100
Received: from testure.choralone.org [194.9.77.134]
	by gelk.kernelslacker.org with IMAP (fetchmail-6.3.6)
	for <davej at localhost> (single-drop); Tue, 08 May 2007 10:22:45 -0400 (EDT)
Received: from vger.kernel.org ([209.132.176.167])
	by testure.choralone.org with esmtp (Exim 4.63)
	(envelope-from <linux-ide-owner at vger.kernel.org>)
	id 1HlQYz-0002lV-Qb
	for davej at codemonkey.org.uk; Tue, 08 May 2007 15:21:14 +0100
Received: (majordomo at vger.kernel.org) by vger.kernel.org via listexpand
	id S968076AbXEHOVB (ORCPT <rfc822;davej at codemonkey.org.uk>);
	Tue, 8 May 2007 10:21:01 -0400
Received: (majordomo at vger.kernel.org) by vger.kernel.org id S968080AbXEHOVA
	(ORCPT <rfc822;linux-ide-outgoing>); Tue, 8 May 2007 10:21:00 -0400
Received: from anchor-post-34.mail.demon.net ([194.217.242.92]:3414 "EHLO
	anchor-post-34.mail.demon.net" rhost-flags-OK-OK-OK-OK)
	by vger.kernel.org with ESMTP id S968076AbXEHOU7 (ORCPT
	<rfc822;linux-ide at vger.kernel.org>); Tue, 8 May 2007 10:20:59 -0400
X-Greylist: delayed 170437 seconds by postgrey-1.27 at vger.kernel.org; Tue, 08 May 2007 10:20:59 EDT
Received: from rsk.demon.co.uk ([80.176.90.227] helo=[192.168.0.6])
	by anchor-post-34.mail.demon.net with esmtp (Exim 4.42)
	id 1HlQYj-000Fw4-DY; Tue, 08 May 2007 14:20:57 +0000
Subject: [PATCH] pata_pcmcia.c: add card ident for jvc cdrom
From:	Richard Kennedy <richard at rsk.demon.co.uk>
To:	jgarzik at pobox.com
Cc:	linux-ide at vger.kernel.org
Content-Type: text/plain
Date:	Tue, 08 May 2007 15:20:56 +0100
Message-Id: <1178634056.3835.12.camel at localhost.localdomain>
Mime-Version: 1.0
X-Mailer: Evolution 2.8.3 (2.8.3-2.fc6) 
Content-Transfer-Encoding: 7bit
Sender:	linux-ide-owner at vger.kernel.org
Precedence: bulk
X-Mailing-List:	linux-ide at vger.kernel.org
Status: RO
Content-Length: 1103
Lines: 31

update pata_pcmcia to add card ident for JVC MP-CDX1 cdrom drive
card info:
PRODID_1="KME"
PRODID_2="KXLC005"
PRODID_3="00"
MANFID=0032,2904

Signed-off-by: Richard Kennedy <richard at rsk.demon.co.uk>
---
patch against 2.6.21.1

This gets my laptop cd drive working with the new libata driver.
thanks
Richard

--- linux-2.6.21.1/drivers/ata/pata_pcmcia.c	2007-04-27 22:49:26.000000000 +0100
+++ linux-2.6.21.1/drivers/ata/pata_pcmcia.c.new	2007-05-08 12:18:35.000000000 +0100
@@ -322,6 +322,7 @@ static struct pcmcia_device_id pcmcia_de
 	PCMCIA_DEVICE_MANF_CARD(0x000a, 0x0000),	/* I-O Data CFA */
 	PCMCIA_DEVICE_MANF_CARD(0x001c, 0x0001),	/* Mitsubishi CFA */
 	PCMCIA_DEVICE_MANF_CARD(0x0032, 0x0704),
+	PCMCIA_DEVICE_MANF_CARD(0x0032, 0x2904),
 	PCMCIA_DEVICE_MANF_CARD(0x0045, 0x0401),	/* SanDisk CFA */
 	PCMCIA_DEVICE_MANF_CARD(0x0098, 0x0000),	/* Toshiba */
 	PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d),
 

-
To unsubscribe from this list: send the line "unsubscribe linux-ide" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


linux-2.6-libata-pata-sis-fix-timing.patch:

--- NEW FILE linux-2.6-libata-pata-sis-fix-timing.patch ---
Date:	Mon, 21 May 2007 15:00:53 +0100
From:	Alan Cox <alan at lxorguk.ukuu.org.uk>
To:	akpm at osdl.org, jeff at garzik.org, linux-ide at vger.kernel.org
Subject: [PATCH] pata_sis: Fix and clean up some timing setups
Message-ID: <20070521150053.3b6f91a2 at the-village.bc.nu>

- Rename sis_port_base to sis_old_port_base() so nobody uses it for new
generation controllers in error.
- Use byte size operations where it is cleaner for mode setup
- Fix a couple of masking errors on certai chip revs when setting speeds

Signed-off-by: Alan Cox <alan at redhat.com>

diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.22-rc1-mm1/drivers/ata/pata_sis.c linux-2.6.22-rc1-mm1/drivers/ata/pata_sis.c
--- linux.vanilla-2.6.22-rc1-mm1/drivers/ata/pata_sis.c	2007-05-18 16:21:46.000000000 +0100
+++ linux-2.6.22-rc1-mm1/drivers/ata/pata_sis.c	2007-05-18 16:34:30.000000000 +0100
@@ -73,14 +73,14 @@
 }
 
 /**
- *	sis_port_base		-	return PCI configuration base for dev
+ *	sis_old_port_base		-	return PCI configuration base for dev
  *	@adev: device
  *
  *	Returns the base of the PCI configuration registers for this port
  *	number.
  */
 
-static int sis_port_base(struct ata_device *adev)
+static int sis_old_port_base(struct ata_device *adev)
 {
 	return  0x40 + (4 * adev->ap->port_no) +  (2 * adev->devno);
 }
@@ -211,7 +211,7 @@
 static void sis_old_set_piomode (struct ata_port *ap, struct ata_device *adev)
 {
 	struct pci_dev *pdev	= to_pci_dev(ap->host->dev);
-	int port = sis_port_base(adev);
+	int port = sis_old_port_base(adev);
 	u8 t1, t2;
 	int speed = adev->pio_mode - XFER_PIO_0;
 
@@ -248,7 +248,7 @@
 static void sis_100_set_piomode (struct ata_port *ap, struct ata_device *adev)
 {
 	struct pci_dev *pdev	= to_pci_dev(ap->host->dev);
-	int port = sis_port_base(adev);
+	int port = sis_old_port_base(adev);
 	int speed = adev->pio_mode - XFER_PIO_0;
 
 	const u8 actrec[] = { 0x00, 0x67, 0x44, 0x33, 0x31 };
@@ -328,7 +328,7 @@
 {
 	struct pci_dev *pdev	= to_pci_dev(ap->host->dev);
 	int speed = adev->dma_mode - XFER_MW_DMA_0;
-	int drive_pci = sis_port_base(adev);
+	int drive_pci = sis_old_port_base(adev);
 	u16 timing;
 
 	const u16 mwdma_bits[] = { 0x707, 0x202, 0x202 };
@@ -367,7 +367,7 @@
 {
 	struct pci_dev *pdev	= to_pci_dev(ap->host->dev);
 	int speed = adev->dma_mode - XFER_MW_DMA_0;
-	int drive_pci = sis_port_base(adev);
+	int drive_pci = sis_old_port_base(adev);
 	u16 timing;
 
 	const u16 mwdma_bits[] = { 0x707, 0x202, 0x202 };
@@ -378,12 +378,12 @@
 	if (adev->dma_mode < XFER_UDMA_0) {
 		/* bits 3-0 hold recovery timing bits 8-10 active timing and
 		   the higer bits are dependant on the device, bit 15 udma */
-		timing &= ~ 0x870F;
+		timing &= ~0x870F;
 		timing |= mwdma_bits[speed];
 	} else {
 		/* Bit 15 is UDMA on/off, bit 12-14 are cycle time */
 		speed = adev->dma_mode - XFER_UDMA_0;
-		timing &= ~0x6000;
+		timing &= ~0xF000;
 		timing |= udma_bits[speed];
 	}
 	pci_write_config_word(pdev, drive_pci, timing);
@@ -405,22 +405,22 @@
 {
 	struct pci_dev *pdev	= to_pci_dev(ap->host->dev);
 	int speed = adev->dma_mode - XFER_MW_DMA_0;
-	int drive_pci = sis_port_base(adev);
-	u16 timing;
+	int drive_pci = sis_old_port_base(adev);
+	u8 timing;
 
-	const u16 udma_bits[]  = { 0x8B00, 0x8700, 0x8500, 0x8300, 0x8200, 0x8100};
+	const u8 udma_bits[]  = { 0x8B, 0x87, 0x85, 0x83, 0x82, 0x81};
 
-	pci_read_config_word(pdev, drive_pci, &timing);
+	pci_read_config_byte(pdev, drive_pci + 1, &timing);
 
 	if (adev->dma_mode < XFER_UDMA_0) {
 		/* NOT SUPPORTED YET: NEED DATA SHEET. DITTO IN OLD DRIVER */
 	} else {
-		/* Bit 15 is UDMA on/off, bit 12-14 are cycle time */
+		/* Bit 7 is UDMA on/off, bit 0-3 are cycle time */
 		speed = adev->dma_mode - XFER_UDMA_0;
-		timing &= ~0x0F00;
+		timing &= ~0x8F;
 		timing |= udma_bits[speed];
 	}
-	pci_write_config_word(pdev, drive_pci, timing);
+	pci_write_config_byte(pdev, drive_pci + 1, timing);
 }
 
 /**
@@ -491,22 +491,23 @@ static void sis_133_early_set_dmamode (s
 {
 	struct pci_dev *pdev	= to_pci_dev(ap->host->dev);
 	int speed = adev->dma_mode - XFER_MW_DMA_0;
-	int drive_pci = sis_port_base(adev);
-	u16 timing;
 
-	const u16 udma_bits[]  = { 0x8F00, 0x8A00, 0x8700, 0x8500, 0x8300, 0x8200, 0x8100};
+	int drive_pci = sis_old_port_base(adev);
+	u8 timing;
+	/* Low 4 bits are timing */
+	static const u8 udma_bits[]  = { 0x8F, 0x8A, 0x87, 0x85, 0x83, 0x82, 0x81};
 
-	pci_read_config_word(pdev, drive_pci, &timing);
+	pci_read_config_byte(pdev, drive_pci + 1, &timing);
 
 	if (adev->dma_mode < XFER_UDMA_0) {
 		/* NOT SUPPORTED YET: NEED DATA SHEET. DITTO IN OLD DRIVER */
 	} else {
-		/* Bit 15 is UDMA on/off, bit 12-14 are cycle time */
+		/* Bit 7 is UDMA on/off, bit 0-3 are cycle time */
 		speed = adev->dma_mode - XFER_UDMA_0;
-		timing &= ~0x0F00;
+		timing &= ~0x8F;
 		timing |= udma_bits[speed];
 	}
-	pci_write_config_word(pdev, drive_pci, timing);
+	pci_write_config_byte(pdev, drive_pci + 1, timing);
 }
 
 /**

linux-2.6-libata-pata_dma-param.patch:

--- NEW FILE linux-2.6-libata-pata_dma-param.patch ---
Allow

	libata.pata_dma=0

to disable DMA (default is 1)

SATA is unaffected as disabling DMA for SATA makes no sense at all.

Signed-off-by: Alan Cox <alan at redhat.com>
[documentation: cebbert at redhat.com]

diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.22-rc4-mm2/drivers/ata/libata-core.c linux-2.6.22-rc4-mm2/drivers/ata/libata-core.c
--- linux.vanilla-2.6.22-rc4-mm2/drivers/ata/libata-core.c	2007-06-07 14:26:08.000000000 +0100
+++ linux-2.6.22-rc4-mm2/drivers/ata/libata-core.c	2007-06-07 16:53:43.000000000 +0100
@@ -94,6 +94,10 @@
 module_param_named(ignore_hpa, ata_ignore_hpa, int, 0644);
 MODULE_PARM_DESC(ignore_hpa, "Ignore HPA limit (0=keep BIOS limits, 1=ignore limits, using full disk)");
 
+static int ata_pata_dma = 1;
+module_param_named(pata_dma, ata_pata_dma, int, 0644);
+MODULE_PARM_DESC(pata_dma, "Use DMA on PATA devices");
+
 static int ata_probe_timeout = ATA_TMOUT_INTERNAL / HZ;
 module_param(ata_probe_timeout, int, 0444);
 MODULE_PARM_DESC(ata_probe_timeout, "Set ATA probing timeout (seconds)");
@@ -2815,7 +2831,12 @@
 		ata_dev_xfermask(dev);
 
 		pio_mask = ata_pack_xfermask(dev->pio_mask, 0, 0);
-		dma_mask = ata_pack_xfermask(0, dev->mwdma_mask, dev->udma_mask);
+		
+		if (ata_pata_dma || ap->cbl == ATA_CBL_SATA)
+			dma_mask = ata_pack_xfermask(0, dev->mwdma_mask, dev->udma_mask);
+		else
+			dma_mask = 0;
+
 		dev->pio_mode = ata_xfer_mask2mode(pio_mask);
 		dev->dma_mode = ata_xfer_mask2mode(dma_mask);
 
--- linux-2.6.21.noarch.orig/Documentation/kernel-parameters.txt
+++ linux-2.6.21.noarch/Documentation/kernel-parameters.txt
@@ -786,6 +786,10 @@ and is between 256 and 4096 characters. 
 	lasi=		[HW,SCSI] PARISC LASI driver for the 53c700 chip
 			Format: addr:<io>,irq:<irq>
 
+	libata.pata_dma	[LIBATA] enable or disable DMA in the
+			Parallel ATA drivers.
+			Format: <integer> (0=disable, 1=enable)
+
 	llsc*=		[IA64] See function print_params() in
 			arch/ia64/sn/kernel/llsc4.c.
 

linux-2.6-libata-pata_it821x-partly-fix-dma.patch:

--- NEW FILE linux-2.6-libata-pata_it821x-partly-fix-dma.patch ---
Gitweb:     http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=374abf2cb16a9df8be96675c606996458872e8b3
Commit:     374abf2cb16a9df8be96675c606996458872e8b3
Parent:     9f7897554eeca34ec23dd877cc27402bd327a1ce
Author:     Bartlomiej Zolnierkiewicz <bzolnier at gmail.com>
AuthorDate: Mon Jun 11 11:40:07 2007 +0200
Committer:  Jeff Garzik <jeff at garzik.org>
CommitDate: Wed Jun 20 19:56:21 2007 -0400

    pata_it821x: (partially) fix DMA in RAID mode
    
    Code intended to check DMA status was checking DMA command register.
    
    Moreover firmware seems to "forget" to set DMA capable bit for the
    slave device (at least in RAID mode but without ITE RAID volumes) so
    check device ID for DMA capable bit when deciding whether to use DMA
    and remove DMA status check completely.
    
    Thanks to Pavol Simo for the bugreport and testing the initial fix.
    
    This change unfortunately still doesn't fix DMA in RAID mode (which
    works fine with IDE it821x) but Alan is working on the missing pieces
    (pata_it821x vs libata EH issues).
    
    Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier at gmail.com>
    Acked-by: Alan Cox <alan at redhat.com>
    Cc: Tejun Heo <htejun at gmail.com>
    Signed-off-by: Jeff Garzik <jeff at garzik.org>
    [remove copyright and version changes: <cebbert at redhat.com>]
---
 drivers/ata/pata_it821x.c |   11 +++--------
 1 files changed, 3 insertions(+), 8 deletions(-)

diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c
index b3456d7..525c9c1 100644
--- a/drivers/ata/pata_it821x.c
+++ b/drivers/ata/pata_it821x.c
@@ -460,14 +461,8 @@ static unsigned int it821x_passthru_qc_issue_prot(struct ata_queued_cmd *qc)
 
 static int it821x_smart_set_mode(struct ata_port *ap, struct ata_device **unused)
 {
-	int dma_enabled = 0;
 	int i;
 
-	/* Bits 5 and 6 indicate if DMA is active on master/slave */
-	/* It is possible that BMDMA isn't allocated */
-	if (ap->ioaddr.bmdma_addr)
-		dma_enabled = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
-
 	for (i = 0; i < ATA_MAX_DEVICES; i++) {
 		struct ata_device *dev = &ap->device[i];
 		if (ata_dev_enabled(dev)) {
@@ -476,7 +471,7 @@ static int it821x_smart_set_mode(struct ata_port *ap, struct ata_device **unused
 			dev->dma_mode = XFER_MW_DMA_0;
 			/* We do need the right mode information for DMA or PIO
 			   and this comes from the current configuration flags */
-			if (dma_enabled & (1 << (5 + i))) {
+			if (ata_id_has_dma(dev->id)) {
 				ata_dev_printk(dev, KERN_INFO, "configured for DMA\n");
 				dev->xfer_mode = XFER_MW_DMA_0;
 				dev->xfer_shift = ATA_SHIFT_MWDMA;

linux-2.6-libata-sata_nv-adma.patch:

--- NEW FILE linux-2.6-libata-sata_nv-adma.patch ---
commit eb20a5742d230c67b9af4efd71b8b6b680ca3a09
Author: Robert Hancock <hancockr at shaw.ca>
Date:   Mon Mar 26 21:43:36 2007 -0800

    sata_nv: don't read shadow registers when in ADMA mode
    
    Reading from the ATA shadow registers while we are in ADMA mode may cause
    undefined behavior.  Don't read the ATA status register when completing
    commands for this reason, it shouldn't be needed as the controller will
    notify us if the command failed.  Also, don't allow commands with result
    taskfile requested to execute in ADMA mode, since that requires accessing
    the shadow registers.  We also still need to override tf_read since libata
    will read the result taskfile on a command failure, and we need to go into
    port register mode before allowing this.
    
    Signed-off-by: Robert Hancock <hancockr at shaw.ca>
    Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
    Signed-off-by: Jeff Garzik <jeff at garzik.org>

diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
index 9d9670a..8a9473b 100644
--- a/drivers/ata/sata_nv.c
+++ b/drivers/ata/sata_nv.c
@@ -260,6 +260,7 @@ static int nv_adma_port_resume(struct ata_port *ap);
 static void nv_adma_error_handler(struct ata_port *ap);
 static void nv_adma_host_stop(struct ata_host *host);
 static void nv_adma_post_internal_cmd(struct ata_queued_cmd *qc);
+static void nv_adma_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
 
 enum nv_host_type
 {
@@ -435,7 +436,7 @@ static const struct ata_port_operations nv_ck804_ops = {
 static const struct ata_port_operations nv_adma_ops = {
 	.port_disable		= ata_port_disable,
 	.tf_load		= ata_tf_load,
-	.tf_read		= ata_tf_read,
+	.tf_read		= nv_adma_tf_read,
 	.check_atapi_dma	= nv_adma_check_atapi_dma,
 	.exec_command		= ata_exec_command,
 	.check_status		= ata_check_status,
@@ -667,6 +668,18 @@ static int nv_adma_check_atapi_dma(struct ata_queued_cmd *qc)
 	return !(pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE);
 }
 
+static void nv_adma_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
+{
+	/* Since commands where a result TF is requested are not
+	   executed in ADMA mode, the only time this function will be called
+	   in ADMA mode will be if a command fails. In this case we
+	   don't care about going into register mode with ADMA commands
+	   pending, as the commands will all shortly be aborted anyway. */
+	nv_adma_register_mode(ap);
+
+	ata_tf_read(ap, tf);
+}
+
 static unsigned int nv_adma_tf_to_cpb(struct ata_taskfile *tf, __le16 *cpb)
 {
 	unsigned int idx = 0;
@@ -738,19 +751,11 @@ static int nv_adma_check_cpb(struct ata_port *ap, int cpb_num, int force_err)
 		return 1;
 	}
 
-	if (flags & NV_CPB_RESP_DONE) {
+	if (likely(flags & NV_CPB_RESP_DONE)) {
 		struct ata_queued_cmd *qc = ata_qc_from_tag(ap, cpb_num);
 		VPRINTK("CPB flags done, flags=0x%x\n", flags);
 		if (likely(qc)) {
-			/* Grab the ATA port status for non-NCQ commands.
-			   For NCQ commands the current status may have nothing to do with
-			   the command just completed. */
-			if (qc->tf.protocol != ATA_PROT_NCQ) {
-				u8 ata_status = readb(pp->ctl_block + (ATA_REG_STATUS * 4));
-				qc->err_mask |= ac_err_mask(ata_status);
-			}
-			DPRINTK("Completing qc from tag %d with err_mask %u\n",cpb_num,
-				qc->err_mask);
+			DPRINTK("Completing qc from tag %d\n",cpb_num);
 			ata_qc_complete(qc);
 		} else {
 			struct ata_eh_info *ehi = &ap->eh_info;
@@ -1167,9 +1172,11 @@ static int nv_adma_use_reg_mode(struct ata_queued_cmd *qc)
 	struct nv_adma_port_priv *pp = qc->ap->private_data;
 
 	/* ADMA engine can only be used for non-ATAPI DMA commands,
-	   or interrupt-driven no-data commands. */
+	   or interrupt-driven no-data commands, where a result taskfile
+	   is not required. */
 	if((pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE) ||
-	   (qc->tf.flags & ATA_TFLAG_POLLING))
+	   (qc->tf.flags & ATA_TFLAG_POLLING) ||
+	   (qc->flags & ATA_QCFLAG_RESULT_TF))
 		return 1;
 
 	if((qc->flags & ATA_QCFLAG_DMAMAP) ||

linux-2.6-libata-sata_nv-wildcard-removal.patch:

--- NEW FILE linux-2.6-libata-sata_nv-wildcard-removal.patch ---
Date:   Wed, 25 Apr 2007 11:17:21 +0800
To:     <linux-kernel at vger.kernel.org>
From:   "Peer Chen" <pchen at nvidia.com>
Cc:     <akpm at osdl.org>, <jgarzik at pobox.com>, <torvalds at osdl.org>
Subject:  [PATCH] drivers/ata: remove the wildcard from sata_nv driver

Because nvidia SATA controllers onward base on AHCI, so wildcard in
sata_nv driver is unnecessary.
Also the wildcard sometimes cause sata_nv driver to be loaded for AHCI
controllers,which is not as expected.

Signed-off-by: Peer Chen <pchen at nvidia.com>

--- linux-2.6.21.noarch/drivers/ata/sata_nv.c~	2007-05-04 00:06:52.000000000 -0400
+++ linux-2.6.21.noarch/drivers/ata/sata_nv.c	2007-05-04 00:07:00.000000000 -0400
@@ -286,12 +286,6 @@ static const struct pci_device_id nv_pci
 	{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA), GENERIC },
 	{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA2), GENERIC },
 	{ PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA3), GENERIC },
-	{ PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
-		PCI_ANY_ID, PCI_ANY_ID,
-		PCI_CLASS_STORAGE_IDE<<8, 0xffff00, GENERIC },
-	{ PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
-		PCI_ANY_ID, PCI_ANY_ID,
-		PCI_CLASS_STORAGE_RAID<<8, 0xffff00, GENERIC },
 
 	{ } /* terminate list */
 };

linux-2.6-libata-setxfer.patch:

--- NEW FILE linux-2.6-libata-setxfer.patch ---
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 3ca9c61..4d6de65 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -3932,10 +3932,13 @@ static unsigned int ata_dev_set_xfermode
 	/* set up set-features taskfile */
 	DPRINTK("set features - xfer mode\n");
 
+	/* Some controllers and ATAPI devices show flaky interrupt
+	 * behavior after setting xfer mode.  Use polling instead.
+	 */
 	ata_tf_init(dev, &tf);
 	tf.command = ATA_CMD_SET_FEATURES;
 	tf.feature = SETFEATURES_XFER;
-	tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
+	tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE | ATA_TFLAG_POLLING;
 	tf.protocol = ATA_PROT_NODATA;
 	tf.nsect = dev->xfer_mode;
 
@@ -5413,14 +5416,6 @@ unsigned int ata_qc_issue_prot(struct at
 		}
 	}
 
-	/* Some controllers show flaky interrupt behavior after
-	 * setting xfer mode.  Use polling instead.
-	 */
-	if (unlikely(qc->tf.command == ATA_CMD_SET_FEATURES &&
-		     qc->tf.feature == SETFEATURES_XFER) &&
-	    (ap->flags & ATA_FLAG_SETXFER_POLLING))
-		qc->tf.flags |= ATA_TFLAG_POLLING;
-
 	/* select the device */
 	ata_dev_select(ap, qc->dev->devno, 1, 0);
 
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 85f7b1b..a6a3113 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -171,7 +171,6 @@ enum {
 	ATA_FLAG_SKIP_D2H_BSY	= (1 << 12), /* can't wait for the first D2H
 					      * Register FIS clearing BSY */
 	ATA_FLAG_DEBUGMSG	= (1 << 13),
-	ATA_FLAG_SETXFER_POLLING= (1 << 14), /* use polling for SETXFER */
 	ATA_FLAG_IGN_SIMPLEX	= (1 << 15), /* ignore SIMPLEX */
 	ATA_FLAG_NO_IORDY	= (1 << 16), /* controller lacks iordy */
 	ATA_FLAG_ACPI_SATA	= (1 << 17), /* need native SATA ACPI layout */

-
--- linux-2.6.21.noarch/drivers/ata/pata_via.c~	2007-06-06 18:39:14.000000000 -0400
+++ linux-2.6.21.noarch/drivers/ata/pata_via.c	2007-06-06 18:39:48.000000000 -0400
@@ -429,7 +429,7 @@ static int via_init_one(struct pci_dev *
 	/* Early VIA without UDMA support */
 	static struct ata_port_info via_mwdma_info = {
 		.sht = &via_sht,
-		.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
+		.flags = ATA_FLAG_SLAVE_POSS,
 		.pio_mask = 0x1f,
 		.mwdma_mask = 0x07,
 		.port_ops = &via_port_ops
@@ -437,7 +437,7 @@ static int via_init_one(struct pci_dev *
 	/* Ditto with IRQ masking required */
 	static struct ata_port_info via_mwdma_info_borked = {
 		.sht = &via_sht,
-		.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
+		.flags = ATA_FLAG_SLAVE_POSS,
 		.pio_mask = 0x1f,
 		.mwdma_mask = 0x07,
 		.port_ops = &via_port_ops_noirq,
@@ -445,7 +445,7 @@ static int via_init_one(struct pci_dev *
 	/* VIA UDMA 33 devices (and borked 66) */
 	static struct ata_port_info via_udma33_info = {
 		.sht = &via_sht,
-		.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
+		.flags = ATA_FLAG_SLAVE_POSS,
 		.pio_mask = 0x1f,
 		.mwdma_mask = 0x07,
 		.udma_mask = 0x7,
@@ -454,7 +454,7 @@ static int via_init_one(struct pci_dev *
 	/* VIA UDMA 66 devices */
 	static struct ata_port_info via_udma66_info = {
 		.sht = &via_sht,
-		.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
+		.flags = ATA_FLAG_SLAVE_POSS,
 		.pio_mask = 0x1f,
 		.mwdma_mask = 0x07,
 		.udma_mask = 0x1f,
@@ -463,7 +463,7 @@ static int via_init_one(struct pci_dev *
 	/* VIA UDMA 100 devices */
 	static struct ata_port_info via_udma100_info = {
 		.sht = &via_sht,
-		.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
+		.flags = ATA_FLAG_SLAVE_POSS,
 		.pio_mask = 0x1f,
 		.mwdma_mask = 0x07,
 		.udma_mask = 0x3f,
@@ -472,7 +472,7 @@ static int via_init_one(struct pci_dev *
 	/* UDMA133 with bad AST (All current 133) */
 	static struct ata_port_info via_udma133_info = {
 		.sht = &via_sht,
-		.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
+		.flags = ATA_FLAG_SLAVE_POSS,
 		.pio_mask = 0x1f,
 		.mwdma_mask = 0x07,
 		.udma_mask = 0x7f,	/* FIXME: should check north bridge */



sata_promise uses two different command modes - packet and TF.  Packet
mode is intelligent low-overhead mode while TF is the same old
taskfile interface.  As with other advanced interface (ahci/sil24),
ATA_TFLAG_POLLING has no effect in packet mode.  However, PIO commands
are issued using TF interface in polling mode, so pdc_interrupt()
considers interrupts spurious if ATA_TFLAG_POLLING is set.

This is broken for polling NODATA commands because command is issued
using packet mode but the interrupt handler ignores it due to
ATA_TFLAG_POLLING.  Fix pdc_qc_issue_prot() such that ATA/ATAPI NODATA
commands are issued using TF interface if ATA_TFLAG_POLLING is set.

This patch fixes detection failure introduced by polling SETXFERMODE.

Signed-off-by: Tejun Heo <htejun at gmail.com>
---
David, please verify this patch.  Mikael, does this look okay?  Please
push this upstream after David and Mikael's ack.

(This repost is identical to the previous posting but it's now on the
 correct thread.)

Thanks.

 drivers/ata/sata_promise.c |    9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c
index 2b924a6..6dc0b01 100644
--- a/drivers/ata/sata_promise.c
+++ b/drivers/ata/sata_promise.c
@@ -784,9 +784,12 @@ static unsigned int pdc_qc_issue_prot(struct ata_queued_cmd *qc)
 		if (qc->dev->flags & ATA_DFLAG_CDB_INTR)
 			break;
 		/*FALLTHROUGH*/
+	case ATA_PROT_NODATA:
+		if (qc->tf.flags & ATA_TFLAG_POLLING)
+			break;
+		/*FALLTHROUGH*/
 	case ATA_PROT_ATAPI_DMA:
 	case ATA_PROT_DMA:
-	case ATA_PROT_NODATA:
 		pdc_packet_start(qc);
 		return 0;
 
@@ -800,7 +803,7 @@ static unsigned int pdc_qc_issue_prot(struct ata_queued_cmd *qc)
 static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
 {
 	WARN_ON (tf->protocol == ATA_PROT_DMA ||
-		 tf->protocol == ATA_PROT_NODATA);
+		 tf->protocol == ATA_PROT_ATAPI_DMA);
 	ata_tf_load(ap, tf);
 }
 
@@ -808,7 +811,7 @@ static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
 static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
 {
 	WARN_ON (tf->protocol == ATA_PROT_DMA ||
-		 tf->protocol == ATA_PROT_NODATA);
+		 tf->protocol == ATA_PROT_ATAPI_DMA);
 	ata_exec_command(ap, tf);
 }
 
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


linux-2.6-libata_ali_max_dma_speed.patch:

--- NEW FILE linux-2.6-libata_ali_max_dma_speed.patch ---
Patch from Alan Cox.
https://bugzilla.redhat.com/bugzilla/attachment.cgi?id=156482&action=view
---
 drivers/ata/pata_ali.c |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

--- linux-2.6.21.noarch.orig/drivers/ata/pata_ali.c
+++ linux-2.6.21.noarch/drivers/ata/pata_ali.c
@@ -613,22 +613,22 @@ static int ali_init_one(struct pci_dev *
 		.udma_mask = 0x1f,
 		.port_ops = &ali_c2_port_ops
 	};
-	/* Revision 0xC3 is UDMA100 */
+	/* Revision 0xC3 is UDMA66 for now */
 	static struct ata_port_info info_c3 = {
 		.sht = &ali_sht,
 		.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_PIO_LBA48,
 		.pio_mask = 0x1f,
 		.mwdma_mask = 0x07,
-		.udma_mask = 0x3f,
+		.udma_mask = 0x1f,
 		.port_ops = &ali_c2_port_ops
 	};
-	/* Revision 0xC4 is UDMA133 */
+	/* Revision 0xC4 is UDMA100 */
 	static struct ata_port_info info_c4 = {
 		.sht = &ali_sht,
 		.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST | ATA_FLAG_PIO_LBA48,
 		.pio_mask = 0x1f,
 		.mwdma_mask = 0x07,
-		.udma_mask = 0x7f,
+		.udma_mask = 0x3f,
 		.port_ops = &ali_c2_port_ops
 	};
 	/* Revision 0xC5 is UDMA133 with LBA48 DMA */

linux-2.6-lirc.patch:

--- NEW FILE linux-2.6-lirc.patch ---
diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig
index 2d87357..61fd0ca 100644
--- a/drivers/input/Kconfig
+++ b/drivers/input/Kconfig
@@ -183,5 +183,7 @@ source "drivers/input/gameport/Kconfig"
 
 endmenu
 
+source "drivers/input/lirc/Kconfig"
+
 endmenu
 
diff --git a/drivers/input/Makefile b/drivers/input/Makefile
index 15eb752..195d342 100644
--- a/drivers/input/Makefile
+++ b/drivers/input/Makefile
@@ -22,4 +22,4 @@ obj-$(CONFIG_INPUT_JOYSTICK)	+= joystick/
 obj-$(CONFIG_INPUT_TABLET)	+= tablet/
 obj-$(CONFIG_INPUT_TOUCHSCREEN)	+= touchscreen/
 obj-$(CONFIG_INPUT_MISC)	+= misc/
-
+obj-$(CONFIG_INPUT_LIRC)	+= lirc/
diff --git a/drivers/input/lirc/Kconfig b/drivers/input/lirc/Kconfig
new file mode 100644
index 0000000..138e58a
--- /dev/null
+++ b/drivers/input/lirc/Kconfig
@@ -0,0 +1,127 @@
+#
+# LIRC driver(s) configuration
+#
+menuconfig INPUT_LIRC
+	bool "Linux Infrared Remote Control IR receiver/transmitter drivers"
+	default n
+	help
+	  Say Y here, and all supported Linux Infrared Remote Control IR and
+	  RF receiver and transmitter drivers will be displayed. When paired
+	  with a remote control and the lirc daemon, the receiver drivers
+	  allow control of your Linux system via remote control.
+
+if INPUT_LIRC
+
+config LIRC_DEV
+	tristate "LIRC device loadable module support"
+	default m
+	help
+	  LIRC device loadable module support, required for most LIRC drivers
+
+config LIRC_ATIUSB
+	tristate "ATI RF USB Receiver support"
+	default m
+	depends on LIRC_DEV
+	help
+	  Driver for the ATI USB RF remote receiver
+
+config LIRC_BT829
+        tristate "BT829 based hardware"
+	default m
+	depends on LIRC_DEV
+	help
+	  Driver for the IR interface on BT829-based hardware
+
+config LIRC_CMDIR
+	tristate "CommandIR USB Transceiver"
+	default m
+	depends on LIRC_DEV
+	help
+	  Driver for the CommandIR USB Transceiver
+
+config LIRC_I2C
+	tristate "I2C Based IR Receivers"
+	default m
+	depends on LIRC_DEV
+	help
+	  Driver for I2C-based IR receivers, such as those commonly
+	  found onboard Hauppauge PVR-150/250/350 video capture cards
+
+config LIRC_IGORPLUGUSB
+	tristate "Igor Cesko's USB IR Receiver"
+	default m
+	depends on LIRC_DEV
+	help
+	  Driver for Igor Cesko's USB IR Receiver
+
+config LIRC_IMON
+	tristate "Soundgraph IMON Receiver"
+	default m
+	depends on LIRC_DEV
+	help
+	  Driver for the Soundgraph IMON IR Receiver
+
+config LIRC_IT87
+	tristate "ITE IT87XX CIR Port Receiver"
+	default m
+	depends on LIRC_DEV
+	help
+	  Driver for the ITE IT87xx IR Receiver
+
+config LIRC_MCEUSB
+	tristate "Microsoft Media Center Ed. Receiver, v1"
+	default m
+	depends on LIRC_DEV
+	help
+	  Driver for the Microsoft Media Center Ed. Receiver, v1
+
+config LIRC_MCEUSB2
+	tristate "Microsoft Media Center Ed. Receiver, v2"
+	default m
+	depends on LIRC_DEV
+	help
+	  Driver for the Microsoft Media Center Ed. Receiver, v2
+
+config LIRC_PVR150
+	tristate "Hauppauge PVR-XXX Transmitter"
+	default m
+	depends on LIRC_DEV
+	help
+	  Driver for the Hauppauge PVR-150/250/350/500 IR Transmitter
+
+config LIRC_PARALLEL
+	tristate "Homebrew Parallel Port Receiver"
+	default m
+	depends on LIRC_DEV && !SMP
+	help
+	  Driver for Homebrew Parallel Port Receivers
+
+config LIRC_SERIAL
+	tristate "Homebrew Serial Port Receiver"
+	default m
+	depends on LIRC_DEV
+	help
+	  Driver for Homebrew Serial Port Receivers
+
+config LIRC_SIR
+	tristate "Built-in SIR IrDA port"
+	default m
+	depends on LIRC_DEV
+	help
+	  Driver for the SIR IrDA port
+
+config LIRC_STREAMZAP
+	tristate "Streamzap PC Receiver"
+	default m
+	depends on LIRC_DEV
+	help
+	  Driver for the Streamzap PC Receiver
+
+config LIRC_TTUSBIR
+	tristate "Technotrend USB IR Receiver"
+	default m
+	depends on LIRC_DEV
+	help
+	  Driver for the Technotrend USB IR Receiver
+
+endif
diff --git a/drivers/input/lirc/Makefile b/drivers/input/lirc/Makefile
new file mode 100644
index 0000000..71124ef
--- /dev/null
+++ b/drivers/input/lirc/Makefile
@@ -0,0 +1,24 @@
+# Makefile for the lirc drivers.
+#
+
+# Each configuration option enables a list of files.
+
+EXTRA_CFLAGS =-DIRCTL_DEV_MAJOR=61 -DLIRC_SERIAL_TRANSMITTER -I$(src)
+
+obj-$(CONFIG_LIRC_DEV)		+= lirc_dev.o
+obj-$(CONFIG_LIRC_ATIUSB)	+= lirc_atiusb.o
+obj-$(CONFIG_LIRC_BT829)	+= lirc_bt829.o
+obj-$(CONFIG_LIRC_CMDIR)	+= lirc_cmdir.o commandir.o
+obj-$(CONFIG_LIRC_I2C)		+= lirc_i2c.o
+obj-$(CONFIG_LIRC_IGORPLUGUSB)	+= lirc_igorplugusb.o
+obj-$(CONFIG_LIRC_IMON)		+= lirc_imon.o
+obj-$(CONFIG_LIRC_IT87)		+= lirc_it87.o
+obj-$(CONFIG_LIRC_MCEUSB)	+= lirc_mceusb.o
+obj-$(CONFIG_LIRC_MCEUSB2)	+= lirc_mceusb2.o
+obj-$(CONFIG_LIRC_PVR150)	+= lirc_pvr150.o
+obj-$(CONFIG_LIRC_PARALLEL)	+= lirc_parallel.o
+obj-$(CONFIG_LIRC_SASEM)	+= lirc_sasem.o
+obj-$(CONFIG_LIRC_SERIAL)	+= lirc_serial.o
+obj-$(CONFIG_LIRC_SIR)		+= lirc_sir.o
+obj-$(CONFIG_LIRC_STREAMZAP)	+= lirc_streamzap.o
+obj-$(CONFIG_LIRC_TTUSBIR)	+= lirc_ttusbir.o
diff --git a/drivers/input/lirc/commandir.c b/drivers/input/lirc/commandir.c
new file mode 100644
index 0000000..32f46aa
--- /dev/null
+++ b/drivers/input/lirc/commandir.c
@@ -0,0 +1,999 @@
+
+/*
+ *
+ *	Hardware Driver for COMMANDIR USB Transceiver
+ *	2005-2007 InnovationOne - Matt Bodkin, Evelyn Yeung
+ *
+ *	Version 1.4.2
+ *	For 2.4.* or 2.6.* kernel versions
[...17690 lines suppressed...]
+};
+
+static void urb_complete(struct urb *urb)
+{
+	struct ttusbir_device *ttusbir;
+	unsigned char *buf;
+	int i;
+	lirc_t l;
+
+	ttusbir = urb->context;
+
+	if (!ttusbir->opened)
+		return;
+
+	buf = (unsigned char *)urb->transfer_buffer;
+
+	for (i = 0; i < 128; i++) {
+		buf[i] = ~map_table[buf[i]];
+		if (ttusbir->last_pulse == buf[i]) {
+			if (ttusbir->last_num < PULSE_MASK/63)
+				ttusbir->last_num++;
+		/* else we are in a idle period and do not need to
+		 * increment any longer */
+		} else {
+			l = ttusbir->last_num * 62; /* about 62 = us/byte */
+			if (ttusbir->last_pulse) /* pulse or space? */
+				l |= PULSE_BIT;
+			if (!lirc_buffer_full(&ttusbir->rbuf)) {
+				lirc_buffer_write_1(&ttusbir->rbuf, (void *)&l);
+				wake_up_interruptible(&ttusbir->rbuf.wait_poll);
+			}
+			ttusbir->last_num = 0;
+			ttusbir->last_pulse = buf[i];
+		}
+	}
+	usb_submit_urb(urb, GFP_ATOMIC); /* keep data rolling :-) */
+}
+
+/* Called whenever the USB subsystem thinks we could be the right driver
+   to handle this device
+*/
+static int probe(struct usb_interface *intf, const struct usb_device_id *id)
+{
+	int alt_set, endp;
+	int found = 0;
+	int i, j;
+	struct usb_host_interface *host_interf;
+	struct usb_interface_descriptor *interf_desc;
+	struct usb_host_endpoint *host_endpoint;
+	struct ttusbir_device *ttusbir;
+
+	DPRINTK("Module ttusbir probe\n");
+
+	ttusbir = (struct ttusbir_device *)
+		  kzalloc(sizeof(struct ttusbir_device), GFP_KERNEL);
+	if (!ttusbir)
+		return -ENOMEM;
+	ttusbir->driver = &driver;
+	ttusbir->alt_setting = -1;
+	ttusbir->udev = usb_get_dev(interface_to_usbdev(intf));
+	ttusbir->interf = intf;
+	ttusbir->last_pulse = 0x00;
+	ttusbir->last_num = 0;
+
+	/* Now look for interface setting we can handle
+	   We are searching for the alt setting where end point
+	   0x82 has max packet size 16
+	*/
+	for (alt_set = 0; alt_set < intf->num_altsetting && !found; alt_set++) {
+		host_interf = &intf->altsetting[alt_set];
+		interf_desc = &host_interf->desc;
+		for (endp = 0; endp < interf_desc->bNumEndpoints; endp++) {
+			host_endpoint = &host_interf->endpoint[endp];
+			if ((host_endpoint->desc.bEndpointAddress == 0x82) &&
+			    (host_endpoint->desc.wMaxPacketSize == 0x10)) {
+				ttusbir->alt_setting = alt_set;
+				ttusbir->endpoint = endp;
+				found = 1;
+				break;
+			}
+		}
+	}
+	if (ttusbir->alt_setting != -1)
+		DPRINTK("alt setting: %d\n", ttusbir->alt_setting);
+	else {
+		err("Could not find alternate setting\n");
+		kfree(ttusbir);
+		return -EINVAL;
+	}
+
+	/* OK lets setup this interface setting */
+	usb_set_interface(ttusbir->udev, 0, ttusbir->alt_setting);
+
+	/* Store device info in interface structure */
+	usb_set_intfdata(intf, ttusbir);
+
+	/* Register as a LIRC plugin */
+	if (lirc_buffer_init(&ttusbir->rbuf, sizeof(lirc_t), 256) < 0) {
+		err("Could not get memory for LIRC data buffer\n");
+		usb_set_intfdata(intf, NULL);
+		kfree(ttusbir);
+		return -ENOMEM;
+	}
+	strcpy(ttusbir->plugin.name, "TTUSBIR");
+	ttusbir->plugin.minor = -1;
+	ttusbir->plugin.code_length = 1;
+	ttusbir->plugin.sample_rate = 0;
+	ttusbir->plugin.data = ttusbir;
+	ttusbir->plugin.add_to_buf = NULL;
+	ttusbir->plugin.get_queue = NULL;
+	ttusbir->plugin.rbuf = &ttusbir->rbuf;
+	ttusbir->plugin.set_use_inc = set_use_inc;
+	ttusbir->plugin.set_use_dec = set_use_dec;
+	ttusbir->plugin.ioctl = NULL;
+	ttusbir->plugin.fops = NULL;
+	ttusbir->plugin.owner = THIS_MODULE;
+	ttusbir->plugin.features = LIRC_CAN_REC_MODE2;
+	ttusbir->minor = lirc_register_plugin(&ttusbir->plugin);
+	if (ttusbir->minor < 0) {
+		err("Error registering as LIRC plugin\n");
+		usb_set_intfdata(intf, NULL);
+		lirc_buffer_free(&ttusbir->rbuf);
+		kfree(ttusbir);
+		return -EIO;
+	}
+
+	/* Allocate and setup the URB that we will use to talk to the device */
+	for (i = 0; i < NUM_URBS; i++) {
+		ttusbir->urb[i] = usb_alloc_urb(8, GFP_KERNEL);
+		if (!ttusbir->urb[i]) {
+			err("Could not allocate memory for the URB\n");
+			for (j = i - 1; j >= 0; j--)
+				kfree(ttusbir->urb[j]);
+			lirc_buffer_free(&ttusbir->rbuf);
+			lirc_unregister_plugin(ttusbir->minor);
+			kfree(ttusbir);
+			usb_set_intfdata(intf, NULL);
+			return -ENOMEM;
+		}
+		ttusbir->urb[i]->dev = ttusbir->udev;
+		ttusbir->urb[i]->context = ttusbir;
+		ttusbir->urb[i]->pipe = usb_rcvisocpipe(ttusbir->udev,
+							ttusbir->endpoint);
+		ttusbir->urb[i]->interval = 1;
+		ttusbir->urb[i]->transfer_flags = URB_ISO_ASAP;
+		ttusbir->urb[i]->transfer_buffer = &ttusbir->buffer[i][0];
+		ttusbir->urb[i]->complete = urb_complete;
+		ttusbir->urb[i]->number_of_packets = 8;
+		ttusbir->urb[i]->transfer_buffer_length = 128;
+		for (j = 0; j < 8; j++) {
+			ttusbir->urb[i]->iso_frame_desc[j].offset = j*16;
+			ttusbir->urb[i]->iso_frame_desc[j].length = 16;
+		}
+	}
+	return 0;
+}
+
+/* Called when the driver is unloaded or the device is unplugged
+ */
+static void disconnect(struct usb_interface *intf)
+{
+	int i;
+	struct ttusbir_device *ttusbir;
+
+	DPRINTK("Module ttusbir disconnect\n");
+
+	lock_kernel();
+	ttusbir = (struct ttusbir_device *) usb_get_intfdata(intf);
+	usb_set_intfdata(intf, NULL);
+	lirc_unregister_plugin(ttusbir->minor);
+	unlock_kernel();
+
+	for (i = 0; i < NUM_URBS; i++)
+		usb_free_urb(ttusbir->urb[i]);
+	lirc_buffer_free(&ttusbir->rbuf);
+	kfree(ttusbir);
+}
+
+static int ttusbir_init_module(void)
+{
+	int result;
+
+	DPRINTK(KERN_DEBUG "Module ttusbir init\n");
+
+	/* register this driver with the USB subsystem */
+	result = usb_register(&driver);
+	if (result)
+		err("usb_register failed. Error number %d", result);
+	return result;
+}
+
+static void ttusbir_exit_module(void)
+{
+	printk(KERN_DEBUG "Module ttusbir exit\n");
+	/* deregister this driver with the USB subsystem */
+	usb_deregister(&driver);
+}
+
+module_init(ttusbir_init_module);
+module_exit(ttusbir_exit_module);

linux-2.6-mac80211-extras.patch:

--- NEW FILE linux-2.6-mac80211-extras.patch ---
diff -up linux-2.6.22.noarch/include/linux/ieee80211.h.orig linux-2.6.22.noarch/include/linux/ieee80211.h
--- linux-2.6.22.noarch/include/linux/ieee80211.h.orig	2007-09-26 20:24:17.000000000 -0400
+++ linux-2.6.22.noarch/include/linux/ieee80211.h	2007-09-26 20:24:22.000000000 -0400
@@ -106,6 +106,75 @@ struct ieee80211_hdr {
 } __attribute__ ((packed));
 
 
+struct ieee80211_ht_capability {
+	__le16 capabilities_info;
+	u8 mac_ht_params_info;
+	u8 supported_mcs_set[16];
+	__le16 extended_ht_capability_info;
+	__le32 tx_BF_capability_info;
+	u8 antenna_selection_info;
+}__attribute__ ((packed));
+
+struct ieee80211_ht_additional_info {
+	u8 control_chan;
+	u8 ht_param;
+	__le16 operation_mode;
+	__le16 stbc_param;
+	u8 basic_set[16];
+}__attribute__ ((packed));
+
+
+#define IEEE80211_TSINFO_TYPE(a)	((a.byte1 & 0x01) >> 0)
+#define IEEE80211_TSINFO_TSID(a)	((a.byte1 & 0x1E) >> 1)
+#define IEEE80211_TSINFO_DIR(a)		((a.byte1 & 0x60) >> 5)
+#define IEEE80211_TSINFO_POLICY(a)	((a.byte1 & 0x80) >> 7 + \
+					 (a.byte2 & 0x01) << 1)
+#define IEEE80211_TSINFO_AGG(a)		((a.byte2 & 0x02) >> 1)
+#define IEEE80211_TSINFO_APSD(a)	((a.byte2 & 0x04) >> 2)
+#define IEEE80211_TSINFO_UP(a)		((a.byte2 & 0x38) >> 3)
+#define IEEE80211_TSINFO_ACK(a)		((a.byte2 & 0xC0) >> 6)
+#define IEEE80211_TSINFO_SCHEDULE(a)	((a.byte3 & 0x01) >> 0)
+
+#define IEEE80211_SET_TSINFO_TYPE(i, d)		(i.byte1 |= (d << 0) & 0x01)
+#define IEEE80211_SET_TSINFO_TSID(i, d)		(i.byte1 |= (d << 1) & 0x1E)
+#define IEEE80211_SET_TSINFO_DIR(i, d)		(i.byte1 |= (d << 5) & 0x60)
+#define IEEE80211_SET_TSINFO_POLICY(i, d)	\
+do {						\
+						i.byte1 |= (d & 0x01) << 7; \
+						i.byte2 |= (d & 0x02) >> 1; \
+} while(0)
+#define IEEE80211_SET_TSINFO_AGG(i, d)		(i.byte2 |= (d << 1) & 0x02)
+#define IEEE80211_SET_TSINFO_APSD(i, d)		(i.byte2 |= (d << 2) & 0x04)
+#define IEEE80211_SET_TSINFO_UP(i, d)		(i.byte2 |= (d << 3) & 0x38)
+#define IEEE80211_SET_TSINFO_ACK(i, d)		(i.byte2 |= (d << 6) & 0xC0)
+#define IEEE80211_SET_TSINFO_SCHEDULE(i, d)	(i.byte3 |= (d << 0) & 0x01)
+
+struct ieee80211_ts_info {
+	u8 byte1;
+	u8 byte2;
+	u8 byte3;
+} __attribute__ ((packed));
+
+struct ieee80211_elem_tspec {
+	struct ieee80211_ts_info ts_info;
+	__le16 nominal_msdu_size;
+	__le16 max_msdu_size;
+	__le32 min_service_interval;
+	__le32 max_service_interval;
+	__le32 inactivity_interval;
+	__le32 suspension_interval;
+	__le32 service_start_time;
+	__le32 min_data_rate;
+	__le32 mean_data_rate;
+	__le32 peak_data_rate;
+	__le32 burst_size;
+	__le32 delay_bound;
+	__le32 min_phy_rate;
+	__le16 surplus_band_allow;
+	__le16 medium_time;
+} __attribute__ ((packed));
+
+
 struct ieee80211_mgmt {
 	__le16 frame_control;
 	__le16 duration;
@@ -173,9 +242,51 @@ struct ieee80211_mgmt {
 				struct {
 					u8 action_code;
 					u8 dialog_token;
+					u8 variable[0];
+				} __attribute__ ((packed)) addts_req;
+				struct {
+					u8 action_code;
+					u8 dialog_token;
+					__le16 status_code;
+					u8 variable[0];
+				} __attribute__ ((packed)) addts_resp;
+				struct {
+					u8 action_code;
+					struct ieee80211_ts_info ts_info;
+					__le16 reason_code;
+				} __attribute__ ((packed)) delts;
+				struct {
+					u8 action_code;
+					u8 dialog_token;
 					u8 status_code;
 					u8 variable[0];
 				} __attribute__ ((packed)) wme_action;
+				struct {
+					u8 action_code;
+					u8 dest[6];
+					u8 src[6];
+					__le16 capab_info;
+					__le16 timeout;
+					/* Followed by Supported Rates and
+					 * Extended Supported Rates */
+					u8 variable[0];
+				} __attribute__ ((packed)) dls_req;
+				struct {
+					u8 action_code;
+					__le16 status_code;
+					u8 dest[6];
+					u8 src[6];
+					/* Followed by Capability Information,
+					 * Supported Rates and Extended
+					 * Supported Rates */
+					u8 variable[0];
+				} __attribute__ ((packed)) dls_resp;
+				struct {
+					u8 action_code;
+					u8 dest[6];
+					u8 src[6];
+					__le16 reason_code;
+				} __attribute__ ((packed)) dls_teardown;
 				struct{
 					u8 action_code;
 					u8 element_id;
@@ -184,6 +295,25 @@ struct ieee80211_mgmt {
 					u8 new_chan;
 					u8 switch_count;
 				} __attribute__((packed)) chan_switch;
+				struct{
+					u8 action_code;
+					u8 dialog_token;
+					__le16 capab;
+					__le16 timeout;
+					__le16 start_seq_num;
+				} __attribute__((packed)) addba_req;
+				struct{
+					u8 action_code;
+					u8 dialog_token;
+					__le16 status;
+					__le16 capab;
+					__le16 timeout;
+				} __attribute__((packed)) addba_resp;
+				struct{
+					u8 action_code;
+					__le16 params;
+					__le16 reason_code;
+				}__attribute__((packed)) delba;
 			} u;
 		} __attribute__ ((packed)) action;
 	} u;
@@ -270,6 +400,18 @@ enum ieee80211_statuscode {
 	WLAN_STATUS_UNSUPP_RSN_VERSION = 44,
 	WLAN_STATUS_INVALID_RSN_IE_CAP = 45,
 	WLAN_STATUS_CIPHER_SUITE_REJECTED = 46,
+	/* 802.11e */
+	WLAN_STATUS_UNSPECIFIED_QOS = 32,
+	WLAN_STATUS_ASSOC_DENIED_NOBANDWIDTH = 33,
+	WLAN_STATUS_ASSOC_DENIED_LOWACK = 34,
+	WLAN_STATUS_ASSOC_DENIED_UNSUPP_QOS = 35,
+	WLAN_STATUS_REQUEST_DECLINED = 37,
+	WLAN_STATUS_INVALID_QOS_PARAM = 38,
+	WLAN_STATUS_CHANGE_TSPEC = 39,
+	WLAN_STATUS_WAIT_TS_DELAY = 47,
+	WLAN_STATUS_NO_DIRECT_LINK = 48,
+	WLAN_STATUS_STA_NOT_PRESENT = 49,
+	WLAN_STATUS_STA_NOT_QSTA = 50,
 };
 
 
@@ -300,9 +442,50 @@ enum ieee80211_reasoncode {
 	WLAN_REASON_INVALID_RSN_IE_CAP = 22,
 	WLAN_REASON_IEEE8021X_FAILED = 23,
 	WLAN_REASON_CIPHER_SUITE_REJECTED = 24,
+	/* 802.11e */
+	WLAN_REASON_DISASSOC_UNSPECIFIED_QOS = 32,
+	WLAN_REASON_DISASSOC_QAP_NO_BANDWIDTH = 33,
+	WLAN_REASON_DISASSOC_LOW_ACK = 34,
+	WLAN_REASON_DISASSOC_QAP_EXCEED_TXOP = 35,
+	WLAN_REASON_QSTA_LEAVE_QBSS = 36,
+	WLAN_REASON_QSTA_NOT_USE = 37,
+	WLAN_REASON_QSTA_REQUIRE_SETUP = 38,
+	WLAN_REASON_QSTA_TIMEOUT = 39,
+	WLAN_REASON_QSTA_CIPHER_NOT_SUPP = 45,
 };
 
 
+/* Category Code */
+enum ieee80211_category {
+	WLAN_CATEGORY_SPECTRUM_MGMT = 0,
+	WLAN_CATEGORY_QOS = 1,
+	WLAN_CATEGORY_DLS = 2,
+	WLAN_CATEGORY_BACK = 3,
[...3755 lines suppressed...]
+			printk(" %02x", mic[i]);
+		printk("\n");
+		printk(KERN_DEBUG "   SA=" MAC_FMT " DA=" MAC_FMT " key",
+		       MAC_ARG(sa), MAC_ARG(da));
+		for (i = 0; i < 8; i++)
+			printk(" %02x", key[i]);
+		printk(" (%d)\n", authenticator);
+#endif /* CONFIG_HOSTAPD_WPA_TESTING */
 
 		mac80211_ev_michael_mic_failure(rx->dev, rx->key->conf.keyidx,
 						(void *) skb->data);
@@ -208,12 +271,30 @@ static int tkip_encrypt_skb(struct ieee8
 	memmove(pos, pos + TKIP_IV_LEN, hdrlen);
 	pos += hdrlen;
 
+#ifdef CONFIG_HOSTAPD_WPA_TESTING
+	if (test & WPA_TRIGGER_TX_REPLAY)
+		goto skip_iv_inc;
+iv_inc:
+#endif /* CONFIG_HOSTAPD_WPA_TESTING */
+
 	/* Increase IV for the frame */
 	key->u.tkip.iv16++;
 	if (key->u.tkip.iv16 == 0)
 		key->u.tkip.iv32++;
 
-	if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) {
+#ifdef CONFIG_HOSTAPD_WPA_TESTING
+	if (test & WPA_TRIGGER_TX_SKIP_SEQ) {
+		test = 0;
+		goto iv_inc;
+	}
+skip_iv_inc:
+#endif /* CONFIG_HOSTAPD_WPA_TESTING */
+
+	if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE
+#ifdef CONFIG_HOSTAPD_WPA_TESTING
+	    && !tx->wpa_test
+#endif /* CONFIG_HOSTAPD_WPA_TESTING */
+		) {
 		hdr = (struct ieee80211_hdr *)skb->data;
 
 		/* hwaccel - with preallocated room for IV */
@@ -255,6 +336,37 @@ ieee80211_tx_h_tkip_encrypt(struct ieee8
 	tx->u.tx.control->iv_len = TKIP_IV_LEN;
 	ieee80211_tx_set_iswep(tx);
 
+#ifdef CONFIG_HOSTAPD_WPA_TESTING
+	if ((tx->sta && tx->sta->wpa_trigger & WPA_TRIGGER_FAIL_TX_ICV) ||
+	    (!(tx->flags & IEEE80211_TXRXD_TXUNICAST) &&
+	     tx->local->wpa_trigger & WPA_TRIGGER_FAIL_TX_ICV)) {
+		wpa_test = 1;
+	}
+
+	if (tx->sta) {
+		test = tx->sta->wpa_trigger;
+		tx->sta->wpa_trigger &=
+			~(WPA_TRIGGER_TX_REPLAY | WPA_TRIGGER_TX_REPLAY_FRAG |
+			  WPA_TRIGGER_TX_SKIP_SEQ);
+	} else {
+		test = tx->local->wpa_trigger;
+		tx->local->wpa_trigger &=
+			~(WPA_TRIGGER_TX_REPLAY | WPA_TRIGGER_TX_REPLAY_FRAG |
+			  WPA_TRIGGER_TX_SKIP_SEQ);
+	}
+	if (test &
+	    (WPA_TRIGGER_TX_REPLAY | WPA_TRIGGER_TX_REPLAY_FRAG |
+	     WPA_TRIGGER_TX_SKIP_SEQ)) {
+		printk(KERN_INFO "%s: WPA testing - TKIP TX packet number "
+		       "%s%s%s%s\n", tx->dev->name,
+		       tx->sta ? "[UNICAST]" : "[MULTICAST]",
+		       test & WPA_TRIGGER_TX_REPLAY ? "[REPLAY]" : "",
+		       test & WPA_TRIGGER_TX_REPLAY_FRAG ?
+		       "[REPLAY FRAG]" : "",
+		       test & WPA_TRIGGER_TX_SKIP_SEQ ? "[SKIP SEQ]" : "");
+	}
+#endif /* CONFIG_HOSTAPD_WPA_TESTING */
+
 	if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) &&
 	    !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) &&
 	    !wpa_test) {
@@ -268,6 +380,10 @@ ieee80211_tx_h_tkip_encrypt(struct ieee8
 
 	if (tx->u.tx.extra_frag) {
 		int i;
+#ifdef CONFIG_HOSTAPD_WPA_TESTING
+		if (test & WPA_TRIGGER_TX_REPLAY_FRAG)
+			test |= WPA_TRIGGER_TX_REPLAY;
+#endif /* CONFIG_HOSTAPD_WPA_TESTING */
 		for (i = 0; i < tx->u.tx.num_extra_frag; i++) {
 			if (tkip_encrypt_skb(tx, tx->u.tx.extra_frag[i], test)
 			    < 0)
@@ -275,6 +391,23 @@ ieee80211_tx_h_tkip_encrypt(struct ieee8
 		}
 	}
 
+#ifdef CONFIG_HOSTAPD_WPA_TESTING
+	if (tx->sta && tx->sta->wpa_trigger & WPA_TRIGGER_FAIL_TX_ICV) {
+		printk(KERN_INFO "%s: WPA testing - corrupting TX TKIP ICV "
+		       "for STA " MAC_FMT "\n",
+		       tx->dev->name, MAC_ARG(tx->sta->addr));
+		tx->sta->wpa_trigger &= ~WPA_TRIGGER_FAIL_TX_ICV;
+		skb->data[skb->len - 1]++;
+	} else if (!(tx->flags & IEEE80211_TXRXD_TXUNICAST) &&
+		   tx->local->wpa_trigger & WPA_TRIGGER_FAIL_TX_ICV) {
+		printk(KERN_INFO "%s: WPA testing - corrupting TX TKIP ICV "
+		       "for Group Key\n",
+		       tx->dev->name);
+		tx->local->wpa_trigger &= ~WPA_TRIGGER_FAIL_TX_ICV;
+		skb->data[skb->len - 1]++;
+	}
+#endif /* CONFIG_HOSTAPD_WPA_TESTING */
+
 	return TXRX_CONTINUE;
 }
 
@@ -299,6 +432,17 @@ ieee80211_rx_h_tkip_decrypt(struct ieee8
 	if (!rx->sta || skb->len - hdrlen < 12)
 		return TXRX_DROP;
 
+#ifdef CONFIG_HOSTAPD_WPA_TESTING
+	if (rx->sta && rx->sta->wpa_trigger & WPA_TRIGGER_FAIL_RX_ICV) {
+		printk(KERN_INFO "%s: WPA testing - corrupting RX TKIP ICV "
+		       "for STA " MAC_FMT "\n",
+		       rx->dev->name, MAC_ARG(rx->sta->addr));
+		rx->sta->wpa_trigger &= ~WPA_TRIGGER_FAIL_RX_ICV;
+		skb->data[skb->len - 1]++;
+		wpa_test = 1;
+	}
+#endif /* CONFIG_HOSTAPD_WPA_TESTING */
+
 	if (rx->u.rx.status->flag & RX_FLAG_DECRYPTED) {
 		if (rx->u.rx.status->flag & RX_FLAG_IV_STRIPPED) {
 			/*
@@ -467,12 +611,26 @@ static int ccmp_encrypt_skb(struct ieee8
 	/* PN = PN + 1 */
 	pn = key->u.ccmp.tx_pn;
 
+#ifdef CONFIG_HOSTAPD_WPA_TESTING
+	if (test & WPA_TRIGGER_TX_REPLAY)
+		goto skip_pn_inc;
+pn_inc:
+#endif /* CONFIG_HOSTAPD_WPA_TESTING */
+
 	for (i = CCMP_PN_LEN - 1; i >= 0; i--) {
 		pn[i]++;
 		if (pn[i])
 			break;
 	}
 
+#ifdef CONFIG_HOSTAPD_WPA_TESTING
+	if (test & WPA_TRIGGER_TX_SKIP_SEQ) {
+		test = 0;
+		goto pn_inc;
+	}
+skip_pn_inc:
+#endif /* CONFIG_HOSTAPD_WPA_TESTING */
+
 	ccmp_pn2hdr(pos, pn, key->conf.keyidx);
 
 	if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) {
@@ -504,6 +662,27 @@ ieee80211_tx_h_ccmp_encrypt(struct ieee8
 	if (!key || key->conf.alg != ALG_CCMP || !WLAN_FC_DATA_PRESENT(fc))
 		return TXRX_CONTINUE;
 
+#ifdef CONFIG_HOSTAPD_WPA_TESTING
+	if (tx->sta) {
+		test = tx->sta->wpa_trigger;
+		tx->sta->wpa_trigger = 0;
+	} else {
+		test = tx->local->wpa_trigger;
+		tx->local->wpa_trigger = 0;
+	}
+	if (test &
+	    (WPA_TRIGGER_TX_REPLAY | WPA_TRIGGER_TX_REPLAY_FRAG |
+	     WPA_TRIGGER_TX_SKIP_SEQ)) {
+		printk(KERN_INFO "%s: WPA testing - CCMP TX packet number "
+		       "%s%s%s%s\n", tx->dev->name,
+		       tx->sta ? "[UNICAST]" : "[MULTICAST]",
+		       test & WPA_TRIGGER_TX_REPLAY ? "[REPLAY]" : "",
+		       test & WPA_TRIGGER_TX_REPLAY_FRAG ?
+		       "[REPLAY FRAG]" : "",
+		       test & WPA_TRIGGER_TX_SKIP_SEQ ? "[SKIP SEQ]" : "");
+	}
+#endif /* CONFIG_HOSTAPD_WPA_TESTING */
+
 	tx->u.tx.control->icv_len = CCMP_MIC_LEN;
 	tx->u.tx.control->iv_len = CCMP_HDR_LEN;
 	ieee80211_tx_set_iswep(tx);
@@ -521,6 +700,10 @@ ieee80211_tx_h_ccmp_encrypt(struct ieee8
 
 	if (tx->u.tx.extra_frag) {
 		int i;
+#ifdef CONFIG_HOSTAPD_WPA_TESTING
+		if (test & WPA_TRIGGER_TX_REPLAY_FRAG)
+			test |= WPA_TRIGGER_TX_REPLAY;
+#endif /* CONFIG_HOSTAPD_WPA_TESTING */
 		for (i = 0; i < tx->u.tx.num_extra_frag; i++) {
 			if (ccmp_encrypt_skb(tx, tx->u.tx.extra_frag[i], test)
 			    < 0)

linux-2.6-mac80211-nm-hidden-ssid.patch:

--- NEW FILE linux-2.6-mac80211-nm-hidden-ssid.patch ---
diff -up linux-2.6.23.noarch/net/mac80211/ieee80211_ioctl.c.orig linux-2.6.23.noarch/net/mac80211/ieee80211_ioctl.c
--- linux-2.6.23.noarch/net/mac80211/ieee80211_ioctl.c.orig	2007-10-10 17:43:20.000000000 -0400
+++ linux-2.6.23.noarch/net/mac80211/ieee80211_ioctl.c	2007-10-10 17:49:04.000000000 -0400
@@ -1320,10 +1320,11 @@ static int ieee80211_ioctl_giwap(struct 
 
 static int ieee80211_ioctl_siwscan(struct net_device *dev,
 				   struct iw_request_info *info,
-				   struct iw_point *data, char *extra)
+				   union iwreq_data *wrqu, 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;
 
@@ -1332,6 +1333,14 @@ static int ieee80211_ioctl_siwscan(struc
 
 	switch (sdata->type) {
 	case IEEE80211_IF_TYPE_STA:
+		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;
+			break;
+		}
+		/* else fall-through */
 	case IEEE80211_IF_TYPE_IBSS:
 		if (local->scan_flags & IEEE80211_SCAN_MATCH_SSID) {
 			ssid = sdata->u.sta.ssid;

linux-2.6-mm-udf-fixes.patch:

--- NEW FILE linux-2.6-mm-udf-fixes.patch ---
Index: linux-2.6.20.noarch/fs/udf/dir.c
===================================================================
--- linux-2.6.20.noarch.orig/fs/udf/dir.c	2007-02-04 13:44:54.000000000 -0500
+++ linux-2.6.20.noarch/fs/udf/dir.c	2007-03-28 15:15:29.000000000 -0400
@@ -111,11 +111,13 @@ do_udf_readdir(struct inode * dir, struc
 	uint16_t liu;
 	uint8_t lfi;
 	loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2;
-	struct buffer_head * bh = NULL, * tmp, * bha[16];
-	kernel_lb_addr bloc, eloc;
-	uint32_t extoffset, elen, offset;
+	struct buffer_head *tmp, *bha[16];
+	kernel_lb_addr eloc;
+	uint32_t elen;
+	sector_t offset;
 	int i, num;
 	unsigned int dt_type;
+	struct extent_position epos = { NULL, 0, {0, 0}};
 
 	if (nf_pos >= size)
 		return 0;
@@ -127,23 +129,22 @@ do_udf_readdir(struct inode * dir, struc
 	if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_IN_ICB)
 		fibh.sbh = fibh.ebh = NULL;
 	else if (inode_bmap(dir, nf_pos >> (dir->i_sb->s_blocksize_bits - 2),
-		&bloc, &extoffset, &eloc, &elen, &offset, &bh) == (EXT_RECORDED_ALLOCATED >> 30))
+		&epos, &eloc, &elen, &offset) == (EXT_RECORDED_ALLOCATED >> 30))
 	{
-		offset >>= dir->i_sb->s_blocksize_bits;
 		block = udf_get_lb_pblock(dir->i_sb, eloc, offset);
 		if ((++offset << dir->i_sb->s_blocksize_bits) < elen)
 		{
 			if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_SHORT)
-				extoffset -= sizeof(short_ad);
+				epos.offset -= sizeof(short_ad);
 			else if (UDF_I_ALLOCTYPE(dir) == ICBTAG_FLAG_AD_LONG)
-				extoffset -= sizeof(long_ad);
+				epos.offset -= sizeof(long_ad);
 		}
 		else
 			offset = 0;
 
 		if (!(fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block)))
 		{
-			udf_release_data(bh);
+			brelse(epos.bh);
 			return -EIO;
 		}
 	
@@ -171,7 +172,7 @@ do_udf_readdir(struct inode * dir, struc
 	}
 	else
 	{
-		udf_release_data(bh);
+		brelse(epos.bh);
 		return -ENOENT;
 	}
 
@@ -179,14 +180,14 @@ do_udf_readdir(struct inode * dir, struc
 	{
 		filp->f_pos = nf_pos + 1;
 
-		fi = udf_fileident_read(dir, &nf_pos, &fibh, &cfi, &bloc, &extoffset, &eloc, &elen, &offset, &bh);
+		fi = udf_fileident_read(dir, &nf_pos, &fibh, &cfi, &epos, &eloc, &elen, &offset);
 
 		if (!fi)
 		{
 			if (fibh.sbh != fibh.ebh)
-				udf_release_data(fibh.ebh);
-			udf_release_data(fibh.sbh);
-			udf_release_data(bh);
+				brelse(fibh.ebh);
+			brelse(fibh.sbh);
+			brelse(epos.bh);
 			return 0;
 		}
 
@@ -244,9 +245,9 @@ do_udf_readdir(struct inode * dir, struc
 			if (filldir(dirent, fname, flen, filp->f_pos, iblock, dt_type) < 0)
 			{
 				if (fibh.sbh != fibh.ebh)
-					udf_release_data(fibh.ebh);
-				udf_release_data(fibh.sbh);
-				udf_release_data(bh);
+					brelse(fibh.ebh);
+				brelse(fibh.sbh);
+				brelse(epos.bh);
 	 			return 0;
 			}
 		}
@@ -255,9 +256,9 @@ do_udf_readdir(struct inode * dir, struc
 	filp->f_pos = nf_pos + 1;
 
 	if (fibh.sbh != fibh.ebh)
-		udf_release_data(fibh.ebh);
-	udf_release_data(fibh.sbh);
-	udf_release_data(bh);
+		brelse(fibh.ebh);
+	brelse(fibh.sbh);
+	brelse(epos.bh);
 
 	return 0;
 }
Index: linux-2.6.20.noarch/fs/udf/directory.c
===================================================================
--- linux-2.6.20.noarch.orig/fs/udf/directory.c	2007-02-04 13:44:54.000000000 -0500
+++ linux-2.6.20.noarch/fs/udf/directory.c	2007-03-28 15:15:29.000000000 -0400
@@ -36,14 +36,14 @@ udf_filead_read(struct inode *dir, uint8
 
 	if (!ad)
 	{
-		udf_release_data(*bh);
+		brelse(*bh);
 		*error = 1;
 		return NULL;
 	}
 
 	if (*offset == dir->i_sb->s_blocksize)
 	{
-		udf_release_data(*bh);
+		brelse(*bh);
 		block = udf_get_lb_pblock(dir->i_sb, fe_loc, ++*pos);
 		if (!block)
 			return NULL;
@@ -57,7 +57,7 @@ udf_filead_read(struct inode *dir, uint8
 		remainder = dir->i_sb->s_blocksize - loffset;
 		memcpy((uint8_t *)ad, (*bh)->b_data + loffset, remainder);
 
-		udf_release_data(*bh);
+		brelse(*bh);
 		block = udf_get_lb_pblock(dir->i_sb, fe_loc, ++*pos);
 		if (!block)
 			return NULL;
@@ -75,9 +75,9 @@ struct fileIdentDesc *
 udf_fileident_read(struct inode *dir, loff_t *nf_pos,
 	struct udf_fileident_bh *fibh,
 	struct fileIdentDesc *cfi,
-	kernel_lb_addr *bloc, uint32_t *extoffset, 
+	struct extent_position *epos,
 	kernel_lb_addr *eloc, uint32_t *elen,
-	uint32_t *offset, struct buffer_head **bh)
+	sector_t *offset)
 {
 	struct fileIdentDesc *fi;
 	int i, num, block;
@@ -105,13 +105,11 @@ udf_fileident_read(struct inode *dir, lo
 
 	if (fibh->eoffset == dir->i_sb->s_blocksize)
 	{
-		int lextoffset = *extoffset;
+		int lextoffset = epos->offset;
 
-		if (udf_next_aext(dir, bloc, extoffset, eloc, elen, bh, 1) !=
+		if (udf_next_aext(dir, epos, eloc, elen, 1) !=
 			(EXT_RECORDED_ALLOCATED >> 30))
-		{
 			return NULL;
-		}
 
 		block = udf_get_lb_pblock(dir->i_sb, *eloc, *offset);
 
@@ -120,9 +118,9 @@ udf_fileident_read(struct inode *dir, lo
 		if ((*offset << dir->i_sb->s_blocksize_bits) >= *elen)
 			*offset = 0;
 		else
-			*extoffset = lextoffset;
+			epos->offset = lextoffset;
 
-		udf_release_data(fibh->sbh);
+		brelse(fibh->sbh);
 		if (!(fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block)))
 			return NULL;
 		fibh->soffset = fibh->eoffset = 0;
@@ -151,7 +149,7 @@ udf_fileident_read(struct inode *dir, lo
 	}
 	else if (fibh->sbh != fibh->ebh)
 	{
-		udf_release_data(fibh->sbh);
+		brelse(fibh->sbh);
 		fibh->sbh = fibh->ebh;
 	}
 
@@ -169,13 +167,11 @@ udf_fileident_read(struct inode *dir, lo
 	}
 	else if (fibh->eoffset > dir->i_sb->s_blocksize)
 	{
-		int lextoffset = *extoffset;
+		int lextoffset = epos->offset;
 
-		if (udf_next_aext(dir, bloc, extoffset, eloc, elen, bh, 1) !=
+		if (udf_next_aext(dir, epos, eloc, elen, 1) !=
 			(EXT_RECORDED_ALLOCATED >> 30))
-		{
 			return NULL;
-		}
 
 		block = udf_get_lb_pblock(dir->i_sb, *eloc, *offset);
 
@@ -184,7 +180,7 @@ udf_fileident_read(struct inode *dir, lo
[...2583 lines suppressed...]
+		brelse(bh);
 	}
 	for (i=0; i<VDS_POS_LENGTH; i++)
 	{
@@ -1269,10 +1269,10 @@ udf_process_sequence(struct super_block 
 					gd = (struct generic_desc *)bh2->b_data;
 					if (ident == TAG_IDENT_PD)
 						udf_load_partdesc(sb, bh2);
-					udf_release_data(bh2);
+					brelse(bh2);
 				}
 			}
-			udf_release_data(bh);
+			brelse(bh);
 		}
 	}
 
@@ -1335,7 +1335,7 @@ udf_load_partition(struct super_block *s
 			reserve_e = reserve_e >> sb->s_blocksize_bits;
 			reserve_e += reserve_s;
 
-			udf_release_data(bh);
+			brelse(bh);
 
 			/* Process the main & reserve sequences */
 			/* responsible for finding the PartitionDesc(s) */
@@ -1405,12 +1405,14 @@ udf_load_partition(struct super_block *s
 
 					pos = udf_block_map(UDF_SB_VAT(sb), 0);
 					bh = sb_bread(sb, pos);
+					if (!bh)
+						return 1;
 					UDF_SB_TYPEVIRT(sb,i).s_start_offset =
 						le16_to_cpu(((struct virtualAllocationTable20 *)bh->b_data + udf_ext0_offset(UDF_SB_VAT(sb)))->lengthHeader) +
 							udf_ext0_offset(UDF_SB_VAT(sb));
 					UDF_SB_TYPEVIRT(sb,i).s_num_entries = (UDF_SB_VAT(sb)->i_size -
 						UDF_SB_TYPEVIRT(sb,i).s_start_offset) >> 2;
-					udf_release_data(bh);
+					brelse(bh);
 				}
 				UDF_SB_PARTROOT(sb,i) = udf_get_pblock(sb, 0, i, 0);
 				UDF_SB_PARTLEN(sb,i) = UDF_SB_PARTLEN(sb,ino.partitionReferenceNum);
@@ -1663,7 +1665,7 @@ static int udf_fill_super(struct super_b
 		iput(inode);
 		goto error_out;
 	}
-	sb->s_maxbytes = 1<<30;
+	sb->s_maxbytes = MAX_LFS_FILESIZE;
 	return 0;
 
 error_out:
@@ -1682,7 +1684,7 @@ error_out:
 		if (UDF_SB_PARTTYPE(sb, UDF_SB_PARTITION(sb)) == UDF_SPARABLE_MAP15)
 		{
 			for (i=0; i<4; i++)
-				udf_release_data(UDF_SB_TYPESPAR(sb, UDF_SB_PARTITION(sb)).s_spar_map[i]);
+				brelse(UDF_SB_TYPESPAR(sb, UDF_SB_PARTITION(sb)).s_spar_map[i]);
 		}
 	}
 #ifdef CONFIG_UDF_NLS
@@ -1691,7 +1693,7 @@ error_out:
 #endif
 	if (!(sb->s_flags & MS_RDONLY))
 		udf_close_lvid(sb);
-	udf_release_data(UDF_SB_LVIDBH(sb));
+	brelse(UDF_SB_LVIDBH(sb));
 	UDF_SB_FREE(sb);
 	kfree(sbi);
 	sb->s_fs_info = NULL;
@@ -1760,7 +1762,7 @@ udf_put_super(struct super_block *sb)
 		if (UDF_SB_PARTTYPE(sb, UDF_SB_PARTITION(sb)) == UDF_SPARABLE_MAP15)
 		{
 			for (i=0; i<4; i++)
-				udf_release_data(UDF_SB_TYPESPAR(sb, UDF_SB_PARTITION(sb)).s_spar_map[i]);
+				brelse(UDF_SB_TYPESPAR(sb, UDF_SB_PARTITION(sb)).s_spar_map[i]);
 		}
 	}
 #ifdef CONFIG_UDF_NLS
@@ -1769,7 +1771,7 @@ udf_put_super(struct super_block *sb)
 #endif
 	if (!(sb->s_flags & MS_RDONLY))
 		udf_close_lvid(sb);
-	udf_release_data(UDF_SB_LVIDBH(sb));
+	brelse(UDF_SB_LVIDBH(sb));
 	UDF_SB_FREE(sb);
 	kfree(sb->s_fs_info);
 	sb->s_fs_info = NULL;
@@ -1839,7 +1841,7 @@ udf_count_free_bitmap(struct super_block
 	}
 	else if (ident != TAG_IDENT_SBD)
 	{
-		udf_release_data(bh);
+		brelse(bh);
 		printk(KERN_ERR "udf: udf_count_free failed\n");
 		goto out;
 	}
@@ -1861,7 +1863,7 @@ udf_count_free_bitmap(struct super_block
 		}
 		if ( bytes )
 		{
-			udf_release_data(bh);
+			brelse(bh);
 			newblock = udf_get_lb_pblock(sb, loc, ++block);
 			bh = udf_tread(sb, newblock);
 			if (!bh)
@@ -1873,7 +1875,7 @@ udf_count_free_bitmap(struct super_block
 			ptr = (uint8_t *)bh->b_data;
 		}
 	}
-	udf_release_data(bh);
+	brelse(bh);
 
 out:
 	unlock_kernel();
@@ -1885,21 +1887,20 @@ static unsigned int
 udf_count_free_table(struct super_block *sb, struct inode * table)
 {
 	unsigned int accum = 0;
-	uint32_t extoffset, elen;
-	kernel_lb_addr bloc, eloc;
+	uint32_t elen;
+	kernel_lb_addr eloc;
 	int8_t etype;
-	struct buffer_head *bh = NULL;
+	struct extent_position epos;
 
 	lock_kernel();
 
-	bloc = UDF_I_LOCATION(table);
-	extoffset = sizeof(struct unallocSpaceEntry);
+	epos.block = UDF_I_LOCATION(table);
+	epos.offset = sizeof(struct unallocSpaceEntry);
+	epos.bh = NULL;
 
-	while ((etype = udf_next_aext(table, &bloc, &extoffset, &eloc, &elen, &bh, 1)) != -1)
-	{
+	while ((etype = udf_next_aext(table, &epos, &eloc, &elen, 1)) != -1)
 		accum += (elen >> table->i_sb->s_blocksize_bits);
-	}
-	udf_release_data(bh);
+	brelse(epos.bh);
 
 	unlock_kernel();
 
Index: linux-2.6.20.noarch/fs/udf/misc.c
===================================================================
--- linux-2.6.20.noarch.orig/fs/udf/misc.c	2007-02-04 13:44:54.000000000 -0500
+++ linux-2.6.20.noarch/fs/udf/misc.c	2007-03-28 15:15:29.000000000 -0400
@@ -274,12 +274,6 @@ udf_read_ptagged(struct super_block *sb,
 		loc.logicalBlockNum + offset, ident);
 }
 
-void udf_release_data(struct buffer_head *bh)
-{
-	if (bh)
-		brelse(bh);
-}
-
 void udf_update_tag(char *data, int length)
 {
 	tag *tptr = (tag *)data;
Index: linux-2.6.20.noarch/fs/udf/partition.c
===================================================================
--- linux-2.6.20.noarch.orig/fs/udf/partition.c	2007-02-04 13:44:54.000000000 -0500
+++ linux-2.6.20.noarch/fs/udf/partition.c	2007-03-28 15:15:29.000000000 -0400
@@ -81,7 +81,7 @@ uint32_t udf_get_pblock_virt15(struct su
 
 	loc = le32_to_cpu(((__le32 *)bh->b_data)[index]);
 
-	udf_release_data(bh);
+	brelse(bh);
 
 	if (UDF_I_LOCATION(UDF_SB_VAT(sb)).partitionReferenceNum == partition)
 	{
Index: linux-2.6.20.noarch/fs/udf/symlink.c
===================================================================
--- linux-2.6.20.noarch.orig/fs/udf/symlink.c	2007-02-04 13:44:54.000000000 -0500
+++ linux-2.6.20.noarch/fs/udf/symlink.c	2007-03-28 15:15:29.000000000 -0400
@@ -95,7 +95,7 @@ static int udf_symlink_filler(struct fil
 	}
 
 	udf_pc_to_char(inode->i_sb, symlink, inode->i_size, p);
-	udf_release_data(bh);
+	brelse(bh);
 
 	unlock_kernel();
 	SetPageUptodate(page);
Index: linux-2.6.20.noarch/fs/udf/udf_sb.h
===================================================================
--- linux-2.6.20.noarch.orig/fs/udf/udf_sb.h	2007-02-04 13:44:54.000000000 -0500
+++ linux-2.6.20.noarch/fs/udf/udf_sb.h	2007-03-28 15:15:29.000000000 -0400
@@ -93,7 +93,7 @@ static inline struct udf_sb_info *UDF_SB
 	for (i=0; i<nr_groups; i++)\
 	{\
 		if (UDF_SB_BITMAP(X,Y,Z,i))\
-			udf_release_data(UDF_SB_BITMAP(X,Y,Z,i));\
+			brelse(UDF_SB_BITMAP(X,Y,Z,i));\
 	}\
 	if (size <= PAGE_SIZE)\
 		kfree(UDF_SB_PARTMAPS(X)[Y].Z.s_bitmap);\

linux-2.6-mpc52xx-fec.patch:

--- NEW FILE linux-2.6-mpc52xx-fec.patch ---
diff -uNr linux-2.6.20.ppc64/drivers/net/fec_mpc52xx/fec.c linux-2.6.20.fec/drivers/net/fec_mpc52xx/fec.c
--- linux-2.6.20.ppc64/drivers/net/fec_mpc52xx/fec.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.20.fec/drivers/net/fec_mpc52xx/fec.c	2007-03-27 23:52:17.000000000 +0100
@@ -0,0 +1,872 @@
+/*
+ * drivers/net/fec_mpc52xx/fec.c
+ *
+ * Driver for the MPC5200 Fast Ethernet Controller
+ *
+ * Author: Dale Farnsworth <dfarnsworth at mvista.com>
+ *
+ * 2003-2004 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#include <linux/module.h>
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/spinlock.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/crc32.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/skbuff.h>
+
+#include <asm/io.h>
+#include <asm/delay.h>
+#include <asm/ppcboot.h>
+#include <asm/mpc52xx.h>
+
+#if defined(CONFIG_PPC_MERGE)
+#include <asm/of_device.h>
+#include <asm/of_platform.h>
+#include <platforms/52xx/bestcomm.h>
+#include "sdma_fec.h"
+#else
+#include <syslib/bestcomm/bestcomm.h>
+#include <syslib/bestcomm/fec.h>
+#endif
+
+#include "fec_phy.h"
+#include "fec.h"
+
+#define DRIVER_NAME "mpc52xx-fec"
+
+static irqreturn_t fec_interrupt(int, void *);
+static irqreturn_t fec_rx_interrupt(int, void *);
+static irqreturn_t fec_tx_interrupt(int, void *);
+static struct net_device_stats *fec_get_stats(struct net_device *);
+static void fec_set_multicast_list(struct net_device *dev);
+static void fec_reinit(struct net_device *dev);
+
+static u8 mpc52xx_fec_mac_addr[6];
+static u8 null_mac[6];
+
+static void fec_tx_timeout(struct net_device *dev)
+{
+	struct fec_priv *priv = (struct fec_priv *)dev->priv;
+
+	priv->stats.tx_errors++;
+
+	if (!priv->tx_full)
+		netif_wake_queue(dev);
+}
+
+static void fec_set_paddr(struct net_device *dev, u8 *mac)
+{
+	struct fec_priv *priv = (struct fec_priv *)dev->priv;
+	struct mpc52xx_fec *fec = priv->fec;
+
+	out_be32(&fec->paddr1, *(u32*)(&mac[0]));
+	out_be32(&fec->paddr2, (*(u16*)(&mac[4]) << 16) | 0x8808);
+}
+
+static void fec_get_paddr(struct net_device *dev, u8 *mac)
+{
+	struct fec_priv *priv = (struct fec_priv *)dev->priv;
+	struct mpc52xx_fec *fec = priv->fec;
+
+	*(u32*)(&mac[0]) = in_be32(&fec->paddr1);
+	*(u16*)(&mac[4]) = in_be32(&fec->paddr2) >> 16;
+}
+
+static int fec_set_mac_address(struct net_device *dev, void *addr)
+{
+	struct sockaddr *sock = (struct sockaddr *)addr;
+
+	memcpy(dev->dev_addr, sock->sa_data, dev->addr_len);
+
+	fec_set_paddr(dev, sock->sa_data);
+	return 0;
+}
+
+/* This function is called to start or restart the FEC during a link
+ * change.  This happens on fifo errors or when switching between half
+ * and full duplex.
+ */
+static void fec_restart(struct net_device *dev, int duplex)
+{
+	struct fec_priv *priv = (struct fec_priv *)dev->priv;
+	struct mpc52xx_fec *fec = priv->fec;
+	u32 rcntrl;
+	u32 tcntrl;
+	int i;
+
+	out_be32(&fec->rfifo_status, in_be32(&fec->rfifo_status) & 0x700000);
+	out_be32(&fec->tfifo_status, in_be32(&fec->tfifo_status) & 0x700000);
+	out_be32(&fec->reset_cntrl, 0x1000000);
+
+	/* Whack a reset.  We should wait for this. */
+	out_be32(&fec->ecntrl, FEC_ECNTRL_RESET);
+	for (i = 0; i < FEC_RESET_DELAY; ++i) {
+		if ((in_be32(&fec->ecntrl) & FEC_ECNTRL_RESET) == 0)
+			break;
+		udelay(1);
+	}
+	if (i == FEC_RESET_DELAY)
+		printk (KERN_ERR DRIVER_NAME ": FEC Reset timeout!\n");
+
+	/* Set station address. */
+	fec_set_paddr(dev, dev->dev_addr);
+
+	fec_set_multicast_list(dev);
+
+	rcntrl = FEC_RX_BUFFER_SIZE << 16;	/* max frame length */
+	rcntrl |= FEC_RCNTRL_FCE;
+	rcntrl |= MII_RCNTL_MODE;
+	if (duplex)
+		tcntrl = FEC_TCNTRL_FDEN;		/* FD enable */
+	else {
+		rcntrl |= FEC_RCNTRL_DRT;
+		tcntrl = 0;
+	}
+	out_be32(&fec->r_cntrl, rcntrl);
+	out_be32(&fec->x_cntrl, tcntrl);
+
+	set_phy_speed(fec, priv->phy_speed);
+
+	priv->full_duplex = duplex;
+
+	/* Clear any outstanding interrupt. */
+	out_be32(&fec->ievent, 0xffffffff);	/* clear intr events */
+
+	/* Enable interrupts we wish to service.
+	*/
+	out_be32(&fec->imask, FEC_IMASK_ENABLE);
+
+	/* And last, enable the transmit and receive processing.
+	*/
+	out_be32(&fec->ecntrl, FEC_ECNTRL_ETHER_EN);
+	out_be32(&fec->r_des_active, 0x01000000);
+
+	/* The tx ring is no longer full. */
+	if (priv->tx_full)
+	{
+		priv->tx_full = 0;
+		netif_wake_queue(dev);
+	}
+}
+
+static void fec_free_rx_buffers(struct sdma *s)
+{
+	struct sk_buff *skb;
+
+	while (!sdma_queue_empty(s)) {
+		skb = sdma_retrieve_buffer(s, NULL);
+		kfree_skb(skb);
+	}
+}
+
+static int fec_open(struct net_device *dev)
+{
+	struct fec_priv *priv = (struct fec_priv *)dev->priv;
+	struct sk_buff *skb;
+	void *data;
+
+	sdma_fec_rx_init(priv->rx_sdma, priv->rx_fifo, FEC_RX_BUFFER_SIZE);
+	sdma_fec_tx_init(priv->tx_sdma, priv->tx_fifo);
+
+	while (!sdma_queue_full(priv->rx_sdma)) {
+		skb = dev_alloc_skb(FEC_RX_BUFFER_SIZE);
+		if (skb == 0)
+			goto eagain;
+
+		/* zero out the initial receive buffers to aid debugging */
+		memset(skb->data, 0, FEC_RX_BUFFER_SIZE);
+		data = (void *)virt_to_phys(skb->data);
+		sdma_submit_buffer(priv->rx_sdma, skb, data, FEC_RX_BUFFER_SIZE);
+	}
+
+	fec_set_paddr(dev, dev->dev_addr);
+
+	if (fec_mii_wait(dev) != 0)
[...1876 lines suppressed...]
+struct sdma_fec_tx_inc {
+	u16 pad0;
+	s16 incr_bytes;
+	u16 pad1;
+	s16 incr_src;
+	u16 pad2;
+	s16 incr_src_ma;
+};
+
+extern int sdma_fec_rx_init(struct sdma *s, phys_addr_t fifo, int maxbufsize);
+extern int sdma_fec_tx_init(struct sdma *s, phys_addr_t fifo);
+
+extern u32 sdma_fec_rx_task[];
+extern u32 sdma_fec_tx_task[];
+
+
+#endif  /* __BESTCOMM_FEC_H__ */
diff -uNr linux-2.6.20.ppc64/drivers/net/fec_mpc52xx/sdma_fec_rx_task.c linux-2.6.20.fec/drivers/net/fec_mpc52xx/sdma_fec_rx_task.c
--- linux-2.6.20.ppc64/drivers/net/fec_mpc52xx/sdma_fec_rx_task.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.20.fec/drivers/net/fec_mpc52xx/sdma_fec_rx_task.c	2007-03-27 22:57:09.000000000 +0100
@@ -0,0 +1,71 @@
+/*
+ * sdma_fec_rx_task.c
+ *
+ * Automatically created based on BestCommAPI-2.2/code_dma/image_rtos1/dma_image.hex
+ * on Tue Mar 22 11:19:38 2005 GMT
+ */
+
+#include <linux/types.h>
+
+/*
+ * The header consists of the following fields:
+ *	uint32_t	magic;
+ *	uint8_t		desc_size;
+ *	uint8_t		var_size;
+ *	uint8_t		inc_size;
+ *	uint8_t		first_var;
+ *	uint8_t		reserved[8];
+ *
+ * The size fields contain the number of 32-bit words.
+*/
+
+uint32_t sdma_fec_rx_task[] = {
+	/* header */
+	0x4243544b,
+	0x18060709,
+	0x00000000,
+	0x00000000,
+
+	/* Task descriptors */
+	0x808220e3, /* LCD: idx0 = var1, idx1 = var4; idx1 <= var3; idx0 += inc4, idx1 += inc3 */
+	0x10601010, /*   DRD1A: var4 = var2; FN=0 MORE init=3 WS=0 RS=0 */
+	0xb8800264, /*   LCD: idx2 = *idx1, idx3 = var0; idx2 < var9; idx2 += inc4, idx3 += inc4 */
+	0x10001308, /*     DRD1A: var4 = idx1; FN=0 MORE init=0 WS=0 RS=0 */
+	0x60140002, /*     DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT init=0 WS=2 RS=2 */
+	0x0cccfcca, /*     DRD2B1: *idx3 = EU3(); EU3(*idx3,var10)  */
+	0x80004000, /*   LCDEXT: idx2 = 0x00000000; ; */
+	0xb8c58029, /*   LCD: idx3 = *(idx1 + var00000015); idx3 once var0; idx3 += inc5 */
+	0x60000002, /*     DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT init=0 WS=0 RS=0 */
+	0x088cf8cc, /*     DRD2B1: idx2 = EU3(); EU3(idx3,var12)  */
+	0x991982f2, /*   LCD: idx2 = idx2, idx3 = idx3; idx2 > var11; idx2 += inc6, idx3 += inc2 */
+	0x006acf80, /*     DRD1A: *idx3 = *idx0; FN=0 init=3 WS=1 RS=1 */
+	0x80004000, /*   LCDEXT: idx2 = 0x00000000; ; */
+	0x9999802d, /*   LCD: idx3 = idx3; idx3 once var0; idx3 += inc5 */
+	0x70000002, /*     DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT MORE init=0 WS=0 RS=0 */
+	0x034cfc4e, /*     DRD2B1: var13 = EU3(); EU3(*idx1,var14)  */
+	0x00008868, /*     DRD1A: idx2 = var13; FN=0 init=0 WS=0 RS=0 */
+	0x99198341, /*   LCD: idx2 = idx2, idx3 = idx3; idx2 > var13; idx2 += inc0, idx3 += inc1 */
+	0x007ecf80, /*     DRD1A: *idx3 = *idx0; FN=0 init=3 WS=3 RS=3 */
+	0x99198272, /*   LCD: idx2 = idx2, idx3 = idx3; idx2 > var9; idx2 += inc6, idx3 += inc2 */
+	0x046acf80, /*     DRD1A: *idx3 = *idx0; FN=0 INT init=3 WS=1 RS=1 */
+	0x9819002d, /*   LCD: idx2 = idx0; idx2 once var0; idx2 += inc5 */
+	0x0060c790, /*     DRD1A: *idx1 = *idx2; FN=0 init=3 WS=0 RS=0 */
+	0x000001f8, /*   NOP */
+
+	/* VAR[9]-VAR[14] */
+	0x40000000,
+	0x7fff7fff,
+	0x00000000,
+	0x00000003,
+	0x40000008,
+	0x43ffffff,
+
+	/* INC[0]-INC[6] */
+	0x40000000,
+	0xe0000000,
+	0xe0000000,
+	0xa0000008,
+	0x20000000,
+	0x00000000,
+	0x4000ffff,
+};
diff -uNr linux-2.6.20.ppc64/drivers/net/fec_mpc52xx/sdma_fec_tx_task.c linux-2.6.20.fec/drivers/net/fec_mpc52xx/sdma_fec_tx_task.c
--- linux-2.6.20.ppc64/drivers/net/fec_mpc52xx/sdma_fec_tx_task.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.20.fec/drivers/net/fec_mpc52xx/sdma_fec_tx_task.c	2007-03-27 22:57:09.000000000 +0100
@@ -0,0 +1,84 @@
+/*
+ * sdma_fec_tx_task.c
+ *
+ * Automatically created based on BestCommAPI-2.2/code_dma/image_rtos1/dma_image.hex
+ * on Tue Mar 22 11:19:29 2005 GMT
+ */
+
+#include <linux/types.h>
+
+/*
+ * The header consists of the following fields:
+ *	uint32_t	magic;
+ *	uint8_t		desc_size;
+ *	uint8_t		var_size;
+ *	uint8_t		inc_size;
+ *	uint8_t		first_var;
+ *	uint8_t		reserved[8];
+ *
+ * The size fields contain the number of 32-bit words.
+*/
+
+uint32_t sdma_fec_tx_task[] = {
+	/* header */
+	0x4243544b,
+	0x2407070d,
+	0x00000000,
+	0x00000000,
+
+	/* Task descriptors */
+	0x8018001b, /* LCD: idx0 = var0; idx0 <= var0; idx0 += inc3 */
+	0x60000005, /*   DRD2A: EU0=0 EU1=0 EU2=0 EU3=5 EXT init=0 WS=0 RS=0 */
+	0x01ccfc0d, /*   DRD2B1: var7 = EU3(); EU3(*idx0,var13)  */
+	0x8082a123, /* LCD: idx0 = var1, idx1 = var5; idx1 <= var4; idx0 += inc4, idx1 += inc3 */
+	0x10801418, /*   DRD1A: var5 = var3; FN=0 MORE init=4 WS=0 RS=0 */
+	0xf88103a4, /*   LCDEXT: idx2 = *idx1, idx3 = var2; idx2 < var14; idx2 += inc4, idx3 += inc4 */
+	0x801a6024, /*   LCD: idx4 = var0; ; idx4 += inc4 */
+	0x10001708, /*     DRD1A: var5 = idx1; FN=0 MORE init=0 WS=0 RS=0 */
+	0x60140002, /*     DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT init=0 WS=2 RS=2 */
+	0x0cccfccf, /*     DRD2B1: *idx3 = EU3(); EU3(*idx3,var15)  */
+	0x991a002c, /*   LCD: idx2 = idx2, idx3 = idx4; idx2 once var0; idx2 += inc5, idx3 += inc4 */
+	0x70000002, /*     DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT MORE init=0 WS=0 RS=0 */
+	0x024cfc4d, /*     DRD2B1: var9 = EU3(); EU3(*idx1,var13)  */
+	0x60000003, /*     DRD2A: EU0=0 EU1=0 EU2=0 EU3=3 EXT init=0 WS=0 RS=0 */
+	0x0cccf247, /*     DRD2B1: *idx3 = EU3(); EU3(var9,var7)  */
+	0x80004000, /*   LCDEXT: idx2 = 0x00000000; ; */
+	0xb8c80029, /*   LCD: idx3 = *(idx1 + var0000001a); idx3 once var0; idx3 += inc5 */
+	0x70000002, /*     DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT MORE init=0 WS=0 RS=0 */
+	0x088cf8d1, /*     DRD2B1: idx2 = EU3(); EU3(idx3,var17)  */
+	0x00002f10, /*     DRD1A: var11 = idx2; FN=0 init=0 WS=0 RS=0 */
+	0x99198432, /*   LCD: idx2 = idx2, idx3 = idx3; idx2 > var16; idx2 += inc6, idx3 += inc2 */
+	0x008ac398, /*     DRD1A: *idx0 = *idx3; FN=0 init=4 WS=1 RS=1 */
+	0x80004000, /*   LCDEXT: idx2 = 0x00000000; ; */
+	0x9999802d, /*   LCD: idx3 = idx3; idx3 once var0; idx3 += inc5 */
+	0x70000002, /*     DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT MORE init=0 WS=0 RS=0 */
+	0x048cfc53, /*     DRD2B1: var18 = EU3(); EU3(*idx1,var19)  */
+	0x60000008, /*     DRD2A: EU0=0 EU1=0 EU2=0 EU3=8 EXT init=0 WS=0 RS=0 */
+	0x088cf48b, /*     DRD2B1: idx2 = EU3(); EU3(var18,var11)  */
+	0x99198481, /*   LCD: idx2 = idx2, idx3 = idx3; idx2 > var18; idx2 += inc0, idx3 += inc1 */
+	0x009ec398, /*     DRD1A: *idx0 = *idx3; FN=0 init=4 WS=3 RS=3 */
+	0x991983b2, /*   LCD: idx2 = idx2, idx3 = idx3; idx2 > var14; idx2 += inc6, idx3 += inc2 */
+	0x088ac398, /*     DRD1A: *idx0 = *idx3; FN=0 TFD init=4 WS=1 RS=1 */
+	0x9919002d, /*   LCD: idx2 = idx2; idx2 once var0; idx2 += inc5 */
+	0x60000005, /*     DRD2A: EU0=0 EU1=0 EU2=0 EU3=5 EXT init=0 WS=0 RS=0 */
+	0x0c4cf88e, /*     DRD2B1: *idx1 = EU3(); EU3(idx2,var14)  */
+	0x000001f8, /*   NOP */
+
+	/* VAR[13]-VAR[19] */
+	0x0c000000,
+	0x40000000,
+	0x7fff7fff,
+	0x00000000,
+	0x00000003,
+	0x40000004,
+	0x43ffffff,
+
+	/* INC[0]-INC[6] */
+	0x40000000,
+	0xe0000000,
+	0xe0000000,
+	0xa0000008,
+	0x20000000,
+	0x00000000,
+	0x4000ffff,
+};
--- linux-2.6.20.ppc64/drivers/net/Makefile	2007-03-22 11:18:04.000000000 +0000
+++ linux-2.6.20.fec/drivers/net/Makefile	2007-03-27 19:09:21.000000000 +0100
@@ -196,6 +196,7 @@ obj-$(CONFIG_SMC91X) += smc91x.o
 obj-$(CONFIG_SMC911X) += smc911x.o
 obj-$(CONFIG_DM9000) += dm9000.o
 obj-$(CONFIG_FEC_8XX) += fec_8xx/
+obj-$(CONFIG_FEC_MPC52xx) += fec_mpc52xx/
 obj-$(CONFIG_PASEMI_MAC) += pasemi_mac.o
 
 obj-$(CONFIG_MACB) += macb.o
--- linux-2.6.20.ppc64/drivers/net/Kconfig	2007-03-22 11:17:54.000000000 +0000
+++ linux-2.6.20.fec/drivers/net/Kconfig	2007-03-27 19:09:21.000000000 +0100
@@ -1889,6 +1889,7 @@ config NE_H8300
 	  controller on the Renesas H8/300 processor.
 
 source "drivers/net/fec_8xx/Kconfig"
+source "drivers/net/fec_mpc52xx/Kconfig"
 source "drivers/net/fs_enet/Kconfig"
 
 endmenu

linux-2.6-mpc52xx-sdma.patch:

--- NEW FILE linux-2.6-mpc52xx-sdma.patch ---
--- linux-2.6.20.ppc64/arch/powerpc/Kconfig	2007-03-22 11:17:52.000000000 +0000
+++ linux-2.6.20.fec/arch/powerpc/Kconfig	2007-03-27 19:09:27.000000000 +0100
@@ -451,6 +456,11 @@
 
 	  It is safe to say 'Y' here
 
+config PPC_BESTCOMM
+	bool
+	depends on PPC_MPC52xx
+	default y
+
 config PPC_EFIKA
 	bool "bPlan Efika 5k2. MPC5200B based computer"
 	depends on PPC_MULTIPLATFORM && PPC32
diff -uNr linux-2.6.20.ppc64/arch/powerpc/platforms/52xx/bestcomm.c linux-2.6.20.fec/arch/powerpc/platforms/52xx/bestcomm.c
--- linux-2.6.20.ppc64/arch/powerpc/platforms/52xx/bestcomm.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.20.fec/arch/powerpc/platforms/52xx/bestcomm.c	2007-03-27 23:40:42.000000000 +0100
@@ -0,0 +1,399 @@
+/*
+ * arch/ppc/syslib/bestcomm/bestcomm.c
+ *
+ * Driver for MPC52xx processor BestComm peripheral controller
+ *
+ * Author: Dale Farnsworth <dfarnsworth at mvista.com>
+ *
+ * 2003-2004 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * HISTORY:
+ *
+ * 2005-08-14	Converted to platform driver by 
+ *		Andrey Volkov <avolkov at varma-el.com>, Varma Electronics Oy
+ */
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+
+#include <asm/bug.h>
+#include <asm/io.h>
+#include <asm/mpc52xx.h>
+#include <asm/of_platform.h>
+
+#include "bestcomm.h"
+
+#define DRIVER_NAME "mpc52xx-bestcomm"
+
+struct sdma_io sdma;
+struct device_node *sdma_node;
+struct device_node *sram_node;
+
+static spinlock_t sdma_lock = SPIN_LOCK_UNLOCKED;
+
+#ifdef CONFIG_BESTCOMM_DEBUG
+void sdma_dump(void)
+{
+	int i;
+	printk("** SDMA registers: pa = %.8lx, va = %p\n",
+	       sdma.base_reg_addr, sdma.io);
+	printk("**  taskBar = %08x\n", sdma.io->taskBar);
+	printk("**  currentPointer = %08x\n", sdma.io->currentPointer);
+	printk("**  endPointer = %08x\n", sdma.io->endPointer);
+	printk("**  variablePointer = %08x\n", sdma.io->variablePointer);
+
+	printk("**  IntVect1 = %08x\n", sdma.io->IntVect1);
+	printk("**  IntVect2 = %08x\n", sdma.io->IntVect2);
+	printk("**  PtdCntrl = %08x\n", sdma.io->PtdCntrl);
+
+	printk("**  IntPend = %08x\n", sdma.io->IntPend);
+	printk("**  IntMask = %08x\n", sdma.io->IntMask);
+
+	printk("**  TCR dump:");	
+
+	for (i=0;i<16;i++)  {
+		if(i%8 == 0)
+			printk("\n**   %02X:",i);
+		printk(" %04X",sdma.io->tcr[i]);
+	}
+	printk("\n**  IPR dump:");	
+	for (i=0;i<32;i++)  {
+		if(i%16 == 0)
+			printk("\n**   %02X:",i);
+		printk(" %02X",sdma.io->ipr[i]);
+	}
+	printk("\n**  cReqSelect = %08x\n", sdma.io->cReqSelect);
+	printk("**  task_size0 = %08x\n", sdma.io->task_size0);
+	printk("**  task_size1 = %08x\n", sdma.io->task_size1);
+	printk("**  MDEDebug = %08x\n", sdma.io->MDEDebug);
+	printk("**  ADSDebug = %08x\n", sdma.io->ADSDebug);
+	printk("**  Value1 = %08x\n", sdma.io->Value1);
+	printk("**  Value2 = %08x\n", sdma.io->Value2);
+	printk("**  Control = %08x\n", sdma.io->Control);
+	printk("**  Status = %08x\n", sdma.io->Status);
+	printk("**  PTDDebug = %08x\n", sdma.io->PTDDebug);
+}
+#endif
+
+#ifdef CONFIG_BESTCOMM_DEBUG
+#define SDMA_DUMP_REGS()	sdma_dump()
+#else
+#define SDMA_DUMP_REGS()
+#endif
+
+/*
+ * Use a very simple SRAM allocator.
+ * There is no mechanism for freeing space.
+ * In an attempt to minimize internal fragmentation, the SRAM is
+ * divided into two areas.
+ *
+ * Area 1 is at the beginning of SRAM
+ * and is used for allocations requiring alignments of 16 bytes or less.
+ * Successive allocations return higher addresses.
+ *
+ * Area 2 is at the end of SRAM and is used for the remaining allocations.
+ * Successive allocations return lower addresses.
+ *
+ * I've considered adding routines to support the freeing of SRAM allocations,
+ * but the SRAM is so small (16K) that fragmentation can quickly cause the
+ * SRAM to be unusable.  If you can come up with a slick way to free SRAM
+ * memory without the fragmentation problem, please do so.
+ */
+
+static u8 *area1_end;
+static u8 *area2_begin;
+
+void *sdma_sram_alloc(int size, int alignment, u32 *dma_handle)
+{
+	u8 *a;
+
+	spin_lock(&sdma_lock);
+
+	/* alignment must be a power of 2 */
+	BUG_ON(alignment & (alignment - 1));
+
+	if (alignment < 16) {
+		a = (u8 *)(((u32)area1_end + (alignment-1)) & ~(alignment-1));
+		if (a + size <= area2_begin)
+			area1_end = a + size;
+		else
+			a = 0;				/* out of memory */
+	} else {
+		a = (u8 *)(((u32)area2_begin - size) & ~(alignment - 1));
+		if (a >= area1_end)
+			area2_begin = a;
+		else
+			a = 0;				/* out of memory */
+	}
+	if(a && dma_handle)
+		*dma_handle = sdma_sram_pa(a);
+	spin_unlock(&sdma_lock);
+	return (void *)a;
+}
+
+/* this will need to be updated if Freescale changes their task code FDT */
+static u32 fdt_ops[] = {
+	0xa0045670,	/* FDT[48] */
+	0x80045670,	/* FDT[49] */
+	0x21800000,	/* FDT[50] */
+	0x21e00000,	/* FDT[51] */
+	0x21500000,	/* FDT[52] */
+	0x21400000,	/* FDT[53] */
+	0x21500000,	/* FDT[54] */
+	0x20400000,	/* FDT[55] */
+	0x20500000,	/* FDT[56] */
+	0x20800000,	/* FDT[57] */
+	0x20a00000,	/* FDT[58] */
+	0xc0170000,	/* FDT[59] */
+	0xc0145670,	/* FDT[60] */
+	0xc0345670,	/* FDT[61] */
+	0xa0076540,	/* FDT[62] */
+	0xa0000760,	/* FDT[63] */
+};
+
+static int new_task_number(void)
+{
+	struct sdma_tdt *tdt;
+	int i;
+
+	spin_lock(&sdma_lock);
+
+	tdt = sdma.tdt;
+	for (i=0; i<SDMA_MAX_TASKS; i++, tdt++)
+		if (tdt->start == 0)
+			break;
+	if (i == SDMA_MAX_TASKS)
+		i = -1;
+
+	spin_unlock(&sdma_lock);
+
+	return i;
+}
+
+int sdma_load_task(u32 *task_image)
+{
+	struct sdma_task_header *head = (struct sdma_task_header *)task_image;
+	struct sdma_tdt *tdt;
+	int tasknum;
+	u32 *desc;
+	u32 *var_src, *var_dst;
+	u32 *inc_src;
+	void *start;
+
+	BUG_ON(head->magic != SDMA_TASK_MAGIC);
+
+	tasknum = new_task_number();
+	if (tasknum < 0)
+		return -ENOMEM;
+
+	desc = (u32 *)(head + 1);
+	var_src = desc + head->desc_size;
+	inc_src = var_src + head->var_size;
+
+	tdt = &sdma.tdt[tasknum];
+
+	start = sdma_sram_alloc(head->desc_size * sizeof(u32), 4, &tdt->start);
+	if (!start)
+		return -ENOMEM;
+	tdt->stop = tdt->start + (head->desc_size - 1)*sizeof(u32);
+	var_dst = sdma_sram_va(tdt->var);
+
+	memcpy(start, desc, head->desc_size * sizeof(u32));
+	memcpy(&var_dst[head->first_var], var_src, head->var_size * sizeof(u32));
+	memcpy(&var_dst[SDMA_MAX_VAR], inc_src, head->inc_size * sizeof(u32));
+
+	return tasknum;
+}
+
+void sdma_set_initiator(int task, int initiator)
+{
+	int i;
+	int num_descs;
+	u32 *desc;
+	int next_drd_has_initiator;
+
+	sdma_set_tcr_initiator(task, initiator);
+
+	desc = sdma_task_desc(task);
+	next_drd_has_initiator = 1;
+	num_descs = sdma_task_num_descs(task);
+
+	for (i=0; i<num_descs; i++, desc++) {
+		if (!sdma_desc_is_drd(*desc))
+			continue;
+		if (next_drd_has_initiator)
+			if (sdma_desc_initiator(*desc) != SDMA_INITIATOR_ALWAYS)
+				sdma_set_desc_initiator(desc, initiator);
+		next_drd_has_initiator = !sdma_drd_is_extended(*desc);
+	}
+}
+
+struct sdma *sdma_alloc(int queue_size)
+{
+	struct sdma *s = kmalloc(sizeof(*s), GFP_KERNEL);
+	void **cookie;
+
+	if (!s)
+		return NULL;
+
+	memset(s, 0, sizeof(*s));
+
+	if (queue_size) {
+		cookie = kmalloc(sizeof(*cookie) * queue_size, GFP_KERNEL);
+		if (!cookie) {
+			kfree(s);
+			return NULL;
+		}
+		s->cookie = cookie;
+	}
+
+	s->num_bd = queue_size;
+	s->node = sdma_node;
+	return s;
+}
+EXPORT_SYMBOL_GPL(sdma_alloc);
+
+void sdma_free(struct sdma *s)
+{
+	if (s->cookie)
+		kfree(s->cookie);
+	kfree(s);
+}
+
+static int __init mpc52xx_sdma_init(void)
+{
+	int task;
+	u32 *context;
+	u32 *fdt;
+	struct sdma_tdt *tdt;
+	struct resource mem_io, mem_sram;
+	u32 tdt_pa, var_pa, context_pa, fdt_pa;
+	int ret = -ENODEV;
+
+	/* Find SDMA registers */
+	sdma_node = of_find_compatible_node(NULL, "dma-controller", "mpc5200-bestcomm");
+	if (!sdma_node) {
+		printk (KERN_ERR DRIVER_NAME ": could not locate DMA controller\n");
+		goto out;
+	}
+
+	if ((ret = of_address_to_resource(sdma_node, 0, &mem_io)) != 0) {
+		printk(KERN_ERR "Could not get address of SDMA controller\n");
+		goto out;
+	}
+
+	/* Find SRAM location */
+	sram_node = of_find_compatible_node(NULL, "sram", "mpc5200-sram");
+	if (!sram_node) {
+		printk (KERN_ERR DRIVER_NAME ": could not locate SRAM\n");
+		goto out;
+	}
+
+	if ((ret = of_address_to_resource(sram_node, 0, &mem_sram)) != 0) {
+		printk(KERN_ERR "Could not get address of SRAM\n");
+		goto out;
+	}
+
+	/* Map register regions */
+	if (!request_mem_region(mem_io.start, mem_io.end - mem_io.start + 1,
+	                        DRIVER_NAME)) {
+		printk(KERN_ERR DRIVER_NAME " - resource unavailable\n");
+		goto out;
+	}
+	sdma.base_reg_addr = mem_io.start;
+
+	sdma.io = ioremap_nocache(mem_io.start, sizeof(struct mpc52xx_sdma));
+
+	if (!sdma.io ) {
+		printk(KERN_ERR DRIVER_NAME " - failed to map sdma regs\n");
+		ret = -ENOMEM;
+		goto map_io_error;
+	}
+
+	SDMA_DUMP_REGS();
+
+	sdma.sram_size = mem_sram.end - mem_sram.start + 1;
+	if (!request_mem_region(mem_sram.start, sdma.sram_size, DRIVER_NAME)) {
+		printk(KERN_ERR DRIVER_NAME " - resource unavailable\n");
+		goto req_sram_error;
+	}
+
+	sdma.base_sram_addr = mem_sram.start;
+	sdma.sram = ioremap_nocache(mem_sram.start, sdma.sram_size);
+	if (!sdma.sram ) {
+		printk(KERN_ERR DRIVER_NAME " - failed to map sdma sram\n");
+		ret = -ENOMEM;
+		goto map_sram_error;
+	}
+
+	area1_end = sdma.sram;
+	area2_begin = area1_end + sdma.sram_size;
+
+	memset(area1_end, 0, sdma.sram_size);
+
+	/* allocate space for task descriptors, contexts, and var tables */
+	sdma.tdt = sdma_sram_alloc(sizeof(struct sdma_tdt) * SDMA_MAX_TASKS, 4, &tdt_pa);
+
+	context = sdma_sram_alloc(SDMA_CONTEXT_SIZE * SDMA_MAX_TASKS,
+							  SDMA_CONTEXT_ALIGN, &context_pa);
+	sdma.var = sdma_sram_alloc( (SDMA_VAR_SIZE + SDMA_INC_SIZE) * SDMA_MAX_TASKS, 
+								SDMA_VAR_ALIGN, &var_pa);
+	fdt = sdma_sram_alloc(SDMA_FDT_SIZE, SDMA_FDT_ALIGN, &fdt_pa);
+	memcpy(&fdt[48], fdt_ops, sizeof(fdt_ops));
+
+	out_be32(&sdma.io->taskBar, tdt_pa);
+
+	tdt = sdma.tdt;
+	for (task=0; task < SDMA_MAX_TASKS; task++) {
+		out_be16(&sdma.io->tcr[task], 0);
+		out_8(&sdma.io->ipr[task], 0);
+
+		tdt->context = context_pa;
+		tdt->var = var_pa;
+		tdt->fdt = fdt_pa;
+		var_pa += (SDMA_MAX_VAR + SDMA_MAX_INC)*sizeof(u32);
+		context_pa += SDMA_MAX_CONTEXT*sizeof(u32);
+		tdt++;
+	}
+
+	out_8(&sdma.io->ipr[SDMA_INITIATOR_ALWAYS], SDMA_IPR_ALWAYS);
+
+	/* Disable COMM Bus Prefetch, apparently it's not reliable yet */
+	out_be16(&sdma.io->PtdCntrl, in_be16(&sdma.io->PtdCntrl) | 1);
+
+	printk(KERN_INFO "MPC52xx BestComm inited\n");
+
+	return 0;
+
+map_sram_error:
+	release_mem_region(mem_sram.start, sdma.sram_size);
+req_sram_error:
+	iounmap(sdma.io);
+map_io_error:
+	release_mem_region(mem_io.start, mem_io.end - mem_io.start + 1);
+out:
+	printk(KERN_ERR "DMA: MPC52xx BestComm init FAILED !!!\n");
+	return ret;
+}
+
+subsys_initcall(mpc52xx_sdma_init);
+
+
+MODULE_DESCRIPTION("Freescale MPC52xx BestComm DMA");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(sdma_sram_alloc);
+EXPORT_SYMBOL(sdma_load_task);
+EXPORT_SYMBOL(sdma_set_initiator);
+EXPORT_SYMBOL(sdma_free);
+EXPORT_SYMBOL(sdma);
+
+
diff -uNr linux-2.6.20.ppc64/arch/powerpc/platforms/52xx/bestcomm.h linux-2.6.20.fec/arch/powerpc/platforms/52xx/bestcomm.h
--- linux-2.6.20.ppc64/arch/powerpc/platforms/52xx/bestcomm.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.20.fec/arch/powerpc/platforms/52xx/bestcomm.h	2007-03-27 22:57:08.000000000 +0100
@@ -0,0 +1,478 @@
+/*
+ * arch/ppc/syslib/bestcomm/bestcomm.h
+ *
+ * Driver for MPC52xx processor BestComm peripheral controller
+ *
+ * Author: Dale Farnsworth <dfarnsworth at mvista.com>
+ *
+ * 2003-2004 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * HISTORY:
+ *
+ * 2005-08-14	Converted to platform driver by 
+ *		Andrey Volkov <avolkov at varma-el.com>, Varma Electronics Oy
+ */
+
+#ifndef __BESTCOMM_BESTCOMM_H__
+#define __BESTCOMM_BESTCOMM_H__
+
+#include "mpc52xx_pic.h"
+
+/* Buffer Descriptor definitions */
+struct sdma_bd {
+	u32 status;
+	void *data;
+};
+
+struct sdma_bd2 {
+	u32 status;
+	void *data1;
+	void *data2;
+};
+
+struct sdma_io {
+	unsigned long			base_reg_addr;
+	struct mpc52xx_sdma __iomem	*io;
+	unsigned long			base_sram_addr;
+	void __iomem			*sram;
+	size_t				sram_size;
+
+	struct sdma_tdt __iomem  	*tdt;
+	u32 __iomem			*var;
+};
+extern struct sdma_io sdma;
+
+#define	sdma_sram_pa(virt)	(((unsigned long)(((void __iomem *)(virt))-sdma.sram))+sdma.base_sram_addr)
+#define	sdma_sram_va(pa)	((void __iomem *)((((unsigned long)(pa))-sdma.base_sram_addr)+((unsigned long)sdma.sram)))
+
+#define	sdma_io_pa(virt)	(((unsigned long)(((void __iomem *)(virt))-((void __iomem *)sdma.io)))+sdma.base_reg_addr)
+#define	sdma_io_va(pa)	((void __iomem *)((((unsigned long)(pa))-sdma.base_reg_addr)+((unsigned long)sdma.io)))
+
+#define SDMA_LEN_BITS		26
+#define SDMA_LEN_MASK		((1 << SDMA_LEN_BITS) - 1)
+
+#define SDMA_BD_READY		0x40000000UL
+
+#define SDMA_FEC_TX_BD_TFD	0x08000000UL	/* transmit frame done */
+#define SDMA_FEC_TX_BD_INT	0x04000000UL	/* Interrupt */
+#define SDMA_FEC_TX_BD_TFD_INIT	(SDMA_BD_READY | SDMA_FEC_TX_BD_TFD | \
+							SDMA_FEC_TX_BD_INT)
+
+struct sdma {
+	union {
+		struct sdma_bd *bd;
+		struct sdma_bd2 *bd2;
+	};
+	void **cookie;
+	u16 index;
+	u16 outdex;
+	u16 num_bd;
+	s16 tasknum;
+	u32 flags;
+	struct device_node *node;
+};
+
+#define SDMA_FLAGS_NONE		0x0000
+#define SDMA_FLAGS_ENABLE_TASK	0x0001
+#define SDMA_FLAGS_BD2		0x0002
+
+/* Task Descriptor Table Entry */
+struct sdma_tdt {
+	u32 start;
+	u32 stop;
+	u32 var;
+	u32 fdt;
+	u32 exec_status; /* used internally by SmartComm engine */
+	u32 mvtp;		 /* used internally by SmartComm engine */
+	u32 context;
+	u32 litbase;
+};
+
+//extern struct sdma_tdt *sdma_tdt;
+
+#define SDMA_MAX_TASKS		16
+#define SDMA_MAX_VAR		24
+#define SDMA_MAX_INC		8
+#define SDMA_MAX_FDT		64
+#define SDMA_MAX_CONTEXT	20
+#define SDMA_CONTEXT_SIZE	SDMA_MAX_CONTEXT * sizeof(u32)
+#define SDMA_CONTEXT_ALIGN	0x100
+#define SDMA_VAR_SIZE		SDMA_MAX_VAR * sizeof(u32)
+#define SDMA_VAR_ALIGN		0x80
+#define SDMA_INC_SIZE		SDMA_MAX_INC * sizeof(u32)
+#define SDMA_FDT_SIZE		SDMA_MAX_FDT * sizeof(u32)
+#define SDMA_FDT_ALIGN		0x100
+#define SDMA_BD_ALIGN		0x10
+
+#define TASK_ENABLE		0x8000
+
+#ifndef DPRINK
+	#ifdef CONFIG_BESTCOMM_DEBUG
+	#define DPRINTK(a,b...)	printk(KERN_DEBUG "sdma: %s: " a, __FUNCTION__ , ## b)
+	#else
+	#define DPRINTK(a,b...)
+	#endif
+#endif
+
+static inline void sdma_enable_task(int task)
+{
+	u16 reg;
+
+	DPRINTK("***DMA enable task (%d): tdt = %p\n",task, sdma.tdt);
+	DPRINTK("***tdt->start   = %08x\n",sdma.tdt[task].start);
+	DPRINTK("***tdt->stop    = %08x\n",sdma.tdt[task].stop);
+	DPRINTK("***tdt->var     = %08x\n",sdma.tdt[task].var);
+	DPRINTK("***tdt->fdt     = %08x\n",sdma.tdt[task].fdt);
+	DPRINTK("***tdt->status  = %08x\n",sdma.tdt[task].exec_status);
+	DPRINTK("***tdt->mvtp    = %08x\n",sdma.tdt[task].mvtp);
+	DPRINTK("***tdt->context = %08x\n",sdma.tdt[task].context);
+	DPRINTK("***tdt->litbase = %08x\n",sdma.tdt[task].litbase);
+	DPRINTK("***--------------\n");
+
+	reg = in_be16(&sdma.io->tcr[task]);
+	DPRINTK("***enable task: &sdma.io->tcr=%p, reg = %04x\n", &sdma.io->tcr, reg);
+	out_be16(&sdma.io->tcr[task],  reg | TASK_ENABLE);
+}
+
+static inline void sdma_disable_task(int task)
+{
+	u16 reg = in_be16(&sdma.io->tcr[task]);
+	DPRINTK("***disable task(%d): reg = %04x\n", task, reg);
+	out_be16(&sdma.io->tcr[task], reg & ~TASK_ENABLE);
+}
+
+static inline int sdma_irq(struct sdma *s)
+{
+	return irq_of_parse_and_map(s->node, s->tasknum);
+}
+
+static inline void sdma_enable(struct sdma *s)
+{
+	sdma_enable_task(s->tasknum);
+}
+
+static inline void sdma_disable(struct sdma *s)
+{
+	sdma_disable_task(s->tasknum);
+}
+
+static inline int sdma_queue_empty(struct sdma *s)
+{
+	return s->index == s->outdex;
+}
+
+static inline void sdma_clear_irq(struct sdma *s)
+{
+	out_be32(&sdma.io->IntPend, 1 << s->tasknum);
+}
+
+static inline int sdma_next_index(struct sdma *s)
+{
+	return ((s->index + 1) == s->num_bd) ? 0 : s->index + 1;
+}
+
+static inline int sdma_next_outdex(struct sdma *s)
+{
+	return ((s->outdex + 1) == s->num_bd) ? 0 : s->outdex + 1;
+}
+
+static inline int sdma_queue_full(struct sdma *s)
+{
+	return s->outdex == sdma_next_index(s);
+}
+
+static inline int sdma_buffer_done(struct sdma *s)
+{
+#ifdef CONFIG_BESTCOMM_DEBUG
+	BUG_ON(s->flags & SDMA_FLAGS_BD2);
+#endif
+	if (sdma_queue_empty(s))
+		return 0;
+	return (s->bd[s->outdex].status & SDMA_BD_READY) == 0;
+}
+
+static inline int sdma_buffer2_done(struct sdma *s)
+{
+#ifdef CONFIG_BESTCOMM_DEBUG
+	BUG_ON(!(s->flags & SDMA_FLAGS_BD2));
+#endif
+	if (sdma_queue_empty(s))
+		return 0;
+
+	return (s->bd2[s->outdex].status & SDMA_BD_READY) == 0;
+}
+
+static inline u32 *sdma_task_desc(int task)
+{
+	return sdma_sram_va(sdma.tdt[task].start);
+}
+
+static inline u32 sdma_task_num_descs(int task)
+{
+	return (sdma.tdt[task].stop - sdma.tdt[task].start)/sizeof(u32) + 1;
+}
+
+static inline u32 *sdma_task_var(int task)
+{
+	return sdma_sram_va(sdma.tdt[task].var);
+}
+
+static inline u32 *sdma_task_inc(int task)
+{
+	return &sdma_task_var(task)[SDMA_MAX_VAR];
+}
+
+static inline void sdma_set_tcr_initiator(int task, int initiator) {
+	u16 *tcr = &sdma.io->tcr[task];
+	out_be16(tcr, (in_be16(tcr) & ~0x1f00) | (initiator << 8));
+}
+
+#define SDMA_DRD_INITIATOR_SHIFT	21
+
+static inline int sdma_desc_initiator(u32 desc)
+{
+	return (desc >> SDMA_DRD_INITIATOR_SHIFT) & 0x1f;
+}
+
+static inline void sdma_set_desc_initiator(u32 *desc, int initiator)
+{
+	*desc = (*desc & ~(0x1f << SDMA_DRD_INITIATOR_SHIFT)) |
+			((initiator << SDMA_DRD_INITIATOR_SHIFT) & 0x1f);
+}
+
+static inline void sdma_submit_buffer(struct sdma *s, void *cookie, void *data,
+								int length)
+{
+#ifdef CONFIG_BESTCOMM_DEBUG
+	BUG_ON(s->flags & SDMA_FLAGS_BD2);
+#endif
+	s->cookie[s->index] = cookie;
+	s->bd[s->index].data = data;
+	s->bd[s->index].status = SDMA_BD_READY | length;
+	s->index = sdma_next_index(s);
+	if (s->flags & SDMA_FLAGS_ENABLE_TASK)
+		sdma_enable_task(s->tasknum);
+}
+
+/*
+ * Special submit_buffer function to submit last buffer of a frame to
+ * the FEC tx task.  tfd means "transmit frame done".
+ */
+static inline void sdma_fec_tfd_submit_buffer(struct sdma *s, void *cookie,
+							void *data, int length)
+{
+#ifdef CONFIG_BESTCOMM_DEBUG
+	BUG_ON(s->flags & SDMA_FLAGS_BD2);
+#endif
+	s->cookie[s->index] = cookie;
+	s->bd[s->index].data = data;
+	s->bd[s->index].status = SDMA_FEC_TX_BD_TFD_INIT | length;
+	s->index = sdma_next_index(s);
+	sdma_enable_task(s->tasknum);
+}
+
+static inline void *sdma_retrieve_buffer(struct sdma *s, int *length)
+{
+	void *cookie = s->cookie[s->outdex];
+
+#ifdef CONFIG_BESTCOMM_DEBUG
+	BUG_ON(s->flags & SDMA_FLAGS_BD2);
+#endif
+	if (length)
+		*length = s->bd[s->outdex].status & SDMA_LEN_MASK;
+	s->outdex = sdma_next_outdex(s);
+	return cookie;
+}
+
+static inline void sdma_submit_buffer2(struct sdma *s, void *cookie,
+					void *data1, void *data2, int length)
+{
+#ifdef CONFIG_BESTCOMM_DEBUG
+	BUG_ON(!(s->flags & SDMA_FLAGS_BD2));
+#endif
+	s->cookie[s->index] = cookie;
+	s->bd2[s->index].data1 = data1;
+	s->bd2[s->index].data2 = data2;
+	s->bd2[s->index].status = SDMA_BD_READY | length;
+	s->index = sdma_next_index(s);
+	if (s->flags & SDMA_FLAGS_ENABLE_TASK)
+		sdma_enable_task(s->tasknum);
+}
+
+static inline void *sdma_retrieve_buffer2(struct sdma *s, int *length)
+{
+	void *cookie = s->cookie[s->outdex];
+
+#ifdef CONFIG_BESTCOMM_DEBUG
+	BUG_ON(!(s->flags & SDMA_FLAGS_BD2));
+#endif
+	if (length)
+		*length = s->bd2[s->outdex].status & SDMA_LEN_MASK;
+	s->outdex = sdma_next_outdex(s);
+	return cookie;
+}
+
+#define SDMA_TASK_MAGIC		0x4243544B	/* 'BCTK' */
+
+/* the size fields are given in number of 32-bit words */
+struct sdma_task_header {
+	u32	magic;
+	u8	desc_size;
+	u8	var_size;
+	u8	inc_size;
+	u8	first_var;
+	u8	reserved[8];
+};
+
+#define SDMA_DESC_NOP		0x000001f8
+#define SDMA_LCD_MASK		0x80000000
+#define SDMA_DRD_EXTENDED	0x40000000
+
+#define sdma_drd_is_extended(desc) ((desc) & SDMA_DRD_EXTENDED)
+
+static inline int sdma_desc_is_drd(u32 desc) {
+	return !(desc & SDMA_LCD_MASK) && desc != SDMA_DESC_NOP;
+};
+
+#define SDMA_PRAGMA_BIT_RSV		7	/* reserved pragma bit */
+#define SDMA_PRAGMA_BIT_PRECISE_INC	6	/* increment 0=when possible, */
+						/*	1=iter end */
+#define SDMA_PRAGMA_BIT_RST_ERROR_NO	5	/* don't reset errors on */
+						/* task enable */
+#define SDMA_PRAGMA_BIT_PACK		4	/* pack data enable */
+#define SDMA_PRAGMA_BIT_INTEGER		3	/* data alignment */
+						/* 0=frac(msb), 1=int(lsb) */
+#define SDMA_PRAGMA_BIT_SPECREAD	2	/* XLB speculative read */
+#define SDMA_PRAGMA_BIT_CW		1	/* write line buffer enable */
+#define SDMA_PRAGMA_BIT_RL		0	/* read line buffer enable */
+
+#define SDMA_STD_PRAGMA		((0 << SDMA_PRAGMA_BIT_RSV)		| \
+				 (0 << SDMA_PRAGMA_BIT_PRECISE_INC)	| \
+				 (0 << SDMA_PRAGMA_BIT_RST_ERROR_NO)	| \
+				 (0 << SDMA_PRAGMA_BIT_PACK)		| \
+				 (0 << SDMA_PRAGMA_BIT_INTEGER)		| \
+				 (1 << SDMA_PRAGMA_BIT_SPECREAD)	| \
+				 (1 << SDMA_PRAGMA_BIT_CW)		| \
+				 (1 << SDMA_PRAGMA_BIT_RL))
+
+#define SDMA_PCI_PRAGMA		((0 << SDMA_PRAGMA_BIT_RSV)		| \
+				 (0 << SDMA_PRAGMA_BIT_PRECISE_INC)	| \
+				 (0 << SDMA_PRAGMA_BIT_RST_ERROR_NO)	| \
+				 (0 << SDMA_PRAGMA_BIT_PACK)		| \
+				 (1 << SDMA_PRAGMA_BIT_INTEGER)		| \
+				 (1 << SDMA_PRAGMA_BIT_SPECREAD)	| \
+				 (1 << SDMA_PRAGMA_BIT_CW)		| \
+				 (1 << SDMA_PRAGMA_BIT_RL))
+
+#define SDMA_ATA_PRAGMA		SDMA_STD_PRAGMA
+#define SDMA_CRC16_DP_0_PRAGMA	SDMA_STD_PRAGMA
+#define SDMA_CRC16_DP_1_PRAGMA	SDMA_STD_PRAGMA
+#define SDMA_FEC_RX_BD_PRAGMA	SDMA_STD_PRAGMA
+#define SDMA_FEC_TX_BD_PRAGMA	SDMA_STD_PRAGMA
+#define SDMA_GEN_DP_0_PRAGMA	SDMA_STD_PRAGMA
+#define SDMA_GEN_DP_1_PRAGMA	SDMA_STD_PRAGMA
+#define SDMA_GEN_DP_2_PRAGMA	SDMA_STD_PRAGMA
+#define SDMA_GEN_DP_3_PRAGMA	SDMA_STD_PRAGMA
+#define SDMA_GEN_DP_BD_0_PRAGMA	SDMA_STD_PRAGMA
+#define SDMA_GEN_DP_BD_1_PRAGMA	SDMA_STD_PRAGMA
+#define SDMA_GEN_RX_BD_PRAGMA	SDMA_STD_PRAGMA
+#define SDMA_GEN_TX_BD_PRAGMA	SDMA_STD_PRAGMA
+#define SDMA_GEN_LPC_PRAGMA	SDMA_STD_PRAGMA
+#define SDMA_PCI_RX_PRAGMA	SDMA_PCI_PRAGMA
+#define SDMA_PCI_TX_PRAGMA	SDMA_PCI_PRAGMA
+
+static inline void sdma_set_task_pragma(int task, int pragma)
+{
+	u32 *fdt = &sdma.tdt[task].fdt;
+	*fdt = (*fdt & ~0xff) | pragma;
+}
+
+static inline void sdma_set_task_auto_start(int task, int next_task)
+{
+	u16 *tcr = &sdma.io->tcr[task];
+	out_be16(tcr, (in_be16(tcr) & ~0xff) | 0x00c0 | next_task);
+}
+
+#define SDMA_INITIATOR_ALWAYS	 0
+#define SDMA_INITIATOR_SCTMR_0	 1
+#define SDMA_INITIATOR_SCTMR_1	 2
+#define SDMA_INITIATOR_FEC_RX	 3
+#define SDMA_INITIATOR_FEC_TX	 4
+#define SDMA_INITIATOR_ATA_RX	 5
+#define SDMA_INITIATOR_ATA_TX	 6
+#define SDMA_INITIATOR_SCPCI_RX	 7
+#define SDMA_INITIATOR_SCPCI_TX	 8
+#define SDMA_INITIATOR_PSC3_RX	 9
+#define SDMA_INITIATOR_PSC3_TX	10
+#define SDMA_INITIATOR_PSC2_RX	11
+#define SDMA_INITIATOR_PSC2_TX	12
+#define SDMA_INITIATOR_PSC1_RX	13
+#define SDMA_INITIATOR_PSC1_TX	14
+#define SDMA_INITIATOR_SCTMR_2	15
+#define SDMA_INITIATOR_SCLPC	16
+#define SDMA_INITIATOR_PSC5_RX	17
+#define SDMA_INITIATOR_PSC5_TX	18
+#define SDMA_INITIATOR_PSC4_RX	19
+#define SDMA_INITIATOR_PSC4_TX	20
+#define SDMA_INITIATOR_I2C2_RX	21
+#define SDMA_INITIATOR_I2C2_TX	22
+#define SDMA_INITIATOR_I2C1_RX	23
+#define SDMA_INITIATOR_I2C1_TX	24
+#define SDMA_INITIATOR_PSC6_RX	25
+#define SDMA_INITIATOR_PSC6_TX	26
+#define SDMA_INITIATOR_IRDA_RX	25
+#define SDMA_INITIATOR_IRDA_TX	26
+#define SDMA_INITIATOR_SCTMR_3	27
+#define SDMA_INITIATOR_SCTMR_4	28
+#define SDMA_INITIATOR_SCTMR_5	29
+#define SDMA_INITIATOR_SCTMR_6	30
+#define SDMA_INITIATOR_SCTMR_7	31
+
+#define SDMA_IPR_ALWAYS	7
+#define SDMA_IPR_SCTMR_0 	2
+#define SDMA_IPR_SCTMR_1 	2
+#define SDMA_IPR_FEC_RX 	6
+#define SDMA_IPR_FEC_TX 	5
+#define SDMA_IPR_ATA_RX 	4
+#define SDMA_IPR_ATA_TX 	3
+#define SDMA_IPR_SCPCI_RX	2
+#define SDMA_IPR_SCPCI_TX	2
+#define SDMA_IPR_PSC3_RX	2
+#define SDMA_IPR_PSC3_TX	2
+#define SDMA_IPR_PSC2_RX	2
+#define SDMA_IPR_PSC2_TX	2
+#define SDMA_IPR_PSC1_RX	2
+#define SDMA_IPR_PSC1_TX	2
+#define SDMA_IPR_SCTMR_2	2
+#define SDMA_IPR_SCLPC		2
+#define SDMA_IPR_PSC5_RX	2
+#define SDMA_IPR_PSC5_TX	2
+#define SDMA_IPR_PSC4_RX	2
+#define SDMA_IPR_PSC4_TX	2
+#define SDMA_IPR_I2C2_RX	2
+#define SDMA_IPR_I2C2_TX	2
+#define SDMA_IPR_I2C1_RX	2
+#define SDMA_IPR_I2C1_TX	2
+#define SDMA_IPR_PSC6_RX	2
+#define SDMA_IPR_PSC6_TX	2
+#define SDMA_IPR_IRDA_RX	2
+#define SDMA_IPR_IRDA_TX	2
+#define SDMA_IPR_SCTMR_3	2
+#define SDMA_IPR_SCTMR_4	2
+#define SDMA_IPR_SCTMR_5	2
+#define SDMA_IPR_SCTMR_6	2
+#define SDMA_IPR_SCTMR_7	2
+
+extern struct sdma *sdma_alloc(int request_queue_size);
+extern void sdma_free(struct sdma *sdma_struct);
+extern int sdma_load_task(u32 *task_image);
+extern void *sdma_sram_alloc(int size, int alignment, u32 *dma_handle);
+extern void sdma_init_bd(struct sdma *s);
+extern void sdma_init_bd2(struct sdma *s);
+
+#define FIELD_OFFSET(s,f) ((unsigned long)(&(((struct s*)0)->f)))
+
+#endif  /* __BESTCOMM_BESTCOMM_H__ */
diff -uNr linux-2.6.20.ppc64/arch/powerpc/platforms/52xx/Makefile linux-2.6.20.fec/arch/powerpc/platforms/52xx/Makefile
--- linux-2.6.20.ppc64/arch/powerpc/platforms/52xx/Makefile	2007-03-22 11:17:52.000000000 +0000
+++ linux-2.6.20.fec/arch/powerpc/platforms/52xx/Makefile	2007-03-27 23:23:04.000000000 +0100
@@ -4,6 +4,7 @@
 ifeq ($(CONFIG_PPC_MERGE),y)
 obj-y				+= mpc52xx_pic.o mpc52xx_common.o
 obj-$(CONFIG_PCI)		+= mpc52xx_pci.o
+obj-$(CONFIG_PPC_BESTCOMM) 	+= bestcomm.o
 endif
 
 obj-$(CONFIG_PPC_EFIKA)		+= efika.o

linux-2.6-net-e1000-no-msi-warning.patch:

--- NEW FILE linux-2.6-net-e1000-no-msi-warning.patch ---
commit e94bd23f67c87011f012f26ca0af3fcf6878eeac
Author: Auke Kok <auke-jan.h.kok at intel.com>
Date:   Wed May 16 01:49:46 2007 -0700

    e1000: Fix msi enable leak on error, don't print error message, cleanup
    
    pci_enable_msi failure is a normal event so we should not print any error.
    Going over the code I spotted a missing pci_disable_msi() leak when irq
    allocation fails. The whole code also needed a cleanup, so I combined the
    two different calls to pci_request_irq into a single call making this
    look a lot better. All #ifdef CONFIG_PCI_MSI's have been removed.
    
    Compile tested with both CONFIG_PCI_MSI enabled and disabled.
    
    Signed-off-by: Auke Kok <auke-jan.h.kok at intel.com>
    Cc: H. Peter Anvin <hpa at zytor.com>
    Signed-off-by: Jeff Garzik <jeff at garzik.org>

diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h
index a9ea67e..16a6edf 100644
--- a/drivers/net/e1000/e1000.h
+++ b/drivers/net/e1000/e1000.h
@@ -333,11 +333,9 @@ struct e1000_adapter {
 	struct e1000_tx_ring test_tx_ring;
 	struct e1000_rx_ring test_rx_ring;
 
-
 	int msg_enable;
-#ifdef CONFIG_PCI_MSI
 	boolean_t have_msi;
-#endif
+
 	/* to not mess up cache alignment, always add to the bottom */
 	boolean_t tso_force;
 	boolean_t smart_power_down;	/* phy smart power down */
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 637ae8f..49be393 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -158,9 +158,7 @@ static struct net_device_stats * e1000_get_stats(struct net_device *netdev);
 static int e1000_change_mtu(struct net_device *netdev, int new_mtu);
 static int e1000_set_mac(struct net_device *netdev, void *p);
 static irqreturn_t e1000_intr(int irq, void *data);
-#ifdef CONFIG_PCI_MSI
 static irqreturn_t e1000_intr_msi(int irq, void *data);
-#endif
 static boolean_t e1000_clean_tx_irq(struct e1000_adapter *adapter,
                                     struct e1000_tx_ring *tx_ring);
 #ifdef CONFIG_E1000_NAPI
@@ -300,31 +298,26 @@ module_exit(e1000_exit_module);
 static int e1000_request_irq(struct e1000_adapter *adapter)
 {
 	struct net_device *netdev = adapter->netdev;
-	int flags, err = 0;
+	void (*handler) = &e1000_intr;
+	int irq_flags = IRQF_SHARED;
+	int err;
 
-	flags = IRQF_SHARED;
-#ifdef CONFIG_PCI_MSI
 	if (adapter->hw.mac_type >= e1000_82571) {
-		adapter->have_msi = TRUE;
-		if ((err = pci_enable_msi(adapter->pdev))) {
-			DPRINTK(PROBE, ERR,
-			 "Unable to allocate MSI interrupt Error: %d\n", err);
-			adapter->have_msi = FALSE;
+		adapter->have_msi = !pci_enable_msi(adapter->pdev);
+		if (adapter->have_msi) {
+			handler = &e1000_intr_msi;
+			irq_flags = 0;
 		}
 	}
-	if (adapter->have_msi) {
-		flags &= ~IRQF_SHARED;
-		err = request_irq(adapter->pdev->irq, &e1000_intr_msi, flags,
-		                  netdev->name, netdev);
-		if (err)
-			DPRINTK(PROBE, ERR,
-			       "Unable to allocate interrupt Error: %d\n", err);
-	} else
-#endif
-	if ((err = request_irq(adapter->pdev->irq, &e1000_intr, flags,
-	                       netdev->name, netdev)))
+
+	err = request_irq(adapter->pdev->irq, handler, irq_flags, netdev->name,
+	                  netdev);
+	if (err) {
+		if (adapter->have_msi)
+			pci_disable_msi(adapter->pdev);
 		DPRINTK(PROBE, ERR,
 		        "Unable to allocate interrupt Error: %d\n", err);
+	}
 
 	return err;
 }
@@ -335,10 +328,8 @@ static void e1000_free_irq(struct e1000_adapter *adapter)
 
 	free_irq(adapter->pdev->irq, netdev);
 
-#ifdef CONFIG_PCI_MSI
 	if (adapter->have_msi)
 		pci_disable_msi(adapter->pdev);
-#endif
 }
 
 /**
@@ -3744,7 +3735,6 @@ e1000_update_stats(struct e1000_adapter *adapter)
 
 	spin_unlock_irqrestore(&adapter->stats_lock, flags);
 }
-#ifdef CONFIG_PCI_MSI
 
 /**
  * e1000_intr_msi - Interrupt Handler
@@ -3810,7 +3800,6 @@ e1000_intr_msi(int irq, void *data)
 
 	return IRQ_HANDLED;
 }
-#endif
 
 /**
  * e1000_intr - Interrupt Handler

linux-2.6-net-silence-noisy-printks.patch:

--- NEW FILE linux-2.6-net-silence-noisy-printks.patch ---
These messages are trivial to trigger when running stress tests
like isic, and add no real value afaict.  Make them go away
instead of filling up logs pointlessly.

Signed-off-by: Dave Jones <davej at redhat.com>

diff --git a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c
index 56b2f75..b2b36c7 100644
--- a/net/ipv4/netfilter/ip_conntrack_standalone.c
+++ b/net/ipv4/netfilter/ip_conntrack_standalone.c
@@ -458,11 +458,8 @@ static unsigned int ip_conntrack_local(unsigned int hooknum,
 {
 	/* root is playing with raw sockets. */
 	if ((*pskb)->len < sizeof(struct iphdr)
-	    || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr)) {
-		if (net_ratelimit())
-			printk("ipt_hook: happy cracking.\n");
+	    || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr))
 		return NF_ACCEPT;
-	}
 	return ip_conntrack_in(hooknum, pskb, in, out, okfn);
 }
 
diff --git a/net/ipv4/netfilter/iptable_filter.c b/net/ipv4/netfilter/iptable_filter.c
index d1d61e9..acd903e 100644
--- a/net/ipv4/netfilter/iptable_filter.c
+++ b/net/ipv4/netfilter/iptable_filter.c
@@ -102,11 +102,8 @@ ipt_local_out_hook(unsigned int hook,
 {
 	/* root is playing with raw sockets. */
 	if ((*pskb)->len < sizeof(struct iphdr)
-	    || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr)) {
-		if (net_ratelimit())
-			printk("ipt_hook: happy cracking.\n");
+	    || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr))
 		return NF_ACCEPT;
-	}
 
 	return ipt_do_table(pskb, hook, in, out, &packet_filter);
 }
diff --git a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c
index 98b66ef..8d7bf96 100644
--- a/net/ipv4/netfilter/iptable_mangle.c
+++ b/net/ipv4/netfilter/iptable_mangle.c
@@ -136,11 +136,8 @@ ipt_local_hook(unsigned int hook,
 
 	/* root is playing with raw sockets. */
 	if ((*pskb)->len < sizeof(struct iphdr)
-	    || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr)) {
-		if (net_ratelimit())
-			printk("ipt_hook: happy cracking.\n");
+	    || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr))
 		return NF_ACCEPT;
-	}
 
 	/* Save things which could affect route */
 	mark = (*pskb)->mark;
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index 8f3e92d..4e3d6f6 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -199,11 +199,8 @@ static unsigned int ipv4_conntrack_local(unsigned int hooknum,
 {
 	/* root is playing with raw sockets. */
 	if ((*pskb)->len < sizeof(struct iphdr)
-	    || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr)) {
-		if (net_ratelimit())
-			printk("ipt_hook: happy cracking.\n");
+	    || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr))
 		return NF_ACCEPT;
-	}
 	return nf_conntrack_in(PF_INET, hooknum, pskb);
 }
 
diff --git a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c
index 112a21d..847e6a4 100644
--- a/net/ipv6/netfilter/ip6table_filter.c
+++ b/net/ipv6/netfilter/ip6table_filter.c
@@ -102,11 +102,8 @@ ip6t_local_out_hook(unsigned int hook,
 #if 0
 	/* root is playing with raw sockets. */
 	if ((*pskb)->len < sizeof(struct iphdr)
-	    || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr)) {
-		if (net_ratelimit())
-			printk("ip6t_hook: happy cracking.\n");
+	    || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr))
 		return NF_ACCEPT;
-	}
 #endif
 
 	return ip6t_do_table(pskb, hook, in, out, &packet_filter);
diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c
index 0c468d3..6c80e35 100644
--- a/net/ipv6/netfilter/ip6table_mangle.c
+++ b/net/ipv6/netfilter/ip6table_mangle.c
@@ -138,11 +138,8 @@ ip6t_local_hook(unsigned int hook,
 #if 0
 	/* root is playing with raw sockets. */
 	if ((*pskb)->len < sizeof(struct iphdr)
-	    || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr)) {
-		if (net_ratelimit())
-			printk("ip6t_hook: happy cracking.\n");
+	    || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr))
 		return NF_ACCEPT;
-	}
 #endif
 
 	/* save source/dest address, mark, hoplimit, flowlabel, priority,  */



Remove noisy, easy to trigger (as user even, with sfuzz) printk.

Signed-off-by: Dave Jones <davej at redhat.com>

--- linux-2.6.20.noarch/net/irda/af_irda.c~	2007-04-19 19:07:21.000000000 -0400
+++ linux-2.6.20.noarch/net/irda/af_irda.c	2007-04-19 19:07:28.000000000 -0400
@@ -1143,8 +1143,6 @@ static int irda_create(struct socket *so
 			self->max_sdu_size_rx = TTP_SAR_UNBOUND;
 			break;
 		default:
-			IRDA_ERROR("%s: protocol not supported!\n",
-				   __FUNCTION__);
 			return -ESOCKTNOSUPPORT;
 		}
 		break;

linux-2.6-netdev-e1000e-01.patch:

--- NEW FILE linux-2.6-netdev-e1000e-01.patch ---
From: Auke Kok <auke-jan.h.kok at intel.com>
Date: Mon, 6 Aug 2007 21:14:44 +0000 (-0700)
Subject: e1000e: New pci-express e1000 driver (currently for ICH9 devices only)
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fjgarzik%2Fnetdev-2.6.git;a=commitdiff_plain;h=5b663b9d5d5d56209c2ea0cf636c8aea172065b8

e1000e: New pci-express e1000 driver (currently for ICH9 devices only)

This driver implements support for the ICH9 on-board LAN ethernet
device. The device is similar to ICH8.

The driver encompasses code to support 82571/2/3, es2lan and ICH8
devices as well, but those device IDs are disabled and will be
"lifted" from the e1000 driver over one at a time once this driver
receives some more live time.

Changes to the last snapshot posted are exclusively in the internal
hardware API organization. Many thanks to Jeff Garzik for jumping in
and getting this organized with a keen eye on the future layout.

Signed-off-by: Auke Kok <auke-jan.h.kok at intel.com>
Signed-off-by: Jeff Garzik <jeff at garzik.org>
---

diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 81ef81c..e5f2f02 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2059,6 +2059,29 @@ config E1000_DISABLE_PACKET_SPLIT
 
 	  If in doubt, say N.
 
+config E1000E
+	tristate "Intel(R) PRO/1000 PCI-Express Gigabit Ethernet support"
+	depends on PCI
+	---help---
+	  This driver supports the PCI-Express Intel(R) PRO/1000 gigabit
+	  ethernet family of adapters. For PCI or PCI-X e1000 adapters,
+	  use the regular e1000 driver For more information on how to
+	  identify your adapter, go to the Adapter & Driver ID Guide at:
+
+	  <http://support.intel.com/support/network/adapter/pro100/21397.htm>
+
+	  For general information and support, go to the Intel support
+	  website at:
+
+	  <http://support.intel.com>
+
+	  More specific information on configuring the driver is in
+	  <file:Documentation/networking/e1000e.txt>.
+
+	  To compile this driver as a module, choose M here and read
+	  <file:Documentation/networking/net-modules.txt>.  The module
+	  will be called e1000e.
+
 source "drivers/net/ixp2000/Kconfig"
 
 config MYRI_SBUS
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index e684212..4140a0c 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -3,6 +3,7 @@
 #
 
 obj-$(CONFIG_E1000) += e1000/
+obj-$(CONFIG_E1000E) += e1000e/
 obj-$(CONFIG_IBM_EMAC) += ibm_emac/
 obj-$(CONFIG_IXGB) += ixgb/
 obj-$(CONFIG_CHELSIO_T1) += chelsio/
diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c
new file mode 100644
index 0000000..a1b9d16
--- /dev/null
+++ b/drivers/net/e1000e/82571.c
@@ -0,0 +1,1382 @@
+/*******************************************************************************
+
+  Intel PRO/1000 Linux driver
+  Copyright(c) 1999 - 2007 Intel Corporation.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope 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 St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Contact Information:
+  Linux NICS <linux.nics at intel.com>
+  e1000-devel Mailing List <e1000-devel at lists.sourceforge.net>
+  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+/*
+ * 82571EB Gigabit Ethernet Controller
+ * 82571EB Gigabit Ethernet Controller (Fiber)
+ * 82572EI Gigabit Ethernet Controller (Copper)
+ * 82572EI Gigabit Ethernet Controller (Fiber)
+ * 82572EI Gigabit Ethernet Controller
+ * 82573V Gigabit Ethernet Controller (Copper)
+ * 82573E Gigabit Ethernet Controller (Copper)
+ * 82573L Gigabit Ethernet Controller
+ */
+
+#include "e1000.h"
+
+#define ID_LED_RESERVED_F746 0xF746
+#define ID_LED_DEFAULT_82573 ((ID_LED_DEF1_DEF2 << 12) | \
+			      (ID_LED_OFF1_ON2  <<  8) | \
+			      (ID_LED_DEF1_DEF2 <<  4) | \
+			      (ID_LED_DEF1_DEF2))
+
+#define E1000_GCR_L1_ACT_WITHOUT_L0S_RX 0x08000000
+
+static s32 e1000_get_phy_id_82571(struct e1000_hw *hw);
+static s32 e1000_setup_copper_link_82571(struct e1000_hw *hw);
+static s32 e1000_setup_fiber_serdes_link_82571(struct e1000_hw *hw);
+static s32 e1000_get_phy_id_82571(struct e1000_hw *hw);
+static s32 e1000_write_nvm_eewr_82571(struct e1000_hw *hw, u16 offset,
+				      u16 words, u16 *data);
+static s32 e1000_fix_nvm_checksum_82571(struct e1000_hw *hw);
+static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw);
+static s32 e1000_setup_link_82571(struct e1000_hw *hw);
+static void e1000_clear_hw_cntrs_82571(struct e1000_hw *hw);
+
+/**
+ *  e1000_init_phy_params_82571 - Init PHY func ptrs.
+ *  @hw: pointer to the HW structure
+ *
+ *  This is a function pointer entry point called by the api module.
+ **/
+static s32 e1000_init_phy_params_82571(struct e1000_hw *hw)
+{
+	struct e1000_phy_info *phy = &hw->phy;
+	s32 ret_val = E1000_SUCCESS;
+
+	if (hw->media_type != e1000_media_type_copper) {
+		phy->type = e1000_phy_none;
+		goto out;
+	}
+
+	phy->addr			 = 1;
+	phy->autoneg_mask		 = AUTONEG_ADVERTISE_SPEED_DEFAULT;
+	phy->reset_delay_us		 = 100;
+
+	switch (hw->mac.type) {
+	case e1000_82571:
+	case e1000_82572:
+		phy->type		 = e1000_phy_igp_2;
+		break;
+	case e1000_82573:
+		phy->type		 = e1000_phy_m88;
+		break;
+	default:
+		ret_val = -E1000_ERR_PHY;
+		goto out;
+		break;
+	}
+
+	/* This can only be done after all function pointers are setup. */
+	ret_val = e1000_get_phy_id_82571(hw);
+
+	/* Verify phy id */
+	switch (hw->mac.type) {
+	case e1000_82571:
+	case e1000_82572:
+		if (phy->id != IGP01E1000_I_PHY_ID) {
+			ret_val = -E1000_ERR_PHY;
+			goto out;
+		}
+		break;
+	case e1000_82573:
+		if (phy->id != M88E1111_I_PHY_ID) {
+			ret_val = -E1000_ERR_PHY;
+			goto out;
+		}
+		break;
+	default:
+		ret_val = -E1000_ERR_PHY;
+		goto out;
+		break;
+	}
+
+out:
+	return ret_val;
+}
+
+/**
+ *  e1000_init_nvm_params_82571 - Init NVM func ptrs.
[...17738 lines suppressed...]
+		phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED;
+		phy->local_rx = e1000_1000t_rx_status_undefined;
+		phy->remote_rx = e1000_1000t_rx_status_undefined;
+	}
+
+out:
+	return ret_val;
+}
+
+/**
+ *  e1000_phy_sw_reset - PHY software reset
+ *  @hw: pointer to the HW structure
+ *
+ *  Does a software reset of the PHY by reading the PHY control register and
+ *  setting/write the control register reset bit to the PHY.
+ **/
+s32 e1000_phy_sw_reset(struct e1000_hw *hw)
+{
+	s32 ret_val;
+	u16 phy_ctrl;
+
+	ret_val = e1e_rphy(hw, PHY_CONTROL, &phy_ctrl);
+	if (ret_val)
+		goto out;
+
+	phy_ctrl |= MII_CR_RESET;
+	ret_val = e1e_wphy(hw, PHY_CONTROL, phy_ctrl);
+	if (ret_val)
+		goto out;
+
+	udelay(1);
+
+out:
+	return ret_val;
+}
+
+/**
+ *  e1000_phy_hw_reset_generic - PHY hardware reset
+ *  @hw: pointer to the HW structure
+ *
+ *  Verify the reset block is not blocking us from resetting.  Acquire
+ *  semaphore (if necessary) and read/set/write the device control reset
+ *  bit in the PHY.  Wait the appropriate delay time for the device to
+ *  reset and relase the semaphore (if necessary).
+ **/
+s32 e1000_phy_hw_reset_generic(struct e1000_hw *hw)
+{
+	struct e1000_phy_info *phy = &hw->phy;
+	s32  ret_val;
+	u32 ctrl;
+
+	ret_val = e1000_check_reset_block(hw);
+	if (ret_val) {
+		ret_val = E1000_SUCCESS;
+		goto out;
+	}
+
+	ret_val = phy->ops.acquire_phy(hw);
+	if (ret_val)
+		goto out;
+
+	ctrl = er32(CTRL);
+	ew32(CTRL, ctrl | E1000_CTRL_PHY_RST);
+	e1e_flush();
+
+	udelay(phy->reset_delay_us);
+
+	ew32(CTRL, ctrl);
+	e1e_flush();
+
+	udelay(150);
+
+	phy->ops.release_phy(hw);
+
+	ret_val = e1000_get_phy_cfg_done(hw);
+
+out:
+	return ret_val;
+}
+
+/**
+ *  e1000_get_cfg_done - Generic configuration done
+ *  @hw: pointer to the HW structure
+ *
+ *  Generic function to wait 10 milli-seconds for configuration to complete
+ *  and return success.
+ **/
+s32 e1000_get_cfg_done(struct e1000_hw *hw)
+{
+	mdelay(10);
+
+	return E1000_SUCCESS;
+}
+
+/* Internal function pointers */
+
+/**
+ *  e1000_get_phy_cfg_done - Generic PHY configuration done
+ *  @hw: pointer to the HW structure
+ *
+ *  Return success if silicon family did not implement a family specific
+ *  get_cfg_done function.
+ **/
+static s32 e1000_get_phy_cfg_done(struct e1000_hw *hw)
+{
+	if (hw->phy.ops.get_cfg_done)
+		return hw->phy.ops.get_cfg_done(hw);
+	else
+		return E1000_SUCCESS;
+}
+
+/**
+ *  e1000_phy_force_speed_duplex - Generic force PHY speed/duplex
+ *  @hw: pointer to the HW structure
+ *
+ *  When the silicon family has not implemented a forced speed/duplex
+ *  function for the PHY, simply return E1000_SUCCESS.
+ **/
+static s32 e1000_phy_force_speed_duplex(struct e1000_hw *hw)
+{
+	if (hw->phy.ops.force_speed_duplex)
+		return hw->phy.ops.force_speed_duplex(hw);
+	else
+		return E1000_SUCCESS;
+}
+
+/**
+ *  e1000_get_phy_type_from_id - Get PHY type from id
+ *  @phy_id: phy_id read from the phy
+ *
+ *  Returns the phy type from the id.
+ **/
+enum e1000_phy_type e1000_get_phy_type_from_id(u32 phy_id)
+{
+	enum e1000_phy_type phy_type = e1000_phy_unknown;
+
+	switch (phy_id) {
+	case M88E1000_I_PHY_ID:
+	case M88E1000_E_PHY_ID:
+	case M88E1111_I_PHY_ID:
+	case M88E1011_I_PHY_ID:
+		phy_type = e1000_phy_m88;
+		break;
+	case IGP01E1000_I_PHY_ID: /* IGP 1 & 2 share this */
+		phy_type = e1000_phy_igp_2;
+		break;
+	case GG82563_E_PHY_ID:
+		phy_type = e1000_phy_gg82563;
+		break;
+	case IGP03E1000_E_PHY_ID:
+		phy_type = e1000_phy_igp_3;
+		break;
+	case IFE_E_PHY_ID:
+	case IFE_PLUS_E_PHY_ID:
+	case IFE_C_E_PHY_ID:
+		phy_type = e1000_phy_ife;
+		break;
+	default:
+		phy_type = e1000_phy_unknown;
+		break;
+	}
+	return phy_type;
+}
+
+/**
+ *  e1000_commit_phy - Soft PHY reset
+ *  @hw: pointer to the HW structure
+ *
+ *  Performs a soft PHY reset on those that apply. This is a function pointer
+ *  entry point called by drivers.
+ **/
+s32 e1000_commit_phy(struct e1000_hw *hw)
+{
+	if (hw->phy.ops.commit_phy)
+		return hw->phy.ops.commit_phy(hw);
+	else
+		return E1000_SUCCESS;
+}
+
+/**
+ *  e1000_set_d0_lplu_state - Sets low power link up state for D0
+ *  @hw: pointer to the HW structure
+ *  @active: boolean used to enable/disable lplu
+ *
+ *  Success returns 0, Failure returns 1
+ *
+ *  The low power link up (lplu) state is set to the power management level D0
+ *  and SmartSpeed is disabled when active is true, else clear lplu for D0
+ *  and enable Smartspeed.  LPLU and Smartspeed are mutually exclusive.  LPLU
+ *  is used during Dx states where the power conservation is most important.
+ *  During driver activity, SmartSpeed should be enabled so performance is
+ *  maintained.  This is a function pointer entry point called by drivers.
+ **/
+s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active)
+{
+	if (hw->phy.ops.set_d0_lplu_state)
+		return hw->phy.ops.set_d0_lplu_state(hw, active);
+	else
+		return E1000_SUCCESS;
+}

linux-2.6-netdev-e1000e-02.patch:

--- NEW FILE linux-2.6-netdev-e1000e-02.patch ---
From: Auke Kok <auke-jan.h.kok at intel.com>
Date: Wed, 8 Aug 2007 17:21:52 +0000 (-0700)
Subject: e1000e: Remove unused or empty labels
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fjgarzik%2Fnetdev-2.6.git;a=commitdiff_plain;h=3ee7c3bfcc0cc2048cc5d53dd792375e52fe930c

e1000e: Remove unused or empty labels

Remove labels with only return, remove E1000_SUCCESS code and
replace with 0. Remove most goto's.

Signed-off-by: Auke Kok <auke-jan.h.kok at intel.com>
Signed-off-by: Jeff Garzik <jeff at garzik.org>
---

diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c
index a1b9d16..ddf2303 100644
--- a/drivers/net/e1000e/82571.c
+++ b/drivers/net/e1000e/82571.c
@@ -67,11 +67,11 @@ static void e1000_clear_hw_cntrs_82571(struct e1000_hw *hw);
 static s32 e1000_init_phy_params_82571(struct e1000_hw *hw)
 {
 	struct e1000_phy_info *phy = &hw->phy;
-	s32 ret_val = E1000_SUCCESS;
+	s32 ret_val;
 
 	if (hw->media_type != e1000_media_type_copper) {
 		phy->type = e1000_phy_none;
-		goto out;
+		return 0;
 	}
 
 	phy->addr			 = 1;
@@ -87,8 +87,7 @@ static s32 e1000_init_phy_params_82571(struct e1000_hw *hw)
 		phy->type		 = e1000_phy_m88;
 		break;
 	default:
-		ret_val = -E1000_ERR_PHY;
-		goto out;
+		return -E1000_ERR_PHY;
 		break;
 	}
 
@@ -99,25 +98,19 @@ static s32 e1000_init_phy_params_82571(struct e1000_hw *hw)
 	switch (hw->mac.type) {
 	case e1000_82571:
 	case e1000_82572:
-		if (phy->id != IGP01E1000_I_PHY_ID) {
-			ret_val = -E1000_ERR_PHY;
-			goto out;
-		}
+		if (phy->id != IGP01E1000_I_PHY_ID)
+			return -E1000_ERR_PHY;
 		break;
 	case e1000_82573:
-		if (phy->id != M88E1111_I_PHY_ID) {
-			ret_val = -E1000_ERR_PHY;
-			goto out;
-		}
+		if (phy->id != M88E1111_I_PHY_ID)
+			return -E1000_ERR_PHY;
 		break;
 	default:
-		ret_val = -E1000_ERR_PHY;
-		goto out;
+		return -E1000_ERR_PHY;
 		break;
 	}
 
-out:
-	return ret_val;
+	return 0;
 }
 
 /**
@@ -174,7 +167,7 @@ static s32 e1000_init_nvm_params_82571(struct e1000_hw *hw)
 		break;
 	}
 
-	return E1000_SUCCESS;
+	return 0;
 }
 
 /**
@@ -188,7 +181,6 @@ static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter)
 	struct e1000_hw *hw = &adapter->hw;
 	struct e1000_mac_info *mac = &hw->mac;
 	struct e1000_mac_operations *func = &mac->ops;
-	s32 ret_val = E1000_SUCCESS;
 
 	/* Set media type */
 	switch (adapter->pdev->device) {
@@ -232,13 +224,11 @@ static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter)
 		func->get_link_up_info = e1000_get_speed_and_duplex_fiber_serdes;
 		break;
 	default:
-		ret_val = -E1000_ERR_CONFIG;
-		goto out;
+		return -E1000_ERR_CONFIG;
 		break;
 	}
 
-out:
-	return ret_val;
+	return 0;
 }
 
 static s32 e1000_get_invariants_82571(struct e1000_adapter *adapter)
@@ -306,7 +296,7 @@ static s32 e1000_get_invariants_82571(struct e1000_adapter *adapter)
 		break;
 	}
 
-	return E1000_SUCCESS;
+	return 0;
 }
 
 /**
@@ -319,7 +309,6 @@ static s32 e1000_get_invariants_82571(struct e1000_adapter *adapter)
 static s32 e1000_get_phy_id_82571(struct e1000_hw *hw)
 {
 	struct e1000_phy_info *phy = &hw->phy;
-	s32 ret_val = E1000_SUCCESS;
 
 	switch (hw->mac.type) {
 	case e1000_82571:
@@ -331,14 +320,14 @@ static s32 e1000_get_phy_id_82571(struct e1000_hw *hw)
 		phy->id = IGP01E1000_I_PHY_ID;
 		break;
 	case e1000_82573:
-		ret_val = e1000_get_phy_id(hw);
+		return e1000_get_phy_id(hw);
 		break;
 	default:
-		ret_val = -E1000_ERR_PHY;
+		return -E1000_ERR_PHY;
 		break;
 	}
 
-	return ret_val;
+	return 0;
 }
 
 /**
@@ -350,7 +339,6 @@ static s32 e1000_get_phy_id_82571(struct e1000_hw *hw)
 static s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw)
 {
 	u32 swsm;
-	s32 ret_val = E1000_SUCCESS;
 	s32 timeout = hw->nvm.word_size + 1;
 	s32 i = 0;
 
@@ -370,12 +358,10 @@ static s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw)
 		/* Release semaphores */
 		e1000_put_hw_semaphore(hw);
 		hw_dbg(hw, "Driver can't access the NVM\n");
-		ret_val = -E1000_ERR_NVM;
-		goto out;
+		return -E1000_ERR_NVM;
 	}
 
-out:
-	return ret_val;
+	return 0;
 }
 
 /**
@@ -410,7 +396,7 @@ static s32 e1000_acquire_nvm_82571(struct e1000_hw *hw)
 
 	ret_val = e1000_get_hw_semaphore_82571(hw);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	if (hw->mac.type != e1000_82573)
 		ret_val = e1000_acquire_nvm(hw);
@@ -418,7 +404,6 @@ static s32 e1000_acquire_nvm_82571(struct e1000_hw *hw)
 	if (ret_val)
 		e1000_put_hw_semaphore_82571(hw);
 
-out:
 	return ret_val;
 }
 
@@ -449,7 +434,7 @@ static void e1000_release_nvm_82571(struct e1000_hw *hw)
 static s32 e1000_write_nvm_82571(struct e1000_hw *hw, u16 offset, u16 words,
 				 u16 *data)
 {
-	s32 ret_val = E1000_SUCCESS;
+	s32 ret_val;
 
 	switch (hw->mac.type) {
 	case e1000_82573:
@@ -483,12 +468,12 @@ static s32 e1000_update_nvm_checksum_82571(struct e1000_hw *hw)
 
 	ret_val = e1000_update_nvm_checksum_generic(hw);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	/* If our nvm is an EEPROM, then we're done
[...3959 lines suppressed...]
 
 	phy->polarity_correction = (phy_data &
 				    M88E1000_PSCR_POLARITY_REVERSAL);
 
 	ret_val = e1000_check_polarity_m88(hw);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	ret_val = e1e_rphy(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	phy->is_mdix = (phy_data & M88E1000_PSSR_MDIX);
 
 	if ((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS) {
 		ret_val = e1000_get_cable_length(hw);
 		if (ret_val)
-			goto out;
+			return ret_val;
 
 		ret_val = e1e_rphy(hw, PHY_1000T_STATUS, &phy_data);
 		if (ret_val)
-			goto out;
+			return ret_val;
 
 		phy->local_rx = (phy_data & SR_1000T_LOCAL_RX_STATUS)
 				? e1000_1000t_rx_status_ok
@@ -1559,7 +1517,6 @@ s32 e1000_get_phy_info_m88(struct e1000_hw *hw)
 		phy->remote_rx = e1000_1000t_rx_status_undefined;
 	}
 
-out:
 	return ret_val;
 }
 
@@ -1581,23 +1538,22 @@ s32 e1000_get_phy_info_igp(struct e1000_hw *hw)
 
 	ret_val = e1000_phy_has_link_generic(hw, 1, 0, &link);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	if (!link) {
 		hw_dbg(hw, "Phy info is only valid if link is up\n");
-		ret_val = -E1000_ERR_CONFIG;
-		goto out;
+		return -E1000_ERR_CONFIG;
 	}
 
 	phy->polarity_correction = 1;
 
 	ret_val = e1000_check_polarity_igp(hw);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_STATUS, &data);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	phy->is_mdix = (data & IGP01E1000_PSSR_MDIX);
 
@@ -1605,11 +1561,11 @@ s32 e1000_get_phy_info_igp(struct e1000_hw *hw)
 	    IGP01E1000_PSSR_SPEED_1000MBPS) {
 		ret_val = e1000_get_cable_length(hw);
 		if (ret_val)
-			goto out;
+			return ret_val;
 
 		ret_val = e1e_rphy(hw, PHY_1000T_STATUS, &data);
 		if (ret_val)
-			goto out;
+			return ret_val;
 
 		phy->local_rx = (data & SR_1000T_LOCAL_RX_STATUS)
 				? e1000_1000t_rx_status_ok
@@ -1624,7 +1580,6 @@ s32 e1000_get_phy_info_igp(struct e1000_hw *hw)
 		phy->remote_rx = e1000_1000t_rx_status_undefined;
 	}
 
-out:
 	return ret_val;
 }
 
@@ -1642,16 +1597,15 @@ s32 e1000_phy_sw_reset(struct e1000_hw *hw)
 
 	ret_val = e1e_rphy(hw, PHY_CONTROL, &phy_ctrl);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	phy_ctrl |= MII_CR_RESET;
 	ret_val = e1e_wphy(hw, PHY_CONTROL, phy_ctrl);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	udelay(1);
 
-out:
 	return ret_val;
 }
 
@@ -1667,18 +1621,16 @@ out:
 s32 e1000_phy_hw_reset_generic(struct e1000_hw *hw)
 {
 	struct e1000_phy_info *phy = &hw->phy;
-	s32  ret_val;
+	s32 ret_val;
 	u32 ctrl;
 
 	ret_val = e1000_check_reset_block(hw);
-	if (ret_val) {
-		ret_val = E1000_SUCCESS;
-		goto out;
-	}
+	if (ret_val)
+		return 0;
 
 	ret_val = phy->ops.acquire_phy(hw);
 	if (ret_val)
-		goto out;
+		return ret_val;
 
 	ctrl = er32(CTRL);
 	ew32(CTRL, ctrl | E1000_CTRL_PHY_RST);
@@ -1693,10 +1645,7 @@ s32 e1000_phy_hw_reset_generic(struct e1000_hw *hw)
 
 	phy->ops.release_phy(hw);
 
-	ret_val = e1000_get_phy_cfg_done(hw);
-
-out:
-	return ret_val;
+	return e1000_get_phy_cfg_done(hw);
 }
 
 /**
@@ -1709,8 +1658,7 @@ out:
 s32 e1000_get_cfg_done(struct e1000_hw *hw)
 {
 	mdelay(10);
-
-	return E1000_SUCCESS;
+	return 0;
 }
 
 /* Internal function pointers */
@@ -1726,8 +1674,8 @@ static s32 e1000_get_phy_cfg_done(struct e1000_hw *hw)
 {
 	if (hw->phy.ops.get_cfg_done)
 		return hw->phy.ops.get_cfg_done(hw);
-	else
-		return E1000_SUCCESS;
+
+	return 0;
 }
 
 /**
@@ -1735,14 +1683,14 @@ static s32 e1000_get_phy_cfg_done(struct e1000_hw *hw)
  *  @hw: pointer to the HW structure
  *
  *  When the silicon family has not implemented a forced speed/duplex
- *  function for the PHY, simply return E1000_SUCCESS.
+ *  function for the PHY, simply return 0.
  **/
 static s32 e1000_phy_force_speed_duplex(struct e1000_hw *hw)
 {
 	if (hw->phy.ops.force_speed_duplex)
 		return hw->phy.ops.force_speed_duplex(hw);
-	else
-		return E1000_SUCCESS;
+
+	return 0;
 }
 
 /**
@@ -1794,8 +1742,8 @@ s32 e1000_commit_phy(struct e1000_hw *hw)
 {
 	if (hw->phy.ops.commit_phy)
 		return hw->phy.ops.commit_phy(hw);
-	else
-		return E1000_SUCCESS;
+
+	return 0;
 }
 
 /**
@@ -1816,6 +1764,6 @@ s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active)
 {
 	if (hw->phy.ops.set_d0_lplu_state)
 		return hw->phy.ops.set_d0_lplu_state(hw, active);
-	else
-		return E1000_SUCCESS;
+
+	return 0;
 }

linux-2.6-netdev-e1000e-03.patch:

--- NEW FILE linux-2.6-netdev-e1000e-03.patch ---
From: Auke Kok <auke-jan.h.kok at intel.com>
Date: Wed, 8 Aug 2007 17:22:11 +0000 (-0700)
Subject: e1000e: Make a few functions static
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fjgarzik%2Fnetdev-2.6.git;a=commitdiff_plain;h=604694f8c19065ee960887d97716d57107ca9a34

e1000e: Make a few functions static

After moving code around we can reduce namespace usage
by making a few functions static.

Signed-off-by: Auke Kok <auke-jan.h.kok at intel.com>
Signed-off-by: Jeff Garzik <jeff at garzik.org>
---

diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h
index 65c31d3..a1394d6 100644
--- a/drivers/net/e1000e/e1000.h
+++ b/drivers/net/e1000e/e1000.h
@@ -365,7 +365,6 @@ extern struct e1000_info e1000_ich9_info;
 extern struct e1000_info e1000_es2_info;
 
 extern s32  e1000_commit_phy(struct e1000_hw *hw);
-extern s32  e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active);
 
 extern bool e1000_enable_mng_pass_thru(struct e1000_hw *hw);
 
@@ -438,7 +437,6 @@ extern s32 e1000_phy_has_link_generic(struct e1000_hw *hw, u32 iterations,
 			       u32 usec_interval, bool *success);
 extern s32 e1000_phy_reset_dsp(struct e1000_hw *hw);
 extern s32 e1000_check_downshift(struct e1000_hw *hw);
-extern s32 e1000_wait_autoneg(struct e1000_hw *hw);
 
 static inline s32 e1000_phy_hw_reset(struct e1000_hw *hw)
 {
diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c
index d11b518..3bbe63e 100644
--- a/drivers/net/e1000e/lib.c
+++ b/drivers/net/e1000e/lib.c
@@ -2289,7 +2289,7 @@ bool e1000_enable_tx_pkt_filtering(struct e1000_hw *hw)
  *
  *  Writes the command header after does the checksum calculation.
  **/
-s32 e1000_mng_write_cmd_header(struct e1000_hw *hw,
+static s32 e1000_mng_write_cmd_header(struct e1000_hw *hw,
 				  struct e1000_host_mng_command_header *hdr)
 {
 	u16 i, length = sizeof(struct e1000_host_mng_command_header);
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index c8d50cc..dd4eca6 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -48,7 +48,7 @@
 char e1000_driver_name[] = "e1000e";
 const char e1000_driver_version[] = DRV_VERSION;
 
-const struct e1000_info * e1000_info_tbl[] = {
+static const struct e1000_info *e1000_info_tbl[] = {
 	[board_82571]		= &e1000_82571_info,
 	[board_82572]		= &e1000_82572_info,
 	[board_82573]		= &e1000_82573_info,
diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c
index d7947b0..1ccbad7 100644
--- a/drivers/net/e1000e/phy.c
+++ b/drivers/net/e1000e/phy.c
@@ -28,8 +28,10 @@
 
 #include "e1000.h"
 
-static s32  e1000_get_phy_cfg_done(struct e1000_hw *hw);
-static s32  e1000_phy_force_speed_duplex(struct e1000_hw *hw);
+static s32 e1000_get_phy_cfg_done(struct e1000_hw *hw);
+static s32 e1000_phy_force_speed_duplex(struct e1000_hw *hw);
+static s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active);
+static s32 e1000_wait_autoneg(struct e1000_hw *hw);
 
 /* Cable length tables */
 static const u16 e1000_m88_cable_length_table[] =
@@ -1281,7 +1283,7 @@ static s32 e1000_check_polarity_igp(struct e1000_hw *hw)
  *  Waits for auto-negotiation to complete or for the auto-negotiation time
  *  limit to expire, which ever happens first.
  **/
-s32 e1000_wait_autoneg(struct e1000_hw *hw)
+static s32 e1000_wait_autoneg(struct e1000_hw *hw)
 {
 	s32 ret_val = 0;
 	u16 i, phy_status;
@@ -1760,7 +1762,7 @@ s32 e1000_commit_phy(struct e1000_hw *hw)
  *  During driver activity, SmartSpeed should be enabled so performance is
  *  maintained.  This is a function pointer entry point called by drivers.
  **/
-s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active)
+static s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active)
 {
 	if (hw->phy.ops.set_d0_lplu_state)
 		return hw->phy.ops.set_d0_lplu_state(hw, active);

linux-2.6-netdev-e1000e-04.patch:

--- NEW FILE linux-2.6-netdev-e1000e-04.patch ---
From: Auke Kok <auke-jan.h.kok at intel.com>
Date: Wed, 8 Aug 2007 17:22:21 +0000 (-0700)
Subject: e1000e: remove duplicate shadowing reference to adapter->hw
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fjgarzik%2Fnetdev-2.6.git;a=commitdiff_plain;h=5b8fe1c4280c9424a5fc03d8e8e13c1b4cde22f0

e1000e: remove duplicate shadowing reference to adapter->hw

Signed-off-by: Auke Kok <auke-jan.h.kok at intel.com>
Signed-off-by: Jeff Garzik <jeff at garzik.org>
---

diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index dd4eca6..741965d 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -2981,7 +2981,6 @@ static void e1000_watchdog_task(struct work_struct *work)
 		} else {
 			/* make sure the receive unit is started */
 			if (adapter->flags & FLAG_RX_NEEDS_RESTART) {
-				struct e1000_hw *hw = &adapter->hw;
 				u32 rctl = er32(RCTL);
 				ew32(RCTL, rctl |
 						E1000_RCTL_EN);

linux-2.6-netdev-e1000e-05.patch:

--- NEW FILE linux-2.6-netdev-e1000e-05.patch ---
From: Auke Kok <auke-jan.h.kok at intel.com>
Date: Fri, 10 Aug 2007 20:00:38 +0000 (-0700)
Subject: e1000e: Fix header includes [v2]
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fjgarzik%2Fnetdev-2.6.git;a=commitdiff_plain;h=867dbd1bea13a265f10a0685488e486836fb3910

e1000e: Fix header includes [v2]

Signed-off-by: Auke Kok <auke-jan.h.kok at intel.com>
Signed-off-by: Jeff Garzik <jeff at garzik.org>
---

diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c
index ddf2303..0f8f0ac 100644
--- a/drivers/net/e1000e/82571.c
+++ b/drivers/net/e1000e/82571.c
@@ -37,6 +37,10 @@
  * 82573L Gigabit Ethernet Controller
  */
 
+#include <linux/netdevice.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+
 #include "e1000.h"
 
 #define ID_LED_RESERVED_F746 0xF746
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h
index a1394d6..de17537 100644
--- a/drivers/net/e1000e/e1000.h
+++ b/drivers/net/e1000e/e1000.h
@@ -31,10 +31,11 @@
 #ifndef _E1000_H_
 #define _E1000_H_
 
+#include <linux/types.h>
+#include <linux/timer.h>
+#include <linux/workqueue.h>
+#include <linux/io.h>
 #include <linux/netdevice.h>
-#include <linux/ethtool.h>
-#include <linux/pci.h>
-#include <asm/io.h>
 
 #include "hw.h"
 
diff --git a/drivers/net/e1000e/es2lan.c b/drivers/net/e1000e/es2lan.c
index 5604c50..8100d03 100644
--- a/drivers/net/e1000e/es2lan.c
+++ b/drivers/net/e1000e/es2lan.c
@@ -31,6 +31,11 @@
  * 80003ES2LAN Gigabit Ethernet Controller (Serdes)
  */
 
+#include <linux/netdevice.h>
+#include <linux/ethtool.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+
 #include "e1000.h"
 
 #define E1000_KMRNCTRLSTA_OFFSET_FIFO_CTRL	 0x00
diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c
index 6c417ea..a8fa1db 100644
--- a/drivers/net/e1000e/ethtool.c
+++ b/drivers/net/e1000e/ethtool.c
@@ -29,8 +29,9 @@
 /* ethtool support for e1000 */
 
 #include <linux/netdevice.h>
-
 #include <linux/ethtool.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
 
 #include "e1000.h"
 
diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h
index 4d562c4..848217a 100644
--- a/drivers/net/e1000e/hw.h
+++ b/drivers/net/e1000e/hw.h
@@ -29,6 +29,8 @@
 #ifndef _E1000_HW_H_
 #define _E1000_HW_H_
 
+#include <linux/types.h>
+
 struct e1000_hw;
 struct e1000_adapter;
 
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c
index 042abd4..85095af 100644
--- a/drivers/net/e1000e/ich8lan.c
+++ b/drivers/net/e1000e/ich8lan.c
@@ -40,6 +40,11 @@
  * 82566MM Gigabit Network Connection
  */
 
+#include <linux/netdevice.h>
+#include <linux/ethtool.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+
 #include "e1000.h"
 
 #define ICH_FLASH_GFPREG		0x0000
diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c
index 3bbe63e..c92ea77 100644
--- a/drivers/net/e1000e/lib.c
+++ b/drivers/net/e1000e/lib.c
@@ -27,6 +27,8 @@
 *******************************************************************************/
 
 #include <linux/netdevice.h>
+#include <linux/ethtool.h>
+#include <linux/delay.h>
 #include <linux/pci.h>
 
 #include "e1000.h"
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 741965d..01a9a4f 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -29,8 +29,10 @@
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/init.h>
+#include <linux/pci.h>
 #include <linux/vmalloc.h>
 #include <linux/pagemap.h>
+#include <linux/delay.h>
 #include <linux/netdevice.h>
 #include <linux/tcp.h>
 #include <linux/ipv6.h>
diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c
index 1ccbad7..c9304d8 100644
--- a/drivers/net/e1000e/phy.c
+++ b/drivers/net/e1000e/phy.c
@@ -26,6 +26,8 @@
 
 *******************************************************************************/
 
+#include <linux/delay.h>
+
 #include "e1000.h"
 
 static s32 e1000_get_phy_cfg_done(struct e1000_hw *hw);

linux-2.6-netdev-e1000e-06.patch:

--- NEW FILE linux-2.6-netdev-e1000e-06.patch ---
From: Auke Kok <auke-jan.h.kok at intel.com>
Date: Fri, 10 Aug 2007 20:00:47 +0000 (-0700)
Subject: e1000e: remove namespace collisions with e1000
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fjgarzik%2Fnetdev-2.6.git;a=commitdiff_plain;h=9c1a53eb0d1c4d8039a74e6408b39c9c0690d3af

e1000e: remove namespace collisions with e1000

To prevent future collisions we rename all extern's from e1000_
to e1000e_*. The list of changed symbols was taken from e1000.h
Compile tested with CONFIG_E1000=y and CONFIG_E1000E=y.

Signed-off-by: Auke Kok <auke-jan.h.kok at intel.com>
Signed-off-by: Jeff Garzik <jeff at garzik.org>
---

diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c
index 0f8f0ac..cf70522 100644
--- a/drivers/net/e1000e/82571.c
+++ b/drivers/net/e1000e/82571.c
@@ -54,7 +54,6 @@
 static s32 e1000_get_phy_id_82571(struct e1000_hw *hw);
 static s32 e1000_setup_copper_link_82571(struct e1000_hw *hw);
 static s32 e1000_setup_fiber_serdes_link_82571(struct e1000_hw *hw);
-static s32 e1000_get_phy_id_82571(struct e1000_hw *hw);
 static s32 e1000_write_nvm_eewr_82571(struct e1000_hw *hw, u16 offset,
 				      u16 words, u16 *data);
 static s32 e1000_fix_nvm_checksum_82571(struct e1000_hw *hw);
@@ -214,18 +213,18 @@ static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter)
 	switch (hw->media_type) {
 	case e1000_media_type_copper:
 		func->setup_physical_interface = e1000_setup_copper_link_82571;
-		func->check_for_link = e1000_check_for_copper_link;
-		func->get_link_up_info = e1000_get_speed_and_duplex_copper;
+		func->check_for_link = e1000e_check_for_copper_link;
+		func->get_link_up_info = e1000e_get_speed_and_duplex_copper;
 		break;
 	case e1000_media_type_fiber:
 		func->setup_physical_interface = e1000_setup_fiber_serdes_link_82571;
-		func->check_for_link = e1000_check_for_fiber_link;
-		func->get_link_up_info = e1000_get_speed_and_duplex_fiber_serdes;
+		func->check_for_link = e1000e_check_for_fiber_link;
+		func->get_link_up_info = e1000e_get_speed_and_duplex_fiber_serdes;
 		break;
 	case e1000_media_type_internal_serdes:
 		func->setup_physical_interface = e1000_setup_fiber_serdes_link_82571;
-		func->check_for_link = e1000_check_for_serdes_link;
-		func->get_link_up_info = e1000_get_speed_and_duplex_fiber_serdes;
+		func->check_for_link = e1000e_check_for_serdes_link;
+		func->get_link_up_info = e1000e_get_speed_and_duplex_fiber_serdes;
 		break;
 	default:
 		return -E1000_ERR_CONFIG;
@@ -324,7 +323,7 @@ static s32 e1000_get_phy_id_82571(struct e1000_hw *hw)
 		phy->id = IGP01E1000_I_PHY_ID;
 		break;
 	case e1000_82573:
-		return e1000_get_phy_id(hw);
+		return e1000e_get_phy_id(hw);
 		break;
 	default:
 		return -E1000_ERR_PHY;
@@ -360,7 +359,7 @@ static s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw)
 
 	if (i == timeout) {
 		/* Release semaphores */
-		e1000_put_hw_semaphore(hw);
+		e1000e_put_hw_semaphore(hw);
 		hw_dbg(hw, "Driver can't access the NVM\n");
 		return -E1000_ERR_NVM;
 	}
@@ -403,7 +402,7 @@ static s32 e1000_acquire_nvm_82571(struct e1000_hw *hw)
 		return ret_val;
 
 	if (hw->mac.type != e1000_82573)
-		ret_val = e1000_acquire_nvm(hw);
+		ret_val = e1000e_acquire_nvm(hw);
 
 	if (ret_val)
 		e1000_put_hw_semaphore_82571(hw);
@@ -419,7 +418,7 @@ static s32 e1000_acquire_nvm_82571(struct e1000_hw *hw)
  **/
 static void e1000_release_nvm_82571(struct e1000_hw *hw)
 {
-	e1000_release_nvm(hw);
+	e1000e_release_nvm(hw);
 	e1000_put_hw_semaphore_82571(hw);
 }
 
@@ -432,7 +431,7 @@ static void e1000_release_nvm_82571(struct e1000_hw *hw)
  *
  *  For non-82573 silicon, write data to EEPROM at offset using SPI interface.
  *
- *  If e1000_update_nvm_checksum is not called after this function, the
+ *  If e1000e_update_nvm_checksum is not called after this function, the
  *  EEPROM will most likley contain an invalid checksum.
  **/
 static s32 e1000_write_nvm_82571(struct e1000_hw *hw, u16 offset, u16 words,
@@ -446,7 +445,7 @@ static s32 e1000_write_nvm_82571(struct e1000_hw *hw, u16 offset, u16 words,
 		break;
 	case e1000_82571:
 	case e1000_82572:
-		ret_val = e1000_write_nvm_spi(hw, offset, words, data);
+		ret_val = e1000e_write_nvm_spi(hw, offset, words, data);
 		break;
 	default:
 		ret_val = -E1000_ERR_NVM;
@@ -470,7 +469,7 @@ static s32 e1000_update_nvm_checksum_82571(struct e1000_hw *hw)
 	s32 ret_val;
 	u16 i;
 
-	ret_val = e1000_update_nvm_checksum_generic(hw);
+	ret_val = e1000e_update_nvm_checksum_generic(hw);
 	if (ret_val)
 		return ret_val;
 
@@ -527,7 +526,7 @@ static s32 e1000_validate_nvm_checksum_82571(struct e1000_hw *hw)
 	if (hw->nvm.type == e1000_nvm_flash_hw)
 		e1000_fix_nvm_checksum_82571(hw);
 
-	return e1000_validate_nvm_checksum_generic(hw);
+	return e1000e_validate_nvm_checksum_generic(hw);
 }
 
 /**
@@ -541,7 +540,7 @@ static s32 e1000_validate_nvm_checksum_82571(struct e1000_hw *hw)
  *  command has completed before trying to write the next word.  After write
  *  poll for completion.
  *
- *  If e1000_update_nvm_checksum is not called after this function, the
+ *  If e1000e_update_nvm_checksum is not called after this function, the
  *  EEPROM will most likley contain an invalid checksum.
  **/
 static s32 e1000_write_nvm_eewr_82571(struct e1000_hw *hw, u16 offset,
@@ -565,13 +564,13 @@ static s32 e1000_write_nvm_eewr_82571(struct e1000_hw *hw, u16 offset,
 		       ((offset+i) << E1000_NVM_RW_ADDR_SHIFT) |
 		       E1000_NVM_RW_REG_START;
 
-		ret_val = e1000_poll_eerd_eewr_done(hw, E1000_NVM_POLL_WRITE);
+		ret_val = e1000e_poll_eerd_eewr_done(hw, E1000_NVM_POLL_WRITE);
 		if (ret_val)
 			break;
 
 		ew32(EEWR, eewr);
 
-		ret_val = e1000_poll_eerd_eewr_done(hw, E1000_NVM_POLL_WRITE);
+		ret_val = e1000e_poll_eerd_eewr_done(hw, E1000_NVM_POLL_WRITE);
 		if (ret_val)
 			break;
 	}
@@ -691,7 +690,7 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw)
 	/* Prevent the PCI-E bus from sticking if there is no TLP connection
 	 * on the last TLP read/write transaction when MAC is reset.
 	 */
-	ret_val = e1000_disable_pcie_master(hw);
+	ret_val = e1000e_disable_pcie_master(hw);
 	if (ret_val)
 		hw_dbg(hw, "PCI-E Master disable polling has failed.\n");
 
@@ -737,7 +736,7 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw)
 		e1e_flush();
 	}
 
-	ret_val = e1000_get_auto_rd_done(hw);
+	ret_val = e1000e_get_auto_rd_done(hw);
 	if (ret_val)
 		/* We don't want to continue accessing MAC registers. */
 		return ret_val;
@@ -773,7 +772,7 @@ static s32 e1000_init_hw_82571(struct e1000_hw *hw)
 	e1000_initialize_hw_bits_82571(hw);
 
 	/* Initialize identification LED */
-	ret_val = e1000_id_led_init(hw);
+	ret_val = e1000e_id_led_init(hw);
 	if (ret_val) {
 		hw_dbg(hw, "Error initializing identification LED\n");
 		return ret_val;
@@ -781,16 +780,16 @@ static s32 e1000_init_hw_82571(struct e1000_hw *hw)
 
 	/* Disabling VLAN filtering */
 	hw_dbg(hw, "Initializing the IEEE VLAN\n");
-	e1000_clear_vfta(hw);
+	e1000e_clear_vfta(hw);
 
 	/* Setup the receive address. */
 	/* If, however, a locally administered address was assigned to the
 	 * 82571, we must reserve a RAR for it to work around an issue where
 	 * resetting one port will reload the MAC on the other port.
 	 */
-	if (e1000_get_laa_state_82571(hw))
+	if (e1000e_get_laa_state_82571(hw))
 		rar_count--;
-	e1000_init_rx_addrs(hw, rar_count);
+	e1000e_init_rx_addrs(hw, rar_count);
 
 	/* Zero out the Multicast HASH table */
 	hw_dbg(hw, "Zeroing the MTA\n");
@@ -815,7 +814,7 @@ static s32 e1000_init_hw_82571(struct e1000_hw *hw)
 			   E1000_TXDCTL_COUNT_DESC;
 		ew32(TXDCTL1, reg_data);
[...3378 lines suppressed...]
+ *  e1000e_check_downshift - Checks whether a downshift in speed occured
  *  @hw: pointer to the HW structure
  *
  *  Success returns 0, Failure returns 1
  *
  *  A downshift is detected by querying the PHY link health.
  **/
-s32 e1000_check_downshift(struct e1000_hw *hw)
+s32 e1000e_check_downshift(struct e1000_hw *hw)
 {
 	struct e1000_phy_info *phy = &hw->phy;
 	s32 ret_val;
@@ -1310,7 +1310,7 @@ static s32 e1000_wait_autoneg(struct e1000_hw *hw)
 }
 
 /**
- *  e1000_phy_has_link_generic - Polls PHY for link
+ *  e1000e_phy_has_link_generic - Polls PHY for link
  *  @hw: pointer to the HW structure
  *  @iterations: number of times to poll for link
  *  @usec_interval: delay between polling attempts
@@ -1318,7 +1318,7 @@ static s32 e1000_wait_autoneg(struct e1000_hw *hw)
  *
  *  Polls the PHY status register for link, 'iterations' number of times.
  **/
-s32 e1000_phy_has_link_generic(struct e1000_hw *hw, u32 iterations,
+s32 e1000e_phy_has_link_generic(struct e1000_hw *hw, u32 iterations,
 			       u32 usec_interval, bool *success)
 {
 	s32 ret_val;
@@ -1349,7 +1349,7 @@ s32 e1000_phy_has_link_generic(struct e1000_hw *hw, u32 iterations,
 }
 
 /**
- *  e1000_get_cable_length_m88 - Determine cable length for m88 PHY
+ *  e1000e_get_cable_length_m88 - Determine cable length for m88 PHY
  *  @hw: pointer to the HW structure
  *
  *  Reads the PHY specific status register to retrieve the cable length
@@ -1363,7 +1363,7 @@ s32 e1000_phy_has_link_generic(struct e1000_hw *hw, u32 iterations,
  *	3			110 - 140 meters
  *	4			> 140 meters
  **/
-s32 e1000_get_cable_length_m88(struct e1000_hw *hw)
+s32 e1000e_get_cable_length_m88(struct e1000_hw *hw)
 {
 	struct e1000_phy_info *phy = &hw->phy;
 	s32 ret_val;
@@ -1384,7 +1384,7 @@ s32 e1000_get_cable_length_m88(struct e1000_hw *hw)
 }
 
 /**
- *  e1000_get_cable_length_igp_2 - Determine cable length for igp2 PHY
+ *  e1000e_get_cable_length_igp_2 - Determine cable length for igp2 PHY
  *  @hw: pointer to the HW structure
  *
  *  The automatic gain control (agc) normalizes the amplitude of the
@@ -1394,7 +1394,7 @@ s32 e1000_get_cable_length_m88(struct e1000_hw *hw)
  *  into a lookup table to obtain the approximate cable length
  *  for each channel.
  **/
-s32 e1000_get_cable_length_igp_2(struct e1000_hw *hw)
+s32 e1000e_get_cable_length_igp_2(struct e1000_hw *hw)
 {
 	struct e1000_phy_info *phy = &hw->phy;
 	s32 ret_val;
@@ -1451,7 +1451,7 @@ s32 e1000_get_cable_length_igp_2(struct e1000_hw *hw)
 }
 
 /**
- *  e1000_get_phy_info_m88 - Retrieve PHY information
+ *  e1000e_get_phy_info_m88 - Retrieve PHY information
  *  @hw: pointer to the HW structure
  *
  *  Valid for only copper links.  Read the PHY status register (sticky read)
@@ -1460,7 +1460,7 @@ s32 e1000_get_cable_length_igp_2(struct e1000_hw *hw)
  *  special status register to determine MDI/MDIx and current speed.  If
  *  speed is 1000, then determine cable length, local and remote receiver.
  **/
-s32 e1000_get_phy_info_m88(struct e1000_hw *hw)
+s32 e1000e_get_phy_info_m88(struct e1000_hw *hw)
 {
 	struct e1000_phy_info *phy = &hw->phy;
 	s32  ret_val;
@@ -1472,7 +1472,7 @@ s32 e1000_get_phy_info_m88(struct e1000_hw *hw)
 		return -E1000_ERR_CONFIG;
 	}
 
-	ret_val = e1000_phy_has_link_generic(hw, 1, 0, &link);
+	ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link);
 	if (ret_val)
 		return ret_val;
 
@@ -1525,7 +1525,7 @@ s32 e1000_get_phy_info_m88(struct e1000_hw *hw)
 }
 
 /**
- *  e1000_get_phy_info_igp - Retrieve igp PHY information
+ *  e1000e_get_phy_info_igp - Retrieve igp PHY information
  *  @hw: pointer to the HW structure
  *
  *  Read PHY status to determine if link is up.  If link is up, then
@@ -1533,14 +1533,14 @@ s32 e1000_get_phy_info_m88(struct e1000_hw *hw)
  *  PHY port status to determine MDI/MDIx and speed.  Based on the speed,
  *  determine on the cable length, local and remote receiver.
  **/
-s32 e1000_get_phy_info_igp(struct e1000_hw *hw)
+s32 e1000e_get_phy_info_igp(struct e1000_hw *hw)
 {
 	struct e1000_phy_info *phy = &hw->phy;
 	s32 ret_val;
 	u16 data;
 	bool link;
 
-	ret_val = e1000_phy_has_link_generic(hw, 1, 0, &link);
+	ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link);
 	if (ret_val)
 		return ret_val;
 
@@ -1588,13 +1588,13 @@ s32 e1000_get_phy_info_igp(struct e1000_hw *hw)
 }
 
 /**
- *  e1000_phy_sw_reset - PHY software reset
+ *  e1000e_phy_sw_reset - PHY software reset
  *  @hw: pointer to the HW structure
  *
  *  Does a software reset of the PHY by reading the PHY control register and
  *  setting/write the control register reset bit to the PHY.
  **/
-s32 e1000_phy_sw_reset(struct e1000_hw *hw)
+s32 e1000e_phy_sw_reset(struct e1000_hw *hw)
 {
 	s32 ret_val;
 	u16 phy_ctrl;
@@ -1614,7 +1614,7 @@ s32 e1000_phy_sw_reset(struct e1000_hw *hw)
 }
 
 /**
- *  e1000_phy_hw_reset_generic - PHY hardware reset
+ *  e1000e_phy_hw_reset_generic - PHY hardware reset
  *  @hw: pointer to the HW structure
  *
  *  Verify the reset block is not blocking us from resetting.  Acquire
@@ -1622,7 +1622,7 @@ s32 e1000_phy_sw_reset(struct e1000_hw *hw)
  *  bit in the PHY.  Wait the appropriate delay time for the device to
  *  reset and relase the semaphore (if necessary).
  **/
-s32 e1000_phy_hw_reset_generic(struct e1000_hw *hw)
+s32 e1000e_phy_hw_reset_generic(struct e1000_hw *hw)
 {
 	struct e1000_phy_info *phy = &hw->phy;
 	s32 ret_val;
@@ -1653,13 +1653,13 @@ s32 e1000_phy_hw_reset_generic(struct e1000_hw *hw)
 }
 
 /**
- *  e1000_get_cfg_done - Generic configuration done
+ *  e1000e_get_cfg_done - Generic configuration done
  *  @hw: pointer to the HW structure
  *
  *  Generic function to wait 10 milli-seconds for configuration to complete
  *  and return success.
  **/
-s32 e1000_get_cfg_done(struct e1000_hw *hw)
+s32 e1000e_get_cfg_done(struct e1000_hw *hw)
 {
 	mdelay(10);
 	return 0;
@@ -1698,12 +1698,12 @@ static s32 e1000_phy_force_speed_duplex(struct e1000_hw *hw)
 }
 
 /**
- *  e1000_get_phy_type_from_id - Get PHY type from id
+ *  e1000e_get_phy_type_from_id - Get PHY type from id
  *  @phy_id: phy_id read from the phy
  *
  *  Returns the phy type from the id.
  **/
-enum e1000_phy_type e1000_get_phy_type_from_id(u32 phy_id)
+enum e1000_phy_type e1000e_get_phy_type_from_id(u32 phy_id)
 {
 	enum e1000_phy_type phy_type = e1000_phy_unknown;
 
@@ -1736,13 +1736,13 @@ enum e1000_phy_type e1000_get_phy_type_from_id(u32 phy_id)
 }
 
 /**
- *  e1000_commit_phy - Soft PHY reset
+ *  e1000e_commit_phy - Soft PHY reset
  *  @hw: pointer to the HW structure
  *
  *  Performs a soft PHY reset on those that apply. This is a function pointer
  *  entry point called by drivers.
  **/
-s32 e1000_commit_phy(struct e1000_hw *hw)
+s32 e1000e_commit_phy(struct e1000_hw *hw)
 {
 	if (hw->phy.ops.commit_phy)
 		return hw->phy.ops.commit_phy(hw);

linux-2.6-netdev-e1000e-07.patch:

--- NEW FILE linux-2.6-netdev-e1000e-07.patch ---
From: Auke Kok <auke-jan.h.kok at intel.com>
Date: Fri, 10 Aug 2007 20:00:52 +0000 (-0700)
Subject: e1000e: Use dma_alloc_coherent where possible
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fjgarzik%2Fnetdev-2.6.git;a=commitdiff_plain;h=5c0904d729b2161ab7559c5683832cb075c8e81d

e1000e: Use dma_alloc_coherent where possible

Instead of using pci_alloc_consistent at GFP_ATOMIC we can be
more reliable at startup and use dma_alloc_coherent instead with
GFP_KERNEL.

Signed-off-by: Auke Kok <auke-jan.h.kok at intel.com>
Signed-off-by: Jeff Garzik <jeff at garzik.org>
---

diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c
index c9d74a8..d184116 100644
--- a/drivers/net/e1000e/ethtool.c
+++ b/drivers/net/e1000e/ethtool.c
@@ -962,13 +962,13 @@ static void e1000_free_desc_rings(struct e1000_adapter *adapter)
 	}
 
 	if (tx_ring->desc) {
-		pci_free_consistent(pdev, tx_ring->size, tx_ring->desc,
-				    tx_ring->dma);
+		dma_free_coherent(&pdev->dev, tx_ring->size, tx_ring->desc,
+				  tx_ring->dma);
 		tx_ring->desc = NULL;
 	}
 	if (rx_ring->desc) {
-		pci_free_consistent(pdev, rx_ring->size, rx_ring->desc,
-				    rx_ring->dma);
+		dma_free_coherent(&pdev->dev, rx_ring->size, rx_ring->desc,
+				  rx_ring->dma);
 		rx_ring->desc = NULL;
 	}
 
@@ -1004,8 +1004,8 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter)
 
 	tx_ring->size = tx_ring->count * sizeof(struct e1000_tx_desc);
 	tx_ring->size = ALIGN(tx_ring->size, 4096);
-	tx_ring->desc = pci_alloc_consistent(pdev, tx_ring->size,
-			&tx_ring->dma);
+	tx_ring->desc = dma_alloc_coherent(&pdev->dev, tx_ring->size,
+					   &tx_ring->dma, GFP_KERNEL);
 	if (!tx_ring->desc) {
 		ret_val = 2;
 		goto err_nomem;
@@ -1065,8 +1065,8 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter)
 	memset(rx_ring->buffer_info, 0, size);
 
 	rx_ring->size = rx_ring->count * sizeof(struct e1000_rx_desc);
-	rx_ring->desc = pci_alloc_consistent(pdev, rx_ring->size,
-					     &rx_ring->dma);
+	rx_ring->desc = dma_alloc_coherent(&pdev->dev, rx_ring->size,
+					   &rx_ring->dma, GFP_KERNEL);
 	if (!rx_ring->desc) {
 		ret_val = 5;
 		goto err_nomem;
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index d711e14..51c9024 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -1344,7 +1344,8 @@ static int e1000_alloc_ring_dma(struct e1000_adapter *adapter,
 {
 	struct pci_dev *pdev = adapter->pdev;
 
-	ring->desc = pci_alloc_consistent(pdev, ring->size, &ring->dma);
+	ring->desc = dma_alloc_coherent(&pdev->dev, ring->size, &ring->dma,
+					GFP_KERNEL);
 	if (!ring->desc)
 		return -ENOMEM;
 
@@ -1479,7 +1480,8 @@ void e1000e_free_tx_resources(struct e1000_adapter *adapter)
 	vfree(tx_ring->buffer_info);
 	tx_ring->buffer_info = NULL;
 
-	pci_free_consistent(pdev, tx_ring->size, tx_ring->desc, tx_ring->dma);
+	dma_free_coherent(&pdev->dev, tx_ring->size, tx_ring->desc,
+			  tx_ring->dma);
 	tx_ring->desc = NULL;
 }
 
@@ -1503,7 +1505,8 @@ void e1000e_free_rx_resources(struct e1000_adapter *adapter)
 	kfree(rx_ring->ps_pages);
 	rx_ring->ps_pages = NULL;
 
-	pci_free_consistent(pdev, rx_ring->size, rx_ring->desc, rx_ring->dma);
+	dma_free_coherent(&pdev->dev, rx_ring->size, rx_ring->desc,
+			  rx_ring->dma);
 	rx_ring->desc = NULL;
 }
 

linux-2.6-netdev-e1000e-08.patch:

--- NEW FILE linux-2.6-netdev-e1000e-08.patch ---
From: Auke Kok <auke-jan.h.kok at intel.com>
Date: Fri, 10 Aug 2007 20:00:57 +0000 (-0700)
Subject: e1000e: Use time_after to account for jiffies wrapping
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fjgarzik%2Fnetdev-2.6.git;a=commitdiff_plain;h=363baa32cd1993c241cf16c862ec958fcaebe77e

e1000e: Use time_after to account for jiffies wrapping

Signed-off-by: Auke Kok <auke-jan.h.kok at intel.com>
Signed-off-by: Jeff Garzik <jeff at garzik.org>
---

diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c
index d184116..d14cc4b 100644
--- a/drivers/net/e1000e/ethtool.c
+++ b/drivers/net/e1000e/ethtool.c
@@ -1411,7 +1411,7 @@ static int e1000_run_loopback_test(struct e1000_adapter *adapter)
 			 * enough time to complete the receives, if it's
 			 * exceeded, break and error off
 			 */
-		} while (good_cnt < 64 && jiffies < (time + 20));
+		} while ((good_cnt < 64) && !time_after(jiffies, time + 20));
 		if (good_cnt != 64) {
 			ret_val = 13; /* ret_val is the same as mis-compare */
 			break;

linux-2.6-netdev-e1000e-09.patch:

--- NEW FILE linux-2.6-netdev-e1000e-09.patch ---
From: Auke Kok <auke-jan.h.kok at intel.com>
Date: Fri, 10 Aug 2007 20:01:02 +0000 (-0700)
Subject: e1000e: error handling for pci_map_single calls.
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fjgarzik%2Fnetdev-2.6.git;a=commitdiff_plain;h=8136b0db9be68942380cac6925cf6dd6a2be9a8f

e1000e: error handling for pci_map_single calls.

Add proper error handling for various callers of pci_map_single.

Signed-off-by: Auke Kok <auke-jan.h.kok at intel.com>
Signed-off-by: Jeff Garzik <jeff at garzik.org>
---

diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h
index 3475e48..e3cd877 100644
--- a/drivers/net/e1000e/e1000.h
+++ b/drivers/net/e1000e/e1000.h
@@ -220,6 +220,7 @@ struct e1000_adapter {
 	u32 tx_fifo_head;
 	u32 tx_head_addr;
 	u32 tx_fifo_size;
+	u32 tx_dma_failed;
 
 	/*
 	 * RX
@@ -241,6 +242,7 @@ struct e1000_adapter {
 	u64 gorcl_old;
 	u32 gorcl;
 	u32 alloc_rx_buff_failed;
+	u32 rx_dma_failed;
 
 	unsigned int rx_ps_pages;
 	u16 rx_ps_bsize0;
diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c
index d14cc4b..0e80406 100644
--- a/drivers/net/e1000e/ethtool.c
+++ b/drivers/net/e1000e/ethtool.c
@@ -91,6 +91,8 @@ static const struct e1000_stats e1000_gstrings_stats[] = {
 	{ "tx_smbus", E1000_STAT(stats.mgptc) },
 	{ "rx_smbus", E1000_STAT(stats.mgprc) },
 	{ "dropped_smbus", E1000_STAT(stats.mgpdc) },
+	{ "rx_dma_failed", E1000_STAT(rx_dma_failed) },
+	{ "tx_dma_failed", E1000_STAT(tx_dma_failed) },
 };
 
 #define E1000_GLOBAL_STATS_LEN	\
@@ -1042,6 +1044,10 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter)
 		tx_ring->buffer_info[i].dma =
 			pci_map_single(pdev, skb->data, skb->len,
 				       PCI_DMA_TODEVICE);
+		if (pci_dma_mapping_error(tx_ring->buffer_info[i].dma)) {
+			ret_val = 4;
+			goto err_nomem;
+		}
 		tx_desc->buffer_addr = cpu_to_le64(
 					 tx_ring->buffer_info[i].dma);
 		tx_desc->lower.data = cpu_to_le32(skb->len);
@@ -1059,7 +1065,7 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter)
 	size = rx_ring->count * sizeof(struct e1000_buffer);
 	rx_ring->buffer_info = kmalloc(size, GFP_KERNEL);
 	if (!rx_ring->buffer_info) {
-		ret_val = 4;
+		ret_val = 5;
 		goto err_nomem;
 	}
 	memset(rx_ring->buffer_info, 0, size);
@@ -1068,7 +1074,7 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter)
 	rx_ring->desc = dma_alloc_coherent(&pdev->dev, rx_ring->size,
 					   &rx_ring->dma, GFP_KERNEL);
 	if (!rx_ring->desc) {
-		ret_val = 5;
+		ret_val = 6;
 		goto err_nomem;
 	}
 	memset(rx_ring->desc, 0, rx_ring->size);
@@ -1093,7 +1099,7 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter)
 
 		skb = alloc_skb(2048 + NET_IP_ALIGN, GFP_KERNEL);
 		if (!skb) {
-			ret_val = 6;
+			ret_val = 7;
 			goto err_nomem;
 		}
 		skb_reserve(skb, NET_IP_ALIGN);
@@ -1101,6 +1107,10 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter)
 		rx_ring->buffer_info[i].dma =
 			pci_map_single(pdev, skb->data, 2048,
 				       PCI_DMA_FROMDEVICE);
+		if (pci_dma_mapping_error(rx_ring->buffer_info[i].dma)) {
+			ret_val = 8;
+			goto err_nomem;
+		}
 		rx_desc->buffer_addr =
 			cpu_to_le64(rx_ring->buffer_info[i].dma);
 		memset(skb->data, 0x00, skb->len);
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 51c9024..8ebe238 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -195,6 +195,11 @@ map_skb:
 		buffer_info->dma = pci_map_single(pdev, skb->data,
 						  adapter->rx_buffer_len,
 						  PCI_DMA_FROMDEVICE);
+		if (pci_dma_mapping_error(buffer_info->dma)) {
+			dev_err(&pdev->dev, "RX DMA map failed\n");
+			adapter->rx_dma_failed++;
+			break;
+		}
 
 		rx_desc = E1000_RX_DESC(*rx_ring, i);
 		rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
@@ -255,6 +260,13 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,
 							   ps_page->page,
 							   0, PAGE_SIZE,
 							   PCI_DMA_FROMDEVICE);
+					if (pci_dma_mapping_error(
+							ps_page->dma)) {
+						dev_err(&adapter->pdev->dev,
+						  "RX DMA page map failed\n");
+						adapter->rx_dma_failed++;
+						goto no_buffers;
+					}
 				}
 				/*
 				 * Refresh the desc even if buffer_addrs
@@ -286,6 +298,14 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,
 		buffer_info->dma = pci_map_single(pdev, skb->data,
 						  adapter->rx_ps_bsize0,
 						  PCI_DMA_FROMDEVICE);
+		if (pci_dma_mapping_error(buffer_info->dma)) {
+			dev_err(&pdev->dev, "RX DMA map failed\n");
+			adapter->rx_dma_failed++;
+			/* cleanup skb */
+			dev_kfree_skb_any(skb);
+			buffer_info->skb = NULL;
+			break;
+		}
 
 		rx_desc->read.buffer_addr[0] = cpu_to_le64(buffer_info->dma);
 
@@ -374,6 +394,11 @@ check_page:
 							buffer_info->page, 0,
 							PAGE_SIZE,
 							PCI_DMA_FROMDEVICE);
+		if (pci_dma_mapping_error(buffer_info->dma)) {
+			dev_err(&adapter->pdev->dev, "RX DMA page map failed\n");
+			adapter->rx_dma_failed++;
+			break;
+		}
 
 		rx_desc = E1000_RX_DESC(*rx_ring, i);
 		rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
@@ -3214,6 +3239,11 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
 				skb->data + offset,
 				size,
 				PCI_DMA_TODEVICE);
+		if (pci_dma_mapping_error(buffer_info->dma)) {
+			dev_err(&adapter->pdev->dev, "TX DMA map failed\n");
+			adapter->tx_dma_failed++;
+			return -1;
+		}
 		buffer_info->next_to_watch = i;
 
 		len -= size;
@@ -3247,6 +3277,13 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
 					offset,
 					size,
 					PCI_DMA_TODEVICE);
+			if (pci_dma_mapping_error(buffer_info->dma)) {
+				dev_err(&adapter->pdev->dev,
+					"TX DMA page map failed\n");
+				adapter->tx_dma_failed++;
+				return -1;
+			}
+
 			buffer_info->next_to_watch = i;
 
 			len -= size;
@@ -3512,9 +3549,15 @@ static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 	if (skb->protocol == htons(ETH_P_IP))
 		tx_flags |= E1000_TX_FLAGS_IPV4;
 
-	e1000_tx_queue(adapter, tx_flags,
-		       e1000_tx_map(adapter, skb, first,
-				    max_per_txd, nr_frags, mss));
+	count = e1000_tx_map(adapter, skb, first, max_per_txd, nr_frags, mss);
+	if (count < 0) {
+		/* handle pci_map_single() error in e1000_tx_map */
+		dev_kfree_skb_any(skb);
+		spin_unlock_irqrestore(&adapter->tx_queue_lock, irq_flags);
+		return NETDEV_TX_BUSY;
+	}
+
+	e1000_tx_queue(adapter, tx_flags, count);
 
 	netdev->trans_start = jiffies;
 

linux-2.6-netdev-e1000e-10.patch:

--- NEW FILE linux-2.6-netdev-e1000e-10.patch ---
From: Auke Kok <auke-jan.h.kok at intel.com>
Date: Fri, 10 Aug 2007 20:01:07 +0000 (-0700)
Subject: e1000e: Remove two compile warnings
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fjgarzik%2Fnetdev-2.6.git;a=commitdiff_plain;h=3e4346712d03162af6b570aa17efb1201c4bf023

e1000e: Remove two compile warnings

CC [M]  drivers/net/e1000e/lib.o
drivers/net/e1000e/lib.c: In function 'e1000e_read_nvm_eerd':
drivers/net/e1000e/lib.c:1941: warning: 'ret_val' may be used uninitialized
in this function
  CC [M]  drivers/net/e1000e/phy.o
drivers/net/e1000e/phy.c: In function 'e1000e_phy_has_link_generic':
drivers/net/e1000e/phy.c:1324: warning: 'ret_val' may be used
uninitialized in this function

Signed-off-by: Auke Kok <auke-jan.h.kok at intel.com>
Signed-off-by: Jeff Garzik <jeff at garzik.org>
---

diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c
index a04c1e4..6645c21 100644
--- a/drivers/net/e1000e/lib.c
+++ b/drivers/net/e1000e/lib.c
@@ -1938,7 +1938,7 @@ s32 e1000e_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
 {
 	struct e1000_nvm_info *nvm = &hw->nvm;
 	u32 i, eerd = 0;
-	s32 ret_val;
+	s32 ret_val = 0;
 
 	/* A check for invalid values:  offset too large, too many words,
 	 * and not enough words. */
diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c
index 1efb47a..7932318 100644
--- a/drivers/net/e1000e/phy.c
+++ b/drivers/net/e1000e/phy.c
@@ -1321,7 +1321,7 @@ static s32 e1000_wait_autoneg(struct e1000_hw *hw)
 s32 e1000e_phy_has_link_generic(struct e1000_hw *hw, u32 iterations,
 			       u32 usec_interval, bool *success)
 {
-	s32 ret_val;
+	s32 ret_val = 0;
 	u16 i, phy_status;
 
 	for (i = 0; i < iterations; i++) {

linux-2.6-nfs-missing-braces.patch:

--- NEW FILE linux-2.6-nfs-missing-braces.patch ---
From:	"Maciej W. Rozycki" <macro at linux-mips.org>
To:	Trond Myklebust <trond.myklebust at fys.uio.no>
cc:	linux-kernel at vger.kernel.org
Subject: [PATCH] 2.6.21: nfs_readpages: Add missing braces
Message-ID: <Pine.LNX.4.64N.0705211402170.8263 at blysk.ds.pg.gda.pl>

 A change a while ago added a call to gather statistics to a conditional 
statement, but braces were missed on that occasion resulting in a change 
of semanticts.  This a change to rectify.

Signed-off-by: Maciej W. Rozycki <macro at linux-mips.org>
---
 It should be obvious -- please apply.

  Maciej

patch-mips-2.6.18-20060920-nfs_readpages-0
diff -up --recursive --new-file linux-mips-2.6.18-20060920.macro/fs/nfs/read.c linux-mips-2.6.18-20060920/fs/nfs/read.c
--- linux-mips-2.6.18-20060920.macro/fs/nfs/read.c	2006-09-20 14:20:24.000000000 +0000
+++ linux-mips-2.6.18-20060920/fs/nfs/read.c	2007-05-20 15:01:31.000000000 +0000
@@ -696,9 +696,10 @@ int nfs_readpages(struct file *filp, str
 	ret = read_cache_pages(mapping, pages, readpage_async_filler, &desc);
 	if (!list_empty(&head)) {
 		int err = nfs_pagein_list(&head, server->rpages);
-		if (!ret)
+		if (!ret) {
 			nfs_add_stats(inode, NFSIOS_READPAGES, err);
 			ret = err;
+		}
 	}
 	put_nfs_open_context(desc.ctx);
 	return ret;
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


linux-2.6-nfs-noreaddirplus.patch:

--- NEW FILE linux-2.6-nfs-noreaddirplus.patch ---
>From davej  Tue May 15 10:20:48 2007
Return-Path: <SteveD at redhat.com>
X-Spam-Checker-Version: SpamAssassin 3.1.8 (2007-02-13) on
	gelk.kernelslacker.org
X-Spam-Level: 
X-Spam-Status: No, score=-2.6 required=5.0 tests=AWL,BAYES_00,
	UNPARSEABLE_RELAY autolearn=ham version=3.1.8
Received: from pobox.devel.redhat.com [10.11.255.8]
	by gelk.kernelslacker.org with IMAP (fetchmail-6.3.6)
	for <davej at localhost> (single-drop); Tue, 15 May 2007 10:20:48 -0400 (EDT)
Received: from pobox.devel.redhat.com ([unix socket])
	 by pobox.devel.redhat.com (Cyrus v2.2.12-Invoca-RPM-2.2.12-8.1.RHEL4) with LMTPA;
	 Tue, 15 May 2007 10:15:17 -0400
X-Sieve: CMU Sieve 2.2
Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254])
	by pobox.devel.redhat.com (8.13.1/8.13.1) with ESMTP id l4FEFH1d017196
	for <davej at pobox.devel.redhat.com>; Tue, 15 May 2007 10:15:17 -0400
Received: from lacrosse.corp.redhat.com (lacrosse.corp.redhat.com [172.16.52.154])
	by int-mx1.corp.redhat.com (8.13.1/8.13.1) with ESMTP id l4FEFGvZ011912
	for <davej at RedHat.com>; Tue, 15 May 2007 10:15:16 -0400
Received: from [10.12.32.32] (dickson.boston.devel.redhat.com [10.12.32.32])
	by lacrosse.corp.redhat.com (8.12.11.20060308/8.11.6) with ESMTP id l4FEFFWE014460
	for <davej at redhat.com>; Tue, 15 May 2007 10:15:15 -0400
Message-ID: <4649C06E.1050306 at RedHat.com>
Date: Tue, 15 May 2007 10:15:10 -0400
From: Steve Dickson <SteveD at redhat.com>
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.8) Gecko/20061105 Red Hat/1.0.6-0.1.el4 SeaMonkey/1.0.6
MIME-Version: 1.0
To: Dave Jone <davej at redhat.com>
Subject: Turning off READDIRPLUS 
Content-Type: multipart/mixed;
 boundary="------------050000030402040802070505"
Status: RO
Content-Length: 2863
Lines: 80

This is a multi-part message in MIME format.
--------------050000030402040802070505
Content-Type: text/plain; charset=ISO-8859-1; format=flawed
Content-Transfer-Encoding: 7bit

Hey Dave,

The attached patch allow READDIRPLUS to be disabled. I was
hoping it would make into the 2.6.21 kernel but it appears
it will be 2.6.22 or .23...

Would you mind adding this in a bit early? I've already
added mount option to nfs-utils so all that's needed
is this kernel part...

steved.

--------------050000030402040802070505
Content-Type: text/x-patch;
 name="nfs-nordirplus.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="nfs-nordirplus.patch"

commit 74dd34e6e8bb127ff4c182423154b294729b663b
Author: Steve Dickson <steved at redhat.com>
Date:   Sat Apr 14 17:01:15 2007 -0400

    NFS: Added support to turn off the NFSv3 READDIRPLUS RPC.
    
    READDIRPLUS can be a performance hindrance when the client is working with
    large directories. In addition, some servers still have bugs in their
    implementations (e.g. Tru64 returns wrong values for the fsid).
    
    Add a mount flag to enable users to turn it off at mount time following the
    implementation in Apple's NFS client.
    
    Signed-off-by: Steve Dickson <steved at redhat.com>
    Signed-off-by: Trond Myklebust <Trond.Myklebust at netapp.com>

diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 2190e6c..5bd03b9 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -618,7 +618,8 @@ static int nfs_init_server(struct nfs_server *server, const struct nfs_mount_dat
 	if (clp->cl_nfsversion == 3) {
 		if (server->namelen == 0 || server->namelen > NFS3_MAXNAMLEN)
 			server->namelen = NFS3_MAXNAMLEN;
-		server->caps |= NFS_CAP_READDIRPLUS;
+		if (!(data->flags & NFS_MOUNT_NORDIRPLUS))
+			server->caps |= NFS_CAP_READDIRPLUS;
 	} else {
 		if (server->namelen == 0 || server->namelen > NFS2_MAXNAMLEN)
 			server->namelen = NFS2_MAXNAMLEN;
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 719464a..ca20d3c 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -290,6 +290,7 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss,
 		{ NFS_MOUNT_NOAC, ",noac", "" },
 		{ NFS_MOUNT_NONLM, ",nolock", "" },
 		{ NFS_MOUNT_NOACL, ",noacl", "" },
+		{ NFS_MOUNT_NORDIRPLUS, ",nordirplus", "" },
 		{ 0, NULL, NULL }
 	};
 	const struct proc_nfs_info *nfs_infop;
diff --git a/include/linux/nfs_mount.h b/include/linux/nfs_mount.h
index 659c754..cc8b9c5 100644
--- a/include/linux/nfs_mount.h
+++ b/include/linux/nfs_mount.h
@@ -61,6 +61,7 @@ struct nfs_mount_data {
 #define NFS_MOUNT_NOACL		0x0800	/* 4 */
 #define NFS_MOUNT_STRICTLOCK	0x1000	/* reserved for NFSv4 */
 #define NFS_MOUNT_SECFLAVOUR	0x2000	/* 5 */
+#define NFS_MOUNT_NORDIRPLUS	0x4000	/* 5 */
 #define NFS_MOUNT_FLAGMASK	0xFFFF
 
 #endif

--------------050000030402040802070505--


linux-2.6-ondemand-timer.patch:

--- NEW FILE linux-2.6-ondemand-timer.patch ---
>From davej  Wed Mar 28 19:01:19 2007
Return-path: <venkatesh.pallipadi at intel.com>
X-Spam-Checker-Version: SpamAssassin 3.1.8 (2007-02-13) on
	gelk.kernelslacker.org
X-Spam-Level: 
X-Spam-Status: No, score=-2.4 required=5.0 tests=AWL,BAYES_00 autolearn=ham
	version=3.1.8
Envelope-to: davej at codemonkey.org.uk
Delivery-date: Thu, 29 Mar 2007 00:01:12 +0100
Received: from testure.choralone.org [194.9.77.134]
	by gelk.kernelslacker.org with IMAP (fetchmail-6.3.6)
	for <davej at localhost> (single-drop); Wed, 28 Mar 2007 19:01:19 -0400 (EDT)
Received: from mga01.intel.com ([192.55.52.88])
	by testure.choralone.org with esmtp (Exim 4.63)
	(envelope-from <venkatesh.pallipadi at intel.com>)
	id 1HWh8h-0006J9-Es
	for davej at codemonkey.org.uk; Thu, 29 Mar 2007 00:01:11 +0100
Received: from fmsmga001.fm.intel.com ([10.253.24.23])
  by mga01.intel.com with ESMTP; 28 Mar 2007 16:01:04 -0700
Received: from linux-os.sc.intel.com ([172.25.110.8])
  by fmsmga001.fm.intel.com with ESMTP; 28 Mar 2007 16:01:03 -0700
X-ExtLoop1: 1
X-IronPort-AV: i="4.14,342,1170662400"; 
   d="scan'208"; a="221109611:sNHT21096852"
Received: by linux-os.sc.intel.com (Postfix, from userid 47009)
	id AADD228006; Wed, 28 Mar 2007 16:00:21 -0700 (PDT)
Date: Wed, 28 Mar 2007 16:00:21 -0700
From: Venki Pallipadi <venkatesh.pallipadi at intel.com>
To: Oleg Nesterov <oleg at tv-sign.ru>
Cc: linux-kernel <linux-kernel at vger.kernel.org>,
	akpm at linux-foundation.org, davej at codemonkey.org.uk,
	johnstul at us.ibm.com, mingo at elte.hu, tglx at linutronix.de,
	Andi Kleen <ak at suse.de>
Subject: Re: [PATCH] Add support for deferrable timers (respun-Mar28)
Message-ID: <20070328230021.GA29774 at linux-os.sc.intel.com>
References: <200703212353.l2LNrNOj007453 at shell0.pdx.osdl.net> <20070322140532.GA120 at tv-sign.ru> <20070322151817.GA29840 at linux-os.sc.intel.com> <20070322161355.GA160 at tv-sign.ru> <20070327204344.GA21529 at linux-os.sc.intel.com> <20070327211145.GB216 at tv-sign.ru> <20070327215542.GA27408 at linux-os.sc.intel.com> <20070327222227.GA279 at tv-sign.ru>
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
In-Reply-To: <20070327222227.GA279 at tv-sign.ru>
User-Agent: Mutt/1.4.1i
Status: RO
Content-Length: 6118
Lines: 195


Andrew,

Please drop the patch you included yesterday and two incremental patches and
use the patch below.

This patch is - yesterday's patch + Your tidy cleanup +
minor changes based on comments from Oleg and Andi. This is a lot
cleaner (and smaller) than earlier patches.

Thanks,
Venki


Introduce a new flag for timers - deferrable:
Timers that work normally when system is busy. But, will not cause CPU to
come out of idle (just to service this timer), when CPU is idle. Instead,
this timer will be serviced when CPU eventually wakes up with a subsequent
non-deferrable timer.

The main advantage of this is to avoid unnecessary timer interrupts when
CPU is idle. If the routine currently called by a timer can wait until next
event without any issues, this new timer can be used to setup timer event
for that routine. This, with dynticks, allows CPUs to be lazy, allowing them
to stay in idle for extended period of time by reducing unnecesary wakeup and
thereby reducing the power consumption.

This patch:
Builds this new timer on top of existing timer infrastructure. It uses
last bit in 'base' pointer of timer_list structure to store this
deferrable timer flag. __next_timer_interrupt() function
skips over these deferrable timers when CPU looks for
next timer event for which it has to wake up.

This is exported by a new interface init_timer_deferrable() that can
be called in place of regular init_timer().

Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi at intel.com>

Index: new/kernel/timer.c
===================================================================
--- new.orig/kernel/timer.c	2007-03-22 16:27:44.000000000 -0800
+++ new/kernel/timer.c	2007-03-28 10:05:38.000000000 -0800
@@ -74,7 +74,7 @@
 	tvec_t tv3;
 	tvec_t tv4;
 	tvec_t tv5;
-} ____cacheline_aligned_in_smp;
+} ____cacheline_aligned;
 
 typedef struct tvec_t_base_s tvec_base_t;
 
@@ -82,6 +82,37 @@
 EXPORT_SYMBOL(boot_tvec_bases);
 static DEFINE_PER_CPU(tvec_base_t *, tvec_bases) = &boot_tvec_bases;
 
+/*
+ * Note that all tvec_bases is 2 byte aligned and lower bit of
+ * base in timer_list is guaranteed to be zero. Use the LSB for
+ * the new flag to indicate whether the timer is deferrable
+ */
+#define TBASE_DEFERRABLE_FLAG		(0x1)
+
+/* Functions below help us manage 'deferrable' flag */
+static inline unsigned int tbase_get_deferrable(tvec_base_t *base)
+{
+	return ((unsigned int)(unsigned long)base & TBASE_DEFERRABLE_FLAG);
+}
+
+static inline tvec_base_t *tbase_get_base(tvec_base_t *base)
+{
+	return ((tvec_base_t *)((unsigned long)base & ~TBASE_DEFERRABLE_FLAG));
+}
+
+static inline void timer_set_deferrable(struct timer_list *timer)
+{
+	timer->base = ((tvec_base_t *)((unsigned long)(timer->base) |
+	                               TBASE_DEFERRABLE_FLAG));
+}
+
+static inline void
+timer_set_base(struct timer_list *timer, tvec_base_t *new_base)
+{
+	timer->base = (tvec_base_t *)((unsigned long)(new_base) |
+	                              tbase_get_deferrable(timer->base));
+}
+
 /**
  * __round_jiffies - function to round jiffies to a full second
  * @j: the time in (absolute) jiffies that should be rounded
@@ -295,6 +326,13 @@
 }
 EXPORT_SYMBOL(init_timer);
 
+void fastcall init_timer_deferrable(struct timer_list *timer)
+{
+	init_timer(timer);
+	timer_set_deferrable(timer);
+}
+EXPORT_SYMBOL(init_timer_deferrable);
+
 static inline void detach_timer(struct timer_list *timer,
 				int clear_pending)
 {
@@ -325,10 +363,11 @@
 	tvec_base_t *base;
 
 	for (;;) {
-		base = timer->base;
+		tvec_base_t *prelock_base = timer->base;
+		base = tbase_get_base(prelock_base);
 		if (likely(base != NULL)) {
 			spin_lock_irqsave(&base->lock, *flags);
-			if (likely(base == timer->base))
+			if (likely(prelock_base == timer->base))
 				return base;
 			/* The timer has migrated to another CPU */
 			spin_unlock_irqrestore(&base->lock, *flags);
@@ -365,11 +404,11 @@
 		 */
 		if (likely(base->running_timer != timer)) {
 			/* See the comment in lock_timer_base() */
-			timer->base = NULL;
+			timer_set_base(timer, NULL);
 			spin_unlock(&base->lock);
 			base = new_base;
 			spin_lock(&base->lock);
-			timer->base = base;
+			timer_set_base(timer, base);
 		}
 	}
 
@@ -397,7 +436,7 @@
 	timer_stats_timer_set_start_info(timer);
   	BUG_ON(timer_pending(timer) || !timer->function);
 	spin_lock_irqsave(&base->lock, flags);
-	timer->base = base;
+	timer_set_base(timer, base);
 	internal_add_timer(base, timer);
 	spin_unlock_irqrestore(&base->lock, flags);
 }
@@ -548,7 +587,7 @@
 	 * don't have to detach them individually.
 	 */
 	list_for_each_entry_safe(timer, tmp, &tv_list, entry) {
-		BUG_ON(timer->base != base);
+		BUG_ON(tbase_get_base(timer->base) != base);
 		internal_add_timer(base, timer);
 	}
 
@@ -634,6 +673,9 @@
 	index = slot = timer_jiffies & TVR_MASK;
 	do {
 		list_for_each_entry(nte, base->tv1.vec + slot, entry) {
+ 			if (tbase_get_deferrable(nte->base))
+ 				continue;
+ 
 			found = 1;
 			expires = nte->expires;
 			/* Look at the cascade bucket(s)? */
@@ -1602,6 +1644,13 @@
 						cpu_to_node(cpu));
 			if (!base)
 				return -ENOMEM;
+
+			/* Make sure that tvec_base is 2 byte aligned */
+			if (tbase_get_deferrable(base)) {
+				WARN_ON(1);
+				kfree(base);
+				return -ENOMEM;
+			}
 			memset(base, 0, sizeof(*base));
 			per_cpu(tvec_bases, cpu) = base;
 		} else {
@@ -1643,7 +1692,7 @@
 	while (!list_empty(head)) {
 		timer = list_entry(head->next, struct timer_list, entry);
 		detach_timer(timer, 0);
-		timer->base = new_base;
+		timer_set_base(timer, new_base);
 		internal_add_timer(new_base, timer);
 	}
 }
Index: new/include/linux/timer.h
===================================================================
--- new.orig/include/linux/timer.h	2007-03-22 16:27:44.000000000 -0800
+++ new/include/linux/timer.h	2007-03-28 10:03:14.000000000 -0800
@@ -37,6 +37,7 @@
 		TIMER_INITIALIZER(_function, _expires, _data)
 
 void fastcall init_timer(struct timer_list * timer);
+void fastcall init_timer_deferrable(struct timer_list *timer);
 
 static inline void setup_timer(struct timer_list * timer,
 				void (*function)(unsigned long),

>From davej  Wed Mar 21 16:25:31 2007
Return-Path: <venkatesh.pallipadi at intel.com>
X-Spam-Checker-Version: SpamAssassin 3.1.8 (2007-02-13) on
	gelk.kernelslacker.org
X-Spam-Level: 
X-Spam-Status: No, score=-2.3 required=5.0 tests=AWL,BAYES_00,
	UNPARSEABLE_RELAY autolearn=ham version=3.1.8
Received: from pobox.devel.redhat.com [10.11.255.8]
	by gelk.kernelslacker.org with IMAP (fetchmail-6.3.6)
	for <davej at localhost> (single-drop); Wed, 21 Mar 2007 16:25:31 -0400 (EDT)
Received: from pobox.devel.redhat.com ([unix socket])
	 by pobox.devel.redhat.com (Cyrus v2.2.12-Invoca-RPM-2.2.12-3.RHEL4.1) with LMTPA;
	 Wed, 21 Mar 2007 16:24:10 -0400
X-Sieve: CMU Sieve 2.2
Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254])
	by pobox.devel.redhat.com (8.13.1/8.13.1) with ESMTP id l2LKOAin016801
	for <davej at pobox.devel.redhat.com>; Wed, 21 Mar 2007 16:24:10 -0400
Received: from mx1.redhat.com (mx1.redhat.com [172.16.48.31])
	by int-mx1.corp.redhat.com (8.13.1/8.13.1) with ESMTP id l2LKO9BO005871
	for <davej at redhat.com>; Wed, 21 Mar 2007 16:24:09 -0400
Received: from mga03.intel.com (mga03.intel.com [143.182.124.21])
	by mx1.redhat.com (8.13.1/8.13.1) with ESMTP id l2LKNs7a016150
	for <davej at redhat.com>; Wed, 21 Mar 2007 16:24:04 -0400
Received: from azsmga001.ch.intel.com ([10.2.17.19])
  by mga03.intel.com with ESMTP; 21 Mar 2007 13:24:03 -0700
Received: from linux-os.sc.intel.com ([172.25.110.8])
  by azsmga001.ch.intel.com with ESMTP; 21 Mar 2007 13:24:03 -0700
X-ExtLoop1: 1
X-IronPort-AV: i="4.14,309,1170662400"; 
   d="scan'208"; a="200303186:sNHT18723936"
Received: by linux-os.sc.intel.com (Postfix, from userid 47009)
	id 0E5B328006; Wed, 21 Mar 2007 13:23:40 -0700 (PDT)
Date: Wed, 21 Mar 2007 13:23:40 -0700
From: Venkatesh Pallipadi <venkatesh.pallipadi at intel.com>
To: Andrew Morton <akpm at osdl.org>
Cc: linux-kernel <linux-kernel at vger.kernel.org>, Dave Jones <davej at redhat.com>,
        tglx at linutronix.de
Subject: [PATCH 2/2] Export deferrable timer through workqueue and use it in ondemand governor
Message-ID: <20070321202339.GB29367 at linux-os.sc.intel.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
User-Agent: Mutt/1.4.1i
X-RedHat-Spam-Score: -1.137 
Status: RO
Content-Length: 1509
Lines: 40



Add a new deferrable delayed work init. This can be used to schedule work
that are 'unimportant' when CPU is idle and can be called later, when CPU
eventually comes out of idle.

Use this init in cpufreq ondemand governor.
 
Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi at intel.com>

Index: new/drivers/cpufreq/cpufreq_ondemand.c
===================================================================
--- new.orig/drivers/cpufreq/cpufreq_ondemand.c	2007-03-21 09:16:52.000000000 -0800
+++ new/drivers/cpufreq/cpufreq_ondemand.c	2007-03-21 09:18:08.000000000 -0800
@@ -470,7 +470,7 @@
 	dbs_info->enable = 1;
 	ondemand_powersave_bias_init();
 	dbs_info->sample_type = DBS_NORMAL_SAMPLE;
-	INIT_DELAYED_WORK(&dbs_info->work, do_dbs_timer);
+	INIT_DELAYED_WORK_DEF(&dbs_info->work, do_dbs_timer);
 	queue_delayed_work_on(dbs_info->cpu, kondemand_wq, &dbs_info->work,
 	                      delay);
 }
Index: new/include/linux/workqueue.h
===================================================================
--- new.orig/include/linux/workqueue.h	2007-03-21 09:16:52.000000000 -0800
+++ new/include/linux/workqueue.h	2007-03-21 09:18:08.000000000 -0800
@@ -115,6 +115,12 @@
 		init_timer(&(_work)->timer);			\
 	} while (0)
 
+#define INIT_DELAYED_WORK_DEF(_work, _func)			\
+	do {							\
+		INIT_WORK(&(_work)->work, (_func));		\
+		init_timer_deferrable(&(_work)->timer);		\
+	} while (0)
+
 #define INIT_DELAYED_WORK_NAR(_work, _func)			\
 	do {							\
 		INIT_WORK_NAR(&(_work)->work, (_func));		\


Userspace governor registers a frequency change notifier at init time, even
when no CPU is set to userspace governor. Make it register only when
atleast one CPU is using userspace.

Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi at intel.com>

Index: linux-2.6.22-rc-mm/drivers/cpufreq/cpufreq_userspace.c
===================================================================
--- linux-2.6.22-rc-mm.orig/drivers/cpufreq/cpufreq_userspace.c
+++ linux-2.6.22-rc-mm/drivers/cpufreq/cpufreq_userspace.c
@@ -37,6 +37,7 @@ static unsigned int	cpu_set_freq[NR_CPUS
 static unsigned int	cpu_is_managed[NR_CPUS];
 
 static DEFINE_MUTEX	(userspace_mutex);
+static int cpus_using_userspace_governor;
 
 #define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_GOVERNOR, "userspace", msg)
 
@@ -47,7 +48,11 @@ userspace_cpufreq_notifier(struct notifi
 {
         struct cpufreq_freqs *freq = data;
 
-	dprintk("saving cpu_cur_freq of cpu %u to be %u kHz\n", freq->cpu, freq->new);
+	if (!cpu_is_managed[freq->cpu])
+		return 0;
+
+	dprintk("saving cpu_cur_freq of cpu %u to be %u kHz\n",
+			freq->cpu, freq->new);
 	cpu_cur_freq[freq->cpu] = freq->new;
 
         return 0;
@@ -142,6 +147,13 @@ static int cpufreq_governor_userspace(st
 		if (rc)
 			goto start_out;
 
+		if (cpus_using_userspace_governor == 0) {
+			cpufreq_register_notifier(
+					&userspace_cpufreq_notifier_block,
+					CPUFREQ_TRANSITION_NOTIFIER);
+		}
+		cpus_using_userspace_governor++;
+
 		cpu_is_managed[cpu] = 1;
 		cpu_min_freq[cpu] = policy->min;
 		cpu_max_freq[cpu] = policy->max;
@@ -153,6 +165,13 @@ start_out:
 		break;
 	case CPUFREQ_GOV_STOP:
 		mutex_lock(&userspace_mutex);
+		cpus_using_userspace_governor--;
+		if (cpus_using_userspace_governor == 0) {
+        		cpufreq_unregister_notifier(
+					&userspace_cpufreq_notifier_block,
+					CPUFREQ_TRANSITION_NOTIFIER);
+		}
+
 		cpu_is_managed[cpu] = 0;
 		cpu_min_freq[cpu] = 0;
 		cpu_max_freq[cpu] = 0;
@@ -198,7 +217,6 @@ EXPORT_SYMBOL(cpufreq_gov_userspace);
 
 static int __init cpufreq_gov_userspace_init(void)
 {
-	cpufreq_register_notifier(&userspace_cpufreq_notifier_block, CPUFREQ_TRANSITION_NOTIFIER);
 	return cpufreq_register_governor(&cpufreq_gov_userspace);
 }
 
@@ -206,7 +224,6 @@ static int __init cpufreq_gov_userspace_
 static void __exit cpufreq_gov_userspace_exit(void)
 {
 	cpufreq_unregister_governor(&cpufreq_gov_userspace);
-        cpufreq_unregister_notifier(&userspace_cpufreq_notifier_block, CPUFREQ_TRANSITION_NOTIFIER);
 }
 
 

Due to rounding and inexact jiffy accounting, idle_ticks can sometimes
be higher than total_ticks. Make sure those cases are handled as
zero load case.

Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi at intel.com>

Index: linux-2.6.22-rc-mm/drivers/cpufreq/cpufreq_ondemand.c
===================================================================
--- linux-2.6.22-rc-mm.orig/drivers/cpufreq/cpufreq_ondemand.c
+++ linux-2.6.22-rc-mm/drivers/cpufreq/cpufreq_ondemand.c
@@ -325,7 +325,7 @@ static struct attribute_group dbs_attr_g
 static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
 {
 	unsigned int idle_ticks, total_ticks;
-	unsigned int load;
+	unsigned int load = 0;
 	cputime64_t cur_jiffies;
 
 	struct cpufreq_policy *policy;
@@ -370,7 +370,8 @@ static void dbs_check_cpu(struct cpu_dbs
 		if (tmp_idle_ticks < idle_ticks)
 			idle_ticks = tmp_idle_ticks;
 	}
-	load = (100 * (total_ticks - idle_ticks)) / total_ticks;
+	if (likely(total_ticks > idle_ticks))
+		load = (100 * (total_ticks - idle_ticks)) / total_ticks;
 
 	/* Check for frequency increase */
 	if (load > dbs_tuners_ins.up_threshold) {

With tickless kernel and software coordination os P-states, ondemand
can look at wrong idle statistics. This can happen when ondemand sampling
is happening on CPU 0 and due to software coordination sampling also looks at
utilization of CPU 1. If CPU 1 is in tickless state at that moment, its idle
statistics will not be uptodate and CPU 0 thinks CPU 1 is idle for less
amount of time than it actually is.

This can be resolved by looking at all the busy times of CPUs, which is
accurate, even with tickless, and use that to determine idle time in a
round about way (total time - busy time).

Thanks to Arjan for originally reporting this ondemand issue on
Lenovo T61.

Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi at intel.com>

Index: linux-2.6.22-rc-mm/drivers/cpufreq/cpufreq_ondemand.c
===================================================================
--- linux-2.6.22-rc-mm.orig/drivers/cpufreq/cpufreq_ondemand.c
+++ linux-2.6.22-rc-mm/drivers/cpufreq/cpufreq_ondemand.c
@@ -96,15 +96,25 @@ static struct dbs_tuners {
 
 static inline cputime64_t get_cpu_idle_time(unsigned int cpu)
 {
-	cputime64_t retval;
+	cputime64_t idle_time;
+	cputime64_t cur_jiffies;
+	cputime64_t busy_time;
 
-	retval = cputime64_add(kstat_cpu(cpu).cpustat.idle,
-			kstat_cpu(cpu).cpustat.iowait);
+	cur_jiffies = jiffies64_to_cputime64(get_jiffies_64());
+	busy_time = cputime64_add(kstat_cpu(cpu).cpustat.user,
+			kstat_cpu(cpu).cpustat.system);
 
-	if (dbs_tuners_ins.ignore_nice)
-		retval = cputime64_add(retval, kstat_cpu(cpu).cpustat.nice);
+	busy_time = cputime64_add(busy_time, kstat_cpu(cpu).cpustat.irq);
+	busy_time = cputime64_add(busy_time, kstat_cpu(cpu).cpustat.softirq);
+	busy_time = cputime64_add(busy_time, kstat_cpu(cpu).cpustat.steal);
 
-	return retval;
+	if (!dbs_tuners_ins.ignore_nice) {
+		busy_time = cputime64_add(busy_time,
+				kstat_cpu(cpu).cpustat.nice);
+	}
+
+	idle_time = cputime64_sub(cur_jiffies, busy_time);
+	return idle_time;
 }
 
 /*
@@ -339,7 +349,8 @@ static void dbs_check_cpu(struct cpu_dbs
 	cur_jiffies = jiffies64_to_cputime64(get_jiffies_64());
 	total_ticks = (unsigned int) cputime64_sub(cur_jiffies,
 			this_dbs_info->prev_cpu_wall);
-	this_dbs_info->prev_cpu_wall = cur_jiffies;
+	this_dbs_info->prev_cpu_wall = get_jiffies_64();
+
 	if (!total_ticks)
 		return;
 	/*

linux-2.6-pass-g-to-assembler-under-config_debug_info.patch:

--- NEW FILE linux-2.6-pass-g-to-assembler-under-config_debug_info.patch ---
From: Roland McGrath <roland at redhat.com>

The assembler for a while now supports -gdwarf to generate source line info
just like the C compiler does.  Source-level assembly debugging sounds like an
oxymoron, but it is handy to be able to see the right source file and read its
comments rather than just the disassembly.  This patch enables -gdwarf for
assembly files when CONFIG_DEBUG_INFO=y and the assembler supports the option.

Signed-off-by: Roland McGrath <roland at redhat.com>
Cc: Sam Ravnborg <sam at ravnborg.org>
Cc: <linux-arch at vger.kernel.org>
Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
---

 Makefile |    1 +
 1 file changed, 1 insertion(+)

diff -puN Makefile~pass-g-to-assembler-under-config_debug_info Makefile
--- a/Makefile~pass-g-to-assembler-under-config_debug_info
+++ a/Makefile
@@ -499,6 +499,7 @@ endif
 
 ifdef CONFIG_DEBUG_INFO
 CFLAGS		+= -g
+AFLAGS		+= $(call as-option, -gdwarf2)
 endif
 
 # Force gcc to behave correct even for buggy distributions
_

linux-2.6-pmac-zilog.patch:

--- NEW FILE linux-2.6-pmac-zilog.patch ---
diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c
index 752ef07..2ab23af 100644
--- a/drivers/serial/pmac_zilog.c
+++ b/drivers/serial/pmac_zilog.c
@@ -99,9 +99,10 @@ static DEFINE_MUTEX(pmz_irq_mutex);
 
 static struct uart_driver pmz_uart_reg = {
 	.owner		=	THIS_MODULE,
-	.driver_name	=	"ttyS",
-	.dev_name	=	"ttyS",
-	.major		=	TTY_MAJOR,
+	.driver_name	=	"ttyPZ",
+	.dev_name	=	"ttyPZ",
+	.major		=	204,
+	.minor		=	192,
 };
 
 
@@ -1776,7 +1777,7 @@ static void pmz_console_write(struct console *con, const char *s, unsigned int c
 static int __init pmz_console_setup(struct console *co, char *options);
 
 static struct console pmz_console = {
-	.name	=	"ttyS",
+	.name	=	"ttyPZ",
 	.write	=	pmz_console_write,
 	.device	=	uart_console_device,
 	.setup	=	pmz_console_setup,
@@ -1800,7 +1801,6 @@ static int __init pmz_register(void)
 	
 	pmz_uart_reg.nr = pmz_ports_count;
 	pmz_uart_reg.cons = PMACZILOG_CONSOLE;
-	pmz_uart_reg.minor = 64;
 
 	/*
 	 * Register this driver with the serial core

linux-2.6-pmtrace-time-fix.patch:

--- NEW FILE linux-2.6-pmtrace-time-fix.patch ---
--- linux-2.6.22.noarch/drivers/base/power/trace.c~	2007-08-29 15:34:17.000000000 -0400
+++ linux-2.6.22.noarch/drivers/base/power/trace.c	2007-08-29 15:34:24.000000000 -0400
@@ -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, time.tm_mday, time.tm_year);
+		time.tm_mon + 1, time.tm_mday, time.tm_year % 100);
 	val = time.tm_year;				/* 100 years */
 	if (val > 100)
 		val -= 100;

linux-2.6-powermac-generic-suspend-1.patch:

--- NEW FILE linux-2.6-powermac-generic-suspend-1.patch ---
Subject: [PATCH] powerpc: generic time suspend/resume code

This patch removes the time suspend/restore code that was done through
a PMU notifier in arch/platforms/powermac/time.c.

Instead, introduce arch/powerpc/sysdev/timer.c which creates a sys
device and handles time of day suspend/resume through that.

This should probably be replaced by using the generic RTC framework
but for now it gets rid of the arcane powermac specific hack.

Signed-off-by: Johannes Berg <johannes at sipsolutions.net>
Cc: Benjamin Herrenschmidt <benh at kernel.crashing.org>

---
 arch/powerpc/Kconfig                   |    5 ++
 arch/powerpc/platforms/powermac/time.c |   38 -----------------
 arch/powerpc/sysdev/Makefile           |    3 +
 arch/powerpc/sysdev/timer.c            |   70 +++++++++++++++++++++++++++++++++
 4 files changed, 78 insertions(+), 38 deletions(-)

--- wireless-dev.orig/arch/powerpc/platforms/powermac/time.c	2007-04-05 14:31:28.928552246 +0200
+++ wireless-dev/arch/powerpc/platforms/powermac/time.c	2007-04-05 14:31:45.778552246 +0200
@@ -297,49 +297,11 @@ int __init via_calibrate_decr(void)
 }
 #endif
 
-#ifdef CONFIG_PM
-/*
- * Reset the time after a sleep.
- */
-static int
-time_sleep_notify(struct pmu_sleep_notifier *self, int when)
-{
-	static unsigned long time_diff;
-	unsigned long flags;
-	unsigned long seq;
-	struct timespec tv;
-
-	switch (when) {
-	case PBOOK_SLEEP_NOW:
-		do {
-			seq = read_seqbegin_irqsave(&xtime_lock, flags);
-			time_diff = xtime.tv_sec - pmac_get_boot_time();
-		} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
-		break;
-	case PBOOK_WAKE:
-		tv.tv_sec = pmac_get_boot_time() + time_diff;
-		tv.tv_nsec = 0;
-		do_settimeofday(&tv);
-		break;
-	}
-	return PBOOK_SLEEP_OK;
-}
-
-static struct pmu_sleep_notifier time_sleep_notifier = {
-	time_sleep_notify, SLEEP_LEVEL_MISC,
-};
-#endif /* CONFIG_PM */
-
 /*
  * Query the OF and get the decr frequency.
  */
 void __init pmac_calibrate_decr(void)
 {
-#if defined(CONFIG_PM) && defined(CONFIG_ADB_PMU)
-	/* XXX why here? */
-	pmu_register_sleep_notifier(&time_sleep_notifier);
-#endif
-
 	generic_calibrate_decr();
 
 #ifdef CONFIG_PPC32
--- wireless-dev.orig/arch/powerpc/Kconfig	2007-04-05 14:31:28.988552246 +0200
+++ wireless-dev/arch/powerpc/Kconfig	2007-04-05 14:31:45.778552246 +0200
@@ -11,6 +11,11 @@ config PPC64
 	  This option selects whether a 32-bit or a 64-bit kernel
 	  will be built.
 
+config PPC_PM_NEEDS_RTC_LIB
+	bool
+	select RTC_LIB
+	default y if PM
+
 config PPC32
 	bool
 	default y if !PPC64
--- wireless-dev.orig/arch/powerpc/sysdev/Makefile	2007-04-05 14:31:29.008552246 +0200
+++ wireless-dev/arch/powerpc/sysdev/Makefile	2007-04-05 14:31:45.778552246 +0200
@@ -14,6 +14,9 @@ obj-$(CONFIG_FSL_SOC)		+= fsl_soc.o
 obj-$(CONFIG_TSI108_BRIDGE)	+= tsi108_pci.o tsi108_dev.o
 obj-$(CONFIG_QUICC_ENGINE)	+= qe_lib/
 
+# contains only the suspend handler for time
+obj-$(CONFIG_PM)		+= timer.o
+
 ifeq ($(CONFIG_PPC_MERGE),y)
 obj-$(CONFIG_PPC_I8259)		+= i8259.o
 obj-$(CONFIG_PPC_83xx)		+= ipic.o
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ wireless-dev/arch/powerpc/sysdev/timer.c	2007-04-05 14:31:45.778552246 +0200
@@ -0,0 +1,70 @@
+/*
+ * Common code to keep time when machine suspends.
+ *
+ * Copyright 2007	Johannes Berg <johannes at sipsolutions.net>
+ *
+ * GPLv2
+ */
+
+#include <linux/time.h>
+#include <asm/rtc.h>
+
+static unsigned long suspend_rtc_time;
+
+/*
+ * Reset the time after a sleep.
+ */
+static int timer_resume(struct sys_device *dev)
+{
+	struct timeval tv;
+	struct timespec ts;
+	struct rtc_time cur_rtc_tm;
+	unsigned long cur_rtc_time, diff;
+
+	/* get current RTC time and convert to seconds */
+	get_rtc_time(&cur_rtc_tm);
+	rtc_tm_to_time(&cur_rtc_tm, &cur_rtc_time);
+
+	diff = cur_rtc_time - suspend_rtc_time;
+
+	/* adjust time of day by seconds that elapsed while
+	 * we were suspended */
+	do_gettimeofday(&tv);
+	ts.tv_sec = tv.tv_sec + diff;
+	ts.tv_nsec = tv.tv_usec * NSEC_PER_USEC;
+	do_settimeofday(&ts);
+
+	return 0;
+}
+
+static int timer_suspend(struct sys_device *dev, pm_message_t state)
+{
+	struct rtc_time suspend_rtc_tm;
+	WARN_ON(!ppc_md.get_rtc_time);
+
+	get_rtc_time(&suspend_rtc_tm);
+	rtc_tm_to_time(&suspend_rtc_tm, &suspend_rtc_time);
+
+	return 0;
+}
+
+static struct sysdev_class timer_sysclass = {
+	.resume = timer_resume,
+	.suspend = timer_suspend,
+	set_kset_name("timer"),
+};
+
+static struct sys_device device_timer = {
+	.id = 0,
+	.cls = &timer_sysclass,
+};
+
+static int time_init_device(void)
+{
+	int error = sysdev_class_register(&timer_sysclass);
+	if (!error)
+		error = sysdev_register(&device_timer);
+	return error;
+}
+
+device_initcall(time_init_device);

linux-2.6-powermac-generic-suspend-2.patch:

--- NEW FILE linux-2.6-powermac-generic-suspend-2.patch ---
Subject: [PATCH] powerpc: fix suspend states again

In commit 0fba3a1f39f8b0a50b56c8b068fa52131cbc84c2 (a very long time ago,
May 2006), I fixed a bug that caused powermacs to crash when you tried
entering standby/mem suspend states.

As I'm now getting more familiar with the suspend code I notice a few
more things:
 1. we previously misunderstood what pm_ops is for, it isn't supposed to be
    for doing platform dependent suspend/resume stuff that needs to be done
    for suspend to disk (as we currently try to use it!), it is instead for
    entering platform dependent suspend states ("standby", "mem").
 2. due to the first point, we never properly save FPU and altivec states
    when suspending to disk. It probably hasn't hurt yet because the process
    that writes the "disk" to /sys/power/state uses neither and its context
    is used.

This patch addresses these points as follows:
 1. remove all pm_ops from powermac, powermac suspend to ram isn't currently
    usable via /sys/power/state but is done via the PMU instead.
 2. move the code responsible for storing FPU/altivec state into
    save_processor_state and the set_context() call to restore_processor_state.
 3. add a call to kernel_enable_spe()

It may look like there is some code removal missing but that is actually because
the new suspend.h file overrides the ppc/suspend.h one which was previously used.

A follow-on patch will create new pm_ops for via-pmu.

Signed-off-by: Johannes Berg <johannes at sipsolutions.net>
Cc: Benjamin Herrenschmidt <benh at kernel.crashing.org>

---
 arch/powerpc/kernel/Makefile            |    1 
 arch/powerpc/kernel/swsusp.c            |   42 ++++++++++++++++++++
 arch/powerpc/platforms/powermac/setup.c |   65 --------------------------------
 include/asm-powerpc/suspend.h           |    9 ++++
 4 files changed, 52 insertions(+), 65 deletions(-)

--- wireless-dev.orig/arch/powerpc/platforms/powermac/setup.c	2007-04-05 14:31:28.448552246 +0200
+++ wireless-dev/arch/powerpc/platforms/powermac/setup.c	2007-04-05 14:31:46.488552246 +0200
@@ -420,76 +420,11 @@ static void __init find_boot_device(void
 #endif
 }
 
-/* TODO: Merge the suspend-to-ram with the common code !!!
- * currently, this is a stub implementation for suspend-to-disk
- * only
- */
-
-#ifdef CONFIG_SOFTWARE_SUSPEND
-
-static int pmac_pm_prepare(suspend_state_t state)
-{
-	printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state);
-
-	return 0;
-}
-
-static int pmac_pm_enter(suspend_state_t state)
-{
-	printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state);
-
-	/* Giveup the lazy FPU & vec so we don't have to back them
-	 * up from the low level code
-	 */
-	enable_kernel_fp();
-
-#ifdef CONFIG_ALTIVEC
-	if (cur_cpu_spec->cpu_features & CPU_FTR_ALTIVEC)
-		enable_kernel_altivec();
-#endif /* CONFIG_ALTIVEC */
-
-	return 0;
-}
-
-static int pmac_pm_finish(suspend_state_t state)
-{
-	printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state);
-
-	/* Restore userland MMU context */
-	set_context(current->active_mm->context.id, current->active_mm->pgd);
-
-	return 0;
-}
-
-static int pmac_pm_valid(suspend_state_t state)
-{
-	switch (state) {
-	case PM_SUSPEND_DISK:
-		return 1;
-	/* can't do any other states via generic mechanism yet */
-	default:
-		return 0;
-	}
-}
-
-static struct pm_ops pmac_pm_ops = {
-	.pm_disk_mode	= PM_DISK_SHUTDOWN,
-	.prepare	= pmac_pm_prepare,
-	.enter		= pmac_pm_enter,
-	.finish		= pmac_pm_finish,
-	.valid		= pmac_pm_valid,
-};
-
-#endif /* CONFIG_SOFTWARE_SUSPEND */
-
 static int initializing = 1;
 
 static int pmac_late_init(void)
 {
 	initializing = 0;
-#ifdef CONFIG_SOFTWARE_SUSPEND
-	pm_set_ops(&pmac_pm_ops);
-#endif /* CONFIG_SOFTWARE_SUSPEND */
 	return 0;
 }
 
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ wireless-dev/include/asm-powerpc/suspend.h	2007-04-05 14:31:46.488552246 +0200
@@ -0,0 +1,9 @@
+#ifndef __ASM_POWERPC_SUSPEND_H
+#define __ASM_POWERPC_SUSPEND_H
+
+static inline int arch_prepare_suspend(void) { return 0; }
+
+void save_processor_state(void);
+void restore_processor_state(void);
+
+#endif /* __ASM_POWERPC_SUSPEND_H */
--- wireless-dev.orig/arch/powerpc/kernel/Makefile	2007-04-05 14:31:28.468552246 +0200
+++ wireless-dev/arch/powerpc/kernel/Makefile	2007-04-05 14:31:46.488552246 +0200
@@ -36,6 +36,7 @@ obj-$(CONFIG_GENERIC_TBSYNC)	+= smp-tbsy
 obj-$(CONFIG_CRASH_DUMP)	+= crash_dump.o
 obj-$(CONFIG_6xx)		+= idle_6xx.o l2cr_6xx.o cpu_setup_6xx.o
 obj-$(CONFIG_TAU)		+= tau_6xx.o
+obj-$(CONFIG_SOFTWARE_SUSPEND)	+= swsusp.o
 obj32-$(CONFIG_SOFTWARE_SUSPEND) += swsusp_32.o
 obj32-$(CONFIG_MODULES)		+= module_32.o
 
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ wireless-dev/arch/powerpc/kernel/swsusp.c	2007-04-05 14:31:46.488552246 +0200
@@ -0,0 +1,42 @@
+/*
+ * Common powerpc suspend code for 32 and 64 bits
+ *
+ * Copyright 2007	Johannes Berg <johannes at sipsolutions.net>
+ *
+ * GPLv2
+ */
+
+#include <linux/sched.h>
+#include <asm/suspend.h>
+#include <asm/cputable.h>
+#include <asm/system.h>
+#include <asm/current.h>
+#include <asm/mmu_context.h>
+
+#ifdef CONFIG_SPE
+extern void enable_kernel_spe(void);
+#endif
+
+void save_processor_state(void)
+{
+	/* Giveup the lazy FPU & vec so we don't have to back them
+	 * up from the low level code
+	 */
+	enable_kernel_fp();
+
+#ifdef CONFIG_ALTIVEC
+	if (cur_cpu_spec->cpu_features & CPU_FTR_ALTIVEC)
+		enable_kernel_altivec();
+#endif /* CONFIG_ALTIVEC */
+
+#ifdef CONFIG_SPE
+	enable_kernel_spe();
+#endif
+}
+
+void restore_processor_state(void)
+{
+#ifdef CONFIG_PPC32
+	set_context(current->active_mm->context.id, current->active_mm->pgd);
+#endif
+}

linux-2.6-powermac-generic-suspend-3.patch:

--- NEW FILE linux-2.6-powermac-generic-suspend-3.patch ---
Subject: [PATCH] powermac: disallow pmu sleep notifiers from aborting sleep

Tracing through the code, no current PMU sleep notifier can abort sleep.
Since no new PMU sleep notifiers should be added, this patch simplifies the
code and removes the ability to abort sleep.

Signed-off-by: Johannes Berg <johannes at sipsolutions.net>
Cc: Benjamin Herrenschmidt <benh at kernel.crashing.org>

---
I did this mostly because it gets rid of code we don't need (any more)

---
 drivers/macintosh/adb.c             |   42 +++++++-----------------------------
 drivers/macintosh/apm_emu.c         |   13 +++--------
 drivers/macintosh/via-pmu-led.c     |    4 ---
 drivers/macintosh/via-pmu.c         |   36 +++++-------------------------
 include/linux/pmu.h                 |   12 +---------
 sound/oss/dmasound/dmasound_awacs.c |    5 +---
 6 files changed, 24 insertions(+), 88 deletions(-)

--- wireless-dev.orig/drivers/macintosh/adb.c	2007-04-05 14:50:53.858552246 +0200
+++ wireless-dev/drivers/macintosh/adb.c	2007-04-05 17:55:25.478549941 +0200
@@ -90,7 +90,7 @@ static int autopoll_devs;
 int __adb_probe_sync;
 
 #ifdef CONFIG_PM
-static int adb_notify_sleep(struct pmu_sleep_notifier *self, int when);
+static void adb_notify_sleep(struct pmu_sleep_notifier *self, int when);
 static struct pmu_sleep_notifier adb_sleep_notifier = {
 	adb_notify_sleep,
 	SLEEP_LEVEL_ADB,
@@ -340,11 +340,9 @@ __initcall(adb_init);
 /*
  * notify clients before sleep and reset bus afterwards
  */
-int
+void
 adb_notify_sleep(struct pmu_sleep_notifier *self, int when)
 {
-	int ret;
-	
 	switch (when) {
 	case PBOOK_SLEEP_REQUEST:
 		adb_got_sleep = 1;
@@ -353,22 +351,8 @@ adb_notify_sleep(struct pmu_sleep_notifi
 		/* Stop autopoll */
 		if (adb_controller->autopoll)
 			adb_controller->autopoll(0);
-		ret = blocking_notifier_call_chain(&adb_client_list,
-				ADB_MSG_POWERDOWN, NULL);
-		if (ret & NOTIFY_STOP_MASK) {
-			up(&adb_probe_mutex);
-			return PBOOK_SLEEP_REFUSE;
-		}
-		break;
-	case PBOOK_SLEEP_REJECT:
-		if (adb_got_sleep) {
-			adb_got_sleep = 0;
-			up(&adb_probe_mutex);
-			adb_reset_bus();
-		}
-		break;
-		
-	case PBOOK_SLEEP_NOW:
+		blocking_notifier_call_chain(&adb_client_list,
+			ADB_MSG_POWERDOWN, NULL);
 		break;
 	case PBOOK_WAKE:
 		adb_got_sleep = 0;
@@ -376,14 +360,13 @@ adb_notify_sleep(struct pmu_sleep_notifi
 		adb_reset_bus();
 		break;
 	}
-	return PBOOK_SLEEP_OK;
 }
 #endif /* CONFIG_PM */
 
 static int
 do_adb_reset_bus(void)
 {
-	int ret, nret;
+	int ret;
 	
 	if (adb_controller == NULL)
 		return -ENXIO;
@@ -391,13 +374,8 @@ do_adb_reset_bus(void)
 	if (adb_controller->autopoll)
 		adb_controller->autopoll(0);
 
-	nret = blocking_notifier_call_chain(&adb_client_list,
-			ADB_MSG_PRE_RESET, NULL);
-	if (nret & NOTIFY_STOP_MASK) {
-		if (adb_controller->autopoll)
-			adb_controller->autopoll(autopoll_devs);
-		return -EBUSY;
-	}
+	blocking_notifier_call_chain(&adb_client_list,
+		ADB_MSG_PRE_RESET, NULL);
 
 	if (sleepy_trackpad) {
 		/* Let the trackpad settle down */
@@ -427,10 +405,8 @@ do_adb_reset_bus(void)
 	}
 	up(&adb_handler_sem);
 
-	nret = blocking_notifier_call_chain(&adb_client_list,
-			ADB_MSG_POST_RESET, NULL);
-	if (nret & NOTIFY_STOP_MASK)
-		return -EBUSY;
+	blocking_notifier_call_chain(&adb_client_list,
+		ADB_MSG_POST_RESET, NULL);
 	
 	return ret;
 }
--- wireless-dev.orig/drivers/macintosh/via-pmu.c	2007-04-05 14:50:53.938552246 +0200
+++ wireless-dev/drivers/macintosh/via-pmu.c	2007-04-05 18:14:00.208549941 +0200
@@ -1769,35 +1769,21 @@ EXPORT_SYMBOL(pmu_unregister_sleep_notif
 #if defined(CONFIG_PM) && defined(CONFIG_PPC32)
 
 /* Sleep is broadcast last-to-first */
-static int
-broadcast_sleep(int when, int fallback)
+static void broadcast_sleep(int when)
 {
-	int ret = PBOOK_SLEEP_OK;
 	struct list_head *list;
 	struct pmu_sleep_notifier *notifier;
 
 	for (list = sleep_notifiers.prev; list != &sleep_notifiers;
 	     list = list->prev) {
 		notifier = list_entry(list, struct pmu_sleep_notifier, list);
-		ret = notifier->notifier_call(notifier, when);
-		if (ret != PBOOK_SLEEP_OK) {
-			printk(KERN_DEBUG "sleep %d rejected by %p (%p)\n",
-			       when, notifier, notifier->notifier_call);
-			for (; list != &sleep_notifiers; list = list->next) {
-				notifier = list_entry(list, struct pmu_sleep_notifier, list);
-				notifier->notifier_call(notifier, fallback);
-			}
-			return ret;
-		}
+		notifier->notifier_call(notifier, when);
 	}
-	return ret;
 }
 
 /* Wake is broadcast first-to-last */
-static int
-broadcast_wake(void)
+static void broadcast_wake(void)
 {
-	int ret = PBOOK_SLEEP_OK;
 	struct list_head *list;
 	struct pmu_sleep_notifier *notifier;
 
@@ -1806,7 +1792,6 @@ broadcast_wake(void)
 		notifier = list_entry(list, struct pmu_sleep_notifier, list);
 		notifier->notifier_call(notifier, PBOOK_WAKE);
 	}
-	return ret;
 }
 
 /*
@@ -2013,12 +1998,8 @@ pmac_suspend_devices(void)
 
 	pm_prepare_console();
 	
-	/* Notify old-style device drivers & userland */
-	ret = broadcast_sleep(PBOOK_SLEEP_REQUEST, PBOOK_SLEEP_REJECT);
-	if (ret != PBOOK_SLEEP_OK) {
-		printk(KERN_ERR "Sleep rejected by drivers\n");
-		return -EBUSY;
-	}
+	/* Notify old-style device drivers */
+	broadcast_sleep(PBOOK_SLEEP_REQUEST);
 
 	/* Sync the disks. */
 	/* XXX It would be nice to have some way to ensure that
@@ -2028,12 +2009,7 @@ pmac_suspend_devices(void)
 	 */
 	sys_sync();
 
-	/* Sleep can fail now. May not be very robust but useful for debugging */
-	ret = broadcast_sleep(PBOOK_SLEEP_NOW, PBOOK_WAKE);
-	if (ret != PBOOK_SLEEP_OK) {
-		printk(KERN_ERR "Driver sleep failed\n");
-		return -EBUSY;
-	}
+	broadcast_sleep(PBOOK_SLEEP_NOW);
 
 	/* Send suspend call to devices, hold the device core's dpm_sem */
 	ret = device_suspend(PMSG_SUSPEND);
--- wireless-dev.orig/include/linux/pmu.h	2007-04-05 14:50:54.048552246 +0200
+++ wireless-dev/include/linux/pmu.h	2007-04-05 17:55:25.488549941 +0200
@@ -168,24 +168,16 @@ extern int pmu_get_model(void);
 
 struct pmu_sleep_notifier
 {
-	int (*notifier_call)(struct pmu_sleep_notifier *self, int when);
+	void (*notifier_call)(struct pmu_sleep_notifier *self, int when);
 	int priority;
 	struct list_head list;
 };
 
 /* Code values for calling sleep/wakeup handlers
- *
- * Note: If a sleep request got cancelled, all drivers will get
- * the PBOOK_SLEEP_REJECT, even those who didn't get the PBOOK_SLEEP_REQUEST.
  */
 #define PBOOK_SLEEP_REQUEST	1
 #define PBOOK_SLEEP_NOW		2
-#define PBOOK_SLEEP_REJECT	3
-#define PBOOK_WAKE		4
-
-/* Result codes returned by the notifiers */
-#define PBOOK_SLEEP_OK		0
-#define PBOOK_SLEEP_REFUSE	-1
+#define PBOOK_WAKE		3
 
 /* priority levels in notifiers */
 #define SLEEP_LEVEL_VIDEO	100	/* Video driver (first wake) */
--- wireless-dev.orig/drivers/macintosh/via-pmu-led.c	2007-04-05 14:50:53.948552246 +0200
+++ wireless-dev/drivers/macintosh/via-pmu-led.c	2007-04-05 17:55:25.488549941 +0200
@@ -81,7 +81,7 @@ static struct led_classdev pmu_led = {
 };
 
 #ifdef CONFIG_PM
-static int pmu_led_sleep_call(struct pmu_sleep_notifier *self, int when)
+static void pmu_led_sleep_call(struct pmu_sleep_notifier *self, int when)
 {
 	unsigned long flags;
 
@@ -99,8 +99,6 @@ static int pmu_led_sleep_call(struct pmu
 		break;
 	}
 	spin_unlock_irqrestore(&pmu_blink_lock, flags);
-
-	return PBOOK_SLEEP_OK;
 }
 
 static struct pmu_sleep_notifier via_pmu_led_sleep_notif = {
--- wireless-dev.orig/drivers/macintosh/apm_emu.c	2007-04-05 14:50:54.028552246 +0200
+++ wireless-dev/drivers/macintosh/apm_emu.c	2007-04-05 17:55:25.498549941 +0200
@@ -96,7 +96,7 @@ static DECLARE_WAIT_QUEUE_HEAD(apm_waitq
 static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue);
 static struct apm_user *	user_list;
 
-static int apm_notify_sleep(struct pmu_sleep_notifier *self, int when);
+static void apm_notify_sleep(struct pmu_sleep_notifier *self, int when);
 static struct pmu_sleep_notifier apm_sleep_notifier = {
 	apm_notify_sleep,
 	SLEEP_LEVEL_USERLAND,
@@ -352,7 +352,7 @@ static int do_open(struct inode * inode,
  * doesn't provide a way to NAK, but this could be added
  * here.
  */
-static int wait_all_suspend(void)
+static void wait_all_suspend(void)
 {
 	DECLARE_WAITQUEUE(wait, current);
 
@@ -366,24 +366,19 @@ static int wait_all_suspend(void)
 	remove_wait_queue(&apm_suspend_waitqueue, &wait);
 
 	DBG("apm_emu: wait_all_suspend() - complete !\n");
-	
-	return 1;
 }
 
-static int apm_notify_sleep(struct pmu_sleep_notifier *self, int when)
+static void apm_notify_sleep(struct pmu_sleep_notifier *self, int when)
 {
 	switch(when) {
 		case PBOOK_SLEEP_REQUEST:
 			queue_event(APM_SYS_SUSPEND, NULL);
-			if (!wait_all_suspend())
-				return PBOOK_SLEEP_REFUSE;
+			wait_all_suspend();
 			break;
-		case PBOOK_SLEEP_REJECT:
 		case PBOOK_WAKE:
 			queue_event(APM_NORMAL_RESUME, NULL);
 			break;
 	}
-	return PBOOK_SLEEP_OK;
 }
 
 #define APM_CRITICAL		10
--- wireless-dev.orig/sound/oss/dmasound/dmasound_awacs.c	2007-04-05 14:50:54.138552246 +0200
+++ wireless-dev/sound/oss/dmasound/dmasound_awacs.c	2007-04-05 17:55:25.498549941 +0200
@@ -257,7 +257,7 @@ static volatile struct dbdma_cmd *emerge
 /*
  * Stuff for restoring after a sleep.
  */
-static int awacs_sleep_notify(struct pmu_sleep_notifier *self, int when);
+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,
 };
@@ -1419,7 +1419,7 @@ load_awacs(void)
  * Save state when going to sleep, restore it afterwards.
  */
 /* FIXME: sort out disabling/re-enabling of read stuff as well */
-static int awacs_sleep_notify(struct pmu_sleep_notifier *self, int when)
+static void awacs_sleep_notify(struct pmu_sleep_notifier *self, int when)
 {
 	unsigned long flags;
 
@@ -1548,7 +1548,6 @@ static int awacs_sleep_notify(struct pmu
 		spin_unlock_irqrestore(&dmasound.lock, flags);
 		UNLOCK();
 	}
-	return PBOOK_SLEEP_OK;
 }
 #endif /* CONFIG_PM */
 

linux-2.6-powermac-generic-suspend-4.patch:

--- NEW FILE linux-2.6-powermac-generic-suspend-4.patch ---
Subject: [PATCH] powermac: proper sleep management

After having removed the power management ops from powermac completely, this
patch adds them back for PMU based machines, directly in the PMU driver.
This finally allows suspending via /sys/power/state on powerbooks.

The patch also replaces the PMU ioctl with a simple call to
pm_suspend(PM_SUSPEND_MEM) and puts the sleep-related PMU ioctls onto the
feature-removal schedule.

Signed-off-by: Johannes Berg <johannes at sipsolutions.net>
Cc: Benjamin Herrenschmidt <benh at kernel.crashing.org>

---
Could use some testing on older powerbooks just to see if they get problems
with the slight reordering of the suspend/resume sequence. I doubt it though.

And before someone asks:
Yes, it is safe to remove the backlight ioctl restrictions
because the generic layer actually freezes processes before STR.

This updated version removes the sys_sync() call that can't be done with
processes frozen.

---
 Documentation/feature-removal-schedule.txt |   10 
 drivers/macintosh/via-pmu.c                |  319 ++++++++++++-----------------
 2 files changed, 149 insertions(+), 180 deletions(-)

--- wireless-dev.orig/drivers/macintosh/via-pmu.c	2007-04-05 17:55:25.488549941 +0200
+++ wireless-dev/drivers/macintosh/via-pmu.c	2007-04-05 18:02:27.368549941 +0200
@@ -155,9 +155,6 @@ static int drop_interrupts;
 #if defined(CONFIG_PM) && defined(CONFIG_PPC32)
 static int option_lid_wakeup = 1;
 #endif /* CONFIG_PM && CONFIG_PPC32 */
-#if (defined(CONFIG_PM)&&defined(CONFIG_PPC32))||defined(CONFIG_PMAC_BACKLIGHT_LEGACY)
-static int sleep_in_progress;
-#endif
 static unsigned long async_req_locks;
 static unsigned int pmu_irq_stats[11];
 
@@ -1991,132 +1988,6 @@ restore_via_state(void)
 
 extern void pmu_backlight_set_sleep(int sleep);
 
-static int
-pmac_suspend_devices(void)
-{
-	int ret;
-
-	pm_prepare_console();
-	
-	/* Notify old-style device drivers */
-	broadcast_sleep(PBOOK_SLEEP_REQUEST);
-
-	/* Sync the disks. */
-	/* XXX It would be nice to have some way to ensure that
-	 * nobody is dirtying any new buffers while we wait. That
-	 * could be achieved using the refrigerator for processes
-	 * that swsusp uses
-	 */
-	sys_sync();
-
-	broadcast_sleep(PBOOK_SLEEP_NOW);
-
-	/* Send suspend call to devices, hold the device core's dpm_sem */
-	ret = device_suspend(PMSG_SUSPEND);
-	if (ret) {
-		broadcast_wake();
-		printk(KERN_ERR "Driver sleep failed\n");
-		return -EBUSY;
-	}
-
-#ifdef CONFIG_PMAC_BACKLIGHT
-	/* Tell backlight code not to muck around with the chip anymore */
-	pmu_backlight_set_sleep(1);
-#endif
-
-	/* Call platform functions marked "on sleep" */
-	pmac_pfunc_i2c_suspend();
-	pmac_pfunc_base_suspend();
-
-	/* Stop preemption */
-	preempt_disable();
-
-	/* Make sure the decrementer won't interrupt us */
-	asm volatile("mtdec %0" : : "r" (0x7fffffff));
-	/* Make sure any pending DEC interrupt occurring while we did
-	 * the above didn't re-enable the DEC */
-	mb();
-	asm volatile("mtdec %0" : : "r" (0x7fffffff));
-
-	/* We can now disable MSR_EE. This code of course works properly only
-	 * on UP machines... For SMP, if we ever implement sleep, we'll have to
-	 * stop the "other" CPUs way before we do all that stuff.
-	 */
-	local_irq_disable();
-
-	/* Broadcast power down irq
-	 * This isn't that useful in most cases (only directly wired devices can
-	 * use this but still... This will take care of sysdev's as well, so
-	 * we exit from here with local irqs disabled and PIC off.
-	 */
-	ret = device_power_down(PMSG_SUSPEND);
-	if (ret) {
-		wakeup_decrementer();
-		local_irq_enable();
-		preempt_enable();
-		device_resume();
-		broadcast_wake();
-		printk(KERN_ERR "Driver powerdown failed\n");
-		return -EBUSY;
-	}
-
-	/* Wait for completion of async requests */
-	while (!batt_req.complete)
-		pmu_poll();
-
-	/* Giveup the lazy FPU & vec so we don't have to back them
-	 * up from the low level code
-	 */
-	enable_kernel_fp();
-
-#ifdef CONFIG_ALTIVEC
-	if (cpu_has_feature(CPU_FTR_ALTIVEC))
-		enable_kernel_altivec();
-#endif /* CONFIG_ALTIVEC */
-
-	return 0;
-}
-
-static int
-pmac_wakeup_devices(void)
-{
-	mdelay(100);
-
-#ifdef CONFIG_PMAC_BACKLIGHT
-	/* Tell backlight code it can use the chip again */
-	pmu_backlight_set_sleep(0);
-#endif
-
-	/* Power back up system devices (including the PIC) */
-	device_power_up();
-
-	/* Force a poll of ADB interrupts */
-	adb_int_pending = 1;
-	via_pmu_interrupt(0, NULL);
-
-	/* Restart jiffies & scheduling */
-	wakeup_decrementer();
-
-	/* Re-enable local CPU interrupts */
-	local_irq_enable();
-	mdelay(10);
-	preempt_enable();
-
-	/* Call platform functions marked "on wake" */
-	pmac_pfunc_base_resume();
-	pmac_pfunc_i2c_resume();
-
-	/* Resume devices */
-	device_resume();
-
-	/* Notify old style drivers */
-	broadcast_wake();
-
-	pm_restore_console();
-
-	return 0;
-}
-
 #define	GRACKLE_PM	(1<<7)
 #define GRACKLE_DOZE	(1<<5)
 #define	GRACKLE_NAP	(1<<4)
@@ -2127,19 +1998,12 @@ static int powerbook_sleep_grackle(void)
 	unsigned long save_l2cr;
 	unsigned short pmcr1;
 	struct adb_request req;
-	int ret;
 	struct pci_dev *grackle;
 
 	grackle = pci_find_slot(0, 0);
 	if (!grackle)
 		return -ENODEV;
 
-	ret = pmac_suspend_devices();
-	if (ret) {
-		printk(KERN_ERR "Sleep rejected by devices\n");
-		return ret;
-	}
-	
 	/* Turn off various things. Darwin does some retry tests here... */
 	pmu_request(&req, NULL, 2, PMU_POWER_CTRL0, PMU_POW0_OFF|PMU_POW0_HARD_DRIVE);
 	pmu_wait_complete(&req);
@@ -2200,8 +2064,6 @@ static int powerbook_sleep_grackle(void)
 			PMU_POW_ON|PMU_POW_BACKLIGHT|PMU_POW_CHARGER|PMU_POW_IRLED|PMU_POW_MEDIABAY);
 	pmu_wait_complete(&req);
 
-	pmac_wakeup_devices();
-
 	return 0;
 }
 
@@ -2211,7 +2073,6 @@ powerbook_sleep_Core99(void)
 	unsigned long save_l2cr;
 	unsigned long save_l3cr;
 	struct adb_request req;
-	int ret;
 	
 	if (pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) < 0) {
 		printk(KERN_ERR "Sleep mode not supported on this machine\n");
@@ -2221,12 +2082,6 @@ powerbook_sleep_Core99(void)
 	if (num_online_cpus() > 1 || cpu_is_offline(0))
 		return -EAGAIN;
 
-	ret = pmac_suspend_devices();
-	if (ret) {
-		printk(KERN_ERR "Sleep rejected by devices\n");
-		return ret;
-	}
-
 	/* Stop environment and ADB interrupts */
 	pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, 0);
 	pmu_wait_complete(&req);
@@ -2297,8 +2152,6 @@ powerbook_sleep_Core99(void)
 	/* Restore LPJ, cpufreq will adjust the cpu frequency */
 	loops_per_jiffy /= 2;
 
-	pmac_wakeup_devices();
-
 	return 0;
 }
 
@@ -2308,7 +2161,7 @@ powerbook_sleep_Core99(void)
 static int
 powerbook_sleep_3400(void)
 {
-	int ret, i, x;
+	int i, x;
 	unsigned int hid0;
 	unsigned long p;
 	struct adb_request sleep_req;
@@ -2326,13 +2179,6 @@ powerbook_sleep_3400(void)
 	/* Allocate room for PCI save */
 	pbook_alloc_pci_save();
 
-	ret = pmac_suspend_devices();
-	if (ret) {
-		pbook_free_pci_save();
-		printk(KERN_ERR "Sleep rejected by devices\n");
-		return ret;
-	}
-
 	/* Save the state of PCI config space for some slots */
 	pbook_pci_save();
 
@@ -2376,7 +2222,6 @@ powerbook_sleep_3400(void)
 	while (asleep)
 		mb();
 
-	pmac_wakeup_devices();
 	pbook_free_pci_save();
 	iounmap(mem_ctrl);
 
@@ -2558,6 +2403,136 @@ pmu_release(struct inode *inode, struct 
 	return 0;
 }
 
+#if defined(CONFIG_PM) && defined(CONFIG_PPC32)
+static int powerbook_prepare_sleep(suspend_state_t state)
+{
+	/* Notify old-style device drivers */
+	broadcast_sleep(PBOOK_SLEEP_REQUEST);
+	broadcast_sleep(PBOOK_SLEEP_NOW);
+
+	return 0;
+}
+
+static void powerbook_irq_off(suspend_state_t state)
+{
+#ifdef CONFIG_PMAC_BACKLIGHT
+	/* Tell backlight code not to muck around with the chip anymore */
+	pmu_backlight_set_sleep(1);
+#endif
+
+	/* Call platform functions marked "on sleep" */
+	pmac_pfunc_i2c_suspend();
+	pmac_pfunc_base_suspend();
+
+	preempt_disable();
+
+	asm volatile("mtdec %0" : : "r" (0x7fffffff));
+	/* Make sure any pending DEC interrupt occurring while we did
+	 * the above didn't re-enable the DEC */
+	mb();
+	asm volatile("mtdec %0" : : "r" (0x7fffffff));
+
+	local_irq_disable();
+}
+
+static int powerbook_sleep(suspend_state_t state)
+{
+	int error = 0;
+
+	/* Wait for completion of async requests */
+	while (!batt_req.complete)
+		pmu_poll();
+
+	/* Giveup the lazy FPU & vec so we don't have to back them
+	 * up from the low level code
+	 */
+	enable_kernel_fp();
+
+#ifdef CONFIG_ALTIVEC
+	if (cpu_has_feature(CPU_FTR_ALTIVEC))
+		enable_kernel_altivec();
+#endif /* CONFIG_ALTIVEC */
+
+	switch (pmu_kind) {
+	case PMU_OHARE_BASED:
+		error = powerbook_sleep_3400();
+		break;
+	case PMU_HEATHROW_BASED:
+	case PMU_PADDINGTON_BASED:
+		error = powerbook_sleep_grackle();
+		break;
+	case PMU_KEYLARGO_BASED:
+		error = powerbook_sleep_Core99();
+		break;
+	default:
+		return -ENOSYS;
+	}
+
+	if (error)
+		return error;
+
+	mdelay(100);
+
+#ifdef CONFIG_PMAC_BACKLIGHT
+	/* Tell backlight code it can use the chip again */
+	pmu_backlight_set_sleep(0);
+#endif
+
+	return 0;
+}
+
+static void powerbook_irq_on(suspend_state_t state)
+{
+	/* Force a poll of ADB interrupts */
+	adb_int_pending = 1;
+	via_pmu_interrupt(0, NULL);
+
+	/* Restart jiffies & scheduling */
+	wakeup_decrementer();
+
+	/* Re-enable local CPU interrupts */
+	local_irq_enable();
+	mdelay(10);
+	preempt_enable();
+
+	/* Call platform functions marked "on wake" */
+	pmac_pfunc_base_resume();
+	pmac_pfunc_i2c_resume();
+}
+
+static int powerbook_finish_sleep(suspend_state_t state)
+{
+	/* Notify old style drivers */
+	broadcast_wake();
+
+	return 0;
+}
+
+static int pmu_sleep_valid(suspend_state_t state)
+{
+	return state == PM_SUSPEND_MEM
+		&& (pmac_call_feature(PMAC_FTR_SLEEP_STATE, NULL, 0, -1) >= 0);
+}
+
+static struct pm_ops pmu_pm_ops = {
+	.prepare = powerbook_prepare_sleep,
+	.irq_off = powerbook_irq_off,
+	.enter = powerbook_sleep,
+	.irq_on = powerbook_irq_on,
+	.finish = powerbook_finish_sleep,
+	.valid = pmu_sleep_valid,
+};
+
+static int register_pmu_pm_ops(void)
+{
+	pm_set_ops(&pmu_pm_ops);
+
+	return 0;
+}
+
+device_initcall(register_pmu_pm_ops);
+#endif
+
 static int
 pmu_ioctl(struct inode * inode, struct file *filp,
 		     u_int cmd, u_long arg)
@@ -2567,29 +2542,19 @@ pmu_ioctl(struct inode * inode, struct f
 
 	switch (cmd) {
 #if defined(CONFIG_PM) && defined(CONFIG_PPC32)
+	/* just provided for compatibility */
 	case PMU_IOC_SLEEP:
 		if (!capable(CAP_SYS_ADMIN))
 			return -EACCES;
-		if (sleep_in_progress)
-			return -EBUSY;
-		sleep_in_progress = 1;
-		switch (pmu_kind) {
-		case PMU_OHARE_BASED:
-			error = powerbook_sleep_3400();
-			break;
-		case PMU_HEATHROW_BASED:
-		case PMU_PADDINGTON_BASED:
-			error = powerbook_sleep_grackle();
-			break;
-		case PMU_KEYLARGO_BASED:
-			error = powerbook_sleep_Core99();
-			break;
-		default:
-			error = -ENOSYS;
-		}
-		sleep_in_progress = 0;
+		printk(KERN_INFO "via-pmu: the PMU_IOC_SLEEP ioctl is deprecated.\n");
+		printk(KERN_INFO "via-pmu: use \"echo mem > /sys/power/state\" instead!\n");
+		printk(KERN_INFO "via-pmu: this ioctl will be removed soon.\n");
+		error = pm_suspend(PM_SUSPEND_MEM);
 		break;
 	case PMU_IOC_CAN_SLEEP:
+		printk(KERN_INFO "via-pmu: the PMU_IOC_CAN_SLEEP ioctl is deprecated.\n");
+		printk(KERN_INFO "via-pmu: use \"grep mem /sys/power/state\" instead!\n");
+		printk(KERN_INFO "via-pmu: this ioctl will be removed soon.\n");
 		if (pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) < 0)
 			return put_user(0, argp);
 		else
@@ -2602,9 +2567,6 @@ pmu_ioctl(struct inode * inode, struct f
 	{
 		int brightness;
 
-		if (sleep_in_progress)
-			return -EBUSY;
-
 		brightness = pmac_backlight_get_legacy_brightness();
 		if (brightness < 0)
 			return brightness;
@@ -2616,9 +2578,6 @@ pmu_ioctl(struct inode * inode, struct f
 	{
 		int brightness;
 
-		if (sleep_in_progress)
-			return -EBUSY;
-
 		error = get_user(brightness, argp);
 		if (error)
 			return error;
--- wireless-dev.orig/Documentation/feature-removal-schedule.txt	2007-04-05 14:50:53.608552246 +0200
+++ wireless-dev/Documentation/feature-removal-schedule.txt	2007-04-05 17:55:25.558549941 +0200
@@ -312,3 +312,13 @@ Why:	the i8xx_tco watchdog driver has be
 Who:	Wim Van Sebroeck <wim at iguana.be>
 
 ---------------------------
+
+What:	/dev/pmu suspend/can-suspend ioctls
+When:	2.6.24
+Files:	drivers/macintosh/via-pmu.c
+Why:	powermac supports proper generic pm_ops now and can suspend with
+	"echo mem > /sys/power/state" instead of the ioctl, checking if
+	it can suspend can be done by reading /sys/power/state.
+Who:	Johannes Berg <johannes at sipsolutions.net>
+
+---------------------------

linux-2.6-powerpc-generic-suspend-2-remove-adb-sleep-notifier.patch:

--- NEW FILE linux-2.6-powerpc-generic-suspend-2-remove-adb-sleep-notifier.patch ---
Subject: adb: replace sleep notifier with platform driver suspend/resume hooks

This patch replaces the pmu sleep notifier that adb had with
suspend/resume hooks in a new platform driver/device.

Signed-off-by: Johannes Berg <johannes at sipsolutions.net>
Cc: Benjamin Herrenschmidt <benh at kernel.crashing.org>

---
Yes, it's more a hack. But the whole code is such a mess that I could
work for days fixing it. Don't feel like doing that right now.

 drivers/macintosh/adb.c |   96 ++++++++++++++++++++++++++++--------------------
 1 file changed, 57 insertions(+), 39 deletions(-)

--- wireless-dev.orig/drivers/macintosh/adb.c	2007-07-18 14:25:25.202900849 +0200
+++ wireless-dev/drivers/macintosh/adb.c	2007-07-18 14:25:39.252900849 +0200
@@ -89,14 +89,6 @@ static int sleepy_trackpad;
 static int autopoll_devs;
 int __adb_probe_sync;
 
-#ifdef CONFIG_PM_SLEEP
-static void adb_notify_sleep(struct pmu_sleep_notifier *self, int when);
-static struct pmu_sleep_notifier adb_sleep_notifier = {
-	adb_notify_sleep,
-	SLEEP_LEVEL_ADB,
-};
-#endif
-
 static int adb_scan_bus(void);
 static int do_adb_reset_bus(void);
 static void adbdev_init(void);
@@ -281,6 +273,36 @@ adb_reset_bus(void)
 	return 0;
 }
 
+#ifdef CONFIG_PM
+/*
+ * notify clients before sleep
+ */
+static int adb_suspend(struct platform_device *dev, pm_message_t state)
+{
+	adb_got_sleep = 1;
+	/* We need to get a lock on the probe thread */
+	down(&adb_probe_mutex);
+	/* Stop autopoll */
+	if (adb_controller->autopoll)
+		adb_controller->autopoll(0);
+	blocking_notifier_call_chain(&adb_client_list, ADB_MSG_POWERDOWN, NULL);
+
+	return 0;
+}
+
+/*
+ * reset bus after sleep
+ */
+static int adb_resume(struct platform_device *dev)
+{
+	adb_got_sleep = 0;
+	up(&adb_probe_mutex);
+	adb_reset_bus();
+
+	return 0;
+}
+#endif /* CONFIG_PM */
+
 int __init adb_init(void)
 {
 	struct adb_driver *driver;
@@ -335,9 +335,6 @@ int __init adb_init(void)
 		printk(KERN_WARNING "Warning: no ADB interface detected\n");
 		adb_controller = NULL;
 	} else {
-#ifdef CONFIG_PM_SLEEP
-		pmu_register_sleep_notifier(&adb_sleep_notifier);
-#endif /* CONFIG_PM */
 #ifdef CONFIG_PPC
 		if (machine_is_compatible("AAPL,PowerBook1998") ||
 			machine_is_compatible("PowerBook1,1"))
@@ -330,33 +350,6 @@ int __init adb_init(void)
 
 __initcall(adb_init);
 
-#ifdef CONFIG_PM
-/*
- * notify clients before sleep and reset bus afterwards
- */
-void
-adb_notify_sleep(struct pmu_sleep_notifier *self, int when)
-{
-	switch (when) {
-	case PBOOK_SLEEP_REQUEST:
-		adb_got_sleep = 1;
-		/* We need to get a lock on the probe thread */
-		down(&adb_probe_mutex);
-		/* Stop autopoll */
-		if (adb_controller->autopoll)
-			adb_controller->autopoll(0);
-		blocking_notifier_call_chain(&adb_client_list,
-			ADB_MSG_POWERDOWN, NULL);
-		break;
-	case PBOOK_WAKE:
-		adb_got_sleep = 0;
-		up(&adb_probe_mutex);
-		adb_reset_bus();
-		break;
-	}
-}
-#endif /* CONFIG_PM */
-
 static int
 do_adb_reset_bus(void)
 {
@@ -864,7 +857,29 @@ static const struct file_operations adb_
 	.release	= adb_release,
 };
 
-static void
+static struct platform_driver adb_pfdrv = {
+	.driver = {
+		.name = "adb",
+	},
+#ifdef CONFIG_PM
+	.suspend = adb_suspend,
+	.resume = adb_resume,
+#endif
+};
+
+static struct platform_device adb_pfdev = {
+	.name = "adb",
+};
+
+static int __init
+adb_dummy_probe(struct platform_device *dev)
+{
+	if (dev == &adb_pfdev)
+		return 0;
+	return -ENODEV;
+}
+
+static void __init
 adbdev_init(void)
 {
 	if (register_chrdev(ADB_MAJOR, "adb", &adb_fops)) {
@@ -876,4 +891,7 @@ adbdev_init(void)
 	if (IS_ERR(adb_dev_class))
 		return;
 	class_device_create(adb_dev_class, NULL, MKDEV(ADB_MAJOR, 0), NULL, "adb");
+
+	platform_device_register(&adb_pfdev);
+	platform_driver_probe(&adb_pfdrv, adb_dummy_probe);
 }

linux-2.6-powerpc-generic-suspend-3-remove-dmasound.patch:

--- NEW FILE linux-2.6-powerpc-generic-suspend-3-remove-dmasound.patch ---
Subject: remove awacs dmasound

This patch kills the obsolete awacs dmasound because it is in
the way of doing power management improvements since it uses
ancient API.

Signed-off-by: Johannes Berg <johannes at sipsolutions.net>
Cc: Benjamin Herrenschmidt <benh at kernel.crashing.org>
Cc: Adrian Bunk <bunk at stusta.de>

---
 sound/oss/dmasound/Makefile          |    6 
 sound/oss/dmasound/awacs_defs.h      |  251 --
 sound/oss/dmasound/dac3550a.c        |  209 --
 sound/oss/dmasound/dmasound_awacs.c  | 3215 -----------------------------------
 sound/oss/dmasound/tas3001c.c        |  849 ---------
 sound/oss/dmasound/tas3001c.h        |   64 
 sound/oss/dmasound/tas3001c_tables.c |  375 ----
 sound/oss/dmasound/tas3004.c         | 1138 ------------
 sound/oss/dmasound/tas3004.h         |   77 
 sound/oss/dmasound/tas3004_tables.c  |  301 ---
 sound/oss/dmasound/tas_common.c      |  214 --
 sound/oss/dmasound/tas_common.h      |  284 ---
 sound/oss/dmasound/tas_eq_prefs.h    |   24 
 sound/oss/dmasound/tas_ioctl.h       |   23 
 sound/oss/dmasound/trans_16.c        |  898 ---------
 15 files changed, 7928 deletions(-)

--- wireless-dev.orig/sound/oss/dmasound/Makefile	2007-07-18 14:25:24.662900849 +0200
+++ wireless-dev/sound/oss/dmasound/Makefile	2007-07-18 14:25:39.812900849 +0200
@@ -2,12 +2,6 @@
 # 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
--- wireless-dev.orig/sound/oss/dmasound/awacs_defs.h	2007-07-18 14:25:24.722900849 +0200
+++ /dev/null	1970-01-01 00:00:00.000000000 +0000
@@ -1,251 +0,0 @@
-/*********************************************************/
-/* 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 */
[...7608 lines suppressed...]
-	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,
-};

linux-2.6-powerpc-generic-suspend-4-kill-pmu-sleep-notifier.patch:

--- NEW FILE linux-2.6-powerpc-generic-suspend-4-kill-pmu-sleep-notifier.patch ---
Subject: via-pmu: kill sleep notifiers completely

This patch kills off the remnants of the ancient sleep notifiers.

Signed-off-by: Johannes Berg <johannes at sipsolutions.net>
Cc: Benjamin Herrenschmidt <benh at kernel.crashing.org>

---
 drivers/macintosh/via-pmu.c |   71 --------------------------------------------
 include/linux/pmu.h         |   36 ----------------------
 2 files changed, 107 deletions(-)

--- wireless-dev.orig/drivers/macintosh/via-pmu.c	2007-07-18 14:25:24.522900849 +0200
+++ wireless-dev/drivers/macintosh/via-pmu.c	2007-07-18 14:25:40.812900849 +0200
@@ -177,7 +177,6 @@ static struct proc_dir_entry *proc_pmu_b
 
 int __fake_sleep;
 int asleep;
-BLOCKING_NOTIFIER_HEAD(sleep_notifier_list);
 
 #ifdef CONFIG_ADB
 static int adb_dev_map;
@@ -1737,67 +1737,8 @@ pmu_present(void)
 	return via != 0;
 }
 
-#ifdef CONFIG_PM_SLEEP
-
-static LIST_HEAD(sleep_notifiers);
-
-int
-pmu_register_sleep_notifier(struct pmu_sleep_notifier *n)
-{
-	struct list_head *list;
-	struct pmu_sleep_notifier *notifier;
-
-	for (list = sleep_notifiers.next; list != &sleep_notifiers;
-	     list = list->next) {
-		notifier = list_entry(list, struct pmu_sleep_notifier, list);
-		if (n->priority > notifier->priority)
-			break;
-	}
-	__list_add(&n->list, list->prev, list);
-	return 0;
-}
-EXPORT_SYMBOL(pmu_register_sleep_notifier);
-
-int
-pmu_unregister_sleep_notifier(struct pmu_sleep_notifier* n)
-{
-	if (n->list.next == 0)
-		return -ENOENT;
-	list_del(&n->list);
-	n->list.next = NULL;
-	return 0;
-}
-EXPORT_SYMBOL(pmu_unregister_sleep_notifier);
-#endif /* CONFIG_PM_SLEEP */
-
 #if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32)
 
-/* Sleep is broadcast last-to-first */
-static void broadcast_sleep(int when)
-{
-	struct list_head *list;
-	struct pmu_sleep_notifier *notifier;
-
-	for (list = sleep_notifiers.prev; list != &sleep_notifiers;
-	     list = list->prev) {
-		notifier = list_entry(list, struct pmu_sleep_notifier, list);
-		notifier->notifier_call(notifier, when);
-	}
-}
-
-/* Wake is broadcast first-to-last */
-static void broadcast_wake(void)
-{
-	struct list_head *list;
-	struct pmu_sleep_notifier *notifier;
-
-	for (list = sleep_notifiers.next; list != &sleep_notifiers;
-	     list = list->next) {
-		notifier = list_entry(list, struct pmu_sleep_notifier, list);
-		notifier->notifier_call(notifier, PBOOK_WAKE);
-	}
-}
-
 /*
  * This struct is used to store config register values for
  * PCI devices which may get powered off when we sleep.
@@ -2003,9 +1942,6 @@ pmac_suspend_devices(void)
 
 	pm_prepare_console();
 	
-	/* Notify old-style device drivers */
-	broadcast_sleep(PBOOK_SLEEP_REQUEST);
-
 	/* Sync the disks. */
 	/* XXX It would be nice to have some way to ensure that
 	 * nobody is dirtying any new buffers while we wait. That
@@ -2014,12 +1950,9 @@ pmac_suspend_devices(void)
 	 */
 	sys_sync();
 
-	broadcast_sleep(PBOOK_SLEEP_NOW);
-
 	/* Send suspend call to devices, hold the device core's dpm_sem */
 	ret = device_suspend(PMSG_SUSPEND);
 	if (ret) {
-		broadcast_wake();
 		printk(KERN_ERR "Driver sleep failed\n");
 		return -EBUSY;
 	}
@@ -2060,7 +1993,6 @@ pmac_suspend_devices(void)
 		local_irq_enable();
 		preempt_enable();
 		device_resume();
-		broadcast_wake();
 		printk(KERN_ERR "Driver powerdown failed\n");
 		return -EBUSY;
 	}
@@ -2114,9 +2046,6 @@ pmac_wakeup_devices(void)
 	/* Resume devices */
 	device_resume();
 
-	/* Notify old style drivers */
-	broadcast_wake();
-
 	pm_restore_console();
 
 	return 0;
--- wireless-dev.orig/include/linux/pmu.h	2007-07-18 14:25:24.562900849 +0200
+++ wireless-dev/include/linux/pmu.h	2007-07-18 14:25:40.812900849 +0200
@@ -159,42 +159,6 @@ extern void pmu_unlock(void);
 extern int pmu_present(void);
 extern int pmu_get_model(void);
 
-#ifdef CONFIG_PM
-/*
- * Stuff for putting the powerbook to sleep and waking it again.
- *
- */
-#include <linux/list.h>
-
-struct pmu_sleep_notifier
-{
-	void (*notifier_call)(struct pmu_sleep_notifier *self, int when);
-	int priority;
-	struct list_head list;
-};
-
-/* Code values for calling sleep/wakeup handlers
- */
-#define PBOOK_SLEEP_REQUEST	1
-#define PBOOK_SLEEP_NOW		2
-#define PBOOK_WAKE		3
-
-/* priority levels in notifiers */
-#define SLEEP_LEVEL_VIDEO	100	/* Video driver (first wake) */
-#define SLEEP_LEVEL_MEDIABAY	90	/* Media bay driver */
-#define SLEEP_LEVEL_BLOCK	80	/* IDE, SCSI */
-#define SLEEP_LEVEL_NET		70	/* bmac, gmac */
-#define SLEEP_LEVEL_MISC	60	/* Anything else */
-#define SLEEP_LEVEL_USERLAND	55	/* Reserved for apm_emu */
-#define SLEEP_LEVEL_ADB		50	/* ADB (async) */
-#define SLEEP_LEVEL_SOUND	40	/* Sound driver (blocking) */
-
-/* special register notifier functions */
-int pmu_register_sleep_notifier(struct pmu_sleep_notifier* notifier);
-int pmu_unregister_sleep_notifier(struct pmu_sleep_notifier* notifier);
-
-#endif /* CONFIG_PM */
-
 #define PMU_MAX_BATTERIES	2
 
 /* values for pmu_power_flags */

linux-2.6-powerpc-generic-suspend-5-pmu-pm_ops.patch:

--- NEW FILE linux-2.6-powerpc-generic-suspend-5-pmu-pm_ops.patch ---
Subject: [PATCH] powermac: proper sleep management

After having removed the power management ops from powermac completely, this
patch adds them back for PMU based machines, directly in the PMU driver.
This finally allows suspending via /sys/power/state on powerbooks.

The patch also replaces the PMU ioctl with a simple call to
pm_suspend(PM_SUSPEND_MEM) and puts the sleep-related PMU ioctls onto the
feature-removal schedule.

Signed-off-by: Johannes Berg <johannes at sipsolutions.net>
Cc: Benjamin Herrenschmidt <benh at kernel.crashing.org>

---
 Documentation/feature-removal-schedule.txt |   10 
 drivers/macintosh/via-pmu.c                |  343 +++++++++++++----------------
 2 files changed, 169 insertions(+), 184 deletions(-)

--- wireless-dev.orig/drivers/macintosh/via-pmu.c	2007-07-18 14:25:40.812900849 +0200
+++ wireless-dev/drivers/macintosh/via-pmu.c	2007-07-18 14:25:42.072900849 +0200
@@ -61,6 +61,7 @@
 #include <asm/cputable.h>
 #include <asm/time.h>
 #include <asm/backlight.h>
+#include <asm/suspend.h>
 
 #include "via-pmu-event.h"
 
@@ -156,9 +156,6 @@ static int drop_interrupts;
 #if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32)
 static int option_lid_wakeup = 1;
 #endif /* CONFIG_PM_SLEEP && CONFIG_PPC32 */
-#if (defined(CONFIG_PM_SLEEP)&&defined(CONFIG_PPC32))||defined(CONFIG_PMAC_BACKLIGHT_LEGACY)
-static int sleep_in_progress;
-#endif
 static unsigned long async_req_locks;
 static unsigned int pmu_irq_stats[11];
 
@@ -1935,122 +1933,6 @@ restore_via_state(void)
 
 extern void pmu_backlight_set_sleep(int sleep);
 
-static int
-pmac_suspend_devices(void)
-{
-	int ret;
-
-	pm_prepare_console();
-	
-	/* Sync the disks. */
-	/* XXX It would be nice to have some way to ensure that
-	 * nobody is dirtying any new buffers while we wait. That
-	 * could be achieved using the refrigerator for processes
-	 * that swsusp uses
-	 */
-	sys_sync();
-
-	/* Send suspend call to devices, hold the device core's dpm_sem */
-	ret = device_suspend(PMSG_SUSPEND);
-	if (ret) {
-		printk(KERN_ERR "Driver sleep failed\n");
-		return -EBUSY;
-	}
-
-#ifdef CONFIG_PMAC_BACKLIGHT
-	/* Tell backlight code not to muck around with the chip anymore */
-	pmu_backlight_set_sleep(1);
-#endif
-
-	/* Call platform functions marked "on sleep" */
-	pmac_pfunc_i2c_suspend();
-	pmac_pfunc_base_suspend();
-
-	/* Stop preemption */
-	preempt_disable();
-
-	/* Make sure the decrementer won't interrupt us */
-	asm volatile("mtdec %0" : : "r" (0x7fffffff));
-	/* Make sure any pending DEC interrupt occurring while we did
-	 * the above didn't re-enable the DEC */
-	mb();
-	asm volatile("mtdec %0" : : "r" (0x7fffffff));
-
-	/* We can now disable MSR_EE. This code of course works properly only
-	 * on UP machines... For SMP, if we ever implement sleep, we'll have to
-	 * stop the "other" CPUs way before we do all that stuff.
-	 */
-	local_irq_disable();
-
-	/* Broadcast power down irq
-	 * This isn't that useful in most cases (only directly wired devices can
-	 * use this but still... This will take care of sysdev's as well, so
-	 * we exit from here with local irqs disabled and PIC off.
-	 */
-	ret = device_power_down(PMSG_SUSPEND);
-	if (ret) {
-		wakeup_decrementer();
-		local_irq_enable();
-		preempt_enable();
-		device_resume();
-		printk(KERN_ERR "Driver powerdown failed\n");
-		return -EBUSY;
-	}
-
-	/* Wait for completion of async requests */
-	while (!batt_req.complete)
-		pmu_poll();
-
-	/* Giveup the lazy FPU & vec so we don't have to back them
-	 * up from the low level code
-	 */
-	enable_kernel_fp();
-
-#ifdef CONFIG_ALTIVEC
-	if (cpu_has_feature(CPU_FTR_ALTIVEC))
-		enable_kernel_altivec();
-#endif /* CONFIG_ALTIVEC */
-
-	return 0;
-}
-
-static int
-pmac_wakeup_devices(void)
-{
-	mdelay(100);
-
-#ifdef CONFIG_PMAC_BACKLIGHT
-	/* Tell backlight code it can use the chip again */
-	pmu_backlight_set_sleep(0);
-#endif
-
-	/* Power back up system devices (including the PIC) */
-	device_power_up();
-
-	/* Force a poll of ADB interrupts */
-	adb_int_pending = 1;
-	via_pmu_interrupt(0, NULL);
-
-	/* Restart jiffies & scheduling */
-	wakeup_decrementer();
-
-	/* Re-enable local CPU interrupts */
-	local_irq_enable();
-	mdelay(10);
-	preempt_enable();
-
-	/* Call platform functions marked "on wake" */
-	pmac_pfunc_base_resume();
-	pmac_pfunc_i2c_resume();
-
-	/* Resume devices */
-	device_resume();
-
-	pm_restore_console();
-
-	return 0;
-}
-
 #define	GRACKLE_PM	(1<<7)
 #define GRACKLE_DOZE	(1<<5)
 #define	GRACKLE_NAP	(1<<4)
@@ -2061,19 +1943,12 @@ static int powerbook_sleep_grackle(void)
 	unsigned long save_l2cr;
 	unsigned short pmcr1;
 	struct adb_request req;
-	int ret;
 	struct pci_dev *grackle;
 
 	grackle = pci_get_bus_and_slot(0, 0);
 	if (!grackle)
 		return -ENODEV;
 
-	ret = pmac_suspend_devices();
-	if (ret) {
-		printk(KERN_ERR "Sleep rejected by devices\n");
-		return ret;
-	}
-	
 	/* Turn off various things. Darwin does some retry tests here... */
 	pmu_request(&req, NULL, 2, PMU_POWER_CTRL0, PMU_POW0_OFF|PMU_POW0_HARD_DRIVE);
 	pmu_wait_complete(&req);
@@ -2136,8 +2011,6 @@ static int powerbook_sleep_grackle(void)
 			PMU_POW_ON|PMU_POW_BACKLIGHT|PMU_POW_CHARGER|PMU_POW_IRLED|PMU_POW_MEDIABAY);
 	pmu_wait_complete(&req);
 
-	pmac_wakeup_devices();
-
 	return 0;
 }
 
@@ -2147,7 +2020,6 @@ powerbook_sleep_Core99(void)
 	unsigned long save_l2cr;
 	unsigned long save_l3cr;
 	struct adb_request req;
-	int ret;
 	
 	if (pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) < 0) {
 		printk(KERN_ERR "Sleep mode not supported on this machine\n");
@@ -2157,12 +2029,6 @@ powerbook_sleep_Core99(void)
 	if (num_online_cpus() > 1 || cpu_is_offline(0))
 		return -EAGAIN;
 
-	ret = pmac_suspend_devices();
-	if (ret) {
-		printk(KERN_ERR "Sleep rejected by devices\n");
-		return ret;
-	}
-
 	/* Stop environment and ADB interrupts */
 	pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, 0);
 	pmu_wait_complete(&req);
@@ -2233,41 +2099,24 @@ powerbook_sleep_Core99(void)
 	/* Restore LPJ, cpufreq will adjust the cpu frequency */
 	loops_per_jiffy /= 2;
 
-	pmac_wakeup_devices();
-
 	return 0;
 }
 
 #define PB3400_MEM_CTRL		0xf8000000
 #define PB3400_MEM_CTRL_SLEEP	0x70
 
+static void __iomem *pb3400_mem_ctrl;
+
 static int
 powerbook_sleep_3400(void)
 {
-	int ret, i, x;
+	int i, x;
 	unsigned int hid0;
 	unsigned long p;
 	struct adb_request sleep_req;
-	void __iomem *mem_ctrl;
 	unsigned int __iomem *mem_ctrl_sleep;
 
-	/* first map in the memory controller registers */
-	mem_ctrl = ioremap(PB3400_MEM_CTRL, 0x100);
-	if (mem_ctrl == NULL) {
-		printk("powerbook_sleep_3400: ioremap failed\n");
-		return -ENOMEM;
-	}
-	mem_ctrl_sleep = mem_ctrl + PB3400_MEM_CTRL_SLEEP;
-
-	/* Allocate room for PCI save */
-	pbook_alloc_pci_save();
-
-	ret = pmac_suspend_devices();
-	if (ret) {
-		pbook_free_pci_save();
-		printk(KERN_ERR "Sleep rejected by devices\n");
-		return ret;
-	}
+	mem_ctrl_sleep = pb3400_mem_ctrl + PB3400_MEM_CTRL_SLEEP;
 
 	/* Save the state of PCI config space for some slots */
 	pbook_pci_save();
@@ -2312,10 +2161,6 @@ powerbook_sleep_3400(void)
 	while (asleep)
 		mb();
 
-	pmac_wakeup_devices();
-	pbook_free_pci_save();
-	iounmap(mem_ctrl);
-
 	return 0;
 }
 
@@ -2494,6 +2339,152 @@ pmu_release(struct inode *inode, struct 
 	return 0;
 }
 
+#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32)
+static int powerbook_prepare_sleep(suspend_state_t state)
+{
+	if (pmu_kind == PMU_OHARE_BASED) {
+		/* first map in the memory controller registers */
+		pb3400_mem_ctrl = ioremap(PB3400_MEM_CTRL, 0x100);
+		if (!pb3400_mem_ctrl) {
+			printk("powerbook_sleep_3400: ioremap failed\n");
+			return -ENOMEM;
+		}
+
+		/* Allocate room for PCI save */
+		pbook_alloc_pci_save();
+	}
+
+	return 0;
+}
+
+/*
+ * overrides the weak arch_suspend_disable_irqs in kernel/power/main.c
+ */
+void arch_suspend_disable_irqs(void)
+{
+#ifdef CONFIG_PMAC_BACKLIGHT
+	/* Tell backlight code not to muck around with the chip anymore */
+	pmu_backlight_set_sleep(1);
+#endif
+
+	/* Call platform functions marked "on sleep" */
+	pmac_pfunc_i2c_suspend();
+	pmac_pfunc_base_suspend();
+
+	/* Stop preemption */
+	preempt_disable();
+
+	/* Make sure the decrementer won't interrupt us */
+	asm volatile("mtdec %0" : : "r" (0x7fffffff));
+	/* Make sure any pending DEC interrupt occurring while we did
+	 * the above didn't re-enable the DEC */
+	mb();
+	asm volatile("mtdec %0" : : "r" (0x7fffffff));
+
+	local_irq_disable();
+}
+
+static int powerbook_sleep(suspend_state_t state)
+{
+	int error = 0;
+
+	/* Wait for completion of async requests */
+	while (!batt_req.complete)
+		pmu_poll();
+
+	/* Giveup the lazy FPU & vec so we don't have to back them
+	 * up from the low level code
+	 */
+	enable_kernel_fp();
+
+#ifdef CONFIG_ALTIVEC
+	if (cpu_has_feature(CPU_FTR_ALTIVEC))
+		enable_kernel_altivec();
+#endif /* CONFIG_ALTIVEC */
+
+	switch (pmu_kind) {
+	case PMU_OHARE_BASED:
+		error = powerbook_sleep_3400();
+		break;
+	case PMU_HEATHROW_BASED:
+	case PMU_PADDINGTON_BASED:
+		error = powerbook_sleep_grackle();
+		break;
+	case PMU_KEYLARGO_BASED:
+		error = powerbook_sleep_Core99();
+		break;
+	default:
+		return -ENOSYS;
+	}
+
+	if (error)
+		return error;
+
+	mdelay(100);
+
+#ifdef CONFIG_PMAC_BACKLIGHT
+	/* Tell backlight code it can use the chip again */
+	pmu_backlight_set_sleep(0);
+#endif
+
+	return 0;
+}
+
+/*
+ * overrides the weak arch_suspend_enable_irqs in kernel/power/main.c
+ */
+void arch_suspend_enable_irqs(void)
+{
+	/* Force a poll of ADB interrupts */
+	adb_int_pending = 1;
+	via_pmu_interrupt(0, NULL);
+
+	/* Restart jiffies & scheduling */
+	wakeup_decrementer();
+
+	/* Re-enable local CPU interrupts */
+	local_irq_enable();
+	mdelay(10);
+	preempt_enable();
+
+	/* Call platform functions marked "on wake" */
+	pmac_pfunc_base_resume();
+	pmac_pfunc_i2c_resume();
+}
+
+static int powerbook_finish_sleep(suspend_state_t state)
+{
+	if (pmu_kind == PMU_OHARE_BASED) {
+		pbook_free_pci_save();
+		iounmap(pb3400_mem_ctrl);
+	}
+
+	return 0;
+}
+
+static int pmu_sleep_valid(suspend_state_t state)
+{
+	return state == PM_SUSPEND_MEM
+		&& (pmac_call_feature(PMAC_FTR_SLEEP_STATE, NULL, 0, -1) >= 0);
+}
+
+static struct pm_ops pmu_pm_ops = {
+	.prepare = powerbook_prepare_sleep,
+	.enter = powerbook_sleep,
+	.finish = powerbook_finish_sleep,
+	.valid = pmu_sleep_valid,
+};
+
+static int register_pmu_pm_ops(void)
+{
+	pm_set_ops(&pmu_pm_ops);
+
+	return 0;
+}
+
+device_initcall(register_pmu_pm_ops);
+#endif
+
 static int
 pmu_ioctl(struct inode * inode, struct file *filp,
 		     u_int cmd, u_long arg)
@@ -2495,29 +2495,19 @@ pmu_ioctl(struct inode * inode, struct f
 
 	switch (cmd) {
 #if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32)
+	/* just provided for compatibility */
 	case PMU_IOC_SLEEP:
 		if (!capable(CAP_SYS_ADMIN))
 			return -EACCES;
-		if (sleep_in_progress)
-			return -EBUSY;
-		sleep_in_progress = 1;
-		switch (pmu_kind) {
-		case PMU_OHARE_BASED:
-			error = powerbook_sleep_3400();
-			break;
-		case PMU_HEATHROW_BASED:
-		case PMU_PADDINGTON_BASED:
-			error = powerbook_sleep_grackle();
-			break;
-		case PMU_KEYLARGO_BASED:
-			error = powerbook_sleep_Core99();
-			break;
-		default:
-			error = -ENOSYS;
-		}
-		sleep_in_progress = 0;
+		printk(KERN_INFO "via-pmu: the PMU_IOC_SLEEP ioctl is deprecated.\n");
+		printk(KERN_INFO "via-pmu: use \"echo mem > /sys/power/state\" instead!\n");
+		printk(KERN_INFO "via-pmu: this ioctl will be removed soon.\n");
+		error = pm_suspend(PM_SUSPEND_MEM);
 		break;
 	case PMU_IOC_CAN_SLEEP:
+		printk(KERN_INFO "via-pmu: the PMU_IOC_CAN_SLEEP ioctl is deprecated.\n");
+		printk(KERN_INFO "via-pmu: use \"grep mem /sys/power/state\" instead!\n");
+		printk(KERN_INFO "via-pmu: this ioctl will be removed soon.\n");
 		if (pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) < 0)
 			return put_user(0, argp);
 		else
@@ -2538,9 +2519,6 @@ pmu_ioctl(struct inode * inode, struct f
 	{
 		int brightness;
 
-		if (sleep_in_progress)
-			return -EBUSY;
-
 		brightness = pmac_backlight_get_legacy_brightness();
 		if (brightness < 0)
 			return brightness;
@@ -2552,9 +2530,6 @@ pmu_ioctl(struct inode * inode, struct f
 	{
 		int brightness;
 
-		if (sleep_in_progress)
-			return -EBUSY;
-
 		error = get_user(brightness, argp);
 		if (error)
 			return error;
--- wireless-dev.orig/Documentation/feature-removal-schedule.txt	2007-07-18 14:25:24.082900849 +0200
+++ wireless-dev/Documentation/feature-removal-schedule.txt	2007-07-18 14:25:42.072900849 +0200
@@ -310,3 +310,13 @@ Why:  The arch/powerpc tree is the merge
 Who:  linuxppc-dev at ozlabs.org
 
 ---------------------------
+
+What:	/dev/pmu suspend/can-suspend ioctls
+When:	August 2009
+Files:	drivers/macintosh/via-pmu.c
+Why:	powermac supports proper generic pm_ops now and can suspend with
+	"echo mem > /sys/power/state" instead of the ioctl, checking if
+	it can suspend can be done by reading /sys/power/state.
+Who:	Johannes Berg <johannes at sipsolutions.net>
+
+---------------------------

linux-2.6-powerpc-lparmap-g.patch:

--- NEW FILE linux-2.6-powerpc-lparmap-g.patch ---
--- linux-2.6.22.noarch/arch/powerpc/kernel/Makefile~	2007-08-20 16:25:12.000000000 -0400
+++ linux-2.6.22.noarch/arch/powerpc/kernel/Makefile	2007-08-20 16:25:27.000000000 -0400
@@ -81,7 +81,7 @@ obj-y				+= iomap.o
 endif
 
 ifeq ($(CONFIG_PPC_ISERIES),y)
-CFLAGS_lparmap.s		+= -g0
+CFLAGS_lparmap.o		+= -g0
 extra-y += lparmap.s
 $(obj)/head_64.o:	$(obj)/lparmap.s
 AFLAGS_head_64.o += -I$(obj)

linux-2.6-powerpc-reserve-initrd-1.patch:

--- NEW FILE linux-2.6-powerpc-reserve-initrd-1.patch ---
>From linuxppc-dev-bounces+dwmw2=infradead.org at ozlabs.org Wed Feb 28 03:12:45 2007
Return-path: <linuxppc-dev-bounces+dwmw2=infradead.org at ozlabs.org>
Envelope-to: dwmw2 at baythorne.infradead.org
Delivery-date: Wed, 28 Feb 2007 03:12:45 +0000
Received: from pentafluge.infradead.org ([2001:4bd0:203e::1]) by
	baythorne.infradead.org with esmtps (Exim 4.63 #1 (Red Hat Linux)) id
	1HMFFE-00054K-V7 for dwmw2 at baythorne.infradead.org; Wed, 28 Feb 2007
	03:12:45 +0000
Received: from ozlabs.org ([203.10.76.45]) by pentafluge.infradead.org with
	esmtps (Exim 4.63 #1 (Red Hat Linux)) id 1HMFFB-0000pp-L0 for
	dwmw2 at infradead.org; Wed, 28 Feb 2007 03:12:44 +0000
Received: from ozlabs.org (localhost [127.0.0.1]) by ozlabs.org (Postfix)
	with ESMTP id 6FE7DDDECB for <dwmw2 at infradead.org>; Wed, 28 Feb 2007
	14:12:34 +1100 (EST)
X-Original-To: linuxppc-dev at ozlabs.org
Delivered-To: linuxppc-dev at ozlabs.org
Received: by ozlabs.org (Postfix, from userid 1007) id 430F3DDDF6; Wed, 28
	Feb 2007 14:12:29 +1100 (EST)
To: Paul Mackerras <paulus at samba.org>, Benjamin Herrenschmidt <benh at kernel.crashing.org>, <linuxppc-dev at ozlabs.org>
From: David Gibson <david at gibson.dropbear.id.au>
Subject: [PATCH 1/2] powerpc: Allow duplicate lmb_reserve() calls
In-Reply-To: <20070228031120.GF11775 at localhost.localdomain>
Message-Id: <20070228031229.430F3DDDF6 at ozlabs.org>
Date: Wed, 28 Feb 2007 14:12:29 +1100 (EST)
X-BeenThere: linuxppc-dev at ozlabs.org
X-Mailman-Version: 2.1.9
Precedence: list
List-Id: Linux on PowerPC Developers Mail List <linuxppc-dev.ozlabs.org>
List-Unsubscribe: <https://ozlabs.org/mailman/listinfo/linuxppc-dev>,
	<mailto:linuxppc-dev-request at ozlabs.org?subject=unsubscribe>
List-Archive: <http://ozlabs.org/pipermail/linuxppc-dev>
List-Post: <mailto:linuxppc-dev at ozlabs.org>
List-Help: <mailto:linuxppc-dev-request at ozlabs.org?subject=help>
List-Subscribe: <https://ozlabs.org/mailman/listinfo/linuxppc-dev>,
	<mailto:linuxppc-dev-request at ozlabs.org?subject=subscribe>
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Sender: linuxppc-dev-bounces+dwmw2=infradead.org at ozlabs.org
Errors-To: linuxppc-dev-bounces+dwmw2=infradead.org at ozlabs.org
X-Bad-Reply: In-Reply-To but no 'Re:' in Subject.
X-Spam-Score: 0.0 (/)
X-Evolution-Source: imap://dwmw2@pentafluge.infradead.org/
Content-Transfer-Encoding: 8bit

At present calling lmb_reserve() (and hence lmb_add_region()) twice
for exactly the same memory region will cause strange behaviour.

This makes life difficult when booting from a flat device tree with
memory reserve map.  Which regions are automatically reserved by the
kernel has changed over time, so it's quite possible a newer kernel
could attempt to auto-reserve a region which is also explicitly listed
in the device tree's reserve map, leading to trouble.

This patch avoids the problem by making lmb_reserve() ignore a call to
reserve a previously reserved region.  It also removes a now redundant
test designed to avoid one specific case of the problem noted above.

At present, this patch deals only with duplicate reservations of an
identical region.  Attempting to reserve two different, but
overlapping regions will still cause problems.  I might post another
patch later dealing with this case, but I'm avoiding it now since it
is substantially more complicated to deal with, less likely to occur
and more likely to indicate a genuine bug elsewhere if it does occur.

Signed-off-by: David Gibson <dwg at au1.ibm.com>
---


 arch/powerpc/kernel/prom.c |    3 ---
 arch/powerpc/mm/lmb.c      |    4 ++++
 2 files changed, 4 insertions(+), 3 deletions(-)

Index: working-2.6/arch/powerpc/mm/lmb.c
===================================================================
--- working-2.6.orig/arch/powerpc/mm/lmb.c	2007-02-06 16:21:02.000000000 +1100
+++ working-2.6/arch/powerpc/mm/lmb.c	2007-02-06 16:22:32.000000000 +1100
@@ -146,6 +146,10 @@ static long __init lmb_add_region(struct
 		unsigned long rgnbase = rgn->region[i].base;
 		unsigned long rgnsize = rgn->region[i].size;
 
+		if ((rgnbase == base) && (rgnsize == size))
+			/* Already have this region, so we're done */
+			return 0;
+
 		adjacent = lmb_addrs_adjacent(base,size,rgnbase,rgnsize);
 		if ( adjacent > 0 ) {
 			rgn->region[i].base -= size;
Index: working-2.6/arch/powerpc/kernel/prom.c
===================================================================
--- working-2.6.orig/arch/powerpc/kernel/prom.c	2007-02-06 16:22:48.000000000 +1100
+++ working-2.6/arch/powerpc/kernel/prom.c	2007-02-06 16:22:57.000000000 +1100
@@ -954,9 +954,6 @@ static void __init early_reserve_mem(voi
 		size = *(reserve_map++);
 		if (size == 0)
 			break;
-		/* skip if the reservation is for the blob */
-		if (base == self_base && size == self_size)
-			continue;
 		DBG("reserving: %llx -> %llx\n", base, size);
 		lmb_reserve(base, size);
 	}
_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev at ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev

linux-2.6-powerpc-reserve-initrd-2.patch:

--- NEW FILE linux-2.6-powerpc-reserve-initrd-2.patch ---
>From linuxppc-dev-bounces+dwmw2=infradead.org at ozlabs.org Wed Feb 28 03:13:44 2007
Return-path: <linuxppc-dev-bounces+dwmw2=infradead.org at ozlabs.org>
Envelope-to: dwmw2 at baythorne.infradead.org
Delivery-date: Wed, 28 Feb 2007 03:13:44 +0000
Received: from pentafluge.infradead.org ([2001:4bd0:203e::1]) by
	baythorne.infradead.org with esmtps (Exim 4.63 #1 (Red Hat Linux)) id
	1HMFGC-00054U-CH for dwmw2 at baythorne.infradead.org; Wed, 28 Feb 2007
	03:13:44 +0000
Received: from ozlabs.org ([203.10.76.45]) by pentafluge.infradead.org with
	esmtps (Exim 4.63 #1 (Red Hat Linux)) id 1HMFG8-0000q5-Ua for
	dwmw2 at infradead.org; Wed, 28 Feb 2007 03:13:43 +0000
Received: from ozlabs.org (localhost [127.0.0.1]) by ozlabs.org (Postfix)
	with ESMTP id 73887DE044 for <dwmw2 at infradead.org>; Wed, 28 Feb 2007
	14:13:05 +1100 (EST)
X-Original-To: linuxppc-dev at ozlabs.org
Delivered-To: linuxppc-dev at ozlabs.org
Received: by ozlabs.org (Postfix, from userid 1007) id 55D11DDDF9; Wed, 28
	Feb 2007 14:12:29 +1100 (EST)
To: Paul Mackerras <paulus at samba.org>, Benjamin Herrenschmidt <benh at kernel.crashing.org>, <linuxppc-dev at ozlabs.org>
From: David Gibson <david at gibson.dropbear.id.au>
Subject: [PATCH 2/2] Automatically lmb_reserve() initrd
In-Reply-To: <20070228031120.GF11775 at localhost.localdomain>
Message-Id: <20070228031229.55D11DDDF9 at ozlabs.org>
Date: Wed, 28 Feb 2007 14:12:29 +1100 (EST)
X-BeenThere: linuxppc-dev at ozlabs.org
X-Mailman-Version: 2.1.9
Precedence: list
List-Id: Linux on PowerPC Developers Mail List <linuxppc-dev.ozlabs.org>
List-Unsubscribe: <https://ozlabs.org/mailman/listinfo/linuxppc-dev>,
	<mailto:linuxppc-dev-request at ozlabs.org?subject=unsubscribe>
List-Archive: <http://ozlabs.org/pipermail/linuxppc-dev>
List-Post: <mailto:linuxppc-dev at ozlabs.org>
List-Help: <mailto:linuxppc-dev-request at ozlabs.org?subject=help>
List-Subscribe: <https://ozlabs.org/mailman/listinfo/linuxppc-dev>,
	<mailto:linuxppc-dev-request at ozlabs.org?subject=subscribe>
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Sender: linuxppc-dev-bounces+dwmw2=infradead.org at ozlabs.org
Errors-To: linuxppc-dev-bounces+dwmw2=infradead.org at ozlabs.org
X-Bad-Reply: In-Reply-To but no 'Re:' in Subject.
X-Spam-Score: 0.0 (/)
X-Evolution-Source: imap://dwmw2@pentafluge.infradead.org/
Content-Transfer-Encoding: 8bit

At present, when an initrd is passed to the kernel used flat device
tree properties, the memory the initrd occupies must also be reserved
in the flat tree's reserve map, or the kernel may overwrite it.  That
makes life more complicated than it could be for the bootwrapper.

This patch makes the kernel automatically reserve the initrd's space.
That in turn requires parsing the initrd parameters earlier than they
are currently, in early_init_dt_scan_chosen() instead of
check_for_initrd().

Signed-off-by: David Gibson <dwg at au1.ibm.com>
---

 arch/powerpc/kernel/prom.c         |   23 +++++++++++++++++++++++
 arch/powerpc/kernel/setup-common.c |   22 ++--------------------
 2 files changed, 25 insertions(+), 20 deletions(-)

Index: working-2.6/arch/powerpc/kernel/prom.c
===================================================================
--- working-2.6.orig/arch/powerpc/kernel/prom.c	2007-02-09 15:12:00.000000000 +1100
+++ working-2.6/arch/powerpc/kernel/prom.c	2007-02-09 15:14:27.000000000 +1100
@@ -719,6 +719,7 @@ static int __init early_init_dt_scan_cho
 					    const char *uname, int depth, void *data)
 {
 	unsigned long *lprop;
+	u32 *prop;
 	unsigned long l;
 	char *p;
 
@@ -760,6 +761,22 @@ static int __init early_init_dt_scan_cho
                crashk_res.end = crashk_res.start + *lprop - 1;
 #endif
 
+#ifdef CONFIG_BLK_DEV_INITRD
+	DBG("Looking for initrd properties... ");
+	prop = of_get_flat_dt_prop(node, "linux,initrd-start", &l);
+	if (prop) {
+		initrd_start = (unsigned long)__va(of_read_ulong(prop, l/4));
+		prop = of_get_flat_dt_prop(node, "linux,initrd-end", &l);
+		if (prop) {
+			initrd_end = (unsigned long)__va(of_read_ulong(prop, l/4));
+			initrd_below_start_ok = 1;
+		} else {
+			initrd_start = 0;
+		}
+	}
+	DBG("initrd_start=0x%lx  initrd_end=0x%lx\n", initrd_start, initrd_end);
+#endif /* CONFIG_BLK_DEV_INITRD */
+
 	/* Retreive command line */
  	p = of_get_flat_dt_prop(node, "bootargs", &l);
 	if (p != NULL && l > 0)
@@ -926,6 +943,12 @@ static void __init early_reserve_mem(voi
 	self_size = initial_boot_params->totalsize;
 	lmb_reserve(self_base, self_size);
 
+#ifdef CONFIG_BLK_DEV_INITRD
+	/* then reserve the initrd, if any */
+	if (initrd_start && (initrd_end > initrd_start))
+		lmb_reserve(__pa(initrd_start), initrd_end - initrd_start);
+#endif /* CONFIG_BLK_DEV_INITRD */
+
 #ifdef CONFIG_PPC32
 	/* 
 	 * Handle the case where we might be booting from an old kexec
Index: working-2.6/arch/powerpc/kernel/setup-common.c
===================================================================
--- working-2.6.orig/arch/powerpc/kernel/setup-common.c	2007-01-24 12:01:17.000000000 +1100
+++ working-2.6/arch/powerpc/kernel/setup-common.c	2007-02-09 15:15:15.000000000 +1100
@@ -304,26 +304,8 @@ struct seq_operations cpuinfo_op = {
 void __init check_for_initrd(void)
 {
 #ifdef CONFIG_BLK_DEV_INITRD
-	const unsigned int *prop;
-	int len;
-
-	DBG(" -> check_for_initrd()\n");
-
-	if (of_chosen) {
-		prop = get_property(of_chosen, "linux,initrd-start", &len);
-		if (prop != NULL) {
-			initrd_start = (unsigned long)
-				__va(of_read_ulong(prop, len / 4));
-			prop = get_property(of_chosen,
-					"linux,initrd-end", &len);
-			if (prop != NULL) {
-				initrd_end = (unsigned long)
-					__va(of_read_ulong(prop, len / 4));
-				initrd_below_start_ok = 1;
-			} else
-				initrd_start = 0;
-		}
-	}
+	DBG(" -> check_for_initrd()  initrd_start=0x%lx  initrd_end=0x%lx\n",
+	    initrd_start, initrd_end);
 
 	/* If we were passed an initrd, set the ROOT_DEV properly if the values
 	 * look sensible. If not, clear initrd reference.
_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev at ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev

linux-2.6-powerpc-slabalign.patch:

--- NEW FILE linux-2.6-powerpc-slabalign.patch ---
diff --git a/include/asm-powerpc/processor.h b/include/asm-powerpc/processor.h
index a26c32e..30f7e59 100644
--- a/include/asm-powerpc/processor.h
+++ b/include/asm-powerpc/processor.h
@@ -270,6 +270,9 @@ static inline void prefetchw(const void *x)
 #define HAVE_ARCH_PICK_MMAP_LAYOUT
 #endif
 
+/* Force slab alignment to work for uint64_t */
+#define ARCH_KMALLOC_MINALIGN 8
+
 #endif /* __KERNEL__ */
 #endif /* __ASSEMBLY__ */
 #endif /* _ASM_POWERPC_PROCESSOR_H */

linux-2.6-powerpc-spu-vicinity.patch:

--- NEW FILE linux-2.6-powerpc-spu-vicinity.patch ---
From: Andre Detsch <adetsch at br.ibm.com>
To: cbe-oss-dev at ozlabs.org
Message-Id: <200707301213.40811.adetsch at br.ibm.com>
Cc: hch at lst.de, Arnd Bergmann <arnd at arndb.de>
Subject: [Cbe-oss-dev] [PATCH] cell: Safer of_has_vicinity routine

Subject: cell: Safer of_has_vicinity routine

From: Andre Detsch <adetsch at br.ibm.com>

This patch changes the way we check for the existence of
vicinity property in spe device nodes.

The new implementation does not depend on having an initialized
cbe_spu_info[0].spus, and checks for presence of vicinity in all
nodes, not only in the first one.

Basically a copy & paste from Arnd's suggestion sent to cbe-oss-dev.

Signed-off-by: Andre Detsch <adetsch at br.ibm.com>

--- linux-2.6.22.ppc64/arch/powerpc/platforms/cell/spu_base.c.orig	2007-07-31 20:44:53.000000000 +0100
+++ linux-2.6.22.ppc64/arch/powerpc/platforms/cell/spu_base.c	2007-07-31 20:47:06.000000000 +0100
@@ -676,10 +676,15 @@ static void init_aff_QS20_harcoded(void)
 
 static int of_has_vicinity(void)
 {
-	struct spu* spu;
+	struct device_node *dn;
 
-	spu = list_entry(cbe_spu_info[0].spus.next, struct spu, cbe_list);
-	return of_find_property(spu_devnode(spu), "vicinity", NULL) != NULL;
+	for_each_node_by_type(dn, "spe") {
+		if (of_find_property(dn, "vicinity", NULL))  {
+			of_node_put(dn);
+			return 1;
+		}
+	}
+	return 0;
 }
 
 static struct spu *aff_devnode_spu(int cbe, struct device_node *dn)

linux-2.6-powerpc-vdso-install-unstripped-copies-on-disk.patch:

--- NEW FILE linux-2.6-powerpc-vdso-install-unstripped-copies-on-disk.patch ---
From: Roland McGrath <roland at redhat.com>

This keeps an unstripped copy of the vDSO images built before they are
stripped and embedded in the kernel.  The unstripped copies get installed in
$(MODLIB)/vdso/ by "make install".  These files can be useful when they
contain source-level debugging information.

Signed-off-by: Roland McGrath <roland at redhat.com>
Cc: Sam Ravnborg <sam at ravnborg.org>
Cc: Paul Mackerras <paulus at samba.org>
Cc: Benjamin Herrenschmidt <benh at kernel.crashing.org>
---

 arch/powerpc/Makefile               |    5 ++++-
 arch/powerpc/kernel/vdso32/Makefile |   20 +++++++++++++++++---
 arch/powerpc/kernel/vdso64/Makefile |   19 ++++++++++++++++---
 3 files changed, 37 insertions(+), 7 deletions(-)

diff -puN arch/powerpc/Makefile~powerpc-vdso-install-unstripped-copies-on-disk arch/powerpc/Makefile
--- a/arch/powerpc/Makefile~powerpc-vdso-install-unstripped-copies-on-disk
+++ a/arch/powerpc/Makefile
@@ -166,9 +166,15 @@ define archhelp
   @echo '  *_defconfig     - Select default config from arch/$(ARCH)/configs'
 endef
 
-install:
+install: vdso_install
 	$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) install
 
+vdso_install:
+ifeq ($(CONFIG_PPC64),y)
+	$(Q)$(MAKE) $(build)=arch/$(ARCH)/kernel/vdso64 $@
+endif
+	$(Q)$(MAKE) $(build)=arch/$(ARCH)/kernel/vdso32 $@
+
 archclean:
 	$(Q)$(MAKE) $(clean)=$(boot)

diff -puN arch/powerpc/kernel/vdso32/Makefile~powerpc-vdso-install-unstripped-copies-on-disk arch/powerpc/kernel/vdso32/Makefile
--- a/arch/powerpc/kernel/vdso32/Makefile~powerpc-vdso-install-unstripped-copies-on-disk
+++ a/arch/powerpc/kernel/vdso32/Makefile
@@ -9,11 +9,11 @@ ifeq ($(CONFIG_PPC32),y)
 CROSS32CC := $(CC)
 endif
 
-targets := $(obj-vdso32) vdso32.so
+targets := $(obj-vdso32) vdso32.so vdso32.so.dbg
 obj-vdso32 := $(addprefix $(obj)/, $(obj-vdso32))
 
 
-EXTRA_CFLAGS := -shared -s -fno-common -fno-builtin
+EXTRA_CFLAGS := -shared -fno-common -fno-builtin
 EXTRA_CFLAGS += -nostdlib -Wl,-soname=linux-vdso32.so.1 \
 		$(call ld-option, -Wl$(comma)--hash-style=sysv)
 EXTRA_AFLAGS := -D__VDSO32__ -s
@@ -26,9 +26,14 @@ CPPFLAGS_vdso32.lds += -P -C -Upowerpc
 $(obj)/vdso32_wrapper.o : $(obj)/vdso32.so
 
 # link rule for the .so file, .lds has to be first
-$(obj)/vdso32.so: $(src)/vdso32.lds $(obj-vdso32)
+$(obj)/vdso32.so.dbg: $(src)/vdso32.lds $(obj-vdso32)
 	$(call if_changed,vdso32ld)
 
+# strip rule for the .so file
+$(obj)/%.so: OBJCOPYFLAGS := -S
+$(obj)/%.so: $(obj)/%.so.dbg FORCE
+	$(call if_changed,objcopy)
+
 # assembly rules for the .S files
 $(obj-vdso32): %.o: %.S
 	$(call if_changed_dep,vdso32as)
@@ -39,3 +44,12 @@ quiet_cmd_vdso32ld = VDSO32L $@
 quiet_cmd_vdso32as = VDSO32A $@
       cmd_vdso32as = $(CROSS32CC) $(a_flags) -c -o $@ $<
 
+# install commands for the unstripped file
+quiet_cmd_vdso_install = INSTALL $@
+      cmd_vdso_install = cp $(obj)/$@.dbg $(MODLIB)/vdso/$@
+
+vdso32.so: $(obj)/vdso32.so.dbg
+	@mkdir -p $(MODLIB)/vdso
+	$(call cmd,vdso_install)
+
+vdso_install: vdso32.so
diff -puN arch/powerpc/kernel/vdso64/Makefile~powerpc-vdso-install-unstripped-copies-on-disk arch/powerpc/kernel/vdso64/Makefile
--- a/arch/powerpc/kernel/vdso64/Makefile~powerpc-vdso-install-unstripped-copies-on-disk
+++ a/arch/powerpc/kernel/vdso64/Makefile
@@ -4,10 +4,10 @@ obj-vdso64 = sigtramp.o gettimeofday.o d
 
 # Build rules
 
-targets := $(obj-vdso64) vdso64.so
+targets := $(obj-vdso64) vdso64.so vdso64.so.dbg
 obj-vdso64 := $(addprefix $(obj)/, $(obj-vdso64))
 
-EXTRA_CFLAGS := -shared -s -fno-common -fno-builtin
+EXTRA_CFLAGS := -shared -fno-common -fno-builtin
 EXTRA_CFLAGS += -nostdlib -Wl,-soname=linux-vdso64.so.1 \
 		$(call ld-option, -Wl$(comma)--hash-style=sysv)
 EXTRA_AFLAGS := -D__VDSO64__ -s
@@ -20,9 +20,14 @@ CPPFLAGS_vdso64.lds += -P -C -U$(ARCH)
 $(obj)/vdso64_wrapper.o : $(obj)/vdso64.so
 
 # link rule for the .so file, .lds has to be first
-$(obj)/vdso64.so: $(src)/vdso64.lds $(obj-vdso64)
+$(obj)/vdso64.so.dbg: $(src)/vdso64.lds $(obj-vdso64)
 	$(call if_changed,vdso64ld)
 
+# strip rule for the .so file
+$(obj)/%.so: OBJCOPYFLAGS := -S
+$(obj)/%.so: $(obj)/%.so.dbg FORCE
+	$(call if_changed,objcopy)
+
 # assembly rules for the .S files
 $(obj-vdso64): %.o: %.S
 	$(call if_changed_dep,vdso64as)
@@ -33,4 +38,12 @@ quiet_cmd_vdso64ld = VDSO64L $@
 quiet_cmd_vdso64as = VDSO64A $@
       cmd_vdso64as = $(CC) $(a_flags) -c -o $@ $<
 
+# install commands for the unstripped file
+quiet_cmd_vdso_install = INSTALL $@
+      cmd_vdso_install = cp $(obj)/$@.dbg $(MODLIB)/vdso/$@
+
+vdso64.so: $(obj)/vdso64.so.dbg
+	@mkdir -p $(MODLIB)/vdso
+	$(call cmd,vdso_install)
 
+vdso_install: vdso64.so

linux-2.6-ppc-data-exception.patch:

--- NEW FILE linux-2.6-ppc-data-exception.patch ---
Gitweb:     http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=9ba4ace39fdfe22268daca9f28c5df384ae462cf
Commit:     9ba4ace39fdfe22268daca9f28c5df384ae462cf
Parent:     7c8545e98468c53809fc06788a3b9a34dff05240
Author:     Segher Boessenkool <segher at kernel.crashing.org>
AuthorDate: Wed Jun 20 01:07:04 2007 +1000
Committer:  Paul Mackerras <paulus at samba.org>
CommitDate: Wed Jun 20 22:07:38 2007 +1000

    [POWERPC] PowerPC: Prevent data exception in kernel space (32-bit)
    
    The "is_exec" branch of the protection check in do_page_fault()
    didn't do anything on 32-bit PowerPC.  So if a userland program
    jumps to a page with Linux protection flags "---p", all the tests
    happily fall through, and handle_mm_fault() is called, which in
    turn calls handle_pte_fault(), which calls update_mmu_cache(),
    which goes flush the dcache to a page with no access rights.
    
    Boom.
    
    This fixes it.
    
    Signed-off-by: Segher Boessenkool <segher at kernel.crashing.org>
    Cc: Johannes Berg <johannes at sipsolutions.net>
    Signed-off-by: Paul Mackerras <paulus at samba.org>
---
 arch/powerpc/mm/fault.c |    5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
index bfe9013..115b25f 100644
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -279,14 +279,13 @@ good_area:
 #endif /* CONFIG_8xx */
 
 	if (is_exec) {
-#ifdef CONFIG_PPC64
+#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
 		/* protection fault */
 		if (error_code & DSISR_PROTFAULT)
 			goto bad_area;
 		if (!(vma->vm_flags & VM_EXEC))
 			goto bad_area;
-#endif
-#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
+#else
 		pte_t *ptep;
 		pmd_t *pmdp;
 

linux-2.6-ppc-pegasos-via-ata-legacy-irq.patch:

--- NEW FILE linux-2.6-ppc-pegasos-via-ata-legacy-irq.patch ---
The built-in IDE controller is configured in legacy mode,
but the PCI registers advertise native mode.
Force the PCI class into legacy mode. This allows pata_via to access
two drives.
The Pegasos specific irq enforcement in the via82cxxx driver
can be removed.

Tested on Pegasos2 with firmware version 20040810, and two IDE disks.

---
 arch/powerpc/kernel/prom_init.c   |   11 ++++++++---
 arch/powerpc/platforms/chrp/pci.c |   28 ++++++++++++++++++++++++++++
 drivers/ide/pci/via82cxxx.c       |    7 -------
 3 files changed, 36 insertions(+), 10 deletions(-)

--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -2041,6 +2041,7 @@ static void __init fixup_device_tree_map
 /*
  * Pegasos and BriQ lacks the "ranges" property in the isa node
  * Pegasos needs decimal IRQ 14/15, not hexadecimal
+ * Pegasos has the IDE configured in legacy mode, but advertised as native
  */
 static void __init fixup_device_tree_chrp(void)
 {
@@ -2078,9 +2079,13 @@ static void __init fixup_device_tree_chr
 		prom_printf("Fixing up IDE interrupt on Pegasos...\n");
 		prop[0] = 14;
 		prop[1] = 0x0;
-		prop[2] = 15;
-		prop[3] = 0x0;
-		prom_setprop(ph, name, "interrupts", prop, 4*sizeof(u32));
+		prom_setprop(ph, name, "interrupts", prop, 2*sizeof(u32));
+		prom_printf("Fixing up IDE class-code on Pegasos...\n");
+		rc = prom_getprop(ph, "class-code", prop, sizeof(u32));
+		if (rc == sizeof(u32)) {
+			prop[0] &= ~0x5;
+			prom_setprop(ph, name, "class-code", prop, sizeof(u32));
+		}
 	}
 }
 #else
--- a/arch/powerpc/platforms/chrp/pci.c
+++ b/arch/powerpc/platforms/chrp/pci.c
@@ -338,3 +338,31 @@ void chrp_pci_fixup_winbond_ata(struct p
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105,
 		chrp_pci_fixup_winbond_ata);
+
+/* Pegasos2 firmware version 20040810 configures the built-in IDE controller
+ * in legacy mode, but sets the PCI registers to PCI native mode.
+ * The chip can only operate in legacy mode, so force the PCI class into legacy
+ * mode as well. The same fixup must be done to the class-code property in
+ * the IDE node /pci at 80000000/ide at C,1
+ */
+static void chrp_pci_fixup_vt8231_ata(struct pci_dev *viaide)
+{
+	u8 progif;
+	struct pci_dev *viaisa;
+
+	if (!machine_is(chrp) || _chrp_type != _CHRP_Pegasos)
+		return;
+	if (viaide->irq != 14)
+		return;
+
+	viaisa = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231, NULL);
+	if (!viaisa)
+		return;
+	printk("Fixing VIA IDE, force legacy mode on '%s'\n", viaide->dev.bus_id);
+
+	pci_read_config_byte(viaide, PCI_CLASS_PROG, &progif);
+	pci_write_config_byte(viaide, PCI_CLASS_PROG, progif & ~0x5);
+
+	pci_dev_put(viaisa);
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, chrp_pci_fixup_vt8231_ata);
--- a/drivers/ide/pci/via82cxxx.c
+++ b/drivers/ide/pci/via82cxxx.c
@@ -436,13 +436,6 @@ static void __devinit init_hwif_via82cxx
 	hwif->tuneproc = &via82cxxx_tune_drive;
 	hwif->speedproc = &via_set_drive;
 
-
-#ifdef CONFIG_PPC_CHRP
-	if(machine_is(chrp) && _chrp_type == _CHRP_Pegasos) {
-		hwif->irq = hwif->channel ? 15 : 14;
-	}
-#endif
-
 	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;

linux-2.6-ps3-clear-spu-irq.patch:

--- NEW FILE linux-2.6-ps3-clear-spu-irq.patch ---
From: Masato Noguchi <Masato.Noguchi at jp.sony.com>

In the PS3 platform, all interrupts are virtuailzed by hypervisor.
Thus, there is a little difference between baremetal and PS3.

Cell BE Architecture says SPU MFC class 0 interrupt is a pulse.
That means, once interrupt raised, never re-raised until someone
changes interrupt status.

Current spufs inplementation rely on it.
Class 0 handler just wake up a process and interrupt status is
cleared by that process at outside of interrupt handler.

While, the PS3 hypervisor treats all SPU interrupt as a level.
That means, if unmasked interrupt status bit remaind at
the end of interrupt handler, the hypervisor creates renewed
virtual interrupt packet.

Thus, Current kernel will freeze by interrupts raised 
over and over again, once SPE raised class 0 interrupt.


Signed-off-by: Masato Noguchi <Masato.Noguchi at jp.sony.com>
Signed-off-by: Geoff Levand <geoffrey.levand at am.sony.com>
---
 arch/powerpc/platforms/cell/spu_base.c |   23 +++++++++++++++--------
 include/asm-powerpc/spu.h              |    2 +-
 2 files changed, 16 insertions(+), 9 deletions(-)

--- ps3-linux-2.6.20.orig/arch/powerpc/platforms/cell/spu_base.c
+++ ps3-linux-2.6.20/arch/powerpc/platforms/cell/spu_base.c
@@ -158,27 +158,34 @@ static irqreturn_t
 spu_irq_class_0(int irq, void *data)
 {
 	struct spu *spu;
+	unsigned long stat, mask;
 
 	spu = data;
-	spu->class_0_pending = 1;
+
+	mask = spu_int_mask_get(spu, 0);
+	stat = spu_int_stat_get(spu, 0);
+	stat &= mask;
+
+	spin_lock(&spu->register_lock);
+	spu->class_0_pending |= stat;
+	spin_unlock(&spu->register_lock);
+
 	spu->stop_callback(spu);
 
+	spu_int_stat_clear(spu, 0, stat);
+
 	return IRQ_HANDLED;
 }
 
 int
 spu_irq_class_0_bottom(struct spu *spu)
 {
-	unsigned long stat, mask;
 	unsigned long flags;
-
-	spu->class_0_pending = 0;
+	unsigned long stat;
 
 	spin_lock_irqsave(&spu->register_lock, flags);
-	mask = spu_int_mask_get(spu, 0);
-	stat = spu_int_stat_get(spu, 0);
-
-	stat &= mask;
+	stat = spu->class_0_pending;
+	spu->class_0_pending = 0;
 
 	if (stat & 1) /* invalid DMA alignment */
 		__spu_trap_dma_align(spu);
--- ps3-linux-2.6.20.orig/include/asm-powerpc/spu.h
+++ ps3-linux-2.6.20/include/asm-powerpc/spu.h
@@ -122,6 +122,7 @@ struct spu {
 	u64 flags;
 	u64 dar;
 	u64 dsisr;
+	u64 class_0_pending;
 	size_t ls_size;
 	unsigned int slb_replace;
 	struct mm_struct *mm;
@@ -129,7 +130,6 @@ struct spu {
 	struct spu_runqueue *rq;
 	unsigned long long timestamp;
 	pid_t pid;
-	int class_0_pending;
 	spinlock_t register_lock;
 
 	void (* wbox_callback)(struct spu *spu);

linux-2.6-ps3-device-init.patch:

--- NEW FILE linux-2.6-ps3-device-init.patch ---
PS3 device init routines.

Signed-off-by: Geoff Levand <geoffrey.levand at am.sony.com>

---
 arch/powerpc/platforms/ps3/Makefile      |    1 
 arch/powerpc/platforms/ps3/device-init.c |  500 +++++++++++++++++++++++++++++++
 2 files changed, 501 insertions(+)

--- ps3-linux-dev.orig/arch/powerpc/platforms/ps3/Makefile
+++ ps3-linux-dev/arch/powerpc/platforms/ps3/Makefile
@@ -6,3 +6,4 @@ obj-$(CONFIG_PS3_STORAGE_ROM) += ps3rom.
 
 obj-$(CONFIG_SMP) += smp.o
 obj-$(CONFIG_SPU_BASE) += spu.o
+obj-y += device-init.o
\ No newline at end of file
--- /dev/null
+++ ps3-linux-dev/arch/powerpc/platforms/ps3/device-init.c
@@ -0,0 +1,500 @@
+/*
+ *  PS3 device init routines.
+ *
+ *  Copyright (C) 2006 Sony Computer Entertainment Inc.
+ *  Copyright 2006 Sony Corp.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; version 2 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#define DEBUG 1
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <asm/firmware.h>
+
+#include "platform.h"
+
+static int __devinit
+ps3_register_gelic (void)
+{
+	int result;
+	struct ps3_system_bus_device *dev;
+	struct ps3_repository_device repo;
+
+	pr_debug(" -> %s:%d\n", __func__, __LINE__);
+
+	/* Puts the regions at the end of the system_bus_device. */
+
+	dev = kzalloc(sizeof(struct ps3_system_bus_device)
+		+ sizeof(struct ps3_dma_region), GFP_KERNEL);
+
+	ps3_system_bus_device_init(dev,
+				   PS3_MATCH_ID_GELIC,
+				   NULL,
+				   NULL);
+
+	result = ps3_repository_find_first_device(PS3_BUS_TYPE_SB,
+		PS3_DEV_TYPE_SB_GELIC, &repo);
+
+	if (result) {
+		pr_debug("%s:%d ps3_repository_find_first_device failed\n",
+			__func__, __LINE__);
+		goto fail;
+	}
+
+	dev->did = repo.did;
+
+	result = ps3_repository_find_interrupt(&repo,
+		PS3_INTERRUPT_TYPE_EVENT_PORT, &dev->interrupt_id);
+
+	if (result) {
+		pr_debug("%s:%d ps3_repository_find_interrupt failed\n",
+			__func__, __LINE__);
+		goto fail;
+	}
+
+	BUG_ON(dev->interrupt_id != 0);
+
+	if (result) {
+		pr_debug("%s:%d ps3_repository_get_interrupt_id failed\n",
+			__func__, __LINE__);
+		goto fail;
+	}
+
+	dev->d_region = (struct ps3_dma_region *)((char*)dev
+		+ sizeof(struct ps3_system_bus_device));
+
+	ps3_dma_region_init(dev->d_region, &dev->did, PS3_DMA_64K,
+			    PS3_DMA_OTHER, NULL, 0, PS3_IOBUS_SB);
+
+	result = ps3_system_bus_device_register(dev, PS3_IOBUS_SB);
+
+	if (result) {
+		pr_debug("%s:%d ps3_system_bus_device_register failed\n",
+			__func__, __LINE__);
+		goto fail;
+	}
+
+	pr_debug(" <- %s:%d\n", __func__, __LINE__);
+	return result;
+
+fail:
+#if defined(DEBUG)
+	memset(dev, 0xad, sizeof(struct ps3_system_bus_device)
+		+ sizeof(struct ps3_dma_region));
+#endif
+	kfree(dev);
+	pr_debug(" <- %s:%d\n", __func__, __LINE__);
+	return result;
+}
+
+static int __devinit
+ps3_register_ohci_0 (void)
+{
+	int result;
+	struct ps3_repository_device repo;
+	u64 bus_addr;
+	u64 len;
+
+	/* Puts the regions at the end of the system_bus_device. */
+
+	struct ohci_layout {
+		struct ps3_system_bus_device dev;
+		struct ps3_dma_region d_region;
+		struct ps3_mmio_region m_region;
+	} *p;
+
+	pr_debug(" -> %s:%d\n", __func__, __LINE__);
+
+	p = kzalloc(sizeof(struct ohci_layout), GFP_KERNEL);
+
+	ps3_system_bus_device_init(&p->dev,
+				   PS3_MATCH_ID_OHCI,
+				   &p->d_region,
+				   &p->m_region);
+
+	result = ps3_repository_find_first_device(PS3_BUS_TYPE_SB,
+		PS3_DEV_TYPE_SB_USB, &repo);
+
+	if (result) {
+		pr_debug("%s:%d ps3_repository_find_device failed\n",
+			__func__, __LINE__);
+		goto fail;
+	}
+
+	p->dev.did = repo.did;
+
+	result = ps3_repository_find_interrupt(&repo,
+		PS3_INTERRUPT_TYPE_SB_OHCI, &p->dev.interrupt_id);
+
+	if (result) {
+		pr_debug("%s:%d ps3_repository_find_interrupt failed\n",
+			__func__, __LINE__);
+		goto fail;
+	}
+
+	ps3_repository_find_reg(&repo, PS3_REG_TYPE_SB_OHCI,
+		&bus_addr, &len);
+
+	BUG_ON(p->dev.interrupt_id != 16);
+	BUG_ON(bus_addr != 0x3010000);
+	BUG_ON(len != 0x10000);
+
+	ps3_dma_region_init(p->dev.d_region, &p->dev.did, PS3_DMA_64K,
+			    PS3_DMA_INTERNAL, NULL, 0, PS3_IOBUS_SB);
+
+	ps3_mmio_region_init(p->dev.m_region, &p->dev.did, bus_addr,
+			     len, PS3_MMIO_4K, PS3_IOBUS_SB);
+
+	result = ps3_system_bus_device_register(&p->dev, PS3_IOBUS_SB);
+
+	if (result)
+		pr_debug("%s:%d ps3_system_bus_device_register failed\n",
+			__func__, __LINE__);
+
+	pr_debug(" <- %s:%d\n", __func__, __LINE__);
+	return result;
+
+fail:
+#if defined(DEBUG)
+	memset(p, 0xad, sizeof(struct ohci_layout));
+#endif
+	kfree(p);
+	pr_debug(" <- %s:%d\n", __func__, __LINE__);
+	return result;
+}
+
+static int __devinit
+ps3_register_ohci_1 (void)
+{
+	int result;
+	struct ps3_repository_device repo;
+	u64 bus_addr;
+	u64 len;
+
+	/* Puts the regions at the end of the system_bus_device. */
+
+	struct ohci_layout {
+		struct ps3_system_bus_device dev;
+		struct ps3_dma_region d_region;
+		struct ps3_mmio_region m_region;
+	} *p;
+
+	pr_debug(" -> %s:%d\n", __func__, __LINE__);
+
+	p = kzalloc(sizeof(struct ohci_layout), GFP_KERNEL);
+
+	ps3_system_bus_device_init(&p->dev,
+				   PS3_MATCH_ID_OHCI,
+				   &p->d_region,
+				   &p->m_region);
+
+	result = ps3_repository_find_first_device(PS3_BUS_TYPE_SB,
+		PS3_DEV_TYPE_SB_USB, &repo);
+
+	if (result) {
+		pr_debug("%s:%d ps3_repository_find_device failed\n",
+			__func__, __LINE__);
+		goto fail;
+	}
+
+	result = ps3_repository_find_device(PS3_BUS_TYPE_SB,
+		PS3_DEV_TYPE_SB_USB, &repo, &repo);
+
+	if (result) {
+		pr_debug("%s:%d ps3_repository_find_device failed\n",
+			__func__, __LINE__);
+		goto fail;
+	}
+
+	p->dev.did = repo.did;
+
+	result = ps3_repository_find_interrupt(&repo,
+		PS3_INTERRUPT_TYPE_SB_OHCI, &p->dev.interrupt_id);
+
+	if (result) {
+		pr_debug("%s:%d ps3_repository_find_interrupt failed\n",
+			__func__, __LINE__);
+		goto fail;
+	}
+
+	ps3_repository_find_reg(&repo, PS3_REG_TYPE_SB_OHCI,
+		&bus_addr, &len);
+
+	BUG_ON(p->dev.interrupt_id != 17);
+	BUG_ON(bus_addr != 0x3020000);
+	BUG_ON(len != 0x10000);
+
+	ps3_dma_region_init(p->dev.d_region, &p->dev.did, PS3_DMA_64K,
+			    PS3_DMA_INTERNAL, NULL, 0, PS3_IOBUS_SB);
+
+	ps3_mmio_region_init(p->dev.m_region, &p->dev.did, bus_addr,
+			     len, PS3_MMIO_4K, PS3_IOBUS_SB);
+
+	result = ps3_system_bus_device_register(&p->dev, PS3_IOBUS_SB);
+
+	if (result)
+		pr_debug("%s:%d ps3_system_bus_device_register failed\n",
+			__func__, __LINE__);
+
+	pr_debug(" <- %s:%d\n", __func__, __LINE__);
+	return result;
+
+fail:
+#if defined(DEBUG)
+	memset(p, 0xad, sizeof(struct ohci_layout));
+#endif
+	kfree(p);
+	pr_debug(" <- %s:%d\n", __func__, __LINE__);
+	return result;
+}
+
+static int __devinit
+ps3_register_ehci_0 (void)
+{
+	int result;
+	struct ps3_repository_device repo;
+	u64 bus_addr;
+	u64 len;
+
+	/* Puts the regions at the end of the system_bus_device. */
+
+	struct ehci_layout {
+		struct ps3_system_bus_device dev;
+		struct ps3_dma_region d_region;
+		struct ps3_mmio_region m_region;
+	} *p;
+
+	pr_debug(" -> %s:%d\n", __func__, __LINE__);
+
+	p = kzalloc(sizeof(struct ehci_layout), GFP_KERNEL);
+
+	ps3_system_bus_device_init(&p->dev,
+				   PS3_MATCH_ID_EHCI,
+				   &p->d_region,
+				   &p->m_region);
+
+	result = ps3_repository_find_first_device(PS3_BUS_TYPE_SB,
+		PS3_DEV_TYPE_SB_USB, &repo);
+
+	if (result) {
+		pr_debug("%s:%d ps3_repository_find_device failed\n",
+			__func__, __LINE__);
+		goto fail;
+	}
+
+	p->dev.did = repo.did;
+
+	result = ps3_repository_find_interrupt(&repo,
+		PS3_INTERRUPT_TYPE_SB_EHCI, &p->dev.interrupt_id);
+
+	if (result) {
+		pr_debug("%s:%d ps3_repository_find_interrupt failed\n",
+			__func__, __LINE__);
+		goto fail;
+	}
+
+	ps3_repository_find_reg(&repo, PS3_REG_TYPE_SB_EHCI,
+		&bus_addr, &len);
+
+	BUG_ON(p->dev.interrupt_id != 10);
+	BUG_ON(bus_addr != 0x3810000);
+	BUG_ON(len != 0x10000);
+
+	ps3_dma_region_init(p->dev.d_region, &p->dev.did, PS3_DMA_64K,
+			    PS3_DMA_INTERNAL, NULL, 0, PS3_IOBUS_SB);
+
+	ps3_mmio_region_init(p->dev.m_region, &p->dev.did, bus_addr,
+			     len, PS3_MMIO_4K, PS3_IOBUS_SB);
+
+	result = ps3_system_bus_device_register(&p->dev, PS3_IOBUS_SB);
+
+	if (result)
+		pr_debug("%s:%d ps3_system_bus_device_register failed\n",
+			__func__, __LINE__);
+
+	pr_debug(" <- %s:%d\n", __func__, __LINE__);
+	return result;
+
+fail:
+#if defined(DEBUG)
+	memset(p, 0xad, sizeof(struct ehci_layout));
+#endif
+	kfree(p);
+	pr_debug(" <- %s:%d\n", __func__, __LINE__);
+	return result;
+}
+
+static int __devinit
+ps3_register_ehci_1 (void)
+{
+	int result;
+	struct ps3_repository_device repo;
+	u64 bus_addr;
+	u64 len;
+
+	/* Puts the regions at the end of the system_bus_device. */
+
+	struct ehci_layout {
+		struct ps3_system_bus_device dev;
+		struct ps3_dma_region d_region;
+		struct ps3_mmio_region m_region;
+	} *p;
+
+	pr_debug(" -> %s:%d\n", __func__, __LINE__);
+
+	p = kzalloc(sizeof(struct ehci_layout), GFP_KERNEL);
+
+	ps3_system_bus_device_init(&p->dev,
+				   PS3_MATCH_ID_EHCI,
+				   &p->d_region,
+				   &p->m_region);
+
+	result = ps3_repository_find_first_device(PS3_BUS_TYPE_SB,
+		PS3_DEV_TYPE_SB_USB, &repo);
+
+	if (result) {
+		pr_debug("%s:%d ps3_repository_find_device failed\n",
+			__func__, __LINE__);
+		goto fail;
+	}
+
+	result = ps3_repository_find_device(PS3_BUS_TYPE_SB,
+		PS3_DEV_TYPE_SB_USB, &repo, &repo);
+
+	if (result) {
+		pr_debug("%s:%d ps3_repository_find_device failed\n",
+			__func__, __LINE__);
+		goto fail;
+	}
+
+	p->dev.did = repo.did;
+
+	result = ps3_repository_find_interrupt(&repo,
+		PS3_INTERRUPT_TYPE_SB_EHCI, &p->dev.interrupt_id);
+
+	if (result) {
+		pr_debug("%s:%d ps3_repository_find_interrupt failed\n",
+			__func__, __LINE__);
+		goto fail;
+	}
+
+	ps3_repository_find_reg(&repo, PS3_REG_TYPE_SB_EHCI,
+		&bus_addr, &len);
+
+	BUG_ON(p->dev.interrupt_id != 11);
+	BUG_ON(bus_addr != 0x3820000);
+	BUG_ON(len != 0x10000);
+
+	ps3_dma_region_init(p->dev.d_region, &p->dev.did, PS3_DMA_64K,
+			    PS3_DMA_INTERNAL, NULL, 0, PS3_IOBUS_SB);
+
+	ps3_mmio_region_init(p->dev.m_region, &p->dev.did, bus_addr,
+			     len, PS3_MMIO_4K, PS3_IOBUS_SB);
+
+	result = ps3_system_bus_device_register(&p->dev, PS3_IOBUS_SB);
+
+	if (result)
+		pr_debug("%s:%d ps3_system_bus_device_register failed\n",
+			__func__, __LINE__);
+
+	pr_debug(" <- %s:%d\n", __func__, __LINE__);
+	return result;
+
+fail:
+#if defined(DEBUG)
+	memset(p, 0xad, sizeof(struct ehci_layout));
+#endif
+	kfree(p);
+	pr_debug(" <- %s:%d\n", __func__, __LINE__);
+	return result;
+}
+
+static int __devinit ps3_register_sound(void)
+{
+	int result;
+
+	struct snd_ps3_layout {
+		struct ps3_system_bus_device dev;
+		struct ps3_dma_region d_region;
+		struct ps3_mmio_region m_region;
+	} *p;
+
+	p = kzalloc(sizeof(*p), GFP_KERNEL);
+	if (!p)
+		return -ENOMEM;
+
+	ps3_system_bus_device_init(&p->dev, PS3_MATCH_ID_SOUND,
+				   &p->d_region,
+				   &p->m_region);
+
+#warning need device specific data here
+
+	result = ps3_system_bus_device_register(&p->dev, PS3_IOBUS_IOC0);
+
+	if (result)
+		kfree(p);
+
+	return result;
+}
+
+static int __devinit
+ps3_register_sys_manager (void)
+{
+	int result;
+	static struct ps3_vuart_port_device dev = {
+		.match_id = PS3_MATCH_ID_SYSTEM_MANAGER,
+	};
+
+	pr_debug(" -> %s:%d\n", __func__, __LINE__);
+
+	result = ps3_vuart_port_device_register(&dev);
+
+	if (result)
+		pr_debug("%s:%d ps3_vuart_port_device_register failed\n",
+			__func__, __LINE__);
+
+	pr_debug(" <- %s:%d\n", __func__, __LINE__);
+	return result;
+}
+
+int __init
+ps3_register_known_devices (void)
+{
+	int result;
+
+	if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
+		return -ENODEV;
+
+	pr_debug(" -> %s:%d\n", __func__, __LINE__);
+
+	//ps3_repository_dump_bus_info();
+
+	result = ps3_register_ohci_0();
+	result = ps3_register_ehci_0();
+	result = ps3_register_ohci_1();
+	result = ps3_register_ehci_1();
+	result = ps3_register_sound();
+
+#if defined(CONFIG_PS3_SYS_MANAGER)
+	result = ps3_register_sys_manager();
+#endif
+	result = ps3_register_gelic();
+
+	pr_debug(" <- %s:%d\n", __func__, __LINE__);
+	return result;
+}
+
+device_initcall(ps3_register_known_devices);

linux-2.6-ps3-ehci-iso.patch:

--- NEW FILE linux-2.6-ps3-ehci-iso.patch ---
From: Masashi Kimoto <Masashi_Kimoto at hq.scei.sony.co.jp>

When we use Linux git tree on PS3 we face a error msg from 
ps3-ehci-driver,
        ps3-ehci-driver sb_04: port 1 resume error -19
        hub 2-0:1.0: hub_port_status failed (err = -32)
        ...
Built-in Bluetooth uses a USB isochronous and causes this error.

USB host controller refers TD after echi driver modify it's Periodic Frame 
List.
Because of this, NULLed TD is asscessed and causes USB error.

In this patch the driver holds the TD while host controller refers the 
list after Active bit=0.

From: Masashi Kimoto <Masashi_Kimoto at hq.scei.sony.co.jp>
Signed-off-by: Geoff Levand <geoffrey.levand at am.sony.com>

---
 drivers/usb/host/ehci-sched.c |   34 ++++++++++++++++++++++++++++++----
 1 file changed, 30 insertions(+), 4 deletions(-)

--- ps3-linux-dev.orig/drivers/usb/host/ehci-sched.c
+++ ps3-linux-dev/drivers/usb/host/ehci-sched.c
@@ -1168,8 +1168,21 @@ itd_urb_transaction (
 		if (likely (!list_empty(&stream->free_list))) {
 			itd = list_entry (stream->free_list.prev,
 					 struct ehci_itd, itd_list);
-			list_del (&itd->itd_list);
-			itd_dma = itd->itd_dma;
+#if defined(CONFIG_PPC_PS3)
+			/* Fix for Cell SCC ISO transfer (PS3 Bluetooth). */
+			if (firmware_has_feature(FW_FEATURE_PS3_LV1)
+				&& itd->frame == ((ehci_readl(ehci,
+				&ehci->regs->frame_index) >> 3)
+				% ehci->periodic_size))
+				itd = NULL;
+			else {
+				list_del (&itd->itd_list);
+				itd_dma = itd->itd_dma;
+			}
+#else
+                       list_del (&itd->itd_list);
+                       itd_dma = itd->itd_dma;
+#endif
 		} else
 			itd = NULL;
 
@@ -1784,8 +1797,21 @@ sitd_urb_transaction (
 		if (!list_empty(&stream->free_list)) {
 			sitd = list_entry (stream->free_list.prev,
 					 struct ehci_sitd, sitd_list);
-			list_del (&sitd->sitd_list);
-			sitd_dma = sitd->sitd_dma;
+#if defined(CONFIG_PPC_PS3)
+			/* Fix for Cell SCC ISO transfer (PS3 Bluetooth). */
+			if (firmware_has_feature(FW_FEATURE_PS3_LV1)
+				&& sitd->frame == ((ehci_readl(ehci,
+				&ehci->regs->frame_index) >> 3)
+				% ehci->periodic_size))
+				sitd = NULL;
+			else {
+				list_del (&sitd->sitd_list);
+				sitd_dma = sitd->sitd_dma;
+			}
+#else
+                       list_del (&sitd->sitd_list);
+                       sitd_dma = sitd->sitd_dma;
+#endif
 		} else
 			sitd = NULL;
 

linux-2.6-ps3-ethernet-autoload.patch:

--- NEW FILE linux-2.6-ps3-ethernet-autoload.patch ---
--- linux-2.6.20.ppc64/drivers/net/gelic_net.c	2007-03-30 18:35:11.000000000 +0100
+++ linux-2.6.20.ps3/drivers/net/gelic_net.c	2007-03-30 22:50:00.000000000 +0100
@@ -1875,3 +1886,4 @@ static int __init early_param_gelic_net(
 }
 early_param("gelic_vlan", early_param_gelic_net);
 #endif
+MODULE_ALIAS("ps3:3");

linux-2.6-ps3-ethernet-modular.patch:

--- NEW FILE linux-2.6-ps3-ethernet-modular.patch ---
diff --git a/drivers/net/gelic_net.c b/drivers/net/gelic_net.c
index f931bc7..48ad627 100644
--- a/drivers/net/gelic_net.c
+++ b/drivers/net/gelic_net.c
@@ -73,8 +73,9 @@ static int ps3_gelic_param = 1; /* vlan desc support */
 module_param(ps3_gelic_param, int, S_IRUGO);
 #endif
 
-struct gelic_net_card *gcard;
-static uint64_t gelic_irq_status;
+static struct gelic_net_card *gcard;
+static uint64_t *gelic_irq_status;
+
 
 static int dmac_status = 0;
 
@@ -838,7 +839,7 @@ gelic_net_kick_txdma(struct gelic_net_card *card,
 		}
 		if (!count) {
 			printk("lv1_net_start_txdma failed, status=%ld %016lx\n",\
-				status, gelic_irq_status);
+				status, *gelic_irq_status);
 		}
 	}
 }
@@ -1130,7 +1131,7 @@ gelic_net_interrupt(int irq, void *ptr)
 	unsigned long flags;
 	uint64_t status;
 
-	status = gelic_irq_status;
+	status = *gelic_irq_status;
 	rmb();
 	status0 = (uint32_t)(status >> 32);
 	status1 = (uint32_t)(status & 0xffffffff);
@@ -1632,6 +1633,12 @@ gelic_net_alloc_card(void)
 	if (!netdev)
 		return NULL;
 
+	gelic_irq_status = kzalloc(sizeof(*gelic_irq_status), GFP_DMA);
+	if (!gelic_irq_status) {
+		free_netdev(netdev);
+		return NULL;
+	}
+
 	card = netdev_priv(netdev);
 	card->netdev = netdev;
 	INIT_WORK(&card->tx_timeout_task, gelic_net_tx_timeout_task);
@@ -1677,7 +1684,7 @@ static int ps3_gelic_driver_probe (struct ps3_system_bus_device *dev)
 	}
 
 	result = lv1_net_set_interrupt_status_indicator(dev->did.bus_id,
-		dev->did.dev_id, ps3_mm_phys_to_lpar(__pa(&gelic_irq_status)),
+		dev->did.dev_id, ps3_mm_phys_to_lpar(__pa(gelic_irq_status)),
 		0);
 
 	if (result) {
@@ -1706,6 +1713,8 @@ fail_status_indicator:
 fail_dma_region:
 	ps3_close_hv_device(&dev->did);
 fail_open:
+	kfree(gelic_irq_status);
+	gelic_irq_status = NULL;
 	free_netdev(gcard->netdev); // enough???
 	gcard = NULL;
 fail_alloc_card:
@@ -1732,6 +1741,8 @@ ps3_gelic_driver_remove (struct ps3_system_bus_device *dev)
 		   atomic_read(&card->tx_timeout_task_counter) == 0);
 
 	unregister_netdev(netdev);
+	kfree(gelic_irq_status);
+	gelic_irq_status = NULL;
 	free_netdev(netdev);
 
 	lv1_net_set_interrupt_status_indicator(dev->did.bus_id, dev->did.dev_id,

linux-2.6-ps3-gelic-wireless.patch:

--- NEW FILE linux-2.6-ps3-gelic-wireless.patch ---
As of 2007-05-04 (commit 197a8b29cbb721909e1bde44c6e7a588d93ba440):

ps3-wip/ps3-gelic_wireless_base.diff
ps3-wip/ps3-gelic_wireless_kern16.diff
ps3-wip/ps3-gelic_wireless_kern21.diff
ps3-wip/ps3-gelic_wireless_wext.diff


diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 7876697..ea828bf 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2270,6 +2270,13 @@ config GELIC_NET
 	  To compile this driver as a module, choose M here: the
 	  module will be called gelic_net.
 
+config GELIC_WIRELESS
+	bool "Gelic net Wireless Extension"
+	depends on GELIC_NET
+	select WIRELESS_EXT
+	help
+	  Wireless Extension support for Gelic Gigabit Ethernet driver
+
 config GIANFAR
 	tristate "Gianfar Ethernet"
 	depends on 85xx || 83xx || PPC_86xx
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 9fa106a..704b839 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -61,6 +61,9 @@ obj-$(CONFIG_BNX2) += bnx2.o
 spidernet-y += spider_net.o spider_net_ethtool.o
 obj-$(CONFIG_SPIDER_NET) += spidernet.o sungem_phy.o
 obj-$(CONFIG_GELIC_NET) += gelic_net.o
+ifeq ($(CONFIG_GELIC_WIRELESS),y)
+  obj-$(CONFIG_GELIC_NET) += gelic_wireless.o
+endif
 obj-$(CONFIG_TC35815) += tc35815.o
 obj-$(CONFIG_SKGE) += skge.o
 obj-$(CONFIG_SKY2) += sky2.o
diff --git a/drivers/net/gelic_net.c b/drivers/net/gelic_net.c
index 79ca65f..f931bc7 100644
--- a/drivers/net/gelic_net.c
+++ b/drivers/net/gelic_net.c
@@ -60,145 +60,13 @@
 #include <asm/ps3.h>
 #include <asm/lv1call.h>
 
-#define GELIC_NET_DRV_NAME "Gelic Network Driver"
-#define GELIC_NET_DRV_VERSION "1.0"
-
-#define GELIC_NET_DEBUG
-
-#ifdef GELIC_NET_DEBUG
-#define DPRINTK(fmt,arg...)   printk(KERN_ERR fmt ,##arg)
-#define DPRINTKK(fmt,arg...)  printk(KERN_ERR fmt ,##arg)
-#else
-#define DPRINTK(fmt,arg...)
-#define DPRINTKK(fmt,arg...)
+#ifdef CONFIG_GELIC_WIRELESS
+#include "gelic_wireless.h"
 #endif
+#include "gelic_net.h"
 
-#define GELIC_NET_ETHTOOL               /* use ethtool */
-
-/* ioctl */
-#define GELIC_NET_GET_MODE              (SIOCDEVPRIVATE + 0)
-#define GELIC_NET_SET_MODE              (SIOCDEVPRIVATE + 1)
-
-/* descriptors */
-#define GELIC_NET_RX_DESCRIPTORS        128 /* num of descriptors */
-#define GELIC_NET_TX_DESCRIPTORS        128 /* num of descriptors */
-
-#define GELIC_NET_MAX_MTU               2308
-#define GELIC_NET_MIN_MTU               64
-#define GELIC_NET_RXBUF_ALIGN           128
-#define GELIC_NET_RX_CSUM_DEFAULT       1 /* hw chksum */
-#define GELIC_NET_WATCHDOG_TIMEOUT      5*HZ
-#define GELIC_NET_NAPI_WEIGHT           64
-#define GELIC_NET_BROADCAST_ADDR        0xffffffffffff
-#define GELIC_NET_VLAN_POS              (VLAN_ETH_ALEN * 2)
-#define GELIC_NET_VLAN_MAX              4
-#define GELIC_NET_MC_COUNT_MAX          32 /* multicast address list */
-
-enum gelic_net_int0_status {
-	GELIC_NET_GDTDCEINT  = 24,
-	GELIC_NET_GRFANMINT  = 28,
-};
-
-/* GHIINT1STS bits */
-enum gelic_net_int1_status {
-	GELIC_NET_GDADCEINT = 14,
-};
-
-/* interrupt mask */
-#define GELIC_NET_TXINT                   (1L << (GELIC_NET_GDTDCEINT + 32))
-
-#define GELIC_NET_RXINT0                  (1L << (GELIC_NET_GRFANMINT + 32))
-#define GELIC_NET_RXINT1                  (1L << GELIC_NET_GDADCEINT)
-#define GELIC_NET_RXINT                   (GELIC_NET_RXINT0 | GELIC_NET_RXINT1)
-
- /* descriptor data_status bits */
-#define GELIC_NET_RXIPCHK                 29
-#define GELIC_NET_TCPUDPIPCHK             28
-#define GELIC_NET_DATA_STATUS_CHK_MASK    (1 << GELIC_NET_RXIPCHK | \
-                                           1 << GELIC_NET_TCPUDPIPCHK)
-
-/* descriptor data_error bits */
-#define GELIC_NET_RXIPCHKERR              27
-#define GELIC_NET_RXTCPCHKERR             26
-#define GELIC_NET_DATA_ERROR_CHK_MASK     (1 << GELIC_NET_RXIPCHKERR | \
-                                           1 << GELIC_NET_RXTCPCHKERR)
-
-#define GELIC_NET_DMAC_CMDSTAT_NOCS       0xa0080000 /* middle of frame */
-#define GELIC_NET_DMAC_CMDSTAT_TCPCS      0xa00a0000
-#define GELIC_NET_DMAC_CMDSTAT_UDPCS      0xa00b0000
-#define GELIC_NET_DMAC_CMDSTAT_END_FRAME  0x00040000 /* end of frame */
-
-#define GELIC_NET_DMAC_CMDSTAT_CHAIN_END  0x00000002 /* RXDCEIS:DMA stopped */
-
-#define GELIC_NET_DESCR_IND_PROC_SHIFT    28
-#define GELIC_NET_DESCR_IND_PROC_MASKO    0x0fffffff
-
-/* ignore ipsec ans multicast */
-#define GELIC_NET_DATA_ERROR_MASK         0xfdefbfff
-/* ignore unmatched sp on sp, drop_packet, multicast address frame*/
-#define GELIC_NET_DATA_ERROR_FLG          0x7def8000
-
-enum gelic_net_descr_status {
-	GELIC_NET_DESCR_COMPLETE            = 0x00, /* used in rx and tx */
-	GELIC_NET_DESCR_RESPONSE_ERROR      = 0x01, /* used in rx and tx */
-	GELIC_NET_DESCR_PROTECTION_ERROR    = 0x02, /* used in rx and tx */
-	GELIC_NET_DESCR_FRAME_END           = 0x04, /* used in rx */
-	GELIC_NET_DESCR_FORCE_END           = 0x05, /* used in rx and tx */
-	GELIC_NET_DESCR_CARDOWNED           = 0x0a, /* used in rx and tx */
-	GELIC_NET_DESCR_NOT_IN_USE                  /* any other value */
-};
-#define GELIC_NET_DMAC_CMDSTAT_NOT_IN_USE 0xb0000000
-
-#define GELIC_NET_DESCR_SIZE              32
-struct gelic_net_descr {
-	/* as defined by the hardware */
-	uint32_t buf_addr;
-	uint32_t buf_size;
-	uint32_t next_descr_addr;
-	uint32_t dmac_cmd_status;
-	uint32_t result_size;
-	uint32_t valid_size;	/* all zeroes for tx */
-	uint32_t data_status;
-	uint32_t data_error;	/* all zeroes for tx */
-
-	/* used in the driver */
-	struct sk_buff *skb;
-	dma_addr_t bus_addr;
-	struct gelic_net_descr *next;
-	struct gelic_net_descr *prev;
-	struct vlan_ethhdr vlan;
-} __attribute__((aligned(32)));
-
-struct gelic_net_descr_chain {
-	/* we walk from tail to head */
-	struct gelic_net_descr *head;
-	struct gelic_net_descr *tail;
-	spinlock_t lock;
-};
-
-struct gelic_net_card {
-	struct net_device *netdev;
-	uint64_t ghiintmask;
-	struct ps3_system_bus_device *dev;
-	uint32_t vlan_id[GELIC_NET_VLAN_MAX];
-	int vlan_index;
-
-	struct gelic_net_descr_chain tx_chain;
-	struct gelic_net_descr_chain rx_chain;
-	spinlock_t chain_lock;
-
-	struct net_device_stats netdev_stats;
-	int rx_csum;
-	spinlock_t intmask_lock;
-
-	struct work_struct tx_timeout_task;
-	atomic_t tx_timeout_task_counter;
-	wait_queue_head_t waitq;
-
-	struct gelic_net_descr *tx_top, *rx_top;
-
-	struct gelic_net_descr descr[0];
-};
+#define GELIC_NET_DRV_NAME "Gelic Network Driver"
+#define GELIC_NET_DRV_VERSION "1.0"
 
 static int ps3_gelic_param = 1; /* vlan desc support */
 #ifdef CONFIG_GELIC_NET_MODULE
@@ -210,33 +78,6 @@ static uint64_t gelic_irq_status;
 
 static int dmac_status = 0;
 
[...2575 lines suppressed...]
+#define MAX_SCAN_BSS			16
+
+#define GELICW_SCAN_INTERVAL		(HZ)
+
+#ifdef DEBUG
+#define CH_INFO_FAIL 0x0600 /* debug */
+#else
+#define CH_INFO_FAIL 0
+#endif
+
+struct gelicw_bss {
+	u8 bssid[ETH_ALEN];
+	u8 channel;
+	u8 mode;
+	u8 essid_len;
+	u8 essid[IW_ESSID_MAX_SIZE + 1]; /* null terminated for debug msg */
+
+	u16 capability;
+	u16 beacon_interval;
+
+	u8 rates_len;
+	u8 rates[MAX_RATES_LENGTH];
+	u8 rates_ex_len;
+	u8 rates_ex[MAX_RATES_EX_LENGTH];
+	u8 rssi;
+
+	/* scan results have sec_info instead of rsn_ie or wpa_ie */
+	u16 sec_info;
+};
+
+struct gelic_wireless {
+	struct gelic_net_card *card;
+	struct completion cmd_done, rssi_done;
+	struct work_struct work_event, work_start_done;
+	struct delayed_work work_rssi, work_scan_all, work_scan_essid;
+	struct delayed_work work_common, work_encode;
+	struct delayed_work work_start, work_stop, work_roam;
+	wait_queue_head_t waitq_cmd, waitq_scan;
+
+	u64 cmd_tag, cmd_id;
+	u8 cmd_send_flg;
+
+	struct iw_public_data wireless_data;
+	u8 *data_buf; /* data buffer for lv1_net_control */
+
+	u8 wireless; /* wireless support */
+	u8 state;
+	u8 scan_all; /* essid scan or all scan */
+	u8 essid_search; /* essid background scan */
+	u8 is_assoc;
+
+	u16 ch_info; /* supoprted channels */
+	u8 wireless_mode; /* 11b/g */
+	u8 channel; /* current ch */
+	u8 iw_mode; /* INFRA or Ad-hoc */
+	u8 rssi;
+	u8 essid_len;
+	u8 essid[IW_ESSID_MAX_SIZE + 1]; /* null terminated for debug msg */
+	u8 nick[IW_ESSID_MAX_SIZE + 1];
+	u8 bssid[ETH_ALEN];
+
+	u8 key_index;
+	u8 key[WEP_KEYS][IW_ENCODING_TOKEN_MAX]; /* 4 * 64byte */
+	u8 key_len[WEP_KEYS];
+	u8 key_alg; /* key algorithm  */
+	u8 auth_mode; /* authenticaton mode */
+
+	u8 bss_index; /* current bss in bss_list */
+	u8 num_bss_list;
+	u8 bss_key_alg; /* key alg of bss */
+	u8 wap_bssid[ETH_ALEN];
+	unsigned long last_scan; /* last scan time */
+	struct gelicw_bss current_bss;
+	struct gelicw_bss bss_list[MAX_SCAN_BSS];
+};
+
+/* net_control command */
+#define GELICW_SET_PORT			3 /* control Ether port */
+#define GELICW_GET_INFO			6 /* get supported channels */
+#define GELICW_SET_CMD			9 /* set configuration */
+#define GELICW_GET_RES			10 /* get command response */
+#define GELICW_GET_EVENT		11 /* get event from device */
+/* net_control command data buffer */
+#define GELICW_DATA_BUF_SIZE		0x1000
+
+/* GELICW_SET_CMD params */
+#define GELICW_CMD_START		1
+#define GELICW_CMD_STOP			2
+#define GELICW_CMD_SCAN			3
+#define GELICW_CMD_GET_SCAN		4
+#define GELICW_CMD_SET_CONFIG		5
+#define GELICW_CMD_GET_CONFIG		6
+#define GELICW_CMD_SET_WEP		7
+#define GELICW_CMD_GET_WEP		8
+#define GELICW_CMD_SET_WPA		9
+#define GELICW_CMD_GET_WPA		10
+#define GELICW_CMD_GET_RSSI		11
+
+/* GELICW_SET_PORT params */
+#define GELICW_ETHER_PORT		2
+#define GELICW_PORT_DOWN		0 /* Ether port off */
+#define GELICW_PORT_UP			4 /* Ether port on (auto neg) */
+
+/* interrupt status bit */
+#define GELICW_DEVICE_CMD_COMP		0x0000000080000000UL
+#define GELICW_DEVICE_EVENT_RECV	0x0000000040000000UL
+
+/* GELICW_GET_EVENT ID */
+#define GELICW_EVENT_UNKNOWN		0x00
+#define GELICW_EVENT_DEVICE_READY	0x01
+#define GELICW_EVENT_SCAN_COMPLETED	0x02
+#define GELICW_EVENT_DEAUTH		0x04
+#define GELICW_EVENT_BEACON_LOST	0x08
+#define GELICW_EVENT_CONNECTED		0x10
+#define GELICW_EVENT_WPA_CONNECTED	0x20
+#define GELICW_EVENT_WPA_ERROR		0x40
+#define GELICW_EVENT_NO_ENTRY		(-6)
+
+#define MAX_IW_PRIV_SIZE		32
+
+/* structure of data buffer for lv1_net_contol */
+/* wep_config: sec */
+#define GELICW_WEP_SEC_NONE		0
+#define GELICW_WEP_SEC_40BIT		1
+#define GELICW_WEP_SEC_104BIT		2
+struct wep_config {
+	u16 sec;
+	u8  key[4][16];
+} __attribute__ ((packed));
+
+/* wpa_config: sec */
+#define GELICW_WPA_SEC_NONE		0
+#define GELICW_WPA_SEC_TKIP		1
+#define GELICW_WPA_SEC_AES		2
+/* wpa_config: psk_type */
+#define GELICW_PSK_PASSPHRASE		0
+#define GELICW_PSK_64HEX		1
+struct wpa_config {
+	u16 sec;
+	u16 psk_type;
+	u8  psk_material[64]; /* key */
+} __attribute__ ((packed));
+
+/* common_config: bss_type */
+#define GELICW_BSS_INFRA		0
+#define GELICW_BSS_ADHOC		1
+/* common_config: auth_method */
+#define GELICW_AUTH_OPEN		0
+#define GELICW_AUTH_SHARED		1
+/* common_config: op_mode */
+#define GELICW_OP_MODE_11BG		0
+#define GELICW_OP_MODE_11B		1
+#define GELICW_OP_MODE_11G		2
+struct common_config {
+	u16 scan_index; /* index of scan_desc list */
+	u16 bss_type;
+	u16 auth_method;
+	u16 op_mode;
+} __attribute__ ((packed));
+
+/* scan_descriptor: security */
+#define GELICW_SEC_TYPE_NONE		0x0000
+#define GELICW_SEC_TYPE_WEP		0x0100
+#define GELICW_SEC_TYPE_WEP40		0x0101
+#define GELICW_SEC_TYPE_WEP104		0x0102
+#define GELICW_SEC_TYPE_TKIP		0x0201
+#define GELICW_SEC_TYPE_AES		0x0202
+#define GELICW_SEC_TYPE_WEP_MASK	0xFF00
+struct scan_desc {
+	u16 size;
+	u16 rssi;
+	u16 channel;
+	u16 beacon_period;
+	u16 capability;
+	u16 security;
+	u64 bssid;
+	u8  essid[32];
+	u8  rate[16];
+	u8  ext_rate[16];
+	u32 reserved1;
+	u32 reserved2;
+	u32 reserved3;
+	u32 reserved4;
+} __attribute__ ((packed));
+
+/* rssi_descriptor */
+struct rssi_desc {
+	u16 rssi; /* max rssi = 100 */
+} __attribute__ ((packed));
+
+
+extern unsigned long p_to_lp(long pa);
+extern int gelicw_setup_netdev(struct net_device *netdev, int wi);
+extern void gelicw_up(struct net_device *netdev);
+extern int gelicw_down(struct net_device *netdev);
+extern void gelicw_remove(struct net_device *netdev);
+extern void gelicw_interrupt(struct net_device *netdev, u32 status1);
+extern int gelicw_is_associated(struct net_device *netdev);
+
+#endif //  _GELIC_WIRELESS_H_

linux-2.6-ps3-gelic.patch:

--- NEW FILE linux-2.6-ps3-gelic.patch ---
As of 2007-05-04 (commit 197a8b29cbb721909e1bde44c6e7a588d93ba440):

ps3-wip/ps3-gelic.patch
ps3-wip/ps3-gelic-2.6.21-version-up.diff
ps3-wip/ps3-gelic-system-bus.patch
ps3-wip/ps3-gelic-fix-ipv6.diff

+ s/ip_hdr(skb)/skb->nh.iph/ to work on 2.6.21

diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index dcdad21..7876697 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2260,6 +2260,16 @@ config TSI108_ETH
 	     To compile this driver as a module, choose M here: the module
 	     will be called tsi108_eth.
 
+config GELIC_NET
+	tristate "PS3 Gigabit Ethernet driver"
+	depends on PPC_PS3
+	help
+	  This driver supports the Gigabit Ethernet device on the
+	  PS3 game console.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called gelic_net.
+
 config GIANFAR
 	tristate "Gianfar Ethernet"
 	depends on 85xx || 83xx || PPC_86xx
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 59c0459..9fa106a 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -60,6 +60,7 @@ obj-$(CONFIG_TIGON3) += tg3.o
 obj-$(CONFIG_BNX2) += bnx2.o
 spidernet-y += spider_net.o spider_net_ethtool.o
 obj-$(CONFIG_SPIDER_NET) += spidernet.o sungem_phy.o
+obj-$(CONFIG_GELIC_NET) += gelic_net.o
 obj-$(CONFIG_TC35815) += tc35815.o
 obj-$(CONFIG_SKGE) += skge.o
 obj-$(CONFIG_SKY2) += sky2.o
--- /dev/null	2007-05-01 15:16:24.100521312 +0100
+++ b/drivers/net/gelic_net.c	2007-05-04 11:35:42.000000000 +0100
@@ -0,0 +1,1919 @@
+/*
+ *  PS3 Platfom gelic network driver.
+ *
+ * Copyright (C) 2006 Sony Computer Entertainment Inc.
+ *
+ *  this file is based on: spider_net.c
+ *
+ * Network device driver for Cell Processor-Based Blade
+ *
+ * (C) Copyright IBM Corp. 2005
+ *
+ * Authors : Utz Bacher <utz.bacher at de.ibm.com>
+ *           Jens Osterkamp <Jens.Osterkamp at de.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, 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.
+ */
+
+#define DEBUG 1
+
+#include <linux/compiler.h>
+#include <linux/crc32.h>
+#include <linux/delay.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/firmware.h>
+#include <linux/if_vlan.h>
+#include <linux/in.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/ip.h>
+#include <linux/kernel.h>
+#include <linux/mii.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/device.h>
+#include <linux/pci.h>
+#include <linux/skbuff.h>
+#include <linux/slab.h>
+#include <linux/tcp.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <linux/workqueue.h>
+#include <asm/bitops.h>
+#include <asm/pci-bridge.h>
+#include <net/checksum.h>
+#include <asm/io.h>
+#include <asm/firmware.h>
+#include <asm/ps3.h>
+#include <asm/lv1call.h>
+
+#define GELIC_NET_DRV_NAME "Gelic Network Driver"
+#define GELIC_NET_DRV_VERSION "1.0"
+
+#define GELIC_NET_DEBUG
+
+#ifdef GELIC_NET_DEBUG
+#define DPRINTK(fmt,arg...)   printk(KERN_ERR fmt ,##arg)
+#define DPRINTKK(fmt,arg...)  printk(KERN_ERR fmt ,##arg)
+#else
+#define DPRINTK(fmt,arg...)
+#define DPRINTKK(fmt,arg...)
+#endif
+
+#define GELIC_NET_ETHTOOL               /* use ethtool */
+
+/* ioctl */
+#define GELIC_NET_GET_MODE              (SIOCDEVPRIVATE + 0)
+#define GELIC_NET_SET_MODE              (SIOCDEVPRIVATE + 1)
+
+/* descriptors */
+#define GELIC_NET_RX_DESCRIPTORS        128 /* num of descriptors */
+#define GELIC_NET_TX_DESCRIPTORS        128 /* num of descriptors */
+
+#define GELIC_NET_MAX_MTU               2308
+#define GELIC_NET_MIN_MTU               64
+#define GELIC_NET_RXBUF_ALIGN           128
+#define GELIC_NET_RX_CSUM_DEFAULT       1 /* hw chksum */
+#define GELIC_NET_WATCHDOG_TIMEOUT      5*HZ
+#define GELIC_NET_NAPI_WEIGHT           64
+#define GELIC_NET_BROADCAST_ADDR        0xffffffffffff
+#define GELIC_NET_VLAN_POS              (VLAN_ETH_ALEN * 2)
+#define GELIC_NET_VLAN_MAX              4
+#define GELIC_NET_MC_COUNT_MAX          32 /* multicast address list */
+
+enum gelic_net_int0_status {
+	GELIC_NET_GDTDCEINT  = 24,
+	GELIC_NET_GRFANMINT  = 28,
+};
+
+/* GHIINT1STS bits */
+enum gelic_net_int1_status {
+	GELIC_NET_GDADCEINT = 14,
+};
+
+/* interrupt mask */
+#define GELIC_NET_TXINT                   (1L << (GELIC_NET_GDTDCEINT + 32))
+
+#define GELIC_NET_RXINT0                  (1L << (GELIC_NET_GRFANMINT + 32))
+#define GELIC_NET_RXINT1                  (1L << GELIC_NET_GDADCEINT)
+#define GELIC_NET_RXINT                   (GELIC_NET_RXINT0 | GELIC_NET_RXINT1)
+
+ /* descriptor data_status bits */
+#define GELIC_NET_RXIPCHK                 29
+#define GELIC_NET_TCPUDPIPCHK             28
+#define GELIC_NET_DATA_STATUS_CHK_MASK    (1 << GELIC_NET_RXIPCHK | \
+                                           1 << GELIC_NET_TCPUDPIPCHK)
+
+/* descriptor data_error bits */
+#define GELIC_NET_RXIPCHKERR              27
+#define GELIC_NET_RXTCPCHKERR             26
+#define GELIC_NET_DATA_ERROR_CHK_MASK     (1 << GELIC_NET_RXIPCHKERR | \
+                                           1 << GELIC_NET_RXTCPCHKERR)
+
+#define GELIC_NET_DMAC_CMDSTAT_NOCS       0xa0080000 /* middle of frame */
+#define GELIC_NET_DMAC_CMDSTAT_TCPCS      0xa00a0000
+#define GELIC_NET_DMAC_CMDSTAT_UDPCS      0xa00b0000
+#define GELIC_NET_DMAC_CMDSTAT_END_FRAME  0x00040000 /* end of frame */
+
+#define GELIC_NET_DMAC_CMDSTAT_CHAIN_END  0x00000002 /* RXDCEIS:DMA stopped */
+
+#define GELIC_NET_DESCR_IND_PROC_SHIFT    28
+#define GELIC_NET_DESCR_IND_PROC_MASKO    0x0fffffff
+
+/* ignore ipsec ans multicast */
+#define GELIC_NET_DATA_ERROR_MASK         0xfdefbfff
+/* ignore unmatched sp on sp, drop_packet, multicast address frame*/
+#define GELIC_NET_DATA_ERROR_FLG          0x7def8000
+
+enum gelic_net_descr_status {
+	GELIC_NET_DESCR_COMPLETE            = 0x00, /* used in rx and tx */
+	GELIC_NET_DESCR_RESPONSE_ERROR      = 0x01, /* used in rx and tx */
+	GELIC_NET_DESCR_PROTECTION_ERROR    = 0x02, /* used in rx and tx */
+	GELIC_NET_DESCR_FRAME_END           = 0x04, /* used in rx */
+	GELIC_NET_DESCR_FORCE_END           = 0x05, /* used in rx and tx */
+	GELIC_NET_DESCR_CARDOWNED           = 0x0a, /* used in rx and tx */
+	GELIC_NET_DESCR_NOT_IN_USE                  /* any other value */
+};
+#define GELIC_NET_DMAC_CMDSTAT_NOT_IN_USE 0xb0000000
+
+#define GELIC_NET_DESCR_SIZE              32
+struct gelic_net_descr {
+	/* as defined by the hardware */
+	uint32_t buf_addr;
+	uint32_t buf_size;
+	uint32_t next_descr_addr;
+	uint32_t dmac_cmd_status;
+	uint32_t result_size;
+	uint32_t valid_size;	/* all zeroes for tx */
+	uint32_t data_status;
+	uint32_t data_error;	/* all zeroes for tx */
+
+	/* used in the driver */
+	struct sk_buff *skb;
+	dma_addr_t bus_addr;
+	struct gelic_net_descr *next;
+	struct gelic_net_descr *prev;
+	struct vlan_ethhdr vlan;
+} __attribute__((aligned(32)));
+
+struct gelic_net_descr_chain {
+	/* we walk from tail to head */
+	struct gelic_net_descr *head;
+	struct gelic_net_descr *tail;
+	spinlock_t lock;
+};
+
+struct gelic_net_card {
+	struct net_device *netdev;
+	uint64_t ghiintmask;
+	struct ps3_system_bus_device *dev;
+	uint32_t vlan_id[GELIC_NET_VLAN_MAX];
+	int vlan_index;
+
+	struct gelic_net_descr_chain tx_chain;
+	struct gelic_net_descr_chain rx_chain;
+	spinlock_t chain_lock;
+
+	struct net_device_stats netdev_stats;
+	int rx_csum;
+	spinlock_t intmask_lock;
+
+	struct work_struct tx_timeout_task;
+	atomic_t tx_timeout_task_counter;
+	wait_queue_head_t waitq;
+
+	struct gelic_net_descr *tx_top, *rx_top;
+
+	struct gelic_net_descr descr[0];
+};
+
+static int ps3_gelic_param = 1; /* vlan desc support */
+#ifdef CONFIG_GELIC_NET_MODULE
+module_param(ps3_gelic_param, int, S_IRUGO);
+#endif
+
+struct gelic_net_card *gcard;
+static uint64_t gelic_irq_status;
+
+static int dmac_status = 0;
+
+/* for lv1_net_control */
+#define GELIC_NET_GET_MAC_ADDRESS               0x0000000000000001
+#define GELIC_NET_GET_ETH_PORT_STATUS           0x0000000000000002
+#define GELIC_NET_SET_NEGOTIATION_MODE          0x0000000000000003
+#define GELIC_NET_GET_VLAN_ID                   0x0000000000000004
+
+#define GELIC_NET_LINK_UP                       0x0000000000000001
+#define GELIC_NET_FULL_DUPLEX                   0x0000000000000002
+#define GELIC_NET_AUTO_NEG                      0x0000000000000004
+#define GELIC_NET_SPEED_10                      0x0000000000000010
+#define GELIC_NET_SPEED_100                     0x0000000000000020
+#define GELIC_NET_SPEED_1000                    0x0000000000000040
+
+#define GELIC_NET_VLAN_ALL                      0x0000000000000001
+#define GELIC_NET_VLAN_WIRED                    0x0000000000000002
+#define GELIC_NET_VLAN_WIRELESS                 0x0000000000000003
+#define GELIC_NET_VLAN_PSP                      0x0000000000000004
+#define GELIC_NET_VLAN_PORT0                    0x0000000000000010
+#define GELIC_NET_VLAN_PORT1                    0x0000000000000011
+#define GELIC_NET_VLAN_PORT2                    0x0000000000000012
+#define GELIC_NET_VLAN_DAEMON_CLIENT_BSS        0x0000000000000013
+#define GELIC_NET_VLAN_LIBERO_CLIENT_BSS        0x0000000000000014
+#define GELIC_NET_VLAN_NO_ENTRY                 -6
+
+#define GELIC_NET_PORT                          2 /* for port status */
+
+
+MODULE_AUTHOR("SCE Inc.");
+MODULE_DESCRIPTION("Gelic Network driver");
+MODULE_LICENSE("GPL");
+
+static int rx_descriptors = GELIC_NET_RX_DESCRIPTORS;
+static int tx_descriptors = GELIC_NET_TX_DESCRIPTORS;
+
+
+/* set irq_mask */
+static int
+gelic_net_set_irq_mask(struct gelic_net_card *card, uint64_t mask)
+{
+	uint64_t status = 0;
+
+	status = lv1_net_set_interrupt_mask(card->dev->did.bus_id,
+		card->dev->did.dev_id, mask, 0);
+	if (status) {
+		printk("lv1_net_set_interrupt_mask failed, status=%ld\n",
+			status);
+	}
+	return status;
+}
+
+/**
+ * gelic_net_get_descr_status -- returns the status of a descriptor
+ * @descr: descriptor to look at
+ *
+ * returns the status as in the dmac_cmd_status field of the descriptor
+ */
+enum gelic_net_descr_status
+gelic_net_get_descr_status(struct gelic_net_descr *descr)
+{
+	uint32_t cmd_status;
+
+	rmb();
+	cmd_status = descr->dmac_cmd_status;
+	rmb();
+	cmd_status >>= GELIC_NET_DESCR_IND_PROC_SHIFT;
+	return cmd_status;
+}
+
+/**
+ * gelic_net_set_descr_status -- sets the status of a descriptor
+ * @descr: descriptor to change
+ * @status: status to set in the descriptor
+ *
+ * changes the status to the specified value. Doesn't change other bits
+ * in the status
+ */
+static void
+gelic_net_set_descr_status(struct gelic_net_descr *descr,
+			    enum gelic_net_descr_status status)
+{
+	uint32_t cmd_status;
+
+	/* read the status */
+	mb();
+	cmd_status = descr->dmac_cmd_status;
+	/* clean the upper 4 bits */
+	cmd_status &= GELIC_NET_DESCR_IND_PROC_MASKO;
+	/* add the status to it */
+	cmd_status |= ((uint32_t)status)<<GELIC_NET_DESCR_IND_PROC_SHIFT;
+	/* and write it back */
+	descr->dmac_cmd_status = cmd_status;
+	wmb();
+}
+
+/**
+ * gelic_net_free_chain - free descriptor chain
+ * @card: card structure
+ * @descr_in: address of desc
+ */
+static void
+gelic_net_free_chain(struct gelic_net_card *card,
+		      struct gelic_net_descr *descr_in)
+{
+	struct gelic_net_descr *descr;
+
+	for (descr = descr_in; descr && !descr->bus_addr; descr = descr->next) {
+		dma_unmap_single(&card->dev->core, descr->bus_addr,
+				 GELIC_NET_DESCR_SIZE, PCI_DMA_BIDIRECTIONAL);
+		descr->bus_addr = 0;
+	}
+}
+
+/**
+ * gelic_net_init_chain - links descriptor chain
+ * @card: card structure
+ * @chain: address of chain
+ * @start_descr: address of descriptor array
+ * @no: number of descriptors
+ *
+ * we manage a circular list that mirrors the hardware structure,
+ * except that the hardware uses bus addresses.
+ *
+ * returns 0 on success, <0 on failure
+ */
+static int
+gelic_net_init_chain(struct gelic_net_card *card,
+		       struct gelic_net_descr_chain *chain,
+		       struct gelic_net_descr *start_descr, int no)
+{
+	int i;
+	struct gelic_net_descr *descr;
+
+	spin_lock_init(&chain->lock);
+	descr = start_descr;
+	memset(descr, 0, sizeof(*descr) * no);
+
+	/* set up the hardware pointers in each descriptor */
+	for (i=0; i<no; i++, descr++) {
+		gelic_net_set_descr_status(descr, GELIC_NET_DESCR_NOT_IN_USE);
+		descr->bus_addr =
+			dma_map_single(&card->dev->core, descr,
+				       GELIC_NET_DESCR_SIZE,
+				       PCI_DMA_BIDIRECTIONAL);
+
+		if (descr->bus_addr == DMA_ERROR_CODE)
+			goto iommu_error;
+
+		descr->next = descr + 1;
+		descr->prev = descr - 1;
+	}
+	/* do actual chain list */
+	(descr-1)->next = start_descr;
+	start_descr->prev = (descr-1);
+
+	descr = start_descr;
+	for (i=0; i < no; i++, descr++) {
+		if (descr->next) {
+			descr->next_descr_addr = descr->next->bus_addr;
+		} else {
+			descr->next_descr_addr = 0;
+		}
+	}
+
+	chain->head = start_descr;
+	chain->tail = start_descr;
+	(descr-1)->next_descr_addr = 0; /* last descr */
+	return 0;
+
+iommu_error:
+	descr = start_descr;
+	for (i=0; i < no; i++, descr++)
+		if (descr->bus_addr)
+			dma_unmap_single(&card->dev->core, descr->bus_addr,
+					 GELIC_NET_DESCR_SIZE,
+					 PCI_DMA_BIDIRECTIONAL);
+	return -ENOMEM;
+}
+
+/**
+ * gelic_net_prepare_rx_descr - reinitializes a rx descriptor
+ * @card: card structure
+ * @descr: descriptor to re-init
+ *
+ * return 0 on succes, <0 on failure
+ *
+ * allocates a new rx skb, iommu-maps it and attaches it to the descriptor.
+ * Activate the descriptor state-wise
+ */
+static int
+gelic_net_prepare_rx_descr(struct gelic_net_card *card,
+			    struct gelic_net_descr *descr)
+{
+	dma_addr_t buf;
+	int error = 0;
+	int offset;
+	int bufsize;
+
+	if( gelic_net_get_descr_status(descr) !=  GELIC_NET_DESCR_NOT_IN_USE) {
+		printk("%s: ERROR status \n", __FUNCTION__);
+	}
+	/* we need to round up the buffer size to a multiple of 128 */
+	bufsize = (GELIC_NET_MAX_MTU + GELIC_NET_RXBUF_ALIGN - 1) &
+		(~(GELIC_NET_RXBUF_ALIGN - 1));
+
+	/* and we need to have it 128 byte aligned, therefore we allocate a
+	 * bit more */
+	/* allocate an skb */
+	descr->skb = dev_alloc_skb(bufsize + GELIC_NET_RXBUF_ALIGN - 1);
+	if (!descr->skb) {
+		if (net_ratelimit())
+			printk("Not enough memory to allocate rx buffer\n");
+		return -ENOMEM;
+	}
+	descr->buf_size = bufsize;
+	descr->dmac_cmd_status = 0;
+	descr->result_size = 0;
+	descr->valid_size = 0;
+	descr->data_error = 0;
+
+	offset = ((unsigned long)descr->skb->data) &
+		(GELIC_NET_RXBUF_ALIGN - 1);
+	if (offset)
+		skb_reserve(descr->skb, GELIC_NET_RXBUF_ALIGN - offset);
+	/* io-mmu-map the skb */
+	buf = dma_map_single(&card->dev->core, descr->skb->data,
+					GELIC_NET_MAX_MTU,
+					PCI_DMA_BIDIRECTIONAL);
+	descr->buf_addr = buf;
+	if (buf == DMA_ERROR_CODE) {
+		dev_kfree_skb_any(descr->skb);
+		printk("Could not iommu-map rx buffer\n");
+		gelic_net_set_descr_status(descr, GELIC_NET_DESCR_NOT_IN_USE);
+	} else {
+		gelic_net_set_descr_status(descr, GELIC_NET_DESCR_CARDOWNED);
+	}
+
+	return error;
+}
+
+/**
+ * gelic_net_release_rx_chain - free all rx descr
+ * @card: card structure
+ *
+ */
+static void
+gelic_net_release_rx_chain(struct gelic_net_card *card)
+{
+	struct gelic_net_descr_chain *chain = &card->rx_chain;
+
+	while(chain->tail != chain->head) {
+		if (chain->tail->skb) {
+			dma_unmap_single(&card->dev->core,
+						chain->tail->buf_addr,
+						chain->tail->skb->len,
+						PCI_DMA_BIDIRECTIONAL);
+			chain->tail->buf_addr = 0;
+			dev_kfree_skb_any(chain->tail->skb);
+			chain->tail->skb = NULL;
+			chain->tail->dmac_cmd_status =
+						GELIC_NET_DESCR_NOT_IN_USE;
+			chain->tail = chain->tail->next;
+		}
+	}
+}
+
+/**
+ * gelic_net_enable_rxdmac - enables a receive DMA controller
+ * @card: card structure
+ *
+ * gelic_net_enable_rxdmac enables the DMA controller by setting RX_DMA_EN
+ * in the GDADMACCNTR register
+ */
+static void
+gelic_net_enable_rxdmac(struct gelic_net_card *card)
+{
+	uint64_t status;
+
+	status = lv1_net_start_rx_dma(card->dev->did.bus_id,
+				card->dev->did.dev_id,
+				(uint64_t)card->rx_chain.tail->bus_addr, 0);
+	if (status) {
+		printk("lv1_net_start_rx_dma failed, status=%ld\n", status);
+	}
+}
+
+/**
+ * gelic_net_refill_rx_chain - refills descriptors/skbs in the rx chains
+ * @card: card structure
+ *
+ * refills descriptors in all chains (last used chain first): allocates skbs
+ * and iommu-maps them.
+ */
+static void
+gelic_net_refill_rx_chain(struct gelic_net_card *card)
+{
+	struct gelic_net_descr_chain *chain;
+	int count = 0;
+
+	chain = &card->rx_chain;
+	while (chain->head && gelic_net_get_descr_status(chain->head) ==
+		GELIC_NET_DESCR_NOT_IN_USE) {
+		if (gelic_net_prepare_rx_descr(card, chain->head))
+			break;
+		count++;
+		chain->head = chain->head->next;
+	}
+}
+
+/**
+ * gelic_net_alloc_rx_skbs - allocates rx skbs in rx descriptor chains
+ * @card: card structure
+ *
+ * returns 0 on success, <0 on failure
+ */
+static int
+gelic_net_alloc_rx_skbs(struct gelic_net_card *card)
+{
+	struct gelic_net_descr_chain *chain;
+
+	chain = &card->rx_chain;
+	gelic_net_refill_rx_chain(card);
+	chain->head = card->rx_top->prev; /* point to the last */
+	return 0;
+}
+
+/**
+ * gelic_net_release_tx_descr - processes a used tx descriptor
+ * @card: card structure
+ * @descr: descriptor to release
+ *
+ * releases a used tx descriptor (unmapping, freeing of skb)
+ */
+static void
+gelic_net_release_tx_descr(struct gelic_net_card *card,
+			    struct gelic_net_descr *descr)
+{
+	struct sk_buff *skb;
+
+  if (!ps3_gelic_param) {
+	/* unmap the skb */
+	skb = descr->skb;
+	dma_unmap_single(&card->dev->core, descr->buf_addr, skb->len,
+			 PCI_DMA_BIDIRECTIONAL);
+
+	dev_kfree_skb_any(skb);
+  } else {
+	if ((descr->data_status & 0x00000001) == 1) { /* end of frame */
+		skb = descr->skb;
+		dma_unmap_single(&card->dev->core, descr->buf_addr, skb->len,
+			 PCI_DMA_BIDIRECTIONAL);
+		dev_kfree_skb_any(skb);
+	} else {
+		dma_unmap_single(&card->dev->core, descr->buf_addr,
+			descr->buf_size, PCI_DMA_BIDIRECTIONAL);
+	}
+  }
+	descr->buf_addr = 0;
+	descr->buf_size = 0;
+	descr->next_descr_addr = 0;
+	descr->result_size = 0;
+	descr->valid_size = 0;
+	descr->data_status = 0;
+	descr->data_error = 0;
+	descr->skb = NULL;
+	card->tx_chain.tail = card->tx_chain.tail->next;
+
+	/* set descr status */
+	descr->dmac_cmd_status = GELIC_NET_DMAC_CMDSTAT_NOT_IN_USE;
+}
+
+/**
+ * gelic_net_release_tx_chain - processes sent tx descriptors
+ * @card: adapter structure
+ * @stop: net_stop sequence
+ *
+ * releases the tx descriptors that gelic has finished with
+ */
+static void
+gelic_net_release_tx_chain(struct gelic_net_card *card, int stop)
+{
+	struct gelic_net_descr_chain *tx_chain = &card->tx_chain;
+	enum gelic_net_descr_status status;
+	int release = 0;
+
+	for (;tx_chain->head != tx_chain->tail && tx_chain->tail;) {
+		status = gelic_net_get_descr_status(tx_chain->tail);
+		switch (status) {
+		case GELIC_NET_DESCR_RESPONSE_ERROR:
+		case GELIC_NET_DESCR_PROTECTION_ERROR:
+		case GELIC_NET_DESCR_FORCE_END:
+			printk("%s: forcing end of tx descriptor "
+			       "with status x%02x\n",
+			       card->netdev->name, status);
+			card->netdev_stats.tx_dropped++;
+			break;
+
+		case GELIC_NET_DESCR_COMPLETE:
+			card->netdev_stats.tx_packets++;
+			card->netdev_stats.tx_bytes +=
+				tx_chain->tail->skb->len;
+			break;
+
+		case GELIC_NET_DESCR_CARDOWNED:
+		default: /* any other value (== GELIC_NET_DESCR_NOT_IN_USE) */
+			goto out;
+		}
+		gelic_net_release_tx_descr(card, tx_chain->tail);
+		release = 1;
+	}
+out:
+	/* status NOT_IN_USE or chain end */
+	if (!tx_chain->tail) {
+		/* release all chains */
+		if(card->tx_chain.head) printk("ERROR tx_chain.head is NULL\n");
+		card->tx_chain.tail = card->tx_top;
+		card->tx_chain.head = card->tx_top;
+	}
+	if (!stop && release && netif_queue_stopped(card->netdev)) {
+		netif_wake_queue(card->netdev);
+	}
+}
+
+/**
+ * gelic_net_set_multi - sets multicast addresses and promisc flags
+ * @netdev: interface device structure
+ *
+ * gelic_net_set_multi configures multicast addresses as needed for the
+ * netdev interface. It also sets up multicast, allmulti and promisc
+ * flags appropriately
+ */
+static void
+gelic_net_set_multi(struct net_device *netdev)
+{
+	int i;
+	uint8_t *p;
+	uint64_t addr, status;
+	struct dev_mc_list *mc;
+	struct gelic_net_card *card = netdev_priv(netdev);
+
+	/* clear all multicast address */
+	status = lv1_net_remove_multicast_address(card->dev->did.bus_id,
+				card->dev->did.dev_id, 0, 1);
+	if (status) {
+		printk("lv1_net_remove_multicast_address failed, status=%ld\n",\
+			status);
+	}
+	/* set broadcast address */
+	status = lv1_net_add_multicast_address(card->dev->did.bus_id,
+			card->dev->did.dev_id, GELIC_NET_BROADCAST_ADDR, 0);
+	if (status) {
+		printk("lv1_net_add_multicast_address failed, status=%ld\n",\
+			status);
+	}
+
+	if (netdev->flags & IFF_ALLMULTI
+		|| netdev->mc_count > GELIC_NET_MC_COUNT_MAX) { /* list max */
+		status = lv1_net_add_multicast_address(card->dev->did.bus_id,
+				card->dev->did.dev_id,
+				0, 1);
+		if (status) {
+			printk("lv1_net_add_multicast_address failed, status=%ld\n",\
+				status);
+		}
+		return ;
+	}
+
+	/* set multicalst address */
+	for ( mc = netdev->mc_list; mc; mc = mc->next) {
+		addr = 0;
+		p = mc->dmi_addr;
+		for (i = 0; i < ETH_ALEN; i++) {
+			addr <<= 8;
+			addr |= *p++;
+		}
+		status = lv1_net_add_multicast_address(card->dev->did.bus_id,
+				card->dev->did.dev_id,
+				addr, 0);
+		if (status) {
+			printk("lv1_net_add_multicast_address failed, status=%ld\n",\
+				status);
+		}
+	}
+}
+
+/**
+ * gelic_net_disable_rxdmac - disables the receive DMA controller
+ * @card: card structure
+ *
+ * gelic_net_disable_rxdmac terminates processing on the DMA controller by
+ * turing off DMA and issueing a force end
+ */
+static void
+gelic_net_disable_rxdmac(struct gelic_net_card *card)
+{
+	uint64_t status;
+
+	status = lv1_net_stop_rx_dma(card->dev->did.bus_id,
+		card->dev->did.dev_id, 0);
+	if (status) {
+		printk("lv1_net_stop_rx_dma faild, status=%ld\n", status);
+	}
+}
+
+/**
+ * gelic_net_disable_txdmac - disables the transmit DMA controller
+ * @card: card structure
+ *
+ * gelic_net_disable_txdmac terminates processing on the DMA controller by
+ * turing off DMA and issueing a force end
+ */
+static void
+gelic_net_disable_txdmac(struct gelic_net_card *card)
+{
+	uint64_t status;
+
+	status = lv1_net_stop_tx_dma(card->dev->did.bus_id,
+		card->dev->did.dev_id, 0);
+	if (status) {
+		printk("lv1_net_stop_tx_dma faild, status=%ld\n", status);
+	}
+}
+
+/**
+ * gelic_net_stop - called upon ifconfig down
+ * @netdev: interface device structure
+ *
+ * always returns 0
+ */
+int
+gelic_net_stop(struct net_device *netdev)
+{
+	struct gelic_net_card *card = netdev_priv(netdev);
+
+	netif_poll_disable(netdev);
+	netif_stop_queue(netdev);
+
+	/* turn off DMA, force end */
+	gelic_net_disable_rxdmac(card);
+	gelic_net_disable_txdmac(card);
+
+	gelic_net_set_irq_mask(card, 0);
+
+	/* disconnect event port */
+	free_irq(card->netdev->irq, card->netdev);
+	ps3_sb_event_receive_port_destroy(&card->dev->did,
+		card->dev->interrupt_id, card->netdev->irq);
+	card->netdev->irq = NO_IRQ;
+
+	netif_carrier_off(netdev);
+
+	/* release chains */
+	gelic_net_release_tx_chain(card, 1);
+	gelic_net_release_rx_chain(card);
+
+	gelic_net_free_chain(card, card->tx_top);
+	gelic_net_free_chain(card, card->rx_top);
+
+	return 0;
+}
+
+/**
+ * gelic_net_get_next_tx_descr - returns the next available tx descriptor
+ * @card: device structure to get descriptor from
+ *
+ * returns the address of the next descriptor, or NULL if not available.
+ */
+static struct gelic_net_descr *
+gelic_net_get_next_tx_descr(struct gelic_net_card *card)
+{
+	if (card->tx_chain.head == NULL) return NULL;
+	/* check, if head points to not-in-use descr */
+  if (!ps3_gelic_param) {
+	if ( card->tx_chain.tail != card->tx_chain.head->next
+		&& gelic_net_get_descr_status(card->tx_chain.head) ==
+		     GELIC_NET_DESCR_NOT_IN_USE ) {
+		return card->tx_chain.head;
+	} else {
+		return NULL;
+	}
+  } else {
+	if ( card->tx_chain.tail != card->tx_chain.head->next
+		&& card->tx_chain.tail != card->tx_chain.head->next->next
+		&& gelic_net_get_descr_status(card->tx_chain.head) ==
+		     GELIC_NET_DESCR_NOT_IN_USE
+		&& gelic_net_get_descr_status(card->tx_chain.head->next) ==
+		     GELIC_NET_DESCR_NOT_IN_USE ) {
+		return card->tx_chain.head;
+	} else {
+		return NULL;
+	}
+  }
+}
+
+/**
+ * gelic_net_set_txdescr_cmdstat - sets the tx descriptor command field
+ * @descr: descriptor structure to fill out
+ * @skb: packet to consider
+ * @middle: middle of frame
+ *
+ * fills out the command and status field of the descriptor structure,
+ * depending on hardware checksum settings. This function assumes a wmb()
+ * has executed before.
+ */
+static void
+gelic_net_set_txdescr_cmdstat(struct gelic_net_descr *descr,
+			       struct sk_buff *skb, int middle)
+{
+	uint32_t nocs, tcpcs, udpcs;
+
+	if (middle) {
+		nocs =  GELIC_NET_DMAC_CMDSTAT_NOCS;
+		tcpcs = GELIC_NET_DMAC_CMDSTAT_TCPCS;
+		udpcs = GELIC_NET_DMAC_CMDSTAT_UDPCS;
+	}else {
+		nocs =  GELIC_NET_DMAC_CMDSTAT_NOCS
+			| GELIC_NET_DMAC_CMDSTAT_END_FRAME;
+		tcpcs = GELIC_NET_DMAC_CMDSTAT_TCPCS
+			| GELIC_NET_DMAC_CMDSTAT_END_FRAME;
+		udpcs = GELIC_NET_DMAC_CMDSTAT_UDPCS
+			| GELIC_NET_DMAC_CMDSTAT_END_FRAME;
+	}
+
+	if (skb->ip_summed != CHECKSUM_PARTIAL) {
+		descr->dmac_cmd_status = nocs;
+	} else {
+		/* is packet ip?
+		 * if yes: tcp? udp? */
+		if (skb->protocol == htons(ETH_P_IP)) {
+			if (skb->nh.iph->protocol == IPPROTO_TCP) {
+				descr->dmac_cmd_status = tcpcs;
+			} else if (skb->nh.iph->protocol == IPPROTO_UDP) {
+				descr->dmac_cmd_status = udpcs;
+			} else { /* the stack should checksum non-tcp and non-udp
+				    packets on his own: NETIF_F_IP_CSUM */
+				descr->dmac_cmd_status = nocs;
+			}
+		}
+	}
+}
+
+/**
+ * gelic_net_prepare_tx_descr - get dma address of skb_data
+ * @card: card structure
+ * @descr: descriptor structure
+ * @skb: packet to use
+ *
+ * returns 0 on success, <0 on failure.
+ *
+ */
+static int
+gelic_net_prepare_tx_descr_v(struct gelic_net_card *card,
+			    struct gelic_net_descr *descr,
+			    struct sk_buff *skb)
+{
+	dma_addr_t buf;
+	uint8_t *hdr;
+	struct vlan_ethhdr *v_hdr;
+	int vlan_len;
+
+	if (skb->len < GELIC_NET_VLAN_POS) {
+		printk("error: skb->len:%d\n", skb->len);
+		return -EINVAL;
+	}
+	hdr = skb->data;
+	v_hdr = (struct vlan_ethhdr *)skb->data;
+	memcpy(&descr->vlan, v_hdr, GELIC_NET_VLAN_POS);
+	if (card->vlan_index != -1) {
+		descr->vlan.h_vlan_proto = htons(ETH_P_8021Q); /* vlan 0x8100*/
+		descr->vlan.h_vlan_TCI = htons(card->vlan_id[card->vlan_index]);
+		vlan_len = GELIC_NET_VLAN_POS + VLAN_HLEN; /* VLAN_HLEN=4 */
+	} else {
+		vlan_len = GELIC_NET_VLAN_POS; /* no vlan tag */
+	}
+
+	/* first descr */
+	buf = dma_map_single(&card->dev->core, &descr->vlan,
+					 vlan_len, PCI_DMA_BIDIRECTIONAL);
+
+	if (buf == DMA_ERROR_CODE) {
+		printk("could not iommu-map packet (%p, %i). "
+			  "Dropping packet\n", v_hdr, vlan_len);
+		return -ENOMEM;
+	}
+
+	descr->buf_addr = buf;
+	descr->buf_size = vlan_len;
+	descr->skb = skb; /* not used */
+	descr->data_status = 0;
+	gelic_net_set_txdescr_cmdstat(descr, skb, 1); /* not the frame end */
+
+	/* second descr */
+	card->tx_chain.head = card->tx_chain.head->next;
+	descr->next_descr_addr = descr->next->bus_addr;
+	descr = descr->next;
+	if (gelic_net_get_descr_status(descr) !=
+			GELIC_NET_DESCR_NOT_IN_USE) {
+		printk("ERROR descr()\n"); /* XXX will be removed */
+	}
+	buf = dma_map_single(&card->dev->core, hdr + GELIC_NET_VLAN_POS,
+				skb->len - GELIC_NET_VLAN_POS,
+				PCI_DMA_BIDIRECTIONAL);
+
+	if (buf == DMA_ERROR_CODE) {
+		printk("could not iommu-map packet (%p, %i). "
+			  "Dropping packet\n", hdr + GELIC_NET_VLAN_POS,
+			  skb->len - GELIC_NET_VLAN_POS);
+		return -ENOMEM;
+	}
+
+	descr->buf_addr = buf;
+	descr->buf_size = skb->len - GELIC_NET_VLAN_POS;
+	descr->skb = skb;
+	descr->data_status = 0;
+	descr->next_descr_addr= 0;
+	gelic_net_set_txdescr_cmdstat(descr,skb, 0);
+
+	return 0;
+}
+
+static int
+gelic_net_prepare_tx_descr(struct gelic_net_card *card,
+			    struct gelic_net_descr *descr,
+			    struct sk_buff *skb)
+{
+	dma_addr_t buf = dma_map_single(&card->dev->core, skb->data,
+					 skb->len, PCI_DMA_BIDIRECTIONAL);
+
+	if (buf == DMA_ERROR_CODE) {
+		printk("could not iommu-map packet (%p, %i). "
+			  "Dropping packet\n", skb->data, skb->len);
+		return -ENOMEM;
+	}
+
+	descr->buf_addr = buf;
+	descr->buf_size = skb->len;
+	descr->skb = skb;
+	descr->data_status = 0;
+
+	return 0;
+}
+
+static void
+gelic_net_set_frame_end(struct gelic_net_card *card,
+		struct gelic_net_descr *descr, struct sk_buff *skb)
+{
+	descr->next_descr_addr= 0;
+	gelic_net_set_txdescr_cmdstat(descr,skb, 0);
+	wmb();
+	if (descr->prev) {
+		descr->prev->next_descr_addr = descr->bus_addr;
+	}
+}
+
+/**
+ * gelic_net_kick_txdma - enables TX DMA processing
+ * @card: card structure
+ * @descr: descriptor address to enable TX processing at
+ *
+ */
+static void
+gelic_net_kick_txdma(struct gelic_net_card *card,
+		       struct gelic_net_descr *descr)
+{
+	uint64_t status = -1;
+	int count = 10;
+
+	if (dmac_status) {
+		return ;
+	}
+
+	if (gelic_net_get_descr_status(descr) == GELIC_NET_DESCR_CARDOWNED) {
+		/* kick */
+		dmac_status = 1;
+
+		while(count--) {
+			status = lv1_net_start_tx_dma(card->dev->did.bus_id,
+					card->dev->did.dev_id,
+					(uint64_t)descr->bus_addr, 0);
+			if (!status) {
+				break;
+			}
+		}
+		if (!count) {
+			printk("lv1_net_start_txdma failed, status=%ld %016lx\n",\
+				status, gelic_irq_status);
+		}
+	}
+}
+
+/**
+ * gelic_net_xmit - transmits a frame over the device
+ * @skb: packet to send out
+ * @netdev: interface device structure
+ *
+ * returns 0 on success, <0 on failure
+ */
+static int
+gelic_net_xmit(struct sk_buff *skb, struct net_device *netdev)
+{
+	struct gelic_net_card *card = netdev_priv(netdev);
+	struct gelic_net_descr *descr = NULL;
+	int result;
+	unsigned long flags;
+
+	spin_lock_irqsave(&card->intmask_lock, flags);
+
+	gelic_net_release_tx_chain(card, 0);
+	if (skb == NULL){
+		goto kick;
+	}
+	descr = gelic_net_get_next_tx_descr(card); /* get tx_chain.head */
+	if (!descr) {
+		netif_stop_queue(netdev);
+		spin_unlock_irqrestore(&card->intmask_lock, flags);
+		return 1;
+	}
+  if (!ps3_gelic_param) {
+	result = gelic_net_prepare_tx_descr(card, descr, skb);
+  } else {
+	result = gelic_net_prepare_tx_descr_v(card, descr, skb);
+  }
+	if (result)
+		goto error;
+
+	card->tx_chain.head = card->tx_chain.head->next;
+  if (!ps3_gelic_param) {
+	gelic_net_set_frame_end(card, descr, skb);
+  } else {
+	if (descr->prev) {
+		descr->prev->next_descr_addr = descr->bus_addr;
+	}
+  }
+kick:
+	wmb();
+	gelic_net_kick_txdma(card, card->tx_chain.tail);
+
+	netdev->trans_start = jiffies;
+	spin_unlock_irqrestore(&card->intmask_lock, flags);
+	return NETDEV_TX_OK;
+
+error:
+	card->netdev_stats.tx_dropped++;
+	spin_unlock_irqrestore(&card->intmask_lock, flags);
+	return NETDEV_TX_LOCKED;
+}
+
+/**
+ * gelic_net_pass_skb_up - takes an skb from a descriptor and passes it on
+ * @descr: descriptor to process
+ * @card: card structure
+ *
+ * returns 1 on success, 0 if no packet was passed to the stack
+ *
+ * iommu-unmaps the skb, fills out skb structure and passes the data to the
+ * stack. The descriptor state is not changed.
+ */
+static int
+gelic_net_pass_skb_up(struct gelic_net_descr *descr,
+		       struct gelic_net_card *card)
+{
+	struct sk_buff *skb;
+	struct net_device *netdev;
+	uint32_t data_status, data_error;
+
+	data_status = descr->data_status;
+	data_error = descr->data_error;
+
+	netdev = card->netdev;
+	/* check for errors in the data_error flag */
+	if ((data_error & GELIC_NET_DATA_ERROR_MASK))
+		DPRINTK("error in received descriptor found, "
+		       "data_status=x%08x, data_error=x%08x\n",
+		       data_status, data_error);
+	/* prepare skb, unmap descriptor */
+	skb = descr->skb;
+	dma_unmap_single(&card->dev->core, descr->buf_addr, GELIC_NET_MAX_MTU,
+			 PCI_DMA_BIDIRECTIONAL);
+
+	/* the cases we'll throw away the packet immediately */
+	if (data_error & GELIC_NET_DATA_ERROR_FLG) {
+		DPRINTK("ERROR DESTROY:%x\n", data_error);
+		return 0;
+	}
+
+	skb->dev = netdev;
+	skb_put(skb, descr->valid_size);
+	descr->skb = NULL;
+	/* the card seems to add 2 bytes of junk in front
+	 * of the ethernet frame */
+#define GELIC_NET_MISALIGN		2
+	skb_pull(skb, GELIC_NET_MISALIGN);
+	skb->protocol = eth_type_trans(skb, netdev);
+
+	/* checksum offload */
+	if (card->rx_csum) {
+		if ( (data_status & GELIC_NET_DATA_STATUS_CHK_MASK) &&
+		     (!(data_error & GELIC_NET_DATA_ERROR_CHK_MASK)) )
+			skb->ip_summed = CHECKSUM_UNNECESSARY;
+		else
+			skb->ip_summed = CHECKSUM_NONE;
+	} else {
+		skb->ip_summed = CHECKSUM_NONE;
+	}
+
+	/* pass skb up to stack */
+	netif_receive_skb(skb);
+
+	/* update netdevice statistics */
+	card->netdev_stats.rx_packets++;
+	card->netdev_stats.rx_bytes += skb->len;
+
+	return 1;
+}
+
+/**
+ * gelic_net_decode_descr - processes an rx descriptor
+ * @card: card structure
+ *
+ * returns 1 if a packet has been sent to the stack, otherwise 0
+ *
+ * processes an rx descriptor by iommu-unmapping the data buffer and passing
+ * the packet up to the stack
+ */
+static int
+gelic_net_decode_one_descr(struct gelic_net_card *card)
+{
+	enum gelic_net_descr_status status;
+	struct gelic_net_descr *descr;
+	struct gelic_net_descr_chain *chain = &card->rx_chain;
+	int result = 0;
+	int kick = 0;
+	uint32_t cmd_status;
+
+	descr = chain->tail;
+	cmd_status = chain->tail->dmac_cmd_status;
+	rmb();
+	status = cmd_status >> GELIC_NET_DESCR_IND_PROC_SHIFT;
+	if (status == GELIC_NET_DESCR_CARDOWNED) {
+		goto no_decode;
+	}
+	if (status == GELIC_NET_DESCR_NOT_IN_USE) {
+		printk("err: decode_one_descr\n");
+		goto no_decode;
+	}
+
+	if ( (status == GELIC_NET_DESCR_RESPONSE_ERROR) ||
+	     (status == GELIC_NET_DESCR_PROTECTION_ERROR) ||
+	     (status == GELIC_NET_DESCR_FORCE_END) ) {
+		printk("%s: dropping RX descriptor with state %d\n",
+		       card->netdev->name, status);
+		card->netdev_stats.rx_dropped++;
+		goto refill;
+	}
+
+	if ( (status != GELIC_NET_DESCR_COMPLETE) &&
+	     (status != GELIC_NET_DESCR_FRAME_END) ) {
+		printk("%s: RX descriptor with state %d\n",
+		       card->netdev->name, status);
+		goto refill;
+	}
+
+	/* ok, we've got a packet in descr */
+	result = gelic_net_pass_skb_up(descr, card); /* 1: skb_up sccess */
+	if (cmd_status & GELIC_NET_DMAC_CMDSTAT_CHAIN_END) {
+		kick = 1;
+	}
+refill:
+	descr->next_descr_addr = 0; /* unlink the descr */
+	wmb();
+	gelic_net_set_descr_status(descr, GELIC_NET_DESCR_NOT_IN_USE);
+	/* change the descriptor state: */
+	gelic_net_prepare_rx_descr(card, descr); /* refill one desc */
+	chain->head = descr;
+	chain->tail = descr->next;
+	descr->prev->next_descr_addr = descr->bus_addr;
+	if(kick) {
+		wmb();
+		gelic_net_enable_rxdmac(card);
+	}
+	return result;
+
+no_decode:
+	return 0;
+}
+
+/**
+ * gelic_net_poll - NAPI poll function called by the stack to return packets
+ * @netdev: interface device structure
+ * @budget: number of packets we can pass to the stack at most
+ *
+ * returns 0 if no more packets available to the driver/stack. Returns 1,
+ * if the quota is exceeded, but the driver has still packets.
+ *
+ */
+static int
+gelic_net_poll(struct net_device *netdev, int *budget)
+{
+	struct gelic_net_card *card = netdev_priv(netdev);
+	int packets_to_do, packets_done = 0;
+	int no_more_packets = 0;
+
+	packets_to_do = min(*budget, netdev->quota);
+
+	while (packets_to_do) {
+		if (gelic_net_decode_one_descr(card)) {
+			packets_done++;
+			packets_to_do--;
+		} else {
+			/* no more packets for the stack */
+			no_more_packets = 1;
+			break;
+		}
+	}
+	netdev->quota -= packets_done;
+	*budget -= packets_done;
+	if (no_more_packets == 1) {
+		netif_rx_complete(netdev);
+
+		/* one more check */
+		while (1) {
+			if (!gelic_net_decode_one_descr(card) ) break;
+		};
+
+		return 0;
+	}else {
+		return 1;
+	}
+}
+
+/**
+ * gelic_net_get_stats - get interface statistics
+ * @netdev: interface device structure
+ *
+ * returns the interface statistics residing in the gelic_net_card struct
+ */
+static struct net_device_stats *
+gelic_net_get_stats(struct net_device *netdev)
+{
+	struct gelic_net_card *card = netdev_priv(netdev);
+	struct net_device_stats *stats = &card->netdev_stats;
+
+	return stats;
+}
+
+/**
+ * gelic_net_change_mtu - changes the MTU of an interface
+ * @netdev: interface device structure
+ * @new_mtu: new MTU value
+ *
+ * returns 0 on success, <0 on failure
+ */
+static int
+gelic_net_change_mtu(struct net_device *netdev, int new_mtu)
+{
+	/* no need to re-alloc skbs or so -- the max mtu is about 2.3k
+	 * and mtu is outbound only anyway */
+	if ( (new_mtu < GELIC_NET_MIN_MTU ) ||
+		(new_mtu > GELIC_NET_MAX_MTU) ) {
+		return -EINVAL;
+	}
+	netdev->mtu = new_mtu;
+	return 0;
+}
+
+/**
+ * gelic_net_interrupt - event handler for gelic_net
+ */
+static irqreturn_t
+gelic_net_interrupt(int irq, void *ptr)
+{
+	struct net_device *netdev = ptr;
+	struct gelic_net_card *card = netdev_priv(netdev);
+	uint32_t status0, status1, status2;
+	unsigned long flags;
+	uint64_t status;
+
+	status = gelic_irq_status;
+	rmb();
+	status0 = (uint32_t)(status >> 32);
+	status1 = (uint32_t)(status & 0xffffffff);
+	status2 = 0;
+
+	if (!status0 && !status1 && !status2) {
+		return IRQ_NONE;
+	}
+
+	if(status1 & (1 << GELIC_NET_GDADCEINT) )  {
+		netif_rx_schedule(netdev);
+	}else
+	if (status0 & (1 << GELIC_NET_GRFANMINT) ) {
+		netif_rx_schedule(netdev);
+	}
+
+	if (status0 & (1 << GELIC_NET_GDTDCEINT) ) {
+		spin_lock_irqsave(&card->intmask_lock, flags);
+		dmac_status = 0;
+		spin_unlock_irqrestore(&card->intmask_lock, flags);
+		gelic_net_xmit(NULL, netdev);
+	}
+	return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/**
+ * gelic_net_poll_controller - artificial interrupt for netconsole etc.
+ * @netdev: interface device structure
+ *
+ * see Documentation/networking/netconsole.txt
+ */
+static void
+gelic_net_poll_controller(struct net_device *netdev)
+{
+	struct gelic_net_card *card = netdev_priv(netdev);
+
+	gelic_net_set_irq_mask(card, 0);
+	gelic_net_interrupt(netdev->irq, netdev);
+	gelic_net_set_irq_mask(card, card->ghiintmask);
+}
+#endif /* CONFIG_NET_POLL_CONTROLLER */
+
+/**
+ * gelic_net_open_device - open device and map dma region
+ * @card: card structure
+ */
+static int
+gelic_net_open_device(struct gelic_net_card *card)
+{
+	unsigned long result;
+	int ret;
+
+	result = ps3_sb_event_receive_port_setup(PS3_BINDING_CPU_ANY,
+		&card->dev->did, card->dev->interrupt_id, &card->netdev->irq);
+
+	if (result) {
+		printk("%s:%d: gelic_net_open_device failed (%ld)\n",
+			__func__, __LINE__, result);
+		ret = -EPERM;
+		goto fail_alloc_irq;
+	}
+
+	ret = request_irq(card->netdev->irq, gelic_net_interrupt, IRQF_DISABLED,
+		"gelic network", card->netdev);
+
+	if (ret) {
+		printk("%s:%d: request_irq failed (%ld)\n",
+			__func__, __LINE__, result);
+		goto fail_request_irq;
+	}
+
+	return 0;
+
+fail_request_irq:
+	ps3_sb_event_receive_port_destroy(&card->dev->did,
+		card->dev->interrupt_id, card->netdev->irq);
+	card->netdev->irq = NO_IRQ;
+fail_alloc_irq:
+	return ret;
+}
+
+
+/**
+ * gelic_net_open - called upon ifonfig up
+ * @netdev: interface device structure
+ *
+ * returns 0 on success, <0 on failure
+ *
+ * gelic_net_open allocates all the descriptors and memory needed for
+ * operation, sets up multicast list and enables interrupts
+ */
+int
+gelic_net_open(struct net_device *netdev)
+{
+	struct gelic_net_card *card = netdev_priv(netdev);
+
+	printk(" -> %s:%d\n", __func__, __LINE__);
+
+	gelic_net_open_device(card);
+
+	if (gelic_net_init_chain(card, &card->tx_chain,
+			card->descr, tx_descriptors))
+		goto alloc_tx_failed;
+	if (gelic_net_init_chain(card, &card->rx_chain,
+			card->descr + tx_descriptors, rx_descriptors))
+		goto alloc_rx_failed;
+
+	/* head of chain */
+	card->tx_top = card->tx_chain.head;
+	card->rx_top = card->rx_chain.head;
+
+	/* allocate rx skbs */
+	if (gelic_net_alloc_rx_skbs(card))
+		goto alloc_skbs_failed;
+
+	dmac_status = 0;
+	card->ghiintmask = GELIC_NET_RXINT | GELIC_NET_TXINT;
+	gelic_net_set_irq_mask(card, card->ghiintmask);
+	gelic_net_enable_rxdmac(card);
+
+	netif_start_queue(netdev);
+	netif_carrier_on(netdev);
+	netif_poll_enable(netdev);
+
+	return 0;
+
+alloc_skbs_failed:
+	gelic_net_free_chain(card, card->rx_top);
+alloc_rx_failed:
+	gelic_net_free_chain(card, card->tx_top);
+alloc_tx_failed:
+	return -ENOMEM;
+}
+
+#ifdef GELIC_NET_ETHTOOL
+static void
+gelic_net_get_drvinfo (struct net_device *netdev, struct ethtool_drvinfo *info)
+{
+	strncpy(info->driver, GELIC_NET_DRV_NAME, sizeof(info->driver) - 1);
+	strncpy(info->version, GELIC_NET_DRV_VERSION, sizeof(info->version) - 1);
+}
+
+static int
+gelic_net_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd)
+{
+	struct gelic_net_card *card = netdev_priv(netdev);
+	uint64_t status, v1, v2;
+	int speed, duplex;
+
+	speed = duplex = -1;
+	status = lv1_net_control(card->dev->did.bus_id, card->dev->did.dev_id,
+			GELIC_NET_GET_ETH_PORT_STATUS, GELIC_NET_PORT, 0, 0,
+			&v1, &v2);
+	if (status) {
+		/* link down */
+	} else {
+		if (v1 & GELIC_NET_FULL_DUPLEX) {
+			duplex = DUPLEX_FULL;
+		} else {
+			duplex = DUPLEX_HALF;
+		}
+
+		if (v1 & GELIC_NET_SPEED_10 ) {
+			speed = SPEED_10;
+		} else if (v1 & GELIC_NET_SPEED_100) {
+			speed = SPEED_100;
+		} else if (v1 & GELIC_NET_SPEED_1000) {
+			speed = SPEED_1000;
+		}
+	}
+	cmd->supported = SUPPORTED_TP | SUPPORTED_Autoneg |
+			SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
+			SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full |
+			SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full;
+	cmd->advertising = cmd->supported;
+	cmd->speed = speed;
+	cmd->duplex = duplex;
+	cmd->autoneg = AUTONEG_ENABLE; /* always enabled */
+	cmd->port = PORT_TP;
+
+	return 0;
+}
+
+static uint32_t
+gelic_net_get_link(struct net_device *netdev)
+{
+	struct gelic_net_card *card = netdev_priv(netdev);
+	uint64_t status, v1, v2;
+	int link;
+
+	status = lv1_net_control(card->dev->did.bus_id, card->dev->did.dev_id,
+			GELIC_NET_GET_ETH_PORT_STATUS, GELIC_NET_PORT, 0, 0,
+			&v1, &v2);
+	if (status) {
+		return 0; /* link down */
+	}
+	if (v1 & GELIC_NET_LINK_UP)
+		link = 1;
+	else
+		link = 0;
+	return link;
+}
+
+static int
+gelic_net_nway_reset(struct net_device *netdev)
+{
+	if (netif_running(netdev)) {
+		gelic_net_stop(netdev);
+		gelic_net_open(netdev);
+	}
+	return 0;
+}
+
+static uint32_t
+gelic_net_get_tx_csum(struct net_device *netdev)
+{
+	return (netdev->features & NETIF_F_IP_CSUM) != 0;
+}
+
+static int
+gelic_net_set_tx_csum(struct net_device *netdev, uint32_t data)
+{
+	if (data)
+		netdev->features |= NETIF_F_IP_CSUM;
+	else
+		netdev->features &= ~NETIF_F_IP_CSUM;
+
+	return 0;
+}
+
+static uint32_t
+gelic_net_get_rx_csum(struct net_device *netdev)
+{
+	struct gelic_net_card *card = netdev_priv(netdev);
+
+	return card->rx_csum;
+}
+
+static int
+gelic_net_set_rx_csum(struct net_device *netdev, uint32_t data)
+{
+	struct gelic_net_card *card = netdev_priv(netdev);
+
+	card->rx_csum = data;
+	return 0;
+}
+
+static struct ethtool_ops gelic_net_ethtool_ops = {
+	.get_drvinfo	= gelic_net_get_drvinfo,
+	.get_settings	= gelic_net_get_settings,
+	.get_link	= gelic_net_get_link,
+	.nway_reset	= gelic_net_nway_reset,
+	.get_tx_csum	= gelic_net_get_tx_csum,
+	.set_tx_csum	= gelic_net_set_tx_csum,
+	.get_rx_csum	= gelic_net_get_rx_csum,
+	.set_rx_csum	= gelic_net_set_rx_csum,
+};
+#endif
+
+static int
+gelic_net_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
+{
+	struct gelic_net_card *card = netdev_priv(netdev);
+	void __user *addr = (void __user *) ifr->ifr_ifru.ifru_data;
+	int mode, res = 0;
+
+	switch(cmd) {
+	case GELIC_NET_GET_MODE:
+		DPRINTK("GELIC_NET_GET_MODE:\n");
+		mode = card->vlan_index;
+		if (copy_to_user(addr, &mode, sizeof(mode)) ) {
+			printk("error copy_to_user\n");
+		}
+		res = 0;
+		break;
+	case GELIC_NET_SET_MODE:
+		if (card->vlan_index == -1) {
+			res = -EOPNOTSUPP; /* vlan mode only */
+			break;
+		}
+		if (copy_from_user(&mode, addr, sizeof(mode)) ) {
+			printk("error copy_from_user\n");
+		}
+		DPRINTK("GELIC_NET_SET_MODE:%x --> %x \n",
+				card->vlan_index, mode);
+		if (mode > GELIC_NET_VLAN_MAX -1 || mode < -1)
+			mode = GELIC_NET_VLAN_WIRED - 1;
+
+		if (card->vlan_index != mode) {
+			card->vlan_index = mode;
+			if (netif_running(netdev)) {
+				gelic_net_stop(netdev);
+				gelic_net_open(netdev);
+			}
+		}
+		res = 0;
+		break;
+	default:
+		res = -EOPNOTSUPP;
+		break;
+	}
+
+	return res;
+}
+
+/**
+ * gelic_net_tx_timeout_task - task scheduled by the watchdog timeout
+ * function (to be called not under interrupt status)
+ * @data: data, is interface device structure
+ *
+ * called as task when tx hangs, resets interface (if interface is up)
+ */
+static void
+gelic_net_tx_timeout_task(struct work_struct *work)
+{
+	struct gelic_net_card *card =
+		container_of(work, struct gelic_net_card, tx_timeout_task);
+	struct net_device *netdev = card->netdev;
+
+	printk("Timed out. Restarting... \n");
+
+	if (!(netdev->flags & IFF_UP))
+		goto out;
+
+	netif_device_detach(netdev);
+	gelic_net_stop(netdev);
+
+	gelic_net_open(netdev);
+	netif_device_attach(netdev);
+
+out:
+	atomic_dec(&card->tx_timeout_task_counter);
+}
+
+/**
+ * gelic_net_tx_timeout - called when the tx timeout watchdog kicks in.
+ * @netdev: interface device structure
+ *
+ * called, if tx hangs. Schedules a task that resets the interface
+ */
+static void
+gelic_net_tx_timeout(struct net_device *netdev)
+{
+	struct gelic_net_card *card;
+
+	card = netdev_priv(netdev);
+	atomic_inc(&card->tx_timeout_task_counter);
+	if (netdev->flags & IFF_UP)
+		schedule_work(&card->tx_timeout_task);
+	else
+		atomic_dec(&card->tx_timeout_task_counter);
+}
+
+/**
+ * gelic_net_setup_netdev_ops - initialization of net_device operations
+ * @netdev: net_device structure
+ *
+ * fills out function pointers in the net_device structure
+ */
+static void
+gelic_net_setup_netdev_ops(struct net_device *netdev)
+{
+	netdev->open = &gelic_net_open;
+	netdev->stop = &gelic_net_stop;
+	netdev->hard_start_xmit = &gelic_net_xmit;
+	netdev->get_stats = &gelic_net_get_stats;
+	netdev->set_multicast_list = &gelic_net_set_multi;
+	netdev->change_mtu = &gelic_net_change_mtu;
+	/* tx watchdog */
+	netdev->tx_timeout = &gelic_net_tx_timeout;
+	netdev->watchdog_timeo = GELIC_NET_WATCHDOG_TIMEOUT;
+	/* NAPI */
+	netdev->poll = &gelic_net_poll;
+	netdev->weight = GELIC_NET_NAPI_WEIGHT;
+#ifdef GELIC_NET_ETHTOOL
+	netdev->ethtool_ops = &gelic_net_ethtool_ops;
+#endif
+	netdev->do_ioctl = &gelic_net_ioctl;
+}
+
+/**
+ * gelic_net_setup_netdev - initialization of net_device
+ * @card: card structure
+ *
+ * Returns 0 on success or <0 on failure
+ *
+ * gelic_net_setup_netdev initializes the net_device structure
+ **/
+static int
+gelic_net_setup_netdev(struct gelic_net_card *card)
+{
+	int i, result;
+	struct net_device *netdev = card->netdev;
+	struct sockaddr addr;
+	uint8_t *mac;
+	uint64_t status, v1, v2;
+
+	SET_MODULE_OWNER(netdev);
+	spin_lock_init(&card->intmask_lock);
+
+	card->rx_csum = GELIC_NET_RX_CSUM_DEFAULT;
+
+	gelic_net_setup_netdev_ops(netdev);
+
+	netdev->features = NETIF_F_IP_CSUM;
+
+	status = lv1_net_control(card->dev->did.bus_id, card->dev->did.dev_id,
+				GELIC_NET_GET_MAC_ADDRESS,
+				0, 0, 0, &v1, &v2);
+	if (status || !v1) {
+		printk("lv1_net_control GET_MAC_ADDR not supported, status=%ld\n",
+			status);
+		return -EINVAL;
+	}
+	v1 <<= 16;
+	mac = (uint8_t *)&v1;
+	memcpy(addr.sa_data, mac, ETH_ALEN);
+	memcpy(netdev->dev_addr, addr.sa_data, ETH_ALEN);
+
+	result = register_netdev(netdev);
+	if (result) {
+			printk("Couldn't register net_device: %i\n", result);
+		return result;
+	}
+
+	printk("%s: %s\n", netdev->name, GELIC_NET_DRV_NAME);
+	printk("%s: Ethernet Address: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
+		netdev->name,
+		netdev->dev_addr[0], netdev->dev_addr[1], netdev->dev_addr[2],
+		netdev->dev_addr[3], netdev->dev_addr[4], netdev->dev_addr[5]);
+
+	card->vlan_index = -1;	/* no vlan */
+	for (i = 0; i < GELIC_NET_VLAN_MAX ;i++) {
+		status = lv1_net_control(card->dev->did.bus_id,
+					card->dev->did.dev_id,
+					GELIC_NET_GET_VLAN_ID,
+					i + 1, /* GELIC_NET_VLAN_X */
+					0, 0, &v1, &v2);
+		if (status == GELIC_NET_VLAN_NO_ENTRY) {
+			DPRINTK("GELIC_VLAN_ID no entry:%ld, VLAN disabled\n",
+				status);
+			card->vlan_id[i] = 0;
+		} else if (status) {
+			printk("GELIC_NET_VLAN_ID faild, status=%ld\n", status);
+			card->vlan_id[i] = 0;
+		} else {
+			card->vlan_id[i] = (uint32_t)v1;
+			DPRINTK("vlan_id:%d, %lx\n", i, v1);
+		}
+	}
+	if (card->vlan_id[GELIC_NET_VLAN_WIRED - 1]) {
+		card->vlan_index = GELIC_NET_VLAN_WIRED - 1;
+	}
+	return 0;
+}
+
+/**
+ * gelic_net_alloc_card - allocates net_device and card structure
+ *
+ * returns the card structure or NULL in case of errors
+ *
+ * the card and net_device structures are linked to each other
+ */
+static struct gelic_net_card *
+gelic_net_alloc_card(void)
+{
+	struct net_device *netdev;
+	struct gelic_net_card *card;
+	size_t alloc_size;
+
+	alloc_size = sizeof (*card) +
+		sizeof (struct gelic_net_descr) * rx_descriptors +
+		sizeof (struct gelic_net_descr) * tx_descriptors;
+	netdev = alloc_etherdev(alloc_size);
+	if (!netdev)
+		return NULL;
+
+	card = netdev_priv(netdev);
+	card->netdev = netdev;
+	INIT_WORK(&card->tx_timeout_task, gelic_net_tx_timeout_task);
+	init_waitqueue_head(&card->waitq);
+	atomic_set(&card->tx_timeout_task_counter, 0);
+
+	return card;
+}
+
+/**
+ * ps3_gelic_driver_probe - add a device to the control of this driver
+ */
+static int ps3_gelic_driver_probe (struct ps3_system_bus_device *dev)
+{
+	int result;
+
+	gcard = gelic_net_alloc_card();
+
+	if (!gcard) {
+		dev_dbg(&dev->core, "%s:%d: gelic_net_alloc_card failed\n",
+			__func__, __LINE__);
+		result = -ENOMEM;
+		goto fail_alloc_card;
+	}
+
+	gcard->dev = dev;
+
+	result = ps3_open_hv_device(&dev->did);
+
+	if (result) {
+		dev_dbg(&dev->core, "%s:%d: ps3_open_hv_device failed\n",
+			__func__, __LINE__);
+		goto fail_open;
+	}
+
+	result = ps3_dma_region_create(dev->d_region);
+
+	if (result) {
+		dev_dbg(&dev->core, "%s:%d: ps3_dma_region_create failed: "
+			"(%d)\n", __func__, __LINE__, result);
+		BUG_ON("check region type");
+		goto fail_dma_region;
+	}
+
+	result = lv1_net_set_interrupt_status_indicator(dev->did.bus_id,
+		dev->did.dev_id, ps3_mm_phys_to_lpar(__pa(&gelic_irq_status)),
+		0);
+
+	if (result) {
+		dev_dbg(&dev->core, "%s:%d: "
+			"lv1_net_set_interrupt_status_indicator failed: %s\n",
+			__func__, __LINE__, ps3_result(result));
+		result = -EIO;
+		goto fail_status_indicator;
+	}
+
+	result = gelic_net_setup_netdev(gcard);
+
+	if (result) {
+		dev_dbg(&dev->core, "%s:%d: ps3_dma_region_create failed: "
+			"(%d)\n", __func__, __LINE__, result);
+		goto fail_setup_netdev;
+	}
+
+	return 0;
+
+fail_setup_netdev:
+	lv1_net_set_interrupt_status_indicator(dev->did.bus_id, dev->did.dev_id,
+		0 , 0); // check if ok!!!
+fail_status_indicator:
+	ps3_dma_region_free(dev->d_region);
+fail_dma_region:
+	ps3_close_hv_device(&dev->did);
+fail_open:
+	free_netdev(gcard->netdev); // enough???
+	gcard = NULL;
+fail_alloc_card:
+	return result;
+}
+
+/**
+ * ps3_gelic_driver_remove - remove a device from the control of this driver
+ */
+
+static int
+ps3_gelic_driver_remove (struct ps3_system_bus_device *dev)
+{
+	struct net_device *netdev;
+	struct gelic_net_card *card;
+
+	card = gcard;
+	netdev = card->netdev;
+
+	wait_event(card->waitq,
+		   atomic_read(&card->tx_timeout_task_counter) == 0);
+
+	unregister_netdev(netdev);
+	free_netdev(netdev);
+
+	lv1_net_set_interrupt_status_indicator(dev->did.bus_id, dev->did.dev_id,
+		0 , 0); // check if ok!!!
+
+	ps3_dma_region_free(dev->d_region);
+
+	ps3_close_hv_device(&dev->did);
+
+	// anything else needed???
+
+	printk(" <- %s:%d:\n", __func__, __LINE__);
+	return 0;
+}
+
+static struct ps3_system_bus_driver ps3_gelic_driver = {
+	.match_id = PS3_MATCH_ID_GELIC,
+	.probe = ps3_gelic_driver_probe,
+	.remove = ps3_gelic_driver_remove,
+	.core = {
+		.name = "ps3_gelic_driver",
+	},
+};
+
+static int __init
+ps3_gelic_driver_init (void)
+{
+	return firmware_has_feature(FW_FEATURE_PS3_LV1)
+		? ps3_system_bus_driver_register(&ps3_gelic_driver)
+		: -ENODEV;
+}
+
+static void __exit
+ps3_gelic_driver_exit (void)
+{
+	ps3_system_bus_driver_unregister(&ps3_gelic_driver);
+}
+
+module_init (ps3_gelic_driver_init);
+module_exit (ps3_gelic_driver_exit);
+
+#ifdef CONFIG_GELIC_NET
+static int __init early_param_gelic_net(char *p)
+{
+	if (strstr(p, "n")) {
+		ps3_gelic_param = 0;	/* gelic_vlan off */
+		printk("ps3_gelic_param:vlan off\n");
+	} else {
+		ps3_gelic_param = 1;	/* gelic_vlan on */
+	}
+	return 0;
+
+}
+early_param("gelic_vlan", early_param_gelic_net);
+#endif

linux-2.6-ps3-kexec.patch:

--- NEW FILE linux-2.6-ps3-kexec.patch ---
As of 2007-05-04 (commit 197a8b29cbb721909e1bde44c6e7a588d93ba440):

ps3-wip/ps3-kexec-core.diff
ps3-wip/ps3-kexec-system-bus.diff
ps3-wip/ps3-kexec-usb.diff
ps3-wip/ps3-kexec-ps3fb.diff

diff --git a/arch/powerpc/platforms/ps3/htab.c b/arch/powerpc/platforms/ps3/htab.c
index ea60c45..08a9074 100644
--- a/arch/powerpc/platforms/ps3/htab.c
+++ b/arch/powerpc/platforms/ps3/htab.c
@@ -234,10 +234,18 @@ static void ps3_hpte_invalidate(unsigned long slot, unsigned long va,
 
 static void ps3_hpte_clear(void)
 {
-	/* Make sure to clean up the frame buffer device first */
-	ps3fb_cleanup();
+	int result;
 
-	lv1_unmap_htab(htab_addr);
+	DBG(" -> %s:%d\n", __func__, __LINE__);
+
+	result = lv1_unmap_htab(htab_addr);
+	BUG_ON(result);
+
+	ps3_mm_shutdown();
+
+	ps3_mm_vas_destroy();
+
+	DBG(" <- %s:%d\n", __func__, __LINE__);
 }
 
 void __init ps3_hpte_init(unsigned long htab_size)
diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c
index 9da82c2..f5c31fb 100644
--- a/arch/powerpc/platforms/ps3/interrupt.c
+++ b/arch/powerpc/platforms/ps3/interrupt.c
@@ -90,6 +90,92 @@ struct ps3_private {
 static DEFINE_PER_CPU(struct ps3_private, ps3_private);
 
 /**
+ * ps3_chip_mask - Set an interrupt mask bit in ps3_bmp.
+ * @virq: The assigned Linux virq.
+ *
+ * Sets ps3_bmp.mask and calls lv1_did_update_interrupt_mask().
+ */
+
+static void ps3_chip_mask(unsigned int virq)
+{
+	struct ps3_private *pd = get_irq_chip_data(virq);
+	u64 bit = 0x8000000000000000UL >> virq;
+	u64 *p = &pd->bmp.mask;
+	u64 old;
+	unsigned long flags;
+
+	pr_debug("%s:%d: cpu %u, virq %d\n", __func__, __LINE__, pd->cpu, virq);
+
+	local_irq_save(flags);
+	asm volatile(
+		     "1:	ldarx %0,0,%3\n"
+		     "andc	%0,%0,%2\n"
+		     "stdcx.	%0,0,%3\n"
+		     "bne-	1b"
+		     : "=&r" (old), "+m" (*p)
+		     : "r" (bit), "r" (p)
+		     : "cc" );
+
+	lv1_did_update_interrupt_mask(pd->node, pd->cpu);
+	local_irq_restore(flags);
+}
+
+/**
+ * ps3_chip_unmask - Clear an interrupt mask bit in ps3_bmp.
+ * @virq: The assigned Linux virq.
+ *
+ * Clears ps3_bmp.mask and calls lv1_did_update_interrupt_mask().
+ */
+
+static void ps3_chip_unmask(unsigned int virq)
+{
+	struct ps3_private *pd = get_irq_chip_data(virq);
+	u64 bit = 0x8000000000000000UL >> virq;
+	u64 *p = &pd->bmp.mask;
+	u64 old;
+	unsigned long flags;
+
+	pr_debug("%s:%d: cpu %u, virq %d\n", __func__, __LINE__, pd->cpu, virq);
+
+	local_irq_save(flags);
+	asm volatile(
+		     "1:	ldarx %0,0,%3\n"
+		     "or	%0,%0,%2\n"
+		     "stdcx.	%0,0,%3\n"
+		     "bne-	1b"
+		     : "=&r" (old), "+m" (*p)
+		     : "r" (bit), "r" (p)
+		     : "cc" );
+
+	lv1_did_update_interrupt_mask(pd->node, pd->cpu);
+	local_irq_restore(flags);
+}
+
+/**
+ * ps3_chip_eoi - HV end-of-interrupt.
+ * @virq: The assigned Linux virq.
+ *
+ * Calls lv1_end_of_interrupt_ext().
+ */
+
+static void ps3_chip_eoi(unsigned int virq)
+{
+	const struct ps3_private *pd = get_irq_chip_data(virq);
+	lv1_end_of_interrupt_ext(pd->node, pd->cpu, virq);
+}
+
+/**
+ * ps3_irq_chip - Represents the ps3_bmp as a Linux struct irq_chip.
+ */
+
+static struct irq_chip ps3_irq_chip = {
+	.typename = "ps3",
+	.mask = ps3_chip_mask,
+	.unmask = ps3_chip_unmask,
+	.eoi = ps3_chip_eoi,
+};
+
+/**
  * ps3_virq_setup - virq related setup.
  * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
  * serviced on.
@@ -133,6 +219,8 @@ int ps3_virq_setup(enum ps3_cpu_binding cpu, unsigned long outlet,
 		goto fail_set;
 	}
 
+	ps3_chip_mask(*virq);
+
 	return result;
 
 fail_set:
@@ -224,6 +312,8 @@ int ps3_irq_plug_destroy(unsigned int virq)
 	pr_debug("%s:%d: node %lu, cpu %d, virq %u\n", __func__, __LINE__,
 		pd->node, pd->cpu, virq);
 
+	ps3_chip_mask(virq);
+
 	result = lv1_disconnect_irq_plug_ext(pd->node, pd->cpu, virq);
 
 	if (result)
@@ -283,23 +373,21 @@ int ps3_event_receive_port_destroy(unsigned int virq)
 
 	pr_debug(" -> %s:%d virq: %u\n", __func__, __LINE__, virq);
 
+	ps3_chip_mask(virq);
+
 	result = lv1_destruct_event_receive_port(virq_to_hw(virq));
 
 	if (result)
 		pr_debug("%s:%d: lv1_destruct_event_receive_port failed: %s\n",
 			__func__, __LINE__, ps3_result(result));
 
-	/* lv1_destruct_event_receive_port() destroys the IRQ plug,
-	 * so don't call ps3_irq_plug_destroy() here.
+	/* Can't call ps3_virq_destroy() here since ps3_smp_cleanup_cpu()
+	 * calls from interrupt context (smp_call_function).
 	 */
 
-	result = ps3_virq_destroy(virq);
-	BUG_ON(result);
-
 	pr_debug(" <- %s:%d\n", __func__, __LINE__);
 	return result;
 }
-EXPORT_SYMBOL_GPL(ps3_event_receive_port_destroy);
 
 int ps3_send_event_locally(unsigned int virq)
 {
@@ -371,6 +459,13 @@ int ps3_sb_event_receive_port_destroy(const struct ps3_device_id *did,
 	result = ps3_event_receive_port_destroy(virq);
 	BUG_ON(result);
 
+	/* ps3_event_receive_port_destroy() destroys the IRQ plug,
+	 * so don't call ps3_irq_plug_destroy() here.
+	 */
+
+	result = ps3_virq_destroy(virq);
+	BUG_ON(result);
+
 	pr_debug(" <- %s:%d\n", __func__, __LINE__);
 	return result;
 }
@@ -411,16 +506,23 @@ EXPORT_SYMBOL_GPL(ps3_io_irq_setup);
 int ps3_io_irq_destroy(unsigned int virq)
 {
 	int result;
+	unsigned int outlet = virq_to_hw(virq);
 
-	result = lv1_destruct_io_irq_outlet(virq_to_hw(virq));
+	ps3_chip_mask(virq);
 
-	if (result)
-		pr_debug("%s:%d: lv1_destruct_io_irq_outlet failed: %s\n",
-			__func__, __LINE__, ps3_result(result));
+	/* lv1_destruct_io_irq_outlet() will destroy the IRQ plug,
+	 * so call ps3_irq_plug_destroy() first.
+	 */
 
 	result = ps3_irq_plug_destroy(virq);
 	BUG_ON(result);
 
+	result = lv1_destruct_io_irq_outlet(outlet);
+
+	if (result)
+		pr_debug("%s:%d: lv1_destruct_io_irq_outlet failed: %s\n",
+			__func__, __LINE__, ps3_result(result));
+
 	return result;
 }
 EXPORT_SYMBOL_GPL(ps3_io_irq_destroy);
@@ -465,6 +567,7 @@ int ps3_vuart_irq_destroy(unsigned int virq)
 {
 	int result;
 
+	ps3_chip_mask(virq);
 	result = lv1_deconfigure_virtual_uart_irq();
 
 	if (result) {
@@ -564,67 +667,6 @@ static void __attribute__ ((unused)) _dump_mask(struct ps3_private* pd,
 static void dump_bmp(struct ps3_private* pd) {};
 #endif /* defined(DEBUG) */
 
-static void ps3_chip_mask(unsigned int virq)
-{
-	struct ps3_private *pd = get_irq_chip_data(virq);
-	u64 bit = 0x8000000000000000UL >> virq;
-	u64 *p = &pd->bmp.mask;
-	u64 old;
-	unsigned long flags;
-
-	pr_debug("%s:%d: cpu %u, virq %d\n", __func__, __LINE__, pd->cpu, virq);
-
-	local_irq_save(flags);
-	asm volatile(
-		     "1:	ldarx %0,0,%3\n"
-		     "andc	%0,%0,%2\n"
-		     "stdcx.	%0,0,%3\n"
-		     "bne-	1b"
-		     : "=&r" (old), "+m" (*p)
-		     : "r" (bit), "r" (p)
-		     : "cc" );
-
-	lv1_did_update_interrupt_mask(pd->node, pd->cpu);
-	local_irq_restore(flags);
-}
-
-static void ps3_chip_unmask(unsigned int virq)
-{
-	struct ps3_private *pd = get_irq_chip_data(virq);
-	u64 bit = 0x8000000000000000UL >> virq;
-	u64 *p = &pd->bmp.mask;
-	u64 old;
-	unsigned long flags;
-
-	pr_debug("%s:%d: cpu %u, virq %d\n", __func__, __LINE__, pd->cpu, virq);
-
-	local_irq_save(flags);
-	asm volatile(
-		     "1:	ldarx %0,0,%3\n"
-		     "or	%0,%0,%2\n"
-		     "stdcx.	%0,0,%3\n"
-		     "bne-	1b"
-		     : "=&r" (old), "+m" (*p)
-		     : "r" (bit), "r" (p)
-		     : "cc" );
-
-	lv1_did_update_interrupt_mask(pd->node, pd->cpu);
-	local_irq_restore(flags);
-}
-
-static void ps3_chip_eoi(unsigned int virq)
-{
-	const struct ps3_private *pd = get_irq_chip_data(virq);
-	lv1_end_of_interrupt_ext(pd->node, pd->cpu, virq);
-}
-
-static struct irq_chip irq_chip = {
-	.typename = "ps3",
-	.mask = ps3_chip_mask,
-	.unmask = ps3_chip_unmask,
-	.eoi = ps3_chip_eoi,
-};
-
 static void ps3_host_unmap(struct irq_host *h, unsigned int virq)
 {
 	set_irq_chip_data(virq, NULL);
@@ -636,7 +678,7 @@ static int ps3_host_map(struct irq_host *h, unsigned int virq,
 	pr_debug("%s:%d: hwirq %lu, virq %u\n", __func__, __LINE__, hwirq,
 		virq);
 
-	set_irq_chip_and_handler(virq, &irq_chip, handle_fasteoi_irq);
+	set_irq_chip_and_handler(virq, &ps3_irq_chip, handle_fasteoi_irq);
 
 	return 0;
 }
diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c
index 25cf1f0..e6ff624 100644
--- a/arch/powerpc/platforms/ps3/mm.c
+++ b/arch/powerpc/platforms/ps3/mm.c
@@ -213,9 +213,15 @@ fail:
 
 void ps3_mm_vas_destroy(void)
 {
+	int result;
+
+	DBG("%s:%d: map.vas_id    = %lu\n", __func__, __LINE__, map.vas_id);
+
 	if (map.vas_id) {
-		lv1_select_virtual_address_space(0);
-		lv1_destruct_virtual_address_space(map.vas_id);
+		result = lv1_select_virtual_address_space(0);
+		BUG_ON(result);
+		result = lv1_destruct_virtual_address_space(map.vas_id);
+		BUG_ON(result);
 		map.vas_id = 0;
 	}
 }
@@ -276,8 +282,12 @@ zero_region:
 
 void ps3_mm_region_destroy(struct mem_region *r)
 {
+	int result;
+
+	DBG("%s:%d: r->base = %lxh\n", __func__, __LINE__, r->base);
 	if (r->base) {
-		lv1_release_memory(r->base);
+		result = lv1_release_memory(r->base);
+		BUG_ON(result);
 		r->size = r->base = r->offset = 0;
 		map.total = map.rm.size;
 	}
@@ -643,6 +653,13 @@ static int dma_sb_region_create(struct ps3_dma_region* r)
 	u64 len;
 	int result;
 
+	BUG_ON(!r);
+	if(!r->did.bus_id) {
+		pr_info("%s:%d: %u:%u no dma\n", __func__, __LINE__,
+			r->did.bus_id, r->did.dev_id);
+		return 0;
+	}
+
 	DBG("%s:%u: len = 0x%lx, page_size = %u, offset = 0x%lx\n", __func__,
 	    __LINE__, r->len, r->page_size, r->offset);
 	INIT_LIST_HEAD(&r->chunk_list.head);
@@ -697,6 +714,13 @@ static int dma_sb_region_free(struct ps3_dma_region* r)
 	struct dma_chunk *c;
 	struct dma_chunk *tmp;
 
+	BUG_ON(!r);
+	if(!r->did.bus_id) {
+		pr_info("%s:%d: %u:%u no dma\n", __func__, __LINE__,
+			r->did.bus_id, r->did.dev_id);
+		return 0;
+	}
+
 	list_for_each_entry_safe(c, tmp, &r->chunk_list.head, link) {
 		list_del(&c->link);
 		dma_sb_free_chunk(c);
@@ -706,7 +730,7 @@ static int dma_sb_region_free(struct ps3_dma_region* r)
 		r->bus_addr);
 
 	if (result)
-		DBG("%s:%d: lv1_free_device_dma_region failed: %s\n",
+		DBG("%s:%d: lv1_release_io_segment failed: %s\n",
 			__func__, __LINE__, ps3_result(result));
 
 	r->len = r->bus_addr = 0;
@@ -1122,12 +1146,18 @@ EXPORT_SYMBOL(ps3_dma_region_init);
 
 int ps3_dma_region_create(struct ps3_dma_region *r)
 {
+	BUG_ON(!r);
+	BUG_ON(!r->region_ops);
+	BUG_ON(!r->region_ops->create);
 	return r->region_ops->create(r);
 }
 EXPORT_SYMBOL(ps3_dma_region_create);
 
 int ps3_dma_region_free(struct ps3_dma_region *r)
 {
+	BUG_ON(!r);
+	BUG_ON(!r->region_ops);
+	BUG_ON(!r->region_ops->free);
 	return r->region_ops->free(r);
 }
 EXPORT_SYMBOL(ps3_dma_region_free);
diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c
index c989493..e045216 100644
--- a/arch/powerpc/platforms/ps3/setup.c
+++ b/arch/powerpc/platforms/ps3/setup.c
@@ -201,31 +201,28 @@ static int __init ps3_probe(void)
 #if defined(CONFIG_KEXEC)
 static void ps3_kexec_cpu_down(int crash_shutdown, int secondary)
 {
-	DBG(" -> %s:%d\n", __func__, __LINE__);
+	int result;
+	u64 ppe_id;
+	u64 thread_id = secondary ? 1 : 0;
+
+	DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, secondary);
+	ps3_smp_cleanup_cpu(thread_id);
+
+	lv1_get_logical_ppe_id(&ppe_id);
+	result = lv1_configure_irq_state_bitmap(ppe_id, secondary ? 0 : 1, 0);
 
-	if (secondary) {
-		int cpu;
-		for_each_online_cpu(cpu)
-			if (cpu)
-				ps3_smp_cleanup_cpu(cpu);
-	} else
-		ps3_smp_cleanup_cpu(0);
+	/* seems to fail on second call */
+	DBG("%s:%d: lv1_configure_irq_state_bitmap (%d) %s\n", __func__,
+		__LINE__, secondary, ps3_result(result));
 
 	DBG(" <- %s:%d\n", __func__, __LINE__);
 }
 
 static void ps3_machine_kexec(struct kimage *image)
 {
-	unsigned long ppe_id;
-
 	DBG(" -> %s:%d\n", __func__, __LINE__);
 
-	lv1_get_logical_ppe_id(&ppe_id);
-	lv1_configure_irq_state_bitmap(ppe_id, 0, 0);
-	ps3_mm_shutdown();
-	ps3_mm_vas_destroy();
-
-	default_machine_kexec(image);
+	default_machine_kexec(image); // needs ipi, never returns.
 
 	DBG(" <- %s:%d\n", __func__, __LINE__);
 }
diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c
index a2591b8..c5afa82 100644
--- a/arch/powerpc/platforms/ps3/system-bus.c
+++ b/arch/powerpc/platforms/ps3/system-bus.c
@@ -36,6 +36,71 @@ static struct device ps3_system_bus = {
         .bus_id         = "ps3_system",
 };
 
+// FIXME: need device usage counters!
+struct {
+	int id_11; // usb 0
+	int id_12; // usb 1
+} static usage_hack;
+
+int ps3_open_hv_device(struct ps3_device_id *did)
+{
+	int result;
+
+	BUG_ON(!did->bus_id); // now just for sb devices.
+
+	// FIXME: hacks for dev usage counts.
+
+	if(did->bus_id == 1 && did->dev_id == 1) {
+		usage_hack.id_11++;
+		if (usage_hack.id_11 > 1)
+			return 0;
+	}
+
+	if(did->bus_id == 1 && did->dev_id == 2) {
+		usage_hack.id_12++;
+		if (usage_hack.id_12 > 1)
+			return 0;
+	}
+
+	result = lv1_open_device(did->bus_id, did->dev_id, 0);
+
+  	if (result) {
+  		pr_debug("%s:%d: lv1_open_device failed: %s\n", __func__,
+			__LINE__, ps3_result(result));
+			result = -EPERM;
+	}
+
+	return result;
+}
+EXPORT_SYMBOL_GPL(ps3_open_hv_device);
+
+int ps3_close_hv_device(struct ps3_device_id *did)
+{
+	int result;
+
+	BUG_ON(!did->bus_id); // now just for sb devices.
+
+	// FIXME: hacks for dev usage counts.
+
+	if(did->bus_id == 1 && did->dev_id == 1) {
+		usage_hack.id_11--;
+		if (usage_hack.id_11)
+			return 0;
+	}
+
+	if(did->bus_id == 1 && did->dev_id == 2) {
+		usage_hack.id_12--;
+		if (usage_hack.id_12)
+			return 0;
+	}
+
+	result = lv1_close_device(did->bus_id, did->dev_id);
+	BUG_ON(result);
+
+	return result;
+}
+EXPORT_SYMBOL_GPL(ps3_close_hv_device);
+
 #define dump_mmio_region(_a) _dump_mmio_region(_a, __func__, __LINE__)
 static void _dump_mmio_region(const struct ps3_mmio_region* r,
 	const char* func, int line)
@@ -80,6 +145,8 @@ static int ps3_sb_free_mmio_region(struct ps3_mmio_region *r)
 {
 	int result;
 
+	dump_mmio_region(r);
+;
 	result = lv1_unmap_device_mmio_region(r->did.bus_id, r->did.dev_id,
 		r->lpar_addr);
 
@@ -156,76 +223,83 @@ static int ps3_system_bus_probe(struct device *_dev)
 {
 	int result = 0;
 	struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev);
-	struct ps3_system_bus_driver *drv =
-		to_ps3_system_bus_driver(_dev->driver);
-
-	if (dev->did.bus_id)
-		result = lv1_open_device(dev->did.bus_id, dev->did.dev_id, 0);
-
-	if (result && (result != LV1_BUSY || (dev->match_id != PS3_MATCH_ID_EHCI
-		&& dev->match_id != PS3_MATCH_ID_OHCI))) {
-		pr_debug("%s:%d: lv1_open_device failed: %s\n",
-			__func__, __LINE__, ps3_result(result));
-		result = -EACCES;
-		goto clean_none;
-	}
+	struct ps3_system_bus_driver *drv;
 
-	if (dev->d_region && dev->d_region->did.bus_id) {
-		result = ps3_dma_region_create(dev->d_region);
-
-		if (result) {
-			pr_debug("%s:%d: ps3_dma_region_create failed (%d)\n",
-				__func__, __LINE__, result);
-			BUG_ON("check region type");
-			result = -EINVAL;
-			goto clean_device;
-		}
-	}
+	BUG_ON(!dev);
+	pr_info(" -> %s:%d: %s\n", __func__, __LINE__, _dev->bus_id);
 
+	drv = to_ps3_system_bus_driver(_dev->driver);
 	BUG_ON(!drv);
 
-	if (drv->probe)
+	if(drv->probe)
 		result = drv->probe(dev);
 	else
 		pr_info("%s:%d: %s no probe method\n", __func__, __LINE__,
 			dev->core.bus_id);
 
-	if (result) {
-		pr_debug("%s:%d: drv->probe failed\n", __func__, __LINE__);
-		goto clean_dma;
-	}
-
-	return result;
-
-clean_dma:
-	if (dev->d_region && dev->d_region->did.bus_id)
-		ps3_dma_region_free(dev->d_region);
-clean_device:
-	if (dev->did.bus_id)
-		lv1_close_device(dev->did.bus_id, dev->did.dev_id);
-clean_none:
+	pr_info(" <- %s:%d: %s\n", __func__, __LINE__, dev->core.bus_id);
 	return result;
 }
 
 static int ps3_system_bus_remove(struct device *_dev)
 {
+	int result = 0;
 	struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev);
-	struct ps3_system_bus_driver *drv =
-		to_ps3_system_bus_driver(_dev->driver);
+	struct ps3_system_bus_driver *drv;
+
+	BUG_ON(!dev);
+	pr_info(" -> %s:%d: %s\n", __func__, __LINE__, _dev->bus_id);
+
+	drv = to_ps3_system_bus_driver(_dev->driver);
+	BUG_ON(!drv);
 
 	if (drv->remove)
-		drv->remove(dev);
+		result = drv->remove(dev);
 	else
 		pr_info("%s:%d: %s no remove method\n", __func__, __LINE__,
 			dev->core.bus_id);
 
-	if (dev->d_region && dev->d_region->did.dev_id)
-		ps3_dma_region_free(dev->d_region);
+	pr_info(" <- %s:%d: %s\n", __func__, __LINE__, dev->core.bus_id);
+	return result;
+}
+
+static void ps3_system_bus_shutdown(struct device *_dev)
+{
+	struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev);
+	struct ps3_system_bus_driver *drv
+		= to_ps3_system_bus_driver(_dev->driver);
+
+	BUG_ON(!dev);
+
+	pr_info(" -> %s:%d: %s, match_id %d\n", __func__, __LINE__,
+		dev->core.bus_id, dev->match_id);
+
+	if(!dev->core.driver) {
+		pr_info("%s:%d: %s: no driver bound\n", __func__, __LINE__,
+			dev->core.bus_id);
+		return;
+	}
+
+	drv = to_ps3_system_bus_driver(dev->core.driver);
 
-	if (dev->did.bus_id)
-		lv1_close_device(dev->did.bus_id, dev->did.dev_id);
+	BUG_ON(!drv);
 
-	return 0;
+	pr_info("%s:%d: %s -> %s\n", __func__, __LINE__, dev->core.bus_id,
+		drv->core.name);
+
+	if (drv->shutdown)
+		drv->shutdown(dev);
+	else if (drv->remove) {
+		pr_info("%s:%d: %s no shutdown, calling remove\n",
+			__func__, __LINE__, dev->core.bus_id);
+		drv->remove(dev);
+	} else {
+		pr_info("%s:%d: %s no shutdown method\n", __func__, __LINE__,
+			dev->core.bus_id);
+		BUG();
+	}
+
+	pr_info(" <- %s:%d: %s\n", __func__, __LINE__, dev->core.bus_id);
 }
 
 static int ps3_system_bus_uevent(struct device *_dev, char **envp,
@@ -262,6 +336,7 @@ struct bus_type ps3_system_bus_type = {
 	.match = ps3_system_bus_match,
 	.probe = ps3_system_bus_probe,
 	.remove = ps3_system_bus_remove,
+ 	.shutdown = ps3_system_bus_shutdown,
 	.uevent = ps3_system_bus_uevent,
 	.dev_attrs = ps3_system_bus_dev_attrs,
 };
@@ -272,10 +347,13 @@ int __init ps3_system_bus_init(void)
 
 	if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
 		return -ENODEV;
+
+	printk(" -> %s:%d\n", __func__, __LINE__);
 	result = device_register(&ps3_system_bus);
 	BUG_ON(result);
 	result = bus_register(&ps3_system_bus_type);
 	BUG_ON(result);
+	printk(" <- %s:%d\n", __func__, __LINE__);
 	return result;
 }
 
@@ -541,9 +619,11 @@ int ps3_system_bus_driver_register(struct ps3_system_bus_driver *drv,
 {
 	int result;
 
+	printk(" -> %s:%d: %s\n", __func__, __LINE__, drv->core.name);
 	drv->core.bus = &ps3_system_bus_type;
 
 	result = driver_register(&drv->core);
+	printk(" <- %s:%d: %s\n", __func__, __LINE__, drv->core.name);
 	return result;
 }
 
@@ -551,7 +631,9 @@ EXPORT_SYMBOL_GPL(ps3_system_bus_driver_register);
 
 void ps3_system_bus_driver_unregister(struct ps3_system_bus_driver *drv)
 {
+	printk(" -> %s:%d: %s\n", __func__, __LINE__, drv->core.name);
 	driver_unregister(&drv->core);
+	printk(" <- %s:%d: %s\n", __func__, __LINE__, drv->core.name);
 }
 
 EXPORT_SYMBOL_GPL(ps3_system_bus_driver_unregister);
diff --git a/drivers/usb/host/ehci-ps3.c b/drivers/usb/host/ehci-ps3.c
index 37b83ba..339f985 100644
--- a/drivers/usb/host/ehci-ps3.c
+++ b/drivers/usb/host/ehci-ps3.c
@@ -19,6 +19,7 @@
  */
 
 #include <asm/ps3.h>
+#include <asm/lv1call.h>
 
 static int ps3_ehci_hc_reset(struct usb_hcd *hcd)
 {
@@ -85,13 +86,30 @@ static int ps3_ehci_sb_probe(struct ps3_system_bus_device *dev)
 		goto fail_start;
 	}
 
+	result = ps3_open_hv_device(&dev->did);
+
+	if (result) {
+		dev_dbg(&dev->core, "%s:%d: ps3_open_hv_device failed\n",
+			__func__, __LINE__);
+		goto fail_open;
+	}
+
+	result = ps3_dma_region_create(dev->d_region);
+
+	if (result) {
+		dev_dbg(&dev->core, "%s:%d: ps3_dma_region_create failed: "
+			"(%d)\n", __func__, __LINE__, result);
+		BUG_ON("check region type");
+		goto fail_dma_region;
+	}
+
 	result = ps3_mmio_region_create(dev->m_region);
 
 	if (result) {
 		dev_dbg(&dev->core, "%s:%d: ps3_map_mmio_region failed\n",
 			__func__, __LINE__);
 		result = -EPERM;
-		goto fail_mmio;
+		goto fail_mmio_region;
 	}
 
 	dev_dbg(&dev->core, "%s:%d: mmio mapped_addr %lxh\n", __func__,
@@ -120,6 +138,11 @@ static int ps3_ehci_sb_probe(struct ps3_system_bus_device *dev)
 
 	hcd->rsrc_start = dev->m_region->lpar_addr;
 	hcd->rsrc_len = dev->m_region->len;
+
+	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name))
+		dev_dbg(&dev->core, "%s:%d: request_mem_region failed\n",
+			__func__, __LINE__);
+
 	hcd->regs = ioremap(dev->m_region->lpar_addr, dev->m_region->len);
 
 	if (!hcd->regs) {
@@ -153,12 +176,17 @@ static int ps3_ehci_sb_probe(struct ps3_system_bus_device *dev)
 fail_add_hcd:
 	iounmap(hcd->regs);
 fail_ioremap:
+	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
 	usb_put_hcd(hcd);
 fail_create_hcd:
 	ps3_io_irq_destroy(virq);
 fail_irq:
 	ps3_free_mmio_region(dev->m_region);
-fail_mmio:
+fail_mmio_region:
+	ps3_dma_region_free(dev->d_region);
+fail_dma_region:
+	ps3_close_hv_device(&dev->did);
+fail_open:
 fail_start:
 	return result;
 }
@@ -168,9 +196,27 @@ static int ps3_ehci_sb_remove(struct ps3_system_bus_device *dev)
 	struct usb_hcd *hcd =
 		(struct usb_hcd *)ps3_system_bus_get_driver_data(dev);
 
-	usb_put_hcd(hcd);
+	BUG_ON(!hcd);
+
+	dev_dbg(&dev->core, "%s:%d: regs %p\n", __func__, __LINE__, hcd->regs);
+	dev_dbg(&dev->core, "%s:%d: irq %u\n", __func__, __LINE__, hcd->irq);
+
+	usb_remove_hcd(hcd);
+
 	ps3_system_bus_set_driver_data(dev, NULL);
 
+	BUG_ON(!hcd->regs);
+	iounmap(hcd->regs);
+
+	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+	usb_put_hcd(hcd);
+
+	ps3_io_irq_destroy(hcd->irq);
+	ps3_free_mmio_region(dev->m_region);
+
+	ps3_dma_region_free(dev->d_region);
+	ps3_close_hv_device(&dev->did);
+
 	return 0;
 }
 
@@ -183,4 +229,5 @@ static struct ps3_system_bus_driver ps3_ehci_sb_driver = {
 	},
 	.probe = ps3_ehci_sb_probe,
 	.remove = ps3_ehci_sb_remove,
+	.shutdown = ps3_ehci_sb_remove,
 };
diff --git a/drivers/usb/host/ohci-ps3.c b/drivers/usb/host/ohci-ps3.c
index d7cf072..429628f 100644
--- a/drivers/usb/host/ohci-ps3.c
+++ b/drivers/usb/host/ohci-ps3.c
@@ -19,6 +19,7 @@
  */
 
 #include <asm/ps3.h>
+#include <asm/lv1call.h>
 
 static int ps3_ohci_hc_reset(struct usb_hcd *hcd)
 {
@@ -84,16 +85,35 @@ static int ps3_ohci_sb_probe(struct ps3_system_bus_device *dev)
 
 	if (usb_disabled()) {
 		result = -ENODEV;
+		BUG();
 		goto fail_start;
 	}
 
+	result = ps3_open_hv_device(&dev->did);
+
+	if (result) {
+		dev_dbg(&dev->core, "%s:%d: lv1_open_device failed: %s\n",
+			__func__, __LINE__, ps3_result(result));
+		result = -EPERM;
+		goto fail_open;
+	}
+
+	result = ps3_dma_region_create(dev->d_region);
+
+	if (result) {
+		dev_dbg(&dev->core, "%s:%d: ps3_dma_region_create failed: "
+			"(%d)\n", __func__, __LINE__, result);
+		BUG_ON("check region type");
+		goto fail_dma_region;
+	}
+
 	result = ps3_mmio_region_create(dev->m_region);
 
 	if (result) {
 		dev_dbg(&dev->core, "%s:%d: ps3_map_mmio_region failed\n",
 			__func__, __LINE__);
 		result = -EPERM;
-		goto fail_mmio;
+		goto fail_mmio_region;
 	}
 
 	dev_dbg(&dev->core, "%s:%d: mmio mapped_addr %lxh\n", __func__,
@@ -122,6 +142,11 @@ static int ps3_ohci_sb_probe(struct ps3_system_bus_device *dev)
 
 	hcd->rsrc_start = dev->m_region->lpar_addr;
 	hcd->rsrc_len = dev->m_region->len;
+
+	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name))
+		dev_dbg(&dev->core, "%s:%d: request_mem_region failed\n",
+			__func__, __LINE__);
+
 	hcd->regs = ioremap(dev->m_region->lpar_addr, dev->m_region->len);
 
 	if (!hcd->regs) {
@@ -155,12 +180,17 @@ static int ps3_ohci_sb_probe(struct ps3_system_bus_device *dev)
 fail_add_hcd:
 	iounmap(hcd->regs);
 fail_ioremap:
+	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
 	usb_put_hcd(hcd);
 fail_create_hcd:
 	ps3_io_irq_destroy(virq);
 fail_irq:
 	ps3_free_mmio_region(dev->m_region);
-fail_mmio:
+fail_mmio_region:
+	ps3_dma_region_free(dev->d_region);
+fail_dma_region:
+	ps3_close_hv_device(&dev->did);
+fail_open:
 fail_start:
 	return result;
 }
@@ -170,9 +200,27 @@ static int ps3_ohci_sb_remove (struct ps3_system_bus_device *dev)
 	struct usb_hcd *hcd =
 		(struct usb_hcd *)ps3_system_bus_get_driver_data(dev);
 
-	usb_put_hcd(hcd);
+	BUG_ON(!hcd);
+
+	dev_dbg(&dev->core, "%s:%d: regs %p\n", __func__, __LINE__, hcd->regs);
+	dev_dbg(&dev->core, "%s:%d: irq %u\n", __func__, __LINE__, hcd->irq);
+
+	usb_remove_hcd(hcd);
+
 	ps3_system_bus_set_driver_data(dev, NULL);
 
+	BUG_ON(!hcd->regs);
+	iounmap(hcd->regs);
+
+	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+	usb_put_hcd(hcd);
+
+	ps3_io_irq_destroy(hcd->irq);
+	ps3_free_mmio_region(dev->m_region);
+
+	ps3_dma_region_free(dev->d_region);
+	ps3_close_hv_device(&dev->did);
+
 	return 0;
 }
 
@@ -185,4 +233,5 @@ static struct ps3_system_bus_driver ps3_ohci_sb_driver = {
 	},
 	.probe = ps3_ohci_sb_probe,
 	.remove = ps3_ohci_sb_remove,
+	.shutdown = ps3_ohci_sb_remove,
 };
diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c
index 9756a72..0237237 100644
--- a/drivers/video/ps3fb.c
+++ b/drivers/video/ps3fb.c
@@ -1094,19 +1094,11 @@ err:
 	return retval;
 }
 
-static void ps3fb_shutdown(struct platform_device *dev)
-{
-	ps3fb_flip_ctl(0);	/* flip off */
-	ps3fb.dinfo->irq.mask = 0;
-	free_irq(ps3fb.irq_no, ps3fb.dev);
-	ps3_irq_plug_destroy(ps3fb.irq_no);
-	iounmap((u8 __iomem *)ps3fb.dinfo);
-}
-
 void ps3fb_cleanup(void)
 {
 	int status;
 
+	printk(" -> %s:%d\n", __func__, __LINE__);
 	if (ps3fb.task) {
 		struct task_struct *task = ps3fb.task;
 		ps3fb.task = NULL;
@@ -1135,15 +1127,32 @@ static int ps3fb_remove(struct platform_device *dev)
 {
 	struct fb_info *info = platform_get_drvdata(dev);
 
+	printk(" -> %s:%d\n", __func__, __LINE__);
+
 	if (info) {
 		unregister_framebuffer(info);
 		fb_dealloc_cmap(&info->cmap);
 		framebuffer_release(info);
 	}
 	ps3fb_cleanup();
+	printk(" <- %s:%d\n", __func__, __LINE__);
 	return 0;
 }
 
+static void ps3fb_shutdown(struct platform_device *dev)
+{
+	printk(" -> %s:%d\n", __func__, __LINE__);
+
+	ps3fb_remove(dev);
+
+	ps3fb_flip_ctl(0);	/* flip off */
+	ps3fb.dinfo->irq.mask = 0;
+	free_irq(ps3fb.irq_no, ps3fb.dev);
+	ps3_irq_plug_destroy(ps3fb.irq_no);
+	iounmap((u8 __iomem *)ps3fb.dinfo);
+	printk(" <- %s:%d\n", __func__, __LINE__);
+}
+
 static struct platform_driver ps3fb_driver = {
 	.probe	= ps3fb_probe,
 	.remove = ps3fb_remove,
diff --git a/include/asm-powerpc/ps3.h b/include/asm-powerpc/ps3.h
index 46e8282..0369120 100644
--- a/include/asm-powerpc/ps3.h
+++ b/include/asm-powerpc/ps3.h
@@ -59,6 +59,8 @@ struct ps3_device_id {
 	unsigned int dev_id;
 };
 
+int ps3_open_hv_device(struct ps3_device_id *did);
+int ps3_close_hv_device(struct ps3_device_id *did);
 
 /* dma routines */
 
@@ -357,6 +359,7 @@ struct ps3_system_bus_driver {
 	struct device_driver core;
 	int (*probe)(struct ps3_system_bus_device *);
 	int (*remove)(struct ps3_system_bus_device *);
+	int (*shutdown)(struct ps3_system_bus_device *);
 /*	int (*suspend)(struct ps3_system_bus_device *, pm_message_t); */
 /*	int (*resume)(struct ps3_system_bus_device *); */
 };

linux-2.6-ps3-legacy-bootloader-hack.patch:

--- NEW FILE linux-2.6-ps3-legacy-bootloader-hack.patch ---
A temporary hack to support the legacy 2.6.16 bootloader.  This will be
removed as soon as a 2.6.22 bootloader is ready.

Hacked-by: Geoff Levand <geoffrey.levand at am.sony.com>
---
 arch/powerpc/kernel/prom.c         |    6 ++++++
 arch/powerpc/platforms/ps3/setup.c |    4 +++-
 2 files changed, 9 insertions(+), 1 deletion(-)

--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -939,6 +939,12 @@ static int __init early_init_dt_scan_mem
 				size = 0x80000000ul - base;
 		}
 #endif
+#ifdef CONFIG_PPC_PS3
+	/* temporary hack for the legacy bootloader */
+	if (of_flat_dt_is_compatible(of_get_flat_dt_root(), "PS3PF")) {
+		size = 0x8000000;
+	}
+#endif
 		lmb_add(base, size);
 	}
 	return 0;
--- a/arch/powerpc/platforms/ps3/setup.c
+++ b/arch/powerpc/platforms/ps3/setup.c
@@ -210,7 +210,9 @@ static int __init ps3_probe(void)
 	DBG(" -> %s:%d\n", __func__, __LINE__);
 
 	dt_root = of_get_flat_dt_root();
-	if (!of_flat_dt_is_compatible(dt_root, "sony,ps3"))
+	if (!of_flat_dt_is_compatible(dt_root, "sony,ps3")
+		/* temporary hack for the legacy bootloader */
+		&& !of_flat_dt_is_compatible(dt_root, "PS3PF"))
 		return 0;
 
 	powerpc_firmware_features |= FW_FEATURE_PS3_POSSIBLE;

linux-2.6-ps3-legacy-ioport.patch:

--- NEW FILE linux-2.6-ps3-legacy-ioport.patch ---
--- linux-2.6.20.ppc64/arch/powerpc/platforms/ps3/setup.c.orig	2007-03-30 00:45:59.000000000 +0100
+++ linux-2.6.20.ppc64/arch/powerpc/platforms/ps3/setup.c	2007-03-30 00:48:29.000000000 +0100
@@ -230,6 +230,11 @@ static void ps3_machine_kexec(struct kim
 }
 #endif
 
+static int ps3_check_legacy_ioport(unsigned int baseport)
+{
+        return -ENODEV;
+}
+
 define_machine(ps3) {
 	.name				= "PS3",
 	.probe				= ps3_probe,
@@ -240,6 +245,7 @@ define_machine(ps3) {
 	.set_rtc_time			= ps3_set_rtc_time,
 	.get_rtc_time			= ps3_get_rtc_time,
 	.calibrate_decr			= ps3_calibrate_decr,
+	.check_legacy_ioport		= ps3_check_legacy_ioport,
 	.progress			= ps3_progress,
 	.restart			= ps3_restart,
 	.power_off			= ps3_power_off,

linux-2.6-ps3-memory-probe.patch:

--- NEW FILE linux-2.6-ps3-memory-probe.patch ---
--- linux-2.6.20.ppc64/include/asm-powerpc/lmb.h~	2007-02-04 18:44:54.000000000 +0000
+++ linux-2.6.20.ppc64/include/asm-powerpc/lmb.h	2007-03-30 01:13:45.000000000 +0100
@@ -51,6 +51,7 @@ extern unsigned long __init __lmb_alloc_
 extern unsigned long __init lmb_phys_mem_size(void);
 extern unsigned long __init lmb_end_of_DRAM(void);
 extern void __init lmb_enforce_memory_limit(unsigned long memory_limit);
+void __init lmb_reset_available(void);
 
 extern void lmb_dump_all(void);
 
--- linux-2.6.20.ppc64/arch/powerpc/mm/lmb.c~	2007-02-04 18:44:54.000000000 +0000
+++ linux-2.6.20.ppc64/arch/powerpc/mm/lmb.c	2007-03-30 01:12:17.000000000 +0100
@@ -338,3 +338,11 @@ void __init lmb_enforce_memory_limit(uns
 		}
 	}
 }
+
+void __init lmb_reset_available(void)
+{
+	lmb.memory.region[0].base = 0;
+	lmb.memory.region[0].size = 0;
+	lmb.memory.cnt = 1;
+	lmb.memory.size = 0;
+}
--- linux-2.6.20.ppc64/arch/powerpc/platforms/ps3/mm.c~	2007-03-29 17:48:27.000000000 +0100
+++ linux-2.6.20.ppc64/arch/powerpc/platforms/ps3/mm.c	2007-03-30 01:24:04.000000000 +0100
@@ -796,6 +796,9 @@ void __init ps3_mm_init(void)
 
 	DBG(" -> %s:%d\n", __func__, __LINE__);
 
+	/* If an old-style device-tree registered memory, forget it */
+	lmb_reset_available();
+
 	result = ps3_repository_read_mm_info(&map.rm.base, &map.rm.size,
 		&map.total);
 

linux-2.6-ps3-smp-boot.patch:

--- NEW FILE linux-2.6-ps3-smp-boot.patch ---
As of 2007-05-04 (commit 197a8b29cbb721909e1bde44c6e7a588d93ba440):

ps3-wip/powerpc-localize-mmu-off.diff
ps3-wip/powerpc-wait-for-secondary.diff

--- linux-2.6.20.ppc64/arch/powerpc/kernel/head_64.S.orig	2007-04-16 14:40:03.000000000 +0100
+++ linux-2.6.20.ppc64/arch/powerpc/kernel/head_64.S	2007-04-16 14:40:18.000000000 +0100
@@ -103,8 +103,8 @@ __secondary_hold_acknowledge:
 
 	. = 0x60
 /*
- * The following code is used on pSeries to hold secondary processors
- * in a spin loop after they have been freed from OpenFirmware, but
+ * The following code is used to hold secondary processors
+ * in a spin loop after they have entered the kernel, but
  * before the bulk of the kernel has been relocated.  This code
  * is relocated to physical address 0x60 before prom_init is run.
  * All of it must fit below the first exception vector at 0x100.
@@ -1689,9 +1689,32 @@ _GLOBAL(__start_initialization_multiplat
 2:
 
 	/* Switch off MMU if not already */
-	LOAD_REG_IMMEDIATE(r4, .__after_prom_start - KERNELBASE)
+	LOAD_REG_IMMEDIATE(r4, __mmu_off_return - KERNELBASE)
 	add	r4,r4,r30
 	bl	.__mmu_off
+__mmu_off_return:
+
+	/* Test if this is a secondary cpu and if so send it off to
+	 * __secondary_hold with a thread number in r3.  Secondary processors
+	 * call _start with regs r3,r4,r5 zeroed.
+	 * Pass cpu number in r6???
+	 */
+	or.	r3, r31, r30
+	bne	1f
+	li	r3, 1
+	b	.__secondary_hold
+1:
+
+	/* The primary cpu waits here for all the expected secondary cpus to
+	 * enter the kernel, after which time it is safe to reclaim the
+	 * memory use by the bootwrapper.
+	 * How to know what to wait for???
+	 * !!! need to use the kexec entry mechanism here!!!!
+	*/
+1:	LOAD_REG_IMMEDIATE(r4, __secondary_hold_acknowledge)
+	cmpwi	r4, 0
+	beq	1b
+	mr	r3, r30
 	b	.__after_prom_start
 
 _STATIC(__boot_from_prom)

linux-2.6-ps3-sound-autoload.patch:

--- NEW FILE linux-2.6-ps3-sound-autoload.patch ---
--- linux-2.6.21.ppc64/sound/ppc/snd_ps3.c~	2007-05-04 15:14:46.000000000 +0100
+++ linux-2.6.21.ppc64/sound/ppc/snd_ps3.c	2007-05-04 15:47:10.000000000 +0100
@@ -45,6 +45,7 @@
 MODULE_LICENSE("GPL v2");
 MODULE_DESCRIPTION("PS3 sound driver");
 MODULE_AUTHOR("Sony Computer Entertainment Inc.");
+MODULE_ALIAS("ps3:9");
 
 static int index = SNDRV_DEFAULT_IDX1;
 static char *id = SNDRV_DEFAULT_STR1;

linux-2.6-ps3-sound.patch:

--- NEW FILE linux-2.6-ps3-sound.patch ---
As of 2007-05-04 (commit 197a8b29cbb721909e1bde44c6e7a588d93ba440):

ps3-wip/ps3snd-core.diff
ps3-wip/ps3snd-bugfix.diff
ps3-wip/ps3snd-glue-2.6.20.diff
ps3-wip/ps3snd-core-2.6.20-version-up.diff
ps3-wip/ps3snd-lv1-returns-int.diff
ps3-wip/ps3snd-kill-iopte-failure.diff
ps3-wip/ps3snd-fix-noise.diff
ps3-wip/ps3snd-fix-style.diff

ps3-wip/ps3-ioc0-dma-sound.diff

unchanged:
--- a/include/asm-powerpc/lv1call.h
+++ b/include/asm-powerpc/lv1call.h
@@ -238,6 +238,7 @@ LV1_CALL(destruct_virtual_address_space,                1, 0,  10 )
 LV1_CALL(configure_irq_state_bitmap,                    3, 0,  11 )
 LV1_CALL(connect_irq_plug_ext,                          5, 0,  12 )
 LV1_CALL(release_memory,                                1, 0,  13 )
+LV1_CALL(put_iopte,                                     5, 0,  15 )
 LV1_CALL(disconnect_irq_plug_ext,                       3, 0,  17 )
 LV1_CALL(construct_event_receive_port,                  0, 1,  18 )
 LV1_CALL(destruct_event_receive_port,                   1, 0,  19 )
@@ -268,6 +269,8 @@ LV1_CALL(remove_repository_node,                        4, 0,  93 )
 LV1_CALL(read_htab_entries,                             2, 5,  95 )
 LV1_CALL(set_dabr,                                      2, 0,  96 )
 LV1_CALL(get_total_execution_time,                      2, 1, 103 )
+LV1_CALL(allocate_io_segment,                           3, 1, 116 )
+LV1_CALL(release_io_segment,                            2, 0, 117 )
 LV1_CALL(construct_io_irq_outlet,                       1, 1, 120 )
 LV1_CALL(destruct_io_irq_outlet,                        1, 0, 121 )
 LV1_CALL(map_htab,                                      1, 1, 122 )
unchanged:
--- a/sound/ppc/Kconfig
+++ b/sound/ppc/Kconfig
@@ -33,3 +33,23 @@ config SND_POWERMAC_AUTO_DRC
 	  option.
 
 endmenu
+
+menu "ALSA PowerPC devices"
+	depends on SND!=n && ( PPC64 || PPC32 )
+
+config SND_PS3
+	tristate "PS3 Audio support"
+	depends on SND && PS3_PS3AV
+	select SND_PCM
+	default m
+	help
+	  Say Y here to include support for audio on the PS3
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd_ps3.
+
+config SND_PS3_DEFAULT_START_DELAY
+	int "Startup delay time in ms"
+	depends on SND_PS3
+	default "2000"
+endmenu
unchanged:
--- a/sound/ppc/Makefile
+++ b/sound/ppc/Makefile
@@ -6,4 +6,5 @@
 snd-powermac-objs := powermac.o pmac.o awacs.o burgundy.o daca.o tumbler.o keywest.o beep.o
 
 # Toplevel Module Dependency
-obj-$(CONFIG_SND_POWERMAC) += snd-powermac.o
+obj-$(CONFIG_SND_POWERMAC)	+= snd-powermac.o
+obj-$(CONFIG_SND_PS3)		+= snd_ps3.o
diff -u b/sound/ppc/snd_ps3.c ps3-linux-dev/sound/ppc/snd_ps3.c
--- b/sound/ppc/snd_ps3.c	2007-05-04 12:30:20.000000000 +0100
+++ ps3-linux-dev/sound/ppc/snd_ps3.c
@@ -0,0 +1,1304 @@
+/*
+ * Audio support for PS3
+ * Copyright (C) 2007 Sony Computer Entertainment Inc.
+ * All rights reserved.
+ * Copyright 2006, 2007 Sony Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2 of the Licence.
+ *
+ * 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
+ */
+
+#define DEBUG
+#undef _SND_PS3_DEV_ATTR
+
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <sound/driver.h>
+#include <sound/core.h>
+#include <sound/initval.h>
+#include <sound/pcm.h>
+#include <sound/asound.h>
+#include <sound/memalloc.h>
+#include <sound/pcm_params.h>
+#include <sound/control.h>
+#include <linux/dmapool.h>
+#include <linux/dma-mapping.h>
+#include <asm/firmware.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+#include <asm/lv1call.h>
+#include <asm/ps3.h>
+#include <asm/ps3av.h>
+
+#include "snd_ps3_reg.h"
+#include "snd_ps3.h"
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("PS3 sound driver");
+MODULE_AUTHOR("Sony Computer Entertainment Inc.");
+
+static int index = SNDRV_DEFAULT_IDX1;
+static char *id = SNDRV_DEFAULT_STR1;
+
+module_param(index, int, 0444);
+MODULE_PARM_DESC(index, "Index value for PS3 soundchip.");
+module_param(id, charp, 0444);
+MODULE_PARM_DESC(id, "ID string for PS3 soundchip.");
+
+
+module_init(snd_ps3_init);
+module_exit(snd_ps3_exit);
+
+
+#if defined(_SND_PS3_DEV_ATTR)
+static DEVICE_ATTR(start_delay,
+		   S_IRUGO | S_IWUSR,
+		   snd_ps3_get_start_delay,
+		   snd_ps3_set_start_delay);
+#endif
+
+/*
+ * global
+ */
+struct snd_ps3_card_info the_card;
+
+static int snd_ps3_start_delay = CONFIG_SND_PS3_DEFAULT_START_DELAY;
+
+module_param_named(start_delay, snd_ps3_start_delay, int, 0444);
+MODULE_PARM_DESC(start_delay, "time to insert silent data in milisec");
+
+/*
+ * PS3 audio register access macros
+ */
+
+/*
+ * chip: pointer to snd_ps3_card_info
+ * name: register offset value; PS3_AUDIO_XXXX
+ */
+#define AUDIOREGPTR(chip, name) \
+	(volatile uint32_t *)(chip->mapped_mmio_vaddr + name)
+
+#define AUDIOREG(chip, name) *(AUDIOREGPTR(chip, name))
+
+/*
+ * ALSA defs
+ */
+const static struct snd_pcm_hardware snd_ps3_pcm_hw = {
+        .info = (SNDRV_PCM_INFO_MMAP |
+                 SNDRV_PCM_INFO_NONINTERLEAVED |
+                 SNDRV_PCM_INFO_MMAP_VALID),
+        .formats = (SNDRV_PCM_FMTBIT_S16_BE |
+		    SNDRV_PCM_FMTBIT_S24_BE),
+        .rates = (SNDRV_PCM_RATE_44100 |
+		  SNDRV_PCM_RATE_48000 |
+		  SNDRV_PCM_RATE_88200 |
+		  SNDRV_PCM_RATE_96000),
+        .rate_min = 44100,
+        .rate_max = 96000,
+
+        .channels_min = 2, /* stereo only */
+        .channels_max = 2,
+
+        .buffer_bytes_max = PS3_AUDIO_FIFO_SIZE * 64,
+
+	/* interrupt by four stages */
+        .period_bytes_min = PS3_AUDIO_FIFO_STAGE_SIZE * 4,
+        .period_bytes_max = PS3_AUDIO_FIFO_STAGE_SIZE * 4,
+
+        .periods_min = 16,
+	.periods_max = 32, /* buffer_size_max/ period_bytes_max */
+
+	.fifo_size = PS3_AUDIO_FIFO_SIZE
+};
+
[...2050 lines suppressed...]
+Configures user bit settings for each block (384 bits).
+Output is performed from the MSB(ao_spdub0 register bit 31).
+
+
+ 31            24 23           16 15            8 7             0
+ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
+ |                             SPOUB                             | AO_SPDUB
+ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
+*/
+/*******************************************************************************
+ *
+ * DMAC register
+ *
+ *******************************************************************************/
+/*
+The PS3_AUDIO_KICK register is used to initiate a DMA transfer and monitor its status
+
+
+ 31            24 23           16 15            8 7             0
+ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
+ |0 0 0 0 0|STATU|0 0 0|  EVENT  |0 0 0 0 0 0 0 0 0 0 0 0 0 0 0|R| KICK
+ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
+*/
+/*
+The REQUEST field is written to ACTIVE to initiate a DMA request when EVENT occurs.
+It will return to the DONE state when the request is completed.
+The registers for a DMA channel should only be written if REQUEST is IDLE.
+*/
+
+#define PS3_AUDIO_KICK_REQUEST                           (1 << 0) /* RWIVF */
+#define PS3_AUDIO_KICK_REQUEST_IDLE                      (0 << 0) /* RWI-V */
+#define PS3_AUDIO_KICK_REQUEST_ACTIVE                    (1 << 0) /* -W--T */
+
+/* The EVENT field is used to set the event in which the DMA request becomes active. */
+#define PS3_AUDIO_KICK_EVENT_MASK                        (0x1f << 16) /* RWIVF */
+#define PS3_AUDIO_KICK_EVENT_ALWAYS                      (0x00 << 16) /* RWI-V */
+#define PS3_AUDIO_KICK_EVENT_SERIALOUT0_EMPTY            (0x01 << 16) /* RW--V */
+#define PS3_AUDIO_KICK_EVENT_SERIALOUT0_UNDERFLOW        (0x02 << 16) /* RW--V */
+#define PS3_AUDIO_KICK_EVENT_SERIALOUT1_EMPTY            (0x03 << 16) /* RW--V */
+#define PS3_AUDIO_KICK_EVENT_SERIALOUT1_UNDERFLOW        (0x04 << 16) /* RW--V */
+#define PS3_AUDIO_KICK_EVENT_SERIALOUT2_EMPTY            (0x05 << 16) /* RW--V */
+#define PS3_AUDIO_KICK_EVENT_SERIALOUT2_UNDERFLOW        (0x06 << 16) /* RW--V */
+#define PS3_AUDIO_KICK_EVENT_SERIALOUT3_EMPTY            (0x07 << 16) /* RW--V */
+#define PS3_AUDIO_KICK_EVENT_SERIALOUT3_UNDERFLOW        (0x08 << 16) /* RW--V */
+#define PS3_AUDIO_KICK_EVENT_SPDIF0_BLOCKTRANSFERCOMPLETE (0x09 << 16) /* RW--V */
+#define PS3_AUDIO_KICK_EVENT_SPDIF0_UNDERFLOW            (0x0A << 16) /* RW--V */
+#define PS3_AUDIO_KICK_EVENT_SPDIF0_EMPTY                (0x0B << 16) /* RW--V */
+#define PS3_AUDIO_KICK_EVENT_SPDIF1_BLOCKTRANSFERCOMPLETE (0x0C << 16) /* RW--V */
+#define PS3_AUDIO_KICK_EVENT_SPDIF1_UNDERFLOW            (0x0D << 16) /* RW--V */
+#define PS3_AUDIO_KICK_EVENT_SPDIF1_EMPTY                (0x0E << 16) /* RW--V */
+
+#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA(n)                ((0x13 + (n)) << 16) /* RW--V */
+#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA0                  (0x13 << 16) /* RW--V */
+#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA1                  (0x14 << 16) /* RW--V */
+#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA2                  (0x15 << 16) /* RW--V */
+#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA3                  (0x16 << 16) /* RW--V */
+#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA4                  (0x17 << 16) /* RW--V */
+#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA5                  (0x18 << 16) /* RW--V */
+#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA6                  (0x19 << 16) /* RW--V */
+#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA7                  (0x1A << 16) /* RW--V */
+#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA8                  (0x1B << 16) /* RW--V */
+#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA9                  (0x1C << 16) /* RW--V */
+
+/*
+The STATUS field can be used to monitor the progress of a DMA request.
+DONE indicates the previous request has completed.
+EVENT indicates that the DMA engine is waiting for the EVENT to occur.
+PENDING indicates that the DMA engine has not started processing this
+request, but the EVENT has occured.
+DMA indicates that the data transfer is in progress.
+NOTIFY indicates that the notifier signalling end of transfer is being written.
+CLEAR indicated that the previous transfer was cleared.
+ERROR indicates the previous transfer requested an unsupported source/destination combination.
+*/
+
+#define PS3_AUDIO_KICK_STATUS_MASK                       (0x7 << 24) /* R-IVF */
+#define PS3_AUDIO_KICK_STATUS_DONE                       (0x0 << 24) /* R-I-V */
+#define PS3_AUDIO_KICK_STATUS_EVENT                      (0x1 << 24) /* R---V */
+#define PS3_AUDIO_KICK_STATUS_PENDING                    (0x2 << 24) /* R---V */
+#define PS3_AUDIO_KICK_STATUS_DMA                        (0x3 << 24) /* R---V */
+#define PS3_AUDIO_KICK_STATUS_NOTIFY                     (0x4 << 24) /* R---V */
+#define PS3_AUDIO_KICK_STATUS_CLEAR                      (0x5 << 24) /* R---V */
+#define PS3_AUDIO_KICK_STATUS_ERROR                      (0x6 << 24) /* R---V */
+
+/*
+The PS3_AUDIO_SOURCE register specifies the source address for transfers.
+
+
+ 31            24 23           16 15            8 7             0
+ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
+ |                      START                      |0 0 0 0 0|TAR| SOURCE
+ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
+*/
+
+/*
+The Audio DMA engine uses 128-byte transfers, thus the address must be aligned
+to a 128 byte boundary.  The low seven bits are assumed to be 0.
+*/
+
+#define PS3_AUDIO_SOURCE_START_MASK                      (0x01FFFFFF << 7) /* RWIUF */
+
+/*
+The TARGET field specifies the memory space containing the source address.
+*/
+
+#define PS3_AUDIO_SOURCE_TARGET_MASK                     (3 << 0) /* RWIVF */
+#define PS3_AUDIO_SOURCE_TARGET_SYSTEM_MEMORY            (2 << 0) /* RW--V */
+
+/*
+The PS3_AUDIO_DEST register specifies the destination address for transfers.
+
+
+ 31            24 23           16 15            8 7             0
+ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
+ |                      START                      |0 0 0 0 0|TAR| DEST
+ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
+*/
+
+/*
+The Audio DMA engine uses 128-byte transfers, thus the address must be aligned
+to a 128 byte boundary.  The low seven bits are assumed to be 0.
+*/
+
+#define PS3_AUDIO_DEST_START_MASK                       (0x01FFFFFF << 7) /* RWIUF */
+
+/*
+The TARGET field specifies the memory space containing the destination address
+AUDIOFIFO = Audio WriteData FIFO,
+*/
+
+#define PS3_AUDIO_DEST_TARGET_MASK                       (3 << 0) /* RWIVF */
+#define PS3_AUDIO_DEST_TARGET_AUDIOFIFO                  (1 << 0) /* RW--V */
+
+/*
+PS3_AUDIO_DMASIZE specifies the number of 128-byte blocks + 1 to transfer.
+So a value of 0 means 128-bytes will get transfered.
+
+
+ 31            24 23           16 15            8 7             0
+ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
+ |0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0|   BLOCKS    | DMASIZE
+ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
+*/
+
+
+#define PS3_AUDIO_DMASIZE_BLOCKS_MASK                    (0x7f << 0) /* RWIUF */
+
+/*
+ * source/destination address for internal fifos
+ */
+#define PS3_AUDIO_AO_3W_LDATA(n)                         (0x1000 + (0x100 * (n)))
+#define PS3_AUDIO_AO_3W_RDATA(n)                         (0x1080 + (0x100 * (n)))
+
+#define PS3_AUDIO_AO_SPD_DATA(n)                         (0x2000 + (0x400 * (n)))
+
+
+/************************************************************************
+ field attiribute
+
+	Read
+	  ' ' = Other Information
+	  '-' = Field is part of a write-only register
+	  'C' = Value read is always the same, constant value line follows (C)
+	  'R' = Value is read
+
+	Write
+	  ' ' = Other Information
+	  '-' = Must not be written (D), value ignored when written (R,A,F)
+	  'W' = Can be written
+
+	Internal State
+	  ' ' = Other Information
+	  '-' = No internal state
+	  'X' = Internal state, initial value is unknown
+	  'I' = Internal state, initial value is known and follows (I)
+
+	Declaration/Size
+	  ' ' = Other Information
+	  '-' = Does Not Apply
+	  'V' = Type is void
+	  'U' = Type is unsigned integer
+	  'S' = Type is signed integer
+	  'F' = Type is IEEE floating point
+	  '1' = Byte size (008)
+	  '2' = Short size (016)
+	  '3' = Three byte size (024)
+	  '4' = Word size (032)
+	  '8' = Double size (064)
+
+	Define Indicator
+	  ' ' = Other Information
+	  'D' = Device
+	  'M' = Memory
+	  'R' = Register
+	  'A' = Array of Registers
+	  'F' = Field
+	  'V' = Value
+          'T' = Task
+
+ **********************************************************************/

linux-2.6-ps3-stable-patches.patch:

--- NEW FILE linux-2.6-ps3-stable-patches.patch ---
All patches in ps3-stable/*.diff of ps3-linux-patches.git as of 
2007-05-04 (commit 197a8b29cbb721909e1bde44c6e7a588d93ba440).

ps3-stable/ps3-remove-bogus-dev-dbg-defs.diff
ps3-stable/ps3-fix-hardware-watchpoints.diff
ps3-stable/ps3-remove-extra-assignment.diff
ps3-stable/ps3-replace-irq-alloc-free.diff
ps3-stable/ps3-fix-slowdown-bug.diff
#ps3-stable/ps3-def-config-updates.diff

ps3-stable/ps3fb-kthread.diff
ps3-stable/ps3fb-atomic.diff
ps3-stable/ps3av-workqueue.diff
ps3-stable/ps3fb-zero-init.diff
ps3-stable/ps3av-misc.diff
ps3-stable/ps3videomode-auto-mode.diff
ps3-stable/ps3fb-__func__.diff
ps3-stable/ps3av-__func__.diff


diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 6c83fe2..5719a53 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -67,6 +67,7 @@
 #ifdef CONFIG_PPC64
 #include <asm/paca.h>
 #include <asm/firmware.h>
+#include <asm/lv1call.h>
 #endif
 
 int __irq_offset_value;
@@ -162,6 +163,16 @@ void local_irq_restore(unsigned long en)
 	local_paca->hard_enabled = en;
 	if ((int)mfspr(SPRN_DEC) < 0)
 		mtspr(SPRN_DEC, 1);
+
+	/*
+	 * Force the delivery of pending soft-disabled interrupts on PS3.
+	 * Any HV call will have this side effect.
+	 */
+	if (firmware_has_feature(FW_FEATURE_PS3_LV1)) {
+		u64 tmp;
+		lv1_get_version_info(&tmp);
+	}
+
 	hard_irq_enable();
 }
 #endif /* CONFIG_PPC64 */
diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c
index 631c300..9da82c2 100644
--- a/arch/powerpc/platforms/ps3/interrupt.c
+++ b/arch/powerpc/platforms/ps3/interrupt.c
@@ -89,7 +89,18 @@ struct ps3_private {
 
 static DEFINE_PER_CPU(struct ps3_private, ps3_private);
 
-int ps3_alloc_irq(enum ps3_cpu_binding cpu, unsigned long outlet,
+/**
+ * ps3_virq_setup - virq related setup.
+ * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
+ * serviced on.
+ * @outlet: The HV outlet from the various create outlet routines.
+ * @virq: The assigned Linux virq.
+ *
+ * Calls irq_create_mapping() to get a virq and sets the chip data to
+ * ps3_private data.
+ */
+
+int ps3_virq_setup(enum ps3_cpu_binding cpu, unsigned long outlet,
 	unsigned int *virq)
 {
 	int result;
@@ -111,17 +122,6 @@ int ps3_alloc_irq(enum ps3_cpu_binding cpu, unsigned long outlet,
 		goto fail_create;
 	}
 
-	/* Binds outlet to cpu + virq. */
-
-	result = lv1_connect_irq_plug_ext(pd->node, pd->cpu, *virq, outlet, 0);
-
-	if (result) {
-		pr_info("%s:%d: lv1_connect_irq_plug_ext failed: %s\n",
-		__func__, __LINE__, ps3_result(result));
-		result = -EPERM;
-		goto fail_connect;
-	}
-
 	pr_debug("%s:%d: outlet %lu => cpu %u, virq %u\n", __func__, __LINE__,
 		outlet, cpu, *virq);
 
@@ -136,94 +136,118 @@ int ps3_alloc_irq(enum ps3_cpu_binding cpu, unsigned long outlet,
 	return result;
 
 fail_set:
-	lv1_disconnect_irq_plug_ext(pd->node, pd->cpu, *virq);
-fail_connect:
 	irq_dispose_mapping(*virq);
 fail_create:
 	return result;
 }
-EXPORT_SYMBOL_GPL(ps3_alloc_irq);
 
-int ps3_free_irq(unsigned int virq)
+/**
+ * ps3_virq_destroy - virq related teardown.
+ * @virq: The assigned Linux virq.
+ *
+ * Clears chip data and calls irq_dispose_mapping() for the virq.
+ */
+
+int ps3_virq_destroy(unsigned int virq)
 {
-	int result;
 	const struct ps3_private *pd = get_irq_chip_data(virq);
 
 	pr_debug("%s:%d: node %lu, cpu %d, virq %u\n", __func__, __LINE__,
 		pd->node, pd->cpu, virq);
 
-	result = lv1_disconnect_irq_plug_ext(pd->node, pd->cpu, virq);
-
-	if (result)
-		pr_info("%s:%d: lv1_disconnect_irq_plug_ext failed: %s\n",
-		__func__, __LINE__, ps3_result(result));
-
 	set_irq_chip_data(virq, NULL);
 	irq_dispose_mapping(virq);
-	return result;
+
+	pr_debug("%s:%d <-\n", __func__, __LINE__);
+	return 0;
 }
-EXPORT_SYMBOL_GPL(ps3_free_irq);
 
 /**
- * ps3_alloc_io_irq - Assign a virq to a system bus device.
+ * ps3_irq_plug_setup - Generic outlet and virq related setup.
  * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
  * serviced on.
- * @interrupt_id: The device interrupt id read from the system repository.
+ * @outlet: The HV outlet from the various create outlet routines.
  * @virq: The assigned Linux virq.
  *
- * An io irq represents a non-virtualized device interrupt.  interrupt_id
- * coresponds to the interrupt number of the interrupt controller.
+ * Sets up virq and connects the irq plug.
  */
 
-int ps3_alloc_io_irq(enum ps3_cpu_binding cpu, unsigned int interrupt_id,
+int ps3_irq_plug_setup(enum ps3_cpu_binding cpu, unsigned long outlet,
 	unsigned int *virq)
 {
 	int result;
-	unsigned long outlet;
+	struct ps3_private *pd;
 
-	result = lv1_construct_io_irq_outlet(interrupt_id, &outlet);
+	result = ps3_virq_setup(cpu, outlet, virq);
 
 	if (result) {
-		pr_debug("%s:%d: lv1_construct_io_irq_outlet failed: %s\n",
-			__func__, __LINE__, ps3_result(result));
-		return result;
+		pr_debug("%s:%d: ps3_virq_setup failed\n", __func__, __LINE__);
+		goto fail_setup;
 	}
 
-	result = ps3_alloc_irq(cpu, outlet, virq);
-	BUG_ON(result);
+	pd = get_irq_chip_data(*virq);
+
+	/* Binds outlet to cpu + virq. */
+
+	result = lv1_connect_irq_plug_ext(pd->node, pd->cpu, *virq, outlet, 0);
 
+	if (result) {
+		pr_info("%s:%d: lv1_connect_irq_plug_ext failed: %s\n",
+		__func__, __LINE__, ps3_result(result));
+		result = -EPERM;
+		goto fail_connect;
+	}
+
+	return result;
+
+fail_connect:
+	ps3_virq_destroy(*virq);
+fail_setup:
 	return result;
 }
-EXPORT_SYMBOL_GPL(ps3_alloc_io_irq);
+EXPORT_SYMBOL_GPL(ps3_irq_plug_setup);
+
+/**
+ * ps3_irq_plug_destroy - Generic outlet and virq related teardown.
+ * @virq: The assigned Linux virq.
+ *
+ * Disconnects the irq plug and tears down virq.
+ * Do not call for system bus event interrupts setup with
+ * ps3_sb_event_receive_port_setup().
+ */
 
-int ps3_free_io_irq(unsigned int virq)
+int ps3_irq_plug_destroy(unsigned int virq)
 {
 	int result;
+	const struct ps3_private *pd = get_irq_chip_data(virq);
 
-	result = lv1_destruct_io_irq_outlet(virq_to_hw(virq));
+	pr_debug("%s:%d: node %lu, cpu %d, virq %u\n", __func__, __LINE__,
+		pd->node, pd->cpu, virq);
+
+	result = lv1_disconnect_irq_plug_ext(pd->node, pd->cpu, virq);
 
 	if (result)
-		pr_debug("%s:%d: lv1_destruct_io_irq_outlet failed: %s\n",
-			__func__, __LINE__, ps3_result(result));
+		pr_info("%s:%d: lv1_disconnect_irq_plug_ext failed: %s\n",
+		__func__, __LINE__, ps3_result(result));
 
-	ps3_free_irq(virq);
+	ps3_virq_destroy(virq);
 
 	return result;
 }
-EXPORT_SYMBOL_GPL(ps3_free_io_irq);
+EXPORT_SYMBOL_GPL(ps3_irq_plug_destroy);
 
 /**
- * ps3_alloc_event_irq - Allocate a virq for use with a system event.
+ * ps3_event_receive_port_setup - Setup an event receive port.
  * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
  * serviced on.
  * @virq: The assigned Linux virq.
  *
  * The virq can be used with lv1_connect_interrupt_event_receive_port() to
- * arrange to receive events, or with ps3_send_event_locally() to signal
- * events.
+ * arrange to receive interrupts from system-bus devices, or with
+ * ps3_send_event_locally() to signal events.
  */
 
-int ps3_alloc_event_irq(enum ps3_cpu_binding cpu, unsigned int *virq)
+int ps3_event_receive_port_setup(enum ps3_cpu_binding cpu, unsigned int *virq)
 {
 	int result;
 	unsigned long outlet;
@@ -237,17 +261,27 @@ int ps3_alloc_event_irq(enum ps3_cpu_binding cpu, unsigned int *virq)
 		return result;
 	}
 
-	result = ps3_alloc_irq(cpu, outlet, virq);
+	result = ps3_irq_plug_setup(cpu, outlet, virq);
 	BUG_ON(result);
 
 	return result;
 }
+EXPORT_SYMBOL_GPL(ps3_event_receive_port_setup);
+
+/**
+ * ps3_event_receive_port_destroy - Destroy an event receive port.
+ * @virq: The assigned Linux virq.
+ *
+ * Since ps3_event_receive_port_destroy destroys the receive port outlet,
+ * SB devices need to call disconnect_interrupt_event_receive_port() before
+ * this.
+ */
 
-int ps3_free_event_irq(unsigned int virq)
+int ps3_event_receive_port_destroy(unsigned int virq)
 {
 	int result;
 
-	pr_debug(" -> %s:%d\n", __func__, __LINE__);
+	pr_debug(" -> %s:%d virq: %u\n", __func__, __LINE__, virq);
 
 	result = lv1_destruct_event_receive_port(virq_to_hw(virq));
 
@@ -255,11 +289,17 @@ int ps3_free_event_irq(unsigned int virq)
 		pr_debug("%s:%d: lv1_destruct_event_receive_port failed: %s\n",
 			__func__, __LINE__, ps3_result(result));
 
-	ps3_free_irq(virq);
+	/* lv1_destruct_event_receive_port() destroys the IRQ plug,
+	 * so don't call ps3_irq_plug_destroy() here.
+	 */
+
+	result = ps3_virq_destroy(virq);
+	BUG_ON(result);
 
 	pr_debug(" <- %s:%d\n", __func__, __LINE__);
 	return result;
 }
+EXPORT_SYMBOL_GPL(ps3_event_receive_port_destroy);
 
 int ps3_send_event_locally(unsigned int virq)
 {
@@ -267,7 +307,7 @@ int ps3_send_event_locally(unsigned int virq)
 }
 
 /**
- * ps3_connect_event_irq - Assign a virq to a system bus device.
+ * ps3_sb_event_receive_port_setup - Setup a system bus event receive port.
  * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
  * serviced on.
  * @did: The HV device identifier read from the system repository.
@@ -278,13 +318,15 @@ int ps3_send_event_locally(unsigned int virq)
  * coresponds to the software interrupt number.
  */
 
-int ps3_connect_event_irq(enum ps3_cpu_binding cpu,
+int ps3_sb_event_receive_port_setup(enum ps3_cpu_binding cpu,
 	const struct ps3_device_id *did, unsigned int interrupt_id,
 	unsigned int *virq)
 {
+	/* this should go in system-bus.c */
+
 	int result;
 
-	result = ps3_alloc_event_irq(cpu, virq);
+	result = ps3_event_receive_port_setup(cpu, virq);
 
 	if (result)
 		return result;
@@ -296,7 +338,7 @@ int ps3_connect_event_irq(enum ps3_cpu_binding cpu,
 		pr_debug("%s:%d: lv1_connect_interrupt_event_receive_port"
 			" failed: %s\n", __func__, __LINE__,
 			ps3_result(result));
-		ps3_free_event_irq(*virq);
+		ps3_event_receive_port_destroy(*virq);
 		*virq = NO_IRQ;
 		return result;
 	}
@@ -306,10 +348,13 @@ int ps3_connect_event_irq(enum ps3_cpu_binding cpu,
 
 	return 0;
 }
+EXPORT_SYMBOL(ps3_sb_event_receive_port_setup);
 
-int ps3_disconnect_event_irq(const struct ps3_device_id *did,
+int ps3_sb_event_receive_port_destroy(const struct ps3_device_id *did,
 	unsigned int interrupt_id, unsigned int virq)
 {
+	/* this should go in system-bus.c */
+
 	int result;
 
 	pr_debug(" -> %s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__,
@@ -323,14 +368,65 @@ int ps3_disconnect_event_irq(const struct ps3_device_id *did,
 			" failed: %s\n", __func__, __LINE__,
 			ps3_result(result));
 
-	ps3_free_event_irq(virq);
+	result = ps3_event_receive_port_destroy(virq);
+	BUG_ON(result);
 
 	pr_debug(" <- %s:%d\n", __func__, __LINE__);
 	return result;
 }
+EXPORT_SYMBOL(ps3_sb_event_receive_port_destroy);
 
 /**
- * ps3_alloc_vuart_irq - Configure the system virtual uart virq.
+ * ps3_io_irq_setup - Setup a system bus io irq.
+ * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
+ * serviced on.
+ * @interrupt_id: The device interrupt id read from the system repository.
+ * @virq: The assigned Linux virq.
+ *
+ * An io irq represents a non-virtualized device interrupt.  interrupt_id
+ * coresponds to the interrupt number of the interrupt controller.
+ */
+
+int ps3_io_irq_setup(enum ps3_cpu_binding cpu, unsigned int interrupt_id,
+	unsigned int *virq)
+{
+	int result;
+	unsigned long outlet;
+
+	result = lv1_construct_io_irq_outlet(interrupt_id, &outlet);
+
+	if (result) {
+		pr_debug("%s:%d: lv1_construct_io_irq_outlet failed: %s\n",
+			__func__, __LINE__, ps3_result(result));
+		return result;
+	}
+
+	result = ps3_irq_plug_setup(cpu, outlet, virq);
+	BUG_ON(result);
+
+	return result;
+}
+EXPORT_SYMBOL_GPL(ps3_io_irq_setup);
+
+int ps3_io_irq_destroy(unsigned int virq)
+{
+	int result;
+
+	result = lv1_destruct_io_irq_outlet(virq_to_hw(virq));
+
+	if (result)
+		pr_debug("%s:%d: lv1_destruct_io_irq_outlet failed: %s\n",
+			__func__, __LINE__, ps3_result(result));
+
+	result = ps3_irq_plug_destroy(virq);
+	BUG_ON(result);
+
+	return result;
+}
+EXPORT_SYMBOL_GPL(ps3_io_irq_destroy);
+
+/**
+ * ps3_vuart_irq_setup - Setup the system virtual uart virq.
  * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
  * serviced on.
  * @virt_addr_bmp: The caller supplied virtual uart interrupt bitmap.
@@ -340,7 +436,7 @@ int ps3_disconnect_event_irq(const struct ps3_device_id *did,
  * freeing the interrupt will return a wrong state error.
  */
 
-int ps3_alloc_vuart_irq(enum ps3_cpu_binding cpu, void* virt_addr_bmp,
+int ps3_vuart_irq_setup(enum ps3_cpu_binding cpu, void* virt_addr_bmp,
 	unsigned int *virq)
 {
 	int result;
@@ -359,13 +455,13 @@ int ps3_alloc_vuart_irq(enum ps3_cpu_binding cpu, void* virt_addr_bmp,
 		return result;
 	}
 
-	result = ps3_alloc_irq(cpu, outlet, virq);
+	result = ps3_irq_plug_setup(cpu, outlet, virq);
 	BUG_ON(result);
 
 	return result;
 }
 
-int ps3_free_vuart_irq(unsigned int virq)
+int ps3_vuart_irq_destroy(unsigned int virq)
 {
 	int result;
 
@@ -377,13 +473,14 @@ int ps3_free_vuart_irq(unsigned int virq)
 		return result;
 	}
 
-	ps3_free_irq(virq);
+	result = ps3_irq_plug_destroy(virq);
+	BUG_ON(result);
 
 	return result;
 }
 
 /**
- * ps3_alloc_spe_irq - Configure an spe virq.
+ * ps3_spe_irq_setup - Setup an spe virq.
  * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
  * serviced on.
  * @spe_id: The spe_id returned from lv1_construct_logical_spe().
@@ -392,7 +489,7 @@ int ps3_free_vuart_irq(unsigned int virq)
  *
  */
 
-int ps3_alloc_spe_irq(enum ps3_cpu_binding cpu, unsigned long spe_id,
+int ps3_spe_irq_setup(enum ps3_cpu_binding cpu, unsigned long spe_id,
 	unsigned int class, unsigned int *virq)
 {
 	int result;
@@ -408,15 +505,16 @@ int ps3_alloc_spe_irq(enum ps3_cpu_binding cpu, unsigned long spe_id,
 		return result;
 	}
 
-	result = ps3_alloc_irq(cpu, outlet, virq);
+	result = ps3_irq_plug_setup(cpu, outlet, virq);
 	BUG_ON(result);
 
 	return result;
 }
 
-int ps3_free_spe_irq(unsigned int virq)
+int ps3_spe_irq_destroy(unsigned int virq)
 {
-	ps3_free_irq(virq);
+	int result = ps3_irq_plug_destroy(virq);
+	BUG_ON(result);
 	return 0;
 }
 
diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c
index 2014d2b..f8a3e20 100644
--- a/arch/powerpc/platforms/ps3/mm.c
+++ b/arch/powerpc/platforms/ps3/mm.c
@@ -826,5 +826,4 @@ void __init ps3_mm_init(void)
 void ps3_mm_shutdown(void)
 {
 	ps3_mm_region_destroy(&map.r1);
-	map.total = map.rm.size;
 }
diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c
index ac5df96..c989493 100644
--- a/arch/powerpc/platforms/ps3/setup.c
+++ b/arch/powerpc/platforms/ps3/setup.c
@@ -137,6 +137,12 @@ early_param("ps3fb", early_parse_ps3fb);
 #define prealloc_ps3fb_videomemory()	do { } while (0)
 #endif
 
+static int ps3_set_dabr(u64 dabr)
+{
+	enum {DABR_USER = 1, DABR_KERNEL = 2,};
+
+	return lv1_set_dabr(dabr, DABR_KERNEL | DABR_USER) ? -1 : 0;
+}
 
 static void __init ps3_setup_arch(void)
 {
@@ -234,6 +240,7 @@ define_machine(ps3) {
 	.get_boot_time			= ps3_get_boot_time,
 	.set_rtc_time			= ps3_set_rtc_time,
 	.get_rtc_time			= ps3_get_rtc_time,
+	.set_dabr			= ps3_set_dabr,
 	.calibrate_decr			= ps3_calibrate_decr,
 	.progress			= ps3_progress,
 	.restart			= ps3_restart,
diff --git a/arch/powerpc/platforms/ps3/smp.c b/arch/powerpc/platforms/ps3/smp.c
index 6fb8879..8729348 100644
--- a/arch/powerpc/platforms/ps3/smp.c
+++ b/arch/powerpc/platforms/ps3/smp.c
@@ -110,7 +110,7 @@ static void __init ps3_smp_setup_cpu(int cpu)
 	BUILD_BUG_ON(PPC_MSG_DEBUGGER_BREAK != 3);
 
 	for (i = 0; i < MSG_COUNT; i++) {
-		result = ps3_alloc_event_irq(cpu, &virqs[i]);
+		result = ps3_event_receive_port_setup(cpu, &virqs[i]);
 
 		if (result)
 			continue;
@@ -134,11 +134,13 @@ void ps3_smp_cleanup_cpu(int cpu)
 	int i;
 
 	DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, cpu);
+
 	for (i = 0; i < MSG_COUNT; i++) {
-		ps3_free_event_irq(virqs[i]);
 		free_irq(virqs[i], (void*)(long)i);
+		ps3_event_receive_port_destroy(virqs[i]);
 		virqs[i] = NO_IRQ;
 	}
+
 	DBG(" <- %s:%d: (%d)\n", __func__, __LINE__, cpu);
 }
 
diff --git a/arch/powerpc/platforms/ps3/spu.c b/arch/powerpc/platforms/ps3/spu.c
index a397e4e..0d051c3 100644
--- a/arch/powerpc/platforms/ps3/spu.c
+++ b/arch/powerpc/platforms/ps3/spu.c
@@ -230,19 +230,19 @@ static int __init setup_interrupts(struct spu *spu)
 {
 	int result;
 
-	result = ps3_alloc_spe_irq(PS3_BINDING_CPU_ANY, spu_pdata(spu)->spe_id,
+	result = ps3_spe_irq_setup(PS3_BINDING_CPU_ANY, spu_pdata(spu)->spe_id,
 		0, &spu->irqs[0]);
 
 	if (result)
 		goto fail_alloc_0;
 
-	result = ps3_alloc_spe_irq(PS3_BINDING_CPU_ANY, spu_pdata(spu)->spe_id,
+	result = ps3_spe_irq_setup(PS3_BINDING_CPU_ANY, spu_pdata(spu)->spe_id,
 		1, &spu->irqs[1]);
 
 	if (result)
 		goto fail_alloc_1;
 
-	result = ps3_alloc_spe_irq(PS3_BINDING_CPU_ANY, spu_pdata(spu)->spe_id,
+	result = ps3_spe_irq_setup(PS3_BINDING_CPU_ANY, spu_pdata(spu)->spe_id,
 		2, &spu->irqs[2]);
 
 	if (result)
@@ -251,9 +251,9 @@ static int __init setup_interrupts(struct spu *spu)
 	return result;
 
 fail_alloc_2:
-	ps3_free_spe_irq(spu->irqs[1]);
+	ps3_spe_irq_destroy(spu->irqs[1]);
 fail_alloc_1:
-	ps3_free_spe_irq(spu->irqs[0]);
+	ps3_spe_irq_destroy(spu->irqs[0]);
 fail_alloc_0:
 	spu->irqs[0] = spu->irqs[1] = spu->irqs[2] = NO_IRQ;
 	return result;
@@ -301,9 +301,9 @@ static int ps3_destroy_spu(struct spu *spu)
 	result = lv1_disable_logical_spe(spu_pdata(spu)->spe_id, 0);
 	BUG_ON(result);
 
-	ps3_free_spe_irq(spu->irqs[2]);
-	ps3_free_spe_irq(spu->irqs[1]);
-	ps3_free_spe_irq(spu->irqs[0]);
+	ps3_spe_irq_destroy(spu->irqs[2]);
+	ps3_spe_irq_destroy(spu->irqs[1]);
+	ps3_spe_irq_destroy(spu->irqs[0]);
 
 	spu->irqs[0] = spu->irqs[1] = spu->irqs[2] = NO_IRQ;
 
diff --git a/drivers/ps3/ps3av.c b/drivers/ps3/ps3av.c
index d21e04c..1393e64 100644
--- a/drivers/ps3/ps3av.c
+++ b/drivers/ps3/ps3av.c
@@ -38,7 +38,24 @@
 static int timeout = 5000;	/* in msec ( 5 sec ) */
 module_param(timeout, int, 0644);
 
-static struct ps3av ps3av;
+static struct ps3av {
+	int available;
+	struct mutex mutex;
+	struct work_struct work;
+	struct completion done;
+	struct workqueue_struct *wq;
+	int open_count;
+	struct ps3_vuart_port_device *dev;
+
+	int region;
+	struct ps3av_pkt_av_get_hw_conf av_hw_conf;
+	u32 av_port[PS3AV_AV_PORT_MAX + PS3AV_OPT_PORT_MAX];
+	u32 opt_port[PS3AV_OPT_PORT_MAX];
+	u32 head[PS3AV_HEAD_MAX];
+	u32 audio_port;
+	int ps3av_mode;
+	int ps3av_mode_old;
+} ps3av;
 
 static struct ps3_vuart_port_device ps3av_dev = {
 	.match_id = PS3_MATCH_ID_AV_SETTINGS
@@ -159,7 +176,7 @@ static int ps3av_parse_event_packet(const struct ps3av_reply_hdr *hdr)
 		else
 			printk(KERN_ERR
 			       "%s: failed event packet, cid:%08x size:%d\n",
-			       __FUNCTION__, hdr->cid, hdr->size);
+			       __func__, hdr->cid, hdr->size);
 		return 1;	/* receive event packet */
 	}
 	return 0;
@@ -181,7 +198,7 @@ static int ps3av_send_cmd_pkt(const struct ps3av_send_hdr *send_buf,
 	if (res < 0) {
 		dev_dbg(&ps3av_dev.core,
 			"%s: ps3av_vuart_write() failed (result=%d)\n",
-			__FUNCTION__, res);
+			__func__, res);
 		return res;
 	}
 
@@ -194,7 +211,7 @@ static int ps3av_send_cmd_pkt(const struct ps3av_send_hdr *send_buf,
 		if (res != PS3AV_HDR_SIZE) {
 			dev_dbg(&ps3av_dev.core,
 				"%s: ps3av_vuart_read() failed (result=%d)\n",
-				__FUNCTION__, res);
+				__func__, res);
 			return res;
 		}
 
@@ -204,7 +221,7 @@ static int ps3av_send_cmd_pkt(const struct ps3av_send_hdr *send_buf,
 		if (res < 0) {
 			dev_dbg(&ps3av_dev.core,
 				"%s: ps3av_vuart_read() failed (result=%d)\n",
-				__FUNCTION__, res);
+				__func__, res);
 			return res;
 		}
 		res += PS3AV_HDR_SIZE;	/* total len */
@@ -214,7 +231,7 @@ static int ps3av_send_cmd_pkt(const struct ps3av_send_hdr *send_buf,
 
 	if ((cmd | PS3AV_REPLY_BIT) != recv_buf->cid) {
 		dev_dbg(&ps3av_dev.core, "%s: reply err (result=%x)\n",
-			__FUNCTION__, recv_buf->cid);
+			__func__, recv_buf->cid);
 		return -EINVAL;
 	}
 
@@ -250,7 +267,7 @@ int ps3av_do_pkt(u32 cid, u16 send_len, size_t usr_buf_size,
 		 struct ps3av_send_hdr *buf)
 {
 	int res = 0;
-	union {
+	static union {
 		struct ps3av_reply_hdr reply_hdr;
 		u8 raw[PS3AV_BUF_SIZE];
 	} recv_buf;
@@ -259,8 +276,7 @@ int ps3av_do_pkt(u32 cid, u16 send_len, size_t usr_buf_size,
 
 	BUG_ON(!ps3av.available);
 
-	if (down_interruptible(&ps3av.sem))
-		return -ERESTARTSYS;
+	mutex_lock(&ps3av.mutex);
 
 	table = ps3av_search_cmd_table(cid, PS3AV_CID_MASK);
 	BUG_ON(!table);
@@ -277,7 +293,7 @@ int ps3av_do_pkt(u32 cid, u16 send_len, size_t usr_buf_size,
 	if (res < 0) {
 		printk(KERN_ERR
 		       "%s: ps3av_send_cmd_pkt() failed (result=%d)\n",
-		       __FUNCTION__, res);
+		       __func__, res);
 		goto err;
 	}
 
@@ -286,16 +302,16 @@ int ps3av_do_pkt(u32 cid, u16 send_len, size_t usr_buf_size,
 					 usr_buf_size);
 	if (res < 0) {
 		printk(KERN_ERR "%s: put_return_status() failed (result=%d)\n",
-		       __FUNCTION__, res);
+		       __func__, res);
 		goto err;
 	}
 
-	up(&ps3av.sem);
+	mutex_unlock(&ps3av.mutex);
 	return 0;
 
       err:
-	up(&ps3av.sem);
-	printk(KERN_ERR "%s: failed cid:%x res:%d\n", __FUNCTION__, cid, res);
+	mutex_unlock(&ps3av.mutex);
+	printk(KERN_ERR "%s: failed cid:%x res:%d\n", __func__, cid, res);
 	return res;
 }
 
@@ -440,7 +456,7 @@ static int ps3av_set_videomode(void)
 	ps3av_set_av_video_mute(PS3AV_CMD_MUTE_ON);
 
 	/* wake up ps3avd to do the actual video mode setting */
-	up(&ps3av.ping);
+	queue_work(ps3av.wq, &ps3av.work);
 
 	return 0;
 }
@@ -506,7 +522,7 @@ static void ps3av_set_videomode_cont(u32 id, u32 old_id)
 	if (res == PS3AV_STATUS_NO_SYNC_HEAD)
 		printk(KERN_WARNING
 		       "%s: Command failed. Please try your request again. \n",
-		       __FUNCTION__);
+		       __func__);
 	else if (res)
 		dev_dbg(&ps3av_dev.core, "ps3av_cmd_avb_param failed\n");
 
@@ -515,18 +531,10 @@ static void ps3av_set_videomode_cont(u32 id, u32 old_id)
 	ps3av_set_av_video_mute(PS3AV_CMD_MUTE_OFF);
 }
 
-static int ps3avd(void *p)
+static void ps3avd(struct work_struct *work)
 {
-	struct ps3av *info = p;
-
-	daemonize("ps3avd");
-	while (1) {
-		down(&info->ping);
-		ps3av_set_videomode_cont(info->ps3av_mode,
-					 info->ps3av_mode_old);
-		up(&info->pong);
-	}
-	return 0;
+	ps3av_set_videomode_cont(ps3av.ps3av_mode, ps3av.ps3av_mode_old);
+	complete(&ps3av.done);
 }
 
 static int ps3av_vid2table_id(int vid)
@@ -707,8 +715,7 @@ int ps3av_set_video_mode(u32 id, int boot)
 
 	size = ARRAY_SIZE(video_mode_table);
 	if ((id & PS3AV_MODE_MASK) > size - 1 || id < 0) {
-		dev_dbg(&ps3av_dev.core, "%s: error id :%d\n", __FUNCTION__,
-			id);
+		dev_dbg(&ps3av_dev.core, "%s: error id :%d\n", __func__, id);
 		return -EINVAL;
 	}
 
@@ -717,15 +724,14 @@ int ps3av_set_video_mode(u32 id, int boot)
 	if ((id & PS3AV_MODE_MASK) == 0) {
 		id = ps3av_auto_videomode(&ps3av.av_hw_conf, boot);
 		if (id < 1) {
-			printk(KERN_ERR "%s: invalid id :%d\n", __FUNCTION__,
-			       id);
+			printk(KERN_ERR "%s: invalid id :%d\n", __func__, id);
 			return -EINVAL;
 		}
 		id |= option;
 	}
 
 	/* set videomode */
-	down(&ps3av.pong);
+	wait_for_completion(&ps3av.done);
 	ps3av.ps3av_mode_old = ps3av.ps3av_mode;
 	ps3av.ps3av_mode = id;
 	if (ps3av_set_videomode())
@@ -736,6 +742,13 @@ int ps3av_set_video_mode(u32 id, int boot)
 
 EXPORT_SYMBOL_GPL(ps3av_set_video_mode);
 
+int ps3av_get_auto_mode(int boot)
+{
+	return ps3av_auto_videomode(&ps3av.av_hw_conf, boot);
+}
+
+EXPORT_SYMBOL_GPL(ps3av_get_auto_mode);
+
 int ps3av_set_mode(u32 id, int boot)
 {
 	int res;
@@ -771,7 +784,7 @@ int ps3av_get_scanmode(int id)
 	id = id & PS3AV_MODE_MASK;
 	size = ARRAY_SIZE(video_mode_table);
 	if (id > size - 1 || id < 0) {
-		printk(KERN_ERR "%s: invalid mode %d\n", __FUNCTION__, id);
+		printk(KERN_ERR "%s: invalid mode %d\n", __func__, id);
 		return -EINVAL;
 	}
 	return video_mode_table[id].interlace;
@@ -786,7 +799,7 @@ int ps3av_get_refresh_rate(int id)
 	id = id & PS3AV_MODE_MASK;
 	size = ARRAY_SIZE(video_mode_table);
 	if (id > size - 1 || id < 0) {
-		printk(KERN_ERR "%s: invalid mode %d\n", __FUNCTION__, id);
+		printk(KERN_ERR "%s: invalid mode %d\n", __func__, id);
 		return -EINVAL;
 	}
 	return video_mode_table[id].freq;
@@ -802,7 +815,7 @@ int ps3av_video_mode2res(u32 id, u32 *xres, u32 *yres)
 	id = id & PS3AV_MODE_MASK;
 	size = ARRAY_SIZE(video_mode_table);
 	if (id > size - 1 || id < 0) {
-		printk(KERN_ERR "%s: invalid mode %d\n", __FUNCTION__, id);
+		printk(KERN_ERR "%s: invalid mode %d\n", __func__, id);
 		return -EINVAL;
 	}
 	*xres = video_mode_table[id].x;
@@ -838,7 +851,7 @@ int ps3av_dev_open(void)
 		status = lv1_gpu_open(0);
 		if (status) {
 			printk(KERN_ERR "%s: lv1_gpu_open failed %d\n",
-			       __FUNCTION__, status);
+			       __func__, status);
 			ps3av.open_count--;
 		}
 	}
@@ -855,13 +868,13 @@ int ps3av_dev_close(void)
 
 	mutex_lock(&ps3av.mutex);
 	if (ps3av.open_count <= 0) {
-		printk(KERN_ERR "%s: GPU already closed\n", __FUNCTION__);
+		printk(KERN_ERR "%s: GPU already closed\n", __func__);
 		status = -1;
 	} else if (!--ps3av.open_count) {
 		status = lv1_gpu_close();
 		if (status)
 			printk(KERN_WARNING "%s: lv1_gpu_close failed %d\n",
-			       __FUNCTION__, status);
+			       __func__, status);
 	}
 	mutex_unlock(&ps3av.mutex);
 
@@ -880,13 +893,16 @@ static int ps3av_probe(struct ps3_vuart_port_device *dev)
 
 	memset(&ps3av, 0, sizeof(ps3av));
 
-	init_MUTEX(&ps3av.sem);
-	init_MUTEX_LOCKED(&ps3av.ping);
-	init_MUTEX(&ps3av.pong);
 	mutex_init(&ps3av.mutex);
 	ps3av.ps3av_mode = 0;
 	ps3av.dev = dev;
-	kernel_thread(ps3avd, &ps3av, CLONE_KERNEL);
+
+	INIT_WORK(&ps3av.work, ps3avd);
+	init_completion(&ps3av.done);
+	complete(&ps3av.done);
+	ps3av.wq = create_singlethread_workqueue("ps3avd");
+	if (!ps3av.wq)
+		return -ENOMEM;
 
 	ps3av.available = 1;
 	switch (ps3_os_area_get_av_multi_out()) {
@@ -908,7 +924,7 @@ static int ps3av_probe(struct ps3_vuart_port_device *dev)
 	/* init avsetting modules */
 	res = ps3av_cmd_init();
 	if (res < 0)
-		printk(KERN_ERR "%s: ps3av_cmd_init failed %d\n", __FUNCTION__,
+		printk(KERN_ERR "%s: ps3av_cmd_init failed %d\n", __func__,
 		       res);
 
 	ps3av_get_hw_conf(&ps3av);
@@ -926,6 +942,8 @@ static int ps3av_remove(struct ps3_vuart_port_device *dev)
 {
 	if (ps3av.available) {
 		ps3av_cmd_fin();
+		if (ps3av.wq)
+			destroy_workqueue(ps3av.wq);
 		ps3av.available = 0;
 	}
 
@@ -958,7 +976,7 @@ static int ps3av_module_init(void)
 	if (error) {
 		printk(KERN_ERR
 		       "%s: ps3_vuart_port_driver_register failed %d\n",
-		       __FUNCTION__, error);
+		       __func__, error);
 		return error;
 	}
 
@@ -966,7 +984,7 @@ static int ps3av_module_init(void)
 	if (error)
 		printk(KERN_ERR
 		       "%s: ps3_vuart_port_device_register failed %d\n",
-		       __FUNCTION__, error);
+		       __func__, error);
 
 	return error;
 }
diff --git a/drivers/ps3/ps3av_cmd.c b/drivers/ps3/ps3av_cmd.c
index bc70e81..0145ea1 100644
--- a/drivers/ps3/ps3av_cmd.c
+++ b/drivers/ps3/ps3av_cmd.c
@@ -395,7 +395,7 @@ u32 ps3av_cmd_set_video_mode(void *p, u32 head, int video_vid, int video_fmt,
 	video_mode->video_order = ps3av_video_fmt_table[video_fmt].order;
 
 	pr_debug("%s: video_mode:vid:%x width:%d height:%d pitch:%d out_format:%d format:%x order:%x\n",
-		__FUNCTION__, video_vid, video_mode->width, video_mode->height,
+		__func__, video_vid, video_mode->width, video_mode->height,
 		video_mode->pitch, video_mode->video_out_format,
 		video_mode->video_format, video_mode->video_order);
 	return sizeof(*video_mode);
@@ -477,7 +477,7 @@ static u8 ps3av_cnv_mclk(u32 fs)
 		if (ps3av_cnv_mclk_table[i].fs == fs)
 			return ps3av_cnv_mclk_table[i].mclk;
 
-	printk(KERN_ERR "%s failed, fs:%x\n", __FUNCTION__, fs);
+	printk(KERN_ERR "%s failed, fs:%x\n", __func__, fs);
 	return 0;
 }
 
@@ -526,13 +526,12 @@ static void ps3av_cnv_ns(u8 *ns, u32 fs, u32 video_vid)
 		d = 4;
 		break;
 	default:
-		printk(KERN_ERR "%s failed, vid:%x\n", __FUNCTION__,
-		       video_vid);
+		printk(KERN_ERR "%s failed, vid:%x\n", __func__, video_vid);
 		break;
 	}
 
 	if (fs < PS3AV_CMD_AUDIO_FS_44K || fs > PS3AV_CMD_AUDIO_FS_192K)
-		printk(KERN_ERR "%s failed, fs:%x\n", __FUNCTION__, fs);
+		printk(KERN_ERR "%s failed, fs:%x\n", __func__, fs);
 	else
 		ns_val = ps3av_ns_table[PS3AV_CMD_AUDIO_FS_44K-BASE][d];
 
@@ -555,8 +554,7 @@ static u8 ps3av_cnv_enable(u32 source, const u8 *enable)
 		ret = ((p[0] << 4) + (p[1] << 5) + (p[2] << 6) + (p[3] << 7)) |
 		      0x01;
 	} else
-		printk(KERN_ERR "%s failed, source:%x\n", __FUNCTION__,
-		       source);
+		printk(KERN_ERR "%s failed, source:%x\n", __func__, source);
 	return ret;
 }
 
@@ -585,7 +583,7 @@ static u8 ps3av_cnv_inputlen(u32 word_bits)
 		ret = PS3AV_CMD_AV_INPUTLEN_24;
 		break;
 	default:
-		printk(KERN_ERR "%s failed, word_bits:%x\n", __FUNCTION__,
+		printk(KERN_ERR "%s failed, word_bits:%x\n", __func__,
 		       word_bits);
 		break;
 	}
@@ -595,7 +593,7 @@ static u8 ps3av_cnv_inputlen(u32 word_bits)
 static u8 ps3av_cnv_layout(u32 num_of_ch)
 {
 	if (num_of_ch > PS3AV_CMD_AUDIO_NUM_OF_CH_8) {
-		printk(KERN_ERR "%s failed, num_of_ch:%x\n", __FUNCTION__,
+		printk(KERN_ERR "%s failed, num_of_ch:%x\n", __func__,
 		       num_of_ch);
 		return 0;
 	}
@@ -864,7 +862,7 @@ int ps3av_cmd_avb_param(struct ps3av_pkt_avb_param *avb, u32 send_len)
 
 	res = get_status(avb);
 	if (res)
-		pr_debug("%s: PS3AV_CID_AVB_PARAM: failed %x\n", __FUNCTION__,
+		pr_debug("%s: PS3AV_CID_AVB_PARAM: failed %x\n", __func__,
 			 res);
 
       out:
@@ -1013,7 +1011,7 @@ int ps3av_vuart_read(struct ps3_vuart_port_device *dev, void *buf,
 			return size;
 		if (error != -EAGAIN) {
 			printk(KERN_ERR "%s: ps3_vuart_read failed %d\n",
-			       __FUNCTION__, error);
+			       __func__, error);
 			return error;
 		}
 		msleep(POLLING_INTERVAL);
diff --git a/drivers/ps3/vuart.c b/drivers/ps3/vuart.c
index 7d7cab1..ec2d36a 100644
--- a/drivers/ps3/vuart.c
+++ b/drivers/ps3/vuart.c
@@ -886,12 +886,12 @@ static int ps3_vuart_probe(struct device *_dev)
 
 	if (++vuart_bus_priv.use_count == 1) {
 
-		result = ps3_alloc_vuart_irq(PS3_BINDING_CPU_ANY,
+		result = ps3_vuart_irq_setup(PS3_BINDING_CPU_ANY,
 			(void*)&vuart_bus_priv.bmp.status, &vuart_bus_priv.virq);
 
 		if (result) {
 			dev_dbg(&dev->core,
-				"%s:%d: ps3_alloc_vuart_irq failed (%d)\n",
+				"%s:%d: ps3_vuart_irq_setup failed (%d)\n",
 				__func__, __LINE__, result);
 			result = -EPERM;
 			goto fail_alloc_irq;
@@ -937,7 +937,7 @@ static int ps3_vuart_probe(struct device *_dev)
 fail_probe:
 	ps3_vuart_set_interrupt_mask(dev, 0);
 fail_request_irq:
-	ps3_free_vuart_irq(vuart_bus_priv.virq);
+	ps3_vuart_irq_destroy(vuart_bus_priv.virq);
 	vuart_bus_priv.virq = NO_IRQ;
 fail_alloc_irq:
 	--vuart_bus_priv.use_count;
@@ -975,7 +975,7 @@ static int ps3_vuart_remove(struct device *_dev)
 	if (--vuart_bus_priv.use_count == 0) {
 		BUG();
 		free_irq(vuart_bus_priv.virq, &vuart_bus_priv);
-		ps3_free_vuart_irq(vuart_bus_priv.virq);
+		ps3_vuart_irq_destroy(vuart_bus_priv.virq);
 		vuart_bus_priv.virq = NO_IRQ;
 	}
 
diff --git a/drivers/usb/host/ehci-ps3.c b/drivers/usb/host/ehci-ps3.c
index 4d781a2..37b83ba 100644
--- a/drivers/usb/host/ehci-ps3.c
+++ b/drivers/usb/host/ehci-ps3.c
@@ -73,13 +73,6 @@ static const struct hc_driver ps3_ehci_hc_driver = {
 #endif
 };
 
-#if !defined(DEBUG)
-#undef dev_dbg
-static inline int __attribute__ ((format (printf, 2, 3))) dev_dbg(
-	const struct device *_dev, const char *fmt, ...) {return 0;}
-#endif
-
-
 static int ps3_ehci_sb_probe(struct ps3_system_bus_device *dev)
 {
 	int result;
@@ -104,7 +97,7 @@ static int ps3_ehci_sb_probe(struct ps3_system_bus_device *dev)
 	dev_dbg(&dev->core, "%s:%d: mmio mapped_addr %lxh\n", __func__,
 		__LINE__, dev->m_region->lpar_addr);
 
-	result = ps3_alloc_io_irq(PS3_BINDING_CPU_ANY, dev->interrupt_id, &virq);
+	result = ps3_io_irq_setup(PS3_BINDING_CPU_ANY, dev->interrupt_id, &virq);
 
 	if (result) {
 		dev_dbg(&dev->core, "%s:%d: ps3_construct_io_irq(%d) failed.\n",
@@ -162,7 +155,7 @@ fail_add_hcd:
 fail_ioremap:
 	usb_put_hcd(hcd);
 fail_create_hcd:
-	ps3_free_io_irq(virq);
+	ps3_io_irq_destroy(virq);
 fail_irq:
 	ps3_free_mmio_region(dev->m_region);
 fail_mmio:
diff --git a/drivers/usb/host/ohci-ps3.c b/drivers/usb/host/ohci-ps3.c
index 62283a3..d7cf072 100644
--- a/drivers/usb/host/ohci-ps3.c
+++ b/drivers/usb/host/ohci-ps3.c
@@ -75,14 +75,6 @@ static const struct hc_driver ps3_ohci_hc_driver = {
 #endif
 };
 
-/* redefine dev_dbg to do a syntax check */
-
-#if !defined(DEBUG)
-#undef dev_dbg
-static inline int __attribute__ ((format (printf, 2, 3))) dev_dbg(
-	const struct device *_dev, const char *fmt, ...) {return 0;}
-#endif
-
 static int ps3_ohci_sb_probe(struct ps3_system_bus_device *dev)
 {
 	int result;
@@ -107,7 +99,7 @@ static int ps3_ohci_sb_probe(struct ps3_system_bus_device *dev)
 	dev_dbg(&dev->core, "%s:%d: mmio mapped_addr %lxh\n", __func__,
 		__LINE__, dev->m_region->lpar_addr);
 
-	result = ps3_alloc_io_irq(PS3_BINDING_CPU_ANY, dev->interrupt_id, &virq);
+	result = ps3_io_irq_setup(PS3_BINDING_CPU_ANY, dev->interrupt_id, &virq);
 
 	if (result) {
 		dev_dbg(&dev->core, "%s:%d: ps3_construct_io_irq(%d) failed.\n",
@@ -165,7 +157,7 @@ fail_add_hcd:
 fail_ioremap:
 	usb_put_hcd(hcd);
 fail_create_hcd:
-	ps3_free_io_irq(virq);
+	ps3_io_irq_destroy(virq);
 fail_irq:
 	ps3_free_mmio_region(dev->m_region);
 fail_mmio:
diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c
index 81e43cd..9756a72 100644
--- a/drivers/video/ps3fb.c
+++ b/drivers/video/ps3fb.c
@@ -32,6 +32,8 @@
 #include <linux/ioctl.h>
 #include <linux/notifier.h>
 #include <linux/reboot.h>
+#include <linux/kthread.h>
+#include <linux/freezer.h>
 
 #include <asm/uaccess.h>
 #include <linux/fb.h>
@@ -45,7 +47,7 @@
 #include <asm/ps3.h>
 
 #ifdef PS3FB_DEBUG
-#define DPRINTK(fmt, args...) printk("%s: " fmt, __FUNCTION__ , ##args)
+#define DPRINTK(fmt, args...) printk("%s: " fmt, __func__ , ##args)
 #else
 #define DPRINTK(fmt, args...)
 #endif
@@ -129,7 +131,6 @@ struct ps3fb_priv {
 	u64 context_handle, memory_handle;
 	void *xdr_ea;
 	struct gpu_driver_info *dinfo;
-	struct semaphore sem;
 	u32 res_index;
 
 	u64 vblank_count;	/* frame count */
@@ -139,6 +140,8 @@ struct ps3fb_priv {
 	atomic_t ext_flip;	/* on/off flip with vsync */
 	atomic_t f_count;	/* fb_open count */
 	int is_blanked;
+	int is_kicked;
+	struct task_struct *task;
 };
 static struct ps3fb_priv ps3fb;
 
@@ -294,10 +297,10 @@ static const struct fb_videomode ps3fb_modedb[] = {
 #define VP_OFF(i)	(WIDTH(i) * Y_OFF(i) * BPP + X_OFF(i) * BPP)
 #define FB_OFF(i)	(GPU_OFFSET - VP_OFF(i) % GPU_OFFSET)
 
-static int ps3fb_mode = 0;
+static int ps3fb_mode;
 module_param(ps3fb_mode, bool, 0);
 
-static char *mode_option __initdata = NULL;
+static char *mode_option __initdata;
 
 
 static int ps3fb_get_res_table(u32 xres, u32 yres)
@@ -393,7 +396,7 @@ static int ps3fb_sync(u32 frame)
 
 	if (frame > ps3fb.num_frames - 1) {
 		printk(KERN_WARNING "%s: invalid frame number (%u)\n",
-		       __FUNCTION__, frame);
+		       __func__, frame);
 		return -EINVAL;
 	}
 	offset = xres * yres * BPP * frame;
@@ -406,23 +409,26 @@ static int ps3fb_sync(u32 frame)
 					   (xres << 16) | yres,
 					   xres * BPP);	/* line_length */
 	if (status)
-		printk(KERN_ERR "%s: lv1_gpu_context_attribute FB_BLIT failed: %d\n",
-		       __FUNCTION__, status);
+		printk(KERN_ERR
+		       "%s: lv1_gpu_context_attribute FB_BLIT failed: %d\n",
+		       __func__, status);
 #ifdef HEAD_A
 	status = lv1_gpu_context_attribute(ps3fb.context_handle,
 					   L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP,
 					   0, offset, 0, 0);
 	if (status)
-		printk(KERN_ERR "%s: lv1_gpu_context_attribute FLIP failed: %d\n",
-		       __FUNCTION__, status);
+		printk(KERN_ERR
+		       "%s: lv1_gpu_context_attribute FLIP failed: %d\n",
+		       __func__, status);
 #endif
 #ifdef HEAD_B
 	status = lv1_gpu_context_attribute(ps3fb.context_handle,
 					   L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP,
 					   1, offset, 0, 0);
 	if (status)
-		printk(KERN_ERR "%s: lv1_gpu_context_attribute FLIP failed: %d\n",
-		       __FUNCTION__, status);
+		printk(KERN_ERR
+		       "%s: lv1_gpu_context_attribute FLIP failed: %d\n",
+		       __func__, status);
 #endif
 	return 0;
 }
@@ -631,7 +637,7 @@ static int ps3fb_blank(int blank, struct fb_info *info)
 {
 	int retval;
 
-	DPRINTK("%s: blank:%d\n", __FUNCTION__, blank);
+	DPRINTK("%s: blank:%d\n", __func__, blank);
 	switch (blank) {
 	case FB_BLANK_POWERDOWN:
 	case FB_BLANK_HSYNC_SUSPEND:
@@ -677,13 +683,10 @@ EXPORT_SYMBOL_GPL(ps3fb_wait_for_vsync);
 
 void ps3fb_flip_ctl(int on)
 {
-	if (on) {
-		if (atomic_read(&ps3fb.ext_flip) > 0) {
-			atomic_dec(&ps3fb.ext_flip);
-		}
-	} else {
+	if (on)
+		atomic_dec_if_positive(&ps3fb.ext_flip);
+	else
 		atomic_inc(&ps3fb.ext_flip);
-	}
 }
 
 EXPORT_SYMBOL_GPL(ps3fb_flip_ctl);
@@ -732,6 +735,11 @@ static int ps3fb_ioctl(struct fb_info *info, unsigned int cmd,
 			if (copy_from_user(&val, argp, sizeof(val)))
 				break;
 
+			if (!(val & PS3AV_MODE_MASK)) {
+				u32 id = ps3av_get_auto_mode(0);
+				if (id > 0)
+					val = (val & ~PS3AV_MODE_MASK) | id;
+			}
 			DPRINTK("PS3FB_IOCTL_SETMODE:%x\n", val);
 			retval = -EINVAL;
 			old_mode = ps3fb_mode;
@@ -783,8 +791,7 @@ static int ps3fb_ioctl(struct fb_info *info, unsigned int cmd,
 
 	case PS3FB_IOCTL_OFF:
 		DPRINTK("PS3FB_IOCTL_OFF:\n");
-		if (atomic_read(&ps3fb.ext_flip) > 0)
-			atomic_dec(&ps3fb.ext_flip);
+		atomic_dec_if_positive(&ps3fb.ext_flip);
 		retval = 0;
 		break;
 
@@ -805,11 +812,14 @@ static int ps3fb_ioctl(struct fb_info *info, unsigned int cmd,
 
 static int ps3fbd(void *arg)
 {
-	daemonize("ps3fbd");
-	for (;;) {
-		down(&ps3fb.sem);
-		if (atomic_read(&ps3fb.ext_flip) == 0)
+	while (!kthread_should_stop()) {
+		try_to_freeze();
+		set_current_state(TASK_INTERRUPTIBLE);
+		if (ps3fb.is_kicked) {
+			ps3fb.is_kicked = 0;
 			ps3fb_sync(0);	/* single buffer */
+		}
+		schedule();
 	}
 	return 0;
 }
@@ -823,15 +833,18 @@ static irqreturn_t ps3fb_vsync_interrupt(int irq, void *ptr)
 	status = lv1_gpu_context_intr(ps3fb.context_handle, &v1);
 	if (status) {
 		printk(KERN_ERR "%s: lv1_gpu_context_intr failed: %d\n",
-		       __FUNCTION__, status);
+		       __func__, status);
 		return IRQ_NONE;
 	}
 
 	if (v1 & (1 << GPU_INTR_STATUS_VSYNC_1)) {
 		/* VSYNC */
 		ps3fb.vblank_count = head->vblank_count;
-		if (!ps3fb.is_blanked)
-			up(&ps3fb.sem);
+		if (ps3fb.task && !ps3fb.is_blanked &&
+		    !atomic_read(&ps3fb.ext_flip)) {
+			ps3fb.is_kicked = 1;
+			wake_up_process(ps3fb.task);
+		}
 		wake_up_interruptible(&ps3fb.wait_vsync);
 	}
 
@@ -879,16 +892,16 @@ static int ps3fb_vsync_settings(struct gpu_driver_info *dinfo, void *dev)
 		dinfo->nvcore_frequency/1000000, dinfo->memory_frequency/1000000);
 
 	if (dinfo->version_driver != GPU_DRIVER_INFO_VERSION) {
-		printk(KERN_ERR "%s: version_driver err:%x\n", __FUNCTION__,
+		printk(KERN_ERR "%s: version_driver err:%x\n", __func__,
 		       dinfo->version_driver);
 		return -EINVAL;
 	}
 
 	ps3fb.dev = dev;
-	error = ps3_alloc_irq(PS3_BINDING_CPU_ANY, dinfo->irq.irq_outlet,
-			      &ps3fb.irq_no);
+	error = ps3_irq_plug_setup(PS3_BINDING_CPU_ANY, dinfo->irq.irq_outlet,
+				   &ps3fb.irq_no);
 	if (error) {
-		printk(KERN_ERR "%s: ps3_alloc_irq failed %d\n", __FUNCTION__,
+		printk(KERN_ERR "%s: ps3_alloc_irq failed %d\n", __func__,
 		       error);
 		return error;
 	}
@@ -896,9 +909,9 @@ static int ps3fb_vsync_settings(struct gpu_driver_info *dinfo, void *dev)
 	error = request_irq(ps3fb.irq_no, ps3fb_vsync_interrupt, IRQF_DISABLED,
 			    "ps3fb vsync", ps3fb.dev);
 	if (error) {
-		printk(KERN_ERR "%s: request_irq failed %d\n", __FUNCTION__,
+		printk(KERN_ERR "%s: request_irq failed %d\n", __func__,
 		       error);
-		ps3_free_irq(ps3fb.irq_no);
+		ps3_irq_plug_destroy(ps3fb.irq_no);
 		return error;
 	}
 
@@ -915,7 +928,7 @@ static int ps3fb_xdr_settings(u64 xdr_lpar)
 				       xdr_lpar, ps3fb_videomemory.size, 0);
 	if (status) {
 		printk(KERN_ERR "%s: lv1_gpu_context_iomap failed: %d\n",
-		       __FUNCTION__, status);
+		       __func__, status);
 		return -ENXIO;
 	}
 	DPRINTK("video:%p xdr_ea:%p ioif:%lx lpar:%lx phys:%lx size:%lx\n",
@@ -927,8 +940,9 @@ static int ps3fb_xdr_settings(u64 xdr_lpar)
 					   xdr_lpar, ps3fb_videomemory.size,
 					   GPU_IOIF, 0);
 	if (status) {
-		printk(KERN_ERR "%s: lv1_gpu_context_attribute FB_SETUP failed: %d\n",
-		       __FUNCTION__, status);
+		printk(KERN_ERR
+		       "%s: lv1_gpu_context_attribute FB_SETUP failed: %d\n",
+		       __func__, status);
 		return -ENXIO;
 	}
 	return 0;
@@ -968,13 +982,14 @@ static int __init ps3fb_probe(struct platform_device *dev)
 	u64 xdr_lpar;
 	int status;
 	unsigned long offset;
+	struct task_struct *task;
 
 	/* get gpu context handle */
 	status = lv1_gpu_memory_allocate(DDR_SIZE, 0, 0, 0, 0,
 					 &ps3fb.memory_handle, &ddr_lpar);
 	if (status) {
 		printk(KERN_ERR "%s: lv1_gpu_memory_allocate failed: %d\n",
-		       __FUNCTION__, status);
+		       __func__, status);
 		goto err;
 	}
 	DPRINTK("ddr:lpar:0x%lx\n", ddr_lpar);
@@ -985,14 +1000,14 @@ static int __init ps3fb_probe(struct platform_device *dev)
 					  &lpar_reports, &lpar_reports_size);
 	if (status) {
 		printk(KERN_ERR "%s: lv1_gpu_context_attribute failed: %d\n",
-		       __FUNCTION__, status);
+		       __func__, status);
 		goto err_gpu_memory_free;
 	}
 
 	/* vsync interrupt */
 	ps3fb.dinfo = ioremap(lpar_driver_info, 128 * 1024);
 	if (!ps3fb.dinfo) {
-		printk(KERN_ERR "%s: ioremap failed\n", __FUNCTION__);
+		printk(KERN_ERR "%s: ioremap failed\n", __func__);
 		goto err_gpu_context_free;
 	}
 
@@ -1050,16 +1065,25 @@ static int __init ps3fb_probe(struct platform_device *dev)
 	       "fb%d: PS3 frame buffer device, using %ld KiB of video memory\n",
 	       info->node, ps3fb_videomemory.size >> 10);
 
-	kernel_thread(ps3fbd, info, CLONE_KERNEL);
+	task = kthread_run(ps3fbd, info, "ps3fbd");
+	if (IS_ERR(task)) {
+		retval = PTR_ERR(task);
+		goto err_unregister_framebuffer;
+	}
+
+	ps3fb.task = task;
+
 	return 0;
 
+err_unregister_framebuffer:
+	unregister_framebuffer(info);
 err_fb_dealloc:
 	fb_dealloc_cmap(&info->cmap);
 err_framebuffer_release:
 	framebuffer_release(info);
 err_free_irq:
 	free_irq(ps3fb.irq_no, ps3fb.dev);
-	ps3_free_irq(ps3fb.irq_no);
+	ps3_irq_plug_destroy(ps3fb.irq_no);
 err_iounmap_dinfo:
 	iounmap((u8 __iomem *)ps3fb.dinfo);
 err_gpu_context_free:
@@ -1075,7 +1099,7 @@ static void ps3fb_shutdown(struct platform_device *dev)
 	ps3fb_flip_ctl(0);	/* flip off */
 	ps3fb.dinfo->irq.mask = 0;
 	free_irq(ps3fb.irq_no, ps3fb.dev);
-	ps3_free_irq(ps3fb.irq_no);
+	ps3_irq_plug_destroy(ps3fb.irq_no);
 	iounmap((u8 __iomem *)ps3fb.dinfo);
 }
 
@@ -1083,9 +1107,14 @@ void ps3fb_cleanup(void)
 {
 	int status;
 
+	if (ps3fb.task) {
+		struct task_struct *task = ps3fb.task;
+		ps3fb.task = NULL;
+		kthread_stop(task);
+	}
 	if (ps3fb.irq_no) {
 		free_irq(ps3fb.irq_no, ps3fb.dev);
-		ps3_free_irq(ps3fb.irq_no);
+		ps3_irq_plug_destroy(ps3fb.irq_no);
 	}
 	iounmap((u8 __iomem *)ps3fb.dinfo);
 
@@ -1137,8 +1166,9 @@ int ps3fb_set_sync(void)
 					   L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC,
 					   0, L1GPU_DISPLAY_SYNC_VSYNC, 0, 0);
 	if (status) {
-		printk(KERN_ERR "%s: lv1_gpu_context_attribute DISPLAY_SYNC failed: %d\n",
-		       __FUNCTION__, status);
+		printk(KERN_ERR
+		       "%s: lv1_gpu_context_attribute DISPLAY_SYNC failed: %d\n",
+		       __func__, status);
 		return -1;
 	}
 #endif
@@ -1148,8 +1178,9 @@ int ps3fb_set_sync(void)
 					   1, L1GPU_DISPLAY_SYNC_VSYNC, 0, 0);
 
 	if (status) {
-		printk(KERN_ERR "%s: lv1_gpu_context_attribute DISPLAY_MODE failed: %d\n",
-		       __FUNCTION__, status);
+		printk(KERN_ERR
+		       "%s: lv1_gpu_context_attribute DISPLAY_MODE failed: %d\n",
+		       __func__, status);
 		return -1;
 	}
 #endif
@@ -1174,7 +1205,7 @@ static int __init ps3fb_init(void)
 
 	error = ps3av_dev_open();
 	if (error) {
-		printk(KERN_ERR "%s: ps3av_dev_open failed\n", __FUNCTION__);
+		printk(KERN_ERR "%s: ps3av_dev_open failed\n", __func__);
 		goto err;
 	}
 
@@ -1195,7 +1226,6 @@ static int __init ps3fb_init(void)
 
 	atomic_set(&ps3fb.f_count, -1);	/* fbcon opens ps3fb */
 	atomic_set(&ps3fb.ext_flip, 0);	/* for flip with vsync */
-	init_MUTEX(&ps3fb.sem);
 	init_waitqueue_head(&ps3fb.wait_vsync);
 	ps3fb.num_frames = 1;
 
diff --git a/include/asm-powerpc/ps3.h b/include/asm-powerpc/ps3.h
index 821581a..13c372d 100644
--- a/include/asm-powerpc/ps3.h
+++ b/include/asm-powerpc/ps3.h
@@ -167,26 +167,31 @@ enum ps3_cpu_binding {
 	PS3_BINDING_CPU_1 = 1,
 };
 
-int ps3_alloc_io_irq(enum ps3_cpu_binding cpu, unsigned int interrupt_id,
+int ps3_virq_setup(enum ps3_cpu_binding cpu, unsigned long outlet,
 	unsigned int *virq);
-int ps3_free_io_irq(unsigned int virq);
-int ps3_alloc_event_irq(enum ps3_cpu_binding cpu, unsigned int *virq);
-int ps3_free_event_irq(unsigned int virq);
+int ps3_virq_destroy(unsigned int virq);
+int ps3_irq_plug_setup(enum ps3_cpu_binding cpu, unsigned long outlet,
+	unsigned int *virq);
+int ps3_irq_plug_destroy(unsigned int virq);
+int ps3_event_receive_port_setup(enum ps3_cpu_binding cpu, unsigned int *virq);
+int ps3_event_receive_port_destroy(unsigned int virq);
 int ps3_send_event_locally(unsigned int virq);
-int ps3_connect_event_irq(enum ps3_cpu_binding cpu,
-	const struct ps3_device_id *did, unsigned int interrupt_id,
+
+int ps3_io_irq_setup(enum ps3_cpu_binding cpu, unsigned int interrupt_id,
 	unsigned int *virq);
-int ps3_disconnect_event_irq(const struct ps3_device_id *did,
-	unsigned int interrupt_id, unsigned int virq);
-int ps3_alloc_vuart_irq(enum ps3_cpu_binding cpu, void* virt_addr_bmp,
+int ps3_io_irq_destroy(unsigned int virq);
+int ps3_vuart_irq_setup(enum ps3_cpu_binding cpu, void* virt_addr_bmp,
 	unsigned int *virq);
-int ps3_free_vuart_irq(unsigned int virq);
-int ps3_alloc_spe_irq(enum ps3_cpu_binding cpu, unsigned long spe_id,
+int ps3_vuart_irq_destroy(unsigned int virq);
+int ps3_spe_irq_setup(enum ps3_cpu_binding cpu, unsigned long spe_id,
 	unsigned int class, unsigned int *virq);
-int ps3_free_spe_irq(unsigned int virq);
-int ps3_alloc_irq(enum ps3_cpu_binding cpu, unsigned long outlet,
+int ps3_spe_irq_destroy(unsigned int virq);
+
+int ps3_sb_event_receive_port_setup(enum ps3_cpu_binding cpu,
+	const struct ps3_device_id *did, unsigned int interrupt_id,
 	unsigned int *virq);
-int ps3_free_irq(unsigned int virq);
+int ps3_sb_event_receive_port_destroy(const struct ps3_device_id *did,
+	unsigned int interrupt_id, unsigned int virq);
 
 /* lv1 result codes */
 
diff --git a/include/asm-powerpc/ps3av.h b/include/asm-powerpc/ps3av.h
index 43e90ea..9efc40f 100644
--- a/include/asm-powerpc/ps3av.h
+++ b/include/asm-powerpc/ps3av.h
@@ -18,8 +18,6 @@
 #ifndef _ASM_POWERPC_PS3AV_H_
 #define _ASM_POWERPC_PS3AV_H_
 
-#include <linux/mutex.h>
-
 /** command for ioctl() **/
 #define PS3AV_VERSION 0x205	/* version of ps3av command */
 
@@ -643,24 +641,6 @@ struct ps3av_pkt_avb_param {
 	u8 buf[PS3AV_PKT_AVB_PARAM_MAX_BUF_SIZE];
 };
 
-struct ps3av {
-	int available;
-	struct semaphore sem;
-	struct semaphore ping;
-	struct semaphore pong;
-	struct mutex mutex;
-	int open_count;
-	struct ps3_vuart_port_device *dev;
-
-	int region;
-	struct ps3av_pkt_av_get_hw_conf av_hw_conf;
-	u32 av_port[PS3AV_AV_PORT_MAX + PS3AV_OPT_PORT_MAX];
-	u32 opt_port[PS3AV_OPT_PORT_MAX];
-	u32 head[PS3AV_HEAD_MAX];
-	u32 audio_port;
-	int ps3av_mode;
-	int ps3av_mode_old;
-};
 
 /** command status **/
 #define PS3AV_STATUS_SUCCESS			0x0000	/* success */
@@ -718,6 +698,7 @@ static inline void ps3av_cmd_av_monitor_info_dump(const struct ps3av_pkt_av_get_
 extern int ps3av_cmd_video_get_monitor_info(struct ps3av_pkt_av_get_monitor_info *,
 					    u32);
 
+struct ps3_vuart_port_device;
 extern int ps3av_vuart_write(struct ps3_vuart_port_device *dev,
 			     const void *buf, unsigned long size);
 extern int ps3av_vuart_read(struct ps3_vuart_port_device *dev, void *buf,
@@ -725,6 +706,7 @@ extern int ps3av_vuart_read(struct ps3_vuart_port_device *dev, void *buf,
 
 extern int ps3av_set_video_mode(u32, int);
 extern int ps3av_set_audio_mode(u32, u32, u32, u32, u32);
+extern int ps3av_get_auto_mode(int);
 extern int ps3av_set_mode(u32, int);
 extern int ps3av_get_mode(void);
 extern int ps3av_get_scanmode(int);

linux-2.6-ps3-storage-alias.patch:

--- NEW FILE linux-2.6-ps3-storage-alias.patch ---
--- linux-2.6.22.ppc64/drivers/block/ps3disk.c~	2007-07-25 16:06:16.000000000 +0100
+++ linux-2.6.22.ppc64/drivers/block/ps3disk.c	2007-07-26 08:49:44.000000000 +0100
@@ -628,3 +628,4 @@ MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("PS3 Disk Storage Driver");
 MODULE_AUTHOR("Sony Corporation");
 MODULE_ALIAS(PS3_MODULE_ALIAS_STOR_DISK);
+MODULE_ALIAS("ps3_storage");

linux-2.6-ps3-storage.patch:

--- NEW FILE linux-2.6-ps3-storage.patch ---
As of 2007-05-04 (commit 197a8b29cbb721909e1bde44c6e7a588d93ba440):

ps3-wip/ps3stor+snd-mem-hack.diff
ps3-wip/ps3_storage.diff
ps3-hacks/ps3stor-repository-exports.diff
ps3-hacks/ps3stor_alloc_bootmem_buffer.diff
ps3-hacks/ps3stor_use_bootmem_buffer.diff
ps3-hacks/ps3-bootmem_buffers-exports.diff
ps3-wip/ps3stor_repository.diff
ps3-wip/ps3_repository_find_bus.diff
ps3-wip/ps3stor_repository-2.diff
ps3-wip/ps3stor_kill_DYNAMIC_BOUNCE.diff
ps3-wip/ps3stor_rw_semaphore.diff
ps3-wip/ps3stor-readcd.diff
ps3-wip/ps3stor_modalias.diff


diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c
index e6ff624..64b56d7 100644
--- a/arch/powerpc/platforms/ps3/mm.c
+++ b/arch/powerpc/platforms/ps3/mm.c
@@ -129,6 +129,16 @@ static void _debug_dump_map(const struct map* m, const char* func, int line)
 
 static struct map map;
 
+// FIXME Temporary solution for the storage and sound drivers
+unsigned long ps3_mem_total;
+EXPORT_SYMBOL_GPL(ps3_mem_total);
+unsigned long ps3_rm_limit;
+EXPORT_SYMBOL_GPL(ps3_rm_limit);
+unsigned long ps3_2nd_mem_base;
+EXPORT_SYMBOL_GPL(ps3_2nd_mem_base);
+unsigned long ps3_2nd_mem_size;
+EXPORT_SYMBOL_GPL(ps3_2nd_mem_size);
+
 /**
  * ps3_mm_phys_to_lpar - translate a linux physical address to lpar address
  * @phys_addr: linux physical address
@@ -1212,6 +1222,12 @@ void __init ps3_mm_init(void)
 	/* correct map.total for the real total amount of memory we use */
 	map.total = map.rm.size + map.r1.size;
 
+	// FIXME Temporary solution for the storage and sound drivers
+	ps3_mem_total = map.rm.size + map.r1.size;
+	ps3_rm_limit = map.rm.size;
+	ps3_2nd_mem_base = map.r1.base;
+	ps3_2nd_mem_size = map.r1.size;
+
 	DBG(" <- %s:%d\n", __func__, __LINE__);
 }
 
diff --git a/arch/powerpc/platforms/ps3/platform.h b/arch/powerpc/platforms/ps3/platform.h
index 4a1015b..dc56127 100644
--- a/arch/powerpc/platforms/ps3/platform.h
+++ b/arch/powerpc/platforms/ps3/platform.h
@@ -134,6 +134,8 @@ struct ps3_repository_device {
 	struct ps3_device_id did;
 };
 
+int ps3_repository_find_bus(enum ps3_bus_type bus_type, unsigned int from,
+	unsigned int *bus_index);
 int ps3_repository_find_device(enum ps3_bus_type bus_type,
 	enum ps3_dev_type dev_type,
 	const struct ps3_repository_device *start_dev,
diff --git a/arch/powerpc/platforms/ps3/repository.c b/arch/powerpc/platforms/ps3/repository.c
index ae586a0..e0067bf 100644
--- a/arch/powerpc/platforms/ps3/repository.c
+++ b/arch/powerpc/platforms/ps3/repository.c
@@ -182,6 +182,7 @@ int ps3_repository_read_bus_id(unsigned int bus_index, unsigned int *bus_id)
 	*bus_id = v1;
 	return result;
 }
+EXPORT_SYMBOL_GPL(ps3_repository_read_bus_id);
 
 int ps3_repository_read_bus_type(unsigned int bus_index,
 	enum ps3_bus_type *bus_type)
@@ -197,6 +198,7 @@ int ps3_repository_read_bus_type(unsigned int bus_index,
 	*bus_type = v1;
 	return result;
 }
+EXPORT_SYMBOL_GPL(ps3_repository_read_bus_type);
 
 int ps3_repository_read_bus_num_dev(unsigned int bus_index,
 	unsigned int *num_dev)
@@ -212,6 +214,7 @@ int ps3_repository_read_bus_num_dev(unsigned int bus_index,
 	*num_dev = v1;
 	return result;
 }
+EXPORT_SYMBOL_GPL(ps3_repository_read_bus_num_dev);
 
 int ps3_repository_read_dev_str(unsigned int bus_index,
 	unsigned int dev_index, const char *dev_str, u64 *value)
@@ -239,6 +242,7 @@ int ps3_repository_read_dev_id(unsigned int bus_index, unsigned int dev_index,
 	*dev_id = v1;
 	return result;
 }
+EXPORT_SYMBOL_GPL(ps3_repository_read_dev_id);
 
 int ps3_repository_read_dev_type(unsigned int bus_index,
 	unsigned int dev_index, enum ps3_dev_type *dev_type)
@@ -255,6 +259,7 @@ int ps3_repository_read_dev_type(unsigned int bus_index,
 	*dev_type = v1;
 	return result;
 }
+EXPORT_SYMBOL_GPL(ps3_repository_read_dev_type);
 
 int ps3_repository_read_dev_intr(unsigned int bus_index,
 	unsigned int dev_index, unsigned int intr_index,
@@ -274,6 +279,7 @@ int ps3_repository_read_dev_intr(unsigned int bus_index,
 	*interrupt_id = v2;
 	return result;
 }
+EXPORT_SYMBOL_GPL(ps3_repository_read_dev_intr);
 
 int ps3_repository_read_dev_reg_type(unsigned int bus_index,
 	unsigned int dev_index, unsigned int reg_index,
@@ -513,6 +519,31 @@ int ps3_repository_dump_bus_info(void)
 }
 #endif /* defined(DEBUG) */
 
+int ps3_repository_find_bus(enum ps3_bus_type bus_type, unsigned int from,
+	unsigned int *bus_index)
+{
+	unsigned int i;
+	enum ps3_bus_type type;
+	int error;
+
+	for (i = from; i < 10; i++) {
+		error = ps3_repository_read_bus_type(i, &type);
+		if (error) {
+			pr_debug("%s:%d read_bus_type failed\n",
+				__func__, __LINE__);
+			*bus_index = UINT_MAX;
+			return error;
+		}
+		if (type == bus_type) {
+			*bus_index = i;
+			return 0;
+		}
+	}
+	*bus_index = UINT_MAX;
+	return -ENODEV;
+}
+EXPORT_SYMBOL_GPL(ps3_repository_find_bus);
+
 static int find_device(unsigned int bus_index, unsigned int num_dev,
 	unsigned int start_dev_index, enum ps3_dev_type dev_type,
 	struct ps3_repository_device *dev)
@@ -541,7 +572,7 @@ static int find_device(unsigned int bus_index, unsigned int num_dev,
 	}
 
 	if (dev_index == num_dev)
-		return -1;
+		return -ENODEV;
 
 	pr_debug("%s:%d: found dev_type %u at dev_index %u\n",
 		__func__, __LINE__, dev_type, dev_index);
@@ -577,25 +608,14 @@ int ps3_repository_find_device (enum ps3_bus_type bus_type,
 
 	BUG_ON(start_dev && start_dev->bus_index > 10);
 
-	for (bus_index = start_dev ? start_dev->bus_index : 0; bus_index < 10;
-		bus_index++) {
-		enum ps3_bus_type x;
-
-		result = ps3_repository_read_bus_type(bus_index, &x);
-
-		if (result) {
-			pr_debug("%s:%d read_bus_type failed\n",
-				__func__, __LINE__);
-			dev->bus_index = UINT_MAX;
-			return result;
-		}
-		if (x == bus_type)
-			break;
+	result = ps3_repository_find_bus(bus_type,
+					 start_dev ? start_dev->bus_index : 0,
+					 &bus_index);
+	if (result) {
+		dev->bus_index = UINT_MAX;
+		return result;
 	}
 
-	if (bus_index >= 10)
-		return -ENODEV;
-
 	pr_debug("%s:%d: found bus_type %u at bus_index %u\n",
 		__func__, __LINE__, bus_type, bus_index);
 
@@ -630,6 +650,7 @@ int ps3_repository_find_device (enum ps3_bus_type bus_type,
 
 	return result;
 }
+EXPORT_SYMBOL_GPL(ps3_repository_find_device);
 
 int ps3_repository_find_interrupt(const struct ps3_repository_device *dev,
 	enum ps3_interrupt_type intr_type, unsigned int *interrupt_id)
@@ -668,6 +689,7 @@ int ps3_repository_find_interrupt(const struct ps3_repository_device *dev,
 
[...2911 lines suppressed...]
+struct lv1_atapi_cmnd_block {
+	u8	pkt[32];	/* packet command block           */
+	u32	pktlen;		/* should be 12 for ATAPI 8020    */
+	u32	blocks;
+	u32	block_size;
+	u32	proto;		/* transfer mode                  */
+	u32	in_out;		/* transfer direction             */
+	u64	buffer;		/* parameter except command block */
+	u32	arglen;		/* length above                   */
+};
+
+enum lv1_atapi_proto {
+	NA_PROTO = -1,
+	NON_DATA_PROTO     = 0,
+	PIO_DATA_IN_PROTO  = 1,
+	PIO_DATA_OUT_PROTO = 2,
+	DMA_PROTO = 3
+};
+
+enum lv1_atapi_in_out {
+	DIR_NA = -1,
+	DIR_WRITE = 0, /* memory -> device */
+	DIR_READ = 1 /* device -> memory */
+};
+
+/*
+ * describe protocol of an ATAPI command
+ */
+struct ps3_stor_dev_info;
+
+struct scsi_command_handler_info {
+	int buflen;
+	int proto;
+	int in_out;
+	int (*cmnd_handler)(struct ps3_stor_dev_info *, struct scsi_cmnd *);
+};
+
+/*
+ * to position parameter
+ */
+enum {
+	NOT_AVAIL          = -1,
+	USE_SRB_10         = -2,
+	USE_SRB_6          = -3,
+	USE_CDDA_FRAME_RAW = -4
+};
+/*
+ * for LV1 maintainance
+ */
+enum  {
+	PS3_STORAGE_PATA_0, /* primary   PATA bus */
+	PS3_STORAGE_PATA_1, /* secondary PATA bus */
+	PS3_STORAGE_FLASH,
+	PS3_STORAGE_NUM_OF_BUS_TYPES /* terminator */
+};
+
+/*
+ * LV1 per physical bus info:
+ * PATA0, PATA1, FLASH
+ */
+struct ps3_stor_lv1_bus_info {
+	int bus_type;           /* PATA0, PATA1, FLASH */
+	int devices;            /* number of devices on the bus */
+	struct list_head dev_list;
+};
+
+/*
+ * LV1 per region info
+ */
+struct ps3_stor_lv1_region_info {
+	int region_index;	/* index of this region       */
+	unsigned int region_id;	/* id of this region          */
+	u64 region_size;	/* region size in sector      */
+	u64 region_start;	/* start sector */
+};
+
+/*
+ * LV1 per device info
+ */
+struct ps3_stor_lv1_dev_info {
+	struct list_head bus_dev_list; /* device list of devices          */
+				       /* which share same physical bus   */
+	struct ps3_stor_dev_info * dev_info;
+	/* repository values */
+	struct ps3_repository_device repo;
+	enum ps3_dev_type device_type;	/* bus#X.dev#Y.type     */
+	u64 attached_port;		/* bus#x.dev#Y.port     */
+	u64 sector_size;		/* bus#X.dev#Y.blk_size */
+
+	/* house keeping */
+	int bus_type;			/* PATA0,1 or FLASH */
+	unsigned int irq_plug_id;
+	unsigned int interrupt_id;
+	u64 dma_region;
+	u64 current_tag;
+	int bus_device_index;		/*
+					 * device index of same lv1 phy bus.
+					 * 0 for first device, 1 for second.
+					 * should be same as SCSI id
+					 */
+	/* regions */
+	unsigned int regions;	/* number of regions reported thru repository */
+	unsigned long accessible_region_flag; /* flag of accessible regions */
+	unsigned int accessible_regions; /* number of accessible regions of this dev.
+				 * currently, this includes region #0
+				 * NOTE: maximum is 8, if exceed, the rest of
+				 * regions are ignored
+				 */
+	struct ps3_stor_lv1_region_info * region_info_array;
+};
+
+enum read_or_write {
+	SCSIDEBUG_READ,
+	SCSIDEBUG_WRITE
+};
+
+
+enum thread_wakeup_reason {
+	SRB_QUEUED,
+	THREAD_TERMINATE
+};
+
+enum bounce_buffer_type {
+	DEDICATED_KMALLOC,
+	DEDICATED_SPECIAL,
+};
+
+struct ps3_stor_dev_info {
+	struct list_head dev_list;
+	struct ps3_stor_lv1_dev_info * lv1_dev_info;
+	struct ps3_stor_host_info *host_info;
+	const struct scsi_command_handler_info * handler_info;
+	unsigned int target;
+
+	u64 sector_size;	/* copied from lv1 repository at initialize */
+	/* devices may change these value */
+	struct rw_semaphore bounce_sem;	/* protect the following members:
+					* bounce_buf (pointer itself, not buffer),
+					* dedicated_bounce_size
+					* max_sectors in scsi_dev->request_queue
+					*/
+	int  dedicated_bounce;	/* set nonzero if the bounce buffer is dedicated */
+	int  dedicated_bounce_size;
+	int  dedicated_dma_region; /* set if partial dma region allocated */
+	enum bounce_buffer_type bounce_type;	/* bounce buffer type */
+	void * bounce_buf;
+	u64 separate_bounce_lpar; /* lpar address for separated buffer  */
+
+	char used;
+
+	/* main thread communication */
+	struct task_struct * thread_struct;
+	spinlock_t srb_lock;
+	struct scsi_cmnd * srb;              /* queued srb; just one srb allowd             */
+	struct semaphore thread_sema;        /* device main thread wakeup                   */
+	struct completion thread_terminated; /* notify thread temination to slave_destory() */
+	int thread_wakeup_reason;
+
+	/* interrupt handler communication */
+	struct completion irq_done;
+	volatile u64 lv1_status;	/* result of get_async_status() */
+	volatile int lv1_retval;	/* return value of get_async_status() */
+
+};
+
+struct ps3_stor_host_info {
+	struct list_head host_list;
+	struct Scsi_Host *scsi_host;
+	struct platform_device dev;
+	struct list_head dev_info_list;
+	struct ps3_stor_lv1_bus_info * lv1_bus_info;
+};
+
+#define from_dev_to_ps3_stor_host(p) \
+	container_of(p, struct ps3_stor_host_info, dev)
+#define from_dev_to_scsi_device(p) \
+	container_of(p, struct scsi_device, sdev_gendev)
+
+
+struct ps3_stor_quirk_probe_info {
+	struct completion irq_done;
+	unsigned int device_id;
+	int lv1_retval;
+	u64 lv1_status;
+	u64 lv1_tag;
+	u64 lv1_ret_tag;
+};
+
+
+#define NOTIFICATION_DEVID ((u64)(-1L))
+
+struct device_probe_info {
+	unsigned int device_id;
+	enum ps3_dev_type device_type;
+	int      found;
+	int      region_expected;
+	int      region_ready;
+};
+
+#endif

linux-2.6-ps3-system-bus-rework-2.patch:

--- NEW FILE linux-2.6-ps3-system-bus-rework-2.patch ---
Relevant parts of ps3-wip/ps3-ioc0-dma-clients-adopted.diff

diff --git a/drivers/net/gelic_net.c b/drivers/net/gelic_net.c
index 48ad627..82c5744 100644
--- a/drivers/net/gelic_net.c
+++ b/drivers/net/gelic_net.c
@@ -1771,7 +1771,8 @@ static int __init
 ps3_gelic_driver_init (void)
 {
 	return firmware_has_feature(FW_FEATURE_PS3_LV1)
-		? ps3_system_bus_driver_register(&ps3_gelic_driver)
+		? ps3_system_bus_driver_register(&ps3_gelic_driver,
+						 PS3_IOBUS_SB)
 		: -ENODEV;
 }
 
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index c7458f7..d0881eb 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -973,8 +973,8 @@ static int __init ehci_hcd_init(void)
 
 #ifdef PS3_SYSTEM_BUS_DRIVER
 	if (firmware_has_feature(FW_FEATURE_PS3_LV1)) {
-		retval = ps3_system_bus_driver_register(
-				&PS3_SYSTEM_BUS_DRIVER);
+		retval = ps3_system_bus_driver_register(&PS3_SYSTEM_BUS_DRIVER,
+							PS3_IOBUS_SB);
 		if (retval < 0) {
 #ifdef PLATFORM_DRIVER
 			platform_driver_unregister(&PLATFORM_DRIVER);
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index e8bbe8b..fd2e1ab 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -942,8 +942,8 @@ static int __init ohci_hcd_mod_init(void)
 
 #ifdef PS3_SYSTEM_BUS_DRIVER
 	if (firmware_has_feature(FW_FEATURE_PS3_LV1)) {
-		retval = ps3_system_bus_driver_register(
-				&PS3_SYSTEM_BUS_DRIVER);
+		retval = ps3_system_bus_driver_register(&PS3_SYSTEM_BUS_DRIVER,
+							PS3_IOBUS_SB);
 		if (retval < 0)
 			goto error_ps3;
 	}

linux-2.6-ps3-system-bus-rework.patch:

--- NEW FILE linux-2.6-ps3-system-bus-rework.patch ---
As of 2007-05-04 (commit 197a8b29cbb721909e1bde44c6e7a588d93ba440):

ps3-wip/ps3-system-bus-rework.diff
ps3-wip/ps3-system-bus-uevent.diff
ps3-wip/ps3-system-bus-add-modinfo-attribute.diff

diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c
index 2014d2b..e1136f7 100644
--- a/arch/powerpc/platforms/ps3/mm.c
+++ b/arch/powerpc/platforms/ps3/mm.c
@@ -17,6 +17,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
+#define DEBUG
 
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -32,7 +33,7 @@
 #if defined(DEBUG)
 #define DBG(fmt...) udbg_printf(fmt)
 #else
-#define DBG(fmt...) do{if(0)printk(fmt);}while(0)
+#define DBG(fmt...) do { if (0) printk(fmt);} while (0)
 #endif
 
 enum {
@@ -329,17 +330,19 @@ core_initcall(ps3_mm_add_memory);
 /*============================================================================*/
 
 /**
- * dma_lpar_to_bus - Translate an lpar address to ioc mapped bus address.
+ * dma_sb_lpar_to_bus - Translate an lpar address to ioc mapped bus address.
  * @r: pointer to dma region structure
  * @lpar_addr: HV lpar address
  */
 
-static unsigned long dma_lpar_to_bus(struct ps3_dma_region *r,
+static unsigned long dma_sb_lpar_to_bus(struct ps3_dma_region *r,
 	unsigned long lpar_addr)
 {
-	BUG_ON(lpar_addr >= map.r1.base + map.r1.size);
-	return r->bus_addr + (lpar_addr <= map.rm.size ? lpar_addr
-		: lpar_addr - map.r1.offset);
+	if (lpar_addr >= map.rm.size)
+		lpar_addr -= map.r1.offset;
+	BUG_ON(lpar_addr < r->offset);
+	BUG_ON(lpar_addr >= r->offset + r->len);
+	return r->bus_addr + lpar_addr - r->offset;
 }
 
 #define dma_dump_region(_a) _dma_dump_region(_a, __func__, __LINE__)
@@ -351,6 +354,7 @@ static void _dma_dump_region(const struct ps3_dma_region *r, const char* func,
 	DBG("%s:%d: page_size  %u\n", func, line, r->page_size);
 	DBG("%s:%d: bus_addr   %lxh\n", func, line, r->bus_addr);
 	DBG("%s:%d: len        %lxh\n", func, line, r->len);
+	DBG("%s:%d: offset     %lxh\n", func, line, r->offset);
 }
 
 /**
@@ -385,6 +389,7 @@ static void _dma_dump_chunk (const struct dma_chunk* c, const char* func,
 	DBG("%s:%d: r.bus_addr   %lxh\n", func, line, c->region->bus_addr);
 	DBG("%s:%d: r.page_size  %u\n", func, line, c->region->page_size);
 	DBG("%s:%d: r.len        %lxh\n", func, line, c->region->len);
+	DBG("%s:%d: r.offset     %lxh\n", func, line, c->region->offset);
 	DBG("%s:%d: c.lpar_addr  %lxh\n", func, line, c->lpar_addr);
 	DBG("%s:%d: c.bus_addr   %lxh\n", func, line, c->bus_addr);
 	DBG("%s:%d: c.len        %lxh\n", func, line, c->len);
@@ -395,33 +400,62 @@ static struct dma_chunk * dma_find_chunk(struct ps3_dma_region *r,
 {
 	struct dma_chunk *c;
 	unsigned long aligned_bus = _ALIGN_DOWN(bus_addr, 1 << r->page_size);
-	unsigned long aligned_len = _ALIGN_UP(len, 1 << r->page_size);
+	unsigned long aligned_len = _ALIGN_UP(len+bus_addr-aligned_bus,
+					      1 << r->page_size);
 
 	list_for_each_entry(c, &r->chunk_list.head, link) {
 		/* intersection */
-		if (aligned_bus >= c->bus_addr
-			&& aligned_bus < c->bus_addr + c->len
-			&& aligned_bus + aligned_len <= c->bus_addr + c->len) {
+		if (aligned_bus >= c->bus_addr &&
+		    aligned_bus + aligned_len <= c->bus_addr + c->len)
 			return c;
-		}
+
 		/* below */
-		if (aligned_bus + aligned_len <= c->bus_addr) {
+		if (aligned_bus + aligned_len <= c->bus_addr)
 			continue;
-		}
+
 		/* above */
-		if (aligned_bus >= c->bus_addr + c->len) {
+		if (aligned_bus >= c->bus_addr + c->len)
 			continue;
-		}
 
 		/* we don't handle the multi-chunk case for now */
-
 		dma_dump_chunk(c);
 		BUG();
 	}
 	return NULL;
 }
 
-static int dma_free_chunk(struct dma_chunk *c)
+static struct dma_chunk * dma_find_chunk_lpar(struct ps3_dma_region *r,
+	unsigned long lpar_addr, unsigned long len)
+{
+	struct dma_chunk *c;
+	unsigned long aligned_lpar = _ALIGN_DOWN(lpar_addr, 1 << r->page_size);
+	unsigned long aligned_len = _ALIGN_UP(len + lpar_addr - aligned_lpar,
+					      1 << r->page_size);
+
+	list_for_each_entry(c, &r->chunk_list.head, link) {
+		/* intersection */
+		if (c->lpar_addr <= aligned_lpar &&
+		    aligned_lpar < c->lpar_addr + c->len) {
+			if (aligned_lpar + aligned_len <= c->lpar_addr + c->len)
+				return c;
+			else {
+				dma_dump_chunk(c);
+				BUG();
+			}
+		}
+		/* below */
+		if (aligned_lpar + aligned_len <= c->lpar_addr) {
+			continue;
+		}
+		/* above */
+		if (c->lpar_addr + c->len <= aligned_lpar) {
+			continue;
+		}
+	}
+	return NULL;
+}
+
+static int dma_sb_free_chunk(struct dma_chunk *c)
 {
 	int result = 0;
 
@@ -435,8 +469,39 @@ static int dma_free_chunk(struct dma_chunk *c)
 	return result;
 }
 
+static int dma_ioc0_free_chunk(struct dma_chunk *c)
+{
+	int result = 0;
+	int iopage;
+	unsigned long offset;
+	struct ps3_dma_region * r = c->region;
+
+	DBG("%s:start\n", __func__);
+	for (iopage = 0; iopage < (c->len >> r->page_size); iopage++) {
+		offset = (1 << r->page_size) * iopage;
+		/* put INVALID entry */
+		result = lv1_put_iopte(0,
+				       c->bus_addr + offset,
+				       c->lpar_addr + offset,
+				       r->ioid,
+				       0);
+		DBG("%s: bus=%#lx, lpar=%#lx, ioid=%d\n", __func__,
+		    c->bus_addr + offset,
+		    c->lpar_addr + offset,
+		    r->ioid);
+
+		if (result) {
+			DBG("%s:%d: lv1_map_device_dma_region failed: %s\n",
+			    __func__, __LINE__, ps3_result(result));
+		}
+	}
+	kfree(c);
+	DBG("%s:end\n", __func__);
+	return result;
+}
+
 /**
- * dma_map_pages - Maps dma pages into the io controller bus address space.
+ * dma_sb_map_pages - Maps dma pages into the io controller bus address space.
  * @r: Pointer to a struct ps3_dma_region.
  * @phys_addr: Starting physical address of the area to map.
  * @len: Length in bytes of the area to map.
@@ -446,8 +511,8 @@ static int dma_free_chunk(struct dma_chunk *c)
  * make the HV call to add the pages into the io controller address space.
  */
 
-static int dma_map_pages(struct ps3_dma_region *r, unsigned long phys_addr,
-	unsigned long len, struct dma_chunk **c_out)
+static int dma_sb_map_pages(struct ps3_dma_region *r, unsigned long phys_addr,
+	    unsigned long len, struct dma_chunk **c_out, u64 iopte_flag)
 {
 	int result;
 	struct dma_chunk *c;
@@ -461,13 +526,13 @@ static int dma_map_pages(struct ps3_dma_region *r, unsigned long phys_addr,
 
 	c->region = r;
 	c->lpar_addr = ps3_mm_phys_to_lpar(phys_addr);
-	c->bus_addr = dma_lpar_to_bus(r, c->lpar_addr);
+	c->bus_addr = dma_sb_lpar_to_bus(r, c->lpar_addr);
 	c->len = len;
 
+	BUG_ON(iopte_flag != 0xf800000000000000UL);
 	result = lv1_map_device_dma_region(c->region->did.bus_id,
-		c->region->did.dev_id, c->lpar_addr, c->bus_addr, c->len,
-		0xf800000000000000UL);
-
+					   c->region->did.dev_id, c->lpar_addr,
+					   c->bus_addr, c->len, iopte_flag);
 	if (result) {
 		DBG("%s:%d: lv1_map_device_dma_region failed: %s\n",
 			__func__, __LINE__, ps3_result(result));
@@ -487,25 +552,105 @@ fail_alloc:
 	return result;
 }
 
+static int dma_ioc0_map_pages(struct ps3_dma_region *r, unsigned long phys_addr,
+			      unsigned long len, struct dma_chunk **c_out,
+			      u64 iopte_flag)
+{
+	int result;
+	struct dma_chunk *c, *last;
+	int iopage, pages;
+	unsigned long offset;
+
+	DBG(KERN_ERR "%s: phy=%#lx, lpar%#lx, len=%#lx\n", __func__,
+	    phys_addr, ps3_mm_phys_to_lpar(phys_addr), len);
+	c = kzalloc(sizeof(struct dma_chunk), GFP_ATOMIC);
+
+	if (!c) {
+		result = -ENOMEM;
+		goto fail_alloc;
+	}
+
+	c->region = r;
+	c->len = len;
+	c->lpar_addr = ps3_mm_phys_to_lpar(phys_addr);
+	/* allocate IO address */
+	if (list_empty(&r->chunk_list.head)) {
+		/* first one */
+		c->bus_addr = r->bus_addr;
+	} else {
+		/* derive from last bus addr*/
+		last  = list_entry(r->chunk_list.head.next,
+				   struct dma_chunk, link);
+		c->bus_addr = last->bus_addr + last->len;
+		DBG("%s: last bus=%#lx, len=%#lx\n", __func__,
+		    last->bus_addr, last->len);
+	}
+
+	/* FIXME: check whether length exceeds region size */
+
+	/* build ioptes for the area */
+	pages = len >> r->page_size;
+	DBG("%s: pgsize=%#x len=%#lx pages=%#x iopteflag=%#lx\n", __func__,
+	    r->page_size, r->len, pages, iopte_flag);
+	for (iopage = 0; iopage < pages; iopage++) {
+		offset = (1 << r->page_size) * iopage;
+		result = lv1_put_iopte(0,
+				       c->bus_addr + offset,
+				       c->lpar_addr + offset,
+				       r->ioid,
+				       iopte_flag);
+		if (result) {
+			printk("%s:%d: lv1_map_device_dma_region failed: %s\n",
+			    __func__, __LINE__, ps3_result(result));
+			goto fail_map;
+		}
+		DBG("%s: pg=%d bus=%#lx, lpar=%#lx, ioid=%#x\n", __func__,
+		    iopage, c->bus_addr + offset, c->lpar_addr + offset,
+		    r->ioid);
+	}
+
+	/* be sure that last allocated one is inserted at head */
+	list_add(&c->link, &r->chunk_list.head);
+
+	*c_out = c;
+	DBG("%s: end\n", __func__);
+	return 0;
+
+fail_map:
+	for (iopage--; 0 <= iopage; iopage--) {
+		lv1_put_iopte(0,
+			      c->bus_addr + offset,
+			      c->lpar_addr + offset,
+			      r->ioid,
+			      0);
+	}
+	kfree(c);
+fail_alloc:
+	*c_out = NULL;
+	return result;
+}
+
 /**
- * dma_region_create - Create a device dma region.
+ * dma_sb_region_create - Create a device dma region.
  * @r: Pointer to a struct ps3_dma_region.
  *
  * This is the lowest level dma region create routine, and is the one that
  * will make the HV call to create the region.
  */
 
-static int dma_region_create(struct ps3_dma_region* r)
+static int dma_sb_region_create(struct ps3_dma_region* r)
 {
+	u64 len;
 	int result;
 
-	r->len = _ALIGN_UP(map.total, 1 << r->page_size);
+	DBG("%s:%u: len = 0x%lx, page_size = %u, offset = 0x%lx\n", __func__,
+	    __LINE__, r->len, r->page_size, r->offset);
 	INIT_LIST_HEAD(&r->chunk_list.head);
 	spin_lock_init(&r->chunk_list.lock);
 
+	len = roundup_pow_of_two(r->len);
 	result = lv1_allocate_device_dma_region(r->did.bus_id, r->did.dev_id,
-		r->len, r->page_size, r->region_type, &r->bus_addr);
-
+		len, r->page_size, r->region_type, &r->bus_addr);
 	dma_dump_region(r);
 
 	if (result) {
@@ -517,6 +662,27 @@ static int dma_region_create(struct ps3_dma_region* r)
 	return result;
 }
 
+static int dma_ioc0_region_create(struct ps3_dma_region* r)
+{
+	int result;
+
+	INIT_LIST_HEAD(&r->chunk_list.head);
+	spin_lock_init(&r->chunk_list.lock);
+
+	result = lv1_allocate_io_segment(0,
+					 r->len,
+					 r->page_size,
+					 &r->bus_addr);
+	if (result) {
+		DBG("%s:%d: lv1_allocate_io_segment failed: %s\n",
+			__func__, __LINE__, ps3_result(result));
+		r->len = r->bus_addr = 0;
+	}
+	DBG("%s: len=%#lx, pg=%d, bus=%#lx\n", __func__,
+	    r->len, r->page_size, r->bus_addr);
+	return result;
+}
+
 /**
  * dma_region_free - Free a device dma region.
  * @r: Pointer to a struct ps3_dma_region.
@@ -525,7 +691,7 @@ static int dma_region_create(struct ps3_dma_region* r)
  * will make the HV call to free the region.
  */
 
-static int dma_region_free(struct ps3_dma_region* r)
+static int dma_sb_region_free(struct ps3_dma_region* r)
 {
 	int result;
 	struct dma_chunk *c;
@@ -533,7 +699,7 @@ static int dma_region_free(struct ps3_dma_region* r)
 
 	list_for_each_entry_safe(c, tmp, &r->chunk_list.head, link) {
 		list_del(&c->link);
-		dma_free_chunk(c);
+		dma_sb_free_chunk(c);
 	}
 
 	result = lv1_free_device_dma_region(r->did.bus_id, r->did.dev_id,
@@ -548,8 +714,31 @@ static int dma_region_free(struct ps3_dma_region* r)
 	return result;
 }
 
+static int dma_ioc0_region_free(struct ps3_dma_region* r)
+{
+	int result;
+	struct dma_chunk *c, *n;
+
+	DBG("%s: start\n", __func__);
+	list_for_each_entry_safe(c, n, &r->chunk_list.head, link) {
+		list_del(&c->link);
+		dma_ioc0_free_chunk(c);
+	}
+
+	result = lv1_release_io_segment(0, r->bus_addr);
+
+	if (result)
+		DBG("%s:%d: lv1_free_device_dma_region failed: %s\n",
+			__func__, __LINE__, ps3_result(result));
+
+	r->len = r->bus_addr = 0;
+	DBG("%s: end\n", __func__);
+
+	return result;
+}
+
 /**
- * dma_map_area - Map an area of memory into a device dma region.
+ * dma_sb_map_area - Map an area of memory into a device dma region.
  * @r: Pointer to a struct ps3_dma_region.
  * @virt_addr: Starting virtual address of the area to map.
  * @len: Length in bytes of the area to map.
@@ -559,16 +748,19 @@ static int dma_region_free(struct ps3_dma_region* r)
  * This is the common dma mapping routine.
  */
 
-static int dma_map_area(struct ps3_dma_region *r, unsigned long virt_addr,
-	unsigned long len, unsigned long *bus_addr)
+static int dma_sb_map_area(struct ps3_dma_region *r, unsigned long virt_addr,
+	   unsigned long len, unsigned long *bus_addr,
+	   u64 iopte_flag)
 {
 	int result;
 	unsigned long flags;
 	struct dma_chunk *c;
 	unsigned long phys_addr = is_kernel_addr(virt_addr) ? __pa(virt_addr)
 		: virt_addr;
-
-	*bus_addr = dma_lpar_to_bus(r, ps3_mm_phys_to_lpar(phys_addr));
+	unsigned long aligned_phys = _ALIGN_DOWN(phys_addr, 1 << r->page_size);
+	unsigned long aligned_len = _ALIGN_UP(len + phys_addr - aligned_phys,
+					      1 << r->page_size);
+	*bus_addr = dma_sb_lpar_to_bus(r, ps3_mm_phys_to_lpar(phys_addr));
 
 	if (!USE_DYNAMIC_DMA) {
 		unsigned long lpar_addr = ps3_mm_phys_to_lpar(phys_addr);
@@ -588,17 +780,18 @@ static int dma_map_area(struct ps3_dma_region *r, unsigned long virt_addr,
 	c = dma_find_chunk(r, *bus_addr, len);
 
 	if (c) {
+		DBG("%s:%d: reusing mapped chunk", __func__, __LINE__);
+		dma_dump_chunk(c);
 		c->usage_count++;
 		spin_unlock_irqrestore(&r->chunk_list.lock, flags);
 		return 0;
 	}
 
-	result = dma_map_pages(r, _ALIGN_DOWN(phys_addr, 1 << r->page_size),
-		_ALIGN_UP(len, 1 << r->page_size), &c);
+	result = dma_sb_map_pages(r, aligned_phys, aligned_len, &c, iopte_flag);
 
 	if (result) {
 		*bus_addr = 0;
-		DBG("%s:%d: dma_map_pages failed (%d)\n",
+		DBG("%s:%d: dma_sb_map_pages failed (%d)\n",
 			__func__, __LINE__, result);
 		spin_unlock_irqrestore(&r->chunk_list.lock, flags);
 		return result;
@@ -610,8 +803,57 @@ static int dma_map_area(struct ps3_dma_region *r, unsigned long virt_addr,
 	return result;
 }
 
+static int dma_ioc0_map_area(struct ps3_dma_region *r, unsigned long virt_addr,
+	     unsigned long len, unsigned long *bus_addr,
+	     u64 iopte_flag)
+{
+	int result;
+	unsigned long flags;
+	struct dma_chunk *c;
+	unsigned long phys_addr = is_kernel_addr(virt_addr) ? __pa(virt_addr)
+		: virt_addr;
+	unsigned long aligned_phys = _ALIGN_DOWN(phys_addr, 1 << r->page_size);
+	unsigned long aligned_len = _ALIGN_UP(len + phys_addr - aligned_phys,
+					      1 << r->page_size);
+
+	DBG(KERN_ERR "%s: vaddr=%#lx, len=%#lx\n", __func__,
+	    virt_addr, len);
+	DBG(KERN_ERR "%s: ph=%#lx a_ph=%#lx a_l=%#lx\n", __func__,
+	    phys_addr, aligned_phys, aligned_len);
+
+	spin_lock_irqsave(&r->chunk_list.lock, flags);
+	c = dma_find_chunk_lpar(r, ps3_mm_phys_to_lpar(phys_addr), len);
+
+	if (c) {
+		/* FIXME */
+		BUG();
+		*bus_addr = c->bus_addr + phys_addr - aligned_phys;
+		c->usage_count++;
+		spin_unlock_irqrestore(&r->chunk_list.lock, flags);
+		return 0;
+	}
+
+	result = dma_ioc0_map_pages(r, aligned_phys, aligned_len, &c,
+				    iopte_flag);
+
+	if (result) {
+		*bus_addr = 0;
+		DBG("%s:%d: dma_ioc0_map_pages failed (%d)\n",
+			__func__, __LINE__, result);
+		spin_unlock_irqrestore(&r->chunk_list.lock, flags);
+		return result;
+	}
+	*bus_addr = c->bus_addr + phys_addr - aligned_phys;
+	DBG("%s: va=%#lx pa=%#lx a_pa=%#lx bus=%#lx\n", __func__,
+	    virt_addr, phys_addr, aligned_phys, *bus_addr);
+	c->usage_count = 1;
+
+	spin_unlock_irqrestore(&r->chunk_list.lock, flags);
+	return result;
+}
+
 /**
- * dma_unmap_area - Unmap an area of memory from a device dma region.
+ * dma_sb_unmap_area - Unmap an area of memory from a device dma region.
  * @r: Pointer to a struct ps3_dma_region.
  * @bus_addr: The starting ioc bus address of the area to unmap.
  * @len: Length in bytes of the area to unmap.
@@ -619,7 +861,7 @@ static int dma_map_area(struct ps3_dma_region *r, unsigned long virt_addr,
  * This is the common dma unmap routine.
  */
 
-int dma_unmap_area(struct ps3_dma_region *r, unsigned long bus_addr,
+int dma_sb_unmap_area(struct ps3_dma_region *r, unsigned long bus_addr,
 	unsigned long len)
 {
 	unsigned long flags;
@@ -631,7 +873,8 @@ int dma_unmap_area(struct ps3_dma_region *r, unsigned long bus_addr,
 	if (!c) {
 		unsigned long aligned_bus = _ALIGN_DOWN(bus_addr,
 			1 << r->page_size);
-		unsigned long aligned_len = _ALIGN_UP(len, 1 << r->page_size);
+		unsigned long aligned_len = _ALIGN_UP(len + bus_addr - aligned_bus,
+						      1 << r->page_size);
 		DBG("%s:%d: not found: bus_addr %lxh\n",
 			__func__, __LINE__, bus_addr);
 		DBG("%s:%d: not found: len %lxh\n",
@@ -647,94 +890,165 @@ int dma_unmap_area(struct ps3_dma_region *r, unsigned long bus_addr,
 
 	if (!c->usage_count) {
 		list_del(&c->link);
-		dma_free_chunk(c);
+		dma_sb_free_chunk(c);
+	}
+
+	spin_unlock_irqrestore(&r->chunk_list.lock, flags);
+	return 0;
+}
+
+int dma_ioc0_unmap_area(struct ps3_dma_region *r, unsigned long bus_addr,
+			unsigned long len)
+{
+	unsigned long flags;
+	struct dma_chunk *c;
+
+	DBG("%s: start a=%#lx l=%#lx\n", __func__, bus_addr, len);
+	spin_lock_irqsave(&r->chunk_list.lock, flags);
+	c = dma_find_chunk(r, bus_addr, len);
+
+	if (!c) {
+		unsigned long aligned_bus = _ALIGN_DOWN(bus_addr,
+							1 << r->page_size);
+		unsigned long aligned_len = _ALIGN_UP(len + bus_addr - aligned_bus,
+						      1 << r->page_size);
+		DBG("%s:%d: not found: bus_addr %lxh\n",
+		    __func__, __LINE__, bus_addr);
+		DBG("%s:%d: not found: len %lxh\n",
+		    __func__, __LINE__, len);
+		DBG("%s:%d: not found: aligned_bus %lxh\n",
+		    __func__, __LINE__, aligned_bus);
+		DBG("%s:%d: not found: aligned_len %lxh\n",
+		    __func__, __LINE__, aligned_len);
+		BUG();
+	}
+
+	c->usage_count--;
+
+	if (!c->usage_count) {
+		list_del(&c->link);
+		dma_ioc0_free_chunk(c);
 	}
 
 	spin_unlock_irqrestore(&r->chunk_list.lock, flags);
+	DBG("%s: end\n", __func__);
 	return 0;
 }
 
 /**
- * dma_region_create_linear - Setup a linear dma maping for a device.
+ * dma_sb_region_create_linear - Setup a linear dma mapping for a device.
  * @r: Pointer to a struct ps3_dma_region.
  *
  * This routine creates an HV dma region for the device and maps all available
  * ram into the io controller bus address space.
  */
 
-static int dma_region_create_linear(struct ps3_dma_region *r)
+static int dma_sb_region_create_linear(struct ps3_dma_region *r)
 {
 	int result;
-	unsigned long tmp;
-
-	/* force 16M dma pages for linear mapping */
-
-	if (r->page_size != PS3_DMA_16M) {
-		pr_info("%s:%d: forcing 16M pages for linear map\n",
-			__func__, __LINE__);
-		r->page_size = PS3_DMA_16M;
+	unsigned long virt_addr, len, tmp;
+
+	if (r->len > 16*1024*1024) {	// FIXME
+		/* force 16M dma pages for linear mapping */
+		if (r->page_size != PS3_DMA_16M) {
+			pr_info("%s:%d: forcing 16M pages for linear map\n",
+				__func__, __LINE__);
+			r->page_size = PS3_DMA_16M;
+			r->len = _ALIGN_UP(r->len, 1 << r->page_size);
+		}
 	}
 
-	result = dma_region_create(r);
-	BUG_ON(result);
-
-	result = dma_map_area(r, map.rm.base, map.rm.size, &tmp);
+	result = dma_sb_region_create(r);
 	BUG_ON(result);
 
-	if (USE_LPAR_ADDR)
-		result = dma_map_area(r, map.r1.base, map.r1.size,
-			&tmp);
-	else
-		result = dma_map_area(r, map.rm.size, map.r1.size,
-			&tmp);
+	if (r->offset < map.rm.size) {
+		/* Map (part of) 1st RAM chunk */
+		virt_addr = map.rm.base + r->offset;
+		len = map.rm.size - r->offset;
+		if (len > r->len)
+			len = r->len;
+		result = dma_sb_map_area(r, virt_addr, len, &tmp,
+			IOPTE_PP_W | IOPTE_PP_R | IOPTE_SO_RW | IOPTE_M);
+		BUG_ON(result);
+	}
 
-	BUG_ON(result);
+	if (r->offset+r->len > map.rm.size) {
+		/* Map (part of) 2nd RAM chunk */
+		virt_addr = USE_LPAR_ADDR ? map.r1.base : map.rm.size;
+		len = r->len;
+		if (r->offset >= map.rm.size)
+			virt_addr += r->offset - map.rm.size;
+		else
+			len -= map.rm.size - r->offset;
+		result = dma_sb_map_area(r, virt_addr, len, &tmp,
+			IOPTE_PP_W | IOPTE_PP_R | IOPTE_SO_RW | IOPTE_M);
+		BUG_ON(result);
+	}
 
 	return result;
 }
 
 /**
- * dma_region_free_linear - Free a linear dma mapping for a device.
+ * dma_sb_region_free_linear - Free a linear dma mapping for a device.
  * @r: Pointer to a struct ps3_dma_region.
  *
  * This routine will unmap all mapped areas and free the HV dma region.
  */
 
-static int dma_region_free_linear(struct ps3_dma_region *r)
+static int dma_sb_region_free_linear(struct ps3_dma_region *r)
 {
 	int result;
+	unsigned long bus_addr, len, lpar_addr;
+
+	if (r->offset < map.rm.size) {
+		/* Unmap (part of) 1st RAM chunk */
+		lpar_addr = map.rm.base + r->offset;
+		len = map.rm.size - r->offset;
+		if (len > r->len)
+			len = r->len;
+		bus_addr = dma_sb_lpar_to_bus(r, lpar_addr);
+		result = dma_sb_unmap_area(r, bus_addr, len);
+		BUG_ON(result);
+	}
 
-	result = dma_unmap_area(r, dma_lpar_to_bus(r, 0), map.rm.size);
-	BUG_ON(result);
-
-	result = dma_unmap_area(r, dma_lpar_to_bus(r, map.r1.base),
-		map.r1.size);
-	BUG_ON(result);
+	if (r->offset+r->len > map.rm.size) {
+		/* Unmap (part of) 2nd RAM chunk */
+		lpar_addr = map.r1.base;
+		len = r->len;
+		if (r->offset >= map.rm.size)
+			lpar_addr += r->offset - map.rm.size;
+		else
+			len -= map.rm.size - r->offset;
+		bus_addr = dma_sb_lpar_to_bus(r, lpar_addr);
+		result = dma_sb_unmap_area(r, bus_addr, len);
+		BUG_ON(result);
+	}
 
-	result = dma_region_free(r);
+	result = dma_sb_region_free(r);
 	BUG_ON(result);
 
 	return result;
 }
 
 /**
- * dma_map_area_linear - Map an area of memory into a device dma region.
+ * dma_sb_map_area_linear - Map an area of memory into a device dma region.
  * @r: Pointer to a struct ps3_dma_region.
  * @virt_addr: Starting virtual address of the area to map.
  * @len: Length in bytes of the area to map.
  * @bus_addr: A pointer to return the starting ioc bus address of the area to
  * map.
  *
- * This routine just returns the coresponding bus address.  Actual mapping
+ * This routine just returns the corresponding bus address.  Actual mapping
  * occurs in dma_region_create_linear().
  */
 
-static int dma_map_area_linear(struct ps3_dma_region *r,
-	unsigned long virt_addr, unsigned long len, unsigned long *bus_addr)
+static int dma_sb_map_area_linear(struct ps3_dma_region *r,
+	unsigned long virt_addr, unsigned long len, unsigned long *bus_addr,
+	u64 iopte_flag)
 {
 	unsigned long phys_addr = is_kernel_addr(virt_addr) ? __pa(virt_addr)
 		: virt_addr;
-	*bus_addr = dma_lpar_to_bus(r, ps3_mm_phys_to_lpar(phys_addr));
+	*bus_addr = dma_sb_lpar_to_bus(r, ps3_mm_phys_to_lpar(phys_addr));
 	return 0;
 }
 
@@ -744,42 +1058,91 @@ static int dma_map_area_linear(struct ps3_dma_region *r,
  * @bus_addr: The starting ioc bus address of the area to unmap.
  * @len: Length in bytes of the area to unmap.
  *
- * This routine does nothing.  Unmapping occurs in dma_region_free_linear().
+ * This routine does nothing.  Unmapping occurs in dma_sb_region_free_linear().
  */
 
-static int dma_unmap_area_linear(struct ps3_dma_region *r,
+static int dma_sb_unmap_area_linear(struct ps3_dma_region *r,
 	unsigned long bus_addr, unsigned long len)
 {
 	return 0;
+};
+
+static const struct ps3_dma_region_ops ps3_dma_sb_region_ops =  {
+	.create = dma_sb_region_create,
+	.free = dma_sb_region_free,
+	.map = dma_sb_map_area,
+	.unmap = dma_sb_unmap_area
+};
+
+static const struct ps3_dma_region_ops ps3_dma_sb_region_linear_ops = {
+	.create = dma_sb_region_create_linear,
+	.free = dma_sb_region_free_linear,
+	.map = dma_sb_map_area_linear,
+	.unmap = dma_sb_unmap_area_linear
+};
+
+static const struct ps3_dma_region_ops ps3_dma_ioc0_region_ops = {
+	.create = dma_ioc0_region_create,
+	.free = dma_ioc0_region_free,
+	.map = dma_ioc0_map_area,
+	.unmap = dma_ioc0_unmap_area
+};
+
+void ps3_dma_region_init(struct ps3_dma_region *r,
+	const struct ps3_device_id *did, enum ps3_dma_page_size page_size,
+	enum ps3_dma_region_type region_type, void *addr, unsigned long len,
+	enum ps3_iobus_type iobus_type)
+{
+	unsigned long lpar_addr;
+
+	lpar_addr = addr ? ps3_mm_phys_to_lpar(__pa(addr)) : 0;
+
+	r->did = *did;
+	r->page_size = page_size;
+	r->region_type = region_type;
+	r->offset = lpar_addr;
+	if (r->offset >= map.rm.size)
+		r->offset -= map.r1.offset;
+	r->len = len ? len : _ALIGN_UP(map.total, 1 << r->page_size);
+
+	switch(iobus_type) {
+	case PS3_IOBUS_SB:
+		r->region_ops =  (USE_DYNAMIC_DMA)
+			? &ps3_dma_sb_region_ops
+			: &ps3_dma_sb_region_linear_ops;
+		break;
+	case PS3_IOBUS_IOC0:
+		r->region_ops = &ps3_dma_ioc0_region_ops;
+		break;
+	default:
+		BUG();
+	}
 }
+EXPORT_SYMBOL(ps3_dma_region_init);
 
 int ps3_dma_region_create(struct ps3_dma_region *r)
 {
-	return (USE_DYNAMIC_DMA)
-		? dma_region_create(r)
-		: dma_region_create_linear(r);
+	return r->region_ops->create(r);
 }
+EXPORT_SYMBOL(ps3_dma_region_create);
 
 int ps3_dma_region_free(struct ps3_dma_region *r)
 {
-	return (USE_DYNAMIC_DMA)
-		? dma_region_free(r)
-		: dma_region_free_linear(r);
+	return r->region_ops->free(r);
 }
+EXPORT_SYMBOL(ps3_dma_region_free);
 
 int ps3_dma_map(struct ps3_dma_region *r, unsigned long virt_addr,
-	unsigned long len, unsigned long *bus_addr)
+	unsigned long len, unsigned long *bus_addr,
+	u64 iopte_flag)
 {
-	return (USE_DYNAMIC_DMA)
-		? dma_map_area(r, virt_addr, len, bus_addr)
-		: dma_map_area_linear(r, virt_addr, len, bus_addr);
+	return r->region_ops->map(r, virt_addr, len, bus_addr, iopte_flag);
 }
 
 int ps3_dma_unmap(struct ps3_dma_region *r, unsigned long bus_addr,
 	unsigned long len)
 {
-	return (USE_DYNAMIC_DMA) ? dma_unmap_area(r, bus_addr, len)
-		: dma_unmap_area_linear(r, bus_addr, len);
+	return r->region_ops->unmap(r, bus_addr, len);
 }
 
 /*============================================================================*/
@@ -816,6 +1179,9 @@ void __init ps3_mm_init(void)
 	/* arrange to do this in ps3_mm_add_memory */
 	ps3_mm_region_create(&map.r1, map.total - map.rm.size);
 
+	/* correct map.total for the real total amount of memory we use */
+	map.total = map.rm.size + map.r1.size;
+
 	DBG(" <- %s:%d\n", __func__, __LINE__);
 }
 
diff --git a/arch/powerpc/platforms/ps3/platform.h b/arch/powerpc/platforms/ps3/platform.h
index ca04f03..4a1015b 100644
--- a/arch/powerpc/platforms/ps3/platform.h
+++ b/arch/powerpc/platforms/ps3/platform.h
@@ -216,4 +216,14 @@ int ps3_repository_read_num_spu_resource_id(unsigned int *num_resource_id);
 int ps3_repository_read_spu_resource_id(unsigned int res_index,
 	enum ps3_spu_resource_type* resource_type, unsigned int *resource_id);
 
+/* Page table entries */
+#define IOPTE_PP_W		0x8000000000000000ul /* protection: write */
+#define IOPTE_PP_R		0x4000000000000000ul /* protection: read */
+#define IOPTE_M			0x2000000000000000ul /* coherency required */
+#define IOPTE_SO_R		0x1000000000000000ul /* ordering: writes */
+#define IOPTE_SO_RW             0x1800000000000000ul /* ordering: r & w */
+#define IOPTE_RPN_Mask		0x07fffffffffff000ul /* RPN */
+#define IOPTE_H			0x0000000000000800ul /* cache hint */
+#define IOPTE_IOID_Mask		0x00000000000007fful /* ioid */
+
 #endif
diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c
index 3c48cce..a2591b8 100644
--- a/arch/powerpc/platforms/ps3/system-bus.c
+++ b/arch/powerpc/platforms/ps3/system-bus.c
@@ -18,6 +18,8 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#define DEBUG
+
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/module.h>
@@ -30,6 +32,10 @@
 
 #include "platform.h"
 
+static struct device ps3_system_bus = {
+        .bus_id         = "ps3_system",
+};
+
 #define dump_mmio_region(_a) _dump_mmio_region(_a, __func__, __LINE__)
 static void _dump_mmio_region(const struct ps3_mmio_region* r,
 	const char* func, int line)
@@ -41,7 +47,7 @@ static void _dump_mmio_region(const struct ps3_mmio_region* r,
 	pr_debug("%s:%d: lpar_addr %lxh\n", func, line, r->lpar_addr);
 }
 
-int ps3_mmio_region_create(struct ps3_mmio_region *r)
+static int ps3_sb_mmio_region_create(struct ps3_mmio_region *r)
 {
 	int result;
 
@@ -57,9 +63,20 @@ int ps3_mmio_region_create(struct ps3_mmio_region *r)
 	dump_mmio_region(r);
 	return result;
 }
+
+static int ps3_ioc0_mmio_region_create(struct ps3_mmio_region *r)
+{
+	/* device specific; do nothing currently */
+	return 0;
+}
+
+int ps3_mmio_region_create(struct ps3_mmio_region *r)
+{
+	return r->mmio_ops->create(r);
+}
 EXPORT_SYMBOL_GPL(ps3_mmio_region_create);
 
-int ps3_free_mmio_region(struct ps3_mmio_region *r)
+static int ps3_sb_free_mmio_region(struct ps3_mmio_region *r)
 {
 	int result;
 
@@ -73,8 +90,53 @@ int ps3_free_mmio_region(struct ps3_mmio_region *r)
 	r->lpar_addr = 0;
 	return result;
 }
+
+static int ps3_ioc0_free_mmio_region(struct ps3_mmio_region *r)
+{
+	/* device specific; do nothing currently */
+	return 0;
+}
+
+
+int ps3_free_mmio_region(struct ps3_mmio_region *r)
+{
+	return r->mmio_ops->free(r);
+}
+
 EXPORT_SYMBOL_GPL(ps3_free_mmio_region);
 
+static const struct ps3_mmio_region_ops ps3_mmio_sb_region_ops = {
+	.create = ps3_sb_mmio_region_create,
+	.free = ps3_sb_free_mmio_region
+};
+
+static const struct ps3_mmio_region_ops ps3_mmio_ioc0_region_ops = {
+	.create = ps3_ioc0_mmio_region_create,
+	.free = ps3_ioc0_free_mmio_region
+};
+
+void ps3_mmio_region_init(struct ps3_mmio_region *r,
+	const struct ps3_device_id* did, unsigned long bus_addr,
+	unsigned long len, enum ps3_mmio_page_size page_size,
+	enum ps3_iobus_type iobus_type)
+{
+	r->did = *did;
+	r->bus_addr = bus_addr;
+	r->len = len;
+	r->page_size = page_size;
+	switch (iobus_type) {
+	case PS3_IOBUS_SB:
+		r->mmio_ops = &ps3_mmio_sb_region_ops;
+		break;
+	case PS3_IOBUS_IOC0:
+		r->mmio_ops = &ps3_mmio_ioc0_region_ops;
+		break;
+	default:
+		BUG();
+	}
+}
+EXPORT_SYMBOL_GPL(ps3_mmio_region_init);
+
 static int ps3_system_bus_match(struct device *_dev,
 	struct device_driver *_drv)
 {
@@ -92,21 +154,23 @@ static int ps3_system_bus_match(struct device *_dev,
 
 static int ps3_system_bus_probe(struct device *_dev)
 {
-	int result;
+	int result = 0;
 	struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev);
 	struct ps3_system_bus_driver *drv =
 		to_ps3_system_bus_driver(_dev->driver);
 
-	result = lv1_open_device(dev->did.bus_id, dev->did.dev_id, 0);
+	if (dev->did.bus_id)
+		result = lv1_open_device(dev->did.bus_id, dev->did.dev_id, 0);
 
-	if (result) {
-		pr_debug("%s:%d: lv1_open_device failed (%d)\n",
-			__func__, __LINE__, result);
+	if (result && (result != LV1_BUSY || (dev->match_id != PS3_MATCH_ID_EHCI
+		&& dev->match_id != PS3_MATCH_ID_OHCI))) {
+		pr_debug("%s:%d: lv1_open_device failed: %s\n",
+			__func__, __LINE__, ps3_result(result));
 		result = -EACCES;
 		goto clean_none;
 	}
 
-	if (dev->d_region->did.bus_id) {
+	if (dev->d_region && dev->d_region->did.bus_id) {
 		result = ps3_dma_region_create(dev->d_region);
 
 		if (result) {
@@ -134,9 +198,11 @@ static int ps3_system_bus_probe(struct device *_dev)
 	return result;
 
 clean_dma:
-	ps3_dma_region_free(dev->d_region);
+	if (dev->d_region && dev->d_region->did.bus_id)
+		ps3_dma_region_free(dev->d_region);
 clean_device:
-	lv1_close_device(dev->did.bus_id, dev->did.dev_id);
+	if (dev->did.bus_id)
+		lv1_close_device(dev->did.bus_id, dev->did.dev_id);
 clean_none:
 	return result;
 }
@@ -153,18 +219,51 @@ static int ps3_system_bus_remove(struct device *_dev)
 		pr_info("%s:%d: %s no remove method\n", __func__, __LINE__,
 			dev->core.bus_id);
 
-	ps3_dma_region_free(dev->d_region);
-	ps3_free_mmio_region(dev->m_region);
-	lv1_close_device(dev->did.bus_id, dev->did.dev_id);
+	if (dev->d_region && dev->d_region->did.dev_id)
+		ps3_dma_region_free(dev->d_region);
+
+	if (dev->did.bus_id)
+		lv1_close_device(dev->did.bus_id, dev->did.dev_id);
 
 	return 0;
 }
 
+static int ps3_system_bus_uevent(struct device *_dev, char **envp,
+				 int num_envp, char *buffer, int buffer_size)
+{
+	struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev);
+	int i=0, length = 0;
+
+	if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size,
+			   &length, "MODALIAS=ps3:%d",
+			   dev->match_id))
+		return -ENOMEM;
+
+	envp[i] = NULL;
+	return 0;
+}
+
+static ssize_t modalias_show(struct device *_dev, struct device_attribute *a,
+			     char *buf)
+{
+	struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev);
+        int len = snprintf(buf, PAGE_SIZE, "ps3:%d\n", dev->match_id);
+
+        return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len;
+}
+
+static struct device_attribute ps3_system_bus_dev_attrs[] = {
+        __ATTR_RO(modalias),
+        __ATTR_NULL,
+};
+
 struct bus_type ps3_system_bus_type = {
 	.name = "ps3_system_bus",
 	.match = ps3_system_bus_match,
 	.probe = ps3_system_bus_probe,
 	.remove = ps3_system_bus_remove,
+	.uevent = ps3_system_bus_uevent,
+	.dev_attrs = ps3_system_bus_dev_attrs,
 };
 
 int __init ps3_system_bus_init(void)
@@ -173,7 +272,8 @@ int __init ps3_system_bus_init(void)
 
 	if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
 		return -ENODEV;
-
+	result = device_register(&ps3_system_bus);
+	BUG_ON(result);
 	result = bus_register(&ps3_system_bus_type);
 	BUG_ON(result);
 	return result;
@@ -185,16 +285,13 @@ core_initcall(ps3_system_bus_init);
  * Returns the virtual address of the buffer and sets dma_handle
  * to the dma address (mapping) of the first page.
  */
-
 static void * ps3_alloc_coherent(struct device *_dev, size_t size,
-	dma_addr_t *dma_handle, gfp_t flag)
+				      dma_addr_t *dma_handle, gfp_t flag)
 {
 	int result;
 	struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev);
 	unsigned long virt_addr;
 
-	BUG_ON(!dev->d_region->bus_addr);
-
 	flag &= ~(__GFP_DMA | __GFP_HIGHMEM);
 	flag |= __GFP_ZERO;
 
@@ -205,7 +302,8 @@ static void * ps3_alloc_coherent(struct device *_dev, size_t size,
 		goto clean_none;
 	}
 
-	result = ps3_dma_map(dev->d_region, virt_addr, size, dma_handle);
+	result = ps3_dma_map(dev->d_region, virt_addr, size, dma_handle,
+			     IOPTE_PP_W | IOPTE_PP_R | IOPTE_SO_RW | IOPTE_M);
 
 	if (result) {
 		pr_debug("%s:%d: ps3_dma_map failed (%d)\n",
@@ -239,7 +337,7 @@ static void ps3_free_coherent(struct device *_dev, size_t size, void *vaddr,
  * byte within the page as vaddr.
  */
 
-static dma_addr_t ps3_map_single(struct device *_dev, void *ptr, size_t size,
+static dma_addr_t ps3_sb_map_single(struct device *_dev, void *ptr, size_t size,
 	enum dma_data_direction direction)
 {
 	struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev);
@@ -247,7 +345,8 @@ static dma_addr_t ps3_map_single(struct device *_dev, void *ptr, size_t size,
 	unsigned long bus_addr;
 
 	result = ps3_dma_map(dev->d_region, (unsigned long)ptr, size,
-		&bus_addr);
+			     &bus_addr,
+			     IOPTE_PP_R | IOPTE_PP_W | IOPTE_SO_RW | IOPTE_M);
 
 	if (result) {
 		pr_debug("%s:%d: ps3_dma_map failed (%d)\n",
@@ -257,6 +356,39 @@ static dma_addr_t ps3_map_single(struct device *_dev, void *ptr, size_t size,
 	return bus_addr;
 }
 
+static dma_addr_t ps3_ioc0_map_single(struct device *_dev, void *ptr, size_t size,
+				      enum dma_data_direction direction)
+{
+	struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev);
+	int result;
+	unsigned long bus_addr;
+	u64 iopte_flag;
+
+	iopte_flag = IOPTE_M;
+	switch (direction) {
+	case DMA_BIDIRECTIONAL:
+		iopte_flag |= IOPTE_PP_R | IOPTE_PP_W | IOPTE_SO_RW;
+		break;
+	case DMA_TO_DEVICE:
+		iopte_flag |= IOPTE_PP_R | IOPTE_SO_R;
+		break;
+	case DMA_FROM_DEVICE:
+		iopte_flag |= IOPTE_PP_W | IOPTE_SO_RW;
+		break;
+	default:
+		/* not happned */
+		BUG();
+	};
+	result = ps3_dma_map(dev->d_region, (unsigned long)ptr, size,
+			     &bus_addr, iopte_flag);
+
+	if (result) {
+		pr_debug("%s:%d: ps3_dma_map failed (%d)\n",
+			__func__, __LINE__, result);
+	}
+	return bus_addr;
+}
+
 static void ps3_unmap_single(struct device *_dev, dma_addr_t dma_addr,
 	size_t size, enum dma_data_direction direction)
 {
@@ -271,7 +403,7 @@ static void ps3_unmap_single(struct device *_dev, dma_addr_t dma_addr,
 	}
 }
 
-static int ps3_map_sg(struct device *_dev, struct scatterlist *sg, int nents,
+static int ps3_sb_map_sg(struct device *_dev, struct scatterlist *sg, int nents,
 	enum dma_data_direction direction)
 {
 	struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev);
@@ -284,7 +416,7 @@ static int ps3_map_sg(struct device *_dev, struct scatterlist *sg, int nents,
 	for (i = 0; i < nents; i++, sg++) {
 		int result = ps3_dma_map(dev->d_region,
 			page_to_phys(sg->page) + sg->offset, sg->length,
-			&sg->dma_address);
+					 &sg->dma_address, 0);
 
 		if (result) {
 			pr_debug("%s:%d: ps3_dma_map failed (%d)\n",
@@ -299,7 +431,14 @@ static int ps3_map_sg(struct device *_dev, struct scatterlist *sg, int nents,
 #endif
 }
 
-static void ps3_unmap_sg(struct device *_dev, struct scatterlist *sg,
+static int ps3_ioc0_map_sg(struct device *_dev, struct scatterlist *sg, int nents,
+			   enum dma_data_direction direction)
+{
+	BUG();
+	return 0;
+}
+
+static void ps3_sb_unmap_sg(struct device *_dev, struct scatterlist *sg,
 	int nents, enum dma_data_direction direction)
 {
 #if defined(CONFIG_PS3_DYNAMIC_DMA)
@@ -307,20 +446,38 @@ static void ps3_unmap_sg(struct device *_dev, struct scatterlist *sg,
 #endif
 }
 
+static void ps3_ioc0_unmap_sg(struct device *_dev, struct scatterlist *sg,
+			    int nents, enum dma_data_direction direction)
+{
+	BUG();
+}
+
 static int ps3_dma_supported(struct device *_dev, u64 mask)
 {
 	return mask >= DMA_32BIT_MASK;
 }
 
-static struct dma_mapping_ops ps3_dma_ops = {
+struct dma_mapping_ops ps3_sb_dma_ops = {
+	.alloc_coherent = ps3_alloc_coherent,
+	.free_coherent = ps3_free_coherent,
+	.map_single = ps3_sb_map_single,
+	.unmap_single = ps3_unmap_single,
+	.map_sg = ps3_sb_map_sg,
+	.unmap_sg = ps3_sb_unmap_sg,
+	.dma_supported = ps3_dma_supported
+};
+EXPORT_SYMBOL(ps3_sb_dma_ops);
+
+struct dma_mapping_ops ps3_ioc0_dma_ops = {
 	.alloc_coherent = ps3_alloc_coherent,
 	.free_coherent = ps3_free_coherent,
-	.map_single = ps3_map_single,
+	.map_single = ps3_ioc0_map_single,
 	.unmap_single = ps3_unmap_single,
-	.map_sg = ps3_map_sg,
-	.unmap_sg = ps3_unmap_sg,
+	.map_sg = ps3_ioc0_map_sg,
+	.unmap_sg = ps3_ioc0_unmap_sg,
 	.dma_supported = ps3_dma_supported
 };
+EXPORT_SYMBOL(ps3_ioc0_dma_ops);
 
 /**
  * ps3_system_bus_release_device - remove a device from the system bus
@@ -340,22 +497,37 @@ static void ps3_system_bus_release_device(struct device *_dev)
  * object and frees the object in ps3_system_bus_release_device().
  */
 
-int ps3_system_bus_device_register(struct ps3_system_bus_device *dev)
+int ps3_system_bus_device_register(struct ps3_system_bus_device *dev,
+	enum ps3_iobus_type iobus_type)
 {
 	int result;
-	static unsigned int dev_count = 1;
+	static unsigned int dev_ioc0_count = 1;
+	static unsigned int dev_sb_count = 1;
 
-	dev->core.parent = NULL;
+	if (!dev->core.parent)
+		dev->core.parent = &ps3_system_bus;
 	dev->core.bus = &ps3_system_bus_type;
 	dev->core.release = ps3_system_bus_release_device;
+	switch (iobus_type) {
+	case PS3_IOBUS_SB:
+		dev->core.archdata.dma_ops = &ps3_sb_dma_ops;
+		snprintf(dev->core.bus_id, sizeof(dev->core.bus_id), "sb_%02x",
+			 dev_sb_count++);
+
+		break;
+
+	case PS3_IOBUS_IOC0:
+		dev->core.archdata.dma_ops = &ps3_ioc0_dma_ops;
+		snprintf(dev->core.bus_id, sizeof(dev->core.bus_id),
+			"ioc0_%02x", dev_ioc0_count++);
+		break;
+	default:
+		BUG();
+	};
 
 	dev->core.archdata.of_node = NULL;
-	dev->core.archdata.dma_ops = &ps3_dma_ops;
 	dev->core.archdata.numa_node = 0;
 
-	snprintf(dev->core.bus_id, sizeof(dev->core.bus_id), "sb_%02x",
-		dev_count++);
-
 	pr_debug("%s:%d add %s\n", __func__, __LINE__, dev->core.bus_id);
 
 	result = device_register(&dev->core);
@@ -364,7 +536,8 @@ int ps3_system_bus_device_register(struct ps3_system_bus_device *dev)
 
 EXPORT_SYMBOL_GPL(ps3_system_bus_device_register);
 
-int ps3_system_bus_driver_register(struct ps3_system_bus_driver *drv)
+int ps3_system_bus_driver_register(struct ps3_system_bus_driver *drv,
+	enum ps3_iobus_type iobus_type)
 {
 	int result;
 
diff --git a/include/asm-powerpc/ps3.h b/include/asm-powerpc/ps3.h
index 821581a..25503a5 100644
--- a/include/asm-powerpc/ps3.h
+++ b/include/asm-powerpc/ps3.h
@@ -74,28 +74,54 @@ enum ps3_dma_region_type {
 	PS3_DMA_INTERNAL = 2,
 };
 
+enum ps3_iobus_type {
+	PS3_IOBUS_IOC0 = 1,
+	PS3_IOBUS_SB
+};
+
+struct ps3_dma_region_ops;
+
 /**
+ * struct ps3_dma_region_ops - dma region operations
  * struct ps3_dma_region - A per device dma state variables structure
  * @did: The HV device id.
  * @page_size: The ioc pagesize.
  * @region_type: The HV region type.
  * @bus_addr: The 'translated' bus address of the region.
  * @len: The length in bytes of the region.
+ * @offset: The offset from the start of memory of the region.
+ * @ioid: The IOID of the device who owns this region
  * @chunk_list: Opaque variable used by the ioc page manager.
  */
 
 struct ps3_dma_region {
+	const struct ps3_dma_region_ops * region_ops;
 	struct ps3_device_id did;
 	enum ps3_dma_page_size page_size;
 	enum ps3_dma_region_type region_type;
 	unsigned long bus_addr;
 	unsigned long len;
+	unsigned long offset;
+	unsigned char ioid;
+ 	//unsigned long iopte_flag;
 	struct {
 		spinlock_t lock;
 		struct list_head head;
 	} chunk_list;
 };
 
+struct ps3_dma_region_ops {
+	int (*create)(struct ps3_dma_region *);
+	int (*free)(struct ps3_dma_region *);
+	int (*map)(struct ps3_dma_region *,
+		   unsigned long virt_addr,
+		   unsigned long len,
+		   unsigned long * bus_addr,
+		   u64 iopte_pp);
+	int (*unmap)(struct ps3_dma_region *,
+		     unsigned long bus_addr,
+		     unsigned long len);
+};
 /**
  * struct ps3_dma_region_init - Helper to initialize structure variables
  *
@@ -103,18 +129,16 @@ struct ps3_dma_region {
  * ps3_system_bus_device_register.
  */
 
-static inline void ps3_dma_region_init(struct ps3_dma_region *r,
-	const struct ps3_device_id* did, enum ps3_dma_page_size page_size,
-	enum ps3_dma_region_type region_type)
-{
-	r->did = *did;
-	r->page_size = page_size;
-	r->region_type = region_type;
-}
+void ps3_dma_region_init(struct ps3_dma_region *r,
+	 const struct ps3_device_id *did,
+	 enum ps3_dma_page_size page_size,
+	 enum ps3_dma_region_type region_type, void *addr,
+	 unsigned long len, enum ps3_iobus_type iobus_type);
 int ps3_dma_region_create(struct ps3_dma_region *r);
 int ps3_dma_region_free(struct ps3_dma_region *r);
 int ps3_dma_map(struct ps3_dma_region *r, unsigned long virt_addr,
-	unsigned long len, unsigned long *bus_addr);
+	unsigned long len, unsigned long *bus_addr,
+	u64 iopte_pp);
 int ps3_dma_unmap(struct ps3_dma_region *r, unsigned long bus_addr,
 	unsigned long len);
 
@@ -125,6 +149,7 @@ enum ps3_mmio_page_size {
 	PS3_MMIO_64K = 16U
 };
 
+struct ps3_mmio_region_ops;
 /**
  * struct ps3_mmio_region - a per device mmio state variables structure
  *
@@ -132,6 +157,7 @@ enum ps3_mmio_page_size {
  */
 
 struct ps3_mmio_region {
+	const struct ps3_mmio_region_ops * mmio_ops;
 	struct ps3_device_id did;
 	unsigned long bus_addr;
 	unsigned long len;
@@ -139,6 +165,10 @@ struct ps3_mmio_region {
 	unsigned long lpar_addr;
 };
 
+struct ps3_mmio_region_ops {
+	int (*create)(struct ps3_mmio_region *);
+	int (*free)(struct ps3_mmio_region *);
+};
 /**
  * struct ps3_mmio_region_init - Helper to initialize structure variables
  *
@@ -146,15 +176,10 @@ struct ps3_mmio_region {
  * ps3_system_bus_device_register.
  */
 
-static inline void ps3_mmio_region_init(struct ps3_mmio_region *r,
+void ps3_mmio_region_init(struct ps3_mmio_region *r,
 	const struct ps3_device_id* did, unsigned long bus_addr,
-	unsigned long len, enum ps3_mmio_page_size page_size)
-{
-	r->did = *did;
-	r->bus_addr = bus_addr;
-	r->len = len;
-	r->page_size = page_size;
-}
+	unsigned long len, enum ps3_mmio_page_size page_size,
+			  enum ps3_iobus_type iobus_type);
 int ps3_mmio_region_create(struct ps3_mmio_region *r);
 int ps3_free_mmio_region(struct ps3_mmio_region *r);
 unsigned long ps3_mm_phys_to_lpar(unsigned long phys_addr);
@@ -289,6 +314,10 @@ enum ps3_match_id {
 	PS3_MATCH_ID_GELIC,
 	PS3_MATCH_ID_AV_SETTINGS,
 	PS3_MATCH_ID_SYSTEM_MANAGER,
+	PS3_MATCH_ID_STOR_DISK,
+	PS3_MATCH_ID_STOR_ROM,
+	PS3_MATCH_ID_STOR_FLASH,
+	PS3_MATCH_ID_SOUND,
 };
 
 /**
@@ -305,6 +334,15 @@ struct ps3_system_bus_device {
 	struct device core;
 };
 
+static inline void ps3_system_bus_device_init(struct ps3_system_bus_device * dev,
+		enum ps3_match_id match_id,
+		struct ps3_dma_region * d_region,
+		struct ps3_mmio_region * m_region)
+{
+	dev->match_id = match_id;
+	dev->m_region = m_region;
+	dev->d_region = d_region;
+};
 /**
  * struct ps3_system_bus_driver - a driver for a device on the system bus
  */
@@ -318,8 +356,10 @@ struct ps3_system_bus_driver {
 /*	int (*resume)(struct ps3_system_bus_device *); */
 };
 
-int ps3_system_bus_device_register(struct ps3_system_bus_device *dev);
-int ps3_system_bus_driver_register(struct ps3_system_bus_driver *drv);
+int ps3_system_bus_device_register(struct ps3_system_bus_device *dev,
+				   enum ps3_iobus_type iobus_type);
+int ps3_system_bus_driver_register(struct ps3_system_bus_driver *drv,
+				   enum ps3_iobus_type iobus_type);
 void ps3_system_bus_driver_unregister(struct ps3_system_bus_driver *drv);
 static inline struct ps3_system_bus_driver *to_ps3_system_bus_driver(
 	struct device_driver *_drv)
--- /dev/null	2007-05-01 15:16:24.100521312 +0100
+++ b/arch/powerpc/platforms/ps3/system-bus-rework.txt	2007-05-04 11:22:01.000000000 +0100
@@ -0,0 +1,37 @@
+Status of the system-bus re-work
+
+o=working
+x=not working
+
+				flash	kexec		kexec	reboot		insmod	rmmod
+				boot	shutdown	boot	shutdown
+
+CONFIG_GELIC_NET		o(1)
+CONFIG_FB_PS3			o
+CONFIG_USB_EHCI_HCD		o
+CONFIG_USB_OHCI_HCD		o
+CONFIG_PS3_VUART		o
+CONFIG_PS3_STORAGE		o
+CONFIG_PS3_STORAGE_BUS		o
+CONFIG_PS3_STORAGE_FLASH	o
+CONFIG_PS3_STORAGE_DISK		o
+CONFIG_PS3_STORAGE_ROM		o
+CONFIG_SND_PS3			o
+
+
+(1) Root-NFS: Unable to get nfsd port number from server
+    Only tested on FC7
+    Startup timing problem?
+
+--------------------------------------------------------------------------------
+-- drv.probe routines --
+
+ps3_gelic_driver_probe
+fb?
+ps3_ohci_sb_probe
+ps3_ehci_sb_probe
+ps3flash_probe
+ps3disk_probe
+ps3rom_probe
+snd_ps3_driver_probe
+--------------------------------------------------------------------------------

linux-2.6-ps3-usb-autoload.patch:

--- NEW FILE linux-2.6-ps3-usb-autoload.patch ---
diff --git a/drivers/usb/host/ehci-ps3.c b/drivers/usb/host/ehci-ps3.c
index 4d781a2..fe485a0 100644
--- a/drivers/usb/host/ehci-ps3.c
+++ b/drivers/usb/host/ehci-ps3.c
@@ -182,6 +182,7 @@ static int ps3_ehci_sb_remove(struct ps3_system_bus_device *dev)
 }
 
 MODULE_ALIAS("ps3-ehci");
+MODULE_ALIAS("ps3:1");
 
 static struct ps3_system_bus_driver ps3_ehci_sb_driver = {
 	.match_id = PS3_MATCH_ID_EHCI,
diff --git a/drivers/usb/host/ohci-ps3.c b/drivers/usb/host/ohci-ps3.c
index 62283a3..1004d91 100644
--- a/drivers/usb/host/ohci-ps3.c
+++ b/drivers/usb/host/ohci-ps3.c
@@ -185,6 +185,7 @@ static int ps3_ohci_sb_remove (struct ps3_system_bus_device *dev)
 }
 
 MODULE_ALIAS("ps3-ohci");
+MODULE_ALIAS("ps3:2");
 
 static struct ps3_system_bus_driver ps3_ohci_sb_driver = {
 	.match_id = PS3_MATCH_ID_OHCI,

linux-2.6-ps3-wrap-spu-runctl.patch:

--- NEW FILE linux-2.6-ps3-wrap-spu-runctl.patch ---
From: Masato Noguchi <Masato.Noguchi at jp.sony.com>

 [ note: This patch is a hot-fix and RFC. ]

Current kernel uses the master run control bit (MFC_SR1[S]) to
control SPE execution in spufs_run_spu(). PS3 hypervisor does not
permit to change this bit.
This cause Oops that Gerhard pointed out before.

I know, oldtime kernel used run control register in priv2, and
it was replaced by master run bit to avoid vulnerability.
But, for now, I made a patch closing my eyes to it.
I want to fix it witout using master run bit, if possible.
Does anyone have comments?


BTW, in current implementation, if spe was running at disabled
by master run, it seems to be failed at next spu_run syscall.
Is it correct?


Signed-off-by: Masato Noguchi <Masato.Noguchi at jp.sony.com>
---
 arch/powerpc/platforms/cell/spu_base.c          |    1 +
 arch/powerpc/platforms/cell/spu_manage.c        |   15 +++++++++++++++
 arch/powerpc/platforms/cell/spufs/backing_ops.c |    6 ++++++
 arch/powerpc/platforms/cell/spufs/hw_ops.c      |   10 ++++++++++
 arch/powerpc/platforms/cell/spufs/run.c         |    4 ++--
 arch/powerpc/platforms/cell/spufs/spufs.h       |    1 +
 arch/powerpc/platforms/ps3/spu.c                |   14 ++++++++++++++
 include/asm-powerpc/spu_priv1.h                 |   14 ++++++++++++++
 8 files changed, 63 insertions(+), 2 deletions(-)

--- ps3-linux-dev.orig/arch/powerpc/platforms/cell/spu_manage.c
+++ ps3-linux-dev/arch/powerpc/platforms/cell/spu_manage.c
@@ -35,6 +35,7 @@
 #include <asm/firmware.h>
 #include <asm/prom.h>
 
+#include "spufs/spufs.h"
 #include "interrupt.h"
 
 struct device_node *spu_devnode(struct spu *spu)
@@ -413,8 +414,22 @@ static int of_destroy_spu(struct spu *sp
 	return 0;
 }
 
+static int enable_spu_by_master_run(struct spu_context *ctx)
+{
+	ctx->ops->master_start(ctx);
+	return 0;
+}
+
+static int disable_spu_by_master_run(struct spu_context *ctx)
+{
+	ctx->ops->master_stop(ctx);
+	return 0;
+}
+
 const struct spu_management_ops spu_management_of_ops = {
 	.enumerate_spus = of_enumerate_spus,
 	.create_spu = of_create_spu,
 	.destroy_spu = of_destroy_spu,
+	.enable_spu = enable_spu_by_master_run,
+	.disable_spu = disable_spu_by_master_run,
 };
--- ps3-linux-dev.orig/arch/powerpc/platforms/cell/spufs/backing_ops.c
+++ ps3-linux-dev/arch/powerpc/platforms/cell/spufs/backing_ops.c
@@ -285,6 +285,11 @@ static void spu_backing_runcntl_write(st
 	spin_unlock(&ctx->csa.register_lock);
 }
 
+static void spu_backing_runcntl_stop(struct spu_context *ctx)
+{
+	spu_backing_runcntl_write(ctx, SPU_RUNCNTL_STOP);
+}
+
 static void spu_backing_master_start(struct spu_context *ctx)
 {
 	struct spu_state *csa = &ctx->csa;
@@ -370,6 +375,7 @@ struct spu_context_ops spu_backing_ops =
 	.get_ls = spu_backing_get_ls,
 	.runcntl_read = spu_backing_runcntl_read,
 	.runcntl_write = spu_backing_runcntl_write,
+	.runcntl_stop = spu_backing_runcntl_stop,
 	.master_start = spu_backing_master_start,
 	.master_stop = spu_backing_master_stop,
 	.set_mfc_query = spu_backing_set_mfc_query,
--- ps3-linux-dev.orig/arch/powerpc/platforms/cell/spufs/hw_ops.c
+++ ps3-linux-dev/arch/powerpc/platforms/cell/spufs/hw_ops.c
@@ -221,6 +221,15 @@ static void spu_hw_runcntl_write(struct 
 	spin_unlock_irq(&ctx->spu->register_lock);
 }
 
+static void spu_hw_runcntl_stop(struct spu_context *ctx)
+{
+	spin_lock_irq(&ctx->spu->register_lock);
+	out_be32(&ctx->spu->problem->spu_runcntl_RW, SPU_RUNCNTL_STOP);
+	while(in_be32(&ctx->spu->problem->spu_status_R) & SPU_STATUS_RUNNING)
+		cpu_relax();
+	spin_unlock_irq(&ctx->spu->register_lock);
+}
+
 static void spu_hw_master_start(struct spu_context *ctx)
 {
 	struct spu *spu = ctx->spu;
@@ -314,6 +323,7 @@ struct spu_context_ops spu_hw_ops = {
 	.get_ls = spu_hw_get_ls,
 	.runcntl_read = spu_hw_runcntl_read,
 	.runcntl_write = spu_hw_runcntl_write,
+	.runcntl_stop = spu_hw_runcntl_stop,
 	.master_start = spu_hw_master_start,
 	.master_stop = spu_hw_master_stop,
 	.set_mfc_query = spu_hw_set_mfc_query,
--- ps3-linux-dev.orig/arch/powerpc/platforms/cell/spufs/run.c
+++ ps3-linux-dev/arch/powerpc/platforms/cell/spufs/run.c
@@ -310,7 +310,7 @@ long spufs_run_spu(struct file *file, st
 	if (down_interruptible(&ctx->run_sema))
 		return -ERESTARTSYS;
 
-	ctx->ops->master_start(ctx);
+	spu_enable_spu(ctx);
 	ctx->event_return = 0;
 	ret = spu_run_init(ctx, npc);
 	if (ret)
@@ -338,7 +338,7 @@ long spufs_run_spu(struct file *file, st
 	} while (!ret && !(status & (SPU_STATUS_STOPPED_BY_STOP |
 				      SPU_STATUS_STOPPED_BY_HALT)));
 
-	ctx->ops->master_stop(ctx);
+	spu_disable_spu(ctx);
 	ret = spu_run_fini(ctx, npc, &status);
 	spu_yield(ctx);
 
--- ps3-linux-dev.orig/arch/powerpc/platforms/cell/spufs/spufs.h
+++ ps3-linux-dev/arch/powerpc/platforms/cell/spufs/spufs.h
@@ -117,6 +117,7 @@ struct spu_context_ops {
 	char*(*get_ls) (struct spu_context * ctx);
 	 u32 (*runcntl_read) (struct spu_context * ctx);
 	void (*runcntl_write) (struct spu_context * ctx, u32 data);
+	void (*runcntl_stop) (struct spu_context * ctx);
 	void (*master_start) (struct spu_context * ctx);
 	void (*master_stop) (struct spu_context * ctx);
 	int (*set_mfc_query)(struct spu_context * ctx, u32 mask, u32 mode);
--- ps3-linux-dev.orig/arch/powerpc/platforms/ps3/spu.c
+++ ps3-linux-dev/arch/powerpc/platforms/ps3/spu.c
@@ -28,6 +28,7 @@
 #include <asm/spu_priv1.h>
 #include <asm/lv1call.h>
 
+#include "../cell/spufs/spufs.h"
 #include "platform.h"
 
 /* spu_management_ops */
@@ -445,10 +446,23 @@ static int __init ps3_enumerate_spus(int
 	return result;
 }
 
+static int ps3_enable_spu(struct spu_context *ctx)
+{
+	return -ENOSYS;
+}
+
+static int ps3_disable_spu(struct spu_context *ctx)
+{
+	ctx->ops->runcntl_stop(ctx);
+	return -ENOSYS;
+}
+
 const struct spu_management_ops spu_management_ps3_ops = {
 	.enumerate_spus = ps3_enumerate_spus,
 	.create_spu = ps3_create_spu,
 	.destroy_spu = ps3_destroy_spu,
+	.enable_spu = ps3_enable_spu,
+	.disable_spu = ps3_disable_spu,
 };
 
 /* spu_priv1_ops */
--- ps3-linux-dev.orig/include/asm-powerpc/spu_priv1.h
+++ ps3-linux-dev/include/asm-powerpc/spu_priv1.h
@@ -24,6 +24,7 @@
 #include <linux/types.h>
 
 struct spu;
+struct spu_context;
 
 /* access to priv1 registers */
 
@@ -178,6 +178,8 @@ struct spu_management_ops {
 	int (*enumerate_spus)(int (*fn)(void *data));
 	int (*create_spu)(struct spu *spu, void *data);
 	int (*destroy_spu)(struct spu *spu);
+	int (*enable_spu)(struct spu_context *ctx);
+	int (*disable_spu)(struct spu_context *ctx);
 };
 
 extern const struct spu_management_ops* spu_management_ops;
@@ -200,6 +202,18 @@ spu_destroy_spu (struct spu *spu)
 	return spu_management_ops->destroy_spu(spu);
 }
 
+static inline int
+spu_enable_spu (struct spu_context *ctx)
+{
+	return spu_management_ops->enable_spu(ctx);
+}
+
+static inline int
+spu_disable_spu (struct spu_context *ctx)
+{
+	return spu_management_ops->disable_spu(ctx);
+}
+
 /*
  * The declarations folowing are put here for convenience
  * and only intended to be used by the platform setup code.

linux-2.6-ps3av-export-header.patch:

--- NEW FILE linux-2.6-ps3av-export-header.patch ---
diff --git a/include/asm-powerpc/Kbuild b/include/asm-powerpc/Kbuild
index 4869513..0f6c60b 100644
--- a/include/asm-powerpc/Kbuild
+++ b/include/asm-powerpc/Kbuild
@@ -34,6 +34,7 @@ unifdef-y += elf.h
 unifdef-y += nvram.h
 unifdef-y += param.h
 unifdef-y += posix_types.h
+unifdef-y += ps3av.h
 unifdef-y += ptrace.h
 unifdef-y += seccomp.h
 unifdef-y += signal.h
diff --git a/include/asm-powerpc/ps3av.h b/include/asm-powerpc/ps3av.h
index 1366fc5..6e34bcf 100644
--- a/include/asm-powerpc/ps3av.h
+++ b/include/asm-powerpc/ps3av.h
@@ -664,6 +664,8 @@ struct ps3av_pkt_avb_param {
 #define PS3AV_STATUS_UNSUPPORTED_HDMI_MODE	0x0012	/* unsupported hdmi mode */
 #define PS3AV_STATUS_NO_SYNC_HEAD		0x0013	/* sync head failed */
 
+#ifdef __KERNEL__
+
 extern void ps3av_set_hdr(u32, u16, struct ps3av_send_hdr *);
 extern int ps3av_do_pkt(u32, u16, size_t, struct ps3av_send_hdr *);
 
@@ -716,4 +718,5 @@ extern int ps3av_audio_mute(int);
 extern int ps3av_dev_open(void);
 extern int ps3av_dev_close(void);
 
+#endif  /* __KERNEL__ */
 #endif	/* _ASM_POWERPC_PS3AV_H_ */

linux-2.6-ps3fb-panic.patch:

--- NEW FILE linux-2.6-ps3fb-panic.patch ---
diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c
index ac5df96..1ae9091 100644
--- a/arch/powerpc/platforms/ps3/setup.c
+++ b/arch/powerpc/platforms/ps3/setup.c
@@ -46,6 +46,8 @@
 static void smp_send_stop(void) {}
 #endif
 
+extern void ps3fb_sync(int);
+
 int ps3_get_firmware_version(union ps3_firmware_version *v)
 {
 	int result = lv1_get_version_info(&v->raw);
@@ -88,8 +90,20 @@ static void ps3_power_off(void)
 
 static void ps3_panic(char *str)
 {
+	static int panicked = 0;
+
 	DBG("%s:%d %s\n", __func__, __LINE__, str);
 
+#ifdef CONFIG_FB_PS3
+	/* It's almost certainly the only available console device outside
+	   Sony, and we don't _see_ the events leading up to the panic 
+	   unless we ask the hypervisor to update it. So do so. Once. */
+	if (!panicked) {
+		panicked = 1;
+		ps3fb_sync(0);
+	}
+#endif
+
 	smp_send_stop();
 	printk("\n");
 	printk("   System does not reboot automatically.\n");
diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c
index 81e43cd..f90a43e 100644
--- a/drivers/video/ps3fb.c
+++ b/drivers/video/ps3fb.c
@@ -381,7 +381,7 @@ static const struct fb_videomode *ps3fb_default_mode(void)
 	return &ps3fb_modedb[mode - 1];
 }
 
-static int ps3fb_sync(u32 frame)
+int ps3fb_sync(u32 frame)
 {
 	int i, status;
 	u32 xres, yres;

linux-2.6-scsi-async-double-add.patch:

--- NEW FILE linux-2.6-scsi-async-double-add.patch ---
From: Matthew Wilcox <matthew at wil.cx>
Date: Tue, 26 Jun 2007 21:18:51 +0000 (-0600)
Subject: [SCSI] Fix async scanning double-add problems
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fjejb%2Fscsi-misc-2.6.git;a=commitdiff_plain;h=a93a091df8232fad60867d41fbc3be855a0b78f2

[SCSI] Fix async scanning double-add problems

Stress-testing and some thought has revealed some places where
asynchronous scanning needs some more attention to locking.

 - Since async_scan is a bit, we need to hold the host_lock while
   modifying it to prevent races against other CPUs modifying the word
   that bit is in.  This is probably a theoretical race for the moment,
   but other patches may change that.
 - The async_scan bit means not only that this host is being scanned
   asynchronously, but that all the devices attached to this host are not
   yet added to sysfs.  So we must ensure that this bit is always in sync.
   I've chosen to do this with the scan_mutex since it's already acquired
   in most of the right places.
 - If the host changes state to deleted while we're in the middle of
   a scan, we'll end up with some devices on the host's list which must
   be deleted.  Add a check to scsi_sysfs_add_devices() to ensure the
   host is still running.
 - To avoid the async_scan bit being protected by three locks, the
   async_scan_lock now only protects the scanning_list.

Signed-off-by: Matthew Wilcox <matthew at wil.cx>
Signed-off-by: James Bottomley <James.Bottomley at SteelEye.com>
---

diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index a86e62f..309b224 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -121,6 +121,7 @@ MODULE_PARM_DESC(inq_timeout,
 		 "Timeout (in seconds) waiting for devices to answer INQUIRY."
 		 " Default is 5. Some non-compliant devices need more.");
 
+/* This lock protects only this list */
 static DEFINE_SPINLOCK(async_scan_lock);
 static LIST_HEAD(scanning_hosts);
 
@@ -1466,14 +1467,14 @@ struct scsi_device *__scsi_add_device(struct Scsi_Host *shost, uint channel,
 	if (strncmp(scsi_scan_type, "none", 4) == 0)
 		return ERR_PTR(-ENODEV);
 
-	if (!shost->async_scan)
-		scsi_complete_async_scans();
-
 	starget = scsi_alloc_target(parent, channel, id);
 	if (!starget)
 		return ERR_PTR(-ENOMEM);
 
 	mutex_lock(&shost->scan_mutex);
+	if (!shost->async_scan)
+		scsi_complete_async_scans();
+
 	if (scsi_host_scan_allowed(shost))
 		scsi_probe_and_add_lun(starget, lun, NULL, &sdev, 1, hostdata);
 	mutex_unlock(&shost->scan_mutex);
@@ -1586,10 +1587,10 @@ void scsi_scan_target(struct device *parent, unsigned int channel,
 	if (strncmp(scsi_scan_type, "none", 4) == 0)
 		return;
 
+	mutex_lock(&shost->scan_mutex);
 	if (!shost->async_scan)
 		scsi_complete_async_scans();
 
-	mutex_lock(&shost->scan_mutex);
 	if (scsi_host_scan_allowed(shost))
 		__scsi_scan_target(parent, channel, id, lun, rescan);
 	mutex_unlock(&shost->scan_mutex);
@@ -1634,15 +1635,15 @@ int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel,
 		"%s: <%u:%u:%u>\n",
 		__FUNCTION__, channel, id, lun));
 
-	if (!shost->async_scan)
-		scsi_complete_async_scans();
-
 	if (((channel != SCAN_WILD_CARD) && (channel > shost->max_channel)) ||
 	    ((id != SCAN_WILD_CARD) && (id >= shost->max_id)) ||
 	    ((lun != SCAN_WILD_CARD) && (lun > shost->max_lun)))
 		return -EINVAL;
 
 	mutex_lock(&shost->scan_mutex);
+	if (!shost->async_scan)
+		scsi_complete_async_scans();
+
 	if (scsi_host_scan_allowed(shost)) {
 		if (channel == SCAN_WILD_CARD)
 			for (channel = 0; channel <= shost->max_channel;
@@ -1661,7 +1662,8 @@ static void scsi_sysfs_add_devices(struct Scsi_Host *shost)
 {
 	struct scsi_device *sdev;
 	shost_for_each_device(sdev, shost) {
-		if (scsi_sysfs_add_sdev(sdev) != 0)
+		if (!scsi_host_scan_allowed(shost) ||
+		    scsi_sysfs_add_sdev(sdev) != 0)
 			scsi_destroy_sdev(sdev);
 	}
 }
@@ -1679,6 +1681,7 @@ static void scsi_sysfs_add_devices(struct Scsi_Host *shost)
 static struct async_scan_data *scsi_prep_async_scan(struct Scsi_Host *shost)
 {
 	struct async_scan_data *data;
+	unsigned long flags;
 
 	if (strncmp(scsi_scan_type, "sync", 4) == 0)
 		return NULL;
@@ -1698,8 +1701,13 @@ static struct async_scan_data *scsi_prep_async_scan(struct Scsi_Host *shost)
 		goto err;
 	init_completion(&data->prev_finished);
 
-	spin_lock(&async_scan_lock);
+	mutex_lock(&shost->scan_mutex);
+	spin_lock_irqsave(shost->host_lock, flags);
 	shost->async_scan = 1;
+	spin_unlock_irqrestore(shost->host_lock, flags);
+	mutex_unlock(&shost->scan_mutex);
+
+	spin_lock(&async_scan_lock);
 	if (list_empty(&scanning_hosts))
 		complete(&data->prev_finished);
 	list_add_tail(&data->list, &scanning_hosts);
@@ -1723,11 +1731,15 @@ static struct async_scan_data *scsi_prep_async_scan(struct Scsi_Host *shost)
 static void scsi_finish_async_scan(struct async_scan_data *data)
 {
 	struct Scsi_Host *shost;
+	unsigned long flags;
 
 	if (!data)
 		return;
 
 	shost = data->shost;
+
+	mutex_lock(&shost->scan_mutex);
+
 	if (!shost->async_scan) {
 		printk("%s called twice for host %d", __FUNCTION__,
 				shost->host_no);
@@ -1739,8 +1751,13 @@ static void scsi_finish_async_scan(struct async_scan_data *data)
 
 	scsi_sysfs_add_devices(shost);
 
-	spin_lock(&async_scan_lock);
+	spin_lock_irqsave(shost->host_lock, flags);
 	shost->async_scan = 0;
+	spin_unlock_irqrestore(shost->host_lock, flags);
+
+	mutex_unlock(&shost->scan_mutex);
+
+	spin_lock(&async_scan_lock);
 	list_del(&data->list);
 	if (!list_empty(&scanning_hosts)) {
 		struct async_scan_data *next = list_entry(scanning_hosts.next,

linux-2.6-scsi-bounce-isa.patch:

--- NEW FILE linux-2.6-scsi-bounce-isa.patch ---

http://marc.info/?l=linux-scsi&m=115981479822790&w=2

--- linux-2.6.21.noarch/block/ll_rw_blk.c~	2007-05-18 16:05:04.000000000 -0400
+++ linux-2.6.21.noarch/block/ll_rw_blk.c	2007-05-18 16:07:32.000000000 -0400
@@ -2556,6 +2556,8 @@ int blk_rq_map_kern(request_queue_t *q, 
 		bio->bi_rw |= (1 << BIO_RW);
 
 	blk_rq_bio_prep(q, rq, bio);
+	blk_queue_bounce(q, &rq->bio);
+
 	rq->buffer = rq->data = NULL;
 	return 0;
 }

linux-2.6-scsi-mpt-vmware-fix.patch:

--- NEW FILE linux-2.6-scsi-mpt-vmware-fix.patch ---
The attached patch is a workaround for a bug in VMWare's emulated LSI
Fusion SCSI HBA.  The emulated firmware returns zero for the maximum
number of attached devices; the real firmware returns a positive
number.  Therefore, the kernel that boots and works fine on bare metal
will fail on VMWare because this firmware value is handed to the SCSI
midlayer, which then skips the entire bus scan.

F7 bz 241935

The patch below was submitted by Eric Moore of LSI to the linux-scsi
mailing list:

http://marc.info/?l=linux-scsi&m=117432237404247

then immediately rejected by Christoph Hellwig, who prefers that
VMWare fix their emulation instead.

diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index eddb933..21fadf2 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -2571,8 +2571,19 @@ GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
 	pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
 	pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
 
-	max_id = (ioc->bus_type == SAS) ? pfacts->PortSCSIID :
-	    pfacts->MaxDevices;
+	switch (ioc->bus_type) {
+	case SAS:
+		max_id = pfacts->PortSCSIID;
+		break;
+	case FC:
+		max_id = pfacts->MaxDevices;
+		break;
+	case SPI:
+	default:
+		max_id = MPT_MAX_SCSI_DEVICES;
+		break;
+	}
+
 	ioc->devices_per_bus = (max_id > 255) ? 256 : max_id;
 	ioc->number_of_buses = (ioc->devices_per_bus < 256) ? 1 : max_id/256;
 

linux-2.6-smarter-relatime.patch:

--- NEW FILE linux-2.6-smarter-relatime.patch ---

Subject: [patch] [patch] implement smarter atime updates support
From: Ingo Molnar <mingo at elte.hu>

change relatime updates to be performed once per day. This makes
relatime a compatible solution for HSM, mailer-notification and
tmpwatch applications too.

also add the CONFIG_DEFAULT_RELATIME kernel option, which makes
"norelatime" the default for all mounts without an extra kernel
boot option.

add the "default_relatime=0" boot option to turn this off.

also add the /proc/sys/kernel/default_relatime flag which can be changed
runtime to modify the behavior of subsequent new mounts.

tested by moving the date forward:

   # date
   Sun Aug  5 22:55:14 CEST 2007
   # date -s "Tue Aug  7 22:55:14 CEST 2007"
   Tue Aug  7 22:55:14 CEST 2007

access to a file did not generate disk IO before the date was set, and
it generated exactly one IO after the date was set.

Signed-off-by: Ingo Molnar <mingo at elte.hu>
---
 Documentation/kernel-parameters.txt |    8 +++++
 fs/Kconfig                          |   22 ++++++++++++++
 fs/inode.c                          |   53 +++++++++++++++++++++++++++---------
 fs/namespace.c                      |   24 ++++++++++++++++
 include/linux/mount.h               |    3 ++
 kernel/sysctl.c                     |   17 +++++++++++
 6 files changed, 114 insertions(+), 13 deletions(-)

Index: linux/Documentation/kernel-parameters.txt
===================================================================
--- linux.orig/Documentation/kernel-parameters.txt
+++ linux/Documentation/kernel-parameters.txt
@@ -525,6 +525,10 @@ and is between 256 and 4096 characters. 
 			This is a 16-member array composed of values
 			ranging from 0-255.
 
+	default_relatime=
+			[FS] mount all filesystems with relative atime
+			updates by default.
+
 	default_utf8=   [VT]
 			Format=<0|1>
 			Set system-wide default UTF-8 mode for all tty's.
@@ -1468,6 +1472,10 @@ and is between 256 and 4096 characters. 
 			Format: <reboot_mode>[,<reboot_mode2>[,...]]
 			See arch/*/kernel/reboot.c or arch/*/kernel/process.c			
 
+	relatime_interval=
+			[FS] relative atime update frequency, in seconds.
+			(default: 1 day: 86400 seconds)
+
 	reserve=	[KNL,BUGS] Force the kernel to ignore some iomem area
 
 	reservetop=	[X86-32]
Index: linux/fs/Kconfig
===================================================================
--- linux.orig/fs/Kconfig
+++ linux/fs/Kconfig
@@ -2060,6 +2060,28 @@ config 9P_FS
 
 endmenu
 
+config DEFAULT_RELATIME
+	bool "Mount all filesystems with relatime by default"
+	default y
+	help
+	  If you say Y here, all your filesystems will be mounted
+	  with the "relatime" mount option. This eliminates many atime
+	  ('file last accessed' timestamp) updates (which otherwise
+	  is performed on every file access and generates a write
+	  IO to the inode) and thus speeds up IO. Atime is still updated,
+	  but only once per day.
+
+	  The mtime ('file last modified') and ctime ('file created')
+	  timestamp are unaffected by this change.
+
+	  Use the "norelatime" kernel boot option to turn off this
+	  feature.
+
+config DEFAULT_RELATIME_VAL
+	int
+	default "1" if DEFAULT_RELATIME
+	default "0"
+
 if BLOCK
 menu "Partition Types"
 
Index: linux/fs/inode.c
===================================================================
--- linux.orig/fs/inode.c
+++ linux/fs/inode.c
@@ -1162,6 +1162,41 @@ sector_t bmap(struct inode * inode, sect
 }
 EXPORT_SYMBOL(bmap);
 
+/*
+ * Relative atime updates frequency (default: 1 day):
+ */
+int relatime_interval __read_mostly = 24*60*60;
+
+/*
+ * With relative atime, only update atime if the
+ * previous atime is earlier than either the ctime or
+ * mtime.
+ */
+static int relatime_need_update(struct inode *inode, struct timespec now)
+{
+	/*
+	 * Is mtime younger than atime? If yes, update atime:
+	 */
+	if (timespec_compare(&inode->i_mtime, &inode->i_atime) >= 0)
+		return 1;
+	/*
+	 * Is ctime younger than atime? If yes, update atime:
+	 */
+	if (timespec_compare(&inode->i_ctime, &inode->i_atime) >= 0)
+		return 1;
+
+	/*
+	 * Is the previous atime value older than a day? If yes,
+	 * update atime:
+	 */
+	if ((long)(now.tv_sec - inode->i_atime.tv_sec) >= relatime_interval)
+		return 1;
+	/*
+	 * Good, we can skip the atime update:
+	 */
+	return 0;
+}
+
 /**
  *	touch_atime	-	update the access time
  *	@mnt: mount the inode is accessed on
@@ -1191,22 +1226,14 @@ void touch_atime(struct vfsmount *mnt, s
 			return;
 		if ((mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode))
 			return;
-
-		if (mnt->mnt_flags & MNT_RELATIME) {
-			/*
-			 * With relative atime, only update atime if the
-			 * previous atime is earlier than either the ctime or
-			 * mtime.
-			 */
-			if (timespec_compare(&inode->i_mtime,
-						&inode->i_atime) < 0 &&
-			    timespec_compare(&inode->i_ctime,
-						&inode->i_atime) < 0)
+	}
+	now = current_fs_time(inode->i_sb);
+	if (mnt) {
+		if (mnt->mnt_flags & MNT_RELATIME)
+			if (!relatime_need_update(inode, now))
 				return;
-		}
 	}
 
-	now = current_fs_time(inode->i_sb);
 	if (timespec_equal(&inode->i_atime, &now))
 		return;
 
Index: linux/fs/namespace.c
===================================================================
--- linux.orig/fs/namespace.c
+++ linux/fs/namespace.c
@@ -1107,6 +1107,7 @@ int do_add_mount(struct vfsmount *newmnt
 		goto unlock;
 
 	newmnt->mnt_flags = mnt_flags;
+
 	if ((err = graft_tree(newmnt, nd)))
 		goto unlock;
 
@@ -1362,6 +1363,24 @@ int copy_mount_options(const void __user
 }
 
 /*
+ * Allow users to disable (or enable) atime updates via a .config
+ * option or via the boot line, or via /proc/sys/fs/default_relatime:
+ */
+int default_relatime __read_mostly = CONFIG_DEFAULT_RELATIME_VAL;
+
+static int __init set_default_relatime(char *str)
+{
+	get_option(&str, &default_relatime);
+
+	printk(KERN_INFO "Mount all filesystems with"
+		"default relative atime updates: %s.\n",
+		default_relatime ? "enabled" : "disabled");
+
+	return 1;
+}
+__setup("default_relatime=", set_default_relatime);
+
+/*
  * Flags is a 32-bit value that allows up to 31 non-fs dependent flags to
  * be given to the mount() call (ie: read-only, no-dev, no-suid etc).
  *
@@ -1409,6 +1428,11 @@ long do_mount(char *dev_name, char *dir_
 		mnt_flags |= MNT_NODIRATIME;
 	if (flags & MS_RELATIME)
 		mnt_flags |= MNT_RELATIME;
+	else if (default_relatime &&
+				!(flags & (MNT_NOATIME | MNT_NODIRATIME))) {
+		mnt_flags |= MNT_RELATIME;
+		flags |= MS_RELATIME;
+	}
 
 	flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE |
 		   MS_NOATIME | MS_NODIRATIME | MS_RELATIME);
Index: linux/include/linux/mount.h
===================================================================
--- linux.orig/include/linux/mount.h
+++ linux/include/linux/mount.h
@@ -103,5 +103,8 @@ extern void shrink_submounts(struct vfsm
 extern spinlock_t vfsmount_lock;
 extern dev_t name_to_dev_t(char *name);
 
+extern int default_relatime;
+extern int relatime_interval;
+
 #endif
 #endif /* _LINUX_MOUNT_H */
Index: linux/kernel/sysctl.c
===================================================================
--- linux.orig/kernel/sysctl.c
+++ linux/kernel/sysctl.c
@@ -30,6 +30,7 @@
 #include <linux/capability.h>
 #include <linux/smp_lock.h>
 #include <linux/fs.h>
+#include <linux/mount.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/kobject.h>
@@ -1206,6 +1207,22 @@ static ctl_table fs_table[] = {
 		.mode		= 0644,
 		.proc_handler	= &proc_dointvec,
 	},
+	{
+		.ctl_name	= CTL_UNNUMBERED,
+		.procname	= "default_relatime",
+		.data		= &default_relatime,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec,
+	},
+	{
+		.ctl_name	= CTL_UNNUMBERED,
+		.procname	= "relatime_interval",
+		.data		= &relatime_interval,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec,
+	},
 #if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE)
 	{
 		.ctl_name	= CTL_UNNUMBERED,


linux-2.6-softirq-printout-irq-trace-events.patch:

--- NEW FILE linux-2.6-softirq-printout-irq-trace-events.patch ---
>From davej  Thu May 24 11:09:36 2007
Return-Path: <cebbert at redhat.com>
X-Spam-Checker-Version: SpamAssassin 3.1.8 (2007-02-13) on
	gelk.kernelslacker.org
X-Spam-Level: 
X-Spam-Status: No, score=-1.9 required=5.0 tests=AWL,BAYES_00,INFO_TLD,
	UNPARSEABLE_RELAY autolearn=no version=3.1.8
Received: from pobox.devel.redhat.com [10.11.255.8]
	by gelk.kernelslacker.org with IMAP (fetchmail-6.3.6)
	for <davej at localhost> (single-drop); Thu, 24 May 2007 11:09:36 -0400 (EDT)
Received: from pobox.devel.redhat.com ([unix socket])
	 by pobox.devel.redhat.com (Cyrus v2.2.12-Invoca-RPM-2.2.12-8.1.RHEL4) with LMTPA;
	 Thu, 24 May 2007 11:05:33 -0400
X-Sieve: CMU Sieve 2.2
Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254])
	by pobox.devel.redhat.com (8.13.1/8.13.1) with ESMTP id l4OF5X6T020270
	for <davej at pobox.devel.redhat.com>; Thu, 24 May 2007 11:05:33 -0400
Received: from mail.boston.redhat.com (mail.boston.redhat.com [172.16.76.12])
	by int-mx1.corp.redhat.com (8.13.1/8.13.1) with ESMTP id l4OF5XHU002244
	for <davej at int-mx1.corp.redhat.com>; Thu, 24 May 2007 11:05:33 -0400
Received: from [172.16.83.145] (dhcp83-145.boston.redhat.com [172.16.83.145])
	by mail.boston.redhat.com (8.13.1/8.13.1) with ESMTP id l4OF5WtT016174
	for <davej at redhat.com>; Thu, 24 May 2007 11:05:32 -0400
Message-ID: <4655A9BC.3000202 at redhat.com>
Date: Thu, 24 May 2007 11:05:32 -0400
From: Chuck Ebbert <cebbert at redhat.com>
Organization: Red Hat
User-Agent: Thunderbird 1.5.0.10 (X11/20070302)
MIME-Version: 1.0
To: Dave Jones <davej at redhat.com>
Subject: [Fwd: Re: [BUG] local_softirq_pending storm]
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
Status: RO
Content-Length: 4816
Lines: 107

Dave, can we get this into the kernel and ask people to run the debug
kernel (it has PROVE_LOCKING enabled.) This is BZ #240982.

-------- Original Message --------
From: - Thu May 24 10:08:27 2007
X-Mozilla-Status: 0011
X-Mozilla-Status2: 00000000
Return-Path: <mingo at elte.hu>
Received: from mail.boston.redhat.com ([unix socket])	 by mail.boston.redhat.com (Cyrus v2.2.12-Invoca-RPM-2.2.12-8.1.RHEL4) with LMTPA;	 Thu, 24 May 2007 03:46:16 -0400
X-Sieve: CMU Sieve 2.2
Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254])	by mail.boston.redhat.com (8.13.1/8.13.1) with ESMTP id l4O7kGS6012258	for <cebbert at boston.redhat.com>; Thu, 24 May 2007 03:46:16 -0400
Received: from mx1.redhat.com (mx1.redhat.com [172.16.48.31])	by int-mx1.corp.redhat.com (8.13.1/8.13.1) with ESMTP id l4O7kGiL020925	for <cebbert at redhat.com>; Thu, 24 May 2007 03:46:16 -0400
Received: from mx2.mail.elte.hu (mx2.mail.elte.hu [157.181.151.9])	by mx1.redhat.com (8.13.1/8.13.1) with ESMTP id l4O7kDV5026097	for <cebbert at redhat.com>; Thu, 24 May 2007 03:46:14 -0400
Received: from elvis.elte.hu ([157.181.1.14])	by mx2.mail.elte.hu with esmtp (Exim)	id 1Hr80v-00074C-LA	from <mingo at elte.hu>; Thu, 24 May 2007 09:45:41 +0200
Received: by elvis.elte.hu (Postfix, from userid 1004)	id B6B893E2149; Thu, 24 May 2007 09:45:32 +0200 (CEST)
Date: Thu, 24 May 2007 09:45:34 +0200
From: Ingo Molnar <mingo at elte.hu>
To: Chuck Ebbert <cebbert at redhat.com>
Cc: Michal Piotrowski <michal.k.k.piotrowski at gmail.com>,        Thomas Gleixner <tglx at linutronix.de>,        Anant Nitya <kernel at prachanda.info>, linux-kernel at vger.kernel.org,        David Miller <davem at davemloft.net>,        Andrew Morton <akpm at linux-foundation.org>
Subject: Re: [BUG] local_softirq_pending storm
Message-ID: <20070524074534.GA21138 at elte.hu>
References: <200705091942.22920.kernel at prachanda.hub> <200705191525.28400.kernel at prachanda.hub> <1179601868.12981.127.camel at chaos> <200705200253.44992.kernel at prachanda.hub> <1179697388.6570.26.camel at chaos> <6bffcb0e0705221203s1ba21ed3j641e91036859db7d at mail.gmail.com> <20070522201046.GA6113 at elte.hu> <46547345.8000808 at redhat.com>
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
In-Reply-To: <46547345.8000808 at redhat.com>
User-Agent: Mutt/1.4.2.2i
Received-SPF: softfail (mx2: transitioning domain of elte.hu does not designate 157.181.1.14 as permitted sender) client-ip=157.181.1.14; envelope-from=mingo at elte.hu; helo=elvis.elte.hu;
X-ELTE-VirusStatus: clean
X-ELTE-SpamScore: -2.0
X-ELTE-SpamLevel: 
X-ELTE-SpamCheck: no
X-ELTE-SpamVersion: ELTE 2.0
X-ELTE-SpamCheck-Details: score=-2.0 required=5.9 tests=BAYES_00 autolearn=no SpamAssassin version=3.1.7	-2.0 BAYES_00               BODY: Bayesian spam probability is 0 to 1%	[score: 0.0000]
X-RedHat-Spam-Score: 0


* Chuck Ebbert <cebbert at redhat.com> wrote:

> >  	if (need_resched() && system_state == SYSTEM_RUNNING) {
> > -		raw_local_irq_disable();
> > -		_local_bh_enable();
> > -		raw_local_irq_enable();
> > +		local_bh_enable();
> >  		__cond_resched();
> >  		local_bh_disable();
> >  		return 1;
> 
> We may have a problem with that:
> 
>  BUG: warning at kernel/softirq.c:138/local_bh_enable() (Not tainted)
>   [<c042b2ef>] local_bh_enable+0x45/0x92
>   [<c06036b7>] cond_resched_softirq+0x2c/0x42
>   [<c059d5d0>] release_sock+0x54/0xa3
>   [<c05c9428>] tcp_sendmsg+0x91b/0xa0c
>   [<c05e1bb9>] inet_sendmsg+0x3b/0x45
>   [<c059af34>] sock_aio_write+0xf9/0x105
>   [<c0476035>] do_sync_write+0xc7/0x10a
>   [<c0437265>] autoremove_wake_function+0x0/0x35
>   [<c047688e>] vfs_write+0xbc/0x154
>   [<c0476e8c>] sys_write+0x41/0x67
>   [<c0404f70>] syscall_call+0x7/0xb

hm, this place really shouldnt call cond_resched_softirq() with hardirqs 
disabled.

perhaps a buggy ->sk_backlog_rcv() handler disabled interrupts without 
restoring them?

could you enable CONFIG_PROVE_LOCKING and apply the patch below - which 
location is printed as having last disabled hardirqs?

	Ingo

--------------------->
Subject: [patch] softirqs: print out irq-trace events
From: Ingo Molnar <mingo at elte.hu>

some code is fiddling with softirqs but hardirqs are disabled, so try to 
figure out who disabled hardirqs.

Signed-off-by: Ingo Molnar <mingo at elte.hu>
---
 kernel/softirq.c |   10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

Index: linux/kernel/softirq.c
===================================================================
--- linux.orig/kernel/softirq.c
+++ linux/kernel/softirq.c
@@ -135,7 +135,15 @@ void local_bh_enable(void)
 
 	WARN_ON_ONCE(in_irq());
 #endif
-	WARN_ON_ONCE(irqs_disabled());
+	if (irqs_disabled()) {
+		static int once = 1;
+
+		if (once) {
+			once = 0;
+			print_irqtrace_events(current);
+			WARN_ON(1);
+		}
+	}
 
 #ifdef CONFIG_TRACE_IRQFLAGS
 	local_irq_save(flags);


linux-2.6-suspend-ordering.patch:

--- NEW FILE linux-2.6-suspend-ordering.patch ---
>From davej  Wed May 16 19:22:13 2007
Return-Path: <cebbert at redhat.com>
X-Spam-Checker-Version: SpamAssassin 3.1.8 (2007-02-13) on
	gelk.kernelslacker.org
X-Spam-Level: 
X-Spam-Status: No, score=-2.6 required=5.0 tests=AWL,BAYES_00,
	UNPARSEABLE_RELAY autolearn=ham version=3.1.8
Received: from pobox.devel.redhat.com [10.11.255.8]
	by gelk.kernelslacker.org with IMAP (fetchmail-6.3.6)
	for <davej at localhost> (single-drop); Wed, 16 May 2007 19:22:13 -0400 (EDT)
Received: from pobox.devel.redhat.com ([unix socket])
	 by pobox.devel.redhat.com (Cyrus v2.2.12-Invoca-RPM-2.2.12-8.1.RHEL4) with LMTPA;
	 Wed, 16 May 2007 19:21:37 -0400
X-Sieve: CMU Sieve 2.2
Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254])
	by pobox.devel.redhat.com (8.13.1/8.13.1) with ESMTP id l4GNLbcA029277
	for <davej at pobox.devel.redhat.com>; Wed, 16 May 2007 19:21:37 -0400
Received: from mail.boston.redhat.com (mail.boston.redhat.com [172.16.76.12])
	by int-mx1.corp.redhat.com (8.13.1/8.13.1) with ESMTP id l4GNLaBd019679
	for <davej at int-mx1.corp.redhat.com>; Wed, 16 May 2007 19:21:37 -0400
Received: from [172.16.83.145] (dhcp83-145.boston.redhat.com [172.16.83.145])
	by mail.boston.redhat.com (8.13.1/8.13.1) with ESMTP id l4GNLaQX003318
	for <davej at redhat.com>; Wed, 16 May 2007 19:21:36 -0400
Message-ID: <464B9200.4020608 at redhat.com>
Date: Wed, 16 May 2007 19:21:36 -0400
From: Chuck Ebbert <cebbert at redhat.com>
Organization: Red Hat
User-Agent: Thunderbird 1.5.0.10 (X11/20070302)
MIME-Version: 1.0
To: Dave Jones <davej at redhat.com>
Subject: [Fwd: Fix ACPI suspend / device suspend ordering problem]
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Status: RO
X-Status: A
Content-Length: 5438
Lines: 113

Critical?

-------- Original Message --------
From: - Wed May 16 19:07:30 2007
X-Mozilla-Status: 0001
X-Mozilla-Status2: 00000000
Return-Path: <git-commits-head-owner at vger.kernel.org>
Received: from mail.boston.redhat.com ([unix socket])	 by mail.boston.redhat.com (Cyrus v2.2.12-Invoca-RPM-2.2.12-8.1.RHEL4) with LMTPA;	 Wed, 16 May 2007 19:06:49 -0400
X-Sieve: CMU Sieve 2.2
Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254])	by mail.boston.redhat.com (8.13.1/8.13.1) with ESMTP id l4GN6nq7000976;	Wed, 16 May 2007 19:06:49 -0400
Received: from mx1.redhat.com (mx1.redhat.com [172.16.48.31])	by int-mx1.corp.redhat.com (8.13.1/8.13.1) with ESMTP id l4GN6nqE015463;	Wed, 16 May 2007 19:06:49 -0400
Received: from vger.kernel.org (vger.kernel.org [209.132.176.167])	by mx1.redhat.com (8.13.1/8.13.1) with ESMTP id l4GMoCil002002;	Wed, 16 May 2007 19:06:47 -0400
Received: (majordomo at vger.kernel.org) by vger.kernel.org via listexpand	id S1757466AbXEPW7G (ORCPT <rfc822;cebbert at redhat.com> + 6 others);	Wed, 16 May 2007 18:59:06 -0400
Received: (majordomo at vger.kernel.org) by vger.kernel.org id S1758932AbXEPW7G	(ORCPT <rfc822;git-commits-head-outgoing>);	Wed, 16 May 2007 18:59:06 -0400
Received: from hera.kernel.org ([140.211.167.34]:42826 "EHLO hera.kernel.org"	rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP	id S1757466AbXEPW7F (ORCPT	<rfc822;git-commits-head at vger.kernel.org>);	Wed, 16 May 2007 18:59:05 -0400
Received: from hera.kernel.org (IDENT:U2FsdGVkX1/F89m4CLkIIOh66EDb7VKNkI7V6uasSZE at localhost [127.0.0.1])	by hera.kernel.org (8.13.8/8.13.7) with ESMTP id l4GMx3Zd012529	(version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO)	for <git-commits-head at vger.kernel.org>; Wed, 16 May 2007 22:59:03 GMT
Received: (from dwmw2 at localhost)	by hera.kernel.org (8.13.8/8.13.1/Submit) id l4GMx2rV012500	for git-commits-head at vger.kernel.org; Wed, 16 May 2007 22:59:02 GMT
Date: Wed, 16 May 2007 22:59:02 GMT
Message-Id: <200705162259.l4GMx2rV012500 at hera.kernel.org>
From: Linux Kernel Mailing List <linux-kernel at vger.kernel.org>
To: git-commits-head at vger.kernel.org
Subject: Fix ACPI suspend / device suspend ordering problem
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
X-Git-Commit: 52ade9b3b97fd3bea42842a056fe0786c28d0555
X-Git-Parent: 7b104bcb8e460e45a1aebe3da9b86aacdb4cab12
X-Spam-Status: No, score=-4.3 required=5.0 tests=ALL_TRUSTED,AWL,BAYES_00	autolearn=ham version=3.1.8
X-Spam-Checker-Version: SpamAssassin 3.1.8 (2007-02-13) on hera.kernel.org
Sender: git-commits-head-owner at vger.kernel.org
Precedence: bulk
X-Mailing-List: git-commits-head at vger.kernel.org
X-RedHat-Spam-Score: 0

Gitweb:     http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=52ade9b3b97fd3bea42842a056fe0786c28d0555
Commit:     52ade9b3b97fd3bea42842a056fe0786c28d0555
Parent:     7b104bcb8e460e45a1aebe3da9b86aacdb4cab12
Author:     Linus Torvalds <torvalds at woody.linux-foundation.org>
AuthorDate: Wed May 16 15:28:14 2007 -0700
Committer:  Linus Torvalds <torvalds at woody.linux-foundation.org>
CommitDate: Wed May 16 15:33:19 2007 -0700

    Fix ACPI suspend / device suspend ordering problem
    
    In commit e3c7db621bed4afb8e231cb005057f2feb5db557 we fixed the resume
    ordering, so that the ACPI low-level resume code was called before the
    actual driver resume was called. However, that broke the nesting logic
    of suspend and resume, and we continued to suspend the devices _after_
    we the ACPI device suspend code was called.
    
    That resulted in us saving PCI state for devices that had already been
    changed by ACPI, and in some cases disabled entirely (causing the PCI
    save_state to be all-ones).  Which in turn caused the wrong state to be
    written back on resume.
    
    This moves the ACPI device suspend to after the device model per-device
    suspend() calls. This fixes the bogus state save.
    
    Thanks to Lukáš Hejtmánek for testing.
    
    Acked-by: Lukas Hejtmanek <xhejtman at ics.muni.cz>
    Acked-by: Rafael J. Wysocki <rjw at sisk.pl>
    Cc: Len Brown <len.brown at intel.com>
    Cc: Pavel Machek <pavel at ucw.cz>
    Cc: Andrew Morton <akpm at linux-foundation.org>
    Cc: Greg KH <greg at kroah.com>
    Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
---
 kernel/power/main.c |   15 ++++++++-------
 1 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/kernel/power/main.c b/kernel/power/main.c
index 40d56a3..b98b80c 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -97,25 +97,26 @@ static int suspend_prepare(suspend_state_t state)
 		}
 	}
 
-	if (pm_ops->prepare) {
-		if ((error = pm_ops->prepare(state)))
-			goto Thaw;
-	}
-
 	suspend_console();
 	error = device_suspend(PMSG_SUSPEND);
 	if (error) {
 		printk(KERN_ERR "Some devices failed to suspend\n");
-		goto Resume_devices;
+		goto Resume_console;
 	}
+	if (pm_ops->prepare) {
+		if ((error = pm_ops->prepare(state)))
+			goto Resume_devices;
+	}
+
 	error = disable_nonboot_cpus();
 	if (!error)
 		return 0;
 
 	enable_nonboot_cpus();
- Resume_devices:
 	pm_finish(state);
+ Resume_devices:
 	device_resume();
+ Resume_console:
 	resume_console();
  Thaw:
 	thaw_processes();
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


linux-2.6-sysfs-inode-allocator-oops.patch:

--- NEW FILE linux-2.6-sysfs-inode-allocator-oops.patch ---
>From davej  Tue May 22 12:17:24 2007
Return-Path: <sandeen at redhat.com>
Received: from pobox.devel.redhat.com [10.11.255.8]
	by gelk.kernelslacker.org with IMAP (fetchmail-6.3.6)
	for <davej at localhost> (single-drop); Tue, 22 May 2007 12:17:24 -0400 (EDT)
Received: from pobox.devel.redhat.com ([unix socket])
	 by pobox.devel.redhat.com (Cyrus v2.2.12-Invoca-RPM-2.2.12-8.1.RHEL4) with LMTPA;
	 Tue, 22 May 2007 12:13:29 -0400
X-Sieve: CMU Sieve 2.2
Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254])
	by pobox.devel.redhat.com (8.13.1/8.13.1) with ESMTP id l4MGDTbW017176
	for <davej at pobox.devel.redhat.com>; Tue, 22 May 2007 12:13:29 -0400
Received: from pobox-2.corp.redhat.com (pobox-2.corp.redhat.com [10.11.255.15])
	by int-mx1.corp.redhat.com (8.13.1/8.13.1) with ESMTP id l4MGDSWd011185
	for <davej at int-mx1.corp.redhat.com>; Tue, 22 May 2007 12:13:28 -0400
Received: from [10.15.80.10] (neon.msp.redhat.com [10.15.80.10])
	by pobox-2.corp.redhat.com (8.13.1/8.13.1) with ESMTP id l4MGDRKc021458
	for <davej at redhat.com>; Tue, 22 May 2007 12:13:27 -0400
Resent-From: Eric Sandeen <sandeen at redhat.com>
Resent-To: Dave Jones <davej at redhat.com>
Resent-Date: Tue, 22 May 2007 11:13:16 -0500
Resent-Message-Id: <4653169C.3060803 at redhat.com>
Resent-User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.8.0.10) Gecko/20070302 Fedora/1.5.0.10-1.fc6 pango-text Thunderbird/1.5.0.10
Received: from pobox-2.corp.redhat.com ([unix socket])
	 by pobox-2.corp.redhat.com (Cyrus v2.2.12-Invoca-RPM-2.2.12-8.1.RHEL4) with LMTPA;
	 Mon, 21 May 2007 22:32:53 -0400
X-Sieve: CMU Sieve 2.2
Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254])
	by pobox-2.corp.redhat.com (8.13.1/8.13.1) with ESMTP id l4M2Wr9W026945
	for <esandeen at pobox-2.corp.redhat.com>; Mon, 21 May 2007 22:32:53 -0400
Received: from mx1.redhat.com (mx1.redhat.com [172.16.48.31])
	by int-mx1.corp.redhat.com (8.13.1/8.13.1) with ESMTP id l4M2WqlW016766
	for <sandeen at redhat.com>; Mon, 21 May 2007 22:32:52 -0400
Received: from sandeen.net (sandeen.net [209.173.210.139])
	by mx1.redhat.com (8.13.1/8.13.1) with ESMTP id l4M2WmPs016891
	for <sandeen at redhat.com>; Mon, 21 May 2007 22:32:48 -0400
Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4])
	(using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))
	(No client certificate requested)
	by sandeen.net (Postfix) with ESMTP id 4EC1818077E83;
	Mon, 21 May 2007 21:32:42 -0500 (CDT)
Message-ID: <46525648.8050807 at sandeen.net>
Date: Mon, 21 May 2007 21:32:40 -0500
From: Eric Sandeen <sandeen at sandeen.net>
User-Agent: Thunderbird 2.0.0.0 (Macintosh/20070326)
MIME-Version: 1.0
To: Eric Sandeen <sandeen at redhat.com>
CC: Andrew Morton <akpm at linux-foundation.org>,
        Linux Kernel Mailing List <linux-kernel at vger.kernel.org>,
        Tejun Heo <htejun at gmail.com>, Maneesh Soni <maneesh at in.ibm.com>,
        stable at kernel.org
Subject: Re: [stable] [PATCH] - store sysfs inode nrs in s_ino to avoid readdir
 oopses
References: <4651E0C9.3080609 at redhat.com> <20070521153935.b549db8f.akpm at linux-foundation.org> <465236EF.40102 at redhat.com>
In-Reply-To: <465236EF.40102 at redhat.com>
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
X-RedHat-Spam-Score: -1.44 
Status: RO
Content-Length: 3622
Lines: 107

(2nd try, better(?) changelog, quilt refreshed(!) patch)

--

Backport of
ftp://ftp.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.22-rc1/2.6.22-rc1-mm1/broken-out/gregkh-driver-sysfs-allocate-inode-number-using-ida.patch

For regular files in sysfs, sysfs_readdir wants to traverse
sysfs_dirent->s_dentry->d_inode->i_ino to get to the inode number.
But, the dentry can be reclaimed under memory pressure, and there
is no synchronization with readdir.  This patch follows Tejun's
scheme of allocating and storing an inode number in the new s_ino
member of a sysfs_dirent, when dirents are created, and retrieving 
it from there for readdir, so that the pointer chain doesn't have 
to be traversed.

Tejun's upstream patch uses a new-ish "ida" allocator which brings along
some extra complexity; this -stable patch has a brain-dead incrementing
counter which does not guarantee uniqueness, but because sysfs doesn't 
hash inodes as iunique expects, uniqueness wasn't guaranteed today anyway.

Signed-off-by: Eric Sandeen <sandeen at redhat.com>

Index: linux-2.6.21/fs/sysfs/dir.c
===================================================================
--- linux-2.6.21.orig/fs/sysfs/dir.c
+++ linux-2.6.21/fs/sysfs/dir.c
@@ -30,6 +30,14 @@ static struct dentry_operations sysfs_de
 	.d_iput		= sysfs_d_iput,
 };
 
+static unsigned int sysfs_inode_counter;
+ino_t sysfs_get_inum(void)
+{
+	if (unlikely(sysfs_inode_counter < 3))
+		sysfs_inode_counter = 3;
+	return sysfs_inode_counter++;
+}
+
 /*
  * Allocates a new sysfs_dirent and links it to the parent sysfs_dirent
  */
@@ -41,6 +49,7 @@ static struct sysfs_dirent * __sysfs_new
 	if (!sd)
 		return NULL;
 
+	sd->s_ino = sysfs_get_inum();
 	atomic_set(&sd->s_count, 1);
 	atomic_set(&sd->s_event, 1);
 	INIT_LIST_HEAD(&sd->s_children);
@@ -509,7 +518,7 @@ static int sysfs_readdir(struct file * f
 
 	switch (i) {
 		case 0:
-			ino = dentry->d_inode->i_ino;
+			ino = parent_sd->s_ino;
 			if (filldir(dirent, ".", 1, i, ino, DT_DIR) < 0)
 				break;
 			filp->f_pos++;
@@ -538,10 +547,7 @@ static int sysfs_readdir(struct file * f
 
 				name = sysfs_get_name(next);
 				len = strlen(name);
-				if (next->s_dentry)
-					ino = next->s_dentry->d_inode->i_ino;
-				else
-					ino = iunique(sysfs_sb, 2);
+				ino = next->s_ino;
 
 				if (filldir(dirent, name, len, filp->f_pos, ino,
 						 dt_type(next)) < 0)
Index: linux-2.6.21/fs/sysfs/inode.c
===================================================================
--- linux-2.6.21.orig/fs/sysfs/inode.c
+++ linux-2.6.21/fs/sysfs/inode.c
@@ -140,6 +140,7 @@ struct inode * sysfs_new_inode(mode_t mo
 		inode->i_mapping->a_ops = &sysfs_aops;
 		inode->i_mapping->backing_dev_info = &sysfs_backing_dev_info;
 		inode->i_op = &sysfs_inode_operations;
+		inode->i_ino = sd->s_ino;
 		lockdep_set_class(&inode->i_mutex, &sysfs_inode_imutex_key);
 
 		if (sd->s_iattr) {
Index: linux-2.6.21/fs/sysfs/mount.c
===================================================================
--- linux-2.6.21.orig/fs/sysfs/mount.c
+++ linux-2.6.21/fs/sysfs/mount.c
@@ -33,6 +33,7 @@ static struct sysfs_dirent sysfs_root = 
 	.s_element	= NULL,
 	.s_type		= SYSFS_ROOT,
 	.s_iattr	= NULL,
+	.s_ino		= 1,
 };
 
 static void sysfs_clear_inode(struct inode *inode)
Index: linux-2.6.21/fs/sysfs/sysfs.h
===================================================================
--- linux-2.6.21.orig/fs/sysfs/sysfs.h
+++ linux-2.6.21/fs/sysfs/sysfs.h
@@ -5,6 +5,7 @@ struct sysfs_dirent {
 	void 			* s_element;
 	int			s_type;
 	umode_t			s_mode;
+	ino_t			s_ino;
 	struct dentry		* s_dentry;
 	struct iattr		* s_iattr;
 	atomic_t		s_event;


linux-2.6-udf-2.6.22-rc2-1-udf_data_corruption.patch:

--- NEW FILE linux-2.6-udf-2.6.22-rc2-1-udf_data_corruption.patch ---
update_next_aext() could possibly rewrite values in elen and eloc, possibly
leading to data corruption when rewriting a file. Use temporary variables
instead. Also advance cur_epos as it can also point to an indirect extent
pointer.

Signed-off-by: Jan Kara <jack at suse.cz>

diff -rupX /home/jack/.kerndiffexclude linux-2.6.22-rc2/fs/udf/inode.c linux-2.6.22-rc2-1-udf_data_corruption/fs/udf/inode.c
--- linux-2.6.22-rc2/fs/udf/inode.c	2007-05-24 18:00:05.000000000 +0200
+++ linux-2.6.22-rc2-1-udf_data_corruption/fs/udf/inode.c	2007-05-24 18:16:36.000000000 +0200
@@ -460,8 +460,8 @@ static struct buffer_head * inode_getblk
 	kernel_long_ad laarr[EXTENT_MERGE_SIZE];
 	struct extent_position prev_epos, cur_epos, next_epos;
 	int count = 0, startnum = 0, endnum = 0;
-	uint32_t elen = 0;
-	kernel_lb_addr eloc;
+	uint32_t elen = 0, tmpelen;
+	kernel_lb_addr eloc, tmpeloc;
 	int c = 1;
 	loff_t lbcount = 0, b_off = 0;
 	uint32_t newblocknum, newblock;
@@ -520,8 +520,12 @@ static struct buffer_head * inode_getblk
 
 	b_off -= lbcount;
 	offset = b_off >> inode->i_sb->s_blocksize_bits;
-	/* Move into indirect extent if we are at a pointer to it */
-	udf_next_aext(inode, &prev_epos, &eloc, &elen, 0);
+	/*
+	 * Move prev_epos and cur_epos into indirect extent if we are at
+	 * the pointer to it
+	 */
+	udf_next_aext(inode, &prev_epos, &tmpeloc, &tmpelen, 0);
+	udf_next_aext(inode, &cur_epos, &tmpeloc, &tmpelen, 0);
 
 	/* if the extent is allocated and recorded, return the block
        if the extent is not a multiple of the blocksize, round up */

linux-2.6-udf-2.6.22-rc4-1-udf_block_leak.patch:

--- NEW FILE linux-2.6-udf-2.6.22-rc4-1-udf_block_leak.patch ---
We have to take care that when we call udf_discard_prealloc() from udf_clear_inode()
we have to write inode ourselves afterwards (otherwise, some changes might be lost
leading to leakage of blocks, use of free blocks or improperly aligned extents).
Also udf_discard_prealloc() does two different things - it removes preallocated
blocks and truncates the last extent to exactly match i_size. We move the latter
functionality to udf_truncate_tail_extent(), call udf_discard_prealloc() when last
reference to a file is dropped and call udf_truncate_tail_extent() when inode
is being removed from inode cache (udf_clear_inode() call). We cannot call
udf_truncate_tail_extent() earlier as subsequent open+write would find the last
block of the file mapped and happily write to the end of it, although the last
extent says it's shorter.

Signed-off-by: Jan Kara <jack at suse.cz>

diff -rupX /home/jack/.kerndiffexclude linux-2.6.22-rc2-1-udf_data_corruption/fs/udf/inode.c linux-2.6.22-rc2-2-udf_block_leak/fs/udf/inode.c
--- linux-2.6.22-rc2-1-udf_data_corruption/fs/udf/inode.c	2007-05-24 18:16:36.000000000 +0200
+++ linux-2.6.22-rc2-2-udf_block_leak/fs/udf/inode.c	2007-06-07 16:38:37.000000000 +0200
@@ -100,14 +100,23 @@ no_delete:
 	clear_inode(inode);
 }
 
+/*
+ * If we are going to release inode from memory, we discard preallocation and
+ * truncate last inode extent to proper length. We could use drop_inode() but it's
+ * called under inode_lock and thus we cannot mark inode dirty there. We use
+ * clear_inode() but we have to make sure to write inode as it's not written
+ * automatically.
+ */
 void udf_clear_inode(struct inode *inode)
 {
 	if (!(inode->i_sb->s_flags & MS_RDONLY)) {
 		lock_kernel();
+		/* Discard preallocation for directories, symlinks, etc. */
 		udf_discard_prealloc(inode);
+		udf_truncate_tail_extent(inode);
 		unlock_kernel();
+		write_inode_now(inode, 1);
 	}
-
 	kfree(UDF_I_DATA(inode));
 	UDF_I_DATA(inode) = NULL;
 }
diff -rupX /home/jack/.kerndiffexclude linux-2.6.22-rc2-1-udf_data_corruption/fs/udf/truncate.c linux-2.6.22-rc2-2-udf_block_leak/fs/udf/truncate.c
--- linux-2.6.22-rc2-1-udf_data_corruption/fs/udf/truncate.c	2007-05-24 18:00:05.000000000 +0200
+++ linux-2.6.22-rc2-2-udf_block_leak/fs/udf/truncate.c	2007-06-06 14:33:29.000000000 +0200
@@ -61,7 +61,11 @@ static void extent_trunc(struct inode * 
 	}
 }
 
-void udf_discard_prealloc(struct inode * inode)
+/*
+ * Truncate the last extent to match i_size. This function assumes
+ * that preallocation extent is already truncated.
+ */
+void udf_truncate_tail_extent(struct inode *inode)
 {
 	struct extent_position epos = { NULL, 0, {0, 0}};
 	kernel_lb_addr eloc;
@@ -71,7 +75,10 @@ void udf_discard_prealloc(struct inode *
 	int adsize;
 
 	if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB ||
-		inode->i_size == UDF_I_LENEXTENTS(inode))
+	    inode->i_size == UDF_I_LENEXTENTS(inode))
+		return;
+	/* Are we going to delete the file anyway? */
+	if (inode->i_nlink == 0)
 		return;
 
 	if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT)
@@ -79,25 +86,69 @@ void udf_discard_prealloc(struct inode *
 	else if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_LONG)
 		adsize = sizeof(long_ad);
 	else
-		adsize = 0;
-
-	epos.block = UDF_I_LOCATION(inode);
+		BUG();
 
 	/* Find the last extent in the file */
 	while ((netype = udf_next_aext(inode, &epos, &eloc, &elen, 1)) != -1)
 	{
 		etype = netype;
 		lbcount += elen;
-		if (lbcount > inode->i_size && lbcount - elen < inode->i_size)
-		{
-			WARN_ON(lbcount - inode->i_size >= inode->i_sb->s_blocksize);
+		if (lbcount > inode->i_size) {
+			if (lbcount - inode->i_size >= inode->i_sb->s_blocksize)
+				printk(KERN_WARNING
+				       "udf_truncate_tail_extent(): Too long "
+				       "extent after EOF in inode %u: i_size: "
+				       "%Ld lbcount: %Ld extent %u+%u\n",
+				       (unsigned)inode->i_ino,
+				       (long long)inode->i_size,
+				       (long long)lbcount,
+				       (unsigned)eloc.logicalBlockNum,
+				       (unsigned)elen);
 			nelen = elen - (lbcount - inode->i_size);
 			epos.offset -= adsize;
 			extent_trunc(inode, &epos, eloc, etype, elen, nelen);
 			epos.offset += adsize;
-			lbcount = inode->i_size;
+			if (udf_next_aext(inode, &epos, &eloc, &elen, 1) != -1)
+				printk(KERN_ERR "udf_truncate_tail_extent(): "
+				       "Extent after EOF in inode %u.\n",
+				       (unsigned)inode->i_ino);
+			break;
 		}
 	}
+	/* This inode entry is in-memory only and thus we don't have to mark
+	 * the inode dirty */
+	UDF_I_LENEXTENTS(inode) = inode->i_size;
+	brelse(epos.bh);
+}
+
+void udf_discard_prealloc(struct inode * inode)
+{
+	struct extent_position epos = { NULL, 0, {0, 0}};
+	kernel_lb_addr eloc;
+	uint32_t elen;
+	uint64_t lbcount = 0;
+	int8_t etype = -1, netype;
+	int adsize;
+
+	if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB ||
+		inode->i_size == UDF_I_LENEXTENTS(inode))
+		return;
+
+	if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_SHORT)
+		adsize = sizeof(short_ad); 
+	else if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_LONG)
+		adsize = sizeof(long_ad);
+	else
+		adsize = 0;
+
+	epos.block = UDF_I_LOCATION(inode);
+
+	/* Find the last extent in the file */
+	while ((netype = udf_next_aext(inode, &epos, &eloc, &elen, 1)) != -1)
+	{
+		etype = netype;
+		lbcount += elen;
+	}
 	if (etype == (EXT_NOT_RECORDED_ALLOCATED >> 30)) {
 		epos.offset -= adsize;
 		lbcount -= elen;
@@ -118,9 +169,9 @@ void udf_discard_prealloc(struct inode *
 			mark_buffer_dirty_inode(epos.bh, inode);
 		}
 	}
+	/* This inode entry is in-memory only and thus we don't have to mark
+	 * the inode dirty */
 	UDF_I_LENEXTENTS(inode) = lbcount;
-
-	WARN_ON(lbcount != inode->i_size);
 	brelse(epos.bh);
 }
 
diff -rupX /home/jack/.kerndiffexclude linux-2.6.22-rc2-1-udf_data_corruption/fs/udf/udfdecl.h linux-2.6.22-rc2-2-udf_block_leak/fs/udf/udfdecl.h
--- linux-2.6.22-rc2-1-udf_data_corruption/fs/udf/udfdecl.h	2007-05-24 18:00:05.000000000 +0200
+++ linux-2.6.22-rc2-2-udf_block_leak/fs/udf/udfdecl.h	2007-06-07 16:32:54.000000000 +0200
@@ -146,6 +146,7 @@ extern void udf_free_inode(struct inode 
 extern struct inode * udf_new_inode (struct inode *, int, int *);
 
 /* truncate.c */
+extern void udf_truncate_tail_extent(struct inode *);
 extern void udf_discard_prealloc(struct inode *);
 extern void udf_truncate_extents(struct inode *);
 

linux-2.6-usb-autosuspend-default-disable.patch:

--- NEW FILE linux-2.6-usb-autosuspend-default-disable.patch ---
Default disable USB autosuspend.

---
 drivers/usb/core/usb.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- linux-2.6.21.noarch.orig/drivers/usb/core/usb.c
+++ linux-2.6.21.noarch/drivers/usb/core/usb.c
@@ -52,7 +52,7 @@ static int nousb;	/* Disable USB when bu
 struct workqueue_struct *ksuspend_usb_wq;	/* For autosuspend */
 
 #ifdef	CONFIG_USB_SUSPEND
-static int usb_autosuspend_delay = 2;		/* Default delay value,
+static int usb_autosuspend_delay = 0;		/* Default delay value,
 						 * in seconds */
 module_param_named(autosuspend, usb_autosuspend_delay, uint, 0644);
 MODULE_PARM_DESC(autosuspend, "default autosuspend delay");

linux-2.6-usb-storage-initialize-huawei-e220-properly.patch:

--- NEW FILE linux-2.6-usb-storage-initialize-huawei-e220-properly.patch ---
>From johann.wilhelm at student.tugraz.at  Sun Sep  9 08:19:38 2007
From: Johann Wilhelm <johann.wilhelm at student.tugraz.at>
Date: Wed, 05 Sep 2007 13:49:29 +0200
Subject: USB: usb-storage: Initialize Huawei E220 properly
To: linux-usb-devel at lists.sourceforge.net
Cc: greg at kroah.com, drussell at redhat.com
Message-ID: <20070905134929.5fv51ji2v40gkw0c at webmail.tugraz.at>
Content-Disposition: inline

bz 253096

From: Johann Wilhelm <johann.wilhelm at student.tugraz.at>

This is a reworked version of this patch:
http://www.mail-archive.com/linux-usb-devel%40lists.sourceforge.net/msg55094/activate_huawei_dev.patch

That properly initializes the HUAWEI E220 devices into multi-port mode.

Signed-off-by: Johann Wilhelm <johann.wilhelm at student.tugraz.at>
Signed-off-by: Greg Kroah-Hartman <gregkh at suse.de>

---
 drivers/usb/storage/initializers.c |   14 ++++++++++++++
 drivers/usb/storage/initializers.h |    3 +++
 drivers/usb/storage/unusual_devs.h |   11 +++++++++++
 3 files changed, 28 insertions(+)

--- linux-2.6.22.noarch.orig/drivers/usb/storage/initializers.c
+++ linux-2.6.22.noarch/drivers/usb/storage/initializers.c
@@ -90,3 +90,17 @@ int usb_stor_ucr61s2b_init(struct us_dat
 
 	return (res ? -1 : 0);
 }
+
+/* This places the HUAWEI E220 devices in multi-port mode */
+int usb_stor_huawei_e220_init(struct us_data *us)
+{
+	int result;
+
+	us->iobuf[0] = 0x1;
+	result = usb_stor_control_msg(us, us->send_ctrl_pipe,
+				      USB_REQ_SET_FEATURE,
+				      USB_TYPE_STANDARD | USB_RECIP_DEVICE,
+				      0x01, 0x0, us->iobuf, 0x1, 1000);
+	US_DEBUGP("usb_control_msg performing result is %d\n", result);
+	return (result ? 0 : -1);
+}
--- linux-2.6.22.noarch.orig/drivers/usb/storage/initializers.h
+++ linux-2.6.22.noarch/drivers/usb/storage/initializers.h
@@ -47,3 +47,6 @@ int usb_stor_euscsi_init(struct us_data 
 /* This function is required to activate all four slots on the UCR-61S2B
  * flash reader */
 int usb_stor_ucr61s2b_init(struct us_data *us);
+
+/* This places the HUAWEI E220 devices in multi-port mode */
+int usb_stor_huawei_e220_init(struct us_data *us);
--- linux-2.6.22.noarch.orig/drivers/usb/storage/unusual_devs.h
+++ linux-2.6.22.noarch/drivers/usb/storage/unusual_devs.h
@@ -1394,6 +1394,17 @@ UNUSUAL_DEV(  0x1210, 0x0003, 0x0100, 0x
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		US_FL_IGNORE_RESIDUE ),
 
+/* Reported by fangxiaozhi <fangxiaozhi60675 at huawei.com>
+ * and by linlei <linlei83 at huawei.com>
+ * Patch reworked by Johann Wilhelm <johann.wilhelm at student.tugraz.at>
+ * This brings the HUAWEI E220 devices into multi-port mode
+ */
+UNUSUAL_DEV( 0x12d1, 0x1003, 0x0000, 0x0000,
+		"HUAWEI MOBILE",
+		"Mass Storage",
+		US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+		0),
+
 /* Reported by Vilius Bilinkevicius <vilisas AT xxx DOT lt) */
 UNUSUAL_DEV(  0x132b, 0x000b, 0x0001, 0x0001,
 		"Minolta",

linux-2.6-usb-suspend-classes.patch:

--- NEW FILE linux-2.6-usb-suspend-classes.patch ---
>From davej  Thu Aug  2 20:00:05 2007
Return-Path: <linux-usb-devel-bounces at lists.sourceforge.net>
X-Spam-Checker-Version: SpamAssassin 3.2.2 (2007-07-23) on
	gelk.kernelslacker.org
X-Spam-Level: 
X-Spam-Status: No, score=-6.4 required=5.0 tests=AWL,BAYES_00,
	RCVD_IN_DNSWL_MED,UNPARSEABLE_RELAY autolearn=ham version=3.2.2
Received: from pobox.devel.redhat.com [10.11.255.8]
	by gelk.kernelslacker.org with IMAP (fetchmail-6.3.7)
	for <davej at localhost> (single-drop); Thu, 02 Aug 2007 20:00:05 -0400 (EDT)
Received: from pobox.devel.redhat.com ([unix socket])
	 by pobox.devel.redhat.com (Cyrus v2.2.12-Invoca-RPM-2.2.12-8.1.RHEL4) with LMTPA;
	 Thu, 02 Aug 2007 19:56:41 -0400
X-Sieve: CMU Sieve 2.2
Received: from int-mx2.corp.redhat.com (int-mx2.corp.redhat.com [172.16.27.26])
	by pobox.devel.redhat.com (8.13.1/8.13.1) with ESMTP id l72NueHI010629;
	Thu, 2 Aug 2007 19:56:40 -0400
Received: from mx2.redhat.com (mx2.redhat.com [10.255.15.25])
	by int-mx2.corp.redhat.com (8.13.1/8.13.1) with ESMTP id l72NudHe028741;
	Thu, 2 Aug 2007 19:56:40 -0400
Received: from lists-outbound.sourceforge.net (lists-outbound.sourceforge.net [66.35.250.225])
	by mx2.redhat.com (8.13.1/8.13.1) with ESMTP id l72NuXOK013200;
	Thu, 2 Aug 2007 19:56:33 -0400
Received: from sc8-sf-list1-new.sourceforge.net (sc8-sf-list1-new-b.sourceforge.net [10.3.1.93])
	by sc8-sf-spam2.sourceforge.net (Postfix) with ESMTP
	id 8FE6C12AED; Thu,  2 Aug 2007 16:56:27 -0700 (PDT)
Received: from sc8-sf-mx1-b.sourceforge.net ([10.3.1.91]
	helo=mail.sourceforge.net)
	by sc8-sf-list1-new.sourceforge.net with esmtp (Exim 4.43)
	id 1IGkWn-0004vJ-BF for linux-usb-devel at lists.sourceforge.net;
	Thu, 02 Aug 2007 16:56:25 -0700
Received: from [78.32.9.130] (helo=vavatch.codon.org.uk)
	by mail.sourceforge.net with esmtps (TLSv1:AES256-SHA:256)
	(Exim 4.44) id 1IGkWn-0003tG-03
	for linux-usb-devel at lists.sourceforge.net;
	Thu, 02 Aug 2007 16:56:25 -0700
Received: from mjg59 by vavatch.codon.org.uk with local (Exim 4.62)
	(envelope-from <mjg59 at codon.org.uk>)
	id 1IGkWb-0002V5-Bi; Fri, 03 Aug 2007 00:56:16 +0100
Date: Fri, 3 Aug 2007 00:56:13 +0100
From: Matthew Garrett <mjg59 at srcf.ucam.org>
To: linux-usb-devel at lists.sourceforge.net
Message-ID: <20070802235613.GA9487 at srcf.ucam.org>
MIME-Version: 1.0
Content-Disposition: inline
User-Agent: Mutt/1.5.12-2006-07-14
X-SA-Exim-Connect-IP: <locally generated>
X-SA-Exim-Mail-From: mjg59 at codon.org.uk
X-SA-Exim-Version: 4.2.1 (built Tue, 20 Jun 2006 01:35:45 +0000)
X-SA-Exim-Scanned: Yes (on vavatch.codon.org.uk)
Cc: amitk at ubuntu.com, gregkh at suse.de, linux-kernel at vger.kernel.org
Subject: [linux-usb-devel] [PATCH] USB: Only enable autosuspend by default
	on certain device classes
X-BeenThere: linux-usb-devel at lists.sourceforge.net
X-Mailman-Version: 2.1.8
Precedence: list
List-Id: <linux-usb-devel.lists.sourceforge.net>
List-Unsubscribe: <https://lists.sourceforge.net/lists/listinfo/linux-usb-devel>, 
	<mailto:linux-usb-devel-request at lists.sourceforge.net?subject=unsubscribe>
List-Archive: <http://sourceforge.net/mailarchive/forum.php?forum_name=linux-usb-devel>
List-Post: <mailto:linux-usb-devel at lists.sourceforge.net>
List-Help: <mailto:linux-usb-devel-request at lists.sourceforge.net?subject=help>
List-Subscribe: <https://lists.sourceforge.net/lists/listinfo/linux-usb-devel>, 
	<mailto:linux-usb-devel-request at lists.sourceforge.net?subject=subscribe>
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
Sender: linux-usb-devel-bounces at lists.sourceforge.net
Errors-To: linux-usb-devel-bounces at lists.sourceforge.net
X-RedHat-Spam-Score: 0.276 
Status: RO
Content-Length: 1912
Lines: 54

We're seeing a large number of problems with devices not appreciating 
USB autosuspend, especially printers and scanners. According to 
http://www.microsoft.com/whdc/system/bus/USB/USBFAQ_intro.mspx only a 
subset of drivers support it in Windows XP, meaning that most devices 
are probably untested in this situation. This patch alters the behaviour 
to match that of Windows. Userspace can still whitelist devices as 
appropriate, and the set of classes supporting autosuspend probably 
covers pretty much every driver likely to be found on any portable 
device.

Signed-off-by: Matthew Garrett <mjg59 at srcf.ucam.org>

---

diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index caaa46f..12ba789 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1278,6 +1278,22 @@ int usb_new_device(struct usb_device *udev)
 {
 	int err;
 
+#ifdef CONFIG_USB_SUSPEND
+	/* Disable autosuspend for most devices - Windows only enables it
+	   for a small subset of classes, so most hardware hasn't been tested
+	   with it. Userspace can always reenable at a later point */
+
+	switch (udev->descriptor.bDeviceClass) {
+	case USB_CLASS_HID:
+	case USB_CLASS_COMM:
+	case USB_CLASS_WIRELESS_CONTROLLER:
+	case USB_CLASS_HUB:
+		break;
+	default:
+		udev->autosuspend_disabled = 1;
+	}
+#endif
+
 	/* Determine quirks */
 	usb_detect_quirks(udev);


-- 
Matthew Garrett | mjg59 at srcf.ucam.org

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/
_______________________________________________
linux-usb-devel at lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel


linux-2.6-utrace-core.patch:

--- NEW FILE linux-2.6-utrace-core.patch ---
[PATCH 3] utrace core

This adds the utrace facility, a new modular interface in the kernel for
implementing user thread tracing and debugging.  This fits on top of the
tracehook_* layer, so the new code is well-isolated.

The new interface is in <linux/utrace.h>, and Documentation/utrace.txt
describes it.  It allows for multiple separate tracing engines to work in
parallel without interfering with each other.  Higher-level tracing
facilities can be implemented as loadable kernel modules using this layer.

The new facility is made optional under CONFIG_UTRACE.
Normal configurations will always want to enable it.
It's optional to emphasize the clean separation of the code,
and in case some stripped-down embedded configurations might want to
omit it to save space (when ptrace and the like can never be used).

Signed-off-by: Roland McGrath <roland at redhat.com>

---

 Documentation/DocBook/Makefile    |    2 
 Documentation/DocBook/utrace.tmpl |   23 
 Documentation/utrace.txt          |  579 ++++++++++
 include/linux/sched.h             |    5 
 include/linux/tracehook.h         |   85 +
 include/linux/utrace.h            |  544 +++++++++
 init/Kconfig                      |   18 
 kernel/Makefile                   |    1 
 kernel/utrace.c                   | 2141 ++++++++++++++++++++++++++++++++++++++
 9 files changed, 3380 insertions(+), 18 deletions(-)
 create kernel/utrace.c
 create Documentation/utrace.txt
 create Documentation/DocBook/utrace.tmpl
 create include/linux/utrace.h

Index: b/kernel/Makefile
===================================================================
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -51,6 +51,7 @@ obj-$(CONFIG_SYSCTL) += utsname_sysctl.o
 obj-$(CONFIG_UTS_NS) += utsname.o
 obj-$(CONFIG_TASK_DELAY_ACCT) += delayacct.o
 obj-$(CONFIG_TASKSTATS) += taskstats.o tsacct.o
+obj-$(CONFIG_UTRACE) += utrace.o
 
 ifneq ($(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER),y)
 # According to Alan Modra <alan at linuxcare.com.au>, the -fno-omit-frame-pointer is
Index: b/kernel/utrace.c
===================================================================
--- /dev/null
+++ b/kernel/utrace.c
@@ -0,0 +1,2141 @@
+/*
+ * utrace infrastructure interface for debugging user processes
+ *
+ * Copyright (C) 2006, 2007 Red Hat, Inc.  All rights reserved.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License v.2.
+ *
+ * Red Hat Author: Roland McGrath.
+ */
+
+#include <linux/utrace.h>
+#include <linux/tracehook.h>
+#include <linux/err.h>
+#include <linux/sched.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <asm/tracehook.h>
+
+
+#define UTRACE_DEBUG 1
+#ifdef UTRACE_DEBUG
+#define CHECK_INIT(p)	atomic_set(&(p)->check_dead, 1)
+#define CHECK_DEAD(p)	BUG_ON(!atomic_dec_and_test(&(p)->check_dead))
+#else
+#define CHECK_INIT(p)	do { } while (0)
+#define CHECK_DEAD(p)	do { } while (0)
+#endif
+
+/*
+ * Per-thread structure task_struct.utrace points to.
+ *
+ * The task itself never has to worry about this going away after
+ * some event is found set in task_struct.utrace_flags.
+ * Once created, this pointer is changed only when the task is quiescent
+ * (TASK_TRACED or TASK_STOPPED with the siglock held, or dead).
+ *
+ * For other parties, the pointer to this is protected by RCU and
+ * task_lock.  Since call_rcu is never used while the thread is alive and
+ * using this struct utrace, we can overlay the RCU data structure used
+ * only for a dead struct with some local state used only for a live utrace
+ * on an active thread.
+ */
+struct utrace
+{
+	union {
+		struct rcu_head dead;
+		struct {
+			struct task_struct *cloning;
+			struct utrace_signal *signal;
+		} live;
+		struct {
+			unsigned long flags;
+		} exit;
+	} u;
+
+	struct list_head engines;
+	spinlock_t lock;
+#ifdef UTRACE_DEBUG
+	atomic_t check_dead;
+#endif
+};
+
+static struct kmem_cache *utrace_cachep;
+static struct kmem_cache *utrace_engine_cachep;
+
+static int __init
+utrace_init(void)
+{
+	utrace_cachep =
+		kmem_cache_create("utrace_cache",
+				  sizeof(struct utrace), 0,
+				  SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL);
+	utrace_engine_cachep =
+		kmem_cache_create("utrace_engine_cache",
+				  sizeof(struct utrace_attached_engine), 0,
+				  SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL);
+	return 0;
+}
+subsys_initcall(utrace_init);
+
+
+/*
+ * Make sure target->utrace is allocated, and return with it locked on
+ * success.  This function mediates startup races.  The creating parent
+ * task has priority, and other callers will delay here to let its call
+ * succeed and take the new utrace lock first.
+ */
+static struct utrace *
+utrace_first_engine(struct task_struct *target,
+		    struct utrace_attached_engine *engine)
+	__acquires(utrace->lock)
+{
+	struct utrace *utrace;
+
+	/*
+	 * If this is a newborn thread and we are not the creator,
+	 * we have to wait for it.  The creator gets the first chance
+	 * to attach.  The PF_STARTING flag is cleared after its
+	 * report_clone hook has had a chance to run.
+	 */
+	if ((target->flags & PF_STARTING)
+	    && (current->utrace == NULL
+		|| current->utrace->u.live.cloning != target)) {
+		yield();
+		return (signal_pending(current)
+			? ERR_PTR(-ERESTARTNOINTR) : NULL);
+	}
+
+	utrace = kmem_cache_alloc(utrace_cachep, GFP_KERNEL);
+	if (unlikely(utrace == NULL))
+		return ERR_PTR(-ENOMEM);
+
+	utrace->u.live.cloning = NULL;
+	utrace->u.live.signal = NULL;
+	INIT_LIST_HEAD(&utrace->engines);
+	list_add(&engine->entry, &utrace->engines);
+	spin_lock_init(&utrace->lock);
+	CHECK_INIT(utrace);
+
+	spin_lock(&utrace->lock);
+	task_lock(target);
+	if (likely(target->utrace == NULL)) {
+		rcu_assign_pointer(target->utrace, utrace);
+
+		/*
+		 * The task_lock protects us against another thread doing
+		 * the same thing.  We might still be racing against
+		 * tracehook_release_task.  It's called with ->exit_state
+		 * set to EXIT_DEAD and then checks ->utrace with an
+		 * smp_mb() in between.  If EXIT_DEAD is set, then
+		 * release_task might have checked ->utrace already and saw
+		 * it NULL; we can't attach.  If we see EXIT_DEAD not yet
+		 * set after our barrier, then we know release_task will
+		 * see our target->utrace pointer.
+		 */
+		smp_mb();
+		if (likely(target->exit_state != EXIT_DEAD)) {
+			task_unlock(target);
+			return utrace;
+		}
+
+		/*
+		 * The target has already been through release_task.
[...3293 lines suppressed...]
+
+
+/*
+ * These are the exported entry points for tracing engines to use.
+ */
+struct utrace_attached_engine *utrace_attach(struct task_struct *target,
+					     int flags,
+					     const struct utrace_engine_ops *,
+					     void *data);
+int utrace_detach(struct task_struct *target,
+		  struct utrace_attached_engine *engine);
+int utrace_set_flags(struct task_struct *target,
+		     struct utrace_attached_engine *engine,
+		     unsigned long flags);
+int utrace_inject_signal(struct task_struct *target,
+			 struct utrace_attached_engine *engine,
+			 u32 action, siginfo_t *info,
+			 const struct k_sigaction *ka);
+const struct utrace_regset *utrace_regset(struct task_struct *target,
+					  struct utrace_attached_engine *,
+					  const struct utrace_regset_view *,
+					  int which);
+
+
+/*
+ * Hooks in <linux/tracehook.h> call these entry points to the utrace dispatch.
+ */
+int utrace_quiescent(struct task_struct *, struct utrace_signal *);
+void utrace_release_task(struct task_struct *);
+int utrace_get_signal(struct task_struct *, struct pt_regs *,
+		      siginfo_t *, struct k_sigaction *);
+void utrace_report_clone(unsigned long clone_flags, struct task_struct *child);
+void utrace_report_vfork_done(pid_t child_pid);
+void utrace_report_exit(long *exit_code);
+void utrace_report_death(struct task_struct *, struct utrace *);
+void utrace_report_delayed_group_leader(struct task_struct *);
+int utrace_report_jctl(int type);
+void utrace_report_exec(struct linux_binprm *bprm, struct pt_regs *regs);
+void utrace_report_syscall(struct pt_regs *regs, int is_exit);
+struct task_struct *utrace_tracer_task(struct task_struct *);
+int utrace_allow_access_process_vm(struct task_struct *);
+int utrace_unsafe_exec(struct task_struct *);
+void utrace_signal_handler_singlestep(struct task_struct *, struct pt_regs *);
+
+/*
+ * <linux/tracehook.h> uses these accessors to avoid #ifdef CONFIG_UTRACE.
+ */
+static inline unsigned long tsk_utrace_flags(struct task_struct *tsk)
+{
+	return tsk->utrace_flags;
+}
+static inline struct utrace *tsk_utrace_struct(struct task_struct *tsk)
+{
+	return tsk->utrace;
+}
+static inline void utrace_init_task(struct task_struct *child)
+{
+	child->utrace_flags = 0;
+	child->utrace = NULL;
+}
+
+#else  /* !CONFIG_UTRACE */
+
+static unsigned long tsk_utrace_flags(struct task_struct *tsk)
+{
+	return 0;
+}
+static struct utrace *tsk_utrace_struct(struct task_struct *tsk)
+{
+	return NULL;
+}
+static inline void utrace_init_task(struct task_struct *child)
+{
+}
+
+/*
+ * The calls to these should all be in if (0) and optimized out entirely.
+ * We have stubs here only so tracehook.h doesn't need to #ifdef them
+ * to avoid external references in case of unoptimized compilation.
+ */
+static inline int utrace_quiescent(struct task_struct *tsk, void *ignored)
+{
+	BUG();
+	return 0;
+}
+static inline void utrace_release_task(struct task_struct *tsk)
+{
+	BUG();
+}
+static inline int utrace_get_signal(struct task_struct *tsk,
+				    struct pt_regs *regs,
+				    siginfo_t *info, struct k_sigaction *ka)
+{
+	BUG();
+	return 0;
+}
+static inline void utrace_report_clone(unsigned long clone_flags,
+				       struct task_struct *child)
+{
+	BUG();
+}
+static inline void utrace_report_vfork_done(pid_t child_pid)
+{
+	BUG();
+}
+static inline void utrace_report_exit(long *exit_code)
+{
+	BUG();
+}
+static inline void utrace_report_death(struct task_struct *tsk, void *ignored)
+{
+	BUG();
+}
+static inline void utrace_report_delayed_group_leader(struct task_struct *tsk)
+{
+	BUG();
+}
+static inline int utrace_report_jctl(int type)
+{
+	BUG();
+	return 0;
+}
+static inline void utrace_report_exec(struct linux_binprm *bprm,
+				      struct pt_regs *regs)
+{
+	BUG();
+}
+static inline void utrace_report_syscall(struct pt_regs *regs, int is_exit)
+{
+	BUG();
+}
+static inline struct task_struct *utrace_tracer_task(struct task_struct *tsk)
+{
+	BUG();
+	return NULL;
+}
+static inline int utrace_allow_access_process_vm(struct task_struct *tsk)
+{
+	BUG();
+	return 0;
+}
+static inline int utrace_unsafe_exec(struct task_struct *tsk)
+{
+	BUG();
+	return 0;
+}
+static inline void utrace_signal_handler_singlestep(struct task_struct *tsk,
+						    struct pt_regs *regs)
+{
+	BUG();
+}
+
+#endif  /* CONFIG_UTRACE */
+
+#endif	/* linux/utrace.h */
Index: b/include/linux/sched.h
===================================================================
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -941,6 +941,11 @@ struct task_struct {
 	struct audit_context *audit_context;
 	seccomp_t seccomp;
 
+#ifdef CONFIG_UTRACE
+	struct utrace *utrace;
+	unsigned long utrace_flags;
+#endif
+
 /* Thread group tracking */
    	u32 parent_exec_id;
    	u32 self_exec_id;
Index: b/init/Kconfig
===================================================================
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -595,6 +595,24 @@ config STOP_MACHINE
 	  Need stop_machine() primitive.
 endmenu
 
+menu "Process debugging support"
+
+config UTRACE
+	bool "Infrastructure for tracing and debugging user processes"
+	default y
+	depends on MODULES
+	help
+	  Enable the utrace process tracing interface.
+	  This is an internal kernel interface to track events in user
+	  threads, extract and change user thread state.  This interface
+	  is exported to kernel modules, and is also used to implement ptrace.
+	  If you disable this, no facilities for debugging user processes
+	  will be available, nor the facilities used by UML and other
+	  applications.  Unless you are making a specially stripped-down
+	  kernel and are very sure you don't need these facilitiies,
+	  say Y.
+endmenu
+
 menu "Block layer"
 source "block/Kconfig"
 endmenu

linux-2.6-utrace-ptrace-compat-avr32.patch:

--- NEW FILE linux-2.6-utrace-ptrace-compat-avr32.patch ---
[PATCH 4d] utrace: avr32 ptrace compatibility

From: Haavard Skinnemoen <hskinnemoen at atmel.com>

Rip out most of the ptrace code for AVR32 and replace it with the much
nicer utrace stuff.  It builds in all possible combinations of
CONFIG_UTRACE and CONFIG_PTRACE, and it seems to work as far as I've tested
it with strace and some simple debugging with gdb.

Signed-off-by: Haavard Skinnemoen <hskinnemoen at atmel.com>
Signed-off-by: Roland McGrath <roland at redhat.com>

---

 arch/avr32/kernel/ptrace.c |   98 ++++++++------------------------------------
 1 files changed, 18 insertions(+), 80 deletions(-)

--- linux-2.6/arch/avr32/kernel/ptrace.c
+++ linux-2.6/arch/avr32/kernel/ptrace.c
@@ -79,106 +79,44 @@ const struct utrace_regset_view *utrace_
 }
 #endif /* CONFIG_UTRACE */
 
+#ifdef CONFIG_PTRACE
 
-#if 0
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+static const struct ptrace_layout_segment avr32_uarea[] = {
+	{ 0, ELF_NGREG * sizeof(long), 0, 0 },
+	{ 0, 0, -1, 0 },
+};
+
+int arch_ptrace(long *request, struct task_struct *child,
+		struct utrace_attached_engine *engine,
+		unsigned long addr, unsigned long data, long *val)
 {
-	int ret;
-
 	pr_debug("arch_ptrace(%ld, %d, %#lx, %#lx)\n",
-		 request, child->pid, addr, data);
+		 *request, child->pid, addr, data);
 
 	pr_debug("ptrace: Enabling monitor mode...\n");
 	__mtdr(DBGREG_DC, __mfdr(DBGREG_DC) | DC_MM | DC_DBE);
 
-	switch (request) {
-	/* Read the word at location addr in the child process */
-	case PTRACE_PEEKTEXT:
-	case PTRACE_PEEKDATA:
-		ret = generic_ptrace_peekdata(child, addr, data);
-		break;
-
+	switch (*request) {
 	case PTRACE_PEEKUSR:
-		ret = ptrace_read_user(child, addr,
-				       (unsigned long __user *)data);
-		break;
-
-	/* Write the word in data at location addr */
-	case PTRACE_POKETEXT:
-	case PTRACE_POKEDATA:
-		ret = generic_ptrace_pokedata(child, addr, data);
-		break;
+		return ptrace_peekusr(child, engine, avr32_uarea, addr, data);
 
 	case PTRACE_POKEUSR:
-		ret = ptrace_write_user(child, addr, data);
-		break;
-
-	/* continue and stop at next (return from) syscall */
-	case PTRACE_SYSCALL:
-	/* restart after signal */
-	case PTRACE_CONT:
-		ret = -EIO;
-		if (!valid_signal(data))
-			break;
-		if (request == PTRACE_SYSCALL)
-			set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-		else
-			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-		child->exit_code = data;
-		/* XXX: Are we sure no breakpoints are active here? */
-		wake_up_process(child);
-		ret = 0;
-		break;
-
-	/*
-	 * Make the child exit. Best I can do is send it a
-	 * SIGKILL. Perhaps it should be put in the status that it
-	 * wants to exit.
-	 */
-	case PTRACE_KILL:
-		ret = 0;
-		if (child->exit_state == EXIT_ZOMBIE)
-			break;
-		child->exit_code = SIGKILL;
-		wake_up_process(child);
-		break;
-
-	/*
-	 * execute single instruction.
-	 */
-	case PTRACE_SINGLESTEP:
-		ret = -EIO;
-		if (!valid_signal(data))
-			break;
-		clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-		ptrace_single_step(child);
-		child->exit_code = data;
-		wake_up_process(child);
-		ret = 0;
-		break;
-
-	/* Detach a process that was attached */
-	case PTRACE_DETACH:
-		ret = ptrace_detach(child, data);
+		return ptrace_pokeusr(child, engine, avr32_uarea, addr, data);
 		break;
 
 	case PTRACE_GETREGS:
-		ret = ptrace_getregs(child, (void __user *)data);
+		return ptrace_whole_regset(child, engine, data, 0, 0);
 		break;
 
 	case PTRACE_SETREGS:
-		ret = ptrace_setregs(child, (const void __user *)data);
-		break;
-
-	default:
-		ret = ptrace_request(child, request, addr, data);
+		return ptrace_whole_regset(child, engine, data, 0, 1);
 		break;
 	}
 
-	pr_debug("sys_ptrace returning %d (DC = 0x%08lx)\n", ret, __mfdr(DBGREG_DC));
-	return ret;
+	return -ENOSYS;
 }
-#endif
+#endif /* CONFIG_PTRACE */
+#endif /* CONFIG_UTRACE */
 
 asmlinkage void syscall_trace(struct pt_regs *regs, int is_exit)
 {

linux-2.6-utrace-ptrace-compat-ia64.patch:

--- NEW FILE linux-2.6-utrace-ptrace-compat-ia64.patch ---
[PATCH 4a] utrace: ia64 ptrace compatibility

This patch implements ptrace compatibility for ia64.

Signed-off-by: Roland McGrath <roland at redhat.com>
Signed-off-by: Anil S Keshavamurthy <anil.s.keshavamurthy at intel.com>
Signed-off-by: Bibo mao <bibo.mao at intel.com>

---

 arch/ia64/ia32/sys_ia32.c |   40 +
 arch/ia64/kernel/ptrace.c | 1016 +++++-----------------------------------------
 2 files changed, 159 insertions(+), 897 deletions(-)

Index: b/arch/ia64/ia32/sys_ia32.c
===================================================================
--- a/arch/ia64/ia32/sys_ia32.c
+++ b/arch/ia64/ia32/sys_ia32.c
@@ -2340,6 +2340,46 @@ const struct utrace_regset_view utrace_i
 };
 #endif
 
+#ifdef CONFIG_PTRACE
+/*
+ * This matches the arch/i386/kernel/ptrace.c definitions.
+ */
+
+static const struct ptrace_layout_segment ia32_uarea[] = {
+	{0, sizeof(struct user_regs_struct32), 0, 0},
+	{0, 0, -1, 0}
+};
+
+fastcall int arch_compat_ptrace(compat_long_t *request,
+		struct task_struct *child,
+		struct utrace_attached_engine *engine,
+		compat_ulong_t addr, compat_ulong_t data,
+		compat_long_t *retval)
+{
+	switch (*request) {
+		case PTRACE_PEEKUSR:
+			return ptrace_compat_peekusr(child, engine, ia32_uarea,
+					addr, data);
+		case PTRACE_POKEUSR:
+			return ptrace_compat_pokeusr(child, engine, ia32_uarea,
+					addr, data);
+		case IA32_PTRACE_GETREGS:
+			return ptrace_whole_regset(child, engine, data, 0, 0);
+		case IA32_PTRACE_SETREGS:
+			return ptrace_whole_regset(child, engine, data, 0, 1);
+		case IA32_PTRACE_GETFPREGS:
+			return ptrace_whole_regset(child, engine, data, 1, 0);
+		case IA32_PTRACE_SETFPREGS:
+			return ptrace_whole_regset(child, engine, data, 1, 1);
+		case IA32_PTRACE_GETFPXREGS:
+			return ptrace_whole_regset(child, engine, data, 2, 0);
+		case IA32_PTRACE_SETFPXREGS:
+			return ptrace_whole_regset(child, engine, data, 2, 1);
+	}
+	return -ENOSYS;
+}
+#endif
+
 typedef struct {
 	unsigned int	ss_sp;
 	unsigned int	ss_flags;
Index: b/arch/ia64/kernel/ptrace.c
===================================================================
--- a/arch/ia64/kernel/ptrace.c
+++ b/arch/ia64/kernel/ptrace.c
@@ -554,81 +554,6 @@ ia64_sync_user_rbs (struct task_struct *
 	return 0;
 }
 
-#if 0				/* XXX */
-static inline int
-thread_matches (struct task_struct *thread, unsigned long addr)
-{
-	unsigned long thread_rbs_end;
-	struct pt_regs *thread_regs;
-
-	if (ptrace_check_attach(thread, 0) < 0)
-		/*
-		 * If the thread is not in an attachable state, we'll
-		 * ignore it.  The net effect is that if ADDR happens
-		 * to overlap with the portion of the thread's
-		 * register backing store that is currently residing
-		 * on the thread's kernel stack, then ptrace() may end
-		 * up accessing a stale value.  But if the thread
-		 * isn't stopped, that's a problem anyhow, so we're
-		 * doing as well as we can...
-		 */
-		return 0;
-
-	thread_regs = task_pt_regs(thread);
-	thread_rbs_end = ia64_get_user_rbs_end(thread, thread_regs, NULL);
-	if (!on_kernel_rbs(addr, thread_regs->ar_bspstore, thread_rbs_end))
-		return 0;
-
-	return 1;	/* looks like we've got a winner */
-}
-
-/*
- * GDB apparently wants to be able to read the register-backing store
- * of any thread when attached to a given process.  If we are peeking
- * or poking an address that happens to reside in the kernel-backing
- * store of another thread, we need to attach to that thread, because
- * otherwise we end up accessing stale data.
- *
- * task_list_lock must be read-locked before calling this routine!
- */
-static struct task_struct *
-find_thread_for_addr (struct task_struct *child, unsigned long addr)
-{
-	struct task_struct *p;
-	struct mm_struct *mm;
-	struct list_head *this, *next;
-	int mm_users;
-
-	if (!(mm = get_task_mm(child)))
-		return child;
-
-	/* -1 because of our get_task_mm(): */
-	mm_users = atomic_read(&mm->mm_users) - 1;
-	if (mm_users <= 1)
-		goto out;		/* not multi-threaded */
-
-	/*
-	 * Traverse the current process' children list.  Every task that
-	 * one attaches to becomes a child.  And it is only attached children
-	 * of the debugger that are of interest (ptrace_check_attach checks
-	 * for this).
-	 */
- 	list_for_each_safe(this, next, &current->children) {
-		p = list_entry(this, struct task_struct, sibling);
-		if (p->tgid != child->tgid)
-			continue;
-		if (thread_matches(p, addr)) {
-			child = p;
-			goto out;
-		}
-	}
-
-  out:
-	mmput(mm);
-	return child;
-}
-#endif
-
 /*
  * Write f32-f127 back to task->thread.fph if it has been modified.
  */
@@ -792,828 +717,6 @@ access_nat_bits (struct task_struct *chi
 	return 0;
 }
 
-#if 0
-static int
-access_uarea (struct task_struct *child, unsigned long addr,
-	      unsigned long *data, int write_access)
-{
-	unsigned long *ptr, regnum, urbs_end, rnat_addr, cfm;
-	struct switch_stack *sw;
-	struct pt_regs *pt;
-#	define pt_reg_addr(pt, reg)	((void *)			    \
-					 ((unsigned long) (pt)		    \
-					  + offsetof(struct pt_regs, reg)))
-
-
-	pt = task_pt_regs(child);
-	sw = (struct switch_stack *) (child->thread.ksp + 16);
-
-	if ((addr & 0x7) != 0) {
-		dprintk("ptrace: unaligned register address 0x%lx\n", addr);
-		return -1;
-	}
-
-	if (addr < PT_F127 + 16) {
-		/* accessing fph */
-		if (write_access)
-			ia64_sync_fph(child);
-		else
-			ia64_flush_fph(child);
-		ptr = (unsigned long *)
-			((unsigned long) &child->thread.fph + addr);
-	} else if ((addr >= PT_F10) && (addr < PT_F11 + 16)) {
-		/* scratch registers untouched by kernel (saved in pt_regs) */
-		ptr = pt_reg_addr(pt, f10) + (addr - PT_F10);
-	} else if (addr >= PT_F12 && addr < PT_F15 + 16) {
-		/*
-		 * Scratch registers untouched by kernel (saved in
-		 * switch_stack).
-		 */
-		ptr = (unsigned long *) ((long) sw
-					 + (addr - PT_NAT_BITS - 32));
-	} else if (addr < PT_AR_LC + 8) {
-		/* preserved state: */
-		struct unw_frame_info info;
-		char nat = 0;
-		int ret;
-
-		unw_init_from_blocked_task(&info, child);
-		if (unw_unwind_to_user(&info) < 0)
-			return -1;
-
-		switch (addr) {
-		      case PT_NAT_BITS:
-			return access_nat_bits(child, pt, &info,
-					       data, write_access);
-
-		      case PT_R4: case PT_R5: case PT_R6: case PT_R7:
-			if (write_access) {
-				/* read NaT bit first: */
-				unsigned long dummy;
-
-				ret = unw_get_gr(&info, (addr - PT_R4)/8 + 4,
-						 &dummy, &nat);
-				if (ret < 0)
-					return ret;
-			}
-			return unw_access_gr(&info, (addr - PT_R4)/8 + 4, data,
-					     &nat, write_access);
-
-		      case PT_B1: case PT_B2: case PT_B3:
-		      case PT_B4: case PT_B5:
-			return unw_access_br(&info, (addr - PT_B1)/8 + 1, data,
-					     write_access);
-
-		      case PT_AR_EC:
-			return unw_access_ar(&info, UNW_AR_EC, data,
-					     write_access);
-
-		      case PT_AR_LC:
-			return unw_access_ar(&info, UNW_AR_LC, data,
-					     write_access);
-
-		      default:
-			if (addr >= PT_F2 && addr < PT_F5 + 16)
-				return access_fr(&info, (addr - PT_F2)/16 + 2,
-						 (addr & 8) != 0, data,
-						 write_access);
-			else if (addr >= PT_F16 && addr < PT_F31 + 16)
-				return access_fr(&info,
-						 (addr - PT_F16)/16 + 16,
-						 (addr & 8) != 0,
-						 data, write_access);
-			else {
-				dprintk("ptrace: rejecting access to register "
-					"address 0x%lx\n", addr);
-				return -1;
-			}
-		}
-	} else if (addr < PT_F9+16) {
-		/* scratch state */
-		switch (addr) {
-		      case PT_AR_BSP:
-			/*
-			 * By convention, we use PT_AR_BSP to refer to
-			 * the end of the user-level backing store.
-			 * Use ia64_rse_skip_regs(PT_AR_BSP, -CFM.sof)
-			 * to get the real value of ar.bsp at the time
-			 * the kernel was entered.
-			 *
-			 * Furthermore, when changing the contents of
-			 * PT_AR_BSP (or PT_CFM) we MUST copy any
-			 * users-level stacked registers that are
-			 * stored on the kernel stack back to
-			 * user-space because otherwise, we might end
-			 * up clobbering kernel stacked registers.
-			 * Also, if this happens while the task is
-			 * blocked in a system call, which convert the
-			 * state such that the non-system-call exit
-			 * path is used.  This ensures that the proper
-			 * state will be picked up when resuming
-			 * execution.  However, it *also* means that
-			 * once we write PT_AR_BSP/PT_CFM, it won't be
-			 * possible to modify the syscall arguments of
-			 * the pending system call any longer.  This
-			 * shouldn't be an issue because modifying
-			 * PT_AR_BSP/PT_CFM generally implies that
-			 * we're either abandoning the pending system
-			 * call or that we defer it's re-execution
-			 * (e.g., due to GDB doing an inferior
-			 * function call).
-			 */
-			urbs_end = ia64_get_user_rbs_end(child, pt, &cfm);
-			if (write_access) {
-				if (*data != urbs_end) {
-					if (ia64_sync_user_rbs(child, sw,
-							       pt->ar_bspstore,
-							       urbs_end) < 0)
-						return -1;
-					if (in_syscall(pt))
-						convert_to_non_syscall(child,
-								       pt,
-								       cfm);
-					/*
-					 * Simulate user-level write
-					 * of ar.bsp:
-					 */
-					pt->loadrs = 0;
-					pt->ar_bspstore = *data;
-				}
-			} else
-				*data = urbs_end;
-			return 0;
-
-		      case PT_CFM:
-			urbs_end = ia64_get_user_rbs_end(child, pt, &cfm);
-			if (write_access) {
-				if (((cfm ^ *data) & PFM_MASK) != 0) {
-					if (ia64_sync_user_rbs(child, sw,
-							       pt->ar_bspstore,
-							       urbs_end) < 0)
-						return -1;
-					if (in_syscall(pt))
-						convert_to_non_syscall(child,
-								       pt,
-								       cfm);
-					pt->cr_ifs = ((pt->cr_ifs & ~PFM_MASK)
-						      | (*data & PFM_MASK));
-				}
-			} else
-				*data = cfm;
-			return 0;
-
-		      case PT_CR_IPSR:
-			if (write_access)
-				pt->cr_ipsr = ((*data & IPSR_MASK)
-					       | (pt->cr_ipsr & ~IPSR_MASK));
-			else
-				*data = (pt->cr_ipsr & IPSR_MASK);
-			return 0;
-
-		      case PT_AR_RSC:
-			if (write_access)
-				pt->ar_rsc = *data | (3 << 2); /* force PL3 */
-			else
-				*data = pt->ar_rsc;
-			return 0;
-
-		      case PT_AR_RNAT:
-			urbs_end = ia64_get_user_rbs_end(child, pt, NULL);
-			rnat_addr = (long) ia64_rse_rnat_addr((long *)
-							      urbs_end);
-			if (write_access)
-				return ia64_poke(child, sw, urbs_end,
-						 rnat_addr, *data);
-			else
-				return ia64_peek(child, sw, urbs_end,
-						 rnat_addr, data);
-
-		      case PT_R1:
-			ptr = pt_reg_addr(pt, r1);
-			break;
-		      case PT_R2:  case PT_R3:
-			ptr = pt_reg_addr(pt, r2) + (addr - PT_R2);
-			break;
-		      case PT_R8:  case PT_R9:  case PT_R10: case PT_R11:
-			ptr = pt_reg_addr(pt, r8) + (addr - PT_R8);
-			break;
-		      case PT_R12: case PT_R13:
-			ptr = pt_reg_addr(pt, r12) + (addr - PT_R12);
-			break;
-		      case PT_R14:
-			ptr = pt_reg_addr(pt, r14);
-			break;
-		      case PT_R15:
-			ptr = pt_reg_addr(pt, r15);
-			break;
-		      case PT_R16: case PT_R17: case PT_R18: case PT_R19:
-		      case PT_R20: case PT_R21: case PT_R22: case PT_R23:
-		      case PT_R24: case PT_R25: case PT_R26: case PT_R27:
-		      case PT_R28: case PT_R29: case PT_R30: case PT_R31:
-			ptr = pt_reg_addr(pt, r16) + (addr - PT_R16);
-			break;
-		      case PT_B0:
-			ptr = pt_reg_addr(pt, b0);
-			break;
-		      case PT_B6:
-			ptr = pt_reg_addr(pt, b6);
-			break;
-		      case PT_B7:
-			ptr = pt_reg_addr(pt, b7);
-			break;
-		      case PT_F6:  case PT_F6+8: case PT_F7: case PT_F7+8:
-		      case PT_F8:  case PT_F8+8: case PT_F9: case PT_F9+8:
-			ptr = pt_reg_addr(pt, f6) + (addr - PT_F6);
-			break;
-		      case PT_AR_BSPSTORE:
-			ptr = pt_reg_addr(pt, ar_bspstore);
-			break;
-		      case PT_AR_UNAT:
-			ptr = pt_reg_addr(pt, ar_unat);
-			break;
-		      case PT_AR_PFS:
-			ptr = pt_reg_addr(pt, ar_pfs);
-			break;
-		      case PT_AR_CCV:
-			ptr = pt_reg_addr(pt, ar_ccv);
-			break;
-		      case PT_AR_FPSR:
-			ptr = pt_reg_addr(pt, ar_fpsr);
-			break;
-		      case PT_CR_IIP:
-			ptr = pt_reg_addr(pt, cr_iip);
-			break;
-		      case PT_PR:
-			ptr = pt_reg_addr(pt, pr);
-			break;
-			/* scratch register */
-
-		      default:
-			/* disallow accessing anything else... */
-			dprintk("ptrace: rejecting access to register "
-				"address 0x%lx\n", addr);
-			return -1;
-		}
-	} else if (addr <= PT_AR_SSD) {
-		ptr = pt_reg_addr(pt, ar_csd) + (addr - PT_AR_CSD);
-	} else {
-		/* access debug registers */
-
-		if (addr >= PT_IBR) {
-			regnum = (addr - PT_IBR) >> 3;
-			ptr = &child->thread.ibr[0];
-		} else {
-			regnum = (addr - PT_DBR) >> 3;
-			ptr = &child->thread.dbr[0];
-		}
-
-		if (regnum >= 8) {
-			dprintk("ptrace: rejecting access to register "
-				"address 0x%lx\n", addr);
-			return -1;
-		}
-#ifdef CONFIG_PERFMON
-		/*
-		 * Check if debug registers are used by perfmon. This
-		 * test must be done once we know that we can do the
-		 * operation, i.e. the arguments are all valid, but
-		 * before we start modifying the state.
-		 *
-		 * Perfmon needs to keep a count of how many processes
-		 * are trying to modify the debug registers for system
-		 * wide monitoring sessions.
-		 *
-		 * We also include read access here, because they may
-		 * cause the PMU-installed debug register state
-		 * (dbr[], ibr[]) to be reset. The two arrays are also
-		 * used by perfmon, but we do not use
-		 * IA64_THREAD_DBG_VALID. The registers are restored
-		 * by the PMU context switch code.
-		 */
-		if (pfm_use_debug_registers(child)) return -1;
-#endif
-
-		if (!(child->thread.flags & IA64_THREAD_DBG_VALID)) {
-			child->thread.flags |= IA64_THREAD_DBG_VALID;
-			memset(child->thread.dbr, 0,
-			       sizeof(child->thread.dbr));
-			memset(child->thread.ibr, 0,
-			       sizeof(child->thread.ibr));
-		}
-
-		ptr += regnum;
-
-		if ((regnum & 1) && write_access) {
-			/* don't let the user set kernel-level breakpoints: */
-			*ptr = *data & ~(7UL << 56);
-			return 0;
-		}
-	}
-	if (write_access)
-		*ptr = *data;
-	else
-		*data = *ptr;
-	return 0;
-}
-
-static long
-ptrace_getregs (struct task_struct *child, struct pt_all_user_regs __user *ppr)
-{
-	unsigned long psr, ec, lc, rnat, bsp, cfm, nat_bits, val;
-	struct unw_frame_info info;
-	struct ia64_fpreg fpval;
-	struct switch_stack *sw;
-	struct pt_regs *pt;
-	long ret, retval = 0;
-	char nat = 0;
-	int i;
-
-	if (!access_ok(VERIFY_WRITE, ppr, sizeof(struct pt_all_user_regs)))
-		return -EIO;
-
-	pt = task_pt_regs(child);
-	sw = (struct switch_stack *) (child->thread.ksp + 16);
-	unw_init_from_blocked_task(&info, child);
-	if (unw_unwind_to_user(&info) < 0) {
-		return -EIO;
-	}
-
-	if (((unsigned long) ppr & 0x7) != 0) {
-		dprintk("ptrace:unaligned register address %p\n", ppr);
-		return -EIO;
-	}
-
-	if (access_uarea(child, PT_CR_IPSR, &psr, 0) < 0
-	    || access_uarea(child, PT_AR_EC, &ec, 0) < 0
-	    || access_uarea(child, PT_AR_LC, &lc, 0) < 0
-	    || access_uarea(child, PT_AR_RNAT, &rnat, 0) < 0
-	    || access_uarea(child, PT_AR_BSP, &bsp, 0) < 0
-	    || access_uarea(child, PT_CFM, &cfm, 0)
-	    || access_uarea(child, PT_NAT_BITS, &nat_bits, 0))
-		return -EIO;
-
-	/* control regs */
-
-	retval |= __put_user(pt->cr_iip, &ppr->cr_iip);
-	retval |= __put_user(psr, &ppr->cr_ipsr);
-
-	/* app regs */
-
-	retval |= __put_user(pt->ar_pfs, &ppr->ar[PT_AUR_PFS]);
-	retval |= __put_user(pt->ar_rsc, &ppr->ar[PT_AUR_RSC]);
-	retval |= __put_user(pt->ar_bspstore, &ppr->ar[PT_AUR_BSPSTORE]);
-	retval |= __put_user(pt->ar_unat, &ppr->ar[PT_AUR_UNAT]);
-	retval |= __put_user(pt->ar_ccv, &ppr->ar[PT_AUR_CCV]);
-	retval |= __put_user(pt->ar_fpsr, &ppr->ar[PT_AUR_FPSR]);
-
-	retval |= __put_user(ec, &ppr->ar[PT_AUR_EC]);
-	retval |= __put_user(lc, &ppr->ar[PT_AUR_LC]);
-	retval |= __put_user(rnat, &ppr->ar[PT_AUR_RNAT]);
-	retval |= __put_user(bsp, &ppr->ar[PT_AUR_BSP]);
-	retval |= __put_user(cfm, &ppr->cfm);
-
-	/* gr1-gr3 */
-
-	retval |= __copy_to_user(&ppr->gr[1], &pt->r1, sizeof(long));
-	retval |= __copy_to_user(&ppr->gr[2], &pt->r2, sizeof(long) *2);
-
-	/* gr4-gr7 */
-
-	for (i = 4; i < 8; i++) {
-		if (unw_access_gr(&info, i, &val, &nat, 0) < 0)
-			return -EIO;
-		retval |= __put_user(val, &ppr->gr[i]);
-	}
-
-	/* gr8-gr11 */
-
-	retval |= __copy_to_user(&ppr->gr[8], &pt->r8, sizeof(long) * 4);
-
-	/* gr12-gr15 */
-
-	retval |= __copy_to_user(&ppr->gr[12], &pt->r12, sizeof(long) * 2);
-	retval |= __copy_to_user(&ppr->gr[14], &pt->r14, sizeof(long));
-	retval |= __copy_to_user(&ppr->gr[15], &pt->r15, sizeof(long));
-
-	/* gr16-gr31 */
-
-	retval |= __copy_to_user(&ppr->gr[16], &pt->r16, sizeof(long) * 16);
-
-	/* b0 */
-
-	retval |= __put_user(pt->b0, &ppr->br[0]);
-
-	/* b1-b5 */
-
-	for (i = 1; i < 6; i++) {
-		if (unw_access_br(&info, i, &val, 0) < 0)
-			return -EIO;
-		__put_user(val, &ppr->br[i]);
-	}
-
-	/* b6-b7 */
-
-	retval |= __put_user(pt->b6, &ppr->br[6]);
-	retval |= __put_user(pt->b7, &ppr->br[7]);
-
-	/* fr2-fr5 */
-
-	for (i = 2; i < 6; i++) {
-		if (unw_get_fr(&info, i, &fpval) < 0)
-			return -EIO;
-		retval |= __copy_to_user(&ppr->fr[i], &fpval, sizeof (fpval));
-	}
-
-	/* fr6-fr11 */
-
-	retval |= __copy_to_user(&ppr->fr[6], &pt->f6,
-				 sizeof(struct ia64_fpreg) * 6);
-
-	/* fp scratch regs(12-15) */
-
-	retval |= __copy_to_user(&ppr->fr[12], &sw->f12,
-				 sizeof(struct ia64_fpreg) * 4);
-
-	/* fr16-fr31 */
-
-	for (i = 16; i < 32; i++) {
-		if (unw_get_fr(&info, i, &fpval) < 0)
-			return -EIO;
-		retval |= __copy_to_user(&ppr->fr[i], &fpval, sizeof (fpval));
-	}
-
-	/* fph */
-
-	ia64_flush_fph(child);
-	retval |= __copy_to_user(&ppr->fr[32], &child->thread.fph,
-				 sizeof(ppr->fr[32]) * 96);
-
-	/*  preds */
-
-	retval |= __put_user(pt->pr, &ppr->pr);
-
-	/* nat bits */
-
-	retval |= __put_user(nat_bits, &ppr->nat);
-
-	ret = retval ? -EIO : 0;
-	return ret;
-}
-#endif /* ptrace_getregs() */
-
-#if 0
-static long
-ptrace_setregs (struct task_struct *child, struct pt_all_user_regs __user *ppr)
-{
-	unsigned long psr, rsc, ec, lc, rnat, bsp, cfm, nat_bits, val = 0;
-	struct unw_frame_info info;
-	struct switch_stack *sw;
-	struct ia64_fpreg fpval;
-	struct pt_regs *pt;
-	long ret, retval = 0;
-	int i;
-
-	memset(&fpval, 0, sizeof(fpval));
-
-	if (!access_ok(VERIFY_READ, ppr, sizeof(struct pt_all_user_regs)))
-		return -EIO;
-
-	pt = task_pt_regs(child);
-	sw = (struct switch_stack *) (child->thread.ksp + 16);
-	unw_init_from_blocked_task(&info, child);
-	if (unw_unwind_to_user(&info) < 0) {
-		return -EIO;
-	}
-
-	if (((unsigned long) ppr & 0x7) != 0) {
-		dprintk("ptrace:unaligned register address %p\n", ppr);
-		return -EIO;
-	}
-
-	/* control regs */
-
-	retval |= __get_user(pt->cr_iip, &ppr->cr_iip);
-	retval |= __get_user(psr, &ppr->cr_ipsr);
-
-	/* app regs */
-
-	retval |= __get_user(pt->ar_pfs, &ppr->ar[PT_AUR_PFS]);
-	retval |= __get_user(rsc, &ppr->ar[PT_AUR_RSC]);
-	retval |= __get_user(pt->ar_bspstore, &ppr->ar[PT_AUR_BSPSTORE]);
-	retval |= __get_user(pt->ar_unat, &ppr->ar[PT_AUR_UNAT]);
-	retval |= __get_user(pt->ar_ccv, &ppr->ar[PT_AUR_CCV]);
-	retval |= __get_user(pt->ar_fpsr, &ppr->ar[PT_AUR_FPSR]);
-
-	retval |= __get_user(ec, &ppr->ar[PT_AUR_EC]);
-	retval |= __get_user(lc, &ppr->ar[PT_AUR_LC]);
-	retval |= __get_user(rnat, &ppr->ar[PT_AUR_RNAT]);
-	retval |= __get_user(bsp, &ppr->ar[PT_AUR_BSP]);
-	retval |= __get_user(cfm, &ppr->cfm);
-
-	/* gr1-gr3 */
-
-	retval |= __copy_from_user(&pt->r1, &ppr->gr[1], sizeof(long));
-	retval |= __copy_from_user(&pt->r2, &ppr->gr[2], sizeof(long) * 2);
-
-	/* gr4-gr7 */
-
-	for (i = 4; i < 8; i++) {
-		retval |= __get_user(val, &ppr->gr[i]);
-		/* NaT bit will be set via PT_NAT_BITS: */
-		if (unw_set_gr(&info, i, val, 0) < 0)
-			return -EIO;
-	}
-
-	/* gr8-gr11 */
-
-	retval |= __copy_from_user(&pt->r8, &ppr->gr[8], sizeof(long) * 4);
-
-	/* gr12-gr15 */
-
-	retval |= __copy_from_user(&pt->r12, &ppr->gr[12], sizeof(long) * 2);
-	retval |= __copy_from_user(&pt->r14, &ppr->gr[14], sizeof(long));
-	retval |= __copy_from_user(&pt->r15, &ppr->gr[15], sizeof(long));
-
-	/* gr16-gr31 */
-
-	retval |= __copy_from_user(&pt->r16, &ppr->gr[16], sizeof(long) * 16);
-
-	/* b0 */
-
-	retval |= __get_user(pt->b0, &ppr->br[0]);
-
-	/* b1-b5 */
-
-	for (i = 1; i < 6; i++) {
-		retval |= __get_user(val, &ppr->br[i]);
-		unw_set_br(&info, i, val);
-	}
-
-	/* b6-b7 */
-
-	retval |= __get_user(pt->b6, &ppr->br[6]);
-	retval |= __get_user(pt->b7, &ppr->br[7]);
-
-	/* fr2-fr5 */
-
-	for (i = 2; i < 6; i++) {
-		retval |= __copy_from_user(&fpval, &ppr->fr[i], sizeof(fpval));
-		if (unw_set_fr(&info, i, fpval) < 0)
-			return -EIO;
-	}
-
-	/* fr6-fr11 */
-
-	retval |= __copy_from_user(&pt->f6, &ppr->fr[6],
-				   sizeof(ppr->fr[6]) * 6);
-
-	/* fp scratch regs(12-15) */
-
-	retval |= __copy_from_user(&sw->f12, &ppr->fr[12],
-				   sizeof(ppr->fr[12]) * 4);
-
-	/* fr16-fr31 */
-
-	for (i = 16; i < 32; i++) {
-		retval |= __copy_from_user(&fpval, &ppr->fr[i],
-					   sizeof(fpval));
-		if (unw_set_fr(&info, i, fpval) < 0)
-			return -EIO;
-	}
-
-	/* fph */
-
-	ia64_sync_fph(child);
-	retval |= __copy_from_user(&child->thread.fph, &ppr->fr[32],
-				   sizeof(ppr->fr[32]) * 96);
-
-	/* preds */
-
-	retval |= __get_user(pt->pr, &ppr->pr);
-
-	/* nat bits */
-
-	retval |= __get_user(nat_bits, &ppr->nat);
-
-	retval |= access_uarea(child, PT_CR_IPSR, &psr, 1);
-	retval |= access_uarea(child, PT_AR_RSC, &rsc, 1);
-	retval |= access_uarea(child, PT_AR_EC, &ec, 1);
-	retval |= access_uarea(child, PT_AR_LC, &lc, 1);
-	retval |= access_uarea(child, PT_AR_RNAT, &rnat, 1);
-	retval |= access_uarea(child, PT_AR_BSP, &bsp, 1);
-	retval |= access_uarea(child, PT_CFM, &cfm, 1);
-	retval |= access_uarea(child, PT_NAT_BITS, &nat_bits, 1);
-
-	ret = retval ? -EIO : 0;
-	return ret;
-}
-#endif /* ptrace_setregs() */
-
-/*
- * Called by kernel/ptrace.c when detaching..
- *
- * Make sure the single step bit is not set.
- */
-void
-ptrace_disable (struct task_struct *child)
-{
-	struct ia64_psr *child_psr = ia64_psr(task_pt_regs(child));
-
-	/* make sure the single step/taken-branch trap bits are not set: */
-	clear_tsk_thread_flag(child, TIF_SINGLESTEP);
-	child_psr->ss = 0;
-	child_psr->tb = 0;
-}
-
-#if 0 				/* XXX */
-asmlinkage long
-sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data)
-{
-	struct pt_regs *pt;
-	unsigned long urbs_end, peek_or_poke;
-	struct task_struct *child;
-	struct switch_stack *sw;
-	long ret;
-
-	lock_kernel();
-	ret = -EPERM;
-	if (request == PTRACE_TRACEME) {
-		ret = ptrace_traceme();
-		goto out;
-	}
-
-	peek_or_poke = (request == PTRACE_PEEKTEXT
-			|| request == PTRACE_PEEKDATA
-			|| request == PTRACE_POKETEXT
-			|| request == PTRACE_POKEDATA);
-	ret = -ESRCH;
-	read_lock(&tasklist_lock);
-	{
-		child = find_task_by_pid(pid);
-		if (child) {
-			if (peek_or_poke)
-				child = find_thread_for_addr(child, addr);
-			get_task_struct(child);
-		}
-	}
-	read_unlock(&tasklist_lock);
-	if (!child)
-		goto out;
-	ret = -EPERM;
-	if (pid == 1)		/* no messing around with init! */
-		goto out_tsk;
-
-	if (request == PTRACE_ATTACH) {
-		ret = ptrace_attach(child);
-		goto out_tsk;
-	}
-
-	ret = ptrace_check_attach(child, request == PTRACE_KILL);
-	if (ret < 0)
-		goto out_tsk;
-
-	pt = task_pt_regs(child);
-	sw = (struct switch_stack *) (child->thread.ksp + 16);
-
-	switch (request) {
-	      case PTRACE_PEEKTEXT:
-	      case PTRACE_PEEKDATA:
-		/* read word at location addr */
-		urbs_end = ia64_get_user_rbs_end(child, pt, NULL);
-		ret = ia64_peek(child, sw, urbs_end, addr, &data);
-		if (ret == 0) {
-			ret = data;
-			/* ensure "ret" is not mistaken as an error code: */
-			force_successful_syscall_return();
-		}
-		goto out_tsk;
-
-	      case PTRACE_POKETEXT:
-	      case PTRACE_POKEDATA:
-		/* write the word at location addr */
-		urbs_end = ia64_get_user_rbs_end(child, pt, NULL);
-		ret = ia64_poke(child, sw, urbs_end, addr, data);
-		goto out_tsk;
-
-	      case PTRACE_PEEKUSR:
-		/* read the word at addr in the USER area */
-		if (access_uarea(child, addr, &data, 0) < 0) {
-			ret = -EIO;
-			goto out_tsk;
-		}
-		ret = data;
-		/* ensure "ret" is not mistaken as an error code */
-		force_successful_syscall_return();
-		goto out_tsk;
-
-	      case PTRACE_POKEUSR:
-		/* write the word at addr in the USER area */
-		if (access_uarea(child, addr, &data, 1) < 0) {
-			ret = -EIO;
-			goto out_tsk;
-		}
-		ret = 0;
-		goto out_tsk;
-
-	      case PTRACE_OLD_GETSIGINFO:
-		/* for backwards-compatibility */
-		ret = ptrace_request(child, PTRACE_GETSIGINFO, addr, data);
-		goto out_tsk;
-
-	      case PTRACE_OLD_SETSIGINFO:
-		/* for backwards-compatibility */
-		ret = ptrace_request(child, PTRACE_SETSIGINFO, addr, data);
-		goto out_tsk;
-
-	      case PTRACE_SYSCALL:
-		/* continue and stop at next (return from) syscall */
-	      case PTRACE_CONT:
-		/* restart after signal. */
-		ret = -EIO;
-		if (!valid_signal(data))
-			goto out_tsk;
-		if (request == PTRACE_SYSCALL)
-			set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-		else
-			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-		child->exit_code = data;
-
-		/*
-		 * Make sure the single step/taken-branch trap bits
-		 * are not set:
-		 */
-		clear_tsk_thread_flag(child, TIF_SINGLESTEP);
-		ia64_psr(pt)->ss = 0;
-		ia64_psr(pt)->tb = 0;
-
-		wake_up_process(child);
-		ret = 0;
-		goto out_tsk;
-
-	      case PTRACE_KILL:
-		/*
-		 * Make the child exit.  Best I can do is send it a
-		 * sigkill.  Perhaps it should be put in the status
-		 * that it wants to exit.
-		 */
-		if (child->exit_state == EXIT_ZOMBIE)
-			/* already dead */
-			goto out_tsk;
-		child->exit_code = SIGKILL;
-
-		ptrace_disable(child);
-		wake_up_process(child);
-		ret = 0;
-		goto out_tsk;
-
-	      case PTRACE_SINGLESTEP:
-		/* let child execute for one instruction */
-	      case PTRACE_SINGLEBLOCK:
-		ret = -EIO;
-		if (!valid_signal(data))
-			goto out_tsk;
-
-		clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-		set_tsk_thread_flag(child, TIF_SINGLESTEP);
-		if (request == PTRACE_SINGLESTEP) {
-			ia64_psr(pt)->ss = 1;
-		} else {
-			ia64_psr(pt)->tb = 1;
-		}
-		child->exit_code = data;
-
-		/* give it a chance to run. */
-		wake_up_process(child);
-		ret = 0;
-		goto out_tsk;
-
-	      case PTRACE_DETACH:
-		/* detach a process that was attached. */
-		clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-		ret = ptrace_detach(child, data);
-		goto out_tsk;
-
-	      case PTRACE_GETREGS:
-		ret = ptrace_getregs(child,
-				     (struct pt_all_user_regs __user *) data);
-		goto out_tsk;
-
-	      case PTRACE_SETREGS:
-		ret = ptrace_setregs(child,
-				     (struct pt_all_user_regs __user *) data);
-		goto out_tsk;
-
-	      default:
-		ret = ptrace_request(child, request, addr, data);
-		goto out_tsk;
-	}
-  out_tsk:
-	put_task_struct(child);
-  out:
-	unlock_kernel();
-	return ret;
-}
-#endif
 
 /* "asmlinkage" so the input arguments are preserved... */
 
@@ -1667,6 +770,9 @@ syscall_trace_leave (long arg0, long arg
 	}
 }
 
+
+#ifdef CONFIG_UTRACE
+
 /* Utrace implementation starts here */
 
 typedef struct utrace_get {
@@ -2454,3 +1560,119 @@ const struct utrace_regset_view *utrace_
 #endif
 	return &utrace_ia64_native;
 }
+#endif	/* CONFIG_UTRACE */
+
+
+#ifdef CONFIG_PTRACE
+
+#define WORD(member, num) \
+	offsetof(struct pt_all_user_regs, member), \
+	offsetof(struct pt_all_user_regs, member) + num * sizeof(long)
+static const struct ptrace_layout_segment pt_all_user_regs_layout[] = {
+	{WORD(nat, 1),			0,	ELF_NAT_OFFSET},
+	{WORD(cr_iip, 1),		0,	ELF_CR_IIP_OFFSET},
+	{WORD(cfm, 1),			0,	ELF_CFM_OFFSET},
+	{WORD(cr_ipsr, 1),		0,	ELF_CR_IPSR_OFFSET},
+	{WORD(pr, 1),			0,	ELF_PR_OFFSET},
+	{WORD(gr[0], 1),		-1,	-1},
+	{WORD(gr[1], 31),		0,	ELF_GR_OFFSET(1)},
+	{WORD(br[0], 8),		0, 	ELF_BR_OFFSET(0)},
+	{WORD(ar[0], 16),		-1,	-1},
+	{WORD(ar[PT_AUR_RSC], 4),	0,	ELF_AR_RSC_OFFSET},
+	{WORD(ar[PT_AUR_RNAT+1], 12),	-1,	-1},
+	{WORD(ar[PT_AUR_CCV], 1),	0,	ELF_AR_CCV_OFFSET},
+	{WORD(ar[PT_AUR_CCV+1], 3),	-1,	-1},
+	{WORD(ar[PT_AUR_UNAT], 1), 	0,	ELF_AR_UNAT_OFFSET},
+	{WORD(ar[PT_AUR_UNAT+1], 3),	-1,	-1},
+	{WORD(ar[PT_AUR_FPSR], 1), 	0,	ELF_AR_FPSR_OFFSET},
+	{WORD(ar[PT_AUR_FPSR+1], 23), 	-1,	-1},
+	{WORD(ar[PT_AUR_PFS], 3),  	0,	ELF_AR_PFS_OFFSET},
+	{WORD(ar[PT_AUR_EC+1], 62),	-1,	-1},
+	{offsetof(struct pt_all_user_regs, fr[0]),
+	 offsetof(struct pt_all_user_regs, fr[2]),
+	 -1, -1},
+	{offsetof(struct pt_all_user_regs, fr[2]),
+	 offsetof(struct pt_all_user_regs, fr[128]),
+	 1, 2 * sizeof(elf_fpreg_t)},
+	{0, 0, -1, 0}
+};
+#undef WORD
+
+#define NEXT(addr, sum)	(addr + sum * sizeof(long))
+static const struct ptrace_layout_segment pt_uarea_layout[] = {
+	{PT_F32,	PT_NAT_BITS,		1,	ELF_FP_OFFSET(32)},
+	{PT_NAT_BITS,	NEXT(PT_NAT_BITS, 1),	0,	ELF_NAT_OFFSET},
+	{PT_F2, 	PT_F10,			1,	ELF_FP_OFFSET(2)},
+	{PT_F10, 	PT_R4, 			1,	ELF_FP_OFFSET(10)},
+	{PT_R4, 	PT_B1, 			0,	ELF_GR_OFFSET(4)},
+	{PT_B1, 	PT_AR_EC, 		0,	ELF_BR_OFFSET(1)},
+	{PT_AR_EC, 	PT_AR_LC,	 	0,	ELF_AR_EC_OFFSET},
+	{PT_AR_LC, 	NEXT(PT_AR_LC, 1), 	0,	ELF_AR_LC_OFFSET},
+	{PT_CR_IPSR,	PT_CR_IIP,		0,	ELF_CR_IPSR_OFFSET},
+	{PT_CR_IIP,	PT_AR_UNAT,		0,	ELF_CR_IIP_OFFSET},
+	{PT_AR_UNAT,	PT_AR_PFS,		0, 	ELF_AR_UNAT_OFFSET},
+	{PT_AR_PFS,	PT_AR_RSC,		0,	ELF_AR_PFS_OFFSET},
+	{PT_AR_RSC,	PT_AR_RNAT,		0,	ELF_AR_RSC_OFFSET},
+	{PT_AR_RNAT,	PT_AR_BSPSTORE,		0,	ELF_AR_RNAT_OFFSET},
+	{PT_AR_BSPSTORE,PT_PR,			0,	ELF_AR_BSPSTORE_OFFSET},
+	{PT_PR,		PT_B6,			0,	ELF_PR_OFFSET},
+	{PT_B6,		PT_AR_BSP,		0,	ELF_BR_OFFSET(6)},
+	{PT_AR_BSP,	PT_R1,			0,	ELF_AR_BSP_OFFSET},
+	{PT_R1,		PT_R12,			0,	ELF_GR_OFFSET(1)},
+	{PT_R12,	PT_R8,			0,	ELF_GR_OFFSET(12)},
+	{PT_R8,		PT_R16,			0,	ELF_GR_OFFSET(8)},
+	{PT_R16,	PT_AR_CCV,		0,	ELF_GR_OFFSET(16)},
+	{PT_AR_CCV,	PT_AR_FPSR,		0,	ELF_AR_CCV_OFFSET},
+	{PT_AR_FPSR,	PT_B0,			0,	ELF_AR_FPSR_OFFSET},
+	{PT_B0,		PT_B7,			0,	ELF_BR_OFFSET(0)},
+	{PT_B7,		PT_F6,			0,	ELF_BR_OFFSET(7)},
+	{PT_F6,		PT_AR_CSD,		1,	ELF_FP_OFFSET(6)},
+	{PT_AR_CSD,	NEXT(PT_AR_CSD, 2),	0,	ELF_AR_CSD_OFFSET},
+	{PT_DBR,	NEXT(PT_DBR, 8), 	2,	0},
+	{PT_IBR,	NEXT(PT_IBR, 8),	2,	8 * sizeof(long)},
+	{0, 0, -1, 0}
+};
+#undef NEXT
+
+int arch_ptrace(long *request, struct task_struct *child,
+		struct utrace_attached_engine *engine,
+		unsigned long addr, unsigned long data, long *val)
+{
+	int ret = -ENOSYS;
+	switch (*request) {
+	case PTRACE_OLD_GETSIGINFO:
+		*request = PTRACE_GETSIGINFO;
+		break;
+	case PTRACE_OLD_SETSIGINFO:
+		*request = PTRACE_SETSIGINFO;
+		break;
+
+	case PTRACE_PEEKTEXT: /* read word at location addr. */
+	case PTRACE_PEEKDATA:
+		ret = access_process_vm(child, addr, val, sizeof(*val), 0);
+		ret = ret == sizeof(*val) ? 0 : -EIO;
+		break;
+
+	case PTRACE_PEEKUSR:
+		return ptrace_layout_access(child, engine,
+					    utrace_native_view(current),
+					    pt_uarea_layout,
+					    addr, sizeof(long),
+					    NULL, val, 0);
+	case PTRACE_POKEUSR:
+		return ptrace_pokeusr(child, engine,
+				      pt_uarea_layout, addr, data);
+
+	case PTRACE_GETREGS:
+	case PTRACE_SETREGS:
+		return ptrace_layout_access(child, engine,
+					    utrace_native_view(current),
+					    pt_all_user_regs_layout,
+					    0, sizeof(struct pt_all_user_regs),
+					    (void __user *) data, NULL,
+					    *request == PTRACE_SETREGS);
+	}
+	return ret;
+}
+
+#endif	/* CONFIG_PTRACE */

linux-2.6-utrace-ptrace-compat-s390.patch:

--- NEW FILE linux-2.6-utrace-ptrace-compat-s390.patch ---
[PATCH 4c] utrace: s390 ptrace compatibility

This patch implements ptrace compatibility for s390.

Signed-off-by: Roland McGrath <roland at redhat.com>
Signed-off-by: David Wilder <dwilder at us.ibm.com>

---

 arch/s390/kernel/compat_wrapper.S |    2 
 arch/s390/kernel/ptrace.c         |  151 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 152 insertions(+), 1 deletion(-)

Index: b/arch/s390/kernel/ptrace.c
===================================================================
--- a/arch/s390/kernel/ptrace.c
+++ b/arch/s390/kernel/ptrace.c
@@ -575,6 +575,157 @@ const struct utrace_regset_view *utrace_
 }
 
 
+#ifdef CONFIG_PTRACE
+static const struct ptrace_layout_segment s390_uarea[] = {
+	{PT_PSWMASK, PT_FPC, 0, 0},
+	{PT_FPC, PT_CR_9, 1, 0},
+	{PT_CR_9, PT_IEEE_IP, 2, 0},
+	{PT_IEEE_IP, sizeof(struct user), -1, -1},
+	{0, 0, -1, 0}
+};
+
+int arch_ptrace(long *request, struct task_struct *child,
+		struct utrace_attached_engine *engine,
+		unsigned long addr, unsigned long data, long *val)
+{
+	ptrace_area parea;
+	unsigned long tmp;
+	int copied;
+
+	switch (*request) {
+	case PTRACE_PEEKUSR:
+#ifdef CONFIG_64BIT
+		/*
+		 * Stupid gdb peeks/pokes the access registers in 64 bit with
+		 * an alignment of 4. Programmers from hell...
+		 */
+		if (addr >= PT_ACR0 && addr < PT_ACR15) {
+			if (addr & 3)
+				return -EIO;
+			tmp = *(unsigned long *)
+				((char *) child->thread.acrs + addr - PT_ACR0);
+			return put_user(tmp, (unsigned long __user *) data);
+		}
+		else if (addr == PT_ACR15) {
+			/*
+			 * Very special case: old & broken 64 bit gdb reading
+			 * from acrs[15]. Result is a 64 bit value. Read the
+			 * 32 bit acrs[15] value and shift it by 32. Sick...
+			 */
+			tmp = ((unsigned long) child->thread.acrs[15]) << 32;
+			return put_user(tmp, (unsigned long __user *) data);
+		}
+#endif
+		return ptrace_peekusr(child, engine, s390_uarea, addr, data);
+	case PTRACE_POKEUSR:
+#ifdef CONFIG_64BIT
+		if (addr >= PT_ACR0 && addr < PT_ACR15) {
+			if (addr & 3)
+				return -EIO;
+			*(unsigned long *) ((char *) child->thread.acrs
+					    + addr - PT_ACR0) = data;
+			return 0;
+		}
+		else if (addr == PT_ACR15) {
+			/*
+			 * Very special case: old & broken 64 bit gdb writing
+			 * to acrs[15] with a 64 bit value. Ignore the lower
+			 * half of the value and write the upper 32 bit to
+			 * acrs[15]. Sick...
+			 */
+			child->thread.acrs[15] = data >> 32;
+			return 0;
+		}
+#endif
+		return ptrace_pokeusr(child, engine, s390_uarea, addr, data);
+
+	case PTRACE_PEEKUSR_AREA:
+	case PTRACE_POKEUSR_AREA:
+		if (copy_from_user(&parea, (ptrace_area __user *) addr,
+				   sizeof(parea)))
+			return -EFAULT;
+		if ((parea.kernel_addr | parea.len) & (sizeof(data) - 1))
+			return -EIO;
+		return ptrace_layout_access(child, engine,
+					    utrace_native_view(current),
+					    s390_uarea,
+					    parea.kernel_addr, parea.len,
+					    (void __user *) parea.process_addr,
+					    NULL,
+					    *request == PTRACE_POKEUSR_AREA);
+
+	case PTRACE_PEEKTEXT:
+	case PTRACE_PEEKDATA:
+		/* Remove high order bit from address (only for 31 bit). */
+		addr &= PSW_ADDR_INSN;
+		/* read word at location addr. */
+		copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
+		if (copied != sizeof(tmp))
+			return -EIO;
+		return put_user(tmp, (unsigned long __user *) data);
+
+	case PTRACE_POKETEXT:
+	case PTRACE_POKEDATA:
+		/* Remove high order bit from address (only for 31 bit). */
+		addr &= PSW_ADDR_INSN;
+		/* write the word at location addr. */
+		copied = access_process_vm(child, addr, &data, sizeof(data),1);
+		if (copied != sizeof(data))
+			return -EIO;
+		return 0;
+	}
+
+	return -ENOSYS;
+}
+
+#ifdef CONFIG_COMPAT
+static const struct ptrace_layout_segment s390_compat_uarea[] = {
+	{PT_PSWMASK / 2, PT_FPC / 2, 0, 0},
+	{PT_FPC / 2, PT_CR_9 / 2, 1, 0},
+	{PT_CR_9 / 2, PT_IEEE_IP / 2, 2, 0},
+	{PT_IEEE_IP / 2, sizeof(struct user32), -1, -1},
+	{0, 0, -1, 0}
+};
+
+int arch_compat_ptrace(compat_long_t *request,
+		       struct task_struct *child,
+		       struct utrace_attached_engine *engine,
+		       compat_ulong_t addr, compat_ulong_t data,
+		       compat_long_t *val)
+{
+	ptrace_area_emu31 parea;
+
+	switch (*request) {
+	case PTRACE_PEEKUSR:
+		return ptrace_compat_peekusr(child, engine, s390_compat_uarea,
+					     addr, data);
+	case PTRACE_POKEUSR:
+		return ptrace_compat_pokeusr(child, engine, s390_compat_uarea,
+					     addr, data);
+	case PTRACE_PEEKUSR_AREA:
+	case PTRACE_POKEUSR_AREA:
+		if (copy_from_user(&parea, ((ptrace_area_emu31 __user *)
+					    (unsigned long) addr),
+				   sizeof(parea)))
+			return -EFAULT;
+		if ((parea.kernel_addr | parea.len) & (sizeof(data) - 1))
+			return -EIO;
+		return ptrace_layout_access(child, engine,
+					    utrace_native_view(current),
+					    s390_compat_uarea,
+					    parea.kernel_addr, parea.len,
+					    (void __user *)
+					    (unsigned long) parea.process_addr,
+					    NULL,
+					    *request == PTRACE_POKEUSR_AREA);
+	}
+
+	return -ENOSYS;
+}
+#endif	/* CONFIG_COMPAT */
+#endif	/* CONFIG_PTRACE */
+
+
 asmlinkage void
 syscall_trace(struct pt_regs *regs, int entryexit)
 {
Index: b/arch/s390/kernel/compat_wrapper.S
===================================================================
--- a/arch/s390/kernel/compat_wrapper.S
+++ b/arch/s390/kernel/compat_wrapper.S
@@ -121,7 +121,7 @@ sys32_ptrace_wrapper:
 	lgfr	%r3,%r3			# long
 	llgtr	%r4,%r4			# long
 	llgfr	%r5,%r5			# long
-	jg	sys_ptrace		# branch to system call
+	jg	compat_sys_ptrace	# branch to system call
 
 	.globl	sys32_alarm_wrapper
 sys32_alarm_wrapper:

linux-2.6-utrace-ptrace-compat-sparc64.patch:

--- NEW FILE linux-2.6-utrace-ptrace-compat-sparc64.patch ---
[PATCH 4b] utrace: sparc64 ptrace compatibility

This patch implements ptrace compatibility for sparc64.

Signed-off-by: Roland McGrath <roland at redhat.com>
Signed-off-by: David S. Miller <davem at davemloft.net>

---

 arch/sparc64/kernel/ptrace.c |  566 +++++++------------------------------------
 1 file changed, 100 insertions(+), 466 deletions(-)

Index: b/arch/sparc64/kernel/ptrace.c
===================================================================
--- a/arch/sparc64/kernel/ptrace.c
+++ b/arch/sparc64/kernel/ptrace.c
@@ -667,484 +667,118 @@ void flush_ptrace_access(struct vm_area_
 	}
 }
 
-#if 0				/* XXX */
-asmlinkage void do_ptrace(struct pt_regs *regs)
+#ifdef CONFIG_PTRACE
+static const struct ptrace_layout_segment sparc64_getregs_layout[] = {
+	{ 0, offsetof(struct pt_regs, u_regs[15]), 0, sizeof(long) },
+	{ offsetof(struct pt_regs, u_regs[15]),
+	  offsetof(struct pt_regs, tstate),
+	  -1, 0 },
+	{ offsetof(struct pt_regs, tstate), offsetof(struct pt_regs, y),
+	  0, 32 * sizeof(long) },
+	{0, 0, -1, 0}
+};
+
+int arch_ptrace(long *request, struct task_struct *child,
+		struct utrace_attached_engine *engine,
+		unsigned long addr, unsigned long data,
+		long *retval)
 {
-	int request = regs->u_regs[UREG_I0];
-	pid_t pid = regs->u_regs[UREG_I1];
-	unsigned long addr = regs->u_regs[UREG_I2];
-	unsigned long data = regs->u_regs[UREG_I3];
-	unsigned long addr2 = regs->u_regs[UREG_I4];
-	struct task_struct *child;
-	int ret;
-
-	if (test_thread_flag(TIF_32BIT)) {
-		addr &= 0xffffffffUL;
-		data &= 0xffffffffUL;
-		addr2 &= 0xffffffffUL;
-	}
-	lock_kernel();
-#ifdef DEBUG_PTRACE
-	{
-		char *s;
-
-		if ((request >= 0) && (request <= 24))
-			s = pt_rq [request];
-		else
-			s = "unknown";
-
-		if (request == PTRACE_POKEDATA && data == 0x91d02001){
-			printk ("do_ptrace: breakpoint pid=%d, addr=%016lx addr2=%016lx\n",
-				pid, addr, addr2);
-		} else 
-			printk("do_ptrace: rq=%s(%d) pid=%d addr=%016lx data=%016lx addr2=%016lx\n",
-			       s, request, pid, addr, data, addr2);
-	}
-#endif
-	if (request == PTRACE_TRACEME) {
-		ret = ptrace_traceme();
-		if (ret < 0)
-			pt_error_return(regs, -ret);
-		else
-			pt_succ_return(regs, 0);
-		goto out;
-	}
-
-	child = ptrace_get_task_struct(pid);
-	if (IS_ERR(child)) {
-		ret = PTR_ERR(child);
-		pt_error_return(regs, -ret);
-		goto out;
-	}
-
-	if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH)
-	    || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) {
-		if (ptrace_attach(child)) {
-			pt_error_return(regs, EPERM);
-			goto out_tsk;
-		}
-		pt_succ_return(regs, 0);
-		goto out_tsk;
-	}
-
-	ret = ptrace_check_attach(child, request == PTRACE_KILL);
-	if (ret < 0) {
-		pt_error_return(regs, -ret);
-		goto out_tsk;
-	}
-
-	if (!(test_thread_flag(TIF_32BIT))	&&
-	    ((request == PTRACE_READDATA64)		||
-	     (request == PTRACE_WRITEDATA64)		||
-	     (request == PTRACE_READTEXT64)		||
-	     (request == PTRACE_WRITETEXT64)		||
-	     (request == PTRACE_PEEKTEXT64)		||
-	     (request == PTRACE_POKETEXT64)		||
-	     (request == PTRACE_PEEKDATA64)		||
-	     (request == PTRACE_POKEDATA64))) {
-		addr = regs->u_regs[UREG_G2];
-		addr2 = regs->u_regs[UREG_G3];
-		request -= 30; /* wheee... */
-	}
-
-	switch(request) {
-	case PTRACE_PEEKUSR:
-		if (addr != 0)
-			pt_error_return(regs, EIO);
-		else
-			pt_succ_return(regs, 0);
-		goto out_tsk;
-
-	case PTRACE_PEEKTEXT: /* read word at location addr. */ 
-	case PTRACE_PEEKDATA: {
-		unsigned long tmp64;
-		unsigned int tmp32;
-		int res, copied;
-
-		res = -EIO;
-		if (test_thread_flag(TIF_32BIT)) {
-			copied = access_process_vm(child, addr,
-						   &tmp32, sizeof(tmp32), 0);
-			tmp64 = (unsigned long) tmp32;
-			if (copied == sizeof(tmp32))
-				res = 0;
-		} else {
-			copied = access_process_vm(child, addr,
-						   &tmp64, sizeof(tmp64), 0);
-			if (copied == sizeof(tmp64))
-				res = 0;
-		}
-		if (res < 0)
-			pt_error_return(regs, -res);
-		else
-			pt_os_succ_return(regs, tmp64, (void __user *) data);
-		goto out_tsk;
-	}
-
-	case PTRACE_POKETEXT: /* write the word at location addr. */
-	case PTRACE_POKEDATA: {
-		unsigned long tmp64;
-		unsigned int tmp32;
-		int copied, res = -EIO;
-
-		if (test_thread_flag(TIF_32BIT)) {
-			tmp32 = data;
-			copied = access_process_vm(child, addr,
-						   &tmp32, sizeof(tmp32), 1);
-			if (copied == sizeof(tmp32))
-				res = 0;
-		} else {
-			tmp64 = data;
-			copied = access_process_vm(child, addr,
-						   &tmp64, sizeof(tmp64), 1);
-			if (copied == sizeof(tmp64))
-				res = 0;
-		}
-		if (res < 0)
-			pt_error_return(regs, -res);
-		else
-			pt_succ_return(regs, res);
-		goto out_tsk;
-	}
-
-	case PTRACE_GETREGS: {
-		struct pt_regs32 __user *pregs =
-			(struct pt_regs32 __user *) addr;
-		struct pt_regs *cregs = task_pt_regs(child);
-		int rval;
-
-		if (__put_user(tstate_to_psr(cregs->tstate), (&pregs->psr)) ||
-		    __put_user(cregs->tpc, (&pregs->pc)) ||
-		    __put_user(cregs->tnpc, (&pregs->npc)) ||
-		    __put_user(cregs->y, (&pregs->y))) {
-			pt_error_return(regs, EFAULT);
-			goto out_tsk;
-		}
-		for (rval = 1; rval < 16; rval++)
-			if (__put_user(cregs->u_regs[rval], (&pregs->u_regs[rval - 1]))) {
-				pt_error_return(regs, EFAULT);
-				goto out_tsk;
-			}
-		pt_succ_return(regs, 0);
-#ifdef DEBUG_PTRACE
-		printk ("PC=%lx nPC=%lx o7=%lx\n", cregs->tpc, cregs->tnpc, cregs->u_regs [15]);
-#endif
-		goto out_tsk;
-	}
-
-	case PTRACE_GETREGS64: {
-		struct pt_regs __user *pregs = (struct pt_regs __user *) addr;
-		struct pt_regs *cregs = task_pt_regs(child);
-		unsigned long tpc = cregs->tpc;
-		int rval;
-
-		if ((task_thread_info(child)->flags & _TIF_32BIT) != 0)
-			tpc &= 0xffffffff;
-		if (__put_user(cregs->tstate, (&pregs->tstate)) ||
-		    __put_user(tpc, (&pregs->tpc)) ||
-		    __put_user(cregs->tnpc, (&pregs->tnpc)) ||
-		    __put_user(cregs->y, (&pregs->y))) {
-			pt_error_return(regs, EFAULT);
-			goto out_tsk;
-		}
-		for (rval = 1; rval < 16; rval++)
-			if (__put_user(cregs->u_regs[rval], (&pregs->u_regs[rval - 1]))) {
-				pt_error_return(regs, EFAULT);
-				goto out_tsk;
-			}
-		pt_succ_return(regs, 0);
-#ifdef DEBUG_PTRACE
-		printk ("PC=%lx nPC=%lx o7=%lx\n", cregs->tpc, cregs->tnpc, cregs->u_regs [15]);
-#endif
-		goto out_tsk;
-	}
-
-	case PTRACE_SETREGS: {
-		struct pt_regs32 __user *pregs =
-			(struct pt_regs32 __user *) addr;
-		struct pt_regs *cregs = task_pt_regs(child);
-		unsigned int psr, pc, npc, y;
-		int i;
-
-		/* Must be careful, tracing process can only set certain
-		 * bits in the psr.
-		 */
-		if (__get_user(psr, (&pregs->psr)) ||
-		    __get_user(pc, (&pregs->pc)) ||
-		    __get_user(npc, (&pregs->npc)) ||
-		    __get_user(y, (&pregs->y))) {
-			pt_error_return(regs, EFAULT);
-			goto out_tsk;
-		}
-		cregs->tstate &= ~(TSTATE_ICC);
-		cregs->tstate |= psr_to_tstate_icc(psr);
-               	if (!((pc | npc) & 3)) {
-			cregs->tpc = pc;
-			cregs->tnpc = npc;
-		}
-		cregs->y = y;
-		for (i = 1; i < 16; i++) {
-			if (__get_user(cregs->u_regs[i], (&pregs->u_regs[i-1]))) {
-				pt_error_return(regs, EFAULT);
-				goto out_tsk;
-			}
-		}
-		pt_succ_return(regs, 0);
-		goto out_tsk;
-	}
-
-	case PTRACE_SETREGS64: {
-		struct pt_regs __user *pregs = (struct pt_regs __user *) addr;
-		struct pt_regs *cregs = task_pt_regs(child);
-		unsigned long tstate, tpc, tnpc, y;
-		int i;
-
-		/* Must be careful, tracing process can only set certain
-		 * bits in the psr.
-		 */
-		if (__get_user(tstate, (&pregs->tstate)) ||
-		    __get_user(tpc, (&pregs->tpc)) ||
-		    __get_user(tnpc, (&pregs->tnpc)) ||
-		    __get_user(y, (&pregs->y))) {
-			pt_error_return(regs, EFAULT);
-			goto out_tsk;
-		}
-		if ((task_thread_info(child)->flags & _TIF_32BIT) != 0) {
-			tpc &= 0xffffffff;
-			tnpc &= 0xffffffff;
-		}
-		tstate &= (TSTATE_ICC | TSTATE_XCC);
-		cregs->tstate &= ~(TSTATE_ICC | TSTATE_XCC);
-		cregs->tstate |= tstate;
-		if (!((tpc | tnpc) & 3)) {
-			cregs->tpc = tpc;
-			cregs->tnpc = tnpc;
-		}
-		cregs->y = y;
-		for (i = 1; i < 16; i++) {
-			if (__get_user(cregs->u_regs[i], (&pregs->u_regs[i-1]))) {
-				pt_error_return(regs, EFAULT);
-				goto out_tsk;
-			}
-		}
-		pt_succ_return(regs, 0);
-		goto out_tsk;
-	}
-
-	case PTRACE_GETFPREGS: {
-		struct fps {
-			unsigned int regs[32];
-			unsigned int fsr;
-			unsigned int flags;
-			unsigned int extra;
-			unsigned int fpqd;
-			struct fq {
-				unsigned int insnaddr;
-				unsigned int insn;
-			} fpq[16];
-		};
-		struct fps __user *fps = (struct fps __user *) addr;
-		unsigned long *fpregs = task_thread_info(child)->fpregs;
-
-		if (copy_to_user(&fps->regs[0], fpregs,
-				 (32 * sizeof(unsigned int))) ||
-		    __put_user(task_thread_info(child)->xfsr[0], (&fps->fsr)) ||
-		    __put_user(0, (&fps->fpqd)) ||
-		    __put_user(0, (&fps->flags)) ||
-		    __put_user(0, (&fps->extra)) ||
-		    clear_user(&fps->fpq[0], 32 * sizeof(unsigned int))) {
-			pt_error_return(regs, EFAULT);
-			goto out_tsk;
-		}
-		pt_succ_return(regs, 0);
-		goto out_tsk;
-	}
-
-	case PTRACE_GETFPREGS64: {
-		struct fps {
-			unsigned int regs[64];
-			unsigned long fsr;
-		};
-		struct fps __user *fps = (struct fps __user *) addr;
-		unsigned long *fpregs = task_thread_info(child)->fpregs;
-
-		if (copy_to_user(&fps->regs[0], fpregs,
-				 (64 * sizeof(unsigned int))) ||
-		    __put_user(task_thread_info(child)->xfsr[0], (&fps->fsr))) {
-			pt_error_return(regs, EFAULT);
-			goto out_tsk;
-		}
-		pt_succ_return(regs, 0);
-		goto out_tsk;
-	}
-
-	case PTRACE_SETFPREGS: {
-		struct fps {
-			unsigned int regs[32];
-			unsigned int fsr;
-			unsigned int flags;
-			unsigned int extra;
-			unsigned int fpqd;
-			struct fq {
-				unsigned int insnaddr;
-				unsigned int insn;
-			} fpq[16];
-		};
-		struct fps __user *fps = (struct fps __user *) addr;
-		unsigned long *fpregs = task_thread_info(child)->fpregs;
-		unsigned fsr;
-
-		if (copy_from_user(fpregs, &fps->regs[0],
-				   (32 * sizeof(unsigned int))) ||
-		    __get_user(fsr, (&fps->fsr))) {
-			pt_error_return(regs, EFAULT);
-			goto out_tsk;
-		}
-		task_thread_info(child)->xfsr[0] &= 0xffffffff00000000UL;
-		task_thread_info(child)->xfsr[0] |= fsr;
-		if (!(task_thread_info(child)->fpsaved[0] & FPRS_FEF))
-			task_thread_info(child)->gsr[0] = 0;
-		task_thread_info(child)->fpsaved[0] |= (FPRS_FEF | FPRS_DL);
-		pt_succ_return(regs, 0);
-		goto out_tsk;
-	}
-
-	case PTRACE_SETFPREGS64: {
-		struct fps {
-			unsigned int regs[64];
-			unsigned long fsr;
-		};
-		struct fps __user *fps = (struct fps __user *) addr;
-		unsigned long *fpregs = task_thread_info(child)->fpregs;
-
-		if (copy_from_user(fpregs, &fps->regs[0],
-				   (64 * sizeof(unsigned int))) ||
-		    __get_user(task_thread_info(child)->xfsr[0], (&fps->fsr))) {
-			pt_error_return(regs, EFAULT);
-			goto out_tsk;
-		}
-		if (!(task_thread_info(child)->fpsaved[0] & FPRS_FEF))
-			task_thread_info(child)->gsr[0] = 0;
-		task_thread_info(child)->fpsaved[0] |= (FPRS_FEF | FPRS_DL | FPRS_DU);
-		pt_succ_return(regs, 0);
-		goto out_tsk;
-	}
+	void __user *uaddr = (void __user *) addr;
+	struct pt_regs *uregs = uaddr;
+	int err = -ENOSYS;
+
+	switch (*request) {
+	case PTRACE_GETREGS64:
+		err = ptrace_layout_access(child, engine,
+					   &utrace_sparc64_native_view,
+					   sparc64_getregs_layout,
+					   0, offsetof(struct pt_regs, y),
+					   uaddr, NULL, 0);
+		if (!err &&
+		    (put_user(task_pt_regs(child)->y, &uregs->y) ||
+		     put_user(task_pt_regs(child)->fprs, &uregs->fprs)))
+			err = -EFAULT;
+		break;
 
-	case PTRACE_READTEXT:
-	case PTRACE_READDATA: {
-		int res = ptrace_readdata(child, addr,
-					  (char __user *)addr2, data);
-		if (res == data) {
-			pt_succ_return(regs, 0);
-			goto out_tsk;
-		}
-		if (res >= 0)
-			res = -EIO;
-		pt_error_return(regs, -res);
-		goto out_tsk;
-	}
+	case PTRACE_SETREGS64:
+		err = ptrace_layout_access(child, engine,
+					   &utrace_sparc64_native_view,
+					   sparc64_getregs_layout,
+					   0, offsetof(struct pt_regs, y),
+					   uaddr, NULL, 1);
+		if (!err &&
+		    (get_user(task_pt_regs(child)->y, &uregs->y) ||
+		     get_user(task_pt_regs(child)->fprs, &uregs->fprs)))
+			err = -EFAULT;
+		break;
 
-	case PTRACE_WRITETEXT:
-	case PTRACE_WRITEDATA: {
-		int res = ptrace_writedata(child, (char __user *) addr2,
-					   addr, data);
-		if (res == data) {
-			pt_succ_return(regs, 0);
-			goto out_tsk;
-		}
-		if (res >= 0)
-			res = -EIO;
-		pt_error_return(regs, -res);
-		goto out_tsk;
-	}
-	case PTRACE_SYSCALL: /* continue and stop at (return from) syscall */
-		addr = 1;
+	case PTRACE_GETFPREGS64:
+	case PTRACE_SETFPREGS64:
+		err = ptrace_regset_access(child, engine,
+					   utrace_native_view(current),
+					   2, 0, 34 * sizeof(long), uaddr,
+					   (*request == PTRACE_SETFPREGS64));
+		break;
 
-	case PTRACE_CONT: { /* restart after signal. */
-		if (!valid_signal(data)) {
-			pt_error_return(regs, EIO);
-			goto out_tsk;
-		}
-
-		if (request == PTRACE_SYSCALL) {
-			set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-		} else {
-			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-		}
-
-		child->exit_code = data;
-#ifdef DEBUG_PTRACE
-		printk("CONT: %s [%d]: set exit_code = %x %lx %lx\n", child->comm,
-			child->pid, child->exit_code,
-			task_pt_regs(child)->tpc,
-			task_pt_regs(child)->tnpc);
-		       
-#endif
-		wake_up_process(child);
-		pt_succ_return(regs, 0);
-		goto out_tsk;
-	}
+	case PTRACE_SUNDETACH:
+		*request = PTRACE_DETACH;
+		break;
 
-/*
- * make the child exit.  Best I can do is send it a sigkill. 
- * perhaps it should be put in the status that it wants to 
- * exit.
- */
-	case PTRACE_KILL: {
-		if (child->exit_state == EXIT_ZOMBIE) {	/* already dead */
-			pt_succ_return(regs, 0);
-			goto out_tsk;
-		}
-		child->exit_code = SIGKILL;
-		wake_up_process(child);
-		pt_succ_return(regs, 0);
-		goto out_tsk;
-	}
+	default:
+		break;
+	};
+	return err;
+}
 
-	case PTRACE_SUNDETACH: { /* detach a process that was attached. */
-		int error = ptrace_detach(child, data);
-		if (error) {
-			pt_error_return(regs, EIO);
-			goto out_tsk;
-		}
-		pt_succ_return(regs, 0);
-		goto out_tsk;
-	}
+#ifdef CONFIG_COMPAT
+static const struct ptrace_layout_segment sparc32_getregs_layout[] = {
+	{ 0, offsetof(struct pt_regs32, u_regs[0]),
+	  0, GENREG32_PSR * sizeof(u32) },
+	{ offsetof(struct pt_regs32, u_regs[0]),
+	  offsetof(struct pt_regs32, u_regs[15]),
+	  0, 1 * sizeof(u32) },
+	{ offsetof(struct pt_regs32, u_regs[15]), sizeof(struct pt_regs32),
+	  -1, 0 },
+	{0, 0, -1, 0}
+};
+
+int arch_compat_ptrace(compat_long_t *request, struct task_struct *child,
+		       struct utrace_attached_engine *engine,
+		       compat_ulong_t addr, compat_ulong_t data,
+		       compat_long_t *retval)
+{
+	void __user *uaddr = (void __user *) (unsigned long) addr;
+	int err = -ENOSYS;
 
-	/* PTRACE_DUMPCORE unsupported... */
+	switch (*request) {
+	case PTRACE_GETREGS:
+	case PTRACE_SETREGS:
+		err = ptrace_layout_access(child, engine,
+					   &utrace_sparc32_view,
+					   sparc32_getregs_layout,
+					   0, sizeof(struct pt_regs32),
+					   uaddr, NULL,
+					   (*request ==
+					    PTRACE_SETREGS));
+		break;
 
-	case PTRACE_GETEVENTMSG: {
-		int err;
+	case PTRACE_GETFPREGS:
+	case PTRACE_SETFPREGS:
+		err = ptrace_whole_regset(child, engine, addr, 1,
+					  (*request == PTRACE_SETFPREGS));
+		break;
 
-		if (test_thread_flag(TIF_32BIT))
-			err = put_user(child->ptrace_message,
-				       (unsigned int __user *) data);
-		else
-			err = put_user(child->ptrace_message,
-				       (unsigned long __user *) data);
-		if (err)
-			pt_error_return(regs, -err);
-		else
-			pt_succ_return(regs, 0);
+	case PTRACE_SUNDETACH:
+		*request = PTRACE_DETACH;
 		break;
-	}
 
-	default: {
-		int err = ptrace_request(child, request, addr, data);
-		if (err)
-			pt_error_return(regs, -err);
-		else
-			pt_succ_return(regs, 0);
-		goto out_tsk;
-	}
-	}
-out_tsk:
-	if (child)
-		put_task_struct(child);
-out:
-	unlock_kernel();
+	default:
+		break;
+	};
+	return err;
 }
-#endif
+#endif	/* CONFIG_COMPAT */
+#endif /* CONFIG_PTRACE */
 
 asmlinkage void syscall_trace(struct pt_regs *regs, int syscall_exit_p)
 {

linux-2.6-utrace-ptrace-compat-xen.patch:

--- NEW FILE linux-2.6-utrace-ptrace-compat-xen.patch ---
Index: patching/arch/x86_64/ia32/ia32entry-xen.S
===================================================================
--- patching.orig/arch/x86_64/ia32/ia32entry-xen.S
+++ patching/arch/x86_64/ia32/ia32entry-xen.S
@@ -448,7 +448,7 @@ ia32_sys_call_table:
 	.quad sys_setuid16
 	.quad sys_getuid16
 	.quad compat_sys_stime	/* stime */		/* 25 */
-	.quad sys32_ptrace	/* ptrace */
+	.quad compat_sys_ptrace	/* ptrace */
 	.quad sys_alarm
 	.quad sys_fstat	/* (old)fstat */
 	.quad sys_pause

linux-2.6-utrace-ptrace-compat.patch:

--- NEW FILE linux-2.6-utrace-ptrace-compat.patch ---
[PATCH 4] utrace: ptrace compatibility

ptrace compatibility on top of <linux/utrace.h> interfaces.
This attempts to be precisely compatible with existing ptrace behavior.
It does not extend, improve, or change it.

The ptrace support is made an option, CONFIG_PTRACE.  For now, noone will
want to turn this off except maybe a bizarre embedded configuration.  But
it looks forward to a day when we can punt the ptrace system call completely.

Signed-off-by: Roland McGrath <roland at redhat.com>

---

 arch/i386/kernel/ptrace.c       |   40 
 arch/powerpc/kernel/ptrace.c    |  250 ++++
 arch/powerpc/kernel/signal_32.c |   52 +
 arch/powerpc/lib/sstep.c        |    3 
 arch/x86_64/ia32/ia32entry.S    |    2 
 arch/x86_64/ia32/ptrace32.c     |   56 -
 arch/x86_64/kernel/ptrace.c     |   46 
 fs/proc/base.c                  |   40 
 include/asm-x86_64/ptrace-abi.h |    3 
 include/asm-x86_64/tracehook.h  |    1 
 include/linux/ptrace.h          |  221 +++-
 include/linux/sched.h           |    4 
 init/Kconfig                    |   15 
 kernel/Makefile                 |    3 
 kernel/exit.c                   |   13 
 kernel/fork.c                   |    2 
 kernel/ptrace.c                 | 2046 +++++++++++++++++++++++++++++++++++++---
 kernel/sys_ni.c                 |    4 
 18 files changed, 2627 insertions(+), 174 deletions(-)

Index: b/fs/proc/base.c
===================================================================
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -148,6 +148,46 @@ static int get_nr_threads(struct task_st
 	return count;
 }
 
+static int __ptrace_may_attach(struct task_struct *task)
+{
+	/* May we inspect the given task?
+	 * This check is used both for attaching with ptrace
+	 * and for allowing access to sensitive information in /proc.
+	 *
+	 * ptrace_attach denies several cases that /proc allows
+	 * because setting up the necessary parent/child relationship
+	 * or halting the specified task is impossible.
+	 */
+	int dumpable = 0;
+	/* Don't let security modules deny introspection */
+	if (task == current)
+		return 0;
+	if (((current->uid != task->euid) ||
+	     (current->uid != task->suid) ||
+	     (current->uid != task->uid) ||
+	     (current->gid != task->egid) ||
+	     (current->gid != task->sgid) ||
+	     (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
+		return -EPERM;
+	smp_rmb();
+	if (task->mm)
+		dumpable = task->mm->dumpable;
+	if (!dumpable && !capable(CAP_SYS_PTRACE))
+		return -EPERM;
+
+	return security_ptrace(current, task);
+}
+
+int ptrace_may_attach(struct task_struct *task)
+{
+	int err;
+	task_lock(task);
+	err = __ptrace_may_attach(task);
+	task_unlock(task);
+	return !err;
+}
+
+
 static int proc_cwd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
 {
 	struct task_struct *task = get_proc_task(inode);
Index: b/arch/i386/kernel/ptrace.c
===================================================================
--- a/arch/i386/kernel/ptrace.c
+++ b/arch/i386/kernel/ptrace.c
@@ -736,6 +736,46 @@ const struct utrace_regset_view *utrace_
 	return &utrace_i386_native;
 }
 
+#ifdef CONFIG_PTRACE
+static const struct ptrace_layout_segment i386_uarea[] = {
+	{0, FRAME_SIZE*4, 0, 0},
+	{FRAME_SIZE*4, offsetof(struct user, u_debugreg[0]), -1, 0},
+	{offsetof(struct user, u_debugreg[0]),
+	 offsetof(struct user, u_debugreg[8]), 4, 0},
+	{0, 0, -1, 0}
+};
+
+int arch_ptrace(long *req, struct task_struct *child,
+		struct utrace_attached_engine *engine,
+		unsigned long addr, unsigned long data, long *val)
+{
+	switch (*req) {
+	case PTRACE_PEEKUSR:
+		return ptrace_peekusr(child, engine, i386_uarea, addr, data);
+	case PTRACE_POKEUSR:
+		return ptrace_pokeusr(child, engine, i386_uarea, addr, data);
+	case PTRACE_GETREGS:
+		return ptrace_whole_regset(child, engine, data, 0, 0);
+	case PTRACE_SETREGS:
+		return ptrace_whole_regset(child, engine, data, 0, 1);
+	case PTRACE_GETFPREGS:
+		return ptrace_whole_regset(child, engine, data, 1, 0);
+	case PTRACE_SETFPREGS:
+		return ptrace_whole_regset(child, engine, data, 1, 1);
+	case PTRACE_GETFPXREGS:
+		return ptrace_whole_regset(child, engine, data, 2, 0);
+	case PTRACE_SETFPXREGS:
+		return ptrace_whole_regset(child, engine, data, 2, 1);
+	case PTRACE_GET_THREAD_AREA:
+	case PTRACE_SET_THREAD_AREA:
+		return ptrace_onereg_access(child, engine,
+					    utrace_native_view(current), 3,
+					    addr, (void __user *)data,
+					    *req == PTRACE_SET_THREAD_AREA);
+	}
+	return -ENOSYS;
+}
+#endif
 
 void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code)
 {
Index: b/arch/x86_64/ia32/ptrace32.c
===================================================================
--- a/arch/x86_64/ia32/ptrace32.c
+++ b/arch/x86_64/ia32/ptrace32.c
@@ -166,11 +166,6 @@ static int getreg32(struct task_struct *
 
 #undef R32
 
-asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data)
-{
-	return -ENOSYS;
-}
-
 static int
 ia32_genregs_get(struct task_struct *target,
 		 const struct utrace_regset *regset,
@@ -600,3 +595,54 @@ const struct utrace_regset_view utrace_i
 	.name = "i386", .e_machine = EM_386,
 	.regsets = ia32_regsets, .n = ARRAY_SIZE(ia32_regsets)
 };
+
+
+#ifdef CONFIG_PTRACE
+/*
+ * This matches the arch/i386/kernel/ptrace.c definitions.
+ */
+
+static const struct ptrace_layout_segment ia32_uarea[] = {
+	{0, sizeof(struct user_regs_struct32), 0, 0},
+	{sizeof(struct user_regs_struct32),
+	 offsetof(struct user32, u_debugreg[0]), -1, 0},
+	{offsetof(struct user32, u_debugreg[0]),
+	 offsetof(struct user32, u_debugreg[8]), 4, 0},
+	{0, 0, -1, 0}
+};
+
+int arch_compat_ptrace(compat_long_t *req, struct task_struct *child,
+		       struct utrace_attached_engine *engine,
+		       compat_ulong_t addr, compat_ulong_t data,
+		       compat_long_t *val)
+{
+	switch (*req) {
+	case PTRACE_PEEKUSR:
+		return ptrace_compat_peekusr(child, engine, ia32_uarea,
+					     addr, data);
+	case PTRACE_POKEUSR:
+		return ptrace_compat_pokeusr(child, engine, ia32_uarea,
+					     addr, data);
+	case PTRACE_GETREGS:
+		return ptrace_whole_regset(child, engine, data, 0, 0);
+	case PTRACE_SETREGS:
+		return ptrace_whole_regset(child, engine, data, 0, 1);
+	case PTRACE_GETFPREGS:
+		return ptrace_whole_regset(child, engine, data, 1, 0);
+	case PTRACE_SETFPREGS:
+		return ptrace_whole_regset(child, engine, data, 1, 1);
+	case PTRACE_GETFPXREGS:
+		return ptrace_whole_regset(child, engine, data, 2, 0);
+	case PTRACE_SETFPXREGS:
+		return ptrace_whole_regset(child, engine, data, 2, 1);
+	case PTRACE_GET_THREAD_AREA:
+	case PTRACE_SET_THREAD_AREA:
+		return ptrace_onereg_access(child, engine,
[...2747 lines suppressed...]
+/*
+ * Convenience wrapper for doing access to a whole utrace_regset for ptrace.
+ */
+static inline int ptrace_whole_regset(struct task_struct *child,
+				      struct utrace_attached_engine *engine,
+				      long data, int setno, int write)
+{
+	return ptrace_regset_access(child, engine, utrace_native_view(current),
+				    setno, 0, -1, (void __user *)data, write);
+}
+
+/*
+ * Convenience function doing access to a single slot in a utrace_regset.
+ * The regno value gives a slot number plus regset->bias.
+ * The value accessed is regset->size bytes long.
+ */
+extern int ptrace_onereg_access(struct task_struct *child,
+				struct utrace_attached_engine *engine,
+				const struct utrace_regset_view *view,
+				int setno, unsigned long regno,
+				void __user *data, int write);
+
+
+/*
+ * An array of these describes the layout of the virtual struct user
+ * accessed by PEEKUSR/POKEUSR, or the structure used by GETREGS et al.
+ * The array is terminated by an element with .end of zero.
+ * An element describes the range [.start, .end) of struct user offsets,
+ * measured in bytes; it maps to the regset in the view's regsets array
+ * at the index given by .regset, at .offset bytes into that regset's data.
+ * If .regset is -1, then the [.start, .end) range reads as zero
+ * if .offset is zero, and is skipped on read (user's buffer unchanged)
+ * if .offset is -1.
+ */
+struct ptrace_layout_segment {
+	unsigned int start, end, regset, offset;
+};
+
+/*
+ * Convenience function for doing access to a ptrace compatibility layout.
+ * The offset and size are in bytes.
+ */
+extern int ptrace_layout_access(struct task_struct *child,
+				struct utrace_attached_engine *engine,
+				const struct utrace_regset_view *view,
+				const struct ptrace_layout_segment layout[],
+				unsigned long offset, unsigned int size,
+				void __user *data, void *kdata, int write);
+
+
+/* Convenience wrapper for the common PTRACE_PEEKUSR implementation.  */
+static inline int ptrace_peekusr(struct task_struct *child,
+				 struct utrace_attached_engine *engine,
+				 const struct ptrace_layout_segment layout[],
+				 unsigned long addr, long data)
+{
+	return ptrace_layout_access(child, engine, utrace_native_view(current),
+				    layout, addr, sizeof(long),
+				    (unsigned long __user *)data, NULL, 0);
+}
+
+/* Convenience wrapper for the common PTRACE_PEEKUSR implementation.  */
+static inline int ptrace_pokeusr(struct task_struct *child,
+				 struct utrace_attached_engine *engine,
+				 const struct ptrace_layout_segment layout[],
+				 unsigned long addr, long data)
+{
+	return ptrace_layout_access(child, engine, utrace_native_view(current),
+				    layout, addr, sizeof(long),
+				    NULL, &data, 1);
+}
+
+/*
+ * Called in copy_process.
+ */
+static inline void ptrace_init_task(struct task_struct *tsk)
+{
+	INIT_LIST_HEAD(&tsk->ptracees);
+}
+
+/*
+ * Called in do_exit, after setting PF_EXITING, no locks are held.
+ */
+void ptrace_exit(struct task_struct *tsk);
+
+/*
+ * Called in do_wait, with tasklist_lock held for reading.
+ * This reports any ptrace-child that is ready as do_wait would a normal child.
+ * If there are no ptrace children, returns -ECHILD.
+ * If there are some ptrace children but none reporting now, returns 0.
+ * In those cases the tasklist_lock is still held so next_thread(tsk) works.
+ * For any other return value, tasklist_lock is released before return.
+ */
+int ptrace_do_wait(struct task_struct *tsk,
+		   pid_t pid, int options, struct siginfo __user *infop,
+		   int __user *stat_addr, struct rusage __user *rusagep);
+
+
+#ifdef CONFIG_COMPAT
+#include <linux/compat.h>
+
+extern int arch_compat_ptrace(compat_long_t *request,
+			      struct task_struct *child,
+			      struct utrace_attached_engine *engine,
+			      compat_ulong_t a, compat_ulong_t d,
+			      compat_long_t *retval);
+
+/* Convenience wrapper for the common PTRACE_PEEKUSR implementation.  */
+static inline int ptrace_compat_peekusr(
+	struct task_struct *child, struct utrace_attached_engine *engine,
+	const struct ptrace_layout_segment layout[],
+	compat_ulong_t addr, compat_ulong_t data)
+{
+	compat_ulong_t *udata = (compat_ulong_t __user *) (unsigned long) data;
+	return ptrace_layout_access(child, engine, utrace_native_view(current),
+				    layout, addr, sizeof(compat_ulong_t),
+				    udata, NULL, 0);
+}
+
+/* Convenience wrapper for the common PTRACE_PEEKUSR implementation.  */
+static inline int ptrace_compat_pokeusr(
+	struct task_struct *child, struct utrace_attached_engine *engine,
+	const struct ptrace_layout_segment layout[],
+	compat_ulong_t addr, compat_ulong_t data)
+{
+	return ptrace_layout_access(child, engine, utrace_native_view(current),
+				    layout, addr, sizeof(compat_ulong_t),
+				    NULL, &data, 1);
+}
+#endif	/* CONFIG_COMPAT */
+
+#else  /* no CONFIG_PTRACE */
+static inline void ptrace_init_task(struct task_struct *tsk) { }
+static inline void ptrace_exit(struct task_struct *tsk) { }
+static inline int ptrace_do_wait(struct task_struct *tsk,
+				 pid_t pid, int options,
+				 struct siginfo __user *infop,
+				 int __user *stat_addr,
+				 struct rusage __user *rusagep)
+{
+	return -ECHILD;
+}
+#endif	/* CONFIG_PTRACE */
+
+
 #ifndef force_successful_syscall_return
 /*
  * System call handlers that, upon successful completion, need to return a
Index: b/include/asm-x86_64/tracehook.h
===================================================================
--- a/include/asm-x86_64/tracehook.h
+++ b/include/asm-x86_64/tracehook.h
@@ -15,6 +15,7 @@
 
 #include <linux/sched.h>
 #include <asm/ptrace.h>
+#include <asm/proto.h>
 
 /*
  * See linux/tracehook.h for the descriptions of what these need to do.
Index: b/include/asm-x86_64/ptrace-abi.h
===================================================================
--- a/include/asm-x86_64/ptrace-abi.h
+++ b/include/asm-x86_64/ptrace-abi.h
@@ -48,4 +48,7 @@
 
 #define PTRACE_ARCH_PRCTL	  30	/* arch_prctl for child */
 
+#define PTRACE_SYSEMU		  31
+#define PTRACE_SYSEMU_SINGLESTEP  32
+
 #endif
Index: b/init/Kconfig
===================================================================
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -597,10 +597,21 @@ endmenu
 
 menu "Process debugging support"
 
+config PTRACE
+	bool "Legacy ptrace system call interface"
+	default y
+	select UTRACE
+	depends on PROC_FS
+	help
+	  Enable the ptrace system call.
+	  This is traditionally used by debuggers like GDB,
+	  and is used by UML and some other applications.
+	  Unless you are very sure you won't run anything that needs it,
+	  say Y.
+
 config UTRACE
 	bool "Infrastructure for tracing and debugging user processes"
-	default y
-	depends on MODULES
+	default y if MODULES || PTRACE
 	help
 	  Enable the utrace process tracing interface.
 	  This is an internal kernel interface to track events in user

linux-2.6-utrace-recalc_sigpending_and_wake.patch:

--- NEW FILE linux-2.6-utrace-recalc_sigpending_and_wake.patch ---
>From 7bb44adef39ad3bda2be40bb34686bc56bd563a5 Mon Sep 17 00:00:00 2001
From: Roland McGrath <roland at redhat.com>
Date: Wed, 23 May 2007 13:57:44 -0700
Subject: [PATCH] recalc_sigpending_tsk fixes

Steve Hawkes discovered a problem where recalc_sigpending_tsk was called in
do_sigaction but no signal_wake_up call was made, preventing later signals
from waking up blocked threads with TIF_SIGPENDING already set.

In fact, the few other calls to recalc_sigpending_tsk outside the signals
code are also subject to this problem in other race conditions.

This change makes recalc_sigpending_tsk private to the signals code.  It
changes the outside calls, as well as do_sigaction, to use the new
recalc_sigpending_and_wake instead.

Signed-off-by: Roland McGrath <roland at redhat.com>
Cc: <Steve.Hawkes at motorola.com>
Cc: Oleg Nesterov <oleg at tv-sign.ru>
Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
---
 include/linux/sched.h  |   12 +++++++-----
 kernel/exit.c          |    7 ++-----
 kernel/power/process.c |    2 +-
 kernel/signal.c        |   24 ++++++++++++++++++------
 4 files changed, 28 insertions(+), 17 deletions(-)

diff --git a/include/linux/sched.h b/include/linux/sched.h
index 870b75e..d58e74b 100644  
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1616,11 +1616,13 @@ static inline int lock_need_resched(spin
 	return 0;
 }
 
-/* Reevaluate whether the task has signals pending delivery.
-   This is required every time the blocked sigset_t changes.
-   callers must hold sighand->siglock.  */
-
-extern FASTCALL(void recalc_sigpending_tsk(struct task_struct *t));
+/*
+ * Reevaluate whether the task has signals pending delivery.
+ * Wake the task if so.
+ * This is required every time the blocked sigset_t changes.
+ * callers must hold sighand->siglock.
+ */
+extern void recalc_sigpending_and_wake(struct task_struct *t);
 extern void recalc_sigpending(void);
 
 extern void signal_wake_up(struct task_struct *t, int resume_stopped);
diff --git a/kernel/exit.c b/kernel/exit.c
index c6d14b8..5b888c2 100644  
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -762,11 +762,8 @@ static void exit_notify(struct task_stru
 		read_lock(&tasklist_lock);
 		spin_lock_irq(&tsk->sighand->siglock);
 		for (t = next_thread(tsk); t != tsk; t = next_thread(t))
-			if (!signal_pending(t) && !(t->flags & PF_EXITING)) {
-				recalc_sigpending_tsk(t);
-				if (signal_pending(t))
-					signal_wake_up(t, 0);
-			}
+			if (!signal_pending(t) && !(t->flags & PF_EXITING))
+				recalc_sigpending_and_wake(t);
 		spin_unlock_irq(&tsk->sighand->siglock);
 		read_unlock(&tasklist_lock);
 	}
diff --git a/kernel/power/process.c b/kernel/power/process.c
index d31d638..e0233d8 100644  
--- a/kernel/power/process.c
+++ b/kernel/power/process.c
@@ -101,7 +101,7 @@ static void cancel_freezing(struct task_
 		pr_debug("  clean up: %s\n", p->comm);
 		do_not_freeze(p);
 		spin_lock_irqsave(&p->sighand->siglock, flags);
-		recalc_sigpending_tsk(p);
+		recalc_sigpending_and_wake(p);
 		spin_unlock_irqrestore(&p->sighand->siglock, flags);
 	}
 }
diff --git a/kernel/signal.c b/kernel/signal.c
index 364fc95..acdfc05 100644  
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -96,15 +96,27 @@ static inline int has_pending_signals(si
 
 #define PENDING(p,b) has_pending_signals(&(p)->signal, (b))
 
-fastcall void recalc_sigpending_tsk(struct task_struct *t)
+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))
+	    PENDING(&t->signal->shared_pending, &t->blocked)) {
 		set_tsk_thread_flag(t, TIF_SIGPENDING);
-	else
-		clear_tsk_thread_flag(t, TIF_SIGPENDING);
+		return 1;
+	}
+	clear_tsk_thread_flag(t, TIF_SIGPENDING);
+	return 0;
+}
+
+/*
+ * After recalculating TIF_SIGPENDING, we need to make sure the task wakes up.
+ * This is superfluous when called on current, the wakeup is a harmless no-op.
+ */
+void recalc_sigpending_and_wake(struct task_struct *t)
+{
+	if (recalc_sigpending_tsk(t))
+		signal_wake_up(t, 0);
 }
 
 void recalc_sigpending(void)
@@ -744,7 +756,7 @@ force_sig_info(int sig, struct siginfo *
 		action->sa.sa_handler = SIG_DFL;
 		if (blocked) {
 			sigdelset(&t->blocked, sig);
-			recalc_sigpending_tsk(t);
+			recalc_sigpending_and_wake(t);
 		}
 	}
 	ret = specific_send_sig_info(sig, info, t);
@@ -2273,7 +2285,7 @@ int do_sigaction(int sig, struct k_sigac
 			rm_from_queue_full(&mask, &t->signal->shared_pending);
 			do {
 				rm_from_queue_full(&mask, &t->pending);
-				recalc_sigpending_tsk(t);
+				recalc_sigpending_and_wake(t);
 				t = next_thread(t);
 			} while (t != current);
 		}
-- 
1.5.0.6


linux-2.6-utrace-regset-avr32.patch:

--- NEW FILE linux-2.6-utrace-regset-avr32.patch ---
[PATCH 2d] utrace: avr32 regset support

From: Haavard Skinnemoen <hskinnemoen at atmel.com>

Rip out most of the ptrace code for AVR32 and replace it with the much
nicer utrace stuff.

CC: Haavard Skinnemoen <hskinnemoen at atmel.com>
Signed-off-by: Roland McGrath <roland at redhat.com>

---

 arch/avr32/kernel/ptrace.c |  109 ++++++++++++++++++--------------------------
 1 files changed, 44 insertions(+), 65 deletions(-)

--- linux-2.6/arch/avr32/kernel/ptrace.c
+++ linux-2.6/arch/avr32/kernel/ptrace.c
@@ -14,94 +14,73 @@
 #include <linux/ptrace.h>
 #include <linux/errno.h>
 #include <linux/user.h>
+#include <linux/tracehook.h>
 
+#include <asm/tracehook.h>
 #include <asm/mmu_context.h>
 #include <linux/kdebug.h>
 
+#ifdef CONFIG_UTRACE
+
 static struct pt_regs *get_user_regs(struct task_struct *tsk)
 {
 	return (struct pt_regs *)((unsigned long)task_stack_page(tsk) +
 				  THREAD_SIZE - sizeof(struct pt_regs));
 }
 
-#if 0
-/*
- * Read the word at offset "offset" into the task's "struct user". We
- * actually access the pt_regs struct stored on the kernel stack.
- */
-static int ptrace_read_user(struct task_struct *tsk, unsigned long offset,
-			    unsigned long __user *data)
+static int genregs_get(struct task_struct *target,
+		       const struct utrace_regset *regset,
+		       unsigned int pos, unsigned int count,
+		       void *kbuf, void __user *ubuf)
 {
-	unsigned long *regs;
-	unsigned long value;
-
-	pr_debug("ptrace_read_user(%p, %#lx, %p)\n",
-		 tsk, offset, data);
-
-	if (offset & 3 || offset >= sizeof(struct user)) {
-		printk("ptrace_read_user: invalid offset 0x%08lx\n", offset);
-		return -EIO;
-	}
+	struct pt_regs *regs = get_user_regs(target);
 
-	regs = (unsigned long *)get_user_regs(tsk);
-
-	value = 0;
-	if (offset < sizeof(struct pt_regs))
-		value = regs[offset / sizeof(regs[0])];
-
-	return put_user(value, data);
+	return utrace_regset_copyout(&pos, &count, &kbuf, &ubuf,
+				     regs, 0, -1);
 }
 
-/*
- * Write the word "value" to offset "offset" into the task's "struct
- * user". We actually access the pt_regs struct stored on the kernel
- * stack.
- */
-static int ptrace_write_user(struct task_struct *tsk, unsigned long offset,
-			     unsigned long value)
+static int genregs_set(struct task_struct *target,
+		       const struct utrace_regset *regset,
+		       unsigned int pos, unsigned int count,
+		       const void *kbuf, const void __user *ubuf)
 {
-	unsigned long *regs;
-
-	if (offset & 3 || offset >= sizeof(struct user)) {
-		printk("ptrace_write_user: invalid offset 0x%08lx\n", offset);
-		return -EIO;
-	}
-
-	if (offset >= sizeof(struct pt_regs))
-		return 0;
+	struct pt_regs *regs = get_user_regs(target);
 
-	regs = (unsigned long *)get_user_regs(tsk);
-	regs[offset / sizeof(regs[0])] = value;
-
-	return 0;
+	return utrace_regset_copyin(&pos, &count, &kbuf, &ubuf,
+				    regs, 0, -1);
 }
 
-static int ptrace_getregs(struct task_struct *tsk, void __user *uregs)
-{
-	struct pt_regs *regs = get_user_regs(tsk);
+static const struct utrace_regset native_regsets[] = {
+	{
+		.core_note_type = NT_PRSTATUS,
+		.n	= ELF_NGREG,
+		.size	= sizeof(long),
+		.align	= sizeof(long),
+		.get	= genregs_get,
+		.set	= genregs_set,
+	},
+	/*
+	 * Other register sets that probably would make sense:
+	 *   - Coprocessor registers (8 coprocs with 16 registers each)
+	 *   - TLS stuff
+	 */
+};
 
-	return copy_to_user(uregs, regs, sizeof(*regs)) ? -EFAULT : 0;
-}
+static const struct utrace_regset_view utrace_avr32_native_view = {
+	.name		= UTS_MACHINE,
+	.e_machine	= ELF_ARCH,
+	.regsets	= native_regsets,
+	.n		= ARRAY_SIZE(native_regsets),
+};
 
-static int ptrace_setregs(struct task_struct *tsk, const void __user *uregs)
+const struct utrace_regset_view *utrace_native_view(struct task_struct *tsk)
 {
-	struct pt_regs newregs;
-	int ret;
-
-	ret = -EFAULT;
-	if (copy_from_user(&newregs, uregs, sizeof(newregs)) == 0) {
-		struct pt_regs *regs = get_user_regs(tsk);
-
-		ret = -EINVAL;
-		if (valid_user_regs(&newregs)) {
-			*regs = newregs;
-			ret = 0;
-		}
-	}
-
-	return ret;
+	return &utrace_avr32_native_view;
 }
+#endif /* CONFIG_UTRACE */
+
 
+#if 0
 long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 {
 	int ret;

linux-2.6-utrace-regset-ia64.patch:

--- NEW FILE linux-2.6-utrace-regset-ia64.patch ---
[PATCH 2a] utrace: ia64 regset support

This patch converts the machine-dependent ptrace code into utrace regset
support for ia64.

Signed-off-by: Roland McGrath <roland at redhat.com>
CC: Anil S Keshavamurthy <anil.s.keshavamurthy at intel.com>
Signed-off-by: Bibo Mao <bibo.mao at intel.com>

---

 arch/ia64/ia32/sys_ia32.c    |  472 +++++++++++++++++++++++++
 arch/ia64/kernel/ptrace.c    |  804 +++++++++++++++++++++++++++++++++++++++++++
 include/asm-ia64/elf.h       |   24 +
 include/asm-ia64/tracehook.h |    7 
 4 files changed, 1305 insertions(+), 2 deletions(-)

Index: b/arch/ia64/ia32/sys_ia32.c
===================================================================
--- a/arch/ia64/ia32/sys_ia32.c
+++ b/arch/ia64/ia32/sys_ia32.c
@@ -44,6 +44,7 @@
 #include <linux/eventpoll.h>
 #include <linux/personality.h>
 #include <linux/ptrace.h>
+#include <linux/tracehook.h>
 #include <linux/stat.h>
 #include <linux/ipc.h>
 #include <linux/capability.h>
@@ -1868,6 +1869,477 @@ sys32_ptrace (int request, pid_t pid, un
 }
 #endif
 
+#ifdef CONFIG_UTRACE
+typedef struct utrace_get {
+	void *kbuf;
+	void __user *ubuf;
+} utrace_get_t;
+
+typedef struct utrace_set {
+	const void *kbuf;
+	const void __user *ubuf;
+} utrace_set_t;
+
+typedef struct utrace_getset {
+	struct task_struct *target;
+	const struct utrace_regset *regset;
+	union {
+		utrace_get_t get;
+		utrace_set_t set;
+	} u;
+	unsigned int pos;
+	unsigned int count;
+	int ret;
+} utrace_getset_t;
+
+static void getfpreg(struct task_struct *task, int regno,int *val)
+{
+	switch (regno / sizeof(int)) {
+		case 0: *val = task->thread.fcr & 0xffff; break;
+		case 1: *val = task->thread.fsr & 0xffff; break;
+		case 2: *val = (task->thread.fsr>>16) & 0xffff; break;
+		case 3: *val = task->thread.fir; break;
+		case 4: *val = (task->thread.fir>>32) & 0xffff; break;
+		case 5: *val = task->thread.fdr; break;
+		case 6: *val = (task->thread.fdr >> 32) & 0xffff; break;
+	}
+}
+
+static void setfpreg(struct task_struct *task, int regno, int val)
+{
+	switch (regno / sizeof(int)) {
+		case 0:
+			task->thread.fcr = (task->thread.fcr & (~0x1f3f))
+				| (val & 0x1f3f);
+			break;
+		case 1:
+			task->thread.fsr = (task->thread.fsr & (~0xffff)) | val;
+			break;
+		case 2:
+			task->thread.fsr = (task->thread.fsr & (~0xffff0000))
+				| (val << 16);
+			break;
+		case 3:
+			task->thread.fir = (task->thread.fir & (~0xffffffff)) | val;
+			break;
+		case 5:
+			task->thread.fdr = (task->thread.fdr & (~0xffffffff)) | val;
+			break;
+	}
+}
+
+static void access_fpreg_ia32(int regno, void *reg,
+		struct pt_regs *pt, struct switch_stack *sw,
+		int tos, int write)
+{
+	void *f;
+
+	if ((regno += tos) >= 8)
+		regno -= 8;
+	if (regno <= 4)
+		f = &pt->f8 + regno;
+	else if (regno <= 7)
+		f = &sw->f12 + (regno - 4);
+	else {
+		printk(" regno must be less than 7 \n");
+		 return;
+	}
+
+	if (write)
+		memcpy(f, reg, sizeof(struct _fpreg_ia32));
+	else
+		memcpy(reg, f, sizeof(struct _fpreg_ia32));
+}
+
+static void do_fpregs_get(struct unw_frame_info *info, void *arg)
+{
+	utrace_getset_t *dst = arg;
+	struct task_struct *task = dst->target;
+	struct pt_regs *pt;
+	int start, end, tos;
+	char buf[80];
+
+	if (dst->count == 0 || unw_unwind_to_user(info) < 0)
+		return;
+	if (dst->pos < 7 * sizeof(int)) {
+		end = min((dst->pos + dst->count), (unsigned int)(7 * sizeof(int)));
+		for (start = dst->pos; start < end; start += sizeof(int))
+			getfpreg(task, start,(int *)( buf + start));
+		dst->ret = utrace_regset_copyout(&dst->pos, &dst->count,
+				&dst->u.get.kbuf, &dst->u.get.ubuf, buf,
+				0, 7 * sizeof(int));
+		if (dst->ret || dst->count == 0)
+			return;
+	}
+	if (dst->pos < sizeof(struct ia32_user_i387_struct)) {
+		pt = task_pt_regs(task);
+		tos = (task->thread.fsr >> 11) & 7;
+		end = min(dst->pos + dst->count,
+				(unsigned int)(sizeof(struct ia32_user_i387_struct)));
+		start = (dst->pos - 7 * sizeof(int)) / sizeof(struct _fpreg_ia32);
+		end = (end - 7 * sizeof(int)) / sizeof(struct _fpreg_ia32);
+		for (; start < end; start++)
+			access_fpreg_ia32(start, (struct _fpreg_ia32 *)buf + start,
+					pt, info->sw, tos, 0);
+		dst->ret = utrace_regset_copyout(&dst->pos, &dst->count,
+				&dst->u.get.kbuf, &dst->u.get.ubuf,
+				buf, 7 * sizeof(int),
+				sizeof(struct ia32_user_i387_struct));
+		if (dst->ret || dst->count == 0)
+			return;
+	}
+}
+
+static void do_fpregs_set(struct unw_frame_info *info, void *arg)
+{
+	utrace_getset_t *dst = arg;
+	struct task_struct *task = dst->target;
+	struct pt_regs *pt;
+	char buf[80];
+	int end, start, tos;
+
+	if (dst->count == 0 || unw_unwind_to_user(info) < 0)
+		return;
+
+	if (dst->pos < 7 * sizeof(int)) {
+		start = dst->pos;
+		dst->ret = utrace_regset_copyin(&dst->pos, &dst->count,
+				&dst->u.set.kbuf, &dst->u.set.ubuf, buf,
+				0, 7 * sizeof(int));
+		if (dst->ret)
+			return;
+		for (; start < dst->pos; start += sizeof(int))
+			setfpreg(task, start, *((int*)(buf + start)));
+		if (dst->count == 0)
+			return;
+	}
+	if (dst->pos < sizeof(struct ia32_user_i387_struct)) {
+		start = (dst->pos - 7 * sizeof(int)) / sizeof(struct _fpreg_ia32);
+		dst->ret = utrace_regset_copyin(&dst->pos, &dst->count,
+				&dst->u.set.kbuf, &dst->u.set.ubuf,
+				buf, 7 * sizeof(int),
+				sizeof(struct ia32_user_i387_struct));
+		if (dst->ret)
+			return;
+		pt = task_pt_regs(task);
+		tos = (task->thread.fsr >> 11) & 7;
+		end = (dst->pos - 7 * sizeof(int)) / sizeof(struct _fpreg_ia32);
+		for (; start < end; start++)
+			access_fpreg_ia32(start, (struct _fpreg_ia32 *)buf + start,
+					pt, info->sw, tos, 0);
+		if (dst->count == 0)
+			return;
+	}
+}
+
+#define OFFSET(member) ((int)(offsetof(struct ia32_user_fxsr_struct, member)))
+static void getfpxreg(struct task_struct *task, int start, int end, char *buf)
+{
+	int min_val;
+
+	min_val = min(end, OFFSET(fop));
+	while (start < min_val) {
+		if (start == OFFSET(cwd))
+			*((short *)buf) = task->thread.fcr & 0xffff;
+		else if (start == OFFSET(swd))
+			*((short *)buf) = task->thread.fsr & 0xffff;
+		else if (start == OFFSET(twd))
+			*((short *)buf) = (task->thread.fsr>>16) & 0xffff;
+		buf += 2;
+		start += 2;
+	}
+	/* skip fop element */
+	if (start == OFFSET(fop)) {
+		start += 2;
+		buf += 2;
+	}
+	while (start < end) {
+		if (start == OFFSET(fip))
+			*((int *)buf) = task->thread.fir;
+		else if (start == OFFSET(fcs))
+			*((int *)buf) = (task->thread.fir>>32) & 0xffff;
+		else if (start == OFFSET(foo))
+			*((int *)buf) = task->thread.fdr;
+		else if (start == OFFSET(fos))
+			*((int *)buf) = (task->thread.fdr>>32) & 0xffff;
+		else if (start == OFFSET(mxcsr))
+			*((int *)buf) = ((task->thread.fcr>>32) & 0xff80)
+					 | ((task->thread.fsr>>32) & 0x3f);
+		buf += 4;
+		start += 4;
+	}
+}
+
+static void setfpxreg(struct task_struct *task, int start, int end, char *buf)
+{
+	int min_val, num32;
+	short num;
+	unsigned long num64;
+
+	min_val = min(end, OFFSET(fop));
+	while (start < min_val) {
+		num = *((short *)buf);
+		if (start == OFFSET(cwd)) {
+			task->thread.fcr = (task->thread.fcr & (~0x1f3f))
+						| (num & 0x1f3f);
+		} else if (start == OFFSET(swd)) {
+			task->thread.fsr = (task->thread.fsr & (~0xffff)) | num;
+		} else if (start == OFFSET(twd)) {
+			task->thread.fsr = (task->thread.fsr & (~0xffff0000)) | num;
+		}
+		buf += 2;
+		start += 2;
+	}
+	/* skip fop element */
+	if (start == OFFSET(fop)) {
+		start += 2;
+		buf += 2;
+	}
+	while (start < end) {
+		num32 = *((int *)buf);
+		if (start == OFFSET(fip))
+			task->thread.fir = (task->thread.fir & (~0xffffffff))
+						 | num32;
+		else if (start == OFFSET(foo))
+			task->thread.fdr = (task->thread.fdr & (~0xffffffff))
+						 | num32;
+		else if (start == OFFSET(mxcsr)) {
+			num64 = num32 & 0xff10;
+			task->thread.fcr = (task->thread.fcr & (~0xff1000000000UL))
+						 | (num64<<32);
+			num64 = num32 & 0x3f;
+			task->thread.fsr = (task->thread.fsr & (~0x3f00000000UL))
+						 | (num64<<32);
+		}
+		buf += 4;
+		start += 4;
+	}
+}
+
+static void do_fpxregs_get(struct unw_frame_info *info, void *arg)
+{
+	utrace_getset_t *dst = arg;
+	struct task_struct *task = dst->target;
+	struct pt_regs *pt;
+	char buf[128];
+	int start, end, tos;
+
+	if (dst->count == 0 || unw_unwind_to_user(info) < 0)
+		return;
+	if (dst->pos < OFFSET(st_space[0])) {
+		end = min(dst->pos + dst->count, (unsigned int)32);
+		getfpxreg(task, dst->pos, end, buf);
+		dst->ret = utrace_regset_copyout(&dst->pos, &dst->count,
+				&dst->u.get.kbuf, &dst->u.get.ubuf, buf,
+				0, OFFSET(st_space[0]));
+		if (dst->ret || dst->count == 0)
+			return;
+	}
+	if (dst->pos < OFFSET(xmm_space[0])) {
+		pt = task_pt_regs(task);
+		tos = (task->thread.fsr >> 11) & 7;
+		end = min(dst->pos + dst->count,
+				(unsigned int)OFFSET(xmm_space[0]));
+		start = (dst->pos - OFFSET(st_space[0])) / 16;
+		end = (end - OFFSET(st_space[0])) / 16;
+		for (; start < end; start++)
+			access_fpreg_ia32(start, buf + 16 * start, pt,
+						info->sw, tos, 0);
+		dst->ret = utrace_regset_copyout(&dst->pos, &dst->count,
+				&dst->u.get.kbuf, &dst->u.get.ubuf,
+				buf, OFFSET(st_space[0]), OFFSET(xmm_space[0]));
+		if (dst->ret || dst->count == 0)
+			return;
+	}
+	if (dst->pos < OFFSET(padding[0]))
+		dst->ret = utrace_regset_copyout(&dst->pos, &dst->count,
+				&dst->u.get.kbuf, &dst->u.get.ubuf,
+				&info->sw->f16, OFFSET(xmm_space[0]),
+				OFFSET(padding[0]));
+}
+
+static void do_fpxregs_set(struct unw_frame_info *info, void *arg)
+{
+	utrace_getset_t *dst = arg;
+	struct task_struct *task = dst->target;
+	char buf[128];
+	int start, end;
+
+	if (dst->count == 0 || unw_unwind_to_user(info) < 0)
+		return;
+
+	if (dst->pos < OFFSET(st_space[0])) {
+		start = dst->pos;
+		dst->ret = utrace_regset_copyin(&dst->pos, &dst->count,
+				&dst->u.set.kbuf, &dst->u.set.ubuf,
+				buf, 0, OFFSET(st_space[0]));
+		if (dst->ret)
+			return;
+		setfpxreg(task, start, dst->pos, buf);
+		if (dst->count == 0)
+			return;
+	}
+	if (dst->pos < OFFSET(xmm_space[0])) {
+		struct pt_regs *pt;
+		int tos;
+		pt = task_pt_regs(task);
+		tos = (task->thread.fsr >> 11) & 7;
+		start = (dst->pos - OFFSET(st_space[0])) / 16;
+		dst->ret = utrace_regset_copyin(&dst->pos, &dst->count,
+				&dst->u.set.kbuf, &dst->u.set.ubuf,
+				buf, OFFSET(st_space[0]), OFFSET(xmm_space[0]));
+		if (dst->ret)
+			return;
+		end = (dst->pos - OFFSET(st_space[0])) / 16;
+		for (; start < end; start++)
+			access_fpreg_ia32(start, buf + 16 * start, pt, info->sw,
+						 tos, 1);
+		if (dst->count == 0)
+			return;
+	}
+	if (dst->pos < OFFSET(padding[0]))
+		dst->ret = utrace_regset_copyin(&dst->pos, &dst->count,
+				&dst->u.set.kbuf, &dst->u.set.ubuf,
+				&info->sw->f16, OFFSET(xmm_space[0]),
+				 OFFSET(padding[0]));
+}
+#undef OFFSET
+
+static int do_regset_call(void (*call)(struct unw_frame_info *, void *),
+		struct task_struct *target,
+		const struct utrace_regset *regset,
+		unsigned int pos, unsigned int count,
+		const void *kbuf, const void __user *ubuf)
+{
+	utrace_getset_t info = { .target = target, .regset = regset,
+		.pos = pos, .count = count,
+		.u.set = { .kbuf = kbuf, .ubuf = ubuf },
+		.ret = 0 };
+
+	if (target == current)
+		unw_init_running(call, &info);
+	else {
+		struct unw_frame_info ufi;
+		memset(&ufi, 0, sizeof(ufi));
+		unw_init_from_blocked_task(&ufi, target);
+		(*call)(&ufi, &info);
+	}
+
+	return info.ret;
+}
+
+static int ia32_fpregs_get(struct task_struct *target,
+		const struct utrace_regset *regset,
+		unsigned int pos, unsigned int count,
+		void *kbuf, void __user *ubuf)
+{
+	return do_regset_call(do_fpregs_get, target, regset, pos, count, kbuf, ubuf);
+}
+
+static int ia32_fpregs_set(struct task_struct *target,
+		const struct utrace_regset *regset,
+		unsigned int pos, unsigned int count,
+		const void *kbuf, const void __user *ubuf)
+{
+	return do_regset_call(do_fpregs_set, target, regset, pos, count, kbuf, ubuf);
+}
+
+static int ia32_fpxregs_get(struct task_struct *target,
+		const struct utrace_regset *regset,
+		unsigned int pos, unsigned int count,
+		void *kbuf, void __user *ubuf)
+{
+	return do_regset_call(do_fpxregs_get, target, regset, pos, count, kbuf, ubuf);
+}
+
+static int ia32_fpxregs_set(struct task_struct *target,
+		const struct utrace_regset *regset,
+		unsigned int pos, unsigned int count,
+		const void *kbuf, const void __user *ubuf)
+{
+	return do_regset_call(do_fpxregs_set, target, regset, pos, count, kbuf, ubuf);
+}
+
+static int ia32_genregs_get(struct task_struct *target,
+		const struct utrace_regset *regset,
+		unsigned int pos, unsigned int count,
+		void *kbuf, void __user *ubuf)
+{
+	if (kbuf) {
+		u32 *kp = kbuf;
+		while (count > 0) {
+			*kp++ = getreg(target, pos);
+			pos += 4;
+			count -= 4;
+		}
+	} else {
+		u32 __user *up = ubuf;
+		while (count > 0) {
+			if (__put_user(getreg(target, pos), up++))
+				return -EFAULT;
+			pos += 4;
+			count -= 4;
+		}
+	}
+	return 0;
+}
+
+static int ia32_genregs_set(struct task_struct *target,
+		const struct utrace_regset *regset,
+		unsigned int pos, unsigned int count,
+		const void *kbuf, const void __user *ubuf)
+{
+	int ret = 0;
+
+	if (kbuf) {
+		const u32 *kp = kbuf;
+		while (!ret && count > 0) {
+			putreg(target, pos, *kp++);
+			pos += 4;
+			count -= 4;
+		}
+	} else {
+		const u32 __user *up = ubuf;
+		u32 val;
+		while (!ret && count > 0) {
+			ret = __get_user(val, up++);
+			if (!ret)
+				putreg(target, pos, val);
+			pos += 4;
+			count -= 4;
+		}
+	}
+	return ret;
+}
+
+/*
+ * This should match arch/i386/kernel/ptrace.c:native_regsets.
+ * XXX ioperm? vm86?
+ */
+static const struct utrace_regset ia32_regsets[] = {
+	{
+		.n = sizeof(struct user_regs_struct32)/4,
+		.size = 4, .align = 4,
+		.get = ia32_genregs_get, .set = ia32_genregs_set
+	},
+	{
+		.n = sizeof(struct ia32_user_i387_struct) / 4,
+		.size = 4, .align = 4,
+		.get = ia32_fpregs_get, .set = ia32_fpregs_set
+	},
+	{
+		.n = sizeof(struct ia32_user_fxsr_struct) / 4,
+		.size = 4, .align = 4,
+		.get = ia32_fpxregs_get, .set = ia32_fpxregs_set
+	},
+};
+
+const struct utrace_regset_view utrace_ia32_view = {
+	.name = "i386", .e_machine = EM_386,
+	.regsets = ia32_regsets, .n = ARRAY_SIZE(ia32_regsets)
+};
+#endif
+
 typedef struct {
 	unsigned int	ss_sp;
 	unsigned int	ss_flags;
Index: b/arch/ia64/kernel/ptrace.c
===================================================================
--- a/arch/ia64/kernel/ptrace.c
+++ b/arch/ia64/kernel/ptrace.c
@@ -3,6 +3,9 @@
  *
  * Copyright (C) 1999-2005 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm at hpl.hp.com>
+ * Copyright (C) 2006 Intel Co
+ *  2006-08-12	- IA64 Native Utrace implementation support added by
+ *	Anil S Keshavamurthy <anil.s.keshavamurthy at intel.com>
  *
  * Derived from the x86 and Alpha versions.
  */
@@ -18,13 +21,16 @@
 #include <linux/security.h>
 #include <linux/audit.h>
 #include <linux/signal.h>
+#include <linux/module.h>
 
+#include <asm/tracehook.h>
 #include <asm/pgtable.h>
 #include <asm/processor.h>
 #include <asm/ptrace_offsets.h>
 #include <asm/rse.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
+#include <asm/elf.h>
 #include <asm/unwind.h>
 #ifdef CONFIG_PERFMON
 #include <asm/perfmon.h>
@@ -548,6 +554,7 @@ ia64_sync_user_rbs (struct task_struct *
 	return 0;
 }
 
+#if 0				/* XXX */
 static inline int
 thread_matches (struct task_struct *thread, unsigned long addr)
 {
@@ -620,6 +627,7 @@ find_thread_for_addr (struct task_struct
 	mmput(mm);
 	return child;
 }
+#endif
 
 /*
  * Write f32-f127 back to task->thread.fph if it has been modified.
@@ -664,6 +672,7 @@ ia64_sync_fph (struct task_struct *task)
 	psr->dfh = 1;
 }
 
+#if 0
 static int
 access_fr (struct unw_frame_info *info, int regnum, int hi,
 	   unsigned long *data, int write_access)
@@ -682,6 +691,7 @@ access_fr (struct unw_frame_info *info, 
 		*data = fpval.u.bits[hi];
 	return ret;
 }
+#endif /* access_fr() */
 
 /*
  * Change the machine-state of CHILD such that it will return via the normal
@@ -782,6 +792,7 @@ access_nat_bits (struct task_struct *chi
 	return 0;
 }
 
+#if 0
 static int
 access_uarea (struct task_struct *child, unsigned long addr,
 	      unsigned long *data, int write_access)
@@ -1248,7 +1259,9 @@ ptrace_getregs (struct task_struct *chil
 	ret = retval ? -EIO : 0;
 	return ret;
 }
+#endif /* ptrace_getregs() */
 
+#if 0
 static long
 ptrace_setregs (struct task_struct *child, struct pt_all_user_regs __user *ppr)
 {
@@ -1394,6 +1407,7 @@ ptrace_setregs (struct task_struct *chil
 	ret = retval ? -EIO : 0;
 	return ret;
 }
+#endif /* ptrace_setregs() */
 
 /*
  * Called by kernel/ptrace.c when detaching..
@@ -1411,6 +1425,7 @@ ptrace_disable (struct task_struct *chil
 	child_psr->tb = 0;
 }
 
+#if 0 				/* XXX */
 asmlinkage long
 sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data)
 {
@@ -1598,6 +1613,7 @@ sys_ptrace (long request, pid_t pid, uns
 	unlock_kernel();
 	return ret;
 }
+#endif
 
 /* "asmlinkage" so the input arguments are preserved... */
 
@@ -1650,3 +1666,791 @@ syscall_trace_leave (long arg0, long arg
 		tracehook_report_syscall_step(&regs);
 	}
 }
+
+/* Utrace implementation starts here */
+
+typedef struct utrace_get {
+	void *kbuf;
+	void __user *ubuf;
+} utrace_get_t;
+
+typedef struct utrace_set {
+	const void *kbuf;
+	const void __user *ubuf;
+} utrace_set_t;
+
+typedef struct utrace_getset {
+	struct task_struct *target;
+	const struct utrace_regset *regset;
+	union {
+		utrace_get_t get;
+		utrace_set_t set;
+	} u;
+	unsigned int pos;
+	unsigned int count;
+	int ret;
+} utrace_getset_t;
+
+static int
+access_elf_gpreg(struct task_struct *target, struct unw_frame_info *info,
+		unsigned long addr, unsigned long *data, int write_access)
+{
+	struct pt_regs *pt;
+	unsigned long *ptr = NULL;
+	int ret;
+	char nat=0;
+
+	pt = task_pt_regs(target);
+	switch (addr) {
+		case ELF_GR_OFFSET(1):
+			ptr = &pt->r1;
+			break;
+		case ELF_GR_OFFSET(2):
+		case ELF_GR_OFFSET(3):
+			ptr = (void *)&pt->r2 + (addr - ELF_GR_OFFSET(2));
+			break;
+		case ELF_GR_OFFSET(4) ... ELF_GR_OFFSET(7):
+			if (write_access) {
+				/* read NaT bit first: */
+				unsigned long dummy;
+
+				ret = unw_get_gr(info, addr/8, &dummy, &nat);
+				if (ret < 0)
+					return ret;
+			}
+			return unw_access_gr(info, addr/8, data, &nat, write_access);
+		case ELF_GR_OFFSET(8) ... ELF_GR_OFFSET(11):
+			ptr = (void *)&pt->r8 + addr - ELF_GR_OFFSET(8);
+			break;
+		case ELF_GR_OFFSET(12):
+		case ELF_GR_OFFSET(13):
+			ptr = (void *)&pt->r12 + addr - ELF_GR_OFFSET(12);
+			break;
+		case ELF_GR_OFFSET(14):
+			ptr = &pt->r14;
+			break;
+		case ELF_GR_OFFSET(15):
+			ptr = &pt->r15;
+	}
+	if (write_access)
+		*ptr = *data;
+	else
+		*data = *ptr;
+	return 0;
+}
+
+static int
+access_elf_breg(struct task_struct *target, struct unw_frame_info *info,
+		unsigned long addr, unsigned long *data, int write_access)
+{
+	struct pt_regs *pt;
+	unsigned long *ptr = NULL;
+
+	pt = task_pt_regs(target);
+	switch (addr) {
+		case ELF_BR_OFFSET(0):
+			ptr = &pt->b0;
+			break;
+		case ELF_BR_OFFSET(1) ... ELF_BR_OFFSET(5):
+			return unw_access_br(info, (addr - ELF_BR_OFFSET(0))/8,
+					data, write_access);
+		case ELF_BR_OFFSET(6):
+			ptr = &pt->b6;
+			break;
+		case ELF_BR_OFFSET(7):
+			ptr = &pt->b7;
+	}
+	if (write_access)
+		*ptr = *data;
+	else
+		*data = *ptr;
+	return 0;
+}
+
+static int
+access_elf_areg(struct task_struct *target, struct unw_frame_info *info,
+		unsigned long addr, unsigned long *data, int write_access)
+{
+	struct pt_regs *pt;
+	unsigned long cfm, urbs_end, rnat_addr;
+	unsigned long *ptr = NULL;
+
+	pt = task_pt_regs(target);
+	if (addr >= ELF_AR_RSC_OFFSET && addr <= ELF_AR_SSD_OFFSET) {
+		switch (addr) {
+			case ELF_AR_RSC_OFFSET:
+				/* force PL3 */
+				if (write_access)
+					pt->ar_rsc = *data | (3 << 2);
+				else
+					*data = pt->ar_rsc;
+				return 0;
+			case ELF_AR_BSP_OFFSET:
+				/*
+				 * By convention, we use PT_AR_BSP to refer to
+				 * the end of the user-level backing store.
+				 * Use ia64_rse_skip_regs(PT_AR_BSP, -CFM.sof)
+				 * to get the real value of ar.bsp at the time
+				 * the kernel was entered.
+				 *
+				 * Furthermore, when changing the contents of
+				 * PT_AR_BSP (or PT_CFM) we MUST copy any
+				 * users-level stacked registers that are
+				 * stored on the kernel stack back to
+				 * user-space because otherwise, we might end
+				 * up clobbering kernel stacked registers.
+				 * Also, if this happens while the task is
+				 * blocked in a system call, which convert the
+				 * state such that the non-system-call exit
+				 * path is used.  This ensures that the proper
+				 * state will be picked up when resuming
+				 * execution.  However, it *also* means that
+				 * once we write PT_AR_BSP/PT_CFM, it won't be
+				 * possible to modify the syscall arguments of
+				 * the pending system call any longer.  This
+				 * shouldn't be an issue because modifying
+				 * PT_AR_BSP/PT_CFM generally implies that
+				 * we're either abandoning the pending system
+				 * call or that we defer it's re-execution
+				 * (e.g., due to GDB doing an inferior
+				 * function call).
+				 */
+				urbs_end = ia64_get_user_rbs_end(target, pt, &cfm);
+				if (write_access) {
+					if (*data != urbs_end) {
+						if (ia64_sync_user_rbs(target, info->sw,
+									pt->ar_bspstore,
+									urbs_end) < 0)
+							return -1;
+						if (in_syscall(pt))
+							convert_to_non_syscall(target,
+									pt,
+									cfm);
+						/*
+						 * Simulate user-level write
+						 * of ar.bsp:
+						 */
+						pt->loadrs = 0;
+						pt->ar_bspstore = *data;
+					}
+				} else
+					*data = urbs_end;
+				return 0;
+			case ELF_AR_BSPSTORE_OFFSET: // ar_bsp_store
+				ptr = &pt->ar_bspstore;
+				break;
+			case ELF_AR_RNAT_OFFSET:  // ar_rnat
+				urbs_end = ia64_get_user_rbs_end(target, pt, NULL);
+				rnat_addr = (long) ia64_rse_rnat_addr((long *)
+						urbs_end);
+				if (write_access)
+					return ia64_poke(target, info->sw, urbs_end,
+							rnat_addr, *data);
+				else
+					return ia64_peek(target, info->sw, urbs_end,
+							rnat_addr, data);
+			case ELF_AR_CCV_OFFSET:   // ar_ccv
+				ptr = &pt->ar_ccv;
+				break;
+			case ELF_AR_UNAT_OFFSET:	// ar_unat
+				ptr = &pt->ar_unat;
+				break;
+			case ELF_AR_FPSR_OFFSET:  // ar_fpsr
+				ptr = &pt->ar_fpsr;
+				break;
+			case ELF_AR_PFS_OFFSET:  // ar_pfs
+				ptr = &pt->ar_pfs;
+				break;
+			case ELF_AR_LC_OFFSET:   // ar_lc
+				return unw_access_ar(info, UNW_AR_LC, data,
+						write_access);
+			case ELF_AR_EC_OFFSET:    // ar_ec
+				return unw_access_ar(info, UNW_AR_EC, data,
+						write_access);
+			case ELF_AR_CSD_OFFSET:   // ar_csd
+				ptr = &pt->ar_csd;
+				break;
+			case ELF_AR_SSD_OFFSET:   // ar_ssd
+				ptr = &pt->ar_ssd;
+		}
+	} else if (addr >= ELF_CR_IIP_OFFSET && addr <= ELF_CR_IPSR_OFFSET) {
+		switch (addr) {
+			case ELF_CR_IIP_OFFSET:
+				ptr = &pt->cr_iip;
+				break;
+			case ELF_CFM_OFFSET:
+				urbs_end = ia64_get_user_rbs_end(target, pt, &cfm);
+				if (write_access) {
+					if (((cfm ^ *data) & PFM_MASK) != 0) {
+						if (ia64_sync_user_rbs(target, info->sw,
+									pt->ar_bspstore,
+									urbs_end) < 0)
+							return -1;
+						if (in_syscall(pt))
+							convert_to_non_syscall(target,
+									pt,
+									cfm);
+						pt->cr_ifs = ((pt->cr_ifs & ~PFM_MASK)
+								| (*data & PFM_MASK));
+					}
+				} else
+					*data = cfm;
+				return 0;
+			case ELF_CR_IPSR_OFFSET:
+				if (write_access)
+					pt->cr_ipsr = ((*data & IPSR_MASK)
+							| (pt->cr_ipsr & ~IPSR_MASK));
+				else
+					*data = (pt->cr_ipsr & IPSR_MASK);
+				return 0;
+		}
+	} else if (addr == ELF_NAT_OFFSET)
+			return access_nat_bits(target, pt, info,
+					data, write_access);
+	else if (addr == ELF_PR_OFFSET)
+			ptr = &pt->pr;
+	else
+		return -1;
+
+	if (write_access)
+		*ptr = *data;
+	else
+		*data = *ptr;
+
+	return 0;
+}
+
+static int
+access_elf_reg(struct task_struct *target, struct unw_frame_info *info,
+		unsigned long addr, unsigned long *data, int write_access)
+{
+	if (addr >= ELF_GR_OFFSET(1) && addr <= ELF_GR_OFFSET(15))
+		return access_elf_gpreg(target, info, addr, data, write_access);
+	else if (addr >= ELF_BR_OFFSET(0) && addr <= ELF_BR_OFFSET(7))
+		return access_elf_breg(target, info, addr, data, write_access);
+	else
+		return access_elf_areg(target, info, addr, data, write_access);
+}
+
+void do_gpregs_get(struct unw_frame_info *info, void *arg)
+{
+	struct pt_regs *pt;
+	utrace_getset_t *dst = arg;
+	elf_greg_t tmp[16];
+	unsigned int i, index, min_copy;
+
+	if (unw_unwind_to_user(info) < 0)
+		return;
+
+	/*
+	 * coredump format:
+	 *      r0-r31
+	 *      NaT bits (for r0-r31; bit N == 1 iff rN is a NaT)
+	 *      predicate registers (p0-p63)
+	 *      b0-b7
+	 *      ip cfm user-mask
+	 *      ar.rsc ar.bsp ar.bspstore ar.rnat
+	 *      ar.ccv ar.unat ar.fpsr ar.pfs ar.lc ar.ec
+	 */
+
+
+	/* Skip r0 */
+	if (dst->count > 0 && dst->pos < ELF_GR_OFFSET(1)) {
+		dst->ret = utrace_regset_copyout_zero(&dst->pos, &dst->count,
+						      &dst->u.get.kbuf,
+						      &dst->u.get.ubuf,
+						      0, ELF_GR_OFFSET(1));
+		if (dst->ret || dst->count == 0)
+			return;
+	}
+
+	/* gr1 - gr15 */
+	if (dst->count > 0 && dst->pos < ELF_GR_OFFSET(16)) {
+		index = (dst->pos - ELF_GR_OFFSET(1)) / sizeof(elf_greg_t);
+		min_copy = ELF_GR_OFFSET(16) > (dst->pos + dst->count) ?
+			 (dst->pos + dst->count) : ELF_GR_OFFSET(16);
+		for (i = dst->pos; i < min_copy; i += sizeof(elf_greg_t), index++)
+			if (access_elf_reg(dst->target, info, i,
+						&tmp[index], 0) < 0) {
+				dst->ret = -EIO;
+				return;
+			}
+		dst->ret = utrace_regset_copyout(&dst->pos, &dst->count,
+				&dst->u.get.kbuf, &dst->u.get.ubuf, tmp,
+				ELF_GR_OFFSET(1), ELF_GR_OFFSET(16));
+		if (dst->ret || dst->count == 0)
+			return;
+	}
+
+	/* r16-r31 */
+	if (dst->count > 0 && dst->pos < ELF_NAT_OFFSET) {
+		pt = task_pt_regs(dst->target);
+		dst->ret = utrace_regset_copyout(&dst->pos, &dst->count,
+				&dst->u.get.kbuf, &dst->u.get.ubuf, &pt->r16,
+				ELF_GR_OFFSET(16), ELF_NAT_OFFSET);
+		if (dst->ret || dst->count == 0)
+			return;
+	}
+
+	/* nat, pr, b0 - b7 */
+	if (dst->count > 0 && dst->pos < ELF_CR_IIP_OFFSET) {
+		index = (dst->pos - ELF_NAT_OFFSET) / sizeof(elf_greg_t);
+		min_copy = ELF_CR_IIP_OFFSET > (dst->pos + dst->count) ?
+			 (dst->pos + dst->count) : ELF_CR_IIP_OFFSET;
+		for (i = dst->pos; i < min_copy; i += sizeof(elf_greg_t), index++)
+			if (access_elf_reg(dst->target, info, i,
+						&tmp[index], 0) < 0) {
+				dst->ret = -EIO;
+				return;
+			}
+		dst->ret = utrace_regset_copyout(&dst->pos, &dst->count,
+				&dst->u.get.kbuf, &dst->u.get.ubuf, tmp,
+				ELF_NAT_OFFSET, ELF_CR_IIP_OFFSET);
+		if (dst->ret || dst->count == 0)
+			return;
+	}
+
+ 	/* ip cfm psr ar.rsc ar.bsp ar.bspstore ar.rnat
+	 * ar.ccv ar.unat ar.fpsr ar.pfs ar.lc ar.ec ar.csd ar.ssd
+	 */
+	if (dst->count > 0 && dst->pos < (ELF_AR_END_OFFSET)) {
+		index = (dst->pos - ELF_CR_IIP_OFFSET) / sizeof(elf_greg_t);
+		min_copy = ELF_AR_END_OFFSET > (dst->pos + dst->count) ?
+			 (dst->pos + dst->count) : ELF_AR_END_OFFSET;
+		for (i = dst->pos; i < min_copy; i += sizeof(elf_greg_t), index++)
+			if (access_elf_reg(dst->target, info, i,
+						&tmp[index], 0) < 0) {
+				dst->ret = -EIO;
+				return;
+			}
+		dst->ret = utrace_regset_copyout(&dst->pos, &dst->count,
+				&dst->u.get.kbuf, &dst->u.get.ubuf, tmp,
+				ELF_CR_IIP_OFFSET, ELF_AR_END_OFFSET);
+        }
+}
+
+void do_gpregs_set(struct unw_frame_info *info, void *arg)
+{
+	struct pt_regs *pt;
+	utrace_getset_t *dst = arg;
+	elf_greg_t tmp[16];
+	unsigned int i, index;
+
+	if (unw_unwind_to_user(info) < 0)
+		return;
+
+	/* Skip r0 */
+	if (dst->count > 0 && dst->pos < ELF_GR_OFFSET(1)) {
+		dst->ret = utrace_regset_copyin_ignore(&dst->pos, &dst->count,
+						       &dst->u.set.kbuf,
+						       &dst->u.set.ubuf,
+						       0, ELF_GR_OFFSET(1));
+		if (dst->ret || dst->count == 0)
+			return;
+	}
+
+	/* gr1-gr15 */
+	if (dst->count > 0 && dst->pos < ELF_GR_OFFSET(16)) {
+		i = dst->pos;
+		index = (dst->pos - ELF_GR_OFFSET(1)) / sizeof(elf_greg_t);
+		dst->ret = utrace_regset_copyin(&dst->pos, &dst->count,
+				&dst->u.set.kbuf, &dst->u.set.ubuf, tmp,
+				ELF_GR_OFFSET(1), ELF_GR_OFFSET(16));
+		if (dst->ret)
+			return;
+		for ( ; i < dst->pos; i += sizeof(elf_greg_t), index++)
+			if (access_elf_reg(dst->target, info, i,
+						&tmp[index], 1) < 0) {
+				dst->ret = -EIO;
+				return;
+			}
+		if (dst->count == 0)
+			return;
+	}
+
+	/* gr16-gr31 */
+	if (dst->count > 0 && dst->pos < ELF_NAT_OFFSET) {
+		pt = task_pt_regs(dst->target);
+		dst->ret = utrace_regset_copyin(&dst->pos, &dst->count,
+				&dst->u.set.kbuf, &dst->u.set.ubuf, &pt->r16,
+				ELF_GR_OFFSET(16), ELF_NAT_OFFSET);
+		if (dst->ret || dst->count == 0)
+			return;
+	}
+
+	/* nat, pr, b0 - b7 */
+	if (dst->count > 0 && dst->pos < ELF_CR_IIP_OFFSET) {
+		i = dst->pos;
+		index = (dst->pos - ELF_NAT_OFFSET) / sizeof(elf_greg_t);
+		dst->ret = utrace_regset_copyin(&dst->pos, &dst->count,
+				&dst->u.set.kbuf, &dst->u.set.ubuf, tmp,
+				ELF_NAT_OFFSET, ELF_CR_IIP_OFFSET);
+		if (dst->ret)
+			return;
+		for (; i < dst->pos; i += sizeof(elf_greg_t), index++)
+			if (access_elf_reg(dst->target, info, i,
+						&tmp[index], 1) < 0) {
+				dst->ret = -EIO;
+				return;
+			}
+		if (dst->count == 0)
+			return;
+	}
+
+ 	/* ip cfm psr ar.rsc ar.bsp ar.bspstore ar.rnat
+	 * ar.ccv ar.unat ar.fpsr ar.pfs ar.lc ar.ec ar.csd ar.ssd
+	 */
+	if (dst->count > 0 && dst->pos < (ELF_AR_END_OFFSET)) {
+		i = dst->pos;
+		index = (dst->pos - ELF_CR_IIP_OFFSET) / sizeof(elf_greg_t);
+		dst->ret = utrace_regset_copyin(&dst->pos, &dst->count,
+				&dst->u.set.kbuf, &dst->u.set.ubuf, tmp,
+				ELF_CR_IIP_OFFSET, ELF_AR_END_OFFSET);
+		if (dst->ret)
+			return;
+		for ( ; i < dst->pos; i += sizeof(elf_greg_t), index++)
+			if (access_elf_reg(dst->target, info, i,
+						&tmp[index], 1) < 0) {
+				dst->ret = -EIO;
+				return;
+			}
+	}
+}
+
+#define ELF_FP_OFFSET(i)	(i * sizeof(elf_fpreg_t))
+
+void do_fpregs_get(struct unw_frame_info *info, void *arg)
+{
+	utrace_getset_t *dst = arg;
+	struct task_struct *task = dst->target;
+	elf_fpreg_t tmp[30];
+	int index, min_copy, i;
+
+	if (unw_unwind_to_user(info) < 0)
+		return;
+
+	/* Skip pos 0 and 1 */
+	if (dst->count > 0 && dst->pos < ELF_FP_OFFSET(2)) {
+		dst->ret = utrace_regset_copyout_zero(&dst->pos, &dst->count,
+						      &dst->u.get.kbuf,
+						      &dst->u.get.ubuf,
+						      0, ELF_FP_OFFSET(2));
+		if (dst->count == 0 || dst->ret)
+			return;
+	}
+
+	/* fr2-fr31 */
+	if (dst->count > 0 && dst->pos < ELF_FP_OFFSET(32)) {
+		index = (dst->pos - ELF_FP_OFFSET(2)) / sizeof(elf_fpreg_t);
+		min_copy = min(((unsigned int)ELF_FP_OFFSET(32)),
+				dst->pos + dst->count);
+		for (i = dst->pos; i < min_copy; i += sizeof(elf_fpreg_t), index++)
+			if (unw_get_fr(info, i / sizeof(elf_fpreg_t),
+					 &tmp[index])) {
+				dst->ret = -EIO;
+				return;
+			}
+		dst->ret = utrace_regset_copyout(&dst->pos, &dst->count,
+				&dst->u.get.kbuf, &dst->u.get.ubuf, tmp,
+				ELF_FP_OFFSET(2), ELF_FP_OFFSET(32));
+		if (dst->count == 0 || dst->ret)
+			return;
+	}
+
+	/* fph */
+	if (dst->count > 0) {
+		ia64_flush_fph(dst->target);
+		if (task->thread.flags & IA64_THREAD_FPH_VALID)
+			dst->ret = utrace_regset_copyout(
+				&dst->pos, &dst->count,
+				&dst->u.get.kbuf, &dst->u.get.ubuf,
+				&dst->target->thread.fph,
+				ELF_FP_OFFSET(32), -1);
+		else
+			/* Zero fill instead.  */
+			dst->ret = utrace_regset_copyout_zero(
+				&dst->pos, &dst->count,
+				&dst->u.get.kbuf, &dst->u.get.ubuf,
+				ELF_FP_OFFSET(32), -1);
+	}
+}
+
+void do_fpregs_set(struct unw_frame_info *info, void *arg)
+{
+	utrace_getset_t *dst = arg;
+	elf_fpreg_t fpreg, tmp[30];
+	int index, start, end;
+
+	if (unw_unwind_to_user(info) < 0)
+		return;
+
+	/* Skip pos 0 and 1 */
+	if (dst->count > 0 && dst->pos < ELF_FP_OFFSET(2)) {
+		dst->ret = utrace_regset_copyin_ignore(&dst->pos, &dst->count,
+						       &dst->u.set.kbuf,
+						       &dst->u.set.ubuf,
+						       0, ELF_FP_OFFSET(2));
+		if (dst->count == 0 || dst->ret)
+			return;
+	}
+
+	/* fr2-fr31 */
+	if (dst->count > 0 && dst->pos < ELF_FP_OFFSET(32)) {
+		start = dst->pos;
+		end = min(((unsigned int)ELF_FP_OFFSET(32)),
+			 dst->pos + dst->count);
+		dst->ret = utrace_regset_copyin(&dst->pos, &dst->count,
+				&dst->u.set.kbuf, &dst->u.set.ubuf, tmp,
+				ELF_FP_OFFSET(2), ELF_FP_OFFSET(32));
+		if (dst->ret)
+			return;
+
+		if (start & 0xF) { //  only write high part
+			if (unw_get_fr(info, start / sizeof(elf_fpreg_t),
+					 &fpreg)) {
+				dst->ret = -EIO;
+				return;
+			}
+			tmp[start / sizeof(elf_fpreg_t) - 2].u.bits[0]
+				= fpreg.u.bits[0];
+			start &= ~0xFUL;
+		}
+		if (end & 0xF) { // only write low part
+			if (unw_get_fr(info, end / sizeof(elf_fpreg_t), &fpreg)) {
+				dst->ret = -EIO;
+				return;
+                       	}
+			tmp[end / sizeof(elf_fpreg_t) -2].u.bits[1]
+				= fpreg.u.bits[1];
+			end = (end + 0xF) & ~0xFUL;
+		}
+
+		for ( ;	start < end ; start += sizeof(elf_fpreg_t)) {
+			index = start / sizeof(elf_fpreg_t);
+			if (unw_set_fr(info, index, tmp[index - 2])){
+				dst->ret = -EIO;
+				return;
+			}
+		}
+		if (dst->ret || dst->count == 0)
+			return;
+	}
+
+	/* fph */
+	if (dst->count > 0 && dst->pos < ELF_FP_OFFSET(128)) {
+		ia64_sync_fph(dst->target);
+		dst->ret = utrace_regset_copyin(&dst->pos, &dst->count,
+						&dst->u.set.kbuf,
+						&dst->u.set.ubuf,
+						&dst->target->thread.fph,
+						ELF_FP_OFFSET(32), -1);
+	}
+}
+
+static int
+do_regset_call(void (*call)(struct unw_frame_info *, void *),
+	       struct task_struct *target,
+	       const struct utrace_regset *regset,
+	       unsigned int pos, unsigned int count,
+	       const void *kbuf, const void __user *ubuf)
+{
+	utrace_getset_t info = { .target = target, .regset = regset,
+				 .pos = pos, .count = count,
+				 .u.set = { .kbuf = kbuf, .ubuf = ubuf },
+				 .ret = 0 };
+
+	if (target == current)
+		unw_init_running(call, &info);
+	else {
+		struct unw_frame_info ufi;
+		memset(&ufi, 0, sizeof(ufi));
+		unw_init_from_blocked_task(&ufi, target);
+		(*call)(&ufi, &info);
+	}
+
+	return info.ret;
+}
+
+static int
+gpregs_get(struct task_struct *target,
+	   const struct utrace_regset *regset,
+	   unsigned int pos, unsigned int count,
+	   void *kbuf, void __user *ubuf)
+{
+	return do_regset_call(do_gpregs_get, target, regset, pos, count, kbuf, ubuf);
+}
+
+static int gpregs_set(struct task_struct *target,
+		const struct utrace_regset *regset,
+		unsigned int pos, unsigned int count,
+		const void *kbuf, const void __user *ubuf)
+{
+	return do_regset_call(do_gpregs_set, target, regset, pos, count, kbuf, ubuf);
+}
+
+static void do_gpregs_writeback(struct unw_frame_info *info, void *arg)
+{
+	struct pt_regs *pt;
+	utrace_getset_t *dst = arg;
+	unsigned long urbs_end;
+
+	if (unw_unwind_to_user(info) < 0)
+		return;
+	pt = task_pt_regs(dst->target);
+	urbs_end = ia64_get_user_rbs_end(dst->target, pt, NULL);
+	dst->ret = ia64_sync_user_rbs(dst->target, info->sw, pt->ar_bspstore, urbs_end);
+}
+/*
+ * This is called to write back the register backing store.
+ * ptrace does this before it stops, so that a tracer reading the user
+ * memory after the thread stops will get the current register data.
+ */
+static int
+gpregs_writeback(struct task_struct *target,
+		 const struct utrace_regset *regset,
+		 int now)
+{
+	return do_regset_call(do_gpregs_writeback, target, regset, 0, 0, NULL, NULL);
+}
+
+static int
+fpregs_active(struct task_struct *target, const struct utrace_regset *regset)
+{
+	return (target->thread.flags & IA64_THREAD_FPH_VALID) ? 128 : 32;
+}
+
+static int fpregs_get(struct task_struct *target,
+		const struct utrace_regset *regset,
+		unsigned int pos, unsigned int count,
+		void *kbuf, void __user *ubuf)
+{
+	return do_regset_call(do_fpregs_get, target, regset, pos, count, kbuf, ubuf);
+}
+
+static int fpregs_set(struct task_struct *target,
+		const struct utrace_regset *regset,
+		unsigned int pos, unsigned int count,
+		const void *kbuf, const void __user *ubuf)
+{
+	return do_regset_call(do_fpregs_set, target, regset, pos, count, kbuf, ubuf);
+}
+
+static int dbregs_get(struct task_struct *target,
+		const struct utrace_regset *regset,
+		unsigned int pos, unsigned int count,
+		void *kbuf, void __user *ubuf)
+{
+	int ret;
+
+#ifdef CONFIG_PERFMON
+	/*
+	 * Check if debug registers are used by perfmon. This
+	 * test must be done once we know that we can do the
+	 * operation, i.e. the arguments are all valid, but
+	 * before we start modifying the state.
+	 *
+	 * Perfmon needs to keep a count of how many processes
+	 * are trying to modify the debug registers for system
+	 * wide monitoring sessions.
+	 *
+	 * We also include read access here, because they may
+	 * cause the PMU-installed debug register state
+	 * (dbr[], ibr[]) to be reset. The two arrays are also
+	 * used by perfmon, but we do not use
+	 * IA64_THREAD_DBG_VALID. The registers are restored
+	 * by the PMU context switch code.
+	 */
+	if (pfm_use_debug_registers(target))
+		return -EIO;
+#endif
+
+	if (!(target->thread.flags & IA64_THREAD_DBG_VALID))
+		ret = utrace_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
+						 0, -1);
+	else {
+		preempt_disable();
+		if (target == current)
+			ia64_load_debug_regs(&target->thread.dbr[0]);
+		preempt_enable_no_resched();
+		ret = utrace_regset_copyout(&pos, &count, &kbuf, &ubuf,
+					    &target->thread.dbr, 0, -1);
+	}
+
+	return ret;
+}
+
+static int dbregs_set(struct task_struct *target,
+		const struct utrace_regset *regset,
+		unsigned int pos, unsigned int count,
+		const void *kbuf, const void __user *ubuf)
+{
+	int i, ret;
+
+#ifdef CONFIG_PERFMON
+	if (pfm_use_debug_registers(target))
+		return -EIO;
+#endif
+
+	ret = 0;
+	if (!(target->thread.flags & IA64_THREAD_DBG_VALID)){
+		target->thread.flags |= IA64_THREAD_DBG_VALID;
+		memset(target->thread.dbr, 0, 2 * sizeof(target->thread.dbr));
+	} else if (target == current){
+		preempt_disable();
+		ia64_save_debug_regs(&target->thread.dbr[0]);
+		preempt_enable_no_resched();
+	}
+
+	ret = utrace_regset_copyin(&pos, &count, &kbuf, &ubuf,
+				   &target->thread.dbr, 0, -1);
+
+	for (i = 1; i < IA64_NUM_DBG_REGS; i += 2) {
+		target->thread.dbr[i] &= ~(7UL << 56);
+		target->thread.ibr[i] &= ~(7UL << 56);
+	}
+
+	if (ret)
+		return ret;
+
+	if (target == current){
+		preempt_disable();
+		ia64_load_debug_regs(&target->thread.dbr[0]);
+		preempt_enable_no_resched();
+	}
+	return 0;
+}
+
+static const struct utrace_regset native_regsets[] = {
+	{
+		.n = ELF_NGREG,
+		.size = sizeof(elf_greg_t), .align = sizeof(elf_greg_t),
+		.get = gpregs_get, .set = gpregs_set,
+		.writeback = gpregs_writeback
+	},
+	{
+		.n = ELF_NFPREG,
+		.size = sizeof(elf_fpreg_t), .align = sizeof(elf_fpreg_t),
+		.get = fpregs_get, .set = fpregs_set, .active = fpregs_active
+	},
+	{
+		.n = 2 * IA64_NUM_DBG_REGS, .size = sizeof(long),
+		.align = sizeof(long),
+		.get = dbregs_get, .set = dbregs_set
+	}
+};
+
+static const struct utrace_regset_view utrace_ia64_native = {
+	.name = "ia64",
+	.e_machine = EM_IA_64,
+	.regsets = native_regsets, .n = ARRAY_SIZE(native_regsets)
+};
+
+const struct utrace_regset_view *utrace_native_view(struct task_struct *tsk)
+{
+#ifdef CONFIG_IA32_SUPPORT
+	extern const struct utrace_regset_view utrace_ia32_view;
+	if (IS_IA32_PROCESS(task_pt_regs(tsk)))
+		return &utrace_ia32_view;
+#endif
+	return &utrace_ia64_native;
+}
Index: b/include/asm-ia64/tracehook.h
===================================================================
--- a/include/asm-ia64/tracehook.h
+++ b/include/asm-ia64/tracehook.h
@@ -67,7 +67,10 @@ static inline int tracehook_single_step_
 
 static inline void tracehook_abort_syscall(struct pt_regs *regs)
 {
-	regs->r15 = -1L;
+	if (IS_IA32_PROCESS(regs))
+		regs->r1 = -1UL;
+	else
+		regs->r15 = -1UL;
 }
 
-#endif
+#endif	/* asm/tracehook.h */
Index: b/include/asm-ia64/elf.h
===================================================================
--- a/include/asm-ia64/elf.h
+++ b/include/asm-ia64/elf.h
@@ -154,6 +154,30 @@ extern void ia64_init_addr_space (void);
 #define ELF_NGREG	128	/* we really need just 72 but let's leave some headroom... */
 #define ELF_NFPREG	128	/* f0 and f1 could be omitted, but so what... */
 
+/* elf_gregset_t register offsets */
+#define ELF_GR_0_OFFSET     0
+#define ELF_NAT_OFFSET     (32 * sizeof(elf_greg_t))
+#define ELF_PR_OFFSET      (33 * sizeof(elf_greg_t))
+#define ELF_BR_0_OFFSET    (34 * sizeof(elf_greg_t))
+#define ELF_CR_IIP_OFFSET  (42 * sizeof(elf_greg_t))
+#define ELF_CFM_OFFSET     (43 * sizeof(elf_greg_t))
+#define ELF_CR_IPSR_OFFSET (44 * sizeof(elf_greg_t))
+#define ELF_GR_OFFSET(i)   (ELF_GR_0_OFFSET + i * sizeof(elf_greg_t))
+#define ELF_BR_OFFSET(i)   (ELF_BR_0_OFFSET + i * sizeof(elf_greg_t))
+#define ELF_AR_RSC_OFFSET  (45 * sizeof(elf_greg_t))
+#define ELF_AR_BSP_OFFSET  (46 * sizeof(elf_greg_t))
+#define ELF_AR_BSPSTORE_OFFSET (47 * sizeof(elf_greg_t))
+#define ELF_AR_RNAT_OFFSET (48 * sizeof(elf_greg_t))
+#define ELF_AR_CCV_OFFSET  (49 * sizeof(elf_greg_t))
+#define ELF_AR_UNAT_OFFSET (50 * sizeof(elf_greg_t))
+#define ELF_AR_FPSR_OFFSET (51 * sizeof(elf_greg_t))
+#define ELF_AR_PFS_OFFSET  (52 * sizeof(elf_greg_t))
+#define ELF_AR_LC_OFFSET   (53 * sizeof(elf_greg_t))
+#define ELF_AR_EC_OFFSET   (54 * sizeof(elf_greg_t))
+#define ELF_AR_CSD_OFFSET  (55 * sizeof(elf_greg_t))
+#define ELF_AR_SSD_OFFSET  (56 * sizeof(elf_greg_t))
+#define ELF_AR_END_OFFSET  (57 * sizeof(elf_greg_t))
+
 typedef unsigned long elf_fpxregset_t;
 
 typedef unsigned long elf_greg_t;

linux-2.6-utrace-regset-s390.patch:

--- NEW FILE linux-2.6-utrace-regset-s390.patch ---
[PATCH 2c] utrace: s390 regset support

This patch converts the machine-dependent ptrace code into utrace regset
support for s390.

Signed-off-by: Roland McGrath <roland at redhat.com>
CC: David Wilder <dwilder at us.ibm.com>

---

 arch/s390/kernel/Makefile |    2 
 arch/s390/kernel/ptrace.c |  952 ++++++++++++++++++----------------------------
 2 files changed, 390 insertions(+), 564 deletions(-)

Index: b/arch/s390/kernel/Makefile
===================================================================
--- a/arch/s390/kernel/Makefile
+++ b/arch/s390/kernel/Makefile
@@ -35,3 +35,5 @@ obj-$(CONFIG_KEXEC) += $(S390_KEXEC_OBJS
 # This is just to get the dependencies...
 #
 binfmt_elf32.o:	$(TOPDIR)/fs/binfmt_elf.c
+
+CFLAGS_ptrace.o		+= -DUTS_MACHINE='"$(UTS_MACHINE)"'
Index: b/arch/s390/kernel/ptrace.c
===================================================================
--- a/arch/s390/kernel/ptrace.c
+++ b/arch/s390/kernel/ptrace.c
@@ -30,6 +30,7 @@
 #include <linux/errno.h>
 #include <linux/ptrace.h>
 #include <linux/tracehook.h>
+#include <linux/module.h>
 #include <linux/user.h>
 #include <linux/security.h>
 #include <linux/audit.h>
@@ -42,6 +43,7 @@
 #include <asm/system.h>
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
+#include <asm/elf.h>
 
 #ifdef CONFIG_COMPAT
 #include "compat_ptrace.h"
@@ -116,640 +118,462 @@ tracehook_single_step_enabled(struct tas
 	return task->thread.per_info.single_step;
 }
 
-/*
- * Called by kernel/ptrace.c when detaching..
- *
- * Make sure single step bits etc are not set.
- */
-void
-ptrace_disable(struct task_struct *child)
-{
-	/* make sure the single step bit is not set. */
-	tracehook_disable_single_step(child);
-}
-
-#ifndef CONFIG_64BIT
-# define __ADDR_MASK 3
-#else
-# define __ADDR_MASK 7
-#endif
 
-/*
- * Read the word at offset addr from the user area of a process. The
- * trouble here is that the information is littered over different
- * locations. The process registers are found on the kernel stack,
- * the floating point stuff and the trace settings are stored in
- * the task structure. In addition the different structures in
- * struct user contain pad bytes that should be read as zeroes.
- * Lovely...
- */
 static int
-peek_user(struct task_struct *child, addr_t addr, addr_t data)
+genregs_get(struct task_struct *target,
+	    const struct utrace_regset *regset,
+	    unsigned int pos, unsigned int count,
+	    void *kbuf, void __user *ubuf)
 {
-	struct user *dummy = NULL;
-	addr_t offset, tmp, mask;
+	struct pt_regs *regs = task_pt_regs(target);
+	unsigned long pswmask;
+	int ret;
 
-	/*
-	 * Stupid gdb peeks/pokes the access registers in 64 bit with
-	 * an alignment of 4. Programmers from hell...
-	 */
-	mask = __ADDR_MASK;
-#ifdef CONFIG_64BIT
-	if (addr >= (addr_t) &dummy->regs.acrs &&
-	    addr < (addr_t) &dummy->regs.orig_gpr2)
-		mask = 3;
-#endif
-	if ((addr & mask) || addr > sizeof(struct user) - __ADDR_MASK)
-		return -EIO;
+	/* Remove per bit from user psw. */
+	pswmask = regs->psw.mask & ~PSW_MASK_PER;
+	ret = utrace_regset_copyout(&pos, &count, &kbuf, &ubuf,
+				    &pswmask, PT_PSWMASK, PT_PSWADDR);
+
+	/* The rest of the PSW and the GPRs are directly on the stack. */
+	if (ret == 0)
+		ret = utrace_regset_copyout(&pos, &count, &kbuf, &ubuf,
+					    &regs->psw.addr, PT_PSWADDR,
+					    PT_ACR0);
+
+	/* The ACRs are kept in the thread_struct.  */
+	if (ret == 0 && count > 0 && pos < PT_ORIGGPR2) {
+		if (target == current)
+			save_access_regs(target->thread.acrs);
+
+		ret = utrace_regset_copyout(&pos, &count, &kbuf, &ubuf,
+					    target->thread.acrs,
+					    PT_ACR0, PT_ORIGGPR2);
+	}
 
-	if (addr < (addr_t) &dummy->regs.acrs) {
-		/*
-		 * psw and gprs are stored on the stack
-		 */
-		tmp = *(addr_t *)((addr_t) &task_pt_regs(child)->psw + addr);
-		if (addr == (addr_t) &dummy->regs.psw.mask)
-			/* Remove per bit from user psw. */
-			tmp &= ~PSW_MASK_PER;
+	/* Finally, the ORIG_GPR2 value.  */
+	if (ret == 0)
+		ret = utrace_regset_copyout(&pos, &count, &kbuf, &ubuf,
+					    &regs->orig_gpr2, PT_ORIGGPR2, -1);
 
-	} else if (addr < (addr_t) &dummy->regs.orig_gpr2) {
-		/*
-		 * access registers are stored in the thread structure
-		 */
-		offset = addr - (addr_t) &dummy->regs.acrs;
-#ifdef CONFIG_64BIT
-		/*
-		 * Very special case: old & broken 64 bit gdb reading
-		 * from acrs[15]. Result is a 64 bit value. Read the
-		 * 32 bit acrs[15] value and shift it by 32. Sick...
-		 */
-		if (addr == (addr_t) &dummy->regs.acrs[15])
-			tmp = ((unsigned long) child->thread.acrs[15]) << 32;
-		else
-#endif
-		tmp = *(addr_t *)((addr_t) &child->thread.acrs + offset);
+	return ret;
+}
 
-	} else if (addr == (addr_t) &dummy->regs.orig_gpr2) {
-		/*
-		 * orig_gpr2 is stored on the kernel stack
-		 */
-		tmp = (addr_t) task_pt_regs(child)->orig_gpr2;
+static int
+genregs_set(struct task_struct *target,
+	    const struct utrace_regset *regset,
+	    unsigned int pos, unsigned int count,
+	    const void *kbuf, const void __user *ubuf)
+{
+	struct pt_regs *regs = task_pt_regs(target);
+	int ret = 0;
+
+	/* Check for an invalid PSW mask.  */
+	if (count > 0 && pos == PT_PSWMASK) {
+		unsigned long pswmask = regs->psw.mask;
+		ret = utrace_regset_copyin(&pos, &count, &kbuf, &ubuf,
+					   &pswmask, PT_PSWMASK, PT_PSWADDR);
+		if (pswmask != PSW_MASK_MERGE(psw_user_bits, pswmask)
+#ifdef CONFIG_COMPAT
+		    && pswmask != PSW_MASK_MERGE(psw_user32_bits, pswmask)
+#endif
+			)
+			/* Invalid psw mask. */
+			return -EINVAL;
+		regs->psw.mask = pswmask;
+		FixPerRegisters(target);
+	}
 
-	} else if (addr < (addr_t) (&dummy->regs.fp_regs + 1)) {
-		/* 
-		 * floating point regs. are stored in the thread structure
-		 */
-		offset = addr - (addr_t) &dummy->regs.fp_regs;
-		tmp = *(addr_t *)((addr_t) &child->thread.fp_regs + offset);
-		if (addr == (addr_t) &dummy->regs.fp_regs.fpc)
-			tmp &= (unsigned long) FPC_VALID_MASK
-				<< (BITS_PER_LONG - 32);
+	/* The rest of the PSW and the GPRs are directly on the stack. */
+	if (ret == 0) {
+		ret = utrace_regset_copyin(&pos, &count, &kbuf, &ubuf,
+					   &regs->psw.addr, PT_PSWADDR,
+					   PT_ACR0);
+#ifndef CONFIG_64BIT
+		/* I'd like to reject addresses without the
+		   high order bit but older gdb's rely on it */
+		regs->psw.addr |= PSW_ADDR_AMODE;
+#endif
+	}
 
-	} else if (addr < (addr_t) (&dummy->regs.per_info + 1)) {
-		/*
-		 * per_info is found in the thread structure
-		 */
-		offset = addr - (addr_t) &dummy->regs.per_info;
-		tmp = *(addr_t *)((addr_t) &child->thread.per_info + offset);
+	/* The ACRs are kept in the thread_struct.  */
+	if (ret == 0 && count > 0 && pos < PT_ORIGGPR2) {
+		if (target == current
+		    && (pos != PT_ACR0 || count < sizeof(target->thread.acrs)))
+			save_access_regs(target->thread.acrs);
+
+		ret = utrace_regset_copyin(&pos, &count, &kbuf, &ubuf,
+					   target->thread.acrs,
+					   PT_ACR0, PT_ORIGGPR2);
+		if (ret == 0 && target == current)
+			restore_access_regs(target->thread.acrs);
+	}
 
-	} else
-		tmp = 0;
+	/* Finally, the ORIG_GPR2 value.  */
+	if (ret == 0)
+		ret = utrace_regset_copyin(&pos, &count, &kbuf, &ubuf,
+					   &regs->orig_gpr2, PT_ORIGGPR2, -1);
 
-	return put_user(tmp, (addr_t __user *) data);
+	return ret;
 }
 
-/*
- * Write a word to the user area of a process at location addr. This
- * operation does have an additional problem compared to peek_user.
- * Stores to the program status word and on the floating point
- * control register needs to get checked for validity.
- */
 static int
-poke_user(struct task_struct *child, addr_t addr, addr_t data)
+fpregs_get(struct task_struct *target,
+	   const struct utrace_regset *regset,
+	   unsigned int pos, unsigned int count,
+	   void *kbuf, void __user *ubuf)
 {
-	struct user *dummy = NULL;
-	addr_t offset, mask;
+	if (target == current)
+		save_fp_regs(&target->thread.fp_regs);
 
-	/*
-	 * Stupid gdb peeks/pokes the access registers in 64 bit with
-	 * an alignment of 4. Programmers from hell indeed...
-	 */
-	mask = __ADDR_MASK;
-#ifdef CONFIG_64BIT
-	if (addr >= (addr_t) &dummy->regs.acrs &&
-	    addr < (addr_t) &dummy->regs.orig_gpr2)
-		mask = 3;
-#endif
-	if ((addr & mask) || addr > sizeof(struct user) - __ADDR_MASK)
-		return -EIO;
+	return utrace_regset_copyout(&pos, &count, &kbuf, &ubuf,
+				     &target->thread.fp_regs, 0, -1);
+}
 
-	if (addr < (addr_t) &dummy->regs.acrs) {
-		/*
-		 * psw and gprs are stored on the stack
-		 */
-		if (addr == (addr_t) &dummy->regs.psw.mask &&
-#ifdef CONFIG_COMPAT
-		    data != PSW_MASK_MERGE(psw_user32_bits, data) &&
-#endif
-		    data != PSW_MASK_MERGE(psw_user_bits, data))
-			/* Invalid psw mask. */
+static int
+fpregs_set(struct task_struct *target,
+	    const struct utrace_regset *regset,
+	    unsigned int pos, unsigned int count,
+	    const void *kbuf, const void __user *ubuf)
+{
+	int ret = 0;
+
+	if (target == current && (pos != 0 || count != sizeof(s390_fp_regs)))
+		save_fp_regs(&target->thread.fp_regs);
+
+	/* If setting FPC, must validate it first. */
+	if (count > 0 && pos == 0) {
+		unsigned long fpc;
+		ret = utrace_regset_copyin(&pos, &count, &kbuf, &ubuf,
+					   &fpc, 0, sizeof(fpc));
+		if (ret)
+			return ret;
+
+		if ((fpc & ~((unsigned long) FPC_VALID_MASK
+			     << (BITS_PER_LONG - 32))) != 0)
 			return -EINVAL;
-#ifndef CONFIG_64BIT
-		if (addr == (addr_t) &dummy->regs.psw.addr)
-			/* I'd like to reject addresses without the
-			   high order bit but older gdb's rely on it */
-			data |= PSW_ADDR_AMODE;
-#endif
-		*(addr_t *)((addr_t) &task_pt_regs(child)->psw + addr) = data;
 
-	} else if (addr < (addr_t) (&dummy->regs.orig_gpr2)) {
-		/*
-		 * access registers are stored in the thread structure
-		 */
-		offset = addr - (addr_t) &dummy->regs.acrs;
-#ifdef CONFIG_64BIT
-		/*
-		 * Very special case: old & broken 64 bit gdb writing
-		 * to acrs[15] with a 64 bit value. Ignore the lower
-		 * half of the value and write the upper 32 bit to
-		 * acrs[15]. Sick...
-		 */
-		if (addr == (addr_t) &dummy->regs.acrs[15])
-			child->thread.acrs[15] = (unsigned int) (data >> 32);
-		else
-#endif
-		*(addr_t *)((addr_t) &child->thread.acrs + offset) = data;
+		memcpy(&target->thread.fp_regs, &fpc, sizeof(fpc));
+	}
 
-	} else if (addr == (addr_t) &dummy->regs.orig_gpr2) {
-		/*
-		 * orig_gpr2 is stored on the kernel stack
-		 */
-		task_pt_regs(child)->orig_gpr2 = data;
+	if (ret == 0)
+		ret = utrace_regset_copyin(&pos, &count, &kbuf, &ubuf,
+					   &target->thread.fp_regs, 0, -1);
 
-	} else if (addr < (addr_t) (&dummy->regs.fp_regs + 1)) {
-		/*
-		 * floating point regs. are stored in the thread structure
-		 */
-		if (addr == (addr_t) &dummy->regs.fp_regs.fpc &&
-		    (data & ~((unsigned long) FPC_VALID_MASK
-			      << (BITS_PER_LONG - 32))) != 0)
-			return -EINVAL;
-		offset = addr - (addr_t) &dummy->regs.fp_regs;
-		*(addr_t *)((addr_t) &child->thread.fp_regs + offset) = data;
+	if (ret == 0 && target == current)
+		restore_fp_regs(&target->thread.fp_regs);
 
-	} else if (addr < (addr_t) (&dummy->regs.per_info + 1)) {
-		/*
-		 * per_info is found in the thread structure 
-		 */
-		offset = addr - (addr_t) &dummy->regs.per_info;
-		*(addr_t *)((addr_t) &child->thread.per_info + offset) = data;
-
-	}
+	return ret;
+}
 
-	FixPerRegisters(child);
-	return 0;
+static int
+per_info_get(struct task_struct *target,
+	     const struct utrace_regset *regset,
+	     unsigned int pos, unsigned int count,
+	     void *kbuf, void __user *ubuf)
+{
+	return utrace_regset_copyout(&pos, &count, &kbuf, &ubuf,
+				     &target->thread.per_info, 0, -1);
 }
 
 static int
-do_ptrace_normal(struct task_struct *child, long request, long addr, long data)
+per_info_set(struct task_struct *target,
+	     const struct utrace_regset *regset,
+	     unsigned int pos, unsigned int count,
+	     const void *kbuf, const void __user *ubuf)
 {
-	unsigned long tmp;
-	ptrace_area parea; 
-	int copied, ret;
-
-	switch (request) {
-	case PTRACE_PEEKTEXT:
-	case PTRACE_PEEKDATA:
-		/* Remove high order bit from address (only for 31 bit). */
-		addr &= PSW_ADDR_INSN;
-		/* read word at location addr. */
-		copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
-		if (copied != sizeof(tmp))
-			return -EIO;
-		return put_user(tmp, (unsigned long __force __user *) data);
-
-	case PTRACE_PEEKUSR:
-		/* read the word at location addr in the USER area. */
-		return peek_user(child, addr, data);
-
-	case PTRACE_POKETEXT:
-	case PTRACE_POKEDATA:
-		/* Remove high order bit from address (only for 31 bit). */
-		addr &= PSW_ADDR_INSN;
-		/* write the word at location addr. */
-		copied = access_process_vm(child, addr, &data, sizeof(data),1);
-		if (copied != sizeof(data))
-			return -EIO;
-		return 0;
-
-	case PTRACE_POKEUSR:
-		/* write the word at location addr in the USER area */
-		return poke_user(child, addr, data);
-
-	case PTRACE_PEEKUSR_AREA:
-	case PTRACE_POKEUSR_AREA:
-		if (copy_from_user(&parea, (void __force __user *) addr,
-							sizeof(parea)))
-			return -EFAULT;
-		addr = parea.kernel_addr;
-		data = parea.process_addr;
-		copied = 0;
-		while (copied < parea.len) {
-			if (request == PTRACE_PEEKUSR_AREA)
-				ret = peek_user(child, addr, data);
-			else {
-				addr_t utmp;
-				if (get_user(utmp,
-					     (addr_t __force __user *) data))
-					return -EFAULT;
-				ret = poke_user(child, addr, utmp);
-			}
-			if (ret)
-				return ret;
-			addr += sizeof(unsigned long);
-			data += sizeof(unsigned long);
-			copied += sizeof(unsigned long);
-		}
-		return 0;
-	}
-	return ptrace_request(child, request, addr, data);
+	int ret = utrace_regset_copyin(&pos, &count, &kbuf, &ubuf,
+				       &target->thread.per_info, 0, -1);
+
+	FixPerRegisters(target);
+
+	return ret;
 }
 
-#ifdef CONFIG_COMPAT
-/*
- * Now the fun part starts... a 31 bit program running in the
- * 31 bit emulation tracing another program. PTRACE_PEEKTEXT,
- * PTRACE_PEEKDATA, PTRACE_POKETEXT and PTRACE_POKEDATA are easy
- * to handle, the difference to the 64 bit versions of the requests
- * is that the access is done in multiples of 4 byte instead of
- * 8 bytes (sizeof(unsigned long) on 31/64 bit).
- * The ugly part are PTRACE_PEEKUSR, PTRACE_PEEKUSR_AREA,
- * PTRACE_POKEUSR and PTRACE_POKEUSR_AREA. If the traced program
- * is a 31 bit program too, the content of struct user can be
- * emulated. A 31 bit program peeking into the struct user of
- * a 64 bit program is a no-no.
- */
 
 /*
- * Same as peek_user but for a 31 bit program.
+ * These are our native regset flavors.
  */
-static int
-peek_user_emu31(struct task_struct *child, addr_t addr, addr_t data)
-{
-	struct user32 *dummy32 = NULL;
-	per_struct32 *dummy_per32 = NULL;
-	addr_t offset;
-	__u32 tmp;
-
-	if (!test_thread_flag(TIF_31BIT) ||
-	    (addr & 3) || addr > sizeof(struct user) - 3)
-		return -EIO;
+static const struct utrace_regset native_regsets[] = {
+	{
+		.size = sizeof(long), .align = sizeof(long),
+		.n = sizeof(s390_regs) / sizeof(long),
+		.get = genregs_get, .set = genregs_set
+	},
+	{
+		.size = sizeof(long), .align = sizeof(long),
+		.n = sizeof(s390_fp_regs) / sizeof(long),
+		.get = fpregs_get, .set = fpregs_set
+	},
+	{
+		.size = sizeof(long), .align = sizeof(long),
+		.n = sizeof(per_struct) / sizeof(long),
+		.get = per_info_get, .set = per_info_set
+	},
+};
+
+static const struct utrace_regset_view utrace_s390_native_view = {
+	.name = UTS_MACHINE, .e_machine = ELF_ARCH,
+	.regsets = native_regsets, .n = ARRAY_SIZE(native_regsets)
+};
 
-	if (addr < (addr_t) &dummy32->regs.acrs) {
-		/*
-		 * psw and gprs are stored on the stack
-		 */
-		if (addr == (addr_t) &dummy32->regs.psw.mask) {
-			/* Fake a 31 bit psw mask. */
-			tmp = (__u32)(task_pt_regs(child)->psw.mask >> 32);
-			tmp = PSW32_MASK_MERGE(psw32_user_bits, tmp);
-		} else if (addr == (addr_t) &dummy32->regs.psw.addr) {
-			/* Fake a 31 bit psw address. */
-			tmp = (__u32) task_pt_regs(child)->psw.addr |
-				PSW32_ADDR_AMODE31;
-		} else {
-			/* gpr 0-15 */
-			tmp = *(__u32 *)((addr_t) &task_pt_regs(child)->psw +
-					 addr*2 + 4);
-		}
-	} else if (addr < (addr_t) (&dummy32->regs.orig_gpr2)) {
-		/*
-		 * access registers are stored in the thread structure
-		 */
-		offset = addr - (addr_t) &dummy32->regs.acrs;
-		tmp = *(__u32*)((addr_t) &child->thread.acrs + offset);
 
-	} else if (addr == (addr_t) (&dummy32->regs.orig_gpr2)) {
-		/*
-		 * orig_gpr2 is stored on the kernel stack
-		 */
-		tmp = *(__u32*)((addr_t) &task_pt_regs(child)->orig_gpr2 + 4);
+#ifdef CONFIG_COMPAT
+static int
+s390_genregs_get(struct task_struct *target,
+		 const struct utrace_regset *regset,
+		 unsigned int pos, unsigned int count,
+		 void *kbuf, void __user *ubuf)
+{
+	struct pt_regs *regs = task_pt_regs(target);
+	int ret = 0;
+
+	/* Fake a 31 bit psw mask. */
+	if (count > 0 && pos == PT_PSWMASK / 2) {
+		u32 pswmask = PSW32_MASK_MERGE(psw32_user_bits,
+					       (u32) (regs->psw.mask >> 32));
+		ret = utrace_regset_copyout(&pos, &count, &kbuf, &ubuf,
+					    &pswmask, PT_PSWMASK / 2,
+					    PT_PSWADDR / 2);
+	}
 
-	} else if (addr < (addr_t) (&dummy32->regs.fp_regs + 1)) {
-		/*
-		 * floating point regs. are stored in the thread structure 
-		 */
-	        offset = addr - (addr_t) &dummy32->regs.fp_regs;
-		tmp = *(__u32 *)((addr_t) &child->thread.fp_regs + offset);
+	/* Fake a 31 bit psw address. */
+	if (ret == 0 && count > 0 && pos == PT_PSWADDR / 2) {
+		u32 pswaddr = (u32) regs->psw.addr | PSW32_ADDR_AMODE31;
+		ret = utrace_regset_copyout(&pos, &count, &kbuf, &ubuf,
+					    &pswaddr, PT_PSWADDR / 2,
+					    PT_GPR0 / 2);
+	}
 
-	} else if (addr < (addr_t) (&dummy32->regs.per_info + 1)) {
-		/*
-		 * per_info is found in the thread structure
-		 */
-		offset = addr - (addr_t) &dummy32->regs.per_info;
-		/* This is magic. See per_struct and per_struct32. */
-		if ((offset >= (addr_t) &dummy_per32->control_regs &&
-		     offset < (addr_t) (&dummy_per32->control_regs + 1)) ||
-		    (offset >= (addr_t) &dummy_per32->starting_addr &&
-		     offset <= (addr_t) &dummy_per32->ending_addr) ||
-		    offset == (addr_t) &dummy_per32->lowcore.words.address)
-			offset = offset*2 + 4;
+	/* The GPRs are directly on the stack.  Just truncate them.  */
+	while (ret == 0 && count > 0 && pos < PT_ACR0 / 2) {
+		u32 value = regs->gprs[(pos - PT_GPR0 / 2) / sizeof(u32)];
+		if (kbuf) {
+			*(u32 *) kbuf = value;
+			kbuf += sizeof(u32);
+		}
+		else if (put_user(value, (u32 __user *) ubuf))
+			ret = -EFAULT;
 		else
-			offset = offset*2;
-		tmp = *(__u32 *)((addr_t) &child->thread.per_info + offset);
+			ubuf += sizeof(u32);
+		pos += sizeof(u32);
+		count -= sizeof(u32);
+	}
 
-	} else
-		tmp = 0;
+	/* The ACRs are kept in the thread_struct.  */
+	if (ret == 0 && count > 0 && pos < PT_ACR0 / 2 + NUM_ACRS * ACR_SIZE) {
+		if (target == current)
+			save_access_regs(target->thread.acrs);
+
+		ret = utrace_regset_copyout(&pos, &count, &kbuf, &ubuf,
+					    target->thread.acrs,
+					    PT_ACR0 / 2,
+					    PT_ACR0 / 2 + NUM_ACRS * ACR_SIZE);
+	}
 
-	return put_user(tmp, (__u32 __user *) data);
+	/* Finally, the ORIG_GPR2 value.  */
+	if (count > 0) {
+		if (kbuf)
+			*(u32 *) kbuf = regs->orig_gpr2;
+		else if (put_user((u32) regs->orig_gpr2,
+				  (u32 __user *) ubuf))
+			return -EFAULT;
+	}
+
+	return 0;
 }
 
-/*
- * Same as poke_user but for a 31 bit program.
- */
 static int
-poke_user_emu31(struct task_struct *child, addr_t addr, addr_t data)
-{
-	struct user32 *dummy32 = NULL;
-	per_struct32 *dummy_per32 = NULL;
-	addr_t offset;
-	__u32 tmp;
+s390_genregs_set(struct task_struct *target,
+		 const struct utrace_regset *regset,
+		 unsigned int pos, unsigned int count,
+		 const void *kbuf, const void __user *ubuf)
+{
+	struct pt_regs *regs = task_pt_regs(target);
+	int ret = 0;
+
+	/* Check for an invalid PSW mask.  */
+	if (count > 0 && pos == PT_PSWMASK / 2) {
+		u32 pswmask;
+		ret = utrace_regset_copyin(&pos, &count, &kbuf, &ubuf,
+					   &pswmask, PT_PSWMASK / 2,
+					   PT_PSWADDR / 2);
+		if (ret)
+			return ret;
 
-	if (!test_thread_flag(TIF_31BIT) ||
-	    (addr & 3) || addr > sizeof(struct user32) - 3)
-		return -EIO;
+		if (pswmask != PSW_MASK_MERGE(psw_user32_bits, pswmask))
+			/* Invalid psw mask. */
+			return -EINVAL;
 
-	tmp = (__u32) data;
+		/* Build a 64 bit psw mask from 31 bit mask. */
+		regs->psw.mask = PSW_MASK_MERGE(psw_user32_bits,
+						(u64) pswmask << 32);
+		FixPerRegisters(target);
+	}
 
-	if (addr < (addr_t) &dummy32->regs.acrs) {
-		/*
-		 * psw, gprs, acrs and orig_gpr2 are stored on the stack
-		 */
-		if (addr == (addr_t) &dummy32->regs.psw.mask) {
+	/* Build a 64 bit psw address from 31 bit address. */
+	if (count > 0 && pos == PT_PSWADDR / 2) {
+		u32 pswaddr;
+		ret = utrace_regset_copyin(&pos, &count, &kbuf, &ubuf,
+					   &pswaddr, PT_PSWADDR / 2,
+					   PT_GPR0 / 2);
+		if (ret == 0)
 			/* Build a 64 bit psw mask from 31 bit mask. */
-			if (tmp != PSW32_MASK_MERGE(psw32_user_bits, tmp))
-				/* Invalid psw mask. */
-				return -EINVAL;
-			task_pt_regs(child)->psw.mask =
-				PSW_MASK_MERGE(psw_user32_bits, (__u64) tmp << 32);
-		} else if (addr == (addr_t) &dummy32->regs.psw.addr) {
-			/* Build a 64 bit psw address from 31 bit address. */
-			task_pt_regs(child)->psw.addr =
-				(__u64) tmp & PSW32_ADDR_INSN;
-		} else {
-			/* gpr 0-15 */
-			*(__u32*)((addr_t) &task_pt_regs(child)->psw
-				  + addr*2 + 4) = tmp;
+			regs->psw.addr = pswaddr & PSW32_ADDR_INSN;
+	}
+
+	/* The GPRs are directly onto the stack. */
+	while (ret == 0 && count > 0 && pos < PT_ACR0 / 2) {
+		u32 value;
+
+		if (kbuf) {
+			value = *(const u32 *) kbuf;
+			kbuf += sizeof(u32);
 		}
-	} else if (addr < (addr_t) (&dummy32->regs.orig_gpr2)) {
-		/*
-		 * access registers are stored in the thread structure
-		 */
-		offset = addr - (addr_t) &dummy32->regs.acrs;
-		*(__u32*)((addr_t) &child->thread.acrs + offset) = tmp;
+		else if (get_user(value, (const u32 __user *) ubuf))
+			return -EFAULT;
+		else
+			ubuf += sizeof(u32);
+		pos += sizeof(u32);
+		count -= sizeof(u32);
 
-	} else if (addr == (addr_t) (&dummy32->regs.orig_gpr2)) {
-		/*
-		 * orig_gpr2 is stored on the kernel stack
-		 */
-		*(__u32*)((addr_t) &task_pt_regs(child)->orig_gpr2 + 4) = tmp;
+		regs->gprs[(pos - PT_GPR0 / 2) / sizeof(u32)] = value;
+	}
 
-	} else if (addr < (addr_t) (&dummy32->regs.fp_regs + 1)) {
-		/*
-		 * floating point regs. are stored in the thread structure 
-		 */
-		if (addr == (addr_t) &dummy32->regs.fp_regs.fpc &&
-		    (tmp & ~FPC_VALID_MASK) != 0)
-			/* Invalid floating point control. */
-			return -EINVAL;
-	        offset = addr - (addr_t) &dummy32->regs.fp_regs;
-		*(__u32 *)((addr_t) &child->thread.fp_regs + offset) = tmp;
+	/* The ACRs are kept in the thread_struct.  */
+	if (count > 0 && pos < PT_ORIGGPR2 / 2) {
+		if (target == current
+		    && (pos != PT_ACR0 / 2
+			|| count < sizeof(target->thread.acrs)))
+			save_access_regs(target->thread.acrs);
+
+		ret = utrace_regset_copyin(&pos, &count, &kbuf, &ubuf,
+					   target->thread.acrs,
+					   PT_ACR0 / 2,
+					   PT_ACR0 / 2 + NUM_ACRS * ACR_SIZE);
 
-	} else if (addr < (addr_t) (&dummy32->regs.per_info + 1)) {
-		/*
-		 * per_info is found in the thread structure.
-		 */
-		offset = addr - (addr_t) &dummy32->regs.per_info;
-		/*
-		 * This is magic. See per_struct and per_struct32.
-		 * By incident the offsets in per_struct are exactly
-		 * twice the offsets in per_struct32 for all fields.
-		 * The 8 byte fields need special handling though,
-		 * because the second half (bytes 4-7) is needed and
-		 * not the first half.
-		 */
-		if ((offset >= (addr_t) &dummy_per32->control_regs &&
-		     offset < (addr_t) (&dummy_per32->control_regs + 1)) ||
-		    (offset >= (addr_t) &dummy_per32->starting_addr &&
-		     offset <= (addr_t) &dummy_per32->ending_addr) ||
-		    offset == (addr_t) &dummy_per32->lowcore.words.address)
-			offset = offset*2 + 4;
-		else
-			offset = offset*2;
-		*(__u32 *)((addr_t) &child->thread.per_info + offset) = tmp;
+		if (ret == 0 && target == current)
+			restore_access_regs(target->thread.acrs);
+	}
 
+	/* Finally, the ORIG_GPR2 value.  */
+	if (ret == 0 && count > 0) {
+		u32 value;
+		if (kbuf)
+			value = *(const u32 *) kbuf;
+		else if (get_user(value, (const u32 __user *) ubuf))
+			return -EFAULT;
+		regs->orig_gpr2 = value;
 	}
 
-	FixPerRegisters(child);
-	return 0;
+	return ret;
 }
 
-static int
-do_ptrace_emu31(struct task_struct *child, long request, long addr, long data)
+
+/*
+ * This is magic. See per_struct and per_struct32.
+ * By incident the offsets in per_struct are exactly
+ * twice the offsets in per_struct32 for all fields.
+ * The 8 byte fields need special handling though,
+ * because the second half (bytes 4-7) is needed and
+ * not the first half.
+ */
+static unsigned int
+offset_from_per32(unsigned int offset)
 {
-	unsigned int tmp;  /* 4 bytes !! */
-	ptrace_area_emu31 parea; 
-	int copied, ret;
-
-	switch (request) {
-	case PTRACE_PEEKTEXT:
-	case PTRACE_PEEKDATA:
-		/* read word at location addr. */
-		copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
-		if (copied != sizeof(tmp))
-			return -EIO;
-		return put_user(tmp, (unsigned int __force __user *) data);
-
-	case PTRACE_PEEKUSR:
-		/* read the word at location addr in the USER area. */
-		return peek_user_emu31(child, addr, data);
-
-	case PTRACE_POKETEXT:
-	case PTRACE_POKEDATA:
-		/* write the word at location addr. */
-		tmp = data;
-		copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 1);
-		if (copied != sizeof(tmp))
-			return -EIO;
-		return 0;
-
-	case PTRACE_POKEUSR:
-		/* write the word at location addr in the USER area */
-		return poke_user_emu31(child, addr, data);
-
-	case PTRACE_PEEKUSR_AREA:
-	case PTRACE_POKEUSR_AREA:
-		if (copy_from_user(&parea, (void __force __user *) addr,
-							sizeof(parea)))
-			return -EFAULT;
-		addr = parea.kernel_addr;
-		data = parea.process_addr;
-		copied = 0;
-		while (copied < parea.len) {
-			if (request == PTRACE_PEEKUSR_AREA)
-				ret = peek_user_emu31(child, addr, data);
-			else {
-				__u32 utmp;
-				if (get_user(utmp,
-					     (__u32 __force __user *) data))
-					return -EFAULT;
-				ret = poke_user_emu31(child, addr, utmp);
-			}
-			if (ret)
-				return ret;
-			addr += sizeof(unsigned int);
-			data += sizeof(unsigned int);
-			copied += sizeof(unsigned int);
+	BUILD_BUG_ON(offsetof(per_struct32, control_regs) != 0);
+	if (offset - offsetof(per_struct32, control_regs) < 3*sizeof(u32)
+	    || (offset >= offsetof(per_struct32, starting_addr) &&
+		offset <= offsetof(per_struct32, ending_addr))
+	    || offset == offsetof(per_struct32, lowcore.words.address))
+		offset = offset*2 + 4;
+	else
+		offset = offset*2;
+	return offset;
+}
+
+static int
+s390_per_info_get(struct task_struct *target,
+		  const struct utrace_regset *regset,
+		  unsigned int pos, unsigned int count,
+		  void *kbuf, void __user *ubuf)
+{
+	while (count > 0) {
+		u32 val = *(u32 *) ((char *) &target->thread.per_info
+				    + offset_from_per32 (pos));
+		if (kbuf) {
+			*(u32 *) kbuf = val;
+			kbuf += sizeof(u32);
 		}
-		return 0;
-#if 0				/* XXX */
-	case PTRACE_GETEVENTMSG:
-		return put_user((__u32) child->ptrace_message,
-				(unsigned int __force __user *) data);
-	case PTRACE_GETSIGINFO:
-		if (child->last_siginfo == NULL)
-			return -EINVAL;
-		return copy_siginfo_to_user32((compat_siginfo_t
-					       __force __user *) data,
-					      child->last_siginfo);
-	case PTRACE_SETSIGINFO:
-		if (child->last_siginfo == NULL)
-			return -EINVAL;
-		return copy_siginfo_from_user32(child->last_siginfo,
-						(compat_siginfo_t
-						 __force __user *) data);
+		else if (put_user(val, (u32 __user *) ubuf))
+			return -EFAULT;
+		else
+			ubuf += sizeof(u32);
+		pos += sizeof(u32);
+		count -= sizeof(u32);
 	}
-	return ptrace_request(child, request, addr, data);
+	return 0;
 }
-#endif
-
-#define PT32_IEEE_IP 0x13c
 
 static int
-do_ptrace(struct task_struct *child, long request, long addr, long data)
-{
-	int ret;
-
-	if (request == PTRACE_ATTACH)
-		return ptrace_attach(child);
+s390_per_info_set(struct task_struct *target,
+		  const struct utrace_regset *regset,
+		  unsigned int pos, unsigned int count,
+		  const void *kbuf, const void __user *ubuf)
+{
+	while (count > 0) {
+		u32 val;
+
+		if (kbuf) {
+			val = *(const u32 *) kbuf;
+			kbuf += sizeof(u32);
+		}
+		else if (get_user(val, (const u32 __user *) ubuf))
+			return -EFAULT;
+		else
+			ubuf += sizeof(u32);
+		pos += sizeof(u32);
+		count -= sizeof(u32);
 
-	/*
-	 * Special cases to get/store the ieee instructions pointer.
-	 */
-	if (child == current) {
-		if (request == PTRACE_PEEKUSR && addr == PT_IEEE_IP)
-			return peek_user(child, addr, data);
-		if (request == PTRACE_POKEUSR && addr == PT_IEEE_IP)
-			return poke_user(child, addr, data);
-#ifdef CONFIG_COMPAT
-		if (request == PTRACE_PEEKUSR &&
-		    addr == PT32_IEEE_IP && test_thread_flag(TIF_31BIT))
-			return peek_user_emu31(child, addr, data);
-		if (request == PTRACE_POKEUSR &&
-		    addr == PT32_IEEE_IP && test_thread_flag(TIF_31BIT))
-			return poke_user_emu31(child, addr, data);
-#endif
+		*(u32 *) ((char *) &target->thread.per_info
+			  + offset_from_per32 (pos)) = val;
 	}
+	return 0;
+}
 
-	ret = ptrace_check_attach(child, request == PTRACE_KILL);
-	if (ret < 0)
-		return ret;
-
-	switch (request) {
-	case PTRACE_SYSCALL:
-		/* continue and stop at next (return from) syscall */
-	case PTRACE_CONT:
-		/* restart after signal. */
-		if (!valid_signal(data))
-			return -EIO;
-		if (request == PTRACE_SYSCALL)
-			set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-		else
-			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-		child->exit_code = data;
-		/* make sure the single step bit is not set. */
-		tracehook_disable_single_step(child);
-		wake_up_process(child);
-		return 0;
-
-	case PTRACE_KILL:
-		/*
-		 * make the child exit.  Best I can do is send it a sigkill. 
-		 * perhaps it should be put in the status that it wants to 
-		 * exit.
-		 */
-		if (child->exit_state == EXIT_ZOMBIE) /* already dead */
-			return 0;
-		child->exit_code = SIGKILL;
-		/* make sure the single step bit is not set. */
-		tracehook_disable_single_step(child);
-		wake_up_process(child);
-		return 0;
-
-	case PTRACE_SINGLESTEP:
-		/* set the trap flag. */
-		if (!valid_signal(data))
-			return -EIO;
-		clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-		child->exit_code = data;
-		if (data)
-			set_tsk_thread_flag(child, TIF_SINGLE_STEP);
-		else
-			tracehook_enable_single_step(child);
-		/* give it a chance to run. */
-		wake_up_process(child);
-		return 0;
-
-	case PTRACE_DETACH:
-		/* detach a process that was attached. */
-		return ptrace_detach(child, data);
 
+static const struct utrace_regset s390_compat_regsets[] = {
+	{
+		.size = sizeof(u32), .align = sizeof(u32),
+		.n = sizeof(s390_regs) / sizeof(long),
+		.get = s390_genregs_get, .set = s390_genregs_set
+	},
+	{
+		.size = sizeof(u32), .align = sizeof(u32),
+		.n = sizeof(s390_fp_regs) / sizeof(u32),
+		.get = fpregs_get, .set = fpregs_set
+	},
+	{
+		.size = sizeof(u32), .align = sizeof(u32),
+		.n = sizeof(per_struct) / sizeof(u32),
+		.get = s390_per_info_get, .set = s390_per_info_set
+	},
+};
+
+static const struct utrace_regset_view utrace_s390_compat_view = {
+	.name = "s390", .e_machine = EM_S390,
+	.regsets = s390_compat_regsets, .n = ARRAY_SIZE(s390_compat_regsets)
+};
+#endif	/* CONFIG_COMPAT */
 
-	/* Do requests that differ for 31/64 bit */
-	default:
+const struct utrace_regset_view *utrace_native_view(struct task_struct *tsk)
+{
 #ifdef CONFIG_COMPAT
-		if (test_thread_flag(TIF_31BIT))
-			return do_ptrace_emu31(child, request, addr, data);
+        if (test_tsk_thread_flag(tsk, TIF_31BIT))
+                return &utrace_s390_compat_view;
 #endif
-		return do_ptrace_normal(child, request, addr, data);
-	}
-	/* Not reached.  */
-	return -EIO;
+        return &utrace_s390_native_view;
 }
 
-asmlinkage long
-sys_ptrace(long request, long pid, long addr, long data)
-{
-	struct task_struct *child;
-	int ret;
-
-	lock_kernel();
-	if (request == PTRACE_TRACEME) {
-		 ret = ptrace_traceme();
-		 goto out;
-	}
-
-	child = ptrace_get_task_struct(pid);
-	if (IS_ERR(child)) {
-		ret = PTR_ERR(child);
-		goto out;
-	}
-
-	ret = do_ptrace(child, request, addr, data);
-	put_task_struct(child);
-out:
-	unlock_kernel();
-	return ret;
-}
 
 asmlinkage void
 syscall_trace(struct pt_regs *regs, int entryexit)

linux-2.6-utrace-regset-sparc64.patch:

--- NEW FILE linux-2.6-utrace-regset-sparc64.patch ---
[PATCH 2b] utrace: sparc64 regset support

This patch converts the machine-dependent ptrace code into utrace regset
support for sparc64.

Signed-off-by: Roland McGrath <roland at redhat.com>
Signed-off-by: David S. Miller <davem at davemloft.net>

---

 arch/sparc64/kernel/Makefile  |    2 
 arch/sparc64/kernel/ptrace.c  |  631 +++++++++++++++++++++++++++++++++++++-----
 arch/sparc64/kernel/systbls.S |    4 
 3 files changed, 568 insertions(+), 69 deletions(-)

Index: b/arch/sparc64/kernel/Makefile
===================================================================
--- a/arch/sparc64/kernel/Makefile
+++ b/arch/sparc64/kernel/Makefile
@@ -5,6 +5,8 @@
 EXTRA_AFLAGS := -ansi
 EXTRA_CFLAGS := -Werror
 
+CFLAGS_ptrace.o += -DUTS_MACHINE='"$(UTS_MACHINE)"'
+
 extra-y		:= head.o init_task.o vmlinux.lds
 
 obj-y		:= process.o setup.o cpu.o idprom.o \
Index: b/arch/sparc64/kernel/ptrace.c
===================================================================
--- a/arch/sparc64/kernel/ptrace.c
+++ b/arch/sparc64/kernel/ptrace.c
@@ -1,6 +1,6 @@
-/* ptrace.c: Sparc process tracing support.
+/* ptrace.c: Sparc64 process tracing support.
  *
- * Copyright (C) 1996 David S. Miller (davem at caipfs.rutgers.edu)
+ * Copyright (C) 1996, 2006 David S. Miller (davem at davemloft.net)
  * Copyright (C) 1997 Jakub Jelinek (jj at sunsite.mff.cuni.cz)
  *
  * Based upon code written by Ross Biro, Linus Torvalds, Bob Manson,
@@ -11,106 +11,603 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
-#include <linux/errno.h>
-#include <linux/ptrace.h>
-#include <linux/user.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
 #include <linux/security.h>
 #include <linux/seccomp.h>
 #include <linux/audit.h>
-#include <linux/signal.h>
 #include <linux/tracehook.h>
+#include <linux/elf.h>
+#include <linux/ptrace.h>
 
 #include <asm/asi.h>
 #include <asm/pgtable.h>
 #include <asm/system.h>
-#include <asm/uaccess.h>
-#include <asm/psrcompat.h>
-#include <asm/visasm.h>
 #include <asm/spitfire.h>
 #include <asm/page.h>
 #include <asm/cpudata.h>
+#include <asm/psrcompat.h>
 
-#if 0				/* XXX */
-/* Returning from ptrace is a bit tricky because the syscall return
- * low level code assumes any value returned which is negative and
- * is a valid errno will mean setting the condition codes to indicate
- * an error return.  This doesn't work, so we have this hook.
+#define GENREG_G0	0
+#define GENREG_O0	8
+#define GENREG_L0	16
+#define GENREG_I0	24
+#define GENREG_TSTATE	32
+#define GENREG_TPC	33
+#define GENREG_TNPC	34
+#define GENREG_Y	35
+
+#define SPARC64_NGREGS	36
+
+static int genregs_get(struct task_struct *target,
+		       const struct utrace_regset *regset,
+		       unsigned int pos, unsigned int count,
+		       void *kbuf, void __user *ubuf)
+{
+	struct pt_regs *regs = task_pt_regs(target);
+	int err;
+
+	err = utrace_regset_copyout(&pos, &count, &kbuf, &ubuf, regs->u_regs,
+				    GENREG_G0 * 8, GENREG_L0 * 8);
+
+	if (err == 0 && count > 0 && pos < (GENREG_TSTATE * 8)) {
+		struct thread_info *t = task_thread_info(target);
+		unsigned long rwindow[16], fp, *win;
+		int wsaved;
+
+		if (target == current)
+			flushw_user();
+
+		wsaved = __thread_flag_byte_ptr(t)[TI_FLAG_BYTE_WSAVED];
+		fp = regs->u_regs[UREG_FP] + STACK_BIAS;
+		if (wsaved && t->rwbuf_stkptrs[wsaved - 1] == fp)
+			win = &t->reg_window[wsaved - 1].locals[0];
+		else {
+			if (target == current) {
+				if (copy_from_user(rwindow,
+						   (void __user *) fp,
+						   16 * sizeof(long)))
+					err = -EFAULT;
+			} else
+				err = access_process_vm(target, fp, rwindow,
+							16 * sizeof(long), 0);
+			if (err)
+				return err;
+			win = rwindow;
+		}
+
+		err = utrace_regset_copyout(&pos, &count, &kbuf, &ubuf,
+					    win, GENREG_L0 * 8,
+					    GENREG_TSTATE * 8);
+	}
+
+	if (err == 0)
+		err = utrace_regset_copyout(&pos, &count, &kbuf, &ubuf,
+					    &regs->tstate, GENREG_TSTATE * 8,
+					    GENREG_Y * 8);
+	if (err == 0 && count > 0) {
+		if (kbuf)
+			*(unsigned long *) kbuf = regs->y;
+		else if (put_user(regs->y, (unsigned long __user *) ubuf))
+			return -EFAULT;
+	}
+
+	return err;
+}
+
+/* Consistent with signal handling, we only allow userspace to
+ * modify the %asi, %icc, and %xcc fields of the %tstate register.
  */
-static inline void pt_error_return(struct pt_regs *regs, unsigned long error)
+#define TSTATE_DEBUGCHANGE	(TSTATE_ASI | TSTATE_ICC | TSTATE_XCC)
+
+static int genregs_set(struct task_struct *target,
+		       const struct utrace_regset *regset,
+		       unsigned int pos, unsigned int count,
+		       const void *kbuf, const void __user *ubuf)
 {
-	regs->u_regs[UREG_I0] = error;
-	regs->tstate |= (TSTATE_ICARRY | TSTATE_XCARRY);
-	regs->tpc = regs->tnpc;
-	regs->tnpc += 4;
+	struct pt_regs *regs = task_pt_regs(target);
+	unsigned long tstate_save;
+	int err;
+
+	err = utrace_regset_copyin(&pos, &count, &kbuf, &ubuf, regs->u_regs,
+				   GENREG_G0 * 8, GENREG_L0 * 8);
+
+	if (err == 0 && count > 0 && pos < (GENREG_TSTATE * 8)) {
+		unsigned long fp = regs->u_regs[UREG_FP] + STACK_BIAS;
+		unsigned long rwindow[16], *winbuf;
+		unsigned int copy = (GENREG_TSTATE * 8) - pos;
+		unsigned int off;
+		int err;
+
+		if (target == current)
+			flushw_user();
+
+		if (count < copy)
+			copy = count;
+		off = pos - (GENREG_L0 * 8);
+
+		if (kbuf) {
+			winbuf = (unsigned long *) kbuf;
+			kbuf += copy;
+		}
+		else {
+			winbuf = rwindow;
+			if (copy_from_user(winbuf, ubuf, copy))
+				return -EFAULT;
+			ubuf += copy;
+		}
+		count -= copy;
+		pos += copy;
+
+		if (target == current)
+			err = copy_to_user((void __user *) fp + off,
+					   winbuf, copy);
+		else
+			err = access_process_vm(target, fp + off,
+						winbuf, copy, 1);
+	}
+
+	tstate_save = regs->tstate &~ TSTATE_DEBUGCHANGE;
+
+	if (err == 0)
+		err = utrace_regset_copyin(&pos, &count, &kbuf, &ubuf,
+					    &regs->tstate, GENREG_TSTATE * 8,
+					    GENREG_Y * 8);
+
+	regs->tstate &= TSTATE_DEBUGCHANGE;
+	regs->tstate |= tstate_save;
+
+	if (err == 0 && count > 0) {
+		if (kbuf)
+			regs->y = *(unsigned long *) kbuf;
+		else if (get_user(regs->y, (unsigned long __user *) ubuf))
+			return -EFAULT;
+	}
+
+	return err;
 }
 
-static inline void pt_succ_return(struct pt_regs *regs, unsigned long value)
+#define FPREG_F0	0
+#define FPREG_FSR	32
+#define FPREG_GSR	33
+#define FPREG_FPRS	34
+
+#define SPARC64_NFPREGS	35
+
+static int fpregs_get(struct task_struct *target,
+		      const struct utrace_regset *regset,
+		      unsigned int pos, unsigned int count,
+		      void *kbuf, void __user *ubuf)
 {
-	regs->u_regs[UREG_I0] = value;
-	regs->tstate &= ~(TSTATE_ICARRY | TSTATE_XCARRY);
-	regs->tpc = regs->tnpc;
-	regs->tnpc += 4;
+	struct thread_info *t = task_thread_info(target);
+	int err;
+
+	err = utrace_regset_copyout(&pos, &count, &kbuf, &ubuf,
+				    t->fpregs, FPREG_F0 * 8, FPREG_FSR * 8);
+
+	if (err == 0)
+		err = utrace_regset_copyout(&pos, &count, &kbuf, &ubuf,
+					    &t->xfsr[0], FPREG_FSR * 8,
+					    FPREG_GSR * 8);
+
+	if (err == 0)
+		err = utrace_regset_copyout(&pos, &count, &kbuf, &ubuf,
+					    &t->gsr[0], FPREG_GSR * 8,
+					    FPREG_FPRS * 8);
+
+	if (err == 0 && count > 0) {
+		struct pt_regs *regs = task_pt_regs(target);
+
+		if (kbuf)
+			*(unsigned long *) kbuf = regs->fprs;
+		else if (put_user(regs->fprs, (unsigned long __user *) ubuf))
+			return -EFAULT;
+	}
+
+	return err;
 }
 
-static inline void
-pt_succ_return_linux(struct pt_regs *regs, unsigned long value, void __user *addr)
+static int fpregs_set(struct task_struct *target,
+		      const struct utrace_regset *regset,
+		      unsigned int pos, unsigned int count,
+		      const void *kbuf, const void __user *ubuf)
 {
-	if (test_thread_flag(TIF_32BIT)) {
-		if (put_user(value, (unsigned int __user *) addr)) {
-			pt_error_return(regs, EFAULT);
-			return;
-		}
-	} else {
-		if (put_user(value, (long __user *) addr)) {
-			pt_error_return(regs, EFAULT);
-			return;
+	struct thread_info *t = task_thread_info(target);
+	int err;
+
+	err = utrace_regset_copyin(&pos, &count, &kbuf, &ubuf,
+				   t->fpregs, FPREG_F0 * 8, FPREG_FSR * 8);
+
+	if (err == 0)
+		err = utrace_regset_copyin(&pos, &count, &kbuf, &ubuf,
+					   &t->xfsr[0], FPREG_FSR * 8,
+					   FPREG_GSR * 8);
+
+	if (err == 0)
+		err = utrace_regset_copyin(&pos, &count, &kbuf, &ubuf,
+					   &t->gsr[0], FPREG_GSR * 8,
+					   FPREG_FPRS * 8);
+
+	if (err == 0 && count > 0) {
+		struct pt_regs *regs = task_pt_regs(target);
+
+		if (kbuf)
+			regs->fprs = *(unsigned long *) kbuf;
+		else if (get_user(regs->fprs, (unsigned long __user *) ubuf))
+			return -EFAULT;
+	}
+
+	return err;
+}
+
+static const struct utrace_regset native_regsets[] = {
+	{
+		.n = SPARC64_NGREGS,
+		.size = sizeof(long), .align = sizeof(long),
+		.get = genregs_get, .set = genregs_set
+	},
+	{
+		.n = SPARC64_NFPREGS,
+		.size = sizeof(long), .align = sizeof(long),
+		.get = fpregs_get, .set = fpregs_set
+	},
+};
+
+static const struct utrace_regset_view utrace_sparc64_native_view = {
+	.name = UTS_MACHINE, .e_machine = ELF_ARCH,
+	.regsets = native_regsets, .n = ARRAY_SIZE(native_regsets)
+};
+
+#ifdef CONFIG_COMPAT
+
+#define GENREG32_G0	0
+#define GENREG32_O0	8
+#define GENREG32_L0	16
+#define GENREG32_I0	24
+#define GENREG32_PSR	32
+#define GENREG32_PC	33
+#define GENREG32_NPC	34
+#define GENREG32_Y	35
+#define GENREG32_WIM	36
+#define GENREG32_TBR	37
+
+#define SPARC32_NGREGS	38
+
+static int genregs32_get(struct task_struct *target,
+			 const struct utrace_regset *regset,
+			 unsigned int pos, unsigned int count,
+			 void *kbuf, void __user *ubuf)
+{
+	struct pt_regs *regs = task_pt_regs(target);
+
+	while (count > 0 && pos < (GENREG32_L0 * 4)) {
+		u32 val = regs->u_regs[(pos - (GENREG32_G0*4))/sizeof(u32)];
+		if (kbuf) {
+			*(u32 *) kbuf = val;
+			kbuf += sizeof(u32);
+		} else if (put_user(val, (u32 __user *) ubuf))
+			return -EFAULT;
+		else
+			ubuf += sizeof(u32);
+		pos += sizeof(u32);
+		count -= sizeof(u32);
+	}
+
+	if (count > 0 && pos < (GENREG32_PSR * 4)) {
+		struct thread_info *t = task_thread_info(target);
+		unsigned long fp;
+		u32 rwindow[16];
+		int wsaved;
+
+		if (target == current)
+			flushw_user();
+
+		wsaved = __thread_flag_byte_ptr(t)[TI_FLAG_BYTE_WSAVED];
+		fp = regs->u_regs[UREG_FP] & 0xffffffffUL;
+		if (wsaved && t->rwbuf_stkptrs[wsaved - 1] == fp) {
+			int i;
+			for (i = 0; i < 8; i++)
+				rwindow[i + 0] =
+					t->reg_window[wsaved-1].locals[i];
+			for (i = 0; i < 8; i++)
+				rwindow[i + 8] =
+					t->reg_window[wsaved-1].ins[i];
+		} else {
+			int err;
+
+			if (target == current) {
+				err = 0;
+				if (copy_from_user(rwindow, (void __user *) fp,
+						   16 * sizeof(u32)))
+					err = -EFAULT;
+			} else
+				err = access_process_vm(target, fp, rwindow,
+							16 * sizeof(u32), 0);
+			if (err)
+				return err;
+		}
+
+		while (count > 0 && pos < (GENREG32_PSR * 4)) {
+			u32 val = rwindow[(pos - (GENREG32_L0*4))/sizeof(u32)];
+
+			if (kbuf) {
+				*(u32 *) kbuf = val;
+				kbuf += sizeof(u32);
+			} else if (put_user(val, (u32 __user *) ubuf))
+				return -EFAULT;
+			else
+				ubuf += sizeof(u32);
+			pos += sizeof(u32);
+			count -= sizeof(u32);
 		}
 	}
-	regs->u_regs[UREG_I0] = 0;
-	regs->tstate &= ~(TSTATE_ICARRY | TSTATE_XCARRY);
-	regs->tpc = regs->tnpc;
-	regs->tnpc += 4;
+
+	if (count > 0 && pos == (GENREG32_PSR * 4)) {
+		u32 psr = tstate_to_psr(regs->tstate);
+
+		if (kbuf) {
+			*(u32 *) kbuf = psr;
+			kbuf += sizeof(u32);
+		} else if (put_user(psr, (u32 __user *) ubuf))
+			return -EFAULT;
+		else
+			ubuf += sizeof(u32);
+		pos += sizeof(u32);
+		count -= sizeof(u32);
+	}
+
+	if (count > 0 && pos == (GENREG32_PC * 4)) {
+		u32 val = regs->tpc;
+
+		if (kbuf) {
+			*(u32 *) kbuf = val;
+			kbuf += sizeof(u32);
+		} else if (put_user(val, (u32 __user *) ubuf))
+			return -EFAULT;
+		else
+			ubuf += sizeof(u32);
+		pos += sizeof(u32);
+		count -= sizeof(u32);
+	}
+
+	if (count > 0 && pos == (GENREG32_NPC * 4)) {
+		u32 val = regs->tnpc;
+
+		if (kbuf) {
+			*(u32 *) kbuf = val;
+			kbuf += sizeof(u32);
+		} else if (put_user(val, (u32 __user *) ubuf))
+			return -EFAULT;
+		else
+			ubuf += sizeof(u32);
+		pos += sizeof(u32);
+		count -= sizeof(u32);
+	}
+
+	if (count > 0 && pos == (GENREG32_Y * 4)) {
+		if (kbuf) {
+			*(u32 *) kbuf = regs->y;
+			kbuf += sizeof(u32);
+		} else if (put_user(regs->y, (u32 __user *) ubuf))
+			return -EFAULT;
+		else
+			ubuf += sizeof(u32);
+		pos += sizeof(u32);
+		count -= sizeof(u32);
+	}
+
+	if (count > 0) {
+		if (kbuf)
+			memset(kbuf, 0, count);
+		else if (clear_user(ubuf, count))
+			return -EFAULT;
+	}
+
+	return 0;
+}
+
+static int genregs32_set(struct task_struct *target,
+			 const struct utrace_regset *regset,
+			 unsigned int pos, unsigned int count,
+			 const void *kbuf, const void __user *ubuf)
+{
+	struct pt_regs *regs = task_pt_regs(target);
+
+	while (count > 0 && pos < (GENREG32_L0 * 4)) {
+		unsigned long *loc;
+		loc = &regs->u_regs[(pos - (GENREG32_G0*4))/sizeof(u32)];
+		if (kbuf) {
+			*loc = *(u32 *) kbuf;
+			kbuf += sizeof(u32);
+		} else if (get_user(*loc, (u32 __user *) ubuf))
+			return -EFAULT;
+		else
+			ubuf += sizeof(u32);
+		pos += sizeof(u32);
+		count -= sizeof(u32);
+	}
+
+	if (count > 0 && pos < (GENREG32_PSR * 4)) {
+		unsigned long fp;
+		u32 regbuf[16];
+		unsigned int off, copy;
+		int err;
+
+		if (target == current)
+			flushw_user();
+
+		copy = (GENREG32_PSR * 4) - pos;
+		if (count < copy)
+			copy = count;
+		BUG_ON(copy > 16 * sizeof(u32));
+
+		fp = regs->u_regs[UREG_FP] & 0xffffffffUL;
+		off = pos - (GENREG32_L0 * 4);
+		if (kbuf) {
+			memcpy(regbuf, kbuf, copy);
+			kbuf += copy;
+		} else if (copy_from_user(regbuf, ubuf, copy))
+			return -EFAULT;
+		else
+			ubuf += copy;
+		pos += copy;
+		count -= copy;
+
+		if (target == current) {
+			err = 0;
+			if (copy_to_user((void __user *) fp + off,
+					 regbuf, count))
+				err = -EFAULT;
+		} else
+			err = access_process_vm(target, fp + off,
+						regbuf, count, 1);
+		if (err)
+			return err;
+	}
+
+	if (count > 0 && pos == (GENREG32_PSR * 4)) {
+		unsigned long tstate, tstate_save;
+		u32 psr;
+
+		tstate_save = regs->tstate&~(TSTATE_ICC|TSTATE_XCC);
+
+		if (kbuf) {
+			psr = *(u32 *) kbuf;
+			kbuf += sizeof(u32);
+		} else if (get_user(psr, (u32 __user *) ubuf))
+			return -EFAULT;
+		else
+			ubuf += sizeof(u32);
+		pos += sizeof(u32);
+		count -= sizeof(u32);
+
+		tstate = psr_to_tstate_icc(psr);
+		regs->tstate = tstate_save | tstate;
+	}
+
+	if (count > 0 && pos == (GENREG32_PC * 4)) {
+		if (kbuf) {
+			regs->tpc = *(u32 *) kbuf;
+			kbuf += sizeof(u32);
+		} else if (get_user(regs->tpc, (u32 __user *) ubuf))
+			return -EFAULT;
+		else
+			ubuf += sizeof(u32);
+		pos += sizeof(u32);
+		count -= sizeof(u32);
+	}
+
+	if (count > 0 && pos == (GENREG32_NPC * 4)) {
+		if (kbuf) {
+			regs->tnpc = *(u32 *) kbuf;
+			kbuf += sizeof(u32);
+		} else if (get_user(regs->tnpc, (u32 __user *) ubuf))
+			return -EFAULT;
+		else
+			ubuf += sizeof(u32);
+		pos += sizeof(u32);
+		count -= sizeof(u32);
+	}
+
+	if (count > 0 && pos == (GENREG32_Y * 4)) {
+		if (kbuf) {
+			regs->y = *(u32 *) kbuf;
+			kbuf += sizeof(u32);
+		} else if (get_user(regs->y, (u32 __user *) ubuf))
+			return -EFAULT;
+		else
+			ubuf += sizeof(u32);
+		pos += sizeof(u32);
+		count -= sizeof(u32);
+	}
+
+	/* Ignore WIM and TBR */
+
+	return 0;
 }
 
-static void
-pt_os_succ_return (struct pt_regs *regs, unsigned long val, void __user *addr)
+#define FPREG32_F0	0
+#define FPREG32_FSR	32
+
+#define SPARC32_NFPREGS	33
+
+static int fpregs32_get(struct task_struct *target,
+			const struct utrace_regset *regset,
+			unsigned int pos, unsigned int count,
+			void *kbuf, void __user *ubuf)
 {
-	if (current->personality == PER_SUNOS)
-		pt_succ_return (regs, val);
-	else
-		pt_succ_return_linux (regs, val, addr);
+	struct thread_info *t = task_thread_info(target);
+	int err;
+
+	err = utrace_regset_copyout(&pos, &count, &kbuf, &ubuf,
+				    t->fpregs, FPREG32_F0 * 4,
+				    FPREG32_FSR * 4);
+
+	if (err == 0 && count > 0) {
+		if (kbuf) {
+			*(u32 *) kbuf = t->xfsr[0];
+		} else if (put_user(t->xfsr[0], (u32 __user *) ubuf))
+			return -EFAULT;
+	}
+
+	return err;
 }
-#endif
 
-/* #define ALLOW_INIT_TRACING */
-/* #define DEBUG_PTRACE */
+static int fpregs32_set(struct task_struct *target,
+			const struct utrace_regset *regset,
+			unsigned int pos, unsigned int count,
+			const void *kbuf, const void __user *ubuf)
+{
+	struct thread_info *t = task_thread_info(target);
+	int err;
 
-#ifdef DEBUG_PTRACE
-char *pt_rq [] = {
-	/* 0  */ "TRACEME", "PEEKTEXT", "PEEKDATA", "PEEKUSR",
-	/* 4  */ "POKETEXT", "POKEDATA", "POKEUSR", "CONT",
-	/* 8  */ "KILL", "SINGLESTEP", "SUNATTACH", "SUNDETACH",
-	/* 12 */ "GETREGS", "SETREGS", "GETFPREGS", "SETFPREGS",
-	/* 16 */ "READDATA", "WRITEDATA", "READTEXT", "WRITETEXT",
-	/* 20 */ "GETFPAREGS", "SETFPAREGS", "unknown", "unknown",
-	/* 24 */ "SYSCALL", ""
+	err = utrace_regset_copyin(&pos, &count, &kbuf, &ubuf,
+				   t->fpregs, FPREG32_F0 * 4,
+				   FPREG32_FSR * 4);
+
+	if (err == 0 && count > 0) {
+		u32 fsr;
+		if (kbuf) {
+			fsr = *(u32 *) kbuf;
+		} else if (get_user(fsr, (u32 __user *) ubuf))
+			return -EFAULT;
+		t->xfsr[0] = (t->xfsr[0] & 0xffffffff00000000UL) | fsr;
+	}
+
+	return 0;
+}
+
+static const struct utrace_regset sparc32_regsets[] = {
+	{
+		.n = SPARC32_NGREGS,
+		.size = sizeof(u32), .align = sizeof(u32),
+		.get = genregs32_get, .set = genregs32_set
+	},
+	{
+		.n = SPARC32_NFPREGS,
+		.size = sizeof(u32), .align = sizeof(u32),
+		.get = fpregs32_get, .set = fpregs32_set
+	},
 };
-#endif
 
-/*
- * Called by kernel/ptrace.c when detaching..
- *
- * Make sure single step bits etc are not set.
- */
-void ptrace_disable(struct task_struct *child)
+static const struct utrace_regset_view utrace_sparc32_view = {
+	.name = "sparc", .e_machine = EM_SPARC,
+	.regsets = sparc32_regsets, .n = ARRAY_SIZE(sparc32_regsets)
+};
+
+#endif	/* CONFIG_COMPAT */
+
+const struct utrace_regset_view *utrace_native_view(struct task_struct *tsk)
 {
-	/* nothing to do */
+#ifdef CONFIG_COMPAT
+	if (test_tsk_thread_flag(tsk, TIF_32BIT))
+		return &utrace_sparc32_view;
+#endif
+	return &utrace_sparc64_native_view;
 }
 
+
 /* To get the necessary page struct, access_process_vm() first calls
  * get_user_pages().  This has done a flush_dcache_page() on the
  * accessed page.  Then our caller (copy_{to,from}_user_page()) did
Index: b/arch/sparc64/kernel/systbls.S
===================================================================
--- a/arch/sparc64/kernel/systbls.S
+++ b/arch/sparc64/kernel/systbls.S
@@ -24,7 +24,7 @@ sys_call_table32:
 /*10*/  .word sys_unlink, sunos_execv, sys_chdir, sys32_chown16, sys32_mknod
 /*15*/	.word sys_chmod, sys32_lchown16, sparc_brk, sys32_perfctr, sys32_lseek
 /*20*/	.word sys_getpid, sys_capget, sys_capset, sys32_setuid16, sys32_getuid16
-/*25*/	.word sys32_vmsplice, sys_ptrace, sys_alarm, sys32_sigaltstack, sys32_pause
+/*25*/	.word sys32_vmsplice, compat_sys_ptrace, sys_alarm, sys32_sigaltstack, sys32_pause
 /*30*/	.word compat_sys_utime, sys_lchown, sys_fchown, sys32_access, sys32_nice
 	.word sys_chown, sys_sync, sys32_kill, compat_sys_newstat, sys32_sendfile
 /*40*/	.word compat_sys_newlstat, sys_dup, sys_pipe, compat_sys_times, sys_getuid
@@ -168,7 +168,7 @@ sunos_sys_table:
 	.word sys_chmod, sys32_lchown16, sunos_brk
 	.word sunos_nosys, sys32_lseek, sunos_getpid
 	.word sunos_nosys, sunos_nosys, sunos_nosys
-	.word sunos_getuid, sunos_nosys, sys_ptrace
+	.word sunos_getuid, sunos_nosys, compat_sys_ptrace
 	.word sunos_nosys, sunos_nosys, sunos_nosys
 	.word sunos_nosys, sunos_nosys, sunos_nosys
 	.word sys_access, sunos_nosys, sunos_nosys

linux-2.6-utrace-regset.patch:

--- NEW FILE linux-2.6-utrace-regset.patch ---
[PATCH 2] utrace: register sets

This provides a new uniform interface in <linux/tracehook.h> for accessing
registers and similar per-thread machine resources.  The old architecture
ptrace code for accessing register state is rolled into new functions to
flesh out the utrace_regset interface.  Nothing yet uses this interface.
The hope is that this interface can cover most of the machine-dependent
issues for any higher-level tracing/debugging interface.

Signed-off-by: Roland McGrath <roland at redhat.com>

---

 arch/i386/kernel/i387.c             |  143 +++---
 arch/i386/kernel/ptrace.c           |  822 ++++++++++++++++++++----------------
 arch/powerpc/kernel/Makefile        |    4 
 arch/powerpc/kernel/ptrace-common.h |  145 ------
 arch/powerpc/kernel/ptrace.c        |  718 +++++++++++++++----------------
 arch/powerpc/kernel/ptrace32.c      |  443 -------------------
 arch/x86_64/ia32/fpu32.c            |   92 +++-
 arch/x86_64/ia32/ptrace32.c         |  721 ++++++++++++++++++++-----------
 arch/x86_64/kernel/ptrace.c         |  730 +++++++++++++++++++------------
 include/asm-i386/i387.h             |   13 
 include/asm-x86_64/fpu32.h          |    3 
 include/asm-x86_64/tracehook.h      |    8 
 include/linux/tracehook.h           |  244 ++++++++++
 kernel/ptrace.c                     |    8 
 14 files changed, 2125 insertions(+), 1969 deletions(-)
 delete arch/powerpc/kernel/ptrace32.c
 delete arch/powerpc/kernel/ptrace-common.h

Index: b/arch/i386/kernel/i387.c
===================================================================
--- a/arch/i386/kernel/i387.c
+++ b/arch/i386/kernel/i387.c
@@ -222,14 +222,10 @@ void set_fpu_twd( struct task_struct *ts
  * FXSR floating point environment conversions.
  */
 
-static int convert_fxsr_to_user( struct _fpstate __user *buf,
-					struct i387_fxsave_struct *fxsave )
+static inline void
+convert_fxsr_env_to_i387(unsigned long env[7],
+			 struct i387_fxsave_struct *fxsave)
 {
-	unsigned long env[7];
-	struct _fpreg __user *to;
-	struct _fpxreg *from;
-	int i;
-
 	env[0] = (unsigned long)fxsave->cwd | 0xffff0000ul;
 	env[1] = (unsigned long)fxsave->swd | 0xffff0000ul;
 	env[2] = twd_fxsr_to_i387(fxsave);
@@ -237,7 +233,17 @@ static int convert_fxsr_to_user( struct 
 	env[4] = fxsave->fcs | ((unsigned long)fxsave->fop << 16);
 	env[5] = fxsave->foo;
 	env[6] = fxsave->fos;
+}
+
+static int convert_fxsr_to_user(struct _fpstate __user *buf,
+				struct i387_fxsave_struct *fxsave)
+{
+	unsigned long env[7];
+	struct _fpreg __user *to;
+	struct _fpxreg *from;
+	int i;
 
+	convert_fxsr_env_to_i387(env, fxsave);
 	if ( __copy_to_user( buf, env, 7 * sizeof(unsigned long) ) )
 		return 1;
 
@@ -255,6 +261,20 @@ static int convert_fxsr_to_user( struct 
 	return 0;
 }
 
+static inline void
+convert_fxsr_env_from_i387(struct i387_fxsave_struct *fxsave,
+			   const unsigned long env[7])
+{
+	fxsave->cwd = (unsigned short)(env[0] & 0xffff);
+	fxsave->swd = (unsigned short)(env[1] & 0xffff);
+	fxsave->twd = twd_i387_to_fxsr((unsigned short)(env[2] & 0xffff));
+	fxsave->fip = env[3];
+	fxsave->fop = (unsigned short)((env[4] & 0xffff0000ul) >> 16);
+	fxsave->fcs = (env[4] & 0xffff);
+	fxsave->foo = env[5];
+	fxsave->fos = env[6];
+}
+
 static int convert_fxsr_from_user( struct i387_fxsave_struct *fxsave,
 					  struct _fpstate __user *buf )
 {
@@ -266,14 +286,7 @@ static int convert_fxsr_from_user( struc
 	if ( __copy_from_user( env, buf, 7 * sizeof(long) ) )
 		return 1;
 
-	fxsave->cwd = (unsigned short)(env[0] & 0xffff);
-	fxsave->swd = (unsigned short)(env[1] & 0xffff);
-	fxsave->twd = twd_i387_to_fxsr((unsigned short)(env[2] & 0xffff));
-	fxsave->fip = env[3];
-	fxsave->fop = (unsigned short)((env[4] & 0xffff0000ul) >> 16);
-	fxsave->fcs = (env[4] & 0xffff);
-	fxsave->foo = env[5];
-	fxsave->fos = env[6];
+	convert_fxsr_env_from_i387(fxsave, env);
 
 	to = (struct _fpxreg *) &fxsave->st_space[0];
 	from = &buf->_st[0];
@@ -388,88 +401,82 @@ int restore_i387( struct _fpstate __user
  * ptrace request handlers.
  */
 
-static inline int get_fpregs_fsave( struct user_i387_struct __user *buf,
-				    struct task_struct *tsk )
+static inline void get_fpregs_fsave(struct user_i387_struct *buf,
+				    struct task_struct *tsk)
 {
-	return __copy_to_user( buf, &tsk->thread.i387.fsave,
-			       sizeof(struct user_i387_struct) );
+	memcpy(buf, &tsk->thread.i387.fsave, sizeof(struct user_i387_struct));
 }
 
-static inline int get_fpregs_fxsave( struct user_i387_struct __user *buf,
-				     struct task_struct *tsk )
+static inline void get_fpregs_fxsave(struct user_i387_struct *buf,
+				     struct task_struct *tsk)
 {
-	return convert_fxsr_to_user( (struct _fpstate __user *)buf,
-				     &tsk->thread.i387.fxsave );
+	struct _fpreg *to;
+	const struct _fpxreg *from;
+	unsigned int i;
+
+	convert_fxsr_env_to_i387((unsigned long *) buf,
+				 &tsk->thread.i387.fxsave);
+
+	to = (struct _fpreg *) buf->st_space;
+	from = (const struct _fpxreg *) &tsk->thread.i387.fxsave.st_space[0];
+	for (i = 0; i < 8; i++, to++, from++)
+		*to = *(const struct _fpreg *) from;
 }
 
-int get_fpregs( struct user_i387_struct __user *buf, struct task_struct *tsk )
+int get_fpregs(struct user_i387_struct *buf, struct task_struct *tsk)
 {
 	if ( HAVE_HWFP ) {
-		if ( cpu_has_fxsr ) {
-			return get_fpregs_fxsave( buf, tsk );
-		} else {
-			return get_fpregs_fsave( buf, tsk );
-		}
+		if (cpu_has_fxsr)
+			get_fpregs_fxsave(buf, tsk);
+		else
+			get_fpregs_fsave(buf, tsk);
+		return 0;
 	} else {
 		return save_i387_soft( &tsk->thread.i387.soft,
 				       (struct _fpstate __user *)buf );
 	}
 }
 
-static inline int set_fpregs_fsave( struct task_struct *tsk,
-				    struct user_i387_struct __user *buf )
+static inline void set_fpregs_fsave(struct task_struct *tsk,
+				    const struct user_i387_struct *buf)
 {
-	return __copy_from_user( &tsk->thread.i387.fsave, buf,
-				 sizeof(struct user_i387_struct) );
+	memcpy(&tsk->thread.i387.fsave, buf, sizeof(struct user_i387_struct));
 }
 
-static inline int set_fpregs_fxsave( struct task_struct *tsk,
-				     struct user_i387_struct __user *buf )
+static inline void set_fpregs_fxsave(struct task_struct *tsk,
+				     const struct user_i387_struct *buf)
 {
-	return convert_fxsr_from_user( &tsk->thread.i387.fxsave,
-				       (struct _fpstate __user *)buf );
+	struct _fpxreg *to;
+	const struct _fpreg *from;
+	unsigned int i;
+
+	convert_fxsr_env_from_i387(&tsk->thread.i387.fxsave,
+				   (unsigned long *) buf);
+
+	to = (struct _fpxreg *) &tsk->thread.i387.fxsave.st_space[0];
+	from = (const struct _fpreg *) buf->st_space;
+	for (i = 0; i < 8; i++, to++, from++)
+		*(struct _fpreg *) to = *from;
 }
 
-int set_fpregs( struct task_struct *tsk, struct user_i387_struct __user *buf )
+int set_fpregs(struct task_struct *tsk, const struct user_i387_struct *buf)
 {
 	if ( HAVE_HWFP ) {
-		if ( cpu_has_fxsr ) {
-			return set_fpregs_fxsave( tsk, buf );
-		} else {
[...4350 lines suppressed...]
+ * might refer to the same machine-specific state in the thread.  For
+ * example, a 32-bit thread's state could be examined from the 32-bit
+ * view or from the 64-bit view.  Either method reaches the same thread
+ * register state, doing appropriate widening or truncation.
+ */
+struct utrace_regset_view {
+	const char *name;
+	const struct utrace_regset *regsets;
+	unsigned int n;
+	u16 e_machine;
+};
+
+/*
+ * This is documented here rather than at the definition sites because its
+ * implementation is machine-dependent but its interface is universal.
+ */
+/**
+ * utrace_native_view - Return the process's native regset view.
+ * @tsk: a thread of the process in question
+ *
+ * Return the &struct utrace_regset_view that is native for the given process.
+ * For example, what it would access when it called ptrace().
+ * Throughout the life of the process, this only changes at exec.
+ */
+const struct utrace_regset_view *utrace_native_view(struct task_struct *tsk);
+
+
+/*
+ * These are helpers for writing regset get/set functions in arch code.
+ * Because @start_pos and @end_pos are always compile-time constants,
+ * these are inlined into very little code though they look large.
+ *
+ * Use one or more calls sequentially for each chunk of regset data stored
+ * contiguously in memory.  Call with constants for @start_pos and @end_pos,
+ * giving the range of byte positions in the regset that data corresponds
+ * to; @end_pos can be -1 if this chunk is at the end of the regset layout.
+ * Each call updates the arguments to point past its chunk.
+ */
+
+static inline int
+utrace_regset_copyout(unsigned int *pos, unsigned int *count,
+		      void **kbuf, void __user **ubuf,
+		      const void *data, int start_pos, int end_pos)
+{
+	if (*count == 0)
+		return 0;
+	BUG_ON(*pos < start_pos);
+	if (end_pos < 0 || *pos < end_pos) {
+		unsigned int copy = (end_pos < 0 ? *count
+				     : min(*count, end_pos - *pos));
+		data += *pos - start_pos;
+		if (*kbuf) {
+			memcpy(*kbuf, data, copy);
+			*kbuf += copy;
+		}
+		else if (copy_to_user(*ubuf, data, copy))
+			return -EFAULT;
+		else
+			*ubuf += copy;
+		*pos += copy;
+		*count -= copy;
+	}
+	return 0;
+}
+
+static inline int
+utrace_regset_copyin(unsigned int *pos, unsigned int *count,
+		     const void **kbuf, const void __user **ubuf,
+		     void *data, int start_pos, int end_pos)
+{
+	if (*count == 0)
+		return 0;
+	BUG_ON(*pos < start_pos);
+	if (end_pos < 0 || *pos < end_pos) {
+		unsigned int copy = (end_pos < 0 ? *count
+				     : min(*count, end_pos - *pos));
+		data += *pos - start_pos;
+		if (*kbuf) {
+			memcpy(data, *kbuf, copy);
+			*kbuf += copy;
+		}
+		else if (copy_from_user(data, *ubuf, copy))
+			return -EFAULT;
+		else
+			*ubuf += copy;
+		*pos += copy;
+		*count -= copy;
+	}
+	return 0;
+}
+
+/*
+ * These two parallel the two above, but for portions of a regset layout
+ * that always read as all-zero or for which writes are ignored.
+ */
+static inline int
+utrace_regset_copyout_zero(unsigned int *pos, unsigned int *count,
+			   void **kbuf, void __user **ubuf,
+			   int start_pos, int end_pos)
+{
+	if (*count == 0)
+		return 0;
+	BUG_ON(*pos < start_pos);
+	if (end_pos < 0 || *pos < end_pos) {
+		unsigned int copy = (end_pos < 0 ? *count
+				     : min(*count, end_pos - *pos));
+		if (*kbuf) {
+			memset(*kbuf, 0, copy);
+			*kbuf += copy;
+		}
+		else if (clear_user(*ubuf, copy))
+			return -EFAULT;
+		else
+			*ubuf += copy;
+		*pos += copy;
+		*count -= copy;
+	}
+	return 0;
+}
+
+static inline int
+utrace_regset_copyin_ignore(unsigned int *pos, unsigned int *count,
+			    const void **kbuf, const void __user **ubuf,
+			    int start_pos, int end_pos)
+{
+	if (*count == 0)
+		return 0;
+	BUG_ON(*pos < start_pos);
+	if (end_pos < 0 || *pos < end_pos) {
+		unsigned int copy = (end_pos < 0 ? *count
+				     : min(*count, end_pos - *pos));
+		if (*kbuf)
+			*kbuf += copy;
+		else
+			*ubuf += copy;
+		*pos += copy;
+		*count -= copy;
+	}
+	return 0;
+}
+
+
 /*
  * Following are entry points from core code, where the user debugging
  * support can affect the normal behavior.  The locking situation is
Index: b/include/asm-i386/i387.h
===================================================================
--- a/include/asm-i386/i387.h
+++ b/include/asm-i386/i387.h
@@ -129,17 +129,12 @@ extern int save_i387( struct _fpstate __
 extern int restore_i387( struct _fpstate __user *buf );
 
 /*
- * ptrace request handers...
+ * ptrace request handlers...
  */
-extern int get_fpregs( struct user_i387_struct __user *buf,
-		       struct task_struct *tsk );
-extern int set_fpregs( struct task_struct *tsk,
-		       struct user_i387_struct __user *buf );
+extern int get_fpregs(struct user_i387_struct *, struct task_struct *);
+extern int set_fpregs(struct task_struct *, const struct user_i387_struct *);
+extern void updated_fpxregs(struct task_struct *tsk);
 
-extern int get_fpxregs( struct user_fxsr_struct __user *buf,
-			struct task_struct *tsk );
-extern int set_fpxregs( struct task_struct *tsk,
-			struct user_fxsr_struct __user *buf );
 
 /*
  * FPU state for core dumps...
Index: b/include/asm-x86_64/fpu32.h
===================================================================
--- a/include/asm-x86_64/fpu32.h
+++ b/include/asm-x86_64/fpu32.h
@@ -7,4 +7,7 @@ int restore_i387_ia32(struct task_struct
 int save_i387_ia32(struct task_struct *tsk, struct _fpstate_ia32 __user *buf, 
 		   struct pt_regs *regs, int fsave);
 
+int get_fpregs32(struct user_i387_ia32_struct *, struct task_struct *);
+int set_fpregs32(struct task_struct *, const struct user_i387_ia32_struct *);
+
 #endif
Index: b/include/asm-x86_64/tracehook.h
===================================================================
--- a/include/asm-x86_64/tracehook.h
+++ b/include/asm-x86_64/tracehook.h
@@ -48,4 +48,12 @@ static inline void tracehook_abort_sysca
 	regs->orig_rax = -1L;
 }
 
+/*
+ * These are used directly by some of the regset code.
+ */
+extern const struct utrace_regset_view utrace_x86_64_native;
+#ifdef CONFIG_IA32_EMULATION
+extern const struct utrace_regset_view utrace_ia32_view;
+#endif
+
 #endif

linux-2.6-utrace-sig_kernel-macros.patch:

--- NEW FILE linux-2.6-utrace-sig_kernel-macros.patch ---
>From 55c0d1f83e481dd6c77f52f7dcfeb043b8b740fa Mon Sep 17 00:00:00 2001
From: Roland McGrath <roland at redhat.com>
Date: Wed, 9 May 2007 02:33:37 -0700
Subject: [PATCH] Move sig_kernel_* et al macros to linux/signal.h

This patch moves the sig_kernel_* and related macros from kernel/signal.c
to linux/signal.h, and cleans them up slightly.  I need the sig_kernel_*
macros for default signal behavior in the utrace code, and want to avoid
duplication or overhead to share the knowledge.

Signed-off-by: Roland McGrath <roland at redhat.com>
Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
---
 include/linux/signal.h |  125 ++++++++++++++++++++++++++++++++++++++++++++++++
 kernel/signal.c        |  119 ---------------------------------------------
 2 files changed, 125 insertions(+), 119 deletions(-)

diff --git a/include/linux/signal.h b/include/linux/signal.h
index 1474905..3fa0fab 100644  
--- a/include/linux/signal.h
+++ b/include/linux/signal.h
@@ -243,6 +243,131 @@ extern int get_signal_to_deliver(siginfo
 
 extern struct kmem_cache *sighand_cachep;
 
+/*
+ * In POSIX a signal is sent either to a specific thread (Linux task)
+ * or to the process as a whole (Linux thread group).  How the signal
+ * is sent determines whether it's to one thread or the whole group,
+ * which determines which signal mask(s) are involved in blocking it
+ * from being delivered until later.  When the signal is delivered,
+ * either it's caught or ignored by a user handler or it has a default
+ * effect that applies to the whole thread group (POSIX process).
+ *
+ * The possible effects an unblocked signal set to SIG_DFL can have are:
+ *   ignore	- Nothing Happens
+ *   terminate	- kill the process, i.e. all threads in the group,
+ * 		  similar to exit_group.  The group leader (only) reports
+ *		  WIFSIGNALED status to its parent.
+ *   coredump	- write a core dump file describing all threads using
+ *		  the same mm and then kill all those threads
+ *   stop 	- stop all the threads in the group, i.e. TASK_STOPPED state
+ *
+ * SIGKILL and SIGSTOP cannot be caught, blocked, or ignored.
+ * Other signals when not blocked and set to SIG_DFL behaves as follows.
+ * The job control signals also have other special effects.
+ *
+ *	+--------------------+------------------+
+ *	|  POSIX signal      |  default action  |
+ *	+--------------------+------------------+
+ *	|  SIGHUP            |  terminate	|
+ *	|  SIGINT            |	terminate	|
+ *	|  SIGQUIT           |	coredump 	|
+ *	|  SIGILL            |	coredump 	|
+ *	|  SIGTRAP           |	coredump 	|
+ *	|  SIGABRT/SIGIOT    |	coredump 	|
+ *	|  SIGBUS            |	coredump 	|
+ *	|  SIGFPE            |	coredump 	|
+ *	|  SIGKILL           |	terminate(+)	|
+ *	|  SIGUSR1           |	terminate	|
+ *	|  SIGSEGV           |	coredump 	|
+ *	|  SIGUSR2           |	terminate	|
+ *	|  SIGPIPE           |	terminate	|
+ *	|  SIGALRM           |	terminate	|
+ *	|  SIGTERM           |	terminate	|
+ *	|  SIGCHLD           |	ignore   	|
+ *	|  SIGCONT           |	ignore(*)	|
+ *	|  SIGSTOP           |	stop(*)(+)  	|
+ *	|  SIGTSTP           |	stop(*)  	|
+ *	|  SIGTTIN           |	stop(*)  	|
+ *	|  SIGTTOU           |	stop(*)  	|
+ *	|  SIGURG            |	ignore   	|
+ *	|  SIGXCPU           |	coredump 	|
+ *	|  SIGXFSZ           |	coredump 	|
+ *	|  SIGVTALRM         |	terminate	|
+ *	|  SIGPROF           |	terminate	|
+ *	|  SIGPOLL/SIGIO     |	terminate	|
+ *	|  SIGSYS/SIGUNUSED  |	coredump 	|
+ *	|  SIGSTKFLT         |	terminate	|
+ *	|  SIGWINCH          |	ignore   	|
+ *	|  SIGPWR            |	terminate	|
+ *	|  SIGRTMIN-SIGRTMAX |	terminate       |
+ *	+--------------------+------------------+
+ *	|  non-POSIX signal  |  default action  |
+ *	+--------------------+------------------+
+ *	|  SIGEMT            |  coredump	|
+ *	+--------------------+------------------+
+ *
+ * (+) For SIGKILL and SIGSTOP the action is "always", not just "default".
+ * (*) Special job control effects:
+ * When SIGCONT is sent, it resumes the process (all threads in the group)
+ * from TASK_STOPPED state and also clears any pending/queued stop signals
+ * (any of those marked with "stop(*)").  This happens regardless of blocking,
+ * catching, or ignoring SIGCONT.  When any stop signal is sent, it clears
+ * any pending/queued SIGCONT signals; this happens regardless of blocking,
+ * catching, or ignored the stop signal, though (except for SIGSTOP) the
+ * default action of stopping the process may happen later or never.
+ */
+
+#ifdef SIGEMT
+#define SIGEMT_MASK	rt_sigmask(SIGEMT)
+#else
+#define SIGEMT_MASK	0
+#endif
+
+#if SIGRTMIN > BITS_PER_LONG
+#define rt_sigmask(sig)	(1ULL << ((sig)-1))
+#else
+#define rt_sigmask(sig)	sigmask(sig)
+#endif
+#define siginmask(sig, mask) (rt_sigmask(sig) & (mask))
+
+#define SIG_KERNEL_ONLY_MASK (\
+	rt_sigmask(SIGKILL)   |  rt_sigmask(SIGSTOP))
+
+#define SIG_KERNEL_STOP_MASK (\
+	rt_sigmask(SIGSTOP)   |  rt_sigmask(SIGTSTP)   | \
+	rt_sigmask(SIGTTIN)   |  rt_sigmask(SIGTTOU)   )
+
+#define SIG_KERNEL_COREDUMP_MASK (\
+        rt_sigmask(SIGQUIT)   |  rt_sigmask(SIGILL)    | \
+	rt_sigmask(SIGTRAP)   |  rt_sigmask(SIGABRT)   | \
+        rt_sigmask(SIGFPE)    |  rt_sigmask(SIGSEGV)   | \
+	rt_sigmask(SIGBUS)    |  rt_sigmask(SIGSYS)    | \
+        rt_sigmask(SIGXCPU)   |  rt_sigmask(SIGXFSZ)   | \
+	SIGEMT_MASK				       )
+
+#define SIG_KERNEL_IGNORE_MASK (\
+        rt_sigmask(SIGCONT)   |  rt_sigmask(SIGCHLD)   | \
+	rt_sigmask(SIGWINCH)  |  rt_sigmask(SIGURG)    )
+
+#define sig_kernel_only(sig) \
+	(((sig) < SIGRTMIN) && siginmask(sig, SIG_KERNEL_ONLY_MASK))
+#define sig_kernel_coredump(sig) \
+	(((sig) < SIGRTMIN) && siginmask(sig, SIG_KERNEL_COREDUMP_MASK))
+#define sig_kernel_ignore(sig) \
+	(((sig) < SIGRTMIN) && siginmask(sig, SIG_KERNEL_IGNORE_MASK))
+#define sig_kernel_stop(sig) \
+	(((sig) < SIGRTMIN) && siginmask(sig, SIG_KERNEL_STOP_MASK))
+
+#define sig_needs_tasklist(sig)	((sig) == SIGCONT)
+
+#define sig_user_defined(t, signr) \
+	(((t)->sighand->action[(signr)-1].sa.sa_handler != SIG_DFL) &&	\
+	 ((t)->sighand->action[(signr)-1].sa.sa_handler != SIG_IGN))
+
+#define sig_fatal(t, signr) \
+	(!siginmask(signr, SIG_KERNEL_IGNORE_MASK|SIG_KERNEL_STOP_MASK) && \
+	 (t)->sighand->action[(signr)-1].sa.sa_handler == SIG_DFL)
+
 #endif /* __KERNEL__ */
 
 #endif /* _LINUX_SIGNAL_H */
diff --git a/kernel/signal.c b/kernel/signal.c
index 1368e67..4c8f49e 100644  
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -38,125 +38,6 @@
 
 static struct kmem_cache *sigqueue_cachep;
 
-/*
- * In POSIX a signal is sent either to a specific thread (Linux task)
- * or to the process as a whole (Linux thread group).  How the signal
- * is sent determines whether it's to one thread or the whole group,
- * which determines which signal mask(s) are involved in blocking it
- * from being delivered until later.  When the signal is delivered,
- * either it's caught or ignored by a user handler or it has a default
- * effect that applies to the whole thread group (POSIX process).
- *
- * The possible effects an unblocked signal set to SIG_DFL can have are:
- *   ignore	- Nothing Happens
- *   terminate	- kill the process, i.e. all threads in the group,
- * 		  similar to exit_group.  The group leader (only) reports
- *		  WIFSIGNALED status to its parent.
- *   coredump	- write a core dump file describing all threads using
- *		  the same mm and then kill all those threads
- *   stop 	- stop all the threads in the group, i.e. TASK_STOPPED state
- *
- * SIGKILL and SIGSTOP cannot be caught, blocked, or ignored.
- * Other signals when not blocked and set to SIG_DFL behaves as follows.
- * The job control signals also have other special effects.
- *
- *	+--------------------+------------------+
- *	|  POSIX signal      |  default action  |
- *	+--------------------+------------------+
- *	|  SIGHUP            |  terminate	|
- *	|  SIGINT            |	terminate	|
- *	|  SIGQUIT           |	coredump 	|
- *	|  SIGILL            |	coredump 	|
- *	|  SIGTRAP           |	coredump 	|
- *	|  SIGABRT/SIGIOT    |	coredump 	|
- *	|  SIGBUS            |	coredump 	|
- *	|  SIGFPE            |	coredump 	|
- *	|  SIGKILL           |	terminate(+)	|
- *	|  SIGUSR1           |	terminate	|
- *	|  SIGSEGV           |	coredump 	|
- *	|  SIGUSR2           |	terminate	|
- *	|  SIGPIPE           |	terminate	|
- *	|  SIGALRM           |	terminate	|
- *	|  SIGTERM           |	terminate	|
- *	|  SIGCHLD           |	ignore   	|
- *	|  SIGCONT           |	ignore(*)	|
- *	|  SIGSTOP           |	stop(*)(+)  	|
- *	|  SIGTSTP           |	stop(*)  	|
- *	|  SIGTTIN           |	stop(*)  	|
- *	|  SIGTTOU           |	stop(*)  	|
- *	|  SIGURG            |	ignore   	|
- *	|  SIGXCPU           |	coredump 	|
- *	|  SIGXFSZ           |	coredump 	|
- *	|  SIGVTALRM         |	terminate	|
- *	|  SIGPROF           |	terminate	|
- *	|  SIGPOLL/SIGIO     |	terminate	|
- *	|  SIGSYS/SIGUNUSED  |	coredump 	|
- *	|  SIGSTKFLT         |	terminate	|
- *	|  SIGWINCH          |	ignore   	|
- *	|  SIGPWR            |	terminate	|
- *	|  SIGRTMIN-SIGRTMAX |	terminate       |
- *	+--------------------+------------------+
- *	|  non-POSIX signal  |  default action  |
- *	+--------------------+------------------+
- *	|  SIGEMT            |  coredump	|
- *	+--------------------+------------------+
- *
- * (+) For SIGKILL and SIGSTOP the action is "always", not just "default".
- * (*) Special job control effects:
- * When SIGCONT is sent, it resumes the process (all threads in the group)
- * from TASK_STOPPED state and also clears any pending/queued stop signals
- * (any of those marked with "stop(*)").  This happens regardless of blocking,
- * catching, or ignoring SIGCONT.  When any stop signal is sent, it clears
- * any pending/queued SIGCONT signals; this happens regardless of blocking,
- * catching, or ignored the stop signal, though (except for SIGSTOP) the
- * default action of stopping the process may happen later or never.
- */
-
-#ifdef SIGEMT
-#define M_SIGEMT	M(SIGEMT)
-#else
-#define M_SIGEMT	0
-#endif
-
-#if SIGRTMIN > BITS_PER_LONG
-#define M(sig) (1ULL << ((sig)-1))
-#else
-#define M(sig) (1UL << ((sig)-1))
-#endif
-#define T(sig, mask) (M(sig) & (mask))
-
-#define SIG_KERNEL_ONLY_MASK (\
-	M(SIGKILL)   |  M(SIGSTOP)                                   )
-
-#define SIG_KERNEL_STOP_MASK (\
-	M(SIGSTOP)   |  M(SIGTSTP)   |  M(SIGTTIN)   |  M(SIGTTOU)   )
-
-#define SIG_KERNEL_COREDUMP_MASK (\
-        M(SIGQUIT)   |  M(SIGILL)    |  M(SIGTRAP)   |  M(SIGABRT)   | \
-        M(SIGFPE)    |  M(SIGSEGV)   |  M(SIGBUS)    |  M(SIGSYS)    | \
-        M(SIGXCPU)   |  M(SIGXFSZ)   |  M_SIGEMT                     )
-
-#define SIG_KERNEL_IGNORE_MASK (\
-        M(SIGCONT)   |  M(SIGCHLD)   |  M(SIGWINCH)  |  M(SIGURG)    )
-
-#define sig_kernel_only(sig) \
-		(((sig) < SIGRTMIN)  && T(sig, SIG_KERNEL_ONLY_MASK))
-#define sig_kernel_coredump(sig) \
-		(((sig) < SIGRTMIN)  && T(sig, SIG_KERNEL_COREDUMP_MASK))
-#define sig_kernel_ignore(sig) \
-		(((sig) < SIGRTMIN)  && T(sig, SIG_KERNEL_IGNORE_MASK))
-#define sig_kernel_stop(sig) \
-		(((sig) < SIGRTMIN)  && T(sig, SIG_KERNEL_STOP_MASK))
-
-#define sig_needs_tasklist(sig)	((sig) == SIGCONT)
-
-#define sig_user_defined(t, signr) \
-	(((t)->sighand->action[(signr)-1].sa.sa_handler != SIG_DFL) &&	\
-	 ((t)->sighand->action[(signr)-1].sa.sa_handler != SIG_IGN))
-
-#define sig_fatal(t, signr) \
-	(!T(signr, SIG_KERNEL_IGNORE_MASK|SIG_KERNEL_STOP_MASK) && \
-	 (t)->sighand->action[(signr)-1].sa.sa_handler == SIG_DFL)
 
 static int sig_ignored(struct task_struct *t, int sig)
 {
-- 
1.5.0.6


linux-2.6-utrace-tracehook-avr32.patch:

--- NEW FILE linux-2.6-utrace-tracehook-avr32.patch ---
[PATCH 1e] utrace: tracehook for AVR32

From: Haavard Skinnemoen <hskinnemoen at atmel.com>

This patch does the initial tracehook conversion for AVR32.

Signed-off-by: Haavard Skinnemoen <hskinnemoen at atmel.com>
Signed-off-by: Roland McGrath <roland at redhat.com>

---

 arch/avr32/kernel/ptrace.c       |  102 ++++++++++----------------------------
 arch/avr32/kernel/process.c      |    2 -
 arch/avr32/kernel/entry-avr32b.S |   10 +++-
 include/asm-avr32/tracehook.h    |   62 +++++++++++++++++++++++
 4 files changed, 96 insertions(+), 80 deletions(-)
 create include/asm-avr32/tracehook.h

--- linux-2.6/arch/avr32/kernel/ptrace.c
+++ linux-2.6/arch/avr32/kernel/ptrace.c
@@ -5,20 +5,16 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-#undef DEBUG
+#include <linux/compile.h>
+#include <linux/elf.h>
+#include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <linux/ptrace.h>
 #include <linux/errno.h>
 #include <linux/user.h>
-#include <linux/security.h>
-#include <linux/unistd.h>
-#include <linux/notifier.h>
-
-#include <asm/traps.h>
-#include <asm/uaccess.h>
-#include <asm/ocd.h>
+
 #include <asm/mmu_context.h>
 #include <linux/kdebug.h>
 
@@ -28,52 +24,7 @@ static struct pt_regs *get_user_regs(str
 				  THREAD_SIZE - sizeof(struct pt_regs));
 }
 
-static void ptrace_single_step(struct task_struct *tsk)
-{
-	pr_debug("ptrace_single_step: pid=%u, SR=0x%08lx\n",
-		 tsk->pid, tsk->thread.cpu_context.sr);
-	if (!(tsk->thread.cpu_context.sr & SR_D)) {
-		/*
-		 * Set a breakpoint at the current pc to force the
-		 * process into debug mode.  The syscall/exception
-		 * exit code will set a breakpoint at the return
-		 * address when this flag is set.
-		 */
-		pr_debug("ptrace_single_step: Setting TIF_BREAKPOINT\n");
-		set_tsk_thread_flag(tsk, TIF_BREAKPOINT);
-	}
-
-	/* The monitor code will do the actual step for us */
-	set_tsk_thread_flag(tsk, TIF_SINGLE_STEP);
-}
-
-/*
- * Called by kernel/ptrace.c when detaching
- *
- * Make sure any single step bits, etc. are not set
- */
-void ptrace_disable(struct task_struct *child)
-{
-	clear_tsk_thread_flag(child, TIF_SINGLE_STEP);
-}
-
-/*
- * Handle hitting a breakpoint
- */
-static void ptrace_break(struct task_struct *tsk, struct pt_regs *regs)
-{
-	siginfo_t info;
-
-	info.si_signo = SIGTRAP;
-	info.si_errno = 0;
-	info.si_code  = TRAP_BRKPT;
-	info.si_addr  = (void __user *)instruction_pointer(regs);
-
-	pr_debug("ptrace_break: Sending SIGTRAP to PID %u (pc = 0x%p)\n",
-		 tsk->pid, info.si_addr);
-	force_sig_info(SIGTRAP, &info, tsk);
-}
-
+#if 0
 /*
  * Read the word at offset "offset" into the task's "struct user". We
  * actually access the pt_regs struct stored on the kernel stack.
@@ -248,32 +199,31 @@ long arch_ptrace(struct task_struct *chi
 	pr_debug("sys_ptrace returning %d (DC = 0x%08lx)\n", ret, __mfdr(DBGREG_DC));
 	return ret;
 }
+#endif
 
-asmlinkage void syscall_trace(void)
+asmlinkage void syscall_trace(struct pt_regs *regs, int is_exit)
 {
-	pr_debug("syscall_trace called\n");
 	if (!test_thread_flag(TIF_SYSCALL_TRACE))
 		return;
-	if (!(current->ptrace & PT_PTRACED))
-		return;
 
-	pr_debug("syscall_trace: notifying parent\n");
-	/* The 0x80 provides a way for the tracing parent to
-	 * distinguish between a syscall stop and SIGTRAP delivery */
-	ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
-				 ? 0x80 : 0));
+	tracehook_report_syscall(regs, is_exit);
+}
 
-	/*
-	 * this isn't the same as continuing with a signal, but it
-	 * will do for normal use.  strace only continues with a
-	 * signal if the stopping signal is not SIGTRAP.  -brl
-	 */
-	if (current->exit_code) {
-		pr_debug("syscall_trace: sending signal %d to PID %u\n",
-			 current->exit_code, current->pid);
-		send_sig(current->exit_code, current, 1);
-		current->exit_code = 0;
-	}
+/*
+ * Handle hitting a breakpoint
+ */
+static void do_breakpoint(struct task_struct *tsk, struct pt_regs *regs)
+{
+	siginfo_t info;
+
+	info.si_signo = SIGTRAP;
+	info.si_errno = 0;
+	info.si_code  = TRAP_BRKPT;
+	info.si_addr  = (void __user *)instruction_pointer(regs);
+
+	pr_debug("ptrace_break: Sending SIGTRAP to PID %u (pc = 0x%p)\n",
+		 tsk->pid, info.si_addr);
+	force_sig_info(SIGTRAP, &info, tsk);
 }
 
 asmlinkage void do_debug_priv(struct pt_regs *regs)
@@ -352,10 +302,10 @@ asmlinkage void do_debug(struct pt_regs 
 			__mtdr(DBGREG_DC, dc);
 
 			clear_thread_flag(TIF_SINGLE_STEP);
-			ptrace_break(current, regs);
+			do_breakpoint(current, regs);
 		}
 	} else {
 		/* regular breakpoint */
-		ptrace_break(current, regs);
+		do_breakpoint(current, regs);
 	}
 }
--- linux-2.6/arch/avr32/kernel/process.c
+++ linux-2.6/arch/avr32/kernel/process.c
@@ -382,8 +382,6 @@ asmlinkage int sys_execve(char __user *u
 		goto out;
 
 	error = do_execve(filename, uargv, uenvp, regs);
-	if (error == 0)
-		current->ptrace &= ~PT_DTRACE;
 	putname(filename);
 
 out:
--- linux-2.6/arch/avr32/kernel/entry-avr32b.S
+++ linux-2.6/arch/avr32/kernel/entry-avr32b.S
@@ -223,15 +223,21 @@ ret_from_fork:
 	rjmp    syscall_exit_cont
 
 syscall_trace_enter:
-	pushm	r8-r12
+	mov	r12, sp		/* regs		*/
+	mov	r11, 0		/* is_exit	*/
 	rcall	syscall_trace
-	popm	r8-r12
+
+	/* syscall_trace may update r8, so reload r8-r12 from regs. */
+	sub	lr, sp, -REG_R12
+	ldm	lr, r8-r12
 	rjmp	syscall_trace_cont
 
 syscall_exit_work:
 	bld	r1, TIF_SYSCALL_TRACE
 	brcc	1f
 	unmask_interrupts
+	mov	r12, sp
+	mov	r11, 1
 	rcall	syscall_trace
 	mask_interrupts
 	ld.w	r1, r0[TI_flags]
--- linux-2.6/include/asm-avr32/tracehook.h
+++ linux-2.6/include/asm-avr32/tracehook.h
@@ -0,0 +1,62 @@
+/*
+ * Tracing hooks for AVR32
+ *
+ * Copyright (C) 2007 Atmel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef _ASM_AVR32_TRACEHOOK_H
+#define _ASM_AVR32_TRACEHOOK_H
+
+#include <linux/sched.h>
+
+#define ARCH_HAS_SINGLE_STEP	1
+
+static inline void tracehook_enable_single_step(struct task_struct *tsk)
+{
+	/*
+	 * If the process is stopped in debug mode, simply set
+	 * TIF_SINGLE_STEP to tell the monitor code to set the single
+	 * step bit in DC before returning.
+	 *
+	 * Otherwise, we need to set a breakpoint at the return
+	 * address before returning to userspace. TIF_BREAKPOINT will
+	 * tell the syscall/exception exit code to do this.
+	 */
+	if (!(tsk->thread.cpu_context.sr & SR_D))
+		set_tsk_thread_flag(tsk, TIF_BREAKPOINT);
+
+	set_tsk_thread_flag(tsk, TIF_SINGLE_STEP);
+}
+
+static inline void tracehook_disable_single_step(struct task_struct *tsk)
+{
+	clear_tsk_thread_flag(tsk, TIF_BREAKPOINT);
+	clear_tsk_thread_flag(tsk, TIF_SINGLE_STEP);
+}
+
+static inline int tracehook_single_step_enabled(struct task_struct *tsk)
+{
+	return test_tsk_thread_flag(tsk, TIF_SINGLE_STEP);
+}
+
+static inline void tracehook_enable_syscall_trace(struct task_struct *tsk)
+{
+	set_tsk_thread_flag(tsk, TIF_SYSCALL_TRACE);
+}
+
+static inline void tracehook_disable_syscall_trace(struct task_struct *tsk)
+{
+	clear_tsk_thread_flag(tsk, TIF_SYSCALL_TRACE);
+}
+
+static inline void tracehook_abort_syscall(struct pt_regs *regs)
+{
+	/* Invalid system call number => return -ENOSYS */
+	regs->r8 = -1;
+}
+
+
+#endif /* _ASM_AVR32_TRACEHOOK_H */

linux-2.6-utrace-tracehook-ia64.patch:

--- NEW FILE linux-2.6-utrace-tracehook-ia64.patch ---
[PATCH 1a] utrace: tracehook for ia64

This patch does the initial tracehook conversion for ia64.

Signed-off-by: Roland McGrath <roland at redhat.com>
Signed-off-by: Anil S Keshavamurthy <anil.s.keshavamurthy at intel.com>
Signed-off-by: Bibo mao <bibo.mao at intel.com>

---

 arch/ia64/ia32/ia32_entry.S  |    2 -
 arch/ia64/ia32/sys_ia32.c    |   23 ++-----------
 arch/ia64/kernel/ptrace.c    |   39 +++++-----------------
 arch/ia64/kernel/signal.c    |    4 +-
 include/asm-ia64/tracehook.h |   73 +++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 91 insertions(+), 50 deletions(-)
 create include/asm-ia64/tracehook.h

Index: b/arch/ia64/ia32/ia32_entry.S
===================================================================
--- a/arch/ia64/ia32/ia32_entry.S
+++ b/arch/ia64/ia32/ia32_entry.S
@@ -236,7 +236,7 @@ ia32_syscall_table:
 	data8 sys_setuid	/* 16-bit version */
 	data8 sys_getuid	/* 16-bit version */
 	data8 compat_sys_stime    /* 25 */
-	data8 sys32_ptrace
+	data8 compat_sys_ptrace
 	data8 sys32_alarm
 	data8 sys_ni_syscall
 	data8 sys32_pause
Index: b/arch/ia64/ia32/sys_ia32.c
===================================================================
--- a/arch/ia64/ia32/sys_ia32.c
+++ b/arch/ia64/ia32/sys_ia32.c
@@ -1436,25 +1436,6 @@ sys32_waitpid (int pid, unsigned int *st
 	return compat_sys_wait4(pid, stat_addr, options, NULL);
 }
 
-static unsigned int
-ia32_peek (struct task_struct *child, unsigned long addr, unsigned int *val)
-{
-	size_t copied;
-	unsigned int ret;
-
-	copied = access_process_vm(child, addr, val, sizeof(*val), 0);
-	return (copied != sizeof(ret)) ? -EIO : 0;
-}
-
-static unsigned int
-ia32_poke (struct task_struct *child, unsigned long addr, unsigned int val)
-{
-
-	if (access_process_vm(child, addr, &val, sizeof(val), 1) != sizeof(val))
-		return -EIO;
-	return 0;
-}
-
 /*
  *  The order in which registers are stored in the ptrace regs structure
  */
@@ -1752,6 +1733,7 @@ restore_ia32_fpxstate (struct task_struc
 	return 0;
 }
 
+#if 0				/* XXX */
 asmlinkage long
 sys32_ptrace (int request, pid_t pid, unsigned int addr, unsigned int data)
 {
@@ -1859,9 +1841,11 @@ sys32_ptrace (int request, pid_t pid, un
 					    compat_ptr(data));
 		break;
 
+#if 0				/* XXX */
 	      case PTRACE_GETEVENTMSG:   
 		ret = put_user(child->ptrace_message, (unsigned int __user *) compat_ptr(data));
 		break;
+#endif
 
 	      case PTRACE_SYSCALL:	/* continue, stop after next syscall */
 	      case PTRACE_CONT:		/* restart after signal. */
@@ -1882,6 +1866,7 @@ sys32_ptrace (int request, pid_t pid, un
 	unlock_kernel();
 	return ret;
 }
+#endif
 
 typedef struct {
 	unsigned int	ss_sp;
Index: b/arch/ia64/kernel/ptrace.c
===================================================================
--- a/arch/ia64/kernel/ptrace.c
+++ b/arch/ia64/kernel/ptrace.c
@@ -12,6 +12,7 @@
 #include <linux/mm.h>
 #include <linux/errno.h>
 #include <linux/ptrace.h>
+#include <linux/tracehook.h>
 #include <linux/smp_lock.h>
 #include <linux/user.h>
 #include <linux/security.h>
@@ -1598,28 +1599,6 @@ sys_ptrace (long request, pid_t pid, uns
 	return ret;
 }
 
-
-static void
-syscall_trace (void)
-{
-	/*
-	 * The 0x80 provides a way for the tracing parent to
-	 * distinguish between a syscall stop and SIGTRAP delivery.
-	 */
-	ptrace_notify(SIGTRAP
-		      | ((current->ptrace & PT_TRACESYSGOOD) ? 0x80 : 0));
-
-	/*
-	 * This isn't the same as continuing with a signal, but it
-	 * will do for normal use.  strace only continues with a
-	 * signal if the stopping signal is not SIGTRAP.  -brl
-	 */
-	if (current->exit_code) {
-		send_sig(current->exit_code, current, 1);
-		current->exit_code = 0;
-	}
-}
-
 /* "asmlinkage" so the input arguments are preserved... */
 
 asmlinkage void
@@ -1627,9 +1606,8 @@ syscall_trace_enter (long arg0, long arg
 		     long arg4, long arg5, long arg6, long arg7,
 		     struct pt_regs regs)
 {
-	if (test_thread_flag(TIF_SYSCALL_TRACE) 
-	    && (current->ptrace & PT_PTRACED))
-		syscall_trace();
+	if (test_thread_flag(TIF_SYSCALL_TRACE))
+		tracehook_report_syscall(&regs, 0);
 
 	if (unlikely(current->audit_context)) {
 		long syscall;
@@ -1664,8 +1642,11 @@ syscall_trace_leave (long arg0, long arg
 		audit_syscall_exit(success, result);
 	}
 
-	if ((test_thread_flag(TIF_SYSCALL_TRACE)
-	    || test_thread_flag(TIF_SINGLESTEP))
-	    && (current->ptrace & PT_PTRACED))
-		syscall_trace();
+	if (test_thread_flag(TIF_SYSCALL_TRACE))
+		tracehook_report_syscall(&regs, 1);
+
+	if (test_thread_flag(TIF_SINGLESTEP)) {
+		force_sig(SIGTRAP, current); /* XXX */
+		tracehook_report_syscall_step(&regs);
+	}
 }
Index: b/arch/ia64/kernel/signal.c
===================================================================
--- a/arch/ia64/kernel/signal.c
+++ b/arch/ia64/kernel/signal.c
@@ -10,7 +10,7 @@
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
-#include <linux/ptrace.h>
+#include <linux/tracehook.h>
 #include <linux/sched.h>
 #include <linux/signal.h>
 #include <linux/smp.h>
@@ -471,6 +471,8 @@ handle_signal (unsigned long sig, struct
 		sigaddset(&current->blocked, sig);
 	recalc_sigpending();
 	spin_unlock_irq(&current->sighand->siglock);
+
+	tracehook_report_handle_signal(sig, ka, oldset, &scr->pt);
 	return 1;
 }
 
Index: b/include/asm-ia64/tracehook.h
===================================================================
--- /dev/null
+++ b/include/asm-ia64/tracehook.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C)2006 Intel Co
+ *	Anil S Keshavamurthy <anil.s.keshavamurthy at intel.com>
+ *	and Bibo Mao <bibo.mao at intel.com> adapted from i386.
+ *
+ * 	Tracing hooks, ia64 CPU support
+ */
+
+#ifndef _ASM_TRACEHOOK_H
+#define _ASM_TRACEHOOK_H	1
+
+#include <linux/sched.h>
+#include <asm/ptrace.h>
+
+/*
+ * See linux/tracehook.h for the descriptions of what these need to do.
+ */
+
+#define ARCH_HAS_SINGLE_STEP	(1)
+#define ARCH_HAS_BLOCK_STEP	(1)
+
+static inline void tracehook_enable_single_step(struct task_struct *tsk)
+{
+	struct pt_regs *pt = task_pt_regs(tsk);
+	ia64_psr(pt)->ss = 1;
+	set_tsk_thread_flag(tsk, TIF_SINGLESTEP);
+}
+
+static inline void tracehook_disable_single_step(struct task_struct *tsk)
+{
+	struct pt_regs *pt = task_pt_regs(tsk);
+	ia64_psr(pt)->ss = 0;
+	if (ia64_psr(pt)->tb == 0)
+		clear_tsk_thread_flag(tsk, TIF_SINGLESTEP);
+}
+
+static inline void tracehook_enable_block_step(struct task_struct *tsk)
+{
+	struct pt_regs *pt = task_pt_regs(tsk);
+	ia64_psr(pt)->tb = 1;
+	set_tsk_thread_flag(tsk, TIF_SINGLESTEP);
+}
+
+static inline void tracehook_disable_block_step(struct task_struct *tsk)
+{
+	struct pt_regs *pt = task_pt_regs(tsk);
+	ia64_psr(pt)->tb = 0;
+	if (ia64_psr(pt)->ss == 0)
+		clear_tsk_thread_flag(tsk, TIF_SINGLESTEP);
+}
+
+static inline void tracehook_enable_syscall_trace(struct task_struct *tsk)
+{
+	set_tsk_thread_flag(tsk, TIF_SYSCALL_TRACE);
+}
+
+static inline void tracehook_disable_syscall_trace(struct task_struct *tsk)
+{
+	clear_tsk_thread_flag(tsk, TIF_SYSCALL_TRACE);
+}
+
+static inline int tracehook_single_step_enabled(struct task_struct *tsk)
+{
+	struct pt_regs *pt = task_pt_regs(tsk);
+	return ia64_psr(pt)->ss;
+}
+
+static inline void tracehook_abort_syscall(struct pt_regs *regs)
+{
+	regs->r15 = -1L;
+}
+
+#endif

linux-2.6-utrace-tracehook-s390.patch:

--- NEW FILE linux-2.6-utrace-tracehook-s390.patch ---
[PATCH 1c] utrace: tracehook for s390

This patch does the initial tracehook conversion for s390.

Signed-off-by: Roland McGrath <roland at redhat.com>
Signed-off-by: David Wilder <dwilder at us.ibm.com>

---

 arch/s390/kernel/compat_signal.c |    5 ++-
 arch/s390/kernel/ptrace.c        |   62 +++++++++++++++++++++------------------
 arch/s390/kernel/signal.c        |    3 +
 arch/s390/kernel/traps.c         |    6 +--
 include/asm-s390/tracehook.h     |   46 ++++++++++++++++++++++++++++
 5 files changed, 90 insertions(+), 32 deletions(-)
 create include/asm-s390/tracehook.h

Index: b/arch/s390/kernel/traps.c
===================================================================
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -18,7 +18,7 @@
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/errno.h>
-#include <linux/ptrace.h>
+#include <linux/tracehook.h>
 #include <linux/timer.h>
 #include <linux/mm.h>
 #include <linux/smp.h>
@@ -360,7 +360,7 @@ void __kprobes do_single_step(struct pt_
 					SIGTRAP) == NOTIFY_STOP){
 		return;
 	}
-	if ((current->ptrace & PT_PTRACED) != 0)
+	if (tracehook_consider_fatal_signal(current, SIGTRAP))
 		force_sig(SIGTRAP, current);
 }
 
@@ -461,7 +461,7 @@ static void illegal_op(struct pt_regs * 
 		if (get_user(*((__u16 *) opcode), (__u16 __user *) location))
 			return;
 		if (*((__u16 *) opcode) == S390_BREAKPOINT_U16) {
-			if (current->ptrace & PT_PTRACED)
+			if (tracehook_consider_fatal_signal(current, SIGTRAP))
 				force_sig(SIGTRAP, current);
 			else
 				signal = SIGILL;
Index: b/arch/s390/kernel/compat_signal.c
===================================================================
--- a/arch/s390/kernel/compat_signal.c
+++ b/arch/s390/kernel/compat_signal.c
@@ -28,6 +28,7 @@
 #include <asm/ucontext.h>
 #include <asm/uaccess.h>
 #include <asm/lowcore.h>
+#include <linux/tracehook.h>
 #include "compat_linux.h"
 #include "compat_ptrace.h"
 
@@ -579,7 +580,9 @@ handle_signal32(unsigned long sig, struc
 			sigaddset(&current->blocked,sig);
 		recalc_sigpending();
 		spin_unlock_irq(&current->sighand->siglock);
+
+		tracehook_report_handle_signal(sig, ka, oldset, regs);
 	}
+
 	return ret;
 }
-
Index: b/arch/s390/kernel/ptrace.c
===================================================================
--- a/arch/s390/kernel/ptrace.c
+++ b/arch/s390/kernel/ptrace.c
@@ -29,6 +29,7 @@
 #include <linux/smp_lock.h>
 #include <linux/errno.h>
 #include <linux/ptrace.h>
+#include <linux/tracehook.h>
 #include <linux/user.h>
 #include <linux/security.h>
 #include <linux/audit.h>
@@ -84,18 +85,35 @@ FixPerRegisters(struct task_struct *task
 		per_info->control_regs.bits.storage_alt_space_ctl = 1;
 	else
 		per_info->control_regs.bits.storage_alt_space_ctl = 0;
+
+	if (task == current)
+		/*
+		 * These registers are loaded in __switch_to on
+		 * context switch.  We must load them now if
+		 * touching the current thread.
+		 */
+		__ctl_load(per_info->control_regs.words.cr, 9, 11);
 }
 
-static void set_single_step(struct task_struct *task)
+void
+tracehook_enable_single_step(struct task_struct *task)
 {
 	task->thread.per_info.single_step = 1;
 	FixPerRegisters(task);
 }
 
-static void clear_single_step(struct task_struct *task)
+void
+tracehook_disable_single_step(struct task_struct *task)
 {
 	task->thread.per_info.single_step = 0;
 	FixPerRegisters(task);
+	clear_tsk_thread_flag(task, TIF_SINGLE_STEP);
+}
+
+int
+tracehook_single_step_enabled(struct task_struct *task)
+{
+	return task->thread.per_info.single_step;
 }
 
 /*
@@ -107,7 +125,7 @@ void
 ptrace_disable(struct task_struct *child)
 {
 	/* make sure the single step bit is not set. */
-	clear_single_step(child);
+	tracehook_disable_single_step(child);
 }
 
 #ifndef CONFIG_64BIT
@@ -593,6 +611,7 @@ do_ptrace_emu31(struct task_struct *chil
 			copied += sizeof(unsigned int);
 		}
 		return 0;
+#if 0				/* XXX */
 	case PTRACE_GETEVENTMSG:
 		return put_user((__u32) child->ptrace_message,
 				(unsigned int __force __user *) data);
@@ -658,7 +677,7 @@ do_ptrace(struct task_struct *child, lon
 			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
 		child->exit_code = data;
 		/* make sure the single step bit is not set. */
-		clear_single_step(child);
+		tracehook_disable_single_step(child);
 		wake_up_process(child);
 		return 0;
 
@@ -672,7 +691,7 @@ do_ptrace(struct task_struct *child, lon
 			return 0;
 		child->exit_code = SIGKILL;
 		/* make sure the single step bit is not set. */
-		clear_single_step(child);
+		tracehook_disable_single_step(child);
 		wake_up_process(child);
 		return 0;
 
@@ -685,7 +704,7 @@ do_ptrace(struct task_struct *child, lon
 		if (data)
 			set_tsk_thread_flag(child, TIF_SINGLE_STEP);
 		else
-			set_single_step(child);
+			tracehook_enable_single_step(child);
 		/* give it a chance to run. */
 		wake_up_process(child);
 		return 0;
@@ -738,30 +757,17 @@ syscall_trace(struct pt_regs *regs, int 
 	if (unlikely(current->audit_context) && entryexit)
 		audit_syscall_exit(AUDITSC_RESULT(regs->gprs[2]), regs->gprs[2]);
 
-	if (!test_thread_flag(TIF_SYSCALL_TRACE))
-		goto out;
-	if (!(current->ptrace & PT_PTRACED))
-		goto out;
-	ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
-				 ? 0x80 : 0));
-
-	/*
-	 * If the debuffer has set an invalid system call number,
-	 * we prepare to skip the system call restart handling.
-	 */
-	if (!entryexit && regs->gprs[2] >= NR_syscalls)
-		regs->trap = -1;
+	if (test_thread_flag(TIF_SYSCALL_TRACE)) {
+		tracehook_report_syscall(regs, entryexit);
 
-	/*
-	 * this isn't the same as continuing with a signal, but it will do
-	 * for normal use.  strace only continues with a signal if the
-	 * stopping signal is not SIGTRAP.  -brl
-	 */
-	if (current->exit_code) {
-		send_sig(current->exit_code, current, 1);
-		current->exit_code = 0;
+		/*
+		 * If the debugger has set an invalid system call number,
+		 * we prepare to skip the system call restart handling.
+		 */
+		if (!entryexit && regs->gprs[2] >= NR_syscalls)
+			regs->trap = -1;
 	}
- out:
+
 	if (unlikely(current->audit_context) && !entryexit)
 		audit_syscall_entry(test_thread_flag(TIF_31BIT)?AUDIT_ARCH_S390:AUDIT_ARCH_S390X,
 				    regs->gprs[2], regs->orig_gpr2, regs->gprs[3],
Index: b/arch/s390/kernel/signal.c
===================================================================
--- a/arch/s390/kernel/signal.c
+++ b/arch/s390/kernel/signal.c
@@ -25,6 +25,7 @@
 #include <linux/tty.h>
 #include <linux/personality.h>
 #include <linux/binfmts.h>
+#include <linux/tracehook.h>
 #include <asm/ucontext.h>
 #include <asm/uaccess.h>
 #include <asm/lowcore.h>
@@ -395,6 +396,8 @@ handle_signal(unsigned long sig, struct 
 			sigaddset(&current->blocked,sig);
 		recalc_sigpending();
 		spin_unlock_irq(&current->sighand->siglock);
+
+		tracehook_report_handle_signal(sig, ka, oldset, regs);
 	}
 
 	return ret;
Index: b/include/asm-s390/tracehook.h
===================================================================
--- /dev/null
+++ b/include/asm-s390/tracehook.h
@@ -0,0 +1,46 @@
+/*
+ * Tracing hooks, s390/s390x support.
+ *
+ * Copyright (C) 2006, 2007 Red Hat, Inc.  All rights reserved.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License v.2.
+ *
+ * Red Hat Author: Roland McGrath.
+ */
+
+#ifndef _ASM_TRACEHOOK_H
+#define _ASM_TRACEHOOK_H	1
+
+#include <linux/sched.h>
+#include <asm/ptrace.h>
+
+/*
+ * See linux/tracehook.h for the descriptions of what these need to do.
+ */
+
+#define ARCH_HAS_SINGLE_STEP	(1)
+
+/* These three are defined in arch/s390/kernel/ptrace.c.  */
+void tracehook_enable_single_step(struct task_struct *tsk);
+void tracehook_disable_single_step(struct task_struct *tsk);
+int tracehook_single_step_enabled(struct task_struct *tsk);
+
+
+static inline void tracehook_enable_syscall_trace(struct task_struct *tsk)
+{
+	set_tsk_thread_flag(tsk, TIF_SYSCALL_TRACE);
+}
+
+static inline void tracehook_disable_syscall_trace(struct task_struct *tsk)
+{
+	clear_tsk_thread_flag(tsk, TIF_SYSCALL_TRACE);
+}
+
+static inline void tracehook_abort_syscall(struct pt_regs *regs)
+{
+	regs->gprs[2] = -1L;
+}
+
+#endif

linux-2.6-utrace-tracehook-sparc64.patch:

--- NEW FILE linux-2.6-utrace-tracehook-sparc64.patch ---
[PATCH 1b] utrace: tracehook for sparc64

This patch does the initial tracehook conversion for sparc64.

Signed-off-by: Roland McGrath <roland at redhat.com>
Signed-off-by: David S. Miller <davem at davemloft.net>

---

 arch/sparc64/kernel/entry.S     |    6 ------
 arch/sparc64/kernel/ptrace.c    |   29 +++++++++--------------------
 arch/sparc64/kernel/signal.c    |    2 ++
 arch/sparc64/kernel/signal32.c  |    2 ++
 include/asm-sparc64/tracehook.h |   40 ++++++++++++++++++++++++++++++++++++++++
 5 files changed, 53 insertions(+), 26 deletions(-)
 create include/asm-sparc64/tracehook.h

Index: b/arch/sparc64/kernel/ptrace.c
===================================================================
--- a/arch/sparc64/kernel/ptrace.c
+++ b/arch/sparc64/kernel/ptrace.c
@@ -22,6 +22,7 @@
 #include <linux/seccomp.h>
 #include <linux/audit.h>
 #include <linux/signal.h>
+#include <linux/tracehook.h>
 
 #include <asm/asi.h>
 #include <asm/pgtable.h>
@@ -33,6 +34,7 @@
 #include <asm/page.h>
 #include <asm/cpudata.h>
 
+#if 0				/* XXX */
 /* Returning from ptrace is a bit tricky because the syscall return
  * low level code assumes any value returned which is negative and
  * is a valid errno will mean setting the condition codes to indicate
@@ -82,6 +84,7 @@ pt_os_succ_return (struct pt_regs *regs,
 	else
 		pt_succ_return_linux (regs, val, addr);
 }
+#endif
 
 /* #define ALLOW_INIT_TRACING */
 /* #define DEBUG_PTRACE */
@@ -167,6 +170,7 @@ void flush_ptrace_access(struct vm_area_
 	}
 }
 
+#if 0				/* XXX */
 asmlinkage void do_ptrace(struct pt_regs *regs)
 {
 	int request = regs->u_regs[UREG_I0];
@@ -643,11 +647,13 @@ out_tsk:
 out:
 	unlock_kernel();
 }
+#endif
 
 asmlinkage void syscall_trace(struct pt_regs *regs, int syscall_exit_p)
 {
 	/* do the secure computing check first */
-	secure_computing(regs->u_regs[UREG_G1]);
+	if (!syscall_exit_p)
+		secure_computing(regs->u_regs[UREG_G1]);
 
 	if (unlikely(current->audit_context) && syscall_exit_p) {
 		unsigned long tstate = regs->tstate;
@@ -659,26 +665,9 @@ asmlinkage void syscall_trace(struct pt_
 		audit_syscall_exit(result, regs->u_regs[UREG_I0]);
 	}
 
-	if (!(current->ptrace & PT_PTRACED))
-		goto out;
-
-	if (!test_thread_flag(TIF_SYSCALL_TRACE))
-		goto out;
-
-	ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
-				 ? 0x80 : 0));
+	if (test_thread_flag(TIF_SYSCALL_TRACE))
+		tracehook_report_syscall(regs, syscall_exit_p);
 
-	/*
-	 * this isn't the same as continuing with a signal, but it will do
-	 * for normal use.  strace only continues with a signal if the
-	 * stopping signal is not SIGTRAP.  -brl
-	 */
-	if (current->exit_code) {
-		send_sig(current->exit_code, current, 1);
-		current->exit_code = 0;
-	}
-
-out:
 	if (unlikely(current->audit_context) && !syscall_exit_p)
 		audit_syscall_entry((test_thread_flag(TIF_32BIT) ?
 				     AUDIT_ARCH_SPARC :
Index: b/arch/sparc64/kernel/signal.c
===================================================================
--- a/arch/sparc64/kernel/signal.c
+++ b/arch/sparc64/kernel/signal.c
@@ -23,6 +23,7 @@
 #include <linux/smp_lock.h>
 #include <linux/binfmts.h>
 #include <linux/bitops.h>
+#include <linux/tracehook.h>
 
 #include <asm/uaccess.h>
 #include <asm/ptrace.h>
@@ -491,6 +492,7 @@ static inline void handle_signal(unsigne
 		sigaddset(&current->blocked,signr);
 	recalc_sigpending();
 	spin_unlock_irq(&current->sighand->siglock);
+	tracehook_report_handle_signal(signr, ka, oldset, regs);
 }
 
 static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
Index: b/arch/sparc64/kernel/signal32.c
===================================================================
--- a/arch/sparc64/kernel/signal32.c
+++ b/arch/sparc64/kernel/signal32.c
@@ -21,6 +21,7 @@
 #include <linux/binfmts.h>
 #include <linux/compat.h>
 #include <linux/bitops.h>
+#include <linux/tracehook.h>
 
 #include <asm/uaccess.h>
 #include <asm/ptrace.h>
@@ -1237,6 +1238,7 @@ static inline void handle_signal32(unsig
 		sigaddset(&current->blocked,signr);
 	recalc_sigpending();
 	spin_unlock_irq(&current->sighand->siglock);
+	tracehook_report_handle_signal(signr, ka, oldset, regs);
 }
 
 static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs,
Index: b/arch/sparc64/kernel/entry.S
===================================================================
--- a/arch/sparc64/kernel/entry.S
+++ b/arch/sparc64/kernel/entry.S
@@ -1434,7 +1434,6 @@ execve_merge:
 
 	.globl	sys_pipe, sys_sigpause, sys_nis_syscall
 	.globl	sys_rt_sigreturn
-	.globl	sys_ptrace
 	.globl	sys_sigaltstack
 	.align	32
 sys_pipe:	ba,pt		%xcc, sparc_pipe
@@ -1477,11 +1476,6 @@ sys32_rt_sigreturn:
 		 add		%o7, 1f-.-4, %o7
 		nop
 #endif
-sys_ptrace:	add		%sp, PTREGS_OFF, %o0
-		call		do_ptrace
-		 add		%o7, 1f-.-4, %o7
-		nop
-		.align		32
 1:		ldx		[%curptr + TI_FLAGS], %l5
 		andcc		%l5, (_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT), %g0
 		be,pt		%icc, rtrap
Index: b/include/asm-sparc64/tracehook.h
===================================================================
--- /dev/null
+++ b/include/asm-sparc64/tracehook.h
@@ -0,0 +1,40 @@
+/*
+ * Tracing hooks, SPARC64 CPU support
+ *
+ * Copyright (C) 2006, 2007 Red Hat, Inc.  All rights reserved.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License v.2.
+ *
+ * Red Hat Author: Roland McGrath.
+ */
+
+#ifndef _ASM_TRACEHOOK_H
+#define _ASM_TRACEHOOK_H	1
+
+
+#include <linux/sched.h>
+#include <asm/ptrace.h>
+
+/*
+ * See linux/tracehook.h for the descriptions of what these need to do.
+ */
+
+
+static inline void tracehook_enable_syscall_trace(struct task_struct *tsk)
+{
+	set_tsk_thread_flag(tsk, TIF_SYSCALL_TRACE);
+}
+
+static inline void tracehook_disable_syscall_trace(struct task_struct *tsk)
+{
+	clear_tsk_thread_flag(tsk, TIF_SYSCALL_TRACE);
+}
+
+static inline void tracehook_abort_syscall(struct pt_regs *regs)
+{
+	regs->u_regs[UREG_G1] = -1L;
+}
+
+#endif

linux-2.6-utrace-tracehook-um.patch:

--- NEW FILE linux-2.6-utrace-tracehook-um.patch ---
[PATCH 1d] utrace: tracehook for UML

From: Jeff Dike <jdike at addtoit.com>

This is the tracehook part of the UML utrace work, enough to get UML
building with the utrace prep patches applied.

Checks of task->ptrace & PT_DTRACE were replaced with
test_thread_flag(TIF_SINGLESTEP, or removed, in the case of execve.

Most of arch/um/kernel/ptrace.c is gone, to be reinstated in future
utrace work.

Similarly, calls to syscall_trace and ptrace notifications in the
signal delivery code are gone.

Signed-off-by: Roland McGrath <roland at redhat.com>
Signed-off-by: Jeff Dike <jdike at linux.intel.com>

---

 arch/um/kernel/exec.c           |    1 
 arch/um/kernel/process.c        |    6 
 arch/um/kernel/ptrace.c         |  327 ++++------------------------------------
 arch/um/kernel/signal.c         |    5 
 arch/um/kernel/skas/syscall.c   |    4 
 arch/um/sys-i386/signal.c       |    4 
 include/asm-um/ptrace-generic.h |    3 
 include/asm-um/ptrace-i386.h    |    2 
 include/asm-um/ptrace-x86_64.h  |    2 
 include/asm-um/thread_info.h    |    3 
 include/asm-um/tracehook.h      |   57 ++++++
 11 files changed, 106 insertions(+), 308 deletions(-)
 create include/asm-um/tracehook.h

Index: b/arch/um/kernel/ptrace.c
===================================================================
--- a/arch/um/kernel/ptrace.c
+++ b/arch/um/kernel/ptrace.c
@@ -3,261 +3,21 @@
  * Licensed under the GPL
  */
 
-#include "linux/sched.h"
-#include "linux/mm.h"
-#include "linux/errno.h"
-#include "linux/smp_lock.h"
-#include "linux/security.h"
-#include "linux/ptrace.h"
-#include "linux/audit.h"
-#ifdef CONFIG_PROC_MM
-#include "linux/proc_mm.h"
-#endif
-#include "asm/ptrace.h"
-#include "asm/uaccess.h"
-#include "kern_util.h"
-#include "skas_ptrace.h"
-#include "sysdep/ptrace.h"
-#include "os.h"
-
-static inline void set_singlestepping(struct task_struct *child, int on)
-{
-        if (on)
-                child->ptrace |= PT_DTRACE;
-        else
-                child->ptrace &= ~PT_DTRACE;
-        child->thread.singlestep_syscall = 0;
-
-#ifdef SUBARCH_SET_SINGLESTEPPING
-        SUBARCH_SET_SINGLESTEPPING(child, on);
-#endif
-}
+#include <linux/audit.h>
+#include <linux/elf.h>
+#include <linux/module.h>
+#include <linux/ptrace.h>
+#include <linux/tracehook.h>
 
 /*
  * Called by kernel/ptrace.c when detaching..
  */
 void ptrace_disable(struct task_struct *child)
 { 
-        set_singlestepping(child,0);
-}
-
-extern int peek_user(struct task_struct * child, long addr, long data);
-extern int poke_user(struct task_struct * child, long addr, long data);
-
-long arch_ptrace(struct task_struct *child, long request, long addr, long data)
-{
-	int i, ret;
-	unsigned long __user *p = (void __user *)(unsigned long)data;
-
-	switch (request) {
-		/* when I and D space are separate, these will need to be fixed. */
-	case PTRACE_PEEKTEXT: /* read word at location addr. */ 
-	case PTRACE_PEEKDATA: {
-		unsigned long tmp;
-		int copied;
-
-		ret = -EIO;
-		copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
-		if (copied != sizeof(tmp))
-			break;
-		ret = put_user(tmp, p);
-		break;
-	}
-
-	/* read the word at location addr in the USER area. */
-        case PTRACE_PEEKUSR:
-                ret = peek_user(child, addr, data);
-                break;
-
-	/* when I and D space are separate, this will have to be fixed. */
-	case PTRACE_POKETEXT: /* write the word at location addr. */
-	case PTRACE_POKEDATA:
-		ret = -EIO;
-		if (access_process_vm(child, addr, &data, sizeof(data), 
-				      1) != sizeof(data))
-			break;
-		ret = 0;
-		break;
-
-	case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
-                ret = poke_user(child, addr, data);
-                break;
-
-	case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
-	case PTRACE_CONT: { /* restart after signal. */
-		ret = -EIO;
-		if (!valid_signal(data))
-			break;
-
-                set_singlestepping(child, 0);
-		if (request == PTRACE_SYSCALL) {
-			set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-		}
-		else {
-			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-		}
-		child->exit_code = data;
-		wake_up_process(child);
-		ret = 0;
-		break;
-	}
-
-/*
- * make the child exit.  Best I can do is send it a sigkill. 
- * perhaps it should be put in the status that it wants to 
- * exit.
- */
-	case PTRACE_KILL: {
-		ret = 0;
-		if (child->exit_state == EXIT_ZOMBIE)	/* already dead */
-			break;
-
-                set_singlestepping(child, 0);
-		child->exit_code = SIGKILL;
-		wake_up_process(child);
-		break;
-	}
-
-	case PTRACE_SINGLESTEP: {  /* set the trap flag. */
-		ret = -EIO;
-		if (!valid_signal(data))
-			break;
-		clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
-                set_singlestepping(child, 1);
-		child->exit_code = data;
-		/* give it a chance to run. */
-		wake_up_process(child);
-		ret = 0;
-		break;
-	}
-
-	case PTRACE_DETACH:
-		/* detach a process that was attached. */
-		ret = ptrace_detach(child, data);
- 		break;
-
-#ifdef PTRACE_GETREGS
-	case PTRACE_GETREGS: { /* Get all gp regs from the child. */
-		if (!access_ok(VERIFY_WRITE, p, MAX_REG_OFFSET)) {
-			ret = -EIO;
-			break;
-		}
-		for ( i = 0; i < MAX_REG_OFFSET; i += sizeof(long) ) {
-			__put_user(getreg(child, i), p);
-			p++;
-		}
-		ret = 0;
-		break;
-	}
-#endif
-#ifdef PTRACE_SETREGS
-	case PTRACE_SETREGS: { /* Set all gp regs in the child. */
-		unsigned long tmp = 0;
-		if (!access_ok(VERIFY_READ, p, MAX_REG_OFFSET)) {
-			ret = -EIO;
-			break;
-		}
-		for ( i = 0; i < MAX_REG_OFFSET; i += sizeof(long) ) {
-			__get_user(tmp, p);
-			putreg(child, i, tmp);
-			p++;
-		}
-		ret = 0;
-		break;
-	}
-#endif
-#ifdef PTRACE_GETFPREGS
-	case PTRACE_GETFPREGS: /* Get the child FPU state. */
-		ret = get_fpregs(data, child);
-		break;
-#endif
-#ifdef PTRACE_SETFPREGS
-	case PTRACE_SETFPREGS: /* Set the child FPU state. */
-	        ret = set_fpregs(data, child);
-		break;
-#endif
-#ifdef PTRACE_GETFPXREGS
-	case PTRACE_GETFPXREGS: /* Get the child FPU state. */
-		ret = get_fpxregs(data, child);
-		break;
-#endif
-#ifdef PTRACE_SETFPXREGS
-	case PTRACE_SETFPXREGS: /* Set the child FPU state. */
-		ret = set_fpxregs(data, child);
-		break;
-#endif
-	case PTRACE_GET_THREAD_AREA:
-		ret = ptrace_get_thread_area(child, addr,
-					     (struct user_desc __user *) data);
-		break;
-
-	case PTRACE_SET_THREAD_AREA:
-		ret = ptrace_set_thread_area(child, addr,
-					     (struct user_desc __user *) data);
-		break;
-
-	case PTRACE_FAULTINFO: {
-		/* Take the info from thread->arch->faultinfo,
-		 * but transfer max. sizeof(struct ptrace_faultinfo).
-		 * On i386, ptrace_faultinfo is smaller!
-		 */
-		ret = copy_to_user(p, &child->thread.arch.faultinfo,
-				   sizeof(struct ptrace_faultinfo));
-		if(ret)
-			break;
-		break;
-	}
-
-#ifdef PTRACE_LDT
-	case PTRACE_LDT: {
-		struct ptrace_ldt ldt;
-
-		if(copy_from_user(&ldt, p, sizeof(ldt))){
-			ret = -EIO;
-			break;
-		}
-
-		/* This one is confusing, so just punt and return -EIO for 
-		 * now
-		 */
-		ret = -EIO;
-		break;
-	}
-#endif
-#ifdef CONFIG_PROC_MM
-	case PTRACE_SWITCH_MM: {
-		struct mm_struct *old = child->mm;
-		struct mm_struct *new = proc_mm_get_mm(data);
-
-		if(IS_ERR(new)){
-			ret = PTR_ERR(new);
-			break;
-		}
-
-		atomic_inc(&new->mm_users);
-		child->mm = new;
-		child->active_mm = new;
-		mmput(old);
-		ret = 0;
-		break;
-	}
-#endif
-#ifdef PTRACE_ARCH_PRCTL
-        case PTRACE_ARCH_PRCTL:
-                /* XXX Calls ptrace on the host - needs some SMP thinking */
-                ret = arch_prctl_skas(child, data, (void *) addr);
-                break;
-#endif
-	default:
-		ret = ptrace_request(child, request, addr, data);
-		break;
-	}
-
-	return ret;
 }
 
-void send_sigtrap(struct task_struct *tsk, union uml_pt_regs *regs,
-		  int error_code)
+static void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs,
+			 int error_code)
 {
 	struct siginfo info;
 
@@ -266,56 +26,39 @@ void send_sigtrap(struct task_struct *ts
 	info.si_code = TRAP_BRKPT;
 
 	/* User-mode eip? */
-	info.si_addr = UPT_IS_USER(regs) ? (void __user *) UPT_IP(regs) : NULL;
+	info.si_addr = UPT_IS_USER(&regs->regs) ?
+		(void __user *) UPT_IP(&regs->regs) : NULL;
 
 	/* Send us the fakey SIGTRAP */
 	force_sig_info(SIGTRAP, &info, tsk);
 }
 
-/* XXX Check PT_DTRACE vs TIF_SINGLESTEP for singlestepping check and
- * PT_PTRACED vs TIF_SYSCALL_TRACE for syscall tracing check
+/* notification of system call entry/exit
+ * - triggered by current->work.syscall_trace
  */
-void syscall_trace(union uml_pt_regs *regs, int entryexit)
+void do_syscall_trace(struct pt_regs *regs, int entryexit)
 {
-	int is_singlestep = (current->ptrace & PT_DTRACE) && entryexit;
-	int tracesysgood;
-
-	if (unlikely(current->audit_context)) {
-		if (!entryexit)
-			audit_syscall_entry(HOST_AUDIT_ARCH,
-					    UPT_SYSCALL_NR(regs),
-					    UPT_SYSCALL_ARG1(regs),
-					    UPT_SYSCALL_ARG2(regs),
-					    UPT_SYSCALL_ARG3(regs),
-					    UPT_SYSCALL_ARG4(regs));
-		else audit_syscall_exit(AUDITSC_RESULT(UPT_SYSCALL_RET(regs)),
-                                        UPT_SYSCALL_RET(regs));
-	}
-
-	/* Fake a debug trap */
-	if (is_singlestep)
-		send_sigtrap(current, regs, 0);
-
-	if (!test_thread_flag(TIF_SYSCALL_TRACE))
-		return;
-
-	if (!(current->ptrace & PT_PTRACED))
-		return;
-
-	/* the 0x80 provides a way for the tracing parent to distinguish
-	   between a syscall stop and SIGTRAP delivery */
-	tracesysgood = (current->ptrace & PT_TRACESYSGOOD);
-	ptrace_notify(SIGTRAP | (tracesysgood ? 0x80 : 0));
-
-	if (entryexit) /* force do_signal() --> is_syscall() */
-		set_thread_flag(TIF_SIGPENDING);
-
-	/* this isn't the same as continuing with a signal, but it will do
-	 * for normal use.  strace only continues with a signal if the
-	 * stopping signal is not SIGTRAP.  -brl
-	 */
-	if (current->exit_code) {
-		send_sig(current->exit_code, current, 1);
-		current->exit_code = 0;
-	}
+	/* do the secure computing check first */
+	if (!entryexit)
+		secure_computing(PT_REGS_SYSCALL_NR(regs));
+
+	if (unlikely(current->audit_context) && entryexit)
+		audit_syscall_exit(AUDITSC_RESULT(UPT_SYSCALL_RET(&regs->regs)),
+				   UPT_SYSCALL_RET(&regs->regs));
+
+	if (test_thread_flag(TIF_SYSCALL_TRACE))
+		tracehook_report_syscall(regs, entryexit);
+
+	if (test_thread_flag(TIF_SINGLESTEP) && entryexit) {
+		send_sigtrap(current, regs, 0);	/* XXX */
+		tracehook_report_syscall_step(regs);
+	}
+
+	if (unlikely(current->audit_context) && !entryexit)
+		audit_syscall_entry(HOST_AUDIT_ARCH,
+				    UPT_SYSCALL_NR(&regs->regs),
+				    UPT_SYSCALL_ARG1(&regs->regs),
+				    UPT_SYSCALL_ARG2(&regs->regs),
+				    UPT_SYSCALL_ARG3(&regs->regs),
+				    UPT_SYSCALL_ARG4(&regs->regs));
 }
Index: b/arch/um/kernel/skas/syscall.c
===================================================================
--- a/arch/um/kernel/skas/syscall.c
+++ b/arch/um/kernel/skas/syscall.c
@@ -19,8 +19,6 @@ void handle_syscall(union uml_pt_regs *r
 	long result;
 	int syscall;
 
-	syscall_trace(r, 0);
-
 	current->thread.nsyscalls++;
 	nsyscalls++;
 
@@ -38,6 +36,4 @@ void handle_syscall(union uml_pt_regs *r
 	else result = EXECUTE_SYSCALL(syscall, regs);
 
 	REGS_SET_SYSCALL_RETURN(r->skas.regs, result);
-
-	syscall_trace(r, 1);
 }
Index: b/arch/um/kernel/signal.c
===================================================================
--- a/arch/um/kernel/signal.c
+++ b/arch/um/kernel/signal.c
@@ -14,6 +14,7 @@
 #include "linux/tty.h"
 #include "linux/binfmts.h"
 #include "linux/ptrace.h"
+#include "linux/tracehook.h"
 #include "asm/signal.h"
 #include "asm/uaccess.h"
 #include "asm/unistd.h"
@@ -93,6 +94,8 @@ static int handle_signal(struct pt_regs 
 			sigaddset(&current->blocked, signr);
 		recalc_sigpending();
 		spin_unlock_irq(&current->sighand->siglock);
+
+		tracehook_report_handle_signal(signr, ka, oldset, regs);
 	}
 
 	return err;
@@ -148,7 +151,7 @@ static int kern_do_signal(struct pt_regs
 	 * on the host.  The tracing thread will check this flag and
 	 * PTRACE_SYSCALL if necessary.
 	 */
-	if(current->ptrace & PT_DTRACE)
+	if(test_thread_flag(TIF_SYSCALL_TRACE))
 		current->thread.singlestep_syscall =
 			is_syscall(PT_REGS_IP(&current->thread.regs));
 
Index: b/arch/um/kernel/exec.c
===================================================================
--- a/arch/um/kernel/exec.c
+++ b/arch/um/kernel/exec.c
@@ -51,7 +51,6 @@ static long execve1(char *file, char __u
         error = do_execve(file, argv, env, &current->thread.regs);
         if (error == 0){
 		task_lock(current);
-                current->ptrace &= ~PT_DTRACE;
 #ifdef SUBARCH_EXECVE1
 		SUBARCH_EXECVE1(&current->thread.regs.regs);
 #endif
Index: b/arch/um/kernel/process.c
===================================================================
--- a/arch/um/kernel/process.c
+++ b/arch/um/kernel/process.c
@@ -458,11 +458,11 @@ int singlestepping(void * t)
 {
 	struct task_struct *task = t ? t : current;
 
-	if ( ! (task->ptrace & PT_DTRACE) )
-		return(0);
+	if (!test_thread_flag(TIF_SINGLESTEP))
+		return 0;
 
 	if (task->thread.singlestep_syscall)
-		return(1);
+		return 1;
 
 	return 2;
 }
Index: b/arch/um/sys-i386/signal.c
===================================================================
--- a/arch/um/sys-i386/signal.c
+++ b/arch/um/sys-i386/signal.c
@@ -267,8 +267,6 @@ int setup_signal_stack_sc(unsigned long 
 	PT_REGS_EDX(regs) = (unsigned long) 0;
 	PT_REGS_ECX(regs) = (unsigned long) 0;
 
-	if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED))
-		ptrace_notify(SIGTRAP);
 	return 0;
 
 err:
@@ -324,8 +322,6 @@ int setup_signal_stack_si(unsigned long 
 	PT_REGS_EDX(regs) = (unsigned long) &frame->info;
 	PT_REGS_ECX(regs) = (unsigned long) &frame->uc;
 
-	if ((current->ptrace & PT_DTRACE) && (current->ptrace & PT_PTRACED))
-		ptrace_notify(SIGTRAP);
 	return 0;
 
 err:
Index: b/include/asm-um/ptrace-x86_64.h
===================================================================
--- a/include/asm-um/ptrace-x86_64.h
+++ b/include/asm-um/ptrace-x86_64.h
@@ -14,6 +14,8 @@
 #define __FRAME_OFFSETS /* Needed to get the R* macros */
 #include "asm/ptrace-generic.h"
 
+#define ARCH_HAS_SINGLE_STEP	(1)
+
 #define HOST_AUDIT_ARCH AUDIT_ARCH_X86_64
 
 /* Also defined in sysdep/ptrace.h, so may already be defined. */
Index: b/include/asm-um/ptrace-generic.h
===================================================================
--- a/include/asm-um/ptrace-generic.h
+++ b/include/asm-um/ptrace-generic.h
@@ -44,9 +44,6 @@ extern int set_fpxregs(unsigned long buf
 
 extern void show_regs(struct pt_regs *regs);
 
-extern void send_sigtrap(struct task_struct *tsk, union uml_pt_regs *regs,
-			 int error_code);
-
 extern int arch_copy_tls(struct task_struct *new);
 extern void clear_flushed_tls(struct task_struct *task);
 
Index: b/include/asm-um/ptrace-i386.h
===================================================================
--- a/include/asm-um/ptrace-i386.h
+++ b/include/asm-um/ptrace-i386.h
@@ -6,6 +6,8 @@
 #ifndef __UM_PTRACE_I386_H
 #define __UM_PTRACE_I386_H
 
+#define ARCH_HAS_SINGLE_STEP	(1)
+
 #define HOST_AUDIT_ARCH AUDIT_ARCH_I386
 
 #include "linux/compiler.h"
Index: b/include/asm-um/tracehook.h
===================================================================
--- /dev/null
+++ b/include/asm-um/tracehook.h
@@ -0,0 +1,57 @@
+/*
+ * Tracing hooks, i386 CPU support
+ *
+ * Copyright (C) 2006, 2007 Red Hat, Inc.  All rights reserved.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License v.2.
+ *
+ * Red Hat Author: Roland McGrath.
+ *
+ * Munged for UML - jdike@{addtoit,linux.intel}.com
+ */
+
+#ifndef _ASM_TRACEHOOK_H
+#define _ASM_TRACEHOOK_H	1
+
+#include <linux/sched.h>
+#include <asm/ptrace.h>
+#include <asm/thread_info.h>
+
+/*
+ * See linux/tracehook.h for the descriptions of what these need to do.
+ */
+
+static inline void tracehook_enable_single_step(struct task_struct *tsk)
+{
+	set_tsk_thread_flag(tsk, TIF_SINGLESTEP);
+}
+
+static inline void tracehook_disable_single_step(struct task_struct *tsk)
+{
+	clear_tsk_thread_flag(tsk, TIF_SINGLESTEP);
+}
+
+static inline int tracehook_single_step_enabled(struct task_struct *tsk)
+{
+	return test_tsk_thread_flag(tsk, TIF_SINGLESTEP);
+}
+
+static inline void tracehook_enable_syscall_trace(struct task_struct *tsk)
+{
+	set_tsk_thread_flag(tsk, TIF_SYSCALL_TRACE);
+}
+
+static inline void tracehook_disable_syscall_trace(struct task_struct *tsk)
+{
+	clear_tsk_thread_flag(tsk, TIF_SYSCALL_TRACE);
+}
+
+static inline void tracehook_abort_syscall(struct pt_regs *regs)
+{
+	PT_REGS_SYSCALL_NR(regs) = -1;
+}
+
+
+#endif
Index: b/include/asm-um/thread_info.h
===================================================================
--- a/include/asm-um/thread_info.h
+++ b/include/asm-um/thread_info.h
@@ -69,6 +69,8 @@ static inline struct thread_info *curren
 #define TIF_MEMDIE	 	5
 #define TIF_SYSCALL_AUDIT	6
 #define TIF_RESTORE_SIGMASK	7
+#define TIF_SINGLESTEP          8       /* restore singlestep on return to user
+                                         * mode */
 
 #define _TIF_SYSCALL_TRACE	(1 << TIF_SYSCALL_TRACE)
 #define _TIF_SIGPENDING		(1 << TIF_SIGPENDING)
@@ -77,5 +79,6 @@ static inline struct thread_info *curren
 #define _TIF_MEMDIE		(1 << TIF_MEMDIE)
 #define _TIF_SYSCALL_AUDIT	(1 << TIF_SYSCALL_AUDIT)
 #define _TIF_RESTORE_SIGMASK	(1 << TIF_RESTORE_SIGMASK)
+#define _TIF_SINGLESTEP         (1 << TIF_SINGLESTEP)
 
 #endif

linux-2.6-utrace-tracehook-xen.patch:

--- NEW FILE linux-2.6-utrace-tracehook-xen.patch ---
Index: patching/arch/i386/kernel/process-xen.c
===================================================================
--- patching.orig/arch/i386/kernel/process-xen.c
+++ patching/arch/i386/kernel/process-xen.c
@@ -745,9 +745,6 @@ asmlinkage int sys_execve(struct pt_regs
 			(char __user * __user *) regs.edx,
 			&regs);
 	if (error == 0) {
-		task_lock(current);
-		current->ptrace &= ~PT_DTRACE;
-		task_unlock(current);
 		/* Make sure we don't return using sysenter.. */
 		set_thread_flag(TIF_IRET);
 	}
Index: patching/arch/i386/kernel/entry-xen.S
===================================================================
--- patching.orig/arch/i386/kernel/entry-xen.S
+++ patching/arch/i386/kernel/entry-xen.S
@@ -359,7 +359,7 @@ sysenter_past_esp:
 	GET_THREAD_INFO(%ebp)
 
 	/* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */
-	testw $(_TIF_SYSCALL_EMU|_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
+	testw $(_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
 	jnz syscall_trace_entry
 	cmpl $(nr_syscalls), %eax
 	jae syscall_badsys
@@ -418,7 +418,7 @@ ENTRY(system_call)
 no_singlestep:
 					# system call tracing in operation / emulation
 	/* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */
-	testw $(_TIF_SYSCALL_EMU|_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
+	testw $(_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT),TI_flags(%ebp)
 	jnz syscall_trace_entry
 	cmpl $(nr_syscalls), %eax
 	jae syscall_badsys
@@ -606,9 +606,6 @@ syscall_trace_entry:
 	movl %esp, %eax
 	xorl %edx,%edx
 	call do_syscall_trace
-	cmpl $0, %eax
-	jne resume_userspace		# ret != 0 -> running under PTRACE_SYSEMU,
-					# so must skip actual syscall
 	movl PT_ORIG_EAX(%esp), %eax
 	cmpl $(nr_syscalls), %eax
 	jnae syscall_call
Index: patching/arch/x86_64/ia32/ia32entry-xen.S
===================================================================
--- patching.orig/arch/x86_64/ia32/ia32entry-xen.S
+++ patching/arch/x86_64/ia32/ia32entry-xen.S
@@ -348,7 +348,7 @@ ENTRY(ia32_syscall)
 	jnz ia32_tracesys
 ia32_do_syscall:	
 	cmpl $(IA32_NR_syscalls-1),%eax
-	ja  ia32_badsys
+	ja  int_ret_from_sys_call	/* ia32_tracesys has set RAX(%rsp) */
 	IA32_ARG_FIXUP
 	call *ia32_sys_call_table(,%rax,8) # xxx: rip relative
 ia32_sysret:
@@ -357,7 +357,7 @@ ia32_sysret:
 
 ia32_tracesys:			 
 	SAVE_REST
-	movq $-ENOSYS,RAX(%rsp)	/* really needed? */
+	movq $-ENOSYS,RAX(%rsp)	/* ptrace can change this for a bad syscall */
 	movq %rsp,%rdi        /* &pt_regs -> arg1 */
 	call syscall_trace_enter
 	LOAD_ARGS ARGOFFSET  /* reload args from stack in case ptrace changed it */
Index: patching/arch/x86_64/kernel/traps-xen.c
===================================================================
--- patching.orig/arch/x86_64/kernel/traps-xen.c
+++ patching/arch/x86_64/kernel/traps-xen.c
@@ -875,14 +875,6 @@ asmlinkage void __kprobes do_debug(struc
 		 */
                 if (!user_mode(regs))
                        goto clear_TF_reenable;
-		/*
-		 * Was the TF flag set by a debugger? If so, clear it now,
-		 * so that register information is correct.
-		 */
-		if (tsk->ptrace & PT_DTRACE) {
-			regs->eflags &= ~TF_MASK;
-			tsk->ptrace &= ~PT_DTRACE;
-		}
 	}
 
 	/* Ok, finally something we can handle */
Index: patching/arch/x86_64/kernel/process-xen.c
===================================================================
--- patching.orig/arch/x86_64/kernel/process-xen.c
+++ patching/arch/x86_64/kernel/process-xen.c
@@ -691,11 +691,6 @@ long sys_execve(char __user *name, char 
 	if (IS_ERR(filename)) 
 		return error;
 	error = do_execve(filename, argv, envp, &regs); 
-	if (error == 0) {
-		task_lock(current);
-		current->ptrace &= ~PT_DTRACE;
-		task_unlock(current);
-	}
 	putname(filename);
 	return error;
 }
Index: patching/arch/x86_64/kernel/entry-xen.S
===================================================================
--- patching.orig/arch/x86_64/kernel/entry-xen.S
+++ patching/arch/x86_64/kernel/entry-xen.S
@@ -339,19 +339,17 @@ badsys:
 	/* Do syscall tracing */
 tracesys:			 
 	SAVE_REST
-	movq $-ENOSYS,RAX(%rsp)
+	movq $-ENOSYS,RAX(%rsp) /* ptrace can change this for a bad syscall */
 	FIXUP_TOP_OF_STACK %rdi
 	movq %rsp,%rdi
 	call syscall_trace_enter
 	LOAD_ARGS ARGOFFSET  /* reload args from stack in case ptrace changed it */
 	RESTORE_REST
 	cmpq $__NR_syscall_max,%rax
-	movq $-ENOSYS,%rcx
-	cmova %rcx,%rax
-	ja  1f
+	ja   int_ret_from_sys_call	/* -ENOSYS already in RAX(%rsp) */
 	movq %r10,%rcx	/* fixup for C */
 	call *sys_call_table(,%rax,8)
-1:	movq %rax,RAX-ARGOFFSET(%rsp)
+	movq %rax,RAX-ARGOFFSET(%rsp)
 	/* Use IRET because user could have changed frame */
 		
 /* 

linux-2.6-utrace-tracehook.patch:

--- NEW FILE linux-2.6-utrace-tracehook.patch ---
[PATCH 1] utrace: tracehook (die, ptrace, die)

This patch rips out the old ptrace implementation.  It leaves behind stubs
so ptrace just fails with ENOSYS.  This is not really a useful kernel tree
to build, but it's a clean removal of the old code before adding the new.
Some dead code is left behind especially in architecture ptrace.c files;
this is left in to be reused under new interfaces by later patches,
reducing the total disruption to the code.

The "real_parent" member in task_struct is renamed "parent", and the old
"parent" member is gone.  That is to say, nothing interferes in the normal
parent/child links any more.  The fact that ptrace could cause these links
to change was the source of numerous race conditions and similar bugs
uncovered and worked around (often contortedly) in the core task management
code under the old ptrace implementation.

In each place in core code that referred to the old ptrace stuff, we now
have the tracehook interface.  These declarations are in <linux/tracehook.h>,
and use "tracehook_*" function names.  This centralizes all the hooks
that a thread tracing facility needs into core code, and the file
documents the calling environment (locking conditions, etc.) and meaning
of each hook.  The definitions here are all stubs doing nothing, so
there are no user debugging features in the kernel at all.  They provide
the placeholders for where a tracing interface can tie into the kernel.

The architecture support for single-step (and block-step) from the old
ptrace support is moved into tracehook_* function interfaces.  Nothing
yet calls these, but this provides the clean interface that user
debugging support can use for the architecture-specific single-step
control code.

Signed-off-by: Roland McGrath <roland at redhat.com>

---

 arch/alpha/kernel/asm-offsets.c     |    2 
 arch/alpha/kernel/entry.S           |    4 
 arch/arm/kernel/ptrace.c            |   17 -
 arch/arm26/kernel/ptrace.c          |   32 --
 arch/frv/kernel/ptrace.c            |   15 -
 arch/i386/kernel/entry.S            |    7 
 arch/i386/kernel/process.c          |    3 
 arch/i386/kernel/ptrace.c           |  104 +--------
 arch/i386/kernel/signal.c           |   37 +--
 arch/i386/kernel/vm86.c             |    7 
 arch/i386/math-emu/fpu_entry.c      |    6 
 arch/ia64/kernel/asm-offsets.c      |    2 
 arch/ia64/kernel/fsys.S             |   16 -
 arch/ia64/kernel/mca.c              |    2 
 arch/mips/kernel/ptrace.c           |   21 -
 arch/mips/kernel/sysirix.c          |    2 
 arch/powerpc/kernel/asm-offsets.c   |    2 
 arch/powerpc/kernel/process.c       |    5 
 arch/powerpc/kernel/ptrace-common.h |   16 -
 arch/powerpc/kernel/ptrace.c        |   74 +-----
 arch/powerpc/kernel/ptrace32.c      |   13 -
 arch/powerpc/kernel/signal_32.c     |    3 
 arch/powerpc/kernel/signal_64.c     |    3 
 arch/powerpc/kernel/sys_ppc32.c     |    5 
 arch/ppc/kernel/asm-offsets.c       |    2 
 arch/s390/kernel/compat_linux.c     |    3 
 arch/s390/kernel/process.c          |    3 
 arch/sparc64/kernel/binfmt_aout32.c |    2 
 arch/sparc64/kernel/process.c       |    3 
 arch/sparc64/kernel/sys_sparc32.c   |    3 
 arch/x86_64/ia32/ia32_aout.c        |    6 
 arch/x86_64/ia32/ia32_signal.c      |    7 
 arch/x86_64/ia32/ia32entry.S        |    4 
 arch/x86_64/ia32/ptrace32.c         |    2 
 arch/x86_64/ia32/sys_ia32.c         |    5 
 arch/x86_64/kernel/entry.S          |    8 
 arch/x86_64/kernel/process.c        |    5 
 arch/x86_64/kernel/ptrace.c         |   57 +---
 arch/x86_64/kernel/signal.c         |   28 +-
 arch/x86_64/kernel/traps.c          |    8 
 arch/x86_64/mm/fault.c              |    4 
 drivers/connector/cn_proc.c         |    4 
 fs/binfmt_aout.c                    |    6 
 fs/binfmt_elf.c                     |    6 
 fs/binfmt_elf_fdpic.c               |    7 
 fs/binfmt_flat.c                    |    3 
 fs/binfmt_som.c                     |    2 
 fs/exec.c                           |   11 
 fs/proc/array.c                     |   12 -
 fs/proc/base.c                      |   17 -
 include/asm-i386/signal.h           |    4 
 include/asm-i386/thread_info.h      |    7 
 include/asm-i386/tracehook.h        |   52 ++++
 include/asm-powerpc/tracehook.h     |   74 ++++++
 include/asm-x86_64/thread_info.h    |    3 
 include/asm-x86_64/tracehook.h      |   51 ++++
 include/linux/init_task.h           |    3 
 include/linux/ptrace.h              |   18 -
 include/linux/sched.h               |   16 -
 include/linux/tracehook.h           |  415 ++++++++++++++++++++++++++++++++++++
 kernel/exit.c                       |  243 +++++----------------
 kernel/fork.c                       |   66 +----
 kernel/ptrace.c                     |  299 +------------------------
 kernel/signal.c                     |  211 +++---------------
 kernel/sys.c                        |    2 
 kernel/timer.c                      |    6 
 kernel/tsacct.c                     |    2 
 mm/nommu.c                          |    4 
 security/selinux/hooks.c            |   54 ++--
 security/selinux/include/objsec.h   |    1 
 70 files changed, 934 insertions(+), 1213 deletions(-)
 create include/linux/tracehook.h
 create include/asm-i386/tracehook.h
 create include/asm-powerpc/tracehook.h
 create include/asm-x86_64/tracehook.h

Index: b/fs/binfmt_flat.c
===================================================================
--- a/fs/binfmt_flat.c
+++ b/fs/binfmt_flat.c
@@ -914,9 +914,6 @@ static int load_flat_binary(struct linux
 	
 	start_thread(regs, start_addr, current->mm->start_stack);
 
-	if (current->ptrace & PT_PTRACED)
-		send_sig(SIGTRAP, current, 0);
-
 	return 0;
 }
 
Index: b/fs/binfmt_som.c
===================================================================
--- a/fs/binfmt_som.c
+++ b/fs/binfmt_som.c
@@ -285,8 +285,6 @@ load_som_binary(struct linux_binprm * bp
 	map_hpux_gateway_page(current,current->mm);
 
 	start_thread_som(regs, som_entry, bprm->p);
-	if (current->ptrace & PT_PTRACED)
-		send_sig(SIGTRAP, current, 0);
 	return 0;
 
 	/* error cleanup */
Index: b/fs/proc/base.c
===================================================================
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -67,6 +67,7 @@
 #include <linux/mount.h>
 #include <linux/security.h>
 #include <linux/ptrace.h>
+#include <linux/tracehook.h>
 #include <linux/seccomp.h>
 #include <linux/cpuset.h>
 #include <linux/audit.h>
@@ -189,13 +190,6 @@ static int proc_root_link(struct inode *
 	return result;
 }
 
-#define MAY_PTRACE(task) \
-	(task == current || \
-	(task->parent == current && \
-	(task->ptrace & PT_PTRACED) && \
-	 (task->state == TASK_STOPPED || task->state == TASK_TRACED) && \
-	 security_ptrace(current,task) == 0))
-
 static int proc_pid_environ(struct task_struct *task, char * buffer)
 {
 	int res = 0;
@@ -523,7 +517,8 @@ static ssize_t mem_read(struct file * fi
 	if (!task)
 		goto out_no_task;
 
-	if (!MAY_PTRACE(task) || !ptrace_may_attach(task))
+	if (!tracehook_allow_access_process_vm(task)
+	    || !ptrace_may_attach(task))
 		goto out;
 
 	ret = -ENOMEM;
@@ -549,7 +544,8 @@ static ssize_t mem_read(struct file * fi
 
 		this_len = (count > PAGE_SIZE) ? PAGE_SIZE : count;
 		retval = access_process_vm(task, src, page, this_len, 0);
-		if (!retval || !MAY_PTRACE(task) || !ptrace_may_attach(task)) {
+		if (!retval || !tracehook_allow_access_process_vm(task)
+		    || !ptrace_may_attach(task)) {
 			if (!ret)
 				ret = -EIO;
 			break;
@@ -593,7 +589,8 @@ static ssize_t mem_write(struct file * f
 	if (!task)
 		goto out_no_task;
 
-	if (!MAY_PTRACE(task) || !ptrace_may_attach(task))
+	if (!tracehook_allow_access_process_vm(task)
+	    || !ptrace_may_attach(task))
 		goto out;
 
 	copied = -ENOMEM;
Index: b/fs/proc/array.c
===================================================================
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -73,6 +73,7 @@
[...3736 lines suppressed...]
-			current->ptrace &= ~PT_DTRACE;	\
+		if (test_and_clear_thread_flag(TIF_FORCED_TF)) \
 			(regs)->eflags &= ~TF_MASK;	\
-		}					\
 	} while (0)
 
 #endif /* __KERNEL__ */
Index: b/include/asm-powerpc/tracehook.h
===================================================================
--- /dev/null
+++ b/include/asm-powerpc/tracehook.h
@@ -0,0 +1,74 @@
+/*
+ * Tracing hooks, PowerPC CPU support
+ *
+ * Copyright (C) 2006, 2007 Red Hat, Inc.  All rights reserved.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License v.2.
+ *
+ * Red Hat Author: Roland McGrath.
+ */
+
+#ifndef _ASM_TRACEHOOK_H
+#define _ASM_TRACEHOOK_H	1
+
+#include <linux/sched.h>
+#include <asm/ptrace.h>
+
+/*
+ * See linux/tracehook.h for the descriptions of what these need to do.
+ */
+
+#define ARCH_HAS_SINGLE_STEP	(1)
+
+static inline void tracehook_enable_single_step(struct task_struct *task)
+{
+	struct pt_regs *regs = task->thread.regs;
+	if (regs != NULL) {
+#if defined(CONFIG_PPC32) && (defined(CONFIG_40x) || defined(CONFIG_BOOKE))
+		task->thread.dbcr0 = DBCR0_IDM | DBCR0_IC;
+		regs->msr |= MSR_DE;
+#else
+		regs->msr |= MSR_SE;
+#endif
+	}
+	set_tsk_thread_flag(task, TIF_SINGLESTEP);
+}
+
+static inline void tracehook_disable_single_step(struct task_struct *task)
+{
+	struct pt_regs *regs = task->thread.regs;
+	if (regs != NULL) {
+#if defined(CONFIG_PPC32) && (defined(CONFIG_40x) || defined(CONFIG_BOOKE))
+		task->thread.dbcr0 = 0;
+		regs->msr &= ~MSR_DE;
+#else
+		regs->msr &= ~MSR_SE;
+#endif
+	}
+	clear_tsk_thread_flag(task, TIF_SINGLESTEP);
+}
+
+static inline int tracehook_single_step_enabled(struct task_struct *tsk)
+{
+	return test_tsk_thread_flag(tsk, TIF_SINGLESTEP);
+}
+
+static inline void tracehook_enable_syscall_trace(struct task_struct *tsk)
+{
+	set_tsk_thread_flag(tsk, TIF_SYSCALL_TRACE);
+}
+
+static inline void tracehook_disable_syscall_trace(struct task_struct *tsk)
+{
+	clear_tsk_thread_flag(tsk, TIF_SYSCALL_TRACE);
+}
+
+static inline void tracehook_abort_syscall(struct pt_regs *regs)
+{
+	regs->orig_gpr3 = -1L;
+}
+
+
+#endif
Index: b/include/asm-x86_64/tracehook.h
===================================================================
--- /dev/null
+++ b/include/asm-x86_64/tracehook.h
@@ -0,0 +1,51 @@
+/*
+ * Tracing hooks, x86-64 CPU support
+ *
+ * Copyright (C) 2006, 2007 Red Hat, Inc.  All rights reserved.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License v.2.
+ *
+ * Red Hat Author: Roland McGrath.
+ */
+
+#ifndef _ASM_TRACEHOOK_H
+#define _ASM_TRACEHOOK_H	1
+
+#include <linux/sched.h>
+#include <asm/ptrace.h>
+
+/*
+ * See linux/tracehook.h for the descriptions of what these need to do.
+ */
+
+#define ARCH_HAS_SINGLE_STEP	(1)
+
+/* These two are defined in arch/x86_64/kernel/ptrace.c.  */
+void tracehook_enable_single_step(struct task_struct *tsk);
+void tracehook_disable_single_step(struct task_struct *tsk);
+
+static inline int tracehook_single_step_enabled(struct task_struct *tsk)
+{
+	return test_tsk_thread_flag(tsk, TIF_SINGLESTEP);
+}
+
+static inline void tracehook_enable_syscall_trace(struct task_struct *tsk)
+{
+	set_tsk_thread_flag(tsk, TIF_SYSCALL_TRACE);
+}
+
+static inline void tracehook_disable_syscall_trace(struct task_struct *tsk)
+{
+	clear_tsk_thread_flag(tsk, TIF_SYSCALL_TRACE);
+}
+
+#define tracehook_syscall_callno(regs)	(&(regs)->orig_rax)
+#define tracehook_syscall_retval(regs)	(&(regs)->rax)
+static inline void tracehook_abort_syscall(struct pt_regs *regs)
+{
+	regs->orig_rax = -1L;
+}
+
+#endif
Index: b/include/asm-x86_64/thread_info.h
===================================================================
--- a/include/asm-x86_64/thread_info.h
+++ b/include/asm-x86_64/thread_info.h
@@ -115,7 +115,7 @@ static inline struct thread_info *stack_
 #define TIF_SYSCALL_AUDIT	7	/* syscall auditing active */
 #define TIF_SECCOMP		8	/* secure computing */
 #define TIF_RESTORE_SIGMASK	9	/* restore signal mask in do_signal */
-/* 16 free */
+#define TIF_FORCED_TF		16	/* true if TF in eflags artificially */
 #define TIF_IA32		17	/* 32bit process */ 
 #define TIF_FORK		18	/* ret_from_fork */
 #define TIF_ABI_PENDING		19
@@ -133,6 +133,7 @@ static inline struct thread_info *stack_
 #define _TIF_SYSCALL_AUDIT	(1<<TIF_SYSCALL_AUDIT)
 #define _TIF_SECCOMP		(1<<TIF_SECCOMP)
 #define _TIF_RESTORE_SIGMASK	(1<<TIF_RESTORE_SIGMASK)
+#define _TIF_FORCED_TF		(1<<TIF_FORCED_TF)
 #define _TIF_IA32		(1<<TIF_IA32)
 #define _TIF_FORK		(1<<TIF_FORK)
 #define _TIF_ABI_PENDING	(1<<TIF_ABI_PENDING)
Index: b/drivers/connector/cn_proc.c
===================================================================
--- a/drivers/connector/cn_proc.c
+++ b/drivers/connector/cn_proc.c
@@ -63,8 +63,8 @@ void proc_fork_connector(struct task_str
 	ktime_get_ts(&ts); /* get high res monotonic timestamp */
 	put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns);
 	ev->what = PROC_EVENT_FORK;
-	ev->event_data.fork.parent_pid = task->real_parent->pid;
-	ev->event_data.fork.parent_tgid = task->real_parent->tgid;
+	ev->event_data.fork.parent_pid = task->parent->pid;
+	ev->event_data.fork.parent_tgid = task->parent->tgid;
 	ev->event_data.fork.child_pid = task->pid;
 	ev->event_data.fork.child_tgid = task->tgid;
 
Index: b/mm/nommu.c
===================================================================
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -20,7 +20,7 @@
 #include <linux/pagemap.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
-#include <linux/ptrace.h>
+#include <linux/tracehook.h>
 #include <linux/blkdev.h>
 #include <linux/backing-dev.h>
 #include <linux/mount.h>
@@ -674,7 +674,7 @@ static unsigned long determine_vm_flags(
 	 * it's being traced - otherwise breakpoints set in it may interfere
 	 * with another untraced process
 	 */
-	if ((flags & MAP_PRIVATE) && (current->ptrace & PT_PTRACED))
+	if ((flags & MAP_PRIVATE) && tracehook_expect_breakpoints(current))
 		vm_flags &= ~VM_MAYSHARE;
 
 	return vm_flags;

linux-2.6-vm-invalidate_mapping_pages-cond-resched.patch:

--- NEW FILE linux-2.6-vm-invalidate_mapping_pages-cond-resched.patch ---
>From davej  Wed May 16 14:45:37 2007
Return-path: <linux-kernel-owner+davej=40kernelslacker.org-S1761694AbXEPSn4 at vger.kernel.org>
X-Spam-Checker-Version: SpamAssassin 3.1.8 (2007-02-13) on
	gelk.kernelslacker.org
X-Spam-Level: 
X-Spam-Status: No, score=-2.1 required=5.0 tests=AWL,BAYES_00,FORGED_RCVD_HELO
	autolearn=ham version=3.1.8
Envelope-to: davej at kernelslacker.org
Delivery-date: Wed, 16 May 2007 19:44:05 +0100
Received: from testure.choralone.org [194.9.77.134]
	by gelk.kernelslacker.org with IMAP (fetchmail-6.3.6)
	for <davej at localhost> (single-drop); Wed, 16 May 2007 14:45:37 -0400 (EDT)
Received: from vger.kernel.org ([209.132.176.167])
	by testure.choralone.org with esmtp (Exim 4.63)
	(envelope-from <linux-kernel-owner+davej=40kernelslacker.org-S1761694AbXEPSn4 at vger.kernel.org>)
	id 1HoOTl-0007I7-Bi
	for davej at kernelslacker.org; Wed, 16 May 2007 19:44:05 +0100
Received: (majordomo at vger.kernel.org) by vger.kernel.org via listexpand
	id S1761694AbXEPSn4 (ORCPT <rfc822;davej at kernelslacker.org>);
	Wed, 16 May 2007 14:43:56 -0400
Received: (majordomo at vger.kernel.org) by vger.kernel.org id S1756223AbXEPSnr
	(ORCPT <rfc822;linux-kernel-outgoing>);
	Wed, 16 May 2007 14:43:47 -0400
Received: from smtp2.linux-foundation.org ([207.189.120.14]:55012 "EHLO
	smtp2.linux-foundation.org" rhost-flags-OK-OK-OK-OK)
	by vger.kernel.org with ESMTP id S1756132AbXEPSnq (ORCPT
	<rfc822;linux-kernel at vger.kernel.org>);
	Wed, 16 May 2007 14:43:46 -0400
Received: from shell0.pdx.osdl.net (fw.osdl.org [65.172.181.6])
	by smtp2.linux-foundation.org (8.13.5.20060308/8.13.5/Debian-3ubuntu1.1) with ESMTP id l4GIh8vo006373
	(version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO);
	Wed, 16 May 2007 11:43:45 -0700
Received: from akpm.corp.google.com (shell0.pdx.osdl.net [10.9.0.31])
	by shell0.pdx.osdl.net (8.13.1/8.11.6) with SMTP id l4GIf0QE007190;
	Wed, 16 May 2007 11:41:01 -0700
Date:	Wed, 16 May 2007 11:41:00 -0700
From:	Andrew Morton <akpm at linux-foundation.org>
To:	Bernd Schubert <bs at q-leap.de>
Cc:	"Michal Piotrowski" <michal.k.k.piotrowski at gmail.com>,
	"Bernd Schubert" <bschubert at q-leap.de>,
	linux-kernel at vger.kernel.org
Subject: Re: mkfs.ext2 triggered softlockup
Message-Id: <20070516114100.9cd642b8.akpm at linux-foundation.org>
In-Reply-To: <200705161901.09072.bs at q-leap.de>
References: <f2fcc1$otm$2 at sea.gmane.org>
	<6bffcb0e0705160949m7486705s1b2fc5bbe8a025df at mail.gmail.com>
	<200705161901.09072.bs at q-leap.de>
X-Mailer: Sylpheed version 2.2.7 (GTK+ 2.8.6; i686-pc-linux-gnu)
Mime-Version: 1.0
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit
X-MIMEDefang-Filter: osdl$Revision: 1.177 $
X-Scanned-By: MIMEDefang 2.53 on 207.189.120.14
Sender:	linux-kernel-owner at vger.kernel.org
Precedence: bulk
X-Mailing-List:	linux-kernel at vger.kernel.org
Status: RO
Content-Length: 6833
Lines: 169

On Wed, 16 May 2007 19:01:08 +0200
Bernd Schubert <bs at q-leap.de> wrote:

> On Wednesday 16 May 2007 18:49:57 Michal Piotrowski wrote:
> > Hi Bernd,
> >
> > On 16/05/07, Bernd Schubert <bschubert at q-leap.de> wrote:
> > > Maybe you still remember my report about an mkfs.ext2 triggered ram disk
> > > corruption?
> > >
> > > http://lkml.org/lkml/2007/5/4/272
> > >
> > > Well, in principle I'm now doing the same stuff, only this time with
> > > another initrd, which mounts the root-fs over nfs.
> > >
> > > [ 1596.928552] BUG: soft lockup detected on CPU#2!
> > > [ 1596.933109]
> > > [ 1596.933110] Call Trace:
> > > [ 1596.933111]  <IRQ>  [<ffffffff8025167b>] softlockup_tick+0xd8/0xef
> > > [ 1596.933129]  [<ffffffff802329f8>] run_local_timers+0x13/0x15
> > > [ 1596.933132]  [<ffffffff80232a44>] update_process_times+0x4a/0x77
> > > [ 1596.933138]  [<ffffffff8021434b>] smp_local_timer_interrupt+0x34/0x54
> > > [ 1596.933143]  [<ffffffff802143cc>] smp_apic_timer_interrupt+0x61/0x78
> > > [ 1596.933147]  [<ffffffff8020a29b>] apic_timer_interrupt+0x6b/0x70
> > > [ 1596.933151]  <EOI>  [<ffffffff80299dff>] free_buffer_head+0x24/0x3e
> > > [ 1596.933162]  [<ffffffff80272a63>] kmem_cache_free+0x1f4/0x201
> > > [ 1596.933170]  [<ffffffff80299dff>] free_buffer_head+0x24/0x3e
> > > [ 1596.933175]  [<ffffffff80299ea1>] try_to_free_buffers+0x88/0x9f
> > > [ 1596.933181]  [<ffffffff802565a9>] try_to_release_page+0x39/0x40
> > > [ 1596.933188]  [<ffffffff8025b76d>] invalidate_mapping_pages+0x9d/0x121
> > > [ 1596.933196]  [<ffffffff8025b800>] invalidate_inode_pages+0xf/0x11
> > > [ 1596.933200]  [<ffffffff80299053>] invalidate_bdev+0x3b/0x3f
> > > [ 1596.933203]  [<ffffffff8029c9ee>] kill_bdev+0x13/0x29
> > > [ 1596.933208]  [<ffffffff8029d6e8>] __blkdev_put+0x62/0x141
> > > [ 1596.933213]  [<ffffffff8029db62>] blkdev_put+0xb/0xd
> > > [ 1596.933218]  [<ffffffff8029dbf7>] blkdev_close+0x2e/0x33
> > > [ 1596.933222]  [<ffffffff8027a3c3>] __fput+0xc3/0x172
> > > [ 1596.933228]  [<ffffffff8027a486>] fput+0x14/0x16
> > > [ 1596.933233]  [<ffffffff80278c4f>] filp_close+0x61/0x6d
> > > [ 1596.933238]  [<ffffffff80278ce7>] sys_close+0x8c/0xce
> > > [ 1596.933244]  [<ffffffff8020965e>] system_call+0x7e/0x83
> > > [ 1596.933250]
> >
> > Can you tell me which kernel version you are using?
> 
> Sorry, forgot that. I think 2.6.20.6 or 2.6.20.7 (I always rename them to .3, 
> for some reasons thats easier than to change our tftp-rembo config). The 
> kernel is patches with lustre patches, hmm, one of them also adds a read-only 
> test to the block device layer.
> Probably I should test a vanilla kernel. Going to do that now...
> 

Don't bother - it'll happen here too.

I assume the disk is large, and that the machine has a lot of RAM?

Root cause: I suck.




From: Andrew Morton <akpm at linux-foundation.org>

invalidate_mapping_pages() can sometimes take a long time (millions of pages
to free).  Long enough for the softlockup detector to trigger.

We used to have a cond_resched() in there but I took it out because the
drop_caches code calls invalidate_mapping_pages() under inode_lock.

The patch adds a nasty flag and puts the cond_resched() back.

Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
---

 fs/drop_caches.c   |    2 +-
 include/linux/fs.h |    3 +++
 mm/truncate.c      |   38 +++++++++++++++++++++++---------------
 3 files changed, 27 insertions(+), 16 deletions(-)

diff -puN fs/drop_caches.c~invalidate_mapping_pages-add-cond_resched fs/drop_caches.c
--- a/fs/drop_caches.c~invalidate_mapping_pages-add-cond_resched
+++ a/fs/drop_caches.c
@@ -20,7 +20,7 @@ static void drop_pagecache_sb(struct sup
 	list_for_each_entry(inode, &sb->s_inodes, i_sb_list) {
 		if (inode->i_state & (I_FREEING|I_WILL_FREE))
 			continue;
-		invalidate_mapping_pages(inode->i_mapping, 0, -1);
+		__invalidate_mapping_pages(inode->i_mapping, 0, -1, true);
 	}
 	spin_unlock(&inode_lock);
 }
diff -puN include/linux/fs.h~invalidate_mapping_pages-add-cond_resched include/linux/fs.h
--- a/include/linux/fs.h~invalidate_mapping_pages-add-cond_resched
+++ a/include/linux/fs.h
@@ -1583,6 +1583,9 @@ extern int __invalidate_device(struct bl
 extern int invalidate_partition(struct gendisk *, int);
 #endif
 extern int invalidate_inodes(struct super_block *);
+unsigned long __invalidate_mapping_pages(struct address_space *mapping,
+					pgoff_t start, pgoff_t end,
+					bool be_atomic);
 unsigned long invalidate_mapping_pages(struct address_space *mapping,
 					pgoff_t start, pgoff_t end);
 
diff -puN mm/truncate.c~invalidate_mapping_pages-add-cond_resched mm/truncate.c
--- a/mm/truncate.c~invalidate_mapping_pages-add-cond_resched
+++ a/mm/truncate.c
@@ -253,21 +253,8 @@ void truncate_inode_pages(struct address
 }
 EXPORT_SYMBOL(truncate_inode_pages);
 
-/**
- * invalidate_mapping_pages - Invalidate all the unlocked pages of one inode
- * @mapping: the address_space which holds the pages to invalidate
- * @start: the offset 'from' which to invalidate
- * @end: the offset 'to' which to invalidate (inclusive)
- *
- * This function only removes the unlocked pages, if you want to
- * remove all the pages of one inode, you must call truncate_inode_pages.
- *
- * invalidate_mapping_pages() will not block on IO activity. It will not
- * invalidate pages which are dirty, locked, under writeback or mapped into
- * pagetables.
- */
-unsigned long invalidate_mapping_pages(struct address_space *mapping,
-				pgoff_t start, pgoff_t end)
+unsigned long __invalidate_mapping_pages(struct address_space *mapping,
+				pgoff_t start, pgoff_t end, bool be_atomic)
 {
 	struct pagevec pvec;
 	pgoff_t next = start;
@@ -308,9 +295,30 @@ unlock:
 				break;
 		}
 		pagevec_release(&pvec);
+		if (likely(!be_atomic))
+			cond_resched();
 	}
 	return ret;
 }
+
+/**
+ * invalidate_mapping_pages - Invalidate all the unlocked pages of one inode
+ * @mapping: the address_space which holds the pages to invalidate
+ * @start: the offset 'from' which to invalidate
+ * @end: the offset 'to' which to invalidate (inclusive)
+ *
+ * This function only removes the unlocked pages, if you want to
+ * remove all the pages of one inode, you must call truncate_inode_pages.
+ *
+ * invalidate_mapping_pages() will not block on IO activity. It will not
+ * invalidate pages which are dirty, locked, under writeback or mapped into
+ * pagetables.
+ */
+unsigned long invalidate_mapping_pages(struct address_space *mapping,
+				pgoff_t start, pgoff_t end)
+{
+	return __invalidate_mapping_pages(mapping, start, end, false);
+}
 EXPORT_SYMBOL(invalidate_mapping_pages);
 
 /*
_

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


linux-2.6-wakeups-hdaps.patch:

--- NEW FILE linux-2.6-wakeups-hdaps.patch ---
diff --git a/drivers/hwmon/hdaps.c b/drivers/hwmon/hdaps.c
index bf759ea..61524d2 100644
--- a/drivers/hwmon/hdaps.c
+++ b/drivers/hwmon/hdaps.c
@@ -449,6 +449,18 @@ static ssize_t hdaps_invert_store(struct device *dev,
 	return count;
 }
 
+static int hdaps_mousedev_open(struct input_dev *dev)
+{
+	add_timer(&hdaps_timer);
+	return 0;
+}
+
+static int hdaps_mousedev_close(struct input_dev *dev)
+{
+	del_timer_sync(&hdaps_timer);
+	return 0;
+}
+
 static DEVICE_ATTR(position, 0444, hdaps_position_show, NULL);
 static DEVICE_ATTR(variance, 0444, hdaps_variance_show, NULL);
 static DEVICE_ATTR(temp1, 0444, hdaps_temp1_show, NULL);
@@ -570,10 +582,17 @@ static int __init hdaps_init(void)
 	/* initial calibrate for the input device */
 	hdaps_calibrate();
 
+	/* start up our timer for the input device */
+	init_timer(&hdaps_timer);
+	hdaps_timer.function = hdaps_mousedev_poll;
+	hdaps_timer.expires = jiffies + HDAPS_POLL_PERIOD;
+
 	/* initialize the input class */
 	hdaps_idev->name = "hdaps";
 	hdaps_idev->cdev.dev = &pdev->dev;
 	hdaps_idev->evbit[0] = BIT(EV_ABS);
+	hdaps_idev->open = hdaps_mousedev_open;
+	hdaps_idev->close = hdaps_mousedev_close;
 	input_set_abs_params(hdaps_idev, ABS_X,
 			-256, 256, HDAPS_INPUT_FUZZ, HDAPS_INPUT_FLAT);
 	input_set_abs_params(hdaps_idev, ABS_Y,
@@ -583,12 +602,6 @@ static int __init hdaps_init(void)
 	if (ret)
 		goto out_idev;
 
-	/* start up our timer for the input device */
-	init_timer(&hdaps_timer);
-	hdaps_timer.function = hdaps_mousedev_poll;
-	hdaps_timer.expires = jiffies + HDAPS_POLL_PERIOD;
-	add_timer(&hdaps_timer);
-
 	printk(KERN_INFO "hdaps: driver successfully loaded.\n");
 	return 0;
 
@@ -609,7 +622,6 @@ out:
 
 static void __exit hdaps_exit(void)
 {
-	del_timer_sync(&hdaps_timer);
 	input_unregister_device(hdaps_idev);
 	sysfs_remove_group(&pdev->dev.kobj, &hdaps_attribute_group);
 	platform_device_unregister(pdev);

linux-2.6-wakeups.patch:

--- NEW FILE linux-2.6-wakeups.patch ---
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 73813c6..7d9bae5 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -433,7 +433,7 @@ static void cursor_timer_handler(unsigned long dev_addr)
 	struct fbcon_ops *ops = info->fbcon_par;
 
 	schedule_work(&info->queue);
-	mod_timer(&ops->cursor_timer, jiffies + HZ/5);
+	mod_timer(&ops->cursor_timer, jiffies + HZ);
 }
 
 static void fbcon_add_cursor_timer(struct fb_info *info)

linux-2.6-wireless.patch:

--- NEW FILE linux-2.6-wireless.patch ---
--- linux-2.6.21.noarch/CREDITS.orig	2007-06-14 13:40:38.000000000 -0400
+++ linux-2.6.21.noarch/CREDITS	2007-06-14 13:40:56.000000000 -0400
@@ -317,6 +317,12 @@ S: 2322 37th Ave SW
 S: Seattle, Washington 98126-2010
 S: USA
 
+N: Johannes Berg
+E: johannes at sipsolutions.net
+W: http://johannes.sipsolutions.net/
+P: 1024D/9AB78CA5 AD02 0176 4E29 C137 1DF6 08D2 FC44 CF86 9AB7 8CA5
+D: powerpc & 802.11 hacker
+
 N: Stephen R. van den Berg (AKA BuGless)
 E: berg at pool.informatik.rwth-aachen.de
 D: General kernel, gcc, and libc hacker
--- linux-2.6.21.noarch/lib/Makefile.orig	2007-06-14 13:54:21.000000000 -0400
+++ linux-2.6.21.noarch/lib/Makefile	2007-06-14 13:41:27.000000000 -0400
@@ -40,6 +40,7 @@ endif
 obj-$(CONFIG_BITREVERSE) += bitrev.o
 obj-$(CONFIG_CRC_CCITT)	+= crc-ccitt.o
 obj-$(CONFIG_CRC16)	+= crc16.o
+obj-$(CONFIG_CRC_ITU_T)	+= crc-itu-t.o
 obj-$(CONFIG_CRC32)	+= crc32.o
 obj-$(CONFIG_LIBCRC32C)	+= libcrc32c.o
 obj-$(CONFIG_GENERIC_ALLOCATOR) += genalloc.o
--- linux-2.6.21.noarch/lib/Kconfig.orig	2007-06-14 13:54:21.000000000 -0400
+++ linux-2.6.21.noarch/lib/Kconfig	2007-06-14 13:41:27.000000000 -0400
@@ -23,6 +23,14 @@ config CRC16
 	  the kernel tree does. Such modules that use library CRC16
 	  functions require M here.
 
+config CRC_ITU_T
+	tristate "CRC ITU-T V.41 functions"
+	help
+	  This option is provided for the case where no in-kernel-tree
+	  modules require CRC ITU-T V.41 functions, but a module built outside
+	  the kernel tree does. Such modules that use library CRC ITU-T V.41
+	  functions require M here.
+
 config CRC32
 	tristate "CRC32 functions"
 	default y
--- linux-2.6.21.noarch/lib/crc-itu-t.c.orig	2007-06-14 13:54:39.000000000 -0400
+++ linux-2.6.21.noarch/lib/crc-itu-t.c	2007-06-14 13:41:27.000000000 -0400
@@ -0,0 +1,69 @@
+/*
+ *      crc-itu-t.c
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2. See the file COPYING for more details.
+ */
+
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/crc-itu-t.h>
+
+/** CRC table for the CRC ITU-T V.41 0x0x1021 (x^16 + x^12 + x^15 + 1) */
+const u16 crc_itu_t_table[256] = {
+	0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
+	0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
+	0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
+	0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
+	0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
+	0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
+	0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
+	0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
+	0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
+	0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
+	0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
+	0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
+	0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
+	0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
+	0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
+	0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
+	0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
+	0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
+	0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
+	0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
+	0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
+	0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
+	0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
+	0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
+	0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
+	0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
+	0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
+	0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
+	0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
+	0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
+	0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
+	0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
+};
+
+EXPORT_SYMBOL(crc_itu_t_table);
+
+/**
+ * crc_itu_t - Compute the CRC-ITU-T for the data buffer
+ *
+ * @crc:     previous CRC value
+ * @buffer:  data pointer
+ * @len:     number of bytes in the buffer
+ *
+ * Returns the updated CRC value
+ */
+u16 crc_itu_t(u16 crc, const u8 *buffer, size_t len)
+{
+	while (len--)
+		crc = crc_itu_t_byte(crc, *buffer++);
+	return crc;
+}
+EXPORT_SYMBOL(crc_itu_t);
+
+MODULE_DESCRIPTION("CRC ITU-T V.41 calculations");
+MODULE_LICENSE("GPL");
+
--- linux-2.6.21.noarch/include/linux/nl80211.h.orig	2007-06-14 13:40:38.000000000 -0400
+++ linux-2.6.21.noarch/include/linux/nl80211.h	2007-06-14 13:40:56.000000000 -0400
@@ -0,0 +1,38 @@
+#ifndef __LINUX_NL80211_H
+#define __LINUX_NL80211_H
+/*
+ * 802.11 netlink interface public header
+ *
+ * Copyright 2006, 2007 Johannes Berg <johannes at sipsolutions.net>
+ */
+
+/**
+ * enum nl80211_iftype - (virtual) interface types
+ * @NL80211_IFTYPE_UNSPECIFIED: unspecified type, driver decides
+ * @NL80211_IFTYPE_ADHOC: independent BSS member
+ * @NL80211_IFTYPE_STATION: managed BSS member
+ * @NL80211_IFTYPE_AP: access point
+ * @NL80211_IFTYPE_AP_VLAN: VLAN interface for access points
+ * @NL80211_IFTYPE_WDS: wireless distribution interface
+ * @NL80211_IFTYPE_MONITOR: monitor interface receiving all frames
+ * @__NL80211_IFTYPE_AFTER_LAST: internal use
+ *
+ * These values are used with the NL80211_ATTR_IFTYPE
+ * to set the type of an interface.
+ *
+ */
+enum nl80211_iftype {
+	NL80211_IFTYPE_UNSPECIFIED,
+	NL80211_IFTYPE_ADHOC,
+	NL80211_IFTYPE_STATION,
+	NL80211_IFTYPE_AP,
+	NL80211_IFTYPE_AP_VLAN,
+	NL80211_IFTYPE_WDS,
+	NL80211_IFTYPE_MONITOR,
+
+	/* keep last */
+	__NL80211_IFTYPE_AFTER_LAST
+};
+#define NL80211_IFTYPE_MAX (__NL80211_IFTYPE_AFTER_LAST - 1)
+
+#endif /* __LINUX_NL80211_H */
--- linux-2.6.21.noarch/include/linux/ieee80211.h.orig	2007-06-14 13:40:38.000000000 -0400
+++ linux-2.6.21.noarch/include/linux/ieee80211.h	2007-06-14 13:40:56.000000000 -0400
@@ -0,0 +1,342 @@
+/*
+ * IEEE 802.11 defines
+ *
+ * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
+ * <jkmaline at cc.hut.fi>
+ * Copyright (c) 2002-2003, Jouni Malinen <jkmaline at cc.hut.fi>
+ * Copyright (c) 2005, Devicescape Software, Inc.
+ * Copyright (c) 2006, Michael Wu <flamingice at sourmilk.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef IEEE80211_H
+#define IEEE80211_H
+
+#include <linux/types.h>
+
+#define FCS_LEN 4
+
+#define IEEE80211_FCTL_VERS		0x0003
+#define IEEE80211_FCTL_FTYPE		0x000c
+#define IEEE80211_FCTL_STYPE		0x00f0
+#define IEEE80211_FCTL_TODS		0x0100
+#define IEEE80211_FCTL_FROMDS		0x0200
+#define IEEE80211_FCTL_MOREFRAGS	0x0400
+#define IEEE80211_FCTL_RETRY		0x0800
+#define IEEE80211_FCTL_PM		0x1000
+#define IEEE80211_FCTL_MOREDATA		0x2000
+#define IEEE80211_FCTL_PROTECTED	0x4000
+#define IEEE80211_FCTL_ORDER		0x8000
+
+#define IEEE80211_SCTL_FRAG		0x000F
+#define IEEE80211_SCTL_SEQ		0xFFF0
+
+#define IEEE80211_FTYPE_MGMT		0x0000
+#define IEEE80211_FTYPE_CTL		0x0004
+#define IEEE80211_FTYPE_DATA		0x0008
+
+/* management */
[...23415 lines suppressed...]
+	---help---
+	  Say Y if you have any 802.11 wireless LAN hardware.
+
+	  This option does not affect the kernel build, it only
+	  lets you choose drivers.
 
 config PCMCIA_RAYCS
 	tristate "Aviator/Raytheon 2.4MHz wireless support"
-	depends on NET_RADIO && PCMCIA
+	depends on PCMCIA && WLAN_80211
+	select WIRELESS_EXT
 	---help---
 	  Say Y here if you intend to attach an Aviator/Raytheon PCMCIA
 	  (PC-card) wireless Ethernet networking card to your computer.
@@ -141,12 +127,10 @@ config PCMCIA_RAYCS
 	  To compile this driver as a module, choose M here: the module will be
 	  called ray_cs.  If unsure, say N.
 
-comment "Wireless 802.11b ISA/PCI cards support"
-	depends on NET_RADIO && (ISA || PCI || PPC_PMAC || PCMCIA)
-
 config IPW2100
 	tristate "Intel PRO/Wireless 2100 Network Connection"
-	depends on NET_RADIO && PCI
+	depends on PCI && WLAN_80211
+	select WIRELESS_EXT
 	select FW_LOADER
 	select IEEE80211
 	---help---
@@ -200,7 +184,8 @@ config IPW2100_DEBUG
 
 config IPW2200
 	tristate "Intel PRO/Wireless 2200BG and 2915ABG Network Connection"
-	depends on NET_RADIO && PCI
+	depends on PCI && WLAN_80211
+	select WIRELESS_EXT
 	select FW_LOADER
 	select IEEE80211
 	---help---
@@ -282,7 +267,8 @@ config IPW2200_DEBUG
 
 config AIRO
 	tristate "Cisco/Aironet 34X/35X/4500/4800 ISA and PCI cards"
- 	depends on NET_RADIO && ISA_DMA_API && (PCI || BROKEN)
+	depends on ISA_DMA_API && WLAN_80211 && (PCI || BROKEN)
+	select WIRELESS_EXT
 	select CRYPTO
 	---help---
 	  This is the standard Linux driver to support Cisco/Aironet ISA and
@@ -299,7 +285,8 @@ config AIRO
 
 config HERMES
 	tristate "Hermes chipset 802.11b support (Orinoco/Prism2/Symbol)"
-	depends on NET_RADIO && (PPC_PMAC || PCI || PCMCIA)
+	depends on (PPC_PMAC || PCI || PCMCIA) && WLAN_80211
+	select WIRELESS_EXT
 	---help---
 	  A driver for 802.11b wireless cards based on the "Hermes" or
 	  Intersil HFA384x (Prism 2) MAC controller.  This includes the vast
@@ -373,7 +360,8 @@ config PCI_HERMES
 
 config ATMEL
       tristate "Atmel at76c50x chipset  802.11b support"
-      depends on NET_RADIO && (PCI || PCMCIA)
+      depends on (PCI || PCMCIA) && WLAN_80211
+      select WIRELESS_EXT
       select FW_LOADER
       select CRC32
        ---help---
@@ -394,13 +382,9 @@ config PCI_ATMEL
         Enable support for PCI and mini-PCI cards containing the
         Atmel at76c506 chip.
 
-# If Pcmcia is compiled in, offer Pcmcia cards...
-comment "Wireless 802.11b Pcmcia/Cardbus cards support"
-	depends on NET_RADIO && PCMCIA
-
 config PCMCIA_HERMES
 	tristate "Hermes PCMCIA card support"
-	depends on NET_RADIO && PCMCIA && HERMES
+	depends on PCMCIA && HERMES
 	---help---
 	  A driver for "Hermes" chipset based PCMCIA wireless adaptors, such
 	  as the Lucent WavelanIEEE/Orinoco cards and their OEM (Cabletron/
@@ -420,7 +404,7 @@ config PCMCIA_HERMES
 
 config PCMCIA_SPECTRUM
 	tristate "Symbol Spectrum24 Trilogy PCMCIA card support"
-	depends on NET_RADIO && PCMCIA && HERMES
+	depends on PCMCIA && HERMES
 	select FW_LOADER
 	---help---
 
@@ -434,7 +418,8 @@ config PCMCIA_SPECTRUM
 
 config AIRO_CS
 	tristate "Cisco/Aironet 34X/35X/4500/4800 PCMCIA cards"
-	depends on NET_RADIO && PCMCIA && (BROKEN || !M32R)
+	depends on PCMCIA && (BROKEN || !M32R) && WLAN_80211
+	select WIRELESS_EXT
 	select CRYPTO
 	select CRYPTO_AES
 	---help---
@@ -458,7 +443,8 @@ config AIRO_CS
 
 config PCMCIA_ATMEL
 	tristate "Atmel at76c502/at76c504 PCMCIA cards"
-	depends on NET_RADIO && ATMEL && PCMCIA
+	depends on ATMEL && PCMCIA
+	select WIRELESS_EXT
 	select FW_LOADER
 	select CRC32
 	---help---
@@ -467,17 +453,17 @@ config PCMCIA_ATMEL
 
 config PCMCIA_WL3501
       tristate "Planet WL3501 PCMCIA cards"
-      depends on NET_RADIO && EXPERIMENTAL && PCMCIA
+      depends on EXPERIMENTAL && PCMCIA && WLAN_80211
+      select WIRELESS_EXT
        ---help---
          A driver for WL3501 PCMCIA 802.11 wireless cards made by Planet.
 	 It has basic support for Linux wireless extensions and initial
 	 micro support for ethtool.
 
-comment "Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support"
-	depends on NET_RADIO && PCI
 config PRISM54
 	tristate 'Intersil Prism GT/Duette/Indigo PCI/Cardbus' 
-	depends on PCI && NET_RADIO && EXPERIMENTAL
+	depends on PCI && EXPERIMENTAL && WLAN_80211
+	select WIRELESS_EXT
 	select FW_LOADER
 	---help---
 	  Enable PCI and Cardbus support for the following chipset based cards:
@@ -523,7 +509,8 @@ config PRISM54
 
 config USB_ZD1201
 	tristate "USB ZD1201 based Wireless device support"
-	depends on USB && NET_RADIO
+	depends on USB && WLAN_80211
+	select WIRELESS_EXT
 	select FW_LOADER
 	---help---
 	  Say Y if you want to use wireless LAN adapters based on the ZyDAS
@@ -542,11 +529,4 @@ source "drivers/net/wireless/hostap/Kcon
 source "drivers/net/wireless/bcm43xx/Kconfig"
 source "drivers/net/wireless/zd1211rw/Kconfig"
 
-# yes, this works even when no drivers are selected
-config NET_WIRELESS
-	bool
-	depends on NET_RADIO && (ISA || PCI || PPC_PMAC || PCMCIA)
-	default y
-
 endmenu
-
--- linux-2.6.21.noarch/drivers/net/wireless/bcm43xx/Kconfig.orig	2007-06-14 13:40:38.000000000 -0400
+++ linux-2.6.21.noarch/drivers/net/wireless/bcm43xx/Kconfig	2007-06-14 13:40:57.000000000 -0400
@@ -1,6 +1,7 @@
 config BCM43XX
 	tristate "Broadcom BCM43xx wireless support"
-	depends on PCI && IEEE80211 && IEEE80211_SOFTMAC && NET_RADIO && EXPERIMENTAL
+	depends on PCI && IEEE80211 && IEEE80211_SOFTMAC && WLAN_80211 && EXPERIMENTAL
+	select WIRELESS_EXT
 	select FW_LOADER
 	select HW_RANDOM
 	---help---
--- linux-2.6.21.noarch/drivers/net/wireless/hostap/Kconfig.orig	2007-06-14 13:40:38.000000000 -0400
+++ linux-2.6.21.noarch/drivers/net/wireless/hostap/Kconfig	2007-06-14 13:40:57.000000000 -0400
@@ -1,6 +1,7 @@
 config HOSTAP
 	tristate "IEEE 802.11 for Host AP (Prism2/2.5/3 and WEP/TKIP/CCMP)"
-	depends on NET_RADIO
+	depends on WLAN_80211
+	select WIRELESS_EXT
 	select IEEE80211
 	select IEEE80211_CRYPT_WEP
 	---help---
--- linux-2.6.21.noarch/Documentation/feature-removal-schedule.txt.orig	2007-06-14 13:40:38.000000000 -0400
+++ linux-2.6.21.noarch/Documentation/feature-removal-schedule.txt	2007-06-14 13:40:57.000000000 -0400
@@ -294,18 +294,6 @@ Who:	Richard Purdie <rpurdie at rpsys.net>
 
 ---------------------------
 
-What:	Wireless extensions over netlink (CONFIG_NET_WIRELESS_RTNETLINK)
-When:	with the merge of wireless-dev, 2.6.22 or later
-Why:	The option/code is
-	 * not enabled on most kernels
-	 * not required by any userspace tools (except an experimental one,
-	   and even there only for some parts, others use ioctl)
-	 * pointless since wext is no longer evolving and the ioctl
-	   interface needs to be kept
-Who:	Johannes Berg <johannes at sipsolutions.net>
-
----------------------------
-
 What:	i8xx_tco watchdog driver
 When:	in 2.6.22
 Why:	the i8xx_tco watchdog driver has been replaced by the iTCO_wdt

linux-2.6-x86-64_pmtrace.patch:

--- NEW FILE linux-2.6-x86-64_pmtrace.patch ---
 arch/x86_64/kernel/vmlinux.lds.S  |    7 +++++++
 drivers/base/power/trace.c        |    4 +++-
 include/asm-i386/resume-trace.h   |   21 +++++++++++++++++++++
 include/asm-x86_64/resume-trace.h |   21 +++++++++++++++++++++
 include/linux/resume-trace.h      |   24 ++++++------------------
 kernel/power/Kconfig              |    2 +-
 6 files changed, 59 insertions(+), 20 deletions(-)
diff -ruNp 930-PM_TRACE.patch-old/arch/x86_64/kernel/vmlinux.lds.S 930-PM_TRACE.patch-new/arch/x86_64/kernel/vmlinux.lds.S
--- 930-PM_TRACE.patch-old/arch/x86_64/kernel/vmlinux.lds.S	2007-01-19 10:47:25.000000000 +1100
+++ 930-PM_TRACE.patch-new/arch/x86_64/kernel/vmlinux.lds.S	2007-01-15 00:00:08.000000000 +1100
@@ -54,6 +54,13 @@ SECTIONS
 
   BUG_TABLE
 
+  . = ALIGN(4);
+  .tracedata : AT(ADDR(.tracedata) - LOAD_OFFSET) {
+  	__tracedata_start = .;
+	*(.tracedata)
+  	__tracedata_end = .;
+  }
+
   . = ALIGN(PAGE_SIZE);        /* Align data segment to page size boundary */
 				/* Data */
   .data : AT(ADDR(.data) - LOAD_OFFSET) {
diff -ruNp 930-PM_TRACE.patch-old/drivers/base/power/trace.c 930-PM_TRACE.patch-new/drivers/base/power/trace.c
--- 930-PM_TRACE.patch-old/drivers/base/power/trace.c	2007-01-11 18:25:02.000000000 +1100
+++ 930-PM_TRACE.patch-new/drivers/base/power/trace.c	2007-01-15 00:00:08.000000000 +1100
@@ -142,6 +142,7 @@ void set_trace_device(struct device *dev
 {
 	dev_hash_value = hash_string(DEVSEED, dev->bus_id, DEVHASH);
 }
+EXPORT_SYMBOL(set_trace_device);
 
 /*
  * We could just take the "tracedata" index into the .tracedata
@@ -162,6 +163,7 @@ void generate_resume_trace(void *traceda
 	file_hash_value = hash_string(lineno, file, FILEHASH);
 	set_magic_time(user_hash_value, file_hash_value, dev_hash_value);
 }
+EXPORT_SYMBOL(generate_resume_trace);
 
 extern char __tracedata_start, __tracedata_end;
 static int show_file_hash(unsigned int value)
@@ -170,7 +172,7 @@ static int show_file_hash(unsigned int v
 	char *tracedata;
 
 	match = 0;
-	for (tracedata = &__tracedata_start ; tracedata < &__tracedata_end ; tracedata += 6) {
+	for (tracedata = &__tracedata_start ; tracedata < &__tracedata_end ; tracedata += 2 + sizeof(unsigned long)) {
 		unsigned short lineno = *(unsigned short *)tracedata;
 		const char *file = *(const char **)(tracedata + 2);
 		unsigned int hash = hash_string(lineno, file, FILEHASH);
diff -ruNp 930-PM_TRACE.patch-old/include/asm-i386/resume-trace.h 930-PM_TRACE.patch-new/include/asm-i386/resume-trace.h
--- 930-PM_TRACE.patch-old/include/asm-i386/resume-trace.h	1970-01-01 10:00:00.000000000 +1000
+++ 930-PM_TRACE.patch-new/include/asm-i386/resume-trace.h	2007-01-15 22:00:33.000000000 +1100
@@ -0,0 +1,21 @@
+#ifndef ARCH_RESUME_TRACE_H
+#define ARCH_RESUME_TRACE_H
+
+#ifdef CONFIG_PM_TRACE
+#define TRACE_RESUME(user) do {					\
+	if (pm_trace_enabled) {					\
+		void *tracedata;				\
+		asm volatile("movl $1f,%0\n"			\
+			".section .tracedata,\"a\"\n"		\
+			"1:\t.word %c1\n"			\
+			"\t.long %c2\n"				\
+			".previous"				\
+			:"=r" (tracedata)			\
+			: "i" (__LINE__), "i" (__FILE__));	\
+		generate_resume_trace(tracedata, user);		\
+	}							\
+} while (0)
+#else
+#define TRACE_RESUME(user) do { } while (0)
+#endif
+#endif
diff -ruNp 930-PM_TRACE.patch-old/include/asm-x86_64/resume-trace.h 930-PM_TRACE.patch-new/include/asm-x86_64/resume-trace.h
--- 930-PM_TRACE.patch-old/include/asm-x86_64/resume-trace.h	1970-01-01 10:00:00.000000000 +1000
+++ 930-PM_TRACE.patch-new/include/asm-x86_64/resume-trace.h	2007-01-15 22:00:16.000000000 +1100
@@ -0,0 +1,21 @@
+#ifndef ARCH_RESUME_TRACE_H
+#define ARCH_RESUME_TRACE_H
+
+#ifdef CONFIG_PM_TRACE
+#define TRACE_RESUME(user) do {					\
+	if (pm_trace_enabled) {					\
+		void *tracedata;				\
+		asm volatile("movq $1f,%0\n"			\
+			".section .tracedata,\"a\"\n"		\
+			"1:\t.word %c1\n"			\
+			"\t.quad %c2\n"				\
+			".previous"				\
+			:"=r" (tracedata)			\
+			: "i" (__LINE__), "i" (__FILE__));	\
+		generate_resume_trace(tracedata, user);		\
+	}							\
+} while (0)
+#else
+#define TRACE_RESUME(user) do { } while (0)
+#endif
+#endif
diff -ruNp 930-PM_TRACE.patch-old/include/linux/resume-trace.h 930-PM_TRACE.patch-new/include/linux/resume-trace.h
--- 930-PM_TRACE.patch-old/include/linux/resume-trace.h	2007-01-11 18:25:16.000000000 +1100
+++ 930-PM_TRACE.patch-new/include/linux/resume-trace.h	2007-01-17 21:06:14.000000000 +1100
@@ -1,6 +1,8 @@
 #ifndef RESUME_TRACE_H
 #define RESUME_TRACE_H
 
+#include <asm/resume-trace.h>
+
 #ifdef CONFIG_PM_TRACE
 
 extern int pm_trace_enabled;
@@ -9,26 +11,12 @@ struct device;
 extern void set_trace_device(struct device *);
 extern void generate_resume_trace(void *tracedata, unsigned int user);
 
-#define TRACE_DEVICE(dev) set_trace_device(dev)
-#define TRACE_RESUME(user) do {					\
-	if (pm_trace_enabled) {					\
-		void *tracedata;				\
-		asm volatile("movl $1f,%0\n"			\
-			".section .tracedata,\"a\"\n"		\
-			"1:\t.word %c1\n"			\
-			"\t.long %c2\n"				\
-			".previous"				\
-			:"=r" (tracedata)			\
-			: "i" (__LINE__), "i" (__FILE__));	\
-		generate_resume_trace(tracedata, user);		\
-	}							\
-} while (0)
-
+#define TRACE_DEVICE(dev) do { \
+	if (pm_trace_enabled) \
+		set_trace_device(dev); \
+	} while(0)
 #else
-
 #define TRACE_DEVICE(dev) do { } while (0)
-#define TRACE_RESUME(dev) do { } while (0)
-
 #endif
 
 #endif
diff -ruNp 930-PM_TRACE.patch-old/kernel/power/Kconfig 930-PM_TRACE.patch-new/kernel/power/Kconfig
--- 930-PM_TRACE.patch-old/kernel/power/Kconfig	2007-01-19 10:47:26.000000000 +1100
+++ 930-PM_TRACE.patch-new/kernel/power/Kconfig	2007-01-19 10:43:53.000000000 +1100
@@ -50,7 +50,7 @@ config DISABLE_CONSOLE_SUSPEND
 
 config PM_TRACE
 	bool "Suspend/resume event tracing"
-	depends on PM && PM_DEBUG && X86_32 && EXPERIMENTAL
+	depends on PM && PM_DEBUG && X86 && EXPERIMENTAL
 	default n
 	---help---
 	This enables some cheesy code to save the last PM event point in the

--- linux-2.6.21.noarch/kernel/power/main.c~	2007-05-29 16:30:53.000000000 -0400
+++ linux-2.6.21.noarch/kernel/power/main.c	2007-05-29 16:31:18.000000000 -0400
@@ -18,7 +18,9 @@
 #include <linux/pm.h>
 #include <linux/console.h>
 #include <linux/cpu.h>
+#ifdef CONFIG_PM_TRACE
 #include <linux/resume-trace.h>
+#endif
 #include <linux/freezer.h>
 #include <linux/vmstat.h>
 
--- linux-2.6.21.noarch/drivers/base/power/resume.c~	2007-05-29 17:01:33.000000000 -0400
+++ linux-2.6.21.noarch/drivers/base/power/resume.c	2007-05-29 17:02:46.000000000 -0400
@@ -9,7 +9,9 @@
  */
 
 #include <linux/device.h>
+#ifdef CONFIG_PM_TRACE
 #include <linux/resume-trace.h>
+#endif
 #include "../base.h"
 #include "power.h"
 
@@ -24,8 +26,10 @@ int resume_device(struct device * dev)
 {
 	int error = 0;
 
+#ifdef CONFIG_PM_TRACE
 	TRACE_DEVICE(dev);
 	TRACE_RESUME(0);
+#endif
 	down(&dev->sem);
 	if (dev->power.pm_parent
 			&& dev->power.pm_parent->power.power_state.event) {
@@ -43,7 +47,9 @@ int resume_device(struct device * dev)
 		error = dev->class->resume(dev);
 	}
 	up(&dev->sem);
+#ifdef CONFIG_PM_TRACE
 	TRACE_RESUME(error);
+#endif
 	return error;
 }
 
@@ -52,13 +58,17 @@ static int resume_device_early(struct de
 {
 	int error = 0;
 
+#ifdef CONFIG_PM_TRACE
 	TRACE_DEVICE(dev);
 	TRACE_RESUME(0);
+#endif
 	if (dev->bus && dev->bus->resume_early) {
 		dev_dbg(dev,"EARLY resume\n");
 		error = dev->bus->resume_early(dev);
 	}
+#ifdef CONFIG_PM_TRACE
 	TRACE_RESUME(error);
+#endif
 	return error;
 }
 

linux-2.6-x86-clean-up-oops-bug-reports.patch:

--- NEW FILE linux-2.6-x86-clean-up-oops-bug-reports.patch ---
i386: clean up oops/bug reports

From: Pavel Emelyanov <xemul at openvz.org>

Typically the oops first lines look like this:

BUG: unable to handle kernel NULL pointer dereference at virtual address 00000000
 printing eip:
c049dfbd
*pde = 00000000
Oops: 0002 [#1]
PREEMPT SMP
...

Such output is gained with some ugly if (!nl) printk("\n"); code and
besides being a waste of lines, this is also annoying to read. The
following output looks better (and it is how it looks on x86_64):

BUG: unable to handle kernel NULL pointer dereference at virtual address 00000000
printing eip: c049dfbd *pde = 00000000
Oops: 0002 [#1] PREEMPT SMP
...

Signed-off-by: Pavel Emelyanov <xemul at openvz.org>
Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
Signed-off-by: Andi Kleen <ak at suse.de>

---

 arch/i386/kernel/traps.c |   16 ++++------------
 arch/i386/mm/fault.c     |   13 +++++++------
 2 files changed, 11 insertions(+), 18 deletions(-)

Index: linux/arch/i386/kernel/traps.c
===================================================================
--- linux.orig/arch/i386/kernel/traps.c
+++ linux/arch/i386/kernel/traps.c
@@ -444,31 +444,23 @@ void die(const char * str, struct pt_reg
 		local_save_flags(flags);
 
 	if (++die.lock_owner_depth < 3) {
-		int nl = 0;
 		unsigned long esp;
 		unsigned short ss;
 
 		report_bug(regs->eip, regs);
 
-		printk(KERN_EMERG "%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
+		printk(KERN_EMERG "%s: %04lx [#%d] ", str, err & 0xffff, ++die_counter);
 #ifdef CONFIG_PREEMPT
-		printk(KERN_EMERG "PREEMPT ");
-		nl = 1;
+		printk("PREEMPT ");
 #endif
 #ifdef CONFIG_SMP
-		if (!nl)
-			printk(KERN_EMERG);
 		printk("SMP ");
-		nl = 1;
 #endif
 #ifdef CONFIG_DEBUG_PAGEALLOC
-		if (!nl)
-			printk(KERN_EMERG);
 		printk("DEBUG_PAGEALLOC");
-		nl = 1;
 #endif
-		if (nl)
-			printk("\n");
+		printk("\n");
+
 		if (notify_die(DIE_OOPS, str, regs, err,
 					current->thread.trap_no, SIGSEGV) !=
 				NOTIFY_STOP) {
Index: linux/arch/i386/mm/fault.c
===================================================================
--- linux.orig/arch/i386/mm/fault.c
+++ linux/arch/i386/mm/fault.c
@@ -544,23 +544,22 @@ no_context:
 			printk(KERN_ALERT "BUG: unable to handle kernel paging"
 					" request");
 		printk(" at virtual address %08lx\n",address);
-		printk(KERN_ALERT " printing eip:\n");
-		printk("%08lx\n", regs->eip);
+		printk(KERN_ALERT "printing eip: %08lx ", regs->eip);
 
 		page = read_cr3();
 		page = ((__typeof__(page) *) __va(page))[address >> PGDIR_SHIFT];
 #ifdef CONFIG_X86_PAE
-		printk(KERN_ALERT "*pdpt = %016Lx\n", page);
+		printk("*pdpt = %016Lx ", page);
 		if ((page >> PAGE_SHIFT) < max_low_pfn
 		    && page & _PAGE_PRESENT) {
 			page &= PAGE_MASK;
 			page = ((__typeof__(page) *) __va(page))[(address >> PMD_SHIFT)
 			                                         & (PTRS_PER_PMD - 1)];
-			printk(KERN_ALERT "*pde = %016Lx\n", page);
+			printk(KERN_ALERT "*pde = %016Lx ", page);
 			page &= ~_PAGE_NX;
 		}
 #else
-		printk(KERN_ALERT "*pde = %08lx\n", page);
+		printk("*pde = %08lx ", page);
 #endif
 
 		/*
@@ -574,8 +573,10 @@ no_context:
 			page &= PAGE_MASK;
 			page = ((__typeof__(page) *) __va(page))[(address >> PAGE_SHIFT)
 			                                         & (PTRS_PER_PTE - 1)];
-			printk(KERN_ALERT "*pte = %0*Lx\n", sizeof(page)*2, (u64)page);
+			printk("*pte = %0*Lx ", sizeof(page)*2, (u64)page);
 		}
+
+		printk("\n");
 	}
 
 	tsk->thread.cr2 = address;

linux-2.6-x86-debug-boot.patch:

--- NEW FILE linux-2.6-x86-debug-boot.patch ---
---
 arch/i386/boot/main.c |   12 ++++++++++++
 arch/i386/boot/pm.c   |    8 ++++++++
 2 files changed, 20 insertions(+)

--- linux-2.6.22.noarch.orig/arch/i386/boot/main.c
+++ linux-2.6.22.noarch/arch/i386/boot/main.c
@@ -105,6 +105,7 @@ static void set_bios_mode(void)
 void main(void)
 {
 	/* First, copy the boot header into the "zeropage" */
+	puts("Booting: ");
 	copy_boot_params();
 
 	/* End of heap check */
@@ -118,6 +119,7 @@ void main(void)
 	}
 
 	/* Make sure we have all the proper CPU support */
+	putchar('A');
 	if (validate_cpu()) {
 		puts("Unable to boot - please use a kernel appropriate "
 		     "for your CPU.\n");
@@ -125,37 +127,47 @@ void main(void)
 	}
 
 	/* Tell the BIOS what CPU mode we intend to run in. */
+	putchar('B');
 	set_bios_mode();
 
 	/* Detect memory layout */
+	putchar('C');
 	detect_memory();
 
 	/* Set keyboard repeat rate (why?) */
+	putchar('D');
 	keyboard_set_repeat();
 
 	/* Set the video mode */
+	putchar('E');
 	set_video();
 
 	/* Query MCA information */
+	putchar('F');
 	query_mca();
 
 	/* Voyager */
 #ifdef CONFIG_X86_VOYAGER
+	putchar('G');
 	query_voyager();
 #endif
 
+	putchar('H');
 	/* Query Intel SpeedStep (IST) information */
 	query_ist();
 
 	/* Query APM information */
 #if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)
+	putchar('I');
 	query_apm_bios();
 #endif
 
 	/* Query EDD information */
 #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
+	putchar('J');
 	query_edd();
 #endif
 	/* Do the last things and invoke protected mode */
+	putchar('K');
 	go_to_protected_mode();
 }
--- linux-2.6.22.noarch.orig/arch/i386/boot/pm.c
+++ linux-2.6.22.noarch/arch/i386/boot/pm.c
@@ -145,24 +145,30 @@ static void setup_idt(void)
 void go_to_protected_mode(void)
 {
 	/* Hook before leaving real mode, also disables interrupts */
+	putchar('L');
 	realmode_switch_hook();
 
 	/* Move the kernel/setup to their final resting places */
+	putchar('M');
 	move_kernel_around();
 
 	/* Enable the A20 gate */
+	putchar('N');
 	if (enable_a20()) {
 		puts("A20 gate not responding, unable to boot...\n");
 		die();
 	}
 
 	/* Reset coprocessor (IGNNE#) */
+	putchar('O');
 	reset_coprocessor();
 
 	/* Mask all interrupts in the PIC */
+	putchar('P');
 	mask_all_interrupts();
 
 	/* Actual transition to protected mode... */
+	puts("Q\n");
 	setup_idt();
 	setup_gdt();
 	protected_mode_jump(boot_params.hdr.code32_start,

linux-2.6-x86-dell-hpet.patch:

--- NEW FILE linux-2.6-x86-dell-hpet.patch ---
>From davej  Fri May  4 17:29:51 2007
Return-path: <linux-kernel-owner+davej=40kernelslacker.org-S1422720AbXEDV3K at vger.kernel.org>
X-Spam-Checker-Version: SpamAssassin 3.1.8 (2007-02-13) on
	gelk.kernelslacker.org
X-Spam-Level: 
X-Spam-Status: No, score=-2.6 required=5.0 tests=AWL,BAYES_00 autolearn=ham
	version=3.1.8
Envelope-to: davej at kernelslacker.org
Delivery-date: Fri, 04 May 2007 22:29:46 +0100
Received: from testure.choralone.org [194.9.77.134]
	by gelk.kernelslacker.org with IMAP (fetchmail-6.3.6)
	for <davej at localhost> (single-drop); Fri, 04 May 2007 17:29:51 -0400 (EDT)
Received: from vger.kernel.org ([209.132.176.167])
	by testure.choralone.org with esmtp (Exim 4.63)
	(envelope-from <linux-kernel-owner+davej=40kernelslacker.org-S1422720AbXEDV3K at vger.kernel.org>)
	id 1Hk5LV-0006nX-Q1
	for davej at kernelslacker.org; Fri, 04 May 2007 22:29:46 +0100
Received: (majordomo at vger.kernel.org) by vger.kernel.org via listexpand
	id S1422720AbXEDV3K (ORCPT <rfc822;davej at kernelslacker.org>);
	Fri, 4 May 2007 17:29:10 -0400
Received: (majordomo at vger.kernel.org) by vger.kernel.org id S1422743AbXEDV3J
	(ORCPT <rfc822;linux-kernel-outgoing>);
	Fri, 4 May 2007 17:29:09 -0400
Received: from e6.ny.us.ibm.com ([32.97.182.146]:47420 "EHLO e6.ny.us.ibm.com"
	rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP
	id S1422720AbXEDV3I (ORCPT <rfc822;linux-kernel at vger.kernel.org>);
	Fri, 4 May 2007 17:29:08 -0400
Received: from d01relay04.pok.ibm.com (d01relay04.pok.ibm.com [9.56.227.236])
	by e6.ny.us.ibm.com (8.13.8/8.13.8) with ESMTP id l44LU3oo010992
	for <linux-kernel at vger.kernel.org>; Fri, 4 May 2007 17:30:04 -0400
Received: from d01av02.pok.ibm.com (d01av02.pok.ibm.com [9.56.224.216])
	by d01relay04.pok.ibm.com (8.13.8/8.13.8/NCO v8.3) with ESMTP id l44LT7tT546216
	for <linux-kernel at vger.kernel.org>; Fri, 4 May 2007 17:29:07 -0400
Received: from d01av02.pok.ibm.com (loopback [127.0.0.1])
	by d01av02.pok.ibm.com (8.12.11.20060308/8.13.3) with ESMTP id l44LT62U004362
	for <linux-kernel at vger.kernel.org>; Fri, 4 May 2007 17:29:07 -0400
Received: from [9.67.61.99] (wecm-9-67-61-99.wecm.ibm.com [9.67.61.99])
	by d01av02.pok.ibm.com (8.12.11.20060308/8.12.11) with ESMTP id l44LT5Ia004316;
	Fri, 4 May 2007 17:29:05 -0400
Subject: [PATCH] Blacklist Dell Optiplex 320 from using the HPET
From:	john stultz <johnstul at us.ibm.com>
To:	Andrew Morton <akpm at linux-foundation.org>
Cc:	"Guilherme M. Schroeder" <guilherme at centralinf.com.br>,
	lkml <linux-kernel at vger.kernel.org>, Andi Kleen <ak at suse.de>,
	Thomas Gleixner <tglx at linutronix.de>
Content-Type: text/plain
Date:	Fri, 04 May 2007 14:29:04 -0700
Message-Id: <1178314144.6094.7.camel at localhost.localdomain>
Mime-Version: 1.0
X-Mailer: Evolution 2.10.1 
Content-Transfer-Encoding: 7bit
Sender:	linux-kernel-owner at vger.kernel.org
Precedence: bulk
X-Mailing-List:	linux-kernel at vger.kernel.org
Status: RO
Content-Length: 2257
Lines: 82

One of the 2.6.21 regressions was Guilherme's problem seeing his box
lock up when the system detected an unstable TSC and dropped back to
using the HPET.

In digging deeper, we found the HPET is not actually incrementing on
this system. And in fact, the reason why this issue just cropped up was
because of Thomas's clocksource watchdog code was comparing the TSC to
the HPET (which wasn't moving) and thought the TSC was broken.

Anyway, Guliherme checked for a BIOS update and did not find one, so
I've added a DMI blacklist against his system so the HPET is not used.

Many thanks to Guilherme for the slow and laborious testing that finally
narrowed down this issue.

thanks
-john

Signed-off-by: John Stultz <johnstul at us.ibm.com>

diff --git a/arch/i386/kernel/hpet.c b/arch/i386/kernel/hpet.c
index 17d7345..1ae27f3 100644
--- a/arch/i386/kernel/hpet.c
+++ b/arch/i386/kernel/hpet.c
@@ -5,6 +5,7 @@
 #include <linux/init.h>
 #include <linux/sysdev.h>
 #include <linux/pm.h>
+#include <linux/dmi.h>
 
 #include <asm/hpet.h>
 #include <asm/io.h>
@@ -48,6 +49,31 @@ static int __init hpet_setup(char* str)
 }
 __setup("hpet=", hpet_setup);
 
+
+/* DMI Blacklist for bad HPETs */
+static int __init dmi_mark_hpet_broken(struct dmi_system_id *d)
+{
+	printk(KERN_NOTICE "%s detected: HPET does not function.\n",
+		       d->ident);
+	boot_hpet_disable = 1;
+	return 0;
+}
+
+/* List of systems that have known HPETproblems */
+static struct dmi_system_id bad_hpet_dmi_table[] = {
+	{
+	 .callback = dmi_mark_hpet_broken,
+	 .ident = "Dell OptiPlex 320",
+	 .matches = {
+		     DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 320"),
+		     DMI_MATCH(DMI_BOARD_VENDOR, "Dell Inc."),
+		     DMI_MATCH(DMI_BOARD_NAME, "0UT237"),
+		     },
+	 },
+	 {}
+};
+
+
 static inline int is_hpet_capable(void)
 {
 	return (!boot_hpet_disable && hpet_address);
@@ -228,6 +254,8 @@ int __init hpet_enable(void)
 	uint64_t hpet_freq;
 	u64 tmp;
 
+	dmi_check_system(bad_hpet_dmi_table);
+
 	if (!is_hpet_capable())
 		return 0;
 




-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

>From davej  Fri May  4 17:46:16 2007
Return-path: <linux-kernel-owner+davej=40kernelslacker.org-S376145AbXEDVoY at vger.kernel.org>
X-Spam-Checker-Version: SpamAssassin 3.1.8 (2007-02-13) on
	gelk.kernelslacker.org
X-Spam-Level: 
X-Spam-Status: No, score=-2.1 required=5.0 tests=AWL,BAYES_00,FORGED_RCVD_HELO
	autolearn=ham version=3.1.8
Envelope-to: davej at kernelslacker.org
Delivery-date: Fri, 04 May 2007 22:44:45 +0100
Received: from testure.choralone.org [194.9.77.134]
	by gelk.kernelslacker.org with IMAP (fetchmail-6.3.6)
	for <davej at localhost> (single-drop); Fri, 04 May 2007 17:46:16 -0400 (EDT)
Received: from vger.kernel.org ([209.132.176.167])
	by testure.choralone.org with esmtp (Exim 4.63)
	(envelope-from <linux-kernel-owner+davej=40kernelslacker.org-S376145AbXEDVoY at vger.kernel.org>)
	id 1Hk5a1-0006qx-Dl
	for davej at kernelslacker.org; Fri, 04 May 2007 22:44:45 +0100
Received: (majordomo at vger.kernel.org) by vger.kernel.org via listexpand
	id S376145AbXEDVoY (ORCPT <rfc822;davej at kernelslacker.org>);
	Fri, 4 May 2007 17:44:24 -0400
Received: (majordomo at vger.kernel.org) by vger.kernel.org id S376156AbXEDVoY
	(ORCPT <rfc822;linux-kernel-outgoing>);
	Fri, 4 May 2007 17:44:24 -0400
Received: from smtp1.linux-foundation.org ([65.172.181.25]:47792 "EHLO
	smtp1.linux-foundation.org" rhost-flags-OK-OK-OK-OK)
	by vger.kernel.org with ESMTP id S376145AbXEDVoX (ORCPT
	<rfc822;linux-kernel at vger.kernel.org>);
	Fri, 4 May 2007 17:44:23 -0400
Received: from shell0.pdx.osdl.net (fw.osdl.org [65.172.181.6])
	by smtp1.linux-foundation.org (8.13.5.20060308/8.13.5/Debian-3ubuntu1.1) with ESMTP id l44Li8VE028869
	(version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO);
	Fri, 4 May 2007 14:44:09 -0700
Received: from akpm.corp.google.com (shell0.pdx.osdl.net [10.9.0.31])
	by shell0.pdx.osdl.net (8.13.1/8.11.6) with SMTP id l44Li8vG016020;
	Fri, 4 May 2007 14:44:08 -0700
Date:	Fri, 4 May 2007 14:44:08 -0700
From:	Andrew Morton <akpm at linux-foundation.org>
To:	john stultz <johnstul at us.ibm.com>
Cc:	"Guilherme M. Schroeder" <guilherme at centralinf.com.br>,
	lkml <linux-kernel at vger.kernel.org>, Andi Kleen <ak at suse.de>,
	Thomas Gleixner <tglx at linutronix.de>
Subject: Re: [PATCH] Blacklist Dell Optiplex 320 from using the HPET
Message-Id: <20070504144408.c041d8df.akpm at linux-foundation.org>
In-Reply-To: <1178314144.6094.7.camel at localhost.localdomain>
References: <1178314144.6094.7.camel at localhost.localdomain>
X-Mailer: Sylpheed version 2.2.7 (GTK+ 2.8.6; i686-pc-linux-gnu)
Mime-Version: 1.0
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit
X-MIMEDefang-Filter: osdl$Revision: 1.177 $
X-Scanned-By: MIMEDefang 2.53 on 65.172.181.25
Sender:	linux-kernel-owner at vger.kernel.org
Precedence: bulk
X-Mailing-List:	linux-kernel at vger.kernel.org
Status: RO
Content-Length: 3068
Lines: 104

On Fri, 04 May 2007 14:29:04 -0700
john stultz <johnstul at us.ibm.com> wrote:

> One of the 2.6.21 regressions was Guilherme's problem seeing his box
> lock up when the system detected an unstable TSC and dropped back to
> using the HPET.
> 
> In digging deeper, we found the HPET is not actually incrementing on
> this system. And in fact, the reason why this issue just cropped up was
> because of Thomas's clocksource watchdog code was comparing the TSC to
> the HPET (which wasn't moving) and thought the TSC was broken.
> 
> Anyway, Guliherme checked for a BIOS update and did not find one, so
> I've added a DMI blacklist against his system so the HPET is not used.
> 
> Many thanks to Guilherme for the slow and laborious testing that finally
> narrowed down this issue.
> 

OK, I tagged that for -stable too.

> 
> diff --git a/arch/i386/kernel/hpet.c b/arch/i386/kernel/hpet.c
> index 17d7345..1ae27f3 100644
> --- a/arch/i386/kernel/hpet.c
> +++ b/arch/i386/kernel/hpet.c
> @@ -5,6 +5,7 @@
>  #include <linux/init.h>
>  #include <linux/sysdev.h>
>  #include <linux/pm.h>
> +#include <linux/dmi.h>
>  
>  #include <asm/hpet.h>
>  #include <asm/io.h>
> @@ -48,6 +49,31 @@ static int __init hpet_setup(char* str)
>  }
>  __setup("hpet=", hpet_setup);
>  
> +
> +/* DMI Blacklist for bad HPETs */
> +static int __init dmi_mark_hpet_broken(struct dmi_system_id *d)
> +{
> +	printk(KERN_NOTICE "%s detected: HPET does not function.\n",
> +		       d->ident);
> +	boot_hpet_disable = 1;
> +	return 0;
> +}
> +
> +/* List of systems that have known HPETproblems */
> +static struct dmi_system_id bad_hpet_dmi_table[] = {
> +	{
> +	 .callback = dmi_mark_hpet_broken,
> +	 .ident = "Dell OptiPlex 320",
> +	 .matches = {
> +		     DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 320"),
> +		     DMI_MATCH(DMI_BOARD_VENDOR, "Dell Inc."),
> +		     DMI_MATCH(DMI_BOARD_NAME, "0UT237"),
> +		     },
> +	 },
> +	 {}
> +};
> +
> +
>  static inline int is_hpet_capable(void)
>  {
>  	return (!boot_hpet_disable && hpet_address);
> @@ -228,6 +254,8 @@ int __init hpet_enable(void)
>  	uint64_t hpet_freq;
>  	u64 tmp;
>  
> +	dmi_check_system(bad_hpet_dmi_table);
> +
>  	if (!is_hpet_capable())
>  		return 0;

The table can be __initdata, can't it?


--- a/arch/i386/kernel/hpet.c~blacklist-dell-optiplex-320-from-using-the-hpet-fix
+++ a/arch/i386/kernel/hpet.c
@@ -60,7 +60,7 @@ static int __init dmi_mark_hpet_broken(s
 }
 
 /* List of systems that have known HPETproblems */
-static struct dmi_system_id bad_hpet_dmi_table[] = {
+static struct dmi_system_id __initdata bad_hpet_dmi_table[] = {
 	{
 	 .callback = dmi_mark_hpet_broken,
 	 .ident = "Dell OptiPlex 320",
@@ -73,7 +73,6 @@ static struct dmi_system_id bad_hpet_dmi
 	 {}
 };
 
-
 static inline int is_hpet_capable(void)
 {
 	return (!boot_hpet_disable && hpet_address);
_

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


linux-2.6-x86-dont-delete-cpu_devs-data.patch:

--- NEW FILE linux-2.6-x86-dont-delete-cpu_devs-data.patch ---
http://bugzilla.kernel.org/show_bug.cgi?id=8033

Don't delete cpu_devs data to identify different x86 types in late_initcall

In arch/i386/cpu/common.c there is:
cpu_devs[X86_VENDOR_INTEL]
cpu_devs[X86_VENDOR_CYRIX]
cpu_devs[X86_VENDOR_AMD]
...
They are all filled with data early.
The data (struct) got set to NULL  for all, but Intel in different
late_initcall (exit_cpu_vendor) calls.
I don't see what sense this makes at all, maybe something that got
forgotten with the HOTPLUG_CPU extenstions?

Please check/review whether initdata, cpuinitdata is still ok and this
still works with HOTPLUG_CPU and without, it should...

Signed-off-by: Thomas Renninger <trenn at suse.de>

---
 arch/i386/kernel/cpu/amd.c       |   10 ----------
 arch/i386/kernel/cpu/centaur.c   |   10 ----------
 arch/i386/kernel/cpu/cyrix.c     |   19 -------------------
 arch/i386/kernel/cpu/nexgen.c    |   10 ----------
 arch/i386/kernel/cpu/rise.c      |    9 ---------
 arch/i386/kernel/cpu/transmeta.c |   10 ----------
 arch/i386/kernel/cpu/umc.c       |   10 ----------
 7 files changed, 78 deletions(-)

Index: linux-2.6.21/arch/i386/kernel/cpu/amd.c
===================================================================
--- linux-2.6.21.orig/arch/i386/kernel/cpu/amd.c
+++ linux-2.6.21/arch/i386/kernel/cpu/amd.c
@@ -314,13 +314,3 @@ int __init amd_init_cpu(void)
 	cpu_devs[X86_VENDOR_AMD] = &amd_cpu_dev;
 	return 0;
 }
-
-//early_arch_initcall(amd_init_cpu);
-
-static int __init amd_exit_cpu(void)
-{
-	cpu_devs[X86_VENDOR_AMD] = NULL;
-	return 0;
-}
-
-late_initcall(amd_exit_cpu);
Index: linux-2.6.21/arch/i386/kernel/cpu/cyrix.c
===================================================================
--- linux-2.6.21.orig/arch/i386/kernel/cpu/cyrix.c
+++ linux-2.6.21/arch/i386/kernel/cpu/cyrix.c
@@ -448,16 +448,6 @@ int __init cyrix_init_cpu(void)
 	return 0;
 }
 
-//early_arch_initcall(cyrix_init_cpu);
-
-static int __init cyrix_exit_cpu(void)
-{
-	cpu_devs[X86_VENDOR_CYRIX] = NULL;
-	return 0;
-}
-
-late_initcall(cyrix_exit_cpu);
-
 static struct cpu_dev nsc_cpu_dev __cpuinitdata = {
 	.c_vendor	= "NSC",
 	.c_ident 	= { "Geode by NSC" },
@@ -470,12 +460,3 @@ int __init nsc_init_cpu(void)
 	return 0;
 }
 
-//early_arch_initcall(nsc_init_cpu);
-
-static int __init nsc_exit_cpu(void)
-{
-	cpu_devs[X86_VENDOR_NSC] = NULL;
-	return 0;
-}
-
-late_initcall(nsc_exit_cpu);
Index: linux-2.6.21/arch/i386/kernel/cpu/rise.c
===================================================================
--- linux-2.6.21.orig/arch/i386/kernel/cpu/rise.c
+++ linux-2.6.21/arch/i386/kernel/cpu/rise.c
@@ -50,12 +50,3 @@ int __init rise_init_cpu(void)
 	return 0;
 }
 
-//early_arch_initcall(rise_init_cpu);
-
-static int __init rise_exit_cpu(void)
-{
-	cpu_devs[X86_VENDOR_RISE] = NULL;
-	return 0;
-}
-
-late_initcall(rise_exit_cpu);
Index: linux-2.6.21/arch/i386/kernel/cpu/umc.c
===================================================================
--- linux-2.6.21.orig/arch/i386/kernel/cpu/umc.c
+++ linux-2.6.21/arch/i386/kernel/cpu/umc.c
@@ -24,13 +24,3 @@ int __init umc_init_cpu(void)
 	cpu_devs[X86_VENDOR_UMC] = &umc_cpu_dev;
 	return 0;
 }
-
-//early_arch_initcall(umc_init_cpu);
-
-static int __init umc_exit_cpu(void)
-{
-	cpu_devs[X86_VENDOR_UMC] = NULL;
-	return 0;
-}
-
-late_initcall(umc_exit_cpu);
Index: linux-2.6.21/arch/i386/kernel/cpu/centaur.c
===================================================================
--- linux-2.6.21.orig/arch/i386/kernel/cpu/centaur.c
+++ linux-2.6.21/arch/i386/kernel/cpu/centaur.c
@@ -469,13 +469,3 @@ int __init centaur_init_cpu(void)
 	cpu_devs[X86_VENDOR_CENTAUR] = &centaur_cpu_dev;
 	return 0;
 }
-
-//early_arch_initcall(centaur_init_cpu);
-
-static int __init centaur_exit_cpu(void)
-{
-	cpu_devs[X86_VENDOR_CENTAUR] = NULL;
-	return 0;
-}
-
-late_initcall(centaur_exit_cpu);
Index: linux-2.6.21/arch/i386/kernel/cpu/transmeta.c
===================================================================
--- linux-2.6.21.orig/arch/i386/kernel/cpu/transmeta.c
+++ linux-2.6.21/arch/i386/kernel/cpu/transmeta.c
@@ -112,13 +112,3 @@ int __init transmeta_init_cpu(void)
 	cpu_devs[X86_VENDOR_TRANSMETA] = &transmeta_cpu_dev;
 	return 0;
 }
-
-//early_arch_initcall(transmeta_init_cpu);
-
-static int __init transmeta_exit_cpu(void)
-{
-	cpu_devs[X86_VENDOR_TRANSMETA] = NULL;
-	return 0;
-}
-
-late_initcall(transmeta_exit_cpu);
Index: linux-2.6.21/arch/i386/kernel/cpu/nexgen.c
===================================================================
--- linux-2.6.21.orig/arch/i386/kernel/cpu/nexgen.c
+++ linux-2.6.21/arch/i386/kernel/cpu/nexgen.c
@@ -58,13 +58,3 @@ int __init nexgen_init_cpu(void)
 	cpu_devs[X86_VENDOR_NEXGEN] = &nexgen_cpu_dev;
 	return 0;
 }
-
-//early_arch_initcall(nexgen_init_cpu);
-
-static int __init nexgen_exit_cpu(void)
-{
-	cpu_devs[X86_VENDOR_NEXGEN] = NULL;
-	return 0;
-}
-
-late_initcall(nexgen_exit_cpu);

linux-2.6-x86-fsc-interrupt-controller-quirk.patch:

--- NEW FILE linux-2.6-x86-fsc-interrupt-controller-quirk.patch ---
>From davej  Thu May  3 19:18:53 2007
Return-path: <linux-kernel-owner+davej=40kernelslacker.org-S1767474AbXECXST at vger.kernel.org>
X-Spam-Checker-Version: SpamAssassin 3.1.8 (2007-02-13) on
	gelk.kernelslacker.org
X-Spam-Level: 
X-Spam-Status: No, score=-2.6 required=5.0 tests=AWL,BAYES_00 autolearn=ham
	version=3.1.8
Envelope-to: davej at kernelslacker.org
Delivery-date: Fri, 04 May 2007 00:18:51 +0100
Received: from testure.choralone.org [194.9.77.134]
	by gelk.kernelslacker.org with IMAP (fetchmail-6.3.6)
	for <davej at localhost> (single-drop); Thu, 03 May 2007 19:18:53 -0400 (EDT)
Received: from vger.kernel.org ([209.132.176.167])
	by testure.choralone.org with esmtp (Exim 4.63)
	(envelope-from <linux-kernel-owner+davej=40kernelslacker.org-S1767474AbXECXST at vger.kernel.org>)
	id 1HjkZW-0006Cr-RV
	for davej at kernelslacker.org; Fri, 04 May 2007 00:18:51 +0100
Received: (majordomo at vger.kernel.org) by vger.kernel.org via listexpand
	id S1767474AbXECXST (ORCPT <rfc822;davej at kernelslacker.org>);
	Thu, 3 May 2007 19:18:19 -0400
Received: (majordomo at vger.kernel.org) by vger.kernel.org id S1767468AbXECXST
	(ORCPT <rfc822;linux-kernel-outgoing>);
	Thu, 3 May 2007 19:18:19 -0400
Received: from jurassic.park.msu.ru ([195.208.223.243]:2073 "EHLO
	jurassic.park.msu.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org
	with ESMTP id S1767466AbXECXSS (ORCPT
	<rfc822;linux-kernel at vger.kernel.org>);
	Thu, 3 May 2007 19:18:18 -0400
Received: by jurassic.park.msu.ru (Postfix, from userid 500)
	id 25D3C11E9A1; Fri,  4 May 2007 03:18:54 +0400 (MSD)
Date:	Fri, 4 May 2007 03:18:54 +0400
From:	Ivan Kokshaysky <ink at jurassic.park.msu.ru>
To:	Chuck Ebbert <cebbert at redhat.com>, linux-kernel at vger.kernel.org,
	Greg Kroah-Hartman <gregkh at suse.de>,
	Andrew Morton <akpm at linux-foundation.org>
Subject: Re: regression on quad Xeon: no SCSI-disks
Message-ID: <20070504031854.B28085 at jurassic.park.msu.ru>
References: <20070501142431.GA11667 at erig.dyndns.org> <46376474.8090505 at redhat.com> <20070502144716.GA11061 at erig.dyndns.org> <20070502211215.A19444 at jurassic.park.msu.ru> <20070503084141.GA22742 at erig.dyndns.org>
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
User-Agent: Mutt/1.2.5i
In-Reply-To: <20070503084141.GA22742 at erig.dyndns.org>; from Wolfgang.Erig at gmx.de on Thu, May 03, 2007 at 10:41:41AM +0200
Sender:	linux-kernel-owner at vger.kernel.org
Precedence: bulk
X-Mailing-List:	linux-kernel at vger.kernel.org
Status: RO
Content-Length: 1815
Lines: 44

On Thu, May 03, 2007 at 10:41:41AM +0200, Wolfgang Erig wrote:
> I am prepared to do tweaks to your small patch, but I need your help.
> My own blindly experiments failed miserably.

I don't think that patch did anything wrong, most likely it just
triggered a bug elsewhere. These two lines from your dmesg look
very suspicious:

> PCI: Cannot allocate resource region 0 of device 0000:00:04.0
> PCI: Error while updating region 0000:00:04.0/0 (a8008000 != fec08000)

Note that the BAR seems to have high address bits hardwired to fec00000.
And device 0000:00:04.0 is
> 00:04.0 System peripheral: Siemens Nixdorf AG FSC Multiprocessor Interrupt Controller (rev 02)

I'd guess that when we try to reassign this resource, PCI interrupts might
just stop working. This could explain SCSI timeouts and other weird things.

Maybe this patch helps?

Ivan.

--- 2.6.21/arch/i386/pci/fixup.c	2007-02-04 21:44:54.000000000 +0300
+++ linux/arch/i386/pci/fixup.c	2007-05-04 01:58:32.629654275 +0400
@@ -436,3 +436,14 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_CY
 			pci_early_fixup_cyrix_5530);
 DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY,
 			pci_early_fixup_cyrix_5530);
+
+/*
+ * Siemens Nixdorf AG FSC Multiprocessor Interrupt Controller:
+ * prevent update of the BAR0, which doesn't look like a normal BAR.
+ */
+static void __devinit pci_siemens_interrupt_controller(struct pci_dev *dev)
+{
+	dev->resource[0].flags |= IORESOURCE_PCI_FIXED;
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SIEMENS, 0x0015,
+			  pci_siemens_interrupt_controller);
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


linux-2.6-x86_64-ia32-vdso-install-unstripped-copies-on-disk.patch:

--- NEW FILE linux-2.6-x86_64-ia32-vdso-install-unstripped-copies-on-disk.patch ---
From: Roland McGrath <roland at redhat.com>

This keeps an unstripped copy of the vDSO images built before they are
stripped and embedded in the kernel.  The unstripped copies get installed in
$(MODLIB)/vdso/ by "make install".  These files can be useful when they
contain source-level debugging information.

Signed-off-by: Roland McGrath <roland at redhat.com>
Cc: Sam Ravnborg <sam at ravnborg.org>
Cc: Andi Kleen <ak at suse.de>
Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
---

 arch/x86_64/Makefile      |    3 +++
 arch/x86_64/ia32/Makefile |   25 +++++++++++++++++++++----
 2 files changed, 24 insertions(+), 4 deletions(-)

diff -puN arch/x86_64/Makefile~x86_64-ia32-vdso-install-unstripped-copies-on-disk arch/x86_64/Makefile
--- a/arch/x86_64/Makefile~x86_64-ia32-vdso-install-unstripped-copies-on-disk
+++ a/arch/x86_64/Makefile
@@ -105,9 +105,14 @@ bzdisk: vmlinux
 fdimage fdimage144 fdimage288 isoimage: vmlinux
 	$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(BOOTIMAGE) $@
 
-install:
+install: vdso_install
 	$(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(BOOTIMAGE) $@ 
 
+vdso_install:
+ifeq ($(CONFIG_IA32_EMULATION),y)
+	$(Q)$(MAKE) $(build)=arch/x86_64/ia32 $@
+endif
+
 archclean:
 	$(Q)$(MAKE) $(clean)=$(boot)

diff -puN arch/x86_64/ia32/Makefile~x86_64-ia32-vdso-install-unstripped-copies-on-disk arch/x86_64/ia32/Makefile
--- a/arch/x86_64/ia32/Makefile~x86_64-ia32-vdso-install-unstripped-copies-on-disk
+++ a/arch/x86_64/ia32/Makefile
@@ -18,18 +18,35 @@ $(obj)/syscall32_syscall.o: \
 	$(foreach F,sysenter syscall,$(obj)/vsyscall-$F.so)
 
 # Teach kbuild about targets
-targets := $(foreach F,sysenter syscall,vsyscall-$F.o vsyscall-$F.so)
+targets := $(foreach F,$(addprefix vsyscall-,sysenter syscall),\
+		     $F.o $F.so $F.so.dbg)
 
 # The DSO images are built using a special linker script
 quiet_cmd_syscall = SYSCALL $@
-      cmd_syscall = $(CC) -m32 -nostdlib -shared -s \
+      cmd_syscall = $(CC) -m32 -nostdlib -shared \
 			  $(call ld-option, -Wl$(comma)--hash-style=sysv) \
 			   -Wl,-soname=linux-gate.so.1 -o $@ \
 			   -Wl,-T,$(filter-out FORCE,$^)
 
-$(obj)/vsyscall-sysenter.so $(obj)/vsyscall-syscall.so: \
-$(obj)/vsyscall-%.so: $(src)/vsyscall.lds $(obj)/vsyscall-%.o FORCE
+$(obj)/%.so: OBJCOPYFLAGS := -S
+$(obj)/%.so: $(obj)/%.so.dbg FORCE
+	$(call if_changed,objcopy)
+
+$(obj)/vsyscall-sysenter.so.dbg $(obj)/vsyscall-syscall.so.dbg: \
+$(obj)/vsyscall-%.so.dbg: $(src)/vsyscall.lds $(obj)/vsyscall-%.o FORCE
 	$(call if_changed,syscall)
 
 AFLAGS_vsyscall-sysenter.o = -m32 -Wa,-32
 AFLAGS_vsyscall-syscall.o = -m32 -Wa,-32
+
+vdsos := vdso32-sysenter.so vdso32-syscall.so
+
+quiet_cmd_vdso_install = INSTALL $@
+      cmd_vdso_install = cp $(@:vdso32-%.so=$(obj)/vsyscall-%.so.dbg) \
+			    $(MODLIB)/vdso/$@
+
+$(vdsos):
+	@mkdir -p $(MODLIB)/vdso
+	$(call cmd,vdso_install)
+
+vdso_install: $(vdsos)


linux-2.6-x86_64-silence-up-apic-errors-xen.patch:

--- NEW FILE linux-2.6-x86_64-silence-up-apic-errors-xen.patch ---
Index: patching/arch/x86_64/kernel/apic-xen.c
===================================================================
--- patching.orig/arch/x86_64/kernel/apic-xen.c
+++ patching/arch/x86_64/kernel/apic-xen.c
@@ -1160,7 +1160,8 @@ asmlinkage void smp_error_interrupt(void
 	   6: Received illegal vector
 	   7: Illegal register address
 	*/
-	printk (KERN_DEBUG "APIC error on CPU%d: %02x(%02x)\n",
+	if (num_online_cpus() > 1)
+		printk (KERN_DEBUG "APIC error on CPU%d: %02x(%02x)\n",
 	        smp_processor_id(), v , v1);
 	irq_exit();
 }

linux-2.6-x86_64-vdso-install-unstripped-copies-on-disk.patch:

--- NEW FILE linux-2.6-x86_64-vdso-install-unstripped-copies-on-disk.patch ---
This keeps an unstripped copy of the vDSO images built before they are
stripped and embedded in the kernel.  The unstripped copies get installed
in $(MODLIB)/vdso/ by "make install".  These files can be useful when they
contain source-level debugging information.

Signed-off-by: Roland McGrath <roland at redhat.com>
---
 arch/x86_64/Makefile      |    1 +
 arch/x86_64/vdso/Makefile |   20 ++++++++++++++++----
 2 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/arch/x86_64/Makefile b/arch/x86_64/Makefile
index 93fc1f2..c0905ae 100644
--- a/arch/x86_64/Makefile
+++ b/arch/x86_64/Makefile
@@ -112,6 +112,7 @@ vdso_install:
 ifeq ($(CONFIG_IA32_EMULATION),y)
 	$(Q)$(MAKE) $(build)=arch/x86_64/ia32 $@
 endif
+	$(Q)$(MAKE) $(build)=arch/x86_64/vdso $@
 
 archclean:
 	$(Q)$(MAKE) $(clean)=$(boot)

diff --git a/arch/x86_64/vdso/Makefile b/arch/x86_64/vdso/Makefile
index faaa72f..20ecf05 100644
--- a/arch/x86_64/vdso/Makefile
+++ b/arch/x86_64/vdso/Makefile
@@ -13,7 +13,7 @@ vobjs := $(foreach F,$(vobjs-y),$(obj)/$F)
 
 $(obj)/vdso.o: $(obj)/vdso.so
 
-targets += vdso.so vdso.lds $(vobjs-y) vdso-syms.o
+targets += vdso.so vdso.so.dbg vdso.lds $(vobjs-y) vdso-syms.o
 
 # The DSO images are built using a special linker script.
 quiet_cmd_syscall = SYSCALL $@
@@ -25,14 +25,18 @@ export CPPFLAGS_vdso.lds += -P -C -U$(ARCH)
 vdso-flags = -fPIC -shared -Wl,-soname=linux-vdso.so.1 \
 		 $(call ld-option, -Wl$(comma)--hash-style=sysv) \
 		-Wl,-z,max-page-size=4096 -Wl,-z,common-page-size=4096
-SYSCFLAGS_vdso.so = $(vdso-flags)
+SYSCFLAGS_vdso.so.dbg = $(vdso-flags)
 
 $(obj)/vdso.o: $(src)/vdso.S $(obj)/vdso.so
 
-$(obj)/vdso.so: $(src)/vdso.lds $(vobjs) FORCE
+$(obj)/vdso.so.dbg: $(src)/vdso.lds $(vobjs) FORCE
 	$(call if_changed,syscall)
 
-CFL := $(PROFILING) -mcmodel=small -fPIC -g0 -O2 -fasynchronous-unwind-tables -m64
+$(obj)/%.so: OBJCOPYFLAGS := -S
+$(obj)/%.so: $(obj)/%.so.dbg FORCE
+	$(call if_changed,objcopy)
+
+CFL := $(PROFILING) -mcmodel=small -fPIC $(if $(CONFIG_DEBUG_INFO),-g,-g0) -O2 -fasynchronous-unwind-tables -m64
 
 $(obj)/vclock_gettime.o: CFLAGS = $(CFL)
 $(obj)/vgetcpu.o: CFLAGS = $(CFL)
@@ -47,3 +51,11 @@ $(obj)/built-in.o: ld_flags += -R $(obj)/vdso-syms.o
 SYSCFLAGS_vdso-syms.o = -r -d
 $(obj)/vdso-syms.o: $(src)/vdso.lds $(vobjs) FORCE
 	$(call if_changed,syscall)
+
+quiet_cmd_vdso_install = INSTALL $@
+      cmd_vdso_install = cp $(obj)/$@.dbg $(MODLIB)/vdso/$@
+vdso.so:
+	@mkdir -p $(MODLIB)/vdso
+	$(call cmd,vdso_install)
+
+vdso_install: vdso.so

linux-2.6-xen-irq_vector-uninitialize.patch:

--- NEW FILE linux-2.6-xen-irq_vector-uninitialize.patch ---
# HG changeset patch
# User ehabkost at localhost.localdomain
# Date 1187635504 10800
# Node ID e1ccc85dfd7c00b7f104838247a868215ad0f748
# Parent  af6283d73d0702d1f394f798add1e0f5a73f49f6
Don't initialize irq_cfg[].vector under Xen

On linux-2.6.20-xen-3.1.0, irq_cfg 'vector' field contents were on
a separated array, irq_vector, and it was not pre-initialized on Xen
(but it was pre-initialized on the upstream non-Xen code). Somewhere
between 2.6.20 and 2.6.21, the array contents were moved to irq_cfg[],
but the Xen code was not changed to keep it not being initialized.

This patches fix this. It creates an irq_cfg_element() macro to make
the field be initialized on the non-Xen case without duplicating the
array initialization.

This fixes SATA timeout problems I had on a Dell Precision
490 machine, and hopefully fixes the problems reported on Fedora
bug #252301.

diff -r af6283d73d07 -r e1ccc85dfd7c arch/x86_64/kernel/io_apic-xen.c
--- a/arch/x86_64/kernel/io_apic-xen.c	Tue Jul 17 20:26:41 2007 +0200
+++ b/arch/x86_64/kernel/io_apic-xen.c	Mon Aug 20 15:45:04 2007 -0300
@@ -56,24 +56,33 @@ struct irq_cfg {
 	u8 move_in_progress : 1;
 };
 
+#ifdef CONFIG_XEN
+/* irq_cfg[].vector is not pre-initialized on Xen */
+#define irq_cfg_element(idx, vec) \
+	[idx] = { .domain = CPU_MASK_ALL, }
+#else
+#define irq_cfg_element(idx, vec) \
+	[idx] = { .domain = CPU_MASK_ALL, .vector = vec, }
+#endif
+
 /* irq_cfg is indexed by the sum of all RTEs in all I/O APICs. */
 struct irq_cfg irq_cfg[NR_IRQS] __read_mostly = {
-	[0]  = { .domain = CPU_MASK_ALL, .vector = IRQ0_VECTOR,  },
-	[1]  = { .domain = CPU_MASK_ALL, .vector = IRQ1_VECTOR,  },
-	[2]  = { .domain = CPU_MASK_ALL, .vector = IRQ2_VECTOR,  },
-	[3]  = { .domain = CPU_MASK_ALL, .vector = IRQ3_VECTOR,  },
-	[4]  = { .domain = CPU_MASK_ALL, .vector = IRQ4_VECTOR,  },
-	[5]  = { .domain = CPU_MASK_ALL, .vector = IRQ5_VECTOR,  },
-	[6]  = { .domain = CPU_MASK_ALL, .vector = IRQ6_VECTOR,  },
-	[7]  = { .domain = CPU_MASK_ALL, .vector = IRQ7_VECTOR,  },
-	[8]  = { .domain = CPU_MASK_ALL, .vector = IRQ8_VECTOR,  },
-	[9]  = { .domain = CPU_MASK_ALL, .vector = IRQ9_VECTOR,  },
-	[10] = { .domain = CPU_MASK_ALL, .vector = IRQ10_VECTOR, },
-	[11] = { .domain = CPU_MASK_ALL, .vector = IRQ11_VECTOR, },
-	[12] = { .domain = CPU_MASK_ALL, .vector = IRQ12_VECTOR, },
-	[13] = { .domain = CPU_MASK_ALL, .vector = IRQ13_VECTOR, },
-	[14] = { .domain = CPU_MASK_ALL, .vector = IRQ14_VECTOR, },
-	[15] = { .domain = CPU_MASK_ALL, .vector = IRQ15_VECTOR, },
+	irq_cfg_element(0,  IRQ0_VECTOR),
+	irq_cfg_element(1,  IRQ1_VECTOR),
+	irq_cfg_element(2,  IRQ2_VECTOR),
+	irq_cfg_element(3,  IRQ3_VECTOR),
+	irq_cfg_element(4,  IRQ4_VECTOR),
+	irq_cfg_element(5,  IRQ5_VECTOR),
+	irq_cfg_element(6,  IRQ6_VECTOR),
+	irq_cfg_element(7,  IRQ7_VECTOR),
+	irq_cfg_element(8,  IRQ8_VECTOR),
+	irq_cfg_element(9,  IRQ9_VECTOR),
+	irq_cfg_element(10, IRQ10_VECTOR),
+	irq_cfg_element(11, IRQ11_VECTOR),
+	irq_cfg_element(12, IRQ12_VECTOR),
+	irq_cfg_element(13, IRQ13_VECTOR),
+	irq_cfg_element(14, IRQ14_VECTOR),
+	irq_cfg_element(15, IRQ15_VECTOR),
 };
 
 static int assign_irq_vector(int irq, cpumask_t mask);

linux-2.6-xfs-optimize-away-dmapi-tests.patch:

--- NEW FILE linux-2.6-xfs-optimize-away-dmapi-tests.patch ---
From: Eric Sandeen <sandeen at sandeen.net>
Date: Thu, 23 Aug 2007 06:19:57 +0000 (+1000)
Subject: [XFS] optimize dmapi event tests w/o dmapi config
X-Git-Url: http://oss.sgi.com/cgi-bin/gitweb.cgi?p=xfs%2Fxfs-2.6.git;a=commitdiff_plain;h=c4389058a94b1b9c4be0484ca15368f560fb1ef7;hp=0a0aa86fe08645c72e5fa26770a70428f2c9ae3c

[XFS] optimize dmapi event tests w/o dmapi config

Defining XFS_DM_EVENT* macros to 0 in the absence of
CONFIG_XFS_DMAPI allows gcc to optimize away tests that
should never be true. Also wrap one hunk of xfs_unmount
in #ifdef CONFIG_XFS_DMAPI

Stack deltas on x86, gcc 4.1:

xfs_create              -16
xfs_free_file_space     -4
xfs_getbmap             +4
xfs_link                -8
xfs_mkidr               -20
xfs_read                -24
xfs_remove              -12
xfs_rename              -8
xfs_rmdir               -16
xfs_setattr             -20
xfs_splice_read         -20
xfs_splice_write        -20
xfs_unmount             -48
xfs_write               -20

SGI-PV: 969372
SGI-Modid: xfs-linux-melb:xfs-kern:29444a

Signed-off-by: Eric Sandeen <sandeen at sandeen.net>
Signed-off-by: Vlad Apostolov <vapo at sgi.com>
Signed-off-by: Tim Shimmin <tes at sgi.com>
---

Index: linux-2.6.22.i386/fs/xfs/xfs_dmapi.h
===================================================================
--- linux-2.6.22.i386.orig/fs/xfs/xfs_dmapi.h
+++ linux-2.6.22.i386/fs/xfs/xfs_dmapi.h
@@ -67,6 +67,7 @@ typedef enum {
 #define HAVE_DM_RIGHT_T
 
 /* Defines for determining if an event message should be sent. */
+#ifdef CONFIG_XFS_DMAPI
 #define	DM_EVENT_ENABLED(vfsp, ip, event) ( \
 	unlikely ((vfsp)->vfs_flag & VFS_DMI) && \
 		( ((ip)->i_d.di_dmevmask & (1 << event)) || \
@@ -78,6 +79,10 @@ typedef enum {
 		( ((io)->io_dmevmask & (1 << event)) || \
 		  ((io)->io_mount->m_dmevmask & (1 << event)) ) \
 	)
+#else
+#define DM_EVENT_ENABLED(vfsp, ip, event) (0)
+#define DM_EVENT_ENABLED_IO(vfsp, io, event) (0)
+#endif
 
 #define DM_XFS_VALID_FS_EVENTS		( \
 	(1 << DM_EVENT_PREUNMOUNT)	| \
Index: linux-2.6.22.i386/fs/xfs/xfs_vfsops.c
===================================================================
--- linux-2.6.22.i386.orig/fs/xfs/xfs_vfsops.c
+++ linux-2.6.22.i386/fs/xfs/xfs_vfsops.c
@@ -568,6 +568,7 @@ xfs_unmount(
 	rip = mp->m_rootip;
 	rvp = XFS_ITOV(rip);
 
+#ifdef HAVE_DMAPI
 	if (vfsp->vfs_flag & VFS_DMI) {
 		error = XFS_SEND_PREUNMOUNT(mp, vfsp,
 				rvp, DM_RIGHT_NULL, rvp, DM_RIGHT_NULL,
@@ -580,7 +581,7 @@ xfs_unmount(
 		unmount_event_flags = (mp->m_dmevmask & (1<<DM_EVENT_UNMOUNT))?
 					0 : DM_FLAGS_UNWANTED;
 	}
-
+#endif
 	/*
 	 * First blow any referenced inode from this file system
 	 * out of the reference cache, and delete the timer.

linux-2.6-xfs-optimize-away-realtime-tests.patch:

--- NEW FILE linux-2.6-xfs-optimize-away-realtime-tests.patch ---
Use XFS_IS_REALTIME_INODE in more places, and #define it to
0 if CONFIG_XFS_RT is off.  This should be safe because mount
checks in xfs_rtmount_init:

# define xfs_rtmount_init(m)    (((mp)->m_sb.sb_rblocks == 0)? 0 : (ENOSYS))

so if we get mounted w/o CONFIG_XFS_RT, no realtime inodes should
be encountered after that.

Defining XFS_IS_REALTIME_INODE to 0 saves a bit of stack space,
presumeably gcc can optimize around the various "if (0)" type
checks:

xfs_alloc_file_space	-8
xfs_bmap_adjacent	-16
xfs_bmapi		-8
xfs_bmap_rtalloc	-16
xfs_bunmapi		-28
xfs_free_file_space	-64
xfs_imap		+8  <-- ?  hmm.
xfs_iomap_write_direct	-12
xfs_qm_dqusage_adjust	-4
xfs_qm_vop_chown_reserve -4

Compile tested only at this point.

Signed-off-by: Eric Sandeen <sandeen at sandeen.net>

Index: linux-2.6.22.i386/fs/xfs/xfs_rtalloc.h
===================================================================
--- linux-2.6.22.i386.orig/fs/xfs/xfs_rtalloc.h
+++ linux-2.6.22.i386/fs/xfs/xfs_rtalloc.h
@@ -21,8 +21,6 @@
 struct xfs_mount;
 struct xfs_trans;
 
-#define XFS_IS_REALTIME_INODE(ip) ((ip)->i_d.di_flags & XFS_DIFLAG_REALTIME)
-
 /* Min and max rt extent sizes, specified in bytes */
 #define	XFS_MAX_RTEXTSIZE	(1024 * 1024 * 1024)	/* 1GB */
 #define	XFS_DFL_RTEXTSIZE	(64 * 1024)	        /* 64KB */
Index: linux-2.6.22.i386/fs/xfs/linux-2.6/xfs_ioctl.c
===================================================================
--- linux-2.6.22.i386.orig/fs/xfs/linux-2.6/xfs_ioctl.c
+++ linux-2.6.22.i386/fs/xfs/linux-2.6/xfs_ioctl.c
@@ -736,7 +736,7 @@ xfs_ioctl(
 	case XFS_IOC_DIOINFO: {
 		struct dioattr	da;
 		xfs_buftarg_t	*target =
-			(ip->i_d.di_flags & XFS_DIFLAG_REALTIME) ?
+			XFS_IS_REALTIME_INODE(ip) ?
 			mp->m_rtdev_targp : mp->m_ddev_targp;
 
 		da.d_mem = da.d_miniosz = 1 << target->bt_sshift;
Index: linux-2.6.22.i386/fs/xfs/linux-2.6/xfs_lrw.c
===================================================================
--- linux-2.6.22.i386.orig/fs/xfs/linux-2.6/xfs_lrw.c
+++ linux-2.6.22.i386/fs/xfs/linux-2.6/xfs_lrw.c
@@ -220,7 +220,7 @@ xfs_read(
 
 	if (unlikely(ioflags & IO_ISDIRECT)) {
 		xfs_buftarg_t	*target =
-			(ip->i_d.di_flags & XFS_DIFLAG_REALTIME) ?
+			XFS_IS_REALTIME_INODE(ip) ?
 				mp->m_rtdev_targp : mp->m_ddev_targp;
 		if ((*offset & target->bt_smask) ||
 		    (size & target->bt_smask)) {
@@ -694,7 +694,7 @@ start:
 
 	if (ioflags & IO_ISDIRECT) {
 		xfs_buftarg_t	*target =
-			(xip->i_d.di_flags & XFS_DIFLAG_REALTIME) ?
+			XFS_IS_REALTIME_INODE(xip) ?
 				mp->m_rtdev_targp : mp->m_ddev_targp;
 
 		if ((pos & target->bt_smask) || (count & target->bt_smask)) {
Index: linux-2.6.22.i386/fs/xfs/xfs_dfrag.c
===================================================================
--- linux-2.6.22.i386.orig/fs/xfs/xfs_dfrag.c
+++ linux-2.6.22.i386/fs/xfs/xfs_dfrag.c
@@ -184,8 +184,7 @@ xfs_swap_extents(
 	}
 
 	/* Verify both files are either real-time or non-realtime */
-	if ((ip->i_d.di_flags & XFS_DIFLAG_REALTIME) !=
-	    (tip->i_d.di_flags & XFS_DIFLAG_REALTIME)) {
+	if (XFS_IS_REALTIME_INODE(ip) != XFS_IS_REALTIME_INODE(tip)) {
 		error = XFS_ERROR(EINVAL);
 		goto error0;
 	}
Index: linux-2.6.22.i386/fs/xfs/xfs_iocore.c
===================================================================
--- linux-2.6.22.i386.orig/fs/xfs/xfs_iocore.c
+++ linux-2.6.22.i386/fs/xfs/xfs_iocore.c
@@ -94,7 +94,7 @@ xfs_iocore_inode_reinit(
 	xfs_iocore_t	*io = &ip->i_iocore;
 
 	io->io_flags = 0;
-	if (ip->i_d.di_flags & XFS_DIFLAG_REALTIME)
+	if (XFS_IS_REALTIME_INODE(ip))
 		io->io_flags |= XFS_IOCORE_RT;
 	io->io_dmevmask = ip->i_d.di_dmevmask;
 	io->io_dmstate = ip->i_d.di_dmstate;
Index: linux-2.6.22.i386/fs/xfs/xfs_rw.h
===================================================================
--- linux-2.6.22.i386.orig/fs/xfs/xfs_rw.h
+++ linux-2.6.22.i386/fs/xfs/xfs_rw.h
@@ -58,7 +58,7 @@ struct xfs_mount;
 static inline xfs_daddr_t
 xfs_fsb_to_db(struct xfs_inode *ip, xfs_fsblock_t fsb)
 {
-	return (((ip)->i_d.di_flags & XFS_DIFLAG_REALTIME) ? \
+	return (XFS_IS_REALTIME_INODE(ip) ? \
 		 (xfs_daddr_t)XFS_FSB_TO_BB((ip)->i_mount, (fsb)) : \
 		 XFS_FSB_TO_DADDR((ip)->i_mount, (fsb)));
 }
@@ -87,7 +87,7 @@ xfs_get_extsz_hint(
 {
 	xfs_extlen_t	extsz;
 
-	if (unlikely(ip->i_d.di_flags & XFS_DIFLAG_REALTIME)) {
+	if (unlikely(XFS_IS_REALTIME_INODE(ip))) {
 		extsz = (ip->i_d.di_flags & XFS_DIFLAG_EXTSIZE)
 				? ip->i_d.di_extsize
 				: ip->i_mount->m_sb.sb_rextsize;
Index: linux-2.6.22.i386/fs/xfs/xfs_vnodeops.c
===================================================================
--- linux-2.6.22.i386.orig/fs/xfs/xfs_vnodeops.c
+++ linux-2.6.22.i386/fs/xfs/xfs_vnodeops.c
@@ -144,7 +144,7 @@ xfs_getattr(
 	default:
 		vap->va_rdev = 0;
 
-		if (!(ip->i_d.di_flags & XFS_DIFLAG_REALTIME)) {
+		if (!(XFS_IS_REALTIME_INODE(ip))) {
 			vap->va_blocksize = xfs_preferred_iosize(mp);
 		} else {
 
@@ -521,7 +521,7 @@ xfs_setattr(
 		 */
 		if ((ip->i_d.di_nextents || ip->i_delayed_blks) &&
 		    (mask & XFS_AT_XFLAGS) &&
-		    (ip->i_d.di_flags & XFS_DIFLAG_REALTIME) !=
+		    (XFS_IS_REALTIME_INODE(ip)) !=
 		    (vap->va_xflags & XFS_XFLAG_REALTIME)) {
 			code = XFS_ERROR(EINVAL);	/* EFBIG? */
 			goto error_return;
@@ -533,7 +533,7 @@ xfs_setattr(
 		if ((mask & XFS_AT_EXTSIZE) && vap->va_extsize != 0) {
 			xfs_extlen_t	size;
 
-			if ((ip->i_d.di_flags & XFS_DIFLAG_REALTIME) ||
+			if (XFS_IS_REALTIME_INODE(ip) ||
 			    ((mask & XFS_AT_XFLAGS) &&
 			    (vap->va_xflags & XFS_XFLAG_REALTIME))) {
 				size = mp->m_sb.sb_rextsize <<
@@ -1188,7 +1188,7 @@ xfs_fsync(
 		 * If this inode is on the RT dev we need to flush that
 		 * cache as well.
 		 */
-		if (ip->i_d.di_flags & XFS_DIFLAG_REALTIME)
+		if (XFS_IS_REALTIME_INODE(ip))
 			xfs_blkdev_issue_flush(ip->i_mount->m_rtdev_targp);
 	}
 
@@ -4263,7 +4263,7 @@ xfs_zero_remaining_bytes(
 	int			error = 0;
 
 	bp = xfs_buf_get_noaddr(mp->m_sb.sb_blocksize,
-				ip->i_d.di_flags & XFS_DIFLAG_REALTIME ?
+				XFS_IS_REALTIME_INODE(ip) ?
 				mp->m_rtdev_targp : mp->m_ddev_targp);
 
 	for (offset = startoff; offset <= endoff; offset = lastoffset + 1) {
@@ -4360,7 +4360,7 @@ xfs_free_file_space(
 	error = 0;
 	if (len <= 0)	/* if nothing being freed */
 		return error;
-	rt = (ip->i_d.di_flags & XFS_DIFLAG_REALTIME);
+	rt = XFS_IS_REALTIME_INODE(ip);
 	startoffset_fsb	= XFS_B_TO_FSB(mp, offset);
 	end_dmi_offset = offset + len;
 	endoffset_fsb = XFS_B_TO_FSBT(mp, end_dmi_offset);
Index: linux-2.6.22.i386/fs/xfs/xfs_dinode.h
===================================================================
--- linux-2.6.22.i386.orig/fs/xfs/xfs_dinode.h
+++ linux-2.6.22.i386/fs/xfs/xfs_dinode.h
@@ -274,6 +274,12 @@ typedef enum xfs_dinode_fmt
 #define XFS_DIFLAG_NODEFRAG      (1 << XFS_DIFLAG_NODEFRAG_BIT)
 #define XFS_DIFLAG_FILESTREAM    (1 << XFS_DIFLAG_FILESTREAM_BIT)
 
+#ifdef CONFIG_XFS_RT
+#define XFS_IS_REALTIME_INODE(ip) ((ip)->i_d.di_flags & XFS_DIFLAG_REALTIME)
+#else
+#define XFS_IS_REALTIME_INODE(ip) (0)
+#endif
+
 #define XFS_DIFLAG_ANY \
 	(XFS_DIFLAG_REALTIME | XFS_DIFLAG_PREALLOC | XFS_DIFLAG_NEWRTBM | \
 	 XFS_DIFLAG_IMMUTABLE | XFS_DIFLAG_APPEND | XFS_DIFLAG_SYNC | \

linux-2.6-xfs-refactor-xfs_mountfs.patch:

--- NEW FILE linux-2.6-xfs-refactor-xfs_mountfs.patch ---
Index: linux-2.6.22.i386/fs/xfs/xfs_mount.c
===================================================================
--- linux-2.6.22.i386.orig/fs/xfs/xfs_mount.c
+++ linux-2.6.22.i386/fs/xfs/xfs_mount.c
@@ -701,51 +701,13 @@ xfs_initialize_perag_data(xfs_mount_t *m
 	return 0;
 }
 
-/*
- * xfs_mountfs
- *
- * This function does the following on an initial mount of a file system:
- *	- reads the superblock from disk and init the mount struct
- *	- if we're a 32-bit kernel, do a size check on the superblock
- *		so we don't mount terabyte filesystems
- *	- init mount struct realtime fields
- *	- allocate inode hash table for fs
- *	- init directory manager
- *	- perform recovery and init the log manager
- */
-int
-xfs_mountfs(
-	bhv_vfs_t	*vfsp,
-	xfs_mount_t	*mp,
-	int		mfsi_flags)
+STATIC int
+xfs_update_alignment(xfs_mount_t *mp,
+			int mfsi_flags,
+		     __uint64_t *update_flags)
 {
-	xfs_buf_t	*bp;
 	xfs_sb_t	*sbp = &(mp->m_sb);
-	xfs_inode_t	*rip;
-	bhv_vnode_t	*rvp = NULL;
-	int		readio_log, writeio_log;
-	xfs_daddr_t	d;
-	__uint64_t	resblks;
-	__int64_t	update_flags;
-	uint		quotamount, quotaflags;
-	int		agno;
-	int		uuid_mounted = 0;
-	int		error = 0;
 
-	if (mp->m_sb_bp == NULL) {
-		if ((error = xfs_readsb(mp, mfsi_flags))) {
-			return error;
-		}
-	}
-	xfs_mount_common(mp, sbp);
-
-	/*
-	 * Check if sb_agblocks is aligned at stripe boundary
-	 * If sb_agblocks is NOT aligned turn off m_dalign since
-	 * allocator alignment is within an ag, therefore ag has
-	 * to be aligned at stripe boundary.
-	 */
-	update_flags = 0LL;
 	if (mp->m_dalign && !(mfsi_flags & XFS_MFSI_SECOND)) {
 		/*
 		 * If stripe unit and stripe width are not multiples
@@ -756,8 +718,7 @@ xfs_mountfs(
 			if (mp->m_flags & XFS_MOUNT_RETERR) {
 				cmn_err(CE_WARN,
 					"XFS: alignment check 1 failed");
-				error = XFS_ERROR(EINVAL);
-				goto error1;
+				return XFS_ERROR(EINVAL);
 			}
 			mp->m_dalign = mp->m_swidth = 0;
 		} else {
@@ -767,8 +728,7 @@ xfs_mountfs(
 			mp->m_dalign = XFS_BB_TO_FSBT(mp, mp->m_dalign);
 			if (mp->m_dalign && (sbp->sb_agblocks % mp->m_dalign)) {
 				if (mp->m_flags & XFS_MOUNT_RETERR) {
-					error = XFS_ERROR(EINVAL);
-					goto error1;
+					return XFS_ERROR(EINVAL);
 				}
 				xfs_fs_cmn_err(CE_WARN, mp,
 "stripe alignment turned off: sunit(%d)/swidth(%d) incompatible with agsize(%d)",
@@ -783,10 +743,9 @@ xfs_mountfs(
 				if (mp->m_flags & XFS_MOUNT_RETERR) {
 					xfs_fs_cmn_err(CE_WARN, mp,
 "stripe alignment turned off: sunit(%d) less than bsize(%d)",
-                                        	mp->m_dalign,
+						mp->m_dalign,
 						mp->m_blockmask +1);
-					error = XFS_ERROR(EINVAL);
-					goto error1;
+					return XFS_ERROR(EINVAL);
 				}
 				mp->m_swidth = 0;
 			}
@@ -799,11 +758,11 @@ xfs_mountfs(
 		if (XFS_SB_VERSION_HASDALIGN(sbp)) {
 			if (sbp->sb_unit != mp->m_dalign) {
 				sbp->sb_unit = mp->m_dalign;
-				update_flags |= XFS_SB_UNIT;
+				*update_flags |= XFS_SB_UNIT;
 			}
 			if (sbp->sb_width != mp->m_swidth) {
 				sbp->sb_width = mp->m_swidth;
-				update_flags |= XFS_SB_WIDTH;
+				*update_flags |= XFS_SB_WIDTH;
 			}
 		}
 	} else if ((mp->m_flags & XFS_MOUNT_NOALIGN) != XFS_MOUNT_NOALIGN &&
@@ -811,11 +770,13 @@ xfs_mountfs(
 			mp->m_dalign = sbp->sb_unit;
 			mp->m_swidth = sbp->sb_width;
 	}
+	return 0;
+}
 
-	xfs_alloc_compute_maxlevels(mp);
-	xfs_bmap_compute_maxlevels(mp, XFS_DATA_FORK);
-	xfs_bmap_compute_maxlevels(mp, XFS_ATTR_FORK);
-	xfs_ialloc_compute_maxlevels(mp);
+STATIC void
+xfs_set_maxicount(xfs_mount_t *mp)
+{
+	xfs_sb_t	*sbp = &(mp->m_sb);
 
 	if (sbp->sb_imax_pct) {
 		__uint64_t	icount;
@@ -831,33 +792,20 @@ xfs_mountfs(
 				   sbp->sb_inopblog;
 	} else
 		mp->m_maxicount = 0;
+}
 
-	mp->m_maxioffset = xfs_max_file_offset(sbp->sb_blocklog);
-
-	/*
-	 * XFS uses the uuid from the superblock as the unique
-	 * identifier for fsid.  We can not use the uuid from the volume
-	 * since a single partition filesystem is identical to a single
-	 * partition volume/filesystem.
-	 */
-	if ((mfsi_flags & XFS_MFSI_SECOND) == 0 &&
-	    (mp->m_flags & XFS_MOUNT_NOUUID) == 0) {
-		__uint64_t	ret64;
-		if (xfs_uuid_mount(mp)) {
-			error = XFS_ERROR(EINVAL);
-			goto error1;
-		}
-		uuid_mounted=1;
-		ret64 = uuid_hash64(&sbp->sb_uuid);
-		memcpy(&vfsp->vfs_fsid, &ret64, sizeof(ret64));
-	}
+/*
+ * Set the default minimum read and write sizes unless
+ * already specified in a mount option.
+ * We use smaller I/O sizes when the file system
+ * is being used for NFS service (wsync mount option).
+ */
+STATIC
+void xfs_set_rw_sizes(xfs_mount_t *mp)
+{
+	xfs_sb_t	*sbp = &(mp->m_sb);
+	int		readio_log, writeio_log;
 
-	/*
-	 * Set the default minimum read and write sizes unless
-	 * already specified in a mount option.
-	 * We use smaller I/O sizes when the file system
-	 * is being used for NFS service (wsync mount option).
-	 */
 	if (!(mp->m_flags & XFS_MOUNT_DFLT_IOSIZE)) {
 		if (mp->m_flags & XFS_MOUNT_WSYNC) {
 			readio_log = XFS_WSYNC_READIO_LOG;
@@ -893,43 +841,20 @@ xfs_mountfs(
 		mp->m_writeio_log = writeio_log;
 	}
 	mp->m_writeio_blocks = 1 << (mp->m_writeio_log - sbp->sb_blocklog);
+}
+
+STATIC int
+xfs_size_checks(xfs_mount_t *mp,
+              int mfsi_flags)
+{
+      xfs_buf_t       *bp;
+      xfs_daddr_t     d;
+      int             error;
 
-	/*
-	 * Set the inode cluster size based on the physical memory
-	 * size.  This may still be overridden by the file system
-	 * block size if it is larger than the chosen cluster size.
-	 */
-	if (xfs_physmem <= btoc(32 * 1024 * 1024)) { /* <= 32 MB */
-		mp->m_inode_cluster_size = XFS_INODE_SMALL_CLUSTER_SIZE;
-	} else {
-		mp->m_inode_cluster_size = XFS_INODE_BIG_CLUSTER_SIZE;
-	}
-	/*
-	 * Set whether we're using inode alignment.
-	 */
-	if (XFS_SB_VERSION_HASALIGN(&mp->m_sb) &&
-	    mp->m_sb.sb_inoalignmt >=
-	    XFS_B_TO_FSBT(mp, mp->m_inode_cluster_size))
-		mp->m_inoalign_mask = mp->m_sb.sb_inoalignmt - 1;
-	else
-		mp->m_inoalign_mask = 0;
-	/*
-	 * If we are using stripe alignment, check whether
-	 * the stripe unit is a multiple of the inode alignment
-	 */
-	if (mp->m_dalign && mp->m_inoalign_mask &&
-	    !(mp->m_dalign & mp->m_inoalign_mask))
-		mp->m_sinoalign = mp->m_dalign;
-	else
-		mp->m_sinoalign = 0;
-	/*
-	 * Check that the data (and log if separate) are an ok size.
-	 */
 	d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks);
 	if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_dblocks) {
 		cmn_err(CE_WARN, "XFS: size check 1 failed");
-		error = XFS_ERROR(E2BIG);
-		goto error1;
+		return XFS_ERROR(E2BIG);
 	}
 	error = xfs_read_buf(mp, mp->m_ddev_targp,
 			     d - XFS_FSS_TO_BB(mp, 1),
@@ -941,7 +866,7 @@ xfs_mountfs(
 		if (error == ENOSPC) {
 			error = XFS_ERROR(E2BIG);
 		}
-		goto error1;
+		return error;
 	}
 
 	if (((mfsi_flags & XFS_MFSI_CLIENT) == 0) &&
@@ -949,8 +874,7 @@ xfs_mountfs(
 		d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks);
 		if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_logblocks) {
 			cmn_err(CE_WARN, "XFS: size check 3 failed");
-			error = XFS_ERROR(E2BIG);
-			goto error1;
+			return XFS_ERROR(E2BIG);
 		}
 		error = xfs_read_buf(mp, mp->m_logdev_targp,
 				     d - XFS_FSB_TO_BB(mp, 1),
@@ -962,10 +886,118 @@ xfs_mountfs(
 			if (error == ENOSPC) {
 				error = XFS_ERROR(E2BIG);
 			}
+			return error;
+		}
+	}
+	return 0;
+}
+
+/*
+ * xfs_mountfs
+ *
+ * This function does the following on an initial mount of a file system:
+ *	- reads the superblock from disk and init the mount struct
+ *	- if we're a 32-bit kernel, do a size check on the superblock
+ *		so we don't mount terabyte filesystems
+ *	- init mount struct realtime fields
+ *	- allocate inode hash table for fs
+ *	- init directory manager
+ *	- perform recovery and init the log manager
+ */
+int
+xfs_mountfs(
+	bhv_vfs_t	*vfsp,
+	xfs_mount_t	*mp,
+	int		mfsi_flags)
+{
+	xfs_sb_t	*sbp = &(mp->m_sb);
+	xfs_inode_t	*rip;
+	bhv_vnode_t	*rvp = NULL;
+	__uint64_t	resblks;
+	__int64_t	update_flags;
+	uint		quotamount, quotaflags;
+	int		agno;
+	int		uuid_mounted = 0;
+	int		error = 0;
+
+	if (mp->m_sb_bp == NULL) {
+		if ((error = xfs_readsb(mp, mfsi_flags))) {
+			return error;
+		}
+	}
+	xfs_mount_common(mp, sbp);
+
+	/*
+	 * Check if sb_agblocks is aligned at stripe boundary
+	 * If sb_agblocks is NOT aligned turn off m_dalign since
+	 * allocator alignment is within an ag, therefore ag has
+	 * to be aligned at stripe boundary.
+	 */
+	update_flags = 0LL;
+	if ((error = xfs_update_alignment(mp, mfsi_flags, &update_flags)))
+		goto error1;
+
+	xfs_alloc_compute_maxlevels(mp);
+	xfs_bmap_compute_maxlevels(mp, XFS_DATA_FORK);
+	xfs_bmap_compute_maxlevels(mp, XFS_ATTR_FORK);
+	xfs_ialloc_compute_maxlevels(mp);
+	xfs_set_maxicount(mp);
+	mp->m_maxioffset = xfs_max_file_offset(sbp->sb_blocklog);
+
+	/*
+	 * XFS uses the uuid from the superblock as the unique
+	 * identifier for fsid.  We can not use the uuid from the volume
+	 * since a single partition filesystem is identical to a single
+	 * partition volume/filesystem.
+	 */
+	if ((mfsi_flags & XFS_MFSI_SECOND) == 0 &&
+	    (mp->m_flags & XFS_MOUNT_NOUUID) == 0) {
+		__uint64_t	ret64;
+		if (xfs_uuid_mount(mp)) {
+			error = XFS_ERROR(EINVAL);
 			goto error1;
 		}
+		uuid_mounted=1;
+		ret64 = uuid_hash64(&sbp->sb_uuid);
+		memcpy(&vfsp->vfs_fsid, &ret64, sizeof(ret64));
 	}
 
+	xfs_set_rw_sizes(mp);
+
+	/*
+	 * Set the inode cluster size based on the physical memory
+	 * size.  This may still be overridden by the file system
+	 * block size if it is larger than the chosen cluster size.
+	 */
+	if (xfs_physmem <= btoc(32 * 1024 * 1024)) { /* <= 32 MB */
+		mp->m_inode_cluster_size = XFS_INODE_SMALL_CLUSTER_SIZE;
+	} else {
+		mp->m_inode_cluster_size = XFS_INODE_BIG_CLUSTER_SIZE;
+	}
+	/*
+	 * Set whether we're using inode alignment.
+	 */
+	if (XFS_SB_VERSION_HASALIGN(&mp->m_sb) &&
+	    mp->m_sb.sb_inoalignmt >=
+	    XFS_B_TO_FSBT(mp, mp->m_inode_cluster_size))
+		mp->m_inoalign_mask = mp->m_sb.sb_inoalignmt - 1;
+	else
+		mp->m_inoalign_mask = 0;
+	/*
+	 * If we are using stripe alignment, check whether
+	 * the stripe unit is a multiple of the inode alignment
+	 */
+	if (mp->m_dalign && mp->m_inoalign_mask &&
+	    !(mp->m_dalign & mp->m_inoalign_mask))
+		mp->m_sinoalign = mp->m_dalign;
+	else
+		mp->m_sinoalign = 0;
+	/*
+	 * Check that the data (and log if separate) are an ok size.
+	 */
+	if ((error = xfs_size_checks(mp, mfsi_flags)))
+		goto error1;
+
 	/*
 	 * Initialize realtime fields in the mount structure
 	 */

linux-2.6-xfs-setfattr-32bit-compat.patch:

--- NEW FILE linux-2.6-xfs-setfattr-32bit-compat.patch ---
Date: Mon, 17 Sep 2007 12:36:02 -0500
From: Eric Sandeen <sandeen at sandeen.net>
To: Eric Sandeen <sandeen at sandeen.net>
CC: xfs-oss <xfs at oss.sgi.com>
Subject: [PATCH V2] fix 32-bit compat ioctls for GETXFLAGS, SETXFLAGS, GETVERSION

In Red Hat bugzilla #291981, Sami Farin notes that 32-bit-compat
lsattr/chattr does not work on xfs.  After investigation, I found:

XFS_IOC_GETVERSION, XFS_IOC_GETXFLAGS and XFS_IOC_SETXFLAGS all
take a "long" which changes size between 32 and 64 bit platforms.

So, the ioctl cmds that come in from a 32-bit app aren't as expected, 
for example on GETXFLAGS,

	unknown cmd fd(3) cmd(80046601){t:'f';sz:4}

due to the size mismatch.

So, use instead the 32-bit version of the commands for compat ioctls,
and other than that it doesn't take any more manipulation.

Also, for both native and compat versions, just define them to
the values as defined in fs.h

Signed-off-by: Eric Sandeen <sandeen at sandeen.net>

Index: linux-2.6.22/fs/xfs/linux-2.6/xfs_ioctl32.c
===================================================================
--- linux-2.6.22.orig/fs/xfs/linux-2.6/xfs_ioctl32.c
+++ linux-2.6.22/fs/xfs/linux-2.6/xfs_ioctl32.c
@@ -376,9 +376,6 @@ xfs_compat_ioctl(
 	switch (cmd) {
 	case XFS_IOC_DIOINFO:
 	case XFS_IOC_FSGEOMETRY:
-	case XFS_IOC_GETVERSION:
-	case XFS_IOC_GETXFLAGS:
-	case XFS_IOC_SETXFLAGS:
 	case XFS_IOC_FSGETXATTR:
 	case XFS_IOC_FSSETXATTR:
 	case XFS_IOC_FSGETXATTRA:
@@ -404,6 +401,11 @@ xfs_compat_ioctl(
 	case XFS_IOC_ERROR_CLEARALL:
 		break;
 
+	case XFS_IOC32_GETXFLAGS:
+	case XFS_IOC32_SETXFLAGS:
+	case XFS_IOC32_GETVERSION:
+		cmd = _NATIVE_IOC(cmd, long);
+		break;
 #ifdef BROKEN_X86_ALIGNMENT
 	/* xfs_flock_t has wrong u32 vs u64 alignment */
 	case XFS_IOC_ALLOCSP_32:
Index: linux-2.6.22/fs/xfs/xfs_fs.h
===================================================================
--- linux-2.6.22.orig/fs/xfs/xfs_fs.h
+++ linux-2.6.22/fs/xfs/xfs_fs.h
@@ -436,9 +436,13 @@ typedef struct xfs_handle {
 /*
  * ioctl commands that are used by Linux filesystems
  */
-#define XFS_IOC_GETXFLAGS	_IOR('f', 1, long)
-#define XFS_IOC_SETXFLAGS	_IOW('f', 2, long)
-#define XFS_IOC_GETVERSION	_IOR('v', 1, long)
+#define XFS_IOC_GETXFLAGS	FS_IOC_GETFLAGS
+#define XFS_IOC_SETXFLAGS	FS_IOC_SETFLAGS
+#define XFS_IOC_GETVERSION	FS_IOC_GETVERSION
+/* 32-bit compat counterparts */
+#define XFS_IOC32_GETXFLAGS	FS_IOC32_GETFLAGS
+#define XFS_IOC32_SETXFLAGS	FS_IOC32_SETFLAGS
+#define XFS_IOC32_GETVERSION	FS_IOC32_GETVERSION
 
 /*

  * ioctl commands that replace IRIX fcntl()'s





linux-2.6-zd1211rw-mac80211.patch:

--- NEW FILE linux-2.6-zd1211rw-mac80211.patch ---
diff -up linux-2.6.22.noarch/MAINTAINERS.orig linux-2.6.22.noarch/MAINTAINERS
--- linux-2.6.22.noarch/MAINTAINERS.orig	2007-09-27 09:59:49.000000000 -0400
+++ linux-2.6.22.noarch/MAINTAINERS	2007-09-27 09:59:55.000000000 -0400
@@ -4287,6 +4287,16 @@ W:	http://www.qsl.net/dl1bke/
 L:	linux-hams at vger.kernel.org
 S:	Maintained
 
+ZD1211RW-MAC80211 WIRELESS DRIVER
+P:	Daniel Drake
+M:	dsd at gentoo.org
+P:	Ulrich Kunitz
+M:	kune at deine-taler.de
+W:	http://zd1211.ath.cx/wiki/DriverRewrite
+L:	linux-wireless at vger.kernel.org
+L:	zd1211-devs at lists.sourceforge.net (subscribers-only)
+S:	Maintained
+
 ZD1211RW WIRELESS DRIVER
 P:	Daniel Drake
 M:	dsd at gentoo.org
diff -up linux-2.6.22.noarch/drivers/net/wireless/Makefile.orig linux-2.6.22.noarch/drivers/net/wireless/Makefile
--- linux-2.6.22.noarch/drivers/net/wireless/Makefile.orig	2007-09-27 09:59:49.000000000 -0400
+++ linux-2.6.22.noarch/drivers/net/wireless/Makefile	2007-09-27 09:59:55.000000000 -0400
@@ -41,6 +41,7 @@ obj-$(CONFIG_BCM43XX)		+= bcm43xx/
 obj-$(CONFIG_B43)		+= b43/
 obj-$(CONFIG_B43LEGACY)		+= b43legacy/
 obj-$(CONFIG_ZD1211RW)		+= zd1211rw/
+obj-$(CONFIG_ZD1211RW_MAC80211)	+= zd1211rw-mac80211/
 
 # 16-bit wireless PCMCIA client drivers
 obj-$(CONFIG_PCMCIA_RAYCS)	+= ray_cs.o
diff -up /dev/null linux-2.6.22.noarch/drivers/net/wireless/zd1211rw-mac80211/zd_chip.c
--- /dev/null	2007-09-27 08:31:24.563724082 -0400
+++ linux-2.6.22.noarch/drivers/net/wireless/zd1211rw-mac80211/zd_chip.c	2007-09-27 10:00:45.000000000 -0400
@@ -0,0 +1,1619 @@
+/* zd_chip.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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
+ */
+
+/* This file implements all the hardware specific functions for the ZD1211
+ * and ZD1211B chips. Support for the ZD1211B was possible after Timothy
+ * Legge sent me a ZD1211B device. Thank you Tim. -- Uli
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+
+#include "zd_def.h"
+#include "zd_chip.h"
+#include "zd_ieee80211.h"
+#include "zd_mac.h"
+#include "zd_rf.h"
+#include "zd_util.h"
+
+void zd_chip_init(struct zd_chip *chip,
+	         struct ieee80211_hw *hw,
+		 struct usb_interface *intf)
+{
+	memset(chip, 0, sizeof(*chip));
+	mutex_init(&chip->mutex);
+	zd_usb_init(&chip->usb, hw, intf);
+	zd_rf_init(&chip->rf);
+}
+
+void zd_chip_clear(struct zd_chip *chip)
+{
+	ZD_ASSERT(!mutex_is_locked(&chip->mutex));
+	zd_usb_clear(&chip->usb);
+	zd_rf_clear(&chip->rf);
+	mutex_destroy(&chip->mutex);
+	ZD_MEMCLEAR(chip, sizeof(*chip));
+}
+
+static int scnprint_mac_oui(struct zd_chip *chip, char *buffer, size_t size)
+{
+	u8 *addr = zd_chip_to_mac(chip)->hwaddr;
+	return scnprintf(buffer, size, "%02x-%02x-%02x",
+		         addr[0], addr[1], addr[2]);
+}
+
+/* Prints an identifier line, which will support debugging. */
+static int scnprint_id(struct zd_chip *chip, char *buffer, size_t size)
+{
+	int i = 0;
+
+	i = scnprintf(buffer, size, "zd1211%s chip ",
+		      zd_chip_is_zd1211b(chip) ? "b" : "");
+	i += zd_usb_scnprint_id(&chip->usb, buffer+i, size-i);
+	i += scnprintf(buffer+i, size-i, " ");
+	i += scnprint_mac_oui(chip, buffer+i, size-i);
+	i += scnprintf(buffer+i, size-i, " ");
+	i += zd_rf_scnprint_id(&chip->rf, buffer+i, size-i);
+	i += scnprintf(buffer+i, size-i, " pa%1x %c%c%c%c%c", chip->pa_type,
+		chip->patch_cck_gain ? 'g' : '-',
+		chip->patch_cr157 ? '7' : '-',
+		chip->patch_6m_band_edge ? '6' : '-',
+		chip->new_phy_layout ? 'N' : '-',
+		chip->al2230s_bit ? 'S' : '-');
+	return i;
+}
+
+static void print_id(struct zd_chip *chip)
+{
+	char buffer[80];
+
+	scnprint_id(chip, buffer, sizeof(buffer));
+	buffer[sizeof(buffer)-1] = 0;
+	dev_info(zd_chip_dev(chip), "%s\n", buffer);
+}
+
+static zd_addr_t inc_addr(zd_addr_t addr)
+{
+	u16 a = (u16)addr;
+	/* Control registers use byte addressing, but everything else uses word
+	 * addressing. */
+	if ((a & 0xf000) == CR_START)
+		a += 2;
+	else
+		a += 1;
+	return (zd_addr_t)a;
+}
+
+/* Read a variable number of 32-bit values. Parameter count is not allowed to
+ * exceed USB_MAX_IOREAD32_COUNT.
+ */
+int zd_ioread32v_locked(struct zd_chip *chip, u32 *values, const zd_addr_t *addr,
+		 unsigned int count)
+{
+	int r;
+	int i;
+	zd_addr_t *a16 = (zd_addr_t *)NULL;
+	u16 *v16;
+	unsigned int count16;
+
+	if (count > USB_MAX_IOREAD32_COUNT)
+		return -EINVAL;
+
+	/* Allocate a single memory block for values and addresses. */
+	count16 = 2*count;
+	a16 = (zd_addr_t *)kmalloc(count16 * (sizeof(zd_addr_t) + sizeof(u16)),
+		                   GFP_KERNEL);
+	if (!a16) {
+		dev_dbg_f(zd_chip_dev(chip),
+			  "error ENOMEM in allocation of a16\n");
+		r = -ENOMEM;
+		goto out;
+	}
+	v16 = (u16 *)(a16 + count16);
+
+	for (i = 0; i < count; i++) {
+		int j = 2*i;
+		/* We read the high word always first. */
+		a16[j] = inc_addr(addr[i]);
+		a16[j+1] = addr[i];
+	}
+
+	r = zd_ioread16v_locked(chip, v16, a16, count16);
+	if (r) {
+		dev_dbg_f(zd_chip_dev(chip),
+			  "error: zd_ioread16v_locked. Error number %d\n", r);
+		goto out;
+	}
+
+	for (i = 0; i < count; i++) {
+		int j = 2*i;
+		values[i] = (v16[j] << 16) | v16[j+1];
+	}
+
+out:
+	kfree((void *)a16);
+	return r;
+}
+
+int _zd_iowrite32v_locked(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs,
+	           unsigned int count)
+{
+	int i, j, r;
+	struct zd_ioreq16 *ioreqs16;
+	unsigned int count16;
+
+	ZD_ASSERT(mutex_is_locked(&chip->mutex));
+
+	if (count == 0)
+		return 0;
+	if (count > USB_MAX_IOWRITE32_COUNT)
+		return -EINVAL;
[...7628 lines suppressed...]
+	hash = mac->multicast_hash;
+	spin_unlock_irq(&mac->lock);
+
+	zd_chip_set_multicast_hash(&mac->chip, &hash);
+}
+
+static void zd_op_set_multicast_list(struct ieee80211_hw *hw,
+				      unsigned short dev_flags, int mc_count)
+{
+	struct zd_mc_hash hash;
+	struct zd_mac *mac = zd_hw_mac(hw);
+	unsigned long flags;
+
+	if ((dev_flags & (IFF_PROMISC|IFF_ALLMULTI)) ||
+	     has_monitor_interfaces(mac))
+	{
+		zd_mc_add_all(&hash);
+	} else {
+		struct dev_mc_list *mc = NULL;
+		void *tmp = NULL;
+
+		zd_mc_clear(&hash);
+		while ((mc = ieee80211_get_mc_list_item(hw, mc, &tmp))) {
+			dev_dbg_f(zd_mac_dev(mac), "mc addr " MAC_FMT "\n",
+				  MAC_ARG(mc->dmi_addr));
+			zd_mc_add_addr(&hash, mc->dmi_addr);
+		}
+	}
+
+	spin_lock_irqsave(&mac->lock, flags);
+	mac->multicast_hash = hash;
+	spin_unlock_irqrestore(&mac->lock, flags);
+	queue_work(zd_workqueue, &mac->set_multicast_hash_work);
+}
+
+static void set_rts_cts_work(struct work_struct *work)
+{
+	struct zd_mac *mac =
+		container_of(work, struct zd_mac, set_rts_cts_work);
+	unsigned long flags;
+	unsigned int short_preamble;
+
+	mutex_lock(&mac->chip.mutex);
+
+	spin_lock_irqsave(&mac->lock, flags);
+	mac->updating_rts_rate = 0;
+	short_preamble = mac->short_preamble;
+	spin_unlock_irqrestore(&mac->lock, flags);
+
+	zd_chip_set_rts_cts_rate_locked(&mac->chip, short_preamble);
+	mutex_unlock(&mac->chip.mutex);
+}
+
+static void zd_op_erp_ie_changed(struct ieee80211_hw *hw, u8 changes,
+				 int cts_protection, int preamble)
+{
+	struct zd_mac *mac = zd_hw_mac(hw);
+	unsigned long flags;
+
+	dev_dbg_f(zd_mac_dev(mac), "changes: %x\n", changes);
+
+	if (changes & IEEE80211_ERP_CHANGE_PREAMBLE) {
+		spin_lock_irqsave(&mac->lock, flags);
+		mac->short_preamble = !preamble;
+		if (!mac->updating_rts_rate) {
+			mac->updating_rts_rate = 1;
+			/* FIXME: should disable TX here, until work has
+			 * completed and RTS_CTS reg is updated */
+			queue_work(zd_workqueue, &mac->set_rts_cts_work);
+		}
+		spin_unlock_irqrestore(&mac->lock, flags);
+	}
+}
+
+static const struct ieee80211_ops zd_ops = {
+	.tx			= zd_op_tx,
+	.open			= zd_op_open,
+	.stop			= zd_op_stop,
+	.add_interface		= zd_op_add_interface,
+	.remove_interface	= zd_op_remove_interface,
+	.config			= zd_op_config,
+	.config_interface	= zd_op_config_interface,
+	.set_multicast_list	= zd_op_set_multicast_list,
+	.erp_ie_changed		= zd_op_erp_ie_changed,
+};
+
+struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf)
+{
+	struct zd_mac *mac;
+	struct ieee80211_hw *hw;
+	int i;
+
+	hw = ieee80211_alloc_hw(sizeof(struct zd_mac), &zd_ops);
+	if (!hw) {
+		dev_dbg_f(&intf->dev, "out of memory\n");
+		return NULL;
+	}
+
+	mac = zd_hw_mac(hw);
+
+	memset(mac, 0, sizeof(*mac));
+	spin_lock_init(&mac->lock);
+	mac->hw = hw;
+
+	mac->type = IEEE80211_IF_TYPE_MGMT;
+	mac->hwaddr = hw->wiphy->perm_addr;
+
+	memcpy(mac->channels, zd_channels, sizeof(zd_channels));
+	memcpy(mac->rates, zd_rates, sizeof(zd_rates));
+	mac->modes[0].mode = MODE_IEEE80211G;
+	mac->modes[0].num_rates = ARRAY_SIZE(zd_rates);
+	mac->modes[0].rates = mac->rates;
+	mac->modes[0].num_channels = ARRAY_SIZE(zd_channels);
+	mac->modes[0].channels = mac->channels;
+	mac->modes[1].mode = MODE_IEEE80211B;
+	mac->modes[1].num_rates = 4;
+	mac->modes[1].rates = mac->rates;
+	mac->modes[1].num_channels = ARRAY_SIZE(zd_channels);
+	mac->modes[1].channels = mac->channels;
+
+	hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
+		     IEEE80211_HW_DEFAULT_REG_DOMAIN_CONFIGURED;
+	hw->max_rssi = 100;
+	hw->max_signal = 100;
+
+	hw->queues = 1;
+	hw->extra_tx_headroom = sizeof(struct zd_ctrlset);
+
+	skb_queue_head_init(&mac->ack_wait_queue);
+
+	for (i = 0; i < 2; i++) {
+		if (ieee80211_register_hwmode(hw, &mac->modes[i])) {
+			dev_dbg_f(&intf->dev, "cannot register hwmode\n");
+			ieee80211_free_hw(hw);
+			return NULL;
+		}
+	}
+
+	zd_chip_init(&mac->chip, hw, intf);
+	housekeeping_init(mac);
+	INIT_WORK(&mac->set_multicast_hash_work, set_multicast_hash_handler);
+	INIT_WORK(&mac->set_rts_cts_work, set_rts_cts_work);
+
+	SET_IEEE80211_DEV(hw, &intf->dev);
+	return hw;
+}
+
+#define LINK_LED_WORK_DELAY HZ
+
+static void link_led_handler(struct work_struct *work)
+{
+	struct zd_mac *mac =
+		container_of(work, struct zd_mac, housekeeping.link_led_work.work);
+	struct zd_chip *chip = &mac->chip;
+	int is_associated;
+	int r;
+
+	spin_lock_irq(&mac->lock);
+	is_associated = mac->associated;
+	spin_unlock_irq(&mac->lock);
+
+	r = zd_chip_control_leds(chip,
+		                 is_associated ? LED_ASSOCIATED : LED_SCANNING);
+	if (r)
+		dev_err(zd_mac_dev(mac), "zd_chip_control_leds error %d\n", r);
+
+	queue_delayed_work(zd_workqueue, &mac->housekeeping.link_led_work,
+		           LINK_LED_WORK_DELAY);
+}
+
+static void housekeeping_init(struct zd_mac *mac)
+{
+	INIT_DELAYED_WORK(&mac->housekeeping.link_led_work, link_led_handler);
+}
+
+static void housekeeping_enable(struct zd_mac *mac)
+{
+	dev_dbg_f(zd_mac_dev(mac), "\n");
+	queue_delayed_work(zd_workqueue, &mac->housekeeping.link_led_work,
+			   0);
+}
+
+static void housekeeping_disable(struct zd_mac *mac)
+{
+	dev_dbg_f(zd_mac_dev(mac), "\n");
+	cancel_rearming_delayed_workqueue(zd_workqueue,
+		&mac->housekeeping.link_led_work);
+	zd_chip_control_leds(&mac->chip, LED_OFF);
+}
diff -up linux-2.6.22.noarch/drivers/net/wireless/Kconfig.orig linux-2.6.22.noarch/drivers/net/wireless/Kconfig
--- linux-2.6.22.noarch/drivers/net/wireless/Kconfig.orig	2007-09-27 09:59:49.000000000 -0400
+++ linux-2.6.22.noarch/drivers/net/wireless/Kconfig	2007-09-27 09:59:55.000000000 -0400
@@ -616,6 +616,7 @@ source "drivers/net/wireless/bcm43xx/Kco
 source "drivers/net/wireless/b43/Kconfig"
 source "drivers/net/wireless/b43legacy/Kconfig"
 source "drivers/net/wireless/zd1211rw/Kconfig"
+source "drivers/net/wireless/zd1211rw-mac80211/Kconfig"
 source "drivers/net/wireless/rt2x00/Kconfig"
 source "drivers/net/wireless/iwlwifi/Kconfig"
 


--- NEW FILE linux-2.6.21.7-xen-3.1.0.patch.bz2 ---
BZh91AY&SYT#z)æÉÿ€ÿÿýÿÿÿÿÿÿÿÿÿÿÿÿd
â€÷z¯{í®³ë·ÖS¾œí÷tô×¾Q¹÷®ïg›nÍjžú}ä¼[¯®z=gS}2Þ›aP ©UïŸ
:ÉôôQJ¼Àh wo§¢”¤@÷êžìÛ¸
TD½¼|àÞø>¢úùÃ[mmïB¾…µkfl÷5½UÍ}÷­Û¸ñc›TUgs<ùÓÛ]²›[Fûw­ÝÞÎííªïwaQ“h&»7}ï=O!öa±€(€

]5±ÎÏ^Ö›‘ñl|Ös5Q"8Æü+à	Ùé]ç½îñë=æúú•J¾÷×ÍU{éE'bŒ®6÷µÛÖ¶îárr×k“ۏA^ë[;ïçžÛ]u§Í²÷°óoiÜÐéÍíÚÞ±¶­5žÝv;r½kµ–uå"E%4õ®WCœÝ²Sr•s–·0¥·{uDìʆµx;™NË·XÛ–”•)#eèÞ‹-é´Û¶‡!î!ÜP:yu¬Öóë}Üy}Œ×ÝœÃ'¦ã}áóì_aÚÁZ=ÙO-éf… ö5²×é¹snìûã^·xo†>À>÷>ðøà{ßqЕ)£F‡ÐÑ÷³»3™ 
}»{܇£ï{Ÿ}­ÝÝA¾ùñ¹ôS³½7m®›‡¦A®^[=Ö]µ­ë´Ÿ^û̢퍅/£Ÿ{ÓÍy»Fìä[ÛÞÏVëvݾ¼=½ié×­	{·ª1yæâ6îÅ:'s»{cÓ uGJ-ïpl÷[m¸ºÆÌÍj
»ÕS^·Öew»jn{šJîöyíî½ïWµ2[¼uݽâîáïwglcuÛØåÞ­9
»gnם{®yÞéo¼ßÞ¾Þ}_m÷=ë³—nÇnªÎívÓ}ì÷™u;¹Î’ÓèÎô6æ“»nã»n‘³™­eÁÀÍÝYSwaZµ;wps»¹öÞÛ=õáÑÞÛ·ZÍ©$ª‡Û@½:sjö=n³]®‹9Ã¥ÝÝÕÝvÖsf]»µ–îèÜ­ÙÏ^ó{—‡Þ`WCZ 0öÉÞÁÊ”
5 
4 at M

zžTöTüŸ©é4'¤Þ”z˜j4$ € h
¨ÓGýê|Çþ3×øàþÄGTÐ
ëÆÒš¨€©–e¸f¯îýÚ
­ÄɈb"
J¢"¡`Š¢’!ˆJ¢ ‚i˜’b
*©¢
UÐ/Ò¨˜ä…”ÄTÇùrpSŽO–p< ™¤ûÑ¥‚‚X&bh ™¦&‰©‚!ªI(˜öاûê{M5ÒÜáç©%4s*Eq1A5Þèç01¬¾K£
)á·nÐIˆX„+
A#­#HTa¡¢@Ùá”ÈtÀùÎ@t‡u\‡‹0œƒA¿}4ÒˆO,Gÿ¸GõÑ÷TPA)üTPUöý€ý¿ÿ.>ÜÚÿ§üÒÿ´OþñíH~r„o}µ÷|µÚ?û$„!~¬vc­„#¶ðÓs°Â›OëNfçKÿðвt]C §ÿ±·WpAWþ•ùì‡ÿ”ke9Æ€¡¤¡
áO­ÿÌú{ã_í#/ŽÉSb(nØ•,Û`’ýZ¢Ö÷”3 
 Ý÷ÿÃ0T6Á*ž;`
?d¥)B…)ÿõ$‘t­#B?¢5RÒ¥*Ä#ß
mÂ*• †&–¢ŠJ *¼`ÔSI0E5 5EUˆÍ
1QDDIDQ	I
ý¿#AÌGÐÆ ¢ <U%¡Ðé"ÐLÌ$EA°è*6tQE,BDã#„ù#™Õà„sš‰j“™ÅGãÅhˆbÿËö|7ä@ùBz¿û^éôÃÑ”)Î?å‰ÿõE\ ³ß®1¼úï]»^	^Q†øn“ì³Qäj!/3’&™*I£÷åÅ0ýàl'²\4ž¼Àš’Z
XŒ¬FØZUÛ9óêõÚøû¸Ôûbhæh¤€Ÿª_ÿp^9…À6å|HTU=ÿüÔäx¨ÇïpÑÿË”TDDUaÌAÿ|f

R˜ŠƒLnᕯ(Æ
ë&èVqŠcli?¦ò˜V+øy0[ß®óñþÕéQÿÜÄÃB õ°{Åž¿H`6š”¨EÚ¡@Ò¾Ò‰¶û·ŸkÂ	޼̑-z¢DZík±U†%‡˜­Õîpš¨{ô0¿Ü*·@~ç©Åʺúù
àlÅ
z‹’«8Œíµ—â¡@$œR{2ײ@TI$£Ù9wÓÆbŠ¨CŽ¶lND]ä^³ÛZ@Òw2cÿãþŒv¨#¿úT«Ö6—î¤} ÿúô¹=Á=–è7_Nòâcúò1çÚãÜa,CHQTU4ÿÄ„™¢Õ¢M ‡4hÄ3_ØŸòíIýÓ.ˆÇÃQ¸b˜8QYAø½¢‚ˆˆˆ„ˆcë‡EIJÔTUKL± ´„EÕ¾\B!(Õ
EQ7Ê1B‡bš5AÓSÛ4“ˆHD6
4.šitèJJ ý¤(hb"9HDb+I ÄU at B‘;h’šhi¢ª&¨ˆªŠªe¤¤&¢Šð”Ê’¨)(h5&T…$KAv‰Š¢
Š ªXe(*!$™j©Š4™˜¦"¢„¥Š©&	ªb‰¡"¦‚ †Œ¬Õ$EE
ýy¡uMDBUPÑSQÍcHÄ´$1!CC at R%QLJèÉ!Î6h Ä†„ÔLCTS)	”$HQÑ­ï)ŽY¤‰¢Š„¤Š[Á4TQ!A[:ª$ ƒjMAIT…%EX€Ä…4Ðbh(ÐT_ù–˜¤¤ý2šN’è"¢&ˆ•Òèjj&*’©
˜§F¢"ª&4a¢BXª ˆ˜¡“T””ÕW›Q at QD@1¥MQ1hÖ³M4ALŶš Äæ"]dÒÒÐÒpm
STPM ¶Ð+‰9¸G˜A·?UXÚ!G‘˜J¡ÐDâ`˜”q:i	„(ˆR%€¢†lIÈÉ@Fp8DªA4h¼Âi(£•.‚™*RŠ
Z‰1iJ™¨"˜(Ó£âs%D¼„Ä$U,MS'ÎÕ
!È
‡BÄ4¾I‰ˆOßø3sy°E;›€HDEÌ8
‚O'†Àr£“M¡ij‘¡¡ ª¦-Sˆˆ)q²TÑI%UJRSHPE‘J”ìD¡”BRT€+&,%™iÓ'ÇŸ¦8zMćçö«LÏs	¶–
Û·7yxö*<ù?k À8T"Oæüäŵ=#(ýIŒ*⹜Zý˜‰yþß'71û°q7½,„¹Å,wÀBE:yrsÇþ°m²a¢ºíZ¼ºÜáõsÇAúþ£ZƒÄ°*h*
†…šI¢%©š
Œºa,mUES$IQ%+T±ÞñåÔC24”Â3E?ýøÑIÉM³ª”i’*™¨(˜
›& ”˜˜*ÇyÈ ™âLã`5-
,À¬IHPÓHFÂGAˆ(

N‚`¤¢j¦‚ +BÛ
*
ªhК­5¢šÛMii
§1Mh41!ÐSE…4ÐQBRU
¡M%LhÄÑBÒPBL¡M
PÅQTR±¢¦–•h)¤¦‚œc†@ Ãþ)P’ļ#¾¼Ž>7mvw9Á9<ÑÞçóG’ü…Ÿ!1ø¡™¸Ù)•µÇúsPêÕ­fˆùZaÑå¶}\
‰àÊE}ÿ«¯DDÄ×K‰‚:O¢¨xü^ºœ?­œaÈVÒŒmµ*Ïóþ˜‰ý¿N·ù½üb¬£Ö‰X¯¶€¾‰rC*}·,Bg\'düwýÌ›¶KÈÄH{
ª!‚.çU|!üЯ¯€dþßwO`b†Ë
™yæÌ—!
é˜ÍRB
§³á}=swzóG		(ðŒføý½ƒÂ(ª/Ïh&h(¢J&H’$ÛQUTÕRDÅLÍkÛ´œ0–ösSD×â3Šˆ’.FÏ—âÌhm·õÀƒcü²
ú4¹t/6Œcn™15TE,fÉ<góy{ü!¦6½ðèÆêØÔaÅ-©¨2tÕ×]`ÆÐųøO#Çû#™¹€Çó¹ÜÓ²ÿÒý¤rÿ“¸%¡M\|;AÞï2`e;&A¿±¥€Š0öРøoVúÎ*ïI¢t/«îÑNŸ""»õùà#CsÂø_ÓýqÒ]î¹ÿ«•š#åuÛ÷`aGöb:µíõ„zí€ÿ'?¶‹JþÙÙ».ˆ÷OæaîaýÄ· ¾¶¶},ï¿m‰fÑûÂ'LZýü ~Ãy‘=·¸Ø=Uuz°Æ¢&hŽÿ^sjŒrFM@úàîÌ‹ÂèFñˆNI˜…˜ÚósÃ«CéžDTO	9Ë×+×pÛ9ë
d¢
ýà®jAB¡ð—š‚èì’<€‚U{Tÿ{Ó0Ôÿô€ûeá_׉¼I ö‰£î=AýaâKè!$S߈a
 †ªP2C	ðááü—™<aÿǶá_‚\b4s] ׫=WpIÃÁçHáF@($h‘&VˆglRÕPÔAÞ†
QРÀ‚"b(¿§õ}ù§×?ü~ʽʦ#ÝD‘V	>Y¦LBRƒBˆ€È){'û:x'ÏÛŸåðÄ“L%M욎ªÌ!µµiÐÏîà¬ÀLŸJˆ"Gí‘ÀQD{€öÑ	Â"€÷€8Bl`("aÐ&Û„’=D÷”œŠAëÀÈ…E4A4µ%1A$´
A0
%4I52P`0©‹pƘªˆ)<µ$$µÒîNr¢N&¨!€)/¯Á"51ìD%0¥Fª=\ å’6°P&¨ÆÂ*`d© ¨¡€ѱ(RRP0’Œ­«*1EÿÌ™*—ͪF;?›¸{#-Dí¢†šf&CÜɘJìd4œ¹Ê(¢P4™î¦9Ru#Æ$CÄEó~ÞyÃ0ÛÜðh("(
)™ic@\ŽQ¢f|ìl™äbŠ$„9SQW•a¿Œ,ÀAì˜!ª¡ò
I…ª¯1±:ØÑ4ëT†ºA°©¨ª –¢*h&qd¢a‚únLãNÔTÌŸ
DîðàT¡M1+3Q1FÛõZj&ª©æÀ‘³ª)ª(š$"’7oĤQDADLMPT„QRwi¨’"
ŠR
Šª…¼h$"‰†Ú!óx(¾½Ë¨ˆ‰£†Hª &(ª]¶—c?Iá-C2DA)RA3Ë5ƝPA[7y¹ˆˆ&&¡¢bª¸msXûy£¹1IQ£KJ¥_vße¯H¸"ˆðƒ>ñ˜ý>nçPd‚&"(¦­`(ØÂMA%ÉTÐÍKBDŤ5IED±!@L1±mEIØÒÓTMÌè(¢¨™¡"©¢b`* ˜#G9šª¨æqkR2M	@TÉE5LMh2Á¤ÐEE$Á$Q.Φˆ ¤¡¢"¦‚š"-b¥¶AmF)¡'lELQD•!¡Ðá—ÑLÁΨH‰‰™!J˜ª¢X$’
*)ˆ(­h©‰¢(‰ ¦
œITÐM:pÔÚ$TTÄPMTM&6bM‘ÀPÁÀK!³1MÍhÌDZr±bÄÉmš
Fd§Ïôc‘ݪ‚cçm‘ÂHL1T5PLò
t¬HU
Eҁƒe4†€q[
10¥
­j‚$™i5l#‚‰5^¹„ ¹4ÒëAÿÊ4ÀI0LA76g "
§IŠDä„s‡F€"Rˆ’b!І6
A4°Ñ¡¢%Ú“!B±1ETTÄA’a+I“Ïá—Ë}	Êpð 
&b¡NF“Jžˆ}Ãäyri
VŠZBšÿy*ž“±’¦‚©h+o‘hÿ'ý5ÿ×÷Gêßžü¢¢¤¤Œ0˜€Éiýá9ŸÓµMLÌÏc_f×1ªJ&o2
‚¨‰ãöpSGÑšš)þ¬æßõyúºxIÿ7;뿆õ5A4S1ñ‡BW™5G"¸\¹µD•!T;½ÇHª"(H’#™ÏÎç5QAÔ"`†
Š‘¸À`Ò5HyÍÓ˜¹˜&˜®í]Î1‚’"`’&•yrá­QEÄÑDÔW6ˆ¤*)b¡bh ¢y±SQP(BLÃ1FØ#mD„´¥–¿=;†y¬;ËÕ+W®ð?ÅÜ$TÄžJ¦€]+sRb7ßëõ–±kcEŽ=(i0Ý¿å…Ö¥^ÖèÄÄÆÁ6Ó&g®ã1š„•’*ŸØcG¢MFŒè
E2_!ˆÃ™ŠÄcé˨j‰ª<C12“$”iÐT),R2…*V4˜TÄ4À)Œ®‚d¥¨)jF"
& b¤‚F($ˆH‚b
$ah¦A”"˜’’ª bXˆˆJ!’Q‰p9Sh}1kÆa!ûi´Ô87Pzõª‚i>aƒPPPHUµS’˜üc¸ÉÈ('åe€¨áQQ2
!l›@`	e‚a¢"OÁŒ—ò@|y‡±Br
&f
4Ð'œú‡{˼ƒI¬‡TMAKD¡Hh´ÄÓ.ïÄ5T•1
„@CQ¡4ºQÌ!I˜ÔHÐe -¢…(‰„¤I$ˆJNq¨'«?ž440ÉA4 at QìÓ â~ÿGDKÎJm©Æ=ú»Àˆ’ ¹:ˆª&»‰Š("Cš™§9Î6¤
]§ùË€90Os¨(m…B“Fƒ@è‰FŒ”Ì.´-ËIŒdJ­h)ØM~ó˜`¤6ÅU±©©fX“@hi"CNš"
(i¢šHµ¢’gß9¹–¨»))Š–bZba™¦’)( ˜¡*J†‚{µAAWì“DpÎ!¨¬Iˆ òÏÓù¸ <'Md&A®ÏÙ±´PPAï½3¢¡ˆ¨†ªŠ¢!¨šB)fŽa(q‚—²èƒë4	”ÐR•8T]™ÄâLMdÃJ
JÒ%
!é]ÿþ±ÿ|Z9(‘¨}+9]ŽèÀ¨y!UL£Ýñ/Úl¥jJ/ÜÁÐQ¨ÃÕ‚åرòm3”ÿl Õ-gddíO\:e8˜Iƒ!/*CÝ&(ƒm?l<‰ÌgÓö›ˆÔ¨£QPBxi6¸‡˜n!ND%ü\"–ôÏòf"™iû^qBïg›]¼W:óÆýóÏÓ¢×Rõ‰bU70äîwŠ‹ÜB»™mú5zäÿÄÿ?œ,ëÿÞûwçEÈ+Õ‡Tá9¬ N®íȸ6²×wÛúùס^`^à£çz£ýp—|vÕFŠ8Eê>ßÓíú—£=cgðõ°Öþ‹áÇÞ¶Ð41ü¶©?xoÙßLB“±›ûTüFû2ôÁ`.0låx»ÖÏ!±¦©ú®\	yÍï¹íAC¢5Ü­@GÎ>,žóSfÒ-ðTOر	é5ó*PȍQ„׶?³U_§³yÿÕã”}Ö©[o
>¢>úÙÂì`»³Å‰*ªFò*m-¸sUO{ãWƒQT1i]a~íÝ4Àß5˜5	󵄃d
¬Í5#5êëÿâJB6y.Óvft2üœê•H:”vÔæ{ÜųàöºÛ6áá	->„Êt‰žlÇ•¸¡ðˆI‡X—P’:þŒÔ¯ÔæÕâ²õFÞZ›‚\U‡Z©ýÕ.ŒÔ3Æž:·~®óèøGíÍ7òY6Ö-Zõ¹Ý%u_&oî…f¸»ß§xÞ5mdøû¾	Pè]¥/msüž.é}ÿìíU],þ6Z„éƒf˜O):LA@®W²×¿P`¶¤Dé];¿¤¿=BPT§r‡?Ñê	#Åí—C=“+mëÊÕ6ꏮ—ÒÓ^*øF<ÃOÈ”E<žóÎáˆ)(î6ûÏ©iÏÎØzçýìò‡eŒø{[3½ñtT
j§2²8*ý'½–d”[•‹Q•µÚ—·÷<¬ƒco–GbŒMŠ81›ëüWqÞ¾—Wͯm¼‘ÌŸèraì)n…ªƒÅ”({lϧcôó­}pa‚þ¬Ñ_Öõñµww¨I@	q÷”DCÞ´Ú®k6„qS8ˆ—gØÂþ¥ÁSCvZ”>²‚%…ˆ*Ÿo¨6i/uoç­gîžH³îˆÄÔa5'wŸ+Ÿêýž¼ö®6Êt²–©°¾.Ø!îˆWݯÇÙÌ´›(£ìª¼™”ý#ymþÿ›;gÐ5™ø3Ս¦Þ¤di°¤ü_ýk!ˆ$îÃ‚4»

b”ƒOùՁ†YcPÓXpqÙûÉX3M“pç(°Z"…V~:\:iÚ>ERQ$º'b”ÈN;¥–!úd­ëDó¤mêÍxchz—ځTÇNš–6Vn4Îípü¬P‘´ÌT<J~¤ƒ3ñ6GUîß!ȃ¨È¸§ùâZ>~¸D<bY~Ãì÷9qù>ž¿›æù½ùìãá¨.~0/Á#qëÌŒfê… a<³9ª’IgpÄn\ÿ‘Í£àË:?Óï	#]å¬C„ÿù±ÆZLÞf}¥×ÌA9Å-áöScH®³daE
ZÈ;*¤švÒg¥uø^ìƒþÝ?Ì¿bËÿëøó/3ßÏz퐥‚âæiòÁ¨˜pÓߧ&Ý{-G›ÖZÿ¢ÊwãÒžž8\ õ†OÝáƝ5¡ÈV$Û@Ùía¯½OÃõ˜jFÈ܁GwaéÉZ×çþ¥5½Æîá'/pã¬J‘çâùÚátŠy>ƒñ:ÊÔò×bï{¦(8ä÷¿pƒ¿\)ˆîÙXþrCåč=ÑEaµ‡È>pÒQßÍ88Þ‰ÕæÆw³¦PÓOôÔŽ™
=‰²2DîóÖ/7ŒR§áCb^ÕÔ˸ÜÓ8&@îáR[†5£øæYxR[
äY’ŽŽY[þþÚÉŽCY*…rXÞÈ¥®v$Ö#5‚1<\–MÁøŒYz…·KµwĹx\“Y	úÈ]äw™(æ8xŽÚq9©â±sŒÀ!g9Ç ˆ'Qtt£âUF1°Öö‰™<KÎ*TÙNf‹²j˜µÛ»¼™¿Y¼N¬"b£AXŦºâ kEÒèÁ¦CÄÏNùëôf&²û“m):KnÐF”!$ GX*ðîÅ«u´i%4!ÇI;Êw<P^&
 ûxtŠµ²ª=1óNi,o>@@U€`H	öŠÑRåà¸=ÈÍš#ÅÏb9šÿ¡À
m·ÂÍp‰z§”¥DÅL†dĎܳiÐÀxó0ìãÀÑËz`@ØÐ7 ˜æeb¤#grŽéøºÑ”ì<ë4„1Œ„6ší/â¬[Œù™z5ËÓW'ÕÕ3¶ã_›v.”™bŒ­¾ï‹1„$¬&‹v7”Âå™™H»E4Ö؃–=½UÌåÎ8öìZé•6<#:á£F©M)$Š6¢§u.n«›~øaA°ðõÁšyYÙòÖô7
2HI—Ʀ.±Šg$Ãn
·³+wÃŽŒŒ7â¾w&áôùÅ_?LÛãN;i;f'ŠG…-‰xyß´½8œó¥c`Zé¦\z³O!ùdMðL`~Ç"dƒáçPNPÉÓ¤–ñÞ™ªÓÙBg´æ–Vo3od¨Îô…5BQÉƵ¦ôðš‹©¾7¦Î‘Aœ¶Ûøæ§HƒiÜf](A>Î]CCl)„•©¶6½¼mŃi Š–óìÇÊNO­ñÏÝ÷‹±£Íª#›T6Æ/!­³Ž6k—–·²(Êšpïc
Œ&ý7XxÔ{È5Ú"¹×)®þ’˜kŠNfH95’'å-a„ðûèâM<û.÷ÑÖöî¡–A ŒÑÙühmtz,HßðM¹rJ†áSªŠR9X‹%vˆ.`·ÝœkfŒ&@Þ8s«`ÍB¿Q%dÇ0—fQ¦iôzhÁ¬§ëë­4ülª¶Çc›¦²-1±d›mýOƒ8V퍅{a“¬(\ÜÁ!´‘œ$¯>‚}X(˜€Ë¹WÚëÎj’ußóG
q\.<›âЯ¡LÄ`ìèM6ø[^ì÷†Ð&#o±f•9A¤šuÙ+Ò™vü¡Ò®í®4ã…Î2ƒbWË|?&A"B€
R€¤¡Ñ¶ßâ@'Œ-Õ>o/Ó`úa¶p› Z!†ÐÄ8ùŠö³áÃý3X»x5*îfݹ@y@ÙÄAqcÈös 0†¾A¥Œ­Ký]§œ<Æ ºù `„
 ÔH«¤ßµ¾õÕnP°˜_J¡o^®>L2xp"ûWäá%½ê ¼Þ
Üb]1<jƒTNfó¸Ô1R‘)‰‘F!;HGÀ…ƒÙ¡Eÿ,w^¢ÿõõFr¦,l.:\>;œ"$¨Š@(Pè!D^ås•L¥#„êC$õÂêJR}˜ßÕ;Ht(be„Edá4PÕ.øànGWCË·‡óA˜ûâßÍBÓ5PpXкb¥Ö@Å×0ß0‹B0ÁfFi¤^ev‹§<ËŸS¹å^à÷÷b	ÄÐêß’äóçÒ}õÿ8ÆÖ‡ÚÄ—
lìx#øà¿$xã®F‹ïBÿ”òœNŠÓx¦Zµ#™\*\°ªÔºGðFËÿ­wƒ‹e1—9ráG:•2%瓲¦³‰±“Ö—%1ïZÓ¶#Ëð£UÎ3—Ë%dª%Xmîji鈖éÿ{–tŽVOž,/Xè¨CJ›·ÂUÕÇ׌ÝÄØdþèn½¿ÑzËi¨ÈwY«#ºÅôfQóŽP·õÀmCý[²Ò}›,™Ã(lƒÝ«k}“—øò°lƒÍ‹æœ —Žè^b^HGë%à[È£Ô@‡¼\¡êT‘QN‹È6rõcÿÆ0êí®(ŸG©âñéˆ;¯Šµr÷cH†)püY"EHMiiÌÜ>a:%
®™½ª­I׎ÀPžü3ñó
2I'@óCccozHéûúݧnmFç}«|PÑ	ð¨jùW¯c64†‚øù(Û²lâ÷©š“R°–æøiª0-›yåRÙ%Šr‡ê§j¿@œ*p«°ôÛCc|/›ÎS”«„­^º9ø¨´˜.8ÛOŒDE¥”
ªÊ>–Ĺ^÷bÏ-{¢¨ÆùM˜ØËmF‡û5ícZ~J ÕL‚"Ë]­83W5X³¨n)i¡~ª„Ís[wº­´hª¶dT”Øje0®æ¹î Ê×;—ÄÔ¯’ÛE‰œ¥Ôµó~dê¹9Ǥ¦È(úÍÔI¥¦ßOdÉìR¯ æ«äÖ^™Ô½É.êE„ˆGWbû‘AÎ4Z	"0…çò½'×;cÂ=q¾ÿ
«
l ?t1姗³Ç#²
G‡ûo{Ô®ŠÐuÒ\Gzð…ô=GËêÜ»1MãÖ¥¥þøIð)§pü"rÿÅ`Á§µ=¼¦
+7©¥g×Z´l}P=VÖçýÜ~q³ç`³7',pÆ{\Éîθ
m¹Yä.Üf®og;mÕíAEþV%ΣúÉÌ‘óð¯S÷ã	:7ŒwlËL\ÐÂÄŒÛ[¸Áeƺƒ\w×Ë&\Œ°ËÇš9
õŸ?øʾ^‘Zq³åÿAÍ~Ûô:Z¶.ñ³uúñªünã=	éÛÓ¯ñ_pÀŽò:ms|¡CvlÖ½³F]œZ®6ÑÞ\û–pWaáÉvhÓQO¯ºÑ.U¤)Û‚ƒb
Éï#Yƶmγ^Ü_µ`[€c£éš:ı*@Û;m—-:è¨@x#e°d0Ð.Æ9žOߺ”D¼}‚€îåƒ=úߤÔ6Y.Ë«“¸õ{Ï#ö}ãúfV¢ B‚	Z
ŠÈC¥ÓùŒTâÍ h÷{Ïã}€~ð÷l!€õªx\ëÂÛ˜T”/°Qú@ˆ˜#TôVÑ}Ó·qÝRþ‘]Ë
’©åÉ, VåÀ
¶ìᛜƒ¸Ê{'‹¨Þ^ʝc5qÚƒ¬gv¬'›Ujƒ³´*0w¯LôölE¼í~«ÅVÏš;/Is¦†SfG}2©fªkN·„RI83­ï«®<½Ôs聠_éD$+¶dOiSó÷Ÿu»r¶Øà€þ¨ÁÙg‹ú2Œ£FšÈ&^¿ƒÓ˜Z'Ýíÿüµìò»ß³›ë1ÊÓqÂvuœw[
Uwö ñöbOâ¡ã×Aã
P³N‡Ä\C³P4`E”N1•Ï™…FcO™YšËÖÓ0m‰î<=6ÃleaÀ{}¼ê4Þ;­×I}ÙŸ³ŽÒÇAÑ(ñ:ú-gá™ðœ!!D(€±*bŽ[ðÃÓŸ'Š˜G#J̃b	bYod­ç´v¿éƒ¬a
Îð=œ<É] ðŽT„QEQEƣƂ!›oíÄ0èC:_‹—ÃÒ÷ú?ǏÕ>VdddC®Îå€]>ïmúªA½ŸwL~ï¦ñ'(º¤/fAãâI‘
¥V«¬E'  UUf]ć<X»ÑðÐS=“a¾ü÷ÏÅÍ©èu.…G”çhúÃâv;£ºÜˆ$
¾ŸlG„j¢*¬¸àd­mÀ|Ïst¹á½ÀÁ³ë…9‹m"¶ÁëzdÁ,0•ò(u[YÑÒ3=ý_Ç;Ÿ›œ÷cG¹‡˜fI?f[>Äx³íîœ-ß´ˆë2Il;ËXÛÛm?ÜÂQ’'=d÷3ׄÅ_nús΂°m¢6Š>È9çk¼ñ†9"ÈGÞ2í;˜¿vþ}œ2é’pŸÍõühV´qõõ!z´ÆL¸ò&›	\<ò1¶ÝP&F,W^Û…Šš)O‡ƒ>^Æ]›Z,m¶ì¬£oÛuÊŠÂ֝¼ÜÖ׫•×ðnxU‹S¹º¤0ŒïJÇóXµ‘é6N•³âühÁ‰ØŸÝ¸ßÿf¡™W¦vaSZ¬žR<M½È2‡›Ž©¸TÍu¤zAf§‰5‘F7ÒÃÓ¬Y¸÷Œ*kɉcs¬§¬†aŹÒJmÆ­­ÞsÅÃJrBœZæIY–ÒÍÂ-7;ºÊ¢’<²ÇŒƒ^¿€YÕ÷yÇd!hÂ÷H]=F1MHÃDŠX8lNº|óü—Ò{ bÓ챃UDÉoøÆ‚&¹2ސ‚aO¼po^›”iY‚ŒÛ+’Ó¾#¡¢¼ãDÜn
c‰%Œhg©…=ïWÒìÈÏOÍ›4ÅÔh‰ˆØÜžz# üa°ûþczêé&	’dŠIˆfª(¢O/–:™™ƒðmZ>Û”M/3“gLµ±z؃›-E4Ñ}0ã– J *¨("h««îµç¹ˆoAÀlëe‘“Ö±¸ÑÕ”mÐvlžçð†Žz‡|ÞLLq_Ç£ËïóCðª~
*QTDøà=}o‚Š·Pþ„]~¶Ã…LâQß‹¬¿FrºÕ´óè—ªæÈi1’|Î|aáøóÞϧKtþhé²7­cÀïU~%ì^¡é<óÓ=ØÔ*N^¹‹-IŒPò/~Ùª~00vf@‹k¿ÓI¼Ó2ôËß/YG0j(Ok*R鲏z¡éYÁfªï{"òI$äBÅO1«…{mqlÇ4Eø€iÛ
°M¨öI¸úM~\Ò7ã+Fª§Ïß×ùvn!ª.\ùZqµbF¦ÚÑ«1ËmhÔ…*)
¦ŒÁ‰@õ}Ö^Á‡‡ÓŽ#\†¼-ѝ7U‰®53ޱㅁœós4‡ë{[lQÝË—šï«ìêÿ,t¨käÃiê,C¯nHs¿~Áߎý5ԏú„aÒWœLãó˜¿Z‹À†"惑êåO“õB¸Á½
¡íkœ†vVõ%éËsY-ÆéâÉmÔ
a‰ÁŽóf•ÆÍ'Ô()ÑrgÂ<Ѻ®s^v°u\ügˆˆù‚êÛùÚ:Øy«R(æ7ûäÆZÎ@Ò˜.9+*Ï!fž½Í_Ï[på2,wà»D¡¼Ih`á7z ï?–ܺ~]nôù¯½ñÓ{ÎŒÜù;PÏ&ŸÜéõ#
Q„’}|P’I@@S6U_™b
:ˆ
dRâ>•wÇDÅ4Î.%G•_r(–I[¤;€¿_Œ1L–<ª~ÝÖ>¯{ùë¾=gg¶¯Ñ«¾6…I?£¾(¦©çcÃw:öß)'òIý°öÈT”BÝ‹xÚm2RWÃ/}UF܆ʐu1§<ÐÔž¿=L3öD*z¡X(H7sBNòƒCâ½â»·sb×{üþy%#UAQå“Ÿ2!ï.šŒLLcå×ó9£5Æ5Y³öÚÿ|ŧ=þR·²@~ï$CBލ•°Ü4rÑÕYª;4µé•î`{|¨à
:3­ÐØÑq¼àf/z©¾ŒÄ’⦮…pòsÚ*Ê]Ààöîè|žlŠqvÌ	Jö¨g**Š
êЛÕuÄ™å5šmŽ(H ôJí±¶RcášÞÊäm60™8¶×$+¦ÜL“R¦š¯uF›²Â6UÓ‰G&ÈÙÃÁ É8a¬yÍF3N>ƒhÅë›”ýÁï g}­Q6›CK¬Q®qùGºŸë㜙Ä^yC÷±¶Þ×ú­=ÑUëB1µ¾W‹ò@
‡ÝÄmwœb²Ö$È­6?gAhxÕêÛêrÞ!ÐÃpa¼û‡Ëçöp{=ä­*?ª9ñÏ}M’=8R	¦ÛFˆyoÀpC–µ£$ÄþI4p"rú–;åð{û¯EMÇàBr"¢ð¤$Hd1ÌPm½HÂ{èÁ誒$Dæ@&ãÝmË,ïïF’Š‚¢áÇ–Š*hüX1?nÇÙŒ‘ú­1¯¢ +õæQÃLÃïD2LД${:õü<>ß·á°vøg/]SE!•›ƒ`X‡ÆæïåH(
<ÚE¾R•þñœWÙðÏ·ÁîÑÚÊHðøoŸ
ÑáGÝÛ-‚ÑÔ›Cq¸¨
Á‡µG6ïºÇknœŠRœHqr…T”@âA1£±‹õlÉ'?íëتª=.#ÖãæšJ–"˜‰ƒ¾Î½=]åì»òcQT>ð⪪?xfEPLDÍILÅTRoMQ¼™yÙpžèÔµE
CLÁDòŒ)¦•0#üLñÑpÍ?aöÛƒ„coˆ©qDÑk„ÆG%US†ŸrÌs“­40i«0°™iÉ$lcôñkL1‘¦	ýS|zZß.›˜*[¸ÄåË}"FèÃMmÝèí)å¬.û€ÕZZP:ûp‰~5nÔÙòªÊŒg¤@ëÒ¾g´ÑIšÅ)i¶2áÇ»†Šüù“©r(M)A¤™®Øó&ä€ &Rƒ²¶š¤


J{#¡¡"¡)
’‘®©rFÀŸŠ.ìƼššƒpj8{ ™…Ü$€h¯œrD~nõ<‘>E
[kõ³ÊÍ4|KŸÃQÃ`ºH÷Æ£þÇ„$”»ø!µ‰„šV”¢iÅh˜ûgãær4åÔäF
ft…ØÕ%²~ìr¡>R¨B…¡) ì´¡¨ˆ€{9%hSÑ"j8Á’ÑI¼;AªŠRƒ‘¢‚jI§âÁ:8¹%ç™-1¼:ýS…FðS”B	 :Õë6Ãîfÿ™×JÄôY%
äÖ›çÍà•¨+ʽ½Ï“´>$Kšj<€­Û/ö³“¯ñUÌ8¤Ÿ¯ªcä«ÇáFäüˆB4ŒEªuí"gãíX°NA¶sT¾D¹aCÕRt}—è´J»›Kõôì„E–\kr0ZH<6Õ³£{d‘¾:g·
RFhhðnÔm3uÝ·5éãŠgI'4‰´ôCÄ•éÙ%„wZù2ä1¶rH¶Í?ÿNÍòs	'ögA×çâ¶Îœã¾V=Cž%ÉŒ‘Áõ'ZE$o)‡I­?Å¿éÍpې8¡Û‰¤º¸H›‰¦ì”|^$þyþ¾úfäõ/!Ä~–*m*ƒä±!ïP+=?j¢mõíiÚ€i-QA¼¢1­T»b‘/Ûªo!4
V©õTÎ'³èê£ÌH?º‚ýX8€ê¬e³‹Ä	"P
—’øÿAì¹4Vµ.¡r‰büöOwD		”Ûó3
Fò~ILg'ÔÌþ,.œ‚c>ìéòŸðøHO’B^Õþ¿wǵ^Nó(-2ô€%%“ý2°£2­F›ðx3LsŸÅ¸puFƒE1ê5þû“h½Øiî(¸±§o‚ž†±“d#Lldkä2ñ5c|ÛÏû!¡6¹dÝrÏÑƪ?SŒf ž86þˆ±ÔÃCL?Aü·å–Q²yՍf»ùuš×ðáGbo…eÿÜq†!ƒbP`ú¾­[Åç	ÕË"Æd ë
\ ¶øäyA·Ãœ
£ÉåÍŸ¬‡hò¬$ >ÕßæïÊʱUQ¨Pù¡³SÀ—pˆd¨æÐ$QèŠãʵöU÷}°zü6}ué?o‚þ¸hßÉÍ=Ùý0 F‡ÆÌ×og­Ò$O7‚vaí^3Àýg»…袉éé#>Çv”én:±ƒÜ b
Ïßúžü5nZHfR¨)&åO
m`A­1qôErH FŽ·ë*=’hkë×j’Œl8z}™åùgëԁ¯
D0!ˆ[†äÃÍCsýYoËÅjmw8 y÷+Í©ÏÒ7ÉTò¢ïOkÇN=™Ú/Ã1
¿	LBZc:vp•k©ë;Y^LMj¨®MʼÙljlÏkçuª$q- >ü^»´PSÛ:Å›`4YU€‹îÜç%D	̹ý—ÅñÁÖÿƒÓ*ÏÕõ-À#ÎzmÅáÛ' 3ÅË„¥ŸÑ?á£QŒ$Õa›‘ôñŽ¸E„¥ÂŽÞdïðcã)rÌN÷;}|þ·K-uu-ÿèuãV!›7ðx]¤¥#Ûæ¸÷ñ¨F¯oÌTCõŸ†ŸØ
ÓÍU£‹ÁÙ:¤·H	V¿»úY±ï¯¾å®å¶Ò0ì¹gsò|›:IÁ,Pâ‹ÈI§ïm"¾šFÔ¬ÞB•;MÿܱAöx}­«­Ÿ±@%5dÞZÖÖU=&Â"Ð~Õ{ÈÚR³‰gâFâ‰yAß}™ÚÕf×T)4*>úIÔ L¥ä%–ª0)• çZ (Bw•¬9·Ö­1[
tk/Vu‘ã<`qÓ¦Ç8iôÒs·«FCG掽ó—5{ç'Ãl®Ÿ–5^1ðƒáP
‡›ÀT?¿oËõzç//Ä­º¿ YztŒ†yÏê9Ò¡g¸(¬QÁ‚”F“Ö,¤Íµ}Îø}ÊÎ_¶¾ Õ>‰!ÜÂõÞ^Tü”0««ùu
UXÞˆ¯ëV;H.T
ÜÑY=‰Oº*ÀŸI„WfŸàÏEÊÏÝð‚R
…01ö¹ï£@‰È,¸(H‘,U¢¬æeš·Š˜Øº»wJ5Ý<R#÷Žùÿ îæV1¶1œ¦fš0³ûºás‚Gcõü¾RÝuëk?‹¤1aôZ[ýÿ§<ä_Õû*@ÿGÝN&gükkÜPÔ~=SÑùÖ‘úb~ƒø¿aî¸X@ˆB(SÒ'ßÉÀi#hë—7ÇS¼Ô52ö¯?žaõ~[X
Å‚ÍôwU¡Æ·ÑZPH
í°É:
×­d*5õÖ7°M$@/8S'‚¬]1=ÿ«Çƒ,ÕJ0É@
3:ôlUO¬è7T¤Ó¡ƒÜÏA6~¾¹îóGžÕ~¸ØÎ÷Í[B¼!s*ÁEÅ°읣)»Û’*F_Â?#ßõ“¼0‘û'ä›”È
@k7¯KK
ÐÆÚº(“Ý{ó20D2^Y— çß…¦][¿Ú[T?}\ùÔ&;õåýO¯¾‘þ÷”Ù_”9²Ä!Ó¦<f¿2Êûp=K±ôúvø˜¶ø^óòåºeÓÜlû~ŸÓ™Þ"ÁúùV!m‹
Üæ,IìT¨¢làW"˜F¦LŠzŠ5Ëi`
«YÝê£
”ØdÊŽ%\£³f>çyˆØ}:Êicew¶Æãt
¬X“ ½
!2gh‰—y¥ú•
“³Ü#ûQ…«ŠÎ!séû0R­ìkØ<´…ê(”!ŠU3YàGÒE_uRÓnzèï…¨*|«Êc?›$ÏÆL„	²T¡AØG¼UÜ¿H‘Õ‹KÆSÊMåá4j$¢‘¯ÅkÜûÿ>ìäŸÕ/ñw$CAøo‰8Êm¹iCÿ¢
#Øù@rˆ{&	‰¥ ¡ì•HŒ)H&“FcHÐw¨’>c€k}™EC`VõH™`/ìu¡ûùš¯êøßßö܉ðWû•´©?×ËÒ½nñ³æÜuÅ·•K~mì)ˆ1öÃìÅà”Aöz©ì•_n—Ê
S“ŽŸêÈ-Bœ £u™°‰´+°'Á‚|&¸‰<\!`XƒÝR éè³Vñ†™Á=;ó¼U+Fƶ =¸6Ýã”b%ʘ…˜W 9WÊÊA!n?lL€ÍE’ @Òª6‚Ÿ#£@|‚ôá¯_Zz¦š*(ª¢š&i*¢*¥`¢¨ªˆ¾o‡ówüOË«[êÎ=†ÅÚP›ÕUUUÆL¿Ó•Q$’I†¿wÝ‚ìv—Ćú¥âcð7íÓDånsq´D_¯Ï×8/‹óëÞÿ?åãöƒkÖF
!ˆŒJò¿’hŽ‘ô‡„;H| Ô=R.§ŒצTѾPöIÆ"ç#Y lÅ-´‘˜PÌ#DbÛ9?%4Í°Œ6|+H§éÖ–¢V)jøƉx{' ¢óñ­F‚@$# †[ßû_ò
R®žŽ­ó”¹ƒ²0BOÓ9i+O5ö¸Žgé`¯ËÚ Nç2zïÅŠâ,NjUOÊëÝî~£ìæzŒ=éˆë3
¨«á¯ñìr˜«?X•F9â’¿o_mÆ{5oÚÚm!ÇâOƒ :_oF¸Ò=dOòQad ÒØÕ\L ¼ %%–ß}G@ªZûEÏÁãàVú«×çèxç‚üø8V་ˆwJ‡–V4" ü` w®à–è;
Õú]ê»#ü¾üš+Ùëëî6/,>¾ÚÏN)„#0A=›²ßæÞŒm‹þ÷4H9›i¢85å¹Æ”
DGâ·—¾ã¤—䌥9íÃE\LÚ¬ªÞü·×™ÀvØ›#âmñÓ^:ߪúËccâŠõ	Oêr»âßÇ—=w¾¶QjÚÈàYÁBÜÀ}®oÑÝþîü®·I¶Ìw?'ÓªW
‰‚’$ª7²ˆª™¢¼s
®Þ9ª¿)ȵÏIªÕ•TU4W¦xwý5T‚}E	AG¿[‘AT};“„QMy‘7ûhà3,÷Þ»~.Š‘!
(¨†Œœ•µ­ùwûÅ; T
TSò„Â"8«âKiÀ;$=’𑢌²(¾çût¦¶”ó™S’è(*š
+l4{”y<š‰th (X‡¼ÊÞg»‡ÁÙh
=l„@Q at U	HRù!¤™I#ˆâ2²9Ë…úãxw¸I‘—ZÖ‡”þ2öFŸ÷|ðœ$>R£¥Ó¤>ôkýù` €A at J‹º­÷ÄĤ¹o\éñ”NJ{;g»?í€Rå^eEŠÅuößüÇÔø‹üô`žï—s}Zt}^Ry«e‚†_˜ò$¢ª€R¬¨„– (&¿—ý—;mËW)4ÆæÂC÷sñ
D[Í'—k¿©iõ{#Œ‡×èTwÎIâçwºâ룃kï
îÈG®k¢R®™nÍÿ›œ“ЪY;y;±úÑuŽ‹äÖFéŠúq‹ Íº¹ÝµÕ©Æë³±ˆãSâ&J…É®hº–x½ì\Ö6ÑžÊíª±LFt=.[•ìmdX¹zü³}BÜÌX¹×þncJé~<®4’šÅôÎÙ.9å23ºòsóëËXqƒÜ‘¾«?\>`J,J@ˆ‰š"B$
ÓŽvÿm Šœ'ýÁ­e)Ä€µÄÏÂ×Ì‚Óþ6ÎP¦%ÂUÈ2Œ!éßÌæï°e2µ H!-B;HT~˜'özL¿»ê×S:‚ó‚©yzç–pÒfølJÙîþŒíØ8ÄO¨M˜‰¡8N…t€œ ¥Òr97	H´' ùG’‘ˆX“’B<„֝"iB:@ºbf%Ðb4>ýÿ¦
ûä øßloÝú<ol(zdW¶SÙ¼TØy¥¿Ÿú¼ºGÝÆ¡›Ösß³OèÕ×Z’‹™fOEy$qI÷W]úœÂ««>–ß
#ð"ûUµ
­+Ô
diÕ>–Q²e%~ÁÒnÿi	—…Qÿ
w‡_º9¾ywW`´u&øF¢+…ךñ¾^“ë-÷þË¿…:zw8²æu/vJ<e$¬òaƒyëAxªKI^‡k.Pω쿴êëêÞl25•?]©P‘-–ÙՏæxÿ†wC÷0Ýèo,ž‚e$ßTÄ‚&óÞ.\(öc·ƒžš6QÜ_¿ÜhcR±¡6˜s„¢%rQ˜ùSÓ±*ì@þ1uþœpÀTEQGÕID‘‘û‡ÇÃÕÌê1G‹øh} MdØz4¯ÚN¬3âý]!}#ñõÛ2Aô|Oo è÷m;ÀÙAB©Öd8Ђs*©$Ž…b3à¡?ò{zÀú960n²3ŠH0Á+ËQXã882^*9ËŠ\ïk3þÅ[?ˆs(æhw7Oûçú}	…ø¢³»OŇ(äíP s(r°ËÉúÈyR¤	~âç §¦€õû8¼ŸÒÚŽÀI²2Të»føOïÒ‡i®¿GÍ€Ð"ËÓ•œáµlp6ÎvÃÑ€¨ù…ͽnÒäÝïoHóˆÛ`w¨
!¤x……<„÷o¢ð+Âu®§2ŠêÃSÍûû2/$ðC8Uµ¶ÙŽ¯ñ<GW§öCö°ðٞœ;3'{þ1¨«¿·U¯uœK#Óý_OÔk‡hŸÜ‘þ1 at A©$ž‚ƒ¡OFLÐÄjñôúóûZ}oíW+ÔRÇ ã XÞyótšžTlžÉM24ßI5Îß"å“Aûw[ªŸÇÁ’Iø
© $>:ÑÃ!”äp¨ŽRNøŒÊy»½£Ä}ˆÂÑ’¦•ÅyùÂ@¢"v—|¿ä©Ýxe$ÄëLÔI¶?~háö}Ï ›
/ó&½=I’èh§)šˆ^°ÓÝ[y¬z¾ò¿¢èLäGݬל¨<½—×ï&ö£uHrïYàj¾oç— ÖYýîÁî‡=LxÖè´pçí`§‰;™$Ykéìþžžlä÷i¼×â¨G¹gÑë¨wöyœ'<Xð´Ñ’=Þ–O|cÝÞà<×R7¡X‡Ï$4¤ Œ÷Ç8ûT@G°ì¶Æ§Š8Àí·L€™ND@pû6~l6tñ?“Ÿ ðÞB¡øÀ0,®¢Š8Y§ØsíIp2ô;Ž¤×'™ADI1PùfIÙ˜vL`cô"„cM\ùñe$zHUšL‡£ý‘Ý»À¨y˜áÇ™Í‡…¢8c‰„t½r€5zKD„qER¯»N÷0ÿ÷)äüõ%y++´zå½Týžr¼üüöS슛èI3½w¸(0s¢ÄÖ±åêyÒg>vìî8釚üý¨7¿úðqÆß>¼†N:§46ð°3‡ù
û½uáœn€!*(@‡£¸IÚ3€ß¨S$ÛjíÚÁ€ ’èöDä
0ÔœP7µé¡’g3ÌBRîND³HËGh×[Κ¶îl׬*€·Š¼.—£¢á‘ÄIúÑèìËÍ«õ0uä®{|×fþ(÷÷Äc~ÈÚŒ=Í/]À…eÊéˆát£•U†ì ¢F‚vníÿ‡
óÎÎm0ÒFæ;UH	o?Zo÷ÒÑ ò‚
Gî‡ôåDò§lß¿2ÇõCÒi_°'ûœ-›€ý|žÅ [ÇÛ¿^pD̦’Ž;ÀÜ¢¤µxÄÁ¥=dL‰ßü+ÙΏ>]$!o°¯Kþ¯M7æ>¼ÒæÕ›–if#ƒê°{ã†áÍÓ϶ØRU‹ù›ºÚ¼´}ß2|‚k?ïCòâàÉÙ«fž ÿ_œqßüçgyä3ƒð—¦  |¾fœ€—ý?錜‚‡Ýþ«’‘	D‘
DP$!Q'ôößÒèñcn‡ôk
Ȫsý<¯q'rnRÄŸb?ÏÍ`w¨ÅöÿÅˬè,	ùEBðaA‘Ä㧷ö'ò[®~‡¸æVïš½ùj:Ëðè÷Òx“ƒû‹™KžÂDy¤†>ä|Ð|{ó	™•Ù|–Fÿy߶ÊG(u2C¯§%¸$ùú1’6·jH”LJ(ŠH˜˜ÙÁ<Äþü²†üÞ˜c˜ó ç)¤8ʯåGÿ…È/À&õX®$V4ÕvOp’¼L.^€¨Sþ¬icƒ_°ùíåˆ÷
"

—½ßÄ¢m’¤?ÁQ+Ö6‘WX”Ú–@:hÔÙÕGŽÑq±“)íí¥?Á€œà!’…4ô09ñð¶s}godÆ@uYÖõ²ŒG·öb+Ù~ˆvfnãWqhó,°|¼-¦NÎ[ñbfFä,vyK›=]—ïÙFD]ñÔȟˤçžJàŒ$‰”(÷ì—/ÙÒÏmz»N}|
ÖQÆÞ½‡
È„:NòŸ2¶DÛÈÎ3¢ÈvªŽÝempl¼÷ÎØ
äFoZÐl¯o«K“~†þÈ6ïµ úDIàÉ
Ð</È·ÈÖ‡a©A™_QF±-19Õõ{‹†È‘BNþ‹nL‰yV£§UüÊü:zF…gÐ)jXšô?u^z·>Ô}e¥B;ÅjÕÅ€ òô1ø°ëžš¶÷U¡€ª¿ð¾ëÿÓoÃÚ~uqóXØȍ@ •+`ªQ@!M!­h5BUDë×Àê
¦Q6
ä ¤Y˜‚	”ÐfZdˆ’ Šø,Õ3Ìeªš¢@ŠšˆøÙ¦"’šª
& ¥ª¦jš*gîî4T!mTTÅT$ÓÑùYÃhb‚(ß0‚ ¨ˆ¨ø>þ‡Twyé‰$¦
f"š¢I¡¢ªb((Š&÷‰ª`ˆˆ)¢h`š) 
&¢(’¤‰"`ˆZVfj—F‘(¢Š&*þ‰© 9Y1M	Ñ$2‘;çWÙ]ƽ—æà{O‰;S>}¼8E÷	Fhš‰‚	'K¯}9¹™ˆ¨’ªH¨š/Üv?ͳ0‘Oq˜Z#éh¯–QGÛ±éÚˆ>yúß>†¢¤š. å Þ8SEs,4Ï8r>y0UUUΗQLRQLêÈÁQ112ÑýŠ¨ €Š
"¶
LTsf‡gUDÏ Ø"üv‚{‡XÙª¢"û
 ¢h£ÈÄQÍ#
¢µ
O7wZð::O¦#6a¶1W¤j*&ˆû6">ý¢"«ëßøý9çN¢ÜäÀTÕ]æ8å‡S£$¢ˆªbï6Fû¶&d&’&†còeÑQ
C
ÄIDEၒTEMQžQTQUQCMÁPÓ‘ÿ)ù„ì¾î®ÛÙÝ?3ØiŸ·b¤‘Ö
!öŒˆl™›KRJ	#}L«ðfŒQíñ°N(F˜â˜’fdƒM4ÓXE
­)_NÝJ6ŽNv7ô¼*ç52j¿>ïÈ&‘4G‘ö.%éX§Ü|Ð9Ñ¡ß@#ðÒ(,±p`ÃhQ÷þ'Ò'æŠzF"}Ù
›^’ñ:B#?>9J¶¸ýºéIÖ£aæ!½šaAâ5ïæFs,‰¬vQ¾Ò#’€ÑcÖæBÍþ
êúglœñ±÷’9­jˆ†«™'+ƒKÀëýÔ·94å“ò›º"]‹5Å4ég¢¸Éáöÿ”·¾•tÕtð¤…Ó!u¨W5,-+)<ér‘û—	¯¼Ój¸EK™¾¾fkTU›¦å‘´83­©»Škòæ,—4™þé†ú•v²
åø¢C®4ra¤{pãbׯ¶lÐÊÇÕN¶u®P=,È<oüØ:rB®>˜'ü+#oäeZ‡
•Åq½ï“ƒÜX“¡š=â)/dâGÊž)bžfòå+Cá>)/áà6yvìØœxßÃéÝeÐËÍ¥ÍE¹‰öy³×‘]½àâªÖ;%dø(]Óƒ»y¦Þ&þ(2­¾0á×ùÑÞe#Ëš€ž‡ò—5.5G_§åŒŸ»*þZÝ:=é½^ü‘"BýR¹G¤ù­&¤ŸŸ1Ý5 ¦·ôOæòóJ'ýÏ„}‹L°YÄ/ý~ë–g”ʱèiNÎf“Ñ2žrpÓ
lhM’·4YWNT`ç*õ{z´<
Wuë͝+Â|Ê¢!†:ÝÜ^ò€ö®¢×Oƒ…£-Ê9œr“º^γŽÃÊÐ|ÑñLõ˜¨lÔÇ5F‡W_ÿAL‹\ T@ªSdÂÉܽö~iðð¯Pÿ»=;ó¦rw^>—E§Ì£Vâ¶úc‰AÄñÁç7ù-Dcد'Ê
€<Z¨ŒÛëgúô;#É+AñòŸ7^^Éîæ$}Ì&¡ùù€ó·½ð5eš¸Z=q©_ÕvÇõ@þÉÚæB{úв¦×ðyuú-*ŽùÓHqöÑfoÊÇ^Ì'š-Bót(£mÔµ;¸ÚCaèÚrïÜiáU1
mVÿkôç‡I«èU=°¡†òƒIF±ýzjmzŘ¾3ò?ðïÍëLåQ cLCa„ae^à첚
á£ùqkrI þ3U¢¿Â2¡„b ã˜ŸÚÅ8×Ao\ϼ9pÀ6;ÍÏ‘ÿNÀÁ'
Y§3½–a¦W:¨ÇÕ®wýT6Ûá®lêÈÉpãa¶|îwr߉¢Š].¯0{½ÆºWÆœknÞ®ÇÒÎ.9FÉøq0iäíøH—ˆ•!jVi2ªÄ®{	AÐœ»O`éI«hÜ$9^aºÄg:=ÎPyY —%Z¸t(6Z.¯ ‹AQcàÁpèW¼KjŽ©ác®ǯÌ萫"&1ÃNµA™®tÑ0 3bHZ0PHÕ­™Åtþ.©ŒØ0"Þ¯Í7:¡ç¶_Ä=Þ‘ï¹ËÛö.?~® Ée®Ü³–VwìÆËÖiüõ¨ûö¾¾:rþ½ó¾yC(Ý#bÆtØ4USAŠÛ_.>áîŽçišŠÆvÒž÷袸0Üäòw]½z†Û€ZšdA{
ŸX¾Ió_Ò\z£Õš˜ªY5‚‚
æ>±øMÁ¢“È
£U±„aÐRÇe*M¯<X™ ÓE`£#@bÝÉLw¼äE¶
LÎÂä2ÁCÐÌá÷ÂìF‚ÂZîÀ¬}gP¬wc"¼øùÅ
9–âöÀ¹­úÙ܇¾9ID‰JP9S
PÄRT”-1ÀÁU	A!PIDR²!@ŽŒ‹ø%¥]×É[´ Gøvsˮɡñ^dJ€›qfƒÙáý"ÐâÑ8?Qoaù’4ÈÆш”æaò2!ï›d3g×›5·FX¸Huü>æxçÇM¯!“~›fž)ÝaŸï‰—‘ùkþꪴkSS
뿲~IØø’7\m	Ƥ‘ãÍ‹§hCXåÁò%]/ŠÅ
CÀ‹	3…)
´Q›n厫–(Áüø³„´hü.›ž7?U~ùûˆÿÄs~‡Š'Ðã½ÃiÑ‹‘_•0}ÏÌõÉ‘!_~CUUT¤†·Êêé̈ƽw¥&sýðb‡jî>µÙBÍëZ=Õý£sB-X
u°lËÕ0κ!Û¢B—ÃÐÊ^½+µxÙÙ’ÑsÌ›’‡ë᥽ùçomV&òÖ°¿:«îP\mغmÿoi!ۏ¶H%b©>É5¬b\_ç_?®jD¡ë`¦`¸&±*äw²²ÑF—8˜©‡6«Aè‰ °4V®Ì‡½À¼±B„]Npß"ÜFëVf…²Éš±â®nmÐÊj鸌û½5:*8M67@Ã@=)TUÀ<> ZÍΟP«<ñ“¼{Ô"ª
%q(H“,œ”e'·?Ÿ›
©š”Áâ*èN®<4è‹tPOòæþ£ÓÅmÑý^Þdfóñ5znѵBùªêª¿7Ñ]B´Àá:ü³Ž$„K`„ÁGŽÕ85iÜ$>g—Þp¬7€š}á5)Õê8(%w}’Ð<ù»3b ÓÅƨЖ‘(Á
Êôï{
„Óí <z÷ñ®»œ1{$éK-lîóß”JEDY¦t×VêͨÖ?«žr'¿ƒßÍGÜðÔ]
ßT0z DCf‰Þü±¼ý9õžÕ–Š
¯G„Ó 3Ñ·Ö­¡§:
(Š™øMÏ%òî.pHl*
ã¨ø	0(]UYJå
²Yg¯nW7¶¦Ðm]C€kï¼e
*ˆÝépÎÐÈ3hŽ·
ú
WÆwá5Z¯1È$ëˆZ—P ÏÎyó»Á÷å£C-¸HÂ!¡£Ò5®pQ|§>b乪…¤
„¥èÛXs·‡
6¤q“	èÉPøj‰sdF&DD•P]¢y Æ~ˆ$ŸÌª+ìÉΑÁ.êd—›B&àC[GU€gWŒšþÝÞ9„q
}g|ÏŽÊ+ß/£ý²þÌÈO”vÕ`i6iwj‘,HF[Œeöóöphá0|×{?WÙ|zݍZ*ŒoTÔ.­-cª"…)1RhôæñNÉUÙ»;`¯¦ánÄvh…†åž»Nysƒd¨é¼
CM^Ú…–4ÅïhÃUbâ0¾AÆ6ªLs-G+69h+(=v…þ»¸sîÕ‡Mu Éi»Ä¢¯$¤I1ßÔÉP±Ö•uD
Ãé­s¬íáÆæ€Kšb£TH
‹mrR[øÉ;õíêïã¬ë 
ëPÈÊŒ6ã	£‡6/¨F‹µÁ5i'r¤?¶Ø¦­2uÅÖ_eßž”¨#PÕ!G?¡Šw”UƨŽ1ôCá1Ž=w$ôþ]cÀ"±*Áÿ'2?4ƒf¿³Íã°–‘˜·Ÿ^ÿc%ۍT{¼Õˆ?QûpInãû±±‚OŸçUënÛ_=1æ›ï;ÖÊioŽ¨G8ãž>b|’HX3õF!zþÞКÃSY¯Ô$)"!㏳òürd2Ž{D~\ÔÇ£å`ÛÇ©Ò*Uj=Z!Ã#!¨*íò¿®zÑ~}ÆqÌ?öt·WþN~V@Ø}Cΐîé²áÍåæ³Ù×¹·¹™^|ü
8XDã)ÄΩa"ߝkYªX‰œÌkXÖuÖ)b3¨t“a˜ìã8±IÏ9ÓFL0n3“ž*1©Å›"meàÒ[™.q[‘‹ÔN^0ôA‰¬ãH"9ÊjÊ>bÓêáåk35R¤Å9C¾uPÅ>hÒSDë5EeôùÕQZœð¤Œ‹ü
‡îï•w<ï¦aYÒÄQ®†´>Ÿ°¿iO÷²”l£?³Ù‹Ã¾›hüüO¡Ó§	Ǎ	DIÌс‚
aÇcÖÿ€;ðõzO†uY-còTÑ¡FÀ$'ñP¢cø}²øáôíURäCíT{Wú ~êAð}ðülÆÈÀ’HCú†_ã'šc?AùÃB¯Ö=Öã°d|ñ ÷ÐÎ…2¹¦ä!ˆÉv²)þ¸òʈ0L#Ï!ÏæéüýüÛ”“º?Ö}4Ô_™m¹àL]Óm74œ?W"º…¶¢@¤%èZV <tí§¦ñ„‘6‹‘¤
d-W×üBÎWȆøýBF¬-ú…IAýcö?.jWa)s‘Ϊ…‡Oï&5 ˆJ±{ƇøgSK@ž¢2A$„/N
¨b¤@?n«>àÄt͝­ÛÜǘ‚*þ}¿Pæ~+×:žð(˝²3¨ .R4ûæÆó4/èÂÍjvx(R”¿´Sn0‰#O`ù`çƒRäÕ_ŒHˆ˜	{“xûø(ÚW
¶¯Õ½yGé'ì‹Ú~D!¶ÝÆƇIŸE{›	þÏœð°l‡ƒ£ý½5 m›uJüë[8MfKð¿ªþ¿_-?ÓìÁõyaž}é?î’CÒ}J¡Ó¤jë÷vOÆJÏ^.EAÄ—ð—zÝf†/DŠ¢@Ͷ÷…F(*¯!¶Èsû熁Ņ‰Ø2p¸‰¾y¸qê_·ìûÿ¦øû;ðyZ
?'xï˜û
¦¸«@Ò-âÝ \‰\N'Zr»#BSM]ÜMõAcùý/㙡i'i¡œþé´™›º§,ǝp³$º#¤å1áþiÙt%I
¥9[¼Ö:Å–Ì;P“v›£¢µËE¹Ûãc±Lˆ¿»°~œËÒPb6”(r(6ýè€@rýiÉGx_“^jî3=
ãätGV
(ýÈÿîq0˜¿S£î0
R¼fé‚B¨!Î|Û)’'ßÓàÕ=	\;«¾Üó<väb}ÆE»‚³!û"KR2uCg3­¶ìj‘FÏ”Â?½~3äQmqä‘9ò¢!ÄE—û`¡Ü¹!EüˆÙ µ€$ÈØ£¨€ânìÊŠvøkõiü¿%‰ýÄ7ùH€@Ò]Ò«¹¿šºÔswóxN›'/Ä:~ž}2ñ彇ú`Úü¾«„ý†»©Ÿ}CR8A
ìóoœ1×äq(>¼k°<#çSœdýAÓ
i&"ÁÝþ>Nð5Ïé`ÍÜäJ'0F@•õc¬Qñ—Îi­J$¿]¶ιÇõ†c¾yƒw,ù²‘>ÏvœfÈR“n v`¢
ÐÏ)Wý=¥Üˆ|'ž샆µ…ó2,‘î6¡œþ
(¢Ð}S†Ðî.þ
š`£Ä5–ºçõÆÎÈ	E@Ö@@–e†¡vPoX[EWf2õZ”@Aƒ%ðô·V2z¤uè®ÚÀœ1
ëÏ]Þd?°<üøõÃ}‘	2çj4à8ðLŸŒ^áñ÷AՐH‚Å
{]j9ãԐo§íðÿFÿû„…Â/§ÆŸBØî _»Ñêçúg‡0}A>BDz+þ8<E!&æ¹/ž~ç‹x{y¿ HræÅ„o‚|Ï0žÙº\•ÇPé²Í_{unÜ;êvooß=–ÄeøŸUa_èõédb1GÑ*E¶ýPíÚ»¸0Ûhxø+¨n apf
1’æ4E:
óQÍ	è9ù/”úçßñèø¦xÏevQnÚ„ÞKpwAt9kÆÊÄ
ÃChû~ó‰Ä;´ÁF¹–‘P2!d¨\¡À¥$-á¢Mõtzj®qO	åWL­Ò€rÛw
Oà¦õçæ·ð=Û9£x˜äÿ14Þôß0Ãù·Ãòõ}>›×jQD¶	rVudº
w"x…9Ñcº‹Œª Ý̪#à9û8ã³.6%
é9RQ
ï=Í‹,•#°$„\ö¶×C‡î¿êÝ!ÝÂÅß_
œ£åèÁ
®Éï$ÚàNA•÷`jc™ò´}ï†ÕÑ=TxWÃgU˜û,8ˆÄ(õ%ÖØ
éÉGã0l F£#ä.< õÿªa—©ìø:	ðøsò8šùéî<Óˆ×æm£Ó;¬êe¤'筝a¶íIÍØÆ=uû>½‡éÑíËt=Q͵P8S·Æ»ßí¼—
½ÀYV……D
ëQ0îèLïœB•åˆ@gº©o÷ã fð>Çyïþ³†Cj‚‰‹'ñE
‘Ä[E±÷žNЃ×(‡›ÝÎZ°i’Ÿ„„öX¨Ö½˜:ñ×»ŽŠTÝ]T‰Gƒõå8v_ô0¨	ô¶‰Eæ¤=´wÃï-Ä->ªÏð è'ÝAi£fÿís¦ËX#b"ÜÏ
=U®òI@
™ÑÕ¨PD~æuËc
q=(ZÚtñÄ@€GuJ)€Y`ÜeŸk9ù´ýn=1p??>›…¦‡Û
Ёûe£ˆh{Á
ÄL¦"ÈØK.}ÓÃe½Ó+´j÷÷á|`x‡wtmö}—ð0eO
4`p–r…'o c!9(€H at .(W"“œ!Ê;ßî°Hjù'ÛÏN|€ÏøcÎÙ}®ý	rvVkx!œ»fõþ›÷³Ÿ°¬~o…·öõ?YÈ—ý¸ŸYs>9½÷h *4DóRTÅé	®]Çöc³æ‰¥Âð¢¦
?¶áx’0Ù¥¼ç®›o+Hz#]w%|ßR·¨™-T9#…÷zX òøxTcø¦¢±Á€¨Za× :=Oÿ_Óåý»yYñkë8j&áBp¢HiŠ¢^åð)89Ï
Lù£WÒ~ÿC¶!úíKê÷yi¼žª¢gz¶ýOúþ²!ï¨6ñ°JÁô—÷»ï-wô )渚°v\‡¶£k8ü†q*õQ…?f©ƒ1‘›iZÛƒ`jjÀmãnGÃ
ÝZÿé„oÇTÔr$VkÕ¨Ðò ¢*c±v
ÛTnDef02Âtpǝ½ð¬Òþ;~ÿ¢k¦ÅiÀã¯L)KøýÛà³ÁíⱘmakOô=(ßm@	þìáЙ ßö —¹Ü…Hzºt§ÙL¡}å¡'³*dþ‚ßê&ÞU×_CôŽmײk€Q°cÑwìç½™7Š¶8¸#rec¥?­â™¹/óÑÝcŸëDnŸÄˆËá¬
jF0Á¡’”+j’2GYr77y‡•‹8ÛM4ó¦xW
Ê&Ö8ÄÚßsg?_´[3‡>Ͻøü|»C>_V éù=Á‚»hÐÈÓb8a¼ƒ
Ê6à;ªlHÑJ&—&Dߊm6Îé¾ó†9)¼)¸
ìÕµ¯¦až²Žv2F$% TbqÒ£0
ñïµÿ‘çzök_W_`ï¤JQE(¢VŒ[VÑö ÎH{Ã	õ¿?®în?ŽÆ5wuŸeèócéäz;?Ò‡‹Aˆð…
$ÈDhÇèáÎœ8iå:w^FŠŒleÜFb€‡cÛþ—ãÛ>¾žÚÇ?œü¨ûXM=ÙâßÎJÑÅï•>ö¸YþšÖÉç’ Z*?2ŽTˆ
âŽVñûýe]cïö¼Û%|©½Ì‚.¨°#qM–<ý›s:ÞútcÙY:nÑÎ@Ä*x
7½À€hªŸ÷lôBÁ}¹ôJßìòÑt[…WxªÁΛ¹0žŸ6¨A ‘¨“d;d®”ÍáKU¥IB2‰)5I#–CFÏ}ÎQ˜t/®N(Ö/À³fÇÄ9œ!òd‰/žào5=Kõ“z'ž:—5Ävó]•í×Ûß+¬h“%cµ·bð.5æ¡:­ó]SÚ!wâºÁÒ5Š\»¤K—´\2±³‰G¹hFR1w*$M—’T©ËÄ ‘ÈBã5‹»æ6¼‹9QLŠÌó«~ÆúƵWX{äÎ9‹—˜G#Á‡Ñ
7'iTätêàÃÁKbx키ÃDFÌSȨâmgêÌÌÙiM¼N¼óƒSXˆÅ´ƒfZØeG0 Ž¸eÑa+bɽГ,ÝôF»²ÙÏóðÖ]ÆÄÿí¹Y½qŸ—ú¬‚‘…öCœý(L‹=[wKüËëâ@K£_ at xÀqÅB`Tà÷†P{Lk7<vÅâ¤Pãí2¹a¯éÝÄsáØà4L[ƒëš%¿O€%5„|:Ä"ñ™%†¡œŠFªbLÕE@æý¨Âx®D>O·öóÍ¥5í¶b´ŒMo*#ò‹EV¦¡ƒ…íxœ>¯²)ì³ýjr¾¨àƒ¿Ê
ì½€!°#³¶¯Bé\Î2uT ’äQ½üø5HáI3\­ïW\µ¦|V:'eG—}A
ªŒÅñàˆ¥{‚† Á¹-”liÁê åæG9âåHzß]s¹ÃÂCA³¿5t/X‚9áÓuí?hóU˜æ°ïý•à–‚Mdd澏£é AØ
®ðmè’Ì((CPtÞÂØWô=ÁêCÌSE®8’wš»t± [ë”ìBcT’'?›$‹4;Ãîê?V€újiÙÿ–;ËZFí´!Jwd¼aÒRö‡§.=Þ;Il¹CŸ;“Ë^ï¦p.–Ÿ¢;)'ÈòÅUGäDŽQ
 ä#ãœY}¸çubÚš:g©p=¿{5>ÜÝWELÕ†ûdŽ
q¼}¡ž˜<[h›à?DzƒpèýƒÐ£ê¯Sǃ]Á/lx³÷Î$ÈröX4DAa²§iÌUBí4rÅÏŽÚG²JAâº/ÎáTT-FçL|6[^C¢¡!Fµ‹´Ý)”H5d?ïxòÁà_§u‘Ÿ{6I)>VuúCðAv¬ºéUûݦՆWºC!›ucûÚx
/ez.ea÷¦_âx…6V/#,ˆ¶ÆŠÔÑw=$;êÒÛ8s_ at l†å§@ƒ%‚­7ǦõMCX·¤°r×¢v…öÍ™QA$3PáÓ£ER”e ;¨T9vO®S×D¦¡
Z±Ú¥6¶ˆ•$¶îÎu!6~dúCýÞ_Mã°çáoøVBŸ³9ÚZ}PÐöøuú¸víÞkˆQ2y©i\/e
þU
ÛõK󦁦+?ÝS…ïE"$)
yÙÇÑîI
Œwuí¿Êé	}Ð4eé¢ñæþ|ÕhÂïA­Ú|´r
æ	˜ëg-N
QYT#ìû”$qÛ£+lª‚b ˆ·¦77c,¿(Ð"EðTwÏsÜ])ríÙ{Ÿl£ôyœí«xÞï]nÈêu’O·èÉ‹°(0ÅÌûÔ3ª6ÒËfGLS9W8í—	>ÅLÙá³¹@¶5È=L¾`…öþ
ÐÅÕÿ§KF4Ç=&=±¸=竆
5>¦èpZI
@ÝW°ó$¥qižÒÕæ•äb‚ìÉÁUC¶ÔDCWì#ú™?s8K/¿vÍä
Œ¾xvõÍT"íq/ºƒs刓܌S±0ã@YŠ…F¼yªÛG3=í©De4 at SY…/x5¾³ÁHü†5Š’D>o"±!Z$´ƒ’Û5ÔäB!DÂMÄMˆK>ÖÙýòüeZn¸±m"ŽÇ4bㆀ٨EsÃÕÌꤲ¬ A Ù›…8¦SCÓ‘ÑÅ^ø¥1|jõãI«f¯(æW'N5wØÌÌÉfAi–æ…òëÄ4¡ê¢T;±‰ºV]¥yʵfìfà´™ƒš†žÓ¶øŽËuÒAÌ»B‡oY0n¹,|‹Ç`µÙöÂ/÷•©Õ‹Õ Ì¤d-´üÛ|¡†ì,mQFW-¸eÊ‹Ä*
¢+ÂÎ1Ò~™ÅW7\|ËTajísƒÃ.­£ólᐻ
°¸éÛÌDùÕdâ[ã€{ÂŽ¢ï7VáH¯ý9Y`Í^?–!¸/f¨­Ðóxûg`ÝŒ¹Ghh4Ù#Üî˜(ÚqÛN ü>:ºöª&ßÞF²Ç­j]+®¼ŒæõÀŽŽQ†æ`5{YMcÙ¬ÑDn!YïÇ>!ÕaHìçýÀ¥@§(S éÙZÌ'ÕHÅ(‹.e `·Êæ­‚‚EÆ¢ž¢1„&’(_åØ4—
çŸgYÃ~FÕuaåçô«0±½®Ð=–ü7Bw«Îu~“óÁAU
DÂÃò?~ãÔPpDü™ü{ùLœ•Aô||º¹TÅ7ÉA÷9öcï€Â
{ސxLúwjrÝäQ¯•5¡ñ<
>J¶­Þ£'DfàŠû®ßcè@ªWjªã4Øú‹€Q‡’³n}Hf»Üi¦4‚”CÑþ\^½vÈ^›æ•_ïéð¯u©êî¯à"ŇË^«0ˆoxa¨yòQ
Y—4{a°ÓýÖâ^ÞžïSt$%ìÛÛ¯Øô;)‘°t–ôÃûô›­±e4ÃããÜ×.jŸÙbÁ&áRŒë…p¯ªE.”d_*˜úºãƒ¯’Œ*È“·+Ö_ãÓÒ9wHð™Ñ¥±t™&}?1ñV9tž<z*ãmrtŽ—T÷B!4™•&èÚç´ÎöÚþŒ<uÖŽ_wZL}äi‹	x¼ä5tãú«Ã’$ru®â"äU¢ÈDÞàÅvÅ 1´ÀA2AÈw…T³à>’+ŠI÷tdŠÂãªØ¶0
2xßH×g¡?
´[ïKÃÃ/h†ßjÆ¡{ÜÏ-=¬Ô¼#@¨etÑ'¸}AûªNˆq­Ö@íÙáp¾v[',XY[Â~˜sqû?Kþ´K2íA吋Ù$˜*Ü>² ‰Òñ’¾E>£vKGl©|Ýì=—\ˆ;…OšF¯.2lDG>6zÜ3'Ñ<ï4V‚@ #a@
¦¤lÐeG"-d?ÚåV^nûsÏím®o[/Ñ”"úV©æ«ûÏ„#cê£	€K~ã”Á·t'fëÝ íäœU{úÔºñS„9\ŸaDªT™“MYß[){›<?Þü-Ò¹È	ÁC}žýoá×|¶*ò¦`(mæZs}¹ß3,ð›"¤©•6žÏ±GÝÐäB–­Tª¼kÞ-õù!
E ²
æ&)3_¤FÓ„‡¢Ð»üN	G9•Wt©³c°$aæIΧiEäêÆ—S„óáa&N&¡³{¿¨¸ÉlÈôêwgwâ?™‚BMȳì#ëËPÌ
Ð	nv]Œ
@Öž%~ßc6™°_CÐkþ}l߾ͦ±=|÷¤%ú¡}*î`â*0J•$b‹§¹t#øƒ/­E?ªÅ
«Ð
Ýóó¯˜LÌ ,Œ¬Ö¢ù÷,5 
jDZ÷æ´4ÊÁª¡Àò„5kH† –ŠHµglƒ„A7´ÿ7‡¡O¦³Çß³o[ì~rvÉ_z„N·šþ¥ü¾Ÿç™/¿(ùƒýÖÍmçÛÀ™Õ~ï¿9O8œW2PÈ£÷À–“óú¾%—ö	7̈W¿ÒùËÍ•@HCyDªM›ðcxÿ•Ö›?G·³Þ=–:Çù§Ýq‡³Ÿx¤`Òš-ú¸º“‹ãÆ¶ãúpô‰á>¸°™Üý0?7¯uÃí$[™+÷‚èÊC–ùÒc\:=óº©.²6téÔìj?+j­ãÖ3cý—*
dS†µoI¬6w„qÚðæÚYèW˜ˆDhê™ÃÞ™ýÄDvaŒß×üN¬¢oäÇÖØB*ÁH%­{óùå`ñ,Xh¿³Ù‘Ú<¼D낸bHÑïOŵÙT‡©·Rþÿ2ܙǨJAN P¦†jx]lÂÖ¤†îGO=ú|‡éPåD‡v/Ёyºæîr|J¬ð±ÕùξÊ,;Jµ
´Ýù÷ZÆÓç8óõζàÂý"h®hÕ(8@£˜ï½kXëÌýÉEÇ
MŒc{ۏ¨4yü?̺ùø÷i‰;÷Ú‹žÝMY®±îØEèžÐ`r½´:ê3;R†ýáó]¸ôlÑö ™¯ƒ¦îÞk¼BÚD`–î}â
¹`aó£Äj×j€H2“387o«oñŽ<Õß[ûô\>¶¹ñ¨Dÿ,,„üéUˆi4p¨#?ù”t4üÁÀuÃ]ºÈ¬AC
”é+î磺 6QÜ_.|žº(É
räž4³þÄ";ہê·ðUIúx›[Z´[Øe„½'×ý¯ÝE±ˆàóîþjä°QQⱬ½z!
Õõ{ödPìŠVÜ3£hì!$SÒÙÍLÈ;âÔmÄxqÄ=R°Ö*v‹t§É…=«sѾ"áYÄ< ˜a~µ+–êÔá-|!ÎØ<þ6ò¸
ñp¢€ úkûâ65ìÀ¹”zÞ;%å÷,ô¡M|F‘Pè0¸xÕƒ¦–Nsf¹…ƒ
lûäÚð~€!é%A~Ênº¤IÉ÷²J`m,ìç1ÅY¸c
X›
–°›	¼\¸U¶­½ãßn
Ü8gÛ—õË~¸üÚç´ÕºŠ^òAßuÝt¸óš„ìDºÚ@"¥¨¹	1ä]y,æ¡ËÍô=ôº—Ù0ùwÖ¾/ÐD+œGSÂVÎ
¬=X±qàð¨Ã~14礼¶DYʪFµUJ×S“^•ri¶2¯u.j†¦¡‹Uá¤à*¦‰
Œ|dq?È®Þ*ÖOvµémé°Íž´HJ5àøÆïÊíí7
S¨õQ"›
Ǿ»)¨E»ª§ƒÿÃ@™áß7ý]¢Álõó햁½otÔ9Èî–}¤ÝWâð>Þ>÷×T29ӑʁXóÑ%èô4Ûm/•)ˆT!Å„7 ±ÏI”äЀ!&¡;Ù„$ušêí`Äa[(@Ã,±ò¥É캍1eË|¬*>©õLm‘òU
NŸD®*ß«Ý,"<K™!J”/„—Òo¯õê·cÍcW2iEUíf]¸¿Í:]SBº>N‰•wÉL˜N—ý•Šwì×*àš¹Ó—Üážb-Ȩf©Îd_m¤Œà3¸·øxƒY%
ðJ?
[...1866 lines suppressed...]
_MCþ9Áx¸'>WŠçÔE ¸ùZà0'8"\,ljD(!f
3î

`ÃÒ]¨
?Åì?Os®À­•È€”^ïúdh_Dt#ÛãEà^Tʧƒß†”ñ•°ý¾» h~²´dC¤ÎÅÒ•ÉQØB’©î“6Œurô(øÓ³‚mk`Î?‹ôlŠ*¦`ˆhP'@&îpAOõCõöRiöÐâb‰ FÞì„CⵚxC!§Ñr? š—O›³%æ
µ¿¼‰¢
ÊE9Lzùa„Ԑè‰[E¬ Ð?Þ‡?
	¿é(±´Ô$
!qhÎÒ@M6¤ÔßÁ‰üðžÕo&_¸ôÄ9˜ÒSŠ_pc';m~h‹	ÍE%¤<#?gÝÁ“I—%}¯ï’$(¨’b*ˆ`¦ˆš"I†ˆ…š"&&^X’( ˜" ‰†¡" !
.Î ¡‚Iš®¢³&e˜C$æ¢*"?š5±RIUÕU4@§”¡r£(Êý ˆóA¢+µxH"öp0ø‘qÂ
¯6|d•§œд‘F"¸?v¥J~P™€ïN†âO:5Im“„ÂÊ´®ôL‹M4x‰£hÚx?,,ª›U+"(DwÀìL¨¾dÒ±Û[‹Á”üÀ9
G±–'ðãï’‘?ç}¤wwøðôk¸XqbžQç~³qR¤A'DnÇ7Ã&~î
 #LlM2buŒlÉ­LOŽy}[´mð`J<äS‘*ä#ý\³óG`Fím®
‡§ ñaííÊΕ1ÂÑ¢^+n&𐙣ÅÉ	­ïÏX5IóAÓb¾„Dì?€>§ æSM}áüGý’U(b‡*‹Ý§Õè½’uèôæðdŽeúì ‚wJ¯ÆU=gÖlinÂõP=øˆõžÐ÷½ƒ@ÐÐiÑîB—
¶Ñhf£Î&
aŒïb1]kg·h_áÊЯ2RœnQ­MŽ°ÉP›,µ‚% hÎb™Œä`Óî…é(>eUîT)N¹‘ê8»ŒP.*iL±7 !‰ˆ Bɍ
M
‡FŒü3èãÙì)I–r”©ib%ˆ@Yˆ€¤PÈ;÷½[äñ±%óÊ
©>ô–‚®BœÎ—MØ}ƏI¡ï澉ô„
ðgVŠ0*§þ2€Û
G'ADÅ`úþ<B€R;~nG2r΂†(²˜•û!œ˜ÍâT1ˆ?òDîóDö=OŽÿ$»bTý90ýsÕUÀ1šßçC±mƒàˆŠMõß»†N˜!óÅëz ).>ÜCÊxÎ(Ž¹ƒB÷Ów uÈìwÂ&›£ƒ<ú†$›Z‰¸™:+SdR*b)Lb”$Mãp’õÅ¡‚öYBÈØ<	£„vƒ|Yƒæ¢>‘m›ÁP]|·¸L+HÒ3 ŸN oåЋŠ¼!—@{{ü"ßàö

Ô*²ãBáŒ…€“ž2ˆ<ðþ—‡™v48™v0úÐu·3”¢š:ÜÛ•E08¹FÓ
g[fjåG„®jçX¸êb*¬n¡ÝtîØÍ1rò"Œr8›GTÉSÖÙƒ«†¹Ì#Tº0C¤ÃTmΑK£Jæ&X&žš®0òd‰~DstwuÔ¤¬ûç£mwƒA$”É'qâ^$—T1‘c#5˜
šÐØÓ2"0ÂÒ‹ÜÆ'fÞa`
Øà’{9Þ`R1E<ŽbXâo!„“{ˆ„M?ld‰ETŸËú?—QÞP’uŸ‹ºuÂC{(ü1ץ܃””Ãb ( -ü|C„¡È09&”11‚ë'Œeá"bU˜€Y†IBôáÉö›¿ÓAp¸=P1€@£Ìw4bȁ8L!Ü¥O_â/ÍMæ`ÚãC‘!¿¶\°l#\Aá0¬Ê`Úq†ÜbþD@
#ɬäƒúŇ»¤=¿	@ð$LÍU"¡Ð9Pë1ëà|€î¾E™U8ú¢Ž^ie÷­7Is·¯÷1RENØÈ…r¤
OÌސ?¿q½QõP?
$U¢B“LÌQt%-(R1P‘RÐ…PRÓTšM…(E¤5LJUTTÒ1$ÔƉD‰"B¥
V˜%j ¡ *„Ò.‘¤ h
°!Ib
¢xˆŠä>鎢iDÜ
ìGÕÌ¢Òèà	 ûøº±³þ#¨DÀ‡÷¸H/P-íÁàÊâ…<D‘
Y8GÀEðH
NØ£mšˆ*oæë£xr|ßœÁÖ0L at B!TD‹¨B àz«\Z…„m_h	•†{‹"1`¾…9
›˜]×
ÀË´64’G£jH`pS°z‡r£àõÀ•ˆg¶2°†øK\m+ta¡(Ûribxy÷¿Ï
Å@?9ÐtC½§°ýPÏùÙÞvˆåî×~”ЁTˆ`bƒÃ°ð[QDTÞ5¾˜*Œð1¢QÈ
b¨P •CÃ
äE^»ðý<¡ãŽ:™³‰œðDKˆóŠD„¥>ü€y u¡iøÜT8(6€ÔF@ €f²†
=ï\	#¡1¤NðéïçPúÉC÷á
奐Èe(:$s÷ñÐE)Ju¨"öóÇ“t
Pº"G@c@Ÿ<rƒÒ3${Üå(D3¾Y7}‘TW“‰òª—ßöŽRRîêöÎDÐäµ<u¹´ÇÒG${¤)4Ñٍà§fcÈ–î •c0ØØâ©€¨å?Œ·ä'•I~'ìÔ¿Sš$2§„2ðàÑ—påƺÅßCµU³5Iº\³E(ÖþŒ;K at 3|<œ˜}±Ž¾Í:Kéö‡Ëæ÷XxÔ!ha¤¡ÉHu£å¹ÈÑ€«MD°ŸÕ/í6àoÌ|á“Ï|Q©X`¬èê™–dbƆà鹌€ ‹ˆñiÊZè>c;!ñbB’J§ä?£¨ëŸjiQüð!ZDÀ¨|`RRÊJU*„7BòÒZ•ôDSÈóȳ"M·éÒ–KãøMúß·7KIR1I»iôuâòzXvéH‚"CÓ Øá‚Iø}Ý3öjßÏk5»½æMH!À‚!“¶C!5„Œ¡‚Hb¨$Ê8}~P4 …)ٝÁÿ˜³ÈQóÈ>Øâp¨BÚýÂçÇ{¹
NKÅŽç] ìèêBbGO3ó®¬àãq(9
‡·[ÃLIDC̘	)e¢¥4b胜Å4”ŒA±©T)MD†•(YƒNOâÆë:>ݹjm–™þ£‘;? v#Ú!깄?¸>±ïúŸ†òBR•ý	±o™ä¹YéIÄM
žÈ†dŠƒ"!û
(ˆ¢bªªªªªªªªªª¨¢Š(ˆ¢Š(¢Š*Š*¨¢Š(ª(¢Š¢Šª(ªª˜¢Š(¢Š(¢"ªªªªªªªªªª¨¢Š(¢Š(¢ˆ’Š(¢Š"(¢Š(’ªªjªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª4H±—Ò{·îìB¯å³¤‰XXwÏÜn—©F\ˆ}]àþXBÍcÛ	úë°Wš:’GÅÖC !HbMæì¥&_„!ÒvJb|ɝh/Å÷¸\:(°a	Qüò¢%@‰ (C™9‘¶4ª}PŽ¢UâM	öG"PB¥H!ˆBf^9
›Ìe
h¤0
6&¦{[ÃÚ+m<?“iÌߦ#ƒk˜‹MÇXÑ=vcëê²fçwçÌÜ÷Ûã™1‹ ê¬L$š&×h²ãþé©öÁ‰ê8î`¾]ÑŠÇõkÒ¯—²¾Îh˜x¸—'u¡)Ÿ}[QkMíFæIñL07=ZÌ‹FÙ¼ÚcHÌs­A0Âøöº31”{Ĉ4Y.áÃÄ5ÒvØD¥†ÞÅç<u^Û®=„Ò„’ØŽ^µÐfa»†u¥O†#¢#ÙH%M0Òb
‘â"àQ¤µ¢M"õÙÒn’ƒ¦ê2'ë	Q́éÙñÿ^z·š=g‘	èö1ugX­‰bXª¨×Åv~$©ú3õJ!á±õ›{Ä÷Kýd'¦>$|IØÞþ
QD½*ø²§«IÛàž¾ÿîœC‘%̈œær”¤äLð"Ùøðõ0ýG$µƒù&:×¼dD£Èïò‚,‰€쇖º
Aý
^(H_Å¡V#Ñ 6ô7êÅÇQAGP÷ç'ûº
GºBxÄ‘±LXÚÀDLHHâDþ[Cœw€ˆÞƒ“²"O÷]v™*!ÄŽrJ¾c&ØBS8=!í‘AILQρŒ]Çeîé¨šc‡FQðJ{çóÝ‘âá‘æ[’	^xp ÚNV¢Ø0v—;èC­“©ä>e’˜´Óh=XŠ!22°­
7@¬øYRBd(:‚ºTp’'²LBè\L¤Ô±EJSA$BB2ÈD“ÎwG¼Âðc	Ÿ{¥Ž"ˆZìîA R at 9Ó‘8B4É4!	ÉCHJ@¤@ÒPw
Vµ¤(Z† 49‰(
&™	F‚‚¤RªHR„)ª&	!
1Ð€™€ÑäùKí!ô™
=æ`UIŒÄ‰¨zK?ßòÖô{ñð88þ@Wˆœ˜4Å‚&"IGI)~ILHQ¼òñ:Íè4^©¿&þf`zƵÑÔD£À¶Œv•­€™i?]‡ xô3‰È¡ë-ÙXÀbnwÂ[>_{@,Š‰Ä–1SÙÞ`>áêhŸíà*.—tRn',=}Õ÷m¾WÚ
*7ï?QÔoß¼Þe¬Á ”Æ{ÙtFÍpXQcÅBã0TÆ•Ï[cLm±qpÃ
²IWwõ!Íkã-ŸP{`"½‘á°ôp[€äEZXЭm¬–”>!Úbº=gŠþ2è@!ýÄS­(P“D 8>¢Öñ(iAª+߀|äš–€¦€¤¤¡*	’ii‚$Š šJ‚’	‚™”–bb	†ï$”i&ˆ%(–"¤šˆ’h$–‰˜ ¤‰ Š‚` $‚`@–¡J "Y–˜!¢ˆ()ijª"E¦Z†ˆ-Ä&=#™£Y‘ë®ÐÖêz6GòlIÜGL‰ߟÿAŽ,!ð:â„Neé;)~I¶äÄüØdË㼸Y>éØÁ¦ñ'Eöý¿tâu"ʁä”\Ú©41	tƁ´9è*祟,®çyTÜÂõN¿m¡ÐĝÃæN˜îä€:•9
×"´ÀÐâ_¥¿j¢9;°5fœ€
*£¹'td1©õXÉÀl6Ô5¥QÆ}Ö#r(Nf¼AY–2ŠyTa¤xæO…¨ä.6T§(éáñ»£žåÅàœñé,ÖaaqÃ
pØg®õÉözUv	¶Ý@œRxÉ{û $ÆøD?Hj<DöŠ„“qêpVzDPõDê‚u9%ƒÉŠÒ^Hÿ,
>ôžÅw°ªŠ‹Ø]˜{à<wAQGµwü1<@ÔNJcdà víaö'¡ÝÞ€íÀæ)äÜïM&¨<ÊHªÝ>®Ãhå
ˆS•æÛçホ´q{Z…Q¡¨Eæë`Ë(¸¾£L4zÕ§°ÀìW¤…Yá}½Ñ@~N¶¹Ìhuz㓱žƒÅ®:{'S%C‘ÈIŒ`:	ã҉ø ê@JH(kq‚,¼à_›Àãaà«ì;äCÒô‡Wížø\µ*¼„åERpêÔ4
U)¹±ãf–µ3
De1ª
·_êoû"Jî)č¤ÖÌ0©s‘W¢©e¨ŒåÄ5ð@@q™™UÕÔ´Ñ£¡T&apÄBä”>gÁÃœ"9“)‚£r ÁÇU4µF‡k\!æÅÖç1.±C
¢ߎ6 Ì*$Cm-e3™04”`˜ÁC$åÝÇ@n*£¿‚kTI<7ë®Oí	™Õæt*|$u0Ë!bcD„@lÅs®!êu¦îºæ%ùÿðFí $™(ƒ@Òy
äS½ÜƒžßŸ}S£¹8;‚ˆ
Q£!Õ(4RÎÎÐ}îDã¡eŽþ dxˆ+†€þƒ6‡¤Êã¡Ióãà$‡¸Œb]I{ÓÜ¿g½š5C™STÊ>Éª¡¢`‰"º ‡X
E”¡ÚÆtQêÌЋaû8.iêñP|¢m0ftÆÈ1»z9Ñß9’ƒ=£L¤ø7·…þ³µù2Ž‰Ðà¤}›ç˜>
ÄýÈAª2²9˜30 B=s™Uý×B_Qè•"}7")\f;Óµ!	'f:C’í¥Ê±Œev6‚tðÏhƒ¨f6&e;ÀÉÀëÂ,ó6\Äm¬kˆM§
†â¨âwz ¢ý;ë"uœÐp¶Bf¢†G„
$“`™o¨Å 2Lq¢
ÎÞg…6ˆhàs<&&Ù›M˜àó*¥ÌL’@m¶ÊiÅ’²±¹12…UxjõH+
¤)Pƒ*r©ÍË^d£EÝTG1§hC¬\á&}@=
0ã
]S–¤Ç3ñÎâÑ7ïî <dB!ŽëÆMÍ׃ǘy§¤ç>zº«O¦ E"fÉJÁ%6F~ˆã	ÀÇX1Ü~Ž
Ì7hª9!œA¦'QPAa¼l[y€ÊÕ„2ûôaŒ!Ã£hg.wr
ñÙŠI¸lhÛ
°½è²nÎ(DBx-wG Òd”ÀŽ3³r|¢m1OŒ/HdHtƒÅ{ÀGEÛt=vú;Ò:Ž³‹[Å0lžÇ·m?—D!PIBH¡ú9¹Ž÷°"°:cȁ:LêpOÁøHð-‚ƒ0¥mªU‰±ÆL[Cç߸¾”ÄÂ[›
Dé FÆÆÎFÛ¾‡Ê{¬neo	ò3¶§½I6Õ™«õ¦é¾…¦úÿ踀I|ÌYÍ*
U¡C/ãÂt}Äϧ‡·Ÿíx>(˜|Ã;ûˆÄÜcLRÅ ÁüØDYe'ºÜ³¨Ïdþ>°òéb’¡
?©T)A,‘`Uªc³€œÖàÒM¡Ãåñï4ÚH+5¶ßÆq"Ý''Ì‚>š
1€?2´ êˆâaNÀû ývò7†Ü]ÅCÿ„
ÞÉOqy˜¸N at D&ç#YÜA0<Mç;D°KJ(p$Q•¶F£4I "È¥·†_ˆÅ¯Åì:
Ÿ#¾ž‚N\G¢‚“ñ†'Z{Põ0L¬7Û\p„ÀLºCI4Ë2LˆúýGAÀbJ¤P`8sæN> <?Ô1É_§†|n£mâ¢b™¼Pëh¨Äµ!¦>÷££¨$Ÿ2ü>Ø1÷AÃûO®*ŠôC a—m©©P?ž{òûôÚÄd=X;•À‚¾J%	ëPCFî0ˆ>Âݧ­:Ñp0üZ
…A
äô²A¶.Ü<cC“¹t$E#†0‡†gVª#E0q¸â¶)2WSˆit‚¼´Ó(c„×aWÖpl©µ¡ÿŽç*€¦N$Û°à ž±,u—LN¤$©@bR¢yb¯W>ZáAKЍ¶?€C…Û“€4•ØãúY‹F
?¨tùª
ÑŸÿ0ÐE£1j³WÝp¸þ{éþdªš£ï0w€²R‹Å ¯ñXq
DÐ;ôd1˜òy
ë؉mÒͳÑøþ¢_¾7ù/}çSñôאÆ¢Šˆ ‰ªª(ˆ Šµ÷ôc
ï0ÍÍýv¢†ôsü h!
*‹8!
-¢?Ï݈)󒁴œÀG|
ŽòTS@æɃ©Hœ<dbVJD‰&I“J™mPRÔ9Pt‰è@±>ý=ïÀ!ãÞHÕS0M¿ïÁ./ KÕÊãÓ¬Õ8/ÂN¼x_&ŽPÅrA`SW+âëÚ3‘Œc^‚þƯÔ{¯¿§wgbZ+\Š’„ƒÈËVeHÀ¡@ÜX1˜Ô2I‹˜(ðǨ€öZ
:DЧë 3&¸eˆF3äâ,[ƒ(ŒjUÑ߉Ä@Ü‚žò
p³Ñ¿©³Ýõü×F÷¼“Õ*+G´Â`Ñëf™ZrsÎd´cŠAÍJmþGOoC›W:¦@”y“ËA¡šCIyÖTßCKƒŒL«’ÆÈñŠ‰rçõ5o‹
")+
ÅY>Þ-M,ãw<S@šƒæ‚ÉN‚( ¹ÑѺÉB˜çé‹ÙQ„?r³©†’F0â;³ˆ€ðæqq:³:-[Nˆ÷æíæÒ‹Gìö2~°Ql6ŠD.6`ÒGGE£Mëè- âiß)káÙ"83Zµu–Û¸1˜±/ç„T
2’êp¨ùšð‘l at enƒMñ¸î4©8¸_Ö”†š tj]C–S!<’3‘KY$7õ^Lî`›ŠÈ³z«•ï7J1Ÿ¤}_ސ:ĆüSR ¤$‘
D
3_Ã64
DàÖË
æÁ—Z',U—£X; 4pÑÁ‰Ó*Í_Zpþ®X.ç.<ì€ Hâ(ŒÓ£]3µeÜòvl=Š]';ö{i†K–⤧œÐèÆÛOCéÆk¬ü=ÒtBð2aҁˆS´Q at fã3*#ºV…è
`lŽ~&¼†ÙŸzn=‰M½
ÐZ&–¬€ÆÙºË
0#ŽcFú~Â¡„!O_.¼Üàil#À‰ŠIˆc1"?L
äf7xU=$D'âü›€òô*§††t1Ï=É<àe
_¿t‚uħÉP$%d-F¿ì8d:ò™RÊG©n©€Ÿ…–N¨÷’ƒa‹ùý@rÑÖ
÷@<zSq½éÙØÒ5E»ÌD$:ŽU
­R—†d&*)Q™) €€H$Pˆ†„‰€$˜‚B&!ŽŒ½öï~X1¹Ã2[kÄ2‘Ër5 ¶ÖuF¦Ùªf
ªÅÌXqpƈÛ1ƒ3‰ÊjIÒ@)CAB%“I¡Zh9€&+˜ö¸KR‘LAO’Ð]2å“¥IÇôÔt”¥ÖÏ·©Úp(£õH}{”¦L}QùÄ áÏo›ªü4u"jÃ^ùêñ\YKSÓ¬‹tgU…¿L
€ëºPú„ ÉŽB2˜ÈGœqXЩÐxÞQø>EL‘[
ÆÆ_…¦B…lƒ‘¯B‡ªŽtjK¨èšÓ	V<dl7$’¬€pƒØ0BØÅñ{aB”¨\Nr Drt†çÍ28ºÖj©Håt=i(4W
$rø0¬ü'-+¦>¤èÝÊñxhL„솧èf4Æ=f{ti톚8LIýÄYe;4ŸD+R€„~ˆbù9öx¡÷šI€7¤W£cŠ|¤ÊBØJTäÑàzrí»teʤ¼VûÂ7Ú!2{ãrØ~¦qÃ?>Wõøa¡8
âsÓÕn£Ý›^}B‚ctÀL‹Hd)7„’2éÎϏ/¸‡(NœËµ(¦€‘=Üóñ¾Ð~ð³Çé1˜vòRÐ×økc"ù)v,‹ú20»«‰Ðáb

LAJLyþe³—lQ@j(&(»
àfPÕ3+I¡•0¦rh)Æ>œÈCʹëÍâa9¨¿D%.A(="'ôÀîFÙa?1"H¡ÚGè莟qá%^î&·N¦‰`÷ðÊï 4AWâ†i
ÞWòM7ìjD¸Ãña7§2ßZÙ²N”–¤´<×
Y†òê=G[M97³Z2²-4ÎÄ>¦˜i®5¬’
Ù±²–+‹úodR`2¨¦Òˆè ÌHÅGSŠcl%Ð|wŠ—­eäW8dì«Aé(tQr[dÓÆ/
Ù»®(ïΚh!u®Jêi‘©Ü’Àó`ãFˆªÆç‘!œX‘¼Ã2Z“sEâ̬š£Ó2BCo5:X(câ™Xä8d8ŠÑÂ1¦ª‹£†›ÖÈ™qfl7­°zf¡Ì-Ž<¶¦G$j7
˜Bݦ±£`ó]3ËpªL@r¶œL›Œxà[ZOm6)…Ñ(m˜Œ9 U¸·b}¶еPpNMkÇb$”{Ž3ÄNÐŒ\=Çv²¡³ˆÝ¥eÛqd°$LT {©r†P1Ænm èZÕCÈ
˜ì@+c¬pÁœj€ñ¥Sq+™Ž:ËX†ùÕ¦oj¦EŽÚ£ÃR-Å„&8ž-Aµf&x#1pên¦÷î‰.£ „ÇUꕦœ¯)¼"«L•q•­šsÖWŒq<xbägQ©P8\€Ì&MvBcNrŠYhqÑÏ'ÜUPès£Læhå§/c!Zν«$h!i¦Ê`åDV½ÝÓ4!âf@ •+ÆaNš¹ ÕÄ#ЩÆÉ&ðÌ°¢6AÍ:Í=‘ö³1‚ŒCSÑAm=F˜‘¡†9á-íµw‹­£‚
b-㈁ ‰è“×›¿Lp®Ìus6±Ã*ˆ(wXê<aáwz‘à¹Ù
YÕ
œB'w@Œ²ðXŽ“tՁ–C‹ŒÇ/ÕN“X¡“´r»	´V±âB]b­±`I™\Z)¤éBÙ«2 h@•°4ñænA›lÆ/6OZ¢ë²ÍuÆ#	ÅÚ=tðèM/‰¥«åÿ˜Ù'Põm„ÔŒB0„
5>÷X>°û…Hš£¸Y|žv[ÜfÜfypá¨(L at i1¸c<Š<üYS£F‰YjòB×Çx€{b	²#NB‹¡³01eä!Ì&0p¾^Hõ8/}&_04DIÅɼg	!ÜðŠO¤•Ì!Ë
Ãzuž”œG.SqÆ¼lËSƒZQƒcá­4©)4*=Í:ÚZpHH™Ë®lÁê!)A¼.Vº*f=5&’(—:ºFy<{Ó‚Òc+U¨Ê„F™*0±±Yò33F‰–‹h‘„N˜Ÿ½‚—ÔÙŸ¹»ãd*Â`=9“‰¦ÐÉËG¾w5m–®òò
½®ŽV$ œi³f2e­Ø­
;\–|oƒ-Æ㣔pŽR
±6aY–²¸†HÖaÄ2õ-ƒLM€ˆÁTàB¹Æ•ä ó‚ŸLhB‘cœ­oSêósÊ6(Ë	2qªq€cÝZªk,òe%èã5†ìõ¶ùCÖë!T,j;Æî
(ÍßD>$¦–·ˆaÄ©ª(*“°èm²a‰nV%hK#ÍRC# Y´86$#Ò¸Œ0„q ˜y	D„p1@ò²P’P!æ0z¦L£Ò¶Tè!p5y<ùí91!Ø3æ:<Šb8cpDÕ±
ØØ&"9[–R¹“Y«¹í9äà=¼°.i%SÓÑfg‹'€×“Žç²`0x%T°½Bb)E ‘¶4Vò.¦Q
Íþ®t¥ÈG›òÑË	¤œÌmx°\2îßùxù}€â=HSKßïÂ!ïÐB d\0¶í³àá¡•tCè?//‚JWÃP'3Üž9	k4@"Ð?ÆÖ“Ø!Ë•ˆø
BŠ¤fˆ 8ˆãÔõ¸uˆ»JÓ¼Lª5—Bs„	˜Ï¬±±X	e‚ƒAÑH4ÂòÜ«d•ÃC,õu*b&&: åpþ>Ší6R„¢6PÐu;éÒò:ΐ:èÀœ JH‘êИÜãÑ
wu/:À»ÐuÐ V:Èæ.ic®`C3J¿Œ%¢“\8&M©läÎê,L!¤nß(‡\
(9i£ÕC˜I‘í$	bˆ”È¶I'
iŒwoLļžìblhÚ[áï¬v‚öÜ´dT©QRR4‘
¥UUR")J”"ЈTB*R"‘
DHÀIL1T4ÒJ1
Œ	€ýV†væè±ÙàδÂ[hR
Pe<0×èàyöÂ?1ÔQEQEQEQC­¼÷›QTêB€1“œþéÂ
†AûmãíÃpICCBTî{;|Í­{#àd®&÷Ôè}á›üOë(mMô-ÞJ|ätX+ÜE~Ã1("|‰zd
@ü]ª:$X$¢@”%d e"„ŸS3(ʉ!€À0”ÌÍQ3C$PT„KLD¤DD,TPC-Ô4
¢¤‚|Sã)K Û*Ÿ!Â÷çû²'„¤4ýrNäÃB`åT·ê¹'cÞÓ©zGÅ<
'*³æ9¡˜)½šˆÃÂkwæZÏŸ7-H´Þa‹#5`ÙFªÇÙˆwÉŸÍôñêÀ9‡Ñåê—d)YO:·æã¿ÿLÛö ï0ï2óWaÕÐ`1뀊!¦ ¡b茓òºu*Pž!!Úq#é©HUÓ˜6½+gBÒø©@ ~‚ÐòL-9@]²gWöâú·EûŒÄI>ìí
YÄDü©óç­äA°ðòCØ4ýŒ,0,tÒÀ˜‰N™¤{çÁØpêeÜñV/@†šbÝÉƨ@uÔΏK7O¡¨Dö>‰¤û!É ~|u4–×ß:3(]R×g0'žÂJÂXl± CߘiFÁ¡±°f8èD;ÆN‹ÑôCÜÛbäí¾SžÆ=x»’ž#E€™AVso·%eI0i4¶’©N ±©h„… aˆ@Þrþ
|­þÙ(MÑO·)‡
d€ˆƒB; Žp…Š
Ê
–Xt`£c5ÎeàA-4l†"@¹Ðl at hÐØë3=²	ÈÅËœËȪ¦˜ºUhºX—¹q-%D¥ë ôH¤ö±¼3'à“¸N¤-Ñpx7=¢ˆ€‚7f`qÜ\%îù½v,h‹lBYœ	f6pŒ€€q =
lwÄt–	ïdÄSlÙ4&´0u&ž)Œ	‹©¦Y‚”Q¢f"P  (AÜÑZ
¯|>ƒ1O)H!â00Ñ(xÇ®9dš7í?Aðw?_{®³Q
Iɲ†S:fÊaùyÕcÕ8R£/±ˆ}5Ž%úÂ/Hå„#Òm¤8í¥ˆ92ä%“žï”<$¶	ϧc9×Ê0B>dCGÆÞw’ˆP ‚$½Æ"äm“k	ŠÓ;‰’
ôa:š’¤ˆ†.ÒNºd³RÈ»Ä6ƒÍ‚uUÎŽƒŠB%{=ÆÈ)Ò¤Þ|ØoÿÃÄ( ½#001TÍö^BáÎ9ÃÇ9–òäsÈQ){‘¸2ÊŒ&h`(ö=ýùÃ$
Æ°<‘jUÅáÝS7Bää™E.´ÅçÄÎ&âÁ¡¥!#w]¾ºë12pàÃJ•Hä¹è»ƒJ½ÈR«Ù*ñë
¡˜†€™fI(";:˜B¢!BETÄ_›5OÖn(ÚÈ&VhÒj/NðÛÖv©ü¦î8.æBX,®C8ø¸ó÷ÞÊ*þ}¥Ã&âð®&òáÊ¥ÒhÐh±€´AE°šbCE	† 6jÆÊ¡­¥ÑAUÔŒ&LÔjò†`Ž†
D0’¸l=è¿æ)ø¥“¬áTÒèt€£ê”\ЀÀ§`PBÁ©ô­‚”*è$	D‚UËÏ>XQ©‹
Y,LíE:`h”> YTAA…{¾àÙ)ž‡Ø· VyhPÜÿË«æ=X" ¼w‡??3(Oˆÿªf ´kŽ miê ïô ™„‘0úIR© o‹Œ~A£‘&0\ÌæH`Á<3Žh60ùæ~÷<‚Œz‹Œ®!;»„GCTÇ‘“Qê同c(ƒƒ¾0±=¡SÇV(ÇpÝÆàGÇ¢ÒxÄ^'z×ýÇAUú‡<]Hm
'd“ûzGmDë$‰˜M¡È_T¥Ì¨{Á
¢¨¥¤&hˆA)ýAçþ'aàíÕü0Ó¶
A¼ˆ¶`bh«¢‚ðûx`¹€”” qå&¤á*™*'8mÂSÞeá(D¬Iü’⃣Ýutˆi¾Øy"Æ?$ǝt³A?‚ó×IÈ.±¤yÛÎ
ÌQÞÌ4BB at K*´JˆžÙ0SìÆQ "r* ¡™f=,ŽÀº…J$IIÒh§l‰Q$Ó"‚MoûcÂÈ2
]ÀmÓaª
Y„†Hè¦÷')7øo¬,é“çBp€[aZ+àdŽ@h’©R_KXÒ&E‰(

Þo8JJ3)[‹džÝEÇdx\൒À>ˆ
æC£‚;ãÂ/á“Q©
¡6Bj³+ñf´ûºÑì)a
„ÉYAì—Ó()c€Ì´“)ÉB¡A at EÞ*]˜&ÆP¡âóB¿DÁC¨*œœ‡ÛÔ ¾ø"4HG¼åÒ|%äëÔmý'nm.6À>cb,W˜¶î#÷@؇Iòo¹³ÿ-„††H•+â›0KÈo‰ë~0Bऍñ ü?z}…XèpŸ+aGZkÆ{ljg•Ø¯(HÑ"ÄTªIï^O@߇ï
_¡Û‡@Ø,Xp‚Dj¨Ù
F9þ>ãGT£CH=ÇÅ(ßÛ¼õ/yÃfS¤Í¤<ˆF?þgy¹f’_Fþ	êë>B‘Œ~>á4ì}JA¹ï6µáÌâ€Pº~A|úü!FŸï˜ï̤ÑóV¾1A£Ëñ[·¢6ÕõÛciƒ Ø;8ú¸#©äx£è
Bˆ(I¡ë;cìD£“ÑÁ‰#óL™G™¹E ì—œuë€ið}þ	‰¡`bko/št|i(ŠÃkñe(<Ìã@Ž͉´1¸Zíš±H©*‘6­	KŽ HR¾$Åæ|ó®¼=uRŒON“^qBâ¬`+ÃNƒ`ÁîZl§>ºò½™Ó.¨íŒÌcc¬y—“IÜ$F!ì";Ü‰蝝ôtÐ@'˜O[.”Фþc1†ÈA96–‹!Öpë3kdF(†Ñ1Iͨ)'¨ÌÆD룇RÜŒsIÿ|4…
VvF'†’ºÈ¯\¨æ,º<A´é67iÓí;‘Oú7¨uÔ©ù?º¢¢¨¢Šª‚Š˜&	ô=%$vcŠ‰2Âi(ÿÑ™O
ÑÜæþ¬…RÏÖê—ÑÌre/¿…ÔSR{f²@ñ¥ AÝÝdHiNår=,†"MÀ2ðazƳ×ÞĤJý}/ÊR	B„¸úqõ†¡Ñfû#Ñ
ˆŠàaÍãœu‡†LžðHz˜ tˆPõ°§PÚ]åáÆÌÖ(eI«ÊLœÞtn]¬ë”M3I04̇rîÅ	üustY´—ö@Ñáõ D((
¤î>Æý á	øí$ƒxgÂD¡¥Íõä©6ü¥%ˆ4ðe“0%XÖ YdEvÅýcþÚ+±z,•üOÍüF&õƒ¹("GÊëýÄ‹paó.”>Щ°ÙüáQïAÜý'—Zþ7ÈÜä
ƒ†p&ɉƒÐ©è'½‚Q	b	©L¨º-ëêã-†´k©æzƒ€†’
¨²~1Ï?Í‹Òsý¥gJÔ+K¶š»±SÜ!×q ñ'ˆ;€:$Ö8¹×„ö‘	œÖ^2ñíæ‚Kb)Ñi¶!b4i)% sî{þï»sðÞñí©¦äŸíòЇCöþk_gï]˜o~L£é
–i‰¶œdnª+#ûòiˆ(¤áÐˆÝ ËÙ”˜’ì%Ÿ1à~ÊQD͘Æ;è–£—äû*ãóÁfåkŒÁ
4W¯öL“–¨žj"‹m8ƒäèÈ€Ä. †ƒ‹¶!±°"Ù+)j|ƒÛZ$AÔ8ø3kQïc"‰¤p6!PÂ39AíCô
™­žW­—2yM•#ŒšNGkòɳ)ÊÎY`Äs‰$‹M4&*‚Þ¨P†Žéa|çq¢ñ¯º5LÜãã„ãðò8Ý֥戼cGN6=…R	Î$;˜C{CI¹E
ñ½+•„¶!”c!C5C
«gg+e¦6S±«KEP›¡„–°Ê´u€^	ø ÑʘØVQ•î|Ã-añ³Üœ“Æ0üš§_c¹óøÕšÀŠ¸Àåã°;º»™7Ç=HÔdˆ ø²
[’>CUÌô‰‡ÐâjR–µRŽŽN
heRNAxR¦‰ôž¥:ôùŽ}o'S¦i ŒMb‡„â±òÝ–¬3œ°d0Ôæ–›“Ç]õ9uÄõ¡(qƒ”ˆ	Ò{ù
ûBQ7,Ê‹ 1iÑS÷f‚ªi	*?ãÿ·÷Û…Ú®w.¨éàX,9D„}Ä£
R["³_â”@˜€è¿ôÙy%$Ê~¨zá`ÐR$0tŶóÌ‘B°¤ÕU¦!Á;X:@ç÷ü}#Žóü̧‰L	cÓÖ‹¯M¦íéxž°Ö6Œ
°	Þ•Àø\·;jßA„Q<± Äí|ø]>xAÄsŠ§"kLÐCÊû~ÀDó
ïÊz³6g°•¡)‚`hˆFàÇÀÈÐðÚ%ÃꙈq­PèÃHÄãÊ‚È.`”Hóùïb;ð‚{c¥—¤óà9INäe„yÈWá&šMd&ö°Œ§£š²á?ì8Ðì2Öͽ[ ý 'NX{Ñz‰4bj, H at m‹ùÌRh»|ä1F eÙ×@=55.¬K;È9ÏÈ”!Ú2Š½ÏàO3ÒÉ@)B5ÑöhšíQàˆ=ϧýp`§zž˜ê%N<&9†ù¬H2¤GÜ=±¢ãâº›g€è˜uþjS	Á®ð×^à†~„57;"‹$e‘L@äùmÂCÿ)2‹D¸÷J8·Ç	.üÀ@€ ž)ϯLs(ñŠ„b |¥žá²£ÿG¡ìÃÀZ‡Ô9š‰Q¥ @7c+@ÈIEF`¾¦‘…³,p]áQSÈ3ñ«JãLN5üÀ0ÁÓÄýø0C¹DçŠq$v¿«èòÜðÚ©lkbµÏˆB…ñ{VÍ‘0ÚgÒ]X} êe°×Ëmreb®wɈK]„%$4\øx:ÑÙ]~"°¥>ëÝãôx9Ýp%}&<=AÃZš8µ»]aŒ£‘„Š!&tL*MþïüiR¸–źÅ"?š°ü{›êKpü úÒLä1þi8öïØø<	…‰*BiHóå&~Ìc¨O¼ö‡™ˆ$ à¶(‹â"'É'Èh!F†3RDÈÏiaž¤@B«ŒADÄé(iá)í+9Ñd at nƒªÞL&H'x=×eDt_²üHkGo–1ÍA6ªíûÿ#€M‘
˜8Ób3DKëîÃû:3ï@òkÀú…î4øÍ
‹t3DMô’ºc¨™<9©´zcÖCAº5BhŸH	çr/ŽNf,M¿Œ:²‡ª.€ÏLQ},£î{C û³=`7 ÄUpM’	ìŸôã…ð/¸ÓCéÄsÒ²§O¼ò‡l<ˆD…š„"!Ft,lÂÀìníã2o6Ü”Œ“o†ƒGsߏ¨)D>"vüØ ´*é‘•¬Üya흅¢ÀÃÊ®¡ÔŽÞk̍°a¶µÉ$ŒÅ¥Ü03Ù/¿IÈŠ2<ÛY˜ža¤Ô=²õ„¾"ô=dç=Þ/úaÀ7ÇÊ*Ã0á®®Fž-kO(·n•ÕîìŒ<窈;ž~E$ý¥üò^ÿ‡Çž.k˜Ûº…èK¶Z=Ùs=avIÌE8qÓ¾|ÙC‚ÚÐÖØRà˜6y—@ǁ!!=CeùÜ‹¤LОb€þ¨Sßâüèµ¹b?ªôk‡G´tEEvtu7gH%š¾o¦ª¨Â¬]§(;Xzb‡ˆvHbfG™ (*"‚”Ä'ãðÐ÷J",|ÏmYÏ屿Žø+ñ¬ò€o²ô8|ýM‡ì6MEɉ=ÄI!; ?¯j4¢×Û¨d,Z
–° T#ô|Gž1+¾‚ÇÇY3ˆB]"½íŠ5~BG@“Û4PÊ3M&¬<©†fH ’	ÑbX ‚ÄmTn€È‡±~ˆàÓ³¼ä‘[¶FÈaP­_ê`«_jzkCX5xrCKº“¨x‰Ð$Fº
V

ÑI—‚† 6TêC‚ÀfDP@,¶D
qÐÁHö.šš¯]PäDKr£E`2¦R‘Rƒ
£&ººYAƒë-v¦HØ}‚|ùgVÛô”Ôõžß½È¥=ò¹–X”µsƒ*uߧìÙG«ƒ—K¹û
jÈ’¸h¿3+‰²ia-lzkhÍàpo‰³ÚÉ`ÑAñ	Øòà”…6†—L;TRâ@"DZ
¹) 

	A0TEl^LK<HŠŠ(&"Ø<ï·tª˜®•âþ±@Æ‚E#ð\ÉÌ

‹È"‰¾
ƒÇ£àzóÇw,ûò¦i¼ÆÆ÷ÞŒpƒÐl…A@ìãÖÔ1T‘Î2© Ÿ¶z0·˜E4 Âž5FÈ4ŠD£HtŒÌÌb<œ8\:š¢**™b5ëyØ&†–5Âà4–&±§,×lÞÔöSgDcÈeƒÉ1u6z1Â'’B†cA;¨ Ó1šLiQôœÀÇ
Ó,K…“Õãã‚Q˜bÛECNŒP3Áéž4ò4Á$ÚÒTdŠpÖv’¶É6Ù ƒŒØ͐©©ªÙ:–ŒÆ÷ìG}áþ1[‘É(Ššq{±KÆŒFô#ŽJc[%%Ë„ò«MUpôç*"‰¸`Ä’bzÎhƒ`OáQ-ËLuŒhÁÙ60ï³:3æ×pÑ›…Œc1H1ËO‰Jª
!Bѽ¹¢ìlO{à®±s ³¶zœÌâŠ!i ƒlXc$A± éÁ‡›k˜SSJwˆÌm°´¨Ö%`€cš¡Fáh¨ºÃA¤Û$CT””l«‚ÝŠ¤ÜٝR¾dp\(‹g@Ô²I’7phxu¹U at DQã9Š>Ìèí4lÏyñtõÃn¾Á?”ŸÑ?æ¸u½„€B9o0ŠJ¨p¯£žørçxDè 6{¿1EÍÈ…YLôpí$QBÂIZ¥Ë8	|ÃWà!-ƒXŽRÃyyhí"ÂÔ˜I±¾9™Lȇ.xµÙÈÖðÕ!'ÐBãBÔYG:ˆˆh£ ÔŠ&5ÚàkA
Tõäç‚	|¸ÎŒv¾ÄÁŽ­>V8J²fZš²ÞØ»)€Ç<¸#O—¸i¸ÜPb$ˆŽ*iÃCÝ­ºÓbÊeCzæa•&0Š±@`D–}®êЀ¯aÂ
uRsëp£| iÜo«2gFc5d9ÃF¡¥·6MöÖf‡ÃUÃ$á‘šq®™	'apŒDÇb‘¦”SnµgP™¼zŒÎ\ÁX`ÔÅi9„Èڍ¤Ù¤1F–í1°à!WÆÌ‘Lir‘@؈K”bUoDRƒiŃFÌäqtÀmÃCBqPƒŽõ¬

ÖŽñ.MÐMœI¦œB‹³•¨k°ÀðM\>ƒ…{Ý

$D£“àÞQëB±Ñ×Bt3HNƒŽ”L†ÝR•pdÓL
ÖÎÜu‹”Æ´„4ƒºK
vÆ-JäXþÝÁ's@#P)mÌ„ÄY<Ì®‡
J(žµQŒXå0¨(b˜Š<d©²e*¹]¡QZ£,£õ4õHàЀԊ–³0BâAˆ
L+f?v÷È

.Dî”ÃFHØÛ×s’qØÿ‰TÜ.Ý©ËäÿߨDЪ:îO`@ÇÒºö¬º!p/ÈÔkêžu†¨6€m±~ŸU’d]1Ž%Yq˜Ý±¼b©<€ž@#lË’`VÙm]«…Vá$­maünæMð‹ÈŸŒ>Ñ"=õÝ€
`s5ÃbæøØwHlùíNƒúr›Oð>8±4V$#ü³Ùwh~'n8þIwùŽ1&1€ÜªŠ»Øª*€âz¸-ǃPK¥ÑIwW*«¬j¶7ÀRÑ2Aì«»Jš.Í‘?láºD	ú‡XL×”˜œ1¡	
i¤‡h•
d¼æñ5îI8ì&7TŸ³8)­‚Ãß7fa»`u*ŸLP RÆ´3DÅ5,¡
ÄR!"~ãöë~ûJ=Í%)žñî_Nz˜ªIuRS5‚p!ìž,ài­›pÉ0
ìhê8ñMPæü—:¢z	z©†b†Xb<	Œ¤CÀ‡Ëyˆ¿Jý0°.LbãE	OÞŒîpäöP”%æ0“ÂDò<E;9Ï;¨ê>]³ÖïŠ'…LÕA²pCÀº—ä^ďg;8}$RõÁ¾{WCÄ‘,	‹ÛË
rÎ$'Ô+ôÂ)@B©ÐJ'š”ÁT—û€ 0ìA fÍ™	ÃvǐH^ô%äà'«râ´¹ø:4å×Qˆc³!0Cx:xòÁŒaßsæ|ùqØ`ëÆÑHR!ïÓ‘¾¡¶™"÷’iÙ\ó¢)`#DxJ•YÔŠ{$4°‹¢ÌŒ@-&—ƒ‚
%¶¡
õ%ÕUP«ü¬îA]À"¼—±63æ¨nƒwíÛ‹ûi(LT4Pˆ”Åâ¾týš6©è'*$èæÛÖ‰ü2¡þhQÈEëÙ÷¼}£Ï)„jÆ	
4ö©py L#¦½»ç`|ŸF".ö:ð~c†éC@*Ùœ€Z˜úyô(+	ªu.–""	%„ÆL ’4*L"’H‰’L @’+ ui‹ɵ/À¥
ƒ¥(‡¹*:¦ú¶ÒA1ƒ}ÿ¡@9"”«BP‰Ò°#^¶Ji¡xn:X´MÛôuž´ð‡z¿¦¡B˜’…BgËÆ<
ø~êNÃ}йŸ„–_ÜCQ°v,‚øˆ©â
àì¤ñ©!† xù¥ú'ßMŒ4ái~B‡Ðþ¦[<ÃM'XùŠ
lHX:¡Jˆ~Ï×XîN 
4	½ÿèë éeÞ½Ðd
H—Ä&BRbfH5ôNeˆ"H¢)(B"€àI¨wC¸”b($”Z(ò;õ?YߝÙÂìà¶Ñ©ùT(† }„R”@𝟋ñóe*b?fÄ¥äàvŠq“štõEÁ­·!@XÔ²1÷£ÐTíDjZ®Z`©¢`¡Ðò70 dœC‚`’ÁHÛÖÀèŠ.(–
ˆIb¸1’Z*‰¢(”ˆqãr
dcÚôä-{GÑWKJ.¿e4ÒSkÂÍTWŒÜx&¾4´µœUSb"ÕëlÌÇèÔE¾MÎœì\`zýýI¿ñí•žp«¾G‹¬­_þñː</Ñ¢DfÓ5hrÊÁòÑœÃß,ùÄ“Ñ.ZÿN'¼9løvڝü¢ÿJsåÇÍ6rúLÍ;›ÊÄž–ŒI„f‹„ðªY ß‚ïG[Œò	;+:yt<ºoy õžîÆ»8€¼h¦àþʳ†(s‡HJ‡~ʌʻ˜zt:I©’D?ý–£î¹·åõõ88ìeÜȶ$f¢jŸœÆ&œ4¨_G˜=:Ü”WÂx—†UØÂc¾me¤l½²
‘yòuÊqÇpÆ3œ’§èïó	7¥(ëÁËä,;aØóï͉^ÖS+K·àþ†­Ömý¶àõºf¶jTåKgGA—¦—äƒì"”xÖÇC
FÓšˆ×¤¢…“Ø÷9–÷b—9¦¬æ18Q‘V±Tp¿mÜçsͧf̓éDý‚8U»rÝJCŽŽº¨‘;Òs¤ïTR@ó°ëy0¯V±ßox\ýý#ÃÏÓ‰zRüþõ+¬s[xd„ˆ¨q¦@ñåþ{üÿzKh¼_‡“¦çHÎÉ%AÒb‘Ôƒå·0¬^2Uô?©ÓL›>BõÃÓjV Ôm­g†S]Ç…K4Žïw-…•:pÖ>L£À6a@³dðôRiG(™qŽT&p5B{îï0eJS¨”z&-2Y<;a7áÈ#fŒâ“#Æ<@Õ‡aÂHÇ‹x’Øü黝óªgÓúkZ£À†ÎŸÃàæõp²é¥Ë~تÃ\žS]$õ³¦ìpz4JUuø”·Œû+‚Ðz(míŽüt¾5SLðù-&A<ü´*¯sŒ÷0ð±\!ÄÌø&¯Zéõ²Ë(Y’Ù9tBlÐåy;Á5	·‚Zœ>ƒÆK=¼˜¼hWèœBÑÁIÛ»©b¢:ËâSJ
	¾gáHŽ¯+ÖXݼðþ0hæ‡Ú;lj×äY´uÊqiž~:b½þt™#1¡ž#Lߐ±©è°åò(…ש½$›
­ÃRí‘HónBÂä~ÈŸÇ¿G1Ös´¨ÎQÊ(rh9¡i at .ªxî7NbÜ’zÍ”	š@鮏_:}»1¼tñ5DASEñŒ” s[;³³šIÙ׃§çD7Ø°“™e¶tçÂ<XøØÔn¸ÂïÃkÔ„·À0jB­è^Ëef¦NPÚ‚(û®9ÔùMCg¡<ç8¼!Â'7ZM*àå;¨ìsÇNO²pÑ›­½Ú8ªéHã²ÌóvÃ
(ãhò‚9+ÌóuÆ—3½P¡`‰mÿ€·×8˜·*œç‡ø_ëZ
ƒˆX•[쨟졦%EuŽ„,=¤çÜï@h &]àWjQlêàBZ-æÆXÆn>æ€æ–Û³³¡ 44†T—D0š9û”YbÛ¨››Ô‰TÈ*Õ%ð]ÌzDGG¬&J¥ŽQSŠ1	˽UÑ‹”2‹!5bÙO´7røïÇ„§30I2á”	»Ù¢7R}½}$×1X,Ò"SîóHŸĉÎ?í‡ä­õÕ„&Ëlˆd©&ûÉêv²‹®x—xcAbcý¥¼@D‡=Ž)]·ÝÒT™©…غ$t @Å\÷g÷ó³vÔmYj½×6…F¡
¬n°bþ‹Ý9ÏÙ³Ù>M÷ŽA¬uJ!½Yês£)Û6ûÍ­È9
É!.fxvºf²nbfS$]Q3h7´öî`Fô/_Í0–u­B§/+vÌ)Ú‘à"ü†Hïÿ&6Ö£tp§’㐁F”ýEi¬¿i…‘-ŽvÇ¢ÜTã-úñJ9‡b
wu²}¸ƒž?¯ò?oïßêÖô0o'…ØÛÐmMAMæóu9Y0Bqü•¶Bµâ/†ªÌ{Þž
Ûâ[¶R’n"%Þ‹~ó>r	Ï®a¼}k“t¾VA†?çÌmm iTøëW_8ÊšùæñŠ~é†D?º–äv}ãÉGèÈ[#Æz;‹©nO+jœéëF=øVºC	Æ,Û¶òøU>Ët&©ev
2»}~ž¹P_ǯi í“:7&ªõg«CÄ­4ÏATËkKXÎŒö°‰|Ë/Óù†Ôdì½q#´.²v«?«¾ë%ØDywá¶>b±Mkïî”ü£ÄKEå{qQŠÀ¡(ˆoKrPHÀ†ò‡K†BüùÙÚÉîanJK×sNHí7º<|õÙˆN|œ¢x¬É\$YçÆò{ÐÏêhjvqü;{{rÍ>Yºô_Šw¸ˆ{ô¿±;ŽxWœæwÚ{ª33·‚(QrûC§œA˜½dÜÞ
î2ÔiÍüM/͏xÚ9ê7.eèNs‚@ô¦(§"ìíA
αЇÀ$«,«‘ã§+öt•‹.Ã
¤ˆ“ã&šañ3tÕ
6çÈí¦JÝ—Uš)¡Ï³ÆÖvÒ>™Ä{3|IÁ3&wvö~à},»>–Ísrß6ߦ½7Š&õ‚£§ÆeG¯dæ"é\‡n×ZÄc
;œ¢’7*Œô8ZÑn6k0ù¨Š'º0-¾¶}ÙžÞ1ÚrP©êÂåA«šx-ëœ,>*|^UJaÙbüFU„øtPéߘ†}Ldqw­ÍÞQ.%ÞOèåÒjOöã¬&fb›a¨ôŽÐÓÖàv4º†h]Ü1ûð鈏pèL.ßÀëÖÒHbÃÐcŽ|N*¢f¼a†aÆ#ªªªMl1ÉGÚ0r;P¶-`9$D>ÅÛZÖ¹±x‰”0nn†½Å>˜€i›Å Ýøo—I	q–ÐìqAŁbôî½8ñUUU¾Ã$„„!!²‰±6<ÇÁ·`äloòw—rIš;Ì]WˆwV†~‹àNºh¯5S—zëHFüJHê0@ð-¬°”
¡ïå¯óœç9Ó¾ž¤p­ˆ±(á$„’B¯ÝÜñßʨeUxN$lŒ¢H ¦ˆˆPç vÞKÓ,ñ7Ãp¡©"R‚x˜ž0[#¨[ë(„QJ‡Òn¨±¢Ÿ„üîIE•¢Yl
1¦3l=;wbÕ2J£‘C†iÆÚÙ¹c\³†0oҁÀ‘¥0‡.>	P--µº7ÌGók$QG½rÁ†
I©vã1¦®]†!½]Æ›§»ÌQT!ºxŒp¤Ï”ñêé/«Çv—ƒ><ð­’g»ò¿Ÿ;¾Äæ~0¡0~øNóç]ÕìpðÆã(ñœšÚË¦ˆÐ÷œqt-16ƒp’§ n5cѪƒ•Ýu¦S¬˜ãŽG9c„så†Ø'>G<W–ú¨8ãbLhØùbËHW¶í_¶)÷FÐ Iêö«î-@>&OÃò7Y­@†¸ü-ƒ{EOÓ²›ŸNÇ®7A‘Ú»)„©:sn³z§£NRt§±GÔÒ°Èzâ \Ì&dݱ`yœénh<J…n˜ÖÛø™À™ŒÔwi
EDËèÊc¹Ƈ‘$ïÞÓ]Y
”1´PµÄåú6ák4žÑˆ`¹|c4[?IŽ³Ôù£í̆
“FÏ6-eä=’ Ã!ÿŽù¢¡…
÷I
€ÐPæÉB/ÓëÎ4óp8ì8ª(‘“³Õ'¡gýPAÔ|p'þH`< QÎC”)òv!,»a(ü+ûá]ž”SçCÜ=PHÛð=„„@ô„ÀÀ~…Cb
 OƒóIËQzRÇã8™”ã„&kŸÞõ}ÿÅÇØ—* æEîÇQĬa¾ðÿÆ\‰R¿•‡kû ÃQõ@`ò~N
?‘“3êsöE™'Û§êì駝	Y4¯¬"œL¿q¼%P<ÉD÷žh¡ÒJã×&Ê>±&ª€ˆ¢]ý3=d~?5ì¢)J{»…h¢Uƒ8È|$*ˆÚ»
{=µâõ,˜óéQóÌÉ&~z 6V›D• ¶Q‚éèGš0¤	£Á"ڰιÓT@)ÉÌìáN@œãHÚi«jÙMÍô~NŽäeä3Bqtr•ˆSÒéŽnDddR~]†á4DC’r_‚cŒÜ"™†îD¾´Î7Fr”`7"HÁÕ£F^JjIdÖ‘æÂ}OS×øáô­@í¨çÎ~‰‰ç4ó,oðøJ-w´`ËØf!C&ÇÙž0§ü û?÷׼ܥÍühuÌðc×­AÓ 8~\Ú$ú˜*ƒc0ÑtïÐzï¬ñç¦P"U>üQ­
!×YäyÆá
K €í¤ó ¯7M„éLDª´ÙÁÜýÝ3¬²CVƒEŒ†6kJ`#€Ìú±ñü¿SßEV&W@‹Äå
ŸŒ'Xg¨P;
w(à¡ÅSjbÜFó3Ui®ºôCîí á·´"G ”ãsúöíQ5{õ; …Æ*"«" •Z.™¤ÌÈnps‰ÄÙ<âa7:	]ÿaÑúÿ/šoÛ™  	¼Fë"Çëö_4F_#¿~1è‚ÅSô&uȽܽ$§€ B揩‡Œ@{Áúh †ŽlÆ1 ‰‚h™b$„— ùq9È{º‡­×Ìí‰Tr¢(.¼0ˆ†„®ì£O îG¯dhC¤½Ð¿Â<TTL
@r*ý%€ €˜›-e÷XÚ¸ I§(yÎóqEÆ€v:u‰æ@p"La‹Ø|áã×Ïc¹~é(ð†a¿bè„ ™
HƒFˆ/\¤îIÜ\:v(ˆ‘€üµ¥_“OºW¹žÓ&@5 5ôƳ3)[ÉJNì`×8KÌa8‡2 |¿ž=LD‘OÜý|y1™J)
È`(>‡òeY©´]ƒº(AA(Qèh»šø—HåÔEó
^¦aÐö¾2ÒÂdXóñ$§wL- ”AbҾŇÖ…mƒ`g˳ŽTU>*…H€#QiüÈB
IUŒH±ŒpÌÅŒM¶pãâÚkŠºFFe`ŒTW	LÐÞ[‹zná&$¸È3{¡ƒ4IÓ4hH4óz•ÖM<e§A7™
zB;Àe9DÈRrΈq€ˆ1Ôò<N¢#T&n£ß\$=}ŒàOwb§"–˜B6ÒB y ƵkB\.Šéhä™”Kß™²ŒV.	#°Y,MÉ>™AÆRCb.‰PK-$,;Z¨ où»½|Ñz#Ãæ0mØTÌ3. úìŽ×K§Bvc…¿
ÓIýlã¦+ ˆ_*m™Šï—®nXwtA}c@=Ä!©¿\~Ÿn»è‚$1‚ù£T|ˆ(ÔAQ¥Õ­TMUTT@“	0EA,D_iˆŠ!ª"†P‰”Š$†i˜^Ж¡¡  •\™y9-‚a  fŠ
	§/zvð÷2c¤n®žŸˆH˜–@?(ÓLý!ÀObrŠPˆìF°wEdë¤á¢ðêp&Äᦦ¡ÙE;iG¿ÃΤ’è;Ê}>¸4iHÔj9Dõ&ät”¾ü~¹tùZXÀ
¾ÅiFK†ü&ì·ñÄÛ]ún€
/°†þÃ9ƒRÌ`ÇØ…nBúèüTåp|j}š€ÚM²;øwO׆&óuEÕ¥Èmî®Feyë?-m¶Ãr6‹M•H vl8Jí¸TW¹Ê(¢Š"9&¢7žp0‹J´ÂI2†¦!$B騨áÂz„Å	½…IIöþ+yœre²I$’I$¶¸Hì¶Ù$v*šlc$Hp³s‰ÍUsq9¢ªªª®öª©¨ÁÌlrHL/8³HÆÛm¶Ü„nê™ÍzIi1†dLD`ØIšÊI#ÂŒL@w`èÅÐm¶Î5EW#pj„Hae¦+„ÄV"—ýR"É2+DAì~Ó<X/'Ž®ÝurK$“	,’[§MHº´°W¶A‡Cƒ]³Y0 ÀÊHÜ	0¥­²€äd((nNÓup¶1‹S×g‘ã RëœÌ„²I5¶¦œrHÛ}$m»&´IˆP©²”)[qŽ²ÂЖ¶[FƘVÛÔm¹$’m¶Ûm«m¶Ûm¶Ûm¶Ûm¶ÛmÞÜÛmËUwµTIUslmlpæªëmµm¶Ûm¶Ú¸Ú-—™΃p-Ä¥ÉÀ عXä)ZKH#ñ£ÉŸ÷þÿ›6ÔïÁYÔi¶Ûɶ<e¶K%Ëh:DOøÒí$Ûm¶Ûm»
ŠÉb®Ž/½ê£G
£ƒ¼3T± Æ8÷	ã'-©7_¡ó0ØöHD„ËA-yE§(`‰ò#ôªýÞ”0 žSXš݉„P¸!{£|	µ»ø?Ia쳆ÓK‰Ù‰´5

"`tNª€ŸE·¶2݈wÁF~I=Úè¹lfÀÅ4×\cpDiï´Ûy;éeFbõYÀ‡85º	SE~ÍC8~ýhÖ½Öš2ýR[«ØŸÇä{¸¦nfkB{ÏÍ­¢`âÙE§áÐQŠ% Š<¸®(ôa6(›äR*¹sY뫳9•ŽRþn\×8nÚ
#)î¶çÊŒãGEâai#/šyÍ6ñ˜hCŸ×Èt3ÂI6YÇs¦8ãÚneHZdŽ³‚¥‚èl³^´.Ú¨J‹­Róç[Íô š[ašÌ²‡+¯BAƒffàr,Á•²†°½,½zð®.†€kUHœˆÎÄC³%*¹44=ÝãÝn;Ð) seƒ80onÉ{{I	2R;ù–„¸æ8$×þé©Ðš¸3”.|q!Zècxj&V#J»É,Â@0© ¯"œÂ/E¡)ÆÀ¦fVB 'rxö:؇åŒÑiÃØ—6@ |ÿs⟱—	ˆ7=ÒF#Ô¦é*÷öq‰LÆhì“‚Ÿ^À-=, 0Ÿ·òií"Ç4Üä‚Äêó'C“BT³”š£0lR{9æè7 ±%ØqâtŒQ~:N›¦sSnACèéÉö5ÐiôÙ¬Êa¥3s9¡Vܬ
ã;
¶m3mRèTPc„ÄÜø܍èW°IHU;,XÂ5>QÄ5 !V¦O‰8–iÀ•ÐŽçðs2Kùs]'ÁŽwÊi[ïK_PK¬Ñ^`¦½8„ÞŽmK¿‹ÌV…ŒñDLAiÕú§‚ûÈé†AÌ^ÙÓ.ƒÛÛqóÂÌú¤cbmxo¯ÉÄms ÎðdY)£knZH¼9€VGÛŽ"Te×[ÏÔàTD!¦:E·‹3|µÀ Zȳ3–'9 É&TIþHZ{4[xÅr±@²L 	ööÇ °›ÃŸucoSc¤â‰©ßË{í¸S¯!/&¦$7€c ~Ôƒ$Ìq1˜ˆH±Þ“‚˜AGBl™®Å$G{Î5ÄÈðÖ—!µ½Ð0†1‚•X&0ŠAF4æÇ*OHäÂg¾¸Šq™O£(=Œ¨çXÎXˆY¿ÇNU&׎°k¦¡	&aÙXÃsÆ•Æc ’&fÎûÌæ{¹1ɏ8àëwð›­ª:¸¯
ÝsëfÌq“Ä3=Wˆœ»—å9	uz®.Ùd B"BA*3XŽk[‰@9R`z''S©¯/¶å;’sÚ.nÒJ´3Ñí"€™„3†ŽH‚Y^´>ðVΪf¯82>:vª&§m8Xº£Thü7O92ôngY²G°a‡…¼½uÆo{"Œl`pqÙØà}À‚„=£×Z Š´âqÎ|ÁRÎSc‰WjØr°DSÉ´„ÍG)qÁ¾NM;A®Œ²vN–ZÌì¤x˜bì©£T¨T`1=Ã|À¯Ï@@ZçA©œ³tá¢X*p§¾¦JN›'	Ja$–w¾¡¡>bì³t9
V3•s;p¶#Fº3ª‚B]zætÇH8³ZÃ3`4†I¸¼ðÁf¼¾²|Á³Ô1€|ÃAQI1êI­j<¸ñÓ#ØÇ–7®ñÃ’KJm–LÀɈÓÍhœ®C­
tÓžVp¬Éåè”&ݺcC²”8ÁÇKÝÀWNR¸¢ÒR»Õ…b•v?ŒL3^¸NT-êp¯;&3‰>0W4Ü›‚Å®"´l"ílŒÖ¹ÅTr1&Ók]2ñVA˜âØßIÍgÓ¦5¤Ã4D‹ÀŠ«@›¬™Hôòq‡¬š „cÝxõë¢Á¡î°×&¥Æ*
o·,;Ù  rqBøS˜xqº¸Ú2Ž7ŽåºÈjMǨ±¶8É„GKÆé¶e—B;r4íj!»dσBpˆ×ôJ¥jiînˆ2ÃÛ¸{G"”–=9!’ÊqÍRÜÖ]ïÚê!dßóÒ]R`ÓœïP\úDa$TT£iœ³Î3)ÌZ™ïi—R!5mœxšg)ÄÆ©n›(ÑN‹³©q¶XعHF¨e;h­¦ ˜Êè/ZCá›9|3ÓebGb'k—ª§œÎrÐi˜ÉÃîü4Ü\¬öö=›]o2ms’ÂW$©l¯P¾eÚ̃¸M!ãIÈ]·
9Ò(àR„‘d!”¢q#‚!|l0JN°<‡á/Tb`"&CÝÐô‡‰LÎŒ'Lƒ‘¾:c¦)
U¤ó¼šúӍ·"}Ô3ZkΝüà~M:d½ÝäZ¢OQUÚ-¦~“AY‚B¦ÄÞhá®I•îGr5!6¾æCpÀ›Á¨¶t9,aS`-SÄ#OD,±êË\MÇP†gjº¾PÎr	`2ŒI²ä«ä
)Fš‚dv å'…ã‚Ô=Èy(ä”ÕÂN8‡Ð|úŒ6‚{É»
¾,mß®­HÆ-0fבÁX0!Yû‰S¯Àhãs9¤a›Ê7…}ª8æQÚÍ}³Xd5HnSæÎN7ÆÎ-F‘¿{‚ÇäóùÍN8€ÞChvÊ;sÓX-ÐóÒaÜÉ[3FŒúꉮU†H…¡†Ë%ÝTKAÓ»Ù:”î8G©Š³|X¬–{¾Â?†¶‚=üäñ—X+©%7¤næiáS‘E=G~‚’/Ç2Qf‚	ÉÎÜ4æzÁVÌÆq43°0i_F)b¡x*Fï‰ÆõѧƴÒÕLãiÿ<XíyYv“~˜ç"`1¨lm¹8Î6͍ö¾NpdúO bXôùkÜ;/†ßÐ8Ôèmzl±ú|™+ÕÍæË>\|qÃi¼Å1¦Cvñд ro!Ñ]Ø[ZÅVÆ[ˆ ‘àpúÜ0rhÂcgµ–)æTց&Ð"˜†wˆô[9@*lÏœ¥†&âÙ’`’XBð"+èDLßrg“=«¨ƒB†DC™SC<œ‡)Ï
G!nTT²©Õ>¯xã9@òèrã=“¶Ñ
 ò	x›²=}äÕöš‰îW¯kZÚ7ÛªWÐä߉¬óˆ‡H¥.]ååTÈ|îCi°›2”æ=1ej ¾Î'“e¨áœL™2s¶™_Žv•ª*¦©!誹¥«-Â
ôA at ETvà›Js’’‡• …öld8³.ë¤G»	x×b
²©BA
ù&0§¡i¹Üg“›„,Œ„&¢ x(Öƒ¦ÐÓ³‰Hp`˜`h´Ç8á34Ž…ñ0Î˜`l0Ü”XÙŠOªunÈ)H©4^Œ½ï0t*ýÁ|&ljñÅìÒl¡ÑÐÎx(ƒ|Pµ!Á¸Dõ·Ï`×:9º@§ƒŒ¤X›&‚¦G¶wšBÅ2q= ø¦‡£LBa„;B^Ž×™H–,Ji¨SØj
š4%§¢{cŽ¦zÈröx”bbpç0Öª«lfž¨s†ô±ïrªÍù„ŒÈ9˜/å;/+,s @Éè°rt >yÉ6ÜÜYjY«ZÅJ!ÞŽ‘RÈŠ8Š¸ˆ&ø)8®ÄCµxãÆg
!ÎôË·ˆVdÁ“8ŸIa j·nvK)ÞËâNmIÉ)åéÛˆX”ù•’¯¸˜43b\0§V#@AÎyÁžŽdaëÖÑ ’’©‘è˜Õçh½ºsEpjC`¢Š_Íca0À‡Óâ}Ý°E!”Î.‰Í÷O…dá­Ñ«R I¢Ùê!|Ó»š…`†œâ8]NÝ,
v‚:”ï<Íøw'e¨2³&ÚÂCÓÀƒiL)ƱÅu„M!¡ƒ£#¸«Ø ÀƵ&†£Æ\!Y½-Êc¨1Flˆ
öÅp˜Ö“£nh€WX£º&²"2&9Ø
áƒ);0Tu‡fz»—C¦rN¢.ìÃÈÚ¹±%qÒláÄF3°A‚9@Ï]'­ÐGpN£KE!‰KQÈAQÅºÏ:°Rp‡3AÞpFø¸tæ» æ0ˆïuâ;í¦«¨ë¬HP*bï )܁ÀÂîÇ
¡‡"P$1Ñ!l­=¡ÑÒt¡Ö]nuH„J«x±k	vyð§HÁfE
T2‘!È5GD„‘FÆ›`Dìp/HІQýƒ3Žô-šÆìI§Øâ,iÍÓ«1¦c™£›‰‚dÔÐX¸Þ^½w`§5ߍ¼RíÆŽXkŽ¨˜ôMðctæD+D–ó›šhçSFBÒÁ4WpvJ«®ŒgÃÃ!®ªáH¹@ñpА$«™CÆÉ¢®„+Å1€>k	Ø8 §Ó1A
6ĝnŒ´•‘
(¤RX~À~ÌIÍ	
½,ù³˜T‘>ûn¥GÌHWP¬ÓaZ=Ãl>=/ŽQHÒÒ÷àÉD=Ê3)ܾ@ö2<D (ê'à^½fº_+.ñ¡üd˜€þ™ùQ÷Â` @!í•P
H¢½Dˆ
¡7‡Ó†}0ÒÊ}j@³ç§ˆR at yžy,í{þŸy:ôì& @í«¼æ¾ÊYQå
*¨eu7À`òQˆvèñ]•Ñ@ðuHÞц$‰
P¥‘vˆ÷¡@¢~ÊÈóëòüGöUnì%LXÊñŽ{uˆ^ÜPfŽÒ´ýQ)€ãˆõ.ÚMŸ£F„Ñö™©5LcP}؍8GDQ‘ÆÉwÊ`2u‡¥íC¹}¾]Âo¢r)GÉÃè·5zjRØ17·ÅçFš$úk9
§¾.¢X“i®_*‘úù¬Ð[‰Ž‚´VƘßוÊÂ9cŒª¨hæ÷s`ÌÖÄ°VŒÐ,Eí{üäê|BŽ&	ˆ!i¨Ôm¦Þä}5z)jN1æ.®®u
 @ˆ¼ã6ˆŠ¢=`uÁÛ¼†@"®F
á€Ð6¡‰yk–Š+“©¤õ¦®9¦q¨€1Š!6›Ýdêäí6×›­×#›#«S6L8ÈÓ$Q´¡8™L,YW €¸4ÆÈäè&œmC¬dÔ ŠŸQáä?Hø<G	âîIÎbƒqŸ0âæ2’ÈKÒ#ÉvHú»˜ÈǤ“´¸Kèù‹JyI¼%žP
Œ)³t–bàû¹O«ÀæOaÝã˜Ðzµš0Ç	
Rÿƒ#-ßšézwî3v–ÝÃMùvH„Ý+ÛT0zH"†’†’C®„È)T(s¢_D0DÒ¯Rƒúã¦PNN‚e€´?\ƒÂ8é1.‚D¦Ê"†¡)©–BŠH‚&$ˆi"+ýÖþÈLaÜB€ñé;ˆøÀ[½¿p+MˆÞâjÝ‹
ˆ$!-i¨ZÎ×>úùŸ`$AzƒŸ*…(ŠHoÀ…y¥„EL#}P¿)­&JâóÒF³Û>þ“¦ÌŽÐz½›¹((BÎâ$#8y”tž°CcyQÆ”}Aā”fO‡1	}òúñŠ¯ £ñ€F~‰ṏÂ'pèˆÒ']U^d%ÐQÉ<ˆà(§dªôbBÉ¿3½5‘Ãæ°û^'¦•{bèÊ0ØSXªÅ§0ŸA®”»ÖO{ØQ0„™—¸ÊÂÁ‡uHH9.ZÀªˆõ5³4®ÜÍK«‹!AŠ
ŸÉ÷Ü:êô°Ñ“0ö¶A„nŸç°`3+EaÓþzʇwá¤ÙR#‚OQ	’s„"L‚:vNLjuÇ™GF¸aG¶ßF->54Õ$Ü›qŒ­å3]&Í
ní6Ín7×VR3l1’ÑLÑä(u>°òü~¯c ñ7y}.ïøœ' ÁÑâg/uL-¡Øjó"og4½
uvóʐÀuà¿@œ%¾)R%݆þÙ(âïâ½0¼`¿‘ê>IøhÁ±€¶M:bv0bÑ hLQBÒT4ARLED£ßDˆ
_f
Ώ‰²Ri
"b QÕÜ<X
ÙÆÁ©ú F¡âçŒòâfæìM:—²¸y¿jÌE?¢©±r}>¿†Ž,)?ˆ$³ÆTp:ë	‚.*Ï+³8&ž#À¦ÓHfu¶¢°Œ«Ó¯žG¬7>“P8o›*R£#—Ô9›vf›ôæñófÏÖ‡Æ	_¥0Àp²n>XrèsÀ:1L{¡ñ„"Ù‘@8; qã«OÙÑáÖ-HÅ\áwÉÃèØ×ÚÆšUF˜÷³ÛjY*HÿA¸Öv•îh8ºƒ¢NG8è  •÷ð¾gíJìš²@ðÈ|p.„$´XwŽ5Ú¬ZŸq63WAGG9‚„¾Îeãºy­Ži(£F˜e¼cªÇå™
,>g—iª:ˆ‰`¦@^r9(
2¯šÿ Ž€íOía@ùà²-á…EP¿ªš•&?R÷‰YÊe»¢P”ФTõ÷"œÁ°@ˆV&<Ig$‘
×Z#»T¥6	ÞÇ
¹æ‡ @EÔ”^{?8ûÅ
(
@á8ŒM|hÁ/%çZ>¬™!:&#£¸	Ù0&Î(ÄLX•{fU<˜Ž‚x'Ëõ÷$ÀAÿ¨]II&ÙÌj–µ‰‰  –Bˆ¢Š&@™
hJ]³“‚H¼	›ÀðëBŠ¢vé	 þ¨  bR{–NÊ (I€3ä¾ÂݸÒê¯N‘>gþ`'ã!|´p(y§“ö§÷1ää"ŒAïƒöœUä)”znàt
ŧã¸]hMwÃù™NÌE3$0 at 0c'Œ¦”)ŒXŸŒƒþ…Ô,MP
"Z!䏒
}xg˜’ì©ýïœte¾\ßLG”%fš‚Äf,C‰²ÈÞx\©l`m;ƒ.ÇŽÄÆc 
>ZÖ	¨ž¤:aìFÂ-\£îî„â".JÆ¢Cœ±=½BI`Ç¥š©$Õ¹3	Rv¬m¡ ™Ý›é:Ãiã~(ºÉ#ÑýÕb*Õ#PmŽ
Ž@hŸ[L"|	D×÷Þ8덒Æ
Ž{7)¯4÷¢	ødB…‡çþ[Mu˜.î™!ŒOQú~ÓtD£lÜâ¿×j?¦bÝ¥?dG,
®.ð‡)ˆŽTà UwOÁ!â=¾°(Š97¢yT¥¿CZ€i‰H¦@&¯A}àýÄ›ÿ)¿‘7)´D"ÿh‘ôxon<µPþl©¼§’]C!—©3÷6¡•M)Ô‡!iDéÓÐ⢧ý$TˆCúU:Ùxé!@R‹HÁOHæìý\¬?Nÿis:â‡ZƒØA¡‡ÊoR´½Ì×6ðÔk+#m̉ÊxdäW)ïr¯I9ÕŽšt§'“­€ÌԝÉâAꫬþð%M
UG‹AŠ„ôâ©Ù(°È¨œ•YLˆrÈ A!äcý.|Z
J”üYáMDRûþ&µT54”PÌ
L·ˆ4ß(éØÌŸ0^¸D š t4$¨†g.í…&	ƒ
oÀû¾<‹èBGÒ…'%¥N Ä&ÎY Ðnÿ6DëÝÀÝ]]çWy ÆVe#Ì`ãM£fcðØø”tœ8jþý‘–"#ª“œÖ6Ði¯¨Ã˜† öÆ
eA„¢vÄAÂùê;ÏìÈòâÔâr ªª%›¢nƒÒ	ë
úÜF!d&‚ÌŠýøc—F€úLÄ4÷úè_z4QBUuѯ™;¢±½NÀÈ?‚îi&ƒ¹¤Ý™ÒPÐ1Jb
<’€rQ
‚X H…šXHo®:Y2´õ²
•üGßÞð,­œ—þ’ÃñâuÙN(¦)¯åèîÀf-}êcϸB% `>Œ‡’ñ"'K÷F2˜$X °ˆñˆi§‘Ó
T?3Úg×;ºŠ×²„бôÁð´¢ÌwM”º(PR`Â}fö‘T8!e+ýc9 OÁpp`Á÷BxœK|šp]Niœä·GÕý”
œfLF§l¬ƒMUV,¾»^j$8…Ž9 ÌbŒÛ†\$.á~ß\Q†B]DãMÐûË;èÁŏŽ=¸çæ
;좐à;†¨fÑø‹€üçâ1Ñó1tGÄ`|ƒƒû
ëþl>8–J( ¢4š¡Ä÷‘,o»³¼AïŠMû…;ÀáîT½>ìæL
	þhÑ+\ÚœØ3íl­¥-®m&è˜â‘±ô\‘ØKÆ5T«¹æAIë.!kN*B"ˆh–(šHM‚Ù
j„ÿ²L¤´Ä…Ì.’ ˆ$c`T s˜xS&Æ`1Œ@LQQEÁ„IBAØØH
p‹¤öp€p($!`ŠS¬ê=bìn…ûƒbP9MO8àü ²y0Ÿ,ˆ˜÷gØÅ7YÀ¦RYªràSòùOÎŽA1~;îÌp$3¢—G¤©©êM_1Ôz“š
#ÆÀA	ð\txŒltŸAuÔÓcóûÃtŽÏåä}Çæ!ÇûF͝¢ r¢–Õ¡C*ý6.æk!&PØ¢d2D®§çí2yóUÏ>‹’B†Š)ÏÕõCgï5“	Oœä„:Ayƒøv OîŠ! D‰W¾ÌH Äˆ}8>D}äJžøÑ}ÉÐÄm¶Bi&Éë_"lô0„4òŽ$ †He¨Õö0FŽ(×oب”&ônBH{¯Pô´;lcŽÚ¼E2U“¡DÂPàݲ·Ÿ¡?!¿úY#oêB!qó05çÞ}‡ ª«2"
†Âè¯
Š¹HøÂ!Ñç‰"¾@~ü‚ú&è ½A^߸ít`EBG쉅‚†Pï?ˆþAÇÄ`qißÂÊ¢í-ÞñÃHtŸÊÿæŸäÌ:ÍÎjݤډcY‡LèP@È[ý˵åwZX€£òGÌ}[’S–À@¿"Ë±‚àÕ2>ŠF‚#©ÆÁÔ`”‚ûÚŒŸQQ±žᶓÄú¶ÓÓƒèù?ì0çpx…øþÜm
-5ù¬m«aˆñ‡
23½C|-cb"œ½¹<úïÂ?ktH¹¡$“ãMÑ8ë‰o3·<ó¡wxíïh.£
whhÍ8CÆÊ>„³Á<G¤Ð¬÷_WŽ–øQp$¶LêtÖdÀÙP ‚M»Òƒ^…7ü ¡Í?è·"‹Â@Jˆ…!þ¨Wë]áôÍ˜äIš>Èûâý8'…¸ŽíÊ@tc :¹ ‡Û µKÝåÕ#ì€ú>'¸÷Œô!:5~köŸ
<O¼)^jˆˆ©™—–à– «N§`ǹŒEŽx¾‹ºŸ¿: ©)$qWÎ
¤¨„$”…”j¹p€rJ²4žŽHz1‚µÔX¦z!òy‚?•^äFÄk4‰¢ß¤±¯Y­°-…&[!† TREz‘ìZWôœöðû~Ë










Zª

Níÿ9Àcw1r:ªª¦£UƐƒM4ÑÏßÌUQE!æ“ASÜ?ñ´pØÿEþŒ28¼WƒlIÈ>軪’¢"¢aé ÷œyÈØ™8sŒóI ¦ ¨‚‚‚¨+AF¼Œ‰åöìç D
`h¼•íCc™—÷1‰Qa¹Eoƒ…NLjàQ0¸½9‹—·A¾@Ñ('4aÈ·BšçQ­0.
,LêhÆccÜe¥Î	Azqõk†™Äœ%ê4vG ¹
RPEŃT+«f’›cJ¾MÞ †÷#AdkL4Œ»QŒ:‹#QÍ.®™\2­0èÃQ$i™Õô°S‚¶R”Q†µw<k®ˆÓÕc-h
±î©çJ0uw/P§  ñPþØòÍ\në¤qt2
ŸúG7_¸b5Ñ¥ä0.q(¯d:œ«QªÒMT_tú¢ßµ1ÄwÜØÙ÷*ln#CÂ
 l at DÆÊcˆ¬è¿Æ(c\Î6órל󫮀>‹Ü/êŠ*@~ˆ€X‡´?QÿÚ½£ÿâúßµûÇáˆ<~ídâþü~³ðø‡ŒúY»v˱$³
ÜU$aø·iXsûÔ0Å¿*€I‰·n&6ófà€Ê´ÙC=9\&Ÿ8pôÆ6ÐuÄ"uڥƆº.c(^Õuf6’ipôÖcÀáf`9é!…j;Ðæ‡{mÑzDãŠrg}ô&o£r¶
ä}V˜ßñÈmôîb³y‰3EE§sRNÔZœ&hR,2Æ#$Ò!É9±ãM¨ƒÂøSºÖc2(ÉÇ(æa t;¸·¸µ5ZI«§¤WìŒO7wæv¼b´F㕾_	ö{hótØ €mÖŒËzÜɨDÜ(Õ)*4RÀØÏMÑD’Ü1s8CG—¸NŽ@š؈Á|®LÙ°IK¼7â{(l¦VöJuÊoi$¹­ŸyM¸=`ÂHèÍ-i®3x•ß)ÊBUpB°Ä¾	qÐœãÈnÕNp<ªŠN/—7MÌ%8|Üm’i²ÂÖ1“N»& B5ŒIŒl	“ÌÄdÎu$MxOC Ú;ʈõÐ>™c1¿ZȺ2ïï“]Kw9¤›Zµ(ìC$?C8€ï8éZD¤
‰»
Ò”ÒBßm
>&“eÓseÐqÆHˆL=ò•³iª |9͉©ív:F‹ldwöõQ˜wY‰»¹Pä{ƒÈ‰‰H†–’…òÐæBšÅë0
µÞœ¸u
НùÅ:Sø‡¬Dl+Hý$¨E(তS™ßà*'ë|'Ä„}h*:‰#E„)>W2ÆÜ,šÁqŒÂˆ0Ð"”Œ‰
/i! $bä? ÷ˆÐ)2)Ñ`ÚZã´­ƒ’„dCF­Lwø”l•0ÀÈ|ƒT”ÐRoC at a¿FHIÄ d’ …(ÚdÐkLBD¨¾ø¡@èII*”…¢¡‰%©¡"ªˆ©)R‘bP"„¤¡¤ª’„
–i(!¢P)ˆ
ÖR~ÈMZ “𖊤f
]ÎŽ%Q”ƒ„Ð$BïÑ\…4
i„WrCÿ_3Éz‡ŽgX1ÿçu%Ç0uM ˜“ <’
Á~æÁtce?v

--- NEW FILE linux-2.6.21.tar.bz2.sign ---
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (GNU/Linux)
Comment: See http://www.kernel.org/signature.html for info

iD8DBQBGMDTzyGugalF9Dw4RAu38AJ91aU60u8cdBZoUuM19AkmZLQunRwCfd66G
DPHXFTHqiYB4RZ6mIx2ymVU=
=cnCB
-----END PGP SIGNATURE-----


--- NEW FILE linux-2.6.23.tar.bz2.sign ---
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (GNU/Linux)
Comment: See http://www.kernel.org/signature.html for info

iD8DBQBHC+s6yGugalF9Dw4RArHzAJ0XfUWR/26hYd+XwBQTMacxZ7FhPwCcDkIP
FBDXpT2RzOrlJcDcwF8QwO0=
=4zXk
-----END PGP SIGNATURE-----


--- NEW FILE mirrors ---
http://ftp.kernel.org/pub/linux/kernel/v2.6/snapshots/
http://ftp.kernel.org/pub/linux/kernel/v2.6/
http://ftp.kernel.org/pub/linux/kernel/v2.6/snapshots/old/
http://ftp.kernel.org/pub/linux/kernel/v2.6/testing/

nouveau-drm.patch:

--- NEW FILE nouveau-drm.patch ---
diff --git a/drivers/char/drm/Kconfig b/drivers/char/drm/Kconfig
index ef833a1..065f499 100644
--- a/drivers/char/drm/Kconfig
+++ b/drivers/char/drm/Kconfig
@@ -106,3 +106,9 @@ config DRM_SAVAGE
 	  Choose this option if you have a Savage3D/4/SuperSavage/Pro/Twister
 	  chipset. If M is selected the module will be called savage.
 
+config DRM_NOUVEAU
+	tristate "Nvidia video cards"
+	depends on DRM && PCI
+	help
+	  Choose this option if you want to enable nouveau reverse engineered
+          driver for nvidia chipset. The module will be called nouveau.
diff --git a/drivers/char/drm/Makefile b/drivers/char/drm/Makefile
index 6915a05..20b79d5 100644
--- a/drivers/char/drm/Makefile
+++ b/drivers/char/drm/Makefile
@@ -14,6 +14,14 @@ mga-objs    := mga_drv.o mga_dma.o mga_state.o mga_warp.o mga_irq.o
 i810-objs   := i810_drv.o i810_dma.o
 i830-objs   := i830_drv.o i830_dma.o i830_irq.o
 i915-objs   := i915_drv.o i915_dma.o i915_irq.o i915_mem.o
+nouveau-objs := nouveau_drv.o nouveau_state.o nouveau_fifo.o nouveau_mem.o \
+                nouveau_object.o nouveau_irq.o \
+		nv04_timer.o \
+		nv04_mc.o nv40_mc.o \
+		nv04_fb.o nv10_fb.o nv40_fb.o \
+		nv04_graph.o nv10_graph.o nv20_graph.o nv30_graph.o \
+		nv40_graph.o
+
 radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o r300_cmdbuf.o
 sis-objs    := sis_drv.o sis_mm.o
 savage-objs := savage_drv.o savage_bci.o savage_state.o
@@ -25,6 +33,7 @@ radeon-objs += radeon_ioc32.o
 mga-objs    += mga_ioc32.o
 r128-objs   += r128_ioc32.o
 i915-objs   += i915_ioc32.o
+nouveau-objs += nouveau_ioc32.o
 endif
 
 obj-$(CONFIG_DRM)	+= drm.o
@@ -38,5 +47,6 @@ obj-$(CONFIG_DRM_I915)  += i915.o
 obj-$(CONFIG_DRM_SIS)   += sis.o
 obj-$(CONFIG_DRM_SAVAGE)+= savage.o
 obj-$(CONFIG_DRM_VIA)	+=via.o
+obj-$(CONFIG_DRM_NOUVEAU) += nouveau.o
 
 
diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c
index a6828cc..f3da5c4 100644
--- a/drivers/char/drm/drm_bufs.c
+++ b/drivers/char/drm/drm_bufs.c
@@ -400,6 +400,7 @@ int drm_rmmap(drm_device_t *dev, drm_local_map_t *map)
 
 	return ret;
 }
+EXPORT_SYMBOL(drm_rmmap);
 
 /* The rmmap ioctl appears to be unnecessary.  All mappings are torn down on
  * the last close of the device, and this is necessary for cleanup when things
diff --git a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h
index ad54b84..87ccae5 100644
--- a/drivers/char/drm/drm_pciids.h
+++ b/drivers/char/drm/drm_pciids.h
@@ -296,5 +296,236 @@
 	{0x8086, 0x2982, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
 	{0x8086, 0x2992, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
 	{0x8086, 0x29a2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
+
+#define nouveau_PCI_IDS \
+	{0x10de, 0x0008, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_03}, \
+	{0x10de, 0x0009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_03}, \
+	{0x10de, 0x0010, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_03}, \
+	{0x10de, 0x0020, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_04}, \
+	{0x10de, 0x0028, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_04}, \
+	{0x10de, 0x0029, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_04}, \
+	{0x10de, 0x002a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_04}, \
+	{0x10de, 0x002b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_04}, \
+	{0x10de, 0x002c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_04}, \
+	{0x10de, 0x002d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_04}, \
+	{0x10de, 0x002e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_04}, \
+	{0x10de, 0x002f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_04}, \
+	{0x10de, 0x0040, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_40}, \
+	{0x10de, 0x0041, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_40}, \
+	{0x10de, 0x0042, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_40}, \
+	{0x10de, 0x0043, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_40}, \
+	{0x10de, 0x0044, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_40}, \
+	{0x10de, 0x0045, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_40}, \
+	{0x10de, 0x0046, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_40}, \
+	{0x10de, 0x0047, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_40}, \
+	{0x10de, 0x0048, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_40}, \
+	{0x10de, 0x0049, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_40}, \
+	{0x10de, 0x004d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_40}, \
+	{0x10de, 0x004e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_40}, \
+	{0x10de, 0x0090, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_40}, \
+	{0x10de, 0x0091, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_40}, \
+	{0x10de, 0x0092, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_40}, \
+	{0x10de, 0x0093, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_40}, \
+	{0x10de, 0x0098, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_40}, \
+	{0x10de, 0x0099, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_40}, \
+	{0x10de, 0x009d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_40}, \
+	{0x10de, 0x00a0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_04}, \
+	{0x10de, 0x00c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_40}, \
+	{0x10de, 0x00c1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_40}, \
+	{0x10de, 0x00c2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_40}, \
+	{0x10de, 0x00c3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_40}, \
+	{0x10de, 0x00c8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_40}, \
+	{0x10de, 0x00c9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_40}, \
+	{0x10de, 0x00cc, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_40}, \
+	{0x10de, 0x00cd, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_40}, \
+	{0x10de, 0x00ce, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_40}, \
+	{0x10de, 0x00f0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_40}, \
+	{0x10de, 0x00f1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_40}, \
+	{0x10de, 0x00f2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_40}, \
+	{0x10de, 0x00f3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_40}, \
+	{0x10de, 0x00f4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_40}, \
+	{0x10de, 0x00f5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_40}, \
+	{0x10de, 0x00f6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_40}, \
+	{0x10de, 0x00f8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_40}, \
+	{0x10de, 0x00f9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_40}, \
+	{0x10de, 0x00fa, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_30}, \
+	{0x10de, 0x00fb, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_30}, \
+	{0x10de, 0x00fc, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_30}, \
+	{0x10de, 0x00fd, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_30}, \
+	{0x10de, 0x00fe, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_30}, \
+	{0x10de, 0x00ff, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_17}, \
+	{0x10de, 0x0100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_10}, \
+	{0x10de, 0x0101, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_10}, \
+	{0x10de, 0x0103, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_10}, \
+	{0x10de, 0x0110, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_11}, \
+	{0x10de, 0x0111, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_11}, \
+	{0x10de, 0x0112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_11}, \
+	{0x10de, 0x0113, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_11}, \
+	{0x10de, 0x0140, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_40}, \
+	{0x10de, 0x0141, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_40}, \
+	{0x10de, 0x0142, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_40}, \
+	{0x10de, 0x0144, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_40}, \
+	{0x10de, 0x0145, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_40}, \
+	{0x10de, 0x0146, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_40}, \
+	{0x10de, 0x0148, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_40}, \
+	{0x10de, 0x0149, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_40}, \
+	{0x10de, 0x014a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_40}, \
+	{0x10de, 0x014d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_17}, \
+	{0x10de, 0x014e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_40}, \
+	{0x10de, 0x014f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_40}, \
+	{0x10de, 0x0150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_15}, \
+	{0x10de, 0x0151, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_15}, \
+	{0x10de, 0x0152, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_15}, \
+	{0x10de, 0x0153, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_15}, \
+	{0x10de, 0x0161, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_44}, \
+	{0x10de, 0x0162, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_44}, \
+	{0x10de, 0x0163, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_44}, \
+	{0x10de, 0x0164, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_44}, \
+	{0x10de, 0x0165, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_44}, \
+	{0x10de, 0x0166, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_44}, \
+	{0x10de, 0x0167, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_44}, \
+	{0x10de, 0x0168, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_44}, \
+	{0x10de, 0x0170, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_17}, \
+	{0x10de, 0x0171, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_17}, \
+	{0x10de, 0x0172, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_17}, \
+	{0x10de, 0x0173, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_17}, \
+	{0x10de, 0x0174, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_17}, \
+	{0x10de, 0x0175, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_17}, \
+	{0x10de, 0x0176, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_17}, \
+	{0x10de, 0x0177, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_17}, \
+	{0x10de, 0x0178, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_17}, \
+	{0x10de, 0x0179, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_17}, \
+	{0x10de, 0x017a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_17}, \
+	{0x10de, 0x017b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_17}, \
+	{0x10de, 0x017c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_17}, \
+	{0x10de, 0x017d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_17}, \
+	{0x10de, 0x0181, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_17}, \
+	{0x10de, 0x0182, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_17}, \
+	{0x10de, 0x0183, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_17}, \
+	{0x10de, 0x0185, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_17}, \
+	{0x10de, 0x0186, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_17}, \
+	{0x10de, 0x0187, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_17}, \
+	{0x10de, 0x0188, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_17}, \
+	{0x10de, 0x018a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_17}, \
+	{0x10de, 0x018b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_17}, \
+	{0x10de, 0x018c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_17}, \
+	{0x10de, 0x018d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_17}, \
+	{0x10de, 0x0191, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_50}, \
+	{0x10de, 0x0193, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_50}, \
+	{0x10de, 0x01a0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_11|NV_NFORCE}, \
+	{0x10de, 0x01d1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_44}, \
+	{0x10de, 0x01d6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_44}, \
+	{0x10de, 0x01d7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_44}, \
+	{0x10de, 0x01d8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_44}, \
+	{0x10de, 0x01da, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_44}, \
+	{0x10de, 0x01dc, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_44}, \
+	{0x10de, 0x01df, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_44}, \
+	{0x10de, 0x01f0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_17|NV_NFORCE2}, \
+	{0x10de, 0x0200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_20}, \
+	{0x10de, 0x0201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_20}, \
+	{0x10de, 0x0202, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_20}, \
+	{0x10de, 0x0203, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_20}, \
+	{0x10de, 0x0211, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_40}, \
+	{0x10de, 0x0212, PCI_ANY_ID, PCI_ANY_ID, 0, 0, NV_40}, \
[...6952 lines suppressed...]
+		NV_WRITE(0x40082c, 0x00000108);
+		break;
+	case 0x43:
+		NV_WRITE(0x400828, 0x0072cb77);
+		NV_WRITE(0x40082c, 0x00000108);
+		break;
+	case 0x44:
+	case 0x46: /* G72 */
+	case 0x4a:
+	case 0x4c: /* G7x-based C51 */
+	case 0x4e:
+		NV_WRITE(0x400860, 0);
+		NV_WRITE(0x400864, 0);
+		break;
+	case 0x47: /* G70 */
+	case 0x49: /* G71 */
+	case 0x4b: /* G73 */
+		NV_WRITE(0x400828, 0x07830610);
+		NV_WRITE(0x40082c, 0x0000016A);
+		break;
+	default:
+		break;
+	}
+
+	NV_WRITE(0x400b38, 0x2ffff800);
+	NV_WRITE(0x400b3c, 0x00006000);
+
+	/* copy tile info from PFB */
+	switch (dev_priv->chipset) {
+	case 0x40: /* vanilla NV40 */
+		for (i=0; i<NV10_PFB_TILE__SIZE; i++) {
+			tmp = NV_READ(NV10_PFB_TILE(i));
+			NV_WRITE(NV40_PGRAPH_TILE0(i), tmp);
+			NV_WRITE(NV40_PGRAPH_TILE1(i), tmp);
+			tmp = NV_READ(NV10_PFB_TLIMIT(i));
+			NV_WRITE(NV40_PGRAPH_TLIMIT0(i), tmp);
+			NV_WRITE(NV40_PGRAPH_TLIMIT1(i), tmp);
+			tmp = NV_READ(NV10_PFB_TSIZE(i));
+			NV_WRITE(NV40_PGRAPH_TSIZE0(i), tmp);
+			NV_WRITE(NV40_PGRAPH_TSIZE1(i), tmp);
+			tmp = NV_READ(NV10_PFB_TSTATUS(i));
+			NV_WRITE(NV40_PGRAPH_TSTATUS0(i), tmp);
+			NV_WRITE(NV40_PGRAPH_TSTATUS1(i), tmp);
+		}
+		break;
+	case 0x44:
+	case 0x4a:
+	case 0x4e: /* NV44-based cores don't have 0x406900? */
+		for (i=0; i<NV40_PFB_TILE__SIZE_0; i++) {
+			tmp = NV_READ(NV40_PFB_TILE(i));
+			NV_WRITE(NV40_PGRAPH_TILE0(i), tmp);
+			tmp = NV_READ(NV40_PFB_TLIMIT(i));
+			NV_WRITE(NV40_PGRAPH_TLIMIT0(i), tmp);
+			tmp = NV_READ(NV40_PFB_TSIZE(i));
+			NV_WRITE(NV40_PGRAPH_TSIZE0(i), tmp);
+			tmp = NV_READ(NV40_PFB_TSTATUS(i));
+			NV_WRITE(NV40_PGRAPH_TSTATUS0(i), tmp);
+		}
+		break;
+	case 0x46:
+	case 0x47:
+	case 0x49:
+	case 0x4b: /* G7X-based cores */
+		for (i=0; i<NV40_PFB_TILE__SIZE_1; i++) {
+			tmp = NV_READ(NV40_PFB_TILE(i));
+			NV_WRITE(NV47_PGRAPH_TILE0(i), tmp);
+			NV_WRITE(NV40_PGRAPH_TILE1(i), tmp);
+			tmp = NV_READ(NV40_PFB_TLIMIT(i));
+			NV_WRITE(NV47_PGRAPH_TLIMIT0(i), tmp);
+			NV_WRITE(NV40_PGRAPH_TLIMIT1(i), tmp);
+			tmp = NV_READ(NV40_PFB_TSIZE(i));
+			NV_WRITE(NV47_PGRAPH_TSIZE0(i), tmp);
+			NV_WRITE(NV40_PGRAPH_TSIZE1(i), tmp);
+			tmp = NV_READ(NV40_PFB_TSTATUS(i));
+			NV_WRITE(NV47_PGRAPH_TSTATUS0(i), tmp);
+			NV_WRITE(NV40_PGRAPH_TSTATUS1(i), tmp);
+		}
+		break;
+	default: /* everything else */
+		for (i=0; i<NV40_PFB_TILE__SIZE_0; i++) {
+			tmp = NV_READ(NV40_PFB_TILE(i));
+			NV_WRITE(NV40_PGRAPH_TILE0(i), tmp);
+			NV_WRITE(NV40_PGRAPH_TILE1(i), tmp);
+			tmp = NV_READ(NV40_PFB_TLIMIT(i));
+			NV_WRITE(NV40_PGRAPH_TLIMIT0(i), tmp);
+			NV_WRITE(NV40_PGRAPH_TLIMIT1(i), tmp);
+			tmp = NV_READ(NV40_PFB_TSIZE(i));
+			NV_WRITE(NV40_PGRAPH_TSIZE0(i), tmp);
+			NV_WRITE(NV40_PGRAPH_TSIZE1(i), tmp);
+			tmp = NV_READ(NV40_PFB_TSTATUS(i));
+			NV_WRITE(NV40_PGRAPH_TSTATUS0(i), tmp);
+			NV_WRITE(NV40_PGRAPH_TSTATUS1(i), tmp);
+		}
+		break;
+	}
+
+	/* begin RAM config */
+	vramsz = drm_get_resource_len(dev, 0) - 1;
+	switch (dev_priv->chipset) {
+	case 0x40:
+		NV_WRITE(0x4009A4, NV_READ(NV04_PFB_CFG0));
+		NV_WRITE(0x4009A8, NV_READ(NV04_PFB_CFG1));
+		NV_WRITE(0x4069A4, NV_READ(NV04_PFB_CFG0));
+		NV_WRITE(0x4069A8, NV_READ(NV04_PFB_CFG1));
+		NV_WRITE(0x400820, 0);
+		NV_WRITE(0x400824, 0);
+		NV_WRITE(0x400864, vramsz);
+		NV_WRITE(0x400868, vramsz);
+		break;
+	default:
+		switch (dev_priv->chipset) {
+		case 0x46:
+		case 0x47:
+		case 0x49:
+		case 0x4b:
+			NV_WRITE(0x400DF0, NV_READ(NV04_PFB_CFG0));
+			NV_WRITE(0x400DF4, NV_READ(NV04_PFB_CFG1));
+			break;
+		default:
+			NV_WRITE(0x4009F0, NV_READ(NV04_PFB_CFG0));
+			NV_WRITE(0x4009F4, NV_READ(NV04_PFB_CFG1));
+			break;
+		}
+		NV_WRITE(0x4069F0, NV_READ(NV04_PFB_CFG0));
+		NV_WRITE(0x4069F4, NV_READ(NV04_PFB_CFG1));
+		NV_WRITE(0x400840, 0);
+		NV_WRITE(0x400844, 0);
+		NV_WRITE(0x4008A0, vramsz);
+		NV_WRITE(0x4008A4, vramsz);
+		break;
+	}
+
+	/* per-context state, doesn't belong here */
+	NV_WRITE(0x400B20, 0x00000000);
+	NV_WRITE(0x400B04, 0xFFFFFFFF);
+
+	tmp = NV_READ(NV10_PGRAPH_SURFACE) & 0x0007ff00;
+	NV_WRITE(NV10_PGRAPH_SURFACE, tmp);
+	tmp = NV_READ(NV10_PGRAPH_SURFACE) | 0x00020100;
+	NV_WRITE(NV10_PGRAPH_SURFACE, tmp);
+
+	NV_WRITE(NV03_PGRAPH_ABS_UCLIP_XMIN, 0);
+	NV_WRITE(NV03_PGRAPH_ABS_UCLIP_YMIN, 0);
+	NV_WRITE(NV03_PGRAPH_ABS_UCLIP_XMAX, 0x7fff);
+	NV_WRITE(NV03_PGRAPH_ABS_UCLIP_YMAX, 0x7fff);
+
+	return 0;
+}
+
+void nv40_graph_takedown(drm_device_t *dev)
+{
+}
+
diff --git a/drivers/char/drm/nv40_mc.c b/drivers/char/drm/nv40_mc.c
new file mode 100644
index 0000000..8dbd96f
--- /dev/null
+++ b/drivers/char/drm/nv40_mc.c
@@ -0,0 +1,41 @@
+#include "drmP.h"
+#include "drm.h"
+#include "nouveau_drv.h"
+#include "nouveau_drm.h"
+
+int
+nv40_mc_init(drm_device_t *dev)
+{
+	drm_nouveau_private_t *dev_priv = dev->dev_private;
+	uint32_t tmp;
+
+	/* Power up everything, resetting each individual unit will
+	 * be done later if needed.
+	 */
+	NV_WRITE(NV03_PMC_ENABLE, 0xFFFFFFFF);
+
+	NV_WRITE(NV03_PMC_INTR_EN_0, 0);
+
+	switch (dev_priv->chipset) {
+	case 0x44:
+	case 0x46: /* G72 */
+	case 0x4e:
+	case 0x4c: /* C51_G7X */
+		tmp = NV_READ(NV40_PFB_020C);
+		NV_WRITE(NV40_PMC_1700, tmp);
+		NV_WRITE(NV40_PMC_1704, 0);
+		NV_WRITE(NV40_PMC_1708, 0);
+		NV_WRITE(NV40_PMC_170C, tmp);
+		break;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+void
+nv40_mc_takedown(drm_device_t *dev)
+{
+}
+


--- NEW FILE patch-2.6.21.7.bz2 ---
BZh91AY&SY
Î̈4
Úvm½³´¡7¹ÖÙïtàfl5´5ÝŠvÀˆï|Σ*’-*€¥«©ª°fØÕl´šÛejB(!tÅCëÜÅ¢Šßt¶Ô]Ö:ô½çPm€ô
Ðí7jï“ÍiÂ6ʾæÖ¯•šÝÊGarÛsMv)Ÿ}½íŸTS«‰Ów.	´4››vHÆӺ卹ÎÈÁÏs›mŒÕm¯.ç]–۝ÓfÕݹwsƒŽUlÆtnÛ»¦ÙmXôm¬Ýµ–ÚbJÒ¬Ùž.¶Ž¶«¹Ü»MlÐU³×U}ñïf®Æ¹ƒÉ66Ù±ö]eMÉ°ía©¸úóÛßg¸³½çaÀi6¹\öh×ÛºÙ®úÇžY»»m»s]Í»ƒ…ZËM;w[kb–ÙS}tv´¼Ñ†š #@h

4É “I!	£I‚i LLF’Ÿêž†¡O)úžŠ<Gªz€=CF€D„Ð4i €
ŸŠl‚z©øŒƒF‰²§‘=MŠd4Ó	
"ZT¨%kkmm[JQ–¶”´£V6¶¬m”ZØ¥e+­,¶[ZÚƒF¨ÆQ*¡R؍°±¡X´`Ëlb#jÒØ…Z$DR%¥c,”‰m©Úª¡”ÐmZ,¶ý
eQUQh(]AÅ´.s>Þ²TœH°8
{©b³ÛkMrÍu¨—i¥K[‘hÑÙ»ÒÝ°#Z˜6ÆÁC›E)|¿ÁþeþK#ëß¼œ¯5®pÑ­µJÈÂÇæR³Rí­4fͪµÆ¥2þ/[çýÏôo"OÅ÷ìyCŒ`¢§ù÷n?˜ãûXþ4~Çò寧ïúÑ4úÚä”0cù½ßÑÓȯKÁü‚s€Œ·ÒàC»a¶hTÃŒ•Q(æQšƒJPBµ¡›K¦¶!€Ùl.=É\%æÈïλ¦s†[“a)q‹(&lÛ˜æxënË„A»)CKYfµŽ”ÎÉD¦(Õ¸vÔ£q©®M„K«qµQmKn³	°ë(]šêTÅ­LmhÝmJi¦n+™DÒí3Š\´*’ݬR…vK³§ÓjãšVÒåc°™¦hêÐƪÌRÊ2™¨ªË¨×YFM‹…Úb£–Íš:âÜÚ
±%.-ÖŠ5#–“ÜÀZ6Ë'
±Kª2ÛuqrYZ™‚ìZ¶­¡u–,šT–QGµ[2aPijÆ[l̲k®×IBa¶ÖÍ5´¦£¥…¶T\ìX‹[f·53K²f»«•²Æ2º Ã\jÃX(6R…Ä-€ˆ”`¥u)51«9hð²°9N°P9Å«)b‹)jÓš¡²¢«‚®0ÖÙ`ë„•’ê|ÿ9Þé&LŸ¶îRþDygÇtå´§5írÿv~	žDHÖ•Z"X‚Q(÷Ñ´¥i­Ö‚¥©KKBÛZÊ•¶ŠEQµ¢ÆÕc+Z¬DLhR‰DV2Zō X¢ØŽÅÿ®ŽC>{X‡­¨éXiÇ«—ýŽîÏùÏnÏúØAúÈ#ύN5Ÿ½Ã#…KPK(¼ØÅ»U‰¤°(FX V×ôGròÞZ~ îÔJ(ÄEZÆË9©ŠgE0ªÑúY†ùøþ)¬5·Ãcïüܺ?‘™Å5»™‘¤Ãiû3çâ‚!‚øõ³
 Í2ˆìJ‘AU)sec©Rƈ¸‚Ê+.ÍŽ´‚][‰‘-¿rñ†¶l˼Übä²ØòÝs-k&×7YµÈJ
TÊ*é*#1K•u¸0’·c]’º(ç»c?ñÃ$"È œÔÒ]]Yu•ÌKµÖ”iQ¡j`LMPT.(7­¶¡´Öã¨ÚS%º«c[]u
0k ¢5*LÝ]±0­ÚÓœèQ›[•ZдQ.©¬°©[°Ý±¨k«)].-5•»1Q´±@JD+6£MŒ.¹ˆ‚":˜f‹+«m¥ibYD«JŦËAÔÓ­RÑÉC$e¶ë
›™vÖÕ+s‘´BÓ8¶ÓXm”ª;TÚÆ[fTq¢Q*¥ŠˆTΆÖauRÂ2™[[F¶—9E³1kBØQDEC/Üëé.S>ïµÀ:Œì²¬îvdŠ
4¥ÕRÜÊ•‚ÀÌ„2fBÆ 2S"0QfdVÊ;Š˜¥2± aÊ͆—Xd&Öe(°Lcu†Ò‚”LÊ”º¹H®s‘Re
dªƒ¨TPETX¬ú‘ØUåÍpƒn3Èì)4f”Ë´l·T6 ¥vi,Zf­5°UqM¬†±T‚S`ÓùË79\5’mšã:ãQÐsmkX¨(±®X¦AQFaT`ÁTaAUXˆ¬(£"–ŽÌÃRº*[en¸¶£g‹b±[K]m‘¸Úµ
¬JÂ؃œÉâ`ŒêÓ–¢
og’d=^þ¯·pÅ9K=ÔØöÝç#ªfKTF‘JRjå”$…üÙBõ•#c·•""Õ›z~²„¼ØÛÏù¿Ô£aùçýœ!¯V8ÿÆœIP¡Ï+ýz’ö/U|JÏF-jVžŸ;Œ¯«^œ13ç´âÏ^ü­ÀÙ±+#mƦW~F±iKÄmÍô2¥¶!ß6姇ŽÐ÷z§_§žpæé͜܍CÙ8-åu³$êsâóå¶c/+¾^K4ÚVÖë.ùîØ
…R¨Á€²sB)N>¬^jó·t)OM½æ%Qòß+ÇÌP`ï­NeŠMœZ%UÄÀM…{Ñø0éõ÷vûÿýe»Ì*„Ø•Ü4¡*¢ê‹âq6ñ„Z¹hðTóÅYíÌ?¯½FÞÿ½¼7+Èb{TV_ÌUÐ`ÄL1I‚Ž÷R(C1ò+W0ÆK+)?vûî["¼«âA¼g×hÓÿ¬µÆӝ"aCSx
LÉßY(PÆ7ó©q†³”Jnh¨èàˆeä¯;ߣªQÏpm\ZŒ§ÇO›“™ô]1`Bˆw@ÿ‚ÿ)‘AÄ<ÀܶUÙIÒÙÍ(¢Î½×­åõo{Gâã³EïÝù7xÑ
méOx‹Æ}VUO9gˆn4ûoÁœ@{O›çiz&±/g•
ž\]øµ–òãeÕq5ß•t£%ÍL%Ó§FÙK["ªˆUcj¨:pÌ”@S%ñ†D€¼(`ÛYw\üT0l2…WZÇ9Â"v–1†%¥l·Ž~ãèTÏ]èôNoN¢sP§ÏNv×­Nº5¬Çí¯—Y­Æw!œnE•¬ìNÛ÷d(’(,zYEE ²l†ç
V)S_‘ÖH)PÙ«×M&Ѭ*¦ V[`‰Pµ!MJÚ4Éq±ðI¥[S‰XÛ³–ƒLUþOxæoœ!=Wy*=—»§ý~¬—yTJ"ªZv–È.FÇæëÓ[6aýMXÀRÃÑ{uVځQUA~—ƒ
Ñ`¢*EŠ§iàíž6ù¦ÉAbZV*‚¨ª£Å¢ò¡EÊV1;mAîö¼qš÷ëÉåæ{}V‰Çh+çjÑ·("DKDìš×⡍¥g–Cä¾ÙHý̺JÄl$nÒ	"
Š/ÕÚaqWðú?½‰(q„o¿ãeµ›1¿î0I­ëG)2óqG æŠó8Œ7 at Mà8„à«QyÐçFºX*Tѯë²_
ÔsÈ
3Wò9ïlî¾W&1U÷Ú.Ÿ;ÍÁóé¬IŠÍÊùwÚ“w—Ñgg
uvk C\Ø`CxÄ
Ýòh<þ“ú;ËŽ²iÛÇn×À6øž¸8š€ÔoÌkÚš6—*ô«Ø,µ89bÍКCÕoÆìãÀðïñÝŠZg,ÁîÕ‚‰¼.ùÞwíyÎ\ü:cs!X—§£—Õ:†ç†óš÷rN¾Ô¸M‡dÕ±°Ì`*£í³|,Þ¨¼ôQñ³[ÙÓˆEA‡^£Âz<{ék£“HÂÅȏÞU™òª”5O]Ëø7.ÛgtEœßµó¸ïjŲþÄVE£ùxH²ð@äþÒ7¨~<1÷¡qmQ~GkÏ£\•ø~špaÆ™†§é+¶|ØbÑސK,á“¥4¡F•'[Wre
ª­<ˆ*ñ#¤Éʇ‡mܘ²#«	¢€zB¡StÍ…Ø•X}KÒɆêܤéšþ¾›{ø¼Ó…‰zmšîJ˜8ú³|/[ÌãdÌeÕ†ÝÎû]ë¶+Î!D4ëü·ÌIIw¤7dª¾:X¥å£fn‚$Ÿ^Û8›<6Ðõ³ʤU†KVâIÞÙÆ)ñIÆC*ÇíeÐfÈÅ–0wýõ˳ðwÑ*º‡'&U¼qïÿžÉRÅå"Óh̵‰öÐ}Äý?os—ê‡A8rGÄÈÛǸ§Ãõ'ßÛA)Q\B¡"VmCHm$£,ÌŸiցö¹®œ¦¨»963XÚ–0ÊV£÷
{BS¾Ñ¿g0ÙÖ—eÊdíû¢‚iOJø•LªFk6X ’¨ªþ‰òÖ¡9þ|"iøqÜz³vä Ö#ðM¥Ë9¤U÷¦ù¬V°^öSd6­%¶6£–öUÛ‡îdðý;«å›û‚üx­i’[–yJ.JÀª•*„((M§"ƒÁ vZ1áb¢0ÑL®¤a,.ÊÁc+Ó—ŒÖÞ7bf/žÖãYfÇw-æa_IFÙ¾ÖˆÏ^¼é¹;Þî§^¢¯
€‰PE±øIVËz,Û!U*Új!´Þ°#Û8øæÒÎlö‚[0{iMmRU™Õ=ŠD:ƒDIÌ^µÕj/iG›ûç‡êù&däOLúþÐKUnï•íé{ØmÃJóY%­ÄRPÊMd?Ey1QšÕ¯J\Zו-§šÓªÃwÒ²"ˆ}	g’ITÚÑèœ<ööÞ<<,á˼{×”JºÝˆõ€rCA+ðõ:däS@×S »c0’@þï\ãÙøß.ãg#Øt¿OÓ·Õ¸QÚ…·„Ê”ÅDŽrӁÌØ\Dås·›dþßTàYUÜZå|Åð"«Ž1ž*Ž‹?Ép\?I˜ÆîõAŒ’ÛëM!ʐúxF¥_6éSD•^É´ií¨¤:Á•‡f&Ú£œÄIñä¨ÇG£"×ß¾;¦œk
ä©~×px*yQéÚźÈâ•û,j¥DfˆpªÅ†(0Yʾ¨Ä½­˜;Ë1bÕׇ‚›-
š(ΰÄ(r—|²CKB*®+Xq>·ã¨èÓßô벑÷w-xnû£AÿðûeLÜ<*ë¦j‡oÝskQ×·4œmA96é¸gàá\ãUcñit£
á·/õ<;´º³…%ûFð9k¿jKv¾7Áçi“)ò1£Ò!/ŒB׳D0R"Ȫ)
¶¬ãµAAM•C! ¦KÂ(‰þjž¸(?åKDÛˆ€}±UB¢‚ Ÿ,\à
–DSóâ„üÑ
DýÇßøïºëüK*~FHÈe
±?ZßøÐÿ5]ºª¼Sï/äÀÞ3øåbfx»¢‹Þ÷~Ra¾çŸò‹ùÊÂ|ÄZ*þja­Ë¥_áæÂÝ;-°–RÝûåYÊ£ö1¾'™ïå͹¹¹®©òý¿qpcFÁèB¬Ê|L,ü?Q=®ïäJ#m¡¦6;fÂz3úþ
¨Ò–poÓó“ë¥0´M€‡‹‚~V0b+ÁoŠ»NSWí±Y/Íø³ñÕÝèùˆúÿéF’ÿÉgý:š™(iµlŠÕ/°9d2ÉjÝnÿÎÑÀD'hP½Ý*{Çý„œã'gðl’Õÿô»™XöU¦ÓLëÁ)?›}õŽºá±µiY(ðj‚e>\¨³:		zo>ÇáðfH0Ø
g'3ÂÞý?üÿÛ«ášÓçàºÄA"À–;Õ~öÅŽŸõ&Øÿ¶	$ïp]NÉN¬ñ¡ö5“†BhPÕ
‘)^²¸¼²Ìû0ëo1_ÅgÔ©ç`¨d(a\÷sè`üK,8ÏC})¿fw	‘´ØÝ\±EŠì¬H~¯Õ˜
’t_yí)û¡7PTS-¤Í7zÇñõ÷\53û?º‡£€ô?‡†I~£V8Übs_,Ç^—0×°K2_°ßjU ÅŸ+9èJ•ƒÕ7æ\°¹MñüÐ7‘þªmú#™÷D(‚†èaÌî	ž‘Qᝐhvdt°ðãHc^)ÿkÒg
 ŸûÄ=E+Î&q	¶¨G{ÊîµÈ±ÞÌH¯iÚ@ÇQàW½4„ã—sÃHRÂŽÿ=߀¥Y@}¦gñU$Gëꋁ
*2,Šz#!¬³ÔzÍdPÕ¡_ÓØÉM}X`3š ‰fOM 3ÎW°»V¬&˯Œ+ÒíÚƒTk³¿¡3KB*PC_Â’óXìƒü;¸8êÙ\ÇG²áìr;Á~è3°V2Aa÷èôœAöðöþÿè%£Û5š¥eº9~Ÿ£Ù§–nJ³
áݢǏñ¥"CT‚ÁÃQFGúAeþ.q+HÛýªŸ+êbTdž9†¡+ˆyËØ}†Ü¹ôùnú&´ªº8wc±ˆ£lmŠŒr¡ï飳å_ÌÞd¦\
†»¯ü€ýÔÿæXxû­¸ýÖ,žÉ¼a,ÂQ=`4’º­ÉGRx†ûâ0lØ)ÀõTërO·öëJW†tM
?€öÖ™ýu0úèämÐÉSb·ÄXÜÜ÷vNã@™Û×Fš²Š`ý =u*det¤ÂhfŠàA6@Û.à{=ý}¹ŒtpßÜ=pCäåø<uŸÚ1 #ʬcï<‘	jAþ×i ôWý	ÎÅEU
¨½§ÅìÎå^†yb6‡£n<ŸÂ×[KVs†žçœKÕo‰|°Ø…S‚Æ)]VŠB•†…bÊÝ3*È-4Õ+ƒOAŠÂ°(¨eD,…“WNæ%˜‚^VÇv˜ÑšÞk+Ï‹1wÖ^|[Å8ámMÊ+nÌ„¸`ØYa‚¥­B™¶™‚EJÆ$¼=™ÂâIYMBµ5´˜ ‘…V¼8pnÕ‰&
Žõ«‡Bv“È
CŽk®Fh7 öíåâ:o“(aˆ³¹õ‰Âùño¹£©2¨BÆðý&5„D@=CÏþª‹FÒOËTHË
ÀìTëúëEM
ÝߝCÓò7Áÿ#í„Šüî5žq¥PùÝOž¿UV<W!ÛKòϦً7e—ãkאê®ÑÆκ}ݯmÔbvÆ9gÏ89ÄïM•·ºáà×ÍòÜð°Ë)]Y„*DÙs¶éâx§z÷¸kûǵ⮞۝D9Ö"'Óª~ÏóýLÜŸMiU(¦\rp·ï|^¶2<y!(GÎ{A]vz`ìR…	Ñè9¾JžW
I$’š>ë[ÁiYX¨ÐºÍ^»›
Hc‹*ß–,ë–@B!ðƒAFjɧž¼N9XO«Xª¿“ØðÙL˜­_Ã…©n,'¥<½oÊÅN߬”pÍÝ-*
œŽ×f®’·d_®á^hv#n/"ä¬>Gh큂2E‹³3,ɨš®óšó
‡nœlR4–mû!¯Y6pJ¹3/à-ÍÜ4GÕmRy&¡<qÓ' xŒþÞ¨7PÎTï}æZ:xõðvìÎhßHÌ1-3Çøãâu4°@ž‰="›à¢nzŠB]°5OÚ;Púr2Åúö¢æ?U|¹z­Õ_«q1¸ß›ÒÜ¢9áfÚêÞ¼hs€Zèñ	‰WÑ·†‘ú$’•ó»¾ƒØ«Ò f„f£êëW¹B—ÕÚÀ+ŠÈƒ8*«‘P²Ú‰öA"¡B/ÜVȉ!ðªòÖÁaeÝÜÝ0c&(²¸pЪfÂÉ’áÕ*áÖÍ««C©KÃIi¤±.ñXÅ܈4Î8ÁIq‡TÁeI	$*á®ÕÈb"‚EÁ–@Ĩ¼b1f¢ÂÕ:«Ét·Ã9
ˆ6áBÄb-­±ˆA¸V!šœ3Ð\;K3¸( OIKMþñûÎ@Ÿ´’Jõ7Š95þß@D×æšwÛ:-i¤ˆßAóà5Gùç‹Ò„>ÔØ<|EZ»á´œã°†¡šµ•£û—òÿX׳‚s!ØQ:Î’00ý‚Ã÷÷ÙÂÁ}Y(ø‚
+s‡™¿aÚr#ù!¬}6Ši¬åª$òù¨ÓÒNüÜú¬<³ÀóðºDýê6Ä9(È{
>åS?¡ý;.˺m¬k뇍|¾Žg¢8X0R£'/#£`æ	?€ÅEZý¯¾„fþîÃtIåž¿’’YœPœ
(ÅX„	¬eˆTc‘	"àG§˜ô£„±–Ôô|µÛõøëÓÛíÙá¹û”‡R:QK9W° hZµµ‹=øUýûÏljá6cwíêe…+Ô×*z@äEyÔ8ÁÖGÔ½ñ	ÝU%±#ÿ?±ñzGyKß)äÕŽNµ¢÷ù•¥~؏N„~‡ÌƒüwA¡—›Žyƹi¡Ã7aéÁÝOððÖó3`ówÐB%*–‰ü¿=øÇD¨Ÿ$ù™¦¹wà¨NÓ–ß•0èSàR†CLcÚ
!J/P õëì?—ëMä60l`¡¤K2߉î00ö¤é¯,J•Xс¨DȘý^ÿác,9\ÐÄp¡6¿y:”Mv€Ÿt€ð_q‰GH¡!`T8'eŽ»ëUšNLó¦ÛlYv3î>îJªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªªª«ñƒ'7Å' QÕ(¨où³Õ$´¢À!¬Þ‡¨7¬‡€Öj]^±/áQš/–{8ÿÒŸb.ƒÁ ŽÌ‚J¾Xö†?Ã|5ß<¡þb:iŠcbÛZJ§mTSz…‘†×ÕDÝEbÑñ{G©×/„â€Æ]Ëï3#æ¯L2²ì…Á~†Ó€QHdƒˆ…|°‰CA&_ËoÀ9.JGŸ5„…TI‚@¯C¨ÝíÈì""ýÈëÁ”îµjå0Ðîz_M¼x0Œ)®.̤s„{ϺžMµUù_Ü⪵Zªªªªªªªªªª®5UUUUUUôµUUUUÍVµUUUUUUUUªªªªªªª­UUUUUVµUÍUUUUUkUUUUUUUUUUUUUUm¶çÉ×¾;W*T´é¼8_¥‹Ùœyg…‘X% `à¬Î†Äk3áoäù
í³úó>ÇDJ¿²"v¿eƒ÷
Mì’<r*;ÝU××T
ïkˆæÙ[•n»Ò»©ôšT{+¼³¥XÉ
*N;z¥Çèµ_fÙr÷ïÝR›ÊjnÞCÜè4@ÌÕ>"àjgT¯ž~ß÷Žídæ\	
¸ù@È&®×"O…~´)¢3=»´°©FTàx7·
–±ðù~%µètXôøã<}×ZÞÖ܏bëZ
£
˜cžøðû~³¯ˆ»óGÙ¸ÞFEF+…ÎQ‹VQ½<††ß.äÑ„(óƍ(¨Ã\EUF4A±Î1®ãáÙCA†¡Â=ō,c÷óeðÑ•dúH=JÛ|/
xwUyIáùÆ´UˆD°C‚S*í_ at BCU‡À€
Ó4ŠÁLVäðšÄ¢…»yÐàÝ2>
#ø·0/{2%iÄÐ\D鉣Ø$3”îžÆ’òW°7êlIQâzyÂgLÂÄúžÞi"œð¥fLj³ ZÓJ$Ô&”6Й
p¤Xù}	Ά>ØíopÁç‹âl:¨8¨ÝTu#˜!¤Pz‰ “ïxĄ̉ÌÅ&¤d~VÓû<Z ܼfﺕ(~ÀØOÎì5j×TSÈzn.][›ËóÎI Æ°Ýí¹ßTcXw¸¹Ê¥W"Vû£æï#uOi†gð­Áûzü6Ü6Õ:‘…¹ëûGmÆÅ•Ù#O×%—êÔ$8Á|
DE5¨²ûÙ+µ‰-[c˜ÈˆaTû!D9mŸ2¨½,Ue‡Î+ûG}æÑdµX9Ý~¦4úµQû³Q–…=ìE¨H”@6–h³ÌùˆG¬Æ<À\¶é¤.êªHõl•ÚÃýb‚Œæ˜ì—Ù
%/#צ¾Ç?VŽZú>×èše-3݆Ï_4D’½S
{ÇÓçý5@
5LTôû1°;ù¾àn:%Ï`SMºTnT}@’˜'j’£¤2Œ™‡Ã8ÌÅW<f'8³ŠI(Gí¦šWâþ² ýýÌ®å¨(_It3
´ÕÁp]U•\,>eQ
›R$q~`9&Wîj))È:ùoÃÀ‡ýn=@î©_è¨Àá[;KUÆ™ÜùD&7ÌDnì×ߥ£2¨úy»¾,0W.—mºÜȵ/·ha¬Á

"6Î?>Jú&ªMsÀŸž1Û*qõøüî;(Õã0rŽüÎGä7Žw
`mirnf8Å®}ùI‹óyëâÎ6YÝÉÇêà~ÓW¬žnT)G•Ê¿Ù÷bÌ“è–k·qb_WúØdAÐM¶ÈÇ#qÀ§&++*ƒ5W¿nZ/m(¢­Ì–ŒtquÔÝ¿\×͍1«ÁðÖC¡“âïfcØ1ÙÃm¦†’(º“|]àÍŒo…Ž:åÞHÞX\ˆ˜[Jr²JÇá`«ò°B©Tž:\7‹c1ú’Cg8ÑÜ–O
ÚX¯“ðÄ¿B®ÍÎ?`ÍZ†š-ŸyApL×û =ôl„¥‘C×ß?/¤*fó3¾zòYUÇ:Ö©Ä&+
[»×^ü™…þã9÷µS6„­5'·ß).¬¿Êl8÷á/“Pz½É7ä}5xîÊ0* ÕŁ6¿,^ÜŽ>\ß·èö~?;íõzyίOº—§êQdUU€(E‚‚ª‹$H( *¬D‹V"¤R"E °<ÝéëÀ©7à*àø{aç+ùzzçQ¿UqR»YH/åºeŠÉ8ǽós«ÉŒâ@K#òL–—+1G¯‡üœeøÞܾ]6òŠ¯´þË\Ê*]ªEß@¯>‰Y…RÞ:ZÉîÔ-~àŸrŽ%–5¾²¨Î#²1¼’;`¨SÕàxuY0¢–3Â\€¼Y6ËñŸS„>«Á^V¨éð{³1²²i_¦ºHÛéi2Bõú4g’áJŽw Õ‹10˜ŠÆñÀäùæp”(Ö„¥®í³Ç¢xW Íào¤eÛ¤¯Ja‹#Ö¥„èÖä)mŒê[9Û\Ô:ÆTÍHÀuª)‘ÎDC‡ŽGÍ7<Óa¥b):l°Ç,¡ìxb9Q´­[†žq5—Bíkä TOëUH ¡
¹N–î¯Þö=Ç\Üs½ÖœÃ¤û1®_M®ù³
,‹ÈÐ$8êÙ­sˆ•ášM>/x-1¾JŽV¥GB¾-„
‘³ò4ÏÒ8+ ìâ«ÜXAëâqÓetxü½y¢s
ñ¶Þß–CƒÊ®ç.±
ÉaÞÊâ‡ÕÙ„ƒ6#ÞÀ¸Ï'üîu~˜àézÍæTƒ„$¬€°Yî@¨¢„Ó²”Õa‚’`a>D(÷YìÊn›­<!;Ô;úüßköîïx‹X þÓgæ>¤ OÔt”7¼FÚÿ†äåÜ”ìôzOiß³¾9QG(ÓÊߍϛå)õ½›û©ö"ŸÄ€¥*õwùËÇyò-.Û¦K~ŸDUžÒWtF»ÊXSYŸÅ”|;Á ÿø~‰ü¾À«ú@tµ“àB”
ZUOžŸÉóY$Ù	6B¤(Ît°Ä¨kAíóù>@áózHzý°ìJ¹‚åÒÿ/—ù\¾1À¿á`Ø/pWªhOÛþ}Nò}ý¢íÎ(ÁBìhüë·ù¢ŸÍ¢~´‰†LBü&zÉ›s=ãÃwhÝ­òNþU$¿ÅI÷*…2‚21"¬¡h»ZÏs2
¹+å,‡Õõ5«m°FÒÑ(VÚ[am-²FÙm‘Ae¶Am¢QbR”±F´¬­µQ¶Œ¥-¡m…@?ƒ²ˆ}yš!ÿçõÝ¿O‘žR2}ïåÞ?Üòaþ6„§["XÉk45;Gþ́÷ùp%Üü
%.ßßæô/ÉŒ?›§œ”
;n@Y§Ïúyýq¢mö$?Ø„Pñ`TŸDLB6’°“Ó«ô\›„œXße%Þë?ɯ"Ü1ö7î*©÷¥lG盋)üíâðéŒ!ŸÎ]Óò˜Àad»	"ÏKúÒၨ\)zi“‚
–Y‹gŒ"ý‘¤‹ÆBŠA ddS8,\X␽?ÐèùV¹¬ŸŒ,7Åà}·=D§¤ðûýÞžÓÏêâ<ÝSO¬N>aâEõD|l2aD–9V}ýl'ñ‘«é_Öª*Tr¹6K Ž
§¢¿°UOáó?ÑXn|}
Oj…˜åT¿ZeÝßwê×ÿÿ8÷Ä"º©1nWúEa|²¦Àý²}¾Û„»YÑÞxAjB!óJªMæÙ©?´þ šŽ«þõ^”ðÈÝ÷R^ïs$øboµŽþƒ—þЮ‚ý7Éøúw¦‚Þ\Ìjé‰Ì/#¼¸½GZ÷šÓw¢}½¡4ƒ5uï‘û™­>˜~ÃÄ•ÀȪyÄúšÙ»eÃõýÈEÑúB‡¬ã»{ƉRh¥Òk	Ò¼ü±ó07Æû’<ìï3ÌÉ2 Bpz½_¾]Ÿn½‡ûüúòÏÊ/üVH‹f=ó¿­?ãåyíåáC êfD¦šOSðÊyW‰8
`Ââ|Ã%ðâÿÛ`|†fš*ÿ¼Óëò^\‹ î|¡}ÑèI§N‰ë¥—©áÊŬ–§s:áçßc䯮†*Æó>Ó5JDZâƒõ¢g¬„á?$A‚ƒ3Ì„¿%r¶¿O¤º`¾
CúÉàj3#ò–0
ˆ÷—±±D¬R~ó^ýŒþ¡í[.ìÐåÆW&Š0)ï3‚
kyFóûj˜«ã3 o"L“ÃF¡YË$ó›·=>f¤#Á Éˆ5G/i]¿Ôf¾Ê±iGÉ‚c
F|ºx¥;ðӐ·s+ x°?y9Uõf¥ ×3"N¾$-¾±*‰­WÜ=Y,|aa1&!Q¢á©7p ¸ìCipÄ“ù~Ì]·àBçЩâEàÏønè³ ÛäÃÑ…æ9T¦mmj•kEÁ‚¨Êq)ÿ[_Wþ²½·UŽÇ; ¹(P|nÔžÈC¥1,fã!¨Eœ_¦qOC…O…L‘g=¥±
-±¸õ	džÒ£Å`XÜOçÅ>Æó„™m¿Z"45¡¶Ûm±ÍîGbοìfæÛaDË-S1ç…}²…ÎþšR†=·íS­à%¸mhɬIŠ€"E¥­Àÿ`tÑù6UØ(M¸Ü“&¢ñ(Ø€}pK1ΟÈì‚åßu‰2w‹õ4¾zÉ%Ž$žêÅÐØ@ÈÚ
°ç<âgï.?ÅGóòÀÙ˜ëbóïÚ,û£€@¤a³ÏË°a@OÍé¿l7„h(¸kñrß½v82¸z at qM!F’‚éÝ[ö	»%]¢{GEXʨÂZ^̽ŽðaFÈ|¹WVä´7”W°M{kZ‚I±U¦àE¼ƒrŒB8!ã>²NUä[öÊß\°Žñê¦Úfý5ë­§výu·…Z*tHÑ–§è¶ùÝBÕ:û,†¸ëÚ»©ZÔÙÕí.¿&ˆºGs‚‘
¦ó
Ú,ùi¤G¶oº
€~]¦n	Xí|‚®‚™•ëaIk>vÔý•C[?	Æ‹Îtp¡ßÎ
b•°Ýl“·‘GwУIÝk–ÆÞìy‡úìxy¸(£°q$y-Y
©>ÿ¢=@nÈðÝÃjÙo~œ8ãn:ùªìÕ†>XPºãx=Hÿ/©ÜÑG{ÆžZv>¿–ÜGF	…ÂcÛ¯ˆû“ÍÈ2°r0äa­àPŒÏ'Ü4Óëõt·—>¿+ÜÛÃÓ8Ž§æOª)?éê)Ï¿Ì9Žïw`ˆöG*ùGÕªÓ@:Ó¸”åÒ
Ÿ&}ñ‘O||)¾7-6êÿ`äùKŠãxxÞ·°ü?oôßL}6|™‡·Ýùó:c¶¯êé™çî±Ù»ƒyÎèeY`Fpܽgç#C᪮è(#B<
óo—Õœþx
äm¬ö×Ô‡ ›Š–‘êO:Ã:]0î<Y†¿.-Ï
Íâç‰9jæ±Ã‡6ÖþsÑÍò¿øüzøZ7%ó¿MmÉέŸ'Ãcäû0賄k½ûô‡¡|¡aÀÔÁp±{Ç#²ËÕô’Û§ûh»]žð›ÃNÀ¨éGßÏþ/囌þm»*Qq€áÜÒ¾ïǤóõ|¾Ž®Îñ×Ú]ÙX²ý&Ö©…G>íν#G¿-×Ï¢û…€ƒx`ØÎOóvKzï†?8ñ¯ëî®ÎF¬ô¹]f™.T†¼iêÙO;¦/÷G„.}Æü¶ôÆñ‚o}ÕÛæßê–À</žú¹îÜ°r¾¬u7
rü€ÿ–ä¨Ù‡#ŽcÖÚà=+qróïp€ùˆYUÙ ðnŠ½Ë”±qm³ÀèûÆÍóiˆý-šýþ¯}BÒ= æ	"ƒnŽ镃ÒÓüý;8nAÛpGdˆÌô
ûù®Ú}Þú¹)â“Ä¿Ê"©ª#§ÑÐ;œ:cðÇom-7Τ„„és9ÃÐ2ZÃ
k·]ð®Av=ÂÁ…[F¯[¹íÔ¥°ò֍sâ–Ëg†×Ó.ã«ð}<ÏcåˆxaC†x
jÁïªjÛ–!þÕ³[øc+%Ô¼I)á_6Ø¿êwv¬YXàG
®w€p›ÝqnØÀøÐ.ˆËj»)V{ÒîgÃÀÝ»Â9’_<3Zÿs«rÂÏF}7ôèñøK³<tê~ù²“çՍ™ÂÁéß7÷XZâ½ižŒGRü7>c½xR ûÃ__^;'ßkVý<óKk—®=Ò§x¿ÍEóy«íÏB8òOµ›ŽV;þ¸¼Ç‰ºÚu×ý`´¢Jõ»êᕳÁcÅß
±´Ëcq…¦¸ÎwCá|£Óä©Ù_¯þÓ«ŸI)óœºÿ‡bF_Ÿÿf]‚ß/{Iôå;™	Tk寷¦ö®·Ë`«—PŠ§¹ÎbŽT^ñâçaÆ>»™ùK.G×Âý›„°Ÿ² ×kŒG¡î êô
Ƶ5
Ãü
Ê1.Ó‡C‡®uöëôºÇÉš°`6¨E@ª‚îe‡cáeÌÍËöꅏ„©múeçû±3_£º9«Ôo¸¶±Â–šëŽår
`8M9-÷Cl+¯¤ó%<=5á_š7ÞTëÖÖ[o£Ü>=¢5J|ÿ֝ÙÃð±ÉMs{TÃXãp¯ðŽ»ä.Ø0î·½©_haXv®C(Q­-辯f¾ul©ÃWFýTÛVíÒÆuSJ	Ø—šÝïίt•|Ïë=/–9t5LõÁ~6oîÓèør靍¯Âº~o¥ô÷<«ûþçããö¥å'Bvíçý#ÿAŠŒëQdDŠeUACåCh’‚DA‘d1‹`¨¨±£@YPDX±(¨±V,`‰EEˆ"ŒEŠÎl
¬ˆÀîd ŒaÕ ‚ ˆ1„bŠ1DU‚C«*EAdŠÁˆ1EAb  ±Q‚ÀÿB’ãÊȝ(¶ÕXê ðˆÿÑz üâ«ü"¥A 	"9çG׶•W”@¨H
Â#h»ÆC„aÄ!nÀ»Í Æ(—XÉ$ú© hÂC‚Ag5!3´CýQTDD	ýÐX*„ëµÒ©u*‡Û߳䡴=H÷à$Oá~'óý‘«vŒcG%ød¬‰öD}‘ùÈ
œ¢©Ñ*ñݪÙ/HÎ|À~>±‚¸€†îŸ?-§á¼sêËâ‚˺æºWÔ¡øD7„í§¾NÂO•u«•]úŸürn¨î»«±@Ò'«ñ¸ùTԏ‘÷Õ²UjõêÕ²¿domhÚÜ1w6û›Bãߧß+œ5¾öÅôXŒ­µ×4~šù&ú@ÆŒ³ÓâÃönÁ×Þg€Ê·â¸þ)‘¶ÙÍo±…7ÄÃDk¬WmÆ·—p3ù„dcìåÐ,HæQ›ò¹·
à/Ûnäû:/¹ý[3µSö›ÓÀâ@ûé£õàÛ#Dæ4YrŽ`5À:Ou î¡˜#Ä0`ÁºWø§²¯É¼jUåÝÊÐQÄùôÌe’ÓÐ.LÑ(=L;pòAf~Mü5pGøó¿kë¿€tHØôqŽä¿¸¤-Z÷=”Ø…Û%Ø&˜¸QÂÔÓfbT»Ž(D
ì³#, 7&ÚY‡ÿà<þ=·p|Æ…¬p±±yTY0ÌÊRflä†	Á6ïëýçtÏ'‘z%Iè.¬Ä
ûÄ2ÔáÓët
³·Æýµýw0’PÜ1A¬‰j2dùƒ,FMÌ7ÅÐ×ãwlâ(!¥TZžþ4ùEӁå²ãX°Z2
0zß™„Eð
>
ë	†"ÿ6‹ñr	äøˆ
0z|9†á sÖèHfòúx¬UôøºåU}™Ž°•L×O¡CB«§¡Cí¦}K«Odùü:F
I¡÷mÛ!ÐØðÑp;<èÐôb¾‡
êНX×¾×vŒ¸>0ó‹ÿAV#áƒ.kY¶0àÜ
SNœ£§,kK2ªb÷Š[
2LKž)_øf]L~†âIê.Žñ†¥·“aƒ¬9¨Ã±7¸pð¬p14#…3r¦MT(ŒE²¶'YgFêš"	Ä4´=$<Œ]-*¸…Z*
=¥‹šœ`4U8
ˈgÀ‘‰Ã3EµáV&pgC-7Š&ið°µ$+*à¶dÅâ¢ÙŠ°0.Þ0PÁµÀg ´îÞ°)©pÖ÷0²&ð«‡v²Ò*nÁZ‡ÆH"ì㊅²æjUdDba™ªj1CôY‡âÝaíaTÖ(̘YiUI4¥¤^8ŠlÏêÖöç†y‡¹q
YaÞ*
±–†jª¬Q‚a„S›º/sb$Ã]—*áqC²½Þ0ØRÑWHø›ÅÅ™Ä[«ÝLªˆóaZñbã·8¼v¨V‡{‰
¬."âQ^ZœV&ÕUCÕÄaÉ»¼;-E"‰wQL.%Ø6?_ô/Àè?¥)ú`)ýQR~ëU	aCóÿb_õ‘U
C¸
!à`ðçuÞN6à\,H0¤r®¹2Ey3žÞîf&1(•®FaB˜‘a°¦r‰qPÀ¹P橉ք(£UVí¾¦Àx-!\Á—9›òÜƁµ¶ÖüMy•±=°1<„‡MÛöëHÖ]j‡·ˆªx“·0ʃ/mÐB
ò9/†73J…û1–~ç&Bàr	âÌ*9׋µ½ì!L¥I‚s(n*C|Q‚ }ÖEŠì°J‡!ub·b/Ë¢”u5ƒg ¦&Æ‚P*ì²¥¼©YÞáôÀàˆºï\èPä	SqXÜÍÄ"C…È5±™½bk‘©‹bâÆ66“mšóC®­ê³2J	%è*’`ŠØi½<|±ì:¤^ñ‡I¥*[¸ÄŸ!˜›\ˁèiñõ@Á€
¨f?Àþ€t€ób?7Ä:§mÎA`ßÏÝÍÉ^’éÐUnÔö°šj
ëª2ì›À.°=GGîé
<»àÌI‡Æ_37D™Þš4ªÌUuWv–­×í[`ì¿XÆ”bpîÇ<sG‹â5ÆsÆûj«9å×~2¼cžsT1uŠŽ+QÆ6ÃÕ¹~X¾v
Wzmͺ'ï xTg9Ѧ{éA¤cœ âÌ•ÊZ at 3Ï“ê*•U+rò)g®N†¾3ŸGªA
Já]q¾;žju«Vú7¥7-
AÍö¬8è`WøÅóé<=.³¾¦vK*—ï–Q¾.{CCh²Ùa:°«f†µún™œL4­V™é²ê…3É…VGs-ÊV½xaܧ'RrÆÇG
Û˜Þº.·Ní¾Áiׯn«d&²¿Eú©8ž¥p8cŽQF¶y1Õ·\ë«Öè]MÎNˍuX:vÁ´—l¤è¹Uѱ±Üí™nµÓ•ÑD3|¤3®8Ši€˜…—}ûc²‹3˜Ü®eÒê’N¯9¼â³Ò«kJµOj³)–FÜôÖÒÕÛVêcß–¹éÜ«»^)›×
Já]q½ù:…uÉ[u‘S+Ma,8ßÝKõípÝá\ž¢=F'Sñ6(H·ö\\ÊÂøOÑ©¿¡o2€¢¦ðFÂÉ"¨	À0Â'Ç®Õóx{}~b—ÖÚ¼£±lÕ›Ëêó¬Ó¤iF½:Ös£tuwUdÞJ^­«QØk÷åúŸ. fri¥ÔÉ{¶Çp2‡"È ðTßæ_‹à"û<tƒ5²¢Ñ:žÅ
SþX†ðȧÛé‰EÏt¥ÃCá¸2©ìTœêq'övF¡ï(™
|Ë7Ó‡½‡ïŠ!ÿˆ¨ΧT7«û'Ñ‚V(#þL «u¬SŒ–0EOÆÊEN2ö…dRªÁŒ‚‹(!Qb"B@C(æÈ}ø]ùþYzþŽ‘ç`wðõ’.ÄŸx~?Î~C¸=ÀP~Ð7†Ðú¹Ÿ>à¿!Ø'PBh>Ðû‚@؁ f6¸*È(‡0 `ƒ˜/ÒTtõ¡¼?
`apæxræ""""""":¡È;€ó‡œ¨0‘t`Já d#Æ1Œb"""""""""""83P¨0á°.p`aqÀh!Çpt~˜Fˆ8`!.
‚#Þ‚""""""#Ô0\"0øwCØ `C:>


áĐÐa b,‚C
!Ä)Èy`˜uÌ@`ƒô†ŒcÆ>HK
á°P4
BC
€ 0¾!p
¡ø!@ÚX<‚à ÃÀò g?7ù4OŸŸ©žô!~'àä>ÏüÆ$˜äêž>ƒ4(•DÿÈ^®K±<†¦,Ƙ@7ÅÌÂM1HU½©e»÷\ÊJ-Näs¦«ÿòà€d`ƒ'	Á‡¢í7·÷g2Óh†ÿ®Ñ“ŽLìú:Äe·ýƒöÁB1z½«xß|Qž¾•@*\ÔÛõ²e3aÑ
©€¦IYž°ópRÁ¥.ÌöVÌÅÕê0c¿6Ù5Ω¾1ílˆGÛ¦ÖUÜ–w§ÔÌ 	i¥Û”vj”ƒƒJïʝà"˜;Cº{ßzjs»Ñ§<à&C&¬êÖy“Æ! "¦hì€d4õ;Øéj㐽…HÝÂØ$‘…{š8âÁ{Í25˝ÉPÈ–%
0PŒXjì«ûªT;Ìã†È<u…è m؝ ¿+·‚YóªP)NI$°²«ûJ‚G|»¨VŒ»íŸlGBW~$uíÇ^äDKÝÖ¬BsC=vœÈ_EóÜ>«jïQ'	—¤œK0¿Ì½Å‚" 'Ž˜„KÔÏEÖ¾¥ aì.60Å+Ç$/¡E¼Øh…rzPìHO¡„¬¬Rm,6DVf†fS6|ƒæÒ¶Ä#ý?ç’ÿ£)Û†ø©‘˜:;@ï§íÕçӫͼœG–©}<|½qňÔRávÊøÒs›¡S€÷¤nÈúÌ€Ø~úÒÌÿM°-–,gðÓ·!X!Sò2ˆÈ ŒŠEA‚Ɔ0up‘=<=î­Õ­ß¦6¶<°ˆìt¡“Cgƒ–k«ñ¬Úñb¿Ã¸-,$/ÚX©†L5j„£`‡Îöcôôÿ8n¢£Iü™/Å¢>>¿¥‚”qÌ@­TÚ¨3åßåü½6=’Û‘ÿ|
[¿PwÍgg>ùàÿPXÌ»¼I÷Ô	ü=5@š{‚}ª^OÝQ«ó	ÅUS7öNlbÛj`Ëòž¸>¾@½þ0%ÎÙšp¹:62ž)Î!·¾±2D7¸TÂ
¯f7›LÞ÷k!à“À(òü€(R‚ªÅfìi°ÚUß&YIüƒr¸Ó^|›n›õ×àD6Þ_–1±¶;“3†êúißm«"C¶É'l."‡GÑÓ§MÎW;4YŠõ=g¾þ´&„þkUdF^QR‡í'±Ÿwn5ôT0D´NýÓ#xù+º
ûÑ€K¢˜»Êr†6uçøØõÀ¯&³ñ
PD~¨õEL¦XåÜc
çü…jSáÈ&@$@;.—-Òìu¸ÄrXjUPªJý­‡N[™G>½8pÈþ—ôÂùo6d=^c
¸Áú¸cc0ýø†ð˜à9M$°Á¾Ôë;dØ‡
u9S\aýKAýèh`+mhcO
ãÏñÓc§
Åüí¹¾\˜ Ô×\fXú8{Ÿï:£o
x!‹…#–˯ÒԺ︚NlêLS+’¢Žx®æv€úÝè‚·¹ÎØU‚hѮ˧kÄçV»`®Ü^ü±¢¹­gfŽ8Õ…´¥ŽtØIŒ Ll`ÀE^/Z³vN¶Ì›mÂ̍ºYqÙÄʧ
	$°/1úîà¸ó¶|ïüýá¿š_¦¥­xÍǪ¥ÎË+ØKnX_c€½,^\~ŸT
á!8¬Z0ÆÖU±‹ª‰·™•ÄB‰
ä}Þ–:ÐûǐgÖ)t3Ñ•ü½°¸TÎwZÍŸ¯7¦#›Böi•²Â,g©]2w廋-XŒð³ÀÓývþ>ÿmâ&lÈè5„¨¼þï9=ö—*íéÕ]]„¬\ÿXì•Õka™:{
ÍEÙð’°$š-ZÞmzځ†ì»ili}2lcî@ÀH@@0?òŸ¾uë
r‰Öwñ¾
ñ f úÒ–e}“\‡|è%H–UD¤ù	‘«F5³ æ<µ±ë°œÉ°fen÷㡍ƒà÷"z“xÞ
xvêd?
xƒµõa˜gê}ï50ýYY¸­xð½xçμա;¸ÂéÄhS<³u´ïñï=<{Ó¶ÃJüo9®{ë<kªÕMWVcŒ6ê,*·*ª«¨zíÔ>uÈÉ\áq¿õa{W¿]<_[¼P¦,îR¡Õ·ã‹õY^uU;ä×NÌeªv`¶Õ

YƒG÷@Wœ‚¶¡q$\«i\ª&·’
|ë³=tZW;¬®ÚµÎªí¬†6]kReŸùÚځ‹8}'²x at wÛl`Ûb
pÛàöÏMú€DC§®¸®µªãÓZb õfõiúo³HUïÊ(û
~>v‚Ì@6	-´ß\xDv¸
46	7É¡*´Ÿ÷ôÂCìëïñ';gX÷ë‡î×x™kÚBéF-ê*éáí^.ñEíñ"NÀŒV"B­Ë’Ö„ùö–Çn¡8qÓj—~xa›Å+ÓÕ[ë×ëî.F™ACW"ÀN¹ãñÁäïAÛŠÛ}ª¡HÀí;ØÉ•åvåw[Òaµ‰²²Ž·Ú\íÅk‚8ó(YÝãDl
ß*5uŽvΙ‚¶ÒŒ\ž¸óÆûà±t½
…Õ‰V8^­‚««3”Æ<–fjzÖ]„ˆaJœ0p5øÃ6¦:+„ÖºñÐmW^ûC³­ZáqUX×MŠ¶§úû›¯°a[¼ØÛk‘ʯ¾¯†»ŸëІŒ˜(;°ãË,÷ÿ-yæñÊI[à0¡¿qjÌVý‹ÃŸ.炵RX[Ӭݵ¬fí†åÒ1lhÂ/ˆ¹—UôžÀ§ïßvl¨lËù|>Ä@P&»õgä›°Š±Ç;øêÓLÂêµßÿlÚáºë6¾+BÒÙ¶“”-éE«Þ(“¤wÎuÍÒ¥V>kœ,Î6ÓrŽ ,åkc'š‰j°ŽS -ºÙ?U$K©ZL°]:­©êíÍÖÞößö¤w±lxé™­xßK ã5ÃVë3ªê¨¼uÇ3ÙdMD"™'Î8`°¸áf%WÔñ7­f ¸æ¯a¦OXøqë
”ñ.dóavã¼8lóûä^ï=[¸t·ÜõÂgœ
A Y4Y¨ø4êWΣ®jøï¢ááGâF¡ÞìÞ#È¡=Äkö«ûÞ{ùÈsi‹¼ßðhókr{Þç} ÷3Ñ®.¬8µj at _·›B/¸9>^úô·!Žq-ÞQ{"êQ1w'Kš
2 u@èÕ–ÛDh at wÖ¿ìPL¢â½V9­#)<<ÁG…ë?V
·¨aƒ GT¥ró:ÙÕÒɁ¾á0À —™ðFÉs›aŽ6˸d£×;Z².ªö`h®aÏ6´l{ªÛ7ñ‡IEÇÈ€9
T@ä+¹yj›aqÌÔ÷¤a|Õ
ãã¥FD?Ýn³UÒy4{iQw¯~§Å&£–U˜N<ÞtæáòÂkëJ÷t“	^Ïßç(D?uà:4y0'u¢d|¢WY$¢{yA¶• ×Ç´.£:Þ®pOóâaMŒËN>P¿aàAï9µ"2Ë'Gr‹"¢w¬•kÜ©™D}™·±7ÖÁkf{zè\l±S°ˆ{z€£ˆ	™÷3 ît(àBý//EÓ—i¼§Y¥Š¢Ë”™0<m(šÎ¢õ/‹Gãîè¤ÑgAݝuÇ3˜ÄI‘²\ºžÜ„À²À—=Y‘)
òŽ—×˪LQÁHˆä[þ«Ó.Ò¾£ÇÐ4°ï0!åV4x–¬2rj>$h­q¤ìg'{&PQ5Š5q¦ŠrÀfSaÄ3)Ötfð3!ä	À,Ïg7ÈíÏP
Ga´…!H|‰¯+§²$ÕܨµúÀwïÇY…æjJU׬Ÿ7'XK.úÑ¡‰x*$Enrü•3®h¸ô™ZœÍ2=õ,k©„Åî@ƒŽa_ÝCÖ°nFiIL[^ù½+15ø‡³-–YO„Pyȇ¶öù$¢Ó‘%)õ(°±¥—¨Ìí:&«‰ê±t¬«ŒŠ<·jŽ&F² y(©ÊÖ+¤ÍÆèܼÏÐQä.…sýnÐ2P·‡×>ª8;–
K·¹…B+ªé²gZêò]¥7ŸcÆl–d¨=–®ÓEQ×5wÐ:Z­PÍïÜ#ˆ¡Õ~GÓP˜d!%­À}5UåxߘÞ;wŸý|ÚlŒ‚‚"DH©û©BB2£°éKQþòžAOýÿ‡å…ÄPb‰"“$ÿÂ`þCøýô0ñ„Ìž‘‚H¡˜P¨¾[%FÈ«E…aë¢Ü¿CI]ãaâs‡O\ï–xŸ†Ü{5kìÖ™kÆ–„;Í1èk5‚Š
ø’Cz•JÑÒ²ã`¦Ç/Õ†3DÞ›°)Ò1f“Þ%|Aas7ñ$¬›…ÖˆÂ1 x„±žÞŬÀ•+öH~6H{0:“Æfu…CשZêVOuë!A˜Ã´èÈY襚2	i£H™P6°Ø’3?Ð]¦þœü¹Å¨nÎù	ç`oÚôOÕ9a¿gØî@ò`–UŒE‹*{K0ÂAa) 
ŸüÄw«Î-?Ð	úí>½TÖšy‚¦×š.y†ðºqÿPxu0‰Ù×PšuÊš’²Dè¬r?¼LÔPg(A”*V(	k†¶ŒŒÚ
Áìijэ¡š,Ü*°ÀºUKqÈ÷ôÃÖ@;Éß$›Gݱ Â†L†h48µe‘±„øè/öÊ(‰gúšñT5ëq`ꎤ„þ;K¢šâ§¦ÁÚL`PÁI ÀÀßÇT‘‹B ‰;E)%,T,/݈êÇáî~V?ËÁj·¦GG>ÄÑàÃaãaáù«Ì+Ïwƒd(˜óÍ ‰úpf=ì6ÌÔ9Ž–`õDõ÷Ä"@
CŠ¯( <½	*ÖkÉìם,¬ß[dN)äcÌh£Å£‹»é„›–ÊVm†K?¡eî7`jwºJüÄ
0·H¨Â“çväÕhè[D*î𐴃N¡zA¤.ûÓ“³ŸæB?(L[“:„pÏÛùº¸,èOb=ýÌ{*XÂF8 –“j¹Ú”-Í+ôpeŒ¡Õ…LJÜpï¼ÿj\3/ñÜNN’9á<Q
¦ëŠp;òÝLÚSlû¤U"0U“VøžŽe<Ýiou¢’<s/ƒ"`†lõ£Ö^ŽGê¤5½AóN‚3}ë:
¦e!
ê(u80˜IÕW“µS•{\µô	)1zuŒË¬¡XΪ…æ€ewC5Š«¡íìbH^
ŸéØ'ˆuÃ@Ø]Ù1H<Ⱦ¦v7É€ÀÿV˜½W‡t¶¨¼÷¦UFïyggmgóFŒD}9!3ù.M(䁝
ÑãZ‚'uZ«P³
¨Œ!]sƒGVÒfA#b¾bmt1°JfRIÉÙŠ Íí4ÜÑ0ÊSåÏ5¢Ðóxñš\ÎæZøîY ‚ƒ'›’.ÉwÉR7ê»á£‘…aÚ!Lœ“ƒœa jNŒK)ÐGÄì"~꬇—vb-6e`>]	ó¬zì£Ê,-8
p8*Z¼±TÈ”æÇ"ÁuSU,øú5]óe¨ÏÑé
>Úõñ´ˆ÷1M„ÌB#
¼Ãš›œŽp_æ?Yäe¼2õ".žPé´™g¬î³w ô7å,l÷6kVWGŒHÉ=aµ0†ùÚ¼.–(k°Þ³uA¸™s¹}¥ÑˆÃádŽäðfôq€FlÛÛôVˆ¸Âó¸ÜBì“`ž*õþ4Ž'º¯ÍØçR9äb
/9÷¡µÌàdiBñ꤉óñ,©@“Ä7þ•³oà*¤º´o;™žð}Kù
·Ë(ì:-év…™è
L	CàA‹Y8Êû»ŽóÃÙ@¸€Kë0	0é)Ñ/1¤
°=;@ó´ˆüQm¥ôßΦgëÆžîŸhÙgµJ—q
-4Y³­Ú9j¨•C&™3 KͪJe}@ï9OØUM¸·#,‘pÖõÌ
úñ’iŒjÄŒÑ\°
	ì’h‡¡ª§&ªŠ(«$DCo)èEõ]œ@5xèÌk7gyqSÉå(±S©X«›‚ ÑPÙ3«ÏEš*˜½Æ¤éV».Uâ-”Ê…HḖ…Ã
„t4'°®Ó˜e“Üa.A\Ób‰‘•po£¸¬>³%@‰Hb”†l¢*Ñ@†hÔŸâo#«¾y©ƞܼ¨8…

VEßÌ\ér‚OÉ’	 _Ç“•b2±#Uû_h­ÛÔ<@ÜÓ:Ä|š…Ålr€ 92Ü’4Ý@=ϐð;Ä<e•Íó\ƒQHfÐÆrª¸ÆûùMŒe™ï@ƒÜé™î %9Âý	=
ÈàÉ¡ÇË֐¸¨\¥{BËo€{@¾àîÉj“‡ýʘ~[Õ¨¡QZ:0™ÐÂ@%§Ue(¤_dË8x¯s7
ËΊ\ë32l„,‰R&k—@݁CŽÍ[!s«ÿ¢¤äD sŒÞ.
‹©Y†Šr!fÔl–"—Ó¬#±”#—È”&*á4(AÙÝL"Ã2ѸÒh¿G[¿E6X0%(&VIçÝž/ôA¢»dÃg©
6õ¶mŠmfJ,õ{n»zˆÈÙO!ôñ ¢ˆ•Š#>`°ø…O˜ˆ6O°žžÙJõ1jªidN«Œìó`»
º$^FIc±¶gcŽûÅ{â¡mšD„Îè5¨iÑÈɐ„ [°|R¼š#ˆ5ÆKz-s5-ž&û•
tQ¡»0ˆIs/žˆ'ËqL›™PÌ ›ÅljUÄ}÷š	-£Ï¬"ílH»³/FèØñµìFÚX‹mŸ$ô%úf^áé^™sÔÇ3C%‘˜™¯ïþKˆùPeU€âUmˆúÉ=]…oGûYFÂ$Cû5-Ö¯°í>
q
ýHè.¸Òb<Ö!Ž$fTÓÉ‘¡Jé¾Êž7ppÞѱµ–*æ•þV±U×þ6ËiªZ$(h˜~Ìûõ·Bc¸Ž†#ê…ðÚ‚üÇ
yYB=¯+Rðˆ­fä•ù렽߁Ønf¢¶s#FiüɍÞgæ"¹–9ŒÝ`ÀÁºeWh
›Ä,J€Sçƒ‰@0f€hjG
 Ábm”ΫØÃ}@óÛ„¬m6¢ô2MæÀÝ\Kuqp.HzfG‡m–›Â× `zXsæ°h.ÞÚиrX-»–·öÜ;–h4h1‚`bæØ‹³¸
«˜ìH˜DÑ2)¤¹.ÆCU¹Ï®Ï0 ÌˆwWRû“E4ÄZ
*7¤+át±“ËÞ“)
袅š£HN‡‚hù wà	
íC+¥¦Åƒ
)»õVÕ•ý,V…OuÁµ˜ÆÂû7Â6ßì g°èY1®D†q,\–B‡Éy•¥3	q'EÁ þÖ¾‡ÿ—c×»€óOå×ÄQ*HüŽºù¤Ècôç#Ññì½>¬@óš–;Š±Îˆõlz(
—ñð”6.•:1CLC¶ãžO¨øxIªˆ©®hã0ôÆ×;‰¸ºXLD²{(£Tv6•ë«Y‰‘Y#Îɸÿ±ÇxHñì÷†,ÈâfgU%ÌQ°ÖczvrÃÚ–âÖ󑮀ϚƵYMÆÉ

]ÁÑ—Íá.=	ÅU,ÉQ Žd8ßžâaÅ6…J%¾ž<šP¹çF?¯›„U1LÜgÌaÄ7uÜq##‘Úü.Ò#&÷RAªd0b5B)
c‚‚†7"ÿÖ·|Z¬rÏv1,ýÆÇÎèÓß—4Ú­y!òB@‡ú_ìåm D×z!Ô2Üäð ÎÎoBuž=DO¤ì{¼ô0yMm¸ùl]eÒŸw½$›Ðß­éî	ðY²ƒ¥-½Îÿis¹ÿDZwêt¶ƒ–Ӂ—omù‘HÂZ(ãÃã½ïëŠÜЮYǸ
<¨b~úç¡KzB#}칧<™$4U:·–ÂMÆ*ÄiÔ†‘¡}OC-_¯¸àîøÝËšE͘Q¶ÒËdm$=4'8·L0o`–x‚:ÿRþ]‚µ.~n݉N¡ÿG4xӀߟG
d÷éq4L	éXåq¢íÅEÍ÷9;5*0ÚA‡¢YUƒfA@À.„ÑÀ́L'„1å±,\ð+~Qåa²œÏv(2¡
\kÞ`VÅQ°hzĹa?¶Tw÷þ?àeoÛñbë_æÂY5£Uÿ³}Tº¡­ƒG?ÒSgü†ï÷œï:B¡Ä2­žÎ~ËŠÝSêÿFÂ.aüM
üÆBü­r‚™.˜¸Þäÿ©±jäÿóØÌÿ3¹ø$©
©õ§ÔüL&̉úa‚‹6Œáª±ÃX-´o,j§ÜgþhÐ?Ÿ5~ÚLÂÁ‚Þ*QÙ³4ôû.ý¦'C@ãz­XÉ9Yíþ>U?¹dfvK¼59.2fS?†í¨o%^Öv
ª®µ0à¯Ïy„j°6òÛÌf¾Å…¿OC™—cÀâ!pH¹¢FFåØí¢(úsèrį¹™;ä†ð³}ePçMÄ ÏÙJè¶G‰ÈZhY´x®¬¥¦GM«¨Ø`dr¥ÇôÜÓþß·ÏĦdæ?<<øvéË—)ÔÜèL©R„€QÐÔxõÊx ˆáæŽ
„#N(¯CX9<ÉîuÄ*Xâùž[É$Ü{”h6ÙªºáÁê–f‚ìÓú{îd›¬|.Æ(àt*žkÈ”fz½Þ§Ç½.EƒOC¾F¸#Àíìµ`eSo#¾Ûœ`d&
ºsJøN`-Ô÷N8†P¿#€nK°<|Oc¯l–\ÐRzšŒØ `õ$Ív…Ù…-Äÿ/_ú@ýùÙoÓ:C@˜t5ŠÂO¡ÇJF†·eμÙä³*…{Ì@ä
 ©€RÿKz¦q,¸*bµL
	²ÉŸô~)û¿€4MIøŸòíòŸÉ
nþd4º¸ÌþØmÕû϶XÌä‡þÀô~†BHÙ?£œŒÌo²¹œÌ:štãkÍtTÉMHGõ®oÇAW8µÕ§ú¸dIdªÎpíãĦ·~Î
##²™QŽaÃ#aÈð·"‰E»Ë²ï©Ðä·\÷øk»¹¾´Ž_¨1U[ùæ´bŽlðéÓXv«m	!È×÷"ȁu¤[ŒI巡⬺NýùsE<g  <wæ]lNFâÈæ¿3©ûI(–÷Ï.@ÑÑæü¿¤OL 1P.@õ‘C•Å]oâT“™ê±ˆÁÅT=%®ˆ5Ó
½ü8ÊóL²K̦è(¤ÁRJïö,òxØÙnà^:£xöU<àôÊ¢ÚoÀY›ÓäÖÃáÕ%ÓÇ´nTœ$ºð×ìît‚8RÔµÄMŠAž[O$-–úî
š\ýü“iŒ§09¼·‡~\¶¨iT6á`ë–ÜaO
ÕZ,ƒ.,àáµ°b—L|V;÷#Œ¨Aš T.“Ì‚ˆ	:tÎüØ]XðøâU#‚689$oò.ù”)©'qÛ<x(j–¶ÚµZ
]m­…]
¤"
ÃDÒ˜‘8溙,_#K-uÍT׉î}9‘sw¤ˆÒT¡à2P‹8´B á6ç5ߺ&
ÉèM
2"•¸Ô–iÞT³˜Ë`E4 cbZ¸GŒ¢wm¶ôúÓ_Cܱ‡ŽñXEEá¸éH<“<öáqã¤	›®P£©ÉPìÉ+Ö¸/©ÜÞ¸qK>E\m—%±ÈÁø\vñ¶?Sjô 3™óå0¡Á̈Vû¸Hh®@—(m¶Ûruz áÀ=}IVÀ×-âBÇI|l*Ú§žñI	Ø£(oŠÏüL¶äoÜX§6¸šwúy¦9Z1ñÍø·#ÓFhà›ly>}‡*¹y_¡SN[ˆF¡Ô*j
ó’„ôð8 ì1¿n¤½ýB"
>ë%˜®%Ð<¡qï7xÊÍgS¾¹/½A›eMŠ¢¥QW:”\ñÎ1”g”øœýy…ò)·…°†Ã®† j"Œ¹3Óœü+†W¯# –ò°L!‡ía»ÓáoRÉj÷öò¶DëÄ~Wæ€XßÇ’òÛ}åÔÕQÈé8dbMû
)¢ìNUÑy ÝâI™oSÏx°]Ø™lò¡ÒQO
wNÅcDr.áÀé·¯lÅ֢̚•d
Èð¢Š
ÄᓘÍL©î7ÝK©m†ØÙŠ©n¢§ˆŽ
~ÚvUÖHçâRù«½Ó±B®ã<‹&;*g•SÌ
 aˆ.E*ŶÏ
ï¼Ùo`ŠRKã…„IFæ‰s4V¾­²]N¯\LƒËÃpòJê¤f¤¹åBõƒÓÅ,ÕJ™Ðòvëª,‰âO—mUœÎ!Üæ‘bîÂ^
Q“Íìøœqßè98sŒ†x—#yÆ<›[è•pœ{%BN唑Æä²FFai<ºQ,Î]ÄÝÈNz®ñ.Á[îxípx4ñ
ç-Ìb8ç˜qÃ#Ôi´×ƒ5$“‰½lr˦ãxpÌÀ¥®òl3±Äù®Ë
Ç–B6Ø‚YnW¹&ìºvcÕ½üau ÔcÕ@.¢ÈèŠ%œùmy$~äx˜$­v£+ï÷j­ƒ1¤³×åßËÚŸÏg™ŽM´á{ºùÍdqæÑi 0‚˜±(¨½Æ¼Æ yð?Äëf†GþÑ¢**( ’¡4k†~›ù|	Çhp8" 3 8€€@è àH	…
C+à÷Ÿð'ÈÏùgӝ¼wˆ~/÷´mÛ¹&½vþÛÚ§ÑR¹c·²¹áۮת±;G\>€G¢:qθåxÝk놭÷â¹0g“D4¤LÔ}»J"¦øGZ„Y6´@Äbrcä†`Óa,ðvAŒ,“ô0kÚýóÄ@ æ8ð÷O‡k›ô3${”,8ÝyQF¶k1~Tê	Â(pÁAƒNBÐl{’xøO<‚Á;ûŸ÷{¹N‡œ
a(²YBÅ¥¶'0ØNÉ!Mm'¨d"MÚ,êÀÅA¥!f!¤
"‡8
n=-!—€?ÙáðŸãÎÙd`žÅ
ž²iØP|Øú2V@„I
ia·CYW2²d3QAaŠ
¥
ô6E¢“Ôu#p¸JHY)ÿXƒG»Ü`=I‡™þ…èÕ!‚ƒ=
ª•Ëg¸;
¨ü!I‡to¢=I÷}¿êDý÷__|Gp<Ã]_UåÕ…Ÿ s8Äô¶  |Ñ
`Yˆ/fàØ{#äï@s7”‘ö…Cú¨]¿WË5¼æ
bVRTlôÿƒ@Ž ‚ä×÷¦u»É‘
foŸÉÝŒ:}oØVl;l\¹òæ8*
H'å­ÊIøD4àÊ
d¯š„:ïˆN³iMß—©Kìî
$È%Çò˜R†|=»IR
~“Aï#ÖZ‚TCX(XmD:IƒýÄ4>¿¿2åâBF1ðÉ/iESCÈz‡²â/Rµ«%3»10ѯ`{8q]iC<QÁCQˆZ) …C⊖… ”1<Ã7=«¨äH\™–
ÉØÀ›B(j>((|/ÀÝ
—aä><Í
l—°6;u1H-ÍÝûbMæ­ïi³¨<A¥{„°Kžø;3Ø{!/*ò’“Aé’¥›CÊÏŒÚÜkO§jûèðÀk!„Ñyl¨lâ‡駗ÈåöUðeËäöï<±æÕg£är<
,¹ž#21$…ñg͘ø8.Áñh4‘þy7fiG]Ô1‡Ò}æù8a°!ê*t bD¡£rPWa>>[mã~˜qÜ2Õøí±vmÜ´PBB€„  ’u
½¿Ê×¾Æ[ï$§ÜŒEbÜbWòQ\:a)Y\‡—Çdzøxdy{éñ²äTþÚË£OeÚ˜KwhBP”Ñ(€œ1z ëŠ'aGãøÀ êðåÕðlxðSª
HñN'ŸÇPÊì蜾O§FºÈŠW¾ÿ¥ávoàÖrµTæKT<¦Ç‚g’ü|9KøRÐ,-ʃv©ý“¬¶Bû
2‚ÜxbÀ3xÓ‹È éøêؤbû£ Àt.°oDgŸŠdŽý·½@ø̆&‡0Ä†r¤Ðyœi_á© 'Beð
¨¬V¤ŒTšÂ*PQlI˜(T}
ï¢Ö/d‡ÊbÁ"	‡³œò
&•Þä
C1äsÛH{¥ý¬ô‚䤎—&>u?+†Æš’`ZN§á×óÑ X]ÎK£
?'áó¦ŒÕ}r&“]¸CÎ¥Âè61­
ÏUõÒµ¼ŽÃ)M†LbæÌ…KÈGt…
É“QÈÊ#µ‘¹ÈÙ…­*äÁ…0¡kµyAAѵóìp8ënìJ(‡·¤ï`M{SÎQù°ÍZ)OÎ&ƒEC‰Pù§ÝÎÔ‡ƒbq,ß2ªŸ%à½ñ9.èHHº†
Ç®9tå—~ãÊôø_3·Äè?b3Dºå¦GÇÛìÔco¨k’Y¾Ì{ÿß¿î8go*ëáó4÷ú"$@¡Š%|¢„…%‘2ª´.¦ÚDÎJDµAȯuÒªŠˆœý;ûlj(ÐbYc‘’fd* ˆ19ïôn= pgí‡
yúSv‡Ÿ¦ÛµÝòBïïׇy­®ì¶ìäj‚§Ï6°„Eb	¬ÀÐhžî~áôüûá5מF+=éX
%‚üèBu$)Ê(3ªÌ2©j9©œ†…ˆÒXB`Œ>ÄŸx˜l3[†<à“Û’T|à›þ:7gÖ~?=´µm„•’ (’(@
/Ž¦RòHB¥ž|z\'¬CÀß©Y6b#ÈJ#ä”p²çQËh¤D…@„K%†Œ
Â	IãCrS€ÀÅeD

)ûHÓ¡EFsƒÉ-¾Ú—Æ8ãÀKYé Ãoñ4…;S%N¢'\ÑIDSð)M§YJ÷–s‰ÚÊZ"Q…‹mÁþQ=&Óý™4¢Ï/B˜NŒÖ£ÞRJ»%:[JBœVLøWC=ø)Q«JÁeP¦”ƒß“ƒ+}£&Œ‚¾OÊ2‡qWªê{COšHöœaƒ
ðÀS!ƒH<J¢¯j$ŒôrÁÆ‘;üpl+[ÞøM±BˆÊP,Iï1š›b	B²he÷ß²)unX$xÐqäú©@7ú÷‚ƒgÁzœÃM‘Hè5³_6
™³™Ý$8ÖC<Îîg#å
²@MB+D‘ANPT¨€²’(¬Ö€J€µø
ÅÍ–Q2ÁØ$ìE†rNÈ’ a©l+Ä6“ÊH¤R0wò4(®®ªÇ˜•€A¦‚“¨_©ûB+˜sOíð‚8w÷`QÞ…Ú2›æT6Ó	T)2Æ
}õÜ–B¨Üv°¸T´(¬3pMßíJØúÓ~<ºM‡F×fÓ8oîb‘>ÊÎðÐ0Sôžp‘SÚÌ&41•c9Çöyvü?NqOÓú-†FC3üuÈQTэúKãðÛ
ýq£H°Aűèö¦ôô ñoSMmºZ†@ÁÂÙ6ó™‚Á'Âðð3€Í­¡LKÄ0Ày‹Þϲ@D
mZhæh„¦ít4èÊ<„‰ÄÖæµ9;ÈÎ0˦C“+/Éa0MÜ`uLÕˆôw/Ës9lYMÒÀÝv)îÚœ÷/-éùYܹ[Û=){i±NÊéh"ŽŸbêŒg2…n)»Ž¢KÚƒ³}j‚€°TKA+Ÿ«ƒf!&…òNÛJÖÚ^ÑÔ¸"¶
@ ‡hTD¥
‚„÷µZ—}|ù¶‹l•,#9Ïlš3†.–8鯞èhL\±{_}m.ƒ|ðác6þÀߟ§rŸ9.ˍÕÄT”¥¸‚"!Þ橉¿Zz¹÷³œå:%@àó§D…1§½Éè‚*`1´%GÔN	[Af–.Õ ¿ÞmŠC/Ñð¼0"–BÀ•F¨Ç)(#Èt5Œž
Ì…˜iI)‘F¡V99/)À[‘át¯_«Ü£ÇÆ¥‘×ç~0£ò†á8r{²z¢=®¡óUÁ
(‡Lÿ%šµ.xIT|ŸiâF‰¸(HõløwÕz®ê“¯FîÈõžâÚÁ *:Õ	Ûgm¡Èi{aç¬$$Y‹	J øÁQéÅá2ùÁ¥Z”1
‚Æb!PTòW`û9ðã’Ž ¥€ï;«
¦ëaìcDϐÊÖ ucÂNjŒ@eÆ¡”UZ¸zCf£2¹eDBXƒqÚ ìXq¨ßxoÛõ“¨À(³`A8Q«¶Áì²B6#Pûé|,/Œú¾ŸŠ½òÌTÅŽqŠþ¸…
Hµ¥“öÉûÕ™”F½X(ÚÏ+[РJ%ÚYÎ›¦švÍ€eÕã0èlJnD[…eJR…IRJ¹E
È›ÜÀÀ+8ç±¥j¡ð¹PÀE ìLB
ÓÒ¤·€ ž¯ÏξÏê˧ÖV¾=S€ØþÃÀGý…P¦Îßn-´ð£´²–ÝP$Œ7íg¢ûže|G
á(ǁÊù›Ò5“
¨<Gu¥ÄW…ÞQº¡¼óh÷O°ãxâ6֐ª!Ç®R暆-³°÷”oƒ„—IÎÎJ¾ÔK‚®ÍÅïÀ%$…R§ïcicHµMmŠÀ
D—
ˆ¢/<4+¾ÔÝ­J~{‘²Ã,ôÍïȃHZ„
¨ævyŠÓ8‘BS î!m».´ƒpW*ˆ*‰"’ð5²t¾Û_)VºÓ™°2·”ØÀ›ÌÓ8!cz†ÒœílMsé-Ã0þÚ
×xÖ7×TÇYˆë«Û)ÀnÓ]¹îF6<8¢¹é×¥§$o¦rÅÈ9TƒÉÄ6ƈPrÈ-8YÎô6

[Û	ÏUGÁU€pº08Vn0Š”AÂͲ·ÝH¢¡4˜!;îÚ¡%Æ•.0îU55]e€èꥑ‚ª®Ä`§
L,D†äINì+nqÑÇK^Ï*/…Éä
nŠ*®‚r-wA¬衉<èXž‡œŒ;a`Å«ñ»l6ʁ؅À¥‹jDÙnk#m
òC’ÆÁV"vã­©eT‹.¡E•fðD4àEEšƒf–Tá&Z,-M—Ñ`¨¡Fјš¥†¢Tϸ͸ȁYK§@0Ä`L)€04'’‰,dO:ú&Øä%+Z!4N-±

Ñj®u©‚	7!ÚðA
Lg+ŒaÁúž­98:ŒÌà{¼ÞÖÙîáÚ®§`1Ë\w“¦íÚ

ó”£mQ+"o(0à79†!P@X,)0ý]Ö¿ªƒä“Á@xÌ
ô‹Pz;d7fÓÖ×ržÎºbë‚-U14¨KÝâùBR"Ú=e]/⸈	Ó<ns«ã³`êpsk¢#Ü5ðTòĦ
©u÷ãÞÃ8\Êq¢F²gg®F* 2e ¦0°•ƒÏ‹,·Ê¶–“|îŽÑ!mžuÉ`¡EªØrÀßCxjbŒV&¦y:«‰¿e¨Þš2±‘ª0Ô55 nÊitÂÑÁ&3Ismª³æVb•…r6C†ý›SI&â Ö&ÌÔ›pt;ÆòË\Ìщ’CNE½a¨ÈÂ3¶©…°¹cbEIÏ,ê™e”ipÉ	Se)g¾â³½†‹
4ª¦C+ÈMŒÖN^b£ol/xR˜d20úùzHM—äIl¨ÙÐCm™ÒVEE€È0dH“ãìÂ'„>;(˜`ñº„I$ÿãqd]LÆ»iA`Jv
×pÑ«w75”6¢ô
ƒõ#¼ŒsN
¸À—lfilê7røCÀ
¢çx›9 ÜíOU$$,å…@$¢ uïîÔ#`LmfJšâç>ì¯Ã!€lñã	Ml¤á€5šƒw•mçöyp
ï3p§¾$ç¤ýxÁ`°TXN½§>±8òA¶Îº¸Ó˜ÜH¶‹³Fh‘µ uÞåÜ@2O¦¢!`ÚPɳäqDšËT(m|S@‡&‰7CRB	‘R94ƒQA^
ÆŽå>ÆÆ+Pýí¨uWCÔØÖñdÈ¥YÂìHQX?J%@À†ñ8XþhÛ"•C;Jó:fÍ{’¦°"³%$&CBw¼ÌaPœ`ÆNœ¤ã/¦tÉ6bê`oECˆ҉„d÷*XQoÒä&ÿPÚõÃö¬ïU;øC¼Õ2㿆ÀÝòQuÔHö ~AÂù¥ÌE:ßO×;,d=}܈ß
'‡ tª÷Ç1€†6&’3h¹•Œð¡´Ðs\‚´¡¼-L’)¥h%a„
-KS)10¡5sŽ’¤£ª	–À+?Sà@Ê•kG­ž¤d»*ÅР=¬ìäpmƶ0K¸í>ʪTljµ­C”zóɶ¬&ÞÙ
Fa”0gjhh»H蘪•	¢Œ2ª²Y@R+õ˜¬*ËŒWhUejQÖ-`c$Ê$›€ŠÝXJU3dRÔÖw`ZÐàˆq  1¶Ó˜Ý‹	h²o]¹Ad†¤T@ওˆï jc\³iM,`½Í¯Ž¡@	EÊ\Àä8¤6ލu¿	Übiý!"¬ØMª®ûFÑÞ"¦æl1pÂÉ
xƒ©#?&À}ݐ» Ë¨…T6c$Ÿó̶¼´-ŸÐcnX<à ͌ʸ·Ù˜\kKY]	TØ+! ÄœŠê	$ôÁñ~ÑÁàW°h…
zÐØ™[‘+i
V;„XHÙ¶„!-„‚\é`Cê>°ö;	û<Nf$à„BT3IœBúJ­4é‘+À€ô5ŒŽÄ6m7dTÀ(P.mÚàw
>áéœ@$BDIE‘Eî¥20( …$@߸)œ›ó•Çmý›ËVû›²:²„ß4T.Q7Ò!FA$eQ„Ÿœ‰  gÏc"p&}íAnáq[[V‚¨'¼¶rVr
Î}œ˜QH±X‰a°°êQŠ,œ¡g „?
ÌÊ­@ 	„±üæ
‚{Èt¡±œ3ÙýôƒéøÌùi§ãÛ³–‡ˆ	p3Gÿø:|Ô]@Ü•ª¢O€i€±‰øÕ¾ð7Áî=Ü
¬Î0
	98¾.I±7£‚¦a·Å	ó²K+‚ßõ&Œ)ÊÝ!ñ„õÚ´+…
o<ƒÄ¡äê'¶=!Rl|Á¶Î:„ìG¦”lA>»ÐÂrh»Îº܍ªÚY*.'á §äaܝã&Ö›AdRg2µ@8#ˆ)”WÿÂPÖ·2F\0ót®ƒ]’ΔìÔ¬ÒD&]a‘-eàCràz€¡â¬ú¤¢ÚZ+Ù‰š0•¢añYãwûÃ%a°<\«ÁµBXQò•1‚åÅC4Y#×ïµQpAƒ;Ë`¨Š“B ¨‰
’ö
4e@é9û½`a,ë±Ø’pt†ä9ÕÀehPi1D‘õµXŒIðè!…ÕžýOzm¨Y;à€|%œà†:¨ˆ5<ùýâ¨Zù“ ‹Aé0¹#…ˆe ’d™LÒ>m#ç’d2 †íû‚¡¿¶„ìj@à½ÂáAEÒÉ`–
0OŒ‚SÚOv
2A	bõ¼|w8︥!ïEä,^ä dÛiŒHSÌ‹	<»fÜxè&Âu64jbš]ªÝäòäQ”¢%¥+^o¥	·šªË‰$yʲ’¢€’¿BÕÇ%Q´8Œáò”U‰âZd4ø|
ƒÙ'2•6'lA•BH0î,DV*F(6€nU*Ô¢•HFÃòã¯ñ¡¹â 4‚á}ˆµ[F&˜¨PÞD­ì‚‚‚ÔºùBñ‡4dÄvŠ2™,C^
'¾ø$+šçžŽìœÓÅœóç¹yî˜pÏ?ÚöíçNÍ通a;[2͸°ÄûéC¡Ï°0îQùéKJ%j7鐘 p9;}a&„>Šy„Æ’Ž­Õb22cù»~<;€ÞzK¶|ŒU'0wóì¤áòPáÂS¡Ðàg„ÈĈêˆ1g
vkI°ÙË)CJ±L6-i/E>b|ˆ,ü‰<dD[~ùöŒ‰“^íN±ŠÁxŸ xÈH) m`~Ç*ã©‚f%È4ûs±	µD¼Ý_óhÐJÆE¿‚=šB<ƒàxú.¿Û`¤ã’A°<2£e
a1“ïë¡uJ¹*ZPÇH,í¦•×|orÌ)j›ƒ
Šð¯ŽgèÄûCP¡¨( nØî›vÜ—@±àF|<]55)ðäAÛÊ3¸Sò>¬©‘WÊ
V‚žÞbn‹þ@>rÔT
‚Z5û ¥Em(‚ý7¥ÁAII¼Y”P•$¨¹‡ï°­€Ó‚'C
¡û#øsÝštÛ°ô”yºz
rgÈùBDšu0^	>¿Vˆˆêò6á’ÄŸu°!ë>a=îs©“æ3÷x4)Á~!†Æ^)B°"	óß`¿o¸Ì’ôuŠ=áy?º•o·Z 4qD‰µ¿rò4E¦J~m–éþ£Ü\’)³ÑMdJO¤Ø™‚ošÁ÷RÄÙ˜{bù|€®Ç³‹	¶^ŸïIÆÖðLž¢H€0 F
#X 
È!îöû²|‰šÞp»Ø ñ»>Dº'Äel6-
‡ÑùhÓ›ÛFՁ*›UX	º¥$ä=I®Lw~|.¶Ï<zçdèž…UdÅXsÌ’½±c ©"ÀæÉH£²_½@â$X€°œûÇIÑ
ChSHD‚2Z,øƒ vç9¢Fª"Š#¯.ˆòvìï\ê}Ã*ó×jo
;o`)f*¢­Z€GçjÁ‚(§" c*5šX; л2q²¨dÃ<ûš*Ä
aàC¬l:ZŒœÆpu›d‹Ë·@鎢 ýi}ÛÏ\ž2c:¢iÓ£A6-ŒÖ²èÕ´.çKÃÜŠkv“`nƒþÐÞA¸›CQNßã/gpÓ®pÜèõùWD\ào*‘Ùϲ‡cÕBöîº$,æ<!V4`È*’GÏØl‚È $%“½úmPé•DMB Ä‚°ŒŠ‘ #ßóü”õ5£ø“Øw†Mß&
‚ϲ…‰=u;;C<¡¨HdôY6I¤5•9J²¨ˆqlœ@Ñ: u$èÀ™
% à)opbÀ"@R@	 IQŒDXÉÔûb
‚Œb,aÆÃ[Q\Ô`ˆÅ®KF^¥Tb¬ˆˆÊÈY
R"Q!ÂtÁÑ’nÖ')»9r½4Q›«-JµÝ0Xª1i@:,ÀèÊ'HÂ	e‚F,ŠSD€&”‰ù׌“ŒÔa¶RPoaQŒ‚ÃHZ2V
ˆ›4ÔÖ
Û1Ÿ«CAæþúÉSqY!dl}F–ñ"†µ
ág ÁðTÀÁ~¶”¬ ¨€Ò³ìÏCX
›Õ¡‡CŸ©“¬†¼ cœÜ¬+€Z¦XHyù´i>ƒ¨]-âxuú;ZLû¬ËhâW o7Ò|×=/®Ü¡È"‚ ŒV$à+l³ìÔ³b“QJÔÙšDbÃC`‚ÊÞ<nËI½WzšÊ'¹4ðmG7˹-ç)ÊeF^*ü-^0 ÖÁ…öv§Ž…¶(6ÔkaƒódÈH „(€P ÂOáíö®‰ÑDi`‡Ó²	6Õ"u{/Q"‡~ÒáDæobd*0ÜÑ‘ƒu
»zd8É<šÌ¹ŸË.EÛ:ô;ÃL<TU˜ê7‹ø¥äLOzSAP“0ê–œí¨“qãéØižA‘CÉi/‡¦ØD6q
ué[6+iü;'
,
Kø6pR…‡´>®ñq„1@9&"c‰=Ý\Ï­áSÕðôpçg¾˜3ôrÅÖÍèõŽ
0¢±V^ȵ
,‹áÈ3‰Ù~¬A¹–òÌk}³`HÆRÞPCÌä€Äi:£+£CkD´r~ˆjmöÉðLˆ¤4zy{
l[vf
mªâY*Y+æc¹Mƒ“,ÞÉd¢÷ó+?®7›ô|XkŸ0È“	CmB€¨£T]!q}¼À`hk˜cÐ!˜¶m²Ë]ª›z§T!Š g„ëÐ]éԛ‡t®…4JÆdd;_ÙÌ
Oñ($
6yÜØ-úµñ´>¿Æœ·‚s8‡Ú›êOª‹*ŒQ7PµÐªÝêMX6U°c`TÊ‚±¦œn)èÅ>‘õá|QQ-£ÙÒ›”¬(rÔ°tB¦ AP {´O8·€xû÷êCôqÑhf€a¸õ¤ö˜eä<ËBƒÙÄöt½º/z—aÛ9(¢¬V"ª3rÔDQUA‚Äg÷ßí0FìuZ£X¡„Ô°´hU\[DkÁ2Fu RÙX ª
D­¨VË­*aÌ2šIõ
7¥ˆŒëX©Oóí̝U’“…6X¬
±‡N›õ¸7›Z¢Åª#·Ü‚q€@b! ˜c@âJöHÒ™Q©‚<s—ߌïüÈ??2Fp3dã‚(r…°å°¶VsMªœqA˜›6
„¬ÇR¼hk9«‘±˜Ÿ`ì[º¦ú§pæE
(ð†ËåÖ‡Úm.Êøž†þPô]†Ñlˆ0Øöº†‰r•û»Q<'ÏgyÌåAD¦ßoçgÖhì-ü\˜êzq+
œ£è„PI‡\ý2©bÑ9šœÏ¯€9—\Èe.‡©ñéʹ«‚"öõ6\è÷žýÖÆ¡Kî^
DótQÐ=Lƒiè$Å‹¶g}ßÑÎÍ^«bìî46­Wh;dÄõX…Å°%ÒPH¬¯µ=ìsµˆCÅÌ,Aá“
!_S at i¹fnÝéCdÞH,wx'õ¨D‰°^ø¶Ç¨r³`›RñÁQ²Ú¬tSEa|ÒE§BA3HL#˜fPC 3"B¸%dhwa&ÎuÒ\økBzN†}´h2!rÄ¡³‚ù`(0Y½5`hcÆ	éy
õ°Ît7™#&yŒÑÄ`‰Ú2ÔDarÓÑïÇµÄ›58Ž¯k¤ç
'qá’”PI¹0ÒÎbð-ço¾¸Ö"ƒ/‚W\Ô–z at 8$´²Z çPk£•©¶ÒŸé=ŽâôöÇ—ÐcÈNffŒÿ0Ò(Æo¡~&QžÜlçÌ^Ü¼¿/O4±84$HŠ’;ቑB°7)ÆF-¬>©êéÞöv3}\UUð/PN¤r7`µ+T¥ˆEŒ7™
»ê0˜2‰®(èp Ê€”"Äúð¨å|2Äð	²
ÄCRa˜LhC€%>¡ÎeE!X²q'yA9HQÌ…r Éc
b

-0Ì⻆#²’›"&Ç.ØDÁu0øÿ÷}¥$Qˆ'jü´IÿV°¦§E´úíœÚN¤ÀõÙÀ7-&‰B¾6±~6Ë€ŸpX†ÉP­œ®¡ÚDlK)Ê¥haØÛéÒ¿†0Qø¾ Ⱥ!»ÊJ*LHab
¨,’Ad*Œ	)Ñ"ȵ+XÒ”Z¬Æ49J´’p-
%×:j"ËI4 at OjJä4#ĺDdRÈJ‹"Â%ÕŠzƒiº9 @.[d;Q
K1ˆpеDÛò’—„£.O˜ÍÁ2KS£Ñ	-Ã
—kæ„]#ï[>£îÄ9“ó
{@òÑ¥g˜a7ø©þß`G:>á
l«€Ø†.Ä0$F‹Bßy>Ç´™N´ä(l‘PÈ‚ùz祸ÑPê‡ÌgqŒ­P|~ÜÓiöͲÅÌE°CDîcÀ‘H6…z``ë—ë‘:½Â øú}àmÁìðdã,‘bt¿
*Bd+CÝj‹ƒJÙ8Dñ]æGŒì£î¾–8€í
˜"6 ×c©š*>½ªJa 1’,ŠÈ>Sâͽ%­iûHW-†ø&åw—r·ç{@çÓC‡xuŽ…W˜LÈ<’¿FY LðB…‡˜Â¤DÔ>)hœ!Ã1
‡<aÛ=
†¢‘‰‡õÁæ0æ5”Â	^ð€î¯t*Ï4¼¡~1úŽÍǍ5°ACÞùZiÓ©yʼŽ$“»ÿ¾›EåªÊ…¾Œ¡Oîˆ)ºR‰ƒ;A3òµ
*DÛ~‡5P¡tìB‘Ñ^@ïQìé}Óó4/-ßRÜ
2>brïÙTÕBõe]"_ZS'y‡ß#Ñs#vdfb
ø Pف‰×
#T~…Ðz™èâÈ_d
jì|¦¥t4gL™Ë\¼.•íÙ¡ÖhΟJgi¡Î
Rÿ—°R~ X4Ì'TÏÀ&íëvl½2³Íöߤú
uœÆˆF)ä_çN‘9Àd¤"‡oZ§µííƒ`wï³Ô’|IØ×ØY%ùmˆÓÔF׸3¼úISq¨ÎPÂ_”ÃÞÏ-€ä vó-Dl`výÙoŒ›N¦^¢ú/yA-©<Á–>vù›’rø|\çÛºªó„çY“Z!£ 
l(KÆhÜ™åïu™3ÙBÍn`\7ºãSнìM.D„2]æ#˜‚
’ñ<Dç{Ê^ˆÑBŽ0W·pô<ŽÃH‹§H`Þ–¬Í¾{ELp%f¥ú’]¥¹?tæÏbJÃÎ0í
Ö0häÀ¦¿3!Y6(^ù¥†,xaÜŸ‘Üž,7Üäµ
HïRêbIˈ\‹vŒ¤*¬$ÒÆ<?‘ÔæÂRÞ0%°Y‘o™@Ë(DÅC;›Êãáñû§!¤÷GçaŽ‚ØTž?hENl-çêT©HàÔN¢.^’H‘èíWÈy…ÃS„0“në8&
Gý?ònµBU±¡âÛ>~S0?Á0 çC¶b,Ãâ¾eù²æ2PrHÆÉ ¡‚¤o(ŠY	7­|ö8ïM
‰p´2P·êhdj
ÙÀÞJ†›Á ÀL 6 WgŽÃÜîÖ¥B!
nèú¤ CÆvÇv².œfã¡,·‡˜zÃѲ¬;ý-2”îJÁîûÓ?"6
Â`Â0ø1hRÀÝ”jÍ‰~Î4úx}‹Âú
†áN}ÞKŽ&,ÔÃÓŒ¬p™†YgËS|ó“Æ£÷V‚À¬î±HÖgVÒ‚§¾×ž¯S”î¦Îˆ!1J"	iFAQTbňÅU‚†û]ÿLðÃûŽ
AI8é38 at Y«­PÕ…%IJr{riÚ{»
Nyæ{Ý>È;å:uéŽRnsº|³sœõ¸âª ˆg-’q:•ç(ŒªÑ#›"«mO ñÔ™
Š•¢Ôæl8ÖÝ
kS×$W´ÐƒÂ§ÄaDÆhË9²°8S¬ÈN( æ@Ô~Í ŒÉÓóx›MpÅ‘cJ)È~D†>yz}ï0\lg”ÛDè!!ƒä^8•Ó¢ö‚ðIp#êóFß7ËðÁM6|ƒØj½q(sô9ÍÓªÎ!Ë9©Åæ|-;ÚΏo
TÄÌO–™= Î3¼(€}ÇPyD=)Ñ ØC2``	
)‚ôE3×Ί^D}A$ÐÕƒi™ESí	ø	9&s0ƒ÷ú 7N+Ô!B@͏LžáΏ­:Áç=ߌPŒ$ðx¥£‰±6Ý½“zd°Ëç(µ”£»#ö
›é<!ñòÕÆC)A-1e)T²°,ŒJoè78o‹ÊÖŠŽâ4vm…j®(žÑÉ6£Š&ª”O•¤÷„-ù’Tþù_Aè9Ó6R… ‚+4”Ÿh?Á¥[–’Ko©SòU'ˆ†ŸÜP¶„4Gꄉa›¦ÛeLq²¡übî‚H!h¢m€"¶ !"§ïHU}¥Ì;ô2áz½—T¤Hyː—:gëY€*1@úÔñ! Ôg«Ü„'¢/Åì(Pºfû>ÀæœÛ˜ÜYT ŒC`M6‡ðúT]-G»ŒØ!Å](3| d¤"$?
è`Ý!‰„]À—(hVWpìÚ€%’„@#!8	Q&ŠÙ Er§’›ÀlSõ@HNKïs$À`0ïaÙÕûÑ6‡öó
ŒbÈLÄAIHDêbü2øO‰tPwH_hº…Š>`ëäƒ~àŒ'¦ýñ‘d„`’AdSúùÄIEÂäâ0bq‘AýJ¿TÍ2AÔÄMBµ‹F( ‚EUT„™
Ç—Iƒ%=<ëÌÞ'#q	nÒ!FV*ÆÅL>Aë
ž‚Ä$P¤õŒ‡ˆ1ƒ"È°îç’£ž?ˆmÜ:Éuëæ=k°Ë{*Ÿ½íêÉ"Þ¦eϸÔu(“Ca@
‰""óqßééã^ÿV2¨~™k¶cðïRÊôKʈŒX2Þ²>ãQ–¶øt,ß÷´f
î¥+0¤‰ !Š™×W\æÛ³8nÔÜóáu—´·mJmt‡(„¸6ßÅc}Q¬
n¹X¶·!ËvrHS"¡€Pº2¾[Cã÷`ô
´Öïk¨ì¹»ÛMh:‹³!NÄë„™ÄFh5Ó,}ªÜÂwn
4\u°qö™à7ZEÌË:œiQÔ+¤^.Œž8—bž¢ï[¨5ç'f©Ið¦9Çb¥^ò#¤ãS’€·ýAò"·à¨š£2âåTëfPª¥JB#—.¡ÑH¬»x½ô’
m“µëCºôùVø¨ÛaÇ]îäŽQÙ‡ÃyæFR÷$;½C‹=ŽàmTûÕq«C^H8©F»„äé¬õí$ÆÊ£ý‚ïdTN*o¥úÞmbªóM"¢ªb&¥^ƒ¼Í4ÈÅUU*¼°ø(@œÂ”
A„ð PAs
Ã

à(3 E·ÆGo.f8Â$#'¾¹,Öf
†‹Ó5`Ѧ¸'¬¢ªååd>šŠëZ¥] ÆTÇÐ=CÎÒ€@À!oXde‚óMæ64
npéYÍ£ä]ôØu
@è#} 2L¨!e‰¸8ØÀ4Š}FØØ•nD@Ìu7V•EVù¾`lÖ¶Ô.@ؐ\¶¨…†ŠHÀì6~3ày©Æ!Þ2 ™Ë庘¹âú˜ŠG}€”žÁ“v؏ÄÂ\D…8|ötO7õ Qv‚ÍWãÃƒ´Ó5Ï•\›,ƒ"%68eó¸N¦¤‰x éT¥@Y†³MiÊìISóUf$…°yé|,,KšlçIQôðšAf^M5¥M²ÚpüSQàžz‡<$8˜Q*ƒ( 
{¿fÄXaô$¹)—…”ddU£A–vtÜ;TçÈ82W¨àÀ„ìª!@‰!â<
ÌUÿ5PæÁÙ»©æ('SV…
ÄÐÀæmom-D¶C¸õi0`Ã~ñ©Á¿
‘aÆ2P¶A85©ä:á5ööL(ã•lAû1LœÎCD…ôC;hõ“ÓMmµNdB†Œú&J:VX[¸ÐQJH’Ù]—»I•Qsm¨ÀáÃ,ž°«©íaxÛišðã‘Ì0ĆÀÑ/²žó[†W¥úI¾‡œ’ÎœÉCxlP>UDáë$òVûÉC:ý˜gËÆ’I£<þ­ ¥dºÖê‹m;4˜È_ÒÉ„ïJD ™Ú°± Ïxž\lDÛUÕÄjä¦!œ
'¸Ea€Ø˜DaÔIs€å5 <ìg+y\ÉŽ,¿;(ÿ
íæáuÅÜ	G×
¤¾wƒÐõêÐøÚÁ&hˆƒi/% ³
% °jÁ`9Ž‰"¢µmA…jU“1lØyêÄ—.þ`ðV€g')HƒV|©+Ò‡@um¦è0æÍl–)šPCŸo3%F2I'$ pý²3ÀL‹maRV
l$X•#ØPlF
¨±iPªÄ¬RÑ-,c‚#Q‰Im©öÚ8¢J"$Fe+ç¤À#5–XQ’”)D
*–Ðb£Pƒ+„©iE€µKfmXVˆ'1J%‚¼: ôJròÊíwUãï2
f' ,‚Ã6á6=ƒõ%V‰/éBXÁ<«æÁƒlÁ”=BÉb­Z‡•TÌ¡KÕŽŠ ¦ï´¨n¬ãr³„Sïš{8vséÊ ]àª,ÐÞùuó¿j‡ jï©ÎITêT¹BIŒk‘«32t
¦ô’®@írPݶàò!yÁÐQg»¤Tä¦3Ó¼ßÏœìöðÐÅ=÷h(zLŽ§f†Æ¹aÍQTãJ#rÎº;$¶PZ2¬Ñä4èBdTÚ)Ó9ha®QÉÐU-ɦ*ÓnU€›°ØÜpÙ·Ð]bD+Љ’MåS ËeäÔã	EàŽ°@¶³iÜ^ÀÚ±¥ÍÑ©™BHH-&1ƒÂh!+8Ïl°X»Ù+Ìc(©3çNMPðO9PCË/º¾Í@Ö³üºdc,µ#¥• 8•°Êæ™Ðá FE¥H:bðãt»p ƒQ̶I®†æ5ÅuÅ
ˆ!}×4¸áK1ìirs
oO~îËôÐ:AP^¿ÏwÇãâ&5|0Xš0Üæô„³Ö@¤âPŒ´0¹ôƒ©Bt3f9Ö¢@Å-º³yQED«{R*̦36#‰V¢T
•V2t·®­G­Ò&c³FbÁ Ûbé­Q²Q!M`ÙŒdŠ²
o.Ù&ÈÖ6m±ÁÙX‘h&+Jµ2ÊXÍrÌÆj¨4ëZLb!wÞðw^IÏ–3Ž%Ú<šHÝÙ@+dèø3lÍïL{§W³iœÎœ¸CkΔ…Ú^§ùÇ,œšmC„;ÃEÚÓ¹Ò)S3bRl,Rñ«Ó]xØ™HE%B	G‹H’B¤2©a6!2áq|Œ(”>áL2‚­p$·u8±ï 6§Ü¶xâŽ×‘°€­x…GC>ѨLå­K¦pÜ›H'«G!]š·W 21¶AUÇqapÂÝAáôE¿Ú£œqˆáBåÃZÑZÇêt)`îFAáBÄiÑ–`mµ‚¡+.ºSn-ƒUÝ®$[¢Ã¨d
¨
ÂM<kUí%H<&$ ëTv“j
"]´$†šoh)1eñßã9ñÏÃÎÙÊ›4\M²‡=ÛL£„[‰|[:‡$(…S"€Tp̶‚ÖÃ	Ø»	ªavŒÂ0U'=Î&nñ%æ@C’è”7K•cM–×1‚Þ‚f
Øî
/Ž”&x
-²œ°“Cn¶„ºË˜¬ç6§NÂ3‰)›£fîlM1º„Á0MÚcÔít$$/¡›PÃDå5®nâ¹{‘]m	¢BÀª •%ò(‰1!® .b ѪãBRŠQ@¹h,ùӏ)ëØ¢ž‘OI
Áï8`I
=|àCŒÒǦÇÈm.'×æÜÉABäm±Ië&Àï†hŽw‚ÒO•PxІÀV°†mø|yù¬ä–	ȍ*£²
0
Ž„TüéÓ™'ˆwyH«°áK;äØÆp"s懈Ýj*3J/7-R£'¬¨2"–PÕ™óxé½”ï
"o‡Ã¬’h@æ)¿r-d&Žu÷s2°f¼>Y=
^ð;BhÄÚ)Ù×@èòÈ°±çÜ=r±£T™¿0Ôªê‚ZòÖK]EƒŠ|ðІ
yž¤	&pJY¾`¸ƒ©ûéå)
 =Ώìûñ¶èVž@q Ç¥…¦«ÈLÐÀëÔV,~‘Øc$  -|Ãíí䉸CÇ$ïN?kì+-ÒVJ9€ðæ@¤¾˜RT
T}–ÄO&6q>_Ó.¤)ÑíF\|Ð^”a”FbÖÆ"ž|Æfì´C·/á²ølX²úßá¡7g½ˆŠ">aÈž‘›è“2’¨+T†Êy†Í"Õ	Œj‚LFXø*"že@µÂ³+
_–ÉññϏ“ÆpÕ茤z‡áŠN*Íy³M¶Ä$Ãzbï:¾c½åE ÓQCúC*e W±%åyØ¡äÖ™¾ÔÏ>­ö[¸í±æ	€ÅphÅ—jæ¤;Œ”-’@ íXA–„ˆ‚ll@¡„XÁ-x~ØaâÃm_ÇŽ2:aJLÙס9u2T¹
©ƒÀ:AàÕMM†n8´›mƒ:™š’¥T‹Õ+%ŒàâiÏyYovY)è8€>éô(x;¡¤zl ©\£ÕPðí—–$jÐO€€àcâ7ä:·Èéh
¤`(T(x~¾H!'²aI°Y±ÜêR”WÙÒ ºý¸*ÓGš“ããG!y¾A—M%êABŒ•êX"â#å¶k¦…XxڮÜCu/x½¦#€öõA‘C׫'ëg·jFp™•v”)b?)þì|xãrXÝ‚Ü
`‚ „ŠôöÇÀT:ýáÓDÉ»}ƒšI²š:PyĘF$Ä(ú£–ü£1	#ÿ(©µT{"R±OýaªÎ¶Lö^âÂÇRÂ9h$o?ïöCÔ<q|ñH;n1ØeÐúT¬0h·ÁAˆ£õ‚ˆ€pþàÀ°=·ƒ°ÿ_^ûF2y—X(y"óI†64;†n¨g½ÀáîæÅ&WÆ0Ñ'kf‘H²E
á©š¼4ëÐódQÊEŒhÂÒ…$QPT(­Â[âBÜ´ïü+Ðõ¡ë3X˜"ÜõP¢Skö÷Ü]D,TL¶´L‰Rêá,Ø_“MâiÃ鍃Žž4ÍÂÊäÞîù¬ZÀS1bù”ª‡ì"‚Ð+™?˜°kîÄ+¬½É{ÚÅ¢FB7…-ýñïò
)he*

@¨(ë%B#$TŠˆ	Ÿ¯·SQ’2DJ&²A’Y?ƒíµR–̇ý9Aa=!	ËÉ(È ¥Œ)ˆœ{‘d•Jp‹´1(F{A“„Pc'	»ƒ2É|	ÌŸ¢ºÛOá>Üfô‰¢Ã°p᫧oªÕ]iX°ÄTu¬Š}“’7Ù2P0{.Ó^@¯’^b¶'“ðù%v4#Eìʆ
d‚ž“6pO@½ÖPcY_ØÎFº*Å€™q’˜FD–Tç‰=C¡]¾}Šk<šg»|ÄÀKh¶Ö@i	ˆ@Ÿ1Ù9‹žS†š¿:Àqê!.ÿÌÀÏà~:ç•eª·Œ>8Ó~8Û»$9¦À´!	
•gËhÊi!ê×AËrTJ9qŽ²T£áù¬K#ˆ"÷Á$INÎÜõþÎK¦Ä=wÜ2(&2Ç0éðQÌ´H	ÓjLŒ|)»ÈA(šˆ
#9Õ‘ŠÅ}d6:
§ˆø°qžÓúNðþRçñ'·e…*N<ûoÿ,Pÿ(žíÿžÞ·šþ´¯,BŠËã
›ä„Wh<‹ê7‡Pwóò¦†¸™qpÏçTFž7
D"„‰¼~V@ˆX¢x;Àfô7òä~~ŽÛtKAùEFÄÆ´R”$”8:ƒ*Yû@¹Ð+rÚ‹H2¡¨šil ’‰~O«¢‡‡0ø]-ÌÌ£ò4xÈWò•c‘# YÀ” ñ«xÑíÑÑ
Ù¹NÉÏ®ç3‚ÒÜAèœïÝÌ:ï	\à8“i3m2jˆöáX—®CnWƒ$ýpÂë}.«¥Ëåå’®Mˆ|.»ÐÆÛ}9¦àq†pÈwF†	†u(J<D.Bã+6w¯Ð§é‹ýYWôEŽÀ`jËb„©@#X@ò8Nïã´7³õ	3§ÙÛÈ|âûÀ @½
#Q€"ƒ’‹ ÁOâ~¯Iþ_Gëþ큢‘ý%	¥+*+êI7Å,`$c

--- NEW FILE patch-2.6.23-git2.bz2.sign ---
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (GNU/Linux)
Comment: See http://www.kernel.org/signature.html for info

iD8DBQBHD8h8yGugalF9Dw4RAhRRAKCPzzteZpOexxqvO6Tp2x2QRpPSBACeMMI0
NftPemvFaeG5glz5nmQozVI=
=r4V7
-----END PGP SIGNATURE-----


--- NEW FILE patch-2.6.23.1.bz2.sign ---
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (GNU/Linux)
Comment: See http://www.kernel.org/signature.html for info

iD8DBQBHD6wRyGugalF9Dw4RAr/CAJ9BsAiCkNZfCQtVNG4YxErkRShR4QCeMSu5
Qaw8VUIRezzD7X6bZPlJ4QU=
=VJ3a
-----END PGP SIGNATURE-----


--- NEW FILE upstream ---
linux-2.6.21.tar.bz2


--- NEW FILE upstream-key.gpg ---
pub  1024D/517D0F0E 2000-10-10 Linux Kernel Archives Verification Key <ftpadmin at kernel.org>
     Key fingerprint = C75D C40A 11D7 AF88 9981  ED5B C86B A06A 517D 0F0E
sub  4096g/E50A8F2A 2000-10-10

-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.0.3 (GNU/Linux)
Comment: For info see http://www.gnupg.org

mQGiBDnirDkRBADCTL/iUTeZKb0tiAcKdZdsUP/KSnrGGjlinolUAsUC0D6/hUB1
RdCpJOOERTIEr1yvehqDM7veRhNMoxJNQxa/sSrkywey5qc8uaskUNEqenimq/70
bahWJeoWXjad68mQFh65lULnHQrrioeJnh9UpyGJppNb/yIjdnymH9aYEwCglgP7
UegBzH22h8NVQEK2PWWbyUUD/jQA4lI0wRWcL9HpkYkHcH0LTKRB9zYpQYtyvzJi
yTGwJyFMfYNXy0RT11dICeLkf3HMR84hkPERKMhALobLxVUbfc7j2AygmzGphWGy
DH/xjptQP/zrsq87ylYRONK18w1J42cm+yZa4XThMDPJMrb9/l8qnxU1JnW7W1al
HKTpBACbs+91KLqrnIGcF44TMwxgUj5CUrayPoEnLU+ZMBqfSjmu8RqEYmTxJCKv
7erBFSuazBGj5X7twunrtrW3bxO63MbLbHjfXSRrMnKOb8dRULIg6eWAnoAx8VVZ
YjrOpwAntU3WxYOpbiCHt9kLbb+N5rvNtFcmOqRRQaCIUFOOaLQ8TGludXggS2Vy
bmVsIEFyY2hpdmVzIFZlcmlmaWNhdGlvbiBLZXkgPGZ0cGFkbWluQGtlcm5lbC5v
cmc+iFUEExECABUFAjnirDkDCwoDAxUDAgMWAgECF4AACgkQyGugalF9Dw4MNACe
JiQTyCmQzPGou2cl/RyOXj79kYYAnAsT6xt72hp/PFiywYM9vBsDVv9niQEVAwUQ
OeKwNWx5eAAqlgcFAQEdZgf/Vn2dMKrn8021NhavP0uA3pHGRmdKQ2WJBdLiN2tv
LkpAioZtho+op+xBz8j1zdIJQ/7XWko869KHge2BAFwA8rWDzjtaAWdE0Jo/NiAR
epUwV2FdRRwSxIcNG2CCPyJnfPokRqjdl2z9k2PkwidHSq+2k6JxCWnOcIXChSKf
kHnemtA65ixAlhuxvyN3MPuYs1jAHyDGcyMfomp1qH9tXFQhhyXRrG2eMAfslstC
XGXLcoLN3O2BMR/fG2GlV6kOqGOvoMIW3clVeQLQ9B1yyekKiVY6Vg+CgK5qhg8z
9tjH4f33zzNDwsx1WSCOU/1LIPzFBNbR9QtTF2XmOUfRs4hGBBARAgAGBQI54rBc
AAoJEH2d7s4ry8YhmjsAoMUW9RxfXBSos0A6LwGd+5pXv/MRAKCYFLG2T4GSV+qf
iRsXnrgDHQHD04hGBBARAgAGBQI54rOZAAoJEPKlddweGoeC/+sAoL5f7JF21mRe
Z8VV4nhh7prm+idSAKCMXDWW/tBOeJDYpiEhgyGSGgJJWrkEDQQ54q+cEBAAjRmb
txamcZ9EYsQTnQvVL2l6vY5Rnbc1JDdcyHEV1kH5OwZWqvckL4QgKKBbTQwyB9pC
o0nGK4PkBbrwL0outfHQ5jl9DUzTKIu+asWUyf3fxfUV6j2A6BMo59KNnJzUyJ2+
B5na6NN8nEqEtmogROtjT8LkOvYwqD4A/5re2vwtie+h5yU6A+JbyGQF6lFxThZj
4WGctBgCcDBqRkPAG8DFFAdeN5SMAArktCYuUGXi2q88EDoOs3Ykw0kB8+ZFECz/
4/b93so5Wt2hC15cxAJoXFfR3mXHm40EHzMdEublWV4blB2KvFocQC74/H74QPUk
cWlc6EhPodKvcuOfTimDxXaiGNFONUPgNAmCXeVoOapdWpb3x7iOHPwSaXeJSrO9
fc4GtVjDv90DT2ekK7cvYk8s6B3t7p7W21Xi+hRgrw63B3HElr01gdMZY5XA5ey/
WmnyBS6LOxXlnVBE+2uSQ+aZHqrLpXcRvq2ZonOziDSE0i940ZvIwlSzn0U5BQWl
9hBDQw78RacYqaFvlpcGiPj75bScB4eemxV6Wdo9mtK0Vrr+9bWScXHEv7did4X+
7tBWKbA8M+g290OSzjeQBGLuPmbjxzEKH9jcUumzBzzC5x5GFh7On9TLXQ4K/oRT
6QQpS93YrTVbR60G4MKsePWLJmg7IgYUtNdLGjsAAwUP/0aAAq8CmWtourj1XxNY
pFmOAU45d65fPWVadKyF++B+uDyRNYN7HQCqrJ7ddn0sH7OBtlE8yaBYgR0TFly9
9+LqQO4r4IGCw2TBgA5tKnOWoPGEzvrLeoxR3SnPrKBlDvx6Rr9h3OJ9UV5u/NLh
mCP9iN10gWCGzsWbONc6qD6PugbTur44D6s4CRK9xfliSrtG3GBHW914UKjJeB9s
e3oc1rkmNv39kKcu33w4XVETAj4qpXnwoJvy639dfvnQt1TWFjIt20iP7m+jkT3B
b526uJ5GuJl6r8sm5OYYRs5cLigvUzRZVgYnjjqlRRACx0WcinKK55Li2Pq4qcRV
vSE5Tr3kTUTGxdmy113FbscrhLhesGALv3Hb7jeeWC8jviGEaHppgUumR6v0hsI1
rZ3K8kCjFRAYV8OKtcEeMqjouArGi5dn0ClmG4lwH4SEdqC/TRNWGG+iVpWf5yCj
9mvtvUhLtl6QjXHLrJdSGyafvqR1EQMJadFt4URvx0M7tqZIcwPUnb+7Oc+J96po
e/EQmnm6rFnTpWz0BbY4mbJC7vUH4JyLs0nlxiKrBjaO9C1DSAKBpjqaga8dQe1Z
kLOI2F7IWFeKV2LaMl+ZvvfWMECNcqNW2fkCuP9Fpz5K+xg21TwovVy93aWKgFL6
06jK51oQp3fW86xXK9ZGKYqQiEYEGBECAAYFAjnir5wACgkQyGugalF9Dw5M9QCg
hhmHalzWf8B3AVrjPrtrRHA1vlgAn3YRlU5l0V5W1iXvHXQCUHIESpgm
=SZZb
-----END PGP PUBLIC KEY BLOCK-----


Index: Config.mk
===================================================================
RCS file: /cvs/pkgs/rpms/kernel-xen-2.6/F-7/Config.mk,v
retrieving revision 1.1
retrieving revision 1.1.14.1
diff -u -r1.1 -r1.1.14.1
--- Config.mk	24 Jan 2007 01:28:48 -0000	1.1
+++ Config.mk	17 Oct 2007 19:26:56 -0000	1.1.14.1
@@ -4,20 +4,14 @@
 debug ?= n
 
 XEN_COMPILE_ARCH    ?= $(shell uname -m | sed -e s/i.86/x86_32/ \
-                         -e s/ppc/powerpc/ -e s/i86pc/x86_32/)
+                                              -e s/ppc/powerpc/)
 XEN_TARGET_ARCH     ?= $(XEN_COMPILE_ARCH)
 XEN_TARGET_X86_PAE  ?= n
-XEN_OS              ?= $(shell uname -s)
-
-CONFIG_$(XEN_OS) := y
 
 # Tools to run on system hosting the build
 HOSTCC     = gcc
 HOSTCFLAGS = -Wall -Werror -Wstrict-prototypes -O2 -fomit-frame-pointer
 
-DISTDIR     ?= $(XEN_ROOT)/dist
-DESTDIR     ?= /
-
 AS         = $(CROSS_COMPILE)as
 LD         = $(CROSS_COMPILE)ld
 CC         = $(CROSS_COMPILE)gcc
@@ -29,72 +23,49 @@
 OBJCOPY    = $(CROSS_COMPILE)objcopy
 OBJDUMP    = $(CROSS_COMPILE)objdump
 
+DISTDIR     ?= $(XEN_ROOT)/dist
+DESTDIR     ?= /
+
 INSTALL      = install
 INSTALL_DIR  = $(INSTALL) -d -m0755
 INSTALL_DATA = $(INSTALL) -m0644
 INSTALL_PROG = $(INSTALL) -m0755
 
-LIB64DIR = lib64
-
-SOCKET_LIBS =
-CURSES_LIBS = -lncurses
-SONAME_LDFLAG = -soname
-SHLIB_CFLAGS = -shared
-
 ifneq ($(debug),y)
 # Optimisation flags are overridable
-CFLAGS ?= -O2 -fomit-frame-pointer
+CFLAGS    ?= -O2 -fomit-frame-pointer
+CFLAGS    += -DNDEBUG
 else
-# Less than -O1 produces bad code and large stack frames
-CFLAGS ?= -O1 -fno-omit-frame-pointer
+CFLAGS    += -O2 -g
 endif
 
+
 ifeq ($(XEN_TARGET_ARCH),x86_32)
 CONFIG_X86 := y
-CONFIG_X86_32 := y
-CONFIG_X86_$(XEN_OS) := y
-
 CONFIG_HVM := y
 CONFIG_MIGRATE := y
 CONFIG_XCUTILS := y
 CONFIG_IOEMU := y
+CONFIG_MBOOTPACK := y
 
 CFLAGS += -m32 -march=i686
 LIBDIR := lib
-
-# Use only if calling $(LD) directly.
-ifeq ($(XEN_OS),OpenBSD)
-LDFLAGS_DIRECT += -melf_i386_obsd
-else
-LDFLAGS_DIRECT += -melf_i386
-endif
 endif
 
 ifeq ($(XEN_TARGET_ARCH),x86_64)
 CONFIG_X86 := y
-CONFIG_X86_64 := y
-CONFIG_X86_$(XEN_OS) := y
-
 CONFIG_HVM := y
 CONFIG_MIGRATE := y
 CONFIG_XCUTILS := y
 CONFIG_IOEMU := y
+CONFIG_MBOOTPACK := y
 
 CFLAGS += -m64
-LIBDIR = $(LIB64DIR)
-
-# Use only if calling $(LD) directly.
-ifeq ($(XEN_OS),OpenBSD)
-LDFLAGS_DIRECT += -melf_x86_64_obsd
-else
-LDFLAGS_DIRECT += -melf_x86_64
-endif
+LIBDIR = lib64
 endif
 
 ifeq ($(XEN_TARGET_ARCH),ia64)
 CONFIG_IA64 := y
-CONFIG_IA64_$(XEN_OS) := y
-
 CONFIG_IOEMU := y
 CONFIG_XCUTILS := y
 
@@ -106,31 +77,19 @@
 EXTRA_LIB += $(EXTRA_PREFIX)/$(LIBDIR)
 endif
 
-# cc-option
-# Usage: cflags-y += $(call cc-option,$(CC),-march=winchip-c6,-march=i586)
-cc-option = $(shell if test -z "`$(1) $(2) -S -o /dev/null -xc \
-              /dev/null 2>&1`"; then echo "$(2)"; else echo "$(3)"; fi ;)
-
-ifneq ($(debug),y)
-CFLAGS += -DNDEBUG
-else
-CFLAGS += -g
-endif
-
-CFLAGS += -std=gnu99
+test-gcc-flag = $(shell $(1) -v --help 2>&1 | grep -q " $(2) " && echo $(2))
 
 CFLAGS += -Wall -Wstrict-prototypes
 
-# -Wunused-value makes GCC 4.x too aggressive for my taste: ignoring the
-# result of any casted expression causes a warning.
-CFLAGS += -Wno-unused-value
-
-HOSTCFLAGS += $(call cc-option,$(HOSTCC),-Wdeclaration-after-statement,)
-CFLAGS     += $(call cc-option,$(CC),-Wdeclaration-after-statement,)
+HOSTCFLAGS += $(call test-gcc-flag,$(HOSTCC),-Wdeclaration-after-statement)
+CFLAGS     += $(call test-gcc-flag,$(CC),-Wdeclaration-after-statement)
 
 LDFLAGS += $(foreach i, $(EXTRA_LIB), -L$(i)) 
 CFLAGS += $(foreach i, $(EXTRA_INCLUDES), -I$(i))
 
+# Choose the best mirror to download linux kernel
+KERNEL_REPO = http://www.kernel.org
+
 # If ACM_SECURITY = y, then the access control module is compiled
 # into Xen and the policy type can be set by the boot policy file
 #        y - Build the Xen ACM framework
@@ -149,8 +108,7 @@
 
 # Optional components
 XENSTAT_XENTOP ?= y
+
 VTPM_TOOLS ?= n
-LIBXENAPI_BINDINGS ?= n
-XENFB_TOOLS ?= n
 
 -include $(XEN_ROOT)/.config


Index: Makefile
===================================================================
RCS file: /cvs/pkgs/rpms/kernel-xen-2.6/F-7/Makefile,v
retrieving revision 1.1
retrieving revision 1.1.14.1
diff -u -r1.1 -r1.1.14.1
--- Makefile	24 Jan 2007 01:26:25 -0000	1.1
+++ Makefile	17 Oct 2007 19:26:56 -0000	1.1.14.1
@@ -1,6 +1,211 @@
-# Makefile for source rpm: kernel-xen-2.6
+# Makefile for source rpm: kernel
 # $Id$
-NAME := kernel-xen-2.6
-SPECFILE = $(firstword $(wildcard *.spec))
+NAME     := kernel
+SPECFILE  = $(firstword $(wildcard *.spec))
 
-include ../common/Makefile.common
+# use noarch for make prep instead of the current CPU
+# noarch creates and checks all config files not just the current one,
+# in addition "i386" isn't a valid kernel target
+PREPARCH  = noarch
+
+# we only check the .sign signatures
+UPSTREAM_CHECKS = sign
+
+# local targets we need to carry around in addition to the default sources
+TARGETS		= download
+
+define find-makefile-common
+for d in common ../common ../../common ; do if [ -f $$d/Makefile.common ] ; then if [ -f $$d/CVS/Root -a -w $$/Makefile.common ] ; then cd $$d ; cvs -Q update ; fi ; echo "$$d/Makefile.common" ; break ; fi ; done
+endef
+
+MAKEFILE_COMMON := $(shell $(find-makefile-common))
+
+ifeq ($(MAKEFILE_COMMON),)
+# attept a checkout
+define checkout-makefile-common
+test -f CVS/Root && { cvs -Q -d $$(cat CVS/Root) checkout common && echo "common/Makefile.common" ; } || { echo "ERROR: I can't figure out how to checkout the 'common' module." ; exit -1 ; } >&2
+endef
+
+MAKEFILE_COMMON := $(shell $(checkout-makefile-common))
+endif
+
+include $(MAKEFILE_COMMON)
+include Makefile.config
+
+debug:
+	@perl -pi -e 's/# CONFIG_SLUB_DEBUG_ON is not set/CONFIG_SLUB_DEBUG_ON=y/' config-nodebug
+	@perl -pi -e 's/# CONFIG_LOCK_STAT is not set/CONFIG_LOCK_STAT=y/' config-nodebug
+	@perl -pi -e 's/# CONFIG_DEBUG_STACK_USAGE is not set/CONFIG_DEBUG_STACK_USAGE=y/' config-nodebug
+	@perl -pi -e 's/# CONFIG_DEBUG_IGNORE_QUIET is not set/CONFIG_DEBUG_IGNORE_QUIET=y/' config-nodebug
+	@perl -pi -e 's/# CONFIG_DEBUG_SLAB is not set/CONFIG_DEBUG_SLAB=y/' config-nodebug
+	@perl -pi -e 's/# CONFIG_DEBUG_MUTEXES is not set/CONFIG_DEBUG_MUTEXES=y/' config-nodebug
+	@perl -pi -e 's/# CONFIG_DEBUG_RT_MUTEXES is not set/CONFIG_DEBUG_RT_MUTEXES=y/' config-nodebug
+	@perl -pi -e 's/# CONFIG_DEBUG_RWSEMS is not set/CONFIG_DEBUG_RWSEMS=y/' config-nodebug
+	@perl -pi -e 's/# CONFIG_DEBUG_LOCK_ALLOC is not set/CONFIG_DEBUG_LOCK_ALLOC=y/' config-nodebug
+	@perl -pi -e 's/# CONFIG_PROVE_LOCKING is not set/CONFIG_PROVE_LOCKING=y/' config-nodebug
+	@perl -pi -e 's/# CONFIG_DEBUG_SPINLOCK is not set/CONFIG_DEBUG_SPINLOCK=y/' config-nodebug
+	@perl -pi -e 's/# CONFIG_DEBUG_VM is not set/CONFIG_DEBUG_VM=y/' config-nodebug
+	@perl -pi -e 's/# CONFIG_DEBUG_SLEEP_IN_IRQ is not set/CONFIG_DEBUG_SLEEP_IN_IRQ=y/' config-nodebug
+	@perl -pi -e 's/# CONFIG_FAULT_INJECTION is not set/CONFIG_FAULT_INJECTION=y/' config-nodebug
+	@perl -pi -e 's/# CONFIG_FAILSLAB is not set/CONFIG_FAILSLAB=y/' config-nodebug
+	@perl -pi -e 's/# CONFIG_FAIL_PAGE_ALLOC is not set/CONFIG_FAIL_PAGE_ALLOC=y/' config-nodebug
+	@perl -pi -e 's/# CONFIG_FAIL_MAKE_REQUEST is not set/CONFIG_FAIL_MAKE_REQUEST=y/' config-nodebug
+	@perl -pi -e 's/# CONFIG_FAULT_INJECTION_DEBUG_FS is not set/CONFIG_FAULT_INJECTION_DEBUG_FS=y/' config-nodebug
+	@perl -pi -e 's/# CONFIG_FAULT_INJECTION_STACKTRACE_FILTER is not set/CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y/' config-nodebug
+
+	@perl -pi -e 's/# CONFIG_EXT4DEV_FS is not set/CONFIG_EXT4DEV_FS=m/' config-generic
+
+	@perl -pi -e 's/^%define debugbuildsenabled 1/%define debugbuildsenabled 0/' kernel.spec
+
+release:
+	@perl -pi -e 's/CONFIG_SLUB_DEBUG_ON=y/# CONFIG_SLUB_DEBUG_ON is not set/' config-nodebug
+	@perl -pi -e 's/CONFIG_LOCK_STAT=y/# CONFIG_LOCK_STAT is not set/' config-nodebug
+	@perl -pi -e 's/CONFIG_DEBUG_STACK_USAGE=y/# CONFIG_DEBUG_STACK_USAGE is not set/' config-nodebug
+	@perl -pi -e 's/CONFIG_DEBUG_IGNORE_QUIET=y/# CONFIG_DEBUG_IGNORE_QUIET is not set/' config-nodebug
+	@perl -pi -e 's/CONFIG_DEBUG_SLAB=y/# CONFIG_DEBUG_SLAB is not set/' config-nodebug
+	@perl -pi -e 's/CONFIG_DEBUG_MUTEXES=y/# CONFIG_DEBUG_MUTEXES is not set/' config-nodebug
+	@perl -pi -e 's/CONFIG_DEBUG_RT_MUTEXES=y/# CONFIG_DEBUG_RT_MUTEXES is not set/' config-nodebug
+	@perl -pi -e 's/CONFIG_DEBUG_RWSEMS=y/# CONFIG_DEBUG_RWSEMS is not set/' config-nodebug
+	@perl -pi -e 's/CONFIG_DEBUG_LOCK_ALLOC=y/# CONFIG_DEBUG_LOCK_ALLOC is not set/' config-nodebug
+	@perl -pi -e 's/CONFIG_PROVE_LOCKING=y/# CONFIG_PROVE_LOCKING is not set/' config-nodebug
+	@perl -pi -e 's/CONFIG_DEBUG_SPINLOCK=y/# CONFIG_DEBUG_SPINLOCK is not set/' config-nodebug
+	@perl -pi -e 's/CONFIG_DEBUG_PAGEALLOC=y/# CONFIG_DEBUG_PAGEALLOC is not set/' config-nodebug
+	@perl -pi -e 's/CONFIG_DEBUG_VM=y/# CONFIG_DEBUG_VM is not set/' config-nodebug
+	@perl -pi -e 's/CONFIG_DEBUG_SLEEP_IN_IRQ=y/# CONFIG_DEBUG_SLEEP_IN_IRQ is not set/' config-nodebug
+	@perl -pi -e 's/CONFIG_FAULT_INJECTION=y/# CONFIG_FAULT_INJECTION is not set/' config-nodebug
+	@perl -pi -e 's/CONFIG_FAILSLAB=y/# CONFIG_FAILSLAB is not set/' config-nodebug
+	@perl -pi -e 's/CONFIG_FAIL_PAGE_ALLOC=y/# CONFIG_FAIL_PAGE_ALLOC is not set/' config-nodebug
+	@perl -pi -e 's/CONFIG_FAIL_MAKE_REQUEST=y/# CONFIG_FAIL_MAKE_REQUEST is not set/' config-nodebug
+	@perl -pi -e 's/CONFIG_FAULT_INJECTION_DEBUG_FS=y/# CONFIG_FAULT_INJECTION_DEBUG_FS is not set/' config-nodebug
+	@perl -pi -e 's/CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y/# CONFIG_FAULT_INJECTION_STACKTRACE_FILTER is not set/' config-nodebug
+
+	@perl -pi -e 's/CONFIG_EXT4DEV_FS=m/# CONFIG_EXT4DEV_FS is not set/' config-generic
+
+	@perl -pi -e 's/^%define debugbuildsenabled 0/%define debugbuildsenabled 1/' kernel.spec
+
+
+reconfig:
+	@rm -f kernel-*-config
+	@VERSION="2.6.23" make -f Makefile.config configs
+	@scripts/reconfig.sh
+
+# since i386 isn't a target...
+compile compile-short: DIST_DEFINES += --target $(shell uname -m)
+
+#
+# Hacks for building vanilla (unpatched) kernel rpms.
+# Use "make vanilla-TARGET" like "make TARGET" (make vanilla-scratch-build).
+#
+vanilla-%: $(SPECFILE:.spec=-vanilla.spec)
+	@$(MAKE) $* SPECFILE=$<
+
+$(SPECFILE:.spec=-vanilla.spec): $(SPECFILE)
+	@rm -f $@
+	(echo %define nopatches 1; cat $<) > $@
+
+scratch-build: NAME = $(shell rpm $(RPM_DEFINES) $(DIST_DEFINES) -q --qf "%{NAME}\n" --specfile $(SPECFILE)| head -1)
+scratch-build: test-srpm
+	$(BUILD_CLIENT) build $(BUILD_FLAGS) --scratch $(TARGET) \
+			$(SRCRPMDIR)/$(NAME)-$(VERSION)-$(RELEASE).src.rpm
+
+# Dismal kludge for building via brew from cvs after "make vanilla-tag".
+ifdef BEEHIVE_SRPM_BUILD
+export CHECKOUT_TAG ?= $(shell sed s/^.// CVS/Tag)
+tag-pattern = $(TAG_NAME)-$(TAG_VERSION)-0_%_$(TAG_RELEASE)
+ifeq (,$(filter-out $(tag-pattern),$(CHECKOUT_TAG)))
+variant := $(patsubst $(tag-pattern),%,$(CHECKOUT_TAG))
+srpm: SPECFILE := $(wildcard $(SPECFILE:.spec=-$(variant).spec) \
+			     $(SPECFILE:.spec=-t.$(variant).spec))
+srpm beehive-sprm: RELEASE := 0.$(variant).$(RELEASE)
+endif
+endif
+
+
+#
+# Hacks for building kernel rpms from upstream code plus local GIT branches.
+# Use "make git/BRANCH/TARGET" like "make TARGET".
+# Use "make git/BRANCH-fedora/TARGET" to include Fedora patches on top.
+#
+ifndef GIT_SPEC
+git/%:
+	@$(MAKE) GIT_SPEC=$(subst /,-,$(*D)) git-$(*F)
+else
+git-%: $(SPECFILE:.spec=-t.$(GIT_SPEC).spec)
+	@$(MAKE) GIT_SPEC= $* SPECFILE=$<
+endif
+
+#
+# Your git-branches.mk file can define GIT_DIR, e.g.:
+#	GIT_DIR = ${HOME}/kernel/.git
+# Make sure GIT_AUTHOR_NAME and GIT_AUTHOR_EMAIL are also set
+# or your rpm changelogs will look like crap.
+#
+# For each branch it can define a variable branch-BRANCH or tag-BRANCH
+# giving the parent of BRANCH to diff against in a separate patch.  If
+# the parent is unknown, it will use $(branch-upstream) defaulting to
+# "refs/remotes/upstream/master".
+#
+# Defining tag-BRANCH means the tag corresponds to an upstream patch in
+# the sources file, so that is used instead of generating a patch with
+# git.  If there is no tag-upstream defined, it will figure out a vNNN
+# tag or vNNN-gitN pseudo-tag from the last patch in the sources file.
+# For example:
+#	tag-some-hacks = v2.6.21-rc5
+#	branch-more-hacks = some-hacks
+# Leads to patches:
+#	git diff v2.6.21-rc5..more-hacks > linux-2.6.21-rc5-some-hacks.patch
+#	git diff some-hacks..more-hacks > linux-2.6.21-rc5-more-hacks.patch
+# Whereas having no git-branches.mk at all but doing
+# "make GIT_DIR=... git/mybranch/test-srpm" does:
+#	id=`cat patch-2.6.21-rc5-git4.id` # auto-fetched via upstream file
+#	git diff $id..upstream > linux-2.6.21-rc5-git4-upstream.patch
+#	git diff upstream..mybranch > linux-2.6.21-rc5-git4-mybranch.patch
+# If the upstream patch (or any branch patch) is empty it's left out.
+#
+git-branches.mk:;
+-include git-branches.mk
+
+branch-upstream ?= refs/remotes/upstream/master
+
+ifdef GIT_DIR
+export GIT_DIR
+export GIT_AUTHOR_NAME
+export GIT_AUTHOR_EMAIL
+gen-patches ?= gen-patches
+
+ifndef havespec
+$(SPECFILE:.spec=-t.%-fedora.spec): $(SPECFILE) $(gen-patches) FORCE
+	./$(gen-patches) --fedora < $< > $@ $(gen-patches-args)
+$(SPECFILE:.spec=-t.%.spec): $(SPECFILE) $(gen-patches) FORCE
+	./$(gen-patches) < $< > $@ $(gen-patches-args)
+.PRECIOUS: $(SPECFILE:.spec=-t.%.spec) $(SPECFILE:.spec=-t.%-fedora.spec)
+endif
+
+spec-%: $(SPECFILE:.spec=-t.%.spec) ;
+$(SPECFILE):;
+FORCE:;
+
+branch-of-* = $(firstword $(head-$*) $*)
+gen-patches-args = --name $* v$(VERSION) $(call heads,$(branch-of-*))
+define heads
+$(if $(tag-$1),$(filter-out v$(VERSION),$(tag-$1)),\
+     $(call heads,$(firstword $(branch-$1) $(branch-upstream)))) $1
+endef
+
+files-%-fedora:
+	@echo $(SPECFILE:.spec=-t.$*-fedora.spec)
+	@$(call list-patches,$(branch-of-*))
+files-%:
+	@echo $(SPECFILE:.spec=-t.$*.spec)
+	@$(call list-patches,$(branch-of-*))
+define list-patches
+$(if $(tag-$1),version=$(patsubst v%,%,$(tag-$1)),\
+     $(call list-patches,$(firstword $(branch-$1) $(branch-upstream)))); \
+echo linux-$${version}-$(patsubst refs/remotes/%/master,%,$1).patch
+endef
+
+ifndef tag-$(branch-upstream)
+tag-$(branch-upstream) := $(shell \
+	sed -n 's/^.*  *//;s/\.bz2$$//;s/patch-/v/p' sources)
+endif
+endif


Index: config-rhel-generic
===================================================================
RCS file: /cvs/pkgs/rpms/kernel-xen-2.6/F-7/config-rhel-generic,v
retrieving revision 1.1
retrieving revision 1.1.14.1
diff -u -r1.1 -r1.1.14.1
--- config-rhel-generic	24 Jan 2007 01:28:48 -0000	1.1
+++ config-rhel-generic	17 Oct 2007 19:26:56 -0000	1.1.14.1
@@ -60,6 +60,9 @@
 # CONFIG_WAN_ROUTER is not set
 # CONFIG_ROMFS_FS is not set
 # CONFIG_MINIX_FS is not set
+# CONFIG_9P_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_FUSE_FS is not set
 # CONFIG_BINFMT_AOUT is not set
 # CONFIG_DRM_TDFX is not set
 # CONFIG_DRM_SIS is not set
@@ -145,7 +148,6 @@
 # CONFIG_VIDEO_SAA5246A is not set
 # CONFIG_FB_ATY128 is not set
 # CONFIG_FB_RADEON is not set
-# CONFIG_FB_VESA is not set
 # CONFIG_FB_NEOMAGIC is not set
 # CONFIG_I82092 is not set
 # CONFIG_YELLOWFIN is not set
@@ -155,7 +157,6 @@
 # CONFIG_DE600 is not set
 # CONFIG_DE620 is not set
 # CONFIG_CS89x0 is not set
-# CONFIG_DGRS is not set
 # CONFIG_AC3200 is not set
 # CONFIG_NI52 is not set
 # CONFIG_NI65 is not set
@@ -188,4 +189,5 @@
 # CONFIG_DECNET is not set
 # CONFIG_TCG_TPM is not set
 CONFIG_RAW_DRIVER=y
+# CONFIG_ISA is not set
 

linux-2.6-common-uevent.patch:

Index: linux-2.6-common-uevent.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel-xen-2.6/F-7/linux-2.6-common-uevent.patch,v
retrieving revision 1.1
retrieving revision 1.1.14.1
diff -u -r1.1 -r1.1.14.1
--- linux-2.6-common-uevent.patch	22 Mar 2007 16:01:16 -0000	1.1
+++ linux-2.6-common-uevent.patch	17 Oct 2007 19:26:56 -0000	1.1.14.1
@@ -166,3 +166,52 @@
 Linuxppc-dev mailing list
 Linuxppc-dev at ozlabs.org
 https://ozlabs.org/mailman/listinfo/linuxppc-dev
+diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
+index b2f73ff..4903292 100644
+--- a/scripts/mod/file2alias.c
++++ b/scripts/mod/file2alias.c
+@@ -354,11 +354,16 @@ static int do_pcmcia_entry(const char *filename,
+ 
+ static int do_of_entry (const char *filename, struct of_device_id *of, char *alias)
+ {
++    int len;
+     char *tmp;
+-    sprintf (alias, "of:N%sT%sC%s",
++    len = sprintf (alias, "of:N%sT%s",
+                     of->name[0] ? of->name : "*",
+-                    of->type[0] ? of->type : "*",
+-                    of->compatible[0] ? of->compatible : "*");
++                    of->type[0] ? of->type : "*");
++
++    if (of->compatible[0])
++        sprintf (&alias[len], "%sC%s",
++                     of->type[0] ? "*" : "",
++                     of->compatible);
+ 
+     /* Replace all whitespace with underscores */
+     for (tmp = alias; tmp && *tmp; tmp++)
+---
+ sound/aoa/soundbus/i2sbus/i2sbus-core.c |    5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+--- wireless-dev.orig/sound/aoa/soundbus/i2sbus/i2sbus-core.c	2007-04-05 14:31:29.318552246 +0200
++++ wireless-dev/sound/aoa/soundbus/i2sbus/i2sbus-core.c	2007-04-05 14:31:45.188552246 +0200
+@@ -23,9 +23,6 @@
+ MODULE_LICENSE("GPL");
+ MODULE_AUTHOR("Johannes Berg <johannes at sipsolutions.net>");
+ MODULE_DESCRIPTION("Apple Soundbus: I2S support");
+-/* for auto-loading, declare that we handle this weird
+- * string that macio puts into the relevant device */
+-MODULE_ALIAS("of:Ni2sTi2sC");
+ 
+ static int force;
+ module_param(force, int, 0444);
+@@ -37,6 +34,8 @@ static struct of_device_id i2sbus_match[
+ 	{ }
+ };
+ 
++MODULE_DEVICE_TABLE(of, i2sbus_match);
++
+ static int alloc_dbdma_descriptor_ring(struct i2sbus_dev *i2sdev,
+ 				       struct dbdma_command_mem *r,
+ 				       int numcmds)

linux-2.6-compile-fixes.patch:

Index: linux-2.6-compile-fixes.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel-xen-2.6/F-7/linux-2.6-compile-fixes.patch,v
retrieving revision 1.2
retrieving revision 1.2.14.1
diff -u -r1.2 -r1.2.14.1
--- linux-2.6-compile-fixes.patch	22 Mar 2007 15:40:59 -0000	1.2
+++ linux-2.6-compile-fixes.patch	17 Oct 2007 19:26:56 -0000	1.2.14.1
@@ -5,69 +5,3 @@
 # to do a compile to figure out what your diff is fixing. Thanks.
 #
 
-
-#drivers/ieee1394/sbp2.c: In function 'sbp2_prep_command_orb_sg':
-#drivers/ieee1394/sbp2.c:1473: error: implicit declaration of function 'sg_dma_len'
-#drivers/ieee1394/sbp2.c:1474: error: implicit declaration of function 'sg_dma_address'
-#
-#Signed-off-by: Dave Jones <davej at redhat.com>
-#
-#--- linux-2.6.19.noarch/include/asm-ia64/scatterlist.h~	2006-12-12 12:35:24.000000000 -0500
-#+++ linux-2.6.19.noarch/include/asm-ia64/scatterlist.h	2006-12-12 12:35:47.000000000 -0500
-#@@ -25,4 +25,12 @@ struct scatterlist {
-#  */
-# #define ISA_DMA_THRESHOLD	0xffffffff
-# 
-#+/* These macros should be used after a pci_map_sg call has been done
-#+ * to get bus addresses of each of the SG entries and their lengths.
-#+ * You should only work with the number of sg entries pci_map_sg
-#+ * returns.
-#+ */
-#+#define sg_dma_address(sg)	((sg)->dma_address)
-#+#define sg_dma_len(sg)		((sg)->dma_length)
-#+
-# #endif /* _ASM_IA64_SCATTERLIST_H */
-
-
-drivers/net/smc-ultra.c: In function 'ultra_block_input':
-drivers/net/smc-ultra.c:458: error: implicit declaration of function 'eth_io_copy_and_sum'
-
-Signed-off-by: Dave Jones <davej at redhat.com>
-
---- linux-2.6.19.noarch/include/asm-powerpc/io.h~	2006-12-29 02:11:33.000000000 -0500
-+++ linux-2.6.19.noarch/include/asm-powerpc/io.h	2006-12-29 02:12:30.000000000 -0500
-@@ -729,6 +729,7 @@ static inline void * bus_to_virt(unsigne
- }
- 
- #define page_to_bus(page)	(page_to_phys(page) + PCI_DRAM_OFFSET)
-+#define eth_io_copy_and_sum(a,b,c,d)	eth_copy_and_sum((a),(void __force *)(void __iomem *)(b),(c),(d))
- 
- #endif /* CONFIG_PPC32 */
- 
-
---- linux-2.6.19.ppc64iseries/arch/powerpc/lib/locks.c~	2006-11-29 21:57:37.000000000 +0000
-+++ linux-2.6.19.ppc64iseries/arch/powerpc/lib/locks.c	2006-12-13 16:53:11.000000000 +0000
-@@ -43,9 +43,11 @@ void __spin_yield(raw_spinlock_t *lock)
- 	if (firmware_has_feature(FW_FEATURE_ISERIES))
- 		HvCall2(HvCallBaseYieldProcessor, HvCall_YieldToProc,
- 			((u64)holder_cpu << 32) | yield_count);
-+#ifdef CONFIG_PPC_PSERIES
- 	else
- 		plpar_hcall_norets(H_CONFER,
- 			get_hard_smp_processor_id(holder_cpu), yield_count);
-+#endif
- }
- 
- /*
-@@ -72,9 +74,11 @@ void __rw_yield(raw_rwlock_t *rw)
- 	if (firmware_has_feature(FW_FEATURE_ISERIES))
- 		HvCall2(HvCallBaseYieldProcessor, HvCall_YieldToProc,
- 			((u64)holder_cpu << 32) | yield_count);
-+#ifdef CONFIG_PPC_PSERIES
- 	else
- 		plpar_hcall_norets(H_CONFER,
- 			get_hard_smp_processor_id(holder_cpu), yield_count);
-+#endif
- }
- #endif
- 

linux-2.6-crash-driver-xen.patch:

Index: linux-2.6-crash-driver-xen.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel-xen-2.6/F-7/linux-2.6-crash-driver-xen.patch,v
retrieving revision 1.1
retrieving revision 1.1.14.1
diff -u -r1.1 -r1.1.14.1
--- linux-2.6-crash-driver-xen.patch	24 Jan 2007 01:28:48 -0000	1.1
+++ linux-2.6-crash-driver-xen.patch	17 Oct 2007 19:26:56 -0000	1.1.14.1
@@ -1,28 +1,47 @@
-# HG changeset patch
-# User quintela at elfo.mitica
-# Node ID ed87076d010ee2f549658308cf2298fd888ba94a
-# Parent  7bad01eaf8f795b08be97187c9ed41891cca9bab
-crash xen bits
-
-diff -r 7bad01eaf8f7 -r ed87076d010e arch/i386/mm/init-xen.c
---- a/arch/i386/mm/init-xen.c	Thu Jul 27 02:44:10 2006 +0200
-+++ b/arch/i386/mm/init-xen.c	Thu Jul 27 02:50:45 2006 +0200
-@@ -275,6 +275,7 @@ int page_is_ram(unsigned long pagenr)
- 	}
+Index: patching/arch/i386/mm/init-xen.c
+===================================================================
+--- patching.orig/arch/i386/mm/init-xen.c
++++ patching/arch/i386/mm/init-xen.c
+@@ -276,6 +276,8 @@ int page_is_ram(unsigned long pagenr)
  	return 0;
  }
+ 
 +EXPORT_SYMBOL_GPL(page_is_ram);
++
+ #ifdef CONFIG_HIGHMEM
+ pte_t *kmap_pte;
+ pgprot_t kmap_prot;
+Index: patching/arch/x86_64/mm/init-xen.c
+===================================================================
+--- patching.orig/arch/x86_64/mm/init-xen.c
++++ patching/arch/x86_64/mm/init-xen.c
+@@ -9,6 +9,7 @@
+  *	Modified for Xen.
+  */
  
- /*
-  * devmem_is_allowed() checks to see if /dev/mem access to a certain address is
-diff -r 7bad01eaf8f7 -r ed87076d010e arch/x86_64/mm/init-xen.c
---- a/arch/x86_64/mm/init-xen.c	Thu Jul 27 02:44:10 2006 +0200
-+++ b/arch/x86_64/mm/init-xen.c	Thu Jul 27 02:50:45 2006 +0200
-@@ -964,6 +964,7 @@ static inline int page_is_ram (unsigned 
- {
- 	return 1;
++#include <linux/module.h>
+ #include <linux/signal.h>
+ #include <linux/sched.h>
+ #include <linux/kernel.h>
+@@ -944,6 +945,8 @@ int __add_pages(struct zone *z, unsigned
  }
+ #endif
+ 
 +EXPORT_SYMBOL_GPL(page_is_ram);
++
+ static struct kcore_list kcore_mem, kcore_vmalloc, kcore_kernel, kcore_modules,
+ 			 kcore_vsyscall;
+ 
+Index: patching/arch/x86_64/kernel/e820-xen.c
+===================================================================
+--- patching.orig/arch/x86_64/kernel/e820-xen.c
++++ patching/arch/x86_64/kernel/e820-xen.c
+@@ -26,7 +26,7 @@
+ #include <asm/sections.h>
+ #include <xen/interface/memory.h>
+ 
+-struct e820map e820 __initdata;
++struct e820map e820;
  
- /*
-  * devmem_is_allowed() checks to see if /dev/mem access to a certain address is
+ /* 
+  * PFN of last memory page.

linux-2.6-crash-driver.patch:

Index: linux-2.6-crash-driver.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel-xen-2.6/F-7/linux-2.6-crash-driver.patch,v
retrieving revision 1.1
retrieving revision 1.1.14.1
diff -u -r1.1 -r1.1.14.1
--- linux-2.6-crash-driver.patch	24 Jan 2007 01:28:48 -0000	1.1
+++ linux-2.6-crash-driver.patch	17 Oct 2007 19:26:56 -0000	1.1.14.1
@@ -448,3 +448,14 @@
 +#endif /* __KERNEL__ */
 +
 +#endif /* _ASM_X86_64_CRASH_H */
+--- linux-2.6.21.noarch/arch/x86_64/kernel/e820.c~	2007-05-04 00:04:56.000000000 -0400
++++ linux-2.6.21.noarch/arch/x86_64/kernel/e820.c	2007-05-04 00:05:02.000000000 -0400
+@@ -25,7 +25,7 @@
+ #include <asm/bootsetup.h>
+ #include <asm/sections.h>
+ 
+-struct e820map e820 __initdata;
++struct e820map e820;
+ 
+ /* 
+  * PFN of last memory page.

linux-2.6-debug-no-quiet.patch:

Index: linux-2.6-debug-no-quiet.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel-xen-2.6/F-7/linux-2.6-debug-no-quiet.patch,v
retrieving revision 1.1
retrieving revision 1.1.14.1
diff -u -r1.1 -r1.1.14.1
--- linux-2.6-debug-no-quiet.patch	24 Jan 2007 01:28:48 -0000	1.1
+++ linux-2.6-debug-no-quiet.patch	17 Oct 2007 19:26:56 -0000	1.1.14.1
@@ -1,11 +1,27 @@
---- linux-2.6.14/init/main.c~	2005-12-02 01:23:31.000000000 -0500
-+++ linux-2.6.14/init/main.c	2005-12-02 01:23:51.000000000 -0500
-@@ -210,7 +210,7 @@ static int __init quiet_kernel(char *str
+diff --git a/init/main.c b/init/main.c
+index a92989e..f4dee52 100644
+--- a/init/main.c
++++ b/init/main.c
+@@ -236,7 +236,11 @@ static int __init quiet_kernel(char *str)
  {
  	if (*str)
  		return 0;
--	console_loglevel = 4;
++#ifdef CONFIG_DEBUG_IGNORE_QUIET
 +	console_loglevel = 10;
++#else
+ 	console_loglevel = 4;
++#endif
  	return 1;
  }
  
+--- linux-2.6.21.noarch/lib/Kconfig.debug~	2007-05-28 02:18:07.000000000 -0400
++++ linux-2.6.21.noarch/lib/Kconfig.debug	2007-05-28 02:18:43.000000000 -0400
+@@ -1,3 +1,8 @@
++config DEBUG_IGNORE_QUIET
++	bool "Ignore 'quiet' boot argument"
++	help
++	  If this option is set, the boot parameter 'quiet' will have
++	  no effect.
+ 
+ config PRINTK_TIME
+ 	bool "Show timing information on printks"

linux-2.6-debug-sizeof-structs.patch:

Index: linux-2.6-debug-sizeof-structs.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel-xen-2.6/F-7/linux-2.6-debug-sizeof-structs.patch,v
retrieving revision 1.1
retrieving revision 1.1.14.1
diff -u -r1.1 -r1.1.14.1
--- linux-2.6-debug-sizeof-structs.patch	24 Jan 2007 01:28:48 -0000	1.1
+++ linux-2.6-debug-sizeof-structs.patch	17 Oct 2007 19:26:56 -0000	1.1.14.1
@@ -11,10 +11,12 @@
  /* Called by boot processor to activate the rest. */
  static void __init smp_init(void)
  {
-@@ -371,6 +374,15 @@ static void __init smp_init(void)
- 
- 	smp_commence();
- #endif
+--- linux-2.6.20.noarch/init/main.c~	2007-02-14 11:47:41.000000000 -0500
++++ linux-2.6.20.noarch/init/main.c	2007-02-14 11:48:39.000000000 -0500
+@@ -403,6 +403,15 @@ static void __init smp_init(void)
+ 	/* Any cleanup work */
+ 	printk(KERN_INFO "Brought up %ld CPUs\n", (long)num_online_cpus());
+ 	smp_cpus_done(max_cpus);
 +
 +	printk(KERN_DEBUG "sizeof(vma)=%u bytes\n", (unsigned int) sizeof(struct vm_area_struct));
 +	printk(KERN_DEBUG "sizeof(page)=%u bytes\n", (unsigned int) sizeof(struct page));

linux-2.6-debug-sysfs-crash-debugging-xen.patch:

Index: linux-2.6-debug-sysfs-crash-debugging-xen.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel-xen-2.6/F-7/linux-2.6-debug-sysfs-crash-debugging-xen.patch,v
retrieving revision 1.1
retrieving revision 1.1.14.1
diff -u -r1.1 -r1.1.14.1
--- linux-2.6-debug-sysfs-crash-debugging-xen.patch	24 Jan 2007 01:28:48 -0000	1.1
+++ linux-2.6-debug-sysfs-crash-debugging-xen.patch	17 Oct 2007 19:26:56 -0000	1.1.14.1
@@ -1,22 +1,17 @@
-# HG changeset patch
-# User quintela at elfo.mitica
-# Node ID e5168f3eb0de30d54f9d03d4afeddbb3a1e69d3f
-# Parent  35d3d547d0d38754c0fc4831a7f073531245c835
-sysfs-crash-debugging xen bits
-
-diff -r 35d3d547d0d3 -r e5168f3eb0de arch/i386/kernel/traps-xen.c
---- a/arch/i386/kernel/traps-xen.c	Thu Jul 27 00:46:20 2006 +0200
-+++ b/arch/i386/kernel/traps-xen.c	Thu Jul 27 00:59:37 2006 +0200
-@@ -100,6 +100,8 @@ static int kstack_depth_to_print = 24;
- static int kstack_depth_to_print = 24;
- static int call_trace = 1;
+Index: patching/arch/i386/kernel/traps-xen.c
+===================================================================
+--- patching.orig/arch/i386/kernel/traps-xen.c
++++ patching/arch/i386/kernel/traps-xen.c
+@@ -103,6 +103,8 @@ int kstack_depth_to_print = 24;
+ static unsigned int code_bytes = 64;
  ATOMIC_NOTIFIER_HEAD(i386die_chain);
-+
-+extern char last_sysfs_file[];
  
++extern char last_sysfs_file[];
++
  int register_die_notifier(struct notifier_block *nb)
  {
-@@ -414,6 +416,9 @@ void die(const char * str, struct pt_reg
+ 	vmalloc_sync_all();
+@@ -431,6 +433,9 @@ void die(const char * str, struct pt_reg
  #endif
  		if (nl)
  			printk("\n");
@@ -26,10 +21,11 @@
  		if (notify_die(DIE_OOPS, str, regs, err,
  					current->thread.trap_no, SIGSEGV) !=
  				NOTIFY_STOP) {
-diff -uNp linux-2.6.19.noarch/arch/x86_64/kernel/traps-xen.c.orig linux-2.6.19.noarch/arch/x86_64/kernel/traps-xen.c
---- linux-2.6.19.noarch/arch/x86_64/kernel/traps-xen.c.orig	2006-12-23 21:21:30.000000000 +0100
-+++ linux-2.6.19.noarch/arch/x86_64/kernel/traps-xen.c	2006-12-23 21:23:13.000000000 +0100
-@@ -73,6 +73,8 @@ asmlinkage void spurious_interrupt_bug(v
+Index: patching/arch/x86_64/kernel/traps-xen.c
+===================================================================
+--- patching.orig/arch/x86_64/kernel/traps-xen.c
++++ patching/arch/x86_64/kernel/traps-xen.c
+@@ -74,6 +74,8 @@ asmlinkage void spurious_interrupt_bug(v
  ATOMIC_NOTIFIER_HEAD(die_chain);
  EXPORT_SYMBOL(die_chain);
  
@@ -38,7 +34,7 @@
  int register_die_notifier(struct notifier_block *nb)
  {
  	vmalloc_sync_all();
-@@ -607,6 +609,9 @@ void __kprobes __die(const char * str, s
+@@ -535,6 +537,9 @@ void __kprobes __die(const char * str, s
  	printk("DEBUG_PAGEALLOC");
  #endif
  	printk("\n");

linux-2.6-debug-sysfs-crash-debugging.patch:

Index: linux-2.6-debug-sysfs-crash-debugging.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel-xen-2.6/F-7/linux-2.6-debug-sysfs-crash-debugging.patch,v
retrieving revision 1.1
retrieving revision 1.1.14.1
diff -u -r1.1 -r1.1.14.1
--- linux-2.6-debug-sysfs-crash-debugging.patch	24 Jan 2007 01:28:48 -0000	1.1
+++ linux-2.6-debug-sysfs-crash-debugging.patch	17 Oct 2007 19:26:56 -0000	1.1.14.1
@@ -15,45 +15,45 @@
  fs/sysfs/file.c          |    8 ++++++++
  2 files changed, 13 insertions(+)
 
-diff -puN fs/sysfs/file.c~sysfs-crash-debugging fs/sysfs/file.c
---- devel/fs/sysfs/file.c~sysfs-crash-debugging	2005-11-22 22:31:16.000000000 -0800
-+++ devel-akpm/fs/sysfs/file.c	2005-11-22 22:31:16.000000000 -0800
-@@ -7,6 +7,7 @@
- #include <linux/kobject.h>
- #include <linux/namei.h>
- #include <linux/poll.h>
-+#include <linux/limits.h>
- #include <asm/uaccess.h>
- #include <asm/semaphore.h>
- 
-@@ -324,8 +326,14 @@ static int check_perm(struct inode * ino
- 	return error;
+Index: patching/fs/sysfs/file.c
+===================================================================
+--- patching.orig/fs/sysfs/file.c
++++ patching/fs/sysfs/file.c
+@@ -276,6 +276,8 @@ out:
+ 	return len;
  }
  
 +char last_sysfs_file[PATH_MAX];
 +
- static int sysfs_open_file(struct inode * inode, struct file * filp)
+ static int sysfs_open_file(struct inode *inode, struct file *file)
  {
-+	char *p = d_path(filp->f_dentry, sysfs_mount, last_sysfs_file,
-+			sizeof(last_sysfs_file));
+ 	struct kobject *kobj = sysfs_get_kobject(file->f_path.dentry->d_parent);
+@@ -285,6 +287,11 @@ static int sysfs_open_file(struct inode 
+ 	struct sysfs_ops * ops = NULL;
+ 	int error = 0;
+ 
++	char *p = d_path(file->f_dentry, sysfs_mount, last_sysfs_file,
++		sizeof(last_sysfs_file));
 +	if (p)
 +		memmove(last_sysfs_file, p, strlen(p) + 1);
- 	return check_perm(inode,filp);
- }
++
+ 	if (!kobj || !attr)
+ 		goto Einval;
  
-diff -puN arch/i386/kernel/traps.c~sysfs-crash-debugging arch/i386/kernel/traps.c
---- devel/arch/i386/kernel/traps.c~sysfs-crash-debugging	2005-11-22 22:31:16.000000000 -0800
-+++ devel-akpm/arch/i386/kernel/traps.c	2005-11-22 22:31:16.000000000 -0800
-@@ -95,6 +95,8 @@ static int kstack_depth_to_print = 24;
- struct notifier_block *i386die_chain;
- static DEFINE_SPINLOCK(die_notifier_lock);
+Index: patching/arch/i386/kernel/traps.c
+===================================================================
+--- patching.orig/arch/i386/kernel/traps.c
++++ patching/arch/i386/kernel/traps.c
+@@ -97,6 +97,8 @@ int kstack_depth_to_print = 24;
+ static unsigned int code_bytes = 64;
+ ATOMIC_NOTIFIER_HEAD(i386die_chain);
  
 +extern char last_sysfs_file[];
 +
  int register_die_notifier(struct notifier_block *nb)
  {
- 	int err = 0;
-@@ -388,6 +388,9 @@ void die(const char * str, struct pt_reg
+ 	vmalloc_sync_all();
+@@ -424,6 +426,9 @@ void die(const char * str, struct pt_reg
  #endif
  		if (nl)
  			printk("\n");
@@ -62,19 +62,21 @@
 +#endif
  		if (notify_die(DIE_OOPS, str, regs, err,
  					current->thread.trap_no, SIGSEGV) !=
- 				NOTIFY_STOP)
---- linux-2.6.14/arch/x86_64/kernel/traps.c~	2005-12-02 18:38:28.000000000 -0500
-+++ linux-2.6.14/arch/x86_64/kernel/traps.c	2005-12-02 18:38:57.000000000 -0500
-@@ -75,6 +75,8 @@ asmlinkage void call_debug(void);
- struct notifier_block *die_chain;
- static DEFINE_SPINLOCK(die_notifier_lock);
+ 				NOTIFY_STOP) {
+Index: patching/arch/x86_64/kernel/traps.c
+===================================================================
+--- patching.orig/arch/x86_64/kernel/traps.c
++++ patching/arch/x86_64/kernel/traps.c
+@@ -74,6 +74,8 @@ asmlinkage void spurious_interrupt_bug(v
+ ATOMIC_NOTIFIER_HEAD(die_chain);
+ EXPORT_SYMBOL(die_chain);
  
 +extern char last_sysfs_file[];
 +
  int register_die_notifier(struct notifier_block *nb)
  {
- 	int err = 0;
-@@ -416,6 +416,9 @@ void __die(const char * str, struct pt_r
+ 	vmalloc_sync_all();
+@@ -533,6 +535,9 @@ void __kprobes __die(const char * str, s
  	printk("DEBUG_PAGEALLOC");
  #endif
  	printk("\n");

linux-2.6-debug-taint-vm.patch:

Index: linux-2.6-debug-taint-vm.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel-xen-2.6/F-7/linux-2.6-debug-taint-vm.patch,v
retrieving revision 1.2
retrieving revision 1.2.14.1
diff -u -r1.2 -r1.2.14.1
--- linux-2.6-debug-taint-vm.patch	22 Mar 2007 15:40:59 -0000	1.2
+++ linux-2.6-debug-taint-vm.patch	17 Oct 2007 19:26:56 -0000	1.2.14.1
@@ -1,14 +1,18 @@
---- linux-2.6.16.noarch/include/asm-generic/bug.h~	2006-03-24 15:32:04.000000000 -0500
-+++ linux-2.6.16.noarch/include/asm-generic/bug.h	2006-03-24 15:33:29.000000000 -0500
-@@ -4,10 +4,14 @@
+--- linux-2.6.20.noarch/include/asm-generic/bug.h~	2007-02-12 16:18:21.000000000 -0500
++++ linux-2.6.20.noarch/include/asm-generic/bug.h	2007-02-12 16:19:57.000000000 -0500
+@@ -3,6 +3,10 @@
+ 
  #include <linux/compiler.h>
- #include <linux/config.h>
  
 +#ifndef __ASSEMBLY__
 +extern const char *print_tainted(void);
 +#endif
 +
  #ifdef CONFIG_BUG
+ 
+ #ifdef CONFIG_GENERIC_BUG
+@@ -22,7 +26,7 @@ struct bug_entry {
+ 
  #ifndef HAVE_ARCH_BUG
  #define BUG() do { \
 -	printk("BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __FUNCTION__); \
@@ -16,15 +20,16 @@
  	panic("BUG!"); \
  } while (0)
  #endif
-@@ -19,7 +23,7 @@
- #ifndef HAVE_ARCH_WARN_ON
- #define WARN_ON(condition) do { \
- 	if (unlikely((condition)!=0)) { \
--		printk("BUG: warning at %s:%d/%s()\n", __FILE__, __LINE__, __FUNCTION__); \
+@@ -35,8 +39,7 @@ struct bug_entry {
+ #define WARN_ON(condition) ({						\
+ 	typeof(condition) __ret_warn_on = (condition);			\
+ 	if (unlikely(__ret_warn_on)) {					\
+-		printk("BUG: at %s:%d %s()\n", __FILE__,		\
+-			__LINE__, __FUNCTION__);			\
 +		printk("BUG: warning at %s:%d/%s() (%s)\n", __FILE__, __LINE__, __FUNCTION__, print_tainted()); \
- 		dump_stack(); \
- 	} \
- } while (0)
+ 		dump_stack();						\
+ 	}								\
+ 	unlikely(__ret_warn_on);					\
 diff -urNp --exclude-from=/home/davej/.exclude linux-1740/kernel/panic.c linux-2000/kernel/panic.c
 --- linux-1740/kernel/panic.c
 +++ linux-2000/kernel/panic.c
@@ -53,16 +58,29 @@
  	dump_stack();
  	page->flags &= ~(1 << PG_lru	|
  			1 << PG_private |
---- linux-2.6.16.noarch/mm/slab.c~	2006-03-22 18:25:29.000000000 -0500
-+++ linux-2.6.16.noarch/mm/slab.c	2006-03-22 18:25:53.000000000 -0500
-@@ -1573,8 +1573,8 @@ static void check_poison_obj(struct kmem
+--- linux-2.6.20.noarch/mm/slab.c~	2007-04-04 16:36:51.000000000 -0400
++++ linux-2.6.20.noarch/mm/slab.c	2007-04-04 16:37:03.000000000 -0400
+@@ -1802,8 +1802,8 @@ static void check_poison_obj(struct kmem
  			/* Print header */
  			if (lines == 0) {
  				printk(KERN_ERR
--					"Slab corruption: start=%p, len=%d\n",
--					realobj, size);
-+					"Slab corruption: (%s) start=%p, len=%d\n",
-+					print_tainted(), realobj, size);
+-					"Slab corruption: %s start=%p, len=%d\n",
+-					cachep->name, realobj, size);
++					"Slab corruption (%s): %s start=%p, len=%d\n",
++					print_tainted(), cachep->name, realobj, size);
  				print_objinfo(cachep, objp, 0);
  				dump_stack();
  			}
+--- linux-2.6.21.noarch/mm/slab.c~	2007-05-14 11:51:33.000000000 -0400
++++ linux-2.6.21.noarch/mm/slab.c	2007-05-14 11:53:00.000000000 -0400
+@@ -2924,8 +2924,8 @@ static void check_slabp(struct kmem_cach
+ 	if (entries != cachep->num - slabp->inuse) {
+ bad:
+ 		printk(KERN_ERR "slab: Internal list corruption detected in "
+-				"cache '%s'(%d), slabp %p(%d). Hexdump:\n",
+-			cachep->name, cachep->num, slabp, slabp->inuse);
++				"cache '%s'(%d), slabp %p(%d). Tainted(%s). Hexdump:\n",
++			cachep->name, cachep->num, slabp, slabp->inuse, print_tainted());
+ 		for (i = 0;
+ 		     i < sizeof(*slabp) + cachep->num * sizeof(kmem_bufctl_t);
+ 		     i++) {

linux-2.6-devmem-xen.patch:

Index: linux-2.6-devmem-xen.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel-xen-2.6/F-7/linux-2.6-devmem-xen.patch,v
retrieving revision 1.1
retrieving revision 1.1.14.1
diff -u -r1.1 -r1.1.14.1
--- linux-2.6-devmem-xen.patch	24 Jan 2007 01:28:48 -0000	1.1
+++ linux-2.6-devmem-xen.patch	17 Oct 2007 19:26:56 -0000	1.1.14.1
@@ -4,9 +4,10 @@
 # Parent  ad6b852bd54573cf46e8f34ffaeeae3877ec5603
 devmem xen bits
 
-diff -r ad6b852bd545 -r b5b4c7616497 arch/i386/mm/init-xen.c
---- a/arch/i386/mm/init-xen.c	Thu Jul 27 02:02:42 2006 +0200
-+++ b/arch/i386/mm/init-xen.c	Thu Jul 27 02:21:44 2006 +0200
+Index: patching/arch/i386/mm/init-xen.c
+===================================================================
+--- patching.orig/arch/i386/mm/init-xen.c
++++ patching/arch/i386/mm/init-xen.c
 @@ -276,6 +276,25 @@ int page_is_ram(unsigned long pagenr)
  	return 0;
  }
@@ -33,12 +34,13 @@
  #ifdef CONFIG_HIGHMEM
  pte_t *kmap_pte;
  pgprot_t kmap_prot;
-diff -r ad6b852bd545 -r b5b4c7616497 arch/x86_64/mm/init-xen.c
---- a/arch/x86_64/mm/init-xen.c	Thu Jul 27 02:02:42 2006 +0200
-+++ b/arch/x86_64/mm/init-xen.c	Thu Jul 27 02:21:44 2006 +0200
-@@ -960,6 +960,31 @@ int __add_pages(struct zone *z, unsigned
+Index: patching/arch/x86_64/mm/init-xen.c
+===================================================================
+--- patching.orig/arch/x86_64/mm/init-xen.c
++++ patching/arch/x86_64/mm/init-xen.c
+@@ -944,6 +944,31 @@ int __add_pages(struct zone *z, unsigned
  }
- #endif /* CONFIG_MEMORY_HOTPLUG */
+ #endif
  
 +static inline int page_is_ram (unsigned long pagenr)
 +{
@@ -68,10 +70,11 @@
  static struct kcore_list kcore_mem, kcore_vmalloc, kcore_kernel, kcore_modules,
  			 kcore_vsyscall;
  
-diff -r ad6b852bd545 -r b5b4c7616497 include/asm-i386/mach-xen/asm/page.h
---- a/include/asm-i386/mach-xen/asm/page.h	Thu Jul 27 02:02:42 2006 +0200
-+++ b/include/asm-i386/mach-xen/asm/page.h	Thu Jul 27 02:21:44 2006 +0200
-@@ -287,6 +287,8 @@ extern unsigned int __VMALLOC_RESERVE;
+Index: patching/include/asm-i386/mach-xen/asm/page.h
+===================================================================
+--- patching.orig/include/asm-i386/mach-xen/asm/page.h
++++ patching/include/asm-i386/mach-xen/asm/page.h
+@@ -186,6 +186,8 @@ extern unsigned int __VMALLOC_RESERVE;
  
  extern int sysctl_legacy_va_layout;
  
@@ -80,10 +83,11 @@
  extern int page_is_ram(unsigned long pagenr);
  
  #endif /* __ASSEMBLY__ */
-diff -r ad6b852bd545 -r b5b4c7616497 include/asm-x86_64/mach-xen/asm/page.h
---- a/include/asm-x86_64/mach-xen/asm/page.h	Thu Jul 27 02:02:42 2006 +0200
-+++ b/include/asm-x86_64/mach-xen/asm/page.h	Thu Jul 27 02:21:44 2006 +0200
-@@ -322,6 +322,10 @@ static inline pgd_t __pgd(unsigned long 
+Index: patching/include/asm-x86_64/mach-xen/asm/page.h
+===================================================================
+--- patching.orig/include/asm-x86_64/mach-xen/asm/page.h
++++ patching/include/asm-x86_64/mach-xen/asm/page.h
+@@ -214,6 +214,10 @@ static inline pgd_t __pgd(unsigned long 
  #include <asm-generic/memory_model.h>
  #include <asm-generic/page.h>
  

linux-2.6-devmem.patch:

Index: linux-2.6-devmem.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel-xen-2.6/F-7/linux-2.6-devmem.patch,v
retrieving revision 1.2
retrieving revision 1.2.14.1
diff -u -r1.2 -r1.2.14.1
--- linux-2.6-devmem.patch	22 Mar 2007 15:40:59 -0000	1.2
+++ linux-2.6-devmem.patch	17 Oct 2007 19:26:56 -0000	1.2.14.1
@@ -1,7 +1,7 @@
-Index: linux-2.6/arch/i386/mm/init.c
+Index: patching/arch/i386/mm/init.c
 ===================================================================
---- linux-2.6.orig/arch/i386/mm/init.c
-+++ linux-2.6/arch/i386/mm/init.c
+--- patching.orig/arch/i386/mm/init.c
++++ patching/arch/i386/mm/init.c
 @@ -233,6 +233,25 @@ int page_is_ram(unsigned long pagenr)
  	return 0;
  }
@@ -28,11 +28,11 @@
  #ifdef CONFIG_HIGHMEM
  pte_t *kmap_pte;
  pgprot_t kmap_prot;
-Index: linux-2.6/arch/ia64/mm/init.c
+Index: patching/arch/ia64/mm/init.c
 ===================================================================
---- linux-2.6.orig/arch/ia64/mm/init.c
-+++ linux-2.6/arch/ia64/mm/init.c
-@@ -263,6 +263,13 @@ free_initrd_mem (unsigned long start, un
+--- patching.orig/arch/ia64/mm/init.c
++++ patching/arch/ia64/mm/init.c
+@@ -281,6 +281,13 @@ free_initrd_mem (unsigned long start, un
  	}
  }
  
@@ -46,10 +46,10 @@
  /*
   * This installs a clean page in the kernel's page table.
   */
-Index: linux-2.6/arch/powerpc/mm/mem.c
+Index: patching/arch/powerpc/mm/mem.c
 ===================================================================
---- linux-2.6.orig/arch/powerpc/mm/mem.c
-+++ linux-2.6/arch/powerpc/mm/mem.c
+--- patching.orig/arch/powerpc/mm/mem.c
++++ patching/arch/powerpc/mm/mem.c
 @@ -45,6 +45,7 @@
  #include <asm/prom.h>
  #include <asm/lmb.h>
@@ -58,7 +58,7 @@
  #include <asm/vdso.h>
  
  #include "mmu_decl.h"
-@@ -343,6 +344,19 @@ void __init mem_init(void)
+@@ -339,6 +340,19 @@ void __init mem_init(void)
  	max_mapnr = max_pfn;
  	totalram_pages += free_all_bootmem();
  #endif
@@ -78,13 +78,13 @@
  	for_each_online_pgdat(pgdat) {
  		for (i = 0; i < pgdat->node_spanned_pages; i++) {
  			if (!pfn_valid(pgdat->node_start_pfn + i))
-Index: linux-2.6/arch/s390/mm/init.c
+Index: patching/arch/s390/mm/init.c
 ===================================================================
---- linux-2.6.orig/arch/s390/mm/init.c
-+++ linux-2.6/arch/s390/mm/init.c
-@@ -241,6 +241,11 @@ void __init paging_init(void)
+--- patching.orig/arch/s390/mm/init.c
++++ patching/arch/s390/mm/init.c
+@@ -148,6 +148,11 @@ void __init paging_init(void)
+ 	free_area_init_nodes(max_zone_pfns);
  }
- #endif /* CONFIG_64BIT */
  
 +int page_is_ram (unsigned long pagenr)
 +{
@@ -94,10 +94,10 @@
  void __init mem_init(void)
  {
  	unsigned long codesize, reservedpages, datasize, initsize;
-Index: linux-2.6/arch/x86_64/mm/init.c
+Index: patching/arch/x86_64/mm/init.c
 ===================================================================
---- linux-2.6.orig/arch/x86_64/mm/init.c
-+++ linux-2.6/arch/x86_64/mm/init.c
+--- patching.orig/arch/x86_64/mm/init.c
++++ patching/arch/x86_64/mm/init.c
 @@ -452,6 +452,28 @@ void __init clear_kernel_mapping(unsigne
  	__flush_tlb_all();
  } 
@@ -154,12 +154,12 @@
  static struct kcore_list kcore_mem, kcore_vmalloc, kcore_kernel, kcore_modules,
  			 kcore_vsyscall;
  
-Index: linux-2.6/drivers/char/mem.c
+Index: patching/drivers/char/mem.c
 ===================================================================
---- linux-2.6.orig/drivers/char/mem.c
-+++ linux-2.6/drivers/char/mem.c
-@@ -102,6 +102,22 @@ static inline int valid_mmap_phys_addr_r
- }
+--- patching.orig/drivers/char/mem.c
++++ patching/drivers/char/mem.c
+@@ -35,6 +35,22 @@
+ # include <linux/efi.h>
  #endif
  
 +static inline int range_is_allowed(unsigned long from, unsigned long to)
@@ -179,9 +179,9 @@
 +}
 +
  /*
-  * This funcion reads the *physical* memory. The f_pos points directly to the 
-  * memory location. 
-@@ -151,6 +167,8 @@ static ssize_t read_mem(struct file * fi
+  * Architectures vary in how they handle caching for addresses
+  * outside of main memory.
+@@ -152,6 +168,8 @@ static ssize_t read_mem(struct file * fi
  		 */
  		ptr = xlate_dev_mem_ptr(p);
  
@@ -190,7 +190,7 @@
  		if (copy_to_user(buf, ptr, sz))
  			return -EFAULT;
  		buf += sz;
-@@ -208,6 +226,8 @@ static ssize_t write_mem(struct file * f
+@@ -209,6 +227,8 @@ static ssize_t write_mem(struct file * f
  		 */
  		ptr = xlate_dev_mem_ptr(p);
  
@@ -199,7 +199,7 @@
  		copied = copy_from_user(ptr, buf, sz);
  		if (copied) {
  			written += sz - copied;
-@@ -357,6 +377,8 @@ static ssize_t read_kmem(struct file *fi
+@@ -359,6 +379,8 @@ static ssize_t read_kmem(struct file *fi
  	ssize_t low_count, read, sz;
  	char * kbuf; /* k-addr because vread() takes vmlist_lock rwlock */
  
@@ -208,7 +208,7 @@
  	read = 0;
  	if (p < (unsigned long) high_memory) {
  		low_count = count;
-@@ -432,126 +454,6 @@ static ssize_t read_kmem(struct file *fi
+@@ -434,126 +456,6 @@ static ssize_t read_kmem(struct file *fi
   	return read;
  }
  
@@ -335,7 +335,7 @@
  #if (defined(CONFIG_ISA) || defined(CONFIG_PCI)) && !defined(__mc68000__)
  static ssize_t read_port(struct file * file, char __user * buf,
  			 size_t count, loff_t *ppos)
-@@ -818,7 +720,6 @@ static const struct file_operations mem_
+@@ -828,7 +730,6 @@ extern const struct file_operations mem_
  static const struct file_operations kmem_fops = {
  	.llseek		= memory_lseek,
  	.read		= read_kmem,
@@ -343,7 +343,7 @@
  	.mmap		= mmap_kmem,
  	.open		= open_kmem,
  	.get_unmapped_area = get_unmapped_area_mem,
-@@ -954,7 +855,6 @@ static const struct {
+@@ -964,7 +865,6 @@ static const struct {
  	const struct file_operations	*fops;
  } devlist[] = { /* list of minor devices */
  	{1, "mem",     S_IRUSR | S_IWUSR | S_IRGRP, &mem_fops},
@@ -351,23 +351,27 @@
  	{3, "null",    S_IRUGO | S_IWUGO,           &null_fops},
  #if (defined(CONFIG_ISA) || defined(CONFIG_PCI)) && !defined(__mc68000__)
  	{4, "port",    S_IRUSR | S_IWUSR | S_IRGRP, &port_fops},
-Index: linux-2.6/fs/proc/kcore.c
+Index: patching/fs/proc/kcore.c
 ===================================================================
---- linux-2.6.orig/fs/proc/kcore.c
-+++ linux-2.6/fs/proc/kcore.c
-@@ -25,7 +25,7 @@
+--- patching.orig/fs/proc/kcore.c
++++ patching/fs/proc/kcore.c
+@@ -23,10 +23,10 @@
+ #include <asm/io.h>
  
+ #define CORE_STR "CORE"
+-
++unsigned int allow_kcore_access = 0;
  static int open_kcore(struct inode * inode, struct file * filp)
  {
 -	return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
-+	return -EPERM;
++	return (capable(CAP_SYS_RAWIO) && allow_kcore_access) ? 0 : -EPERM;
  }
  
  static ssize_t read_kcore(struct file *, char __user *, size_t, loff_t *);
-Index: linux-2.6/include/asm-alpha/page.h
+Index: patching/include/asm-alpha/page.h
 ===================================================================
---- linux-2.6.orig/include/asm-alpha/page.h
-+++ linux-2.6/include/asm-alpha/page.h
+--- patching.orig/include/asm-alpha/page.h
++++ patching/include/asm-alpha/page.h
 @@ -93,6 +93,8 @@ typedef unsigned long pgprot_t;
  #define VM_DATA_DEFAULT_FLAGS		(VM_READ | VM_WRITE | VM_EXEC | \
  					 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
@@ -377,10 +381,10 @@
  #include <asm-generic/memory_model.h>
  #include <asm-generic/page.h>
  
-Index: linux-2.6/include/asm-arm/page.h
+Index: patching/include/asm-arm/page.h
 ===================================================================
---- linux-2.6.orig/include/asm-arm/page.h
-+++ linux-2.6/include/asm-arm/page.h
+--- patching.orig/include/asm-arm/page.h
++++ patching/include/asm-arm/page.h
 @@ -192,6 +192,8 @@ typedef unsigned long pgprot_t;
  
  #include <asm-generic/page.h>
@@ -390,10 +394,10 @@
  #endif /* __KERNEL__ */
  
  #endif
-Index: linux-2.6/include/asm-arm26/page.h
+Index: patching/include/asm-arm26/page.h
 ===================================================================
---- linux-2.6.orig/include/asm-arm26/page.h
-+++ linux-2.6/include/asm-arm26/page.h
+--- patching.orig/include/asm-arm26/page.h
++++ patching/include/asm-arm26/page.h
 @@ -95,6 +95,8 @@ typedef unsigned long pgprot_t;
  #define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
  				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
@@ -403,10 +407,10 @@
  #endif /* __KERNEL__ */
  
  #include <asm-generic/page.h>
-Index: linux-2.6/include/asm-cris/page.h
+Index: patching/include/asm-cris/page.h
 ===================================================================
---- linux-2.6.orig/include/asm-cris/page.h
-+++ linux-2.6/include/asm-cris/page.h
+--- patching.orig/include/asm-cris/page.h
++++ patching/include/asm-cris/page.h
 @@ -76,6 +76,8 @@ typedef struct { unsigned long pgprot; }
  #include <asm-generic/memory_model.h>
  #include <asm-generic/page.h>
@@ -416,10 +420,10 @@
  #endif /* __KERNEL__ */
  
  #endif /* _CRIS_PAGE_H */
-Index: linux-2.6/include/asm-h8300/page.h
+Index: patching/include/asm-h8300/page.h
 ===================================================================
---- linux-2.6.orig/include/asm-h8300/page.h
-+++ linux-2.6/include/asm-h8300/page.h
+--- patching.orig/include/asm-h8300/page.h
++++ patching/include/asm-h8300/page.h
 @@ -78,6 +78,8 @@ extern unsigned long memory_end;
  #include <asm-generic/memory_model.h>
  #include <asm-generic/page.h>
@@ -429,11 +433,11 @@
  #endif /* __KERNEL__ */
  
  #endif /* _H8300_PAGE_H */
-Index: linux-2.6/include/asm-i386/page.h
+Index: patching/include/asm-i386/page.h
 ===================================================================
---- linux-2.6.orig/include/asm-i386/page.h
-+++ linux-2.6/include/asm-i386/page.h
-@@ -108,6 +108,8 @@ extern int sysctl_legacy_va_layout;
+--- patching.orig/include/asm-i386/page.h
++++ patching/include/asm-i386/page.h
+@@ -110,6 +110,8 @@ extern int sysctl_legacy_va_layout;
  
  extern int page_is_ram(unsigned long pagenr);
  
@@ -442,20 +446,23 @@
  #endif /* __ASSEMBLY__ */
  
  #ifdef __ASSEMBLY__
-diff -uNp linux-2.6.20.noarch/include/asm-ia64/page.h.orig linux-2.6.20.noarch/include/asm-ia64/page.h
---- linux-2.6.20.noarch/include/asm-ia64/page.h.orig	2007-03-22 15:34:18.000000000 +0100
-+++ linux-2.6.20.noarch/include/asm-ia64/page.h	2007-03-22 15:34:59.000000000 +0100
-@@ -276,5 +276,6 @@ extern struct address_space xen_ia64_for
+Index: patching/include/asm-ia64/page.h
+===================================================================
+--- patching.orig/include/asm-ia64/page.h
++++ patching/include/asm-ia64/page.h
+@@ -229,6 +229,8 @@ get_order (unsigned long size)
+ 					 (((current->personality & READ_IMPLIES_EXEC) != 0)	\
+ 					  ? VM_EXEC : 0))
  
- #endif /* CONFIG_XEN */
- #endif /* __ASSEMBLY__ */
 +#define devmem_is_allowed(x) 1
- #endif /* __KERNEL__ */
- #endif /* _ASM_IA64_PAGE_H */
-Index: linux-2.6/include/asm-m68k/page.h
++
+ #ifndef __ASSEMBLY__
+ #ifdef CONFIG_XEN
+ 
+Index: patching/include/asm-m68k/page.h
 ===================================================================
---- linux-2.6.orig/include/asm-m68k/page.h
-+++ linux-2.6/include/asm-m68k/page.h
+--- patching.orig/include/asm-m68k/page.h
++++ patching/include/asm-m68k/page.h
 @@ -177,6 +177,8 @@ static inline void *__va(unsigned long x
  
  #include <asm-generic/page.h>
@@ -465,10 +472,10 @@
  #endif /* __KERNEL__ */
  
  #endif /* _M68K_PAGE_H */
-Index: linux-2.6/include/asm-m68knommu/page.h
+Index: patching/include/asm-m68knommu/page.h
 ===================================================================
---- linux-2.6.orig/include/asm-m68knommu/page.h
-+++ linux-2.6/include/asm-m68knommu/page.h
+--- patching.orig/include/asm-m68knommu/page.h
++++ patching/include/asm-m68knommu/page.h
 @@ -77,6 +77,8 @@ extern unsigned long memory_end;
  
  #include <asm-generic/page.h>
@@ -478,22 +485,22 @@
  #endif /* __KERNEL__ */
  
  #endif /* _M68KNOMMU_PAGE_H */
-Index: linux-2.6/include/asm-mips/page.h
+Index: patching/include/asm-mips/page.h
 ===================================================================
---- linux-2.6.orig/include/asm-mips/page.h
-+++ linux-2.6/include/asm-mips/page.h
-@@ -178,4 +178,6 @@ typedef struct { unsigned long pgprot; }
+--- patching.orig/include/asm-mips/page.h
++++ patching/include/asm-mips/page.h
+@@ -199,4 +199,6 @@ typedef struct { unsigned long pgprot; }
  
  #endif /* defined (__KERNEL__) */
  
 +#define devmem_is_allowed(x) 1
 +
  #endif /* _ASM_PAGE_H */
-Index: linux-2.6/include/asm-parisc/page.h
+Index: patching/include/asm-parisc/page.h
 ===================================================================
---- linux-2.6.orig/include/asm-parisc/page.h
-+++ linux-2.6/include/asm-parisc/page.h
-@@ -169,6 +169,8 @@ extern int npmem_ranges;
+--- patching.orig/include/asm-parisc/page.h
++++ patching/include/asm-parisc/page.h
+@@ -173,6 +173,8 @@ extern int npmem_ranges;
  #include <asm-generic/memory_model.h>
  #include <asm-generic/page.h>
  
@@ -502,10 +509,10 @@
  #endif /* __KERNEL__ */
  
  #endif /* _PARISC_PAGE_H */
-Index: linux-2.6/include/asm-ppc/page.h
+Index: patching/include/asm-ppc/page.h
 ===================================================================
---- linux-2.6.orig/include/asm-ppc/page.h
-+++ linux-2.6/include/asm-ppc/page.h
+--- patching.orig/include/asm-ppc/page.h
++++ patching/include/asm-ppc/page.h
 @@ -173,6 +173,8 @@ extern __inline__ int get_order(unsigned
  /* We do define AT_SYSINFO_EHDR but don't use the gate mechanism */
  #define __HAVE_ARCH_GATE_AREA		1
@@ -515,10 +522,10 @@
  #include <asm-generic/memory_model.h>
  #endif /* __KERNEL__ */
  #endif /* _PPC_PAGE_H */
-Index: linux-2.6/include/asm-powerpc/page.h
+Index: patching/include/asm-powerpc/page.h
 ===================================================================
---- linux-2.6.orig/include/asm-powerpc/page.h
-+++ linux-2.6/include/asm-powerpc/page.h
+--- patching.orig/include/asm-powerpc/page.h
++++ patching/include/asm-powerpc/page.h
 @@ -191,6 +191,8 @@ extern const char *arch_vma_name(struct 
  #include <asm-generic/memory_model.h>
  #endif /* __ASSEMBLY__ */
@@ -528,11 +535,11 @@
  #endif /* __KERNEL__ */
  
  #endif /* _ASM_POWERPC_PAGE_H */
-Index: linux-2.6/include/asm-s390/page.h
+Index: patching/include/asm-s390/page.h
 ===================================================================
---- linux-2.6.orig/include/asm-s390/page.h
-+++ linux-2.6/include/asm-s390/page.h
-@@ -148,6 +148,8 @@ page_get_storage_key(unsigned long addr)
+--- patching.orig/include/asm-s390/page.h
++++ patching/include/asm-s390/page.h
+@@ -166,6 +166,8 @@ static inline int pfn_valid(unsigned lon
  #include <asm-generic/memory_model.h>
  #include <asm-generic/page.h>
  
@@ -541,11 +548,11 @@
  #endif /* __KERNEL__ */
  
  #endif /* _S390_PAGE_H */
-Index: linux-2.6/include/asm-sh/page.h
+Index: patching/include/asm-sh/page.h
 ===================================================================
---- linux-2.6.orig/include/asm-sh/page.h
-+++ linux-2.6/include/asm-sh/page.h
-@@ -124,5 +124,7 @@ typedef struct { unsigned long pgprot; }
+--- patching.orig/include/asm-sh/page.h
++++ patching/include/asm-sh/page.h
+@@ -148,5 +148,7 @@ typedef struct { unsigned long pgd; } pg
  #define __HAVE_ARCH_GATE_AREA
  #endif
  
@@ -553,10 +560,10 @@
 +
  #endif /* __KERNEL__ */
  #endif /* __ASM_SH_PAGE_H */
-Index: linux-2.6/include/asm-sh64/page.h
+Index: patching/include/asm-sh64/page.h
 ===================================================================
---- linux-2.6.orig/include/asm-sh64/page.h
-+++ linux-2.6/include/asm-sh64/page.h
+--- patching.orig/include/asm-sh64/page.h
++++ patching/include/asm-sh64/page.h
 @@ -115,5 +115,7 @@ typedef struct { unsigned long pgprot; }
  #include <asm-generic/memory_model.h>
  #include <asm-generic/page.h>
@@ -565,10 +572,10 @@
 +
  #endif /* __KERNEL__ */
  #endif /* __ASM_SH64_PAGE_H */
-Index: linux-2.6/include/asm-sparc/page.h
+Index: patching/include/asm-sparc/page.h
 ===================================================================
---- linux-2.6.orig/include/asm-sparc/page.h
-+++ linux-2.6/include/asm-sparc/page.h
+--- patching.orig/include/asm-sparc/page.h
++++ patching/include/asm-sparc/page.h
 @@ -163,6 +163,8 @@ extern unsigned long pfn_base;
  #include <asm-generic/memory_model.h>
  #include <asm-generic/page.h>
@@ -578,10 +585,10 @@
  #endif /* __KERNEL__ */
  
  #endif /* _SPARC_PAGE_H */
-Index: linux-2.6/include/asm-sparc64/page.h
+Index: patching/include/asm-sparc64/page.h
 ===================================================================
---- linux-2.6.orig/include/asm-sparc64/page.h
-+++ linux-2.6/include/asm-sparc64/page.h
+--- patching.orig/include/asm-sparc64/page.h
++++ patching/include/asm-sparc64/page.h
 @@ -141,6 +141,8 @@ typedef unsigned long pgprot_t;
  #define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
  				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
@@ -591,22 +598,22 @@
  #include <asm-generic/page.h>
  
  #endif /* __KERNEL__ */
-Index: linux-2.6/include/asm-um/page.h
+Index: patching/include/asm-um/page.h
 ===================================================================
---- linux-2.6.orig/include/asm-um/page.h
-+++ linux-2.6/include/asm-um/page.h
+--- patching.orig/include/asm-um/page.h
++++ patching/include/asm-um/page.h
 @@ -113,6 +113,7 @@ extern unsigned long uml_physmem;
  
  extern struct page *arch_validate(struct page *page, gfp_t mask, int order);
  #define HAVE_ARCH_VALIDATE
 +#define devmem_is_allowed(x) 1
  
- extern void arch_free_page(struct page *page, int order);
+ extern int arch_free_page(struct page *page, int order);
  #define HAVE_ARCH_FREE_PAGE
-Index: linux-2.6/include/asm-v850/page.h
+Index: patching/include/asm-v850/page.h
 ===================================================================
---- linux-2.6.orig/include/asm-v850/page.h
-+++ linux-2.6/include/asm-v850/page.h
+--- patching.orig/include/asm-v850/page.h
++++ patching/include/asm-v850/page.h
 @@ -126,6 +126,8 @@ typedef unsigned long pgprot_t;
  #include <asm-generic/memory_model.h>
  #include <asm-generic/page.h>
@@ -616,10 +623,10 @@
  #endif /* KERNEL */
  
  #endif /* __V850_PAGE_H__ */
-Index: linux-2.6/include/asm-x86_64/page.h
+Index: patching/include/asm-x86_64/page.h
 ===================================================================
---- linux-2.6.orig/include/asm-x86_64/page.h
-+++ linux-2.6/include/asm-x86_64/page.h
+--- patching.orig/include/asm-x86_64/page.h
++++ patching/include/asm-x86_64/page.h
 @@ -138,6 +138,10 @@ typedef struct { unsigned long pgprot; }
  #include <asm-generic/memory_model.h>
  #include <asm-generic/page.h>
@@ -631,3 +638,20 @@
  #endif /* __KERNEL__ */
  
  #endif /* _X86_64_PAGE_H */
+Index: patching/arch/x86_64/kernel/machine_kexec.c
+===================================================================
+--- patching.orig/arch/x86_64/kernel/machine_kexec.c
++++ patching/arch/x86_64/kernel/machine_kexec.c
+@@ -344,10 +344,12 @@ NORET_TYPE void machine_kexec(struct kim
+  * Useful for holding code to do something appropriate
+  * after a kernel panic.
+  */
++extern int allow_kcore_access;
+ static int __init setup_crashkernel(char *arg)
+ {
+ 	unsigned long size, base;
+ 	char *p;
++	allow_kcore_access = 1; /*enable ability to read /proc/kcore*/
+ 	if (!arg)
+ 		return -EINVAL;
+ 	size = memparse(arg, &p);

linux-2.6-disable-netback-checksum.patch:

Index: linux-2.6-disable-netback-checksum.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel-xen-2.6/F-7/linux-2.6-disable-netback-checksum.patch,v
retrieving revision 1.1
retrieving revision 1.1.8.1
diff -u -r1.1 -r1.1.8.1
--- linux-2.6-disable-netback-checksum.patch	7 May 2007 18:47:08 -0000	1.1
+++ linux-2.6-disable-netback-checksum.patch	17 Oct 2007 19:26:56 -0000	1.1.8.1
@@ -23,9 +23,11 @@
 Home Page: http://gondor.apana.org.au/~herbert/
 PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
 --
---- a/drivers/xen/netback/interface.c	2007-04-28 11:57:31.000000000 +1000
-+++ b/drivers/xen/netback/interface.c	2007-05-02 19:58:16.000000000 +1000
-@@ -161,7 +161,6 @@
+Index: linux-2.6.21.i386/drivers/xen/netback/interface.c
+===================================================================
+--- linux-2.6.21.i386.orig/drivers/xen/netback/interface.c
++++ linux-2.6.21.i386/drivers/xen/netback/interface.c
+@@ -164,7 +164,6 @@ netif_t *netif_alloc(domid_t domid, unsi
  	dev->open            = net_open;
  	dev->stop            = net_close;
  	dev->change_mtu	     = netbk_change_mtu;
@@ -33,5 +35,3 @@
  
  	SET_ETHTOOL_OPS(dev, &network_ethtool_ops);
  
-
-

linux-2.6-execshield.patch:

Index: linux-2.6-execshield.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel-xen-2.6/F-7/linux-2.6-execshield.patch,v
retrieving revision 1.2
retrieving revision 1.2.14.1
diff -u -r1.2 -r1.2.14.1
--- linux-2.6-execshield.patch	22 Mar 2007 15:40:59 -0000	1.2
+++ linux-2.6-execshield.patch	17 Oct 2007 19:26:57 -0000	1.2.14.1
@@ -90,10 +90,8 @@
 +		current->mm->brk = new_brk;
 +}
 +
-Index: linux-2.6/arch/i386/kernel/smp.c
-===================================================================
---- linux-2.6.orig/arch/i386/kernel/smp.c
-+++ linux-2.6/arch/i386/kernel/smp.c
+--- linux-2.6.20.noarch/arch/i386/kernel/smp.c~	2007-02-17 21:43:47.000000000 -0500
++++ linux-2.6.20.noarch/arch/i386/kernel/smp.c	2007-02-17 21:43:53.000000000 -0500
 @@ -23,6 +23,7 @@
  
  #include <asm/mtrr.h>

linux-2.6-firewire.patch:

View full diff with command:
/usr/bin/cvs -f diff  -kk -u -N -r 1.1 -r 1.1.14.1 linux-2.6-firewire.patch
Index: linux-2.6-firewire.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel-xen-2.6/F-7/linux-2.6-firewire.patch,v
retrieving revision 1.1
retrieving revision 1.1.14.1
diff -u -r1.1 -r1.1.14.1
--- linux-2.6-firewire.patch	22 Mar 2007 16:01:16 -0000	1.1
+++ linux-2.6-firewire.patch	17 Oct 2007 19:26:57 -0000	1.1.14.1
@@ -1,18 +1,18 @@
 diff --git a/drivers/Makefile b/drivers/Makefile
-index 0dd96d1..719f420 100644
+index 3a718f5..ace16e9 100644
 --- a/drivers/Makefile
 +++ b/drivers/Makefile
 @@ -36,6 +36,7 @@ obj-$(CONFIG_FC4)		+= fc4/
  obj-$(CONFIG_SCSI)		+= scsi/
  obj-$(CONFIG_ATA)		+= ata/
  obj-$(CONFIG_FUSION)		+= message/
-+obj-$(CONFIG_FW)		+= firewire/
++obj-$(CONFIG_FIREWIRE)		+= firewire/
  obj-$(CONFIG_IEEE1394)		+= ieee1394/
  obj-y				+= cdrom/
- obj-$(CONFIG_MTD)		+= mtd/
+ obj-y				+= auxdisplay/
 diff --git a/drivers/firewire/Kconfig b/drivers/firewire/Kconfig
 new file mode 100644
-index 0000000..5c46e25
+index 0000000..5fc56fa
 --- /dev/null
 +++ b/drivers/firewire/Kconfig
 @@ -0,0 +1,60 @@
@@ -21,7 +21,7 @@
 +comment "An alternative FireWire stack is available with EXPERIMENTAL=y"
 +	depends on EXPERIMENTAL=n
 +
-+config FW
++config FIREWIRE
 +	tristate "IEEE 1394 (FireWire) support (JUJU alternative stack, experimental)"
 +	depends on EXPERIMENTAL
 +	help
@@ -42,9 +42,9 @@
 +	  stack, or the classic stack (the ieee1394 driver, ohci1394 etc.)
 +	  or both.
 +
-+config FW_OHCI
++config FIREWIRE_OHCI
 +	tristate "Support for OHCI FireWire host controllers"
-+	depends on PCI && FW
++	depends on PCI && FIREWIRE
 +	help
 +	  Enable this driver if you have a FireWire controller based
 +	  on the OHCI specification.  For all practical purposes, this
@@ -57,9 +57,9 @@
 +	  blacklist either ohci1394 or fw-ohci to let hotplug load the desired
 +	  driver.
 +
-+config FW_SBP2
++config FIREWIRE_SBP2
 +	tristate "Support for storage devices (SBP-2 protocol driver)"
-+	depends on FW && SCSI
++	depends on FIREWIRE && SCSI
 +	help
 +	  This option enables you to use SBP-2 devices connected to a
 +	  FireWire bus.  SBP-2 devices include storage devices like
@@ -78,7 +78,7 @@
 +
 diff --git a/drivers/firewire/Makefile b/drivers/firewire/Makefile
 new file mode 100644
-index 0000000..b955c99
+index 0000000..7f02d6f
 --- /dev/null
 +++ b/drivers/firewire/Makefile
 @@ -0,0 +1,10 @@
@@ -87,18 +87,17 @@
 +#
 +
 +fw-core-objs := fw-card.o fw-topology.o fw-transaction.o fw-iso.o \
-+	fw-device.o fw-device-cdev.o
++	fw-device.o fw-cdev.o
 +
-+obj-$(CONFIG_FW) += fw-core.o
-+obj-$(CONFIG_FW_OHCI) += fw-ohci.o
-+obj-$(CONFIG_FW_SBP2) += fw-sbp2.o
-\ No newline at end of file
++obj-$(CONFIG_FIREWIRE) += fw-core.o
++obj-$(CONFIG_FIREWIRE_OHCI) += fw-ohci.o
++obj-$(CONFIG_FIREWIRE_SBP2) += fw-sbp2.o
 diff --git a/drivers/firewire/fw-card.c b/drivers/firewire/fw-card.c
 new file mode 100644
-index 0000000..3f8661a
+index 0000000..a2de680
 --- /dev/null
 +++ b/drivers/firewire/fw-card.c
-@@ -0,0 +1,547 @@
+@@ -0,0 +1,544 @@
 +/*						-*- c-basic-offset: 8 -*-
 + *
 + * fw-card.c - card level functions
@@ -123,6 +122,7 @@
 +#include <linux/module.h>
 +#include <linux/errno.h>
 +#include <linux/device.h>
++#include <linux/rwsem.h>
 +#include "fw-transaction.h"
 +#include "fw-topology.h"
 +#include "fw-device.h"
@@ -131,7 +131,7 @@
 + * polynomial, but we need the ITU-T (or CCITT) polynomial (0x1021).
 + * The implementation below works on an array of host-endian u32
 + * words, assuming they'll be transmited msb first. */
-+static u16
++u16
 +crc16_itu_t(const u32 *buffer, size_t length)
 +{
 +	int shift, i;
@@ -150,6 +150,7 @@
 +	return crc;
 +}
 +
++static DECLARE_RWSEM(card_rwsem);
 +static LIST_HEAD(card_list);
 +
 +static LIST_HEAD(descriptor_list);
@@ -201,11 +202,12 @@
 +	i = 5;
 +	config_rom[i++] = 0;
 +	config_rom[i++] = 0x0c0083c0; /* node capabilities */
-+	config_rom[i++] = 0x03d00d1e; /* vendor id */
 +	j = i + descriptor_count;
 +
 +	/* Generate root directory entries for descriptors. */
 +	list_for_each_entry (desc, &descriptor_list, link) {
++		if (desc->immediate > 0)
++			config_rom[i++] = desc->immediate;
 +		config_rom[i] = desc->key | (j - i);
 +		i++;
 +		j += desc->length;
@@ -260,15 +262,17 @@
 +		i += (desc->data[i] >> 16) + 1;
 +
 +	if (i != desc->length)
-+		return -1;
++		return -EINVAL;
 +
-+	down_write(&fw_bus_type.subsys.rwsem);
++	down_write(&card_rwsem);
 +
 +	list_add_tail (&desc->link, &descriptor_list);
 +	descriptor_count++;
++	if (desc->immediate > 0)
++		descriptor_count++;
 +	update_config_roms();
 +
-+	up_write(&fw_bus_type.subsys.rwsem);
++	up_write(&card_rwsem);
 +
 +	return 0;
 +}
@@ -277,13 +281,15 @@
 +void
 +fw_core_remove_descriptor (struct fw_descriptor *desc)
 +{
-+	down_write(&fw_bus_type.subsys.rwsem);
++	down_write(&card_rwsem);
 +
 +	list_del(&desc->link);
 +	descriptor_count--;
++	if (desc->immediate > 0)
++		descriptor_count--;
 +	update_config_roms();
 +
-+	up_write(&fw_bus_type.subsys.rwsem);
++	up_write(&card_rwsem);
 +}
 +EXPORT_SYMBOL(fw_core_remove_descriptor);
 +
@@ -448,15 +454,6 @@
 +}
 +
 +static void
-+release_card(struct device *device)
-+{
-+	struct fw_card *card =
-+		container_of(device, struct fw_card, card_device);
-+
-+	kfree(card);
-+}
-+
-+static void
 +flush_timer_callback(unsigned long data)
 +{
 +	struct fw_card *card = (struct fw_card *)data;
@@ -470,6 +467,7 @@
 +{
 +	static atomic_t index = ATOMIC_INIT(-1);
 +
++	kref_init(&card->kref);
 +	card->index = atomic_inc_return(&index);
 +	card->driver = driver;
 +	card->device = device;
[...4247 lines suppressed...]
++#define FW_CDEV_EVENT_REQUEST		0x02
++#define FW_CDEV_EVENT_ISO_INTERRUPT	0x03
++
++/* The 'closure' fields are for user space to use.  Data passed in the
++ * 'closure' field for a request will be returned in the corresponding
++ * event.  It's a 64-bit type so that it's a fixed size type big
++ * enough to hold a pointer on all platforms. */
++
++struct fw_cdev_event_common {
++	__u64 closure;
++	__u32 type;
++};
++
++struct fw_cdev_event_bus_reset {
++	__u64 closure;
++	__u32 type;
++	__u32 node_id;
++	__u32 local_node_id;
++	__u32 bm_node_id;
++	__u32 irm_node_id;
++	__u32 root_node_id;
++	__u32 generation;
++};
++
++struct fw_cdev_event_response {
++	__u64 closure;
++	__u32 type;
++	__u32 rcode;
++	__u32 length;
++	__u32 data[0];
++};
++
++struct fw_cdev_event_request {
++	__u64 closure;
++	__u32 type;
++	__u32 tcode;
++	__u64 offset;
++	__u32 handle;
++	__u32 length;
++	__u32 data[0];
++};
++
++struct fw_cdev_event_iso_interrupt {
++	__u64 closure;
++	__u32 type;
++	__u32 cycle;
++	__u32 header_length;	/* Length in bytes of following headers. */
++	__u32 header[0];
++};
++
++union fw_cdev_event {
++	struct fw_cdev_event_common common;
++	struct fw_cdev_event_bus_reset bus_reset;
++	struct fw_cdev_event_response response;
++	struct fw_cdev_event_request request;
++	struct fw_cdev_event_iso_interrupt iso_interrupt;
++};
++
++#define FW_CDEV_IOC_GET_INFO		_IOWR('#', 0x00, struct fw_cdev_get_info)
++#define FW_CDEV_IOC_SEND_REQUEST	_IOW('#', 0x01, struct fw_cdev_send_request)
++#define FW_CDEV_IOC_ALLOCATE		_IOWR('#', 0x02, struct fw_cdev_allocate)
++#define FW_CDEV_IOC_DEALLOCATE		_IOW('#', 0x03, struct fw_cdev_deallocate)
++#define FW_CDEV_IOC_SEND_RESPONSE	_IOW('#', 0x04, struct fw_cdev_send_response)
++#define FW_CDEV_IOC_INITIATE_BUS_RESET	_IOW('#', 0x05, struct fw_cdev_initiate_bus_reset)
++#define FW_CDEV_IOC_ADD_DESCRIPTOR	_IOWR('#', 0x06, struct fw_cdev_add_descriptor)
++#define FW_CDEV_IOC_REMOVE_DESCRIPTOR	_IOW('#', 0x07, struct fw_cdev_remove_descriptor)
++
++#define FW_CDEV_IOC_CREATE_ISO_CONTEXT	_IOWR('#', 0x08, struct fw_cdev_create_iso_context)
++#define FW_CDEV_IOC_QUEUE_ISO		_IOWR('#', 0x09, struct fw_cdev_queue_iso)
++#define FW_CDEV_IOC_START_ISO		_IOW('#', 0x0a, struct fw_cdev_start_iso)
++#define FW_CDEV_IOC_STOP_ISO		_IOW('#', 0x0b, struct fw_cdev_stop_iso)
++
++/* FW_CDEV_VERSION History
++ *
++ * 1	Feb 18, 2007:  Initial version.
++ */
++#define FW_CDEV_VERSION		1
++
++struct fw_cdev_get_info {
++	/* The version field is just a running serial number.  We
++	 * never break backwards compatibility.  Userspace passes in
++	 * the version it expects and the kernel passes back the
++	 * highest version it can provide.  Even if the structs in
++	 * this interface are extended in a later version, the kernel
++	 * will not copy back more data than what was present in the
++	 * interface version userspace expects. */
++	__u32 version;
++
++	/* If non-zero, at most rom_length bytes of config rom will be
++	 * copied into that user space address.  In either case,
++	 * rom_length is updated with the actual length of the config
++	 * rom. */
++	__u32 rom_length;
++	__u64 rom;
++
++	/* If non-zero, a fw_cdev_event_bus_reset struct will be
++	 * copied here with the current state of the bus.  This does
++	 * not cause a bus reset to happen.  The value of closure in
++	 * this and sub-sequent bus reset events is set to
++	 * bus_reset_closure. */
++	__u64 bus_reset;
++	__u64 bus_reset_closure;
++
++	/* The index of the card this devices belongs to. */
++	__u32 card;
++};
++
++struct fw_cdev_send_request {
++	__u32 tcode;
++	__u32 length;
++	__u64 offset;
++	__u64 closure;
++	__u64 data;
++	__u32 generation;
++};
++
++struct fw_cdev_send_response {
++	__u32 rcode;
++	__u32 length;
++	__u64 data;
++	__u32 handle;
++};
++
++struct fw_cdev_allocate {
++	__u64 offset;
++	__u64 closure;
++	__u32 length;
++	__u32 handle;
++};
++
++struct fw_cdev_deallocate {
++	__u32 handle;
++};
++
++#define FW_CDEV_LONG_RESET	0
++#define FW_CDEV_SHORT_RESET	1
++
++struct fw_cdev_initiate_bus_reset {
++	__u32 type;
++};
++
++struct fw_cdev_add_descriptor {
++	__u32 immediate;
++	__u32 key;
++	__u64 data;
++	__u32 length;
++	__u32 handle;
++};
++
++struct fw_cdev_remove_descriptor {
++	__u32 handle;
++};
++
++#define FW_CDEV_ISO_CONTEXT_TRANSMIT	0
++#define FW_CDEV_ISO_CONTEXT_RECEIVE	1
++
++#define FW_CDEV_ISO_CONTEXT_MATCH_TAG0		 1
++#define FW_CDEV_ISO_CONTEXT_MATCH_TAG1		 2
++#define FW_CDEV_ISO_CONTEXT_MATCH_TAG2		 4
++#define FW_CDEV_ISO_CONTEXT_MATCH_TAG3		 8
++#define FW_CDEV_ISO_CONTEXT_MATCH_ALL_TAGS	15
++
++struct fw_cdev_create_iso_context {
++	__u32 type;
++	__u32 header_size;
++	__u32 channel;
++	__u32 speed;
++	__u64 closure;
++	__u32 handle;
++};
++
++struct fw_cdev_iso_packet {
++	__u16 payload_length;	/* Length of indirect payload. */
++	__u32 interrupt : 1;	/* Generate interrupt on this packet */
++	__u32 skip : 1;		/* Set to not send packet at all. */
++	__u32 tag : 2;
++	__u32 sy : 4;
++	__u32 header_length : 8;	/* Length of immediate header. */
++	__u32 header[0];
++};
++
++struct fw_cdev_queue_iso {
++	__u64 packets;
++	__u64 data;
++	__u32 size;
++	__u32 handle;
++};
++
++struct fw_cdev_start_iso {
++	__s32 cycle;
++	__u32 sync;
++	__u32 tags;
++	__u32 handle;
++};
++
++struct fw_cdev_stop_iso {
++	__u32 handle;
++};
++
++#endif /* __fw_cdev_h */

linux-2.6-gfs2-update.patch:

View full diff with command:
/usr/bin/cvs -f diff  -kk -u -N -r 1.1 -r 1.1.14.1 linux-2.6-gfs2-update.patch
Index: linux-2.6-gfs2-update.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel-xen-2.6/F-7/linux-2.6-gfs2-update.patch,v
retrieving revision 1.1
retrieving revision 1.1.14.1
diff -u -r1.1 -r1.1.14.1
--- linux-2.6-gfs2-update.patch	24 Jan 2007 01:28:48 -0000	1.1
+++ linux-2.6-gfs2-update.patch	17 Oct 2007 19:26:57 -0000	1.1.14.1
@@ -1,8764 +1,4636 @@
->From 3ca68df6ee61e1a2034f3307b9edb9b3d87e5ca1 Mon Sep 17 00:00:00 2001
-From: Al Viro <viro at zeniv.linux.org.uk>
-Date: Fri, 13 Oct 2006 20:11:25 -0400
-Subject: [PATCH] [GFS2] split gfs2_dinode into on-disk and host variants
-
-The latter is used as part of gfs2-private part of struct inode.
-It actually stores a lot of fields differently; for now the
-declaration is just cloned, inode field is swtiched and changes
-propagated.
-
-Signed-off-by: Al Viro <viro at zeniv.linux.org.uk>
-Signed-off-by: Steven Whitehouse <swhiteho at redhat.com>
+From davej  Thu May 10 10:55:07 2007
+Return-Path: <swhiteho at redhat.com>
+X-Spam-Checker-Version: SpamAssassin 3.1.8 (2007-02-13) on
+	gelk.kernelslacker.org
+X-Spam-Level: 
+X-Spam-Status: No, score=-2.2 required=5.0 tests=AWL,BAYES_00,
+	UNPARSEABLE_RELAY autolearn=ham version=3.1.8
+Received: from pobox.devel.redhat.com [10.11.255.8]
+	by gelk.kernelslacker.org with IMAP (fetchmail-6.3.6)
+	for <davej at localhost> (single-drop); Thu, 10 May 2007 10:55:07 -0400 (EDT)
+Received: from pobox.devel.redhat.com ([unix socket])
+	 by pobox.devel.redhat.com (Cyrus v2.2.12-Invoca-RPM-2.2.12-3.RHEL4.1) with LMTPA;
+	 Thu, 10 May 2007 10:54:17 -0400
+X-Sieve: CMU Sieve 2.2
+Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254])
+	by pobox.devel.redhat.com (8.13.1/8.13.1) with ESMTP id l4AEsHxI020423
+	for <davej at pobox.devel.redhat.com>; Thu, 10 May 2007 10:54:17 -0400
+Received: from pobox.surrey.redhat.com (pobox.fab.redhat.com [10.33.63.12])
+	by int-mx1.corp.redhat.com (8.13.1/8.13.1) with ESMTP id l4AEsGBe000721
+	for <davej at int-mx1.corp.redhat.com>; Thu, 10 May 2007 10:54:16 -0400
+Received: from [172.31.0.3] (vpn-14-64.rdu.redhat.com [10.11.14.64])
+	by pobox.surrey.redhat.com (8.12.11.20060308/8.12.11) with ESMTP id l4AEsDhb029528
+	for <davej at redhat.com>; Thu, 10 May 2007 15:54:13 +0100
+Subject: GFS2 updated for FC7
+From: Steven Whitehouse <swhiteho at redhat.com>
+To: Dave Jones <davej at redhat.com>
+Content-Type: text/plain
+Organization: Red Hat (UK) Ltd (Registered in England and Wales, No.
+	3798903) Registered office: Red Hat UK Ltd, Amberley Place, 107-111 Peascod
+	Street, Windsor, Berkshire, SL4 ITE
+Date: Thu, 10 May 2007 15:53:30 +0100
+Message-Id: <1178808810.7476.64.camel at quoit>
+Mime-Version: 1.0
+X-Mailer: Evolution 2.8.3 (2.8.3-2.fc6) 
+Content-Transfer-Encoding: 7bit
+Status: RO
+Content-Length: 94290
+Lines: 2983
+
+Hi,
+
+Here is an update patch for FC7. I guess that 2.6.21 will be the kernel
+for the release now? The attached brings it uptodate to the latest
+upstream minus a couple of minor things which we will pick up later on
+when upstream has filtered through. This applies and builds ok for me,
+
+Steve.
+
+
+-----------------------------------------------------------------------------
+
+From: Robert Peterson <rpeterso at redhat.com>
+Date: Mon, 30 Apr 2007 22:09:48 +0000 (-0700)
+Subject: Extend print_symbol capability
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=42e380832a6911c8a3173ee0172fbc0e4864d80b
+
+Extend print_symbol capability
+
+Today's print_symbol function dumps a kernel symbol with printk.  This
+patch extends the functionality of kallsyms.c so that the symbol lookup
+function may be used without the printk.  This is useful for modules that
+want to dump symbols elsewhere, for example, to debugfs.  I intend to use
+the new function call in the GFS2 file system (which will be a separate
+patch).
+
+[akpm at linux-foundation.org: build fix]
+[clameter at sgi.com: sprint_symbol should return length of string like sprintf]
+Signed-off-by: Robert Peterson <rpeterso at redhat.com>
+Cc: Rusty Russell <rusty at rustcorp.com.au>
+Cc: Roman Zippel <zippel at linux-m68k.org>
+Cc: "Randy.Dunlap" <rdunlap at xenotime.net>
+Cc: Sam Ravnborg <sam at ravnborg.org>
+Acked-by: Paulo Marques <pmarques at grupopie.com>
+Signed-off-by: Christoph Lameter <clameter at sgi.com>
+Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
 ---
- fs/gfs2/inode.c             |    4 ++--
- fs/gfs2/ondisk.c            |    6 +++--
- include/linux/gfs2_ondisk.h |   48 ++++++++++++++++++++++++++++++++++++++++---
- 3 files changed, 50 insertions(+), 8 deletions(-)
 
-diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
-index d470e52..191a3df 100644
---- a/fs/gfs2/inode.c
-+++ b/fs/gfs2/inode.c
-@@ -48,7 +48,7 @@ #include "util.h"
- void gfs2_inode_attr_in(struct gfs2_inode *ip)
- {
- 	struct inode *inode = &ip->i_inode;
--	struct gfs2_dinode *di = &ip->i_di;
-+	struct gfs2_dinode_host *di = &ip->i_di;
+diff --git a/include/linux/kallsyms.h b/include/linux/kallsyms.h
+index 1cebcbc..3e3b92d 100644
+--- a/include/linux/kallsyms.h
++++ b/include/linux/kallsyms.h
+@@ -7,6 +7,8 @@
  
- 	inode->i_ino = ip->i_num.no_addr;
  
-@@ -98,7 +98,7 @@ void gfs2_inode_attr_in(struct gfs2_inod
- void gfs2_inode_attr_out(struct gfs2_inode *ip)
- {
- 	struct inode *inode = &ip->i_inode;
--	struct gfs2_dinode *di = &ip->i_di;
-+	struct gfs2_dinode_host *di = &ip->i_di;
- 	gfs2_assert_withdraw(GFS2_SB(inode),
- 		(di->di_mode & S_IFMT) == (inode->i_mode & S_IFMT));
- 	di->di_mode = inode->i_mode;
-diff --git a/fs/gfs2/ondisk.c b/fs/gfs2/ondisk.c
-index 1025960..52cb9a2 100644
---- a/fs/gfs2/ondisk.c
-+++ b/fs/gfs2/ondisk.c
-@@ -153,7 +153,7 @@ void gfs2_quota_in(struct gfs2_quota *qu
- 	qu->qu_value = be64_to_cpu(str->qu_value);
- }
+ #define KSYM_NAME_LEN 127
++#define KSYM_SYMBOL_LEN (sizeof("%s+%#lx/%#lx [%s]") + KSYM_NAME_LEN +	\
++			 2*(BITS_PER_LONG*3/10) + MODULE_NAME_LEN + 1)
  
--void gfs2_dinode_in(struct gfs2_dinode *di, const void *buf)
-+void gfs2_dinode_in(struct gfs2_dinode_host *di, const void *buf)
- {
- 	const struct gfs2_dinode *str = buf;
+ #ifdef CONFIG_KALLSYMS
+ /* Lookup the address for a symbol. Returns 0 if not found. */
+@@ -22,7 +24,10 @@ const char *kallsyms_lookup(unsigned long addr,
+ 			    unsigned long *offset,
+ 			    char **modname, char *namebuf);
  
-@@ -187,7 +187,7 @@ void gfs2_dinode_in(struct gfs2_dinode *
+-/* Replace "%s" in format with address, if found */
++/* Look up a kernel symbol and return it in a text buffer. */
++extern int sprint_symbol(char *buffer, unsigned long address);
++
++/* Look up a kernel symbol and print it to the kernel messages. */
+ extern void __print_symbol(const char *fmt, unsigned long address);
  
+ #else /* !CONFIG_KALLSYMS */
+@@ -47,6 +52,12 @@ static inline const char *kallsyms_lookup(unsigned long addr,
+ 	return NULL;
  }
  
--void gfs2_dinode_out(const struct gfs2_dinode *di, void *buf)
-+void gfs2_dinode_out(const struct gfs2_dinode_host *di, void *buf)
- {
- 	struct gfs2_dinode *str = buf;
- 
-@@ -221,7 +221,7 @@ void gfs2_dinode_out(const struct gfs2_d
- 
++static inline int sprint_symbol(char *buffer, unsigned long addr)
++{
++	*buffer = '\0';
++	return 0;
++}
++
+ /* Stupid that this does nothing, but I didn't create this mess. */
+ #define __print_symbol(fmt, addr)
+ #endif /*CONFIG_KALLSYMS*/
+diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
+index 6f294ff..5a0de84 100644
+--- a/kernel/kallsyms.c
++++ b/kernel/kallsyms.c
+@@ -267,27 +267,33 @@ const char *kallsyms_lookup(unsigned long addr,
+ 	return NULL;
  }
  
--void gfs2_dinode_print(const struct gfs2_dinode *di)
-+void gfs2_dinode_print(const struct gfs2_dinode_host *di)
- {
- 	gfs2_meta_header_print(&di->di_header);
- 	gfs2_inum_print(&di->di_num);
-diff --git a/include/linux/gfs2_ondisk.h b/include/linux/gfs2_ondisk.h
-index a7ae7c1..f334b4b 100644
---- a/include/linux/gfs2_ondisk.h
-+++ b/include/linux/gfs2_ondisk.h
-@@ -270,6 +270,48 @@ struct gfs2_dinode {
- 	__u8 di_reserved[56];
- };
[...12593 lines suppressed...]
-This fixes Red Hat bugzilla #221237
-
-Signed-off-by: S. Wendy Cheng <wcheng at redhat.com>
-Signed-off-by: Steven Whitehouse <swhiteho at redhat.com>
----
- fs/gfs2/inode.c     |   50 +++++++++++++++++++++++++++++++-------------------
- fs/gfs2/inode.h     |    2 +-
- fs/gfs2/ops_inode.c |   25 +++----------------------
- 3 files changed, 35 insertions(+), 42 deletions(-)
-
-diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
-index bab338f..80787de 100644
---- a/fs/gfs2/inode.c
-+++ b/fs/gfs2/inode.c
-@@ -281,13 +281,13 @@ out:
- }
- 
- /**
-- * gfs2_change_nlink_i - Change nlink count on inode
-+ * gfs2_change_nlink - Change nlink count on inode
-  * @ip: The GFS2 inode
-  * @diff: The change in the nlink count required
-  *
-  * Returns: errno
-  */
--int gfs2_change_nlink_i(struct gfs2_inode *ip, int diff)
-+int gfs2_change_nlink(struct gfs2_inode *ip, int diff)
- {
- 	struct buffer_head *dibh;
- 	u32 nlink;
-@@ -320,40 +320,52 @@ int gfs2_change_nlink_i(struct gfs2_inod
- 	brelse(dibh);
- 	mark_inode_dirty(&ip->i_inode);
- 
-+	if (ip->i_di.di_nlink == 0)
-+		error = gfs2_change_nlink_i(ip);
-+
- 	return error;
- }
- 
--int gfs2_change_nlink(struct gfs2_inode *ip, int diff)
-+int gfs2_change_nlink_i(struct gfs2_inode *ip)
- {
- 	struct gfs2_sbd *sdp = ip->i_inode.i_sb->s_fs_info;
--	int error;
--
--	/* update the nlink */
--	error = gfs2_change_nlink_i(ip, diff);
--	if (error)
--		return error;
--
--	/* return meta data block back to rg */
--	if (ip->i_inode.i_nlink == 0) {
--		struct gfs2_rgrpd *rgd;
--		struct gfs2_holder ri_gh, rg_gh;
-+	struct gfs2_inode *rindex = GFS2_I(sdp->sd_rindex);
-+	struct gfs2_glock *ri_gl = rindex->i_gl;
-+	struct gfs2_rgrpd *rgd;
-+	struct gfs2_holder ri_gh, rg_gh;
-+	int existing, error;
- 
-+	/* if we come from rename path, we could have the lock already */
-+	existing = gfs2_glock_is_locked_by_me(ri_gl);
-+	if (!existing) {
- 		error = gfs2_rindex_hold(sdp, &ri_gh);
- 		if (error)
- 			goto out;
--		error = -EIO;
--		rgd = gfs2_blk2rgrpd(sdp, ip->i_num.no_addr);
--		if (!rgd)
--			goto out_norgrp;
-+	}
-+
-+	/* find the matching rgd */
-+	error = -EIO;
-+	rgd = gfs2_blk2rgrpd(sdp, ip->i_num.no_addr);
-+	if (!rgd)
-+		goto out_norgrp;
-+
-+	/*
-+	 * Eventually we may want to move rgd(s) to a linked list
-+	 * and piggyback the free logic into one of gfs2 daemons
-+	 * to gain some performance.
-+	 */
-+	if (!rgd->rd_gl || !gfs2_glock_is_locked_by_me(rgd->rd_gl)) {
- 		error = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, &rg_gh);
- 		if (error)
- 			goto out_norgrp;
- 
- 		gfs2_unlink_di(&ip->i_inode); /* mark inode unlinked */
- 		gfs2_glock_dq_uninit(&rg_gh);
-+	}
-+
- out_norgrp:
-+	if (!existing)
- 		gfs2_glock_dq_uninit(&ri_gh);
--	}
- out:
- 	return error;
- }
-diff --git a/fs/gfs2/inode.h b/fs/gfs2/inode.h
-index 85c67cb..cee281b 100644
---- a/fs/gfs2/inode.h
-+++ b/fs/gfs2/inode.h
-@@ -40,7 +40,7 @@ int gfs2_inode_refresh(struct gfs2_inode
- 
- int gfs2_dinode_dealloc(struct gfs2_inode *inode);
- int gfs2_change_nlink(struct gfs2_inode *ip, int diff);
--int gfs2_change_nlink_i(struct gfs2_inode *ip, int diff);
-+int gfs2_change_nlink_i(struct gfs2_inode *ip);
- struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name,
- 			   int is_root, struct nameidata *nd);
- struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name,
-diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c
-index 919e894..b2a12f4 100644
---- a/fs/gfs2/ops_inode.c
-+++ b/fs/gfs2/ops_inode.c
-@@ -553,7 +553,6 @@ static int gfs2_rename(struct inode *odi
- 	int alloc_required;
- 	unsigned int x;
- 	int error;
--	struct gfs2_rgrpd *rgd;
- 
- 	if (ndentry->d_inode) {
- 		nip = GFS2_I(ndentry->d_inode);
-@@ -685,12 +684,12 @@ static int gfs2_rename(struct inode *odi
- 		error = gfs2_trans_begin(sdp, sdp->sd_max_dirres +
- 					 al->al_rgd->rd_ri.ri_length +
- 					 4 * RES_DINODE + 4 * RES_LEAF +
--					 RES_STATFS + RES_QUOTA + 1, 0);
-+					 RES_STATFS + RES_QUOTA + 4, 0);
- 		if (error)
- 			goto out_ipreserv;
- 	} else {
- 		error = gfs2_trans_begin(sdp, 4 * RES_DINODE +
--					 5 * RES_LEAF + 1, 0);
-+					 5 * RES_LEAF + 4, 0);
- 		if (error)
- 			goto out_gunlock;
- 	}
-@@ -704,25 +703,7 @@ static int gfs2_rename(struct inode *odi
- 			error = gfs2_dir_del(ndip, &ndentry->d_name);
- 			if (error)
- 				goto out_end_trans;
--			error = gfs2_change_nlink_i(nip, -1);
--			if ((!error) && (nip->i_inode.i_nlink == 0)) {
--				error = -EIO;
--				rgd = gfs2_blk2rgrpd(sdp, nip->i_num.no_addr);
--				if (rgd) {
--					struct gfs2_holder nlink_rg_gh;
--					if (rgd != nip->i_alloc.al_rgd)
--						error = gfs2_glock_nq_init(
--						rgd->rd_gl, LM_ST_EXCLUSIVE,
--						0, &nlink_rg_gh);
--					else
--						error = 0;
--                			if (!error) {
--						gfs2_unlink_di(&nip->i_inode);
--						if (rgd != nip->i_alloc.al_rgd)
--							gfs2_glock_dq_uninit(&nlink_rg_gh);
--					}
--				}
--			}
-+			error = gfs2_change_nlink(nip, -1);
- 		}
- 		if (error)
- 			goto out_end_trans;
--- 
-1.4.1
-
->From f8fb3e9d4c0d4e7709803eab2e1b23d76e42009b Mon Sep 17 00:00:00 2001
-From: Steven Whitehouse <swhiteho at redhat.com>
-Date: Tue, 9 Jan 2007 12:00:31 -0500
-Subject: [PATCH] [GFS2] Compile file for previous patch
-
-This is a quick fix to the previous patch to fix a typo which
-prevents it compiling.
-
-Signed-off-by: Steven Whitehouse <swhiteho at redhat.com>
-Cc: Wendy Cheng <wcheng at redhat.com>
----
- fs/gfs2/inode.c |    2 +-
- 1 files changed, 1 insertions(+), 1 deletions(-)
-
-diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
-index 80787de..58c2ce7 100644
---- a/fs/gfs2/inode.c
-+++ b/fs/gfs2/inode.c
-@@ -320,7 +320,7 @@ int gfs2_change_nlink(struct gfs2_inode 
- 	brelse(dibh);
- 	mark_inode_dirty(&ip->i_inode);
- 
--	if (ip->i_di.di_nlink == 0)
-+	if (ip->i_inode.i_nlink == 0)
- 		error = gfs2_change_nlink_i(ip);
- 
- 	return error;
--- 
-1.4.1
 

linux-2.6-modsign-core.patch:

Index: linux-2.6-modsign-core.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel-xen-2.6/F-7/linux-2.6-modsign-core.patch,v
retrieving revision 1.2
retrieving revision 1.2.14.1
diff -u -r1.2 -r1.2.14.1
--- linux-2.6-modsign-core.patch	22 Mar 2007 15:40:59 -0000	1.2
+++ linux-2.6-modsign-core.patch	17 Oct 2007 19:26:57 -0000	1.2.14.1
@@ -1,21 +1,43 @@
---- linux-2.6.18.noarch/include/linux/module.h~	2006-10-14 18:37:27.000000000 -0400
-+++ linux-2.6.18.noarch/include/linux/module.h	2006-10-14 18:38:27.000000000 -0400
-@@ -319,6 +319,9 @@ struct module
- 
- 	unsigned int taints;	/* same bits as kernel:tainted */
+MODSIGN: Apply signature checking to modules on module load
+
+From: David Howells <dhowells at redhat.com>
+
+Apply signature checking to modules on module load, checking the signature
+against the ring of public keys compiled into the kernel.
+
+Signed-Off-By: David Howells <dhowells at redhat.com>
+---
+
+ include/linux/module.h     |    3 
+ init/Kconfig               |   18 ++
+ kernel/Makefile            |    1 
+ kernel/module-verify-sig.c |  450 ++++++++++++++++++++++++++++++++++++++++++++
+ kernel/module-verify.c     |    5 
+ kernel/module-verify.h     |   12 +
+ kernel/module.c            |   12 +
+ 7 files changed, 498 insertions(+), 3 deletions(-)
+
+diff --git a/include/linux/module.h b/include/linux/module.h
+index 10f771a..159560d 100644
+--- a/include/linux/module.h
++++ b/include/linux/module.h
+@@ -326,6 +326,9 @@ #ifdef CONFIG_GENERIC_BUG
+ 	unsigned num_bugs;
+ #endif
  
-+	/* Am I gpg signed */
++	/* Is this module GPG signed */
 +	int gpgsig_ok;
 +
  #ifdef CONFIG_MODULE_UNLOAD
  	/* Reference counts */
  	struct module_ref ref[NR_CPUS];
-diff -urNp --exclude-from=/home/davej/.exclude linux-811/init/Kconfig linux-900/init/Kconfig
---- linux-811/init/Kconfig
-+++ linux-900/init/Kconfig
-@@ -434,6 +434,22 @@ config MODULE_SRCVERSION_ALL
- 	  the version).  With this option, such a "srcversion" field
- 	  will be created for all modules.  If unsure, say N.
+diff --git a/init/Kconfig b/init/Kconfig
+index d1ca69b..b03e9f3 100644
+--- a/init/Kconfig
++++ b/init/Kconfig
+@@ -555,10 +555,26 @@ config MODULE_VERIFY_ELF
+ 	help
+ 	  Check ELF structure of modules upon load
  
 +config MODULE_SIG
 +	bool "Module signature verification (EXPERIMENTAL)"
@@ -33,469 +55,32 @@
 +	  Reject unsigned modules or signed modules for which we don't have a
 +	  key.
 +
+ config MODULE_VERIFY
+ 	bool
+ 	depends on MODULES
+-	default y if MODULE_VERIFY_ELF
++	default y if MODULE_VERIFY_ELF || MODULE_SIG
+ 
  config KMOD
  	bool "Automatic kernel module loading"
- 	depends on MODULES
---- linux-2.6.17.noarch/kernel/Makefile~	2006-06-21 23:47:11.000000000 -0400
-+++ linux-2.6.17.noarch/kernel/Makefile	2006-06-21 23:47:19.000000000 -0400
-@@ -19,7 +19,8 @@ obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o
- obj-$(CONFIG_SMP) += cpu.o spinlock.o
- obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock.o
- obj-$(CONFIG_UID16) += uid16.o
--obj-$(CONFIG_MODULES) += module.o
-+obj-$(CONFIG_MODULES) += module.o module-verify.o
+diff --git a/kernel/Makefile b/kernel/Makefile
+index 5ed0824..715da89 100644
+--- a/kernel/Makefile
++++ b/kernel/Makefile
+@@ -32,6 +32,7 @@ obj-$(CONFIG_UID16) += uid16.o
+ obj-$(CONFIG_MODULES) += module.o
+ obj-$(CONFIG_MODULE_VERIFY) += module-verify.o
+ obj-$(CONFIG_MODULE_VERIFY_ELF) += module-verify-elf.o
 +obj-$(CONFIG_MODULE_SIG) += module-verify-sig.o
  obj-$(CONFIG_KALLSYMS) += kallsyms.o
  obj-$(CONFIG_PM) += power/
  obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
-diff -urNp --exclude-from=/home/davej/.exclude linux-811/kernel/module.c linux-900/kernel/module.c
---- linux-811/kernel/module.c
-+++ linux-900/kernel/module.c
-@@ -45,6 +45,7 @@
- #include <asm/semaphore.h>
- #include <asm/cacheflush.h>
- #include <linux/license.h>
-+#include "module-verify.h"
- 
- #if 0
- #define DEBUGP printk
-@@ -1413,6 +1414,7 @@ static struct module *load_module(void _
- 	long err = 0;
- 	void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */
- 	struct exception_table_entry *extable;
-	mm_segment_t old_fs;
-+	int gpgsig_ok;
- 
- 	DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
-@@ -1438,8 +1440,13 @@ static struct module *load_module(void _
- 		goto free_hdr;
- 	}
- 
--	if (len < hdr->e_shoff + hdr->e_shnum * sizeof(Elf_Shdr))
--		goto truncated;
-+	/* verify the module (validates ELF and checks signature) */
-+	gpgsig_ok = 0;
-+	err = module_verify(hdr, len);
-+	if (err < 0)
-+		goto free_hdr;
-+	if (err == 1)
-+		gpgsig_ok = 1;
- 
- 	/* Convenience variables */
- 	sechdrs = (void *)hdr + hdr->e_shoff;
-@@ -1476,6 +1483,7 @@ static struct module *load_module(void _
- 		goto free_hdr;
- 	}
- 	mod = (void *)sechdrs[modindex].sh_addr;
-+	mod->gpgsig_ok = gpgsig_ok;
- 
- 	if (symindex == 0) {
- 		printk(KERN_WARNING "%s: module has no symbols (stripped?)\n",
---- linux-2.6.18.noarch/kernel/module.c~	2006-10-14 18:39:12.000000000 -0400
-+++ linux-2.6.18.noarch/kernel/module.c	2006-10-14 18:39:43.000000000 -0400
-@@ -2276,8 +2276,13 @@ void print_modules(void)
- 	char buf[8];
- 
- 	printk("Modules linked in:");
--	list_for_each_entry(mod, &modules, list)
-+	list_for_each_entry(mod, &modules, list) {
- 		printk(" %s%s", mod->name, taint_flags(mod->taints, buf));
-+#if CONFIG_MODULE_SIG      
-+		if (!mod->gpgsig_ok)
-+			printk("(U)");
-+#endif
-+	}
- 	printk("\n");
- }
- 
-diff -urNp --exclude-from=/home/davej/.exclude linux-811/kernel/module-verify.c linux-900/kernel/module-verify.c
---- linux-811/kernel/module-verify.c
-+++ linux-900/kernel/module-verify.c
-@@ -0,0 +1,339 @@
-+/* module-verify.c: module verifier
-+ *
-+ * Written by David Howells (dhowells at redhat.com)
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/slab.h>
-+#include <linux/elf.h>
-+#include <linux/crypto.h>
-+#include <linux/crypto/ksign.h>
-+#include "module-verify.h"
-+
-+#if 0
-+#define _debug(FMT, ...) printk(FMT, ##__VA_ARGS__)
-+#else
-+#define _debug(FMT, ...) do {} while (0)
-+#endif
-+
-+static int module_verify_elf(struct module_verify_data *mvdata);
-+
-+/*****************************************************************************/
-+/*
-+ * verify a module's integrity
-+ * - check the ELF is viable
-+ * - check the module's signature if it has one
-+ */
-+int module_verify(const Elf_Ehdr *hdr, size_t size)
-+{
-+	struct module_verify_data mvdata;
-+	int ret;
-+
-+	memset(&mvdata, 0, sizeof(mvdata));
-+	mvdata.buffer	= hdr;
-+	mvdata.hdr	= hdr;
-+	mvdata.size	= size;
-+
-+	ret = module_verify_elf(&mvdata);
-+	if (ret < 0) {
-+		if (ret == -ELIBBAD)
-+			printk("Module failed ELF checks\n");
-+		goto error;
-+	}
-+
-+#ifdef CONFIG_MODULE_SIG
-+	ret = module_verify_signature(&mvdata);
-+#endif
-+
-+ error:
-+	kfree(mvdata.secsizes);
-+	kfree(mvdata.canonlist);
-+	return ret;
-+
-+} /* end module_verify() */
-+
-+/*****************************************************************************/
-+/*
-+ * verify the ELF structure of a module
-+ */
-+static int module_verify_elf(struct module_verify_data *mvdata)
-+{
-+	const Elf_Ehdr *hdr = mvdata->hdr;
-+	const Elf_Shdr *section, *section2, *secstop;
-+	const Elf_Rela *relas, *rela, *relastop;
-+	const Elf_Rel *rels, *rel, *relstop;
-+	const Elf_Sym *symbol, *symstop;
-+	size_t size, sssize, *secsize, tmp, tmp2;
-+	long last;
-+	int line;
-+
-+	size = mvdata->size;
-+	mvdata->nsects = hdr->e_shnum;
-+
-+#define elfcheck(X) \
-+do { if (unlikely(!(X))) { line = __LINE__; goto elfcheck_error; } } while(0)
-+
-+#define seccheck(X) \
-+do { if (unlikely(!(X))) { line = __LINE__; goto seccheck_error; } } while(0)
-+
-+#define symcheck(X) \
-+do { if (unlikely(!(X))) { line = __LINE__; goto symcheck_error; } } while(0)
-+
-+#define relcheck(X) \
-+do { if (unlikely(!(X))) { line = __LINE__; goto relcheck_error; } } while(0)
-+
-+#define relacheck(X) \
-+do { if (unlikely(!(X))) { line = __LINE__; goto relacheck_error; } } while(0)
-+
-+	/* validate the ELF header */
-+	elfcheck(hdr->e_ehsize < size);
-+	elfcheck(hdr->e_entry == 0);
-+	elfcheck(hdr->e_phoff == 0);
-+	elfcheck(hdr->e_phnum == 0);
-+
-+	elfcheck(hdr->e_shnum < SHN_LORESERVE);
-+	elfcheck(hdr->e_shoff < size);
-+	elfcheck(hdr->e_shoff >= hdr->e_ehsize);
-+	elfcheck((hdr->e_shoff & (sizeof(long) - 1)) == 0);
-+	elfcheck(hdr->e_shstrndx > 0);
-+	elfcheck(hdr->e_shstrndx < hdr->e_shnum);
-+	elfcheck(hdr->e_shentsize == sizeof(Elf_Shdr));
-+
-+	tmp = (size_t) hdr->e_shentsize * (size_t) hdr->e_shnum;
-+	elfcheck(tmp < size - hdr->e_shoff);
-+
-+	/* allocate a table to hold in-file section sizes */
-+	mvdata->secsizes = kmalloc(hdr->e_shnum * sizeof(size_t), GFP_KERNEL);
-+	if (!mvdata->secsizes)
-+		return -ENOMEM;
-+
-+	memset(mvdata->secsizes, 0, hdr->e_shnum * sizeof(size_t));
-+
-+	/* validate the ELF section headers */
-+	mvdata->sections = mvdata->buffer + hdr->e_shoff;
-+	secstop = mvdata->sections + mvdata->nsects;
-+
-+	sssize = mvdata->sections[hdr->e_shstrndx].sh_size;
-+	elfcheck(sssize > 0);
-+
-+	section = mvdata->sections;
-+	seccheck(section->sh_type == SHT_NULL);
-+	seccheck(section->sh_size == 0);
-+	seccheck(section->sh_offset == 0);
-+
-+	secsize = mvdata->secsizes + 1;
-+	for (section++; section < secstop; secsize++, section++) {
-+		seccheck(section->sh_name < sssize);
-+		seccheck(section->sh_link < hdr->e_shnum);
-+
-+		if (section->sh_entsize > 0)
-+			seccheck(section->sh_size % section->sh_entsize == 0);
-+
-+		seccheck(section->sh_offset >= hdr->e_ehsize);
-+		seccheck(section->sh_offset < size);
-+
-+		/* determine the section's in-file size */
-+		tmp = size - section->sh_offset;
-+		if (section->sh_offset < hdr->e_shoff)
-+			tmp = hdr->e_shoff - section->sh_offset;
-+
-+		for (section2 = mvdata->sections + 1; section2 < secstop; section2++) {
-+			if (section->sh_offset < section2->sh_offset) {
-+				tmp2 = section2->sh_offset - section->sh_offset;
-+				if (tmp2 < tmp)
-+					tmp = tmp2;
-+			}
-+		}
-+		*secsize = tmp;
-+
-+		_debug("Section %ld: %zx bytes at %lx\n",
-+		       section - mvdata->sections,
-+		       *secsize,
-+		       section->sh_offset);
-+
-+		/* perform section type specific checks */
-+		switch (section->sh_type) {
-+		case SHT_NOBITS:
-+			break;
-+
-+		case SHT_REL:
-+			seccheck(section->sh_entsize == sizeof(Elf_Rel));
-+			goto more_rel_checks;
-+
-+		case SHT_RELA:
-+			seccheck(section->sh_entsize == sizeof(Elf_Rela));
-+		more_rel_checks:
-+			seccheck(section->sh_info > 0);
-+			seccheck(section->sh_info < hdr->e_shnum);
-+			goto more_sec_checks;
-+
-+		case SHT_SYMTAB:
-+			seccheck(section->sh_entsize == sizeof(Elf_Sym));
-+			goto more_sec_checks;
-+
-+		default:
-+		more_sec_checks:
-+			/* most types of section must be contained entirely
-+			 * within the file */
-+			seccheck(section->sh_size <= *secsize);
-+			break;
-+		}
-+	}
-+
-+	/* validate the ELF section names */
-+	section = &mvdata->sections[hdr->e_shstrndx];
-+
-+	seccheck(section->sh_offset != hdr->e_shoff);
-+
-+	mvdata->secstrings = mvdata->buffer + section->sh_offset;
-+
-+	last = -1;
-+	for (section = mvdata->sections + 1; section < secstop; section++) {
-+		const char *secname;
-+		tmp = sssize - section->sh_name;
-+		secname = mvdata->secstrings + section->sh_name;
-+		seccheck(secname[0] != 0);
-+		if (section->sh_name > last)
-+			last = section->sh_name;
-+	}
-+
-+	if (last > -1) {
-+		tmp = sssize - last;
-+		elfcheck(memchr(mvdata->secstrings + last, 0, tmp) != NULL);
-+	}
-+
-+	/* look for various sections in the module */
-+	for (section = mvdata->sections + 1; section < secstop; section++) {
-+		switch (section->sh_type) {
-+		case SHT_SYMTAB:
-+			if (strcmp(mvdata->secstrings + section->sh_name,
-+				   ".symtab") == 0
-+			    ) {
-+				seccheck(mvdata->symbols == NULL);
-+				mvdata->symbols =
-+					mvdata->buffer + section->sh_offset;
-+				mvdata->nsyms =
-+					section->sh_size / sizeof(Elf_Sym);
-+				seccheck(section->sh_size > 0);
-+			}
-+			break;
-+
-+		case SHT_STRTAB:
-+			if (strcmp(mvdata->secstrings + section->sh_name,
-+				   ".strtab") == 0
-+			    ) {
-+				seccheck(mvdata->strings == NULL);
-+				mvdata->strings =
-+					mvdata->buffer + section->sh_offset;
-+				sssize = mvdata->nstrings = section->sh_size;
-+				seccheck(section->sh_size > 0);
-+			}
-+			break;
-+		}
-+	}
-+
-+	if (!mvdata->symbols) {
-+		printk("Couldn't locate module symbol table\n");
-+		goto format_error;
-+	}
-+
-+	if (!mvdata->strings) {
-+		printk("Couldn't locate module strings table\n");
-+		goto format_error;
-+	}
-+
-+	/* validate the symbol table */
-+	symstop = mvdata->symbols + mvdata->nsyms;
-+
-+	symbol = mvdata->symbols;
-+	symcheck(ELF_ST_TYPE(symbol[0].st_info) == STT_NOTYPE);
-+	symcheck(symbol[0].st_shndx == SHN_UNDEF);
-+	symcheck(symbol[0].st_value == 0);
-+	symcheck(symbol[0].st_size == 0);
-+
-+	last = -1;
-+	for (symbol++; symbol < symstop; symbol++) {
-+		symcheck(symbol->st_name < sssize);
-+		if (symbol->st_name > last)
-+			last = symbol->st_name;
-+		symcheck(symbol->st_shndx < mvdata->nsects ||
-+			 symbol->st_shndx >= SHN_LORESERVE);
-+	}
-+
-+	if (last > -1) {
-+		tmp = sssize - last;
-+		elfcheck(memchr(mvdata->strings + last, 0, tmp) != NULL);
-+	}
-+
-+	/* validate each relocation table as best we can */
-+	for (section = mvdata->sections + 1; section < secstop; section++) {
-+		section2 = mvdata->sections + section->sh_info;
-+
-+		switch (section->sh_type) {
-+		case SHT_REL:
-+			rels = mvdata->buffer + section->sh_offset;
-+			relstop = mvdata->buffer + section->sh_offset + section->sh_size;
-+
-+			for (rel = rels; rel < relstop; rel++) {
-+				relcheck(rel->r_offset < section2->sh_size);
-+				relcheck(ELF_R_SYM(rel->r_info) < mvdata->nsyms);
-+			}
-+
-+			break;
-+
-+		case SHT_RELA:
-+			relas = mvdata->buffer + section->sh_offset;
-+			relastop = mvdata->buffer + section->sh_offset + section->sh_size;
-+
-+			for (rela = relas; rela < relastop; rela++) {
-+				relacheck(rela->r_offset < section2->sh_size);
-+				relacheck(ELF_R_SYM(rela->r_info) < mvdata->nsyms);
-+			}
-+
-+			break;
-+
-+		default:
-+			break;
-+		}
-+	}
-+
-+
-+	_debug("ELF okay\n");
-+	return 0;
-+
-+ elfcheck_error:
-+	printk("Verify ELF error (assertion %d)\n", line);
-+	goto format_error;
-+
-+ seccheck_error:
-+	printk("Verify ELF error [sec %ld] (assertion %d)\n",
-+	       (long)(section - mvdata->sections), line);
-+	goto format_error;
-+
-+ symcheck_error:
-+	printk("Verify ELF error [sym %ld] (assertion %d)\n",
-+	       (long)(symbol - mvdata->symbols), line);
-+	goto format_error;
-+
-+ relcheck_error:
-+	printk("Verify ELF error [sec %ld rel %ld] (assertion %d)\n",
-+	       (long)(section - mvdata->sections),
-+	       (long)(rel - rels), line);
-+	goto format_error;
-+
-+ relacheck_error:
-+	printk("Verify ELF error [sec %ld rela %ld] (assertion %d)\n",
-+	       (long)(section - mvdata->sections),
-+	       (long)(rela - relas), line);
-+	goto format_error;
-+
-+ format_error:
-+	return -ELIBBAD;
-+
-+} /* end module_verify_elf() */
-diff -urNp --exclude-from=/home/davej/.exclude linux-811/kernel/module-verify.h linux-900/kernel/module-verify.h
---- linux-811/kernel/module-verify.h
-+++ linux-900/kernel/module-verify.h
-@@ -0,0 +1,37 @@
-+/* module-verify.h: module verification definitions
-+ *
-+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
-+ * Written by David Howells (dhowells at redhat.com)
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ */
-+
-+#include <linux/types.h>
-+#include <asm/module.h>
-+
-+struct module_verify_data {
-+	struct crypto_tfm	*digest;	/* module signature digest */
-+	const void		*buffer;	/* module buffer */
-+	const Elf_Ehdr		*hdr;		/* ELF header */
-+	const Elf_Shdr		*sections;	/* ELF section table */
-+	const Elf_Sym		*symbols;	/* ELF symbol table */
-+	const char		*secstrings;	/* ELF section string table */
-+	const char		*strings;	/* ELF string table */
-+	size_t			*secsizes;	/* section size list */
-+	size_t			size;		/* module object size */
-+	size_t			nsects;		/* number of sections */
-+	size_t			nsyms;		/* number of symbols */
-+	size_t			nstrings;	/* size of strings section */
-+	size_t			signed_size;	/* count of bytes contributed to digest */
-+	int			*canonlist;	/* list of canonicalised sections */
-+	int			*canonmap;	/* section canonicalisation map */
-+	int			sig_index;	/* module signature section index */
-+	uint8_t			xcsum;		/* checksum of bytes contributed to digest */
-+	uint8_t			csum;		/* checksum of bytes representing a section */
-+};
-+
-+extern int module_verify(const Elf_Ehdr *hdr, size_t size);
-+extern int module_verify_signature(struct module_verify_data *mvdata);
-diff -urNp --exclude-from=/home/davej/.exclude linux-811/kernel/module-verify-sig.c linux-900/kernel/module-verify-sig.c
---- linux-811/kernel/module-verify-sig.c
-+++ linux-900/kernel/module-verify-sig.c
-@@ -0,0 +1,441 @@
+diff --git a/kernel/module-verify-sig.c b/kernel/module-verify-sig.c
+new file mode 100644
+index 0000000..45cb967
+--- /dev/null
++++ b/kernel/module-verify-sig.c
+@@ -0,0 +1,450 @@
 +/* module-verify-sig.c: module signature checker
 + *
 + * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
@@ -546,7 +131,7 @@
 +	size_t __n = (N);					\
 +	uint8_t *__p = (uint8_t *)(PTR);			\
 +	count_and_csum((C), __p, __n);				\
-+	crypto_digest_update_kernel((C)->digest, __p, __n);	\
++	crypto_hash_update_kernel(&(C)->hash, __p, __n);	\
 +} while(0)
 +
 +#define crypto_digest_update_val(C,VAL)				\
@@ -554,7 +139,7 @@
 +	size_t __n = sizeof(VAL);				\
 +	uint8_t *__p = (uint8_t *)&(VAL);			\
 +	count_and_csum((C), __p, __n);				\
-+	crypto_digest_update_kernel((C)->digest, __p, __n);	\
++	crypto_hash_update_kernel(&(C)->hash, __p, __n);	\
 +} while(0)
 +
 +static int module_verify_canonicalise(struct module_verify_data *mvdata);
@@ -571,7 +156,13 @@
 +
 +static int signedonly;
 +
-+/*****************************************************************************/
++static int __init sign_setup(char *str)
++{
++	signedonly = 1;
++	return 0;
++}
++__setup("enforcemodulesig", sign_setup);
++
 +/*
 + * verify a module's signature
 + */
@@ -611,13 +202,13 @@
 +	/* grab an SHA1 transformation context
 +	 * - !!! if this tries to load the sha1.ko module, we will deadlock!!!
 +	 */
-+	mvdata->digest = crypto_alloc_tfm2("sha1", 0, 1);
-+	if (!mvdata->digest) {
++	mvdata->hash.tfm = crypto_hash_cast(crypto_alloc_tfm2("sha1", 0, 1));
++	if (!mvdata->hash.tfm) {
 +		printk("Couldn't load module - SHA1 transform unavailable\n");
 +		return -EPERM;
 +	}
 +
-+	crypto_digest_init(mvdata->digest);
++	crypto_hash_init(&mvdata->hash);
 +
 +#ifdef MODSIGN_DEBUG
 +	mvdata->xcsum = 0;
@@ -698,28 +289,39 @@
 +	       mvdata->signed_size, mvdata->xcsum);
 +
 +	/* do the actual signature verification */
-+	i = ksign_verify_signature(sig, sig_size, mvdata->digest);
++	ret = ksign_verify_signature(sig, sig_size, mvdata->hash.tfm);
 +
-+	_debug("verify-sig : %d\n", i);
++	_debug("verify-sig : %d\n", ret);
 +
-+	if (i == 0)
-+		i = 1;
-+	return i;
++	switch (ret) {
++	case 0:			/* good signature */
++		ret = 1;
++		break;
++	case -EKEYREJECTED:	/* signature mismatch or number format error */
++		printk(KERN_ERR "Module signature verification failed\n");
++		break;
++	case -ENOKEY:		/* signed, but we don't have the public key */
++		printk(KERN_ERR "Module signed with unknown public key\n");
++		break;
++	default:		/* other error (probably ENOMEM) */
++		break;
++	}
 +
-+ format_error:
-+	crypto_free_tfm(mvdata->digest);
++	return ret;
++
++format_error:
++	crypto_free_hash(mvdata->hash.tfm);
++	printk(KERN_ERR "Module format error encountered\n");
 +	return -ELIBBAD;
 +
 +	/* deal with the case of an unsigned module */
-+ no_signature:
++no_signature:
 + 	if (!signedonly)
 +		return 0;
-+	printk("An attempt to load unsigned module was rejected\n");
-+	return -EPERM;
-+
-+} /* end module_verify_signature() */
++	printk(KERN_ERR "An attempt to load unsigned module was rejected\n");
++	return -EKEYREJECTED;
++}
 +
-+/*****************************************************************************/
 +/*
 + * canonicalise the section table index numbers
 + */
@@ -775,12 +377,10 @@
 +		mvdata->canonmap[mvdata->canonlist[loop]] = loop + 1;
 +
 +	return 0;
++}
 +
-+} /* end module_verify_canonicalise() */
-+
-+/*****************************************************************************/
 +/*
-+ * extract a RELA table
++ * extract an ELF RELA table
 + * - need to canonicalise the entries in case section addition/removal has
 + *   rearranged the symbol table and the section table
 + */
@@ -855,11 +455,12 @@
 +	       mvdata->signed_size, mvdata->csum, sh_name, nrels);
 +
 +	return 0;
-+} /* end extract_elf_rela() */
++}
 +
-+/*****************************************************************************/
 +/*
-+ *
++ * extract an ELF REL table
++ * - need to canonicalise the entries in case section addition/removal has
++ *   rearranged the symbol table and the section table
 + */
 +static int extract_elf_rel(struct module_verify_data *mvdata,
 +			   int secix,
@@ -929,23 +530,109 @@
 +	       mvdata->signed_size, mvdata->csum, sh_name, nrels);
 +
 +	return 0;
-+} /* end extract_elf_rel() */
-+
-+static int __init sign_setup(char *str)
-+{
-+	signedonly = 1;
-+	return 0;
 +}
-+__setup("enforcemodulesig", sign_setup);
---- linux-2.6.12/kernel/module-verify.c.~1~	2005-08-07 17:39:38.000000000 -0700
-+++ linux-2.6.12/kernel/module-verify.c	2005-08-10 00:48:43.000000000 -0700
-@@ -107,7 +107,7 @@ do { if (unlikely(!(X))) { line = __LINE
- 	elfcheck(hdr->e_shentsize == sizeof(Elf_Shdr));
- 
- 	tmp = (size_t) hdr->e_shentsize * (size_t) hdr->e_shnum;
--	elfcheck(tmp < size - hdr->e_shoff);
-+	elfcheck(tmp <= size - hdr->e_shoff);
+diff --git a/kernel/module-verify.c b/kernel/module-verify.c
+index 875279f..04920b2 100644
+--- a/kernel/module-verify.c
++++ b/kernel/module-verify.c
+@@ -16,6 +16,9 @@ #include "module-verify.h"
+ /*
+  * verify a module's integrity
+  * - check the ELF is viable
++ * - return 1 if the module has a correct signature
++ * - return 0 if the module has no signature or one we don't have a key for
++ * - return -ve on error
+  */
+ int module_verify(const Elf_Ehdr *hdr, size_t size)
+ {
+@@ -34,6 +37,8 @@ int module_verify(const Elf_Ehdr *hdr, s
+ 		goto error;
+ 	}
+ 
++	ret = module_verify_signature(&mvdata);
++
+ error:
+ 	kfree(mvdata.secsizes);
+ 	kfree(mvdata.canonlist);
+diff --git a/kernel/module-verify.h b/kernel/module-verify.h
+index 63f5e08..f4e3dc7 100644
+--- a/kernel/module-verify.h
++++ b/kernel/module-verify.h
+@@ -10,11 +10,12 @@
+  */
+ 
+ #include <linux/types.h>
++#include <linux/crypto.h>
+ #include <asm/module.h>
+ 
+ #ifdef CONFIG_MODULE_VERIFY
+ struct module_verify_data {
+-	struct crypto_tfm	*digest;	/* module signature digest */
++	struct hash_desc	hash;		/* module signature digest */
+ 	const void		*buffer;	/* module buffer */
+ 	const Elf_Ehdr		*hdr;		/* ELF header */
+ 	const Elf_Shdr		*sections;	/* ELF section table */
+@@ -48,6 +49,15 @@ #else
+ #define module_verify_elf(m) (0)
+ #endif
+ 
++/*
++ * module-verify-sig.c
++ */
++#ifdef CONFIG_MODULE_SIG
++extern int module_verify_signature(struct module_verify_data *mvdata);
++#else
++#define module_verify_signature(m) (0)
++#endif
++
+ #else
+ #define module_verify(h, s) (0)
+ #endif
+diff --git a/kernel/module.c b/kernel/module.c
+index 9d5787d..6825888 100644
+--- a/kernel/module.c
++++ b/kernel/module.c
+@@ -1567,6 +1567,7 @@ static struct module *load_module(void _
+ 	void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */
+ 	struct exception_table_entry *extable;
+ 	mm_segment_t old_fs;
++	int gpgsig_ok;
+ 
+ 	DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
+ 	       umod, len, uargs);
+@@ -1593,9 +1594,12 @@ static struct module *load_module(void _
+ 	}
+ 
+ 	/* Verify the module's contents */
++	gpgsig_ok = 0;
+ 	err = module_verify(hdr, len);
+ 	if (err < 0)
+ 		goto free_hdr;
++	if (err == 1)
++		gpgsig_ok = 1;
+ 
+ 	/* Convenience variables */
+ 	sechdrs = (void *)hdr + hdr->e_shoff;
+@@ -1632,6 +1636,7 @@ #endif
+ 		goto free_hdr;
+ 	}
+ 	mod = (void *)sechdrs[modindex].sh_addr;
++	mod->gpgsig_ok = gpgsig_ok;
+ 
+ 	if (symindex == 0) {
+ 		printk(KERN_WARNING "%s: module has no symbols (stripped?)\n",
+@@ -2325,8 +2330,13 @@ void print_modules(void)
+ 	char buf[8];
+ 
+ 	printk("Modules linked in:");
+-	list_for_each_entry(mod, &modules, list)
++	list_for_each_entry(mod, &modules, list) {
+ 		printk(" %s%s", mod->name, taint_flags(mod->taints, buf));
++#if CONFIG_MODULE_SIG      
++		if (!mod->gpgsig_ok)
++			printk("(U)");
++#endif
++	}
+ 	printk("\n");
+ }
  
- 	/* allocate a table to hold in-file section sizes */
- 	mvdata->secsizes = kmalloc(hdr->e_shnum * sizeof(size_t), GFP_KERNEL);
-

linux-2.6-modsign-crypto.patch:

Index: linux-2.6-modsign-crypto.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel-xen-2.6/F-7/linux-2.6-modsign-crypto.patch,v
retrieving revision 1.2
retrieving revision 1.2.14.1
diff -u -r1.2 -r1.2.14.1
--- linux-2.6-modsign-crypto.patch	22 Mar 2007 15:40:59 -0000	1.2
+++ linux-2.6-modsign-crypto.patch	17 Oct 2007 19:26:57 -0000	1.2.14.1
@@ -1,31 +1,78 @@
-diff -urNp --exclude-from=/home/davej/.exclude linux-900/crypto/api.c linux-901/crypto/api.c
---- linux-900/crypto/api.c
-+++ linux-901/crypto/api.c
-@@ -361,7 +361,8 @@ out:
- }
+MODSIGN: In-kernel crypto extensions
+
+From: David Howells <dhowells at redhat.com>
+
+Two extensions are added:
+
+ (1) Support for SHA1 digestion of in-kernel buffers directly without the use
+     of scatter-gather lists.
+
+ (2) Allocation of crypto algorithm instances without resort to fallback module
+     loading.
+
+SHA1 is used by module signature checking, and so must not itself require
+loading as a module when the module signature checking is enabled.
+
+Signed-Off-By: David Howells <dhowells at redhat.com>
+---
+
+ crypto/api.c           |   46 +++++++++++++++++++++++++++++++++++++++++++++-
+ crypto/digest.c        |    9 +++++++++
+ include/linux/crypto.h |   11 +++++++++++
+ 3 files changed, 65 insertions(+), 1 deletions(-)
+
+diff --git a/crypto/api.c b/crypto/api.c
+index 55af8bb..3138d7c 100644
+--- a/crypto/api.c
++++ b/crypto/api.c
+@@ -341,6 +341,45 @@ out:
  EXPORT_SYMBOL_GPL(__crypto_alloc_tfm);
  
--struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags)
+ /*
++ *	crypto_alloc_tfm2 - Find or load crypto module
++ *	@name: Name of algorithm
++ *	@flags: Flags to control algorithm instance
++ *	@nomodload: True to suppress resort to module loading
++ *
++ *	Attempt to find or load a crypto algorithm module and create an
++ *	instance of it.
++ */
 +struct crypto_tfm *crypto_alloc_tfm2(const char *name, u32 flags,
-+			int nomodload)
- {
- 	struct crypto_tfm *tfm = NULL;
- 	int err;
-@@ -369,7 +370,11 @@ struct crypto_tfm *crypto_alloc_tfm(cons
- 	do {
- 		struct crypto_alg *alg;
- 
--		alg = crypto_alg_mod_lookup(name, 0, CRYPTO_ALG_ASYNC);
++				     int nomodload)
++{
++	struct crypto_tfm *tfm = NULL;
++	int err;
++
++	do {
++		struct crypto_alg *alg;
++
 +		if (!nomodload)
 +			alg = crypto_alg_mod_lookup(name, 0, CRYPTO_ALG_ASYNC);
 +		else
 +			alg = crypto_alg_lookup(name, 0, CRYPTO_ALG_ASYNC);
 +
- 		err = PTR_ERR(alg);
- 		if (IS_ERR(alg))
- 			continue;
-@@ -443,7 +443,12 @@ err:
- 	return tfm;
++		err = PTR_ERR(alg);
++		if (IS_ERR(alg))
++			continue;
++
++		tfm = __crypto_alloc_tfm(alg, flags, 0);
++		err = 0;
++		if (IS_ERR(tfm)) {
++			crypto_mod_put(alg);
++			err = PTR_ERR(tfm);
++			tfm = NULL;
++		}
++	} while (err == -EAGAIN && !signal_pending(current));
++
++	return tfm;
++}
++
++/*
+  *	crypto_alloc_base - Locate algorithm and allocate transform
+  *	@alg_name: Name of algorithm
+  *	@type: Type of algorithm
+@@ -392,7 +431,12 @@ err:
+ 	return ERR_PTR(err);
  }
  EXPORT_SYMBOL_GPL(crypto_alloc_base);
 - 
@@ -38,48 +85,47 @@
  /*
   *	crypto_free_tfm - Free crypto transform
   *	@tfm: Transform to free
-diff -urNp --exclude-from=/home/davej/.exclude linux-900/crypto/Kconfig linux-901/crypto/Kconfig
---- linux-900/crypto/Kconfig
-+++ linux-901/crypto/Kconfig
-@@ -287,6 +287,25 @@ config CRYPTO_TEST
- 	help
- 	  Quick & dirty crypto test module.
- 
-+config CRYPTO_SIGNATURE
-+	bool "In-kernel signature checker (EXPERIMENTAL)"
-+	depends on CRYPTO
-+	help
-+	  Signature checker (used for module sig checking).
-+
-+config CRYPTO_SIGNATURE_DSA
-+	bool "Handle DSA signatures (EXPERIMENTAL)"
-+	depends on CRYPTO_SIGNATURE
-+	select CRYPTO_MPILIB
-+	help
-+	  DSA Signature checker.
-+
-+config CRYPTO_MPILIB
-+	bool "Multiprecision maths library (EXPERIMENTAL)"
-+	depends on CRYPTO
-+	help
-+	  Multiprecision maths library from GnuPG
-+
- source "drivers/crypto/Kconfig"
- endmenu
- 
-diff -urNp --exclude-from=/home/davej/.exclude linux-900/crypto/Makefile linux-901/crypto/Makefile
---- linux-900/crypto/Makefile
-+++ linux-901/crypto/Makefile
-@@ -32,3 +32,6 @@ obj-$(CONFIG_CRYPTO_MICHAEL_MIC) += mich
- obj-$(CONFIG_CRYPTO_CRC32C) += crc32c.o
+diff --git a/crypto/digest.c b/crypto/digest.c
+index 1bf7414..d03a4e1 100644
+--- a/crypto/digest.c
++++ b/crypto/digest.c
+@@ -91,6 +91,14 @@ static int update(struct hash_desc *desc,
+ 	return update2(desc, sg, nbytes);
+ }
  
- obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o
++static void update_kernel(struct hash_desc *desc,
++			  const void *data, size_t count)
++{
++	struct crypto_tfm *tfm = crypto_hash_tfm(desc->tfm);
++	tfm->__crt_alg->cra_digest.dia_update(tfm, data, count);
++	crypto_yield(desc->flags);
++}
 +
-+obj-$(CONFIG_CRYPTO_SIGNATURE) += signature/
-+obj-$(CONFIG_CRYPTO_MPILIB) += mpi/
---- linux-2.6.18.noarch/include/linux/crypto.h~	2006-10-14 18:46:26.000000000 -0400
-+++ linux-2.6.18.noarch/include/linux/crypto.h	2006-10-14 18:47:17.000000000 -0400
-@@ -368,6 +368,8 @@ struct crypto_attr_alg {
+ static int final(struct hash_desc *desc, u8 *out)
+ {
+ 	struct crypto_tfm *tfm = crypto_hash_tfm(desc->tfm);
+@@ -146,6 +154,7 @@ int crypto_init_digest_ops(struct crypto_tfm *tfm)
+ 	
+ 	ops->init	= init;
+ 	ops->update	= update;
++	ops->update_kernel = update_kernel;
+ 	ops->final	= final;
+ 	ops->digest	= digest;
+ 	ops->setkey	= dalg->dia_setkey ? setkey : nosetkey;
+diff --git a/include/linux/crypto.h b/include/linux/crypto.h
+index 779aa78..d960ec1 100644
+--- a/include/linux/crypto.h
++++ b/include/linux/crypto.h
+@@ -273,6 +273,8 @@ struct hash_tfm {
+ 	int (*init)(struct hash_desc *desc);
+ 	int (*update)(struct hash_desc *desc,
+ 		      struct scatterlist *sg, unsigned int nsg);
++	void (*update_kernel)(struct hash_desc *desc,
++			      const void *data, size_t count);
+ 	int (*final)(struct hash_desc *desc, u8 *out);
+ 	int (*digest)(struct hash_desc *desc, struct scatterlist *sg,
+ 		      unsigned int nsg, u8 *out);
+@@ -341,6 +343,8 @@ struct crypto_attr_alg {
   */
   
  struct crypto_tfm *crypto_alloc_tfm(const char *alg_name, u32 tfm_flags);
@@ -88,3 +134,17 @@
  struct crypto_tfm *crypto_alloc_base(const char *alg_name, u32 type, u32 mask);
  void crypto_free_tfm(struct crypto_tfm *tfm);
  
+@@ -739,6 +743,13 @@ static inline int crypto_hash_update(struct hash_desc *desc,
+ 	return crypto_hash_crt(desc->tfm)->update(desc, sg, nbytes);
+ }
+ 
++static inline void crypto_hash_update_kernel(struct hash_desc *desc,
++					     const void *data,
++					     size_t count)
++{
++	return crypto_hash_crt(desc->tfm)->update_kernel(desc, data, count);
++}
++
+ static inline int crypto_hash_final(struct hash_desc *desc, u8 *out)
+ {
+ 	return crypto_hash_crt(desc->tfm)->final(desc, out);

linux-2.6-modsign-include.patch:

Index: linux-2.6-modsign-include.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel-xen-2.6/F-7/linux-2.6-modsign-include.patch,v
retrieving revision 1.2
retrieving revision 1.2.14.1
diff -u -r1.2 -r1.2.14.1
--- linux-2.6-modsign-include.patch	22 Mar 2007 15:40:59 -0000	1.2
+++ linux-2.6-modsign-include.patch	17 Oct 2007 19:26:57 -0000	1.2.14.1
@@ -1,6 +1,36 @@
-diff -urNp --exclude-from=/home/davej/.exclude linux-904/include/asm-alpha/module.h linux-905/include/asm-alpha/module.h
---- linux-904/include/asm-alpha/module.h
-+++ linux-905/include/asm-alpha/module.h
+MODSIGN: Add indications of module ELF types
+
+From: David Howells <dhowells at redhat.com>
+
+Add per-arch indications of module ELF types and relocation table entry types.
+
+Signed-Off-By: David Howells <dhowells at redhat.com>
+---
+
+ include/asm-alpha/module.h   |    3 +++
+ include/asm-arm/module.h     |    5 +++++
+ include/asm-cris/module.h    |    5 +++++
+ include/asm-h8300/module.h   |    5 +++++
+ include/asm-i386/module.h    |    5 +++++
+ include/asm-ia64/module.h    |    5 +++++
+ include/asm-m32r/module.h    |    5 +++++
+ include/asm-m68k/module.h    |    5 +++++
+ include/asm-mips/module.h    |   12 ++++++++++--
+ include/asm-parisc/module.h  |    8 ++++++++
+ include/asm-powerpc/module.h |   10 ++++++++++
+ include/asm-s390/module.h    |    3 +++
+ include/asm-sh/module.h      |    5 +++++
+ include/asm-sparc/module.h   |    5 +++++
+ include/asm-sparc64/module.h |    5 +++++
+ include/asm-um/module-i386.h |    4 ++++
+ include/asm-v850/module.h    |    5 +++++
+ include/asm-x86_64/module.h  |    5 +++++
+ 18 files changed, 98 insertions(+), 2 deletions(-)
+
+diff --git a/include/asm-alpha/module.h b/include/asm-alpha/module.h
+index 7b63743..3d5a3ea 100644
+--- a/include/asm-alpha/module.h
++++ b/include/asm-alpha/module.h
 @@ -6,6 +6,7 @@ struct mod_arch_specific
  	unsigned int gotsecindex;
  };
@@ -9,7 +39,7 @@
  #define Elf_Sym Elf64_Sym
  #define Elf_Shdr Elf64_Shdr
  #define Elf_Ehdr Elf64_Ehdr
-@@ -13,6 +14,8 @@ struct mod_arch_specific
+@@ -13,6 +14,8 @@ #define Elf_Phdr Elf64_Phdr
  #define Elf_Dyn Elf64_Dyn
  #define Elf_Rel Elf64_Rel
  #define Elf_Rela Elf64_Rela
@@ -18,9 +48,10 @@
  
  #define ARCH_SHF_SMALL SHF_ALPHA_GPREL
  
-diff -urNp --exclude-from=/home/davej/.exclude linux-904/include/asm-arm/module.h linux-905/include/asm-arm/module.h
---- linux-904/include/asm-arm/module.h
-+++ linux-905/include/asm-arm/module.h
+diff --git a/include/asm-arm/module.h b/include/asm-arm/module.h
+index 24b168d..f1558f3 100644
+--- a/include/asm-arm/module.h
++++ b/include/asm-arm/module.h
 @@ -6,9 +6,14 @@ struct mod_arch_specific
  	int foo;
  };
@@ -36,10 +67,11 @@
  
  /*
   * Include the ARM architecture version.
-diff -urNp --exclude-from=/home/davej/.exclude linux-904/include/asm-cris/module.h linux-905/include/asm-cris/module.h
---- linux-904/include/asm-cris/module.h
-+++ linux-905/include/asm-cris/module.h
-@@ -3,7 +3,12 @@
+diff --git a/include/asm-cris/module.h b/include/asm-cris/module.h
+index 7ee7231..03f7b2e 100644
+--- a/include/asm-cris/module.h
++++ b/include/asm-cris/module.h
+@@ -3,7 +3,12 @@ #define _ASM_CRIS_MODULE_H
  /* cris is simple */
  struct mod_arch_specific { };
  
@@ -52,10 +84,11 @@
 +#define ELF_R_TYPE(X)	ELF32_R_TYPE(X)
 +#define ELF_R_SYM(X)	ELF32_R_SYM(X)
  #endif /* _ASM_CRIS_MODULE_H */
-diff -urNp --exclude-from=/home/davej/.exclude linux-904/include/asm-h8300/module.h linux-905/include/asm-h8300/module.h
---- linux-904/include/asm-h8300/module.h
-+++ linux-905/include/asm-h8300/module.h
-@@ -4,9 +4,14 @@
+diff --git a/include/asm-h8300/module.h b/include/asm-h8300/module.h
+index de23231..b1c08e2 100644
+--- a/include/asm-h8300/module.h
++++ b/include/asm-h8300/module.h
+@@ -4,9 +4,14 @@ #define _ASM_H8300_MODULE_H
   * This file contains the H8/300 architecture specific module code.
   */
  struct mod_arch_specific { };
@@ -70,9 +103,10 @@
  
  #define MODULE_SYMBOL_PREFIX "_"
  
-diff -urNp --exclude-from=/home/davej/.exclude linux-904/include/asm-i386/module.h linux-905/include/asm-i386/module.h
---- linux-904/include/asm-i386/module.h
-+++ linux-905/include/asm-i386/module.h
+diff --git a/include/asm-i386/module.h b/include/asm-i386/module.h
+index 02f8f54..42ab093 100644
+--- a/include/asm-i386/module.h
++++ b/include/asm-i386/module.h
 @@ -6,9 +6,14 @@ struct mod_arch_specific
  {
  };
@@ -88,9 +122,10 @@
  
  #ifdef CONFIG_M386
  #define MODULE_PROC_FAMILY "386 "
-diff -urNp --exclude-from=/home/davej/.exclude linux-904/include/asm-ia64/module.h linux-905/include/asm-ia64/module.h
---- linux-904/include/asm-ia64/module.h
-+++ linux-905/include/asm-ia64/module.h
+diff --git a/include/asm-ia64/module.h b/include/asm-ia64/module.h
+index d2da61e..191355a 100644
+--- a/include/asm-ia64/module.h
++++ b/include/asm-ia64/module.h
 @@ -23,9 +23,14 @@ struct mod_arch_specific {
  	unsigned int next_got_entry;	/* index of next available got entry */
  };
@@ -105,11 +140,12 @@
 +#define ELF_R_SYM(X)	ELF64_R_SYM(X)
  
  #define MODULE_PROC_FAMILY	"ia64"
- #define MODULE_ARCH_VERMAGIC	MODULE_PROC_FAMILY
-diff -urNp --exclude-from=/home/davej/.exclude linux-904/include/asm-m32r/module.h linux-905/include/asm-m32r/module.h
---- linux-904/include/asm-m32r/module.h
-+++ linux-905/include/asm-m32r/module.h
-@@ -5,9 +5,14 @@
+ #define MODULE_ARCH_VERMAGIC	MODULE_PROC_FAMILY \
+diff --git a/include/asm-m32r/module.h b/include/asm-m32r/module.h
+index 3f2541c..6ca963a 100644
+--- a/include/asm-m32r/module.h
++++ b/include/asm-m32r/module.h
+@@ -5,9 +5,14 @@ #define _ASM_M32R_MODULE_H
  
  struct mod_arch_specific { };
  
@@ -124,9 +160,10 @@
  
  #endif /* _ASM_M32R_MODULE_H */
  
-diff -urNp --exclude-from=/home/davej/.exclude linux-904/include/asm-m68k/module.h linux-905/include/asm-m68k/module.h
---- linux-904/include/asm-m68k/module.h
-+++ linux-905/include/asm-m68k/module.h
+diff --git a/include/asm-m68k/module.h b/include/asm-m68k/module.h
+index c6d75af..ee98908 100644
+--- a/include/asm-m68k/module.h
++++ b/include/asm-m68k/module.h
 @@ -1,7 +1,12 @@
  #ifndef _ASM_M68K_MODULE_H
  #define _ASM_M68K_MODULE_H
@@ -140,10 +177,11 @@
 +#define ELF_R_TYPE(X)	ELF32_R_TYPE(X)
 +#define ELF_R_SYM(X)	ELF32_R_SYM(X)
  #endif /* _ASM_M68K_MODULE_H */
-
---- linux-2.6.14/include/asm-mips/module.h~	2005-10-30 21:31:42.000000000 -0500
-+++ linux-2.6.14/include/asm-mips/module.h	2005-10-30 21:33:30.000000000 -0500
-@@ -34,11 +34,15 @@ typedef struct {
+diff --git a/include/asm-mips/module.h b/include/asm-mips/module.h
+index 399d03f..694f979 100644
+--- a/include/asm-mips/module.h
++++ b/include/asm-mips/module.h
+@@ -33,11 +33,15 @@ typedef struct {
  } Elf64_Mips_Rela;
  
  #ifdef CONFIG_32BIT
@@ -160,7 +198,7 @@
  
  #define Elf_Mips_Rel	Elf32_Rel
  #define Elf_Mips_Rela	Elf32_Rela
-@@ -49,11 +53,15 @@ typedef struct {
+@@ -48,11 +52,15 @@ #define ELF_MIPS_R_TYPE(rel) ELF32_R_TYP
  #endif
  
  #ifdef CONFIG_64BIT
@@ -177,13 +215,14 @@
  
  #define Elf_Mips_Rel	Elf64_Mips_Rel
  #define Elf_Mips_Rela	Elf64_Mips_Rela
-diff -urNp --exclude-from=/home/davej/.exclude linux-904/include/asm-parisc/module.h linux-905/include/asm-parisc/module.h
---- linux-904/include/asm-parisc/module.h
-+++ linux-905/include/asm-parisc/module.h
-@@ -4,17 +4,25 @@
+diff --git a/include/asm-parisc/module.h b/include/asm-parisc/module.h
+index 00f0688..ebd9a5e 100644
+--- a/include/asm-parisc/module.h
++++ b/include/asm-parisc/module.h
+@@ -4,17 +4,25 @@ #define _ASM_PARISC_MODULE_H
   * This file contains the parisc architecture specific module code.
   */
- #ifdef __LP64__
+ #ifdef CONFIG_64BIT
 +#define MODULES_ARE_ELF64
  #define Elf_Shdr Elf64_Shdr
  #define Elf_Sym Elf64_Sym
@@ -206,9 +245,11 @@
  #endif
  
  struct unwind_table;
---- linux-2.6.13/include/asm-powerpc/module.h~	2005-09-08 01:05:31.000000000 -0400
-+++ linux-2.6.13/include/asm-powerpc/module.h	2005-09-08 01:11:30.000000000 -0400
-@@ -53,16 +53,26 @@ extern struct bug_entry *module_find_bug
+diff --git a/include/asm-powerpc/module.h b/include/asm-powerpc/module.h
+index e5f14b1..f9baae1 100644
+--- a/include/asm-powerpc/module.h
++++ b/include/asm-powerpc/module.h
+@@ -52,16 +52,26 @@ #endif
   */
  
  #ifdef __powerpc64__
@@ -235,9 +276,10 @@
  #    ifdef MODULE
  	asm(".section .plt,\"ax\", at nobits; .align 3; .previous");
  	asm(".section .init.plt,\"ax\", at nobits; .align 3; .previous");
-diff -urNp --exclude-from=/home/davej/.exclude linux-904/include/asm-s390/module.h linux-905/include/asm-s390/module.h
---- linux-904/include/asm-s390/module.h
-+++ linux-905/include/asm-s390/module.h
+diff --git a/include/asm-s390/module.h b/include/asm-s390/module.h
+index 1cc1c5a..b64dab0 100644
+--- a/include/asm-s390/module.h
++++ b/include/asm-s390/module.h
 @@ -29,14 +29,17 @@ struct mod_arch_specific
  };
  
@@ -256,9 +298,10 @@
  #define Elf_Rela ElfW(Rela)
  #define Elf_Shdr ElfW(Shdr)
  #define Elf_Sym ElfW(Sym)
-diff -urNp --exclude-from=/home/davej/.exclude linux-904/include/asm-sh/module.h linux-905/include/asm-sh/module.h
---- linux-904/include/asm-sh/module.h
-+++ linux-905/include/asm-sh/module.h
+diff --git a/include/asm-sh/module.h b/include/asm-sh/module.h
+index 118d5a2..c3cf495 100644
+--- a/include/asm-sh/module.h
++++ b/include/asm-sh/module.h
 @@ -9,9 +9,14 @@ struct mod_arch_specific {
  	/* Nothing to see here .. */
  };
@@ -274,9 +317,10 @@
  
  #ifdef CONFIG_CPU_LITTLE_ENDIAN
  # ifdef CONFIG_CPU_SH2
-diff -urNp --exclude-from=/home/davej/.exclude linux-904/include/asm-sparc/module.h linux-905/include/asm-sparc/module.h
---- linux-904/include/asm-sparc/module.h
-+++ linux-905/include/asm-sparc/module.h
+diff --git a/include/asm-sparc/module.h b/include/asm-sparc/module.h
+index cbd9e67..e2921e2 100644
+--- a/include/asm-sparc/module.h
++++ b/include/asm-sparc/module.h
 @@ -1,7 +1,12 @@
  #ifndef _ASM_SPARC_MODULE_H
  #define _ASM_SPARC_MODULE_H
@@ -290,9 +334,10 @@
 +#define ELF_R_TYPE(X)	ELF32_R_TYPE(X)
 +#define ELF_R_SYM(X)	ELF32_R_SYM(X)
  #endif /* _ASM_SPARC_MODULE_H */
-diff -urNp --exclude-from=/home/davej/.exclude linux-904/include/asm-sparc64/module.h linux-905/include/asm-sparc64/module.h
---- linux-904/include/asm-sparc64/module.h
-+++ linux-905/include/asm-sparc64/module.h
+diff --git a/include/asm-sparc64/module.h b/include/asm-sparc64/module.h
+index 3d77ba4..2e7ca17 100644
+--- a/include/asm-sparc64/module.h
++++ b/include/asm-sparc64/module.h
 @@ -1,7 +1,12 @@
  #ifndef _ASM_SPARC64_MODULE_H
  #define _ASM_SPARC64_MODULE_H
@@ -306,9 +351,10 @@
 +#define ELF_R_TYPE(X)	ELF64_R_TYPE(X)
 +#define ELF_R_SYM(X)	ELF64_R_SYM(X)
  #endif /* _ASM_SPARC64_MODULE_H */
-diff -urNp --exclude-from=/home/davej/.exclude linux-904/include/asm-um/module-i386.h linux-905/include/asm-um/module-i386.h
---- linux-904/include/asm-um/module-i386.h
-+++ linux-905/include/asm-um/module-i386.h
+diff --git a/include/asm-um/module-i386.h b/include/asm-um/module-i386.h
+index 5ead4a0..b441057 100644
+--- a/include/asm-um/module-i386.h
++++ b/include/asm-um/module-i386.h
 @@ -9,5 +9,9 @@ struct mod_arch_specific
  #define Elf_Shdr Elf32_Shdr
  #define Elf_Sym Elf32_Sym
@@ -319,9 +365,10 @@
 +#define ELF_R_SYM(X)	ELF32_R_SYM(X)
  
  #endif
-diff -urNp --exclude-from=/home/davej/.exclude linux-904/include/asm-v850/module.h linux-905/include/asm-v850/module.h
---- linux-904/include/asm-v850/module.h
-+++ linux-905/include/asm-v850/module.h
+diff --git a/include/asm-v850/module.h b/include/asm-v850/module.h
+index 2c2f494..48752f3 100644
+--- a/include/asm-v850/module.h
++++ b/include/asm-v850/module.h
 @@ -31,9 +31,14 @@ struct mod_arch_specific
  	unsigned int core_plt_section, init_plt_section;
  };
@@ -337,10 +384,11 @@
  
  /* Make empty sections for module_frob_arch_sections to expand. */
  #ifdef MODULE
-diff -urNp --exclude-from=/home/davej/.exclude linux-904/include/asm-x86_64/module.h linux-905/include/asm-x86_64/module.h
---- linux-904/include/asm-x86_64/module.h
-+++ linux-905/include/asm-x86_64/module.h
-@@ -3,8 +3,13 @@
+diff --git a/include/asm-x86_64/module.h b/include/asm-x86_64/module.h
+index 67f8f69..3a7373a 100644
+--- a/include/asm-x86_64/module.h
++++ b/include/asm-x86_64/module.h
+@@ -3,8 +3,13 @@ #define _ASM_X8664_MODULE_H
  
  struct mod_arch_specific {}; 
  

linux-2.6-modsign-ksign.patch:

Index: linux-2.6-modsign-ksign.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel-xen-2.6/F-7/linux-2.6-modsign-ksign.patch,v
retrieving revision 1.2
retrieving revision 1.2.14.1
diff -u -r1.2 -r1.2.14.1
--- linux-2.6-modsign-ksign.patch	22 Mar 2007 15:40:59 -0000	1.2
+++ linux-2.6-modsign-ksign.patch	17 Oct 2007 19:26:57 -0000	1.2.14.1
@@ -1,31 +1,81 @@
---- linux-2.6.18.noarch/crypto/digest.c~	2006-10-14 18:53:16.000000000 -0400
-+++ linux-2.6.18.noarch/crypto/digest.c	2006-10-14 18:54:08.000000000 -0400
-@@ -45,6 +45,13 @@ void crypto_digest_update(struct crypto_
- }
- EXPORT_SYMBOL_GPL(crypto_digest_update);
+MODSIGN: Module signature checker and key manager
+
+From: David Howells <dhowells at redhat.com>
+
+Add a facility to retain public keys and to verify signatures made with those
+public keys, given a signature and crypto_hash of the data that was signed.
+
+Signed-Off-By: David Howells <dhowells at redhat.com>
+---
+
+ crypto/Kconfig                     |   13 +
+ crypto/Makefile                    |    1 
+ crypto/signature/Makefile          |   10 +
+ crypto/signature/dsa.c             |   96 ++++++
+ crypto/signature/key.h             |    7 
+ crypto/signature/ksign-keyring.c   |  116 +++++++
+ crypto/signature/ksign-parse.c     |  603 ++++++++++++++++++++++++++++++++++++
+ crypto/signature/ksign-publickey.c |   18 +
+ crypto/signature/ksign.c           |  180 +++++++++++
+ crypto/signature/local.h           |  160 ++++++++++
+ include/linux/crypto/ksign.h       |   22 +
+ 11 files changed, 1226 insertions(+), 0 deletions(-)
+
+diff --git a/crypto/Kconfig b/crypto/Kconfig
+index d768c46..205cbdf 100644
+--- a/crypto/Kconfig
++++ b/crypto/Kconfig
+@@ -471,6 +471,19 @@ config CRYPTO_MPILIB
+ 	help
+ 	  Multiprecision maths library from GnuPG
  
-+static void crypto_update_kernel(struct crypto_tfm *tfm,
-+             const void *data, size_t count)
-+{
-+   tfm->__crt_alg->cra_digest.dia_update(tfm, data, count);
-+   crypto_yield(tfm);
-+}
++config CRYPTO_SIGNATURE
++	bool "In-kernel signature checker (EXPERIMENTAL)"
++	depends on CRYPTO
++	help
++	  Signature checker (used for module sig checking).
++
++config CRYPTO_SIGNATURE_DSA
++	bool "Handle DSA signatures (EXPERIMENTAL)"
++	depends on CRYPTO_SIGNATURE
++	select CRYPTO_MPILIB
++	help
++	  DSA Signature checker.
++
+ source "drivers/crypto/Kconfig"
+ 
+ endif	# if CRYPTO
+diff --git a/crypto/Makefile b/crypto/Makefile
+index 36a6211..309a806 100644
+--- a/crypto/Makefile
++++ b/crypto/Makefile
+@@ -47,3 +47,4 @@ obj-$(CONFIG_CRYPTO_CRC32C) += crc32c.o
+ obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o
+ 
+ obj-$(CONFIG_CRYPTO_MPILIB) += mpi/
++obj-$(CONFIG_CRYPTO_SIGNATURE) += signature/
+diff --git a/crypto/signature/Makefile b/crypto/signature/Makefile
+new file mode 100644
+index 0000000..4d1042e
+--- /dev/null
++++ b/crypto/signature/Makefile
+@@ -0,0 +1,10 @@
++#
++# Makefile for the signature checker
++#
 +
- void crypto_digest_final(struct crypto_tfm *tfm, u8 *out)
- {
- 	struct crypto_hash *hash = crypto_hash_cast(tfm);
-@@ -186,6 +193,7 @@ int crypto_init_digest_ops(struct crypto
- 	
- 	ops->init	= init;
- 	ops->update	= update;
-+	ops->dit_update_kernel = crypto_update_kernel;
- 	ops->final	= final;
- 	ops->digest	= digest;
- 	ops->setkey	= dalg->dia_setkey ? setkey : nosetkey;
-diff -urNp --exclude-from=/home/davej/.exclude linux-901/crypto/signature/dsa.c linux-902/crypto/signature/dsa.c
---- linux-901/crypto/signature/dsa.c
-+++ linux-902/crypto/signature/dsa.c
-@@ -0,0 +1,98 @@
++obj-y := \
++	ksign.o \
++	ksign-parse.o \
++	ksign-keyring.o \
++	ksign-publickey.o \
++	dsa.o
+diff --git a/crypto/signature/dsa.c b/crypto/signature/dsa.c
+new file mode 100644
+index 0000000..469539c
+--- /dev/null
++++ b/crypto/signature/dsa.c
+@@ -0,0 +1,96 @@
 +/* dsa.c  -  DSA signature algorithm
 + *	Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
 + *
@@ -51,7 +101,6 @@
 +#include <asm/errno.h>
 +#include "local.h"
 +
-+/*****************************************************************************/
 +/*
 + * perform DSA algorithm signature verification
 + */
@@ -65,8 +114,7 @@
 +
 +	if (!datahash ||
 +	    !sig[0] || !sig[1] ||
-+	    !pkey[0] || !pkey[1] || !pkey[2] || !pkey[3]
-+	    )
++	    !pkey[0] || !pkey[1] || !pkey[2] || !pkey[3])
 +		return -EINVAL;
 +
 +	p = pkey[0];	/* prime */
@@ -78,12 +126,12 @@
 +
 +	if (!(mpi_cmp_ui(r, 0) > 0 && mpi_cmp(r, q) < 0)) {
 +		printk("DSA_verify assertion failed [0 < r < q]\n");
-+		return -EPERM;
++		return -EKEYREJECTED;
 +	}
 +
 +	if (!(mpi_cmp_ui(s, 0) > 0 && mpi_cmp(s, q) < 0)) {
 +		printk("DSA_verify assertion failed [0 < s < q]\n");
-+		return -EPERM;
++		return -EKEYREJECTED;
 +	}
 +
 +	rc = -ENOMEM;
@@ -115,18 +163,20 @@
 +	if (mpi_fdiv_r(v, v, q) < 0)
 +		goto cleanup;
 +
-+	rc = mpi_cmp(v, r) == 0 ? 0 : -EPERM;
++	rc = (mpi_cmp(v, r) == 0) ? 0 : -EKEYREJECTED;
 +
-+ cleanup:
++cleanup:
 +	mpi_free(w);
 +	mpi_free(u1);
 +	mpi_free(u2);
 +	mpi_free(v);
 +	return rc;
-+} /* end DSA_verify() */
-diff -urNp --exclude-from=/home/davej/.exclude linux-901/crypto/signature/key.h linux-902/crypto/signature/key.h
---- linux-901/crypto/signature/key.h
-+++ linux-902/crypto/signature/key.h
++}
+diff --git a/crypto/signature/key.h b/crypto/signature/key.h
+new file mode 100644
+index 0000000..7297968
+--- /dev/null
++++ b/crypto/signature/key.h
 @@ -0,0 +1,7 @@
 +const int ksign_def_public_key_size = 0;
 +/* automatically generated by bin2hex */
@@ -135,193 +185,12 @@
 +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00
 +};
 +
-diff -urNp --exclude-from=/home/davej/.exclude linux-901/crypto/signature/ksign.c linux-902/crypto/signature/ksign.c
---- linux-901/crypto/signature/ksign.c
-+++ linux-902/crypto/signature/ksign.c
-@@ -0,0 +1,179 @@
-+/* ksign.c: signature checker
-+ *
-+ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
-+ * Written by David Howells (dhowells at redhat.com)
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ */
-+
-+#include <linux/kernel.h>
-+#include <asm/errno.h>
-+#include "local.h"
-+
-+#if 0
-+#define _debug(FMT, ...) printk(KERN_DEBUG FMT, ##__VA_ARGS__)
-+#else
-+#define _debug(FMT, ...) do { ; } while (0)
-+#endif
-+
-+/*****************************************************************************/
-+/*
-+ * check the signature which is contained in SIG.
-+ */
-+static int ksign_signature_check(const struct ksign_signature *sig,
-+				 struct crypto_tfm *sha1_tfm)
-+{
-+	struct ksign_public_key *pk;
-+	uint8_t sha1[SHA1_DIGEST_SIZE];
-+	MPI result = NULL;
-+	int rc = 0;
-+
-+	pk = ksign_get_public_key(sig->keyid);
-+	if (!pk) {
-+		printk("ksign: module signed with unknown public key\n");
-+		printk("- signature keyid: %08x%08x ver=%u\n",
-+		       sig->keyid[0], sig->keyid[1], sig->version);
-+		return -EPERM;
-+	}
-+
-+	if (pk->timestamp > sig->timestamp)
-+		printk("ksign:"
-+		       " public key is %lu seconds newer than the signature\n",
-+		       pk->timestamp - sig->timestamp);
-+
-+	/* complete the digest */
-+	if (sig->version >= 4)
-+		SHA1_putc(sha1_tfm, sig->version);
-+	SHA1_putc(sha1_tfm, sig->sig_class);
-+
-+	if (sig->version < 4) {
-+		u32 a = sig->timestamp;
-+		SHA1_putc(sha1_tfm, (a >> 24) & 0xff);
-+		SHA1_putc(sha1_tfm, (a >> 16) & 0xff);
-+		SHA1_putc(sha1_tfm, (a >>  8) & 0xff);
-+		SHA1_putc(sha1_tfm, (a >>  0) & 0xff);
-+	}
-+	else {
-+		uint8_t buf[6];
-+		size_t n;
-+		SHA1_putc(sha1_tfm, PUBKEY_ALGO_DSA);
-+		SHA1_putc(sha1_tfm, DIGEST_ALGO_SHA1);
-+		if (sig->hashed_data) {
-+			n = (sig->hashed_data[0] << 8) | sig->hashed_data[1];
-+			SHA1_write(sha1_tfm, sig->hashed_data, n + 2);
-+			n += 6;
-+		}
-+		else {
-+			n = 6;
-+		}
-+
-+		/* add some magic */
-+		buf[0] = sig->version;
-+		buf[1] = 0xff;
-+		buf[2] = n >> 24;
-+		buf[3] = n >> 16;
-+		buf[4] = n >>  8;
-+		buf[5] = n;
-+		SHA1_write(sha1_tfm, buf, 6);
-+	}
-+
-+	crypto_digest_final(sha1_tfm, sha1);
-+	crypto_free_tfm(sha1_tfm);
-+
-+
-+
-+
-+
-+
-+	rc = -ENOMEM;
-+	result = mpi_alloc((SHA1_DIGEST_SIZE + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB);
-+	if (!result)
-+		goto cleanup;
-+
-+	rc = mpi_set_buffer(result, sha1, SHA1_DIGEST_SIZE, 0);
-+	if (rc < 0)
-+		goto cleanup;
-+
-+	rc = DSA_verify(result, sig->data, pk->pkey);
-+
-+ cleanup:
-+	mpi_free(result);
-+	ksign_put_public_key(pk);
-+
-+	return rc;
-+} /* end ksign_signature_check() */
-+
-+/*****************************************************************************/
-+/*
-+ * examine the signatures that are parsed out of the signature data - we keep
-+ * the first one that's appropriate and ignore the rest
-+ * - return 0 if signature of interest (sig not freed by caller)
-+ * - return 1 if no interest (caller frees)
-+ */
-+static int ksign_grab_signature(struct ksign_signature *sig, void *fnxdata)
-+{
-+	struct ksign_signature **_sig = fnxdata;
-+
-+	if (sig->sig_class != 0x00) {
-+		_debug("ksign: standalone signature of class 0x%02x\n",
-+		       sig->sig_class);
-+		return 1;
-+	}
-+
-+	if (*_sig)
-+		return 1;
-+
-+	*_sig = sig;
-+	return 0;
-+} /* end ksign_grab_signature() */
-+
-+/*****************************************************************************/
-+/*
-+ * verify the signature of some data with one of the kernel's known public keys
-+ * - the SHA1 context should be currently open with the signed data digested
-+ *   into it so that more data can be appended
-+ * - the SHA1 context is finalised and freed before returning
-+ */
-+int ksign_verify_signature(const char *sigdata, unsigned sig_size,
-+			   struct crypto_tfm *sha1)
-+{
-+	struct ksign_signature *sig = NULL;
-+	int retval;
-+
-+	/* parse the signature data to get the actual signature */
-+	retval = ksign_parse_packets(sigdata, sig_size,
-+				     &ksign_grab_signature, NULL, NULL,
-+				     &sig);
-+	if (retval < 0)
-+		goto cleanup;
-+
-+	if (!sig) {
-+		printk("Couldn't find valid DSA signature in module\n");
-+		return -ENOENT;
-+	}
-+
-+	_debug("signature keyid: %08x%08x ver=%u\n",
-+	       sig->keyid[0], sig->keyid[1], sig->version);
-+
-+	/* check the data SHA1 transformation against the public key */
-+	retval = ksign_signature_check(sig, sha1);
-+	if (retval == 0) {
-+		_debug("ksign: Signature check succeeded\n");
-+	}
-+	else if (retval != -ENOMEM) {
-+		_debug("ksign: Signature check failed\n");
-+		retval = -EPERM;
-+	}
-+	else {
-+		_debug("ksign: Signature check ENOMEM\n");
-+	}
-+
-+ cleanup:
-+	if (sig)
-+		ksign_free_signature(sig);
-+
-+	return retval;
-+} /* end ksign_verify_signature() */
-diff -urNp --exclude-from=/home/davej/.exclude linux-901/crypto/signature/ksign-keyring.c linux-902/crypto/signature/ksign-keyring.c
---- linux-901/crypto/signature/ksign-keyring.c
-+++ linux-902/crypto/signature/ksign-keyring.c
-@@ -0,0 +1,112 @@
+diff --git a/crypto/signature/ksign-keyring.c b/crypto/signature/ksign-keyring.c
+new file mode 100644
+index 0000000..a839261
+--- /dev/null
++++ b/crypto/signature/ksign-keyring.c
+@@ -0,0 +1,116 @@
 +/* ksign-keyring.c: public key cache
 + *
 + * Copyright (C) 2001 Red Hat, Inc. All Rights Reserved.
@@ -350,6 +219,9 @@
 +static LIST_HEAD(keyring);
 +static DECLARE_RWSEM(keyring_sem);
 +
++/*
++ * handle a public key element parsed from the keyring blob
++ */
 +static int add_keyblock_key(struct ksign_public_key *pk, void *data)
 +{
 +	printk("- Added public key %X%X\n", pk->keyid[0], pk->keyid[1]);
@@ -370,15 +242,17 @@
 +	return 0;
 +}
 +
++/*
++ * handle a user ID element parsed from the keyring blob
++ */
 +static int add_keyblock_uid(struct ksign_user_id *uid, void *data)
 +{
 +	printk("- User ID: %s\n", uid->name);
 +	return 1;
 +}
 +
-+/*****************************************************************************/
 +/*
-+ *
++ * add the keys from a ASN.1 encoded blob into the keyring
 + */
 +int ksign_load_keyring_from_buffer(const void *buffer, size_t size)
 +{
@@ -390,11 +264,10 @@
 +			       add_keyblock_key,
 +			       add_keyblock_uid,
 +			       NULL);
-+} /* end ksign_load_keyring_from_buffer() */
++}
 +
-+/*****************************************************************************/
 +/*
-+ *
++ * find a public key by ID
 + */
 +struct ksign_public_key *ksign_get_public_key(const uint32_t *keyid)
 +{
@@ -409,15 +282,15 @@
 +		}
 +	}
 +
-+ found:
-+	up_read(&keyring_sem);
++	pk = NULL;
 +
++found:
++	up_read(&keyring_sem);
 +	return pk;
-+} /* end ksign_get_public_key() */
++}
 +
-+/*****************************************************************************/
 +/*
-+ * clear the public key keyring
++ * clear the public-key keyring
 + */
 +void ksign_clear_keyring(void)
 +{
@@ -433,12 +306,14 @@
 +	}
 +
 +	up_write(&keyring_sem);
-+} /* end ksign_clear_keyring() */
-diff -urNp --exclude-from=/home/davej/.exclude linux-901/crypto/signature/ksign-parse.c linux-902/crypto/signature/ksign-parse.c
---- linux-901/crypto/signature/ksign-parse.c
-+++ linux-902/crypto/signature/ksign-parse.c
-@@ -0,0 +1,609 @@
-+/* parse-packet.c  - read packets
++}
+diff --git a/crypto/signature/ksign-parse.c b/crypto/signature/ksign-parse.c
+new file mode 100644
+index 0000000..96e2ff5
+--- /dev/null
++++ b/crypto/signature/ksign-parse.c
+@@ -0,0 +1,603 @@
++/* parse packet data
 + * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
 + *
 + * This file is part of GnuPG.
@@ -495,14 +370,13 @@
 +{
 +	int i;
 +
-+	if (!sig)
-+		return;
-+
-+	for (i = 0; i < DSA_NSIG; i++)
-+		mpi_free(sig->data[i]);
-+	kfree(sig->hashed_data);
-+	kfree(sig->unhashed_data);
-+	kfree(sig);
++	if (sig) {
++		for (i = 0; i < DSA_NSIG; i++)
++			mpi_free(sig->data[i]);
++		kfree(sig->hashed_data);
++		kfree(sig->unhashed_data);
++		kfree(sig);
++	}
 +}
 +
 +void ksign_free_public_key(struct ksign_public_key *pk)
@@ -518,15 +392,13 @@
 +
 +void ksign_free_user_id(struct ksign_user_id *uid)
 +{
-+	if (uid)
-+		kfree(uid);
++	kfree(uid);
 +}
 +
-+/*****************************************************************************/
 +/*
 + *
 + */
-+static void ksign_calc_pk_keyid(struct crypto_tfm *sha1,
++static void ksign_calc_pk_keyid(struct hash_desc *sha1,
 +				struct ksign_public_key *pk)
 +{
 +	unsigned n;
@@ -537,7 +409,7 @@
 +	int i;
 +	int npkey = DSA_NPKEY;
 +
-+	crypto_digest_init(sha1);
++	crypto_hash_init(sha1);
 +
 +	n = pk->version < 4 ? 8 : 6;
 +	for (i = 0; i < npkey; i++) {
@@ -550,7 +422,7 @@
 +	SHA1_putc(sha1, n >> 8);   /* 2 uint8_t length header */
 +	SHA1_putc(sha1, n);
 +
-+	if( pk->version < 4)
++	if (pk->version < 4)
 +		SHA1_putc(sha1, 3);
 +	else
 +		SHA1_putc(sha1, 4);
@@ -565,7 +437,8 @@
 +		uint16_t a16;
 +
 +		if( pk->expiredate )
-+			a16 = (uint16_t) ((pk->expiredate - pk->timestamp) / 86400L);
++			a16 = (uint16_t)
++				((pk->expiredate - pk->timestamp) / 86400L);
 +		else
 +			a16 = 0;
 +		SHA1_putc(sha1, a16 >> 8);
@@ -580,10 +453,8 @@
 +		SHA1_write(sha1, pp[i], nn[i]);
 +		kfree(pp[i]);
 +	}
++}
 +
-+} /* end ksign_calc_pk_keyid() */
-+
-+/*****************************************************************************/
 +/*
 + * parse a user ID embedded in a signature
 + */
@@ -614,9 +485,8 @@
 +
 +	ksign_free_user_id(uid);
 +	return rc;
-+} /* end ksign_parse_user_id() */
++}
 +
-+/*****************************************************************************/
 +/*
 + * extract a public key embedded in a signature
 + */
@@ -625,9 +495,9 @@
 +			   ksign_public_key_actor_t pkfnx, void *fnxdata)
 +{
 +	struct ksign_public_key *pk;
-+	struct crypto_tfm *sha1_tfm;
++	struct hash_desc sha1;
 +	unsigned long timestamp, expiredate;
-+	uint8_t sha1[SHA1_DIGEST_SIZE];
++	uint8_t hash[SHA1_DIGEST_SIZE];
 +	int i, version;
 +	int is_v4 = 0;
 +	int rc = 0;
@@ -651,9 +521,9 @@
 +	}
 +
 +	timestamp = read_32(&datap);
-+	if (is_v4)
++	if (is_v4) {
 +		expiredate = 0; /* have to get it from the selfsignature */
-+	else {
++	} else {
 +		unsigned short ndays;
 +		ndays = read_16(&datap);
 +		if (ndays)
@@ -669,11 +539,10 @@
 +	}
 +
 +	/* extract the stuff from the DSA public key */
-+	pk = kmalloc(sizeof(struct ksign_public_key), GFP_KERNEL);
++	pk = kzalloc(sizeof(struct ksign_public_key), GFP_KERNEL);
 +	if (!pk)
 +		return -ENOMEM;
 +
-+	memset(pk, 0, sizeof(struct ksign_public_key));
 +	atomic_set(&pk->count, 1);
 +	pk->timestamp	= timestamp;
 +	pk->expiredate	= expiredate;
@@ -688,29 +557,29 @@
 +
 +	rc = -ENOMEM;
 +
-+	sha1_tfm = crypto_alloc_tfm2("sha1", 0, 1);
-+	if (!sha1_tfm)
++	sha1.tfm = crypto_hash_cast(crypto_alloc_tfm2("sha1", 0, 1));
++	if (!sha1.tfm)
 +		goto cleanup;
++	sha1.flags = 0;
 +
-+	ksign_calc_pk_keyid(sha1_tfm, pk);
-+	crypto_digest_final(sha1_tfm, sha1);
-+	crypto_free_tfm(sha1_tfm);
++	ksign_calc_pk_keyid(&sha1, pk);
++	crypto_hash_final(&sha1, hash);
++	crypto_free_hash(sha1.tfm);
 +
-+	pk->keyid[0] = sha1[12] << 24 | sha1[13] << 16 | sha1[14] << 8 | sha1[15];
-+	pk->keyid[1] = sha1[16] << 24 | sha1[17] << 16 | sha1[18] << 8 | sha1[19];
++	pk->keyid[0] = hash[12] << 24 | hash[13] << 16 | hash[14] << 8 | hash[15];
++	pk->keyid[1] = hash[16] << 24 | hash[17] << 16 | hash[18] << 8 | hash[19];
 +
 +	rc = 0;
 +	if (pkfnx)
 +		rc = pkfnx(pk, fnxdata);
 +
-+ cleanup:
++cleanup:
 +	ksign_put_public_key(pk);
 +	return rc;
-+} /* end ksign_parse_key() */
++}
 +
-+/*****************************************************************************/
 +/*
-+ *
++ * find an element representing the issuer
 + */
 +static const uint8_t *ksign_find_sig_issuer(const uint8_t *buffer)
 +{
@@ -730,8 +599,7 @@
 +				goto too_short;
 +			n = read_32(&buffer);
 +			buflen -= 4;
-+		}
-+		else if (n >= 192) {
++		} else if (n >= 192) {
 +			if(buflen < 2)
 +				goto too_short;
 +			n = ((n - 192) << 8) + *buffer + 192;
@@ -743,9 +611,10 @@
 +			goto too_short;
 +
 +		type = *buffer & 0x7f;
-+		if (!(++seq > 0))
++		if (!(++seq > 0)) {
 +			;
-+		else if (type == SIGSUBPKT_ISSUER) { /* found */
++		} else if (type == SIGSUBPKT_ISSUER) {
++			/* found */
 +			buffer++;
 +			n--;
 +			if (n > buflen || n < 8)
@@ -757,11 +626,10 @@
 +		buflen -= n;
 +	}
 +
-+ too_short:
++too_short:
 +	return NULL; /* end of subpackets; not found */
-+} /* end ksign_find_sig_issuer() */
++}
 +
-+/*****************************************************************************/
 +/*
 + * extract signature data embedded in a signature
 + */
@@ -787,16 +655,16 @@
 +	case 2:
 +		break;
 +	default:
-+		printk("ksign: signature packet with unknown version %d\n", version);
++		printk("ksign: signature packet with unknown version %d\n",
++		       version);
 +		return 0;
 +	}
 +
 +	/* store information */
-+	sig = kmalloc(sizeof(*sig), GFP_KERNEL);
++	sig = kzalloc(sizeof(*sig), GFP_KERNEL);
 +	if (!sig)
 +		return -ENOMEM;
 +
-+	memset(sig, 0, sizeof(*sig));
 +	sig->version = version;
 +
 +	if (!is_v4)
@@ -820,15 +688,18 @@
 +	}
 +
 +	rc = -EBADMSG;
-+	if (is_v4) { /* read subpackets */
++	if (is_v4) {
++		/* read subpackets */
 +		n = read_16(&datap); /* length of hashed data */
 +		if (n > 10000) {
-+			printk("ksign: signature packet: hashed data too long\n");
++			printk("ksign: signature packet:"
++			       " hashed data too long\n");
 +			goto leave;
 +		}
 +		if (n) {
 +			if ((size_t)(endp - datap) < n) {
-+				printk("ksign: signature packet: available data too short\n");
++				printk("ksign: signature packet:"
++				       " available data too short\n");
 +				goto leave;
 +			}
 +			sig->hashed_data = kmalloc(n + 2, GFP_KERNEL);
@@ -844,12 +715,14 @@
 +
 +		n = read_16(&datap); /* length of unhashed data */
 +		if (n > 10000) {
-+			printk("ksign: signature packet: unhashed data too long\n");
++			printk("ksign: signature packet:"
++			       " unhashed data too long\n");
 +			goto leave;
 +		}
 +		if (n) {
 +			if ((size_t) (endp - datap) < n) {
-+				printk("ksign: signature packet: available data too short\n");
++				printk("ksign: signature packet:"
++				       " available data too short\n");
 +				goto leave;
 +			}
 +			sig->unhashed_data = kmalloc(n + 2, GFP_KERNEL);
@@ -878,9 +751,9 @@
 +		p = ksign_find_sig_issuer(sig->hashed_data);
 +		if (!p)
 +			p = ksign_find_sig_issuer(sig->unhashed_data);
-+		if (!p)
++		if (!p) {
 +			printk("ksign: signature packet without issuer\n");
-+		else {
++		} else {
 +			sig->keyid[0] = buffer_to_u32(p);
 +			sig->keyid[1] = buffer_to_u32(p + 4);
 +		}
@@ -901,12 +774,11 @@
 +			rc = 0;
 +	}
 +
-+ leave:
++leave:
 +	ksign_free_signature(sig);
 +	return rc;
-+} /* end ksign_parse_signature() */
++}
 +
-+/*****************************************************************************/
 +/*
 + * parse the next packet and call appropriate handler function for known types
 + * - returns:
@@ -954,8 +826,7 @@
 +
 +		if (c < 192) {
 +			pktlen = c;
-+		}
-+		else if (c < 224) {
++		} else if (c < 224) {
 +			pktlen = (c - 192) * 256;
 +			if (*datap >= endp) {
 +				printk("ksign: 2nd length uint8_t missing\n");
@@ -964,28 +835,24 @@
 +			c = *(*datap)++;
 +			hdr[hdrlen++] = c;
 +			pktlen += c + 192;
-+		}
-+		else if (c == 255) {
++		} else if (c == 255) {
 +			if (*datap + 3 >= endp) {
 +				printk("ksign: 4 uint8_t length invalid\n");
 +				goto leave;
 +			}
-+			pktlen  = (hdr[hdrlen++] = *(*datap)++ << 24	);
-+			pktlen |= (hdr[hdrlen++] = *(*datap)++ << 16	);
-+			pktlen |= (hdr[hdrlen++] = *(*datap)++ <<  8	);
-+			pktlen |= (hdr[hdrlen++] = *(*datap)++ <<  0	);
-+		}
-+		else {
++			pktlen  = (hdr[hdrlen++] = *(*datap)++ << 24);
++			pktlen |= (hdr[hdrlen++] = *(*datap)++ << 16);
++			pktlen |= (hdr[hdrlen++] = *(*datap)++ <<  8);
++			pktlen |= (hdr[hdrlen++] = *(*datap)++ <<  0);
++		} else {
 +			pktlen = 0;/* to indicate partial length */
 +		}
-+	}
-+	else {
++	} else {
 +		pkttype = (ctb >> 2) & 0xf;
 +		lenuint8_ts = ((ctb & 3) == 3) ? 0 : (1 << (ctb & 3));
 +		if( !lenuint8_ts ) {
 +			pktlen = 0; /* don't know the value */
-+		}
-+		else {
++		} else {
 +			if (*datap + lenuint8_ts > endp) {
 +				printk("ksign: length uint8_ts missing\n");
 +				goto leave;
@@ -1005,13 +872,16 @@
 +	/* deal with the next packet appropriately */
 +	switch (pkttype) {
 +	case PKT_PUBLIC_KEY:
-+		rc = ksign_parse_key(*datap, *datap + pktlen, hdr, hdrlen, pkfnx, data);
++		rc = ksign_parse_key(*datap, *datap + pktlen, hdr, hdrlen,
++				     pkfnx, data);
 +		break;
 +	case PKT_SIGNATURE:
-+		rc = ksign_parse_signature(*datap, *datap + pktlen, sigfnx, data);
++		rc = ksign_parse_signature(*datap, *datap + pktlen,
++					   sigfnx, data);
 +		break;
 +	case PKT_USER_ID:
-+		rc = ksign_parse_user_id(*datap, *datap + pktlen, uidfnx, data);
++		rc = ksign_parse_user_id(*datap, *datap + pktlen,
++					 uidfnx, data);
 +		break;
 +	default:
 +		rc = 0; /* unknown packet */
@@ -1019,11 +889,10 @@
 +	}
 +
 +	*datap += pktlen;
-+ leave:
++leave:
 +	return rc;
-+} /* end ksign_parse_one_packet() */
++}
 +
-+/*****************************************************************************/
 +/*
 + * parse the contents of a packet buffer, passing the signature, public key and
 + * user ID to the caller's callback functions
@@ -1046,13 +915,14 @@
 +	} while (rc == 0 && datap < endp);
 +
 +	return rc;
-+} /* end ksign_parse_packets() */
-diff -urNp --exclude-from=/home/davej/.exclude linux-901/crypto/signature/ksign-publickey.c linux-902/crypto/signature/ksign-publickey.c
---- linux-901/crypto/signature/ksign-publickey.c
-+++ linux-902/crypto/signature/ksign-publickey.c
-@@ -0,0 +1,19 @@
++}
+diff --git a/crypto/signature/ksign-publickey.c b/crypto/signature/ksign-publickey.c
+new file mode 100644
+index 0000000..832a419
+--- /dev/null
++++ b/crypto/signature/ksign-publickey.c
+@@ -0,0 +1,18 @@
 +#include "local.h"
-+
 +#include "key.h"
 +
 +static int __init ksign_init(void)
@@ -1070,10 +940,198 @@
 +}
 +
 +module_init(ksign_init)
-diff -urNp --exclude-from=/home/davej/.exclude linux-901/crypto/signature/local.h linux-902/crypto/signature/local.h
---- linux-901/crypto/signature/local.h
-+++ linux-902/crypto/signature/local.h
-@@ -0,0 +1,163 @@
+diff --git a/crypto/signature/ksign.c b/crypto/signature/ksign.c
+new file mode 100644
+index 0000000..b62eb38
+--- /dev/null
++++ b/crypto/signature/ksign.c
+@@ -0,0 +1,180 @@
++/* ksign.c: signature checker
++ *
++ * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
++ * Written by David Howells (dhowells at redhat.com)
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version
++ * 2 of the License, or (at your option) any later version.
++ */
++
++#include <linux/kernel.h>
++#include <asm/errno.h>
++#include "local.h"
++
++#if 0
++#define _debug(FMT, ...) printk(KERN_DEBUG FMT, ##__VA_ARGS__)
++#else
++#define _debug(FMT, ...) do { ; } while (0)
++#endif
++
++/*
++ * check the signature which is contained in SIG.
++ */
++static int ksign_signature_check(const struct ksign_signature *sig,
++				 struct crypto_hash *sha1_tfm)
++{
++	struct ksign_public_key *pk;
++	struct hash_desc sha1_d;
++	uint8_t sha1[SHA1_DIGEST_SIZE];
++	MPI result = NULL;
++	int rc = 0;
++
++	pk = ksign_get_public_key(sig->keyid);
++	if (!pk) {
++		printk("ksign: module signed with unknown public key\n");
++		printk("- signature keyid: %08x%08x ver=%u\n",
++		       sig->keyid[0], sig->keyid[1], sig->version);
++		return -ENOKEY;
++	}
++
++	if (pk->timestamp > sig->timestamp)
++		printk("ksign:"
++		       " public key is %lu seconds newer than the signature\n",
++		       pk->timestamp - sig->timestamp);
++
++	sha1_d.tfm = sha1_tfm;
++	sha1_d.flags = 0;
++
++	/* complete the digest */
++	if (sig->version >= 4)
++		SHA1_putc(&sha1_d, sig->version);
++	SHA1_putc(&sha1_d, sig->sig_class);
++
++	if (sig->version < 4) {
++		u32 a = sig->timestamp;
++		SHA1_putc(&sha1_d, (a >> 24) & 0xff);
++		SHA1_putc(&sha1_d, (a >> 16) & 0xff);
++		SHA1_putc(&sha1_d, (a >>  8) & 0xff);
++		SHA1_putc(&sha1_d, (a >>  0) & 0xff);
++	}
++	else {
++		uint8_t buf[6];
++		size_t n;
++		SHA1_putc(&sha1_d, PUBKEY_ALGO_DSA);
++		SHA1_putc(&sha1_d, DIGEST_ALGO_SHA1);
++		if (sig->hashed_data) {
++			n = (sig->hashed_data[0] << 8) | sig->hashed_data[1];
++			SHA1_write(&sha1_d, sig->hashed_data, n + 2);
++			n += 6;
++		}
++		else {
++			n = 6;
++		}
++
++		/* add some magic */
++		buf[0] = sig->version;
++		buf[1] = 0xff;
++		buf[2] = n >> 24;
++		buf[3] = n >> 16;
++		buf[4] = n >>  8;
++		buf[5] = n;
++		SHA1_write(&sha1_d, buf, 6);
++	}
++
++	crypto_hash_final(&sha1_d, sha1);
++	crypto_free_hash(sha1_tfm);
++
++	rc = -ENOMEM;
++	result = mpi_alloc((SHA1_DIGEST_SIZE + BYTES_PER_MPI_LIMB - 1) /
++			   BYTES_PER_MPI_LIMB);
++	if (!result)
++		goto cleanup;
++
++	rc = mpi_set_buffer(result, sha1, SHA1_DIGEST_SIZE, 0);
++	if (rc < 0)
++		goto cleanup;
++
++	rc = DSA_verify(result, sig->data, pk->pkey);
++
++ cleanup:
++	mpi_free(result);
++	ksign_put_public_key(pk);
++
++	return rc;
++}
++
++/*
++ * examine the signatures that are parsed out of the signature data - we keep
++ * the first one that's appropriate and ignore the rest
++ * - return 0 if signature of interest (sig not freed by caller)
++ * - return 1 if no interest (caller frees)
++ */
++static int ksign_grab_signature(struct ksign_signature *sig, void *fnxdata)
++{
++	struct ksign_signature **_sig = fnxdata;
++
++	if (sig->sig_class != 0x00) {
++		_debug("ksign: standalone signature of class 0x%02x\n",
++		       sig->sig_class);
++		return 1;
++	}
++
++	if (*_sig)
++		return 1;
++
++	*_sig = sig;
++	return 0;
++}
++
++/*
++ * verify the signature of some data with one of the kernel's known public keys
++ * - the SHA1 context should be currently open with the signed data digested
++ *   into it so that more data can be appended
++ * - the SHA1 context is finalised and freed before returning
++ */
++int ksign_verify_signature(const char *sigdata, unsigned sig_size,
++			   struct crypto_hash *sha1)
++{
++	struct ksign_signature *sig = NULL;
++	int retval;
++
++	/* parse the signature data to get the actual signature */
++	retval = ksign_parse_packets(sigdata, sig_size,
++				     &ksign_grab_signature, NULL, NULL,
++				     &sig);
++	if (retval < 0)
++		goto cleanup;
++
++	if (!sig) {
++		printk(KERN_NOTICE
++		       "Couldn't find valid DSA signature in module\n");
++		return -ENOENT;
++	}
++
++	_debug("signature keyid: %08x%08x ver=%u\n",
++	       sig->keyid[0], sig->keyid[1], sig->version);
++
++	/* check the data SHA1 transformation against the public key */
++	retval = ksign_signature_check(sig, sha1);
++	switch (retval) {
++	case 0:
++		_debug("ksign: Signature check succeeded\n");
++		break;
++	case -ENOMEM:
++		_debug("ksign: Signature check ENOMEM\n");
++		break;
++	default:
++		_debug("ksign: Signature check failed\n");
++		if (retval != -ENOKEY)
++			retval = -EKEYREJECTED;
++		break;
++	}
++
++ cleanup:
++	if (sig)
++		ksign_free_signature(sig);
++
++	return retval;
++}
+diff --git a/crypto/signature/local.h b/crypto/signature/local.h
+new file mode 100644
+index 0000000..aa18cc4
+--- /dev/null
++++ b/crypto/signature/local.h
+@@ -0,0 +1,160 @@
 +/* local.h: kernel signature checker internal defs
 + *
 + * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
@@ -1152,8 +1210,7 @@
 +/*
 + * signature record
 + */
-+struct ksign_signature
-+{
++struct ksign_signature {
 +	uint32_t	keyid[2];		/* 64 bit keyid */
 +	time_t		timestamp;		/* signature made */
 +	uint8_t		version;
@@ -1169,8 +1226,7 @@
 +/*
 + * public key record
 + */
-+struct ksign_public_key
-+{
++struct ksign_public_key {
 +	struct list_head link;
 +	atomic_t	count;			/* ref count */
 +	time_t		timestamp;		/* key made */
@@ -1199,8 +1255,7 @@
 +/*
 + * user ID record
 + */
-+struct ksign_user_id
-+{
++struct ksign_user_id {
 +	int		len;			/* length of the name */
 +	char		name[0];
 +};
@@ -1228,32 +1283,20 @@
 + * - we _know_ the data is locked into kernel memory, so we don't want to have
 + *   to kmap() it
 + */
-+static inline void SHA1_putc(struct crypto_tfm *sha1, uint8_t ch)
++static inline void SHA1_putc(struct hash_desc *sha1, uint8_t ch)
 +{
-+	crypto_digest_update_kernel(sha1, &ch, 1);
++	crypto_hash_update_kernel(sha1, &ch, 1);
 +}
 +
-+static inline void SHA1_write(struct crypto_tfm *sha1, const void *s, size_t n)
++static inline void SHA1_write(struct hash_desc *sha1, const void *s, size_t n)
 +{
-+	crypto_digest_update_kernel(sha1, s, n);
++	crypto_hash_update_kernel(sha1, s, n);
 +}
-diff -urNp --exclude-from=/home/davej/.exclude linux-901/crypto/signature/Makefile linux-902/crypto/signature/Makefile
---- linux-901/crypto/signature/Makefile
-+++ linux-902/crypto/signature/Makefile
-@@ -0,0 +1,10 @@
-+#
-+# Makefile for the signature checker
-+#
-+
-+obj-y := \
-+	ksign.o \
-+	ksign-parse.o \
-+	ksign-keyring.o \
-+	ksign-publickey.o \
-+	dsa.o
-diff -urNp --exclude-from=/home/davej/.exclude linux-901/include/linux/crypto/ksign.h linux-902/include/linux/crypto/ksign.h
---- linux-901/include/linux/crypto/ksign.h
-+++ linux-902/include/linux/crypto/ksign.h
+diff --git a/include/linux/crypto/ksign.h b/include/linux/crypto/ksign.h
+new file mode 100644
+index 0000000..27c9e4a
+--- /dev/null
++++ b/include/linux/crypto/ksign.h
 @@ -0,0 +1,22 @@
 +/* ksign.h: in-kernel signature checker
 + *
@@ -1273,43 +1316,7 @@
 +
 +#ifdef CONFIG_CRYPTO_SIGNATURE
 +extern int ksign_verify_signature(const char *sig, unsigned sig_size,
-+				  struct crypto_tfm *sha1);
++				  struct crypto_hash *sha1);
 +#endif
 +
 +#endif /* _LINUX_CRYPTO_KSIGN_H */
---- linux-2.6.18.noarch/include/linux/crypto.h~	2006-10-14 18:55:16.000000000 -0400
-+++ linux-2.6.18.noarch/include/linux/crypto.h	2006-10-14 18:56:59.000000000 -0400
-@@ -305,6 +305,8 @@ struct hash_tfm {
- 	int (*init)(struct hash_desc *desc);
- 	int (*update)(struct hash_desc *desc,
- 		      struct scatterlist *sg, unsigned int nsg);
-+	void (*dit_update_kernel)(struct crypto_tfm *tfm,
-+		      const void *data, size_t count);
- 	int (*final)(struct hash_desc *desc, u8 *out);
- 	int (*digest)(struct hash_desc *desc, struct scatterlist *sg,
- 		      unsigned int nsg, u8 *out);
-@@ -713,6 +715,13 @@ void crypto_digest_init(struct crypto_tf
- void crypto_digest_update(struct crypto_tfm *tfm,
- 			  struct scatterlist *sg, unsigned int nsg)
- 	__deprecated_for_modules;
-+static inline void crypto_digest_update_kernel(struct crypto_tfm *tfm,
-+                          const void *data,
-+                          size_t count)
-+{
-+	BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
-+	tfm->crt_digest.dit_update_kernel(tfm, data, count);
-+}
- void crypto_digest_final(struct crypto_tfm *tfm, u8 *out)
- 	__deprecated_for_modules;
- void crypto_digest_digest(struct crypto_tfm *tfm,
---- linux-2.6.14/crypto/signature/ksign-keyring.c~	2005-11-22 14:11:25.000000000 -0500
-+++ linux-2.6.14/crypto/signature/ksign-keyring.c	2005-11-22 14:11:38.000000000 -0500
-@@ -85,6 +85,8 @@ struct ksign_public_key *ksign_get_publi
- 		}
- 	}
- 
-+	pk = NULL;
-+
-  found:
- 	up_read(&keyring_sem);
- 

linux-2.6-modsign-mpilib.patch:

View full diff with command:
/usr/bin/cvs -f diff  -kk -u -N -r 1.2 -r 1.2.14.1 linux-2.6-modsign-mpilib.patch
Index: linux-2.6-modsign-mpilib.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel-xen-2.6/F-7/linux-2.6-modsign-mpilib.patch,v
retrieving revision 1.2
retrieving revision 1.2.14.1
diff -u -r1.2 -r1.2.14.1
--- linux-2.6-modsign-mpilib.patch	22 Mar 2007 15:40:59 -0000	1.2
+++ linux-2.6-modsign-mpilib.patch	17 Oct 2007 19:26:57 -0000	1.2.14.1
@@ -1,6 +1,119 @@
-diff -urNp --exclude-from=/home/davej/.exclude linux-902/crypto/mpi/generic_mpi-asm-defs.h linux-903/crypto/mpi/generic_mpi-asm-defs.h
---- linux-902/crypto/mpi/generic_mpi-asm-defs.h
-+++ linux-903/crypto/mpi/generic_mpi-asm-defs.h
+MODSIGN: Multiprecision maths library
+
+From: David Howells <dhowells at redhat.com>
+
+Add a multiprecision maths library (MPILIB) required for doing cryptographic
+operations based on very large prime numbers.
+
+This is derived from GPG, reduced to the minimum necessary bits for doing DSA
+signature verification with error handling added.  This is used to do kernel
+module signing.
+
+Signed-Off-By: David Howells <dhowells at redhat.com>
+---
+
+ crypto/Kconfig                    |    6 
+ crypto/Makefile                   |    2 
+ crypto/mpi/Makefile               |   30 +
+ crypto/mpi/generic_mpi-asm-defs.h |   10 
+ crypto/mpi/generic_mpih-add1.c    |   62 ++
+ crypto/mpi/generic_mpih-lshift.c  |   66 ++
+ crypto/mpi/generic_mpih-mul1.c    |   58 +
+ crypto/mpi/generic_mpih-mul2.c    |   63 ++
+ crypto/mpi/generic_mpih-mul3.c    |   64 ++
+ crypto/mpi/generic_mpih-rshift.c  |   65 ++
+ crypto/mpi/generic_mpih-sub1.c    |   62 ++
+ crypto/mpi/generic_udiv-w-sdiv.c  |  130 +++
+ crypto/mpi/longlong.h             | 1502 +++++++++++++++++++++++++++++++++++++
+ crypto/mpi/mpi-add.c              |  258 ++++++
+ crypto/mpi/mpi-bit.c              |  245 ++++++
+ crypto/mpi/mpi-cmp.c              |   71 ++
+ crypto/mpi/mpi-div.c              |  345 ++++++++
+ crypto/mpi/mpi-gcd.c              |   60 +
+ crypto/mpi/mpi-inline.c           |   33 +
+ crypto/mpi/mpi-inline.h           |  128 +++
+ crypto/mpi/mpi-internal.h         |  265 +++++++
+ crypto/mpi/mpi-inv.c              |  148 ++++
+ crypto/mpi/mpi-mpow.c             |  113 +++
+ crypto/mpi/mpi-mul.c              |  202 +++++
+ crypto/mpi/mpi-pow.c              |  312 ++++++++
+ crypto/mpi/mpi-scan.c             |  129 +++
+ crypto/mpi/mpicoder.c             |  359 +++++++++
+ crypto/mpi/mpih-cmp.c             |   58 +
+ crypto/mpi/mpih-div.c             |  534 +++++++++++++
+ crypto/mpi/mpih-mul.c             |  546 +++++++++++++
+ crypto/mpi/mpiutil.c              |  213 +++++
+ include/linux/crypto/mpi.h        |  147 ++++
+ 32 files changed, 6286 insertions(+), 0 deletions(-)
+
+diff --git a/crypto/Kconfig b/crypto/Kconfig
+index 92ba249..d768c46 100644
+--- a/crypto/Kconfig
++++ b/crypto/Kconfig
+@@ -465,6 +465,12 @@ config CRYPTO_TEST
+ 	help
+ 	  Quick & dirty crypto test module.
+ 
++config CRYPTO_MPILIB
++	bool "Multiprecision maths library (EXPERIMENTAL)"
++	depends on CRYPTO
++	help
++	  Multiprecision maths library from GnuPG
++
+ source "drivers/crypto/Kconfig"
+ 
+ endif	# if CRYPTO
+diff --git a/crypto/Makefile b/crypto/Makefile
+index 60e3d24..36a6211 100644
+--- a/crypto/Makefile
++++ b/crypto/Makefile
+@@ -45,3 +45,5 @@ obj-$(CONFIG_CRYPTO_MICHAEL_MIC) += mich
+ obj-$(CONFIG_CRYPTO_CRC32C) += crc32c.o
+ 
+ obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o
++
++obj-$(CONFIG_CRYPTO_MPILIB) += mpi/
+diff --git a/crypto/mpi/Makefile b/crypto/mpi/Makefile
+new file mode 100644
+index 0000000..e96597d
+--- /dev/null
++++ b/crypto/mpi/Makefile
+@@ -0,0 +1,30 @@
++#
++# MPI multiprecision maths library (from gpg) 
++#
++
++obj-$(CONFIG_CRYPTO_MPILIB) = \
++	generic_mpih-lshift.o		\
++	generic_mpih-mul1.o		\
++	generic_mpih-mul2.o		\
++	generic_mpih-mul3.o		\
++	generic_mpih-rshift.o		\
++	generic_mpih-sub1.o		\
++	generic_mpih-add1.o		\
++	generic_udiv-w-sdiv.o		\
++	mpicoder.o			\
++	mpi-add.o			\
++	mpi-bit.o			\
++	mpi-div.o			\
++	mpi-cmp.o			\
++	mpi-gcd.o			\
++	mpih-cmp.o			\
++	mpih-div.o			\
++	mpih-mul.o			\
++	mpi-inline.o			\
++	mpi-inv.o			\
++	mpi-mpow.o			\
++	mpi-mul.o			\
++	mpi-pow.o			\
++	mpi-scan.o			\
++	mpiutil.o
++
+diff --git a/crypto/mpi/generic_mpi-asm-defs.h b/crypto/mpi/generic_mpi-asm-defs.h
+new file mode 100644
+index 0000000..13424e2
+--- /dev/null
++++ b/crypto/mpi/generic_mpi-asm-defs.h
 @@ -0,0 +1,10 @@
 +/* This file defines some basic constants for the MPI machinery.  We
 + * need to define the types on a per-CPU basis, so it is done with
@@ -12,9 +125,11 @@
 +
 +
 +
-diff -urNp --exclude-from=/home/davej/.exclude linux-902/crypto/mpi/generic_mpih-add1.c linux-903/crypto/mpi/generic_mpih-add1.c
---- linux-902/crypto/mpi/generic_mpih-add1.c
-+++ linux-903/crypto/mpi/generic_mpih-add1.c
+diff --git a/crypto/mpi/generic_mpih-add1.c b/crypto/mpi/generic_mpih-add1.c
+new file mode 100644
+index 0000000..891fef0
+--- /dev/null
++++ b/crypto/mpi/generic_mpih-add1.c
 @@ -0,0 +1,62 @@
 +/* mpihelp-add_1.c  -  MPI helper functions
 + * Copyright (C) 1994, 1996, 1997, 1998, 
@@ -78,9 +193,11 @@
 +    return cy;
 +}
 +
-diff -urNp --exclude-from=/home/davej/.exclude linux-902/crypto/mpi/generic_mpih-lshift.c linux-903/crypto/mpi/generic_mpih-lshift.c
---- linux-902/crypto/mpi/generic_mpih-lshift.c
-+++ linux-903/crypto/mpi/generic_mpih-lshift.c
+diff --git a/crypto/mpi/generic_mpih-lshift.c b/crypto/mpi/generic_mpih-lshift.c
+new file mode 100644
+index 0000000..9e159b5
+--- /dev/null
++++ b/crypto/mpi/generic_mpih-lshift.c
 @@ -0,0 +1,66 @@
 +/* mpihelp-lshift.c  -	MPI helper functions
 + * Copyright (C) 1994, 1996, 1998, 2001 Free Software Foundation, Inc.
@@ -148,9 +265,11 @@
 +}
 +
 +
-diff -urNp --exclude-from=/home/davej/.exclude linux-902/crypto/mpi/generic_mpih-mul1.c linux-903/crypto/mpi/generic_mpih-mul1.c
---- linux-902/crypto/mpi/generic_mpih-mul1.c
-+++ linux-903/crypto/mpi/generic_mpih-mul1.c
+diff --git a/crypto/mpi/generic_mpih-mul1.c b/crypto/mpi/generic_mpih-mul1.c
+new file mode 100644
+index 0000000..4e34d46
+--- /dev/null
++++ b/crypto/mpi/generic_mpih-mul1.c
 @@ -0,0 +1,58 @@
 +/* mpihelp-mul_1.c  -  MPI helper functions
 + * Copyright (C) 1994, 1996, 1997, 1998, 2001 Free Software Foundation, Inc.
@@ -210,9 +329,11 @@
 +    return cy_limb;
 +}
 +
-diff -urNp --exclude-from=/home/davej/.exclude linux-902/crypto/mpi/generic_mpih-mul2.c linux-903/crypto/mpi/generic_mpih-mul2.c
---- linux-902/crypto/mpi/generic_mpih-mul2.c
-+++ linux-903/crypto/mpi/generic_mpih-mul2.c
+diff --git a/crypto/mpi/generic_mpih-mul2.c b/crypto/mpi/generic_mpih-mul2.c
+new file mode 100644
+index 0000000..c1f41f3
+--- /dev/null
++++ b/crypto/mpi/generic_mpih-mul2.c
 @@ -0,0 +1,63 @@
 +/* mpihelp-mul_2.c  -  MPI helper functions
 + * Copyright (C) 1994, 1996, 1997, 1998, 2001 Free Software Foundation, Inc.
@@ -277,9 +398,11 @@
 +}
 +
 +
-diff -urNp --exclude-from=/home/davej/.exclude linux-902/crypto/mpi/generic_mpih-mul3.c linux-903/crypto/mpi/generic_mpih-mul3.c
---- linux-902/crypto/mpi/generic_mpih-mul3.c
-+++ linux-903/crypto/mpi/generic_mpih-mul3.c
+diff --git a/crypto/mpi/generic_mpih-mul3.c b/crypto/mpi/generic_mpih-mul3.c
+new file mode 100644
[...5398 lines suppressed...]
 + */
 +
-+#include "mpi-internal.h"
-+#include "longlong.h"
-+
-+/****************
-+ * Scan through an mpi and return byte for byte. a -1 is returned to indicate
-+ * the end of the mpi. Scanning is done from the lsb to the msb, returned
-+ * values are in the range of 0 .. 255.
-+ *
-+ * FIXME: This code is VERY ugly!
-+ */
 +int
-+mpi_getbyte( const MPI a, unsigned idx )
++mpihelp_mul( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t usize,
++	     mpi_ptr_t vp, mpi_size_t vsize,
++	     mpi_limb_t *_result)
 +{
-+    int i, j;
-+    unsigned n;
-+    mpi_ptr_t ap;
-+    mpi_limb_t limb;
-+
-+    ap = a->d;
-+    for(n=0,i=0; i < a->nlimbs; i++ ) {
-+	limb = ap[i];
-+	for( j=0; j < BYTES_PER_MPI_LIMB; j++, n++ )
-+	    if( n == idx )
-+		return (limb >> j*8) & 0xff;
-+    }
-+    return -1;
-+}
-+
++    mpi_ptr_t prod_endp = prodp + usize + vsize - 1;
++    mpi_limb_t cy;
++    struct karatsuba_ctx ctx;
 +
-+/****************
-+ * Put a value at position IDX into A. idx counts from lsb to msb
-+ */
-+void
-+mpi_putbyte( MPI a, unsigned idx, int xc )
-+{
-+    int i, j;
-+    unsigned n;
-+    mpi_ptr_t ap;
-+    mpi_limb_t limb, c;
++    if( vsize < KARATSUBA_THRESHOLD ) {
++	mpi_size_t i;
++	mpi_limb_t v_limb;
 +
-+    c = xc & 0xff;
-+    ap = a->d;
-+    for(n=0,i=0; i < a->alloced; i++ ) {
-+	limb = ap[i];
-+	for( j=0; j < BYTES_PER_MPI_LIMB; j++, n++ )
-+	    if( n == idx ) {
-+	      #if BYTES_PER_MPI_LIMB == 4
-+		if( j == 0 )
-+		    limb = (limb & 0xffffff00) | c;
-+		else if( j == 1 )
-+		    limb = (limb & 0xffff00ff) | (c<<8);
-+		else if( j == 2 )
-+		    limb = (limb & 0xff00ffff) | (c<<16);
-+		else
-+		    limb = (limb & 0x00ffffff) | (c<<24);
-+	      #elif BYTES_PER_MPI_LIMB == 8
-+		if( j == 0 )
-+		    limb = (limb & 0xffffffffffffff00) | c;
-+		else if( j == 1 )
-+		    limb = (limb & 0xffffffffffff00ff) | (c<<8);
-+		else if( j == 2 )
-+		    limb = (limb & 0xffffffffff00ffff) | (c<<16);
-+		else if( j == 3 )
-+		    limb = (limb & 0xffffffff00ffffff) | (c<<24);
-+		else if( j == 4 )
-+		    limb = (limb & 0xffffff00ffffffff) | (c<<32);
-+		else if( j == 5 )
-+		    limb = (limb & 0xffff00ffffffffff) | (c<<40);
-+		else if( j == 6 )
-+		    limb = (limb & 0xff00ffffffffffff) | (c<<48);
-+		else
-+		    limb = (limb & 0x00ffffffffffffff) | (c<<56);
-+	      #else
-+		 #error please enhance this function, its ugly - i know.
-+	      #endif
-+		if( a->nlimbs <= i )
-+		    a->nlimbs = i+1;
-+		ap[i] = limb;
-+		return;
-+	    }
-+    }
-+    log_bug("index out of range\n");
-+}
++	if( !vsize ) {
++		*_result = 0;
++		return 0;
++	}
 +
++	/* Multiply by the first limb in V separately, as the result can be
++	 * stored (not added) to PROD.	We also avoid a loop for zeroing.  */
++	v_limb = vp[0];
++	if( v_limb <= 1 ) {
++	    if( v_limb == 1 )
++		MPN_COPY( prodp, up, usize );
++	    else
++		MPN_ZERO( prodp, usize );
++	    cy = 0;
++	}
++	else
++	    cy = mpihelp_mul_1( prodp, up, usize, v_limb );
 +
-+/****************
-+ * Count the number of zerobits at the low end of A
-+ */
-+unsigned
-+mpi_trailing_zeros( const MPI a )
-+{
-+    unsigned n, count = 0;
++	prodp[usize] = cy;
++	prodp++;
 +
-+    for(n=0; n < a->nlimbs; n++ ) {
-+	if( a->d[n] ) {
-+	    unsigned nn;
-+	    mpi_limb_t alimb = a->d[n];
++	/* For each iteration in the outer loop, multiply one limb from
++	 * U with one limb from V, and add it to PROD.	*/
++	for( i = 1; i < vsize; i++ ) {
++	    v_limb = vp[i];
++	    if( v_limb <= 1 ) {
++		cy = 0;
++		if( v_limb == 1 )
++		   cy = mpihelp_add_n(prodp, prodp, up, usize);
++	    }
++	    else
++		cy = mpihelp_addmul_1(prodp, up, usize, v_limb);
 +
-+	    count_trailing_zeros( nn, alimb );
-+	    count += nn;
-+	    break;
++	    prodp[usize] = cy;
++	    prodp++;
 +	}
-+	count += BITS_PER_MPI_LIMB;
++
++	*_result = cy;
++	return 0;
 +    }
-+    return count;
 +
++    memset( &ctx, 0, sizeof ctx );
++    if (mpihelp_mul_karatsuba_case( prodp, up, usize, vp, vsize, &ctx ) < 0)
++	    return -ENOMEM;
++    mpihelp_release_karatsuba_ctx( &ctx );
++    *_result = *prod_endp;
++    return 0;
 +}
 +
 +
-diff -urNp --exclude-from=/home/davej/.exclude linux-902/crypto/mpi/mpiutil.c linux-903/crypto/mpi/mpiutil.c
---- linux-902/crypto/mpi/mpiutil.c
-+++ linux-903/crypto/mpi/mpiutil.c
-@@ -0,0 +1,214 @@
+diff --git a/crypto/mpi/mpiutil.c b/crypto/mpi/mpiutil.c
+new file mode 100644
+index 0000000..26157e9
+--- /dev/null
++++ b/crypto/mpi/mpiutil.c
+@@ -0,0 +1,213 @@
 +/* mpiutil.ac  -  Utility functions for MPI
 + * Copyright (C) 1998, 1999 Free Software Foundation, Inc.
 + *
@@ -6132,10 +6264,9 @@
 +		kfree(a->d);
 +		a->d = p;
 +	} else {
-+		a->d = kmalloc( nlimbs * sizeof(mpi_limb_t), GFP_KERNEL);
++		a->d = kzalloc( nlimbs * sizeof(mpi_limb_t), GFP_KERNEL);
 +		if (!a->d)
 +			return -ENOMEM;
-+		memset(a->d, 0, nlimbs * sizeof(mpi_limb_t) );
 +	}
 +	a->alloced = nlimbs;
 +	return 0;
@@ -6247,9 +6378,11 @@
 +	tmp = *a; *a = *b; *b = tmp;
 +}
 +
-diff -urNp --exclude-from=/home/davej/.exclude linux-902/include/linux/crypto/mpi.h linux-903/include/linux/crypto/mpi.h
---- linux-902/include/linux/crypto/mpi.h
-+++ linux-903/include/linux/crypto/mpi.h
+diff --git a/include/linux/crypto/mpi.h b/include/linux/crypto/mpi.h
+new file mode 100644
+index 0000000..4de3ba0
+--- /dev/null
++++ b/include/linux/crypto/mpi.h
 @@ -0,0 +1,147 @@
 +/* mpi.h  -  Multi Precision Integers
 + *	Copyright (C) 1994, 1996, 1998, 1999,

linux-2.6-modsign-script.patch:

Index: linux-2.6-modsign-script.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel-xen-2.6/F-7/linux-2.6-modsign-script.patch,v
retrieving revision 1.2
retrieving revision 1.2.14.1
diff -u -r1.2 -r1.2.14.1
--- linux-2.6-modsign-script.patch	22 Mar 2007 15:40:59 -0000	1.2
+++ linux-2.6-modsign-script.patch	17 Oct 2007 19:26:57 -0000	1.2.14.1
@@ -1,6 +1,36 @@
-diff -urNp --exclude-from=/home/davej/.exclude linux-903/scripts/modsign/Makefile linux-904/scripts/modsign/Makefile
---- linux-903/scripts/modsign/Makefile
-+++ linux-904/scripts/modsign/Makefile
+MODSIGN: Stuff for signing modules
+
+From: David Howells <dhowells at redhat.com>
+
+Add scripts and programs for signing module files (.ko files).
+
+With the kernel key files (kernel.sec and kernel.pub) in the parent directory
+of the kernel source file, any particular module can be signed by doing:
+
+	sh scripts/modsign/modsign.sh <module>
+
+For example, the RxRPC module can be signed:
+
+	sh scripts/modsign/modsign.sh net/rxrpc/rxrpc.ko
+
+This will leave a file called <module>.signed (eg: net/rxrpc/rxrpc.ko.signed)
+that is the signed module binary.  This file can then be stripped if desired to
+remove debugging information without invalidating the signature.  It would be
+loaded with insmod as normal.
+
+Signed-Off-By: David Howells <dhowells at redhat.com>
+---
+
+ scripts/modsign/Makefile      |   27 +
+ scripts/modsign/mod-extract.c |  890 +++++++++++++++++++++++++++++++++++++++++
+ scripts/modsign/modsign.sh    |   58 +++
+ 3 files changed, 975 insertions(+), 0 deletions(-)
+
+diff --git a/scripts/modsign/Makefile b/scripts/modsign/Makefile
+new file mode 100644
+index 0000000..9cf4fd9
+--- /dev/null
++++ b/scripts/modsign/Makefile
 @@ -0,0 +1,27 @@
 +# Set the following to `true' to make a debuggable build.
 +# Leave this set to `false' for production use.
@@ -14,7 +44,7 @@
 +
 +CC = gcc
 +
-+INCLUDES = 
++INCLUDES =
 +CFLAGS = -g -O -Wall
 +
 +OBJS =	mod-extract.o
@@ -29,10 +59,12 @@
 +
 +clean:
 +	-rm $(OBJS) $(ROOT)
-diff -urNp --exclude-from=/home/davej/.exclude linux-903/scripts/modsign/mod-extract.c linux-904/scripts/modsign/mod-extract.c
---- linux-903/scripts/modsign/mod-extract.c
-+++ linux-904/scripts/modsign/mod-extract.c
-@@ -0,0 +1,900 @@
+diff --git a/scripts/modsign/mod-extract.c b/scripts/modsign/mod-extract.c
+new file mode 100644
+index 0000000..b7b5dd1
+--- /dev/null
++++ b/scripts/modsign/mod-extract.c
+@@ -0,0 +1,890 @@
 +/* mod-extract.c: module extractor for signing
 + *
 + * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
@@ -141,7 +173,6 @@
 +	exit(2);
 +}
 +
-+/*****************************************************************************/
 +/*
 + *
 + */
@@ -230,10 +261,8 @@
 +	}
 +
 +	return 0;
++}
 +
-+} /* end main() */
-+
-+/*****************************************************************************/
 +/*
 + * extract a RELA table
 + * - need to canonicalise the entries in case section addition/removal has
@@ -301,10 +330,8 @@
 +	}
 +
 +	verbose("%02x %4d %s [canon]\n", csum, secix, sh_name);
++}
 +
-+} /* end extract_elf64_rela() */
-+
-+/*****************************************************************************/
 +/*
 + * extract a REL table
 + * - need to canonicalise the entries in case section addition/removal has
@@ -370,10 +397,8 @@
 +	}
 +
 +	verbose("%02x %4d %s [canon]\n", csum, secix, sh_name);
++}
 +
-+} /* end extract_elf64_rel() */
-+
-+/*****************************************************************************/
 +/*
 + * extract the data from a 64-bit module
 + */
@@ -403,6 +428,8 @@
 +
 +	symbols = NULL;
 +	strings = NULL;
++	nstrings = 0;
++	nsyms = 0;
 +
 +	for (loop = 1; loop < shnum; loop++) {
 +		const char *sh_name = secstrings + get32(&sections[loop].sh_name);
@@ -578,10 +605,8 @@
 +
 +	verbose("%08lx         (%lu bytes csum 0x%02x)\n",
 +		ftell(outfd), ftell(outfd), xcsum);
++}
 +
-+} /* end extract_elf64() */
-+
-+/*****************************************************************************/
 +/*
 + * extract a RELA table
 + * - need to canonicalise the entries in case section addition/removal has
@@ -649,10 +674,8 @@
 +	}
 +
 +	verbose("%02x %4d %s [canon]\n", csum, secix, sh_name);
++}
 +
-+} /* end extract_elf32_rela() */
-+
-+/*****************************************************************************/
 +/*
 + * extract a REL table
 + * - need to canonicalise the entries in case section addition/removal has
@@ -707,7 +730,7 @@
 +		/* canonicalise the section used by the symbol */
 +		if (st_shndx > SHN_UNDEF && st_shndx < nsects)
 +			set16(&relocation.st_shndx, canonmap[st_shndx]);
-+		
++
 +		write_out_val(relocation);
 +
 +		/* undefined symbols must be named if referenced */
@@ -718,10 +741,8 @@
 +	}
 +
 +	verbose("%02x %4d %s [canon]\n", csum, secix, sh_name);
++}
 +
-+} /* end extract_elf32_rel() */
-+
-+/*****************************************************************************/
 +/*
 + * extract the data from a 32-bit module
 + */
@@ -751,6 +772,8 @@
 +
 +	symbols = NULL;
 +	strings = NULL;
++	nstrings = 0;
++	nsyms = 0;
 +
 +	for (loop = 1; loop < shnum; loop++) {
 +		const char *sh_name = secstrings + get32(&sections[loop].sh_name);
@@ -931,12 +954,13 @@
 +
 +	verbose("%08lx         (%lu bytes csum 0x%02x)\n",
 +		ftell(outfd), ftell(outfd), xcsum);
-+
-+} /* end extract_elf32() */
-diff -urNp --exclude-from=/home/davej/.exclude linux-903/scripts/modsign/modsign.sh linux-904/scripts/modsign/modsign.sh
---- linux-903/scripts/modsign/modsign.sh
-+++ linux-904/scripts/modsign/modsign.sh
-@@ -0,0 +1,57 @@
++}
+diff --git a/scripts/modsign/modsign.sh b/scripts/modsign/modsign.sh
+new file mode 100644
+index 0000000..5615f92
+--- /dev/null
++++ b/scripts/modsign/modsign.sh
+@@ -0,0 +1,58 @@
 +#!/bin/bash
 +###############################################################################
 +#
@@ -980,6 +1004,7 @@
 +
 +# strip out only the sections that we care about
 +scripts/modsign/mod-extract $verbose $module $module.out || exit $?
++# dd if=/dev/zero of=$module.out bs=1 count=1 # inject fault
 +
 +# sign the sections
 +gpg --no-greeting $KEYFLAGS -b $module.out || exit $?

linux-2.6-silence-noise.patch:

Index: linux-2.6-silence-noise.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel-xen-2.6/F-7/linux-2.6-silence-noise.patch,v
retrieving revision 1.2
retrieving revision 1.2.14.1
diff -u -r1.2 -r1.2.14.1
--- linux-2.6-silence-noise.patch	22 Mar 2007 15:40:59 -0000	1.2
+++ linux-2.6-silence-noise.patch	17 Oct 2007 19:26:57 -0000	1.2.14.1
@@ -1,17 +1,3 @@
---- linux-2.6.18.noarch/arch/x86_64/pci/mmconfig.c~	2006-10-11 13:45:34.000000000 -0400
-+++ linux-2.6.18.noarch/arch/x86_64/pci/mmconfig.c	2006-10-11 13:48:50.000000000 -0400
-@@ -180,9 +180,9 @@ void __init pci_mmcfg_init(void)
- 	if (!e820_all_mapped(pci_mmcfg_config[0].base_address,
- 			pci_mmcfg_config[0].base_address + MMCONFIG_APER_MIN,
- 			E820_RESERVED)) {
--		printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %x is not E820-reserved\n",
-+		printk(KERN_INFO "PCI: BIOS Bug: MCFG area at %x is not E820-reserved\n",
- 				pci_mmcfg_config[0].base_address);
--		printk(KERN_ERR "PCI: Not using MMCONFIG.\n");
-+		printk(KERN_INFO "PCI: Not using MMCONFIG.\n");
- 		return;
- 	}
- 
 --- linux-2.6.18.noarch/arch/x86_64/mm/init.c~	2006-10-16 17:09:56.000000000 -0400
 +++ linux-2.6.18.noarch/arch/x86_64/mm/init.c	2006-10-16 17:10:09.000000000 -0400
 @@ -337,10 +337,6 @@ static void __init find_early_table_spac
@@ -66,3 +52,48 @@
  						"resource region %d "
  						"of device %s\n",
  						idx, pci_name(dev));
+--- linux-2.6.20.noarch/drivers/base/power/main.c~	2007-04-12 15:29:10.000000000 -0400
++++ linux-2.6.20.noarch/drivers/base/power/main.c	2007-04-12 15:29:34.000000000 -0400
+@@ -53,9 +53,6 @@ int device_pm_add(struct device * dev)
+ {
+ 	int error;
+ 
+-	pr_debug("PM: Adding info for %s:%s\n",
+-		 dev->bus ? dev->bus->name : "No Bus",
+-		 kobject_name(&dev->kobj));
+ 	down(&dpm_list_sem);
+ 	list_add_tail(&dev->power.entry, &dpm_active);
+ 	device_pm_set_parent(dev, dev->parent);
+@@ -67,9 +64,6 @@ int device_pm_add(struct device * dev)
+ 
+ void device_pm_remove(struct device * dev)
+ {
+-	pr_debug("PM: Removing info for %s:%s\n",
+-		 dev->bus ? dev->bus->name : "No Bus",
+-		 kobject_name(&dev->kobj));
+ 	down(&dpm_list_sem);
+ 	dpm_sysfs_remove(dev);
+ 	put_device(dev->power.pm_parent);
+Remove noisy PM printk.
+This has served its purpose.
+
+Signed-off-by: Dave Jones <davej at redhat.com>
+
+--- linux-2.6.20.noarch/drivers/pci/pci.c~	2007-04-16 18:14:14.000000000 -0400
++++ linux-2.6.20.noarch/drivers/pci/pci.c	2007-04-16 18:14:33.000000000 -0400
+@@ -664,14 +664,9 @@ pci_restore_state(struct pci_dev *dev)
+ 	 */
+ 	for (i = 15; i >= 0; i--) {
+ 		pci_read_config_dword(dev, i * 4, &val);
+-		if (val != dev->saved_config_space[i]) {
+-			printk(KERN_DEBUG "PM: Writing back config space on "
+-				"device %s at offset %x (was %x, writing %x)\n",
+-				pci_name(dev), i,
+-				val, (int)dev->saved_config_space[i]);
++		if (val != dev->saved_config_space[i])
+ 			pci_write_config_dword(dev,i * 4,
+ 				dev->saved_config_space[i]);
+-		}
+ 	}
+ 	pci_restore_pcix_state(dev);
+ 	pci_restore_msi_state(dev);

linux-2.6-squashfs.patch:

Index: linux-2.6-squashfs.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel-xen-2.6/F-7/linux-2.6-squashfs.patch,v
retrieving revision 1.2
retrieving revision 1.2.14.1
diff -u -r1.2 -r1.2.14.1
--- linux-2.6-squashfs.patch	22 Mar 2007 15:40:59 -0000	1.2
+++ linux-2.6-squashfs.patch	17 Oct 2007 19:26:57 -0000	1.2.14.1
@@ -1,11 +1,97 @@
-diff -urpN --exclude-from=/home/davej/.exclude vanilla/fs/squashfs/inode.c squash/fs/squashfs/inode.c
---- vanilla/fs/squashfs/inode.c	1969-12-31 19:00:00.000000000 -0500
-+++ squash/fs/squashfs/inode.c	2006-12-11 20:41:22.000000000 -0500
-@@ -0,0 +1,2299 @@
+diff -x .gitignore -Nurp linux-2.6.20/fs/Kconfig linux-2.6.20-squashfs3.2-r2/fs/Kconfig
+--- linux-2.6.20/fs/Kconfig	2006-12-25 01:13:12.000000000 +0000
++++ linux-2.6.20-squashfs3.2-r2/fs/Kconfig	2007-01-16 02:06:03.000000000 +0000
+@@ -1404,6 +1404,71 @@ config CRAMFS
+ 
+ 	  If unsure, say N.
+ 
++config SQUASHFS
++	tristate "SquashFS 3.2 - Squashed file system support"
++	select ZLIB_INFLATE
++	help
++	  Saying Y here includes support for SquashFS 3.2 (a Compressed Read-Only File
++	  System).  Squashfs is a highly compressed read-only filesystem for Linux.
++	  It uses zlib compression to compress both files, inodes and directories.
++	  Inodes in the system are very small and all blocks are packed to minimise
++	  data overhead. Block sizes greater than 4K are supported up to a maximum of 64K.
++	  SquashFS 3.1 supports 64 bit filesystems and files (larger than 4GB), full
++	  uid/gid information, hard links and timestamps.
++
++	  Squashfs is intended for general read-only filesystem use, for archival
++	  use (i.e. in cases where a .tar.gz file may be used), and in embedded
++	  systems where low overhead is needed.  Further information and filesystem tools
++	  are available from http://squashfs.sourceforge.net.
++
++	  If you want to compile this as a module ( = code which can be
++	  inserted in and removed from the running kernel whenever you want),
++	  say M here and read <file:Documentation/modules.txt>.  The module
++	  will be called squashfs.  Note that the root file system (the one
++	  containing the directory /) cannot be compiled as a module.
++
++	  If unsure, say N.
++
++config SQUASHFS_EMBEDDED
++
++	bool "Additional options for memory-constrained systems" 
++	depends on SQUASHFS
++	default n
++	help
++	  Saying Y here allows you to specify cache sizes and how Squashfs
++	  allocates memory.  This is only intended for memory constrained
++	  systems.
++
++	  If unsure, say N.
++
++config SQUASHFS_FRAGMENT_CACHE_SIZE
++	int "Number of fragments cached" if SQUASHFS_EMBEDDED
++	depends on SQUASHFS
++	default "3"
++	help
++	  By default SquashFS caches the last 3 fragments read from
++	  the filesystem.  Increasing this amount may mean SquashFS
++	  has to re-read fragments less often from disk, at the expense
++	  of extra system memory.  Decreasing this amount will mean
++	  SquashFS uses less memory at the expense of extra reads from disk.
++
++	  Note there must be at least one cached fragment.  Anything
++	  much more than three will probably not make much difference.
++
++config SQUASHFS_VMALLOC
++	bool "Use Vmalloc rather than Kmalloc" if SQUASHFS_EMBEDDED
++	depends on SQUASHFS
++	default n
++	help
++	  By default SquashFS uses kmalloc to obtain fragment cache memory.
++	  Kmalloc memory is the standard kernel allocator, but it can fail
++	  on memory constrained systems.  Because of the way Vmalloc works,
++	  Vmalloc can succeed when kmalloc fails.  Specifying this option
++	  will make SquashFS always use Vmalloc to allocate the
++	  fragment cache memory.
++
++	  If unsure, say N.
++
+ config VXFS_FS
+ 	tristate "FreeVxFS file system support (VERITAS VxFS(TM) compatible)"
+ 	depends on BLOCK
+diff -x .gitignore -Nurp linux-2.6.20/fs/Makefile linux-2.6.20-squashfs3.2-r2/fs/Makefile
+--- linux-2.6.20/fs/Makefile	2006-12-25 01:13:12.000000000 +0000
++++ linux-2.6.20-squashfs3.2-r2/fs/Makefile	2007-01-16 02:06:03.000000000 +0000
+@@ -68,6 +68,7 @@ obj-$(CONFIG_JBD)		+= jbd/
+ obj-$(CONFIG_JBD2)		+= jbd2/
+ obj-$(CONFIG_EXT2_FS)		+= ext2/
+ obj-$(CONFIG_CRAMFS)		+= cramfs/
++obj-$(CONFIG_SQUASHFS)		+= squashfs/
+ obj-$(CONFIG_RAMFS)		+= ramfs/
+ obj-$(CONFIG_HUGETLBFS)		+= hugetlbfs/
+ obj-$(CONFIG_CODA_FS)		+= coda/
+diff -x .gitignore -Nurp linux-2.6.20/fs/squashfs/inode.c linux-2.6.20-squashfs3.2-r2/fs/squashfs/inode.c
+--- linux-2.6.20/fs/squashfs/inode.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.20-squashfs3.2-r2/fs/squashfs/inode.c	2007-01-16 02:28:36.000000000 +0000
+@@ -0,0 +1,2329 @@
 +/*
 + * Squashfs - a compressed read only filesystem for Linux
 + *
-+ * Copyright (c) 2002, 2003, 2004, 2005, 2006
++ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007
 + * Phillip Lougher <phillip at lougher.org.uk>
 + *
 + * This program is free software; you can redistribute it and/or
@@ -25,49 +111,40 @@
 + * inode.c
 + */
 +
-+#include <linux/types.h>
 +#include <linux/squashfs_fs.h>
 +#include <linux/module.h>
-+#include <linux/errno.h>
-+#include <linux/slab.h>
 +#include <linux/zlib.h>
 +#include <linux/fs.h>
-+#include <linux/smp_lock.h>
-+#include <linux/slab.h>
 +#include <linux/squashfs_fs_sb.h>
 +#include <linux/squashfs_fs_i.h>
 +#include <linux/buffer_head.h>
 +#include <linux/vfs.h>
-+#include <linux/init.h>
-+#include <linux/dcache.h>
-+#include <linux/wait.h>
-+#include <linux/blkdev.h>
 +#include <linux/vmalloc.h>
-+#include <asm/uaccess.h>
-+#include <asm/semaphore.h>
++#include <linux/smp_lock.h>
 +
 +#include "squashfs.h"
 +
-+static void squashfs_put_super(struct super_block *);
++static void vfs_read_inode(struct inode *i);
++static struct dentry *squashfs_get_parent(struct dentry *child);
++static int squashfs_read_inode(struct inode *i, squashfs_inode_t inode);
 +static int squashfs_statfs(struct dentry *, struct kstatfs *);
 +static int squashfs_symlink_readpage(struct file *file, struct page *page);
++static long long read_blocklist(struct inode *inode, int index,
++				int readahead_blks, char *block_list,
++				unsigned short **block_p, unsigned int *bsize);
 +static int squashfs_readpage(struct file *file, struct page *page);
 +static int squashfs_readpage4K(struct file *file, struct page *page);
 +static int squashfs_readdir(struct file *, void *, filldir_t);
-+static struct inode *squashfs_alloc_inode(struct super_block *sb);
-+static void squashfs_destroy_inode(struct inode *inode);
-+static int init_inodecache(void);
-+static void destroy_inodecache(void);
 +static struct dentry *squashfs_lookup(struct inode *, struct dentry *,
 +				struct nameidata *);
-+static int squashfs_read_inode(struct inode *i, squashfs_inode_t inode);
-+static long long read_blocklist(struct inode *inode, int index,
-+				int readahead_blks, char *block_list,
-+				unsigned short **block_p, unsigned int *bsize);
++static int squashfs_remount(struct super_block *s, int *flags, char *data);
++static void squashfs_put_super(struct super_block *);
 +static int squashfs_get_sb(struct file_system_type *,int, const char *, void *,
 +				struct vfsmount *);
-+static void vfs_read_inode(struct inode *i);
-+static struct dentry *squashfs_get_parent(struct dentry *child);
++static struct inode *squashfs_alloc_inode(struct super_block *sb);
++static void squashfs_destroy_inode(struct inode *inode);
++static int init_inodecache(void);
++static void destroy_inodecache(void);
 +
 +static struct file_system_type squashfs_fs_type = {
 +	.owner = THIS_MODULE,
@@ -77,7 +154,7 @@
 +	.fs_flags = FS_REQUIRES_DEV
 +};
 +
-+static unsigned char squashfs_filetype_table[] = {
++static const unsigned char squashfs_filetype_table[] = {
 +	DT_UNKNOWN, DT_DIR, DT_REG, DT_LNK, DT_BLK, DT_CHR, DT_FIFO, DT_SOCK
 +};
 +
@@ -86,6 +163,7 @@
 +	.destroy_inode = squashfs_destroy_inode,
 +	.statfs = squashfs_statfs,
 +	.put_super = squashfs_put_super,
++	.remount_fs = squashfs_remount
 +};
 +
 +static struct super_operations squashfs_export_super_ops = {
@@ -96,23 +174,23 @@
 +	.read_inode = vfs_read_inode
 +};
 +
-+struct export_operations squashfs_export_ops = {
++static struct export_operations squashfs_export_ops = {
 +	.get_parent = squashfs_get_parent
 +};
 +
-+SQSH_EXTERN struct address_space_operations squashfs_symlink_aops = {
++SQSH_EXTERN const struct address_space_operations squashfs_symlink_aops = {
 +	.readpage = squashfs_symlink_readpage
 +};
 +
-+SQSH_EXTERN struct address_space_operations squashfs_aops = {
++SQSH_EXTERN const struct address_space_operations squashfs_aops = {
 +	.readpage = squashfs_readpage
 +};
 +
-+SQSH_EXTERN struct address_space_operations squashfs_aops_4K = {
++SQSH_EXTERN const struct address_space_operations squashfs_aops_4K = {
 +	.readpage = squashfs_readpage4K
 +};
 +
-+static struct file_operations squashfs_dir_ops = {
++static const struct file_operations squashfs_dir_ops = {
 +	.read = generic_read_dir,
 +	.readdir = squashfs_readdir
 +};
@@ -200,14 +278,12 @@
 +	unsigned int offset = index & ((1 << msblk->devblksize_log2) - 1);
 +	unsigned int cur_index = index >> msblk->devblksize_log2;
 +	int bytes, avail_bytes, b = 0, k = 0;
-+	char *c_buffer;
 +	unsigned int compressed;
 +	unsigned int c_byte = length;
 +
 +	if (c_byte) {
 +		bytes = msblk->devblksize - offset;
 +		compressed = SQUASHFS_COMPRESSED_BLOCK(c_byte);
-+		c_buffer = compressed ? msblk->read_data : buffer;
 +		c_byte = SQUASHFS_COMPRESSED_SIZE_BLOCK(c_byte);
 +
 +		TRACE("Block @ 0x%llx, %scompressed size %d, src size %d\n", index, compressed
@@ -235,7 +311,6 @@
 +
 +		bytes = msblk->devblksize - offset;
 +		compressed = SQUASHFS_COMPRESSED(c_byte);
-+		c_buffer = compressed ? msblk->read_data : buffer;
 +		c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte);
 +
 +		TRACE("Block @ 0x%llx, %scompressed size %d\n", index, compressed
@@ -252,47 +327,85 @@
 +		ll_rw_block(READ, b - 1, bh + 1);
 +	}
 +
-+	if (compressed)
-+		down(&msblk->read_data_mutex);
++	if (compressed) {
++		int zlib_err = 0;
 +
-+	for (bytes = 0; k < b; k++) {
-+		avail_bytes = (c_byte - bytes) > (msblk->devblksize - offset) ?
-+					msblk->devblksize - offset :
-+					c_byte - bytes;
-+		wait_on_buffer(bh[k]);
-+		if (!buffer_uptodate(bh[k]))
-+			goto block_release;
-+		memcpy(c_buffer + bytes, bh[k]->b_data + offset, avail_bytes);
-+		bytes += avail_bytes;
-+		offset = 0;
-+		brelse(bh[k]);
-+	}
++		/*
++	 	* uncompress block
++	 	*/
 +
-+	/*
-+	 * uncompress block
-+	 */
-+	if (compressed) {
-+		int zlib_err;
++		mutex_lock(&msblk->read_data_mutex);
 +
-+		msblk->stream.next_in = c_buffer;
-+		msblk->stream.avail_in = c_byte;
 +		msblk->stream.next_out = buffer;
-+		//msblk->stream.avail_out = msblk->read_size;//srclength;
 +		msblk->stream.avail_out = srclength;
 +
-+		if (((zlib_err = zlib_inflateInit(&msblk->stream)) != Z_OK) ||
-+				((zlib_err = zlib_inflate(&msblk->stream, Z_FINISH))
-+				 != Z_STREAM_END) || ((zlib_err =
-+				zlib_inflateEnd(&msblk->stream)) != Z_OK)) {
-+			//ERROR("zlib_fs returned unexpected result 0x%x\n",
-+			//	zlib_err);
-+			ERROR("zlib_fs returned unexpected result 0x%x, srclength %d\n",
++		for (bytes = 0; k < b; k++) {
++			avail_bytes = (c_byte - bytes) > (msblk->devblksize - offset) ?
++					msblk->devblksize - offset :
++					c_byte - bytes;
++			wait_on_buffer(bh[k]);
++			if (!buffer_uptodate(bh[k]))
++				goto release_mutex;
++
++			msblk->stream.next_in = bh[k]->b_data + offset;
++			msblk->stream.avail_in = avail_bytes;
++
++			if (k == 0) {
++				zlib_err = zlib_inflateInit(&msblk->stream);
++				if (zlib_err != Z_OK) {
++					ERROR("zlib_inflateInit returned unexpected result 0x%x, srclength %d\n",
++						zlib_err, srclength);
++					goto release_mutex;
++				}
++
++				if (avail_bytes == 0) {
++					offset = 0;
++					brelse(bh[k]);
++					continue;
++				}
++			}
++
++			zlib_err = zlib_inflate(&msblk->stream, Z_NO_FLUSH);
++			if (zlib_err != Z_OK && zlib_err != Z_STREAM_END) {
++				ERROR("zlib_inflate returned unexpected result 0x%x, srclength %d, avail_in %d, avail_out %d\n",
++					zlib_err, srclength, msblk->stream.avail_in, msblk->stream.avail_out);
++				goto release_mutex;
++			}
++
++			bytes += avail_bytes;
++			offset = 0;
++			brelse(bh[k]);
++		}
++
++		if (zlib_err != Z_STREAM_END)
++			goto release_mutex;
++
++		zlib_err = zlib_inflateEnd(&msblk->stream);
++		if (zlib_err != Z_OK) {
++			ERROR("zlib_inflateEnd returned unexpected result 0x%x, srclength %d\n",
 +				zlib_err, srclength);
-+			bytes = 0;
-+		} else
-+			bytes = msblk->stream.total_out;
-+		
-+		up(&msblk->read_data_mutex);
++			goto release_mutex;
++		}
++		bytes = msblk->stream.total_out;
++		mutex_unlock(&msblk->read_data_mutex);
++	} else {
++		int i;
++
++		for(i = 0; i < b; i++) {
++			wait_on_buffer(bh[i]);
++			if(!buffer_uptodate(bh[i]))
++				goto block_release;
++		}
++
++		for (bytes = 0; k < b; k++) {
++			avail_bytes = (c_byte - bytes) > (msblk->devblksize - offset) ?
++					msblk->devblksize - offset :
++					c_byte - bytes;
++			memcpy(buffer + bytes, bh[k]->b_data + offset, avail_bytes);
++			bytes += avail_bytes;
++			offset = 0;
++			brelse(bh[k]);
++		}
 +	}
 +
 +	if (next_index)
@@ -301,6 +414,9 @@
 +				 ? 3 : 2));
 +	return bytes;
 +
++release_mutex:
++	mutex_unlock(&msblk->read_data_mutex);
++
 +block_release:
 +	for (; k < b; k++)
 +		brelse(bh[k]);
@@ -327,7 +443,7 @@
 +			if (msblk->block_cache[i].block == block)
 +				break; 
 +		
-+		down(&msblk->block_cache_mutex);
++		mutex_lock(&msblk->block_cache_mutex);
 +
 +		if (i == SQUASHFS_CACHED_BLKS) {
 +			/* read inode header block */
@@ -344,7 +460,7 @@
 +				init_waitqueue_entry(&wait, current);
 +				add_wait_queue(&msblk->waitq, &wait);
 +				set_current_state(TASK_UNINTERRUPTIBLE);
-+ 				up(&msblk->block_cache_mutex);
++ 				mutex_unlock(&msblk->block_cache_mutex);
 +				schedule();
 +				set_current_state(TASK_RUNNING);
 +				remove_wait_queue(&msblk->waitq, &wait);
@@ -359,28 +475,28 @@
 +						GFP_KERNEL))) {
 +					ERROR("Failed to allocate cache"
 +							"block\n");
-+					up(&msblk->block_cache_mutex);
++					mutex_unlock(&msblk->block_cache_mutex);
 +					goto out;
 +				}
 +			}
 +	
 +			msblk->block_cache[i].block = SQUASHFS_USED_BLK;
-+			up(&msblk->block_cache_mutex);
++			mutex_unlock(&msblk->block_cache_mutex);
 +
 +			msblk->block_cache[i].length = squashfs_read_data(s,
 +				msblk->block_cache[i].data, block, 0, &next_index, SQUASHFS_METADATA_SIZE);
 +			if (msblk->block_cache[i].length == 0) {
 +				ERROR("Unable to read cache block [%llx:%x]\n",
 +						block, offset);
-+				down(&msblk->block_cache_mutex);
++				mutex_lock(&msblk->block_cache_mutex);
 +				msblk->block_cache[i].block = SQUASHFS_INVALID_BLK;
 +				kfree(msblk->block_cache[i].data);
 +				wake_up(&msblk->waitq);
-+				up(&msblk->block_cache_mutex);
++				mutex_unlock(&msblk->block_cache_mutex);
 +				goto out;
 +			}
 +
-+			down(&msblk->block_cache_mutex);
++			mutex_lock(&msblk->block_cache_mutex);
 +			wake_up(&msblk->waitq);
 +			msblk->block_cache[i].block = block;
 +			msblk->block_cache[i].next_index = next_index;
@@ -388,14 +504,14 @@
 +		}
 +
 +		if (msblk->block_cache[i].block != block) {
-+			up(&msblk->block_cache_mutex);
++			mutex_unlock(&msblk->block_cache_mutex);
 +			continue;
 +		}
 +
 +		bytes = msblk->block_cache[i].length - offset;
 +
 +		if (bytes < 1) {
-+			up(&msblk->block_cache_mutex);
++			mutex_unlock(&msblk->block_cache_mutex);
 +			goto out;
 +		} else if (bytes >= length) {
 +			if (buffer)
@@ -408,7 +524,7 @@
 +				*next_block = block;
 +				*next_offset = offset + length;
 +			}
-+			up(&msblk->block_cache_mutex);
++			mutex_unlock(&msblk->block_cache_mutex);
 +			goto finish;
 +		} else {
 +			if (buffer) {
@@ -417,7 +533,7 @@
 +				buffer += bytes;
 +			}
 +			block = msblk->block_cache[i].next_index;
-+			up(&msblk->block_cache_mutex);
++			mutex_unlock(&msblk->block_cache_mutex);
 +			length -= bytes;
 +			offset = 0;
 +		}
@@ -469,10 +585,10 @@
 +SQSH_EXTERN void release_cached_fragment(struct squashfs_sb_info *msblk, struct
 +					squashfs_fragment_cache *fragment)
 +{
-+	down(&msblk->fragment_mutex);
++	mutex_lock(&msblk->fragment_mutex);
 +	fragment->locked --;
 +	wake_up(&msblk->fragment_wait_queue);
-+	up(&msblk->fragment_mutex);
++	mutex_unlock(&msblk->fragment_mutex);
 +}
 +
 +
@@ -485,7 +601,7 @@
 +	struct squashfs_super_block *sblk = &msblk->sblk;
 +
 +	while ( 1 ) {
-+		down(&msblk->fragment_mutex);
++		mutex_lock(&msblk->fragment_mutex);
 +
 +		for (i = 0; i < SQUASHFS_CACHED_FRAGMENTS &&
 +				msblk->fragment[i].block != start_block; i++);
@@ -503,7 +619,7 @@
 +				add_wait_queue(&msblk->fragment_wait_queue,
 +									&wait);
 +				set_current_state(TASK_UNINTERRUPTIBLE);
-+				up(&msblk->fragment_mutex);
++				mutex_unlock(&msblk->fragment_mutex);
 +				schedule();
 +				set_current_state(TASK_RUNNING);
 +				remove_wait_queue(&msblk->fragment_wait_queue,
@@ -518,13 +634,13 @@
 +						(SQUASHFS_FILE_MAX_SIZE))) {
 +					ERROR("Failed to allocate fragment "
 +							"cache block\n");
-+					up(&msblk->fragment_mutex);
++					mutex_unlock(&msblk->fragment_mutex);
 +					goto out;
 +				}
 +
 +			msblk->fragment[i].block = SQUASHFS_INVALID_BLK;
 +			msblk->fragment[i].locked = 1;
-+			up(&msblk->fragment_mutex);
++			mutex_unlock(&msblk->fragment_mutex);
 +
 +			if (!(msblk->fragment[i].length = squashfs_read_data(s,
 +						msblk->fragment[i].data,
@@ -532,18 +648,21 @@
 +				ERROR("Unable to read fragment cache block "
 +							"[%llx]\n", start_block);
 +				msblk->fragment[i].locked = 0;
++				smp_mb();
 +				goto out;
 +			}
 +
++			mutex_lock(&msblk->fragment_mutex);
 +			msblk->fragment[i].block = start_block;
 +			TRACE("New fragment %d, start block %lld, locked %d\n",
 +						i, msblk->fragment[i].block,
 +						msblk->fragment[i].locked);
++			mutex_unlock(&msblk->fragment_mutex);
 +			break;
 +		}
 +
 +		msblk->fragment[i].locked++;
-+		up(&msblk->fragment_mutex);
++		mutex_unlock(&msblk->fragment_mutex);
 +		TRACE("Got fragment %d, start block %lld, locked %d\n", i,
 +						msblk->fragment[i].block,
 +						msblk->fragment[i].locked);
@@ -1099,11 +1218,11 @@
 +	msblk->devblksize = sb_min_blocksize(s, BLOCK_SIZE);
 +	msblk->devblksize_log2 = ffz(~msblk->devblksize);
 +
-+	init_MUTEX(&msblk->read_data_mutex);
-+	init_MUTEX(&msblk->read_page_mutex);
-+	init_MUTEX(&msblk->block_cache_mutex);
-+	init_MUTEX(&msblk->fragment_mutex);
-+	init_MUTEX(&msblk->meta_index_mutex);
++	mutex_init(&msblk->read_data_mutex);
++	mutex_init(&msblk->read_page_mutex);
++	mutex_init(&msblk->block_cache_mutex);
++	mutex_init(&msblk->fragment_mutex);
++	mutex_init(&msblk->meta_index_mutex);
 +	
 +	init_waitqueue_head(&msblk->waitq);
 +	init_waitqueue_head(&msblk->fragment_wait_queue);
@@ -1187,16 +1306,6 @@
 +
 +	msblk->next_cache = 0;
 +
-+	/* Allocate read_data block */
-+	msblk->read_size = (sblk->block_size < SQUASHFS_METADATA_SIZE) ?
-+					SQUASHFS_METADATA_SIZE :
-+					sblk->block_size;
-+
-+	if (!(msblk->read_data = kmalloc(msblk->read_size, GFP_KERNEL))) {
-+		ERROR("Failed to allocate read_data block\n");
-+		goto failed_mount;
-+	}
-+
 +	/* Allocate read_page block */
 +	if (!(msblk->read_page = kmalloc(sblk->block_size, GFP_KERNEL))) {
 +		ERROR("Failed to allocate read_page block\n");
@@ -1255,7 +1364,7 @@
 +	if (msblk->read_fragment_index_table(s) == 0)
 +		goto failed_mount;
 +
-+	if(sblk->lookup_table_start == SQUASHFS_INVALID_BLK)
++	if(sblk->s_major < 3 || sblk->lookup_table_start == SQUASHFS_INVALID_BLK)
 +		goto allocate_root;
 +
 +	/* Allocate and read inode lookup table */
@@ -1286,7 +1395,6 @@
 +	kfree(msblk->fragment);
 +	kfree(msblk->uid);
 +	kfree(msblk->read_page);
-+	kfree(msblk->read_data);
 +	kfree(msblk->block_cache);
 +	kfree(msblk->fragment_index_2);
 +	vfree(msblk->stream.workspace);
@@ -1357,6 +1465,7 @@
 +skip_read:
 +	memset(pageaddr + bytes, 0, PAGE_CACHE_SIZE - bytes);
 +	kunmap(page);
++	flush_dcache_page(page);
 +	SetPageUptodate(page);
 +	unlock_page(page);
 +
@@ -1370,7 +1479,7 @@
 +	struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
 +	int i;
 +
-+	down(&msblk->meta_index_mutex);
++	mutex_lock(&msblk->meta_index_mutex);
 +
 +	TRACE("locate_meta_index: index %d, offset %d\n", index, offset);
 +
@@ -1392,7 +1501,7 @@
 +		meta->locked = 1;
 +
 +not_allocated:
-+	up(&msblk->meta_index_mutex);
++	mutex_unlock(&msblk->meta_index_mutex);
 +
 +	return meta;
 +}
@@ -1404,7 +1513,7 @@
 +	struct meta_index *meta = NULL;
 +	int i;
 +
-+	down(&msblk->meta_index_mutex);
++	mutex_lock(&msblk->meta_index_mutex);
 +
 +	TRACE("empty_meta_index: offset %d, skip %d\n", offset, skip);
 +
@@ -1446,7 +1555,7 @@
 +	meta->locked = 1;
 +
 +failed:
-+	up(&msblk->meta_index_mutex);
++	mutex_unlock(&msblk->meta_index_mutex);
 +	return meta;
 +}
 +
@@ -1454,6 +1563,7 @@
 +void release_meta_index(struct inode *inode, struct meta_index *meta)
 +{
 +	meta->locked = 0;
++	smp_mb();
 +}
 +
 +
@@ -1666,13 +1776,13 @@
 +					block_list, NULL, &bsize)) == 0)
 +			goto skip_read;
 +
-+		down(&msblk->read_page_mutex);
++		mutex_lock(&msblk->read_page_mutex);
 +		
 +		if (!(bytes = squashfs_read_data(inode->i_sb, msblk->read_page,
 +					block, bsize, NULL, sblk->block_size))) {
 +			ERROR("Unable to read page, block %llx, size %x\n", block,
 +					bsize);
-+			up(&msblk->read_page_mutex);
++			mutex_unlock(&msblk->read_page_mutex);
 +			goto skip_read;
 +		}
 +	} else {
@@ -1728,7 +1838,7 @@
 +	if (SQUASHFS_I(inode)->u.s1.fragment_start_block == SQUASHFS_INVALID_BLK
 +					|| index < (i_size_read(inode) >>
 +					sblk->block_log))
-+		up(&msblk->read_page_mutex);
++		mutex_unlock(&msblk->read_page_mutex);
 +	else
 +		release_cached_fragment(msblk, fragment);
 +
@@ -1781,7 +1891,7 @@
 +		if(block == 0)
 +			goto skip_read;
 +
-+		down(&msblk->read_page_mutex);
++		mutex_lock(&msblk->read_page_mutex);
 +		bytes = squashfs_read_data(inode->i_sb, msblk->read_page, block,
 +					bsize, NULL, sblk->block_size);
 +		if (bytes) {
@@ -1791,7 +1901,7 @@
 +		} else
 +			ERROR("Unable to read page, block %llx, size %x\n",
 +					block, bsize);
-+		up(&msblk->read_page_mutex);
++		mutex_unlock(&msblk->read_page_mutex);
 +	} else {
 +		struct squashfs_fragment_cache *fragment =
 +			get_cached_fragment(inode->i_sb,
@@ -2187,6 +2297,13 @@
 +}
 +
 +
++static int squashfs_remount(struct super_block *s, int *flags, char *data)
++{
++	*flags |= MS_RDONLY;
++	return 0;
++}
++
++
 +static void squashfs_put_super(struct super_block *s)
 +{
 +	int i;
@@ -2203,7 +2320,6 @@
 +				SQUASHFS_FREE(sbi->fragment[i].data);
 +		kfree(sbi->fragment);
 +		kfree(sbi->block_cache);
-+		kfree(sbi->read_data);
 +		kfree(sbi->read_page);
 +		kfree(sbi->uid);
 +		kfree(sbi->fragment_index);
@@ -2231,7 +2347,7 @@
 +	if (err)
 +		goto out;
 +
-+	printk(KERN_INFO "squashfs: version 3.2-alpha (2006/12/12) "
++	printk(KERN_INFO "squashfs: version 3.2-r2 (2007/01/15) "
 +		"Phillip Lougher\n");
 +
 +	if ((err = register_filesystem(&squashfs_fs_type)))
@@ -2249,7 +2365,7 @@
 +}
 +
 +
-+static struct kmem_cache *squashfs_inode_cachep;
++static struct kmem_cache * squashfs_inode_cachep;
 +
 +
 +static struct inode *squashfs_alloc_inode(struct super_block *sb)
@@ -2268,7 +2384,7 @@
 +}
 +
 +
-+static void init_once(void * foo, struct kmem_cache *cachep, unsigned long flags)
++static void init_once(void * foo, struct kmem_cache * cachep, unsigned long flags)
 +{
 +	struct squashfs_inode_info *ei = foo;
 +
@@ -2298,17 +2414,28 @@
 +
 +module_init(init_squashfs_fs);
 +module_exit(exit_squashfs_fs);
-+MODULE_DESCRIPTION("squashfs 3.2, a compressed read-only filesystem");
++MODULE_DESCRIPTION("squashfs 3.2-r2, a compressed read-only filesystem");
 +MODULE_AUTHOR("Phillip Lougher <phillip at lougher.org.uk>");
 +MODULE_LICENSE("GPL");
-diff -urpN --exclude-from=/home/davej/.exclude vanilla/fs/squashfs/squashfs2_0.c squash/fs/squashfs/squashfs2_0.c
---- vanilla/fs/squashfs/squashfs2_0.c	1969-12-31 19:00:00.000000000 -0500
-+++ squash/fs/squashfs/squashfs2_0.c	2006-12-11 20:41:22.000000000 -0500
-@@ -0,0 +1,757 @@
+diff -x .gitignore -Nurp linux-2.6.20/fs/squashfs/Makefile linux-2.6.20-squashfs3.2-r2/fs/squashfs/Makefile
+--- linux-2.6.20/fs/squashfs/Makefile	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.20-squashfs3.2-r2/fs/squashfs/Makefile	2007-01-12 00:06:09.000000000 +0000
+@@ -0,0 +1,7 @@
++#
++# Makefile for the linux squashfs routines.
++#
++
++obj-$(CONFIG_SQUASHFS) += squashfs.o
++squashfs-y += inode.o
++squashfs-y += squashfs2_0.o
+diff -x .gitignore -Nurp linux-2.6.20/fs/squashfs/squashfs2_0.c linux-2.6.20-squashfs3.2-r2/fs/squashfs/squashfs2_0.c
+--- linux-2.6.20/fs/squashfs/squashfs2_0.c	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.20-squashfs3.2-r2/fs/squashfs/squashfs2_0.c	2007-01-12 02:27:20.000000000 +0000
+@@ -0,0 +1,742 @@
 +/*
 + * Squashfs - a compressed read only filesystem for Linux
 + *
-+ * Copyright (c) 2002, 2003, 2004, 2005, 2006
++ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007
 + * Phillip Lougher <phillip at lougher.org.uk>
 + *
 + * This program is free software; you can redistribute it and/or
@@ -2328,27 +2455,12 @@
 + * squashfs2_0.c
 + */
 +
-+#include <linux/types.h>
 +#include <linux/squashfs_fs.h>
 +#include <linux/module.h>
-+#include <linux/errno.h>
-+#include <linux/slab.h>
 +#include <linux/zlib.h>
 +#include <linux/fs.h>
-+#include <linux/smp_lock.h>
-+#include <linux/slab.h>
 +#include <linux/squashfs_fs_sb.h>
 +#include <linux/squashfs_fs_i.h>
-+#include <linux/buffer_head.h>
-+#include <linux/vfs.h>
-+#include <linux/init.h>
-+#include <linux/dcache.h>
-+#include <linux/wait.h>
-+#include <linux/zlib.h>
-+#include <linux/blkdev.h>
-+#include <linux/vmalloc.h>
-+#include <asm/uaccess.h>
-+#include <asm/semaphore.h>
 +
 +#include "squashfs.h"
 +static int squashfs_readdir_2(struct file *file, void *dirent, filldir_t filldir);
@@ -2499,7 +2611,7 @@
 +			struct squashfs_reg_inode_header_2 *inodep = &id.reg;
 +			struct squashfs_reg_inode_header_2 *sinodep = &sid.reg;
 +			long long frag_blk;
-+			unsigned int frag_size;
++			unsigned int frag_size = 0;
 +				
 +			if (msblk->swap) {
 +				if (!squashfs_get_cached_block(s, (char *)
@@ -3062,14 +3174,14 @@
 +
 +	return 1;
 +}
-diff -urpN --exclude-from=/home/davej/.exclude vanilla/fs/squashfs/squashfs.h squash/fs/squashfs/squashfs.h
---- vanilla/fs/squashfs/squashfs.h	1969-12-31 19:00:00.000000000 -0500
-+++ squash/fs/squashfs/squashfs.h	2006-12-04 09:55:57.000000000 -0500
+diff -x .gitignore -Nurp linux-2.6.20/fs/squashfs/squashfs.h linux-2.6.20-squashfs3.2-r2/fs/squashfs/squashfs.h
+--- linux-2.6.20/fs/squashfs/squashfs.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.20-squashfs3.2-r2/fs/squashfs/squashfs.h	2007-01-12 01:42:11.000000000 +0000
 @@ -0,0 +1,87 @@
 +/*
 + * Squashfs - a compressed read only filesystem for Linux
 + *
-+ * Copyright (c) 2002, 2003, 2004, 2005, 2006
++ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007
 + * Phillip Lougher <phillip at lougher.org.uk>
 + *
 + * This program is free software; you can redistribute it and/or
@@ -3099,7 +3211,7 @@
 +#define TRACE(s, args...)	{}
 +#endif
 +
-+#define ERROR(s, args...)	printk(KERN_NOTICE "SQUASHFS error: "s, ## args)
++#define ERROR(s, args...)	printk(KERN_ERR "SQUASHFS error: "s, ## args)
 +
 +#define SERROR(s, args...)	do { \
 +				if (!silent) \
@@ -3128,9 +3240,9 @@
 +					*s, long long start_block,
 +					int length);
 +extern struct inode *squashfs_iget(struct super_block *s, squashfs_inode_t inode, unsigned int inode_number);
-+extern struct address_space_operations squashfs_symlink_aops;
-+extern struct address_space_operations squashfs_aops;
-+extern struct address_space_operations squashfs_aops_4K;
++extern const struct address_space_operations squashfs_symlink_aops;
++extern const struct address_space_operations squashfs_aops;
++extern const struct address_space_operations squashfs_aops_4K;
 +extern struct inode_operations squashfs_dir_inode_ops;
 +#else
 +#define SQSH_EXTERN static
@@ -3153,9 +3265,9 @@
 +	return 0;
 +}
 +#endif
-diff -urpN --exclude-from=/home/davej/.exclude vanilla/include/linux/squashfs_fs.h squash/include/linux/squashfs_fs.h
---- vanilla/include/linux/squashfs_fs.h	1969-12-31 19:00:00.000000000 -0500
-+++ squash/include/linux/squashfs_fs.h	2006-12-04 09:55:57.000000000 -0500
+diff -x .gitignore -Nurp linux-2.6.20/include/linux/squashfs_fs.h linux-2.6.20-squashfs3.2-r2/include/linux/squashfs_fs.h
+--- linux-2.6.20/include/linux/squashfs_fs.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.20-squashfs3.2-r2/include/linux/squashfs_fs.h	2007-01-12 00:06:09.000000000 +0000
 @@ -0,0 +1,934 @@
 +#ifndef SQUASHFS_FS
 +#define SQUASHFS_FS
@@ -3163,7 +3275,7 @@
 +/*
 + * Squashfs
 + *
-+ * Copyright (c) 2002, 2003, 2004, 2005, 2006
++ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007
 + * Phillip Lougher <phillip at lougher.org.uk>
 + *
 + * This program is free software; you can redistribute it and/or
@@ -3194,7 +3306,7 @@
 +#define SQUASHFS_ALLOC(a)		kmalloc(a, GFP_KERNEL)
 +#define SQUASHFS_FREE(a)		kfree(a)
 +#endif
-+#define SQUASHFS_CACHED_FRAGMENTS	3	
++#define SQUASHFS_CACHED_FRAGMENTS	CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE	
 +#define SQUASHFS_MAJOR			3
 +#define SQUASHFS_MINOR			0
 +#define SQUASHFS_MAGIC			0x73717368
@@ -4091,16 +4203,16 @@
 +
 +#endif
 +#endif
-diff -urpN --exclude-from=/home/davej/.exclude vanilla/include/linux/squashfs_fs_i.h squash/include/linux/squashfs_fs_i.h
---- vanilla/include/linux/squashfs_fs_i.h	1969-12-31 19:00:00.000000000 -0500
-+++ squash/include/linux/squashfs_fs_i.h	2006-12-04 09:55:57.000000000 -0500
+diff -x .gitignore -Nurp linux-2.6.20/include/linux/squashfs_fs_i.h linux-2.6.20-squashfs3.2-r2/include/linux/squashfs_fs_i.h
+--- linux-2.6.20/include/linux/squashfs_fs_i.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.20-squashfs3.2-r2/include/linux/squashfs_fs_i.h	2007-01-12 00:06:09.000000000 +0000
 @@ -0,0 +1,45 @@
 +#ifndef SQUASHFS_FS_I
 +#define SQUASHFS_FS_I
 +/*
 + * Squashfs
 + *
-+ * Copyright (c) 2002, 2003, 2004, 2005, 2006
++ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007
 + * Phillip Lougher <phillip at lougher.org.uk>
 + *
 + * This program is free software; you can redistribute it and/or
@@ -4140,16 +4252,16 @@
 +	struct inode	vfs_inode;
 +};
 +#endif
-diff -urpN --exclude-from=/home/davej/.exclude vanilla/include/linux/squashfs_fs_sb.h squash/include/linux/squashfs_fs_sb.h
---- vanilla/include/linux/squashfs_fs_sb.h	1969-12-31 19:00:00.000000000 -0500
-+++ squash/include/linux/squashfs_fs_sb.h	2006-12-04 09:55:57.000000000 -0500
-@@ -0,0 +1,76 @@
+diff -x .gitignore -Nurp linux-2.6.20/include/linux/squashfs_fs_sb.h linux-2.6.20-squashfs3.2-r2/include/linux/squashfs_fs_sb.h
+--- linux-2.6.20/include/linux/squashfs_fs_sb.h	1970-01-01 01:00:00.000000000 +0100
++++ linux-2.6.20-squashfs3.2-r2/include/linux/squashfs_fs_sb.h	2007-01-12 01:23:47.000000000 +0000
+@@ -0,0 +1,74 @@
 +#ifndef SQUASHFS_FS_SB
 +#define SQUASHFS_FS_SB
 +/*
 + * Squashfs
 + *
-+ * Copyright (c) 2002, 2003, 2004, 2005, 2006
++ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007
 + * Phillip Lougher <phillip at lougher.org.uk>
 + *
 + * This program is free software; you can redistribute it and/or
@@ -4199,14 +4311,12 @@
 +	unsigned int		*guid;
 +	long long		*fragment_index;
 +	unsigned int		*fragment_index_2;
-+	unsigned int		read_size;
-+	char			*read_data;
 +	char			*read_page;
-+	struct semaphore	read_data_mutex;
-+	struct semaphore	read_page_mutex;
-+	struct semaphore	block_cache_mutex;
-+	struct semaphore	fragment_mutex;
-+	struct semaphore	meta_index_mutex;
++	struct mutex		read_data_mutex;
++	struct mutex		read_page_mutex;
++	struct mutex		block_cache_mutex;
++	struct mutex		fragment_mutex;
++	struct mutex		meta_index_mutex;
 +	wait_queue_head_t	waitq;
 +	wait_queue_head_t	fragment_wait_queue;
 +	struct meta_index	*meta_index;
@@ -4220,93 +4330,57 @@
 +	int			(*read_fragment_index_table)(struct super_block *s);
 +};
 +#endif
---- linux-2.6.19.noarch/fs/Kconfig~	2006-12-18 18:14:31.000000000 -0500
-+++ linux-2.6.19.noarch/fs/Kconfig	2006-12-18 18:16:15.000000000 -0500
-@@ -1401,6 +1401,71 @@ config CRAMFS
+diff -x .gitignore -Nurp linux-2.6.20/init/do_mounts_rd.c linux-2.6.20-squashfs3.2-r2/init/do_mounts_rd.c
+--- linux-2.6.20/init/do_mounts_rd.c	2006-11-29 21:57:37.000000000 +0000
++++ linux-2.6.20-squashfs3.2-r2/init/do_mounts_rd.c	2007-01-16 02:06:03.000000000 +0000
+@@ -5,6 +5,7 @@
+ #include <linux/ext2_fs.h>
+ #include <linux/romfs_fs.h>
+ #include <linux/cramfs_fs.h>
++#include <linux/squashfs_fs.h>
+ #include <linux/initrd.h>
+ #include <linux/string.h>
  
- 	  If unsure, say N.
+@@ -39,6 +40,7 @@ static int __init crd_load(int in_fd, in
+  * numbers could not be found.
+  *
+  * We currently check for the following magic numbers:
++ *      squashfs
+  * 	minix
+  * 	ext2
+  *	romfs
+@@ -53,6 +55,7 @@ identify_ramdisk_image(int fd, int start
+ 	struct ext2_super_block *ext2sb;
+ 	struct romfs_super_block *romfsb;
+ 	struct cramfs_super *cramfsb;
++	struct squashfs_super_block *squashfsb;
+ 	int nblocks = -1;
+ 	unsigned char *buf;
  
-+config SQUASHFS
-+       tristate "SquashFS 3.0 - Squashed file system support"
-+       select ZLIB_INFLATE
-+       help
-+         Saying Y here includes support for SquashFS 3.0 (a Compressed Read-Only File
-+         System).  Squashfs is a highly compressed read-only filesystem for Linux.
-+         It uses zlib compression to compress both files, inodes and directories.
-+         Inodes in the system are very small and all blocks are packed to minimise
-+         data overhead. Block sizes greater than 4K are supported up to a maximum of 64K.
-+         SquashFS 3.0 supports 64 bit filesystems and files (larger than 4GB), full
-+         uid/gid information, hard links and timestamps.
-+
-+         Squashfs is intended for general read-only filesystem use, for archival
-+         use (i.e. in cases where a .tar.gz file may be used), and in embedded
-+         systems where low overhead is needed.  Further information and filesystem tools
-+         are available from http://squashfs.sourceforge.net.
-+
-+         If you want to compile this as a module ( = code which can be
-+         inserted in and removed from the running kernel whenever you want),
-+         say M here and read <file:Documentation/modules.txt>.  The module
-+         will be called squashfs.  Note that the root file system (the one
-+         containing the directory /) cannot be compiled as a module.
-+
-+         If unsure, say N.
-+
-+config SQUASHFS_EMBEDDED
-+
-+       bool "Additional options for memory-constrained systems"
-+       depends on SQUASHFS
-+       default n
-+       help
-+         Saying Y here allows you to specify cache sizes and how Squashfs
-+         allocates memory.  This is only intended for memory constrained
-+         systems.
-+
-+         If unsure, say N.
-+
-+config SQUASHFS_FRAGMENT_CACHE_SIZE
-+       int "Number of fragments cached" if SQUASHFS_EMBEDDED
-+       depends on SQUASHFS
-+       default "3"
-+       help
-+         By default SquashFS caches the last 3 fragments read from
-+         the filesystem.  Increasing this amount may mean SquashFS
-+         has to re-read fragments less often from disk, at the expense
-+         of extra system memory.  Decreasing this amount will mean
-+         SquashFS uses less memory at the expense of extra reads from disk.
-+
-+         Note there must be at least one cached fragment.  Anything
-+         much more than three will probably not make much difference.
-+
-+config SQUASHFS_VMALLOC
-+       bool "Use Vmalloc rather than Kmalloc" if SQUASHFS_EMBEDDED
-+       depends on SQUASHFS
-+       default n
-+       help
-+         By default SquashFS uses kmalloc to obtain fragment cache memory.
-+         Kmalloc memory is the standard kernel allocator, but it can fail
-+         on memory constrained systems.  Because of the way Vmalloc works,
-+         Vmalloc can succeed when kmalloc fails.  Specifying this option
-+         will make SquashFS always use Vmalloc to allocate the
-+         fragment cache memory.
-+
-+         If unsure, say N.
-+
- config VXFS_FS
- 	tristate "FreeVxFS file system support (VERITAS VxFS(TM) compatible)"
- 	depends on BLOCK
---- linux-2.6.19.noarch/fs/Makefile~	2006-12-18 18:16:23.000000000 -0500
-+++ linux-2.6.19.noarch/fs/Makefile	2006-12-18 18:16:55.000000000 -0500
-@@ -68,6 +68,7 @@ obj-$(CONFIG_JBD)		+= jbd/
- obj-$(CONFIG_JBD2)		+= jbd2/
- obj-$(CONFIG_EXT2_FS)		+= ext2/
- obj-$(CONFIG_CRAMFS)		+= cramfs/
-+obj-$(CONFIG_SQUASHFS)		+= squashfs/
- obj-$(CONFIG_RAMFS)		+= ramfs/
- obj-$(CONFIG_HUGETLBFS)		+= hugetlbfs/
- obj-$(CONFIG_CODA_FS)		+= coda/
---- /dev/null	2006-12-18 15:12:55.143924919 +0000
-+++ linux-2.6.19.ppc/fs/squashfs/Makefile	2006-12-19 11:15:13.000000000 +0000
-@@ -0,0 +1,3 @@
-+obj-$(CONFIG_SQUASHFS) += squashfs.o
+@@ -64,6 +67,7 @@ identify_ramdisk_image(int fd, int start
+ 	ext2sb = (struct ext2_super_block *) buf;
+ 	romfsb = (struct romfs_super_block *) buf;
+ 	cramfsb = (struct cramfs_super *) buf;
++	squashfsb = (struct squashfs_super_block *) buf;
+ 	memset(buf, 0xe5, size);
+ 
+ 	/*
+@@ -101,6 +105,18 @@ identify_ramdisk_image(int fd, int start
+ 		goto done;
+ 	}
+ 
++	/* squashfs is at block zero too */
++	if (squashfsb->s_magic == SQUASHFS_MAGIC) {
++		printk(KERN_NOTICE
++		       "RAMDISK: squashfs filesystem found at block %d\n",
++		       start_block);
++		if (squashfsb->s_major < 3)
++			nblocks = (squashfsb->bytes_used_2+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS;
++		else
++			nblocks = (squashfsb->bytes_used+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS;
++		goto done;
++	}
 +
-+squashfs-objs := inode.o squashfs2_0.o
+ 	/*
+ 	 * Read block 1 to test for minix and ext2 superblock
+ 	 */

linux-2.6-xen-backwards-time.patch:

Index: linux-2.6-xen-backwards-time.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel-xen-2.6/F-7/linux-2.6-xen-backwards-time.patch,v
retrieving revision 1.1
retrieving revision 1.1.4.1
diff -u -r1.1 -r1.1.4.1
--- linux-2.6-xen-backwards-time.patch	9 Aug 2007 17:19:55 -0000	1.1
+++ linux-2.6-xen-backwards-time.patch	17 Oct 2007 19:26:57 -0000	1.1.4.1
@@ -7,11 +7,11 @@
 x86 time: Ensure gettimeofday() is monotonically increasing.
 Signed-off-by: Atsushi SAKAI <sakaia at jp.fujitsu.com>
 
-Index: linux-2.6.20.i386/arch/i386/kernel/time-xen.c
+Index: linux-2.6.21.i386/arch/i386/kernel/time-xen.c
 ===================================================================
---- linux-2.6.20.i386.orig/arch/i386/kernel/time-xen.c
-+++ linux-2.6.20.i386/arch/i386/kernel/time-xen.c
-@@ -109,6 +109,9 @@ static DEFINE_PER_CPU(struct shadow_time
+--- linux-2.6.21.i386.orig/arch/i386/kernel/time-xen.c
++++ linux-2.6.21.i386/arch/i386/kernel/time-xen.c
+@@ -107,6 +107,9 @@ static DEFINE_PER_CPU(struct shadow_time
  static struct timespec shadow_tv;
  static u32 shadow_tv_version;
  
@@ -21,7 +21,7 @@
  /* Keep track of last time we did processing/updating of jiffies and xtime. */
  static u64 processed_system_time;   /* System time (ns) at last processing. */
  static DEFINE_PER_CPU(u64, processed_system_time);
-@@ -324,6 +327,7 @@ void do_gettimeofday(struct timeval *tv)
+@@ -322,6 +325,7 @@ void do_gettimeofday(struct timeval *tv)
  	unsigned long seq;
  	unsigned long usec, sec;
  	unsigned long max_ntp_tick;
@@ -29,7 +29,7 @@
  	s64 nsec;
  	unsigned int cpu;
  	struct shadow_time_info *shadow;
-@@ -376,6 +380,18 @@ void do_gettimeofday(struct timeval *tv)
+@@ -374,6 +378,18 @@ void do_gettimeofday(struct timeval *tv)
  		sec++;
  	}
  
@@ -48,7 +48,7 @@
  	tv->tv_sec = sec;
  	tv->tv_usec = usec;
  }
-@@ -425,6 +441,12 @@ int do_settimeofday(struct timespec *tv)
+@@ -423,6 +439,12 @@ int do_settimeofday(struct timespec *tv)
  		__update_wallclock(sec, nsec);
  	}
  

linux-2.6-xen-blkfront-wait-add.patch:

Index: linux-2.6-xen-blkfront-wait-add.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel-xen-2.6/F-7/linux-2.6-xen-blkfront-wait-add.patch,v
retrieving revision 1.1
retrieving revision 1.1.4.1
diff -u -r1.1 -r1.1.4.1
--- linux-2.6-xen-blkfront-wait-add.patch	17 Jul 2007 13:44:59 -0000	1.1
+++ linux-2.6-xen-blkfront-wait-add.patch	17 Oct 2007 19:26:57 -0000	1.1.4.1
@@ -1,8 +1,8 @@
-Index: linux-2.6.20.i386/drivers/xen/blkfront/blkfront.c
+Index: patching/drivers/xen/blkfront/blkfront.c
 ===================================================================
---- linux-2.6.20.i386.orig/drivers/xen/blkfront/blkfront.c
-+++ linux-2.6.20.i386/drivers/xen/blkfront/blkfront.c
-@@ -343,6 +343,8 @@ static void connect(struct blkfront_info
+--- patching.orig/drivers/xen/blkfront/blkfront.c
++++ patching/drivers/xen/blkfront/blkfront.c
+@@ -354,6 +354,8 @@ static void connect(struct blkfront_info
  	spin_unlock_irq(&blkif_io_lock);
  
  	add_disk(info->gd);
@@ -11,7 +11,7 @@
  }
  
  /**
-@@ -852,6 +854,13 @@ static void blkif_recover(struct blkfron
+@@ -863,6 +865,13 @@ static void blkif_recover(struct blkfron
  	spin_unlock_irq(&blkif_io_lock);
  }
  
@@ -25,7 +25,7 @@
  
  /* ** Driver Registration ** */
  
-@@ -870,6 +879,7 @@ static struct xenbus_driver blkfront = {
+@@ -881,6 +890,7 @@ static struct xenbus_driver blkfront = {
  	.remove = blkfront_remove,
  	.resume = blkfront_resume,
  	.otherend_changed = backend_changed,
@@ -33,11 +33,11 @@
  };
  
  
-Index: linux-2.6.20.i386/drivers/xen/blkfront/block.h
+Index: patching/drivers/xen/blkfront/block.h
 ===================================================================
---- linux-2.6.20.i386.orig/drivers/xen/blkfront/block.h
-+++ linux-2.6.20.i386/drivers/xen/blkfront/block.h
-@@ -125,6 +125,7 @@ struct blkfront_info
+--- patching.orig/drivers/xen/blkfront/block.h
++++ patching/drivers/xen/blkfront/block.h
+@@ -111,6 +111,7 @@ struct blkfront_info
  	struct blk_shadow shadow[BLK_RING_SIZE];
  	unsigned long shadow_free;
  	int feature_barrier;
@@ -45,11 +45,11 @@
  
  	/**
  	 * The number of people holding this device open.  We won't allow a
-Index: linux-2.6.20.i386/drivers/xen/xenbus/xenbus_probe.c
+Index: patching/drivers/xen/xenbus/xenbus_probe.c
 ===================================================================
---- linux-2.6.20.i386.orig/drivers/xen/xenbus/xenbus_probe.c
-+++ linux-2.6.20.i386/drivers/xen/xenbus/xenbus_probe.c
-@@ -940,6 +940,7 @@ static int is_disconnected_device(struct
+--- patching.orig/drivers/xen/xenbus/xenbus_probe.c
++++ patching/drivers/xen/xenbus/xenbus_probe.c
+@@ -995,6 +995,7 @@ static int is_disconnected_device(struct
  {
  	struct xenbus_device *xendev = to_xenbus_device(dev);
  	struct device_driver *drv = data;
@@ -57,7 +57,7 @@
  
  	/*
  	 * A device with no driver will never connect. We care only about
-@@ -952,7 +953,9 @@ static int is_disconnected_device(struct
+@@ -1007,7 +1008,9 @@ static int is_disconnected_device(struct
  	if (drv && (dev->driver != drv))
  		return 0;
  
@@ -68,11 +68,11 @@
  }
  
  static int exists_disconnected_device(struct device_driver *drv)
-Index: linux-2.6.20.i386/include/xen/xenbus.h
+Index: patching/include/xen/xenbus.h
 ===================================================================
---- linux-2.6.20.i386.orig/include/xen/xenbus.h
-+++ linux-2.6.20.i386/include/xen/xenbus.h
-@@ -105,6 +105,7 @@ struct xenbus_driver {
+--- patching.orig/include/xen/xenbus.h
++++ patching/include/xen/xenbus.h
+@@ -106,6 +106,7 @@ struct xenbus_driver {
  	int (*uevent)(struct xenbus_device *, char **, int, char *, int);
  	struct device_driver driver;
  	int (*read_otherend_details)(struct xenbus_device *dev);


Index: sources
===================================================================
RCS file: /cvs/pkgs/rpms/kernel-xen-2.6/F-7/sources,v
retrieving revision 1.6
retrieving revision 1.6.4.1
diff -u -r1.6 -r1.6.4.1
--- sources	17 Jul 2007 14:21:11 -0000	1.6
+++ sources	17 Oct 2007 19:26:57 -0000	1.6.4.1
@@ -1,3 +1,4 @@
-34b0f354819217e6a345f48ebbd8f13e  linux-2.6.20.tar.bz2
+1b515f588078dfa7f4bab2634bd17e80  linux-2.6.21.tar.bz2
+b9c8734471a454806c77f040fcf9869b  patch-2.6.21.7.bz2
 b73a966a55f3907020a1a29b4e2df64d  xen-3.1.0-rc7-7041b52471c3.tar.bz2
-126867078011af577963b0e946013a56  patch-2.6.20.14.bz2
+0b7a1468bcd3353b77494cbf0e97d2e4  linux-2.6.21.7-xen-3.1.0.patch.bz2

xen-compile-fix.patch:

Index: xen-compile-fix.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel-xen-2.6/F-7/xen-compile-fix.patch,v
retrieving revision 1.2
retrieving revision 1.2.10.1
diff -u -r1.2 -r1.2.10.1
--- xen-compile-fix.patch	30 Apr 2007 22:09:41 -0000	1.2
+++ xen-compile-fix.patch	17 Oct 2007 19:26:57 -0000	1.2.10.1
@@ -1,7 +1,7 @@
-Index: xen/include/asm-x86/hvm/hvm.h
+Index: xen-3.1.0/xen/include/asm-x86/hvm/hvm.h
 ===================================================================
---- xen.orig/include/asm-x86/hvm/hvm.h
-+++ xen/include/asm-x86/hvm/hvm.h
+--- xen-3.1.0/xen/include/asm-x86/hvm/hvm.h
++++ xen-3.1.0/xen/include/asm-x86/hvm/hvm.h
 @@ -183,7 +183,7 @@ hvm_long_mode_enabled(struct vcpu *v)
      return hvm_funcs.long_mode_enabled(v);
  }

xen-version-strings.patch:

Index: xen-version-strings.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel-xen-2.6/F-7/xen-version-strings.patch,v
retrieving revision 1.3
retrieving revision 1.3.8.1
diff -u -r1.3 -r1.3.8.1
--- xen-version-strings.patch	7 May 2007 18:47:08 -0000	1.3
+++ xen-version-strings.patch	17 Oct 2007 19:26:57 -0000	1.3.8.1
@@ -1,7 +1,7 @@
-Index: xen/Makefile
+Index: xen-3.1.0/xen/Makefile
 ===================================================================
---- xen.orig/Makefile
-+++ xen/Makefile
+--- xen-3.1.0/xen/Makefile
++++ xen-3.1.0/xen/Makefile
 @@ -2,7 +2,11 @@
  # All other places this is stored (eg. compile.h) should be autogenerated.
  export XEN_VERSION       = 3

xen-vmx-fpu-ts-fix.patch:

Index: xen-vmx-fpu-ts-fix.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel-xen-2.6/F-7/xen-vmx-fpu-ts-fix.patch,v
retrieving revision 1.1
retrieving revision 1.1.4.1
diff -u -r1.1 -r1.1.4.1
--- xen-vmx-fpu-ts-fix.patch	21 Sep 2007 15:13:42 -0000	1.1
+++ xen-vmx-fpu-ts-fix.patch	17 Oct 2007 19:26:57 -0000	1.1.4.1
@@ -12,8 +12,8 @@
 xen-unstable date: Mon Jun 04 16:47:48 2007 +0100
 
 diff -r eec47edb2a25 -r 8c24767501ff xen/arch/x86/hvm/vmx/vmcs.c
---- xen/arch/x86/hvm/vmx/vmcs.c	Fri Sep 14 16:33:37 2007 +0100
-+++ xen/arch/x86/hvm/vmx/vmcs.c	Fri Sep 14 16:33:37 2007 +0100
+--- a/xen/arch/x86/hvm/vmx/vmcs.c	Fri Sep 14 16:33:37 2007 +0100
++++ b/xen/arch/x86/hvm/vmx/vmcs.c	Fri Sep 14 16:33:37 2007 +0100
 @@ -338,7 +338,7 @@ static void construct_vmcs(struct vcpu *
  #endif
  

xen-vpic-irqbase-mode.patch:

Index: xen-vpic-irqbase-mode.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel-xen-2.6/F-7/xen-vpic-irqbase-mode.patch,v
retrieving revision 1.1
retrieving revision 1.1.4.1
diff -u -r1.1 -r1.1.4.1
--- xen-vpic-irqbase-mode.patch	13 Sep 2007 19:57:59 -0000	1.1
+++ xen-vpic-irqbase-mode.patch	17 Oct 2007 19:26:57 -0000	1.1.4.1
@@ -12,10 +12,10 @@
 xen-unstable changeset: 15239:656b8175f4f24b5bb3a761e62c496075510914ed
 xen-unstable date: Fri Jun 08 11:19:55 2007 +0100
 
-Index: xen/arch/x86/hvm/vmx/vmx.c
+Index: xen-3.1-testing-32/xen/arch/x86/hvm/vmx/vmx.c
 ===================================================================
---- xen/arch/x86/hvm/vmx/vmx.c
-+++ xen/arch/x86/hvm/vmx/vmx.c
+--- xen-3.1-testing-32.orig/xen/arch/x86/hvm/vmx/vmx.c
++++ xen-3.1-testing-32/xen/arch/x86/hvm/vmx/vmx.c
 @@ -1878,8 +1878,8 @@ enum { VMX_ASSIST_INVOKE = 0, VMX_ASSIST
  static int vmx_assist(struct vcpu *v, int mode)
  {
@@ -52,10 +52,10 @@
              v->arch.hvm_vmx.vmxassist_enabled = 0;
              return 1;
          }
-Index: xen/arch/x86/hvm/vpic.c
+Index: xen-3.1-testing-32/xen/arch/x86/hvm/vpic.c
 ===================================================================
---- xen/arch/x86/hvm/vpic.c
-+++ xen/arch/x86/hvm/vpic.c
+--- xen-3.1-testing-32.orig/xen/arch/x86/hvm/vpic.c
++++ xen-3.1-testing-32/xen/arch/x86/hvm/vpic.c
 @@ -174,7 +174,8 @@ static int vpic_intack(struct hvm_hw_vpi
      return irq;
  }
@@ -78,10 +78,10 @@
              /* ICW2 */
              vpic->irq_base = val & 0xf8;
              vpic->init_state++;
-Index: xen/include/asm-x86/hvm/vmx/vmcs.h
+Index: xen-3.1-testing-32/xen/include/asm-x86/hvm/vmx/vmcs.h
 ===================================================================
---- xen/include/asm-x86/hvm/vmx/vmcs.h
-+++ xen/include/asm-x86/hvm/vmx/vmcs.h
+--- xen-3.1-testing-32.orig/xen/include/asm-x86/hvm/vmx/vmcs.h
++++ xen-3.1-testing-32/xen/include/asm-x86/hvm/vmx/vmcs.h
 @@ -77,7 +77,11 @@ struct arch_vmx_struct {
      unsigned long        cpu_cr2; /* save CR2 */
      unsigned long        cpu_cr3;
@@ -94,10 +94,10 @@
  };
  
  struct vmcs_struct *vmx_alloc_host_vmcs(void);
-Index: xen/include/public/hvm/vmx_assist.h
+Index: xen-3.1-testing-32/xen/include/public/hvm/vmx_assist.h
 ===================================================================
---- xen/include/public/hvm/vmx_assist.h
-+++ xen/include/public/hvm/vmx_assist.h
+--- xen-3.1-testing-32.orig/xen/include/public/hvm/vmx_assist.h
++++ xen-3.1-testing-32/xen/include/public/hvm/vmx_assist.h
 @@ -35,6 +35,10 @@
  
  #ifndef __ASSEMBLY__


--- config-olpc-generic DELETED ---


--- git-geode.patch DELETED ---


--- kernel-2.6.20-i586.config DELETED ---


--- kernel-2.6.20-i686-PAE-debug.config DELETED ---


--- kernel-2.6.20-i686-PAE.config DELETED ---


--- kernel-2.6.20-i686-debug.config DELETED ---


--- kernel-2.6.20-i686-xen.config DELETED ---


--- kernel-2.6.20-i686.config DELETED ---


--- kernel-2.6.20-ia64-xen.config DELETED ---


--- kernel-2.6.20-ia64.config DELETED ---


--- kernel-2.6.20-ppc-smp.config DELETED ---


--- kernel-2.6.20-ppc.config DELETED ---


--- kernel-2.6.20-ppc64-kdump.config DELETED ---


--- kernel-2.6.20-ppc64.config DELETED ---


--- kernel-2.6.20-ppc64iseries-kdump.config DELETED ---


--- kernel-2.6.20-ppc64iseries.config DELETED ---


--- kernel-2.6.20-s390.config DELETED ---


--- kernel-2.6.20-s390x.config DELETED ---


--- kernel-2.6.20-x86_64-debug.config DELETED ---


--- kernel-2.6.20-x86_64-kdump.config DELETED ---


--- kernel-2.6.20-x86_64-xen.config DELETED ---


--- kernel-2.6.20-x86_64.config DELETED ---


--- kernel-xen.spec DELETED ---


--- linux-2.6-NFSD-badness.patch DELETED ---


--- linux-2.6-NFSD-ctlbits.patch DELETED ---


--- linux-2.6-build-input-not-embedded.patch DELETED ---


--- linux-2.6-cachefiles.patch DELETED ---


--- linux-2.6-cafe-nand.patch DELETED ---


--- linux-2.6-cell-mambo-drivers.patch DELETED ---


--- linux-2.6-cpufreq-unload-smi.patch DELETED ---


--- linux-2.6-csum-missing-line.patch DELETED ---


--- linux-2.6-debug-Wundef.patch DELETED ---


--- linux-2.6-debug-disable-builtins.patch DELETED ---


--- linux-2.6-debug-sleep-in-irq-warning.patch DELETED ---


--- linux-2.6-debug-verbosify-bug.patch DELETED ---


--- linux-2.6-defaults-disable-split-ptlock.patch DELETED ---


--- linux-2.6-defaults-firmware-loader-timeout.patch DELETED ---


--- linux-2.6-defaults-phys-start.patch DELETED ---


--- linux-2.6-drivers-add-qlogic-firmware.patch DELETED ---


--- linux-2.6-fix-x86_64-vgetcpu.patch DELETED ---


--- linux-2.6-forwarding_of_ip_summed.patch DELETED ---


--- linux-2.6-gfs2-locking-exports.patch DELETED ---


--- linux-2.6-gfs2-tux.patch DELETED ---


--- linux-2.6-hvc-console.patch DELETED ---


--- linux-2.6-ia64-kexec-kdump-xen-conflict.patch DELETED ---


--- linux-2.6-ips-softlockup.patch DELETED ---


--- linux-2.6-kill_skbuff_hack.patch DELETED ---


--- linux-2.6-lockdep-fixes.patch DELETED ---


--- linux-2.6-mac-raid-autorun.patch DELETED ---


--- linux-2.6-marvell-88alp01.patch DELETED ---


--- linux-2.6-marvell-update.patch DELETED ---


--- linux-2.6-mm-prevent-oom-fixes.patch DELETED ---


--- linux-2.6-mpc52xx-ata.patch DELETED ---


--- linux-2.6-mtd-update.patch DELETED ---


--- linux-2.6-net-forcedeth-suspend.patch DELETED ---


--- linux-2.6-obsolete-oss-warning.patch DELETED ---


--- linux-2.6-ohci-multi-init.patch DELETED ---


--- linux-2.6-ohci-platform-bus.patch DELETED ---


--- linux-2.6-olpc-battery.patch DELETED ---


--- linux-2.6-olpc-dcon.patch DELETED ---


--- linux-2.6-power6-no-ci-large-page.patch DELETED ---


--- linux-2.6-ppc-iseries-input-layer.patch DELETED ---


--- linux-2.6-ppc-rtas-check.patch DELETED ---


--- linux-2.6-sata-ahci-suspend.patch DELETED ---


--- linux-2.6-sata-pata-piix3.patch DELETED ---


--- linux-2.6-sata-promise-pata-ports.patch DELETED ---


--- linux-2.6-sata-sg_init_one-oops.patch DELETED ---


--- linux-2.6-serial-tickle-nmi.patch DELETED ---


--- linux-2.6-sleepon.patch DELETED ---


--- linux-2.6-softcursor-persistent-alloc.patch DELETED ---


--- linux-2.6-sysprof-1.0.3.patch DELETED ---


--- linux-2.6-systemsim-work.patch DELETED ---


--- linux-2.6-treat_partial_as_unnecessary.patch DELETED ---


--- linux-2.6-tux.patch DELETED ---


--- linux-2.6-usb-endian-ehci.patch DELETED ---


--- linux-2.6-usb-endian-quirks.patch DELETED ---


--- linux-2.6-usb-endian-toshiba.patch DELETED ---


--- linux-2.6-usb-storage-reboot.patch DELETED ---


--- linux-2.6-use_csum_start_offset_instead.patch DELETED ---


--- linux-2.6-utrace.patch DELETED ---


--- linux-2.6-vm-debug.patch DELETED ---


--- linux-2.6-warn-c-p-a.patch DELETED ---


--- linux-2.6-x86-apic-auto.patch DELETED ---


--- linux-2.6-xen-add-packet_auxdata-cmsg-1.patch DELETED ---


--- linux-2.6-xen-add-packet_auxdata-cmsg-2.patch DELETED ---


--- linux-2.6-xen-af_packet-no-skb_checksum_setup.patch DELETED ---


--- linux-2.6-xen-execshield.patch DELETED ---


--- linux-2.6-xen-iscsi-x86_64-no_iommu_init.patch DELETED ---


--- linux-2.6-xen-tux.patch DELETED ---


--- linux-2.6-xen-utrace.patch DELETED ---


--- linux-2.6-xen-x86_64-silence-up-apic-errors.patch DELETED ---


--- linux-2.6-xfs-umount-fix.patch DELETED ---


--- linux-2.6-xfs_attr2.patch DELETED ---


--- linux-2.6.20.14-xen-3.1.0.patch DELETED ---


--- linux-2.6.20.tar.bz2.sign DELETED ---




More information about the fedora-extras-commits mailing list