[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

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



Author: ehabkost

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

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

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




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

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

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

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

CONFIG_SLUB_DEBUG_ON=y

CONFIG_LOCK_STAT=y

CONFIG_DEBUG_STACK_USAGE=y

CONFIG_ACPI_DEBUG=y
# CONFIG_ACPI_DEBUG_FUNC_TRACE is not set

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

CONFIG_SLUB=y

CONFIG_MISC_DEVICES=y

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

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

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

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

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

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

#
# Device Drivers
#

#
# Generic Driver Options
#
CONFIG_FW_LOADER=y

# CONFIG_SPI is not set

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

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

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

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

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

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

# CONFIG_PCWATCHDOG is not set
# CONFIG_WDT is not set

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

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

## END of ISA options.

# CONFIG_FORCED_INLINING is not set

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

CONFIG_DMA_ENGINE=y
CONFIG_NET_DMA=y
CONFIG_INTEL_IOATDMA=m

# CONFIG_UNUSED_SYMBOLS is not set

CONFIG_UTRACE=y
CONFIG_PTRACE=y

CONFIG_KPROBES=y

# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set

CONFIG_HZ_1000=y

CONFIG_TIMER_STATS=y

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

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

CONFIG_CPU_IDLE=y
# CONFIG_CPU_IDLE_GOV_LADDER is not set
CONFIG_CPU_IDLE_GOV_MENU=y

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

CONFIG_AUXDISPLAY=y

CONFIG_UIO=m
CONFIG_UIO_CIF=m

CONFIG_INSTRUMENTATION=y
# CONFIG_CRC7 is not set

CONFIG_DEFAULT_RELATIME=y

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


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

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

CONFIG_X86_POWERNOW_K6=m


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

CONFIG_CRYPTO_DEV_PADLOCK=m
CONFIG_CRYPTO_DEV_PADLOCK_AES=m
CONFIG_CRYPTO_DEV_PADLOCK_SHA=m


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



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



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

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

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

#
# Character devices
#

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


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

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

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

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

#
# SGI
#
CONFIG_SGI_SNSC=y
CONFIG_IA64_SGI_SN_XP=y

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

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

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

CONFIG_SCHED_SMT=y
CONFIG_SGI_TIOCX=y
CONFIG_SGI_MBCS=m

CONFIG_ARCH_DISCONTIGMEM_ENABLE=y

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

CONFIG_IA64_ACPI_CPUFREQ=m

# CONFIG_CRASH is not set

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

# CONFIG_PERMIT_BSP_REMOVE is not set
# CONFIG_FORCE_CPEI_RETARGET is not set

CONFIG_NODES_SHIFT=10

# CONFIG_BCM43XX is not set

CONFIG_HW_RANDOM_INTEL=m

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

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

# CONFIG_IA64_MC_ERR_INJECT is not set

CONFIG_DMIID=y


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

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

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

CONFIG_SLUB_DEBUG_ON=y

CONFIG_LOCK_STAT=y

CONFIG_DEBUG_STACK_USAGE=y

# CONFIG_ACPI_DEBUG is not set


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

CONFIG_TAU=y
# CONFIG_TAU_INT is not set
CONFIG_TAU_AVERAGE=y

CONFIG_SECCOMP=y

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

CONFIG_PM=y

CONFIG_PM_STD_PARTITION=""

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

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

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

CONFIG_XMON=y
CONFIG_XMON_DEFAULT=y
CONFIG_XMON_DISASSEMBLY=y

CONFIG_BOOTX_TEXT=y
CONFIG_MAC_EMUMOUSEBTN=y
CONFIG_CAPI_EICON=y

CONFIG_NVRAM=y

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

CONFIG_MEMORY_HOTPLUG=y

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

CONFIG_USB_HIDINPUT_POWERBOOK=y

# CONFIG_PPC_EARLY_DEBUG is not set

# CONFIG_PMAC_BACKLIGHT_LEGACY is not set
CONFIG_LEDS_TRIGGER_TIMER=m
CONFIG_LEDS_TRIGGER_HEARTBEAT=m

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

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

CONFIG_SERIAL_UARTLITE=m
CONFIG_SERIAL_UARTLITE_CONSOLE=y

CONFIG_SENSORS_AMS=m
CONFIG_SENSORS_AMS_PMU=y
CONFIG_SENSORS_AMS_I2C=y

CONFIG_IDE=y
CONFIG_BLK_DEV_IDE=y

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

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

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

CONFIG_AXON_RAM=m
CONFIG_OPROFILE_CELL=y

# CONFIG_MPC5200_WDT is not set


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

CONFIG_PMAC_APM_EMU=y
CONFIG_PMAC_BACKLIGHT=y

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

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

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

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

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

# CONFIG_CRASH is not set

# CONFIG_HVC_RTAS is not set
# CONFIG_MAMBO is not set

# CONFIG_UDBG_RTAS_CONSOLE is not set
CONFIG_BRIQ_PANEL=m

CONFIG_PATA_MPC52xx=m

CONFIG_PPC_MPC5200_BUGFIX=y
CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_DEBUG_STACKOVERFLOW=y


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


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

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

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

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

CONFIG_HVC_BEAT=y

CONFIG_FB_PS3=y
CONFIG_FB_PS3_DEFAULT_SIZE_M=18

CONFIG_PPC_PMI=m
CONFIG_PS3_SYS_MANAGER=y
# CONFIG_BLK_DEV_CELLEB is not set

CONFIG_PATA_SCC=m

CONFIG_APM_EMULATION=m

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

# CONFIG_POWER4_ONLY is not set
# CONFIG_PPC_PASEMI is not set

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

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

CONFIG_EHEA=m
CONFIG_INFINIBAND_EHCA=m
CONFIG_INFINIBAND_EHCA_SCALING=y

CONFIG_HCALL_STATS=y

CONFIG_XMON_DISASSEMBLY=y

CONFIG_SCSI_IBMVSCSIS=m

CONFIG_SECCOMP=y


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


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

CONFIG_MMU=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y

CONFIG_LOG_BUF_SHIFT=16
CONFIG_NO_IDLE_HZ=y
CONFIG_NO_IDLE_HZ_INIT=y

CONFIG_SMP=y

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

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

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

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

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

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


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

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

# CONFIG_PPP is not set
# CONFIG_SLIP is not set

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

#
# Wan interfaces
#
# CONFIG_WAN is not set

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

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

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

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


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

#
# Kernel hacking
#

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

CONFIG_ZVM_WATCHDOG=m
CONFIG_VMLOGRDR=m
CONFIG_MONREADER=m

CONFIG_VIRT_CPU_ACCOUNTING=y

# CONFIG_CLAW is not set

CONFIG_VMCP=m

# CONFIG_ATMEL is not set

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

# CONFIG_BOOT_DELAY is not set

CONFIG_STACK_GUARD=256
CONFIG_CMM_IUCV=y

# CONFIG_DETECT_SOFTLOCKUP is not set

CONFIG_S390_HYPFS_FS=y

CONFIG_MONWRITER=m
CONFIG_ZCRYPT=m
CONFIG_ZCRYPT_MONOLITHIC=y

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

CONFIG_S390_VMUR=m



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


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


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


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



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

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

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



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


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

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

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

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

CONFIG_SECCOMP=y

CONFIG_CAPI_EICON=y

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

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

#
# Kernel debugging
#
CONFIG_X86_FIND_SMP_CONFIG=y
CONFIG_X86_MPPARSE=y

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

CONFIG_ASUS_LAPTOP=m

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

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

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

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

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

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

# CONFIG_DEBUG_PAGEALLOC is not set

CONFIG_PCI_DIRECT=y
CONFIG_PCI_MMCONFIG=y
CONFIG_PCI_BIOS=y

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

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

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

CONFIG_BLK_DEV_AMD74XX=y

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

# CONFIG_X86_REBOOTFIXUPS is not set

CONFIG_DELL_RBU=m
CONFIG_DCDBAS=m

CONFIG_PC8736x_GPIO=m
# CONFIG_NSC_GPIO is not set
CONFIG_CS5535_GPIO=m

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

CONFIG_SCHED_MC=y

CONFIG_SND_ES18XX=m

CONFIG_TCG_INFINEON=m

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

CONFIG_USB_HIDINPUT_POWERBOOK=y

# CONFIG_COMPAT_VDSO is not set

# CONFIG_SGI_IOC4 is not set
CONFIG_MSI_LAPTOP=m

# CONFIG_SMSC37B787_WDT is not set
CONFIG_W83697HF_WDT=m

CONFIG_PARAVIRT=y

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

CONFIG_CRYPTO_DEV_GEODE=m

CONFIG_VIDEO_CAFE_CCIC=m

CONFIG_KVM=m
CONFIG_KVM_INTEL=m
CONFIG_KVM_AMD=m

CONFIG_MTD_ESB2ROM=m
CONFIG_MTD_CK804XROM=m
CONFIG_MTD_NAND_CAFE=m

CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y

CONFIG_THINKPAD_ACPI=m
# CONFIG_THINKPAD_ACPI_DEBUG is not set
CONFIG_THINKPAD_ACPI_BAY=y

CONFIG_MACINTOSH_DRIVERS=y

CONFIG_DMIID=y

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


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

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

CONFIG_SECCOMP=y

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

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

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

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

CONFIG_THINKPAD_ACPI=m
# CONFIG_THINKPAD_ACPI_DEBUG is not set
CONFIG_THINKPAD_ACPI_BAY=y

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

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

CONFIG_PNP=y
CONFIG_PNPACPI=y

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

CONFIG_X86_MCE_INTEL=y
CONFIG_X86_MCE_AMD=y

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

CONFIG_DELL_RBU=m
CONFIG_DCDBAS=m

CONFIG_NVRAM=y

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

CONFIG_SCHED_MC=y

CONFIG_TCG_INFINEON=m

CONFIG_HW_RANDOM_INTEL=m
CONFIG_HW_RANDOM_AMD=m
CONFIG_HW_RANDOM_VIA=m

# CONFIG_HW_RANDOM_GEODE is not set

CONFIG_DEBUG_STACKOVERFLOW=y
CONFIG_DEBUG_NMI_TIMEOUT=5

CONFIG_PC8736x_GPIO=m

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

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

CONFIG_CC_STACKPROTECTOR=y
# CONFIG_CC_STACKPROTECTOR_ALL is not set

CONFIG_SGI_IOC4=m
# CONFIG_SGI_IOC4 is not set

# CONFIG_SMSC37B787_WDT is not set
CONFIG_W83697HF_WDT=m

CONFIG_VIDEO_CAFE_CCIC=m

CONFIG_KVM=m
CONFIG_KVM_INTEL=m
CONFIG_KVM_AMD=m

CONFIG_MTD_ESB2ROM=m
CONFIG_MTD_CK804XROM=m

CONFIG_RELOCATABLE=y
CONFIG_MACINTOSH_DRIVERS=y

CONFIG_CRASH_DUMP=y
CONFIG_PHYSICAL_START=0x1000000
CONFIG_PROC_VMCORE=y

CONFIG_DMIID=y

CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y

CONFIG_VIRTUALIZATION=y


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

CONFIG_XEN_PCIDEV_FRONTEND=y
# CONFIG_XEN_PCIDEV_FE_DEBUG is not set


CONFIG_XEN=y
CONFIG_XEN_INTERFACE_VERSION=0x00030202

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

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

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

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

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

# CONFIG_HZ_1000 is not set
CONFIG_HZ_250=y

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



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

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

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

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

# Missing function not exported
# CONFIG_XEN_BLKDEV_TAP is not set


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

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


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

CONFIG_X86_64=y

# CONFIG_X86_XEN is not set
CONFIG_X86_64_XEN=y

CONFIG_GENERIC_CPU=y

drm-mm-git.patch:

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


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

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

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

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

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

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

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

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

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

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

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

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

for branch; do

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

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

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

  usepatch $file
  log $branch_rev branch $branch

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

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

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

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

"

git-wireless-dev.patch:

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


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

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

#
# General setup
#
CONFIG_LOCALVERSION=""
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_IPC_NS=y
CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
CONFIG_TASKSTATS=y
CONFIG_TASK_DELAY_ACCT=y
CONFIG_TASK_XACCT=y
CONFIG_TASK_IO_ACCOUNTING=y
CONFIG_UTS_NS=y
CONFIG_AUDIT=y
CONFIG_AUDITSYSCALL=y
# CONFIG_IKCONFIG is not set
CONFIG_CPUSETS=y
CONFIG_SYSFS_DEPRECATED=y
CONFIG_RELAY=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
# CONFIG_EMBEDDED is not set
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
CONFIG_KALLSYMS_EXTRA_PASS=y
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_SHMEM=y
CONFIG_SLAB=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
# CONFIG_SLOB is not set

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

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

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

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

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

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

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

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

#
# Security options
#
CONFIG_KEYS=y
CONFIG_KEYS_DEBUG_PROC_KEYS=y
CONFIG_SECURITY=y
CONFIG_SECURITY_NETWORK=y
CONFIG_SECURITY_NETWORK_XFRM=y
CONFIG_SECURITY_CAPABILITIES=y
# CONFIG_SECURITY_ROOTPLUG is not set
CONFIG_SECURITY_SELINUX=y
CONFIG_SECURITY_SELINUX_BOOTPARAM=y
CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1
CONFIG_SECURITY_SELINUX_DISABLE=y
CONFIG_SECURITY_SELINUX_DEVELOP=y
CONFIG_SECURITY_SELINUX_AVC_STATS=y
CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set
# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set

#
# Cryptographic options
#
CONFIG_CRYPTO=y
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_BLKCIPHER=m
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_XCBC=m
CONFIG_CRYPTO_NULL=m
CONFIG_CRYPTO_MD4=m
CONFIG_CRYPTO_MD5=y
CONFIG_CRYPTO_SHA1=y
CONFIG_CRYPTO_SHA256=m
CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_TGR192=m
CONFIG_CRYPTO_GF128MUL=m
CONFIG_CRYPTO_ECB=m
CONFIG_CRYPTO_CBC=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_DES=m
CONFIG_CRYPTO_FCRYPT=m
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_TWOFISH_COMMON=m
# CONFIG_CRYPTO_TWOFISH_586 is not set
CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_AES=m
# CONFIG_CRYPTO_AES_586 is not set
CONFIG_CRYPTO_CAST5=m
CONFIG_CRYPTO_CAST6=m
CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_KHAZAD=m
CONFIG_CRYPTO_ANUBIS=m
CONFIG_CRYPTO_DEFLATE=m
CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_CRC32C=m
CONFIG_CRYPTO_CAMELLIA=m
# CONFIG_CRYPTO_TEST is not set
CONFIG_CRYPTO_MPILIB=y
CONFIG_CRYPTO_SIGNATURE=y
CONFIG_CRYPTO_SIGNATURE_DSA=y

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

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

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


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

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

#
# General setup
#
CONFIG_LOCALVERSION=""
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_IPC_NS=y
CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
CONFIG_BSD_PROCESS_ACCT=y
# CONFIG_BSD_PROCESS_ACCT_V3 is not set
CONFIG_TASKSTATS=y
CONFIG_TASK_DELAY_ACCT=y
CONFIG_TASK_XACCT=y
CONFIG_TASK_IO_ACCOUNTING=y
CONFIG_UTS_NS=y
CONFIG_AUDIT=y
CONFIG_AUDITSYSCALL=y
# CONFIG_IKCONFIG is not set
CONFIG_CPUSETS=y
CONFIG_SYSFS_DEPRECATED=y
CONFIG_RELAY=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
# CONFIG_EMBEDDED is not set
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
CONFIG_KALLSYMS_EXTRA_PASS=y
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_SHMEM=y
CONFIG_SLAB=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
# CONFIG_SLOB is not set

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

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

#
# Block layer
#
CONFIG_BLOCK=y
CONFIG_BLK_DEV_IO_TRACE=y

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

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

#
# Power management options
#

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

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

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

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

#
# Security options
#
CONFIG_KEYS=y
CONFIG_KEYS_DEBUG_PROC_KEYS=y
CONFIG_SECURITY=y
CONFIG_SECURITY_NETWORK=y
CONFIG_SECURITY_NETWORK_XFRM=y
CONFIG_SECURITY_CAPABILITIES=y
# CONFIG_SECURITY_ROOTPLUG is not set
CONFIG_SECURITY_SELINUX=y
CONFIG_SECURITY_SELINUX_BOOTPARAM=y
CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1
CONFIG_SECURITY_SELINUX_DISABLE=y
CONFIG_SECURITY_SELINUX_DEVELOP=y
CONFIG_SECURITY_SELINUX_AVC_STATS=y
CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
# CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT is not set
# CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set

#
# Cryptographic options
#
CONFIG_CRYPTO=y
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_BLKCIPHER=m
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_MANAGER=y
CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_XCBC=m
CONFIG_CRYPTO_NULL=m
CONFIG_CRYPTO_MD4=m
CONFIG_CRYPTO_MD5=y
CONFIG_CRYPTO_SHA1=y
CONFIG_CRYPTO_SHA256=m
CONFIG_CRYPTO_SHA512=m
CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_TGR192=m
CONFIG_CRYPTO_GF128MUL=m
CONFIG_CRYPTO_ECB=m
CONFIG_CRYPTO_CBC=m
CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_DES=m
CONFIG_CRYPTO_FCRYPT=m
CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_TWOFISH_COMMON=m
CONFIG_CRYPTO_TWOFISH_X86_64=m
CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_AES=m
CONFIG_CRYPTO_AES_X86_64=m
CONFIG_CRYPTO_CAST5=m
CONFIG_CRYPTO_CAST6=m
CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_KHAZAD=m
CONFIG_CRYPTO_ANUBIS=m
CONFIG_CRYPTO_DEFLATE=m
CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_CRC32C=m
CONFIG_CRYPTO_CAMELLIA=m
# CONFIG_CRYPTO_TEST is not set
CONFIG_CRYPTO_MPILIB=y
CONFIG_CRYPTO_SIGNATURE=y
CONFIG_CRYPTO_SIGNATURE_DSA=y

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

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

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


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

--- NEW FILE linux-2.6-2110_scsi-sd-printing.patch ---
>From e73aec8247032ee730b5f38edf48922c4f72522e Mon Sep 17 00:00:00 2001
From: Martin K. Petersen <martin petersen 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 oracle com>
Signed-off-by: James Bottomley <James Bottomley SteelEye com>
---
 drivers/scsi/sd.c |  253 ++++++++++++++++++++---------------------------------
 include/scsi/sd.h |   70 +++++++++++++++
 2 files changed, 165 insertions(+), 158 deletions(-)
 create mode 100644 include/scsi/sd.h

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


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

--- NEW FILE linux-2.6-2111_sd-start-stop.patch ---
>From c3c94c5a2fb43a654e777f509d5032b0db8ed09f Mon Sep 17 00:00:00 2001
From: Tejun Heo <htejun 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 gmail com>

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

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


linux-2.6-2112_libata-suspend.patch:

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

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

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

--- NEW FILE linux-2.6-2113_libata-spindown-compat.patch ---
>From 920a4b1038e442700a1cfac77ea7e20bd615a2c3 Mon Sep 17 00:00:00 2001
From: Tejun Heo <htejun 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 gmail com>
Signed-off-by: Jeff Garzik <jeff garzik org>
---
 Documentation/feature-removal-schedule.txt |   19 +++++++++++++++++++
 drivers/ata/libata-core.c                  |    6 ++++++
 drivers/ata/libata-scsi.c                  |   28 +++++++++++++++++++++++++++-
 drivers/ata/libata.h                       |    1 +
 4 files changed, 53 insertions(+), 1 deletions(-)

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

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

--- NEW FILE linux-2.6-2114_libata-shutdown-warning.patch ---
>From da071b42f73dabbd0daf7ea4c3ff157d53b00648 Mon Sep 17 00:00:00 2001
From: Tejun Heo <htejun 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 gmail com>
Signed-off-by: Jeff Garzik <jeff garzik org>
---
 drivers/ata/libata-scsi.c |   35 +++++++++++++++++++++++++++--------
 1 files changed, 27 insertions(+), 8 deletions(-)

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


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

--- NEW FILE linux-2.6-2115_libata-spindown-status.patch ---
>From 13b8d09f5de0aaa3153bbccc98baf247387823dc Mon Sep 17 00:00:00 2001
From: Tejun Heo <htejun 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 gmail com>
Signed-off-by: Jeff Garzik <jeff garzik org>
---
 drivers/ata/libata-scsi.c |    9 +++++++++
 include/linux/libata.h    |    1 +
 2 files changed, 10 insertions(+), 0 deletions(-)

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


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

--- NEW FILE linux-2.6-2116_libata-remove-spindown-compat.patch ---
>From d9aca22cf443f5ed77d15a320abbab055ae4a976 Mon Sep 17 00:00:00 2001
From: Tejun Heo <htejun 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 gmail com>
Signed-off-by: Jeff Garzik <jeff garzik org>
---
 Documentation/feature-removal-schedule.txt |   25 ++++++++++++-------------
 drivers/ata/libata-core.c                  |    6 ------
 drivers/ata/libata-scsi.c                  |    9 ++++-----
 drivers/ata/libata.h                       |    1 -
 4 files changed, 16 insertions(+), 25 deletions(-)

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

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

--- NEW FILE linux-2.6-2117_sata-via-suspend.patch ---
Index: linux-2.6.21-gentoo-r2/drivers/ata/sata_via.c
===================================================================
--- linux-2.6.21-gentoo-r2.orig/drivers/ata/sata_via.c
+++ linux-2.6.21-gentoo-r2/drivers/ata/sata_via.c
@@ -120,10 +120,6 @@ static struct scsi_host_template svia_sh
 	.slave_configure	= ata_scsi_slave_config,
 	.slave_destroy		= ata_scsi_slave_destroy,
 	.bios_param		= ata_std_bios_param,
-#ifdef CONFIG_PM
-	.suspend		= ata_scsi_device_suspend,
-	.resume			= ata_scsi_device_resume,
-#endif
 };
 
 static const struct ata_port_operations vt6420_sata_ops = {

linux-2.6-2118_scsi-constants.patch:

--- NEW FILE linux-2.6-2118_scsi-constants.patch ---
From: Martin K. Petersen <martin petersen 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 oracle com>
Signed-off-by: James Bottomley <James Bottomley SteelEye com>
---

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

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

--- NEW FILE linux-2.6-acpi-boot-regression.patch ---
commit d5a3d32a042126f65a008e0e5204ef92ad2ee55d
Author: Venkatesh Pallipadi <venkatesh pallipadi 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 intel com>
    Signed-off-by: Len Brown <len brown intel com>

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

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

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

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

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

--- NEW FILE linux-2.6-acpi-git-ec-init-fixes.patch ---
From: Alexey Starikovskiy <astarikovskiy 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 suse de>
Signed-off-by: Len Brown <len brown intel com>
---

diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 3f7935a..9cd7997 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -121,6 +121,7 @@ static struct acpi_ec {
 	atomic_t event_count;
 	wait_queue_head_t wait;
 	struct list_head list;
+	u8 handlers_installed;
 } *boot_ec, *first_ec;
 
 /* --------------------------------------------------------------------------
@@ -680,32 +681,50 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval)
 	status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec->gpe);
 	if (ACPI_FAILURE(status))
 		return status;
-
 	/* Find and register all query methods */
 	acpi_walk_namespace(ACPI_TYPE_METHOD, handle, 1,
 			    acpi_ec_register_query_methods, ec, NULL);
-
 	/* Use the global lock for all EC transactions? */
 	acpi_evaluate_integer(handle, "_GLK", NULL, &ec->global_lock);
-
 	ec->handle = handle;
-
-	printk(KERN_INFO PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n",
-			  ec->gpe, ec->command_addr, ec->data_addr);
-
 	return AE_CTRL_TERMINATE;
 }
 
+static void ec_remove_handlers(struct acpi_ec *ec)
+{
+	if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle,
+				ACPI_ADR_SPACE_EC, &acpi_ec_space_handler)))
+		printk(KERN_ERR PREFIX "failed to remove space handler\n");
+	if (ACPI_FAILURE(acpi_remove_gpe_handler(NULL, ec->gpe,
+				&acpi_ec_gpe_handler)))
+		printk(KERN_ERR PREFIX "failed to remove gpe handler\n");
+	ec->handlers_installed = 0;
+}
+
 static int acpi_ec_add(struct acpi_device *device)
 {
 	struct acpi_ec *ec = NULL;
 
 	if (!device)
 		return -EINVAL;
-
 	strcpy(acpi_device_name(device), ACPI_EC_DEVICE_NAME);
 	strcpy(acpi_device_class(device), ACPI_EC_CLASS);
 
+	/* Check for boot EC */
+	if (boot_ec) {
+		if (boot_ec->handle == device->handle) {
+			/* Pre-loaded EC from DSDT, just move pointer */
+			ec = boot_ec;
+			boot_ec = NULL;
+			goto end;
+		} else if (boot_ec->handle == ACPI_ROOT_OBJECT) {
+			/* ECDT-based EC, time to shut it down */
+			ec_remove_handlers(boot_ec);
+			kfree(boot_ec);
+			first_ec = boot_ec = NULL;
+		}
+	}
+
 	ec = make_acpi_ec();
 	if (!ec)
 		return -ENOMEM;
@@ -715,25 +734,14 @@ static int acpi_ec_add(struct acpi_device *device)
 		kfree(ec);
 		return -EINVAL;
 	}
-
-	/* Check if we found the boot EC */
-	if (boot_ec) {
-		if (boot_ec->gpe == ec->gpe) {
-			/* We might have incorrect info for GL at boot time */
-			mutex_lock(&boot_ec->lock);
-			boot_ec->global_lock = ec->global_lock;
-			/* Copy handlers from new ec into boot ec */
-			list_splice(&ec->list, &boot_ec->list);
-			mutex_unlock(&boot_ec->lock);
-			kfree(ec);
-			ec = boot_ec;
-		}
-	} else
-		first_ec = ec;
 	ec->handle = device->handle;
+      end:
+	if (!first_ec)
+		first_ec = ec;
 	acpi_driver_data(device) = ec;
-
 	acpi_ec_add_fs(device);
+	printk(KERN_INFO PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n",
+			  ec->gpe, ec->command_addr, ec->data_addr);
 	return 0;
 }
 
@@ -756,10 +764,7 @@ static int acpi_ec_remove(struct acpi_device *device, int type)
 	acpi_driver_data(device) = NULL;
 	if (ec == first_ec)
 		first_ec = NULL;
-
-	/* Don't touch boot EC */
-	if (boot_ec != ec)
-		kfree(ec);
+	kfree(ec);
 	return 0;
 }
 
@@ -789,6 +794,8 @@ ec_parse_io_ports(struct acpi_resource *resource, void *context)
 static int ec_install_handlers(struct acpi_ec *ec)
 {
 	acpi_status status;
+	if (ec->handlers_installed)
+		return 0;
 	status = acpi_install_gpe_handler(NULL, ec->gpe,
 					  ACPI_GPE_EDGE_TRIGGERED,
 					  &acpi_ec_gpe_handler, ec);
@@ -807,6 +814,7 @@ static int ec_install_handlers(struct acpi_ec *ec)
 		return -ENODEV;
 	}
 
+	ec->handlers_installed = 1;
 	return 0;
 }
 
@@ -823,41 +831,22 @@ static int acpi_ec_start(struct acpi_device *device)
 	if (!ec)
 		return -EINVAL;
 
-	/* Boot EC is already working */
-	if (ec != boot_ec)
-		ret = ec_install_handlers(ec);
+	ret = ec_install_handlers(ec);
 
 	/* EC is fully operational, allow queries */
 	atomic_set(&ec->query_pending, 0);
-
 	return ret;
 }
 
 static int acpi_ec_stop(struct acpi_device *device, int type)
 {
-	acpi_status status;
 	struct acpi_ec *ec;
-
 	if (!device)
 		return -EINVAL;
-
 	ec = acpi_driver_data(device);
 	if (!ec)
 		return -EINVAL;
-
-	/* Don't touch boot EC */
-	if (ec == boot_ec)
-		return 0;
-
-	status = acpi_remove_address_space_handler(ec->handle,
-						   ACPI_ADR_SPACE_EC,
-						   &acpi_ec_space_handler);
-	if (ACPI_FAILURE(status))
-		return -ENODEV;
-
-	status = acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler);
-	if (ACPI_FAILURE(status))
-		return -ENODEV;
+	ec_remove_handlers(ec);
 
 	return 0;
 }
@@ -877,7 +866,7 @@ int __init acpi_ec_ecdt_probe(void)
 	status = acpi_get_table(ACPI_SIG_ECDT, 1,
 				(struct acpi_table_header **)&ecdt_ptr);
 	if (ACPI_SUCCESS(status)) {
-		printk(KERN_INFO PREFIX "EC description table is found, configuring boot EC\n\n");
+		printk(KERN_INFO PREFIX "EC description table is found, configuring boot EC\n");
 		boot_ec->command_addr = ecdt_ptr->control.address;
 		boot_ec->data_addr = ecdt_ptr->data.address;
 		boot_ec->gpe = ecdt_ptr->gpe;
@@ -899,7 +888,6 @@ int __init acpi_ec_ecdt_probe(void)
       error:
 	kfree(boot_ec);
 	boot_ec = NULL;
-
 	return -ENODEV;
 }
 

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

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

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

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

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

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

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

--- NEW FILE linux-2.6-acpi-preserve-ebx-in-acpi_copy_wakeup_routine.patch ---
Gitweb:     http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=c8cbee61c9d53ee28473ad33bbb54f6a88f5e3af
Commit:     c8cbee61c9d53ee28473ad33bbb54f6a88f5e3af
Parent:     e5d2861f31474b373ce7754dc5122b414a176c64
Author:     Tian Kevin <kevin tian intel com>
AuthorDate: Sat Jun 23 17:16:52 2007 -0700
Committer:  Linus Torvalds <torvalds 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 intel com>
    Looks-okay-to: Pavel Machek <pavel ucw cz>
    Signed-off-by: Rafael J. Wysocki <rjw sisk pl>
    Cc: Len Brown <lenb kernel org>
    Acked-by: Andi Kleen <ak suse de>
    Signed-off-by: Andrew Morton <akpm linux-foundation org>
    Signed-off-by: Linus Torvalds <torvalds linux-foundation org>
---
 arch/i386/kernel/acpi/wakeup.S |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

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

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

--- NEW FILE linux-2.6-acpi-unblacklist-dell-gx240.patch ---
>From davej  Wed May 23 17:33:54 2007
Return-Path: <linux-acpi-owner 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 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 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 vger kernel org) by vger.kernel.org via listexpand
	id S1755625AbXEWVYq (ORCPT <rfc822;prarit redhat com> + 1 other);
	Wed, 23 May 2007 17:24:46 -0400
Received: (majordomo 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 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 shell0 pdx osdl net>
Subject: [patch 6/6] Remove Dell Optiplex GX240 from the ACPI blacklist
To: lenb kernel org
Cc: linux-acpi vger kernel org, akpm linux-foundation org, tarrqt yahoo com
From: akpm linux-foundation org
Date: 	Wed, 23 May 2007 14:12:30 -0700
X-MIMEDefang-Filter: osdl$Revision: 1.179 $
X-Scanned-By: MIMEDefang 2.53 on 207.189.120.13
Sender: linux-acpi-owner vger kernel org
Precedence: bulk
X-Mailing-List: 	linux-acpi vger kernel org
X-RedHat-Spam-Score: 0.55 
Status: RO
Content-Length: 2331
Lines: 62

From: Tear <tarrqt 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 kernel org>
Signed-off-by: Andrew Morton <akpm 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 vger kernel org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


linux-2.6-add-mmf_dump_elf_headers.patch:

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


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

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

------------------------------------------------------
Subject: Add MMF_DUMP_ELF_HEADERS
From: Roland McGrath <roland 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 redhat com>
Cc: Hidehiro Kawai <hidehiro kawai ez hitachi com>
Signed-off-by: Andrew Morton <akpm linux-foundation org>
---

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

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

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

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


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

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

------------------------------------------------------
Subject: Add /sys/module/name/notes
From: Roland McGrath <roland 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 redhat com>
Signed-off-by: Andrew Morton <akpm linux-foundation org>
---

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

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

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

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

From: H.J. Lu

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

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

--- NEW FILE linux-2.6-amd-disabled-svm-detect.patch ---
commit cfc329b216bc3e54fe1107e8f714c7b3bc133224
Author: Joerg Roedel <joerg roedel 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 amd com>
    Signed-off-by: Avi Kivity <avi qumranet com>

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

linux-2.6-at76.patch:

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

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

--- NEW FILE linux-2.6-ata-call-check-dma-with-qc-prepared.patch ---
Gitweb:     http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=e00f1ff3c8977eff07d0214d2f3478ac947bda0f
Commit:     e00f1ff3c8977eff07d0214d2f3478ac947bda0f
Parent:     914616a3c2a54504f3b0eda0b67fcd32226b3e83
Author:     Tejun Heo <htejun gmail com>
AuthorDate: Wed Jun 27 02:47:35 2007 +0900
Committer:  Jeff Garzik <jeff 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 gmail com>
    Signed-off-by: Jeff Garzik <jeff garzik org>
---
 drivers/ata/libata-scsi.c |   20 ++++++++------------
 1 files changed, 8 insertions(+), 12 deletions(-)

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

linux-2.6-ata-quirk.patch:

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

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

--- NEW FILE linux-2.6-ata-use-pio-for-non-16-byte-xfers.patch ---
Gitweb:     http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=b9a4197e266a40d5d1d16c9fb2a852cf10743afe
Commit:     b9a4197e266a40d5d1d16c9fb2a852cf10743afe
Parent:     e00f1ff3c8977eff07d0214d2f3478ac947bda0f
Author:     Tejun Heo <htejun gmail com>
AuthorDate: Wed Jun 27 02:48:43 2007 +0900
Committer:  Jeff Garzik <jeff 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 gmail com>
    Cc: Albert Lee <albertcc tw ibm com>
    Signed-off-by: Jeff Garzik <jeff garzik org>
    [cebbert redhat com: removed extraneous whitespace change for -stable]
---
 drivers/ata/libata-core.c |   33 ++++++++++-----------------------
 1 files changed, 10 insertions(+), 23 deletions(-)

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

linux-2.6-ath5k.patch:

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

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

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

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

--- NEW FILE linux-2.6-cell-spu-device-tree.patch ---
Subject: [PATCH 01/10] cell: add cbe_node_to_cpu function
From: Christian Krafft <krafft 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 de ibm com>
Signed-off-by: Arnd Bergmann <arnd bergmann de ibm com>

----------

Subject: [PATCH 07/10] add of_iomap function
From: Christian Krafft <krafft 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 de ibm com>
Signed-off-by: Arnd Bergmann <arnd bergmann de ibm com>

----------

Subject: [PATCH 08/10] cell: add support for proper device-tree
From: Christian Krafft <krafft 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 de ibm com>
Signed-off-by: Arnd Bergmann <arnd bergmann 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 ozlabs org
https://ozlabs.org/mailman/listinfo/linuxppc-dev

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

--- NEW FILE linux-2.6-cell-spufs-fixes.patch ---
commit ccf17e9d008dfebbf90dfa4ee1a56e81c784c73e
Author: Jeremy Kerr <jk 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 ozlabs org>
    Signed-off-by: Arnd Bergmann <arnd bergmann 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 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 lst de>
    Signed-off-by: Arnd Bergmann <arnd bergmann de ibm com>

commit aa45e2569ffe963dfbbbfddfdccd12afe69b2d65
Author: Christoph Hellwig <hch 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 lst de>
    Signed-off-by: Arnd Bergmann <arnd bergmann de ibm com>

commit fe8a29db5bce1b5bd1ceb85fd153fac52cdab7b2
Author: Akinobu Mita <mita 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 de ibm com>

commit 6cf2179202cf706471777ad6ee5d0377d5990ab7
Author: Arnd Bergmann <arnd bergmann 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 fixstars com>
    Signed-off-by: Arnd Bergmann <arnd bergmann de ibm com>

commit d3764397d07b1e03943edfdcc3fb77af7bdac02b
Author: Jeremy Kerr <jk 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 ozlabs org>
    Signed-off-by: Arnd Bergmann <arnd bergmann de ibm com>

commit f11f5ee70f48899506514e5e0d10ee2c8ddd359a
Author: Jeremy Kerr <jk 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 ozlabs org>
    Signed-off-by: Arnd Bergmann <arnd bergmann de ibm com>

commit 9e2fe2ce4e957a79d3dc5d813e0cfb10d79b79b3
Author: Akinobu Mita <mita 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 fixstars com>
    Signed-off-by: Arnd Bergmann <arnd bergmann de ibm com>

commit 8a7d86bdb22678b17928eef0c8fa356d8b21cc76
Author: Christoph Hellwig <hch 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 lst de>
    Signed-off-by: Arnd Bergmann <arnd bergmann de ibm com>

commit db1384b40d12eda6910513ff429ad90453ca49e1
Author: Akinobu Mita <mita 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 arndb de>
    Signed-off-by: Akinobu Mita <mita fixstars com>
    Signed-off-by: Christoph Hellwig <hch lst de>
    Signed-off-by: Arnd Bergmann <arnd bergmann de ibm com>

commit c99c1994a2bb9493b4ac372b2b6ee2606d291171
Author: Akinobu Mita <mita 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 arndb de>
    Signed-off-by: Akinobu Mita <mita fixstars com>
    Signed-off-by: Christoph Hellwig <hch lst de>
    Signed-off-by: Arnd Bergmann <arnd bergmann de ibm com>

commit 577f8f1021f9ee6ef2a98a142652759ec122d27f
Author: Akinobu Mita <mita 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 fixstars com>
    Signed-off-by: Christoph Hellwig <hch lst de>
    Signed-off-by: Arnd Bergmann <arnd bergmann de ibm com>

commit e45d48a34d4d1862d28d22c2533b8c6bb83b8c1f
Author: Christoph Hellwig <hch 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 lst de>
    Signed-off-by: Arnd Bergmann <arnd bergmann de ibm com>

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

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

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

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

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

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

Fixup the existing users.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

linux-2.6-default-mmf_dump_elf_headers.patch:

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


linux-2.6-defaults-pci_no_msi_mmconf.patch:

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

Original mmconfig patch by Kyle McMartin <kyle ubuntu com>

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

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

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

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

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

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

linux-2.6-dvb-spinlock.patch:

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

# HG changeset patch
# User Mauro Carvalho Chehab <mchehab 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 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 linuxtv org>
Signed-off-by: Mauro Carvalho Chehab <mchehab infradead org>

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


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

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

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

linux-2.6-execshield-xen.patch:

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

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

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

linux-2.6-firewire-lockdep.patch:

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


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

--- NEW FILE linux-2.6-firewire-multi-lun.patch ---
From: Stefan Richter <stefanr s5r6 in-berlin de>
Subject: [PATCH update] firewire: fw-sbp2: add support for multiple logical
	units per target
To: linux1394-devel lists sourceforge net
cc: =?iso-8859-1?Q?Kristian_H=F8gsberg?= <krh redhat com>
Message-ID: <tkrat 1d824f10636d44c0 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 s5r6 in-berlin de>
---

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

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

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

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


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

--- NEW FILE linux-2.6-fix-pmops-1.patch ---
>From johannes sipsolutions net Wed Mar 21 15:56:28 2007
Date: Wed, 21 Mar 2007 15:56:28 +0100
From: Johannes Berg <johannes sipsolutions net>
To: Andrew Morton <akpm linux-foundation org>
Cc: linux-pm lists linux-foundation org, David Brownell <david-b pacbell net>, Pavel Machek <pavel 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 sipsolutions net>
Cc: David Brownell <david-b pacbell net>
Cc: Pavel Machek <pavel ucw cz>
Cc: linux-pm lists linux-foundation org

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

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

--

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

--- NEW FILE linux-2.6-fix-pmops-2.patch ---
>From johannes sipsolutions net Wed Mar 21 15:56:26 2007
Date: Wed, 21 Mar 2007 15:56:26 +0100
From: Johannes Berg <johannes sipsolutions net>
To: Andrew Morton <akpm linux-foundation org>
Cc: linux-pm lists linux-foundation org, Pavel Machek <pavel 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 sipsolutions net>
Cc: Pavel Machek <pavel ucw cz>
Cc: linux-pm lists linux-foundation org

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

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

--

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

--- NEW FILE linux-2.6-fix-pmops-3.patch ---
>From johannes sipsolutions net Wed Mar 21 15:56:31 2007
Date: Wed, 21 Mar 2007 15:56:31 +0100
From: Johannes Berg <johannes sipsolutions net>
To: Andrew Morton <akpm linux-foundation org>
Cc: linux-pm lists linux-foundation org, David Brownell <david-b pacbell net>, Pavel Machek <pavel 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 sipsolutions net>
Cc: David Brownell <david-b pacbell net>
Cc: Pavel Machek <pavel ucw cz>
Cc: linux-pm lists linux-foundation org

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

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

--

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

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

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

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

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

Steve.

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



linux-2.6-highres-timers.patch:

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

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

--- NEW FILE linux-2.6-i386-vdso-install-unstripped-copies-on-disk.patch ---
From: Roland McGrath <roland 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 redhat com>
Cc: Sam Ravnborg <sam ravnborg org>
Cc: Andi Kleen <ak suse de>
Signed-off-by: Andrew Morton <akpm linux-foundation org>
---

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

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

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

--- NEW FILE linux-2.6-i82875-edac-pci-setup.patch ---
From: John Feeney <jfeeney 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 redhat com>
Changelog: edac: fix /proc/bus/pci/devices to allow X to start


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

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

(EE) No devices detected.

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

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

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

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

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

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

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

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

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

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


linux-2.6-i965gm-support.patch:

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

linux-2.6-iwlwifi-fixes.patch:

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

linux-2.6-kvm-19.patch:

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

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

--- NEW FILE linux-2.6-kvm-reinit-real-mode-tss.patch ---
From: Avi Kivity <avi 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 qumranet com>
---

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

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

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

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

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

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


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

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

linux-2.6-libata-hpa.patch:

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

--- NEW FILE linux-2.6-libata-pata-hpt3x2n-correct-revision-boundary.patch ---
>From davej  Mon May 21 09:55:32 2007
Return-path: <linux-ide-owner 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 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 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 vger kernel org>)
	id 1Hq8K4-0003Ov-L0
	for davej codemonkey org uk; Mon, 21 May 2007 14:53:17 +0100
