rpms/kernel-xen-2.6/F-7 Makefile.config, 1.1, 1.2 config-debug, 1.1, 1.2 config-generic, 1.1, 1.2 config-i586, 1.1, 1.2 config-i686, 1.1, 1.2 config-i686-PAE, 1.1, 1.2 config-ia64, 1.1, 1.2 config-ia64-generic, 1.1, 1.2 config-nodebug, 1.1, 1.2 config-powerpc-generic, 1.1, 1.2 config-powerpc32-generic, 1.1, 1.2 config-powerpc32-smp, 1.1, 1.2 config-powerpc64, 1.1, 1.2 config-powerpc64-kdump, 1.1, 1.2 config-s390x, 1.1, 1.2 config-sparc, 1.1, 1.2 config-sparc-generic, 1.1, 1.2 config-sparc-smp, 1.1, 1.2 config-sparc64, 1.1, 1.2 config-sparc64-generic, 1.1, 1.2 config-sparc64-smp, 1.1, 1.2 config-x86-generic, 1.1, 1.2 config-x86_64-generic, 1.1, 1.2 config-xen-generic, 1.1, 1.2 config-xen-ia64, 1.1, 1.2 config-xen-x86, 1.1, 1.2 config-xen-x86_64, 1.1, 1.2 drm-mm-git.patch, 1.1, 1.2 gen-patches, 1.1, 1.2 git-wireless-dev.patch, 1.1, 1.2 kernel-2.6.21-i686-xen.config, 1.1, 1.2 kernel-2.6.21-x86_64-xen.config, 1.1, 1.2 kernel.spec, 1.1, 1.2 linux-2.6-2110_scsi-sd-printing.patch, 1.1, 1.2 linux-2.6-2111_sd-start-stop.patch, 1.1, 1.2 linux-2.6-2112_libata-suspend.patch, 1.1, 1.2 linux-2.6-2113_libata-spindown-compat.patch, 1.1, 1.2 linux-2.6-2114_libata-shutdown-warning.patch, 1.1, 1.2 linux-2.6-2115_libata-spindown-status.patch, 1.1, 1.2 linux-2.6-2116_libata-remove-spindown-compat.patch, 1.1, 1.2 linux-2.6-2117_sata-via-suspend.patch, 1.1, 1.2 linux-2.6-2118_scsi-constants.patch, 1.1, 1.2 linux-2.6-acpi-boot-regression.patch, 1.1, 1.2 linux-2.6-acpi-dock-oops.patch, 1.1, 1.2 linux-2.6-acpi-git-ec-init-fixes.patch, 1.1, 1.2 linux-2.6-acpi-keep-tsc-stable-when-lapic-timer-c2-ok-is-set.patch, 1.1, 1.2 linux-2.6-acpi-preserve-ebx-in-acpi_copy_wakeup_routine.patch, 1.1, 1.2 linux-2.6-acpi-unblacklist-dell-gx240.patch, 1.1, 1.2 linux-2.6-add-mmf_dump_elf_headers.patch, 1.1, 1.2 linux-2.6-add-sys-module-name-notes.patch, 1.1, 1.2 linux-2.6-amd-disabled-svm-detect-msr-1.patch, 1.1, 1.2 linux-2.6-amd-disabled-svm-detect.patch, 1.1, 1.2 linux-2.6-at76.patch, 1.1, 1.2 linux-2.6-ata-call-check-dma-with-qc-prepared.patch, 1.1, 1.2 linux-2.6-ata-quirk.patch, 1.1, 1.2 linux-2.6-ata-use-pio-for-non-16-byte-xfers.patch, 1.1, 1.2 linux-2.6-ath5k.patch, 1.1, 1.2 linux-2.6-bcm43xx-pci-neuter.patch, 1.1, 1.2 linux-2.6-cell-spu-device-tree.patch, 1.1, 1.2 linux-2.6-cell-spufs-fixes.patch, 1.1, 1.2 linux-2.6-clockevents-fix-resume-logic.patch, 1.1, 1.2 linux-2.6-crap-sysfs-workaround.patch, 1.1, 1.2 linux-2.6-debug-acpi-os-write-port.patch, 1.1, 1.2 linux-2.6-debug-extra-warnings.patch, 1.1, 1.2 linux-2.6-debug-nmi-timeout.patch, 1.1, 1.2 linux-2.6-default-mmf_dump_elf_headers.patch, 1.1, 1.2 linux-2.6-defaults-pci_no_msi_mmconf.patch, 1.1, 1.2 linux-2.6-drivers-ssb-debug-revision.patch, 1.1, 1.2 linux-2.6-dvb-spinlock.patch, 1.1, 1.2 linux-2.6-e1000-corrupt-eeprom-checksum.patch, 1.1, 1.2 linux-2.6-execshield-xen.patch, 1.1, 1.2 linux-2.6-firewire-be32-fix.patch, 1.1, 1.2 linux-2.6-firewire-lockdep.patch, 1.1, 1.2 linux-2.6-firewire-multi-lun.patch, 1.1, 1.2 linux-2.6-fix-pmops-1.patch, 1.1, 1.2 linux-2.6-fix-pmops-2.patch, 1.1, 1.2 linux-2.6-fix-pmops-3.patch, 1.1, 1.2 linux-2.6-fix-pmops-4.patch, 1.1, 1.2 linux-2.6-gfs-locking-exports.patch, 1.1, 1.2 linux-2.6-highres-timers.patch, 1.1, 1.2 linux-2.6-i386-vdso-install-unstripped-copies-on-disk.patch, 1.1, 1.2 linux-2.6-i82875-edac-pci-setup.patch, 1.1, 1.2 linux-2.6-i965gm-support.patch, 1.1, 1.2 linux-2.6-iwlwifi-fixes.patch, 1.1, 1.2 linux-2.6-kvm-19.patch, 1.1, 1.2 linux-2.6-kvm-reinit-real-mode-tss.patch, 1.1, 1.2 linux-2.6-libata-acpi-enable.patch, 1.1, 1.2 linux-2.6-libata-ali-atapi-dma.patch, 1.1, 1.2 linux-2.6-libata-atiixp-ids.patch, 1.1, 1.2 linux-2.6-libata-hpa.patch, 1.1, 1.2 linux-2.6-libata-ich8m-add-pciid.patch, 1.1, 1.2 linux-2.6-libata-ncq-blacklist-2.6.22-rc7.patch, 1.1, 1.2 linux-2.6-libata-pata-dma-disable-option.patch, 1.1, 1.2 linux-2.6-libata-pata-hpt3x2n-correct-revision-boundary.patch, 1.1, 1.2 linux-2.6-libata-pata-pcmcia-new-ident.patch, 1.1, 1.2 linux-2.6-libata-pata-sis-fix-timing.patch, 1.1, 1.2 linux-2.6-libata-pata_dma-param.patch, 1.1, 1.2 linux-2.6-libata-pata_it821x-partly-fix-dma.patch, 1.1, 1.2 linux-2.6-libata-sata_nv-adma.patch, 1.1, 1.2 linux-2.6-libata-sata_nv-wildcard-removal.patch, 1.1, 1.2 linux-2.6-libata-setxfer.patch, 1.1, 1.2 linux-2.6-libata_ali_max_dma_speed.patch, 1.1, 1.2 linux-2.6-lirc.patch, 1.1, 1.2 linux-2.6-mac80211-extras.patch, 1.1, 1.2 linux-2.6-mac80211-nm-hidden-ssid.patch, 1.1, 1.2 linux-2.6-mm-udf-fixes.patch, 1.1, 1.2 linux-2.6-mpc52xx-fec.patch, 1.1, 1.2 linux-2.6-mpc52xx-sdma.patch, 1.1, 1.2 linux-2.6-net-e1000-no-msi-warning.patch, 1.1, 1.2 linux-2.6-net-silence-noisy-printks.patch, 1.1, 1.2 linux-2.6-netdev-e1000e-01.patch, 1.1, 1.2 linux-2.6-netdev-e1000e-02.patch, 1.1, 1.2 linux-2.6-netdev-e1000e-03.patch, 1.1, 1.2 linux-2.6-netdev-e1000e-04.patch, 1.1, 1.2 linux-2.6-netdev-e1000e-05.patch, 1.1, 1.2 linux-2.6-netdev-e1000e-06.patch, 1.1, 1.2 linux-2.6-netdev-e1000e-07.patch, 1.1, 1.2 linux-2.6-netdev-e1000e-08.patch, 1.1, 1.2 linux-2.6-netdev-e1000e-09.patch, 1.1, 1.2 linux-2.6-netdev-e1000e-10.patch, 1.1, 1.2 linux-2.6-nfs-missing-braces.patch, 1.1, 1.2 linux-2.6-nfs-noreaddirplus.patch, 1.1, 1.2 linux-2.6-ondemand-timer.patch, 1.1, 1.2 linux-2.6-pass-g-to-assembler-under-config_debug_info.patch, 1.1, 1.2 linux-2.6-pmac-zilog.patch, 1.1, 1.2 linux-2.6-pmtrace-time-fix.patch, 1.1, 1.2 linux-2.6-powermac-generic-suspend-1.patch, 1.1, 1.2 linux-2.6-powermac-generic-suspend-2.patch, 1.1, 1.2 linux-2.6-powermac-generic-suspend-3.patch, 1.1, 1.2 linux-2.6-powermac-generic-suspend-4.patch, 1.1, 1.2 linux-2.6-powerpc-generic-suspend-2-remove-adb-sleep-notifier.patch, 1.1, 1.2 linux-2.6-powerpc-generic-suspend-3-remove-dmasound.patch, 1.1, 1.2 linux-2.6-powerpc-generic-suspend-4-kill-pmu-sleep-notifier.patch, 1.1, 1.2 linux-2.6-powerpc-generic-suspend-5-pmu-pm_ops.patch, 1.1, 1.2 linux-2.6-powerpc-lparmap-g.patch, 1.1, 1.2 linux-2.6-powerpc-reserve-initrd-1.patch, 1.1, 1.2 linux-2.6-powerpc-reserve-initrd-2.patch, 1.1, 1.2 linux-2.6-powerpc-slabalign.patch, 1.1, 1.2 linux-2.6-powerpc-spu-vicinity.patch, 1.1, 1.2 linux-2.6-powerpc-vdso-install-unstripped-copies-on-disk.patch, 1.1, 1.2 linux-2.6-ppc-data-exception.patch, 1.1, 1.2 linux-2.6-ppc-pegasos-via-ata-legacy-irq.patch, 1.1, 1.2 linux-2.6-ps3-clear-spu-irq.patch, 1.1, 1.2 linux-2.6-ps3-device-init.patch, 1.1, 1.2 linux-2.6-ps3-ehci-iso.patch, 1.1, 1.2 linux-2.6-ps3-ethernet-autoload.patch, 1.1, 1.2 linux-2.6-ps3-ethernet-modular.patch, 1.1, 1.2 linux-2.6-ps3-gelic-wireless.patch, 1.1, 1.2 linux-2.6-ps3-gelic.patch, 1.1, 1.2 linux-2.6-ps3-kexec.patch, 1.1, 1.2 linux-2.6-ps3-legacy-bootloader-hack.patch, 1.1, 1.2 linux-2.6-ps3-legacy-ioport.patch, 1.1, 1.2 linux-2.6-ps3-memory-probe.patch, 1.1, 1.2 linux-2.6-ps3-smp-boot.patch, 1.1, 1.2 linux-2.6-ps3-sound-autoload.patch, 1.1, 1.2 linux-2.6-ps3-sound.patch, 1.1, 1.2 linux-2.6-ps3-stable-patches.patch, 1.1, 1.2 linux-2.6-ps3-storage-alias.patch, 1.1, 1.2 linux-2.6-ps3-storage.patch, 1.1, 1.2 linux-2.6-ps3-system-bus-rework-2.patch, 1.1, 1.2 linux-2.6-ps3-system-bus-rework.patch, 1.1, 1.2 linux-2.6-ps3-usb-autoload.patch, 1.1, 1.2 linux-2.6-ps3-wrap-spu-runctl.patch, 1.1, 1.2 linux-2.6-ps3av-export-header.patch, 1.1, 1.2 linux-2.6-ps3fb-panic.patch, 1.1, 1.2 linux-2.6-scsi-async-double-add.patch, 1.1, 1.2 linux-2.6-scsi-bounce-isa.patch, 1.1, 1.2 linux-2.6-scsi-mpt-vmware-fix.patch, 1.1, 1.2 linux-2.6-smarter-relatime.patch, 1.1, 1.2 linux-2.6-softirq-printout-irq-trace-events.patch, 1.1, 1.2 linux-2.6-suspend-ordering.patch, 1.1, 1.2 linux-2.6-sysfs-inode-allocator-oops.patch, 1.1, 1.2 linux-2.6-udf-2.6.22-rc2-1-udf_data_corruption.patch, 1.1, 1.2 linux-2.6-udf-2.6.22-rc4-1-udf_block_leak.patch, 1.1, 1.2 linux-2.6-usb-autosuspend-default-disable.patch, 1.1, 1.2 linux-2.6-usb-storage-initialize-huawei-e220-properly.patch, 1.1, 1.2 linux-2.6-usb-suspend-classes.patch, 1.1, 1.2 linux-2.6-utrace-core.patch, 1.1, 1.2 linux-2.6-utrace-ptrace-compat-avr32.patch, 1.1, 1.2 linux-2.6-utrace-ptrace-compat-ia64.patch, 1.1, 1.2 linux-2.6-utrace-ptrace-compat-s390.patch, 1.1, 1.2 linux-2.6-utrace-ptrace-compat-sparc64.patch, 1.1, 1.2 linux-2.6-utrace-ptrace-compat-xen.patch, 1.1, 1.2 linux-2.6-utrace-ptrace-compat.patch, 1.1, 1.2 linux-2.6-utrace-recalc_sigpending_and_wake.patch, 1.1, 1.2 linux-2.6-utrace-regset-avr32.patch, 1.1, 1.2 linux-2.6-utrace-regset-ia64.patch, 1.1, 1.2 linux-2.6-utrace-regset-s390.patch, 1.1, 1.2 linux-2.6-utrace-regset-sparc64.patch, 1.1, 1.2 linux-2.6-utrace-regset.patch, 1.1, 1.2 linux-2.6-utrace-sig_kernel-macros.patch, 1.1, 1.2 linux-2.6-utrace-tracehook-avr32.patch, 1.1, 1.2 linux-2.6-utrace-tracehook-ia64.patch, 1.1, 1.2 linux-2.6-utrace-tracehook-s390.patch, 1.1, 1.2 linux-2.6-utrace-tracehook-sparc64.patch, 1.1, 1.2 linux-2.6-utrace-tracehook-um.patch, 1.1, 1.2 linux-2.6-utrace-tracehook-xen.patch, 1.1, 1.2 linux-2.6-utrace-tracehook.patch, 1.1, 1.2 linux-2.6-vm-invalidate_mapping_pages-cond-resched.patch, 1.1, 1.2 linux-2.6-wakeups-hdaps.patch, 1.1, 1.2 linux-2.6-wakeups.patch, 1.1, 1.2 linux-2.6-wireless.patch, 1.1, 1.2 linux-2.6-x86-64_pmtrace.patch, 1.1, 1.2 linux-2.6-x86-clean-up-oops-bug-reports.patch, 1.1, 1.2 linux-2.6-x86-debug-boot.patch, 1.1, 1.2 linux-2.6-x86-dell-hpet.patch, 1.1, 1.2 linux-2.6-x86-dont-delete-cpu_devs-data.patch, 1.1, 1.2 linux-2.6-x86-fsc-interrupt-controller-quirk.patch, 1.1, 1.2 linux-2.6-x86_64-ia32-vdso-install-unstripped-copies-on-disk.patch, 1.1, 1.2 linux-2.6-x86_64-silence-up-apic-errors-xen.patch, 1.1, 1.2 linux-2.6-x86_64-vdso-install-unstripped-copies-on-disk.patch, 1.1, 1.2 linux-2.6-xen-irq_vector-uninitialize.patch, 1.1, 1.2 linux-2.6-xfs-optimize-away-dmapi-tests.patch, 1.1, 1.2 linux-2.6-xfs-optimize-away-realtime-tests.patch, 1.1, 1.2 linux-2.6-xfs-refactor-xfs_mountfs.patch, 1.1, 1.2 linux-2.6-xfs-setfattr-32bit-compat.patch, 1.1, 1.2 linux-2.6-zd1211rw-mac80211.patch, 1.1, 1.2 linux-2.6.21.7-xen-3.1.0.patch.bz2, 1.1, 1.2 linux-2.6.21.tar.bz2.sign, 1.1, 1.2 linux-2.6.23.tar.bz2.sign, 1.1, 1.2 mirrors, 1.1, 1.2 nouveau-drm.patch, 1.1, 1.2 patch-2.6.21.7.bz2, 1.1, 1.2 patch-2.6.23-git2.bz2.sign, 1.1, 1.2 patch-2.6.23.1.bz2.sign, 1.1, 1.2 upstream, 1.1, 1.2 upstream-key.gpg, 1.1, 1.2 Config.mk, 1.1, 1.2 Makefile, 1.1, 1.2 config-rhel-generic, 1.1, 1.2 linux-2.6-common-uevent.patch, 1.1, 1.2 linux-2.6-compile-fixes.patch, 1.2, 1.3 linux-2.6-crash-driver-xen.patch, 1.1, 1.2 linux-2.6-crash-driver.patch, 1.1, 1.2 linux-2.6-debug-no-quiet.patch, 1.1, 1.2 linux-2.6-debug-sizeof-structs.patch, 1.1, 1.2 linux-2.6-debug-sysfs-crash-debugging-xen.patch, 1.1, 1.2 linux-2.6-debug-sysfs-crash-debugging.patch, 1.1, 1.2 linux-2.6-debug-taint-vm.patch, 1.2, 1.3 linux-2.6-devmem-xen.patch, 1.1, 1.2 linux-2.6-devmem.patch, 1.2, 1.3 linux-2.6-disable-netback-checksum.patch, 1.1, 1.2 linux-2.6-execshield.patch, 1.2, 1.3 linux-2.6-firewire.patch, 1.1, 1.2 linux-2.6-gfs2-update.patch, 1.1, 1.2 linux-2.6-modsign-core.patch, 1.2, 1.3 linux-2.6-modsign-crypto.patch, 1.2, 1.3 linux-2.6-modsign-include.patch, 1.2, 1.3 linux-2.6-modsign-ksign.patch, 1.2, 1.3 linux-2.6-modsign-mpilib.patch, 1.2, 1.3 linux-2.6-modsign-script.patch, 1.2, 1.3 linux-2.6-silence-noise.patch, 1.2, 1.3 linux-2.6-squashfs.patch, 1.2, 1.3 linux-2.6-xen-backwards-time.patch, 1.1, 1.2 linux-2.6-xen-blkfront-wait-add.patch, 1.1, 1.2 sources, 1.6, 1.7 xen-compile-fix.patch, 1.2, 1.3 xen-version-strings.patch, 1.3, 1.4 xen-vmx-fpu-ts-fix.patch, 1.1, 1.2 xen-vpic-irqbase-mode.patch, 1.1, 1.2 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 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
Mon Nov 12 12:59:47 UTC 2007
- Previous message: rpms/kernel-xen-2.6/F-7/scripts bumpspecfile.py, 1.1, 1.2 configcommon.pl, 1.1, 1.2 configdiff.pl, 1.1, 1.2 cross-amd64.sh, 1.1, 1.2 cross-i586.sh, 1.1, 1.2 cross-i686.sh, 1.1, 1.2 cross-ia64.sh, 1.1, 1.2 cross-iseries.sh, 1.1, 1.2 cross-ppc.sh, 1.1, 1.2 cross-ppc64.sh, 1.1, 1.2 cross-ppc8260.sh, 1.1, 1.2 cross-ppc8560.sh, 1.1, 1.2 cross-pseries.sh, 1.1, 1.2 cross-s390.sh, 1.1, 1.2 cross-s390x.sh, 1.1, 1.2 newpatch.sh, 1.1, 1.2 pull-upstreams.sh, 1.1, 1.2 rebase-xen-hv.sh, 1.1, 1.2 rebase-xen-kernel.sh, 1.1, 1.2 rebase.sh, 1.1, 1.2 reconfig.sh, 1.1, 1.2 rediffall.pl, 1.1, 1.2
- Next message: rpms/kernel-xen-2.6/F-7 kernel.spec,1.2,1.3
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Author: ehabkost
Update of /cvs/pkgs/rpms/kernel-xen-2.6/F-7
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv20157
Modified Files:
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:
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-i686-xen.config
kernel-2.6.21-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:
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
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:
Merging from private-ehabkost-debuginfo-branch
Index: Makefile.config
===================================================================
RCS file: Makefile.config
diff -N Makefile.config
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ Makefile.config 12 Nov 2007 12:56:58 -0000 1.2
@@ -0,0 +1,137 @@
+# Make rules for configuration files.
+#
+# $Id$
+
+CFG = kernel-$(VERSION)
+
+CONFIGFILES = \
+ $(CFG)-i586.config \
+ $(CFG)-i686.config $(CFG)-i686-PAE.config \
+ $(CFG)-i686-debug.config $(CFG)-i686-PAE-debug.config \
+ $(CFG)-x86_64.config $(CFG)-x86_64-debug.config \
+ $(CFG)-s390x.config \
+ $(CFG)-ppc.config $(CFG)-ppc-smp.config \
+ $(CFG)-sparc64.config $(CFG)-sparc64-smp.config \
+ $(CFG)-ppc64.config $(CFG)-ppc64-kdump.config $(CFG)-ia64.config \
+ $(CFG)-i686-xen.config $(CFG)-x86_64-xen.config \
+ $(CFG)-ia64-xen.config
+
+PLATFORMS = x86 x86_64 powerpc powerpc32 powerpc64 s390x ia64 sparc64 sparc
+TEMPFILES = $(addprefix temp-, $(addsuffix -generic, $(PLATFORMS)))
+
+configs: $(CONFIGFILES)
+ @rm -f kernel-*-config
+ @rm -f $(TEMPFILES)
+ @rm -f temp-generic temp-*-generic temp-*-generic-tmp
+
+# Augment the clean target to clean up our own cruft
+clean ::
+ @rm -fv $(CONFIGFILES) $(TEMPFILES) temp-generic kernel-$(VERSION)*config
+
+temp-generic: config-generic
+ cat config-generic config-nodebug > temp-generic
+
+temp-debug-generic: config-generic
+ cat config-generic config-debug > temp-debug-generic
+
+temp-x86-generic: config-x86-generic temp-generic
+ perl merge.pl $^ > $@
+
+temp-x86-debug-generic: config-x86-generic temp-debug-generic
+ perl merge.pl $^ > $@
+
+temp-x86_64-generic: config-x86_64-generic temp-generic
+ perl merge.pl $^ > $@
+
+temp-x86_64-debug-generic: config-x86_64-generic temp-debug-generic
+ perl merge.pl $^ > $@
+
+temp-sparc-generic: config-sparc-generic temp-generic
+ perl merge.pl $^ > $@
+
+temp-sparc64-generic: config-sparc64-generic temp-generic
+ perl merge.pl $^ > $@
+
+temp-powerpc-generic: config-powerpc-generic temp-generic
+ perl merge.pl $^ > $@
+
+temp-powerpc32-generic: config-powerpc32-generic temp-powerpc-generic
+ perl merge.pl $^ > $@
+
+temp-s390-generic: config-s390x temp-generic
+ perl merge.pl $^ > $@
+
+temp-ia64-generic: config-ia64-generic temp-generic
+ perl merge.pl $^ > $@
+
+temp-x86-xen-generic-tmp: config-xen-generic temp-x86-generic
+ perl merge.pl $^ > $@
+
+temp-x86-xen-generic: config-xen-x86 temp-x86-xen-generic-tmp
+ perl merge.pl $^ > $@
+
+temp-x86_64-xen-generic-tmp: config-xen-generic temp-x86_64-generic
+ perl merge.pl $^ > $@
+
+temp-x86_64-xen-generic: config-xen-x86_64 temp-x86_64-xen-generic-tmp
+ perl merge.pl $^ > $@
+
+temp-ia64-xen-generic: config-xen-generic temp-ia64-generic
+ perl merge.pl $^ > $@
+
+kernel-$(VERSION)-i686.config: config-i686 temp-x86-generic
+ perl merge.pl $^ i386 > $@
+
+kernel-$(VERSION)-i686-debug.config: config-i686 temp-x86-debug-generic
+ perl merge.pl $^ i386 > $@
+
+kernel-$(VERSION)-i686-PAE.config: config-i686-PAE temp-x86-generic
+ perl merge.pl $^ i386 > $@
+
+kernel-$(VERSION)-i686-PAE-debug.config: config-i686-PAE temp-x86-debug-generic
+ perl merge.pl $^ i386 > $@
+
+kernel-$(VERSION)-i586.config: config-i586 temp-x86-generic
+ perl merge.pl $^ i386 > $@
+
+kernel-$(VERSION)-x86_64.config: /dev/null temp-x86_64-generic
+ perl merge.pl $^ x86_64 > $@
+
+kernel-$(VERSION)-x86_64-debug.config: /dev/null temp-x86_64-debug-generic
+ perl merge.pl $^ x86_64 > $@
+
+kernel-$(VERSION)-sparc64-smp.config: config-sparc64-smp temp-sparc64-generic
+ perl merge.pl $^ sparc64 > $@
+
+kernel-$(VERSION)-sparc64.config: config-sparc64 temp-sparc64-generic
+ perl merge.pl $^ sparc64 > $@
+
+kernel-$(VERSION)-sparc.config: config-sparc temp-sparc-generic
+ perl merge.pl $^ sparc > $@
+
+kernel-$(VERSION)-ppc64.config: config-powerpc64 temp-powerpc-generic
+ perl merge.pl $^ powerpc > $@
+
+kernel-$(VERSION)-ppc64-kdump.config: config-powerpc64-kdump kernel-$(VERSION)-ppc64.config
+ perl merge.pl $^ powerpc > $@
+
+kernel-$(VERSION)-s390x.config: config-s390x temp-s390-generic
+ perl merge.pl $^ s390 > $@
+
+kernel-$(VERSION)-ppc.config: /dev/null temp-powerpc32-generic
+ perl merge.pl $^ powerpc > $@
+
+kernel-$(VERSION)-ppc-smp.config: config-powerpc32-smp temp-powerpc32-generic
+ perl merge.pl $^ powerpc > $@
+
+kernel-$(VERSION)-ia64.config: config-ia64 temp-ia64-generic
+ perl merge.pl $^ ia64 > $@
+
+kernel-$(VERSION)-i686-xen.config: config-i686-PAE temp-x86-xen-generic
+ perl merge.pl $^ i386 > $@
+
+kernel-$(VERSION)-x86_64-xen.config: /dev/null temp-x86_64-xen-generic
+ perl merge.pl $^ x86_64 > $@
+
+kernel-$(VERSION)-ia64-xen.config: config-xen-ia64 temp-ia64-xen-generic
+ perl merge.pl $^ ia64 > $@
Index: config-debug
===================================================================
RCS file: config-debug
diff -N config-debug
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ config-debug 12 Nov 2007 12:56:58 -0000 1.2
@@ -0,0 +1,28 @@
+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
\ No newline at end of file
View full diff with command:
/usr/bin/cvs -f diff -kk -u -N -r 1.1 -r 1.2 config-generic
Index: config-generic
===================================================================
RCS file: config-generic
diff -N config-generic
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ config-generic 12 Nov 2007 12:56:58 -0000 1.2
@@ -0,0 +1,3259 @@
+#
+# 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
[...2866 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
Index: config-i586
===================================================================
RCS file: config-i586
diff -N config-i586
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ config-i586 12 Nov 2007 12:56:58 -0000 1.2
@@ -0,0 +1,7 @@
+CONFIG_M586=y
+
+# CONFIG_NOHIGHMEM is not set
+CONFIG_HIGHMEM4G=y
+# CONFIG_HIGHMEM64G is not set
+
+CONFIG_X86_POWERNOW_K6=m
Index: config-i686
===================================================================
RCS file: config-i686
diff -N config-i686
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ config-i686 12 Nov 2007 12:56:58 -0000 1.2
@@ -0,0 +1,8 @@
+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
Index: config-i686-PAE
===================================================================
RCS file: config-i686-PAE
diff -N config-i686-PAE
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ config-i686-PAE 12 Nov 2007 12:56:58 -0000 1.2
@@ -0,0 +1,5 @@
+CONFIG_M686=y
+# CONFIG_NOHIGHMEM is not set
+# CONFIG_HIGHMEM4G is not set
+CONFIG_HIGHMEM64G=y
+
Index: config-ia64
===================================================================
RCS file: config-ia64
diff -N config-ia64
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ config-ia64 12 Nov 2007 12:56:58 -0000 1.2
@@ -0,0 +1,3 @@
+CONFIG_CRASH_DUMP=y
+CONFIG_PROC_VMCORE=y
+
Index: config-ia64-generic
===================================================================
RCS file: config-ia64-generic
diff -N config-ia64-generic
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ config-ia64-generic 12 Nov 2007 12:56:58 -0000 1.2
@@ -0,0 +1,187 @@
+#
+# 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
Index: config-nodebug
===================================================================
RCS file: config-nodebug
diff -N config-nodebug
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ config-nodebug 12 Nov 2007 12:56:58 -0000 1.2
@@ -0,0 +1,27 @@
+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
Index: config-powerpc-generic
===================================================================
RCS file: config-powerpc-generic
diff -N config-powerpc-generic
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ config-powerpc-generic 12 Nov 2007 12:56:58 -0000 1.2
@@ -0,0 +1,213 @@
+# 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
Index: config-powerpc32-generic
===================================================================
RCS file: config-powerpc32-generic
diff -N config-powerpc32-generic
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ config-powerpc32-generic 12 Nov 2007 12:56:58 -0000 1.2
@@ -0,0 +1,72 @@
+# 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
Index: config-powerpc32-smp
===================================================================
RCS file: config-powerpc32-smp
diff -N config-powerpc32-smp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ config-powerpc32-smp 12 Nov 2007 12:56:58 -0000 1.2
@@ -0,0 +1,4 @@
+CONFIG_SMP=y
+# CONFIG_HOTPLUG_CPU is not set
+CONFIG_NR_CPUS=4
+# CONFIG_BATTERY_PMU is not set
Index: config-powerpc64
===================================================================
RCS file: config-powerpc64
diff -N config-powerpc64
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ config-powerpc64 12 Nov 2007 12:56:58 -0000 1.2
@@ -0,0 +1,136 @@
+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
Index: config-powerpc64-kdump
===================================================================
RCS file: config-powerpc64-kdump
diff -N config-powerpc64-kdump
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ config-powerpc64-kdump 12 Nov 2007 12:56:58 -0000 1.2
@@ -0,0 +1,3 @@
+# CONFIG_EMBEDDED is not set
+CONFIG_CRASH_DUMP=y
+CONFIG_PROC_VMCORE=y
Index: config-s390x
===================================================================
RCS file: config-s390x
diff -N config-s390x
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ config-s390x 12 Nov 2007 12:56:58 -0000 1.2
@@ -0,0 +1,199 @@
+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
+
Index: config-sparc
===================================================================
RCS file: config-sparc
diff -N config-sparc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ config-sparc 12 Nov 2007 12:56:58 -0000 1.2
@@ -0,0 +1,10 @@
+# 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
Index: config-sparc-generic
===================================================================
RCS file: config-sparc-generic
diff -N config-sparc-generic
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ config-sparc-generic 12 Nov 2007 12:56:58 -0000 1.2
@@ -0,0 +1,154 @@
+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
Index: config-sparc-smp
===================================================================
RCS file: config-sparc-smp
diff -N config-sparc-smp
Index: config-sparc64
===================================================================
RCS file: config-sparc64
diff -N config-sparc64
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ config-sparc64 12 Nov 2007 12:56:58 -0000 1.2
@@ -0,0 +1,2 @@
+# CONFIG_SMP is not set
+
Index: config-sparc64-generic
===================================================================
RCS file: config-sparc64-generic
diff -N config-sparc64-generic
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ config-sparc64-generic 12 Nov 2007 12:56:58 -0000 1.2
@@ -0,0 +1,161 @@
+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
+
Index: config-sparc64-smp
===================================================================
RCS file: config-sparc64-smp
diff -N config-sparc64-smp
Index: config-x86-generic
===================================================================
RCS file: config-x86-generic
diff -N config-x86-generic
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ config-x86-generic 12 Nov 2007 12:56:58 -0000 1.2
@@ -0,0 +1,347 @@
+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
Index: config-x86_64-generic
===================================================================
RCS file: config-x86_64-generic
diff -N config-x86_64-generic
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ config-x86_64-generic 12 Nov 2007 12:56:58 -0000 1.2
@@ -0,0 +1,228 @@
+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
Index: config-xen-generic
===================================================================
RCS file: config-xen-generic
diff -N config-xen-generic
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ config-xen-generic 12 Nov 2007 12:56:58 -0000 1.2
@@ -0,0 +1,72 @@
+
+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
+
Index: config-xen-ia64
===================================================================
RCS file: config-xen-ia64
diff -N config-xen-ia64
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ config-xen-ia64 12 Nov 2007 12:56:58 -0000 1.2
@@ -0,0 +1,25 @@
+# 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
Index: config-xen-x86
===================================================================
RCS file: config-xen-x86
diff -N config-xen-x86
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ config-xen-x86 12 Nov 2007 12:56:58 -0000 1.2
@@ -0,0 +1,4 @@
+
+# CONFIG_X86_PC is not set
+CONFIG_X86_XEN=y
+# CONFIG_X86_GENERICARCH is not set
Index: config-xen-x86_64
===================================================================
RCS file: config-xen-x86_64
diff -N config-xen-x86_64
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ config-xen-x86_64 12 Nov 2007 12:56:58 -0000 1.2
@@ -0,0 +1,8 @@
+# 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:
View full diff with command:
/usr/bin/cvs -f diff -kk -u -N -r 1.1 -r 1.2 drm-mm-git.patch
Index: drm-mm-git.patch
===================================================================
RCS file: drm-mm-git.patch
diff -N drm-mm-git.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ drm-mm-git.patch 12 Nov 2007 12:56:58 -0000 1.2
@@ -0,0 +1,12430 @@
+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);
[...12037 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;
Index: gen-patches
===================================================================
RCS file: gen-patches
diff -N gen-patches
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ gen-patches 12 Nov 2007 12:56:58 -0000 1.2
@@ -0,0 +1,186 @@
+#!/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:
View full diff with command:
/usr/bin/cvs -f diff -kk -u -N -r 1.1 -r 1.2 git-wireless-dev.patch
Index: git-wireless-dev.patch
===================================================================
RCS file: git-wireless-dev.patch
diff -N git-wireless-dev.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ git-wireless-dev.patch 12 Nov 2007 12:56:58 -0000 1.2
@@ -0,0 +1,91408 @@
+--- 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
[...91015 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);
View full diff with command:
/usr/bin/cvs -f diff -kk -u -N -r 1.1 -r 1.2 kernel-2.6.21-i686-xen.config
Index: kernel-2.6.21-i686-xen.config
===================================================================
RCS file: kernel-2.6.21-i686-xen.config
diff -N kernel-2.6.21-i686-xen.config
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ kernel-2.6.21-i686-xen.config 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,3503 @@
+# 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
+
+#
[...3110 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
View full diff with command:
/usr/bin/cvs -f diff -kk -u -N -r 1.1 -r 1.2 kernel-2.6.21-x86_64-xen.config
Index: kernel-2.6.21-x86_64-xen.config
===================================================================
RCS file: kernel-2.6.21-x86_64-xen.config
diff -N kernel-2.6.21-x86_64-xen.config
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ kernel-2.6.21-x86_64-xen.config 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,3353 @@
+# 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
+#
+
[...2960 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
View full diff with command:
/usr/bin/cvs -f diff -kk -u -N -r 1.1 -r 1.2 kernel.spec
Index: kernel.spec
===================================================================
RCS file: kernel.spec
diff -N kernel.spec
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ kernel.spec 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,2270 @@
+# we are kernel-xen-2.6!
+%define xen_package_magic 1
+
+Summary: The Linux kernel (the core of the Linux operating system)
+
+# For a stable, released kernel, released_kernel should be 1. For rawhide
+# and/or a kernel built from an rc or git snapshot, released_kernel should
+# be 0.
+%define released_kernel 1
+
+# Versions of various parts
+
+# Polite request for people who spin their own kernel rpms:
+# please modify the "buildid" define in a way that identifies
+# that the kernel isn't the stock distribution kernel, for example,
+# by setting the define to ".local" or ".bz123456"
+#
+#% define buildid .local
+
+# fedora_build defines which build revision of this kernel version we're
+# building. Rather than incrementing forever, as with the prior versioning
+# setup, the trick below will allow us to use the automatic CVS Revision keyword
+# expansion, without breaking release number ordering.
+#
+# CVS Revision 1.42 was after RPM Release 2925.14. We do some math to
+# increase the Release number starting from 2926
+#
+%define baserevision 2
+%define baserelease 2945
+%define fedora_build %(R="$Revision$"; \
+ # be careful: '%%' becomes '%' below \
+ R="${R%% \$}"; R="${R##: 1.}"; \
+ # keep anything after the first dot, so this won't \
+ # break horribily when using branches \
+ # (e.g. 1.42.1.2.3.4 will become 1.2926.1.2.3.4) \
+ r1="${R%%%%.*}";rest="${R#$r1}"; \
+ # now, the math: \
+ echo `expr '(' $r1 - %{baserevision} ')' + %{baserelease}`$rest)
+
+# base_sublevel is the kernel version we're starting with and patching
+# on top of -- for example, 2.6.22-rc7-git1 starts with a 2.6.21 base,
+# which yields a base_sublevel of 21.
+%define base_sublevel 21
+
+## If this is a released kernel ##
+%if 0%{?released_kernel}
+# Do we have a 2.6.21.y update to apply?
+%define stable_update 7
+# Set rpm version accordingly
+#if 0%{?stable_update}
+#define stablerev .%{stable_update}
+#endif
+%define rpmversion 2.6.%{base_sublevel}%{?stablerev}
+
+## The not-released-kernel case ##
+%else
+# The next upstream release sublevel (base_sublevel+1)
+%define upstream_sublevel %(expr %{base_sublevel} + 1)
+# The rc snapshot level
+%define rcrev 0
+# The git snapshot level
+%define gitrev 12
+# Set rpm version accordingly
+%define rpmversion 2.6.%{upstream_sublevel}
+%endif
+# Nb: The above rcrev and gitrev values automagically define Patch00 and Patch01 below.
+
+# What parts do we want to build? We must build at least one kernel.
+# These are the kernels that are built IF the architecture allows it.
+# All should default to 1 (enabled) and be flipped to 0 (disabled)
+# by later arch-specific checks.
+
+# The following build options are enabled by default.
+# Use either --without <opt> in your rpmbuild command or force values
+# to 0 in here to disable them.
+#
+# standard kernel
+%define with_up %{?_without_up: 0} %{?!_without_up: 1}
+# kernel-smp (only valid for ppc 32-bit, sparc64)
+%define with_smp %{?_without_smp: 0} %{?!_without_smp: 1}
+# kernel-PAE (only valid for i686)
+%define with_pae %{?_without_pae: 0} %{?!_without_pae: 1}
+# kernel-xen
+%define with_xen %{?_without_xen: 0} %{?!_without_xen: 1}
+# kernel-kdump
+%define with_kdump %{?_without_kdump: 0} %{?!_without_kdump: 1}
+# kernel-debug
+%define with_debug %{?_without_debug: 0} %{!?_without_debug: 1}
+# kernel-doc
+%define with_doc %{?_without_doc: 0} %{?!_without_doc: 1}
+# kernel-headers
+%define with_headers %{?_without_headers: 0} %{?!_without_headers: 1}
+# kernel-debuginfo
+%define with_debuginfo %{?_without_debuginfo: 0} %{!?_without_debuginfo: 1}
+
+# Additional options for user-friendly one-off kernel building:
+#
+# Only build the base kernel (--with baseonly):
+%define with_baseonly %{?_with_baseonly: 1} %{?!_with_baseonly: 0}
+# Only build the smp kernel (--with smponly):
+%define with_smponly %{?_with_smponly: 1} %{?!_with_smponly: 0}
+# Only build the pae kernel (--with paeonly):
+%define with_paeonly %{?_with_paeonly: 1} %{?!_with_paeonly: 0}
+# Only build the xen kernel (--with xenonly):
+%define with_xenonly %{?_with_xenonly: 1} %{?!_with_xenonly: 0}
+
+# Whether or not to do C=1 builds with sparse
+%define usesparse 0
+%if "%fedora" >= "7"
+%define usesparse 1
+%endif
+
+# defaults for the non-xen package:
+
+# don't include xen patches
+%define includexen 0
+
+# don't build xen variant
+%define with_xen 0
+
+# Install vdso files
+%define do_vdso_install 1
+
+
+# Magic that will be enabled for the kernel-xen-2.6 Fedora package:
+%if 0%{?xen_package_magic}
+
+# Include the Xen patches
+%define includexen 1
+
+# Enable the xen variant
+%define with_xen 1
+
+# No vdso files
+%define do_vdso_install 0
+
+# Disable all other variants
+%define with_xenonly 1
+
+# No kernel-headers
+%define with_headers 0
+
+
+# We don't build the .config files dynamically, currently
+%define preconfigured 1
+
+# The main package is called kernel-xen-2.6
+%define variant -xen-2.6
+
+# However the -xen variant will be called kernel-xen
+%define variantbase kernel
+
+%endif # (xen_package_magic)
+
+
+# Set debugbuildsenabled to 1 for production (build separate debug kernels)
+# and 0 for rawhide (all kernels are debug kernels).
+# See also 'make debug' and 'make release'.
+%define debugbuildsenabled 0
+
+# Want to build a vanilla kernel build without any non-upstream patches?
+# (well, almost none, we need nonintconfig for build purposes). Default to 0 (off).
+%define with_vanilla %{?_with_vanilla: 1} %{?!_with_vanilla: 0}
+
+# pkg_release is what we'll fill in for the rpm Release: field
+%if 0%{?released_kernel}
+%define pkg_release %{fedora_build}%{?buildid}%{?dist}
+%else
+%if 0%{?rcrev}
+%define rctag .rc%rcrev
+%endif
+%if 0%{?gitrev}
+%define gittag .git%gitrev
+%if !0%{?rcrev}
+%define rctag .rc0
+%endif
+%endif
+%define pkg_release 0.%{fedora_build}%{?rctag}%{?gittag}%{?buildid}%{?dist}
+%endif
+
+%define mainpkgname kernel%{?variant}
+%if !0%{?variantbase:1}
+%define variantbase %{mainpkgname}
+%endif
+
+# The kernel tarball/base version
+%define kversion 2.6.%{base_sublevel}
+
+%define make_target bzImage
+
+%define xen_hv_version 3.1.0-rc7
+%define xen_hv_cset 7041b52471c3
+%define xen_flags verbose=y crash_debug=y
[...1877 lines suppressed...]
+rm -f $RPM_BUILD_ROOT/usr/include/asm*/io.h
+rm -f $RPM_BUILD_ROOT/usr/include/asm*/irq.h
+%endif
+
+###
+### clean
+###
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+###
+### scripts
+###
+
+#
+# This macro defines a %%post script for a kernel*-devel package.
+# %%kernel_devel_post <subpackage>
+#
+%define kernel_devel_post() \
+%{expand:%%post -n %{variantbase}-%{?1:%{1}-}devel}\
+if [ -f /etc/sysconfig/kernel ]\
+then\
+ . /etc/sysconfig/kernel || exit $?\
+fi\
+if [ "$HARDLINK" != "no" -a -x /usr/sbin/hardlink ]\
+then\
+ (cd /usr/src/kernels/%{KVERREL}-%{?1:%{1}-}%{_target_cpu} &&\
+ /usr/bin/find . -type f | while read f; do\
+ hardlink -c /usr/src/kernels/*.fc*-*/$f $f\
+ done)\
+fi\
+%{nil}
+
+#
+# This macro defines a %%post script for a kernel package and its devel package.
+# %%kernel_variant_post [-v <subpackage>] [-s <s> -r <r>] <mkinitrd-args>
+# More text can follow to go at the end of this variant's %%post.
+#
+%define kernel_variant_post(s:r:v:) \
+%{expand:%%kernel_devel_post %{?-v*}}\
+%{expand:%%post -n %{variantbase}%{?-v:-%{-v*}}}\
+%{-s:\
+if [ `uname -i` == "x86_64" -o `uname -i` == "i386" ] &&\
+ [ -f /etc/sysconfig/kernel ]; then\
+ /bin/sed -i -e 's/^DEFAULTKERNEL=%{-s*}$/DEFAULTKERNEL=%{-r*}/' /etc/sysconfig/kernel || exit $?\
+fi}\
+/sbin/new-kernel-pkg --package kernel%{?-v:-%{-v*}} --mkinitrd --depmod --install %{*} %{KVERREL}%{?-v*} || exit $?\
+#if [ -x /sbin/weak-modules ]\
+#then\
+# /sbin/weak-modules --add-kernel %{KVERREL}%{?-v*} || exit $?\
+#fi\
+%{nil}
+
+#
+# This macro defines a %%preun script for a kernel package.
+# %%kernel_variant_preun <subpackage>
+#
+%define kernel_variant_preun() \
+%{expand:%%preun -n %{variantbase}%{?1:-%{1}}}\
+/sbin/new-kernel-pkg --rminitrd --rmmoddep --remove %{KVERREL}%{?1} || exit $?\
+#if [ -x /sbin/weak-modules ]\
+#then\
+# /sbin/weak-modules --remove-kernel %{KVERREL}%{?1} || exit $?\
+#fi\
+%{nil}
+
+%if %{with_up}
+%kernel_variant_preun
+%kernel_variant_post -s kernel-smp -r kernel
+%endif
+
+%if %{with_smp}
+%kernel_variant_preun smp
+%kernel_variant_post -v smp
+%endif
+
+%if %{with_pae}
+%kernel_variant_preun PAE
+%kernel_variant_post -v PAE -s kernel-smp -r kernel-PAE
+%endif
+
+%if %{with_debug}
+%kernel_variant_preun debug
+%kernel_variant_post -v debug
+%endif
+
+%if %{with_pae_debug}
+%kernel_variant_preun PAE-debug
+%kernel_variant_post -v PAE-debug -s kernel-smp -r kernel-PAE-debug
+%endif
+
+%if %{with_xen}
+%kernel_variant_preun xen
+%kernel_variant_post -v xen -s kernel-xen[0U] -r kernel-xen -- `[ -d /proc/xen -a ! -e /proc/xen/xsd_kva ] || echo --multiboot=/%{image_install_path}/xen.gz-%{KVERREL}`
+if [ -x /sbin/ldconfig ]
+then
+ /sbin/ldconfig -X || exit $?
+fi
+%endif
+
+###
+### file lists
+###
+
+%if %{with_headers}
+%files -n %{mainpkgname}-headers
+%defattr(-,root,root)
+/usr/include/*
+%endif
+
+# only some architecture builds need kernel-doc
+%if %{with_doc}
+%files -n %{mainpkgname}-doc
+%defattr(-,root,root)
+%{_datadir}/doc/kernel-doc-%{kversion}/Documentation/*
+%dir %{_datadir}/doc/kernel-doc-%{kversion}/Documentation
+%dir %{_datadir}/doc/kernel-doc-%{kversion}
+%endif
+
+# This is %{image_install_path} on an arch where that includes ELF files,
+# or empty otherwise.
+%define elf_image_install_path %{?kernel_image_elf:%{image_install_path}}
+
+#
+# This macro defines the %%files sections for a kernel package
+# and its devel and debuginfo packages.
+# %%kernel_variant_files [-k vmlinux] [-a <extra-files-glob>] [-e <extra-nonbinary>] <condition> <subpackage>
+#
+%define kernel_variant_files(a:e:k:) \
+%if %{1}\
+%{expand:%%files -n %{variantbase}%{?2:-%{2}}}\
+%defattr(-,root,root)\
+/%{image_install_path}/%{?-k:%{-k*}}%{!?-k:vmlinuz}-%{KVERREL}%{?2}\
+/boot/System.map-%{KVERREL}%{?2}\
+#/boot/symvers-%{KVERREL}%{?2}.gz\
+/boot/config-%{KVERREL}%{?2}\
+%{?-a:%{-a*}}\
+%dir /lib/modules/%{KVERREL}%{?2}\
+/lib/modules/%{KVERREL}%{?2}/kernel\
+/lib/modules/%{KVERREL}%{?2}/build\
+/lib/modules/%{KVERREL}%{?2}/source\
+/lib/modules/%{KVERREL}%{?2}/extra\
+/lib/modules/%{KVERREL}%{?2}/updates\
+/lib/modules/%{KVERREL}%{?2}/weak-updates\
+%if %{do_vdso_install}\
+%ifarch %{vdso_arches}\
+/lib/modules/%{KVERREL}%{?2}/vdso\
+%endif\
+%endif\
+/lib/modules/%{KVERREL}%{?2}/modules.block\
+/lib/modules/%{KVERREL}%{?2}/modules.networking\
+%ghost /boot/initrd-%{KVERREL}%{?2}.img\
+%{?-e:%{-e*}}\
+%{expand:%%files -n %{variantbase}-%{?2:%{2}-}devel}\
+%defattr(-,root,root)\
+%verify(not mtime) /usr/src/kernels/%{KVERREL}%{?2:-%{2}}-%{_target_cpu}\
+/usr/src/kernels/%{KVERREL}%{?2}-%{_target_cpu}\
+%if %{with_debuginfo}\
+%ifnarch noarch\
+%if %{fancy_debuginfo}\
+%{expand:%%files -f debuginfo%{?2}.list -n %{variantbase}-%{?2:%{2}-}debuginfo}\
+%else\
+%{expand:%%files -n %{variantbase}-%{?2:%{2}-}debuginfo}\
+%endif\
+%defattr(-,root,root)\
+%if !%{fancy_debuginfo}\
+%if "%{elf_image_install_path}" != ""\
+%{debuginfodir}/%{elf_image_install_path}/*-%{KVERREL}%{?2}.debug\
+%endif\
+%{debuginfodir}/lib/modules/%{KVERREL}%{?2}\
+%{debuginfodir}/usr/src/kernels/%{KVERREL}%{?2:-%{2}}-%{_target_cpu}\
+%endif\
+%endif\
+%endif\
+%endif\
+%{nil}
+
+
+%kernel_variant_files %{with_up}
+%kernel_variant_files %{with_smp} smp
+%kernel_variant_files %{with_debug} debug
+%kernel_variant_files %{with_pae} PAE
+%kernel_variant_files %{with_pae_debug} PAE-debug
+%kernel_variant_files -k vmlinux %{with_kdump} kdump
+%kernel_variant_files -a /%{image_install_path}/xen*-%{KVERREL} -e /etc/ld.so.conf.d/kernelcap-%{KVERREL}.conf %{with_xen} xen
+
+
+%changelog
+* Wed Oct 17 2007 Dave Jones <davej at redhat.com>
+- 2.6.23-git12
+
+* Mon Oct 15 2007 Dave Jones <davej at redhat.com>
+- Work around E1000 corrupt EEPROM problem.
+
+* Fri Oct 12 2007 Dave Jones <davej at redhat.com>
+- 2.6.23-git2
+
+* Fri Oct 12 2007 Dave Jones <davej at redhat.com>
+- Start F9 branch.
linux-2.6-2110_scsi-sd-printing.patch:
Index: linux-2.6-2110_scsi-sd-printing.patch
===================================================================
RCS file: linux-2.6-2110_scsi-sd-printing.patch
diff -N linux-2.6-2110_scsi-sd-printing.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-2110_scsi-sd-printing.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,651 @@
+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:
Index: linux-2.6-2111_sd-start-stop.patch
===================================================================
RCS file: linux-2.6-2111_sd-start-stop.patch
diff -N linux-2.6-2111_sd-start-stop.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-2111_sd-start-stop.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,273 @@
+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:
Index: linux-2.6-2112_libata-suspend.patch
===================================================================
RCS file: linux-2.6-2112_libata-suspend.patch
diff -N linux-2.6-2112_libata-suspend.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-2112_libata-suspend.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,1281 @@
+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:
Index: linux-2.6-2113_libata-spindown-compat.patch
===================================================================
RCS file: linux-2.6-2113_libata-spindown-compat.patch
diff -N linux-2.6-2113_libata-spindown-compat.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-2113_libata-spindown-compat.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,126 @@
+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:
Index: linux-2.6-2114_libata-shutdown-warning.patch
===================================================================
RCS file: linux-2.6-2114_libata-shutdown-warning.patch
diff -N linux-2.6-2114_libata-shutdown-warning.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-2114_libata-shutdown-warning.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,98 @@
+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:
Index: linux-2.6-2115_libata-spindown-status.patch
===================================================================
RCS file: linux-2.6-2115_libata-spindown-status.patch
diff -N linux-2.6-2115_libata-spindown-status.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-2115_libata-spindown-status.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,60 @@
+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:
Index: linux-2.6-2116_libata-remove-spindown-compat.patch
===================================================================
RCS file: linux-2.6-2116_libata-remove-spindown-compat.patch
diff -N linux-2.6-2116_libata-remove-spindown-compat.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-2116_libata-remove-spindown-compat.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,90 @@
+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:
Index: linux-2.6-2117_sata-via-suspend.patch
===================================================================
RCS file: linux-2.6-2117_sata-via-suspend.patch
diff -N linux-2.6-2117_sata-via-suspend.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-2117_sata-via-suspend.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,15 @@
+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:
Index: linux-2.6-2118_scsi-constants.patch
===================================================================
RCS file: linux-2.6-2118_scsi-constants.patch
diff -N linux-2.6-2118_scsi-constants.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-2118_scsi-constants.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,532 @@
+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:
Index: linux-2.6-acpi-boot-regression.patch
===================================================================
RCS file: linux-2.6-acpi-boot-regression.patch
diff -N linux-2.6-acpi-boot-regression.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-acpi-boot-regression.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,50 @@
+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:
Index: linux-2.6-acpi-dock-oops.patch
===================================================================
RCS file: linux-2.6-acpi-dock-oops.patch
diff -N linux-2.6-acpi-dock-oops.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-acpi-dock-oops.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,54 @@
+---
+ 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:
Index: linux-2.6-acpi-git-ec-init-fixes.patch
===================================================================
RCS file: linux-2.6-acpi-git-ec-init-fixes.patch
diff -N linux-2.6-acpi-git-ec-init-fixes.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-acpi-git-ec-init-fixes.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,207 @@
+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:
Index: linux-2.6-acpi-keep-tsc-stable-when-lapic-timer-c2-ok-is-set.patch
===================================================================
RCS file: linux-2.6-acpi-keep-tsc-stable-when-lapic-timer-c2-ok-is-set.patch
diff -N linux-2.6-acpi-keep-tsc-stable-when-lapic-timer-c2-ok-is-set.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-acpi-keep-tsc-stable-when-lapic-timer-c2-ok-is-set.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,65 @@
+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:
Index: linux-2.6-acpi-preserve-ebx-in-acpi_copy_wakeup_routine.patch
===================================================================
RCS file: linux-2.6-acpi-preserve-ebx-in-acpi_copy_wakeup_routine.patch
diff -N linux-2.6-acpi-preserve-ebx-in-acpi_copy_wakeup_routine.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-acpi-preserve-ebx-in-acpi_copy_wakeup_routine.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,55 @@
+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:
Index: linux-2.6-acpi-unblacklist-dell-gx240.patch
===================================================================
RCS file: linux-2.6-acpi-unblacklist-dell-gx240.patch
diff -N linux-2.6-acpi-unblacklist-dell-gx240.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-acpi-unblacklist-dell-gx240.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,121 @@
+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$
+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:
Index: linux-2.6-add-mmf_dump_elf_headers.patch
===================================================================
RCS file: linux-2.6-add-mmf_dump_elf_headers.patch
diff -N linux-2.6-add-mmf_dump_elf_headers.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-add-mmf_dump_elf_headers.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,172 @@
+
+
+*** 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:
Index: linux-2.6-add-sys-module-name-notes.patch
===================================================================
RCS file: linux-2.6-add-sys-module-name-notes.patch
diff -N linux-2.6-add-sys-module-name-notes.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-add-sys-module-name-notes.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,183 @@
+
+
+*** 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,
++ ¬es_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 = ¬es_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,
++ ¬es_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:
Index: linux-2.6-amd-disabled-svm-detect-msr-1.patch
===================================================================
RCS file: linux-2.6-amd-disabled-svm-detect-msr-1.patch
diff -N linux-2.6-amd-disabled-svm-detect-msr-1.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-amd-disabled-svm-detect-msr-1.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,17 @@
+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:
Index: linux-2.6-amd-disabled-svm-detect.patch
===================================================================
RCS file: linux-2.6-amd-disabled-svm-detect.patch
diff -N linux-2.6-amd-disabled-svm-detect.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-amd-disabled-svm-detect.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,47 @@
+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:
View full diff with command:
/usr/bin/cvs -f diff -kk -u -N -r 1.1 -r 1.2 linux-2.6-at76.patch
Index: linux-2.6-at76.patch
===================================================================
RCS file: linux-2.6-at76.patch
diff -N linux-2.6-at76.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-at76.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,6272 @@
+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;
[...5879 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:
Index: linux-2.6-ata-call-check-dma-with-qc-prepared.patch
===================================================================
RCS file: linux-2.6-ata-call-check-dma-with-qc-prepared.patch
diff -N linux-2.6-ata-call-check-dma-with-qc-prepared.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-ata-call-check-dma-with-qc-prepared.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,74 @@
+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:
Index: linux-2.6-ata-quirk.patch
===================================================================
RCS file: linux-2.6-ata-quirk.patch
diff -N linux-2.6-ata-quirk.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-ata-quirk.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,58 @@
+--- 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:
Index: linux-2.6-ata-use-pio-for-non-16-byte-xfers.patch
===================================================================
RCS file: linux-2.6-ata-use-pio-for-non-16-byte-xfers.patch
diff -N linux-2.6-ata-use-pio-for-non-16-byte-xfers.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-ata-use-pio-for-non-16-byte-xfers.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,82 @@
+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:
View full diff with command:
/usr/bin/cvs -f diff -kk -u -N -r 1.1 -r 1.2 linux-2.6-ath5k.patch
Index: linux-2.6-ath5k.patch
===================================================================
RCS file: linux-2.6-ath5k.patch
diff -N linux-2.6-ath5k.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-ath5k.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,14257 @@
+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,
[...13864 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:
Index: linux-2.6-bcm43xx-pci-neuter.patch
===================================================================
RCS file: linux-2.6-bcm43xx-pci-neuter.patch
diff -N linux-2.6-bcm43xx-pci-neuter.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-bcm43xx-pci-neuter.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,18 @@
+--- 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:
Index: linux-2.6-cell-spu-device-tree.patch
===================================================================
RCS file: linux-2.6-cell-spu-device-tree.patch
diff -N linux-2.6-cell-spu-device-tree.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-cell-spu-device-tree.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,391 @@
+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:
View full diff with command:
/usr/bin/cvs -f diff -kk -u -N -r 1.1 -r 1.2 linux-2.6-cell-spufs-fixes.patch
Index: linux-2.6-cell-spufs-fixes.patch
===================================================================
RCS file: linux-2.6-cell-spufs-fixes.patch
diff -N linux-2.6-cell-spufs-fixes.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-cell-spufs-fixes.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,2064 @@
+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
[...1671 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:
Index: linux-2.6-clockevents-fix-resume-logic.patch
===================================================================
RCS file: linux-2.6-clockevents-fix-resume-logic.patch
diff -N linux-2.6-clockevents-fix-resume-logic.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-clockevents-fix-resume-logic.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,284 @@
+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:
Index: linux-2.6-crap-sysfs-workaround.patch
===================================================================
RCS file: linux-2.6-crap-sysfs-workaround.patch
diff -N linux-2.6-crap-sysfs-workaround.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-crap-sysfs-workaround.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,11 @@
+--- 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:
Index: linux-2.6-debug-acpi-os-write-port.patch
===================================================================
RCS file: linux-2.6-debug-acpi-os-write-port.patch
diff -N linux-2.6-debug-acpi-os-write-port.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-debug-acpi-os-write-port.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,15 @@
+---
+ 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:
Index: linux-2.6-debug-extra-warnings.patch
===================================================================
RCS file: linux-2.6-debug-extra-warnings.patch
diff -N linux-2.6-debug-extra-warnings.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-debug-extra-warnings.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,21 @@
+-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:
Index: linux-2.6-debug-nmi-timeout.patch
===================================================================
RCS file: linux-2.6-debug-nmi-timeout.patch
diff -N linux-2.6-debug-nmi-timeout.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-debug-nmi-timeout.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,39 @@
+--- 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:
Index: linux-2.6-default-mmf_dump_elf_headers.patch
===================================================================
RCS file: linux-2.6-default-mmf_dump_elf_headers.patch
diff -N linux-2.6-default-mmf_dump_elf_headers.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-default-mmf_dump_elf_headers.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,13 @@
+--- 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:
Index: linux-2.6-defaults-pci_no_msi_mmconf.patch
===================================================================
RCS file: linux-2.6-defaults-pci_no_msi_mmconf.patch
diff -N linux-2.6-defaults-pci_no_msi_mmconf.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-defaults-pci_no_msi_mmconf.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,99 @@
+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:
Index: linux-2.6-drivers-ssb-debug-revision.patch
===================================================================
RCS file: linux-2.6-drivers-ssb-debug-revision.patch
diff -N linux-2.6-drivers-ssb-debug-revision.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-drivers-ssb-debug-revision.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,15 @@
+---
+ 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:
Index: linux-2.6-dvb-spinlock.patch
===================================================================
RCS file: linux-2.6-dvb-spinlock.patch
diff -N linux-2.6-dvb-spinlock.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-dvb-spinlock.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,62 @@
+
+# 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:
Index: linux-2.6-e1000-corrupt-eeprom-checksum.patch
===================================================================
RCS file: linux-2.6-e1000-corrupt-eeprom-checksum.patch
diff -N linux-2.6-e1000-corrupt-eeprom-checksum.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-e1000-corrupt-eeprom-checksum.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,30 @@
+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:
Index: linux-2.6-execshield-xen.patch
===================================================================
RCS file: linux-2.6-execshield-xen.patch
diff -N linux-2.6-execshield-xen.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-execshield-xen.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,390 @@
+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(¤t->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(¤t->mm->page_table_lock);
++ if (limit >= TASK_SIZE)
++ limit = -1UL;
++ current->mm->context.exec_limit = limit;
++ }
++ set_user_cs(¤t->mm->context.user_cs, limit);
++
++ desc1 = ¤t->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:
Index: linux-2.6-firewire-be32-fix.patch
===================================================================
RCS file: linux-2.6-firewire-be32-fix.patch
diff -N linux-2.6-firewire-be32-fix.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-firewire-be32-fix.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,23 @@
+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:
Index: linux-2.6-firewire-lockdep.patch
===================================================================
RCS file: linux-2.6-firewire-lockdep.patch
diff -N linux-2.6-firewire-lockdep.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-firewire-lockdep.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,113 @@
+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:
Index: linux-2.6-firewire-multi-lun.patch
===================================================================
RCS file: linux-2.6-firewire-multi-lun.patch
diff -N linux-2.6-firewire-multi-lun.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-firewire-multi-lun.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,997 @@
+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:
Index: linux-2.6-fix-pmops-1.patch
===================================================================
RCS file: linux-2.6-fix-pmops-1.patch
diff -N linux-2.6-fix-pmops-1.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-fix-pmops-1.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,339 @@
+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:
Index: linux-2.6-fix-pmops-2.patch
===================================================================
RCS file: linux-2.6-fix-pmops-2.patch
diff -N linux-2.6-fix-pmops-2.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-fix-pmops-2.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,219 @@
+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:
Index: linux-2.6-fix-pmops-3.patch
===================================================================
RCS file: linux-2.6-fix-pmops-3.patch
diff -N linux-2.6-fix-pmops-3.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-fix-pmops-3.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,237 @@
+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:
Index: linux-2.6-fix-pmops-4.patch
===================================================================
RCS file: linux-2.6-fix-pmops-4.patch
diff -N linux-2.6-fix-pmops-4.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-fix-pmops-4.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,61 @@
+---
+ 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:
Index: linux-2.6-gfs-locking-exports.patch
===================================================================
RCS file: linux-2.6-gfs-locking-exports.patch
diff -N linux-2.6-gfs-locking-exports.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-gfs-locking-exports.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,21 @@
+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:
View full diff with command:
/usr/bin/cvs -f diff -kk -u -N -r 1.1 -r 1.2 linux-2.6-highres-timers.patch
Index: linux-2.6-highres-timers.patch
===================================================================
RCS file: linux-2.6-highres-timers.patch
diff -N linux-2.6-highres-timers.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-highres-timers.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,6486 @@
+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
[...6093 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:
Index: linux-2.6-i386-vdso-install-unstripped-copies-on-disk.patch
===================================================================
RCS file: linux-2.6-i386-vdso-install-unstripped-copies-on-disk.patch
diff -N linux-2.6-i386-vdso-install-unstripped-copies-on-disk.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-i386-vdso-install-unstripped-copies-on-disk.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,86 @@
+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:
Index: linux-2.6-i82875-edac-pci-setup.patch
===================================================================
RCS file: linux-2.6-i82875-edac-pci-setup.patch
diff -N linux-2.6-i82875-edac-pci-setup.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-i82875-edac-pci-setup.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,107 @@
+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:
Index: linux-2.6-i965gm-support.patch
===================================================================
RCS file: linux-2.6-i965gm-support.patch
diff -N linux-2.6-i965gm-support.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-i965gm-support.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,23 @@
+
+--- 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:
Index: linux-2.6-iwlwifi-fixes.patch
===================================================================
RCS file: linux-2.6-iwlwifi-fixes.patch
diff -N linux-2.6-iwlwifi-fixes.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-iwlwifi-fixes.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,794 @@
+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:
View full diff with command:
/usr/bin/cvs -f diff -kk -u -N -r 1.1 -r 1.2 linux-2.6-kvm-19.patch
Index: linux-2.6-kvm-19.patch
===================================================================
RCS file: linux-2.6-kvm-19.patch
diff -N linux-2.6-kvm-19.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-kvm-19.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,3395 @@
+--- 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;
[...3002 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:
Index: linux-2.6-kvm-reinit-real-mode-tss.patch
===================================================================
RCS file: linux-2.6-kvm-reinit-real-mode-tss.patch
diff -N linux-2.6-kvm-reinit-real-mode-tss.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-kvm-reinit-real-mode-tss.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,35 @@
+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:
Index: linux-2.6-libata-acpi-enable.patch
===================================================================
RCS file: linux-2.6-libata-acpi-enable.patch
diff -N linux-2.6-libata-acpi-enable.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-libata-acpi-enable.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,13 @@
+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:
Index: linux-2.6-libata-ali-atapi-dma.patch
===================================================================
RCS file: linux-2.6-libata-ali-atapi-dma.patch
diff -N linux-2.6-libata-ali-atapi-dma.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-libata-ali-atapi-dma.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,50 @@
+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:
Index: linux-2.6-libata-atiixp-ids.patch
===================================================================
RCS file: linux-2.6-libata-atiixp-ids.patch
diff -N linux-2.6-libata-atiixp-ids.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-libata-atiixp-ids.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,42 @@
+--- 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:
Index: linux-2.6-libata-hpa.patch
===================================================================
RCS file: linux-2.6-libata-hpa.patch
diff -N linux-2.6-libata-hpa.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-libata-hpa.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,287 @@
+
+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:
Index: linux-2.6-libata-ich8m-add-pciid.patch
===================================================================
RCS file: linux-2.6-libata-ich8m-add-pciid.patch
diff -N linux-2.6-libata-ich8m-add-pciid.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-libata-ich8m-add-pciid.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,21 @@
+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:
Index: linux-2.6-libata-ncq-blacklist-2.6.22-rc7.patch
===================================================================
RCS file: linux-2.6-libata-ncq-blacklist-2.6.22-rc7.patch
diff -N linux-2.6-libata-ncq-blacklist-2.6.22-rc7.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-libata-ncq-blacklist-2.6.22-rc7.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,28 @@
+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:
Index: linux-2.6-libata-pata-dma-disable-option.patch
===================================================================
RCS file: linux-2.6-libata-pata-dma-disable-option.patch
diff -N linux-2.6-libata-pata-dma-disable-option.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-libata-pata-dma-disable-option.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,97 @@
+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:
Index: linux-2.6-libata-pata-hpt3x2n-correct-revision-boundary.patch
===================================================================
RCS file: linux-2.6-libata-pata-hpt3x2n-correct-revision-boundary.patch
diff -N linux-2.6-libata-pata-hpt3x2n-correct-revision-boundary.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-libata-pata-hpt3x2n-correct-revision-boundary.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,69 @@
+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:
Index: linux-2.6-libata-pata-pcmcia-new-ident.patch
===================================================================
RCS file: linux-2.6-libata-pata-pcmcia-new-ident.patch
diff -N linux-2.6-libata-pata-pcmcia-new-ident.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-libata-pata-pcmcia-new-ident.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,79 @@
+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:
Index: linux-2.6-libata-pata-sis-fix-timing.patch
===================================================================
RCS file: linux-2.6-libata-pata-sis-fix-timing.patch
diff -N linux-2.6-libata-pata-sis-fix-timing.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-libata-pata-sis-fix-timing.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,145 @@
+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:
Index: linux-2.6-libata-pata_dma-param.patch
===================================================================
RCS file: linux-2.6-libata-pata_dma-param.patch
diff -N linux-2.6-libata-pata_dma-param.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-libata-pata_dma-param.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,52 @@
+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:
Index: linux-2.6-libata-pata_it821x-partly-fix-dma.patch
===================================================================
RCS file: linux-2.6-libata-pata_it821x-partly-fix-dma.patch
diff -N linux-2.6-libata-pata_it821x-partly-fix-dma.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-libata-pata_it821x-partly-fix-dma.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,60 @@
+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:
Index: linux-2.6-libata-sata_nv-adma.patch
===================================================================
RCS file: linux-2.6-libata-sata_nv-adma.patch
diff -N linux-2.6-libata-sata_nv-adma.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-libata-sata_nv-adma.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,95 @@
+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:
Index: linux-2.6-libata-sata_nv-wildcard-removal.patch
===================================================================
RCS file: linux-2.6-libata-sata_nv-wildcard-removal.patch
diff -N linux-2.6-libata-sata_nv-wildcard-removal.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-libata-sata_nv-wildcard-removal.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,28 @@
+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:
Index: linux-2.6-libata-setxfer.patch
===================================================================
RCS file: linux-2.6-libata-setxfer.patch
diff -N linux-2.6-libata-setxfer.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-libata-setxfer.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,176 @@
+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:
Index: linux-2.6-libata_ali_max_dma_speed.patch
===================================================================
RCS file: linux-2.6-libata_ali_max_dma_speed.patch
diff -N linux-2.6-libata_ali_max_dma_speed.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-libata_ali_max_dma_speed.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,35 @@
+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:
View full diff with command:
/usr/bin/cvs -f diff -kk -u -N -r 1.1 -r 1.2 linux-2.6-lirc.patch
Index: linux-2.6-lirc.patch
===================================================================
RCS file: linux-2.6-lirc.patch
diff -N linux-2.6-lirc.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-lirc.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,18089 @@
+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 @@
++
++/*
[...17696 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:
View full diff with command:
/usr/bin/cvs -f diff -kk -u -N -r 1.1 -r 1.2 linux-2.6-mac80211-extras.patch
Index: linux-2.6-mac80211-extras.patch
===================================================================
RCS file: linux-2.6-mac80211-extras.patch
diff -N linux-2.6-mac80211-extras.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-mac80211-extras.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,4154 @@
+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,
+ };
+
+
[...3761 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:
Index: linux-2.6-mac80211-nm-hidden-ssid.patch
===================================================================
RCS file: linux-2.6-mac80211-nm-hidden-ssid.patch
diff -N linux-2.6-mac80211-nm-hidden-ssid.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-mac80211-nm-hidden-ssid.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,31 @@
+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:
View full diff with command:
/usr/bin/cvs -f diff -kk -u -N -r 1.1 -r 1.2 linux-2.6-mm-udf-fixes.patch
Index: linux-2.6-mm-udf-fixes.patch
===================================================================
RCS file: linux-2.6-mm-udf-fixes.patch
diff -N linux-2.6-mm-udf-fixes.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-mm-udf-fixes.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,2982 @@
+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))
+- {
[...2589 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:
View full diff with command:
/usr/bin/cvs -f diff -kk -u -N -r 1.1 -r 1.2 linux-2.6-mpc52xx-fec.patch
Index: linux-2.6-mpc52xx-fec.patch
===================================================================
RCS file: linux-2.6-mpc52xx-fec.patch
diff -N linux-2.6-mpc52xx-fec.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-mpc52xx-fec.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,2275 @@
+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);
[...1882 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:
Index: linux-2.6-mpc52xx-sdma.patch
===================================================================
RCS file: linux-2.6-mpc52xx-sdma.patch
diff -N linux-2.6-mpc52xx-sdma.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-mpc52xx-sdma.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,910 @@
+--- 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:
Index: linux-2.6-net-e1000-no-msi-warning.patch
===================================================================
RCS file: linux-2.6-net-e1000-no-msi-warning.patch
diff -N linux-2.6-net-e1000-no-msi-warning.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-net-e1000-no-msi-warning.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,122 @@
+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:
Index: linux-2.6-net-silence-noisy-printks.patch
===================================================================
RCS file: linux-2.6-net-silence-noisy-printks.patch
diff -N linux-2.6-net-silence-noisy-printks.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-net-silence-noisy-printks.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,126 @@
+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:
View full diff with command:
/usr/bin/cvs -f diff -kk -u -N -r 1.1 -r 1.2 linux-2.6-netdev-e1000e-01.patch
Index: linux-2.6-netdev-e1000e-01.patch
===================================================================
RCS file: linux-2.6-netdev-e1000e-01.patch
diff -N linux-2.6-netdev-e1000e-01.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-netdev-e1000e-01.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,18137 @@
+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;
++ }
++
[...17744 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:
View full diff with command:
/usr/bin/cvs -f diff -kk -u -N -r 1.1 -r 1.2 linux-2.6-netdev-e1000e-02.patch
Index: linux-2.6-netdev-e1000e-02.patch
===================================================================
RCS file: linux-2.6-netdev-e1000e-02.patch
diff -N linux-2.6-netdev-e1000e-02.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-netdev-e1000e-02.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,4358 @@
+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)
+
[...3965 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:
Index: linux-2.6-netdev-e1000e-03.patch
===================================================================
RCS file: linux-2.6-netdev-e1000e-03.patch
diff -N linux-2.6-netdev-e1000e-03.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-netdev-e1000e-03.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,95 @@
+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:
Index: linux-2.6-netdev-e1000e-04.patch
===================================================================
RCS file: linux-2.6-netdev-e1000e-04.patch
diff -N linux-2.6-netdev-e1000e-04.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-netdev-e1000e-04.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,23 @@
+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:
Index: linux-2.6-netdev-e1000e-05.patch
===================================================================
RCS file: linux-2.6-netdev-e1000e-05.patch
diff -N linux-2.6-netdev-e1000e-05.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-netdev-e1000e-05.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,146 @@
+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:
View full diff with command:
/usr/bin/cvs -f diff -kk -u -N -r 1.1 -r 1.2 linux-2.6-netdev-e1000e-06.patch
Index: linux-2.6-netdev-e1000e-06.patch
===================================================================
RCS file: linux-2.6-netdev-e1000e-06.patch
diff -N linux-2.6-netdev-e1000e-06.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-netdev-e1000e-06.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,3777 @@
+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);
[...3384 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:
Index: linux-2.6-netdev-e1000e-07.patch
===================================================================
RCS file: linux-2.6-netdev-e1000e-07.patch
diff -N linux-2.6-netdev-e1000e-07.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-netdev-e1000e-07.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,93 @@
+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:
Index: linux-2.6-netdev-e1000e-08.patch
===================================================================
RCS file: linux-2.6-netdev-e1000e-08.patch
diff -N linux-2.6-netdev-e1000e-08.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-netdev-e1000e-08.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,24 @@
+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:
Index: linux-2.6-netdev-e1000e-09.patch
===================================================================
RCS file: linux-2.6-netdev-e1000e-09.patch
diff -N linux-2.6-netdev-e1000e-09.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-netdev-e1000e-09.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,197 @@
+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:
Index: linux-2.6-netdev-e1000e-10.patch
===================================================================
RCS file: linux-2.6-netdev-e1000e-10.patch
diff -N linux-2.6-netdev-e1000e-10.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-netdev-e1000e-10.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,46 @@
+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:
Index: linux-2.6-nfs-missing-braces.patch
===================================================================
RCS file: linux-2.6-nfs-missing-braces.patch
diff -N linux-2.6-nfs-missing-braces.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-nfs-missing-braces.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,38 @@
+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:
Index: linux-2.6-nfs-noreaddirplus.patch
===================================================================
RCS file: linux-2.6-nfs-noreaddirplus.patch
diff -N linux-2.6-nfs-noreaddirplus.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-nfs-noreaddirplus.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,117 @@
+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:
Index: linux-2.6-ondemand-timer.patch
===================================================================
RCS file: linux-2.6-ondemand-timer.patch
diff -N linux-2.6-ondemand-timer.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-ondemand-timer.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,499 @@
+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:
Index: linux-2.6-pass-g-to-assembler-under-config_debug_info.patch
===================================================================
RCS file: linux-2.6-pass-g-to-assembler-under-config_debug_info.patch
diff -N linux-2.6-pass-g-to-assembler-under-config_debug_info.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-pass-g-to-assembler-under-config_debug_info.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,29 @@
+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:
Index: linux-2.6-pmac-zilog.patch
===================================================================
RCS file: linux-2.6-pmac-zilog.patch
diff -N linux-2.6-pmac-zilog.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-pmac-zilog.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,35 @@
+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:
Index: linux-2.6-pmtrace-time-fix.patch
===================================================================
RCS file: linux-2.6-pmtrace-time-fix.patch
diff -N linux-2.6-pmtrace-time-fix.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-pmtrace-time-fix.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,11 @@
+--- 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:
Index: linux-2.6-powermac-generic-suspend-1.patch
===================================================================
RCS file: linux-2.6-powermac-generic-suspend-1.patch
diff -N linux-2.6-powermac-generic-suspend-1.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-powermac-generic-suspend-1.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,172 @@
+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:
Index: linux-2.6-powermac-generic-suspend-2.patch
===================================================================
RCS file: linux-2.6-powermac-generic-suspend-2.patch
diff -N linux-2.6-powermac-generic-suspend-2.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-powermac-generic-suspend-2.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,185 @@
+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:
Index: linux-2.6-powermac-generic-suspend-3.patch
===================================================================
RCS file: linux-2.6-powermac-generic-suspend-3.patch
diff -N linux-2.6-powermac-generic-suspend-3.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-powermac-generic-suspend-3.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,317 @@
+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:
Index: linux-2.6-powermac-generic-suspend-4.patch
===================================================================
RCS file: linux-2.6-powermac-generic-suspend-4.patch
diff -N linux-2.6-powermac-generic-suspend-4.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-powermac-generic-suspend-4.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,475 @@
+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:
Index: linux-2.6-powerpc-generic-suspend-2-remove-adb-sleep-notifier.patch
===================================================================
RCS file: linux-2.6-powerpc-generic-suspend-2-remove-adb-sleep-notifier.patch
diff -N linux-2.6-powerpc-generic-suspend-2-remove-adb-sleep-notifier.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-powerpc-generic-suspend-2-remove-adb-sleep-notifier.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,152 @@
+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:
View full diff with command:
/usr/bin/cvs -f diff -kk -u -N -r 1.1 -r 1.2 linux-2.6-powerpc-generic-suspend-3-remove-dmasound.patch
Index: linux-2.6-powerpc-generic-suspend-3-remove-dmasound.patch
===================================================================
RCS file: linux-2.6-powerpc-generic-suspend-3-remove-dmasound.patch
diff -N linux-2.6-powerpc-generic-suspend-3-remove-dmasound.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-powerpc-generic-suspend-3-remove-dmasound.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,8007 @@
+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 */
[...7614 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:
Index: linux-2.6-powerpc-generic-suspend-4-kill-pmu-sleep-notifier.patch
===================================================================
RCS file: linux-2.6-powerpc-generic-suspend-4-kill-pmu-sleep-notifier.patch
diff -N linux-2.6-powerpc-generic-suspend-4-kill-pmu-sleep-notifier.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-powerpc-generic-suspend-4-kill-pmu-sleep-notifier.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,176 @@
+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:
Index: linux-2.6-powerpc-generic-suspend-5-pmu-pm_ops.patch
===================================================================
RCS file: linux-2.6-powerpc-generic-suspend-5-pmu-pm_ops.patch
diff -N linux-2.6-powerpc-generic-suspend-5-pmu-pm_ops.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-powerpc-generic-suspend-5-pmu-pm_ops.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,495 @@
+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:
Index: linux-2.6-powerpc-lparmap-g.patch
===================================================================
RCS file: linux-2.6-powerpc-lparmap-g.patch
diff -N linux-2.6-powerpc-lparmap-g.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-powerpc-lparmap-g.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,11 @@
+--- 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:
Index: linux-2.6-powerpc-reserve-initrd-1.patch
===================================================================
RCS file: linux-2.6-powerpc-reserve-initrd-1.patch
diff -N linux-2.6-powerpc-reserve-initrd-1.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-powerpc-reserve-initrd-1.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,105 @@
+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:
Index: linux-2.6-powerpc-reserve-initrd-2.patch
===================================================================
RCS file: linux-2.6-powerpc-reserve-initrd-2.patch
diff -N linux-2.6-powerpc-reserve-initrd-2.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-powerpc-reserve-initrd-2.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,146 @@
+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:
Index: linux-2.6-powerpc-slabalign.patch
===================================================================
RCS file: linux-2.6-powerpc-slabalign.patch
diff -N linux-2.6-powerpc-slabalign.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-powerpc-slabalign.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,14 @@
+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:
Index: linux-2.6-powerpc-spu-vicinity.patch
===================================================================
RCS file: linux-2.6-powerpc-spu-vicinity.patch
diff -N linux-2.6-powerpc-spu-vicinity.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-powerpc-spu-vicinity.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,42 @@
+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:
Index: linux-2.6-powerpc-vdso-install-unstripped-copies-on-disk.patch
===================================================================
RCS file: linux-2.6-powerpc-vdso-install-unstripped-copies-on-disk.patch
diff -N linux-2.6-powerpc-vdso-install-unstripped-copies-on-disk.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-powerpc-vdso-install-unstripped-copies-on-disk.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,129 @@
+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:
Index: linux-2.6-ppc-data-exception.patch
===================================================================
RCS file: linux-2.6-ppc-data-exception.patch
diff -N linux-2.6-ppc-data-exception.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-ppc-data-exception.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,49 @@
+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:
Index: linux-2.6-ppc-pegasos-via-ata-legacy-irq.patch
===================================================================
RCS file: linux-2.6-ppc-pegasos-via-ata-legacy-irq.patch
diff -N linux-2.6-ppc-pegasos-via-ata-legacy-irq.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-ppc-pegasos-via-ata-legacy-irq.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,92 @@
+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:
Index: linux-2.6-ps3-clear-spu-irq.patch
===================================================================
RCS file: linux-2.6-ps3-clear-spu-irq.patch
diff -N linux-2.6-ps3-clear-spu-irq.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-ps3-clear-spu-irq.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,92 @@
+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:
Index: linux-2.6-ps3-device-init.patch
===================================================================
RCS file: linux-2.6-ps3-device-init.patch
diff -N linux-2.6-ps3-device-init.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-ps3-device-init.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,520 @@
+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:
Index: linux-2.6-ps3-ehci-iso.patch
===================================================================
RCS file: linux-2.6-ps3-ehci-iso.patch
diff -N linux-2.6-ps3-ehci-iso.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-ps3-ehci-iso.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,73 @@
+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:
Index: linux-2.6-ps3-ethernet-autoload.patch
===================================================================
RCS file: linux-2.6-ps3-ethernet-autoload.patch
diff -N linux-2.6-ps3-ethernet-autoload.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-ps3-ethernet-autoload.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,7 @@
+--- 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:
Index: linux-2.6-ps3-ethernet-modular.patch
===================================================================
RCS file: linux-2.6-ps3-ethernet-modular.patch
diff -N linux-2.6-ps3-ethernet-modular.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-ps3-ethernet-modular.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,74 @@
+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:
View full diff with command:
/usr/bin/cvs -f diff -kk -u -N -r 1.1 -r 1.2 linux-2.6-ps3-gelic-wireless.patch
Index: linux-2.6-ps3-gelic-wireless.patch
===================================================================
RCS file: linux-2.6-ps3-gelic-wireless.patch
diff -N linux-2.6-ps3-gelic-wireless.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-ps3-gelic-wireless.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,2974 @@
+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"
+
[...2581 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:
Index: linux-2.6-ps3-gelic.patch
===================================================================
RCS file: linux-2.6-ps3-gelic.patch
diff -N linux-2.6-ps3-gelic.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-ps3-gelic.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,1964 @@
+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:
Index: linux-2.6-ps3-kexec.patch
===================================================================
RCS file: linux-2.6-ps3-kexec.patch
diff -N linux-2.6-ps3-kexec.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-ps3-kexec.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,1008 @@
+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:
Index: linux-2.6-ps3-legacy-bootloader-hack.patch
===================================================================
RCS file: linux-2.6-ps3-legacy-bootloader-hack.patch
diff -N linux-2.6-ps3-legacy-bootloader-hack.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-ps3-legacy-bootloader-hack.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,37 @@
+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:
Index: linux-2.6-ps3-legacy-ioport.patch
===================================================================
RCS file: linux-2.6-ps3-legacy-ioport.patch
diff -N linux-2.6-ps3-legacy-ioport.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-ps3-legacy-ioport.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,22 @@
+--- 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:
Index: linux-2.6-ps3-memory-probe.patch
===================================================================
RCS file: linux-2.6-ps3-memory-probe.patch
diff -N linux-2.6-ps3-memory-probe.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-ps3-memory-probe.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,36 @@
+--- 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:
Index: linux-2.6-ps3-smp-boot.patch
===================================================================
RCS file: linux-2.6-ps3-smp-boot.patch
diff -N linux-2.6-ps3-smp-boot.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-ps3-smp-boot.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,52 @@
+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:
Index: linux-2.6-ps3-sound-autoload.patch
===================================================================
RCS file: linux-2.6-ps3-sound-autoload.patch
diff -N linux-2.6-ps3-sound-autoload.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-ps3-sound-autoload.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,10 @@
+--- 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:
View full diff with command:
/usr/bin/cvs -f diff -kk -u -N -r 1.1 -r 1.2 linux-2.6-ps3-sound.patch
Index: linux-2.6-ps3-sound.patch
===================================================================
RCS file: linux-2.6-ps3-sound.patch
diff -N linux-2.6-ps3-sound.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-ps3-sound.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,2449 @@
+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,
++
[...2056 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:
Index: linux-2.6-ps3-stable-patches.patch
===================================================================
RCS file: linux-2.6-ps3-stable-patches.patch
diff -N linux-2.6-ps3-stable-patches.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-ps3-stable-patches.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,1578 @@
+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:
Index: linux-2.6-ps3-storage-alias.patch
===================================================================
RCS file: linux-2.6-ps3-storage-alias.patch
diff -N linux-2.6-ps3-storage-alias.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-ps3-storage-alias.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,7 @@
+--- 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:
View full diff with command:
/usr/bin/cvs -f diff -kk -u -N -r 1.1 -r 1.2 linux-2.6-ps3-storage.patch
Index: linux-2.6-ps3-storage.patch
===================================================================
RCS file: linux-2.6-ps3-storage.patch
diff -N linux-2.6-ps3-storage.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-ps3-storage.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,3310 @@
+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;
+ }
[...2917 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:
Index: linux-2.6-ps3-system-bus-rework-2.patch
===================================================================
RCS file: linux-2.6-ps3-system-bus-rework-2.patch
diff -N linux-2.6-ps3-system-bus-rework-2.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-ps3-system-bus-rework-2.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,46 @@
+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:
Index: linux-2.6-ps3-system-bus-rework.patch
===================================================================
RCS file: linux-2.6-ps3-system-bus-rework.patch
diff -N linux-2.6-ps3-system-bus-rework.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-ps3-system-bus-rework.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,1511 @@
+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:
Index: linux-2.6-ps3-usb-autoload.patch
===================================================================
RCS file: linux-2.6-ps3-usb-autoload.patch
diff -N linux-2.6-ps3-usb-autoload.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-ps3-usb-autoload.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,24 @@
+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:
Index: linux-2.6-ps3-wrap-spu-runctl.patch
===================================================================
RCS file: linux-2.6-ps3-wrap-spu-runctl.patch
diff -N linux-2.6-ps3-wrap-spu-runctl.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-ps3-wrap-spu-runctl.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,216 @@
+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:
Index: linux-2.6-ps3av-export-header.patch
===================================================================
RCS file: linux-2.6-ps3av-export-header.patch
diff -N linux-2.6-ps3av-export-header.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-ps3av-export-header.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,31 @@
+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:
Index: linux-2.6-ps3fb-panic.patch
===================================================================
RCS file: linux-2.6-ps3fb-panic.patch
diff -N linux-2.6-ps3fb-panic.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-ps3fb-panic.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,47 @@
+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:
Index: linux-2.6-scsi-async-double-add.patch
===================================================================
RCS file: linux-2.6-scsi-async-double-add.patch
diff -N linux-2.6-scsi-async-double-add.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-scsi-async-double-add.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,155 @@
+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:
Index: linux-2.6-scsi-bounce-isa.patch
===================================================================
RCS file: linux-2.6-scsi-bounce-isa.patch
diff -N linux-2.6-scsi-bounce-isa.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-scsi-bounce-isa.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,14 @@
+
+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:
Index: linux-2.6-scsi-mpt-vmware-fix.patch
===================================================================
RCS file: linux-2.6-scsi-mpt-vmware-fix.patch
diff -N linux-2.6-scsi-mpt-vmware-fix.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-scsi-mpt-vmware-fix.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,43 @@
+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:
Index: linux-2.6-smarter-relatime.patch
===================================================================
RCS file: linux-2.6-smarter-relatime.patch
diff -N linux-2.6-smarter-relatime.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-smarter-relatime.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,268 @@
+
+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:
Index: linux-2.6-softirq-printout-irq-trace-events.patch
===================================================================
RCS file: linux-2.6-softirq-printout-irq-trace-events.patch
diff -N linux-2.6-softirq-printout-irq-trace-events.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-softirq-printout-irq-trace-events.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,145 @@
+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:
Index: linux-2.6-suspend-ordering.patch
===================================================================
RCS file: linux-2.6-suspend-ordering.patch
diff -N linux-2.6-suspend-ordering.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-suspend-ordering.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,152 @@
+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:
Index: linux-2.6-sysfs-inode-allocator-oops.patch
===================================================================
RCS file: linux-2.6-sysfs-inode-allocator-oops.patch
diff -N linux-2.6-sysfs-inode-allocator-oops.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-sysfs-inode-allocator-oops.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,170 @@
+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:
Index: linux-2.6-udf-2.6.22-rc2-1-udf_data_corruption.patch
===================================================================
RCS file: linux-2.6-udf-2.6.22-rc2-1-udf_data_corruption.patch
diff -N linux-2.6-udf-2.6.22-rc2-1-udf_data_corruption.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-udf-2.6.22-rc2-1-udf_data_corruption.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,36 @@
+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:
Index: linux-2.6-udf-2.6.22-rc4-1-udf_block_leak.patch
===================================================================
RCS file: linux-2.6-udf-2.6.22-rc4-1-udf_block_leak.patch
diff -N linux-2.6-udf-2.6.22-rc4-1-udf_block_leak.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-udf-2.6.22-rc4-1-udf_block_leak.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,170 @@
+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:
Index: linux-2.6-usb-autosuspend-default-disable.patch
===================================================================
RCS file: linux-2.6-usb-autosuspend-default-disable.patch
diff -N linux-2.6-usb-autosuspend-default-disable.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-usb-autosuspend-default-disable.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,17 @@
+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:
Index: linux-2.6-usb-storage-initialize-huawei-e220-properly.patch
===================================================================
RCS file: linux-2.6-usb-storage-initialize-huawei-e220-properly.patch
diff -N linux-2.6-usb-storage-initialize-huawei-e220-properly.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-usb-storage-initialize-huawei-e220-properly.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,76 @@
+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:
Index: linux-2.6-usb-suspend-classes.patch
===================================================================
RCS file: linux-2.6-usb-suspend-classes.patch
diff -N linux-2.6-usb-suspend-classes.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-usb-suspend-classes.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,128 @@
+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:
View full diff with command:
/usr/bin/cvs -f diff -kk -u -N -r 1.1 -r 1.2 linux-2.6-utrace-core.patch
Index: linux-2.6-utrace-core.patch
===================================================================
RCS file: linux-2.6-utrace-core.patch
diff -N linux-2.6-utrace-core.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-utrace-core.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,3692 @@
+[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)) {
[...3299 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:
Index: linux-2.6-utrace-ptrace-compat-avr32.patch
===================================================================
RCS file: linux-2.6-utrace-ptrace-compat-avr32.patch
diff -N linux-2.6-utrace-ptrace-compat-avr32.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-utrace-ptrace-compat-avr32.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,144 @@
+[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:
Index: linux-2.6-utrace-ptrace-compat-ia64.patch
===================================================================
RCS file: linux-2.6-utrace-ptrace-compat-ia64.patch
diff -N linux-2.6-utrace-ptrace-compat-ia64.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-utrace-ptrace-compat-ia64.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,1110 @@
+[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, ¤t->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:
Index: linux-2.6-utrace-ptrace-compat-s390.patch
===================================================================
RCS file: linux-2.6-utrace-ptrace-compat-s390.patch
diff -N linux-2.6-utrace-ptrace-compat-s390.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-utrace-ptrace-compat-s390.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,188 @@
+[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:
Index: linux-2.6-utrace-ptrace-compat-sparc64.patch
===================================================================
RCS file: linux-2.6-utrace-ptrace-compat-sparc64.patch
diff -N linux-2.6-utrace-ptrace-compat-sparc64.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-utrace-ptrace-compat-sparc64.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,601 @@
+[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:
Index: linux-2.6-utrace-ptrace-compat-xen.patch
===================================================================
RCS file: linux-2.6-utrace-ptrace-compat-xen.patch
diff -N linux-2.6-utrace-ptrace-compat-xen.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-utrace-ptrace-compat-xen.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,13 @@
+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:
View full diff with command:
/usr/bin/cvs -f diff -kk -u -N -r 1.1 -r 1.2 linux-2.6-utrace-ptrace-compat.patch
Index: linux-2.6-utrace-ptrace-compat.patch
===================================================================
RCS file: linux-2.6-utrace-ptrace-compat.patch
diff -N linux-2.6-utrace-ptrace-compat.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-utrace-ptrace-compat.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,3146 @@
+[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:
[...2753 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:
Index: linux-2.6-utrace-recalc_sigpending_and_wake.patch
===================================================================
RCS file: linux-2.6-utrace-recalc_sigpending_and_wake.patch
diff -N linux-2.6-utrace-recalc_sigpending_and_wake.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-utrace-recalc_sigpending_and_wake.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,139 @@
+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:
Index: linux-2.6-utrace-regset-avr32.patch
===================================================================
RCS file: linux-2.6-utrace-regset-avr32.patch
diff -N linux-2.6-utrace-regset-avr32.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-utrace-regset-avr32.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,156 @@
+[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:
Index: linux-2.6-utrace-regset-ia64.patch
===================================================================
RCS file: linux-2.6-utrace-regset-ia64.patch
diff -N linux-2.6-utrace-regset-ia64.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-utrace-regset-ia64.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,1456 @@
+[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(®s);
+ }
+ }
++
++/* 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:
Index: linux-2.6-utrace-regset-s390.patch
===================================================================
RCS file: linux-2.6-utrace-regset-s390.patch
diff -N linux-2.6-utrace-regset-s390.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-utrace-regset-s390.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,1071 @@
+[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,
++ ®s->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,
++ ®s->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,
++ ®s->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,
++ ®s->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:
Index: linux-2.6-utrace-regset-sparc64.patch
===================================================================
RCS file: linux-2.6-utrace-regset-sparc64.patch
diff -N linux-2.6-utrace-regset-sparc64.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-utrace-regset-sparc64.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,732 @@
+[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,
++ ®s->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,
++ ®s->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 = ®s->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:
View full diff with command:
/usr/bin/cvs -f diff -kk -u -N -r 1.1 -r 1.2 linux-2.6-utrace-regset.patch
Index: linux-2.6-utrace-regset.patch
===================================================================
RCS file: linux-2.6-utrace-regset.patch
diff -N linux-2.6-utrace-regset.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-utrace-regset.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,4749 @@
+[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 )
[...4356 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:
Index: linux-2.6-utrace-sig_kernel-macros.patch
===================================================================
RCS file: linux-2.6-utrace-sig_kernel-macros.patch
diff -N linux-2.6-utrace-sig_kernel-macros.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-utrace-sig_kernel-macros.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,287 @@
+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:
Index: linux-2.6-utrace-tracehook-avr32.patch
===================================================================
RCS file: linux-2.6-utrace-tracehook-avr32.patch
diff -N linux-2.6-utrace-tracehook-avr32.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-utrace-tracehook-avr32.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,266 @@
+[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:
Index: linux-2.6-utrace-tracehook-ia64.patch
===================================================================
RCS file: linux-2.6-utrace-tracehook-ia64.patch
diff -N linux-2.6-utrace-tracehook-ia64.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-utrace-tracehook-ia64.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,258 @@
+[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(®s, 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(®s, 1);
++
++ if (test_thread_flag(TIF_SINGLESTEP)) {
++ force_sig(SIGTRAP, current); /* XXX */
++ tracehook_report_syscall_step(®s);
++ }
+ }
+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(¤t->blocked, sig);
+ recalc_sigpending();
+ spin_unlock_irq(¤t->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:
Index: linux-2.6-utrace-tracehook-s390.patch
===================================================================
RCS file: linux-2.6-utrace-tracehook-s390.patch
diff -N linux-2.6-utrace-tracehook-s390.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-utrace-tracehook-s390.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,277 @@
+[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(¤t->blocked,sig);
+ recalc_sigpending();
+ spin_unlock_irq(¤t->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(¤t->blocked,sig);
+ recalc_sigpending();
+ spin_unlock_irq(¤t->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:
Index: linux-2.6-utrace-tracehook-sparc64.patch
===================================================================
RCS file: linux-2.6-utrace-tracehook-sparc64.patch
diff -N linux-2.6-utrace-tracehook-sparc64.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-utrace-tracehook-sparc64.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,206 @@
+[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(¤t->blocked,signr);
+ recalc_sigpending();
+ spin_unlock_irq(¤t->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(¤t->blocked,signr);
+ recalc_sigpending();
+ spin_unlock_irq(¤t->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:
Index: linux-2.6-utrace-tracehook-um.patch
===================================================================
RCS file: linux-2.6-utrace-tracehook-um.patch
diff -N linux-2.6-utrace-tracehook-um.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-utrace-tracehook-um.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,618 @@
+[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(®s->regs) ?
++ (void __user *) UPT_IP(®s->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(®s->regs)),
++ UPT_SYSCALL_RET(®s->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(®s->regs),
++ UPT_SYSCALL_ARG1(®s->regs),
++ UPT_SYSCALL_ARG2(®s->regs),
++ UPT_SYSCALL_ARG3(®s->regs),
++ UPT_SYSCALL_ARG4(®s->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(¤t->blocked, signr);
+ recalc_sigpending();
+ spin_unlock_irq(¤t->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(¤t->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, ¤t->thread.regs);
+ if (error == 0){
+ task_lock(current);
+- current->ptrace &= ~PT_DTRACE;
+ #ifdef SUBARCH_EXECVE1
+ SUBARCH_EXECVE1(¤t->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:
Index: linux-2.6-utrace-tracehook-xen.patch
===================================================================
RCS file: linux-2.6-utrace-tracehook-xen.patch
diff -N linux-2.6-utrace-tracehook-xen.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-utrace-tracehook-xen.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,130 @@
+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,
+ ®s);
+ 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, ®s);
+- 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:
View full diff with command:
/usr/bin/cvs -f diff -kk -u -N -r 1.1 -r 1.2 linux-2.6-utrace-tracehook.patch
Index: linux-2.6-utrace-tracehook.patch
===================================================================
RCS file: linux-2.6-utrace-tracehook.patch
diff -N linux-2.6-utrace-tracehook.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-utrace-tracehook.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,4135 @@
+[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;
+
[...3742 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:
Index: linux-2.6-vm-invalidate_mapping_pages-cond-resched.patch
===================================================================
RCS file: linux-2.6-vm-invalidate_mapping_pages-cond-resched.patch
diff -N linux-2.6-vm-invalidate_mapping_pages-cond-resched.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-vm-invalidate_mapping_pages-cond-resched.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,230 @@
+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$
+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:
Index: linux-2.6-wakeups-hdaps.patch
===================================================================
RCS file: linux-2.6-wakeups-hdaps.patch
diff -N linux-2.6-wakeups-hdaps.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-wakeups-hdaps.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,62 @@
+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:
Index: linux-2.6-wakeups.patch
===================================================================
RCS file: linux-2.6-wakeups.patch
diff -N linux-2.6-wakeups.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-wakeups.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,13 @@
+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:
View full diff with command:
/usr/bin/cvs -f diff -kk -u -N -r 1.1 -r 1.2 linux-2.6-wireless.patch
Index: linux-2.6-wireless.patch
===================================================================
RCS file: linux-2.6-wireless.patch
diff -N linux-2.6-wireless.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-wireless.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,23814 @@
+--- 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
[...23421 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:
Index: linux-2.6-x86-64_pmtrace.patch
===================================================================
RCS file: linux-2.6-x86-64_pmtrace.patch
diff -N linux-2.6-x86-64_pmtrace.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-x86-64_pmtrace.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,221 @@
+ 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:
Index: linux-2.6-x86-clean-up-oops-bug-reports.patch
===================================================================
RCS file: linux-2.6-x86-clean-up-oops-bug-reports.patch
diff -N linux-2.6-x86-clean-up-oops-bug-reports.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-x86-clean-up-oops-bug-reports.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,117 @@
+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:
Index: linux-2.6-x86-debug-boot.patch
===================================================================
RCS file: linux-2.6-x86-debug-boot.patch
diff -N linux-2.6-x86-debug-boot.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-x86-debug-boot.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,104 @@
+---
+ 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:
Index: linux-2.6-x86-dell-hpet.patch
===================================================================
RCS file: linux-2.6-x86-dell-hpet.patch
diff -N linux-2.6-x86-dell-hpet.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-x86-dell-hpet.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,304 @@
+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$
+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:
Index: linux-2.6-x86-dont-delete-cpu_devs-data.patch
===================================================================
RCS file: linux-2.6-x86-dont-delete-cpu_devs-data.patch
diff -N linux-2.6-x86-dont-delete-cpu_devs-data.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-x86-dont-delete-cpu_devs-data.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,171 @@
+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] = ¢aur_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:
Index: linux-2.6-x86-fsc-interrupt-controller-quirk.patch
===================================================================
RCS file: linux-2.6-x86-fsc-interrupt-controller-quirk.patch
diff -N linux-2.6-x86-fsc-interrupt-controller-quirk.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-x86-fsc-interrupt-controller-quirk.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,95 @@
+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:
Index: linux-2.6-x86_64-ia32-vdso-install-unstripped-copies-on-disk.patch
===================================================================
RCS file: linux-2.6-x86_64-ia32-vdso-install-unstripped-copies-on-disk.patch
diff -N linux-2.6-x86_64-ia32-vdso-install-unstripped-copies-on-disk.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-x86_64-ia32-vdso-install-unstripped-copies-on-disk.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,80 @@
+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:
Index: linux-2.6-x86_64-silence-up-apic-errors-xen.patch
===================================================================
RCS file: linux-2.6-x86_64-silence-up-apic-errors-xen.patch
diff -N linux-2.6-x86_64-silence-up-apic-errors-xen.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-x86_64-silence-up-apic-errors-xen.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,14 @@
+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:
Index: linux-2.6-x86_64-vdso-install-unstripped-copies-on-disk.patch
===================================================================
RCS file: linux-2.6-x86_64-vdso-install-unstripped-copies-on-disk.patch
diff -N linux-2.6-x86_64-vdso-install-unstripped-copies-on-disk.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-x86_64-vdso-install-unstripped-copies-on-disk.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,71 @@
+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:
Index: linux-2.6-xen-irq_vector-uninitialize.patch
===================================================================
RCS file: linux-2.6-xen-irq_vector-uninitialize.patch
diff -N linux-2.6-xen-irq_vector-uninitialize.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-xen-irq_vector-uninitialize.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,74 @@
+# 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:
Index: linux-2.6-xfs-optimize-away-dmapi-tests.patch
===================================================================
RCS file: linux-2.6-xfs-optimize-away-dmapi-tests.patch
diff -N linux-2.6-xfs-optimize-away-dmapi-tests.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-xfs-optimize-away-dmapi-tests.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,81 @@
+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:
Index: linux-2.6-xfs-optimize-away-realtime-tests.patch
===================================================================
RCS file: linux-2.6-xfs-optimize-away-realtime-tests.patch
diff -N linux-2.6-xfs-optimize-away-realtime-tests.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-xfs-optimize-away-realtime-tests.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,200 @@
+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:
Index: linux-2.6-xfs-refactor-xfs_mountfs.patch
===================================================================
RCS file: linux-2.6-xfs-refactor-xfs_mountfs.patch
diff -N linux-2.6-xfs-refactor-xfs_mountfs.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-xfs-refactor-xfs_mountfs.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,363 @@
+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:
Index: linux-2.6-xfs-setfattr-32bit-compat.patch
===================================================================
RCS file: linux-2.6-xfs-setfattr-32bit-compat.patch
diff -N linux-2.6-xfs-setfattr-32bit-compat.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-xfs-setfattr-32bit-compat.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,79 @@
+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:
View full diff with command:
/usr/bin/cvs -f diff -kk -u -N -r 1.1 -r 1.2 linux-2.6-zd1211rw-mac80211.patch
Index: linux-2.6-zd1211rw-mac80211.patch
===================================================================
RCS file: linux-2.6-zd1211rw-mac80211.patch
diff -N linux-2.6-zd1211rw-mac80211.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6-zd1211rw-mac80211.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,8027 @@
+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;
++
[...7634 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"
+
Index: linux-2.6.21.7-xen-3.1.0.patch.bz2
===================================================================
RCS file: linux-2.6.21.7-xen-3.1.0.patch.bz2
diff -N linux-2.6.21.7-xen-3.1.0.patch.bz2
Binary files /dev/null and /tmp/cvsKeg5sc differ
Index: linux-2.6.21.tar.bz2.sign
===================================================================
RCS file: linux-2.6.21.tar.bz2.sign
diff -N linux-2.6.21.tar.bz2.sign
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6.21.tar.bz2.sign 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,8 @@
+-----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-----
Index: linux-2.6.23.tar.bz2.sign
===================================================================
RCS file: linux-2.6.23.tar.bz2.sign
diff -N linux-2.6.23.tar.bz2.sign
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ linux-2.6.23.tar.bz2.sign 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,8 @@
+-----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-----
Index: mirrors
===================================================================
RCS file: mirrors
diff -N mirrors
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ mirrors 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,4 @@
+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:
View full diff with command:
/usr/bin/cvs -f diff -kk -u -N -r 1.1 -r 1.2 nouveau-drm.patch
Index: nouveau-drm.patch
===================================================================
RCS file: nouveau-drm.patch
diff -N nouveau-drm.patch
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ nouveau-drm.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,7351 @@
+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}, \
[...6958 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)
++{
++}
++
Index: patch-2.6.21.7.bz2
===================================================================
RCS file: patch-2.6.21.7.bz2
diff -N patch-2.6.21.7.bz2
Binary files /dev/null and /tmp/cvsPK6erS differ
Index: patch-2.6.23-git2.bz2.sign
===================================================================
RCS file: patch-2.6.23-git2.bz2.sign
diff -N patch-2.6.23-git2.bz2.sign
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patch-2.6.23-git2.bz2.sign 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,8 @@
+-----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-----
Index: patch-2.6.23.1.bz2.sign
===================================================================
RCS file: patch-2.6.23.1.bz2.sign
diff -N patch-2.6.23.1.bz2.sign
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patch-2.6.23.1.bz2.sign 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,8 @@
+-----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-----
Index: upstream
===================================================================
RCS file: upstream
diff -N upstream
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ upstream 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1 @@
+linux-2.6.21.tar.bz2
Index: upstream-key.gpg
===================================================================
RCS file: upstream-key.gpg
diff -N upstream-key.gpg
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ upstream-key.gpg 12 Nov 2007 12:56:59 -0000 1.2
@@ -0,0 +1,54 @@
+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.2
diff -u -r1.1 -r1.2
--- Config.mk 24 Jan 2007 01:28:48 -0000 1.1
+++ Config.mk 12 Nov 2007 12:56:58 -0000 1.2
@@ -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.2
diff -u -r1.1 -r1.2
--- Makefile 24 Jan 2007 01:26:25 -0000 1.1
+++ Makefile 12 Nov 2007 12:56:58 -0000 1.2
@@ -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-xen-2.6
+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.2
diff -u -r1.1 -r1.2
--- config-rhel-generic 24 Jan 2007 01:28:48 -0000 1.1
+++ config-rhel-generic 12 Nov 2007 12:56:58 -0000 1.2
@@ -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.2
diff -u -r1.1 -r1.2
--- linux-2.6-common-uevent.patch 22 Mar 2007 16:01:16 -0000 1.1
+++ linux-2.6-common-uevent.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -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.3
diff -u -r1.2 -r1.3
--- linux-2.6-compile-fixes.patch 22 Mar 2007 15:40:59 -0000 1.2
+++ linux-2.6-compile-fixes.patch 12 Nov 2007 12:56:59 -0000 1.3
@@ -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.2
diff -u -r1.1 -r1.2
--- linux-2.6-crash-driver-xen.patch 24 Jan 2007 01:28:48 -0000 1.1
+++ linux-2.6-crash-driver-xen.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -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.2
diff -u -r1.1 -r1.2
--- linux-2.6-crash-driver.patch 24 Jan 2007 01:28:48 -0000 1.1
+++ linux-2.6-crash-driver.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -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.2
diff -u -r1.1 -r1.2
--- linux-2.6-debug-no-quiet.patch 24 Jan 2007 01:28:48 -0000 1.1
+++ linux-2.6-debug-no-quiet.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -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.2
diff -u -r1.1 -r1.2
--- linux-2.6-debug-sizeof-structs.patch 24 Jan 2007 01:28:48 -0000 1.1
+++ linux-2.6-debug-sizeof-structs.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -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.2
diff -u -r1.1 -r1.2
--- 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 12 Nov 2007 12:56:59 -0000 1.2
@@ -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.2
diff -u -r1.1 -r1.2
--- 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 12 Nov 2007 12:56:59 -0000 1.2
@@ -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.3
diff -u -r1.2 -r1.3
--- linux-2.6-debug-taint-vm.patch 22 Mar 2007 15:40:59 -0000 1.2
+++ linux-2.6-debug-taint-vm.patch 12 Nov 2007 12:56:59 -0000 1.3
@@ -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.2
diff -u -r1.1 -r1.2
--- linux-2.6-devmem-xen.patch 24 Jan 2007 01:28:48 -0000 1.1
+++ linux-2.6-devmem-xen.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -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.3
diff -u -r1.2 -r1.3
--- linux-2.6-devmem.patch 22 Mar 2007 15:40:59 -0000 1.2
+++ linux-2.6-devmem.patch 12 Nov 2007 12:56:59 -0000 1.3
@@ -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.2
diff -u -r1.1 -r1.2
--- linux-2.6-disable-netback-checksum.patch 7 May 2007 18:47:08 -0000 1.1
+++ linux-2.6-disable-netback-checksum.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -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.3
diff -u -r1.2 -r1.3
--- linux-2.6-execshield.patch 22 Mar 2007 15:40:59 -0000 1.2
+++ linux-2.6-execshield.patch 12 Nov 2007 12:56:59 -0000 1.3
@@ -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.2 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.2
diff -u -r1.1 -r1.2
--- linux-2.6-firewire.patch 22 Mar 2007 16:01:16 -0000 1.1
+++ linux-2.6-firewire.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -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.2 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.2
diff -u -r1.1 -r1.2
--- linux-2.6-gfs2-update.patch 24 Jan 2007 01:28:48 -0000 1.1
+++ linux-2.6-gfs2-update.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -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.3
diff -u -r1.2 -r1.3
--- linux-2.6-modsign-core.patch 22 Mar 2007 15:40:59 -0000 1.2
+++ linux-2.6-modsign-core.patch 12 Nov 2007 12:56:59 -0000 1.3
@@ -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.3
diff -u -r1.2 -r1.3
--- linux-2.6-modsign-crypto.patch 22 Mar 2007 15:40:59 -0000 1.2
+++ linux-2.6-modsign-crypto.patch 12 Nov 2007 12:56:59 -0000 1.3
@@ -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.3
diff -u -r1.2 -r1.3
--- linux-2.6-modsign-include.patch 22 Mar 2007 15:40:59 -0000 1.2
+++ linux-2.6-modsign-include.patch 12 Nov 2007 12:56:59 -0000 1.3
@@ -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.3
diff -u -r1.2 -r1.3
--- linux-2.6-modsign-ksign.patch 22 Mar 2007 15:40:59 -0000 1.2
+++ linux-2.6-modsign-ksign.patch 12 Nov 2007 12:56:59 -0000 1.3
@@ -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.3 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.3
diff -u -r1.2 -r1.3
--- linux-2.6-modsign-mpilib.patch 22 Mar 2007 15:40:59 -0000 1.2
+++ linux-2.6-modsign-mpilib.patch 12 Nov 2007 12:56:59 -0000 1.3
@@ -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.3
diff -u -r1.2 -r1.3
--- linux-2.6-modsign-script.patch 22 Mar 2007 15:40:59 -0000 1.2
+++ linux-2.6-modsign-script.patch 12 Nov 2007 12:56:59 -0000 1.3
@@ -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(§ions[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(§ions[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.3
diff -u -r1.2 -r1.3
--- linux-2.6-silence-noise.patch 22 Mar 2007 15:40:59 -0000 1.2
+++ linux-2.6-silence-noise.patch 12 Nov 2007 12:56:59 -0000 1.3
@@ -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.3
diff -u -r1.2 -r1.3
--- linux-2.6-squashfs.patch 22 Mar 2007 15:40:59 -0000 1.2
+++ linux-2.6-squashfs.patch 12 Nov 2007 12:56:59 -0000 1.3
@@ -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.2
diff -u -r1.1 -r1.2
--- linux-2.6-xen-backwards-time.patch 9 Aug 2007 17:19:55 -0000 1.1
+++ linux-2.6-xen-backwards-time.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -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.2
diff -u -r1.1 -r1.2
--- 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 12 Nov 2007 12:56:59 -0000 1.2
@@ -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.7
diff -u -r1.6 -r1.7
--- sources 17 Jul 2007 14:21:11 -0000 1.6
+++ sources 12 Nov 2007 12:56:59 -0000 1.7
@@ -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.3
diff -u -r1.2 -r1.3
--- xen-compile-fix.patch 30 Apr 2007 22:09:41 -0000 1.2
+++ xen-compile-fix.patch 12 Nov 2007 12:56:59 -0000 1.3
@@ -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.4
diff -u -r1.3 -r1.4
--- xen-version-strings.patch 7 May 2007 18:47:08 -0000 1.3
+++ xen-version-strings.patch 12 Nov 2007 12:56:59 -0000 1.4
@@ -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.2
diff -u -r1.1 -r1.2
--- xen-vmx-fpu-ts-fix.patch 21 Sep 2007 15:13:42 -0000 1.1
+++ xen-vmx-fpu-ts-fix.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -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.2
diff -u -r1.1 -r1.2
--- xen-vpic-irqbase-mode.patch 13 Sep 2007 19:57:59 -0000 1.1
+++ xen-vpic-irqbase-mode.patch 12 Nov 2007 12:56:59 -0000 1.2
@@ -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 ---
--- 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 ---
- Previous message: rpms/kernel-xen-2.6/F-7/scripts bumpspecfile.py, 1.1, 1.2 configcommon.pl, 1.1, 1.2 configdiff.pl, 1.1, 1.2 cross-amd64.sh, 1.1, 1.2 cross-i586.sh, 1.1, 1.2 cross-i686.sh, 1.1, 1.2 cross-ia64.sh, 1.1, 1.2 cross-iseries.sh, 1.1, 1.2 cross-ppc.sh, 1.1, 1.2 cross-ppc64.sh, 1.1, 1.2 cross-ppc8260.sh, 1.1, 1.2 cross-ppc8560.sh, 1.1, 1.2 cross-pseries.sh, 1.1, 1.2 cross-s390.sh, 1.1, 1.2 cross-s390x.sh, 1.1, 1.2 newpatch.sh, 1.1, 1.2 pull-upstreams.sh, 1.1, 1.2 rebase-xen-hv.sh, 1.1, 1.2 rebase-xen-kernel.sh, 1.1, 1.2 rebase.sh, 1.1, 1.2 reconfig.sh, 1.1, 1.2 rediffall.pl, 1.1, 1.2
- Next message: rpms/kernel-xen-2.6/F-7 kernel.spec,1.2,1.3
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the scm-commits
mailing list