Received: (majordomo vger kernel org) by vger.kernel.org via listexpand
	id S1756248AbXEUNwz (ORCPT <rfc822;davej codemonkey org uk>);
	Mon, 21 May 2007 09:52:55 -0400
Received: (majordomo 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 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 lxorguk ukuu org uk>
To:	akpm osdl org, linux-ide vger kernel org, jeff garzik org
Subject: [PATCH] hpt3x2n: Correct revision boundary
Message-ID: <20070521145701 7283c30a 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 vger kernel org
Precedence: bulk
X-Mailing-List:	linux-ide 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 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 vger kernel org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


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

--- NEW FILE linux-2.6-libata-pata-pcmcia-new-ident.patch ---
>From davej  Tue May  8 10:22:45 2007
Return-path: <linux-ide-owner 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 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 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 vger kernel org>)
	id 1HlQYz-0002lV-Qb
	for davej codemonkey org uk; Tue, 08 May 2007 15:21:14 +0100
Received: (majordomo vger kernel org) by vger.kernel.org via listexpand
	id S968076AbXEHOVB (ORCPT <rfc822;davej codemonkey org uk>);
	Tue, 8 May 2007 10:21:01 -0400
Received: (majordomo 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 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 rsk demon co uk>
To:	jgarzik pobox com
Cc:	linux-ide vger kernel org
Content-Type: text/plain
Date:	Tue, 08 May 2007 15:20:56 +0100
Message-Id: <1178634056 3835 12 camel 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 vger kernel org
Precedence: bulk
X-Mailing-List:	linux-ide 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 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 vger kernel org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


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

--- NEW FILE linux-2.6-libata-pata-sis-fix-timing.patch ---
Date:	Mon, 21 May 2007 15:00:53 +0100
From:	Alan Cox <alan lxorguk ukuu org uk>
To:	akpm osdl org, jeff garzik org, linux-ide vger kernel org
Subject: [PATCH] pata_sis: Fix and clean up some timing setups
Message-ID: <20070521150053 3b6f91a2 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 redhat com>

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

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

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

	libata.pata_dma=0

to disable DMA (default is 1)

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

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

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

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

--- NEW FILE linux-2.6-libata-pata_it821x-partly-fix-dma.patch ---
Gitweb:     http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=374abf2cb16a9df8be96675c606996458872e8b3
Commit:     374abf2cb16a9df8be96675c606996458872e8b3
Parent:     9f7897554eeca34ec23dd877cc27402bd327a1ce
Author:     Bartlomiej Zolnierkiewicz <bzolnier gmail com>
AuthorDate: Mon Jun 11 11:40:07 2007 +0200
Committer:  Jeff Garzik <jeff 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 gmail com>
    Acked-by: Alan Cox <alan redhat com>
    Cc: Tejun Heo <htejun gmail com>
    Signed-off-by: Jeff Garzik <jeff garzik org>
    [remove copyright and version changes: <cebbert redhat com>]
---
 drivers/ata/pata_it821x.c |   11 +++--------
 1 files changed, 3 insertions(+), 8 deletions(-)

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

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

--- NEW FILE linux-2.6-libata-sata_nv-adma.patch ---
commit eb20a5742d230c67b9af4efd71b8b6b680ca3a09
Author: Robert Hancock <hancockr 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 shaw ca>
    Signed-off-by: Andrew Morton <akpm linux-foundation org>
    Signed-off-by: Jeff Garzik <jeff garzik org>

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

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

--- NEW FILE linux-2.6-libata-sata_nv-wildcard-removal.patch ---
Date:   Wed, 25 Apr 2007 11:17:21 +0800
To:     <linux-kernel vger kernel org>
From:   "Peer Chen" <pchen nvidia com>
Cc:     <akpm osdl org>, <jgarzik pobox com>, <torvalds 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 nvidia com>

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

linux-2.6-libata-setxfer.patch:

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

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



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

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

This patch fixes detection failure introduced by polling SETXFERMODE.

Signed-off-by: Tejun Heo <htejun 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 vger kernel org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


linux-2.6-libata_ali_max_dma_speed.patch:

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

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

linux-2.6-lirc.patch:

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

linux-2.6-mac80211-extras.patch:

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

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

--- NEW FILE linux-2.6-mac80211-nm-hidden-ssid.patch ---
diff -up linux-2.6.23.noarch/net/mac80211/ieee80211_ioctl.c.orig linux-2.6.23.noarch/net/mac80211/ieee80211_ioctl.c
--- linux-2.6.23.noarch/net/mac80211/ieee80211_ioctl.c.orig	2007-10-10 17:43:20.000000000 -0400
+++ linux-2.6.23.noarch/net/mac80211/ieee80211_ioctl.c	2007-10-10 17:49:04.000000000 -0400
@@ -1320,10 +1320,11 @@ static int ieee80211_ioctl_giwap(struct 
 
 static int ieee80211_ioctl_siwscan(struct net_device *dev,
 				   struct iw_request_info *info,
-				   struct iw_point *data, char *extra)
+				   union iwreq_data *wrqu, char *extra)
 {
 	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+	struct iw_scan_req *req = NULL;
 	u8 *ssid = NULL;
 	size_t ssid_len = 0;
 
@@ -1332,6 +1333,14 @@ static int ieee80211_ioctl_siwscan(struc
 
 	switch (sdata->type) {
 	case IEEE80211_IF_TYPE_STA:
+		if (wrqu->data.length == sizeof(struct iw_scan_req) &&
+		    wrqu->data.flags & IW_SCAN_THIS_ESSID) {
+			req = (struct iw_scan_req *)extra;
+			ssid = req->essid;
+			ssid_len = req->essid_len;
+			break;
+		}
+		/* else fall-through */
 	case IEEE80211_IF_TYPE_IBSS:
 		if (local->scan_flags & IEEE80211_SCAN_MATCH_SSID) {
 			ssid = sdata->u.sta.ssid;

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

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

linux-2.6-mpc52xx-fec.patch:

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

linux-2.6-mpc52xx-sdma.patch:

--- NEW FILE linux-2.6-mpc52xx-sdma.patch ---
--- linux-2.6.20.ppc64/arch/powerpc/Kconfig	2007-03-22 11:17:52.000000000 +0000
+++ linux-2.6.20.fec/arch/powerpc/Kconfig	2007-03-27 19:09:27.000000000 +0100
@@ -451,6 +456,11 @@
 
 	  It is safe to say 'Y' here
 
+config PPC_BESTCOMM
+	bool
+	depends on PPC_MPC52xx
+	default y
+
 config PPC_EFIKA
 	bool "bPlan Efika 5k2. MPC5200B based computer"
 	depends on PPC_MULTIPLATFORM && PPC32
diff -uNr linux-2.6.20.ppc64/arch/powerpc/platforms/52xx/bestcomm.c linux-2.6.20.fec/arch/powerpc/platforms/52xx/bestcomm.c
--- linux-2.6.20.ppc64/arch/powerpc/platforms/52xx/bestcomm.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.20.fec/arch/powerpc/platforms/52xx/bestcomm.c	2007-03-27 23:40:42.000000000 +0100
@@ -0,0 +1,399 @@
+/*
+ * arch/ppc/syslib/bestcomm/bestcomm.c
+ *
+ * Driver for MPC52xx processor BestComm peripheral controller
+ *
+ * Author: Dale Farnsworth <dfarnsworth 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 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 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 varma-el com>, Varma Electronics Oy
+ */
+
+#ifndef __BESTCOMM_BESTCOMM_H__
+#define __BESTCOMM_BESTCOMM_H__
+
+#include "mpc52xx_pic.h"
+
+/* Buffer Descriptor definitions */
+struct sdma_bd {
+	u32 status;
+	void *data;
+};
+
+struct sdma_bd2 {
+	u32 status;
+	void *data1;
+	void *data2;
+};
+
+struct sdma_io {
+	unsigned long			base_reg_addr;
+	struct mpc52xx_sdma __iomem	*io;
+	unsigned long			base_sram_addr;
+	void __iomem			*sram;
+	size_t				sram_size;
+
+	struct sdma_tdt __iomem  	*tdt;
+	u32 __iomem			*var;
+};
+extern struct sdma_io sdma;
+
+#define	sdma_sram_pa(virt)	(((unsigned long)(((void __iomem *)(virt))-sdma.sram))+sdma.base_sram_addr)
+#define	sdma_sram_va(pa)	((void __iomem *)((((unsigned long)(pa))-sdma.base_sram_addr)+((unsigned long)sdma.sram)))
+
+#define	sdma_io_pa(virt)	(((unsigned long)(((void __iomem *)(virt))-((void __iomem *)sdma.io)))+sdma.base_reg_addr)
+#define	sdma_io_va(pa)	((void __iomem *)((((unsigned long)(pa))-sdma.base_reg_addr)+((unsigned long)sdma.io)))
+
+#define SDMA_LEN_BITS		26
+#define SDMA_LEN_MASK		((1 << SDMA_LEN_BITS) - 1)
+
+#define SDMA_BD_READY		0x40000000UL
+
+#define SDMA_FEC_TX_BD_TFD	0x08000000UL	/* transmit frame done */
+#define SDMA_FEC_TX_BD_INT	0x04000000UL	/* Interrupt */
+#define SDMA_FEC_TX_BD_TFD_INIT	(SDMA_BD_READY | SDMA_FEC_TX_BD_TFD | \
+							SDMA_FEC_TX_BD_INT)
+
+struct sdma {
+	union {
+		struct sdma_bd *bd;
+		struct sdma_bd2 *bd2;
+	};
+	void **cookie;
+	u16 index;
+	u16 outdex;
+	u16 num_bd;
+	s16 tasknum;
+	u32 flags;
+	struct device_node *node;
+};
+
+#define SDMA_FLAGS_NONE		0x0000
+#define SDMA_FLAGS_ENABLE_TASK	0x0001
+#define SDMA_FLAGS_BD2		0x0002
+
+/* Task Descriptor Table Entry */
+struct sdma_tdt {
+	u32 start;
+	u32 stop;
+	u32 var;
+	u32 fdt;
+	u32 exec_status; /* used internally by SmartComm engine */
+	u32 mvtp;		 /* used internally by SmartComm engine */
+	u32 context;
+	u32 litbase;
+};
+
+//extern struct sdma_tdt *sdma_tdt;
+
+#define SDMA_MAX_TASKS		16
+#define SDMA_MAX_VAR		24
+#define SDMA_MAX_INC		8
+#define SDMA_MAX_FDT		64
+#define SDMA_MAX_CONTEXT	20
+#define SDMA_CONTEXT_SIZE	SDMA_MAX_CONTEXT * sizeof(u32)
+#define SDMA_CONTEXT_ALIGN	0x100
+#define SDMA_VAR_SIZE		SDMA_MAX_VAR * sizeof(u32)
+#define SDMA_VAR_ALIGN		0x80
+#define SDMA_INC_SIZE		SDMA_MAX_INC * sizeof(u32)
+#define SDMA_FDT_SIZE		SDMA_MAX_FDT * sizeof(u32)
+#define SDMA_FDT_ALIGN		0x100
+#define SDMA_BD_ALIGN		0x10
+
+#define TASK_ENABLE		0x8000
+
+#ifndef DPRINK
+	#ifdef CONFIG_BESTCOMM_DEBUG
+	#define DPRINTK(a,b...)	printk(KERN_DEBUG "sdma: %s: " a, __FUNCTION__ , ## b)
+	#else
+	#define DPRINTK(a,b...)
+	#endif
+#endif
+
+static inline void sdma_enable_task(int task)
+{
+	u16 reg;
+
+	DPRINTK("***DMA enable task (%d): tdt = %p\n",task, sdma.tdt);
+	DPRINTK("***tdt->start   = %08x\n",sdma.tdt[task].start);
+	DPRINTK("***tdt->stop    = %08x\n",sdma.tdt[task].stop);
+	DPRINTK("***tdt->var     = %08x\n",sdma.tdt[task].var);
+	DPRINTK("***tdt->fdt     = %08x\n",sdma.tdt[task].fdt);
+	DPRINTK("***tdt->status  = %08x\n",sdma.tdt[task].exec_status);
+	DPRINTK("***tdt->mvtp    = %08x\n",sdma.tdt[task].mvtp);
+	DPRINTK("***tdt->context = %08x\n",sdma.tdt[task].context);
+	DPRINTK("***tdt->litbase = %08x\n",sdma.tdt[task].litbase);
+	DPRINTK("***--------------\n");
+
+	reg = in_be16(&sdma.io->tcr[task]);
+	DPRINTK("***enable task: &sdma.io->tcr=%p, reg = %04x\n", &sdma.io->tcr, reg);
+	out_be16(&sdma.io->tcr[task],  reg | TASK_ENABLE);
+}
+
+static inline void sdma_disable_task(int task)
+{
+	u16 reg = in_be16(&sdma.io->tcr[task]);
+	DPRINTK("***disable task(%d): reg = %04x\n", task, reg);
+	out_be16(&sdma.io->tcr[task], reg & ~TASK_ENABLE);
+}
+
+static inline int sdma_irq(struct sdma *s)
+{
+	return irq_of_parse_and_map(s->node, s->tasknum);
+}
+
+static inline void sdma_enable(struct sdma *s)
+{
+	sdma_enable_task(s->tasknum);
+}
+
+static inline void sdma_disable(struct sdma *s)
+{
+	sdma_disable_task(s->tasknum);
+}
+
+static inline int sdma_queue_empty(struct sdma *s)
+{
+	return s->index == s->outdex;
+}
+
+static inline void sdma_clear_irq(struct sdma *s)
+{
+	out_be32(&sdma.io->IntPend, 1 << s->tasknum);
+}
+
+static inline int sdma_next_index(struct sdma *s)
+{
+	return ((s->index + 1) == s->num_bd) ? 0 : s->index + 1;
+}
+
+static inline int sdma_next_outdex(struct sdma *s)
+{
+	return ((s->outdex + 1) == s->num_bd) ? 0 : s->outdex + 1;
+}
+
+static inline int sdma_queue_full(struct sdma *s)
+{
+	return s->outdex == sdma_next_index(s);
+}
+
+static inline int sdma_buffer_done(struct sdma *s)
+{
+#ifdef CONFIG_BESTCOMM_DEBUG
+	BUG_ON(s->flags & SDMA_FLAGS_BD2);
+#endif
+	if (sdma_queue_empty(s))
+		return 0;
+	return (s->bd[s->outdex].status & SDMA_BD_READY) == 0;
+}
+
+static inline int sdma_buffer2_done(struct sdma *s)
+{
+#ifdef CONFIG_BESTCOMM_DEBUG
+	BUG_ON(!(s->flags & SDMA_FLAGS_BD2));
+#endif
+	if (sdma_queue_empty(s))
+		return 0;
+
+	return (s->bd2[s->outdex].status & SDMA_BD_READY) == 0;
+}
+
+static inline u32 *sdma_task_desc(int task)
+{
+	return sdma_sram_va(sdma.tdt[task].start);
+}
+
+static inline u32 sdma_task_num_descs(int task)
+{
+	return (sdma.tdt[task].stop - sdma.tdt[task].start)/sizeof(u32) + 1;
+}
+
+static inline u32 *sdma_task_var(int task)
+{
+	return sdma_sram_va(sdma.tdt[task].var);
+}
+
+static inline u32 *sdma_task_inc(int task)
+{
+	return &sdma_task_var(task)[SDMA_MAX_VAR];
+}
+
+static inline void sdma_set_tcr_initiator(int task, int initiator) {
+	u16 *tcr = &sdma.io->tcr[task];
+	out_be16(tcr, (in_be16(tcr) & ~0x1f00) | (initiator << 8));
+}
+
+#define SDMA_DRD_INITIATOR_SHIFT	21
+
+static inline int sdma_desc_initiator(u32 desc)
+{
+	return (desc >> SDMA_DRD_INITIATOR_SHIFT) & 0x1f;
+}
+
+static inline void sdma_set_desc_initiator(u32 *desc, int initiator)
+{
+	*desc = (*desc & ~(0x1f << SDMA_DRD_INITIATOR_SHIFT)) |
+			((initiator << SDMA_DRD_INITIATOR_SHIFT) & 0x1f);
+}
+
+static inline void sdma_submit_buffer(struct sdma *s, void *cookie, void *data,
+								int length)
+{
+#ifdef CONFIG_BESTCOMM_DEBUG
+	BUG_ON(s->flags & SDMA_FLAGS_BD2);
+#endif
+	s->cookie[s->index] = cookie;
+	s->bd[s->index].data = data;
+	s->bd[s->index].status = SDMA_BD_READY | length;
+	s->index = sdma_next_index(s);
+	if (s->flags & SDMA_FLAGS_ENABLE_TASK)
+		sdma_enable_task(s->tasknum);
+}
+
+/*
+ * Special submit_buffer function to submit last buffer of a frame to
+ * the FEC tx task.  tfd means "transmit frame done".
+ */
+static inline void sdma_fec_tfd_submit_buffer(struct sdma *s, void *cookie,
+							void *data, int length)
+{
+#ifdef CONFIG_BESTCOMM_DEBUG
+	BUG_ON(s->flags & SDMA_FLAGS_BD2);
+#endif
+	s->cookie[s->index] = cookie;
+	s->bd[s->index].data = data;
+	s->bd[s->index].status = SDMA_FEC_TX_BD_TFD_INIT | length;
+	s->index = sdma_next_index(s);
+	sdma_enable_task(s->tasknum);
+}
+
+static inline void *sdma_retrieve_buffer(struct sdma *s, int *length)
+{
+	void *cookie = s->cookie[s->outdex];
+
+#ifdef CONFIG_BESTCOMM_DEBUG
+	BUG_ON(s->flags & SDMA_FLAGS_BD2);
+#endif
+	if (length)
+		*length = s->bd[s->outdex].status & SDMA_LEN_MASK;
+	s->outdex = sdma_next_outdex(s);
+	return cookie;
+}
+
+static inline void sdma_submit_buffer2(struct sdma *s, void *cookie,
+					void *data1, void *data2, int length)
+{
+#ifdef CONFIG_BESTCOMM_DEBUG
+	BUG_ON(!(s->flags & SDMA_FLAGS_BD2));
+#endif
+	s->cookie[s->index] = cookie;
+	s->bd2[s->index].data1 = data1;
+	s->bd2[s->index].data2 = data2;
+	s->bd2[s->index].status = SDMA_BD_READY | length;
+	s->index = sdma_next_index(s);
+	if (s->flags & SDMA_FLAGS_ENABLE_TASK)
+		sdma_enable_task(s->tasknum);
+}
+
+static inline void *sdma_retrieve_buffer2(struct sdma *s, int *length)
+{
+	void *cookie = s->cookie[s->outdex];
+
+#ifdef CONFIG_BESTCOMM_DEBUG
+	BUG_ON(!(s->flags & SDMA_FLAGS_BD2));
+#endif
+	if (length)
+		*length = s->bd2[s->outdex].status & SDMA_LEN_MASK;
+	s->outdex = sdma_next_outdex(s);
+	return cookie;
+}
+
+#define SDMA_TASK_MAGIC		0x4243544B	/* 'BCTK' */
+
+/* the size fields are given in number of 32-bit words */
+struct sdma_task_header {
+	u32	magic;
+	u8	desc_size;
+	u8	var_size;
+	u8	inc_size;
+	u8	first_var;
+	u8	reserved[8];
+};
+
+#define SDMA_DESC_NOP		0x000001f8
+#define SDMA_LCD_MASK		0x80000000
+#define SDMA_DRD_EXTENDED	0x40000000
+
+#define sdma_drd_is_extended(desc) ((desc) & SDMA_DRD_EXTENDED)
+
+static inline int sdma_desc_is_drd(u32 desc) {
+	return !(desc & SDMA_LCD_MASK) && desc != SDMA_DESC_NOP;
+};
+
+#define SDMA_PRAGMA_BIT_RSV		7	/* reserved pragma bit */
+#define SDMA_PRAGMA_BIT_PRECISE_INC	6	/* increment 0=when possible, */
+						/*	1=iter end */
+#define SDMA_PRAGMA_BIT_RST_ERROR_NO	5	/* don't reset errors on */
+						/* task enable */
+#define SDMA_PRAGMA_BIT_PACK		4	/* pack data enable */
+#define SDMA_PRAGMA_BIT_INTEGER		3	/* data alignment */
+						/* 0=frac(msb), 1=int(lsb) */
+#define SDMA_PRAGMA_BIT_SPECREAD	2	/* XLB speculative read */
+#define SDMA_PRAGMA_BIT_CW		1	/* write line buffer enable */
+#define SDMA_PRAGMA_BIT_RL		0	/* read line buffer enable */
+
+#define SDMA_STD_PRAGMA		((0 << SDMA_PRAGMA_BIT_RSV)		| \
+				 (0 << SDMA_PRAGMA_BIT_PRECISE_INC)	| \
+				 (0 << SDMA_PRAGMA_BIT_RST_ERROR_NO)	| \
+				 (0 << SDMA_PRAGMA_BIT_PACK)		| \
+				 (0 << SDMA_PRAGMA_BIT_INTEGER)		| \
+				 (1 << SDMA_PRAGMA_BIT_SPECREAD)	| \
+				 (1 << SDMA_PRAGMA_BIT_CW)		| \
+				 (1 << SDMA_PRAGMA_BIT_RL))
+
+#define SDMA_PCI_PRAGMA		((0 << SDMA_PRAGMA_BIT_RSV)		| \
+				 (0 << SDMA_PRAGMA_BIT_PRECISE_INC)	| \
+				 (0 << SDMA_PRAGMA_BIT_RST_ERROR_NO)	| \
+				 (0 << SDMA_PRAGMA_BIT_PACK)		| \
+				 (1 << SDMA_PRAGMA_BIT_INTEGER)		| \
+				 (1 << SDMA_PRAGMA_BIT_SPECREAD)	| \
+				 (1 << SDMA_PRAGMA_BIT_CW)		| \
+				 (1 << SDMA_PRAGMA_BIT_RL))
+
+#define SDMA_ATA_PRAGMA		SDMA_STD_PRAGMA
+#define SDMA_CRC16_DP_0_PRAGMA	SDMA_STD_PRAGMA
+#define SDMA_CRC16_DP_1_PRAGMA	SDMA_STD_PRAGMA
+#define SDMA_FEC_RX_BD_PRAGMA	SDMA_STD_PRAGMA
+#define SDMA_FEC_TX_BD_PRAGMA	SDMA_STD_PRAGMA
+#define SDMA_GEN_DP_0_PRAGMA	SDMA_STD_PRAGMA
+#define SDMA_GEN_DP_1_PRAGMA	SDMA_STD_PRAGMA
+#define SDMA_GEN_DP_2_PRAGMA	SDMA_STD_PRAGMA
+#define SDMA_GEN_DP_3_PRAGMA	SDMA_STD_PRAGMA
+#define SDMA_GEN_DP_BD_0_PRAGMA	SDMA_STD_PRAGMA
+#define SDMA_GEN_DP_BD_1_PRAGMA	SDMA_STD_PRAGMA
+#define SDMA_GEN_RX_BD_PRAGMA	SDMA_STD_PRAGMA
+#define SDMA_GEN_TX_BD_PRAGMA	SDMA_STD_PRAGMA
+#define SDMA_GEN_LPC_PRAGMA	SDMA_STD_PRAGMA
+#define SDMA_PCI_RX_PRAGMA	SDMA_PCI_PRAGMA
+#define SDMA_PCI_TX_PRAGMA	SDMA_PCI_PRAGMA
+
+static inline void sdma_set_task_pragma(int task, int pragma)
+{
+	u32 *fdt = &sdma.tdt[task].fdt;
+	*fdt = (*fdt & ~0xff) | pragma;
+}
+
+static inline void sdma_set_task_auto_start(int task, int next_task)
+{
+	u16 *tcr = &sdma.io->tcr[task];
+	out_be16(tcr, (in_be16(tcr) & ~0xff) | 0x00c0 | next_task);
+}
+
+#define SDMA_INITIATOR_ALWAYS	 0
+#define SDMA_INITIATOR_SCTMR_0	 1
+#define SDMA_INITIATOR_SCTMR_1	 2
+#define SDMA_INITIATOR_FEC_RX	 3
+#define SDMA_INITIATOR_FEC_TX	 4
+#define SDMA_INITIATOR_ATA_RX	 5
+#define SDMA_INITIATOR_ATA_TX	 6
+#define SDMA_INITIATOR_SCPCI_RX	 7
+#define SDMA_INITIATOR_SCPCI_TX	 8
+#define SDMA_INITIATOR_PSC3_RX	 9
+#define SDMA_INITIATOR_PSC3_TX	10
+#define SDMA_INITIATOR_PSC2_RX	11
+#define SDMA_INITIATOR_PSC2_TX	12
+#define SDMA_INITIATOR_PSC1_RX	13
+#define SDMA_INITIATOR_PSC1_TX	14
+#define SDMA_INITIATOR_SCTMR_2	15
+#define SDMA_INITIATOR_SCLPC	16
+#define SDMA_INITIATOR_PSC5_RX	17
+#define SDMA_INITIATOR_PSC5_TX	18
+#define SDMA_INITIATOR_PSC4_RX	19
+#define SDMA_INITIATOR_PSC4_TX	20
+#define SDMA_INITIATOR_I2C2_RX	21
+#define SDMA_INITIATOR_I2C2_TX	22
+#define SDMA_INITIATOR_I2C1_RX	23
+#define SDMA_INITIATOR_I2C1_TX	24
+#define SDMA_INITIATOR_PSC6_RX	25
+#define SDMA_INITIATOR_PSC6_TX	26
+#define SDMA_INITIATOR_IRDA_RX	25
+#define SDMA_INITIATOR_IRDA_TX	26
+#define SDMA_INITIATOR_SCTMR_3	27
+#define SDMA_INITIATOR_SCTMR_4	28
+#define SDMA_INITIATOR_SCTMR_5	29
+#define SDMA_INITIATOR_SCTMR_6	30
+#define SDMA_INITIATOR_SCTMR_7	31
+
+#define SDMA_IPR_ALWAYS	7
+#define SDMA_IPR_SCTMR_0 	2
+#define SDMA_IPR_SCTMR_1 	2
+#define SDMA_IPR_FEC_RX 	6
+#define SDMA_IPR_FEC_TX 	5
+#define SDMA_IPR_ATA_RX 	4
+#define SDMA_IPR_ATA_TX 	3
+#define SDMA_IPR_SCPCI_RX	2
+#define SDMA_IPR_SCPCI_TX	2
+#define SDMA_IPR_PSC3_RX	2
+#define SDMA_IPR_PSC3_TX	2
+#define SDMA_IPR_PSC2_RX	2
+#define SDMA_IPR_PSC2_TX	2
+#define SDMA_IPR_PSC1_RX	2
+#define SDMA_IPR_PSC1_TX	2
+#define SDMA_IPR_SCTMR_2	2
+#define SDMA_IPR_SCLPC		2
+#define SDMA_IPR_PSC5_RX	2
+#define SDMA_IPR_PSC5_TX	2
+#define SDMA_IPR_PSC4_RX	2
+#define SDMA_IPR_PSC4_TX	2
+#define SDMA_IPR_I2C2_RX	2
+#define SDMA_IPR_I2C2_TX	2
+#define SDMA_IPR_I2C1_RX	2
+#define SDMA_IPR_I2C1_TX	2
+#define SDMA_IPR_PSC6_RX	2
+#define SDMA_IPR_PSC6_TX	2
+#define SDMA_IPR_IRDA_RX	2
+#define SDMA_IPR_IRDA_TX	2
+#define SDMA_IPR_SCTMR_3	2
+#define SDMA_IPR_SCTMR_4	2
+#define SDMA_IPR_SCTMR_5	2
+#define SDMA_IPR_SCTMR_6	2
+#define SDMA_IPR_SCTMR_7	2
+
+extern struct sdma *sdma_alloc(int request_queue_size);
+extern void sdma_free(struct sdma *sdma_struct);
+extern int sdma_load_task(u32 *task_image);
+extern void *sdma_sram_alloc(int size, int alignment, u32 *dma_handle);
+extern void sdma_init_bd(struct sdma *s);
+extern void sdma_init_bd2(struct sdma *s);
+
+#define FIELD_OFFSET(s,f) ((unsigned long)(&(((struct s*)0)->f)))
+
+#endif  /* __BESTCOMM_BESTCOMM_H__ */
diff -uNr linux-2.6.20.ppc64/arch/powerpc/platforms/52xx/Makefile linux-2.6.20.fec/arch/powerpc/platforms/52xx/Makefile
--- linux-2.6.20.ppc64/arch/powerpc/platforms/52xx/Makefile	2007-03-22 11:17:52.000000000 +0000
+++ linux-2.6.20.fec/arch/powerpc/platforms/52xx/Makefile	2007-03-27 23:23:04.000000000 +0100
@@ -4,6 +4,7 @@
 ifeq ($(CONFIG_PPC_MERGE),y)
 obj-y				+= mpc52xx_pic.o mpc52xx_common.o
 obj-$(CONFIG_PCI)		+= mpc52xx_pci.o
+obj-$(CONFIG_PPC_BESTCOMM) 	+= bestcomm.o
 endif
 
 obj-$(CONFIG_PPC_EFIKA)		+= efika.o

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

--- NEW FILE linux-2.6-net-e1000-no-msi-warning.patch ---
commit e94bd23f67c87011f012f26ca0af3fcf6878eeac
Author: Auke Kok <auke-jan h kok 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 intel com>
    Cc: H. Peter Anvin <hpa zytor com>
    Signed-off-by: Jeff Garzik <jeff garzik org>

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

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

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

Signed-off-by: Dave Jones <davej 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 redhat com>

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

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

--- NEW FILE linux-2.6-netdev-e1000e-01.patch ---
From: Auke Kok <auke-jan h kok 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 intel com>
Signed-off-by: Jeff Garzik <jeff 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 intel com>
+  e1000-devel Mailing List <e1000-devel lists sourceforge net>
+  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+/*
+ * 82571EB Gigabit Ethernet Controller
+ * 82571EB Gigabit Ethernet Controller (Fiber)
+ * 82572EI Gigabit Ethernet Controller (Copper)
+ * 82572EI Gigabit Ethernet Controller (Fiber)
+ * 82572EI Gigabit Ethernet Controller
+ * 82573V Gigabit Ethernet Controller (Copper)
+ * 82573E Gigabit Ethernet Controller (Copper)
+ * 82573L Gigabit Ethernet Controller
+ */
+
+#include "e1000.h"
+
+#define ID_LED_RESERVED_F746 0xF746
+#define ID_LED_DEFAULT_82573 ((ID_LED_DEF1_DEF2 << 12) | \
+			      (ID_LED_OFF1_ON2  <<  8) | \
+			      (ID_LED_DEF1_DEF2 <<  4) | \
+			      (ID_LED_DEF1_DEF2))
+
+#define E1000_GCR_L1_ACT_WITHOUT_L0S_RX 0x08000000
+
+static s32 e1000_get_phy_id_82571(struct e1000_hw *hw);
+static s32 e1000_setup_copper_link_82571(struct e1000_hw *hw);
+static s32 e1000_setup_fiber_serdes_link_82571(struct e1000_hw *hw);
+static s32 e1000_get_phy_id_82571(struct e1000_hw *hw);
+static s32 e1000_write_nvm_eewr_82571(struct e1000_hw *hw, u16 offset,
+				      u16 words, u16 *data);
+static s32 e1000_fix_nvm_checksum_82571(struct e1000_hw *hw);
+static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw);
+static s32 e1000_setup_link_82571(struct e1000_hw *hw);
+static void e1000_clear_hw_cntrs_82571(struct e1000_hw *hw);
+
+/**
+ *  e1000_init_phy_params_82571 - Init PHY func ptrs.
+ *  @hw: pointer to the HW structure
+ *
+ *  This is a function pointer entry point called by the api module.
+ **/
+static s32 e1000_init_phy_params_82571(struct e1000_hw *hw)
+{
+	struct e1000_phy_info *phy = &hw->phy;
+	s32 ret_val = E1000_SUCCESS;
+
+	if (hw->media_type != e1000_media_type_copper) {
+		phy->type = e1000_phy_none;
+		goto out;
+	}
+
+	phy->addr			 = 1;
+	phy->autoneg_mask		 = AUTONEG_ADVERTISE_SPEED_DEFAULT;
+	phy->reset_delay_us		 = 100;
+
+	switch (hw->mac.type) {
+	case e1000_82571:
+	case e1000_82572:
+		phy->type		 = e1000_phy_igp_2;
+		break;
+	case e1000_82573:
+		phy->type		 = e1000_phy_m88;
+		break;
+	default:
+		ret_val = -E1000_ERR_PHY;
+		goto out;
+		break;
+	}
+
+	/* This can only be done after all function pointers are setup. */
+	ret_val = e1000_get_phy_id_82571(hw);
+
+	/* Verify phy id */
+	switch (hw->mac.type) {
+	case e1000_82571:
+	case e1000_82572:
+		if (phy->id != IGP01E1000_I_PHY_ID) {
+			ret_val = -E1000_ERR_PHY;
+			goto out;
+		}
+		break;
+	case e1000_82573:
+		if (phy->id != M88E1111_I_PHY_ID) {
+			ret_val = -E1000_ERR_PHY;
+			goto out;
+		}
+		break;
+	default:
+		ret_val = -E1000_ERR_PHY;
+		goto out;
+		break;
+	}
+
+out:
+	return ret_val;
+}
+
+/**
+ *  e1000_init_nvm_params_82571 - Init NVM func ptrs.
[...17738 lines suppressed...]
+		phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED;
+		phy->local_rx = e1000_1000t_rx_status_undefined;
+		phy->remote_rx = e1000_1000t_rx_status_undefined;
+	}
+
+out:
+	return ret_val;
+}
+
+/**
+ *  e1000_phy_sw_reset - PHY software reset
+ *  @hw: pointer to the HW structure
+ *
+ *  Does a software reset of the PHY by reading the PHY control register and
+ *  setting/write the control register reset bit to the PHY.
+ **/
+s32 e1000_phy_sw_reset(struct e1000_hw *hw)
+{
+	s32 ret_val;
+	u16 phy_ctrl;
+
+	ret_val = e1e_rphy(hw, PHY_CONTROL, &phy_ctrl);
+	if (ret_val)
+		goto out;
+
+	phy_ctrl |= MII_CR_RESET;
+	ret_val = e1e_wphy(hw, PHY_CONTROL, phy_ctrl);
+	if (ret_val)
+		goto out;
+
+	udelay(1);
+
+out:
+	return ret_val;
+}
+
+/**
+ *  e1000_phy_hw_reset_generic - PHY hardware reset
+ *  @hw: pointer to the HW structure
+ *
+ *  Verify the reset block is not blocking us from resetting.  Acquire
+ *  semaphore (if necessary) and read/set/write the device control reset
+ *  bit in the PHY.  Wait the appropriate delay time for the device to
+ *  reset and relase the semaphore (if necessary).
+ **/
+s32 e1000_phy_hw_reset_generic(struct e1000_hw *hw)
+{
+	struct e1000_phy_info *phy = &hw->phy;
+	s32  ret_val;
+	u32 ctrl;
+
+	ret_val = e1000_check_reset_block(hw);
+	if (ret_val) {
+		ret_val = E1000_SUCCESS;
+		goto out;
+	}
+
+	ret_val = phy->ops.acquire_phy(hw);
+	if (ret_val)
+		goto out;
+
+	ctrl = er32(CTRL);
+	ew32(CTRL, ctrl | E1000_CTRL_PHY_RST);
+	e1e_flush();
+
+	udelay(phy->reset_delay_us);
+
+	ew32(CTRL, ctrl);
+	e1e_flush();
+
+	udelay(150);
+
+	phy->ops.release_phy(hw);
+
+	ret_val = e1000_get_phy_cfg_done(hw);
+
+out:
+	return ret_val;
+}
+
+/**
+ *  e1000_get_cfg_done - Generic configuration done
+ *  @hw: pointer to the HW structure
+ *
+ *  Generic function to wait 10 milli-seconds for configuration to complete
+ *  and return success.
+ **/
+s32 e1000_get_cfg_done(struct e1000_hw *hw)
+{
+	mdelay(10);
+
+	return E1000_SUCCESS;
+}
+
+/* Internal function pointers */
+
+/**
+ *  e1000_get_phy_cfg_done - Generic PHY configuration done
+ *  @hw: pointer to the HW structure
+ *
+ *  Return success if silicon family did not implement a family specific
+ *  get_cfg_done function.
+ **/
+static s32 e1000_get_phy_cfg_done(struct e1000_hw *hw)
+{
+	if (hw->phy.ops.get_cfg_done)
+		return hw->phy.ops.get_cfg_done(hw);
+	else
+		return E1000_SUCCESS;
+}
+
+/**
+ *  e1000_phy_force_speed_duplex - Generic force PHY speed/duplex
+ *  @hw: pointer to the HW structure
+ *
+ *  When the silicon family has not implemented a forced speed/duplex
+ *  function for the PHY, simply return E1000_SUCCESS.
+ **/
+static s32 e1000_phy_force_speed_duplex(struct e1000_hw *hw)
+{
+	if (hw->phy.ops.force_speed_duplex)
+		return hw->phy.ops.force_speed_duplex(hw);
+	else
+		return E1000_SUCCESS;
+}
+
+/**
+ *  e1000_get_phy_type_from_id - Get PHY type from id
+ *  @phy_id: phy_id read from the phy
+ *
+ *  Returns the phy type from the id.
+ **/
+enum e1000_phy_type e1000_get_phy_type_from_id(u32 phy_id)
+{
+	enum e1000_phy_type phy_type = e1000_phy_unknown;
+
+	switch (phy_id) {
+	case M88E1000_I_PHY_ID:
+	case M88E1000_E_PHY_ID:
+	case M88E1111_I_PHY_ID:
+	case M88E1011_I_PHY_ID:
+		phy_type = e1000_phy_m88;
+		break;
+	case IGP01E1000_I_PHY_ID: /* IGP 1 & 2 share this */
+		phy_type = e1000_phy_igp_2;
+		break;
+	case GG82563_E_PHY_ID:
+		phy_type = e1000_phy_gg82563;
+		break;
+	case IGP03E1000_E_PHY_ID:
+		phy_type = e1000_phy_igp_3;
+		break;
+	case IFE_E_PHY_ID:
+	case IFE_PLUS_E_PHY_ID:
+	case IFE_C_E_PHY_ID:
+		phy_type = e1000_phy_ife;
+		break;
+	default:
+		phy_type = e1000_phy_unknown;
+		break;
+	}
+	return phy_type;
+}
+
+/**
+ *  e1000_commit_phy - Soft PHY reset
+ *  @hw: pointer to the HW structure
+ *
+ *  Performs a soft PHY reset on those that apply. This is a function pointer
+ *  entry point called by drivers.
+ **/
+s32 e1000_commit_phy(struct e1000_hw *hw)
+{
+	if (hw->phy.ops.commit_phy)
+		return hw->phy.ops.commit_phy(hw);
+	else
+		return E1000_SUCCESS;
+}
+
+/**
+ *  e1000_set_d0_lplu_state - Sets low power link up state for D0
+ *  @hw: pointer to the HW structure
+ *  @active: boolean used to enable/disable lplu
+ *
+ *  Success returns 0, Failure returns 1
+ *
+ *  The low power link up (lplu) state is set to the power management level D0
+ *  and SmartSpeed is disabled when active is true, else clear lplu for D0
+ *  and enable Smartspeed.  LPLU and Smartspeed are mutually exclusive.  LPLU
+ *  is used during Dx states where the power conservation is most important.
+ *  During driver activity, SmartSpeed should be enabled so performance is
+ *  maintained.  This is a function pointer entry point called by drivers.
+ **/
+s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active)
+{
+	if (hw->phy.ops.set_d0_lplu_state)
+		return hw->phy.ops.set_d0_lplu_state(hw, active);
+	else
+		return E1000_SUCCESS;
+}

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

--- NEW FILE linux-2.6-netdev-e1000e-02.patch ---
From: Auke Kok <auke-jan h kok 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 intel com>
Signed-off-by: Jeff Garzik <jeff garzik org>
---

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

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

--- NEW FILE linux-2.6-netdev-e1000e-03.patch ---
From: Auke Kok <auke-jan h kok 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 intel com>
Signed-off-by: Jeff Garzik <jeff garzik org>
---

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

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

--- NEW FILE linux-2.6-netdev-e1000e-04.patch ---
From: Auke Kok <auke-jan h kok 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 intel com>
Signed-off-by: Jeff Garzik <jeff garzik org>
---

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

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

--- NEW FILE linux-2.6-netdev-e1000e-05.patch ---
From: Auke Kok <auke-jan h kok 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 intel com>
Signed-off-by: Jeff Garzik <jeff garzik org>
---

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

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

--- NEW FILE linux-2.6-netdev-e1000e-06.patch ---
From: Auke Kok <auke-jan h kok 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 intel com>
Signed-off-by: Jeff Garzik <jeff garzik org>
---

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

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

--- NEW FILE linux-2.6-netdev-e1000e-07.patch ---
From: Auke Kok <auke-jan h kok 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 intel com>
Signed-off-by: Jeff Garzik <jeff garzik org>
---

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

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

--- NEW FILE linux-2.6-netdev-e1000e-08.patch ---
From: Auke Kok <auke-jan h kok 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 intel com>
Signed-off-by: Jeff Garzik <jeff garzik org>
---

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

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

--- NEW FILE linux-2.6-netdev-e1000e-09.patch ---
From: Auke Kok <auke-jan h kok 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 intel com>
Signed-off-by: Jeff Garzik <jeff garzik org>
---

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

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

--- NEW FILE linux-2.6-netdev-e1000e-10.patch ---
From: Auke Kok <auke-jan h kok 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 intel com>
Signed-off-by: Jeff Garzik <jeff garzik org>
---

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

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

--- NEW FILE linux-2.6-nfs-missing-braces.patch ---
From:	"Maciej W. Rozycki" <macro linux-mips org>
To:	Trond Myklebust <trond myklebust fys uio no>
cc:	linux-kernel vger kernel org
Subject: [PATCH] 2.6.21: nfs_readpages: Add missing braces
Message-ID: <Pine LNX 4 64N 0705211402170 8263 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 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 vger kernel org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


linux-2.6-nfs-noreaddirplus.patch:

--- NEW FILE linux-2.6-nfs-noreaddirplus.patch ---
>From davej  Tue May 15 10:20:48 2007
Return-Path: <SteveD 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 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 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 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 redhat com>; Tue, 15 May 2007 10:15:15 -0400
Message-ID: <4649C06E 1050306 RedHat com>
Date: Tue, 15 May 2007 10:15:10 -0400
From: Steve Dickson <SteveD 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 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 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 redhat com>
    Signed-off-by: Trond Myklebust <Trond Myklebust netapp com>

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

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


linux-2.6-ondemand-timer.patch:

--- NEW FILE linux-2.6-ondemand-timer.patch ---
>From davej  Wed Mar 28 19:01:19 2007
Return-path: <venkatesh pallipadi 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 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 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 intel com>)
	id 1HWh8h-0006J9-Es
	for davej 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 intel com>
To: Oleg Nesterov <oleg tv-sign ru>
Cc: linux-kernel <linux-kernel vger kernel org>,
	akpm linux-foundation org, davej codemonkey org uk,
	johnstul us ibm com, mingo elte hu, tglx linutronix de,
	Andi Kleen <ak suse de>
Subject: Re: [PATCH] Add support for deferrable timers (respun-Mar28)
Message-ID: <20070328230021 GA29774 linux-os sc intel com>
References: <200703212353 l2LNrNOj007453 shell0 pdx osdl net> <20070322140532 GA120 tv-sign ru> <20070322151817 GA29840 linux-os sc intel com> <20070322161355 GA160 tv-sign ru> <20070327204344 GA21529 linux-os sc intel com> <20070327211145 GB216 tv-sign ru> <20070327215542 GA27408 linux-os sc intel com> <20070327222227 GA279 tv-sign ru>
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
In-Reply-To: <20070327222227 GA279 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 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 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 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 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 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 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 intel com>
To: Andrew Morton <akpm osdl org>
Cc: linux-kernel <linux-kernel vger kernel org>, Dave Jones <davej redhat com>,
        tglx linutronix de
Subject: [PATCH 2/2] Export deferrable timer through workqueue and use it in ondemand governor
Message-ID: <20070321202339 GB29367 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 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 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 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 intel com>

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

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

--- NEW FILE linux-2.6-pass-g-to-assembler-under-config_debug_info.patch ---
From: Roland McGrath <roland 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 redhat com>
Cc: Sam Ravnborg <sam ravnborg org>
Cc: <linux-arch vger kernel org>
Signed-off-by: Andrew Morton <akpm linux-foundation org>
---

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

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

linux-2.6-pmac-zilog.patch:

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

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

--- NEW FILE linux-2.6-pmtrace-time-fix.patch ---
--- linux-2.6.22.noarch/drivers/base/power/trace.c~	2007-08-29 15:34:17.000000000 -0400
+++ linux-2.6.22.noarch/drivers/base/power/trace.c	2007-08-29 15:34:24.000000000 -0400
@@ -114,7 +114,7 @@ static unsigned int read_magic_time(void
 	get_rtc_time(&time);
 	printk("Time: %2d:%02d:%02d  Date: %02d/%02d/%02d\n",
 		time.tm_hour, time.tm_min, time.tm_sec,
-		time.tm_mon, time.tm_mday, time.tm_year);
+		time.tm_mon + 1, time.tm_mday, time.tm_year % 100);
 	val = time.tm_year;				/* 100 years */
 	if (val > 100)
 		val -= 100;

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

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

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

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

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

Signed-off-by: Johannes Berg <johannes sipsolutions net>
Cc: Benjamin Herrenschmidt <benh 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 sipsolutions net>
+ *
+ * GPLv2
+ */
+
+#include <linux/time.h>
+#include <asm/rtc.h>
+
+static unsigned long suspend_rtc_time;
+
+/*
+ * Reset the time after a sleep.
+ */
+static int timer_resume(struct sys_device *dev)
+{
+	struct timeval tv;
+	struct timespec ts;
+	struct rtc_time cur_rtc_tm;
+	unsigned long cur_rtc_time, diff;
+
+	/* get current RTC time and convert to seconds */
+	get_rtc_time(&cur_rtc_tm);
+	rtc_tm_to_time(&cur_rtc_tm, &cur_rtc_time);
+
+	diff = cur_rtc_time - suspend_rtc_time;
+
+	/* adjust time of day by seconds that elapsed while
+	 * we were suspended */
+	do_gettimeofday(&tv);
+	ts.tv_sec = tv.tv_sec + diff;
+	ts.tv_nsec = tv.tv_usec * NSEC_PER_USEC;
+	do_settimeofday(&ts);
+
+	return 0;
+}
+
+static int timer_suspend(struct sys_device *dev, pm_message_t state)
+{
+	struct rtc_time suspend_rtc_tm;
+	WARN_ON(!ppc_md.get_rtc_time);
+
+	get_rtc_time(&suspend_rtc_tm);
+	rtc_tm_to_time(&suspend_rtc_tm, &suspend_rtc_time);
+
+	return 0;
+}
+
+static struct sysdev_class timer_sysclass = {
+	.resume = timer_resume,
+	.suspend = timer_suspend,
+	set_kset_name("timer"),
+};
+
+static struct sys_device device_timer = {
+	.id = 0,
+	.cls = &timer_sysclass,
+};
+
+static int time_init_device(void)
+{
+	int error = sysdev_class_register(&timer_sysclass);
+	if (!error)
+		error = sysdev_register(&device_timer);
+	return error;
+}
+
+device_initcall(time_init_device);

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

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

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

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

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

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

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

Signed-off-by: Johannes Berg <johannes sipsolutions net>
Cc: Benjamin Herrenschmidt <benh 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 sipsolutions net>
+ *
+ * GPLv2
+ */
+
+#include <linux/sched.h>
+#include <asm/suspend.h>
+#include <asm/cputable.h>
+#include <asm/system.h>
+#include <asm/current.h>
+#include <asm/mmu_context.h>
+
+#ifdef CONFIG_SPE
+extern void enable_kernel_spe(void);
+#endif
+
+void save_processor_state(void)
+{
+	/* Giveup the lazy FPU & vec so we don't have to back them
+	 * up from the low level code
+	 */
+	enable_kernel_fp();
+
+#ifdef CONFIG_ALTIVEC
+	if (cur_cpu_spec->cpu_features & CPU_FTR_ALTIVEC)
+		enable_kernel_altivec();
+#endif /* CONFIG_ALTIVEC */
+
+#ifdef CONFIG_SPE
+	enable_kernel_spe();
+#endif
+}
+
+void restore_processor_state(void)
+{
+#ifdef CONFIG_PPC32
+	set_context(current->active_mm->context.id, current->active_mm->pgd);
+#endif
+}

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

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

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

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

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

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

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

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

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

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

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

Signed-off-by: Johannes Berg <johannes sipsolutions net>
Cc: Benjamin Herrenschmidt <benh 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 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 sipsolutions net>
+
+---------------------------

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

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

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

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

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

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

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

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

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

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

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

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

--- wireless-dev.orig/sound/oss/dmasound/Makefile	2007-07-18 14:25:24.662900849 +0200
+++ wireless-dev/sound/oss/dmasound/Makefile	2007-07-18 14:25:39.812900849 +0200
@@ -2,12 +2,6 @@
 # Makefile for the DMA sound driver
 #
 
-dmasound_pmac-y			+= dmasound_awacs.o \
-				   trans_16.o dac3550a.o tas_common.o \
-				   tas3001c.o tas3001c_tables.o \
-				   tas3004.o tas3004_tables.o
-
 obj-$(CONFIG_DMASOUND_ATARI)	+= dmasound_core.o dmasound_atari.o
-obj-$(CONFIG_DMASOUND_PMAC)	+= dmasound_core.o dmasound_pmac.o
 obj-$(CONFIG_DMASOUND_PAULA)	+= dmasound_core.o dmasound_paula.o
 obj-$(CONFIG_DMASOUND_Q40)	+= dmasound_core.o dmasound_q40.o
--- wireless-dev.orig/sound/oss/dmasound/awacs_defs.h	2007-07-18 14:25:24.722900849 +0200
+++ /dev/null	1970-01-01 00:00:00.000000000 +0000
@@ -1,251 +0,0 @@
-/*********************************************************/
-/* This file was written by someone, somewhere, sometime */
-/* And is released into the Public Domain                */
-/*********************************************************/
-
-#ifndef _AWACS_DEFS_H_
-#define _AWACS_DEFS_H_
-
-/*******************************/
-/* AWACs Audio Register Layout */
-/*******************************/
-
-struct awacs_regs {
-    unsigned	control;	/* Audio control register */
-    unsigned	pad0[3];
-    unsigned	codec_ctrl;	/* Codec control register */
-    unsigned	pad1[3];
-    unsigned	codec_stat;	/* Codec status register */
-    unsigned	pad2[3];
-    unsigned	clip_count;	/* Clipping count register */
-    unsigned	pad3[3];
-    unsigned	byteswap;	/* Data is little-endian if 1 */
-};
-
-/*******************/
-/* Audio Bit Masks */
-/*******************/
-
-/* Audio Control Reg Bit Masks */
-/* ----- ------- --- --- ----- */
-#define MASK_ISFSEL	(0xf)		/* Input SubFrame Select */
-#define MASK_OSFSEL	(0xf << 4)	/* Output SubFrame Select */
-#define MASK_RATE	(0x7 << 8)	/* Sound Rate */
-#define MASK_CNTLERR	(0x1 << 11)	/* Error */
-#define MASK_PORTCHG	(0x1 << 12)	/* Port Change */
-#define MASK_IEE	(0x1 << 13)	/* Enable Interrupt on Error */
-#define MASK_IEPC	(0x1 << 14)	/* Enable Interrupt on Port Change */
-#define MASK_SSFSEL	(0x3 << 15)	/* Status SubFrame Select */
-
-/* Audio Codec Control Reg Bit Masks */
-/* ----- ----- ------- --- --- ----- */
-#define MASK_NEWECMD	(0x1 << 24)	/* Lock: don't write to reg when 1 */
-#define MASK_EMODESEL	(0x3 << 22)	/* Send info out on which frame? */
-#define MASK_EXMODEADDR	(0x3ff << 12)	/* Extended Mode Address -- 10 bits */
-#define MASK_EXMODEDATA	(0xfff)		/* Extended Mode Data -- 12 bits */
-
-/* Audio Codec Control Address Values / Masks */
-/* ----- ----- ------- ------- ------ - ----- */
-#define MASK_ADDR0	(0x0 << 12)	/* Expanded Data Mode Address 0 */
-#define MASK_ADDR_MUX	MASK_ADDR0	/* Mux Control */
-#define MASK_ADDR_GAIN	MASK_ADDR0
-
-#define MASK_ADDR1	(0x1 << 12)	/* Expanded Data Mode Address 1 */
-#define MASK_ADDR_MUTE	MASK_ADDR1
-#define MASK_ADDR_RATE	MASK_ADDR1
-
-#define MASK_ADDR2	(0x2 << 12)	/* Expanded Data Mode Address 2 */
-#define MASK_ADDR_VOLA	MASK_ADDR2	/* Volume Control A -- Headphones */
-#define MASK_ADDR_VOLHD MASK_ADDR2
-
-#define MASK_ADDR4	(0x4 << 12)	/* Expanded Data Mode Address 4 */
-#define MASK_ADDR_VOLC	MASK_ADDR4	/* Volume Control C -- Speaker */
-#define MASK_ADDR_VOLSPK MASK_ADDR4
-
-/* additional registers of screamer */
-#define MASK_ADDR5	(0x5 << 12)	/* Expanded Data Mode Address 5 */
-#define MASK_ADDR6	(0x6 << 12)	/* Expanded Data Mode Address 6 */
-#define MASK_ADDR7	(0x7 << 12)	/* Expanded Data Mode Address 7 */
-
-/* Address 0 Bit Masks & Macros */
-/* ------- - --- ----- - ------ */
-#define MASK_GAINRIGHT	(0xf)		/* Gain Right Mask */
-#define MASK_GAINLEFT	(0xf << 4)	/* Gain Left Mask */
-#define MASK_GAINLINE	(0x1 << 8)	/* Disable Mic preamp */
-#define MASK_GAINMIC	(0x0 << 8)	/* Enable Mic preamp */
-
-#define MASK_MUX_CD	(0x1 << 9)	/* Select CD in MUX */
-#define MASK_MUX_MIC	(0x1 << 10)	/* Select Mic in MUX */
-#define MASK_MUX_AUDIN	(0x1 << 11)	/* Select Audio In in MUX */
-#define MASK_MUX_LINE	MASK_MUX_AUDIN
-
-#define GAINRIGHT(x)	((x) & MASK_GAINRIGHT)
-#define GAINLEFT(x)	(((x) << 4) & MASK_GAINLEFT)
-
-#define DEF_CD_GAIN 0x00bb
-#define DEF_MIC_GAIN 0x00cc
-
-/* Address 1 Bit Masks */
-/* ------- - --- ----- */
-#define MASK_ADDR1RES1	(0x3)		/* Reserved */
-#define MASK_RECALIBRATE (0x1 << 2)	/* Recalibrate */
-#define MASK_SAMPLERATE	(0x7 << 3)	/* Sample Rate: */
-#define MASK_LOOPTHRU	(0x1 << 6)	/* Loopthrough Enable */
-#define MASK_CMUTE	(0x1 << 7)	/* Output C (Speaker) Mute when 1 */
-#define MASK_SPKMUTE	MASK_CMUTE
-#define MASK_ADDR1RES2	(0x1 << 8)	/* Reserved */
-#define MASK_AMUTE	(0x1 << 9)	/* Output A (Headphone) Mute when 1 */
-#define MASK_HDMUTE	MASK_AMUTE
-#define MASK_PAROUT0	(0x1 << 10)	/* Parallel Output 0 */
-#define MASK_PAROUT1	(0x2 << 10)	/* Parallel Output 1 */
-
-#define MASK_MIC_BOOST  (0x4)           /* screamer mic boost */
-
-#define SAMPLERATE_48000	(0x0 << 3)	/* 48 or 44.1 kHz */
-#define SAMPLERATE_32000	(0x1 << 3)	/* 32 or 29.4 kHz */
-#define SAMPLERATE_24000	(0x2 << 3)	/* 24 or 22.05 kHz */
-#define SAMPLERATE_19200	(0x3 << 3)	/* 19.2 or 17.64 kHz */
-#define SAMPLERATE_16000	(0x4 << 3)	/* 16 or 14.7 kHz */
-#define SAMPLERATE_12000	(0x5 << 3)	/* 12 or 11.025 kHz */
-#define SAMPLERATE_9600		(0x6 << 3)	/* 9.6 or 8.82 kHz */
-#define SAMPLERATE_8000		(0x7 << 3)	/* 8 or 7.35 kHz */
-
-/* Address 2 & 4 Bit Masks & Macros */
-/* ------- - - - --- ----- - ------ */
-#define MASK_OUTVOLRIGHT (0xf)		/* Output Right Volume */
-#define MASK_ADDR2RES1	(0x2 << 4)	/* Reserved */
-#define MASK_ADDR4RES1	MASK_ADDR2RES1
-#define MASK_OUTVOLLEFT	(0xf << 6)	/* Output Left Volume */
-#define MASK_ADDR2RES2	(0x2 << 10)	/* Reserved */
-#define MASK_ADDR4RES2	MASK_ADDR2RES2
-
-#define VOLRIGHT(x)	(((~(x)) & MASK_OUTVOLRIGHT))
-#define VOLLEFT(x)	(((~(x)) << 6) & MASK_OUTVOLLEFT)
-
-/* Audio Codec Status Reg Bit Masks */
-/* ----- ----- ------ --- --- ----- */
-#define MASK_EXTEND	(0x1 << 23)	/* Extend */
-#define MASK_VALID	(0x1 << 22)	/* Valid Data? */
-#define MASK_OFLEFT	(0x1 << 21)	/* Overflow Left */
-#define MASK_OFRIGHT	(0x1 << 20)	/* Overflow Right */
-#define MASK_ERRCODE	(0xf << 16)	/* Error Code */
-#define MASK_REVISION	(0xf << 12)	/* Revision Number */
-#define MASK_MFGID	(0xf << 8)	/* Mfg. ID */
-#define MASK_CODSTATRES	(0xf << 4)	/* bits 4 - 7 reserved */
-#define MASK_INPPORT	(0xf)		/* Input Port */
-#define MASK_HDPCONN	8		/* headphone plugged in */
-
-/* Clipping Count Reg Bit Masks */
-/* -------- ----- --- --- ----- */
-#define MASK_CLIPLEFT	(0xff << 7)	/* Clipping Count, Left Channel */
-#define MASK_CLIPRIGHT	(0xff)		/* Clipping Count, Right Channel */
-
-/* DBDMA ChannelStatus Bit Masks */
-/* ----- ------------- --- ----- */
-#define MASK_CSERR	(0x1 << 7)	/* Error */
-#define MASK_EOI	(0x1 << 6)	/* End of Input -- only for Input Channel */
-#define MASK_CSUNUSED	(0x1f << 1)	/* bits 1-5 not used */
-#define MASK_WAIT	(0x1)		/* Wait */
-
-/* Various Rates */
-/* ------- ----- */
-#define RATE_48000	(0x0 << 8)	/* 48 kHz */
-#define RATE_44100	(0x0 << 8)	/* 44.1 kHz */
[...7608 lines suppressed...]
-	userCount >>= (stereo? 2: 1);
-	ftotal = frameLeft;
-	utotal = userCount;
-	while (frameLeft) {
-		int datal,datar;
-
-		if (bal<0 && userCount == 0)
-			break;
-
-		datal = *fp++;
-		datal = (datal * software_input_volume) >> 7;
-		if (stereo) {
-			datar = *fp;
-			datar = (datar * software_input_volume) >> 7;
-		}
-		fp++;
-		if (bal < 0) {
-			if (put_user(datal, up++))
-				return -EFAULT;
-			if (stereo) {
-				if (put_user(datar, up++))
-					return -EFAULT;
-			}
-			userCount--;
-			bal += hSpeed;
-		}
-		frameLeft--;
-		bal -= sSpeed;
-	}
-	expand_read_bal=bal;
-	*frameUsed += (ftotal - frameLeft) * 4;
-	utotal -= userCount;
-	return stereo? utotal * 4: utotal * 2;
-}
-
-static ssize_t pmac_ctx_u16_read(const u_char __user *userPtr, size_t userCount,
-			   u_char frame[], ssize_t *frameUsed,
-			   ssize_t frameLeft)
-{
-	int bal = expand_read_bal;
-	int mask = (dmasound.soft.format == AFMT_U16_LE? 0x0080: 0x8000);
-	short *fp = (short *) &frame[*frameUsed];
-	short __user *up = (short __user *) userPtr;
-	int stereo = dmasound.soft.stereo;
-	int hSpeed = dmasound.hard.speed, sSpeed = dmasound.soft.speed;
-	int utotal, ftotal;
-
-	frameLeft >>= 2;
-	userCount >>= (stereo? 2: 1);
-	ftotal = frameLeft;
-	utotal = userCount;
-	while (frameLeft) {
-		int datal,datar;
-
-		if (bal<0 && userCount == 0)
-			break;
-
-		datal = *fp++;
-		datal = (datal * software_input_volume) >> 7;
-		datal ^= mask;
-		if (stereo) {
-			datar = *fp;
-			datar = (datar * software_input_volume) >> 7;
-			datar ^= mask;
-		}
-		fp++;
-		if (bal < 0) {
-			if (put_user(datal, up++))
-				return -EFAULT;
-			if (stereo) {
-				if (put_user(datar, up++))
-					return -EFAULT;
-			}
-			userCount--;
-			bal += hSpeed;
-		}
-		frameLeft--;
-		bal -= sSpeed;
-	}
-	expand_read_bal=bal;
-	*frameUsed += (ftotal - frameLeft) * 4;
-	utotal -= userCount;
-	return stereo? utotal * 4: utotal * 2;
-}
-
-
-TRANS transAwacsNormal = {
-	.ct_ulaw=	pmac_ct_law,
-	.ct_alaw=	pmac_ct_law,
-	.ct_s8=		pmac_ct_s8,
-	.ct_u8=		pmac_ct_u8,
-	.ct_s16be=	pmac_ct_s16,
-	.ct_u16be=	pmac_ct_u16,
-	.ct_s16le=	pmac_ct_s16,
-	.ct_u16le=	pmac_ct_u16,
-};
-
-TRANS transAwacsExpand = {
-	.ct_ulaw=	pmac_ctx_law,
-	.ct_alaw=	pmac_ctx_law,
-	.ct_s8=		pmac_ctx_s8,
-	.ct_u8=		pmac_ctx_u8,
-	.ct_s16be=	pmac_ctx_s16,
-	.ct_u16be=	pmac_ctx_u16,
-	.ct_s16le=	pmac_ctx_s16,
-	.ct_u16le=	pmac_ctx_u16,
-};
-
-TRANS transAwacsNormalRead = {
-	.ct_s8=		pmac_ct_s8_read,
-	.ct_u8=		pmac_ct_u8_read,
-	.ct_s16be=	pmac_ct_s16_read,
-	.ct_u16be=	pmac_ct_u16_read,
-	.ct_s16le=	pmac_ct_s16_read,
-	.ct_u16le=	pmac_ct_u16_read,
-};
-
-TRANS transAwacsExpandRead = {
-	.ct_s8=		pmac_ctx_s8_read,
-	.ct_u8=		pmac_ctx_u8_read,
-	.ct_s16be=	pmac_ctx_s16_read,
-	.ct_u16be=	pmac_ctx_u16_read,
-	.ct_s16le=	pmac_ctx_s16_read,
-	.ct_u16le=	pmac_ctx_u16_read,
-};
-
-/* translation tables */
-/* 16 bit mu-law */
-
-static short dmasound_ulaw2dma16[] = {
-	-32124,	-31100,	-30076,	-29052,	-28028,	-27004,	-25980,	-24956,
-	-23932,	-22908,	-21884,	-20860,	-19836,	-18812,	-17788,	-16764,
-	-15996,	-15484,	-14972,	-14460,	-13948,	-13436,	-12924,	-12412,
-	-11900,	-11388,	-10876,	-10364,	-9852,	-9340,	-8828,	-8316,
-	-7932,	-7676,	-7420,	-7164,	-6908,	-6652,	-6396,	-6140,
-	-5884,	-5628,	-5372,	-5116,	-4860,	-4604,	-4348,	-4092,
-	-3900,	-3772,	-3644,	-3516,	-3388,	-3260,	-3132,	-3004,
-	-2876,	-2748,	-2620,	-2492,	-2364,	-2236,	-2108,	-1980,
-	-1884,	-1820,	-1756,	-1692,	-1628,	-1564,	-1500,	-1436,
-	-1372,	-1308,	-1244,	-1180,	-1116,	-1052,	-988,	-924,
-	-876,	-844,	-812,	-780,	-748,	-716,	-684,	-652,
-	-620,	-588,	-556,	-524,	-492,	-460,	-428,	-396,
-	-372,	-356,	-340,	-324,	-308,	-292,	-276,	-260,
-	-244,	-228,	-212,	-196,	-180,	-164,	-148,	-132,
-	-120,	-112,	-104,	-96,	-88,	-80,	-72,	-64,
-	-56,	-48,	-40,	-32,	-24,	-16,	-8,	0,
-	32124,	31100,	30076,	29052,	28028,	27004,	25980,	24956,
-	23932,	22908,	21884,	20860,	19836,	18812,	17788,	16764,
-	15996,	15484,	14972,	14460,	13948,	13436,	12924,	12412,
-	11900,	11388,	10876,	10364,	9852,	9340,	8828,	8316,
-	7932,	7676,	7420,	7164,	6908,	6652,	6396,	6140,
-	5884,	5628,	5372,	5116,	4860,	4604,	4348,	4092,
-	3900,	3772,	3644,	3516,	3388,	3260,	3132,	3004,
-	2876,	2748,	2620,	2492,	2364,	2236,	2108,	1980,
-	1884,	1820,	1756,	1692,	1628,	1564,	1500,	1436,
-	1372,	1308,	1244,	1180,	1116,	1052,	988,	924,
-	876,	844,	812,	780,	748,	716,	684,	652,
-	620,	588,	556,	524,	492,	460,	428,	396,
-	372,	356,	340,	324,	308,	292,	276,	260,
-	244,	228,	212,	196,	180,	164,	148,	132,
-	120,	112,	104,	96,	88,	80,	72,	64,
-	56,	48,	40,	32,	24,	16,	8,	0,
-};
-
-/* 16 bit A-law */
-
-static short dmasound_alaw2dma16[] = {
-	-5504,	-5248,	-6016,	-5760,	-4480,	-4224,	-4992,	-4736,
-	-7552,	-7296,	-8064,	-7808,	-6528,	-6272,	-7040,	-6784,
-	-2752,	-2624,	-3008,	-2880,	-2240,	-2112,	-2496,	-2368,
-	-3776,	-3648,	-4032,	-3904,	-3264,	-3136,	-3520,	-3392,
-	-22016,	-20992,	-24064,	-23040,	-17920,	-16896,	-19968,	-18944,
-	-30208,	-29184,	-32256,	-31232,	-26112,	-25088,	-28160,	-27136,
-	-11008,	-10496,	-12032,	-11520,	-8960,	-8448,	-9984,	-9472,
-	-15104,	-14592,	-16128,	-15616,	-13056,	-12544,	-14080,	-13568,
-	-344,	-328,	-376,	-360,	-280,	-264,	-312,	-296,
-	-472,	-456,	-504,	-488,	-408,	-392,	-440,	-424,
-	-88,	-72,	-120,	-104,	-24,	-8,	-56,	-40,
-	-216,	-200,	-248,	-232,	-152,	-136,	-184,	-168,
-	-1376,	-1312,	-1504,	-1440,	-1120,	-1056,	-1248,	-1184,
-	-1888,	-1824,	-2016,	-1952,	-1632,	-1568,	-1760,	-1696,
-	-688,	-656,	-752,	-720,	-560,	-528,	-624,	-592,
-	-944,	-912,	-1008,	-976,	-816,	-784,	-880,	-848,
-	5504,	5248,	6016,	5760,	4480,	4224,	4992,	4736,
-	7552,	7296,	8064,	7808,	6528,	6272,	7040,	6784,
-	2752,	2624,	3008,	2880,	2240,	2112,	2496,	2368,
-	3776,	3648,	4032,	3904,	3264,	3136,	3520,	3392,
-	22016,	20992,	24064,	23040,	17920,	16896,	19968,	18944,
-	30208,	29184,	32256,	31232,	26112,	25088,	28160,	27136,
-	11008,	10496,	12032,	11520,	8960,	8448,	9984,	9472,
-	15104,	14592,	16128,	15616,	13056,	12544,	14080,	13568,
-	344,	328,	376,	360,	280,	264,	312,	296,
-	472,	456,	504,	488,	408,	392,	440,	424,
-	88,	72,	120,	104,	24,	8,	56,	40,
-	216,	200,	248,	232,	152,	136,	184,	168,
-	1376,	1312,	1504,	1440,	1120,	1056,	1248,	1184,
-	1888,	1824,	2016,	1952,	1632,	1568,	1760,	1696,
-	688,	656,	752,	720,	560,	528,	624,	592,
-	944,	912,	1008,	976,	816,	784,	880,	848,
-};

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

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

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

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

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

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

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

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

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

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

Signed-off-by: Johannes Berg <johannes sipsolutions net>
Cc: Benjamin Herrenschmidt <benh 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 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 sipsolutions net>
+
+---------------------------

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

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

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

--- NEW FILE linux-2.6-powerpc-reserve-initrd-1.patch ---
>From linuxppc-dev-bounces+dwmw2=infradead org ozlabs org Wed Feb 28 03:12:45 2007
Return-path: <linuxppc-dev-bounces+dwmw2=infradead org ozlabs org>
Envelope-to: dwmw2 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 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 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 infradead org>; Wed, 28 Feb 2007
	14:12:34 +1100 (EST)
X-Original-To: linuxppc-dev ozlabs org
Delivered-To: linuxppc-dev 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 samba org>, Benjamin Herrenschmidt <benh kernel crashing org>, <linuxppc-dev ozlabs org>
From: David Gibson <david gibson dropbear id au>
Subject: [PATCH 1/2] powerpc: Allow duplicate lmb_reserve() calls
In-Reply-To: <20070228031120 GF11775 localhost localdomain>
Message-Id: <20070228031229 430F3DDDF6 ozlabs org>
Date: Wed, 28 Feb 2007 14:12:29 +1100 (EST)
X-BeenThere: linuxppc-dev 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 ozlabs org?subject=unsubscribe>
List-Archive: <http://ozlabs.org/pipermail/linuxppc-dev>
List-Post: <mailto:linuxppc-dev ozlabs org>
List-Help: <mailto:linuxppc-dev-request ozlabs org?subject=help>
List-Subscribe: <https://ozlabs.org/mailman/listinfo/linuxppc-dev>,
	<mailto:linuxppc-dev-request ozlabs org?subject=subscribe>
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Sender: linuxppc-dev-bounces+dwmw2=infradead org ozlabs org
Errors-To: linuxppc-dev-bounces+dwmw2=infradead org 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 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 ozlabs org
https://ozlabs.org/mailman/listinfo/linuxppc-dev

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

--- NEW FILE linux-2.6-powerpc-reserve-initrd-2.patch ---
>From linuxppc-dev-bounces+dwmw2=infradead org ozlabs org Wed Feb 28 03:13:44 2007
Return-path: <linuxppc-dev-bounces+dwmw2=infradead org ozlabs org>
Envelope-to: dwmw2 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 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 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 infradead org>; Wed, 28 Feb 2007
	14:13:05 +1100 (EST)
X-Original-To: linuxppc-dev ozlabs org
Delivered-To: linuxppc-dev 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 samba org>, Benjamin Herrenschmidt <benh kernel crashing org>, <linuxppc-dev ozlabs org>
From: David Gibson <david gibson dropbear id au>
Subject: [PATCH 2/2] Automatically lmb_reserve() initrd
In-Reply-To: <20070228031120 GF11775 localhost localdomain>
Message-Id: <20070228031229 55D11DDDF9 ozlabs org>
Date: Wed, 28 Feb 2007 14:12:29 +1100 (EST)
X-BeenThere: linuxppc-dev 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 ozlabs org?subject=unsubscribe>
List-Archive: <http://ozlabs.org/pipermail/linuxppc-dev>
List-Post: <mailto:linuxppc-dev ozlabs org>
List-Help: <mailto:linuxppc-dev-request ozlabs org?subject=help>
List-Subscribe: <https://ozlabs.org/mailman/listinfo/linuxppc-dev>,
	<mailto:linuxppc-dev-request ozlabs org?subject=subscribe>
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Sender: linuxppc-dev-bounces+dwmw2=infradead org ozlabs org
Errors-To: linuxppc-dev-bounces+dwmw2=infradead org 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 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 ozlabs org
https://ozlabs.org/mailman/listinfo/linuxppc-dev

linux-2.6-powerpc-slabalign.patch:

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

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

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

Subject: cell: Safer of_has_vicinity routine

From: Andre Detsch <adetsch 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 br ibm com>

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

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

--- NEW FILE linux-2.6-powerpc-vdso-install-unstripped-copies-on-disk.patch ---
From: Roland McGrath <roland 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 redhat com>
Cc: Sam Ravnborg <sam ravnborg org>
Cc: Paul Mackerras <paulus samba org>
Cc: Benjamin Herrenschmidt <benh kernel crashing org>
---

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

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

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

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

--- NEW FILE linux-2.6-ppc-data-exception.patch ---
Gitweb:     http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=9ba4ace39fdfe22268daca9f28c5df384ae462cf
Commit:     9ba4ace39fdfe22268daca9f28c5df384ae462cf
Parent:     7c8545e98468c53809fc06788a3b9a34dff05240
Author:     Segher Boessenkool <segher kernel crashing org>
AuthorDate: Wed Jun 20 01:07:04 2007 +1000
Committer:  Paul Mackerras <paulus 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 kernel crashing org>
    Cc: Johannes Berg <johannes sipsolutions net>
    Signed-off-by: Paul Mackerras <paulus samba org>
---
 arch/powerpc/mm/fault.c |    5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)

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

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

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

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

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

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

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

--- NEW FILE linux-2.6-ps3-clear-spu-irq.patch ---
From: Masato Noguchi <Masato Noguchi 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 jp sony com>
Signed-off-by: Geoff Levand <geoffrey levand am sony com>
---
 arch/powerpc/platforms/cell/spu_base.c |   23 +++++++++++++++--------
 include/asm-powerpc/spu.h              |    2 +-
 2 files changed, 16 insertions(+), 9 deletions(-)

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

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

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

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

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

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

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

--- NEW FILE linux-2.6-ps3-ehci-iso.patch ---
From: Masashi Kimoto <Masashi_Kimoto 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 hq scei sony co jp>
Signed-off-by: Geoff Levand <geoffrey levand am sony com>

---
 drivers/usb/host/ehci-sched.c |   34 ++++++++++++++++++++++++++++++----
 1 file changed, 30 insertions(+), 4 deletions(-)

--- ps3-linux-dev.orig/drivers/usb/host/ehci-sched.c
+++ ps3-linux-dev/drivers/usb/host/ehci-sched.c
@@ -1168,8 +1168,21 @@ itd_urb_transaction (
 		if (likely (!list_empty(&stream->free_list))) {
 			itd = list_entry (stream->free_list.prev,
 					 struct ehci_itd, itd_list);
-			list_del (&itd->itd_list);
-			itd_dma = itd->itd_dma;
+#if defined(CONFIG_PPC_PS3)
+			/* Fix for Cell SCC ISO transfer (PS3 Bluetooth). */
+			if (firmware_has_feature(FW_FEATURE_PS3_LV1)
+				&& itd->frame == ((ehci_readl(ehci,
+				&ehci->regs->frame_index) >> 3)
+				% ehci->periodic_size))
+				itd = NULL;
+			else {
+				list_del (&itd->itd_list);
+				itd_dma = itd->itd_dma;
+			}
+#else
+                       list_del (&itd->itd_list);
+                       itd_dma = itd->itd_dma;
+#endif
 		} else
 			itd = NULL;
 
@@ -1784,8 +1797,21 @@ sitd_urb_transaction (
 		if (!list_empty(&stream->free_list)) {
 			sitd = list_entry (stream->free_list.prev,
 					 struct ehci_sitd, sitd_list);
-			list_del (&sitd->sitd_list);
-			sitd_dma = sitd->sitd_dma;
+#if defined(CONFIG_PPC_PS3)
+			/* Fix for Cell SCC ISO transfer (PS3 Bluetooth). */
+			if (firmware_has_feature(FW_FEATURE_PS3_LV1)
+				&& sitd->frame == ((ehci_readl(ehci,
+				&ehci->regs->frame_index) >> 3)
+				% ehci->periodic_size))
+				sitd = NULL;
+			else {
+				list_del (&sitd->sitd_list);
+				sitd_dma = sitd->sitd_dma;
+			}
+#else
+                       list_del (&sitd->sitd_list);
+                       sitd_dma = sitd->sitd_dma;
+#endif
 		} else
 			sitd = NULL;
 

linux-2.6-ps3-ethernet-autoload.patch:

--- NEW FILE linux-2.6-ps3-ethernet-autoload.patch ---
--- linux-2.6.20.ppc64/drivers/net/gelic_net.c	2007-03-30 18:35:11.000000000 +0100
+++ linux-2.6.20.ps3/drivers/net/gelic_net.c	2007-03-30 22:50:00.000000000 +0100
@@ -1875,3 +1886,4 @@ static int __init early_param_gelic_net(
 }
 early_param("gelic_vlan", early_param_gelic_net);
 #endif
+MODULE_ALIAS("ps3:3");

linux-2.6-ps3-ethernet-modular.patch:

--- NEW FILE linux-2.6-ps3-ethernet-modular.patch ---
diff --git a/drivers/net/gelic_net.c b/drivers/net/gelic_net.c
index f931bc7..48ad627 100644
--- a/drivers/net/gelic_net.c
+++ b/drivers/net/gelic_net.c
@@ -73,8 +73,9 @@ static int ps3_gelic_param = 1; /* vlan desc support */
 module_param(ps3_gelic_param, int, S_IRUGO);
 #endif
 
-struct gelic_net_card *gcard;
-static uint64_t gelic_irq_status;
+static struct gelic_net_card *gcard;
+static uint64_t *gelic_irq_status;
+
 
 static int dmac_status = 0;
 
@@ -838,7 +839,7 @@ gelic_net_kick_txdma(struct gelic_net_card *card,
 		}
 		if (!count) {
 			printk("lv1_net_start_txdma failed, status=%ld %016lx\n",\
-				status, gelic_irq_status);
+				status, *gelic_irq_status);
 		}
 	}
 }
@@ -1130,7 +1131,7 @@ gelic_net_interrupt(int irq, void *ptr)
 	unsigned long flags;
 	uint64_t status;
 
-	status = gelic_irq_status;
+	status = *gelic_irq_status;
 	rmb();
 	status0 = (uint32_t)(status >> 32);
 	status1 = (uint32_t)(status & 0xffffffff);
@@ -1632,6 +1633,12 @@ gelic_net_alloc_card(void)
 	if (!netdev)
 		return NULL;
 
+	gelic_irq_status = kzalloc(sizeof(*gelic_irq_status), GFP_DMA);
+	if (!gelic_irq_status) {
+		free_netdev(netdev);
+		return NULL;
+	}
+
 	card = netdev_priv(netdev);
 	card->netdev = netdev;
 	INIT_WORK(&card->tx_timeout_task, gelic_net_tx_timeout_task);
@@ -1677,7 +1684,7 @@ static int ps3_gelic_driver_probe (struct ps3_system_bus_device *dev)
 	}
 
 	result = lv1_net_set_interrupt_status_indicator(dev->did.bus_id,
-		dev->did.dev_id, ps3_mm_phys_to_lpar(__pa(&gelic_irq_status)),
+		dev->did.dev_id, ps3_mm_phys_to_lpar(__pa(gelic_irq_status)),
 		0);
 
 	if (result) {
@@ -1706,6 +1713,8 @@ fail_status_indicator:
 fail_dma_region:
 	ps3_close_hv_device(&dev->did);
 fail_open:
+	kfree(gelic_irq_status);
+	gelic_irq_status = NULL;
 	free_netdev(gcard->netdev); // enough???
 	gcard = NULL;
 fail_alloc_card:
@@ -1732,6 +1741,8 @@ ps3_gelic_driver_remove (struct ps3_system_bus_device *dev)
 		   atomic_read(&card->tx_timeout_task_counter) == 0);
 
 	unregister_netdev(netdev);
+	kfree(gelic_irq_status);
+	gelic_irq_status = NULL;
 	free_netdev(netdev);
 
 	lv1_net_set_interrupt_status_indicator(dev->did.bus_id, dev->did.dev_id,

linux-2.6-ps3-gelic-wireless.patch:

--- NEW FILE linux-2.6-ps3-gelic-wireless.patch ---
As of 2007-05-04 (commit 197a8b29cbb721909e1bde44c6e7a588d93ba440):

ps3-wip/ps3-gelic_wireless_base.diff
ps3-wip/ps3-gelic_wireless_kern16.diff
ps3-wip/ps3-gelic_wireless_kern21.diff
ps3-wip/ps3-gelic_wireless_wext.diff


diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 7876697..ea828bf 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2270,6 +2270,13 @@ config GELIC_NET
 	  To compile this driver as a module, choose M here: the
 	  module will be called gelic_net.
 
+config GELIC_WIRELESS
+	bool "Gelic net Wireless Extension"
+	depends on GELIC_NET
+	select WIRELESS_EXT
+	help
+	  Wireless Extension support for Gelic Gigabit Ethernet driver
+
 config GIANFAR
 	tristate "Gianfar Ethernet"
 	depends on 85xx || 83xx || PPC_86xx
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 9fa106a..704b839 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -61,6 +61,9 @@ obj-$(CONFIG_BNX2) += bnx2.o
 spidernet-y += spider_net.o spider_net_ethtool.o
 obj-$(CONFIG_SPIDER_NET) += spidernet.o sungem_phy.o
 obj-$(CONFIG_GELIC_NET) += gelic_net.o
+ifeq ($(CONFIG_GELIC_WIRELESS),y)
+  obj-$(CONFIG_GELIC_NET) += gelic_wireless.o
+endif
 obj-$(CONFIG_TC35815) += tc35815.o
 obj-$(CONFIG_SKGE) += skge.o
 obj-$(CONFIG_SKY2) += sky2.o
diff --git a/drivers/net/gelic_net.c b/drivers/net/gelic_net.c
index 79ca65f..f931bc7 100644
--- a/drivers/net/gelic_net.c
+++ b/drivers/net/gelic_net.c
@@ -60,145 +60,13 @@
 #include <asm/ps3.h>
 #include <asm/lv1call.h>
 
-#define GELIC_NET_DRV_NAME "Gelic Network Driver"
-#define GELIC_NET_DRV_VERSION "1.0"
-
-#define GELIC_NET_DEBUG
-
-#ifdef GELIC_NET_DEBUG
-#define DPRINTK(fmt,arg...)   printk(KERN_ERR fmt ,##arg)
-#define DPRINTKK(fmt,arg...)  printk(KERN_ERR fmt ,##arg)
-#else
-#define DPRINTK(fmt,arg...)
-#define DPRINTKK(fmt,arg...)
+#ifdef CONFIG_GELIC_WIRELESS
+#include "gelic_wireless.h"
 #endif
+#include "gelic_net.h"
 
-#define GELIC_NET_ETHTOOL               /* use ethtool */
-
-/* ioctl */
-#define GELIC_NET_GET_MODE              (SIOCDEVPRIVATE + 0)
-#define GELIC_NET_SET_MODE              (SIOCDEVPRIVATE + 1)
-
-/* descriptors */
-#define GELIC_NET_RX_DESCRIPTORS        128 /* num of descriptors */
-#define GELIC_NET_TX_DESCRIPTORS        128 /* num of descriptors */
-
-#define GELIC_NET_MAX_MTU               2308
-#define GELIC_NET_MIN_MTU               64
-#define GELIC_NET_RXBUF_ALIGN           128
-#define GELIC_NET_RX_CSUM_DEFAULT       1 /* hw chksum */
-#define GELIC_NET_WATCHDOG_TIMEOUT      5*HZ
-#define GELIC_NET_NAPI_WEIGHT           64
-#define GELIC_NET_BROADCAST_ADDR        0xffffffffffff
-#define GELIC_NET_VLAN_POS              (VLAN_ETH_ALEN * 2)
-#define GELIC_NET_VLAN_MAX              4
-#define GELIC_NET_MC_COUNT_MAX          32 /* multicast address list */
-
-enum gelic_net_int0_status {
-	GELIC_NET_GDTDCEINT  = 24,
-	GELIC_NET_GRFANMINT  = 28,
-};
-
-/* GHIINT1STS bits */
-enum gelic_net_int1_status {
-	GELIC_NET_GDADCEINT = 14,
-};
-
-/* interrupt mask */
-#define GELIC_NET_TXINT                   (1L << (GELIC_NET_GDTDCEINT + 32))
-
-#define GELIC_NET_RXINT0                  (1L << (GELIC_NET_GRFANMINT + 32))
-#define GELIC_NET_RXINT1                  (1L << GELIC_NET_GDADCEINT)
-#define GELIC_NET_RXINT                   (GELIC_NET_RXINT0 | GELIC_NET_RXINT1)
-
- /* descriptor data_status bits */
-#define GELIC_NET_RXIPCHK                 29
-#define GELIC_NET_TCPUDPIPCHK             28
-#define GELIC_NET_DATA_STATUS_CHK_MASK    (1 << GELIC_NET_RXIPCHK | \
-                                           1 << GELIC_NET_TCPUDPIPCHK)
-
-/* descriptor data_error bits */
-#define GELIC_NET_RXIPCHKERR              27
-#define GELIC_NET_RXTCPCHKERR             26
-#define GELIC_NET_DATA_ERROR_CHK_MASK     (1 << GELIC_NET_RXIPCHKERR | \
-                                           1 << GELIC_NET_RXTCPCHKERR)
-
-#define GELIC_NET_DMAC_CMDSTAT_NOCS       0xa0080000 /* middle of frame */
-#define GELIC_NET_DMAC_CMDSTAT_TCPCS      0xa00a0000
-#define GELIC_NET_DMAC_CMDSTAT_UDPCS      0xa00b0000
-#define GELIC_NET_DMAC_CMDSTAT_END_FRAME  0x00040000 /* end of frame */
-
-#define GELIC_NET_DMAC_CMDSTAT_CHAIN_END  0x00000002 /* RXDCEIS:DMA stopped */
-
-#define GELIC_NET_DESCR_IND_PROC_SHIFT    28
-#define GELIC_NET_DESCR_IND_PROC_MASKO    0x0fffffff
-
-/* ignore ipsec ans multicast */
-#define GELIC_NET_DATA_ERROR_MASK         0xfdefbfff
-/* ignore unmatched sp on sp, drop_packet, multicast address frame*/
-#define GELIC_NET_DATA_ERROR_FLG          0x7def8000
-
-enum gelic_net_descr_status {
-	GELIC_NET_DESCR_COMPLETE            = 0x00, /* used in rx and tx */
-	GELIC_NET_DESCR_RESPONSE_ERROR      = 0x01, /* used in rx and tx */
-	GELIC_NET_DESCR_PROTECTION_ERROR    = 0x02, /* used in rx and tx */
-	GELIC_NET_DESCR_FRAME_END           = 0x04, /* used in rx */
-	GELIC_NET_DESCR_FORCE_END           = 0x05, /* used in rx and tx */
-	GELIC_NET_DESCR_CARDOWNED           = 0x0a, /* used in rx and tx */
-	GELIC_NET_DESCR_NOT_IN_USE                  /* any other value */
-};
-#define GELIC_NET_DMAC_CMDSTAT_NOT_IN_USE 0xb0000000
-
-#define GELIC_NET_DESCR_SIZE              32
-struct gelic_net_descr {
-	/* as defined by the hardware */
-	uint32_t buf_addr;
-	uint32_t buf_size;
-	uint32_t next_descr_addr;
-	uint32_t dmac_cmd_status;
-	uint32_t result_size;
-	uint32_t valid_size;	/* all zeroes for tx */
-	uint32_t data_status;
-	uint32_t data_error;	/* all zeroes for tx */
-
-	/* used in the driver */
-	struct sk_buff *skb;
-	dma_addr_t bus_addr;
-	struct gelic_net_descr *next;
-	struct gelic_net_descr *prev;
-	struct vlan_ethhdr vlan;
-} __attribute__((aligned(32)));
-
-struct gelic_net_descr_chain {
-	/* we walk from tail to head */
-	struct gelic_net_descr *head;
-	struct gelic_net_descr *tail;
-	spinlock_t lock;
-};
-
-struct gelic_net_card {
-	struct net_device *netdev;
-	uint64_t ghiintmask;
-	struct ps3_system_bus_device *dev;
-	uint32_t vlan_id[GELIC_NET_VLAN_MAX];
-	int vlan_index;
-
-	struct gelic_net_descr_chain tx_chain;
-	struct gelic_net_descr_chain rx_chain;
-	spinlock_t chain_lock;
-
-	struct net_device_stats netdev_stats;
-	int rx_csum;
-	spinlock_t intmask_lock;
-
-	struct work_struct tx_timeout_task;
-	atomic_t tx_timeout_task_counter;
-	wait_queue_head_t waitq;
-
-	struct gelic_net_descr *tx_top, *rx_top;
-
-	struct gelic_net_descr descr[0];
-};
+#define GELIC_NET_DRV_NAME "Gelic Network Driver"
+#define GELIC_NET_DRV_VERSION "1.0"
 
 static int ps3_gelic_param = 1; /* vlan desc support */
 #ifdef CONFIG_GELIC_NET_MODULE
@@ -210,33 +78,6 @@ static uint64_t gelic_irq_status;
 
 static int dmac_status = 0;
 
[...2575 lines suppressed...]
+#define MAX_SCAN_BSS			16
+
+#define GELICW_SCAN_INTERVAL		(HZ)
+
+#ifdef DEBUG
+#define CH_INFO_FAIL 0x0600 /* debug */
+#else
+#define CH_INFO_FAIL 0
+#endif
+
+struct gelicw_bss {
+	u8 bssid[ETH_ALEN];
+	u8 channel;
+	u8 mode;
+	u8 essid_len;
+	u8 essid[IW_ESSID_MAX_SIZE + 1]; /* null terminated for debug msg */
+
+	u16 capability;
+	u16 beacon_interval;
+
+	u8 rates_len;
+	u8 rates[MAX_RATES_LENGTH];
+	u8 rates_ex_len;
+	u8 rates_ex[MAX_RATES_EX_LENGTH];
+	u8 rssi;
+
+	/* scan results have sec_info instead of rsn_ie or wpa_ie */
+	u16 sec_info;
+};
+
+struct gelic_wireless {
+	struct gelic_net_card *card;
+	struct completion cmd_done, rssi_done;
+	struct work_struct work_event, work_start_done;
+	struct delayed_work work_rssi, work_scan_all, work_scan_essid;
+	struct delayed_work work_common, work_encode;
+	struct delayed_work work_start, work_stop, work_roam;
+	wait_queue_head_t waitq_cmd, waitq_scan;
+
+	u64 cmd_tag, cmd_id;
+	u8 cmd_send_flg;
+
+	struct iw_public_data wireless_data;
+	u8 *data_buf; /* data buffer for lv1_net_control */
+
+	u8 wireless; /* wireless support */
+	u8 state;
+	u8 scan_all; /* essid scan or all scan */
+	u8 essid_search; /* essid background scan */
+	u8 is_assoc;
+
+	u16 ch_info; /* supoprted channels */
+	u8 wireless_mode; /* 11b/g */
+	u8 channel; /* current ch */
+	u8 iw_mode; /* INFRA or Ad-hoc */
+	u8 rssi;
+	u8 essid_len;
+	u8 essid[IW_ESSID_MAX_SIZE + 1]; /* null terminated for debug msg */
+	u8 nick[IW_ESSID_MAX_SIZE + 1];
+	u8 bssid[ETH_ALEN];
+
+	u8 key_index;
+	u8 key[WEP_KEYS][IW_ENCODING_TOKEN_MAX]; /* 4 * 64byte */
+	u8 key_len[WEP_KEYS];
+	u8 key_alg; /* key algorithm  */
+	u8 auth_mode; /* authenticaton mode */
+
+	u8 bss_index; /* current bss in bss_list */
+	u8 num_bss_list;
+	u8 bss_key_alg; /* key alg of bss */
+	u8 wap_bssid[ETH_ALEN];
+	unsigned long last_scan; /* last scan time */
+	struct gelicw_bss current_bss;
+	struct gelicw_bss bss_list[MAX_SCAN_BSS];
+};
+
+/* net_control command */
+#define GELICW_SET_PORT			3 /* control Ether port */
+#define GELICW_GET_INFO			6 /* get supported channels */
+#define GELICW_SET_CMD			9 /* set configuration */
+#define GELICW_GET_RES			10 /* get command response */
+#define GELICW_GET_EVENT		11 /* get event from device */
+/* net_control command data buffer */
+#define GELICW_DATA_BUF_SIZE		0x1000
+
+/* GELICW_SET_CMD params */
+#define GELICW_CMD_START		1
+#define GELICW_CMD_STOP			2
+#define GELICW_CMD_SCAN			3
+#define GELICW_CMD_GET_SCAN		4
+#define GELICW_CMD_SET_CONFIG		5
+#define GELICW_CMD_GET_CONFIG		6
+#define GELICW_CMD_SET_WEP		7
+#define GELICW_CMD_GET_WEP		8
+#define GELICW_CMD_SET_WPA		9
+#define GELICW_CMD_GET_WPA		10
+#define GELICW_CMD_GET_RSSI		11
+
+/* GELICW_SET_PORT params */
+#define GELICW_ETHER_PORT		2
+#define GELICW_PORT_DOWN		0 /* Ether port off */
+#define GELICW_PORT_UP			4 /* Ether port on (auto neg) */
+
+/* interrupt status bit */
+#define GELICW_DEVICE_CMD_COMP		0x0000000080000000UL
+#define GELICW_DEVICE_EVENT_RECV	0x0000000040000000UL
+
+/* GELICW_GET_EVENT ID */
+#define GELICW_EVENT_UNKNOWN		0x00
+#define GELICW_EVENT_DEVICE_READY	0x01
+#define GELICW_EVENT_SCAN_COMPLETED	0x02
+#define GELICW_EVENT_DEAUTH		0x04
+#define GELICW_EVENT_BEACON_LOST	0x08
+#define GELICW_EVENT_CONNECTED		0x10
+#define GELICW_EVENT_WPA_CONNECTED	0x20
+#define GELICW_EVENT_WPA_ERROR		0x40
+#define GELICW_EVENT_NO_ENTRY		(-6)
+
+#define MAX_IW_PRIV_SIZE		32
+
+/* structure of data buffer for lv1_net_contol */
+/* wep_config: sec */
+#define GELICW_WEP_SEC_NONE		0
+#define GELICW_WEP_SEC_40BIT		1
+#define GELICW_WEP_SEC_104BIT		2
+struct wep_config {
+	u16 sec;
+	u8  key[4][16];
+} __attribute__ ((packed));
+
+/* wpa_config: sec */
+#define GELICW_WPA_SEC_NONE		0
+#define GELICW_WPA_SEC_TKIP		1
+#define GELICW_WPA_SEC_AES		2
+/* wpa_config: psk_type */
+#define GELICW_PSK_PASSPHRASE		0
+#define GELICW_PSK_64HEX		1
+struct wpa_config {
+	u16 sec;
+	u16 psk_type;
+	u8  psk_material[64]; /* key */
+} __attribute__ ((packed));
+
+/* common_config: bss_type */
+#define GELICW_BSS_INFRA		0
+#define GELICW_BSS_ADHOC		1
+/* common_config: auth_method */
+#define GELICW_AUTH_OPEN		0
+#define GELICW_AUTH_SHARED		1
+/* common_config: op_mode */
+#define GELICW_OP_MODE_11BG		0
+#define GELICW_OP_MODE_11B		1
+#define GELICW_OP_MODE_11G		2
+struct common_config {
+	u16 scan_index; /* index of scan_desc list */
+	u16 bss_type;
+	u16 auth_method;
+	u16 op_mode;
+} __attribute__ ((packed));
+
+/* scan_descriptor: security */
+#define GELICW_SEC_TYPE_NONE		0x0000
+#define GELICW_SEC_TYPE_WEP		0x0100
+#define GELICW_SEC_TYPE_WEP40		0x0101
+#define GELICW_SEC_TYPE_WEP104		0x0102
+#define GELICW_SEC_TYPE_TKIP		0x0201
+#define GELICW_SEC_TYPE_AES		0x0202
+#define GELICW_SEC_TYPE_WEP_MASK	0xFF00
+struct scan_desc {
+	u16 size;
+	u16 rssi;
+	u16 channel;
+	u16 beacon_period;
+	u16 capability;
+	u16 security;
+	u64 bssid;
+	u8  essid[32];
+	u8  rate[16];
+	u8  ext_rate[16];
+	u32 reserved1;
+	u32 reserved2;
+	u32 reserved3;
+	u32 reserved4;
+} __attribute__ ((packed));
+
+/* rssi_descriptor */
+struct rssi_desc {
+	u16 rssi; /* max rssi = 100 */
+} __attribute__ ((packed));
+
+
+extern unsigned long p_to_lp(long pa);
+extern int gelicw_setup_netdev(struct net_device *netdev, int wi);
+extern void gelicw_up(struct net_device *netdev);
+extern int gelicw_down(struct net_device *netdev);
+extern void gelicw_remove(struct net_device *netdev);
+extern void gelicw_interrupt(struct net_device *netdev, u32 status1);
+extern int gelicw_is_associated(struct net_device *netdev);
+
+#endif //  _GELIC_WIRELESS_H_

linux-2.6-ps3-gelic.patch:

--- NEW FILE linux-2.6-ps3-gelic.patch ---
As of 2007-05-04 (commit 197a8b29cbb721909e1bde44c6e7a588d93ba440):

ps3-wip/ps3-gelic.patch
ps3-wip/ps3-gelic-2.6.21-version-up.diff
ps3-wip/ps3-gelic-system-bus.patch
ps3-wip/ps3-gelic-fix-ipv6.diff

+ s/ip_hdr(skb)/skb->nh.iph/ to work on 2.6.21

diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index dcdad21..7876697 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2260,6 +2260,16 @@ config TSI108_ETH
 	     To compile this driver as a module, choose M here: the module
 	     will be called tsi108_eth.
 
+config GELIC_NET
+	tristate "PS3 Gigabit Ethernet driver"
+	depends on PPC_PS3
+	help
+	  This driver supports the Gigabit Ethernet device on the
+	  PS3 game console.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called gelic_net.
+
 config GIANFAR
 	tristate "Gianfar Ethernet"
 	depends on 85xx || 83xx || PPC_86xx
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 59c0459..9fa106a 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -60,6 +60,7 @@ obj-$(CONFIG_TIGON3) += tg3.o
 obj-$(CONFIG_BNX2) += bnx2.o
 spidernet-y += spider_net.o spider_net_ethtool.o
 obj-$(CONFIG_SPIDER_NET) += spidernet.o sungem_phy.o
+obj-$(CONFIG_GELIC_NET) += gelic_net.o
 obj-$(CONFIG_TC35815) += tc35815.o
 obj-$(CONFIG_SKGE) += skge.o
 obj-$(CONFIG_SKY2) += sky2.o
--- /dev/null	2007-05-01 15:16:24.100521312 +0100
+++ b/drivers/net/gelic_net.c	2007-05-04 11:35:42.000000000 +0100
@@ -0,0 +1,1919 @@
+/*
+ *  PS3 Platfom gelic network driver.
+ *
+ * Copyright (C) 2006 Sony Computer Entertainment Inc.
+ *
+ *  this file is based on: spider_net.c
+ *
+ * Network device driver for Cell Processor-Based Blade
+ *
+ * (C) Copyright IBM Corp. 2005
+ *
+ * Authors : Utz Bacher <utz bacher de ibm com>
+ *           Jens Osterkamp <Jens Osterkamp de ibm com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#define DEBUG 1
+
+#include <linux/compiler.h>
+#include <linux/crc32.h>
+#include <linux/delay.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/firmware.h>
+#include <linux/if_vlan.h>
+#include <linux/in.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/ip.h>
+#include <linux/kernel.h>
+#include <linux/mii.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/device.h>
+#include <linux/pci.h>
+#include <linux/skbuff.h>
+#include <linux/slab.h>
+#include <linux/tcp.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <linux/workqueue.h>
+#include <asm/bitops.h>
+#include <asm/pci-bridge.h>
+#include <net/checksum.h>
+#include <asm/io.h>
+#include <asm/firmware.h>
+#include <asm/ps3.h>
+#include <asm/lv1call.h>
+
+#define GELIC_NET_DRV_NAME "Gelic Network Driver"
+#define GELIC_NET_DRV_VERSION "1.0"
+
+#define GELIC_NET_DEBUG
+
+#ifdef GELIC_NET_DEBUG
+#define DPRINTK(fmt,arg...)   printk(KERN_ERR fmt ,##arg)
+#define DPRINTKK(fmt,arg...)  printk(KERN_ERR fmt ,##arg)
+#else
+#define DPRINTK(fmt,arg...)
+#define DPRINTKK(fmt,arg...)
+#endif
+
+#define GELIC_NET_ETHTOOL               /* use ethtool */
+
+/* ioctl */
+#define GELIC_NET_GET_MODE              (SIOCDEVPRIVATE + 0)
+#define GELIC_NET_SET_MODE              (SIOCDEVPRIVATE + 1)
+
+/* descriptors */
+#define GELIC_NET_RX_DESCRIPTORS        128 /* num of descriptors */
+#define GELIC_NET_TX_DESCRIPTORS        128 /* num of descriptors */
+
+#define GELIC_NET_MAX_MTU               2308
+#define GELIC_NET_MIN_MTU               64
+#define GELIC_NET_RXBUF_ALIGN           128
+#define GELIC_NET_RX_CSUM_DEFAULT       1 /* hw chksum */
+#define GELIC_NET_WATCHDOG_TIMEOUT      5*HZ
+#define GELIC_NET_NAPI_WEIGHT           64
+#define GELIC_NET_BROADCAST_ADDR        0xffffffffffff
+#define GELIC_NET_VLAN_POS              (VLAN_ETH_ALEN * 2)
+#define GELIC_NET_VLAN_MAX              4
+#define GELIC_NET_MC_COUNT_MAX          32 /* multicast address list */
+
+enum gelic_net_int0_status {
+	GELIC_NET_GDTDCEINT  = 24,
+	GELIC_NET_GRFANMINT  = 28,
+};
+
+/* GHIINT1STS bits */
+enum gelic_net_int1_status {
+	GELIC_NET_GDADCEINT = 14,
+};
+
+/* interrupt mask */
+#define GELIC_NET_TXINT                   (1L << (GELIC_NET_GDTDCEINT + 32))
+
+#define GELIC_NET_RXINT0                  (1L << (GELIC_NET_GRFANMINT + 32))
+#define GELIC_NET_RXINT1                  (1L << GELIC_NET_GDADCEINT)
+#define GELIC_NET_RXINT                   (GELIC_NET_RXINT0 | GELIC_NET_RXINT1)
+
+ /* descriptor data_status bits */
+#define GELIC_NET_RXIPCHK                 29
+#define GELIC_NET_TCPUDPIPCHK             28
+#define GELIC_NET_DATA_STATUS_CHK_MASK    (1 << GELIC_NET_RXIPCHK | \
+                                           1 << GELIC_NET_TCPUDPIPCHK)
+
+/* descriptor data_error bits */
+#define GELIC_NET_RXIPCHKERR              27
+#define GELIC_NET_RXTCPCHKERR             26
+#define GELIC_NET_DATA_ERROR_CHK_MASK     (1 << GELIC_NET_RXIPCHKERR | \
+                                           1 << GELIC_NET_RXTCPCHKERR)
+
+#define GELIC_NET_DMAC_CMDSTAT_NOCS       0xa0080000 /* middle of frame */
+#define GELIC_NET_DMAC_CMDSTAT_TCPCS      0xa00a0000
+#define GELIC_NET_DMAC_CMDSTAT_UDPCS      0xa00b0000
+#define GELIC_NET_DMAC_CMDSTAT_END_FRAME  0x00040000 /* end of frame */
+
+#define GELIC_NET_DMAC_CMDSTAT_CHAIN_END  0x00000002 /* RXDCEIS:DMA stopped */
+
+#define GELIC_NET_DESCR_IND_PROC_SHIFT    28
+#define GELIC_NET_DESCR_IND_PROC_MASKO    0x0fffffff
+
+/* ignore ipsec ans multicast */
+#define GELIC_NET_DATA_ERROR_MASK         0xfdefbfff
+/* ignore unmatched sp on sp, drop_packet, multicast address frame*/
+#define GELIC_NET_DATA_ERROR_FLG          0x7def8000
+
+enum gelic_net_descr_status {
+	GELIC_NET_DESCR_COMPLETE            = 0x00, /* used in rx and tx */
+	GELIC_NET_DESCR_RESPONSE_ERROR      = 0x01, /* used in rx and tx */
+	GELIC_NET_DESCR_PROTECTION_ERROR    = 0x02, /* used in rx and tx */
+	GELIC_NET_DESCR_FRAME_END           = 0x04, /* used in rx */
+	GELIC_NET_DESCR_FORCE_END           = 0x05, /* used in rx and tx */
+	GELIC_NET_DESCR_CARDOWNED           = 0x0a, /* used in rx and tx */
+	GELIC_NET_DESCR_NOT_IN_USE                  /* any other value */
+};
+#define GELIC_NET_DMAC_CMDSTAT_NOT_IN_USE 0xb0000000
+
+#define GELIC_NET_DESCR_SIZE              32
+struct gelic_net_descr {
+	/* as defined by the hardware */
+	uint32_t buf_addr;
+	uint32_t buf_size;
+	uint32_t next_descr_addr;
+	uint32_t dmac_cmd_status;
+	uint32_t result_size;
+	uint32_t valid_size;	/* all zeroes for tx */
+	uint32_t data_status;
+	uint32_t data_error;	/* all zeroes for tx */
+
+	/* used in the driver */
+	struct sk_buff *skb;
+	dma_addr_t bus_addr;
+	struct gelic_net_descr *next;
+	struct gelic_net_descr *prev;
+	struct vlan_ethhdr vlan;
+} __attribute__((aligned(32)));
+
+struct gelic_net_descr_chain {
+	/* we walk from tail to head */
+	struct gelic_net_descr *head;
+	struct gelic_net_descr *tail;
+	spinlock_t lock;
+};
+
+struct gelic_net_card {
+	struct net_device *netdev;
+	uint64_t ghiintmask;
+	struct ps3_system_bus_device *dev;
+	uint32_t vlan_id[GELIC_NET_VLAN_MAX];
+	int vlan_index;
+
+	struct gelic_net_descr_chain tx_chain;
+	struct gelic_net_descr_chain rx_chain;
+	spinlock_t chain_lock;
+
+	struct net_device_stats netdev_stats;
+	int rx_csum;
+	spinlock_t intmask_lock;
+
+	struct work_struct tx_timeout_task;
+	atomic_t tx_timeout_task_counter;
+	wait_queue_head_t waitq;
+
+	struct gelic_net_descr *tx_top, *rx_top;
+
+	struct gelic_net_descr descr[0];
+};
+
+static int ps3_gelic_param = 1; /* vlan desc support */
+#ifdef CONFIG_GELIC_NET_MODULE
+module_param(ps3_gelic_param, int, S_IRUGO);
+#endif
+
+struct gelic_net_card *gcard;
+static uint64_t gelic_irq_status;
+
+static int dmac_status = 0;
+
+/* for lv1_net_control */
+#define GELIC_NET_GET_MAC_ADDRESS               0x0000000000000001
+#define GELIC_NET_GET_ETH_PORT_STATUS           0x0000000000000002
+#define GELIC_NET_SET_NEGOTIATION_MODE          0x0000000000000003
+#define GELIC_NET_GET_VLAN_ID                   0x0000000000000004
+
+#define GELIC_NET_LINK_UP                       0x0000000000000001
+#define GELIC_NET_FULL_DUPLEX                   0x0000000000000002
+#define GELIC_NET_AUTO_NEG                      0x0000000000000004
+#define GELIC_NET_SPEED_10                      0x0000000000000010
+#define GELIC_NET_SPEED_100                     0x0000000000000020
+#define GELIC_NET_SPEED_1000                    0x0000000000000040
+
+#define GELIC_NET_VLAN_ALL                      0x0000000000000001
+#define GELIC_NET_VLAN_WIRED                    0x0000000000000002
+#define GELIC_NET_VLAN_WIRELESS                 0x0000000000000003
+#define GELIC_NET_VLAN_PSP                      0x0000000000000004
+#define GELIC_NET_VLAN_PORT0                    0x0000000000000010
+#define GELIC_NET_VLAN_PORT1                    0x0000000000000011
+#define GELIC_NET_VLAN_PORT2                    0x0000000000000012
+#define GELIC_NET_VLAN_DAEMON_CLIENT_BSS        0x0000000000000013
+#define GELIC_NET_VLAN_LIBERO_CLIENT_BSS        0x0000000000000014
+#define GELIC_NET_VLAN_NO_ENTRY                 -6
+
+#define GELIC_NET_PORT                          2 /* for port status */
+
+
+MODULE_AUTHOR("SCE Inc.");
+MODULE_DESCRIPTION("Gelic Network driver");
+MODULE_LICENSE("GPL");
+
+static int rx_descriptors = GELIC_NET_RX_DESCRIPTORS;
+static int tx_descriptors = GELIC_NET_TX_DESCRIPTORS;
+
+
+/* set irq_mask */
+static int
+gelic_net_set_irq_mask(struct gelic_net_card *card, uint64_t mask)
+{
+	uint64_t status = 0;
+
+	status = lv1_net_set_interrupt_mask(card->dev->did.bus_id,
+		card->dev->did.dev_id, mask, 0);
+	if (status) {
+		printk("lv1_net_set_interrupt_mask failed, status=%ld\n",
+			status);
+	}
+	return status;
+}
+
+/**
+ * gelic_net_get_descr_status -- returns the status of a descriptor
+ * @descr: descriptor to look at
+ *
+ * returns the status as in the dmac_cmd_status field of the descriptor
+ */
+enum gelic_net_descr_status
+gelic_net_get_descr_status(struct gelic_net_descr *descr)
+{
+	uint32_t cmd_status;
+
+	rmb();
+	cmd_status = descr->dmac_cmd_status;
+	rmb();
+	cmd_status >>= GELIC_NET_DESCR_IND_PROC_SHIFT;
+	return cmd_status;
+}
+
+/**
+ * gelic_net_set_descr_status -- sets the status of a descriptor
+ * @descr: descriptor to change
+ * @status: status to set in the descriptor
+ *
+ * changes the status to the specified value. Doesn't change other bits
+ * in the status
+ */
+static void
+gelic_net_set_descr_status(struct gelic_net_descr *descr,
+			    enum gelic_net_descr_status status)
+{
+	uint32_t cmd_status;
+
+	/* read the status */
+	mb();
+	cmd_status = descr->dmac_cmd_status;
+	/* clean the upper 4 bits */
+	cmd_status &= GELIC_NET_DESCR_IND_PROC_MASKO;
+	/* add the status to it */
+	cmd_status |= ((uint32_t)status)<<GELIC_NET_DESCR_IND_PROC_SHIFT;
+	/* and write it back */
+	descr->dmac_cmd_status = cmd_status;
+	wmb();
+}
+
+/**
+ * gelic_net_free_chain - free descriptor chain
+ * @card: card structure
+ * @descr_in: address of desc
+ */
+static void
+gelic_net_free_chain(struct gelic_net_card *card,
+		      struct gelic_net_descr *descr_in)
+{
+	struct gelic_net_descr *descr;
+
+	for (descr = descr_in; descr && !descr->bus_addr; descr = descr->next) {
+		dma_unmap_single(&card->dev->core, descr->bus_addr,
+				 GELIC_NET_DESCR_SIZE, PCI_DMA_BIDIRECTIONAL);
+		descr->bus_addr = 0;
+	}
+}
+
+/**
+ * gelic_net_init_chain - links descriptor chain
+ * @card: card structure
+ * @chain: address of chain
+ * @start_descr: address of descriptor array
+ * @no: number of descriptors
+ *
+ * we manage a circular list that mirrors the hardware structure,
+ * except that the hardware uses bus addresses.
+ *
+ * returns 0 on success, <0 on failure
+ */
+static int
+gelic_net_init_chain(struct gelic_net_card *card,
+		       struct gelic_net_descr_chain *chain,
+		       struct gelic_net_descr *start_descr, int no)
+{
+	int i;
+	struct gelic_net_descr *descr;
+
+	spin_lock_init(&chain->lock);
+	descr = start_descr;
+	memset(descr, 0, sizeof(*descr) * no);
+
+	/* set up the hardware pointers in each descriptor */
+	for (i=0; i<no; i++, descr++) {
+		gelic_net_set_descr_status(descr, GELIC_NET_DESCR_NOT_IN_USE);
+		descr->bus_addr =
+			dma_map_single(&card->dev->core, descr,
+				       GELIC_NET_DESCR_SIZE,
+				       PCI_DMA_BIDIRECTIONAL);
+
+		if (descr->bus_addr == DMA_ERROR_CODE)
+			goto iommu_error;
+
+		descr->next = descr + 1;
+		descr->prev = descr - 1;
+	}
+	/* do actual chain list */
+	(descr-1)->next = start_descr;
+	start_descr->prev = (descr-1);
+
+	descr = start_descr;
+	for (i=0; i < no; i++, descr++) {
+		if (descr->next) {
+			descr->next_descr_addr = descr->next->bus_addr;
+		} else {
+			descr->next_descr_addr = 0;
+		}
+	}
+
+	chain->head = start_descr;
+	chain->tail = start_descr;
+	(descr-1)->next_descr_addr = 0; /* last descr */
+	return 0;
+
+iommu_error:
+	descr = start_descr;
+	for (i=0; i < no; i++, descr++)
+		if (descr->bus_addr)
+			dma_unmap_single(&card->dev->core, descr->bus_addr,
+					 GELIC_NET_DESCR_SIZE,
+					 PCI_DMA_BIDIRECTIONAL);
+	return -ENOMEM;
+}
+
+/**
+ * gelic_net_prepare_rx_descr - reinitializes a rx descriptor
+ * @card: card structure
+ * @descr: descriptor to re-init
+ *
+ * return 0 on succes, <0 on failure
+ *
+ * allocates a new rx skb, iommu-maps it and attaches it to the descriptor.
+ * Activate the descriptor state-wise
+ */
+static int
+gelic_net_prepare_rx_descr(struct gelic_net_card *card,
+			    struct gelic_net_descr *descr)
+{
+	dma_addr_t buf;
+	int error = 0;
+	int offset;
+	int bufsize;
+
+	if( gelic_net_get_descr_status(descr) !=  GELIC_NET_DESCR_NOT_IN_USE) {
+		printk("%s: ERROR status \n", __FUNCTION__);
+	}
+	/* we need to round up the buffer size to a multiple of 128 */
+	bufsize = (GELIC_NET_MAX_MTU + GELIC_NET_RXBUF_ALIGN - 1) &
+		(~(GELIC_NET_RXBUF_ALIGN - 1));
+
+	/* and we need to have it 128 byte aligned, therefore we allocate a
+	 * bit more */
+	/* allocate an skb */
+	descr->skb = dev_alloc_skb(bufsize + GELIC_NET_RXBUF_ALIGN - 1);
+	if (!descr->skb) {
+		if (net_ratelimit())
+			printk("Not enough memory to allocate rx buffer\n");
+		return -ENOMEM;
+	}
+	descr->buf_size = bufsize;
+	descr->dmac_cmd_status = 0;
+	descr->result_size = 0;
+	descr->valid_size = 0;
+	descr->data_error = 0;
+
+	offset = ((unsigned long)descr->skb->data) &
+		(GELIC_NET_RXBUF_ALIGN - 1);
+	if (offset)
+		skb_reserve(descr->skb, GELIC_NET_RXBUF_ALIGN - offset);
+	/* io-mmu-map the skb */
+	buf = dma_map_single(&card->dev->core, descr->skb->data,
+					GELIC_NET_MAX_MTU,
+					PCI_DMA_BIDIRECTIONAL);
+	descr->buf_addr = buf;
+	if (buf == DMA_ERROR_CODE) {
+		dev_kfree_skb_any(descr->skb);
+		printk("Could not iommu-map rx buffer\n");
+		gelic_net_set_descr_status(descr, GELIC_NET_DESCR_NOT_IN_USE);
+	} else {
+		gelic_net_set_descr_status(descr, GELIC_NET_DESCR_CARDOWNED);
+	}
+
+	return error;
+}
+
+/**
+ * gelic_net_release_rx_chain - free all rx descr
+ * @card: card structure
+ *
+ */
+static void
+gelic_net_release_rx_chain(struct gelic_net_card *card)
+{
+	struct gelic_net_descr_chain *chain = &card->rx_chain;
+
+	while(chain->tail != chain->head) {
+		if (chain->tail->skb) {
+			dma_unmap_single(&card->dev->core,
+						chain->tail->buf_addr,
+						chain->tail->skb->len,
+						PCI_DMA_BIDIRECTIONAL);
+			chain->tail->buf_addr = 0;
+			dev_kfree_skb_any(chain->tail->skb);
+			chain->tail->skb = NULL;
+			chain->tail->dmac_cmd_status =
+						GELIC_NET_DESCR_NOT_IN_USE;
+			chain->tail = chain->tail->next;
+		}
+	}
+}
+
+/**
+ * gelic_net_enable_rxdmac - enables a receive DMA controller
+ * @card: card structure
+ *
+ * gelic_net_enable_rxdmac enables the DMA controller by setting RX_DMA_EN
+ * in the GDADMACCNTR register
+ */
+static void
+gelic_net_enable_rxdmac(struct gelic_net_card *card)
+{
+	uint64_t status;
+
+	status = lv1_net_start_rx_dma(card->dev->did.bus_id,
+				card->dev->did.dev_id,
+				(uint64_t)card->rx_chain.tail->bus_addr, 0);
+	if (status) {
+		printk("lv1_net_start_rx_dma failed, status=%ld\n", status);
+	}
+}
+
+/**
+ * gelic_net_refill_rx_chain - refills descriptors/skbs in the rx chains
+ * @card: card structure
+ *
+ * refills descriptors in all chains (last used chain first): allocates skbs
+ * and iommu-maps them.
+ */
+static void
+gelic_net_refill_rx_chain(struct gelic_net_card *card)
+{
+	struct gelic_net_descr_chain *chain;
+	int count = 0;
+
+	chain = &card->rx_chain;
+	while (chain->head && gelic_net_get_descr_status(chain->head) ==
+		GELIC_NET_DESCR_NOT_IN_USE) {
+		if (gelic_net_prepare_rx_descr(card, chain->head))
+			break;
+		count++;
+		chain->head = chain->head->next;
+	}
+}
+
+/**
+ * gelic_net_alloc_rx_skbs - allocates rx skbs in rx descriptor chains
+ * @card: card structure
+ *
+ * returns 0 on success, <0 on failure
+ */
+static int
+gelic_net_alloc_rx_skbs(struct gelic_net_card *card)
+{
+	struct gelic_net_descr_chain *chain;
+
+	chain = &card->rx_chain;
+	gelic_net_refill_rx_chain(card);
+	chain->head = card->rx_top->prev; /* point to the last */
+	return 0;
+}
+
+/**
+ * gelic_net_release_tx_descr - processes a used tx descriptor
+ * @card: card structure
+ * @descr: descriptor to release
+ *
+ * releases a used tx descriptor (unmapping, freeing of skb)
+ */
+static void
+gelic_net_release_tx_descr(struct gelic_net_card *card,
+			    struct gelic_net_descr *descr)
+{
+	struct sk_buff *skb;
+
+  if (!ps3_gelic_param) {
+	/* unmap the skb */
+	skb = descr->skb;
+	dma_unmap_single(&card->dev->core, descr->buf_addr, skb->len,
+			 PCI_DMA_BIDIRECTIONAL);
+
+	dev_kfree_skb_any(skb);
+  } else {
+	if ((descr->data_status & 0x00000001) == 1) { /* end of frame */
+		skb = descr->skb;
+		dma_unmap_single(&card->dev->core, descr->buf_addr, skb->len,
+			 PCI_DMA_BIDIRECTIONAL);
+		dev_kfree_skb_any(skb);
+	} else {
+		dma_unmap_single(&card->dev->core, descr->buf_addr,
+			descr->buf_size, PCI_DMA_BIDIRECTIONAL);
+	}
+  }
+	descr->buf_addr = 0;
+	descr->buf_size = 0;
+	descr->next_descr_addr = 0;
+	descr->result_size = 0;
+	descr->valid_size = 0;
+	descr->data_status = 0;
+	descr->data_error = 0;
+	descr->skb = NULL;
+	card->tx_chain.tail = card->tx_chain.tail->next;
+
+	/* set descr status */
+	descr->dmac_cmd_status = GELIC_NET_DMAC_CMDSTAT_NOT_IN_USE;
+}
+
+/**
+ * gelic_net_release_tx_chain - processes sent tx descriptors
+ * @card: adapter structure
+ * @stop: net_stop sequence
+ *
+ * releases the tx descriptors that gelic has finished with
+ */
+static void
+gelic_net_release_tx_chain(struct gelic_net_card *card, int stop)
+{
+	struct gelic_net_descr_chain *tx_chain = &card->tx_chain;
+	enum gelic_net_descr_status status;
+	int release = 0;
+
+	for (;tx_chain->head != tx_chain->tail && tx_chain->tail;) {
+		status = gelic_net_get_descr_status(tx_chain->tail);
+		switch (status) {
+		case GELIC_NET_DESCR_RESPONSE_ERROR:
+		case GELIC_NET_DESCR_PROTECTION_ERROR:
+		case GELIC_NET_DESCR_FORCE_END:
+			printk("%s: forcing end of tx descriptor "
+			       "with status x%02x\n",
+			       card->netdev->name, status);
+			card->netdev_stats.tx_dropped++;
+			break;
+
+		case GELIC_NET_DESCR_COMPLETE:
+			card->netdev_stats.tx_packets++;
+			card->netdev_stats.tx_bytes +=
+				tx_chain->tail->skb->len;
+			break;
+
+		case GELIC_NET_DESCR_CARDOWNED:
+		default: /* any other value (== GELIC_NET_DESCR_NOT_IN_USE) */
+			goto out;
+		}
+		gelic_net_release_tx_descr(card, tx_chain->tail);
+		release = 1;
+	}
+out:
+	/* status NOT_IN_USE or chain end */
+	if (!tx_chain->tail) {
+		/* release all chains */
+		if(card->tx_chain.head) printk("ERROR tx_chain.head is NULL\n");
+		card->tx_chain.tail = card->tx_top;
+		card->tx_chain.head = card->tx_top;
+	}
+	if (!stop && release && netif_queue_stopped(card->netdev)) {
+		netif_wake_queue(card->netdev);
+	}
+}
+
+/**
+ * gelic_net_set_multi - sets multicast addresses and promisc flags
+ * @netdev: interface device structure
+ *
+ * gelic_net_set_multi configures multicast addresses as needed for the
+ * netdev interface. It also sets up multicast, allmulti and promisc
+ * flags appropriately
+ */
+static void
+gelic_net_set_multi(struct net_device *netdev)
+{
+	int i;
+	uint8_t *p;
+	uint64_t addr, status;
+	struct dev_mc_list *mc;
+	struct gelic_net_card *card = netdev_priv(netdev);
+
+	/* clear all multicast address */
+	status = lv1_net_remove_multicast_address(card->dev->did.bus_id,
+				card->dev->did.dev_id, 0, 1);
+	if (status) {
+		printk("lv1_net_remove_multicast_address failed, status=%ld\n",\
+			status);
+	}
+	/* set broadcast address */
+	status = lv1_net_add_multicast_address(card->dev->did.bus_id,
+			card->dev->did.dev_id, GELIC_NET_BROADCAST_ADDR, 0);
+	if (status) {
+		printk("lv1_net_add_multicast_address failed, status=%ld\n",\
+			status);
+	}
+
+	if (netdev->flags & IFF_ALLMULTI
+		|| netdev->mc_count > GELIC_NET_MC_COUNT_MAX) { /* list max */
+		status = lv1_net_add_multicast_address(card->dev->did.bus_id,
+				card->dev->did.dev_id,
+				0, 1);
+		if (status) {
+			printk("lv1_net_add_multicast_address failed, status=%ld\n",\
+				status);
+		}
+		return ;
+	}
+
+	/* set multicalst address */
+	for ( mc = netdev->mc_list; mc; mc = mc->next) {
+		addr = 0;
+		p = mc->dmi_addr;
+		for (i = 0; i < ETH_ALEN; i++) {
+			addr <<= 8;
+			addr |= *p++;
+		}
+		status = lv1_net_add_multicast_address(card->dev->did.bus_id,
+				card->dev->did.dev_id,
+				addr, 0);
+		if (status) {
+			printk("lv1_net_add_multicast_address failed, status=%ld\n",\
+				status);
+		}
+	}
+}
+
+/**
+ * gelic_net_disable_rxdmac - disables the receive DMA controller
+ * @card: card structure
+ *
+ * gelic_net_disable_rxdmac terminates processing on the DMA controller by
+ * turing off DMA and issueing a force end
+ */
+static void
+gelic_net_disable_rxdmac(struct gelic_net_card *card)
+{
+	uint64_t status;
+
+	status = lv1_net_stop_rx_dma(card->dev->did.bus_id,
+		card->dev->did.dev_id, 0);
+	if (status) {
+		printk("lv1_net_stop_rx_dma faild, status=%ld\n", status);
+	}
+}
+
+/**
+ * gelic_net_disable_txdmac - disables the transmit DMA controller
+ * @card: card structure
+ *
+ * gelic_net_disable_txdmac terminates processing on the DMA controller by
+ * turing off DMA and issueing a force end
+ */
+static void
+gelic_net_disable_txdmac(struct gelic_net_card *card)
+{
+	uint64_t status;
+
+	status = lv1_net_stop_tx_dma(card->dev->did.bus_id,
+		card->dev->did.dev_id, 0);
+	if (status) {
+		printk("lv1_net_stop_tx_dma faild, status=%ld\n", status);
+	}
+}
+
+/**
+ * gelic_net_stop - called upon ifconfig down
+ * @netdev: interface device structure
+ *
+ * always returns 0
+ */
+int
+gelic_net_stop(struct net_device *netdev)
+{
+	struct gelic_net_card *card = netdev_priv(netdev);
+
+	netif_poll_disable(netdev);
+	netif_stop_queue(netdev);
+
+	/* turn off DMA, force end */
+	gelic_net_disable_rxdmac(card);
+	gelic_net_disable_txdmac(card);
+
+	gelic_net_set_irq_mask(card, 0);
+
+	/* disconnect event port */
+	free_irq(card->netdev->irq, card->netdev);
+	ps3_sb_event_receive_port_destroy(&card->dev->did,
+		card->dev->interrupt_id, card->netdev->irq);
+	card->netdev->irq = NO_IRQ;
+
+	netif_carrier_off(netdev);
+
+	/* release chains */
+	gelic_net_release_tx_chain(card, 1);
+	gelic_net_release_rx_chain(card);
+
+	gelic_net_free_chain(card, card->tx_top);
+	gelic_net_free_chain(card, card->rx_top);
+
+	return 0;
+}
+
+/**
+ * gelic_net_get_next_tx_descr - returns the next available tx descriptor
+ * @card: device structure to get descriptor from
+ *
+ * returns the address of the next descriptor, or NULL if not available.
+ */
+static struct gelic_net_descr *
+gelic_net_get_next_tx_descr(struct gelic_net_card *card)
+{
+	if (card->tx_chain.head == NULL) return NULL;
+	/* check, if head points to not-in-use descr */
+  if (!ps3_gelic_param) {
+	if ( card->tx_chain.tail != card->tx_chain.head->next
+		&& gelic_net_get_descr_status(card->tx_chain.head) ==
+		     GELIC_NET_DESCR_NOT_IN_USE ) {
+		return card->tx_chain.head;
+	} else {
+		return NULL;
+	}
+  } else {
+	if ( card->tx_chain.tail != card->tx_chain.head->next
+		&& card->tx_chain.tail != card->tx_chain.head->next->next
+		&& gelic_net_get_descr_status(card->tx_chain.head) ==
+		     GELIC_NET_DESCR_NOT_IN_USE
+		&& gelic_net_get_descr_status(card->tx_chain.head->next) ==
+		     GELIC_NET_DESCR_NOT_IN_USE ) {
+		return card->tx_chain.head;
+	} else {
+		return NULL;
+	}
+  }
+}
+
+/**
+ * gelic_net_set_txdescr_cmdstat - sets the tx descriptor command field
+ * @descr: descriptor structure to fill out
+ * @skb: packet to consider
+ * @middle: middle of frame
+ *
+ * fills out the command and status field of the descriptor structure,
+ * depending on hardware checksum settings. This function assumes a wmb()
+ * has executed before.
+ */
+static void
+gelic_net_set_txdescr_cmdstat(struct gelic_net_descr *descr,
+			       struct sk_buff *skb, int middle)
+{
+	uint32_t nocs, tcpcs, udpcs;
+
+	if (middle) {
+		nocs =  GELIC_NET_DMAC_CMDSTAT_NOCS;
+		tcpcs = GELIC_NET_DMAC_CMDSTAT_TCPCS;
+		udpcs = GELIC_NET_DMAC_CMDSTAT_UDPCS;
+	}else {
+		nocs =  GELIC_NET_DMAC_CMDSTAT_NOCS
+			| GELIC_NET_DMAC_CMDSTAT_END_FRAME;
+		tcpcs = GELIC_NET_DMAC_CMDSTAT_TCPCS
+			| GELIC_NET_DMAC_CMDSTAT_END_FRAME;
+		udpcs = GELIC_NET_DMAC_CMDSTAT_UDPCS
+			| GELIC_NET_DMAC_CMDSTAT_END_FRAME;
+	}
+
+	if (skb->ip_summed != CHECKSUM_PARTIAL) {
+		descr->dmac_cmd_status = nocs;
+	} else {
+		/* is packet ip?
+		 * if yes: tcp? udp? */
+		if (skb->protocol == htons(ETH_P_IP)) {
+			if (skb->nh.iph->protocol == IPPROTO_TCP) {
+				descr->dmac_cmd_status = tcpcs;
+			} else if (skb->nh.iph->protocol == IPPROTO_UDP) {
+				descr->dmac_cmd_status = udpcs;
+			} else { /* the stack should checksum non-tcp and non-udp
+				    packets on his own: NETIF_F_IP_CSUM */
+				descr->dmac_cmd_status = nocs;
+			}
+		}
+	}
+}
+
+/**
+ * gelic_net_prepare_tx_descr - get dma address of skb_data
+ * @card: card structure
+ * @descr: descriptor structure
+ * @skb: packet to use
+ *
+ * returns 0 on success, <0 on failure.
+ *
+ */
+static int
+gelic_net_prepare_tx_descr_v(struct gelic_net_card *card,
+			    struct gelic_net_descr *descr,
+			    struct sk_buff *skb)
+{
+	dma_addr_t buf;
+	uint8_t *hdr;
+	struct vlan_ethhdr *v_hdr;
+	int vlan_len;
+
+	if (skb->len < GELIC_NET_VLAN_POS) {
+		printk("error: skb->len:%d\n", skb->len);
+		return -EINVAL;
+	}
+	hdr = skb->data;
+	v_hdr = (struct vlan_ethhdr *)skb->data;
+	memcpy(&descr->vlan, v_hdr, GELIC_NET_VLAN_POS);
+	if (card->vlan_index != -1) {
+		descr->vlan.h_vlan_proto = htons(ETH_P_8021Q); /* vlan 0x8100*/
+		descr->vlan.h_vlan_TCI = htons(card->vlan_id[card->vlan_index]);
+		vlan_len = GELIC_NET_VLAN_POS + VLAN_HLEN; /* VLAN_HLEN=4 */
+	} else {
+		vlan_len = GELIC_NET_VLAN_POS; /* no vlan tag */
+	}
+
+	/* first descr */
+	buf = dma_map_single(&card->dev->core, &descr->vlan,
+					 vlan_len, PCI_DMA_BIDIRECTIONAL);
+
+	if (buf == DMA_ERROR_CODE) {
+		printk("could not iommu-map packet (%p, %i). "
+			  "Dropping packet\n", v_hdr, vlan_len);
+		return -ENOMEM;
+	}
+
+	descr->buf_addr = buf;
+	descr->buf_size = vlan_len;
+	descr->skb = skb; /* not used */
+	descr->data_status = 0;
+	gelic_net_set_txdescr_cmdstat(descr, skb, 1); /* not the frame end */
+
+	/* second descr */
+	card->tx_chain.head = card->tx_chain.head->next;
+	descr->next_descr_addr = descr->next->bus_addr;
+	descr = descr->next;
+	if (gelic_net_get_descr_status(descr) !=
+			GELIC_NET_DESCR_NOT_IN_USE) {
+		printk("ERROR descr()\n"); /* XXX will be removed */
+	}
+	buf = dma_map_single(&card->dev->core, hdr + GELIC_NET_VLAN_POS,
+				skb->len - GELIC_NET_VLAN_POS,
+				PCI_DMA_BIDIRECTIONAL);
+
+	if (buf == DMA_ERROR_CODE) {
+		printk("could not iommu-map packet (%p, %i). "
+			  "Dropping packet\n", hdr + GELIC_NET_VLAN_POS,
+			  skb->len - GELIC_NET_VLAN_POS);
+		return -ENOMEM;
+	}
+
+	descr->buf_addr = buf;
+	descr->buf_size = skb->len - GELIC_NET_VLAN_POS;
+	descr->skb = skb;
+	descr->data_status = 0;
+	descr->next_descr_addr= 0;
+	gelic_net_set_txdescr_cmdstat(descr,skb, 0);
+
+	return 0;
+}
+
+static int
+gelic_net_prepare_tx_descr(struct gelic_net_card *card,
+			    struct gelic_net_descr *descr,
+			    struct sk_buff *skb)
+{
+	dma_addr_t buf = dma_map_single(&card->dev->core, skb->data,
+					 skb->len, PCI_DMA_BIDIRECTIONAL);
+
+	if (buf == DMA_ERROR_CODE) {
+		printk("could not iommu-map packet (%p, %i). "
+			  "Dropping packet\n", skb->data, skb->len);
+		return -ENOMEM;
+	}
+
+	descr->buf_addr = buf;
+	descr->buf_size = skb->len;
+	descr->skb = skb;
+	descr->data_status = 0;
+
+	return 0;
+}
+
+static void
+gelic_net_set_frame_end(struct gelic_net_card *card,
+		struct gelic_net_descr *descr, struct sk_buff *skb)
+{
+	descr->next_descr_addr= 0;
+	gelic_net_set_txdescr_cmdstat(descr,skb, 0);
+	wmb();
+	if (descr->prev) {
+		descr->prev->next_descr_addr = descr->bus_addr;
+	}
+}
+
+/**
+ * gelic_net_kick_txdma - enables TX DMA processing
+ * @card: card structure
+ * @descr: descriptor address to enable TX processing at
+ *
+ */
+static void
+gelic_net_kick_txdma(struct gelic_net_card *card,
+		       struct gelic_net_descr *descr)
+{
+	uint64_t status = -1;
+	int count = 10;
+
+	if (dmac_status) {
+		return ;
+	}
+
+	if (gelic_net_get_descr_status(descr) == GELIC_NET_DESCR_CARDOWNED) {
+		/* kick */
+		dmac_status = 1;
+
+		while(count--) {
+			status = lv1_net_start_tx_dma(card->dev->did.bus_id,
+					card->dev->did.dev_id,
+					(uint64_t)descr->bus_addr, 0);
+			if (!status) {
+				break;
+			}
+		}
+		if (!count) {
+			printk("lv1_net_start_txdma failed, status=%ld %016lx\n",\
+				status, gelic_irq_status);
+		}
+	}
+}
+
+/**
+ * gelic_net_xmit - transmits a frame over the device
+ * @skb: packet to send out
+ * @netdev: interface device structure
+ *
+ * returns 0 on success, <0 on failure
+ */
+static int
+gelic_net_xmit(struct sk_buff *skb, struct net_device *netdev)
+{
+	struct gelic_net_card *card = netdev_priv(netdev);
+	struct gelic_net_descr *descr = NULL;
+	int result;
+	unsigned long flags;
+
+	spin_lock_irqsave(&card->intmask_lock, flags);
+
+	gelic_net_release_tx_chain(card, 0);
+	if (skb == NULL){
+		goto kick;
+	}
+	descr = gelic_net_get_next_tx_descr(card); /* get tx_chain.head */
+	if (!descr) {
+		netif_stop_queue(netdev);
+		spin_unlock_irqrestore(&card->intmask_lock, flags);
+		return 1;
+	}
+  if (!ps3_gelic_param) {
+	result = gelic_net_prepare_tx_descr(card, descr, skb);
+  } else {
+	result = gelic_net_prepare_tx_descr_v(card, descr, skb);
+  }
+	if (result)
+		goto error;
+
+	card->tx_chain.head = card->tx_chain.head->next;
+  if (!ps3_gelic_param) {
+	gelic_net_set_frame_end(card, descr, skb);
+  } else {
+	if (descr->prev) {
+		descr->prev->next_descr_addr = descr->bus_addr;
+	}
+  }
+kick:
+	wmb();
+	gelic_net_kick_txdma(card, card->tx_chain.tail);
+
+	netdev->trans_start = jiffies;
+	spin_unlock_irqrestore(&card->intmask_lock, flags);
+	return NETDEV_TX_OK;
+
+error:
+	card->netdev_stats.tx_dropped++;
+	spin_unlock_irqrestore(&card->intmask_lock, flags);
+	return NETDEV_TX_LOCKED;
+}
+
+/**
+ * gelic_net_pass_skb_up - takes an skb from a descriptor and passes it on
+ * @descr: descriptor to process
+ * @card: card structure
+ *
+ * returns 1 on success, 0 if no packet was passed to the stack
+ *
+ * iommu-unmaps the skb, fills out skb structure and passes the data to the
+ * stack. The descriptor state is not changed.
+ */
+static int
+gelic_net_pass_skb_up(struct gelic_net_descr *descr,
+		       struct gelic_net_card *card)
+{
+	struct sk_buff *skb;
+	struct net_device *netdev;
+	uint32_t data_status, data_error;
+
+	data_status = descr->data_status;
+	data_error = descr->data_error;
+
+	netdev = card->netdev;
+	/* check for errors in the data_error flag */
+	if ((data_error & GELIC_NET_DATA_ERROR_MASK))
+		DPRINTK("error in received descriptor found, "
+		       "data_status=x%08x, data_error=x%08x\n",
+		       data_status, data_error);
+	/* prepare skb, unmap descriptor */
+	skb = descr->skb;
+	dma_unmap_single(&card->dev->core, descr->buf_addr, GELIC_NET_MAX_MTU,
+			 PCI_DMA_BIDIRECTIONAL);
+
+	/* the cases we'll throw away the packet immediately */
+	if (data_error & GELIC_NET_DATA_ERROR_FLG) {
+		DPRINTK("ERROR DESTROY:%x\n", data_error);
+		return 0;
+	}
+
+	skb->dev = netdev;
+	skb_put(skb, descr->valid_size);
+	descr->skb = NULL;
+	/* the card seems to add 2 bytes of junk in front
+	 * of the ethernet frame */
+#define GELIC_NET_MISALIGN		2
+	skb_pull(skb, GELIC_NET_MISALIGN);
+	skb->protocol = eth_type_trans(skb, netdev);
+
+	/* checksum offload */
+	if (card->rx_csum) {
+		if ( (data_status & GELIC_NET_DATA_STATUS_CHK_MASK) &&
+		     (!(data_error & GELIC_NET_DATA_ERROR_CHK_MASK)) )
+			skb->ip_summed = CHECKSUM_UNNECESSARY;
+		else
+			skb->ip_summed = CHECKSUM_NONE;
+	} else {
+		skb->ip_summed = CHECKSUM_NONE;
+	}
+
+	/* pass skb up to stack */
+	netif_receive_skb(skb);
+
+	/* update netdevice statistics */
+	card->netdev_stats.rx_packets++;
+	card->netdev_stats.rx_bytes += skb->len;
+
+	return 1;
+}
+
+/**
+ * gelic_net_decode_descr - processes an rx descriptor
+ * @card: card structure
+ *
+ * returns 1 if a packet has been sent to the stack, otherwise 0
+ *
+ * processes an rx descriptor by iommu-unmapping the data buffer and passing
+ * the packet up to the stack
+ */
+static int
+gelic_net_decode_one_descr(struct gelic_net_card *card)
+{
+	enum gelic_net_descr_status status;
+	struct gelic_net_descr *descr;
+	struct gelic_net_descr_chain *chain = &card->rx_chain;
+	int result = 0;
+	int kick = 0;
+	uint32_t cmd_status;
+
+	descr = chain->tail;
+	cmd_status = chain->tail->dmac_cmd_status;
+	rmb();
+	status = cmd_status >> GELIC_NET_DESCR_IND_PROC_SHIFT;
+	if (status == GELIC_NET_DESCR_CARDOWNED) {
+		goto no_decode;
+	}
+	if (status == GELIC_NET_DESCR_NOT_IN_USE) {
+		printk("err: decode_one_descr\n");
+		goto no_decode;
+	}
+
+	if ( (status == GELIC_NET_DESCR_RESPONSE_ERROR) ||
+	     (status == GELIC_NET_DESCR_PROTECTION_ERROR) ||
+	     (status == GELIC_NET_DESCR_FORCE_END) ) {
+		printk("%s: dropping RX descriptor with state %d\n",
+		       card->netdev->name, status);
+		card->netdev_stats.rx_dropped++;
+		goto refill;
+	}
+
+	if ( (status != GELIC_NET_DESCR_COMPLETE) &&
+	     (status != GELIC_NET_DESCR_FRAME_END) ) {
+		printk("%s: RX descriptor with state %d\n",
+		       card->netdev->name, status);
+		goto refill;
+	}
+
+	/* ok, we've got a packet in descr */
+	result = gelic_net_pass_skb_up(descr, card); /* 1: skb_up sccess */
+	if (cmd_status & GELIC_NET_DMAC_CMDSTAT_CHAIN_END) {
+		kick = 1;
+	}
+refill:
+	descr->next_descr_addr = 0; /* unlink the descr */
+	wmb();
+	gelic_net_set_descr_status(descr, GELIC_NET_DESCR_NOT_IN_USE);
+	/* change the descriptor state: */
+	gelic_net_prepare_rx_descr(card, descr); /* refill one desc */
+	chain->head = descr;
+	chain->tail = descr->next;
+	descr->prev->next_descr_addr = descr->bus_addr;
+	if(kick) {
+		wmb();
+		gelic_net_enable_rxdmac(card);
+	}
+	return result;
+
+no_decode:
+	return 0;
+}
+
+/**
+ * gelic_net_poll - NAPI poll function called by the stack to return packets
+ * @netdev: interface device structure
+ * @budget: number of packets we can pass to the stack at most
+ *
+ * returns 0 if no more packets available to the driver/stack. Returns 1,
+ * if the quota is exceeded, but the driver has still packets.
+ *
+ */
+static int
+gelic_net_poll(struct net_device *netdev, int *budget)
+{
+	struct gelic_net_card *card = netdev_priv(netdev);
+	int packets_to_do, packets_done = 0;
+	int no_more_packets = 0;
+
+	packets_to_do = min(*budget, netdev->quota);
+
+	while (packets_to_do) {
+		if (gelic_net_decode_one_descr(card)) {
+			packets_done++;
+			packets_to_do--;
+		} else {
+			/* no more packets for the stack */
+			no_more_packets = 1;
+			break;
+		}
+	}
+	netdev->quota -= packets_done;
+	*budget -= packets_done;
+	if (no_more_packets == 1) {
+		netif_rx_complete(netdev);
+
+		/* one more check */
+		while (1) {
+			if (!gelic_net_decode_one_descr(card) ) break;
+		};
+
+		return 0;
+	}else {
+		return 1;
+	}
+}
+
+/**
+ * gelic_net_get_stats - get interface statistics
+ * @netdev: interface device structure
+ *
+ * returns the interface statistics residing in the gelic_net_card struct
+ */
+static struct net_device_stats *
+gelic_net_get_stats(struct net_device *netdev)
+{
+	struct gelic_net_card *card = netdev_priv(netdev);
+	struct net_device_stats *stats = &card->netdev_stats;
+
+	return stats;
+}
+
+/**
+ * gelic_net_change_mtu - changes the MTU of an interface
+ * @netdev: interface device structure
+ * @new_mtu: new MTU value
+ *
+ * returns 0 on success, <0 on failure
+ */
+static int
+gelic_net_change_mtu(struct net_device *netdev, int new_mtu)
+{
+	/* no need to re-alloc skbs or so -- the max mtu is about 2.3k
+	 * and mtu is outbound only anyway */
+	if ( (new_mtu < GELIC_NET_MIN_MTU ) ||
+		(new_mtu > GELIC_NET_MAX_MTU) ) {
+		return -EINVAL;
+	}
+	netdev->mtu = new_mtu;
+	return 0;
+}
+
+/**
+ * gelic_net_interrupt - event handler for gelic_net
+ */
+static irqreturn_t
+gelic_net_interrupt(int irq, void *ptr)
+{
+	struct net_device *netdev = ptr;
+	struct gelic_net_card *card = netdev_priv(netdev);
+	uint32_t status0, status1, status2;
+	unsigned long flags;
+	uint64_t status;
+
+	status = gelic_irq_status;
+	rmb();
+	status0 = (uint32_t)(status >> 32);
+	status1 = (uint32_t)(status & 0xffffffff);
+	status2 = 0;
+
+	if (!status0 && !status1 && !status2) {
+		return IRQ_NONE;
+	}
+
+	if(status1 & (1 << GELIC_NET_GDADCEINT) )  {
+		netif_rx_schedule(netdev);
+	}else
+	if (status0 & (1 << GELIC_NET_GRFANMINT) ) {
+		netif_rx_schedule(netdev);
+	}
+
+	if (status0 & (1 << GELIC_NET_GDTDCEINT) ) {
+		spin_lock_irqsave(&card->intmask_lock, flags);
+		dmac_status = 0;
+		spin_unlock_irqrestore(&card->intmask_lock, flags);
+		gelic_net_xmit(NULL, netdev);
+	}
+	return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/**
+ * gelic_net_poll_controller - artificial interrupt for netconsole etc.
+ * @netdev: interface device structure
+ *
+ * see Documentation/networking/netconsole.txt
+ */
+static void
+gelic_net_poll_controller(struct net_device *netdev)
+{
+	struct gelic_net_card *card = netdev_priv(netdev);
+
+	gelic_net_set_irq_mask(card, 0);
+	gelic_net_interrupt(netdev->irq, netdev);
+	gelic_net_set_irq_mask(card, card->ghiintmask);
+}
+#endif /* CONFIG_NET_POLL_CONTROLLER */
+
+/**
+ * gelic_net_open_device - open device and map dma region
+ * @card: card structure
+ */
+static int
+gelic_net_open_device(struct gelic_net_card *card)
+{
+	unsigned long result;
+	int ret;
+
+	result = ps3_sb_event_receive_port_setup(PS3_BINDING_CPU_ANY,
+		&card->dev->did, card->dev->interrupt_id, &card->netdev->irq);
+
+	if (result) {
+		printk("%s:%d: gelic_net_open_device failed (%ld)\n",
+			__func__, __LINE__, result);
+		ret = -EPERM;
+		goto fail_alloc_irq;
+	}
+
+	ret = request_irq(card->netdev->irq, gelic_net_interrupt, IRQF_DISABLED,
+		"gelic network", card->netdev);
+
+	if (ret) {
+		printk("%s:%d: request_irq failed (%ld)\n",
+			__func__, __LINE__, result);
+		goto fail_request_irq;
+	}
+
+	return 0;
+
+fail_request_irq:
+	ps3_sb_event_receive_port_destroy(&card->dev->did,
+		card->dev->interrupt_id, card->netdev->irq);
+	card->netdev->irq = NO_IRQ;
+fail_alloc_irq:
+	return ret;
+}
+
+
+/**
+ * gelic_net_open - called upon ifonfig up
+ * @netdev: interface device structure
+ *
+ * returns 0 on success, <0 on failure
+ *
+ * gelic_net_open allocates all the descriptors and memory needed for
+ * operation, sets up multicast list and enables interrupts
+ */
+int
+gelic_net_open(struct net_device *netdev)
+{
+	struct gelic_net_card *card = netdev_priv(netdev);
+
+	printk(" -> %s:%d\n", __func__, __LINE__);
+
+	gelic_net_open_device(card);
+
+	if (gelic_net_init_chain(card, &card->tx_chain,
+			card->descr, tx_descriptors))
+		goto alloc_tx_failed;
+	if (gelic_net_init_chain(card, &card->rx_chain,
+			card->descr + tx_descriptors, rx_descriptors))
+		goto alloc_rx_failed;
+
+	/* head of chain */
+	card->tx_top = card->tx_chain.head;
+	card->rx_top = card->rx_chain.head;
+
+	/* allocate rx skbs */
+	if (gelic_net_alloc_rx_skbs(card))
+		goto alloc_skbs_failed;
+
+	dmac_status = 0;
+	card->ghiintmask = GELIC_NET_RXINT | GELIC_NET_TXINT;
+	gelic_net_set_irq_mask(card, card->ghiintmask);
+	gelic_net_enable_rxdmac(card);
+
+	netif_start_queue(netdev);
+	netif_carrier_on(netdev);
+	netif_poll_enable(netdev);
+
+	return 0;
+
+alloc_skbs_failed:
+	gelic_net_free_chain(card, card->rx_top);
+alloc_rx_failed:
+	gelic_net_free_chain(card, card->tx_top);
+alloc_tx_failed:
+	return -ENOMEM;
+}
+
+#ifdef GELIC_NET_ETHTOOL
+static void
+gelic_net_get_drvinfo (struct net_device *netdev, struct ethtool_drvinfo *info)
+{
+	strncpy(info->driver, GELIC_NET_DRV_NAME, sizeof(info->driver) - 1);
+	strncpy(info->version, GELIC_NET_DRV_VERSION, sizeof(info->version) - 1);
+}
+
+static int
+gelic_net_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd)
+{
+	struct gelic_net_card *card = netdev_priv(netdev);
+	uint64_t status, v1, v2;
+	int speed, duplex;
+
+	speed = duplex = -1;
+	status = lv1_net_control(card->dev->did.bus_id, card->dev->did.dev_id,
+			GELIC_NET_GET_ETH_PORT_STATUS, GELIC_NET_PORT, 0, 0,
+			&v1, &v2);
+	if (status) {
+		/* link down */
+	} else {
+		if (v1 & GELIC_NET_FULL_DUPLEX) {
+			duplex = DUPLEX_FULL;
+		} else {
+			duplex = DUPLEX_HALF;
+		}
+
+		if (v1 & GELIC_NET_SPEED_10 ) {
+			speed = SPEED_10;
+		} else if (v1 & GELIC_NET_SPEED_100) {
+			speed = SPEED_100;
+		} else if (v1 & GELIC_NET_SPEED_1000) {
+			speed = SPEED_1000;
+		}
+	}
+	cmd->supported = SUPPORTED_TP | SUPPORTED_Autoneg |
+			SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
+			SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full |
+			SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full;
+	cmd->advertising = cmd->supported;
+	cmd->speed = speed;
+	cmd->duplex = duplex;
+	cmd->autoneg = AUTONEG_ENABLE; /* always enabled */
+	cmd->port = PORT_TP;
+
+	return 0;
+}
+
+static uint32_t
+gelic_net_get_link(struct net_device *netdev)
+{
+	struct gelic_net_card *card = netdev_priv(netdev);
+	uint64_t status, v1, v2;
+	int link;
+
+	status = lv1_net_control(card->dev->did.bus_id, card->dev->did.dev_id,
+			GELIC_NET_GET_ETH_PORT_STATUS, GELIC_NET_PORT, 0, 0,
+			&v1, &v2);
+	if (status) {
+		return 0; /* link down */
+	}
+	if (v1 & GELIC_NET_LINK_UP)
+		link = 1;
+	else
+		link = 0;
+	return link;
+}
+
+static int
+gelic_net_nway_reset(struct net_device *netdev)
+{
+	if (netif_running(netdev)) {
+		gelic_net_stop(netdev);
+		gelic_net_open(netdev);
+	}
+	return 0;
+}
+
+static uint32_t
+gelic_net_get_tx_csum(struct net_device *netdev)
+{
+	return (netdev->features & NETIF_F_IP_CSUM) != 0;
+}
+
+static int
+gelic_net_set_tx_csum(struct net_device *netdev, uint32_t data)
+{
+	if (data)
+		netdev->features |= NETIF_F_IP_CSUM;
+	else
+		netdev->features &= ~NETIF_F_IP_CSUM;
+
+	return 0;
+}
+
+static uint32_t
+gelic_net_get_rx_csum(struct net_device *netdev)
+{
+	struct gelic_net_card *card = netdev_priv(netdev);
+
+	return card->rx_csum;
+}
+
+static int
+gelic_net_set_rx_csum(struct net_device *netdev, uint32_t data)
+{
+	struct gelic_net_card *card = netdev_priv(netdev);
+
+	card->rx_csum = data;
+	return 0;
+}
+
+static struct ethtool_ops gelic_net_ethtool_ops = {
+	.get_drvinfo	= gelic_net_get_drvinfo,
+	.get_settings	= gelic_net_get_settings,
+	.get_link	= gelic_net_get_link,
+	.nway_reset	= gelic_net_nway_reset,
+	.get_tx_csum	= gelic_net_get_tx_csum,
+	.set_tx_csum	= gelic_net_set_tx_csum,
+	.get_rx_csum	= gelic_net_get_rx_csum,
+	.set_rx_csum	= gelic_net_set_rx_csum,
+};
+#endif
+
+static int
+gelic_net_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
+{
+	struct gelic_net_card *card = netdev_priv(netdev);
+	void __user *addr = (void __user *) ifr->ifr_ifru.ifru_data;
+	int mode, res = 0;
+
+	switch(cmd) {
+	case GELIC_NET_GET_MODE:
+		DPRINTK("GELIC_NET_GET_MODE:\n");
+		mode = card->vlan_index;
+		if (copy_to_user(addr, &mode, sizeof(mode)) ) {
+			printk("error copy_to_user\n");
+		}
+		res = 0;
+		break;
+	case GELIC_NET_SET_MODE:
+		if (card->vlan_index == -1) {
+			res = -EOPNOTSUPP; /* vlan mode only */
+			break;
+		}
+		if (copy_from_user(&mode, addr, sizeof(mode)) ) {
+			printk("error copy_from_user\n");
+		}
+		DPRINTK("GELIC_NET_SET_MODE:%x --> %x \n",
+				card->vlan_index, mode);
+		if (mode > GELIC_NET_VLAN_MAX -1 || mode < -1)
+			mode = GELIC_NET_VLAN_WIRED - 1;
+
+		if (card->vlan_index != mode) {
+			card->vlan_index = mode;
+			if (netif_running(netdev)) {
+				gelic_net_stop(netdev);
+				gelic_net_open(netdev);
+			}
+		}
+		res = 0;
+		break;
+	default:
+		res = -EOPNOTSUPP;
+		break;
+	}
+
+	return res;
+}
+
+/**
+ * gelic_net_tx_timeout_task - task scheduled by the watchdog timeout
+ * function (to be called not under interrupt status)
+ * @data: data, is interface device structure
+ *
+ * called as task when tx hangs, resets interface (if interface is up)
+ */
+static void
+gelic_net_tx_timeout_task(struct work_struct *work)
+{
+	struct gelic_net_card *card =
+		container_of(work, struct gelic_net_card, tx_timeout_task);
+	struct net_device *netdev = card->netdev;
+
+	printk("Timed out. Restarting... \n");
+
+	if (!(netdev->flags & IFF_UP))
+		goto out;
+
+	netif_device_detach(netdev);
+	gelic_net_stop(netdev);
+
+	gelic_net_open(netdev);
+	netif_device_attach(netdev);
+
+out:
+	atomic_dec(&card->tx_timeout_task_counter);
+}
+
+/**
+ * gelic_net_tx_timeout - called when the tx timeout watchdog kicks in.
+ * @netdev: interface device structure
+ *
+ * called, if tx hangs. Schedules a task that resets the interface
+ */
+static void
+gelic_net_tx_timeout(struct net_device *netdev)
+{
+	struct gelic_net_card *card;
+
+	card = netdev_priv(netdev);
+	atomic_inc(&card->tx_timeout_task_counter);
+	if (netdev->flags & IFF_UP)
+		schedule_work(&card->tx_timeout_task);
+	else
+		atomic_dec(&card->tx_timeout_task_counter);
+}
+
+/**
+ * gelic_net_setup_netdev_ops - initialization of net_device operations
+ * @netdev: net_device structure
+ *
+ * fills out function pointers in the net_device structure
+ */
+static void
+gelic_net_setup_netdev_ops(struct net_device *netdev)
+{
+	netdev->open = &gelic_net_open;
+	netdev->stop = &gelic_net_stop;
+	netdev->hard_start_xmit = &gelic_net_xmit;
+	netdev->get_stats = &gelic_net_get_stats;
+	netdev->set_multicast_list = &gelic_net_set_multi;
+	netdev->change_mtu = &gelic_net_change_mtu;
+	/* tx watchdog */
+	netdev->tx_timeout = &gelic_net_tx_timeout;
+	netdev->watchdog_timeo = GELIC_NET_WATCHDOG_TIMEOUT;
+	/* NAPI */
+	netdev->poll = &gelic_net_poll;
+	netdev->weight = GELIC_NET_NAPI_WEIGHT;
+#ifdef GELIC_NET_ETHTOOL
+	netdev->ethtool_ops = &gelic_net_ethtool_ops;
+#endif
+	netdev->do_ioctl = &gelic_net_ioctl;
+}
+
+/**
+ * gelic_net_setup_netdev - initialization of net_device
+ * @card: card structure
+ *
+ * Returns 0 on success or <0 on failure
+ *
+ * gelic_net_setup_netdev initializes the net_device structure
+ **/
+static int
+gelic_net_setup_netdev(struct gelic_net_card *card)
+{
+	int i, result;
+	struct net_device *netdev = card->netdev;
+	struct sockaddr addr;
+	uint8_t *mac;
+	uint64_t status, v1, v2;
+
+	SET_MODULE_OWNER(netdev);
+	spin_lock_init(&card->intmask_lock);
+
+	card->rx_csum = GELIC_NET_RX_CSUM_DEFAULT;
+
+	gelic_net_setup_netdev_ops(netdev);
+
+	netdev->features = NETIF_F_IP_CSUM;
+
+	status = lv1_net_control(card->dev->did.bus_id, card->dev->did.dev_id,
+				GELIC_NET_GET_MAC_ADDRESS,
+				0, 0, 0, &v1, &v2);
+	if (status || !v1) {
+		printk("lv1_net_control GET_MAC_ADDR not supported, status=%ld\n",
+			status);
+		return -EINVAL;
+	}
+	v1 <<= 16;
+	mac = (uint8_t *)&v1;
+	memcpy(addr.sa_data, mac, ETH_ALEN);
+	memcpy(netdev->dev_addr, addr.sa_data, ETH_ALEN);
+
+	result = register_netdev(netdev);
+	if (result) {
+			printk("Couldn't register net_device: %i\n", result);
+		return result;
+	}
+
+	printk("%s: %s\n", netdev->name, GELIC_NET_DRV_NAME);
+	printk("%s: Ethernet Address: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
+		netdev->name,
+		netdev->dev_addr[0], netdev->dev_addr[1], netdev->dev_addr[2],
+		netdev->dev_addr[3], netdev->dev_addr[4], netdev->dev_addr[5]);
+
+	card->vlan_index = -1;	/* no vlan */
+	for (i = 0; i < GELIC_NET_VLAN_MAX ;i++) {
+		status = lv1_net_control(card->dev->did.bus_id,
+					card->dev->did.dev_id,
+					GELIC_NET_GET_VLAN_ID,
+					i + 1, /* GELIC_NET_VLAN_X */
+					0, 0, &v1, &v2);
+		if (status == GELIC_NET_VLAN_NO_ENTRY) {
+			DPRINTK("GELIC_VLAN_ID no entry:%ld, VLAN disabled\n",
+				status);
+			card->vlan_id[i] = 0;
+		} else if (status) {
+			printk("GELIC_NET_VLAN_ID faild, status=%ld\n", status);
+			card->vlan_id[i] = 0;
+		} else {
+			card->vlan_id[i] = (uint32_t)v1;
+			DPRINTK("vlan_id:%d, %lx\n", i, v1);
+		}
+	}
+	if (card->vlan_id[GELIC_NET_VLAN_WIRED - 1]) {
+		card->vlan_index = GELIC_NET_VLAN_WIRED - 1;
+	}
+	return 0;
+}
+
+/**
+ * gelic_net_alloc_card - allocates net_device and card structure
+ *
+ * returns the card structure or NULL in case of errors
+ *
+ * the card and net_device structures are linked to each other
+ */
+static struct gelic_net_card *
+gelic_net_alloc_card(void)
+{
+	struct net_device *netdev;
+	struct gelic_net_card *card;
+	size_t alloc_size;
+
+	alloc_size = sizeof (*card) +
+		sizeof (struct gelic_net_descr) * rx_descriptors +
+		sizeof (struct gelic_net_descr) * tx_descriptors;
+	netdev = alloc_etherdev(alloc_size);
+	if (!netdev)
+		return NULL;
+
+	card = netdev_priv(netdev);
+	card->netdev = netdev;
+	INIT_WORK(&card->tx_timeout_task, gelic_net_tx_timeout_task);
+	init_waitqueue_head(&card->waitq);
+	atomic_set(&card->tx_timeout_task_counter, 0);
+
+	return card;
+}
+
+/**
+ * ps3_gelic_driver_probe - add a device to the control of this driver
+ */
+static int ps3_gelic_driver_probe (struct ps3_system_bus_device *dev)
+{
+	int result;
+
+	gcard = gelic_net_alloc_card();
+
+	if (!gcard) {
+		dev_dbg(&dev->core, "%s:%d: gelic_net_alloc_card failed\n",
+			__func__, __LINE__);
+		result = -ENOMEM;
+		goto fail_alloc_card;
+	}
+
+	gcard->dev = dev;
+
+	result = ps3_open_hv_device(&dev->did);
+
+	if (result) {
+		dev_dbg(&dev->core, "%s:%d: ps3_open_hv_device failed\n",
+			__func__, __LINE__);
+		goto fail_open;
+	}
+
+	result = ps3_dma_region_create(dev->d_region);
+
+	if (result) {
+		dev_dbg(&dev->core, "%s:%d: ps3_dma_region_create failed: "
+			"(%d)\n", __func__, __LINE__, result);
+		BUG_ON("check region type");
+		goto fail_dma_region;
+	}
+
+	result = lv1_net_set_interrupt_status_indicator(dev->did.bus_id,
+		dev->did.dev_id, ps3_mm_phys_to_lpar(__pa(&gelic_irq_status)),
+		0);
+
+	if (result) {
+		dev_dbg(&dev->core, "%s:%d: "
+			"lv1_net_set_interrupt_status_indicator failed: %s\n",
+			__func__, __LINE__, ps3_result(result));
+		result = -EIO;
+		goto fail_status_indicator;
+	}
+
+	result = gelic_net_setup_netdev(gcard);
+
+	if (result) {
+		dev_dbg(&dev->core, "%s:%d: ps3_dma_region_create failed: "
+			"(%d)\n", __func__, __LINE__, result);
+		goto fail_setup_netdev;
+	}
+
+	return 0;
+
+fail_setup_netdev:
+	lv1_net_set_interrupt_status_indicator(dev->did.bus_id, dev->did.dev_id,
+		0 , 0); // check if ok!!!
+fail_status_indicator:
+	ps3_dma_region_free(dev->d_region);
+fail_dma_region:
+	ps3_close_hv_device(&dev->did);
+fail_open:
+	free_netdev(gcard->netdev); // enough???
+	gcard = NULL;
+fail_alloc_card:
+	return result;
+}
+
+/**
+ * ps3_gelic_driver_remove - remove a device from the control of this driver
+ */
+
+static int
+ps3_gelic_driver_remove (struct ps3_system_bus_device *dev)
+{
+	struct net_device *netdev;
+	struct gelic_net_card *card;
+
+	card = gcard;
+	netdev = card->netdev;
+
+	wait_event(card->waitq,
+		   atomic_read(&card->tx_timeout_task_counter) == 0);
+
+	unregister_netdev(netdev);
+	free_netdev(netdev);
+
+	lv1_net_set_interrupt_status_indicator(dev->did.bus_id, dev->did.dev_id,
+		0 , 0); // check if ok!!!
+
+	ps3_dma_region_free(dev->d_region);
+
+	ps3_close_hv_device(&dev->did);
+
+	// anything else needed???
+
+	printk(" <- %s:%d:\n", __func__, __LINE__);
+	return 0;
+}
+
+static struct ps3_system_bus_driver ps3_gelic_driver = {
+	.match_id = PS3_MATCH_ID_GELIC,
+	.probe = ps3_gelic_driver_probe,
+	.remove = ps3_gelic_driver_remove,
+	.core = {
+		.name = "ps3_gelic_driver",
+	},
+};
+
+static int __init
+ps3_gelic_driver_init (void)
+{
+	return firmware_has_feature(FW_FEATURE_PS3_LV1)
+		? ps3_system_bus_driver_register(&ps3_gelic_driver)
+		: -ENODEV;
+}
+
+static void __exit
+ps3_gelic_driver_exit (void)
+{
+	ps3_system_bus_driver_unregister(&ps3_gelic_driver);
+}
+
+module_init (ps3_gelic_driver_init);
+module_exit (ps3_gelic_driver_exit);
+
+#ifdef CONFIG_GELIC_NET
+static int __init early_param_gelic_net(char *p)
+{
+	if (strstr(p, "n")) {
+		ps3_gelic_param = 0;	/* gelic_vlan off */
+		printk("ps3_gelic_param:vlan off\n");
+	} else {
+		ps3_gelic_param = 1;	/* gelic_vlan on */
+	}
+	return 0;
+
+}
+early_param("gelic_vlan", early_param_gelic_net);
+#endif

linux-2.6-ps3-kexec.patch:

--- NEW FILE linux-2.6-ps3-kexec.patch ---
As of 2007-05-04 (commit 197a8b29cbb721909e1bde44c6e7a588d93ba440):

ps3-wip/ps3-kexec-core.diff
ps3-wip/ps3-kexec-system-bus.diff
ps3-wip/ps3-kexec-usb.diff
ps3-wip/ps3-kexec-ps3fb.diff

diff --git a/arch/powerpc/platforms/ps3/htab.c b/arch/powerpc/platforms/ps3/htab.c
index ea60c45..08a9074 100644
--- a/arch/powerpc/platforms/ps3/htab.c
+++ b/arch/powerpc/platforms/ps3/htab.c
@@ -234,10 +234,18 @@ static void ps3_hpte_invalidate(unsigned long slot, unsigned long va,
 
 static void ps3_hpte_clear(void)
 {
-	/* Make sure to clean up the frame buffer device first */
-	ps3fb_cleanup();
+	int result;
 
-	lv1_unmap_htab(htab_addr);
+	DBG(" -> %s:%d\n", __func__, __LINE__);
+
+	result = lv1_unmap_htab(htab_addr);
+	BUG_ON(result);
+
+	ps3_mm_shutdown();
+
+	ps3_mm_vas_destroy();
+
+	DBG(" <- %s:%d\n", __func__, __LINE__);
 }
 
 void __init ps3_hpte_init(unsigned long htab_size)
diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c
index 9da82c2..f5c31fb 100644
--- a/arch/powerpc/platforms/ps3/interrupt.c
+++ b/arch/powerpc/platforms/ps3/interrupt.c
@@ -90,6 +90,92 @@ struct ps3_private {
 static DEFINE_PER_CPU(struct ps3_private, ps3_private);
 
 /**
+ * ps3_chip_mask - Set an interrupt mask bit in ps3_bmp.
+ * @virq: The assigned Linux virq.
+ *
+ * Sets ps3_bmp.mask and calls lv1_did_update_interrupt_mask().
+ */
+
+static void ps3_chip_mask(unsigned int virq)
+{
+	struct ps3_private *pd = get_irq_chip_data(virq);
+	u64 bit = 0x8000000000000000UL >> virq;
+	u64 *p = &pd->bmp.mask;
+	u64 old;
+	unsigned long flags;
+
+	pr_debug("%s:%d: cpu %u, virq %d\n", __func__, __LINE__, pd->cpu, virq);
+
+	local_irq_save(flags);
+	asm volatile(
+		     "1:	ldarx %0,0,%3\n"
+		     "andc	%0,%0,%2\n"
+		     "stdcx.	%0,0,%3\n"
+		     "bne-	1b"
+		     : "=&r" (old), "+m" (*p)
+		     : "r" (bit), "r" (p)
+		     : "cc" );
+
+	lv1_did_update_interrupt_mask(pd->node, pd->cpu);
+	local_irq_restore(flags);
+}
+
+/**
+ * ps3_chip_unmask - Clear an interrupt mask bit in ps3_bmp.
+ * @virq: The assigned Linux virq.
+ *
+ * Clears ps3_bmp.mask and calls lv1_did_update_interrupt_mask().
+ */
+
+static void ps3_chip_unmask(unsigned int virq)
+{
+	struct ps3_private *pd = get_irq_chip_data(virq);
+	u64 bit = 0x8000000000000000UL >> virq;
+	u64 *p = &pd->bmp.mask;
+	u64 old;
+	unsigned long flags;
+
+	pr_debug("%s:%d: cpu %u, virq %d\n", __func__, __LINE__, pd->cpu, virq);
+
+	local_irq_save(flags);
+	asm volatile(
+		     "1:	ldarx %0,0,%3\n"
+		     "or	%0,%0,%2\n"
+		     "stdcx.	%0,0,%3\n"
+		     "bne-	1b"
+		     : "=&r" (old), "+m" (*p)
+		     : "r" (bit), "r" (p)
+		     : "cc" );
+
+	lv1_did_update_interrupt_mask(pd->node, pd->cpu);
+	local_irq_restore(flags);
+}
+
+/**
+ * ps3_chip_eoi - HV end-of-interrupt.
+ * @virq: The assigned Linux virq.
+ *
+ * Calls lv1_end_of_interrupt_ext().
+ */
+
+static void ps3_chip_eoi(unsigned int virq)
+{
+	const struct ps3_private *pd = get_irq_chip_data(virq);
+	lv1_end_of_interrupt_ext(pd->node, pd->cpu, virq);
+}
+
+/**
+ * ps3_irq_chip - Represents the ps3_bmp as a Linux struct irq_chip.
+ */
+
+static struct irq_chip ps3_irq_chip = {
+	.typename = "ps3",
+	.mask = ps3_chip_mask,
+	.unmask = ps3_chip_unmask,
+	.eoi = ps3_chip_eoi,
+};
+
+/**
  * ps3_virq_setup - virq related setup.
  * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
  * serviced on.
@@ -133,6 +219,8 @@ int ps3_virq_setup(enum ps3_cpu_binding cpu, unsigned long outlet,
 		goto fail_set;
 	}
 
+	ps3_chip_mask(*virq);
+
 	return result;
 
 fail_set:
@@ -224,6 +312,8 @@ int ps3_irq_plug_destroy(unsigned int virq)
 	pr_debug("%s:%d: node %lu, cpu %d, virq %u\n", __func__, __LINE__,
 		pd->node, pd->cpu, virq);
 
+	ps3_chip_mask(virq);
+
 	result = lv1_disconnect_irq_plug_ext(pd->node, pd->cpu, virq);
 
 	if (result)
@@ -283,23 +373,21 @@ int ps3_event_receive_port_destroy(unsigned int virq)
 
 	pr_debug(" -> %s:%d virq: %u\n", __func__, __LINE__, virq);
 
+	ps3_chip_mask(virq);
+
 	result = lv1_destruct_event_receive_port(virq_to_hw(virq));
 
 	if (result)
 		pr_debug("%s:%d: lv1_destruct_event_receive_port failed: %s\n",
 			__func__, __LINE__, ps3_result(result));
 
-	/* lv1_destruct_event_receive_port() destroys the IRQ plug,
-	 * so don't call ps3_irq_plug_destroy() here.
+	/* Can't call ps3_virq_destroy() here since ps3_smp_cleanup_cpu()
+	 * calls from interrupt context (smp_call_function).
 	 */
 
-	result = ps3_virq_destroy(virq);
-	BUG_ON(result);
-
 	pr_debug(" <- %s:%d\n", __func__, __LINE__);
 	return result;
 }
-EXPORT_SYMBOL_GPL(ps3_event_receive_port_destroy);
 
 int ps3_send_event_locally(unsigned int virq)
 {
@@ -371,6 +459,13 @@ int ps3_sb_event_receive_port_destroy(const struct ps3_device_id *did,
 	result = ps3_event_receive_port_destroy(virq);
 	BUG_ON(result);
 
+	/* ps3_event_receive_port_destroy() destroys the IRQ plug,
+	 * so don't call ps3_irq_plug_destroy() here.
+	 */
+
+	result = ps3_virq_destroy(virq);
+	BUG_ON(result);
+
 	pr_debug(" <- %s:%d\n", __func__, __LINE__);
 	return result;
 }
@@ -411,16 +506,23 @@ EXPORT_SYMBOL_GPL(ps3_io_irq_setup);
 int ps3_io_irq_destroy(unsigned int virq)
 {
 	int result;
+	unsigned int outlet = virq_to_hw(virq);
 
-	result = lv1_destruct_io_irq_outlet(virq_to_hw(virq));
+	ps3_chip_mask(virq);
 
-	if (result)
-		pr_debug("%s:%d: lv1_destruct_io_irq_outlet failed: %s\n",
-			__func__, __LINE__, ps3_result(result));
+	/* lv1_destruct_io_irq_outlet() will destroy the IRQ plug,
+	 * so call ps3_irq_plug_destroy() first.
+	 */
 
 	result = ps3_irq_plug_destroy(virq);
 	BUG_ON(result);
 
+	result = lv1_destruct_io_irq_outlet(outlet);
+
+	if (result)
+		pr_debug("%s:%d: lv1_destruct_io_irq_outlet failed: %s\n",
+			__func__, __LINE__, ps3_result(result));
+
 	return result;
 }
 EXPORT_SYMBOL_GPL(ps3_io_irq_destroy);
@@ -465,6 +567,7 @@ int ps3_vuart_irq_destroy(unsigned int virq)
 {
 	int result;
 
+	ps3_chip_mask(virq);
 	result = lv1_deconfigure_virtual_uart_irq();
 
 	if (result) {
@@ -564,67 +667,6 @@ static void __attribute__ ((unused)) _dump_mask(struct ps3_private* pd,
 static void dump_bmp(struct ps3_private* pd) {};
 #endif /* defined(DEBUG) */
 
-static void ps3_chip_mask(unsigned int virq)
-{
-	struct ps3_private *pd = get_irq_chip_data(virq);
-	u64 bit = 0x8000000000000000UL >> virq;
-	u64 *p = &pd->bmp.mask;
-	u64 old;
-	unsigned long flags;
-
-	pr_debug("%s:%d: cpu %u, virq %d\n", __func__, __LINE__, pd->cpu, virq);
-
-	local_irq_save(flags);
-	asm volatile(
-		     "1:	ldarx %0,0,%3\n"
-		     "andc	%0,%0,%2\n"
-		     "stdcx.	%0,0,%3\n"
-		     "bne-	1b"
-		     : "=&r" (old), "+m" (*p)
-		     : "r" (bit), "r" (p)
-		     : "cc" );
-
-	lv1_did_update_interrupt_mask(pd->node, pd->cpu);
-	local_irq_restore(flags);
-}
-
-static void ps3_chip_unmask(unsigned int virq)
-{
-	struct ps3_private *pd = get_irq_chip_data(virq);
-	u64 bit = 0x8000000000000000UL >> virq;
-	u64 *p = &pd->bmp.mask;
-	u64 old;
-	unsigned long flags;
-
-	pr_debug("%s:%d: cpu %u, virq %d\n", __func__, __LINE__, pd->cpu, virq);
-
-	local_irq_save(flags);
-	asm volatile(
-		     "1:	ldarx %0,0,%3\n"
-		     "or	%0,%0,%2\n"
-		     "stdcx.	%0,0,%3\n"
-		     "bne-	1b"
-		     : "=&r" (old), "+m" (*p)
-		     : "r" (bit), "r" (p)
-		     : "cc" );
-
-	lv1_did_update_interrupt_mask(pd->node, pd->cpu);
-	local_irq_restore(flags);
-}
-
-static void ps3_chip_eoi(unsigned int virq)
-{
-	const struct ps3_private *pd = get_irq_chip_data(virq);
-	lv1_end_of_interrupt_ext(pd->node, pd->cpu, virq);
-}
-
-static struct irq_chip irq_chip = {
-	.typename = "ps3",
-	.mask = ps3_chip_mask,
-	.unmask = ps3_chip_unmask,
-	.eoi = ps3_chip_eoi,
-};
-
 static void ps3_host_unmap(struct irq_host *h, unsigned int virq)
 {
 	set_irq_chip_data(virq, NULL);
@@ -636,7 +678,7 @@ static int ps3_host_map(struct irq_host *h, unsigned int virq,
 	pr_debug("%s:%d: hwirq %lu, virq %u\n", __func__, __LINE__, hwirq,
 		virq);
 
-	set_irq_chip_and_handler(virq, &irq_chip, handle_fasteoi_irq);
+	set_irq_chip_and_handler(virq, &ps3_irq_chip, handle_fasteoi_irq);
 
 	return 0;
 }
diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c
index 25cf1f0..e6ff624 100644
--- a/arch/powerpc/platforms/ps3/mm.c
+++ b/arch/powerpc/platforms/ps3/mm.c
@@ -213,9 +213,15 @@ fail:
 
 void ps3_mm_vas_destroy(void)
 {
+	int result;
+
+	DBG("%s:%d: map.vas_id    = %lu\n", __func__, __LINE__, map.vas_id);
+
 	if (map.vas_id) {
-		lv1_select_virtual_address_space(0);
-		lv1_destruct_virtual_address_space(map.vas_id);
+		result = lv1_select_virtual_address_space(0);
+		BUG_ON(result);
+		result = lv1_destruct_virtual_address_space(map.vas_id);
+		BUG_ON(result);
 		map.vas_id = 0;
 	}
 }
@@ -276,8 +282,12 @@ zero_region:
 
 void ps3_mm_region_destroy(struct mem_region *r)
 {
+	int result;
+
+	DBG("%s:%d: r->base = %lxh\n", __func__, __LINE__, r->base);
 	if (r->base) {
-		lv1_release_memory(r->base);
+		result = lv1_release_memory(r->base);
+		BUG_ON(result);
 		r->size = r->base = r->offset = 0;
 		map.total = map.rm.size;
 	}
@@ -643,6 +653,13 @@ static int dma_sb_region_create(struct ps3_dma_region* r)
 	u64 len;
 	int result;
 
+	BUG_ON(!r);
+	if(!r->did.bus_id) {
+		pr_info("%s:%d: %u:%u no dma\n", __func__, __LINE__,
+			r->did.bus_id, r->did.dev_id);
+		return 0;
+	}
+
 	DBG("%s:%u: len = 0x%lx, page_size = %u, offset = 0x%lx\n", __func__,
 	    __LINE__, r->len, r->page_size, r->offset);
 	INIT_LIST_HEAD(&r->chunk_list.head);
@@ -697,6 +714,13 @@ static int dma_sb_region_free(struct ps3_dma_region* r)
 	struct dma_chunk *c;
 	struct dma_chunk *tmp;
 
+	BUG_ON(!r);
+	if(!r->did.bus_id) {
+		pr_info("%s:%d: %u:%u no dma\n", __func__, __LINE__,
+			r->did.bus_id, r->did.dev_id);
+		return 0;
+	}
+
 	list_for_each_entry_safe(c, tmp, &r->chunk_list.head, link) {
 		list_del(&c->link);
 		dma_sb_free_chunk(c);
@@ -706,7 +730,7 @@ static int dma_sb_region_free(struct ps3_dma_region* r)
 		r->bus_addr);
 
 	if (result)
-		DBG("%s:%d: lv1_free_device_dma_region failed: %s\n",
+		DBG("%s:%d: lv1_release_io_segment failed: %s\n",
 			__func__, __LINE__, ps3_result(result));
 
 	r->len = r->bus_addr = 0;
@@ -1122,12 +1146,18 @@ EXPORT_SYMBOL(ps3_dma_region_init);
 
 int ps3_dma_region_create(struct ps3_dma_region *r)
 {
+	BUG_ON(!r);
+	BUG_ON(!r->region_ops);
+	BUG_ON(!r->region_ops->create);
 	return r->region_ops->create(r);
 }
 EXPORT_SYMBOL(ps3_dma_region_create);
 
 int ps3_dma_region_free(struct ps3_dma_region *r)
 {
+	BUG_ON(!r);
+	BUG_ON(!r->region_ops);
+	BUG_ON(!r->region_ops->free);
 	return r->region_ops->free(r);
 }
 EXPORT_SYMBOL(ps3_dma_region_free);
diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c
index c989493..e045216 100644
--- a/arch/powerpc/platforms/ps3/setup.c
+++ b/arch/powerpc/platforms/ps3/setup.c
@@ -201,31 +201,28 @@ static int __init ps3_probe(void)
 #if defined(CONFIG_KEXEC)
 static void ps3_kexec_cpu_down(int crash_shutdown, int secondary)
 {
-	DBG(" -> %s:%d\n", __func__, __LINE__);
+	int result;
+	u64 ppe_id;
+	u64 thread_id = secondary ? 1 : 0;
+
+	DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, secondary);
+	ps3_smp_cleanup_cpu(thread_id);
+
+	lv1_get_logical_ppe_id(&ppe_id);
+	result = lv1_configure_irq_state_bitmap(ppe_id, secondary ? 0 : 1, 0);
 
-	if (secondary) {
-		int cpu;
-		for_each_online_cpu(cpu)
-			if (cpu)
-				ps3_smp_cleanup_cpu(cpu);
-	} else
-		ps3_smp_cleanup_cpu(0);
+	/* seems to fail on second call */
+	DBG("%s:%d: lv1_configure_irq_state_bitmap (%d) %s\n", __func__,
+		__LINE__, secondary, ps3_result(result));
 
 	DBG(" <- %s:%d\n", __func__, __LINE__);
 }
 
 static void ps3_machine_kexec(struct kimage *image)
 {
-	unsigned long ppe_id;
-
 	DBG(" -> %s:%d\n", __func__, __LINE__);
 
-	lv1_get_logical_ppe_id(&ppe_id);
-	lv1_configure_irq_state_bitmap(ppe_id, 0, 0);
-	ps3_mm_shutdown();
-	ps3_mm_vas_destroy();
-
-	default_machine_kexec(image);
+	default_machine_kexec(image); // needs ipi, never returns.
 
 	DBG(" <- %s:%d\n", __func__, __LINE__);
 }
diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c
index a2591b8..c5afa82 100644
--- a/arch/powerpc/platforms/ps3/system-bus.c
+++ b/arch/powerpc/platforms/ps3/system-bus.c
@@ -36,6 +36,71 @@ static struct device ps3_system_bus = {
         .bus_id         = "ps3_system",
 };
 
+// FIXME: need device usage counters!
+struct {
+	int id_11; // usb 0
+	int id_12; // usb 1
+} static usage_hack;
+
+int ps3_open_hv_device(struct ps3_device_id *did)
+{
+	int result;
+
+	BUG_ON(!did->bus_id); // now just for sb devices.
+
+	// FIXME: hacks for dev usage counts.
+
+	if(did->bus_id == 1 && did->dev_id == 1) {
+		usage_hack.id_11++;
+		if (usage_hack.id_11 > 1)
+			return 0;
+	}
+
+	if(did->bus_id == 1 && did->dev_id == 2) {
+		usage_hack.id_12++;
+		if (usage_hack.id_12 > 1)
+			return 0;
+	}
+
+	result = lv1_open_device(did->bus_id, did->dev_id, 0);
+
+  	if (result) {
+  		pr_debug("%s:%d: lv1_open_device failed: %s\n", __func__,
+			__LINE__, ps3_result(result));
+			result = -EPERM;
+	}
+
+	return result;
+}
+EXPORT_SYMBOL_GPL(ps3_open_hv_device);
+
+int ps3_close_hv_device(struct ps3_device_id *did)
+{
+	int result;
+
+	BUG_ON(!did->bus_id); // now just for sb devices.
+
+	// FIXME: hacks for dev usage counts.
+
+	if(did->bus_id == 1 && did->dev_id == 1) {
+		usage_hack.id_11--;
+		if (usage_hack.id_11)
+			return 0;
+	}
+
+	if(did->bus_id == 1 && did->dev_id == 2) {
+		usage_hack.id_12--;
+		if (usage_hack.id_12)
+			return 0;
+	}
+
+	result = lv1_close_device(did->bus_id, did->dev_id);
+	BUG_ON(result);
+
+	return result;
+}
+EXPORT_SYMBOL_GPL(ps3_close_hv_device);
+
 #define dump_mmio_region(_a) _dump_mmio_region(_a, __func__, __LINE__)
 static void _dump_mmio_region(const struct ps3_mmio_region* r,
 	const char* func, int line)
@@ -80,6 +145,8 @@ static int ps3_sb_free_mmio_region(struct ps3_mmio_region *r)
 {
 	int result;
 
+	dump_mmio_region(r);
+;
 	result = lv1_unmap_device_mmio_region(r->did.bus_id, r->did.dev_id,
 		r->lpar_addr);
 
@@ -156,76 +223,83 @@ static int ps3_system_bus_probe(struct device *_dev)
 {
 	int result = 0;
 	struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev);
-	struct ps3_system_bus_driver *drv =
-		to_ps3_system_bus_driver(_dev->driver);
-
-	if (dev->did.bus_id)
-		result = lv1_open_device(dev->did.bus_id, dev->did.dev_id, 0);
-
-	if (result && (result != LV1_BUSY || (dev->match_id != PS3_MATCH_ID_EHCI
-		&& dev->match_id != PS3_MATCH_ID_OHCI))) {
-		pr_debug("%s:%d: lv1_open_device failed: %s\n",
-			__func__, __LINE__, ps3_result(result));
-		result = -EACCES;
-		goto clean_none;
-	}
+	struct ps3_system_bus_driver *drv;
 
-	if (dev->d_region && dev->d_region->did.bus_id) {
-		result = ps3_dma_region_create(dev->d_region);
-
-		if (result) {
-			pr_debug("%s:%d: ps3_dma_region_create failed (%d)\n",
-				__func__, __LINE__, result);
-			BUG_ON("check region type");
-			result = -EINVAL;
-			goto clean_device;
-		}
-	}
+	BUG_ON(!dev);
+	pr_info(" -> %s:%d: %s\n", __func__, __LINE__, _dev->bus_id);
 
+	drv = to_ps3_system_bus_driver(_dev->driver);
 	BUG_ON(!drv);
 
-	if (drv->probe)
+	if(drv->probe)
 		result = drv->probe(dev);
 	else
 		pr_info("%s:%d: %s no probe method\n", __func__, __LINE__,
 			dev->core.bus_id);
 
-	if (result) {
-		pr_debug("%s:%d: drv->probe failed\n", __func__, __LINE__);
-		goto clean_dma;
-	}
-
-	return result;
-
-clean_dma:
-	if (dev->d_region && dev->d_region->did.bus_id)
-		ps3_dma_region_free(dev->d_region);
-clean_device:
-	if (dev->did.bus_id)
-		lv1_close_device(dev->did.bus_id, dev->did.dev_id);
-clean_none:
+	pr_info(" <- %s:%d: %s\n", __func__, __LINE__, dev->core.bus_id);
 	return result;
 }
 
 static int ps3_system_bus_remove(struct device *_dev)
 {
+	int result = 0;
 	struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev);
-	struct ps3_system_bus_driver *drv =
-		to_ps3_system_bus_driver(_dev->driver);
+	struct ps3_system_bus_driver *drv;
+
+	BUG_ON(!dev);
+	pr_info(" -> %s:%d: %s\n", __func__, __LINE__, _dev->bus_id);
+
+	drv = to_ps3_system_bus_driver(_dev->driver);
+	BUG_ON(!drv);
 
 	if (drv->remove)
-		drv->remove(dev);
+		result = drv->remove(dev);
 	else
 		pr_info("%s:%d: %s no remove method\n", __func__, __LINE__,
 			dev->core.bus_id);
 
-	if (dev->d_region && dev->d_region->did.dev_id)
-		ps3_dma_region_free(dev->d_region);
+	pr_info(" <- %s:%d: %s\n", __func__, __LINE__, dev->core.bus_id);
+	return result;
+}
+
+static void ps3_system_bus_shutdown(struct device *_dev)
+{
+	struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev);
+	struct ps3_system_bus_driver *drv
+		= to_ps3_system_bus_driver(_dev->driver);
+
+	BUG_ON(!dev);
+
+	pr_info(" -> %s:%d: %s, match_id %d\n", __func__, __LINE__,
+		dev->core.bus_id, dev->match_id);
+
+	if(!dev->core.driver) {
+		pr_info("%s:%d: %s: no driver bound\n", __func__, __LINE__,
+			dev->core.bus_id);
+		return;
+	}
+
+	drv = to_ps3_system_bus_driver(dev->core.driver);
 
-	if (dev->did.bus_id)
-		lv1_close_device(dev->did.bus_id, dev->did.dev_id);
+	BUG_ON(!drv);
 
-	return 0;
+	pr_info("%s:%d: %s -> %s\n", __func__, __LINE__, dev->core.bus_id,
+		drv->core.name);
+
+	if (drv->shutdown)
+		drv->shutdown(dev);
+	else if (drv->remove) {
+		pr_info("%s:%d: %s no shutdown, calling remove\n",
+			__func__, __LINE__, dev->core.bus_id);
+		drv->remove(dev);
+	} else {
+		pr_info("%s:%d: %s no shutdown method\n", __func__, __LINE__,
+			dev->core.bus_id);
+		BUG();
+	}
+
+	pr_info(" <- %s:%d: %s\n", __func__, __LINE__, dev->core.bus_id);
 }
 
 static int ps3_system_bus_uevent(struct device *_dev, char **envp,
@@ -262,6 +336,7 @@ struct bus_type ps3_system_bus_type = {
 	.match = ps3_system_bus_match,
 	.probe = ps3_system_bus_probe,
 	.remove = ps3_system_bus_remove,
+ 	.shutdown = ps3_system_bus_shutdown,
 	.uevent = ps3_system_bus_uevent,
 	.dev_attrs = ps3_system_bus_dev_attrs,
 };
@@ -272,10 +347,13 @@ int __init ps3_system_bus_init(void)
 
 	if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
 		return -ENODEV;
+
+	printk(" -> %s:%d\n", __func__, __LINE__);
 	result = device_register(&ps3_system_bus);
 	BUG_ON(result);
 	result = bus_register(&ps3_system_bus_type);
 	BUG_ON(result);
+	printk(" <- %s:%d\n", __func__, __LINE__);
 	return result;
 }
 
@@ -541,9 +619,11 @@ int ps3_system_bus_driver_register(struct ps3_system_bus_driver *drv,
 {
 	int result;
 
+	printk(" -> %s:%d: %s\n", __func__, __LINE__, drv->core.name);
 	drv->core.bus = &ps3_system_bus_type;
 
 	result = driver_register(&drv->core);
+	printk(" <- %s:%d: %s\n", __func__, __LINE__, drv->core.name);
 	return result;
 }
 
@@ -551,7 +631,9 @@ EXPORT_SYMBOL_GPL(ps3_system_bus_driver_register);
 
 void ps3_system_bus_driver_unregister(struct ps3_system_bus_driver *drv)
 {
+	printk(" -> %s:%d: %s\n", __func__, __LINE__, drv->core.name);
 	driver_unregister(&drv->core);
+	printk(" <- %s:%d: %s\n", __func__, __LINE__, drv->core.name);
 }
 
 EXPORT_SYMBOL_GPL(ps3_system_bus_driver_unregister);
diff --git a/drivers/usb/host/ehci-ps3.c b/drivers/usb/host/ehci-ps3.c
index 37b83ba..339f985 100644
--- a/drivers/usb/host/ehci-ps3.c
+++ b/drivers/usb/host/ehci-ps3.c
@@ -19,6 +19,7 @@
  */
 
 #include <asm/ps3.h>
+#include <asm/lv1call.h>
 
 static int ps3_ehci_hc_reset(struct usb_hcd *hcd)
 {
@@ -85,13 +86,30 @@ static int ps3_ehci_sb_probe(struct ps3_system_bus_device *dev)
 		goto fail_start;
 	}
 
+	result = ps3_open_hv_device(&dev->did);
+
+	if (result) {
+		dev_dbg(&dev->core, "%s:%d: ps3_open_hv_device failed\n",
+			__func__, __LINE__);
+		goto fail_open;
+	}
+
+	result = ps3_dma_region_create(dev->d_region);
+
+	if (result) {
+		dev_dbg(&dev->core, "%s:%d: ps3_dma_region_create failed: "
+			"(%d)\n", __func__, __LINE__, result);
+		BUG_ON("check region type");
+		goto fail_dma_region;
+	}
+
 	result = ps3_mmio_region_create(dev->m_region);
 
 	if (result) {
 		dev_dbg(&dev->core, "%s:%d: ps3_map_mmio_region failed\n",
 			__func__, __LINE__);
 		result = -EPERM;
-		goto fail_mmio;
+		goto fail_mmio_region;
 	}
 
 	dev_dbg(&dev->core, "%s:%d: mmio mapped_addr %lxh\n", __func__,
@@ -120,6 +138,11 @@ static int ps3_ehci_sb_probe(struct ps3_system_bus_device *dev)
 
 	hcd->rsrc_start = dev->m_region->lpar_addr;
 	hcd->rsrc_len = dev->m_region->len;
+
+	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name))
+		dev_dbg(&dev->core, "%s:%d: request_mem_region failed\n",
+			__func__, __LINE__);
+
 	hcd->regs = ioremap(dev->m_region->lpar_addr, dev->m_region->len);
 
 	if (!hcd->regs) {
@@ -153,12 +176,17 @@ static int ps3_ehci_sb_probe(struct ps3_system_bus_device *dev)
 fail_add_hcd:
 	iounmap(hcd->regs);
 fail_ioremap:
+	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
 	usb_put_hcd(hcd);
 fail_create_hcd:
 	ps3_io_irq_destroy(virq);
 fail_irq:
 	ps3_free_mmio_region(dev->m_region);
-fail_mmio:
+fail_mmio_region:
+	ps3_dma_region_free(dev->d_region);
+fail_dma_region:
+	ps3_close_hv_device(&dev->did);
+fail_open:
 fail_start:
 	return result;
 }
@@ -168,9 +196,27 @@ static int ps3_ehci_sb_remove(struct ps3_system_bus_device *dev)
 	struct usb_hcd *hcd =
 		(struct usb_hcd *)ps3_system_bus_get_driver_data(dev);
 
-	usb_put_hcd(hcd);
+	BUG_ON(!hcd);
+
+	dev_dbg(&dev->core, "%s:%d: regs %p\n", __func__, __LINE__, hcd->regs);
+	dev_dbg(&dev->core, "%s:%d: irq %u\n", __func__, __LINE__, hcd->irq);
+
+	usb_remove_hcd(hcd);
+
 	ps3_system_bus_set_driver_data(dev, NULL);
 
+	BUG_ON(!hcd->regs);
+	iounmap(hcd->regs);
+
+	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+	usb_put_hcd(hcd);
+
+	ps3_io_irq_destroy(hcd->irq);
+	ps3_free_mmio_region(dev->m_region);
+
+	ps3_dma_region_free(dev->d_region);
+	ps3_close_hv_device(&dev->did);
+
 	return 0;
 }
 
@@ -183,4 +229,5 @@ static struct ps3_system_bus_driver ps3_ehci_sb_driver = {
 	},
 	.probe = ps3_ehci_sb_probe,
 	.remove = ps3_ehci_sb_remove,
+	.shutdown = ps3_ehci_sb_remove,
 };
diff --git a/drivers/usb/host/ohci-ps3.c b/drivers/usb/host/ohci-ps3.c
index d7cf072..429628f 100644
--- a/drivers/usb/host/ohci-ps3.c
+++ b/drivers/usb/host/ohci-ps3.c
@@ -19,6 +19,7 @@
  */
 
 #include <asm/ps3.h>
+#include <asm/lv1call.h>
 
 static int ps3_ohci_hc_reset(struct usb_hcd *hcd)
 {
@@ -84,16 +85,35 @@ static int ps3_ohci_sb_probe(struct ps3_system_bus_device *dev)
 
 	if (usb_disabled()) {
 		result = -ENODEV;
+		BUG();
 		goto fail_start;
 	}
 
+	result = ps3_open_hv_device(&dev->did);
+
+	if (result) {
+		dev_dbg(&dev->core, "%s:%d: lv1_open_device failed: %s\n",
+			__func__, __LINE__, ps3_result(result));
+		result = -EPERM;
+		goto fail_open;
+	}
+
+	result = ps3_dma_region_create(dev->d_region);
+
+	if (result) {
+		dev_dbg(&dev->core, "%s:%d: ps3_dma_region_create failed: "
+			"(%d)\n", __func__, __LINE__, result);
+		BUG_ON("check region type");
+		goto fail_dma_region;
+	}
+
 	result = ps3_mmio_region_create(dev->m_region);
 
 	if (result) {
 		dev_dbg(&dev->core, "%s:%d: ps3_map_mmio_region failed\n",
 			__func__, __LINE__);
 		result = -EPERM;
-		goto fail_mmio;
+		goto fail_mmio_region;
 	}
 
 	dev_dbg(&dev->core, "%s:%d: mmio mapped_addr %lxh\n", __func__,
@@ -122,6 +142,11 @@ static int ps3_ohci_sb_probe(struct ps3_system_bus_device *dev)
 
 	hcd->rsrc_start = dev->m_region->lpar_addr;
 	hcd->rsrc_len = dev->m_region->len;
+
+	if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name))
+		dev_dbg(&dev->core, "%s:%d: request_mem_region failed\n",
+			__func__, __LINE__);
+
 	hcd->regs = ioremap(dev->m_region->lpar_addr, dev->m_region->len);
 
 	if (!hcd->regs) {
@@ -155,12 +180,17 @@ static int ps3_ohci_sb_probe(struct ps3_system_bus_device *dev)
 fail_add_hcd:
 	iounmap(hcd->regs);
 fail_ioremap:
+	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
 	usb_put_hcd(hcd);
 fail_create_hcd:
 	ps3_io_irq_destroy(virq);
 fail_irq:
 	ps3_free_mmio_region(dev->m_region);
-fail_mmio:
+fail_mmio_region:
+	ps3_dma_region_free(dev->d_region);
+fail_dma_region:
+	ps3_close_hv_device(&dev->did);
+fail_open:
 fail_start:
 	return result;
 }
@@ -170,9 +200,27 @@ static int ps3_ohci_sb_remove (struct ps3_system_bus_device *dev)
 	struct usb_hcd *hcd =
 		(struct usb_hcd *)ps3_system_bus_get_driver_data(dev);
 
-	usb_put_hcd(hcd);
+	BUG_ON(!hcd);
+
+	dev_dbg(&dev->core, "%s:%d: regs %p\n", __func__, __LINE__, hcd->regs);
+	dev_dbg(&dev->core, "%s:%d: irq %u\n", __func__, __LINE__, hcd->irq);
+
+	usb_remove_hcd(hcd);
+
 	ps3_system_bus_set_driver_data(dev, NULL);
 
+	BUG_ON(!hcd->regs);
+	iounmap(hcd->regs);
+
+	release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+	usb_put_hcd(hcd);
+
+	ps3_io_irq_destroy(hcd->irq);
+	ps3_free_mmio_region(dev->m_region);
+
+	ps3_dma_region_free(dev->d_region);
+	ps3_close_hv_device(&dev->did);
+
 	return 0;
 }
 
@@ -185,4 +233,5 @@ static struct ps3_system_bus_driver ps3_ohci_sb_driver = {
 	},
 	.probe = ps3_ohci_sb_probe,
 	.remove = ps3_ohci_sb_remove,
+	.shutdown = ps3_ohci_sb_remove,
 };
diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c
index 9756a72..0237237 100644
--- a/drivers/video/ps3fb.c
+++ b/drivers/video/ps3fb.c
@@ -1094,19 +1094,11 @@ err:
 	return retval;
 }
 
-static void ps3fb_shutdown(struct platform_device *dev)
-{
-	ps3fb_flip_ctl(0);	/* flip off */
-	ps3fb.dinfo->irq.mask = 0;
-	free_irq(ps3fb.irq_no, ps3fb.dev);
-	ps3_irq_plug_destroy(ps3fb.irq_no);
-	iounmap((u8 __iomem *)ps3fb.dinfo);
-}
-
 void ps3fb_cleanup(void)
 {
 	int status;
 
+	printk(" -> %s:%d\n", __func__, __LINE__);
 	if (ps3fb.task) {
 		struct task_struct *task = ps3fb.task;
 		ps3fb.task = NULL;
@@ -1135,15 +1127,32 @@ static int ps3fb_remove(struct platform_device *dev)
 {
 	struct fb_info *info = platform_get_drvdata(dev);
 
+	printk(" -> %s:%d\n", __func__, __LINE__);
+
 	if (info) {
 		unregister_framebuffer(info);
 		fb_dealloc_cmap(&info->cmap);
 		framebuffer_release(info);
 	}
 	ps3fb_cleanup();
+	printk(" <- %s:%d\n", __func__, __LINE__);
 	return 0;
 }
 
+static void ps3fb_shutdown(struct platform_device *dev)
+{
+	printk(" -> %s:%d\n", __func__, __LINE__);
+
+	ps3fb_remove(dev);
+
+	ps3fb_flip_ctl(0);	/* flip off */
+	ps3fb.dinfo->irq.mask = 0;
+	free_irq(ps3fb.irq_no, ps3fb.dev);
+	ps3_irq_plug_destroy(ps3fb.irq_no);
+	iounmap((u8 __iomem *)ps3fb.dinfo);
+	printk(" <- %s:%d\n", __func__, __LINE__);
+}
+
 static struct platform_driver ps3fb_driver = {
 	.probe	= ps3fb_probe,
 	.remove = ps3fb_remove,
diff --git a/include/asm-powerpc/ps3.h b/include/asm-powerpc/ps3.h
index 46e8282..0369120 100644
--- a/include/asm-powerpc/ps3.h
+++ b/include/asm-powerpc/ps3.h
@@ -59,6 +59,8 @@ struct ps3_device_id {
 	unsigned int dev_id;
 };
 
+int ps3_open_hv_device(struct ps3_device_id *did);
+int ps3_close_hv_device(struct ps3_device_id *did);
 
 /* dma routines */
 
@@ -357,6 +359,7 @@ struct ps3_system_bus_driver {
 	struct device_driver core;
 	int (*probe)(struct ps3_system_bus_device *);
 	int (*remove)(struct ps3_system_bus_device *);
+	int (*shutdown)(struct ps3_system_bus_device *);
 /*	int (*suspend)(struct ps3_system_bus_device *, pm_message_t); */
 /*	int (*resume)(struct ps3_system_bus_device *); */
 };

linux-2.6-ps3-legacy-bootloader-hack.patch:

--- NEW FILE linux-2.6-ps3-legacy-bootloader-hack.patch ---
A temporary hack to support the legacy 2.6.16 bootloader.  This will be
removed as soon as a 2.6.22 bootloader is ready.

Hacked-by: Geoff Levand <geoffrey levand am sony com>
---
 arch/powerpc/kernel/prom.c         |    6 ++++++
 arch/powerpc/platforms/ps3/setup.c |    4 +++-
 2 files changed, 9 insertions(+), 1 deletion(-)

--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -939,6 +939,12 @@ static int __init early_init_dt_scan_mem
 				size = 0x80000000ul - base;
 		}
 #endif
+#ifdef CONFIG_PPC_PS3
+	/* temporary hack for the legacy bootloader */
+	if (of_flat_dt_is_compatible(of_get_flat_dt_root(), "PS3PF")) {
+		size = 0x8000000;
+	}
+#endif
 		lmb_add(base, size);
 	}
 	return 0;
--- a/arch/powerpc/platforms/ps3/setup.c
+++ b/arch/powerpc/platforms/ps3/setup.c
@@ -210,7 +210,9 @@ static int __init ps3_probe(void)
 	DBG(" -> %s:%d\n", __func__, __LINE__);
 
 	dt_root = of_get_flat_dt_root();
-	if (!of_flat_dt_is_compatible(dt_root, "sony,ps3"))
+	if (!of_flat_dt_is_compatible(dt_root, "sony,ps3")
+		/* temporary hack for the legacy bootloader */
+		&& !of_flat_dt_is_compatible(dt_root, "PS3PF"))
 		return 0;
 
 	powerpc_firmware_features |= FW_FEATURE_PS3_POSSIBLE;

linux-2.6-ps3-legacy-ioport.patch:

--- NEW FILE linux-2.6-ps3-legacy-ioport.patch ---
--- linux-2.6.20.ppc64/arch/powerpc/platforms/ps3/setup.c.orig	2007-03-30 00:45:59.000000000 +0100
+++ linux-2.6.20.ppc64/arch/powerpc/platforms/ps3/setup.c	2007-03-30 00:48:29.000000000 +0100
@@ -230,6 +230,11 @@ static void ps3_machine_kexec(struct kim
 }
 #endif
 
+static int ps3_check_legacy_ioport(unsigned int baseport)
+{
+        return -ENODEV;
+}
+
 define_machine(ps3) {
 	.name				= "PS3",
 	.probe				= ps3_probe,
@@ -240,6 +245,7 @@ define_machine(ps3) {
 	.set_rtc_time			= ps3_set_rtc_time,
 	.get_rtc_time			= ps3_get_rtc_time,
 	.calibrate_decr			= ps3_calibrate_decr,
+	.check_legacy_ioport		= ps3_check_legacy_ioport,
 	.progress			= ps3_progress,
 	.restart			= ps3_restart,
 	.power_off			= ps3_power_off,

linux-2.6-ps3-memory-probe.patch:

--- NEW FILE linux-2.6-ps3-memory-probe.patch ---
--- linux-2.6.20.ppc64/include/asm-powerpc/lmb.h~	2007-02-04 18:44:54.000000000 +0000
+++ linux-2.6.20.ppc64/include/asm-powerpc/lmb.h	2007-03-30 01:13:45.000000000 +0100
@@ -51,6 +51,7 @@ extern unsigned long __init __lmb_alloc_
 extern unsigned long __init lmb_phys_mem_size(void);
 extern unsigned long __init lmb_end_of_DRAM(void);
 extern void __init lmb_enforce_memory_limit(unsigned long memory_limit);
+void __init lmb_reset_available(void);
 
 extern void lmb_dump_all(void);
 
--- linux-2.6.20.ppc64/arch/powerpc/mm/lmb.c~	2007-02-04 18:44:54.000000000 +0000
+++ linux-2.6.20.ppc64/arch/powerpc/mm/lmb.c	2007-03-30 01:12:17.000000000 +0100
@@ -338,3 +338,11 @@ void __init lmb_enforce_memory_limit(uns
 		}
 	}
 }
+
+void __init lmb_reset_available(void)
+{
+	lmb.memory.region[0].base = 0;
+	lmb.memory.region[0].size = 0;
+	lmb.memory.cnt = 1;
+	lmb.memory.size = 0;
+}
--- linux-2.6.20.ppc64/arch/powerpc/platforms/ps3/mm.c~	2007-03-29 17:48:27.000000000 +0100
+++ linux-2.6.20.ppc64/arch/powerpc/platforms/ps3/mm.c	2007-03-30 01:24:04.000000000 +0100
@@ -796,6 +796,9 @@ void __init ps3_mm_init(void)
 
 	DBG(" -> %s:%d\n", __func__, __LINE__);
 
+	/* If an old-style device-tree registered memory, forget it */
+	lmb_reset_available();
+
 	result = ps3_repository_read_mm_info(&map.rm.base, &map.rm.size,
 		&map.total);
 

linux-2.6-ps3-smp-boot.patch:

--- NEW FILE linux-2.6-ps3-smp-boot.patch ---
As of 2007-05-04 (commit 197a8b29cbb721909e1bde44c6e7a588d93ba440):

ps3-wip/powerpc-localize-mmu-off.diff
ps3-wip/powerpc-wait-for-secondary.diff

--- linux-2.6.20.ppc64/arch/powerpc/kernel/head_64.S.orig	2007-04-16 14:40:03.000000000 +0100
+++ linux-2.6.20.ppc64/arch/powerpc/kernel/head_64.S	2007-04-16 14:40:18.000000000 +0100
@@ -103,8 +103,8 @@ __secondary_hold_acknowledge:
 
 	. = 0x60
 /*
- * The following code is used on pSeries to hold secondary processors
- * in a spin loop after they have been freed from OpenFirmware, but
+ * The following code is used to hold secondary processors
+ * in a spin loop after they have entered the kernel, but
  * before the bulk of the kernel has been relocated.  This code
  * is relocated to physical address 0x60 before prom_init is run.
  * All of it must fit below the first exception vector at 0x100.
@@ -1689,9 +1689,32 @@ _GLOBAL(__start_initialization_multiplat
 2:
 
 	/* Switch off MMU if not already */
-	LOAD_REG_IMMEDIATE(r4, .__after_prom_start - KERNELBASE)
+	LOAD_REG_IMMEDIATE(r4, __mmu_off_return - KERNELBASE)
 	add	r4,r4,r30
 	bl	.__mmu_off
+__mmu_off_return:
+
+	/* Test if this is a secondary cpu and if so send it off to
+	 * __secondary_hold with a thread number in r3.  Secondary processors
+	 * call _start with regs r3,r4,r5 zeroed.
+	 * Pass cpu number in r6???
+	 */
+	or.	r3, r31, r30
+	bne	1f
+	li	r3, 1
+	b	.__secondary_hold
+1:
+
+	/* The primary cpu waits here for all the expected secondary cpus to
+	 * enter the kernel, after which time it is safe to reclaim the
+	 * memory use by the bootwrapper.
+	 * How to know what to wait for???
+	 * !!! need to use the kexec entry mechanism here!!!!
+	*/
+1:	LOAD_REG_IMMEDIATE(r4, __secondary_hold_acknowledge)
+	cmpwi	r4, 0
+	beq	1b
+	mr	r3, r30
 	b	.__after_prom_start
 
 _STATIC(__boot_from_prom)

linux-2.6-ps3-sound-autoload.patch:

--- NEW FILE linux-2.6-ps3-sound-autoload.patch ---
--- linux-2.6.21.ppc64/sound/ppc/snd_ps3.c~	2007-05-04 15:14:46.000000000 +0100
+++ linux-2.6.21.ppc64/sound/ppc/snd_ps3.c	2007-05-04 15:47:10.000000000 +0100
@@ -45,6 +45,7 @@
 MODULE_LICENSE("GPL v2");
 MODULE_DESCRIPTION("PS3 sound driver");
 MODULE_AUTHOR("Sony Computer Entertainment Inc.");
+MODULE_ALIAS("ps3:9");
 
 static int index = SNDRV_DEFAULT_IDX1;
 static char *id = SNDRV_DEFAULT_STR1;

linux-2.6-ps3-sound.patch:

--- NEW FILE linux-2.6-ps3-sound.patch ---
As of 2007-05-04 (commit 197a8b29cbb721909e1bde44c6e7a588d93ba440):

ps3-wip/ps3snd-core.diff
ps3-wip/ps3snd-bugfix.diff
ps3-wip/ps3snd-glue-2.6.20.diff
ps3-wip/ps3snd-core-2.6.20-version-up.diff
ps3-wip/ps3snd-lv1-returns-int.diff
ps3-wip/ps3snd-kill-iopte-failure.diff
ps3-wip/ps3snd-fix-noise.diff
ps3-wip/ps3snd-fix-style.diff

ps3-wip/ps3-ioc0-dma-sound.diff

unchanged:
--- a/include/asm-powerpc/lv1call.h
+++ b/include/asm-powerpc/lv1call.h
@@ -238,6 +238,7 @@ LV1_CALL(destruct_virtual_address_space,                1, 0,  10 )
 LV1_CALL(configure_irq_state_bitmap,                    3, 0,  11 )
 LV1_CALL(connect_irq_plug_ext,                          5, 0,  12 )
 LV1_CALL(release_memory,                                1, 0,  13 )
+LV1_CALL(put_iopte,                                     5, 0,  15 )
 LV1_CALL(disconnect_irq_plug_ext,                       3, 0,  17 )
 LV1_CALL(construct_event_receive_port,                  0, 1,  18 )
 LV1_CALL(destruct_event_receive_port,                   1, 0,  19 )
@@ -268,6 +269,8 @@ LV1_CALL(remove_repository_node,                        4, 0,  93 )
 LV1_CALL(read_htab_entries,                             2, 5,  95 )
 LV1_CALL(set_dabr,                                      2, 0,  96 )
 LV1_CALL(get_total_execution_time,                      2, 1, 103 )
+LV1_CALL(allocate_io_segment,                           3, 1, 116 )
+LV1_CALL(release_io_segment,                            2, 0, 117 )
 LV1_CALL(construct_io_irq_outlet,                       1, 1, 120 )
 LV1_CALL(destruct_io_irq_outlet,                        1, 0, 121 )
 LV1_CALL(map_htab,                                      1, 1, 122 )
unchanged:
--- a/sound/ppc/Kconfig
+++ b/sound/ppc/Kconfig
@@ -33,3 +33,23 @@ config SND_POWERMAC_AUTO_DRC
 	  option.
 
 endmenu
+
+menu "ALSA PowerPC devices"
+	depends on SND!=n && ( PPC64 || PPC32 )
+
+config SND_PS3
+	tristate "PS3 Audio support"
+	depends on SND && PS3_PS3AV
+	select SND_PCM
+	default m
+	help
+	  Say Y here to include support for audio on the PS3
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called snd_ps3.
+
+config SND_PS3_DEFAULT_START_DELAY
+	int "Startup delay time in ms"
+	depends on SND_PS3
+	default "2000"
+endmenu
unchanged:
--- a/sound/ppc/Makefile
+++ b/sound/ppc/Makefile
@@ -6,4 +6,5 @@
 snd-powermac-objs := powermac.o pmac.o awacs.o burgundy.o daca.o tumbler.o keywest.o beep.o
 
 # Toplevel Module Dependency
-obj-$(CONFIG_SND_POWERMAC) += snd-powermac.o
+obj-$(CONFIG_SND_POWERMAC)	+= snd-powermac.o
+obj-$(CONFIG_SND_PS3)		+= snd_ps3.o
diff -u b/sound/ppc/snd_ps3.c ps3-linux-dev/sound/ppc/snd_ps3.c
--- b/sound/ppc/snd_ps3.c	2007-05-04 12:30:20.000000000 +0100
+++ ps3-linux-dev/sound/ppc/snd_ps3.c
@@ -0,0 +1,1304 @@
+/*
+ * Audio support for PS3
+ * Copyright (C) 2007 Sony Computer Entertainment Inc.
+ * All rights reserved.
+ * Copyright 2006, 2007 Sony Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2 of the Licence.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#define DEBUG
+#undef _SND_PS3_DEV_ATTR
+
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <sound/driver.h>
+#include <sound/core.h>
+#include <sound/initval.h>
+#include <sound/pcm.h>
+#include <sound/asound.h>
+#include <sound/memalloc.h>
+#include <sound/pcm_params.h>
+#include <sound/control.h>
+#include <linux/dmapool.h>
+#include <linux/dma-mapping.h>
+#include <asm/firmware.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+#include <asm/lv1call.h>
+#include <asm/ps3.h>
+#include <asm/ps3av.h>
+
+#include "snd_ps3_reg.h"
+#include "snd_ps3.h"
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("PS3 sound driver");
+MODULE_AUTHOR("Sony Computer Entertainment Inc.");
+
+static int index = SNDRV_DEFAULT_IDX1;
+static char *id = SNDRV_DEFAULT_STR1;
+
+module_param(index, int, 0444);
+MODULE_PARM_DESC(index, "Index value for PS3 soundchip.");
+module_param(id, charp, 0444);
+MODULE_PARM_DESC(id, "ID string for PS3 soundchip.");
+
+
+module_init(snd_ps3_init);
+module_exit(snd_ps3_exit);
+
+
+#if defined(_SND_PS3_DEV_ATTR)
+static DEVICE_ATTR(start_delay,
+		   S_IRUGO | S_IWUSR,
+		   snd_ps3_get_start_delay,
+		   snd_ps3_set_start_delay);
+#endif
+
+/*
+ * global
+ */
+struct snd_ps3_card_info the_card;
+
+static int snd_ps3_start_delay = CONFIG_SND_PS3_DEFAULT_START_DELAY;
+
+module_param_named(start_delay, snd_ps3_start_delay, int, 0444);
+MODULE_PARM_DESC(start_delay, "time to insert silent data in milisec");
+
+/*
+ * PS3 audio register access macros
+ */
+
+/*
+ * chip: pointer to snd_ps3_card_info
+ * name: register offset value; PS3_AUDIO_XXXX
+ */
+#define AUDIOREGPTR(chip, name) \
+	(volatile uint32_t *)(chip->mapped_mmio_vaddr + name)
+
+#define AUDIOREG(chip, name) *(AUDIOREGPTR(chip, name))
+
+/*
+ * ALSA defs
+ */
+const static struct snd_pcm_hardware snd_ps3_pcm_hw = {
+        .info = (SNDRV_PCM_INFO_MMAP |
+                 SNDRV_PCM_INFO_NONINTERLEAVED |
+                 SNDRV_PCM_INFO_MMAP_VALID),
+        .formats = (SNDRV_PCM_FMTBIT_S16_BE |
+		    SNDRV_PCM_FMTBIT_S24_BE),
+        .rates = (SNDRV_PCM_RATE_44100 |
+		  SNDRV_PCM_RATE_48000 |
+		  SNDRV_PCM_RATE_88200 |
+		  SNDRV_PCM_RATE_96000),
+        .rate_min = 44100,
+        .rate_max = 96000,
+
+        .channels_min = 2, /* stereo only */
+        .channels_max = 2,
+
+        .buffer_bytes_max = PS3_AUDIO_FIFO_SIZE * 64,
+
+	/* interrupt by four stages */
+        .period_bytes_min = PS3_AUDIO_FIFO_STAGE_SIZE * 4,
+        .period_bytes_max = PS3_AUDIO_FIFO_STAGE_SIZE * 4,
+
+        .periods_min = 16,
+	.periods_max = 32, /* buffer_size_max/ period_bytes_max */
+
+	.fifo_size = PS3_AUDIO_FIFO_SIZE
+};
+
[...2050 lines suppressed...]
+Configures user bit settings for each block (384 bits).
+Output is performed from the MSB(ao_spdub0 register bit 31).
+
+
+ 31            24 23           16 15            8 7             0
+ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
+ |                             SPOUB                             | AO_SPDUB
+ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
+*/
+/*******************************************************************************
+ *
+ * DMAC register
+ *
+ *******************************************************************************/
+/*
+The PS3_AUDIO_KICK register is used to initiate a DMA transfer and monitor its status
+
+
+ 31            24 23           16 15            8 7             0
+ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
+ |0 0 0 0 0|STATU|0 0 0|  EVENT  |0 0 0 0 0 0 0 0 0 0 0 0 0 0 0|R| KICK
+ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
+*/
+/*
+The REQUEST field is written to ACTIVE to initiate a DMA request when EVENT occurs.
+It will return to the DONE state when the request is completed.
+The registers for a DMA channel should only be written if REQUEST is IDLE.
+*/
+
+#define PS3_AUDIO_KICK_REQUEST                           (1 << 0) /* RWIVF */
+#define PS3_AUDIO_KICK_REQUEST_IDLE                      (0 << 0) /* RWI-V */
+#define PS3_AUDIO_KICK_REQUEST_ACTIVE                    (1 << 0) /* -W--T */
+
+/* The EVENT field is used to set the event in which the DMA request becomes active. */
+#define PS3_AUDIO_KICK_EVENT_MASK                        (0x1f << 16) /* RWIVF */
+#define PS3_AUDIO_KICK_EVENT_ALWAYS                      (0x00 << 16) /* RWI-V */
+#define PS3_AUDIO_KICK_EVENT_SERIALOUT0_EMPTY            (0x01 << 16) /* RW--V */
+#define PS3_AUDIO_KICK_EVENT_SERIALOUT0_UNDERFLOW        (0x02 << 16) /* RW--V */
+#define PS3_AUDIO_KICK_EVENT_SERIALOUT1_EMPTY            (0x03 << 16) /* RW--V */
+#define PS3_AUDIO_KICK_EVENT_SERIALOUT1_UNDERFLOW        (0x04 << 16) /* RW--V */
+#define PS3_AUDIO_KICK_EVENT_SERIALOUT2_EMPTY            (0x05 << 16) /* RW--V */
+#define PS3_AUDIO_KICK_EVENT_SERIALOUT2_UNDERFLOW        (0x06 << 16) /* RW--V */
+#define PS3_AUDIO_KICK_EVENT_SERIALOUT3_EMPTY            (0x07 << 16) /* RW--V */
+#define PS3_AUDIO_KICK_EVENT_SERIALOUT3_UNDERFLOW        (0x08 << 16) /* RW--V */
+#define PS3_AUDIO_KICK_EVENT_SPDIF0_BLOCKTRANSFERCOMPLETE (0x09 << 16) /* RW--V */
+#define PS3_AUDIO_KICK_EVENT_SPDIF0_UNDERFLOW            (0x0A << 16) /* RW--V */
+#define PS3_AUDIO_KICK_EVENT_SPDIF0_EMPTY                (0x0B << 16) /* RW--V */
+#define PS3_AUDIO_KICK_EVENT_SPDIF1_BLOCKTRANSFERCOMPLETE (0x0C << 16) /* RW--V */
+#define PS3_AUDIO_KICK_EVENT_SPDIF1_UNDERFLOW            (0x0D << 16) /* RW--V */
+#define PS3_AUDIO_KICK_EVENT_SPDIF1_EMPTY                (0x0E << 16) /* RW--V */
+
+#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA(n)                ((0x13 + (n)) << 16) /* RW--V */
+#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA0                  (0x13 << 16) /* RW--V */
+#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA1                  (0x14 << 16) /* RW--V */
+#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA2                  (0x15 << 16) /* RW--V */
+#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA3                  (0x16 << 16) /* RW--V */
+#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA4                  (0x17 << 16) /* RW--V */
+#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA5                  (0x18 << 16) /* RW--V */
+#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA6                  (0x19 << 16) /* RW--V */
+#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA7                  (0x1A << 16) /* RW--V */
+#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA8                  (0x1B << 16) /* RW--V */
+#define PS3_AUDIO_KICK_EVENT_AUDIO_DMA9                  (0x1C << 16) /* RW--V */
+
+/*
+The STATUS field can be used to monitor the progress of a DMA request.
+DONE indicates the previous request has completed.
+EVENT indicates that the DMA engine is waiting for the EVENT to occur.
+PENDING indicates that the DMA engine has not started processing this
+request, but the EVENT has occured.
+DMA indicates that the data transfer is in progress.
+NOTIFY indicates that the notifier signalling end of transfer is being written.
+CLEAR indicated that the previous transfer was cleared.
+ERROR indicates the previous transfer requested an unsupported source/destination combination.
+*/
+
+#define PS3_AUDIO_KICK_STATUS_MASK                       (0x7 << 24) /* R-IVF */
+#define PS3_AUDIO_KICK_STATUS_DONE                       (0x0 << 24) /* R-I-V */
+#define PS3_AUDIO_KICK_STATUS_EVENT                      (0x1 << 24) /* R---V */
+#define PS3_AUDIO_KICK_STATUS_PENDING                    (0x2 << 24) /* R---V */
+#define PS3_AUDIO_KICK_STATUS_DMA                        (0x3 << 24) /* R---V */
+#define PS3_AUDIO_KICK_STATUS_NOTIFY                     (0x4 << 24) /* R---V */
+#define PS3_AUDIO_KICK_STATUS_CLEAR                      (0x5 << 24) /* R---V */
+#define PS3_AUDIO_KICK_STATUS_ERROR                      (0x6 << 24) /* R---V */
+
+/*
+The PS3_AUDIO_SOURCE register specifies the source address for transfers.
+
+
+ 31            24 23           16 15            8 7             0
+ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
+ |                      START                      |0 0 0 0 0|TAR| SOURCE
+ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
+*/
+
+/*
+The Audio DMA engine uses 128-byte transfers, thus the address must be aligned
+to a 128 byte boundary.  The low seven bits are assumed to be 0.
+*/
+
+#define PS3_AUDIO_SOURCE_START_MASK                      (0x01FFFFFF << 7) /* RWIUF */
+
+/*
+The TARGET field specifies the memory space containing the source address.
+*/
+
+#define PS3_AUDIO_SOURCE_TARGET_MASK                     (3 << 0) /* RWIVF */
+#define PS3_AUDIO_SOURCE_TARGET_SYSTEM_MEMORY            (2 << 0) /* RW--V */
+
+/*
+The PS3_AUDIO_DEST register specifies the destination address for transfers.
+
+
+ 31            24 23           16 15            8 7             0
+ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
+ |                      START                      |0 0 0 0 0|TAR| DEST
+ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
+*/
+
+/*
+The Audio DMA engine uses 128-byte transfers, thus the address must be aligned
+to a 128 byte boundary.  The low seven bits are assumed to be 0.
+*/
+
+#define PS3_AUDIO_DEST_START_MASK                       (0x01FFFFFF << 7) /* RWIUF */
+
+/*
+The TARGET field specifies the memory space containing the destination address
+AUDIOFIFO = Audio WriteData FIFO,
+*/
+
+#define PS3_AUDIO_DEST_TARGET_MASK                       (3 << 0) /* RWIVF */
+#define PS3_AUDIO_DEST_TARGET_AUDIOFIFO                  (1 << 0) /* RW--V */
+
+/*
+PS3_AUDIO_DMASIZE specifies the number of 128-byte blocks + 1 to transfer.
+So a value of 0 means 128-bytes will get transfered.
+
+
+ 31            24 23           16 15            8 7             0
+ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
+ |0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0|   BLOCKS    | DMASIZE
+ +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
+*/
+
+
+#define PS3_AUDIO_DMASIZE_BLOCKS_MASK                    (0x7f << 0) /* RWIUF */
+
+/*
+ * source/destination address for internal fifos
+ */
+#define PS3_AUDIO_AO_3W_LDATA(n)                         (0x1000 + (0x100 * (n)))
+#define PS3_AUDIO_AO_3W_RDATA(n)                         (0x1080 + (0x100 * (n)))
+
+#define PS3_AUDIO_AO_SPD_DATA(n)                         (0x2000 + (0x400 * (n)))
+
+
+/************************************************************************
+ field attiribute
+
+	Read
+	  ' ' = Other Information
+	  '-' = Field is part of a write-only register
+	  'C' = Value read is always the same, constant value line follows (C)
+	  'R' = Value is read
+
+	Write
+	  ' ' = Other Information
+	  '-' = Must not be written (D), value ignored when written (R,A,F)
+	  'W' = Can be written
+
+	Internal State
+	  ' ' = Other Information
+	  '-' = No internal state
+	  'X' = Internal state, initial value is unknown
+	  'I' = Internal state, initial value is known and follows (I)
+
+	Declaration/Size
+	  ' ' = Other Information
+	  '-' = Does Not Apply
+	  'V' = Type is void
+	  'U' = Type is unsigned integer
+	  'S' = Type is signed integer
+	  'F' = Type is IEEE floating point
+	  '1' = Byte size (008)
+	  '2' = Short size (016)
+	  '3' = Three byte size (024)
+	  '4' = Word size (032)
+	  '8' = Double size (064)
+
+	Define Indicator
+	  ' ' = Other Information
+	  'D' = Device
+	  'M' = Memory
+	  'R' = Register
+	  'A' = Array of Registers
+	  'F' = Field
+	  'V' = Value
+          'T' = Task
+
+ **********************************************************************/

linux-2.6-ps3-stable-patches.patch:

--- NEW FILE linux-2.6-ps3-stable-patches.patch ---
All patches in ps3-stable/*.diff of ps3-linux-patches.git as of 
2007-05-04 (commit 197a8b29cbb721909e1bde44c6e7a588d93ba440).

ps3-stable/ps3-remove-bogus-dev-dbg-defs.diff
ps3-stable/ps3-fix-hardware-watchpoints.diff
ps3-stable/ps3-remove-extra-assignment.diff
ps3-stable/ps3-replace-irq-alloc-free.diff
ps3-stable/ps3-fix-slowdown-bug.diff
#ps3-stable/ps3-def-config-updates.diff

ps3-stable/ps3fb-kthread.diff
ps3-stable/ps3fb-atomic.diff
ps3-stable/ps3av-workqueue.diff
ps3-stable/ps3fb-zero-init.diff
ps3-stable/ps3av-misc.diff
ps3-stable/ps3videomode-auto-mode.diff
ps3-stable/ps3fb-__func__.diff
ps3-stable/ps3av-__func__.diff


diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 6c83fe2..5719a53 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -67,6 +67,7 @@
 #ifdef CONFIG_PPC64
 #include <asm/paca.h>
 #include <asm/firmware.h>
+#include <asm/lv1call.h>
 #endif
 
 int __irq_offset_value;
@@ -162,6 +163,16 @@ void local_irq_restore(unsigned long en)
 	local_paca->hard_enabled = en;
 	if ((int)mfspr(SPRN_DEC) < 0)
 		mtspr(SPRN_DEC, 1);
+
+	/*
+	 * Force the delivery of pending soft-disabled interrupts on PS3.
+	 * Any HV call will have this side effect.
+	 */
+	if (firmware_has_feature(FW_FEATURE_PS3_LV1)) {
+		u64 tmp;
+		lv1_get_version_info(&tmp);
+	}
+
 	hard_irq_enable();
 }
 #endif /* CONFIG_PPC64 */
diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c
index 631c300..9da82c2 100644
--- a/arch/powerpc/platforms/ps3/interrupt.c
+++ b/arch/powerpc/platforms/ps3/interrupt.c
@@ -89,7 +89,18 @@ struct ps3_private {
 
 static DEFINE_PER_CPU(struct ps3_private, ps3_private);
 
-int ps3_alloc_irq(enum ps3_cpu_binding cpu, unsigned long outlet,
+/**
+ * ps3_virq_setup - virq related setup.
+ * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
+ * serviced on.
+ * @outlet: The HV outlet from the various create outlet routines.
+ * @virq: The assigned Linux virq.
+ *
+ * Calls irq_create_mapping() to get a virq and sets the chip data to
+ * ps3_private data.
+ */
+
+int ps3_virq_setup(enum ps3_cpu_binding cpu, unsigned long outlet,
 	unsigned int *virq)
 {
 	int result;
@@ -111,17 +122,6 @@ int ps3_alloc_irq(enum ps3_cpu_binding cpu, unsigned long outlet,
 		goto fail_create;
 	}
 
-	/* Binds outlet to cpu + virq. */
-
-	result = lv1_connect_irq_plug_ext(pd->node, pd->cpu, *virq, outlet, 0);
-
-	if (result) {
-		pr_info("%s:%d: lv1_connect_irq_plug_ext failed: %s\n",
-		__func__, __LINE__, ps3_result(result));
-		result = -EPERM;
-		goto fail_connect;
-	}
-
 	pr_debug("%s:%d: outlet %lu => cpu %u, virq %u\n", __func__, __LINE__,
 		outlet, cpu, *virq);
 
@@ -136,94 +136,118 @@ int ps3_alloc_irq(enum ps3_cpu_binding cpu, unsigned long outlet,
 	return result;
 
 fail_set:
-	lv1_disconnect_irq_plug_ext(pd->node, pd->cpu, *virq);
-fail_connect:
 	irq_dispose_mapping(*virq);
 fail_create:
 	return result;
 }
-EXPORT_SYMBOL_GPL(ps3_alloc_irq);
 
-int ps3_free_irq(unsigned int virq)
+/**
+ * ps3_virq_destroy - virq related teardown.
+ * @virq: The assigned Linux virq.
+ *
+ * Clears chip data and calls irq_dispose_mapping() for the virq.
+ */
+
+int ps3_virq_destroy(unsigned int virq)
 {
-	int result;
 	const struct ps3_private *pd = get_irq_chip_data(virq);
 
 	pr_debug("%s:%d: node %lu, cpu %d, virq %u\n", __func__, __LINE__,
 		pd->node, pd->cpu, virq);
 
-	result = lv1_disconnect_irq_plug_ext(pd->node, pd->cpu, virq);
-
-	if (result)
-		pr_info("%s:%d: lv1_disconnect_irq_plug_ext failed: %s\n",
-		__func__, __LINE__, ps3_result(result));
-
 	set_irq_chip_data(virq, NULL);
 	irq_dispose_mapping(virq);
-	return result;
+
+	pr_debug("%s:%d <-\n", __func__, __LINE__);
+	return 0;
 }
-EXPORT_SYMBOL_GPL(ps3_free_irq);
 
 /**
- * ps3_alloc_io_irq - Assign a virq to a system bus device.
+ * ps3_irq_plug_setup - Generic outlet and virq related setup.
  * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
  * serviced on.
- * @interrupt_id: The device interrupt id read from the system repository.
+ * @outlet: The HV outlet from the various create outlet routines.
  * @virq: The assigned Linux virq.
  *
- * An io irq represents a non-virtualized device interrupt.  interrupt_id
- * coresponds to the interrupt number of the interrupt controller.
+ * Sets up virq and connects the irq plug.
  */
 
-int ps3_alloc_io_irq(enum ps3_cpu_binding cpu, unsigned int interrupt_id,
+int ps3_irq_plug_setup(enum ps3_cpu_binding cpu, unsigned long outlet,
 	unsigned int *virq)
 {
 	int result;
-	unsigned long outlet;
+	struct ps3_private *pd;
 
-	result = lv1_construct_io_irq_outlet(interrupt_id, &outlet);
+	result = ps3_virq_setup(cpu, outlet, virq);
 
 	if (result) {
-		pr_debug("%s:%d: lv1_construct_io_irq_outlet failed: %s\n",
-			__func__, __LINE__, ps3_result(result));
-		return result;
+		pr_debug("%s:%d: ps3_virq_setup failed\n", __func__, __LINE__);
+		goto fail_setup;
 	}
 
-	result = ps3_alloc_irq(cpu, outlet, virq);
-	BUG_ON(result);
+	pd = get_irq_chip_data(*virq);
+
+	/* Binds outlet to cpu + virq. */
+
+	result = lv1_connect_irq_plug_ext(pd->node, pd->cpu, *virq, outlet, 0);
 
+	if (result) {
+		pr_info("%s:%d: lv1_connect_irq_plug_ext failed: %s\n",
+		__func__, __LINE__, ps3_result(result));
+		result = -EPERM;
+		goto fail_connect;
+	}
+
+	return result;
+
+fail_connect:
+	ps3_virq_destroy(*virq);
+fail_setup:
 	return result;
 }
-EXPORT_SYMBOL_GPL(ps3_alloc_io_irq);
+EXPORT_SYMBOL_GPL(ps3_irq_plug_setup);
+
+/**
+ * ps3_irq_plug_destroy - Generic outlet and virq related teardown.
+ * @virq: The assigned Linux virq.
+ *
+ * Disconnects the irq plug and tears down virq.
+ * Do not call for system bus event interrupts setup with
+ * ps3_sb_event_receive_port_setup().
+ */
 
-int ps3_free_io_irq(unsigned int virq)
+int ps3_irq_plug_destroy(unsigned int virq)
 {
 	int result;
+	const struct ps3_private *pd = get_irq_chip_data(virq);
 
-	result = lv1_destruct_io_irq_outlet(virq_to_hw(virq));
+	pr_debug("%s:%d: node %lu, cpu %d, virq %u\n", __func__, __LINE__,
+		pd->node, pd->cpu, virq);
+
+	result = lv1_disconnect_irq_plug_ext(pd->node, pd->cpu, virq);
 
 	if (result)
-		pr_debug("%s:%d: lv1_destruct_io_irq_outlet failed: %s\n",
-			__func__, __LINE__, ps3_result(result));
+		pr_info("%s:%d: lv1_disconnect_irq_plug_ext failed: %s\n",
+		__func__, __LINE__, ps3_result(result));
 
-	ps3_free_irq(virq);
+	ps3_virq_destroy(virq);
 
 	return result;
 }
-EXPORT_SYMBOL_GPL(ps3_free_io_irq);
+EXPORT_SYMBOL_GPL(ps3_irq_plug_destroy);
 
 /**
- * ps3_alloc_event_irq - Allocate a virq for use with a system event.
+ * ps3_event_receive_port_setup - Setup an event receive port.
  * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
  * serviced on.
  * @virq: The assigned Linux virq.
  *
  * The virq can be used with lv1_connect_interrupt_event_receive_port() to
- * arrange to receive events, or with ps3_send_event_locally() to signal
- * events.
+ * arrange to receive interrupts from system-bus devices, or with
+ * ps3_send_event_locally() to signal events.
  */
 
-int ps3_alloc_event_irq(enum ps3_cpu_binding cpu, unsigned int *virq)
+int ps3_event_receive_port_setup(enum ps3_cpu_binding cpu, unsigned int *virq)
 {
 	int result;
 	unsigned long outlet;
@@ -237,17 +261,27 @@ int ps3_alloc_event_irq(enum ps3_cpu_binding cpu, unsigned int *virq)
 		return result;
 	}
 
-	result = ps3_alloc_irq(cpu, outlet, virq);
+	result = ps3_irq_plug_setup(cpu, outlet, virq);
 	BUG_ON(result);
 
 	return result;
 }
+EXPORT_SYMBOL_GPL(ps3_event_receive_port_setup);
+
+/**
+ * ps3_event_receive_port_destroy - Destroy an event receive port.
+ * @virq: The assigned Linux virq.
+ *
+ * Since ps3_event_receive_port_destroy destroys the receive port outlet,
+ * SB devices need to call disconnect_interrupt_event_receive_port() before
+ * this.
+ */
 
-int ps3_free_event_irq(unsigned int virq)
+int ps3_event_receive_port_destroy(unsigned int virq)
 {
 	int result;
 
-	pr_debug(" -> %s:%d\n", __func__, __LINE__);
+	pr_debug(" -> %s:%d virq: %u\n", __func__, __LINE__, virq);
 
 	result = lv1_destruct_event_receive_port(virq_to_hw(virq));
 
@@ -255,11 +289,17 @@ int ps3_free_event_irq(unsigned int virq)
 		pr_debug("%s:%d: lv1_destruct_event_receive_port failed: %s\n",
 			__func__, __LINE__, ps3_result(result));
 
-	ps3_free_irq(virq);
+	/* lv1_destruct_event_receive_port() destroys the IRQ plug,
+	 * so don't call ps3_irq_plug_destroy() here.
+	 */
+
+	result = ps3_virq_destroy(virq);
+	BUG_ON(result);
 
 	pr_debug(" <- %s:%d\n", __func__, __LINE__);
 	return result;
 }
+EXPORT_SYMBOL_GPL(ps3_event_receive_port_destroy);
 
 int ps3_send_event_locally(unsigned int virq)
 {
@@ -267,7 +307,7 @@ int ps3_send_event_locally(unsigned int virq)
 }
 
 /**
- * ps3_connect_event_irq - Assign a virq to a system bus device.
+ * ps3_sb_event_receive_port_setup - Setup a system bus event receive port.
  * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
  * serviced on.
  * @did: The HV device identifier read from the system repository.
@@ -278,13 +318,15 @@ int ps3_send_event_locally(unsigned int virq)
  * coresponds to the software interrupt number.
  */
 
-int ps3_connect_event_irq(enum ps3_cpu_binding cpu,
+int ps3_sb_event_receive_port_setup(enum ps3_cpu_binding cpu,
 	const struct ps3_device_id *did, unsigned int interrupt_id,
 	unsigned int *virq)
 {
+	/* this should go in system-bus.c */
+
 	int result;
 
-	result = ps3_alloc_event_irq(cpu, virq);
+	result = ps3_event_receive_port_setup(cpu, virq);
 
 	if (result)
 		return result;
@@ -296,7 +338,7 @@ int ps3_connect_event_irq(enum ps3_cpu_binding cpu,
 		pr_debug("%s:%d: lv1_connect_interrupt_event_receive_port"
 			" failed: %s\n", __func__, __LINE__,
 			ps3_result(result));
-		ps3_free_event_irq(*virq);
+		ps3_event_receive_port_destroy(*virq);
 		*virq = NO_IRQ;
 		return result;
 	}
@@ -306,10 +348,13 @@ int ps3_connect_event_irq(enum ps3_cpu_binding cpu,
 
 	return 0;
 }
+EXPORT_SYMBOL(ps3_sb_event_receive_port_setup);
 
-int ps3_disconnect_event_irq(const struct ps3_device_id *did,
+int ps3_sb_event_receive_port_destroy(const struct ps3_device_id *did,
 	unsigned int interrupt_id, unsigned int virq)
 {
+	/* this should go in system-bus.c */
+
 	int result;
 
 	pr_debug(" -> %s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__,
@@ -323,14 +368,65 @@ int ps3_disconnect_event_irq(const struct ps3_device_id *did,
 			" failed: %s\n", __func__, __LINE__,
 			ps3_result(result));
 
-	ps3_free_event_irq(virq);
+	result = ps3_event_receive_port_destroy(virq);
+	BUG_ON(result);
 
 	pr_debug(" <- %s:%d\n", __func__, __LINE__);
 	return result;
 }
+EXPORT_SYMBOL(ps3_sb_event_receive_port_destroy);
 
 /**
- * ps3_alloc_vuart_irq - Configure the system virtual uart virq.
+ * ps3_io_irq_setup - Setup a system bus io irq.
+ * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
+ * serviced on.
+ * @interrupt_id: The device interrupt id read from the system repository.
+ * @virq: The assigned Linux virq.
+ *
+ * An io irq represents a non-virtualized device interrupt.  interrupt_id
+ * coresponds to the interrupt number of the interrupt controller.
+ */
+
+int ps3_io_irq_setup(enum ps3_cpu_binding cpu, unsigned int interrupt_id,
+	unsigned int *virq)
+{
+	int result;
+	unsigned long outlet;
+
+	result = lv1_construct_io_irq_outlet(interrupt_id, &outlet);
+
+	if (result) {
+		pr_debug("%s:%d: lv1_construct_io_irq_outlet failed: %s\n",
+			__func__, __LINE__, ps3_result(result));
+		return result;
+	}
+
+	result = ps3_irq_plug_setup(cpu, outlet, virq);
+	BUG_ON(result);
+
+	return result;
+}
+EXPORT_SYMBOL_GPL(ps3_io_irq_setup);
+
+int ps3_io_irq_destroy(unsigned int virq)
+{
+	int result;
+
+	result = lv1_destruct_io_irq_outlet(virq_to_hw(virq));
+
+	if (result)
+		pr_debug("%s:%d: lv1_destruct_io_irq_outlet failed: %s\n",
+			__func__, __LINE__, ps3_result(result));
+
+	result = ps3_irq_plug_destroy(virq);
+	BUG_ON(result);
+
+	return result;
+}
+EXPORT_SYMBOL_GPL(ps3_io_irq_destroy);
+
+/**
+ * ps3_vuart_irq_setup - Setup the system virtual uart virq.
  * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
  * serviced on.
  * @virt_addr_bmp: The caller supplied virtual uart interrupt bitmap.
@@ -340,7 +436,7 @@ int ps3_disconnect_event_irq(const struct ps3_device_id *did,
  * freeing the interrupt will return a wrong state error.
  */
 
-int ps3_alloc_vuart_irq(enum ps3_cpu_binding cpu, void* virt_addr_bmp,
+int ps3_vuart_irq_setup(enum ps3_cpu_binding cpu, void* virt_addr_bmp,
 	unsigned int *virq)
 {
 	int result;
@@ -359,13 +455,13 @@ int ps3_alloc_vuart_irq(enum ps3_cpu_binding cpu, void* virt_addr_bmp,
 		return result;
 	}
 
-	result = ps3_alloc_irq(cpu, outlet, virq);
+	result = ps3_irq_plug_setup(cpu, outlet, virq);
 	BUG_ON(result);
 
 	return result;
 }
 
-int ps3_free_vuart_irq(unsigned int virq)
+int ps3_vuart_irq_destroy(unsigned int virq)
 {
 	int result;
 
@@ -377,13 +473,14 @@ int ps3_free_vuart_irq(unsigned int virq)
 		return result;
 	}
 
-	ps3_free_irq(virq);
+	result = ps3_irq_plug_destroy(virq);
+	BUG_ON(result);
 
 	return result;
 }
 
 /**
- * ps3_alloc_spe_irq - Configure an spe virq.
+ * ps3_spe_irq_setup - Setup an spe virq.
  * @cpu: enum ps3_cpu_binding indicating the cpu the interrupt should be
  * serviced on.
  * @spe_id: The spe_id returned from lv1_construct_logical_spe().
@@ -392,7 +489,7 @@ int ps3_free_vuart_irq(unsigned int virq)
  *
  */
 
-int ps3_alloc_spe_irq(enum ps3_cpu_binding cpu, unsigned long spe_id,
+int ps3_spe_irq_setup(enum ps3_cpu_binding cpu, unsigned long spe_id,
 	unsigned int class, unsigned int *virq)
 {
 	int result;
@@ -408,15 +505,16 @@ int ps3_alloc_spe_irq(enum ps3_cpu_binding cpu, unsigned long spe_id,
 		return result;
 	}
 
-	result = ps3_alloc_irq(cpu, outlet, virq);
+	result = ps3_irq_plug_setup(cpu, outlet, virq);
 	BUG_ON(result);
 
 	return result;
 }
 
-int ps3_free_spe_irq(unsigned int virq)
+int ps3_spe_irq_destroy(unsigned int virq)
 {
-	ps3_free_irq(virq);
+	int result = ps3_irq_plug_destroy(virq);
+	BUG_ON(result);
 	return 0;
 }
 
diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c
index 2014d2b..f8a3e20 100644
--- a/arch/powerpc/platforms/ps3/mm.c
+++ b/arch/powerpc/platforms/ps3/mm.c
@@ -826,5 +826,4 @@ void __init ps3_mm_init(void)
 void ps3_mm_shutdown(void)
 {
 	ps3_mm_region_destroy(&map.r1);
-	map.total = map.rm.size;
 }
diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c
index ac5df96..c989493 100644
--- a/arch/powerpc/platforms/ps3/setup.c
+++ b/arch/powerpc/platforms/ps3/setup.c
@@ -137,6 +137,12 @@ early_param("ps3fb", early_parse_ps3fb);
 #define prealloc_ps3fb_videomemory()	do { } while (0)
 #endif
 
+static int ps3_set_dabr(u64 dabr)
+{
+	enum {DABR_USER = 1, DABR_KERNEL = 2,};
+
+	return lv1_set_dabr(dabr, DABR_KERNEL | DABR_USER) ? -1 : 0;
+}
 
 static void __init ps3_setup_arch(void)
 {
@@ -234,6 +240,7 @@ define_machine(ps3) {
 	.get_boot_time			= ps3_get_boot_time,
 	.set_rtc_time			= ps3_set_rtc_time,
 	.get_rtc_time			= ps3_get_rtc_time,
+	.set_dabr			= ps3_set_dabr,
 	.calibrate_decr			= ps3_calibrate_decr,
 	.progress			= ps3_progress,
 	.restart			= ps3_restart,
diff --git a/arch/powerpc/platforms/ps3/smp.c b/arch/powerpc/platforms/ps3/smp.c
index 6fb8879..8729348 100644
--- a/arch/powerpc/platforms/ps3/smp.c
+++ b/arch/powerpc/platforms/ps3/smp.c
@@ -110,7 +110,7 @@ static void __init ps3_smp_setup_cpu(int cpu)
 	BUILD_BUG_ON(PPC_MSG_DEBUGGER_BREAK != 3);
 
 	for (i = 0; i < MSG_COUNT; i++) {
-		result = ps3_alloc_event_irq(cpu, &virqs[i]);
+		result = ps3_event_receive_port_setup(cpu, &virqs[i]);
 
 		if (result)
 			continue;
@@ -134,11 +134,13 @@ void ps3_smp_cleanup_cpu(int cpu)
 	int i;
 
 	DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, cpu);
+
 	for (i = 0; i < MSG_COUNT; i++) {
-		ps3_free_event_irq(virqs[i]);
 		free_irq(virqs[i], (void*)(long)i);
+		ps3_event_receive_port_destroy(virqs[i]);
 		virqs[i] = NO_IRQ;
 	}
+
 	DBG(" <- %s:%d: (%d)\n", __func__, __LINE__, cpu);
 }
 
diff --git a/arch/powerpc/platforms/ps3/spu.c b/arch/powerpc/platforms/ps3/spu.c
index a397e4e..0d051c3 100644
--- a/arch/powerpc/platforms/ps3/spu.c
+++ b/arch/powerpc/platforms/ps3/spu.c
@@ -230,19 +230,19 @@ static int __init setup_interrupts(struct spu *spu)
 {
 	int result;
 
-	result = ps3_alloc_spe_irq(PS3_BINDING_CPU_ANY, spu_pdata(spu)->spe_id,
+	result = ps3_spe_irq_setup(PS3_BINDING_CPU_ANY, spu_pdata(spu)->spe_id,
 		0, &spu->irqs[0]);
 
 	if (result)
 		goto fail_alloc_0;
 
-	result = ps3_alloc_spe_irq(PS3_BINDING_CPU_ANY, spu_pdata(spu)->spe_id,
+	result = ps3_spe_irq_setup(PS3_BINDING_CPU_ANY, spu_pdata(spu)->spe_id,
 		1, &spu->irqs[1]);
 
 	if (result)
 		goto fail_alloc_1;
 
-	result = ps3_alloc_spe_irq(PS3_BINDING_CPU_ANY, spu_pdata(spu)->spe_id,
+	result = ps3_spe_irq_setup(PS3_BINDING_CPU_ANY, spu_pdata(spu)->spe_id,
 		2, &spu->irqs[2]);
 
 	if (result)
@@ -251,9 +251,9 @@ static int __init setup_interrupts(struct spu *spu)
 	return result;
 
 fail_alloc_2:
-	ps3_free_spe_irq(spu->irqs[1]);
+	ps3_spe_irq_destroy(spu->irqs[1]);
 fail_alloc_1:
-	ps3_free_spe_irq(spu->irqs[0]);
+	ps3_spe_irq_destroy(spu->irqs[0]);
 fail_alloc_0:
 	spu->irqs[0] = spu->irqs[1] = spu->irqs[2] = NO_IRQ;
 	return result;
@@ -301,9 +301,9 @@ static int ps3_destroy_spu(struct spu *spu)
 	result = lv1_disable_logical_spe(spu_pdata(spu)->spe_id, 0);
 	BUG_ON(result);
 
-	ps3_free_spe_irq(spu->irqs[2]);
-	ps3_free_spe_irq(spu->irqs[1]);
-	ps3_free_spe_irq(spu->irqs[0]);
+	ps3_spe_irq_destroy(spu->irqs[2]);
+	ps3_spe_irq_destroy(spu->irqs[1]);
+	ps3_spe_irq_destroy(spu->irqs[0]);
 
 	spu->irqs[0] = spu->irqs[1] = spu->irqs[2] = NO_IRQ;
 
diff --git a/drivers/ps3/ps3av.c b/drivers/ps3/ps3av.c
index d21e04c..1393e64 100644
--- a/drivers/ps3/ps3av.c
+++ b/drivers/ps3/ps3av.c
@@ -38,7 +38,24 @@
 static int timeout = 5000;	/* in msec ( 5 sec ) */
 module_param(timeout, int, 0644);
 
-static struct ps3av ps3av;
+static struct ps3av {
+	int available;
+	struct mutex mutex;
+	struct work_struct work;
+	struct completion done;
+	struct workqueue_struct *wq;
+	int open_count;
+	struct ps3_vuart_port_device *dev;
+
+	int region;
+	struct ps3av_pkt_av_get_hw_conf av_hw_conf;
+	u32 av_port[PS3AV_AV_PORT_MAX + PS3AV_OPT_PORT_MAX];
+	u32 opt_port[PS3AV_OPT_PORT_MAX];
+	u32 head[PS3AV_HEAD_MAX];
+	u32 audio_port;
+	int ps3av_mode;
+	int ps3av_mode_old;
+} ps3av;
 
 static struct ps3_vuart_port_device ps3av_dev = {
 	.match_id = PS3_MATCH_ID_AV_SETTINGS
@@ -159,7 +176,7 @@ static int ps3av_parse_event_packet(const struct ps3av_reply_hdr *hdr)
 		else
 			printk(KERN_ERR
 			       "%s: failed event packet, cid:%08x size:%d\n",
-			       __FUNCTION__, hdr->cid, hdr->size);
+			       __func__, hdr->cid, hdr->size);
 		return 1;	/* receive event packet */
 	}
 	return 0;
@@ -181,7 +198,7 @@ static int ps3av_send_cmd_pkt(const struct ps3av_send_hdr *send_buf,
 	if (res < 0) {
 		dev_dbg(&ps3av_dev.core,
 			"%s: ps3av_vuart_write() failed (result=%d)\n",
-			__FUNCTION__, res);
+			__func__, res);
 		return res;
 	}
 
@@ -194,7 +211,7 @@ static int ps3av_send_cmd_pkt(const struct ps3av_send_hdr *send_buf,
 		if (res != PS3AV_HDR_SIZE) {
 			dev_dbg(&ps3av_dev.core,
 				"%s: ps3av_vuart_read() failed (result=%d)\n",
-				__FUNCTION__, res);
+				__func__, res);
 			return res;
 		}
 
@@ -204,7 +221,7 @@ static int ps3av_send_cmd_pkt(const struct ps3av_send_hdr *send_buf,
 		if (res < 0) {
 			dev_dbg(&ps3av_dev.core,
 				"%s: ps3av_vuart_read() failed (result=%d)\n",
-				__FUNCTION__, res);
+				__func__, res);
 			return res;
 		}
 		res += PS3AV_HDR_SIZE;	/* total len */
@@ -214,7 +231,7 @@ static int ps3av_send_cmd_pkt(const struct ps3av_send_hdr *send_buf,
 
 	if ((cmd | PS3AV_REPLY_BIT) != recv_buf->cid) {
 		dev_dbg(&ps3av_dev.core, "%s: reply err (result=%x)\n",
-			__FUNCTION__, recv_buf->cid);
+			__func__, recv_buf->cid);
 		return -EINVAL;
 	}
 
@@ -250,7 +267,7 @@ int ps3av_do_pkt(u32 cid, u16 send_len, size_t usr_buf_size,
 		 struct ps3av_send_hdr *buf)
 {
 	int res = 0;
-	union {
+	static union {
 		struct ps3av_reply_hdr reply_hdr;
 		u8 raw[PS3AV_BUF_SIZE];
 	} recv_buf;
@@ -259,8 +276,7 @@ int ps3av_do_pkt(u32 cid, u16 send_len, size_t usr_buf_size,
 
 	BUG_ON(!ps3av.available);
 
-	if (down_interruptible(&ps3av.sem))
-		return -ERESTARTSYS;
+	mutex_lock(&ps3av.mutex);
 
 	table = ps3av_search_cmd_table(cid, PS3AV_CID_MASK);
 	BUG_ON(!table);
@@ -277,7 +293,7 @@ int ps3av_do_pkt(u32 cid, u16 send_len, size_t usr_buf_size,
 	if (res < 0) {
 		printk(KERN_ERR
 		       "%s: ps3av_send_cmd_pkt() failed (result=%d)\n",
-		       __FUNCTION__, res);
+		       __func__, res);
 		goto err;
 	}
 
@@ -286,16 +302,16 @@ int ps3av_do_pkt(u32 cid, u16 send_len, size_t usr_buf_size,
 					 usr_buf_size);
 	if (res < 0) {
 		printk(KERN_ERR "%s: put_return_status() failed (result=%d)\n",
-		       __FUNCTION__, res);
+		       __func__, res);
 		goto err;
 	}
 
-	up(&ps3av.sem);
+	mutex_unlock(&ps3av.mutex);
 	return 0;
 
       err:
-	up(&ps3av.sem);
-	printk(KERN_ERR "%s: failed cid:%x res:%d\n", __FUNCTION__, cid, res);
+	mutex_unlock(&ps3av.mutex);
+	printk(KERN_ERR "%s: failed cid:%x res:%d\n", __func__, cid, res);
 	return res;
 }
 
@@ -440,7 +456,7 @@ static int ps3av_set_videomode(void)
 	ps3av_set_av_video_mute(PS3AV_CMD_MUTE_ON);
 
 	/* wake up ps3avd to do the actual video mode setting */
-	up(&ps3av.ping);
+	queue_work(ps3av.wq, &ps3av.work);
 
 	return 0;
 }
@@ -506,7 +522,7 @@ static void ps3av_set_videomode_cont(u32 id, u32 old_id)
 	if (res == PS3AV_STATUS_NO_SYNC_HEAD)
 		printk(KERN_WARNING
 		       "%s: Command failed. Please try your request again. \n",
-		       __FUNCTION__);
+		       __func__);
 	else if (res)
 		dev_dbg(&ps3av_dev.core, "ps3av_cmd_avb_param failed\n");
 
@@ -515,18 +531,10 @@ static void ps3av_set_videomode_cont(u32 id, u32 old_id)
 	ps3av_set_av_video_mute(PS3AV_CMD_MUTE_OFF);
 }
 
-static int ps3avd(void *p)
+static void ps3avd(struct work_struct *work)
 {
-	struct ps3av *info = p;
-
-	daemonize("ps3avd");
-	while (1) {
-		down(&info->ping);
-		ps3av_set_videomode_cont(info->ps3av_mode,
-					 info->ps3av_mode_old);
-		up(&info->pong);
-	}
-	return 0;
+	ps3av_set_videomode_cont(ps3av.ps3av_mode, ps3av.ps3av_mode_old);
+	complete(&ps3av.done);
 }
 
 static int ps3av_vid2table_id(int vid)
@@ -707,8 +715,7 @@ int ps3av_set_video_mode(u32 id, int boot)
 
 	size = ARRAY_SIZE(video_mode_table);
 	if ((id & PS3AV_MODE_MASK) > size - 1 || id < 0) {
-		dev_dbg(&ps3av_dev.core, "%s: error id :%d\n", __FUNCTION__,
-			id);
+		dev_dbg(&ps3av_dev.core, "%s: error id :%d\n", __func__, id);
 		return -EINVAL;
 	}
 
@@ -717,15 +724,14 @@ int ps3av_set_video_mode(u32 id, int boot)
 	if ((id & PS3AV_MODE_MASK) == 0) {
 		id = ps3av_auto_videomode(&ps3av.av_hw_conf, boot);
 		if (id < 1) {
-			printk(KERN_ERR "%s: invalid id :%d\n", __FUNCTION__,
-			       id);
+			printk(KERN_ERR "%s: invalid id :%d\n", __func__, id);
 			return -EINVAL;
 		}
 		id |= option;
 	}
 
 	/* set videomode */
-	down(&ps3av.pong);
+	wait_for_completion(&ps3av.done);
 	ps3av.ps3av_mode_old = ps3av.ps3av_mode;
 	ps3av.ps3av_mode = id;
 	if (ps3av_set_videomode())
@@ -736,6 +742,13 @@ int ps3av_set_video_mode(u32 id, int boot)
 
 EXPORT_SYMBOL_GPL(ps3av_set_video_mode);
 
+int ps3av_get_auto_mode(int boot)
+{
+	return ps3av_auto_videomode(&ps3av.av_hw_conf, boot);
+}
+
+EXPORT_SYMBOL_GPL(ps3av_get_auto_mode);
+
 int ps3av_set_mode(u32 id, int boot)
 {
 	int res;
@@ -771,7 +784,7 @@ int ps3av_get_scanmode(int id)
 	id = id & PS3AV_MODE_MASK;
 	size = ARRAY_SIZE(video_mode_table);
 	if (id > size - 1 || id < 0) {
-		printk(KERN_ERR "%s: invalid mode %d\n", __FUNCTION__, id);
+		printk(KERN_ERR "%s: invalid mode %d\n", __func__, id);
 		return -EINVAL;
 	}
 	return video_mode_table[id].interlace;
@@ -786,7 +799,7 @@ int ps3av_get_refresh_rate(int id)
 	id = id & PS3AV_MODE_MASK;
 	size = ARRAY_SIZE(video_mode_table);
 	if (id > size - 1 || id < 0) {
-		printk(KERN_ERR "%s: invalid mode %d\n", __FUNCTION__, id);
+		printk(KERN_ERR "%s: invalid mode %d\n", __func__, id);
 		return -EINVAL;
 	}
 	return video_mode_table[id].fre